diff --git a/CHANGELOG.md b/CHANGELOG.md index dac0704e..9f619380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,65 @@ [TOC] +## 18.1.0 (2023-06-23) + +### Features: + + - Supports and requires OEMCrypto v18.1. + - Removed support for persistent usage records. (a.k.a. Secure Stops) W3C has + removed this session type from the EME specification, and Chrome has + deprecated their equivalent session type. The following API methods have + been removed: + - `Cdm::listUsageRecords()` + - `Cdm::deleteUsageRecord()` + - `Cdm::deleteAllUsageRecords()` + - There's a new host interface that integrators must implement, `ILogger`. + This interface has only one method, `log()`. It's called anytime the CE CDM + wants to log a message. This replaces the CE CDM's previous behavior of + logging all messages to `stderr`. + - For users that just want to log messages to `stderr` as in previous CE + CDM versions, a reference implementation is provided in `stderr_logger.h` + that logs all messages to `stderr`. + - The `privacy_mode` parameter may now be omitted when calling + `Cdm::create()`. It defaults to `false`. + - A new event, `onExpirationChange()`, has been added to `IEventListener`. + It'll be called anytime the expiration time of a session changes. + - A new parameter, `server_url`, has been added to + `IEventListener::onMessage()`. Use of this parameter is optional, and it has + no equivalent in EME. For renewal and release messages, it'll contain a + reminder of which license service to send the message to. This can be + useful if the app doesn't want to hardcode this information or get it + out-of-band. + - Added additional logging when provisioning fails, to help diagnose what went + wrong. + - Improved specificity of the logs when a CE CDM API method returns an error. + - Added support for licenses whose renewal timers start when the license is + loaded instead of on first decryption. + - Tests that are skipped because they don't apply to the device being tested + are now marked as SKIPPED instead of PASSED. + +### Bugfixes: + + - Fixed errors that could occur if the OEMCrypto integration reported a minor + version number for HDCP 1.x. + - Fixed an issue where the CDM might violate the threading guarantees for + `OEMCrypto_LoadOEMPrivateKey()`. + - Fixed rare errors that could occur if two threads tried to perform usage + actions simultaneously. + - Fixed errors that would occur if an entitled key was loaded into the session + with ID zero. This could happen if OEMCrypto reuses the session IDs of + closed sessions. + +### Dependency Updates: + + - The bundled version of Protobuf has been updated to [v21.12][proto-v21.12]. + (a.k.a. 3.21.12) + - The bundled version of BoringSSL has been updated to commit + [`e1b8685770d0e82e5a4a3c5d24ad1602e05f2e83`][boringssl-e1b868]. + +[proto-v21.12]: https://github.com/protocolbuffers/protobuf/releases/tag/v21.12 +[boringssl-e1b868]: https://boringssl.googlesource.com/boringssl/+/e1b8685770d0e82e5a4a3c5d24ad1602e05f2e83 + ## 17.1.2 (2023-06-23) ### Features: diff --git a/README.md b/README.md index 80ce0336..41d8d7bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Widevine CE CDM 17.1.2 +# Widevine CE CDM 18.1.0 Released 2023-06-23 diff --git a/cdm/cdm.gyp b/cdm/cdm.gyp index 6c58fb7b..6fa02c58 100644 --- a/cdm/cdm.gyp +++ b/cdm/cdm.gyp @@ -219,6 +219,7 @@ 'include/properties_ce.h', 'src/cdm.cpp', 'src/log.cpp', + 'src/logger_global.cpp', 'src/properties_ce.cpp', ], 'conditions': [ diff --git a/cdm/cdm_unittests.gyp b/cdm/cdm_unittests.gyp index ac42c836..5420a222 100644 --- a/cdm/cdm_unittests.gyp +++ b/cdm/cdm_unittests.gyp @@ -19,6 +19,8 @@ # The path to the prebuilt CDM to test against. (iOS only) 'prebuilt_cdm_path%': '', 'supports_dynamic_perf_test%': 0, + 'json_dir': '../third_party/nlohmann-json', + 'jsmn_dir': '../third_party/jsmn', }, 'targets': [{ 'toolsets' : [ 'target' ], diff --git a/cdm/core.gypi b/cdm/core.gypi index bedeee15..0653433e 100644 --- a/cdm/core.gypi +++ b/cdm/core.gypi @@ -14,6 +14,7 @@ '../core/include/cdm_engine_metrics_decorator.h', '../core/include/cdm_session.h', '../core/include/cdm_session_map.h', + '../core/include/cdm_usage_table.h', '../core/include/certificate_provisioning.h', '../core/include/client_identification.h', '../core/include/content_key_session.h', @@ -32,20 +33,20 @@ '../core/include/ota_keybox_provisioner.h', '../core/include/policy_engine.h', '../core/include/policy_timers.h', - '../core/include/policy_timers_v15.h', '../core/include/policy_timers_v16.h', + '../core/include/policy_timers_v18.h', '../core/include/privacy_crypto.h', '../core/include/properties.h', '../core/include/service_certificate.h', '../core/include/wv_cdm_constants.h', '../core/include/wv_cdm_event_listener.h', '../core/include/wv_cdm_types.h', - '../core/include/usage_table_header.h', '../core/src/buffer_reader.cpp', '../core/src/cdm_engine.cpp', '../core/src/cdm_engine_factory.cpp', '../core/src/cdm_session.cpp', '../core/src/cdm_session_map.cpp', + '../core/src/cdm_usage_table.cpp', '../core/src/certificate_provisioning.cpp', '../core/src/client_identification.cpp', '../core/src/content_key_session.cpp', @@ -55,17 +56,17 @@ '../core/src/initialization_data.cpp', '../core/src/license.cpp', '../core/src/license_key_status.cpp', + '../core/src/license_protocol_conversions.cpp', '../core/src/okp_fallback_policy.cpp', '../core/src/okp_info.cpp', '../core/src/ota_keybox_provisioner.cpp', '../core/src/policy_engine.cpp', '../core/src/policy_timers.cpp', - '../core/src/policy_timers_v15.cpp', '../core/src/policy_timers_v16.cpp', + '../core/src/policy_timers_v18.cpp', '../core/src/properties.cpp', '../core/src/service_certificate.cpp', '../core/src/system_id_extractor.cpp', - '../core/src/usage_table_header.cpp', '../core/src/wv_cdm_types.cpp', '../metrics/src/attribute_handler.cpp', '../metrics/src/counter_metric.cpp', diff --git a/cdm/core_unittests.gypi b/cdm/core_unittests.gypi index dd3644d3..95941b1c 100644 --- a/cdm/core_unittests.gypi +++ b/cdm/core_unittests.gypi @@ -10,6 +10,7 @@ '../core/test/cdm_engine_test.cpp', '../core/test/cdm_engine_metrics_decorator_unittest.cpp', '../core/test/cdm_session_unittest.cpp', + '../core/test/cdm_usage_table_unittest.cpp', '../core/test/config_test_env.cpp', '../core/test/certificate_provisioning_unittest.cpp', '../core/test/crypto_session_unittest.cpp', @@ -39,7 +40,6 @@ '../core/test/test_printers.cpp', '../core/test/url_request.cpp', '../core/test/url_request_unittest.cpp', - '../core/test/usage_table_header_unittest.cpp', '../metrics/test/counter_metric_unittest.cpp', '../metrics/test/distribution_unittest.cpp', '../metrics/test/event_metric_unittest.cpp', diff --git a/cdm/include/cdm.h b/cdm/include/cdm.h index 64d2ead8..dc81eba8 100644 --- a/cdm/include/cdm.h +++ b/cdm/include/cdm.h @@ -55,7 +55,7 @@ class CDM_EXPORT Cdm : public ITimerClient { kTemporary = 0, kPersistentLicense = 1, kPersistent = kPersistentLicense, // deprecated name from June 1 draft - kPersistentUsageRecord = 2, + // kPersistentUsageRecord = 2, // deprecated, no longer supported. }; // Message types defined by EME. @@ -226,14 +226,26 @@ class CDM_EXPORT Cdm : public ITimerClient { // application's license server. // The response, if successful, should be provided back to the CDM via a // call to Cdm::update(). + // + // The |server_url| parameter is not part of EME and may be ignored + // on EME-based integrations. It will be blank for initial license requests + // but filled in for renewal and release messages. It's offered for the use + // of apps that want to know the URL to send renewals and releases to + // without hardcoding it or retrieving it out-of-band. virtual void onMessage(const std::string& session_id, - MessageType message_type, - const std::string& message) = 0; + MessageType message_type, const std::string& message, + const std::string& server_url) = 0; // There has been a change in the keys in the session or their status. virtual void onKeyStatusesChange(const std::string& session_id, bool has_new_usable_key) = 0; + // Called when the CDM changes the expiration time for a session. + // |new_expiration| is in milliseconds since 1970 UTC. If the license + // doesn't expire, it'll be -1. + virtual void onExpirationChange(const std::string& session_id, + int64_t new_expiration) = 0; + // A remove() operation has been completed. virtual void onRemoveComplete(const std::string& session_id) = 0; @@ -320,6 +332,24 @@ class CDM_EXPORT Cdm : public ITimerClient { ITimer() {} }; + // A logging interface provided by the application. This will be called any + // time the CE CDM wants to log a message. + // See Cdm::initialize(). + // + // A reference implementation that logs to stderr is provided in + // stderr_logger.h. Its behavior is identical to the behavior of previous + // CE CDM releases. + class ILogger { + public: + virtual ~ILogger() {} + + // Log the provided message. + virtual void log(const std::string& message) = 0; + + protected: + ILogger() {} + }; + // The CE CDM has various pieces of client information baked into it at // compile-time. These can be retrieved at runtime by Cdm::getClientInfo(), // which returns them in this struct. @@ -363,7 +393,7 @@ class CDM_EXPORT Cdm : public ITimerClient { // Must be called and must return kSuccess before create() is called. static Status initialize(SecureOutputType secure_output_type, IStorage* storage, IClock* clock, ITimer* timer, - LogLevel verbosity); + ILogger* logger, LogLevel verbosity); // This is a variant of the above function that allows the caller to pass a // Sandbox ID. Platforms that use Sandbox IDs should use this initalize() @@ -371,7 +401,8 @@ class CDM_EXPORT Cdm : public ITimerClient { // should not use this version of initialize(). static Status initialize(SecureOutputType secure_output_type, IStorage* storage, IClock* clock, ITimer* timer, - LogLevel verbosity, const std::string& sandbox_id); + ILogger* logger, LogLevel verbosity, + const std::string& sandbox_id); // Query the CDM library version. static const char* version(); @@ -387,6 +418,7 @@ class CDM_EXPORT Cdm : public ITimerClient { // |storage| defines the storage to use for this instance. By providing // different objects here for different origins, this parameter can be used to // provide per-origin storage. It may not be NULL. + // // If |privacy_mode| is true, service certificates are required and will be // used to encrypt messages to the license server. // By using service certificates to encrypt communication with the license @@ -395,23 +427,19 @@ class CDM_EXPORT Cdm : public ITimerClient { // the server. // This is particularly useful for browser environments, but is recommended // for use whenever possible. - static Cdm* create(IEventListener* listener, IStorage* storage, - bool privacy_mode); - - // This is a variant of the above function that allows the caller to specify - // that the IStorage should be treated as read-only. Passing true for this - // parameter will cause the Widevine CE CDM to prevent attempts to modify any - // data in the IStorage. Note that this is *not* the expected operation mode - // for most clients and will likely lead to playback failures. It should only - // be used in cases where read-only certificates and licenses have been - // pre-loaded on a device, such as the preloaded licenses in ATSC 3. // + // If |storage_is_read_only| is true, the Widevine CE CDM will treat |storage| + // as read-only and prevent attempts to modify any data in the IStorage. Note + // that this is *not* the expected operation mode for most clients and will + // likely lead to playback failures. It should only be used in cases where + // read-only certificates and licenses have been pre-loaded on a device, such + // as the preloaded licenses in ATSC 3. // It is not possible to mix read-only and non-read-only files in the same // IStorage instance. A separate CDM with a separate IStorage pointing to the - // non-read-only files should be created with the read-only flag omitted or - // set to false. + // non-read-only files should be created with the read-only flag set to false. static Cdm* create(IEventListener* listener, IStorage* storage, - bool privacy_mode, bool storage_is_read_only); + bool privacy_mode = false, + bool storage_is_read_only = false); ~Cdm() override {} @@ -509,22 +537,6 @@ class CDM_EXPORT Cdm : public ITimerClient { // CDM's current IStorage object. virtual Status listStoredLicenses(std::vector* key_set_ids) = 0; - // Get the current list of secure-stop licenses on the system. - // License storage is origin-specific, and the origin is determined by the - // CDM's current IStorage object. ksids receives list of KSIDs representing - // usage records or secure-stop licenses. - virtual Status listUsageRecords(std::vector* ksids) = 0; - - // Delete the usage record for the given key_set_id. - // Usage info storage is origin-specific, and the origin is determined by the - // CDM's current IStorage object. - virtual Status deleteUsageRecord(const std::string& key_set_id) = 0; - - // Delete all usage records for the current origin. - // Usage info storage is origin-specific, and the origin is determined by the - // CDM's current IStorage object. - virtual Status deleteAllUsageRecords() = 0; - // Checks whether the device is capable of supporting a given HDCP version. // If successful, |key_status| is set to either kUsable or kOutputRestricted. virtual Status getStatusForHdcpVersion(HdcpVersion hdcp, @@ -549,7 +561,14 @@ class CDM_EXPORT Cdm : public ITimerClient { virtual Status createSession(SessionType session_type, std::string* session_id) = 0; - // Generates a request based on the initData. + // Generates a request based on the provided |init_data|. For PSSH init data, + // the CE CDM can accept the full concatenated blob of PSSH boxes from the + // stream. It will select the correct Widevine PSSH, so callers do not have to + // determine the correct PSSH from the list themselves. + // If the init data contains embedded keys, they will be remembered by the + // session and loaded after the matching entitlement key is provided to + // update(). + // // The request will be provided via a synchronous call to // IEventListener::onMessage(). // This is done so that license requests and renewals follow the same flow. @@ -567,8 +586,16 @@ class CDM_EXPORT Cdm : public ITimerClient { const std::string& response) = 0; // Loads the entitled keys embedded in |init_data| into the session identified - // by |session_id|. This function is only used when using entitlement - // licenses for key rotation. + // by |session_id|. The matching entitlement key must already be loaded in the + // session via previous calls to update() or load(). For PSSH init data, the + // CE CDM can accept the full concatenated blob of PSSH boxes from the stream. + // It will select the correct Widevine PSSH, so callers do not have to + // determine the correct PSSH from the list themselves. + // + // It is not necessary to call this function after passing PSSHs containing + // entitled keys to generateRequest(). This function is only used when adding + // new entitled keys to an existing session, such as for key rotation or + // after loading a persisted entitlement license. virtual Status loadEmbeddedKeys(const std::string& session_id, InitDataType init_data_type, const std::string& init_data) = 0; diff --git a/cdm/include/cdm_version.h b/cdm/include/cdm_version.h index 4ecdf4da..f57cda42 100644 --- a/cdm/include/cdm_version.h +++ b/cdm/include/cdm_version.h @@ -7,13 +7,13 @@ // Widevine CE CDM Version #ifndef CDM_VERSION_MAJOR -# define CDM_VERSION_MAJOR 17 +# define CDM_VERSION_MAJOR 18 #endif #ifndef CDM_VERSION_MINOR # define CDM_VERSION_MINOR 1 #endif #ifndef CDM_VERSION_PATCH -# define CDM_VERSION_PATCH 2 +# define CDM_VERSION_PATCH 0 #endif #ifndef CDM_VERSION_TAG # define CDM_VERSION_TAG "" diff --git a/cdm/include/logger_global.h b/cdm/include/logger_global.h new file mode 100644 index 00000000..2d840fbe --- /dev/null +++ b/cdm/include/logger_global.h @@ -0,0 +1,14 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#ifndef WVCDM_CDM_LOGGER_GLOBAL_H_ +#define WVCDM_CDM_LOGGER_GLOBAL_H_ + +#include "cdm.h" + +namespace widevine { +extern Cdm::ILogger* g_logger; +} + +#endif // WVCDM_CDM_LOGGER_GLOBAL_H_ diff --git a/cdm/include/stderr_logger.h b/cdm/include/stderr_logger.h new file mode 100644 index 00000000..62e818cf --- /dev/null +++ b/cdm/include/stderr_logger.h @@ -0,0 +1,28 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +// +// You can use this implementation of ILogger when calling Cdm::initialize() in +// order to log all messages to stderr. This preserves the behavior of past CE +// CDM releases. +#ifndef WVCDM_CDM_STDERR_LOGGER_H_ +#define WVCDM_CDM_STDERR_LOGGER_H_ + +#include +#include + +#include "cdm.h" + +namespace widevine { +class StderrLogger : public Cdm::ILogger { + public: + StderrLogger() {} + ~StderrLogger() override {} + + void log(const std::string& message) override { + std::cerr << message << std::endl << std::flush; + } +}; +} // namespace widevine + +#endif // WVCDM_CDM_STDERR_LOGGER_H_ diff --git a/cdm/platform_properties.gypi b/cdm/platform_properties.gypi index 3153f0ee..05443cd3 100644 --- a/cdm/platform_properties.gypi +++ b/cdm/platform_properties.gypi @@ -117,6 +117,10 @@ # Valid values are 'true' or 'false'. 'support_ota_keybox_functions%': 'false', + # Compile with clang source based code coverage tool when run a code coverage + # build by set this to true. + 'generate_code_coverage_report%': 'false', + # Override this to indicate what CPU architecture's assembly-language files # should be used when building assembly language files. Or, set it to # "none" to turn off the use of assembly language. The default is "none" for diff --git a/cdm/src/cdm.cpp b/cdm/src/cdm.cpp index 32c88c18..3ad12092 100644 --- a/cdm/src/cdm.cpp +++ b/cdm/src/cdm.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include "file_store.h" #include "license.h" #include "log.h" +#include "logger_global.h" #include "properties.h" #include "service_certificate.h" #include "string_conversions.h" @@ -34,6 +36,11 @@ #include "cdm_version.h" #include "properties_ce.h" +#ifdef HAS_EMBEDDED_CERT +extern uint8_t kDeviceCert[]; +extern size_t kDeviceCertSize; +#endif + namespace widevine { #ifdef HAS_EMBEDDED_CERT @@ -103,7 +110,6 @@ class PropertySet final : public CdmClientPropertySet { void set_session_sharing_id(uint32_t) override { // Unused on CE platforms. - return; } const std::string& app_id() const override { @@ -222,12 +228,6 @@ class CdmImpl final : public Cdm, public WvCdmEventListener { Status listStoredLicenses(std::vector* key_set_ids) override; - Status listUsageRecords(std::vector* ksids) override; - - Status deleteUsageRecord(const std::string& key_set_id) override; - - Status deleteAllUsageRecords() override; - Status getStatusForHdcpVersion(HdcpVersion hdcp, KeyStatus* key_status) override; @@ -345,7 +345,7 @@ class CdmImpl final : public Cdm, public WvCdmEventListener { std::string* cert, std::string* wrapped_key); - Cdm::Status ConvertStatusCode(CdmResponseType inner_error) const; + Cdm::Status ConvertStatusCode(const CdmResponseType& inner_error) const; IEventListener* listener_; bool policy_timer_enabled_; @@ -559,25 +559,6 @@ Cdm::Status CdmImpl::listStoredLicenses(std::vector* key_set_ids) { kSecurityLevelL1, key_set_ids)); } -Cdm::Status CdmImpl::listUsageRecords(std::vector* ksids) { - if (ksids == nullptr) { - LOGE("Missing vector parameter to receive KSIDs."); - return kTypeError; - } - return ConvertStatusCode(cdm_engine_->ListUsageIds( - property_set_.app_id(), kSecurityLevelL1, ksids, nullptr)); -} - -Cdm::Status CdmImpl::deleteUsageRecord(const std::string& key_set_id) { - return ConvertStatusCode(cdm_engine_->DeleteUsageRecord( - property_set_.app_id(), kSecurityLevelL1, key_set_id)); -} - -Cdm::Status CdmImpl::deleteAllUsageRecords() { - return ConvertStatusCode(cdm_engine_->RemoveAllUsageInfo( - property_set_.app_id(), kSecurityLevelL1)); -} - Cdm::Status CdmImpl::getStatusForHdcpVersion(Cdm::HdcpVersion hdcp, Cdm::KeyStatus* key_status) { std::string query_value; @@ -645,7 +626,6 @@ Cdm::Status CdmImpl::createSession(SessionType session_type, switch (session_type) { case kTemporary: case kPersistentLicense: - case kPersistentUsageRecord: break; default: LOGE("Unsupported session type: %d", static_cast(session_type)); @@ -688,9 +668,6 @@ Cdm::Status CdmImpl::generateRequest(const std::string& session_id, case kPersistentLicense: license_type = kLicenseTypeOffline; break; - case kPersistentUsageRecord: - license_type = kLicenseTypeStreaming; - break; default: LOGE("Unexpected session type: %d", static_cast(session_type)); return kUnexpectedError; @@ -744,7 +721,8 @@ Cdm::Status CdmImpl::generateRequest(const std::string& session_id, assert(key_request.type == kKeyRequestTypeInitial); LOGI("A license request has been generated"); - listener_->onMessage(session_id, kLicenseRequest, key_request.message); + listener_->onMessage(session_id, kLicenseRequest, key_request.message, + key_request.url); return kSuccess; } @@ -770,18 +748,8 @@ Cdm::Status CdmImpl::load(const std::string& session_id) { } if (!f.LicenseExists(session_id)) { - // This might be a usage record session which needs to be loaded. - CdmKeyMessage ignored_release_message; - result = ConvertStatusCode(cdm_engine_->LoadUsageSession( - session_id, &ignored_release_message)); - if (result != kSuccess) { - cdm_engine_->CloseSession(session_id); - return result; - } - - sessions_[session_id].type = kPersistentUsageRecord; - sessions_[session_id].callable = true; - return kSuccess; + LOGE("Unable to load license: %s", IdToString(session_id)); + return kSessionNotFound; } result = ConvertStatusCode(cdm_engine_->RestoreKey(session_id, session_id)); @@ -1029,7 +997,8 @@ Cdm::Status CdmImpl::remove(const std::string& session_id) { LOGI("A license release has been generated."); MessageType message_type = kLicenseRelease; - listener_->onMessage(session_id, message_type, key_request.message); + listener_->onMessage(session_id, message_type, key_request.message, + key_request.url); return kSuccess; } @@ -1290,7 +1259,8 @@ void CdmImpl::OnSessionRenewalNeeded(const CdmSessionId& session_id) { LOGI("A license renewal has been generated."); MessageType message_type = kLicenseRenewal; - listener_->onMessage(session_id, message_type, key_request.message); + listener_->onMessage(session_id, message_type, key_request.message, + key_request.url); } void CdmImpl::OnSessionKeysChange(const CdmSessionId& session_id, @@ -1348,6 +1318,7 @@ void CdmImpl::OnExpirationUpdate(const CdmSessionId& session_id, } else { sessions_[session_id].expiration = new_expiry_time_seconds * 1000; } + listener_->onExpirationChange(session_id, sessions_[session_id].expiration); } Cdm::KeyAllowedUsageFlags CdmImpl::KeyAllowedFlags( @@ -1416,8 +1387,10 @@ Cdm::Status CdmImpl::handleProvisioningResponse(const std::string& response, response, kLevelDefault, cert, wrapped_key)); } -Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { - switch (inner_error) { +Cdm::Status CdmImpl::ConvertStatusCode( + const CdmResponseType& inner_error) const { + const std::string message = inner_error.ToString(); + switch (inner_error.code()) { case GET_RELEASED_LICENSE_ERROR: // This was partially removed already. // The EME spec states that we should be able to load it, but not use it. @@ -1427,14 +1400,14 @@ Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { return kSuccess; case KEY_CONFLICT_1: - LOGE("Multiple sessions contain given key (inner_error=%d)", inner_error); + LOGE("Multiple sessions contain given key; %s", message.c_str()); return kTypeError; case NEED_PROVISIONING: - LOGE("Device not provisioned (inner_error=%d)", inner_error); + LOGE("Device not provisioned; %s", message.c_str()); return kNeedsDeviceCertificate; case LOAD_USAGE_INFO_MISSING: - LOGE("Unable to load license (inner_error=%d)", inner_error); + LOGE("Unable to load license; %s", message.c_str()); return kSessionNotFound; case SESSION_NOT_FOUND_1: case SESSION_NOT_FOUND_2: @@ -1459,7 +1432,7 @@ Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { case SESSION_NOT_FOUND_21: case SESSION_NOT_FOUND_22: case SESSION_NOT_FOUND_23: - LOGE("Session not found (inner_error=%d)", inner_error); + LOGE("Session not found; %s", message.c_str()); return kSessionNotFound; case KEY_NOT_FOUND_1: case KEY_NOT_FOUND_2: @@ -1472,7 +1445,7 @@ Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { case NO_CONTENT_KEY_2: case NO_CONTENT_KEY_3: case SESSION_NOT_FOUND_FOR_DECRYPT: - LOGE("Key not found (inner_error=%d)", inner_error); + LOGE("Key not found; %s", message.c_str()); return kNoKey; case INSUFFICIENT_OUTPUT_PROTECTION: LOGE("Key usage blocked due to HDCP or display resolution constraints."); @@ -1487,25 +1460,25 @@ Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { case CERT_PROVISIONING_NONCE_GENERATION_ERROR: case LICENSE_REQUEST_NONCE_GENERATION_ERROR: - LOGE("Nonce quota exceeded (inner_error=%d)", inner_error); + LOGE("Nonce quota exceeded; %s", message.c_str()); return kResourceContention; case SESSION_LOST_STATE_ERROR: - LOGE("Session invalidated (inner_error=%d)", inner_error); + LOGE("Session invalidated; %s", message.c_str()); return kSessionStateLost; case SYSTEM_INVALIDATED_ERROR: - LOGE("System invalidated (inner_error=%d)", inner_error); + LOGE("System invalidated; %s", message.c_str()); return kSystemStateLost; case OUTPUT_TOO_LARGE_ERROR: - LOGE("Output too large (inner_error=%d)", inner_error); + LOGE("Output too large; %s", message.c_str()); return kOutputTooLarge; case PRIVACY_MODE_ERROR_1: case PRIVACY_MODE_ERROR_2: case PRIVACY_MODE_ERROR_3: - LOGE("No service certificate installed (inner_error=%d)", inner_error); + LOGE("No service certificate installed; %s", message.c_str()); return kNeedsServiceCertificate; default: - LOGE("Unknown error: %d", inner_error); + LOGE("Unknown error; %s", message.c_str()); return kUnexpectedError; } } @@ -1515,15 +1488,28 @@ Cdm::Status CdmImpl::ConvertStatusCode(CdmResponseType inner_error) const { // static Cdm::Status Cdm::initialize(SecureOutputType secure_output_type, IStorage* storage, IClock* clock, ITimer* timer, - LogLevel verbosity) { - return initialize(secure_output_type, storage, clock, timer, verbosity, - kNoSandboxId); + ILogger* logger, LogLevel verbosity) { + return initialize(secure_output_type, storage, clock, timer, logger, + verbosity, kNoSandboxId); } // static Cdm::Status Cdm::initialize(SecureOutputType secure_output_type, IStorage* storage, IClock* clock, ITimer* timer, - LogLevel verbosity, const std::string& sandbox_id) { + ILogger* logger, LogLevel verbosity, + const std::string& sandbox_id) { + // Assigning the logger should always be the first thing we do, or else we + // can't log any errors. + if (!logger) { + // Since we don't have a logger to log errors to, we can't use LOGE(). We + // log to stderr as a last resort. + std::cerr + << "[FATAL] No ILogger implementation provided to Cdm::initialize()" + << std::endl + << std::flush; + return kTypeError; + } + g_logger = logger; // Specify the maximum severity of message that will be output to // the console. See core/include/log.h for the valid priority values. g_cutoff = static_cast(verbosity); @@ -1605,13 +1591,6 @@ Cdm::Status Cdm::getClientInfo(ClientInfo* client_info) { return kSuccess; } -// static -Cdm* Cdm::create(IEventListener* listener, IStorage* storage, - bool privacy_mode) { - return create(listener, storage, privacy_mode, - false /* storage_is_read_only */); -} - // static Cdm* Cdm::create(IEventListener* listener, IStorage* storage, bool privacy_mode, bool storage_is_read_only) { @@ -1751,6 +1730,14 @@ std::unique_ptr FileSystem::Open(const std::string& file_path, return std::unique_ptr(new FileImpl(impl_->storage_, file_path, flags)); } +bool FileSystem::Exists(const std::string& file_path, int* errno_value) { + bool res = Exists(file_path); + // TODO(b/280026170): Add more robust error reporting when a file does + // not exist + if (errno_value != nullptr) *errno_value = res ? 0 : ENOENT; + return res; +} + bool FileSystem::Exists(const std::string& file_path) { #ifdef HAS_EMBEDDED_CERT if (file_path == kLegacyCertificateFileName) return true; diff --git a/cdm/src/log.cpp b/cdm/src/log.cpp index 11188f1d..c0848998 100644 --- a/cdm/src/log.cpp +++ b/cdm/src/log.cpp @@ -11,6 +11,17 @@ #include #include +#include + +#include "logger_global.h" +#include "string_format.h" + +namespace { +// We initialize every log message with this message so that if formatting +// fails, we'll still get a readable message. +const char* const kFallbackLogMessage = "[FATAL] Unable to format log message"; +} // namespace + namespace wvutil { LogPriority g_cutoff = CDM_LOG_WARN; @@ -19,24 +30,39 @@ void InitLogging() {} void Log(const char* file, const char* function, int line, LogPriority level, const char* fmt, ...) { + if (widevine::g_logger == nullptr) { + // If somehow we got here with no logger configured, as a last resort + // complain to stderr and bail. + fprintf(stderr, "[FATAL:%s(%d):%s] NO LOGGER CONFIGURED\n", file, line, + function); + fflush(stderr); + return; + } + const char* severities[] = {"ERROR", "WARN", "INFO", "DEBUG", "VERBOSE"}; if (level >= static_cast(sizeof(severities) / sizeof(*severities))) { - fprintf(stderr, "[FATAL:%s(%d)] Invalid log priority level: %d\n", file, - line, level); + std::string fatal_message(kFallbackLogMessage); + FormatString(&fatal_message, + "[FATAL:%s(%d):%s] Invalid log priority level: %d", file, line, + function, level); + widevine::g_logger->log(fatal_message); return; } + if (level > g_cutoff) return; - fprintf(stderr, "[%s:%s(%d):%s] ", severities[level], file, line, function); - + std::string formatted_message(kFallbackLogMessage); va_list ap; va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + VFormatString(&formatted_message, fmt, ap); va_end(ap); - putc('\n', stderr); - fflush(stderr); + std::string log_line(kFallbackLogMessage); + FormatString(&log_line, "[%s:%s(%d):%s] %s", severities[level], file, line, + function, formatted_message.c_str()); + + widevine::g_logger->log(log_line); } } // namespace wvutil diff --git a/cdm/src/logger_global.cpp b/cdm/src/logger_global.cpp new file mode 100644 index 00000000..fc2cb7be --- /dev/null +++ b/cdm/src/logger_global.cpp @@ -0,0 +1,9 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "logger_global.h" + +namespace widevine { +Cdm::ILogger* g_logger = nullptr; +} diff --git a/cdm/src/properties_ce.cpp b/cdm/src/properties_ce.cpp index 477f3629..60a36de4 100644 --- a/cdm/src/properties_ce.cpp +++ b/cdm/src/properties_ce.cpp @@ -253,14 +253,14 @@ bool Properties::GetFactoryKeyboxPath(std::string*) { } // static -bool Properties::GetOEMCryptoPath(std::string* path) { - if (path == nullptr) return false; +bool Properties::GetOEMCryptoPaths(std::vector* paths) { + if (paths == nullptr) return false; // Using an environment variable is useful for testing. const char* env_path = getenv("LIBOEMCRYPTO_PATH"); if (env_path) { - *path = std::string(env_path); + paths->push_back(std::string(env_path)); } else { - *path = "liboemcrypto.so"; + paths->push_back(std::string("liboemcrypto.so")); } return true; } diff --git a/cdm/test/cdm_reboot_test_main.cpp b/cdm/test/cdm_reboot_test_main.cpp index 694d1204..03cfbc90 100644 --- a/cdm/test/cdm_reboot_test_main.cpp +++ b/cdm/test/cdm_reboot_test_main.cpp @@ -99,6 +99,10 @@ int main(int argc, char** argv) { Cdm::IClock* const clock = g_host; Cdm::ITimer* const timer = g_host; + // Partners who prefer their logs to go somewhere other than stderr may want + // to replace this implementation. + Cdm::ILogger* const logger = &g_stderr_logger; + // If the tests need a spearate file system from that used by the host, that // should be set up here. For the reference code, we use a default test file // system, but save the data from the file system. @@ -108,7 +112,7 @@ int main(int argc, char** argv) { wvutil::FileSystem* file_system = nullptr; wvcdm::RebootTest::set_file_system(file_system); - const int test_results = Main(storage, clock, timer, argc, argv); + const int test_results = Main(storage, clock, timer, logger, argc, argv); DumpFileSystems(); // This is used by the test driver to know what time to use for initializing // the fake clock for the next pass. diff --git a/cdm/test/cdm_test.cpp b/cdm/test/cdm_test.cpp index e88fc19f..c7cf382e 100644 --- a/cdm/test/cdm_test.cpp +++ b/cdm/test/cdm_test.cpp @@ -222,11 +222,14 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener { // IEventListener mocks: MOCK_METHOD(void, onMessage, (const std::string& session_id, Cdm::MessageType message_type, - const std::string& message), + const std::string& message, const std::string& server_url), (override)); MOCK_METHOD(void, onKeyStatusesChange, (const std::string& session_id, bool has_new_usable_key), (override)); + MOCK_METHOD(void, onExpirationChange, + (const std::string& session_id, int64_t new_expiry_time_seconds), + (override)); MOCK_METHOD(void, onRemoveComplete, (const std::string& session_id), (override)); @@ -240,7 +243,7 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener { // Reinit the library. Cdm::Status status = Cdm::initialize( Cdm::kNoSecureOutput, &g_host->global_storage(), g_host, g_host, - static_cast(g_cutoff), g_sandbox_id); + &g_stderr_logger, static_cast(g_cutoff), g_sandbox_id); ASSERT_EQ(Cdm::kSuccess, status); // Make a fresh CDM. @@ -372,8 +375,7 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener { init_data_type_name = HLS_INIT_DATA_FORMAT; init_data = kHlsInitData; } - } else if (session_type == Cdm::kPersistentLicense || - session_type == Cdm::kPersistentUsageRecord) { + } else if (session_type == Cdm::kPersistentLicense) { if (init_data_type == Cdm::kCenc) { init_data = kCencPersistentInitData; init_data_type_name = CENC_INIT_DATA_FORMAT; @@ -385,7 +387,7 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener { } ASSERT_FALSE(init_data.empty()); - EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(message)); status = generateRequestWithRetry(*session_id, init_data_type, init_data); ASSERT_EQ(Cdm::kSuccess, status); @@ -416,10 +418,21 @@ class CdmTest : public WvCdmTestBase, public Cdm::IEventListener { std::string response; ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense( session_type, init_data_type, session_id, &response)); + EXPECT_CALL(*this, onKeyStatusesChange(*session_id, true)); + int64_t event_expiry_time = 0; + EXPECT_CALL(*this, onExpirationChange(*session_id, _)) + .WillOnce(SaveArg<1>(&event_expiry_time)); + Cdm::Status status = updateWithRetry(*session_id, response); ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); + ASSERT_TRUE(Mock::VerifyAndClear(this)); + + // The new expiry time should be consistent. + int64_t function_expiry_time = 0; + ASSERT_EQ(cdm_->getExpiration(*session_id, &function_expiry_time), + Cdm::kSuccess); + EXPECT_EQ(event_expiry_time, function_expiry_time); } void FetchLicenseAndUpdate(const std::string& session_id, @@ -603,6 +616,8 @@ TEST_F(CdmTest, PrintClientInformation) { // Collect OEMCrypto info ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + (void)OEMCrypto_SetMaxAPIVersion(CDM_VERSION_MAJOR); + (void)OEMCrypto_EnterTestMode(); const uint32_t oec_major = OEMCrypto_APIVersion(); const uint32_t oec_minor = OEMCrypto_MinorAPIVersion(); const char* const supports_usage_tables = @@ -673,39 +688,46 @@ TEST_F(CdmTest, Initialize) { // Try with an invalid output type. Cdm::Status status = Cdm::initialize( static_cast(-1), &g_host->global_storage(), g_host, - g_host, static_cast(g_cutoff), g_sandbox_id); + g_host, &g_stderr_logger, static_cast(g_cutoff), + g_sandbox_id); EXPECT_EQ(Cdm::kTypeError, status); // Try with various host interfaces missing. status = Cdm::initialize(Cdm::kNoSecureOutput, nullptr, g_host, g_host, + &g_stderr_logger, static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kTypeError, status); status = Cdm::initialize(Cdm::kNoSecureOutput, &g_host->global_storage(), - nullptr, g_host, + nullptr, g_host, &g_stderr_logger, static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kTypeError, status); status = Cdm::initialize(Cdm::kNoSecureOutput, &g_host->global_storage(), - g_host, nullptr, + g_host, nullptr, &g_stderr_logger, + static_cast(g_cutoff), g_sandbox_id); + EXPECT_EQ(Cdm::kTypeError, status); + + status = Cdm::initialize(Cdm::kNoSecureOutput, &g_host->global_storage(), + g_host, g_host, nullptr, static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kTypeError, status); // Try all output types. status = Cdm::initialize(Cdm::kDirectRender, &g_host->global_storage(), - g_host, g_host, static_cast(g_cutoff), - g_sandbox_id); + g_host, g_host, &g_stderr_logger, + static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kSuccess, status); status = Cdm::initialize(Cdm::kOpaqueHandle, &g_host->global_storage(), - g_host, g_host, static_cast(g_cutoff), - g_sandbox_id); + g_host, g_host, &g_stderr_logger, + static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kSuccess, status); // One last init with everything correct and working. status = Cdm::initialize(Cdm::kNoSecureOutput, &g_host->global_storage(), - g_host, g_host, static_cast(g_cutoff), - g_sandbox_id); + g_host, g_host, &g_stderr_logger, + static_cast(g_cutoff), g_sandbox_id); EXPECT_EQ(Cdm::kSuccess, status); } @@ -838,7 +860,7 @@ TEST_F(CdmTest, OpenSessionWithoutServiceCertificate) { ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id)); // License request generation, however, should fail. - EXPECT_CALL(*this, onMessage(session_id, _, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, _, _, _)).Times(0); EXPECT_EQ(Cdm::kNeedsServiceCertificate, generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData)); Mock::VerifyAndClear(this); @@ -852,7 +874,7 @@ TEST_F(CdmTest, OpenSessionWithoutServiceCertificate) { cdm_->setServiceCertificate(Cdm::kLicensingService, config_.license_service_certificate())); - EXPECT_CALL(*this, onMessage(session_id, _, _)).Times(AtLeast(1)); + EXPECT_CALL(*this, onMessage(session_id, _, _, _)).Times(AtLeast(1)); EXPECT_EQ(Cdm::kSuccess, generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData)); Mock::VerifyAndClear(this); @@ -942,9 +964,13 @@ TEST_F(CdmTest, GenerateRequest) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)); + std::string url; + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .WillOnce(SaveArg<3>(&url)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSuccess, status); + Mock::VerifyAndClear(this); + EXPECT_TRUE(url.empty()); } TEST_F(CdmTest, GenerateRequest_ReuseSession) { @@ -953,13 +979,14 @@ TEST_F(CdmTest, GenerateRequest_ReuseSession) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSuccess, status); Mock::VerifyAndClear(this); // Can't call generateRequest more than once on a session. - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kInvalidState, status); } @@ -970,9 +997,13 @@ TEST_F(CdmTest, GenerateRequest_WebM) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)); + std::string url; + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .WillOnce(SaveArg<3>(&url)); status = generateRequestWithRetry(session_id, Cdm::kWebM, kWebMInitData); EXPECT_EQ(Cdm::kSuccess, status); + Mock::VerifyAndClear(this); + EXPECT_TRUE(url.empty()); } TEST_F(CdmTest, GenerateRequest_KeyIds) { @@ -981,7 +1012,8 @@ TEST_F(CdmTest, GenerateRequest_KeyIds) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kKeyIds, kKeyIdsInitData); EXPECT_EQ(Cdm::kNotSupported, status); } @@ -992,9 +1024,13 @@ TEST_F(CdmTest, GenerateRequest_HLS) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)); + std::string url; + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .WillOnce(SaveArg<3>(&url)); status = generateRequestWithRetry(session_id, Cdm::kHls, kHlsInitData); EXPECT_EQ(Cdm::kSuccess, status); + Mock::VerifyAndClear(this); + EXPECT_TRUE(url.empty()); } TEST_F(CdmTest, GenerateRequest_BogusType) { @@ -1003,14 +1039,15 @@ TEST_F(CdmTest, GenerateRequest_BogusType) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, kBogusInitDataType, "asdf"); EXPECT_EQ(Cdm::kTypeError, status); Mock::VerifyAndClear(this); // This same session should still be usable with a supported init data type // after failing with an unsupported or bogus type. - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSuccess, status); } @@ -1021,7 +1058,8 @@ TEST_F(CdmTest, GenerateRequest_Empty) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kCenc, ""); EXPECT_EQ(Cdm::kTypeError, status); } @@ -1032,7 +1070,8 @@ TEST_F(CdmTest, GenerateRequest_InvalidCenc) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kCenc, kInvalidCencInitData); EXPECT_EQ(Cdm::kNotSupported, status); @@ -1044,7 +1083,8 @@ TEST_F(CdmTest, GenerateRequest_NonWidevineCenc) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kCenc, kNonWidevineCencInitData); EXPECT_EQ(Cdm::kNotSupported, status); @@ -1056,7 +1096,7 @@ TEST_F(CdmTest, GenerateRequest_BogusSessionId) { Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(_, _, _)).Times(0); + EXPECT_CALL(*this, onMessage(_, _, _, _)).Times(0); status = generateRequestWithRetry(kBogusSessionId, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSessionNotFound, status); } @@ -1178,7 +1218,8 @@ TEST_F(CdmTest, Close) { ASSERT_EQ(Cdm::kSuccess, status); // Can't generate a license request after close. - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) + .Times(0); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSessionNotFound, status); Mock::VerifyAndClear(this); @@ -1270,10 +1311,12 @@ TEST_F(CdmTest, LoadWillFireExpiration) { // Let the key expire, make sure we get a key status update. EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)) - .Times(AtLeast(1)); + std::string url; + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _, _)) + .WillOnce(SaveArg<3>(&url)); g_host->ElapseTime(kOfflineLicenseDurationMs); Mock::VerifyAndClear(this); + EXPECT_FALSE(url.empty()); } TEST_F(CdmTest, PerOriginLoadPersistent) { @@ -1339,162 +1382,6 @@ TEST_F(CdmTest, PerOriginLoadPersistent) { } } -TEST_F(CdmTest, LoadUsageRecord) { - EnsureProvisioned(); - std::string session_id; - std::string response; - - ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense( - Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response)); - - // Update the session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, true)); - Cdm::Status status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after closing it. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - - // There should be no usable keys after loading this session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after recreating the CDM. - ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */)); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should not be able to load the session again clearing storage. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - g_host->Reset(); - EnsureProvisioned(); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSessionNotFound, status); - Mock::VerifyAndClear(this); -} - -TEST_F(CdmTest, DestroyUsageRecord) { - EnsureProvisioned(); - std::string session_id; - std::string response; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense( - Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response)); - - // Update the session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, true)); - Cdm::Status status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after closing it. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - - // There should be no usable keys after loading this session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after recreating the CDM. - ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */)); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->deleteUsageRecord(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSessionNotFound, status); - Mock::VerifyAndClear(this); -} - -TEST_F(CdmTest, DestroyAllUsageRecords) { - EnsureProvisioned(); - std::string session_id; - std::string response; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense( - Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response)); - - // Update the session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, true)); - Cdm::Status status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after closing it. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - - // There should be no usable keys after loading this session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after recreating the CDM. - ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */)); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->deleteAllUsageRecords(); - EXPECT_EQ(Cdm::kSuccess, status); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSessionNotFound, status); - Mock::VerifyAndClear(this); -} - -TEST_F(CdmTest, ListUsageRecords) { - EnsureProvisioned(); - std::string session_id; - std::string response; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense( - Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response)); - - // Update the session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, true)); - Cdm::Status status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after closing it. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - - // There should be no usable keys after loading this session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Should be able to load the session again after recreating the CDM. - ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */)); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - - std::vector ksids; - status = cdm_->listUsageRecords(&ksids); - EXPECT_EQ(Cdm::kSuccess, status); - EXPECT_EQ(ksids.size(), 1UL); - if (ksids.size() > 0UL) { - EXPECT_TRUE(ksids[0] == session_id); - } - status = cdm_->load(session_id); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); -} - TEST_F(CdmTest, LoadBogus) { EnsureProvisioned(); EXPECT_CALL(*this, onKeyStatusesChange(_, _)).Times(0); @@ -1521,7 +1408,7 @@ TEST_F(CdmTest, GetKeyStatuses) { // Let the key expire. EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _, _)) .Times(AtLeast(1)); g_host->ElapseTime(kExpirationTestDelayMs); Mock::VerifyAndClear(this); @@ -1553,7 +1440,7 @@ TEST_F(CdmTest, GetExpiration) { // Let the key expire. EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _, _)) .Times(AtLeast(1)); g_host->ElapseTime(kExpirationTestDelayMs); Mock::VerifyAndClear(this); @@ -1582,12 +1469,14 @@ TEST_P(CdmTestWithRemoveParam, Remove) { // Remove the session. This causes a release message to be generated. std::string message; + std::string url; EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _, _)) + .WillOnce(DoAll(SaveArg<2>(&message), SaveArg<3>(&url))); Cdm::Status status = cdm_->remove(session_id); ASSERT_EQ(Cdm::kSuccess, status); Mock::VerifyAndClear(this); + EXPECT_FALSE(url.empty()); // The keys should already be unusable. Cdm::KeyStatusMap map; @@ -1653,7 +1542,8 @@ TEST_F(CdmTest, ForceRemove) { // Forcibly remove the session. This should immediately trigger a removal // callback and should *not* cause a release message to be generated. EXPECT_CALL(*this, onRemoveComplete(session_id)).Times(1); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _, _)) + .Times(0); Cdm::Status status = cdm_->forceRemove(session_id); ASSERT_EQ(Cdm::kSuccess, status); Mock::VerifyAndClear(this); @@ -1681,162 +1571,6 @@ TEST_F(CdmTest, ForceRemove) { EXPECT_EQ(Cdm::kRangeError, status); } -TEST_F(CdmTest, RemoveUsageRecord) { - EnsureProvisioned(); - std::string session_id; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kPersistentUsageRecord, - Cdm::kCenc, &session_id)); - - // Remove the session. This causes a release message to be generated. - std::string message; - EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - Cdm::Status status = cdm_->remove(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The keys should already be unusable. - Cdm::KeyStatusMap map; - status = cdm_->getKeyStatuses(session_id, &map); - ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_EQ(Cdm::kReleased, map.begin()->second); - - // Post the release message to the license server. - std::string response; - ASSERT_NO_FATAL_FAILURE( - FetchLicense(config_.license_server(), message, &response)); - - // Update the session. - EXPECT_CALL(*this, onRemoveComplete(session_id)); - status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The session is now completely gone. - status = cdm_->close(session_id); - ASSERT_EQ(Cdm::kSessionNotFound, status); -} - -TEST_F(CdmTest, RemoveThreeUsageRecords) { - EnsureProvisioned(); - std::string session_id1, session_id2, session_id3; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kPersistentUsageRecord, - Cdm::kCenc, &session_id1)); - ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kPersistentUsageRecord, - Cdm::kCenc, &session_id2)); - ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kPersistentUsageRecord, - Cdm::kCenc, &session_id3)); - - // Close, reload and remove the middle session first - EXPECT_EQ(Cdm::kSuccess, cdm_->close(session_id2)); - - EXPECT_CALL(*this, onKeyStatusesChange(session_id2, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRelease, _)).Times(0); - Cdm::Status status = cdm_->load(session_id2); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Remove the session. This causes a release message to be generated. - std::string message; - EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - status = cdm_->remove(session_id2); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The keys should already be unusable. - Cdm::KeyStatusMap map; - status = cdm_->getKeyStatuses(session_id2, &map); - ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_TRUE(map.empty()); - - // Post the release message to the license server. - std::string response; - ASSERT_NO_FATAL_FAILURE( - FetchLicense(config_.license_server(), message, &response)); - - // Update the session. - EXPECT_CALL(*this, onRemoveComplete(session_id2)); - status = updateWithRetry(session_id2, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The session is now completely gone. - status = cdm_->close(session_id2); - ASSERT_EQ(Cdm::kSessionNotFound, status); - - // Close, reload and remove the last session next - EXPECT_EQ(Cdm::kSuccess, cdm_->close(session_id3)); - - EXPECT_CALL(*this, onKeyStatusesChange(session_id3, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id3, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id3); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Remove the session. This causes a release message to be generated. - EXPECT_CALL(*this, onMessage(session_id3, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - status = cdm_->remove(session_id3); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The keys should already be unusable. - status = cdm_->getKeyStatuses(session_id3, &map); - ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_TRUE(map.empty()); - - // Post the release message to the license server. - ASSERT_NO_FATAL_FAILURE( - FetchLicense(config_.license_server(), message, &response)); - - // Update the session. - EXPECT_CALL(*this, onRemoveComplete(session_id3)); - status = updateWithRetry(session_id3, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The session is now completely gone. - status = cdm_->close(session_id3); - ASSERT_EQ(Cdm::kSessionNotFound, status); - - // Close, reload and remove the first session next - EXPECT_EQ(Cdm::kSuccess, cdm_->close(session_id1)); - - EXPECT_CALL(*this, onKeyStatusesChange(session_id1, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id1, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id1); - EXPECT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Remove the session. This causes a release message to be generated. - EXPECT_CALL(*this, onMessage(session_id1, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - status = cdm_->remove(session_id1); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The keys should already be unusable. - status = cdm_->getKeyStatuses(session_id1, &map); - ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_TRUE(map.empty()); - - // Post the release message to the license server. - ASSERT_NO_FATAL_FAILURE( - FetchLicense(config_.license_server(), message, &response)); - - // Update the session. - EXPECT_CALL(*this, onRemoveComplete(session_id1)); - status = updateWithRetry(session_id1, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The session is now completely gone. - status = cdm_->close(session_id1); - ASSERT_EQ(Cdm::kSessionNotFound, status); -} - // Reload an offline license that does not have a usage entry. TEST_F(CdmTest, LoadPersistentNoNonce) { EnsureProvisioned(); @@ -1852,7 +1586,7 @@ TEST_F(CdmTest, LoadPersistentNoNonce) { const std::string init_data = MakePSSH(pssh); std::string license_request; { - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(&license_request)); ASSERT_EQ(Cdm::kSuccess, generateRequestWithRetry(session_id, Cdm::kCenc, init_data)); @@ -1905,7 +1639,7 @@ TEST_F(CdmTest, RemoveIncomplete) { // Remove the session. This causes a release message to be generated. std::string message; EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _, _)) .WillOnce(SaveArg<2>(&message)); Cdm::Status status = cdm_->remove(session_id); ASSERT_EQ(Cdm::kSuccess, status); @@ -1923,7 +1657,8 @@ TEST_F(CdmTest, RemoveIncomplete) { // Load the partially removed session. EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _, _)) + .Times(0); status = cdm_->load(session_id); ASSERT_EQ(Cdm::kSuccess, status); Mock::VerifyAndClear(this); @@ -1936,7 +1671,7 @@ TEST_F(CdmTest, RemoveIncomplete) { // Remove the session again to fire the release message. message.clear(); EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _, _)) .WillOnce(SaveArg<2>(&message)); status = cdm_->remove(session_id); ASSERT_EQ(Cdm::kSuccess, status); @@ -1960,70 +1695,6 @@ TEST_F(CdmTest, RemoveIncomplete) { ASSERT_EQ(Cdm::kSessionNotFound, status); } -TEST_F(CdmTest, RemoveUsageRecordIncomplete) { - EnsureProvisioned(); - std::string session_id; - ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kPersistentUsageRecord, - Cdm::kCenc, &session_id)); - - // Remove the session. This causes a release message to be generated. - std::string message; - EXPECT_CALL(*this, onKeyStatusesChange(session_id, false)); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - Cdm::Status status = cdm_->remove(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The keys should already be unusable, but they should still exist. - Cdm::KeyStatusMap map; - status = cdm_->getKeyStatuses(session_id, &map); - ASSERT_EQ(Cdm::kSuccess, status); - ASSERT_FALSE(map.empty()); - EXPECT_EQ(Cdm::kReleased, map.begin()->second); - - // Recreate the CDM. - ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */)); - - // Load the partially removed session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0); - status = cdm_->load(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // Remove the session again to fire a release message. - message.clear(); - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)) - .WillOnce(SaveArg<2>(&message)); - status = cdm_->remove(session_id); - ASSERT_EQ(Cdm::kSuccess, status); - ASSERT_FALSE(message.empty()); - Mock::VerifyAndClear(this); - - // This session has no keys. - status = cdm_->getKeyStatuses(session_id, &map); - ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_TRUE(map.empty()); - - // Post the release message to the license server. - std::string response; - ASSERT_NO_FATAL_FAILURE( - FetchLicense(config_.license_server(), message, &response)); - - // Update the session. - EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0); - EXPECT_CALL(*this, onRemoveComplete(session_id)); - status = updateWithRetry(session_id, response); - ASSERT_EQ(Cdm::kSuccess, status); - Mock::VerifyAndClear(this); - - // The session is now completely gone. - status = cdm_->load(session_id); - ASSERT_EQ(Cdm::kSessionNotFound, status); -} - TEST_F(CdmTest, RemoveNotLoaded) { EnsureProvisioned(); // Create a persistent session and then close it. @@ -2049,7 +1720,7 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) { ASSERT_EQ(Cdm::kSuccess, status); std::string message; - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(&message)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); ASSERT_EQ(Cdm::kSuccess, status); @@ -2068,7 +1739,7 @@ TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) { ASSERT_EQ(Cdm::kSuccess, status); std::string message; - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(&message)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencPersistentInitData); @@ -2098,11 +1769,13 @@ TEST_F(CdmTest, Renewal) { // When we elapse time, we should get a renewal message. std::string message; - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)) - .WillOnce(SaveArg<2>(&message)); + std::string url; + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _, _)) + .WillOnce(DoAll(SaveArg<2>(&message), SaveArg<3>(&url))); g_host->ElapseTime(kRenewalTestDelayMs); Mock::VerifyAndClear(this); ASSERT_FALSE(message.empty()); // Stop the test if no message came through. + EXPECT_FALSE(url.empty()); // When should still have a timer. EXPECT_NE(0u, g_host->NumTimers()); @@ -2114,7 +1787,8 @@ TEST_F(CdmTest, Renewal) { Cdm::Status status = cdm_->close(session_id); ASSERT_EQ(Cdm::kSuccess, status); - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)).Times(0); + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _, _)) + .Times(0); g_host->ElapseTime(kRenewalTestDelayMs * 10); Mock::VerifyAndClear(this); } @@ -2176,7 +1850,7 @@ TEST_F(CdmTest, SetAppParameters) { // Send a generate request to ensure the parameter is in the message. std::string message; - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(&message)); status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData); EXPECT_EQ(Cdm::kSuccess, status); @@ -2278,7 +1952,7 @@ TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) { // Generate a license request for the 1st entitlement init data. std::string license_request; { - EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)) + EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _, _)) .WillOnce(SaveArg<2>(&license_request)); ASSERT_EQ(Cdm::kSuccess, generateRequestWithRetry(session_id, Cdm::kCenc, @@ -2794,7 +2468,15 @@ TEST_F(CdmIndividualizationTest, CastReceiverProvisionAndSign) { EXPECT_EQ(decrypted_digest, kFakeCastMessage); } -class CdmProv40IndividualizationTest : public CdmTest {}; +class CdmProv40IndividualizationTest : public CdmTest { + void SetUp() override { + CdmTest::SetUp(); + if (wvoec::global_features.provisioning_method != + OEMCrypto_BootCertificateChain) { + GTEST_SKIP() << "Test for Prov 4.0 devices only."; + } + } +}; TEST_F(CdmProv40IndividualizationTest, NeedsOemCertProvisioning) { // No OEM cert, no DRM cert. diff --git a/cdm/test/cdm_test_main.cpp b/cdm/test/cdm_test_main.cpp index b573b41a..2ea3b7dd 100644 --- a/cdm/test/cdm_test_main.cpp +++ b/cdm/test/cdm_test_main.cpp @@ -35,6 +35,10 @@ int main(int argc, char** argv) { Cdm::IClock* const clock = g_host; Cdm::ITimer* const timer = g_host; - const int test_results = Main(storage, clock, timer, argc, argv); + // Partners who prefer their logs to go somewhere other than stderr may want + // to replace this implementation. + Cdm::ILogger* const logger = &g_stderr_logger; + + const int test_results = Main(storage, clock, timer, logger, argc, argv); return test_results; } diff --git a/cdm/test/cdm_test_runner.cpp b/cdm/test/cdm_test_runner.cpp index 089f5dbc..02fcc07a 100644 --- a/cdm/test/cdm_test_runner.cpp +++ b/cdm/test/cdm_test_runner.cpp @@ -12,10 +12,12 @@ #include "cdm.h" #include "log.h" +#include "stderr_logger.h" #include "test_base.h" #include "test_host.h" -std::string g_sandbox_id = ""; +widevine::StderrLogger g_stderr_logger; +std::string g_sandbox_id; namespace widevine { namespace { @@ -30,7 +32,7 @@ constexpr char kExtraHelpText[] = } // namespace int Main(Cdm::IStorage* storage, Cdm::IClock* clock, Cdm::ITimer* timer, - int argc, char** argv) { + Cdm::ILogger* logger, int argc, char** argv) { // Find and filter out the Sandbox ID, if any. std::vector args(argv, argv + argc); auto sandbox_id_iter = std::find_if(std::begin(args) + 1, std::end(args), @@ -43,7 +45,7 @@ int Main(Cdm::IStorage* storage, Cdm::IClock* clock, Cdm::ITimer* timer, } Cdm::Status status = Cdm::initialize( - Cdm::kOpaqueHandle, storage, clock, timer, + Cdm::kOpaqueHandle, storage, clock, timer, logger, static_cast(wvutil::g_cutoff), g_sandbox_id); (void)status; // status is now used when assertions are turned off. assert(status == Cdm::kSuccess); diff --git a/cdm/test/cdm_test_runner.h b/cdm/test/cdm_test_runner.h index 544d8b3b..b3151e8a 100644 --- a/cdm/test/cdm_test_runner.h +++ b/cdm/test/cdm_test_runner.h @@ -14,7 +14,7 @@ namespace widevine { // initializes a CDM object, and then runs all the tests. // Returns 0 on success. int Main(Cdm::IStorage* storage, Cdm::IClock* clock, Cdm::ITimer* timer, - int argc, char** argv); + Cdm::ILogger* logger, int argc, char** argv); } // namespace widevine #endif // WVCDM_CDM_TEST_CDM_TEST_RUNNER_H_ diff --git a/cdm/test/perf_test.cpp b/cdm/test/perf_test.cpp index fa204430..9f027b0e 100644 --- a/cdm/test/perf_test.cpp +++ b/cdm/test/perf_test.cpp @@ -136,11 +136,12 @@ class EventListener : public Cdm::IEventListener { std::string session_id; std::string message; Cdm::MessageType message_type; + std::string url; }; void onMessage(const std::string& session_id, Cdm::MessageType message_type, - const std::string& message) override { - messages.push_back({session_id, message, message_type}); + const std::string& message, const std::string& url) override { + messages.push_back({session_id, message, message_type, url}); } void onKeyStatusesChange(const std::string& session_id, bool has_new_usable_key) override {} @@ -189,7 +190,7 @@ class GlobalEnv : public testing::Environment { if (std::strcmp(verbose, "1") == 0) log_level = Cdm::kVerbose; } ASSERT_SUCCESS(init_func_(Cdm::kNoSecureOutput, &g_host->global_storage(), - g_host, g_host, log_level)); + g_host, g_host, &g_stderr_logger, log_level)); } private: diff --git a/cdm/test/perf_test.h b/cdm/test/perf_test.h index 3e8a4797..b8fe9b96 100644 --- a/cdm/test/perf_test.h +++ b/cdm/test/perf_test.h @@ -12,7 +12,8 @@ namespace widevine { using InitFuncType = Cdm::Status (*)(Cdm::SecureOutputType, Cdm::IStorage*, - Cdm::IClock*, Cdm::ITimer*, Cdm::LogLevel); + Cdm::IClock*, Cdm::ITimer*, Cdm::ILogger*, + Cdm::LogLevel); using CreateFuncType = Cdm* (*)(Cdm::IEventListener*, Cdm::IStorage*, bool); int PerfTestMain(InitFuncType init_func, CreateFuncType create_func, diff --git a/cdm/test/perf_test_dynamic.cpp b/cdm/test/perf_test_dynamic.cpp index b3e484b9..c15e2bb0 100644 --- a/cdm/test/perf_test_dynamic.cpp +++ b/cdm/test/perf_test_dynamic.cpp @@ -20,7 +20,7 @@ namespace widevine { constexpr char kInitName[] = "_ZN8widevine3Cdm10initializeENS0_16SecureOutputTypeEPNS0_8IStorageEPNS0_" - "6IClockEPNS0_6ITimerENS0_8LogLevelE"; + "6IClockEPNS0_6ITimerEPNS0_7ILoggerENS0_8LogLevelE"; constexpr char kCreateName[] = "_ZN8widevine3Cdm6createEPNS0_14IEventListenerEPNS0_8IStorageEb"; diff --git a/cdm/test/test_host.h b/cdm/test/test_host.h index b34f1a0a..5879ddfb 100644 --- a/cdm/test/test_host.h +++ b/cdm/test/test_host.h @@ -10,6 +10,7 @@ #include #include "cdm.h" +#include "stderr_logger.h" #include "test_sleep.h" // This provides a host environment for running CDM tests. It implements the @@ -94,6 +95,7 @@ class TestHost : public widevine::Cdm::IClock, // Owned and managed by the test runner. extern TestHost* g_host; +extern widevine::StderrLogger g_stderr_logger; extern std::string g_sandbox_id; #endif // WVCDM_CDM_TEST_TEST_HOST_H_ diff --git a/core/include/cdm_engine.h b/core/include/cdm_engine.h index 76ffa386..ce93727d 100644 --- a/core/include/cdm_engine.h +++ b/core/include/cdm_engine.h @@ -88,7 +88,7 @@ class CdmEngine { // request to. virtual CdmResponseType GenerateKeyRequest( const CdmSessionId& session_id, const CdmKeySetId& key_set_id, - const InitializationData& init_data, const CdmLicenseType license_type, + const InitializationData& init_data, CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request); // This API may // (a) accept license response, extract key info and load keys. @@ -214,17 +214,17 @@ class CdmEngine { // Return the list of IDs associated with usage records for the // current (origin-specific) file system. At least one parameter - // |ksids| or |provider_session_tokens| needs to be supplied. - virtual CdmResponseType ListUsageIds( - const std::string& app_id, CdmSecurityLevel security_level, - std::vector* ksids, - std::vector* provider_session_tokens); + // |ksids| or |psts| needs to be supplied. + virtual CdmResponseType ListUsageIds(const std::string& app_id, + CdmSecurityLevel security_level, + std::vector* ksids, + std::vector* psts); // Delete the usage record for the given key_set_id. This removes the // usage record in the file system and the OEMCrypto usage record. virtual CdmResponseType DeleteUsageRecord(const std::string& app_id, CdmSecurityLevel security_level, - const std::string& key_set_id); + const CdmKeySetId& key_set_id); // Get offline license status: active, release or unknown virtual CdmResponseType GetOfflineLicenseState( @@ -235,13 +235,17 @@ class CdmEngine { virtual CdmResponseType RemoveOfflineLicense(const std::string& key_set_id, CdmSecurityLevel security_level); + virtual CdmResponseType StoreAtscLicense( + RequestedSecurityLevel security_level, const CdmKeySetId& key_set_id, + const std::string& serialized_license_data); + // Usage related methods for streaming licenses // Retrieve a random usage info from the list of all usage infos for this app // id. If |error_detail| is not null, an additional error code may be provided // in the event of an error. virtual CdmResponseType GetUsageInfo(const std::string& app_id, int* error_detail, - CdmUsageInfo* usage_info); + CdmUsageReport* usage_report); // Retrieve usage info whose PST is specified by |ssid| // If |error_detail| is not null, an additional error code may be provided @@ -249,7 +253,7 @@ class CdmEngine { virtual CdmResponseType GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, int* error_detail, - CdmUsageInfo* usage_info); + CdmUsageReport* usage_report); // Retrieve usage info for a given security level and whose // PST is specified by |ssid|. @@ -259,7 +263,7 @@ class CdmEngine { const CdmSecureStopId& ssid, RequestedSecurityLevel security_level, int* error_detail, - CdmUsageInfo* usage_info); + CdmUsageReport* usage_report); // Remove all usage records for the current origin. virtual CdmResponseType RemoveAllUsageInfo(const std::string& app_id, @@ -272,8 +276,7 @@ class CdmEngine { virtual CdmResponseType RemoveUsageInfo( const std::string& app_id, const CdmSecureStopId& secure_stop_id); - virtual CdmResponseType ReleaseUsageInfo( - const CdmUsageInfoReleaseMessage& message); + virtual CdmResponseType ReleaseUsageInfo(const CdmKeyResponse& message); virtual CdmResponseType LoadUsageSession(const CdmKeySetId& key_set_id, CdmKeyMessage* release_message); @@ -415,12 +418,10 @@ class CdmEngine { bool ValidateKeySystem(const CdmKeySystem& key_system); CdmResponseType GetUsageInfo(const std::string& app_id, RequestedSecurityLevel requested_security_level, - int* error_detail, CdmUsageInfo* usage_info); + int* error_detail, CdmUsageReport* usage_report); void OnKeyReleaseEvent(const CdmKeySetId& key_set_id); - std::string MapHdcpVersion(CryptoSession::HdcpCapability version); - void CloseExpiredReleaseSessions(); // Returns "true" if |okp_provisioner_| should be checked. @@ -458,7 +459,10 @@ class CdmEngine { // API will release the handle to previously active secure stop license. std::unique_ptr usage_session_; std::unique_ptr usage_property_set_; - int64_t last_usage_information_update_time_; + int64_t last_usage_information_update_time_ = 0; + // Should be acquired before changes to |usage_property_set_| or + // |usage_session_|. + std::mutex usage_session_mutex_; // Protect release_key_sets_ from non-thread-safe operations. std::mutex release_key_sets_lock_; diff --git a/core/include/cdm_engine_metrics_decorator.h b/core/include/cdm_engine_metrics_decorator.h index 4d908af7..e1719254 100644 --- a/core/include/cdm_engine_metrics_decorator.h +++ b/core/include/cdm_engine_metrics_decorator.h @@ -122,7 +122,7 @@ class CdmEngineMetricsImpl : public T { CdmKeySetId* key_set_id) override { if (license_type == nullptr) { LOGE("|license_type| cannot be null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } CdmResponseType sts; @@ -184,10 +184,10 @@ class CdmEngineMetricsImpl : public T { } CdmResponseType GetUsageInfo(const std::string& app_id, int* error_detail, - CdmUsageInfo* usage_info) override { + CdmUsageReport* usage_report) override { CdmResponseType sts; int error_detail_alt; - M_TIME(sts = T::GetUsageInfo(app_id, &error_detail_alt, usage_info), + M_TIME(sts = T::GetUsageInfo(app_id, &error_detail_alt, usage_report), metrics_, cdm_engine_get_usage_info_, sts, error_detail_alt); if (error_detail != nullptr) { *error_detail = error_detail_alt; @@ -197,10 +197,10 @@ class CdmEngineMetricsImpl : public T { CdmResponseType GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, int* error_detail, - CdmUsageInfo* usage_info) override { + CdmUsageReport* usage_report) override { CdmResponseType sts; int error_detail_alt; - M_TIME(sts = T::GetUsageInfo(app_id, ssid, &error_detail_alt, usage_info), + M_TIME(sts = T::GetUsageInfo(app_id, ssid, &error_detail_alt, usage_report), metrics_, cdm_engine_get_usage_info_, sts, error_detail_alt); if (error_detail != nullptr) { *error_detail = error_detail_alt; @@ -209,14 +209,14 @@ class CdmEngineMetricsImpl : public T { } CdmResponseType RemoveAllUsageInfo(const std::string& app_id) override { - CdmResponseType sts = T::RemoveAllUsageInfo(app_id); + const CdmResponseType sts = T::RemoveAllUsageInfo(app_id); metrics_->cdm_engine_remove_all_usage_info_.Increment(sts); return sts; } CdmResponseType RemoveAllUsageInfo(const std::string& app_id, CdmSecurityLevel security_level) override { - CdmResponseType sts = T::RemoveAllUsageInfo(app_id, security_level); + const CdmResponseType sts = T::RemoveAllUsageInfo(app_id, security_level); metrics_->cdm_engine_remove_all_usage_info_.Increment(sts); return sts; } @@ -224,24 +224,23 @@ class CdmEngineMetricsImpl : public T { CdmResponseType RemoveUsageInfo( const std::string& app_id, const CdmSecureStopId& secure_stop_id) override { - CdmResponseType sts = T::RemoveUsageInfo(app_id, secure_stop_id); + const CdmResponseType sts = T::RemoveUsageInfo(app_id, secure_stop_id); metrics_->cdm_engine_remove_usage_info_.Increment(sts); return sts; } - CdmResponseType ReleaseUsageInfo( - const CdmUsageInfoReleaseMessage& message) override { - CdmResponseType sts = T::ReleaseUsageInfo(message); + CdmResponseType ReleaseUsageInfo(const CdmKeyResponse& message) override { + const CdmResponseType sts = T::ReleaseUsageInfo(message); metrics_->cdm_engine_release_usage_info_.Increment(sts); return sts; } - CdmResponseType ListUsageIds( - const std::string& app_id, CdmSecurityLevel security_level, - std::vector* ksids, - std::vector* provider_session_tokens) override { - CdmResponseType sts = - T::ListUsageIds(app_id, security_level, ksids, provider_session_tokens); + CdmResponseType ListUsageIds(const std::string& app_id, + CdmSecurityLevel security_level, + std::vector* ksids, + std::vector* ssids) override { + const CdmResponseType sts = + T::ListUsageIds(app_id, security_level, ksids, ssids); metrics_->cdm_engine_get_secure_stop_ids_.Increment(sts); return sts; } diff --git a/core/include/cdm_session.h b/core/include/cdm_session.h index 14400aa4..2c6018b0 100644 --- a/core/include/cdm_session.h +++ b/core/include/cdm_session.h @@ -27,7 +27,8 @@ namespace wvcdm { class CdmClientPropertySet; class ServiceCertificate; class WvCdmEventListener; -class UsageTableHeader; +class CdmUsageTable; +class SystemIdExtractor; class CdmSession { public: @@ -129,7 +130,7 @@ class CdmSession { // ReleaseKey() - Accept response and release key. virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response); - virtual CdmResponseType DeleteUsageEntry(uint32_t usage_entry_number); + virtual CdmResponseType DeleteUsageEntry(UsageEntryIndex entry_index); virtual bool IsKeyLoaded(const KeyId& key_id); virtual int64_t GetDurationRemaining(); @@ -164,9 +165,7 @@ class CdmSession { license_parser_->provider_session_token().size() > 0); } - virtual bool supports_usage_info() const { - return usage_table_header_ != nullptr; - } + virtual bool SupportsUsageTable() const { return usage_table_ != nullptr; } // This method will remove keys by resetting crypto resources and // policy information. This renders the session mostly useless and it is @@ -264,11 +263,14 @@ class CdmSession { // true otherwise. bool VerifyOfflineUsageEntry(); + bool HasRootOfTrustBeenRenewed(); + // These setters are for testing only. Takes ownership of the pointers. void set_license_parser(CdmLicense* license_parser); void set_crypto_session(CryptoSession* crypto_session); void set_policy_engine(PolicyEngine* policy_engine); void set_file_handle(DeviceFiles* file_handle); + void set_system_id_extractor(SystemIdExtractor* extractor); // instance variables std::shared_ptr metrics_; @@ -285,6 +287,7 @@ class CdmSession { std::unique_ptr crypto_session_; std::unique_ptr policy_engine_; std::unique_ptr file_handle_; + std::unique_ptr mock_system_id_extractor_; bool license_received_; bool is_offline_; bool is_release_; @@ -314,11 +317,11 @@ class CdmSession { // Usage related flags and data bool is_initial_usage_update_; bool is_usage_update_needed_; - // Only assign |usage_table_header_| if capable of supporting usage + // Only assign |usage_table_| if capable of supporting usage // information. - UsageTableHeader* usage_table_header_ = nullptr; - uint32_t usage_entry_number_; - CdmUsageEntry usage_entry_; + CdmUsageTable* usage_table_ = nullptr; + UsageEntryIndex usage_entry_index_ = 0; + UsageEntry usage_entry_; std::string usage_provider_session_token_; // information useful for offline and usage scenarios diff --git a/core/include/usage_table_header.h b/core/include/cdm_usage_table.h similarity index 74% rename from core/include/usage_table_header.h rename to core/include/cdm_usage_table.h index 66aef9b3..07cc3a3f 100644 --- a/core/include/usage_table_header.h +++ b/core/include/cdm_usage_table.h @@ -2,8 +2,8 @@ // source code may only be used and distributed under the Widevine License // Agreement. -#ifndef WVCDM_CORE_USAGE_TABLE_HEADER_H_ -#define WVCDM_CORE_USAGE_TABLE_HEADER_H_ +#ifndef WVCDM_CORE_CDM_USAGE_TABLE_H_ +#define WVCDM_CORE_CDM_USAGE_TABLE_H_ #include #include @@ -46,12 +46,12 @@ namespace wvcdm { // // Upgrades from a fixed size usage table (supported by previous // versions of the OEMCrypto API v9-12) are handled by this class. -// |usage_entry| and |usage_entry_number|s need to be saved in the license +// |entry| and |entry_index|s need to be saved in the license // and usage info records by the caller. -class UsageTableHeader { +class CdmUsageTable { public: - UsageTableHeader(); - virtual ~UsageTableHeader() {} + CdmUsageTable(); + virtual ~CdmUsageTable() {} // |crypto_session| is used to create or load a usage master table // and not cached beyound this call. @@ -65,36 +65,36 @@ class UsageTableHeader { // Adds a new entry to the OEMCrypto usage table header, and associates // the entry with the provided |crypto_session|. The index of the new - // usage entry will be returned by |usage_entry_number|. + // usage entry will be returned by |entry_index|. // // Type of entry depends on the value of |persistent_license|: // false - usage info / secure stop record // true - offline license // - // Threading: Method takes exclusive use of |usage_table_header_lock_|. + // Threading: Method takes exclusive use of |lock_|. virtual CdmResponseType AddEntry(CryptoSession* crypto_session, bool persistent_license, const CdmKeySetId& key_set_id, const std::string& usage_info_filename, const CdmKeyResponse& license_message, - uint32_t* usage_entry_number); - // Threading: Method takes exclusive use of |usage_table_header_lock_|. + UsageEntryIndex* entry_index); + // Threading: Method takes exclusive use of |lock_|. virtual CdmResponseType LoadEntry(CryptoSession* crypto_session, - const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number); - // Threading: Method takes exclusive use of |usage_table_header_lock_|. - virtual CdmResponseType UpdateEntry(uint32_t usage_entry_number, + const UsageEntry& entry, + UsageEntryIndex entry_index); + // Threading: Method takes exclusive use of |lock_|. + virtual CdmResponseType UpdateEntry(UsageEntryIndex entry_index, CryptoSession* crypto_session, - CdmUsageEntry* usage_entry); + UsageEntry* entry); - // The licenses or usage info records specified by |usage_entry_number| + // The licenses or usage info records specified by |entry_index| // should not be in use by any open CryptoSession objects when calls // to InvalidateEntry and MoveEntry are made. // If |defrag_table| is true, the table will be defragmented after // the entry has been invalidated. // - // Threading: Method takes exclusive use of |usage_table_header_lock_|. - virtual CdmResponseType InvalidateEntry(uint32_t usage_entry_number, + // Threading: Method takes exclusive use of |lock_|. + virtual CdmResponseType InvalidateEntry(UsageEntryIndex entry_index, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics); @@ -107,13 +107,13 @@ class UsageTableHeader { // for the objects that InvalidateEntry depends on. // // Threading: Method requires care of caller for exclusive access. - void InvalidateEntryForTest(uint32_t usage_entry_number); + void InvalidateEntryForTest(UsageEntryIndex entry_index); // == Table information methods == // Threading: None of the following are thread safe. Intended for // testing or internal use. - size_t size() { return usage_entry_info_.size(); } + size_t size() { return entry_info_list_.size(); } size_t potential_table_capacity() const { return potential_table_capacity_; } @@ -128,8 +128,8 @@ class UsageTableHeader { // are related to offline licenses. size_t OfflineEntryCount() const; - const std::vector& usage_entry_info() const { - return usage_entry_info_; + const std::vector& entry_info_list() const { + return entry_info_list_; } // Set the reference clock used for the method GetCurrentTime(). @@ -141,10 +141,10 @@ class UsageTableHeader { } static bool DetermineLicenseToRemoveForTesting( - const std::vector& usage_entry_info_list, + const std::vector& entry_info_list, int64_t current_time, size_t unexpired_threshold, - uint32_t* entry_to_remove) { - return DetermineLicenseToRemove(usage_entry_info_list, current_time, + UsageEntryIndex* entry_to_remove) { + return DetermineLicenseToRemove(entry_info_list, current_time, unexpired_threshold, entry_to_remove); } @@ -155,94 +155,91 @@ class UsageTableHeader { // Creates a new, empty usage table. Any existing usage table files // will be deleted. - // Threading: Method takes exclusive use of |usage_table_header_lock_| + // Threading: Method takes exclusive use of |lock_| // when required. - bool CreateNewTable(CryptoSession* const crypto_session); + bool CreateNewTable(CryptoSession* crypto_session); // Attempts to restore the usage table from persistent storage, and // loads the usage table header into OEMCrypto. // Note: No other OEMCrypto session should be opened before calling. - // Threading: Method takes exclusive use of |usage_table_header_lock_| + // Threading: Method takes exclusive use of |lock_| // when required. - bool RestoreTable(CryptoSession* const crypto_session); + bool RestoreTable(CryptoSession* crypto_session); // Performs a check that there are no open OEMCrypto sessions for // the current security level of the usage table. // Threading: No special threading requirements. - bool OpenSessionCheck(CryptoSession* const crypto_session); + bool OpenSessionCheck(CryptoSession* crypto_session); // Performs a check that the OEMCrypto table can support at least // one more entry if the table is at or near the reported capacity. // If this check fails, a new usage table SHOULD be created. // Threading: Method requires caller to take exclusive use of - // |usage_table_header_lock_|. - bool CapacityCheck(CryptoSession* const crypto_session); + // |lock_|. + bool CapacityCheck(CryptoSession* crypto_session); // Attempts to determine the capacity of the OEMCrypto usage table. // Sets the result to |potential_table_capacity_|. // Threading: Method requires caller to take exclusive use of - // |usage_table_header_lock_|. + // |lock_|. bool DetermineTableCapacity(CryptoSession* crypto_session); // == Table operation methods == // Threading: All of the following methods require caller to take - // exclusive use of |usage_table_header_lock_|. + // exclusive use of |lock_|. // Creates a new entry for the provided crypto session. If the // entry is created successfully in OEMCrypto, then a new entry // info is added to the table's vector of entry info. - CdmResponseType CreateEntry(CryptoSession* const crypto_session, - uint32_t* usage_entry_number); + CdmResponseType CreateEntry(CryptoSession* crypto_session, + UsageEntryIndex* entry_index); // Attempts to relocate a newly created usage entry associated with // the provided |crypto_session| to the lowest unoccupied position in // the table. - // |usage_entry_number| is treated as both an input and output. + // |entry_index| is treated as both an input and output. // Returns NO_ERROR so long as no internal operation fails, // regardless of whether the entry was moved or not. - CdmResponseType RelocateNewEntry(CryptoSession* const crypto_session, - uint32_t* usage_entry_number); + CdmResponseType RelocateNewEntry(CryptoSession* crypto_session, + UsageEntryIndex* entry_index); - // Checks if the specified |usage_entry_number| is known to be + // Checks if the specified |entry_index| is known to be // unoccupied (released). - bool IsEntryUnoccupied(const uint32_t usage_entry_number) const; + bool IsEntryUnoccupied(UsageEntryIndex entry_index) const; // SetOfflineEntryInfo() and SetUsageInfoEntryInfo() populate the // entry meta-data with the required information based on the type // of entry. - void SetOfflineEntryInfo(const uint32_t usage_entry_number, + void SetOfflineEntryInfo(UsageEntryIndex entry_index, const std::string& key_set_id, const CdmKeyResponse& license_message); - void SetUsageInfoEntryInfo(const uint32_t usage_entry_number, + void SetUsageInfoEntryInfo(UsageEntryIndex entry_index, const std::string& key_set_id, const std::string& usage_info_file_name); // Shrinks the table, removing all trailing unoccupied entries. - // |usage_entry_info_| will be resized appropriately. + // |entry_info_list_| will be resized appropriately. // Caller must store the table after a successful call. - CdmResponseType RefitTable(CryptoSession* const crypto_session); + CdmResponseType RefitTable(CryptoSession* crypto_session); virtual CdmResponseType InvalidateEntryInternal( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, + UsageEntryIndex entry_index, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics); - CdmResponseType MoveEntry(uint32_t from /* usage entry number */, - const CdmUsageEntry& from_usage_entry, - uint32_t to /* usage entry number */, - DeviceFiles* device_files, + CdmResponseType MoveEntry(UsageEntryIndex from, const UsageEntry& from_entry, + UsageEntryIndex to, DeviceFiles* device_files, metrics::CryptoMetrics* metrics); - CdmResponseType GetEntry(uint32_t usage_entry_number, - DeviceFiles* device_files, - CdmUsageEntry* usage_entry); - CdmResponseType StoreEntry(uint32_t usage_entry_number, + CdmResponseType GetEntry(UsageEntryIndex entry_index, + DeviceFiles* device_files, UsageEntry* entry); + CdmResponseType StoreEntry(UsageEntryIndex entry_index, DeviceFiles* device_files, - const CdmUsageEntry& usage_entry); + const UsageEntry& entry); // Stores the usage table and it's info. This will increment // |store_table_counter_| if successful. bool StoreTable(); CdmResponseType Shrink(metrics::CryptoMetrics* metrics, - uint32_t number_of_usage_entries_to_delete); + uint32_t number_of_entries_to_delete); // Must lock table before calling. CdmResponseType DefragTable(DeviceFiles* device_files, @@ -286,7 +283,7 @@ class UsageTableHeader { // types. // // Parameters: - // [in] usage_entry_info_list: The complete list of known usage + // [in] entry_info_list: The complete list of known usage // entries. // [in] current_time: The current time to compare expiration times // against. @@ -301,20 +298,20 @@ class UsageTableHeader { // |true| if an entry has been determined to be removed. // Otherwise returns |false|. static bool DetermineLicenseToRemove( - const std::vector& usage_entry_info_list, + const std::vector& entry_info_list, int64_t current_time, size_t unexpired_threshold, - uint32_t* entry_to_remove); + UsageEntryIndex* entry_to_remove); // This handle and file system is only to be used when accessing - // usage_table_header. Usage entries should use the file system provided + // header. Usage entries should use the file system provided // by CdmSession. std::unique_ptr device_files_; std::unique_ptr file_system_; CdmSecurityLevel security_level_ = kSecurityLevelUninitialized; RequestedSecurityLevel requested_security_level_ = kLevelDefault; - CdmUsageTableHeader usage_table_header_; - std::vector usage_entry_info_; + UsageTableHeader header_; + std::vector entry_info_list_; // Table is sync with persistent storage and can be used by the CDM // to interact with OEMCrypto. @@ -322,7 +319,7 @@ class UsageTableHeader { // Synchonizes access to the Usage Table Header and bookkeeping // data-structures - mutable std::mutex usage_table_header_lock_; + mutable std::mutex lock_; metrics::CryptoMetrics alternate_crypto_metrics_; @@ -347,12 +344,12 @@ class UsageTableHeader { #if defined(UNIT_TEST) // Test related declarations - friend class UsageTableHeaderTest; + friend class CdmUsageTableTest; - FRIEND_TEST(UsageTableHeaderTest, Shrink_NoneOfTable); - FRIEND_TEST(UsageTableHeaderTest, Shrink_PartOfTable); - FRIEND_TEST(UsageTableHeaderTest, Shrink_AllOfTable); - FRIEND_TEST(UsageTableHeaderTest, Shrink_MoreThanTable); + FRIEND_TEST(CdmUsageTableTest, Shrink_NoneOfTable); + FRIEND_TEST(CdmUsageTableTest, Shrink_PartOfTable); + FRIEND_TEST(CdmUsageTableTest, Shrink_AllOfTable); + FRIEND_TEST(CdmUsageTableTest, Shrink_MoreThanTable); #endif // These setters are for testing only. Takes ownership of the pointers. @@ -366,9 +363,9 @@ class UsageTableHeader { // Test related data members std::unique_ptr test_crypto_session_; - CORE_DISALLOW_COPY_AND_ASSIGN(UsageTableHeader); + CORE_DISALLOW_COPY_AND_ASSIGN(CdmUsageTable); }; } // namespace wvcdm -#endif // WVCDM_CORE_USAGE_TABLE_HEADER_H_ +#endif // WVCDM_CORE_CDM_USAGE_TABLE_H_ diff --git a/core/include/certificate_provisioning.h b/core/include/certificate_provisioning.h index 8189958b..05751485 100644 --- a/core/include/certificate_provisioning.h +++ b/core/include/certificate_provisioning.h @@ -50,8 +50,6 @@ class CertificateProvisioning { wvutil::FileSystem* file_system, const CdmProvisioningResponse& response, std::string* cert, std::string* wrapped_key); - bool supports_core_messages() const { return supports_core_messages_; } - // Helper methods // Extract serial number and system ID from a DRM Device certificate. @@ -123,13 +121,6 @@ class CertificateProvisioning { // Key type of the generated key pair in provisioning 4. CryptoWrappedKey::Type provisioning_40_key_type_; - // Indicates whether OEMCrypto supports core messages, and whether the - // CDM should expect a core message in the response. This is primarily - // used to distinguish between v16+ OEMCrypto or an earlier version. - // Assume core messages are supported, and check if OEMCrypto populates - // the core message field when calling PrepAndSignProvisioningRequest(). - bool supports_core_messages_ = true; - CORE_DISALLOW_COPY_AND_ASSIGN(CertificateProvisioning); }; diff --git a/core/include/content_key_session.h b/core/include/content_key_session.h index 209242dc..e3681752 100644 --- a/core/include/content_key_session.h +++ b/core/include/content_key_session.h @@ -13,10 +13,12 @@ namespace wvcdm { class ContentKeySession : public KeySession { public: - ContentKeySession(CryptoSessionId oec_session_id, + ContentKeySession(RequestedSecurityLevel security_level, + CryptoSessionId oec_session_id, metrics::CryptoMetrics* metrics) : KeySession(metrics), oec_session_id_(oec_session_id), + security_level_(security_level), cipher_mode_(kCipherModeCtr) {} ~ContentKeySession() override {} @@ -52,6 +54,24 @@ class ContentKeySession : public KeySession { const OEMCrypto_SampleDescription* samples, size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc& pattern) override; + OEMCryptoResult GenericEncrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) override; + + OEMCryptoResult GenericDecrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) override; + + OEMCryptoResult GenericSign(const std::string& message, + OEMCrypto_Algorithm algorithm, + std::string* signature) override; + + OEMCryptoResult GenericVerify(const std::string& message, + OEMCrypto_Algorithm algorithm, + const std::string& signature) override; + protected: virtual OEMCryptoResult LoadKeysAsLicenseType( const std::string& message, const std::string& signature, @@ -60,11 +80,19 @@ class ContentKeySession : public KeySession { const std::string& provider_session_token, const std::string& srm_requirement, OEMCrypto_LicenseType license_type); + OEMCryptoResult GetKeyHandle(CryptoSessionId session_id, + const std::string& key_id, + CdmCipherMode cipher_mode); + CryptoSessionId oec_session_id_; private: + RequestedSecurityLevel security_level_; + KeyId cached_key_id_; CdmCipherMode cipher_mode_; + + std::vector key_handle_; }; } // namespace wvcdm diff --git a/core/include/crypto_session.h b/core/include/crypto_session.h index 7d6cc3a7..c27920fd 100644 --- a/core/include/crypto_session.h +++ b/core/include/crypto_session.h @@ -26,7 +26,7 @@ namespace wvcdm { class CryptoKey; class CryptoSessionFactory; class OtaKeyboxProvisioner; -class UsageTableHeader; +class CdmUsageTable; namespace okp { class SystemFallbackPolicy; @@ -153,17 +153,9 @@ class CryptoSession { // License request/responses virtual CdmResponseType PrepareAndSignLicenseRequest( const std::string& message, std::string* core_message, - std::string* signature); + std::string* signature, bool& should_specify_algorithm, + OEMCrypto_SignatureHashAlgorithm& algorithm); virtual CdmResponseType UseSecondaryKey(bool dual_key); - // V15 licenses. - virtual CdmResponseType LoadKeys(const std::string& message, - const std::string& signature, - const std::string& mac_key_iv, - const std::string& mac_key, - const std::vector& key_array, - const std::string& provider_session_token, - const std::string& srm_requirement, - CdmLicenseKeyType key_type); // V16 licenses. virtual CdmResponseType LoadLicense(const std::string& signed_message, const std::string& core_message, @@ -174,10 +166,6 @@ class CryptoSession { virtual CdmResponseType PrepareAndSignRenewalRequest( const std::string& message, std::string* core_message, std::string* signature); - // V15 licenses. - virtual CdmResponseType RefreshKeys(const std::string& message, - const std::string& signature, - const std::vector& key_array); // V16 licenses. virtual CdmResponseType LoadRenewal(const std::string& signed_message, const std::string& core_message, @@ -193,7 +181,8 @@ class CryptoSession { const std::string& session_key); virtual CdmResponseType PrepareAndSignProvisioningRequest( const std::string& message, std::string* core_message, - std::string* signature); + std::string* signature, bool& should_specify_algorithm, + OEMCrypto_SignatureHashAlgorithm& algorithm); virtual CdmResponseType LoadProvisioning(const std::string& signed_message, const std::string& core_message, const std::string& signature, @@ -228,7 +217,6 @@ class CryptoSession { uint32_t* tier); virtual bool GetSupportedCertificateTypes(SupportedCertificateTypes* support); - virtual CdmResponseType GetRandom(size_t data_length, uint8_t* random_data); virtual CdmResponseType GetNumberOfOpenSessions( RequestedSecurityLevel security_level, size_t* count); virtual CdmResponseType GetMaxNumberOfSessions( @@ -284,13 +272,13 @@ class CryptoSession { // Used to manipulate the CDM managed usage table header & entries, // delegating calls to OEMCrypto. - // Determines whether the OEMCrypto library supports usage info. + // Determines whether the OEMCrypto library supports usage table. // As of V16, the only valid type of support is usage table header + // usage entries. // The first method will use a cached value if present. - virtual bool HasUsageInfoSupport(bool* has_support); - virtual bool HasUsageInfoSupport(RequestedSecurityLevel security_level, - bool* has_support); + virtual bool HasUsageTableSupport(bool* has_support); + virtual bool HasUsageTableSupport(RequestedSecurityLevel security_level, + bool* has_support); // Usage report. virtual CdmResponseType DeactivateUsageInformation( @@ -301,30 +289,28 @@ class CryptoSession { int64_t* seconds_since_started, int64_t* seconds_since_last_played); // Usage table header. - virtual UsageTableHeader* GetUsageTableHeader() { - return usage_table_header_; - } + virtual CdmUsageTable* GetUsageTable() { return usage_table_; } // The following crypto methods do not require an open session to // complete the operations. virtual CdmResponseType CreateUsageTableHeader( RequestedSecurityLevel requested_security_level, - CdmUsageTableHeader* usage_table_header); + UsageTableHeader* usage_table_header); virtual CdmResponseType LoadUsageTableHeader( RequestedSecurityLevel requested_security_level, - const CdmUsageTableHeader& usage_table_header); + const UsageTableHeader& usage_table_header); virtual CdmResponseType ShrinkUsageTableHeader( RequestedSecurityLevel requested_security_level, uint32_t new_entry_count, - CdmUsageTableHeader* usage_table_header); + UsageTableHeader* usage_table_header); // Usage entry. - virtual CdmResponseType CreateUsageEntry(uint32_t* entry_number); - virtual CdmResponseType LoadUsageEntry(uint32_t entry_number, - const CdmUsageEntry& usage_entry); - virtual CdmResponseType UpdateUsageEntry( - CdmUsageTableHeader* usage_table_header, CdmUsageEntry* usage_entry); + virtual CdmResponseType CreateUsageEntry(UsageEntryIndex* entry_index); + virtual CdmResponseType LoadUsageEntry(UsageEntryIndex entry_index, + const UsageEntry& usage_entry); + virtual CdmResponseType UpdateUsageEntry(UsageTableHeader* usage_table_header, + UsageEntry* usage_entry); // Adjust usage entries in usage table header. - virtual CdmResponseType MoveUsageEntry(uint32_t new_entry_number); + virtual CdmResponseType MoveUsageEntry(UsageEntryIndex new_entry_index); virtual bool GetAnalogOutputCapabilities(bool* can_support_output, bool* can_disable_output, @@ -400,11 +386,11 @@ class CryptoSession { void Init(); - // Will set up the UsageTableHeader for this session. This may require - // creating a new UsageTableHeader if the global instance has not + // Will set up the CdmUsageTable for this session. This may require + // creating a new CdmUsageTable if the global instance has not // been initialized. // Note: This function will lock the global static field lock in write mode. - bool SetUpUsageTableHeader(RequestedSecurityLevel requested_security_level); + bool SetUpUsageTable(RequestedSecurityLevel requested_security_level); size_t GetMaxSubsampleRegionSize(); @@ -413,10 +399,10 @@ class CryptoSession { CdmResponseType SelectKey(const std::string& key_id, CdmCipherMode cipher_mode); - // Retrieves the OEMCrypto usage info support for the specified + // Retrieves the OEMCrypto usage table support for the specified // |requested_security_level|. // Caller should acquire the OEMCrypto read lock before calling. - bool HasUsageInfoSupportInternal( + bool HasUsageTableSupportInternal( RequestedSecurityLevel requested_security_level, bool* has_support); // These methods fall back into each other in the order given, depending on @@ -540,12 +526,12 @@ class CryptoSession { RequestedSecurityLevel requested_security_level_; // Open session-cached result of OEMCrypto_SupportsUsageTable(). - CachedBooleanProperty has_usage_info_support_ = kBooleanUnset; - UsageTableHeader* usage_table_header_ = nullptr; + CachedBooleanProperty has_usage_table_support_ = kBooleanUnset; + CdmUsageTable* usage_table_ = nullptr; // These fields are protected by |usage_table_mutex_| and not // |static_field_mutex_|. - static std::unique_ptr usage_table_header_l1_; - static std::unique_ptr usage_table_header_l3_; + static std::unique_ptr usage_table_l1_; + static std::unique_ptr usage_table_l3_; std::string request_id_; static std::atomic request_id_index_source_; diff --git a/core/include/device_files.h b/core/include/device_files.h index 93fd99a8..e2125bea 100644 --- a/core/include/device_files.h +++ b/core/include/device_files.h @@ -68,6 +68,15 @@ class DeviceFiles { kIncorrectFileType = kResponseTypeBase + 14, kIncorrectFileVersion = kResponseTypeBase + 15, kLicenseNotPresent = kResponseTypeBase + 16, + kFileNotFoundEAcces = kResponseTypeBase + 17, + kFileNotFoundEFault = kResponseTypeBase + 18, + kFileNotFoundELoop = kResponseTypeBase + 19, + kFileNotFoundENameTooLong = kResponseTypeBase + 20, + kFileNotFoundENoEnt = kResponseTypeBase + 21, + kFileNotFoundENoMem = kResponseTypeBase + 22, + kFileNotFoundENotDir = kResponseTypeBase + 23, + kFileNotFoundEOverflow = kResponseTypeBase + 24, + kFileNotFoundOther = kResponseTypeBase + 25, }; // Converts the different enum types to a human readable C-string for @@ -75,6 +84,7 @@ class DeviceFiles { static const char* CertificateStateToString(CertificateState state); static const char* CertificateTypeToString(CertificateType type); static const char* ResponseTypeToString(ResponseType type); + static ResponseType ErrnoToResponseType(int errno_value); // CdmLicenseData represents all of the data that is stored in CDM // license file. License data is uniquely keyed using |key_set_id|. @@ -97,8 +107,8 @@ class DeviceFiles { // App parameters. CdmAppParameterMap app_parameters; // Usage entry and index. - CdmUsageEntry usage_entry; - uint32_t usage_entry_number; + UsageEntry usage_entry; + UsageEntryIndex usage_entry_index; std::string drm_certificate; CryptoWrappedKey wrapped_private_key; }; @@ -108,8 +118,8 @@ class DeviceFiles { CdmKeyMessage license_request; CdmKeyResponse license; std::string key_set_id; - CdmUsageEntry usage_entry; - uint32_t usage_entry_number; + UsageEntry usage_entry; + UsageEntryIndex usage_entry_index; std::string drm_certificate; CryptoWrappedKey wrapped_private_key; }; @@ -155,6 +165,9 @@ class DeviceFiles { virtual bool RetrieveLicense(const std::string& key_set_id, CdmLicenseData* license_data, ResponseType* result); + virtual ResponseType StoreAtscLicense( + const CdmKeySetId& key_set_id, + const std::string& serialized_license_data); virtual bool DeleteLicense(const std::string& key_set_id); virtual bool ListLicenses(std::vector* key_set_ids); @@ -180,7 +193,7 @@ class DeviceFiles { const std::string& provider_session_token, const CdmKeyMessage& key_request, const CdmKeyResponse& key_response, const std::string& usage_info_file_name, const std::string& key_set_id, - const CdmUsageEntry& usage_entry, uint32_t usage_entry_number, + const UsageEntry& usage_entry, UsageEntryIndex usage_entry_index, const std::string& drm_certificate, const CryptoWrappedKey& wrapped_key); // Retrieve usage identifying information stored on the file system. @@ -233,8 +246,8 @@ class DeviceFiles { const std::string& provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license_response, - CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number, + UsageEntry* usage_entry, + UsageEntryIndex* usage_entry_index, std::string* drm_certificate, CryptoWrappedKey* wrapped_key); // Retrieve the usage info entry specified by |key_set_id|. @@ -242,8 +255,8 @@ class DeviceFiles { virtual bool RetrieveUsageInfoByKeySetId( const std::string& usage_info_file_name, const std::string& key_set_id, std::string* provider_session_token, CdmKeyMessage* license_request, - CdmKeyResponse* license_response, CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number, std::string* drm_certificate, + CdmKeyResponse* license_response, UsageEntry* usage_entry, + UsageEntryIndex* usage_entry_index, std::string* drm_certificate, CryptoWrappedKey* wrapped_key); // These APIs support upgrading from usage tables to usage tabler header + @@ -262,7 +275,7 @@ class DeviceFiles { const CdmUsageData& usage_data); virtual bool StoreHlsAttributes(const std::string& key_set_id, - const CdmHlsMethod method, + CdmHlsMethod method, const std::vector& media_segment_iv); virtual bool RetrieveHlsAttributes(const std::string& key_set_id, CdmHlsMethod* method, @@ -270,15 +283,15 @@ class DeviceFiles { virtual bool DeleteHlsAttributes(const std::string& key_set_id); virtual bool StoreUsageTableInfo( - const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info); + const UsageTableHeader& usage_table_header, + const std::vector& usage_entry_info_list); // When retrieving usage table information from the file system; any // table that has yet to be updated for the LRU attributes will be // indicated by |lru_upgrade|. virtual bool RetrieveUsageTableInfo( - CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info, bool* lru_upgrade); + UsageTableHeader* usage_table_header, + std::vector* usage_entry_info_list, bool* lru_upgrade); virtual bool DeleteUsageTableInfo(); diff --git a/core/include/entitlement_key_session.h b/core/include/entitlement_key_session.h index 2c33b285..aecd8990 100644 --- a/core/include/entitlement_key_session.h +++ b/core/include/entitlement_key_session.h @@ -17,7 +17,8 @@ namespace wvcdm { class EntitlementKeySession : public ContentKeySession { public: - EntitlementKeySession(CryptoSessionId oec_session_id, + EntitlementKeySession(RequestedSecurityLevel security_level, + CryptoSessionId oec_session_id, metrics::CryptoMetrics* metrics); ~EntitlementKeySession() override; @@ -35,9 +36,6 @@ class EntitlementKeySession : public ContentKeySession { const std::vector& keys) override; OEMCryptoResult SelectKey(const std::string& key_id, CdmCipherMode cipher_mode) override; - OEMCryptoResult Decrypt( - const OEMCrypto_SampleDescription* samples, size_t samples_length, - const OEMCrypto_CENCEncryptPatternDesc& pattern) override; private: // The message is populated with the fields of the provided CryptoKey and the diff --git a/core/include/key_session.h b/core/include/key_session.h index 22d50ea2..36b641fc 100644 --- a/core/include/key_session.h +++ b/core/include/key_session.h @@ -40,6 +40,20 @@ class KeySession { virtual OEMCryptoResult Decrypt( const OEMCrypto_SampleDescription* samples, size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc& pattern) = 0; + virtual OEMCryptoResult GenericEncrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) = 0; + virtual OEMCryptoResult GenericDecrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) = 0; + virtual OEMCryptoResult GenericSign(const std::string& message, + OEMCrypto_Algorithm algorithm, + std::string* signature) = 0; + virtual OEMCryptoResult GenericVerify(const std::string& message, + OEMCrypto_Algorithm algorithm, + const std::string& signature) = 0; protected: metrics::CryptoMetrics* metrics_; diff --git a/core/include/license.h b/core/include/license.h index ea03ed83..112e58d8 100644 --- a/core/include/license.h +++ b/core/include/license.h @@ -82,10 +82,6 @@ class CdmLicense { virtual bool is_offline() const { return is_offline_; } - virtual bool supports_core_messages() const { - return supports_core_messages_; - } - virtual const VersionInfo& GetServiceVersion() { return latest_service_version_; } @@ -110,8 +106,7 @@ class CdmLicense { CdmResponseType HandleContentKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, - const std::string& signature, const std::string& mac_key_iv, - const std::string& mac_key, const std::vector& key_array, + const std::string& signature, const std::vector& key_array, const video_widevine::License& license); // HandleEntitlementKeyResponse loads the entitlement keys in |key_array| into @@ -119,8 +114,7 @@ class CdmLicense { // |wrapped_keys_| and loads them for use. CdmResponseType HandleEntitlementKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, - const std::string& signature, const std::string& mac_key_iv, - const std::string& mac_key, const std::vector& key_array, + const std::string& signature, const std::vector& key_array, const video_widevine::License& license); // Prepare to reload a key update message. Some special code is needed to work @@ -146,11 +140,6 @@ class CdmLicense { std::string provider_session_token_; bool renew_with_client_id_; bool is_offline_; - // Indicates whether the license contains / supports OEMCrypto-level - // support for core messages. If the original license was created before - // upgrading from V15, or if the licensing server is still running V15, - // then the license does not support core messages. - bool supports_core_messages_; // Associated with ClientIdentification encryption bool use_privacy_mode_; diff --git a/core/include/license_key_status.h b/core/include/license_key_status.h index db7b9525..4c32d52f 100644 --- a/core/include/license_key_status.h +++ b/core/include/license_key_status.h @@ -143,7 +143,7 @@ class LicenseKeyStatus { using ConstraintList = ::google::protobuf::RepeatedPtrField; - LicenseKeyStatus(const KeyContainer& key, const CdmSecurityLevel level); + LicenseKeyStatus(const KeyContainer& key, CdmSecurityLevel level); virtual ~LicenseKeyStatus() {} @@ -155,12 +155,12 @@ class LicenseKeyStatus { void SetConstraints(const ConstraintList& constraints); - bool is_content_key_; - CdmKeyStatus key_status_; - bool meets_constraints_; - bool meets_security_level_constraints_; + bool is_content_key_ = false; + CdmKeyStatus key_status_ = kKeyStatusInternalError; + bool meets_constraints_ = true; + bool meets_security_level_constraints_ = true; CdmKeyAllowedUsage allowed_usage_; - CryptoSession::HdcpCapability default_hdcp_level_; + CryptoSession::HdcpCapability default_hdcp_level_ = HDCP_NONE; ConstraintList constraints_; CORE_DISALLOW_COPY_AND_ASSIGN(LicenseKeyStatus); diff --git a/core/include/license_protocol_conversions.h b/core/include/license_protocol_conversions.h new file mode 100644 index 00000000..5805b202 --- /dev/null +++ b/core/include/license_protocol_conversions.h @@ -0,0 +1,17 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#ifndef WVCDM_CORE_LICENSE_PROTOCOL_CONVERSIONS_H_ +#define WVCDM_CORE_LICENSE_PROTOCOL_CONVERSIONS_H_ + +#include + +#include "OEMCryptoCENC.h" +#include "license_protocol.pb.h" + +namespace wvcdm { +bool OecAlgorithmToProtoAlgorithm( + OEMCrypto_SignatureHashAlgorithm oec_algorithm, + video_widevine::HashAlgorithmProto& proto_algorithm); +} // namespace wvcdm +#endif // WVCDM_CORE_LICENSE_PROTOCOL_CONVERSIONS_H_ diff --git a/core/include/oemcrypto_adapter.h b/core/include/oemcrypto_adapter.h index 33a10e1f..afcf32bd 100644 --- a/core/include/oemcrypto_adapter.h +++ b/core/include/oemcrypto_adapter.h @@ -73,94 +73,32 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert, OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport( RequestedSecurityLevel level); OEMCryptoResult OEMCrypto_ProductionReady(RequestedSecurityLevel level); + +OEMCryptoResult OEMCrypto_DecryptCENC( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SampleDescription* samples, + size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc* pattern); +OEMCryptoResult OEMCrypto_Generic_Encrypt( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); +OEMCryptoResult OEMCrypto_Generic_Decrypt( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); +OEMCryptoResult OEMCrypto_Generic_Sign( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* signature, size_t* signature_length); +OEMCryptoResult OEMCrypto_Generic_Verify( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + const OEMCrypto_SharedMemory* signature, size_t signature_length); + } // namespace wvcdm -/* The following functions are deprecated in OEMCrypto v13. They are defined - * here so that core cdm code may be backwards compatible with an OEMCrypto - * v12. - */ -extern "C" { - -typedef struct { // Used for backwards compatibility. - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_data_iv; - const uint8_t* key_data; - size_t key_data_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; -} OEMCrypto_KeyObject_V10; - -typedef struct { // Used for backwards compatibility. - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_data_iv; - const uint8_t* key_data; - size_t key_data_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; - OEMCryptoCipherMode cipher_mode; -} OEMCrypto_KeyObject_V13; - -typedef struct { - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_data_iv; - const uint8_t* key_data; - size_t key_data_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; -} OEMCrypto_KeyObject_V14; - -// Backwards compatibility between v14 and v13. -OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, - OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, - size_t num_keys, const OEMCrypto_KeyObject* key_array, - OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, - OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes); - -OEMCryptoResult OEMCrypto_DeactivateUsageEntry_V12(const uint8_t* pst, - size_t pst_length); -typedef struct { - const uint8_t* entitlement_key_id; - size_t entitlement_key_id_length; - const uint8_t* content_key_id; - size_t content_key_id_length; - const uint8_t* content_key_data_iv; - const uint8_t* content_key_data; - size_t content_key_data_length; -} OEMCrypto_EntitledContentKeyObject_V14; - -typedef struct { - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; -} OEMCrypto_KeyRefreshObject_V14; - -OEMCryptoResult OEMCrypto_LoadKeys_V14( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, - const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, - size_t num_keys, const OEMCrypto_KeyObject_V14* key_array, - const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement, - OEMCrypto_LicenseType license_type); - -OEMCryptoResult OEMCrypto_LoadEntitledContentKeys_V14( - OEMCrypto_SESSION session, size_t num_keys, - const OEMCrypto_EntitledContentKeyObject_V14* key_array); - -OEMCryptoResult OEMCrypto_RefreshKeys_V14( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, size_t num_keys, - const OEMCrypto_KeyRefreshObject_V14* key_array); - -OEMCryptoResult OEMCrypto_CopyBuffer_V14( - const uint8_t* data_addr, size_t data_length, - OEMCrypto_DestBufferDesc* out_buffer_descriptor, uint8_t subsample_flags); - -} // extern "C" - #endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_ diff --git a/core/include/policy_engine.h b/core/include/policy_engine.h index 9ef54364..3819cc34 100644 --- a/core/include/policy_engine.h +++ b/core/include/policy_engine.h @@ -64,7 +64,6 @@ class PolicyEngine { // being restored and transitions and notifications will be deferred until // stored playback times are restored. virtual void SetLicense(const video_widevine::License& license, - bool supports_core_messages, bool defer_license_state_update); // Used to update the currently loaded entitled content keys. @@ -73,8 +72,7 @@ class PolicyEngine { // SetLicenseForRelease is used when releasing a license. The keys in this // license will be ignored, and any old keys will be expired. - virtual void SetLicenseForRelease(const video_widevine::License& license, - bool supports_core_messages); + virtual void SetLicenseForRelease(const video_widevine::License& license); // Call this on first decrypt to set the start of playback. virtual bool BeginDecryption(void); @@ -169,8 +167,8 @@ class PolicyEngine { void SetSecurityLevelForTest(CdmSecurityLevel security_level); - LicenseState license_state_; - int64_t license_state_update_deadline_; + LicenseState license_state_ = kLicenseStateInitial; + int64_t license_state_update_deadline_ = 0; // This is the license id field from server response. This data gets passed // back to the server in each renewal request. When we get a renewal response @@ -178,11 +176,11 @@ class PolicyEngine { video_widevine::LicenseIdentification license_id_; // to assist in clock rollback checks - int64_t last_recorded_current_time_; + int64_t last_recorded_current_time_ = 0; // Used to dispatch CDM events. CdmSessionId session_id_; - WvCdmEventListener* event_listener_; + WvCdmEventListener* event_listener_ = nullptr; // Keys associated with license - holds allowed usage, usage constraints, // and current status (CdmKeyStatus) @@ -193,9 +191,9 @@ class PolicyEngine { video_widevine::License::Policy policy_; // Device checks - int64_t next_device_check_; - uint32_t current_resolution_; - CryptoSession* crypto_session_; + int64_t next_device_check_ = 0; + uint32_t current_resolution_ = 0; + CryptoSession* crypto_session_ = nullptr; std::unique_ptr policy_timers_; std::unique_ptr clock_; diff --git a/core/include/policy_timers.h b/core/include/policy_timers.h index 4287b0cf..b5bc0f83 100644 --- a/core/include/policy_timers.h +++ b/core/include/policy_timers.h @@ -10,6 +10,7 @@ #include "disallow_copy_and_assign.h" #include "license_protocol.pb.h" +#include "wv_cdm_constants.h" #include "wv_cdm_types.h" namespace wvcdm { @@ -43,20 +44,45 @@ class PolicyTimers { // For offline save and restore virtual int64_t GetPlaybackStartTime() { return playback_start_time_; } virtual int64_t GetLastPlaybackTime() { return last_playback_time_; } - virtual int64_t GetGracePeriodEndTime() = 0; + // This is a legacy field for offline licenses. Since no grace period is + // supported return a default value. + virtual int64_t GetGracePeriodEndTime() { return 0; } virtual void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, int64_t last_playback_time, - int64_t grace_period_end_time) = 0; + int64_t grace_period_end_time); - virtual bool HasPlaybackStarted(int64_t current_time) = 0; + virtual bool HasPlaybackStarted(int64_t /* current_time */) { + return playback_start_time_ != 0; + } + + // For licenses that support core messages, evaluation of only rental and + // playback durations are needed. virtual bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) = 0; - virtual bool HasPassedGracePeriod(int64_t current_time) = 0; + int64_t current_time) { + return HasRentalOrPlaybackDurationExpired(current_time); + } + virtual bool HasPassedGracePeriod(int64_t /* current_time */) { return true; } + // This returns + // * before playback begins: the time remaining on |rental_duration_seconds| + // * after playback begins: + // - |soft_enforce_playback_duration| is true: the time remaining on + // |playback_duration_seconds| + // - |soft_enforce_playback_duration| is false: the minimum + // of the time remaining on |rental_duration_seconds| or + // |playback_duration_seconds| + // + // |license_duration_seconds| is ignored with the introduction of core + // messages virtual int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) = 0; - virtual int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) = 0; + int64_t current_time); + // This is only used in Query. This should return the time remaining on + // |rental_duration_seconds|. + virtual int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) { + return GetRentalDurationRemaining(current_time); + }; + // This is only used in Query. This should return |playback_duration_seconds| // before playback begins or the time remaining on // |playback_duration_seconds| after playback begins. @@ -72,7 +98,7 @@ class PolicyTimers { virtual bool UpdateExpirationTime(int64_t current_time, int64_t* expiry_time); // Renewal related methods - virtual bool HasRenewalDelayExpired(int64_t current_time); + virtual bool HasRenewalDelayExpired(int64_t current_time) = 0; virtual bool HasRenewalRetryIntervalExpired(int64_t current_time); virtual void UpdateRenewalRequest(int64_t current_time); virtual bool HasRenewalRecoveryDurationExpired(int64_t current_time); @@ -90,11 +116,11 @@ class PolicyTimers { was_expired_on_load_(false) {} // Gets the clock time that the license expires based on whether we have - // started playing. + // started playing. This takes into account GetHardLicenseExpiryTime. virtual int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) = 0; - - virtual int64_t GetRenewalStartTime() = 0; + bool ignore_soft_enforce_playback_duration); + virtual int64_t GetRentalExpiryTime(int64_t current_time); + virtual int64_t GetRenewalStartTime() { return renewal_start_time_; } // This is the current policy information for this license. This gets updated // as license renewals occur. @@ -105,12 +131,19 @@ class PolicyTimers { int64_t last_playback_time_; int64_t last_expiry_time_; int64_t last_expiry_time_set_; + int64_t renewal_start_time_ = 0; int64_t next_renewal_time_; // Indicates whether a persistent license was expired when loaded bool was_expired_on_load_; private: + // Gets the clock time that the rental duration or playback will expire. + virtual int64_t GetPlaybackExpiryTime( + int64_t current_time, bool ignore_soft_enforce_playback_duration); + bool HasRentalOrPlaybackDurationExpired(int64_t current_time); + virtual int64_t GetRentalDurationRemaining(int64_t current_time); + CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimers); }; diff --git a/core/include/policy_timers_v15.h b/core/include/policy_timers_v15.h deleted file mode 100644 index a9f42c2d..00000000 --- a/core/include/policy_timers_v15.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine License -// Agreement. - -#ifndef WVCDM_CORE_POLICY_TIMERS_V15_H_ -#define WVCDM_CORE_POLICY_TIMERS_V15_H_ - -#include -#include - -#include "disallow_copy_and_assign.h" -#include "license_protocol.pb.h" -#include "policy_timers.h" -#include "wv_cdm_types.h" - -namespace wvcdm { - -// OEMCrypto v16 and core messages introduced changes to how duration values -// and clocks should be evaluated. This class provides backward compatibility -// for licenses that do not include a core message. Durations are handled -// in the same way as in earlier releases. -// -// Backward compatibility may be needed if -// * OEMCrypto has not been upgraded to v16 -// * Licenses were persisted before the device was upgraded to v16 -// * License service does not yet support core messages - -class PolicyTimersV15 : public PolicyTimers { - public: - PolicyTimersV15() : grace_period_end_time_(0) {} - - ~PolicyTimersV15() override {} - - // UpdateLicense is used in handling a license response, a renewal response, - // or when restoring or releasing a persistent license. - // In a renewal the response may only contain policy fields that have - // changed. In this case an exact copy is not what we want to happen. - // |license_start_time_| is updated to the time mentioned in the renewal - // response. - // UpdateLicense will return false if |license_start_time| is not - // present or playback is not allowed due to policy or timer duration - // expiration. - bool UpdateLicense(int64_t current_time, - const video_widevine::License& license) override; - - // Call this on first decrypt to set the start of playback. - void BeginDecryption(int64_t current_time) override; - - // for offline save and restore - int64_t GetGracePeriodEndTime() override { return grace_period_end_time_; } - - // for offline save and restore - void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, - int64_t last_playback_time, - int64_t grace_period_end_time) override; - - bool HasPlaybackStarted(int64_t current_time) override; - bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) override; - bool HasPassedGracePeriod(int64_t current_time) override; - - // This returns - // * for streaming licenses: the time remaining on |license_duration_seconds| - // * for persistent licenses: the time remaining on |rental_duration_seconds| - // before playback begins or the time remaining on - // |playback_duration_seconds| after. - int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) override; - // This is only used in Query. This should return the time remaining on - // |license_duration_seconds| for streaming licenses and - // |rental_duration_seconds| for persistent licenses. - int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) override; - - protected: - // Gets the clock time that the license expires based on whether we have - // started playing. This takes into account GetHardLicenseExpiryTime. - int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) override; - - int64_t GetRenewalStartTime() override { return license_start_time_; } - - private: - // Gets the clock time that the license expires. This is the hard limit that - // all license types must obey at all times. - int64_t GetHardLicenseExpiryTime(); - // Gets the clock time that the rental duration will expire, using the license - // duration if one is not present. - int64_t GetRentalExpiryTime(); - - int64_t grace_period_end_time_; - - CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV15); -}; - -} // namespace wvcdm - -#endif // WVCDM_CORE_POLICY_TIMERS_V15_H_ diff --git a/core/include/policy_timers_v16.h b/core/include/policy_timers_v16.h index 2e0c472d..15adc6c7 100644 --- a/core/include/policy_timers_v16.h +++ b/core/include/policy_timers_v16.h @@ -43,68 +43,10 @@ class PolicyTimersV16 : public PolicyTimers { // Call this on first decrypt to set the start of playback. void BeginDecryption(int64_t current_time) override; - // This is a legacy field for offline licenses. Since no grace period is - // supported return a default value. - int64_t GetGracePeriodEndTime() override { return 0; } - - // For offline save and restore. - void RestorePlaybackTimes(int64_t current_time, int64_t playback_start_time, - int64_t last_playback_time, - int64_t grace_period_end_time) override; - - bool HasPlaybackStarted(int64_t /* current_time */) override { - return playback_start_time_ != 0; - } - // For licenses that support core messages, evaluation of only rental and - // playback durations are needed. - bool HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) override { - return HasRentalOrPlaybackDurationExpired(current_time); - } - bool HasPassedGracePeriod(int64_t /* current_time */) override { - return true; - } - - // This returns - // * before playback begins: the time remaining on |rental_duration_seconds| - // * after playback begins: - // - |soft_enforce_playback_duration| is true: the time remaining on - // |playback_duration_seconds| - // - |soft_enforce_playback_duration| is false: the minimum - // of the time remaining on |rental_duration_seconds| or - // |playback_duration_seconds| - // - // |license_duration_seconds| is ignored with the introduction of core - // messages - int64_t GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) override; - // This is only used in Query. This should return the time remaining on - // |rental_duration_seconds|. - int64_t GetLicenseOrRentalDurationRemaining(int64_t current_time) override { - return GetRentalDurationRemaining(current_time); - }; - + // Renewal related methods bool HasRenewalDelayExpired(int64_t current_time) override; - protected: - // Gets the clock time that the license expires based on whether we have - // started playing. This takes into account GetHardLicenseExpiryTime. - int64_t GetExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration) override; - - int64_t GetRenewalStartTime() override { return renewal_start_time_; } - private: - // Gets the clock time that the rental duration or playback will expire. - int64_t GetRentalExpiryTime(int64_t current_time); - int64_t GetPlaybackExpiryTime(int64_t current_time, - bool ignore_soft_enforce_playback_duration); - - bool HasRentalOrPlaybackDurationExpired(int64_t current_time); - int64_t GetRentalDurationRemaining(int64_t current_time); - - int64_t renewal_start_time_ = 0; - CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV16); }; diff --git a/core/include/policy_timers_v18.h b/core/include/policy_timers_v18.h new file mode 100644 index 00000000..e8048522 --- /dev/null +++ b/core/include/policy_timers_v18.h @@ -0,0 +1,57 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#ifndef WVCDM_CORE_POLICY_TIMERS_V18_H_ +#define WVCDM_CORE_POLICY_TIMERS_V18_H_ + +#include "disallow_copy_and_assign.h" +#include "license_protocol.pb.h" +#include "policy_timers.h" +#include "wv_cdm_types.h" + +namespace wvcdm { + +// OEMCrypto v18 includes support for renewing licenses on load by using +// |initial_renewal_delay_base| and TimerDelayBase. +// +// Backward compatibility may be needed if +// * OEMCrypto has not been upgraded to v18 +// * Licenses were persisted before the device was upgraded to v18 + +class PolicyTimersV18 : public PolicyTimers { + public: + PolicyTimersV18() {} + + ~PolicyTimersV18() override {} + + // UpdateLicense is used in handling a license response, a renewal response, + // or when restoring or releasing a persistent license. + // In a renewal the response may only contain policy fields that have + // changed. In this case an exact copy is not what we want to happen. + // |renewal_start_time_| is set to the time mentioned in the renewal + // response. + // UpdateLicense will return false if |license_start_time| is not + // present or playback is not allowed due to policy or timer duration + // expiration. + bool UpdateLicense(int64_t current_time, + const video_widevine::License& license) override; + + // Call this on first decrypt to set the start of playback. + void BeginDecryption(int64_t current_time) override; + + // Renewal related methods + bool HasRenewalDelayExpired(int64_t current_time) override; + + private: + // Indicates whether this is an initial license or a renewal + bool license_renewal_ = false; + bool renew_on_first_decrypt_ = false; + bool can_renew_ = false; + + CORE_DISALLOW_COPY_AND_ASSIGN(PolicyTimersV18); +}; + +} // namespace wvcdm + +#endif // WVCDM_CORE_POLICY_TIMERS_V18_H_ diff --git a/core/include/properties.h b/core/include/properties.h index 360cac5c..3ff6f055 100644 --- a/core/include/properties.h +++ b/core/include/properties.h @@ -78,7 +78,7 @@ class Properties { static bool GetDeviceFilesBasePath(CdmSecurityLevel security_level, std::string* base_path); static bool GetFactoryKeyboxPath(std::string* keybox); - static bool GetOEMCryptoPath(std::string* library_name); + static bool GetOEMCryptoPaths(std::vector* library_name); static bool GetSandboxId(std::string* sandbox_id); static bool AlwaysUseKeySetIds(); static bool UseProviderIdInProvisioningRequest(); diff --git a/core/include/wv_cdm_constants.h b/core/include/wv_cdm_constants.h index 4aaaaff6..3c49ff5d 100644 --- a/core/include/wv_cdm_constants.h +++ b/core/include/wv_cdm_constants.h @@ -51,6 +51,9 @@ constexpr uint32_t RESOURCE_RATING_TIER_MAX = RESOURCE_RATING_TIER_VERY_HIGH; // OEMCrypto features by version constexpr uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER = 15; +constexpr uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_PROV40_CORE_MESSAGE = 18; +constexpr uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_INITIAL_RENEWAL_DELAY_BASE = + 18; constexpr char SESSION_ID_PREFIX[] = "sid"; constexpr char ATSC_KEY_SET_ID_PREFIX[] = "atscksid"; @@ -61,11 +64,8 @@ constexpr char ATSC_APP_PACKAGE_NAME[] = "org.atsc"; // Define query keys, values here. // To expose these query items to Android update: // android/mediadrm/src/WVDrmPlugin.cpp -// android/mediadrm/src_hidl/WVDrmPlugin.cpp // Update test QueryStatus and QueryStatusL3 test for all possible outputs: // android/cdm/test/request_license_test.cpp -// Update HIDL debug output: -// android/src_hidl/WVDrmFactory.cpp static const std::string QUERY_KEY_LICENSE_TYPE = "LicenseType"; // "Streaming", "Offline" static const std::string QUERY_KEY_PLAY_ALLOWED = @@ -121,6 +121,9 @@ static const std::string QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT = "CanDisableAnalogOutput"; static const std::string QUERY_KEY_WATERMARKING_SUPPORT = "WatermarkingSupport"; static const std::string QUERY_KEY_PRODUCTION_READY = "ProductionReady"; +// Internal query key. Should not be exposed to Android apps. +static const std::string QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN = + "DebugBootCertificateChain"; static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; @@ -141,6 +144,11 @@ static const std::string QUERY_VALUE_HDCP_V2_0 = "HDCP-2.0"; static const std::string QUERY_VALUE_HDCP_V2_1 = "HDCP-2.1"; static const std::string QUERY_VALUE_HDCP_V2_2 = "HDCP-2.2"; static const std::string QUERY_VALUE_HDCP_V2_3 = "HDCP-2.3"; +static const std::string QUERY_VALUE_HDCP_V1_0 = "HDCP-1.0"; +static const std::string QUERY_VALUE_HDCP_V1_1 = "HDCP-1.1"; +static const std::string QUERY_VALUE_HDCP_V1_2 = "HDCP-1.2"; +static const std::string QUERY_VALUE_HDCP_V1_3 = "HDCP-1.3"; +static const std::string QUERY_VALUE_HDCP_V1_4 = "HDCP-1.4"; static const std::string QUERY_VALUE_HDCP_LEVEL_UNKNOWN = "HDCP-LevelUnknown"; static const std::string QUERY_VALUE_DRM_CERTIFICATE = "DrmCertificate"; static const std::string QUERY_VALUE_KEYBOX = "Keybox"; diff --git a/core/include/wv_cdm_types.h b/core/include/wv_cdm_types.h index e6ffd370..55a586b3 100644 --- a/core/include/wv_cdm_types.h +++ b/core/include/wv_cdm_types.h @@ -12,6 +12,8 @@ #include #include +#include "OEMCryptoCENC.h" + namespace wvcdm { using CdmKeySystem = std::string; @@ -19,11 +21,9 @@ using CdmInitData = std::string; using CdmKeyMessage = std::string; using CdmKeyResponse = std::string; using KeyId = std::string; -using CdmSecureStopId = std::string; using CdmSessionId = std::string; using CdmKeySetId = std::string; using RequestId = std::string; -using CryptoResult = uint32_t; using CryptoSessionId = uint32_t; using EntitledKeySessionId = uint32_t; using CdmAppParameterMap = std::map; @@ -32,8 +32,16 @@ using CdmUsageInfo = std::vector; using CdmUsageInfoReleaseMessage = std::string; using CdmProvisioningRequest = std::string; using CdmProvisioningResponse = std::string; -using CdmUsageTableHeader = std::string; -using CdmUsageEntry = std::string; + +// OEMCrypto's usage table information. +using UsageTableHeader = std::string; +using UsageEntry = std::string; +using UsageEntryIndex = uint32_t; + +// Secure stop related data types. +using CdmSecureStopId = std::string; +using CdmUsageReport = std::string; +using CdmUsageReportList = std::vector; enum CdmKeyRequestType : uint32_t { kKeyRequestTypeUnknown, @@ -50,7 +58,7 @@ enum CdmOfflineLicenseState : int32_t { kLicenseStateUnknown, }; -enum CdmResponseType : int32_t { +enum CdmResponseEnum : int32_t { NO_ERROR = 0, UNKNOWN_ERROR = 1, KEY_ADDED = 2, @@ -454,11 +462,73 @@ enum CdmResponseType : int32_t { SESSION_NOT_FOUND_GENERIC_CRYPTO = 396, SESSION_NOT_FOUND_24 = 397, // Don't forget to add new values to - // * core/test/test_printers.cpp. + // * core/src/wv_cdm_types.cpp // * android/include/mapErrors-inl.h - // * android/include_hidl/mapErrors-inl.h }; +class CdmResponseType { + public: + constexpr CdmResponseType() {} + constexpr explicit CdmResponseType(CdmResponseEnum code) : code_(code) {} + constexpr CdmResponseType(CdmResponseEnum code, OEMCryptoResult oemc_result, + const char* crypto_session_method) + : code_(code), + has_oemc_result_(true), + oemc_result_(oemc_result), + crypto_session_method_(crypto_session_method) {} + + constexpr bool IsOk() const { + return (code_ == NO_ERROR) && + (!HasOemcResult() || (oemc_result_ == OEMCrypto_SUCCESS)); + } + + constexpr explicit operator CdmResponseEnum() const { return code_; }; + constexpr CdmResponseEnum code() const { return code_; }; + // Returns the string representation of |code_|, ignores + // the other fields. + const char* GetCodeString() const; + + constexpr bool HasOemcResult() const { return has_oemc_result_; } + constexpr OEMCryptoResult oemc_result() const { return oemc_result_; } + + constexpr bool HasCryptoSessionMethod() const { + return crypto_session_method_ != nullptr; + } + constexpr const char* crypto_session_method() const { + return crypto_session_method_; + } + + constexpr int ToInt() const { return static_cast(code_); } + constexpr explicit operator int() const { return ToInt(); }; + + bool operator==(CdmResponseEnum other) const { return code_ == other; } + bool operator!=(CdmResponseEnum other) const { return code_ != other; } + bool operator==(const CdmResponseType& other) const; + bool operator!=(const CdmResponseType& other) const { + return !(*this == other); + } + + std::string ToString() const; + + private: + CdmResponseEnum code_ = NO_ERROR; + // Setting |oemc_result_| is optional, only set if |has_oemc_result_| + // is true. + // TODO(b/254108623): Remove |has_oemc_result_| and replace |oemc_result_| + // with std::optional. + bool has_oemc_result_ = false; + OEMCryptoResult oemc_result_ = OEMCrypto_SUCCESS; + const char* crypto_session_method_ = nullptr; +}; + +inline bool operator==(const CdmResponseEnum lhs, const CdmResponseType& rhs) { + return lhs == rhs.code(); +} + +inline bool operator!=(const CdmResponseEnum lhs, const CdmResponseType& rhs) { + return lhs != rhs.code(); +} + enum CdmKeyStatus : int32_t { kKeyStatusKeyUnknown, kKeyStatusUsable, @@ -636,17 +706,14 @@ class CdmKeyAllowedUsage { } bool Equals(const CdmKeyAllowedUsage& other) { - if (!valid_ || !other.Valid() || - decrypt_to_clear_buffer != other.decrypt_to_clear_buffer || - decrypt_to_secure_buffer != other.decrypt_to_secure_buffer || - generic_encrypt != other.generic_encrypt || - generic_decrypt != other.generic_decrypt || - generic_sign != other.generic_sign || - generic_verify != other.generic_verify || - key_security_level_ != other.key_security_level_) { - return false; - } - return true; + return valid_ && other.Valid() && + decrypt_to_clear_buffer == other.decrypt_to_clear_buffer && + decrypt_to_secure_buffer == other.decrypt_to_secure_buffer && + generic_encrypt == other.generic_encrypt && + generic_decrypt == other.generic_decrypt && + generic_sign == other.generic_sign && + generic_verify == other.generic_verify && + key_security_level_ == other.key_security_level_; } bool decrypt_to_clear_buffer; @@ -855,6 +922,7 @@ const char* CdmClientTokenTypeToString(CdmClientTokenType type); const char* CdmLicenseTypeToString(CdmLicenseType license_type); const char* CdmOfflineLicenseStateToString( CdmOfflineLicenseState license_state); +const char* CdmResponseEnumToString(CdmResponseEnum cdm_response_enum); const char* CdmSecurityLevelToString(CdmSecurityLevel security_level); const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type); const char* RequestedSecurityLevelToString( @@ -873,6 +941,9 @@ const char* IdToString(const std::string& id); // Some CDM API function allow for optional string parameters to be // provided as string pointers. const char* IdPtrToString(const std::string* id); + +// Logging utilities for OEMCrypto types. +const char* OemCryptoResultToString(OEMCryptoResult result); } // namespace wvcdm #endif // WVCDM_CORE_WV_CDM_TYPES_H_ diff --git a/core/src/Android.bp b/core/src/Android.bp index 5b6afc36..77c84584 100644 --- a/core/src/Android.bp +++ b/core/src/Android.bp @@ -8,6 +8,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } @@ -17,8 +18,8 @@ cc_library { vendor: true, srcs: [ - "license_protocol.proto", - "device_files.proto", + "license_protocol.proto", + "device_files.proto", ], cflags: [ @@ -34,4 +35,5 @@ cc_library { static_libs: ["libcdm_metrics_protos"], whole_static_libs: ["libcdm_metrics_protos"], export_static_lib_headers: ["libcdm_metrics_protos"], + min_sdk_version: "UpsideDownCake", } diff --git a/core/src/cdm_engine.cpp b/core/src/cdm_engine.cpp index 8a062f31..ccbe11f7 100644 --- a/core/src/cdm_engine.cpp +++ b/core/src/cdm_engine.cpp @@ -33,6 +33,37 @@ namespace wvcdm { namespace { const uint64_t kReleaseSessionTimeToLive = 60; // seconds const uint32_t kUpdateUsageInformationPeriod = 60; // seconds + +std::string MapHdcpVersion(CryptoSession::HdcpCapability version) { + switch (version) { + case HDCP_NONE: + return QUERY_VALUE_HDCP_NONE; + case HDCP_V1: + return QUERY_VALUE_HDCP_V1; + case HDCP_V2: + return QUERY_VALUE_HDCP_V2_0; + case HDCP_V2_1: + return QUERY_VALUE_HDCP_V2_1; + case HDCP_V2_2: + return QUERY_VALUE_HDCP_V2_2; + case HDCP_V2_3: + return QUERY_VALUE_HDCP_V2_3; + // V17 and forward. + case HDCP_V1_0: + return QUERY_VALUE_HDCP_V1_0; + case HDCP_V1_1: + return QUERY_VALUE_HDCP_V1_1; + case HDCP_V1_2: + return QUERY_VALUE_HDCP_V1_2; + case HDCP_V1_3: + return QUERY_VALUE_HDCP_V1_3; + case HDCP_V1_4: + return QUERY_VALUE_HDCP_V1_4; + case HDCP_NO_DIGITAL_OUTPUT: + return QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT; + } + return QUERY_VALUE_HDCP_LEVEL_UNKNOWN; +} } // namespace class UsagePropertySet : public CdmClientPropertySet { @@ -64,18 +95,17 @@ class UsagePropertySet : public CdmClientPropertySet { CdmEngine::CdmEngine(wvutil::FileSystem* file_system, std::shared_ptr metrics) - : metrics_(metrics), - file_system_(file_system), - spoid_(EMPTY_SPOID), - usage_session_(), - usage_property_set_(), - last_usage_information_update_time_(0) { + : metrics_(metrics), file_system_(file_system), spoid_(EMPTY_SPOID) { assert(file_system); Properties::Init(); } CdmEngine::~CdmEngine() { - usage_session_.reset(); + { + std::unique_lock lock(usage_session_mutex_); + usage_session_.reset(); + } + std::unique_lock lock(session_map_lock_); session_map_.Terminate(); } @@ -103,21 +133,21 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, CdmSessionId* session_id) { if (!ValidateKeySystem(key_system)) { LOGI("Invalid key system: %s", IdToString(key_system)); - return INVALID_KEY_SYSTEM; + return CdmResponseType(INVALID_KEY_SYSTEM); } if (session_id == nullptr && forced_session_id == nullptr) { LOGE("Input |forced_session_id| and output |session_id| are both null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (forced_session_id != nullptr) { if (forced_session_id->empty()) { // This should be enforce by the CE CDM code. - return EMPTY_SESSION_ID; + return CdmResponseType(EMPTY_SESSION_ID); } if (session_map_.Exists(*forced_session_id)) { - return DUPLICATE_SESSION_ID_SPECIFIED; + return CdmResponseType(DUPLICATE_SESSION_ID_SPECIFIED); } LOGD("forced_session_id = %s", IdPtrToString(forced_session_id)); } @@ -158,7 +188,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, forced_level3 = true; } else { // OKP is required. - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); } } else { std::unique_lock lock(okp_mutex_); @@ -188,7 +218,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, std::unique_lock lock(session_map_lock_); session_map_.Add(id, new_session.release()); if (session_id) *session_id = id; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::OpenKeySetSession( @@ -197,7 +227,7 @@ CdmResponseType CdmEngine::OpenKeySetSession( LOGI("key_set_id = %s", IdToString(key_set_id)); if (key_set_id.empty()) { LOGE("Invalid key set ID"); - return EMPTY_KEYSET_ID_ENG_1; + return CdmResponseType(EMPTY_KEYSET_ID_ENG_1); } // If in-use, release key set before re-opening, to avoid leaking @@ -224,7 +254,7 @@ CdmResponseType CdmEngine::OpenKeySetSession( release_key_sets_[key_set_id] = std::make_pair( session_id, clock_.GetCurrentTime() + kReleaseSessionTimeToLive); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { @@ -232,10 +262,10 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { std::unique_lock lock(session_map_lock_); if (!session_map_.CloseSession(session_id)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_1; + return CdmResponseType(SESSION_NOT_FOUND_1); } metrics_->ConsolidateSessions(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) { @@ -246,7 +276,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) { CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); - return KEYSET_ID_NOT_FOUND_1; + return CdmResponseType(KEYSET_ID_NOT_FOUND_1); } session_id = iter->second.first; } @@ -273,7 +303,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( CdmLicenseTypeToString(license_type)); if (key_request == nullptr) { LOGE("Output |key_request| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } CdmSessionId id = session_id; @@ -283,19 +313,19 @@ CdmResponseType CdmEngine::GenerateKeyRequest( !Properties::AlwaysUseKeySetIds()) { if (key_set_id.empty()) { LOGE("Invalid key set ID"); - return EMPTY_KEYSET_ID_ENG_2; + return CdmResponseType(EMPTY_KEYSET_ID_ENG_2); } if (!session_id.empty()) { LOGE("Session ID should be empty: session_id = %s", IdToString(session_id)); - return INVALID_SESSION_ID; + return CdmResponseType(INVALID_SESSION_ID); } std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); - return KEYSET_ID_NOT_FOUND_2; + return CdmResponseType(KEYSET_ID_NOT_FOUND_2); } id = iter->second.first; @@ -304,7 +334,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( std::shared_ptr session; if (!session_map_.FindSession(id, &session)) { LOGE("Session not found: session_id = %s", IdToString(id)); - return SESSION_NOT_FOUND_2; + return CdmResponseType(SESSION_NOT_FOUND_2); } key_request->message.clear(); @@ -341,7 +371,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( LOGD("key_request = (%zu) %s", key_request->message.size(), wvutil::Base64SafeEncode(key_request->message).c_str()); - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, @@ -352,7 +382,7 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, IdPtrToString(key_set_id)); if (license_type == nullptr) { LOGE("Output |license_type| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } CdmSessionId id = session_id; @@ -360,19 +390,19 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, if (license_type_release) { if (key_set_id == nullptr) { LOGE("Input/output |key_set_id| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (key_set_id->empty()) { LOGE("Invalid key set ID"); - return EMPTY_KEYSET_ID_ENG_3; + return CdmResponseType(EMPTY_KEYSET_ID_ENG_3); } std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(*key_set_id); if (iter == release_key_sets_.end()) { LOGE("Key set not found: key_set_id = %s", IdPtrToString(key_set_id)); - return KEYSET_ID_NOT_FOUND_3; + return CdmResponseType(KEYSET_ID_NOT_FOUND_3); } id = iter->second.first; } else { @@ -383,15 +413,15 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, std::shared_ptr session; if (!session_map_.FindSession(id, &session)) { LOGE("Session not found: session_id = %s", IdToString(id)); - return SESSION_NOT_FOUND_3; + return CdmResponseType(SESSION_NOT_FOUND_3); } if (key_data.empty()) { LOGE("No key data"); - return EMPTY_KEY_DATA_1; + return CdmResponseType(EMPTY_KEY_DATA_1); } - CdmResponseType sts = KEY_ADDED; + CdmResponseType sts(KEY_ADDED); { // TODO(rfrias): Refactor. For now lock while adding keys to prevent // a race condition between this and the decryption thread. This may @@ -423,7 +453,7 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, } } - switch (sts) { + switch (sts.code()) { case KEY_ADDED: break; case NEED_KEY: @@ -444,13 +474,13 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, IdToString(key_set_id)); if (key_set_id.empty()) { LOGI("Invalid key set ID"); - return EMPTY_KEYSET_ID_ENG_4; + return CdmResponseType(EMPTY_KEYSET_ID_ENG_4); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_4; + return CdmResponseType(SESSION_NOT_FOUND_4); } int error_detail = NO_ERROR; @@ -471,10 +501,10 @@ CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) { std::unique_lock lock(session_map_lock_); if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_5; + return CdmResponseType(SESSION_NOT_FOUND_5); } session->RemoveKeys(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::RemoveLicense(const CdmSessionId& session_id) { @@ -483,7 +513,7 @@ CdmResponseType CdmEngine::RemoveLicense(const CdmSessionId& session_id) { std::unique_lock lock(session_map_lock_); if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_19; + return CdmResponseType(SESSION_NOT_FOUND_19); } return session->RemoveLicense(); } @@ -493,12 +523,12 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( LOGI("session_id = %s", IdToString(session_id)); if (key_request == nullptr) { LOGE("Output |key_request| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_6; + return CdmResponseType(SESSION_NOT_FOUND_6); } key_request->message.clear(); const CdmResponseType sts = session->GenerateRenewalRequest(key_request); @@ -507,7 +537,7 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( static_cast(sts)); return sts; } - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, @@ -515,12 +545,12 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, LOGI("session_id = %s", IdToString(session_id)); if (key_data.empty()) { LOGE("No key data"); - return EMPTY_KEY_DATA_2; + return CdmResponseType(EMPTY_KEY_DATA_2); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_7; + return CdmResponseType(SESSION_NOT_FOUND_7); } CdmResponseType sts; M_TIME(sts = session->RenewKey(key_data), session->GetMetrics(), @@ -530,7 +560,7 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, static_cast(sts)); return sts; } - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } CdmResponseType CdmEngine::SetSessionServiceCertificate( @@ -539,7 +569,7 @@ CdmResponseType CdmEngine::SetSessionServiceCertificate( std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_22; + return CdmResponseType(SESSION_NOT_FOUND_22); } return session->SetServiceCertificate(service_certificate); } @@ -551,7 +581,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, RequestedSecurityLevelToString(security_level), IdToString(query_token)); if (query_response == nullptr) { LOGE("Output |query_response| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::unique_ptr crypto_session( CryptoSession::MakeCryptoSession(metrics_->GetCryptoMetrics())); @@ -585,9 +615,9 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, default: LOGW("Unknown security level: %d", static_cast(found_security_level)); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL || query_token == QUERY_KEY_MAX_HDCP_LEVEL) { @@ -602,18 +632,18 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, } *query_response = MapHdcpVersion( query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ? current_hdcp : max_hdcp); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_USAGE_SUPPORT) { bool supports_usage_reporting; - const bool got_info = crypto_session->HasUsageInfoSupport( + const bool got_info = crypto_session->HasUsageTableSupport( security_level, &supports_usage_reporting); if (!got_info) { - LOGW("HasUsageInfoSupport failed"); + LOGW("HasUsageTableSupport failed"); metrics_->GetCryptoMetrics() ->crypto_session_usage_information_support_.SetError(got_info); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } metrics_->GetCryptoMetrics() ->crypto_session_usage_information_support_.Record( @@ -621,7 +651,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, *query_response = supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { size_t number_of_open_sessions; @@ -633,7 +663,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, return status; } *query_response = std::to_string(number_of_open_sessions); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { size_t maximum_number_of_sessions = 0; @@ -645,16 +675,16 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, return status; } *query_response = std::to_string(maximum_number_of_sessions); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { uint32_t api_version; if (!crypto_session->GetApiVersion(security_level, &api_version)) { LOGW("GetApiVersion failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = std::to_string(api_version); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { uint16_t current_srm_version; @@ -662,54 +692,54 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, crypto_session->GetSrmVersion(¤t_srm_version); if (status == NO_ERROR) { *query_response = std::to_string(current_srm_version); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (status == NO_SRM_VERSION) { // SRM is not supported or not applicable (ex. local display only). *query_response = QUERY_VALUE_NONE; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } LOGW("GetCurrentSRMVersion failed: status = %d", static_cast(status)); return status; } if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { *query_response = QUERY_VALUE_FALSE; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_WVCDM_VERSION) { std::string cdm_version; if (!Properties::GetWVCdmVersion(&cdm_version)) { LOGW("GetWVCdmVersion failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = cdm_version; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_RESOURCE_RATING_TIER) { uint32_t tier; if (!crypto_session->GetResourceRatingTier(security_level, &tier)) { LOGW("GetResourceRatingTier failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = std::to_string(tier); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION) { if (!crypto_session->GetBuildInformation(security_level, query_response)) { LOGW("GetBuildInformation failed"); query_response->clear(); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_DECRYPT_HASH_SUPPORT) { uint32_t hash_support = 0; if (!crypto_session->GetDecryptHashSupport(security_level, &hash_support)) { LOGW("GetDecryptHashSupport failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = std::to_string(hash_support); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_PROVISIONING_MODEL) { CdmClientTokenType token_type = kClientTokenUninitialized; @@ -737,16 +767,16 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, default: LOGW("GetProvisioningMethod returned invalid method: token_type = %d", static_cast(token_type)); - return GET_PROVISIONING_METHOD_ERROR; + return CdmResponseType(GET_PROVISIONING_METHOD_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_MAX_USAGE_TABLE_ENTRIES) { size_t max_number_of_usage_entries; if (!crypto_session->GetMaximumUsageTableEntries( security_level, &max_number_of_usage_entries)) { LOGW("GetMaxUsageTableEntries failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } if (max_number_of_usage_entries == 0) { // Zero indicates that the table is dynamically allocated and does @@ -755,17 +785,17 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, max_number_of_usage_entries = std::numeric_limits::max(); } *query_response = std::to_string(max_number_of_usage_entries); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION) { uint32_t api_minor_version; if (!crypto_session->GetApiMinorVersion(security_level, &api_minor_version)) { LOGW("GetApiMinorVersion failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = std::to_string(api_minor_version); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES) { bool supported = false, can_disable = false, cgms_a = false; @@ -783,7 +813,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, } else { *query_response = QUERY_VALUE_UNKNOWN; } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT) { bool supported = false, can_disable = false, cgms_a = false; @@ -793,7 +823,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, } else { *query_response = QUERY_VALUE_UNKNOWN; } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_WATERMARKING_SUPPORT) { CdmWatermarkingSupport support; @@ -813,15 +843,15 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, break; default: LOGW("Unknown watermarking support: %d", static_cast(support)); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_PRODUCTION_READY) { CdmProductionReadiness readiness; if (!crypto_session->GetProductionReadiness(security_level, &readiness)) { LOGW("GetProductionReadiness failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } switch (readiness) { case kProductionReadinessUnknown: @@ -835,9 +865,9 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, break; default: LOGW("Unknown readiness: %d", static_cast(readiness)); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_SYSTEM_ID) { wvutil::FileSystem global_file_system; @@ -846,10 +876,29 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, uint32_t system_id; if (!extractor.ExtractSystemId(&system_id)) { LOGW("ExtractSystemId failed"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } *query_response = std::to_string(system_id); - return NO_ERROR; + return CdmResponseType(NO_ERROR); + } + if (query_token == QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN) { + std::string bcc; + std::string signature_unused; + const CdmResponseType status = crypto_session->GetBootCertificateChain( + security_level, &bcc, &signature_unused); + if (status == NO_ERROR) { + LOGD("BCC length: %zu", bcc.size()); + *query_response = std::move(bcc); + return CdmResponseType(NO_ERROR); + } + if (status == NOT_IMPLEMENTED_ERROR || + status == PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR) { + LOGD("BCC not available: %d", status.ToInt()); + *query_response = QUERY_VALUE_NONE; + return CdmResponseType(NO_ERROR); + } + LOGE("Failed to extract BCC: status = %d", status.ToInt()); + return status; } CdmResponseType status; @@ -867,7 +916,7 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, ->crypto_session_get_device_unique_id_.Increment(status); if (status != NO_ERROR) return status; *query_response = device_id; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (query_token == QUERY_KEY_PROVISIONING_ID) { std::string provisioning_id; @@ -877,10 +926,10 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, return status; } *query_response = provisioning_id; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } LOGW("Unknown status requested: query_token = %s", IdToString(query_token)); - return INVALID_QUERY_KEY; + return CdmResponseType(INVALID_QUERY_KEY); } CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, @@ -889,7 +938,7 @@ CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_8; + return CdmResponseType(SESSION_NOT_FOUND_8); } return session->QueryStatus(query_response); } @@ -920,7 +969,7 @@ CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id, std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_9; + return CdmResponseType(SESSION_NOT_FOUND_9); } return session->QueryKeyStatus(query_response); } @@ -932,12 +981,12 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, IdToString(key_id)); if (key_usage == nullptr) { LOGE("Output |key_usage| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_12; + return CdmResponseType(SESSION_NOT_FOUND_12); } return session->QueryKeyAllowedUsage(key_id, key_usage); } @@ -947,7 +996,7 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, LOGI("key_id = %s", IdToString(key_id)); if (!key_usage) { LOGE("Output |key_usage| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } key_usage->Clear(); CdmSessionList sessions; @@ -963,7 +1012,7 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, // Found another key. If usage settings do not match, fail. if (!key_usage->Equals(found_in_this_session)) { key_usage->Clear(); - return KEY_CONFLICT_1; + return CdmResponseType(KEY_CONFLICT_1); } } else { *key_usage = found_in_this_session; @@ -975,7 +1024,7 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, return sts; } } - return (found) ? NO_ERROR : KEY_NOT_FOUND_2; + return (found) ? CdmResponseType(NO_ERROR) : CdmResponseType(KEY_NOT_FOUND_2); } CdmResponseType CdmEngine::QueryOemCryptoSessionId( @@ -984,7 +1033,7 @@ CdmResponseType CdmEngine::QueryOemCryptoSessionId( std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_10; + return CdmResponseType(SESSION_NOT_FOUND_10); } return session->QueryOemCryptoSessionId(query_response); } @@ -1020,11 +1069,11 @@ CdmResponseType CdmEngine::GetProvisioningRequest( LOGI("cert_type = %s", CdmCertificateTypeToString(cert_type)); if (!request) { LOGE("Output |request| is null"); - return INVALID_PROVISIONING_REQUEST_PARAM_1; + return CdmResponseType(INVALID_PROVISIONING_REQUEST_PARAM_1); } if (!default_url) { LOGE("Output |default_url| is null"); - return INVALID_PROVISIONING_REQUEST_PARAM_2; + return CdmResponseType(INVALID_PROVISIONING_REQUEST_PARAM_2); } if (requested_security_level == kLevelDefault) { @@ -1040,7 +1089,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest( // OKP is required. const CdmResponseType status = okp_provisioner_->GetProvisioningRequest(request, default_url); - if (status == NO_ERROR) return NO_ERROR; + if (status == NO_ERROR) return CdmResponseType(NO_ERROR); if (status == NOT_IMPLEMENTED_ERROR) { LOGW("OKP not supoprted, falling back to L3"); OkpTriggerFallback(); @@ -1098,22 +1147,22 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( if (response.empty()) { LOGE("Empty provisioning response"); cert_provisioning_.reset(); - return EMPTY_PROVISIONING_RESPONSE; + return CdmResponseType(EMPTY_PROVISIONING_RESPONSE); } if (cert == nullptr) { LOGE("Output |cert| is null"); cert_provisioning_.reset(); - return INVALID_PROVISIONING_PARAMETERS_1; + return CdmResponseType(INVALID_PROVISIONING_PARAMETERS_1); } if (wrapped_key == nullptr) { LOGE("Output |wrapped_key| is null"); cert_provisioning_.reset(); - return INVALID_PROVISIONING_PARAMETERS_2; + return CdmResponseType(INVALID_PROVISIONING_PARAMETERS_2); } if (requested_security_level == kLevelDefault) { bool use_okp = false; - CdmResponseType okp_res = UNKNOWN_ERROR; + CdmResponseType okp_res(UNKNOWN_ERROR); { std::unique_lock lock(okp_mutex_); if (okp_provisioner_) { @@ -1147,14 +1196,14 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( requested_security_level); if (NO_ERROR != status) { LOGE("Provisioning object missing and crypto session open failed"); - return EMPTY_PROVISIONING_CERTIFICATE_2; + return CdmResponseType(EMPTY_PROVISIONING_CERTIFICATE_2); } CdmSecurityLevel security_level = crypto_session->GetSecurityLevel(); if (!IsProvisioned(security_level)) { LOGE("Provisioning object missing"); - return EMPTY_PROVISIONING_CERTIFICATE_1; + return CdmResponseType(EMPTY_PROVISIONING_CERTIFICATE_1); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } const CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( @@ -1237,35 +1286,35 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { return res; } if (token_type == kClientTokenDrmCert) { - return DEVICE_CANNOT_REPROVISION; + return CdmResponseType(DEVICE_CANNOT_REPROVISION); } DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Unable to initialize device files"); - return UNPROVISION_ERROR_1; + return CdmResponseType(UNPROVISION_ERROR_1); } // TODO(b/141705730): Remove usage entries during unprovisioning. if (!file_system_->IsGlobal()) { if (!handle.RemoveCertificate() || !handle.RemoveOemCertificate()) { LOGE("Unable to delete certificate"); - return UNPROVISION_ERROR_2; + return CdmResponseType(UNPROVISION_ERROR_2); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (!handle.DeleteAllFiles()) { LOGE("Unable to delete files"); - return UNPROVISION_ERROR_3; + return CdmResponseType(UNPROVISION_ERROR_3); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::ListStoredLicenses( CdmSecurityLevel security_level, std::vector* key_set_ids) { if (!key_set_ids) { LOGE("Output |key_set_ids| is null"); - return INVALID_PARAMETERS_ENG_22; + return CdmResponseType(INVALID_PARAMETERS_ENG_22); } if (security_level == kSecurityLevelL1 && OkpIsInFallbackMode()) { LOGD("OKP fallback to L3"); @@ -1274,22 +1323,22 @@ CdmResponseType CdmEngine::ListStoredLicenses( DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Unable to initialize device files"); - return LIST_LICENSE_ERROR_1; + return CdmResponseType(LIST_LICENSE_ERROR_1); } if (!handle.ListLicenses(key_set_ids)) { LOGE("ListLicenses call failed"); - return LIST_LICENSE_ERROR_2; + return CdmResponseType(LIST_LICENSE_ERROR_2); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -CdmResponseType CdmEngine::ListUsageIds( - const std::string& app_id, CdmSecurityLevel security_level, - std::vector* ksids, - std::vector* provider_session_tokens) { - if (!ksids && !provider_session_tokens) { - LOGE("Outputs |ksids| and |provider_session_tokens| are null"); - return INVALID_PARAMETERS_ENG_23; +CdmResponseType CdmEngine::ListUsageIds(const std::string& app_id, + CdmSecurityLevel security_level, + std::vector* ksids, + std::vector* psts) { + if (!ksids && !psts) { + LOGE("Outputs |ksids| and |psts| are null"); + return CdmResponseType(INVALID_PARAMETERS_ENG_23); } if (security_level == kSecurityLevelL1 && OkpIsInFallbackMode()) { LOGD("OKP fallback to L3"); @@ -1298,19 +1347,19 @@ CdmResponseType CdmEngine::ListUsageIds( DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Unable to initialize device files"); - return LIST_USAGE_ERROR_1; + return CdmResponseType(LIST_USAGE_ERROR_1); } - if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) { + if (!handle.ListUsageIds(app_id, ksids, psts)) { LOGE("Failed: app_id = %s, security_level = %s", IdToString(app_id), CdmSecurityLevelToString(security_level)); - return LIST_USAGE_ERROR_2; + return CdmResponseType(LIST_USAGE_ERROR_2); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id, CdmSecurityLevel security_level, - const std::string& key_set_id) { + const CdmKeySetId& key_set_id) { LOGI("app_id = %s, key_set_id = %s", IdToString(app_id), IdToString(key_set_id)); if (security_level == kSecurityLevelL1 && OkpIsInFallbackMode()) { @@ -1320,13 +1369,13 @@ CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id, DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Unable to initialize device files"); - return DELETE_USAGE_ERROR_1; + return CdmResponseType(DELETE_USAGE_ERROR_1); } std::string provider_session_token; if (!handle.GetProviderSessionToken(app_id, key_set_id, &provider_session_token)) { LOGE("GetProviderSessionToken failed"); - return DELETE_USAGE_ERROR_2; + return CdmResponseType(DELETE_USAGE_ERROR_2); } return RemoveUsageInfo(app_id, provider_session_token); } @@ -1341,17 +1390,17 @@ CdmResponseType CdmEngine::GetOfflineLicenseState( DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Cannot initialize device files"); - return GET_OFFLINE_LICENSE_STATE_ERROR_1; + return CdmResponseType(GET_OFFLINE_LICENSE_STATE_ERROR_1); } DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; if (!handle.RetrieveLicense(key_set_id, &license_data, &sub_error_code)) { LOGE("Failed to retrieve license state: key_set_id = %s", IdToString(key_set_id)); - return GET_OFFLINE_LICENSE_STATE_ERROR_2; + return CdmResponseType(GET_OFFLINE_LICENSE_STATE_ERROR_2); } *license_state = license_data.state; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::RemoveOfflineLicense( @@ -1368,7 +1417,7 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( if (!handle.Init(security_level)) { LOGE("Cannot initialize device files: security_level = %s", security_level == kSecurityLevelL3 ? "L3" : "Default"); - return REMOVE_OFFLINE_LICENSE_ERROR_1; + return CdmResponseType(REMOVE_OFFLINE_LICENSE_ERROR_1); } CdmResponseType sts = OpenKeySetSession(key_set_id, &property_set, @@ -1391,7 +1440,7 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); - sts = REMOVE_OFFLINE_LICENSE_ERROR_2; + sts = CdmResponseType(REMOVE_OFFLINE_LICENSE_ERROR_2); } else { session_id = iter->second.first; sts = RemoveLicense(session_id); @@ -1403,7 +1452,7 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( // and the file should simply be deleted. LOGW("License usage entry is missing, deleting license file"); handle.DeleteLicense(key_set_id); - sts = NO_ERROR; + sts = CdmResponseType(NO_ERROR); } if (sts != NO_ERROR) { @@ -1414,21 +1463,50 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( return sts; } +CdmResponseType CdmEngine::StoreAtscLicense( + RequestedSecurityLevel requested_security_level, + const CdmKeySetId& key_set_id, const std::string& serialized_license_data) { + std::string security_level_string; + + CdmResponseType status = + QueryStatus(requested_security_level, QUERY_KEY_SECURITY_LEVEL, + &security_level_string); + if (status != NO_ERROR) return status; + + DeviceFiles handle(file_system_); + CdmSecurityLevel security_level = + security_level_string == QUERY_VALUE_SECURITY_LEVEL_L1 ? kSecurityLevelL1 + : kSecurityLevelL3; + if (!handle.Init(security_level)) { + LOGE("Unable to initialize device files"); + return CdmResponseType(STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR); + } + + DeviceFiles::ResponseType response_type = + handle.StoreAtscLicense(key_set_id, serialized_license_data); + if (response_type != DeviceFiles::kNoError) { + LOGE("Unable to store ATSC license: response = %s", + DeviceFiles::ResponseTypeToString(response_type)); + return CdmResponseType(STORE_ATSC_LICENSE_ERROR); + } + return CdmResponseType(NO_ERROR); +} + CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, int* error_detail, - CdmUsageInfo* usage_info) { + CdmUsageReport* usage_report) { // Try to find usage info at the default security level. If the // security level is unprovisioned or we are unable to find it, // try L3. CdmResponseType status = - GetUsageInfo(app_id, ssid, kLevelDefault, error_detail, usage_info); - switch (status) { + GetUsageInfo(app_id, ssid, kLevelDefault, error_detail, usage_report); + switch (status.code()) { case NEED_PROVISIONING: case GET_USAGE_INFO_ERROR_1: case GET_USAGE_INFO_ERROR_2: case USAGE_INFO_NOT_FOUND: - status = GetUsageInfo(app_id, ssid, kLevel3, error_detail, usage_info); + status = GetUsageInfo(app_id, ssid, kLevel3, error_detail, usage_report); return status; default: return status; @@ -1439,15 +1517,18 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, RequestedSecurityLevel security_level, int* error_detail, - CdmUsageInfo* usage_info) { + CdmUsageReport* usage_report) { LOGI("app_id = %s, ssid = %s", IdToString(app_id), IdToString(ssid)); + std::unique_lock lock(usage_session_mutex_); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } - if (usage_info == nullptr) { - LOGE("Output |usage_info| is null"); - return PARAMETER_NULL; + if (usage_report == nullptr) { + LOGE("Output |usage_report| is null"); + return CdmResponseType(PARAMETER_NULL); } + usage_report->clear(); + usage_property_set_->set_security_level(security_level); usage_property_set_->set_app_id(app_id); usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession())); @@ -1459,7 +1540,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, DeviceFiles handle(file_system_); if (!handle.Init(usage_session_->GetSecurityLevel())) { LOGE("Device file init error"); - return GET_USAGE_INFO_ERROR_1; + return CdmResponseType(GET_USAGE_INFO_ERROR_1); } DeviceFiles::CdmUsageData usage_data; @@ -1475,12 +1556,12 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, } if (!handle.Reset(usage_session_->GetSecurityLevel())) { LOGE("Device file init error"); - return GET_USAGE_INFO_ERROR_2; + return CdmResponseType(GET_USAGE_INFO_ERROR_2); } if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), ssid, &usage_data)) { // No entry found for that ssid. - return USAGE_INFO_NOT_FOUND; + return CdmResponseType(USAGE_INFO_NOT_FOUND); } } @@ -1488,68 +1569,67 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, if (KEY_ADDED != status) { LOGE("RestoreUsageSession failed: status = %d", static_cast(status)); - usage_info->clear(); return status; } CdmKeyRequest request; status = usage_session_->GenerateReleaseRequest(&request); - usage_info->clear(); - usage_info->push_back(request.message); - if (KEY_MESSAGE != status) { LOGE("GenerateReleaseRequest failed: status = %d", static_cast(status)); - usage_info->clear(); return status; } - return KEY_MESSAGE; + *usage_report = std::move(request.message); + return CdmResponseType(KEY_MESSAGE); } CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, int* error_detail, - CdmUsageInfo* usage_info) { + CdmUsageReport* usage_report) { LOGI("app_id = %s", IdToString(app_id)); - if (usage_info == nullptr) { - LOGE("Output |usage_info| is null"); - return PARAMETER_NULL; + if (usage_report == nullptr) { + LOGE("Output |usage_report| is null"); + return CdmResponseType(PARAMETER_NULL); } // Return a random usage report from a random security level RequestedSecurityLevel security_level = wvutil::CdmRandom::RandomBool() ? kLevelDefault : kLevel3; - CdmResponseType status = UNKNOWN_ERROR; + CdmResponseType status(UNKNOWN_ERROR); do { - status = GetUsageInfo(app_id, security_level, error_detail, usage_info); - if (KEY_MESSAGE == status && !usage_info->empty()) { + status = GetUsageInfo(app_id, security_level, error_detail, usage_report); + if (KEY_MESSAGE == status && !usage_report->empty()) { return status; } } while (KEY_CANCELED == status); security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3; do { - status = GetUsageInfo(app_id, security_level, error_detail, usage_info); + status = GetUsageInfo(app_id, security_level, error_detail, usage_report); if (NEED_PROVISIONING == status) - return NO_ERROR; // Valid scenario that one of the security - // levels has not been provisioned + return CdmResponseType( + NO_ERROR); // Valid scenario that one of the security + // levels has not been provisioned } while (KEY_CANCELED == status); return status; } CdmResponseType CdmEngine::GetUsageInfo( const std::string& app_id, RequestedSecurityLevel requested_security_level, - int* error_detail, CdmUsageInfo* usage_info) { + int* error_detail, CdmUsageReport* usage_report) { LOGI("app_id = %s, security_level = %s", IdToString(app_id), RequestedSecurityLevelToString(requested_security_level)); - if (usage_info == nullptr) { - LOGE("Output |usage_info| is null"); - return PARAMETER_NULL; + if (usage_report == nullptr) { + LOGE("Output |usage_report| is null"); + return CdmResponseType(PARAMETER_NULL); } + usage_report->clear(); if (requested_security_level == kLevelDefault && OkpIsInFallbackMode()) { LOGD("OKP fallback to L3"); requested_security_level = kLevel3; } + std::unique_lock lock(usage_session_mutex_); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } @@ -1567,19 +1647,18 @@ CdmResponseType CdmEngine::GetUsageInfo( DeviceFiles handle(file_system_); if (!handle.Init(usage_session_->GetSecurityLevel())) { LOGE("Unable to initialize device files"); - return GET_USAGE_INFO_ERROR_3; + return CdmResponseType(GET_USAGE_INFO_ERROR_3); } std::vector usage_data; if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), &usage_data)) { LOGE("Unable to read usage information"); - return GET_USAGE_INFO_ERROR_4; + return CdmResponseType(GET_USAGE_INFO_ERROR_4); } if (usage_data.empty()) { - usage_info->clear(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } const size_t index = wvutil::CdmRandom::RandomInRange(usage_data.size() - 1); @@ -1588,27 +1667,22 @@ CdmResponseType CdmEngine::GetUsageInfo( // TODO(b/141704872): Make multiple attempts. LOGE("RestoreUsageSession failed: index = %zu, status = %d", index, static_cast(status)); - usage_info->clear(); return status; } CdmKeyRequest request; status = usage_session_->GenerateReleaseRequest(&request); - usage_info->clear(); - usage_info->push_back(request.message); - - switch (status) { + switch (status.code()) { case KEY_MESSAGE: + *usage_report = std::move(request.message); break; case KEY_CANCELED: // usage information not present in usage_session_->DeleteLicenseFile(); // OEMCrypto, delete and try again - usage_info->clear(); break; default: LOGE("GenerateReleaseRequest failed: status = %d", static_cast(status)); - usage_info->clear(); break; } return status; @@ -1618,12 +1692,13 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( const std::string& app_id, CdmSecurityLevel cdm_security_level) { LOGI("app_id = %s, security_level = %s", IdToString(app_id), CdmSecurityLevelToString(cdm_security_level)); + std::unique_lock lock(usage_session_mutex_); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } usage_property_set_->set_app_id(app_id); - CdmResponseType status = NO_ERROR; + CdmResponseType status(NO_ERROR); DeviceFiles handle(file_system_); if (handle.Init(cdm_security_level)) { const RequestedSecurityLevel security_level = @@ -1632,7 +1707,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession())); usage_session_->Init(usage_property_set_.get()); - if (usage_session_->supports_usage_info()) { + if (usage_session_->SupportsUsageTable()) { std::vector usage_data; // Retrieve all usage information but delete only one before // refetching. This is because deleting the usage entry @@ -1647,7 +1722,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( if (usage_data.empty()) break; CdmResponseType res = - usage_session_->DeleteUsageEntry(usage_data[0].usage_entry_number); + usage_session_->DeleteUsageEntry(usage_data[0].usage_entry_index); if (res != NO_ERROR) { LOGW("Failed to delete usage entry: status = %d", @@ -1666,7 +1741,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( if (!handle.DeleteAllUsageInfoForApp( DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens)) { - status = REMOVE_ALL_USAGE_INFO_ERROR_5; + status = CdmResponseType(REMOVE_ALL_USAGE_INFO_ERROR_5); } } } @@ -1691,12 +1766,13 @@ CdmResponseType CdmEngine::RemoveUsageInfo( const std::string& app_id, const CdmSecureStopId& provider_session_token) { LOGI("app_id = %s, pst = %s", IdToString(app_id), IdToString(provider_session_token)); + std::unique_lock lock(usage_session_mutex_); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } usage_property_set_->set_app_id(app_id); - CdmResponseType status = NO_ERROR; + CdmResponseType status(NO_ERROR); for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) { DeviceFiles handle(file_system_); if (handle.Init(static_cast(j))) { @@ -1715,36 +1791,35 @@ CdmResponseType CdmEngine::RemoveUsageInfo( continue; } - if (usage_session_->supports_usage_info()) { - status = - usage_session_->DeleteUsageEntry(usage_data.usage_entry_number); + if (usage_session_->SupportsUsageTable()) { + status = usage_session_->DeleteUsageEntry(usage_data.usage_entry_index); if (!handle.DeleteUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), usage_data.key_set_id)) { - status = REMOVE_USAGE_INFO_ERROR_1; + status = CdmResponseType(REMOVE_USAGE_INFO_ERROR_1); } usage_session_.reset(); return status; } } else { LOGE("Failed to initialize L%d device files", j); - status = REMOVE_USAGE_INFO_ERROR_2; + status = CdmResponseType(REMOVE_USAGE_INFO_ERROR_2); } } usage_session_.reset(); - return REMOVE_USAGE_INFO_ERROR_3; + return CdmResponseType(REMOVE_USAGE_INFO_ERROR_3); } -CdmResponseType CdmEngine::ReleaseUsageInfo( - const CdmUsageInfoReleaseMessage& message) { +CdmResponseType CdmEngine::ReleaseUsageInfo(const CdmKeyResponse& message) { LOGI("message_size = %zu", message.size()); + std::unique_lock lock(usage_session_mutex_); if (!usage_session_) { LOGE("Usage session not initialized"); - return RELEASE_USAGE_INFO_ERROR; + return CdmResponseType(RELEASE_USAGE_INFO_ERROR); } const CdmResponseType status = usage_session_->ReleaseKey(message); usage_session_.reset(); if (NO_ERROR != status) { - LOGE("ReleaseKey failed: status = %d", status); + LOGE("ReleaseKey failed: status = %d", static_cast(status)); } return status; } @@ -1757,23 +1832,23 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, assert(Properties::AlwaysUseKeySetIds()); if (key_set_id.empty()) { LOGE("Invalid key set ID"); - return EMPTY_KEYSET_ID_ENG_5; + return CdmResponseType(EMPTY_KEYSET_ID_ENG_5); } if (release_message == nullptr) { LOGE("Output |release_message| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(key_set_id, &session)) { LOGE("Session not found: key_set_id = %s", IdToString(key_set_id)); - return SESSION_NOT_FOUND_11; + return CdmResponseType(SESSION_NOT_FOUND_11); } DeviceFiles handle(file_system_); if (!handle.Init(session->GetSecurityLevel())) { LOGE("Unable to initialize device files"); - return LOAD_USAGE_INFO_FILE_ERROR; + return CdmResponseType(LOAD_USAGE_INFO_FILE_ERROR); } std::string app_id; @@ -1784,10 +1859,10 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, DeviceFiles::GetUsageInfoFileName(app_id), key_set_id, &(usage_data.provider_session_token), &(usage_data.license_request), &(usage_data.license), &(usage_data.usage_entry), - &(usage_data.usage_entry_number), &(usage_data.drm_certificate), + &(usage_data.usage_entry_index), &(usage_data.drm_certificate), &(usage_data.wrapped_private_key))) { LOGE("Unable to find usage information"); - return LOAD_USAGE_INFO_MISSING; + return CdmResponseType(LOAD_USAGE_INFO_MISSING); } int error_detail = NO_ERROR; @@ -1805,7 +1880,7 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, CdmKeyRequest request; status = session->GenerateReleaseRequest(&request); *release_message = std::move(request.message); - switch (status) { + switch (status.code()) { case KEY_MESSAGE: break; case KEY_CANCELED: @@ -1826,14 +1901,14 @@ CdmResponseType CdmEngine::DecryptV16( for (const CdmDecryptionSample& sample : parameters.samples) { if (sample.encrypt_buffer == nullptr) { LOGE("No src encrypt buffer"); - return INVALID_DECRYPT_PARAMETERS_ENG_2; + return CdmResponseType(INVALID_DECRYPT_PARAMETERS_ENG_2); } if (sample.decrypt_buffer == nullptr) { if (!parameters.is_secure && !Properties::Properties::oem_crypto_use_fifo()) { LOGE("No dest decrypt buffer"); - return INVALID_DECRYPT_PARAMETERS_ENG_4; + return CdmResponseType(INVALID_DECRYPT_PARAMETERS_ENG_4); } // else we must be level 1 direct and we don't need to return a buffer. } @@ -1860,12 +1935,12 @@ CdmResponseType CdmEngine::DecryptV16( } if (!session) { LOGE("Session not found: session_id = "); - return SESSION_NOT_FOUND_FOR_DECRYPT; + return CdmResponseType(SESSION_NOT_FOUND_FOR_DECRYPT); } } else { if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_FOR_DECRYPT; + return CdmResponseType(SESSION_NOT_FOUND_FOR_DECRYPT); } } @@ -1880,12 +1955,12 @@ CdmResponseType CdmEngine::GenericEncrypt(const std::string& session_id, std::string* out_buffer) { if (out_buffer == nullptr) { LOGE("Output |out_buffer| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_13; + return CdmResponseType(SESSION_NOT_FOUND_13); } return session->GenericEncrypt(in_buffer, key_id, iv, algorithm, out_buffer); } @@ -1898,12 +1973,12 @@ CdmResponseType CdmEngine::GenericDecrypt(const std::string& session_id, std::string* out_buffer) { if (out_buffer == nullptr) { LOGE("Output |out_buffer| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_14; + return CdmResponseType(SESSION_NOT_FOUND_14); } return session->GenericDecrypt(in_buffer, key_id, iv, algorithm, out_buffer); } @@ -1915,12 +1990,12 @@ CdmResponseType CdmEngine::GenericSign(const std::string& session_id, std::string* signature) { if (signature == nullptr) { LOGE("Output |signature| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_15; + return CdmResponseType(SESSION_NOT_FOUND_15); } return session->GenericSign(message, key_id, algorithm, signature); } @@ -1933,7 +2008,7 @@ CdmResponseType CdmEngine::GenericVerify(const std::string& session_id, std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_16; + return CdmResponseType(SESSION_NOT_FOUND_16); } return session->GenericVerify(message, key_id, algorithm, signature); } @@ -1943,15 +2018,15 @@ CdmResponseType CdmEngine::ParseDecryptHashString( uint32_t* frame_number, std::string* hash) { if (session_id == nullptr) { LOGE("Output |session_id| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (frame_number == nullptr) { LOGE("Output |frame_number| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (hash == nullptr) { LOGE("Output |hash| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } std::stringstream ss; std::string token; @@ -1965,7 +2040,7 @@ CdmResponseType CdmEngine::ParseDecryptHashString( "Hash string has invalid format: " "Unexpected number of tokens: %zu (hash_string = %s)", tokens.size(), hash_string.c_str()); - return INVALID_DECRYPT_HASH_FORMAT; + return CdmResponseType(INVALID_DECRYPT_HASH_FORMAT); } for (size_t i = 0; i < tokens.size(); ++i) { @@ -1974,7 +2049,7 @@ CdmResponseType CdmEngine::ParseDecryptHashString( "Hash string has invalid format: token %zu of length 0: " "hash_string = %s", i, hash_string.c_str()); - return INVALID_DECRYPT_HASH_FORMAT; + return CdmResponseType(INVALID_DECRYPT_HASH_FORMAT); } } @@ -1983,15 +2058,15 @@ CdmResponseType CdmEngine::ParseDecryptHashString( if (!(iss >> *frame_number)) { LOGE("Error while trying to convert frame number to a numeric format: %s", hash_string.c_str()); - return INVALID_DECRYPT_HASH_FORMAT; + return CdmResponseType(INVALID_DECRYPT_HASH_FORMAT); } *hash = wvutil::a2bs_hex(tokens[2]); if (hash->empty()) { LOGE("Malformed hash: %s", hash_string.c_str()); - return INVALID_DECRYPT_HASH_FORMAT; + return CdmResponseType(INVALID_DECRYPT_HASH_FORMAT); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmEngine::SetDecryptHash(const CdmSessionId& session_id, @@ -2000,7 +2075,7 @@ CdmResponseType CdmEngine::SetDecryptHash(const CdmSessionId& session_id, LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - return SESSION_NOT_FOUND_20; + return CdmResponseType(SESSION_NOT_FOUND_20); } return session->SetDecryptHash(frame_number, hash); } @@ -2010,12 +2085,12 @@ CdmResponseType CdmEngine::GetDecryptHashError(const CdmSessionId& session_id, LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - return SESSION_NOT_FOUND_20; + return CdmResponseType(SESSION_NOT_FOUND_20); } return session->GetDecryptHashError(error_string); } -// TODO(gmorgan) Used? Delete if unused. +// TODO(rfrias) Used? Delete if unused. bool CdmEngine::IsKeyLoaded(const KeyId& key_id) { CdmSessionList sessions; session_map_.GetSessionList(sessions); @@ -2113,7 +2188,7 @@ void CdmEngine::OnTimerEvent() { for (CdmSessionList::iterator iter = sessions.begin(); iter != sessions.end(); ++iter) { (*iter)->reset_usage_flags(); - if ((*iter)->supports_usage_info() && + if ((*iter)->SupportsUsageTable() && (*iter)->has_provider_session_token()) { (*iter)->UpdateUsageEntryInformation(); } @@ -2144,31 +2219,10 @@ CdmResponseType CdmEngine::SetPlaybackId(const CdmSessionId& session_id, std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { LOGE("Session not found: session_id = %s", IdToString(session_id)); - return SESSION_NOT_FOUND_23; + return CdmResponseType(SESSION_NOT_FOUND_23); } session->GetMetrics()->playback_id_.Record(playback_id); - return NO_ERROR; -} - -std::string CdmEngine::MapHdcpVersion(CryptoSession::HdcpCapability version) { - switch (version) { - case HDCP_NONE: - return QUERY_VALUE_HDCP_NONE; - case HDCP_V1: - return QUERY_VALUE_HDCP_V1; - case HDCP_V2: - return QUERY_VALUE_HDCP_V2_0; - case HDCP_V2_1: - return QUERY_VALUE_HDCP_V2_1; - case HDCP_V2_2: - return QUERY_VALUE_HDCP_V2_2; - case HDCP_V2_3: - return QUERY_VALUE_HDCP_V2_3; - case HDCP_NO_DIGITAL_OUTPUT: - return QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT; - default: - return QUERY_VALUE_HDCP_LEVEL_UNKNOWN; - } + return CdmResponseType(NO_ERROR); } void CdmEngine::CloseExpiredReleaseSessions() { diff --git a/core/src/cdm_session.cpp b/core/src/cdm_session.cpp index c35f1ef7..783c0416 100644 --- a/core/src/cdm_session.cpp +++ b/core/src/cdm_session.cpp @@ -12,13 +12,15 @@ #include #include "cdm_engine.h" +#include "cdm_random.h" +#include "cdm_usage_table.h" #include "clock.h" #include "crypto_wrapped_key.h" #include "file_store.h" #include "log.h" #include "properties.h" #include "string_conversions.h" -#include "usage_table_header.h" +#include "system_id_extractor.h" #include "wv_cdm_constants.h" #include "wv_cdm_event_listener.h" @@ -29,7 +31,7 @@ #define RETURN_STATUS_IF_NULL(PARAM) \ if ((PARAM) == nullptr) { \ LOGE("Output parameter |" STRINGIFY(PARAM) "| not provided"); \ - return PARAMETER_NULL; \ + return CdmResponseType(PARAMETER_NULL); \ } #define RETURN_FALSE_IF_NULL(PARAM) \ @@ -46,7 +48,7 @@ const size_t kKeySetIdLength = 14; template void SetErrorDetail(int* error_detail, T error_code) { if (error_detail != nullptr) { - *error_detail = error_code; + *error_detail = static_cast(error_code); } } @@ -80,8 +82,6 @@ CdmSession::CdmSession(wvutil::FileSystem* file_system, requested_security_level_(kLevelDefault), is_initial_usage_update_(true), is_usage_update_needed_(false), - usage_table_header_(nullptr), - usage_entry_number_(0), mock_license_parser_in_use_(false), mock_policy_engine_in_use_(false) { assert(metrics_); // metrics_ must not be null. @@ -91,7 +91,7 @@ CdmSession::CdmSession(wvutil::FileSystem* file_system, } CdmSession::~CdmSession() { - if (has_provider_session_token() && supports_usage_info() && !is_release_) { + if (has_provider_session_token() && SupportsUsageTable() && !is_release_) { UpdateUsageEntryInformation(); } @@ -118,7 +118,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, bool forced_level3) { if (initialized_) { LOGE("Failed due to previous initialization"); - return REINIT_ERROR; + return CdmResponseType(REINIT_ERROR); } if ((cdm_client_property_set && cdm_client_property_set->security_level() == @@ -144,12 +144,12 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, if (!file_handle_->Init(security_level_)) { LOGE("Unable to initialize file handle"); - return SESSION_FILE_HANDLE_INIT_ERROR; + return CdmResponseType(SESSION_FILE_HANDLE_INIT_ERROR); } bool has_support = false; - if (crypto_session_->HasUsageInfoSupport(&has_support) && has_support) { - usage_table_header_ = crypto_session_->GetUsageTableHeader(); + if (crypto_session_->HasUsageTableSupport(&has_support) && has_support) { + usage_table_ = crypto_session_->GetUsageTable(); } if (cdm_client_property_set != nullptr) @@ -159,7 +159,10 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, // The actual validation and loading of a certificate will happen when // a key request is generated or an offline license is loaded. if (!file_handle_->HasCertificate(atsc_mode_enabled_)) - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); + + // Require reprovisioning if the root of trust has changed + if (HasRootOfTrustBeenRenewed()) return CdmResponseType(NEED_PROVISIONING); if (forced_session_id) { key_set_id_ = *forced_session_id; @@ -178,7 +181,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, if (session_id_.empty()) { LOGE("Empty session ID"); - return EMPTY_SESSION_ID; + return CdmResponseType(EMPTY_SESSION_ID); } if (cdm_client_property_set) Properties::AddSessionPropertySet(session_id_, cdm_client_property_set); @@ -196,13 +199,13 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, if (!license_parser_->Init(Properties::UsePrivacyMode(session_id_), service_certificate, crypto_session_.get(), policy_engine_.get())) - return LICENSE_PARSER_INIT_ERROR; + return CdmResponseType(LICENSE_PARSER_INIT_ERROR); license_received_ = false; is_initial_decryption_ = true; initialized_ = true; closed_ = false; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, @@ -210,7 +213,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, int* error_detail) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } if (!key_set_id_.empty()) { file_handle_->UnreserveLicenseId(key_set_id_); @@ -219,7 +222,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, LOGE( "Disallow multiple offline license restores or restoring a license if " "a license has already been loaded"); - return RESTORE_OFFLINE_LICENSE_ERROR_3; + return CdmResponseType(RESTORE_OFFLINE_LICENSE_ERROR_3); } key_set_id_ = key_set_id; @@ -233,8 +236,21 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, DeviceFiles::ResponseTypeToString(sub_error_code), IdToString(key_set_id)); SetErrorDetail(error_detail, sub_error_code); - return sub_error_code == DeviceFiles::kFileNotFound ? KEYSET_ID_NOT_FOUND_4 - : GET_LICENSE_ERROR; + switch (sub_error_code) { + case DeviceFiles::kFileNotFound: + case DeviceFiles::kFileNotFoundEAcces: + case DeviceFiles::kFileNotFoundEFault: + case DeviceFiles::kFileNotFoundELoop: + case DeviceFiles::kFileNotFoundENameTooLong: + case DeviceFiles::kFileNotFoundENoEnt: + case DeviceFiles::kFileNotFoundENoMem: + case DeviceFiles::kFileNotFoundENotDir: + case DeviceFiles::kFileNotFoundEOverflow: + case DeviceFiles::kFileNotFoundOther: + return (CdmResponseType(KEYSET_ID_NOT_FOUND_4)); + default: + return (CdmResponseType(GET_LICENSE_ERROR)); + } } offline_init_data_ = std::move(license_data.pssh_data); key_request_ = std::move(license_data.license_request); @@ -245,7 +261,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, offline_release_server_url_ = std::move(license_data.release_server_url); app_parameters_ = std::move(license_data.app_parameters); usage_entry_ = std::move(license_data.usage_entry); - usage_entry_number_ = license_data.usage_entry_number; + usage_entry_index_ = license_data.usage_entry_index; CdmResponseType result = LoadPrivateOrLegacyKey( license_data.drm_certificate, license_data.wrapped_private_key); @@ -266,27 +282,27 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, LOGE("Invalid offline license state: state = %s, license_type = %s", CdmOfflineLicenseStateToString(license_data.state), CdmLicenseTypeToString(license_type)); - return GET_RELEASED_LICENSE_ERROR; + return CdmResponseType(GET_RELEASED_LICENSE_ERROR); } std::string provider_session_token; bool sign_fake_request = false; // TODO(b/169483174): remove this variable. - if (supports_usage_info()) { + if (SupportsUsageTable()) { if (!license_parser_->ExtractProviderSessionToken( key_response_, &provider_session_token)) { provider_session_token.clear(); sign_fake_request = true; // TODO(b/169483174): remove this line. } else if (!VerifyOfflineUsageEntry()) { LOGE("License usage entry is invalid, cannot restore"); - return LICENSE_USAGE_ENTRY_MISSING; + return CdmResponseType(LICENSE_USAGE_ENTRY_MISSING); } else { - CdmResponseType sts = usage_table_header_->LoadEntry( - crypto_session_.get(), usage_entry_, usage_entry_number_); + CdmResponseType sts = usage_table_->LoadEntry( + crypto_session_.get(), usage_entry_, usage_entry_index_); crypto_metrics_->usage_table_header_load_entry_.Increment(sts); if (sts == LOAD_USAGE_ENTRY_INVALID_SESSION) { LOGE("License loaded in different session: key_set_id = %s", IdToString(key_set_id)); - return USAGE_ENTRY_ALREADY_LOADED; + return CdmResponseType(USAGE_ENTRY_ALREADY_LOADED); } if (sts != NO_ERROR) { LOGE("Failed to load usage entry: status = %d", static_cast(sts)); @@ -305,13 +321,16 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, std::string fake_message("empty message"); std::string core_message; std::string license_request_signature; + bool should_specify_algorithm; + OEMCrypto_SignatureHashAlgorithm algorithm = OEMCrypto_SHA1; uint32_t nonce; // Sign a fake message so that OEMCrypto will start the rental clock. The // signature and generated core message are ignored. result = crypto_session_->GenerateNonce(&nonce); if (result != NO_ERROR) return result; result = crypto_session_->PrepareAndSignLicenseRequest( - fake_message, &core_message, &license_request_signature); + fake_message, &core_message, &license_request_signature, + should_specify_algorithm, algorithm); if (result != NO_ERROR) return result; } @@ -320,8 +339,8 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, license_data.drm_certificate, key_request_, key_response_); if (result != NO_ERROR) { - SetErrorDetail(error_detail, result); - return RELEASE_LICENSE_ERROR_1; + SetErrorDetail(error_detail, result.code()); + return CdmResponseType(RELEASE_LICENSE_ERROR_1); } } else { result = license_parser_->RestoreOfflineLicense( @@ -330,14 +349,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, license_data.last_playback_time, license_data.grace_period_end_time, this); if (result != NO_ERROR) { - SetErrorDetail(error_detail, result); - return RESTORE_OFFLINE_LICENSE_ERROR_2; + SetErrorDetail(error_detail, result.code()); + return CdmResponseType(RESTORE_OFFLINE_LICENSE_ERROR_2); } } - if (!provider_session_token.empty() && supports_usage_info()) { - CdmResponseType sts = usage_table_header_->UpdateEntry( - usage_entry_number_, crypto_session_.get(), &usage_entry_); + if (!provider_session_token.empty() && SupportsUsageTable()) { + CdmResponseType sts = usage_table_->UpdateEntry( + usage_entry_index_, crypto_session_.get(), &usage_entry_); if (sts != NO_ERROR) { LOGE("Failed to update usage entry: status = %d", static_cast(sts)); return sts; @@ -351,14 +370,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id, is_offline_ = true; is_release_ = license_type == kLicenseTypeRelease; has_license_been_restored_ = true; - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } CdmResponseType CdmSession::RestoreUsageSession( const DeviceFiles::CdmUsageData& usage_data, int* error_detail) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } if (!key_set_id_.empty()) { file_handle_->UnreserveLicenseId(key_set_id_); @@ -367,17 +386,17 @@ CdmResponseType CdmSession::RestoreUsageSession( key_request_ = usage_data.license_request; key_response_ = usage_data.license; usage_entry_ = usage_data.usage_entry; - usage_entry_number_ = usage_data.usage_entry_number; + usage_entry_index_ = usage_data.usage_entry_index; usage_provider_session_token_ = usage_data.provider_session_token; CdmResponseType status = LoadPrivateOrLegacyKey( usage_data.drm_certificate, usage_data.wrapped_private_key); if (status != NO_ERROR) return status; - CdmResponseType sts = NO_ERROR; - if (supports_usage_info()) { - sts = usage_table_header_->LoadEntry(crypto_session_.get(), usage_entry_, - usage_entry_number_); + CdmResponseType sts(NO_ERROR); + if (SupportsUsageTable()) { + sts = usage_table_->LoadEntry(crypto_session_.get(), usage_entry_, + usage_entry_index_); crypto_metrics_->usage_table_header_load_entry_.Increment(sts); if (sts != NO_ERROR) { LOGE("Failed to load usage entry: status = %d", static_cast(sts)); @@ -390,12 +409,12 @@ CdmResponseType CdmSession::RestoreUsageSession( if (sts != NO_ERROR) { SetErrorDetail(error_detail, sts); - return RELEASE_LICENSE_ERROR_2; + return CdmResponseType(RELEASE_LICENSE_ERROR_2); } - if (supports_usage_info()) { - sts = usage_table_header_->UpdateEntry( - usage_entry_number_, crypto_session_.get(), &usage_entry_); + if (SupportsUsageTable()) { + sts = usage_table_->UpdateEntry(usage_entry_index_, crypto_session_.get(), + &usage_entry_); if (sts != NO_ERROR) { LOGE("Failed to update usage entry: status = %d", static_cast(sts)); return sts; @@ -408,7 +427,7 @@ CdmResponseType CdmSession::RestoreUsageSession( license_received_ = true; is_offline_ = false; is_release_ = true; - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } // This is a thin wrapper that initiates the latency metric. @@ -432,7 +451,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal( const CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } RETURN_STATUS_IF_NULL(key_request); @@ -460,7 +479,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal( return license_parser_->HandleEmbeddedKeyData(init_data); default: LOGE("Unrecognized license type: %d", static_cast(license_type)); - return INVALID_LICENSE_TYPE; + return CdmResponseType(INVALID_LICENSE_TYPE); } if (is_release_) { @@ -482,15 +501,15 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal( if (!init_data.is_supported()) { LOGW("Unsupported init data type: %s", init_data.type().c_str()); - return UNSUPPORTED_INIT_DATA; + return CdmResponseType(UNSUPPORTED_INIT_DATA); } if (init_data.IsEmpty() && !license_parser_->HasInitData()) { LOGW("Init data absent"); - return INIT_DATA_NOT_FOUND; + return CdmResponseType(INIT_DATA_NOT_FOUND); } if (is_offline_ && key_set_id_.empty()) { LOGE("Key set ID not set"); - return KEY_REQUEST_ERROR_1; + return CdmResponseType(KEY_REQUEST_ERROR_1); } // Attempt to load provisioned private key if available. CdmResponseType status = LoadPrivateKey(); @@ -507,7 +526,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal( offline_init_data_ = init_data.data(); offline_release_server_url_ = key_request->url; } - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } // This thin wrapper allows us to update metrics. @@ -521,12 +540,12 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { if (!initialized_) { LOGE("Not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } if (is_release_) { const CdmResponseType sts = ReleaseKey(key_response); - return (sts == NO_ERROR) ? KEY_ADDED : sts; + return (sts == NO_ERROR) ? CdmResponseType(KEY_ADDED) : sts; } if (license_received_) { // renewal return RenewKey(key_response); @@ -536,16 +555,16 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { // to be created. CdmResponseType sts; std::string provider_session_token; - if (supports_usage_info()) { + if (SupportsUsageTable()) { if (license_parser_->ExtractProviderSessionToken(key_response, &provider_session_token) && !provider_session_token.empty()) { std::string app_id; GetApplicationId(&app_id); - sts = usage_table_header_->AddEntry( - crypto_session_.get(), is_offline_, key_set_id_, - DeviceFiles::GetUsageInfoFileName(app_id), key_response, - &usage_entry_number_); + sts = usage_table_->AddEntry(crypto_session_.get(), is_offline_, + key_set_id_, + DeviceFiles::GetUsageInfoFileName(app_id), + key_response, &usage_entry_index_); crypto_metrics_->usage_table_header_add_entry_.Increment(sts); if (sts != NO_ERROR) return sts; } @@ -560,11 +579,10 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { version_info.license_service_version()); // Update or invalidate entry if usage table header+entries are supported - if (!provider_session_token.empty() && supports_usage_info()) { + if (!provider_session_token.empty() && SupportsUsageTable()) { if (sts != KEY_ADDED) { - const CdmResponseType invalidate_sts = - usage_table_header_->InvalidateEntry( - usage_entry_number_, true, file_handle_.get(), crypto_metrics_); + const CdmResponseType invalidate_sts = usage_table_->InvalidateEntry( + usage_entry_index_, true, file_handle_.get(), crypto_metrics_); crypto_metrics_->usage_table_header_delete_entry_.Increment( invalidate_sts); if (invalidate_sts != NO_ERROR) { @@ -574,7 +592,8 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { } } - if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts; + if (sts != KEY_ADDED) + return (sts == KEY_ERROR) ? CdmResponseType(ADD_KEY_ERROR) : sts; license_received_ = true; key_response_ = key_response; @@ -584,9 +603,9 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { license_parser_->provider_session_token().size()); if ((is_offline_ || has_provider_session_token()) && !is_temporary_) { - if (has_provider_session_token() && supports_usage_info()) { - usage_table_header_->UpdateEntry(usage_entry_number_, - crypto_session_.get(), &usage_entry_); + if (has_provider_session_token() && SupportsUsageTable()) { + usage_table_->UpdateEntry(usage_entry_index_, crypto_session_.get(), + &usage_entry_); } if (!is_offline_) @@ -597,13 +616,13 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) { } has_license_been_loaded_ = true; - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } RETURN_STATUS_IF_NULL(query_response); @@ -626,9 +645,9 @@ CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) { QUERY_VALUE_SECURITY_LEVEL_UNKNOWN; break; default: - return INVALID_QUERY_KEY; + return CdmResponseType(INVALID_QUERY_KEY); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmSession::SetServiceCertificate( @@ -649,19 +668,19 @@ CdmResponseType CdmSession::QueryOemCryptoSessionId( CdmQueryMap* query_response) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } RETURN_STATUS_IF_NULL(query_response); (*query_response)[QUERY_KEY_OEMCRYPTO_SESSION_ID] = std::to_string(crypto_session_->oec_session_id()); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Decrypt() - Accept encrypted buffer and return decrypted data. CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) { if (!initialized_) { - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } bool is_protected = std::any_of( @@ -680,18 +699,19 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) { // the security level is not high enough yet. if (is_protected) { if (!policy_engine_->CanDecryptContent(params.key_id)) { - if (policy_engine_->IsLicenseForFuture()) return DECRYPT_NOT_READY; + if (policy_engine_->IsLicenseForFuture()) + return CdmResponseType(DECRYPT_NOT_READY); if (!policy_engine_->IsSufficientOutputProtection(params.key_id)) { LOGE("Key use prohibited as HDCP or resolution requirements not met"); - return INSUFFICIENT_OUTPUT_PROTECTION; + return CdmResponseType(INSUFFICIENT_OUTPUT_PROTECTION); } - return NEED_KEY; + return CdmResponseType(NEED_KEY); } if (!policy_engine_->CanUseKeyForSecurityLevel(params.key_id)) { LOGE( "Key use prohibited as security level requirements in the policy" " not met"); - return KEY_PROHIBITED_FOR_SECURITY_LEVEL; + return CdmResponseType(KEY_PROHIBITED_FOR_SECURITY_LEVEL); } } @@ -718,7 +738,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) { const int64_t current_time = clock.GetCurrentTime(); if (policy_engine_->HasLicenseOrRentalOrPlaybackDurationExpired( current_time)) { - return NEED_KEY; + return CdmResponseType(NEED_KEY); } } @@ -731,7 +751,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) { CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyRequest* key_request) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } RETURN_STATUS_IF_NULL(key_request); @@ -747,14 +767,14 @@ CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyRequest* key_request) { } key_request_type_ = key_request->type; license_request_latency_.Start(); // Start or restart timer. - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } // RenewKey() - Accept renewal response and update key info. CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } CdmResponseType sts = license_parser_->HandleKeyUpdateResponse( /* is renewal */ true, @@ -763,35 +783,36 @@ CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) { // Record the timing on success. UpdateRequestLatencyTiming(sts); - if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RENEW_KEY_ERROR_1 : sts; + if (sts != KEY_ADDED) + return (sts == KEY_ERROR) ? CdmResponseType(RENEW_KEY_ERROR_1) : sts; if (is_offline_) { offline_key_renewal_response_ = key_response; if (!StoreLicense(kLicenseStateActive, nullptr /* error_detail */)) - return RENEW_KEY_ERROR_2; + return CdmResponseType(RENEW_KEY_ERROR_2); } - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } RETURN_STATUS_IF_NULL(key_request); is_release_ = true; license_request_latency_.Clear(); CdmResponseType status = license_parser_->PrepareKeyUpdateRequest( - false, app_parameters_, usage_table_header_ == nullptr ? nullptr : this, + false, app_parameters_, usage_table_ == nullptr ? nullptr : this, &key_request->message, &key_request->url); key_request->type = kKeyRequestTypeRelease; if (KEY_MESSAGE != status) return status; - if (has_provider_session_token() && supports_usage_info()) { - status = usage_table_header_->UpdateEntry( - usage_entry_number_, crypto_session_.get(), &usage_entry_); + if (has_provider_session_token() && SupportsUsageTable()) { + status = usage_table_->UpdateEntry(usage_entry_index_, + crypto_session_.get(), &usage_entry_); if (status != NO_ERROR) { LOGE("Update usage entry failed: status = %d", static_cast(status)); @@ -801,24 +822,24 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) { if (is_offline_) { // Mark license as being released if (!StoreLicense(kLicenseStateReleasing, nullptr)) - return RELEASE_KEY_REQUEST_ERROR; + return CdmResponseType(RELEASE_KEY_REQUEST_ERROR); } else if (!usage_provider_session_token_.empty()) { - if (supports_usage_info()) { - if (!UpdateUsageInfo()) return RELEASE_USAGE_INFO_FAILED; + if (SupportsUsageTable()) { + if (!UpdateUsageInfo()) return CdmResponseType(RELEASE_USAGE_INFO_FAILED); } } key_request_type_ = key_request->type; license_request_latency_.Start(); // Start or restart timer. - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } // ReleaseKey() - Accept release response and release license. CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } CdmResponseType sts = license_parser_->HandleKeyUpdateResponse( /* is renewal */ false, @@ -826,19 +847,20 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) { // Record the timing on success. UpdateRequestLatencyTiming(sts); - if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RELEASE_KEY_ERROR : sts; + if (sts != KEY_ADDED) + return (sts == KEY_ERROR) ? CdmResponseType(RELEASE_KEY_ERROR) : sts; return RemoveLicense(); } -CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) { +CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_index) { if (!initialized_) { LOGE("CDM session not initialized"); - return NOT_INITIALIZED_ERROR; + return CdmResponseType(NOT_INITIALIZED_ERROR); } - if (!supports_usage_info()) { + if (!SupportsUsageTable()) { LOGE("Cannot delete entry, usage table not supported"); - return INCORRECT_USAGE_SUPPORT_TYPE_1; + return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_1); } // The usage entry cannot be deleted if it has a crypto session handling @@ -851,19 +873,19 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) { crypto_metrics_, crypto_session_open_, sts, requested_security_level_); if (sts != NO_ERROR) return sts; - usage_table_header_ = nullptr; + usage_table_ = nullptr; bool has_support = false; - if (crypto_session_->HasUsageInfoSupport(&has_support) && has_support) { - usage_table_header_ = crypto_session_->GetUsageTableHeader(); + if (crypto_session_->HasUsageTableSupport(&has_support) && has_support) { + usage_table_ = crypto_session_->GetUsageTable(); } - if (usage_table_header_ == nullptr) { + if (usage_table_ == nullptr) { LOGE("Usage table header unavailable"); - return INCORRECT_USAGE_SUPPORT_TYPE_1; + return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_1); } - sts = usage_table_header_->InvalidateEntry( - usage_entry_number, true, file_handle_.get(), crypto_metrics_); + sts = usage_table_->InvalidateEntry(usage_entry_index, true, + file_handle_.get(), crypto_metrics_); crypto_metrics_->usage_table_header_delete_entry_.Increment(sts); return sts; } @@ -886,15 +908,14 @@ bool CdmSession::GenerateKeySetId(bool atsc_mode_enabled, CdmKeySetId* key_set_id) { RETURN_FALSE_IF_NULL(key_set_id); - std::vector random_data( - (kKeySetIdLength - sizeof(KEY_SET_ID_PREFIX)) / 2, 0); - while (key_set_id->empty()) { - if (crypto_session_->GetRandom(random_data.size(), &random_data[0]) != - NO_ERROR) { + constexpr size_t random_size = + (kKeySetIdLength - sizeof(KEY_SET_ID_PREFIX)) / 2; + std::string random_data = wvutil::CdmRandom::RandomData(random_size); + if (random_data.size() != random_size) { + LOGE("Error generating random id."); return false; } - if (atsc_mode_enabled) *key_set_id = ATSC_KEY_SET_ID_PREFIX + wvutil::b2a_hex(random_data); else @@ -913,32 +934,32 @@ bool CdmSession::GenerateKeySetId(bool atsc_mode_enabled, CdmResponseType CdmSession::StoreLicense() { if (is_temporary_) { LOGE("Session type prohibits storage"); - return STORAGE_PROHIBITED; + return CdmResponseType(STORAGE_PROHIBITED); } if (is_offline_) { if (key_set_id_.empty()) { LOGE("No key set ID"); - return EMPTY_KEYSET_ID; + return CdmResponseType(EMPTY_KEYSET_ID); } if (!license_parser_->is_offline()) { LOGE("License policy prohibits storage"); - return OFFLINE_LICENSE_PROHIBITED; + return CdmResponseType(OFFLINE_LICENSE_PROHIBITED); } if (!StoreLicense(kLicenseStateActive, nullptr)) { LOGE("Unable to store license"); - return STORE_LICENSE_ERROR_1; + return CdmResponseType(STORE_LICENSE_ERROR_1); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // if (is_offline_) std::string provider_session_token = license_parser_->provider_session_token(); if (provider_session_token.empty()) { LOGE("No provider session token and not offline"); - return STORE_LICENSE_ERROR_2; + return CdmResponseType(STORE_LICENSE_ERROR_2); } std::string app_id; @@ -946,11 +967,11 @@ CdmResponseType CdmSession::StoreLicense() { if (!file_handle_->StoreUsageInfo( provider_session_token, key_request_, key_response_, DeviceFiles::GetUsageInfoFileName(app_id), key_set_id_, usage_entry_, - usage_entry_number_, drm_certificate_, wrapped_private_key_)) { + usage_entry_index_, drm_certificate_, wrapped_private_key_)) { LOGE("Unable to store usage info"); // Usage info file is corrupt. Delete current usage entry and file. - if (supports_usage_info()) { - DeleteUsageEntry(usage_entry_number_); + if (SupportsUsageTable()) { + DeleteUsageEntry(usage_entry_index_); } else { LOGW("Cannot store, usage table not supported"); } @@ -958,9 +979,9 @@ CdmResponseType CdmSession::StoreLicense() { file_handle_->DeleteAllUsageInfoForApp( DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens); - return STORE_USAGE_INFO_ERROR; + return CdmResponseType(STORE_USAGE_INFO_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } bool CdmSession::StoreLicense(CdmOfflineLicenseState state, int* error_detail) { @@ -979,7 +1000,7 @@ bool CdmSession::StoreLicense(CdmOfflineLicenseState state, int* error_detail) { policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry_, - usage_entry_number_, + usage_entry_index_, drm_certificate_, wrapped_private_key_}; @@ -998,17 +1019,17 @@ CdmResponseType CdmSession::RemoveKeys() { crypto_metrics_, crypto_session_open_, sts, requested_security_level_); policy_engine_.reset( new PolicyEngine(session_id_, nullptr, crypto_session_.get())); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmSession::RemoveLicense() { if (is_offline_ || has_provider_session_token()) { - if (has_provider_session_token() && supports_usage_info()) { - DeleteUsageEntry(usage_entry_number_); + if (has_provider_session_token() && SupportsUsageTable()) { + DeleteUsageEntry(usage_entry_index_); } DeleteLicenseFile(); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } bool CdmSession::DeleteLicenseFile() { @@ -1052,19 +1073,19 @@ void CdmSession::GetApplicationId(std::string* app_id) { } CdmResponseType CdmSession::UpdateUsageEntryInformation() { - if (!has_provider_session_token() || !supports_usage_info()) { + if (!has_provider_session_token() || !SupportsUsageTable()) { LOGE("Unexpected state: usage_support = %s, PST present = %s, ", - supports_usage_info() ? "true" : "false", + SupportsUsageTable() ? "true" : "false", has_provider_session_token() ? "yes" : "no"); - return INCORRECT_USAGE_SUPPORT_TYPE_2; + return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_2); } - CdmResponseType sts = NO_ERROR; + CdmResponseType sts(NO_ERROR); // TODO(blueeyes): Add measurements to all UpdateEntry calls in a way that // allos us to isolate this particular use case within // UpdateUsageEntryInformation. - M_TIME(sts = usage_table_header_->UpdateEntry( - usage_entry_number_, crypto_session_.get(), &usage_entry_), + M_TIME(sts = usage_table_->UpdateEntry(usage_entry_index_, + crypto_session_.get(), &usage_entry_), crypto_metrics_, usage_table_header_update_entry_, sts); if (sts != NO_ERROR) return sts; @@ -1075,7 +1096,7 @@ CdmResponseType CdmSession::UpdateUsageEntryInformation() { else if (!usage_provider_session_token_.empty()) UpdateUsageInfo(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer, @@ -1150,7 +1171,7 @@ bool CdmSession::UpdateUsageInfo() { usage_data.license = key_response_; usage_data.key_set_id = key_set_id_; usage_data.usage_entry = usage_entry_; - usage_data.usage_entry_number = usage_entry_number_; + usage_data.usage_entry_index = usage_entry_index_; return file_handle_->UpdateUsageInfo( DeviceFiles::GetUsageInfoFileName(app_id), usage_data); @@ -1168,15 +1189,15 @@ bool CdmSession::VerifyOfflineUsageEntry() { // Check that the current license is the same as the expected // entry in the usage table. It is possible that the license has // been removed from the usage table but the license file remains. - if (usage_entry_number_ >= usage_table_header_->size()) { - LOGD("License usage entry does not exist: entry_number = %u, size = %zu", - usage_entry_number_, usage_table_header_->size()); + if (usage_entry_index_ >= usage_table_->size()) { + LOGD("License usage entry does not exist: entry_index = %u, size = %zu", + usage_entry_index_, usage_table_->size()); return false; } - const CdmUsageEntryInfo& usage_entry_info = - usage_table_header_->usage_entry_info().at(usage_entry_number_); - if (usage_entry_info.storage_type != kStorageLicense || - usage_entry_info.key_set_id != key_set_id_) { + const CdmUsageEntryInfo& entry_info = + usage_table_->entry_info_list().at(usage_entry_index_); + if (entry_info.storage_type != kStorageLicense || + entry_info.key_set_id != key_set_id_) { LOGD("License usage entry does not match"); return false; } @@ -1191,7 +1212,7 @@ CdmResponseType CdmSession::LoadPrivateKey() { if (file_handle_->RetrieveCertificate(atsc_mode_enabled_, &drm_certificate, &private_key, nullptr, &system_id) != DeviceFiles::kCertificateValid) { - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); } return LoadPrivateKey(drm_certificate, private_key); @@ -1209,7 +1230,7 @@ CdmResponseType CdmSession::LoadPrivateOrLegacyKey( if (file_handle_->RetrieveLegacyCertificate( &drm_certificate, &wrapped_private_key, nullptr, nullptr) != DeviceFiles::kCertificateValid) - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); return LoadPrivateKey(drm_certificate, wrapped_private_key); } @@ -1222,22 +1243,65 @@ CdmResponseType CdmSession::LoadPrivateKey( crypto_metrics_, crypto_session_load_certificate_private_key_, load_cert_sts); - switch (load_cert_sts) { + switch (load_cert_sts.code()) { case NO_ERROR: metrics_->drm_certificate_key_type_.Record( DrmKeyTypeToMetricValue(private_key.type())); drm_certificate_ = drm_certificate; - wrapped_private_key_ = std::move(private_key); - return NO_ERROR; + wrapped_private_key_ = private_key; + return CdmResponseType(NO_ERROR); case SESSION_LOST_STATE_ERROR: case SYSTEM_INVALIDATED_ERROR: return load_cert_sts; default: - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); } } +// Use a change in system ID as an indication that Root of Trust +// has been renewed. +bool CdmSession::HasRootOfTrustBeenRenewed() { + if (atsc_mode_enabled_) return false; + // Ignore System ID changes for L3 as the root of trust might not have + // changed even if the system ID has + if (crypto_session_->GetSecurityLevel() == kSecurityLevelL3) return false; + + std::string drm_certificate; + CryptoWrappedKey private_key; + uint32_t drm_cert_system_id; + if (file_handle_->RetrieveCertificate( + atsc_mode_enabled_, &drm_certificate, &private_key, nullptr, + &drm_cert_system_id) != DeviceFiles::kCertificateValid) { + LOGE("Failed to retrieve DRM certificate"); + return true; + } + + wvutil::FileSystem global_file_system; + SystemIdExtractor system_id_extractor(kLevelDefault, crypto_session_.get(), + &global_file_system); + + SystemIdExtractor* extractor = &system_id_extractor; + if (mock_system_id_extractor_) { + extractor = mock_system_id_extractor_.get(); + } + + uint32_t system_id; + if (!extractor->ExtractSystemId(&system_id)) { + LOGW("ExtractSystemId failed"); + return false; + } + + if (system_id == drm_cert_system_id) return false; + + LOGI( + "System Id changed from %d to %d. Removing certificates and " + "reprovisioning", + drm_cert_system_id, system_id); + file_handle_->RemoveCertificate(); + return true; +} + CdmResponseType CdmSession::LoadCastPrivateKey( const CryptoWrappedKey& private_key) { return crypto_session_->LoadCertificatePrivateKey(private_key); @@ -1269,4 +1333,8 @@ void CdmSession::set_policy_engine(PolicyEngine* policy_engine) { void CdmSession::set_file_handle(DeviceFiles* file_handle) { file_handle_.reset(file_handle); } + +void CdmSession::set_system_id_extractor(SystemIdExtractor* extractor) { + mock_system_id_extractor_.reset(extractor); +} } // namespace wvcdm diff --git a/core/src/usage_table_header.cpp b/core/src/cdm_usage_table.cpp similarity index 58% rename from core/src/usage_table_header.cpp rename to core/src/cdm_usage_table.cpp index 4d57dc72..f560e6d1 100644 --- a/core/src/usage_table_header.cpp +++ b/core/src/cdm_usage_table.cpp @@ -2,7 +2,7 @@ // source code may only be used and distributed under the Widevine License // Agreement. -#include "usage_table_header.h" +#include "cdm_usage_table.h" #include #include @@ -71,7 +71,7 @@ bool ParseLicenseFromLicenseMessage(const CdmKeyResponse& license_message, bool RetrieveOfflineLicense(DeviceFiles* device_files, const std::string& key_set_id, CdmKeyResponse* license_message, - uint32_t* usage_entry_number) { + UsageEntryIndex* entry_index) { if (device_files == nullptr) { LOGE("DeviceFiles handle is null"); return false; @@ -80,8 +80,8 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files, LOGE("Output parameter |license_message| is null"); return false; } - if (usage_entry_number == nullptr) { - LOGE("Output parameter |usage_entry_number| is null"); + if (entry_index == nullptr) { + LOGE("Output parameter |entry_index| is null"); return false; } DeviceFiles::CdmLicenseData license_data; @@ -92,7 +92,7 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files, return false; } *license_message = std::move(license_data.license); - *usage_entry_number = license_data.usage_entry_number; + *entry_index = license_data.usage_entry_index; return true; } @@ -100,7 +100,7 @@ bool RetrieveUsageInfoLicense(DeviceFiles* device_files, const std::string& usage_info_file_name, const std::string& key_set_id, CdmKeyResponse* license_message, - uint32_t* usage_entry_number) { + UsageEntryIndex* entry_index) { if (device_files == nullptr) { LOGE("DeviceFiles handle is null"); return false; @@ -109,18 +109,18 @@ bool RetrieveUsageInfoLicense(DeviceFiles* device_files, LOGE("Output parameter |license_message| is null"); return false; } - if (usage_entry_number == nullptr) { - LOGE("Output parameter |usage_entry_number| is null"); + if (entry_index == nullptr) { + LOGE("Output parameter |entry_index| is null"); return false; } - CdmUsageEntry usage_entry; + UsageEntry entry; std::string provider_session_token; CdmKeyMessage license_request; std::string drm_certificate; CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( usage_info_file_name, key_set_id, &provider_session_token, - &license_request, license_message, &usage_entry, usage_entry_number, + &license_request, license_message, &entry, entry_index, &drm_certificate, &wrapped_private_key)) { LOGW( "Failed to retrieve usage information: " @@ -152,13 +152,13 @@ RequestedSecurityLevel CdmSecurityLevelToRequestedLevel( } } // namespace -UsageTableHeader::UsageTableHeader() : clock_ref_(&clock_) { +CdmUsageTable::CdmUsageTable() : clock_ref_(&clock_) { file_system_.reset(new wvutil::FileSystem()); device_files_.reset(new DeviceFiles(file_system_.get())); } -bool UsageTableHeader::Init(CdmSecurityLevel security_level, - CryptoSession* crypto_session) { +bool CdmUsageTable::Init(CdmSecurityLevel security_level, + CryptoSession* crypto_session) { LOGD("security_level = %s", CdmSecurityLevelToString(security_level)); if (crypto_session == nullptr) { LOGE("No crypto session provided"); @@ -192,21 +192,20 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level, return RestoreTable(crypto_session) || CreateNewTable(crypto_session); } -bool UsageTableHeader::RestoreTable(CryptoSession* const crypto_session) { +bool CdmUsageTable::RestoreTable(CryptoSession* const crypto_session) { bool run_lru_upgrade = false; - if (!device_files_->RetrieveUsageTableInfo( - &usage_table_header_, &usage_entry_info_, &run_lru_upgrade)) { + if (!device_files_->RetrieveUsageTableInfo(&header_, &entry_info_list_, + &run_lru_upgrade)) { LOGW("Could not retrieve usage table"); return false; } LOGI("Found usage table to restore: entry_count = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); - const CdmResponseType status = crypto_session->LoadUsageTableHeader( - requested_security_level_, usage_table_header_); + const CdmResponseType status = + crypto_session->LoadUsageTableHeader(requested_security_level_, header_); if (status != NO_ERROR) { - LOGE("Failed to load usage table header: sts = %d", - static_cast(status)); + LOGE("Failed to load usage table header: sts = %d", status.ToInt()); return false; } @@ -225,18 +224,18 @@ bool UsageTableHeader::RestoreTable(CryptoSession* const crypto_session) { return true; } -bool UsageTableHeader::CreateNewTable(CryptoSession* const crypto_session) { +bool CdmUsageTable::CreateNewTable(CryptoSession* const crypto_session) { LOGD("Removing all usage table files"); // Existing files need to be deleted to avoid attempts to restore // licenses which no longer have a usage entry. device_files_->DeleteAllLicenses(); device_files_->DeleteAllUsageInfo(); device_files_->DeleteUsageTableInfo(); - usage_entry_info_.clear(); - usage_table_header_.clear(); + entry_info_list_.clear(); + header_.clear(); const CdmResponseType status = crypto_session->CreateUsageTableHeader( - requested_security_level_, &usage_table_header_); + requested_security_level_, &header_); if (status != NO_ERROR) { LOGE("Failed to create new usage table header"); return false; @@ -249,133 +248,130 @@ bool UsageTableHeader::CreateNewTable(CryptoSession* const crypto_session) { return true; } -CdmResponseType UsageTableHeader::AddEntry( - CryptoSession* crypto_session, bool persistent_license, - const CdmKeySetId& key_set_id, const std::string& usage_info_file_name, - const CdmKeyResponse& license_message, uint32_t* usage_entry_number) { +CdmResponseType CdmUsageTable::AddEntry(CryptoSession* crypto_session, + bool persistent_license, + const CdmKeySetId& key_set_id, + const std::string& usage_info_file_name, + const CdmKeyResponse& license_message, + UsageEntryIndex* entry_index) { LOGD("key_set_id = %s, type = %s, current_size = %zu", IdToString(key_set_id), persistent_license ? "OfflineLicense" : "Streaming", - usage_entry_info_.size()); + entry_info_list_.size()); metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics(); if (metrics == nullptr) metrics = &alternate_crypto_metrics_; - TableLock auto_lock(usage_table_header_lock_); + TableLock auto_lock(lock_); - CdmResponseType status = CreateEntry(crypto_session, usage_entry_number); + CdmResponseType status = CreateEntry(crypto_session, entry_index); if (status == INSUFFICIENT_CRYPTO_RESOURCES) { LOGW("Usage table may be full, releasing oldest entry: size = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); status = ReleaseOldestEntry(metrics); if (status == NO_ERROR) { - status = CreateEntry(crypto_session, usage_entry_number); + status = CreateEntry(crypto_session, entry_index); } } if (status != NO_ERROR) return status; - status = RelocateNewEntry(crypto_session, usage_entry_number); + status = RelocateNewEntry(crypto_session, entry_index); if (status != NO_ERROR) return status; if (persistent_license) { - SetOfflineEntryInfo(*usage_entry_number, key_set_id, license_message); + SetOfflineEntryInfo(*entry_index, key_set_id, license_message); } else { - SetUsageInfoEntryInfo(*usage_entry_number, key_set_id, - usage_info_file_name); + SetUsageInfoEntryInfo(*entry_index, key_set_id, usage_info_file_name); } status = RefitTable(crypto_session); if (status != NO_ERROR) { - usage_entry_info_[*usage_entry_number].Clear(); + entry_info_list_[*entry_index].Clear(); return status; } // Call to update the usage table header, but don't store the usage // entry. If the entry is used by the CDM, the CDM session will make // subsequent calls to update the usage entry and store that entry. - std::string usage_entry; - status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry); + UsageEntry entry; + status = crypto_session->UpdateUsageEntry(&header_, &entry); if (status != NO_ERROR) { - LOGE("Failed to update new usage entry: usage_entry_number = %u", - *usage_entry_number); - usage_entry_info_[*usage_entry_number].Clear(); + LOGE("Failed to update new usage entry: entry_index = %u", *entry_index); + entry_info_list_[*entry_index].Clear(); return status; } StoreTable(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session, - const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number) { +CdmResponseType CdmUsageTable::LoadEntry(CryptoSession* crypto_session, + const UsageEntry& entry, + UsageEntryIndex entry_index) { { - LOGD("usage_entry_number = %u", usage_entry_number); - std::unique_lock auto_lock(usage_table_header_lock_); + LOGD("entry_index = %u", entry_index); + std::unique_lock auto_lock(lock_); - if (usage_entry_number >= usage_entry_info_.size()) { + if (entry_index >= entry_info_list_.size()) { LOGE( - "Requested usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); - return USAGE_INVALID_LOAD_ENTRY; + "Requested usage entry index is larger than table size: " + "entry_index = %u, table_size = %zu", + entry_index, entry_info_list_.size()); + return CdmResponseType(USAGE_INVALID_LOAD_ENTRY); } } - metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics(); - if (metrics == nullptr) metrics = &alternate_crypto_metrics_; const CdmResponseType status = - crypto_session->LoadUsageEntry(usage_entry_number, usage_entry); + crypto_session->LoadUsageEntry(entry_index, entry); if (status == NO_ERROR) { - usage_entry_info_[usage_entry_number].last_use_time = GetCurrentTime(); + entry_info_list_[entry_index].last_use_time = GetCurrentTime(); } return status; } -CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number, - CryptoSession* crypto_session, - CdmUsageEntry* usage_entry) { - LOGD("usage_entry_number = %u", usage_entry_number); - std::unique_lock auto_lock(usage_table_header_lock_); - if (usage_entry_number >= usage_entry_info_.size()) { - LOGE("Usage entry number %u is larger than usage entry size %zu", - usage_entry_number, usage_entry_info_.size()); - return USAGE_INVALID_PARAMETERS_2; +CdmResponseType CdmUsageTable::UpdateEntry(UsageEntryIndex entry_index, + CryptoSession* crypto_session, + UsageEntry* entry) { + LOGD("entry_index = %u", entry_index); + std::unique_lock auto_lock(lock_); + if (entry_index >= entry_info_list_.size()) { + LOGE("Usage entry index %u is larger than usage entry size %zu", + entry_index, entry_info_list_.size()); + return CdmResponseType(USAGE_INVALID_PARAMETERS_2); } - CdmResponseType status = - crypto_session->UpdateUsageEntry(&usage_table_header_, usage_entry); + CdmResponseType status = crypto_session->UpdateUsageEntry(&header_, entry); if (status != NO_ERROR) return status; - usage_entry_info_[usage_entry_number].last_use_time = GetCurrentTime(); + entry_info_list_[entry_index].last_use_time = GetCurrentTime(); StoreTable(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::InvalidateEntry( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, +CdmResponseType CdmUsageTable::InvalidateEntry( + UsageEntryIndex entry_index, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { - LOGD("usage_entry_number = %u", usage_entry_number); - TableLock auto_lock(usage_table_header_lock_); - return InvalidateEntryInternal(usage_entry_number, defrag_table, device_files, + LOGD("entry_index = %u", entry_index); + TableLock auto_lock(lock_); + return InvalidateEntryInternal(entry_index, defrag_table, device_files, metrics); } -CdmResponseType UsageTableHeader::InvalidateEntryInternal( - uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files, +CdmResponseType CdmUsageTable::InvalidateEntryInternal( + UsageEntryIndex entry_index, bool defrag_table, DeviceFiles* device_files, metrics::CryptoMetrics* metrics) { // OEMCrypto does not have any concept of "deleting" an entry. // Instead, the CDM marks the entry's meta data as invalid (storage // type unknown) and then performs a "defrag" of the OEMCrypto table. - if (usage_entry_number >= usage_entry_info_.size()) { + if (entry_index >= entry_info_list_.size()) { LOGE( - "Usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); - return USAGE_INVALID_PARAMETERS_1; + "Usage entry index is larger than table size: " + "entry_index = %u, table_size = %zu", + entry_index, entry_info_list_.size()); + return CdmResponseType(USAGE_INVALID_PARAMETERS_1); } - usage_entry_info_[usage_entry_number].Clear(); + entry_info_list_[entry_index].Clear(); if (defrag_table) { // The defrag operation calls many OEMCrypto functions that are @@ -395,29 +391,29 @@ CdmResponseType UsageTableHeader::InvalidateEntryInternal( } if (status == SYSTEM_INVALIDATED_ERROR) { LOGE("Invalidate entry failed due to system invalidation error"); - return SYSTEM_INVALIDATED_ERROR; + return CdmResponseType(SYSTEM_INVALIDATED_ERROR); } } else { StoreTable(); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -size_t UsageTableHeader::UsageInfoCount() const { +size_t CdmUsageTable::UsageInfoCount() const { LOGV("Locking to count usage info (streaming license) entries"); - return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(), + return std::count_if(entry_info_list_.cbegin(), entry_info_list_.cend(), EntryIsUsageInfo); } -size_t UsageTableHeader::OfflineEntryCount() const { +size_t CdmUsageTable::OfflineEntryCount() const { LOGV("Locking to count offline license entries"); - return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(), + return std::count_if(entry_info_list_.cbegin(), entry_info_list_.cend(), EntryIsOfflineLicense); } -bool UsageTableHeader::OpenSessionCheck(CryptoSession* const crypto_session) { - // The UsageTableHeader for the specified |requested_security_level_| +bool CdmUsageTable::OpenSessionCheck(CryptoSession* const crypto_session) { + // The CdmUsageTable for the specified |requested_security_level_| // MUST be initialized before any sessions are opened. size_t session_count = 0; const CdmResponseType status = crypto_session->GetNumberOfOpenSessions( @@ -426,13 +422,13 @@ bool UsageTableHeader::OpenSessionCheck(CryptoSession* const crypto_session) { LOGE( "Cannot initialize usage table header with open crypto session: " "status = %d, count = %zu", - static_cast(status), session_count); + status.ToInt(), session_count); return false; } return true; } -bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { +bool CdmUsageTable::CapacityCheck(CryptoSession* const crypto_session) { // If the table is around capacity or if unlimited and the table is // larger than the minimally required capacity, then a test must be // performed to ensure that the usage table is not in a state which @@ -440,7 +436,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { const size_t capacity_threshold = HasUnlimitedTableCapacity() ? kMinimumUsageTableEntriesSupported : potential_table_capacity(); - if (usage_entry_info_.size() <= capacity_threshold) { + if (entry_info_list_.size() <= capacity_threshold) { // No need to perform test if below capacity. return true; } @@ -460,28 +456,27 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { local_crypto_session->Open(requested_security_level_); if (status != NO_ERROR) { LOGE("Failed to open crypto session for capacity test: sts = %d", - static_cast(status)); + status.ToInt()); return false; } - uint32_t temporary_usage_entry_number; + UsageEntryIndex temporary_entry_index; status = AddEntry(local_crypto_session, true, kDummyKeySetId, kEmptyString, - kEmptyString, &temporary_usage_entry_number); + kEmptyString, &temporary_entry_index); if (status != NO_ERROR) { - LOGE("Failed to add entry for capacity test: sts = %d", - static_cast(status)); + LOGE("Failed to add entry for capacity test: sts = %d", status.ToInt()); return false; } status = - InvalidateEntry(temporary_usage_entry_number, + InvalidateEntry(temporary_entry_index, /* defrag_table = */ true, device_files_.get(), metrics); if (status != NO_ERROR) { LOGE("Failed to invalidate entry for capacity test: sts = %d", - static_cast(status)); + status.ToInt()); return false; } - if (usage_entry_info_.size() > temporary_usage_entry_number) { + if (entry_info_list_.size() > temporary_entry_index) { // The entry should have been deleted from the usage table, // not just marked as type unknown. Failure to call // Shrink() may be an indicator of other issues. @@ -491,7 +486,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) { return true; } -bool UsageTableHeader::DetermineTableCapacity(CryptoSession* crypto_session) { +bool CdmUsageTable::DetermineTableCapacity(CryptoSession* crypto_session) { if (!crypto_session->GetMaximumUsageTableEntries( requested_security_level_, &potential_table_capacity_)) { LOGW( @@ -515,91 +510,85 @@ bool UsageTableHeader::DetermineTableCapacity(CryptoSession* crypto_session) { return true; } -CdmResponseType UsageTableHeader::CreateEntry( - CryptoSession* const crypto_session, uint32_t* usage_entry_number) { - const CdmResponseType status = - crypto_session->CreateUsageEntry(usage_entry_number); +CdmResponseType CdmUsageTable::CreateEntry(CryptoSession* const crypto_session, + UsageEntryIndex* entry_index) { + const CdmResponseType status = crypto_session->CreateUsageEntry(entry_index); if (status != NO_ERROR) return status; - // If the new entry number is smaller than expected, then the usage + // If the new entry index is smaller than expected, then the usage // table may be out of sync or OEMCrypto has been rolled back. // Not safe to continue. - if (*usage_entry_number < usage_entry_info_.size()) { + if (*entry_index < entry_info_list_.size()) { LOGE( - "New entry number is smaller than table size: " - "entry_info_number = %u, table_size = %zu", - *usage_entry_number, usage_entry_info_.size()); - return USAGE_INVALID_NEW_ENTRY; + "New entry index is smaller than table size: " + "entry_index = %u, table_size = %zu", + *entry_index, entry_info_list_.size()); + return CdmResponseType(USAGE_INVALID_NEW_ENTRY); } - LOGI("usage_entry_number = %u", *usage_entry_number); - const size_t previous_size = usage_entry_info_.size(); - usage_entry_info_.resize(*usage_entry_number + 1); - if (*usage_entry_number > previous_size) { + LOGI("entry_index = %u", *entry_index); + const size_t previous_size = entry_info_list_.size(); + entry_info_list_.resize(*entry_index + 1); + if (*entry_index > previous_size) { LOGW( - "New entry number is larger than table size, resizing: " - "entry_info_number = %u, table_size = %zu", - *usage_entry_number, previous_size); - for (size_t i = previous_size; i < usage_entry_info_.size() - 1; ++i) { - usage_entry_info_[i].Clear(); + "New entry index is larger than table size, resizing: " + "entry_index = %u, table_size = %zu", + *entry_index, previous_size); + for (size_t i = previous_size; i < entry_info_list_.size() - 1; ++i) { + entry_info_list_[i].Clear(); } } - usage_entry_info_[*usage_entry_number].Clear(); - return NO_ERROR; + entry_info_list_[*entry_index].Clear(); + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::RelocateNewEntry( - CryptoSession* const crypto_session, uint32_t* usage_entry_number) { - static constexpr uint32_t kMinimumEntryNumber = 0; - const uint32_t initial_entry_number = *usage_entry_number; - if (initial_entry_number == kMinimumEntryNumber) { +CdmResponseType CdmUsageTable::RelocateNewEntry( + CryptoSession* const crypto_session, UsageEntryIndex* entry_index) { + static constexpr UsageEntryIndex kMinimumEntryNumber = 0; + const UsageEntryIndex initial_entry_index = *entry_index; + if (initial_entry_index == kMinimumEntryNumber) { // First entry in the table. - return NO_ERROR; + return CdmResponseType(NO_ERROR); } - uint32_t unoccupied_entry_number = initial_entry_number; - for (uint32_t i = kMinimumEntryNumber; i < initial_entry_number; i++) { + UsageEntryIndex unoccupied_entry_index = initial_entry_index; + for (UsageEntryIndex i = kMinimumEntryNumber; i < initial_entry_index; i++) { if (IsEntryUnoccupied(i)) { - unoccupied_entry_number = i; + unoccupied_entry_index = i; break; } } - if (unoccupied_entry_number == initial_entry_number) { + if (unoccupied_entry_index == initial_entry_index) { // No open position. - return NO_ERROR; + return CdmResponseType(NO_ERROR); } const CdmResponseType status = - crypto_session->MoveUsageEntry(unoccupied_entry_number); + crypto_session->MoveUsageEntry(unoccupied_entry_index); if (status == MOVE_USAGE_ENTRY_DESTINATION_IN_USE) { // Not unexpected, there is a window of time between releasing the // entry and closing the OEMCrypto session. - LOGD("Released entry still in use: index = %u", unoccupied_entry_number); - return NO_ERROR; + LOGD("Released entry still in use: index = %u", unoccupied_entry_index); + return CdmResponseType(NO_ERROR); } if (status != NO_ERROR) return status; - LOGI("Entry moved: from_index = %u, to_index = %u", initial_entry_number, - unoccupied_entry_number); - *usage_entry_number = unoccupied_entry_number; - usage_entry_info_[unoccupied_entry_number] = - std::move(usage_entry_info_[initial_entry_number]); - usage_entry_info_[initial_entry_number].Clear(); - return NO_ERROR; + LOGI("Entry moved: from_index = %u, to_index = %u", initial_entry_index, + unoccupied_entry_index); + *entry_index = unoccupied_entry_index; + entry_info_list_[unoccupied_entry_index] = + std::move(entry_info_list_[initial_entry_index]); + entry_info_list_[initial_entry_index].Clear(); + return CdmResponseType(NO_ERROR); } -bool UsageTableHeader::IsEntryUnoccupied( - const uint32_t usage_entry_number) const { - if (usage_entry_info_[usage_entry_number].storage_type != - kStorageTypeUnknown) { - return false; - } +bool CdmUsageTable::IsEntryUnoccupied(const UsageEntryIndex entry_index) const { // TODO(sigquit): Check that entry is not in use by another session. // NOTE: The |storage_type| check will protect the integrity of the // entry. Attempting to use an entry index that is used by another // session is recoverable and will not affect any opened sessions. - return true; + return entry_info_list_[entry_index].storage_type == kStorageTypeUnknown; } -void UsageTableHeader::SetOfflineEntryInfo( - const uint32_t usage_entry_number, const std::string& key_set_id, - const CdmKeyResponse& license_message) { - CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number]; +void CdmUsageTable::SetOfflineEntryInfo(const UsageEntryIndex entry_index, + const std::string& key_set_id, + const CdmKeyResponse& license_message) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_index]; entry_info.Clear(); entry_info.storage_type = kStorageLicense; entry_info.key_set_id = key_set_id; @@ -620,10 +609,10 @@ void UsageTableHeader::SetOfflineEntryInfo( } } -void UsageTableHeader::SetUsageInfoEntryInfo( - const uint32_t usage_entry_number, const std::string& key_set_id, +void CdmUsageTable::SetUsageInfoEntryInfo( + const UsageEntryIndex entry_index, const std::string& key_set_id, const std::string& usage_info_file_name) { - CdmUsageEntryInfo& entry_info = usage_entry_info_[usage_entry_number]; + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_index]; entry_info.Clear(); entry_info.storage_type = kStorageUsageInfo; entry_info.key_set_id = key_set_id; @@ -631,42 +620,42 @@ void UsageTableHeader::SetUsageInfoEntryInfo( entry_info.usage_info_file_name = usage_info_file_name; } -CdmResponseType UsageTableHeader::RefitTable( - CryptoSession* const crypto_session) { +CdmResponseType CdmUsageTable::RefitTable(CryptoSession* const crypto_session) { // Remove all unoccupied entries at end of the table. uint32_t entries_to_remove = 0; - const uint32_t old_size = static_cast(usage_entry_info_.size()); + const uint32_t old_size = static_cast(entry_info_list_.size()); for (uint32_t i = 0; i < old_size; i++) { - const uint32_t usage_entry_number = old_size - i - 1; - if (!IsEntryUnoccupied(usage_entry_number)) break; + const UsageEntryIndex entry_index = old_size - i - 1; + if (!IsEntryUnoccupied(entry_index)) break; ++entries_to_remove; } - if (entries_to_remove == 0) return NO_ERROR; + if (entries_to_remove == 0) return CdmResponseType(NO_ERROR); const uint32_t new_size = old_size - entries_to_remove; const CdmResponseType status = crypto_session->ShrinkUsageTableHeader( - requested_security_level_, new_size, &usage_table_header_); + requested_security_level_, new_size, &header_); if (status == SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE) { // This error likely indicates that another session has released // its entry via a call to InvalidateEntry(), but has yet to close // its OEMCrypto session. // Safe to assume table state is not invalidated. LOGW("Unexpected entry in use: range = [%u, %zu]", new_size, - usage_entry_info_.size() - 1); - return NO_ERROR; + entry_info_list_.size() - 1); + return CdmResponseType(NO_ERROR); } if (status != NO_ERROR) return status; - LOGD("Table shrunk: old_size = %zu, new_size = %u", usage_entry_info_.size(), + LOGD("Table shrunk: old_size = %zu, new_size = %u", entry_info_list_.size(), new_size); - usage_entry_info_.resize(new_size); - return NO_ERROR; + entry_info_list_.resize(new_size); + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::MoveEntry( - uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry, - uint32_t to_usage_entry_number, DeviceFiles* device_files, - metrics::CryptoMetrics* metrics) { - LOGD("from_usage_entry_number = %u, to_usage_entry_number = %u", - from_usage_entry_number, to_usage_entry_number); +CdmResponseType CdmUsageTable::MoveEntry(UsageEntryIndex from_entry_index, + const UsageEntry& from_entry, + UsageEntryIndex to_entry_index, + DeviceFiles* device_files, + metrics::CryptoMetrics* metrics) { + LOGD("from_entry_index = %u, to_entry_index = %u", from_entry_index, + to_entry_index); // crypto_session points to an object whose scope is this method or a test // object whose scope is the lifetime of this class @@ -679,73 +668,68 @@ CdmResponseType UsageTableHeader::MoveEntry( CdmResponseType status = crypto_session->Open(requested_security_level_); if (status != NO_ERROR) { - LOGE("Cannot open session for move: usage_entry_number = %u", - from_usage_entry_number); + LOGE("Cannot open session for move: entry_index = %u", from_entry_index); return status; } - status = - crypto_session->LoadUsageEntry(from_usage_entry_number, from_usage_entry); + status = crypto_session->LoadUsageEntry(from_entry_index, from_entry); if (status != NO_ERROR) { - LOGE("Failed to load usage entry: usage_entry_number = %u", - from_usage_entry_number); + LOGE("Failed to load usage entry: entry_index = %u", from_entry_index); return status; } - status = crypto_session->MoveUsageEntry(to_usage_entry_number); + status = crypto_session->MoveUsageEntry(to_entry_index); if (status != NO_ERROR) { LOGE( "Failed to move usage entry: " - "from_usage_entry_number = %u, to_usage_entry_number = %u", - from_usage_entry_number, to_usage_entry_number); + "from_entry_index = %u, to_entry_index = %u", + from_entry_index, to_entry_index); return status; } - usage_entry_info_[to_usage_entry_number] = - usage_entry_info_[from_usage_entry_number]; - usage_entry_info_[from_usage_entry_number].Clear(); + entry_info_list_[to_entry_index] = entry_info_list_[from_entry_index]; + entry_info_list_[from_entry_index].Clear(); - CdmUsageEntry usage_entry; - status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry); + UsageEntry entry; + status = crypto_session->UpdateUsageEntry(&header_, &entry); if (status != NO_ERROR) { - LOGE("Failed to update usage entry: usage_entry_number = %u", - to_usage_entry_number); + LOGE("Failed to update usage entry: entry_index = %u", to_entry_index); return status; } // Store the usage table and usage entry after successful move. StoreTable(); - StoreEntry(to_usage_entry_number, device_files, usage_entry); + StoreEntry(to_entry_index, device_files, entry); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, - DeviceFiles* device_files, - CdmUsageEntry* usage_entry) { - LOGD("Getting usage_entry_number = %u, storage_type = %s", usage_entry_number, +CdmResponseType CdmUsageTable::GetEntry(UsageEntryIndex entry_index, + DeviceFiles* device_files, + UsageEntry* entry) { + LOGD("Getting entry_index = %u, storage_type = %s", entry_index, CdmUsageEntryStorageTypeToString( - usage_entry_number < usage_entry_info_.size() - ? usage_entry_info_[usage_entry_number].storage_type + entry_index < entry_info_list_.size() + ? entry_info_list_[entry_index].storage_type : kStorageTypeUnknown)); - uint32_t entry_number; - switch (usage_entry_info_[usage_entry_number].storage_type) { + UsageEntryIndex retrieved_entry_index; + switch (entry_info_list_[entry_index].storage_type) { case kStorageLicense: { DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; if (!device_files->RetrieveLicense( - usage_entry_info_[usage_entry_number].key_set_id, &license_data, + entry_info_list_[entry_index].key_set_id, &license_data, &sub_error_code)) { LOGE("Failed to retrieve license: status = %d", static_cast(sub_error_code)); - return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED; + return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED); } - entry_number = license_data.usage_entry_number; - *usage_entry = std::move(license_data.usage_entry); + retrieved_entry_index = license_data.usage_entry_index; + *entry = std::move(license_data.usage_entry); break; } case kStorageUsageInfo: { @@ -756,12 +740,12 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( - usage_entry_info_[usage_entry_number].usage_info_file_name, - usage_entry_info_[usage_entry_number].key_set_id, - &provider_session_token, &license_request, &license, usage_entry, - &entry_number, &drm_certificate, &wrapped_private_key)) { + entry_info_list_[entry_index].usage_info_file_name, + entry_info_list_[entry_index].key_set_id, &provider_session_token, + &license_request, &license, entry, &retrieved_entry_index, + &drm_certificate, &wrapped_private_key)) { LOGE("Failed to retrieve usage information"); - return USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED; + return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED); } break; } @@ -770,79 +754,79 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, LOGE( "Cannot retrieve usage information with unknown storage type: " "storage_type = %d", - static_cast(usage_entry_info_[usage_entry_number].storage_type)); - return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; + static_cast(entry_info_list_[entry_index].storage_type)); + return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE); } - if (usage_entry_number != entry_number) { + if (entry_index != retrieved_entry_index) { LOGE( - "Usage entry number mismatch: expected_usage_entry_number = %u, " - "retrieved_usage_entry_number = %u", - usage_entry_number, entry_number); - return USAGE_ENTRY_NUMBER_MISMATCH; + "Usage entry index mismatch: expected_entry_index = %u, " + "retrieved_entry_index = %u", + entry_index, retrieved_entry_index); + return CdmResponseType(USAGE_ENTRY_NUMBER_MISMATCH); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, - DeviceFiles* device_files, - const CdmUsageEntry& usage_entry) { - LOGD("usage_entry_number = %u, storage_type = %s", usage_entry_number, +CdmResponseType CdmUsageTable::StoreEntry(UsageEntryIndex entry_index, + DeviceFiles* device_files, + const UsageEntry& entry) { + LOGD("entry_index = %u, storage_type = %s", entry_index, CdmUsageEntryStorageTypeToString( - usage_entry_number < usage_entry_info_.size() - ? usage_entry_info_[usage_entry_number].storage_type + entry_index < entry_info_list_.size() + ? entry_info_list_[entry_index].storage_type : kStorageTypeUnknown)); - switch (usage_entry_info_[usage_entry_number].storage_type) { + switch (entry_info_list_[entry_index].storage_type) { case kStorageLicense: { DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; if (!device_files->RetrieveLicense( - usage_entry_info_[usage_entry_number].key_set_id, &license_data, + entry_info_list_[entry_index].key_set_id, &license_data, &sub_error_code)) { LOGE("Failed to retrieve license: status = %s", DeviceFiles::ResponseTypeToString(sub_error_code)); - return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED; + return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED); } // Update. - license_data.usage_entry = usage_entry; - license_data.usage_entry_number = usage_entry_number; + license_data.usage_entry = entry; + license_data.usage_entry_index = entry_index; if (!device_files->StoreLicense(license_data, &sub_error_code)) { LOGE("Failed to store license: status = %s", DeviceFiles::ResponseTypeToString(sub_error_code)); - return USAGE_STORE_LICENSE_FAILED; + return CdmResponseType(USAGE_STORE_LICENSE_FAILED); } break; } case kStorageUsageInfo: { - CdmUsageEntry entry; - uint32_t entry_number; + UsageEntry retrieved_entry; + UsageEntryIndex retrieved_entry_index; std::string provider_session_token, init_data, key_request, key_response, key_renewal_request; std::string drm_certificate; CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( - usage_entry_info_[usage_entry_number].usage_info_file_name, - usage_entry_info_[usage_entry_number].key_set_id, - &provider_session_token, &key_request, &key_response, &entry, - &entry_number, &drm_certificate, &wrapped_private_key)) { + entry_info_list_[entry_index].usage_info_file_name, + entry_info_list_[entry_index].key_set_id, &provider_session_token, + &key_request, &key_response, &retrieved_entry, + &retrieved_entry_index, &drm_certificate, &wrapped_private_key)) { LOGE("Failed to retrieve usage information"); - return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED; + return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED); } device_files->DeleteUsageInfo( - usage_entry_info_[usage_entry_number].usage_info_file_name, - usage_entry_info_[usage_entry_number].key_set_id); + entry_info_list_[entry_index].usage_info_file_name, + entry_info_list_[entry_index].key_set_id); if (!device_files->StoreUsageInfo( provider_session_token, key_request, key_response, - usage_entry_info_[usage_entry_number].usage_info_file_name, - usage_entry_info_[usage_entry_number].key_set_id, usage_entry, - usage_entry_number, drm_certificate, wrapped_private_key)) { + entry_info_list_[entry_index].usage_info_file_name, + entry_info_list_[entry_index].key_set_id, entry, entry_index, + drm_certificate, wrapped_private_key)) { LOGE("Failed to store usage information"); - return USAGE_STORE_USAGE_INFO_FAILED; + return CdmResponseType(USAGE_STORE_USAGE_INFO_FAILED); } break; } @@ -851,16 +835,16 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, LOGE( "Cannot retrieve usage information with unknown storage type: " "storage_type = %d", - static_cast(usage_entry_info_[usage_entry_number].storage_type)); - return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; + static_cast(entry_info_list_[entry_index].storage_type)); + return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -bool UsageTableHeader::StoreTable() { +bool CdmUsageTable::StoreTable() { LOGV("Storing usage table information"); - const bool result = device_files_->StoreUsageTableInfo(usage_table_header_, - usage_entry_info_); + const bool result = + device_files_->StoreUsageTableInfo(header_, entry_info_list_); if (result) { ++store_table_counter_; } else { @@ -869,26 +853,26 @@ bool UsageTableHeader::StoreTable() { return result; } -CdmResponseType UsageTableHeader::Shrink( +CdmResponseType CdmUsageTable::Shrink( metrics::CryptoMetrics* metrics, uint32_t number_of_usage_entries_to_delete) { - LOGD("table_size = %zu, number_to_delete = %u", usage_entry_info_.size(), + LOGD("table_size = %zu, number_to_delete = %u", entry_info_list_.size(), number_of_usage_entries_to_delete); - if (usage_entry_info_.empty()) { + if (entry_info_list_.empty()) { LOGE("Usage entry info table unexpectedly empty"); - return NO_USAGE_ENTRIES; + return CdmResponseType(NO_USAGE_ENTRIES); } - if (usage_entry_info_.size() < number_of_usage_entries_to_delete) { + if (entry_info_list_.size() < number_of_usage_entries_to_delete) { LOGW( "Cannot delete more entries than the table size, reducing to current " "table size: table_size = %zu, number_to_delete = %u", - usage_entry_info_.size(), number_of_usage_entries_to_delete); + entry_info_list_.size(), number_of_usage_entries_to_delete); number_of_usage_entries_to_delete = - static_cast(usage_entry_info_.size()); + static_cast(entry_info_list_.size()); } - if (number_of_usage_entries_to_delete == 0) return NO_ERROR; + if (number_of_usage_entries_to_delete == 0) return CdmResponseType(NO_ERROR); // crypto_session points to an object whose scope is this method or a test // object whose scope is the lifetime of this class @@ -899,21 +883,21 @@ CdmResponseType UsageTableHeader::Shrink( crypto_session = scoped_crypto_session.get(); } - const uint32_t new_size = static_cast(usage_entry_info_.size()) - + const uint32_t new_size = static_cast(entry_info_list_.size()) - number_of_usage_entries_to_delete; const CdmResponseType status = crypto_session->ShrinkUsageTableHeader( - requested_security_level_, new_size, &usage_table_header_); + requested_security_level_, new_size, &header_); if (status == NO_ERROR) { - usage_entry_info_.resize(new_size); + entry_info_list_.resize(new_size); StoreTable(); } return status; } -CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, - metrics::CryptoMetrics* metrics) { - LOGV("current_size = %zu", usage_entry_info_.size()); +CdmResponseType CdmUsageTable::DefragTable(DeviceFiles* device_files, + metrics::CryptoMetrics* metrics) { + LOGV("current_size = %zu", entry_info_list_.size()); // Defragging the usage table involves moving valid entries near the // end of the usage table to the position of invalid entries near the // front of the table. After the entries are moved, the CDM shrinks @@ -921,20 +905,20 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // the table. // Special case 0: Empty table, do nothing. - if (usage_entry_info_.empty()) { + if (entry_info_list_.empty()) { LOGD("Table empty, nothing to defrag"); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Step 1: Create a list of entries to be removed from the table. // Priority is given to the entries near the beginning of the table. // To avoid large delays from the swapping process, we limit the // quantity of entries to remove to |kMaxDefragEntryMoves| or fewer. - std::vector entries_to_remove; - for (uint32_t i = 0; i < usage_entry_info_.size() && - entries_to_remove.size() < kMaxDefragEntryMoves; + std::vector entries_to_remove; + for (UsageEntryIndex i = 0; i < entry_info_list_.size() && + entries_to_remove.size() < kMaxDefragEntryMoves; ++i) { - if (usage_entry_info_[i].storage_type == kStorageTypeUnknown) { + if (entry_info_list_[i].storage_type == kStorageTypeUnknown) { entries_to_remove.push_back(i); } } @@ -943,19 +927,19 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // needs to be done. if (entries_to_remove.empty()) { LOGD("No entries are invalid"); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Step 2: Create a list of entries to be moved from the end of the // table to the positions identified for removal. - std::vector entries_to_move; - for (uint32_t i = 0; i < usage_entry_info_.size() && + std::vector entries_to_move; + for (uint32_t i = 0; i < entry_info_list_.size() && entries_to_move.size() < entries_to_remove.size(); ++i) { // Search from the end of the table. - const uint32_t entry_index = - static_cast(usage_entry_info_.size()) - i - 1; - if (usage_entry_info_[entry_index].storage_type != kStorageTypeUnknown) { + const UsageEntryIndex entry_index = + static_cast(entry_info_list_.size()) - i - 1; + if (entry_info_list_[entry_index].storage_type != kStorageTypeUnknown) { entries_to_move.push_back(entry_index); } } @@ -964,8 +948,8 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // the whole table can be removed. if (entries_to_move.empty()) { LOGD("No valid entries found, shrinking entire table: size = %zu", - usage_entry_info_.size()); - return Shrink(metrics, static_cast(usage_entry_info_.size())); + entry_info_list_.size()); + return Shrink(metrics, static_cast(entry_info_list_.size())); } // Step 3: Ignore invalid entries that are after the last valid @@ -974,7 +958,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // the shrink operation is applied to the table. // Note: Special case 4 will handle any non-trivial cases related to // interweaving of valid and invalid entries. - const uint32_t last_valid_entry = entries_to_move.front(); + const UsageEntryIndex last_valid_entry = entries_to_move.front(); while (!entries_to_remove.empty() && entries_to_remove.back() > last_valid_entry) { entries_to_remove.pop_back(); @@ -984,50 +968,51 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // entry. In this case, no movement is required and the table can just // be shrunk to the last valid entry. if (entries_to_remove.empty()) { - const uint32_t to_remove = - static_cast(usage_entry_info_.size()) - last_valid_entry - 1; + const UsageEntryIndex to_remove = + static_cast(entry_info_list_.size()) - + last_valid_entry - 1; LOGD("Removing all entries after the last valid entry: count = %u", to_remove); return Shrink(metrics, to_remove); } // Step 4: Move the valid entries to overwrite the invalid entries. - // Moving the highest numbered valid entry to the lowest numbered + // Moving the highest indexed valid entry to the lowest indexed // invalid entry. // Reversing vectors to make accessing and popping easier. This - // will put the lowest number invalid entry and the highest number + // will put the lowest index invalid entry and the highest index // valid entry at the back of their respective vectors. std::reverse(entries_to_remove.begin(), entries_to_remove.end()); std::reverse(entries_to_move.begin(), entries_to_move.end()); while (!entries_to_remove.empty() && !entries_to_move.empty()) { // Entries are popped after use only. - const uint32_t to_entry_number = entries_to_remove.back(); - const uint32_t from_entry_number = entries_to_move.back(); + const UsageEntryIndex to_entry_index = entries_to_remove.back(); + const UsageEntryIndex from_entry_index = entries_to_move.back(); // Special case 4: We don't want to move any entries to a higher // index than their current. Once this occurs, we can stop the // loop. - if (to_entry_number > from_entry_number) { + if (to_entry_index > from_entry_index) { LOGD("Entries will not be moved further down the table"); break; } - CdmUsageEntry from_entry; + UsageEntry from_entry; CdmResponseType status = - GetEntry(from_entry_number, device_files, &from_entry); + GetEntry(from_entry_index, device_files, &from_entry); if (status != NO_ERROR) { - LOGW("Could not get entry: entry_number = %u", from_entry_number); + LOGW("Could not get entry: entry_index = %u", from_entry_index); // It is unlikely that an unretrievable entry will suddenly // become retrievable later on when it is needed. - usage_entry_info_[from_entry_number].Clear(); + entry_info_list_[from_entry_index].Clear(); entries_to_move.pop_back(); continue; } - status = MoveEntry(from_entry_number, from_entry, to_entry_number, + status = MoveEntry(from_entry_index, from_entry, to_entry_index, device_files, metrics); - switch (status) { + switch (status.code()) { case NO_ERROR: { entries_to_remove.pop_back(); entries_to_move.pop_back(); @@ -1038,8 +1023,8 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // This is a special error code when returned from LoadEntry() // indicating that the entry is already in use in a different // session. In this case, skip the entry and move on. - LOGD("From entry already in use: from_entry_number = %u", - from_entry_number); + LOGD("From entry already in use: from_entry_index = %u", + from_entry_index); entries_to_move.pop_back(); break; } @@ -1050,19 +1035,19 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // can no longer be used. Safe to continue loop. // TODO(b/152256186): Remove local files associated with this // entry. - usage_entry_info_[from_entry_number].Clear(); - LOGW("From entry was corrupted: from_entry_number = %u", - from_entry_number); + entry_info_list_[from_entry_index].Clear(); + LOGW("From entry was corrupted: from_entry_index = %u", + from_entry_index); entries_to_move.pop_back(); break; } // Handle errors associated with the invalid "to" entry. case MOVE_USAGE_ENTRY_DESTINATION_IN_USE: { - // The usage entry specified by |to_entry_number| is currently + // The usage entry specified by |to_entry_index| is currently // being used by another session. This is unlikely, but still // possible. Given that this entry is already marked as unknown // storage type, it will likely be removed at a later time. - LOGD("To entry already in use: to_entry_number = %u", to_entry_number); + LOGD("To entry already in use: to_entry_index = %u", to_entry_index); entries_to_remove.pop_back(); break; } @@ -1072,8 +1057,8 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // entry. Both should be skipped on the next iteration. LOGW( "Move failed, skipping both to entry and from entry: " - "to_entry_number = %u, from_entry_number = %u", - to_entry_number, from_entry_number); + "to_entry_index = %u, from_entry_index = %u", + to_entry_index, from_entry_index); entries_to_remove.pop_back(); entries_to_move.pop_back(); break; @@ -1091,19 +1076,19 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // For all other cases, it may not be safe to proceed, even to // shrink the table. LOGE("Unrecoverable error occurred while defragging table: status = %d", - static_cast(status)); + status.ToInt()); return status; } } // End switch case. } // End while loop. // Step 5: Find the new last valid entry. - uint32_t new_last_valid_entry = - static_cast(usage_entry_info_.size()); - for (uint32_t i = 0; i < usage_entry_info_.size(); ++i) { - const uint32_t entry_index = - static_cast(usage_entry_info_.size()) - i - 1; - if (usage_entry_info_[entry_index].storage_type != kStorageTypeUnknown) { + UsageEntryIndex new_last_valid_entry = + static_cast(entry_info_list_.size()); + for (size_t i = 0; i < entry_info_list_.size(); ++i) { + const UsageEntryIndex entry_index = + static_cast(entry_info_list_.size() - i) - 1; + if (entry_info_list_[entry_index].storage_type != kStorageTypeUnknown) { new_last_valid_entry = entry_index; break; } @@ -1112,15 +1097,16 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, // Special case 5: No entries in the table are valid. This could // have occurred if entries during the move process were found to be // invalid. In this case, remove the whole table. - if (new_last_valid_entry == usage_entry_info_.size()) { + if (new_last_valid_entry == entry_info_list_.size()) { LOGD( "All entries have been invalidated, shrinking entire table: size = %zu", - usage_entry_info_.size()); - return Shrink(metrics, static_cast(usage_entry_info_.size())); + entry_info_list_.size()); + return Shrink(metrics, static_cast(entry_info_list_.size())); } - const uint32_t to_remove = static_cast(usage_entry_info_.size()) - - new_last_valid_entry - 1; + const UsageEntryIndex to_remove = + static_cast(entry_info_list_.size()) - + new_last_valid_entry - 1; // Special case 6: It is possible that the last entry in the table // is valid and currently loaded in the table by another session. @@ -1129,7 +1115,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, if (to_remove == 0) { LOGD("Defrag completed without shrinking table"); StoreTable(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Step 6: Shrink table to the new size. @@ -1137,167 +1123,160 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files, return Shrink(metrics, to_remove); } // End Defrag(). -CdmResponseType UsageTableHeader::ReleaseOldestEntry( +CdmResponseType CdmUsageTable::ReleaseOldestEntry( metrics::CryptoMetrics* metrics) { LOGV("Releasing oldest entry"); - uint32_t entry_number_to_delete; - if (!GetRemovalCandidate(&entry_number_to_delete)) { + UsageEntryIndex entry_index_to_delete; + if (!GetRemovalCandidate(&entry_index_to_delete)) { LOGE("Could not determine which license to remove"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } - const CdmUsageEntryInfo& usage_entry_info = - usage_entry_info_[entry_number_to_delete]; + const CdmUsageEntryInfo& entry_info = entry_info_list_[entry_index_to_delete]; const int64_t current_time = GetCurrentTime(); - // Capture metric values now, as the |usage_entry_info| reference will + // Capture metric values now, as the |entry_info| reference will // change after the call to invalidate. - const int64_t staleness = current_time - usage_entry_info.last_use_time; - const CdmUsageEntryStorageType storage_type = usage_entry_info.storage_type; + const int64_t staleness = current_time - entry_info.last_use_time; + const CdmUsageEntryStorageType storage_type = entry_info.storage_type; const CdmResponseType status = - InvalidateEntryInternal(entry_number_to_delete, /* defrag_table = */ true, + InvalidateEntryInternal(entry_index_to_delete, /* defrag_table = */ true, device_files_.get(), metrics); if (status != NO_ERROR) { - LOGE("Failed to invalidate oldest entry: status = %d", - static_cast(status)); + LOGE("Failed to invalidate oldest entry: status = %d", status.ToInt()); return status; } // Record metrics on success. RecordLruEventMetrics(metrics, staleness, storage_type); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Test only method. -void UsageTableHeader::InvalidateEntryForTest(uint32_t usage_entry_number) { - LOGD("usage_entry_number = %u", usage_entry_number); - if (usage_entry_number >= usage_entry_info_.size()) { +void CdmUsageTable::InvalidateEntryForTest(UsageEntryIndex entry_index) { + LOGD("entry_index = %u", entry_index); + if (entry_index >= entry_info_list_.size()) { LOGE( - "Requested usage entry number is larger than table size: " - "usage_entry_number = %u, table_size = %zu", - usage_entry_number, usage_entry_info_.size()); + "Requested usage entry index is larger than table size: " + "entry_index = %u, table_size = %zu", + entry_index, entry_info_list_.size()); return; } // Move last entry into invalidated entry location and shrink usage // entries. - usage_entry_info_[usage_entry_number] = - usage_entry_info_[usage_entry_info_.size() - 1]; - usage_entry_info_.resize(usage_entry_info_.size() - 1); + entry_info_list_[entry_index] = entry_info_list_[entry_info_list_.size() - 1]; + entry_info_list_.resize(entry_info_list_.size() - 1); } -bool UsageTableHeader::LruUpgradeAllUsageEntries() { +bool CdmUsageTable::LruUpgradeAllUsageEntries() { LOGV("Upgrading all usage entries with LRU information"); - if (usage_entry_info_.size() == 0) return true; // Nothing to upgrade. + if (entry_info_list_.size() == 0) return true; // Nothing to upgrade. // For each entry, the status upgrading that entry is stored. At the // end, all problematic licenses will be marked as invalid. - std::vector bad_license_file_entries; + std::vector bad_license_file_entries; - for (uint32_t usage_entry_number = 0; - usage_entry_number < usage_entry_info_.size(); ++usage_entry_number) { - CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number]; + for (UsageEntryIndex entry_index = 0; entry_index < entry_info_list_.size(); + ++entry_index) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_index]; - uint32_t retrieved_entry_number; + UsageEntryIndex retrieved_entry_index; CdmKeyResponse license_message; bool retrieve_response = false; - switch (usage_entry_info.storage_type) { + switch (entry_info.storage_type) { case kStorageLicense: { - retrieve_response = RetrieveOfflineLicense( - device_files_.get(), usage_entry_info.key_set_id, &license_message, - &retrieved_entry_number); + retrieve_response = + RetrieveOfflineLicense(device_files_.get(), entry_info.key_set_id, + &license_message, &retrieved_entry_index); break; } case kStorageUsageInfo: { retrieve_response = RetrieveUsageInfoLicense( - device_files_.get(), usage_entry_info.usage_info_file_name, - usage_entry_info.key_set_id, &license_message, - &retrieved_entry_number); + device_files_.get(), entry_info.usage_info_file_name, + entry_info.key_set_id, &license_message, &retrieved_entry_index); break; } case kStorageTypeUnknown: - bad_license_file_entries.push_back(usage_entry_number); + bad_license_file_entries.push_back(entry_index); continue; default: { - LOGW("Unknown usage entry storage type: %d, usage_entry_number = %u", - static_cast(usage_entry_info.storage_type), - usage_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + LOGW("Unknown usage entry storage type: %d, entry_index = %u", + static_cast(entry_info.storage_type), entry_index); + bad_license_file_entries.push_back(entry_index); continue; } } if (!retrieve_response) { - LOGW("Could not retrieve license message: usage_entry_number = %u", - usage_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + LOGW("Could not retrieve license message: entry_index = %u", entry_index); + bad_license_file_entries.push_back(entry_index); continue; } - if (retrieved_entry_number != usage_entry_number) { + if (retrieved_entry_index != entry_index) { LOGW( - "Usage entry number mismatched: usage_entry_number = %u, " - "retrieved_entry_number = %u", - usage_entry_number, retrieved_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + "Usage entry index mismatched: entry_index = %u, " + "retrieved_entry_index = %u", + entry_index, retrieved_entry_index); + bad_license_file_entries.push_back(entry_index); continue; } video_widevine::License license; if (!ParseLicenseFromLicenseMessage(license_message, &license)) { - LOGW("Could not parse license: usage_entry_number = %u", - usage_entry_number); - bad_license_file_entries.push_back(usage_entry_number); + LOGW("Could not parse license: entry_index = %u", entry_index); + bad_license_file_entries.push_back(entry_index); continue; } // If |license_start_time| is 0, then this entry will be considered // for replacement above all others. - usage_entry_info.last_use_time = license.license_start_time(); + entry_info.last_use_time = license.license_start_time(); - if (usage_entry_info.storage_type == kStorageLicense) { + if (entry_info.storage_type == kStorageLicense) { // Only offline licenses need |offline_license_expiry_time| set. const video_widevine::License::Policy& policy = license.policy(); // TODO(b/139372190): Change how these fields are set once feature is // implemented. if (policy.license_duration_seconds() == 0) { // Zero implies unlimited license duration. - usage_entry_info.offline_license_expiry_time = + entry_info.offline_license_expiry_time = license.license_start_time() + policy.rental_duration_seconds() + policy.playback_duration_seconds(); } else { - usage_entry_info.offline_license_expiry_time = + entry_info.offline_license_expiry_time = license.license_start_time() + policy.license_duration_seconds(); } } else { - usage_entry_info.offline_license_expiry_time = 0; + entry_info.offline_license_expiry_time = 0; } } // End for loop. - if (bad_license_file_entries.size() == usage_entry_info_.size()) { + if (bad_license_file_entries.size() == entry_info_list_.size()) { LOGE("Failed to perform LRU upgrade for every entry: count = %zu", - usage_entry_info_.size()); + entry_info_list_.size()); return false; } // Maps -> []. std::map> usage_info_clean_up; - for (size_t usage_entry_number : bad_license_file_entries) { - CdmUsageEntryInfo& usage_entry_info = usage_entry_info_[usage_entry_number]; - if (usage_entry_info.storage_type == kStorageLicense) { - device_files_->DeleteLicense(usage_entry_info.key_set_id); - } else if (usage_entry_info.storage_type == kStorageUsageInfo) { + for (UsageEntryIndex entry_index : bad_license_file_entries) { + CdmUsageEntryInfo& entry_info = entry_info_list_[entry_index]; + if (entry_info.storage_type == kStorageLicense) { + device_files_->DeleteLicense(entry_info.key_set_id); + } else if (entry_info.storage_type == kStorageUsageInfo) { // To reduce write cycles, the deletion of usage info will be done // in bulk. - auto it = usage_info_clean_up.find(usage_entry_info.usage_info_file_name); + auto it = usage_info_clean_up.find(entry_info.usage_info_file_name); if (it == usage_info_clean_up.end()) { it = usage_info_clean_up - .emplace(usage_entry_info.usage_info_file_name, + .emplace(entry_info.usage_info_file_name, std::vector()) .first; } - it->second.push_back(usage_entry_info.key_set_id); + it->second.push_back(entry_info.key_set_id); } // else kStorageUnknown { Nothing special }. - usage_entry_info.Clear(); + entry_info.Clear(); } for (const auto& p : usage_info_clean_up) { @@ -1307,16 +1286,16 @@ bool UsageTableHeader::LruUpgradeAllUsageEntries() { return true; } -bool UsageTableHeader::GetRemovalCandidate(uint32_t* entry_to_remove) { +bool CdmUsageTable::GetRemovalCandidate(UsageEntryIndex* entry_to_remove) { const size_t lru_unexpired_threshold = HasUnlimitedTableCapacity() ? kLruUnexpiredThresholdFraction * size() : kLruUnexpiredThresholdFraction * potential_table_capacity(); - return DetermineLicenseToRemove(usage_entry_info_, GetCurrentTime(), + return DetermineLicenseToRemove(entry_info_list_, GetCurrentTime(), lru_unexpired_threshold, entry_to_remove); } -void UsageTableHeader::RecordLruEventMetrics( +void CdmUsageTable::RecordLruEventMetrics( metrics::CryptoMetrics* metrics, uint64_t staleness, CdmUsageEntryStorageType storage_type) { if (metrics == nullptr) return; @@ -1329,65 +1308,63 @@ void UsageTableHeader::RecordLruEventMetrics( } // Static. -bool UsageTableHeader::DetermineLicenseToRemove( - const std::vector& usage_entry_info_list, - int64_t current_time, size_t unexpired_threshold, - uint32_t* entry_to_remove) { +bool CdmUsageTable::DetermineLicenseToRemove( + const std::vector& entry_info_list, int64_t current_time, + size_t unexpired_threshold, UsageEntryIndex* entry_to_remove) { if (entry_to_remove == nullptr) { LOGE("Output parameter |entry_to_remove| is null"); return false; } - if (usage_entry_info_list.empty()) { + if (entry_info_list.empty()) { return false; } // Returns true if entry of first index is more stale than the // entry of the second index. - const auto is_more_stale = [&](uint32_t i, uint32_t j) -> bool { - return usage_entry_info_list[i].last_use_time < - usage_entry_info_list[j].last_use_time; + const auto is_more_stale = [&](UsageEntryIndex i, UsageEntryIndex j) -> bool { + return entry_info_list[i].last_use_time < entry_info_list[j].last_use_time; }; // Find the most stale expired offline / streaming license and the // most stale unexpired offline entry. Count the number of unexpired // entries. If any entry is of storage type unknown, then it should // be removed. - constexpr uint32_t kNoEntry = std::numeric_limits::max(); - uint32_t stalest_expired_offline_license = kNoEntry; - uint32_t stalest_unexpired_offline_license = kNoEntry; - uint32_t stalest_streaming_license = kNoEntry; + constexpr UsageEntryIndex kNoEntry = + std::numeric_limits::max(); + UsageEntryIndex stalest_expired_offline_license = kNoEntry; + UsageEntryIndex stalest_unexpired_offline_license = kNoEntry; + UsageEntryIndex stalest_streaming_license = kNoEntry; size_t unexpired_license_count = 0; - for (uint32_t entry_number = 0; entry_number < usage_entry_info_list.size(); - ++entry_number) { - const CdmUsageEntryInfo& usage_entry_info = - usage_entry_info_list[entry_number]; + for (UsageEntryIndex entry_index = 0; entry_index < entry_info_list.size(); + ++entry_index) { + const CdmUsageEntryInfo& entry_info = entry_info_list[entry_index]; - if (usage_entry_info.storage_type != kStorageLicense && - usage_entry_info.storage_type != kStorageUsageInfo) { + if (entry_info.storage_type != kStorageLicense && + entry_info.storage_type != kStorageUsageInfo) { // Unknown storage type entries. Remove this entry. - *entry_to_remove = entry_number; + *entry_to_remove = entry_index; return true; } - if (usage_entry_info.storage_type == kStorageLicense && - usage_entry_info.offline_license_expiry_time > current_time) { + if (entry_info.storage_type == kStorageLicense && + entry_info.offline_license_expiry_time > current_time) { // Unexpired offline. ++unexpired_license_count; if (stalest_unexpired_offline_license == kNoEntry || - is_more_stale(entry_number, stalest_unexpired_offline_license)) { - stalest_unexpired_offline_license = entry_number; + is_more_stale(entry_index, stalest_unexpired_offline_license)) { + stalest_unexpired_offline_license = entry_index; } - } else if (usage_entry_info.storage_type == kStorageLicense) { + } else if (entry_info.storage_type == kStorageLicense) { // Expired offline. if (stalest_expired_offline_license == kNoEntry || - is_more_stale(entry_number, stalest_expired_offline_license)) { - stalest_expired_offline_license = entry_number; + is_more_stale(entry_index, stalest_expired_offline_license)) { + stalest_expired_offline_license = entry_index; } } else { // Streaming. if (stalest_streaming_license == kNoEntry || - is_more_stale(entry_number, stalest_streaming_license)) { - stalest_streaming_license = entry_number; + is_more_stale(entry_index, stalest_streaming_license)) { + stalest_streaming_license = entry_index; } } } @@ -1399,13 +1376,13 @@ bool UsageTableHeader::DetermineLicenseToRemove( LOGW( "Table only contains unexpired offline licenses, " "but threshold not met: size = %zu, count = %zu, threshold = %zu", - usage_entry_info_list.size(), unexpired_license_count, - unexpired_threshold); + entry_info_list.size(), unexpired_license_count, unexpired_threshold); *entry_to_remove = stalest_unexpired_offline_license; return true; } - const auto select_most_stale = [&](uint32_t a, uint32_t b) -> uint32_t { + const auto select_most_stale = [&](UsageEntryIndex a, + UsageEntryIndex b) -> UsageEntryIndex { if (a == kNoEntry) return b; if (b == kNoEntry) return a; return is_more_stale(a, b) ? a : b; @@ -1413,8 +1390,8 @@ bool UsageTableHeader::DetermineLicenseToRemove( // Only consider an unexpired entry if the threshold is reached. if (unexpired_license_count > unexpired_threshold) { - const uint32_t temp = select_most_stale(stalest_unexpired_offline_license, - stalest_streaming_license); + const UsageEntryIndex temp = select_most_stale( + stalest_unexpired_offline_license, stalest_streaming_license); *entry_to_remove = select_most_stale(temp, stalest_expired_offline_license); } else { *entry_to_remove = select_most_stale(stalest_streaming_license, @@ -1423,9 +1400,9 @@ bool UsageTableHeader::DetermineLicenseToRemove( if (*entry_to_remove == kNoEntry) { // Illegal state check. The loop above should have found at least - // one entry given that |usage_entry_info_list| is not empty. + // one entry given that |entry_info_list| is not empty. LOGE("No entry could be used for removal: size = %zu", - usage_entry_info_list.size()); + entry_info_list.size()); return false; } return true; diff --git a/core/src/certificate_provisioning.cpp b/core/src/certificate_provisioning.cpp index 0ed12abe..c8158b1f 100644 --- a/core/src/certificate_provisioning.cpp +++ b/core/src/certificate_provisioning.cpp @@ -9,6 +9,7 @@ #include "device_files.h" #include "file_store.h" #include "license_protocol.pb.h" +#include "license_protocol_conversions.h" #include "log.h" #include "properties.h" #include "service_certificate.h" @@ -88,18 +89,14 @@ bool RetrieveOemCertificateAndLoadPrivateKey(CryptoSession& crypto_session, } // namespace // Protobuf generated classes. -using video_widevine::ClientIdentification_ClientCapabilities; -using video_widevine::ClientIdentification_NameValue; using video_widevine::DrmCertificate; -using video_widevine::EncryptedClientIdentification; +using video_widevine::HashAlgorithmProto; using video_widevine::ProvisioningOptions; using video_widevine::ProvisioningRequest; using video_widevine::ProvisioningResponse; using video_widevine::PublicKeyToCertify; using video_widevine::SignedDrmCertificate; using video_widevine::SignedProvisioningMessage; -using video_widevine:: - SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1; // static void CertificateProvisioning::GetProvisioningServerUrl( @@ -113,38 +110,35 @@ void CertificateProvisioning::GetProvisioningServerUrl( CdmResponseType CertificateProvisioning::Init( const std::string& service_certificate) { - std::string certificate = + const std::string certificate = service_certificate.empty() ? wvutil::a2bs_hex(kCpProductionServiceCertificate) : service_certificate; return service_certificate_->Init(certificate); } -/* - * Fill in the appropriate SPOID (Stable Per-Origin IDentifier) option. - * One of spoid, provider_id or stable_id will be passed to the provisioning - * server for determining a unique per origin ID for the device. - * It is also valid (though deprecated) to leave the settings unset. - */ +// Fill in the appropriate SPOID (Stable Per-Origin IDentifier) option. +// One of spoid, provider_id or stable_id will be passed to the provisioning +// server for determining a unique per origin ID for the device. +// It is also valid (though deprecated) to leave the settings unset. CdmResponseType CertificateProvisioning::SetSpoidParameter( const std::string& origin, const std::string& spoid, ProvisioningRequest* request) { if (!request) { LOGE("Output parameter |request| is not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (!spoid.empty()) { // Use the SPOID that has been pre-provided request->set_spoid(spoid); } else if (Properties::UseProviderIdInProvisioningRequest()) { - if (!service_certificate_->provider_id().empty()) { - request->set_provider_id(service_certificate_->provider_id()); - } else { + if (service_certificate_->provider_id().empty()) { LOGE( "Failed to set provider ID: " "Service certificate provider ID is empty"); - return SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY; + return CdmResponseType(SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY); } + request->set_provider_id(service_certificate_->provider_id()); } else if (origin != EMPTY_ORIGIN) { // Legacy behavior - Concatenate Unique ID with Origin std::string device_unique_id; @@ -158,13 +152,11 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter( } request->set_stable_id(device_unique_id + origin); } // No else clause, by design. It is valid to do nothing. - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -/* - * Return the provisioning protocol version - dictated by OEMCrypto - * support for OEM certificates. - */ +// Return the provisioning protocol version - dictated by OEMCrypto +// support for OEM certificates. SignedProvisioningMessage::ProvisioningType CertificateProvisioning::GetProvisioningType() { switch (crypto_session_->GetPreProvisionTokenType()) { @@ -177,13 +169,11 @@ CertificateProvisioning::GetProvisioningType() { } } -/* - * Compose a device provisioning request and output *request in a - * JSON-compatible format (web-safe base64). - * Also return *default_url of the provisioning server. - * - * Returns NO_ERROR for success and CERT_PROVISIONING_REQUEST_ERROR_? if fails. - */ +// Compose a device provisioning request and output *request in a +// JSON-compatible format (web-safe base64). +// Also return *default_url of the provisioning server. +// +// Returns NO_ERROR for success and CERT_PROVISIONING_REQUEST_ERROR_? if fails. CdmResponseType CertificateProvisioning::GetProvisioningRequest( wvutil::FileSystem* file_system, RequestedSecurityLevel requested_security_level, @@ -204,7 +194,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( if (!request || !default_url) { LOGE("Output parameter |%s| is not provided", request ? "default_url" : "request"); - return CERT_PROVISIONING_REQUEST_ERROR_1; + return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_1); } default_url->assign(kProvisioningServerUrl); @@ -236,28 +226,27 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( if (status != NO_ERROR) { LOGE("Failed to generate a nonce: status = %d", static_cast(status)); return status == NONCE_GENERATION_ERROR - ? CERT_PROVISIONING_NONCE_GENERATION_ERROR + ? CdmResponseType(CERT_PROVISIONING_NONCE_GENERATION_ERROR) : status; } // The provisioning server does not convert the nonce to uint32_t, it just // passes the binary data to the response message. - std::string the_nonce(reinterpret_cast(&nonce), sizeof(nonce)); - provisioning_request.set_nonce(the_nonce); + const std::string encoded_nonce(reinterpret_cast(&nonce), + sizeof(nonce)); + provisioning_request.set_nonce(encoded_nonce); ProvisioningOptions* options = provisioning_request.mutable_options(); switch (cert_type) { case kCertificateWidevine: - options->set_certificate_type( - video_widevine::ProvisioningOptions_CertificateType_WIDEVINE_DRM); + options->set_certificate_type(ProvisioningOptions::WIDEVINE_DRM); break; case kCertificateX509: - options->set_certificate_type( - video_widevine::ProvisioningOptions_CertificateType_X509); + options->set_certificate_type(ProvisioningOptions::X509); break; default: LOGE("Unknown certificate type: %d", static_cast(cert_type)); - return CERT_PROVISIONING_INVALID_CERT_TYPE; + return CdmResponseType(CERT_PROVISIONING_INVALID_CERT_TYPE); } cert_type_ = cert_type; @@ -272,8 +261,11 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( // Derives signing and encryption keys and constructs signature. std::string core_message; std::string request_signature; + bool should_specify_algorithm; + OEMCrypto_SignatureHashAlgorithm oec_algorithm = OEMCrypto_SHA1; status = crypto_session_->PrepareAndSignProvisioningRequest( - serialized_message, &core_message, &request_signature); + serialized_message, &core_message, &request_signature, + should_specify_algorithm, oec_algorithm); if (status != NO_ERROR) { LOGE("Failed to prepare provisioning request: status = %d", @@ -283,21 +275,24 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( if (request_signature.empty()) { LOGE("Request signature is empty"); - return CERT_PROVISIONING_REQUEST_ERROR_4; + return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_4); } SignedProvisioningMessage signed_provisioning_msg; signed_provisioning_msg.set_message(serialized_message); signed_provisioning_msg.set_signature(request_signature); signed_provisioning_msg.set_provisioning_type(GetProvisioningType()); - if (core_message.empty()) { - // OEMCrypto does not support core messages. - supports_core_messages_ = false; - } else { - signed_provisioning_msg.set_oemcrypto_core_message(core_message); - } + signed_provisioning_msg.set_oemcrypto_core_message(core_message); signed_provisioning_msg.set_protocol_version( - SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1); + SignedProvisioningMessage::VERSION_1_1); + if (should_specify_algorithm) { + HashAlgorithmProto proto_algorithm = + HashAlgorithmProto::HASH_ALGORITHM_UNSPECIFIED; + if (!OecAlgorithmToProtoAlgorithm(oec_algorithm, proto_algorithm)) { + return CdmResponseType(UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3); + } + signed_provisioning_msg.set_hash_algorithm(proto_algorithm); + } std::string serialized_request; signed_provisioning_msg.SerializeToString(&serialized_request); @@ -308,7 +303,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( } else { *request = std::move(serialized_request); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal( @@ -317,19 +312,19 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal( std::string* default_url) { if (!crypto_session_->IsOpen()) { LOGE("Crypto session is not open"); - return PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN; + return CdmResponseType(PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN); } if (file_system == nullptr) { LOGE("file_system is nullptr but is required in provisioning 4"); - return PROVISIONING_4_FILE_SYSTEM_IS_NULL; + return CdmResponseType(PROVISIONING_4_FILE_SYSTEM_IS_NULL); } const CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel(); wvutil::FileSystem global_file_system; DeviceFiles global_file_handle(&global_file_system); if (!global_file_handle.Init(security_level)) { LOGE("Failed to initialize global DeviceFiles"); - return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES; + return CdmResponseType(PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES); } ProvisioningRequest provisioning_request; @@ -418,24 +413,63 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal( ? PublicKeyToCertify::RSA : PublicKeyToCertify::ECC); - // In provisioning 4, the message is not signed. + std::string serialized_message; + provisioning_request.SerializeToString(&serialized_message); + SignedProvisioningMessage signed_provisioning_msg; - provisioning_request.SerializeToString( - signed_provisioning_msg.mutable_message()); + signed_provisioning_msg.set_message(serialized_message); signed_provisioning_msg.set_provisioning_type(GetProvisioningType()); signed_provisioning_msg.set_protocol_version( - SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1); + SignedProvisioningMessage::VERSION_1_1); + + // Core message and request signature are added to the provisioning request + // starting OEMCrypto v18 + uint32_t api_version = 0; + const bool core_message_signature_required = + crypto_session_->GetApiVersion(&api_version) && + (api_version >= OEM_CRYPTO_API_VERSION_SUPPORTS_PROV40_CORE_MESSAGE); + if (core_message_signature_required) { + std::string core_message; + std::string request_signature; + bool should_specify_algorithm; + OEMCrypto_SignatureHashAlgorithm oec_algorithm = OEMCrypto_SHA1; + status = crypto_session_->PrepareAndSignProvisioningRequest( + serialized_message, &core_message, &request_signature, + should_specify_algorithm, oec_algorithm); + if (status != NO_ERROR) { + LOGE("Failed to prepare provisioning 4.0 request: status = %d", + static_cast(status)); + return status; + } + if (core_message.empty()) { + LOGE("Core message is empty"); + return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_4); + } + if (request_signature.empty()) { + LOGE("Request signature is empty"); + return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_4); + } + signed_provisioning_msg.set_oemcrypto_core_message(core_message); + signed_provisioning_msg.set_signature(request_signature); + if (should_specify_algorithm) { + HashAlgorithmProto proto_algorithm = + HashAlgorithmProto::HASH_ALGORITHM_UNSPECIFIED; + if (!OecAlgorithmToProtoAlgorithm(oec_algorithm, proto_algorithm)) { + return CdmResponseType(UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4); + } + signed_provisioning_msg.set_hash_algorithm(proto_algorithm); + } + } std::string serialized_request; signed_provisioning_msg.SerializeToString(&serialized_request); - if (!wvcdm::Properties::provisioning_messages_are_binary()) { // Return request as web-safe base64 string *request = wvutil::Base64SafeEncodeNoPad(serialized_request); } else { *request = std::move(serialized_request); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CertificateProvisioning::FillEncryptedClientId( @@ -453,7 +487,7 @@ CertificateProvisioning::FillEncryptedClientIdWithAdditionalParameter( ProvisioningRequest& provisioning_request, const ServiceCertificate& service_certificate) { if (!crypto_session_->IsOpen()) { - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } wvcdm::ClientIdentification id; @@ -467,7 +501,7 @@ CertificateProvisioning::FillEncryptedClientIdWithAdditionalParameter( if (!service_certificate.has_certificate()) { LOGE("Service certificate not staged"); - return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE; + return CdmResponseType(CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE); } // Encrypt client identification @@ -481,7 +515,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response( ProvisioningResponse provisioning_response; if (response_message.empty() || !provisioning_response.ParseFromString(response_message)) { - return PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE; + return CdmResponseType(PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE); } if (provisioning_response.has_status() && provisioning_response.status() != ProvisioningResponse::NO_ERROR) { @@ -489,9 +523,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response( switch (provisioning_response.status()) { case ProvisioningResponse::REVOKED_DEVICE_CREDENTIALS: case ProvisioningResponse::REVOKED_DEVICE_SERIES: - return DEVICE_REVOKED; + return CdmResponseType(DEVICE_REVOKED); default: - return PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS; + return CdmResponseType(PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS); } } @@ -499,12 +533,12 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response( provisioning_response.device_certificate(); if (device_certificate.empty()) { LOGE("Provisioning response has no certificate"); - return PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE; + return CdmResponseType(PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE); } if (provisioning_40_wrapped_private_key_.empty()) { LOGE("No private key was generated"); - return PROVISIONING_4_NO_PRIVATE_KEY; + return CdmResponseType(PROVISIONING_4_NO_PRIVATE_KEY); } const CryptoWrappedKey private_key(provisioning_40_key_type_, provisioning_40_wrapped_private_key_); @@ -515,7 +549,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response( DeviceFiles global_file_handle(&global_file_system); if (!global_file_handle.Init(security_level)) { LOGE("Failed to initialize global DeviceFiles"); - return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2; + return CdmResponseType(PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2); } // Check the stage of the provisioning by checking if an OEM cert is already @@ -525,39 +559,40 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response( if (!global_file_handle.StoreOemCertificate(device_certificate, private_key)) { LOGE("Failed to store provisioning 4 OEM certificate"); - return PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE; + return CdmResponseType(PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE); } } else { // The response is assumed to be an DRM cert. DeviceFiles per_origin_file_handle(file_system); if (!per_origin_file_handle.Init(security_level)) { LOGE("Failed to initialize per-origin DeviceFiles"); - return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3; + return CdmResponseType( + PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3); } if (!per_origin_file_handle.StoreCertificate(device_certificate, private_key)) { LOGE("Failed to store provisioning 4 DRM certificate"); - return PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE; + return CdmResponseType(PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE); } } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } -/* - * The response message consists of a device certificate and the device RSA key. - * The device RSA key is stored in the T.E.E. The device certificate is stored - * in the device. - * - * Returns NO_ERROR for success and CERT_PROVISIONING_RESPONSE_ERROR_? if fails. - */ +// The response message consists of a device certificate and the +// wrapped device private key (either RSA or ECC). The wrapped device +// private key is loaded into the TEE, unwrapped, verified and +// re-wrapped. The device certificate and re-wrapped device private +// key are stored on the device. +// +// Returns NO_ERROR for success and CERT_PROVISIONING_RESPONSE_ERROR_? if fails. CdmResponseType CertificateProvisioning::HandleProvisioningResponse( wvutil::FileSystem* file_system, const CdmProvisioningResponse& response_message, std::string* cert, std::string* wrapped_key) { if (response_message.empty()) { LOGE("Provisioning response message is empty"); - return CERT_PROVISIONING_RESPONSE_ERROR_1; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_1); } std::string response; @@ -569,8 +604,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( const bool result = ExtractAndDecodeSignedMessage(response_message, &response); if (!result || response.empty()) { - LOGE("Provisioning response message is an invalid JSON/base64 string"); - return CERT_PROVISIONING_RESPONSE_ERROR_1; + LOGE("Provisioning response message is an invalid JSON/base64 string: %s", + response.c_str()); + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_1); } } @@ -580,7 +616,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( SignedProvisioningMessage signed_response; if (!signed_response.ParseFromString(response)) { LOGE("Failed to parse signed provisioining response"); - return CERT_PROVISIONING_RESPONSE_ERROR_2; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_2); } if (signed_response.provisioning_type() == @@ -599,40 +635,26 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( error = true; } - if (supports_core_messages() && - (!signed_response.has_oemcrypto_core_message() || - signed_response.oemcrypto_core_message().empty())) { + if (!signed_response.has_oemcrypto_core_message()) { LOGE("Signed response does not have core message"); error = true; - } else if (!supports_core_messages() && - (signed_response.has_oemcrypto_core_message() && - !signed_response.oemcrypto_core_message().empty())) { - const std::string& core_message = signed_response.oemcrypto_core_message(); - // This case should not occur. However, the CDM will let OEMCrypto - // fail. - LOGW( - "Received unexpected core message in provisioning request: " - "core_message_size = %zu", - core_message.size()); } - if (error) return CERT_PROVISIONING_RESPONSE_ERROR_3; + if (error) return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_3); const std::string& signed_message = signed_response.message(); const std::string& signature = signed_response.signature(); - const std::string core_message = - supports_core_messages() ? signed_response.oemcrypto_core_message() - : std::string(); + const std::string& core_message = signed_response.oemcrypto_core_message(); ProvisioningResponse provisioning_response; if (!provisioning_response.ParseFromString(signed_message)) { LOGE("Failed to parse provisioning response"); - return CERT_PROVISIONING_RESPONSE_ERROR_4; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_4); } if (provisioning_response.has_status()) { if (provisioning_response.status() != ProvisioningResponse::NO_ERROR) { - LOGE("Provisioning Response status: %d", provisioning_response.status()); + LOGE("Provisioning response status: %d", provisioning_response.status()); } switch (provisioning_response.status()) { @@ -640,9 +662,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( break; case ProvisioningResponse::REVOKED_DEVICE_CREDENTIALS: case ProvisioningResponse::REVOKED_DEVICE_SERIES: - return DEVICE_REVOKED; + return CdmResponseType(DEVICE_REVOKED); default: - return CERT_PROVISIONING_RESPONSE_ERROR_10; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_10); } } @@ -665,19 +687,19 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( if (cert_type_ == kCertificateX509) { *cert = device_cert_data; *wrapped_key = private_key.key(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Need to parse cert for key type. SignedDrmCertificate signed_device_cert; if (!signed_device_cert.ParseFromString(device_cert_data)) { LOGE("Failed to parse signed DRM certificate"); - return CERT_PROVISIONING_RESPONSE_ERROR_9; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9); } DrmCertificate device_cert; if (!device_cert.ParseFromString(signed_device_cert.drm_certificate())) { LOGE("Failed to parse DRM certificate"); - return CERT_PROVISIONING_RESPONSE_ERROR_9; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9); } if (!device_cert.has_algorithm()) { LOGW("DRM certificate does not specify algorithm type, assuming RSA"); @@ -695,24 +717,23 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( default: LOGE("Unknown DRM key type: algorithm = %d", static_cast(device_cert.algorithm())); - return CERT_PROVISIONING_RESPONSE_ERROR_9; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9); } } // The certificate will be stored to the device as the final step in // the device provisioning process. - DeviceFiles handle(file_system); if (!handle.Init(security_level)) { LOGE("Failed to initialize DeviceFiles"); - return CERT_PROVISIONING_RESPONSE_ERROR_7; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_7); } if (!handle.StoreCertificate(device_cert_data, private_key)) { LOGE("Failed to store provisioning certificate"); - return CERT_PROVISIONING_RESPONSE_ERROR_8; + return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_8); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Provisioning response is a base64-encoded protobuf, optionally within a @@ -736,7 +757,7 @@ bool CertificateProvisioning::ExtractAndDecodeSignedMessage( if (start == provisioning_response.npos) { // Message is not properly wrapped - reject it. - LOGE("Cannot locate start substring"); + LOGE("Cannot locate start substring '%s'", json_start_substr.c_str()); result->clear(); return false; } @@ -745,7 +766,7 @@ bool CertificateProvisioning::ExtractAndDecodeSignedMessage( const size_t end = provisioning_response.find( json_end_substr, start + json_start_substr.length()); if (end == provisioning_response.npos) { - LOGE("Cannot locate end substring"); + LOGE("Cannot locate end substring '%s'", json_end_substr.c_str()); result->clear(); return false; } @@ -787,7 +808,7 @@ bool CertificateProvisioning::ExtractDeviceInfo( DrmCertificate drm_certificate; if (!drm_certificate.ParseFromString( signed_drm_certificate.drm_certificate()) || - (drm_certificate.type() != video_widevine::DrmCertificate::DEVICE)) { + (drm_certificate.type() != DrmCertificate::DEVICE)) { LOGE("Failed to parse DRM device certificate message"); return false; } diff --git a/core/src/client_identification.cpp b/core/src/client_identification.cpp index f3ae6ddc..d65072e1 100644 --- a/core/src/client_identification.cpp +++ b/core/src/client_identification.cpp @@ -62,49 +62,44 @@ using ClientCapabilities = video_widevine::ClientIdentification::ClientCapabilities; using AnalogOutputCapabilities = ClientCapabilities::AnalogOutputCapabilities; using video_widevine::ClientIdentification_NameValue; -using video_widevine::EncryptedClientIdentification; -using video_widevine::ProvisioningOptions; -using video_widevine::ProvisioningRequest; -using video_widevine::ProvisioningResponse; -using video_widevine::SignedProvisioningMessage; CdmResponseType ClientIdentification::InitForProvisioningRequest( const std::string& client_token, CryptoSession* crypto_session) { if (crypto_session == nullptr) { LOGE("Crypto session not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } is_license_request_ = false; client_token_ = client_token; crypto_session_ = crypto_session; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType ClientIdentification::InitForLicenseRequest( const std::string& client_token, CryptoSession* crypto_session) { if (crypto_session == nullptr) { LOGE("Crypto session not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (client_token.empty()) { LOGE("Client token is empty"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } is_license_request_ = true; client_token_ = client_token; crypto_session_ = crypto_session; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType ClientIdentification::InitForOtaKeyboxProvisioning( CryptoSession* crypto_session) { if (crypto_session == nullptr) { LOGE("Crypto session not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } is_okp_request_ = true; crypto_session_ = crypto_session; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } /* @@ -131,7 +126,7 @@ CdmResponseType ClientIdentification::Prepare( video_widevine::ClientIdentification::TokenType token_type; if (!GetProvisioningTokenType(&token_type)) { LOGE("Failed to get provisioning token type"); - return CLIENT_IDENTIFICATION_TOKEN_ERROR_1; + return CdmResponseType(CLIENT_IDENTIFICATION_TOKEN_ERROR_1); } client_id->set_type(token_type); @@ -140,8 +135,7 @@ CdmResponseType ClientIdentification::Prepare( CdmResponseType status = crypto_session_->GetProvisioningToken(&token, &additional_token); if (status != NO_ERROR) { - LOGE("Failed to get provisioning token: status = %d", - static_cast(status)); + LOGE("Failed to get provisioning token: status = %d", status.ToInt()); return status; } client_id->set_token(token); @@ -221,7 +215,7 @@ CdmResponseType ClientIdentification::Prepare( if (is_okp_request_) { // Capabilities is not important for OTA keybox provisionining. - return NO_ERROR; + return CdmResponseType(NO_ERROR); } ClientCapabilities* client_capabilities = @@ -230,9 +224,9 @@ CdmResponseType ClientIdentification::Prepare( client_capabilities->set_client_token(true); if (is_license_request_) { - bool supports_usage_information; - if (crypto_session_->HasUsageInfoSupport(&supports_usage_information)) { - client_capabilities->set_session_token(supports_usage_information); + bool supports_usage_table; + if (crypto_session_->HasUsageTableSupport(&supports_usage_table)) { + client_capabilities->set_session_token(supports_usage_table); } client_capabilities->set_anti_rollback_usage_table( @@ -365,7 +359,12 @@ CdmResponseType ClientIdentification::Prepare( } } - return NO_ERROR; + if (api_version >= + OEM_CRYPTO_API_VERSION_SUPPORTS_INITIAL_RENEWAL_DELAY_BASE) { + client_capabilities->set_initial_renewal_delay_base(true); + } + + return CdmResponseType(NO_ERROR); } bool ClientIdentification::GetProvisioningTokenType( diff --git a/core/src/content_key_session.cpp b/core/src/content_key_session.cpp index 3c808d32..1e391505 100644 --- a/core/src/content_key_session.cpp +++ b/core/src/content_key_session.cpp @@ -80,25 +80,23 @@ OEMCryptoResult ContentKeySession::LoadKeys( OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id, CdmCipherMode cipher_mode) { // Crypto session lock already locked. - if (!cached_key_id_.empty() && cached_key_id_ == key_id && + if (key_id.empty()) { + LOGE("Empty key ID argument"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + if (!key_handle_.empty() && cached_key_id_ == key_id && cipher_mode_ == cipher_mode) { // Already using the desired key and cipher mode. return OEMCrypto_SUCCESS; } - cached_key_id_ = key_id; - cipher_mode_ = cipher_mode; - - const uint8_t* key_id_string = - reinterpret_cast(cached_key_id_.data()); - - OEMCryptoResult sts; - M_TIME(sts = OEMCrypto_SelectKey(oec_session_id_, key_id_string, - cached_key_id_.size(), - ToOEMCryptoCipherMode(cipher_mode)), - metrics_, oemcrypto_select_key_, sts); - - if (OEMCrypto_SUCCESS != sts) { + const OEMCryptoResult sts = + GetKeyHandle(oec_session_id_, key_id, cipher_mode); + if (sts == OEMCrypto_SUCCESS) { + cached_key_id_ = key_id; + cipher_mode_ = cipher_mode; + } else { + key_handle_.clear(); cached_key_id_.clear(); } return sts; @@ -114,65 +112,193 @@ OEMCryptoResult ContentKeySession::Decrypt( } OEMCryptoResult sts; - M_TIME(sts = OEMCrypto_DecryptCENC(oec_session_id_, samples, samples_length, - &pattern), + M_TIME(sts = OEMCrypto_DecryptCENC(security_level_, key_handle_.data(), + key_handle_.size(), samples, + samples_length, &pattern), metrics_, oemcrypto_decrypt_cenc_, sts, metrics::Pow2Bucket(total_size)); return sts; } -OEMCryptoResult ContentKeySession::LoadKeysAsLicenseType( - const std::string& message, const std::string& signature, - const std::string& mac_key_iv, const std::string& mac_key, - const std::vector& keys, - const std::string& provider_session_token, - const std::string& srm_requirement, OEMCrypto_LicenseType license_type) { - const uint8_t* msg = reinterpret_cast(message.data()); - cached_key_id_.clear(); - bool valid_mac_keys = - mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE; - OEMCrypto_Substring enc_mac_key = - GetSubstring(message, mac_key, !valid_mac_keys); - OEMCrypto_Substring enc_mac_key_iv = - GetSubstring(message, mac_key_iv, !valid_mac_keys); - if (!valid_mac_keys) LOGV("|enc_mac_key| is not set"); - std::vector load_keys(keys.size()); - std::vector cipher_modes(keys.size()); - for (size_t i = 0; i < keys.size(); ++i) { - const CryptoKey* ki = &keys[i]; - OEMCrypto_KeyObject* ko = &load_keys[i]; - ko->key_id = GetSubstring(message, ki->key_id()); - ko->key_data_iv = GetSubstring(message, ki->key_data_iv()); - ko->key_data = GetSubstring(message, ki->key_data()); - bool has_key_control = ki->HasKeyControl(); - ko->key_control_iv = - GetSubstring(message, ki->key_control_iv(), !has_key_control); - ko->key_control = - GetSubstring(message, ki->key_control(), !has_key_control); - if (!has_key_control) { - LOGE( - "Crypto key does not have a control block: " - "key_index = %zu, size = %zu", - i, ki->key_control().length()); +OEMCryptoResult ContentKeySession::GenericEncrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) { + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_Generic_Encrypt( + security_level_, key_handle_.data(), key_handle_.size(), + reinterpret_cast(in_buffer.data()), in_buffer.size(), + reinterpret_cast(iv.data()), algorithm, + reinterpret_cast(const_cast(out_buffer->data()))), + metrics_, oemcrypto_generic_encrypt_, sts, + metrics::Pow2Bucket(in_buffer.size())); + if (sts != OEMCrypto_SUCCESS) { + LOGE("OEMCrypto_Generic_Encrypt failed: status = %d", + static_cast(sts)); + } + return sts; +} + +OEMCryptoResult ContentKeySession::GenericDecrypt(const std::string& in_buffer, + const std::string& iv, + OEMCrypto_Algorithm algorithm, + std::string* out_buffer) { + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_Generic_Decrypt( + security_level_, key_handle_.data(), key_handle_.size(), + reinterpret_cast(in_buffer.data()), in_buffer.size(), + reinterpret_cast(iv.data()), algorithm, + reinterpret_cast(const_cast(out_buffer->data()))), + metrics_, oemcrypto_generic_decrypt_, sts, + metrics::Pow2Bucket(in_buffer.size())); + if (sts != OEMCrypto_SUCCESS) { + LOGE("OEMCrypto_Generic_Decrypt failed: status = %d", + static_cast(sts)); + } + return sts; +} + +OEMCryptoResult ContentKeySession::GenericSign(const std::string& message, + OEMCrypto_Algorithm algorithm, + std::string* signature) { + OEMCryptoResult sts; + size_t length = signature->size(); + + // At most two attempts. + // The first attempt may fail due to buffer too short + for (int i = 0; i < 2; ++i) { + M_TIME(sts = OEMCrypto_Generic_Sign( + security_level_, key_handle_.data(), key_handle_.size(), + reinterpret_cast(message.data()), message.size(), + algorithm, + reinterpret_cast(const_cast(signature->data())), + &length), + metrics_, oemcrypto_generic_sign_, sts, + metrics::Pow2Bucket(message.size())); + + if (sts != OEMCrypto_ERROR_SHORT_BUFFER) { + if (sts == OEMCrypto_SUCCESS) { + // Trim signature buffer and done + signature->resize(length); + } + break; } - cipher_modes[i] = ToOEMCryptoCipherMode(ki->cipher_mode()); + + // Retry with proper-sized return buffer + signature->resize(length); } - OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); - OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement); + if (sts != OEMCrypto_SUCCESS) { + LOGE("OEMCrypto_Generic_Sign failed: status = %d", static_cast(sts)); + } + return sts; +} - LOGV("session_id = %u", oec_session_id_); +OEMCryptoResult ContentKeySession::GenericVerify(const std::string& message, + OEMCrypto_Algorithm algorithm, + const std::string& signature) { OEMCryptoResult sts; - OEMCrypto_KeyObject* key_array_ptr = nullptr; - if (keys.size() > 0) key_array_ptr = &load_keys[0]; - OEMCryptoCipherMode* cipher_mode_ptr = nullptr; - if (keys.size() > 0) cipher_mode_ptr = &cipher_modes[0]; - M_TIME(sts = ::OEMCrypto_LoadKeys_Back_Compat( - oec_session_id_, msg, message.length(), - reinterpret_cast(signature.data()), - signature.length(), enc_mac_key_iv, enc_mac_key, keys.size(), - key_array_ptr, pst, srm_req, license_type, cipher_mode_ptr), - metrics_, oemcrypto_load_keys_, sts); + M_TIME(sts = OEMCrypto_Generic_Verify( + security_level_, key_handle_.data(), key_handle_.size(), + reinterpret_cast(message.data()), message.size(), + algorithm, reinterpret_cast(signature.data()), + signature.size()), + metrics_, oemcrypto_generic_verify_, sts, + metrics::Pow2Bucket(signature.size())); + if (sts != OEMCrypto_SUCCESS) { + LOGE("OEMCrypto_Generic_Verify failed: status = %d", static_cast(sts)); + } + return sts; +} + +OEMCryptoResult ContentKeySession::LoadKeysAsLicenseType( + const std::string& /* message */, const std::string& /* signature */, + const std::string& /* mac_key_iv */, const std::string& /* mac_key */, + const std::vector& /* keys */, + const std::string& /* provider_session_token */, + const std::string& /* srm_requirement */, + OEMCrypto_LicenseType /* license_type */) { + // TODO(b/252670759): remove all of this. + // const uint8_t* msg = reinterpret_cast(message.data()); + // cached_key_id_.clear(); + // bool valid_mac_keys = + // mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE; + // OEMCrypto_Substring enc_mac_key = + // GetSubstring(message, mac_key, !valid_mac_keys); + // OEMCrypto_Substring enc_mac_key_iv = + // GetSubstring(message, mac_key_iv, !valid_mac_keys); + // if (!valid_mac_keys) LOGV("|enc_mac_key| is not set"); + // std::vector load_keys(keys.size()); + // std::vector cipher_modes(keys.size()); + // for (size_t i = 0; i < keys.size(); ++i) { + // const CryptoKey* ki = &keys[i]; + // OEMCrypto_KeyObject* ko = &load_keys[i]; + // ko->key_id = GetSubstring(message, ki->key_id()); + // ko->key_data_iv = GetSubstring(message, ki->key_data_iv()); + // ko->key_data = GetSubstring(message, ki->key_data()); + // bool has_key_control = ki->HasKeyControl(); + // ko->key_control_iv = + // GetSubstring(message, ki->key_control_iv(), !has_key_control); + // ko->key_control = + // GetSubstring(message, ki->key_control(), !has_key_control); + // if (!has_key_control) { + // LOGE( + // "Crypto key does not have a control block: " + // "key_index = %zu, size = %zu", + // i, ki->key_control().length()); + // } + // cipher_modes[i] = ToOEMCryptoCipherMode(ki->cipher_mode()); + // } + + // OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + // OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement); + + // LOGV("session_id = %u", oec_session_id_); + // OEMCryptoResult sts; + // OEMCrypto_KeyObject* key_array_ptr = nullptr; + // if (keys.size() > 0) key_array_ptr = &load_keys[0]; + // OEMCryptoCipherMode* cipher_mode_ptr = nullptr; + // if (keys.size() > 0) cipher_mode_ptr = &cipher_modes[0]; + // M_TIME(sts = ::OEMCrypto_LoadKeys_Back_Compat( + // oec_session_id_, msg, message.length(), + // reinterpret_cast(signature.data()), + // signature.length(), enc_mac_key_iv, enc_mac_key, keys.size(), + // key_array_ptr, pst, srm_req, license_type, cipher_mode_ptr), + // metrics_, oemcrypto_load_keys_, sts); + return OEMCrypto_ERROR_INVALID_CONTEXT; +} + +OEMCryptoResult ContentKeySession::GetKeyHandle(CryptoSessionId session_id, + const std::string& key_id, + CdmCipherMode cipher_mode) { + const uint8_t* const key_id_pointer = + reinterpret_cast(key_id.data()); + const OEMCryptoCipherMode oec_cipher_mode = + ToOEMCryptoCipherMode(cipher_mode); + + size_t key_handle_length = 0; + OEMCryptoResult sts; + M_TIME(sts = OEMCrypto_GetKeyHandle(session_id, key_id_pointer, key_id.size(), + oec_cipher_mode, nullptr, + &key_handle_length), + metrics_, oemcrypto_get_key_handle_, sts); + + if (sts == OEMCrypto_SUCCESS) { + LOGE( + "OEMCrypto_GetKeyHandle returned SUCCESS despite getting no key handle " + "buffer"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } else if (sts != OEMCrypto_ERROR_SHORT_BUFFER) { + return sts; + } + + key_handle_.resize(key_handle_length); + M_TIME(sts = OEMCrypto_GetKeyHandle(session_id, key_id_pointer, key_id.size(), + oec_cipher_mode, key_handle_.data(), + &key_handle_length), + metrics_, oemcrypto_get_key_handle_, sts); return sts; } diff --git a/core/src/crypto_session.cpp b/core/src/crypto_session.cpp index 63ad9d22..0eef7f70 100644 --- a/core/src/crypto_session.cpp +++ b/core/src/crypto_session.cpp @@ -16,41 +16,60 @@ #include "advance_iv_ctr.h" #include "arraysize.h" +#include "cdm_random.h" +#include "cdm_usage_table.h" #include "content_key_session.h" #include "crypto_key.h" #include "entitlement_key_session.h" #include "log.h" +#include "odk_structs.h" #include "okp_fallback_policy.h" #include "platform.h" #include "privacy_crypto.h" #include "properties.h" #include "pst_report.h" #include "string_conversions.h" -#include "usage_table_header.h" #include "wv_cdm_constants.h" // Stringify turns macro arguments into static C strings. // Example: STRINGIFY(this_argument) -> "this_argument" #define STRINGIFY(PARAM) #PARAM +namespace { +bool WrapIfNecessary(bool ret_value) { return ret_value; } + +wvcdm::CdmResponseType WrapIfNecessary(wvcdm::CdmResponseEnum ret_value) { + return wvcdm::CdmResponseType(ret_value); +} + +wvcdm::CdmSecurityLevel WrapIfNecessary(wvcdm::CdmSecurityLevel ret_value) { + return ret_value; +} + +OEMCryptoResult WrapIfNecessary(OEMCryptoResult ret_value) { return ret_value; } +} // namespace + #define RETURN_IF_NULL(PARAM, ret_value) \ if ((PARAM) == nullptr) { \ LOGE("Output parameter |" STRINGIFY(PARAM) "| not provided"); \ - return ret_value; \ + return WrapIfNecessary(ret_value); \ } #define RETURN_IF_UNINITIALIZED(ret_value) \ if (!IsInitialized()) { \ LOGE("Crypto session is not initialized"); \ - return ret_value; \ + return WrapIfNecessary(ret_value); \ } #define RETURN_IF_NOT_OPEN(ret_value) \ if (!open_) { \ LOGE("Crypto session is not open"); \ - return ret_value; \ + return WrapIfNecessary(ret_value); \ } +#define CRYPTO_ERROR(cdm_err, oem_err) \ + CdmResponseType(cdm_err, oem_err, __func__) + #ifdef HAS_DUAL_KEY /** * Internal only OEMCrypto method. This is called before parsing the license @@ -104,7 +123,7 @@ constexpr size_t kMaxExternalDeviceIdLength = 64; // are not universal but are OEMCrypto method specific. Those will be // specified in the CryptoSession method rather than here. CdmResponseType MapOEMCryptoResult(OEMCryptoResult result, - CdmResponseType default_status, + CdmResponseEnum default_status, const char* crypto_session_method) { if (result != OEMCrypto_SUCCESS) { LOGE("Mapping OEMCrypto result: crypto_session_method = %s, result = %d", @@ -112,20 +131,27 @@ CdmResponseType MapOEMCryptoResult(OEMCryptoResult result, static_cast(result)); } + CdmResponseEnum status{}; switch (result) { case OEMCrypto_SUCCESS: - return NO_ERROR; + status = NO_ERROR; + break; case OEMCrypto_ERROR_NOT_IMPLEMENTED: - return NOT_IMPLEMENTED_ERROR; + status = NOT_IMPLEMENTED_ERROR; + break; case OEMCrypto_ERROR_TOO_MANY_SESSIONS: - return INSUFFICIENT_CRYPTO_RESOURCES; + status = INSUFFICIENT_CRYPTO_RESOURCES; + break; case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + status = SESSION_LOST_STATE_ERROR; + break; case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + status = SYSTEM_INVALIDATED_ERROR; + break; default: - return default_status; + status = default_status; } + return CdmResponseType(status, result, crypto_session_method); } void AdvanceDestBuffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { @@ -191,8 +217,8 @@ bool CryptoSession::initialized_ = false; bool CryptoSession::needs_keybox_provisioning_ = false; int CryptoSession::session_count_ = 0; int CryptoSession::termination_counter_ = 0; -std::unique_ptr CryptoSession::usage_table_header_l1_; -std::unique_ptr CryptoSession::usage_table_header_l3_; +std::unique_ptr CryptoSession::usage_table_l1_; +std::unique_ptr CryptoSession::usage_table_l3_; std::recursive_mutex CryptoSession::usage_table_mutex_; std::atomic CryptoSession::request_id_index_source_(0); std::unique_ptr @@ -329,10 +355,10 @@ CdmResponseType CryptoSession::GetProvisioningMethod( LOGE("OEMCrypto_GetProvisioningMethod failed: method = %d", static_cast(method)); metrics_->oemcrypto_provisioning_method_.SetError(method); - return GET_PROVISIONING_METHOD_ERROR; + return CdmResponseType(GET_PROVISIONING_METHOD_ERROR); } *token_type = type; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } void CryptoSession::Init() { @@ -380,8 +406,8 @@ void CryptoSession::ReinitializeForTest() { } initialized_ = false; // Tables will be reinitialized by tests when needed. - usage_table_header_l1_.reset(); - usage_table_header_l3_.reset(); + usage_table_l1_.reset(); + usage_table_l3_.reset(); } // Give up if we cannot initialize at all. const OEMCryptoResult status = OEMCrypto_Initialize(); @@ -389,6 +415,8 @@ void CryptoSession::ReinitializeForTest() { LOGE("OEMCrypto_Initialize failed: %d", status); return; } + OEMCrypto_SetMaxAPIVersion(ODK_MAJOR_VERSION); + OEMCrypto_EnterTestMode(); initialized_ = true; // For integration and unit tests we will install a test keybox and do not // need to do keybox provisioning. @@ -457,8 +485,8 @@ bool CryptoSession::TryTerminate() { }); if (terminated) { UsageTableLock lock(usage_table_mutex_); - usage_table_header_l1_.reset(); - usage_table_header_l3_.reset(); + usage_table_l1_.reset(); + usage_table_l3_.reset(); } return terminated; } @@ -469,9 +497,9 @@ void CryptoSession::DisableDelayedTermination() { [&] { termination_counter_ = 0; }); } -bool CryptoSession::SetUpUsageTableHeader( +bool CryptoSession::SetUpUsageTable( RequestedSecurityLevel requested_security_level) { - if (usage_table_header_ != nullptr) { + if (usage_table_ != nullptr) { LOGE("Usage table is already set up for the current crypto session"); return false; } @@ -486,7 +514,7 @@ bool CryptoSession::SetUpUsageTableHeader( // Check if usage support is available. bool supports_usage_table = false; - if (!HasUsageInfoSupport(requested_security_level, &supports_usage_table)) { + if (!HasUsageTableSupport(requested_security_level, &supports_usage_table)) { metrics_->oemcrypto_usage_table_support_.SetError( USAGE_INFORMATION_SUPPORT_FAILED); return false; @@ -497,30 +525,28 @@ bool CryptoSession::SetUpUsageTableHeader( return false; } - LOGV("Usage table lock: SetUpUsageTableHeader()"); + LOGV("Usage table lock: SetUpUsageTable()"); UsageTableLock auto_lock(usage_table_mutex_); // TODO(b/141350978): Prevent any recursive logic. // Manipulate only the usage table for the requested security level. - std::unique_ptr& header = security_level == kSecurityLevelL1 - ? usage_table_header_l1_ - : usage_table_header_l3_; - if (!header) { + std::unique_ptr& table = + security_level == kSecurityLevelL1 ? usage_table_l1_ : usage_table_l3_; + if (!table) { // This may be called twice within the same thread when the table // is initialized. On the second call |header| will not be null, // causing this block to be skipped. - header.reset(new UsageTableHeader()); - if (!header->Init(security_level, this)) { + table.reset(new CdmUsageTable()); + if (!table->Init(security_level, this)) { LOGE("Failed to initialize and sync usage usage table"); // Must be cleared globally to prevent the next session to be - // opened from using the invalid UsageTableHeader. - header.reset(); + // opened from using the invalid CdmUsageTable. + table.reset(); return false; } } - usage_table_header_ = header.get(); - metrics_->usage_table_header_initial_size_.Record( - usage_table_header_->size()); + usage_table_ = table.get(); + metrics_->usage_table_header_initial_size_.Record(usage_table_->size()); return true; } @@ -537,7 +563,7 @@ CdmResponseType CryptoSession::GetTokenFromKeybox( if (requested_security_level_ != kLevelDefault) return false; return needs_keybox_provisioning_; }); - if (keybox_provisioning_required) return NEED_PROVISIONING; + if (keybox_provisioning_required) return CdmResponseType(NEED_PROVISIONING); size_t key_data_length = KEYBOX_KEY_DATA_SIZE; key_data->assign(key_data_length, '\0'); @@ -551,7 +577,7 @@ CdmResponseType CryptoSession::GetTokenFromKeybox( }); if (OEMCrypto_SUCCESS == status) { key_data->resize(key_data_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } key_data->clear(); return MapOEMCryptoResult(status, GET_TOKEN_FROM_KEYBOX_ERROR, @@ -573,7 +599,7 @@ CdmResponseType CryptoSession::GetTokenFromOemCert( oem_cert->assign(oem_token_); return true; }); - if (cache_success) return NO_ERROR; + if (cache_success) return CdmResponseType(NO_ERROR); size_t oem_cert_length = CERTIFICATE_DATA_SIZE; oem_cert->assign(oem_cert_length, '\0'); @@ -598,7 +624,7 @@ CdmResponseType CryptoSession::GetTokenFromOemCert( oem_cert->resize(oem_cert_length); WithOecSessionLock("GetTokenFromOemCert - set cache", [&] { oem_token_ = *oem_cert; }); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } oem_cert->clear(); return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR, @@ -616,17 +642,18 @@ CdmResponseType CryptoSession::GetProvisioningToken( RequestedSecurityLevel requested_security_level, std::string* token, std::string* additional_token) { if (token == nullptr || additional_token == nullptr) { - metrics_->crypto_session_get_token_.Increment(PARAMETER_NULL); + metrics_->crypto_session_get_token_.Increment( + CdmResponseType(PARAMETER_NULL)); RETURN_IF_NULL(token, PARAMETER_NULL); RETURN_IF_NULL(additional_token, PARAMETER_NULL); } if (!IsInitialized()) { metrics_->crypto_session_get_token_.Increment( - CRYPTO_SESSION_NOT_INITIALIZED); - return CRYPTO_SESSION_NOT_INITIALIZED; + CdmResponseType(CRYPTO_SESSION_NOT_INITIALIZED)); + return CdmResponseType(CRYPTO_SESSION_NOT_INITIALIZED); } - CdmResponseType status = UNKNOWN_CLIENT_TOKEN_TYPE; + CdmResponseType status(UNKNOWN_CLIENT_TOKEN_TYPE); if (pre_provision_token_type_ == kClientTokenKeybox) { status = GetTokenFromKeybox(requested_security_level, token); } else if (pre_provision_token_type_ == kClientTokenOemCert) { @@ -709,7 +736,7 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId( // implemented, so the OEMCrypto can continue to report the same device ID. if (sts == OEMCrypto_SUCCESS) { device_id->resize(device_id_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } device_id->clear(); @@ -734,7 +761,7 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId( LOGD("Using null device ID"); constexpr size_t kKeyboxDeviceIdLength = 32; device_id->assign(kKeyboxDeviceIdLength, '\0'); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } return MapOEMCryptoResult(sts, GET_DEVICE_ID_ERROR, @@ -752,7 +779,7 @@ CdmResponseType CryptoSession::GetExternalDeviceUniqueId( // the large OEM Public Cert to a smaller value. *device_id = Sha256Hash(*device_id); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } bool CryptoSession::GetApiVersion(uint32_t* version) { @@ -816,20 +843,18 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) { RETURN_IF_NULL(provisioning_id, PARAMETER_NULL); RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); - if (pre_provision_token_type_ == kClientTokenOemCert) { - // OEM Cert devices have no provisioning-unique ID embedded in them, so we - // synthesize one by using the External Device-Unique ID and inverting all - // the bits. - CdmResponseType status = GetExternalDeviceUniqueId(provisioning_id); - + if (pre_provision_token_type_ == kClientTokenOemCert || + pre_provision_token_type_ == kClientTokenBootCertChain) { + // OEM Cert and BCC devices have no provisioning-unique ID embedded in + // them, so we synthesize one by using the External Device-Unique ID + // and inverting all the bits. + const CdmResponseType status = GetExternalDeviceUniqueId(provisioning_id); if (status != NO_ERROR) return status; - for (size_t i = 0; i < provisioning_id->size(); ++i) { - char value = (*provisioning_id)[i]; - (*provisioning_id)[i] = ~value; + for (char& c : *provisioning_id) { + c ^= 0xff; } - - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (pre_provision_token_type_ == kClientTokenKeybox) { std::string token; @@ -840,15 +865,15 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) { if (token.size() < 24) { LOGE("Keybox token size too small: %zu", token.size()); - return KEYBOX_TOKEN_TOO_SHORT; + return CdmResponseType(KEYBOX_TOKEN_TOO_SHORT); } provisioning_id->assign(reinterpret_cast(&token[8]), 16); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } LOGE("Unsupported pre-provision token type: %d", static_cast(pre_provision_token_type_)); - return UNKNOWN_CLIENT_TOKEN_TYPE; + return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE); } uint8_t CryptoSession::GetSecurityPatchLevel() { @@ -865,9 +890,9 @@ CdmResponseType CryptoSession::Open( LOGD("Opening crypto session: requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); - if (open_) return NO_ERROR; + if (open_) return CdmResponseType(NO_ERROR); - if (!SetUpUsageTableHeader(requested_security_level)) { + if (!SetUpUsageTable(requested_security_level)) { // Ignore errors since we do not know when a session is opened, // if it is intended to be used for offline/usage session related // or otherwise. @@ -907,13 +932,8 @@ CdmResponseType CryptoSession::Open( open_ = true; // Set up request ID - uint64_t request_id_base; - OEMCryptoResult random_sts; - WithOecReadLock("Open() calling OEMCrypto_GetRandom", [&] { - random_sts = OEMCrypto_GetRandom( - reinterpret_cast(&request_id_base), sizeof(request_id_base)); - }); - metrics_->oemcrypto_get_random_.Increment(random_sts); + uint64_t request_id_base = + wvutil::CdmRandom::RandomInRange(std::numeric_limits::max()); uint64_t request_id_index = request_id_index_source_.fetch_add(1, std::memory_order_relaxed); request_id_ = wvutil::HexEncode(reinterpret_cast(&request_id_base), @@ -923,14 +943,15 @@ CdmResponseType CryptoSession::Open( // Initialize key session WithOecSessionLock("Open() calling key_session_.reset()", [&] { - key_session_.reset(new ContentKeySession(oec_session_id_, metrics_)); + key_session_.reset(new ContentKeySession(requested_security_level_, + oec_session_id_, metrics_)); }); if (!GetApiVersion(&api_version_)) { LOGE("Failed to get API version"); - return USAGE_SUPPORT_GET_API_FAILED; + return CdmResponseType(USAGE_SUPPORT_GET_API_FAILED); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } void CryptoSession::Close() { @@ -943,7 +964,7 @@ void CryptoSession::Close() { metrics_->oemcrypto_close_session_.Increment(close_sts); // Clear cached values. - has_usage_info_support_ = kBooleanUnset; + has_usage_table_support_ = kBooleanUnset; oem_token_.clear(); system_id_ = NULL_SYSTEM_ID; pre_provision_token_type_ = kClientTokenUninitialized; @@ -956,7 +977,7 @@ void CryptoSession::Close() { case OEMCrypto_SUCCESS: case OEMCrypto_ERROR_INVALID_SESSION: case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - usage_table_header_ = nullptr; + usage_table_ = nullptr; open_ = false; break; case OEMCrypto_ERROR_CLOSE_SESSION_FAILED: @@ -968,12 +989,27 @@ void CryptoSession::Close() { CdmResponseType CryptoSession::PrepareAndSignLicenseRequest( const std::string& message, std::string* core_message, - std::string* signature) { + std::string* signature, bool& should_specify_algorithm, + OEMCrypto_SignatureHashAlgorithm& algorithm) { LOGV("Preparing and signing license request: id = %u", oec_session_id_); RETURN_IF_NULL(signature, PARAMETER_NULL); RETURN_IF_NULL(core_message, PARAMETER_NULL); + RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); OEMCryptoResult sts; + WithOecSessionLock("GetSignatureHashAlgorithm", [&] { + sts = OEMCrypto_GetSignatureHashAlgorithm(oec_session_id_, &algorithm); + }); + metrics_->oemcrypto_get_signature_hash_algorithm_.Increment(sts, algorithm); + if (sts == OEMCrypto_SUCCESS) { + should_specify_algorithm = true; + } else if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { + should_specify_algorithm = false; + } else { + return MapOEMCryptoResult(sts, GET_SIGNATURE_HASH_ALGORITHM_ERROR_1, + "PrepareAndSignLicenseRequest"); + } + size_t signature_length = 0; size_t core_message_length = 0; *core_message = ""; @@ -997,7 +1033,7 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest( if (static_cast(sts) == kRsaSsaPssSignatureLengthError) { LOGE("OEMCrypto PrepareAndSignLicenseRequest result = %d", static_cast(sts)); - return NEED_PROVISIONING; + return CRYPTO_ERROR(NEED_PROVISIONING, sts); } return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR, "PrepareAndSignLicenseRequest"); @@ -1024,7 +1060,7 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest( *core_message = std::move(combined_message); // Truncate combined message to only contain the core message. core_message->resize(core_message_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // TODO(b/174412779): Remove when b/170704368 is fixed. // Temporary workaround. If this error is returned the only way to @@ -1032,63 +1068,26 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest( if (static_cast(sts) == kRsaSsaPssSignatureLengthError) { LOGE("OEMCrypto PrepareAndSignLicenseRequest result = %d", static_cast(sts)); - return NEED_PROVISIONING; + return CRYPTO_ERROR(NEED_PROVISIONING, sts); } return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR, "PrepareAndSignLicenseRequest"); } -CdmResponseType CryptoSession::UseSecondaryKey(bool dual_key) { #ifdef HAS_DUAL_KEY +CdmResponseType CryptoSession::UseSecondaryKey(bool dual_key) { OEMCryptoResult sts; WithOecSessionLock("UseSecondaryKey", [&] { sts = OEMCrypto_UseSecondaryKey(oec_session_id_, dual_key); }); return MapOEMCryptoResult(sts, LOAD_KEY_ERROR, "UseSecondaryKey"); +} #else - return NO_ERROR; +CdmResponseType CryptoSession::UseSecondaryKey(bool /* dual_key */) { + return CdmResponseType(NO_ERROR); +} #endif -} - -CdmResponseType CryptoSession::LoadKeys( - const std::string& message, const std::string& signature, - const std::string& mac_key_iv, const std::string& mac_key, - const std::vector& keys, - const std::string& provider_session_token, - const std::string& srm_requirement, CdmLicenseKeyType key_type) { - LOGV("Loading keys: id = %u", oec_session_id_); - OEMCryptoResult sts; - WithOecSessionLock("LoadKeys", [&] { - if (key_type == kLicenseKeyTypeEntitlement && - key_session_->Type() != KeySession::kEntitlement) { - key_session_.reset(new EntitlementKeySession(oec_session_id_, metrics_)); - } - - LOGV("Loading key: id = %u", oec_session_id_); - sts = key_session_->LoadKeys(message, signature, mac_key_iv, mac_key, keys, - provider_session_token, srm_requirement); - }); - - if (sts != OEMCrypto_SUCCESS) { - LOGE("OEMCrypto_LoadKeys failed: status = %d", static_cast(sts)); - } - - switch (sts) { - case OEMCrypto_SUCCESS: - if (!provider_session_token.empty()) - update_usage_table_after_close_session_ = true; - return KEY_ADDED; - case OEMCrypto_ERROR_TOO_MANY_KEYS: - return INSUFFICIENT_CRYPTO_RESOURCES; - case OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE: - // Handle vendor specific error - return NEED_PROVISIONING; - default: - break; - } - return MapOEMCryptoResult(sts, LOAD_KEY_ERROR, "LoadKeys"); -} CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message, const std::string& core_message, @@ -1100,7 +1099,8 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message, WithOecSessionLock("LoadLicense", [&] { if (key_type == kLicenseKeyTypeEntitlement && key_session_->Type() != KeySession::kEntitlement) { - key_session_.reset(new EntitlementKeySession(oec_session_id_, metrics_)); + key_session_.reset(new EntitlementKeySession(requested_security_level_, + oec_session_id_, metrics_)); } M_TIME(sts = OEMCrypto_LoadLicense( @@ -1114,13 +1114,13 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message, switch (sts) { case OEMCrypto_SUCCESS: - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); case OEMCrypto_ERROR_BUFFER_TOO_LARGE: LOGE("LoadLicense buffer too large: size = %zu", combined_message.size()); - return LOAD_LICENSE_ERROR; + return CRYPTO_ERROR(LOAD_LICENSE_ERROR, sts); case OEMCrypto_ERROR_TOO_MANY_KEYS: LOGE("Too many keys in license"); - return INSUFFICIENT_CRYPTO_RESOURCES; + return CRYPTO_ERROR(INSUFFICIENT_CRYPTO_RESOURCES, sts); default: break; } @@ -1133,11 +1133,11 @@ CdmResponseType CryptoSession::PrepareAndSignRenewalRequest( LOGV("Preparing and signing renewal request: id = %u", oec_session_id_); if (signature == nullptr) { LOGE("Output parameter |signature| not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (core_message == nullptr) { LOGE("Output parameter |core_message| not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } OEMCryptoResult sts; @@ -1183,42 +1183,12 @@ CdmResponseType CryptoSession::PrepareAndSignRenewalRequest( *core_message = std::move(combined_message); // Truncate combined message to only contain the core message. core_message->resize(core_message_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR, "PrepareAndSignRenewalRequest"); } -CdmResponseType CryptoSession::RefreshKeys( - const std::string& message, const std::string& signature, - const std::vector& key_array) { - const uint8_t* msg = reinterpret_cast(message.data()); - std::vector load_key_array(key_array.size()); - for (size_t i = 0; i < key_array.size(); ++i) { - const CryptoKey* ki = &key_array[i]; - OEMCrypto_KeyRefreshObject* ko = &load_key_array[i]; - ko->key_id = GetSubstring(message, ki->key_id()); - bool has_key_control = ki->HasKeyControl(); - ko->key_control_iv = - GetSubstring(message, ki->key_control_iv(), !has_key_control); - ko->key_control = - GetSubstring(message, ki->key_control(), !has_key_control); - } - LOGV("Refreshing keys: id = %u", oec_session_id_); - OEMCryptoResult refresh_sts; - WithOecSessionLock("RefreshKeys", [&] { - M_TIME(refresh_sts = OEMCrypto_RefreshKeys( - oec_session_id_, msg, message.size(), - reinterpret_cast(signature.data()), - signature.size(), key_array.size(), &load_key_array[0]), - metrics_, oemcrypto_refresh_keys_, refresh_sts); - }); - - if (refresh_sts == OEMCrypto_SUCCESS) return KEY_ADDED; - - return MapOEMCryptoResult(refresh_sts, REFRESH_KEYS_ERROR, "RefreshKeys"); -} - CdmResponseType CryptoSession::LoadRenewal(const std::string& signed_message, const std::string& core_message, const std::string& signature) { @@ -1235,43 +1205,65 @@ CdmResponseType CryptoSession::LoadRenewal(const std::string& signed_message, metrics_, oemcrypto_load_renewal_, sts); }); if (sts == OEMCrypto_SUCCESS) { - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE) { LOGE("Buffer too large: size = %zu", combined_message.size()); - return LOAD_RENEWAL_ERROR; + return CRYPTO_ERROR(LOAD_RENEWAL_ERROR, sts); } return MapOEMCryptoResult(sts, LOAD_RENEWAL_ERROR, "LoadRenewal"); } CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest( const std::string& message, std::string* core_message, - std::string* signature) { + std::string* signature, bool& should_specify_algorithm, + OEMCrypto_SignatureHashAlgorithm& algorithm) { LOGV("Preparing and signing provisioning request: id = %u", oec_session_id_); if (signature == nullptr) { LOGE("Output parameter |signature| not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (core_message == nullptr) { LOGE("Output parameter |core_message| not provided"); - return PARAMETER_NULL; - } - - if (pre_provision_token_type_ == kClientTokenKeybox) { - const CdmResponseType status = GenerateDerivedKeys(message); - if (status != NO_ERROR) return status; - } else if (pre_provision_token_type_ == kClientTokenOemCert) { - const OEMCryptoResult status = OEMCrypto_LoadOEMPrivateKey(oec_session_id_); - if (status != OEMCrypto_SUCCESS) { - return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR, - "PrepareAndSignProvisioningRequest"); - } - } else { - LOGE("Unknown method %d", pre_provision_token_type_); - return UNKNOWN_CLIENT_TOKEN_TYPE; + return CdmResponseType(PARAMETER_NULL); } OEMCryptoResult sts; + if (pre_provision_token_type_ == kClientTokenKeybox) { + should_specify_algorithm = false; + const CdmResponseType status = GenerateDerivedKeys(message); + if (status != NO_ERROR) return status; + } else if (pre_provision_token_type_ == kClientTokenOemCert) { + should_specify_algorithm = true; + WithOecSessionLock("LoadOEMPrivateKey", [&] { + sts = OEMCrypto_LoadOEMPrivateKey(oec_session_id_); + }); + if (sts != OEMCrypto_SUCCESS) { + return MapOEMCryptoResult(sts, GET_TOKEN_FROM_OEM_CERT_ERROR, + "PrepareAndSignProvisioningRequest"); + } + } else if (pre_provision_token_type_ == kClientTokenBootCertChain) { + should_specify_algorithm = true; + // Do nothing here. The key to signing the provisioning 4.0 request for each + // stage has been loaded already when it was generated by OEMCrypto. + } else { + LOGE("Unknown method %d", pre_provision_token_type_); + return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE); + } + + if (should_specify_algorithm) { + WithOecSessionLock("GetSignatureHashAlgorithm", [&] { + sts = OEMCrypto_GetSignatureHashAlgorithm(oec_session_id_, &algorithm); + }); + metrics_->oemcrypto_get_signature_hash_algorithm_.Increment(sts, algorithm); + if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { + should_specify_algorithm = false; + } else if (sts != OEMCrypto_SUCCESS) { + return MapOEMCryptoResult(sts, GET_SIGNATURE_HASH_ALGORITHM_ERROR_3, + "PrepareAndSignProvisioningRequest"); + } + } + size_t signature_length = 0; size_t core_message_length = 0; *core_message = ""; @@ -1314,7 +1306,7 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest( *core_message = std::move(combined_message); // Truncate combined message to only contain the core message. core_message->resize(core_message_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR, "PrepareAndSignProvisioningRequest"); @@ -1328,19 +1320,19 @@ CdmResponseType CryptoSession::LoadEntitledContentKeys( switch (sts) { case OEMCrypto_SUCCESS: - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: - return INSUFFICIENT_CRYPTO_RESOURCES; + return CRYPTO_ERROR(INSUFFICIENT_CRYPTO_RESOURCES, sts); case OEMCrypto_ERROR_INVALID_CONTEXT: - return NOT_AN_ENTITLEMENT_SESSION; + return CRYPTO_ERROR(NOT_AN_ENTITLEMENT_SESSION, sts); case OEMCrypto_KEY_NOT_ENTITLED: - return NO_MATCHING_ENTITLEMENT_KEY; + return CRYPTO_ERROR(NO_MATCHING_ENTITLEMENT_KEY, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return LOAD_ENTITLED_CONTENT_KEYS_ERROR; + return CRYPTO_ERROR(LOAD_ENTITLED_CONTENT_KEYS_ERROR, sts); } } @@ -1383,12 +1375,20 @@ CdmResponseType CryptoSession::GetBootCertificateChain( RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); LOGV("requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); - if (pre_provision_token_type_ != kClientTokenBootCertChain) { - return PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR; + CdmClientTokenType token_type = kClientTokenUninitialized; + const CdmResponseType status = + GetProvisioningMethod(requested_security_level, &token_type); + if (status != NO_ERROR) { + LOGE("Failed to get token type"); + return status; + } + if (token_type != kClientTokenBootCertChain) { + return CdmResponseType( + PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR); } if (requested_security_level != kLevelDefault) { LOGE("CDM only supports L1 BCC"); - return NOT_IMPLEMENTED_ERROR; + return CdmResponseType(NOT_IMPLEMENTED_ERROR); } size_t bcc_length = 0; @@ -1414,7 +1414,7 @@ CdmResponseType CryptoSession::GetBootCertificateChain( } bcc->resize(bcc_length); additional_signature->resize(additional_signature_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CryptoSession::GenerateCertificateKeyPair( @@ -1475,10 +1475,11 @@ CdmResponseType CryptoSession::GenerateCertificateKeyPair( } else { LOGE("Unexpected key type returned from GenerateCertificateKeyPair: %d", static_cast(oemcrypto_key_type)); - return GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR; + // TODO(b/261185349): add OEMCrypto_PrivateKeyType to CdmResponseType + return CdmResponseType(GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CryptoSession::LoadOemCertificatePrivateKey( @@ -1515,36 +1516,36 @@ CdmResponseType CryptoSession::SelectKey(const std::string& key_id, switch (sts) { // SelectKey errors. case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_INVALID_SESSION: - return INVALID_SESSION_1; + return CRYPTO_ERROR(INVALID_SESSION_1, sts); case OEMCrypto_ERROR_NO_DEVICE_KEY: - return NO_DEVICE_KEY_1; + return CRYPTO_ERROR(NO_DEVICE_KEY_1, sts); case OEMCrypto_ERROR_NO_CONTENT_KEY: - return NO_CONTENT_KEY_2; + return CRYPTO_ERROR(NO_CONTENT_KEY_2, sts); case OEMCrypto_ERROR_CONTROL_INVALID: case OEMCrypto_ERROR_KEYBOX_INVALID: - return UNKNOWN_SELECT_KEY_ERROR_2; + return CRYPTO_ERROR(UNKNOWN_SELECT_KEY_ERROR_2, sts); case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: - return INSUFFICIENT_CRYPTO_RESOURCES; + return CRYPTO_ERROR(INSUFFICIENT_CRYPTO_RESOURCES, sts); case OEMCrypto_ERROR_UNKNOWN_FAILURE: - return UNKNOWN_SELECT_KEY_ERROR_1; + return CRYPTO_ERROR(UNKNOWN_SELECT_KEY_ERROR_1, sts); case OEMCrypto_ERROR_ANALOG_OUTPUT: - return ANALOG_OUTPUT_ERROR; + return CRYPTO_ERROR(ANALOG_OUTPUT_ERROR, sts); case OEMCrypto_ERROR_INSUFFICIENT_HDCP: - return INSUFFICIENT_OUTPUT_PROTECTION; + return CRYPTO_ERROR(INSUFFICIENT_OUTPUT_PROTECTION, sts); // LoadEntitledContentKeys errors. // |key_session_| may make calls to OEMCrypto_LoadEntitledContentKeys // if the key selected has not yet been loaded. case OEMCrypto_ERROR_INVALID_CONTEXT: - return NOT_AN_ENTITLEMENT_SESSION; + return CRYPTO_ERROR(NOT_AN_ENTITLEMENT_SESSION, sts); case OEMCrypto_KEY_NOT_ENTITLED: - return NO_MATCHING_ENTITLEMENT_KEY; + return CRYPTO_ERROR(NO_MATCHING_ENTITLEMENT_KEY, sts); // Obsolete errors. case OEMCrypto_KEY_NOT_LOADED: - return NO_CONTENT_KEY_3; + return CRYPTO_ERROR(NO_CONTENT_KEY_3, sts); // Catch all else. default: return MapOEMCryptoResult(sts, UNKNOWN_SELECT_KEY_ERROR_2, "SelectKey"); @@ -1598,7 +1599,7 @@ CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message, if (OEMCrypto_SUCCESS == sts) { // Trim signature buffer and done signature->resize(length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (OEMCrypto_ERROR_SHORT_BUFFER != sts) { break; @@ -1639,22 +1640,23 @@ size_t CryptoSession::GetMaxSubsampleRegionSize() { CdmResponseType CryptoSession::Decrypt( const CdmDecryptionParametersV16& params) { if (!is_destination_buffer_type_valid_) { - if (!SetDestinationBufferType()) return UNKNOWN_ERROR; + if (!SetDestinationBufferType()) return CdmResponseType(UNKNOWN_ERROR); } OEMCryptoBufferType output_descriptor_type = params.is_secure ? destination_buffer_type_ : OEMCrypto_BufferType_Clear; if (params.is_secure && output_descriptor_type == OEMCrypto_BufferType_Clear) { - return SECURE_BUFFER_REQUIRED; + return CdmResponseType(SECURE_BUFFER_REQUIRED); } - if (params.samples.size() == 0) return CANNOT_DECRYPT_ZERO_SAMPLES; + if (params.samples.size() == 0) + return CdmResponseType(CANNOT_DECRYPT_ZERO_SAMPLES); if (std::any_of(std::begin(params.samples), std::end(params.samples), [](const CdmDecryptionSample& sample) -> bool { return sample.subsamples.size() == 0; })) { - return CANNOT_DECRYPT_ZERO_SUBSAMPLES; + return CdmResponseType(CANNOT_DECRYPT_ZERO_SUBSAMPLES); } // Convert all the sample and subsample definitions to OEMCrypto structs. @@ -1745,11 +1747,12 @@ CdmResponseType CryptoSession::Decrypt( // Check that the total size is valid if (sample_size != oec_sample.buffers.input_data_length) - return SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH; + return CdmResponseType(SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH); // Set up the sample's IV if (is_any_subsample_protected) { - if (sizeof(oec_sample.iv) != sample.iv.size()) return INVALID_IV_SIZE; + if (sizeof(oec_sample.iv) != sample.iv.size()) + return CdmResponseType(INVALID_IV_SIZE); memcpy(oec_sample.iv, sample.iv.data(), sizeof(oec_sample.iv)); } else { memset(oec_sample.iv, 0, sizeof(oec_sample.iv)); @@ -1806,63 +1809,63 @@ CdmResponseType CryptoSession::Decrypt( switch (sts) { case OEMCrypto_SUCCESS: case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: - return INSUFFICIENT_CRYPTO_RESOURCES; + return CRYPTO_ERROR(INSUFFICIENT_CRYPTO_RESOURCES, sts); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_INVALID_SESSION: - return INVALID_SESSION_2; + return CRYPTO_ERROR(INVALID_SESSION_2, sts); case OEMCrypto_ERROR_DECRYPT_FAILED: case OEMCrypto_ERROR_UNKNOWN_FAILURE: - return DECRYPT_ERROR; + return CRYPTO_ERROR(DECRYPT_ERROR, sts); case OEMCrypto_ERROR_INSUFFICIENT_HDCP: - return INSUFFICIENT_OUTPUT_PROTECTION; + return CRYPTO_ERROR(INSUFFICIENT_OUTPUT_PROTECTION, sts); case OEMCrypto_ERROR_ANALOG_OUTPUT: - return ANALOG_OUTPUT_ERROR; + return CRYPTO_ERROR(ANALOG_OUTPUT_ERROR, sts); case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - return OUTPUT_TOO_LARGE_ERROR; + return CRYPTO_ERROR(OUTPUT_TOO_LARGE_ERROR, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return UNKNOWN_ERROR; + return CRYPTO_ERROR(UNKNOWN_ERROR, sts); } } -bool CryptoSession::HasUsageInfoSupport(bool* has_support) { +bool CryptoSession::HasUsageTableSupport(bool* has_support) { RETURN_IF_NOT_OPEN(false); RETURN_IF_NULL(has_support, false); - return WithOecReadLock("HasUsageInfoSupport", [&] { + return WithOecReadLock("HasUsageTableSupport", [&] { // Use cached value if set. - if (has_usage_info_support_ != kBooleanUnset) { - *has_support = (has_usage_info_support_ == kBooleanTrue); + if (has_usage_table_support_ != kBooleanUnset) { + *has_support = (has_usage_table_support_ == kBooleanTrue); return true; } - if (!HasUsageInfoSupportInternal(requested_security_level_, has_support)) { + if (!HasUsageTableSupportInternal(requested_security_level_, has_support)) { return false; } // Cache result if successful. - has_usage_info_support_ = (*has_support ? kBooleanTrue : kBooleanFalse); + has_usage_table_support_ = (*has_support ? kBooleanTrue : kBooleanFalse); return true; }); } -bool CryptoSession::HasUsageInfoSupport( +bool CryptoSession::HasUsageTableSupport( RequestedSecurityLevel requested_security_level, bool* has_support) { RETURN_IF_UNINITIALIZED(false); RETURN_IF_NULL(has_support, false); - return WithOecReadLock("HasUsageInfoSupport", [&] { - return HasUsageInfoSupportInternal(requested_security_level, has_support); + return WithOecReadLock("HasUsageTableSupport", [&] { + return HasUsageTableSupportInternal(requested_security_level, has_support); }); } -bool CryptoSession::HasUsageInfoSupportInternal( +bool CryptoSession::HasUsageTableSupportInternal( RequestedSecurityLevel requested_security_level, bool* has_support) { LOGV("requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); - *has_support = WithOecReadLock("HasUsageInfoSupport", [&] { + *has_support = WithOecReadLock("HasUsageTableSupport", [&] { return OEMCrypto_SupportsUsageTable(requested_security_level); }); return true; @@ -1890,15 +1893,15 @@ CdmResponseType CryptoSession::DeactivateUsageInformation( switch (status) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_INVALID_CONTEXT: - return KEY_CANCELED; + return CRYPTO_ERROR(KEY_CANCELED, status); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, status); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, status); default: - return DEACTIVATE_USAGE_ENTRY_ERROR; + return CRYPTO_ERROR(DEACTIVATE_USAGE_ENTRY_ERROR, status); } } @@ -1954,12 +1957,13 @@ CdmResponseType CryptoSession::GenerateUsageReport( "Parsed usage report smaller than expected: " "usage_length = %zu, report_size = %zu", usage_length, pst_report.report_size()); - return NO_ERROR; // usage report available but no duration information + return CdmResponseType( + NO_ERROR); // usage report available but no duration information } if (kUnused == pst_report.status()) { *usage_duration_status = kUsageDurationPlaybackNotBegun; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } LOGV("OEMCrypto_PST_Report.status: %d\n", static_cast(pst_report.status())); @@ -1979,7 +1983,7 @@ CdmResponseType CryptoSession::GenerateUsageReport( if (kInactiveUnused == pst_report.status()) { *usage_duration_status = kUsageDurationPlaybackNotBegun; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } // Before OEMCrypto v13, When usage report state is inactive, we have to // deduce whether the license was ever used. @@ -1988,13 +1992,13 @@ CdmResponseType CryptoSession::GenerateUsageReport( pst_report.seconds_since_license_received() < pst_report.seconds_since_first_decrypt())) { *usage_duration_status = kUsageDurationPlaybackNotBegun; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } *usage_duration_status = kUsageDurationsValid; *seconds_since_started = pst_report.seconds_since_first_decrypt(); *seconds_since_last_played = pst_report.seconds_since_last_decrypt(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } bool CryptoSession::IsAntiRollbackHwPresent() { @@ -2039,7 +2043,7 @@ CdmResponseType CryptoSession::LoadProvisioning( LOGV("Loading provisioning certificate: id = %u", oec_session_id_); if (wrapped_private_key == nullptr) { LOGE("Missing wrapped |wrapped_private_key|"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } const std::string combined_message = core_message + signed_message; @@ -2077,7 +2081,7 @@ CdmResponseType CryptoSession::LoadProvisioning( if (status == OEMCrypto_SUCCESS) { wrapped_private_key->resize(wrapped_private_key_length); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } wrapped_private_key->clear(); return MapOEMCryptoResult(status, LOAD_PROVISIONING_ERROR, @@ -2100,9 +2104,8 @@ CdmResponseType CryptoSession::GetHdcpCapabilities( RETURN_IF_NULL(current, PARAMETER_NULL); RETURN_IF_NULL(max, PARAMETER_NULL); - OEMCryptoResult status; - WithOecReadLock("GetHdcpCapabilities", [&] { - status = OEMCrypto_GetHDCPCapability(security_level, current, max); + const OEMCryptoResult status = WithOecReadLock("GetHdcpCapabilities", [&] { + return OEMCrypto_GetHDCPCapability(security_level, current, max); }); if (OEMCrypto_SUCCESS == status) { @@ -2135,18 +2138,6 @@ bool CryptoSession::GetSupportedCertificateTypes( return true; } -CdmResponseType CryptoSession::GetRandom(size_t data_length, - uint8_t* random_data) { - RETURN_IF_NULL(random_data, PARAMETER_NULL); - - OEMCryptoResult sts; - WithOecReadLock("GetRandom", - [&] { sts = OEMCrypto_GetRandom(random_data, data_length); }); - metrics_->oemcrypto_get_random_.Increment(sts); - - return MapOEMCryptoResult(sts, RANDOM_GENERATION_ERROR, "GetRandom"); -} - CdmResponseType CryptoSession::GetNumberOfOpenSessions( RequestedSecurityLevel security_level, size_t* count) { LOGV("Getting number of open sessions: id = %u, security_level = %s", @@ -2211,13 +2202,13 @@ CdmResponseType CryptoSession::GetSrmVersion(uint16_t* srm_version) { // returned. switch (status) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_LOCAL_DISPLAY_ONLY: LOGD("No SRM: Local display only"); - return NO_SRM_VERSION; + return CRYPTO_ERROR(NO_SRM_VERSION, status); case OEMCrypto_ERROR_NOT_IMPLEMENTED: LOGD("No SRM: Not implemented"); - return NO_SRM_VERSION; + return CRYPTO_ERROR(NO_SRM_VERSION, status); default: return MapOEMCryptoResult(status, GET_SRM_VERSION_ERROR, "GetCurrentSRMVersion"); @@ -2440,15 +2431,15 @@ CdmResponseType CryptoSession::GetDecryptHashError(std::string* error_string) { error_string->assign(std::to_string(sts)); error_string->append(","); error_string->append(std::to_string(failed_frame_number)); - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); case OEMCrypto_ERROR_UNKNOWN_FAILURE: case OEMCrypto_ERROR_NOT_IMPLEMENTED: default: - return GET_DECRYPT_HASH_ERROR; + return CRYPTO_ERROR(GET_DECRYPT_HASH_ERROR, sts); } } @@ -2463,7 +2454,7 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer, OEMCrypto_Algorithm oec_algorithm = OEMCrypto_AES_CBC_128_NO_PADDING; if (iv.size() != GenericEncryptionBlockSize(algorithm) || !GetGenericEncryptionAlgorithm(algorithm, &oec_algorithm)) { - return INVALID_PARAMETERS_ENG_13; + return CdmResponseType(INVALID_PARAMETERS_ENG_13); } if (out_buffer->size() < in_buffer.size()) { @@ -2479,14 +2470,8 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer, OEMCryptoResult sts; WithOecSessionLock("GenericEncrypt", [&] { - M_TIME( - sts = OEMCrypto_Generic_Encrypt( - oec_session_id_, reinterpret_cast(in_buffer.data()), - in_buffer.size(), reinterpret_cast(iv.data()), - oec_algorithm, - reinterpret_cast(const_cast(out_buffer->data()))), - metrics_, oemcrypto_generic_encrypt_, sts, - metrics::Pow2Bucket(in_buffer.size())); + sts = + key_session_->GenericEncrypt(in_buffer, iv, oec_algorithm, out_buffer); }); if (OEMCrypto_SUCCESS != sts) { @@ -2496,20 +2481,20 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer, switch (sts) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_NO_CONTENT_KEY: case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15. - return KEY_NOT_FOUND_3; + return CRYPTO_ERROR(KEY_NOT_FOUND_3, sts); case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - return OUTPUT_TOO_LARGE_ERROR; + return CRYPTO_ERROR(OUTPUT_TOO_LARGE_ERROR, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return UNKNOWN_ERROR; + return CRYPTO_ERROR(UNKNOWN_ERROR, sts); } } @@ -2524,7 +2509,7 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer, OEMCrypto_Algorithm oec_algorithm = OEMCrypto_AES_CBC_128_NO_PADDING; if (iv.size() != GenericEncryptionBlockSize(algorithm) || !GetGenericEncryptionAlgorithm(algorithm, &oec_algorithm)) { - return INVALID_PARAMETERS_ENG_14; + return CdmResponseType(INVALID_PARAMETERS_ENG_14); } if (out_buffer->size() < in_buffer.size()) { @@ -2540,14 +2525,8 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer, OEMCryptoResult sts; WithOecSessionLock("GenericDecrypt", [&] { - M_TIME( - sts = OEMCrypto_Generic_Decrypt( - oec_session_id_, reinterpret_cast(in_buffer.data()), - in_buffer.size(), reinterpret_cast(iv.data()), - oec_algorithm, - reinterpret_cast(const_cast(out_buffer->data()))), - metrics_, oemcrypto_generic_decrypt_, sts, - metrics::Pow2Bucket(in_buffer.size())); + sts = + key_session_->GenericDecrypt(in_buffer, iv, oec_algorithm, out_buffer); }); if (OEMCrypto_SUCCESS != sts) { @@ -2557,20 +2536,20 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer, switch (sts) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_NO_CONTENT_KEY: case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15. - return KEY_NOT_FOUND_4; + return CRYPTO_ERROR(KEY_NOT_FOUND_4, sts); case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - return OUTPUT_TOO_LARGE_ERROR; + return CRYPTO_ERROR(OUTPUT_TOO_LARGE_ERROR, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return UNKNOWN_ERROR; + return CRYPTO_ERROR(UNKNOWN_ERROR, sts); } } @@ -2583,61 +2562,36 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message, OEMCrypto_Algorithm oec_algorithm = OEMCrypto_HMAC_SHA256; if (!GetGenericSigningAlgorithm(algorithm, &oec_algorithm)) { - return INVALID_PARAMETERS_ENG_15; + return CdmResponseType(INVALID_PARAMETERS_ENG_15); } - OEMCryptoResult sts; - size_t length = signature->size(); - // TODO(jfore): We need to select a key with a cipher mode and algorithm // doesn't seem to fit. Is it ok to just use a default value here? // Or do we need to pass it in? CdmResponseType result = SelectKey(key_id, kCipherModeCbc); if (result != NO_ERROR) return result; - // At most two attempts. - // The first attempt may fail due to buffer too short - for (int i = 0; i < 2; ++i) { - WithOecSessionLock("GenericSign", [&] { - M_TIME( - sts = OEMCrypto_Generic_Sign( - oec_session_id_, reinterpret_cast(message.data()), - message.size(), oec_algorithm, - reinterpret_cast(const_cast(signature->data())), - &length), - metrics_, oemcrypto_generic_sign_, sts, - metrics::Pow2Bucket(message.size())); - }); - - if (OEMCrypto_SUCCESS == sts) { - // Trim signature buffer and done - signature->resize(length); - return NO_ERROR; - } - if (OEMCrypto_ERROR_SHORT_BUFFER != sts) { - break; - } - - // Retry with proper-sized return buffer - signature->resize(length); - } - - LOGE("OEMCrypto_Generic_Sign failed: status = %d", static_cast(sts)); + OEMCryptoResult sts; + WithOecSessionLock("GenericSign", [&] { + sts = key_session_->GenericSign(message, oec_algorithm, signature); + }); switch (sts) { + case OEMCrypto_SUCCESS: + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_NO_CONTENT_KEY: case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15. - return KEY_NOT_FOUND_5; + return CRYPTO_ERROR(KEY_NOT_FOUND_5, sts); case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - return OUTPUT_TOO_LARGE_ERROR; + return CRYPTO_ERROR(OUTPUT_TOO_LARGE_ERROR, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return UNKNOWN_ERROR; + return CRYPTO_ERROR(UNKNOWN_ERROR, sts); } } @@ -2649,7 +2603,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message, OEMCrypto_Algorithm oec_algorithm = OEMCrypto_HMAC_SHA256; if (!GetGenericSigningAlgorithm(algorithm, &oec_algorithm)) { - return INVALID_PARAMETERS_ENG_16; + return CdmResponseType(INVALID_PARAMETERS_ENG_16); } // TODO(jfore): We need to select a key with a cipher mode and algorithm @@ -2660,14 +2614,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message, OEMCryptoResult sts; WithOecSessionLock("GenericVerify", [&] { - M_TIME( - sts = OEMCrypto_Generic_Verify( - oec_session_id_, reinterpret_cast(message.data()), - message.size(), oec_algorithm, - reinterpret_cast(signature.data()), - signature.size()), - metrics_, oemcrypto_generic_verify_, sts, - metrics::Pow2Bucket(signature.size())); + sts = key_session_->GenericVerify(message, oec_algorithm, signature); }); if (OEMCrypto_SUCCESS != sts) { @@ -2676,26 +2623,26 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message, switch (sts) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_KEY_EXPIRED: - return NEED_KEY; + return CRYPTO_ERROR(NEED_KEY, sts); case OEMCrypto_ERROR_NO_CONTENT_KEY: case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15. - return KEY_NOT_FOUND_6; + return CRYPTO_ERROR(KEY_NOT_FOUND_6, sts); case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - return OUTPUT_TOO_LARGE_ERROR; + return CRYPTO_ERROR(OUTPUT_TOO_LARGE_ERROR, sts); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, sts); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, sts); default: - return UNKNOWN_ERROR; + return CRYPTO_ERROR(UNKNOWN_ERROR, sts); } } CdmResponseType CryptoSession::CreateUsageTableHeader( RequestedSecurityLevel requested_security_level, - CdmUsageTableHeader* usage_table_header) { + UsageTableHeader* usage_table_header) { LOGV("Creating usage table header: requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); RETURN_IF_NULL(usage_table_header, PARAMETER_NULL); @@ -2727,7 +2674,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader( switch (result) { case OEMCrypto_SUCCESS: usage_table_header->resize(usage_table_header_size); - return NO_ERROR; + return CdmResponseType(NO_ERROR); default: return MapOEMCryptoResult(result, CREATE_USAGE_TABLE_ERROR, "CreateUsageTableHeader"); @@ -2736,7 +2683,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader( CdmResponseType CryptoSession::LoadUsageTableHeader( RequestedSecurityLevel requested_security_level, - const CdmUsageTableHeader& usage_table_header) { + const UsageTableHeader& usage_table_header) { LOGV("Loading usage table header: requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); @@ -2760,24 +2707,24 @@ CdmResponseType CryptoSession::LoadUsageTableHeader( switch (result) { case OEMCrypto_SUCCESS: case OEMCrypto_WARNING_GENERATION_SKEW: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_GENERATION_SKEW: - return LOAD_USAGE_HEADER_GENERATION_SKEW; + return CRYPTO_ERROR(LOAD_USAGE_HEADER_GENERATION_SKEW, result); case OEMCrypto_ERROR_SIGNATURE_FAILURE: - return LOAD_USAGE_HEADER_SIGNATURE_FAILURE; + return CRYPTO_ERROR(LOAD_USAGE_HEADER_SIGNATURE_FAILURE, result); case OEMCrypto_ERROR_BAD_MAGIC: - return LOAD_USAGE_HEADER_BAD_MAGIC; + return CRYPTO_ERROR(LOAD_USAGE_HEADER_BAD_MAGIC, result); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, result); case OEMCrypto_ERROR_UNKNOWN_FAILURE: default: - return LOAD_USAGE_HEADER_UNKNOWN_ERROR; + return CRYPTO_ERROR(LOAD_USAGE_HEADER_UNKNOWN_ERROR, result); } } CdmResponseType CryptoSession::ShrinkUsageTableHeader( RequestedSecurityLevel requested_security_level, uint32_t new_entry_count, - CdmUsageTableHeader* usage_table_header) { + UsageTableHeader* usage_table_header) { LOGV("Shrinking usage table header: requested_security_level = %s", RequestedSecurityLevelToString(requested_security_level)); RETURN_IF_NULL(usage_table_header, PARAMETER_NULL); @@ -2806,23 +2753,23 @@ CdmResponseType CryptoSession::ShrinkUsageTableHeader( switch (result) { case OEMCrypto_SUCCESS: usage_table_header->resize(usage_table_header_len); - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_ENTRY_IN_USE: - return SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE; + return CRYPTO_ERROR(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE, result); default: return MapOEMCryptoResult(result, SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR, "ShrinkUsageTableHeader"); } } -CdmResponseType CryptoSession::CreateUsageEntry(uint32_t* entry_number) { +CdmResponseType CryptoSession::CreateUsageEntry(UsageEntryIndex* entry_index) { LOGV("Creating usage entry: id = %u", oec_session_id_); - RETURN_IF_NULL(entry_number, PARAMETER_NULL); + RETURN_IF_NULL(entry_index, PARAMETER_NULL); OEMCryptoResult result; WithOecWriteLock("CreateUsageEntry", [&] { - result = OEMCrypto_CreateNewUsageEntry(oec_session_id_, entry_number); + result = OEMCrypto_CreateNewUsageEntry(oec_session_id_, entry_index); metrics_->oemcrypto_create_new_usage_entry_.Increment(result); }); @@ -2833,26 +2780,26 @@ CdmResponseType CryptoSession::CreateUsageEntry(uint32_t* entry_number) { switch (result) { case OEMCrypto_SUCCESS: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: - return INSUFFICIENT_CRYPTO_RESOURCES; + return CRYPTO_ERROR(INSUFFICIENT_CRYPTO_RESOURCES, result); case OEMCrypto_ERROR_SESSION_LOST_STATE: - return SESSION_LOST_STATE_ERROR; + return CRYPTO_ERROR(SESSION_LOST_STATE_ERROR, result); case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - return SYSTEM_INVALIDATED_ERROR; + return CRYPTO_ERROR(SYSTEM_INVALIDATED_ERROR, result); default: - return CREATE_USAGE_ENTRY_UNKNOWN_ERROR; + return CRYPTO_ERROR(CREATE_USAGE_ENTRY_UNKNOWN_ERROR, result); } } -CdmResponseType CryptoSession::LoadUsageEntry( - uint32_t entry_number, const CdmUsageEntry& usage_entry) { +CdmResponseType CryptoSession::LoadUsageEntry(UsageEntryIndex entry_index, + const UsageEntry& usage_entry) { LOGV("Loading usage entry: id = %u", oec_session_id_); OEMCryptoResult result; WithOecWriteLock("LoadUsageEntry", [&] { result = OEMCrypto_LoadUsageEntry( - oec_session_id_, entry_number, + oec_session_id_, entry_index, reinterpret_cast(usage_entry.data()), usage_entry.size()); metrics_->oemcrypto_load_usage_entry_.Increment(result); @@ -2870,17 +2817,17 @@ CdmResponseType CryptoSession::LoadUsageEntry( switch (result) { case OEMCrypto_SUCCESS: case OEMCrypto_WARNING_GENERATION_SKEW: - return NO_ERROR; + return CdmResponseType(NO_ERROR); case OEMCrypto_ERROR_INVALID_SESSION: // This case is special, as it could imply that the provided // session ID is invalid (CDM internal bug), or that the entry // being loaded is already in use in a different session. // It is up to the caller to handle this. - return LOAD_USAGE_ENTRY_INVALID_SESSION; + return CRYPTO_ERROR(LOAD_USAGE_ENTRY_INVALID_SESSION, result); case OEMCrypto_ERROR_GENERATION_SKEW: - return LOAD_USAGE_ENTRY_GENERATION_SKEW; + return CRYPTO_ERROR(LOAD_USAGE_ENTRY_GENERATION_SKEW, result); case OEMCrypto_ERROR_SIGNATURE_FAILURE: - return LOAD_USAGE_ENTRY_SIGNATURE_FAILURE; + return CRYPTO_ERROR(LOAD_USAGE_ENTRY_SIGNATURE_FAILURE, result); default: return MapOEMCryptoResult(result, LOAD_USAGE_ENTRY_UNKNOWN_ERROR, "LoadUsageEntry"); @@ -2888,7 +2835,7 @@ CdmResponseType CryptoSession::LoadUsageEntry( } CdmResponseType CryptoSession::UpdateUsageEntry( - CdmUsageTableHeader* usage_table_header, CdmUsageEntry* usage_entry) { + UsageTableHeader* usage_table_header, UsageEntry* usage_entry) { LOGV("Updating usage entry: id = %u", oec_session_id_); RETURN_IF_NULL(usage_table_header, PARAMETER_NULL); @@ -2929,20 +2876,20 @@ CdmResponseType CryptoSession::UpdateUsageEntry( "UpdateUsageEntry"); } -CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) { +CdmResponseType CryptoSession::MoveUsageEntry(UsageEntryIndex new_entry_index) { LOGV("Moving usage entry: id = %u", oec_session_id_); OEMCryptoResult result; WithOecWriteLock("MoveUsageEntry", [&] { - result = OEMCrypto_MoveEntry(oec_session_id_, new_entry_number); + result = OEMCrypto_MoveEntry(oec_session_id_, new_entry_index); metrics_->oemcrypto_move_entry_.Increment(result); }); switch (result) { case OEMCrypto_ERROR_ENTRY_IN_USE: LOGW("OEMCrypto_MoveEntry failed: Destination index in use: index = %u", - new_entry_number); - return MOVE_USAGE_ENTRY_DESTINATION_IN_USE; + new_entry_index); + return CRYPTO_ERROR(MOVE_USAGE_ENTRY_DESTINATION_IN_USE, result); default: return MapOEMCryptoResult(result, MOVE_USAGE_ENTRY_UNKNOWN_ERROR, "MoveUsageEntry"); @@ -2965,12 +2912,6 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output, return true; } -// OEMCryptoResult OEMCrypto_DecryptCENC( -// OEMCrypto_SESSION session, -// const OEMCrypto_SampleDescription* samples, // an array of samples. -// size_t samples_length, // the number of samples. -// const OEMCrypto_CENCEncryptPatternDesc* pattern); - OEMCryptoResult CryptoSession::DecryptMultipleSamples( const std::vector& samples, CdmCipherMode cipher_mode, @@ -3293,7 +3234,7 @@ CdmResponseType CryptoSession::PrepareOtaProvisioningRequest( "PrepareOtaProvisioningRequest"); if (buffer_length == 0) { LOGE("OTA request size is zero"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } request->resize(buffer_length); uint8_t* buf = reinterpret_cast(&request->front()); diff --git a/core/src/device_files.cpp b/core/src/device_files.cpp index 22eb9eb7..c3ca252a 100644 --- a/core/src/device_files.cpp +++ b/core/src/device_files.cpp @@ -358,12 +358,56 @@ const char* DeviceFiles::ResponseTypeToString(ResponseType type) { return "IncorrectFileVersion"; case kLicenseNotPresent: return "LicenseNotFound"; + case kFileNotFoundEAcces: + return "FileNotFound_EAcces"; + case kFileNotFoundEFault: + return "FileNotFound_EFault"; + case kFileNotFoundELoop: + return "FileNotFound_ELoop"; + case kFileNotFoundENameTooLong: + return "FileNotFound_ENameTooLong"; + case kFileNotFoundENoEnt: + return "FileNotFound_ENoEnt"; + case kFileNotFoundENoMem: + return "FileNotFound_ENoMem"; + case kFileNotFoundENotDir: + return "FileNotFound_ENotDir"; + case kFileNotFoundEOverflow: + return "FileNotFound_EOverflow"; + case kFileNotFoundOther: + return "FileNotFound_Other"; case kResponseTypeBase: // Not a valid value. break; } return UnknownEnumValueToString(static_cast(type)); } +// static +DeviceFiles::ResponseType DeviceFiles::ErrnoToResponseType(int errno_value) { + switch (errno_value) { + case 0: + return kNoError; + case EACCES: + return kFileNotFoundEAcces; + case EFAULT: + return kFileNotFoundEFault; + case ELOOP: + return kFileNotFoundELoop; + case ENAMETOOLONG: + return kFileNotFoundENameTooLong; + case ENOENT: + return kFileNotFoundENoEnt; + case ENOMEM: + return kFileNotFoundENoMem; + case ENOTDIR: + return kFileNotFoundENotDir; + case EOVERFLOW: + return kFileNotFoundEOverflow; + default: + return kFileNotFoundOther; + } +} + // static std::set DeviceFiles::reserved_license_ids_; std::mutex DeviceFiles::reserved_license_ids_mutex_; @@ -649,9 +693,7 @@ bool DeviceFiles::RetrieveLegacyCertificate(std::string* certificate, const CertificateState state = RetrieveCertificate( kCertificateLegacy, certificate, private_key, serial_number, system_id); - if (state == kCertificateValid || state == kCertificateExpired) return true; - - return false; + return state == kCertificateValid || state == kCertificateExpired; } bool DeviceFiles::HasCertificate(bool atsc_mode_enabled) { @@ -838,7 +880,7 @@ bool DeviceFiles::StoreLicense(const CdmLicenseData& license_data, app_params->set_value(iter->second); } license->set_usage_entry(license_data.usage_entry); - license->set_usage_entry_number(license_data.usage_entry_number); + license->set_usage_entry_index(license_data.usage_entry_index); if (!license_data.drm_certificate.empty()) { DeviceCertificate* device_certificate = license->mutable_drm_certificate(); if (!SetDeviceCertificate(license_data.drm_certificate, @@ -929,8 +971,8 @@ bool DeviceFiles::RetrieveLicense(const std::string& key_set_id, license.app_parameters(i).value(); } license_data->usage_entry = license.usage_entry(); - license_data->usage_entry_number = - static_cast(license.usage_entry_number()); + license_data->usage_entry_index = + static_cast(license.usage_entry_index()); if (!license.has_drm_certificate()) { license_data->drm_certificate.clear(); @@ -943,6 +985,11 @@ bool DeviceFiles::RetrieveLicense(const std::string& key_set_id, &license_data->wrapped_private_key); } +DeviceFiles::ResponseType DeviceFiles::StoreAtscLicense( + const CdmKeySetId& key_set_id, const std::string& serialized_data) { + return StoreFileWithHash(key_set_id + kLicenseFileNameExt, serialized_data); +} + bool DeviceFiles::DeleteLicense(const std::string& key_set_id) { RETURN_FALSE_IF_UNINITIALIZED(); return RemoveFile(key_set_id + kLicenseFileNameExt); @@ -1010,8 +1057,8 @@ bool DeviceFiles::UnreserveLicenseId(const std::string& key_set_id) { bool DeviceFiles::StoreUsageInfo( const std::string& provider_session_token, const CdmKeyMessage& key_request, const CdmKeyResponse& key_response, const std::string& usage_info_file_name, - const std::string& key_set_id, const std::string& usage_entry, - uint32_t usage_entry_number, const std::string& drm_certificate, + const std::string& key_set_id, const UsageEntry& usage_entry, + UsageEntryIndex usage_entry_index, const std::string& drm_certificate, const CryptoWrappedKey& wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); video_widevine_client::sdk::File file; @@ -1034,7 +1081,7 @@ bool DeviceFiles::StoreUsageInfo( provider_session->set_license(key_response.data(), key_response.size()); provider_session->set_key_set_id(key_set_id.data(), key_set_id.size()); provider_session->set_usage_entry(usage_entry); - provider_session->set_usage_entry_number(usage_entry_number); + provider_session->set_usage_entry_index(usage_entry_index); if (drm_certificate.size() > 0) { uint32_t drm_certificate_id; @@ -1237,15 +1284,15 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, const std::string& provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license, - std::string* usage_entry, - uint32_t* usage_entry_number, + UsageEntry* usage_entry, + UsageEntryIndex* usage_entry_index, std::string* drm_certificate, CryptoWrappedKey* wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); RETURN_FALSE_IF_NULL(license_request); RETURN_FALSE_IF_NULL(license); RETURN_FALSE_IF_NULL(usage_entry); - RETURN_FALSE_IF_NULL(usage_entry_number); + RETURN_FALSE_IF_NULL(usage_entry_index); RETURN_FALSE_IF_NULL(drm_certificate); RETURN_FALSE_IF_NULL(wrapped_private_key); @@ -1261,8 +1308,8 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, *license_request = file.usage_info().sessions(index).license_request(); *license = file.usage_info().sessions(index).license(); *usage_entry = file.usage_info().sessions(index).usage_entry(); - *usage_entry_number = static_cast( - file.usage_info().sessions(index).usage_entry_number()); + *usage_entry_index = static_cast( + file.usage_info().sessions(index).usage_entry_index()); if (!file.usage_info().sessions(index).has_drm_certificate_id()) { drm_certificate->clear(); @@ -1287,14 +1334,14 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, bool DeviceFiles::RetrieveUsageInfoByKeySetId( const std::string& usage_info_file_name, const std::string& key_set_id, std::string* provider_session_token, CdmKeyMessage* license_request, - CdmKeyResponse* license, std::string* usage_entry, - uint32_t* usage_entry_number, std::string* drm_certificate, + CdmKeyResponse* license, UsageEntry* usage_entry, + UsageEntryIndex* usage_entry_index, std::string* drm_certificate, CryptoWrappedKey* wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); RETURN_FALSE_IF_NULL(license_request); RETURN_FALSE_IF_NULL(license); RETURN_FALSE_IF_NULL(usage_entry); - RETURN_FALSE_IF_NULL(usage_entry_number); + RETURN_FALSE_IF_NULL(usage_entry_index); RETURN_FALSE_IF_NULL(drm_certificate); RETURN_FALSE_IF_NULL(wrapped_private_key); @@ -1311,8 +1358,8 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId( *license_request = file.usage_info().sessions(index).license_request(); *license = file.usage_info().sessions(index).license(); *usage_entry = file.usage_info().sessions(index).usage_entry(); - *usage_entry_number = static_cast( - file.usage_info().sessions(index).usage_entry_number()); + *usage_entry_index = static_cast( + file.usage_info().sessions(index).usage_entry_index()); if (!file.usage_info().sessions(index).has_drm_certificate_id()) { drm_certificate->clear(); @@ -1356,7 +1403,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name, provider_session->set_key_set_id(usage_data[i].key_set_id.data(), usage_data[i].key_set_id.size()); provider_session->set_usage_entry(usage_data[i].usage_entry); - provider_session->set_usage_entry_number(usage_data[i].usage_entry_number); + provider_session->set_usage_entry_index(usage_data[i].usage_entry_index); if (usage_data[i].drm_certificate.size() > 0) { uint32_t drm_certificate_id; @@ -1415,7 +1462,7 @@ bool DeviceFiles::UpdateUsageInfo(const std::string& usage_info_file_name, session->set_license_request(usage_data.license_request); session->set_license(usage_data.license); session->set_usage_entry(usage_data.usage_entry); - session->set_usage_entry_number(usage_data.usage_entry_number); + session->set_usage_entry_index(usage_data.usage_entry_index); if (usage_data.drm_certificate.size() > 0) { uint32_t drm_certificate_id; if (!FindOrInsertUsageCertificate(usage_data.drm_certificate, @@ -1458,8 +1505,8 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, (*usage_data)[i].license = file.usage_info().sessions(i).license(); (*usage_data)[i].key_set_id = file.usage_info().sessions(i).key_set_id(); (*usage_data)[i].usage_entry = file.usage_info().sessions(i).usage_entry(); - (*usage_data)[i].usage_entry_number = static_cast( - file.usage_info().sessions(i).usage_entry_number()); + (*usage_data)[i].usage_entry_index = static_cast( + file.usage_info().sessions(i).usage_entry_index()); if (!file.usage_info().sessions(i).has_drm_certificate_id()) { (*usage_data)[i].drm_certificate.clear(); @@ -1500,8 +1547,8 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, usage_data->license = file.usage_info().sessions(index).license(); usage_data->key_set_id = file.usage_info().sessions(index).key_set_id(); usage_data->usage_entry = file.usage_info().sessions(index).usage_entry(); - usage_data->usage_entry_number = static_cast( - file.usage_info().sessions(index).usage_entry_number()); + usage_data->usage_entry_index = static_cast( + file.usage_info().sessions(index).usage_entry_index()); if (!file.usage_info().sessions(index).has_drm_certificate_id()) { usage_data->drm_certificate.clear(); @@ -1639,8 +1686,8 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) { } bool DeviceFiles::StoreUsageTableInfo( - const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info) { + const UsageTableHeader& table_header, + const std::vector& entry_info_list) { RETURN_FALSE_IF_UNINITIALIZED(); // Fill in file information @@ -1650,25 +1697,24 @@ bool DeviceFiles::StoreUsageTableInfo( file.set_version(video_widevine_client::sdk::File::VERSION_1); UsageTableInfo* usage_table_info = file.mutable_usage_table_info(); - usage_table_info->set_usage_table_header(usage_table_header); - for (size_t i = 0; i < usage_entry_info.size(); ++i) { + usage_table_info->set_table_header(table_header); + for (size_t i = 0; i < entry_info_list.size(); ++i) { UsageTableInfo_UsageEntryInfo* info = - usage_table_info->add_usage_entry_info(); - info->set_key_set_id(usage_entry_info[i].key_set_id); - switch (usage_entry_info[i].storage_type) { + usage_table_info->add_entry_info_list(); + info->set_key_set_id(entry_info_list[i].key_set_id); + switch (entry_info_list[i].storage_type) { case kStorageLicense: info->set_storage( UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE); - info->set_last_use_time(usage_entry_info[i].last_use_time); + info->set_last_use_time(entry_info_list[i].last_use_time); info->set_offline_license_expiry_time( - usage_entry_info[i].offline_license_expiry_time); + entry_info_list[i].offline_license_expiry_time); break; case kStorageUsageInfo: info->set_storage( UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO); - info->set_usage_info_file_name( - usage_entry_info[i].usage_info_file_name); - info->set_last_use_time(usage_entry_info[i].last_use_time); + info->set_usage_info_file_name(entry_info_list[i].usage_info_file_name); + info->set_last_use_time(entry_info_list[i].last_use_time); break; case kStorageTypeUnknown: default: @@ -1687,11 +1733,11 @@ bool DeviceFiles::StoreUsageTableInfo( } bool DeviceFiles::RetrieveUsageTableInfo( - CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info, bool* lru_upgrade) { + UsageTableHeader* table_header, + std::vector* entry_info_list, bool* lru_upgrade) { RETURN_FALSE_IF_UNINITIALIZED(); - RETURN_FALSE_IF_NULL(usage_table_header); - RETURN_FALSE_IF_NULL(usage_entry_info); + RETURN_FALSE_IF_NULL(table_header); + RETURN_FALSE_IF_NULL(entry_info_list); RETURN_FALSE_IF_NULL(lru_upgrade); video_widevine_client::sdk::File file; @@ -1723,28 +1769,28 @@ bool DeviceFiles::RetrieveUsageTableInfo( *lru_upgrade = !usage_table_info.use_lru(); - *usage_table_header = usage_table_info.usage_table_header(); - usage_entry_info->resize(usage_table_info.usage_entry_info_size()); - for (int i = 0; i < usage_table_info.usage_entry_info_size(); ++i) { + *table_header = usage_table_info.table_header(); + entry_info_list->resize(usage_table_info.entry_info_list_size()); + for (int i = 0; i < usage_table_info.entry_info_list_size(); ++i) { const UsageTableInfo_UsageEntryInfo& info = - usage_table_info.usage_entry_info(i); - (*usage_entry_info)[i].key_set_id = info.key_set_id(); + usage_table_info.entry_info_list(i); + (*entry_info_list)[i].key_set_id = info.key_set_id(); switch (info.storage()) { case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE: - (*usage_entry_info)[i].storage_type = kStorageLicense; - (*usage_entry_info)[i].last_use_time = info.last_use_time(); - (*usage_entry_info)[i].offline_license_expiry_time = + (*entry_info_list)[i].storage_type = kStorageLicense; + (*entry_info_list)[i].last_use_time = info.last_use_time(); + (*entry_info_list)[i].offline_license_expiry_time = info.offline_license_expiry_time(); break; case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO: - (*usage_entry_info)[i].storage_type = kStorageUsageInfo; - (*usage_entry_info)[i].usage_info_file_name = + (*entry_info_list)[i].storage_type = kStorageUsageInfo; + (*entry_info_list)[i].usage_info_file_name = info.usage_info_file_name(); - (*usage_entry_info)[i].last_use_time = info.last_use_time(); + (*entry_info_list)[i].last_use_time = info.last_use_time(); break; case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN: default: - (*usage_entry_info)[i].storage_type = kStorageTypeUnknown; + (*entry_info_list)[i].storage_type = kStorageTypeUnknown; break; } } @@ -1995,9 +2041,12 @@ DeviceFiles::ResponseType DeviceFiles::RetrieveHashedFile( path += name; - if (!file_system_->Exists(path)) { - LOGW("File does not exist: path = %s", path.c_str()); - return kFileNotFound; + int errno_value = 0; + if (!file_system_->Exists(path, &errno_value)) { + const ResponseType result = ErrnoToResponseType(errno_value); + LOGW("File does not exist: path = %s, error = %s", path.c_str(), + ResponseTypeToString(result)); + return result; } const ssize_t file_size = file_system_->FileSize(path); diff --git a/core/src/device_files.proto b/core/src/device_files.proto index b2e13f65..7b4a02ef 100644 --- a/core/src/device_files.proto +++ b/core/src/device_files.proto @@ -75,7 +75,7 @@ message License { // ignored if there is no grace period. optional int64 grace_period_end_time = 11 [default = 0]; optional bytes usage_entry = 12; - optional int64 usage_entry_number = 13; + optional int64 usage_entry_index = 13; optional DeviceCertificate drm_certificate = 14; } @@ -88,7 +88,7 @@ message UsageInfo { optional bytes license = 3; optional bytes key_set_id = 4; optional bytes usage_entry = 5; - optional int64 usage_entry_number = 6; + optional int64 usage_entry_index = 6; // If not present, use the legacy DRM certificate rather than // one in DrmDeviceCertificate optional uint32 drm_certificate_id = 7; @@ -131,8 +131,8 @@ message UsageTableInfo { optional int64 offline_license_expiry_time = 5 [default = 0]; } - optional bytes usage_table_header = 1; - repeated UsageEntryInfo usage_entry_info = 2; + optional bytes table_header = 1; + repeated UsageEntryInfo entry_info_list = 2; optional bool use_lru = 3 [default = false]; } diff --git a/core/src/entitlement_key_session.cpp b/core/src/entitlement_key_session.cpp index 06ffd1cb..b52ee22a 100644 --- a/core/src/entitlement_key_session.cpp +++ b/core/src/entitlement_key_session.cpp @@ -10,12 +10,13 @@ namespace wvcdm { namespace { -constexpr int kInvalidKeySessionId = 0; +constexpr uint32_t kInvalidKeySessionId = 0xFFFFFFFF; } // namespace -EntitlementKeySession::EntitlementKeySession(CryptoSessionId oec_session_id, - metrics::CryptoMetrics* metrics) - : ContentKeySession(oec_session_id, metrics), +EntitlementKeySession::EntitlementKeySession( + RequestedSecurityLevel security_level, CryptoSessionId oec_session_id, + metrics::CryptoMetrics* metrics) + : ContentKeySession(security_level, oec_session_id, metrics), key_session_id_(kInvalidKeySessionId) {} EntitlementKeySession::~EntitlementKeySession() { @@ -109,27 +110,7 @@ OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id, key_id; } - M_TIME(result = OEMCrypto_SelectKey( - key_session_id_, reinterpret_cast(key_id.data()), - key_id.size(), ToOEMCryptoCipherMode(cipher_mode)), - metrics_, oemcrypto_select_key_, result); - return result; -} - -OEMCryptoResult EntitlementKeySession::Decrypt( - const OEMCrypto_SampleDescription* samples, size_t samples_length, - const OEMCrypto_CENCEncryptPatternDesc& pattern) { - size_t total_size = 0; - for (size_t i = 0; i < samples_length; ++i) { - total_size += samples[i].buffers.input_data_length; - } - - OEMCryptoResult sts; - M_TIME(sts = OEMCrypto_DecryptCENC(key_session_id_, samples, samples_length, - &pattern), - metrics_, oemcrypto_decrypt_cenc_, sts, - metrics::Pow2Bucket(total_size)); - return sts; + return GetKeyHandle(key_session_id_, key_id, cipher_mode); } OEMCrypto_EntitledContentKeyObject EntitlementKeySession::MakeOecEntitledKey( diff --git a/core/src/initialization_data.cpp b/core/src/initialization_data.cpp index e819aef7..373e5a96 100644 --- a/core/src/initialization_data.cpp +++ b/core/src/initialization_data.cpp @@ -43,11 +43,8 @@ namespace wvcdm { // Protobuf generated classes. using video_widevine::WidevinePsshData; -using video_widevine::WidevinePsshData_Algorithm; using video_widevine::WidevinePsshData_Algorithm_AESCTR; -using video_widevine::WidevinePsshData_Type; using video_widevine::WidevinePsshData_Type_ENTITLED_KEY; -using video_widevine::WidevinePsshData_Type_SINGLE; InitializationData::InitializationData(const std::string& type, const CdmInitData& data, @@ -376,7 +373,7 @@ bool InitializationData::ExtractHlsAttributes(const std::string& attribute_list, std::vector versions = ExtractKeyFormatVersions(value); bool supported = false; for (size_t i = 0; i < versions.size(); ++i) { - if (versions[i].compare(HLS_KEYFORMAT_VERSION_VALUE_1) == 0) { + if (versions[i] == HLS_KEYFORMAT_VERSION_VALUE_1) { supported = true; break; } @@ -393,11 +390,11 @@ bool InitializationData::ExtractHlsAttributes(const std::string& attribute_list, return false; } - if (value.compare(HLS_METHOD_AES_128) == 0) { + if (value == HLS_METHOD_AES_128) { *method = kHlsMethodAes128; - } else if (value.compare(HLS_METHOD_SAMPLE_AES) == 0) { + } else if (value == HLS_METHOD_SAMPLE_AES) { *method = kHlsMethodSampleAes; - } else if (value.compare(HLS_METHOD_NONE) == 0) { + } else if (value == HLS_METHOD_NONE) { *method = kHlsMethodNone; } else { LOGV("HLS method unrecognized: value = %s", value.c_str()); @@ -734,7 +731,8 @@ void InitializationData::DumpToLogs() const { } for (int i = 0; i < pssh.entitled_keys_size(); i++) { - video_widevine::WidevinePsshData_EntitledKey key = pssh.entitled_keys(i); + const video_widevine::WidevinePsshData_EntitledKey& key = + pssh.entitled_keys(i); LOGD("InitData: entitlement_key_id %d: %s -> %s", i, wvutil::b2a_hex(key.entitlement_key_id()).c_str(), wvutil::b2a_hex(key.key_id()).c_str()); diff --git a/core/src/license.cpp b/core/src/license.cpp index 2f99a056..6f44a625 100644 --- a/core/src/license.cpp +++ b/core/src/license.cpp @@ -13,6 +13,7 @@ #include "crypto_key.h" #include "crypto_session.h" #include "device_files.h" +#include "license_protocol_conversions.h" #include "log.h" #include "platform.h" #include "policy_engine.h" @@ -38,6 +39,7 @@ constexpr size_t kLicenseMacKeySize = wvcdm::MAC_KEY_SIZE * 2; namespace wvcdm { // Protobuf generated classes. using video_widevine::EncryptedClientIdentification; +using video_widevine::HashAlgorithmProto; using video_widevine::License; using video_widevine::License_KeyContainer; using video_widevine::LicenseError; @@ -199,7 +201,6 @@ CdmLicense::CdmLicense(const CdmSessionId& session_id) initialized_(false), renew_with_client_id_(false), is_offline_(false), - supports_core_messages_(true), use_privacy_mode_(false), clock_(new wvutil::Clock()), license_key_type_(kLicenseKeyTypeContent) {} @@ -211,7 +212,6 @@ CdmLicense::CdmLicense(const CdmSessionId& session_id, wvutil::Clock* clock) initialized_(false), renew_with_client_id_(false), is_offline_(false), - supports_core_messages_(true), use_privacy_mode_(false), license_key_type_(kLicenseKeyTypeContent) { clock_.reset(clock); @@ -263,7 +263,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest( CdmKeyMessage* signed_request, std::string* server_url) { if (!initialized_) { LOGE("CdmLicense not initialized"); - return LICENSE_PARSER_NOT_INITIALIZED_4; + return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_4); } client_token_ = client_token; if (init_data.IsEmpty() && stored_init_data_) { @@ -275,19 +275,19 @@ CdmResponseType CdmLicense::PrepareKeyRequest( wrapped_keys_ = init_data.ExtractWrappedKeys(); if (!init_data.is_supported()) { LOGE("Unsupported init data type: type = %s", init_data.type().c_str()); - return INVALID_PARAMETERS_LIC_3; + return CdmResponseType(INVALID_PARAMETERS_LIC_3); } if (init_data.IsEmpty()) { LOGE("Init data is empty"); - return INVALID_PARAMETERS_LIC_4; + return CdmResponseType(INVALID_PARAMETERS_LIC_4); } if (signed_request == nullptr) { LOGE("Output parameter |signed_request| not provided"); - return INVALID_PARAMETERS_LIC_6; + return CdmResponseType(INVALID_PARAMETERS_LIC_6); } if (server_url == nullptr) { LOGE("Output parameter |server_url| not provided"); - return INVALID_PARAMETERS_LIC_7; + return CdmResponseType(INVALID_PARAMETERS_LIC_7); } // If privacy mode and no service certificate, depending on platform @@ -295,17 +295,18 @@ CdmResponseType CdmLicense::PrepareKeyRequest( if (use_privacy_mode_ && !service_certificate_.has_certificate()) { if (!Properties::allow_service_certificate_requests()) { LOGE("Privacy mode failure: No service certificate"); - return PRIVACY_MODE_ERROR_1; + return CdmResponseType(PRIVACY_MODE_ERROR_1); } stored_init_data_.reset(new InitializationData(init_data)); if (!ServiceCertificate::GetRequest(signed_request)) { LOGE("Failed to prepare service certificated request"); - return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR; + return CdmResponseType( + LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR); } - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } const std::string& request_id = crypto_session_->request_id(); @@ -327,14 +328,14 @@ CdmResponseType CdmLicense::PrepareKeyRequest( // of the license response. status = crypto_session_->GenerateNonce(&license_nonce_); - switch (status) { + switch (status.code()) { case NO_ERROR: break; case SESSION_LOST_STATE_ERROR: case SYSTEM_INVALIDATED_ERROR: return status; default: - return LICENSE_REQUEST_NONCE_GENERATION_ERROR; + return CdmResponseType(LICENSE_REQUEST_NONCE_GENERATION_ERROR); } license_request.set_key_control_nonce(license_nonce_); license_request.set_protocol_version(video_widevine::VERSION_2_1); @@ -349,8 +350,11 @@ CdmResponseType CdmLicense::PrepareKeyRequest( // signature. std::string core_message; std::string license_request_signature; + bool should_specify_algorithm; + OEMCrypto_SignatureHashAlgorithm oec_algorithm = OEMCrypto_SHA1; status = crypto_session_->PrepareAndSignLicenseRequest( - serialized_license_req, &core_message, &license_request_signature); + serialized_license_req, &core_message, &license_request_signature, + should_specify_algorithm, oec_algorithm); if (status != NO_ERROR) { signed_request->clear(); @@ -360,7 +364,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest( if (license_request_signature.empty()) { LOGE("License request signature is empty"); signed_request->clear(); - return EMPTY_LICENSE_REQUEST; + return CdmResponseType(EMPTY_LICENSE_REQUEST); } // Put serialized license request and signature together @@ -368,14 +372,20 @@ CdmResponseType CdmLicense::PrepareKeyRequest( signed_message.set_type(SignedMessage::LICENSE_REQUEST); signed_message.set_signature(license_request_signature); signed_message.set_msg(serialized_license_req); - if (core_message.size() > 0) { - signed_message.set_oemcrypto_core_message(core_message); + signed_message.set_oemcrypto_core_message(core_message); + if (should_specify_algorithm) { + HashAlgorithmProto proto_algorithm = + HashAlgorithmProto::HASH_ALGORITHM_UNSPECIFIED; + if (!OecAlgorithmToProtoAlgorithm(oec_algorithm, proto_algorithm)) { + return CdmResponseType(UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1); + } + signed_message.set_hash_algorithm(proto_algorithm); } signed_message.SerializeToString(signed_request); *server_url = server_url_; - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } // TODO(b/166007195): Remove this. @@ -383,9 +393,9 @@ CdmResponseType CdmLicense::PrepareKeyUpdateReload(CdmSession* cdm_session) { uint32_t api_version = 0; if (!crypto_session_->GetApiVersion(&api_version)) { LOGW("Unknown API Version"); - api_version = 15; + api_version = 16; } - if (api_version != 16) return NO_ERROR; + if (api_version != 16) return CdmResponseType(NO_ERROR); // To work around b/166010609, we ask OEMCrypto to prepare an unused renewal // request. This lets the ODK library update its clock saying when the renewal // was signed. @@ -403,26 +413,26 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( std::string* server_url) { if (!initialized_) { LOGE("CdmLicense not initialized"); - return LICENSE_PARSER_NOT_INITIALIZED_1; + return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_1); } if (signed_request == nullptr) { LOGE("Output parameter |signed_request| not provided"); - return INVALID_PARAMETERS_LIC_1; + return CdmResponseType(INVALID_PARAMETERS_LIC_1); } if (server_url == nullptr) { LOGE("Output parameter |server_url| not provided"); - return INVALID_PARAMETERS_LIC_2; + return CdmResponseType(INVALID_PARAMETERS_LIC_2); } if (is_renewal && !policy_engine_->CanRenew()) { LOGE("License renewal prohibited"); - return LICENSE_RENEWAL_PROHIBITED; + return CdmResponseType(LICENSE_RENEWAL_PROHIBITED); } if (renew_with_client_id_) { if (use_privacy_mode_ && !service_certificate_.has_certificate()) { LOGE("Privacy mode failure: No service certificate"); - return PRIVACY_MODE_ERROR_2; + return CdmResponseType(PRIVACY_MODE_ERROR_2); } } @@ -456,7 +466,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( } // TODO(rfrias): Refactor to avoid needing to call CdmSession - if (cdm_session && cdm_session->supports_usage_info()) { + if (cdm_session && cdm_session->SupportsUsageTable()) { const CdmResponseType status = cdm_session->UpdateUsageEntryInformation(); if (NO_ERROR != status) return status; } @@ -469,7 +479,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( if (NO_ERROR == status) current_license->set_session_usage_table_entry(usage_report); else - return GENERATE_USAGE_REPORT_ERROR; + return CdmResponseType(GENERATE_USAGE_REPORT_ERROR); } } @@ -484,27 +494,6 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( current_license->set_seconds_since_last_played(seconds_since_last_played); } - uint32_t api_version = 0; - if (!crypto_session_->GetApiVersion(&api_version)) { - LOGW("Unknown API Version"); - api_version = 15; - } - if (api_version < 16) { - // For a pre-v16 license, get/set the nonce. This value will be reflected - // in the Key Control Block of the license response. - const CdmResponseType status = - crypto_session_->GenerateNonce(&license_nonce_); - switch (status) { - case NO_ERROR: - break; - case SESSION_LOST_STATE_ERROR: - case SYSTEM_INVALIDATED_ERROR: - return status; - default: - return LICENSE_RENEWAL_NONCE_GENERATION_ERROR; - } - } - license_request.set_key_control_nonce(license_nonce_); license_request.set_protocol_version(video_widevine::VERSION_2_1); // License request is complete. Serialize it. @@ -520,7 +509,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( if (license_request_signature.empty()) { LOGE("License request signature is empty"); - return EMPTY_LICENSE_RENEWAL; + return CdmResponseType(EMPTY_LICENSE_RENEWAL); } // Put serialize license request and signature together @@ -528,35 +517,31 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( signed_message.set_type(SignedMessage::LICENSE_REQUEST); signed_message.set_signature(license_request_signature); signed_message.set_msg(serialized_license_req); - if (supports_core_messages()) { - // Only include the |core_message| in renewal requests if it is - // already known that the license is v16. - signed_message.set_oemcrypto_core_message(core_message); - } + signed_message.set_oemcrypto_core_message(core_message); signed_message.SerializeToString(signed_request); *server_url = server_url_; - return KEY_MESSAGE; + return CdmResponseType(KEY_MESSAGE); } CdmResponseType CdmLicense::HandleKeyResponse( bool is_restore, const CdmKeyResponse& license_response) { if (!initialized_) { LOGE("CdmLicense not initialized"); - return LICENSE_PARSER_NOT_INITIALIZED_2; + return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_2); } // Clear the latest service version when we receive a new response. latest_service_version_.Clear(); if (license_response.empty()) { LOGE("License response is empty"); - return EMPTY_LICENSE_RESPONSE_1; + return CdmResponseType(EMPTY_LICENSE_RESPONSE_1); } SignedMessage signed_response; if (!signed_response.ParseFromString(license_response)) { LOGE("Unable to parse signed license response"); - return INVALID_LICENSE_RESPONSE; + return CdmResponseType(INVALID_LICENSE_RESPONSE); } latest_service_version_ = signed_response.service_version_info(); @@ -569,7 +554,7 @@ CdmResponseType CdmLicense::HandleKeyResponse( if (status != NO_ERROR) return status; status = service_certificate_.Init(signed_certificate); - return (status == NO_ERROR) ? NEED_KEY : status; + return (status == NO_ERROR) ? CdmResponseType(NEED_KEY) : status; } if (signed_response.type() == SignedMessage::ERROR_RESPONSE) @@ -578,39 +563,27 @@ CdmResponseType CdmLicense::HandleKeyResponse( if (signed_response.type() != SignedMessage::LICENSE) { LOGE("Unrecognized signed message type: type = %d", static_cast(signed_response.type())); - return INVALID_LICENSE_TYPE; + return CdmResponseType(INVALID_LICENSE_TYPE); } if (!signed_response.has_signature()) { LOGE("License response is not signed"); - return LICENSE_RESPONSE_NOT_SIGNED; - } - - // Check that the server returned a |core_message|. If missing, then - // the server is assumed to operate as V15. This will imply that the - // |signature| field in the response does not include a core message - // either. - if (!signed_response.has_oemcrypto_core_message() || - signed_response.oemcrypto_core_message().empty()) { - supports_core_messages_ = false; + return CdmResponseType(LICENSE_RESPONSE_NOT_SIGNED); } const std::string& signed_message = signed_response.msg(); - const std::string core_message = - signed_response.has_oemcrypto_core_message() - ? signed_response.oemcrypto_core_message() - : std::string(); + const std::string& core_message = signed_response.oemcrypto_core_message(); const std::string& signature = signed_response.signature(); License license; if (!license.ParseFromString(signed_message)) { LOGE("Unable to parse license response"); - return LICENSE_RESPONSE_PARSE_ERROR_1; + return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_1); } if (!signed_response.has_session_key()) { LOGE("Signed response has no session keys present"); - return SESSION_KEYS_NOT_FOUND; + return CdmResponseType(SESSION_KEYS_NOT_FOUND); } CdmResponseType status = crypto_session_->GenerateDerivedKeys( key_request_, signed_response.session_key()); @@ -631,14 +604,14 @@ CdmResponseType CdmLicense::HandleKeyResponse( } } if (license.policy().can_renew() || - (mac_key_iv.size() != 0 || mac_keys.size() != 0)) { + (!mac_key_iv.empty() || !mac_keys.empty())) { if (mac_key_iv.size() != KEY_IV_SIZE || mac_keys.size() != kLicenseMacKeySize) { LOGE( "MAC key/IV size error: expected = %zu/%zu, " "actual = %zu/%zu (key/iv)", kLicenseMacKeySize, KEY_IV_SIZE, mac_keys.size(), mac_key_iv.size()); - return KEY_SIZE_ERROR_1; + return CdmResponseType(KEY_SIZE_ERROR_1); } } @@ -655,7 +628,7 @@ CdmResponseType CdmLicense::HandleKeyResponse( } if (key_array.empty()) { LOGE("No content keys"); - return NO_CONTENT_KEY; + return CdmResponseType(NO_CONTENT_KEY); } license_key_type_ = key_type; @@ -686,15 +659,14 @@ CdmResponseType CdmLicense::HandleKeyResponse( crypto_session_->UseSecondaryKey(signed_response.using_secondary_key()); if (status != NO_ERROR) return status; - CdmResponseType resp = NO_CONTENT_KEY; + CdmResponseType resp(NO_CONTENT_KEY); if (kLicenseKeyTypeEntitlement == key_type) { - resp = HandleEntitlementKeyResponse(is_restore, signed_message, - core_message, signature, mac_key_iv, - mac_keys, key_array, license); + resp = + HandleEntitlementKeyResponse(is_restore, signed_message, core_message, + signature, key_array, license); } else if (kLicenseKeyTypeContent == key_type) { resp = HandleContentKeyResponse(is_restore, signed_message, core_message, - signature, mac_key_iv, mac_keys, key_array, - license); + signature, key_array, license); } return resp; } @@ -703,17 +675,17 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( bool is_renewal, bool is_restore, const CdmKeyResponse& license_response) { if (!initialized_) { LOGE("CdmLicense not initialized"); - return LICENSE_PARSER_NOT_INITIALIZED_3; + return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_3); } if (license_response.empty()) { LOGE("License response is empty"); - return EMPTY_LICENSE_RESPONSE_2; + return CdmResponseType(EMPTY_LICENSE_RESPONSE_2); } SignedMessage signed_response; if (!signed_response.ParseFromString(license_response)) { LOGE("Unable to parse signed message"); - return LICENSE_RESPONSE_PARSE_ERROR_2; + return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_2); } switch (signed_response.type()) { @@ -724,42 +696,32 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( default: LOGE("Unrecognized signed message type: type = %d", static_cast(signed_response.type())); - return INVALID_LICENSE_TYPE; + return CdmResponseType(INVALID_LICENSE_TYPE); } - // At this point of the license life-cycle (handling a renewal), we should - // already know if the license is v15 or not. If license is v16, then a - // renewal should have a |core_message| present; otherwise there might have - // been some tampering with the request or response. On the other hand, a - // release is processed without loading the license, so OEMCrypto does not - // know if it is v15 or v16, and will not add a core message. - if (is_renewal && supports_core_messages() && - (!signed_response.has_oemcrypto_core_message() || - signed_response.oemcrypto_core_message().empty())) { - LOGE("Renewal response is missing |core_message| field"); - return CORE_MESSAGE_NOT_FOUND; - } - - if (!signed_response.has_signature()) { - LOGE("Update key response is missing signature"); - return SIGNATURE_NOT_FOUND; - } const std::string& signed_message = signed_response.msg(); - const std::string core_message = - signed_response.has_oemcrypto_core_message() - ? signed_response.oemcrypto_core_message() - : std::string(); + const std::string& core_message = signed_response.oemcrypto_core_message(); const std::string& signature = signed_response.signature(); + if (is_renewal && core_message.empty()) { + LOGE("Renewal response is missing |core_message| field"); + return CdmResponseType(CORE_MESSAGE_NOT_FOUND); + } + + if (signature.empty()) { + LOGE("Update key response is missing signature"); + return CdmResponseType(SIGNATURE_NOT_FOUND); + } + License license; if (!license.ParseFromString(signed_message)) { LOGE("Unable to parse license from signed message"); - return LICENSE_RESPONSE_PARSE_ERROR_3; + return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_3); } if (!license.has_id()) { LOGE("License ID not present"); - return LICENSE_ID_NOT_FOUND; + return CdmResponseType(LICENSE_ID_NOT_FOUND); } if (license.policy().has_always_include_client_id()) { @@ -767,9 +729,10 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( } if (!is_renewal) { - if (!license.id().has_provider_session_token()) return KEY_ADDED; + if (!license.id().has_provider_session_token()) + return CdmResponseType(KEY_ADDED); provider_session_token_ = license.id().provider_session_token(); - return KEY_ADDED; + return CdmResponseType(KEY_ADDED); } if (license.policy().has_renewal_server_url() && @@ -777,19 +740,13 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse( server_url_ = license.policy().renewal_server_url(); } - CdmResponseType status; // If the field is not set, it will default to false. - status = + CdmResponseType status = crypto_session_->UseSecondaryKey(signed_response.using_secondary_key()); if (status != NO_ERROR) return status; - if (supports_core_messages()) { - status = - crypto_session_->LoadRenewal(signed_message, core_message, signature); - } else { - std::vector key_array = ExtractContentKeys(license); - status = crypto_session_->RefreshKeys(signed_message, signature, key_array); - } + status = + crypto_session_->LoadRenewal(signed_message, core_message, signature); if (status == KEY_ADDED) { policy_engine_->UpdateLicense(license, is_restore); @@ -811,12 +768,12 @@ CdmResponseType CdmLicense::RestoreOfflineLicense( CdmSession* cdm_session) { if (license_request.empty()) { LOGE("License request is empty"); - return EMPTY_LICENSE_REQUEST_2; + return CdmResponseType(EMPTY_LICENSE_REQUEST_2); } if (license_response.empty()) { LOGE("License response is empty"); - return EMPTY_LICENSE_RESPONSE_3; + return CdmResponseType(EMPTY_LICENSE_RESPONSE_3); } client_token_ = client_token; @@ -824,21 +781,14 @@ CdmResponseType CdmLicense::RestoreOfflineLicense( SignedMessage signed_request; if (!signed_request.ParseFromString(license_request)) { LOGE("Failed to parse license request"); - return PARSE_REQUEST_ERROR_1; + return CdmResponseType(PARSE_REQUEST_ERROR_1); } if (signed_request.type() != SignedMessage::LICENSE_REQUEST) { LOGE("Unexpected license request type: expected = %d, actual = %d", static_cast(SignedMessage::LICENSE_REQUEST), static_cast(signed_request.type())); - return INVALID_LICENSE_REQUEST_TYPE_1; - } - - if (!signed_request.has_oemcrypto_core_message() || - signed_request.oemcrypto_core_message().empty()) { - // Pre V16 license did not include |core_message| components. - // The license response is checked by HandleKeyResponse(). - supports_core_messages_ = false; + return CdmResponseType(INVALID_LICENSE_REQUEST_TYPE_1); } key_request_ = signed_request.msg(); @@ -861,7 +811,7 @@ CdmResponseType CdmLicense::RestoreOfflineLicense( } if (!provider_session_token_.empty()) { - if (cdm_session && cdm_session->supports_usage_info()) { + if (cdm_session && cdm_session->SupportsUsageTable()) { const CdmResponseType status = cdm_session->UpdateUsageEntryInformation(); if (NO_ERROR != status) return sts; } @@ -897,7 +847,7 @@ CdmResponseType CdmLicense::RestoreOfflineLicense( policy_engine_->RestorePlaybackTimes(playback_start_time, last_playback_time, grace_period_end_time); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmLicense::RestoreLicenseForRelease( @@ -905,12 +855,12 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease( const CdmKeyResponse& license_response) { if (license_request.empty()) { LOGE("License request is empty"); - return EMPTY_LICENSE_REQUEST_3; + return CdmResponseType(EMPTY_LICENSE_REQUEST_3); } if (license_response.empty()) { LOGE("License response is empty"); - return EMPTY_LICENSE_RESPONSE_4; + return CdmResponseType(EMPTY_LICENSE_RESPONSE_4); } client_token_ = client_token; @@ -918,19 +868,14 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease( SignedMessage signed_request; if (!signed_request.ParseFromString(license_request)) { LOGE("Failed to parse signed license request"); - return PARSE_REQUEST_ERROR_2; + return CdmResponseType(PARSE_REQUEST_ERROR_2); } if (signed_request.type() != SignedMessage::LICENSE_REQUEST) { LOGE("Unexpected signed license request type: expected = %d, actual = %d", static_cast(SignedMessage::LICENSE_REQUEST), static_cast(signed_request.type())); - return INVALID_LICENSE_REQUEST_TYPE_2; - } - - if (!signed_request.has_oemcrypto_core_message()) { - // Pre V16 license did not include |core_message| components. - supports_core_messages_ = false; + return CdmResponseType(INVALID_LICENSE_REQUEST_TYPE_2); } key_request_ = signed_request.msg(); @@ -938,33 +883,30 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease( SignedMessage signed_response; if (!signed_response.ParseFromString(license_response)) { LOGE("Failed to parse signed license response"); - return LICENSE_RESPONSE_PARSE_ERROR_4; + return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_4); } if (SignedMessage::LICENSE != signed_response.type()) { LOGE("Unexpected signed license response type: expected = %d, actual = %d", static_cast(SignedMessage::LICENSE), static_cast(signed_response.type())); - return INVALID_LICENSE_TYPE_2; + return CdmResponseType(INVALID_LICENSE_TYPE_2); } if (!signed_response.has_signature()) { LOGE("License response is not signed"); - return SIGNATURE_NOT_FOUND_2; + return CdmResponseType(SIGNATURE_NOT_FOUND_2); } - if (!signed_response.has_oemcrypto_core_message() || - signed_response.oemcrypto_core_message().empty()) { - // Possible that the request contains a |core_message|, but the - // response does not. This would occur if the licensing server - // is v15. - supports_core_messages_ = false; + if (!signed_response.has_oemcrypto_core_message()) { + LOGE("License response is missing core message"); + return CdmResponseType(CORE_MESSAGE_NOT_FOUND); } License license; if (!license.ParseFromString(signed_response.msg())) { LOGE("Failed to parse license response"); - return LICENSE_RESPONSE_PARSE_ERROR_5; + return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_5); } if (license.has_provider_client_token()) @@ -978,12 +920,12 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease( if (!signed_response.has_session_key()) { LOGE("No session keys present"); - return SESSION_KEYS_NOT_FOUND_2; + return CdmResponseType(SESSION_KEYS_NOT_FOUND_2); } if (!license.id().has_provider_session_token()) { CdmResponseType result = HandleKeyResponse(false, license_response); - return result == KEY_ADDED ? NO_ERROR : result; + return result == KEY_ADDED ? CdmResponseType(NO_ERROR) : result; } if (license.policy().has_renewal_server_url()) @@ -991,8 +933,8 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease( // If the policy engine already has keys, they will now expire. // If the policy engine does not already have keys, this will not add any. - policy_engine_->SetLicenseForRelease(license, supports_core_messages()); - return NO_ERROR; + policy_engine_->SetLicenseForRelease(license); + return CdmResponseType(NO_ERROR); } bool CdmLicense::IsKeyLoaded(const KeyId& key_id) { @@ -1040,19 +982,20 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse( LicenseError license_error; if (!license_error.ParseFromString(signed_message.msg())) { LOGE("Failed to parse license error response"); - return KEY_ERROR; + return CdmResponseType(KEY_ERROR); } + // TODO(b/261185349) Add new field in CdmResponseType to handle license_error switch (license_error.error_code()) { case LicenseError::INVALID_DRM_DEVICE_CERTIFICATE: - return NEED_PROVISIONING; + return CdmResponseType(NEED_PROVISIONING); case LicenseError::REVOKED_DRM_DEVICE_CERTIFICATE: - return DEVICE_REVOKED; + return CdmResponseType(DEVICE_REVOKED); case LicenseError::SERVICE_UNAVAILABLE: default: LOGW("Unknown error type: error_code = %d", static_cast(license_error.error_code())); - return KEY_ERROR; + return CdmResponseType(KEY_ERROR); } } @@ -1062,7 +1005,7 @@ CdmResponseType CdmLicense::PrepareClientId( wvcdm::ClientIdentification id; if (client_token_.empty()) { LOGE("Client token not set when preparing client ID"); - return CLIENT_TOKEN_NOT_SET; + return CdmResponseType(CLIENT_TOKEN_NOT_SET); } CdmResponseType status = @@ -1077,7 +1020,7 @@ CdmResponseType CdmLicense::PrepareClientId( if (Properties::UsePrivacyMode(session_id_)) { if (!service_certificate_.has_certificate()) { LOGE("Service certificate not staged"); - return PRIVACY_MODE_ERROR_3; + return CdmResponseType(PRIVACY_MODE_ERROR_3); } EncryptedClientIdentification* encrypted_client_id = license_request->mutable_encrypted_client_id(); @@ -1090,7 +1033,7 @@ CdmResponseType CdmLicense::PrepareClientId( } return status; } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmLicense::PrepareContentId( @@ -1108,11 +1051,11 @@ CdmResponseType CdmLicense::PrepareContentId( widevine_pssh_data->add_pssh_data(init_data.data()); } else { LOGE("ISO-CENC init data not available"); - return CENC_INIT_DATA_UNAVAILABLE; + return CdmResponseType(CENC_INIT_DATA_UNAVAILABLE); } if (!SetTypeAndId(license_type, request_id, widevine_pssh_data)) { - return PREPARE_CENC_CONTENT_ID_FAILED; + return CdmResponseType(PREPARE_CENC_CONTENT_ID_FAILED); } } else if (init_data.is_webm()) { LicenseRequest_ContentIdentification_WebmKeyId* webm_key_id = @@ -1122,67 +1065,49 @@ CdmResponseType CdmLicense::PrepareContentId( webm_key_id->set_header(init_data.data()); } else { LOGE("WebM init data not available"); - return WEBM_INIT_DATA_UNAVAILABLE; + return CdmResponseType(WEBM_INIT_DATA_UNAVAILABLE); } if (!SetTypeAndId(license_type, request_id, webm_key_id)) { - return PREPARE_WEBM_CONTENT_ID_FAILED; + return CdmResponseType(PREPARE_WEBM_CONTENT_ID_FAILED); } } else { LOGE("Unsupported init data type: type = %s", init_data.type().c_str()); - return UNSUPPORTED_INIT_DATA_FORMAT; + return CdmResponseType(UNSUPPORTED_INIT_DATA_FORMAT); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType CdmLicense::HandleContentKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, - const std::string& signature, const std::string& mac_key_iv, - const std::string& mac_key, const std::vector& key_array, + const std::string& signature, const std::vector& key_array, const video_widevine::License& license) { if (key_array.empty()) { LOGE("No content keys provided"); - return NO_CONTENT_KEY; + return CdmResponseType(NO_CONTENT_KEY); } - CdmResponseType resp; - if (supports_core_messages()) { - resp = crypto_session_->LoadLicense(msg, core_message, signature, - kLicenseKeyTypeContent); - } else { - resp = crypto_session_->LoadKeys( - msg, signature, mac_key_iv, mac_key, key_array, provider_session_token_, - license.srm_requirement(), kLicenseKeyTypeContent); - } - + const CdmResponseType resp = crypto_session_->LoadLicense( + msg, core_message, signature, kLicenseKeyTypeContent); if (KEY_ADDED == resp) { loaded_keys_.clear(); - for (std::vector::const_iterator it = key_array.begin(); - it != key_array.end(); ++it) { - loaded_keys_.insert(it->key_id()); + for (const CryptoKey& key : key_array) { + loaded_keys_.insert(key.key_id()); } - policy_engine_->SetLicense(license, supports_core_messages(), is_restore); + policy_engine_->SetLicense(license, is_restore); } return resp; } CdmResponseType CdmLicense::HandleEntitlementKeyResponse( bool is_restore, const std::string& msg, const std::string& core_message, - const std::string& signature, const std::string& mac_key_iv, - const std::string& mac_key, const std::vector& key_array, + const std::string& signature, const std::vector& key_array, const video_widevine::License& license) { if (key_array.empty()) { LOGE("No entitlement keys provided"); - return NO_CONTENT_KEY; - } - CdmResponseType resp; - if (supports_core_messages()) { - resp = crypto_session_->LoadLicense(msg, core_message, signature, - kLicenseKeyTypeEntitlement); - } else { - resp = crypto_session_->LoadKeys( - msg, signature, mac_key_iv, mac_key, key_array, provider_session_token_, - license.srm_requirement(), kLicenseKeyTypeEntitlement); + return CdmResponseType(NO_CONTENT_KEY); } + const CdmResponseType resp = crypto_session_->LoadLicense( + msg, core_message, signature, kLicenseKeyTypeEntitlement); if (KEY_ADDED != resp) { return resp; @@ -1190,8 +1115,7 @@ CdmResponseType CdmLicense::HandleEntitlementKeyResponse( // Save the entitlement keys for future use to handle key changes. entitlement_keys_.CopyFrom(license.key()); - policy_engine_->SetLicense(license, supports_core_messages(), is_restore); - + policy_engine_->SetLicense(license, is_restore); return HandleNewEntitledKeys(wrapped_keys_); } @@ -1199,53 +1123,42 @@ CdmResponseType CdmLicense::HandleNewEntitledKeys( const std::vector& wrapped_keys) { std::vector entitled_key_array; entitled_key_array.reserve(wrapped_keys.size()); - - for (RepeatedPtrField::const_iterator kc = - entitlement_keys_.begin(); - kc != entitlement_keys_.end(); ++kc) { - if (kc->type() != video_widevine::License::KeyContainer::ENTITLEMENT) { + for (const auto& kc : entitlement_keys_) { + if (kc.type() != video_widevine::License::KeyContainer::ENTITLEMENT) { continue; } - for (std::vector::const_iterator wk = - wrapped_keys.begin(); - wk != wrapped_keys.end(); wk++) { - if (wk->entitlement_key_id() == kc->id()) { - // Add a new entry to the key array to load oemcrypto. - entitled_key_array.resize(entitled_key_array.size() + 1); - - // Strip PKCS#5 padding from entitled content keys. - std::string content_key = wk->key(); - if (content_key.size() < CONTENT_KEY_SIZE) { - LOGE( - "Entitled content key too small: " - "expected = %zu, actual = %zu (bytes)", - CONTENT_KEY_SIZE, content_key.size()); - return KEY_SIZE_ERROR_2; - } else if (content_key.size() > CONTENT_KEY_SIZE) { - content_key.resize(CONTENT_KEY_SIZE); - } - - CryptoKey& this_entry = entitled_key_array.back(); - this_entry.set_key_id(wk->key_id()); - this_entry.set_key_data_iv(wk->iv()); - this_entry.set_entitlement_key_id(wk->entitlement_key_id()); - this_entry.set_key_data(content_key); + for (const auto& wk : wrapped_keys) { + if (wk.entitlement_key_id() != kc.id()) continue; + // Strip PKCS#5 padding from entitled content keys. + std::string content_key = wk.key(); + if (content_key.size() < CONTENT_KEY_SIZE) { + LOGE( + "Entitled content key too small: " + "expected = %zu, actual = %zu (bytes)", + CONTENT_KEY_SIZE, content_key.size()); + return CdmResponseType(KEY_SIZE_ERROR_2); + } else if (content_key.size() > CONTENT_KEY_SIZE) { + content_key.resize(CONTENT_KEY_SIZE); } + + CryptoKey this_entry; + this_entry.set_key_id(wk.key_id()); + this_entry.set_key_data_iv(wk.iv()); + this_entry.set_entitlement_key_id(wk.entitlement_key_id()); + this_entry.set_key_data(content_key); + // Add a new entry to the key array to load oemcrypto. + entitled_key_array.push_back(std::move(this_entry)); } } - CdmResponseType resp = + const CdmResponseType resp = crypto_session_->LoadEntitledContentKeys(entitled_key_array); - if (KEY_ADDED == resp) { - for (std::vector::const_iterator it = - wrapped_keys.begin(); - it != wrapped_keys.end(); ++it) { - loaded_keys_.insert(it->key_id()); - } - - policy_engine_->SetEntitledLicenseKeys(wrapped_keys); + if (resp != KEY_ADDED) return resp; + for (const auto& wk : wrapped_keys) { + loaded_keys_.insert(wk.key_id()); } - return resp; + policy_engine_->SetEntitledLicenseKeys(wrapped_keys); + return CdmResponseType(KEY_ADDED); } template diff --git a/core/src/license_key_status.cpp b/core/src/license_key_status.cpp index 6294cb7a..76993358 100644 --- a/core/src/license_key_status.cpp +++ b/core/src/license_key_status.cpp @@ -9,6 +9,7 @@ #include "log.h" #include "wv_cdm_constants.h" +namespace wvcdm { namespace { // License protocol aliases using KeyContainer = ::video_widevine::License::KeyContainer; @@ -19,7 +20,7 @@ using ConstraintList = // Map the HDCP protection associated with a key in the license to // an equivalent OEMCrypto HDCP protection level -wvcdm::CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp( +CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp( const OutputProtection::HDCP& input) { switch (input) { case OutputProtection::HDCP_NONE: @@ -36,11 +37,46 @@ wvcdm::CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp( return HDCP_V2_3; case OutputProtection::HDCP_NO_DIGITAL_OUTPUT: return HDCP_NO_DIGITAL_OUTPUT; - default: - LOGE("Unknown HDCP Level, returning HDCP_NO_DIGITAL_OUTPUT: input = %d", - static_cast(input)); - return HDCP_NO_DIGITAL_OUTPUT; } + LOGW("Unknown HDCP Level, returning HDCP_NO_DIGITAL_OUTPUT: input = %d", + static_cast(input)); + return HDCP_NO_DIGITAL_OUTPUT; +} + +bool MeetsHdcpRequirements(const CryptoSession::HdcpCapability& required, + const CryptoSession::HdcpCapability& provided) { + if (provided == HDCP_NO_DIGITAL_OUTPUT) return true; // Always met. + switch (required) { + case HDCP_NONE: + return true; // Always met. + case HDCP_V1: // Means v1.x + // Can be any HDCP level other than NONE. + return provided != HDCP_NONE; + case HDCP_V2: // Means v2.0 + case HDCP_V2_1: + case HDCP_V2_2: + case HDCP_V2_3: + // Must be equal to or higher than the required v2.x version. + return provided >= required && provided <= HDCP_V2_3; + case HDCP_V1_0: + case HDCP_V1_1: + case HDCP_V1_2: + case HDCP_V1_3: + case HDCP_V1_4: + // Must be equal to or higher than the required v1.x version, + // be exactly v1.x, or within the 2.x range. OEMCrypto may + // behave differently. + return (provided == HDCP_V1) || + (provided >= required && provided <= HDCP_V1_4) || + (provided >= HDCP_V2 && provided <= HDCP_V2_3); + case HDCP_NO_DIGITAL_OUTPUT: + // If |provided| was HDCP_NO_DIGITAL_OUTPUT, it would have been caught + // at the top of this function. + return false; + } + LOGE("Unknown required HDCP level: required = %d, provided = %d", + static_cast(required), static_cast(provided)); + return false; } // Returns the constraint from a set of constraints that matches the @@ -63,8 +99,6 @@ VideoResolutionConstraint* GetConstraintForRes( } // namespace -namespace wvcdm { - bool LicenseKeys::IsContentKey(const std::string& key_id) { if (key_statuses_.count(key_id) > 0) { return key_statuses_[key_id]->IsContentKey(); @@ -199,12 +233,7 @@ void LicenseKeys::SetEntitledKeys( } LicenseKeyStatus::LicenseKeyStatus(const KeyContainer& key, - const CdmSecurityLevel security_level) - : is_content_key_(false), - key_status_(kKeyStatusInternalError), - meets_constraints_(true), - meets_security_level_constraints_(true), - default_hdcp_level_(HDCP_NONE) { + const CdmSecurityLevel security_level) { allowed_usage_.Clear(); constraints_.Clear(); @@ -293,7 +322,7 @@ void LicenseKeyStatus::ParseContentKey(const KeyContainer& key, void LicenseKeyStatus::ParseOperatorSessionKey(const KeyContainer& key) { is_content_key_ = false; if (key.has_operator_session_key_permissions()) { - OperatorSessionKeyPermissions permissions = + const OperatorSessionKeyPermissions& permissions = key.operator_session_key_permissions(); if (permissions.has_allow_encrypt()) allowed_usage_.generic_encrypt = permissions.allow_encrypt(); @@ -370,15 +399,14 @@ void LicenseKeyStatus::ApplyConstraints( } } - CryptoSession::HdcpCapability desired_hdcp_level; + CryptoSession::HdcpCapability desired_hdcp_level = default_hdcp_level_; if (current_constraint && current_constraint->has_required_protection()) { desired_hdcp_level = ProtobufHdcpToOemCryptoHdcp( current_constraint->required_protection().hdcp()); - } else { - desired_hdcp_level = default_hdcp_level_; } - meets_constraints_ = (new_hdcp_level >= desired_hdcp_level); + meets_constraints_ = + MeetsHdcpRequirements(desired_hdcp_level, new_hdcp_level); } void LicenseKeyStatus::SetConstraints(const ConstraintList& constraints) { diff --git a/core/src/license_protocol.proto b/core/src/license_protocol.proto index 9101ae7c..25ede138 100644 --- a/core/src/license_protocol.proto +++ b/core/src/license_protocol.proto @@ -29,6 +29,156 @@ message RemoteAttestation { optional bytes signature = 3; } +// ---------------------------------------------------------------------------- +// dtcp_usage.proto +// ---------------------------------------------------------------------------- +// Description of section: +// Definitions of the protocol buffer message used for DTCP2 usage rules. + +message DTCPUsageRules { + // This field indicates the value of Retention_State. + enum RetentionState { + // (-- api-linter: core::0126::unspecified=disabled + // aip.dev/not-precedent: name and values are defined in the DTCP + // specification. --) + // Forever + RETENTION_STATE_FOREVER = 0; + // 1 week + RETENTION_STATE_1_WEEK = 1; + // 2 day + RETENTION_STATE_2_DAYS = 2; + // 1 day + RETENTION_STATE_1_DAY = 3; + // 12 hours + RETENTION_STATE_12_HOURS = 4; + // 6 hours + RETENTION_STATE_6_HOURS = 5; + // 3 hours + RETENTION_STATE_3_HOURS = 6; + // 90 minutes + RETENTION_STATE_90_MINUTES = 7; + } + + // This field indicates Copy Control Information (CCI). + enum CopyControlInfo { + // Copy freely + COPY_FREE = 0; + // No more copies + COPY_NO_MORE = 1; + // One time copy + COPY_ONE = 2; + // Copy not allowed + COPY_NEVER = 3; + } + + // This field indicates Analog Protection System (APS) used to block + // recording devices. + enum AnalogProtectionSystem { + // Copy freely, APS is off + APS_OFF = 0; + // APS is on, Type 1 (AGC) + APS_TYPE1 = 1; + // APS is on, Type 2 (AGC + 2L Colorstripe) + APS_TYPE2 = 2; + // APS is on, Type 3 (AGC + 4L Colorstripe) + APS_TYPE3 = 3; + } + + // This field indicates the value of the Image Constraint Token (ICT) that + // controls downsampling of high-definition video. + enum ImageConstraintToken { + // HD analog output, Constrained Image + ICT_CONSTRAINED = 0; + // HD analog out + ICT_HD_ANALOG = 1; + } + + // This field indicates the value of Analog Sunset Token (AST) used to limit + // playback to standard definition (SD) only + enum AnalogSunsetToken { + // Asserted + AST_ASSERTED = 0; + // Unasserted + AST_UNASERTED = 1; + } + + // This field indicates the value of Digital Only Token (DOT) used to restrict + // output to digital only. + enum DigitalOnlyToken { + // Asserted + DOT_ASSERTED = 0; + // Unasserted + DOT_UNASSERTED = 1; + } + + // This field indicates the value of Audio Enhanced Token (AET). + enum AudioEnhancedToken { + // Asserted + AET_ASSERTED = 0; + // Unasserted + AET_UNASSERTED = 1; + } + + // This field indicates the value of Standard Digital Output (SDO) token. + enum StandardDigitalOutputToken { + // Unasserted + SDO_UNASSEERTED = 0; + // Asserted, L2 protection is permitted + SDO_ASSEERTED = 1; + } + + // This field indicates the value of High Dynamic Rnage (HDR) token. + enum HighDynamicRangeToken { + // Unasserted, SDR conversion is permitted + HDR_UNASSERTED = 0; + // Unasserted, SDR conversion is not permitted + HDR_ASSERTED = 1; + } + + // This field indicates the value of the L2 Protection Only token. + enum L2ProtectionOnlyToken { + // Unasserted + L2_ONLY_UNASSERTED = 0; + // Aasserted (L2 protection onl) + L2_ONLY_ASSERTED = 1; + } + + // This field indicates the value of the Enhanced Image (EI) token + enum EnhancedImageToken { + // Unasserted, Non-Enhanced Image + EI_UNASSERTED = 0; + // Asserted, Enhanced Image + EI_ASSERTED = 1; + } + + // This field indicates whether a further Bound Copy can be made from a + // Bound Copy retained in accordance with the RetentionStatefield. + enum FurtherBoundCopy { + // Further Bound Copy Prohibited + FBC_PROHIBITED = 0; + // Further Bound Copy Permitted + FBC_PERMITTED = 1; + } + + // Indicates if Digital Transmission Control Protection 2 (DTCP2) is required. + optional bool require_dtcp2 = 1 [default = false]; + optional CopyControlInfo copy_control = 2; + optional bool encryption_plus = 3; + optional RetentionState retention_state = 4; + optional AnalogProtectionSystem analog_protection_system = 5; + optional ImageConstraintToken image_constraint_token = 6; + optional AnalogSunsetToken analog_sunset_token = 7; + optional DigitalOnlyToken digital_only_token = 8; + optional AudioEnhancedToken audio_enhanced_token = 9; + optional uint32 copy_count = 10; + optional StandardDigitalOutputToken standard_digital_token = 11; + optional HighDynamicRangeToken high_dynamic_token = 12; + optional L2ProtectionOnlyToken l2_only_token = 13; + optional EnhancedImageToken enhaned_image_token = 14; + optional uint32 retention_time = 15; + optional FurtherBoundCopy further_copy = 16; +} + // ---------------------------------------------------------------------------- // license_protocol.proto // ---------------------------------------------------------------------------- @@ -134,6 +284,26 @@ message License { WATERMARKING_REQUIRED = 2; } + // The base for (delayed) timers, i.e. the time from which the delayed timer + // starts. + enum TimerDelayBase { + // Not specified + TIMER_DELAY_BASE_UNSPECIFIED = 0; + // The timer delay is based on |license_start_time|. + LICENSE_START = 1; + // The timer delay is based on the time the license is received by the + // client, whether the license is newly issued by the server or loaded + // from the disk (for persistent licenses). + // IMPORTANT: The playback window also begins immediately at license load + // time. + LICENSE_LOAD = 2; + // The timer delay is based on the time of first decryption. + // NOTE: For persistent licenses, the first decryption time should be + // persisted so that the "first decrypt" should only happen once even when + // the license is loaded repeatedly. + FIRST_DECRYPT = 3; + } + // Indicates that playback of the content is allowed. optional bool can_play = 1 [default = false]; @@ -169,10 +339,17 @@ message License { // specified URL. optional string renewal_server_url = 8; - // How many seconds after |license_start_time| before renewal is first - // attempted. If |renew_with_usage| is true in a new license, then this is - // the optional number of seconds after first playback, before renewal is - // first attempted. + // How many seconds after the "renewal delay base" before renewal is first + // attempted. For an initial license, see comments on + // |initial_renewal_delay_base| on how the "renewal delay base" is + // determined. For a renewal license, the "renewal delay base" is always the + // |license_start_time| of the renewal license. + // NOTE: + // - Renewal should not be attempted if |can_renew| or |can_play| is false, + // or if the license has expired. + // - When the "renewal delay base" is first time of decryption + // (|FIRST_DECRYPT|), this delay is optional: the client can attempt the + // renewal without the delay. optional int64 renewal_delay_seconds = 9 [default = 0]; // Specifies the delay in seconds between subsequent license @@ -207,6 +384,19 @@ message License { // Optional requirement to indicate watermarking is allowed. optional WatermarkingControl watermarking_control = 16 [default = WATERMARKING_CONTROL_UNSPECIFIED]; + + // Optional DTCP2 requirements. Default is to not allow dtcp2. + optional DTCPUsageRules dtcp2 = 17; + + // The base for |renewal_delay_seconds| for the initial license. For renewal + // licenses this field will be ignored and |renewal_delay_seconds| is always + // be based on |license_start_time|. + // NOTE: For backward compatibility, when set to + // TIMER_DELAY_BASE_UNSPECIFIED or has no value, the actual "renewal delay + // base" will be FIRST_DECRYPT if |renew_with_usage| is true, or + // LICENSE_START otherwise. + optional TimerDelayBase initial_renewal_delay_base = 18 + [default = TIMER_DELAY_BASE_UNSPECIFIED]; } message KeyContainer { @@ -247,6 +437,14 @@ message License { HW_SECURE_ALL = 5; } + // The EncryptionScheme to be used for the content keys. This is applicable + // only to Moho API. + enum EncryptionScheme { + ENCRYPTION_SCHEME_UNSPECIFIED = 0; + AES128_CTR = 1; + AES128_CBC = 2; + } + message KeyControl { // If present, the key control must be communicated to the secure // environment prior to any usage. This message is automatically generated @@ -368,6 +566,10 @@ message License { // single content or a group of contents. Currently it is only used in CAS // request. optional KeyCategorySpec key_category_spec = 13; + // Optional. Used by Moho API for Content key encryption. If unspecified, + // the Moho code uses the encryption scheme of type AES128_CTR. + optional EncryptionScheme encryption_scheme = 14 + [default = ENCRYPTION_SCHEME_UNSPECIFIED]; } optional LicenseIdentification id = 1; @@ -479,6 +681,9 @@ message LicenseRequest { optional uint32 key_control_nonce = 7; // Encrypted ClientIdentification message, used for privacy purposes. optional EncryptedClientIdentification encrypted_client_id = 8; + // The version of the client implementation. This field is optional and + // informational only. + optional string client_version = 9; } message LicenseError { @@ -944,6 +1149,9 @@ message ClientIdentification { // Support is optional. // Value is only required to be set for license requests. optional WatermarkingSupport watermarking_support = 13; + // Indicate whether or not `initial_renewal_delay_base` is supported by the + // client. + optional bool initial_renewal_delay_base = 14 [default = false]; } message ClientCredentials { diff --git a/core/src/license_protocol_conversions.cpp b/core/src/license_protocol_conversions.cpp new file mode 100644 index 00000000..f228763b --- /dev/null +++ b/core/src/license_protocol_conversions.cpp @@ -0,0 +1,30 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "license_protocol_conversions.h" + +namespace wvcdm { +// Protobuf generated classes. +using video_widevine::HashAlgorithmProto; + +bool OecAlgorithmToProtoAlgorithm( + OEMCrypto_SignatureHashAlgorithm oec_algorithm, + HashAlgorithmProto& proto_algorithm) { + switch (oec_algorithm) { + case OEMCrypto_SHA1: + proto_algorithm = HashAlgorithmProto::HASH_ALGORITHM_SHA_1; + return true; + case OEMCrypto_SHA2_256: + proto_algorithm = HashAlgorithmProto::HASH_ALGORITHM_SHA_256; + return true; + case OEMCrypto_SHA2_384: + proto_algorithm = HashAlgorithmProto::HASH_ALGORITHM_SHA_384; + return true; + case OEMCrypto_SHA2_512: + // TODO(b/259268439): The service does not support SHA-512 + return false; + } + return false; +} +} // namespace wvcdm diff --git a/core/src/oemcrypto_adapter_static.cpp b/core/src/oemcrypto_adapter_static.cpp index d3aa9994..de07d877 100644 --- a/core/src/oemcrypto_adapter_static.cpp +++ b/core/src/oemcrypto_adapter_static.cpp @@ -7,6 +7,8 @@ // compile time. // +#include "log.h" +#include "odk_structs.h" #include "oemcrypto_adapter.h" namespace wvcdm { @@ -15,6 +17,13 @@ OEMCryptoResult OEMCrypto_InitializeAndCheckKeybox( if (!needs_keybox_provisioning) return OEMCrypto_ERROR_UNKNOWN_FAILURE; const OEMCryptoResult status = ::OEMCrypto_Initialize(); if (status != OEMCrypto_SUCCESS) return status; + const OEMCryptoResult api_status = + ::OEMCrypto_SetMaxAPIVersion(ODK_MAJOR_VERSION); + if (api_status != OEMCrypto_SUCCESS && + api_status != OEMCrypto_ERROR_NOT_IMPLEMENTED) { + // Log error, but continue assuming no error. + LOGE("OEMCrypto_SetMaxAPIVersion returned %d", api_status); + } const OEMCryptoResult keybox_status = ::OEMCrypto_IsKeyboxOrOEMCertValid(); if (keybox_status == OEMCrypto_SUCCESS) { *needs_keybox_provisioning = false; @@ -147,20 +156,6 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert, return ::OEMCrypto_GetOEMPublicCertificate(public_cert, public_cert_length); } -extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, - OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, - size_t num_keys, const OEMCrypto_KeyObject* key_array, - OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, - OEMCrypto_LicenseType license_type, OEMCryptoCipherMode*) { - // TODO(b/72223802): make this backwards compatibile for versions < 14. - return OEMCrypto_LoadKeys(session, message, message_length, signature, - signature_length, enc_mac_keys_iv, enc_mac_keys, - num_keys, key_array, pst, srm_restriction_data, - license_type); -} - size_t OEMCrypto_MaximumUsageTableHeaderSize(RequestedSecurityLevel) { return ::OEMCrypto_MaximumUsageTableHeaderSize(); } @@ -177,4 +172,51 @@ OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport( OEMCryptoResult OEMCrypto_ProductionReady(RequestedSecurityLevel) { return ::OEMCrypto_ProductionReady(); } + +OEMCryptoResult OEMCrypto_DecryptCENC( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SampleDescription* samples, + size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc* pattern) { + return OEMCrypto_DecryptCENC(key_handle, key_handle_length, samples, + samples_length, pattern); +} + +OEMCryptoResult OEMCrypto_Generic_Encrypt( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer) { + return OEMCrypto_Generic_Encrypt(key_handle, key_handle_length, in_buffer, + in_buffer_length, iv, algorithm, out_buffer); +} + +OEMCryptoResult OEMCrypto_Generic_Decrypt( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer) { + return OEMCrypto_Generic_Decrypt(key_handle, key_handle_length, in_buffer, + in_buffer_length, iv, algorithm, out_buffer); +} + +OEMCryptoResult OEMCrypto_Generic_Sign( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* signature, size_t* signature_length) { + return OEMCrypto_Generic_Sign(key_handle, key_handle_length, buffer, + buffer_length, algorithm, signature, + signature_length); +} + +OEMCryptoResult OEMCrypto_Generic_Verify( + RequestedSecurityLevel level, const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + const OEMCrypto_SharedMemory* signature, size_t signature_length) { + return OEMCrypto_Generic_Verify(key_handle, key_handle_length, buffer, + buffer_length, algorithm, signature, + signature_length); +} + } // namespace wvcdm diff --git a/core/src/ota_keybox_provisioner.cpp b/core/src/ota_keybox_provisioner.cpp index 1cbf035d..ccc11463 100644 --- a/core/src/ota_keybox_provisioner.cpp +++ b/core/src/ota_keybox_provisioner.cpp @@ -129,21 +129,21 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest( std::string* request, std::string* default_url) { if (request == nullptr) { LOGE("Output |request| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (default_url == nullptr) { LOGE("Output |default_url| is null"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (IsProvisioned()) { LOGW("Already provisioned"); CleanUp(); - return OKP_ALREADY_PROVISIONED; + return CdmResponseType(OKP_ALREADY_PROVISIONED); } if (!crypto_session_) { LOGE("Crypto session has been released, OKP unavailable"); // Caller should not reuse provisioner after failure. - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } // Step 1: Generate raw request from OEMCrypto. std::string ota_request_data; @@ -155,8 +155,7 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest( CleanUp(); return result; } else if (result != NO_ERROR) { - LOGE("Failed to generate OKP request: status = %d", - static_cast(result)); + LOGE("Failed to generate OKP request: status = %d", result.ToInt()); return result; } // Step 2: Wrap in ProvisioningRequest. @@ -165,7 +164,7 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest( result = client_id_.Prepare(kEmptyAppParameters, kEmptyString, client_id); if (result != NO_ERROR) { LOGW("Failed to prepare client ID, continuing without: result = %d", - static_cast(result)); + result.ToInt()); client_id->Clear(); } LOGI("OTA request generated"); @@ -189,36 +188,36 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest( request_generated_ = true; CertificateProvisioning::GetProvisioningServerUrl(default_url); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType OtaKeyboxProvisioner::HandleProvisioningResponse( const std::string& response) { if (response.empty()) { LOGE("Signed provisioning message is empty"); - return EMPTY_PROVISIONING_RESPONSE; + return CdmResponseType(EMPTY_PROVISIONING_RESPONSE); } if (IsProvisioned()) { LOGD("Already provisioned"); response_received_ = true; CleanUp(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } if (!request_generated_) { LOGE("Received response without generating request"); - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } if (!crypto_session_) { LOGE("Crypto session has been released, OKP unavailable"); // Caller should not reuse provisioner after failure. - return UNKNOWN_ERROR; + return CdmResponseType(UNKNOWN_ERROR); } std::string decoded_response; if (!wvcdm::Properties::provisioning_messages_are_binary()) { if (!CertificateProvisioning::ExtractAndDecodeSignedMessage( response, &decoded_response)) { LOGE("Failed to extract OKP provisioning response"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } } else { decoded_response = response; @@ -227,38 +226,38 @@ CdmResponseType OtaKeyboxProvisioner::HandleProvisioningResponse( SignedProvisioningMessage signed_response; if (!signed_response.ParseFromString(decoded_response)) { LOGE("Failed to parse SignedProvisioningMessage"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } if (!signed_response.has_message()) { LOGE("Signed response is missing message"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } if (signed_response.provisioning_type() != SignedProvisioningMessage::ANDROID_ATTESTATION_KEYBOX_OTA) { LOGE("Unexpected protocol type/version: protocol_type = %d", static_cast(signed_response.provisioning_type())); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } // Step 2: Unwrap from ProvisioningResponse. ProvisioningResponse prov_response; if (!prov_response.ParseFromString(signed_response.message())) { LOGE("Failed to parse ProvisioningResponse"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } if (!prov_response.has_android_ota_keybox_response()) { LOGE("Missing OTA keybox response message"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } const OtaResponse& ota_response = prov_response.android_ota_keybox_response(); if (!ota_response.has_ota_response()) { LOGE("Missing OTA keybox response data"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } // Step 3: Load response. const std::string ota_response_data = ota_response.ota_response(); if (ota_response_data.empty()) { LOGE("Raw OTA response is empty"); - return PARSE_OKP_RESPONSE_ERROR; + return CdmResponseType(PARSE_OKP_RESPONSE_ERROR); } const CdmResponseType result = crypto_session_->LoadOtaProvisioning( kProductionKeybox, ota_response_data); diff --git a/core/src/policy_engine.cpp b/core/src/policy_engine.cpp index 60d6e836..6ee78c58 100644 --- a/core/src/policy_engine.cpp +++ b/core/src/policy_engine.cpp @@ -8,8 +8,8 @@ #include "clock.h" #include "log.h" -#include "policy_timers_v15.h" #include "policy_timers_v16.h" +#include "policy_timers_v18.h" #include "properties.h" #include "string_conversions.h" #include "wv_cdm_constants.h" @@ -22,7 +22,7 @@ namespace { const int kCdmPolicyTimerDurationSeconds = 1; const int kClockSkewDelta = 5; // seconds const int64_t kLicenseStateUpdateDelay = 20; // seconds - +const uint32_t kMinOemCryptoApiVersionSupportsRenewalDelayBase = 18; } // namespace namespace wvcdm { @@ -30,14 +30,20 @@ namespace wvcdm { PolicyEngine::PolicyEngine(CdmSessionId session_id, WvCdmEventListener* event_listener, CryptoSession* crypto_session) - : license_state_(kLicenseStateInitial), - license_state_update_deadline_(0), - last_recorded_current_time_(0), - session_id_(session_id), + : session_id_(session_id), event_listener_(event_listener), license_keys_(new LicenseKeys(crypto_session->GetSecurityLevel())), - policy_timers_(new PolicyTimersV15), - clock_(new wvutil::Clock) { + clock_(new wvutil::Clock()) { + uint32_t version = 0; + if (crypto_session->GetApiVersion(&version)) { + if (version >= kMinOemCryptoApiVersionSupportsRenewalDelayBase) { + policy_timers_.reset(new PolicyTimersV18()); + } + } + + if (policy_timers_ == nullptr) { + policy_timers_.reset(new PolicyTimersV16()); + } InitDevice(crypto_session); } @@ -46,11 +52,10 @@ PolicyEngine::~PolicyEngine() {} bool PolicyEngine::CanDecryptContent(const KeyId& key_id) { if (license_keys_->IsContentKey(key_id)) { return license_keys_->CanDecryptContent(key_id); - } else { - LOGE("Provided content key is not in license: key_id = %s", - wvutil::b2a_hex(key_id).c_str()); - return false; } + LOGE("Provided content key is not in license: key_id = %s", + wvutil::b2a_hex(key_id).c_str()); + return false; } CdmKeyStatus PolicyEngine::GetKeyStatus(const KeyId& key_id) { @@ -77,9 +82,9 @@ void PolicyEngine::CheckDeviceHdcpStatusOnTimer(int64_t current_time) { void PolicyEngine::CheckDeviceHdcpStatus() { if (!license_keys_->Empty()) { - CryptoSession::HdcpCapability current_hdcp_level; - CryptoSession::HdcpCapability ignored; - CdmResponseType status = + CryptoSession::HdcpCapability current_hdcp_level = HDCP_NONE; + CryptoSession::HdcpCapability ignored = HDCP_NONE; + const CdmResponseType status = crypto_session_->GetHdcpCapabilities(¤t_hdcp_level, &ignored); if (status != NO_ERROR) { current_hdcp_level = HDCP_NONE; @@ -104,7 +109,8 @@ void PolicyEngine::OnTimerEvent() { } // If we have passed the grace period, the expiration will update. - if (policy_timers_->HasPassedGracePeriod(current_time)) { + if (license_state_ != kLicenseStateInitial && + policy_timers_->HasPassedGracePeriod(current_time)) { NotifyExpirationUpdate(current_time); } @@ -125,7 +131,8 @@ void PolicyEngine::OnTimerEvent() { // Test to determine if renewal should be attempted. switch (license_state_) { case kLicenseStateCanPlay: { - if (policy_timers_->HasRenewalDelayExpired(current_time)) { + if (policy_timers_->HasRenewalDelayExpired(current_time) && + policy_timers_->get_policy().can_renew()) { renewal_needed = true; } // HDCP may change, so force a check. @@ -134,12 +141,15 @@ void PolicyEngine::OnTimerEvent() { } case kLicenseStateNeedRenewal: { - renewal_needed = true; + if (policy_timers_->get_policy().can_renew()) { + renewal_needed = true; + } break; } case kLicenseStateWaitingLicenseUpdate: { - if (policy_timers_->HasRenewalRetryIntervalExpired(current_time)) { + if (policy_timers_->HasRenewalRetryIntervalExpired(current_time) && + policy_timers_->get_policy().can_renew()) { renewal_needed = true; } break; @@ -172,9 +182,7 @@ void PolicyEngine::OnTimerEvent() { } void PolicyEngine::SetLicense(const License& license, - bool supports_core_messages, bool defer_license_state_update) { - if (supports_core_messages) policy_timers_.reset(new PolicyTimersV16()); license_id_.CopyFrom(license.id()); license_keys_->SetFromLicense(license); policy_timers_->SetLicense(license); @@ -186,11 +194,8 @@ void PolicyEngine::SetEntitledLicenseKeys( license_keys_->SetEntitledKeys(entitled_keys); } -void PolicyEngine::SetLicenseForRelease(const License& license, - bool supports_core_messages) { - if (supports_core_messages) policy_timers_.reset(new PolicyTimersV16()); +void PolicyEngine::SetLicenseForRelease(const License& license) { license_id_.CopyFrom(license.id()); - // Expire any old keys. NotifyKeysChange(kKeyStatusExpired); policy_timers_->SetLicense(license); @@ -211,18 +216,20 @@ void PolicyEngine::UpdateLicense(const License& license, // if renewal, discard license if version has not been updated if (license_state_ != kLicenseStateInitial) { - if (license.id().version() > license_id_.version()) + if (license.id().version() > license_id_.version()) { license_id_.CopyFrom(license.id()); - else + } else { return; + } } const int64_t current_time = GetCurrentTime(); policy_timers_->UpdateLicense(current_time, license); - if (defer_license_state_update) + if (defer_license_state_update) { license_state_update_deadline_ = current_time + kLicenseStateUpdateDelay; - else + } else { UpdateLicenseState(current_time); + } } void PolicyEngine::UpdateLicenseState(int64_t current_time) { @@ -256,7 +263,8 @@ bool PolicyEngine::BeginDecryption() { case kLicenseStateWaitingLicenseUpdate: policy_timers_->BeginDecryption(current_time); - if (policy_timers_->get_policy().renew_with_usage()) { + if (policy_timers_->get_policy().renew_with_usage() && + policy_timers_->get_policy().can_renew()) { license_state_ = kLicenseStateNeedRenewal; } NotifyExpirationUpdate(current_time); @@ -290,7 +298,7 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) { if (license_state_ == kLicenseStateInitial) { query_response->clear(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } (*query_response)[QUERY_KEY_LICENSE_TYPE] = @@ -314,19 +322,19 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) { (*query_response)[QUERY_KEY_RENEWAL_SERVER_URL] = policy_timers_->get_policy().renewal_server_url(); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType PolicyEngine::QueryKeyAllowedUsage( const KeyId& key_id, CdmKeyAllowedUsage* key_usage) { if (key_usage == nullptr) { LOGE("Output parameter |key_usage| not provided"); - return PARAMETER_NULL; + return CdmResponseType(PARAMETER_NULL); } if (license_keys_->GetAllowedUsage(key_id, key_usage)) { - return NO_ERROR; + return CdmResponseType(NO_ERROR); } - return KEY_NOT_FOUND_1; + return CdmResponseType(KEY_NOT_FOUND_1); } bool PolicyEngine::CanUseKeyForSecurityLevel(const KeyId& key_id) { @@ -410,17 +418,19 @@ void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) { void PolicyEngine::NotifyExpirationUpdate(int64_t current_time) { int64_t expiry_time; if (policy_timers_->UpdateExpirationTime(current_time, &expiry_time)) { - if (event_listener_) + if (event_listener_) { event_listener_->OnExpirationUpdate(session_id_, expiry_time); + } } } int64_t PolicyEngine::GetCurrentTime() { int64_t current_time = clock_->GetCurrentTime(); - if (current_time + kClockSkewDelta < last_recorded_current_time_) + if (current_time + kClockSkewDelta < last_recorded_current_time_) { current_time = last_recorded_current_time_; - else + } else { last_recorded_current_time_ = current_time; + } return current_time; } diff --git a/core/src/policy_timers.cpp b/core/src/policy_timers.cpp index 55c54b4a..d03dc8b5 100644 --- a/core/src/policy_timers.cpp +++ b/core/src/policy_timers.cpp @@ -10,8 +10,6 @@ #include "log.h" -using video_widevine::License; - namespace wvcdm { void PolicyTimers::SetLicense(const video_widevine::License& license) { @@ -24,6 +22,28 @@ void PolicyTimers::DecryptionEvent(int64_t current_time) { last_playback_time_ = current_time; } +void PolicyTimers::RestorePlaybackTimes(int64_t current_time, + int64_t playback_start_time, + int64_t last_playback_time, + int64_t /* grace_period_end_time */) { + playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0; + last_playback_time_ = (last_playback_time > 0) ? last_playback_time : 0; + + const int64_t expiry_time = GetExpiryTime( + current_time, /* ignore_soft_enforce_playback_duration */ true); + was_expired_on_load_ = + expiry_time != NEVER_EXPIRES && expiry_time < current_time; +} + +int64_t PolicyTimers::GetLicenseOrRentalOrPlaybackDurationRemaining( + int64_t current_time) { + const int64_t expiry_time = GetExpiryTime( + current_time, /* ignore_soft_enforce_playback_duration */ false); + if (expiry_time == NEVER_EXPIRES) return LLONG_MAX; + if (expiry_time < current_time) return 0; + return expiry_time - current_time; +} + int64_t PolicyTimers::GetPlaybackDurationRemaining(int64_t current_time) { const int64_t playback_duration = policy_.playback_duration_seconds(); if (playback_duration == 0) return LLONG_MAX; @@ -46,7 +66,7 @@ bool PolicyTimers::GetSecondsSinceStarted(int64_t current_time, if (playback_start_time_ == 0) return false; *seconds_since_started = current_time - playback_start_time_; - return (*seconds_since_started >= 0) ? true : false; + return *seconds_since_started >= 0; } bool PolicyTimers::GetSecondsSinceLastPlayed( @@ -59,7 +79,7 @@ bool PolicyTimers::GetSecondsSinceLastPlayed( if (last_playback_time_ == 0) return false; *seconds_since_last_played = current_time - last_playback_time_; - return (*seconds_since_last_played >= 0) ? true : false; + return *seconds_since_last_played >= 0; } bool PolicyTimers::IsLicenseForFuture(int64_t current_time) { @@ -85,12 +105,6 @@ bool PolicyTimers::UpdateExpirationTime(int64_t current_time, return has_expiry_time_been_updated; } -bool PolicyTimers::HasRenewalDelayExpired(int64_t current_time) { - return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) && - (license_start_time_ + policy_.renewal_delay_seconds() <= - current_time); -} - bool PolicyTimers::HasRenewalRetryIntervalExpired(int64_t current_time) { return policy_.can_renew() && (policy_.renewal_retry_interval_seconds() > 0) && @@ -107,4 +121,61 @@ bool PolicyTimers::HasRenewalRecoveryDurationExpired(int64_t current_time) { current_time); } +int64_t PolicyTimers::GetExpiryTime( + int64_t current_time, bool ignore_soft_enforce_playback_duration) { + const int64_t rental_expiry_time = GetRentalExpiryTime(current_time); + const int64_t playback_expiry_time = GetPlaybackExpiryTime( + current_time, ignore_soft_enforce_playback_duration); + + if (rental_expiry_time == NEVER_EXPIRES) return playback_expiry_time; + if (playback_expiry_time == NEVER_EXPIRES) return rental_expiry_time; + + return std::min(rental_expiry_time, playback_expiry_time); +} + +// For the policy time fields checked in the following methods, a value of 0 +// (UNLIMITED_DURATION) indicates that there is no limit to the duration. +// If the fields are UNLIMITED_DURATION then these methods will return +// NEVER_EXPIRES. +int64_t PolicyTimers::GetRentalExpiryTime(int64_t current_time) { + if (policy_.rental_duration_seconds() == UNLIMITED_DURATION) + return NEVER_EXPIRES; + + if (HasPlaybackStarted(current_time) && + policy_.soft_enforce_rental_duration()) + return NEVER_EXPIRES; + + return license_start_time_ + policy_.rental_duration_seconds(); +} + +int64_t PolicyTimers::GetPlaybackExpiryTime( + int64_t current_time, bool ignore_soft_enforce_playback_duration) { + if (policy_.playback_duration_seconds() == UNLIMITED_DURATION) + return NEVER_EXPIRES; + + if (!HasPlaybackStarted(current_time)) return NEVER_EXPIRES; + + if (was_expired_on_load_) return current_time; + + if (!ignore_soft_enforce_playback_duration && + policy_.soft_enforce_playback_duration()) + return NEVER_EXPIRES; + + return playback_start_time_ + policy_.playback_duration_seconds(); +} + +int64_t PolicyTimers::GetRentalDurationRemaining(int64_t current_time) { + if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0; + const int64_t rental_expiry_time = GetRentalExpiryTime(current_time); + if (rental_expiry_time == NEVER_EXPIRES) return LLONG_MAX; + if (rental_expiry_time < current_time) return 0; + return rental_expiry_time - current_time; +} + +bool PolicyTimers::HasRentalOrPlaybackDurationExpired(int64_t current_time) { + const int64_t expiry_time = GetExpiryTime( + current_time, /* ignore_soft_enforce_playback_duration */ false); + return expiry_time != NEVER_EXPIRES && expiry_time <= current_time; +} + } // namespace wvcdm diff --git a/core/src/policy_timers_v15.cpp b/core/src/policy_timers_v15.cpp deleted file mode 100644 index f917c061..00000000 --- a/core/src/policy_timers_v15.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine License -// Agreement. - -#include "policy_timers_v15.h" - -#include -#include - -#include "log.h" -#include "wv_cdm_constants.h" - -using video_widevine::License; - -namespace { - -const int64_t kTimeZero = 0; - -} // namespace - -namespace wvcdm { - -bool PolicyTimersV15::UpdateLicense(int64_t current_time, - const License& license) { - if (!license.has_policy()) return false; - - policy_.MergeFrom(license.policy()); - - // some basic license validation - // license start time needs to be specified in the initial response - if (!license.has_license_start_time()) return false; - - // Update time information - license_start_time_ = license.license_start_time(); - next_renewal_time_ = license_start_time_ + policy_.renewal_delay_seconds(); - - if (!policy_.can_play() || - HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) - return false; - - return true; -} - -void PolicyTimersV15::BeginDecryption(int64_t current_time) { - if (playback_start_time_ == 0) { - playback_start_time_ = current_time; - last_playback_time_ = current_time; - if (policy_.play_start_grace_period_seconds() == 0) - grace_period_end_time_ = current_time; - } -} - -void PolicyTimersV15::RestorePlaybackTimes(int64_t current_time, - int64_t playback_start_time, - int64_t last_playback_time, - int64_t grace_period_end_time) { - playback_start_time_ = std::max(playback_start_time, kTimeZero); - last_playback_time_ = std::max(last_playback_time, kTimeZero); - grace_period_end_time_ = grace_period_end_time; - - if (policy_.play_start_grace_period_seconds() != 0) { - // If we are using grace period, we may need to override some of the values - // given to us by OEMCrypto. |grace_period_end_time| will be 0 if the grace - // period has not expired (effectively playback has not begun). Otherwise, - // |grace_period_end_time| contains the playback start time we should use. - playback_start_time_ = grace_period_end_time; - } - - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ true); - was_expired_on_load_ = - expiry_time != NEVER_EXPIRES && expiry_time < current_time; -} - -bool PolicyTimersV15::HasPlaybackStarted(int64_t current_time) { - if (playback_start_time_ == 0) return false; - - const int64_t playback_time = current_time - playback_start_time_; - return playback_time >= policy_.play_start_grace_period_seconds(); -} - -bool PolicyTimersV15::HasLicenseOrRentalOrPlaybackDurationExpired( - int64_t current_time) { - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ false); - return expiry_time != NEVER_EXPIRES && expiry_time <= current_time; -} - -bool PolicyTimersV15::HasPassedGracePeriod(int64_t current_time) { - if (grace_period_end_time_ == 0 && HasPlaybackStarted(current_time)) { - grace_period_end_time_ = playback_start_time_; - return true; - } - return false; -} - -int64_t PolicyTimersV15::GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) { - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ false); - if (expiry_time == NEVER_EXPIRES) return LLONG_MAX; - if (expiry_time < current_time) return 0; - return expiry_time - current_time; -} - -int64_t PolicyTimersV15::GetLicenseOrRentalDurationRemaining( - int64_t current_time) { - if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0; - const int64_t license_expiry_time = GetRentalExpiryTime(); - if (license_expiry_time == NEVER_EXPIRES) return LLONG_MAX; - if (license_expiry_time < current_time) return 0; - const int64_t policy_license_duration = policy_.license_duration_seconds(); - if (policy_license_duration == UNLIMITED_DURATION) - return license_expiry_time - current_time; - return std::min(license_expiry_time - current_time, policy_license_duration); -} - -// For the policy time fields checked in the following methods, a value of 0 -// (UNLIMITED_DURATION) indicates that there is no limit to the duration. -// If the fields are UNLIMITED_DURATION (including the hard limit) then these -// methods will return NEVER_EXPIRES. -int64_t PolicyTimersV15::GetHardLicenseExpiryTime() { - return policy_.license_duration_seconds() > 0 - ? license_start_time_ + policy_.license_duration_seconds() - : NEVER_EXPIRES; -} - -int64_t PolicyTimersV15::GetRentalExpiryTime() { - const int64_t hard_limit = GetHardLicenseExpiryTime(); - if (policy_.rental_duration_seconds() == 0) return hard_limit; - const int64_t expiry_time = - license_start_time_ + policy_.rental_duration_seconds(); - if (hard_limit == NEVER_EXPIRES) return expiry_time; - return std::min(hard_limit, expiry_time); -} - -int64_t PolicyTimersV15::GetExpiryTime( - int64_t current_time, bool ignore_soft_enforce_playback_duration) { - if (!HasPlaybackStarted(current_time)) return GetRentalExpiryTime(); - - const int64_t hard_limit = GetHardLicenseExpiryTime(); - if (policy_.playback_duration_seconds() == 0) return hard_limit; - if (!ignore_soft_enforce_playback_duration && !was_expired_on_load_ && - policy_.soft_enforce_playback_duration()) { - return hard_limit; - } - const int64_t expiry_time = - playback_start_time_ + policy_.playback_duration_seconds(); - - if (hard_limit == NEVER_EXPIRES) return expiry_time; - return std::min(hard_limit, expiry_time); -} - -} // namespace wvcdm diff --git a/core/src/policy_timers_v16.cpp b/core/src/policy_timers_v16.cpp index 4395a562..30e71b84 100644 --- a/core/src/policy_timers_v16.cpp +++ b/core/src/policy_timers_v16.cpp @@ -28,11 +28,8 @@ bool PolicyTimersV16::UpdateLicense(int64_t current_time, next_renewal_time_ = license.license_start_time() + policy_.renewal_delay_seconds(); - if (!policy_.can_play() || - HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) - return false; - - return true; + return policy_.can_play() && + !HasLicenseOrRentalOrPlaybackDurationExpired(current_time); } void PolicyTimersV16::BeginDecryption(int64_t current_time) { @@ -42,88 +39,10 @@ void PolicyTimersV16::BeginDecryption(int64_t current_time) { } } -void PolicyTimersV16::RestorePlaybackTimes( - int64_t current_time, int64_t playback_start_time, - int64_t last_playback_time, int64_t /* grace_period_end_time */) { - playback_start_time_ = (playback_start_time > 0) ? playback_start_time : 0; - last_playback_time_ = (last_playback_time > 0) ? last_playback_time : 0; - - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ true); - was_expired_on_load_ = - expiry_time != NEVER_EXPIRES && expiry_time < current_time; -} - -bool PolicyTimersV16::HasRentalOrPlaybackDurationExpired(int64_t current_time) { - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ false); - return expiry_time != NEVER_EXPIRES && expiry_time <= current_time; -} - -int64_t PolicyTimersV16::GetLicenseOrRentalOrPlaybackDurationRemaining( - int64_t current_time) { - const int64_t expiry_time = GetExpiryTime( - current_time, /* ignore_soft_enforce_playback_duration */ false); - if (expiry_time == NEVER_EXPIRES) return LLONG_MAX; - if (expiry_time < current_time) return 0; - return expiry_time - current_time; -} - -int64_t PolicyTimersV16::GetRentalDurationRemaining(int64_t current_time) { - if (HasLicenseOrRentalOrPlaybackDurationExpired(current_time)) return 0; - const int64_t rental_expiry_time = GetRentalExpiryTime(current_time); - if (rental_expiry_time == NEVER_EXPIRES) return LLONG_MAX; - if (rental_expiry_time < current_time) return 0; - return rental_expiry_time - current_time; -} - bool PolicyTimersV16::HasRenewalDelayExpired(int64_t current_time) { return policy_.can_renew() && (policy_.renewal_delay_seconds() > 0) && (renewal_start_time_ + policy_.renewal_delay_seconds() <= current_time); } -// For the policy time fields checked in the following methods, a value of 0 -// (UNLIMITED_DURATION) indicates that there is no limit to the duration. -// If the fields are UNLIMITED_DURATION then these methods will return -// NEVER_EXPIRES. -int64_t PolicyTimersV16::GetRentalExpiryTime(int64_t current_time) { - if (policy_.rental_duration_seconds() == UNLIMITED_DURATION) - return NEVER_EXPIRES; - - if (HasPlaybackStarted(current_time) && - policy_.soft_enforce_rental_duration()) - return NEVER_EXPIRES; - - return license_start_time_ + policy_.rental_duration_seconds(); -} - -int64_t PolicyTimersV16::GetPlaybackExpiryTime( - int64_t current_time, bool ignore_soft_enforce_playback_duration) { - if (policy_.playback_duration_seconds() == UNLIMITED_DURATION) - return NEVER_EXPIRES; - - if (!HasPlaybackStarted(current_time)) return NEVER_EXPIRES; - - if (was_expired_on_load_) return current_time; - - if (!ignore_soft_enforce_playback_duration && - policy_.soft_enforce_playback_duration()) - return NEVER_EXPIRES; - - return playback_start_time_ + policy_.playback_duration_seconds(); -} - -int64_t PolicyTimersV16::GetExpiryTime( - int64_t current_time, bool ignore_soft_enforce_playback_duration) { - const int64_t rental_expiry_time = GetRentalExpiryTime(current_time); - const int64_t playback_expiry_time = GetPlaybackExpiryTime( - current_time, ignore_soft_enforce_playback_duration); - - if (rental_expiry_time == NEVER_EXPIRES) return playback_expiry_time; - if (playback_expiry_time == NEVER_EXPIRES) return rental_expiry_time; - - return std::min(rental_expiry_time, playback_expiry_time); -} - } // namespace wvcdm diff --git a/core/src/policy_timers_v18.cpp b/core/src/policy_timers_v18.cpp new file mode 100644 index 00000000..ad46cf80 --- /dev/null +++ b/core/src/policy_timers_v18.cpp @@ -0,0 +1,93 @@ +// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "policy_timers_v18.h" + +#include + +#include "log.h" +#include "wv_cdm_constants.h" + +using video_widevine::License; + +namespace wvcdm { + +bool PolicyTimersV18::UpdateLicense(int64_t current_time, + const License& license) { + if (!license.has_policy()) return false; + + policy_.MergeFrom(license.policy()); + can_renew_ = policy_.can_renew(); + + // some basic license validation + // license start time needs to be specified in the initial response + if (!license.has_license_start_time()) return false; + + // Update renewal information + if (license_renewal_) { + renewal_start_time_ = license.license_start_time(); + next_renewal_time_ = + license.license_start_time() + policy_.renewal_delay_seconds(); + } else { + // Initial license received, use |renewal_delay_base| in calcualtion + switch (license.policy().initial_renewal_delay_base()) { + case video_widevine:: + License_Policy_TimerDelayBase_TIMER_DELAY_BASE_UNSPECIFIED: + case video_widevine::License_Policy_TimerDelayBase_LICENSE_START: + renewal_start_time_ = license.license_start_time(); + break; + case video_widevine::License_Policy_TimerDelayBase_LICENSE_LOAD: { + const int64_t rental_expiry_time = GetRentalExpiryTime(current_time); + if ((rental_expiry_time == NEVER_EXPIRES) || + (rental_expiry_time >= current_time)) { + renewal_start_time_ = current_time; + BeginDecryption(current_time); + } else { + can_renew_ = false; + } + } break; + case video_widevine::License_Policy_TimerDelayBase_FIRST_DECRYPT: + renew_on_first_decrypt_ = true; + break; + default: + LOGE("Unrecognized initial_renewal_delay_base value = %d", + license.policy().initial_renewal_delay_base()); + renewal_start_time_ = license.license_start_time(); + break; + } + + if (!renew_on_first_decrypt_) { + next_renewal_time_ = + renewal_start_time_ + policy_.renewal_delay_seconds(); + } + // Any subsequent calls to |UpdateLicense| will be license renewals + license_renewal_ = true; + } + + return policy_.can_play() && + !HasLicenseOrRentalOrPlaybackDurationExpired(current_time); +} + +void PolicyTimersV18::BeginDecryption(int64_t current_time) { + if (playback_start_time_ != 0) return; + + playback_start_time_ = current_time; + last_playback_time_ = current_time; + + if (renew_on_first_decrypt_) { + renewal_start_time_ = current_time; + next_renewal_time_ = renewal_start_time_ + policy_.renewal_delay_seconds(); + renew_on_first_decrypt_ = false; + } +} + +bool PolicyTimersV18::HasRenewalDelayExpired(int64_t current_time) { + if (renew_on_first_decrypt_ && playback_start_time_ == 0) return false; + + return can_renew_ && (policy_.renewal_delay_seconds() > 0) && + (renewal_start_time_ + policy_.renewal_delay_seconds() <= + current_time); +} + +} // namespace wvcdm diff --git a/core/src/service_certificate.cpp b/core/src/service_certificate.cpp index 2d2947bf..c89648a1 100644 --- a/core/src/service_certificate.cpp +++ b/core/src/service_certificate.cpp @@ -4,6 +4,7 @@ #include "service_certificate.h" +#include "cdm_random.h" #include "crypto_key.h" #include "crypto_session.h" #include "license_protocol.pb.h" @@ -18,7 +19,7 @@ namespace { // as the root of a signing chain. // clang-format off -static const unsigned char kRootCertForProd[] = { +const unsigned char kRootCertForProd[] = { 0x0a, 0x9c, 0x03, 0x08, 0x00, 0x12, 0x01, 0x00, 0x18, 0xdd, 0x94, 0x88, 0x8b, 0x05, 0x22, 0x8e, 0x03, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, @@ -143,17 +144,17 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { SignedDrmCertificate signed_root_cert; if (!signed_root_cert.ParseFromString(root_cert_str)) { LOGE("Failed to deserialize signed root certificate"); - return DEVICE_CERTIFICATE_ERROR_1; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1); } DrmCertificate root_cert; if (!root_cert.ParseFromString(signed_root_cert.drm_certificate())) { LOGE("Failed to deserialize root certificate"); - return DEVICE_CERTIFICATE_ERROR_1; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1); } RsaPublicKey root_key; if (!root_key.Init(root_cert.public_key())) { LOGE("Failed to load root certificate public key"); - return DEVICE_CERTIFICATE_ERROR_1; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1); } // Load the provided service certificate. @@ -161,7 +162,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { SignedDrmCertificate signed_service_cert; if (!signed_service_cert.ParseFromString(certificate)) { LOGE("Failed to parse signed service certificate"); - return DEVICE_CERTIFICATE_ERROR_2; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2); } #ifdef ACCEPT_TEST_CERT @@ -170,14 +171,14 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { if (!root_key.VerifySignature(signed_service_cert.drm_certificate(), signed_service_cert.signature())) { LOGE("Failed to verify service certificate signature"); - return DEVICE_CERTIFICATE_ERROR_3; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_3); } #endif DrmCertificate service_cert; if (!service_cert.ParseFromString(signed_service_cert.drm_certificate())) { LOGE("Failed to parse service certificate"); - return DEVICE_CERTIFICATE_ERROR_2; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2); } if (service_cert.type() != video_widevine::DrmCertificate_Type_SERVICE) { LOGE( @@ -185,7 +186,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { "type = %d, expected_type = %d", static_cast(service_cert.type()), static_cast(video_widevine::DrmCertificate_Type_SERVICE)); - return DEVICE_CERTIFICATE_ERROR_3; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_3); } // Service certificate passes all checks - set up its RSA public key. @@ -193,7 +194,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { if (!public_key_->Init(service_cert.public_key())) { public_key_.reset(); LOGE("Failed to load service certificate public key"); - return DEVICE_CERTIFICATE_ERROR_2; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2); } // Have service certificate and its public key - keep relevant fields. @@ -202,67 +203,56 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { provider_id_ = service_cert.provider_id(); has_certificate_ = true; - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType ServiceCertificate::VerifySignedMessage( const std::string& message, const std::string& signature) const { if (!public_key_) { LOGE("Service certificate not set"); - return DEVICE_CERTIFICATE_ERROR_4; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_4); } if (!public_key_->VerifySignature(message, signature)) - return CLIENT_ID_RSA_ENCRYPT_ERROR; // TODO(tinskip): Need new error code. + return CdmResponseType( + CLIENT_ID_RSA_ENCRYPT_ERROR); // TODO(rfrias): Need new error code. - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType ServiceCertificate::EncryptRsaOaep( const std::string& plaintext, std::string* ciphertext) const { if (!public_key_) { LOGE("Service certificate not set"); - return DEVICE_CERTIFICATE_ERROR_4; + return CdmResponseType(DEVICE_CERTIFICATE_ERROR_4); } if (!public_key_->Encrypt(plaintext, ciphertext)) - return CLIENT_ID_RSA_ENCRYPT_ERROR; + return CdmResponseType(CLIENT_ID_RSA_ENCRYPT_ERROR); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } CdmResponseType ServiceCertificate::EncryptClientId( - CryptoSession* crypto_session, const ClientIdentification* clear_client_id, + CryptoSession* /* crypto_session */, + const ClientIdentification* clear_client_id, EncryptedClientIdentification* encrypted_client_id) const { encrypted_client_id->set_provider_id(provider_id_); encrypted_client_id->set_service_certificate_serial_number(serial_number_); - std::string iv(KEY_IV_SIZE, 0); - std::string key(SERVICE_KEY_SIZE, 0); - - CdmResponseType status = crypto_session->GetRandom( - key.size(), reinterpret_cast(&key[0])); - - if (status != NO_ERROR) { - LOGE("GetRandom failed for key: status = %d", static_cast(status)); - return (status == RANDOM_GENERATION_ERROR) ? CLIENT_ID_GENERATE_RANDOM_ERROR - : status; - } - - status = - crypto_session->GetRandom(iv.size(), reinterpret_cast(&iv[0])); - - if (status != NO_ERROR) { - LOGE("GetRandom failed for IV: status = %d", static_cast(status)); - return (status == RANDOM_GENERATION_ERROR) ? CLIENT_ID_GENERATE_RANDOM_ERROR - : status; + std::string iv = wvutil::CdmRandom::RandomData(KEY_IV_SIZE); + std::string key = wvutil::CdmRandom::RandomData(SERVICE_KEY_SIZE); + if (key.length() != SERVICE_KEY_SIZE || iv.length() != KEY_IV_SIZE) { + LOGE("RandomData failed for key or iv."); + return CdmResponseType(CLIENT_ID_GENERATE_RANDOM_ERROR); } std::string id, enc_id, enc_key; clear_client_id->SerializeToString(&id); AesCbcKey aes; - if (!aes.Init(key)) return CLIENT_ID_AES_INIT_ERROR; - if (!aes.Encrypt(id, &enc_id, &iv)) return CLIENT_ID_AES_ENCRYPT_ERROR; + if (!aes.Init(key)) return CdmResponseType(CLIENT_ID_AES_INIT_ERROR); + if (!aes.Encrypt(id, &enc_id, &iv)) + return CdmResponseType(CLIENT_ID_AES_ENCRYPT_ERROR); CdmResponseType encrypt_result = EncryptRsaOaep(key, &enc_key); if (encrypt_result != NO_ERROR) return encrypt_result; @@ -270,7 +260,7 @@ CdmResponseType ServiceCertificate::EncryptClientId( encrypted_client_id->set_encrypted_client_id_iv(iv); encrypted_client_id->set_encrypted_privacy_key(enc_key); encrypted_client_id->set_encrypted_client_id(enc_id); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } bool ServiceCertificate::GetRequest(CdmKeyMessage* request) { @@ -288,39 +278,39 @@ CdmResponseType ServiceCertificate::ParseResponse(const std::string& response, std::string* certificate) { if (response.empty()) { LOGE("Response is empty"); - return EMPTY_RESPONSE_ERROR_1; + return CdmResponseType(EMPTY_RESPONSE_ERROR_1); } if (certificate == nullptr) { LOGE("Output parameter |certificate| not provided"); - return INVALID_PARAMETERS_ENG_24; + return CdmResponseType(INVALID_PARAMETERS_ENG_24); } SignedMessage signed_response; if (!signed_response.ParseFromString(response)) { LOGE("Failed to parse signed response"); - return PARSE_RESPONSE_ERROR_1; + return CdmResponseType(PARSE_RESPONSE_ERROR_1); } if (signed_response.type() == SignedMessage::ERROR_RESPONSE) { LicenseError license_error; if (!license_error.ParseFromString(signed_response.msg())) { LOGE("Failed to parse license error"); - return PARSE_RESPONSE_ERROR_2; + return CdmResponseType(PARSE_RESPONSE_ERROR_2); } LOGE("Server response contains error: error_code = %d", static_cast(license_error.error_code())); - return PARSE_RESPONSE_ERROR_3; + return CdmResponseType(PARSE_RESPONSE_ERROR_3); } if (signed_response.type() != SignedMessage::SERVICE_CERTIFICATE) { LOGE("Unexpected response type: type = %d, expected_type = %d", static_cast(signed_response.type()), static_cast(SignedMessage::SERVICE_CERTIFICATE)); - return PARSE_RESPONSE_ERROR_4; + return CdmResponseType(PARSE_RESPONSE_ERROR_4); } certificate->assign(signed_response.msg()); - return NO_ERROR; + return CdmResponseType(NO_ERROR); } } // namespace wvcdm diff --git a/core/src/system_id_extractor.cpp b/core/src/system_id_extractor.cpp index 9db41f6d..edfdd3f0 100644 --- a/core/src/system_id_extractor.cpp +++ b/core/src/system_id_extractor.cpp @@ -53,8 +53,7 @@ bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) { crypto_session_->GetProvisioningMethod(security_level_, &type); if (status != NO_ERROR) { LOGE("Failed to get provisioning method: security_level = %s, status = %d", - RequestedSecurityLevelToString(security_level_), - static_cast(status)); + RequestedSecurityLevelToString(security_level_), status.ToInt()); return false; } bool success = false; @@ -122,8 +121,7 @@ bool SystemIdExtractor::ExtractSystemIdProv20(uint32_t* system_id) { } if (status != NO_ERROR) { LOGE("Failed to get keybox data: security_level = %s, status = %d", - RequestedSecurityLevelToString(security_level_), - static_cast(status)); + RequestedSecurityLevelToString(security_level_), status.ToInt()); return false; } if (!ExtractSystemIdFromKeyboxData(key_data, system_id)) { @@ -139,8 +137,7 @@ bool SystemIdExtractor::ExtractSystemIdProv30(uint32_t* system_id) { crypto_session_->GetTokenFromOemCert(security_level_, &oem_cert); if (status != NO_ERROR) { LOGE("Failed to get OEM certificate: security_level = %s, status = %d", - RequestedSecurityLevelToString(security_level_), - static_cast(status)); + RequestedSecurityLevelToString(security_level_), status.ToInt()); return false; } if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) { diff --git a/core/src/wv_cdm_types.cpp b/core/src/wv_cdm_types.cpp index 3ba2d4b4..6015f1f7 100644 --- a/core/src/wv_cdm_types.cpp +++ b/core/src/wv_cdm_types.cpp @@ -4,6 +4,7 @@ #include "wv_cdm_types.h" #include +#include #include "wv_cdm_constants.h" @@ -24,6 +25,33 @@ const char* UnknownValueRep(EnumType value) { } } // namespace +const char* CdmResponseType::GetCodeString() const { + return CdmResponseEnumToString(code_); +} + +bool CdmResponseType::operator==(const CdmResponseType& other) const { + if (code_ != other.code_) return false; + if (!HasOemcResult() || !other.HasOemcResult()) + return !HasOemcResult() && !other.HasOemcResult(); + if (oemc_result_ != other.oemc_result_) return false; + if (!HasCryptoSessionMethod() || !other.HasCryptoSessionMethod()) + return !HasCryptoSessionMethod() && !other.HasCryptoSessionMethod(); + return strcmp(crypto_session_method_, other.crypto_session_method_) == 0; +} + +std::string CdmResponseType::ToString() const { + std::string result = CdmResponseEnumToString(code_); + if (!HasOemcResult()) return result; + result.append(" (oemc_result = "); + result.append(OemCryptoResultToString(oemc_result_)); + if (HasCryptoSessionMethod()) { + result.append(", method = "); + result.append(crypto_session_method_); + } + result.append(")"); + return result; +} + const char* CdmCertificateTypeToString(CdmCertificateType type) { switch (type) { case kCertificateWidevine: @@ -143,6 +171,708 @@ const char* CdmProductionReadinessToString(CdmProductionReadiness readiness) { return UnknownValueRep(readiness); } +const char* CdmResponseEnumToString(CdmResponseEnum cdm_response_enum) { + switch (cdm_response_enum) { + case NO_ERROR: + return "NO_ERROR"; + case UNKNOWN_ERROR: + return "UNKNOWN_ERROR"; + case KEY_ADDED: + return "KEY_ADDED"; + case KEY_ERROR: + return "KEY_ERROR"; + case KEY_MESSAGE: + return "KEY_MESSAGE"; + case NEED_KEY: + return "NEED_KEY"; + case KEY_CANCELED: + return "KEY_CANCELED"; + case NEED_PROVISIONING: + return "NEED_PROVISIONING"; + case DEVICE_REVOKED: + return "DEVICE_REVOKED"; + case INSUFFICIENT_CRYPTO_RESOURCES: + return "INSUFFICIENT_CRYPTO_RESOURCES"; + case ADD_KEY_ERROR: + return "ADD_KEY_ERROR"; + case CERT_PROVISIONING_GET_KEYBOX_ERROR_1: + return "CERT_PROVISIONING_GET_KEYBOX_ERROR_1"; + case CERT_PROVISIONING_INVALID_CERT_TYPE: + return "CERT_PROVISIONING_INVALID_CERT_TYPE"; + case CERT_PROVISIONING_REQUEST_ERROR_1: + return "CERT_PROVISIONING_REQUEST_ERROR_1"; + case CERT_PROVISIONING_NONCE_GENERATION_ERROR: + return "CERT_PROVISIONING_NONCE_GENERATION_ERROR"; + case CERT_PROVISIONING_REQUEST_ERROR_4: + return "CERT_PROVISIONING_REQUEST_ERROR_4"; + case CERT_PROVISIONING_RESPONSE_ERROR_1: + return "CERT_PROVISIONING_RESPONSE_ERROR_1"; + case CERT_PROVISIONING_RESPONSE_ERROR_2: + return "CERT_PROVISIONING_RESPONSE_ERROR_2"; + case CERT_PROVISIONING_RESPONSE_ERROR_3: + return "CERT_PROVISIONING_RESPONSE_ERROR_3"; + case CERT_PROVISIONING_RESPONSE_ERROR_4: + return "CERT_PROVISIONING_RESPONSE_ERROR_4"; + case CERT_PROVISIONING_RESPONSE_ERROR_7: + return "CERT_PROVISIONING_RESPONSE_ERROR_7"; + case CERT_PROVISIONING_RESPONSE_ERROR_8: + return "CERT_PROVISIONING_RESPONSE_ERROR_8"; + case DECRYPT_NOT_READY: + return "DECRYPT_NOT_READY"; + case DEVICE_CERTIFICATE_ERROR_1: + return "DEVICE_CERTIFICATE_ERROR_1"; + case DEVICE_CERTIFICATE_ERROR_2: + return "DEVICE_CERTIFICATE_ERROR_2"; + case DEVICE_CERTIFICATE_ERROR_3: + return "DEVICE_CERTIFICATE_ERROR_3"; + case DEVICE_CERTIFICATE_ERROR_4: + return "DEVICE_CERTIFICATE_ERROR_4"; + case EMPTY_KEY_DATA_1: + return "EMPTY_KEY_DATA_1"; + case EMPTY_KEY_DATA_2: + return "EMPTY_KEY_DATA_2"; + case EMPTY_KEYSET_ID: + return "EMPTY_KEYSET_ID"; + case EMPTY_KEYSET_ID_ENG_1: + return "EMPTY_KEYSET_ID_ENG_1"; + case EMPTY_KEYSET_ID_ENG_2: + return "EMPTY_KEYSET_ID_ENG_2"; + case EMPTY_KEYSET_ID_ENG_3: + return "EMPTY_KEYSET_ID_ENG_3"; + case EMPTY_KEYSET_ID_ENG_4: + return "EMPTY_KEYSET_ID_ENG_4"; + case EMPTY_LICENSE_RENEWAL: + return "EMPTY_LICENSE_RENEWAL"; + case EMPTY_LICENSE_RESPONSE_1: + return "EMPTY_LICENSE_RESPONSE_1"; + case EMPTY_LICENSE_RESPONSE_2: + return "EMPTY_LICENSE_RESPONSE_2"; + case EMPTY_PROVISIONING_CERTIFICATE_1: + return "EMPTY_PROVISIONING_CERTIFICATE_1"; + case EMPTY_PROVISIONING_RESPONSE: + return "EMPTY_PROVISIONING_RESPONSE"; + case EMPTY_SESSION_ID: + return "EMPTY_SESSION_ID"; + case GENERATE_DERIVED_KEYS_ERROR: + return "GENERATE_DERIVED_KEYS_ERROR"; + case LICENSE_RENEWAL_NONCE_GENERATION_ERROR: + return "LICENSE_RENEWAL_NONCE_GENERATION_ERROR"; + case GENERATE_USAGE_REPORT_ERROR: + return "GENERATE_USAGE_REPORT_ERROR"; + case GET_LICENSE_ERROR: + return "GET_LICENSE_ERROR"; + case GET_RELEASED_LICENSE_ERROR: + return "GET_RELEASED_LICENSE_ERROR"; + case GET_USAGE_INFO_ERROR_1: + return "GET_USAGE_INFO_ERROR_1"; + case GET_USAGE_INFO_ERROR_2: + return "GET_USAGE_INFO_ERROR_2"; + case GET_USAGE_INFO_ERROR_3: + return "GET_USAGE_INFO_ERROR_3"; + case GET_USAGE_INFO_ERROR_4: + return "GET_USAGE_INFO_ERROR_4"; + case INIT_DATA_NOT_FOUND: + return "INIT_DATA_NOT_FOUND"; + case INVALID_DECRYPT_PARAMETERS_ENG_1: + return "INVALID_DECRYPT_PARAMETERS_ENG_1"; + case INVALID_DECRYPT_PARAMETERS_ENG_2: + return "INVALID_DECRYPT_PARAMETERS_ENG_2"; + case INVALID_DECRYPT_PARAMETERS_ENG_3: + return "INVALID_DECRYPT_PARAMETERS_ENG_3"; + case INVALID_DECRYPT_PARAMETERS_ENG_4: + return "INVALID_DECRYPT_PARAMETERS_ENG_4"; + case INVALID_DEVICE_CERTIFICATE_TYPE: + return "INVALID_DEVICE_CERTIFICATE_TYPE"; + case INVALID_KEY_SYSTEM: + return "INVALID_KEY_SYSTEM"; + case INVALID_LICENSE_RESPONSE: + return "INVALID_LICENSE_RESPONSE"; + case INVALID_LICENSE_TYPE: + return "INVALID_LICENSE_TYPE"; + case PARAMETER_NULL: + return "PARAMETER_NULL"; + case INVALID_PARAMETERS_LIC_1: + return "INVALID_PARAMETERS_LIC_1"; + case INVALID_PARAMETERS_LIC_2: + return "INVALID_PARAMETERS_LIC_2"; + case INVALID_PROVISIONING_PARAMETERS_1: + return "INVALID_PROVISIONING_PARAMETERS_1"; + case INVALID_PROVISIONING_PARAMETERS_2: + return "INVALID_PROVISIONING_PARAMETERS_2"; + case INVALID_PROVISIONING_REQUEST_PARAM_1: + return "INVALID_PROVISIONING_REQUEST_PARAM_1"; + case INVALID_PROVISIONING_REQUEST_PARAM_2: + return "INVALID_PROVISIONING_REQUEST_PARAM_2"; + case INVALID_QUERY_KEY: + return "INVALID_QUERY_KEY"; + case INVALID_SESSION_ID: + return "INVALID_SESSION_ID"; + case KEY_REQUEST_ERROR_1: + return "KEY_REQUEST_ERROR_1"; + case KEY_SIZE_ERROR_1: + return "KEY_SIZE_ERROR_1"; + case KEYSET_ID_NOT_FOUND_1: + return "KEYSET_ID_NOT_FOUND_1"; + case KEYSET_ID_NOT_FOUND_2: + return "KEYSET_ID_NOT_FOUND_2"; + case KEYSET_ID_NOT_FOUND_3: + return "KEYSET_ID_NOT_FOUND_3"; + case LICENSE_ID_NOT_FOUND: + return "LICENSE_ID_NOT_FOUND"; + case LICENSE_PARSER_INIT_ERROR: + return "LICENSE_PARSER_INIT_ERROR"; + case LICENSE_PARSER_NOT_INITIALIZED_1: + return "LICENSE_PARSER_NOT_INITIALIZED_1"; + case LICENSE_PARSER_NOT_INITIALIZED_2: + return "LICENSE_PARSER_NOT_INITIALIZED_2"; + case LICENSE_PARSER_NOT_INITIALIZED_3: + return "LICENSE_PARSER_NOT_INITIALIZED_3"; + case LICENSE_RESPONSE_NOT_SIGNED: + return "LICENSE_RESPONSE_NOT_SIGNED"; + case LICENSE_RESPONSE_PARSE_ERROR_1: + return "LICENSE_RESPONSE_PARSE_ERROR_1"; + case LICENSE_RESPONSE_PARSE_ERROR_2: + return "LICENSE_RESPONSE_PARSE_ERROR_2"; + case LICENSE_RESPONSE_PARSE_ERROR_3: + return "LICENSE_RESPONSE_PARSE_ERROR_3"; + case LOAD_KEY_ERROR: + return "LOAD_KEY_ERROR"; + case NO_CONTENT_KEY: + return "NO_CONTENT_KEY"; + case REFRESH_KEYS_ERROR: + return "REFRESH_KEYS_ERROR"; + case REMOVE_ALL_USAGE_INFO_ERROR_1: + return "REMOVE_ALL_USAGE_INFO_ERROR_1"; + case REMOVE_ALL_USAGE_INFO_ERROR_2: + return "REMOVE_ALL_USAGE_INFO_ERROR_2"; + case RELEASE_KEY_ERROR: + return "RELEASE_KEY_ERROR"; + case RELEASE_KEY_REQUEST_ERROR: + return "RELEASE_KEY_REQUEST_ERROR"; + case RELEASE_LICENSE_ERROR_1: + return "RELEASE_LICENSE_ERROR_1"; + case RELEASE_LICENSE_ERROR_2: + return "RELEASE_LICENSE_ERROR_2"; + case RELEASE_USAGE_INFO_ERROR: + return "RELEASE_USAGE_INFO_ERROR"; + case RENEW_KEY_ERROR_1: + return "RENEW_KEY_ERROR_1"; + case RENEW_KEY_ERROR_2: + return "RENEW_KEY_ERROR_2"; + case RESTORE_OFFLINE_LICENSE_ERROR_2: + return "RESTORE_OFFLINE_LICENSE_ERROR_2"; + case NOT_INITIALIZED_ERROR: + return "NOT_INITIALIZED_ERROR"; + case REINIT_ERROR: + return "REINIT_ERROR"; + case SESSION_NOT_FOUND_1: + return "SESSION_NOT_FOUND_1"; + case SESSION_NOT_FOUND_2: + return "SESSION_NOT_FOUND_2"; + case SESSION_NOT_FOUND_3: + return "SESSION_NOT_FOUND_3"; + case SESSION_NOT_FOUND_4: + return "SESSION_NOT_FOUND_4"; + case SESSION_NOT_FOUND_5: + return "SESSION_NOT_FOUND_5"; + case SESSION_NOT_FOUND_6: + return "SESSION_NOT_FOUND_6"; + case SESSION_NOT_FOUND_7: + return "SESSION_NOT_FOUND_7"; + case SESSION_NOT_FOUND_8: + return "SESSION_NOT_FOUND_8"; + case SESSION_NOT_FOUND_9: + return "SESSION_NOT_FOUND_9"; + case SESSION_NOT_FOUND_10: + return "SESSION_NOT_FOUND_10"; + case SESSION_NOT_FOUND_FOR_DECRYPT: + return "SESSION_NOT_FOUND_FOR_DECRYPT"; + case SESSION_KEYS_NOT_FOUND: + return "SESSION_KEYS_NOT_FOUND"; + case SIGNATURE_NOT_FOUND: + return "SIGNATURE_NOT_FOUND"; + case STORE_LICENSE_ERROR_1: + return "STORE_LICENSE_ERROR_1"; + case STORE_LICENSE_ERROR_2: + return "STORE_LICENSE_ERROR_2"; + case STORE_USAGE_INFO_ERROR: + return "STORE_USAGE_INFO_ERROR"; + case UNPROVISION_ERROR_1: + return "UNPROVISION_ERROR_1"; + case UNPROVISION_ERROR_2: + return "UNPROVISION_ERROR_2"; + case UNPROVISION_ERROR_3: + return "UNPROVISION_ERROR_3"; + case UNPROVISION_ERROR_4: + return "UNPROVISION_ERROR_4"; + case UNSUPPORTED_INIT_DATA: + return "UNSUPPORTED_INIT_DATA"; + case USAGE_INFO_NOT_FOUND: + return "USAGE_INFO_NOT_FOUND"; + case PARSE_SERVICE_CERTIFICATE_ERROR: + return "PARSE_SERVICE_CERTIFICATE_ERROR"; + case CLIENT_ID_GENERATE_RANDOM_ERROR: + return "CLIENT_ID_GENERATE_RANDOM_ERROR"; + case CLIENT_ID_AES_INIT_ERROR: + return "CLIENT_ID_AES_INIT_ERROR"; + case CLIENT_ID_AES_ENCRYPT_ERROR: + return "CLIENT_ID_AES_ENCRYPT_ERROR"; + case CLIENT_ID_RSA_INIT_ERROR: + return "CLIENT_ID_RSA_INIT_ERROR"; + case CLIENT_ID_RSA_ENCRYPT_ERROR: + return "CLIENT_ID_RSA_ENCRYPT_ERROR"; + case LICENSE_PARSER_NOT_INITIALIZED_4: + return "LICENSE_PARSER_NOT_INITIALIZED_4"; + case INVALID_PARAMETERS_LIC_3: + return "INVALID_PARAMETERS_LIC_3"; + case INVALID_PARAMETERS_LIC_4: + return "INVALID_PARAMETERS_LIC_4"; + case INVALID_PARAMETERS_LIC_6: + return "INVALID_PARAMETERS_LIC_6"; + case INVALID_PARAMETERS_LIC_7: + return "INVALID_PARAMETERS_LIC_7"; + case LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR: + return "LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR"; + case CENC_INIT_DATA_UNAVAILABLE: + return "CENC_INIT_DATA_UNAVAILABLE"; + case PREPARE_CENC_CONTENT_ID_FAILED: + return "PREPARE_CENC_CONTENT_ID_FAILED"; + case WEBM_INIT_DATA_UNAVAILABLE: + return "WEBM_INIT_DATA_UNAVAILABLE"; + case PREPARE_WEBM_CONTENT_ID_FAILED: + return "PREPARE_WEBM_CONTENT_ID_FAILED"; + case UNSUPPORTED_INIT_DATA_FORMAT: + return "UNSUPPORTED_INIT_DATA_FORMAT"; + case LICENSE_REQUEST_NONCE_GENERATION_ERROR: + return "LICENSE_REQUEST_NONCE_GENERATION_ERROR"; + case EMPTY_LICENSE_REQUEST: + return "EMPTY_LICENSE_REQUEST"; + case SECURE_BUFFER_REQUIRED: + return "SECURE_BUFFER_REQUIRED"; + case DUPLICATE_SESSION_ID_SPECIFIED: + return "DUPLICATE_SESSION_ID_SPECIFIED"; + case LICENSE_RENEWAL_PROHIBITED: + return "LICENSE_RENEWAL_PROHIBITED"; + case EMPTY_PROVISIONING_CERTIFICATE_2: + return "EMPTY_PROVISIONING_CERTIFICATE_2"; + case OFFLINE_LICENSE_PROHIBITED: + return "OFFLINE_LICENSE_PROHIBITED"; + case STORAGE_PROHIBITED: + return "STORAGE_PROHIBITED"; + case EMPTY_KEYSET_ID_ENG_5: + return "EMPTY_KEYSET_ID_ENG_5"; + case SESSION_NOT_FOUND_11: + return "SESSION_NOT_FOUND_11"; + case LOAD_USAGE_INFO_FILE_ERROR: + return "LOAD_USAGE_INFO_FILE_ERROR"; + case LOAD_USAGE_INFO_MISSING: + return "LOAD_USAGE_INFO_MISSING"; + case SESSION_FILE_HANDLE_INIT_ERROR: + return "SESSION_FILE_HANDLE_INIT_ERROR"; + case INCORRECT_CRYPTO_MODE: + return "INCORRECT_CRYPTO_MODE"; + case INVALID_PARAMETERS_ENG_5: + return "INVALID_PARAMETERS_ENG_5"; + case DECRYPT_ERROR: + return "DECRYPT_ERROR"; + case INSUFFICIENT_OUTPUT_PROTECTION: + return "INSUFFICIENT_OUTPUT_PROTECTION"; + case SESSION_NOT_FOUND_12: + return "SESSION_NOT_FOUND_12"; + case KEY_NOT_FOUND_1: + return "KEY_NOT_FOUND_1"; + case KEY_NOT_FOUND_2: + return "KEY_NOT_FOUND_2"; + case KEY_CONFLICT_1: + return "KEY_CONFLICT_1"; + case SESSION_NOT_FOUND_13: + return "SESSION_NOT_FOUND_13"; + case SESSION_NOT_FOUND_14: + return "SESSION_NOT_FOUND_14"; + case SESSION_NOT_FOUND_15: + return "SESSION_NOT_FOUND_15"; + case SESSION_NOT_FOUND_16: + return "SESSION_NOT_FOUND_16"; + case KEY_NOT_FOUND_3: + return "KEY_NOT_FOUND_3"; + case KEY_NOT_FOUND_4: + return "KEY_NOT_FOUND_4"; + case KEY_NOT_FOUND_5: + return "KEY_NOT_FOUND_5"; + case KEY_NOT_FOUND_6: + return "KEY_NOT_FOUND_6"; + case INVALID_SESSION_1: + return "INVALID_SESSION_1"; + case NO_DEVICE_KEY_1: + return "NO_DEVICE_KEY_1"; + case NO_CONTENT_KEY_2: + return "NO_CONTENT_KEY_2"; + case INVALID_PARAMETERS_ENG_13: + return "INVALID_PARAMETERS_ENG_13"; + case INVALID_PARAMETERS_ENG_14: + return "INVALID_PARAMETERS_ENG_14"; + case INVALID_PARAMETERS_ENG_15: + return "INVALID_PARAMETERS_ENG_15"; + case INVALID_PARAMETERS_ENG_16: + return "INVALID_PARAMETERS_ENG_16"; + case CLIENT_IDENTIFICATION_TOKEN_ERROR_1: + return "CLIENT_IDENTIFICATION_TOKEN_ERROR_1"; + case ANALOG_OUTPUT_ERROR: + return "ANALOG_OUTPUT_ERROR"; + case UNKNOWN_SELECT_KEY_ERROR_1: + return "UNKNOWN_SELECT_KEY_ERROR_1"; + case UNKNOWN_SELECT_KEY_ERROR_2: + return "UNKNOWN_SELECT_KEY_ERROR_2"; + case CREATE_USAGE_TABLE_ERROR: + return "CREATE_USAGE_TABLE_ERROR"; + case LOAD_USAGE_HEADER_GENERATION_SKEW: + return "LOAD_USAGE_HEADER_GENERATION_SKEW"; + case LOAD_USAGE_HEADER_SIGNATURE_FAILURE: + return "LOAD_USAGE_HEADER_SIGNATURE_FAILURE"; + case LOAD_USAGE_HEADER_BAD_MAGIC: + return "LOAD_USAGE_HEADER_BAD_MAGIC"; + case LOAD_USAGE_HEADER_UNKNOWN_ERROR: + return "LOAD_USAGE_HEADER_UNKNOWN_ERROR"; + case CREATE_USAGE_ENTRY_UNKNOWN_ERROR: + return "CREATE_USAGE_ENTRY_UNKNOWN_ERROR"; + case LOAD_USAGE_ENTRY_GENERATION_SKEW: + return "LOAD_USAGE_ENTRY_GENERATION_SKEW"; + case LOAD_USAGE_ENTRY_SIGNATURE_FAILURE: + return "LOAD_USAGE_ENTRY_SIGNATURE_FAILURE"; + case LOAD_USAGE_ENTRY_UNKNOWN_ERROR: + return "LOAD_USAGE_ENTRY_UNKNOWN_ERROR"; + case UPDATE_USAGE_ENTRY_UNKNOWN_ERROR: + return "UPDATE_USAGE_ENTRY_UNKNOWN_ERROR"; + case SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR: + return "SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR"; + case MOVE_USAGE_ENTRY_UNKNOWN_ERROR: + return "MOVE_USAGE_ENTRY_UNKNOWN_ERROR"; + case COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR: + return "COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR"; + case INVALID_PARAMETERS_ENG_22: + return "INVALID_PARAMETERS_ENG_22"; + case LIST_LICENSE_ERROR_1: + return "LIST_LICENSE_ERROR_1"; + case LIST_LICENSE_ERROR_2: + return "LIST_LICENSE_ERROR_2"; + case INVALID_PARAMETERS_ENG_23: + return "INVALID_PARAMETERS_ENG_23"; + case USAGE_INFORMATION_SUPPORT_FAILED: + return "USAGE_INFORMATION_SUPPORT_FAILED"; + case USAGE_SUPPORT_GET_API_FAILED: + return "USAGE_SUPPORT_GET_API_FAILED"; + case UNEXPECTED_EMPTY_USAGE_ENTRY: + return "UNEXPECTED_EMPTY_USAGE_ENTRY"; + case INVALID_USAGE_ENTRY_NUMBER_MODIFICATION: + return "INVALID_USAGE_ENTRY_NUMBER_MODIFICATION"; + case USAGE_INVALID_NEW_ENTRY: + return "USAGE_INVALID_NEW_ENTRY"; + case USAGE_INVALID_PARAMETERS_1: + return "USAGE_INVALID_PARAMETERS_1"; + case USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED: + return "USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED"; + case USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED: + return "USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED"; + case USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE: + return "USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE"; + case USAGE_ENTRY_NUMBER_MISMATCH: + return "USAGE_ENTRY_NUMBER_MISMATCH"; + case USAGE_STORE_LICENSE_FAILED: + return "USAGE_STORE_LICENSE_FAILED"; + case USAGE_STORE_USAGE_INFO_FAILED: + return "USAGE_STORE_USAGE_INFO_FAILED"; + case USAGE_INVALID_LOAD_ENTRY: + return "USAGE_INVALID_LOAD_ENTRY"; + case REMOVE_ALL_USAGE_INFO_ERROR_5: + return "REMOVE_ALL_USAGE_INFO_ERROR_5"; + case RELEASE_USAGE_INFO_FAILED: + return "RELEASE_USAGE_INFO_FAILED"; + case INCORRECT_USAGE_SUPPORT_TYPE_1: + return "INCORRECT_USAGE_SUPPORT_TYPE_1"; + case INCORRECT_USAGE_SUPPORT_TYPE_2: + return "INCORRECT_USAGE_SUPPORT_TYPE_2"; + case KEY_PROHIBITED_FOR_SECURITY_LEVEL: + return "KEY_PROHIBITED_FOR_SECURITY_LEVEL"; + case KEY_NOT_FOUND_IN_SESSION: + return "KEY_NOT_FOUND_IN_SESSION"; + case NO_USAGE_ENTRIES: + return "NO_USAGE_ENTRIES"; + case LIST_USAGE_ERROR_1: + return "LIST_USAGE_ERROR_1"; + case LIST_USAGE_ERROR_2: + return "LIST_USAGE_ERROR_2"; + case DELETE_USAGE_ERROR_1: + return "DELETE_USAGE_ERROR_1"; + case DELETE_USAGE_ERROR_2: + return "DELETE_USAGE_ERROR_2"; + case DELETE_USAGE_ERROR_3: + return "DELETE_USAGE_ERROR_3"; + case PRIVACY_MODE_ERROR_1: + return "PRIVACY_MODE_ERROR_1"; + case PRIVACY_MODE_ERROR_2: + return "PRIVACY_MODE_ERROR_2"; + case PRIVACY_MODE_ERROR_3: + return "PRIVACY_MODE_ERROR_3"; + case EMPTY_RESPONSE_ERROR_1: + return "EMPTY_RESPONSE_ERROR_1"; + case INVALID_PARAMETERS_ENG_24: + return "INVALID_PARAMETERS_ENG_24"; + case PARSE_RESPONSE_ERROR_1: + return "PARSE_RESPONSE_ERROR_1"; + case PARSE_RESPONSE_ERROR_2: + return "PARSE_RESPONSE_ERROR_2"; + case PARSE_RESPONSE_ERROR_3: + return "PARSE_RESPONSE_ERROR_3"; + case PARSE_RESPONSE_ERROR_4: + return "PARSE_RESPONSE_ERROR_4"; + case USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED: + return "USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED"; + case USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED: + return "USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED"; + case USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE: + return "USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE"; + case REMOVE_ALL_USAGE_INFO_ERROR_6: + return "REMOVE_ALL_USAGE_INFO_ERROR_6"; + case REMOVE_ALL_USAGE_INFO_ERROR_7: + return "REMOVE_ALL_USAGE_INFO_ERROR_7"; + case CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE: + return "CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE"; + case LOAD_SYSTEM_ID_ERROR: + return "LOAD_SYSTEM_ID_ERROR"; + case REMOVE_USAGE_INFO_ERROR_1: + return "REMOVE_USAGE_INFO_ERROR_1"; + case REMOVE_USAGE_INFO_ERROR_2: + return "REMOVE_USAGE_INFO_ERROR_2"; + case REMOVE_USAGE_INFO_ERROR_3: + return "REMOVE_USAGE_INFO_ERROR_3"; + case NOT_AN_ENTITLEMENT_SESSION: + return "NOT_AN_ENTITLEMENT_SESSION"; + case NO_MATCHING_ENTITLEMENT_KEY: + return "NO_MATCHING_ENTITLEMENT_KEY"; + case LOAD_ENTITLED_CONTENT_KEYS_ERROR: + return "LOAD_ENTITLED_CONTENT_KEYS_ERROR"; + case GET_PROVISIONING_METHOD_ERROR: + return "GET_PROVISIONING_METHOD_ERROR"; + case INVALID_SESSION_2: + return "INVALID_SESSION_2"; + case SESSION_NOT_FOUND_18: + return "SESSION_NOT_FOUND_18"; + case NO_CONTENT_KEY_3: + return "NO_CONTENT_KEY_3"; + case DEVICE_CANNOT_REPROVISION: + return "DEVICE_CANNOT_REPROVISION"; + case SESSION_NOT_FOUND_19: + return "SESSION_NOT_FOUND_19"; + case KEY_SIZE_ERROR_2: + return "KEY_SIZE_ERROR_2"; + case SET_DECRYPT_HASH_ERROR: + return "SET_DECRYPT_HASH_ERROR"; + case GET_DECRYPT_HASH_ERROR: + return "GET_DECRYPT_HASH_ERROR"; + case SESSION_NOT_FOUND_20: + return "SESSION_NOT_FOUND_20"; + case INVALID_DECRYPT_HASH_FORMAT: + return "INVALID_DECRYPT_HASH_FORMAT"; + case EMPTY_LICENSE_REQUEST_2: + return "EMPTY_LICENSE_REQUEST_2"; + case EMPTY_LICENSE_REQUEST_3: + return "EMPTY_LICENSE_REQUEST_3"; + case EMPTY_LICENSE_RESPONSE_3: + return "EMPTY_LICENSE_RESPONSE_3"; + case EMPTY_LICENSE_RESPONSE_4: + return "EMPTY_LICENSE_RESPONSE_4"; + case PARSE_REQUEST_ERROR_1: + return "PARSE_REQUEST_ERROR_1"; + case PARSE_REQUEST_ERROR_2: + return "PARSE_REQUEST_ERROR_2"; + case INVALID_LICENSE_REQUEST_TYPE_1: + return "INVALID_LICENSE_REQUEST_TYPE_1"; + case INVALID_LICENSE_REQUEST_TYPE_2: + return "INVALID_LICENSE_REQUEST_TYPE_2"; + case LICENSE_RESPONSE_PARSE_ERROR_4: + return "LICENSE_RESPONSE_PARSE_ERROR_4"; + case LICENSE_RESPONSE_PARSE_ERROR_5: + return "LICENSE_RESPONSE_PARSE_ERROR_5"; + case INVALID_LICENSE_TYPE_2: + return "INVALID_LICENSE_TYPE_2"; + case SIGNATURE_NOT_FOUND_2: + return "SIGNATURE_NOT_FOUND_2"; + case SESSION_KEYS_NOT_FOUND_2: + return "SESSION_KEYS_NOT_FOUND_2"; + case GET_OFFLINE_LICENSE_STATE_ERROR_1: + return "GET_OFFLINE_LICENSE_STATE_ERROR_1"; + case GET_OFFLINE_LICENSE_STATE_ERROR_2: + return "GET_OFFLINE_LICENSE_STATE_ERROR_2"; + case REMOVE_OFFLINE_LICENSE_ERROR_1: + return "REMOVE_OFFLINE_LICENSE_ERROR_1"; + case REMOVE_OFFLINE_LICENSE_ERROR_2: + return "REMOVE_OFFLINE_LICENSE_ERROR_2"; + case SESSION_NOT_FOUND_21: + return "SESSION_NOT_FOUND_21"; + case OUTPUT_TOO_LARGE_ERROR: + return "OUTPUT_TOO_LARGE_ERROR"; + case SESSION_LOST_STATE_ERROR: + return "SESSION_LOST_STATE_ERROR"; + case GENERATE_DERIVED_KEYS_ERROR_2: + return "GENERATE_DERIVED_KEYS_ERROR_2"; + case LOAD_DEVICE_RSA_KEY_ERROR: + return "LOAD_DEVICE_RSA_KEY_ERROR"; + case NONCE_GENERATION_ERROR: + return "NONCE_GENERATION_ERROR"; + case GENERATE_SIGNATURE_ERROR: + return "GENERATE_SIGNATURE_ERROR"; + case UNKNOWN_CLIENT_TOKEN_TYPE: + return "UNKNOWN_CLIENT_TOKEN_TYPE"; + case DEACTIVATE_USAGE_ENTRY_ERROR: + return "DEACTIVATE_USAGE_ENTRY_ERROR"; + case SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY: + return "SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY"; + case SYSTEM_INVALIDATED_ERROR: + return "SYSTEM_INVALIDATED_ERROR"; + case OPEN_CRYPTO_SESSION_ERROR: + return "OPEN_CRYPTO_SESSION_ERROR"; + case LOAD_SRM_ERROR: + return "LOAD_SRM_ERROR"; + case RANDOM_GENERATION_ERROR: + return "RANDOM_GENERATION_ERROR"; + case CRYPTO_SESSION_NOT_INITIALIZED: + return "CRYPTO_SESSION_NOT_INITIALIZED"; + case GET_DEVICE_ID_ERROR: + return "GET_DEVICE_ID_ERROR"; + case GET_TOKEN_FROM_OEM_CERT_ERROR: + return "GET_TOKEN_FROM_OEM_CERT_ERROR"; + case CRYPTO_SESSION_NOT_OPEN: + return "CRYPTO_SESSION_NOT_OPEN"; + case GET_TOKEN_FROM_KEYBOX_ERROR: + return "GET_TOKEN_FROM_KEYBOX_ERROR"; + case KEYBOX_TOKEN_TOO_SHORT: + return "KEYBOX_TOKEN_TOO_SHORT"; + case EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR: + return "EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR"; + case RSA_SIGNATURE_GENERATION_ERROR: + return "RSA_SIGNATURE_GENERATION_ERROR"; + case GET_HDCP_CAPABILITY_FAILED: + return "GET_HDCP_CAPABILITY_FAILED"; + case GET_NUMBER_OF_OPEN_SESSIONS_ERROR: + return "GET_NUMBER_OF_OPEN_SESSIONS_ERROR"; + case GET_MAX_NUMBER_OF_OPEN_SESSIONS_ERROR: + return "GET_MAX_NUMBER_OF_OPEN_SESSIONS_ERROR"; + case NOT_IMPLEMENTED_ERROR: + return "NOT_IMPLEMENTED_ERROR"; + case GET_SRM_VERSION_ERROR: + return "GET_SRM_VERSION_ERROR"; + case REWRAP_DEVICE_RSA_KEY_ERROR: + return "REWRAP_DEVICE_RSA_KEY_ERROR"; + case LOAD_PROVISIONING_ERROR: + return "LOAD_PROVISIONING_ERROR"; + case INVALID_SRM_LIST: + return "INVALID_SRM_LIST"; + case KEYSET_ID_NOT_FOUND_4: + return "KEYSET_ID_NOT_FOUND_4"; + case SESSION_NOT_FOUND_22: + return "SESSION_NOT_FOUND_22"; + case USAGE_INVALID_PARAMETERS_2: + return "USAGE_INVALID_PARAMETERS_2"; + case CORE_MESSAGE_NOT_FOUND: + return "CORE_MESSAGE_NOT_FOUND"; + case LOAD_LICENSE_ERROR: + return "LOAD_LICENSE_ERROR"; + case LOAD_RENEWAL_ERROR: + return "LOAD_RENEWAL_ERROR"; + case CANNOT_DECRYPT_ZERO_SAMPLES: + return "CANNOT_DECRYPT_ZERO_SAMPLES"; + case CANNOT_DECRYPT_ZERO_SUBSAMPLES: + return "CANNOT_DECRYPT_ZERO_SUBSAMPLES"; + case SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH: + return "SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH"; + case INVALID_IV_SIZE: + return "INVALID_IV_SIZE"; + case PROVISIONING_NOT_ALLOWED_FOR_ATSC: + return "PROVISIONING_NOT_ALLOWED_FOR_ATSC"; + case MOVE_USAGE_ENTRY_DESTINATION_IN_USE: + return "MOVE_USAGE_ENTRY_DESTINATION_IN_USE"; + case SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE: + return "SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE"; + case LICENSE_USAGE_ENTRY_MISSING: + return "LICENSE_USAGE_ENTRY_MISSING"; + case LOAD_USAGE_ENTRY_INVALID_SESSION: + return "LOAD_USAGE_ENTRY_INVALID_SESSION"; + case RESTORE_OFFLINE_LICENSE_ERROR_3: + return "RESTORE_OFFLINE_LICENSE_ERROR_3"; + case NO_SRM_VERSION: + return "NO_SRM_VERSION"; + case SESSION_NOT_FOUND_23: + return "SESSION_NOT_FOUND_23"; + case CERT_PROVISIONING_RESPONSE_ERROR_9: + return "CERT_PROVISIONING_RESPONSE_ERROR_9"; + case CERT_PROVISIONING_RESPONSE_ERROR_10: + return "CERT_PROVISIONING_RESPONSE_ERROR_10"; + case CLIENT_TOKEN_NOT_SET: + return "CLIENT_TOKEN_NOT_SET"; + case USAGE_ENTRY_ALREADY_LOADED: + return "USAGE_ENTRY_ALREADY_LOADED"; + case PARSE_OKP_RESPONSE_ERROR: + return "PARSE_OKP_RESPONSE_ERROR"; + case OKP_ALREADY_PROVISIONED: + return "OKP_ALREADY_PROVISIONED"; + case PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR: + return "PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR"; + case GET_BOOT_CERTIFICATE_CHAIN_ERROR: + return "GET_BOOT_CERTIFICATE_CHAIN_ERROR"; + case GENERATE_CERTIFICATE_KEY_PAIR_ERROR: + return "GENERATE_CERTIFICATE_KEY_PAIR_ERROR"; + case GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR: + return "GENERATE_CERTIFICATE_KEY_PAIR_ERROR"; + case LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR: + return "LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR"; + case PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN: + return "PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN"; + case PROVISIONING_4_FILE_SYSTEM_IS_NULL: + return "PROVISIONING_4_FILE_SYSTEM_IS_NULL"; + case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES: + return "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES"; + case PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE: + return "PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE"; + case PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS: + return "PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS"; + case PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE: + return "PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE"; + case PROVISIONING_4_NO_PRIVATE_KEY: + return "PROVISIONING_4_NO_PRIVATE_KEY"; + case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2: + return "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2"; + case PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE: + return "PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE"; + case PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE: + return "PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE"; + case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3: + return "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3"; + case GET_SIGNATURE_HASH_ALGORITHM_ERROR_1: + return "GET_SIGNATURE_HASH_ALGORITHM_ERROR_1"; + case GET_SIGNATURE_HASH_ALGORITHM_ERROR_2: + return "GET_SIGNATURE_HASH_ALGORITHM_ERROR_2"; + case GET_SIGNATURE_HASH_ALGORITHM_ERROR_3: + return "GET_SIGNATURE_HASH_ALGORITHM_ERROR_3"; + case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1: + return "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1"; + case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_2: + return "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_2"; + case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3: + return "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3"; + case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4: + return "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4"; + case STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR: + return "STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR"; + case STORE_ATSC_LICENSE_ERROR: + return "STORE_ATSC_LICENSE_ERROR"; + case SESSION_NOT_FOUND_GENERIC_CRYPTO: + return "SESSION_NOT_FOUND_GENERIC_CRYPTO"; + case SESSION_NOT_FOUND_24: + return "SESSION_NOT_FOUND_24"; + } + return UnknownValueRep(cdm_response_enum); +} + const char* UnknownEnumValueToString(int value) { snprintf(tl_unknown_rep_buf, sizeof(tl_unknown_rep_buf), "", value); @@ -157,4 +887,168 @@ const char* IdPtrToString(const std::string* id) { if (id == nullptr) return kNullIdRep; return id->empty() ? kEmptyIdRep : id->c_str(); } + +const char* OemCryptoResultToString(OEMCryptoResult result) { + switch (result) { + /* OEMCrypto return values */ + case OEMCrypto_SUCCESS: + return "SUCCESS"; + case OEMCrypto_ERROR_INIT_FAILED: + return "ERROR_INIT_FAILED"; + case OEMCrypto_ERROR_TERMINATE_FAILED: + return "ERROR_TERMINATE_FAILED"; + case OEMCrypto_ERROR_OPEN_FAILURE: + return "ERROR_OPEN_FAILURE"; + case OEMCrypto_ERROR_CLOSE_FAILURE: + return "ERROR_CLOSE_FAILURE"; + case OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED: + return "ERROR_ENTER_SECURE_PLAYBACK_FAILED"; + case OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED: + return "ERROR_EXIT_SECURE_PLAYBACK_FAILED"; + case OEMCrypto_ERROR_SHORT_BUFFER: + return "ERROR_SHORT_BUFFER"; + case OEMCrypto_ERROR_NO_DEVICE_KEY: + return "ERROR_NO_DEVICE_KEY"; + case OEMCrypto_ERROR_NO_ASSET_KEY: + return "ERROR_NO_ASSET_KEY"; + case OEMCrypto_ERROR_KEYBOX_INVALID: + return "ERROR_KEYBOX_INVALID"; + case OEMCrypto_ERROR_NO_KEYDATA: + return "ERROR_NO_KEYDATA"; + case OEMCrypto_ERROR_NO_CW: + return "ERROR_NO_CW"; + case OEMCrypto_ERROR_DECRYPT_FAILED: + return "ERROR_DECRYPT_FAILED"; + case OEMCrypto_ERROR_WRITE_KEYBOX: + return "ERROR_WRITE_KEYBOX"; + case OEMCrypto_ERROR_WRAP_KEYBOX: + return "ERROR_WRAP_KEYBOX"; + case OEMCrypto_ERROR_BAD_MAGIC: + return "ERROR_BAD_MAGIC"; + case OEMCrypto_ERROR_BAD_CRC: + return "ERROR_BAD_CRC"; + case OEMCrypto_ERROR_NO_DEVICEID: + return "ERROR_NO_DEVICEID"; + case OEMCrypto_ERROR_RNG_FAILED: + return "ERROR_RNG_FAILED"; + case OEMCrypto_ERROR_RNG_NOT_SUPPORTED: + return "ERROR_RNG_NOT_SUPPORTED"; + case OEMCrypto_ERROR_SETUP: + return "ERROR_SETUP"; + case OEMCrypto_ERROR_OPEN_SESSION_FAILED: + return "ERROR_OPEN_SESSION_FAILED"; + case OEMCrypto_ERROR_CLOSE_SESSION_FAILED: + return "ERROR_CLOSE_SESSION_FAILED"; + case OEMCrypto_ERROR_INVALID_SESSION: + return "ERROR_INVALID_SESSION"; + case OEMCrypto_ERROR_NOT_IMPLEMENTED: + return "ERROR_NOT_IMPLEMENTED"; + case OEMCrypto_ERROR_NO_CONTENT_KEY: + return "ERROR_NO_CONTENT_KEY"; + case OEMCrypto_ERROR_CONTROL_INVALID: + return "ERROR_CONTROL_INVALID"; + case OEMCrypto_ERROR_UNKNOWN_FAILURE: + return "ERROR_UNKNOWN_FAILURE"; + case OEMCrypto_ERROR_INVALID_CONTEXT: + return "ERROR_INVALID_CONTEXT"; + case OEMCrypto_ERROR_SIGNATURE_FAILURE: + return "ERROR_SIGNATURE_FAILURE"; + case OEMCrypto_ERROR_TOO_MANY_SESSIONS: + return "ERROR_TOO_MANY_SESSIONS"; + case OEMCrypto_ERROR_INVALID_NONCE: + return "ERROR_INVALID_NONCE"; + case OEMCrypto_ERROR_TOO_MANY_KEYS: + return "ERROR_TOO_MANY_KEYS"; + case OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED: + return "ERROR_DEVICE_NOT_RSA_PROVISIONED"; + case OEMCrypto_ERROR_INVALID_RSA_KEY: + return "ERROR_INVALID_RSA_KEY"; + case OEMCrypto_ERROR_KEY_EXPIRED: + return "ERROR_KEY_EXPIRED"; + case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: + return "ERROR_INSUFFICIENT_RESOURCES"; + case OEMCrypto_ERROR_INSUFFICIENT_HDCP: + return "ERROR_INSUFFICIENT_HDCP"; + case OEMCrypto_ERROR_BUFFER_TOO_LARGE: + return "ERROR_BUFFER_TOO_LARGE"; + case OEMCrypto_WARNING_GENERATION_SKEW: + return "WARNING_GENERATION_SKEW"; + case OEMCrypto_ERROR_GENERATION_SKEW: + return "ERROR_GENERATION_SKEW"; + case OEMCrypto_LOCAL_DISPLAY_ONLY: + return "LOCAL_DISPLAY_ONLY"; + case OEMCrypto_ERROR_ANALOG_OUTPUT: + return "ERROR_ANALOG_OUTPUT"; + case OEMCrypto_ERROR_WRONG_PST: + return "ERROR_WRONG_PST"; + case OEMCrypto_ERROR_WRONG_KEYS: + return "ERROR_WRONG_KEYS"; + case OEMCrypto_ERROR_MISSING_MASTER: + return "ERROR_MISSING_MASTER"; + case OEMCrypto_ERROR_LICENSE_INACTIVE: + return "ERROR_LICENSE_INACTIVE"; + case OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE: + return "ERROR_ENTRY_NEEDS_UPDATE"; + case OEMCrypto_ERROR_ENTRY_IN_USE: + return "ERROR_ENTRY_IN_USE"; + case OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE: + return "ERROR_USAGE_TABLE_UNRECOVERABLE"; + case OEMCrypto_KEY_NOT_LOADED: + return "KEY_NOT_LOADED"; + case OEMCrypto_KEY_NOT_ENTITLED: + return "KEY_NOT_ENTITLED"; + case OEMCrypto_ERROR_BAD_HASH: + return "ERROR_BAD_HASH"; + case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: + return "ERROR_OUTPUT_TOO_LARGE"; + case OEMCrypto_ERROR_SESSION_LOST_STATE: + return "ERROR_SESSION_LOST_STATE"; + case OEMCrypto_ERROR_SYSTEM_INVALIDATED: + return "ERROR_SYSTEM_INVALIDATED"; + case OEMCrypto_ERROR_LICENSE_RELOAD: + return "ERROR_LICENSE_RELOAD"; + case OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES: + return "ERROR_MULTIPLE_USAGE_ENTRIES"; + case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION: + return "WARNING_MIXED_OUTPUT_PROTECTION"; + case OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION: + return "ERROR_INVALID_ENTITLED_KEY_SESSION"; + case OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING: + return "ERROR_NEEDS_KEYBOX_PROVISIONING"; + case OEMCrypto_ERROR_UNSUPPORTED_CIPHER: + return "ERROR_UNSUPPORTED_CIPHER"; + case OEMCrypto_ERROR_DVR_FORBIDDEN: + return "ERROR_DVR_FORBIDDEN"; + case OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE: + return "ERROR_INSUFFICIENT_PRIVILEGE"; + case OEMCrypto_ERROR_INVALID_KEY: + return "ERROR_INVALID_KEY"; + /* ODK return values */ + case ODK_ERROR_CORE_MESSAGE: + return "ERROR_CORE_MESSAGE"; + case ODK_SET_TIMER: + return "SET_TIMER"; + case ODK_DISABLE_TIMER: + return "DISABLE_TIMER"; + case ODK_TIMER_EXPIRED: + return "TIMER_EXPIRED"; + case ODK_UNSUPPORTED_API: + return "UNSUPPORTED_API"; + case ODK_STALE_RENEWAL: + return "STALE_RENEWAL"; + /* OPK return values */ + case OPK_ERROR_REMOTE_CALL: + return "ERROR_REMOTE_CALL"; + case OPK_ERROR_INCOMPATIBLE_VERSION: + return "ERROR_INCOMPATIBLE_VERSION"; + case OPK_ERROR_NO_PERSISTENT_DATA: + return "ERROR_NO_PERSISTENT_DATA"; + case OPK_ERROR_PREHOOK_FAILURE: + return "ERROR_PREHOOK_FAILURE"; + case OPK_ERROR_POSTHOOK_FAILURE: + return "ERROR_POSTHOOK_FAILURE"; + } + return UnknownValueRep(result); +} + } // namespace wvcdm diff --git a/core/test/Android.bp b/core/test/Android.bp index c170be40..97f23cab 100644 --- a/core/test/Android.bp +++ b/core/test/Android.bp @@ -22,6 +22,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } diff --git a/core/test/cdm_engine_metrics_decorator_unittest.cpp b/core/test/cdm_engine_metrics_decorator_unittest.cpp index b453235f..b325578d 100644 --- a/core/test/cdm_engine_metrics_decorator_unittest.cpp +++ b/core/test/cdm_engine_metrics_decorator_unittest.cpp @@ -20,7 +20,6 @@ #include "wv_metrics.pb.h" using ::testing::_; -using ::testing::ByRef; using ::testing::Eq; using ::testing::Matcher; using ::testing::Return; @@ -95,8 +94,8 @@ class MockCdmEngineImpl : public CdmEngine { (override)); MOCK_METHOD(CdmResponseType, Unprovision, (CdmSecurityLevel), (override)); MOCK_METHOD(CdmResponseType, ListUsageIds, - (const std::string&, CdmSecurityLevel, std::vector*, - std::vector*), + (const std::string&, CdmSecurityLevel, std::vector*, + std::vector*), (override)); MOCK_METHOD(CdmResponseType, RemoveAllUsageInfo, (const std::string&), (override)); @@ -104,8 +103,8 @@ class MockCdmEngineImpl : public CdmEngine { (const std::string&, CdmSecurityLevel), (override)); MOCK_METHOD(CdmResponseType, RemoveUsageInfo, (const std::string&, const CdmSecureStopId&), (override)); - MOCK_METHOD(CdmResponseType, ReleaseUsageInfo, - (const CdmUsageInfoReleaseMessage&), (override)); + MOCK_METHOD(CdmResponseType, ReleaseUsageInfo, (const CdmKeyResponse&), + (override)); MOCK_METHOD(CdmResponseType, DecryptV16, (const CdmSessionId&, const CdmDecryptionParametersV16&), (override)); @@ -137,7 +136,7 @@ TEST_F(WvCdmEngineMetricsImplTest, OpenSession_Overload1) { *test_cdm_metrics_engine_, OpenSession(StrEq("foo"), Eq(&property_set), Matcher(Eq("bar")), Eq(&event_listener))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->OpenSession("foo", &property_set, "bar", @@ -160,7 +159,7 @@ TEST_F(WvCdmEngineMetricsImplTest, OpenSession_Overload2) { EXPECT_CALL(*test_cdm_metrics_engine_, OpenSession(StrEq("foo"), Eq(&property_set), Eq(&event_listener), Matcher(Eq(&session_id)))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->OpenSession( @@ -180,7 +179,7 @@ TEST_F(WvCdmEngineMetricsImplTest, CloseSession) { MockWvCdmEventListener event_listener; EXPECT_CALL(*test_cdm_metrics_engine_, CloseSession(Eq("bar"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->CloseSession("bar")); @@ -201,7 +200,7 @@ TEST_F(WvCdmEngineMetricsImplTest, OpenKeySetSession) { EXPECT_CALL( *test_cdm_metrics_engine_, OpenKeySetSession(Eq("bar"), Eq(&property_set), Eq(&event_listener))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->OpenKeySetSession( "bar", &property_set, &event_listener)); @@ -225,7 +224,7 @@ TEST_F(WvCdmEngineMetricsImplTest, GenerateKeyRequest) { *test_cdm_metrics_engine_, GenerateKeyRequest(Eq("foo"), Eq("bar"), _, Eq(kLicenseTypeStreaming), Eq(app_parameters), Eq(&key_request))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->GenerateKeyRequest( @@ -250,7 +249,7 @@ TEST_F(WvCdmEngineMetricsImplTest, AddKey) { EXPECT_CALL(*test_cdm_metrics_engine_, AddKey(Eq("fake session id"), Eq("fake response"), Eq(&license_type), Eq(&key_set_id))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->AddKey("fake session id", "fake response", @@ -269,7 +268,7 @@ TEST_F(WvCdmEngineMetricsImplTest, AddKey) { TEST_F(WvCdmEngineMetricsImplTest, RestoreKey) { EXPECT_CALL(*test_cdm_metrics_engine_, RestoreKey(Eq("fake session id"), Eq("fake key set id"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->RestoreKey( "fake session id", "fake key set id")); @@ -286,7 +285,7 @@ TEST_F(WvCdmEngineMetricsImplTest, RestoreKey) { TEST_F(WvCdmEngineMetricsImplTest, RemoveKeys) { EXPECT_CALL(*test_cdm_metrics_engine_, RemoveKeys(Eq("fake session id"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->RemoveKeys("fake session id")); @@ -304,7 +303,7 @@ TEST_F(WvCdmEngineMetricsImplTest, QueryKeyStatus) { CdmQueryMap query_response; EXPECT_CALL(*test_cdm_metrics_engine_, QueryKeyStatus(Eq("fake session id"), Eq(&query_response))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->QueryKeyStatus( "fake session id", &query_response)); @@ -328,7 +327,7 @@ TEST_F(WvCdmEngineMetricsImplTest, GetProvisioningRequest) { Eq(kCertificateX509), Eq("fake certificate authority"), Eq("fake service certificate"), Eq(wvcdm::kLevelDefault), Eq(&request), Eq(&default_url))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->GetProvisioningRequest( @@ -356,7 +355,7 @@ TEST_F(WvCdmEngineMetricsImplTest, HandleProvisioningResponse) { HandleProvisioningResponse(Eq("fake provisioning response"), Eq(wvcdm::kLevelDefault), Eq(&cert), Eq(&wrapped_key))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->HandleProvisioningResponse( @@ -376,7 +375,7 @@ TEST_F(WvCdmEngineMetricsImplTest, HandleProvisioningResponse) { TEST_F(WvCdmEngineMetricsImplTest, Unprovision) { EXPECT_CALL(*test_cdm_metrics_engine_, Unprovision(Eq(kSecurityLevelL2))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->Unprovision(kSecurityLevelL2)); @@ -392,7 +391,7 @@ TEST_F(WvCdmEngineMetricsImplTest, Unprovision) { TEST_F(WvCdmEngineMetricsImplTest, RemoveAllUsageInfo_Overload1) { EXPECT_CALL(*test_cdm_metrics_engine_, RemoveAllUsageInfo(Eq("fake app id"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->RemoveAllUsageInfo("fake app id")); @@ -411,7 +410,7 @@ TEST_F(WvCdmEngineMetricsImplTest, RemoveAllUsageInfo_Overload1) { TEST_F(WvCdmEngineMetricsImplTest, RemoveAllUsageInfo_Overload2) { EXPECT_CALL(*test_cdm_metrics_engine_, RemoveAllUsageInfo(Eq("fake app id"), Eq(kSecurityLevelL2))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->RemoveAllUsageInfo( "fake app id", kSecurityLevelL2)); @@ -430,7 +429,7 @@ TEST_F(WvCdmEngineMetricsImplTest, RemoveAllUsageInfo_Overload2) { TEST_F(WvCdmEngineMetricsImplTest, RemoveUsageInfo) { EXPECT_CALL(*test_cdm_metrics_engine_, RemoveUsageInfo(Eq("fake app id"), Eq("fake secure stop id"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->RemoveUsageInfo( "fake app id", "fake secure stop id")); @@ -448,7 +447,7 @@ TEST_F(WvCdmEngineMetricsImplTest, RemoveUsageInfo) { TEST_F(WvCdmEngineMetricsImplTest, ReleaseUsageInfo) { EXPECT_CALL(*test_cdm_metrics_engine_, ReleaseUsageInfo(Eq("fake release message"))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->ReleaseUsageInfo("fake release message")); @@ -464,17 +463,17 @@ TEST_F(WvCdmEngineMetricsImplTest, ReleaseUsageInfo) { } TEST_F(WvCdmEngineMetricsImplTest, ListUsageIds) { - std::vector ksids; - std::vector provider_session_tokens; + std::vector ksids; + std::vector ssids; EXPECT_CALL(*test_cdm_metrics_engine_, ListUsageIds(Eq("fake app id"), Eq(kSecurityLevelL2), Eq(&ksids), - Eq(&provider_session_tokens))) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + Eq(&ssids))) + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); - ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->ListUsageIds( - "fake app id", kSecurityLevelL2, &ksids, - &provider_session_tokens)); + ASSERT_EQ(wvcdm::UNKNOWN_ERROR, + test_cdm_metrics_engine_->ListUsageIds( + "fake app id", kSecurityLevelL2, &ksids, &ssids)); drm_metrics::WvCdmMetrics metrics_proto; test_cdm_metrics_engine_->GetMetricsSnapshot(&metrics_proto); @@ -509,7 +508,7 @@ TEST_F(WvCdmEngineMetricsImplTest, FindSessionForKey) { TEST_F(WvCdmEngineMetricsImplTest, Decrypt) { CdmDecryptionParametersV16 parameters; EXPECT_CALL(*test_cdm_metrics_engine_, DecryptV16(Eq("fake session id"), _)) - .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); ASSERT_EQ(wvcdm::UNKNOWN_ERROR, test_cdm_metrics_engine_->DecryptV16( "fake session id", parameters)); diff --git a/core/test/cdm_engine_test.cpp b/core/test/cdm_engine_test.cpp index 8f266bed..9ab7598b 100644 --- a/core/test/cdm_engine_test.cpp +++ b/core/test/cdm_engine_test.cpp @@ -34,7 +34,6 @@ namespace wvcdm { using drm_metrics::DistributionMetric; using drm_metrics::WvCdmMetrics; -using metrics::EngineMetrics; namespace { @@ -153,7 +152,7 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { WvCdmEngineTest() {} void SetUp() override { - WvCdmTestBase::SetUp(); + WvCdmEnginePreProvTest::SetUp(); session_opened_ = false; WvCdmEnginePreProvTest::OpenSession(); } @@ -275,12 +274,12 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { engine_metrics.Serialize(&metrics_proto); bool has_request_type = false; for (int i = 0; i < metrics_proto.session_metrics_size(); i++) { - WvCdmMetrics::SessionMetrics session_metrics = + const WvCdmMetrics::SessionMetrics& session_metrics = metrics_proto.session_metrics(i); for (int j = 0; j < session_metrics.cdm_session_license_request_latency_ms_size(); j++) { - DistributionMetric latency_distribution = + const DistributionMetric& latency_distribution = session_metrics.cdm_session_license_request_latency_ms(j); if (latency_distribution.attributes().key_request_type() == key_request_type && @@ -362,7 +361,7 @@ TEST_F(WvCdmEngineTest, BaseIsoBmffMessageTest) { TEST_F(WvCdmEngineTest, DISABLED_BaseWebmMessageTest) { // Extract the key ID from the PSSH box. InitializationData extractor(CENC_INIT_DATA_FORMAT, binary_key_id()); - KeyId key_id_unwrapped = extractor.data(); + const KeyId& key_id_unwrapped = extractor.data(); GenerateKeyRequest(key_id_unwrapped, kWebmMimeType); GetKeyRequestResponse(config_.license_server(), config_.client_auth()); } @@ -383,7 +382,7 @@ TEST_F(WvCdmEngineTest, ReturnsLicenseTypeDetailStreaming) { TEST_F(WvCdmEngineTest, DISABLED_NormalDecryptionWebm) { // Extract the key ID from the PSSH box. InitializationData extractor(CENC_INIT_DATA_FORMAT, binary_key_id()); - KeyId key_id_unwrapped = extractor.data(); + const KeyId& key_id_unwrapped = extractor.data(); GenerateKeyRequest(key_id_unwrapped, kWebmMimeType); VerifyNewKeyResponse(config_.license_server(), config_.client_auth()); } diff --git a/core/test/cdm_session_unittest.cpp b/core/test/cdm_session_unittest.cpp index 5ec877dc..0e553f53 100644 --- a/core/test/cdm_session_unittest.cpp +++ b/core/test/cdm_session_unittest.cpp @@ -9,14 +9,15 @@ #include +#include "cdm_usage_table.h" #include "crypto_key.h" #include "crypto_wrapped_key.h" #include "properties.h" #include "service_certificate.h" #include "string_conversions.h" +#include "system_id_extractor.h" #include "test_base.h" #include "test_printers.h" -#include "usage_table_header.h" #include "wv_cdm_constants.h" #include "wv_metrics.pb.h" @@ -29,13 +30,14 @@ using ::testing::NotNull; using ::testing::Return; using ::testing::Sequence; using ::testing::SetArgPointee; -using ::testing::StrEq; namespace wvcdm { namespace { const std::string kEmptyString; +const uint32_t kSystemId = 1234; +const uint32_t kUpdatedSystemId = 5678; const std::string kToken = wvutil::a2bs_hex( "0AAE02080212107E0A892DEEB021E7AF696B938BB1D5B1188B85AD9D05228E023082010A02" @@ -121,15 +123,16 @@ class MockDeviceFiles : public DeviceFiles { (bool, std::string*, CryptoWrappedKey*, std::string*, uint32_t*), (override)); MOCK_METHOD(bool, HasCertificate, (bool), (override)); + MOCK_METHOD(bool, RemoveCertificate, (), (override)); }; -class MockUsageTableHeader : public UsageTableHeader { +class MockCdmUsageTable : public CdmUsageTable { public: - MockUsageTableHeader() : UsageTableHeader() {} + MockCdmUsageTable() : CdmUsageTable() {} MOCK_METHOD(CdmResponseType, UpdateEntry, - (uint32_t usage_entry_number, CryptoSession* crypto_session, - CdmUsageEntry* usage_entry), + (UsageEntryIndex usage_entry_index, CryptoSession* crypto_session, + UsageEntry* usage_entry), (override)); }; @@ -137,10 +140,10 @@ class MockCryptoSession : public TestCryptoSession { public: MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) : TestCryptoSession(crypto_metrics) { - // By default, call the concrete implementation of HasUsageInfoSupport. - ON_CALL(*this, HasUsageInfoSupport(_)) + // By default, call the concrete implementation of HasUsageTableSupport. + ON_CALL(*this, HasUsageTableSupport(_)) .WillByDefault( - Invoke(this, &MockCryptoSession::BaseHasUsageInfoSupport)); + Invoke(this, &MockCryptoSession::BaseHasUsageTableSupport)); } MOCK_METHOD(CdmResponseType, GetProvisioningToken, (std::string*, std::string*), (override)); @@ -151,14 +154,35 @@ class MockCryptoSession : public TestCryptoSession { (override)); MOCK_METHOD(CdmResponseType, LoadCertificatePrivateKey, (const CryptoWrappedKey&), (override)); - MOCK_METHOD(bool, HasUsageInfoSupport, (bool*), (override)); - MOCK_METHOD(UsageTableHeader*, GetUsageTableHeader, (), (override)); + MOCK_METHOD(bool, HasUsageTableSupport, (bool*), (override)); + MOCK_METHOD(CdmUsageTable*, GetUsageTable, (), (override)); - bool BaseHasUsageInfoSupport(bool* has_support) { - return CryptoSession::HasUsageInfoSupport(has_support); + bool BaseHasUsageTableSupport(bool* has_support) { + return CryptoSession::HasUsageTableSupport(has_support); } }; +class TestCdmClientPropertySet : public CdmClientPropertySet { + public: + TestCdmClientPropertySet(bool atsc_mode) : atsc_mode_(atsc_mode) {} + ~TestCdmClientPropertySet() override {} + + const std::string& security_level() const override { return kEmptyString; } + bool use_privacy_mode() const override { return false; } + const std::string& service_certificate() const override { + return kEmptyString; + } + void set_service_certificate(const std::string& /* cert */) override {} + bool is_session_sharing_enabled() const override { return false; } + uint32_t session_sharing_id() const override { return 1; } + void set_session_sharing_id(uint32_t /* id */) override {} + const std::string& app_id() const override { return kEmptyString; } + bool use_atsc_mode() const override { return atsc_mode_; } + + private: + bool atsc_mode_; +}; + class MockPolicyEngine : public PolicyEngine { public: MockPolicyEngine(CryptoSession* crypto_session) @@ -177,13 +201,21 @@ class MockCdmLicense : public CdmLicense { MOCK_METHOD(std::string, provider_session_token, (), (override)); }; +class MockSystemIdExtractor : public SystemIdExtractor { + public: + MockSystemIdExtractor(CryptoSession* crypto_session, wvutil::FileSystem* fs) + : SystemIdExtractor(kLevelDefault, crypto_session, fs) {} + + MOCK_METHOD(bool, ExtractSystemId, (uint32_t*), (override)); +}; + } // namespace class CdmSessionTest : public WvCdmTestBase { protected: void SetUp() override { WvCdmTestBase::SetUp(); - metrics_.reset(new metrics::SessionMetrics); + metrics_ = std::make_shared(); cdm_session_.reset(new CdmSession(nullptr, metrics_)); // Inject testing mocks. license_parser_ = new MockCdmLicense(cdm_session_->session_id()); @@ -194,6 +226,9 @@ class CdmSessionTest : public WvCdmTestBase { cdm_session_->set_policy_engine(policy_engine_); file_handle_ = new MockDeviceFiles(); cdm_session_->set_file_handle(file_handle_); + system_id_extractor_ = + new MockSystemIdExtractor(crypto_session_, &global_file_system_); + cdm_session_->set_system_id_extractor(system_id_extractor_); } void TearDown() override { @@ -209,25 +244,33 @@ class CdmSessionTest : public WvCdmTestBase { NiceMock* crypto_session_; MockPolicyEngine* policy_engine_; MockDeviceFiles* file_handle_; - MockUsageTableHeader usage_table_header_; + MockCdmUsageTable usage_table_; + MockSystemIdExtractor* system_id_extractor_; + wvutil::FileSystem global_file_system_; }; TEST_F(CdmSessionTest, InitWithBuiltInCertificate) { Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) - .InSequence(crypto_session_seq) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, GetSecurityLevel()) - .InSequence(crypto_session_seq) - .WillOnce(Return(level)); + .WillRepeatedly(Return(level)); + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RetrieveCertificate(false, NotNull(), _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(kSystemId), + Return(DeviceFiles::kCertificateValid))); + EXPECT_CALL(*file_handle_, RemoveCertificate()).Times(0); EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_))) .WillOnce(Return(true)); EXPECT_CALL(*license_parser_, provider_session_token()) .WillRepeatedly(Return("Mock provider session token")); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kSystemId), Return(true))); ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr)); } @@ -236,13 +279,20 @@ TEST_F(CdmSessionTest, InitWithCertificate) { Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) - .InSequence(crypto_session_seq) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, GetSecurityLevel()) - .InSequence(crypto_session_seq) - .WillOnce(Return(level)); + .WillRepeatedly(Return(level)); + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RetrieveCertificate(false, NotNull(), _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(kSystemId), + Return(DeviceFiles::kCertificateValid))); + EXPECT_CALL(*file_handle_, RemoveCertificate()).Times(0); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kSystemId), Return(true))); + EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_))) .WillOnce(Return(true)); @@ -257,17 +307,22 @@ TEST_F(CdmSessionTest, ReInitFail) { CdmSecurityLevel level = kSecurityLevelL1; EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) .InSequence(crypto_session_seq) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, GetSecurityLevel()) .InSequence(crypto_session_seq) - .WillOnce(Return(level)); + .WillRepeatedly(Return(level)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RetrieveCertificate(false, NotNull(), _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(kSystemId), + Return(DeviceFiles::kCertificateValid))); EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_))) .WillOnce(Return(true)); EXPECT_CALL(*license_parser_, provider_session_token()) .WillRepeatedly(Return("Mock provider session token")); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kSystemId), Return(true))); ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr)); ASSERT_NE(NO_ERROR, cdm_session_->Init(nullptr)); @@ -275,41 +330,117 @@ TEST_F(CdmSessionTest, ReInitFail) { TEST_F(CdmSessionTest, InitFailCryptoError) { EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) - .WillOnce(Return(UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); EXPECT_CALL(*license_parser_, provider_session_token()) .WillRepeatedly(Return("Mock provider session token")); ASSERT_EQ(UNKNOWN_ERROR, cdm_session_->Init(nullptr)); } +TEST_F(CdmSessionTest, Init_SystemIdChanged_NeedsProvisioning) { + Sequence crypto_session_seq; + CdmSecurityLevel level = kSecurityLevelL1; + EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .WillRepeatedly(Return(level)); + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); + EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RetrieveCertificate(false, NotNull(), _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(kSystemId), + Return(DeviceFiles::kCertificateValid))); + EXPECT_CALL(*file_handle_, RemoveCertificate()).WillOnce(Return(true)); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kUpdatedSystemId), Return(true))); + + EXPECT_CALL(*license_parser_, provider_session_token()) + .WillRepeatedly(Return("Mock provider session token")); + + ASSERT_EQ(NEED_PROVISIONING, cdm_session_->Init(nullptr)); +} + +TEST_F(CdmSessionTest, Init_AtscSystemIdChanged_NoReProvisionNeeded) { + Sequence crypto_session_seq; + CdmSecurityLevel level = kSecurityLevelL3; + EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .WillRepeatedly(Return(level)); + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); + EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, HasCertificate(true)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RemoveCertificate()).Times(0); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())).Times(0); + + EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), + Eq(crypto_session_), Eq(policy_engine_))) + .WillOnce(Return(true)); + EXPECT_CALL(*license_parser_, provider_session_token()) + .WillRepeatedly(Return("Mock provider session token")); + + TestCdmClientPropertySet atsc_property_set(true); + ASSERT_EQ(NO_ERROR, cdm_session_->Init(&atsc_property_set)); +} + +TEST_F(CdmSessionTest, Init_L3SystemIdChanged_NoReProvisionNeeded) { + Sequence crypto_session_seq; + CdmSecurityLevel level = kSecurityLevelL3; + EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .WillRepeatedly(Return(level)); + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); + EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); + EXPECT_CALL(*file_handle_, RemoveCertificate()).Times(0); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())).Times(0); + + EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), + Eq(crypto_session_), Eq(policy_engine_))) + .WillOnce(Return(true)); + EXPECT_CALL(*license_parser_, provider_session_token()) + .WillRepeatedly(Return("Mock provider session token")); + + ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr)); +} + TEST_F(CdmSessionTest, UpdateUsageEntry) { // Setup common expectations for initializing the CdmSession object. Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) .InSequence(crypto_session_seq) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, GetSecurityLevel()) .InSequence(crypto_session_seq) - .WillOnce(Return(level)); + .WillRepeatedly(Return(level)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true)); - EXPECT_CALL(*crypto_session_, GetUsageTableHeader()) - .WillOnce(Return(&usage_table_header_)); + EXPECT_CALL(*file_handle_, RetrieveCertificate(false, NotNull(), _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(kSystemId), + Return(DeviceFiles::kCertificateValid))); + EXPECT_CALL(*crypto_session_, GetUsageTable()) + .WillOnce(Return(&usage_table_)); EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_))) .WillOnce(Return(true)); + EXPECT_CALL(*system_id_extractor_, ExtractSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kSystemId), Return(false))); // Set up mocks and expectations for the UpdateUsageEntryInformation call. - EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(_)) + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(_)) .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true))); EXPECT_CALL(*license_parser_, provider_session_token()) .WillRepeatedly(Return("Mock provider session token")); - EXPECT_CALL(usage_table_header_, UpdateEntry(_, NotNull(), NotNull())) - .WillRepeatedly(Return(NO_ERROR)); + EXPECT_CALL(usage_table_, UpdateEntry(_, NotNull(), NotNull())) + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); EXPECT_EQ(NO_ERROR, cdm_session_->Init(nullptr)); - EXPECT_TRUE(cdm_session_->supports_usage_info()); + EXPECT_TRUE(cdm_session_->SupportsUsageTable()); EXPECT_EQ(NO_ERROR, cdm_session_->UpdateUsageEntryInformation()); // Verify the UsageEntry metric is set. diff --git a/core/test/usage_table_header_unittest.cpp b/core/test/cdm_usage_table_unittest.cpp similarity index 74% rename from core/test/usage_table_header_unittest.cpp rename to core/test/cdm_usage_table_unittest.cpp index 5ab81e2a..5d602796 100644 --- a/core/test/usage_table_header_unittest.cpp +++ b/core/test/cdm_usage_table_unittest.cpp @@ -2,7 +2,7 @@ // source code may only be used and distributed under the Widevine License // Agreement. -#include "usage_table_header.h" +#include "cdm_usage_table.h" #include #include @@ -23,24 +23,16 @@ // gmock methods using ::testing::_; -using ::testing::AllOf; -using ::testing::AtMost; using ::testing::ContainerEq; using ::testing::Contains; using ::testing::DoAll; using ::testing::ElementsAre; -using ::testing::ElementsAreArray; -using ::testing::Ge; using ::testing::Invoke; -using ::testing::InvokeWithoutArgs; -using ::testing::Lt; using ::testing::NotNull; using ::testing::Return; using ::testing::SaveArg; using ::testing::SetArgPointee; using ::testing::SizeIs; -using ::testing::StrEq; -using ::testing::UnorderedElementsAre; using ::testing::UnorderedElementsAreArray; namespace wvcdm { @@ -51,21 +43,19 @@ constexpr size_t kDefaultTableCapacity = 300; constexpr int64_t kDefaultExpireDuration = 33 * 24 * 60 * 60; // 33 Days -const CdmUsageTableHeader kEmptyUsageTableHeader; -const CdmUsageTableHeader kUsageTableHeader = "some usage table header"; -const CdmUsageTableHeader kAnotherUsageTableHeader = - "another usage table header"; -const CdmUsageTableHeader kYetAnotherUsageTableHeader = +const UsageTableHeader kEmptyUsageTableHeader; +const UsageTableHeader kUsageTableHeader = "some usage table header"; +const UsageTableHeader kAnotherUsageTableHeader = "another usage table header"; +const UsageTableHeader kYetAnotherUsageTableHeader = "yet another usage table header"; -const CdmUsageTableHeader kAndAnotherUsageTableHeader = +const UsageTableHeader kAndAnotherUsageTableHeader = "and another usage table header"; -const CdmUsageTableHeader kOneMoreUsageTableHeader = - "one more usage table header"; -const CdmUsageEntry kUsageEntry = "usage entry"; -const CdmUsageEntry kAnotherUsageEntry = "another usage entry"; -const CdmUsageEntry kYetAnotherUsageEntry = "yet another usage entry"; -const CdmUsageEntry kAndAnotherUsageEntry = "and another usage entry"; -const CdmUsageEntry kOneMoreUsageEntry = "one more usage entry"; +const UsageTableHeader kOneMoreUsageTableHeader = "one more usage table header"; +const UsageEntry kUsageEntry = "usage entry"; +const UsageEntry kAnotherUsageEntry = "another usage entry"; +const UsageEntry kYetAnotherUsageEntry = "yet another usage entry"; +const UsageEntry kAndAnotherUsageEntry = "and another usage entry"; +const UsageEntry kOneMoreUsageEntry = "one more usage entry"; const std::string kDrmCertificate = "a drm certificate"; const std::string kWrappedPrivateKey = "a wrapped private key"; const CryptoWrappedKey kCryptoWrappedKey(CryptoWrappedKey::kRsa, @@ -175,7 +165,7 @@ const DeviceFiles::CdmUsageData kCdmUsageData1 = { /* license = */ "license_1", /* key_set_id = */ "key_set_id_1", /* usage_entry = */ "usage_entry_1", - /* usage_entry_number = */ 0, + /* usage_entry_index = */ 0, /* drm_certificate = */ kDrmCertificate, /* wrapped_private_key = */ kCryptoWrappedKey, }; @@ -185,7 +175,7 @@ const DeviceFiles::CdmUsageData kCdmUsageData2 = { /* license = */ "license_2", /* key_set_id = */ "key_set_id_2", /* usage_entry = */ "usage_entry_2", - /* usage_entry_number = */ 0, + /* usage_entry_index = */ 0, /* drm_certificate = */ kDrmCertificate, /* wrapped_private_key = */ kCryptoWrappedKey, }; @@ -195,7 +185,7 @@ const DeviceFiles::CdmUsageData kCdmUsageData3 = { /* license = */ "license_3", /* key_set_id = */ "key_set_id_3", /* usage_entry = */ "usage_entry_3", - /* usage_entry_number = */ 0, + /* usage_entry_index = */ 0, /* drm_certificate = */ kDrmCertificate, /* wrapped_private_key = */ kCryptoWrappedKey, }; @@ -228,8 +218,7 @@ int64_t kPlaybackDuration = 300; int64_t kGracePeriodEndTime = 60; // ==== LRU Upgrade Data ==== -const CdmUsageTableHeader kUpgradableUsageTableHeader = - "Upgradable Table Header"; +const UsageTableHeader kUpgradableUsageTableHeader = "Upgradable Table Header"; // Usage entries. const CdmUsageEntryInfo kUpgradableUsageEntryInfo1 = { @@ -291,7 +280,7 @@ const int64_t kUpgradedUsageEntryInfo2ExpireTime = 0; // Unset const int64_t kUpgradedUsageEntryInfo3LastUsedTime = kLruBaseTime; const int64_t kUpgradedUsageEntryInfo3ExpireTime = kLruBaseTime + 604800 + 86400; -const CdmUsageTableHeader kUpgradedUsageTableHeader = "Upgraded Table Header"; +const UsageTableHeader kUpgradedUsageTableHeader = "Upgraded Table Header"; std::vector kUpgradedUsageEntryInfoList; namespace { @@ -359,7 +348,7 @@ void InitVectorConstants() { license_data.key_set_id = kUpgradableUsageEntryInfoList[i].key_set_id; license_data.state = kActiveLicenseState; license_data.license = kUpgradableLicenseInfoList[i]; - license_data.usage_entry_number = static_cast(i); + license_data.usage_entry_index = static_cast(i); kUpgradableLicenseDataList.push_back(license_data); } } @@ -391,12 +380,11 @@ class MockDeviceFiles : public DeviceFiles { } MOCK_METHOD(bool, RetrieveUsageTableInfo, - (CdmUsageTableHeader*, std::vector*, + (UsageTableHeader*, std::vector*, bool* lru_upgrade), (override)); MOCK_METHOD(bool, StoreUsageTableInfo, - (const CdmUsageTableHeader&, - const std::vector&), + (const UsageTableHeader&, const std::vector&), (override)); MOCK_METHOD(bool, DeleteUsageInfo, (const std::string&, const CdmKeySetId&), (override)); @@ -405,7 +393,7 @@ class MockDeviceFiles : public DeviceFiles { (override)); MOCK_METHOD(bool, RetrieveUsageInfoByKeySetId, (const std::string&, const std::string&, std::string*, - CdmKeyMessage*, CdmKeyResponse*, CdmUsageEntry*, uint32_t*, + CdmKeyMessage*, CdmKeyResponse*, UsageEntry*, UsageEntryIndex*, std::string*, CryptoWrappedKey*), (override)); MOCK_METHOD(bool, StoreLicense, (const CdmLicenseData&, ResponseType*), @@ -416,8 +404,8 @@ class MockDeviceFiles : public DeviceFiles { MOCK_METHOD(bool, DeleteUsageTableInfo, (), (override)); MOCK_METHOD(bool, StoreUsageInfo, (const std::string&, const CdmKeyMessage&, const CdmKeyResponse&, - const std::string&, const std::string&, const CdmUsageEntry&, - uint32_t, const std::string&, const CryptoWrappedKey&), + const std::string&, const std::string&, const UsageEntry&, + UsageEntryIndex, const std::string&, const CryptoWrappedKey&), (override)); MOCK_METHOD(bool, RetrieveUsageInfo, (const std::string&, std::vector*), (override)); @@ -438,21 +426,21 @@ class MockCryptoSession : public TestCryptoSession { (override)); // Usage Table Header. MOCK_METHOD(CdmResponseType, CreateUsageTableHeader, - (wvcdm::RequestedSecurityLevel, CdmUsageTableHeader*), - (override)); + (wvcdm::RequestedSecurityLevel, UsageTableHeader*), (override)); MOCK_METHOD(CdmResponseType, LoadUsageTableHeader, - (wvcdm::RequestedSecurityLevel, const CdmUsageTableHeader&), + (wvcdm::RequestedSecurityLevel, const UsageTableHeader&), (override)); MOCK_METHOD(CdmResponseType, ShrinkUsageTableHeader, - (wvcdm::RequestedSecurityLevel, uint32_t, CdmUsageTableHeader*), + (wvcdm::RequestedSecurityLevel, uint32_t, UsageTableHeader*), (override)); // Usage Entry. - MOCK_METHOD(CdmResponseType, CreateUsageEntry, (uint32_t*), (override)); - MOCK_METHOD(CdmResponseType, LoadUsageEntry, (uint32_t, const CdmUsageEntry&), + MOCK_METHOD(CdmResponseType, CreateUsageEntry, (UsageEntryIndex*), (override)); + MOCK_METHOD(CdmResponseType, LoadUsageEntry, + (UsageEntryIndex, const UsageEntry&), (override)); MOCK_METHOD(CdmResponseType, UpdateUsageEntry, - (CdmUsageTableHeader*, CdmUsageEntry*), (override)); - MOCK_METHOD(CdmResponseType, MoveUsageEntry, (uint32_t), (override)); + (UsageTableHeader*, UsageEntry*), (override)); + MOCK_METHOD(CdmResponseType, MoveUsageEntry, (UsageEntryIndex), (override)); MOCK_METHOD(CdmResponseType, GetNumberOfOpenSessions, (wvcdm::RequestedSecurityLevel, size_t*), (override)); @@ -478,17 +466,17 @@ class MockCryptoSession : public TestCryptoSession { bool maximum_usage_table_entries_set_ = true; }; -// Partial mock of the UsageTableHeader. This is to test when dependency +// Partial mock of the CdmUsageTable. This is to test when dependency // exist on internal methods which would require complex expectations -class MockUsageTableHeader : public UsageTableHeader { +class MockCdmUsageTable : public CdmUsageTable { public: - MockUsageTableHeader() : UsageTableHeader() {} + MockCdmUsageTable() : CdmUsageTable() {} MOCK_METHOD(CdmResponseType, InvalidateEntryInternal, - (uint32_t, bool, DeviceFiles*, metrics::CryptoMetrics*), + (UsageEntryIndex, bool, DeviceFiles*, metrics::CryptoMetrics*), (override)); MOCK_METHOD(CdmResponseType, AddEntry, (CryptoSession*, bool, const CdmKeySetId&, const std::string&, - const CdmKeyResponse&, uint32_t*), + const CdmKeyResponse&, UsageEntryIndex*), (override)); CdmResponseType SuperAddEntry(CryptoSession* crypto_session, @@ -496,29 +484,29 @@ class MockUsageTableHeader : public UsageTableHeader { const CdmKeySetId& key_set_id, const std::string& usage_info_filename, const CdmKeyResponse& license_message, - uint32_t* usage_entry_number) { - return UsageTableHeader::AddEntry(crypto_session, persistent_license, - key_set_id, usage_info_filename, - license_message, usage_entry_number); + UsageEntryIndex* entry_index) { + return CdmUsageTable::AddEntry(crypto_session, persistent_license, + key_set_id, usage_info_filename, + license_message, entry_index); } }; } // namespace -class UsageTableHeaderTest : public WvCdmTestBase { +class CdmUsageTableTest : public WvCdmTestBase { public: static void SetUpTestCase() { InitVectorConstants(); } - // Useful when UsageTableHeader is mocked - void InvalidateEntry(uint32_t usage_entry_number, bool, DeviceFiles*, + // Useful when CdmUsageTable is mocked + void InvalidateEntry(UsageEntryIndex entry_index, bool, DeviceFiles*, metrics::CryptoMetrics*) { - usage_table_header_->InvalidateEntryForTest(usage_entry_number); + usage_table_->InvalidateEntryForTest(entry_index); } protected: void SetUp() override { WvCdmTestBase::SetUp(); - // UsageTableHeader will take ownership of the pointer + // CdmUsageTable will take ownership of the pointer device_files_ = new MockDeviceFiles(); ON_CALL(*device_files_, RetrieveLicense(_, _, _)) .WillByDefault( @@ -528,60 +516,59 @@ class UsageTableHeaderTest : public WvCdmTestBase { crypto_session_ = new MockCryptoSession(&crypto_metrics_); - usage_table_header_ = new UsageTableHeader(); + usage_table_ = new CdmUsageTable(); - // usage_table_header_ object takes ownership of these objects - usage_table_header_->SetDeviceFiles(device_files_); - usage_table_header_->SetCryptoSession(crypto_session_); + // usage_table_ object takes ownership of these objects + usage_table_->SetDeviceFiles(device_files_); + usage_table_->SetCryptoSession(crypto_session_); - // Several UsageTableHeader methods will make calls to GetCurrentTime(), + // Several CdmUsageTable methods will make calls to GetCurrentTime(), // but the test expectations require a fixed value. Frozen clock provides // the test cases with a fixed value of 0, without needing to set // EXPECT_CALL() in every test case. test_clock_.reset(new FrozenClock()); - usage_table_header_->SetClock(test_clock_.get()); + usage_table_->SetClock(test_clock_.get()); } - // UsageTableHeaderTest maintains ownership of returned pointer - MockUsageTableHeader* SetUpMock() { + // CdmUsageTableTest maintains ownership of returned pointer + MockCdmUsageTable* SetUpMock() { // Release non-mocked usage table header - if (usage_table_header_ != nullptr) { - delete usage_table_header_; - usage_table_header_ = nullptr; + if (usage_table_ != nullptr) { + delete usage_table_; + usage_table_ = nullptr; } - // Create new mock objects if using MockUsageTableHeader + // Create new mock objects if using MockCdmUsageTable device_files_ = new MockDeviceFiles(); crypto_session_ = new MockCryptoSession(&crypto_metrics_); - MockUsageTableHeader* mock_usage_table_header = new MockUsageTableHeader(); + MockCdmUsageTable* mock_usage_table = new MockCdmUsageTable(); - // mock_usage_table_header_ object takes ownership of these objects - mock_usage_table_header->SetDeviceFiles(device_files_); - mock_usage_table_header->SetCryptoSession(crypto_session_); + // mock_usage_table_ object takes ownership of these objects + mock_usage_table->SetDeviceFiles(device_files_); + mock_usage_table->SetCryptoSession(crypto_session_); - usage_table_header_ = mock_usage_table_header; - usage_table_header_->SetClock(test_clock_.get()); - return mock_usage_table_header; + usage_table_ = mock_usage_table; + usage_table_->SetClock(test_clock_.get()); + return mock_usage_table; } - void TearDown() override { - if (usage_table_header_ != nullptr) delete usage_table_header_; - } + void TearDown() override { delete usage_table_; } void Init(CdmSecurityLevel security_level, - const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info_vector) { + const UsageTableHeader& table_header, + const std::vector& entry_info_list) { EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(_, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillOnce( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(usage_table_header), - SetArgPointee<1>(usage_entry_info_vector), + .WillOnce(DoAll(SetArgPointee<0>(table_header), + SetArgPointee<1>(entry_info_list), SetArgPointee<2>(false), Return(true))); - EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(_, usage_table_header)) - .WillOnce(Return(NO_ERROR)); - EXPECT_TRUE(usage_table_header_->Init(security_level, crypto_session_)); + EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(_, table_header)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_TRUE(usage_table_->Init(security_level, crypto_session_)); } void ExpectToDeleteUsageTableFiles() { @@ -593,22 +580,21 @@ class UsageTableHeaderTest : public WvCdmTestBase { MockDeviceFiles* device_files_; metrics::CryptoMetrics crypto_metrics_; MockCryptoSession* crypto_session_; - UsageTableHeader* usage_table_header_; + CdmUsageTable* usage_table_; std::unique_ptr test_clock_; }; -TEST_F(UsageTableHeaderTest, InitError) { +TEST_F(CdmUsageTableTest, InitError) { EXPECT_FALSE( - usage_table_header_->Init(kSecurityLevelUninitialized, crypto_session_)); - EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL2, crypto_session_)); - EXPECT_FALSE( - usage_table_header_->Init(kSecurityLevelUnknown, crypto_session_)); - EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL1, nullptr)); - EXPECT_FALSE(usage_table_header_->Init(kSecurityLevelL2, nullptr)); + usage_table_->Init(kSecurityLevelUninitialized, crypto_session_)); + EXPECT_FALSE(usage_table_->Init(kSecurityLevelL2, crypto_session_)); + EXPECT_FALSE(usage_table_->Init(kSecurityLevelUnknown, crypto_session_)); + EXPECT_FALSE(usage_table_->Init(kSecurityLevelL1, nullptr)); + EXPECT_FALSE(usage_table_->Init(kSecurityLevelL2, nullptr)); } -class UsageTableHeaderInitializationTest - : public UsageTableHeaderTest, +class CdmUsageTableInitializationTest + : public CdmUsageTableTest, public ::testing::WithParamInterface { public: static void SetUpTestCase() { InitVectorConstants(); } @@ -618,11 +604,12 @@ class UsageTableHeaderInitializationTest } }; -TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_Success) { +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_Success) { const RequestedSecurityLevel security_level = GetSecurityLevel(); EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -630,20 +617,20 @@ TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_Success) { SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // First attempt at initializing the table succeeds, however, attempting // to reinitialize the usage table should result in a failure. -TEST_P(UsageTableHeaderInitializationTest, - RestoreUsageTable_FailureDueToReInit) { +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_FailureDueToReInit) { const RequestedSecurityLevel security_level = GetSecurityLevel(); // First run, success. EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -651,25 +638,26 @@ TEST_P(UsageTableHeaderInitializationTest, SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); // Second run, failure. - EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_FALSE(usage_table_->Init(GetParam(), crypto_session_)); } // Table MUST not be initialized before another session has been opened. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_FailureDueToExistingSessions) { const RequestedSecurityLevel security_level = GetSecurityLevel(); EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(1), Return(NO_ERROR))); - EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_)); + .WillRepeatedly( + DoAll(SetArgPointee<1>(1), Return(CdmResponseType(NO_ERROR)))); + EXPECT_FALSE(usage_table_->Init(GetParam(), crypto_session_)); } // No existing usage table in storage, creating a new table succeeds. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_CreateNew_AfterRetrieveFails) { const RequestedSecurityLevel security_level = GetSecurityLevel(); @@ -677,7 +665,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 1) Fail to retrieve existing table file EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); @@ -689,18 +678,18 @@ TEST_P(UsageTableHeaderInitializationTest, ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) - .WillOnce( - DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // A table exists in storage, but it cannot be loaded due to generation // skew. Creating a new table succeeds. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_CreateNew_AfterLoadFails) { const RequestedSecurityLevel security_level = GetSecurityLevel(); @@ -709,7 +698,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 2) Loading existing header within OEMCrypto fails EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -717,7 +707,7 @@ TEST_P(UsageTableHeaderInitializationTest, SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_HEADER_GENERATION_SKEW))); // Expectations for create: // 1) Existing table is destroyed (files etc.) @@ -726,25 +716,26 @@ TEST_P(UsageTableHeaderInitializationTest, ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) - .WillOnce( - DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // No existing table in storage, and attempting to create a new usage // table fails for unknown reason. Initialization MUST fail. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_CreateNew_CreateFails) { const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: // 1) No table info file exists EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); @@ -753,22 +744,23 @@ TEST_P(UsageTableHeaderInitializationTest, ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) - .WillOnce(Return(CREATE_USAGE_TABLE_ERROR)); + .WillOnce(Return(CdmResponseType(CREATE_USAGE_TABLE_ERROR))); - EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_FALSE(usage_table_->Init(GetParam(), crypto_session_)); } // No existing table in storage, attempting to create a new usage // table succeeds; however, storing the new table header fails. // Initialization MUST fail. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_CreateNew_StoreFails) { const RequestedSecurityLevel security_level = GetSecurityLevel(); // Expectations for restore: // 1) No table info file exists EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); @@ -778,16 +770,17 @@ TEST_P(UsageTableHeaderInitializationTest, ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(false)); - EXPECT_FALSE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_FALSE(usage_table_->Init(GetParam(), crypto_session_)); } // Restoring table succeeds, and the current table is at capacity. // No special action needs to be taken. -TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) { +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_AtCapacity) { std::vector usage_entries = kOverFullUsageEntryInfoVector; usage_entries.resize(kDefaultTableCapacity); const RequestedSecurityLevel security_level = GetSecurityLevel(); @@ -796,7 +789,8 @@ TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) { // 2) Loading existing header within OEMCrypto succeeds EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -804,14 +798,14 @@ TEST_P(UsageTableHeaderInitializationTest, RestoreUsageTable_AtCapacity) { Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // Restoring table succeeds, OEMCrypto does not specify an absolute // capacity, existing table is under the minimum required capacity. // No special action needs to be taken. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_NoCapacity_UnderMinimum) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. std::vector usage_entries = kOverFullUsageEntryInfoVector; @@ -823,7 +817,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 2) Loading existing header within OEMCrypto succeeds EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -831,16 +826,16 @@ TEST_P(UsageTableHeaderInitializationTest, Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // Restoring table succeeds, OEMCrypto does not specify an absolute // capacity, existing table is above the minimum required capacity. // After restoring, the header class must check that new entries can // be added. This capacity check succeeds. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_NoCapacity_AboveMinimum) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); @@ -853,7 +848,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 2) Loading existing header within OEMCrypto succeeds EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -861,7 +857,7 @@ TEST_P(UsageTableHeaderInitializationTest, SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expectations for capacity check: // 1) Open a new crypto session. @@ -872,14 +868,14 @@ TEST_P(UsageTableHeaderInitializationTest, // 6) Table is shrunk by 1 // 7) Table state is stored EXPECT_CALL(*crypto_session_, Open(security_level)) - .WillOnce(Return(NO_ERROR)); - const uint32_t expect_usage_entry_number = table_start_size; + .WillOnce(Return(CdmResponseType(NO_ERROR))); + const uint32_t expect_entry_index = table_start_size; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(expect_entry_index), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, SizeIs(table_start_size + 1))) .WillOnce(Return(true)); @@ -887,12 +883,12 @@ TEST_P(UsageTableHeaderInitializationTest, *crypto_session_, ShrinkUsageTableHeader(security_level, table_start_size, NotNull())) .WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageTableHeader), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader, SizeIs(table_start_size))) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // Restoring table succeeds, OEMCrypto does not specify an absolute @@ -900,7 +896,7 @@ TEST_P(UsageTableHeaderInitializationTest, // After restoring, the header class must check that new entries can // be added. This capacity check fails due to adding an entry. // The result is a new usage table. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_AboveCapacity_AddEntryFails) { ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); const RequestedSecurityLevel security_level = GetSecurityLevel(); @@ -910,7 +906,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 2) Loading existing header within OEMCrypto succeeds EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -918,15 +915,15 @@ TEST_P(UsageTableHeaderInitializationTest, SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expectations for capacity check: // 1) Open a new crypto session. // 2) Creating a new usage entry within OEMCrypto fails EXPECT_CALL(*crypto_session_, Open(security_level)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(CREATE_USAGE_ENTRY_UNKNOWN_ERROR))); // Expectations for create: // 1) Existing table is destroyed (files etc.) @@ -935,13 +932,13 @@ TEST_P(UsageTableHeaderInitializationTest, ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) - .WillOnce( - DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } // Restoring table succeeds, OEMCrypto does not specify an absolute @@ -949,7 +946,7 @@ TEST_P(UsageTableHeaderInitializationTest, // After restoring, the header class must check that new entries can // be added. This capacity check fails due to invalidating an entry. // The result is a new usage table. -TEST_P(UsageTableHeaderInitializationTest, +TEST_P(CdmUsageTableInitializationTest, RestoreUsageTable_NoCapacity_AboveMinimum_InvalidateEntryFails) { crypto_session_->SetMaximumUsageTableEntries(0); // Unlimited. ASSERT_LT(kDefaultTableCapacity, kOverFullUsageEntryInfoVector.size()); @@ -962,7 +959,8 @@ TEST_P(UsageTableHeaderInitializationTest, // 2) Loading existing header within OEMCrypto succeeds EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(security_level, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), @@ -970,7 +968,7 @@ TEST_P(UsageTableHeaderInitializationTest, SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(security_level, kUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expectations for capacity check: // 1) Open a new crypto session. @@ -980,14 +978,14 @@ TEST_P(UsageTableHeaderInitializationTest, // 5) New session is closed // 6) Shrinking table fails EXPECT_CALL(*crypto_session_, Open(security_level)) - .WillOnce(Return(NO_ERROR)); - const uint32_t expect_usage_entry_number = table_start_size; + .WillOnce(Return(CdmResponseType(NO_ERROR))); + const UsageEntryIndex expect_entry_index = table_start_size; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(expect_entry_index), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); // Called twice due to defrag. EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, SizeIs(table_start_size + 1))) @@ -996,7 +994,8 @@ TEST_P(UsageTableHeaderInitializationTest, EXPECT_CALL( *crypto_session_, ShrinkUsageTableHeader(security_level, table_start_size, NotNull())) - .WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR)); + .WillOnce( + Return(CdmResponseType(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR))); // Expectations for create: // 1) Existing table is destroyed (files etc.) @@ -1006,51 +1005,52 @@ TEST_P(UsageTableHeaderInitializationTest, EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(security_level, NotNull())) .WillOnce(DoAll(SetArgPointee<1>(kYetAnotherUsageTableHeader), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_)); + EXPECT_TRUE(usage_table_->Init(GetParam(), crypto_session_)); } -INSTANTIATE_TEST_SUITE_P(Cdm, UsageTableHeaderInitializationTest, +INSTANTIATE_TEST_SUITE_P(Cdm, CdmUsageTableInitializationTest, ::testing::Values(kSecurityLevelL1, kSecurityLevelL3)); -TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailed_UnknownError) { +TEST_F(CdmUsageTableTest, AddEntry_CreateUsageEntryFailed_UnknownError) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t expect_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); - EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(expect_usage_entry_number), - Return(CREATE_USAGE_ENTRY_UNKNOWN_ERROR))); - - uint32_t usage_entry_number = 0; - EXPECT_NE(NO_ERROR, - usage_table_header_->AddEntry( - crypto_session_, - kUsageEntryInfoOfflineLicense1.storage_type == kStorageLicense, - kUsageEntryInfoOfflineLicense1.key_set_id, - kUsageEntryInfoOfflineLicense1.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); -} - -TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) { - Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t expect_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; + const UsageEntryIndex expect_entry_index = + static_cast(kUsageEntryInfoVector.size()); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .WillOnce( - DoAll(SetArgPointee<0>(expect_usage_entry_number), Return(NO_ERROR))); + DoAll(SetArgPointee<0>(expect_entry_index), + Return(CdmResponseType(CREATE_USAGE_ENTRY_UNKNOWN_ERROR)))); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_NE(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoOfflineLicense1.storage_type == kStorageLicense, kUsageEntryInfoOfflineLicense1.key_set_id, kUsageEntryInfoOfflineLicense1.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); + kEmptyString /* license */, &entry_index)); +} + +TEST_F(CdmUsageTableTest, AddEntry_UsageEntryTooSmall) { + Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); + const UsageEntryIndex expect_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(expect_entry_index), + Return(CdmResponseType(NO_ERROR)))); + + UsageEntryIndex entry_index = 0; + EXPECT_NE(NO_ERROR, + usage_table_->AddEntry( + crypto_session_, + kUsageEntryInfoOfflineLicense1.storage_type == kStorageLicense, + kUsageEntryInfoOfflineLicense1.key_set_id, + kUsageEntryInfoOfflineLicense1.usage_info_file_name, + kEmptyString /* license */, &entry_index)); } // Initial Test state: @@ -1075,45 +1075,42 @@ TEST_F(UsageTableHeaderTest, AddEntry_UsageEntryTooSmall) { // DNE = Does Not Exist // // # of usage entries 3 3 -TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { +TEST_F(CdmUsageTableTest, AddEntry_NextConsecutiveOfflineUsageEntry) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t initial_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); - const uint32_t final_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; - std::vector expect_usage_entry_info_vector = - kUsageEntryInfoVector; - expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoOfflineLicense2; + const UsageEntryIndex initial_entry_index = + static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex final_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + std::vector expect_entry_info_list = kUsageEntryInfoVector; + expect_entry_info_list[final_entry_index] = kUsageEntryInfoOfflineLicense2; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), - Return(NO_ERROR))); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, - ShrinkUsageTableHeader( - kLevelDefault, - static_cast(expect_usage_entry_info_vector.size()), - NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(initial_entry_index), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_entry_index)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL( + *crypto_session_, + ShrinkUsageTableHeader( + kLevelDefault, static_cast(expect_entry_info_list.size()), + NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kYetAnotherUsageTableHeader), - Return(NO_ERROR))); - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kYetAnotherUsageTableHeader, - expect_usage_entry_info_vector)) + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader, + expect_entry_info_list)) .WillOnce(Return(true)); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoOfflineLicense2.storage_type == kStorageLicense, kUsageEntryInfoOfflineLicense2.key_set_id, kUsageEntryInfoOfflineLicense2.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); - EXPECT_EQ(final_usage_entry_number, usage_entry_number); + kEmptyString /* license */, &entry_index)); + EXPECT_EQ(final_entry_index, entry_index); } // Initial Test state: @@ -1138,46 +1135,43 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveOfflineUsageEntry) { // DNE = Does Not Exist // // # of usage entries 3 3 -TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) { +TEST_F(CdmUsageTableTest, AddEntry_NextConsecutiveSecureStopUsageEntry) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t initial_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); - const uint32_t final_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; - std::vector expect_usage_entry_info_vector = - kUsageEntryInfoVector; - expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoSecureStop2; + const UsageEntryIndex initial_entry_index = + static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex final_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + std::vector expect_entry_info_list = kUsageEntryInfoVector; + expect_entry_info_list[final_entry_index] = kUsageEntryInfoSecureStop2; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), - Return(NO_ERROR))); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, - ShrinkUsageTableHeader( - kLevelDefault, - static_cast(expect_usage_entry_info_vector.size()), - NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(initial_entry_index), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_entry_index)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL( + *crypto_session_, + ShrinkUsageTableHeader( + kLevelDefault, static_cast(expect_entry_info_list.size()), + NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kYetAnotherUsageTableHeader), - Return(NO_ERROR))); - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kYetAnotherUsageTableHeader, - expect_usage_entry_info_vector)) + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader, + expect_entry_info_list)) .WillOnce(Return(true)); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoSecureStop2.storage_type == kStorageLicense, kUsageEntryInfoSecureStop2.key_set_id, kUsageEntryInfoSecureStop2.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); - EXPECT_EQ(final_usage_entry_number, usage_entry_number); + kEmptyString /* license */, &entry_index)); + EXPECT_EQ(final_entry_index, entry_index); } // Initial Test state: @@ -1208,49 +1202,46 @@ TEST_F(UsageTableHeaderTest, AddEntry_NextConsecutiveSecureStopUsageEntry) { // DNE = Does Not Exist // // # of usage entries 3 3 -TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) { +TEST_F(CdmUsageTableTest, AddEntry_SkipUsageEntries) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t next_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex next_entry_index = + static_cast(kUsageEntryInfoVector.size()); const size_t skip_usage_entries = 3; - const uint32_t initial_usage_entry_number = - next_usage_entry_number + skip_usage_entries; - const uint32_t final_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; - std::vector expect_usage_entry_info_vector = - kUsageEntryInfoVector; - expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoSecureStop2; + const UsageEntryIndex initial_entry_index = + next_entry_index + skip_usage_entries; + const UsageEntryIndex final_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + std::vector expect_entry_info_list = kUsageEntryInfoVector; + expect_entry_info_list[final_entry_index] = kUsageEntryInfoSecureStop2; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), - Return(NO_ERROR))); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, - ShrinkUsageTableHeader( - kLevelDefault, - static_cast(expect_usage_entry_info_vector.size()), - NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(initial_entry_index), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_entry_index)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL( + *crypto_session_, + ShrinkUsageTableHeader( + kLevelDefault, static_cast(expect_entry_info_list.size()), + NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kYetAnotherUsageTableHeader), - Return(NO_ERROR))); - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kYetAnotherUsageTableHeader, - expect_usage_entry_info_vector)) + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageTableHeader, + expect_entry_info_list)) .WillOnce(Return(true)); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoSecureStop2.storage_type == kStorageLicense, kUsageEntryInfoSecureStop2.key_set_id, kUsageEntryInfoSecureStop2.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); - EXPECT_EQ(final_usage_entry_number, usage_entry_number); + kEmptyString /* license */, &entry_index)); + EXPECT_EQ(final_entry_index, entry_index); } // Initial Test state: @@ -1275,38 +1266,36 @@ TEST_F(UsageTableHeaderTest, AddEntry_SkipUsageEntries) { // DNE = Does Not Exist // // # of usage entries 3 4 -TEST_F(UsageTableHeaderTest, AddEntry_CannotMoveNewEntry) { +TEST_F(CdmUsageTableTest, AddEntry_CannotMoveNewEntry) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t final_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); - const uint32_t attempted_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; - std::vector expect_usage_entry_info_vector = - kUsageEntryInfoVector; - expect_usage_entry_info_vector.push_back(kUsageEntryInfoSecureStop2); + const UsageEntryIndex final_entry_index = + static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex attempted_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + std::vector expect_entry_info_list = kUsageEntryInfoVector; + expect_entry_info_list.push_back(kUsageEntryInfoSecureStop2); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(final_usage_entry_number), Return(NO_ERROR))); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(attempted_usage_entry_number)) - .WillOnce(Return(MOVE_USAGE_ENTRY_DESTINATION_IN_USE)); + .WillOnce(DoAll(SetArgPointee<0>(final_entry_index), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(attempted_entry_index)) + .WillOnce(Return(CdmResponseType(MOVE_USAGE_ENTRY_DESTINATION_IN_USE))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kAnotherUsageTableHeader, - expect_usage_entry_info_vector)) + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, + expect_entry_info_list)) .WillOnce(Return(true)); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoSecureStop2.storage_type == kStorageLicense, kUsageEntryInfoSecureStop2.key_set_id, kUsageEntryInfoSecureStop2.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); - EXPECT_EQ(final_usage_entry_number, usage_entry_number); + kEmptyString /* license */, &entry_index)); + EXPECT_EQ(final_entry_index, entry_index); } // Initial Test state: @@ -1332,47 +1321,44 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotMoveNewEntry) { // DNE = Does Not Exist // // # of usage entries 3 4 -TEST_F(UsageTableHeaderTest, AddEntry_CannotShinkAfterMove) { +TEST_F(CdmUsageTableTest, AddEntry_CannotShinkAfterMove) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t initial_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); - const uint32_t final_usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) - 1; - std::vector expect_usage_entry_info_vector = - kUsageEntryInfoVector; - expect_usage_entry_info_vector[final_usage_entry_number] = - kUsageEntryInfoSecureStop2; - expect_usage_entry_info_vector.push_back(kUsageEntryInfoStorageTypeUnknown); + const UsageEntryIndex initial_entry_index = + static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex final_entry_index = + static_cast(kUsageEntryInfoVector.size()) - 1; + std::vector expect_entry_info_list = kUsageEntryInfoVector; + expect_entry_info_list[final_entry_index] = kUsageEntryInfoSecureStop2; + expect_entry_info_list.push_back(kUsageEntryInfoStorageTypeUnknown); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(initial_usage_entry_number), - Return(NO_ERROR))); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_usage_entry_number)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(DoAll(SetArgPointee<0>(initial_entry_index), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(final_entry_index)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL( *crypto_session_, ShrinkUsageTableHeader( kLevelDefault, - static_cast(expect_usage_entry_info_vector.size()) - 1, - NotNull())) - .WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE)); - EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) + static_cast(expect_entry_info_list.size()) - 1, NotNull())) .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); - EXPECT_CALL(*device_files_, - StoreUsageTableInfo(kAnotherUsageTableHeader, - expect_usage_entry_info_vector)) + Return(CdmResponseType(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE))); + EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); + EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, + expect_entry_info_list)) .WillOnce(Return(true)); - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - usage_table_header_->AddEntry( + usage_table_->AddEntry( crypto_session_, kUsageEntryInfoSecureStop2.storage_type == kStorageLicense, kUsageEntryInfoSecureStop2.key_set_id, kUsageEntryInfoSecureStop2.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); - EXPECT_EQ(final_usage_entry_number, usage_entry_number); + kEmptyString /* license */, &entry_index)); + EXPECT_EQ(final_entry_index, entry_index); } // Initial Test state: @@ -1387,51 +1373,51 @@ TEST_F(UsageTableHeaderTest, AddEntry_CannotShinkAfterMove) { // c. Table will be stored // d. Second call to OEMCrypto to create an entry will succeed // e. Storing the new updated usage table -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, AddEntry_CreateUsageEntryFailsOnce_SucceedsSecondTime) { // Initialize and setup - MockUsageTableHeader* mock_usage_table_header = SetUpMock(); + MockCdmUsageTable* mock_usage_table = SetUpMock(); Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); - std::vector usage_entry_info_vector_at_start = + std::vector entry_info_list_at_start = k10UsageEntryInfoVector; - uint32_t invalidated_entry = 0; // Randomly chosen by UsageTableHeader + UsageEntryIndex invalidated_entry = 0; // Randomly chosen by CdmUsageTable - const uint32_t expected_usage_entry_number = - static_cast(k10UsageEntryInfoVector.size()) - 1; + const UsageEntryIndex expected_entry_index = + static_cast(k10UsageEntryInfoVector.size()) - 1; EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) // First call fails - .WillOnce(Return(INSUFFICIENT_CRYPTO_RESOURCES)) + .WillOnce(Return(CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES))) // Second call succeeds - .WillOnce(DoAll(SetArgPointee<0>(expected_usage_entry_number), - Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(expected_entry_index), + Return(CdmResponseType(NO_ERROR)))); // Covers all other expectations. - EXPECT_CALL(*mock_usage_table_header, + EXPECT_CALL(*mock_usage_table, InvalidateEntryInternal(_, true, device_files_, NotNull())) .WillOnce(DoAll(SaveArg<0>(&invalidated_entry), - Invoke(this, &UsageTableHeaderTest::InvalidateEntry), - Return(NO_ERROR))); + Invoke(this, &CdmUsageTableTest::InvalidateEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); std::vector final_usage_entries; EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)) .WillOnce(DoAll(SaveArg<1>(&final_usage_entries), Return(true))); // Now invoke the method under test - uint32_t usage_entry_number = 0; + UsageEntryIndex entry_index = 0; EXPECT_EQ(NO_ERROR, - mock_usage_table_header->SuperAddEntry( + mock_usage_table->SuperAddEntry( crypto_session_, kUsageEntryInfoOfflineLicense6.storage_type == kStorageLicense, kUsageEntryInfoOfflineLicense6.key_set_id, kUsageEntryInfoOfflineLicense6.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); + kEmptyString /* license */, &entry_index)); - // Verify added/deleted usage entry number and entries - EXPECT_EQ(expected_usage_entry_number, usage_entry_number); + // Verify added/deleted of usage entry index and entry info. + EXPECT_EQ(expected_entry_index, entry_index); EXPECT_LE(0u, invalidated_entry); EXPECT_LE(invalidated_entry, k10UsageEntryInfoVector.size() - 1); @@ -1447,35 +1433,35 @@ TEST_F(UsageTableHeaderTest, // The usage table should only delete/invalidate a single entry. // After which, it should fail. -TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) { +TEST_F(CdmUsageTableTest, AddEntry_CreateUsageEntryFailsEveryTime) { // Initialize and setup - MockUsageTableHeader* mock_usage_table_header = SetUpMock(); + MockCdmUsageTable* mock_usage_table = SetUpMock(); Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); // Setup expectations - EXPECT_CALL(*mock_usage_table_header, + EXPECT_CALL(*mock_usage_table, InvalidateEntryInternal(_, true, device_files_, NotNull())) - .WillOnce(DoAll(Invoke(this, &UsageTableHeaderTest::InvalidateEntry), - Return(NO_ERROR))); + .WillOnce(DoAll(Invoke(this, &CdmUsageTableTest::InvalidateEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) .Times(2) - .WillRepeatedly(Return(INSUFFICIENT_CRYPTO_RESOURCES)); + .WillRepeatedly(Return(CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES))); // Now invoke the method under test - uint32_t usage_entry_number; + UsageEntryIndex entry_index; EXPECT_EQ(INSUFFICIENT_CRYPTO_RESOURCES, - mock_usage_table_header->SuperAddEntry( + mock_usage_table->SuperAddEntry( crypto_session_, true /* persistent */, kUsageEntryInfoOfflineLicense6.key_set_id, kUsageEntryInfoOfflineLicense6.usage_info_file_name, - kEmptyString /* license */, &usage_entry_number)); + kEmptyString /* license */, &entry_index)); // Verify the number of entries deleted. constexpr uint32_t kExpectedEntriesDeleted = 1; const std::vector& final_usage_entries = - mock_usage_table_header->usage_entry_info(); + mock_usage_table->entry_info_list(); uint32_t invalid_entries = 0; for (const CdmUsageEntryInfo& usage_entry_info : final_usage_entries) { if (usage_entry_info.storage_type == kStorageTypeUnknown) { @@ -1491,57 +1477,58 @@ TEST_F(UsageTableHeaderTest, AddEntry_CreateUsageEntryFailsEveryTime) { EXPECT_EQ(kExpectedEntriesDeleted, entries_deleted); } -TEST_F(UsageTableHeaderTest, LoadEntry_InvalidEntryNumber) { +TEST_F(CdmUsageTableTest, LoadEntry_InvalidEntryNumber) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t usage_entry_number = - static_cast(kUsageEntryInfoVector.size()) + 3; + const UsageEntryIndex entry_index = + static_cast(kUsageEntryInfoVector.size()) + 3; - EXPECT_NE(NO_ERROR, usage_table_header_->LoadEntry( - crypto_session_, kUsageEntry, usage_entry_number)); + EXPECT_NE(NO_ERROR, + usage_table_->LoadEntry(crypto_session_, kUsageEntry, entry_index)); } -TEST_F(UsageTableHeaderTest, LoadEntry_CryptoSessionError) { +TEST_F(CdmUsageTableTest, LoadEntry_CryptoSessionError) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t usage_entry_number = 1; + const UsageEntryIndex entry_index = 1; - EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_GENERATION_SKEW)); + EXPECT_CALL(*crypto_session_, LoadUsageEntry(entry_index, kUsageEntry)) + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_GENERATION_SKEW))); - EXPECT_NE(NO_ERROR, usage_table_header_->LoadEntry( - crypto_session_, kUsageEntry, usage_entry_number)); + EXPECT_NE(NO_ERROR, + usage_table_->LoadEntry(crypto_session_, kUsageEntry, entry_index)); } -TEST_F(UsageTableHeaderTest, LoadEntry) { +TEST_F(CdmUsageTableTest, LoadEntry) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t usage_entry_number = 1; + const UsageEntryIndex entry_index = 1; - EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, LoadUsageEntry(entry_index, kUsageEntry)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); - EXPECT_EQ(NO_ERROR, usage_table_header_->LoadEntry( - crypto_session_, kUsageEntry, usage_entry_number)); + EXPECT_EQ(NO_ERROR, + usage_table_->LoadEntry(crypto_session_, kUsageEntry, entry_index)); } -TEST_F(UsageTableHeaderTest, UpdateEntry_CryptoSessionError) { +TEST_F(CdmUsageTableTest, UpdateEntry_CryptoSessionError) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - CdmUsageEntry usage_entry; + UsageEntry usage_entry; + + EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) + .WillOnce(DoAll( + SetArgPointee<0>(kUsageTableHeader), SetArgPointee<1>(kUsageEntry), + Return(CdmResponseType(UPDATE_USAGE_ENTRY_UNKNOWN_ERROR)))); + + EXPECT_NE(NO_ERROR, + usage_table_->UpdateEntry(0, crypto_session_, &usage_entry)); +} + +TEST_F(CdmUsageTableTest, UpdateEntry) { + Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); + UsageEntry usage_entry; EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), SetArgPointee<1>(kUsageEntry), - Return(UPDATE_USAGE_ENTRY_UNKNOWN_ERROR))); - - EXPECT_NE(NO_ERROR, - usage_table_header_->UpdateEntry(0, crypto_session_, &usage_entry)); -} - -TEST_F(UsageTableHeaderTest, UpdateEntry) { - Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - CdmUsageEntry usage_entry; - - EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), - SetArgPointee<1>(kUsageEntry), Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL( *device_files_, @@ -1550,17 +1537,17 @@ TEST_F(UsageTableHeaderTest, UpdateEntry) { .WillOnce(Return(true)); EXPECT_EQ(NO_ERROR, - usage_table_header_->UpdateEntry(0, crypto_session_, &usage_entry)); + usage_table_->UpdateEntry(0, crypto_session_, &usage_entry)); } -TEST_F(UsageTableHeaderTest, InvalidateEntry_InvalidUsageEntryNumber) { +TEST_F(CdmUsageTableTest, InvalidateEntry_InvalidUsageEntryNumber) { Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - const uint32_t usage_entry_number = - static_cast(kUsageEntryInfoVector.size()); + const UsageEntryIndex entry_index = + static_cast(kUsageEntryInfoVector.size()); metrics::CryptoMetrics metrics; - EXPECT_NE(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number, true, device_files_, &metrics)); + EXPECT_NE(NO_ERROR, usage_table_->InvalidateEntry(entry_index, true, + device_files_, &metrics)); } // Initial Test state: @@ -1574,7 +1561,8 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_InvalidUsageEntryNumber) { // and the unknown entry before it. // c. OEMCrypto error will cause the internal entries to remain the // same. -// d. InvalidateEntry() will return NO_ERROR as the storage type is +// d. InvalidateEntry() will return CdmResponseType(NO_ERROR) as the storage +// type is // changed. // // Storage type Usage entries @@ -1586,19 +1574,20 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_InvalidUsageEntryNumber) { // Offline License 2 3 3 (Storage Type Unknown) // // # of usage entries 4 4 -TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_CryptoSessionError) { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 3; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR)); + .WillOnce( + Return(CdmResponseType(SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR))); // Regardless, the usage table should be updated to reflect the changes // to the usage entry marked as storage type unknown. @@ -1611,12 +1600,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { kUsageEntryInfoStorageTypeUnknown))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check that the list is unchanged. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -1626,7 +1615,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { // a. The entry will be marked as kStorageTypeUnknown. // b. Usage table will be resized to remove the last two entries. // c. Updated table will be saved. -// d. InvalidateEntry() will return NO_ERROR. +// d. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1637,21 +1626,21 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_CryptoSessionError) { // Offline License 2 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntry_OfflineEntry) { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 3; // kUsageEntryInfoOfflineLicense2 metrics::CryptoMetrics metrics; // Expectations for call to shrink. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, @@ -1659,12 +1648,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { kUsageEntryInfoSecureStop1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -1674,7 +1663,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { // a. The entry will be marked as kStorageTypeUnknown. // b. Usage table will be resized to remove the last two entries. // c. Updated table will be saved. -// d. InvalidateEntry() will return NO_ERROR. +// d. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1685,21 +1674,21 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_OfflineEntry) { // Secure Stop 2 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntry_SecureStopEntry) { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop2}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 3; // kUsageEntryInfoSecureStop2 metrics::CryptoMetrics metrics; // Expectation when shrinking table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, @@ -1707,12 +1696,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { kUsageEntryInfoSecureStop1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -1729,7 +1718,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1741,15 +1730,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntry_SecureStopEntry) { // Offline License 3 4 Deleted (because missing) // // # of usage entries 5 1 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastOfflineEntriesHaveMissingLicenses) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; @@ -1766,20 +1755,20 @@ TEST_F(UsageTableHeaderTest, // Shrink to contain only the one valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 1, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoSecureStop1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -1796,7 +1785,7 @@ TEST_F(UsageTableHeaderTest, // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1808,14 +1797,14 @@ TEST_F(UsageTableHeaderTest, // Secure stop 3 4 Deleted (because missing) // // # of usage entries 5 1 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -1836,25 +1825,25 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { // Shrink to contain only the one valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 1, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: // 1. Last few entries are offline licenses, but have incorrect usage -// entry number stored in persistent file store. +// entry index stored in persistent file store. // 2. Usage entry to be deleted precedes those in (1). // // Attempting to delete the entry in (2) will result in: @@ -1862,12 +1851,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { // b. While defragging, the last two entries will be selected to // move. // c. Getting the usage entry for the selected entries will fail due -// to a mismatch in usage entry number and result in them being set +// to a mismatch in usage entry index and result in them being set // as kStorageTypeUnknown. // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1879,18 +1868,18 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { // Offline License 3 4 Deleted (because incorrect #) // // # of usage entries 5 1 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastOfflineEntriesHaveIncorrectUsageEntryNumber) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; - // Set offline license file data with mismatched usage entry numbers. + // Set offline license file data with mismatched usage entry indexes. const DeviceFiles::CdmLicenseData offline_license_3_data{ kUsageEntryInfoOfflineLicense3.key_set_id, kActiveLicenseState, @@ -1905,7 +1894,7 @@ TEST_F(UsageTableHeaderTest, kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(3) /* Mismatch */, + static_cast(3) /* Mismatch */, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -1927,7 +1916,7 @@ TEST_F(UsageTableHeaderTest, kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(2) /* Mismatch */, + static_cast(2) /* Mismatch */, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -1938,24 +1927,24 @@ TEST_F(UsageTableHeaderTest, // Shrink to contain only the one valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 1, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoSecureStop1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: // 1. Last few entries are secure stops, but have incorrect usage -// entry number stored in persistent file store. +// entry index stored in persistent file store. // 2. Usage entry to be deleted precedes those in (1). // // Attempting to delete the entry in (2) will result in: @@ -1963,12 +1952,12 @@ TEST_F(UsageTableHeaderTest, // b. While defragging, the last two entries will be selected to // move. // c. Getting the usage entry for the selected entries will fail due -// to a mismatch in usage entry number and result in them being set +// to a mismatch in usage entry index and result in them being set // as kStorageTypeUnknown. // d. No entries will be moved due to (c). // e. Usage table will be resized to have only one entry. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -1980,19 +1969,19 @@ TEST_F(UsageTableHeaderTest, // Secure stop 3 4 Deleted (because incorrect #) // // # of usage entries 5 1 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastSecureStopEntriesHaveIncorrectUsageEntryNumber) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; - // Set streaming license file data with mismatched usage entry numbers. + // Set streaming license file data with mismatched usage entry indexes. EXPECT_CALL(*device_files_, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, @@ -2020,20 +2009,20 @@ TEST_F(UsageTableHeaderTest, // Shrink to contain only the one valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 1, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 1; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2051,7 +2040,7 @@ TEST_F(UsageTableHeaderTest, // e. The moved entry will be updated in device files. // f. Usage table will be resized to have only one entry. // g. Updated table will be saved. -// h. InvalidateEntry() will return NO_ERROR. +// h. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2065,15 +2054,15 @@ TEST_F(UsageTableHeaderTest, // Storage Type Unknown 6 Deleted // // # of usage entries 7 3 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 4; // kUsageEntryInfoOfflineLicense3 metrics::CryptoMetrics metrics; @@ -2092,7 +2081,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(3), + static_cast(3), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2102,13 +2091,16 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); // Calls during Move(). - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)).WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kYetAnotherUsageEntry), - SetArgPointee<1>(kUsageEntry), Return(NO_ERROR))); + SetArgPointee<1>(kUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, _)) .WillOnce(Return(true)); EXPECT_CALL(*device_files_, StoreLicense(_, NotNull())) @@ -2117,8 +2109,8 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // Shrink to contain the remaining valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 3, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, @@ -2127,12 +2119,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2150,7 +2142,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // the entry inplace. // e. Usage table will not be resized. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2162,15 +2154,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntriesAreStorageTypeUnknown) { // Offline License 3 4 4 // // # of usage entries 5 5 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntryIsOffline_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; @@ -2190,7 +2182,7 @@ TEST_F(UsageTableHeaderTest, kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - /* usage_entry_number = */ 4, + /* usage_entry_index = */ 4, kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2199,9 +2191,10 @@ TEST_F(UsageTableHeaderTest, .WillOnce(DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); // Calls during Move(). - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // No calls to shrink are expected. @@ -2216,12 +2209,12 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoOfflineLicense3))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check that the table has been updated as expected. constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2238,7 +2231,7 @@ TEST_F(UsageTableHeaderTest, // the entry inplace. // e. Usage table will not be resized. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2250,15 +2243,15 @@ TEST_F(UsageTableHeaderTest, // Secure Stop 3 4 4 // // # of usage entries 5 5 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntryIsSecureStop_MoveSecureStopEntryFailed) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -2277,9 +2270,10 @@ TEST_F(UsageTableHeaderTest, SetArgPointee<8>(kCryptoWrappedKey), Return(true))); // Calls during Move(). - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // No calls to shrink are expected. @@ -2294,11 +2288,11 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoSecureStop3))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2317,7 +2311,7 @@ TEST_F(UsageTableHeaderTest, // the entries inplace. // e. Usage table will be resized to remove the last two entries. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2331,22 +2325,22 @@ TEST_F(UsageTableHeaderTest, // Storage Type Unknown 6 Deleted // // # of usage entries 7 5 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntriesAreOfflineAndUnknown_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); // Expect calls for moving offline license 3 (position 4), but // failure to move will not result in any calls for updating. @@ -2372,7 +2366,7 @@ TEST_F(UsageTableHeaderTest, NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // Expect calls for moving offline license 2 (position 3), but // failure to move will not result in any calls for updating. @@ -2398,14 +2392,14 @@ TEST_F(UsageTableHeaderTest, NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // Expect a call to shrink table to cut off only the unknown entries // at the end of the table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 5, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); // Update table for the entry now marked storage type unknown and // the entries that were cut off. @@ -2418,12 +2412,12 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoOfflineLicense3))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2442,7 +2436,7 @@ TEST_F(UsageTableHeaderTest, // the entries inplace. // e. Usage table will be resized to remove the last two entries. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2457,22 +2451,22 @@ TEST_F(UsageTableHeaderTest, // // # of usage entries 7 5 TEST_F( - UsageTableHeaderTest, + CdmUsageTableTest, InvalidateEntry_LastEntriesAreSecureStopAndUnknown_MoveOfflineEntryFailed) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); // Expect calls for moving streaming license 3 (position 4), but // failure to move will not result in any calls for updating. @@ -2488,7 +2482,7 @@ TEST_F( SetArgPointee<7>(kDrmCertificate), SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // Expect calls for moving streaming license 2 (position 3), but // failure to move will not result in any calls for updating. @@ -2504,14 +2498,14 @@ TEST_F( SetArgPointee<7>(kDrmCertificate), SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION))); // Expect a call to shrink table to cut off only the unknown entries // at the end of the table. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 5, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); // Update table for the entry now marked storage type unknown and // the entries that were cut off. @@ -2524,12 +2518,12 @@ TEST_F( kUsageEntryInfoSecureStop3))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 5; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2543,7 +2537,7 @@ TEST_F( // c. The selected entries will be moved. // d. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2555,14 +2549,14 @@ TEST_F( // Offline License 3 4 1 (moved) // // # of usage entries 5 3 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntryIsOffline) { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; @@ -2581,7 +2575,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(4), + static_cast(4), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2591,8 +2585,9 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)).WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expect calls for moving offline license 2 (position 3) to position 2. const DeviceFiles::CdmLicenseData offline_license_2_data{ @@ -2609,7 +2604,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(3), + static_cast(3), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2619,13 +2614,14 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)).WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Common to both moves. EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*device_files_, StoreLicense(_, NotNull())) .Times(2) .WillRepeatedly(Return(true)); @@ -2633,7 +2629,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { .Times(2) .WillRepeatedly(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), SetArgPointee<1>(kAnotherUsageEntry), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)) .Times(2) .WillRepeatedly(Return(true)); @@ -2641,8 +2637,8 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // Shrink to contain the remaining valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 3, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, ElementsAre(kUsageEntryInfoSecureStop1, @@ -2650,12 +2646,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2669,7 +2665,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // c. The selected entries will be moved. // d. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2681,14 +2677,14 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsOffline) { // Secure stop 3 4 1 (moved) // // # of usage entries 5 3 -TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntryIsSecureStop) { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -2715,7 +2711,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { kUsageEntryInfoSecureStop3.key_set_id, _, 1, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)); // Expect calls for moving streaming license 2 (position 3) to position 2. @@ -2741,18 +2737,18 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { kUsageEntryInfoSecureStop2.key_set_id, _, 2, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)); // Common to both moves. EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .Times(2) .WillRepeatedly(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), SetArgPointee<1>(kAnotherUsageEntry), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)) .Times(2) .WillRepeatedly(Return(true)); @@ -2760,8 +2756,8 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { // Shrink to contain the remaining valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 3, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, ElementsAre(kUsageEntryInfoOfflineLicense1, @@ -2769,12 +2765,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { kUsageEntryInfoSecureStop2))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2789,7 +2785,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { // c. The selected entries will be moved. // d. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2803,16 +2799,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { // Storage Type Unknown 6 Deleted // // # of usage entries 7 4 -TEST_F(UsageTableHeaderTest, - InvalidateEntry_LastEntriesAreOfflineAndUnknknown) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntriesAreOfflineAndUnknknown) { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoOfflineLicense1 metrics::CryptoMetrics metrics; @@ -2831,7 +2826,7 @@ TEST_F(UsageTableHeaderTest, kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(4), + static_cast(4), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2841,8 +2836,9 @@ TEST_F(UsageTableHeaderTest, .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_3_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)).WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expect calls for moving offline license 2 (position 3) to position 2. const DeviceFiles::CdmLicenseData offline_license_2_data{ @@ -2859,7 +2855,7 @@ TEST_F(UsageTableHeaderTest, kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(3), + static_cast(3), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -2869,13 +2865,14 @@ TEST_F(UsageTableHeaderTest, .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_2_data), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)).WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Common to both moves. EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*device_files_, StoreLicense(_, NotNull())) .Times(2) .WillRepeatedly(Return(true)); @@ -2883,7 +2880,7 @@ TEST_F(UsageTableHeaderTest, .Times(2) .WillRepeatedly(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), SetArgPointee<1>(kAnotherUsageEntry), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)) .Times(2) .WillRepeatedly(Return(true)); @@ -2891,8 +2888,8 @@ TEST_F(UsageTableHeaderTest, // Shrink to contain the remaining valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 3, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, ElementsAre(kUsageEntryInfoSecureStop1, @@ -2900,12 +2897,12 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoOfflineLicense2))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -2919,7 +2916,7 @@ TEST_F(UsageTableHeaderTest, // c. The selected entries will be moved. // d. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -2933,16 +2930,16 @@ TEST_F(UsageTableHeaderTest, // Storage Type unknown 6 Deleted // // # of usage entries 7 3 -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, InvalidateEntry_LastEntriesAreSecureStopAndUnknknown) { - const std::vector usage_entry_info_vector = { + const std::vector entry_info_list = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2, kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -2969,7 +2966,7 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoSecureStop3.key_set_id, _, 1, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, MoveUsageEntry(1)); // Expect calls for moving streaming license 2 (position 3) to position 2. @@ -2995,18 +2992,18 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoSecureStop2.key_set_id, _, 2, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, MoveUsageEntry(2)); // Common to both moves. EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) .Times(2) - .WillRepeatedly(Return(NO_ERROR)); + .WillRepeatedly(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .Times(2) .WillRepeatedly(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), SetArgPointee<1>(kAnotherUsageEntry), - Return(NO_ERROR))); + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)) .Times(2) .WillRepeatedly(Return(true)); @@ -3014,8 +3011,8 @@ TEST_F(UsageTableHeaderTest, // Shrink to contain the remaining valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 3, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kYetAnotherUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kYetAnotherUsageEntry, @@ -3024,12 +3021,12 @@ TEST_F(UsageTableHeaderTest, kUsageEntryInfoSecureStop2))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 3; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // Initial Test state: @@ -3041,7 +3038,7 @@ TEST_F(UsageTableHeaderTest, // b. Defrag is skipped (no calls to Move()). // c. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3055,38 +3052,38 @@ TEST_F(UsageTableHeaderTest, // Storage Type Unknown 6 Deleted // // # of usage entries 7 0 -TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_NoValidSessionsAfter) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 3; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; // No calls related to defragging, just shrinking the table and save. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 0, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); - EXPECT_TRUE(usage_table_header_->usage_entry_info().empty()); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); + EXPECT_TRUE(usage_table_->entry_info_list().empty()); } // 1. Usage entry to be deleted is last valid entry (Secure stop 1) // 2. There exists an entry to be moved (Offline License 1) // 3. OEMCrypto is at max sessions, and any attempt to open a new session -// will fail with INSUFFICIENT_CRYPTO_RESOURCES. +// will fail with CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES). // // Attempting to delete the entry in (1) will result in: // a. The entry will be marked as kStorageTypeUnknown. @@ -3095,7 +3092,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { // d. Defrag is aborted; but shrink is still made up to last valid. // e. Usage table will be resized. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3106,13 +3103,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_NoValidSessionsAfter) { // Storage Type Unknown 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_MaxSessionReached) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3132,7 +3129,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -3140,32 +3137,32 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) - .WillRepeatedly(Return(INSUFFICIENT_CRYPTO_RESOURCES)); + .WillRepeatedly(Return(CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES))); // Despite being unable to open session, the table should be resized to // exclude the trailing invalid entries. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // 1. Usage entry to be deleted is first valid entry (Secure stop 1) // 2. There exists an entry to be moved (Offline License 1) // 3. OEMCrypto is at max sessions, and any attempt to open a new session -// will fail with INSUFFICIENT_CRYPTO_RESOURCES. +// will fail with CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES). // // Attempting to delete the entry in (1) will result in: // a. The entry will be marked as kStorageTypeUnknown. @@ -3174,7 +3171,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { // d. Defrag is aborted; but shrink is still made up to last valid. // e. Usage table will be resized. // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3185,13 +3182,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_MaxSessionReached) { // Storage Type Unknown 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_FirstEntry_MaxSessionReached) { + const std::vector entry_info_list = { kUsageEntryInfoSecureStop1, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 0; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3211,7 +3208,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -3219,26 +3216,26 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) - .WillRepeatedly(Return(INSUFFICIENT_CRYPTO_RESOURCES)); + .WillRepeatedly(Return(CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES))); // Despite being unable to open session, the table should be resized to // exclude the trailing invalid entries. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce( - DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, ElementsAre(kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // 1. Usage entry to be deleted is last valid entry (Secure stop 1) @@ -3262,13 +3259,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_FirstEntry_MaxSessionReached) { // Storage Type Unknown 3 3 // // # of usage entries 4 4 -TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_SystemInvalidation_OnMove) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3288,17 +3285,18 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(1, kUsageEntry)); EXPECT_CALL(*crypto_session_, MoveUsageEntry(0)) - .WillOnce(Return(SYSTEM_INVALIDATED_ERROR)); + .WillOnce(Return(CdmResponseType(SYSTEM_INVALIDATED_ERROR))); // Defrag is aborted, and table is saved, but no call to shrink(). EXPECT_CALL( @@ -3310,12 +3308,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { kUsageEntryInfoStorageTypeUnknown))) .WillOnce(Return(true)); - EXPECT_EQ(SYSTEM_INVALIDATED_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, - true, device_files_, &metrics)); + EXPECT_EQ(SYSTEM_INVALIDATED_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // 1. Usage entry to be deleted is last valid entry (Secure stop 1) @@ -3324,7 +3322,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // // Note: This is very similar to InvalidateEntry_SystemInvalidation_OnMove // except that the error returned is not of importance to the calling -// session and is ignored (NO_ERROR returned). +// session and is ignored (CdmResponseType(NO_ERROR) returned). // // Attempting to delete the entry in (1) will result in: // a. The entry will be marked as kStorageTypeUnknown. @@ -3332,7 +3330,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // c. Moving entry will result in session invalidation. // d. Defrag is aborted; no call to Shrink() // f. Updated table will be saved. -// g. InvalidateEntry() will return NO_ERROR. +// g. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3343,13 +3341,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SystemInvalidation_OnMove) { // Storage Type Unknown 3 3 // // # of usage entries 4 4 -TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_SessionInvalidation_OnMove) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3369,17 +3367,18 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(1, kUsageEntry)); EXPECT_CALL(*crypto_session_, MoveUsageEntry(0)) - .WillOnce(Return(SESSION_LOST_STATE_ERROR)); + .WillOnce(Return(CdmResponseType(SESSION_LOST_STATE_ERROR))); // Defrag is aborted, and table is saved, but no call to shrink(). EXPECT_CALL( @@ -3392,12 +3391,12 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { .WillOnce(Return(true)); // The underlying error should not be returned to the caller. - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // 1. Usage entry to be deleted is last valid entry (Secure stop 1) @@ -3408,9 +3407,10 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { // a. The entry will be marked as kStorageTypeUnknown. // b. Only remaining entry is selected for move (Offline license 1) // c. Entry will be moved successfully. -// d. Shrinking table fill fail with SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE. -// f. Updated table will be saved, with trailing invalid entries. -// g. InvalidateEntry() will return NO_ERROR. +// d. Shrinking table fill fail with +// CdmResponseType(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE). f. Updated table +// will be saved, with trailing invalid entries. g. InvalidateEntry() will +// return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3421,13 +3421,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_SessionInvalidation_OnMove) { // Storage Type Unknown 3 3 // // # of usage entries 4 4 -TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_ShrinkFails) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3446,7 +3446,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, @@ -3455,12 +3455,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { .Times(2) // First to get entry, then again to update. .WillRepeatedly( DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(1, kUsageEntry)); - EXPECT_CALL(*crypto_session_, MoveUsageEntry(0)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, MoveUsageEntry(0)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), - SetArgPointee<1>(kUsageEntry), Return(NO_ERROR))); + SetArgPointee<1>(kUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL( *device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, @@ -3476,14 +3479,15 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { // entry being in use. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 1, NotNull())) - .WillOnce(Return(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE)); + .WillOnce( + Return(CdmResponseType(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE))); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 4; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // 1. Usage entry to be deleted is last valid entry (Secure stop 1) @@ -3497,7 +3501,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { // c. Call to move will fail with MOVE_USAGE_ENTRY_DESTINATION_IN_USE. // d. Usage table will be resized. // e. Updated table will be saved. -// f. InvalidateEntry() will return NO_ERROR. +// f. InvalidateEntry() will return CdmResponseType(NO_ERROR). // // Storage type Usage entries // at start at end @@ -3508,13 +3512,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_ShrinkFails) { // Storage Type Unknown 3 Deleted // // # of usage entries 4 2 -TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { - const std::vector usage_entry_info_vector = { +TEST_F(CdmUsageTableTest, InvalidateEntry_DestinationInUse_OnMove) { + const std::vector entry_info_list = { kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown}; - Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector); - const uint32_t usage_entry_number_to_be_deleted = + Init(kSecurityLevelL1, kUsageTableHeader, entry_info_list); + const UsageEntryIndex entry_index_to_be_deleted = 2; // kUsageEntryInfoSecureStop1 metrics::CryptoMetrics metrics; @@ -3534,73 +3538,76 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_DestinationInUse_OnMove) { kGracePeriodEndTime, kEmptyAppParameters, kUsageEntry, - static_cast(1), + static_cast(1), kDrmCertificate, kCryptoWrappedKey}; EXPECT_CALL(*device_files_, RetrieveLicense(kUsageEntryInfoOfflineLicense1.key_set_id, NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<1>(offline_license_1_data), Return(true))); - EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, Open(kLevelDefault)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(1, kUsageEntry)); EXPECT_CALL(*crypto_session_, MoveUsageEntry(0)) - .WillOnce(Return(MOVE_USAGE_ENTRY_DESTINATION_IN_USE)); + .WillOnce(Return(CdmResponseType(MOVE_USAGE_ENTRY_DESTINATION_IN_USE))); // No expectations for updating the entry or the header from the move // operation. // Shrink table down to the last valid entry. EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 2, NotNull())) - .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageEntry), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<2>(kAnotherUsageEntry), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageEntry, ElementsAre(kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense1))) .WillOnce(Return(true)); - EXPECT_EQ(NO_ERROR, usage_table_header_->InvalidateEntry( - usage_entry_number_to_be_deleted, true, device_files_, - &metrics)); + EXPECT_EQ(NO_ERROR, + usage_table_->InvalidateEntry(entry_index_to_be_deleted, true, + device_files_, &metrics)); // Check the end state of the usage table. constexpr size_t expected_size = 2; - EXPECT_EQ(expected_size, usage_table_header_->usage_entry_info().size()); + EXPECT_EQ(expected_size, usage_table_->entry_info_list().size()); } // If the crypto session says the usage table header is stale, init should fail. -TEST_F(UsageTableHeaderTest, StaleHeader) { - std::vector usage_entry_info_vector; +TEST_F(CdmUsageTableTest, StaleHeader) { + std::vector entry_info_list; const CdmUsageEntryInfo usage_entry_info_array[] = { kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2}; - ToVector(usage_entry_info_vector, usage_entry_info_array, + ToVector(entry_info_list, usage_entry_info_array, sizeof(usage_entry_info_array)); EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader), - SetArgPointee<1>(usage_entry_info_vector), + SetArgPointee<1>(entry_info_list), SetArgPointee<2>(false), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUsageTableHeader)) - .WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW)); + .WillOnce(Return(CdmResponseType(LOAD_USAGE_HEADER_GENERATION_SKEW))); ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(kLevelDefault, NotNull())) - .WillOnce( - DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); } -// Testing of the private function UsageTableHeader::Shrink. +// Testing of the private function CdmUsageTable::Shrink. // Don't shrink any entries. -TEST_F(UsageTableHeaderTest, Shrink_NoneOfTable) { +TEST_F(CdmUsageTableTest, Shrink_NoneOfTable) { Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); metrics::CryptoMetrics metrics; @@ -3611,11 +3618,11 @@ TEST_F(UsageTableHeaderTest, Shrink_NoneOfTable) { .Times(0); EXPECT_CALL(*device_files_, StoreUsageTableInfo(_, _)).Times(0); - EXPECT_EQ(usage_table_header_->Shrink(&metrics, 0), NO_ERROR); + EXPECT_EQ(usage_table_->Shrink(&metrics, 0), CdmResponseType(NO_ERROR)); } // Shrink some of the table, but not all of it. -TEST_F(UsageTableHeaderTest, Shrink_PartOfTable) { +TEST_F(CdmUsageTableTest, Shrink_PartOfTable) { Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); const uint32_t to_shink = 5; const std::vector shrunken_entries( @@ -3627,48 +3634,48 @@ TEST_F(UsageTableHeaderTest, Shrink_PartOfTable) { ShrinkUsageTableHeader( kLevelDefault, static_cast(shrunken_entries.size()), NotNull())) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, shrunken_entries)) .WillOnce(Return(true)); - EXPECT_EQ(usage_table_header_->Shrink(&metrics, to_shink), NO_ERROR); + EXPECT_EQ(usage_table_->Shrink(&metrics, to_shink), + CdmResponseType(NO_ERROR)); } // Shrink all of the table, no entries left. -TEST_F(UsageTableHeaderTest, Shrink_AllOfTable) { +TEST_F(CdmUsageTableTest, Shrink_AllOfTable) { Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 0, NotNull())) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_EQ( - usage_table_header_->Shrink( - &metrics, static_cast(k10UsageEntryInfoVector.size())), - NO_ERROR); + EXPECT_EQ(usage_table_->Shrink(&metrics, static_cast( + k10UsageEntryInfoVector.size())), + CdmResponseType(NO_ERROR)); } // Request to shrink more entries than there are in the table; should remove // all entries, but log a warning. -TEST_F(UsageTableHeaderTest, Shrink_MoreThanTable) { +TEST_F(CdmUsageTableTest, Shrink_MoreThanTable) { Init(kSecurityLevelL1, kUsageTableHeader, k10UsageEntryInfoVector); metrics::CryptoMetrics metrics; EXPECT_CALL(*crypto_session_, ShrinkUsageTableHeader(kLevelDefault, 0, NotNull())) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); EXPECT_EQ( - usage_table_header_->Shrink( + usage_table_->Shrink( &metrics, static_cast(k10UsageEntryInfoVector.size()) + 10), - NO_ERROR); + CdmResponseType(NO_ERROR)); } // LRU Usage Table Upgrade Test @@ -3677,19 +3684,20 @@ TEST_F(UsageTableHeaderTest, Shrink_MoreThanTable) { // 1. Table info is load from device files and device files reports that // the table header and entries are configured for LRU. // 2. No upgrading action is taken. -TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) { +TEST_F(CdmUsageTableTest, LruUsageTableUpgrade_NoAction) { EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader), SetArgPointee<1>(kUpgradableUsageEntryInfoList), - SetArgPointee<2>(/* lru_upgrade = */ false), + SetArgPointee<2>(false), // lru_upgrade Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); // These function are called specifically by the LRU upgrading system. EXPECT_CALL(*device_files_, RetrieveLicense(_, _, _)).Times(0); @@ -3697,9 +3705,8 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) { RetrieveUsageInfoByKeySetId(_, _, _, _, _, _, _, _, _)) .Times(0); - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(usage_table_header_->usage_entry_info(), - kUpgradableUsageEntryInfoList); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_EQ(usage_table_->entry_info_list(), kUpgradableUsageEntryInfoList); } // Initial Test state: @@ -3707,19 +3714,20 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) { // that the table has not been configured for upgrade. // 2. The usage table header will load license or usage information to // determine appropriate expiry and last_used times. -TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { +TEST_F(CdmUsageTableTest, LruUsageTableUpgrade_Succeed) { EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader), SetArgPointee<1>(kUpgradableUsageEntryInfoList), - SetArgPointee<2>(/* lru_upgrade = */ true), + SetArgPointee<2>(true), // lru_upgrade Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) { const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i]; @@ -3736,15 +3744,14 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { NotNull(), NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<4>(kUpgradableLicenseInfoList[i]), - SetArgPointee<6>(static_cast(i)), + SetArgPointee<6>(static_cast(i)), SetArgPointee<7>(kDrmCertificate), SetArgPointee<8>(kCryptoWrappedKey), Return(true))); } } - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(usage_table_header_->usage_entry_info(), - kUpgradedUsageEntryInfoList); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_EQ(usage_table_->entry_info_list(), kUpgradedUsageEntryInfoList); } // Initial Test state: @@ -3758,7 +3765,7 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { // 0 Offline Upgraded // 1 Unknown Cleared // 2 Invalid (99) Cleared -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, LruUsageTableUpgrade_PartialSucceedWithUnknownStorageTypes) { std::vector upgradable_usage_entry_info_list = kUpgradableUsageEntryInfoList; @@ -3779,16 +3786,17 @@ TEST_F(UsageTableHeaderTest, // Load table expectations. EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader), SetArgPointee<1>(upgradable_usage_entry_info_list), - SetArgPointee<2>(/* lru_upgrade = */ true), + SetArgPointee<2>(true), // lru_upgrade Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); // Expectations of the one successful license. EXPECT_CALL(*device_files_, @@ -3797,9 +3805,8 @@ TEST_F(UsageTableHeaderTest, .WillOnce( DoAll(SetArgPointee<1>(kUpgradableLicenseDataList[0]), Return(true))); - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(upgraded_usage_entry_info_list, - usage_table_header_->usage_entry_info()); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_EQ(upgraded_usage_entry_info_list, usage_table_->entry_info_list()); } // Initial Test state: @@ -3813,7 +3820,7 @@ TEST_F(UsageTableHeaderTest, // 0 Offline No signature Cleared // 1 Streaming Wrong type Cleared // 2 Offline Upgraded -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, LruUsageTableUpgrade_PartialSucceedWithLicenseParseIssues) { std::vector license_data_list = kUpgradableLicenseDataList; @@ -3842,16 +3849,17 @@ TEST_F(UsageTableHeaderTest, EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader), SetArgPointee<1>(kUpgradableUsageEntryInfoList), - SetArgPointee<2>(/* lru_upgrade = */ true), + SetArgPointee<2>(true), // lru_upgrade Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) { const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i]; @@ -3867,7 +3875,7 @@ TEST_F(UsageTableHeaderTest, NotNull(), NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<4>(upgradable_license_info_list[i]), - SetArgPointee<6>(static_cast(i)), + SetArgPointee<6>(static_cast(i)), SetArgPointee<7>(kDrmCertificate), SetArgPointee<8>(kCryptoWrappedKey), Return(true))); } @@ -3888,28 +3896,28 @@ TEST_F(UsageTableHeaderTest, ContainerEq(corrupted_usage_info_key_set_ids))) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); - EXPECT_EQ(upgraded_usage_entry_info_list, - usage_table_header_->usage_entry_info()); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_EQ(upgraded_usage_entry_info_list, usage_table_->entry_info_list()); } // Initial Test state: // 1. Table info is load from device files; however, device files reports // that the table has not been configured for upgrade. // 2. None of the entries can have their license info loaded. -TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) { +TEST_F(CdmUsageTableTest, LruUsageTableUpgrade_AllFailure) { EXPECT_CALL(*crypto_session_, GetNumberOfOpenSessions(kLevelDefault, NotNull())) - .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<1>(0), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kUpgradableUsageTableHeader), SetArgPointee<1>(kUpgradableUsageEntryInfoList), - SetArgPointee<2>(/* lru_upgrade = */ true), + SetArgPointee<2>(true), // lru_upgrade Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kLevelDefault, kUpgradableUsageTableHeader)) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); for (size_t i = 0; i < kUpgradableUsageEntryInfoList.size(); ++i) { const CdmUsageEntryInfo& info = kUpgradableUsageEntryInfoList[i]; @@ -3933,21 +3941,22 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) { ExpectToDeleteUsageTableFiles(); EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(kLevelDefault, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUsageTableHeader, kEmptyUsageEntryInfoVector)) .WillOnce(Return(true)); - EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); + EXPECT_TRUE(usage_table_->Init(kSecurityLevelL1, crypto_session_)); } -TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) { +TEST_F(CdmUsageTableTest, LruLastUsedTime_CreateLicenseEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); // Expected values. - const uint32_t expected_usage_entry_number = - static_cast(kUpgradedUsageEntryInfoList.size()); + const UsageEntryIndex expected_entry_index = + static_cast(kUpgradedUsageEntryInfoList.size()); const CdmUsageEntryInfo expected_new_entry = { kStorageLicense, "offline_key_set_4", "", kLruBaseTime, kLruBaseTime + kDefaultExpireDuration}; @@ -3957,35 +3966,35 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateLicenseEntry) { // AddKey expectations EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(expected_usage_entry_number), - Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(expected_entry_index), + Return(CdmResponseType(NO_ERROR)))); MockClock mock_clock; - usage_table_header_->SetClock(&mock_clock); + usage_table_->SetClock(&mock_clock); EXPECT_CALL(mock_clock, GetCurrentTime()).WillOnce(Return(kLruBaseTime)); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)); // The Call. - uint32_t usage_entry_number = 0; - EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( + UsageEntryIndex entry_index = 0; + EXPECT_EQ(NO_ERROR, usage_table_->AddEntry( crypto_session_, true /* persistent_license */, expected_new_entry.key_set_id, expected_new_entry.usage_info_file_name, kEmptyString, - &usage_entry_number)); + &entry_index)); - EXPECT_EQ(expected_usage_entry_number, usage_entry_number); - EXPECT_EQ(expected_usage_info_list, usage_table_header_->usage_entry_info()); + EXPECT_EQ(expected_entry_index, entry_index); + EXPECT_EQ(expected_usage_info_list, usage_table_->entry_info_list()); } -TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) { +TEST_F(CdmUsageTableTest, LruLastUsedTime_CreateUsageInfoEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); // Expected values. - const uint32_t expected_usage_entry_number = - static_cast(kUpgradedUsageEntryInfoList.size()); + const UsageEntryIndex expected_entry_index = + static_cast(kUpgradedUsageEntryInfoList.size()); const CdmUsageEntryInfo expected_new_entry = { kStorageUsageInfo, "secure_stop_key_set_5", "streaming_license_file_4", kLruBaseTime, 0 /* No set for streaming license. */ @@ -3996,91 +4005,85 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_CreateUsageInfoEntry) { // AddKey expectations EXPECT_CALL(*crypto_session_, CreateUsageEntry(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(expected_usage_entry_number), - Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(expected_entry_index), + Return(CdmResponseType(NO_ERROR)))); MockClock mock_clock; - usage_table_header_->SetClock(&mock_clock); + usage_table_->SetClock(&mock_clock); EXPECT_CALL(mock_clock, GetCurrentTime()).WillOnce(Return(kLruBaseTime)); EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce( - DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<0>(kAnotherUsageTableHeader), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kAnotherUsageTableHeader, _)); // The Call. - uint32_t usage_entry_number = 0; - EXPECT_EQ(NO_ERROR, usage_table_header_->AddEntry( + UsageEntryIndex entry_index = 0; + EXPECT_EQ(NO_ERROR, usage_table_->AddEntry( crypto_session_, false /* persistent_license */, expected_new_entry.key_set_id, expected_new_entry.usage_info_file_name, kEmptyString, - &usage_entry_number)); + &entry_index)); - EXPECT_EQ(expected_usage_entry_number, usage_entry_number); - EXPECT_EQ(expected_usage_info_list, usage_table_header_->usage_entry_info()); + EXPECT_EQ(expected_entry_index, entry_index); + EXPECT_EQ(expected_usage_info_list, usage_table_->entry_info_list()); } -TEST_F(UsageTableHeaderTest, LruLastUsedTime_UpdateEntry) { +TEST_F(CdmUsageTableTest, LruLastUsedTime_UpdateEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); std::vector expected_usage_info_list = kUpgradedUsageEntryInfoList; MockClock mock_clock; - usage_table_header_->SetClock(&mock_clock); + usage_table_->SetClock(&mock_clock); const int64_t expected_update_time = kLruBaseTime + 60 * 60; // Any value larger than the original works. - for (uint32_t usage_entry_number = 0; - usage_entry_number < expected_usage_info_list.size(); - ++usage_entry_number) { + for (UsageEntryIndex entry_index = 0; + entry_index < expected_usage_info_list.size(); ++entry_index) { // Update expected values. - expected_usage_info_list[usage_entry_number].last_use_time = - expected_update_time; + expected_usage_info_list[entry_index].last_use_time = expected_update_time; // Update expectations EXPECT_CALL(*crypto_session_, UpdateUsageEntry(NotNull(), NotNull())) - .WillOnce(Return(NO_ERROR)); + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(mock_clock, GetCurrentTime()) .WillOnce(Return(expected_update_time)); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kUpgradedUsageTableHeader, _)); // The Call. - CdmUsageEntry usage_entry; - EXPECT_EQ(NO_ERROR, usage_table_header_->UpdateEntry( - usage_entry_number, crypto_session_, &usage_entry)); - EXPECT_EQ(expected_usage_info_list, - usage_table_header_->usage_entry_info()); + UsageEntry usage_entry; + EXPECT_EQ(NO_ERROR, usage_table_->UpdateEntry(entry_index, crypto_session_, + &usage_entry)); + EXPECT_EQ(expected_usage_info_list, usage_table_->entry_info_list()); } } -TEST_F(UsageTableHeaderTest, LruLastUsedTime_LoadEntry) { +TEST_F(CdmUsageTableTest, LruLastUsedTime_LoadEntry) { Init(kSecurityLevelL1, kUpgradedUsageTableHeader, kUpgradedUsageEntryInfoList); std::vector expected_usage_info_list = kUpgradedUsageEntryInfoList; MockClock mock_clock; - usage_table_header_->SetClock(&mock_clock); + usage_table_->SetClock(&mock_clock); const int64_t expected_update_time = kLruBaseTime + 60 * 60; // Any value larger than the original works. - for (uint32_t usage_entry_number = 0; - usage_entry_number < expected_usage_info_list.size(); - ++usage_entry_number) { + for (UsageEntryIndex entry_index = 0; + entry_index < expected_usage_info_list.size(); ++entry_index) { // Update expected values. - expected_usage_info_list[usage_entry_number].last_use_time = - expected_update_time; + expected_usage_info_list[entry_index].last_use_time = expected_update_time; // Update expectations - EXPECT_CALL(*crypto_session_, LoadUsageEntry(usage_entry_number, _)) - .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, LoadUsageEntry(entry_index, _)) + .WillOnce(Return(CdmResponseType(NO_ERROR))); EXPECT_CALL(mock_clock, GetCurrentTime()) .WillOnce(Return(expected_update_time)); // The Call. - CdmUsageEntry usage_entry; - EXPECT_EQ(NO_ERROR, usage_table_header_->LoadEntry( - crypto_session_, kEmptyString, usage_entry_number)); - EXPECT_EQ(expected_usage_info_list, - usage_table_header_->usage_entry_info()); + UsageEntry usage_entry; + EXPECT_EQ(NO_ERROR, usage_table_->LoadEntry(crypto_session_, kEmptyString, + entry_index)); + EXPECT_EQ(expected_usage_info_list, usage_table_->entry_info_list()); } } @@ -4089,17 +4092,17 @@ TEST_F(UsageTableHeaderTest, LruLastUsedTime_LoadEntry) { // This testcase is intended to push the boundaries of valid inputs to // the LRU algorithm. None of these are expected inputs under normal // operations. -TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_InvalidInput) { +TEST_F(CdmUsageTableTest, DetermineLicenseToRemove_InvalidInput) { constexpr size_t kUnexpiredThreshold = 50; // Arbitrary std::vector usage_entry_info_list; - uint32_t entry_to_remove = 0; + UsageEntryIndex entry_to_remove = 0; // Empty list. - EXPECT_FALSE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_FALSE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kLruBaseTime, kUnexpiredThreshold, &entry_to_remove)); // Output is null. usage_entry_info_list = kUpgradedUsageEntryInfoList; - EXPECT_FALSE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_FALSE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kLruBaseTime, kUnexpiredThreshold, nullptr)); } @@ -4107,10 +4110,10 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_InvalidInput) { // Expects that unknown entries to be chosen above all others. // Unexpired licenses should only be considered if the threshold // is met. -TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { +TEST_F(CdmUsageTableTest, DetermineLicenseToRemove_BasicPriorities) { constexpr int64_t kOneDay = 24 * 60 * 60; constexpr int64_t kCurrentTime = kLruBaseTime + kOneDay; - constexpr uint32_t kInvalidEntry = 9999; + constexpr UsageEntryIndex kInvalidEntry = 9999; std::vector usage_entry_info_list; // Unexpired offline license. @@ -4119,7 +4122,7 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { unexpired_entry_info.last_use_time = kLruBaseTime; unexpired_entry_info.offline_license_expiry_time = kLruBaseTime + 2 * kOneDay; usage_entry_info_list.push_back(unexpired_entry_info); - constexpr uint32_t unexpired_entry_number = 0; + constexpr UsageEntryIndex unexpired_entry_index = 0; // Expired offline license. CdmUsageEntryInfo expired_entry_info; @@ -4127,14 +4130,14 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { expired_entry_info.last_use_time = kLruBaseTime; expired_entry_info.offline_license_expiry_time = kLruBaseTime; usage_entry_info_list.push_back(expired_entry_info); - constexpr uint32_t expired_entry_number = 1; + constexpr UsageEntryIndex expired_entry_index = 1; // Streaming license. CdmUsageEntryInfo streaming_entry_info; streaming_entry_info.storage_type = kStorageUsageInfo; streaming_entry_info.last_use_time = kLruBaseTime; usage_entry_info_list.push_back(streaming_entry_info); - constexpr uint32_t streaming_entry_number = 2; + constexpr UsageEntryIndex streaming_entry_index = 2; // Unknown entry. CdmUsageEntryInfo unknown_entry_info; @@ -4142,35 +4145,35 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { // Should be chosen regardless of |last_use_time|. unknown_entry_info.last_use_time = kCurrentTime; usage_entry_info_list.push_back(unknown_entry_info); - constexpr uint32_t unknown_entry_number = 3; + constexpr UsageEntryIndex unknown_entry_index = 3; // Case 1: If there is an entry with unknown storage type, it should // be selected above any other entry. - uint32_t entry_to_remove = kInvalidEntry; + UsageEntryIndex entry_to_remove = kInvalidEntry; // Expect the unknown entry. - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(unknown_entry_number, entry_to_remove); + EXPECT_EQ(unknown_entry_index, entry_to_remove); usage_entry_info_list.pop_back(); // Removing unknown. // Case 2a: Threshold not met, all entries are equally stale. // The expired entry should be selected over the streaming license. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(expired_entry_number, entry_to_remove); + EXPECT_EQ(expired_entry_index, entry_to_remove); // Case 2b: Threshold not met, streaming license is most stale. - usage_entry_info_list[streaming_entry_number].last_use_time--; + usage_entry_info_list[streaming_entry_index].last_use_time--; entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(streaming_entry_number, entry_to_remove); + EXPECT_EQ(streaming_entry_index, entry_to_remove); usage_entry_info_list.pop_back(); // Removing streaming. // |usage_entry_info_list| only contains 1 expired and 1 unexpired offline @@ -4179,72 +4182,71 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_BasicPriorities) { // Case 2c: Threshold met, equally stale entries. Expect the expired // entry over the unexpired. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); - EXPECT_EQ(expired_entry_number, entry_to_remove); + EXPECT_EQ(expired_entry_index, entry_to_remove); // Case 3a: Threshold not met, expired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time--; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + usage_entry_info_list[expired_entry_index].last_use_time--; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(expired_entry_number, entry_to_remove); + EXPECT_EQ(expired_entry_index, entry_to_remove); // Case 3b: Threshold not met, unexpired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time++; - usage_entry_info_list[unexpired_entry_number].last_use_time--; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + usage_entry_info_list[expired_entry_index].last_use_time++; + usage_entry_info_list[unexpired_entry_index].last_use_time--; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(expired_entry_number, entry_to_remove); + EXPECT_EQ(expired_entry_index, entry_to_remove); // Case 3c: Threshold met, unexpired entry is the most stale. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); - EXPECT_EQ(unexpired_entry_number, entry_to_remove); + EXPECT_EQ(unexpired_entry_index, entry_to_remove); // Case 3d: Threshold met, expired entry is the most stale. entry_to_remove = kInvalidEntry; - usage_entry_info_list[expired_entry_number].last_use_time--; - usage_entry_info_list[unexpired_entry_number].last_use_time++; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + usage_entry_info_list[expired_entry_index].last_use_time--; + usage_entry_info_list[unexpired_entry_index].last_use_time++; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); - EXPECT_EQ(expired_entry_number, entry_to_remove); + EXPECT_EQ(expired_entry_index, entry_to_remove); usage_entry_info_list.pop_back(); // Removing expired offline. // Case 4a: Threshold met, and only an unexpired offline license // is available. entry_to_remove = kInvalidEntry; // Invalidate value. - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); - EXPECT_EQ(unexpired_entry_number, entry_to_remove); + EXPECT_EQ(unexpired_entry_index, entry_to_remove); // Case 4b (stability check): Threshold not met, and only an // unexpired offline license is available. This is an unexpected // condition in normal operation, but the algorithm should still // return an entry. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 3, &entry_to_remove)); - EXPECT_EQ(unexpired_entry_number, entry_to_remove); + EXPECT_EQ(unexpired_entry_index, entry_to_remove); } // Testing algorithm with unexpired offline and streaming license. The // sum of offline licenses is below the threshold for consideration. // Only the streaming license should be considered for removal. -TEST_F(UsageTableHeaderTest, - DetermineLicenseToRemove_NoExpiredAndBelowThreshold) { +TEST_F(CdmUsageTableTest, DetermineLicenseToRemove_NoExpiredAndBelowThreshold) { constexpr int64_t kOneDay = 24 * 60 * 60; - constexpr uint32_t kInvalidEntry = 9999; + constexpr UsageEntryIndex kInvalidEntry = 9999; std::vector usage_entry_info_list = kUpgradedUsageEntryInfoList; const size_t offline_threshold = usage_entry_info_list.size() + 1; @@ -4265,8 +4267,8 @@ TEST_F(UsageTableHeaderTest, // Must exist at least one streaming license for test to work. ASSERT_LT(0ull, usage_info_count); - uint32_t entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + UsageEntryIndex entry_to_remove = kInvalidEntry; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kLruBaseTime, offline_threshold, &entry_to_remove)); @@ -4279,20 +4281,20 @@ TEST_F(UsageTableHeaderTest, // should be considered. // Providing only offline licenses, only the expired license should be // considered for removal. -TEST_F(UsageTableHeaderTest, +TEST_F(CdmUsageTableTest, DetermineLicenseToRemove_SomeExpiredAndBelowThreshold) { constexpr int64_t kOneDay = 24 * 60 * 60; constexpr size_t kSetSize = 10; constexpr int64_t kCurrentTime = kLruBaseTime + kOneDay * 2; // A threshold larger than the possible number of offline entries. constexpr size_t kUnexpiredThreshold = kSetSize + 1; - constexpr uint32_t kInvalidEntry = 9999; + constexpr UsageEntryIndex kInvalidEntry = 9999; std::vector usage_entry_info_list; usage_entry_info_list.resize(kSetSize); // Create a set of all offline licenses. - for (uint32_t i = 0; i < kSetSize; ++i) { + for (size_t i = 0; i < kSetSize; ++i) { CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i]; usage_entry_info.storage_type = kStorageLicense; usage_entry_info.key_set_id = "nothing_unusual"; @@ -4302,10 +4304,10 @@ TEST_F(UsageTableHeaderTest, } // Mark 3 as expired. - std::vector expired_license_numbers; - while (expired_license_numbers.size() < 3) { - const uint32_t i = - static_cast(wvutil::CdmRandom::RandomInRange(kSetSize - 1)); + std::vector expired_license_indexes; + while (expired_license_indexes.size() < 3) { + const UsageEntryIndex i = static_cast( + wvutil::CdmRandom::RandomInRange(kSetSize - 1)); CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i]; // Skip already expired ones if (usage_entry_info.key_set_id != "nothing_unusual") continue; @@ -4313,15 +4315,15 @@ TEST_F(UsageTableHeaderTest, usage_entry_info.last_use_time = kLruBaseTime + kOneDay; usage_entry_info.offline_license_expiry_time = kCurrentTime - kOneDay; usage_entry_info.key_set_id = "expired_offline"; - expired_license_numbers.push_back(i); + expired_license_indexes.push_back(i); } - uint32_t entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + UsageEntryIndex entry_to_remove = kInvalidEntry; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, kUnexpiredThreshold, &entry_to_remove)); - EXPECT_THAT(expired_license_numbers, Contains(entry_to_remove)); + EXPECT_THAT(expired_license_indexes, Contains(entry_to_remove)); } // This test primarily tests the robustness of the algorithm for a full @@ -4334,16 +4336,16 @@ TEST_F(UsageTableHeaderTest, // // Second, with the stale offline license marked as expired, checks that // offline licenses are selected over the streaming. -TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) { +TEST_F(CdmUsageTableTest, DetermineLicenseToRemove_LargeMixedSet) { constexpr int64_t kOneDay = 24 * 60 * 60; constexpr size_t kLargeSetSize = 200; constexpr int64_t kCurrentTime = kLruBaseTime + kOneDay * 2; - constexpr uint32_t kInvalidEntry = 9999; + constexpr UsageEntryIndex kInvalidEntry = 9999; std::vector usage_entry_info_list; usage_entry_info_list.resize(kLargeSetSize); // Create a set of usage entries. - for (uint32_t i = 0; i < kLargeSetSize; ++i) { + for (size_t i = 0; i < kLargeSetSize; ++i) { CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i]; usage_entry_info.key_set_id = "nothing_unusual"; usage_entry_info.last_use_time = kLruBaseTime + kOneDay; @@ -4358,95 +4360,95 @@ TEST_F(UsageTableHeaderTest, DetermineLicenseToRemove_LargeMixedSet) { } // Select a streaming license to be more stale than the rest. - uint32_t modified_usage_info_number = kInvalidEntry; - while (modified_usage_info_number == kInvalidEntry) { - const uint32_t i = static_cast( + UsageEntryIndex modified_usage_info_index = kInvalidEntry; + while (modified_usage_info_index == kInvalidEntry) { + const UsageEntryIndex i = static_cast( wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1)); CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i]; // Skip offline licenses. if (usage_entry_info.storage_type != kStorageUsageInfo) continue; usage_entry_info.last_use_time = kLruBaseTime + 10; usage_entry_info.key_set_id = "stale_streaming"; - modified_usage_info_number = i; + modified_usage_info_index = i; } // Select a offline license to be even more stale, but unexpired. - uint32_t modified_offline_license_number = kInvalidEntry; - while (modified_offline_license_number == kInvalidEntry) { - const uint32_t i = static_cast( + UsageEntryIndex modified_offline_license_index = kInvalidEntry; + while (modified_offline_license_index == kInvalidEntry) { + const UsageEntryIndex i = static_cast( wvutil::CdmRandom::RandomInRange(kLargeSetSize - 1)); CdmUsageEntryInfo& usage_entry_info = usage_entry_info_list[i]; // Skip streaming licenses. if (usage_entry_info.storage_type != kStorageLicense) continue; usage_entry_info.last_use_time = kLruBaseTime; usage_entry_info.key_set_id = "stale_offline"; - modified_offline_license_number = i; + modified_offline_license_index = i; } // Test using only streaming and expired offline licenses // (which there are none). - uint32_t entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + UsageEntryIndex entry_to_remove = kInvalidEntry; + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ kLargeSetSize, &entry_to_remove)); - EXPECT_EQ(modified_usage_info_number, entry_to_remove); + EXPECT_EQ(modified_usage_info_index, entry_to_remove); // Test where the equality threshold is met, now the stale unexpired // license should be selected. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ 0, &entry_to_remove)); - EXPECT_EQ(modified_offline_license_number, entry_to_remove); + EXPECT_EQ(modified_offline_license_index, entry_to_remove); // Make the stale offline license expired. CdmUsageEntryInfo& offline_usage_entry_info = - usage_entry_info_list[modified_offline_license_number]; + usage_entry_info_list[modified_offline_license_index]; offline_usage_entry_info.offline_license_expiry_time = kLruBaseTime; // Test again, expecting that the expired license should be considered. entry_to_remove = kInvalidEntry; - EXPECT_TRUE(UsageTableHeader::DetermineLicenseToRemoveForTesting( + EXPECT_TRUE(CdmUsageTable::DetermineLicenseToRemoveForTesting( usage_entry_info_list, kCurrentTime, /* unexpired_threshold = */ kLargeSetSize, &entry_to_remove)); - EXPECT_EQ(modified_offline_license_number, entry_to_remove); + EXPECT_EQ(modified_offline_license_index, entry_to_remove); } -TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unavailable) { +TEST_F(CdmUsageTableTest, PotentialTableCapacity_Unavailable) { crypto_session_->UnsetMaximumUsageTableEntries(); Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - EXPECT_EQ(usage_table_header_->potential_table_capacity(), + EXPECT_EQ(usage_table_->potential_table_capacity(), kMinimumUsageTableEntriesSupported); - EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity()); + EXPECT_FALSE(usage_table_->HasUnlimitedTableCapacity()); } -TEST_F(UsageTableHeaderTest, PotentialTableCapacity_TooSmall) { +TEST_F(CdmUsageTableTest, PotentialTableCapacity_TooSmall) { // This will issue a warning about the reported capacity is unexpected, // and will default to the version's required minimum. crypto_session_->SetMaximumUsageTableEntries( kMinimumUsageTableEntriesSupported / 2); Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - EXPECT_EQ(usage_table_header_->potential_table_capacity(), + EXPECT_EQ(usage_table_->potential_table_capacity(), kMinimumUsageTableEntriesSupported); - EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity()); + EXPECT_FALSE(usage_table_->HasUnlimitedTableCapacity()); } -TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Unlimited) { - MockUsageTableHeader* mock_usage_table_header = SetUpMock(); +TEST_F(CdmUsageTableTest, PotentialTableCapacity_Unlimited) { + MockCdmUsageTable* mock_usage_table = SetUpMock(); // Zero indicates that the table size is unlimited. crypto_session_->SetMaximumUsageTableEntries(0u); Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); constexpr size_t kZero = 0u; - EXPECT_EQ(mock_usage_table_header->potential_table_capacity(), kZero); - EXPECT_TRUE(mock_usage_table_header->HasUnlimitedTableCapacity()); + EXPECT_EQ(mock_usage_table->potential_table_capacity(), kZero); + EXPECT_TRUE(mock_usage_table->HasUnlimitedTableCapacity()); } -TEST_F(UsageTableHeaderTest, PotentialTableCapacity_Available) { +TEST_F(CdmUsageTableTest, PotentialTableCapacity_Available) { constexpr size_t kTableCapacity = 2000u; crypto_session_->SetMaximumUsageTableEntries(kTableCapacity); Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector); - EXPECT_EQ(usage_table_header_->potential_table_capacity(), kTableCapacity); - EXPECT_FALSE(usage_table_header_->HasUnlimitedTableCapacity()); + EXPECT_EQ(usage_table_->potential_table_capacity(), kTableCapacity); + EXPECT_FALSE(usage_table_->HasUnlimitedTableCapacity()); } } // namespace wvcdm diff --git a/core/test/certificate_provisioning_unittest.cpp b/core/test/certificate_provisioning_unittest.cpp index 2076d922..9f80b2be 100644 --- a/core/test/certificate_provisioning_unittest.cpp +++ b/core/test/certificate_provisioning_unittest.cpp @@ -63,21 +63,21 @@ class MockCryptoSession : public TestCryptoSession { (override)); // Usage Table Header. MOCK_METHOD(CdmResponseType, CreateUsageTableHeader, - (wvcdm::RequestedSecurityLevel, CdmUsageTableHeader*), - (override)); + (wvcdm::RequestedSecurityLevel, UsageTableHeader*), (override)); MOCK_METHOD(CdmResponseType, LoadUsageTableHeader, - (wvcdm::RequestedSecurityLevel, const CdmUsageTableHeader&), + (wvcdm::RequestedSecurityLevel, const UsageTableHeader&), (override)); MOCK_METHOD(CdmResponseType, ShrinkUsageTableHeader, - (wvcdm::RequestedSecurityLevel, uint32_t, CdmUsageTableHeader*), + (wvcdm::RequestedSecurityLevel, uint32_t, UsageTableHeader*), (override)); // Usage Entry. - MOCK_METHOD(CdmResponseType, CreateUsageEntry, (uint32_t*), (override)); - MOCK_METHOD(CdmResponseType, LoadUsageEntry, (uint32_t, const CdmUsageEntry&), + MOCK_METHOD(CdmResponseType, CreateUsageEntry, (UsageEntryIndex*), (override)); + MOCK_METHOD(CdmResponseType, LoadUsageEntry, + (UsageEntryIndex, const UsageEntry&), (override)); MOCK_METHOD(CdmResponseType, UpdateUsageEntry, - (CdmUsageTableHeader*, CdmUsageEntry*), (override)); - MOCK_METHOD(CdmResponseType, MoveUsageEntry, (uint32_t), (override)); + (UsageTableHeader*, UsageEntry*), (override)); + MOCK_METHOD(CdmResponseType, MoveUsageEntry, (UsageEntryIndex), (override)); }; class TestStubCryptoSessionFactory : public CryptoSessionFactory { @@ -87,9 +87,6 @@ class TestStubCryptoSessionFactory : public CryptoSessionFactory { } }; -// gmock methods -using ::testing::_; - class CertificateProvisioningTest : public WvCdmTestBase { protected: void SetUp() override { diff --git a/core/test/crypto_session_unittest.cpp b/core/test/crypto_session_unittest.cpp index 3e67165b..0a5545a2 100644 --- a/core/test/crypto_session_unittest.cpp +++ b/core/test/crypto_session_unittest.cpp @@ -62,7 +62,7 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { session->Open(wvcdm::kLevelDefault); // Exercise a method that will touch a metric. bool supports_usage_table; - ASSERT_TRUE(session->HasUsageInfoSupport(&supports_usage_table)); + ASSERT_TRUE(session->HasUsageTableSupport(&supports_usage_table)); drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto; crypto_metrics.Serialize(&metrics_proto); diff --git a/core/test/device_files_unittest.cpp b/core/test/device_files_unittest.cpp index 7998605a..1e0f811a 100644 --- a/core/test/device_files_unittest.cpp +++ b/core/test/device_files_unittest.cpp @@ -29,7 +29,6 @@ using wvutil::ArraySize; using wvutil::b2a_hex; using wvutil::CdmRandom; using wvutil::File; -using wvutil::FileSystem; const uint32_t kCertificateLen = 700; const uint32_t kWrappedKeyLen = 500; @@ -1627,7 +1626,7 @@ struct LicenseInfo { int64_t grace_period_end_time; std::string app_parameters; std::string usage_entry; - uint32_t usage_entry_number; + uint32_t usage_entry_index; std::string drm_certificate; CryptoWrappedKey::Type key_type; std::string private_key; @@ -2997,7 +2996,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 7d2b905e5eafd4b28aeeb7633283579e48add21a68eb26cc8c3b2e344579 // 003b12a38554336305525fa6ab70f024a18c73631bb1531eca3f0782c72d // ba017311b3f1e98c739632e305e4bc0b2561ae2b - // usage_entry_number: 5 + // usage_entry_index: 5 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex( @@ -3109,7 +3108,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 7d2b905e5eafd4b28aeeb7633283579e48add21a68eb26cc8c3b2e344579 // 003b12a38554336305525fa6ab70f024a18c73631bb1531eca3f0782c72d // ba017311b3f1e98c739632e305e4bc0b2561ae2b - // usage_entry_number: 5 + // usage_entry_index: 5 // drm_certificate_id: 0 // -token: // 5d637be37a9722aa35c23d346470851aca7d2edcd1a27edf124ea6 @@ -3140,7 +3139,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // b5a8c3f16d9f964afbd011e2326f9c27afbe74536f3f0601a71d9c1c422f // 335611bf3bf1a1c89e2dea27c17a9d9a58a74121e840b002e8a6fb590072 // 45be786c1f64 - // usage_entry_number: 9 + // usage_entry_index: 9 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex( @@ -3257,7 +3256,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // e016c8a03c9a406094d80059ef4ca26f1928fa2daa5de9a6f22372e5c7a9 // 41e610d1efb56ed7ce2228a70e2e150afb66edc2da066d463aa90ba0caff // 078fbfec05c8 - // usage_entry_number: 0 + // usage_entry_index: 0 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex("0AF404080310012AED040AEA040A20BB3370CCD3C3C49573D6B74386D1886D98" @@ -3345,7 +3344,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 5422463fd2e4dd47626e97dd6b4ee0b89523aaebe8d11e7e7be703ef01e4 // 9b17eaf020cede0a9e0e7b5d91e4db7abdce445936cb2deecdefefdb14b7 // 8f67b7ca5c733c9e88446fd814584584b86becbf6eb2b0e3d5603e8b - // usage_entry_number: 25 + // usage_entry_index: 25 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex( @@ -3433,7 +3432,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 5422463fd2e4dd47626e97dd6b4ee0b89523aaebe8d11e7e7be703ef01e4 // 9b17eaf020cede0a9e0e7b5d91e4db7abdce445936cb2deecdefefdb14b7 // 8f67b7ca5c733c9e88446fd814584584b86becbf6eb2b0e3d5603e8b - // usage_entry_number: 25 + // usage_entry_index: 25 // drm_certificate_id: 0 // -token: // 831fad51e52a403524539eab6a1b201e46674ca3b9167b1c1b53f5e5e3 @@ -3461,7 +3460,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 8599079cde11fadfab23aa1b97622839f3b7e1a96f8332bec5fbcbc9eb64 // fd5ed05887b8fa3bfd6ecc7bc91e621342732062d2f4411b763e20328af6 // f8ef5030e2f8027aef9e - // usage_entry_number: 6 + // usage_entry_index: 6 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex( @@ -3571,7 +3570,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // e016c8a03c9a406094d80059ef4ca26f1928fa2daa5de9a6f22372e5c7a9 // 41e610d1efb56ed7ce2228a70e2e150afb66edc2da066d463aa90ba0caff // 078fbfec05c8 - // usage_entry_number: 0 + // usage_entry_index: 0 // drm_certificate_id: 0 // -token: // eace80e30bfda213f1ce4dbcfd9d4d24b8e2ae00054d167d9d7ae9954706 @@ -3600,7 +3599,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 103465fe3441612bbdfdf4d1c24b2147feb8565cef4993e439c9d564a39a // 4ac5bb1da69acb44da06e4522c9a93d310cdda5dac1e1e0b91abff41e4e2 // edda4001 - // usage_entry_number: 7 + // usage_entry_index: 7 // drm_certificate_id: 0 // drm_certificate_cache: // -drm_certificate_id: 0 @@ -3727,7 +3726,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 7d2b905e5eafd4b28aeeb7633283579e48add21a68eb26cc8c3b2e344579 // 003b12a38554336305525fa6ab70f024a18c73631bb1531eca3f0782c72d // ba017311b3f1e98c739632e305e4bc0b2561ae2b - // usage_entry_number: 5 + // usage_entry_index: 5 // drm_certificate_id: 0 // -token: // 5d637be37a9722aa35c23d346470851aca7d2edcd1a27edf124ea6 @@ -3758,7 +3757,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // b5a8c3f16d9f964afbd011e2326f9c27afbe74536f3f0601a71d9c1c422f // 335611bf3bf1a1c89e2dea27c17a9d9a58a74121e840b002e8a6fb590072 // 45be786c1f64 - // usage_entry_number: 9 + // usage_entry_index: 9 // drm_certificate_id: 0 // -token: // 1fbf0a1d2432805a0f8292ff627a9a7c60b733a51b365892c832261d71 @@ -3786,7 +3785,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 4eabcc985a695be2ef4a8361d86979859c490922d92d3ed0484e1666270a // a96388bf6be3c4f4f0b7e2f59efc6b8e965d8fadd5ab86b2bb816d2573ec // 36eb42b571297681be152d40639d - // usage_entry_number: 0 + // usage_entry_index: 0 // drm_certificate_id: 0 // drm_certificate_cache: a2bs_hex( @@ -3920,7 +3919,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 5422463fd2e4dd47626e97dd6b4ee0b89523aaebe8d11e7e7be703ef01e4 // 9b17eaf020cede0a9e0e7b5d91e4db7abdce445936cb2deecdefefdb14b7 // 8f67b7ca5c733c9e88446fd814584584b86becbf6eb2b0e3d5603e8b - // usage_entry_number: 25 + // usage_entry_index: 25 // drm_certificate_id: 0 // -token: // 831fad51e52a403524539eab6a1b201e46674ca3b9167b1c1b53f5e5e3 @@ -3948,7 +3947,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 8599079cde11fadfab23aa1b97622839f3b7e1a96f8332bec5fbcbc9eb64 // fd5ed05887b8fa3bfd6ecc7bc91e621342732062d2f4411b763e20328af6 // f8ef5030e2f8027aef9e - // usage_entry_number: 6 + // usage_entry_index: 6 // drm_certificate_id: 0 // -token: 8f922e955b269458ed1345bde9a24516520a536817e8e8612154a1 // license_request: @@ -3974,7 +3973,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 703f69807c8f4d140168874b924a625132eb3b896a381d617b8fb83c7314 // a6b634d840925f711ae330599f0e0863800902b05d201a8a87b88a4bc170 // 65a1a8a556c34bf86b53afcc9951be15bea9ab55 - // usage_entry_number: 27 + // usage_entry_index: 27 // drm_certificate_id: 0 // drm_certificate_cache: // -drm_certificate_id: 0 @@ -4108,7 +4107,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // e016c8a03c9a406094d80059ef4ca26f1928fa2daa5de9a6f22372e5c7a9 // 41e610d1efb56ed7ce2228a70e2e150afb66edc2da066d463aa90ba0caff // 078fbfec05c8 - // usage_entry_number: 0 + // usage_entry_index: 0 // drm_certificate_id: 0 // -token: // eace80e30bfda213f1ce4dbcfd9d4d24b8e2ae00054d167d9d7ae9954706 @@ -4137,7 +4136,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // 103465fe3441612bbdfdf4d1c24b2147feb8565cef4993e439c9d564a39a // 4ac5bb1da69acb44da06e4522c9a93d310cdda5dac1e1e0b91abff41e4e2 // edda4001 - // usage_entry_number: 7 + // usage_entry_index: 7 // drm_certificate_id: 0 // -token: // d0b9a07ad7ffeec13784bd60da011be3589f3e450227fd36b1a3f6786cdb @@ -4165,7 +4164,7 @@ const UsageInfoTestContext kUsageInfoTestData[] = { // c3cb027611397b5d70cc0b08e0f5249cd19996da674e33722902173d45d7 // 09914a3d7e898d93170317bfcff34861c0d687048cc93542a75a2c99b232 // 3fafea1ee0c3e3d24edf2633 - // usage_entry_number: 7 + // usage_entry_index: 7 // drm_certificate_id: 0 // drm_certificate_cache: // -drm_certificate_id: 0 @@ -4317,7 +4316,7 @@ const CdmUsageEntryInfo kUsageEntriesTestData[] = { }; struct UsageTableTestInfo { - CdmUsageTableHeader usage_table_header; + UsageTableHeader usage_table_header; std::string file_data; }; @@ -4432,6 +4431,7 @@ class MockFileSystem : public wvutil::FileSystem { MOCK_METHOD(std::unique_ptr, Open, (const std::string&, int flags), (override)); MOCK_METHOD(bool, Exists, (const std::string&), (override)); + MOCK_METHOD(bool, Exists, (const std::string&, int*), (override)); MOCK_METHOD(bool, Remove, (const std::string&), (override)); MOCK_METHOD(ssize_t, FileSize, (const std::string&), (override)); MOCK_METHOD(bool, List, (const std::string&, std::vector*), @@ -4443,17 +4443,12 @@ class MockFileSystem : public wvutil::FileSystem { // gmock methods using ::testing::_; using ::testing::AllArgs; -using ::testing::AllOf; using ::testing::AtLeast; using ::testing::ByMove; using ::testing::DoAll; using ::testing::Eq; using ::testing::Expectation; -using ::testing::Gt; -using ::testing::HasSubstr; -using ::testing::InSequence; using ::testing::Invoke; -using ::testing::InvokeWithoutArgs; using ::testing::NotNull; using ::testing::Return; using ::testing::ReturnArg; @@ -4640,6 +4635,9 @@ TEST_F(DeviceFilesTest, RetrieveAtscCertificate) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); @@ -4908,6 +4906,9 @@ TEST_F(DeviceFilesTest, RetrieveDefaultCertificateNeverExpires) { EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path))) .WillOnce(Return(data.size())); EXPECT_CALL(file_system, Open(StrEq(device_certificate_path), _)) @@ -4955,6 +4956,9 @@ TEST_P(RetrieveDefaultCertificateTest, ErrorScenarios) { EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path))) .WillOnce(Return(data.size())); EXPECT_CALL(file_system, Open(StrEq(device_certificate_path), _)) @@ -5009,6 +5013,10 @@ TEST_F(DeviceFilesTest, RetrieveCertificateWithoutKeyType) { EXPECT_CALL(file_system, Exists(StrEq(device_legacy_certificate_path))) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, + Exists(StrEq(device_legacy_certificate_path), NotNull())) + .Times(AtLeast(1)) + .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, Exists(StrEq(device_default_certificate_path))) .Times(AtLeast(1)) .WillRepeatedly(Return(false)); @@ -5220,7 +5228,7 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) { kLicenseTestData[license_num].grace_period_end_time, app_parameters, kLicenseTestData[license_num].usage_entry, - kLicenseTestData[license_num].usage_entry_number, + kLicenseTestData[license_num].usage_entry_index, kLicenseTestData[license_num].drm_certificate, CryptoWrappedKey(kLicenseTestData[license_num].key_type, kLicenseTestData[license_num].private_key)}; @@ -5289,7 +5297,7 @@ TEST_F(DeviceFilesTest, StoreLicenses) { kLicenseTestData[i].grace_period_end_time, app_parameters, kLicenseTestData[i].usage_entry, - kLicenseTestData[i].usage_entry_number, + kLicenseTestData[i].usage_entry_index, kLicenseTestData[i].drm_certificate, CryptoWrappedKey(kLicenseTestData[i].key_type, kLicenseTestData[i].private_key)}; @@ -5311,7 +5319,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(license_path))) + EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull())) .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(license_path))) .WillOnce(Return(size)); @@ -5349,8 +5357,8 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) { EXPECT_EQ(kLicenseTestData[i].grace_period_end_time, license_data.grace_period_end_time); EXPECT_EQ(kLicenseTestData[i].usage_entry, license_data.usage_entry); - EXPECT_EQ(kLicenseTestData[i].usage_entry_number, - license_data.usage_entry_number); + EXPECT_EQ(kLicenseTestData[i].usage_entry_index, + license_data.usage_entry_index); EXPECT_EQ(kLicenseTestData[i].drm_certificate, license_data.drm_certificate); EXPECT_EQ(kLicenseTestData[i].key_type, @@ -5383,7 +5391,8 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(license_path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(license_path))) .WillOnce(Return(size)); EXPECT_CALL(file_system, Open(StrEq(license_path), _)) @@ -5415,7 +5424,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) { license_data.grace_period_end_time); EXPECT_EQ(0u, license_data.app_parameters.size()); EXPECT_EQ(test_data->usage_entry, license_data.usage_entry); - EXPECT_EQ(test_data->usage_entry_number, license_data.usage_entry_number); + EXPECT_EQ(test_data->usage_entry_index, license_data.usage_entry_index); EXPECT_EQ(test_data->drm_certificate, license_data.drm_certificate); EXPECT_EQ(test_data->key_type, license_data.wrapped_private_key.type()); EXPECT_EQ(test_data->private_key, license_data.wrapped_private_key.key()); @@ -5454,7 +5463,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) { kLicenseUpdateTestData[0].grace_period_end_time, GetAppParameters(kLicenseTestData[0].app_parameters), kLicenseUpdateTestData[0].usage_entry, - kLicenseUpdateTestData[0].usage_entry_number, + kLicenseUpdateTestData[0].usage_entry_index, kLicenseUpdateTestData[0].drm_certificate, CryptoWrappedKey(kLicenseTestData[0].key_type, kLicenseTestData[0].private_key)}; @@ -5474,10 +5483,9 @@ TEST_F(DeviceFilesTest, DeleteLicense) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(license_path))) - .Times(2) - .WillOnce(Return(true)) - .WillOnce(Return(false)); + EXPECT_CALL(file_system, Exists(StrEq(license_path))).WillOnce(Return(false)); + EXPECT_CALL(file_system, Exists(StrEq(license_path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(license_path))) .WillOnce(Return(size)); EXPECT_CALL(file_system, Open(StrEq(license_path), _)) @@ -5520,8 +5528,8 @@ TEST_F(DeviceFilesTest, DeleteLicense) { std::string::npos); } EXPECT_EQ(kLicenseTestData[0].usage_entry, license_data.usage_entry); - EXPECT_EQ(kLicenseTestData[0].usage_entry_number, - license_data.usage_entry_number); + EXPECT_EQ(kLicenseTestData[0].usage_entry_index, + license_data.usage_entry_index); EXPECT_EQ(kLicenseTestData[0].drm_certificate, license_data.drm_certificate); EXPECT_EQ(kLicenseTestData[0].key_type, license_data.wrapped_private_key.type()); @@ -5579,10 +5587,12 @@ TEST_F(DeviceFilesTest, OkpInfo_FileDoesNotExist) { MockFileSystem file_system; DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + int errno_value = ENOENT; const std::string kOkpInfoPath = device_base_path_ + DeviceFiles::GetOkpInfoFileName(); - EXPECT_CALL(file_system, Exists(kOkpInfoPath)).WillOnce(Return(false)); + EXPECT_CALL(file_system, Exists(StrEq(kOkpInfoPath), NotNull())) + .WillRepeatedly(DoAll(SetArgPointee<1>(errno_value), (Return(false)))); okp::SystemFallbackInfo info; EXPECT_FALSE(device_files.RetrieveOkpInfo(&info)); @@ -5641,7 +5651,8 @@ TEST_F(DeviceFilesTest, OkpInfo_StoreAndRetrieve) { // Set retrieve expectations. file = new MockFile(); - EXPECT_CALL(file_system, Exists(kOkpInfoPath)).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(kOkpInfoPath), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(kOkpInfoPath)) .WillOnce(Return(serialized.size())); EXPECT_CALL(file_system, Open(kOkpInfoPath, _)) @@ -5676,6 +5687,7 @@ TEST_P(DeviceFilesDeleteMultipleUsageInfoTest, DeleteAllButOne) { file_path += kUsageInfoFileName; EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(_, NotNull())).WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(file_path)) .WillOnce(Return(kHashedUsageInfoFileWithThreeKeySetIds.size())); @@ -5733,6 +5745,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteAllKeySetIds) { // File read expectations. MockFile* file_in = new MockFile(); EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(file_path)) .WillOnce(Return(kHashedUsageInfoFileWithThreeKeySetIds.size())); EXPECT_CALL(file_system, Open(file_path, wvutil::FileSystem::kReadOnly)) @@ -5763,6 +5776,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteNone) { file_path += kUsageInfoFileName; EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true)); // Call, not providing any key set IDs. Should return true without any // action, assuming the file exists. @@ -5803,6 +5817,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, DeleteOne) { file_path += kUsageInfoFileName; EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(file_path)) .WillOnce(Return(kHashedUsageInfoFileWithTwoKeySetIds.size())); @@ -5857,6 +5872,7 @@ TEST_F(DeviceFilesDeleteMultipleUsageInfoTest, BadFile) { // File is missing hash. MockFile* file_in = new MockFile(); EXPECT_CALL(file_system, Exists(_)).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(_, NotNull())).WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(file_path)) .WillOnce(Return(kHashlessUsageInfoFile.size())); EXPECT_CALL(file_system, Open(file_path, wvutil::FileSystem::kReadOnly)) @@ -5903,9 +5919,9 @@ TEST_F(DeviceFilesUsageInfoTest, ListUsageIds) { if (index >= 0) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .Times(2) .WillRepeatedly(Return(file_data.size())); @@ -6038,9 +6054,9 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) { if (index >= 0) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .Times(2) .WillRepeatedly(Return(file_data.size())); @@ -6074,8 +6090,8 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) { EXPECT_EQ(retrieved_usage_data.license, known_usage_data.license); EXPECT_EQ(retrieved_usage_data.key_set_id, known_usage_data.key_set_id); EXPECT_EQ(retrieved_usage_data.usage_entry, known_usage_data.usage_entry); - EXPECT_EQ(retrieved_usage_data.usage_entry_number, - known_usage_data.usage_entry_number); + EXPECT_EQ(retrieved_usage_data.usage_entry_index, + known_usage_data.usage_entry_index); EXPECT_EQ(retrieved_usage_data.drm_certificate, known_usage_data.drm_certificate); EXPECT_EQ(retrieved_usage_data.wrapped_private_key, @@ -6101,9 +6117,9 @@ TEST_P(DeviceFilesUsageInfoTest, ListKeySetIds) { if (index >= 0) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .Times(2) .WillRepeatedly(Return(file_data.size())); @@ -6153,9 +6169,9 @@ TEST_P(DeviceFilesUsageInfoTest, ListProviderSessionTokenIds) { if (index >= 0) { // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .Times(2) .WillRepeatedly(Return(file_data.size())); @@ -6215,7 +6231,8 @@ TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) { kUsageInfoTestData[index < 0 ? 0 : index] .usage_data.provider_session_token; - EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .WillOnce(Return(file_data.size())); EXPECT_CALL(file_system, Open(StrEq(path), _)) @@ -6244,8 +6261,8 @@ TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) { EXPECT_EQ(expected_usage_data.license, usage_data.license); EXPECT_EQ(expected_usage_data.key_set_id, usage_data.key_set_id); EXPECT_EQ(expected_usage_data.usage_entry, usage_data.usage_entry); - EXPECT_EQ(expected_usage_data.usage_entry_number, - usage_data.usage_entry_number); + EXPECT_EQ(expected_usage_data.usage_entry_index, + usage_data.usage_entry_index); } } @@ -6299,9 +6316,9 @@ TEST_P(DeviceFilesUsageInfoTest, UpdateUsageInfo) { (index < 0) ? kEmptyUsageInfoFileData : kUsageInfoTestData[max_index_by_app_id].file_data; - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .WillOnce(Return(file_data.size())); EXPECT_CALL(*file, Read(NotNull(), Eq(file_data.size()))) @@ -6344,7 +6361,8 @@ TEST_P(DeviceFilesHlsAttributesTest, Read) { std::string path = device_base_path_ + param->key_set_id + DeviceFiles::GetHlsAttributesFileNameExtension(); - EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .WillRepeatedly(Return(param->file_data.size())); EXPECT_CALL(file_system, Open(StrEq(path), _)) @@ -6452,7 +6470,8 @@ TEST_P(DeviceFilesUsageTableTest, Read) { std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName(); const std::string& file_data = kUsageTableInfoTestData[index].file_data; - EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillOnce(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .WillRepeatedly(Return(file_data.size())); EXPECT_CALL(file_system, Open(StrEq(path), _)) @@ -6467,7 +6486,7 @@ TEST_P(DeviceFilesUsageTableTest, Read) { EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); std::vector usage_entry_info; - CdmUsageTableHeader usage_table_header; + UsageTableHeader usage_table_header; bool lru_upgrade; ASSERT_TRUE(device_files.RetrieveUsageTableInfo( &usage_table_header, &usage_entry_info, &lru_upgrade)); @@ -6505,7 +6524,8 @@ TEST_F(DeviceFilesUsageTableTest, ReadWithoutLruData) { const std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName(); MockFileSystem file_system; - EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, Exists(StrEq(path), NotNull())) + .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(path))) .WillRepeatedly(Return(kUsageTableWithoutLruData.size())); EXPECT_CALL(file_system, Open(StrEq(path), _)) @@ -6515,7 +6535,7 @@ TEST_F(DeviceFilesUsageTableTest, ReadWithoutLruData) { EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); std::vector usage_entry_info; - CdmUsageTableHeader usage_table_header; + UsageTableHeader usage_table_header; bool lru_upgrade; ASSERT_TRUE(device_files.RetrieveUsageTableInfo( &usage_table_header, &usage_entry_info, &lru_upgrade)); @@ -6619,7 +6639,7 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateSuccess) { device_base_path_ + wvutil::kOemCertificateFileName; // Call to Open will return a unique_ptr, freeing this object. MockFile* read_file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path))) @@ -6650,7 +6670,7 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateRandomCertFail) { std::string ramdom_cert = "random_cert"; // Call to Open will return a unique_ptr, freeing this object. MockFile* read_file = new MockFile(); - EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) .Times(AtLeast(1)) .WillRepeatedly(Return(true)); EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path))) @@ -6676,9 +6696,10 @@ TEST_F(DeviceFilesTest, RetrieveOemCertificateNotFoundFail) { MockFileSystem file_system; const std::string device_certificate_path = device_base_path_ + wvutil::kOemCertificateFileName; - EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) + int errno_value = ENOENT; + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path), NotNull())) .Times(AtLeast(1)) - .WillRepeatedly(Return(false)); + .WillRepeatedly(DoAll(SetArgPointee<1>(errno_value), (Return(false)))); DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); diff --git a/core/test/duration_use_case_test.cpp b/core/test/duration_use_case_test.cpp index 35978242..d2ffd2f3 100644 --- a/core/test/duration_use_case_test.cpp +++ b/core/test/duration_use_case_test.cpp @@ -80,6 +80,8 @@ const RenewalPolicy kLDLRenewal = {"CDM_LimitedDurationLicense_renewal", 0, 0}; const RenewalPolicy kInfiniteRenewal = {"CDM_InfiniteRenewal_renewal", 0, 0}; const RenewalPolicy kLicenseDurationWithRenewal = { "CDM_LicenseDurationWithRenewal_renewal", 10, 0}; +const RenewalPolicy kRenewOnLicenseLoad = {"CDM_RenewOnLicenseLoad_renewal", 0, + 0}; const RenewalPolicy kHeartbeatRenewal = {"CDM_Heartbeat_renewal", 10, 30}; // Key ID in all duration tests. @@ -1538,6 +1540,164 @@ TEST_P(CdmUseCase_LimitedDurationLicense, Case6) { AllowPlayback(start_of_playback_, end_of_play); } +// Limited Duration License with Clear lead. (See above for notes on Use Case +// tests). The user has 15 minutes to begin watching the movie. If a renewal is +// not received, playback is terminated after 30 seconds. If a renewal is +// received, playback may continue for two hours from playback start. +class CdmUseCase_RenewOnLicenseLoad : public RenewalTest { + public: + CdmUseCase_RenewOnLicenseLoad() : RenewalTest("CDM_RenewOnLicenseLoad") { + renewal_delay_ = 5u; + renewal_recovery_ = 15; + + // Pick a start of playback that is within the rental window, but so that + // the initial renewal window is after rental window. + start_of_playback_ = 10; + + timer_limits_.soft_enforce_rental_duration = true; + timer_limits_.rental_duration_seconds = 20; + timer_limits_.soft_enforce_playback_duration = false; + timer_limits_.total_playback_duration_seconds = 50; + timer_limits_.initial_renewal_duration_seconds = + renewal_delay_ + renewal_recovery_; + + // Calculate the renewal cutoff: + renewal_cutoff_ = start_of_playback_ + renewal_delay_ + renewal_recovery_; + + // Load the renewal just before the cutoff: + renewal_load_time_ = renewal_cutoff_ - kFudge; + } + + void SetUp() override { + RenewalTest::SetUp(); + // The Renew on License Load feature is only supported on v18+ servers. + if (config_.ServerOlderThan(18) || + wvoec::global_features.api_version < 18) { + GTEST_SKIP() << "Renew on License Load supported on v18+ servers and " + "devices only."; + } + } + + uint64_t renewal_cutoff_; + uint64_t renewal_delay_; + uint64_t renewal_load_time_; + uint64_t renewal_recovery_; +}; + +// License loaded within rental duration window and playback continues. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case1S) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + SleepUntilRenewalNeeded(); + RequestRenewal(kRenewOnLicenseLoad); + const uint64_t start = 15; // time of first decrypt + const uint64_t stop = 45; + RenewAndContinue(start, renewal_load_time_, stop, kRenewOnLicenseLoad); +} + +// License loaded within rental duration window and playback continues. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case1M) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + SleepUntilRenewalNeeded(); + RequestRenewal(kRenewOnLicenseLoad); + const uint64_t start = 25; // time of first decrypt + const uint64_t stop = 45; // end of decrypt + RenewAndContinue(start, renewal_load_time_, stop, kRenewOnLicenseLoad); +} + +// License loaded within rental duration window and playback continues. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case1L) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + SleepUntilRenewalNeeded(); + RequestRenewal(kRenewOnLicenseLoad); + const uint64_t start = 35; // time of first decrypt + const uint64_t stop = 45; // end of decrypt + LoadRenewal(renewal_load_time_, kRenewOnLicenseLoad); + AllowPlayback(start, stop); +} + +// License loaded after rental duration window and playback should fail. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case2) { + start_of_playback_ = EndOfRentalWindow() + kFudge; + SleepUntil(start_of_playback_); + license_holder_.FailLoadLicense(); +} + +// License loaded within rental duration window but renewal not received. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case3S) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + const uint64_t start = 15; // time of first decrypt + // Allow playback within the initial renewal window. + TerminatePlayback(start, renewal_cutoff_); +} + +// License loaded within rental duration window but renewal not received. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case3M) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + const uint64_t start = 25; // time of first decrypt + // Allow playback within the initial renewal window. + TerminatePlayback(start, renewal_cutoff_); +} + +// License loaded within rental duration window but renewal not received. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case3L) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + const uint64_t start = 35; // time of first decrypt + SleepUntil(start); + // No playback at all. + FailDecrypt(); +} + +// Playback is started within the rental duration window and the renewal is +// received, but playback exceeds the playback duration. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case4) { + start_of_playback_ = 10; + SleepUntil(start_of_playback_); + LoadLicense(); + SleepUntilRenewalNeeded(); + RequestRenewal(kRenewOnLicenseLoad); + const uint64_t start = 20; // time of first decrypt + const uint64_t load_renewal = 20; + const uint64_t stop = 45; // end of decrypt + const uint64_t cutoff = EndOfPlaybackWindow(); + RenewAndContinue(start, load_renewal, stop, kRenewOnLicenseLoad); + TerminatePlayback(stop, cutoff); +} + +// Playback is able to be restarted. +TEST_P(CdmUseCase_RenewOnLicenseLoad, Case5) { + start_of_playback_ = 10; + const uint64_t load_renewal = 20; + SleepUntil(start_of_playback_); + LoadLicense(); + SleepUntilRenewalNeeded(); + RequestRenewal(kRenewOnLicenseLoad); + const uint64_t start = 20; + const uint64_t end = 35; + RenewAndContinue(start, load_renewal, end, kRenewOnLicenseLoad); + UnloadLicense(); + // Simulate reloading the license, and then reloading the renewal, and then + // restarting playback. That is allowed, and playback shall be terminated at + // the end of the original playback window. + const uint64_t reload_time = 45; + ReloadAndAllowPlayback(reload_time, EndOfPlaybackWindow(), + kRenewOnLicenseLoad); + // But not beyond playback window. + SleepUntil(EndOfPlaybackWindow() + 3 * kFudge); + FailDecrypt(); +} + // Heartbeat Playback Window License. (See above for notes on Use Case tests). // This is similar to the renewal, but the renewal recovery is larger than the // renewal delay. @@ -1779,6 +1939,8 @@ INSTANTIATE_TEST_SUITE_P(Both, CdmUseCase_LicenseWithRenewalPlayback, ::testing::Values(false, true)); INSTANTIATE_TEST_SUITE_P(Both, CdmUseCase_LimitedDurationLicense, ::testing::Values(false, true)); +INSTANTIATE_TEST_SUITE_P(Both, CdmUseCase_RenewOnLicenseLoad, + ::testing::Values(false, true)); INSTANTIATE_TEST_SUITE_P(Both, CdmUseCase_InfiniteRenewal, ::testing::Values(false, true)); INSTANTIATE_TEST_SUITE_P(Both, CdmUseCase_LicenseDuration, diff --git a/core/test/fake_provisioning_server.cpp b/core/test/fake_provisioning_server.cpp index 4b550450..359307e3 100644 --- a/core/test/fake_provisioning_server.cpp +++ b/core/test/fake_provisioning_server.cpp @@ -324,7 +324,7 @@ bool FakeProvisioningServer::MakeResponse( if (signed_request.has_oemcrypto_core_message()) { // If the request has a core message, then the response should also have a // core message. - std::string core_request = signed_request.oemcrypto_core_message(); + const std::string& core_request = signed_request.oemcrypto_core_message(); oemcrypto_core_message::ODK_ProvisioningRequest core_request_data; if (!oemcrypto_core_message::deserialize:: CoreProvisioningRequestFromMessage(core_request, @@ -335,7 +335,7 @@ bool FakeProvisioningServer::MakeResponse( std::string core_response; oemcrypto_core_message::serialize::CreateCoreProvisioningResponseFromProto( oemcrypto_core_message::features::CoreMessageFeatures::kDefaultFeatures, - message, core_request_data, &core_response); + message, core_request_data, OEMCrypto_RSA_Private_Key, &core_response); signed_response.set_oemcrypto_core_message(core_response); // Also, the signature should be over the concatenation of the core message // and the message body. This is done to ensure that neither the message diff --git a/core/test/http_socket.cpp b/core/test/http_socket.cpp index 9760a65e..51d0436d 100644 --- a/core/test/http_socket.cpp +++ b/core/test/http_socket.cpp @@ -67,8 +67,8 @@ SSL_CTX* InitSslContext() { return ctx; } -static int LogBoringSslError(const char* message, size_t /* length */, - void* /* user_data */) { +int LogBoringSslError(const char* message, size_t /* length */, + void* /* user_data */) { LOGE(" BoringSSL Error: %s", message); return 1; } diff --git a/core/test/initialization_data_unittest.cpp b/core/test/initialization_data_unittest.cpp index 86cfe36d..57d2265f 100644 --- a/core/test/initialization_data_unittest.cpp +++ b/core/test/initialization_data_unittest.cpp @@ -24,9 +24,6 @@ using video_widevine::WidevinePsshData; namespace { -// Import names from ::testing for convenience -using ::testing::_; - // Constants for JSON formatting const std::string kLeftBrace = "{"; const std::string kRightBrace = "}"; @@ -807,12 +804,12 @@ TEST_P(HlsParseTest, Parse) { if (param.success_) { EXPECT_TRUE(init_data.is_hls()); EXPECT_FALSE(init_data.IsEmpty()); - if (param.key_.compare(HLS_METHOD_ATTRIBUTE) == 0) { - if (param.value_.compare(HLS_METHOD_SAMPLE_AES) == 0) { + if (param.key_ == HLS_METHOD_ATTRIBUTE) { + if (param.value_ == HLS_METHOD_SAMPLE_AES) { EXPECT_EQ(kHlsMethodSampleAes, init_data.hls_method()); - } else if (param.value_.compare(HLS_METHOD_AES_128) == 0) { + } else if (param.value_ == HLS_METHOD_AES_128) { EXPECT_EQ(kHlsMethodAes128, init_data.hls_method()); - } else if (param.value_.compare(HLS_METHOD_NONE) == 0) { + } else if (param.value_ == HLS_METHOD_NONE) { EXPECT_EQ(kHlsMethodNone, init_data.hls_method()); } } else { @@ -825,11 +822,11 @@ TEST_P(HlsParseTest, Parse) { CORE_UTIL_IGNORE_DEPRECATED EXPECT_EQ(video_widevine::WidevinePsshData_Algorithm_AESCTR, cenc_header.algorithm()); - if (param.key_.compare(kJsonProvider) == 0) { + if (param.key_ == kJsonProvider) { EXPECT_EQ(param.value_, cenc_header.provider()); - } else if (param.key_.compare(kJsonContentId) == 0) { + } else if (param.key_ == kJsonContentId) { EXPECT_EQ(param.value_, cenc_header.content_id()); - } else if (param.key_.compare(kJsonKeyIds) == 0) { + } else if (param.key_ == kJsonKeyIds) { EXPECT_EQ(param.value_, wvutil::b2a_hex(cenc_header.key_ids(0))); } CORE_UTIL_RESTORE_WARNINGS diff --git a/core/test/license_holder.cpp b/core/test/license_holder.cpp index 20e80d7e..ceef5315 100644 --- a/core/test/license_holder.cpp +++ b/core/test/license_holder.cpp @@ -62,6 +62,13 @@ void LicenseHolder::LoadLicense() { } } +void LicenseHolder::FailLoadLicense() { + CdmLicenseType license_type; + ASSERT_NE(KEY_ADDED, cdm_engine_->AddKey(session_id_, key_response_, + &license_type, &key_set_id_)) + << "Unexpected success loading license for " << content_id(); +} + void LicenseHolder::ReloadLicense() { CdmResponseType status = cdm_engine_->RestoreKey(session_id_, key_set_id_); ASSERT_EQ(KEY_ADDED, status) @@ -168,7 +175,7 @@ void LicenseHolder::DecryptSecure(const KeyId& key_id) { } void LicenseHolder::FailDecrypt(const KeyId& key_id, - CdmResponseType expected_status) { + CdmResponseEnum expected_status) { CdmResponseType status = Decrypt(key_id); // If the server knows we cannot handle the key, it would not have given us // the key. In that case, the status should indicate no key. @@ -210,7 +217,7 @@ std::string LicenseHolder::MakeUrl(const std::string& server_url, } // If there is already a parameter, then we don't need to add another // question mark. - return path + ((path.find("?") == std::string::npos) ? "?" : "&") + + return path + ((path.find('?') == std::string::npos) ? '?' : '&') + video_query; } else { return path; diff --git a/core/test/license_holder.h b/core/test/license_holder.h index eb1e5e37..914e8d22 100644 --- a/core/test/license_holder.h +++ b/core/test/license_holder.h @@ -59,6 +59,9 @@ class LicenseHolder { // Load the license response into the CDM engine. A call to FetchLicense() // must be made first. void LoadLicense(); + // Attempt to load the license response into the CDM engine, but expect a + // failure. + void FailLoadLicense(); // Reload the license. Call OpenSession() before calling // ReloadLicense(). Also, the key_set_id must have been set previously. The // key_set_id is set by calling LoadLicense(), or by calling set_key_set_id(). @@ -83,7 +86,7 @@ class LicenseHolder { // Try to decrypt some random data, but expect failure. The failure may // be either the expected_status, or NEED_KEY. We allow NEED_KEY in case // the server recognized that we cannot support the given key. - void FailDecrypt(const KeyId& key_id, CdmResponseType expected_status); + void FailDecrypt(const KeyId& key_id, CdmResponseEnum expected_status); const std::string& content_id() const { return content_id_; } void set_content_id(const std::string& content_id) { diff --git a/core/test/license_keys_unittest.cpp b/core/test/license_keys_unittest.cpp index 8a8f7b91..1dc7991a 100644 --- a/core/test/license_keys_unittest.cpp +++ b/core/test/license_keys_unittest.cpp @@ -12,59 +12,58 @@ namespace wvcdm { namespace { -static const uint32_t dev_lo_res = 200; -static const uint32_t dev_hi_res = 400; -static const uint32_t dev_top_res = 800; +const uint32_t dev_lo_res = 200; +const uint32_t dev_hi_res = 400; +const uint32_t dev_top_res = 800; -static const uint32_t key_lo_res_min = 151; -static const uint32_t key_lo_res_max = 300; -static const uint32_t key_hi_res_min = 301; -static const uint32_t key_hi_res_max = 450; -static const uint32_t key_top_res_min = 451; -static const uint32_t key_top_res_max = 650; +const uint32_t key_lo_res_min = 151; +const uint32_t key_lo_res_max = 300; +const uint32_t key_hi_res_min = 301; +const uint32_t key_hi_res_max = 450; +const uint32_t key_top_res_min = 451; +const uint32_t key_top_res_max = 650; // Content Keys -static const KeyId ck_sw_crypto = "c_key_SW_SECURE_CRYPTO"; -static const KeyId ck_sw_decode = "c_key_SW_SECURE_DECODE"; -static const KeyId ck_hw_crypto = "c_key_HW_SECURE_CRYPTO"; -static const KeyId ck_hw_decode = "c_key_HW_SECURE_DECODE"; -static const KeyId ck_hw_secure = "c_key_HW_SECURE_ALL"; +const KeyId ck_sw_crypto = "c_key_SW_SECURE_CRYPTO"; +const KeyId ck_sw_decode = "c_key_SW_SECURE_DECODE"; +const KeyId ck_hw_crypto = "c_key_HW_SECURE_CRYPTO"; +const KeyId ck_hw_decode = "c_key_HW_SECURE_DECODE"; +const KeyId ck_hw_secure = "c_key_HW_SECURE_ALL"; // Operator Session Keys -static const KeyId osk_decrypt = "os_key_generic_decrypt"; -static const KeyId osk_encrypt = "os_key_generic_encrypt"; -static const KeyId osk_sign = "os_key_generic_sign"; -static const KeyId osk_verify = "os_key_generic_verify"; -static const KeyId osk_encrypt_decrypt = "os_key_generic_encrypt_decrypt"; -static const KeyId osk_sign_verify = "os_key_generic_sign_verify"; -static const KeyId osk_all = "os_key_generic_all"; +const KeyId osk_decrypt = "os_key_generic_decrypt"; +const KeyId osk_encrypt = "os_key_generic_encrypt"; +const KeyId osk_sign = "os_key_generic_sign"; +const KeyId osk_verify = "os_key_generic_verify"; +const KeyId osk_encrypt_decrypt = "os_key_generic_encrypt_decrypt"; +const KeyId osk_sign_verify = "os_key_generic_sign_verify"; +const KeyId osk_all = "os_key_generic_all"; // HDCP test keys -static const KeyId ck_sw_crypto_NO_HDCP = "ck_sw_crypto_NO_HDCP"; -static const KeyId ck_hw_secure_NO_HDCP = "ck_hw_secure_NO_HDCP"; -static const KeyId ck_sw_crypto_HDCP_V2_1 = "ck_sw_crypto_HDCP_V2_1"; -static const KeyId ck_hw_secure_HDCP_V2_1 = "ck_hw_secure_HDCP_V2_1"; -static const KeyId ck_sw_crypto_HDCP_V2_2 = "ck_sw_crypto_HDCP_V2_2"; -static const KeyId ck_hw_secure_HDCP_V2_2 = "ck_hw_secure_HDCP_V2_2"; -static const KeyId ck_sw_crypto_HDCP_V2_3 = "ck_sw_crypto_HDCP_V2_3"; -static const KeyId ck_hw_secure_HDCP_V2_3 = "ck_hw_secure_HDCP_V2_3"; -static const KeyId ck_sw_crypto_HDCP_NO_OUTPUT = "ck_sw_crypto_HDCP_NO_OUT"; -static const KeyId ck_hw_secure_HDCP_NO_OUTPUT = "ck_hw_secure_HDCP_NO_OUT"; +const KeyId ck_sw_crypto_NO_HDCP = "ck_sw_crypto_NO_HDCP"; +const KeyId ck_hw_secure_NO_HDCP = "ck_hw_secure_NO_HDCP"; +const KeyId ck_sw_crypto_HDCP_V2_1 = "ck_sw_crypto_HDCP_V2_1"; +const KeyId ck_hw_secure_HDCP_V2_1 = "ck_hw_secure_HDCP_V2_1"; +const KeyId ck_sw_crypto_HDCP_V2_2 = "ck_sw_crypto_HDCP_V2_2"; +const KeyId ck_hw_secure_HDCP_V2_2 = "ck_hw_secure_HDCP_V2_2"; +const KeyId ck_sw_crypto_HDCP_V2_3 = "ck_sw_crypto_HDCP_V2_3"; +const KeyId ck_hw_secure_HDCP_V2_3 = "ck_hw_secure_HDCP_V2_3"; +const KeyId ck_sw_crypto_HDCP_NO_OUTPUT = "ck_sw_crypto_HDCP_NO_OUT"; +const KeyId ck_hw_secure_HDCP_NO_OUTPUT = "ck_hw_secure_HDCP_NO_OUT"; // Constraint test keys -static const KeyId ck_NO_HDCP_lo_res = "ck_NO_HDCP_lo_res"; -static const KeyId ck_HDCP_NO_OUTPUT_hi_res = "ck_HDCP_NO_OUTPUT_hi_res"; -static const KeyId ck_HDCP_V2_1_hi_res = "ck_HDCP_V2_1_hi_res"; -static const KeyId ck_HDCP_V2_2_max_res = "ck_HDCP_V2_2_max_res"; -static const KeyId ck_HDCP_V2_3_max_res = "ck_HDCP_V2_3_max_res"; -static const KeyId ck_NO_HDCP_dual_res = "ck_NO_HDCP_dual_res"; +const KeyId ck_NO_HDCP_lo_res = "ck_NO_HDCP_lo_res"; +const KeyId ck_HDCP_NO_OUTPUT_hi_res = "ck_HDCP_NO_OUTPUT_hi_res"; +const KeyId ck_HDCP_V2_1_hi_res = "ck_HDCP_V2_1_hi_res"; +const KeyId ck_HDCP_V2_2_max_res = "ck_HDCP_V2_2_max_res"; +const KeyId ck_HDCP_V2_3_max_res = "ck_HDCP_V2_3_max_res"; +const KeyId ck_NO_HDCP_dual_res = "ck_NO_HDCP_dual_res"; } // namespace // protobuf generated classes. using video_widevine::License; using video_widevine::LicenseIdentification; -using video_widevine::OFFLINE; using video_widevine::STREAMING; using KeyContainer = ::video_widevine::License::KeyContainer; diff --git a/core/test/license_unittest.cpp b/core/test/license_unittest.cpp index c1acaa73..c45804a0 100644 --- a/core/test/license_unittest.cpp +++ b/core/test/license_unittest.cpp @@ -143,7 +143,7 @@ class MockCryptoSession : public TestCryptoSession { : TestCryptoSession(crypto_metrics) {} MOCK_METHOD(bool, IsOpen, (), (override)); MOCK_METHOD(const std::string&, request_id, (), (override)); - MOCK_METHOD(bool, HasUsageInfoSupport, (bool*), (override)); + MOCK_METHOD(bool, HasUsageTableSupport, (bool*), (override)); MOCK_METHOD(CdmResponseType, GetHdcpCapabilities, (HdcpCapability*, HdcpCapability*), (override)); MOCK_METHOD(bool, GetSupportedCertificateTypes, (SupportedCertificateTypes*), @@ -151,7 +151,9 @@ class MockCryptoSession : public TestCryptoSession { MOCK_METHOD(bool, GetApiVersion, (uint32_t*), (override)); MOCK_METHOD(CdmResponseType, GenerateNonce, (uint32_t*), (override)); MOCK_METHOD(CdmResponseType, PrepareAndSignLicenseRequest, - (const std::string&, std::string*, std::string*), (override)); + (const std::string&, std::string*, std::string*, bool&, + OEMCrypto_SignatureHashAlgorithm&), + (override)); MOCK_METHOD(CdmResponseType, LoadEntitledContentKeys, (const std::vector& key_array), (override)); MOCK_METHOD(bool, GetResourceRatingTier, (uint32_t*), (override)); @@ -188,12 +190,12 @@ using video_widevine::WidevinePsshData_EntitledKey; // gmock methods using ::testing::_; using ::testing::DoAll; -using ::testing::Eq; using ::testing::NotNull; using ::testing::PrintToStringParamName; using ::testing::Return; using ::testing::ReturnRef; using ::testing::SetArgPointee; +using ::testing::SetArgReferee; using ::testing::UnorderedElementsAre; using ::testing::Values; @@ -226,11 +228,11 @@ class CdmLicenseTest : public WvCdmTestBase { } void TearDown() override { - if (cdm_license_) delete cdm_license_; - if (policy_engine_) delete policy_engine_; - if (init_data_) delete init_data_; - if (crypto_session_) delete crypto_session_; - if (clock_) delete clock_; + delete cdm_license_; + delete policy_engine_; + delete init_data_; + delete crypto_session_; + delete clock_; } virtual void CreateCdmLicense() { @@ -303,12 +305,13 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, request_id()) .WillOnce(ReturnRef(kCryptoRequestId)); - EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(NotNull())) + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) .WillOnce( DoAll(SetArgPointee<0>(usage_information_support), Return(true))); EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version), - SetArgPointee<1>(max_hdcp_version), Return(NO_ERROR))); + SetArgPointee<1>(max_hdcp_version), + Return(CdmResponseType(NO_ERROR)))); // Supported certificates set by SetUp(). EXPECT_CALL(*crypto_session_, GetSupportedCertificateTypes(NotNull())); EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())) @@ -318,12 +321,14 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { .WillOnce(DoAll(SetArgPointee<0>(resource_rating_tier), Return(true))); EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime)); EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(kNonce), Return(NO_ERROR))); + .WillOnce( + DoAll(SetArgPointee<0>(kNonce), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, - PrepareAndSignLicenseRequest(_, NotNull(), NotNull())) + PrepareAndSignLicenseRequest(_, NotNull(), NotNull(), _, _)) .WillOnce(DoAll(SetArgPointee<1>(kFakeCoreMessage), SetArgPointee<2>(kLicenseRequestSignature), - Return(NO_ERROR))); + SetArgReferee<3>(false), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, GetBuildInformation(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kFakeBuildInfo), Return(true))); EXPECT_CALL(*crypto_session_, GetWatermarkingSupport(NotNull())) @@ -435,12 +440,13 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) { EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, request_id()) .WillOnce(ReturnRef(kCryptoRequestId)); - EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(NotNull())) + EXPECT_CALL(*crypto_session_, HasUsageTableSupport(NotNull())) .WillOnce( DoAll(SetArgPointee<0>(usage_information_support), Return(true))); EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version), - SetArgPointee<1>(max_hdcp_version), Return(NO_ERROR))); + SetArgPointee<1>(max_hdcp_version), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, GetSupportedCertificateTypes(NotNull())); EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())) .WillOnce( @@ -449,12 +455,14 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) { .WillOnce(DoAll(SetArgPointee<0>(resource_rating_tier), Return(true))); EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime)); EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull())) - .WillOnce(DoAll(SetArgPointee<0>(kNonce), Return(NO_ERROR))); + .WillOnce( + DoAll(SetArgPointee<0>(kNonce), Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, - PrepareAndSignLicenseRequest(_, NotNull(), NotNull())) + PrepareAndSignLicenseRequest(_, NotNull(), NotNull(), _, _)) .WillOnce(DoAll(SetArgPointee<1>(kFakeCoreMessage), SetArgPointee<2>(kLicenseRequestSignature), - Return(NO_ERROR))); + SetArgReferee<3>(false), + Return(CdmResponseType(NO_ERROR)))); EXPECT_CALL(*crypto_session_, GetBuildInformation(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kFakeBuildInfo), Return(true))); EXPECT_CALL(*crypto_session_, GetWatermarkingSupport(NotNull())) @@ -598,7 +606,7 @@ TEST_P(CdmLicenseEntitledKeyTest, LoadsEntitledKeys) { if (variant.should_succeed) { EXPECT_CALL(*crypto_session_, LoadEntitledContentKeys(_)) - .WillOnce(Return(KEY_ADDED)); + .WillOnce(Return(CdmResponseType(KEY_ADDED))); EXPECT_CALL(*policy_engine_, SetEntitledLicenseKeys(_)).Times(1); } else { EXPECT_CALL(*crypto_session_, LoadEntitledContentKeys(_)).Times(0); diff --git a/core/test/message_dumper.cpp b/core/test/message_dumper.cpp index 8548833e..65289fba 100644 --- a/core/test/message_dumper.cpp +++ b/core/test/message_dumper.cpp @@ -13,14 +13,10 @@ #include "oec_device_features.h" #include "test_base.h" -using video_widevine::ClientIdentification; using video_widevine::License; -using video_widevine::License_KeyContainer; using video_widevine::LicenseRequest; -using video_widevine::LicenseRequest_ContentIdentification; using video_widevine::SignedMessage; using video_widevine::SignedProvisioningMessage; -using video_widevine::WidevinePsshData_EntitledKey; namespace wvcdm { namespace { @@ -112,7 +108,7 @@ void MessageDumper::DumpLicense(const std::string& response) { Unpack_ODK_LicenseResponse(&odk_msg, &odk_license_response); EXPECT_EQ(ODK_Message_GetStatus(&odk_msg), MESSAGE_STATUS_OK); // Valid hash is only needed for v16 messages. - std::string hash(' ', ODK_SHA256_HASH_SIZE); + std::string hash(ODK_SHA256_HASH_SIZE, ' '); DumpHex(&license_file, "core_request_sha256", hash); license_file << " nonce_required_ = " << (odk_parsed_license.nonce_required ? "true" : "false") @@ -165,7 +161,7 @@ void MessageDumper::DumpProvisioningRequest( const CdmProvisioningRequest& request) { if (wvoec::global_features.derive_key_method == wvoec::DeviceFeatures::TEST_PROVISION_40) { - LOGD("Provisioning 4.0 does not have a v17 core message."); + LOGD("Provisioning 4.0 does not have a v17 or v18 core message."); } else { DumpHeader(&provision_file, "Provision"); SignedProvisioningMessage signed_message; @@ -195,6 +191,26 @@ void MessageDumper::DumpProvisioning(const CdmProvisioningResponse& response) { signed_response.oemcrypto_core_message()); DumpHex(&provision_file, "provisioning_response", signed_response.message()); + // The choice of ECC or RSA key is decided at the server, based on + // information in the DCSL. We can only reproduce this by looking + // at the current response. + std::string message = + signed_response.oemcrypto_core_message() + signed_response.message(); + ODK_Message odk_msg = ODK_Message_Create( + reinterpret_cast(const_cast(message.c_str())), + message.length()); + ODK_Message_SetSize(&odk_msg, + signed_response.oemcrypto_core_message().length()); + ODK_ParsedProvisioning odk_parsed_response; + ODK_ProvisioningResponse provisioning_response; + provisioning_response.parsed_provisioning = &odk_parsed_response; + Unpack_ODK_ProvisioningResponse(&odk_msg, &provisioning_response); + EXPECT_EQ(ODK_Message_GetStatus(&odk_msg), MESSAGE_STATUS_OK); + provision_file << " device_key_type_ = " + << ((odk_parsed_response.key_type == + OEMCrypto_RSA_Private_Key) + ? "OEMCrypto_RSA_Private_Key;\n" + : "OEMCrypto_ECC_Private_Key;\n"); provision_file << " RunTest();\n"; provision_file << "}\n\n"; } diff --git a/core/test/ota_keybox_provisioner_test.cpp b/core/test/ota_keybox_provisioner_test.cpp index a0913d4d..8bbf3e65 100644 --- a/core/test/ota_keybox_provisioner_test.cpp +++ b/core/test/ota_keybox_provisioner_test.cpp @@ -68,7 +68,8 @@ class MockCryptoSession : public CryptoSession { void ExpectRequest(const std::string& request, CdmResponseType result) { if (result == NO_ERROR) { EXPECT_CALL(*this, PrepareOtaProvisioningRequest(false, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(request), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(request), + Return(CdmResponseType(NO_ERROR)))); } else { EXPECT_CALL(*this, PrepareOtaProvisioningRequest(false, NotNull())) .WillOnce(Return(result)); @@ -208,7 +209,8 @@ TEST_F(OtaKeyboxProvisionerTest, FullProvisioning) { EXPECT_FALSE(provisioner_->response_received()); // Generate request. - crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, NO_ERROR); + crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, + CdmResponseType(NO_ERROR)); std::string signed_prov_message, default_url; EXPECT_EQ(NO_ERROR, provisioner_->GetProvisioningRequest(&signed_prov_message, &default_url)); @@ -226,7 +228,8 @@ TEST_F(OtaKeyboxProvisionerTest, FullProvisioning) { clock_.SetTime(kProvisioningTime); std::string response; MakeSignedOtaProvisioningResponse(kFakeOtaProvisioningResponse, &response); - crypto_session_->ExpectResponse(kFakeOtaProvisioningResponse, NO_ERROR); + crypto_session_->ExpectResponse(kFakeOtaProvisioningResponse, + CdmResponseType(NO_ERROR)); EXPECT_EQ(NO_ERROR, provisioner_->HandleProvisioningResponse(response)); // Post-response conditions. @@ -242,7 +245,8 @@ TEST_F(OtaKeyboxProvisionerTest, FullProvisioning) { // Provisioning from A perspective should complete without issues. TEST_F(OtaKeyboxProvisionerTest, CompletedInDifferentEngine) { // Generate request (engine A). - crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, NO_ERROR); + crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, + CdmResponseType(NO_ERROR)); std::string signed_prov_message, default_url; EXPECT_EQ(NO_ERROR, provisioner_->GetProvisioningRequest(&signed_prov_message, &default_url)); @@ -276,7 +280,8 @@ TEST_F(OtaKeyboxProvisionerTest, CompletedInDifferentEngine) { // malformed SignedProvisioningMessage. TEST_F(OtaKeyboxProvisionerTest, MalformedResponseMessage) { // Generate request. - crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, NO_ERROR); + crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, + CdmResponseType(NO_ERROR)); std::string signed_prov_message, default_url; EXPECT_EQ(NO_ERROR, provisioner_->GetProvisioningRequest(&signed_prov_message, &default_url)); @@ -321,7 +326,8 @@ TEST_F(OtaKeyboxProvisionerTest, MalformedResponseMessage) { // Test case where OEMCrypto rejects the provided OTA keybox response. TEST_F(OtaKeyboxProvisionerTest, RejectedResponse) { // Generate request. - crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, NO_ERROR); + crypto_session_->ExpectRequest(kFakeOtaProvisioningRequest, + CdmResponseType(NO_ERROR)); std::string request, default_url; EXPECT_EQ(NO_ERROR, provisioner_->GetProvisioningRequest(&request, &default_url)); @@ -329,7 +335,8 @@ TEST_F(OtaKeyboxProvisionerTest, RejectedResponse) { // Load response. OEMCrypto returns error. std::string response; MakeSignedOtaProvisioningResponse(kFakeOtaProvisioningResponse, &response); - crypto_session_->ExpectResponse(kFakeOtaProvisioningResponse, UNKNOWN_ERROR); + crypto_session_->ExpectResponse(kFakeOtaProvisioningResponse, + CdmResponseType(UNKNOWN_ERROR)); EXPECT_NE(NO_ERROR, provisioner_->HandleProvisioningResponse(response)); // Post-response failure conditions. @@ -341,7 +348,8 @@ TEST_F(OtaKeyboxProvisionerTest, RejectedResponse) { TEST_F(OtaKeyboxProvisionerTest, OtaProvisioningNotImplemented) { // Generate request. - crypto_session_->ExpectRequest(kEmptyString, NOT_IMPLEMENTED_ERROR); + crypto_session_->ExpectRequest(kEmptyString, + CdmResponseType(NOT_IMPLEMENTED_ERROR)); std::string request, default_url; EXPECT_EQ(NOT_IMPLEMENTED_ERROR, provisioner_->GetProvisioningRequest(&request, &default_url)); diff --git a/core/test/policy_engine_constraints_unittest.cpp b/core/test/policy_engine_constraints_unittest.cpp index 726ab3bc..1158148f 100644 --- a/core/test/policy_engine_constraints_unittest.cpp +++ b/core/test/policy_engine_constraints_unittest.cpp @@ -18,7 +18,6 @@ #include "wv_cdm_types.h" // protobuf generated classes. -using video_widevine::License; using video_widevine::License_Policy; using video_widevine::STREAMING; @@ -72,6 +71,7 @@ class HdcpOnlyMockCryptoSession : public TestCryptoSession { MOCK_METHOD(CdmResponseType, GetHdcpCapabilities, (HdcpCapability*, HdcpCapability*), (override)); + CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; } }; class MockCdmEventListener : public WvCdmEventListener { @@ -130,7 +130,6 @@ class PolicyEngineConstraintsTest : public WvCdmTestBase { id->set_type(STREAMING); License_Policy* policy = license_.mutable_policy(); - policy = license_.mutable_policy(); policy->set_can_play(true); policy->set_can_persist(false); policy->set_rental_duration_seconds(kRentalDuration); @@ -238,10 +237,11 @@ TEST_F(PolicyEngineConstraintsTest, IsPermissiveWithoutAResolution) { } EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); @@ -270,10 +270,10 @@ TEST_F(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) { } EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly( - DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(NO_ERROR))); + .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(NO_ERROR)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->NotifyResolution(1, kTargetRes1); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); @@ -317,27 +317,28 @@ TEST_F(PolicyEngineConstraintsTest, kKeyStatusUsable, kKeyId4, kKeyStatusOutputNotAllowed, true); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), - Return(GET_HDCP_CAPABILITY_FAILED))) + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))) .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), - Return(GET_HDCP_CAPABILITY_FAILED))); + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); } int64_t start_time = current_time_ + 5; { InSequence calls; EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), - Return(GET_HDCP_CAPABILITY_FAILED))); + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(start_time + kHdcpInterval / 2)) .WillOnce(Return(start_time + kHdcpInterval)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), - Return(GET_HDCP_CAPABILITY_FAILED))) - .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), Return(NO_ERROR))); + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))) + .WillOnce(DoAll(SetArgPointee<0>(HDCP_V2_2), + Return(CdmResponseType(NO_ERROR)))); } policy_engine_->NotifyResolution(1, kTargetRes1); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent(); @@ -368,9 +369,10 @@ TEST_F(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) { } EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_V2), Return(NO_ERROR))); + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_V2), Return(CdmResponseType(NO_ERROR)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->NotifyResolution(1, kTargetRes1); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); @@ -410,9 +412,10 @@ TEST_F(PolicyEngineConstraintsTest, HandlesNoHdcp) { } EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NONE), Return(NO_ERROR))); + .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NONE), + Return(CdmResponseType(NO_ERROR)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->NotifyResolution(1, kTargetRes1); policy_engine_->OnTimerEvent(); @@ -453,10 +456,11 @@ TEST_F(PolicyEngineConstraintsTest, UsesDefaultHdcpWhenResolutionNotSet) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId2)); diff --git a/core/test/policy_engine_unittest.cpp b/core/test/policy_engine_unittest.cpp index c6ebf0ae..677502a4 100644 --- a/core/test/policy_engine_unittest.cpp +++ b/core/test/policy_engine_unittest.cpp @@ -11,6 +11,7 @@ #include #include +#include "crypto_key.h" #include "license.h" #include "mock_clock.h" #include "policy_engine.h" @@ -35,6 +36,31 @@ const int64_t kLicenseRenewalRecoveryDuration = 30; // 30 seconds const int64_t kLowDuration = 300; // 5 minutes const int64_t kHighDuration = std::max(std::max(kRentalDuration, kPlaybackDuration), kLicenseDuration); +const int64_t kOneDay = 24 * 60 * 60; +const int64_t kTwoDays = 2 * 24 * 60 * 60; +const int64_t kSevenDays = 7 * 24 * 60 * 60; +const int64_t kFiveSeconds = 5; +const int64_t kTenSeconds = 10; +const int64_t kThirtySeconds = 30; +const int64_t kFortySeconds = 30; +const int64_t kFiveMinutes = 5 * 60; +const int64_t kFifteenMinutes = 15 * 60; +const int64_t kTwoHours = 2 * 60 * 60; +const int64_t kThreeHours = 3 * 60 * 60; +const int64_t kDurationUnlimited = 0; +const video_widevine::License::Policy::TimerDelayBase + kTimerDelayBaseUnspecified = video_widevine:: + License_Policy_TimerDelayBase_TIMER_DELAY_BASE_UNSPECIFIED; +const video_widevine::License::Policy::TimerDelayBase + kTimerDelayBaseLicenseStart = + video_widevine::License_Policy_TimerDelayBase_LICENSE_START; +const video_widevine::License::Policy::TimerDelayBase + kTimerDelayBaseLicenseLoad = + video_widevine::License_Policy_TimerDelayBase_LICENSE_LOAD; +const video_widevine::License::Policy::TimerDelayBase + kTimerDelayBaseLicenseFirstDecrypt = + video_widevine::License_Policy_TimerDelayBase_FIRST_DECRYPT; + const char* kRenewalServerUrl = "https://test.google.com/license/GetCencLicense"; const KeyId kKeyId = "357adc89f1673433c36c621f1b5c41ee"; @@ -44,23 +70,40 @@ const KeyId kSomeRandomKeyId = "some_random_key_id"; const KeyId kUnknownKeyId = "some_random_unknown_key_id"; const CdmSessionId kSessionId = "mock_session_id"; +const uint32_t kOemCryptoV16 = 16; +const uint32_t kOemCryptoV18 = 18; + int64_t GetLicenseRenewalDelay(int64_t license_duration) { return license_duration > kLicenseRenewalPeriod ? license_duration - kLicenseRenewalPeriod : 0; } -class HdcpOnlyMockCryptoSession : public TestCryptoSession { +class MockCryptoSession : public CryptoSession { public: - HdcpOnlyMockCryptoSession(metrics::CryptoMetrics* metrics) - : TestCryptoSession(metrics) {} - + MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) + : CryptoSession(crypto_metrics) {} + MOCK_METHOD(bool, IsOpen, (), (override)); + MOCK_METHOD(const std::string&, request_id, (), (override)); + MOCK_METHOD(bool, HasUsageTableSupport, (bool*), (override)); + MOCK_METHOD(bool, GetSupportedCertificateTypes, (SupportedCertificateTypes*), + (override)); + MOCK_METHOD(bool, GetApiVersion, (uint32_t*), (override)); + MOCK_METHOD(CdmResponseType, GenerateNonce, (uint32_t*), (override)); + MOCK_METHOD(CdmResponseType, PrepareAndSignLicenseRequest, + (const std::string&, std::string*, std::string*, bool&, + OEMCrypto_SignatureHashAlgorithm&), + (override)); + MOCK_METHOD(CdmResponseType, LoadEntitledContentKeys, + (const std::vector& key_array), (override)); + MOCK_METHOD(bool, GetResourceRatingTier, (uint32_t*), (override)); + MOCK_METHOD(bool, GetWatermarkingSupport, (CdmWatermarkingSupport*), + (override)); + MOCK_METHOD(bool, GetBuildInformation, (std::string*), (override)); MOCK_METHOD(CdmResponseType, GetHdcpCapabilities, (HdcpCapability*, HdcpCapability*), (override)); - CdmResponseType DoRealGetHdcpCapabilities(HdcpCapability* current, - HdcpCapability* max) { - return CryptoSession::GetHdcpCapabilities(current, max); - } + + CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; } }; class MockCdmEventListener : public WvCdmEventListener { @@ -87,7 +130,6 @@ using video_widevine::STREAMING; // gmock methods using ::testing::_; -using ::testing::AtLeast; using ::testing::InSequence; using ::testing::Invoke; using ::testing::MockFunction; @@ -98,13 +140,14 @@ using ::testing::UnorderedElementsAre; class PolicyEngineTest : public WvCdmTestBase { public: - PolicyEngineTest() : crypto_session_(&dummy_metrics_) {} + PolicyEngineTest() + : crypto_session_(new MockCryptoSession(&dummy_metrics_)) {} protected: void SetUp() override { WvCdmTestBase::SetUp(); - policy_engine_.reset( - new PolicyEngine(kSessionId, &mock_event_listener_, &crypto_session_)); + policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_, + crypto_session_.get())); InjectMockClock(); license_.set_license_start_time(kLicenseStartTime); @@ -118,7 +161,6 @@ class PolicyEngineTest : public WvCdmTestBase { key->set_id(kKeyId); License_Policy* policy = license_.mutable_policy(); - policy = license_.mutable_policy(); policy->set_can_play(true); policy->set_can_persist(false); policy->set_can_renew(false); @@ -133,11 +175,6 @@ class PolicyEngineTest : public WvCdmTestBase { policy->set_renewal_delay_seconds(0); policy->set_renewal_retry_interval_seconds(kLicenseRenewalRetryInterval); policy->set_renew_with_usage(false); - - ON_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillByDefault( - Invoke(&crypto_session_, - &HdcpOnlyMockCryptoSession::DoRealGetHdcpCapabilities)); } void InjectMockClock() { @@ -145,6 +182,12 @@ class PolicyEngineTest : public WvCdmTestBase { policy_engine_->set_clock(mock_clock_); } + void ResetPolicyEngine(MockClock* mock_clock) { + policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_, + crypto_session_.get())); + policy_engine_->set_clock(mock_clock); + } + void ExpectSessionKeysChange(CdmKeyStatus expected_key_status, bool expected_has_new_usable_key) { EXPECT_CALL( @@ -154,6 +197,17 @@ class PolicyEngineTest : public WvCdmTestBase { expected_has_new_usable_key)); } + void ExpectSessionKeysChange(CdmKeyStatus expected_key_status, + bool expected_has_new_usable_key, + int repetitions) { + EXPECT_CALL( + mock_event_listener_, + OnSessionKeysChange( + kSessionId, UnorderedElementsAre(Pair(kKeyId, expected_key_status)), + expected_has_new_usable_key)) + .Times(repetitions); + } + void ExpectSessionKeysChange(CdmKeyStatus expected_key_status, bool expected_has_new_usable_key, KeyId expected_keyid) { @@ -181,7 +235,7 @@ class PolicyEngineTest : public WvCdmTestBase { } metrics::CryptoMetrics dummy_metrics_; - NiceMock crypto_session_; + std::unique_ptr crypto_session_; StrictMock mock_event_listener_; MockClock* mock_clock_; std::unique_ptr policy_engine_; @@ -189,69 +243,37 @@ class PolicyEngineTest : public WvCdmTestBase { MockFunction check_; }; +class PolicyEngineTestV16 : public PolicyEngineTest { + public: + PolicyEngineTestV16() {} + + protected: + void SetUp() override { + EXPECT_CALL(*crypto_session_, GetApiVersion(_)) + .WillOnce(DoAll(SetArgPointee<0>(kOemCryptoV16), Return(true))); + PolicyEngineTest::SetUp(); + } +}; + +class PolicyEngineTestV18 : public PolicyEngineTest { + public: + PolicyEngineTestV18() {} + + protected: + void SetUp() override { + EXPECT_CALL(*crypto_session_, GetApiVersion(_)) + .WillRepeatedly(DoAll(SetArgPointee<0>(kOemCryptoV18), Return(true))); + PolicyEngineTest::SetUp(); + } +}; + TEST_F(PolicyEngineTest, NoLicense) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackSuccess_OfflineLicense_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly( - DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(NO_ERROR))); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicense_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true, kEntitlementKeyId); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly( - DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(NO_ERROR))); - - License::KeyContainer* key = license_.mutable_key(0); - key->set_type(License::KeyContainer::ENTITLEMENT); - key->set_id(kEntitlementKeyId); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - std::vector entitled_keys(1); - entitled_keys[0].set_entitlement_key_id(kEntitlementKeyId); - entitled_keys[0].set_key_id(kKeyId); - policy_engine_->SetEntitledLicenseKeys(entitled_keys); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicenseExpiration_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, + DISABLED_PlaybackSuccess_EntitlementLicenseExpiration_V15) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kPlaybackStartTime)) @@ -269,7 +291,7 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicenseExpiration_V15) { key->set_type(License::KeyContainer::ENTITLEMENT); key->set_id(kEntitlementKeyId); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -283,7 +305,8 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicenseExpiration_V15) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackSuccess_StreamingLicense_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, DISABLED_PlaybackSuccess_StreamingLicense_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_license_duration_seconds(kLowDuration); @@ -295,12 +318,17 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_StreamingLicense_V15) { ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); + // TODO(b/256021697): Test is failing after migrating to v16. + // The value passed to OnExpirationUpdate() are not the same. + // Current expectation: kLicenseStartTime + kLowDuration (license duration) + // Actual: kLicenseStart + kRentalDuration - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); @@ -308,817 +336,8 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_StreamingLicense_V15) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_can_play(false); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 5)) - .WillOnce(Return(kLicenseStartTime + 7)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - - policy_engine_->BeginDecryption(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, - LicenseExpired_RentalDurationExpiredWithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kLowDuration); - policy->set_license_duration_seconds(kHighDuration); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(3)); - - policy_engine_->SetLicense(license_, false, false); - - for (int i = 1; i <= 3; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalDurationPassedWithPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kLowDuration); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired_V15) { - int64_t playback_start_time = kLicenseStartTime + 10000; - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(playback_start_time)) - .WillOnce(Return(playback_start_time + kPlaybackDuration - 2)) - .WillOnce(Return(playback_start_time + kPlaybackDuration + 2)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, playback_start_time + kPlaybackDuration)); - EXPECT_CALL(check_, Call(1)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(2)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, - LicenseExpired_LicenseDurationExpiredWithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_license_duration_seconds(kLowDuration); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(3)); - - policy_engine_->SetLicense(license_, false, false); - - for (int i = 1; i <= 3; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_Offline_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_renewal_delay_seconds(kLicenseDuration + 10); - policy->set_can_renew(true); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(1)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(2)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_Streaming_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_rental_duration_seconds(); - policy->clear_playback_duration_seconds(); - policy->set_renewal_delay_seconds(kLicenseDuration + 10); - policy->set_can_renew(true); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - EXPECT_CALL(check_, Call(1)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(2)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(3)); - - policy_engine_->SetLicense(license_, false, false); - - for (int i = 1; i <= 3; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 2)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 2)) - .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 2)) - .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 2)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - EXPECT_CALL(check_, Call(3)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(4)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 4; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_LicenseDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(1)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(2)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_rental_duration_seconds(); - policy->clear_playback_duration_seconds(); - // Only |license_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndLicense0_WithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_playback_duration_seconds(); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndLicense0_WithPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_playback_duration_seconds(); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalAndLicense0_WithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_rental_duration_seconds(); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalAndLicense0_WithPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_rental_duration_seconds(); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, - PlaybackOk_RentalAndLicense0_WithPlaybackBeforeLicense_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_rental_duration_seconds(); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime - 10)) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - // Attempt decryption before the license has been received - policy_engine_->BeginDecryption(); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_Durations0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kHighDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kHighDuration)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime - 100)) - .WillOnce(Return(kLicenseStartTime - 50)) - .WillOnce(Return(kLicenseStartTime)) - .WillOnce(Return(kPlaybackStartTime)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsableInFuture, false); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->OnTimerEvent(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse_V15) { - License_Policy* policy = license_.mutable_policy(); - const int64_t license_renewal_delay = - GetLicenseRenewalDelay(kPlaybackDuration); - policy->set_renewal_delay_seconds(license_renewal_delay); - policy->set_can_renew(false); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(3)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 3; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_can_renew(true); - policy->set_license_duration_seconds(kLowDuration); - int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration); - policy->set_renewal_delay_seconds(license_renewal_delay); - int64_t new_license_start_time = - kLicenseStartTime + license_renewal_delay + 15; - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 15)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + - kLicenseRenewalRetryInterval + 10)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); - EXPECT_CALL(check_, Call(2)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, new_license_start_time + kLowDuration)); - EXPECT_CALL(check_, Call(3)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - license_.set_license_start_time(new_license_start_time); - policy->set_playback_duration_seconds(2 * kPlaybackDuration); - LicenseIdentification* id = license_.mutable_id(); - id->set_version(2); - policy_engine_->UpdateLicense(license_, false); - - policy_engine_->OnTimerEvent(); - check_.Call(3); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_WithFutureStartTime_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_can_renew(true); - policy->set_license_duration_seconds(kLowDuration); - int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration); - policy->set_renewal_delay_seconds(license_renewal_delay); - int64_t new_license_start_time = - kLicenseStartTime + license_renewal_delay + 50; - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 15)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 20)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 30)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 60)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); - EXPECT_CALL(check_, Call(2)); - ExpectSessionKeysChange(kKeyStatusUsableInFuture, false); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, new_license_start_time + kLowDuration)); - EXPECT_CALL(check_, Call(3)); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(check_, Call(4)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - license_.set_license_start_time(new_license_start_time); - LicenseIdentification* id = license_.mutable_id(); - id->set_version(2); - policy_engine_->UpdateLicense(license_, false); - - policy_engine_->OnTimerEvent(); - check_.Call(3); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - check_.Call(4); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_can_renew(true); - policy->set_license_duration_seconds(kLowDuration); - int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration); - policy->set_renewal_delay_seconds(license_renewal_delay); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 10)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 10)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence s; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); - EXPECT_CALL(check_, Call(2)); - EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); - EXPECT_CALL(check_, Call(3)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(4)); - - policy_engine_->SetLicense(license_, false, false); - - for (int i = 1; i <= 2; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - license_.set_license_start_time(kLicenseStartTime + license_renewal_delay + - 30); - policy_engine_->UpdateLicense(license_, false); - - policy_engine_->OnTimerEvent(); - check_.Call(3); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - check_.Call(4); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, DISABLED_PlaybackFailed_RepeatedRenewFailures_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); const int64_t license_renewal_delay = @@ -1139,9 +358,10 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures_V15) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 15)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1161,7 +381,7 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures_V15) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(8)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 8; ++i) { @@ -1172,7 +392,8 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures_V15) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewSuccessAfterExpiry_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); policy->set_license_duration_seconds(kLowDuration); @@ -1199,9 +420,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry_V15) { .WillOnce(Return(new_license_start_time)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 20)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1227,7 +449,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry_V15) { OnExpirationUpdate(_, kPlaybackStartTime + new_playback_duration)); EXPECT_CALL(check_, Call(10)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 9; ++i) { @@ -1251,7 +473,8 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry_V15) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterFailures_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewSuccessAfterFailures_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); policy->clear_rental_duration_seconds(); @@ -1273,9 +496,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterFailures_V15) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 67)) .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 200)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1293,7 +517,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterFailures_V15) { EXPECT_CALL(check_, Call(6)); EXPECT_CALL(check_, Call(7)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 5; ++i) { @@ -1315,7 +539,9 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterFailures_V15) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +// Note: Test passes in without v15 timers. +TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RenewedWithUsage_V15) { int64_t new_license_start_time = kLicenseStartTime + 10; int64_t new_playback_duration = kPlaybackDuration + 100; @@ -1331,9 +557,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage_V15) { .WillOnce(Return(kLicenseStartTime + 20)) .WillOnce(Return(kLicenseStartTime + 40)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1349,7 +576,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage_V15) { OnExpirationUpdate(_, kPlaybackStartTime + new_playback_duration)); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); check_.Call(1); @@ -1374,7 +601,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage_V15) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, MultipleKeysInLicense) { +TEST_F(PolicyEngineTestV16, MultipleKeysInLicense) { const char kSigningKeyId[] = "signing_key"; license_.clear_key(); @@ -1393,21 +620,23 @@ TEST_F(PolicyEngineTest, MultipleKeysInLicense) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); EXPECT_TRUE(policy_engine_->CanDecryptContent(kAnotherKeyId)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kSigningKeyId)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_SoftEnforcePlaybackDuration_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_SoftEnforcePlaybackDuration_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_playback_duration(true); @@ -1419,9 +648,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_SoftEnforcePlaybackDuration_V15) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 5)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 5)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -1435,7 +665,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_SoftEnforcePlaybackDuration_V15) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 4; ++i) { @@ -1447,7 +677,9 @@ TEST_F(PolicyEngineTest, PlaybackOk_SoftEnforcePlaybackDuration_V15) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, + DISABLED_LicenseExpired_SoftEnforceLoadBeforeExpire_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_playback_duration(true); @@ -1456,16 +688,17 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire_V15) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - policy_engine_->SetLicense(license_, false, true); + policy_engine_->SetLicense(license_, true); policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime, kPlaybackStartTime); policy_engine_->OnTimerEvent(); @@ -1473,7 +706,9 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire_V15) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineTest, + DISABLED_LicenseExpired_SoftEnforceLoadAfterExpire_V15) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_playback_duration(true); @@ -1482,14 +717,15 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire_V15) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence seq; ExpectSessionKeysChange(kKeyStatusExpired, false); - policy_engine_->SetLicense(license_, false, true); + policy_engine_->SetLicense(license_, true); policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime, kPlaybackStartTime); policy_engine_->OnTimerEvent(); @@ -1497,167 +733,25 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire_V15) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_GracePeriod_V15) { - const int64_t kGracePeriod = 300; // 5 minutes - License_Policy* policy = license_.mutable_policy(); - policy->set_play_start_grace_period_seconds(kGracePeriod); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kGracePeriod - 5)) - .WillOnce(Return(kPlaybackStartTime + kGracePeriod + 5)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence seq; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(2)); - EXPECT_CALL(check_, Call(3)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(4)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 4; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithLoad_V15) { - const int64_t kGracePeriod = 300; // 5 minutes - const int64_t kNewPlaybackStartTime = kPlaybackStartTime + kPlaybackDuration; - License_Policy* policy = license_.mutable_policy(); - policy->set_play_start_grace_period_seconds(kGracePeriod); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kNewPlaybackStartTime)) - .WillOnce(Return(kNewPlaybackStartTime)) - .WillOnce(Return(kNewPlaybackStartTime + kGracePeriod - 5)) - .WillOnce(Return(kNewPlaybackStartTime + kGracePeriod + 5)) - .WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration - 5)) - .WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence seq; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(check_, Call(1)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kNewPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(check_, Call(2)); - EXPECT_CALL(check_, Call(3)); - ExpectSessionKeysChange(kKeyStatusExpired, false); - EXPECT_CALL(check_, Call(4)); - - policy_engine_->SetLicense(license_, false, true); - policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime, - 0); - policy_engine_->BeginDecryption(); - - for (int i = 1; i <= 4; ++i) { - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->OnTimerEvent(); - check_.Call(i); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithExpiredLoad_V15) { - const int64_t kGracePeriod = 300; // 5 minutes - const int64_t kNewPlaybackStartTime = - kPlaybackStartTime + kPlaybackDuration + 5; - License_Policy* policy = license_.mutable_policy(); - policy->set_play_start_grace_period_seconds(kGracePeriod); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kNewPlaybackStartTime)) - .WillOnce(Return(kNewPlaybackStartTime)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence seq; - ExpectSessionKeysChange(kKeyStatusExpired, false); - - policy_engine_->SetLicense(license_, false, true); - policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime, - kPlaybackStartTime); - - policy_engine_->OnTimerEvent(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_CanStoreGracePeriod_V15) { - const int64_t kGracePeriod = 300; // 5 minutes - License_Policy* policy = license_.mutable_policy(); - policy->set_play_start_grace_period_seconds(kGracePeriod); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + 50)) - .WillOnce(Return(kPlaybackStartTime + kGracePeriod + 2)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - InSequence seq; - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - - policy_engine_->OnTimerEvent(); - EXPECT_EQ(0, policy_engine_->GetGracePeriodEndTime()); - - policy_engine_->OnTimerEvent(); - EXPECT_EQ(kPlaybackStartTime, policy_engine_->GetGracePeriodEndTime()); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RestoreWithoutPlaybackTimes_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +// Note: Test passes in without v15 timers. +TEST_F(PolicyEngineTest, DISABLED_PlaybackOk_RestoreWithoutPlaybackTimes_V15) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kLicenseStartTime + 15)) .WillOnce(Return(kLicenseStartTime + 30)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - policy_engine_->SetLicense(license_, false, true); + policy_engine_->SetLicense(license_, true); policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent(); @@ -1673,7 +767,7 @@ struct KeySecurityLevelParams { bool expect_can_level_unknown_use_key; }; -KeySecurityLevelParams key_security_test_vectors[] = { +const KeySecurityLevelParams kKeySecurityTestVectors[] = { {false, License::KeyContainer::HW_SECURE_ALL, true, true, true, true}, {true, License::KeyContainer::SW_SECURE_CRYPTO, true, true, true, false}, {true, License::KeyContainer::SW_SECURE_DECODE, true, true, true, false}, @@ -1683,11 +777,11 @@ KeySecurityLevelParams key_security_test_vectors[] = { }; class PolicyEngineKeySecurityLevelTest - : public PolicyEngineTest, - public ::testing::WithParamInterface {}; + : public PolicyEngineTestV16, + public ::testing::WithParamInterface {}; -TEST_P(PolicyEngineKeySecurityLevelTest, CanUseKeyForSecurityLevel) { - KeySecurityLevelParams* param = GetParam(); +TEST_P(PolicyEngineKeySecurityLevelTest, CanUseKeyForSecurityLeve) { + const KeySecurityLevelParams* param = GetParam(); license_.clear_key(); @@ -1700,39 +794,44 @@ TEST_P(PolicyEngineKeySecurityLevelTest, CanUseKeyForSecurityLevel) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); SetCdmSecurityLevel(kSecurityLevelL1); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); EXPECT_EQ(param->expect_can_L1_use_key, policy_engine_->CanUseKeyForSecurityLevel(kKeyId)); SetCdmSecurityLevel(kSecurityLevelL2); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); EXPECT_EQ(param->expect_can_L2_use_key, policy_engine_->CanUseKeyForSecurityLevel(kKeyId)); SetCdmSecurityLevel(kSecurityLevelL3); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); EXPECT_EQ(param->expect_can_L3_use_key, policy_engine_->CanUseKeyForSecurityLevel(kKeyId)); SetCdmSecurityLevel(kSecurityLevelUnknown); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); EXPECT_EQ(param->expect_can_level_unknown_use_key, policy_engine_->CanUseKeyForSecurityLevel(kKeyId)); } INSTANTIATE_TEST_SUITE_P(PolicyEngine, PolicyEngineKeySecurityLevelTest, - ::testing::Range(&key_security_test_vectors[0], - &key_security_test_vectors[5])); + ::testing::Range(&kKeySecurityTestVectors[0], + &kKeySecurityTestVectors[5])); -class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest { +class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTestV16 { protected: enum KeyFlag { kKeyFlagNull, kKeyFlagFalse, kKeyFlagTrue }; @@ -1856,14 +955,15 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageBasic) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); ExpectSecureContentKey(kKeyId, kHardwareSecureAll); ExpectLessSecureContentKey(kAnotherKeyId, kKeySecurityLevelUnset); @@ -1916,14 +1016,15 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageGeneric) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); ExpectSecureContentKey(kKeyId, kHardwareSecureDecode); ExpectLessSecureContentKey(kAnotherKeyId, kHardwareSecureCrypto); @@ -1941,12 +1042,12 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageGeneric) { kSignFalse, kVerifyTrue); } -class PolicyEngineQueryTest : public PolicyEngineTest { +class PolicyEngineQueryTest : public PolicyEngineTestV16 { protected: void SetUp() override { PolicyEngineTest::SetUp(); policy_engine_.reset( - new PolicyEngine(kSessionId, nullptr, &crypto_session_)); + new PolicyEngine(kSessionId, nullptr, crypto_session_.get())); InjectMockClock(); // Use a STREAMING license policy. @@ -1957,137 +1058,8 @@ class PolicyEngineQueryTest : public PolicyEngineTest { } }; -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseNotReceived_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(0u, query_info.size()); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseStartTimeNotSet_V15) { - license_.clear_license_start_time(); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)); - - policy_engine_->SetLicense(license_, false, false); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(0u, query_info.size()); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 100)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 100, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 100)) - .WillOnce(Return(kLicenseStartTime + 200)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 100, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 200, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 50)) - .WillOnce(Return(kLicenseStartTime + 100)) - .WillOnce(Return(kLicenseStartTime + 150)) - .WillOnce(Return(kLicenseStartTime + 200)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 50, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 200, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - 100, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_Offline_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineQueryTest, DISABLED_QuerySuccess_Offline_V15) { LicenseIdentification* id = license_.mutable_id(); id->set_type(OFFLINE); @@ -2103,11 +1075,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Offline_V15) { .WillOnce(Return(kLicenseStartTime + 200)) .WillOnce(Return(kLicenseStartTime + 300)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); @@ -2128,745 +1101,8 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Offline_V15) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kLowDuration); - policy->set_license_duration_seconds(kHighDuration); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - - policy_engine_->SetLicense(license_, false, false); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialLicenseDurationExpired_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - - policy_engine_->SetLicense(license_, false, false); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse_V15) { - LicenseIdentification* id = license_.mutable_id(); - id->set_type(OFFLINE); - - License_Policy* policy = license_.mutable_policy(); - policy->set_can_play(false); - policy->set_can_persist(true); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 5)) - .WillOnce(Return(kLicenseStartTime + 7)) - .WillOnce(Return(kLicenseStartTime + 100)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - - policy_engine_->BeginDecryption(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_OFFLINE, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 100, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kLowDuration); - policy->set_license_duration_seconds(kHighDuration); - policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration)); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 2; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - kLowDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_playback_duration_seconds(kLowDuration); - policy->set_license_duration_seconds(kHighDuration); - policy->set_renewal_delay_seconds(GetLicenseRenewalDelay(kHighDuration)); - - int64_t playback_start_time = kLicenseStartTime + 10000; - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(playback_start_time)) - .WillOnce(Return(playback_start_time - 2 + kLowDuration)) - .WillOnce(Return(playback_start_time + 2 + kLowDuration)) - .WillOnce(Return(playback_start_time + 5 + kLowDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 2; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseDurationExpired_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_can_renew(false); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 2; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - kLowDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - int64_t license_renewal_delay = GetLicenseRenewalDelay(kLowDuration); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 5)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 1)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) - .WillOnce(Return(kLicenseStartTime + kLowDuration)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 4; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - kLowDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(kHighDuration); - int64_t license_renewal_delay = GetLicenseRenewalDelay(kHighDuration); - policy->set_renewal_delay_seconds(license_renewal_delay); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime)) - .WillOnce(Return(kLicenseStartTime + 5)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay - 2)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 2)) - .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 5)) - .WillOnce(Return(kLicenseStartTime + kHighDuration - 2)) - .WillOnce(Return(kLicenseStartTime + kHighDuration + 2)) - .WillOnce(Return(kLicenseStartTime + kHighDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 2; ++i) { - policy_engine_->OnTimerEvent(); - } - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - for (int i = 3; i <= 4; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseDuration0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - for (int i = 1; i <= 2; ++i) { - policy_engine_->OnTimerEvent(); - } - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(kLowDuration); - // Only |license_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(10, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, - QuerySuccess_PlaybackAndLicense0_WithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kRentalDuration); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(10, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, - QuerySuccess_PlaybackAndLicense0_WithPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kRentalDuration); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kRentalDuration - kPlaybackDuration + 10, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kRentalDuration - kPlaybackDuration - 10, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, - QuerySuccess_RentalAndLicense0_WithoutPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - policy->set_playback_duration_seconds(kPlaybackDuration); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalAndLicense0_WithPlayback_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - policy->set_playback_duration_seconds(kPlaybackDuration); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + 10)) - .WillOnce(Return(kPlaybackStartTime + 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - 10, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(10, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(0, std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_Durations0_V15) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(UNLIMITED_DURATION); - policy->set_playback_duration_seconds(UNLIMITED_DURATION); - policy->set_license_duration_seconds(UNLIMITED_DURATION); - policy->set_renewal_delay_seconds(kHighDuration + 10); - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 5)) - .WillOnce(Return(kLicenseStartTime + kHighDuration)) - .WillOnce(Return(kLicenseStartTime + kHighDuration + 9)) - .WillOnce(Return(kLicenseStartTime + kHighDuration + 15)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->BeginDecryption(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime - 100)) - .WillOnce(Return(kLicenseStartTime - 50)) - .WillOnce(Return(kLicenseStartTime - 10)) - .WillOnce(Return(kLicenseStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + 25)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - - policy_engine_->OnTimerEvent(); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - - policy_engine_->OnTimerEvent(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - policy_engine_->BeginDecryption(); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kLowDuration - 25, - std::stoll(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - 15, - std::stoll(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_Renew_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineQueryTest, DISABLED_QuerySuccess_Renew_V15) { int64_t license_renewal_delay = license_.policy().renewal_delay_seconds(); EXPECT_CALL(*mock_clock_, GetCurrentTime()) @@ -2880,11 +1116,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Renew_V15) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 15)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -2919,7 +1156,9 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Renew_V15) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_RenewWithFutureStartTime_V15) { +// TODO(b/256021697): Migrate to v16 or remove this test. +TEST_F(PolicyEngineQueryTest, + DISABLED_QuerySuccess_RenewWithFutureStartTime_V15) { int64_t license_renewal_delay = license_.policy().renewal_delay_seconds(); EXPECT_CALL(*mock_clock_, GetCurrentTime()) @@ -2937,11 +1176,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RenewWithFutureStartTime_V15) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 40)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, false, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -2992,52 +1232,10 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RenewWithFutureStartTime_V15) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineTest, SetLicenseForRelease_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)); - - // No key change event will fire. - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - policy_engine_->SetLicenseForRelease(license_, false); - // No keys were loaded. - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - -TEST_F(PolicyEngineTest, SetLicenseForReleaseAfterSetLicense_V15) { - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); - - policy_engine_->SetLicense(license_, false, false); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - ::testing::Mock::VerifyAndClear(&mock_event_listener_); - - // Set the license again with use_keys set to false. - // This would happen when asking the session to generate a release message - // on an existing session. - ExpectSessionKeysChange(kKeyStatusExpired, false); - policy_engine_->SetLicenseForRelease(license_, false); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); -} - // These test execise license policy when the license service and client // both support OEMCrypto v16 -TEST_F(PolicyEngineTest, PlaybackSuccess_V16) { +TEST_F(PolicyEngineTestV16, PlaybackSuccess_OfflineLicense) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kPlaybackStartTime)) @@ -3049,11 +1247,11 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_V16) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly( - DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(NO_ERROR))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(NO_ERROR)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); @@ -3061,7 +1259,7 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFailed_CanPlayFalse) { License_Policy* policy = license_.mutable_policy(); policy->set_can_play(false); @@ -3074,11 +1272,12 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse_V16) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); policy_engine_->OnTimerEvent(); @@ -3087,8 +1286,8 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, - LicenseExpired_RentalDurationExpiredWithoutPlayback_V16) { +TEST_F(PolicyEngineTestV16, + LicenseExpired_RentalDurationExpiredWithoutPlayback) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -3100,9 +1299,10 @@ TEST_F(PolicyEngineTest, .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3113,7 +1313,7 @@ TEST_F(PolicyEngineTest, ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 3; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3125,8 +1325,8 @@ TEST_F(PolicyEngineTest, } TEST_F( - PolicyEngineTest, - LicenseExpired_RentalDurationExpiredWithoutPlayback_SoftEnforceRentalDuration_V16) { + PolicyEngineTestV16, + LicenseExpired_RentalDurationExpiredWithoutPlayback_SoftEnforceRentalDuration) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -3138,9 +1338,10 @@ TEST_F( .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3151,7 +1352,7 @@ TEST_F( ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 3; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3162,7 +1363,7 @@ TEST_F( EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationPassedWithPlayback_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFails_RentalDurationPassedWithPlayback) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_soft_enforce_rental_duration(false); @@ -3174,9 +1375,10 @@ TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationPassedWithPlayback_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3186,7 +1388,7 @@ TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationPassedWithPlayback_V16) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(2)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3198,9 +1400,8 @@ TEST_F(PolicyEngineTest, PlaybackFails_RentalDurationPassedWithPlayback_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F( - PolicyEngineTest, - PlaybackOk_RentalDurationPassedWithPlayback_SoftEnforceRentalDuration_V16) { +TEST_F(PolicyEngineTestV16, + PlaybackOk_RentalDurationPassedWithPlayback_SoftEnforceRentalDuration) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_soft_enforce_rental_duration(true); @@ -3212,9 +1413,10 @@ TEST_F( .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3225,7 +1427,7 @@ TEST_F( EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(2)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3237,7 +1439,7 @@ TEST_F( EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFails_PlaybackDurationExpired) { const int64_t playback_start_time = kLicenseStartTime + 10000; License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); @@ -3249,9 +1451,10 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired_V16) { .WillOnce(Return(playback_start_time + kPlaybackDuration - 2)) .WillOnce(Return(playback_start_time + kPlaybackDuration + 2)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3263,7 +1466,7 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired_V16) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(2)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3275,8 +1478,8 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, - PlaybackOk_PlaybackDurationExpired_SoftEnforcePlaybackDuration_V16) { +TEST_F(PolicyEngineTestV16, + PlaybackOk_PlaybackDurationExpired_SoftEnforcePlaybackDuration) { int64_t playback_start_time = kLicenseStartTime + 10000; License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); @@ -3288,9 +1491,10 @@ TEST_F(PolicyEngineTest, .WillOnce(Return(playback_start_time + kPlaybackDuration - 2)) .WillOnce(Return(playback_start_time + kPlaybackDuration + 2)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3299,7 +1503,7 @@ TEST_F(PolicyEngineTest, EXPECT_CALL(check_, Call(1)); EXPECT_CALL(check_, Call(2)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3315,7 +1519,7 @@ TEST_F(PolicyEngineTest, // OEMCrypto v16. Rental and Playback durations are used for both streaming and // offline. Verify that License duration expiry does not cause the license // to expire. -TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithoutPlayback_V16) { +TEST_F(PolicyEngineTestV16, LicenseOk_LicenseDurationExpiredWithoutPlayback) { License_Policy* policy = license_.mutable_policy(); policy->set_license_duration_seconds(kLowDuration); policy->set_soft_enforce_rental_duration(false); @@ -3327,9 +1531,10 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithoutPlayback_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3339,7 +1544,7 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithoutPlayback_V16) { EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 3; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3350,7 +1555,7 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithoutPlayback_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithPlayback_V16) { +TEST_F(PolicyEngineTestV16, LicenseOk_LicenseDurationExpiredWithPlayback) { License_Policy* policy = license_.mutable_policy(); policy->set_license_duration_seconds(kLowDuration); policy->set_soft_enforce_rental_duration(false); @@ -3363,9 +1568,10 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithPlayback_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3377,7 +1583,7 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithPlayback_V16) { EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 3; ++i) { @@ -3389,7 +1595,7 @@ TEST_F(PolicyEngineTest, LicenseOk_LicenseDurationExpiredWithPlayback_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFails_ExpiryBeforeRenewalDelay) { License_Policy* policy = license_.mutable_policy(); policy->set_renewal_delay_seconds(kLicenseDuration + 10); policy->set_can_renew(true); @@ -3402,9 +1608,10 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_V16) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3416,7 +1623,7 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_V16) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(2)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3428,7 +1635,7 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, LicenseOk_RentalDuration0_V16) { +TEST_F(PolicyEngineTestV16, LicenseOk_RentalDuration0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(UNLIMITED_DURATION); policy->set_soft_enforce_rental_duration(false); @@ -3440,9 +1647,10 @@ TEST_F(PolicyEngineTest, LicenseOk_RentalDuration0_V16) { .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3451,7 +1659,7 @@ TEST_F(PolicyEngineTest, LicenseOk_RentalDuration0_V16) { EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 3; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3462,7 +1670,7 @@ TEST_F(PolicyEngineTest, LicenseOk_RentalDuration0_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0_V16) { +TEST_F(PolicyEngineTestV16, PlaybackOk_RentalDuration0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(UNLIMITED_DURATION); policy->set_soft_enforce_rental_duration(false); @@ -3475,9 +1683,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0_V16) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 10)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3489,7 +1698,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0_V16) { OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration + 10 + kPlaybackDuration)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 3; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3502,7 +1711,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDuration0_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFails_PlaybackDuration0) { License_Policy* policy = license_.mutable_policy(); policy->set_playback_duration_seconds(UNLIMITED_DURATION); policy->set_soft_enforce_rental_duration(false); @@ -3516,9 +1725,10 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDuration0_V16) { .WillOnce(Return(kLicenseStartTime + kRentalDuration - 2)) .WillOnce(Return(kLicenseStartTime + kRentalDuration + 2)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3530,7 +1740,7 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDuration0_V16) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 4; ++i) { @@ -3542,8 +1752,8 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDuration0_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, - PlaybackOk_PlaybackDuration0_SoftEnforceRentalDuration_V16) { +TEST_F(PolicyEngineTestV16, + PlaybackOk_PlaybackDuration0_SoftEnforceRentalDuration) { License_Policy* policy = license_.mutable_policy(); policy->set_playback_duration_seconds(UNLIMITED_DURATION); policy->set_soft_enforce_rental_duration(true); @@ -3557,9 +1767,10 @@ TEST_F(PolicyEngineTest, .WillOnce(Return(kPlaybackStartTime + kRentalDuration - 2)) .WillOnce(Return(kPlaybackStartTime + kRentalDuration + 2)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3571,7 +1782,7 @@ TEST_F(PolicyEngineTest, EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 4; ++i) { @@ -3583,7 +1794,7 @@ TEST_F(PolicyEngineTest, EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0_V16) { +TEST_F(PolicyEngineTestV16, PlaybackOk_PlaybackAndRental0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(UNLIMITED_DURATION); policy->set_playback_duration_seconds(UNLIMITED_DURATION); @@ -3599,9 +1810,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0_V16) { .WillOnce(Return(kPlaybackStartTime + kRentalDuration - 2)) .WillOnce(Return(kPlaybackStartTime + kRentalDuration + 2)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3611,7 +1823,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0_V16) { EXPECT_CALL(check_, Call(3)); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 4; ++i) { @@ -3623,7 +1835,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime_V16) { +TEST_F(PolicyEngineTestV16, PlaybackOk_LicenseWithFutureStartTime) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -3634,9 +1846,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime_V16) { .WillOnce(Return(kLicenseStartTime)) .WillOnce(Return(kPlaybackStartTime)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsableInFuture, false); @@ -3646,7 +1859,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime_V16) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3658,7 +1871,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse_V16) { +TEST_F(PolicyEngineTestV16, PlaybackFailed_CanRenewFalse) { License_Policy* policy = license_.mutable_policy(); const int64_t license_renewal_delay = GetLicenseRenewalDelay(kPlaybackDuration); @@ -3674,9 +1887,10 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse_V16) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3689,7 +1903,7 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse_V16) { ExpectSessionKeysChange(kKeyStatusExpired, false); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 3; ++i) { @@ -3701,7 +1915,7 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_V16) { +TEST_F(PolicyEngineTestV16, PlaybackOk_RenewSuccess) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); int64_t license_renewal_delay = GetLicenseRenewalDelay(kPlaybackDuration); @@ -3721,9 +1935,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_V16) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 10)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3736,7 +1951,7 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_V16) { EXPECT_CALL(check_, Call(2)); EXPECT_CALL(check_, Call(3)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3760,8 +1975,8 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_V16) { } // TODO(b/161992421): Rewrite after clarifying expected behavior -TEST_F(PolicyEngineTest, - DISABLED_PlaybackOk_RenewSuccess_WithFutureStartTime_V16) { +TEST_F(PolicyEngineTestV16, + DISABLED_PlaybackOk_RenewSuccess_WithFutureStartTime) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); const int64_t license_renewal_delay = @@ -3782,9 +1997,10 @@ TEST_F(PolicyEngineTest, .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 30)) .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 60)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3800,7 +2016,7 @@ TEST_F(PolicyEngineTest, EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); for (int i = 1; i <= 2; ++i) { @@ -3824,7 +2040,7 @@ TEST_F(PolicyEngineTest, EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated_V16) { +TEST_F(PolicyEngineTestV16, LicenseExpired_RenewFailedVersionNotUpdated) { License_Policy* policy = license_.mutable_policy(); policy->set_can_renew(true); int64_t license_renewal_delay = GetLicenseRenewalDelay(kPlaybackDuration); @@ -3839,9 +2055,10 @@ TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated_V16) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40)) .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); @@ -3855,7 +2072,7 @@ TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated_V16) { EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); EXPECT_CALL(check_, Call(4)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); for (int i = 1; i <= 2; ++i) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3880,7 +2097,7 @@ TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated_V16) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicense_V16) { +TEST_F(PolicyEngineTestV16, PlaybackSuccess_EntitlementLicense) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kPlaybackStartTime)) @@ -3892,15 +2109,15 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicense_V16) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly( - DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(NO_ERROR))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(NO_ERROR)))); License::KeyContainer* key = license_.mutable_key(0); key->set_type(License::KeyContainer::ENTITLEMENT); key->set_id(kEntitlementKeyId); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -3914,7 +2131,7 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_EntitlementLicense_V16) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseNotReceived_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseNotReceived) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime)); @@ -3923,20 +2140,20 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseNotReceived_V16) { EXPECT_EQ(0u, query_info.size()); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseStartTimeNotSet_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseStartTimeNotSet) { license_.clear_license_start_time(); EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); EXPECT_EQ(0u, query_info.size()); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -3945,11 +2162,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_V16) { .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kLicenseStartTime + 100)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); @@ -3965,7 +2183,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -3975,11 +2193,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun_V16) { .WillOnce(Return(kLicenseStartTime + 100)) .WillOnce(Return(kLicenseStartTime + 200)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); @@ -4007,7 +2226,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -4019,11 +2238,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun_V16) { .WillOnce(Return(kLicenseStartTime + 150)) .WillOnce(Return(kLicenseStartTime + 200)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); @@ -4056,7 +2276,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_soft_enforce_rental_duration(false); @@ -4066,7 +2286,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4083,7 +2303,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_InitialRentalDurationExpired_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse) { LicenseIdentification* id = license_.mutable_id(); id->set_type(OFFLINE); @@ -4099,11 +2319,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse_V16) { .WillOnce(Return(kLicenseStartTime + 7)) .WillOnce(Return(kLicenseStartTime + 100)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); policy_engine_->OnTimerEvent(); @@ -4125,7 +2346,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -4140,11 +2361,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4168,7 +2390,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired) { License_Policy* policy = license_.mutable_policy(); policy->set_playback_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -4184,11 +2406,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired_V16) { .WillOnce(Return(playback_start_time + 2 + kLowDuration)) .WillOnce(Return(playback_start_time + 5 + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4212,7 +2435,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired_V16) { } TEST_F(PolicyEngineQueryTest, - QuerySuccess_RentalDurationExpired_SoftEnforceRentalDuration_V16) { + QuerySuccess_RentalDurationExpired_SoftEnforceRentalDuration) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -4227,11 +2450,12 @@ TEST_F(PolicyEngineQueryTest, .WillOnce(Return(kLicenseStartTime + 2 + kLowDuration)) .WillOnce(Return(kLicenseStartTime + 5 + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4258,7 +2482,7 @@ TEST_F(PolicyEngineQueryTest, } TEST_F(PolicyEngineQueryTest, - QuerySuccess_PlaybackDurationExpired_SoftEnforcePlaybackDuration_V16) { + QuerySuccess_PlaybackDurationExpired_SoftEnforcePlaybackDuration) { License_Policy* policy = license_.mutable_policy(); policy->set_playback_duration_seconds(kLowDuration); policy->set_license_duration_seconds(kHighDuration); @@ -4273,11 +2497,12 @@ TEST_F(PolicyEngineQueryTest, .WillOnce(Return(kPlaybackStartTime + 2 + kLowDuration)) .WillOnce(Return(kPlaybackStartTime + 5 + kLowDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4302,7 +2527,7 @@ TEST_F(PolicyEngineQueryTest, EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(UNLIMITED_DURATION); policy->set_soft_enforce_rental_duration(false); @@ -4318,11 +2543,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4347,7 +2573,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0) { License_Policy* policy = license_.mutable_policy(); policy->set_playback_duration_seconds(UNLIMITED_DURATION); policy->set_license_duration_seconds(kHighDuration); @@ -4366,11 +2592,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0_V16) { .WillOnce(Return(kLicenseStartTime + kHighDuration + 2)) .WillOnce(Return(kLicenseStartTime + kHighDuration + 5)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4409,7 +2636,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(UNLIMITED_DURATION); policy->set_playback_duration_seconds(UNLIMITED_DURATION); @@ -4426,7 +2653,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0_V16) { .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)); - policy_engine_->SetLicense(license_, true, false); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); @@ -4461,7 +2693,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime_V16) { +TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -4474,11 +2706,12 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime_V16) { .WillOnce(Return(kLicenseStartTime + 10)) .WillOnce(Return(kLicenseStartTime + 25)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->OnTimerEvent(); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4515,7 +2748,7 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime_V16) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineTest, SetLicenseForRelease_V16) { +TEST_F(PolicyEngineTestV16, SetLicenseForRelease) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -4526,12 +2759,12 @@ TEST_F(PolicyEngineTest, SetLicenseForRelease_V16) { // No key change event will fire. EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - policy_engine_->SetLicenseForRelease(license_, false); + policy_engine_->SetLicenseForRelease(license_); // No keys were loaded. EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, SetLicenseForReleaseAfterSetLicense_V16) { +TEST_F(PolicyEngineTestV16, SetLicenseForReleaseAfterSetLicense) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -4547,11 +2780,12 @@ TEST_F(PolicyEngineTest, SetLicenseForReleaseAfterSetLicense_V16) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); - policy_engine_->SetLicense(license_, true, false); + policy_engine_->SetLicense(license_, false); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); @@ -4561,11 +2795,11 @@ TEST_F(PolicyEngineTest, SetLicenseForReleaseAfterSetLicense_V16) { // This would happen when asking the session to generate a release message // on an existing session. ExpectSessionKeysChange(kKeyStatusExpired, false); - policy_engine_->SetLicenseForRelease(license_, false); + policy_engine_->SetLicenseForRelease(license_); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); } -TEST_F(PolicyEngineTest, PlaybackOk_RestoreWithoutPlaybackTimes_V16) { +TEST_F(PolicyEngineTestV16, PlaybackOk_RestoreWithoutPlaybackTimes) { License_Policy* policy = license_.mutable_policy(); policy->set_soft_enforce_rental_duration(false); policy->set_soft_enforce_playback_duration(false); @@ -4575,20 +2809,2359 @@ TEST_F(PolicyEngineTest, PlaybackOk_RestoreWithoutPlaybackTimes_V16) { .WillOnce(Return(kLicenseStartTime + 15)) .WillOnce(Return(kLicenseStartTime + 30)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) - .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), - Return(GET_HDCP_CAPABILITY_FAILED))); + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - policy_engine_->SetLicense(license_, false, true); + policy_engine_->SetLicense(license_, true); policy_engine_->OnTimerEvent(); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); } +// These tests exercise license policy when OEMCrypto supports v18. +// The following scenarios are from the duration-and-renewal doc. +// Verifies correct reporting of events, OnSessionRenewalNeeded, +// OnExpirationUpdate, OnSessionKeysChange. Actual license expiration +// is managed/tested by OEMCrypto. + +// Scenario: Streaming +// Case: 1, 2, 3 and 4 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. Expiration is unaffected when playback begins +// 3. After rental window +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, Streaming_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kThreeHours; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(kDurationUnlimited); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Streaming +// Case: 5 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window expires +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, Streaming_5) { + const int64_t rental_duration = kThreeHours; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(kDurationUnlimited); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Streaming Quick Start +// Case: 1, 2 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is correctly set based on playback duration +// 3. After playback window +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, StreamingQuickStart_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kThirtySeconds; + const int64_t playback_duration = kThreeHours; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Streaming Quick Start +// Case: 3 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is correctly set based on playback duration +// 3. After license is restored +// a. Expiration is correctly set based on playback duration +// b. Usable keys are returned +// 4. After license is restored +// a. Expiration is correctly set based on playback duration +// b. Usable keys are returned +// 5. After playback window is passed +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, StreamingQuickStart_3) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kThirtySeconds; + const int64_t playback_duration = kThreeHours; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 10)); + + uint32_t license_last_decrypt_time = license_decrypt_start_time + 10; + + ExpectSessionKeysChange(kKeyStatusUsable, true, 3); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)) + .Times(3); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + MockClock* mock_clock1(new MockClock()); + EXPECT_CALL(*mock_clock1, GetCurrentTime()) + .WillOnce(Return(license_decrypt_start_time + 600)) + .WillOnce(Return(license_decrypt_start_time + 610)) + .WillOnce(Return(license_decrypt_start_time + 620)); + ResetPolicyEngine(mock_clock1); + + policy_engine_->SetLicense(license_, true); + policy_engine_->RestorePlaybackTimes(license_decrypt_start_time, + license_last_decrypt_time, 0); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + license_last_decrypt_time = license_decrypt_start_time + 620; + + MockClock* mock_clock2(new MockClock()); + EXPECT_CALL(*mock_clock2, GetCurrentTime()) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 30)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 20)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + ResetPolicyEngine(mock_clock2); + + policy_engine_->SetLicense(license_, true); + policy_engine_->RestorePlaybackTimes(license_decrypt_start_time, + license_last_decrypt_time, 0); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Streaming Quick Start +// Case: 4 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window expires +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, StreamingQuickStart_4) { + const int64_t rental_duration = kThirtySeconds; + const int64_t playback_duration = kThreeHours; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard) +// Case: 1, 2, 3, 4 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is correctly set based on playback duration +// 3. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenHardTwoHard_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard) +// Case: 5, 6, 7, 8 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins close to rental window expiration +// a. Expiration is unchanged +// 3. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired +// 4. Before playback window is past +// a. Keys remain expired + +TEST_F(PolicyEngineTestV18, SevenHardTwoHard_5) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = + kLicenseStartTime + rental_duration - playback_duration + kOneDay; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Hard Rental Expiry (Seven Hard Two Hard) +// Case: 9 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenHardTwoHard_9) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft) +// Case: 1, 2, 3 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is unchanged +// 3. After playback window is past +// a. Playback is allowed +// 4. After rental window is past +// a. Keys are expired correctly based on rental duration +// a. Playback is disallowed + +TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft) +// Case: 5, 6, 7, 8 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins close to rental window expiration +// a. Expiration is unchanged +// 3. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired +// 4. Before and after playback window is past +// a. Keys remain expired + +TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_5) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = + kLicenseStartTime + rental_duration - playback_duration + kOneDay; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Playback Expiry (Seven Hard Two Soft) +// Case: 9 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenHardTwoSoft_9) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard) +// Case: 1, 2, 3, 4 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is correctly set based on playback duration +// 3. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard) +// Case: 5, 6, 7, 8 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins close to rental window expiration +// a. Expiration is correctly set based on playback duration +// 3. After rental window is past +// a. Expiration is unaffected +// b. Keys are not reported as expired +// 3. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired +// 4. Before playback window is past +// a. Keys remain expired + +TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_5) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = + kLicenseStartTime + rental_duration - playback_duration + kOneDay; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Rental Expiry (Seven Soft Two Hard) +// Case: 9 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenSoftTwoHard_9) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft) +// Case: 1, 2, 3 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is set to unlimited +// 3. After playback window is past +// a. Playback is allowed +// 4. After rental window is past +// a. Playback is allowed + +TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft) +// Case: 5, 6, 7, 8 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. When playback begins close to rental window expiration +// a. Expiration is correctly set to unlimited +// 3. After rental window is past +// a. Expiration is unaffected +// b. Keys are not reported as expired +// 3. After playback window is past +// a. Expiration is unaffected +// b. Keys are not reported as expired + +TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_5) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = + kLicenseStartTime + rental_duration - playback_duration + kOneDay; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration - 10)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->BeginDecryption(); + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + + policy_engine_->OnTimerEvent(); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: Seven Day/Two Day Soft Expiry (Seven Soft Two Soft) +// Case: 9 +// +// Verifies +// 1. When license is loaded +// a. Expiration is correctly set based on rental duration +// b. Usable keys are returned +// 2. After rental window is past +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, SevenSoftTwoSoft_9) { + const int64_t rental_duration = kSevenDays; + const int64_t playback_duration = kTwoDays; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(false); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(true); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + ExpectSessionKeysChange(kKeyStatusUsable, true); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + policy_engine_->SetLicense(license_, false); + policy_engine_->OnTimerEvent(); + + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); +} + +// Scenario: License with Renewal +// Case: 1, 2, 5, 6 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to unlimited as playback has not begun +// b. Usable keys are returned +// 2. When playback begins Expiration is correctly set based on +// playback duration +// 3. When renewal_delay is exceeded a session renewal event is returned +// 4. When license is renewed, durations have been adjusted but windows +// have not been changed so no event is sent +// 5. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, LicenseWithRenewal_1) { + const int64_t playback_duration = kTwoDays; + const int64_t renewal_delay = kFiveMinutes; + const int64_t renewal_recovery_duration = kTenSeconds; + const int64_t license_decrypt_start_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_rental_duration_seconds(kDurationUnlimited); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(kLicenseStartTime)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + renewal_delay - 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 20)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->BeginDecryption(); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy_engine_->UpdateLicense(license_, false); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + +// Scenario: License with Renewal +// Case: 3, 4 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to unlimited as playback has not begun +// b. Usable keys are returned +// 2. When playback begins Expiration is correctly set based on +// playback duration +// 3. When renewal_delay is exceeded a session renewal event is returned +// 4. When license is renewed, durations have been adjusted but windows +// have not been changed so no event is sent. Keys are still available + +TEST_F(PolicyEngineTestV18, LicenseWithRenewal_3) { + const int64_t playback_duration = kTwoDays; + const int64_t renewal_delay = kFiveMinutes; + const int64_t renewal_recovery_duration = kTenSeconds; + const int64_t license_decrypt_start_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_rental_duration_seconds(kDurationUnlimited); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(kLicenseStartTime)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + renewal_delay - 5)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 5)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + + renewal_recovery_duration + 5)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + + renewal_recovery_duration + 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + + renewal_recovery_duration + 20)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->BeginDecryption(); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(5); + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy_engine_->UpdateLicense(license_, false); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + +// Scenario: Limited duration license (playback starts in rental duration) +// Case: 1, 4, 5 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When playback begins +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned +// 3. When renewal_delay is exceeded a session renewal event is returned +// 4. When license is renewed, durations have been adjusted but windows +// have not been changed so no event is sent +// 5. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, LimitedDurationLicense_1) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 20; + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 2)) + .WillOnce(Return(license_decrypt_start_time + 10)) + .WillOnce(Return(license_decrypt_start_time + 20)) + .WillOnce(Return(license_decrypt_start_time + 30)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + EXPECT_CALL(check_, Call(8)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(9)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->BeginDecryption(); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(9); +} + +// Scenario: Limited duration license (playback starts after rental duration) +// Case: 2 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When playback begins after rental duration expires +// a. License is correctly expired based on rental duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, LimitedDurationLicense_2) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(kLicenseStartTime + rental_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(check_, Call(2)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(3)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); +} + +// Scenario: Limited duration license (playback starts after renewal) +// Case: 6 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal is received durations remain the same and no events are +// returned +// 3. When playback begins +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned + +TEST_F(PolicyEngineTestV18, LimitedDurationLicense_6) { + const int64_t license_load_time = kLicenseStartTime + 10; + const int64_t license_decrypt_start_time = kLicenseStartTime + 60; + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseStart); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly(DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType( + CdmResponseType(GET_HDCP_CAPABILITY_FAILED))))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(3); + + policy_engine_->BeginDecryption(); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(5); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 1S +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. When encrypted playback begins +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1S) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = license_load_time + 20; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 20)) + .WillOnce(Return(license_load_time + playback_duration - 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->BeginDecryption(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 1M +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. When encrypted playback begins after rental duration +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1M) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = license_load_time + 35; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 5)) + .WillOnce(Return(license_load_time + playback_duration - 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->BeginDecryption(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 1L +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. When encrypted playback begins after rental duration +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_1L) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = + license_load_time + renewal_delay + renewal_recovery_duration + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_load_time + renewal_delay + + renewal_recovery_duration - 5)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 5)) + .WillOnce(Return(license_load_time + playback_duration - 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(5); + + policy_engine_->BeginDecryption(); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + +// Scenario: Limited duration license with clear lead +// Case: 2 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. When encrypted playback begins after rental duration +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_2) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration + 30; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, kLicenseStartTime + rental_duration)); + EXPECT_CALL(check_, Call(3)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); +} + +// Scenario: Limited duration license with clear lead +// Case: 3S +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. Encrypted playback begins just inside the rental window +// a. The expiration time is unaffected +// 4. No renewal license is loaded + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3S) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = license_load_time + 20; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 20)) + .WillOnce(Return(license_decrypt_start_time + 30)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->BeginDecryption(); + check_.Call(5); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 3M +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. No renewal license is loaded +// 3. Encrypted playback begins just outside the rental window +// a. The expiration time is unaffected +// 4. No renewal license is loaded + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3M) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = license_load_time + 35; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 5)) + .WillOnce(Return(license_decrypt_start_time + 15)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->BeginDecryption(); + + check_.Call(5); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 3L +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. No renewal license is loaded +// 4. Encrypted playback begins outsdide the rental duration + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_3L) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = + license_load_time + renewal_delay + renewal_recovery_duration + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + renewal_delay + 10)) + .WillOnce(Return(license_load_time + renewal_delay + + renewal_recovery_duration - 5)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 5)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(5); + + policy_engine_->BeginDecryption(); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + check_.Call(7); +} + +// Scenario: Limited duration license with clear lead +// Case: 4, 5 +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to rental duration as playback has not begun +// b. Usable keys are returned +// 2. When renewal_delay is exceeded a session renewal event is returned +// 3. When encrypted playback begins after rental duration +// a. Expiration is correctly set based on playback duration +// b. A session renewal event is returned +// 4. When playback duration is exceeded +// a. Keys are expired + +TEST_F(PolicyEngineTestV18, LimitedDurationLicenseWithClearLead_4) { + const int64_t rental_duration = kFifteenMinutes; + const int64_t playback_duration = kTwoHours; + const int64_t renewal_delay = kFiveSeconds; + const int64_t renewal_recovery_duration = kFortySeconds; + const int64_t license_load_time = kLicenseStartTime + rental_duration - 30; + const int64_t license_decrypt_start_time = license_load_time + 30; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_renew_with_usage(true); + policy->set_rental_duration_seconds(rental_duration); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(true); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseLoad); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(license_load_time)) + .WillOnce(Return(license_load_time + 3)) + .WillOnce(Return(license_load_time + 10)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(license_decrypt_start_time + 10)) + .WillOnce(Return(license_load_time + playback_duration - 10)) + .WillOnce(Return(license_load_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, + OnExpirationUpdate(_, license_load_time + playback_duration)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(check_, Call(7)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->BeginDecryption(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy->set_can_renew(false); + policy->set_renewal_delay_seconds(kTwoHours); + policy_engine_->UpdateLicense(license_, false); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + +// Scenario: License with Renewal +// Case: Timer Base unspecified. +// +// This should be the same bevhavior as license start +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to unlimited as playback has not begun +// b. Usable keys are returned +// 2. When playback begins Expiration is correctly set based on +// playback duration +// 3. When renewal_delay is exceeded a session renewal event is returned +// 4. When license is renewed, durations have been adjusted but windows +// have not been changed so no event is sent +// 5. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, LicensWithRenewal_TimerBaseUnspecified) { + const int64_t playback_duration = kTwoDays; + const int64_t renewal_delay = kFiveMinutes; + const int64_t renewal_recovery_duration = kTenSeconds; + const int64_t license_decrypt_start_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_rental_duration_seconds(kDurationUnlimited); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseUnspecified); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(kLicenseStartTime)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + renewal_delay - 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 20)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->BeginDecryption(); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy_engine_->UpdateLicense(license_, false); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + +// Scenario: License with Renewal +// Case: Timer Base First Decrypt +// +// Verifies +// 1. When license is loaded +// a. Expiration is is set to unlimited as playback has not begun +// b. Usable keys are returned +// 2. When playback begins Expiration is correctly set based on +// playback duration +// 3. When renewal_delay is exceeded a session renewal event is returned +// 4. When license is renewed, durations have been adjusted but windows +// have not been changed so no event is sent +// 5. After playback window is past +// a. License is correctly expired based on playback duration +// b. Keys are reported as expired + +TEST_F(PolicyEngineTestV18, LicensWithRenewal_TimerBaseFirstDecrypt) { + const int64_t playback_duration = kTwoDays; + const int64_t renewal_delay = kFiveMinutes; + const int64_t renewal_recovery_duration = kTenSeconds; + const int64_t license_decrypt_start_time = kLicenseStartTime + 10; + + License_Policy* policy = license_.mutable_policy(); + policy->set_can_renew(true); + policy->set_rental_duration_seconds(kDurationUnlimited); + policy->set_playback_duration_seconds(playback_duration); + policy->set_renewal_delay_seconds(renewal_delay); + policy->set_renewal_recovery_duration_seconds(renewal_recovery_duration); + policy->set_soft_enforce_rental_duration(false); + policy->set_soft_enforce_playback_duration(false); + policy->set_initial_renewal_delay_base(kTimerDelayBaseLicenseFirstDecrypt); + + EXPECT_CALL(*mock_clock_, GetCurrentTime()) + .WillOnce(Return(kLicenseStartTime)) + .WillOnce(Return(license_decrypt_start_time)) + .WillOnce(Return(kLicenseStartTime + renewal_delay - 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 10)) + .WillOnce(Return(kLicenseStartTime + renewal_delay + 20)) + .WillOnce(Return(license_decrypt_start_time + playback_duration - 10)) + .WillOnce(Return(license_decrypt_start_time + playback_duration + 10)); + + EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(CdmResponseType(GET_HDCP_CAPABILITY_FAILED)))); + InSequence s; + EXPECT_CALL(check_, Call(1)); + ExpectSessionKeysChange(kKeyStatusUsable, true); + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); + EXPECT_CALL(check_, Call(2)); + EXPECT_CALL( + mock_event_listener_, + OnExpirationUpdate(_, license_decrypt_start_time + playback_duration)); + EXPECT_CALL(check_, Call(3)); + EXPECT_CALL(check_, Call(4)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(5)); + EXPECT_CALL(check_, Call(6)); + EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)); + EXPECT_CALL(check_, Call(7)); + ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(check_, Call(8)); + + check_.Call(1); + policy_engine_->SetLicense(license_, false); + check_.Call(2); + policy_engine_->BeginDecryption(); + check_.Call(3); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(4); + + policy_engine_->OnTimerEvent(); + check_.Call(5); + + LicenseIdentification* id = license_.mutable_id(); + id->set_version(2); + policy_engine_->UpdateLicense(license_, false); + + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(6); + + policy_engine_->OnTimerEvent(); + EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(7); + + policy_engine_->OnTimerEvent(); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); + check_.Call(8); +} + } // namespace wvcdm diff --git a/core/test/policy_integration_test.cpp b/core/test/policy_integration_test.cpp index 2b626249..2f6f8d1c 100644 --- a/core/test/policy_integration_test.cpp +++ b/core/test/policy_integration_test.cpp @@ -86,7 +86,8 @@ TEST_F(CorePIGTest, OfflineHWSecureRequired) { ASSERT_NO_FATAL_FAILURE(holder.FetchLicense()); ASSERT_NO_FATAL_FAILURE(holder.LoadLicense()); EXPECT_EQ(NO_ERROR, holder.Decrypt(sw_key_id)); - ASSERT_NO_FATAL_FAILURE(holder.FailDecrypt(hw_key_id, DECRYPT_ERROR)); + ASSERT_NO_FATAL_FAILURE( + holder.FailDecrypt(hw_key_id, DECRYPT_ERROR)); // Next, if possible, we try to decrypt to a secure buffer, and verify // success. if (wvoec::global_features.test_secure_buffers) { @@ -101,7 +102,8 @@ TEST_F(CorePIGTest, OfflineHWSecureRequired) { ASSERT_NO_FATAL_FAILURE(holder.OpenSession()); ASSERT_NO_FATAL_FAILURE(holder.ReloadLicense()); EXPECT_EQ(NO_ERROR, holder.Decrypt(sw_key_id)); - ASSERT_NO_FATAL_FAILURE(holder.FailDecrypt(hw_key_id, DECRYPT_ERROR)); + ASSERT_NO_FATAL_FAILURE( + holder.FailDecrypt(hw_key_id, DECRYPT_ERROR)); // Next, if possible, we try to decrypt to a secure buffer, and verify // success. if (wvoec::global_features.test_secure_buffers) { diff --git a/core/test/reboot_test.cpp b/core/test/reboot_test.cpp index 39e208b2..3e5ce5fe 100644 --- a/core/test/reboot_test.cpp +++ b/core/test/reboot_test.cpp @@ -707,16 +707,6 @@ class OfflineLicenseTest : public RebootTest { for (auto key_set : key_set_ids) { cdm_engine_.RemoveOfflineLicense(key_set, kSecurityLevelL1); } - // TODO(b/215230202): Is this necessary? It doesn't seem to work. - std::vector ksids; - std::vector pst; - std::string app_id = ""; - EXPECT_EQ(NO_ERROR, - cdm_engine_.ListUsageIds(app_id, kSecurityLevelL1, &ksids, &pst)); - for (auto k : ksids) { - EXPECT_EQ(NO_ERROR, - cdm_engine_.DeleteUsageRecord(app_id, kSecurityLevelL1, k)); - } } std::vector>> test_case_; diff --git a/core/test/system_id_extractor_unittest.cpp b/core/test/system_id_extractor_unittest.cpp index 93635479..0a66935e 100644 --- a/core/test/system_id_extractor_unittest.cpp +++ b/core/test/system_id_extractor_unittest.cpp @@ -331,7 +331,8 @@ class SystemIdExtractorTest : public WvCdmTestBase { void ExpectProvisioningType(CdmClientTokenType type) { EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false)); EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(type), Return(NO_ERROR))); + .WillOnce( + DoAll(SetArgPointee<1>(type), Return(CdmResponseType(NO_ERROR)))); } void ExpectSet(uint32_t system_id) { @@ -382,7 +383,7 @@ TEST_F(SystemIdExtractorTest, SetSystemIdMetrics) { TEST_F(SystemIdExtractorTest, GetProvisioningMethod_Failed) { EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false)); EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull())) - .WillOnce(Return(UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); auto extractor = CreateExtractor(kLevelDefault); ASSERT_TRUE(extractor); uint32_t system_id; @@ -409,7 +410,8 @@ TEST_F(SystemIdExtractorTest, DrmCertDevice_NullSystemId) { TEST_F(SystemIdExtractorTest, KeyboxDevice_Success) { ExpectProvisioningType(kClientTokenKeybox); EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kKeyboxDataStr), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kKeyboxDataStr), + Return(CdmResponseType(NO_ERROR)))); ExpectSet(kKeyboxSystemId); auto extractor = CreateExtractor(kLevelDefault); ASSERT_TRUE(extractor); @@ -421,7 +423,7 @@ TEST_F(SystemIdExtractorTest, KeyboxDevice_Success) { TEST_F(SystemIdExtractorTest, KeyboxDevice_NeedsOtaKeyboxProvisioning) { ExpectProvisioningType(kClientTokenKeybox); EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull())) - .WillOnce(Return(NEED_PROVISIONING)); + .WillOnce(Return(CdmResponseType(NEED_PROVISIONING))); auto extractor = CreateExtractor(kLevelDefault); ASSERT_TRUE(extractor); uint32_t system_id; @@ -432,7 +434,7 @@ TEST_F(SystemIdExtractorTest, KeyboxDevice_NeedsOtaKeyboxProvisioning) { TEST_F(SystemIdExtractorTest, KeyboxDevice_FailedToGetKeyboxData) { ExpectProvisioningType(kClientTokenKeybox); EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevel3, NotNull())) - .WillOnce(Return(UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); auto extractor = CreateExtractor(kLevel3); ASSERT_TRUE(extractor); uint32_t system_id; @@ -443,7 +445,8 @@ TEST_F(SystemIdExtractorTest, KeyboxDevice_FailedToParse) { const std::string kShortKeyData = "123456"; ExpectProvisioningType(kClientTokenKeybox); EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevel3, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kShortKeyData), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kShortKeyData), + Return(CdmResponseType(NO_ERROR)))); auto extractor = CreateExtractor(kLevel3); ASSERT_TRUE(extractor); uint32_t system_id; @@ -453,7 +456,8 @@ TEST_F(SystemIdExtractorTest, KeyboxDevice_FailedToParse) { TEST_F(SystemIdExtractorTest, OemCertDevice_Success) { ExpectProvisioningType(kClientTokenOemCert); EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevel3, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kOemCertStr), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kOemCertStr), + Return(CdmResponseType(NO_ERROR)))); ExpectSet(kOemCertSystemId); auto extractor = CreateExtractor(kLevel3); ASSERT_TRUE(extractor); @@ -465,7 +469,7 @@ TEST_F(SystemIdExtractorTest, OemCertDevice_Success) { TEST_F(SystemIdExtractorTest, OemCertDevice_FailedToGetCert) { ExpectProvisioningType(kClientTokenOemCert); EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevelDefault, NotNull())) - .WillOnce(Return(UNKNOWN_ERROR)); + .WillOnce(Return(CdmResponseType(UNKNOWN_ERROR))); auto extractor = CreateExtractor(kLevelDefault); ASSERT_TRUE(extractor); uint32_t system_id; @@ -477,7 +481,8 @@ TEST_F(SystemIdExtractorTest, OemCertDevice_FailedToParse) { wvutil::CdmRandom::RandomData(kOemCertStr.size()); ExpectProvisioningType(kClientTokenOemCert); EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevelDefault, NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(kNotACertChain), Return(NO_ERROR))); + .WillOnce(DoAll(SetArgPointee<1>(kNotACertChain), + Return(CdmResponseType(NO_ERROR)))); auto extractor = CreateExtractor(kLevelDefault); ASSERT_TRUE(extractor); uint32_t system_id; diff --git a/core/test/test_base.cpp b/core/test/test_base.cpp index 7baa6694..f5c13e8e 100644 --- a/core/test/test_base.cpp +++ b/core/test/test_base.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -163,24 +164,22 @@ void WvCdmTestBase::StripeBuffer(std::vector* buffer, size_t size, std::string WvCdmTestBase::Aes128CbcEncrypt(std::vector key, const std::vector& clear, - const std::vector iv) { + std::vector iv) { std::vector encrypted(clear.size()); - std::vector iv_mod(iv.begin(), iv.end()); AES_KEY aes_key; AES_set_encrypt_key(&key[0], 128, &aes_key); - AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0], + AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0], AES_ENCRYPT); return std::string(encrypted.begin(), encrypted.end()); } std::string WvCdmTestBase::Aes128CbcDecrypt(std::vector key, const std::vector& clear, - const std::vector iv) { + std::vector iv) { std::vector encrypted(clear.size()); - std::vector iv_mod(iv.begin(), iv.end()); AES_KEY aes_key; AES_set_decrypt_key(&key[0], 128, &aes_key); - AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0], + AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0], AES_DECRYPT); return std::string(encrypted.begin(), encrypted.end()); } @@ -198,15 +197,33 @@ std::string WvCdmTestBase::SignHMAC(const std::string& message, TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics) : CryptoSession(crypto_metrics) { - // The first CryptoSession should have initialized OEMCrypto. This is right - // after that, so we should tell oemcrypto to use a test keybox. - if (session_count() == 1) { + MaybeInstallTestKeybox(); +} + +TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics, + const TestCryptoSessionConfig* config) + : CryptoSession(crypto_metrics), config_(config) { + MaybeInstallTestKeybox(); +} + +void TestCryptoSession::MaybeInstallTestKeybox() { + if (IsTestKeyboxNeeded()) { CryptoSession::SetAllowTestKeybox(true); ReinitializeForTest(); WvCdmTestBase::InstallTestRootOfTrust(); } } +bool TestCryptoSession::IsTestKeyboxNeeded() { + // The first CryptoSession should have initialized OEMCrypto. This is right + // after that. + if (session_count() != 1) return false; + // If config is not available, assume keybox is required. + if (config_ == nullptr) return true; + // Unless disabled, test keybox is required. + return !config_->disable_test_keybox; +} + CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) { CdmResponseType status = CryptoSession::GenerateNonce(nonce); for (int i = 0; status != NO_ERROR; i++) { @@ -215,10 +232,11 @@ CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) { wvutil::TestSleep::Sleep(1); status = CryptoSession::GenerateNonce(nonce); } - return NO_ERROR; + return CdmResponseType(NO_ERROR); } class TestCryptoSessionFactory : public CryptoSessionFactory { + public: CryptoSession* MakeCryptoSession( metrics::CryptoMetrics* crypto_metrics) override { // We need to add extra locking here because we need to make sure that there @@ -228,9 +246,18 @@ class TestCryptoSessionFactory : public CryptoSessionFactory { // InstallTestRootOfTrust is only called in the constructor of the // TestCryptoSession, above. std::unique_lock auto_lock(init_lock_); - return new TestCryptoSession(crypto_metrics); + return new TestCryptoSession(crypto_metrics, &session_config_); } + + void SetDisableTestKeybox(bool disable) { + std::unique_lock auto_lock(init_lock_); + session_config_.disable_test_keybox = disable; + } + + private: std::mutex init_lock_; + // Shared with all TestCryptoSession instances created by this factory. + TestCryptoSessionConfig session_config_; }; void WvCdmTestBase::SetUp() { @@ -250,7 +277,13 @@ void WvCdmTestBase::SetUp() { std::string(test_info->test_case_name()) + "." + test_info->name(); int overwrite = 1; // Set value even if already set. setenv("MODEL_NAME", model_name.c_str(), overwrite); - CryptoSession::SetCryptoSessionFactory(new TestCryptoSessionFactory()); + TestCryptoSessionFactory* factory = new TestCryptoSessionFactory(); + CryptoSession::SetCryptoSessionFactory(factory); + const char* const disable_test_keybox_flag = getenv("DISABLE_TEST_KEYBOX"); + if (disable_test_keybox_flag != nullptr && + strcmp(disable_test_keybox_flag, "yes") == 0) { + factory->SetDisableTestKeybox(true); + } // TODO(fredgc): Add a test version of DeviceFiles. } @@ -291,15 +324,11 @@ void WvCdmTestBase::Provision() { const CdmCertificateType cert_type = kCertificateWidevine; std::unique_ptr file_system(CreateTestFileSystem()); TestCdmEngine cdm_engine(file_system.get(), - std::shared_ptr(new EngineMetrics)); + std::make_shared()); ProvisioningHolder provisioner(&cdm_engine, config_); provisioner.Provision(cert_type, binary_provisioning_); } -// TODO(fredgc): Replace this with a pre-defined DRM certificate. We could do -// that because either the device is using a known test keybox with a known -// device key, or the device is using an OEM certificate, and we can extract -// that certificate from the provisioning request. void WvCdmTestBase::EnsureProvisioned() { CdmSessionId session_id; std::unique_ptr file_system(CreateTestFileSystem()); @@ -307,7 +336,7 @@ void WvCdmTestBase::EnsureProvisioned() { // GenerateKeyRequest will actually load the wrapped private key. // Either may return a NEED_PROVISIONING error, so both have to be checked. TestCdmEngine cdm_engine(file_system.get(), - std::shared_ptr(new EngineMetrics)); + std::make_shared()); CdmResponseType status = cdm_engine.OpenSession(config_.key_system(), nullptr, nullptr, &session_id); CdmAppParameterMap app_parameters; @@ -339,6 +368,36 @@ void WvCdmTestBase::EnsureProvisioned() { ASSERT_EQ(NO_ERROR, cdm_engine.CloseSession(session_id)); } +bool WvCdmTestBase::ExtractSignedMessage(const std::string& response, + std::string* result) { + static const std::string kMessageStart = "\"signedResponse\": \""; + static const std::string kMessageEnd = "\""; + std::string response_string; + size_t start = response.find(kMessageStart); + + if (start == response.npos) { + // Assume serialized protobuf message. + result->assign(response); + } else { + // Assume JSON-wrapped protobuf. + size_t end = response.find(kMessageEnd, start + kMessageStart.length()); + if (end == response.npos) { + LOGE("ExtractSignedMessage cannot locate end substring"); + result->clear(); + return false; + } + size_t result_string_size = end - start - kMessageStart.length(); + result->assign(response, start + kMessageStart.length(), + result_string_size); + } + + if (result->empty()) { + LOGE("ExtractSignedMessage: Response message is empty"); + return false; + } + return true; +} + bool WvCdmTestBase::Initialize(int argc, const char* const argv[], const std::string& extra_help_text) { Properties::Init(); @@ -457,7 +516,13 @@ bool WvCdmTestBase::Initialize(int argc, const char* const argv[], // Figure out which tests are appropriate for OEMCrypto, based on features // supported. wvoec::global_features.Initialize(); - wvoec::global_features.set_cast_receiver(is_cast_receiver); + if (is_cast_receiver) { + // Turn it on if passed in on the command line. Do not turn these tests off + // automtically -- instead, we'll let the caller filter them out if they + // need to. These tests will normally only run if the device claims to + // support being a cast receiver. + wvoec::global_features.set_cast_receiver(is_cast_receiver); + } // If the user requests --no_filter, we don't change the filter, otherwise, we // filter out features that are not supported. if (filter_tests) { diff --git a/core/test/test_base.h b/core/test/test_base.h index ec2056e2..98c3dd4f 100644 --- a/core/test/test_base.h +++ b/core/test/test_base.h @@ -48,19 +48,27 @@ class WvCdmTestBase : public ::testing::Test { // Calls Provision() if not already provisioned. virtual void EnsureProvisioned(); - // Fill a buffer with some nonconstant data of the given size. The first byte - // will be set to to help you find the buffer when debugging. + // Locate the portion of the server's provisioning response message that is + // between the strings jason_start_substr and json_end_substr. Returns the + // string through *result. If the start substring match fails, assume the + // entire string represents a serialized protobuf mesaage and return true with + // the entire string. If the end_substring match fails, return false with an + // empty *result. + bool ExtractSignedMessage(const std::string& response, std::string* result); + + // Fill a buffer with some nonconstant data of the given size. The first + // byte will be set to to help you find the buffer when debugging. static void StripeBuffer(std::vector* buffer, size_t size, uint8_t init); // Helper method for doing cryptography. static std::string Aes128CbcEncrypt(std::vector key, const std::vector& clear, - const std::vector iv); + std::vector iv); // Helper method for doing cryptography. static std::string Aes128CbcDecrypt(std::vector key, const std::vector& clear, - const std::vector iv); + std::vector iv); // Helper method for doing cryptography. static std::string SignHMAC(const std::string& message, const std::vector& key); @@ -104,12 +112,28 @@ class WvCdmTestBaseWithEngine : public WvCdmTestBase { TestCdmEngine cdm_engine_; }; +struct TestCryptoSessionConfig { + // Disables newly created TestCryptoSession instances from installing + // a test keybox. + bool disable_test_keybox = false; +}; + class TestCryptoSession : public CryptoSession { public: explicit TestCryptoSession(metrics::CryptoMetrics* crypto_metrics); + TestCryptoSession(metrics::CryptoMetrics* crypto_metrics, + const TestCryptoSessionConfig* config); // This intercepts nonce flood errors, which is useful for tests that request // many nonces and are not time critical. CdmResponseType GenerateNonce(uint32_t* nonce) override; + + private: + // Called once when TestCryptoSession is constructed. + void MaybeInstallTestKeybox(); + bool IsTestKeyboxNeeded(); + + // An un-owned pointer to the config. + const TestCryptoSessionConfig* const config_ = nullptr; }; // Given a PSSH data structure, this makes a PSSH string for use in diff --git a/core/test/test_printers.cpp b/core/test/test_printers.cpp index 0f167270..b39b4bc4 100644 --- a/core/test/test_printers.cpp +++ b/core/test/test_printers.cpp @@ -7,1030 +7,12 @@ #include "test_printers.h" namespace wvcdm { -void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { - switch (value) { - case NO_ERROR: - *os << "NO_ERROR"; - break; - case UNKNOWN_ERROR: - *os << "UNKNOWN_ERROR"; - break; - // Remaining codes are order alphabetically. - case ADD_KEY_ERROR: - *os << "ADD_KEY_ERROR"; - break; - case ANALOG_OUTPUT_ERROR: - *os << "ANALOG_OUTPUT_ERROR"; - break; - case CANNOT_DECRYPT_ZERO_SAMPLES: - *os << "CANNOT_DECRYPT_ZERO_SAMPLES"; - break; - case CANNOT_DECRYPT_ZERO_SUBSAMPLES: - *os << "CANNOT_DECRYPT_ZERO_SUBSAMPLES"; - break; - case CENC_INIT_DATA_UNAVAILABLE: - *os << "CENC_INIT_DATA_UNAVAILABLE"; - break; - case CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE: - *os << "CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE"; - break; - case CERT_PROVISIONING_GET_KEYBOX_ERROR_1: - *os << "CERT_PROVISIONING_GET_KEYBOX_ERROR_1"; - break; - case CERT_PROVISIONING_INVALID_CERT_TYPE: - *os << "CERT_PROVISIONING_INVALID_CERT_TYPE"; - break; - case CERT_PROVISIONING_NONCE_GENERATION_ERROR: - *os << "CERT_PROVISIONING_NONCE_GENERATION_ERROR"; - break; - case CERT_PROVISIONING_REQUEST_ERROR_1: - *os << "CERT_PROVISIONING_REQUEST_ERROR_1"; - break; - case CERT_PROVISIONING_REQUEST_ERROR_4: - *os << "CERT_PROVISIONING_REQUEST_ERROR_4"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_1: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_1"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_2: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_2"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_3: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_3"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_4: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_4"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_7: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_7"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_8: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_8"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_9: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_9"; - break; - case CERT_PROVISIONING_RESPONSE_ERROR_10: - *os << "CERT_PROVISIONING_RESPONSE_ERROR_10"; - break; - case CLIENT_ID_AES_ENCRYPT_ERROR: - *os << "CLIENT_ID_AES_ENCRYPT_ERROR"; - break; - case CLIENT_ID_AES_INIT_ERROR: - *os << "CLIENT_ID_AES_INIT_ERROR"; - break; - case CLIENT_IDENTIFICATION_TOKEN_ERROR_1: - *os << "CLIENT_IDENTIFICATION_TOKEN_ERROR_1"; - break; - case CLIENT_ID_GENERATE_RANDOM_ERROR: - *os << "CLIENT_ID_GENERATE_RANDOM_ERROR"; - break; - case CLIENT_ID_RSA_ENCRYPT_ERROR: - *os << "CLIENT_ID_RSA_ENCRYPT_ERROR"; - break; - case CLIENT_ID_RSA_INIT_ERROR: - *os << "CLIENT_ID_RSA_INIT_ERROR"; - break; - case CLIENT_TOKEN_NOT_SET: - *os << "CLIENT_TOKEN_NOT_SET"; - break; - case COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR: - *os << "COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR"; - break; - case CORE_MESSAGE_NOT_FOUND: - *os << "CORE_MESSAGE_NOT_FOUND"; - break; - case CREATE_USAGE_ENTRY_UNKNOWN_ERROR: - *os << "CREATE_USAGE_ENTRY_UNKNOWN_ERROR"; - break; - case CREATE_USAGE_TABLE_ERROR: - *os << "CREATE_USAGE_TABLE_ERROR"; - break; - case CRYPTO_SESSION_NOT_INITIALIZED: - *os << "CRYPTO_SESSION_NOT_INITIALIZED"; - break; - case CRYPTO_SESSION_NOT_OPEN: - *os << "CRYPTO_SESSION_NOT_OPEN"; - break; - case DEACTIVATE_USAGE_ENTRY_ERROR: - *os << "DEACTIVATE_USAGE_ENTRY_ERROR"; - break; - case DECRYPT_ERROR: - *os << "DECRYPT_ERROR"; - break; - case DECRYPT_NOT_READY: - *os << "DECRYPT_NOT_READY"; - break; - case DELETE_USAGE_ERROR_1: - *os << "DELETE_USAGE_ERROR_1"; - break; - case DELETE_USAGE_ERROR_2: - *os << "DELETE_USAGE_ERROR_2"; - break; - case DELETE_USAGE_ERROR_3: - *os << "DELETE_USAGE_ERROR_3"; - break; - case DEVICE_CANNOT_REPROVISION: - *os << "DEVICE_CANNOT_REPROVISION"; - break; - case DEVICE_CERTIFICATE_ERROR_1: - *os << "DEVICE_CERTIFICATE_ERROR_1"; - break; - case DEVICE_CERTIFICATE_ERROR_2: - *os << "DEVICE_CERTIFICATE_ERROR_2"; - break; - case DEVICE_CERTIFICATE_ERROR_3: - *os << "DEVICE_CERTIFICATE_ERROR_3"; - break; - case DEVICE_CERTIFICATE_ERROR_4: - *os << "DEVICE_CERTIFICATE_ERROR_4"; - break; - case DEVICE_REVOKED: - *os << "DEVICE_REVOKED"; - break; - case DUPLICATE_SESSION_ID_SPECIFIED: - *os << "DUPLICATE_SESSION_ID_SPECIFIED"; - break; - case EMPTY_KEY_DATA_1: - *os << "EMPTY_KEY_DATA_1"; - break; - case EMPTY_KEY_DATA_2: - *os << "EMPTY_KEY_DATA_2"; - break; - case EMPTY_KEYSET_ID: - *os << "EMPTY_KEYSET_ID"; - break; - case EMPTY_KEYSET_ID_ENG_1: - *os << "EMPTY_KEYSET_ID_ENG_1"; - break; - case EMPTY_KEYSET_ID_ENG_2: - *os << "EMPTY_KEYSET_ID_ENG_2"; - break; - case EMPTY_KEYSET_ID_ENG_3: - *os << "EMPTY_KEYSET_ID_ENG_3"; - break; - case EMPTY_KEYSET_ID_ENG_4: - *os << "EMPTY_KEYSET_ID_ENG_4"; - break; - case EMPTY_LICENSE_RENEWAL: - *os << "EMPTY_LICENSE_RENEWAL"; - break; - case EMPTY_LICENSE_REQUEST: - *os << "EMPTY_LICENSE_REQUEST"; - break; - case EMPTY_LICENSE_REQUEST_2: - *os << "EMPTY_LICENSE_REQUEST_2"; - break; - case EMPTY_LICENSE_REQUEST_3: - *os << "EMPTY_LICENSE_REQUEST_3"; - break; - case EMPTY_LICENSE_RESPONSE_1: - *os << "EMPTY_LICENSE_RESPONSE_1"; - break; - case EMPTY_LICENSE_RESPONSE_2: - *os << "EMPTY_LICENSE_RESPONSE_2"; - break; - case EMPTY_LICENSE_RESPONSE_3: - *os << "EMPTY_LICENSE_RESPONSE_3"; - break; - case EMPTY_LICENSE_RESPONSE_4: - *os << "EMPTY_LICENSE_RESPONSE_4"; - break; - case EMPTY_PROVISIONING_CERTIFICATE_1: - *os << "EMPTY_PROVISIONING_CERTIFICATE_1"; - break; - case EMPTY_PROVISIONING_CERTIFICATE_2: - *os << "EMPTY_PROVISIONING_CERTIFICATE_2"; - break; - case EMPTY_PROVISIONING_RESPONSE: - *os << "EMPTY_PROVISIONING_RESPONSE"; - break; - case EMPTY_RESPONSE_ERROR_1: - *os << "EMPTY_RESPONSE_ERROR_1"; - break; - case EMPTY_SESSION_ID: - *os << "EMPTY_SESSION_ID"; - break; - case EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR: - *os << "EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR"; - break; - case GENERATE_DERIVED_KEYS_ERROR: - *os << "GENERATE_DERIVED_KEYS_ERROR"; - break; - case GENERATE_DERIVED_KEYS_ERROR_2: - *os << "GENERATE_DERIVED_KEYS_ERROR_2"; - break; - case GENERATE_SIGNATURE_ERROR: - *os << "GENERATE_SIGNATURE_ERROR"; - break; - case GENERATE_USAGE_REPORT_ERROR: - *os << "GENERATE_USAGE_REPORT_ERROR"; - break; - case GET_DECRYPT_HASH_ERROR: - *os << "GET_DECRYPT_HASH_ERROR"; - break; - case GET_DEVICE_ID_ERROR: - *os << "GET_DEVICE_ID_ERROR"; - break; - case GET_HDCP_CAPABILITY_FAILED: - *os << "GET_HDCP_CAPABILITY_FAILED"; - break; - case GET_LICENSE_ERROR: - *os << "GET_LICENSE_ERROR"; - break; - case GET_MAX_NUMBER_OF_OPEN_SESSIONS_ERROR: - *os << "GET_MAX_NUMBER_OF_OPEN_SESSIONS_ERROR"; - break; - case GET_NUMBER_OF_OPEN_SESSIONS_ERROR: - *os << "GET_NUMBER_OF_OPEN_SESSIONS_ERROR"; - break; - case GET_OFFLINE_LICENSE_STATE_ERROR_1: - *os << "GET_OFFLINE_LICENSE_STATE_ERROR_1"; - break; - case GET_OFFLINE_LICENSE_STATE_ERROR_2: - *os << "GET_OFFLINE_LICENSE_STATE_ERROR_2"; - break; - case GET_PROVISIONING_METHOD_ERROR: - *os << "GET_PROVISIONING_METHOD_ERROR"; - break; - case GET_RELEASED_LICENSE_ERROR: - *os << "GET_RELEASED_LICENSE_ERROR"; - break; - case GET_SRM_VERSION_ERROR: - *os << "GET_SRM_VERSION_ERROR"; - break; - case GET_TOKEN_FROM_KEYBOX_ERROR: - *os << "GET_TOKEN_FROM_KEYBOX_ERROR"; - break; - case GET_TOKEN_FROM_OEM_CERT_ERROR: - *os << "GET_TOKEN_FROM_OEM_CERT_ERROR"; - break; - case GET_USAGE_INFO_ERROR_1: - *os << "GET_USAGE_INFO_ERROR_1"; - break; - case GET_USAGE_INFO_ERROR_2: - *os << "GET_USAGE_INFO_ERROR_2"; - break; - case GET_USAGE_INFO_ERROR_3: - *os << "GET_USAGE_INFO_ERROR_3"; - break; - case GET_USAGE_INFO_ERROR_4: - *os << "GET_USAGE_INFO_ERROR_4"; - break; - case INCORRECT_CRYPTO_MODE: - *os << "INCORRECT_CRYPTO_MODE"; - break; - case INCORRECT_USAGE_SUPPORT_TYPE_1: - *os << "INCORRECT_USAGE_SUPPORT_TYPE_1"; - break; - case INCORRECT_USAGE_SUPPORT_TYPE_2: - *os << "INCORRECT_USAGE_SUPPORT_TYPE_2"; - break; - case INIT_DATA_NOT_FOUND: - *os << "INIT_DATA_NOT_FOUND"; - break; - case INSUFFICIENT_CRYPTO_RESOURCES: - *os << "INSUFFICIENT_CRYPTO_RESOURCES"; - break; - case INSUFFICIENT_OUTPUT_PROTECTION: - *os << "INSUFFICIENT_OUTPUT_PROTECTION"; - break; - case INVALID_DECRYPT_HASH_FORMAT: - *os << "INVALID_DECRYPT_HASH_FORMAT"; - break; - case INVALID_DECRYPT_PARAMETERS_ENG_1: - *os << "INVALID_DECRYPT_PARAMETERS_ENG_1"; - break; - case INVALID_DECRYPT_PARAMETERS_ENG_2: - *os << "INVALID_DECRYPT_PARAMETERS_ENG_2"; - break; - case INVALID_DECRYPT_PARAMETERS_ENG_3: - *os << "INVALID_DECRYPT_PARAMETERS_ENG_3"; - break; - case INVALID_DECRYPT_PARAMETERS_ENG_4: - *os << "INVALID_DECRYPT_PARAMETERS_ENG_4"; - break; - case INVALID_DEVICE_CERTIFICATE_TYPE: - *os << "INVALID_DEVICE_CERTIFICATE_TYPE"; - break; - case INVALID_IV_SIZE: - *os << "INVALID_IV_SIZE"; - break; - case INVALID_KEY_SYSTEM: - *os << "INVALID_KEY_SYSTEM"; - break; - case INVALID_LICENSE_REQUEST_TYPE_1: - *os << "INVALID_LICENSE_REQUEST_TYPE_1"; - break; - case INVALID_LICENSE_REQUEST_TYPE_2: - *os << "INVALID_LICENSE_REQUEST_TYPE_2"; - break; - case INVALID_LICENSE_RESPONSE: - *os << "INVALID_LICENSE_RESPONSE"; - break; - case INVALID_LICENSE_TYPE: - *os << "INVALID_LICENSE_TYPE"; - break; - case INVALID_LICENSE_TYPE_2: - *os << "INVALID_LICENSE_TYPE_2"; - break; - case INVALID_PARAMETERS_ENG_5: - *os << "INVALID_PARAMETERS_ENG_5"; - break; - case INVALID_PARAMETERS_ENG_13: - *os << "INVALID_PARAMETERS_ENG_13"; - break; - case INVALID_PARAMETERS_ENG_14: - *os << "INVALID_PARAMETERS_ENG_14"; - break; - case INVALID_PARAMETERS_ENG_15: - *os << "INVALID_PARAMETERS_ENG_15"; - break; - case INVALID_PARAMETERS_ENG_16: - *os << "INVALID_PARAMETERS_ENG_16"; - break; - case INVALID_PARAMETERS_ENG_22: - *os << "INVALID_PARAMETERS_ENG_22"; - break; - case INVALID_PARAMETERS_ENG_23: - *os << "INVALID_PARAMETERS_ENG_23"; - break; - case INVALID_PARAMETERS_ENG_24: - *os << "INVALID_PARAMETERS_ENG_24"; - break; - case INVALID_PARAMETERS_LIC_1: - *os << "INVALID_PARAMETERS_LIC_1"; - break; - case INVALID_PARAMETERS_LIC_2: - *os << "INVALID_PARAMETERS_LIC_2"; - break; - case INVALID_PARAMETERS_LIC_3: - *os << "INVALID_PARAMETERS_LIC_3"; - break; - case INVALID_PARAMETERS_LIC_4: - *os << "INVALID_PARAMETERS_LIC_4"; - break; - case INVALID_PARAMETERS_LIC_6: - *os << "INVALID_PARAMETERS_LIC_6"; - break; - case INVALID_PARAMETERS_LIC_7: - *os << "INVALID_PARAMETERS_LIC_7"; - break; - case INVALID_PROVISIONING_PARAMETERS_1: - *os << "INVALID_PROVISIONING_PARAMETERS_1"; - break; - case INVALID_PROVISIONING_PARAMETERS_2: - *os << "INVALID_PROVISIONING_PARAMETERS_2"; - break; - case INVALID_PROVISIONING_REQUEST_PARAM_1: - *os << "INVALID_PROVISIONING_REQUEST_PARAM_1"; - break; - case INVALID_PROVISIONING_REQUEST_PARAM_2: - *os << "INVALID_PROVISIONING_REQUEST_PARAM_2"; - break; - case INVALID_QUERY_KEY: - *os << "INVALID_QUERY_KEY"; - break; - case INVALID_SESSION_1: - *os << "INVALID_SESSION_1"; - break; - case INVALID_SESSION_2: - *os << "INVALID_SESSION_2"; - break; - case INVALID_SESSION_ID: - *os << "INVALID_SESSION_ID"; - break; - case INVALID_SRM_LIST: - *os << "INVALID_SRM_LIST"; - break; - case INVALID_USAGE_ENTRY_NUMBER_MODIFICATION: - *os << "INVALID_USAGE_ENTRY_NUMBER_MODIFICATION"; - break; - case KEY_ADDED: - *os << "KEY_ADDED"; - break; - case KEYBOX_TOKEN_TOO_SHORT: - *os << "KEYBOX_TOKEN_TOO_SHORT"; - break; - case KEY_CANCELED: - *os << "KEY_CANCELED"; - break; - case KEY_CONFLICT_1: - *os << "KEY_CONFLICT_1"; - break; - case KEY_ERROR: - *os << "KEY_ERROR"; - break; - case KEY_MESSAGE: - *os << "KEY_MESSAGE"; - break; - case KEY_NOT_FOUND_1: - *os << "KEY_NOT_FOUND_1"; - break; - case KEY_NOT_FOUND_2: - *os << "KEY_NOT_FOUND_2"; - break; - case KEY_NOT_FOUND_3: - *os << "KEY_NOT_FOUND_3"; - break; - case KEY_NOT_FOUND_4: - *os << "KEY_NOT_FOUND_4"; - break; - case KEY_NOT_FOUND_5: - *os << "KEY_NOT_FOUND_5"; - break; - case KEY_NOT_FOUND_6: - *os << "KEY_NOT_FOUND_6"; - break; - case KEY_NOT_FOUND_IN_SESSION: - *os << "KEY_NOT_FOUND_IN_SESSION"; - break; - case KEY_PROHIBITED_FOR_SECURITY_LEVEL: - *os << "KEY_PROHIBITED_FOR_SECURITY_LEVEL"; - break; - case KEY_REQUEST_ERROR_1: - *os << "KEY_REQUEST_ERROR_1"; - break; - case KEYSET_ID_NOT_FOUND_1: - *os << "KEYSET_ID_NOT_FOUND_1"; - break; - case KEYSET_ID_NOT_FOUND_2: - *os << "KEYSET_ID_NOT_FOUND_2"; - break; - case KEYSET_ID_NOT_FOUND_3: - *os << "KEYSET_ID_NOT_FOUND_3"; - break; - case KEYSET_ID_NOT_FOUND_4: - *os << "KEYSET_ID_NOT_FOUND_4"; - break; - case KEY_SIZE_ERROR_1: - *os << "KEY_SIZE_ERROR_1"; - break; - case KEY_SIZE_ERROR_2: - *os << "KEY_SIZE_ERROR_2"; - break; - case LICENSE_ID_NOT_FOUND: - *os << "LICENSE_ID_NOT_FOUND"; - break; - case LICENSE_PARSER_INIT_ERROR: - *os << "LICENSE_PARSER_INIT_ERROR"; - break; - case LICENSE_PARSER_NOT_INITIALIZED_1: - *os << "LICENSE_PARSER_NOT_INITIALIZED_1"; - break; - case LICENSE_PARSER_NOT_INITIALIZED_2: - *os << "LICENSE_PARSER_NOT_INITIALIZED_2"; - break; - case LICENSE_PARSER_NOT_INITIALIZED_3: - *os << "LICENSE_PARSER_NOT_INITIALIZED_3"; - break; - case LICENSE_PARSER_NOT_INITIALIZED_4: - *os << "LICENSE_PARSER_NOT_INITIALIZED_4"; - break; - case LICENSE_RENEWAL_NONCE_GENERATION_ERROR: - *os << "LICENSE_RENEWAL_NONCE_GENERATION_ERROR"; - break; - case LICENSE_RENEWAL_PROHIBITED: - *os << "LICENSE_RENEWAL_PROHIBITED"; - break; - case LICENSE_REQUEST_NONCE_GENERATION_ERROR: - *os << "LICENSE_REQUEST_NONCE_GENERATION_ERROR"; - break; - case LICENSE_RESPONSE_NOT_SIGNED: - *os << "LICENSE_RESPONSE_NOT_SIGNED"; - break; - case LICENSE_RESPONSE_PARSE_ERROR_1: - *os << "LICENSE_RESPONSE_PARSE_ERROR_1"; - break; - case LICENSE_RESPONSE_PARSE_ERROR_2: - *os << "LICENSE_RESPONSE_PARSE_ERROR_2"; - break; - case LICENSE_RESPONSE_PARSE_ERROR_3: - *os << "LICENSE_RESPONSE_PARSE_ERROR_3"; - break; - case LICENSE_RESPONSE_PARSE_ERROR_4: - *os << "LICENSE_RESPONSE_PARSE_ERROR_4"; - break; - case LICENSE_RESPONSE_PARSE_ERROR_5: - *os << "LICENSE_RESPONSE_PARSE_ERROR_5"; - break; - case LICENSE_USAGE_ENTRY_MISSING: - *os << "LICENSE_USAGE_ENTRY_MISSING"; - break; - case LIST_LICENSE_ERROR_1: - *os << "LIST_LICENSE_ERROR_1"; - break; - case LIST_LICENSE_ERROR_2: - *os << "LIST_LICENSE_ERROR_2"; - break; - case LIST_USAGE_ERROR_1: - *os << "LIST_USAGE_ERROR_1"; - break; - case LIST_USAGE_ERROR_2: - *os << "LIST_USAGE_ERROR_2"; - break; - case LOAD_DEVICE_RSA_KEY_ERROR: - *os << "LOAD_DEVICE_RSA_KEY_ERROR"; - break; - case LOAD_ENTITLED_CONTENT_KEYS_ERROR: - *os << "LOAD_ENTITLED_CONTENT_KEYS_ERROR"; - break; - case LOAD_KEY_ERROR: - *os << "LOAD_KEY_ERROR"; - break; - case LOAD_LICENSE_ERROR: - *os << "LOAD_LICENSE_ERROR"; - break; - case LOAD_PROVISIONING_ERROR: - *os << "LOAD_PROVISIONING_ERROR"; - break; - case LOAD_RENEWAL_ERROR: - *os << "LOAD_RENEWAL_ERROR"; - break; - case LOAD_SRM_ERROR: - *os << "LOAD_SRM_ERROR"; - break; - case LOAD_SYSTEM_ID_ERROR: - *os << "LOAD_SYSTEM_ID_ERROR"; - break; - case LOAD_USAGE_ENTRY_GENERATION_SKEW: - *os << "LOAD_USAGE_ENTRY_GENERATION_SKEW"; - break; - case LOAD_USAGE_ENTRY_INVALID_SESSION: - *os << "LOAD_USAGE_ENTRY_INVALID_SESSION"; - break; - case LOAD_USAGE_ENTRY_SIGNATURE_FAILURE: - *os << "LOAD_USAGE_ENTRY_SIGNATURE_FAILURE"; - break; - case LOAD_USAGE_ENTRY_UNKNOWN_ERROR: - *os << "LOAD_USAGE_ENTRY_UNKNOWN_ERROR"; - break; - case LOAD_USAGE_HEADER_BAD_MAGIC: - *os << "LOAD_USAGE_HEADER_BAD_MAGIC"; - break; - case LOAD_USAGE_HEADER_GENERATION_SKEW: - *os << "LOAD_USAGE_HEADER_GENERATION_SKEW"; - break; - case LOAD_USAGE_HEADER_SIGNATURE_FAILURE: - *os << "LOAD_USAGE_HEADER_SIGNATURE_FAILURE"; - break; - case LOAD_USAGE_HEADER_UNKNOWN_ERROR: - *os << "LOAD_USAGE_HEADER_UNKNOWN_ERROR"; - break; - case MOVE_USAGE_ENTRY_DESTINATION_IN_USE: - *os << "MOVE_USAGE_ENTRY_DESTINATION_IN_USE"; - break; - case MOVE_USAGE_ENTRY_UNKNOWN_ERROR: - *os << "MOVE_USAGE_ENTRY_UNKNOWN_ERROR"; - break; - case NEED_KEY: - *os << "NEED_KEY"; - break; - case NEED_PROVISIONING: - *os << "NEED_PROVISIONING"; - break; - case NO_CONTENT_KEY: - *os << "NO_CONTENT_KEY"; - break; - case NO_CONTENT_KEY_2: - *os << "NO_CONTENT_KEY_2"; - break; - case NO_CONTENT_KEY_3: - *os << "NO_CONTENT_KEY_3"; - break; - case NO_DEVICE_KEY_1: - *os << "NO_DEVICE_KEY_1"; - break; - case NO_MATCHING_ENTITLEMENT_KEY: - *os << "NO_MATCHING_ENTITLEMENT_KEY"; - break; - case NO_SRM_VERSION: - *os << "NO_SRM_VERSION"; - break; - case NONCE_GENERATION_ERROR: - *os << "NONCE_GENERATION_ERROR"; - break; - case NOT_AN_ENTITLEMENT_SESSION: - *os << "NOT_AN_ENTITLEMENT_SESSION"; - break; - case NOT_IMPLEMENTED_ERROR: - *os << "NOT_IMPLEMENTED_ERROR"; - break; - case NOT_INITIALIZED_ERROR: - *os << "NOT_INITIALIZED_ERROR"; - break; - case NO_USAGE_ENTRIES: - *os << "NO_USAGE_ENTRIES"; - break; - case OKP_ALREADY_PROVISIONED: - *os << "OKP_ALREADY_PROVISIONED"; - break; - case OPEN_CRYPTO_SESSION_ERROR: - *os << "OPEN_CRYPTO_SESSION_ERROR"; - break; - case OUTPUT_TOO_LARGE_ERROR: - *os << "OUTPUT_TOO_LARGE_ERROR"; - break; - case PARAMETER_NULL: - *os << "PARAMETER_NULL"; - break; - case PARSE_OKP_RESPONSE_ERROR: - *os << "PARSE_OKP_RESPONSE_ERROR"; - break; - case PARSE_REQUEST_ERROR_1: - *os << "PARSE_REQUEST_ERROR_1"; - break; - case PARSE_REQUEST_ERROR_2: - *os << "PARSE_REQUEST_ERROR_2"; - break; - case PARSE_RESPONSE_ERROR_1: - *os << "PARSE_RESPONSE_ERROR_1"; - break; - case PARSE_RESPONSE_ERROR_2: - *os << "PARSE_RESPONSE_ERROR_2"; - break; - case PARSE_RESPONSE_ERROR_3: - *os << "PARSE_RESPONSE_ERROR_3"; - break; - case PARSE_RESPONSE_ERROR_4: - *os << "PARSE_RESPONSE_ERROR_4"; - break; - case PARSE_SERVICE_CERTIFICATE_ERROR: - *os << "PARSE_SERVICE_CERTIFICATE_ERROR"; - break; - case PREPARE_CENC_CONTENT_ID_FAILED: - *os << "PREPARE_CENC_CONTENT_ID_FAILED"; - break; - case PREPARE_WEBM_CONTENT_ID_FAILED: - *os << "PREPARE_WEBM_CONTENT_ID_FAILED"; - break; - case PRIVACY_MODE_ERROR_1: - *os << "PRIVACY_MODE_ERROR_1"; - break; - case PRIVACY_MODE_ERROR_2: - *os << "PRIVACY_MODE_ERROR_2"; - break; - case PRIVACY_MODE_ERROR_3: - *os << "PRIVACY_MODE_ERROR_3"; - break; - case RANDOM_GENERATION_ERROR: - *os << "RANDOM_GENERATION_ERROR"; - break; - case REFRESH_KEYS_ERROR: - *os << "REFRESH_KEYS_ERROR"; - break; - case REINIT_ERROR: - *os << "REINIT_ERROR"; - break; - case RELEASE_KEY_ERROR: - *os << "RELEASE_KEY_ERROR"; - break; - case RELEASE_KEY_REQUEST_ERROR: - *os << "RELEASE_KEY_REQUEST_ERROR"; - break; - case RELEASE_LICENSE_ERROR_1: - *os << "RELEASE_LICENSE_ERROR_1"; - break; - case RELEASE_LICENSE_ERROR_2: - *os << "RELEASE_LICENSE_ERROR_2"; - break; - case RELEASE_USAGE_INFO_ERROR: - *os << "RELEASE_USAGE_INFO_ERROR"; - break; - case RELEASE_USAGE_INFO_FAILED: - *os << "RELEASE_USAGE_INFO_FAILED"; - break; - case REMOVE_ALL_USAGE_INFO_ERROR_1: - *os << "REMOVE_ALL_USAGE_INFO_ERROR_1"; - break; - case REMOVE_ALL_USAGE_INFO_ERROR_2: - *os << "REMOVE_ALL_USAGE_INFO_ERROR_2"; - break; - case REMOVE_ALL_USAGE_INFO_ERROR_5: - *os << "REMOVE_ALL_USAGE_INFO_ERROR_5"; - break; - case REMOVE_ALL_USAGE_INFO_ERROR_6: - *os << "REMOVE_ALL_USAGE_INFO_ERROR_6"; - break; - case REMOVE_ALL_USAGE_INFO_ERROR_7: - *os << "REMOVE_ALL_USAGE_INFO_ERROR_7"; - break; - case REMOVE_OFFLINE_LICENSE_ERROR_1: - *os << "REMOVE_OFFLINE_LICENSE_ERROR_1"; - break; - case REMOVE_OFFLINE_LICENSE_ERROR_2: - *os << "REMOVE_OFFLINE_LICENSE_ERROR_2"; - break; - case REMOVE_USAGE_INFO_ERROR_1: - *os << "REMOVE_USAGE_INFO_ERROR_1"; - break; - case REMOVE_USAGE_INFO_ERROR_2: - *os << "REMOVE_USAGE_INFO_ERROR_2"; - break; - case REMOVE_USAGE_INFO_ERROR_3: - *os << "REMOVE_USAGE_INFO_ERROR_3"; - break; - case RENEW_KEY_ERROR_1: - *os << "RENEW_KEY_ERROR_1"; - break; - case RENEW_KEY_ERROR_2: - *os << "RENEW_KEY_ERROR_2"; - break; - case RESTORE_OFFLINE_LICENSE_ERROR_2: - *os << "RESTORE_OFFLINE_LICENSE_ERROR_2"; - break; - case REWRAP_DEVICE_RSA_KEY_ERROR: - *os << "REWRAP_DEVICE_RSA_KEY_ERROR"; - break; - case RSA_SIGNATURE_GENERATION_ERROR: - *os << "RSA_SIGNATURE_GENERATION_ERROR"; - break; - case SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH: - *os << "SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH"; - break; - case SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY: - *os << "SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY"; - break; - case SESSION_FILE_HANDLE_INIT_ERROR: - *os << "SESSION_FILE_HANDLE_INIT_ERROR"; - break; - case SESSION_KEYS_NOT_FOUND: - *os << "SESSION_KEYS_NOT_FOUND"; - break; - case SESSION_KEYS_NOT_FOUND_2: - *os << "SESSION_KEYS_NOT_FOUND_2"; - break; - case SESSION_LOST_STATE_ERROR: - *os << "SESSION_LOST_STATE_ERROR"; - break; - case SESSION_NOT_FOUND_1: - *os << "SESSION_NOT_FOUND_1"; - break; - case SESSION_NOT_FOUND_2: - *os << "SESSION_NOT_FOUND_2"; - break; - case SESSION_NOT_FOUND_3: - *os << "SESSION_NOT_FOUND_3"; - break; - case SESSION_NOT_FOUND_4: - *os << "SESSION_NOT_FOUND_4"; - break; - case SESSION_NOT_FOUND_5: - *os << "SESSION_NOT_FOUND_5"; - break; - case SESSION_NOT_FOUND_6: - *os << "SESSION_NOT_FOUND_6"; - break; - case SESSION_NOT_FOUND_7: - *os << "SESSION_NOT_FOUND_7"; - break; - case SESSION_NOT_FOUND_8: - *os << "SESSION_NOT_FOUND_8"; - break; - case SESSION_NOT_FOUND_9: - *os << "SESSION_NOT_FOUND_9"; - break; - case SESSION_NOT_FOUND_10: - *os << "SESSION_NOT_FOUND_10"; - break; - case SESSION_NOT_FOUND_12: - *os << "SESSION_NOT_FOUND_12"; - break; - case SESSION_NOT_FOUND_13: - *os << "SESSION_NOT_FOUND_13"; - break; - case SESSION_NOT_FOUND_14: - *os << "SESSION_NOT_FOUND_14"; - break; - case SESSION_NOT_FOUND_15: - *os << "SESSION_NOT_FOUND_15"; - break; - case SESSION_NOT_FOUND_16: - *os << "SESSION_NOT_FOUND_16"; - break; - case SESSION_NOT_FOUND_18: - *os << "SESSION_NOT_FOUND_18"; - break; - case SESSION_NOT_FOUND_19: - *os << "SESSION_NOT_FOUND_19"; - break; - case SESSION_NOT_FOUND_20: - *os << "SESSION_NOT_FOUND_20"; - break; - case SESSION_NOT_FOUND_21: - *os << "SESSION_NOT_FOUND_21"; - break; - case SESSION_NOT_FOUND_22: - *os << "SESSION_NOT_FOUND_22"; - break; - case SESSION_NOT_FOUND_23: - *os << "SESSION_NOT_FOUND_23"; - break; - case SESSION_NOT_FOUND_FOR_DECRYPT: - *os << "SESSION_NOT_FOUND_FOR_DECRYPT"; - break; - case SET_DECRYPT_HASH_ERROR: - *os << "SET_DECRYPT_HASH_ERROR"; - break; - case SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE: - *os << "SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE"; - break; - case SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR: - *os << "SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR"; - break; - case SIGNATURE_NOT_FOUND: - *os << "SIGNATURE_NOT_FOUND"; - break; - case SIGNATURE_NOT_FOUND_2: - *os << "SIGNATURE_NOT_FOUND_2"; - break; - case STORE_LICENSE_ERROR_1: - *os << "STORE_LICENSE_ERROR_1"; - break; - case STORE_LICENSE_ERROR_2: - *os << "STORE_LICENSE_ERROR_2"; - break; - case STORE_USAGE_INFO_ERROR: - *os << "STORE_USAGE_INFO_ERROR"; - break; - case SYSTEM_INVALIDATED_ERROR: - *os << "SYSTEM_INVALIDATED_ERROR"; - break; - case UNEXPECTED_EMPTY_USAGE_ENTRY: - *os << "UNEXPECTED_EMPTY_USAGE_ENTRY"; - break; - case UNKNOWN_CLIENT_TOKEN_TYPE: - *os << "UNKNOWN_CLIENT_TOKEN_TYPE"; - break; - case UNKNOWN_SELECT_KEY_ERROR_1: - *os << "UNKNOWN_SELECT_KEY_ERROR_1"; - break; - case UNKNOWN_SELECT_KEY_ERROR_2: - *os << "UNKNOWN_SELECT_KEY_ERROR_2"; - break; - case UNPROVISION_ERROR_1: - *os << "UNPROVISION_ERROR_1"; - break; - case UNPROVISION_ERROR_2: - *os << "UNPROVISION_ERROR_2"; - break; - case UNPROVISION_ERROR_3: - *os << "UNPROVISION_ERROR_3"; - break; - case UNPROVISION_ERROR_4: - *os << "UNPROVISION_ERROR_4"; - break; - case UNSUPPORTED_INIT_DATA: - *os << "UNSUPPORTED_INIT_DATA"; - break; - case UNSUPPORTED_INIT_DATA_FORMAT: - *os << "UNSUPPORTED_INIT_DATA_FORMAT"; - break; - case UPDATE_USAGE_ENTRY_UNKNOWN_ERROR: - *os << "UPDATE_USAGE_ENTRY_UNKNOWN_ERROR"; - break; - case USAGE_ENTRY_NUMBER_MISMATCH: - *os << "USAGE_ENTRY_NUMBER_MISMATCH"; - break; - case USAGE_ENTRY_ALREADY_LOADED: - *os << "USAGE_ENTRY_ALREADY_LOADED"; - break; - case USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE: - *os << "USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE"; - break; - case USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED: - *os << "USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED"; - break; - case USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED: - *os << "USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED"; - break; - case USAGE_INFO_NOT_FOUND: - *os << "USAGE_INFO_NOT_FOUND"; - break; - case USAGE_INFORMATION_SUPPORT_FAILED: - *os << "USAGE_INFORMATION_SUPPORT_FAILED"; - break; - case USAGE_INVALID_LOAD_ENTRY: - *os << "USAGE_INVALID_LOAD_ENTRY"; - break; - case USAGE_INVALID_NEW_ENTRY: - *os << "USAGE_INVALID_NEW_ENTRY"; - break; - case USAGE_INVALID_PARAMETERS_1: - *os << "USAGE_INVALID_PARAMETERS_1"; - break; - case USAGE_INVALID_PARAMETERS_2: - *os << "USAGE_INVALID_PARAMETERS_2"; - break; - case USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE: - *os << "USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE"; - break; - case USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED: - *os << "USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED"; - break; - case USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED: - *os << "USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED"; - break; - case USAGE_STORE_LICENSE_FAILED: - *os << "USAGE_STORE_LICENSE_FAILED"; - break; - case USAGE_STORE_USAGE_INFO_FAILED: - *os << "USAGE_STORE_USAGE_INFO_FAILED"; - break; - case USAGE_SUPPORT_GET_API_FAILED: - *os << "USAGE_SUPPORT_GET_API_FAILED"; - break; - case WEBM_INIT_DATA_UNAVAILABLE: - *os << "WEBM_INIT_DATA_UNAVAILABLE"; - break; - case PROVISIONING_NOT_ALLOWED_FOR_ATSC: - *os << "PROVISIONING_NOT_ALLOWED_FOR_ATSC"; - break; - case PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR: - *os << "PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR"; - break; - case GET_BOOT_CERTIFICATE_CHAIN_ERROR: - *os << "GET_BOOT_CERTIFICATE_CHAIN_ERROR"; - break; - case GENERATE_CERTIFICATE_KEY_PAIR_ERROR: - *os << "GENERATE_CERTIFICATE_KEY_PAIR_ERROR"; - break; - case GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR: - *os << "GENERATE_CERTIFICATE_KEY_PAIR_ERROR"; - break; - case LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR: - *os << "GENERATE_CERTIFICATE_KEY_PAIR_ERROR"; - break; - case PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN: - *os << "PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN"; - break; - case PROVISIONING_4_FILE_SYSTEM_IS_NULL: - *os << "PROVISIONING_4_FILE_SYSTEM_IS_NULL"; - break; - case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES: - *os << "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES"; - break; - case PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE: - *os << "PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE"; - break; - case PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS: - *os << "PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS"; - break; - case PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE: - *os << "PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE"; - break; - case PROVISIONING_4_NO_PRIVATE_KEY: - *os << "PROVISIONING_4_NO_PRIVATE_KEY"; - break; - case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2: - *os << "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2"; - break; - case PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE: - *os << "PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE"; - break; - case PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE: - *os << "PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE"; - break; - case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3: - *os << "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3"; - break; - case GET_SIGNATURE_HASH_ALGORITHM_ERROR_1: - *os << "GET_SIGNATURE_HASH_ALGORITHM_ERROR_1"; - break; - case GET_SIGNATURE_HASH_ALGORITHM_ERROR_2: - *os << "GET_SIGNATURE_HASH_ALGORITHM_ERROR_2"; - break; - case GET_SIGNATURE_HASH_ALGORITHM_ERROR_3: - *os << "GET_SIGNATURE_HASH_ALGORITHM_ERROR_3"; - break; - case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1: - *os << "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1"; - break; - case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_2: - *os << "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_2"; - break; - case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3: - *os << "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3"; - break; - case UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4: - *os << "UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4"; - break; - case STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR: - *os << "STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR"; - break; - case STORE_ATSC_LICENSE_ERROR: - *os << "STORE_ATSC_LICENSE_ERROR"; - break; - case SESSION_NOT_FOUND_GENERIC_CRYPTO: - *os << "SESSION_NOT_FOUND_GENERIC_CRYPTO"; - break; - case SESSION_NOT_FOUND_24: - *os << "SESSION_NOT_FOUND_24"; - break; - default: - *os << "Unknown CdmResponseType"; - break; - } +void PrintTo(CdmResponseEnum value, ::std::ostream* os) { + *os << CdmResponseEnumToString(value); +} + +void PrintTo(const CdmResponseType& value, ::std::ostream* os) { + *os << value.ToString(); } void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) { @@ -1088,236 +70,9 @@ void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os) { } void PrintTo(const enum OEMCryptoResult& value, ::std::ostream* os) { - switch (value) { - case OEMCrypto_SUCCESS: - *os << "SUCCESS"; - break; - case OEMCrypto_ERROR_INIT_FAILED: - *os << "INIT_FAILED"; - break; - case OEMCrypto_ERROR_TERMINATE_FAILED: - *os << "TERMINATE_FAILED"; - break; - case OEMCrypto_ERROR_OPEN_FAILURE: - *os << "OPEN_FAILURE"; - break; - case OEMCrypto_ERROR_CLOSE_FAILURE: - *os << "CLOSE_FAILURE"; - break; - case OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED: - *os << "ENTER_SECURE_PLAYBACK_FAILED"; - break; - case OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED: - *os << "EXIT_SECURE_PLAYBACK_FAILED"; - break; - case OEMCrypto_ERROR_SHORT_BUFFER: - *os << "SHORT_BUFFER"; - break; - case OEMCrypto_ERROR_NO_DEVICE_KEY: - *os << "NO_DEVICE_KEY"; - break; - case OEMCrypto_ERROR_NO_ASSET_KEY: - *os << "NO_ASSET_KEY"; - break; - case OEMCrypto_ERROR_KEYBOX_INVALID: - *os << "KEYBOX_INVALID"; - break; - case OEMCrypto_ERROR_NO_KEYDATA: - *os << "NO_KEYDATA"; - break; - case OEMCrypto_ERROR_NO_CW: - *os << "NO_CW"; - break; - case OEMCrypto_ERROR_DECRYPT_FAILED: - *os << "DECRYPT_FAILED"; - break; - case OEMCrypto_ERROR_WRITE_KEYBOX: - *os << "WRITE_KEYBOX"; - break; - case OEMCrypto_ERROR_WRAP_KEYBOX: - *os << "WRAP_KEYBOX"; - break; - case OEMCrypto_ERROR_BAD_MAGIC: - *os << "BAD_MAGIC"; - break; - case OEMCrypto_ERROR_BAD_CRC: - *os << "BAD_CRC"; - break; - case OEMCrypto_ERROR_NO_DEVICEID: - *os << "NO_DEVICEID"; - break; - case OEMCrypto_ERROR_RNG_FAILED: - *os << "RNG_FAILED"; - break; - case OEMCrypto_ERROR_RNG_NOT_SUPPORTED: - *os << "RNG_NOT_SUPPORTED"; - break; - case OEMCrypto_ERROR_SETUP: - *os << "SETUP"; - break; - case OEMCrypto_ERROR_OPEN_SESSION_FAILED: - *os << "OPEN_SESSION_FAILED"; - break; - case OEMCrypto_ERROR_CLOSE_SESSION_FAILED: - *os << "CLOSE_SESSION_FAILED"; - break; - case OEMCrypto_ERROR_INVALID_SESSION: - *os << "INVALID_SESSION"; - break; - case OEMCrypto_ERROR_NOT_IMPLEMENTED: - *os << "NOT_IMPLEMENTED"; - break; - case OEMCrypto_ERROR_NO_CONTENT_KEY: - *os << "NO_CONTENT_KEY"; - break; - case OEMCrypto_ERROR_CONTROL_INVALID: - *os << "CONTROL_INVALID"; - break; - case OEMCrypto_ERROR_UNKNOWN_FAILURE: - *os << "UNKNOWN_FAILURE"; - break; - case OEMCrypto_ERROR_INVALID_CONTEXT: - *os << "INVALID_CONTEXT"; - break; - case OEMCrypto_ERROR_SIGNATURE_FAILURE: - *os << "SIGNATURE_FAILURE"; - break; - case OEMCrypto_ERROR_TOO_MANY_SESSIONS: - *os << "TOO_MANY_SESSIONS"; - break; - case OEMCrypto_ERROR_INVALID_NONCE: - *os << "INVALID_NONCE"; - break; - case OEMCrypto_ERROR_TOO_MANY_KEYS: - *os << "TOO_MANY_KEYS"; - break; - case OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED: - *os << "DEVICE_NOT_RSA_PROVISIONED"; - break; - case OEMCrypto_ERROR_INVALID_RSA_KEY: - *os << "INVALID_RSA_KEY"; - break; - case OEMCrypto_ERROR_KEY_EXPIRED: - *os << "KEY_EXPIRED"; - break; - case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES: - *os << "INSUFFICIENT_RESOURCES"; - break; - case OEMCrypto_ERROR_INSUFFICIENT_HDCP: - *os << "INSUFFICIENT_HDCP"; - break; - case OEMCrypto_ERROR_BUFFER_TOO_LARGE: - *os << "BUFFER_TOO_LARGE"; - break; - case OEMCrypto_WARNING_GENERATION_SKEW: - *os << "OEMCrypto_WARNING_GENERATION_SKEW"; - break; - case OEMCrypto_ERROR_GENERATION_SKEW: - *os << "GENERATION_SKEW"; - break; - case OEMCrypto_LOCAL_DISPLAY_ONLY: - *os << "OEMCrypto_LOCAL_DISPLAY_ONLY"; - break; - case OEMCrypto_ERROR_ANALOG_OUTPUT: - *os << "ANALOG_OUTPUT"; - break; - case OEMCrypto_ERROR_WRONG_PST: - *os << "WRONG_PST"; - break; - case OEMCrypto_ERROR_WRONG_KEYS: - *os << "WRONG_KEYS"; - break; - case OEMCrypto_ERROR_MISSING_MASTER: - *os << "MISSING_MASTER"; - break; - case OEMCrypto_ERROR_LICENSE_INACTIVE: - *os << "LICENSE_INACTIVE"; - break; - case OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE: - *os << "ENTRY_NEEDS_UPDATE"; - break; - case OEMCrypto_ERROR_ENTRY_IN_USE: - *os << "ENTRY_IN_USE"; - break; - case OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE: - *os << "USAGE_TABLE_UNRECOVERABLE"; - break; - case OEMCrypto_KEY_NOT_LOADED: - *os << "OEMCrypto_KEY_NOT_LOADED"; - break; - case OEMCrypto_KEY_NOT_ENTITLED: - *os << "OEMCrypto_KEY_NOT_ENTITLED"; - break; - case OEMCrypto_ERROR_BAD_HASH: - *os << "BAD_HASH"; - break; - case OEMCrypto_ERROR_OUTPUT_TOO_LARGE: - *os << "OUTPUT_TOO_LARGE"; - break; - case OEMCrypto_ERROR_SESSION_LOST_STATE: - *os << "SESSION_LOST_STATE"; - break; - case OEMCrypto_ERROR_SYSTEM_INVALIDATED: - *os << "SYSTEM_INVALIDATED"; - break; - case OEMCrypto_ERROR_LICENSE_RELOAD: - *os << "LICENSE_RELOAD"; - break; - case OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES: - *os << "MULTIPLE_USAGE_ENTRIES"; - break; - case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION: - *os << "MIXED_OUTPUT_PROTECTION"; - break; - case OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION: - *os << "INVALID_ENTITLED_KEY_SESSION"; - break; - case OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING: - *os << "NEEDS_KEYBOX_PROVISIONING"; - break; - case OEMCrypto_ERROR_UNSUPPORTED_CIPHER: - *os << "OEMCrypto_ERROR_UNSUPPORTED_CIPHER"; - break; - case OEMCrypto_ERROR_DVR_FORBIDDEN: - *os << "OEMCrypto_ERROR_DVR_FORBIDDEN"; - break; - case OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE: - *os << "OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE"; - break; - case OEMCrypto_ERROR_INVALID_KEY: - *os << "INVALID_KEY"; - break; - // ODK Values. - case ODK_ERROR_CORE_MESSAGE: - *os << "CORE_MESSAGE"; - break; - case ODK_SET_TIMER: - *os << "SET_TIMER"; - break; - case ODK_DISABLE_TIMER: - *os << "DISABLE_TIMER"; - break; - case ODK_TIMER_EXPIRED: - *os << "TIMER_EXPIRED"; - break; - case ODK_UNSUPPORTED_API: - *os << "UNSUPPORTED_API"; - break; - case ODK_STALE_RENEWAL: - *os << "STALE_RENEWAL"; - break; - // OPK Values. - case OPK_ERROR_INCOMPATIBLE_VERSION: - *os << "INCOMPATIBLE_VERSION"; - break; - case OPK_ERROR_REMOTE_CALL: - *os << "REMOTE_CALL"; - break; - case OPK_ERROR_NO_PERSISTENT_DATA: - *os << "NO_PERSISTENT_DATA"; - break; - } + *os << OemCryptoResultToString(value); } + namespace okp { void PrintTo(const SystemState& state, std::ostream* os) { *os << SystemStateToString(state); diff --git a/core/test/test_printers.h b/core/test/test_printers.h index b51adc8f..174872c7 100644 --- a/core/test/test_printers.h +++ b/core/test/test_printers.h @@ -14,7 +14,8 @@ #include "wv_cdm_types.h" namespace wvcdm { -void PrintTo(const enum CdmResponseType& value, ::std::ostream* os); +void PrintTo(CdmResponseEnum value, ::std::ostream* os); +void PrintTo(const CdmResponseType& value, ::std::ostream* os); void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os); void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os); void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os); diff --git a/core/test/url_request.cpp b/core/test/url_request.cpp index dc81da8d..302816b6 100644 --- a/core/test/url_request.cpp +++ b/core/test/url_request.cpp @@ -171,7 +171,7 @@ bool UrlRequest::GetDebugHeaderFields( // cases of parsing provisioning/license/renewal responses. for (size_t key_pos = find_next(0); key_pos != std::string::npos; key_pos = find_next(key_pos)) { - const size_t end_key_pos = response.find(":", key_pos); + const size_t end_key_pos = response.find(':', key_pos); const size_t end_value_pos = response.find(kCrLf, key_pos); // Skip if the colon cannot be found. Technically possible to find // "X-Google" inside the value of a nother header field. diff --git a/metrics/include/metrics_collections.h b/metrics/include/metrics_collections.h index 230a9494..655d9b13 100644 --- a/metrics/include/metrics_collections.h +++ b/metrics/include/metrics_collections.h @@ -61,7 +61,6 @@ namespace wvcdm { namespace metrics { -namespace { // Short name definitions to ease AttributeHandler definitions. // Internal namespace to help simplify declarations. const int kErrorCodeFieldNumber = @@ -89,7 +88,8 @@ const int kKeyRequestTypeFieldNumber = ::drm_metrics::Attributes::kKeyRequestTypeFieldNumber; const int kLicenseTypeFieldNumber = ::drm_metrics::Attributes::kLicenseTypeFieldNumber; -} // namespace +const int kOemCryptoSignatureHashAlgorithmFieldNumber = + ::drm_metrics::Attributes::kOemCryptoSignatureHashAlgorithmFieldNumber; // The maximum number of completed sessions that can be stored. More than this // will cause some metrics to be discarded. @@ -252,8 +252,6 @@ class CryptoMetrics { EventMetric oemcrypto_rewrap_device_rsa_key_30_; ValueMetric oemcrypto_security_patch_level_; - EventMetric - oemcrypto_select_key_; ValueMetric oemcrypto_usage_table_support_; CounterMetric oemcrypto_update_usage_table_; @@ -299,6 +297,12 @@ class CryptoMetrics { oemcrypto_install_oem_private_key_; ValueMetric oemcrypto_watermarking_support_; ValueMetric oemcrypto_production_readiness_; + EventMetric + oemcrypto_get_key_handle_; + CounterMetric + oemcrypto_get_signature_hash_algorithm_; }; // class CryptoMetrics // This class contains session-scoped metrics. All properties and diff --git a/metrics/include/value_metric.h b/metrics/include/value_metric.h index 315bbe4f..d7113575 100644 --- a/metrics/include/value_metric.h +++ b/metrics/include/value_metric.h @@ -39,8 +39,6 @@ void SetValue(drm_metrics::ValueMetric* value_proto, const T& value); template class ValueMetric { public: - ValueMetric() {} - // Record the value of the metric. void Record(const T& value) { std::unique_lock lock(mutex_); @@ -103,7 +101,7 @@ class ValueMetric { private: enum ValueState { kNone, kHasValue, kHasError }; - T value_; + T value_ = T(); int error_code_ = 0; ValueState state_ = kNone; diff --git a/metrics/src/Android.bp b/metrics/src/Android.bp index 5c01872a..83f3dcd0 100644 --- a/metrics/src/Android.bp +++ b/metrics/src/Android.bp @@ -22,6 +22,7 @@ package { // all of the 'license_kinds' from "vendor_widevine_license" // to get the below license kinds: // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } @@ -65,4 +66,6 @@ cc_library { export_proto_headers: true, type: "full", }, + + min_sdk_version: "UpsideDownCake", } diff --git a/metrics/src/attribute_handler.cpp b/metrics/src/attribute_handler.cpp index a435e0df..0c51d574 100644 --- a/metrics/src/attribute_handler.cpp +++ b/metrics/src/attribute_handler.cpp @@ -20,6 +20,13 @@ template <> void SetAttributeField(const CdmResponseType& cdm_error, drm_metrics::Attributes* attributes) { + attributes->set_error_code(cdm_error.code()); +} + +template <> +void SetAttributeField(const CdmResponseEnum& cdm_error, + drm_metrics::Attributes* attributes) { attributes->set_error_code(cdm_error); } @@ -98,6 +105,15 @@ void SetAttributeFieldset_error_detail(error_detail); } +template <> +void SetAttributeField< + drm_metrics::Attributes::kOemCryptoSignatureHashAlgorithmFieldNumber, + OEMCrypto_SignatureHashAlgorithm>( + const OEMCrypto_SignatureHashAlgorithm& algorithm, + drm_metrics::Attributes* attributes) { + attributes->set_oem_crypto_signature_hash_algorithm(algorithm); +} + template <> void SetAttributeField<0, util::Unused>(const util::Unused&, drm_metrics::Attributes*) { diff --git a/metrics/src/metrics_collections.cpp b/metrics/src/metrics_collections.cpp index a3070576..ee054358 100644 --- a/metrics/src/metrics_collections.cpp +++ b/metrics/src/metrics_collections.cpp @@ -10,10 +10,7 @@ namespace wvcdm { namespace metrics { -using ::drm_metrics::Attributes; using ::drm_metrics::WvCdmMetrics; -using ::google::protobuf::RepeatedPtrField; -using ::wvcdm::metrics::EventMetric; namespace { // Helper struct for comparing session ids. struct CompareSessionIds { @@ -161,8 +158,6 @@ void CryptoMetrics::Serialize( crypto_metrics->mutable_oemcrypto_rewrap_device_rsa_key_30_time_us()); crypto_metrics->set_allocated_oemcrypto_security_patch_level( oemcrypto_security_patch_level_.ToProto()); - oemcrypto_select_key_.ToProto( - crypto_metrics->mutable_oemcrypto_select_key_time_us()); crypto_metrics->set_allocated_oemcrypto_usage_table_support( oemcrypto_usage_table_support_.ToProto()); oemcrypto_update_usage_table_.ToProto( @@ -213,9 +208,13 @@ void CryptoMetrics::Serialize( oemcrypto_watermarking_support_.ToProto()); crypto_metrics->set_allocated_oemcrypto_production_readiness( oemcrypto_production_readiness_.ToProto()); + oemcrypto_get_key_handle_.ToProto( + crypto_metrics->mutable_oemcrypto_get_key_handle_time_us()); + oemcrypto_get_signature_hash_algorithm_.ToProto( + crypto_metrics->mutable_oemcrypto_get_signature_hash_algorithm()); } -SessionMetrics::SessionMetrics() : session_id_(""), completed_(false) {} +SessionMetrics::SessionMetrics() : session_id_(), completed_(false) {} void SessionMetrics::Serialize( WvCdmMetrics::SessionMetrics* session_metrics) const { diff --git a/metrics/src/wv_metrics.proto b/metrics/src/wv_metrics.proto index d899b209..e8e4ffb9 100644 --- a/metrics/src/wv_metrics.proto +++ b/metrics/src/wv_metrics.proto @@ -49,6 +49,9 @@ message Attributes { optional uint32 license_type = 17; // Error detail supplemental to the error_code field. optional int32 error_detail = 18; + // The type of hashing algorithm used in signing with a private key. See + // OEMCrypto_SignatureHashAlgorithm in OEMCryptoCENC.h. + optional uint32 oem_crypto_signature_hash_algorithm = 19; } // The Counter message is used to store a count value with an associated @@ -194,6 +197,8 @@ message WvCdmMetrics { optional ValueMetric oemcrypto_maximum_usage_table_header_size = 84; optional ValueMetric oemcrypto_watermarking_support = 85; optional ValueMetric oemcrypto_production_readiness = 86; + repeated DistributionMetric oemcrypto_get_key_handle_time_us = 87; + repeated CounterMetric oemcrypto_get_signature_hash_algorithm = 88; } // This contains metrics that were captured within a CdmSession. This contains diff --git a/metrics/test/metrics_collections_test.cpp b/metrics/test/metrics_collections_test.cpp index f5c5e646..93833e33 100644 --- a/metrics/test/metrics_collections_test.cpp +++ b/metrics/test/metrics_collections_test.cpp @@ -395,13 +395,16 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { kLevelDefault); crypto_metrics.oemcrypto_security_patch_level_.Record(1.0, 123, kLevelDefault); - crypto_metrics.oemcrypto_select_key_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED); crypto_metrics.oemcrypto_supports_usage_table_.Record( 1.0, OEMCrypto_ERROR_INIT_FAILED, kLevelDefault); crypto_metrics.oemcrypto_update_usage_table_.Record( 1.0, OEMCrypto_ERROR_INIT_FAILED); crypto_metrics.oemcrypto_wrap_keybox_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED); + crypto_metrics.oemcrypto_get_key_handle_.Record(1.0, + OEMCrypto_ERROR_INIT_FAILED); + crypto_metrics.oemcrypto_get_signature_hash_algorithm_.Increment( + OEMCrypto_ERROR_INIT_FAILED, OEMCrypto_SHA1); // Internal OEMCrypto Metrics crypto_metrics.oemcrypto_initialization_mode_.Record( diff --git a/metrics/test/metrics_collections_unittest.cpp b/metrics/test/metrics_collections_unittest.cpp index b3931e60..f0dcbd76 100644 --- a/metrics/test/metrics_collections_unittest.cpp +++ b/metrics/test/metrics_collections_unittest.cpp @@ -31,32 +31,42 @@ TEST_F(EngineMetricsTest, AllEngineMetrics) { EngineMetrics engine_metrics; // Set some values in all of the engine metrics. - engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED, + engine_metrics.cdm_engine_add_key_.Record(1.0, CdmResponseType(KEY_ADDED), kLicenseTypeRelease); - engine_metrics.cdm_engine_close_session_.Increment(NO_ERROR); - engine_metrics.cdm_engine_decrypt_.Record(1.0, NO_ERROR, + engine_metrics.cdm_engine_close_session_.Increment(CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_decrypt_.Record(1.0, CdmResponseType(NO_ERROR), metrics::Pow2Bucket(8)); engine_metrics.cdm_engine_find_session_for_key_.Increment(false); - engine_metrics.cdm_engine_generate_key_request_.Record(1.0, NO_ERROR, - kLicenseTypeRelease); - engine_metrics.cdm_engine_get_provisioning_request_.Record(1.0, NO_ERROR); - engine_metrics.cdm_engine_get_usage_info_.Record(1.0, NO_ERROR, - UNKNOWN_ERROR); - engine_metrics.cdm_engine_handle_provisioning_response_.Record(1.0, NO_ERROR); - engine_metrics.cdm_engine_open_key_set_session_.Increment(NO_ERROR); - engine_metrics.cdm_engine_open_session_.Increment(NO_ERROR); - engine_metrics.cdm_engine_query_key_status_.Record(1.0, NO_ERROR); - engine_metrics.cdm_engine_release_all_usage_info_.Increment(NO_ERROR); - engine_metrics.cdm_engine_release_usage_info_.Increment(NO_ERROR); - engine_metrics.cdm_engine_remove_keys_.Increment(NO_ERROR); - engine_metrics.cdm_engine_restore_key_.Record(1.0, NO_ERROR); - engine_metrics.cdm_engine_unprovision_.Increment(NO_ERROR, kSecurityLevelL1); + engine_metrics.cdm_engine_generate_key_request_.Record( + 1.0, CdmResponseType(NO_ERROR), kLicenseTypeRelease); + engine_metrics.cdm_engine_get_provisioning_request_.Record( + 1.0, CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_get_usage_info_.Record( + 1.0, CdmResponseType(NO_ERROR), UNKNOWN_ERROR); + engine_metrics.cdm_engine_handle_provisioning_response_.Record( + 1.0, CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_open_key_set_session_.Increment( + CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_open_session_.Increment(CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_query_key_status_.Record(1.0, + CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_release_all_usage_info_.Increment( + CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_release_usage_info_.Increment( + CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_remove_keys_.Increment(CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_restore_key_.Record(1.0, CdmResponseType(NO_ERROR)); + engine_metrics.cdm_engine_unprovision_.Increment(CdmResponseType(NO_ERROR), + kSecurityLevelL1); engine_metrics.SetAppPackageName("test package name"); engine_metrics.cdm_engine_cdm_version_.Record("test cdm version"); engine_metrics.cdm_engine_creation_time_millis_.Record(100); - engine_metrics.cdm_engine_get_secure_stop_ids_.Increment(UNKNOWN_ERROR); - engine_metrics.cdm_engine_remove_all_usage_info_.Increment(UNKNOWN_ERROR); - engine_metrics.cdm_engine_remove_usage_info_.Increment(UNKNOWN_ERROR); + engine_metrics.cdm_engine_get_secure_stop_ids_.Increment( + CdmResponseType(UNKNOWN_ERROR)); + engine_metrics.cdm_engine_remove_all_usage_info_.Increment( + CdmResponseType(UNKNOWN_ERROR)); + engine_metrics.cdm_engine_remove_usage_info_.Increment( + CdmResponseType(UNKNOWN_ERROR)); // Also set and serialize the oemcrypto dynamic adapter metrics. OemCryptoDynamicAdapterMetrics adapter_metrics; @@ -110,14 +120,17 @@ TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) { EngineMetrics engine_metrics; // Set some values in some of the engine metrics and some crypto metrics. - engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED, + engine_metrics.cdm_engine_add_key_.Record(1.0, CdmResponseType(KEY_ADDED), kLicenseTypeRelease); - engine_metrics.cdm_engine_close_session_.Increment(UNKNOWN_ERROR); + engine_metrics.cdm_engine_close_session_.Increment( + CdmResponseType(UNKNOWN_ERROR)); CryptoMetrics* crypto_metrics = engine_metrics.GetCryptoMetrics(); - crypto_metrics->crypto_session_get_device_unique_id_.Increment(NO_ERROR); + crypto_metrics->crypto_session_get_device_unique_id_.Increment( + CdmResponseType(NO_ERROR)); crypto_metrics->crypto_session_generic_decrypt_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kEncryptionAlgorithmAesCbc128); WvCdmMetrics actual_metrics; engine_metrics.Serialize(&actual_metrics); @@ -178,10 +191,11 @@ TEST_F(EngineMetricsTest, EngineMetricsWithSessions) { EngineMetrics engine_metrics; // Set a values in an engine metric and in a crypto metric. - engine_metrics.cdm_engine_add_key_.Record(1.0, KEY_ADDED, + engine_metrics.cdm_engine_add_key_.Record(1.0, CdmResponseType(KEY_ADDED), kLicenseTypeRelease); engine_metrics.GetCryptoMetrics() - ->crypto_session_load_certificate_private_key_.Record(2.0, NO_ERROR); + ->crypto_session_load_certificate_private_key_.Record( + 2.0, CdmResponseType(NO_ERROR)); // Create two sessions and record some metrics. std::shared_ptr session_metrics_1 = @@ -192,7 +206,8 @@ TEST_F(EngineMetricsTest, EngineMetricsWithSessions) { session_metrics_2->SetSessionId(kSessionId2); // Record a CryptoMetrics metric in the session. session_metrics_2->GetCryptoMetrics()->crypto_session_generic_decrypt_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kEncryptionAlgorithmAesCbc128); WvCdmMetrics actual_metrics; engine_metrics.Serialize(&actual_metrics); @@ -271,11 +286,13 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) { SessionMetrics session_metrics; session_metrics.SetSessionId(kSessionId1); session_metrics.cdm_session_life_span_.Record(1.0); - session_metrics.cdm_session_renew_key_.Record(1.0, NO_ERROR); + session_metrics.cdm_session_renew_key_.Record(1.0, CdmResponseType(NO_ERROR)); session_metrics.cdm_session_restore_offline_session_.Increment( - NO_ERROR, DeviceFiles::ResponseType::kObjectNotInitialized); + CdmResponseType(NO_ERROR), + DeviceFiles::ResponseType::kObjectNotInitialized); session_metrics.cdm_session_restore_usage_session_.Increment( - NO_ERROR, DeviceFiles::ResponseType::kObjectNotInitialized); + CdmResponseType(NO_ERROR), + DeviceFiles::ResponseType::kObjectNotInitialized); session_metrics.cdm_session_license_request_latency_ms_.Record( 2.0, kKeyRequestTypeInitial); session_metrics.oemcrypto_build_info_.Record("test build info"); @@ -286,7 +303,8 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) { // Record a CryptoMetrics metric in the session. session_metrics.GetCryptoMetrics()->crypto_session_generic_decrypt_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kEncryptionAlgorithmAesCbc128); WvCdmMetrics::SessionMetrics actual; session_metrics.Serialize(&actual); @@ -327,33 +345,45 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { CryptoMetrics crypto_metrics; // Crypto session metrics. - crypto_metrics.crypto_session_delete_all_usage_reports_.Increment(NO_ERROR); + crypto_metrics.crypto_session_delete_all_usage_reports_.Increment( + CdmResponseType(NO_ERROR)); crypto_metrics.crypto_session_delete_multiple_usage_information_.Increment( - NO_ERROR); + CdmResponseType(NO_ERROR)); crypto_metrics.crypto_session_generic_decrypt_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kEncryptionAlgorithmAesCbc128); crypto_metrics.crypto_session_generic_encrypt_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kEncryptionAlgorithmAesCbc128); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kEncryptionAlgorithmAesCbc128); crypto_metrics.crypto_session_generic_sign_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kSigningAlgorithmHmacSha256); crypto_metrics.crypto_session_generic_verify_.Record( - 2.0, NO_ERROR, Pow2Bucket(1025), kSigningAlgorithmHmacSha256); - crypto_metrics.crypto_session_get_device_unique_id_.Increment(NO_ERROR); - crypto_metrics.crypto_session_get_token_.Increment(NO_ERROR); + 2.0, CdmResponseType(NO_ERROR), Pow2Bucket(1025), + kSigningAlgorithmHmacSha256); + crypto_metrics.crypto_session_get_device_unique_id_.Increment( + CdmResponseType(NO_ERROR)); + crypto_metrics.crypto_session_get_token_.Increment(CdmResponseType(NO_ERROR)); crypto_metrics.crypto_session_life_span_.Record(1.0); - crypto_metrics.crypto_session_load_certificate_private_key_.Record(1.0, - NO_ERROR); - crypto_metrics.crypto_session_open_.Record(1.0, NO_ERROR, kLevelDefault); - crypto_metrics.crypto_session_update_usage_information_.Record(1.0, NO_ERROR); + crypto_metrics.crypto_session_load_certificate_private_key_.Record( + 1.0, CdmResponseType(NO_ERROR)); + crypto_metrics.crypto_session_open_.Record(1.0, CdmResponseType(NO_ERROR), + kLevelDefault); + crypto_metrics.crypto_session_update_usage_information_.Record( + 1.0, CdmResponseType(NO_ERROR)); crypto_metrics.crypto_session_usage_information_support_.Record(true); crypto_metrics.crypto_session_security_level_.Record(kSecurityLevelL2); // Usage table header metrics. crypto_metrics.usage_table_header_initial_size_.Record(200); - crypto_metrics.usage_table_header_add_entry_.Increment(UNKNOWN_ERROR); - crypto_metrics.usage_table_header_delete_entry_.Increment(UNKNOWN_ERROR); - crypto_metrics.usage_table_header_update_entry_.Record(2.0, UNKNOWN_ERROR); - crypto_metrics.usage_table_header_load_entry_.Increment(UNKNOWN_ERROR); + crypto_metrics.usage_table_header_add_entry_.Increment( + CdmResponseType(UNKNOWN_ERROR)); + crypto_metrics.usage_table_header_delete_entry_.Increment( + CdmResponseType(UNKNOWN_ERROR)); + crypto_metrics.usage_table_header_update_entry_.Record( + 2.0, CdmResponseType(UNKNOWN_ERROR)); + crypto_metrics.usage_table_header_load_entry_.Increment( + CdmResponseType(UNKNOWN_ERROR)); // Usage table LRU metrics. crypto_metrics.usage_table_header_lru_usage_info_count_.Record(150); crypto_metrics.usage_table_header_lru_offline_license_count_.Record(50); @@ -419,7 +449,6 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { crypto_metrics.oemcrypto_rewrap_device_rsa_key_30_.Record( 1.0, OEMCrypto_ERROR_INIT_FAILED); crypto_metrics.oemcrypto_security_patch_level_.Record(123); - crypto_metrics.oemcrypto_select_key_.Record(1.0, OEMCrypto_ERROR_INIT_FAILED); crypto_metrics.oemcrypto_update_usage_table_.Increment( OEMCrypto_ERROR_INIT_FAILED); crypto_metrics.oemcrypto_create_usage_table_header_.Increment( @@ -446,6 +475,10 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { crypto_metrics.oemcrypto_watermarking_support_.Record( OEMCrypto_WatermarkingAlwaysOn); crypto_metrics.oemcrypto_production_readiness_.Record(OEMCrypto_SUCCESS); + crypto_metrics.oemcrypto_get_key_handle_.Record(1.0, + OEMCrypto_ERROR_INIT_FAILED); + crypto_metrics.oemcrypto_get_signature_hash_algorithm_.Increment( + OEMCrypto_ERROR_INIT_FAILED, OEMCrypto_SHA1); WvCdmMetrics::CryptoMetrics actual; crypto_metrics.Serialize(&actual); @@ -521,7 +554,7 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { EXPECT_GT(actual.oemcrypto_rewrap_device_rsa_key_time_us_size(), 0); EXPECT_GT(actual.oemcrypto_rewrap_device_rsa_key_30_time_us_size(), 0); EXPECT_EQ(123, actual.oemcrypto_security_patch_level().int_value()); - EXPECT_GT(actual.oemcrypto_select_key_time_us_size(), 0); + EXPECT_GT(actual.oemcrypto_get_key_handle_time_us_size(), 0); EXPECT_GT(actual.oemcrypto_update_usage_table_size(), 0); EXPECT_GT(actual.oemcrypto_create_usage_table_header_size(), 0); EXPECT_GT(actual.oemcrypto_load_usage_table_header_size(), 0); @@ -541,6 +574,7 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { actual.oemcrypto_watermarking_support().int_value()); EXPECT_EQ(static_cast(OEMCrypto_SUCCESS), actual.oemcrypto_production_readiness().int_value()); + EXPECT_GT(actual.oemcrypto_get_signature_hash_algorithm_size(), 0); } } // namespace metrics } // namespace wvcdm diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index 018fc2d3..fcfdd3bb 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -3,7 +3,7 @@ // License Agreement. /** - * @mainpage OEMCrypto API v17 + * @mainpage OEMCrypto API v18.2 * * OEMCrypto is the low level library implemented by the OEM to provide key and * content protection, usually in a separate secure memory or process space. The @@ -135,6 +135,13 @@ * The usage table is used to store license usage and allows a persistent * license to be reloaded. * + * @defgroup entitled Entitlement License API + * + * [Entitlement licensing](../../index#entitlement) is a way to provide access + * to content keys that may be stored elsewhere, such as in the content itself. + * This can be used to implement content key rotation without requiring new + * licenses, or access to multiple pieces of content with a single license. + * * @defgroup test_verify Test and Verification API * Functions that are designed to help test OEMCrypto and the device. They are * not used during normal operation. Some functions, like those that test the @@ -376,6 +383,20 @@ typedef enum OEMCryptoCipherMode { OEMCrypto_CipherMode_MaxValue = OEMCrypto_CipherMode_ECB, } OEMCryptoCipherMode; +/** + * This is a list of valid algorithms for OEMCrypto_Generic_* functions. + * Some are valid for encryption/decryption, and some for signing/verifying. + */ +typedef enum OEMCrypto_Algorithm { + OEMCrypto_AES_CBC_128_NO_PADDING = 0, + OEMCrypto_HMAC_SHA256 = 1, + OEMCrypto_Algorithm_MaxValue = 1, +} OEMCrypto_Algorithm; + +/// @} + +/// @addtogroup entitled +/// @{ /** * Contains encrypted content key data for loading into the sessions keytable. * The content key data is encrypted using AES-256-CBC encryption, with PKCS#7 @@ -399,46 +420,6 @@ typedef struct { OEMCryptoCipherMode cipher_mode; } OEMCrypto_EntitledContentKeyObject; -/** - * This is a list of valid algorithms for OEMCrypto_Generic_* functions. - * Some are valid for encryption/decryption, and some for signing/verifying. - */ -typedef enum OEMCrypto_Algorithm { - OEMCrypto_AES_CBC_128_NO_PADDING = 0, - OEMCrypto_HMAC_SHA256 = 1, - OEMCrypto_Algorithm_MaxValue = 1, -} OEMCrypto_Algorithm; - -/// @} - -/// @addtogroup keyladder -/// @{ -/** - * This structure is being deprecated. It is only used for legacy licenses. - * Points to the relevant fields for renewing a content key. The fields are - * extracted from the License Renewal Response message offered to - * OEMCrypto_RefreshKeys(). Each field points to one of the components of - * the key. - - * @param key_id: the unique id of this key. - * @param key_control_iv: the IV for performing AES-128-CBC decryption of the - * key_control field. 16 bytes. - * @param key_control: the key control block. It is encrypted (AES-128-CBC) with - * the content key from the key_data field. 16 bytes. - * - * The key_data is unchanged from the original OEMCrypto_LoadKeys() call. Some - * Key Control Block fields, especially those related to key lifetime, may - * change. - * - * The memory for the OEMCrypto_KeyRefreshObject fields is allocated and freed - * by the caller of OEMCrypto_RefreshKeys(). - */ -typedef struct { - OEMCrypto_Substring key_id; - OEMCrypto_Substring key_control_iv; - OEMCrypto_Substring key_control; -} OEMCrypto_KeyRefreshObject; - /// @} /// @addtogroup usage_table @@ -543,6 +524,16 @@ typedef enum OEMCrypto_WatermarkingSupport { OEMCrypto_WatermarkingAlwaysOn = 3, } OEMCrypto_WatermarkingSupport; +/** + Return value for OEMCrypto_GetSignatureHashAlgorithm(). + */ +typedef enum OEMCrypto_SignatureHashAlgorithm { + OEMCrypto_SHA1 = 0, + OEMCrypto_SHA2_256 = 1, + OEMCrypto_SHA2_384 = 2, + OEMCrypto_SHA2_512 = 3, +} OEMCrypto_SignatureHashAlgorithm; + /** * Flags indicating public/private key types supported. */ @@ -615,10 +606,10 @@ typedef enum OEMCrypto_WatermarkingSupport { #define OEMCrypto_DeriveKeysFromSessionKey _oecc21 #define OEMCrypto_APIVersion _oecc22 #define OEMCrypto_SecurityLevel_V16 _oecc23 -#define OEMCrypto_Generic_Encrypt _oecc24 -#define OEMCrypto_Generic_Decrypt _oecc25 -#define OEMCrypto_Generic_Sign _oecc26 -#define OEMCrypto_Generic_Verify _oecc27 +#define OEMCrypto_Generic_Encrypt_V17 _oecc24 +#define OEMCrypto_Generic_Decrypt_V17 _oecc25 +#define OEMCrypto_Generic_Sign_V17 _oecc26 +#define OEMCrypto_Generic_Verify_V17 _oecc27 #define OEMCrypto_GetHDCPCapability_V9 _oecc28 #define OEMCrypto_SupportsUsageTable _oecc29 #define OEMCrypto_UpdateUsageTable _oecc30 @@ -685,7 +676,7 @@ typedef enum OEMCrypto_WatermarkingSupport { #define OEMCrypto_LoadProvisioning _oecc102 #define OEMCrypto_LoadOEMPrivateKey _oecc103 #define OEMCrypto_GetOEMPublicCertificate _oecc104 -#define OEMCrypto_DecryptCENC _oecc105 +#define OEMCrypto_DecryptCENC_V17 _oecc105 #define OEMCrypto_LoadDRMPrivateKey _oecc107 #define OEMCrypto_MinorAPIVersion _oecc108 #define OEMCrypto_AllocateSecureBuffer _oecc109 @@ -710,6 +701,17 @@ typedef enum OEMCrypto_WatermarkingSupport { #define OEMCrypto_GetDTCP2Capability _oecc128 #define OEMCrypto_GetWatermarkingSupport _oecc129 #define OEMCrypto_GetOEMKeyToken _oecc130 +#define OEMCrypto_GetDeviceInformation _oecc131 +#define OEMCrypto_SetMaxAPIVersion _oecc132 +#define OEMCrypto_GetKeyHandle _oecc133 +#define OEMCrypto_DecryptCENC _oecc134 +#define OEMCrypto_Generic_Encrypt _oecc135 +#define OEMCrypto_Generic_Decrypt _oecc136 +#define OEMCrypto_Generic_Sign _oecc137 +#define OEMCrypto_Generic_Verify _oecc138 +#define OEMCrypto_GetSignatureHashAlgorithm _oecc139 +#define OEMCrypto_EnterTestMode _oecc140 +#define OEMCrypto_GetDeviceSignedCsrPayload _oecc141 // clang-format on /// @addtogroup initcontrol @@ -775,6 +777,30 @@ OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* sandbox_id, */ OEMCryptoResult OEMCrypto_Initialize(void); +/** + * Specify the maximum OEMCrypto API version supported by the CDM layer above + * OEMCrypto. If OEMCrypto can support multiple versions then it must restrict + * itself to this version number. If OEMCrypto only supports one version, then + * it may ignore this function and return + * ERROR_NOT_IMPLEMENTED. OEMCrypto_SetMaxAPIVersion will be called after + * OEMCrypto_Initialize() and before any other functions. + * + * @param[in] max_version: the maximum version of OEMCrypto supported by CDM + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED function not implemented + * @retval other any other error + * + * @threading + * This is an "Initialization and Termination Function" and will not be + * called simultaneously with any other function, as if the CDM holds a write + * lock on the OEMCrypto system. + * + * @version + * This method is new in API version 18. + */ +OEMCryptoResult OEMCrypto_SetMaxAPIVersion(uint32_t max_version); + /** * Closes the crypto operation and releases all related resources. * @@ -923,57 +949,6 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session); */ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); -/** - * This method creates an entitled key session. - * OEMCrypto is required to support at least one entitled key session per - * license. For CAS support, we also require that OEMCrypto support at least - * six entitled key sessions per license. - * - * @param[in] oec_session: handle for the OEMCrypto session to be associated - * with the created entitled key session. - * @param[out] key_session: id of the created entitled key session. - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_TOO_MANY_SESSIONS - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this oec_session. It will not be called simultaneously with - * initialization or usage table functions. It is as if the CDM holds a write - * lock for this session, and a read lock on the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_CreateEntitledKeySession( - OEMCrypto_SESSION oec_session, OEMCrypto_SESSION* key_session); - -/** - * This method which removes an entitled key session. - * - * @param[in] key_session: id of the entitled key session to be removed. - * - * Returns: - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_RemoveEntitledKeySession( - OEMCrypto_SESSION key_session); - /** * Generates three secondary keys, mac_key[server], mac_key[client], and * encrypt_key, for handling signing and content key decryption under the @@ -985,7 +960,7 @@ OEMCryptoResult OEMCrypto_RemoveEntitledKeySession( * the mac_key_context and stores it in the mac_keys -- the first two cycles * generate the mac_key[server] and the second two cycles generate the * mac_key[client]. These two keys will be stored until the next call to - * OEMCrypto_LoadKeys(). The device key from the keybox is used as the key + * OEMCrypto_LoadLicense(). The device key from the keybox is used as the key * for the AES-128-CMAC. * * @param[in] session: handle for the session to be used. @@ -1058,9 +1033,13 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( * ECC private key and the derivation_key. See the document "OEMCrypto * Elliptic Curve Support" for details. * - * Once the enc_key and mac_keys have been generated, all calls to LoadKeys - * or LoadLicense proceed in the same manner for license requests using RSA - * or using a Widevine keybox token. + * Once the enc_key and mac_keys have been generated, all calls to + * OEMCrypto_LoadLicense() proceed in the same manner for license requests using + * RSA or using a Widevine keybox token. + * + * This function is also used to derive keys before processing a Cast + * Certificate provisioning response in OEMCrypto_LoadProvisioning(). + * See [Cast Receiver](../../cast) for more details. * * @verification * If the RSA key's allowed_schemes is not kSign_RSASSA_PSS, then no keys are @@ -1266,14 +1245,14 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest( * for license request signing under the license server protocol for CENC. * * The key used for signing should be the mac_key[client] that was generated - * for this session or loaded for this session by OEMCrypto_LoadKeys(), - * OEMCrypto_LoadLicense(), or OEMCrypto_LoadUsageEntry(). + * for this session or loaded for this session by + * OEMCrypto_LoadLicense() or OEMCrypto_LoadUsageEntry(). * * Refer to the Signing Messages Sent to a Server section above for more * details. * * If a usage entry has been loaded, but keys have not been loaded through - * OEMCrypto_LoadKeys(), then the derived mac keys and the keys in the usage + * OEMCrypto_LoadLicense(), then the derived mac keys and the keys in the usage * entry may be different. In this case, the mac keys specified in the usage * entry should be used. * @@ -1322,253 +1301,6 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( OEMCrypto_SESSION session, uint8_t* message, size_t message_length, size_t* core_message_size, uint8_t* signature, size_t* signature_length); -/** - * Install a set of keys for performing decryption in the current session. - * This function will be deprecated and will only be used for legacy license - * from a license server that does not yet support the v16 interface. - * - * The relevant fields have been extracted from the License Response protocol - * message, but the entire message and associated signature are provided so - * the message can be verified (using HMAC-SHA256 with the derived - * mac_key[server]). If the signature verification fails, ignore all other - * arguments and return OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the - * keys to the session context. - * - * The keys will be decrypted using the current encrypt_key (AES-128-CBC) and - * the IV given in the KeyObject. Each key control block will be decrypted - * using the first 128 bits of the corresponding content key (AES-128-CBC) - * and the IV given in the KeyObject. - * - * If its length is not zero, enc_mac_keys will be used to create new - * mac_keys. After all keys have been decrypted and validated, the new mac_keys - * are decrypted with the current encrypt_key and the offered IV. The new - * mac_keys replaces the current mac_keys for future calls to - * OEMCrypto_RefreshKeys(). The first 256 bits of the mac_keys become the - * mac_key[server] and the following 256 bits of the mac_keys become the - * mac_key[client]. Some servers will pad the encrypted mac keys to 80 bytes. If - * there are more than 64 bytes in the enc_mac_keys string, the remaining bytes - * shall be ignored by OEMCrypto. - * - * The mac_key and encrypt_key were generated and stored by the previous call - * to OEMCrypto_GenerateDerivedKeys() or - * OEMCrypto_DeriveKeysFromSessionKey(). The nonce was generated and stored - * in the session's nonce_values by the previous call to - * OEMCrypto_GenerateNonce(). - * - * This session's elapsed time clock is started at 0. The clock will be used - * in OEMCrypto_DecryptCENC(). - * - * NOTE: The calling software must have previously established the mac_keys - * and encrypt_key with a call to OEMCrypto_DeriveKeysFromSessionKey(). - * - * Refer to the Verification of Messages from a Server section above for more - * details. - * - * If the parameter license_type is OEMCrypto_ContentLicense, then the fields - * key_id and key_data in an OEMCrypto_KeyObject are loaded in to the - * content_key_id and content_key_data fields of the key table entry. In this - * case, entitlement key ids and entitlement key data is left blank. - * - * If the parameter license_type is OEMCrypto_EntitlementLicense, then the - * fields key_id and key_data in an OEMCrypto_KeyObject are loaded in to the - * entitlement_key_id and entitlement_key_data fields of the key table entry. - * In this case, content key ids and content key data will be loaded later - * with a call to OEMCrypto_LoadEntitledContentKeys(). - * - * OEMCrypto may assume that the key_id_length is at most 16. However, - * OEMCrypto shall correctly handle key id lengths from 1 to 16 bytes. - * - * OEMCrypto shall handle at least 20 keys per session. This allows a single - * license to contain separate keys for 3 key rotations (previous interval, - * current interval, next interval) times 4 content keys (audio, SD, HD, UHD) - * plus up to 8 keys for watermarks. - * - * After a call to OEMCrypto_LoadKeys(), oemcrypto should clear the encrypt_key - * for the session. - * - * @verification - * The following checks should be performed. If any check fails, an error is - * returned, and none of the keys are loaded. - * 1. The signature of the message shall be computed, and the API shall - * verify the computed signature matches the signature passed in. If - * not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature - * verification shall use a constant-time algorithm (a signature - * mismatch will always take the same time as a successful comparison). - * 2. If there already is a license loaded into this session, return - * OEMCrypto_ERROR_LICENSE_RELOAD. - * 3. The enc_mac_keys substring must either have zero length, or satisfy - * the range check. I.e. (offset < message_length) && (offset + length - * <= message_length) && (offset <= offset + length), and offset + length - * does not cause an integer overflow. If it does not have zero length, - * then enc_mac_keys_iv must not have zero length, and must also satisfy - * the range check. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. If - * the length is zero, then OEMCrypto may assume that the offset is also - * zero. - * 4. The API shall verify that each substring in each KeyObject points to - * a location in the message. I.e. (offset < message_length) && - * (offset + length <= message_length) && (offset <= offset + length), - * and offset + length does not cause an integer overflow, for each of - * key_id, key_data_iv, key_data, key_control_iv, key_control. If not, - * return OEMCrypto_ERROR_INVALID_CONTEXT. - * 5. Each key's control block, after decryption, shall have a valid - * verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 6. If any key control block has the Nonce_Enabled bit set, that key's - * Nonce field shall match a nonce in the cache. If not, return - * OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that - * nonce from the cache. Note that all the key control blocks in a - * particular call shall have the same nonce value. - * 7. If any key control block has the Require_AntiRollback_Hardware bit - * set, and the device does not protect the usage table from rollback, - * then do not load the keys and return OEMCrypto_ERROR_UNKNOWN_FAILURE. - * 8. If the key control block has a nonzero Replay_Control, then the - * verification described below is also performed. - * 9. If the key control block has the bit SRMVersionRequired is set, then - * the verification described below is also performed. If the SRM - * requirement is not met, then the key control block's HDCP_Version - * will be changed to 0xF - local display only. - * 10. If key_array_length == 0, then return - * OEMCrypto_ERROR_INVALID_CONTEXT. - * 11. If this session is associated with a usage table entry, and that - * entry is marked as "inactive" (either kInactiveUsed or - * kInactiveUnused), then the keys are not loaded, and the error - * OEMCrypto_ERROR_LICENSE_INACTIVE is returned. - * 12. The data in enc_mac_keys_iv is not identical to the 16 bytes before - * enc_mac_keys. If it is, return OEMCrypto_ERROR_INVALID_CONTEXT. - * Usage Table and Provider Session Token (pst) - * If a key control block has a nonzero value for Replay_Control, then all - * keys in this license will have the same value for Replay_Control. In this - * case, the following additional checks are performed. - * - The substring pst must have nonzero length and must satisfy the range - * check described above. If not, return - * OEMCrypto_ERROR_INVALID_CONTEXT. - * - The session must be associated with a usage table entry, either - * created via OEMCrypto_CreateNewUsageEntry() or loaded via - * OEMCrypto_LoadUsageEntry(). - * - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a - * nonce check as described above. OEMCrypto will verify that the - * usage entry is newly created with OEMCrypto_CreateNewUsageEntry(). If - * an existing entry was reloaded, an error - * OEMCrypto_ERROR_INVALID_CONTEXT is returned and no keys are loaded. - * OEMCrypto will then copy the pst and the mac keys to the usage entry, - * and set the status to Unused. This Replay_Control prevents the - * license from being loaded more than once, and will be used for online - * streaming. - * - If Replay_Control is 2 = "Require existing Session Usage table entry - * or Nonce", then OEMCrypto will behave slightly differently on the - * first call to LoadKeys for this license. - * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry() - * for this session, then OEMCrypto will verify the nonce for each - * key. OEMCrypto will copy the pst and mac keys to the usage - * entry. The license received time of the entry will be updated - * to the current time, and the status will be set to Unused. - * * If the usage entry was loaded with OEMCrypto_LoadUsageEntry() for - * this session, then OEMCrypto will NOT verify the nonce for each - * key. Instead, it will verify that the pst passed in matches - * that in the entry. Also, the entry's mac keys will be verified - * against the current session's mac keys. This allows an offline - * license to be reloaded but maintain continuity of the playback - * times from one session to the next. - * * If the nonce is not valid and a usage entry was not loaded, the - * return error is OEMCrypto_ERROR_INVALID_NONCE. - * * If the loaded usage entry has a pst that does not match, - * OEMCrypto returns the error OEMCrypto_ERROR_WRONG_PST. - * * If the loaded usage entry has mac keys that do not match the - * license, OEMCrypto returns the error OEMCrypto_ERROR_WRONG_KEYS. - * Note: If LoadKeys updates the mac keys, then the new updated mac keys will - * be used with the Usage Entry -- i.e. the new keys are stored in the - * usage table when creating a new entry, or the new keys are verified - * against those in the usage table if there is an existing entry. If - * LoadKeys does not update the mac keys, the existing session mac keys are - * used. - * - * Sessions that are associated with an entry will need to be able to update - * and verify the status of the entry, and the time stamps in the entry. - * - * Devices that do not support the Usage Table will return - * OEMCrypto_ERROR_INVALID_CONTEXT if the Replay_Control is nonzero. - * - * Timer Update - * After verification, the session's clock and timer values are updated by - * calling the function ODK_InitializeV15Values as described in the document - * "Widevine Core Message Serialization". - * - * SRM Restriction Data - * - * If any key control block has the flag SRMVersionRequired set, then the - * following verification is also performed. - * - * 1. The substring srm_restriction_data must have nonzero length and must - * satisfy the range check described above. If not, return - * OEMCrypto_ERROR_INVALID_CONTEXT. - * 2. The first 8 bytes of srm_restriction_data must match the string - * "HDCPDATA". If not, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 3. The next 4 bytes of srm_restriction_data will be converted from - * network byte order. If the current SRM installed on the device has a - * version number less than this, then the SRM requirement is not met. - * If the device does not support SRM files, or OEMCrypto cannot - * determine the current SRM version number, then the SRM requirement is - * not met. - * Note: if the current SRM version requirement is not met, LoadKeys will - * still succeed and the keys will be loaded. However, those keys with the - * SRMVersionRequired bit set will have their HDCP_Version increased to 0xF - - * local display only. Any future call to SelectKey for these keys while - * there is an external display will return OEMCrypto_ERROR_INSUFFICIENT_HDCP - * at that time. - * - * @param[in] session: crypto session identifier. - * @param[in] message: pointer to memory containing message to be verified. - * @param[in] message_length: length of the message, in bytes. - * @param[in] signature: pointer to memory containing the signature. - * @param[in] signature_length: length of the signature, in bytes. - * @param[in] enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits. - * @param[in] enc_mac_keys: encrypted mac_keys for generating new mac_keys. - * Size is 512 bits. - * @param[in] key_array_length: number of keys present. - * @param[in] key_array: set of keys to be installed. - * @param[in] pst: the Provider Session Token. - * @param[in] srm_restriction_data: optional data specifying the minimum SRM - * version. - * @param[in] license_type: specifies if the license contains content keys or - * entitlement keys. - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NO_DEVICE_KEY - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_SIGNATURE_FAILURE - * @retval OEMCrypto_ERROR_INVALID_NONCE - * @retval OEMCrypto_ERROR_TOO_MANY_KEYS - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE - * @retval OEMCrypto_ERROR_SESSION_LOST_STATE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED - * @retval OEMCrypto_ERROR_LICENSE_RELOAD - * - * @buffer_size - * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier(). - * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is - * larger than the supported size. - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method changed in API version 16. - */ -OEMCryptoResult OEMCrypto_LoadKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, - OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, - size_t key_array_length, const OEMCrypto_KeyObject* key_array, - OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, - OEMCrypto_LicenseType license_type); - /** * Install a set of keys for performing decryption in the current session. * @@ -1679,6 +1411,10 @@ OEMCryptoResult OEMCrypto_LoadKeys( * OEMCrypto_ERROR_LICENSE_INACTIVE is returned. * 24. The data in enc_mac_keys_iv is not identical to the 16 bytes before * enc_mac_keys. If it is, return OEMCrypto_ERROR_INVALID_CONTEXT. + * 25. IF ODK_ParseLicense returns ODK_TIMER_EXPIRED, return + * OEMCrypto_ERROR_KEY_EXPIRED. If ODK_ParseLicense returns ODK_SET_TIMER + * or ODK_DISABLE_TIMER, the playback timer has started and OEMCrypto + * should treat this as if a Decrypt call has been made. * * Usage Table and Provider Session Token (pst) * The function ODK_ParseLicense takes several parameters that may need more @@ -1726,7 +1462,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * more than once, and will be used for online streaming. * - If Replay_Control is 2 = "Require existing Session Usage table entry * or Nonce", then OEMCrypto will behave slightly differently on the - * first call to LoadKeys for this license. + * first call to LoadLicense for this license. * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry() * for this session, then OEMCrypto will verify the nonce for each * key. OEMCrypto will copy the pst and mac keys to the usage @@ -1745,11 +1481,11 @@ OEMCryptoResult OEMCrypto_LoadKeys( * OEMCrypto returns the error OEMCrypto_ERROR_WRONG_PST. * * If the loaded usage entry has mac keys that do not match the * license, OEMCrypto returns the error OEMCrypto_ERROR_WRONG_KEYS. - * Note: If LoadKeys updates the mac keys, then the new updated mac keys will + * Note: If LoadLicense updates the mac keys, then the new updated mac keys will * be used with the Usage Entry -- i.e. the new keys are stored in the * usage table when creating a new entry, or the new keys are verified * against those in the usage table if there is an existing entry. If - * LoadKeys does not update the mac keys, the existing session mac keys are + * LoadLicense does not update the mac keys, the existing session mac keys are * used. * Sessions that are associated with an entry will need to be able to update * and verify the status of the entry, and the time stamps in the entry. @@ -1769,7 +1505,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * If the device does not support SRM files, or OEMCrypto cannot * determine the current SRM version number, then the SRM requirement is * not met. - * Note: if the current SRM version requirement is not met, LoadKeys will + * Note: if the current SRM version requirement is not met, LoadLicense will * still succeed and the keys will be loaded. However, those keys with the * SRMVersionRequired bit set will have their HDCP_Version increased to 0xF - * local display only. Any future call to SelectKey for these keys while @@ -1797,6 +1533,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * @retval OEMCrypto_ERROR_SESSION_LOST_STATE * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED * @retval OEMCrypto_ERROR_LICENSE_RELOAD + * @retval OEMCrypto_ERROR_KEY_EXPIRED * * @buffer_size * OEMCrypto shall support message sizes as described in the section @@ -1821,6 +1558,194 @@ OEMCryptoResult OEMCrypto_LoadLicense(OEMCrypto_SESSION session, const uint8_t* signature, size_t signature_length); +/** + * Updates the clock values and resets the renewal timer for the current + * session. + * + * OEMCrypto shall verify the signature of the entire message using the + * session's renewal mac key for the server. The entire message is the buffer + * starting at message with length message_length. If the signature does not + * match, OEMCrypto returns OEMCrypto_ERROR_SIGNATURE_FAILURE. + * + * OEMCrypto shall verify that nonce_values.api_major_version is 16. If not, + * return the error OEMCrypto_ERROR_INVALID_CONTEXT. + * + * If the signature passes, OEMCrypto shall use the function + * ODK_ParseRenewal, as described in the document "Widevine Core Message + * Serialization" to parse and verify the message. If ODK_ParseRenewal + * returns an error OEMCrypto returns the error to the CDM layer. + * + * The function ODK_ParseRenewal updates the clock values for the session, + * and may return ODK_SET_TIMER, ODK_DISABLE_TIMER or ODK_TIMER_EXPIRED on + * success. These values shall be handled by OEMCrypto, as discussed in the + * document "License Duration and Renewal". + * + * NOTE: OEMCrypto_LoadLicense() must be called first to load the keys into + * the session. + * + * @verification + * The signature of the message shall be computed using mac_key[server], and + * the API shall verify the computed signature matches the signature passed + * in. If not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature + * verification shall use a constant-time algorithm (a signature mismatch + * will always take the same time as a successful comparison). + * + * @param[in] session: handle for the session to be used. + * @param[in] message: pointer to memory containing message to be verified. + * @param[in] message_length: length of the message, in bytes. + * @param[in] core_message_length: length of the core submessage, in bytes. + * @param[in] signature: pointer to memory containing the signature. + * @param[in] signature_length: length of the signature, in bytes. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_NO_DEVICE_KEY + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_SIGNATURE_FAILURE + * @retval OEMCrypto_ERROR_INVALID_NONCE + * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE + * @retval OEMCrypto_ERROR_SESSION_LOST_STATE + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval ODK_STALE_RENEWAL + * + * @buffer_size + * OEMCrypto shall support message sizes as described in the section + * OEMCrypto_ResourceRatingTier(). + * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is + * larger than the supported size. + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It will not be called simultaneously with initialization + * or usage table functions. It is as if the CDM holds a write lock for this + * session, and a read lock on the OEMCrypto system. + * + * @version + * This method changed in API version 12. + */ +OEMCryptoResult OEMCrypto_LoadRenewal(OEMCrypto_SESSION session, + const uint8_t* message, + size_t message_length, + size_t core_message_length, + const uint8_t* signature, + size_t signature_length); + +/** + * Returns the decrypted key control block for the given content_key_id. This + * function is for application developers to debug license server and key + * timelines. It only returns a key control block if LoadLicense was successful, + * otherwise it returns OEMCrypto_ERROR_NO_CONTENT_KEY. The developer of the + * OEMCrypto library must be careful that the keys themselves are not + * accidentally revealed. + * + * Note: returns control block in original, network byte order. If OEMCrypto + * converts fields to host byte order internally for storage, it should + * convert them back. Since OEMCrypto might not store the nonce or validation + * fields, values of 0 may be used instead. + * + * @verification + * The following checks should be performed. + * 1. If key_id is null, return OEMCrypto_ERROR_INVALID_CONTEXT. + * 2. If key_control_block_length is null, return + * OEMCrypto_ERROR_INVALID_CONTEXT. + * 3. If *key_control_block_length is less than the length of a key control + * block, set it to the correct value, and return + * OEMCrypto_ERROR_SHORT_BUFFER. + * 4. If key_control_block is null, return OEMCrypto_ERROR_INVALID_CONTEXT. + * 5. If the specified key has not been loaded, return + * OEMCrypto_ERROR_NO_CONTENT_KEY. + * + * @param[in] session: handle for the crypto or entitled key session to be used. + * @param[in] content_key_id: The unique id of the key of interest. + * @param[in] content_key_id_length: The length of key_id, in bytes. From 1 to + * 16, inclusive. + * @param[out] key_control_block: A caller-owned buffer. + * @param[in,out] key_control_block_length. The length of key_control_block + * buffer. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * @retval OEMCrypto_ERROR_SESSION_LOST_STATE + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It will not be called simultaneously with initialization + * or usage table functions. It is as if the CDM holds a write lock for this + * session, and a read lock on the OEMCrypto system. + * + * @version + * This method is changed in API version 17. + */ +OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, + const uint8_t* content_key_id, + size_t content_key_id_length, + uint8_t* key_control_block, + size_t* key_control_block_length); + +/// @} + +/// @addtogroup entitled +/// @{ + +/** + * This method creates an entitled key session. + * OEMCrypto is required to support at least one entitled key session per + * license. For CAS support, we also require that OEMCrypto support at least + * six entitled key sessions per license. + * + * @param[in] oec_session: handle for the OEMCrypto session to be associated + * with the created entitled key session. + * @param[out] key_session: id of the created entitled key session. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_TOO_MANY_SESSIONS + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this oec_session. It will not be called simultaneously with + * initialization or usage table functions. It is as if the CDM holds a write + * lock for this session, and a read lock on the OEMCrypto system. + * + * @version + * This method is new in API version 17. + */ +OEMCryptoResult OEMCrypto_CreateEntitledKeySession( + OEMCrypto_SESSION oec_session, OEMCrypto_SESSION* key_session); + +/** + * This method which removes an entitled key session. + * + * @param[in] key_session: id of the entitled key session to be removed. + * + * Returns: + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It will not be called simultaneously with initialization + * or usage table functions. It is as if the CDM holds a write lock for this + * session, and a read lock on the OEMCrypto system. + * + * @version + * This method is new in API version 17. + */ +OEMCryptoResult OEMCrypto_RemoveEntitledKeySession( + OEMCrypto_SESSION key_session); + /** * Load content keys into an entitled session which is associated with an * entitlement sessions. This function will only be called for an entitled @@ -1890,221 +1815,79 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( const OEMCrypto_EntitledContentKeyObject* key_array); /** - * NOTE: OEMCrypto_RefreshKeys() is only used to load a v15 license or renewal. - * Because there are no longer any active v15 servers, this function is only - * needed for devices that are upgraded to v17, not new devices. + * This method associates an existing entitled key session to the specified + * OEMCrypto session. * - * Updates the license clock values to allow playback to continue. This - * function is being deprecated and is only used for version v15 licenses -- - * i.e. offline license saved before an update or licenses from a server that - * has not update to the v16 license server SDK. - * - * OEMCrypto shall compute the signature of the message using - * mac_key[server], and shall verify the computed signature matches the - * signature passed in. If not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The - * signature verification shall use a constant-time algorithm (a signature - * mismatch will always take the same time as a successful comparison). - * - * The key control from the first OEMCrypto_KeyRefreshObject in the key_array - * shall be extracted. If it is encrypted, as described below, it shall be - * decrypted. The duration from the key control shall be extracted and - * converted to host byte order. This duration shall be passed to the - * function ODK_RefreshV15Values as the parameter new_key_duration. - * - * If the KeyRefreshObject's key_control_iv has zero length, then the - * key_control is not encrypted. If the key_control_iv is specified, then - * key_control is encrypted with the first 128 bits of the corresponding - * content key. - * - * If the KeyRefreshObject's key_id has zero length, then it is an error for - * the key_control_iv to have nonzero length. OEMCrypto shall return an error - * of OEMCrypto_ERROR_INVALID_CONTEXT. - * - * If the session's license_type is OEMCrypto_ContentLicense, and the - * KeyRefreshObject's key_id is not null, then the entry in the keytable with - * the matching content_key_id is used. - * - * If the session's license_type is OEMCrypto_EntitlementLicense, and the - * KeyRefreshObject's key_id is not null, then the entry in the keytable with - * the matching entitlment_key_id is used. - * - * The function ODK_RefreshV15Values shall be called to update the clock - * values. See [Widevine Core Message Serialization](../../odk) for the - * documentation of the ODK library functions. - * - * If ODK_RefreshV15Values returns - * - * - ODK_SET_TIMER: Success. The timer should be reset to the specified - * timer value. - * - ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is - * allowed. - * - ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed. - * - ODK_STALE_RENEWAL: This renewal is not the most recently signed. It is - * rejected. Return this error - * - Any other error - OEMCrypto shall pass any other error up to the - * caller of OEMCrypto_RefreshKeys(). - * - * NOTE: OEMCrypto_LoadKeys() must be called first to load the keys into the - * session. - * - * @param[in] session: handle for the session to be used. - * @param[in] message: pointer to memory containing message to be verified. - * @param[in] message_length: length of the message, in bytes. - * @param[in] signature: pointer to memory containing the signature. - * @param[in] signature_length: length of the signature, in bytes. - * @param[in] num_keys: number of keys present. - * @param[in] key_array: set of key updates. + * @param[in] key_session: id of the entitled key session. + * @param[in] oec_session: handle for the OEMCrypto session to be associated + * with the entitled key session. * * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NO_DEVICE_KEY - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_SIGNATURE_FAILURE - * @retval OEMCrypto_ERROR_INVALID_NONCE - * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE - * @retval OEMCrypto_ERROR_NO_CONTENT_KEY - * @retval OEMCrypto_ERROR_SESSION_LOST_STATE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED - * - * @buffer_size - * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier(). - * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is - * larger than the supported size. - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method changed in API version 16. - */ -OEMCryptoResult OEMCrypto_RefreshKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, size_t num_keys, - const OEMCrypto_KeyRefreshObject* key_array); - -/** - * Updates the clock values and resets the renewal timer for the current - * session. - * - * OEMCrypto shall verify the signature of the entire message using the - * session's renewal mac key for the server. The entire message is the buffer - * starting at message with length message_length. If the signature does not - * match, OEMCrypto returns OEMCrypto_ERROR_SIGNATURE_FAILURE. - * - * OEMCrypto shall verify that nonce_values.api_major_version is 16. If not, - * return the error OEMCrypto_ERROR_INVALID_CONTEXT. Legacy licenses will use - * the function OEMCrypto_RefreshKeys() instead of OEMCrypto_LoadRenewal(). - * - * If the signature passes, OEMCrypto shall use the function - * ODK_ParseRenewal, as described in the document "Widevine Core Message - * Serialization" to parse and verify the message. If ODK_ParseRenewal - * returns an error OEMCrypto returns the error to the CDM layer. - * - * The function ODK_ParseRenewal updates the clock values for the session, - * and may return ODK_SET_TIMER, ODK_DISABLE_TIMER or ODK_TIMER_EXPIRED on - * success. These values shall be handled by OEMCrypto, as discussed in the - * document "License Duration and Renewal". - * - * NOTE: OEMCrypto_LoadLicense() must be called first to load the keys into - * the session. - * - * @verification - * The signature of the message shall be computed using mac_key[server], and - * the API shall verify the computed signature matches the signature passed - * in. If not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature - * verification shall use a constant-time algorithm (a signature mismatch - * will always take the same time as a successful comparison). - * - * @param[in] session: handle for the session to be used. - * @param[in] message: pointer to memory containing message to be verified. - * @param[in] message_length: length of the message, in bytes. - * @param[in] core_message_length: length of the core submessage, in bytes. - * @param[in] signature: pointer to memory containing the signature. - * @param[in] signature_length: length of the signature, in bytes. - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NO_DEVICE_KEY - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_SIGNATURE_FAILURE - * @retval OEMCrypto_ERROR_INVALID_NONCE - * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE - * @retval OEMCrypto_ERROR_SESSION_LOST_STATE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED - * @retval ODK_STALE_RENEWAL - * - * @buffer_size - * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier(). - * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is - * larger than the supported size. - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method changed in API version 12. - */ -OEMCryptoResult OEMCrypto_LoadRenewal(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - size_t core_message_length, - const uint8_t* signature, - size_t signature_length); - -/** - * Returns the decrypted key control block for the given content_key_id. This - * function is for application developers to debug license server and key - * timelines. It only returns a key control block if LoadKeys was successful, - * otherwise it returns OEMCrypto_ERROR_NO_CONTENT_KEY. The developer of the - * OEMCrypto library must be careful that the keys themselves are not - * accidentally revealed. - * - * Note: returns control block in original, network byte order. If OEMCrypto - * converts fields to host byte order internally for storage, it should - * convert them back. Since OEMCrypto might not store the nonce or validation - * fields, values of 0 may be used instead. - * - * @verification - * The following checks should be performed. - * 1. If key_id is null, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 2. If key_control_block_length is null, return - * OEMCrypto_ERROR_INVALID_CONTEXT. - * 3. If *key_control_block_length is less than the length of a key control - * block, set it to the correct value, and return - * OEMCrypto_ERROR_SHORT_BUFFER. - * 4. If key_control_block is null, return OEMCrypto_ERROR_INVALID_CONTEXT. - * 5. If the specified key has not been loaded, return - * OEMCrypto_ERROR_NO_CONTENT_KEY. - * - * @param[in] session: handle for the crypto or entitled key session to be used. - * @param[in] content_key_id: The unique id of the key of interest. - * @param[in] content_key_id_length: The length of key_id, in bytes. From 1 to - * 16, inclusive. - * @param[out] key_control_block: A caller-owned buffer. - * @param[in,out] key_control_block_length. The length of key_control_block - * buffer. - * - * @retval OEMCrypto_SUCCESS - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_ERROR_SESSION_LOST_STATE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION + * @retval OEMCrypto_ERROR_INVALID_SESSION + * + * @threading + * This is a "Session Initialization Function" and will not be called + * simultaneously with any other function, as if the CDM holds a write lock + * on the OEMCrypto system. + * + * @version + * This method is new in API version 17. + */ +OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession( + OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session); + +/** + * The OEMCrypto_LoadCasECMKeys method is added to load content keys into an + * entitled key session, which already has entitlement keys loaded. Used only by + * CAS. + * + * This function will only be called for a session after a call to + * OEMCrypto_LoadLicense with the license_type equal to + * OEMCrypto_EntitlementLicense, and a call to + * OEMCrypto_CreateEntitledKeySession initializing the entitled key session. + * This function may be called multiple times for the same session. + * + * For each key object, odd and even, OEMCrypto shall look up the entry in the + * key table with the corresponding entitlement_key_id. Before the + * entitlement_key is used: + * 1) If no entry is found, return OEMCrypto_KEY_NOT_ENTITLED. + * 2) Check the entitlement key’s key control block use. If failed, return + * corresponding error code such as OEMCrypto_ERROR_ANALOG_OUTPUT, + * OEMCrypto_ERROR_INSUFFICIENT_HDCP. + * 3) If the entitlement key’s control block has a nonzero Duration field, + * then the API shall verify that the duration is greater than the + * session’s elapsed time clock before the key is used. OEMCrypto will + * return OEMCrypto_ERROR_KEY_EXPIRED. + * 4) The content_key_data decrypted using the entitlement_key_data as a key + * for AES-256-CBC with an IV of content_key_data_iv. Wrapped content is + * padded using PKCS#7 padding. Notice that the entitlement key will be an + * AES 256 bit key. The clear content key data will be stored in the + * entry’s content_key_data. + * 5) The decrypted content key data may be set in a hardware KeySlot, + * together with content iv and cipher mode information, which can be used + * by the Descrambler in TunerHal. The entitled key session ID may be used + * as the key token to uniquely identify the content key in KeySlot. + * + * @param[in] session: handle for the entitled key session to be used. + * @param[in] message: pointer to memory containing message to be verified. + * @param[in] message_length: length of the message, in bytes. + * @param[in] even_key: key update for the even ecm key. May be null if the key + * does not change. + * @param[in] odd_key: key update for the odd ecm key. May be null if the key + * does not change. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * @retval OEMCrypto_KEY_NOT_ENTITLED + * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION + * @retval OEMCrypto_ERROR_KEY_EXPIRED + * @retval OEMCrypto_ERROR_ANALOG_OUTPUT + * @retval OEMCrypto_ERROR_INSUFFICIENT_HDCP * * @threading * This is a "Session Function" and may be called simultaneously with session @@ -2114,13 +1897,38 @@ OEMCryptoResult OEMCrypto_LoadRenewal(OEMCrypto_SESSION session, * session, and a read lock on the OEMCrypto system. * * @version - * This method is changed in API version 17. + * This method is new in API version 17. */ -OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, - const uint8_t* content_key_id, - size_t content_key_id_length, - uint8_t* key_control_block, - size_t* key_control_block_length); +OEMCryptoResult OEMCrypto_LoadCasECMKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const OEMCrypto_EntitledContentKeyObject* even_key, + const OEMCrypto_EntitledContentKeyObject* odd_key); + +/** + * Retrieves the key token associated with the input entitled key session. This + * method is currently used only by CAS, where key token is a means to share + * vendor specific crypto info with other frameworks (e.g. Descrambler in + * Android TunerHAL) that are also under control of the vendor. + * + * @param[in] key_session: handle for the entitled key session to be used. + * @param[out] key_token: where the key token is stored. + * @param[in,out] key_token_length: length of the key token, in bytes. + * + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_SHORT_BUFFER if buffer_length is too small. + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * + * @threading + * This is an "Initialization and Termination Function" and will not be called + * simultaneously with any other function, as if the CDM holds a write lock on + * the OEMCrypto system. + * + * @version + * This method is new in API version 17. + */ +OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session, + uint8_t* key_token, + size_t* key_token_length); /// @} @@ -2129,10 +1937,20 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, /** * Select a content key and install it in the hardware key ladder for - * subsequent decryption operations (OEMCrypto_DecryptCENC()) for this - * session. The specified key must have been previously "installed" via - * OEMCrypto_LoadKeys(), OEMCrypto_LoadLicense(), or - * OEMCrypto_LoadEntitledContentKeys(). + * subsequent decryption operations. (e.g. OEMCrypto_DecryptCENC(), generic + * crypto functions) The specified key must have been previously imported via + * OEMCrypto_LoadLicense() or OEMCrypto_LoadEntitledContentKeys(). Write a + * handle that can be used to refer to the installed key into the buffer pointed + * to by the key_handle parameter and set key_handle_length to the size of the + * data written to key_handle. + * + * If key_handle is NULL or key_handle_length is too small to hold the handle, + * write the number of bytes needed to hold a key handle to key_handle_length + * and return OEMCrypto_ERROR_SHORT_BUFFER. Do not install the key in this case. + * + * If the session has an entry in the Usage Table and the status of the entry is + * "unused", then change the status to "active" and set the + * time_of_first_decrypt. * * A key control block is associated with the key and the session, and is * used to configure the session context. The Key Control data is documented @@ -2149,9 +1967,44 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * 256 bits it will be used for OEMCrypto_Generic_Sign() or * OEMCrypto_Generic_Verify() as specified in the key control block. If the key * will be used for OEMCrypto_Generic_Encrypt() or OEMCrypto_Generic_Decrypt() - * then the cipher mode will always be OEMCrypto_CipherMode_CBCS. Continue to - * use this key for this session until OEMCrypto_SelectKey() is called again, - * or until OEMCrypto_CloseSession() is called. + * then the cipher mode will always be OEMCrypto_CipherMode_CBCS. + * + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt should latch the key into + * secure crypto hardware such that it can be fed by the chosen bypass method. + * For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * If the device is bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. The hardware that the key is latched into must be able + * to enforce that the key expires and becomes unusable after the amount of + * time returned by ODK in the timer_value field. + * + * The format of the key handle is opaque to Widevine and platform-specific. It + * should contain whatever information the platform will need to find the key in + * the hardware on the bypass decryption path, as well as in + * OEMCrypto_DecryptCENC() and the generic crypto functions. A key slot number + * is generally not sufficient, as this could lead to the wrong key being used + * if that slot later has a different key loaded into it. + * + * The key handle must not contain the actual cryptographic key. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. These devices may latch the + * key to the session and continue to use this key for this session until + * OEMCrypto_SelectKey() is called again, or until OEMCrypto_CloseSession() is + * called. + * + * The "key handle" in this mode is the session ID. Platforms should request a + * 4-byte key handle buffer and copy the session ID into it. * * @verification * 1. If the key id is not found in the keytable for this session, then the @@ -2179,8 +2032,15 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * @param[in] cipher_mode: whether the key should be prepared for CTR mode or * CBC mode when used in later calls to DecryptCENC. This should be ignored * when the key is used for Generic Crypto calls. + * @param[out] key_handle: pointer to a buffer in which the key handle should be + * stored. May be NULL on the first call in order to find required buffer + * size. + * @param[in,out] key_handle_length: (in) length of the key_handle buffer, in + * bytes. (out) actual length of the key handle written to the key_handle + * buffer, in bytes. May not be NULL. * * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is NULL or too small * @retval OEMCrypto_ERROR_KEY_EXPIRED if the session's timer has expired * @retval OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or not open * @retval OEMCrypto_ERROR_NO_DEVICE_KEY failed to decrypt device key @@ -2203,16 +2063,18 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * session, and a read lock on the OEMCrypto system. * * @version - * This method changed in API version 16. + * This method is new in API version 18. */ -OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, - const uint8_t* content_key_id, - size_t content_key_id_length, - OEMCryptoCipherMode cipher_mode); +OEMCryptoResult OEMCrypto_GetKeyHandle(OEMCrypto_SESSION session, + const uint8_t* content_key_id, + size_t content_key_id_length, + OEMCryptoCipherMode cipher_mode, + uint8_t* key_handle, + size_t* key_handle_length); /** * Decrypts or copies a series of input payloads into output buffers using - * the session context indicated by the session parameter. The input payload + * the installed key indicated by the key handle parameter. The input payload * is delivered in the form of samples. The samples are subdivided into * subsamples. "Samples" and "subsamples" are defined as in the ISO Common * Encryption standard (ISO/IEC 23001-7:2016). The samples parameter contains @@ -2229,7 +2091,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * * Decryption mode is AES-128-CTR or AES-128-CBC depending on the value of * cipher_mode previously passed in to OEMCrypto_SelectKey(). For the encrypted - * portion of subsamples, the content key associated with the session is + * portion of subsamples, the content key associated with the handle is * latched in the active hardware key ladder and is used for the decryption * operation. For the clear portion of subsamples, the data is simply copied. * @@ -2245,6 +2107,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * buffer. * 3. The structure OEMCrypto_DestBufferDesc indicates that the data should * be sent directly to the decoder and renderer. + * * Depending on your platform's needs, you may not need to support all three * of these options. * @@ -2441,10 +2304,6 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * OEMCrypto_DecryptCENC() begins storing data buffers.output.secure.offset * bytes after the beginning of the secure buffer. * - * If the session has an entry in the Usage Table, then OEMCrypto must update - * the time_of_last_decrypt. If the status of the entry is "unused", then - * change the status to "active" and set the time_of_first_decrypt. - * * OEMCrypto cannot assume that the buffers of consecutive samples are * consecutive in memory. * @@ -2469,14 +2328,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * OEMCrypto_ERROR_UNKNOWN_FAILURE if the subsamples are larger than the * input buffer. No decryption should be performed in this case. * If the subsamples all contain only clear bytes, then no further - * verification is performed. This call shall copy clear data even when there - * are no keys loaded, or there is no selected key. - * If this is the first use of a key for this session, then OEMCrypto shall - * call ODK_AttemptFirstPlayback to update the session's clock values and - * verify playback is allowed. If this is not the first use of a key for this - * session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See - * [ODK Clocks and Timers](../../odk-timers) for handling the return value of - * these ODK functions. + * verification is performed. * The following checks should be performed if any subsamples contain any * encrypted bytes. If any check fails, an error is returned, and no * decryption is performed. @@ -2503,9 +2355,9 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * restrict those displays, return * OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION. (See note on delayed * error conditions below) - * 5. If the current session has an entry in the Usage Table, and the - * status of that entry is either kInactiveUsed or kInactiveUnused, then - * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. + * 5. If the current key has an entry in the Usage Table, and the status of + * that entry is either kInactiveUsed or kInactiveUnused, then return the + * error OEMCrypto_ERROR_LICENSE_INACTIVE. * 6. If a Decrypt Hash has been initialized via OEMCrypto_SetDecryptHash(), * and the current key's control block does not have the * Allow_Hash_Verification bit set, then do not compute a hash and @@ -2538,8 +2390,33 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * In either case, a call to OEMCrypto_GetHDCPCapability() shall return the * current HDCP level. * - * @param[in] session: Crypto or entitled session identifier. The crypto session - * in which decrypt is to be performed. + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt are still required to implement + * this function so that the decrypt path can be tested. It is acceptable for + * this function to invoke the bypass mechanism instead of calling into the + * OEMCrypto TA. For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. The "key handle" created by + * OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be + * used the same as the session ID previously passed to OEMCrypto_DecryptCENC(). + * + * If the device is not bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. + * + * @param[in] key_handle: pointer to a buffer containing the key handle for a + * key previously installed with OEMCrypto_GetKeyHandle(). + * @param[in] key_handle_length: length of the data in the key_handle buffer, in + * bytes. * @param[in] samples: A caller-owned array of OEMCrypto_SampleDescription * structures. Each entry in this array contains one sample of the content. * @param[in] samples_length: The length of the array pointed to by the samples @@ -2585,16 +2462,21 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * @threading * This is a "Session Function" and may be called simultaneously with session * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. + * for the session containing the key. It will not be called simultaneously + * with initialization or usage table functions. It is as if the CDM holds a + * write lock for the key's session, and a read lock on the OEMCrypto system. + * + * The threading guarantees for this function are only guaranteed when the + * function is called through the Widevine CDM. If the platform uses Bypass + * Decrypt in a way that still calls this function, the OS may call this + * function in ways that violate these threading guarantees. * * @version - * This method changed in API version 17. This method changed its name in API + * This method changed in API version 18. This method changed its name in API * version 11. */ OEMCryptoResult OEMCrypto_DecryptCENC( - OEMCrypto_SESSION session, + const uint8_t* key_handle, size_t key_handle_length, const OEMCrypto_SampleDescription* samples, // an array of samples. size_t samples_length, // the number of samples. const OEMCrypto_CENCEncryptPatternDesc* pattern); @@ -2684,31 +2566,44 @@ OEMCryptoResult OEMCrypto_CopyBuffer( uint8_t subsample_flags); /** - * This function encrypts a generic buffer of data using the current key. - * - * If the session has an entry in the Usage Table, then OEMCrypto will update - * the time_of_last_decrypt. If the status of the entry is "unused", then - * change the status to "active" and set the time_of_first_decrypt. + * This function encrypts a generic buffer of data using the given key. * * OEMCrypto shall be able to handle buffers at least 100 KiB long. * + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt are still required to implement + * this function. For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. The "key handle" created by + * OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be + * used the same as the session ID previously passed to OEMCrypto_DecryptCENC(). + * + * If the device is not bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. + * * @verification * The following checks should be performed. If any check fails, an error is * returned, and the data is not encrypted. - * 1. The control bit for the current key shall have the Allow_Encrypt set. - * If not, return OEMCrypto_ERROR_UNKNOWN_FAILURE. - * 2. If this is the first use of a key for this session, then OEMCrypto - * shall call ODK_AttemptFirstPlayback to update the session's clock - * values and verify playback is allowed. If this is not the first use - * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. - * See [ODK Clocks and Timers](../../odk-timers) for handling the return - * value of these ODK functions. - * 3. If the current session has an entry in the Usage Table, and the - * status of that entry is either kInactiveUsed or kInactiveUnused, then - * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. + * 1. The control bit for the key shall have the Allow_Encrypt set. If not, + * return OEMCrypto_ERROR_UNKNOWN_FAILURE. + * 2. If the key has an entry in the Usage Table, and the status of that + * entry is either kInactiveUsed or kInactiveUnused, then return the + * error OEMCrypto_ERROR_LICENSE_INACTIVE. * - * @param[in] session: crypto or entitled key session identifier. + * @param[in] key_handle: pointer to a buffer containing the key handle for a + * key previously installed with OEMCrypto_GetKeyHandle(). + * @param[in] key_handle_length: length of the data in the key_handle buffer, in + * bytes. * @param[in] in_buffer: pointer to memory containing data to be encrypted. * @param[in] in_buffer_length: length of the buffer, in bytes. The algorithm * may restrict in_buffer_length to be a multiple of block size. @@ -2731,7 +2626,7 @@ OEMCryptoResult OEMCrypto_CopyBuffer( * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION * * @buffer_size - * OEMCrypto shall support buffers sizes of at least 100 KiB for generic + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic * crypto operations. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. @@ -2739,46 +2634,60 @@ OEMCryptoResult OEMCrypto_CopyBuffer( * @threading * This is a "Session Function" and may be called simultaneously with session * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. + * for the session containing the key. It will not be called simultaneously + * with initialization or usage table functions. It is as if the CDM holds a + * write lock for the key's session, and a read lock on the OEMCrypto system. * * @version - * This method changed in API version 17. + * This method changed in API version 18. */ OEMCryptoResult OEMCrypto_Generic_Encrypt( - OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer, - size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* in_buffer, size_t in_buffer_length, + const uint8_t* iv, OEMCrypto_Algorithm algorithm, OEMCrypto_SharedMemory* out_buffer); /** - * This function decrypts a generic buffer of data using the current key. - * - * If the session has an entry in the Usage Table, then OEMCrypto will update - * the time_of_last_decrypt. If the status of the entry is "unused", then - * change the status to "active" and set the time_of_first_decrypt. + * This function decrypts a generic buffer of data using the given key. * * OEMCrypto should be able to handle buffers at least 100 KiB long. * + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt are still required to implement + * this function. For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. The "key handle" created by + * OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be + * used the same as the session ID previously passed to OEMCrypto_DecryptCENC(). + * + * If the device is not bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. + * * @verification * The following checks should be performed. If any check fails, an error is * returned, and the data is not decrypted. - * 1. The control bit for the current key shall have the Allow_Decrypt set. - * If not, return OEMCrypto_ERROR_DECRYPT_FAILED. - * 2. If the current key's control block has the Data_Path_Type bit set, - * then return OEMCrypto_ERROR_DECRYPT_FAILED. - * 3. If this is the first use of a key for this session, then OEMCrypto - * shall call ODK_AttemptFirstPlayback to update the session's clock - * values and verify playback is allowed. If this is not the first use - * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. - * See [ODK Clocks and Timers](../../odk-timers) for handling the return - * value of these ODK functions. - * 4. If the current session has an entry in the Usage Table, and the - * status of that entry is either kInactiveUsed or kInactiveUnused, then - * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. + * 1. The control bit for the key shall have the Allow_Decrypt set. If not, + * return OEMCrypto_ERROR_DECRYPT_FAILED. + * 2. If the key's control block has the Data_Path_Type bit set, then return + * OEMCrypto_ERROR_DECRYPT_FAILED. + * 3. If the key has an entry in the Usage Table, and the status of that + * entry is either kInactiveUsed or kInactiveUnused, then return the + * error OEMCrypto_ERROR_LICENSE_INACTIVE. * - * @param[in] session: crypto or entitled key session identifier. + * @param[in] key_handle: pointer to a buffer containing the key handle for a + * key previously installed with OEMCrypto_GetKeyHandle(). + * @param[in] key_handle_length: length of the data in the key_handle buffer, in + * bytes. * @param[in] in_buffer: pointer to memory containing data to be encrypted. * @param[in] in_buffer_length: length of the buffer, in bytes. The algorithm * may restrict in_buffer_length to be a multiple of block size. @@ -2802,7 +2711,7 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt( * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION * * @buffer_size - * OEMCrypto shall support buffers sizes of at least 100 KiB for generic + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic * crypto operations. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. @@ -2810,41 +2719,55 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt( * @threading * This is a "Session Function" and may be called simultaneously with session * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. + * for the session containing the key. It will not be called simultaneously + * with initialization or usage table functions. It is as if the CDM holds a + * write lock for the key's session, and a read lock on the OEMCrypto system. * * @version - * This method changed in API version 17. + * This method changed in API version 18. */ OEMCryptoResult OEMCrypto_Generic_Decrypt( - OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer, - size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* in_buffer, size_t in_buffer_length, + const uint8_t* iv, OEMCrypto_Algorithm algorithm, OEMCrypto_SharedMemory* out_buffer); /** - * This function signs a generic buffer of data using the current key. + * This function signs a generic buffer of data using the given key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update - * the time_of_last_decrypt. If the status of the entry is "unused", then - * change the status to "active" and set the time_of_first_decrypt. + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt are still required to implement + * this function. For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. The "key handle" created by + * OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be + * used the same as the session ID previously passed to OEMCrypto_DecryptCENC(). + * + * If the device is not bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. * * @verification * The following checks should be performed. If any check fails, an error is * returned, and the data is not signed. - * 1. The control bit for the current key shall have the Allow_Sign set. - * 2. If this is the first use of a key for this session, then OEMCrypto - * shall call ODK_AttemptFirstPlayback to update the session's clock - * values and verify playback is allowed. If this is not the first use - * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. - * See [ODK Clocks and Timers](../../odk-timers) for handling the return - * value of these ODK functions. - * 3. If the current session has an entry in the Usage Table, and the - * status of that entry is either kInactiveUsed or kInactiveUnused, then - * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. + * 1. The control bit for the key shall have the Allow_Sign set. + * 2. If the key has an entry in the Usage Table, and the status of that + * entry is either kInactiveUsed or kInactiveUnused, then return the + * error OEMCrypto_ERROR_LICENSE_INACTIVE. * - * @param[in] session: crypto or entitled key session identifier. + * @param[in] key_handle: pointer to a buffer containing the key handle for a + * key previously installed with OEMCrypto_GetKeyHandle(). + * @param[in] key_handle_length: length of the data in the key_handle buffer, in + * bytes. * @param[in] buffer: pointer to memory containing data to be encrypted. * @param[in] buffer_length: length of the buffer, in bytes. * @param[in] algorithm: Specifies which algorithm to use. @@ -2869,7 +2792,7 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt( * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION * * @buffer_size - * OEMCrypto shall support buffers sizes of at least 100 KiB for generic + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic * crypto operations. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. @@ -2877,14 +2800,15 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt( * @threading * This is a "Session Function" and may be called simultaneously with session * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. + * for the session containing the key. It will not be called simultaneously + * with initialization or usage table functions. It is as if the CDM holds a + * write lock for the key's session, and a read lock on the OEMCrypto system. * * @version - * This method changed in API version 17. + * This method changed in API version 18. */ -OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, +OEMCryptoResult OEMCrypto_Generic_Sign(const uint8_t* key_handle, + size_t key_handle_length, const OEMCrypto_SharedMemory* buffer, size_t buffer_length, OEMCrypto_Algorithm algorithm, @@ -2893,34 +2817,47 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, /** * This function verifies the signature of a generic buffer of data using the - * current key. + * given key. * - * If the session has an entry in the Usage Table, then OEMCrypto will update - * the time_of_last_decrypt. If the status of the entry is "unused", then - * change the status to "active" and set the time_of_first_decrypt. + * #### Bypass Decrypt + * + * Platforms that wish to support Bypass Decrypt are still required to implement + * this function. For more information on Bypass Decrypt, see the + * [Bypass Decrypt](../../bypass) documentation. + * + * #### Non-Bypass Decrypt + * + * For platforms that do not need to support Bypass Decrypt, a mode compatible + * with previous versions of OEMCrypto is available. The "key handle" created by + * OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be + * used the same as the session ID previously passed to OEMCrypto_DecryptCENC(). + * + * If the device is not bypassing, it must update the ODK clock values in this + * function call. If this is the first use of a key for this session, then + * OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock + * values and verify playback is allowed. If this is not the first use of a key + * for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of + * these ODK functions. * * @verification * The following checks should be performed. If any check fails, an error is * returned. - * 1. The control bit for the current key shall have the Allow_Verify set. + * 1. The control bit for the key shall have the Allow_Verify set. * 2. The signature of the message shall be computed, and the API shall * verify the computed signature matches the signature passed in. If * not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. * 3. The signature verification shall use a constant-time algorithm (a * signature mismatch will always take the same time as a successful * comparison). - * 4. If this is the first use of a key for this session, then OEMCrypto - * shall call ODK_AttemptFirstPlayback to update the session's clock - * values and verify playback is allowed. If this is not the first use - * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. - * See [ODK Clocks and Timers](../../odk-timers) for handling the return - * value of these ODK functions. - * 5. If the current session has an entry in the Usage Table, and the - * status of that entry is either kInactiveUsed or kInactiveUnused, then - * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. + * 4. If the key has an entry in the Usage Table, and the status of that + * entry is either kInactiveUsed or kInactiveUnused, then return the + * error OEMCrypto_ERROR_LICENSE_INACTIVE. * - * @param[in] session: crypto or entitled key session identifier. + * @param[in] key_handle: pointer to a buffer containing the key handle for a + * key previously installed with OEMCrypto_GetKeyHandle(). + * @param[in] key_handle_length: length of the data in the key_handle buffer, in + * bytes. * @param[in] buffer: pointer to memory containing data to be encrypted. * @param[in] buffer_length: length of the buffer, in bytes. * @param[in] algorithm: Specifies which algorithm to use. @@ -2941,7 +2878,7 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION * * @buffer_size - * OEMCrypto shall support buffers sizes of at least 100 KiB for generic + * OEMCrypto shall support buffer sizes of at least 100 KiB for generic * crypto operations. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. @@ -2949,17 +2886,18 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * @threading * This is a "Session Function" and may be called simultaneously with session * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. + * for the session containing the key. It will not be called simultaneously + * with initialization or usage table functions. It is as if the CDM holds a + * write lock for the key's session, and a read lock on the OEMCrypto system. * * @version - * This method changed in API version 17. + * This method changed in API version 18. */ OEMCryptoResult OEMCrypto_Generic_Verify( - OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* buffer, - size_t buffer_length, OEMCrypto_Algorithm algorithm, - const OEMCrypto_SharedMemory* signature, size_t signature_length); + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* buffer, size_t buffer_length, + OEMCrypto_Algorithm algorithm, const OEMCrypto_SharedMemory* signature, + size_t signature_length); /// @} @@ -3191,6 +3129,10 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id, OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data, size_t* key_data_length); +/// @} + +/// @addtogroup test_verify +/// @{ /** * Temporarily use the specified test keybox until the next call to * OEMCrypto_Terminate(). This allows a standard suite of unit tests to be run @@ -3297,38 +3239,6 @@ typedef enum OEMCrypto_Security_Level { OEMCrypto_Level3 = 3, } OEMCrypto_Security_Level; -/** - * Returns a buffer filled with hardware-generated random bytes, if supported - * by the hardware. If the hardware feature does not exist, return - * OEMCrypto_ERROR_RNG_NOT_SUPPORTED. - * - * @param[out] random_data: pointer to the buffer that receives random data - * @param[in] random_data_length: length of the random data buffer in bytes - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_RNG_FAILED failed to generate random number - * @retval OEMCrypto_ERROR_RNG_NOT_SUPPORTED function not supported - * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED - * - * @buffer_size - * OEMCrypto shall support random_data_length sizes of at least 32 bytes - * for random number generation. - * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is - * larger than the supported size. - * - * @threading - * This is a "Property Function" and may be called simultaneously with any - * other property function or session function, but not any initialization or - * usage table function, as if the CDM holds a read lock on the OEMCrypto - * system. - * - * @version - * This method is supported in all API versions. - */ -OEMCryptoResult OEMCrypto_GetRandom(uint8_t* random_data, - size_t random_data_length); - /** * This function returns the current API version number. The version number * allows the calling application to avoid version mis-match errors, because @@ -3383,31 +3293,64 @@ uint32_t OEMCrypto_MinorAPIVersion(void); /** * Stores the build information of the OEMCrypto library in a buffer. This - * string should be updated with each release or OEMCrypto build. If - * buffer_length is not enough, the function will return + * string should be updated with each release or OEMCrypto build. + * + * It may be used for logging or bug tracking and may be bubbled up to the + * app so that it may track metrics on errors. + * + * The returned string must be JSON formatted. It shall also contain the + * following top level values [data types in brackets]: + * - "soc_vendor" [string]: SOC manufacturer name + * - "soc_model" [string]: SOC model name + * - "ta_ver" [string]: TA version in string format eg "1.12.3+tag", "2.0" + * - "uses_opk" [bool]: Whether TA was built with Widevine's OPK + * - "tee_os" [string]: Trusted OS intended to run the TA, eg "Trusty", "QSEE", + * "OP-TEE" + * - "tee_os_ver" [string]: Version of Trusted OS intended to run the TA + * - "is_debug" [bool]: Whether this is a debug build of the TA. Debug builds + * can enter Test Mode via OEMCrypto_EnterTestMode(), while production builds + * cannot. Debug builds are not released to the public. + * + * While not required, the following top level fields are recommended: + * - "implementer" [string]: Name of company or entity that provides OEMCrypto. + * Important if not SOC vendor. + * - "git_commit" [string]: Git commit hash of the code repository that + * produced the TA build. Useful for implementers to distinguish the state of + * different TA builds. + * - "build_timestamp" [string]: ISO 8601 formatted timestamp of the time the + * TA was compiled, eg "YYYY-MM-DDTHH:MM:SS" + * + * While not required, another optional top level struct can be added to the + * build information string to provide information about liboemcrypto.so: + * - "ree" { + * - "liboemcrypto_ver" [string]: liboemcrypto.so version in string format + * eg "2.15.0+tag". Note that this is separate from the "ta_ver" field + * above, since this section is specific to the liboemcrypto.so binary. + * - "git_commit" [string]: git hash of code that compiled liboemcrypto.so + * - "build_timestamp" [string]: ISO 8601 timestamp for when + * liboemcrypto.so was built + * } + * + * The JSON string can contain other values, structs, arrays, etc in addition to + * the above, if desired. + * + * If buffer_length is not enough, the function will return * OEMCrypto_ERROR_SHORT_BUFFER. Before returning OEMCrypto_ERROR_SHORT_BUFFER, * the function should set buffer_length to the length of buffer needed. If the * write is successful, buffer_length will be set to the number of bytes * written. * - * Some SOC vendors deliver a binary OEMCrypto library to a device - * manufacturer. This means the OEMCrypto version may not be exactly in sync - * with the system's versions. This string can be used to help track which - * version is installed on a device. - * - * It may be used for logging or bug tracking and may be bubbled up to the - * app so that it may track metrics on errors. - * - * Since the OEMCrypto API also changes its minor version number when there - * are minor corrections, it would be useful to include the API version - * number in this string, e.g. "15.1" or "15.2" if those minor versions are - * released. + * The returned data shall be no larger than 1024 bytes. If the buffer length is + * larger, this function will return OEMCrypto_ERROR_BUFFER_TOO_LARGE and set + * |buffer_length| to 1024. * * @param[out] buffer: pointer to the buffer that receives build information * @param[in,out] buffer_length: length of the data buffer in bytes * * @retval OEMCrypto_SUCCESS * @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small. + * @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is too large. + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE any other failure. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3800,7 +3743,7 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void); * The message size limit applies to all functions that sign or verify a * message: OEMCrypto_PrepAndSignLicenseRequest(), * OEMCrypto_PrepAndSignRenewalRequest(), - * OEMCrypto_PrepAndSignProvisioningRequest(), and OEMCrypto_LoadKeys(). A + * OEMCrypto_PrepAndSignProvisioningRequest(), and OEMCrypto_LoadLicense(). A * request message is also used as the context buffer in * OEMCrypto_DeriveKeysFromSessionKey() and OEMCrypto_GenerateDerivedKeys(). * @@ -3890,6 +3833,44 @@ OEMCryptoResult OEMCrypto_ProductionReady(void); */ OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(void); +/** + * Queries the hash algorithm that the device will use when performing + * RSASSA-PSS or ECDSA with the private key currently loaded in the given + * session. + * + * For RSA keys, SHA-1 was used for all OEMCrypto versions prior to 18, but + * SHA-256 is strongly recommended for all devices. SHA-384 and SHA-512 are not + * supported with RSA keys. + * + * For ECC keys, the algorithm chosen depends on the curve used to generate the + * key, as outlined in the OEMCrypto Integration Guide. SHA-1 is not supported + * with ECC keys. + * + * For devices that do not support ECC, it is acceptable for this function to + * return a hardcoded value, since the answer does not depend on the currently + * loaded private key. + * + * @param[in] session: crypto session identifier. + * @param[out] algorithm: the algorithm the device will use. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It will not be called simultaneously with initialization + * or usage table functions. It is as if the CDM holds a write lock for this + * session, and a read lock on the OEMCrypto system. + * + * @version + * This method is new in API version 18. + */ +OEMCryptoResult OEMCrypto_GetSignatureHashAlgorithm( + OEMCrypto_SESSION session, OEMCrypto_SignatureHashAlgorithm* algorithm); + /// @} /// @addtogroup drm_cert @@ -4102,8 +4083,8 @@ OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(OEMCrypto_SESSION session, * on a production device without permanently changing the key. Using the * test key is not persistent. * - * The test key can be found in the unit test code, oemcrypto_test.cpp, in - * PKCS8 form as the constant kTestRSAPKCS8PrivateKeyInfo2_2048. + * The test key can be found in the OEMCrypto unit test, in PKCS8 form as the + * constant kTestRSAPKCS8PrivateKeyInfo2_2048. * * @retval OEMCrypto_SUCCESS success * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES @@ -4196,12 +4177,15 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature( RSA_Padding_Scheme padding_scheme); /** - * OEMCrypto will use ODK_PrepareCoreProvisioningRequest(), as described - * in the document "Widevine Core Message Serialization", to prepare the core - * message. If it returns an error, the error should be returned by OEMCrypto - * to the CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall - * compute the signature of the entire message. The entire message is the - * buffer starting at message with length message_length. + * OEMCrypto will use ODK_PrepareCoreProvisioningRequest() or + * ODK_PrepareCoreProvisioning40Request(), as described in the document + * "Widevine Core Message Serialization", to prepare the core message. + * ODK_PrepareCoreProvisioningRequest() for Provisioning 2 or 3, and + * ODK_PrepareCoreProvisioning40Request() for Provisioning 4. If the ODK + * function returns an error, the error should be returned by OEMCrypto to the + * CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall compute the + * signature of the entire message. The entire message is the buffer starting at + * message with length message_length. * * For a device that has a keybox, i.e. Provisioning 2.0, OEMCrypto will sign * the request with the session's derived client mac key from the previous @@ -4935,11 +4919,160 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair( uint8_t* wrapped_private_key, size_t* wrapped_private_key_length, OEMCrypto_PrivateKeyType* key_type); +/** + * Get the serialized device information in CBOR map format. + * + * The device + * information may contain, for example, device make and model, "fused" status, + * and other properties, which is intended to be 1) uploaded during device + * manufacture in the factory, 2) checked by the server to verify that the + * provisioning request is coming from the expected device in the fields, based + * on the values previously uploaded and registered. + * + * This method is used by provisioning 4 only. + * + * @param[out] device_info: pointer to the buffer that receives the serialized + * device information in CBOR map format. + * @param[in,out] device_info_length: on input, size of the caller's + * device_info buffer. On output, the number of bytes written into the buffer. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_SHORT_BUFFER if device_info_length is too small to + * return the device_info. + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if provisioning 4 is not supported, + * or device information is not available on the platform. + * + * @threading + * This is a "Property Function" and may be called simultaneously with any + * other property function or session function, but not any initialization or + * usage table function, as if the CDM holds a read lock on the OEMCrypto + * system. + * + * @version + * This method is new in API version 18. + */ +OEMCryptoResult OEMCrypto_GetDeviceInformation(uint8_t* device_info, + size_t* device_info_length); + +/** + * Get the serialized signed Certificate Signing Request (Csr) payload in + * COSE_Sign1 format. + * + * The signed CSR payload contains challenge and device information. It is + * signed by the leaf cert of the boot certificate chain (BCC). It is only used + * in the factory, uploaded and validated during device registration. + * + * This method is used by provisioning 4 only. + * + * @param[in] challenge: pointer to the buffer containing a byte string to be + * signed. + * @param[in] challenge_length: size of the challenge buffer. + * @param[in] encoded_device_info: pointer to the buffer containing the + * serialized device information in CBOR map format. + * @param[in] encoded_device_info_length: size of the encoded_device_info + * buffer. + * @param[out] signed_csr_payload: pointer to the buffer that receives the + * serialized CSR payload in COSE_Sign1 format. + * @param[in,out] signed_csr_payload_length: on input, size of the caller's + * signed_csr_payload buffer. On output, the number of bytes written into the + * buffer. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_INVALID_CONTEXT if challenge_length or + * encoded_device_info_length is 0, or any pointer is NULL + * @retval OEMCrypto_ERROR_SHORT_BUFFER if signed_csr_payload_length is too + * small to return the signed_csr_payload. + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if provisioning 4 is not supported, + * or device information is not available on the platform. + * + * @threading + * This is a "Property Function" and may be called simultaneously with any + * other property function or session function, but not any initialization or + * usage table function, as if the CDM holds a read lock on the OEMCrypto + * system. + * + * @version + * This method is new in API version 18. + */ +OEMCryptoResult OEMCrypto_GetDeviceSignedCsrPayload( + const uint8_t* challenge, size_t challenge_length, + const uint8_t* encoded_device_info, size_t encoded_device_info_length, + uint8_t* signed_csr_payload, size_t* signed_csr_payload_length); + +/** + * Loads an OEM private key to a session. The key will be used in signing DRM + * certificate request, or the public key generated by calling + * OEMCrypto_GenerateCertificateKeyPair. + * + * @param[in] session: session id. + * @param[in] key_type: type of the leaf key (RSA or ECC). + * @param[in] wrapped_private_key: the encrypted private key. This is the + * wrapped key generated by OEMCrypto_GenerateCertificateKeyPair. + * @param[in] wrapped_private_key_length: length of |wrapped_private_key| in + * bytes. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_NO_DEVICE_KEY + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_KEY + * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * @retval OEMCrypto_ERROR_SESSION_LOST_STATE + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * + * @threading + * This is a "Session Function" and may be called simultaneously with session + * functions for other sessions but not simultaneously with other functions + * for this session. It will not be called simultaneously with initialization + * or usage table functions. It is as if the CDM holds a write lock for this + * session, and a read lock on the OEMCrypto system. + * + * @version + * This method is new in API version 17. + */ +OEMCryptoResult OEMCrypto_InstallOemPrivateKey( + OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type, + const uint8_t* wrapped_private_key, size_t wrapped_private_key_length); /// @} /// @addtogroup test_verify /// @{ +/** + * Enter Test Mode. This enables OEMCrypto test functionality. Without a call to + * this function, none of the test functions](./test-verify) shall be + * enabled. After this function has been called, OEMCrypto will not use the + * production keybox. Once OEMCrypto has entered Test Mode, it will not leave + * Test Mode until the next reboot. + * + * If the device is not in Test Mode, it will be in Production Mode and + * OEMCrypto will use a production root of trust (keybox or OEM Certificate) if + * available. In Production Mode, none of the test functions are enabled. + * + * Widevine recommends shipping a Production Only version of OEMCrypto on + * released devices. A Production Only version of OEMCrypto will have all test + * functions disabled. In this case, OEMCrypto_EnterTestMode() will return + * OEMCRYPTO_ERROR_NOT_IMPLEMENTED. + * + * @retval OEMCrypto_SUCCESS success + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED OEMCrypto is a production build, and + * does not support debug or test-only functions. + * + * @threading + * This is an "Initialization and Termination Function" and will not be + * called simultaneously with any other function, as if the CDM holds a write + * lock on the OEMCrypto system. It is called once after + * OEMCrypto_Initialize(), and before any other test-only functions are + * called. + * + * @version + * This method is new in API version 18. + */ +OEMCryptoResult OEMCrypto_EnterTestMode(void); + /** * Returns the type of hash function supported for Full Decrypt Path Testing. * A hash type of OEMCrypto_Hash_Not_Supported = 0 means this feature is not @@ -5145,138 +5278,15 @@ OEMCryptoResult OEMCrypto_FreeSecureBuffer( OEMCrypto_SESSION session, OEMCrypto_DestBufferDesc* output_descriptor, int secure_fd); -/** - * Loads an OEM private key to a session. The key will be used in signing DRM - * certificate request, or the public key generated by calling - * OEMCrypto_GenerateCertificateKeyPair. - * - * @param[in] session: session id. - * @param[in] key_type: type of the leaf key (RSA or ECC). - * @param[in] wrapped_private_key: the encrypted private key. This is the - * wrapped key generated by OEMCrypto_GenerateCertificateKeyPair. - * @param[in] wrapped_private_key_length: length of |wrapped_private_key| in - * bytes. - * - * @retval OEMCrypto_SUCCESS - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_NO_DEVICE_KEY - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_INVALID_KEY - * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_ERROR_SESSION_LOST_STATE - * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_InstallOemPrivateKey( - OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type, - const uint8_t* wrapped_private_key, size_t wrapped_private_key_length); - /// @} -/** - * This method associates an existing entitled key session to the specified - * OEMCrypto session. - * - * @param[in] key_session: id of the entitled key session. - * @param[in] oec_session: handle for the OEMCrypto session to be associated - * with the entitled key session. - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION - * @retval OEMCrypto_ERROR_INVALID_SESSION - * - * @threading - * This is a "Session Initialization Function" and will not be called - * simultaneously with any other function, as if the CDM holds a write lock - * on the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession( - OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session); - -/** - * The OEMCrypto_LoadCasECMKeys method is added to load content keys into an - * entitled key session, which already has entitlement keys loaded. Used only by - * CAS. - * - * This function will only be called for a session after a call to - * OEMCrypto_LoadKeys with the license_type equal to - * OEMCrypto_EntitlementLicense, and a call to - * OEMCrypto_CreateEntitledKeySession initializing the entitled key session. - * This function may be called multiple times for the same session. - * - * For each key object, odd and even, OEMCrypto shall look up the entry in the - * key table with the corresponding entitlement_key_id. Before the - * entitlement_key is used: - * 1) If no entry is found, return OEMCrypto_KEY_NOT_ENTITLED. - * 2) Check the entitlement key’s key control block use. If failed, return - * corresponding error code such as OEMCrypto_ERROR_ANALOG_OUTPUT, - * OEMCrypto_ERROR_INSUFFICIENT_HDCP. - * 3) If the entitlement key’s control block has a nonzero Duration field, - * then the API shall verify that the duration is greater than the - * session’s elapsed time clock before the key is used. OEMCrypto will - * return OEMCrypto_ERROR_KEY_EXPIRED. - * 4) The content_key_data decrypted using the entitlement_key_data as a key - * for AES-256-CBC with an IV of content_key_data_iv. Wrapped content is - * padded using PKCS#7 padding. Notice that the entitlement key will be an - * AES 256 bit key. The clear content key data will be stored in the - * entry’s content_key_data. - * 5) The decrypted content key data may be set in a hardware KeySlot, - * together with content iv and cipher mode information, which can be used - * by the Descrambler in TunerHal. The entitled key session ID may be used - * as the key token to uniquely identify the content key in KeySlot. - * - * @param[in] session: handle for the entitled key session to be used. - * @param[in] message: pointer to memory containing message to be verified. - * @param[in] message_length: length of the message, in bytes. - * @param[in] even_key: key update for the even ecm key. May be null if the key - * does not change. - * @param[in] odd_key: key update for the odd ecm key. May be null if the key - * does not change. - * - * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_INVALID_SESSION - * @retval OEMCrypto_ERROR_INVALID_CONTEXT - * @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE - * @retval OEMCrypto_KEY_NOT_ENTITLED - * @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION - * @retval OEMCrypto_ERROR_KEY_EXPIRED - * @retval OEMCrypto_ERROR_ANALOG_OUTPUT - * @retval OEMCrypto_ERROR_INSUFFICIENT_HDCP - * - * @threading - * This is a "Session Function" and may be called simultaneously with session - * functions for other sessions but not simultaneously with other functions - * for this session. It will not be called simultaneously with initialization - * or usage table functions. It is as if the CDM holds a write lock for this - * session, and a read lock on the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_LoadCasECMKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const OEMCrypto_EntitledContentKeyObject* even_key, - const OEMCrypto_EntitledContentKeyObject* odd_key); - /* * OEMCrypto_OPK_SerializationVersion + * + * Note: This is an undocumented function. It is only required and used by the + * OPK implementation of OEMCrypto. It is not in a documentation group and does + * not show up on the devsite documentation page. + * * Check the serialization protocol version used by the OEMCrypto Porting Kit * (OPK). If the OPK is not used, this function must return * OEMCrypto_ERROR_NOT_IMPLEMENTED. The serialization version is expressed as @@ -5389,31 +5399,6 @@ OEMCryptoResult OEMCrypto_ProcessOTAKeybox(OEMCrypto_SESSION session, const uint8_t* buffer, size_t buffer_length, uint32_t use_test_key); -/** - * Retrieves the key token associated with the input entitled key session. This - * method is currently used only by CAS, where key token is a means to share - * vendor specific crypto info with other frameworks (e.g. Descrambler in - * Android TunerHAL) that are also under control of the vendor. - * - * @param[in] key_session: handle for the entitled key session to be used. - * @param[out] key_token: where the key token is stored. - * @param[in,out] key_token_length: length of the key token, in bytes. - * - * @retval OEMCrypto_SUCCESS on success - * @retval OEMCrypto_ERROR_SHORT_BUFFER if buffer_length is too small. - * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * - * @threading - * This is an "Initialization and Termination Function" and will not be called - * simultaneously with any other function, as if the CDM holds a write lock on - * the OEMCrypto system. - * - * @version - * This method is new in API version 17. - */ -OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session, - uint8_t* key_token, - size_t* key_token_length); /****************************************************************************/ /****************************************************************************/ @@ -5626,6 +5611,110 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * help with backward compatibility. */ OEMCryptoResult OEMCrypto_RemoveSRM(void); + +/** + * OEMCrypto_LoadKeys + * @deprecated + * OEMCrypto_LoadKeys is only used to load a v15 license or renewal. + */ +OEMCryptoResult OEMCrypto_LoadKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t key_array_length, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type); + +typedef struct { + OEMCrypto_Substring key_id; + OEMCrypto_Substring key_control_iv; + OEMCrypto_Substring key_control; +} OEMCrypto_KeyRefreshObject; +/** + * OEMCrypto_RefreshKeys + * @deprecated + * OEMCrypto_RefreshKeys is only used to load a v15 license or renewal. + */ +OEMCryptoResult OEMCrypto_RefreshKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, size_t num_keys, + const OEMCrypto_KeyRefreshObject* key_array); + +/** + * OEMCrypto_GetRandom + * @deprecated + * OEMCrypto_GetRandom is not needed to export random numbers. + */ +OEMCryptoResult OEMCrypto_GetRandom(uint8_t* random_data, + size_t random_data_length); + +/** + * OEMCrypto_SelectKey + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, + const uint8_t* content_key_id, + size_t content_key_id_length, + OEMCryptoCipherMode cipher_mode); + +/** + * OEMCrypto_DecryptCENC_V17 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_DecryptCENC_V17( + OEMCrypto_SESSION session, const OEMCrypto_SampleDescription* samples, + size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc* pattern); + +/** + * OEMCrypto_Generic_Encrypt_V17 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_Generic_Encrypt_V17( + OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); + +/** + * OEMCrypto_Generic_Decrypt_V17 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_Generic_Decrypt_V17( + OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); + +/** + * OEMCrypto_Generic_Sign_V17 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_Generic_Sign_V17(OEMCrypto_SESSION session, + const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, + OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* signature, + size_t* signature_length); + +/** + * OEMCrypto_Generic_Verify_V17 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_Generic_Verify_V17( + OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + const OEMCrypto_SharedMemory* signature, size_t signature_length); + /****************************************************************************/ /****************************************************************************/ diff --git a/oemcrypto/odk/Android.bp b/oemcrypto/odk/Android.bp index 3b7d807a..544c838f 100644 --- a/oemcrypto/odk/Android.bp +++ b/oemcrypto/odk/Android.bp @@ -14,6 +14,7 @@ package { // all of the 'license_kinds' from "vendor_widevine_license" // to get the below license kinds: // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } @@ -37,6 +38,7 @@ cc_library_static { proprietary: true, owner: "widevine", + min_sdk_version: "UpsideDownCake", } // ---------------------------------------------------------------- @@ -93,6 +95,10 @@ cc_test { "libwv_kdo", ], + shared_libs: [ + "libprotobuf-cpp-lite", + ], + srcs: [ "test/odk_test.cpp", "test/odk_test_helper.cpp", diff --git a/oemcrypto/odk/include/OEMCryptoCENCCommon.h b/oemcrypto/odk/include/OEMCryptoCENCCommon.h index e94f1774..a4e54380 100644 --- a/oemcrypto/odk/include/OEMCryptoCENCCommon.h +++ b/oemcrypto/odk/include/OEMCryptoCENCCommon.h @@ -106,6 +106,8 @@ typedef enum OEMCryptoResult { OPK_ERROR_REMOTE_CALL = OPK_ERROR_BASE, OPK_ERROR_INCOMPATIBLE_VERSION = OPK_ERROR_BASE + 1, OPK_ERROR_NO_PERSISTENT_DATA = OPK_ERROR_BASE + 2, + OPK_ERROR_PREHOOK_FAILURE = OPK_ERROR_BASE + 3, + OPK_ERROR_POSTHOOK_FAILURE = OPK_ERROR_BASE + 4, } OEMCryptoResult; /* clang-format on */ @@ -143,8 +145,19 @@ typedef enum OEMCrypto_PrivateKeyType { } OEMCrypto_PrivateKeyType; /** - * Used to indicate a substring of a signed message in OEMCrypto_LoadKeys and - * other functions which must verify that a parameter is contained within a + * The base for (delayed) timers, i.e. from what time the (delayed) timer + * starts. + */ +typedef enum OEMCrypto_TimerDelayBase { + OEMCrypto_License_Start = 0, + OEMCrypto_License_Load = 1, + OEMCrypto_First_Decrypt = 2, + OEMCrypto_TimerDelayBase_MaxValue = OEMCrypto_First_Decrypt, +} OEMCrypto_TimerDelayBase; + +/** + * Used to indicate a substring of a signed message in ODK_ParseLicense + * and other functions which must verify that a parameter is contained within a * signed message. */ typedef struct { @@ -210,7 +223,7 @@ typedef struct { /** * Points to the relevant fields for a content key. The fields are extracted - * from the License Response message offered to OEMCrypto_LoadKeys(). Each + * from the License Response message offered to ODK_ParseLicense(). Each * field points to one of the components of the key. Key data, key control, * and both IV fields are 128 bits (16 bytes): * @param key_id: the unique id of this key. @@ -227,7 +240,7 @@ typedef struct { * the content key from the key_data field. * * The memory for the OEMCrypto_KeyObject fields is allocated and freed - * by the caller of OEMCrypto_LoadKeys(). + * by the caller of ODK_ParseLicense(). */ typedef struct { OEMCrypto_Substring key_id; diff --git a/oemcrypto/odk/include/core_message_deserialize.h b/oemcrypto/odk/include/core_message_deserialize.h index 545a8062..a52c5fd8 100644 --- a/oemcrypto/odk/include/core_message_deserialize.h +++ b/oemcrypto/odk/include/core_message_deserialize.h @@ -55,6 +55,18 @@ bool CoreProvisioningRequestFromMessage( const std::string& oemcrypto_core_message, ODK_ProvisioningRequest* core_provisioning_request); +/** + * Counterpart (deserializer) of ODK_PrepareCoreProvisioning40Request + * (serializer) + * + * Parameters: + * [in] oemcrypto_core_message + * [out] core_provisioning_request + */ +bool CoreProvisioning40RequestFromMessage( + const std::string& oemcrypto_core_message, + ODK_Provisioning40Request* core_provisioning_request); + /** * Counterpart (deserializer) of ODK_PrepareCoreRenewedProvisioningRequest * (serializer) diff --git a/oemcrypto/odk/include/core_message_features.h b/oemcrypto/odk/include/core_message_features.h index 42c41ba9..01cdda8f 100644 --- a/oemcrypto/odk/include/core_message_features.h +++ b/oemcrypto/odk/include/core_message_features.h @@ -8,6 +8,7 @@ #include #include +#include #include namespace oemcrypto_core_message { @@ -25,8 +26,8 @@ struct CoreMessageFeatures { // This is the published version of the ODK Core Message library. The default // behavior is for the server to restrict messages to at most this version - // number. The default is 17.2. - uint32_t maximum_major_version = 17; + // number. The default is 18.2. + uint32_t maximum_major_version = 18; uint32_t maximum_minor_version = 2; bool operator==(const CoreMessageFeatures &other) const; diff --git a/oemcrypto/odk/include/core_message_serialize.h b/oemcrypto/odk/include/core_message_serialize.h index bd6d6354..a76b79fd 100644 --- a/oemcrypto/odk/include/core_message_serialize.h +++ b/oemcrypto/odk/include/core_message_serialize.h @@ -39,7 +39,7 @@ using oemcrypto_core_message::features::CoreMessageFeatures; * [out] oemcrypto_core_message */ bool CreateCoreLicenseResponse(const CoreMessageFeatures& features, - const ODK_ParsedLicense& parsed_lic, + const ODK_Packing_ParsedLicense& parsed_lic, const ODK_LicenseRequest& core_request, const std::string& core_request_sha256, std::string* oemcrypto_core_message); @@ -72,6 +72,21 @@ bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features, const ODK_ParsedProvisioning& parsed_prov, const ODK_ProvisioningRequest& core_request, std::string* oemcrypto_core_message); + +/** + * Counterpart (serializer) of ODK_ParseProvisioning40 (deserializer) + * struct-input variant + * + * Parameters: + * [in] features feature support for response message. + * [in] core_request + * [out] oemcrypto_core_message + */ +bool CreateCoreProvisioning40Response( + const CoreMessageFeatures& features, + const ODK_Provisioning40Request& core_request, + std::string* oemcrypto_core_message); + } // namespace serialize } // namespace oemcrypto_core_message diff --git a/oemcrypto/odk/include/core_message_serialize_proto.h b/oemcrypto/odk/include/core_message_serialize_proto.h index de753620..73d7b738 100644 --- a/oemcrypto/odk/include/core_message_serialize_proto.h +++ b/oemcrypto/odk/include/core_message_serialize_proto.h @@ -17,6 +17,7 @@ #include #include +#include "OEMCryptoCENCCommon.h" #include "core_message_features.h" #include "core_message_types.h" #include "license_protocol.pb.h" @@ -42,8 +43,8 @@ bool CreateCoreLicenseResponseFromProto( const oemcrypto_core_message::features::CoreMessageFeatures& features, const std::string& serialized_license, const ODK_LicenseRequest& core_request, - const std::string& core_request_sha256, const bool nonce_required, - const bool uses_padding, std::string* oemcrypto_core_message); + const std::string& core_request_sha256, bool nonce_required, + bool uses_padding, std::string* oemcrypto_core_message); /** * Counterpart (serializer) of ODK_ParseProvisioning (deserializer) @@ -59,6 +60,7 @@ bool CreateCoreProvisioningResponseFromProto( const oemcrypto_core_message::features::CoreMessageFeatures& features, const std::string& serialized_provisioning_response, const ODK_ProvisioningRequest& core_request, + OEMCrypto_PrivateKeyType device_key_type, std::string* oemcrypto_core_message); } // namespace serialize diff --git a/oemcrypto/odk/include/core_message_types.h b/oemcrypto/odk/include/core_message_types.h index 5315913e..d268aeff 100644 --- a/oemcrypto/odk/include/core_message_types.h +++ b/oemcrypto/odk/include/core_message_types.h @@ -30,23 +30,25 @@ * KDO provides a corresponding writer. * * Table: ODK vs KDO (s: serialize; d: deserialize) - * +----------------------------------------+---------------------------------------+ - * | ODK | KDO | - * +---+------------------------------------+---+-----------------------------------+ - * | s | ODK_PrepareCoreLicenseRequest | d | CoreLicenseRequestFromMessage | - * | +------------------------------------+ +-----------------------------------+ - * | | ODK_PrepareCoreRenewalRequest | | CoreRenewalRequestFromMessage | - * | +------------------------------------+ +-----------------------------------+ - * | | ODK_PrepareCoreProvisioningRequest | | CoreProvisioningRequestFromMessage| - * | +------------------------------------+ +-----------------------------------+ - * | | ODK_PrepareCommonRequest | | CoreCommonRequestFromMessage | - * +---+------------------------------------+---+-----------------------------------+ - * | d | ODK_ParseLicense | s | CreateCoreLicenseResponse | - * | +------------------------------------+ +-----------------------------------+ - * | | ODK_ParseRenewal | | CreateCoreRenewalResponse | - * | +------------------------------------+ +-----------------------------------+ - * | | ODK_ParseProvisioning | | CreateCoreProvisioningResponse | - * +---+------------------------------------+---+-----------------------------------+ + * +------------------------------------------+------------------------------------------+ + * | ODK | KDO | + * +---+--------------------------------------+---+--------------------------------------+ + * | s | ODK_PrepareCoreLicenseRequest | d | CoreLicenseRequestFromMessage | + * | +--------------------------------------+ +--------------------------------------+ + * | | ODK_PrepareCoreRenewalRequest | | CoreRenewalRequestFromMessage | + * | +--------------------------------------+ +--------------------------------------+ + * | | ODK_PrepareCoreProvisioningRequest | | CoreProvisioningRequestFromMessage | + * | | ODK_PrepareCoreProvisioning40Request | | CoreProvisioning40RequestFromMessage | + * | +--------------------------------------+ +--------------------------------------+ + * | | ODK_PrepareCommonRequest | | CoreCommonRequestFromMessage | + * +---+--------------------------------------+---+--------------------------------------+ + * | d | ODK_ParseLicense | s | CreateCoreLicenseResponse | + * | +--------------------------------------+ +--------------------------------------+ + * | | ODK_ParseRenewal | | CreateCoreRenewalResponse | + * | +--------------------------------------+ +--------------------------------------+ + * | | ODK_ParseProvisioning | | CreateCoreProvisioningResponse | + * | | ODK_ParseProvisioning40 | | CreateCoreProvisioning40Response | + * +---+--------------------------------------+---+--------------------------------------+ * *********************************************************************/ // clang-format on @@ -66,12 +68,27 @@ namespace oemcrypto_core_message { * Input structure for CreateCommonResponse */ struct ODK_CommonRequest { + uint32_t message_type; + uint32_t message_length; uint16_t api_minor_version; uint16_t api_major_version; uint32_t nonce; uint32_t session_id; }; +struct ODK_MessageCounter { + uint64_t master_generation_number; + uint32_t provisioning_count; + uint32_t license_count; + uint32_t decrypt_count; + uint16_t major_version; + uint16_t minor_version; + uint16_t patch_version; + uint8_t soc_vendor[16]; + uint8_t chipset_model[16]; + uint8_t extra[12]; +}; + /** * Output structure for CoreLicenseRequestFromMessage * Input structure for CreateCoreLicenseResponse @@ -81,6 +98,7 @@ struct ODK_LicenseRequest { uint16_t api_major_version; uint32_t nonce; uint32_t session_id; + ODK_MessageCounter counter_info; }; /** @@ -108,6 +126,20 @@ struct ODK_ProvisioningRequest { std::string device_id; uint16_t renewal_type; std::string renewal_data; + ODK_MessageCounter counter_info; +}; + +/** + * Output structure for CoreProvisioningRequest40FromMessage + * Input structure for CreateCoreProvisioning40Response + */ +struct ODK_Provisioning40Request { + uint16_t api_minor_version; + uint16_t api_major_version; + uint32_t nonce; + uint32_t session_id; + std::string device_info; + ODK_MessageCounter counter_info; }; } // namespace oemcrypto_core_message diff --git a/oemcrypto/odk/include/odk.h b/oemcrypto/odk/include/odk.h index e3499da2..16af94af 100644 --- a/oemcrypto/odk/include/odk.h +++ b/oemcrypto/odk/include/odk.h @@ -259,6 +259,8 @@ OEMCryptoResult ODK_DeactivateUsageEntry(ODK_ClockValues* clock_values); * of the message. (in) size of buffer reserved for the core message, in * bytes. (out) actual length of the core message, in bytes. * @param[in] nonce_values: pointer to the session's nonce data. + * @param[in] message_count_info: information used for server-side anomaly + * detection * * @retval OEMCrypto_SUCCESS * @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small @@ -269,7 +271,8 @@ OEMCryptoResult ODK_DeactivateUsageEntry(ODK_ClockValues* clock_values); */ OEMCryptoResult ODK_PrepareCoreLicenseRequest( uint8_t* message, size_t message_length, size_t* core_message_size, - const ODK_NonceValues* nonce_values); + const ODK_NonceValues* nonce_values, + const ODK_MessageCounterInfo* counter_info); /** * Modifies the message to include a core renewal request at the beginning of @@ -337,11 +340,8 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message, * of the message. (in) size of buffer reserved for the core message, in * bytes. (out) actual length of the core message, in bytes. * @param[in] nonce_values: pointer to the session's nonce data. - * @param[in] device_id: For devices with a keybox, this is the device ID from - * the keybox. For devices with an OEM Certificate, this is a device - * unique id string. - * @param[in] device_id_length: length of device_id. The device ID can be at - * most 64 bytes. + * @param[in] message_count_info: information used for server-side anomaly + * detection * * @retval OEMCrypto_SUCCESS * @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small @@ -352,8 +352,44 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message, */ OEMCryptoResult ODK_PrepareCoreProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, - const ODK_NonceValues* nonce_values, const uint8_t* device_id, - size_t device_id_length); + const ODK_NonceValues* nonce_values, + const ODK_MessageCounterInfo* counter_info); + +/** + * Modifies the message to include a core provisioning 4.0 request at the + * beginning of the message buffer. The values in nonce_values are used to + * populate the message. + * + * This shall be called by OEMCrypto from + * OEMCrypto_PrepAndSignProvisioningRequest. + * + * NOTE: if the message pointer is null and/or input core_message_length is + * zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output + * core_message_size to the size needed. + * + * @param[in,out] message: Pointer to memory for the entire message. Modified by + * the ODK library. + * @param[in] message_length: length of the entire message buffer. + * @param[in,out] core_message_size: length of the core message at the beginning + * of the message. (in) size of buffer reserved for the core message, in + * bytes. (out) actual length of the core message, in bytes. + * @param[in] nonce_values: pointer to the session's nonce data. + * @param[in] device_info: Encoded device hardware info in CBOR format. + * @param[in] device_info_length: length of device_info. + * @param[in] message_count_info: information used for server-side anomaly + * detection + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * + * @version + * This method is new in version 18 of the API. + */ +OEMCryptoResult ODK_PrepareCoreProvisioning40Request( + uint8_t* message, size_t message_length, size_t* core_message_length, + const ODK_NonceValues* nonce_values, const uint8_t* device_info, + size_t device_info_length, const ODK_MessageCounterInfo* counter_info); /** * Modifies the message to include a core renewal provisioning request at the @@ -515,6 +551,7 @@ OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits, * and false when called for OEMCrypto_ReloadLicense. * @param[in] usage_entry_present: true if the session has a new usage entry * associated with it created via OEMCrypto_CreateNewUsageEntry. + * @param[in] system_time_seconds: The current system's time in seconds. * @param[in,out] timer_limits: The session's timer limits. These will be * updated. * @param[in,out] clock_values: The session's clock values. These will be @@ -522,13 +559,19 @@ OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits, * @param[in,out] nonce_values: The session's nonce values. These will be * updated. * @param[out] parsed_license: the destination for the data. + * @param[out] timer_value: set if playback timer should be started. * * @retval OEMCrypto_SUCCESS * @retval ODK_ERROR_CORE_MESSAGE: if the message did not parse correctly, or * there were other incorrect values. An error should be returned to the * CDM layer. * @retval ODK_UNSUPPORTED_API - * @retval OEMCrypto_ERROR_INVALID_NONCE + * @retval ODK_SET_TIMER: if the playback timer has been started successfully + * @retval ODK_DISABLE_TIMER: if the playtime timer has been started + * successfully then is disabled. + * @retval ODK_TIMER_EXPIRED: if the license is attempted to be loaded after the + * rental duration expires. + * @retval OEMCrypto_ERROR_INVALåID_NONCE * * @version * This method is new in version 16 of the API. @@ -536,8 +579,9 @@ OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits, OEMCryptoResult ODK_ParseLicense( const uint8_t* message, size_t message_length, size_t core_message_length, bool initial_license_load, bool usage_entry_present, - ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values, - ODK_NonceValues* nonce_values, ODK_ParsedLicense* parsed_license); + uint64_t system_time_seconds, ODK_TimerLimits* timer_limits, + ODK_ClockValues* clock_values, ODK_NonceValues* nonce_values, + ODK_ParsedLicense* parsed_license, uint64_t* timer_value); /** * The function ODK_ParseRenewal will parse the message and verify its @@ -564,7 +608,8 @@ OEMCryptoResult ODK_ParseLicense( * @param[in] message_length: length of the entire message buffer. * @param[in] core_message_size: length of the core message, at the beginning of * the message buffer. - * @param[in] nonce_values: pointer to the session's nonce data. + * @param[in,out] nonce_values: pointer to the session's nonce data. These might + * be updated if the server returns a lower API version. * @param[in] system_time_seconds: the current time on OEMCrypto's clock, in * seconds. * @param[in] timer_limits: timer limits specified in the license. @@ -591,7 +636,7 @@ OEMCryptoResult ODK_ParseLicense( */ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, size_t core_message_length, - const ODK_NonceValues* nonce_values, + ODK_NonceValues* nonce_values, uint64_t system_time_seconds, const ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values, @@ -604,8 +649,8 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, * If the message does not parse correctly, ODK_ParseProvisioning will return * an error that OEMCrypto should return to the CDM layer above. * - * If the API in the message is larger than 16, then ODK_UNSUPPORTED_API is - * returned. + * If the API in the message is larger than ODK_MAJOR_VERSION, then + * ODK_UNSUPPORTED_API is returned. * * ODK_ParseProvisioning shall verify that nonce_values->nonce and * nonce_values->session_id are the same as those in the message. Otherwise @@ -620,11 +665,13 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, * @param[in] message_length: length of the entire message buffer. * @param[in] core_message_size: length of the core message, at the beginning of * the message buffer. - * @param[in] nonce_values: pointer to the session's nonce data. + * @param[in/out] nonce_values: pointer to the session's nonce data. These might + * be updated if the server returns a lower API version. * @param[in] device_id: a pointer to a buffer containing the device ID of the * device. The ODK function will verify it matches that in the message. * @param[in] device_id_length: the length of the device ID. - * @param[out] parsed_response: destination for the parse data. + * @param[out] counter_info: destination for counter portion of parse data. + * @param[out] parsed_response: destination for response portion of parse data. * * @retval OEMCrypto_SUCCESS * @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there @@ -638,9 +685,45 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, */ OEMCryptoResult ODK_ParseProvisioning( const uint8_t* message, size_t message_length, size_t core_message_length, - const ODK_NonceValues* nonce_values, const uint8_t* device_id, + ODK_NonceValues* nonce_values, const uint8_t* device_id, size_t device_id_length, ODK_ParsedProvisioning* parsed_response); +/** + * The function ODK_ParseProvisioning40 will parse the message and verify the + * nonce values match those in the request. + * + * If the message does not parse correctly, ODK_ParseProvisioning40 will return + * an error that OEMCrypto should return to the CDM layer above. + * + * If the API in the message is larger than ODK_MAJOR_VERSION, then + * ODK_UNSUPPORTED_API is returned. + * + * ODK_ParseProvisioning40 shall verify that nonce_values->nonce and + * nonce_values->session_id are the same as those in the message. Otherwise + * it shall return OEMCrypto_ERROR_INVALID_NONCE. + * + * @param[in] message: pointer to the message buffer. + * @param[in] message_length: length of the entire message buffer. + * @param[in] core_message_size: length of the core message, at the beginning of + * the message buffer. + * @param[in,out] nonce_values: pointer to the session's nonce data. These might + * be updated if the server returns a lower API version. + * + * @retval OEMCrypto_SUCCESS + * @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there + * were other incorrect values. An error should be returned to the CDM + * layer. + * @retval ODK_UNSUPPORTED_API + * @retval OEMCrypto_ERROR_INVALID_NONCE + * + * @version + * This method is new in version 18 of the API. + */ +OEMCryptoResult ODK_ParseProvisioning40(const uint8_t* message, + size_t message_length, + size_t core_message_length, + ODK_NonceValues* nonce_values); + /** * The function ODK_ParseProvisioning will parse the message and verify the * API version is at most the version passed in. diff --git a/oemcrypto/odk/include/odk_structs.h b/oemcrypto/odk/include/odk_structs.h index 78e8b6a7..457617e0 100644 --- a/oemcrypto/odk/include/odk_structs.h +++ b/oemcrypto/odk/include/odk_structs.h @@ -15,11 +15,11 @@ extern "C" { #include "odk_target.h" /* The version of this library. */ -#define ODK_MAJOR_VERSION 17 +#define ODK_MAJOR_VERSION 18 #define ODK_MINOR_VERSION 2 /* ODK Version string. Date changed automatically on each release. */ -#define ODK_RELEASE_DATE "ODK v17.2 2022-11-21" +#define ODK_RELEASE_DATE "ODK v18.2 2023-06-14" /* The lowest version number for an ODK message. */ #define ODK_FIRST_VERSION 16 @@ -28,6 +28,11 @@ extern "C" { #define ODK_DEVICE_ID_LEN_MAX 64 #define ODK_SHA256_HASH_SIZE 32 #define ODK_KEYBOX_RENEWAL_DATA_SIZE 1600 +/* The max length of the encoded device info in CBOR format. Make sure it gets + * updated when more device info is included. Refer to + * https://www.rfc-editor.org/rfc/rfc8949.html#name-specification-of-the-cbor-e + * for an estimation of the required length. */ +#define ODK_DEVICE_INFO_LEN_MAX 768 /// @addtogroup odk_timer /// @{ @@ -92,7 +97,8 @@ typedef struct { * * @param time_of_license_request_signed: Time that the license request was * signed, based on OEMCrypto's system clock. This value shall be stored - * and reloaded with usage entry as time_of_license_received. + * and reloaded with usage entry as time_of_license_received. This is + * also used to track the start of the rental clock time. * @param time_of_first_decrypt: Time of the first decrypt or call select key, * based on OEMCrypto's system clock. This is 0 if the license has not * been used to decrypt any data. This value shall be stored and reloaded @@ -161,6 +167,47 @@ typedef struct { /// @addtogroup odk_parser /// @{ +/** + * This counter information is used by the license and provisioning servers to + * keep track of requests. Values should be updated after every successful + * provisioning request, license request, and decrypt call. + * + * @param provisioning_count: number of times a provisioning request was made on + * this device in the current instance. May be reset to 0 on device power off. + * @param license_count: number of times a license request was made on this + * device in the current instance. May be reset to 0 on device power off. + * @param decrypt_count: number of times OEMCrypto_DecryptCENC() has been called + * on this device in the current instance. May be reset to 0 on device power + * off. + * @param master_generation_number: current master generation number value from + * the OEMCrypto usage table. Persists across reboots. + * @param soc_vendor: name of the system-on-a-chip vendor for the device, + * limited to 16 bytes + * @param chipset_model: name of the chipset on the device, limited to 16 bytes + * @param major_version: major version of the TA binary. This is different from + * the OEMCrypto version that is being implemented. + * @param minor_version: minor version of the TA binary, if applicable. This is + * different from the OEMCrypto version that is being implemented. + * @param patch_version: patch version of the TA binary, if applicable. This is + * different from the OEMCrypto version that is being implemented. + * @param extra: unused in V18 + * + * @version + * This struct was added in API version 18. + */ +typedef struct { + uint64_t master_generation_number; + uint32_t provisioning_count; + uint32_t license_count; + uint32_t decrypt_count; + uint16_t major_version; + uint16_t minor_version; + uint16_t patch_version; + uint8_t soc_vendor[16]; + uint8_t chipset_model[16]; + uint8_t extra[12]; +} ODK_MessageCounterInfo; + /** * The parsed license structure contains information from the license * message. The function ODK_ParseLicense will fill in the fields of this @@ -178,11 +225,12 @@ typedef struct { * @param timer_limits: time limits of the for the license. * @param watermarking: specifies if device supports watermarking. * @param dtcp2_required: specifies if device supports DTCP. + * @param renewal_delay_base: what time the timer starting is based off of. * @param key_array_length: number of keys present. * @param key_array: set of keys to be installed. * * @version - * This struct changed in API version 17. + * This struct changed in API version 18. */ typedef struct { OEMCrypto_Substring enc_mac_keys_iv; @@ -194,10 +242,51 @@ typedef struct { ODK_TimerLimits timer_limits; uint32_t watermarking; OEMCrypto_DTCP2_CMI_Packet dtcp2_required; + OEMCrypto_TimerDelayBase renewal_delay_base; uint32_t key_array_length; OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS]; } ODK_ParsedLicense; +/** + * The parsed license structure contains information from the license + * message. The function ODK_ParseLicense will fill in the fields of this + * message. All substrings are contained within the message body. + * + * @param enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits. + * @param enc_mac_keys: encrypted mac_keys for generating new mac_keys. Size is + * 512 bits. + * @param pst: the Provider Session Token. + * @param srm_restriction_data: optional data specifying the minimum SRM + * version. + * @param license_type: specifies if the license contains content keys or + * entitlement keys. + * @param nonce_required: indicates if the license requires a nonce. + * @param timer_limits: time limits of the for the license. + * @param watermarking: specifies if device supports watermarking. + * @param dtcp2_required: specifies if device supports DTCP. + * @param renewal_delay_base: what time the timer starting is based off of. + * @param key_array_length: number of keys present. + * @param key_array: set of keys to be installed. This is a pointer to an array + * to allow packing a number of keys greater than |ODK_MAX_NUM_KEYS|. + * + * @version + * This struct changed in API version 18. + */ +typedef struct { + OEMCrypto_Substring enc_mac_keys_iv; + OEMCrypto_Substring enc_mac_keys; + OEMCrypto_Substring pst; + OEMCrypto_Substring srm_restriction_data; + OEMCrypto_LicenseType license_type; + bool nonce_required; + ODK_TimerLimits timer_limits; + uint32_t watermarking; + OEMCrypto_DTCP2_CMI_Packet dtcp2_required; + OEMCrypto_TimerDelayBase renewal_delay_base; + uint32_t key_array_length; + OEMCrypto_KeyObject* key_array; +} ODK_Packing_ParsedLicense; + /** * The parsed provisioning structure contains information from the license * message. The function ODK_ParseProvisioning will fill in the fields of diff --git a/oemcrypto/odk/src/core_message_deserialize.cpp b/oemcrypto/odk/src/core_message_deserialize.cpp index 2e69641d..30e68c4e 100644 --- a/oemcrypto/odk/src/core_message_deserialize.cpp +++ b/oemcrypto/odk/src/core_message_deserialize.cpp @@ -11,10 +11,10 @@ #include #include "OEMCryptoCENCCommon.h" +#include "odk_message.h" #include "odk_serialize.h" #include "odk_structs.h" #include "odk_structs_priv.h" -#include "serialization_base.h" namespace oemcrypto_core_message { namespace deserialize { @@ -89,12 +89,62 @@ bool ParseRequest(uint32_t message_type, } // namespace +static bool GetNonceFromMessage(const std::string& oemcrypto_core_message, + ODK_NonceValues* nonce_values) { + if (nonce_values == nullptr) return false; + if (oemcrypto_core_message.size() < sizeof(ODK_CoreMessage)) return false; + + ODK_CoreMessage core_message; + const uint8_t* buf = + reinterpret_cast(oemcrypto_core_message.c_str()); + ODK_Message msg = ODK_Message_Create(const_cast(buf), + oemcrypto_core_message.size()); + ODK_Message_SetSize(&msg, sizeof(ODK_CoreMessage)); + Unpack_ODK_CoreMessage(&msg, &core_message); + if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK) return false; + *nonce_values = core_message.nonce_values; + return true; +} + +bool CopyCounterInfo(ODK_MessageCounter* dest, ODK_MessageCounterInfo* src) { + if (!src || !dest) return false; + + dest->master_generation_number = src->master_generation_number; + dest->license_count = src->license_count; + dest->provisioning_count = src->provisioning_count; + dest->decrypt_count = src->decrypt_count; + dest->major_version = src->major_version; + dest->minor_version = src->minor_version; + dest->patch_version = src->patch_version; + memcpy(&dest->soc_vendor, &src->soc_vendor, sizeof(dest->soc_vendor)); + memcpy(&dest->chipset_model, &src->chipset_model, + sizeof(dest->chipset_model)); + memcpy(&dest->extra, &src->extra, sizeof(dest->extra)); + return true; +} + bool CoreLicenseRequestFromMessage(const std::string& oemcrypto_core_message, ODK_LicenseRequest* core_license_request) { + ODK_NonceValues nonce; + if (!GetNonceFromMessage(oemcrypto_core_message, &nonce)) return false; + if (nonce.api_major_version <= 17) { + const auto unpacker = Unpack_ODK_PreparedLicenseRequestV17; + ODK_PreparedLicenseRequestV17 prepared_license = {}; + return ParseRequest(ODK_License_Request_Type, oemcrypto_core_message, + core_license_request, &prepared_license, unpacker); + } const auto unpacker = Unpack_ODK_PreparedLicenseRequest; ODK_PreparedLicenseRequest prepared_license = {}; - return ParseRequest(ODK_License_Request_Type, oemcrypto_core_message, - core_license_request, &prepared_license, unpacker); + if (!ParseRequest(ODK_License_Request_Type, oemcrypto_core_message, + core_license_request, &prepared_license, unpacker)) { + return false; + } + if (!CopyCounterInfo(&core_license_request->counter_info, + &prepared_license.counter_info)) { + return false; + } + + return true; } bool CoreRenewalRequestFromMessage(const std::string& oemcrypto_core_message, @@ -112,26 +162,82 @@ bool CoreRenewalRequestFromMessage(const std::string& oemcrypto_core_message, bool CoreProvisioningRequestFromMessage( const std::string& oemcrypto_core_message, ODK_ProvisioningRequest* core_provisioning_request) { - const auto unpacker = Unpack_ODK_PreparedProvisioningRequest; - ODK_PreparedProvisioningRequest prepared_provision = {}; - if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message, + // Need to partially parse in order to get the nonce values, which will tell + // us the major/minor version + ODK_NonceValues nonce; + if (!GetNonceFromMessage(oemcrypto_core_message, &nonce)) return false; + + if (nonce.api_major_version == 18) { + // Use special case unpacker for v18.0 + const auto unpacker = nonce.api_minor_version == 0 + ? Unpack_ODK_PreparedProvisioningRequestV180 + : Unpack_ODK_PreparedProvisioningRequest; + ODK_PreparedProvisioningRequest prepared_provision = {}; + + if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message, + core_provisioning_request, &prepared_provision, + unpacker)) { + return false; + } + + if (!CopyCounterInfo(&core_provisioning_request->counter_info, + &prepared_provision.counter_info)) { + return false; + } + } else { + // V17 and older + const auto unpacker = Unpack_ODK_PreparedProvisioningRequestV17; + ODK_PreparedProvisioningRequestV17 prepared_provision = {}; + if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message, + core_provisioning_request, &prepared_provision, + unpacker)) { + return false; + } + const uint8_t* device_id = prepared_provision.device_id; + const uint32_t device_id_length = prepared_provision.device_id_length; + if (device_id_length > ODK_DEVICE_ID_LEN_MAX) { + return false; + } + if (device_id_length > 0) { + uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {}; + if (memcmp(zero, device_id + device_id_length, + ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) { + return false; + } + core_provisioning_request->device_id.assign( + reinterpret_cast(device_id), device_id_length); + } + core_provisioning_request->renewal_type = OEMCrypto_NoRenewal; + core_provisioning_request->renewal_data.clear(); + } + return true; +} + +bool CoreProvisioning40RequestFromMessage( + const std::string& oemcrypto_core_message, + ODK_Provisioning40Request* core_provisioning_request) { + const auto unpacker = Unpack_ODK_PreparedProvisioning40Request; + ODK_PreparedProvisioning40Request prepared_provision = {}; + if (!ParseRequest(ODK_Provisioning40_Request_Type, oemcrypto_core_message, core_provisioning_request, &prepared_provision, unpacker)) { return false; } - const uint8_t* device_id = prepared_provision.device_id; - const uint32_t device_id_length = prepared_provision.device_id_length; - if (device_id_length > ODK_DEVICE_ID_LEN_MAX) { + if (!CopyCounterInfo(&core_provisioning_request->counter_info, + &prepared_provision.counter_info)) { return false; } - uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {}; - if (memcmp(zero, device_id + device_id_length, - ODK_DEVICE_ID_LEN_MAX - device_id_length)) { + const uint8_t* device_info = prepared_provision.device_info; + const uint32_t device_info_length = prepared_provision.device_info_length; + if (device_info_length > ODK_DEVICE_INFO_LEN_MAX) { return false; } - core_provisioning_request->device_id.assign( - reinterpret_cast(device_id), device_id_length); - core_provisioning_request->renewal_type = OEMCrypto_NoRenewal; - core_provisioning_request->renewal_data.clear(); + uint8_t zero[ODK_DEVICE_INFO_LEN_MAX] = {}; + if (memcmp(zero, device_info + device_info_length, + ODK_DEVICE_INFO_LEN_MAX - device_info_length) != 0) { + return false; + } + core_provisioning_request->device_info.assign( + reinterpret_cast(device_info), device_info_length); return true; } @@ -152,7 +258,7 @@ bool CoreRenewedProvisioningRequestFromMessage( } uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {}; if (memcmp(zero, device_id + device_id_length, - ODK_DEVICE_ID_LEN_MAX - device_id_length)) { + ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) { return false; } core_provisioning_request->device_id.assign( @@ -173,8 +279,16 @@ bool CoreCommonRequestFromMessage(const std::string& oemcrypto_core_message, ODK_CommonRequest* common_request) { const auto unpacker = Unpack_ODK_PreparedCommonRequest; ODK_PreparedCommonRequest prepared_common = {}; - return ParseRequest(ODK_Common_Request_Type, oemcrypto_core_message, - common_request, &prepared_common, unpacker); + const bool success = + ParseRequest(ODK_Common_Request_Type, oemcrypto_core_message, + common_request, &prepared_common, unpacker); + + if (success) { + const auto& core_message = prepared_common.core_message; + common_request->message_type = core_message.message_type; + common_request->message_length = core_message.message_length; + } + return success; } } // namespace deserialize diff --git a/oemcrypto/odk/src/core_message_features.cpp b/oemcrypto/odk/src/core_message_features.cpp index 60431f7d..6ee2a250 100644 --- a/oemcrypto/odk/src/core_message_features.cpp +++ b/oemcrypto/odk/src/core_message_features.cpp @@ -4,6 +4,8 @@ #include "core_message_features.h" +#include + namespace oemcrypto_core_message { namespace features { const CoreMessageFeatures CoreMessageFeatures::kDefaultFeatures; @@ -25,6 +27,9 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures( case 17: features.maximum_minor_version = 2; // 17.2 break; + case 18: + features.maximum_minor_version = 2; // 18.2 + break; default: features.maximum_minor_version = 0; } diff --git a/oemcrypto/odk/src/core_message_serialize.cpp b/oemcrypto/odk/src/core_message_serialize.cpp index 3c3590ef..5edd3525 100644 --- a/oemcrypto/odk/src/core_message_serialize.cpp +++ b/oemcrypto/odk/src/core_message_serialize.cpp @@ -25,13 +25,13 @@ namespace { * computing the API version of the response. * * Template arguments: - * T: struct to be deserialized by odk * S: kdo input struct */ -template +template bool CreateResponseHeader(const CoreMessageFeatures& features, - ODK_MessageType message_type, const S& core_request, - T& response) { + ODK_MessageType message_type, + ODK_CoreMessage* response_header, + const S& core_request) { // Bad major version. if ((features.maximum_major_version > ODK_MAJOR_VERSION) || (features.maximum_major_version == ODK_MAJOR_VERSION && @@ -40,20 +40,24 @@ bool CreateResponseHeader(const CoreMessageFeatures& features, return false; } - auto* header = &response.request.core_message; - header->message_type = message_type; - header->nonce_values.api_major_version = core_request.api_major_version; - header->nonce_values.api_minor_version = core_request.api_minor_version; - header->nonce_values.nonce = core_request.nonce; - header->nonce_values.session_id = core_request.session_id; + response_header->message_type = message_type; + response_header->nonce_values.api_major_version = + core_request.api_major_version; + response_header->nonce_values.api_minor_version = + core_request.api_minor_version; + response_header->nonce_values.nonce = core_request.nonce; + response_header->nonce_values.session_id = core_request.session_id; // The message API version for the response is the minimum of our version and // the request's version. if (core_request.api_major_version > features.maximum_major_version) { - header->nonce_values.api_major_version = features.maximum_major_version; - header->nonce_values.api_minor_version = features.maximum_minor_version; + response_header->nonce_values.api_major_version = + features.maximum_major_version; + response_header->nonce_values.api_minor_version = + features.maximum_minor_version; } else if (core_request.api_major_version == features.maximum_major_version && core_request.api_minor_version > features.maximum_minor_version) { - header->nonce_values.api_minor_version = features.maximum_minor_version; + response_header->nonce_values.api_minor_version = + features.maximum_minor_version; } return true; } @@ -63,19 +67,18 @@ bool CreateResponseHeader(const CoreMessageFeatures& features, * * Template arguments: * T: struct to be deserialized by odk - * S: kdo input struct * P: auto-generated serializing function for |T| */ -template -bool CreateResponse(ODK_MessageType message_type, const S& core_request, - std::string* oemcrypto_core_message, T& response, +template +bool CreateResponse(ODK_MessageType message_type, + std::string* oemcrypto_core_message, + ODK_CoreMessage* response_header, T& response, const P& packer) { if (!oemcrypto_core_message) { return false; } - auto* header = &response.request.core_message; - if (header->message_type != message_type || - header->nonce_values.api_major_version < ODK_FIRST_VERSION) { + if (response_header->message_type != message_type || + response_header->nonce_values.api_major_version < ODK_FIRST_VERSION) { // This indicates CreateResponseHeader was not called. return false; } @@ -89,8 +92,8 @@ bool CreateResponse(ODK_MessageType message_type, const S& core_request, } uint32_t message_length = static_cast(ODK_Message_GetSize(&msg)); - msg = ODK_Message_Create(buf.data() + sizeof(header->message_type), - sizeof(header->message_length)); + msg = ODK_Message_Create(buf.data() + sizeof(response_header->message_type), + sizeof(response_header->message_length)); Pack_uint32_t(&msg, &message_length); oemcrypto_core_message->assign(reinterpret_cast(buf.data()), message_length); @@ -98,10 +101,10 @@ bool CreateResponse(ODK_MessageType message_type, const S& core_request, } bool CopyDeviceId(const ODK_ProvisioningRequest& src, - ODK_ProvisioningResponse* dest) { + ODK_ProvisioningResponseV16* dest) { auto& request = dest->request; const std::string& device_id = src.device_id; - if (request.device_id_length > sizeof(request.device_id)) { + if (device_id.size() > sizeof(request.device_id)) { return false; } request.device_id_length = static_cast(device_id.size()); @@ -113,56 +116,24 @@ bool CopyDeviceId(const ODK_ProvisioningRequest& src, } // namespace bool CreateCoreLicenseResponse(const CoreMessageFeatures& features, - const ODK_ParsedLicense& parsed_lic, + const ODK_Packing_ParsedLicense& parsed_lic, const ODK_LicenseRequest& core_request, const std::string& core_request_sha256, std::string* oemcrypto_core_message) { - ODK_LicenseResponse license_response{ - {}, const_cast(&parsed_lic)}; - if (!CreateResponseHeader(features, ODK_License_Response_Type, core_request, - license_response)) { + ODK_Packing_LicenseResponse license_response{ + {}, const_cast(&parsed_lic), {}}; + if (!CreateResponseHeader(features, ODK_License_Response_Type, + &license_response.core_message, core_request)) { return false; } - if (ODK_MAX_NUM_KEYS < license_response.parsed_license->key_array_length) { - return false; - } - if (license_response.request.core_message.nonce_values.api_major_version == - 16) { - ODK_LicenseResponseV16 license_response_v16; - license_response_v16.request = license_response.request; - license_response_v16.parsed_license.enc_mac_keys_iv = - license_response.parsed_license->enc_mac_keys_iv; - license_response_v16.parsed_license.enc_mac_keys = - license_response.parsed_license->enc_mac_keys; - license_response_v16.parsed_license.pst = - license_response.parsed_license->pst; - license_response_v16.parsed_license.srm_restriction_data = - license_response.parsed_license->srm_restriction_data; - license_response_v16.parsed_license.license_type = - license_response.parsed_license->license_type; - license_response_v16.parsed_license.nonce_required = - license_response.parsed_license->nonce_required; - license_response_v16.parsed_license.timer_limits = - license_response.parsed_license->timer_limits; - license_response_v16.parsed_license.key_array_length = - license_response.parsed_license->key_array_length; - uint32_t i; - for (i = 0; i < license_response_v16.parsed_license.key_array_length && - i < license_response.parsed_license->key_array_length; - i++) { - license_response_v16.parsed_license.key_array[i] = - license_response.parsed_license->key_array[i]; - } - if (core_request_sha256.size() != sizeof(license_response_v16.request_hash)) + if (license_response.core_message.nonce_values.api_major_version == 16) { + if (core_request_sha256.size() != sizeof(license_response.request_hash)) return false; - memcpy(license_response_v16.request_hash, core_request_sha256.data(), - sizeof(license_response_v16.request_hash)); - return CreateResponse(ODK_License_Response_Type, core_request, - oemcrypto_core_message, license_response_v16, - Pack_ODK_LicenseResponseV16); + memcpy(license_response.request_hash, core_request_sha256.data(), + sizeof(license_response.request_hash)); } - return CreateResponse(ODK_License_Response_Type, core_request, - oemcrypto_core_message, license_response, + return CreateResponse(ODK_License_Response_Type, oemcrypto_core_message, + &license_response.core_message, license_response, Pack_ODK_LicenseResponse); } @@ -173,13 +144,14 @@ bool CreateCoreRenewalResponse(const CoreMessageFeatures& features, ODK_RenewalResponse renewal_response{{}, core_request.playback_time_seconds}; renewal_response.request.playback_time = core_request.playback_time_seconds; renewal_response.renewal_duration_seconds = renewal_duration_seconds; - if (!CreateResponseHeader(features, ODK_Renewal_Response_Type, core_request, - renewal_response)) { + if (!CreateResponseHeader(features, ODK_Renewal_Response_Type, + &renewal_response.request.core_message, + core_request)) { return false; } - return CreateResponse(ODK_Renewal_Response_Type, core_request, - oemcrypto_core_message, renewal_response, - Pack_ODK_RenewalResponse); + return CreateResponse(ODK_Renewal_Response_Type, oemcrypto_core_message, + &renewal_response.request.core_message, + renewal_response, Pack_ODK_RenewalResponse); } bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features, @@ -188,17 +160,42 @@ bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features, std::string* oemcrypto_core_message) { ODK_ProvisioningResponse prov_response{ {}, const_cast(&parsed_prov)}; - if (!CopyDeviceId(core_request, &prov_response)) { - return false; - } if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type, - core_request, prov_response)) { + &prov_response.core_message, core_request)) { return false; } - return CreateResponse(ODK_Provisioning_Response_Type, core_request, - oemcrypto_core_message, prov_response, + + if (prov_response.core_message.nonce_values.api_major_version <= 17) { + ODK_ProvisioningResponseV16 prov_response_v16; + if (!CopyDeviceId(core_request, &prov_response_v16)) { + return false; + } + prov_response_v16.request.core_message = prov_response.core_message; + prov_response_v16.parsed_provisioning = prov_response.parsed_provisioning; + return CreateResponse(ODK_Provisioning_Response_Type, + oemcrypto_core_message, + &prov_response_v16.request.core_message, + prov_response_v16, Pack_ODK_ProvisioningResponseV16); + } + + return CreateResponse(ODK_Provisioning_Response_Type, oemcrypto_core_message, + &prov_response.core_message, prov_response, Pack_ODK_ProvisioningResponse); } +bool CreateCoreProvisioning40Response( + const CoreMessageFeatures& features, + const ODK_Provisioning40Request& core_request, + std::string* oemcrypto_core_message) { + ODK_Provisioning40Response prov_response = {}; + if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type, + &prov_response.core_message, core_request)) { + return false; + } + return CreateResponse(ODK_Provisioning_Response_Type, oemcrypto_core_message, + &prov_response.core_message, prov_response, + Pack_ODK_Provisioning40Response); +} + } // namespace serialize } // namespace oemcrypto_core_message diff --git a/oemcrypto/odk/src/core_message_serialize_proto.cpp b/oemcrypto/odk/src/core_message_serialize_proto.cpp index 5132bda2..61c50312 100644 --- a/oemcrypto/odk/src/core_message_serialize_proto.cpp +++ b/oemcrypto/odk/src/core_message_serialize_proto.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "core_message_serialize.h" #include "license_protocol.pb.h" @@ -83,7 +84,8 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features, return false; } - ODK_ParsedLicense parsed_lic{}; + ODK_Packing_ParsedLicense parsed_lic{}; + std::vector key_array; bool any_content = false; bool any_entitlement = false; @@ -110,12 +112,8 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features, } else { any_content = true; } - if (parsed_lic.key_array_length >= ODK_MAX_NUM_KEYS) { - return false; - } - uint32_t& n = parsed_lic.key_array_length; - parsed_lic.key_array[n++] = - KeyContainerToOecKey(serialized_license, k, uses_padding); + key_array.push_back( + KeyContainerToOecKey(serialized_license, k, uses_padding)); break; } default: { @@ -147,6 +145,19 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features, } parsed_lic.nonce_required = nonce_required; const auto& policy = lic.policy(); + switch (policy.initial_renewal_delay_base()) { + case video_widevine::License_Policy::LICENSE_LOAD: + parsed_lic.renewal_delay_base = OEMCrypto_License_Load; + break; + case video_widevine::License_Policy::FIRST_DECRYPT: + parsed_lic.renewal_delay_base = OEMCrypto_First_Decrypt; + break; + case video_widevine::License_Policy::TIMER_DELAY_BASE_UNSPECIFIED: + case video_widevine::License_Policy::LICENSE_START: + default: + parsed_lic.renewal_delay_base = OEMCrypto_License_Start; + break; + } ODK_TimerLimits& timer_limits = parsed_lic.timer_limits; timer_limits.soft_enforce_rental_duration = policy.soft_enforce_rental_duration(); @@ -160,23 +171,23 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features, policy.renewal_delay_seconds() + policy.renewal_recovery_duration_seconds(); + parsed_lic.key_array = key_array.data(); + parsed_lic.key_array_length = static_cast(key_array.size()); + return CreateCoreLicenseResponse(features, parsed_lic, core_request, core_request_sha256, oemcrypto_core_message); } -bool CreateCoreProvisioningResponseFromProto( - const CoreMessageFeatures& features, +bool DeserializeProvisioningResponse( const std::string& serialized_provisioning_resp, - const ODK_ProvisioningRequest& core_request, - std::string* oemcrypto_core_message) { - ODK_ParsedProvisioning parsed_prov{}; + const OEMCrypto_PrivateKeyType device_key_type, + ODK_ParsedProvisioning& parsed_prov) { video_widevine::ProvisioningResponse prov; if (!prov.ParseFromString(serialized_provisioning_resp)) { return false; } - parsed_prov.key_type = - OEMCrypto_RSA_Private_Key; // TODO(b/148404408): ECC or RSA + parsed_prov.key_type = device_key_type; if (prov.has_device_rsa_key()) { parsed_prov.enc_private_key = GetOecSubstring(serialized_provisioning_resp, prov.device_rsa_key()); @@ -189,7 +200,19 @@ bool CreateCoreProvisioningResponseFromProto( parsed_prov.encrypted_message_key = GetOecSubstring(serialized_provisioning_resp, prov.wrapping_key()); } + return true; +} +bool CreateCoreProvisioningResponseFromProto( + const CoreMessageFeatures& features, + const std::string& serialized_provisioning_resp, + const ODK_ProvisioningRequest& core_request, + const OEMCrypto_PrivateKeyType device_key_type, + std::string* oemcrypto_core_message) { + ODK_ParsedProvisioning parsed_prov{}; + if (!DeserializeProvisioningResponse(serialized_provisioning_resp, + device_key_type, parsed_prov)) + return false; return CreateCoreProvisioningResponse(features, parsed_prov, core_request, oemcrypto_core_message); } diff --git a/oemcrypto/odk/src/odk.c b/oemcrypto/odk/src/odk.c index 4f283898..fafa0ab6 100644 --- a/oemcrypto/odk/src/odk.c +++ b/oemcrypto/odk/src/odk.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "odk_overflow.h" @@ -13,7 +14,6 @@ #include "odk_structs.h" #include "odk_structs_priv.h" #include "odk_util.h" -#include "serialization_base.h" /* @ private odk functions */ @@ -31,7 +31,7 @@ static OEMCryptoResult ODK_PrepareRequest( /* The core message should be at the beginning of the buffer, and with a * shorter length. */ - if (sizeof(ODK_CoreMessage) > prepared_request_buffer_length) { + if (ODK_CORE_MESSAGE_SIZE > prepared_request_buffer_length) { return ODK_ERROR_CORE_MESSAGE; } ODK_CoreMessage* core_message = (ODK_CoreMessage*)prepared_request_buffer; @@ -72,6 +72,16 @@ static OEMCryptoResult ODK_PrepareRequest( &msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer); break; } + case ODK_Provisioning40_Request_Type: { + core_message->message_length = ODK_PROVISIONING40_REQUEST_SIZE; + if (sizeof(ODK_PreparedProvisioning40Request) > + prepared_request_buffer_length) { + return ODK_ERROR_CORE_MESSAGE; + } + Pack_ODK_PreparedProvisioning40Request( + &msg, (ODK_PreparedProvisioning40Request*)prepared_request_buffer); + break; + } case ODK_Renewed_Provisioning_Request_Type: { core_message->message_length = ODK_RENEWED_PROVISIONING_REQUEST_SIZE; if (sizeof(ODK_PreparedRenewedProvisioningRequest) > @@ -169,14 +179,18 @@ static OEMCryptoResult ODK_ParseCoreHeader(const uint8_t* message, /* @@ prepare request functions */ OEMCryptoResult ODK_PrepareCoreLicenseRequest( - uint8_t* message, size_t message_length, size_t* core_message_length, - const ODK_NonceValues* nonce_values) { - if (core_message_length == NULL || nonce_values == NULL) { + uint8_t* message, size_t message_length, size_t* core_message_size, + const ODK_NonceValues* nonce_values, + const ODK_MessageCounterInfo* counter_info) { + if (core_message_size == NULL || nonce_values == NULL || + counter_info == NULL) { return ODK_ERROR_CORE_MESSAGE; } ODK_PreparedLicenseRequest license_request = {0}; + memcpy(&license_request.counter_info, counter_info, + sizeof(license_request.counter_info)); return ODK_PrepareRequest( - message, message_length, core_message_length, ODK_License_Request_Type, + message, message_length, core_message_size, ODK_License_Request_Type, nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest)); } @@ -230,25 +244,47 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message, OEMCryptoResult ODK_PrepareCoreProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, - const ODK_NonceValues* nonce_values, const uint8_t* device_id, - size_t device_id_length) { - if (core_message_length == NULL || nonce_values == NULL) { + const ODK_NonceValues* nonce_values, + const ODK_MessageCounterInfo* counter_info) { + if (core_message_length == NULL || nonce_values == NULL || + counter_info == NULL) { return ODK_ERROR_CORE_MESSAGE; } ODK_PreparedProvisioningRequest provisioning_request = {0}; - if (device_id_length > sizeof(provisioning_request.device_id)) { - return ODK_ERROR_CORE_MESSAGE; - } - provisioning_request.device_id_length = (uint32_t)device_id_length; - if (device_id) { - memcpy(provisioning_request.device_id, device_id, device_id_length); - } + memcpy(&provisioning_request.counter_info, counter_info, + sizeof(ODK_MessageCounterInfo)); + return ODK_PrepareRequest(message, message_length, core_message_length, ODK_Provisioning_Request_Type, nonce_values, &provisioning_request, sizeof(ODK_PreparedProvisioningRequest)); } +OEMCryptoResult ODK_PrepareCoreProvisioning40Request( + uint8_t* message, size_t message_length, size_t* core_message_length, + const ODK_NonceValues* nonce_values, const uint8_t* device_info, + size_t device_info_length, const ODK_MessageCounterInfo* counter_info) { + if (core_message_length == NULL || nonce_values == NULL || + counter_info == NULL) { + return ODK_ERROR_CORE_MESSAGE; + } + ODK_PreparedProvisioning40Request provisioning_request = {0}; + if (device_info_length > sizeof(provisioning_request.device_info)) { + return ODK_ERROR_CORE_MESSAGE; + } + provisioning_request.device_info_length = (uint32_t)device_info_length; + if (device_info) { + memcpy(provisioning_request.device_info, device_info, device_info_length); + } + memcpy(&provisioning_request.counter_info, counter_info, + sizeof(provisioning_request.counter_info)); + + return ODK_PrepareRequest(message, message_length, core_message_length, + ODK_Provisioning40_Request_Type, nonce_values, + &provisioning_request, + sizeof(provisioning_request)); +} + OEMCryptoResult ODK_PrepareCoreRenewedProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, const ODK_NonceValues* nonce_values, const uint8_t* device_id, @@ -285,14 +321,15 @@ OEMCryptoResult ODK_PrepareCoreRenewedProvisioningRequest( OEMCryptoResult ODK_ParseLicense( const uint8_t* message, size_t message_length, size_t core_message_length, bool initial_license_load, bool usage_entry_present, - ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values, - ODK_NonceValues* nonce_values, ODK_ParsedLicense* parsed_license) { + uint64_t system_time_seconds, ODK_TimerLimits* timer_limits, + ODK_ClockValues* clock_values, ODK_NonceValues* nonce_values, + ODK_ParsedLicense* parsed_license, uint64_t* timer_value) { if (message == NULL || timer_limits == NULL || clock_values == NULL || nonce_values == NULL || parsed_license == NULL) { return ODK_ERROR_CORE_MESSAGE; } - const OEMCryptoResult err = + OEMCryptoResult err = ODK_ParseCoreHeader(message, message_length, core_message_length, ODK_License_Response_Type, nonce_values); if (err != OEMCrypto_SUCCESS) { @@ -303,68 +340,14 @@ OEMCryptoResult ODK_ParseLicense( license_response.parsed_license = parsed_license; ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length); + ODK_Message_SetSize(&msg, core_message_length); - if (nonce_values->api_major_version == 16) { - ODK_LicenseResponseV16 license_response_v16 = {0}; - Unpack_ODK_LicenseResponseV16(&msg, &license_response_v16); - if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || - ODK_Message_GetOffset(&msg) != core_message_length) { - return ODK_ERROR_CORE_MESSAGE; - } + Unpack_ODK_LicenseResponse(&msg, &license_response); - // Need to manually set parsed_license fields to - // license_response_v16.parsed_license field values since - // license_response_v16 is no longer a pointer so parsed_license doesn't get - // updated during the unpacking. - parsed_license->enc_mac_keys_iv = - license_response_v16.parsed_license.enc_mac_keys_iv; - parsed_license->enc_mac_keys = - license_response_v16.parsed_license.enc_mac_keys; - parsed_license->pst = license_response_v16.parsed_license.pst; - parsed_license->srm_restriction_data = - license_response_v16.parsed_license.srm_restriction_data; - parsed_license->license_type = - license_response_v16.parsed_license.license_type; - parsed_license->nonce_required = - license_response_v16.parsed_license.nonce_required; - parsed_license->timer_limits = - license_response_v16.parsed_license.timer_limits; - parsed_license->key_array_length = - license_response_v16.parsed_license.key_array_length; - uint32_t i; - for (i = 0; i < parsed_license->key_array_length; i++) { - parsed_license->key_array[i] = - license_response_v16.parsed_license.key_array[i]; - } - // Set fields not used in V16 to default values. - parsed_license->watermarking = 0; - // Set fields not used in V16 to default values. - parsed_license->dtcp2_required.dtcp2_required = 0; - parsed_license->dtcp2_required.cmi_descriptor_0.id = 0; - parsed_license->dtcp2_required.cmi_descriptor_0.extension = 0; - parsed_license->dtcp2_required.cmi_descriptor_0.length = 1; - parsed_license->dtcp2_required.cmi_descriptor_0.data = 0; - parsed_license->dtcp2_required.cmi_descriptor_1.id = 1; - parsed_license->dtcp2_required.cmi_descriptor_1.extension = 0; - parsed_license->dtcp2_required.cmi_descriptor_1.length = 3; - parsed_license->dtcp2_required.cmi_descriptor_1.data[0] = 0; - parsed_license->dtcp2_required.cmi_descriptor_1.data[1] = 0; - parsed_license->dtcp2_required.cmi_descriptor_1.data[2] = 0; - parsed_license->dtcp2_required.cmi_descriptor_2.id = 2; - parsed_license->dtcp2_required.cmi_descriptor_2.extension = 0; - parsed_license->dtcp2_required.cmi_descriptor_2.length = 3; - parsed_license->dtcp2_required.cmi_descriptor_2.data[0] = 0; - parsed_license->dtcp2_required.cmi_descriptor_2.data[1] = 0; - parsed_license->dtcp2_required.cmi_descriptor_2.data[2] = 0; - license_response.request = license_response_v16.request; - } else { - Unpack_ODK_LicenseResponse(&msg, &license_response); - - if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || - ODK_Message_GetOffset(&msg) != core_message_length) { - return ODK_ERROR_CORE_MESSAGE; - } + if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || + ODK_Message_GetOffset(&msg) != core_message_length) { + return ODK_ERROR_CORE_MESSAGE; } /* If the license has a provider session token (pst), then OEMCrypto should @@ -382,26 +365,38 @@ OEMCryptoResult ODK_ParseLicense( */ if (parsed_license->nonce_required && initial_license_load) { if (nonce_values->nonce != - license_response.request.core_message.nonce_values.nonce || + license_response.core_message.nonce_values.nonce || nonce_values->session_id != - license_response.request.core_message.nonce_values.session_id) { + license_response.core_message.nonce_values.session_id) { return OEMCrypto_ERROR_INVALID_NONCE; } } else { /* !initial_license_load, or can't tell if initial. */ - nonce_values->nonce = - license_response.request.core_message.nonce_values.nonce; + nonce_values->nonce = license_response.core_message.nonce_values.nonce; nonce_values->session_id = - license_response.request.core_message.nonce_values.session_id; + license_response.core_message.nonce_values.session_id; + /* Start the rental clock if not already started for reloading an offline + * license without a nonce. */ + if (!parsed_license->nonce_required && + clock_values->time_of_license_request_signed == 0) { + clock_values->time_of_license_request_signed = system_time_seconds; + } } + bool license_load = + (parsed_license->renewal_delay_base == OEMCrypto_License_Load); *timer_limits = parsed_license->timer_limits; /* And update the clock values state. */ clock_values->timer_status = ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED; + if (nonce_values->api_major_version == 18 && license_load) { + err = ODK_AttemptFirstPlayback(system_time_seconds, timer_limits, + clock_values, timer_value); + return err; + } return OEMCrypto_SUCCESS; } OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, size_t core_message_length, - const ODK_NonceValues* nonce_values, + ODK_NonceValues* nonce_values, uint64_t system_time, const ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values, @@ -413,7 +408,7 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, const OEMCryptoResult err = ODK_ParseCoreHeader(message, message_length, core_message_length, - ODK_Renewal_Response_Type, NULL); + ODK_Renewal_Response_Type, nonce_values); if (err != OEMCrypto_SUCCESS) { return err; } @@ -454,7 +449,7 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, OEMCryptoResult ODK_ParseProvisioning( const uint8_t* message, size_t message_length, size_t core_message_length, - const ODK_NonceValues* nonce_values, const uint8_t* device_id, + ODK_NonceValues* nonce_values, const uint8_t* device_id, size_t device_id_length, ODK_ParsedProvisioning* parsed_response) { if (message == NULL || nonce_values == NULL || device_id == NULL || parsed_response == NULL) { @@ -462,44 +457,96 @@ OEMCryptoResult ODK_ParseProvisioning( } const OEMCryptoResult err = ODK_ParseCoreHeader(message, message_length, core_message_length, - ODK_Provisioning_Response_Type, NULL); + ODK_Provisioning_Response_Type, nonce_values); if (err != OEMCrypto_SUCCESS) { return err; } - ODK_ProvisioningResponse provisioning_response = {0}; - provisioning_response.parsed_provisioning = parsed_response; - if (device_id_length > ODK_DEVICE_ID_LEN_MAX) { + if (nonce_values->api_major_version <= 17) { + // Do v16/v17 + ODK_ProvisioningResponseV16 provisioning_response = {0}; + provisioning_response.parsed_provisioning = parsed_response; + + if (device_id_length > ODK_DEVICE_ID_LEN_MAX) { + return ODK_ERROR_CORE_MESSAGE; + } + + ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length); + ODK_Message_SetSize(&msg, core_message_length); + Unpack_ODK_ProvisioningResponseV16(&msg, &provisioning_response); + if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || + ODK_Message_GetOffset(&msg) != core_message_length) { + return ODK_ERROR_CORE_MESSAGE; + } + /* always verify nonce_values for Renewal and Provisioning responses */ + if (!ODK_NonceValuesEqualExcludingVersion( + nonce_values, + &(provisioning_response.request.core_message.nonce_values))) { + return OEMCrypto_ERROR_INVALID_NONCE; + } + + if (crypto_memcmp(device_id, provisioning_response.request.device_id, + device_id_length) != 0) { + return ODK_ERROR_CORE_MESSAGE; + } + + const uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {0}; + /* check bytes beyond device_id_length are 0 */ + if (crypto_memcmp( + zero, provisioning_response.request.device_id + device_id_length, + ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) { + return ODK_ERROR_CORE_MESSAGE; + } + } else { + // v18 + ODK_ProvisioningResponse provisioning_response = {0}; + provisioning_response.parsed_provisioning = parsed_response; + + ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length); + ODK_Message_SetSize(&msg, core_message_length); + Unpack_ODK_ProvisioningResponse(&msg, &provisioning_response); + if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || + ODK_Message_GetOffset(&msg) != core_message_length) { + return ODK_ERROR_CORE_MESSAGE; + } + /* always verify nonce_values for Renewal and Provisioning responses */ + if (!ODK_NonceValuesEqualExcludingVersion( + nonce_values, &(provisioning_response.core_message.nonce_values))) { + return OEMCrypto_ERROR_INVALID_NONCE; + } + } + + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult ODK_ParseProvisioning40(const uint8_t* message, + size_t message_length, + size_t core_message_length, + ODK_NonceValues* nonce_values) { + if (message == NULL || nonce_values == NULL) { return ODK_ERROR_CORE_MESSAGE; } + const OEMCryptoResult err = + ODK_ParseCoreHeader(message, message_length, core_message_length, + ODK_Provisioning_Response_Type, nonce_values); + if (err != OEMCrypto_SUCCESS) { + return err; + } + ODK_Provisioning40Response provisioning_response = {0}; ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length); ODK_Message_SetSize(&msg, core_message_length); - Unpack_ODK_ProvisioningResponse(&msg, &provisioning_response); + Unpack_ODK_Provisioning40Response(&msg, &provisioning_response); if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK || ODK_Message_GetOffset(&msg) != core_message_length) { return ODK_ERROR_CORE_MESSAGE; } /* always verify nonce_values for Renewal and Provisioning responses */ if (!ODK_NonceValuesEqualExcludingVersion( - nonce_values, - &(provisioning_response.request.core_message.nonce_values))) { + nonce_values, &(provisioning_response.core_message.nonce_values))) { return OEMCrypto_ERROR_INVALID_NONCE; } - if (crypto_memcmp(device_id, provisioning_response.request.device_id, - device_id_length) != 0) { - return ODK_ERROR_CORE_MESSAGE; - } - - const uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {0}; - /* check bytes beyond device_id_length are 0 */ - if (crypto_memcmp(zero, - provisioning_response.request.device_id + device_id_length, - ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) { - return ODK_ERROR_CORE_MESSAGE; - } - return OEMCrypto_SUCCESS; } diff --git a/oemcrypto/odk/src/odk_message.c b/oemcrypto/odk/src/odk_message.c index df29d231..7cc05c05 100644 --- a/oemcrypto/odk/src/odk_message.c +++ b/oemcrypto/odk/src/odk_message.c @@ -8,20 +8,13 @@ #include #include +#include "odk_assert.h" #include "odk_message_priv.h" -/* - * C11 defines static_assert in assert.h. If it is available, force a compile - * time error if the abstract ODK_Message struct size does not match its - * implementation. If static_assert is not available, the runtime assert in - * InitMessage will catch the mismatch at the time a message is initialized. - */ -#ifdef static_assert -static_assert( +odk_static_assert( sizeof(ODK_Message) >= sizeof(ODK_Message_Impl), "sizeof(ODK_Message) is too small. You can increase " "SIZE_OF_ODK_MESSAGE_IMPL in odk_message.h to make it large enough."); -#endif /* * Create a message structure that references a separate data buffer. An @@ -34,7 +27,6 @@ static_assert( * unchanged by this function. */ ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity) { - assert(sizeof(ODK_Message) >= sizeof(ODK_Message_Impl)); ODK_Message message; ODK_Message_Impl* message_impl = (ODK_Message_Impl*)&message; message_impl->base = buffer; diff --git a/oemcrypto/odk/src/odk_overflow.c b/oemcrypto/odk/src/odk_overflow.c index 0ebc0846..37c3bb9b 100644 --- a/oemcrypto/odk/src/odk_overflow.c +++ b/oemcrypto/odk/src/odk_overflow.c @@ -2,6 +2,8 @@ // source code may only be used and distributed under the Widevine // License Agreement. +#include "odk_overflow.h" + #include #include diff --git a/oemcrypto/odk/src/odk_serialize.c b/oemcrypto/odk/src/odk_serialize.c index 537eefe2..eec02663 100644 --- a/oemcrypto/odk/src/odk_serialize.c +++ b/oemcrypto/odk/src/odk_serialize.c @@ -6,6 +6,8 @@ * This code is auto-generated, do not edit */ +#include "odk_serialize.h" + #include "odk_structs_priv.h" #include "serialization_base.h" @@ -45,7 +47,8 @@ static void Pack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits const* obj) { } static void Pack_ODK_ParsedLicense(ODK_Message* msg, - ODK_ParsedLicense const* obj) { + ODK_Packing_ParsedLicense const* obj, + const ODK_NonceValues* nonce_values) { /* hand-coded */ if (obj->key_array_length > ODK_MAX_NUM_KEYS) { ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR); @@ -58,47 +61,31 @@ static void Pack_ODK_ParsedLicense(ODK_Message* msg, Pack_enum(msg, obj->license_type); Pack_bool(msg, &obj->nonce_required); Pack_ODK_TimerLimits(msg, &obj->timer_limits); - Pack_uint32_t(msg, &obj->watermarking); - Pack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required); - if (obj->dtcp2_required.dtcp2_required) { - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension); - Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension); - Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension); - Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]); - Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]); + if (nonce_values->api_major_version >= 17) { + Pack_uint32_t(msg, &obj->watermarking); + Pack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required); + if (obj->dtcp2_required.dtcp2_required) { + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension); + Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension); + Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension); + Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]); + Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]); + } } - Pack_uint32_t(msg, &obj->key_array_length); - size_t i; - for (i = 0; i < (size_t)obj->key_array_length; i++) { - Pack_OEMCrypto_KeyObject(msg, &obj->key_array[i]); + if (nonce_values->api_major_version >= 18) { + Pack_enum(msg, obj->renewal_delay_base); } -} - -static void Pack_ODK_ParsedLicenseV16(ODK_Message* msg, - ODK_ParsedLicenseV16 const* obj) { - /* hand-coded */ - if (obj->key_array_length > ODK_MAX_NUM_KEYS) { - ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR); - return; - } - Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv); - Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys); - Pack_OEMCrypto_Substring(msg, &obj->pst); - Pack_OEMCrypto_Substring(msg, &obj->srm_restriction_data); - Pack_enum(msg, obj->license_type); - Pack_bool(msg, &obj->nonce_required); - Pack_ODK_TimerLimits(msg, &obj->timer_limits); Pack_uint32_t(msg, &obj->key_array_length); size_t i; for (i = 0; i < (size_t)obj->key_array_length; i++) { @@ -114,11 +101,31 @@ static void Pack_ODK_ParsedProvisioning(ODK_Message* msg, Pack_OEMCrypto_Substring(msg, &obj->encrypted_message_key); } +static void Pack_ODK_MessageCounterInfo(ODK_Message* msg, + ODK_MessageCounterInfo const* obj) { + Pack_uint64_t(msg, &obj->master_generation_number); + Pack_uint32_t(msg, &obj->provisioning_count); + Pack_uint32_t(msg, &obj->license_count); + Pack_uint32_t(msg, &obj->decrypt_count); + Pack_uint16_t(msg, &obj->major_version); + Pack_uint16_t(msg, &obj->minor_version); + Pack_uint16_t(msg, &obj->patch_version); + PackArray(msg, &obj->soc_vendor[0], sizeof(obj->soc_vendor)); + PackArray(msg, &obj->chipset_model[0], sizeof(obj->chipset_model)); + PackArray(msg, &obj->extra[0], sizeof(obj->extra)); +} + /* @@ odk serialize */ void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg, ODK_PreparedLicenseRequest const* obj) { Pack_ODK_CoreMessage(msg, &obj->core_message); + Pack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + +void Pack_ODK_PreparedLicenseRequestV17( + ODK_Message* msg, ODK_PreparedLicenseRequestV17 const* obj) { + Pack_ODK_CoreMessage(msg, &obj->core_message); } void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg, @@ -130,10 +137,28 @@ void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg, void Pack_ODK_PreparedProvisioningRequest( ODK_Message* msg, const ODK_PreparedProvisioningRequest* obj) { Pack_ODK_CoreMessage(msg, &obj->core_message); + // Fake device_id_length for older servers, since we removed device id from + // the v18 request + uint32_t device_id_len = 64; + Pack_uint32_t(msg, &device_id_len); + Pack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + +void Pack_ODK_PreparedProvisioningRequestV17( + ODK_Message* msg, const ODK_PreparedProvisioningRequestV17* obj) { + Pack_ODK_CoreMessage(msg, &obj->core_message); Pack_uint32_t(msg, &obj->device_id_length); PackArray(msg, &obj->device_id[0], sizeof(obj->device_id)); } +void Pack_ODK_PreparedProvisioning40Request( + ODK_Message* msg, const ODK_PreparedProvisioning40Request* obj) { + Pack_ODK_CoreMessage(msg, &obj->core_message); + Pack_uint32_t(msg, &obj->device_info_length); + PackArray(msg, &obj->device_info[0], sizeof(obj->device_info)); + Pack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + void Pack_ODK_PreparedRenewedProvisioningRequest( ODK_Message* msg, const ODK_PreparedRenewedProvisioningRequest* obj) { Pack_ODK_CoreMessage(msg, &obj->core_message); @@ -147,16 +172,14 @@ void Pack_ODK_PreparedRenewedProvisioningRequest( /* @@ kdo serialize */ void Pack_ODK_LicenseResponse(ODK_Message* msg, - ODK_LicenseResponse const* obj) { - Pack_ODK_PreparedLicenseRequest(msg, &obj->request); - Pack_ODK_ParsedLicense(msg, (const ODK_ParsedLicense*)obj->parsed_license); -} - -void Pack_ODK_LicenseResponseV16(ODK_Message* msg, - ODK_LicenseResponseV16 const* obj) { - Pack_ODK_PreparedLicenseRequest(msg, &obj->request); - Pack_ODK_ParsedLicenseV16(msg, &obj->parsed_license); - PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash)); + ODK_Packing_LicenseResponse const* obj) { + Pack_ODK_CoreMessage(msg, &obj->core_message); + Pack_ODK_ParsedLicense(msg, + (const ODK_Packing_ParsedLicense*)obj->parsed_license, + &obj->core_message.nonce_values); + if ((&obj->core_message.nonce_values)->api_major_version == 16) { + PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash)); + } } void Pack_ODK_RenewalResponse(ODK_Message* msg, @@ -167,11 +190,23 @@ void Pack_ODK_RenewalResponse(ODK_Message* msg, void Pack_ODK_ProvisioningResponse(ODK_Message* msg, const ODK_ProvisioningResponse* obj) { - Pack_ODK_PreparedProvisioningRequest(msg, &obj->request); + Pack_ODK_CoreMessage(msg, &obj->core_message); Pack_ODK_ParsedProvisioning( msg, (const ODK_ParsedProvisioning*)obj->parsed_provisioning); } +void Pack_ODK_ProvisioningResponseV16(ODK_Message* msg, + const ODK_ProvisioningResponseV16* obj) { + Pack_ODK_PreparedProvisioningRequestV17(msg, &obj->request); + Pack_ODK_ParsedProvisioning( + msg, (const ODK_ParsedProvisioning*)obj->parsed_provisioning); +} + +void Pack_ODK_Provisioning40Response(ODK_Message* msg, + const ODK_Provisioning40Response* obj) { + Pack_ODK_CoreMessage(msg, &obj->core_message); +} + /* @ deserialize */ /* @@ private deserialize */ @@ -207,7 +242,8 @@ static void Unpack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits* obj) { Unpack_uint64_t(msg, &obj->initial_renewal_duration_seconds); } -static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) { +static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj, + const ODK_NonceValues* nonce_values) { Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv); Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys); Unpack_OEMCrypto_Substring(msg, &obj->pst); @@ -215,64 +251,31 @@ static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) { Unpack_OEMCrypto_LicenseType(msg, &obj->license_type); Unpack_bool(msg, &obj->nonce_required); Unpack_ODK_TimerLimits(msg, &obj->timer_limits); - Unpack_uint32_t(msg, &obj->watermarking); - Unpack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required); - if (obj->dtcp2_required.dtcp2_required) { - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension); - Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension); - Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension); - Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]); - Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]); - } else { - obj->dtcp2_required.dtcp2_required = 0; - obj->dtcp2_required.cmi_descriptor_0.id = 0; - obj->dtcp2_required.cmi_descriptor_0.extension = 0; - obj->dtcp2_required.cmi_descriptor_0.length = 0; - obj->dtcp2_required.cmi_descriptor_0.data = 0; - obj->dtcp2_required.cmi_descriptor_1.id = 0; - obj->dtcp2_required.cmi_descriptor_1.extension = 0; - obj->dtcp2_required.cmi_descriptor_1.length = 0; - obj->dtcp2_required.cmi_descriptor_1.data[0] = 0; - obj->dtcp2_required.cmi_descriptor_1.data[1] = 0; - obj->dtcp2_required.cmi_descriptor_1.data[2] = 0; - obj->dtcp2_required.cmi_descriptor_2.id = 0; - obj->dtcp2_required.cmi_descriptor_2.extension = 0; - obj->dtcp2_required.cmi_descriptor_2.length = 0; - obj->dtcp2_required.cmi_descriptor_2.data[0] = 0; - obj->dtcp2_required.cmi_descriptor_2.data[1] = 0; - obj->dtcp2_required.cmi_descriptor_2.data[2] = 0; + if (nonce_values->api_major_version >= 17) { + Unpack_uint32_t(msg, &obj->watermarking); + Unpack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required); + if (obj->dtcp2_required.dtcp2_required) { + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension); + Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension); + Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension); + Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]); + Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]); + } } - Unpack_uint32_t(msg, &obj->key_array_length); - if (obj->key_array_length > ODK_MAX_NUM_KEYS) { - ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR); - return; + if (nonce_values->api_major_version >= 18) { + Unpack_OEMCrypto_TimerDelayBase(msg, &obj->renewal_delay_base); } - uint32_t i; - for (i = 0; i < obj->key_array_length; i++) { - Unpack_OEMCrypto_KeyObject(msg, &obj->key_array[i]); - } -} - -static void Unpack_ODK_ParsedLicenseV16(ODK_Message* msg, - ODK_ParsedLicenseV16* obj) { - Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv); - Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys); - Unpack_OEMCrypto_Substring(msg, &obj->pst); - Unpack_OEMCrypto_Substring(msg, &obj->srm_restriction_data); - Unpack_OEMCrypto_LicenseType(msg, &obj->license_type); - Unpack_bool(msg, &obj->nonce_required); - Unpack_ODK_TimerLimits(msg, &obj->timer_limits); Unpack_uint32_t(msg, &obj->key_array_length); if (obj->key_array_length > ODK_MAX_NUM_KEYS) { ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR); @@ -292,11 +295,31 @@ static void Unpack_ODK_ParsedProvisioning(ODK_Message* msg, Unpack_OEMCrypto_Substring(msg, &obj->encrypted_message_key); } +static void Unpack_ODK_MessageCounterInfo(ODK_Message* msg, + ODK_MessageCounterInfo* obj) { + Unpack_uint64_t(msg, &obj->master_generation_number); + Unpack_uint32_t(msg, &obj->provisioning_count); + Unpack_uint32_t(msg, &obj->license_count); + Unpack_uint32_t(msg, &obj->decrypt_count); + Unpack_uint16_t(msg, &obj->major_version); + Unpack_uint16_t(msg, &obj->minor_version); + Unpack_uint16_t(msg, &obj->patch_version); + UnpackArray(msg, &obj->soc_vendor[0], sizeof(obj->soc_vendor)); + UnpackArray(msg, &obj->chipset_model[0], sizeof(obj->chipset_model)); + UnpackArray(msg, &obj->extra[0], sizeof(obj->extra)); +} + /* @ kdo deserialize */ void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg, ODK_PreparedLicenseRequest* obj) { Unpack_ODK_CoreMessage(msg, &obj->core_message); + Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + +void Unpack_ODK_PreparedLicenseRequestV17(ODK_Message* msg, + ODK_PreparedLicenseRequestV17* obj) { + Unpack_ODK_CoreMessage(msg, &obj->core_message); } void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg, @@ -308,10 +331,34 @@ void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg, void Unpack_ODK_PreparedProvisioningRequest( ODK_Message* msg, ODK_PreparedProvisioningRequest* obj) { Unpack_ODK_CoreMessage(msg, &obj->core_message); + // Fake device_id_length for older servers, since we removed device id from + // the v18 request + uint32_t device_id_len = 0; + Unpack_uint32_t(msg, &device_id_len); + Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + +void Unpack_ODK_PreparedProvisioningRequestV180( + ODK_Message* msg, ODK_PreparedProvisioningRequest* obj) { + Unpack_ODK_CoreMessage(msg, &obj->core_message); + Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + +void Unpack_ODK_PreparedProvisioningRequestV17( + ODK_Message* msg, ODK_PreparedProvisioningRequestV17* obj) { + Unpack_ODK_CoreMessage(msg, &obj->core_message); Unpack_uint32_t(msg, &obj->device_id_length); UnpackArray(msg, &obj->device_id[0], sizeof(obj->device_id)); } +void Unpack_ODK_PreparedProvisioning40Request( + ODK_Message* msg, ODK_PreparedProvisioning40Request* obj) { + Unpack_ODK_CoreMessage(msg, &obj->core_message); + Unpack_uint32_t(msg, &obj->device_info_length); + UnpackArray(msg, &obj->device_info[0], sizeof(obj->device_info)); + Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info); +} + void Unpack_ODK_PreparedRenewedProvisioningRequest( ODK_Message* msg, ODK_PreparedRenewedProvisioningRequest* obj) { Unpack_ODK_CoreMessage(msg, &obj->core_message); @@ -329,15 +376,12 @@ void Unpack_ODK_PreparedCommonRequest(ODK_Message* msg, /* @@ odk deserialize */ void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj) { - Unpack_ODK_PreparedLicenseRequest(msg, &obj->request); - Unpack_ODK_ParsedLicense(msg, obj->parsed_license); -} - -void Unpack_ODK_LicenseResponseV16(ODK_Message* msg, - ODK_LicenseResponseV16* obj) { - Unpack_ODK_PreparedLicenseRequest(msg, &obj->request); - Unpack_ODK_ParsedLicenseV16(msg, &obj->parsed_license); - UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash)); + Unpack_ODK_CoreMessage(msg, &obj->core_message); + Unpack_ODK_ParsedLicense(msg, obj->parsed_license, + &obj->core_message.nonce_values); + if ((&obj->core_message.nonce_values)->api_major_version == 16) { + UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash)); + } } void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj) { @@ -347,6 +391,17 @@ void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj) { void Unpack_ODK_ProvisioningResponse(ODK_Message* msg, ODK_ProvisioningResponse* obj) { - Unpack_ODK_PreparedProvisioningRequest(msg, &obj->request); + Unpack_ODK_CoreMessage(msg, &obj->core_message); Unpack_ODK_ParsedProvisioning(msg, obj->parsed_provisioning); } + +void Unpack_ODK_ProvisioningResponseV16(ODK_Message* msg, + ODK_ProvisioningResponseV16* obj) { + Unpack_ODK_PreparedProvisioningRequestV17(msg, &obj->request); + Unpack_ODK_ParsedProvisioning(msg, obj->parsed_provisioning); +} + +void Unpack_ODK_Provisioning40Response(ODK_Message* msg, + ODK_Provisioning40Response* obj) { + Unpack_ODK_CoreMessage(msg, &obj->core_message); +} diff --git a/oemcrypto/odk/src/odk_serialize.h b/oemcrypto/odk/src/odk_serialize.h index 0904700c..1ec74b6c 100644 --- a/oemcrypto/odk/src/odk_serialize.h +++ b/oemcrypto/odk/src/odk_serialize.h @@ -8,8 +8,8 @@ #ifndef WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_ #define WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_ +#include "odk_message.h" #include "odk_structs_priv.h" -#include "serialization_base.h" #ifdef __cplusplus extern "C" { @@ -18,37 +18,56 @@ extern "C" { /* odk pack */ void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg, const ODK_PreparedLicenseRequest* obj); +void Pack_ODK_PreparedLicenseRequestV17( + ODK_Message* msg, const ODK_PreparedLicenseRequestV17* obj); void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg, const ODK_PreparedRenewalRequest* obj); void Pack_ODK_PreparedProvisioningRequest( ODK_Message* msg, const ODK_PreparedProvisioningRequest* obj); +void Pack_ODK_PreparedProvisioningRequestV17( + ODK_Message* msg, const ODK_PreparedProvisioningRequestV17* obj); +void Pack_ODK_PreparedProvisioning40Request( + ODK_Message* msg, const ODK_PreparedProvisioning40Request* obj); void Pack_ODK_PreparedRenewedProvisioningRequest( ODK_Message* msg, const ODK_PreparedRenewedProvisioningRequest* obj); /* odk unpack */ void Unpack_ODK_CoreMessage(ODK_Message* msg, ODK_CoreMessage* obj); void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj); -void Unpack_ODK_LicenseResponseV16(ODK_Message* msg, - ODK_LicenseResponseV16* obj); void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj); void Unpack_ODK_ProvisioningResponse(ODK_Message* msg, ODK_ProvisioningResponse* obj); +void Unpack_ODK_ProvisioningResponseV16(ODK_Message* msg, + ODK_ProvisioningResponseV16* obj); +void Unpack_ODK_Provisioning40Response(ODK_Message* msg, + ODK_Provisioning40Response* obj); /* kdo pack */ -void Pack_ODK_LicenseResponse(ODK_Message* msg, const ODK_LicenseResponse* obj); -void Pack_ODK_LicenseResponseV16(ODK_Message* msg, - const ODK_LicenseResponseV16* obj); +void Pack_ODK_LicenseResponse(ODK_Message* msg, + const ODK_Packing_LicenseResponse* obj); void Pack_ODK_RenewalResponse(ODK_Message* msg, const ODK_RenewalResponse* obj); void Pack_ODK_ProvisioningResponse(ODK_Message* msg, const ODK_ProvisioningResponse* obj); +void Pack_ODK_ProvisioningResponseV16(ODK_Message* msg, + const ODK_ProvisioningResponseV16* obj); +void Pack_ODK_Provisioning40Response(ODK_Message* msg, + const ODK_Provisioning40Response* obj); /* kdo unpack */ void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg, ODK_PreparedLicenseRequest* obj); +void Unpack_ODK_PreparedLicenseRequestV17(ODK_Message* msg, + ODK_PreparedLicenseRequestV17* obj); void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg, ODK_PreparedRenewalRequest* obj); void Unpack_ODK_PreparedProvisioningRequest( ODK_Message* msg, ODK_PreparedProvisioningRequest* obj); +void Unpack_ODK_PreparedProvisioningRequestV180( + ODK_Message* msg, ODK_PreparedProvisioningRequest* obj); +void Unpack_ODK_PreparedProvisioningRequestV17( + ODK_Message* msg, ODK_PreparedProvisioningRequestV17* obj); +void Unpack_ODK_PreparedProvisioning40Request( + ODK_Message* msg, ODK_PreparedProvisioning40Request* obj); void Unpack_ODK_PreparedRenewedProvisioningRequest( ODK_Message* msg, ODK_PreparedRenewedProvisioningRequest* obj); diff --git a/oemcrypto/odk/src/odk_structs_priv.h b/oemcrypto/odk/src/odk_structs_priv.h index 3fe73eed..abfdc23b 100644 --- a/oemcrypto/odk/src/odk_structs_priv.h +++ b/oemcrypto/odk/src/odk_structs_priv.h @@ -25,8 +25,10 @@ typedef uint32_t ODK_MessageType; #define ODK_Provisioning_Request_Type ((ODK_MessageType)5u) #define ODK_Provisioning_Response_Type ((ODK_MessageType)6u) #define ODK_Renewed_Provisioning_Request_Type ((ODK_MessageType)11u) +#define ODK_Provisioning40_Request_Type ((ODK_MessageType)12u) -// Reserve future message types to support forward compatibility. +// TODO(b/244580447): Reserve future message types to support +// forward compatibility. #define ODK_Release_Request_Type ((ODK_MessageType)7u) #define ODK_Release_Response_Type ((ODK_MessageType)8u) #define ODK_Common_Request_Type ((ODK_MessageType)9u) @@ -40,18 +42,35 @@ typedef struct { typedef struct { ODK_CoreMessage core_message; + ODK_MessageCounterInfo counter_info; } ODK_PreparedLicenseRequest; +typedef struct { + ODK_CoreMessage core_message; +} ODK_PreparedLicenseRequestV17; + typedef struct { ODK_CoreMessage core_message; uint64_t playback_time; } ODK_PreparedRenewalRequest; +typedef struct { + ODK_CoreMessage core_message; + ODK_MessageCounterInfo counter_info; +} ODK_PreparedProvisioningRequest; + typedef struct { ODK_CoreMessage core_message; uint32_t device_id_length; uint8_t device_id[ODK_DEVICE_ID_LEN_MAX]; -} ODK_PreparedProvisioningRequest; +} ODK_PreparedProvisioningRequestV17; + +typedef struct { + ODK_CoreMessage core_message; + uint32_t device_info_length; + uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX]; + ODK_MessageCounterInfo counter_info; +} ODK_PreparedProvisioning40Request; typedef struct { ODK_CoreMessage core_message; @@ -67,27 +86,16 @@ typedef struct { } ODK_PreparedCommonRequest; typedef struct { - OEMCrypto_Substring enc_mac_keys_iv; - OEMCrypto_Substring enc_mac_keys; - OEMCrypto_Substring pst; - OEMCrypto_Substring srm_restriction_data; - OEMCrypto_LicenseType license_type; - bool nonce_required; - ODK_TimerLimits timer_limits; - uint32_t key_array_length; - OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS]; -} ODK_ParsedLicenseV16; - -typedef struct { - ODK_PreparedLicenseRequest request; + ODK_CoreMessage core_message; ODK_ParsedLicense* parsed_license; + uint8_t request_hash[ODK_SHA256_HASH_SIZE]; } ODK_LicenseResponse; typedef struct { - ODK_PreparedLicenseRequest request; - ODK_ParsedLicenseV16 parsed_license; + ODK_CoreMessage core_message; + ODK_Packing_ParsedLicense* parsed_license; uint8_t request_hash[ODK_SHA256_HASH_SIZE]; -} ODK_LicenseResponseV16; +} ODK_Packing_LicenseResponse; typedef struct { ODK_PreparedRenewalRequest request; @@ -95,18 +103,31 @@ typedef struct { } ODK_RenewalResponse; typedef struct { - ODK_PreparedProvisioningRequest request; + ODK_CoreMessage core_message; ODK_ParsedProvisioning* parsed_provisioning; } ODK_ProvisioningResponse; +// Used by V16 and V17 +typedef struct { + ODK_PreparedProvisioningRequestV17 request; + ODK_ParsedProvisioning* parsed_provisioning; +} ODK_ProvisioningResponseV16; + +typedef struct { + ODK_CoreMessage core_message; +} ODK_Provisioning40Response; + // These are the sum of sizeof of each individual member of the request structs // without any padding added by the compiler. Make sure they get updated when // request structs change. Refer to test suite OdkSizeTest in // ../test/odk_test.cpp for validations of each of the defined request sizes. -#define ODK_LICENSE_REQUEST_SIZE 20u +#define ODK_CORE_MESSAGE_SIZE 20u +#define ODK_LICENSE_REQUEST_SIZE 90u #define ODK_RENEWAL_REQUEST_SIZE 28u -#define ODK_PROVISIONING_REQUEST_SIZE 88u +#define ODK_PROVISIONING_REQUEST_SIZE 94u +#define ODK_PROVISIONING40_REQUEST_SIZE 862u #define ODK_RENEWED_PROVISIONING_REQUEST_SIZE 1694u +#define ODK_MESSAGECOUNTERINFO_SIZE 70u // These are the possible timer status values. #define ODK_CLOCK_TIMER_STATUS_UNDEFINED 0u // Should not happen. diff --git a/oemcrypto/odk/src/serialization_base.c b/oemcrypto/odk/src/serialization_base.c index 2ea30654..b84385bd 100644 --- a/oemcrypto/odk/src/serialization_base.c +++ b/oemcrypto/odk/src/serialization_base.c @@ -132,6 +132,18 @@ void Unpack_OEMCrypto_PrivateKeyType(ODK_Message* message, } } +void Unpack_OEMCrypto_TimerDelayBase(ODK_Message* message, + OEMCrypto_TimerDelayBase* value) { + assert(value); + uint32_t v32 = 0; + Unpack_uint32_t(message, &v32); + if (v32 <= OEMCrypto_TimerDelayBase_MaxValue) { + *value = (OEMCrypto_TimerDelayBase)v32; + } else { + ODK_Message_SetStatus(message, MESSAGE_STATUS_PARSE_ERROR); + } +} + void Unpack_bool(ODK_Message* message, bool* value) { uint8_t data[4] = {0}; UnpackBytes(message, data, sizeof(data)); diff --git a/oemcrypto/odk/src/serialization_base.h b/oemcrypto/odk/src/serialization_base.h index f3979376..299e0479 100644 --- a/oemcrypto/odk/src/serialization_base.h +++ b/oemcrypto/odk/src/serialization_base.h @@ -29,6 +29,8 @@ void Unpack_OEMCrypto_LicenseType(ODK_Message* message, OEMCrypto_LicenseType* value); void Unpack_OEMCrypto_PrivateKeyType(ODK_Message* message, OEMCrypto_PrivateKeyType* value); +void Unpack_OEMCrypto_TimerDelayBase(ODK_Message* message, + OEMCrypto_TimerDelayBase* value); void Unpack_bool(ODK_Message* message, bool* value); void Unpack_uint8_t(ODK_Message* message, uint8_t* value); void Unpack_uint16_t(ODK_Message* message, uint16_t* value); diff --git a/oemcrypto/odk/test/fuzzing/Android.bp b/oemcrypto/odk/test/fuzzing/Android.bp index 3b8fe6d6..f3512177 100644 --- a/oemcrypto/odk/test/fuzzing/Android.bp +++ b/oemcrypto/odk/test/fuzzing/Android.bp @@ -11,6 +11,7 @@ package { // all of the 'license_kinds' from "vendor_widevine_license" // to get the below license kinds: // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } diff --git a/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp b/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp index 78519cb0..0a0c0ae7 100644 --- a/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp +++ b/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp @@ -18,6 +18,7 @@ package { // all of the 'license_kinds' from "vendor_widevine_license" // to get the below license kinds: // legacy_by_exception_only (by exception only) + // legacy_proprietary (by exception only) default_applicable_licenses: ["vendor_widevine_license"], } diff --git a/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c b/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c index 0a2d0747..655bd06d 100644 --- a/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c +++ b/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c @@ -113,15 +113,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length, OEMCryptoResult ODK_PrepareCoreProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, - const ODK_NonceValues* nonce_values, const uint8_t* device_id, - size_t device_id_length) { + const ODK_NonceValues* nonce_values, + const ODK_MessageCounterInfo* counter_info) { OEMCryptoResult (*original_function)(uint8_t*, size_t, size_t*, - const ODK_NonceValues*, const uint8_t*, - size_t); + const ODK_NonceValues*, + const ODK_MessageCounterInfo*); original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreProvisioningRequest"); - OEMCryptoResult oem_crypto_result = - (*original_function)(message, message_length, core_message_length, - nonce_values, device_id, device_id_length); + OEMCryptoResult oem_crypto_result = (*original_function)( + message, message_length, core_message_length, nonce_values, counter_info); char* file_name = GetFileName("provisioning_request_corpus"); // Provisioning Request format expected by fuzzer - [Core Provisioning @@ -134,18 +133,19 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest( OEMCryptoResult ODK_ParseProvisioning( const uint8_t* message, size_t message_length, size_t core_message_length, const ODK_NonceValues* nonce_values, const uint8_t* device_id, - size_t device_id_length, ODK_ParsedProvisioning* parsed_response) { + size_t device_id_length, ODK_MessageCounterInfo* counter_info, + ODK_ParsedProvisioning* parsed_response) { struct ODK_ParseProvisioning_Args parse_provisioning_args; parse_provisioning_args.nonce_values = *nonce_values; memcpy(parse_provisioning_args.device_id, device_id, device_id_length); parse_provisioning_args.device_id_length = device_id_length; - OEMCryptoResult (*original_function)(const uint8_t*, size_t, size_t, - const ODK_NonceValues*, const uint8_t*, - size_t, ODK_ParsedProvisioning*); + OEMCryptoResult (*original_function)( + const uint8_t*, size_t, size_t, const ODK_NonceValues*, const uint8_t*, + size_t, ODK_MessageCounterInfo*, ODK_ParsedProvisioning*); original_function = dlsym(RTLD_NEXT, "ODK_ParseProvisioning"); OEMCryptoResult oem_crypto_result = (*original_function)( message, message_length, core_message_length, nonce_values, device_id, - device_id_length, parsed_response); + device_id_length, counter_info, parsed_response); char* file_name = GetFileName("provisioning_response_corpus"); // Provisioning Response format expected by fuzzer - diff --git a/oemcrypto/odk/test/fuzzing/odk_fuzz.gyp b/oemcrypto/odk/test/fuzzing/odk_fuzz.gyp index 7602e0a5..694e3acc 100644 --- a/oemcrypto/odk/test/fuzzing/odk_fuzz.gyp +++ b/oemcrypto/odk/test/fuzzing/odk_fuzz.gyp @@ -23,7 +23,7 @@ '-Wno-error=cast-qual', ], 'cflags_cc': [ - '-std=c++11', + '-std=c++14', '-g3', '-O0', '-fsanitize=fuzzer,address,undefined', diff --git a/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp b/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp index 1f3b2301..04905f1d 100644 --- a/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp +++ b/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp @@ -4,8 +4,12 @@ #include "fuzzing/odk_fuzz_helper.h" #include +#include +#include "core_message_types.h" #include "odk.h" +#include "odk_attributes.h" +#include "odk_structs.h" namespace oemcrypto_core_message { using features::CoreMessageFeatures; @@ -39,7 +43,11 @@ OEMCryptoResult odk_serialize_LicenseRequest( const void* in UNUSED, uint8_t* out, size_t* size, const ODK_LicenseRequest& core_license_request UNUSED, const ODK_NonceValues* nonce_values) { - return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values); + // TODO(mattfedd): hook up counters to fuzzer + const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0, + 0, 0, {0}, {0}, {0}}; + return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values, + &counter_info); } OEMCryptoResult odk_serialize_RenewalRequest( @@ -54,12 +62,13 @@ OEMCryptoResult odk_serialize_RenewalRequest( OEMCryptoResult odk_serialize_ProvisioningRequest( const void* in UNUSED, uint8_t* out, size_t* size, - const ODK_ProvisioningRequest& core_provisioning, + const ODK_ProvisioningRequest& core_provisioning UNUSED, const ODK_NonceValues* nonce_values) { - const std::string& device_id = core_provisioning.device_id; - return ODK_PrepareCoreProvisioningRequest( - out, SIZE_MAX, size, nonce_values, - reinterpret_cast(device_id.data()), device_id.size()); + // TODO(mattfedd): hook up counters to fuzzer + const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0, + 0, 0, {0}, {0}, {0}}; + return ODK_PrepareCoreProvisioningRequest(out, SIZE_MAX, size, nonce_values, + &counter_info); } OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message, @@ -69,9 +78,9 @@ OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message, ODK_ParsedLicense* parsed_lic) { return ODK_ParseLicense(message, SIZE_MAX, core_message_length, static_cast(a->initial_license_load), - static_cast(a->usage_entry_present), + static_cast(a->usage_entry_present), 0, &a->timer_limits, &a->clock_values, nonce_values, - parsed_lic); + parsed_lic, nullptr); } OEMCryptoResult odk_deserialize_RenewalResponse( @@ -119,13 +128,32 @@ bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args, const ODK_ParsedLicense& parsed_lic, std::string* oemcrypto_core_message) { const auto& nonce_values = args->nonce_values; - ODK_LicenseRequest core_request{nonce_values.api_minor_version, - nonce_values.api_major_version, - nonce_values.nonce, nonce_values.session_id}; + const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}}; + ODK_LicenseRequest core_request{ + nonce_values.api_minor_version, nonce_values.api_major_version, + nonce_values.nonce, nonce_values.session_id, counter_info}; std::string core_request_sha_256( reinterpret_cast(args->request_hash), ODK_SHA256_HASH_SIZE); + ODK_Packing_ParsedLicense parsed_license; + parsed_license.enc_mac_keys_iv = parsed_lic.enc_mac_keys_iv; + parsed_license.enc_mac_keys = parsed_lic.enc_mac_keys; + parsed_license.pst = parsed_lic.pst; + parsed_license.srm_restriction_data = parsed_lic.srm_restriction_data; + parsed_license.license_type = parsed_lic.license_type; + parsed_license.nonce_required = parsed_lic.nonce_required; + parsed_license.timer_limits = parsed_lic.timer_limits; + parsed_license.watermarking = parsed_lic.watermarking; + parsed_license.dtcp2_required = parsed_lic.dtcp2_required; + parsed_license.renewal_delay_base = parsed_lic.renewal_delay_base; + parsed_license.key_array_length = parsed_lic.key_array_length; + std::vector key_array; + size_t i; + for (i = 0; i < parsed_lic.key_array_length; i++) { + key_array.push_back(parsed_lic.key_array[i]); + } + parsed_license.key_array = key_array.data(); return serialize::CreateCoreLicenseResponse( - CoreMessageFeatures::kDefaultFeatures, parsed_lic, core_request, + CoreMessageFeatures::kDefaultFeatures, parsed_license, core_request, core_request_sha_256, oemcrypto_core_message); } @@ -151,11 +179,17 @@ bool kdo_serialize_ProvisioningResponse( if (args->device_id_length > sizeof(args->device_id)) { return false; } + const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}}; ODK_ProvisioningRequest core_request{ - nonce_values.api_minor_version, nonce_values.api_major_version, - nonce_values.nonce, nonce_values.session_id, + nonce_values.api_minor_version, + nonce_values.api_major_version, + nonce_values.nonce, + nonce_values.session_id, std::string(reinterpret_cast(args->device_id), - args->device_id_length)}; + args->device_id_length), + 0, + "", + counter_info}; return serialize::CreateCoreProvisioningResponse( CoreMessageFeatures::kDefaultFeatures, parsed_prov, core_request, oemcrypto_core_message); diff --git a/oemcrypto/odk/test/odk_core_message_test.cpp b/oemcrypto/odk/test/odk_core_message_test.cpp index 22051b22..db476ad0 100644 --- a/oemcrypto/odk/test/odk_core_message_test.cpp +++ b/oemcrypto/odk/test/odk_core_message_test.cpp @@ -2,14 +2,30 @@ // source code may only be used and distributed under the Widevine // License Agreement. +#include #include +#include +#include #include "OEMCryptoCENCCommon.h" +#include "core_message_deserialize.h" +#include "core_message_features.h" +#include "core_message_serialize_proto.h" +#include "core_message_types.h" #include "gtest/gtest.h" #include "odk.h" #include "third_party/absl/strings/escaping.h" namespace wvodk_test { + +using oemcrypto_core_message::ODK_CommonRequest; +using oemcrypto_core_message::ODK_ProvisioningRequest; +using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage; +using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage; +using oemcrypto_core_message::features::CoreMessageFeatures; +using oemcrypto_core_message::serialize:: + CreateCoreProvisioningResponseFromProto; + TEST(CoreMessageTest, RenwalRequest) { std::string oem = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst" @@ -36,4 +52,145 @@ TEST(CoreMessageTest, RenwalRequest) { char* m = reinterpret_cast(message); VLOG(0) << absl::BytesToHexString(std::string(m, core_message_length)); } + +TEST(CoreMessageTest, ParseCoreCommonRequestFromMessage) { + // Core message header format: + // message_type : 4 bytes + // message_length : 4 bytes + // minor_version : 2 bytes + // major_version : 2 bytes + // nonce : 4 bytes + // session_id : 4 bytes + const char kv16CoreMessageLicenseRequest[] = + "0000000100000014000300100000000100000001"; + std::string oemcrypto_core_message = + absl::HexStringToBytes(kv16CoreMessageLicenseRequest); + ODK_CommonRequest odk_common_request; + ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message, + &odk_common_request)); + EXPECT_EQ(odk_common_request.message_type, 1); + EXPECT_EQ(odk_common_request.message_length, 20); + EXPECT_EQ(odk_common_request.api_minor_version, 3); + EXPECT_EQ(odk_common_request.api_major_version, 16); + EXPECT_EQ(odk_common_request.nonce, 1); + EXPECT_EQ(odk_common_request.session_id, 1); +} + +struct TestParameters_18V0 { + std::string message; + uint16_t expected_api_minor_version; + uint16_t expected_api_major_version; + uint32_t expected_nonce; + uint32_t expected_session_id; + uint64_t expected_master_generation_number; +}; + +void PrintTo(const TestParameters_18V0& p, std::ostream* os) { + *os << "request = " << p.message << ", expected : {version = v" + << p.expected_api_major_version << "." << p.expected_api_minor_version + << ", nonce = " << p.expected_nonce + << ", session_id = " << p.expected_session_id + << ", master_generation_number = " << p.expected_master_generation_number + << "}"; +} + +class ProvisioningRoundTripTest_18V0 + : public ::testing::Test, + public ::testing::WithParamInterface {}; + +// Make sure that the first version of the V18 provisioning request (no hidden +// 4-byte value, all 0s in message counter struct) will still parse with +// current v18 code. This test is in this file rather than odk_test.cpp +// because of the use of absl::HexStringToBytes +TEST_P(ProvisioningRoundTripTest_18V0, ProvisioningRoundtrip) { + TestParameters_18V0 tc = GetParam(); + + ODK_ProvisioningRequest request; + + // Make sure we can parse the request + ASSERT_TRUE(CoreProvisioningRequestFromMessage( + absl::HexStringToBytes(tc.message), &request)); + EXPECT_EQ(request.api_minor_version, tc.expected_api_minor_version); + EXPECT_EQ(request.api_major_version, tc.expected_api_major_version); + EXPECT_EQ(request.nonce, tc.expected_nonce); + EXPECT_EQ(request.session_id, tc.expected_session_id); + + if (request.api_major_version >= 18) { + EXPECT_EQ(request.counter_info.master_generation_number, + tc.expected_master_generation_number); + } + + // Make sure we can create a response from that request with the same core + // message + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + std::string serialized_provisioning_resp; + video_widevine::ProvisioningResponse provisioning_response; + provisioning_response.set_device_certificate("device_certificate"); + provisioning_response.set_device_rsa_key("device_rsa_key"); + provisioning_response.set_device_rsa_key_iv("device_rsa_key_iv"); + if (!provisioning_response.SerializeToString(&serialized_provisioning_resp)) { + FAIL() << "Cannot set up prov response"; + } + std::string oemcrypto_core_message; + EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( + features, serialized_provisioning_resp, request, + OEMCrypto_RSA_Private_Key, &oemcrypto_core_message)); + + // Extract core message from generated prov response and match values with + // request + ODK_CommonRequest odk_common_request; + ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message, + &odk_common_request)); + EXPECT_EQ(odk_common_request.message_type, 6u); + EXPECT_EQ(odk_common_request.nonce, tc.expected_nonce); + EXPECT_EQ(odk_common_request.session_id, tc.expected_session_id); +} + +std::vector TestCases() { + return std::vector{ + // Source: ODKTest ProvisionRequestRoundtrip running on v18.0 ODK checkout + {"000000050000005a00000012deadbeefcafebabe12345678abcdffff0000000c0000003" + "200000154001200000004ffffffffffffffffffffffffffffffffdddddddddddddddddd" + "ddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee", + 0, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff}, + // same as previous request, but replace counter info with all 0s + {"000000050000005a00000012deadbeefcafebabe0000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000", + 0, 18, 0xdeadbeef, 0xcafebabe, 0x0}, + // Source: ODKTest ProvisionRequestRoundtrip running on v17.2 ODK checkout + {"000000050000005800020011deadbeefcafebabe00000020fffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000" + "0000000000000000000000000000000000", + 2, 17, 0xdeadbeef, 0xcafebabe, 0x0}, + // Source: ODKTest ProvisionRequestRoundtrip running on v18.2 ODK checkout + {"000000050000005e00020012deadbeefcafebabe0000004012345678abcdffff0000000" + "c0000003200000154001200020004ffffffffffffffffffffffffffffffffdddddddddd" + "ddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee", + 2, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff}, + // Source: CDM unit tests on oemcrypto-v18 internal commit 5c77383 (pre + // v18.0 -> v18.1 ODK bump) + {"000000050000005a00000012b85dfa09000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000", + 0, 18, 0xb85dfa09, 0x0, 0x0}, + // Same as above but non-zero counter info + {"000000050000005a00000012b85dfa09000000001000000000000001000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000", + 0, 18, 0xb85dfa09, 0x0, 0x1000000000000001}, + // Source: CDM unit tests on oemcrypto-v18 internal commit fc46827a (post + // v18.0 -> v18.1 ODK bump) + {"000000050000005e000100127c8ac703000000000000004000000000000000000000000" + "00000000000000000001200010000746573740000000000000000000000007465737400" + "0000000000000000000000000000000000000000000000", + 1, 18, 0x7c8ac703, 0x0, 0x0}, + }; +} + +INSTANTIATE_TEST_SUITE_P(ProvisioningRoundTripTests_18V0, + ProvisioningRoundTripTest_18V0, + ::testing::ValuesIn(TestCases())); + } // namespace wvodk_test diff --git a/oemcrypto/odk/test/odk_golden_v16.cpp b/oemcrypto/odk/test/odk_golden_v16.cpp index ba0e6aa9..2e80b0a9 100644 --- a/oemcrypto/odk/test/odk_golden_v16.cpp +++ b/oemcrypto/odk/test/odk_golden_v16.cpp @@ -1,20 +1,17 @@ -// Copyright 2022 Google LLC. All rights reserved. This file and proprietary +// Copyright 2023 Google LLC. All rights reserved. This file and proprietary // source code may only be used and distributed under the Widevine // License Agreement. -#include "odk.h" - #include #include - #include -#include "gtest/gtest.h" - #include "core_message_deserialize.h" #include "core_message_serialize.h" #include "core_message_serialize_proto.h" #include "core_message_types.h" +#include "gtest/gtest.h" +#include "odk.h" #include "odk_structs.h" #include "odk_structs_priv.h" @@ -46,10 +43,11 @@ class ODKGoldenProvisionV16 : public ::testing::Test { CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( features, provisioning_response_, core_provisioning_request, - &generated_core_message)); + device_key_type_, &generated_core_message)); EXPECT_EQ(core_response_, generated_core_message); } + OEMCrypto_PrivateKeyType device_key_type_ = OEMCrypto_RSA_Private_Key; std::string core_request_; std::string core_response_; std::string provisioning_response_; @@ -71,8 +69,7 @@ class ODKGoldenLicenseV16 : public ::testing::Test { EXPECT_EQ(core_response_, generated_core_message); } - bool nonce_required_; - // TODO(fredgc): padding is removed in protocol 2.2. + bool nonce_required_ = true; bool uses_padding_ = true; std::string core_request_; std::string core_response_; @@ -101,7 +98,8 @@ class ODKGoldenRenewalV16 : public ::testing::Test { std::string renewal_; }; -// README (for ODK maintainers): Set the environment variable DUMP_LICENSE="yes" +// README (for ODK maintainers): Set the environment variable +// DUMP_GOLDEN_DATA="yes" // Then set the environment variable GTEST_FILTER to the test you want to run. // Run the script for the platform we want. E.g. run_fake_l1_tests, // run_prov30_tests or run_prov40_tests. Look for the autogenerated code in diff --git a/oemcrypto/odk/test/odk_golden_v17.cpp b/oemcrypto/odk/test/odk_golden_v17.cpp index 2a734087..786c6783 100644 --- a/oemcrypto/odk/test/odk_golden_v17.cpp +++ b/oemcrypto/odk/test/odk_golden_v17.cpp @@ -1,20 +1,17 @@ -// Copyright 2022 Google LLC. All rights reserved. This file and proprietary +// Copyright 2023 Google LLC. All rights reserved. This file and proprietary // source code may only be used and distributed under the Widevine // License Agreement. -#include "odk.h" - #include #include - #include -#include "gtest/gtest.h" - #include "core_message_deserialize.h" #include "core_message_serialize.h" #include "core_message_serialize_proto.h" #include "core_message_types.h" +#include "gtest/gtest.h" +#include "odk.h" #include "odk_structs.h" #include "odk_structs_priv.h" @@ -46,10 +43,11 @@ class ODKGoldenProvisionV17 : public ::testing::Test { CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( features, provisioning_response_, core_provisioning_request, - &generated_core_message)); + device_key_type_, &generated_core_message)); EXPECT_EQ(core_response_, generated_core_message); } + OEMCrypto_PrivateKeyType device_key_type_ = OEMCrypto_RSA_Private_Key; std::string core_request_; std::string core_response_; std::string provisioning_response_; @@ -71,8 +69,7 @@ class ODKGoldenLicenseV17 : public ::testing::Test { EXPECT_EQ(core_response_, generated_core_message); } - bool nonce_required_; - // TODO(fredgc): padding is removed in protocol 2.2. + bool nonce_required_ = true; bool uses_padding_ = true; std::string core_request_; std::string core_response_; @@ -101,7 +98,8 @@ class ODKGoldenRenewalV17 : public ::testing::Test { std::string renewal_; }; -// README (for ODK maintainers): Set the environment variable DUMP_LICENSE="yes" +// README (for ODK maintainers): Set the environment variable +// DUMP_GOLDEN_DATA="yes" // Then set the environment variable GTEST_FILTER to the test you want to run. // Run the script for the platform we want. E.g. run_fake_l1_tests, // run_prov30_tests or run_prov40_tests. Look for the autogenerated code in @@ -3844,4 +3842,5 @@ TEST_F(ODKGoldenRenewalV17, Both_CdmUseCase_Heartbeat_Case1_0) { } ////////////////////////////////////////////////////////////////////// } // namespace + } // namespace wvodk_test diff --git a/oemcrypto/odk/test/odk_golden_v18.cpp b/oemcrypto/odk/test/odk_golden_v18.cpp new file mode 100644 index 00000000..c1adfb1e --- /dev/null +++ b/oemcrypto/odk/test/odk_golden_v18.cpp @@ -0,0 +1,4574 @@ +// Copyright 2023 Google LLC. All rights reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. + +#include +#include +#include + +#include "core_message_deserialize.h" +#include "core_message_serialize.h" +#include "core_message_serialize_proto.h" +#include "core_message_types.h" +#include "gtest/gtest.h" +#include "odk.h" +#include "odk_structs.h" +#include "odk_structs_priv.h" + +namespace wvodk_test { + +namespace { + +using oemcrypto_core_message::ODK_LicenseRequest; +using oemcrypto_core_message::ODK_ProvisioningRequest; +using oemcrypto_core_message::ODK_RenewalRequest; + +using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage; +using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage; +using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage; +using oemcrypto_core_message::features::CoreMessageFeatures; +using oemcrypto_core_message::serialize::CreateCoreLicenseResponseFromProto; +using oemcrypto_core_message::serialize:: + CreateCoreProvisioningResponseFromProto; +using oemcrypto_core_message::serialize::CreateCoreRenewalResponse; + +class ODKGoldenProvisionV18 : public ::testing::Test { + protected: + void RunTest() { + ODK_ProvisioningRequest core_provisioning_request; + EXPECT_TRUE(CoreProvisioningRequestFromMessage(core_request_, + &core_provisioning_request)); + std::string generated_core_message; + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( + features, provisioning_response_, core_provisioning_request, + device_key_type_, &generated_core_message)); + EXPECT_EQ(core_response_, generated_core_message); + } + + OEMCrypto_PrivateKeyType device_key_type_ = OEMCrypto_RSA_Private_Key; + std::string core_request_; + std::string core_response_; + std::string provisioning_response_; +}; + +class ODKGoldenLicenseV18 : public ::testing::Test { + protected: + void RunTest() { + ODK_LicenseRequest core_license_request; + EXPECT_TRUE( + CoreLicenseRequestFromMessage(core_request_, &core_license_request)); + std::string generated_core_message; + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + EXPECT_TRUE(CreateCoreLicenseResponseFromProto( + features, serialized_license_, core_license_request, + core_request_sha256_, nonce_required_, uses_padding_, + &generated_core_message)); + EXPECT_EQ(core_response_, generated_core_message); + } + + bool nonce_required_ = true; + bool uses_padding_ = true; // This will change for v19. + std::string core_request_; + std::string core_response_; + std::string serialized_license_; + std::string core_request_sha256_; +}; + +class ODKGoldenRenewalV18 : public ::testing::Test { + protected: + void RunTest() { + ODK_RenewalRequest core_renewal_request; + EXPECT_TRUE( + CoreRenewalRequestFromMessage(core_request_, &core_renewal_request)); + std::string generated_core_message; + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + EXPECT_TRUE(CreateCoreRenewalResponse(features, core_renewal_request, + renewal_duration_seconds_, + &generated_core_message)); + EXPECT_EQ(core_response_, generated_core_message); + } + + uint64_t renewal_duration_seconds_; + std::string core_request_; + std::string core_response_; + std::string renewal_; +}; + +// README (for ODK maintainers): Set the environment variable +// DUMP_GOLDEN_DATA="yes" +// Then set the environment variable GTEST_FILTER to the test you want to run. +// Run the script for the platform we want. E.g. run_fake_l1_tests, +// run_prov30_tests or run_prov40_tests. Look for the autogenerated code in +// $CDM_DIR/out/testbed/debug/*_data.cpp. If you are updating the ODK library, +// and you have to change the code above, then you're fine. If you have to +// change the code below then there is probably a backwards compatibility +// problem. + +////////////////////////////////////////////////////////////////////// +// Provisioning tests. +// One provisioning example from each of fake-l1 (with keybox), prov20ecc +// and prov30. For v18, Prov 4.0 does not use a core message. +// GTEST_FILTER='*CorePIGTest.OfflineNoNonce*" +////////////////////////////////////////////////////////////////////// +TEST_F(ODKGoldenProvisionV18, CorePIGTest_OfflineNoNonce_prov20) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x02, 0x00, 0x12, + 0xcf, 0x3a, 0x5f, 0x1b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x12, + 0xcf, 0x3a, 0x5f, 0x1b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xd0, 0x00, 0x00, 0x04, 0xd5, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t provisioning_response_raw[] = { + 0x0a, 0xd0, 0x09, 0xcc, 0x78, 0xcb, 0xbc, 0xf8, 0xb6, 0x81, 0xfb, 0x5c, + 0x39, 0xf0, 0xef, 0x36, 0xea, 0x95, 0x47, 0x23, 0x84, 0x25, 0xb2, 0xba, + 0x6a, 0xe3, 0xed, 0x74, 0xdf, 0x38, 0xe7, 0x93, 0x3e, 0x48, 0xac, 0x92, + 0x13, 0x95, 0xa0, 0x78, 0x0d, 0x4c, 0x8f, 0xb8, 0x01, 0xe8, 0x7b, 0xc9, + 0x55, 0xc6, 0x03, 0x28, 0x33, 0xa4, 0x8c, 0x16, 0xc7, 0x6c, 0xa4, 0xae, + 0xb4, 0x5e, 0xd9, 0xea, 0x84, 0x29, 0xf2, 0xa7, 0x6a, 0xe8, 0xe6, 0x1c, + 0x56, 0xd6, 0x01, 0xea, 0x31, 0xc7, 0x94, 0x71, 0x9c, 0x53, 0x43, 0x75, + 0x94, 0xfe, 0x89, 0x70, 0x7b, 0xd5, 0xf7, 0xcf, 0x3d, 0xc9, 0x7b, 0x1a, + 0x56, 0xd2, 0x8b, 0x1b, 0x44, 0xf8, 0x51, 0x36, 0x57, 0x33, 0x7a, 0x3f, + 0x8d, 0xa5, 0x9d, 0x97, 0x4a, 0x02, 0x90, 0x62, 0x93, 0xc9, 0x02, 0x74, + 0x2c, 0x8d, 0xc1, 0x95, 0xef, 0xcc, 0x71, 0xd0, 0xc7, 0x1e, 0xff, 0x67, + 0x75, 0x84, 0x44, 0x18, 0xa1, 0x98, 0xdd, 0xca, 0x55, 0x2b, 0x75, 0x33, + 0xfc, 0x50, 0x87, 0x6c, 0xbb, 0x72, 0x5a, 0xc7, 0xcf, 0x9d, 0xed, 0x60, + 0x28, 0x29, 0x77, 0x14, 0xd7, 0x2e, 0xb2, 0x27, 0x37, 0xa7, 0x5b, 0x80, + 0x5c, 0xe8, 0x22, 0xe8, 0xde, 0x93, 0xe4, 0x79, 0xa9, 0x2d, 0xb4, 0xfc, + 0x57, 0x1a, 0xa6, 0x2b, 0xb9, 0xc6, 0x22, 0x51, 0x9e, 0x2d, 0x56, 0x00, + 0x6d, 0xc6, 0x79, 0x7a, 0x6f, 0xf4, 0x53, 0xe5, 0xc4, 0x27, 0x94, 0xa0, + 0x4b, 0x83, 0x1a, 0x43, 0xb0, 0x4b, 0x13, 0x3c, 0x56, 0x5d, 0x1c, 0x98, + 0x0d, 0xab, 0xbd, 0x7b, 0xd9, 0x4e, 0x26, 0x19, 0x69, 0xaf, 0x5a, 0xcd, + 0xcf, 0x3e, 0xae, 0xc2, 0x39, 0x8c, 0xa0, 0xb4, 0x9d, 0x72, 0xd4, 0x98, + 0xdc, 0x53, 0x92, 0x3f, 0xc8, 0xd2, 0x7e, 0xfd, 0x00, 0xfb, 0x22, 0x8e, + 0xdc, 0xc2, 0x09, 0xd3, 0xb6, 0x0c, 0x0e, 0xe7, 0x04, 0xd2, 0x2b, 0x98, + 0x4d, 0x7c, 0x9a, 0xae, 0x4e, 0xa4, 0x84, 0x3c, 0x44, 0x10, 0x65, 0x90, + 0xdc, 0x1b, 0x82, 0xd0, 0x38, 0xb1, 0x40, 0x02, 0xf7, 0xf0, 0xbb, 0xcf, + 0x8a, 0x6b, 0xd3, 0xd0, 0x88, 0x52, 0xb4, 0x2e, 0x92, 0xa3, 0xcb, 0x65, + 0xff, 0xbd, 0x5c, 0xe5, 0x6a, 0xba, 0x7c, 0x67, 0x6f, 0x52, 0xa9, 0xf4, + 0xde, 0xf1, 0x47, 0xca, 0x0c, 0x25, 0xcd, 0xa8, 0x37, 0x88, 0x10, 0x08, + 0xef, 0x0a, 0x30, 0x53, 0xed, 0xe2, 0x7c, 0x1a, 0x55, 0x89, 0x6c, 0x7d, + 0xfb, 0x6a, 0x71, 0xda, 0x0f, 0x02, 0xf1, 0x69, 0x85, 0x07, 0x5b, 0xbd, + 0x7d, 0xe7, 0x5c, 0x21, 0xd3, 0xfc, 0xb6, 0x80, 0xcb, 0x63, 0x77, 0xdf, + 0x24, 0x12, 0x33, 0x86, 0x5d, 0xd0, 0xa5, 0xaf, 0x21, 0x52, 0x2c, 0xaf, + 0x4d, 0xbe, 0xcc, 0x3d, 0x14, 0x96, 0x97, 0x04, 0xb5, 0x7c, 0xf3, 0x44, + 0x82, 0x63, 0xea, 0x17, 0xa2, 0x09, 0xaa, 0x24, 0xc2, 0xdf, 0x04, 0xd4, + 0x3f, 0xb0, 0x67, 0xbc, 0x4c, 0xe2, 0x0e, 0xad, 0xfc, 0xe6, 0xa0, 0x9d, + 0x8c, 0xb6, 0x40, 0x09, 0x82, 0x9f, 0xe3, 0xda, 0x47, 0xb5, 0xbf, 0x0d, + 0xb4, 0xa7, 0x2b, 0xee, 0xc2, 0x89, 0x34, 0x33, 0x76, 0xa6, 0x3d, 0xbe, + 0xd6, 0x81, 0xa5, 0x94, 0xb9, 0x81, 0x90, 0xae, 0x89, 0xe4, 0x10, 0xbd, + 0x7c, 0xbe, 0x81, 0xbc, 0x18, 0x05, 0xb4, 0x13, 0xf1, 0xe8, 0xba, 0xdb, + 0x3e, 0x04, 0xc4, 0xb3, 0x31, 0x14, 0x19, 0xec, 0xe9, 0x16, 0x69, 0x10, + 0xbf, 0x64, 0xb0, 0x94, 0x26, 0xd2, 0xd7, 0x01, 0xd0, 0x8b, 0x53, 0xf8, + 0xd8, 0x54, 0xdb, 0x6e, 0x0f, 0x2d, 0xc6, 0x99, 0x06, 0xbf, 0xfe, 0x9e, + 0x35, 0x83, 0x4c, 0xda, 0xb5, 0x90, 0x71, 0xc4, 0x90, 0xeb, 0x01, 0x83, + 0xde, 0x6d, 0xfc, 0xaf, 0x04, 0x5f, 0xd6, 0x25, 0x4d, 0x8a, 0x93, 0x47, + 0xac, 0x7d, 0x52, 0xea, 0xfe, 0x34, 0xad, 0xce, 0x2d, 0xd5, 0xd7, 0x78, + 0xce, 0xe5, 0x8e, 0x5c, 0x00, 0x2e, 0xc9, 0x6c, 0x48, 0x6e, 0x4f, 0x19, + 0x6f, 0x3f, 0xa8, 0x79, 0x6c, 0x6e, 0x1f, 0xd9, 0x9d, 0x9f, 0xf4, 0x62, + 0x25, 0x84, 0x35, 0x30, 0xf2, 0xd2, 0xbd, 0x2a, 0xec, 0x2d, 0xc3, 0xa3, + 0x02, 0xff, 0x9b, 0xfd, 0x6b, 0x8e, 0x0b, 0x16, 0x18, 0xf2, 0x99, 0xb8, + 0x15, 0x9a, 0x1c, 0x8f, 0x89, 0x02, 0x07, 0xed, 0x66, 0x69, 0x35, 0x13, + 0x25, 0xf6, 0xfb, 0x30, 0x8c, 0x94, 0xb6, 0x98, 0xc0, 0x8b, 0xfd, 0x47, + 0xbe, 0x66, 0x84, 0x51, 0x59, 0x6d, 0x1c, 0x00, 0x7a, 0xa1, 0x35, 0xf4, + 0x67, 0xf1, 0xa6, 0xc4, 0x30, 0xb4, 0x85, 0x74, 0x2e, 0x3e, 0x28, 0x22, + 0x51, 0xfe, 0x54, 0x88, 0xcc, 0x8a, 0xe4, 0x04, 0xc6, 0x10, 0xbd, 0x5b, + 0x91, 0x02, 0xb0, 0x37, 0x7d, 0x3b, 0xcd, 0x98, 0x2e, 0x8c, 0x5f, 0x63, + 0x7e, 0x58, 0x58, 0x18, 0x13, 0x1d, 0x32, 0x29, 0x3e, 0xb8, 0x95, 0xed, + 0x2b, 0xc1, 0xd0, 0xab, 0x33, 0x9c, 0x82, 0xa9, 0xcf, 0xcf, 0x21, 0x2e, + 0x7c, 0x05, 0xe7, 0xa7, 0xbb, 0xc1, 0x63, 0x4a, 0x1e, 0xb5, 0x04, 0x13, + 0x30, 0x34, 0xa1, 0x8b, 0x5a, 0x84, 0x53, 0x66, 0x42, 0xed, 0xc3, 0xd7, + 0x14, 0xf5, 0xf4, 0x19, 0x78, 0x95, 0xd1, 0x16, 0xc9, 0x5c, 0xbd, 0x05, + 0xf9, 0xe0, 0xe0, 0x96, 0x8c, 0x51, 0x3f, 0xb4, 0x38, 0x78, 0x59, 0x79, + 0xe8, 0xbc, 0x66, 0x26, 0xc2, 0x46, 0xee, 0xbb, 0x58, 0xfa, 0x06, 0xfe, + 0x24, 0x54, 0x8c, 0x06, 0xe5, 0xc1, 0x58, 0x74, 0x22, 0xb6, 0x94, 0x17, + 0xe6, 0x27, 0x09, 0xab, 0x5b, 0x89, 0x3a, 0xbd, 0x29, 0x8b, 0xc7, 0xf4, + 0x67, 0x51, 0x79, 0xf7, 0x34, 0x2c, 0xb1, 0x84, 0x5f, 0xd8, 0x46, 0xf6, + 0x30, 0xc3, 0xf6, 0xb6, 0x11, 0x2d, 0x0a, 0x6f, 0x0c, 0x54, 0x37, 0x13, + 0x26, 0x4c, 0x17, 0xe8, 0x08, 0x68, 0x84, 0xea, 0xad, 0x48, 0x8b, 0x65, + 0x20, 0xa5, 0x3e, 0x54, 0x15, 0x25, 0xae, 0xb6, 0x2f, 0xae, 0xf3, 0x4f, + 0xb5, 0x5a, 0xb2, 0x26, 0xb6, 0xcb, 0xe4, 0xcf, 0x30, 0x4b, 0x79, 0xba, + 0xd3, 0xd4, 0xb5, 0x7e, 0xe5, 0xc4, 0x2f, 0xf7, 0x39, 0xd6, 0x75, 0xd6, + 0xb2, 0x8d, 0xab, 0x44, 0xe5, 0x5e, 0x0f, 0x87, 0xa2, 0x1d, 0xc0, 0x1e, + 0xa4, 0xe4, 0xf4, 0x90, 0x47, 0x40, 0xb8, 0xec, 0x3d, 0x7e, 0x9a, 0x90, + 0x8c, 0x56, 0x92, 0x82, 0xd7, 0x37, 0xe2, 0x50, 0x39, 0x29, 0xc4, 0x6c, + 0xa6, 0x57, 0xfc, 0xfc, 0xe1, 0x5e, 0xa4, 0x5b, 0xa8, 0xec, 0x05, 0x09, + 0xfd, 0xcf, 0x4f, 0xb7, 0x82, 0x4e, 0xb1, 0xfc, 0x95, 0x74, 0x0a, 0x17, + 0xdc, 0xc5, 0xc4, 0x1e, 0x6a, 0x60, 0x9f, 0x62, 0x77, 0x31, 0x69, 0xdc, + 0x2d, 0x13, 0x2a, 0x6b, 0xa3, 0x0c, 0x69, 0xfd, 0x7d, 0x1f, 0x52, 0xde, + 0xbb, 0xfd, 0x4d, 0x94, 0xf2, 0x55, 0xfb, 0x3b, 0x28, 0xd0, 0xc1, 0x5d, + 0xe4, 0xe9, 0x72, 0xa3, 0x70, 0x08, 0x00, 0xc5, 0x07, 0x37, 0x89, 0x50, + 0xd7, 0x08, 0x42, 0x39, 0x10, 0xa6, 0xb9, 0xb5, 0x23, 0x3d, 0xd7, 0xd3, + 0x7b, 0x94, 0x45, 0x11, 0x0f, 0x60, 0x0a, 0x55, 0x28, 0xb9, 0x16, 0xfa, + 0x53, 0xa1, 0x7c, 0x6d, 0x19, 0x8b, 0xad, 0x11, 0x5e, 0x67, 0xb1, 0xba, + 0xc9, 0x71, 0x9b, 0xf8, 0x43, 0x3d, 0x98, 0xe5, 0x5f, 0x49, 0x90, 0xf3, + 0x6c, 0x59, 0x67, 0xea, 0x1f, 0xe1, 0x61, 0x57, 0x1d, 0xb5, 0x31, 0x3f, + 0x24, 0x4e, 0x42, 0x4a, 0xfd, 0x28, 0xea, 0x46, 0x62, 0x4a, 0x89, 0xa8, + 0xd6, 0x62, 0x5e, 0x51, 0x16, 0x69, 0x83, 0x23, 0x51, 0x91, 0x2b, 0x27, + 0xe0, 0xf0, 0x76, 0x1b, 0x6f, 0x67, 0xf6, 0xfc, 0x03, 0xf0, 0x45, 0x94, + 0xed, 0xd2, 0x6f, 0xcc, 0x2c, 0x24, 0xdd, 0x5a, 0x2e, 0xa6, 0xac, 0xf2, + 0x25, 0x5a, 0x61, 0x62, 0xff, 0x30, 0x34, 0xd3, 0x6e, 0xde, 0x15, 0x19, + 0xe2, 0xde, 0x9c, 0xfb, 0x77, 0x73, 0x3c, 0x11, 0xd6, 0x69, 0x78, 0x4e, + 0x37, 0x88, 0x61, 0xe4, 0xfd, 0x42, 0xf6, 0x5f, 0xc0, 0x00, 0x8a, 0x14, + 0x71, 0xc4, 0x7f, 0x54, 0xc3, 0xd8, 0x87, 0x6a, 0x08, 0x92, 0x3d, 0x2d, + 0x57, 0x0c, 0x0f, 0x56, 0x57, 0x02, 0xa9, 0x1f, 0x74, 0xcc, 0x96, 0x65, + 0x90, 0x17, 0xbf, 0xf5, 0x30, 0x19, 0x27, 0x37, 0xea, 0xe1, 0xe9, 0xa7, + 0xbe, 0x92, 0x9d, 0x88, 0xe1, 0x39, 0x92, 0x49, 0x1e, 0xc7, 0x18, 0x31, + 0x8f, 0x9f, 0x68, 0x2f, 0x56, 0x7d, 0x63, 0xb1, 0x8a, 0xe5, 0xba, 0x23, + 0x75, 0x1b, 0x3f, 0xd0, 0x71, 0xad, 0x74, 0x1a, 0x02, 0xc5, 0x21, 0x10, + 0x3f, 0x06, 0x7c, 0x36, 0x3d, 0x65, 0x98, 0x16, 0xc2, 0x90, 0x1a, 0xe6, + 0x4c, 0xa8, 0x52, 0xe1, 0x64, 0xde, 0xd9, 0xa7, 0x04, 0x2d, 0x32, 0x36, + 0xeb, 0x5c, 0xa7, 0x95, 0x15, 0x91, 0x15, 0x9a, 0x1f, 0x7f, 0x5c, 0xa3, + 0x55, 0x04, 0x2b, 0x9f, 0x89, 0xd0, 0x8e, 0xac, 0x4f, 0x95, 0x13, 0x8b, + 0x9c, 0x56, 0x6c, 0x9f, 0x82, 0xe0, 0x5a, 0x44, 0x83, 0x89, 0x25, 0x34, + 0x60, 0x86, 0x37, 0xd7, 0x58, 0x71, 0xa2, 0x21, 0x4f, 0x6a, 0x27, 0xff, + 0xf4, 0x02, 0x2b, 0x31, 0xd8, 0xec, 0x5a, 0x7d, 0xe8, 0x55, 0x19, 0x12, + 0x10, 0x26, 0x06, 0x38, 0x1f, 0xe5, 0x86, 0x4d, 0x00, 0x08, 0x3c, 0x7a, + 0x49, 0x29, 0xfd, 0x0b, 0x77, 0x1a, 0xaa, 0x0b, 0x0a, 0xeb, 0x03, 0x08, + 0x02, 0x12, 0x10, 0x7c, 0xb4, 0x9f, 0x98, 0x7a, 0x63, 0x5e, 0x1e, 0x0a, + 0x52, 0x18, 0x46, 0x94, 0x58, 0x2d, 0x6e, 0x18, 0xec, 0xf5, 0x92, 0xa2, + 0x06, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xaa, 0x2e, 0x47, 0xb8, 0x48, 0x93, 0xf1, 0x45, 0x3f, 0xca, 0x0f, + 0xbc, 0xdf, 0x3a, 0x3f, 0x44, 0x82, 0xee, 0x0c, 0xd3, 0xc3, 0x8f, 0xeb, + 0x8c, 0xda, 0x35, 0xa7, 0x39, 0x20, 0xff, 0xd5, 0x4a, 0x71, 0x50, 0xfd, + 0x22, 0x4a, 0x9e, 0x1a, 0x51, 0x33, 0x90, 0xa8, 0xf3, 0xe9, 0xe1, 0x66, + 0xa8, 0xcd, 0x8f, 0xfb, 0x23, 0x27, 0x94, 0xb5, 0xd7, 0x79, 0xbd, 0x03, + 0x98, 0x74, 0x6c, 0x7e, 0xfc, 0x8a, 0x85, 0x4e, 0x5f, 0x98, 0x33, 0x77, + 0x67, 0xb9, 0xc8, 0x90, 0xc4, 0xfc, 0x63, 0x1f, 0x45, 0xd7, 0x67, 0x9f, + 0x1f, 0xf1, 0x9e, 0x30, 0x36, 0xd6, 0xd2, 0x31, 0x73, 0x4c, 0x64, 0x20, + 0x61, 0x18, 0x1c, 0xe8, 0xad, 0x65, 0xdb, 0x6e, 0x8e, 0xb5, 0x80, 0x22, + 0x98, 0xe2, 0xcb, 0x65, 0x28, 0xc1, 0xd0, 0x24, 0xc0, 0x9d, 0xf6, 0x94, + 0x02, 0x74, 0x16, 0x1e, 0xe2, 0x0e, 0xf0, 0x37, 0x41, 0x59, 0x00, 0x3a, + 0x76, 0x25, 0x67, 0xb3, 0x77, 0xcf, 0xcc, 0x1f, 0xbf, 0x3d, 0x30, 0x42, + 0xa6, 0xf1, 0xb6, 0x7b, 0x5f, 0x3b, 0x5d, 0x88, 0x13, 0x9a, 0xe1, 0xbf, + 0x05, 0x74, 0x72, 0x33, 0x94, 0x9e, 0x5a, 0xc9, 0x29, 0x09, 0x04, 0x46, + 0x3f, 0x7c, 0x8d, 0xe8, 0xd2, 0xc1, 0x69, 0xb2, 0xb4, 0x0d, 0xca, 0x5f, + 0x6c, 0x7e, 0x99, 0x28, 0x8c, 0x77, 0x07, 0xec, 0x7c, 0xe2, 0x4f, 0xc0, + 0x90, 0xd2, 0xac, 0x76, 0x87, 0x8e, 0x99, 0x39, 0x19, 0x67, 0x96, 0x18, + 0xc9, 0xe6, 0xc8, 0xd4, 0x18, 0xd9, 0x13, 0x85, 0xbc, 0xee, 0x93, 0xdd, + 0xf2, 0x2b, 0xf2, 0x15, 0x40, 0x8d, 0xf2, 0x78, 0xc6, 0x69, 0xc5, 0xe3, + 0x05, 0x6e, 0x28, 0x40, 0xe4, 0x11, 0xcf, 0x20, 0xee, 0x53, 0xea, 0x62, + 0x5f, 0x57, 0x89, 0xf5, 0xe2, 0x77, 0x52, 0x18, 0x4d, 0x39, 0xcc, 0x84, + 0x73, 0x5a, 0x18, 0x22, 0x81, 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0xe8, + 0x3d, 0x3a, 0x0c, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x48, 0x01, 0x52, 0xaa, 0x01, 0x08, 0x01, 0x10, 0x00, + 0x1a, 0x81, 0x01, 0x04, 0x5d, 0xc0, 0xcb, 0x28, 0xe6, 0x81, 0x2d, 0xc6, + 0xc1, 0x5f, 0x8e, 0x3e, 0x6c, 0x4e, 0xfc, 0xf5, 0x7e, 0x1e, 0xfa, 0xf7, + 0x9b, 0x0d, 0x99, 0x48, 0x40, 0x25, 0x9d, 0x2e, 0x9a, 0x26, 0x5a, 0xa4, + 0xae, 0xd4, 0xd1, 0xee, 0x42, 0x61, 0xc7, 0x44, 0x92, 0x25, 0x55, 0x27, + 0x23, 0x9f, 0x40, 0xc2, 0x28, 0xe7, 0xd2, 0x00, 0x52, 0x07, 0xb7, 0xf0, + 0xe7, 0x56, 0x7f, 0xd6, 0xcb, 0x89, 0x8a, 0x6d, 0x7f, 0xf9, 0x2e, 0x0e, + 0xf8, 0x69, 0x1a, 0xa3, 0x5f, 0xbd, 0xd1, 0xd1, 0x98, 0xf8, 0x3f, 0x6f, + 0x94, 0x72, 0x29, 0x50, 0x6e, 0x5e, 0xdd, 0xc6, 0x1e, 0xf5, 0xfd, 0xe8, + 0x2c, 0x19, 0x22, 0x28, 0xcc, 0x3a, 0x98, 0x7a, 0x9e, 0x28, 0x3d, 0x52, + 0xbf, 0xc4, 0x72, 0xd7, 0x9b, 0x7e, 0xdf, 0xb6, 0x1a, 0x81, 0x05, 0x7d, + 0x6b, 0x5f, 0xcc, 0xa9, 0x16, 0x3d, 0x07, 0x4b, 0xa3, 0xa2, 0xbc, 0x5f, + 0x22, 0x20, 0x8a, 0x81, 0x2c, 0xe3, 0x90, 0x4f, 0x05, 0x09, 0xef, 0xbb, + 0xf6, 0x6e, 0xdd, 0x04, 0x3e, 0x6d, 0x7e, 0x93, 0x5d, 0x59, 0x2c, 0xc6, + 0x6d, 0xde, 0x7c, 0xe0, 0x24, 0xf6, 0x5d, 0x40, 0x3d, 0x09, 0x12, 0x80, + 0x02, 0x0d, 0x3a, 0x4b, 0xe8, 0x5b, 0x15, 0xdd, 0x25, 0x5a, 0x6f, 0x00, + 0xa7, 0xad, 0x43, 0xc5, 0x48, 0x65, 0x06, 0x1b, 0x47, 0xd2, 0xef, 0xd0, + 0xd1, 0x56, 0xca, 0x9f, 0x2a, 0xe4, 0xae, 0x49, 0x69, 0x1f, 0x2e, 0x07, + 0x58, 0x2a, 0xfd, 0x33, 0xd6, 0x11, 0x9b, 0x18, 0xe5, 0x53, 0x6a, 0x6a, + 0x23, 0x2c, 0x9d, 0x3d, 0xb0, 0x36, 0x76, 0x82, 0x0e, 0x1f, 0xd8, 0x06, + 0x66, 0x84, 0x5d, 0x53, 0x9b, 0x84, 0x01, 0x04, 0x7b, 0xa0, 0x81, 0x16, + 0x75, 0x22, 0xdc, 0x36, 0xaf, 0x6f, 0xc3, 0xd5, 0xe4, 0x1b, 0x0e, 0x16, + 0xba, 0x15, 0xea, 0xd1, 0xeb, 0xad, 0x0b, 0x2b, 0x9a, 0xd6, 0x83, 0xf8, + 0xfb, 0x7d, 0xa1, 0x3a, 0x6c, 0xcf, 0x59, 0x4c, 0x38, 0xcc, 0x6b, 0x47, + 0xba, 0x41, 0x52, 0x22, 0xdb, 0x82, 0x8b, 0xfb, 0xe6, 0xc2, 0xc6, 0x42, + 0x92, 0x48, 0xa1, 0x9a, 0x68, 0x7b, 0xbf, 0x32, 0xe4, 0xf2, 0xcf, 0x6e, + 0x22, 0xae, 0x1e, 0x47, 0x0d, 0x09, 0x65, 0x2b, 0x8f, 0xc5, 0x8e, 0x82, + 0x33, 0x53, 0xa1, 0xd6, 0xd2, 0x8a, 0x46, 0x82, 0xf9, 0x17, 0xd3, 0xa4, + 0x5e, 0x61, 0xf9, 0xd5, 0xbd, 0xae, 0x40, 0xaf, 0x38, 0xe1, 0xbe, 0xb7, + 0x58, 0x76, 0x24, 0x65, 0x9e, 0x69, 0x10, 0x83, 0x98, 0xcd, 0xbf, 0x34, + 0x4a, 0x11, 0x72, 0xd3, 0xa4, 0x4d, 0xe2, 0x7f, 0xaa, 0x4f, 0xbb, 0x1c, + 0xae, 0x44, 0x22, 0x12, 0xdc, 0x63, 0xd7, 0x3a, 0xb0, 0xd4, 0xe5, 0xec, + 0x37, 0xec, 0x36, 0xf1, 0xc9, 0x42, 0xef, 0x76, 0x99, 0xe3, 0x8a, 0xd5, + 0x8a, 0x84, 0xbf, 0x4a, 0x60, 0x63, 0xc9, 0xc1, 0xe9, 0x86, 0xce, 0xbf, + 0xff, 0xa5, 0xc8, 0xa5, 0x2f, 0xc8, 0xb1, 0x80, 0xdb, 0x09, 0x18, 0xd5, + 0x10, 0xc0, 0x0a, 0x96, 0xaf, 0x9f, 0x23, 0xb3, 0x6a, 0x52, 0x85, 0xfc, + 0x2c, 0xa7, 0xa5, 0xa1, 0x89, 0x1a, 0xb4, 0x05, 0x0a, 0xae, 0x02, 0x08, + 0x01, 0x12, 0x10, 0x65, 0x80, 0x2c, 0x9b, 0x62, 0x5e, 0x5a, 0x31, 0x9c, + 0x33, 0xdc, 0x1c, 0xb7, 0xc3, 0xc6, 0xd4, 0x18, 0xe3, 0xa5, 0xbd, 0xd0, + 0x05, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xb8, 0x05, 0x02, 0x04, 0x3c, 0x2a, 0x8a, 0x0f, 0xd8, 0xd2, 0x5c, + 0x61, 0x3e, 0x1e, 0x3e, 0x3b, 0x5e, 0x34, 0x9f, 0x33, 0x2f, 0x04, 0x51, + 0x6a, 0x75, 0x10, 0xd3, 0x80, 0x21, 0xa5, 0x62, 0x9b, 0x9a, 0xa0, 0x27, + 0xae, 0xad, 0x3c, 0x75, 0x9b, 0x7a, 0xfe, 0x70, 0xbe, 0xd6, 0x5f, 0x3d, + 0xf6, 0x86, 0x0f, 0xf5, 0xeb, 0x60, 0xb9, 0x83, 0xa3, 0xff, 0xa3, 0x3f, + 0xde, 0x06, 0xf3, 0xb7, 0x30, 0x14, 0xdf, 0xc8, 0x45, 0xab, 0x37, 0x1c, + 0x66, 0x00, 0x56, 0x2e, 0x9d, 0x90, 0x4f, 0x84, 0x2b, 0x8b, 0xa4, 0xa5, + 0xd9, 0x20, 0x0f, 0xfa, 0x3e, 0xd4, 0x5d, 0x70, 0x55, 0x20, 0xa5, 0xc3, + 0x72, 0xa8, 0x89, 0xf9, 0xe3, 0x14, 0x38, 0x62, 0x34, 0xc6, 0x89, 0x7a, + 0xe6, 0x55, 0x85, 0x1f, 0xcd, 0x9a, 0xdb, 0x4e, 0xf9, 0x12, 0x6c, 0x78, + 0x38, 0x6e, 0xa9, 0x3b, 0xcb, 0x25, 0xba, 0x3e, 0xc4, 0x75, 0xc5, 0x5c, + 0x60, 0x8e, 0x77, 0x1c, 0x76, 0x3a, 0xb0, 0x25, 0x06, 0xf9, 0xb0, 0x72, + 0x52, 0xd6, 0xab, 0xf7, 0xea, 0x64, 0xb1, 0xeb, 0xde, 0x7b, 0x95, 0xc6, + 0x40, 0x76, 0x90, 0x53, 0x3b, 0xd6, 0x89, 0x0b, 0x92, 0x74, 0xc1, 0x60, + 0x66, 0xf7, 0x4f, 0xc4, 0x01, 0xea, 0x35, 0x5f, 0x0a, 0x02, 0x10, 0x68, + 0x14, 0xd4, 0x9b, 0xf0, 0xc8, 0x9e, 0x6e, 0x1f, 0x8d, 0xb2, 0xa4, 0x78, + 0x41, 0xcd, 0x0d, 0xad, 0x79, 0x32, 0x96, 0xa1, 0x07, 0xc3, 0x62, 0x23, + 0x40, 0x4f, 0x2b, 0xf1, 0xfc, 0xa1, 0x6f, 0xd0, 0xa4, 0xb9, 0x82, 0x63, + 0x4d, 0xb6, 0x24, 0x07, 0xf8, 0xf1, 0x4a, 0xca, 0xe3, 0xb0, 0x5a, 0x03, + 0x8b, 0xd3, 0xe4, 0xbb, 0xba, 0xe4, 0x39, 0x1b, 0xbf, 0xa7, 0xa4, 0x7f, + 0xb9, 0xd0, 0x1d, 0xe8, 0x57, 0xea, 0x88, 0xe5, 0xe3, 0x6e, 0xe3, 0x6e, + 0x24, 0x58, 0x59, 0xfc, 0x0f, 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0xe8, + 0x3d, 0x12, 0x80, 0x03, 0x7e, 0x06, 0x58, 0x1a, 0x01, 0x91, 0x84, 0xab, + 0x57, 0x2a, 0xfd, 0xca, 0xdd, 0xd0, 0x3f, 0x16, 0x1c, 0xe6, 0x82, 0x00, + 0xf8, 0xe6, 0xf8, 0xad, 0x16, 0x19, 0x47, 0x36, 0x0b, 0xc8, 0xd4, 0x9c, + 0x0d, 0x68, 0x00, 0x9b, 0x1c, 0x46, 0x44, 0xf9, 0xb3, 0xf3, 0xfb, 0x6d, + 0xdf, 0xd9, 0x2e, 0xf9, 0x2d, 0xe6, 0x2d, 0x41, 0xd4, 0x59, 0xd2, 0x9d, + 0x81, 0xbf, 0xae, 0xf3, 0x97, 0x0a, 0x3a, 0x39, 0xd2, 0x5b, 0x26, 0x62, + 0xec, 0xb0, 0x3b, 0x2d, 0xa7, 0xb6, 0x83, 0x02, 0xfa, 0xa6, 0xdd, 0x98, + 0xd9, 0x5a, 0x14, 0x3c, 0xc8, 0xc1, 0xcb, 0x6a, 0xdd, 0xa7, 0x6d, 0x2e, + 0xe9, 0xc3, 0x72, 0x3f, 0xaf, 0x95, 0xa2, 0x9c, 0xdc, 0x3e, 0x96, 0x8b, + 0x68, 0x21, 0xa9, 0x1c, 0x05, 0x1c, 0xa2, 0x80, 0xa8, 0x66, 0x69, 0x71, + 0x0a, 0x1a, 0xd7, 0xa4, 0x4b, 0xf9, 0x21, 0x80, 0x27, 0x46, 0x0d, 0xf6, + 0x94, 0xe2, 0xe9, 0x27, 0x03, 0x96, 0xdf, 0x22, 0x19, 0x63, 0xf2, 0x1e, + 0xe6, 0xaa, 0x22, 0x0a, 0x5e, 0xe4, 0xa4, 0xd0, 0xfe, 0xb3, 0xd5, 0x3e, + 0xb5, 0x73, 0x2f, 0x8f, 0x91, 0xe9, 0xa9, 0x6b, 0x3b, 0x8b, 0xe2, 0x84, + 0xc5, 0x13, 0x39, 0xea, 0x28, 0x4d, 0x4d, 0x0e, 0xdd, 0x55, 0xb6, 0xad, + 0x56, 0xf7, 0x41, 0x64, 0x20, 0xe0, 0x5e, 0x05, 0x9f, 0x97, 0x34, 0xa9, + 0x6b, 0xe2, 0x5a, 0xa4, 0x45, 0x60, 0xdb, 0xa8, 0xc3, 0x87, 0x55, 0xa4, + 0x2a, 0x82, 0xbd, 0x7f, 0x88, 0xed, 0xd1, 0x9d, 0xf3, 0x46, 0xa6, 0x67, + 0xb3, 0x3b, 0x81, 0x14, 0xc7, 0x6a, 0x88, 0x38, 0xc4, 0x23, 0xd8, 0x24, + 0xa5, 0x0b, 0x23, 0x25, 0x1a, 0x08, 0x81, 0x36, 0xd6, 0xe8, 0xf4, 0x75, + 0x29, 0x9d, 0x2a, 0xfd, 0x46, 0xce, 0xa5, 0x1b, 0x5c, 0xbd, 0xf7, 0x89, + 0xa5, 0x72, 0x12, 0x5c, 0xd2, 0x4f, 0xbb, 0x81, 0x3b, 0x38, 0x7a, 0x10, + 0xcd, 0x2a, 0x30, 0xe3, 0x44, 0x76, 0x34, 0xab, 0x34, 0x08, 0xf9, 0x6b, + 0x9c, 0xf3, 0xd9, 0x88, 0x96, 0xd4, 0x05, 0xf3, 0xf5, 0x40, 0xd9, 0xc5, + 0x79, 0x62, 0x76, 0x0f, 0xcd, 0x17, 0x7c, 0xdd, 0x10, 0x1e, 0xb8, 0xa4, + 0x14, 0x8b, 0x9c, 0x29, 0xce, 0xd5, 0xea, 0xd6, 0x45, 0xa9, 0x5b, 0x69, + 0x8f, 0x1c, 0xdc, 0x6e, 0x1d, 0xb6, 0x67, 0x8b, 0x85, 0x07, 0x41, 0x86, + 0x08, 0x0d, 0x68, 0xd1, 0x3c, 0xd3, 0x7e, 0x07, 0xb1, 0x6d, 0xe3, 0x70, + 0xcd, 0x9a, 0xfb, 0x9b, 0x25, 0x56, 0x4a, 0x73, 0xa3, 0x0e, 0x2a, 0xf8, + 0x08, 0x5e, 0xa3, 0x7d, 0x31, 0x0c, 0x47, 0x4f, 0x0e, 0x67, 0xac, 0x00, + 0xca, 0x99, 0x2a, 0x52, 0x96, 0xfa, 0xed, 0xad, 0x7a, 0xa0, 0x6e, 0xcd, + 0x79, 0x0f, 0x1e, 0x3d, 0x42, 0x65, 0x58, 0xfa, 0x98, 0x38, 0x3e, 0x3c, + 0xd2, 0xed, 0x48, 0x30, 0x20, 0x02, 0x22, 0x04, 0x1b, 0x5f, 0x3a, 0xcf, + }; + provisioning_response_ = + std::string(reinterpret_cast(provisioning_response_raw), + sizeof(provisioning_response_raw)); + device_key_type_ = OEMCrypto_RSA_Private_Key; + RunTest(); +} + +TEST_F(ODKGoldenProvisionV18, CorePIGTest_OfflineNoNonce_prov20ecc) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x02, 0x00, 0x12, + 0xac, 0x0a, 0xc5, 0x83, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x12, + 0xac, 0x0a, 0xc5, 0x83, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x95, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t provisioning_response_raw[] = { + 0x0a, 0x90, 0x01, 0x81, 0x65, 0x7c, 0xa2, 0x52, 0x38, 0x6e, 0x34, 0x7e, + 0x52, 0x27, 0xfb, 0xcc, 0x3e, 0x6b, 0x16, 0x58, 0x3a, 0xde, 0x26, 0x5c, + 0x41, 0x95, 0x03, 0xdb, 0x25, 0xd9, 0x48, 0x41, 0xeb, 0xc0, 0xef, 0x04, + 0xd3, 0x41, 0xa9, 0x16, 0xc7, 0xf5, 0x68, 0x22, 0x53, 0x61, 0xde, 0x81, + 0xc0, 0x73, 0x9f, 0x12, 0x2a, 0x40, 0x65, 0x46, 0xdd, 0x6e, 0xdb, 0x72, + 0xac, 0x4b, 0x20, 0x6e, 0x71, 0x62, 0x6e, 0x86, 0x2f, 0x98, 0x1b, 0xec, + 0x7e, 0xd7, 0x1d, 0x79, 0xc7, 0x57, 0x28, 0x9f, 0x71, 0x48, 0xb0, 0x9c, + 0xff, 0x59, 0xa8, 0x97, 0xb0, 0x11, 0x56, 0xfa, 0x70, 0x9e, 0x3e, 0x40, + 0xda, 0x80, 0x64, 0xa6, 0x20, 0xaf, 0x5c, 0x73, 0xe2, 0x39, 0x26, 0xb7, + 0xd1, 0xa3, 0x52, 0x08, 0xe7, 0xa7, 0xac, 0x31, 0xc2, 0x5b, 0x72, 0x28, + 0x00, 0x30, 0xfe, 0x10, 0xbe, 0x3d, 0xec, 0x16, 0xe0, 0xd1, 0x4a, 0xd5, + 0x6e, 0x46, 0xef, 0x8d, 0xde, 0xb6, 0xc1, 0x8a, 0x0e, 0xde, 0xaf, 0xe7, + 0x5b, 0x03, 0xc3, 0x12, 0x10, 0x8f, 0xef, 0xc7, 0x4f, 0x16, 0x00, 0xae, + 0x22, 0xb8, 0x65, 0xf3, 0x3d, 0x63, 0x36, 0x3a, 0x01, 0x1a, 0xca, 0x07, + 0x0a, 0xb8, 0x02, 0x08, 0x02, 0x12, 0x10, 0x48, 0x4c, 0x97, 0x33, 0xdd, + 0x59, 0x35, 0xad, 0x65, 0x6f, 0xbf, 0x74, 0xa0, 0x5d, 0x51, 0xbb, 0x18, + 0x8b, 0xdc, 0x95, 0xa2, 0x06, 0x22, 0x5b, 0x30, 0x59, 0x30, 0x13, 0x06, + 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x42, 0x60, + 0x66, 0x81, 0x7c, 0x62, 0x5b, 0x89, 0x52, 0x73, 0xae, 0xc0, 0xcc, 0x5d, + 0x28, 0x5a, 0x82, 0xb2, 0xea, 0xea, 0xd8, 0x8c, 0x77, 0xab, 0x32, 0x5d, + 0x51, 0xb5, 0xe4, 0xae, 0x53, 0x8e, 0xc9, 0xde, 0x97, 0x7e, 0x8e, 0x47, + 0xd6, 0xb9, 0xb7, 0x49, 0x1a, 0xee, 0x3d, 0xc7, 0x3e, 0x81, 0x96, 0x83, + 0xef, 0x19, 0xe7, 0xbc, 0xdf, 0x76, 0x6a, 0x3e, 0xe9, 0x54, 0x15, 0x0a, + 0x04, 0xd8, 0x28, 0xd9, 0xd4, 0x01, 0x3a, 0x0c, 0x77, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x48, 0x02, 0x52, 0xaa, + 0x01, 0x08, 0x01, 0x10, 0x00, 0x1a, 0x81, 0x01, 0x04, 0xb8, 0x88, 0x06, + 0x02, 0x12, 0x58, 0x1b, 0x04, 0x6a, 0x25, 0x3a, 0x68, 0xd2, 0xeb, 0x61, + 0xe2, 0x4f, 0xa1, 0x4d, 0x55, 0x39, 0x85, 0x4c, 0xb1, 0xfe, 0x04, 0x01, + 0xd4, 0x5f, 0x2e, 0xd2, 0x80, 0xde, 0x27, 0xd2, 0x37, 0x54, 0x04, 0x85, + 0x8b, 0xfa, 0x4a, 0x31, 0x7f, 0x4b, 0x8d, 0x74, 0xfe, 0xd5, 0xdc, 0x85, + 0x36, 0xd5, 0x0c, 0xc6, 0x4e, 0x3b, 0x7a, 0xd6, 0xe9, 0x5d, 0x49, 0x41, + 0x9f, 0x00, 0xac, 0x89, 0x6e, 0x73, 0x75, 0x86, 0xfe, 0x9a, 0xa2, 0x50, + 0xf2, 0x19, 0xcf, 0xf5, 0x2e, 0x75, 0x21, 0x3a, 0x09, 0x76, 0x21, 0x6e, + 0x03, 0xa6, 0x46, 0x0f, 0xff, 0xa2, 0xfb, 0xf1, 0xa2, 0xbe, 0x62, 0x19, + 0x0e, 0xdc, 0x0d, 0x82, 0xb7, 0x20, 0x95, 0x81, 0x3c, 0xad, 0xa8, 0x3e, + 0x18, 0x20, 0x58, 0xc9, 0x4d, 0x75, 0xf0, 0x45, 0xa7, 0x8c, 0x9b, 0xc5, + 0xbb, 0x31, 0xa0, 0xd9, 0x25, 0x22, 0x20, 0x03, 0x0c, 0x37, 0x13, 0xa7, + 0x1a, 0x35, 0x44, 0x7c, 0x57, 0x7b, 0xfb, 0x47, 0x6d, 0x4b, 0x40, 0xf8, + 0xe8, 0x4b, 0x66, 0x44, 0x0d, 0x99, 0xe8, 0x0a, 0xcf, 0x00, 0x25, 0xdd, + 0xfd, 0x38, 0xbb, 0x12, 0x66, 0x30, 0x64, 0x02, 0x30, 0x20, 0x0e, 0x49, + 0x58, 0x0b, 0x5b, 0x5e, 0x6f, 0x9b, 0xa8, 0x78, 0x55, 0xce, 0xde, 0x43, + 0xef, 0x57, 0xa7, 0x86, 0xc2, 0x28, 0x76, 0xbf, 0x54, 0xc8, 0x99, 0x72, + 0x71, 0xdd, 0x14, 0xc7, 0x72, 0xf1, 0x1e, 0xcc, 0x6c, 0x2d, 0x75, 0xfd, + 0x99, 0x84, 0x34, 0xa4, 0x99, 0x39, 0x79, 0xe5, 0x28, 0x02, 0x30, 0x33, + 0x20, 0x1e, 0xc4, 0x98, 0x75, 0xe7, 0xac, 0x6f, 0xb2, 0x90, 0x3b, 0xe1, + 0x12, 0xd1, 0x8b, 0x88, 0xbf, 0xd6, 0x27, 0x6d, 0x80, 0x2a, 0x90, 0xd6, + 0x8d, 0xfd, 0x3c, 0x61, 0xfb, 0x45, 0xb2, 0xce, 0x8e, 0x6d, 0x65, 0x0d, + 0x61, 0x78, 0xf4, 0x0d, 0x8f, 0xbb, 0x47, 0xa7, 0xf7, 0x45, 0xca, 0x1a, + 0xa2, 0x04, 0x0a, 0x9a, 0x01, 0x08, 0x01, 0x12, 0x10, 0xc6, 0x10, 0x80, + 0x8e, 0xce, 0x58, 0x74, 0x5c, 0x0f, 0xb3, 0xda, 0x8c, 0xeb, 0x33, 0x3d, + 0x8a, 0x18, 0xed, 0xad, 0xab, 0x97, 0x06, 0x22, 0x78, 0x30, 0x76, 0x30, + 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, + 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0x0b, 0x5c, 0xca, + 0xda, 0x33, 0x99, 0x3b, 0xf6, 0xd9, 0xa7, 0xec, 0x5c, 0x91, 0xb5, 0x1d, + 0x07, 0x63, 0x38, 0x25, 0xad, 0x59, 0x2c, 0x14, 0x00, 0xf2, 0xc7, 0x5f, + 0x36, 0xec, 0xa0, 0x68, 0x21, 0xa2, 0xbd, 0x8a, 0xd3, 0xb2, 0x0c, 0x76, + 0x90, 0xef, 0x99, 0xe9, 0x57, 0xc6, 0x60, 0x1c, 0x3d, 0x89, 0x03, 0xd6, + 0xe1, 0xb3, 0x5d, 0x83, 0x94, 0xe9, 0x39, 0xea, 0xd5, 0xac, 0x00, 0x5b, + 0x4a, 0x14, 0xd7, 0xc2, 0x08, 0xa8, 0x1c, 0x05, 0xe2, 0x3b, 0x50, 0xe9, + 0x8c, 0x64, 0x32, 0x92, 0xa8, 0x5f, 0x7e, 0x33, 0xd6, 0x99, 0xcd, 0x09, + 0xe6, 0x18, 0x13, 0x2f, 0x16, 0x3a, 0x7e, 0xbf, 0xa8, 0x28, 0xd9, 0xd4, + 0x01, 0x48, 0x03, 0x12, 0x80, 0x03, 0x81, 0x6f, 0xdc, 0x22, 0x5d, 0x32, + 0x26, 0x9e, 0x8b, 0x54, 0x18, 0x11, 0x11, 0x1f, 0xa4, 0x4f, 0x58, 0x95, + 0xd0, 0x74, 0x19, 0xd3, 0x72, 0xa5, 0x5b, 0x30, 0xe5, 0xa9, 0x8f, 0x11, + 0x99, 0x1a, 0x0d, 0x9c, 0x27, 0xd9, 0xc8, 0xe7, 0xff, 0xf0, 0x08, 0xc7, + 0xcf, 0xb2, 0x94, 0x94, 0xd4, 0x56, 0x7f, 0xf5, 0xd8, 0x31, 0x9e, 0xd6, + 0xd1, 0x3f, 0xbc, 0x52, 0x48, 0x30, 0x33, 0x61, 0x41, 0x5b, 0x3d, 0xa6, + 0xf5, 0xb1, 0xd0, 0x73, 0x53, 0x75, 0x16, 0xf4, 0xb7, 0xe0, 0x6f, 0x2e, + 0xe1, 0x34, 0x63, 0x96, 0x72, 0x79, 0x72, 0xe8, 0xf8, 0x4a, 0x37, 0xf4, + 0x73, 0xbb, 0x8e, 0x5e, 0x73, 0x6c, 0xdd, 0x14, 0x2d, 0xe8, 0xb6, 0xc0, + 0xf2, 0xbb, 0x34, 0xca, 0x6d, 0x9c, 0x1b, 0xde, 0xf6, 0x48, 0xe2, 0xce, + 0xd7, 0x98, 0x42, 0x51, 0x03, 0x3a, 0x54, 0x74, 0x0d, 0xcf, 0x2d, 0xc4, + 0x77, 0x6b, 0x5d, 0x7a, 0xd0, 0xf0, 0x1a, 0xec, 0x59, 0xa8, 0xb7, 0x87, + 0x2c, 0x3d, 0x5a, 0xd2, 0x4d, 0x2d, 0xf8, 0xc6, 0x71, 0x87, 0x0d, 0xda, + 0x88, 0x93, 0xf7, 0x60, 0xd9, 0xd9, 0x3d, 0x4b, 0x8d, 0x6c, 0x43, 0x57, + 0x17, 0x7e, 0x89, 0xc6, 0x56, 0x4c, 0xd4, 0x51, 0xe7, 0x8a, 0x7d, 0x91, + 0x73, 0xda, 0xfa, 0x32, 0xb7, 0xd5, 0xdf, 0xb9, 0xe4, 0x45, 0x22, 0x45, + 0xc5, 0x8b, 0x5e, 0x0f, 0xe9, 0x77, 0x8c, 0x8e, 0xd6, 0x18, 0x02, 0xad, + 0x47, 0xd4, 0x22, 0xdc, 0x9e, 0xf1, 0xbb, 0xf1, 0x5b, 0x9f, 0x5d, 0xde, + 0xa8, 0x16, 0xfa, 0x80, 0x33, 0xa8, 0x31, 0x36, 0x71, 0xb1, 0x04, 0x7b, + 0xc2, 0x88, 0xe9, 0x9b, 0xc5, 0xd2, 0x32, 0xd4, 0x0c, 0xef, 0xfe, 0x4d, + 0x5a, 0xe9, 0x85, 0xb5, 0x00, 0x7e, 0x67, 0xd5, 0xe9, 0x16, 0x1b, 0x97, + 0xc5, 0xea, 0xf6, 0xfe, 0x52, 0xc9, 0x04, 0xd0, 0x07, 0xe8, 0x49, 0x6e, + 0x3e, 0x9f, 0x1f, 0xdb, 0xb1, 0xfe, 0x7a, 0x40, 0xd6, 0x07, 0x71, 0x20, + 0x83, 0x22, 0x29, 0x20, 0x4b, 0xa5, 0x56, 0xac, 0x78, 0x2a, 0x76, 0x1b, + 0xe8, 0x08, 0x3e, 0x1b, 0xf8, 0x4f, 0xae, 0xc6, 0x45, 0x5d, 0x2b, 0xdc, + 0x1f, 0x0b, 0x22, 0xdb, 0x77, 0xd7, 0xf4, 0xde, 0x5e, 0xa8, 0x0c, 0x43, + 0x92, 0xb6, 0xa6, 0x09, 0x0d, 0xc9, 0xce, 0xcb, 0xf8, 0xb3, 0x0d, 0x05, + 0x25, 0xf0, 0xee, 0x5f, 0x8a, 0xc7, 0xf4, 0x0f, 0xf1, 0xb6, 0x59, 0x48, + 0xa8, 0xd0, 0x46, 0xec, 0xdf, 0x73, 0xb7, 0xfe, 0x2b, 0xda, 0x6a, 0xe6, + 0x52, 0x4c, 0xc4, 0x5b, 0xd3, 0xf3, 0x40, 0x76, 0xbf, 0xc9, 0x7a, 0x85, + 0xe1, 0x68, 0xce, 0x69, 0x53, 0x43, 0xc9, 0x3f, 0x86, 0xdb, 0x5d, 0x98, + 0x8e, 0xdb, 0x3c, 0x4a, 0x4f, 0xc6, 0x18, 0x73, 0x00, 0xf4, 0xb3, 0x93, + 0xec, 0x37, 0x16, 0x73, 0xbb, 0x74, 0x20, 0x03, 0x20, 0x02, 0x22, 0x04, + 0x83, 0xc5, 0x0a, 0xac, + }; + provisioning_response_ = + std::string(reinterpret_cast(provisioning_response_raw), + sizeof(provisioning_response_raw)); + device_key_type_ = OEMCrypto_ECC_Private_Key; + RunTest(); +} + +TEST_F(ODKGoldenProvisionV18, CorePIGTest_OfflineNoNonce_prov30) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x02, 0x00, 0x12, + 0x7f, 0x32, 0x70, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x12, + 0x7f, 0x32, 0x70, 0x49, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xd0, 0x00, 0x00, 0x04, 0xd5, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x01, 0x00, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t provisioning_response_raw[] = { + 0x0a, 0xd0, 0x09, 0xea, 0x1f, 0x31, 0x8d, 0x3c, 0xa8, 0xa5, 0x43, 0x25, + 0xf6, 0x92, 0xb0, 0x49, 0x4b, 0xdc, 0x4b, 0x17, 0x61, 0x0e, 0x1d, 0x8c, + 0x85, 0x00, 0x21, 0x35, 0x84, 0x54, 0x56, 0x53, 0x0a, 0x34, 0x08, 0x34, + 0x87, 0x67, 0x03, 0xa6, 0x07, 0x72, 0x11, 0x23, 0x36, 0xcd, 0x5a, 0x84, + 0x24, 0x48, 0x6a, 0x6c, 0x71, 0x5e, 0xf0, 0x28, 0x24, 0xaf, 0x83, 0xbb, + 0x4f, 0x54, 0x38, 0xc3, 0x3d, 0xfc, 0xb7, 0x79, 0x01, 0x87, 0xf2, 0x6e, + 0xac, 0xfe, 0x80, 0x5d, 0xcb, 0xbe, 0x95, 0x29, 0x76, 0x79, 0xda, 0xf6, + 0xd4, 0x7b, 0x7a, 0xd9, 0xb4, 0x32, 0xd3, 0xa8, 0x6d, 0x14, 0xc0, 0xac, + 0x36, 0xab, 0x77, 0xc3, 0xbd, 0xd5, 0x79, 0x72, 0x0b, 0x21, 0xc9, 0x44, + 0x07, 0x57, 0x86, 0x43, 0xe1, 0x2a, 0x3e, 0x8e, 0x7e, 0x1d, 0x50, 0x64, + 0x09, 0x0f, 0x0c, 0x76, 0x0b, 0xb6, 0x36, 0xe0, 0x64, 0x62, 0x4e, 0xda, + 0xc1, 0x56, 0x08, 0x8b, 0x13, 0x3d, 0x80, 0x3f, 0x26, 0x0e, 0xa0, 0x4a, + 0xc5, 0x95, 0x51, 0xcd, 0x15, 0x41, 0x44, 0x17, 0x78, 0xc6, 0xec, 0x00, + 0x5b, 0x47, 0xad, 0x21, 0xf7, 0x4b, 0x98, 0xed, 0x1d, 0x82, 0x6d, 0x22, + 0xfc, 0xcb, 0x07, 0x69, 0x7c, 0x96, 0x57, 0xd7, 0x01, 0xe1, 0xc3, 0x64, + 0x92, 0xc8, 0xc0, 0xe1, 0x00, 0x31, 0xc2, 0xf9, 0x44, 0x37, 0x5c, 0x60, + 0xe3, 0x4f, 0x61, 0x79, 0xec, 0x7d, 0xed, 0xb6, 0xfa, 0x05, 0x1b, 0xf4, + 0xd5, 0xb5, 0x15, 0xb4, 0x03, 0xab, 0x36, 0xc5, 0xb8, 0xcc, 0xd1, 0x58, + 0x21, 0xfe, 0x1f, 0xa7, 0x75, 0xaa, 0xbe, 0x8e, 0x7b, 0x47, 0x93, 0x7c, + 0xf2, 0x28, 0xbd, 0x07, 0x26, 0x38, 0x99, 0x5d, 0x2b, 0x39, 0xad, 0x67, + 0x26, 0x1d, 0xee, 0xb5, 0xd5, 0x84, 0x5c, 0x6d, 0x2a, 0x21, 0x2b, 0x17, + 0x8a, 0x33, 0x1c, 0x57, 0x64, 0xd2, 0x59, 0x85, 0x6c, 0xae, 0xd1, 0x4d, + 0x8a, 0x90, 0xcd, 0xc2, 0xd4, 0x75, 0xb8, 0x1a, 0x27, 0xbb, 0xa5, 0x6e, + 0xb6, 0xe2, 0x79, 0xa8, 0x4c, 0xb0, 0x89, 0x5a, 0xe8, 0x96, 0x7f, 0xf0, + 0x21, 0x57, 0xec, 0x16, 0x83, 0x46, 0x2c, 0x52, 0xec, 0xb7, 0xee, 0x5b, + 0x16, 0xbd, 0x11, 0xd3, 0xa8, 0x6c, 0x33, 0x43, 0x9e, 0x63, 0x4c, 0x60, + 0x33, 0xcd, 0xc2, 0xad, 0x1f, 0xfa, 0x16, 0x9d, 0xea, 0x37, 0x96, 0x76, + 0x61, 0x7a, 0x81, 0x1f, 0x10, 0xa6, 0x77, 0x5e, 0x8a, 0x0f, 0xe0, 0xbf, + 0x17, 0x25, 0x63, 0x90, 0x88, 0x9d, 0xa0, 0xcf, 0xe1, 0x79, 0xa2, 0x68, + 0x5a, 0x79, 0x98, 0x17, 0xac, 0x83, 0x3d, 0x37, 0xd2, 0x60, 0x56, 0x05, + 0x71, 0x33, 0xbf, 0xe6, 0x14, 0x39, 0x38, 0xb3, 0xc9, 0xa4, 0x8c, 0xc5, + 0x50, 0x77, 0xbf, 0x6e, 0xc2, 0xa7, 0x44, 0x49, 0x8e, 0x68, 0x79, 0xd2, + 0x66, 0x3b, 0xba, 0xad, 0x05, 0x39, 0xeb, 0x27, 0xc9, 0xbf, 0xa2, 0x31, + 0x31, 0x52, 0x71, 0xdd, 0xe2, 0x24, 0xbe, 0xc5, 0xcc, 0x0a, 0x19, 0xc9, + 0x98, 0x75, 0xde, 0xc2, 0x21, 0x74, 0x63, 0x71, 0xb0, 0x33, 0xbc, 0x3f, + 0xfb, 0x01, 0x43, 0xb9, 0x53, 0xf7, 0xcd, 0x02, 0xeb, 0xca, 0x4f, 0x1c, + 0xb0, 0xdf, 0x1a, 0xcf, 0x04, 0xb0, 0x49, 0xaf, 0xce, 0x23, 0x0a, 0x4e, + 0x61, 0x29, 0xe9, 0x92, 0xea, 0x9c, 0x35, 0xed, 0xb4, 0x7c, 0x40, 0x92, + 0x7d, 0x55, 0xf8, 0x3e, 0xc1, 0xf0, 0x36, 0xd7, 0xca, 0xee, 0xa1, 0x5d, + 0x56, 0xf2, 0x8a, 0x1e, 0xce, 0xcc, 0xb6, 0x86, 0x39, 0x6d, 0x87, 0xdc, + 0x85, 0xbc, 0x56, 0xdc, 0xf5, 0x2e, 0x17, 0xa0, 0xf2, 0x9d, 0xc3, 0xdd, + 0xa3, 0x56, 0xd8, 0x8e, 0x00, 0x8a, 0xb6, 0x27, 0x87, 0xe0, 0x8e, 0x79, + 0x13, 0x05, 0x48, 0xd2, 0xb0, 0x21, 0x8d, 0x86, 0xb3, 0x7a, 0xef, 0xea, + 0x4f, 0x57, 0x6a, 0xe0, 0xb5, 0x59, 0xe2, 0x80, 0xa8, 0x0f, 0x60, 0x05, + 0x1b, 0x9e, 0x55, 0xc1, 0x64, 0xab, 0x7f, 0x63, 0xf4, 0x02, 0x5a, 0xb5, + 0x58, 0xa9, 0xbc, 0x43, 0x28, 0x41, 0xaa, 0x8a, 0x5b, 0xde, 0xd1, 0x88, + 0xb3, 0x52, 0x39, 0x4d, 0x6c, 0x3f, 0x6e, 0x88, 0x11, 0x80, 0xda, 0xa1, + 0x8a, 0x04, 0x5d, 0x30, 0x98, 0xc4, 0xe8, 0x28, 0x90, 0x4d, 0x9b, 0x92, + 0x61, 0x9f, 0xdb, 0xf1, 0x9b, 0xbf, 0xd4, 0xd9, 0x83, 0x74, 0x6f, 0xee, + 0x95, 0x2e, 0x64, 0x05, 0x84, 0xf5, 0x51, 0xb6, 0xc9, 0x3f, 0xf8, 0xbd, + 0xf9, 0x21, 0x92, 0x2f, 0x08, 0xe1, 0x43, 0x13, 0x94, 0x97, 0x18, 0x50, + 0x7f, 0x3f, 0x85, 0xf9, 0x15, 0xab, 0x6a, 0x17, 0x3c, 0x5a, 0x5e, 0x26, + 0xf1, 0x47, 0xdd, 0x06, 0x58, 0x40, 0x27, 0x5d, 0x2f, 0xe6, 0xa1, 0x91, + 0xb2, 0xfd, 0xdb, 0x49, 0x89, 0x7e, 0x78, 0x85, 0x81, 0xfc, 0x6d, 0xf8, + 0x29, 0x7a, 0x1f, 0x76, 0x69, 0xb1, 0x17, 0x2f, 0xb9, 0x29, 0x17, 0x55, + 0x25, 0x2e, 0x7c, 0xca, 0xdc, 0x1d, 0xee, 0xb0, 0x8f, 0xf6, 0x62, 0x5d, + 0x05, 0xe2, 0xb4, 0x47, 0x83, 0x1c, 0xbe, 0x69, 0x85, 0x7b, 0xc9, 0xd9, + 0x95, 0x2f, 0x2a, 0xa1, 0x79, 0x9b, 0xeb, 0x93, 0x5f, 0x1a, 0xa9, 0x0f, + 0x1a, 0xaf, 0xfb, 0x3a, 0xee, 0x0a, 0x69, 0x69, 0xab, 0x33, 0xbb, 0x2b, + 0x6b, 0x53, 0x77, 0xd8, 0xd9, 0xcc, 0x60, 0xe3, 0xbe, 0x6d, 0x24, 0x4f, + 0x0c, 0x0b, 0x6f, 0x09, 0x4d, 0xa3, 0x64, 0x47, 0x71, 0x07, 0x23, 0x3a, + 0x11, 0xd5, 0x2b, 0xc6, 0x13, 0xf8, 0xe7, 0x2b, 0x88, 0x94, 0xfe, 0x70, + 0xe8, 0x40, 0x16, 0x7f, 0x3a, 0xac, 0x06, 0xa1, 0x44, 0xa3, 0xa9, 0xd2, + 0xff, 0xb7, 0xa1, 0x86, 0x95, 0x15, 0x2b, 0xc5, 0x83, 0x10, 0xb8, 0x72, + 0x14, 0x24, 0x97, 0x8a, 0xf5, 0x45, 0xa8, 0x1b, 0x1c, 0xfa, 0x52, 0xab, + 0x25, 0x8a, 0x2c, 0xed, 0x48, 0x8f, 0xe4, 0x3b, 0xc1, 0x61, 0xcb, 0xb6, + 0x85, 0xb1, 0x32, 0x57, 0xaf, 0x3e, 0x5a, 0x14, 0x93, 0xc9, 0xd3, 0x97, + 0xc0, 0x6e, 0x67, 0x22, 0xfe, 0x3c, 0xf3, 0x79, 0xaa, 0x4e, 0x35, 0x84, + 0x7d, 0x27, 0xd0, 0x84, 0x53, 0x1d, 0x91, 0xba, 0x3b, 0x06, 0x36, 0xa6, + 0xdd, 0xbd, 0x9e, 0x91, 0x31, 0x88, 0xed, 0xee, 0x8c, 0xe9, 0x68, 0x9c, + 0x00, 0x52, 0x1a, 0xbb, 0x45, 0x75, 0x2f, 0x9a, 0x81, 0xf7, 0xe8, 0xf8, + 0x76, 0x71, 0xd3, 0x3e, 0x9b, 0x7e, 0x13, 0x92, 0x6a, 0x70, 0x55, 0x3f, + 0x48, 0xef, 0xbd, 0xd6, 0x9f, 0x5e, 0x9c, 0x0c, 0x68, 0x22, 0xba, 0x71, + 0x7d, 0x36, 0x11, 0xe1, 0xe5, 0xd8, 0x00, 0xa8, 0xce, 0x2c, 0x89, 0x79, + 0xbf, 0x5b, 0x02, 0xac, 0xda, 0xd4, 0x68, 0x4f, 0xdf, 0x8d, 0xe3, 0x07, + 0x38, 0x39, 0xd1, 0xe0, 0x4d, 0xb4, 0xdc, 0x79, 0x2c, 0x04, 0x68, 0xb4, + 0xed, 0x53, 0x2e, 0x2e, 0x0e, 0xbe, 0xee, 0xae, 0x33, 0xad, 0x80, 0x9c, + 0x77, 0x9d, 0xc1, 0x61, 0x9c, 0x5e, 0x19, 0x72, 0x51, 0xeb, 0xc8, 0x1c, + 0xc9, 0xd2, 0xd3, 0x54, 0x6f, 0xe6, 0x88, 0x37, 0x2b, 0x35, 0x00, 0xb1, + 0xd4, 0x8b, 0xa6, 0xb2, 0x1b, 0x73, 0x5b, 0xdf, 0x93, 0xb2, 0x96, 0x77, + 0x4b, 0x2d, 0xf2, 0x9f, 0xf7, 0xd0, 0xb4, 0x78, 0x5d, 0xe5, 0x6d, 0x6c, + 0xa3, 0xd0, 0xf5, 0xc7, 0xd2, 0x00, 0x2f, 0xa2, 0xfc, 0x0c, 0xb0, 0x9f, + 0x63, 0x53, 0xe9, 0x08, 0xc1, 0x51, 0x85, 0x73, 0x6a, 0xfa, 0x01, 0xe5, + 0xf6, 0x7c, 0xcb, 0xdd, 0x53, 0x53, 0x47, 0xa1, 0xb8, 0x64, 0xb1, 0xda, + 0xd7, 0xd7, 0xef, 0x9a, 0x62, 0x53, 0x8f, 0x4b, 0xbe, 0x0f, 0x3c, 0x12, + 0x3b, 0x2c, 0xda, 0x5b, 0x12, 0x43, 0x81, 0xf5, 0x3c, 0x8a, 0x21, 0x0f, + 0x52, 0x6b, 0x81, 0x85, 0xaa, 0xbd, 0xae, 0x3f, 0x2f, 0x46, 0x2b, 0x4a, + 0x19, 0x6b, 0xa2, 0x69, 0x2f, 0xbe, 0x50, 0x79, 0x71, 0xa1, 0x03, 0x0d, + 0x29, 0xe5, 0xc0, 0xe5, 0xc4, 0x32, 0x77, 0x4c, 0xbb, 0x3b, 0xb7, 0x8e, + 0xa4, 0xc5, 0xd7, 0x58, 0x83, 0x40, 0x25, 0x20, 0x8e, 0xa0, 0x7f, 0x9a, + 0x9f, 0x62, 0x2f, 0xb1, 0xce, 0x95, 0x53, 0x29, 0xd3, 0x39, 0xd4, 0x7a, + 0xe6, 0x96, 0x73, 0x5f, 0x65, 0xbe, 0x8e, 0x8c, 0x59, 0x88, 0xf4, 0x1b, + 0x40, 0x13, 0xca, 0x74, 0x39, 0x6f, 0xef, 0x08, 0xbc, 0xdb, 0x9a, 0x1c, + 0x38, 0xa7, 0x67, 0x2f, 0x96, 0x78, 0x87, 0x3a, 0xfa, 0xf7, 0x29, 0x16, + 0x1d, 0x73, 0x6b, 0x1f, 0xdf, 0x1d, 0x91, 0xd3, 0x93, 0x1f, 0xef, 0x06, + 0xa1, 0xef, 0x19, 0x28, 0x61, 0xe0, 0x09, 0xae, 0x69, 0xa3, 0x41, 0x2f, + 0x28, 0x35, 0x00, 0xe4, 0xd3, 0x85, 0xc4, 0x69, 0x34, 0x63, 0xee, 0xc7, + 0xa0, 0x31, 0x02, 0x92, 0x63, 0x54, 0xeb, 0x24, 0x68, 0xf8, 0x44, 0x80, + 0x86, 0x9b, 0x21, 0xf0, 0x85, 0xb0, 0x84, 0xaa, 0xe8, 0xe3, 0xf0, 0x3a, + 0x61, 0xe8, 0x5d, 0xf6, 0x66, 0xac, 0x05, 0xd1, 0xc0, 0x4b, 0x5d, 0xe0, + 0xa8, 0x63, 0xf6, 0xcd, 0xba, 0x97, 0x40, 0x55, 0xa0, 0xe7, 0x3b, 0xc2, + 0x2e, 0x05, 0x61, 0x06, 0x89, 0x18, 0x5f, 0x22, 0xb7, 0x00, 0x3f, 0x63, + 0xed, 0xcb, 0x8d, 0x2c, 0xf5, 0xc5, 0x6e, 0xb4, 0xca, 0x4f, 0x83, 0x12, + 0x10, 0x99, 0x21, 0x38, 0x4a, 0xd4, 0x11, 0x68, 0x1a, 0xfc, 0x9c, 0xd2, + 0xea, 0xc2, 0xaa, 0x60, 0xcb, 0x1a, 0xfb, 0x09, 0x0a, 0xbe, 0x02, 0x08, + 0x02, 0x12, 0x10, 0x35, 0x7f, 0x7a, 0xfa, 0x7d, 0x33, 0x42, 0x33, 0x1c, + 0x8c, 0xd1, 0x07, 0xdd, 0xc7, 0x5a, 0x96, 0x18, 0xad, 0xf6, 0x92, 0xa2, + 0x06, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xbc, 0x6d, 0x9d, 0x5a, 0xd1, 0x9f, 0x64, 0xca, 0xb2, 0x2c, 0x8f, + 0x69, 0x1d, 0xa5, 0x41, 0x3a, 0xcc, 0x01, 0x86, 0xf7, 0x69, 0x77, 0x25, + 0x58, 0xed, 0x4a, 0xbe, 0xbd, 0x24, 0x73, 0xd9, 0xa3, 0x21, 0xac, 0x6e, + 0xf1, 0x12, 0xf0, 0x3c, 0xcc, 0x12, 0x09, 0x46, 0x15, 0x2f, 0xd7, 0xbd, + 0x9e, 0x06, 0xd3, 0x44, 0x72, 0xe7, 0x33, 0x3a, 0xa7, 0x1e, 0xab, 0x4a, + 0x73, 0x09, 0x45, 0xf7, 0x7e, 0x94, 0x6b, 0xb2, 0xc8, 0xf2, 0xea, 0xd6, + 0xf1, 0xfe, 0x20, 0xd2, 0x34, 0x5b, 0x02, 0x9e, 0x41, 0xae, 0x56, 0xa9, + 0x3d, 0x17, 0xa4, 0x68, 0x16, 0xda, 0xb5, 0xe7, 0x9b, 0x2c, 0xc6, 0xf8, + 0x51, 0x1f, 0x34, 0xd5, 0x16, 0x67, 0x77, 0x17, 0x95, 0xbf, 0x3d, 0x19, + 0x1e, 0xe0, 0x02, 0x76, 0xab, 0xa1, 0xbd, 0x0a, 0x88, 0xc1, 0x3c, 0x51, + 0xc2, 0x71, 0x1b, 0x28, 0x90, 0x74, 0x6e, 0x06, 0xb1, 0x04, 0xa2, 0x4f, + 0xae, 0x43, 0x03, 0xce, 0xf8, 0x31, 0x97, 0x04, 0xf6, 0x74, 0xae, 0xb8, + 0x82, 0x8e, 0x6c, 0x08, 0x4f, 0xbf, 0x2b, 0xac, 0x45, 0xdc, 0x19, 0x41, + 0x2b, 0x64, 0x53, 0x4d, 0x10, 0x5a, 0x36, 0x46, 0xba, 0xd5, 0xae, 0xa1, + 0xdb, 0xce, 0x42, 0x60, 0xa6, 0xe4, 0x80, 0x65, 0x8c, 0xed, 0x29, 0x89, + 0x8b, 0xe9, 0x3b, 0xe6, 0x33, 0xb1, 0xf1, 0x63, 0x3a, 0x6c, 0x91, 0x49, + 0x6b, 0xd6, 0xc1, 0x1a, 0x52, 0x55, 0x5d, 0x03, 0x9e, 0x92, 0xa3, 0x15, + 0x84, 0x1c, 0x3a, 0x39, 0x80, 0x9a, 0x7a, 0x70, 0xe0, 0xd0, 0x2d, 0x52, + 0xf0, 0x04, 0x7e, 0x88, 0xb5, 0x2d, 0x8e, 0x97, 0x85, 0x88, 0xb3, 0x3d, + 0xb4, 0xd4, 0x21, 0x41, 0x0d, 0x4b, 0x92, 0xb9, 0x77, 0xb1, 0xff, 0x10, + 0x56, 0x8a, 0x0d, 0x94, 0xbe, 0x5b, 0x77, 0x2e, 0x5f, 0xd7, 0x63, 0xdd, + 0xbc, 0x87, 0x1c, 0x67, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0xe9, + 0x3d, 0x3a, 0x0c, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x48, 0x01, 0x12, 0x80, 0x02, 0x34, 0xdf, 0x8b, 0x7b, + 0x40, 0x3f, 0x6b, 0xbe, 0xb7, 0x47, 0x72, 0x7e, 0x9c, 0x8e, 0x5b, 0xc1, + 0x4a, 0x4e, 0xe7, 0x60, 0x72, 0x43, 0x51, 0x5e, 0x1d, 0x3e, 0x82, 0x53, + 0x89, 0x6a, 0x4f, 0x48, 0x8d, 0x50, 0xd1, 0x74, 0x2c, 0x3d, 0x6d, 0xa0, + 0xf0, 0xc9, 0x4e, 0x80, 0xcb, 0xf6, 0x12, 0xb2, 0xf0, 0xc1, 0x03, 0xa0, + 0x8e, 0xb6, 0x1b, 0x75, 0x94, 0x72, 0x42, 0x0d, 0x8e, 0xa9, 0x94, 0xd7, + 0x5b, 0x17, 0x9d, 0x3a, 0xad, 0x09, 0x5b, 0x0d, 0x29, 0x08, 0x67, 0xaf, + 0xee, 0x72, 0x65, 0x03, 0xa5, 0xe2, 0xf4, 0x49, 0xd2, 0x8c, 0x26, 0x7c, + 0x5e, 0xb3, 0x42, 0x90, 0x57, 0xe2, 0x28, 0x26, 0xb2, 0x9e, 0x32, 0x6b, + 0xdd, 0x2b, 0x2f, 0x12, 0x64, 0xea, 0xd0, 0x6b, 0xd8, 0xf7, 0x53, 0x21, + 0x57, 0x2f, 0x12, 0x1d, 0xc7, 0x88, 0x0a, 0xfb, 0x70, 0x3d, 0x9b, 0x15, + 0xd1, 0xdb, 0x6c, 0xe7, 0x25, 0xf3, 0x87, 0xdd, 0xa0, 0x3b, 0xc1, 0x99, + 0x33, 0xbe, 0x50, 0x36, 0x5b, 0x50, 0x62, 0x0a, 0xc4, 0xae, 0x09, 0x36, + 0x32, 0x8e, 0x19, 0xdc, 0x79, 0x80, 0xd4, 0xe0, 0x82, 0xa2, 0x73, 0xf3, + 0x5f, 0x69, 0x56, 0xcc, 0xe2, 0x29, 0xbd, 0xae, 0x9d, 0xc8, 0x15, 0xdb, + 0xf8, 0xb2, 0xda, 0xfb, 0x04, 0xac, 0x45, 0xaa, 0x6d, 0x3b, 0x7b, 0x26, + 0x87, 0xa5, 0xee, 0x34, 0x46, 0x81, 0x0e, 0xb4, 0x37, 0x2e, 0x6b, 0x8e, + 0x60, 0xc5, 0x6e, 0xec, 0x88, 0x5a, 0x71, 0x34, 0x80, 0x1a, 0xc5, 0x4b, + 0x6c, 0x07, 0x01, 0x2a, 0x39, 0x50, 0x9b, 0x67, 0xa3, 0xc1, 0x5c, 0xee, + 0x9f, 0x8e, 0xd7, 0x3e, 0xe4, 0x7f, 0xd4, 0x11, 0x86, 0xa4, 0x38, 0xa9, + 0xdf, 0x7f, 0xb7, 0x1e, 0x50, 0xe1, 0x34, 0xbe, 0x01, 0x69, 0x5e, 0xad, + 0xbf, 0xcf, 0xba, 0xc8, 0x9d, 0x04, 0x42, 0xf7, 0x3f, 0xf2, 0xaa, 0x92, + 0x1a, 0xb4, 0x05, 0x0a, 0xae, 0x02, 0x08, 0x01, 0x12, 0x10, 0x6b, 0x99, + 0x4c, 0x4a, 0x94, 0x73, 0x2e, 0x0c, 0x81, 0xca, 0xcc, 0x34, 0x71, 0xcf, + 0x8a, 0x63, 0x18, 0xe1, 0xa7, 0xbd, 0xd0, 0x05, 0x22, 0x8e, 0x02, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbc, 0xfa, 0x43, 0x1b, + 0xaa, 0xbb, 0xd9, 0xb7, 0x5b, 0xb8, 0xec, 0xf6, 0xf0, 0xb6, 0xb1, 0xa6, + 0xc3, 0xd1, 0x45, 0xb8, 0x6e, 0x40, 0x85, 0xa0, 0xcf, 0x24, 0x68, 0x91, + 0xc2, 0x45, 0x8d, 0x4e, 0xf2, 0x42, 0x9e, 0xaa, 0x72, 0xed, 0x86, 0xdc, + 0xfb, 0x85, 0x29, 0x3f, 0x90, 0xb0, 0xc5, 0x12, 0x4e, 0x42, 0x0b, 0xce, + 0xfa, 0x0f, 0x83, 0x1a, 0x4c, 0xe9, 0xc9, 0xc1, 0x0b, 0x12, 0xeb, 0xc7, + 0xc5, 0x1a, 0xd5, 0xa1, 0x8d, 0x26, 0x6d, 0x78, 0x87, 0x2d, 0xc2, 0x63, + 0x84, 0x6c, 0x5e, 0x78, 0xd8, 0x0a, 0x78, 0x68, 0xc2, 0x82, 0x40, 0x0a, + 0xf7, 0x02, 0x63, 0x97, 0xec, 0x1c, 0x08, 0x91, 0x2b, 0xc2, 0xa7, 0xe9, + 0x17, 0xb8, 0x7b, 0x84, 0xed, 0xdc, 0x5c, 0x6c, 0x11, 0x38, 0xb4, 0x18, + 0xff, 0x11, 0x32, 0xd4, 0x34, 0x48, 0xc0, 0xa0, 0x47, 0x2d, 0x81, 0xe2, + 0xb6, 0x41, 0xe9, 0xd4, 0x5a, 0xf1, 0x75, 0x3d, 0x94, 0xf7, 0xb7, 0xf6, + 0x3b, 0x35, 0x78, 0x9c, 0x72, 0x7b, 0x12, 0xe0, 0x73, 0xd9, 0x92, 0x3d, + 0x23, 0xe6, 0xa2, 0x50, 0x95, 0xcc, 0xbc, 0x8b, 0xef, 0xa3, 0x09, 0x85, + 0x85, 0xb8, 0x74, 0xa8, 0x10, 0xab, 0x0a, 0x18, 0x35, 0x7d, 0x27, 0x5c, + 0x6a, 0x52, 0x0e, 0x5b, 0xb9, 0xa9, 0x2c, 0xee, 0xdf, 0x6e, 0xa3, 0x49, + 0xbf, 0x32, 0x3a, 0x6a, 0xe2, 0x72, 0xe4, 0xdd, 0x6f, 0xfb, 0x89, 0xf3, + 0xdf, 0xa6, 0x4a, 0x52, 0x8a, 0x9d, 0xd5, 0x49, 0x04, 0x33, 0xd2, 0xa2, + 0xca, 0x74, 0x3b, 0x2c, 0x34, 0xf1, 0x12, 0x2f, 0x85, 0xc3, 0x3c, 0x4f, + 0x73, 0x1f, 0x2c, 0x8a, 0xd2, 0x6f, 0xa4, 0xb7, 0x91, 0xf9, 0x5f, 0x79, + 0x04, 0x9c, 0x69, 0xe6, 0x62, 0xab, 0x15, 0x91, 0x23, 0x0e, 0x62, 0xbc, + 0x80, 0x1f, 0x97, 0x5f, 0x33, 0xe7, 0x33, 0x9e, 0x91, 0xf6, 0xdc, 0xfb, + 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0xe9, 0x3d, 0x12, 0x80, 0x03, 0x0e, + 0x78, 0x2b, 0x14, 0x53, 0x5c, 0x82, 0x9a, 0x00, 0x8d, 0x49, 0x18, 0x5e, + 0x21, 0xb6, 0xfb, 0xeb, 0xa7, 0xee, 0x10, 0x26, 0x75, 0x6f, 0xcd, 0x45, + 0xe8, 0x64, 0x72, 0x56, 0x9e, 0x39, 0x3d, 0x7e, 0x6a, 0x70, 0x5d, 0xf1, + 0x4a, 0xc0, 0x23, 0x66, 0x07, 0x04, 0x4c, 0x8d, 0x18, 0xf7, 0xa7, 0xc5, + 0xc3, 0x18, 0x3f, 0x72, 0xf4, 0xfd, 0xad, 0xb5, 0xc6, 0x8b, 0x77, 0x2e, + 0x20, 0xfb, 0xe4, 0x7b, 0xef, 0x79, 0xef, 0xcd, 0x7f, 0x21, 0x9c, 0x32, + 0xcf, 0xf4, 0xc8, 0xee, 0xfa, 0x81, 0x38, 0x7e, 0x36, 0xec, 0xdd, 0x29, + 0x94, 0xc3, 0xb7, 0x25, 0x6e, 0x77, 0x90, 0x81, 0xbe, 0x6c, 0x16, 0x75, + 0x83, 0x33, 0x41, 0x78, 0x74, 0xb3, 0x54, 0xa4, 0xe6, 0x1c, 0x95, 0xa2, + 0x1c, 0x2b, 0x93, 0x6c, 0xb7, 0xd3, 0x37, 0x31, 0x57, 0xa8, 0x95, 0xce, + 0x0e, 0x16, 0xc0, 0xbb, 0x4e, 0x23, 0xca, 0x23, 0x2a, 0x66, 0x4c, 0xe5, + 0xac, 0xc3, 0x0a, 0xe3, 0x31, 0x32, 0x53, 0xad, 0x2c, 0x70, 0x1d, 0x5a, + 0x20, 0x27, 0xf2, 0x6f, 0x0c, 0x53, 0x7b, 0x71, 0x77, 0x94, 0x5c, 0x28, + 0xc3, 0xf3, 0x3e, 0x48, 0x5f, 0x1a, 0xa2, 0x18, 0xf3, 0x53, 0xb4, 0xa5, + 0x3c, 0xb1, 0x9c, 0x67, 0x39, 0x68, 0x8d, 0xfa, 0x96, 0x8f, 0x6f, 0xdd, + 0x29, 0x35, 0xbc, 0x2c, 0x0d, 0xe5, 0xd7, 0xff, 0x25, 0x2d, 0xcd, 0x3f, + 0xdc, 0xb9, 0xa0, 0xaf, 0x5a, 0x41, 0x3c, 0xce, 0xa9, 0xab, 0x75, 0xee, + 0xf2, 0xbe, 0xee, 0xa8, 0x3b, 0x29, 0xaf, 0x07, 0xbf, 0x84, 0xbd, 0xdd, + 0xe3, 0x83, 0x42, 0xd5, 0x40, 0x8d, 0x39, 0xcf, 0x4d, 0xa9, 0xa3, 0x0c, + 0xd8, 0xbc, 0xfc, 0x32, 0xa5, 0x03, 0x63, 0x22, 0x82, 0xde, 0x3d, 0x1d, + 0xd9, 0x54, 0xd8, 0xcc, 0x57, 0x10, 0x8b, 0xbe, 0xc3, 0xae, 0x52, 0xbc, + 0xaf, 0x17, 0x62, 0xe7, 0x9f, 0x42, 0x75, 0xb8, 0x92, 0x7f, 0x61, 0xd8, + 0x08, 0x57, 0x40, 0x10, 0x2c, 0x85, 0x96, 0x97, 0x48, 0x14, 0xde, 0xb0, + 0x5f, 0xf9, 0xc6, 0xde, 0xfc, 0x25, 0x9c, 0x4d, 0x6e, 0x52, 0x54, 0xf0, + 0xa2, 0xa5, 0xfc, 0x32, 0x45, 0x75, 0x94, 0xbe, 0xe9, 0x57, 0x2a, 0xb8, + 0x6e, 0xab, 0x0f, 0xf5, 0x0c, 0x9a, 0xf9, 0x29, 0x06, 0x65, 0x54, 0xd8, + 0x93, 0x98, 0x3a, 0x5c, 0x71, 0x52, 0x0d, 0xf3, 0x4b, 0xc4, 0xc5, 0xbd, + 0x34, 0xb3, 0x58, 0xcf, 0x83, 0x94, 0xf0, 0x60, 0xb7, 0x91, 0x56, 0xff, + 0x21, 0x7d, 0x03, 0xeb, 0xc9, 0x09, 0x0c, 0x45, 0x6d, 0xa0, 0xaa, 0xd3, + 0x58, 0xc6, 0xea, 0x9d, 0x2c, 0xfc, 0xd3, 0x0a, 0x43, 0x62, 0x66, 0x4d, + 0xdc, 0x25, 0xe2, 0x7f, 0x7e, 0x39, 0x33, 0x82, 0x97, 0x30, 0xfe, 0xdd, + 0x4d, 0x64, 0x56, 0xff, 0xf1, 0x76, 0xc2, 0x78, 0x0b, 0xce, 0xb3, 0x22, + 0x04, 0x49, 0x70, 0x32, 0x7f, 0x2a, 0x80, 0x02, 0x4a, 0x5c, 0x04, 0x01, + 0xf6, 0xa8, 0xcb, 0x49, 0x2f, 0xed, 0x48, 0x46, 0x15, 0xad, 0xa8, 0x0b, + 0x01, 0xb1, 0xf4, 0xcc, 0x79, 0x08, 0xb6, 0x82, 0x46, 0x3e, 0xdd, 0xc8, + 0x66, 0x4a, 0x84, 0xb3, 0xcb, 0x6a, 0xfb, 0xc4, 0x70, 0xca, 0xdf, 0x29, + 0x90, 0x25, 0x2a, 0x28, 0xd3, 0x7d, 0xcb, 0x3e, 0x95, 0x4e, 0xf8, 0x92, + 0xa2, 0xce, 0xe6, 0x21, 0x8e, 0x49, 0x29, 0x41, 0x0c, 0x64, 0x8c, 0x75, + 0xd6, 0x95, 0x69, 0xa0, 0xeb, 0x7d, 0xc9, 0x12, 0x60, 0x16, 0x31, 0xc9, + 0x9b, 0x40, 0xad, 0x58, 0x15, 0x1a, 0x9f, 0x81, 0xc1, 0x16, 0xec, 0x10, + 0xa4, 0x5a, 0x4e, 0xd0, 0x97, 0x60, 0xa0, 0x36, 0xc9, 0xfe, 0x42, 0x65, + 0xea, 0xd9, 0xf8, 0xa8, 0x3d, 0x19, 0xfe, 0xde, 0x1f, 0x57, 0x94, 0xf8, + 0x32, 0xab, 0xca, 0x9b, 0xfe, 0x5c, 0x21, 0x37, 0xb1, 0xc4, 0xf0, 0x2a, + 0x5a, 0xd7, 0x6a, 0xab, 0xd9, 0x7d, 0xd7, 0xa0, 0xb8, 0xb7, 0x35, 0x05, + 0xe7, 0xf4, 0xa7, 0xfc, 0xf9, 0x46, 0xe1, 0x84, 0x39, 0x14, 0x4c, 0xaa, + 0x69, 0x04, 0x39, 0x4a, 0x0b, 0xfb, 0x89, 0x9a, 0x39, 0x0b, 0x8c, 0xb4, + 0xd9, 0x3e, 0x96, 0xef, 0x7a, 0xb5, 0x13, 0xc7, 0x4e, 0x57, 0x3a, 0xd8, + 0xc9, 0x58, 0x0b, 0x76, 0xea, 0x21, 0xd3, 0x98, 0x26, 0xe7, 0xbb, 0x46, + 0xe4, 0x06, 0x91, 0x08, 0xf0, 0x10, 0xd6, 0x95, 0x31, 0x7f, 0x47, 0x95, + 0x79, 0x2b, 0xb8, 0x84, 0xeb, 0x9a, 0xc7, 0x89, 0x48, 0x12, 0xd3, 0x64, + 0xbe, 0x57, 0xfd, 0xc4, 0x26, 0x60, 0xc0, 0x01, 0xb7, 0x23, 0x40, 0xff, + 0x3d, 0x41, 0x51, 0xe8, 0x63, 0x74, 0x2d, 0xa5, 0x99, 0xaa, 0x73, 0xc0, + 0xad, 0xa5, 0xf7, 0x8d, 0x9a, 0xae, 0x13, 0xc9, 0x9b, 0x0e, 0x98, 0x0f, + 0xe7, 0xa7, 0x80, 0x5d, 0xf1, 0xe2, 0xf2, 0x27, 0x12, 0x34, 0x2f, 0x0c, + }; + provisioning_response_ = + std::string(reinterpret_cast(provisioning_response_raw), + sizeof(provisioning_response_raw)); + device_key_type_ = OEMCrypto_RSA_Private_Key; + RunTest(); +} + +////////////////////////////////////////////////////////////////////// +// License tests. +// All license requests from fake_l1, +// GTEST_FILTER="*PIG*:*CdmUseCase*Case1*" +////////////////////////////////////////////////////////////////////// + +TEST_F(ODKGoldenLicenseV18, CorePIGTest_OfflineNoNonce) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xd5, 0xb0, 0xe6, 0x63, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x99, 0x00, 0x02, 0x00, 0x12, + 0xd5, 0xb0, 0xe6, 0x63, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x02, 0x12, 0x08, 0xc2, 0xb4, 0x77, 0xd5, + 0x84, 0xc8, 0x31, 0xbf, 0x0a, 0x20, 0x33, 0x45, 0x44, 0x46, 0x41, 0x33, + 0x37, 0x36, 0x46, 0x46, 0x44, 0x31, 0x31, 0x37, 0x45, 0x31, 0x30, 0x33, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, 0x01, 0x18, 0x00, 0x20, 0x90, + 0x1c, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, + 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x74, 0x62, + 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0xb0, 0xe6, 0x63, 0xa0, 0x00, 0x00, 0x00, 0x3a, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xd4, + 0x66, 0x29, 0xee, 0x8b, 0x7c, 0x4e, 0x3b, 0x7e, 0x05, 0x51, 0xaf, 0xb8, + 0x94, 0xf4, 0xa7, 0xdc, 0xc7, 0x91, 0xb1, 0x3c, 0xbf, 0x9c, 0xb4, 0xf0, + 0x98, 0x18, 0xa4, 0xed, 0x97, 0xcd, 0xf9, 0x12, 0x10, 0xdb, 0x10, 0x29, + 0x51, 0xba, 0x34, 0x50, 0x67, 0x56, 0xbe, 0xe6, 0x8e, 0x31, 0x47, 0x90, + 0xa6, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x8c, 0xe5, 0x92, 0xa2, + 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = false; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, CorePIGTest_OfflineWithPST) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xea, 0x26, 0x31, 0x90, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x99, 0x00, 0x02, 0x00, 0x12, + 0xea, 0x26, 0x31, 0x90, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xc2, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x26, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x49, 0x32, 0x16, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4f, 0x66, 0x66, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x50, + 0x53, 0x54, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x41, 0x31, 0x42, 0x34, 0x37, + 0x45, 0x41, 0x34, 0x44, 0x42, 0x30, 0x30, 0x34, 0x30, 0x31, 0x30, 0x30, + 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, 0x01, 0x18, 0x00, 0x20, + 0x90, 0x1c, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, + 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x66, + 0x20, 0x01, 0x1a, 0x50, 0x6c, 0x21, 0x6a, 0x29, 0x1a, 0x78, 0x10, 0xd8, + 0xa0, 0x83, 0x56, 0x61, 0x43, 0x0d, 0x71, 0x29, 0xe7, 0x65, 0x34, 0x41, + 0xa5, 0x8b, 0x47, 0x19, 0x8d, 0x33, 0x2d, 0xb5, 0xbb, 0xfd, 0x6c, 0x30, + 0xa6, 0x01, 0x7d, 0xb2, 0x27, 0x53, 0xfa, 0x6d, 0xa5, 0x91, 0x59, 0x7c, + 0xf7, 0x25, 0x3d, 0x94, 0x44, 0xd0, 0x08, 0xba, 0x29, 0x80, 0xca, 0x02, + 0xb2, 0x84, 0x70, 0x8b, 0xb1, 0x4a, 0xcf, 0x0a, 0x1a, 0x03, 0xf2, 0x2d, + 0xa0, 0x07, 0x7f, 0x57, 0xbb, 0xf4, 0xe0, 0x33, 0x61, 0xd4, 0x92, 0x3a, + 0x12, 0x10, 0xe9, 0xc4, 0x28, 0x4e, 0x79, 0x62, 0x1a, 0x43, 0x99, 0xe6, + 0x99, 0x4f, 0xbf, 0x2e, 0x04, 0xb8, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xea, 0x26, + 0x31, 0x90, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x4d, 0xad, 0x9d, 0x20, + 0x56, 0xbe, 0x73, 0x9d, 0xbd, 0x78, 0x62, 0x79, 0x20, 0x63, 0x07, 0x34, + 0xa2, 0x79, 0x8e, 0x6f, 0x07, 0x82, 0x39, 0x98, 0x8d, 0xcf, 0x33, 0x40, + 0xc8, 0xb2, 0x32, 0x8a, 0x12, 0x10, 0x23, 0xa0, 0xc0, 0x02, 0xa1, 0x77, + 0x01, 0x80, 0xb3, 0xbc, 0xee, 0x5d, 0xf7, 0xb3, 0xd5, 0x3f, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x20, 0x8c, 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, CorePIGTest_OfflineHWSecureRequired) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x60, 0xa7, 0x85, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x02, 0x00, 0x12, + 0x60, 0xa7, 0x85, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xcb, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x41, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x2f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xb7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa5, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x83, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x52, 0x32, 0x1f, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4f, 0x66, 0x66, 0x6c, 0x69, 0x6e, 0x65, 0x48, 0x57, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x28, + 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x0a, 0x20, 0x30, 0x44, 0x41, 0x31, 0x30, 0x33, 0x41, 0x34, + 0x35, 0x34, 0x43, 0x46, 0x42, 0x46, 0x43, 0x46, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x12, 0x1d, 0x08, 0x01, 0x10, 0x01, 0x18, 0x00, 0x20, 0x90, 0x1c, 0x28, + 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, + 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x66, 0x20, 0x01, 0x1a, + 0x50, 0x95, 0xe5, 0x5f, 0x39, 0xfc, 0x34, 0x15, 0x00, 0x87, 0x88, 0x86, + 0x3d, 0x5a, 0x3b, 0xa2, 0xad, 0x51, 0x7d, 0xbc, 0xe0, 0x72, 0x99, 0x13, + 0xeb, 0x9d, 0x5c, 0xda, 0x92, 0x99, 0x5b, 0xe1, 0x3a, 0xc5, 0xe1, 0xc6, + 0x0b, 0x7b, 0x7e, 0x04, 0x4c, 0x17, 0x49, 0x26, 0x3a, 0xc4, 0xb1, 0xfb, + 0xec, 0x38, 0xce, 0x27, 0xc7, 0x54, 0x3b, 0x80, 0xec, 0xb1, 0x8e, 0xc9, + 0x5c, 0xa0, 0x70, 0xa1, 0x4d, 0x72, 0xee, 0xd6, 0x43, 0xfa, 0x28, 0xfe, + 0x58, 0x0a, 0x89, 0xe0, 0x0d, 0x8b, 0xe1, 0xe6, 0xbd, 0x12, 0x10, 0x93, + 0x88, 0x4d, 0xad, 0x48, 0x45, 0x49, 0x2b, 0x3d, 0x1a, 0xe8, 0xe8, 0xb3, + 0x60, 0x56, 0x8f, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x85, 0x0d, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0x0c, 0xd1, 0x21, 0xd5, 0xed, 0x86, 0xf2, + 0xf5, 0x00, 0xd7, 0xd1, 0x23, 0x29, 0x58, 0x3c, 0x0c, 0x14, 0x25, 0x9c, + 0xe4, 0x1f, 0x28, 0xc6, 0xc2, 0x7d, 0x8a, 0x21, 0xa0, 0xb6, 0x81, 0x34, + 0x85, 0x12, 0x10, 0x73, 0x6e, 0x1b, 0x2c, 0x67, 0xa4, 0x8e, 0x1d, 0xe1, + 0xc1, 0x8b, 0x5e, 0x86, 0x51, 0xf6, 0x24, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x85, 0x0d, 0xac, 0x00, 0x40, + 0x10, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x05, 0x20, + 0x02, 0x1a, 0x20, 0x84, 0x6e, 0x3d, 0x07, 0x57, 0x27, 0x4e, 0xd6, 0x1c, + 0x89, 0xeb, 0xe9, 0x9b, 0xba, 0x3a, 0x65, 0xbf, 0x60, 0xe9, 0x96, 0x66, + 0xee, 0xc1, 0xbf, 0xa5, 0xc8, 0x24, 0x4e, 0x58, 0x28, 0x93, 0x81, 0x12, + 0x10, 0xac, 0x3f, 0x24, 0x40, 0xa5, 0x05, 0x66, 0x3c, 0x77, 0x98, 0xf0, + 0xce, 0x29, 0xed, 0xa6, 0xa5, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x20, + 0x8c, 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_Streaming_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x8a, 0x97, 0xdf, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x8a, 0x97, 0xdf, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0xbb, 0xbe, 0x77, 0xd5, + 0x84, 0xc8, 0x31, 0xbf, 0x0a, 0x20, 0x43, 0x38, 0x42, 0x32, 0x39, 0x37, + 0x33, 0x43, 0x38, 0x33, 0x35, 0x43, 0x32, 0x43, 0x32, 0x30, 0x30, 0x43, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x28, + 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x00, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x8a, 0x97, 0xdf, 0x06, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xf1, 0x2c, + 0xbc, 0x3b, 0x17, 0x0f, 0x1c, 0xcd, 0xa6, 0xe5, 0xf6, 0x4b, 0xb2, 0xf2, + 0xd1, 0xbc, 0x19, 0x30, 0x1a, 0xa1, 0xc5, 0x9d, 0x0f, 0xba, 0xd7, 0x42, + 0x5c, 0xca, 0x96, 0xcf, 0x94, 0x79, 0x12, 0x10, 0xb7, 0xa8, 0xb0, 0xe3, + 0xdc, 0x06, 0x9f, 0xb0, 0x93, 0x59, 0x91, 0xf7, 0x48, 0xc3, 0x6f, 0x40, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x97, + 0xdf, 0x06, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x1d, 0xf6, 0x3a, 0x48, + 0xc4, 0x4b, 0x74, 0x6d, 0x79, 0x67, 0x9b, 0x16, 0xdb, 0x08, 0x92, 0x9c, + 0x08, 0x2c, 0x90, 0x70, 0x75, 0x38, 0x5e, 0x62, 0x39, 0xfc, 0x85, 0xc3, + 0x21, 0x96, 0x4b, 0x21, 0x12, 0x10, 0x4d, 0xcc, 0x09, 0x05, 0x88, 0x2c, + 0x92, 0xd4, 0x9e, 0x4b, 0x9b, 0x21, 0xd3, 0xea, 0x77, 0x50, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x97, 0xdf, 0x06, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xdd, 0xc1, 0x7b, 0x64, 0x3b, 0xdf, + 0x15, 0x56, 0x5a, 0x7d, 0xd1, 0xcb, 0x3a, 0xf5, 0xbb, 0xcd, 0x96, 0x89, + 0x12, 0xb2, 0xe7, 0xf7, 0x4c, 0xe3, 0x2c, 0xb4, 0x41, 0x54, 0xc3, 0xe6, + 0x8b, 0x3a, 0x12, 0x10, 0xfc, 0x3b, 0xae, 0x9f, 0x0c, 0x76, 0x3d, 0x25, + 0x81, 0x38, 0x64, 0xc6, 0xa6, 0x37, 0x6c, 0x4d, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x97, 0xdf, 0x06, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xb9, 0xd9, 0x58, 0x45, 0xa9, 0x41, 0x23, 0xf6, + 0x79, 0x8c, 0x02, 0x8f, 0x70, 0xc6, 0xb5, 0x09, 0xb7, 0x02, 0xf5, 0x37, + 0xf2, 0xeb, 0x66, 0x43, 0x92, 0x56, 0x2a, 0xe8, 0x37, 0x50, 0x40, 0x74, + 0x12, 0x10, 0x34, 0x3f, 0xf8, 0x2f, 0x7f, 0x13, 0x58, 0xf6, 0x76, 0x12, + 0xcb, 0xc8, 0x9d, 0xce, 0x0a, 0x63, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x97, 0xdf, 0x06, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x1d, 0x4a, 0xa0, 0xb2, 0x00, 0xb0, 0x41, 0xa3, 0xf2, 0xe5, + 0x4f, 0xf8, 0x19, 0x20, 0xe5, 0x35, 0xb1, 0x03, 0x65, 0xca, 0xe9, 0x76, + 0x07, 0x0d, 0xbc, 0xfc, 0xc3, 0xa1, 0xa4, 0x9b, 0x28, 0xe2, 0x12, 0x10, + 0x29, 0xb9, 0x38, 0x4d, 0x17, 0x06, 0x80, 0x42, 0x27, 0xb2, 0xdb, 0x59, + 0x01, 0x0f, 0x5d, 0x89, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x8c, + 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_Streaming_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x3f, 0xf4, 0x18, 0xc2, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x3f, 0xf4, 0x18, 0xc2, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xc8, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xb4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x2a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xf6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x6c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x16, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x50, 0x32, 0x1d, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, + 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, + 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x0a, 0x20, 0x39, 0x45, 0x36, 0x35, 0x39, 0x36, 0x32, 0x34, 0x36, 0x35, + 0x33, 0x32, 0x31, 0x36, 0x37, 0x36, 0x30, 0x45, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, + 0x08, 0x01, 0x10, 0x01, 0x18, 0x00, 0x20, 0x28, 0x28, 0x00, 0x30, 0x00, + 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x01, 0x78, 0x00, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0xfd, 0x23, + 0x53, 0x7d, 0xef, 0x21, 0xc4, 0x41, 0xd9, 0x91, 0xf7, 0xa1, 0x0b, 0x59, + 0x8e, 0x3c, 0x01, 0x6a, 0xa9, 0x61, 0x4e, 0x41, 0x01, 0xa5, 0x83, 0x09, + 0xe4, 0x6c, 0x00, 0xe5, 0xbd, 0x8d, 0xa2, 0x2d, 0x3e, 0x60, 0x04, 0xaf, + 0xd9, 0xf2, 0x26, 0x2e, 0xc2, 0x90, 0xad, 0x20, 0xec, 0xb1, 0x59, 0xa6, + 0xac, 0xf1, 0xae, 0x41, 0xea, 0x30, 0x4d, 0x26, 0x4a, 0x9e, 0x7d, 0xb6, + 0x49, 0x9c, 0x56, 0x7d, 0x15, 0xa4, 0x87, 0x5d, 0x8e, 0x8d, 0xa8, 0x04, + 0xb1, 0xd9, 0x35, 0xec, 0xe2, 0x28, 0x12, 0x10, 0xb8, 0x54, 0x5f, 0x94, + 0x08, 0xe2, 0xfb, 0x04, 0x1b, 0x37, 0x88, 0xf3, 0xa7, 0x04, 0x4f, 0x60, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, 0x18, 0xc2, 0xa0, 0x00, 0x40, 0x00, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0xce, 0xaa, 0x42, 0x05, 0x73, 0x6a, 0x3f, 0x91, 0xd4, 0x59, + 0xfb, 0xa4, 0xed, 0x70, 0xc4, 0x52, 0x1b, 0xfa, 0xd0, 0x9f, 0x65, 0x60, + 0x0c, 0xee, 0xa5, 0x93, 0x79, 0x56, 0x4d, 0x99, 0x66, 0xad, 0x12, 0x10, + 0x3d, 0xab, 0x36, 0xe6, 0xcd, 0xe5, 0xcc, 0x8a, 0x3b, 0xb9, 0x6f, 0x1c, + 0xd7, 0xad, 0x17, 0x01, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xf4, 0x18, 0xc2, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0xe2, 0x32, 0x82, 0xee, 0xfd, 0x30, 0x86, 0x68, 0xb7, 0xce, 0x0b, 0x68, + 0x7b, 0xcb, 0x83, 0xb4, 0xff, 0xa5, 0x9e, 0xa9, 0xcf, 0x11, 0x95, 0x49, + 0xf8, 0xea, 0x8b, 0x6e, 0x58, 0x9b, 0x4e, 0x0b, 0x12, 0x10, 0x91, 0x14, + 0x07, 0x38, 0xdd, 0x0a, 0xc3, 0xf6, 0xa6, 0x11, 0x61, 0x7a, 0x92, 0x61, + 0xf0, 0x5c, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xf4, 0x18, 0xc2, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x48, 0x07, + 0xdd, 0x06, 0xf2, 0x01, 0x7b, 0xa1, 0x7a, 0x5a, 0xee, 0x4a, 0x73, 0x79, + 0x7d, 0x51, 0x60, 0x4a, 0x84, 0xb6, 0x15, 0xae, 0x61, 0xbd, 0xdc, 0xe6, + 0xc6, 0x7f, 0x19, 0xf1, 0xdc, 0x30, 0x12, 0x10, 0xc6, 0x67, 0x0a, 0x18, + 0x38, 0xc6, 0x3b, 0xb9, 0x9a, 0xc3, 0x89, 0xbe, 0x87, 0xdd, 0xf8, 0x02, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, + 0x18, 0xc2, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x09, 0x89, 0x2c, 0x1f, + 0x09, 0x67, 0x21, 0xe2, 0x8f, 0x58, 0x5e, 0xab, 0x45, 0x07, 0xdf, 0x92, + 0x38, 0x8a, 0xa9, 0x93, 0x5d, 0xcd, 0xba, 0x37, 0x22, 0x50, 0x78, 0x8c, + 0x0d, 0x56, 0x83, 0xcb, 0x12, 0x10, 0xd6, 0x1c, 0x3c, 0xf8, 0xbb, 0xdb, + 0xbc, 0x96, 0xec, 0x78, 0x07, 0x36, 0x8a, 0x09, 0x1d, 0x31, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, 0x18, 0xc2, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xc1, 0xf8, 0xd9, 0xfd, 0x70, 0xb4, + 0x8a, 0x36, 0xbb, 0x0f, 0x20, 0x7d, 0x99, 0xb0, 0x8a, 0x1f, 0x49, 0x59, + 0xd9, 0x76, 0xd3, 0x10, 0x6e, 0x74, 0xea, 0x3a, 0x11, 0xc2, 0x5a, 0xc0, + 0x95, 0x87, 0x12, 0x10, 0x9a, 0x39, 0xb1, 0xa7, 0x58, 0x34, 0x90, 0x41, + 0x5d, 0xb2, 0x86, 0x8e, 0x43, 0x87, 0x06, 0x43, 0x0a, 0x10, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, + 0x3d, 0x3d, 0x20, 0xb2, 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_StreamingQuickStart_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xb9, 0x93, 0x15, 0xdf, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xb9, 0x93, 0x15, 0xdf, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0x9e, 0xf9, 0xba, 0x9a, + 0xe7, 0x55, 0x4d, 0xe1, 0x0a, 0x20, 0x46, 0x31, 0x44, 0x43, 0x33, 0x46, + 0x37, 0x43, 0x42, 0x32, 0x37, 0x46, 0x36, 0x42, 0x34, 0x39, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x14, + 0x28, 0x28, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0xb9, 0x93, 0x15, 0xdf, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x09, 0xd2, + 0x95, 0xac, 0x6d, 0x8d, 0xa8, 0x93, 0x1f, 0x8d, 0x99, 0x6c, 0xa7, 0x97, + 0xd6, 0x74, 0x4c, 0x12, 0x65, 0x2e, 0x28, 0xce, 0x56, 0x61, 0xfe, 0x1f, + 0x4c, 0xa2, 0x16, 0xdb, 0xa2, 0xc0, 0x12, 0x10, 0xad, 0xf5, 0x6f, 0xa0, + 0x90, 0xbc, 0xec, 0x90, 0x45, 0x9a, 0x26, 0x89, 0xfa, 0x0e, 0x05, 0xe9, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x93, + 0x15, 0xdf, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x38, 0xf3, 0x56, 0x63, + 0x38, 0x08, 0xd9, 0xa9, 0xc4, 0x6c, 0x2b, 0xc7, 0xf4, 0x20, 0x96, 0xc6, + 0xfc, 0xe9, 0x77, 0x2c, 0x2f, 0x3b, 0x4c, 0x95, 0x29, 0x72, 0x77, 0x89, + 0xfb, 0x00, 0x5a, 0xba, 0x12, 0x10, 0x04, 0xc0, 0xd8, 0x71, 0x49, 0x0f, + 0xe8, 0x5a, 0xbe, 0x79, 0x8b, 0x26, 0xff, 0x0e, 0xea, 0x32, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x93, 0x15, 0xdf, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x52, 0x05, 0xcd, 0x54, 0xd0, 0x57, + 0xd7, 0x20, 0x73, 0xfb, 0xc9, 0x17, 0x6a, 0x00, 0x97, 0x2c, 0x46, 0xef, + 0xac, 0x89, 0x76, 0x6e, 0x9d, 0x75, 0x1c, 0x77, 0x0d, 0x78, 0x4f, 0x92, + 0x8a, 0x66, 0x12, 0x10, 0x20, 0xb2, 0xd6, 0xe0, 0xdb, 0x28, 0x17, 0xd0, + 0x6c, 0x73, 0x43, 0x61, 0x26, 0x85, 0x6b, 0xff, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x93, 0x15, 0xdf, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x1f, 0x33, 0xf5, 0x6b, 0x0b, 0x3d, 0x66, 0x80, + 0xd7, 0xfc, 0x54, 0xc0, 0x0b, 0x62, 0x64, 0x3a, 0x86, 0x9b, 0xb2, 0x59, + 0x7f, 0xaa, 0x60, 0xb9, 0x63, 0x1f, 0x61, 0xf1, 0xeb, 0xdd, 0xd5, 0x6a, + 0x12, 0x10, 0x57, 0xe6, 0x99, 0x9b, 0x03, 0x81, 0x00, 0x53, 0x19, 0xbb, + 0x33, 0xf5, 0x46, 0xe8, 0xea, 0xe7, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0xb9, 0x93, 0x15, 0xdf, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x5d, 0xb3, 0x31, 0x70, 0x1a, 0x43, 0x40, 0xd8, 0x5c, 0xfa, + 0x2f, 0x33, 0x24, 0x0a, 0x9c, 0xa4, 0xd1, 0xc6, 0x7a, 0x78, 0x06, 0x79, + 0x77, 0xc9, 0x91, 0x32, 0x1d, 0x50, 0xae, 0x22, 0xaa, 0x04, 0x12, 0x10, + 0xc4, 0x0f, 0x3e, 0x4c, 0xef, 0x41, 0xb0, 0xd2, 0x55, 0x6d, 0x58, 0x8c, + 0x67, 0x61, 0x32, 0x14, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xd8, + 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_StreamingQuickStart_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xbc, 0xec, 0x1a, 0x0e, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xbc, 0xec, 0x1a, 0x0e, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xd2, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbe, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x22, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xaa, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x76, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x5a, 0x32, 0x27, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x69, + 0x63, 0x6b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x61, 0x6e, 0x5f, + 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, + 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, + 0x36, 0x44, 0x38, 0x46, 0x38, 0x37, 0x31, 0x34, 0x36, 0x45, 0x32, 0x42, + 0x44, 0x31, 0x39, 0x37, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, + 0x10, 0x01, 0x18, 0x00, 0x20, 0x14, 0x28, 0x28, 0x30, 0x00, 0x38, 0x00, + 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, + 0x78, 0x01, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0x88, 0x47, 0xab, 0x96, + 0x76, 0x99, 0xbc, 0xd2, 0xf8, 0xef, 0xb2, 0xcf, 0x1f, 0x30, 0xc4, 0x2e, + 0x14, 0x74, 0xee, 0x87, 0x04, 0x39, 0x62, 0x92, 0xcf, 0xbd, 0x86, 0xb0, + 0x21, 0xd2, 0x38, 0xa0, 0x6d, 0x3f, 0xe4, 0x15, 0x91, 0xbb, 0xda, 0xe0, + 0x21, 0x98, 0x23, 0xc4, 0x32, 0x2a, 0x47, 0x5a, 0xa1, 0x96, 0x5e, 0xae, + 0xf4, 0x6f, 0xc3, 0x2b, 0x88, 0xdc, 0xe3, 0x2a, 0x76, 0x96, 0x33, 0xd7, + 0xff, 0x9f, 0x39, 0x06, 0x43, 0x49, 0x4d, 0xdc, 0x04, 0xcd, 0x39, 0xe7, + 0x18, 0xde, 0x10, 0xe0, 0x12, 0x10, 0xa7, 0x26, 0xd7, 0x8e, 0xbf, 0xcc, + 0xbb, 0x23, 0xb5, 0xdd, 0xb2, 0x21, 0x63, 0x97, 0x67, 0x91, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x00, 0xbc, 0xec, 0x1a, 0x0e, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x21, 0xe3, 0xf4, 0xb8, 0x06, 0x1a, 0x58, 0x7a, 0xf1, 0x2e, 0x1b, 0x1e, + 0xc3, 0x0e, 0x16, 0x98, 0x68, 0xb4, 0x64, 0x51, 0xca, 0xa3, 0x32, 0x93, + 0x29, 0xb7, 0xb7, 0x1a, 0x1b, 0xdf, 0xf7, 0x83, 0x12, 0x10, 0x3d, 0xb1, + 0x0b, 0x85, 0x88, 0x4c, 0xf7, 0x90, 0xd2, 0xb9, 0xa5, 0x29, 0x40, 0x26, + 0xe5, 0x0b, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0xbc, 0xec, 0x1a, 0x0e, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xde, 0x6f, + 0x93, 0xf4, 0x98, 0x0a, 0xd6, 0x51, 0x7b, 0x13, 0x3e, 0x78, 0xbb, 0xf4, + 0xb1, 0xf7, 0xa9, 0x3b, 0xcc, 0x0a, 0xc7, 0x47, 0xaa, 0x36, 0xa7, 0xa4, + 0x6c, 0x95, 0x37, 0xbd, 0xa5, 0x71, 0x12, 0x10, 0x89, 0x36, 0xbf, 0x1b, + 0x08, 0x80, 0x93, 0xa6, 0x16, 0x19, 0x1c, 0x1d, 0x12, 0xee, 0xbc, 0xfa, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xec, + 0x1a, 0x0e, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xea, 0x7e, 0x0f, 0x41, + 0x82, 0x35, 0xab, 0xbd, 0x29, 0xa6, 0xb0, 0x6b, 0x71, 0xde, 0x44, 0x63, + 0xd0, 0xd4, 0xcf, 0xb7, 0xb0, 0xac, 0xa7, 0x13, 0xb0, 0x32, 0xad, 0x59, + 0x17, 0x0f, 0x12, 0x09, 0x12, 0x10, 0xf6, 0x90, 0x09, 0xf1, 0xb0, 0x2a, + 0xf5, 0xf7, 0x59, 0x5b, 0x80, 0x70, 0x61, 0x9c, 0x52, 0x4b, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xec, 0x1a, 0x0e, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xba, 0xbe, 0x6e, 0x4f, 0x61, 0x3a, + 0xea, 0xb8, 0x1f, 0xc8, 0x4e, 0xc3, 0x89, 0x62, 0xc7, 0xc6, 0x66, 0xb6, + 0x46, 0x0b, 0xac, 0x83, 0x70, 0xd7, 0x9b, 0x06, 0x64, 0x18, 0xe9, 0x1c, + 0xf7, 0xdb, 0x12, 0x10, 0xb2, 0xb3, 0x5d, 0x04, 0xd3, 0xfc, 0xf5, 0xd6, + 0x9d, 0x45, 0x30, 0x93, 0xab, 0x0a, 0xb0, 0x8c, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xec, 0x1a, 0x0e, 0xa0, 0x00, + 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x72, 0xff, 0xef, 0x83, 0xc9, 0x46, 0x33, 0xa3, + 0x9f, 0x9d, 0x12, 0xf0, 0xac, 0xad, 0xc0, 0x11, 0x0f, 0x22, 0x54, 0xe5, + 0x46, 0x95, 0xe3, 0x9e, 0x24, 0x34, 0x2c, 0x38, 0x4f, 0x33, 0xaf, 0xb3, + 0x12, 0x10, 0x9b, 0xe8, 0xf0, 0x81, 0x44, 0x2d, 0x03, 0x83, 0x41, 0x96, + 0xa2, 0x2f, 0x27, 0x1c, 0x01, 0xbb, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, + 0x20, 0xec, 0xe5, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenHardTwoHard_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x58, 0x6b, 0xd9, 0xcf, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x58, 0x6b, 0xd9, 0xcf, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0x3c, 0xff, 0xba, 0x9a, + 0xe7, 0x55, 0x4d, 0xe1, 0x0a, 0x20, 0x41, 0x31, 0x41, 0x36, 0x46, 0x44, + 0x32, 0x33, 0x35, 0x39, 0x30, 0x31, 0x36, 0x38, 0x31, 0x41, 0x31, 0x34, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x64, + 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x6b, 0xd9, 0xcf, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x25, 0xcf, + 0x8b, 0xa2, 0xd5, 0xaa, 0x7b, 0x7b, 0x03, 0x9c, 0xbc, 0x83, 0x08, 0xe2, + 0xbd, 0xdd, 0xab, 0xd4, 0x32, 0x13, 0x75, 0xa1, 0x3f, 0x89, 0x73, 0x89, + 0x7b, 0x7f, 0xae, 0x91, 0x75, 0xdc, 0x12, 0x10, 0xb6, 0xed, 0xbf, 0x9e, + 0xf9, 0xae, 0xae, 0x70, 0x91, 0xf9, 0x75, 0x8c, 0xa6, 0xf2, 0x0c, 0xf3, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x6b, + 0xd9, 0xcf, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xcf, 0xf5, 0xf1, 0xa0, + 0x71, 0x28, 0x33, 0x90, 0xb7, 0xf3, 0x5c, 0xf3, 0xab, 0xd2, 0xc9, 0x06, + 0xf4, 0xd8, 0x02, 0xf1, 0x0a, 0xe3, 0x35, 0x11, 0xd8, 0x43, 0x49, 0x3f, + 0xab, 0x11, 0x66, 0x56, 0x12, 0x10, 0xa0, 0xff, 0xb1, 0x20, 0xe9, 0xc1, + 0xc4, 0xcb, 0x5a, 0x6b, 0xc8, 0x14, 0xd1, 0x93, 0x92, 0xbf, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x6b, 0xd9, 0xcf, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x7e, 0xa7, 0x9a, 0xea, 0xb1, 0x3f, + 0xbb, 0x43, 0x8f, 0x87, 0x6f, 0xc3, 0x22, 0x08, 0xb2, 0xf8, 0xdc, 0x23, + 0xf0, 0xe7, 0x39, 0xd5, 0xf3, 0xcd, 0x8c, 0x61, 0xaf, 0xc5, 0x5e, 0xed, + 0x2a, 0xb8, 0x12, 0x10, 0x16, 0x35, 0xe9, 0x61, 0x87, 0x0d, 0xeb, 0xc0, + 0x49, 0x23, 0x1e, 0x81, 0x6d, 0x4c, 0x0f, 0x3d, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x6b, 0xd9, 0xcf, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xbc, 0x0d, 0x2c, 0xc4, 0xea, 0x97, 0x35, 0x58, + 0x2d, 0x68, 0x59, 0xe9, 0x5a, 0xde, 0x62, 0x4d, 0x2c, 0x3f, 0xd6, 0xf5, + 0xd4, 0x9d, 0x0c, 0xd4, 0x12, 0x94, 0xa4, 0xee, 0x18, 0xe3, 0x6c, 0x84, + 0x12, 0x10, 0x1f, 0x33, 0xdf, 0xba, 0xfb, 0x62, 0xc3, 0x89, 0xa5, 0x42, + 0xd1, 0x0f, 0x2f, 0x9a, 0xe0, 0x5d, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x6b, 0xd9, 0xcf, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0xc6, 0x7a, 0xc8, 0x0b, 0x86, 0x53, 0x8f, 0x95, 0xf0, 0x42, + 0x84, 0xc4, 0xc0, 0x1b, 0x95, 0x71, 0x16, 0x50, 0x32, 0xb2, 0x9e, 0xa5, + 0x0d, 0xbd, 0xe2, 0xb5, 0x30, 0x24, 0xc4, 0x7f, 0x83, 0x20, 0x12, 0x10, + 0x35, 0xc1, 0xcd, 0x22, 0x49, 0x39, 0x68, 0xf5, 0xdc, 0xb6, 0xc4, 0x01, + 0x60, 0xa7, 0x66, 0x12, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x80, + 0xe6, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenHardTwoHard_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xe0, 0xac, 0x6c, 0xd3, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xe0, 0xac, 0x6c, 0xd3, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x1f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x57, 0x32, 0x24, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x65, 0x76, 0x65, 0x6e, 0x48, 0x61, 0x72, 0x64, 0x54, 0x77, 0x6f, + 0x48, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x45, 0x42, 0x33, + 0x35, 0x33, 0x37, 0x41, 0x41, 0x35, 0x31, 0x33, 0x31, 0x44, 0x43, 0x43, + 0x43, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, + 0x00, 0x20, 0x64, 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, + 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, + 0x66, 0x20, 0x01, 0x1a, 0x50, 0x67, 0x27, 0x5d, 0xad, 0xc3, 0x2a, 0xd0, + 0x1c, 0xaf, 0xc4, 0x98, 0x00, 0x78, 0xd8, 0x8e, 0x44, 0x57, 0x56, 0xfa, + 0x43, 0x7a, 0x66, 0x68, 0x85, 0x72, 0xb0, 0xd7, 0x78, 0x9a, 0x64, 0xbb, + 0xd6, 0x72, 0x17, 0x03, 0x45, 0x3e, 0xd4, 0xbd, 0xf1, 0x8e, 0x10, 0xa3, + 0xe6, 0x9c, 0x7f, 0xf9, 0x74, 0x11, 0x2b, 0x0f, 0xe5, 0x43, 0x74, 0x65, + 0x4e, 0x5b, 0x75, 0x06, 0x1b, 0x34, 0x31, 0x4c, 0xf3, 0x1b, 0xd4, 0xf6, + 0xf4, 0x3b, 0x1c, 0x33, 0xdc, 0x12, 0x72, 0xde, 0x23, 0x1b, 0xee, 0x38, + 0x4c, 0x12, 0x10, 0x98, 0xa6, 0x43, 0x34, 0xc4, 0x6f, 0xf5, 0x9d, 0x06, + 0x3a, 0x11, 0x1b, 0x7f, 0xa3, 0x43, 0x15, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0xac, 0x6c, 0xd3, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x64, 0x9b, 0xdf, + 0x37, 0x92, 0x73, 0xc0, 0xe9, 0x42, 0x0f, 0x66, 0x22, 0x8e, 0xaf, 0x52, + 0x8d, 0x4b, 0x51, 0xe8, 0xc9, 0x93, 0xcb, 0x0e, 0x6a, 0x97, 0x09, 0xb6, + 0xd2, 0x66, 0x71, 0x04, 0x6a, 0x12, 0x10, 0xe7, 0x24, 0x8f, 0xd8, 0x17, + 0x35, 0x7f, 0xdd, 0x4c, 0xcb, 0xeb, 0x7d, 0x0b, 0xf5, 0x2b, 0xd8, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xac, 0x6c, + 0xd3, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x87, 0x32, 0xb2, 0x84, 0x23, + 0x9e, 0x58, 0x74, 0x2b, 0x1a, 0xee, 0x70, 0x33, 0x7a, 0xb8, 0x92, 0x59, + 0x83, 0x27, 0xfd, 0x88, 0xd2, 0x27, 0x58, 0xaf, 0x5a, 0xc6, 0x80, 0x0f, + 0xe6, 0xaf, 0x52, 0x12, 0x10, 0x67, 0x5e, 0x28, 0xe7, 0x03, 0x03, 0x02, + 0x25, 0x6c, 0xb3, 0x6b, 0x5d, 0x6d, 0x17, 0xfd, 0xb4, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xac, 0x6c, 0xd3, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0x11, 0xbe, 0xe2, 0x5d, 0xbf, 0xaf, 0x99, + 0x15, 0xf0, 0x92, 0x9f, 0x73, 0x14, 0x5a, 0xe0, 0xf4, 0x1d, 0x18, 0xe5, + 0xcb, 0x75, 0x94, 0xa3, 0x1f, 0xc1, 0x6b, 0x29, 0x41, 0x96, 0xac, 0x5b, + 0xfb, 0x12, 0x10, 0xa9, 0x96, 0x6f, 0x3f, 0x71, 0x6d, 0x82, 0x97, 0xe6, + 0x1a, 0x8f, 0xd7, 0x80, 0x8c, 0x1c, 0xed, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xac, 0x6c, 0xd3, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x3f, 0x3e, 0x52, 0x34, 0xbb, 0x73, 0x2f, 0x87, 0x13, + 0xcd, 0x5e, 0xfb, 0x07, 0x0a, 0xd9, 0x59, 0x39, 0x8c, 0x6a, 0x0c, 0x24, + 0x46, 0xeb, 0xf4, 0xce, 0x98, 0x3e, 0x58, 0x80, 0x9e, 0xb2, 0x5e, 0x12, + 0x10, 0x08, 0x0d, 0xdf, 0x40, 0x1f, 0xe2, 0x80, 0x39, 0xf6, 0x00, 0xee, + 0x13, 0x7e, 0xdc, 0x66, 0x36, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0xac, 0x6c, 0xd3, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0xcb, 0x38, 0x5c, 0xe5, 0x50, 0xae, 0x40, 0xad, 0x0b, 0x43, 0xa8, + 0xda, 0x6a, 0x9c, 0x05, 0xd2, 0x75, 0x3a, 0x4e, 0x36, 0xf2, 0xa8, 0x31, + 0xe1, 0x5d, 0xec, 0xca, 0x78, 0x74, 0x94, 0xcf, 0x90, 0x12, 0x10, 0x36, + 0x0c, 0x71, 0x35, 0xba, 0xaa, 0x72, 0xd4, 0x44, 0x49, 0x59, 0xa4, 0xdc, + 0x93, 0xf6, 0xf7, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x98, 0xe6, + 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenHardTwoSoft_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x58, 0x89, 0xaa, 0xf3, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x58, 0x89, 0xaa, 0xf3, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0x0b, 0xfa, 0xba, 0x9a, + 0xe7, 0x55, 0x4d, 0xe1, 0x0a, 0x20, 0x45, 0x35, 0x30, 0x45, 0x31, 0x39, + 0x33, 0x46, 0x45, 0x46, 0x43, 0x41, 0x42, 0x37, 0x33, 0x42, 0x31, 0x38, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x64, + 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x00, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x89, 0xaa, 0xf3, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x8c, 0x9d, + 0x9b, 0x6a, 0x42, 0x78, 0x1a, 0x23, 0x63, 0x6d, 0x33, 0x03, 0x4b, 0x40, + 0x6f, 0x11, 0xd2, 0xfd, 0x53, 0x71, 0x1b, 0xed, 0x57, 0x6a, 0xb2, 0x90, + 0x6a, 0x95, 0x0a, 0x96, 0xa7, 0xa6, 0x12, 0x10, 0xcf, 0x6c, 0xff, 0xe6, + 0xee, 0xfb, 0x2b, 0xbf, 0x00, 0xce, 0x19, 0x9b, 0xcb, 0x4f, 0x5d, 0x68, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, + 0xaa, 0xf3, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xee, 0xbb, 0x14, 0x48, + 0xe5, 0xbf, 0x02, 0xba, 0xe7, 0x04, 0xfe, 0xd9, 0xb8, 0x27, 0xc1, 0xd0, + 0x2a, 0x2f, 0x3e, 0x3a, 0x0b, 0x63, 0x93, 0xf4, 0xb5, 0x5c, 0x76, 0x10, + 0xe9, 0xd5, 0xb6, 0xbb, 0x12, 0x10, 0x75, 0x8f, 0xbf, 0x03, 0xf6, 0x48, + 0xd1, 0x17, 0x4c, 0x77, 0xdc, 0x38, 0xca, 0x24, 0x8d, 0x88, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, 0xaa, 0xf3, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xed, 0xd6, 0xe0, 0x57, 0xb1, 0xf3, + 0xd1, 0x78, 0x2f, 0x70, 0x0e, 0x13, 0xff, 0xc6, 0x8c, 0x46, 0x01, 0x87, + 0xfd, 0x50, 0x10, 0x21, 0x69, 0x54, 0x21, 0x5e, 0x32, 0x22, 0x79, 0x16, + 0x97, 0xe0, 0x12, 0x10, 0x33, 0x86, 0x55, 0xf6, 0xde, 0x28, 0x2a, 0x57, + 0x7d, 0x1b, 0x23, 0x5f, 0xf8, 0xe8, 0x6a, 0x57, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, 0xaa, 0xf3, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x79, 0x9c, 0xa1, 0xcb, 0xc1, 0x90, 0x92, 0xff, + 0xe7, 0x2e, 0x3f, 0x5e, 0x00, 0x0f, 0x94, 0x43, 0xb7, 0xe8, 0x08, 0x7a, + 0xd4, 0xaa, 0xcf, 0xb8, 0xe4, 0x3a, 0x55, 0x55, 0xa2, 0xe1, 0x62, 0x7a, + 0x12, 0x10, 0x50, 0x1f, 0xa9, 0xad, 0xbe, 0x02, 0xc9, 0x45, 0xae, 0xa8, + 0x4d, 0x14, 0x89, 0x65, 0x24, 0x5e, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, 0xaa, 0xf3, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0xb4, 0xce, 0x8c, 0x83, 0xda, 0xb6, 0x2f, 0x70, 0x2c, 0x26, + 0xe4, 0xfa, 0x53, 0x18, 0xe6, 0xa9, 0x6e, 0x62, 0x67, 0x99, 0xf2, 0x96, + 0xfa, 0xcf, 0x05, 0xd4, 0x04, 0x33, 0x87, 0x79, 0x1e, 0x46, 0x12, 0x10, + 0xa3, 0x73, 0x28, 0x41, 0x77, 0xa6, 0x5c, 0xc2, 0xde, 0xe5, 0xb2, 0xbb, + 0x2a, 0xb7, 0x1a, 0xa7, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xb0, + 0xe6, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenHardTwoSoft_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x43, 0xea, 0x2d, 0x91, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x43, 0xea, 0x2d, 0x91, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x1f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x57, 0x32, 0x24, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x65, 0x76, 0x65, 0x6e, 0x48, 0x61, 0x72, 0x64, 0x54, 0x77, 0x6f, + 0x53, 0x6f, 0x66, 0x74, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x37, 0x37, 0x33, + 0x45, 0x44, 0x34, 0x33, 0x42, 0x30, 0x45, 0x42, 0x46, 0x38, 0x44, 0x39, + 0x39, 0x31, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, + 0x00, 0x20, 0x64, 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, + 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x00, 0x1a, + 0x66, 0x20, 0x01, 0x1a, 0x50, 0x52, 0x1e, 0x3c, 0x1d, 0x11, 0x35, 0xda, + 0xe5, 0x50, 0xa9, 0x90, 0xa6, 0x61, 0xbb, 0x49, 0xaf, 0x97, 0xbb, 0x14, + 0xf0, 0x5e, 0xbc, 0x34, 0xe4, 0x28, 0x30, 0xa8, 0x5d, 0x7b, 0x5e, 0x86, + 0x7f, 0xff, 0x45, 0x27, 0xd0, 0x71, 0x47, 0x3a, 0xb4, 0xbd, 0xa1, 0xed, + 0x35, 0xee, 0xe9, 0x51, 0x35, 0xb9, 0x50, 0xd3, 0x12, 0xef, 0xa6, 0x2d, + 0xe5, 0xb9, 0x28, 0xea, 0xb4, 0xd5, 0xa1, 0xc7, 0xd0, 0x88, 0xcc, 0x69, + 0x15, 0x54, 0xff, 0x82, 0x0e, 0x49, 0x28, 0x05, 0x3f, 0x16, 0x8c, 0xbb, + 0x1c, 0x12, 0x10, 0x42, 0x07, 0x9e, 0xe0, 0xa1, 0x15, 0x2e, 0xc2, 0x61, + 0x15, 0x61, 0xa5, 0x5d, 0x14, 0xd3, 0x96, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x43, + 0xea, 0x2d, 0x91, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x88, 0x73, 0xab, + 0x7b, 0x78, 0x40, 0x6c, 0xdb, 0x91, 0x1f, 0xab, 0x1e, 0xcd, 0x82, 0xe5, + 0x35, 0xd4, 0x4d, 0x73, 0x00, 0x7a, 0x23, 0x4c, 0x94, 0x81, 0x91, 0xcc, + 0xfb, 0x85, 0x0b, 0x91, 0x69, 0x12, 0x10, 0x0f, 0xd6, 0xcd, 0x74, 0xfa, + 0xb1, 0xc6, 0x75, 0xbe, 0xd3, 0x5b, 0xaa, 0x6e, 0xc6, 0x7e, 0xc5, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x43, 0xea, 0x2d, + 0x91, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xb0, 0x90, 0xfb, 0xee, 0x67, + 0x8b, 0xd2, 0x5c, 0xc7, 0xb7, 0x0d, 0x75, 0x18, 0x3e, 0x16, 0xbd, 0xd9, + 0x79, 0x81, 0x78, 0x98, 0xd4, 0x28, 0x1c, 0x5c, 0x02, 0x73, 0x7d, 0x34, + 0x74, 0xe6, 0xc3, 0x12, 0x10, 0x8e, 0xac, 0x28, 0xb7, 0xaf, 0x6c, 0x0c, + 0x86, 0xfa, 0xca, 0x50, 0xa7, 0x8b, 0xbc, 0xa2, 0x52, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x43, 0xea, 0x2d, 0x91, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0xb4, 0x4c, 0xc4, 0x8e, 0x9d, 0xa8, 0xae, + 0x95, 0x15, 0xe9, 0x73, 0x22, 0xfe, 0xa8, 0x94, 0x9a, 0xeb, 0xe6, 0xd3, + 0xaa, 0x84, 0xaf, 0x19, 0x6e, 0x76, 0xa3, 0x72, 0x33, 0x1a, 0x9c, 0xf3, + 0x83, 0x12, 0x10, 0xed, 0x21, 0x55, 0xca, 0x58, 0xfc, 0xcd, 0x0f, 0x53, + 0xc0, 0xac, 0xdc, 0xca, 0x64, 0xc8, 0x7c, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x43, 0xea, 0x2d, 0x91, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0xbd, 0x7c, 0xdf, 0xc3, 0x46, 0x14, 0xb4, 0xbe, 0x35, + 0x91, 0xde, 0x41, 0xee, 0x04, 0x75, 0x16, 0x6b, 0xe6, 0x25, 0x13, 0x51, + 0xd7, 0x05, 0x81, 0xd9, 0xd2, 0x74, 0xa7, 0xc8, 0xad, 0x16, 0xb3, 0x12, + 0x10, 0x27, 0xa4, 0x71, 0x7b, 0xe6, 0xc4, 0x45, 0x30, 0xea, 0x22, 0xdf, + 0x2c, 0x2e, 0x4f, 0x62, 0xe5, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x00, 0x43, 0xea, 0x2d, 0x91, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0x3a, 0xe2, 0xa9, 0x3a, 0xb3, 0x16, 0x7f, 0xdd, 0xa0, 0x0b, 0x5b, + 0x09, 0xf0, 0xd3, 0xa9, 0xd9, 0x46, 0x7a, 0x02, 0xc1, 0xa2, 0xee, 0x9a, + 0x43, 0x87, 0xda, 0xcb, 0x50, 0x71, 0x97, 0x72, 0x80, 0x12, 0x10, 0x3b, + 0xbe, 0x4c, 0xfc, 0x5c, 0x9c, 0xb6, 0x73, 0x6b, 0x3d, 0x65, 0x12, 0xce, + 0x73, 0x9f, 0x35, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xc8, 0xe6, + 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenSoftTwoHard_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xbd, 0xfa, 0x35, 0x42, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xbd, 0xfa, 0x35, 0x42, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0xa9, 0xff, 0xba, 0x9a, + 0xe7, 0x55, 0x4d, 0xe1, 0x0a, 0x20, 0x41, 0x41, 0x31, 0x30, 0x36, 0x33, + 0x35, 0x39, 0x39, 0x34, 0x36, 0x43, 0x30, 0x36, 0x39, 0x46, 0x31, 0x43, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x64, + 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0xbd, 0xfa, 0x35, 0x42, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x43, 0x6c, + 0xbb, 0x90, 0x68, 0xa0, 0xb9, 0xb3, 0x0a, 0xc4, 0x8a, 0xb5, 0xa4, 0xe0, + 0xd5, 0x04, 0x10, 0x9e, 0x76, 0xbd, 0xac, 0x3b, 0xbe, 0x8b, 0x0e, 0x74, + 0x3d, 0xfb, 0x2d, 0xcd, 0x71, 0x24, 0x12, 0x10, 0x4e, 0x14, 0xa2, 0x79, + 0xb9, 0xe6, 0x00, 0x76, 0xf6, 0x07, 0x35, 0xa2, 0x17, 0x2f, 0x67, 0x63, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfa, + 0x35, 0x42, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x35, 0xa1, 0x98, 0x43, + 0x76, 0x9e, 0x28, 0x79, 0x05, 0xcc, 0x81, 0x43, 0x7d, 0x30, 0x96, 0xd9, + 0x2a, 0xba, 0xc5, 0x6d, 0x28, 0x74, 0xb2, 0x28, 0xbd, 0x58, 0x46, 0x43, + 0xe3, 0xd5, 0xec, 0xf4, 0x12, 0x10, 0x52, 0xc9, 0x3d, 0xd0, 0x79, 0x84, + 0x6f, 0x28, 0xb1, 0x37, 0x77, 0x35, 0x6f, 0x56, 0x43, 0x41, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfa, 0x35, 0x42, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xa3, 0xe0, 0xff, 0x2b, 0xbc, 0x43, + 0xd9, 0x53, 0xbe, 0xa6, 0x02, 0x0c, 0x40, 0x9f, 0x6e, 0x38, 0x0e, 0x91, + 0x2e, 0xac, 0x29, 0x22, 0x4a, 0xe2, 0x45, 0x6c, 0x3a, 0x7d, 0x13, 0x49, + 0xb3, 0x78, 0x12, 0x10, 0x0e, 0xf1, 0x6c, 0x28, 0xe2, 0x60, 0xbb, 0x78, + 0xc2, 0x39, 0x41, 0x81, 0x2a, 0xab, 0x02, 0x59, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfa, 0x35, 0x42, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xd5, 0x7e, 0x38, 0x92, 0x1e, 0xe3, 0x47, 0x56, + 0x59, 0x9d, 0x91, 0xeb, 0x37, 0x43, 0x92, 0x04, 0xe7, 0x47, 0xa2, 0x3a, + 0x2e, 0x3c, 0x10, 0x1e, 0x73, 0xfb, 0x98, 0xd8, 0xe2, 0x73, 0xbe, 0x1e, + 0x12, 0x10, 0x7a, 0x8e, 0x64, 0xd8, 0x95, 0xf0, 0xe1, 0x63, 0xb8, 0xd8, + 0xfc, 0x27, 0x21, 0x19, 0x40, 0xda, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0xbd, 0xfa, 0x35, 0x42, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x7d, 0x36, 0x11, 0xef, 0x63, 0x68, 0xfb, 0x01, 0xa6, 0xcc, + 0xec, 0x3c, 0x7d, 0x67, 0x6c, 0x9e, 0x93, 0x0b, 0x4d, 0x92, 0xbc, 0xf9, + 0xb0, 0xd9, 0x4a, 0xda, 0xe0, 0x75, 0x58, 0x30, 0x88, 0x4d, 0x12, 0x10, + 0x19, 0xb0, 0xb1, 0x14, 0xce, 0x54, 0x65, 0x4f, 0xfa, 0x87, 0x70, 0x23, + 0xa7, 0xad, 0x10, 0x26, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xe0, + 0xe6, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenSoftTwoHard_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xc2, 0xd9, 0x80, 0xde, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xc2, 0xd9, 0x80, 0xde, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x1f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x57, 0x32, 0x24, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x65, 0x76, 0x65, 0x6e, 0x53, 0x6f, 0x66, 0x74, 0x54, 0x77, 0x6f, + 0x48, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x44, 0x32, 0x39, + 0x35, 0x45, 0x43, 0x35, 0x33, 0x37, 0x43, 0x38, 0x30, 0x30, 0x33, 0x34, + 0x43, 0x31, 0x45, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, + 0x00, 0x20, 0x64, 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, + 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, + 0x66, 0x20, 0x01, 0x1a, 0x50, 0x5e, 0xce, 0x69, 0xc0, 0x21, 0x8f, 0x81, + 0xdd, 0xbc, 0xf5, 0xac, 0x66, 0x2c, 0xd1, 0x67, 0x7d, 0x3e, 0xca, 0xd3, + 0xdc, 0x52, 0x7d, 0xf6, 0x4f, 0x21, 0xaa, 0xd8, 0x21, 0x01, 0x9c, 0xf7, + 0x21, 0xd5, 0x81, 0xa0, 0x45, 0x58, 0x9e, 0xcb, 0x40, 0x6a, 0x2a, 0x92, + 0x06, 0xd8, 0xef, 0xb7, 0xf8, 0x6a, 0x63, 0x22, 0x49, 0xcf, 0x74, 0x87, + 0x82, 0xca, 0xe9, 0x9f, 0xaf, 0x7d, 0x15, 0x7e, 0x24, 0x3f, 0x77, 0x0a, + 0xea, 0x5c, 0xc2, 0xd7, 0xfa, 0x80, 0x09, 0xcc, 0xe2, 0x2a, 0xfb, 0x2f, + 0x2d, 0x12, 0x10, 0x13, 0x0a, 0x55, 0x40, 0xa6, 0x36, 0xd5, 0x19, 0x25, + 0x2e, 0xe0, 0x5c, 0x9c, 0x02, 0x8b, 0x0e, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc2, + 0xd9, 0x80, 0xde, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xdf, 0xda, 0x08, + 0x71, 0xfa, 0x80, 0x50, 0x59, 0x97, 0x11, 0x70, 0x74, 0xdb, 0x6f, 0x7f, + 0x5a, 0xbb, 0xd4, 0x92, 0x59, 0xca, 0xa9, 0x88, 0x35, 0xec, 0x24, 0x87, + 0xbc, 0x9a, 0x8c, 0x0b, 0x1e, 0x12, 0x10, 0x62, 0xd4, 0xfa, 0xfd, 0xf9, + 0x56, 0x49, 0xa3, 0x0f, 0x82, 0x2b, 0x22, 0xf2, 0xb3, 0xc5, 0xe0, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xd9, 0x80, + 0xde, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xd2, 0x1b, 0xeb, 0x5b, 0xd4, + 0x4d, 0xec, 0xd2, 0x13, 0x88, 0xc9, 0x19, 0xfd, 0xd1, 0x1d, 0x0f, 0x01, + 0x4e, 0xcb, 0xcb, 0x23, 0xdc, 0xe2, 0x65, 0x29, 0x4a, 0x53, 0x72, 0xf4, + 0x86, 0x8b, 0x91, 0x12, 0x10, 0xa4, 0x28, 0x55, 0xf5, 0xdb, 0x3a, 0x7a, + 0x79, 0x15, 0x14, 0x36, 0xd4, 0xc0, 0x12, 0xa7, 0x7d, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xd9, 0x80, 0xde, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0x71, 0x74, 0xa1, 0xb0, 0x90, 0x81, 0xfb, + 0x38, 0x37, 0xee, 0x76, 0xd3, 0xce, 0xe4, 0xb1, 0xf5, 0xb6, 0xe3, 0xc0, + 0xa5, 0x33, 0xfc, 0x72, 0x6b, 0x7e, 0xb1, 0x70, 0x1e, 0xb5, 0xf6, 0x0a, + 0x3d, 0x12, 0x10, 0x4d, 0x54, 0x9a, 0x85, 0xf6, 0x1e, 0x39, 0x9a, 0x92, + 0x62, 0x07, 0x15, 0xb3, 0x16, 0x3c, 0xa3, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xd9, 0x80, 0xde, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x18, 0x5a, 0x83, 0xdf, 0x56, 0x5b, 0xb1, 0xec, 0x57, + 0x99, 0x21, 0xda, 0xf4, 0x20, 0xad, 0x46, 0x53, 0x81, 0x62, 0x10, 0x66, + 0x92, 0x03, 0xc4, 0x75, 0x10, 0x32, 0xa0, 0xe5, 0x21, 0x68, 0xe9, 0x12, + 0x10, 0x3d, 0xa9, 0x5c, 0xf8, 0xe2, 0x2b, 0x8a, 0xab, 0xfe, 0xff, 0x25, + 0xfe, 0x9a, 0xab, 0x8c, 0x3c, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x00, 0xc2, 0xd9, 0x80, 0xde, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0xe6, 0xb2, 0x40, 0x8d, 0xc9, 0x90, 0x6b, 0x96, 0xb0, 0x37, 0x87, + 0x53, 0x08, 0xef, 0xf3, 0x59, 0x06, 0x34, 0xf3, 0xb8, 0x48, 0x05, 0x19, + 0x26, 0x12, 0x73, 0x46, 0xd0, 0x88, 0xdf, 0xd4, 0x8d, 0x12, 0x10, 0xf0, + 0xcc, 0xf0, 0xd8, 0xf1, 0x62, 0xdb, 0x42, 0x49, 0xaf, 0x3e, 0x1b, 0xe1, + 0xbc, 0x8b, 0x64, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xf8, 0xe6, + 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenSoftTwoSoft_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x3f, 0x75, 0x72, 0xd7, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x3f, 0x75, 0x72, 0xd7, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0x78, 0xfa, 0xba, 0x9a, + 0xe7, 0x55, 0x4d, 0xe1, 0x0a, 0x20, 0x31, 0x41, 0x39, 0x42, 0x31, 0x38, + 0x38, 0x31, 0x44, 0x33, 0x32, 0x42, 0x35, 0x42, 0x42, 0x30, 0x32, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x64, + 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x01, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0x75, 0x72, 0xd7, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xd5, 0x47, + 0xa3, 0xf2, 0x91, 0x78, 0xa8, 0xbe, 0xd9, 0xc5, 0x1c, 0x28, 0xb3, 0xf7, + 0x65, 0x41, 0xd5, 0x27, 0x1d, 0x74, 0x40, 0x90, 0x33, 0xfb, 0x74, 0x16, + 0x2b, 0xf6, 0x18, 0xee, 0xee, 0x73, 0x12, 0x10, 0x2f, 0xd1, 0x4e, 0xd4, + 0x4f, 0x59, 0x12, 0xb4, 0x2e, 0xe4, 0x9b, 0xcb, 0xb3, 0x75, 0x70, 0xa7, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x75, + 0x72, 0xd7, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xda, 0x53, 0x3b, 0x6c, + 0x9d, 0xfc, 0xc0, 0x62, 0x64, 0x2e, 0x03, 0xc5, 0xbb, 0xdd, 0xd6, 0xcd, + 0x6c, 0x8e, 0x70, 0x47, 0x4b, 0xec, 0x57, 0x26, 0x43, 0x7b, 0x2c, 0x0c, + 0xda, 0xc5, 0x5b, 0x97, 0x12, 0x10, 0xc5, 0x52, 0xe5, 0x73, 0xac, 0x07, + 0x4f, 0xde, 0x8f, 0x73, 0x68, 0x69, 0x51, 0x00, 0x8a, 0x22, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x75, 0x72, 0xd7, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x1d, 0xd9, 0xbb, 0x09, 0xb1, 0xe3, + 0x5b, 0x85, 0xc9, 0x1a, 0xf6, 0x5f, 0xec, 0x5e, 0x7e, 0xd7, 0xa0, 0xfe, + 0x67, 0x64, 0x87, 0xb1, 0x7e, 0xfb, 0xb3, 0x6c, 0x4a, 0xb1, 0x46, 0x0d, + 0xa8, 0xcc, 0x12, 0x10, 0x1f, 0x9e, 0xea, 0x2a, 0xa7, 0x60, 0x20, 0xb9, + 0x4d, 0x38, 0xca, 0x67, 0x9f, 0x0f, 0xdf, 0x15, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x75, 0x72, 0xd7, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xc9, 0xb8, 0xc6, 0x06, 0x65, 0x33, 0x08, 0xaf, + 0xbf, 0x5a, 0xff, 0x77, 0xf8, 0x5f, 0xa2, 0xff, 0x8a, 0xaf, 0x81, 0x6f, + 0xb5, 0xf7, 0x9d, 0x2e, 0x9a, 0xda, 0x21, 0xf2, 0x30, 0x3c, 0xeb, 0xb5, + 0x12, 0x10, 0xa4, 0x30, 0x98, 0x92, 0xb2, 0x43, 0xe7, 0x37, 0xf4, 0xa2, + 0xd9, 0x50, 0x83, 0x9e, 0x63, 0x0e, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x75, 0x72, 0xd7, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x2e, 0x5b, 0x72, 0xa7, 0x41, 0xff, 0xd6, 0x5a, 0xe8, 0xe9, + 0x4d, 0x22, 0x25, 0x87, 0x50, 0xee, 0x95, 0xdc, 0xf9, 0x9b, 0x03, 0x83, + 0x1d, 0x9d, 0xb0, 0x55, 0xc0, 0xbd, 0x7a, 0x4c, 0x80, 0xd0, 0x12, 0x10, + 0x92, 0x62, 0x33, 0x68, 0x92, 0xd5, 0x1f, 0xda, 0x35, 0x84, 0xfa, 0x31, + 0x5f, 0xdb, 0x20, 0xae, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x90, + 0xe7, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_SevenSoftTwoSoft_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x68, 0xb3, 0xd7, 0x92, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x68, 0xb3, 0xd7, 0x92, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x31, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x1f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x57, 0x32, 0x24, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x53, 0x65, 0x76, 0x65, 0x6e, 0x53, 0x6f, 0x66, 0x74, 0x54, 0x77, 0x6f, + 0x53, 0x6f, 0x66, 0x74, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, + 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x43, 0x45, 0x43, + 0x46, 0x35, 0x43, 0x36, 0x44, 0x39, 0x30, 0x43, 0x32, 0x31, 0x38, 0x35, + 0x46, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, + 0x00, 0x20, 0x64, 0x28, 0x32, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, + 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x01, 0x1a, + 0x66, 0x20, 0x01, 0x1a, 0x50, 0x68, 0xfe, 0x0c, 0x61, 0x12, 0xd1, 0x77, + 0xe4, 0x1c, 0xaf, 0x5d, 0x97, 0x19, 0xcd, 0xb5, 0x6e, 0xe9, 0x22, 0xe4, + 0x23, 0x9a, 0xc5, 0x2a, 0x47, 0xc4, 0x16, 0x2c, 0x0d, 0x0c, 0x39, 0xad, + 0x96, 0xe5, 0x4b, 0x30, 0x9f, 0x62, 0xb8, 0xa4, 0x4b, 0x8c, 0x50, 0xb3, + 0x38, 0x9f, 0x2a, 0xbf, 0x3f, 0x0b, 0x30, 0xcc, 0x76, 0xbe, 0xd5, 0x7f, + 0x4e, 0x22, 0x94, 0x47, 0xc8, 0xab, 0xa6, 0x01, 0xb6, 0xae, 0xde, 0x0a, + 0xfc, 0x2a, 0xfc, 0x13, 0x47, 0x59, 0xc6, 0xbc, 0xa9, 0x9e, 0x98, 0x80, + 0xec, 0x12, 0x10, 0x60, 0x94, 0x62, 0x02, 0x71, 0xc9, 0x06, 0x51, 0xeb, + 0xce, 0x10, 0xc7, 0x6a, 0xe0, 0xbd, 0x2c, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x68, + 0xb3, 0xd7, 0x92, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x82, 0xe9, 0x8d, + 0xdf, 0xf0, 0x4b, 0x17, 0x83, 0x64, 0x16, 0xc6, 0xdf, 0xc6, 0xc9, 0xfc, + 0x9b, 0x3f, 0xff, 0xdf, 0x20, 0x0e, 0xea, 0xba, 0x23, 0x9d, 0x43, 0x81, + 0xbb, 0xbe, 0x70, 0x84, 0x27, 0x12, 0x10, 0xa7, 0x3d, 0x76, 0x35, 0x6f, + 0xf2, 0x4d, 0x92, 0xc8, 0x4a, 0x93, 0x98, 0x40, 0x0d, 0x4b, 0xb5, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x68, 0xb3, 0xd7, + 0x92, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x3c, 0x5b, 0x9b, 0x21, 0x54, + 0x98, 0xf2, 0x2e, 0x8e, 0xdb, 0xa2, 0x43, 0xaa, 0x8b, 0xe3, 0x19, 0xe7, + 0xa7, 0x04, 0xb0, 0x76, 0x48, 0x36, 0xad, 0x18, 0x32, 0x90, 0x83, 0x28, + 0x9a, 0x90, 0xd8, 0x12, 0x10, 0x75, 0xa5, 0xa5, 0xbb, 0x0c, 0xd5, 0xbc, + 0x6a, 0xb0, 0x38, 0xed, 0xc2, 0x08, 0x27, 0x54, 0xe3, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x68, 0xb3, 0xd7, 0x92, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0xca, 0x25, 0x06, 0xd4, 0x8a, 0xd0, 0xae, + 0xe7, 0x56, 0xa1, 0xe4, 0x2c, 0x08, 0xad, 0x30, 0xec, 0x2b, 0xb7, 0x33, + 0xff, 0x1b, 0x25, 0x6c, 0xa1, 0x9f, 0x00, 0xfd, 0xec, 0x77, 0x6b, 0xc8, + 0x1a, 0x12, 0x10, 0xa2, 0x24, 0x3f, 0x95, 0x36, 0x32, 0x2c, 0xf8, 0xeb, + 0xa2, 0x3b, 0x45, 0x33, 0x8c, 0x8b, 0xc5, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x68, 0xb3, 0xd7, 0x92, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x43, 0xbc, 0x0c, 0x2f, 0x5f, 0xae, 0x42, 0x3c, 0x9e, + 0xc3, 0x71, 0x55, 0x59, 0x47, 0xa2, 0x59, 0xb7, 0xf3, 0x2f, 0xe6, 0x05, + 0x2b, 0xb9, 0x4f, 0x11, 0x2e, 0x3e, 0x3f, 0x34, 0xda, 0x28, 0xa9, 0x12, + 0x10, 0xc6, 0xf0, 0x32, 0xd0, 0x8e, 0x0a, 0x5d, 0xc0, 0xfd, 0x34, 0x25, + 0xa2, 0xb0, 0x56, 0xfb, 0x17, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x00, 0x68, 0xb3, 0xd7, 0x92, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0xb7, 0xe3, 0xb9, 0x2b, 0x00, 0x73, 0xc1, 0x82, 0xba, 0xec, 0xb8, + 0xc3, 0x73, 0xa7, 0xbc, 0x00, 0x4a, 0x31, 0xab, 0x6b, 0x44, 0x62, 0xc9, + 0xd7, 0x95, 0x12, 0xb2, 0xd9, 0x68, 0xd3, 0xdb, 0x10, 0x12, 0x10, 0x2e, + 0xac, 0x1c, 0x95, 0x86, 0x02, 0x05, 0xec, 0xf5, 0xa1, 0xc6, 0x47, 0xd3, + 0x09, 0x17, 0x22, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xa8, 0xe7, + 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LicenseWithRenewal_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x96, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xfa, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x82, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x4e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xe6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x31, 0x28, 0x00, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x38, 0x39, 0x36, 0x37, 0x33, + 0x45, 0x32, 0x43, 0x31, 0x37, 0x46, 0x32, 0x41, 0x41, 0x44, 0x42, 0x32, + 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, + 0xb4, 0x01, 0x28, 0x00, 0x30, 0x00, 0x38, 0x0a, 0x42, 0x00, 0x48, 0x0f, + 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, 0x66, + 0x20, 0x01, 0x1a, 0x50, 0x6d, 0xef, 0xff, 0x94, 0x3d, 0xce, 0xf7, 0xeb, + 0x9e, 0x99, 0x37, 0x3e, 0x0a, 0x33, 0xf5, 0x5b, 0x22, 0xcf, 0xe0, 0x75, + 0xfc, 0xda, 0x96, 0xd5, 0x4e, 0x22, 0x6f, 0x0f, 0x59, 0x72, 0xad, 0x38, + 0xea, 0x32, 0x66, 0xa4, 0x36, 0x42, 0x70, 0x58, 0x1b, 0xa2, 0xb4, 0x77, + 0x9e, 0xe2, 0x5e, 0x97, 0xa4, 0x9d, 0xcf, 0xc5, 0x72, 0x61, 0xbe, 0xf9, + 0x43, 0xb9, 0x24, 0x68, 0x31, 0x38, 0x8d, 0x55, 0x17, 0xa0, 0x13, 0xce, + 0x41, 0xab, 0x8a, 0xdd, 0xf2, 0x0d, 0xd9, 0x61, 0x58, 0x03, 0x90, 0xea, + 0x12, 0x10, 0xa3, 0x5a, 0xbc, 0xca, 0x8a, 0x41, 0x40, 0xdb, 0x77, 0xbc, + 0x54, 0xb4, 0xe6, 0x0f, 0x6e, 0xd9, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x0c, 0x6a, + 0x70, 0xec, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xae, 0x95, 0x75, 0xaa, + 0xe8, 0x44, 0xd8, 0x7b, 0x50, 0xce, 0x53, 0x02, 0xb8, 0xc2, 0x72, 0xb9, + 0xd5, 0xc9, 0xb9, 0x1d, 0x51, 0x9d, 0xa9, 0x15, 0xc0, 0xf1, 0x20, 0xfc, + 0x74, 0xf5, 0xe8, 0x14, 0x12, 0x10, 0xda, 0x8b, 0x62, 0x3e, 0x69, 0x54, + 0x7e, 0xf0, 0x33, 0x20, 0x2d, 0xdd, 0x7c, 0x34, 0x27, 0x4f, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x0c, 0x6a, 0x70, 0xec, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xb5, 0x10, 0xbb, 0x3a, 0xf3, 0xad, + 0xf6, 0xe6, 0x7f, 0xfd, 0xa8, 0x92, 0x4d, 0x84, 0xe7, 0x91, 0x34, 0x39, + 0x19, 0x4e, 0x28, 0xc1, 0x49, 0x83, 0x9a, 0xe1, 0x5d, 0x8b, 0x70, 0x22, + 0x26, 0x4e, 0x12, 0x10, 0x69, 0x75, 0x1d, 0x55, 0x68, 0xa2, 0x75, 0x38, + 0x50, 0x4e, 0xa5, 0x43, 0x26, 0x91, 0x82, 0x43, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x0c, 0x6a, 0x70, 0xec, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x3c, 0xc9, 0x9b, 0x1f, 0x43, 0x19, 0x1a, 0x31, + 0xbb, 0x01, 0xde, 0x65, 0x6e, 0x85, 0xfe, 0x6f, 0x0c, 0x12, 0x93, 0x14, + 0xbb, 0x63, 0x53, 0x0b, 0xaa, 0x96, 0x9a, 0x91, 0xfc, 0x75, 0x13, 0xda, + 0x12, 0x10, 0xf2, 0x26, 0x92, 0x82, 0xbe, 0x77, 0xc9, 0x64, 0x52, 0x7a, + 0x04, 0x90, 0xbb, 0xb3, 0x53, 0xb5, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x19, 0x0c, 0x6a, 0x70, 0xec, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x30, 0x45, 0xd5, 0xb3, 0x99, 0x59, 0x4f, 0xab, 0x1f, 0xa5, + 0xa6, 0x8e, 0xab, 0x64, 0x55, 0x87, 0x58, 0xbe, 0xc6, 0x2b, 0x0d, 0xc7, + 0x40, 0xaf, 0xc9, 0x77, 0xb8, 0x3f, 0x79, 0x74, 0x96, 0x5c, 0x12, 0x10, + 0x8c, 0x53, 0xb4, 0x34, 0x31, 0x45, 0x3d, 0x82, 0x8c, 0xf3, 0x32, 0xc0, + 0xe2, 0xad, 0x1a, 0xff, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x19, 0x0c, 0x6a, 0x70, 0xec, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x2f, 0x3e, 0xc1, 0x5d, 0x94, 0xe6, 0x4b, 0xbe, 0x57, 0xc6, 0xb6, 0xa6, + 0xbd, 0x6a, 0x78, 0x94, 0xb8, 0x94, 0xe3, 0x7f, 0x8b, 0x23, 0x46, 0xb0, + 0x3b, 0x28, 0x10, 0xb5, 0x64, 0x1c, 0x1b, 0x6c, 0x12, 0x10, 0x94, 0x09, + 0xfb, 0x98, 0x64, 0x06, 0x1a, 0xdf, 0xcd, 0x72, 0xae, 0x2c, 0xbd, 0x44, + 0x82, 0x6f, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xc0, 0xe7, 0x92, + 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LicenseWithRenewal_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x90, 0x7f, 0xd2, 0x4a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x90, 0x7f, 0xd2, 0x4a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0xd2, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbe, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x34, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x22, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xaa, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x76, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x59, 0x32, 0x26, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, + 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x43, + 0x41, 0x35, 0x45, 0x46, 0x41, 0x31, 0x44, 0x35, 0x33, 0x37, 0x41, 0x41, + 0x46, 0x34, 0x44, 0x32, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, + 0x01, 0x18, 0x01, 0x20, 0xb4, 0x01, 0x28, 0x00, 0x30, 0x00, 0x38, 0x0a, + 0x42, 0x00, 0x48, 0x0f, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, + 0x78, 0x00, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0xf7, 0x41, 0x5c, 0x07, + 0x70, 0xa9, 0xae, 0xff, 0x5f, 0x94, 0xcb, 0x02, 0xc1, 0xf5, 0xb9, 0x28, + 0xbd, 0x85, 0x9f, 0x70, 0x31, 0xfb, 0xa7, 0x83, 0x2f, 0x98, 0xda, 0x3d, + 0xba, 0x56, 0xfe, 0xcb, 0x91, 0x5b, 0x10, 0x8e, 0xdc, 0x54, 0xb0, 0x57, + 0xee, 0x43, 0x13, 0xbf, 0xab, 0x36, 0xc0, 0x71, 0xe3, 0x3b, 0xc3, 0x53, + 0xe3, 0xfa, 0xab, 0xef, 0x9e, 0xd8, 0xf8, 0xc0, 0x06, 0xdd, 0x5d, 0x0f, + 0x18, 0xc3, 0x42, 0x6b, 0xc0, 0x38, 0x5c, 0x9a, 0x33, 0xd6, 0xc6, 0x10, + 0x64, 0xc3, 0x9b, 0x18, 0x12, 0x10, 0x5f, 0xf3, 0x4b, 0x13, 0xef, 0xda, + 0x3c, 0xa0, 0x33, 0xf1, 0x84, 0xfa, 0x0e, 0x84, 0xeb, 0x6d, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x19, 0x90, 0x7f, 0xd2, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0xf1, 0x1f, 0x0e, 0x77, 0xdc, 0x5e, 0xcf, 0x90, 0xb9, 0x0c, 0x83, 0x24, + 0x3a, 0x45, 0x30, 0xa0, 0x6f, 0x28, 0xd6, 0x5d, 0x8e, 0x7d, 0xa2, 0xdf, + 0x06, 0x11, 0x01, 0x03, 0x29, 0x8d, 0x71, 0x27, 0x12, 0x10, 0x1b, 0x6e, + 0x88, 0xf0, 0xed, 0xe5, 0x26, 0xc4, 0x0a, 0xa9, 0x58, 0xa4, 0x19, 0xa5, + 0x63, 0x4d, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, + 0x90, 0x7f, 0xd2, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x8c, 0xb3, + 0x69, 0x30, 0x19, 0x30, 0x96, 0xdf, 0x98, 0xab, 0xd3, 0xf2, 0x75, 0xbd, + 0xd4, 0x6d, 0x3d, 0xf2, 0x31, 0x13, 0x4e, 0xd5, 0xbd, 0xb1, 0xac, 0xf3, + 0xc2, 0xd5, 0x82, 0x52, 0xfd, 0xbe, 0x12, 0x10, 0x94, 0x67, 0x49, 0x7f, + 0x6e, 0xd8, 0x51, 0x96, 0x70, 0xb1, 0x88, 0xb0, 0x74, 0xe8, 0xa4, 0xbc, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x90, 0x7f, + 0xd2, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x27, 0x6a, 0x20, 0x08, + 0x26, 0x8a, 0xed, 0xad, 0xf9, 0x2b, 0xae, 0xd7, 0x29, 0x78, 0x65, 0x01, + 0x91, 0xd8, 0x53, 0x69, 0xc7, 0x6d, 0x2b, 0xaa, 0xaa, 0xc7, 0xc7, 0x04, + 0xbf, 0x82, 0x5e, 0xda, 0x12, 0x10, 0xd2, 0x27, 0xe2, 0x0f, 0x36, 0x36, + 0x95, 0x91, 0x6e, 0xd9, 0x51, 0x7d, 0xf2, 0xb4, 0x01, 0xb6, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x90, 0x7f, 0xd2, 0x4a, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x18, 0x7a, 0x0b, 0x3f, 0x15, 0x41, + 0x9b, 0x06, 0xa8, 0xca, 0x83, 0x02, 0x62, 0x1e, 0x95, 0x25, 0x65, 0x40, + 0xe7, 0xca, 0x19, 0x70, 0x52, 0x89, 0xfc, 0xdf, 0x98, 0x50, 0xd8, 0x7b, + 0x71, 0x68, 0x12, 0x10, 0x37, 0xdd, 0xd1, 0xc1, 0xc9, 0x60, 0xb8, 0xe5, + 0xcc, 0x07, 0xc7, 0x2c, 0xeb, 0x0d, 0xe5, 0x89, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x90, 0x7f, 0xd2, 0x4a, 0xa0, 0x00, + 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xbd, 0xb0, 0xbe, 0x82, 0x4f, 0x3f, 0x05, 0x65, + 0x48, 0xee, 0x9a, 0x2c, 0xa3, 0x9d, 0xe0, 0x9a, 0x69, 0xb7, 0x3f, 0xe1, + 0x1a, 0xc9, 0xfe, 0x3c, 0x6f, 0xd5, 0x2b, 0x17, 0x54, 0xcb, 0xd2, 0x94, + 0x12, 0x10, 0x77, 0x0e, 0x54, 0x27, 0x4b, 0xd6, 0x20, 0x17, 0xb2, 0xae, + 0xe7, 0x1e, 0x03, 0xcc, 0xea, 0x55, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, + 0x20, 0xb3, 0xe8, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, + Both_CdmUseCase_LicenseWithRenewalPlayback_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x05, 0xd3, 0xe8, 0xe8, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x05, 0xd3, 0xe8, 0xe8, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x96, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xfa, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x82, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x4e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xe6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x31, 0x28, 0x00, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x34, 0x42, 0x44, 0x43, 0x35, + 0x37, 0x34, 0x39, 0x37, 0x34, 0x45, 0x39, 0x36, 0x31, 0x35, 0x36, 0x32, + 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, + 0x00, 0x28, 0xb4, 0x01, 0x30, 0x00, 0x38, 0x0a, 0x42, 0x00, 0x48, 0x0f, + 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, 0x66, + 0x20, 0x01, 0x1a, 0x50, 0xfd, 0x36, 0xa7, 0x75, 0xab, 0xd5, 0x44, 0xf4, + 0x09, 0xfc, 0x08, 0x7a, 0xe6, 0xf9, 0xcc, 0x03, 0x13, 0x3d, 0xf2, 0x04, + 0x45, 0xb5, 0xbe, 0xac, 0x94, 0x6c, 0xcb, 0x53, 0xe4, 0x12, 0xf7, 0x14, + 0xb9, 0x88, 0x31, 0x94, 0x9b, 0x28, 0xc8, 0xe9, 0x37, 0x42, 0xe0, 0x55, + 0x45, 0xc0, 0x44, 0x7f, 0x7f, 0x4d, 0x84, 0x62, 0xbf, 0x0a, 0x5b, 0x1b, + 0x6c, 0x99, 0xb3, 0x21, 0x7d, 0x85, 0x75, 0x15, 0x65, 0x76, 0x86, 0x7c, + 0x54, 0xca, 0x3a, 0xdd, 0x80, 0xaa, 0x68, 0x12, 0xc5, 0x32, 0x93, 0xcd, + 0x12, 0x10, 0xcd, 0xf6, 0xfc, 0xfa, 0x31, 0x8f, 0x67, 0x91, 0x14, 0xc2, + 0x98, 0x67, 0x35, 0xa2, 0x20, 0xa0, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x05, 0xd3, + 0xe8, 0xe8, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x72, 0xab, 0xf2, 0xf4, + 0xe0, 0x16, 0x30, 0x3a, 0xbf, 0x03, 0x3d, 0xa6, 0x3a, 0x88, 0x63, 0xc9, + 0xef, 0xda, 0x15, 0xc3, 0xdc, 0x45, 0x30, 0xde, 0x54, 0x56, 0x26, 0x08, + 0xde, 0xaa, 0x4b, 0xbd, 0x12, 0x10, 0x32, 0x3d, 0x48, 0x43, 0xc2, 0xcc, + 0x9c, 0x7c, 0x31, 0x20, 0xe4, 0xb8, 0xc1, 0xb7, 0x08, 0xbc, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x05, 0xd3, 0xe8, 0xe8, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x50, 0xa5, 0x46, 0xbd, 0xe0, 0xdb, + 0x52, 0x81, 0xa6, 0xb9, 0xb9, 0x32, 0x54, 0xe9, 0x65, 0x0c, 0x4d, 0x2e, + 0xbf, 0x2a, 0xe8, 0x13, 0x15, 0xa6, 0x3e, 0x30, 0xa1, 0x59, 0xd8, 0x5c, + 0x88, 0xff, 0x12, 0x10, 0x87, 0x57, 0x61, 0x95, 0xff, 0xc5, 0xff, 0x42, + 0xd8, 0xe8, 0xb9, 0xe8, 0x14, 0x06, 0x39, 0x59, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x05, 0xd3, 0xe8, 0xe8, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x5a, 0x85, 0xa7, 0x6a, 0x4f, 0x56, 0x2f, 0x89, + 0x46, 0x29, 0x24, 0xfd, 0x7b, 0xc1, 0x2c, 0xe8, 0x31, 0x5b, 0x41, 0xbd, + 0x07, 0x9e, 0x88, 0xf2, 0xfc, 0x5f, 0x5a, 0x88, 0x77, 0x0c, 0x3e, 0x05, + 0x12, 0x10, 0x3a, 0x22, 0x79, 0x11, 0xea, 0x97, 0x0f, 0xdf, 0xa0, 0x78, + 0x0c, 0x44, 0x7b, 0xf7, 0x98, 0x5d, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x19, 0x05, 0xd3, 0xe8, 0xe8, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x5f, 0x19, 0x3f, 0x95, 0x73, 0x12, 0x95, 0x31, 0x9f, 0x26, + 0x1b, 0x99, 0xac, 0x2f, 0x8c, 0xff, 0xba, 0x41, 0x61, 0xf7, 0x8a, 0xab, + 0xa6, 0x98, 0x57, 0xd8, 0x3a, 0xeb, 0x70, 0x5e, 0xfc, 0x98, 0x12, 0x10, + 0x31, 0x1b, 0x09, 0x47, 0xed, 0xd5, 0x43, 0x16, 0x7c, 0x83, 0x00, 0xa4, + 0x08, 0xfc, 0xa4, 0xd3, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x19, 0x05, 0xd3, 0xe8, 0xe8, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x23, 0x66, 0x4c, 0x9c, 0xf2, 0x01, 0xa2, 0xd3, 0xaf, 0x57, 0x78, 0x4c, + 0xee, 0x31, 0xf8, 0x6a, 0xd9, 0xf8, 0x73, 0x97, 0xda, 0x61, 0xa0, 0x50, + 0xa0, 0x8d, 0xca, 0x51, 0xc2, 0x95, 0x98, 0xcd, 0x12, 0x10, 0x1e, 0xe5, + 0x64, 0x2c, 0xf0, 0x43, 0x34, 0x46, 0xe4, 0x03, 0x88, 0x3b, 0xca, 0xcb, + 0x62, 0x20, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xa6, 0xe9, 0x92, + 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, + Both_CdmUseCase_LicenseWithRenewalPlayback_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x61, 0xa5, 0xde, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x61, 0xa5, 0xde, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0xdb, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x1d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xc7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xb5, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x93, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x3d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x2b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x09, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xb3, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xa1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x7f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x29, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x17, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xf5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x62, 0x32, 0x2f, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, + 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x62, + 0x61, 0x63, 0x6b, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x34, 0x46, 0x30, 0x35, + 0x42, 0x30, 0x42, 0x31, 0x32, 0x42, 0x32, 0x33, 0x39, 0x32, 0x33, 0x37, + 0x32, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x12, 0x1d, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, + 0x20, 0x00, 0x28, 0xb4, 0x01, 0x30, 0x00, 0x38, 0x0a, 0x42, 0x00, 0x48, + 0x0f, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, + 0x66, 0x20, 0x01, 0x1a, 0x50, 0xfe, 0xf1, 0xfc, 0xf9, 0x6a, 0xbe, 0xbe, + 0xd2, 0xc4, 0x28, 0x0b, 0x35, 0x5b, 0x2b, 0x52, 0xe4, 0x9f, 0x24, 0x8a, + 0xd9, 0x02, 0xd1, 0x6f, 0xc3, 0xa6, 0x48, 0x94, 0x5d, 0x87, 0x57, 0xbc, + 0x48, 0x86, 0xf4, 0x16, 0xa7, 0xee, 0xd9, 0x2e, 0x1c, 0xb8, 0xb8, 0x15, + 0xc9, 0xdf, 0x13, 0x19, 0x13, 0x48, 0xb0, 0x03, 0xdc, 0xc4, 0xc9, 0x45, + 0x45, 0xbb, 0x0d, 0x87, 0xda, 0xa8, 0x23, 0x40, 0xcc, 0x49, 0x14, 0x44, + 0xd7, 0x7a, 0x98, 0x73, 0x10, 0x37, 0x9e, 0x1c, 0xeb, 0x3d, 0x06, 0x89, + 0x65, 0x12, 0x10, 0x55, 0x50, 0x69, 0xf5, 0x3a, 0xd9, 0xc6, 0x7e, 0xbf, + 0xe7, 0x16, 0xea, 0x62, 0xf0, 0x44, 0x93, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x61, + 0xa5, 0xde, 0x06, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x60, 0xb6, 0x80, + 0xd1, 0xc8, 0x62, 0x11, 0x9e, 0x57, 0x94, 0xf0, 0xb1, 0xd5, 0x48, 0x2f, + 0xe6, 0x9f, 0xaf, 0xb4, 0x12, 0xb7, 0xd9, 0x66, 0x4e, 0x7d, 0x61, 0xb4, + 0x3c, 0x76, 0xf7, 0x7e, 0x6e, 0x12, 0x10, 0x7c, 0xda, 0x3f, 0xef, 0x08, + 0xf1, 0xd7, 0x70, 0x28, 0x2f, 0x23, 0x09, 0xa4, 0x60, 0xc6, 0x75, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x61, 0xa5, 0xde, + 0x06, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x39, 0x7e, 0x04, 0xe1, 0xd6, + 0x52, 0xd0, 0x4a, 0x3b, 0x49, 0x43, 0xc6, 0xbf, 0x70, 0x8b, 0xed, 0xb5, + 0x94, 0x79, 0x67, 0xa0, 0x49, 0x35, 0x6c, 0x5e, 0xe3, 0x77, 0x49, 0xde, + 0xd2, 0x3e, 0xdd, 0x12, 0x10, 0x52, 0xad, 0xc6, 0x5e, 0x20, 0x9e, 0x12, + 0xbd, 0x3d, 0x6f, 0x7e, 0xba, 0x24, 0x6f, 0x4e, 0x72, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x19, 0x61, 0xa5, 0xde, 0x06, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0xd2, 0x45, 0x8b, 0x97, 0x7b, 0xcd, 0xac, + 0x67, 0x11, 0x8f, 0x78, 0xca, 0xdf, 0x77, 0xbb, 0x42, 0x90, 0xb1, 0x56, + 0x14, 0xda, 0x61, 0xc0, 0x30, 0x3c, 0x05, 0xc5, 0xb0, 0xbb, 0xd3, 0x8f, + 0x2e, 0x12, 0x10, 0x6a, 0x03, 0x4c, 0x60, 0x44, 0x47, 0xfb, 0x23, 0xb2, + 0xf2, 0xae, 0x28, 0xb9, 0x11, 0x68, 0xd5, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x19, 0x61, 0xa5, 0xde, 0x06, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x00, 0xdb, 0x10, 0x5b, 0x15, 0x6e, 0x51, 0xca, 0x1e, + 0xb6, 0x2e, 0x33, 0x19, 0x79, 0x14, 0xa8, 0xf8, 0x34, 0xbb, 0x59, 0x03, + 0x41, 0x56, 0x43, 0xcb, 0x84, 0xf3, 0x39, 0x7d, 0x1c, 0xb8, 0x5c, 0x12, + 0x10, 0x93, 0x65, 0x95, 0xd4, 0x54, 0x19, 0x8c, 0xcd, 0xe4, 0x66, 0x16, + 0x10, 0xd3, 0xb8, 0x09, 0xe4, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x19, 0x61, 0xa5, 0xde, 0x06, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0x13, 0xb8, 0x60, 0xc7, 0xcd, 0x84, 0xd0, 0x1e, 0x23, 0x05, 0x9c, + 0xb6, 0xdc, 0x69, 0x30, 0x6f, 0xd9, 0x34, 0xa0, 0xa5, 0x09, 0xc5, 0x69, + 0x7a, 0xf5, 0x8d, 0x81, 0xc9, 0x93, 0xe0, 0xb9, 0x4a, 0x12, 0x10, 0x01, + 0x98, 0xc8, 0xf7, 0xfc, 0x66, 0xb4, 0xf3, 0xc0, 0x3e, 0xa7, 0x29, 0x88, + 0x48, 0x0f, 0xf9, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x99, 0xea, + 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LimitedDurationLicense_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x1d, 0x71, 0xab, 0x3b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x1d, 0x71, 0xab, 0x3b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xa9, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x1f, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xeb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x83, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xf9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xd7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x6f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0xf7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xc3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x31, 0x28, 0x00, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x42, 0x44, 0x46, 0x30, 0x45, + 0x34, 0x42, 0x39, 0x30, 0x34, 0x32, 0x41, 0x42, 0x38, 0x30, 0x41, 0x32, + 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, + 0x0f, 0x28, 0x3c, 0x30, 0x00, 0x38, 0x0f, 0x42, 0x00, 0x48, 0x05, 0x50, + 0x00, 0x58, 0x01, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x66, 0x20, + 0x01, 0x1a, 0x50, 0xa1, 0x7b, 0x9a, 0x06, 0x24, 0x4e, 0x5e, 0x63, 0x05, + 0xab, 0x1e, 0xf8, 0xd2, 0x18, 0xe3, 0x0a, 0xec, 0xe5, 0xef, 0xb2, 0x3a, + 0xe8, 0x1a, 0x1a, 0x8f, 0xe9, 0x2a, 0x17, 0x2c, 0x32, 0xdb, 0x59, 0xca, + 0xa9, 0x05, 0x23, 0x20, 0x9c, 0xa1, 0x5b, 0xa3, 0x72, 0xed, 0x04, 0xde, + 0xd5, 0x17, 0xd4, 0x78, 0x52, 0x73, 0x1e, 0x7d, 0x42, 0xcb, 0x62, 0x6d, + 0xa4, 0x99, 0xc0, 0x66, 0x71, 0x87, 0x2a, 0xed, 0xfc, 0x4e, 0xff, 0x15, + 0x23, 0x13, 0x98, 0xaa, 0x29, 0x20, 0x54, 0x44, 0x9e, 0xbb, 0x34, 0x12, + 0x10, 0x83, 0xa9, 0x0f, 0x5c, 0xb9, 0x63, 0x19, 0x2c, 0x21, 0xdf, 0xb2, + 0x7f, 0x43, 0xa8, 0x5d, 0xbb, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0x1d, 0x71, 0xab, + 0x3b, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x2d, 0x6e, 0x41, 0xea, 0x05, + 0xc4, 0xd5, 0xea, 0x7e, 0xa3, 0xb6, 0x29, 0x0f, 0x27, 0x21, 0x31, 0xae, + 0xbc, 0x7f, 0x48, 0x71, 0xd2, 0xce, 0xc6, 0xc3, 0xe0, 0x1a, 0xb0, 0xdf, + 0x13, 0xa0, 0x3d, 0x12, 0x10, 0x7b, 0x87, 0x16, 0x1e, 0x9c, 0xcd, 0x51, + 0xae, 0x23, 0x96, 0x7a, 0x8b, 0x7e, 0xe5, 0xe6, 0x60, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0x1d, 0x71, 0xab, 0x3b, 0xa0, + 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0xc5, 0x78, 0x21, 0x56, 0xe3, 0xd4, 0xcb, + 0x40, 0x6d, 0xc0, 0xc9, 0x90, 0xae, 0xe2, 0x8a, 0x58, 0x6f, 0x21, 0x68, + 0x7e, 0x5d, 0x1b, 0xed, 0x03, 0xd2, 0xb7, 0xb9, 0x5b, 0x26, 0x6d, 0xbc, + 0x3e, 0x12, 0x10, 0x97, 0x67, 0x9f, 0x8a, 0x5d, 0xf5, 0xe6, 0x3c, 0xdc, + 0x6c, 0xf0, 0xac, 0x86, 0xfc, 0xeb, 0x20, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x14, 0x1d, 0x71, 0xab, 0x3b, 0xa0, 0x00, 0x00, + 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x27, 0x7b, 0x6a, 0x8e, 0xdc, 0xee, 0xbf, 0x5e, 0x9a, + 0x34, 0x96, 0xbf, 0x85, 0xc0, 0x50, 0xce, 0x0f, 0x3a, 0xf7, 0x5b, 0xc1, + 0x02, 0xc5, 0x18, 0xcd, 0xc3, 0xe0, 0x3d, 0x66, 0x80, 0x88, 0xe7, 0x12, + 0x10, 0x4f, 0xa4, 0xe2, 0x7c, 0x38, 0x76, 0xa6, 0x2f, 0xe9, 0xd0, 0x04, + 0x02, 0x51, 0x25, 0x52, 0xfd, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x14, 0x1d, 0x71, 0xab, 0x3b, 0xa0, 0x00, 0x00, 0x08, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0x4b, 0x4e, 0xdc, 0x72, 0xb5, 0x45, 0x2c, 0x8b, 0x2d, 0xf8, 0x10, + 0x28, 0x2d, 0xef, 0x43, 0xf9, 0x81, 0x37, 0xb4, 0x05, 0x3a, 0x83, 0x0b, + 0x2d, 0xa6, 0x9c, 0x8d, 0x80, 0x05, 0x37, 0xa3, 0x6f, 0x12, 0x10, 0x15, + 0x45, 0x60, 0xaf, 0xb9, 0x42, 0x5d, 0xd5, 0xb2, 0x64, 0x76, 0x26, 0x24, + 0xdb, 0x06, 0x59, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, + 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, + 0x14, 0x1d, 0x71, 0xab, 0x3b, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xbd, + 0x16, 0x1e, 0x17, 0x8b, 0x0c, 0xb9, 0x59, 0x10, 0x63, 0x5b, 0xcb, 0x40, + 0x98, 0xba, 0xe4, 0x98, 0xce, 0x1f, 0xd4, 0x7c, 0x13, 0x87, 0x43, 0x05, + 0x07, 0xf8, 0xf4, 0xa8, 0x9a, 0x3f, 0xa6, 0x12, 0x10, 0x34, 0xa4, 0x3b, + 0x05, 0x69, 0x18, 0x16, 0x22, 0x4f, 0x05, 0xbc, 0xc8, 0x4e, 0x18, 0x43, + 0xe1, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x8c, 0xeb, 0x92, 0xa2, + 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LimitedDurationLicense_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xd4, 0x57, 0xcc, 0x27, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xd4, 0x57, 0xcc, 0x27, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0xd5, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x4b, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x39, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x17, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x8d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x37, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x25, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xad, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x79, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xef, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x5d, 0x32, 0x2a, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x63, + 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, + 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x0a, 0x20, 0x39, 0x35, 0x31, 0x38, 0x34, 0x35, 0x33, 0x39, 0x36, + 0x34, 0x31, 0x31, 0x46, 0x31, 0x45, 0x38, 0x32, 0x45, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, + 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x0f, 0x28, 0x3c, 0x30, + 0x00, 0x38, 0x0f, 0x42, 0x00, 0x48, 0x05, 0x50, 0x00, 0x58, 0x01, 0x60, + 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0xdc, + 0x72, 0x77, 0xc9, 0x58, 0xc5, 0xf9, 0x02, 0x40, 0xec, 0xe6, 0x7a, 0x7a, + 0x1c, 0xef, 0x40, 0x6a, 0x5c, 0x05, 0xf9, 0xa7, 0x64, 0x0e, 0xa2, 0xa4, + 0x3c, 0xab, 0x16, 0xbe, 0xd0, 0x0a, 0xf2, 0x93, 0x23, 0x76, 0x6e, 0xe5, + 0xe3, 0x29, 0x2a, 0x9e, 0x90, 0x52, 0x63, 0xcf, 0x80, 0x05, 0x91, 0x9f, + 0x04, 0x99, 0x26, 0x59, 0x77, 0x17, 0xba, 0x6e, 0xec, 0x49, 0x76, 0xa7, + 0xe8, 0xea, 0x7d, 0x25, 0x20, 0xbc, 0xcb, 0x8b, 0x2e, 0xdb, 0x42, 0x18, + 0x61, 0xc6, 0xb4, 0x79, 0x56, 0xcd, 0x36, 0x12, 0x10, 0x0b, 0x0c, 0xca, + 0xf6, 0x53, 0x4c, 0x0d, 0xf7, 0xde, 0x66, 0x75, 0x6c, 0xa3, 0xb1, 0xc5, + 0x34, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x14, 0xd4, 0x57, 0xcc, 0x27, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x9b, 0xcc, 0xa8, 0xe2, 0x9e, 0x5e, 0x24, 0xfb, 0x66, + 0x5e, 0xd5, 0xc1, 0x75, 0x9a, 0xf9, 0x6b, 0x64, 0x1f, 0xed, 0xdf, 0x9b, + 0x09, 0x73, 0x0c, 0xfa, 0xbe, 0x21, 0xf2, 0x37, 0x85, 0x59, 0x87, 0x12, + 0x10, 0x99, 0xaa, 0xfb, 0x08, 0xc6, 0x23, 0x58, 0x1a, 0xf1, 0x98, 0x30, + 0x0f, 0x72, 0xae, 0x1b, 0xe6, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x14, 0xd4, 0x57, 0xcc, 0x27, 0xa0, 0x00, 0x40, 0x00, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0x52, 0x2c, 0x88, 0xf6, 0x1f, 0xe8, 0xa7, 0xf2, 0x79, 0x21, 0x49, + 0x55, 0x55, 0x17, 0x27, 0x30, 0x51, 0x3c, 0x4d, 0xe5, 0xe7, 0x48, 0x19, + 0xc8, 0xa0, 0x2a, 0x2c, 0xec, 0xff, 0xc6, 0x8f, 0x7d, 0x12, 0x10, 0xae, + 0xfc, 0x48, 0x7c, 0x84, 0xbf, 0x33, 0xc8, 0xe2, 0xc0, 0x0e, 0x2e, 0x38, + 0x3d, 0x4a, 0xb7, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, + 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, + 0x14, 0xd4, 0x57, 0xcc, 0x27, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x54, + 0xd9, 0x6b, 0x58, 0x99, 0xb5, 0x8c, 0x59, 0x8a, 0xd3, 0xbc, 0x6c, 0x1c, + 0x50, 0xbd, 0xea, 0x5e, 0xa5, 0xc7, 0x8f, 0x38, 0x75, 0xfb, 0x3d, 0x78, + 0x63, 0x51, 0x4e, 0xf2, 0x7c, 0x04, 0xe3, 0x12, 0x10, 0x15, 0x04, 0xe4, + 0xce, 0x52, 0x63, 0x7c, 0x45, 0x91, 0xcd, 0xdf, 0xa2, 0xbf, 0x19, 0xd3, + 0xe5, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0xd4, + 0x57, 0xcc, 0x27, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x9e, 0xe9, 0xba, + 0x83, 0x56, 0xea, 0x25, 0x0a, 0xb3, 0xe8, 0xe1, 0x19, 0x7e, 0xa6, 0x02, + 0xaa, 0x97, 0x19, 0xfa, 0x79, 0xfc, 0x0f, 0x12, 0x16, 0xbb, 0xab, 0x89, + 0xfd, 0x73, 0x55, 0xcf, 0x78, 0x12, 0x10, 0xb9, 0xa3, 0x65, 0xe7, 0x0d, + 0x41, 0xd8, 0xb5, 0xf6, 0xde, 0xfc, 0x66, 0xe2, 0x38, 0xb6, 0x77, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0xd4, 0x57, 0xcc, + 0x27, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x3a, 0x7c, 0x35, 0x84, 0x7b, + 0x89, 0x05, 0xf2, 0x07, 0xfd, 0xe6, 0x2d, 0xfa, 0x47, 0x9e, 0xa0, 0x65, + 0x06, 0xa8, 0x0f, 0xe7, 0x9c, 0x02, 0x4a, 0x58, 0x3a, 0xb6, 0x4c, 0x61, + 0xf2, 0xc6, 0xd1, 0x12, 0x10, 0x13, 0x44, 0x08, 0xf4, 0xf9, 0x4d, 0x99, + 0x18, 0x65, 0xff, 0x40, 0x95, 0xb8, 0xa1, 0x66, 0x0b, 0x0a, 0x10, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, + 0x3d, 0x3d, 0x3d, 0x20, 0xad, 0xeb, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_RenewOnLicenseLoad_Case1S_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xfe, 0xe4, 0xb3, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xfe, 0xe4, 0xb3, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xfc, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xda, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x84, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x72, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0xfa, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xc6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x31, 0x28, 0x00, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x43, 0x44, 0x43, 0x32, 0x45, + 0x35, 0x39, 0x32, 0x32, 0x34, 0x43, 0x46, 0x45, 0x37, 0x32, 0x44, 0x33, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1f, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, + 0x14, 0x28, 0x32, 0x30, 0x00, 0x38, 0x0f, 0x42, 0x00, 0x48, 0x05, 0x50, + 0x00, 0x58, 0x01, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x90, 0x01, 0x02, + 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0x64, 0xbf, 0xd5, 0x47, 0x73, 0x1a, + 0xca, 0xe6, 0x4e, 0xc8, 0x27, 0x4a, 0x85, 0xfd, 0x10, 0xb5, 0xbf, 0xf2, + 0x89, 0x7d, 0x67, 0x4c, 0xfd, 0x83, 0x2b, 0xe9, 0x9e, 0x5f, 0xf7, 0x2d, + 0xf9, 0x84, 0xd9, 0xb2, 0xa8, 0xc7, 0xdf, 0x4c, 0x53, 0xdd, 0x92, 0x96, + 0x90, 0xee, 0x80, 0xbf, 0x5b, 0xf0, 0x01, 0x87, 0x92, 0x47, 0x6e, 0x1e, + 0x0e, 0xa5, 0xf7, 0x3e, 0x5b, 0x23, 0x6d, 0x51, 0x0b, 0x95, 0xd7, 0x88, + 0xa5, 0x18, 0xa1, 0x0e, 0x27, 0xbf, 0xa3, 0xc1, 0xd1, 0xfe, 0xa8, 0xbe, + 0x5f, 0x63, 0x12, 0x10, 0xb0, 0xe8, 0x54, 0x73, 0x75, 0x49, 0xe4, 0x1b, + 0x57, 0xc4, 0xbe, 0x7b, 0x70, 0xb4, 0x1f, 0xc6, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, + 0xfe, 0xe4, 0xb3, 0x02, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xf6, 0x29, + 0x8e, 0x12, 0x81, 0xcb, 0x6e, 0x10, 0x67, 0xc9, 0xdc, 0xf5, 0xce, 0x65, + 0x39, 0x97, 0x68, 0xe1, 0x14, 0x7c, 0x0f, 0xc7, 0x70, 0x77, 0x3d, 0x77, + 0xbc, 0x1e, 0x55, 0x0f, 0x8b, 0x30, 0x12, 0x10, 0xd0, 0x30, 0xbc, 0xbf, + 0xca, 0x72, 0xf3, 0x33, 0x6f, 0xeb, 0x65, 0x5b, 0x4f, 0x29, 0xe3, 0x79, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0xfe, 0xe4, + 0xb3, 0x02, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xe5, 0xfc, 0x1c, 0x6e, + 0xd6, 0x40, 0x9d, 0x92, 0xf6, 0xc2, 0x5a, 0x3f, 0x8d, 0x02, 0x90, 0x29, + 0x8b, 0x52, 0x7b, 0xf0, 0xb4, 0x26, 0xb9, 0x57, 0x18, 0x7c, 0x91, 0x29, + 0xa4, 0xbf, 0x0e, 0xe0, 0x12, 0x10, 0xc5, 0x44, 0x84, 0xf2, 0x91, 0x41, + 0xb9, 0xd5, 0xf7, 0x33, 0x99, 0x3a, 0x2c, 0x01, 0x97, 0x51, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0xfe, 0xe4, 0xb3, 0x02, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x7c, 0x02, 0x54, 0xf1, 0x58, 0xa4, + 0x87, 0x4b, 0x5b, 0x5b, 0x4c, 0x7d, 0x2a, 0x37, 0xcd, 0x56, 0x75, 0x28, + 0x22, 0x1f, 0x46, 0x8e, 0xb2, 0x78, 0x74, 0x85, 0x77, 0x9a, 0x80, 0x57, + 0xd8, 0xa0, 0x12, 0x10, 0x56, 0x88, 0x6b, 0xe9, 0x49, 0xf1, 0x60, 0xb2, + 0x41, 0xa4, 0x93, 0x08, 0x39, 0x47, 0xdc, 0xea, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0xfe, 0xe4, 0xb3, 0x02, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xb4, 0x8c, 0x7f, 0x27, 0x46, 0x7a, 0xa9, 0x2d, + 0xff, 0xcd, 0xb1, 0xa4, 0xd6, 0x0f, 0xcc, 0xbb, 0x05, 0x5c, 0xf3, 0x1f, + 0x89, 0xdf, 0x75, 0xee, 0xaf, 0xa8, 0x5a, 0x63, 0xd2, 0xf7, 0x24, 0xbe, + 0x12, 0x10, 0xbc, 0xe2, 0xe8, 0xbd, 0x43, 0x35, 0xaa, 0x37, 0xdf, 0x08, + 0x79, 0x76, 0x68, 0xc1, 0x5c, 0xff, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x14, 0xfe, 0xe4, 0xb3, 0x02, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0xd3, 0x21, 0xe6, 0x68, 0x67, 0x33, 0x42, 0xfa, 0x69, 0x83, + 0x0e, 0x72, 0x9a, 0xe9, 0xbd, 0xa3, 0xbf, 0x65, 0x89, 0x14, 0x4a, 0x42, + 0x40, 0x69, 0x97, 0xbc, 0xdd, 0x85, 0xca, 0xab, 0x7c, 0x43, 0x12, 0x10, + 0xf7, 0x87, 0xfc, 0xd1, 0x23, 0xc3, 0x78, 0xb0, 0x64, 0x2b, 0x9b, 0x21, + 0xfd, 0x8b, 0x0c, 0x5d, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xce, + 0xeb, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_RenewOnLicenseLoad_Case1S_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x89, 0x1b, 0x93, 0x4a, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x89, 0x1b, 0x93, 0x4a, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xd4, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x4a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x16, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xc0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xae, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x24, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xac, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x78, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x22, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xee, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x59, 0x32, 0x26, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x52, 0x65, 0x6e, 0x65, 0x77, 0x4f, 0x6e, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x33, + 0x39, 0x36, 0x31, 0x44, 0x41, 0x33, 0x32, 0x39, 0x31, 0x38, 0x43, 0x45, + 0x38, 0x39, 0x45, 0x33, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1f, 0x08, 0x01, 0x10, + 0x01, 0x18, 0x01, 0x20, 0x14, 0x28, 0x32, 0x30, 0x00, 0x38, 0x0f, 0x42, + 0x00, 0x48, 0x05, 0x50, 0x00, 0x58, 0x01, 0x60, 0x00, 0x70, 0x00, 0x78, + 0x01, 0x90, 0x01, 0x02, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0xde, 0xdf, + 0x6d, 0x7e, 0x92, 0x6d, 0x88, 0xc2, 0x7b, 0x1f, 0x19, 0xd4, 0xce, 0xc4, + 0x29, 0x26, 0x3a, 0x5f, 0x08, 0x73, 0x4d, 0x53, 0xab, 0x19, 0x78, 0x94, + 0xd5, 0x0e, 0xa9, 0x39, 0x9d, 0x49, 0x2e, 0x1d, 0xd2, 0x35, 0x99, 0x29, + 0x45, 0xb6, 0x71, 0x62, 0x7f, 0x84, 0xef, 0x38, 0x8a, 0x4b, 0x6f, 0x95, + 0xdf, 0x77, 0x29, 0x13, 0x6c, 0x59, 0xbf, 0xcb, 0x68, 0xee, 0x86, 0x02, + 0xab, 0x5f, 0x3b, 0xd2, 0x59, 0x0f, 0x0c, 0xc9, 0xa5, 0x08, 0xaa, 0xa7, + 0xea, 0xbf, 0x04, 0xe0, 0x74, 0x10, 0x12, 0x10, 0x0f, 0x43, 0xab, 0xfd, + 0x5a, 0x22, 0x2e, 0x0c, 0x20, 0xfe, 0x1f, 0xd7, 0x26, 0xb2, 0x4b, 0x8b, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x14, 0x89, 0x1b, 0x93, 0x4a, 0xa0, 0x00, 0x40, 0x00, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0xd6, 0xad, 0x65, 0x99, 0xda, 0xab, 0xc5, 0x20, 0x9d, 0x2f, + 0xc5, 0x50, 0xbd, 0x87, 0xcd, 0x8e, 0xbf, 0xa8, 0x2c, 0x72, 0x26, 0x99, + 0xa5, 0xe5, 0xdc, 0x9f, 0x53, 0x24, 0x3a, 0x9b, 0x25, 0x00, 0x12, 0x10, + 0xf4, 0x86, 0x40, 0xc9, 0xf8, 0x07, 0x49, 0x65, 0x9d, 0x86, 0x32, 0xba, + 0x4a, 0xf6, 0x14, 0xca, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x14, 0x89, 0x1b, 0x93, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x54, 0x91, 0xb8, 0xdb, 0x8d, 0x4f, 0xbe, 0xb4, 0x1d, 0x6d, 0x2f, 0x80, + 0xdb, 0xcf, 0x08, 0xe9, 0xe3, 0x71, 0x0e, 0x81, 0x7c, 0x29, 0x2f, 0x1d, + 0xff, 0xc0, 0x10, 0x97, 0x01, 0x5a, 0x24, 0xb3, 0x12, 0x10, 0x9d, 0x99, + 0xf6, 0x9a, 0x51, 0x94, 0xe0, 0x53, 0xb3, 0xfd, 0x48, 0x3a, 0x68, 0xef, + 0xb0, 0x89, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, + 0x89, 0x1b, 0x93, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x24, 0xd2, + 0x67, 0x90, 0xb6, 0x45, 0xf4, 0x00, 0x13, 0xf3, 0xf8, 0x1a, 0x18, 0x7e, + 0x72, 0x99, 0x42, 0xe6, 0x90, 0xa8, 0x34, 0x05, 0xa0, 0x82, 0xa1, 0x65, + 0x21, 0x60, 0x00, 0xc7, 0x08, 0x12, 0x12, 0x10, 0xac, 0x8b, 0x07, 0x6c, + 0x81, 0x40, 0xb2, 0xf6, 0xa4, 0xe4, 0xb5, 0xef, 0xb6, 0xe8, 0x1c, 0xfe, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0x89, 0x1b, + 0x93, 0x4a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x52, 0x7b, 0x3f, 0xfb, + 0x2f, 0x4f, 0xd4, 0x1a, 0x99, 0x16, 0x57, 0xdf, 0xc6, 0x9b, 0x7a, 0xb0, + 0xb0, 0x0f, 0x3a, 0x3e, 0x58, 0xed, 0x7f, 0x36, 0x24, 0x0c, 0x31, 0xee, + 0x4d, 0xba, 0x14, 0x2f, 0x12, 0x10, 0xf7, 0x91, 0xce, 0x0e, 0xca, 0x85, + 0x09, 0xc3, 0xb6, 0x8e, 0x55, 0xba, 0x57, 0x78, 0x06, 0xd5, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x14, 0x89, 0x1b, 0x93, 0x4a, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x7e, 0xd6, 0x01, 0xe7, 0x8e, 0x9c, + 0x69, 0x62, 0x48, 0x7d, 0x87, 0x36, 0x52, 0x00, 0xb1, 0xba, 0x17, 0x17, + 0x18, 0x2f, 0xbc, 0x41, 0xed, 0x49, 0x89, 0xc8, 0xd8, 0x86, 0x7d, 0xc1, + 0x40, 0x17, 0x12, 0x10, 0xdc, 0xa2, 0x65, 0x56, 0x19, 0xec, 0x28, 0x1a, + 0x52, 0xc0, 0xee, 0xff, 0x8e, 0xd7, 0x27, 0x71, 0x0a, 0x10, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, + 0x3d, 0x3d, 0x20, 0xf9, 0xeb, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_Heartbeat_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x65, 0x6d, 0xbf, 0xb7, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x65, 0x6d, 0xbf, 0xb7, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa9, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x1f, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xeb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x95, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x83, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xf9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xd7, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x81, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x6f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x4d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0xf7, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xc3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x31, 0x28, 0x00, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x38, 0x33, 0x37, 0x34, 0x42, + 0x32, 0x38, 0x39, 0x36, 0x46, 0x31, 0x33, 0x34, 0x46, 0x33, 0x36, 0x33, + 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, + 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x1e, 0x42, 0x00, 0x48, 0x0a, 0x50, + 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x1a, 0x66, 0x20, + 0x01, 0x1a, 0x50, 0x3c, 0x24, 0xe5, 0xa4, 0x72, 0x7b, 0x14, 0xd1, 0x6d, + 0x16, 0x30, 0x6e, 0x1c, 0xf9, 0xe2, 0xe8, 0xad, 0x7b, 0x37, 0x8e, 0xce, + 0x2c, 0x9c, 0x02, 0xf4, 0x93, 0xb3, 0xa1, 0x51, 0x26, 0x24, 0x25, 0x8a, + 0x84, 0x5f, 0xe8, 0xbb, 0x68, 0x75, 0x80, 0xaf, 0x9c, 0x7e, 0x39, 0xc4, + 0x6e, 0xe0, 0xb0, 0xd5, 0x4c, 0x0d, 0x89, 0xb8, 0x83, 0x67, 0x72, 0x4c, + 0x4c, 0x7c, 0x83, 0x3c, 0x67, 0x0c, 0x18, 0xf9, 0x6d, 0xb9, 0xe2, 0x31, + 0x36, 0x23, 0x75, 0x5b, 0x95, 0xd5, 0xbc, 0x87, 0x63, 0x2d, 0x5f, 0x12, + 0x10, 0x07, 0xf9, 0x13, 0x26, 0x2e, 0x8e, 0xcd, 0x99, 0xcf, 0x51, 0xc7, + 0x23, 0x9d, 0x93, 0x7e, 0x17, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x65, 0x6d, 0xbf, + 0xb7, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x08, 0x32, 0xa2, 0xe4, 0x52, + 0xe8, 0xb6, 0xe9, 0x9b, 0x35, 0x12, 0x27, 0x34, 0x61, 0xb4, 0x65, 0xa2, + 0xa0, 0x36, 0x8a, 0xe5, 0x4e, 0x87, 0xb9, 0x63, 0x88, 0x46, 0x52, 0x24, + 0x0d, 0x99, 0x81, 0x12, 0x10, 0xcd, 0xdd, 0x7d, 0x3f, 0x55, 0x1b, 0x55, + 0x4a, 0xde, 0x62, 0x11, 0x22, 0xa7, 0x6f, 0x7f, 0xf4, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x65, 0x6d, 0xbf, 0xb7, 0xa0, + 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0x2c, 0x20, 0xca, 0x90, 0xe5, 0x74, 0xb4, + 0x51, 0x9e, 0x76, 0xb2, 0xb9, 0x9c, 0x90, 0x8c, 0xa1, 0xc7, 0x95, 0x2d, + 0xa5, 0xc4, 0x4e, 0x6f, 0x60, 0xd2, 0xe1, 0xdd, 0x48, 0x6a, 0x7c, 0xfb, + 0x7f, 0x12, 0x10, 0xbb, 0x62, 0x59, 0x12, 0x20, 0x34, 0x33, 0xbb, 0x54, + 0xc9, 0xcb, 0xeb, 0xc5, 0xd2, 0xaa, 0x81, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x28, 0x65, 0x6d, 0xbf, 0xb7, 0xa0, 0x00, 0x00, + 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0x63, 0x14, 0xef, 0x69, 0xdf, 0x79, 0x12, 0x54, 0x65, + 0xb2, 0x16, 0xb7, 0xe3, 0x11, 0xc0, 0x76, 0x55, 0x74, 0x46, 0x69, 0x74, + 0x43, 0x88, 0xb5, 0x05, 0x58, 0x97, 0x49, 0x31, 0x54, 0x49, 0xe9, 0x12, + 0x10, 0x4f, 0x97, 0xeb, 0x53, 0xed, 0x6c, 0xe7, 0x0c, 0x14, 0xcd, 0x90, + 0xaa, 0x7a, 0xc3, 0x37, 0xfc, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, + 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, + 0x00, 0x00, 0x28, 0x65, 0x6d, 0xbf, 0xb7, 0xa0, 0x00, 0x00, 0x08, 0x3a, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, + 0x20, 0xdb, 0x37, 0x77, 0xed, 0x7a, 0xc2, 0x1e, 0x60, 0xf2, 0x82, 0xe2, + 0x7b, 0x56, 0x03, 0xb8, 0x21, 0xdd, 0xeb, 0x01, 0xf3, 0xe1, 0xa7, 0xaf, + 0x7a, 0xf5, 0x38, 0x8e, 0x1d, 0x01, 0x9d, 0x1b, 0xe4, 0x12, 0x10, 0x89, + 0x97, 0xdb, 0x38, 0x9a, 0xc9, 0x12, 0x79, 0x60, 0x37, 0x5e, 0x1a, 0x29, + 0xf9, 0x16, 0x34, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, + 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, + 0x28, 0x65, 0x6d, 0xbf, 0xb7, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x52, + 0x32, 0xcf, 0x3c, 0xae, 0x98, 0x40, 0xef, 0x7f, 0xc2, 0x5b, 0x6b, 0x5f, + 0x4a, 0x2b, 0x57, 0x03, 0xfa, 0x1c, 0x1a, 0xd3, 0x9c, 0x03, 0x96, 0xf7, + 0x0a, 0x09, 0x7e, 0x88, 0xa7, 0xd5, 0x4d, 0x12, 0x10, 0xa4, 0xa0, 0x78, + 0xe7, 0x65, 0x31, 0x98, 0xbd, 0x72, 0xf4, 0xa5, 0xec, 0xc4, 0x5f, 0x15, + 0xa1, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xd0, 0xed, 0x92, 0xa2, + 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_Heartbeat_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0xff, 0x39, 0xcd, 0x87, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0xff, 0x39, 0xcd, 0x87, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0xc8, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x0a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xb4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x2a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xf6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x6c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x16, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x50, 0x32, 0x1d, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x63, 0x61, + 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, + 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x0a, 0x20, 0x31, 0x45, 0x43, 0x38, 0x42, 0x30, 0x30, 0x33, 0x42, 0x32, + 0x42, 0x32, 0x34, 0x30, 0x34, 0x37, 0x33, 0x45, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, + 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, + 0x38, 0x1e, 0x42, 0x00, 0x48, 0x0a, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x00, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0xbc, 0x1c, + 0x7d, 0xe8, 0x97, 0x48, 0x11, 0x56, 0x47, 0xa2, 0x80, 0xe5, 0x76, 0x69, + 0x27, 0x5e, 0x06, 0x21, 0x13, 0x66, 0xcb, 0x76, 0xb6, 0xc5, 0xbf, 0xf8, + 0xce, 0x25, 0x66, 0x31, 0x42, 0x70, 0x98, 0xad, 0xe4, 0xce, 0x4b, 0x4b, + 0x61, 0x74, 0x66, 0x50, 0x32, 0x59, 0xbb, 0x7f, 0x4a, 0xa1, 0x66, 0x3a, + 0x88, 0xd7, 0xb5, 0x35, 0xde, 0xa1, 0xb6, 0xb1, 0xe8, 0xbe, 0x05, 0xfe, + 0xcd, 0x7c, 0xe2, 0x96, 0xdc, 0xc2, 0xdf, 0x91, 0xb2, 0x90, 0x4d, 0xbb, + 0x81, 0xcb, 0x01, 0xaa, 0x42, 0xd3, 0x12, 0x10, 0x46, 0x77, 0x79, 0x61, + 0x62, 0x62, 0xed, 0xaa, 0x46, 0x5a, 0x67, 0xf2, 0x19, 0xba, 0xee, 0x9e, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x28, 0xff, 0x39, 0xcd, 0x87, 0xa0, 0x00, 0x40, 0x00, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x48, 0xff, 0x8e, 0x66, 0x20, 0xd1, 0xbc, 0x5b, 0x76, 0x04, + 0x2f, 0x09, 0x9b, 0xc5, 0x06, 0x7f, 0x4e, 0xb7, 0x26, 0x9f, 0x7c, 0xbc, + 0x18, 0x59, 0xc8, 0xe4, 0x80, 0xae, 0xef, 0xac, 0xe9, 0xa2, 0x12, 0x10, + 0x4c, 0x2e, 0x98, 0xba, 0xcc, 0xac, 0x5d, 0x8d, 0x39, 0x02, 0x1a, 0xcb, + 0x26, 0xea, 0x2d, 0x9a, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x28, 0xff, 0x39, 0xcd, 0x87, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x93, 0x8a, 0x54, 0xea, 0xa0, 0xf6, 0x46, 0xa0, 0x30, 0x43, 0x0b, 0xab, + 0x83, 0xae, 0x5c, 0xff, 0xcb, 0xef, 0x9e, 0x6c, 0xc1, 0x60, 0x77, 0xdb, + 0xb0, 0x52, 0x41, 0x0e, 0x8f, 0x5e, 0x71, 0x61, 0x12, 0x10, 0xd9, 0x43, + 0xf4, 0xe0, 0x79, 0xb5, 0xfa, 0xaa, 0xc1, 0x1c, 0x4f, 0x06, 0xcb, 0xa7, + 0x6d, 0xf0, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, + 0xff, 0x39, 0xcd, 0x87, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xcc, 0xc8, + 0xf0, 0xc2, 0x89, 0xb6, 0x55, 0xa7, 0xc8, 0x8b, 0xfc, 0x1a, 0x77, 0x31, + 0xd6, 0x2f, 0x0b, 0x9b, 0x6f, 0x80, 0x30, 0x82, 0x44, 0x90, 0x87, 0x81, + 0x4a, 0x3e, 0x08, 0xbf, 0x66, 0x0c, 0x12, 0x10, 0xba, 0xb6, 0x61, 0xb5, + 0x67, 0xaa, 0x5a, 0xfb, 0x54, 0xa9, 0xf7, 0x2d, 0x0a, 0xf5, 0x7e, 0x53, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0xff, 0x39, + 0xcd, 0x87, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x9b, 0xdc, 0x8d, 0x37, + 0xc5, 0x6e, 0x42, 0xe1, 0xb9, 0xd2, 0xf4, 0xa2, 0x3d, 0x35, 0xc8, 0xc9, + 0xd3, 0x98, 0xd7, 0xf4, 0x48, 0x99, 0x37, 0x29, 0x82, 0x1c, 0xd0, 0x09, + 0xf1, 0x3d, 0x6b, 0x2c, 0x12, 0x10, 0x7c, 0xdd, 0xf1, 0xf4, 0x4c, 0x0f, + 0xda, 0xf2, 0x11, 0xde, 0x1c, 0x63, 0x67, 0xf7, 0x64, 0xe3, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0xff, 0x39, 0xcd, 0x87, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xb6, 0x8c, 0xc4, 0xe3, 0x81, 0x2d, + 0x12, 0x8b, 0x4e, 0x34, 0xb0, 0xd1, 0x98, 0xfe, 0x3d, 0xac, 0xb9, 0x23, + 0x55, 0x2c, 0xd2, 0x92, 0x6f, 0xb8, 0x43, 0x29, 0x9e, 0xbc, 0x65, 0xf6, + 0x1c, 0xa7, 0x12, 0x10, 0x93, 0x46, 0x6d, 0x6f, 0xc4, 0x67, 0xaa, 0xa2, + 0x67, 0x00, 0x1d, 0x31, 0x4e, 0xce, 0xca, 0x56, 0x0a, 0x10, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, + 0x3d, 0x3d, 0x20, 0xaa, 0xee, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_UnlimitedStreaming_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x1a, 0xb9, 0xef, 0x9e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x1a, 0xb9, 0xef, 0x9e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0xf2, 0xb9, 0x77, 0xd5, + 0x84, 0xc8, 0x31, 0xbf, 0x0a, 0x20, 0x39, 0x41, 0x32, 0x39, 0x30, 0x42, + 0x35, 0x37, 0x43, 0x44, 0x32, 0x34, 0x34, 0x43, 0x38, 0x30, 0x34, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, 0x01, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0xb9, 0xef, 0x9e, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xe4, 0xe3, + 0x94, 0xff, 0x8b, 0x7b, 0xe0, 0x33, 0xbb, 0x8d, 0xe4, 0x12, 0xda, 0xa6, + 0xff, 0xb1, 0x0c, 0x12, 0x52, 0xb6, 0x18, 0x75, 0xca, 0x42, 0xc0, 0x79, + 0xa9, 0x1e, 0xce, 0x50, 0xe4, 0xdc, 0x12, 0x10, 0x19, 0x7a, 0x19, 0xaf, + 0x7a, 0x9d, 0x7a, 0x42, 0xcd, 0x63, 0x28, 0xdb, 0x60, 0x9b, 0xd7, 0xbb, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xb9, + 0xef, 0x9e, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x0a, 0xca, 0xc3, 0x4a, + 0xef, 0xc3, 0x1f, 0x88, 0xdb, 0x98, 0x0a, 0xe6, 0xfe, 0xdc, 0xd4, 0x1a, + 0xfe, 0x75, 0x70, 0x52, 0x40, 0x14, 0x8c, 0xc4, 0xfd, 0x31, 0x4e, 0x70, + 0x72, 0x0f, 0x3a, 0x16, 0x12, 0x10, 0x38, 0xa3, 0xf3, 0x06, 0x12, 0x23, + 0x3c, 0x90, 0xe6, 0x97, 0xce, 0xe5, 0x30, 0xf2, 0xf8, 0x74, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xb9, 0xef, 0x9e, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x3b, 0x0e, 0xfc, 0x2d, 0x2c, 0x09, + 0xee, 0x4e, 0x26, 0xac, 0x63, 0xa2, 0x78, 0x8f, 0x07, 0xa8, 0x1e, 0xf1, + 0xeb, 0x6b, 0xc5, 0x50, 0x4f, 0xca, 0xcb, 0x73, 0xe8, 0x6a, 0xec, 0x04, + 0x0c, 0x3f, 0x12, 0x10, 0xc6, 0x14, 0xa3, 0xcf, 0xd5, 0xb7, 0x6d, 0xc7, + 0x39, 0x53, 0x3f, 0xf8, 0xf9, 0xc2, 0x8e, 0x44, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xb9, 0xef, 0x9e, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x99, 0xb7, 0x72, 0x61, 0x4a, 0x47, 0xae, 0x57, + 0x5f, 0xf6, 0xfb, 0xd2, 0x86, 0x19, 0x56, 0x65, 0x3d, 0x79, 0x6c, 0x88, + 0x9d, 0xa2, 0x06, 0xf8, 0x50, 0x21, 0xda, 0x1a, 0xdc, 0xc6, 0xac, 0xd2, + 0x12, 0x10, 0x80, 0x2c, 0xbb, 0x2f, 0x10, 0x99, 0xbf, 0xc2, 0x10, 0xfa, + 0x04, 0x32, 0xc4, 0xb8, 0xe7, 0x77, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0xb9, 0xef, 0x9e, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x19, 0x97, 0xf8, 0x93, 0x7a, 0xb2, 0x45, 0xde, 0x2d, 0x9e, + 0xc5, 0x3d, 0xae, 0xf6, 0xf9, 0xf0, 0xd1, 0x42, 0xa5, 0x51, 0x59, 0xbb, + 0x00, 0x9c, 0xa8, 0xd4, 0xe4, 0x32, 0x63, 0x39, 0x17, 0x87, 0x12, 0x10, + 0x3a, 0xef, 0x60, 0x77, 0x8d, 0x75, 0xa4, 0x72, 0x6c, 0x75, 0xaa, 0x72, + 0x77, 0xde, 0x02, 0xc6, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x84, + 0xef, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_UnlimitedStreaming_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x8d, 0x57, 0x68, 0x72, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x8d, 0x57, 0x68, 0x72, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0xd1, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x47, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x13, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xbd, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xab, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x89, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x33, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x21, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa9, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x97, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x75, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xeb, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x59, 0x32, 0x26, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x55, 0x6e, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x46, + 0x37, 0x33, 0x44, 0x33, 0x42, 0x32, 0x32, 0x42, 0x42, 0x41, 0x37, 0x41, + 0x34, 0x45, 0x31, 0x34, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, + 0x01, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x42, + 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x01, 0x78, + 0x01, 0x1a, 0x66, 0x20, 0x01, 0x1a, 0x50, 0x5d, 0x0d, 0x4a, 0x1f, 0x5f, + 0x83, 0x6c, 0xf4, 0x8f, 0x56, 0x85, 0x6f, 0x7c, 0xa1, 0x37, 0xb5, 0x26, + 0x29, 0xa0, 0x22, 0x46, 0x0b, 0xf3, 0x4e, 0xea, 0xc5, 0x71, 0x7e, 0x20, + 0x08, 0x95, 0xcb, 0x7c, 0xb1, 0x63, 0x4f, 0x5c, 0x4f, 0xd7, 0xde, 0x13, + 0x12, 0x72, 0x46, 0x30, 0x27, 0x9e, 0xad, 0x5a, 0x25, 0x8a, 0xe5, 0x64, + 0x2e, 0x48, 0xfc, 0x52, 0x95, 0x62, 0xb2, 0x4e, 0xd8, 0x6d, 0x14, 0xd4, + 0x9b, 0xd4, 0x98, 0x97, 0x68, 0x21, 0xe2, 0x0a, 0xe3, 0xcc, 0x27, 0xeb, + 0xfe, 0x47, 0x3e, 0x12, 0x10, 0x8b, 0x98, 0x83, 0x17, 0x2c, 0x86, 0x55, + 0x18, 0xbc, 0x7c, 0x65, 0x50, 0x7e, 0xb1, 0xaa, 0x53, 0x1a, 0x74, 0x62, + 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x8d, 0x57, 0x68, 0x72, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, + 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xed, + 0x6c, 0xeb, 0xc4, 0x44, 0xc9, 0xa2, 0x37, 0x35, 0xfc, 0xa0, 0x15, 0x5b, + 0x22, 0xd3, 0xdd, 0xb7, 0x60, 0x8f, 0x7d, 0x37, 0xfb, 0xe9, 0x46, 0x3f, + 0x54, 0x81, 0x0d, 0x19, 0xc8, 0x66, 0x1e, 0x12, 0x10, 0x96, 0xbf, 0x5c, + 0xf6, 0xe9, 0x97, 0xa9, 0x50, 0x5c, 0x66, 0x0d, 0xe7, 0x82, 0x4a, 0xed, + 0x32, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, + 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8d, + 0x57, 0x68, 0x72, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, + 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x47, 0x20, 0xd3, + 0x75, 0xd1, 0xab, 0xb1, 0x83, 0x40, 0x9a, 0xbe, 0x30, 0xcf, 0xed, 0x5e, + 0x38, 0x41, 0x1d, 0x1f, 0x24, 0x56, 0xfb, 0x68, 0x2b, 0x5c, 0x6f, 0xe4, + 0x4a, 0xba, 0x9f, 0x83, 0xd3, 0x12, 0x10, 0x23, 0xe6, 0xff, 0x76, 0x47, + 0xca, 0xb8, 0xdf, 0x87, 0x5e, 0xd6, 0xf8, 0x0e, 0x7e, 0x1b, 0x54, 0x0a, + 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, + 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x57, 0x68, + 0x72, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, + 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x54, 0x82, 0xa0, 0x1f, 0x11, + 0x1a, 0x3a, 0x97, 0xbb, 0xb8, 0xd0, 0x5f, 0x8a, 0x1c, 0x46, 0x3f, 0xdf, + 0xeb, 0x1f, 0xa7, 0x6f, 0x76, 0x1e, 0xe4, 0x38, 0x1b, 0x2d, 0x0e, 0x16, + 0x18, 0x28, 0x2e, 0x12, 0x10, 0xc4, 0x4d, 0x7f, 0xe8, 0x06, 0x7c, 0xa7, + 0x9d, 0x8d, 0x57, 0x8e, 0x79, 0x36, 0x99, 0xd1, 0xee, 0x0a, 0x10, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, + 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x57, 0x68, 0x72, 0xa0, + 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, + 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, + 0x01, 0x20, 0x02, 0x1a, 0x20, 0x0b, 0xc5, 0x6f, 0x96, 0xd3, 0x5c, 0xeb, + 0x9f, 0xce, 0xe2, 0x5e, 0xcc, 0x18, 0x4b, 0x16, 0x93, 0x30, 0x4c, 0x54, + 0x93, 0xf7, 0xc2, 0x44, 0x6a, 0x55, 0x7d, 0xa9, 0x8f, 0xb4, 0x87, 0xe6, + 0xef, 0x12, 0x10, 0xfc, 0x24, 0x24, 0x57, 0xcd, 0xd5, 0x88, 0xbc, 0x8b, + 0x2b, 0x68, 0x39, 0x11, 0x07, 0xec, 0x05, 0x0a, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x33, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x57, 0x68, 0x72, 0xa0, 0x00, 0x40, + 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, + 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, + 0x02, 0x1a, 0x20, 0xb7, 0xc4, 0xda, 0xb3, 0x69, 0xa9, 0xb8, 0x00, 0xce, + 0xf1, 0xae, 0x14, 0x78, 0xe3, 0xcd, 0x53, 0x04, 0x6a, 0x53, 0x3a, 0x21, + 0xb4, 0xf8, 0x93, 0xa5, 0x01, 0x90, 0x3f, 0x96, 0xf7, 0x03, 0x3f, 0x12, + 0x10, 0x94, 0x6b, 0xeb, 0xf2, 0xd4, 0x31, 0xf2, 0x53, 0x7e, 0x87, 0xff, + 0x92, 0x32, 0x98, 0x14, 0xba, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, + 0x92, 0xef, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LicenseDuration_Case1_0) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x10, 0x13, 0x2c, 0xd0, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x10, 0x13, 0x2c, 0xd0, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xe4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x8e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x30, 0x28, 0x00, 0x20, 0x01, 0x12, 0x08, 0x45, 0xbd, 0x77, 0xd5, + 0x84, 0xc8, 0x31, 0xbf, 0x0a, 0x20, 0x37, 0x37, 0x33, 0x46, 0x46, 0x38, + 0x38, 0x37, 0x45, 0x43, 0x41, 0x41, 0x41, 0x46, 0x35, 0x44, 0x34, 0x34, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x28, + 0x28, 0x28, 0x30, 0x28, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x74, 0x62, 0x00, + 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, + 0x10, 0x13, 0x2c, 0xd0, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x76, 0x44, + 0x2f, 0xe8, 0xe6, 0xc6, 0x69, 0xd7, 0xe6, 0x58, 0x52, 0xa2, 0x55, 0x21, + 0xff, 0x35, 0x18, 0x6e, 0xf4, 0xd1, 0xcf, 0xf7, 0xa6, 0x3f, 0x28, 0x1b, + 0x9c, 0xb9, 0x7c, 0xd5, 0x55, 0xf3, 0x12, 0x10, 0x84, 0x64, 0x82, 0xfd, + 0x48, 0xb2, 0x95, 0x64, 0x40, 0xfb, 0xdb, 0x52, 0xf0, 0x65, 0xeb, 0x4c, + 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x10, 0x13, + 0x2c, 0xd0, 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xca, 0x46, 0xaa, 0xa0, + 0x09, 0x72, 0x53, 0x17, 0x0d, 0x87, 0x93, 0xef, 0x04, 0x54, 0x58, 0x2f, + 0x23, 0xfc, 0x5b, 0xa2, 0x3b, 0xf4, 0x92, 0x85, 0x20, 0x7c, 0x70, 0x89, + 0x74, 0x8b, 0xa7, 0xdf, 0x12, 0x10, 0x89, 0xe6, 0x26, 0xe0, 0xea, 0x66, + 0xc9, 0xfe, 0xe5, 0x00, 0x49, 0x97, 0xb1, 0x44, 0x5f, 0xd0, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x10, 0x13, 0x2c, 0xd0, + 0xa0, 0x00, 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x49, 0x88, 0xb9, 0x28, 0x94, 0xb7, + 0x79, 0x98, 0x26, 0xcb, 0x73, 0xa7, 0x46, 0x7a, 0xad, 0xff, 0x67, 0x6f, + 0xd6, 0x6d, 0xb1, 0xa4, 0xbf, 0x77, 0x00, 0x47, 0x41, 0x5b, 0x46, 0xb8, + 0xd7, 0x8c, 0x12, 0x10, 0x6e, 0x4c, 0x66, 0x7f, 0xf8, 0x13, 0x1a, 0xe7, + 0x39, 0x37, 0x0a, 0x10, 0xbf, 0x2e, 0x3f, 0x60, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x10, 0x13, 0x2c, 0xd0, 0xa0, 0x00, + 0x00, 0x08, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0xd4, 0x6e, 0xdd, 0x52, 0x3a, 0xef, 0x82, 0x79, + 0xb0, 0xc2, 0x65, 0x82, 0x1a, 0x95, 0x42, 0x7a, 0xaf, 0x08, 0x20, 0xeb, + 0x6b, 0x8d, 0xc8, 0x66, 0x76, 0x82, 0xee, 0x21, 0x20, 0x98, 0x94, 0xd1, + 0x12, 0x10, 0x1f, 0xd3, 0x15, 0x4c, 0xaa, 0xd4, 0xa4, 0xea, 0x38, 0x26, + 0xaf, 0x2b, 0x83, 0x8d, 0xb9, 0x41, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x28, 0x10, 0x13, 0x2c, 0xd0, 0xa0, 0x00, 0x00, 0x08, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x02, 0xb7, 0xe2, 0x66, 0x85, 0x9c, 0x89, 0xc5, 0x1a, 0xc2, + 0x64, 0xd1, 0xad, 0x54, 0xe1, 0x8c, 0xc6, 0x58, 0xa2, 0xef, 0x16, 0x6c, + 0xba, 0x07, 0x53, 0x3a, 0xf4, 0xf0, 0x91, 0xdb, 0x98, 0xfa, 0x12, 0x10, + 0x66, 0x4e, 0xc3, 0xd9, 0x5b, 0xd1, 0xae, 0x03, 0x7c, 0x7d, 0x02, 0x3d, + 0x46, 0x63, 0x5b, 0x8a, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xa0, + 0xef, 0x92, 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +TEST_F(ODKGoldenLicenseV18, Both_CdmUseCase_LicenseDuration_Case1_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x12, + 0x6c, 0x30, 0xc9, 0x6a, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x39, 0x00, 0x02, 0x00, 0x12, + 0x6c, 0x30, 0xc9, 0x6a, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xce, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x32, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, + 0xba, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xa8, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x1e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xa6, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0x94, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, + 0x72, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, + 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x0a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, + 0x10, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t serialized_license_raw[] = { + 0x0a, 0x56, 0x32, 0x23, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x28, 0x00, 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x46, 0x33, 0x30, 0x42, + 0x34, 0x32, 0x34, 0x45, 0x37, 0x32, 0x45, 0x39, 0x44, 0x42, 0x31, 0x34, + 0x34, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, 0x10, 0x01, 0x18, 0x00, + 0x20, 0x28, 0x28, 0x28, 0x30, 0x28, 0x38, 0x00, 0x42, 0x00, 0x48, 0x00, + 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x1a, 0x66, + 0x20, 0x01, 0x1a, 0x50, 0x88, 0x49, 0x61, 0x40, 0xdb, 0x33, 0x95, 0x3c, + 0x00, 0x45, 0xe8, 0x2a, 0x7f, 0x4f, 0x19, 0xf5, 0xa9, 0x95, 0x0c, 0x87, + 0x9a, 0x3a, 0x07, 0xac, 0x9b, 0x2d, 0xc1, 0xe7, 0x33, 0x3f, 0x02, 0xcd, + 0xab, 0xa8, 0x28, 0x59, 0x4a, 0x87, 0xe8, 0x34, 0x2e, 0x59, 0xb5, 0xbf, + 0x0d, 0x5a, 0xea, 0x48, 0x92, 0xb5, 0x6a, 0x4d, 0x9f, 0x3b, 0x05, 0x77, + 0x1e, 0xf0, 0xc6, 0x86, 0x7f, 0xf6, 0xda, 0x86, 0x63, 0xa1, 0x83, 0xcb, + 0xa8, 0x42, 0xa6, 0x8f, 0x1d, 0x51, 0x7e, 0x30, 0x3d, 0x8e, 0x9d, 0xd3, + 0x12, 0x10, 0xa8, 0x5d, 0x94, 0xdf, 0x84, 0xa9, 0x21, 0xfe, 0x34, 0xf5, + 0x1c, 0x46, 0x91, 0x3f, 0x5a, 0xd3, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, + 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x6c, 0x30, + 0xc9, 0x6a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, + 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0xcd, 0xf2, 0x1a, 0x88, + 0x12, 0x76, 0x9c, 0xe3, 0xa4, 0xd2, 0x4e, 0xb4, 0x47, 0x7e, 0x5f, 0xbd, + 0x3d, 0xf3, 0xb6, 0x8b, 0x08, 0x2a, 0x08, 0xd2, 0x8c, 0x48, 0xc1, 0x2a, + 0x7d, 0xea, 0x7c, 0x1d, 0x12, 0x10, 0xcc, 0x3a, 0x0a, 0x97, 0x77, 0x32, + 0x0a, 0x3e, 0xba, 0x4e, 0x4b, 0x49, 0x0c, 0x31, 0x20, 0xbf, 0x0a, 0x10, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, + 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x6c, 0x30, 0xc9, 0x6a, + 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, + 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, 0x4f, 0xab, 0x30, 0xee, 0xcb, 0xd8, + 0x98, 0x92, 0x98, 0x9e, 0x68, 0xc6, 0xec, 0x62, 0x10, 0xbd, 0x77, 0x1b, + 0xdd, 0x76, 0xf9, 0x3d, 0x54, 0xbd, 0x4d, 0xdf, 0xc1, 0x2c, 0x1b, 0x99, + 0xc4, 0xbc, 0x12, 0x10, 0x9e, 0xc1, 0x2c, 0xe9, 0x27, 0x28, 0x8e, 0x10, + 0xc3, 0x10, 0x4a, 0x29, 0x0c, 0xd4, 0xe0, 0xf3, 0x0a, 0x10, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, + 0x31, 0x38, 0x00, 0x00, 0x00, 0x28, 0x6c, 0x30, 0xc9, 0x6a, 0xa0, 0x00, + 0x40, 0x00, 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, + 0x32, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, + 0x20, 0x02, 0x1a, 0x20, 0x12, 0x21, 0x5b, 0x6b, 0x76, 0xe1, 0xb1, 0x54, + 0xee, 0x90, 0xb5, 0x9e, 0x07, 0x52, 0x83, 0x90, 0x6e, 0x59, 0xed, 0x1b, + 0x7c, 0xda, 0xa5, 0x54, 0xd7, 0xed, 0x8b, 0x2a, 0x1d, 0x71, 0xeb, 0x11, + 0x12, 0x10, 0xd2, 0x5b, 0xd0, 0x80, 0x0e, 0x79, 0x33, 0xc2, 0xfb, 0xf6, + 0x5c, 0xc8, 0xbf, 0x70, 0x4b, 0xfb, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x1a, 0x74, 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, + 0x00, 0x00, 0x00, 0x28, 0x6c, 0x30, 0xc9, 0x6a, 0xa0, 0x00, 0x40, 0x00, + 0x3a, 0x08, 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, + 0x1a, 0x20, 0x12, 0xfc, 0x46, 0xad, 0xa8, 0x4a, 0xa6, 0x32, 0x3f, 0xbd, + 0x56, 0x2c, 0xc5, 0xd7, 0x9e, 0x4b, 0xd1, 0x58, 0x5d, 0xdb, 0x11, 0x4c, + 0x98, 0xde, 0x7e, 0xfa, 0x76, 0x53, 0xfd, 0x26, 0x16, 0x3d, 0x12, 0x10, + 0x70, 0x32, 0x63, 0x16, 0x9d, 0xf9, 0xe6, 0xbd, 0x98, 0x15, 0x4d, 0xa5, + 0x64, 0x37, 0x80, 0xdf, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x1a, 0x74, + 0x62, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x38, 0x00, 0x00, + 0x00, 0x28, 0x6c, 0x30, 0xc9, 0x6a, 0xa0, 0x00, 0x40, 0x00, 0x3a, 0x08, + 0x08, 0x00, 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x32, 0x08, 0x08, 0x00, + 0x10, 0x2a, 0x18, 0x00, 0x20, 0x00, 0x28, 0x01, 0x20, 0x02, 0x1a, 0x20, + 0x73, 0x93, 0xe0, 0xf1, 0x39, 0xcb, 0x32, 0xc1, 0xb7, 0x33, 0x0f, 0x1f, + 0x98, 0xd2, 0x7c, 0x88, 0xc0, 0x8c, 0xcb, 0x5e, 0x9f, 0x75, 0xe7, 0xb7, + 0x6b, 0x0c, 0x30, 0x8b, 0x7a, 0xb0, 0x90, 0xff, 0x12, 0x10, 0x31, 0x6b, + 0xc7, 0xf8, 0x79, 0xa1, 0x32, 0xbd, 0x66, 0x86, 0x11, 0x42, 0x8c, 0xcc, + 0x8d, 0x21, 0x0a, 0x10, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x4b, 0x65, 0x79, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0xc6, 0xef, 0x92, + 0xa2, 0x06, 0x38, 0x00, + }; + serialized_license_ = + std::string(reinterpret_cast(serialized_license_raw), + sizeof(serialized_license_raw)); + const uint8_t core_request_sha256_raw[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + core_request_sha256_ = + std::string(reinterpret_cast(core_request_sha256_raw), + sizeof(core_request_sha256_raw)); + nonce_required_ = true; + RunTest(); +} + +////////////////////////////////////////////////////////////////////// +// Renewal Tests. +// A few renewal examples from filter *PIG*:*CdmUseCase*. +// Note: running these cases generates many renewals. It should be +// ok to only test one or two. +////////////////////////////////////////////////////////////////////// + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_LicenseWithRenewal_Case1_0_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x01, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x38, 0x39, 0x36, + 0x37, 0x33, 0x45, 0x32, 0x43, 0x31, 0x37, 0x46, 0x32, 0x41, 0x41, + 0x44, 0x42, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, + 0x10, 0x00, 0x18, 0x01, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, + 0x0a, 0x42, 0x00, 0x48, 0x0f, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x01, 0x20, 0xd7, 0xe7, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 25; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_LicenseWithRenewal_Case1_0_2) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x0c, 0x6a, 0x70, 0xec, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x04, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x38, 0x39, 0x36, + 0x37, 0x33, 0x45, 0x32, 0x43, 0x31, 0x37, 0x46, 0x32, 0x41, 0x41, + 0x44, 0x42, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, + 0x10, 0x00, 0x18, 0x01, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, + 0x0a, 0x42, 0x00, 0x48, 0x0f, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x01, 0x20, 0x9c, 0xe8, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 25; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, + Both_CdmUseCase_LicenseWithRenewalPlayback_Case1_0_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x05, 0xd3, 0xe8, 0xe8, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x05, 0xd3, 0xe8, 0xe8, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x02, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x34, 0x42, 0x44, + 0x43, 0x35, 0x37, 0x34, 0x39, 0x37, 0x34, 0x45, 0x39, 0x36, 0x31, + 0x35, 0x36, 0x32, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, + 0x10, 0x00, 0x18, 0x01, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, + 0x0a, 0x42, 0x00, 0x48, 0x0f, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x01, 0x20, 0xd4, 0xe9, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 25; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_LimitedDurationLicense_Case1_0_2) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x1d, 0x71, 0xab, 0x3b, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x1d, 0x71, 0xab, 0x3b, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x33, 0x80, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x01, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x42, 0x44, 0x46, 0x30, 0x45, + 0x34, 0x42, 0x39, 0x30, 0x34, 0x32, 0x41, 0x42, 0x38, 0x30, 0x41, 0x32, + 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1f, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x80, 0xe7, 0x84, 0x0f, 0x42, 0x00, + 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, + 0x20, 0x9d, 0xeb, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 31536000; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_LimitedDurationLicense_Case1_1_3) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0xd4, 0x57, 0xcc, 0x27, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0xd4, 0x57, 0xcc, 0x27, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x33, 0x80, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x5d, 0x32, 0x2a, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x63, + 0x61, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x01, + 0x20, 0x02, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x0a, 0x20, 0x39, 0x35, 0x31, 0x38, 0x34, 0x35, 0x33, 0x39, 0x36, + 0x34, 0x31, 0x31, 0x46, 0x31, 0x45, 0x38, 0x32, 0x45, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, + 0x1f, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, + 0x00, 0x38, 0x80, 0xe7, 0x84, 0x0f, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, + 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, 0x20, 0xbe, 0xeb, 0x92, + 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 31536000; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_RenewOnLicenseLoad_Case1L_0_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x84, 0x57, 0x13, 0x9e, 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x84, 0x57, 0x13, 0x9e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x33, 0x80, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x01, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x34, 0x31, 0x35, 0x34, 0x39, + 0x42, 0x42, 0x46, 0x44, 0x36, 0x45, 0x36, 0x38, 0x42, 0x32, 0x37, 0x33, + 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x12, 0x1f, 0x08, 0x01, 0x10, 0x00, 0x18, 0x00, 0x20, + 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x80, 0xe7, 0x84, 0x0f, 0x42, 0x00, + 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x01, + 0x20, 0x85, 0xed, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 31536000; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_RenewOnLicenseLoad_Case1L_1_2) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0xb8, 0xfc, 0x76, 0x3a, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0xb8, 0xfc, 0x76, 0x3a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe1, 0x33, 0x80, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x59, 0x32, 0x26, 0x70, 0x73, 0x74, 0x5f, 0x43, 0x44, 0x4d, 0x5f, + 0x52, 0x65, 0x6e, 0x65, 0x77, 0x4f, 0x6e, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x61, 0x6e, 0x5f, 0x70, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x28, 0x01, 0x20, 0x02, 0x12, 0x09, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x30, + 0x45, 0x42, 0x34, 0x39, 0x44, 0x34, 0x37, 0x39, 0x32, 0x32, 0x37, 0x32, + 0x33, 0x31, 0x45, 0x33, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1f, 0x08, 0x01, 0x10, + 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x80, 0xe7, + 0x84, 0x0f, 0x42, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x01, 0x20, 0xb0, 0xed, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 31536000; + RunTest(); +} + +TEST_F(ODKGoldenRenewalV18, Both_CdmUseCase_Heartbeat_Case1_0_1) { + const uint8_t core_request_raw[] = { + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, + 0x00, 0x12, 0x65, 0x6d, 0xbf, 0xb7, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + }; + core_request_ = std::string(reinterpret_cast(core_request_raw), + sizeof(core_request_raw)); + const uint8_t core_response_raw[] = { + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x02, 0x00, 0x12, + 0x65, 0x6d, 0xbf, 0xb7, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + }; + core_response_ = + std::string(reinterpret_cast(core_response_raw), + sizeof(core_response_raw)); + const uint8_t renewal_raw[] = { + 0x0a, 0x31, 0x28, 0x03, 0x20, 0x01, 0x12, 0x09, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x0a, 0x20, 0x38, 0x33, 0x37, + 0x34, 0x42, 0x32, 0x38, 0x39, 0x36, 0x46, 0x31, 0x33, 0x34, 0x46, + 0x33, 0x36, 0x33, 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x1c, 0x08, 0x01, + 0x10, 0x00, 0x18, 0x01, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, + 0x1e, 0x42, 0x00, 0x48, 0x0a, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, + 0x70, 0x00, 0x78, 0x00, 0x20, 0x86, 0xee, 0x92, 0xa2, 0x06, + }; + renewal_ = std::string(reinterpret_cast(renewal_raw), + sizeof(renewal_raw)); + renewal_duration_seconds_ = 40; + RunTest(); +} + +////////////////////////////////////////////////////////////////////// +} // namespace + +} // namespace wvodk_test diff --git a/oemcrypto/odk/test/odk_test.cpp b/oemcrypto/odk/test/odk_test.cpp index 5fafb070..31d0c3b4 100644 --- a/oemcrypto/odk/test/odk_test.cpp +++ b/oemcrypto/odk/test/odk_test.cpp @@ -4,16 +4,22 @@ #include "odk.h" +#include #include #include +#include #include +#include #include "OEMCryptoCENCCommon.h" #include "core_message_deserialize.h" #include "core_message_features.h" #include "core_message_serialize.h" +#include "core_message_serialize_proto.h" #include "core_message_types.h" #include "gtest/gtest.h" +#include "odk_overflow.h" +#include "odk_structs.h" #include "odk_structs_priv.h" #include "odk_test_helper.h" @@ -21,11 +27,16 @@ namespace wvodk_test { namespace { +using oemcrypto_core_message::ODK_CommonRequest; using oemcrypto_core_message::ODK_LicenseRequest; +using oemcrypto_core_message::ODK_MessageCounter; +using oemcrypto_core_message::ODK_Provisioning40Request; using oemcrypto_core_message::ODK_ProvisioningRequest; using oemcrypto_core_message::ODK_RenewalRequest; +using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage; using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage; +using oemcrypto_core_message::deserialize::CoreProvisioning40RequestFromMessage; using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage; using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage; using oemcrypto_core_message::deserialize:: @@ -34,7 +45,10 @@ using oemcrypto_core_message::deserialize:: using oemcrypto_core_message::features::CoreMessageFeatures; using oemcrypto_core_message::serialize::CreateCoreLicenseResponse; +using oemcrypto_core_message::serialize::CreateCoreProvisioning40Response; using oemcrypto_core_message::serialize::CreateCoreProvisioningResponse; +using oemcrypto_core_message::serialize:: + CreateCoreProvisioningResponseFromProto; using oemcrypto_core_message::serialize::CreateCoreRenewalResponse; constexpr uint32_t kExtraPayloadSize = 128u; @@ -59,6 +73,40 @@ void PrintTo(const VersionParameters& p, std::ostream* os) { << p.response_minor_version; } +void SetDefaultSerializedProvisioningResponse(std::string* serialized_message) { + // Create a dummy provisioning response + video_widevine::ProvisioningResponse provisioning_response; + provisioning_response.set_device_certificate("device_certificate"); + provisioning_response.set_device_rsa_key("device_rsa_key"); + provisioning_response.set_device_rsa_key_iv("device_rsa_key_iv"); + if (!provisioning_response.SerializeToString(serialized_message)) { + FAIL(); + } +} + +bool CheckCounterInfoIsEqual(ODK_MessageCounterInfo* a, ODK_MessageCounter* b) { + if (!a || !b) return false; + + EXPECT_EQ(a->master_generation_number, b->master_generation_number); + EXPECT_EQ(a->provisioning_count, b->provisioning_count); + EXPECT_EQ(a->license_count, b->license_count); + EXPECT_EQ(a->decrypt_count, b->decrypt_count); + EXPECT_EQ(a->major_version, b->major_version); + EXPECT_EQ(a->minor_version, b->minor_version); + EXPECT_EQ(a->patch_version, b->patch_version); + for (size_t i = 0; i < sizeof(a->soc_vendor); i++) { + EXPECT_EQ(a->soc_vendor[i], b->soc_vendor[i]); + } + for (size_t i = 0; i < sizeof(a->chipset_model); i++) { + EXPECT_EQ(a->chipset_model[i], b->chipset_model[i]); + } + for (size_t i = 0; i < sizeof(a->extra); i++) { + EXPECT_EQ(a->extra[i], b->extra[i]); + } + + return true; +} + template void ValidateRequest(uint32_t message_type, const std::vector& extra_fields, @@ -241,13 +289,19 @@ TEST(OdkTest, NullRequestTest) { memset(&nonce_values, 0, sizeof(nonce_values)); ODK_ClockValues clock_values; memset(&clock_values, 0, sizeof(clock_values)); + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); // Assert that nullptr does not cause a core dump. - EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest( - nullptr, 0uL, nullptr, &nonce_values)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_PrepareCoreLicenseRequest(nullptr, 0uL, nullptr, &nonce_values, + &counter_info)); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length, - nullptr)); + nullptr, &counter_info)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length, + &nonce_values, nullptr)); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreRenewalRequest(nullptr, 0uL, nullptr, &nonce_values, @@ -261,10 +315,23 @@ TEST(OdkTest, NullRequestTest) { EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioningRequest( - nullptr, 0uL, &core_message_length, nullptr, nullptr, 0uL)); + nullptr, 0uL, &core_message_length, nullptr, &counter_info)); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioningRequest(nullptr, 0uL, nullptr, - &nonce_values, nullptr, 0uL)); + &nonce_values, &counter_info)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_PrepareCoreProvisioningRequest( + nullptr, 0uL, &core_message_length, &nonce_values, nullptr)); + + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request( + nullptr, 0uL, &core_message_length, + nullptr, nullptr, 0uL, &counter_info)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request( + nullptr, 0uL, nullptr, &nonce_values, + nullptr, 0uL, &counter_info)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request( + nullptr, 0uL, &core_message_length, + &nonce_values, nullptr, 0uL, nullptr)); // Null device id in provisioning request is ok uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0}; @@ -272,7 +339,16 @@ TEST(OdkTest, NullRequestTest) { EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreProvisioningRequest( message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length, - &nonce_values, nullptr, 0uL)); + &nonce_values, &counter_info)); + + // Null device info in provisioning 4.0 request is ok + uint8_t message_prov4[ODK_PROVISIONING40_REQUEST_SIZE] = {0}; + core_message_length = ODK_PROVISIONING40_REQUEST_SIZE; + EXPECT_EQ( + OEMCrypto_SUCCESS, + ODK_PrepareCoreProvisioning40Request( + message_prov4, ODK_PROVISIONING40_REQUEST_SIZE, &core_message_length, + &nonce_values, nullptr, 0uL, &counter_info)); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreRenewedProvisioningRequest( @@ -316,26 +392,26 @@ TEST(OdkTest, NullResponseTest) { memset(&clock_values, 0, sizeof(clock_values)); // Assert that nullptr does not cause a core dump. - EXPECT_EQ( - ODK_ERROR_CORE_MESSAGE, - ODK_ParseLicense(message, message_size, core_message_length, true, true, - &timer_limits, &clock_values, &nonce_values, nullptr)); - EXPECT_EQ( - ODK_ERROR_CORE_MESSAGE, - ODK_ParseLicense(message, message_size, core_message_length, true, true, - &timer_limits, &clock_values, nullptr, &parsed_license)); - EXPECT_EQ( - ODK_ERROR_CORE_MESSAGE, - ODK_ParseLicense(message, message_size, core_message_length, true, true, - &timer_limits, nullptr, &nonce_values, &parsed_license)); - EXPECT_EQ( - ODK_ERROR_CORE_MESSAGE, - ODK_ParseLicense(message, message_size, core_message_length, true, true, - nullptr, &clock_values, &nonce_values, &parsed_license)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseLicense(message, message_size, core_message_length, true, + true, 0, &timer_limits, &clock_values, + &nonce_values, nullptr, nullptr)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseLicense(message, message_size, core_message_length, true, + true, 0, &timer_limits, &clock_values, nullptr, + &parsed_license, nullptr)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseLicense(message, message_size, core_message_length, true, + true, 0, &timer_limits, nullptr, &nonce_values, + &parsed_license, nullptr)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseLicense(message, message_size, core_message_length, true, + true, 0, nullptr, &clock_values, &nonce_values, + &parsed_license, nullptr)); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_ParseLicense(nullptr, message_size, core_message_length, true, - true, &timer_limits, &clock_values, &nonce_values, - &parsed_license)); + true, 0, &timer_limits, &clock_values, + &nonce_values, &parsed_license, nullptr)); constexpr uint64_t system_time = 0; uint64_t timer_value = 0; @@ -373,6 +449,13 @@ TEST(OdkTest, NullResponseTest) { ODK_ParseProvisioning(nullptr, message_size, core_message_length, &nonce_values, device_id, ODK_DEVICE_ID_LEN_MAX, &parsed_response)); + + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseProvisioning40(message, message_size, core_message_length, + nullptr)); + EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, + ODK_ParseProvisioning40(nullptr, message_size, core_message_length, + &nonce_values)); } TEST(OdkTest, PrepareCoreLicenseRequest) { @@ -380,9 +463,12 @@ TEST(OdkTest, PrepareCoreLicenseRequest) { size_t core_message_length = sizeof(license_message); ODK_NonceValues nonce_values; memset(&nonce_values, 0, sizeof(nonce_values)); - EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreLicenseRequest( - license_message, sizeof(license_message), - &core_message_length, &nonce_values)); + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); + EXPECT_EQ(OEMCrypto_SUCCESS, + ODK_PrepareCoreLicenseRequest( + license_message, sizeof(license_message), &core_message_length, + &nonce_values, &counter_info)); } TEST(OdkTest, PrepareCoreLicenseRequestSize) { @@ -390,18 +476,20 @@ TEST(OdkTest, PrepareCoreLicenseRequestSize) { size_t core_message_length = sizeof(license_message); ODK_NonceValues nonce_values; memset(&nonce_values, 0, sizeof(nonce_values)); + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); // message length smaller than core message length size_t core_message_length_invalid = core_message_length + 1; EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest( license_message, sizeof(license_message), - &core_message_length_invalid, &nonce_values)); + &core_message_length_invalid, &nonce_values, &counter_info)); // message length larger than core message length uint8_t license_message_large[ODK_LICENSE_REQUEST_SIZE * 2] = {0}; EXPECT_EQ(OEMCrypto_SUCCESS, - ODK_PrepareCoreLicenseRequest(license_message_large, - sizeof(license_message_large), - &core_message_length, &nonce_values)); + ODK_PrepareCoreLicenseRequest( + license_message_large, sizeof(license_message_large), + &core_message_length, &nonce_values, &counter_info)); } TEST(OdkTest, PrepareCoreRenewalRequest) { @@ -446,12 +534,27 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) { size_t core_message_length = sizeof(provisioning_message); ODK_NonceValues nonce_values; memset(&nonce_values, 0, sizeof(nonce_values)); - uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0}; - EXPECT_EQ( - OEMCrypto_SUCCESS, - ODK_PrepareCoreProvisioningRequest( - provisioning_message, sizeof(provisioning_message), - &core_message_length, &nonce_values, device_id, sizeof(device_id))); + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); + EXPECT_EQ(OEMCrypto_SUCCESS, + ODK_PrepareCoreProvisioningRequest( + provisioning_message, sizeof(provisioning_message), + &core_message_length, &nonce_values, &counter_info)); +} + +TEST(OdkTest, PrepareCoreProvisioning40Request) { + uint8_t provisioning_message[ODK_PROVISIONING40_REQUEST_SIZE] = {0}; + size_t core_message_length = sizeof(provisioning_message); + ODK_NonceValues nonce_values; + memset(&nonce_values, 0, sizeof(nonce_values)); + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); + uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0}; + EXPECT_EQ(OEMCrypto_SUCCESS, + ODK_PrepareCoreProvisioning40Request( + provisioning_message, sizeof(provisioning_message), + &core_message_length, &nonce_values, device_info, + sizeof(device_info), &counter_info)); } TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) { @@ -469,17 +572,19 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) { OEMCrypto_RenewalACert, renewal_data, sizeof(renewal_data))); } -TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) { - uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0}; +TEST(OdkTest, PrepareCoreProvisioning40RequestDeviceInfo) { + uint8_t provisioning_message[ODK_PROVISIONING40_REQUEST_SIZE] = {0}; size_t core_message_length = sizeof(provisioning_message); ODK_NonceValues nonce_values; memset(&nonce_values, 0, sizeof(nonce_values)); - uint8_t device_id_invalid[ODK_DEVICE_ID_LEN_MAX + 1] = {0}; + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); + uint8_t device_info_invalid[ODK_DEVICE_INFO_LEN_MAX + 1] = {0}; EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, - ODK_PrepareCoreProvisioningRequest( + ODK_PrepareCoreProvisioning40Request( provisioning_message, sizeof(provisioning_message), - &core_message_length, &nonce_values, device_id_invalid, - sizeof(device_id_invalid))); + &core_message_length, &nonce_values, device_info_invalid, + sizeof(device_info_invalid), &counter_info)); } TEST(OdkTest, PrepareCoreRenewedProvisioningRequestDeviceId) { @@ -514,13 +619,36 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequestRenewalDataInvalid) { // Serialize and de-serialize license request TEST(OdkTest, LicenseRequestRoundtrip) { - std::vector empty; + ODK_MessageCounterInfo counter_info; + counter_info.master_generation_number = 0x12345678abcdffff; + counter_info.provisioning_count = 12; + counter_info.license_count = 50; + counter_info.decrypt_count = 340; + counter_info.major_version = ODK_MAJOR_VERSION; + counter_info.minor_version = ODK_MINOR_VERSION; + counter_info.patch_version = 4; + memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor)); + memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model)); + memset(counter_info.extra, 0xee, sizeof(counter_info.extra)); + std::vector extra_fields = { + {ODK_MESSAGECOUNTER, &counter_info, "counter_info"}, + }; auto odk_prepare_func = [&](uint8_t* const buf, size_t* size, ODK_NonceValues* nonce_values) { - return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values); + return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values, + &counter_info); }; - auto kdo_parse_func = CoreLicenseRequestFromMessage; - ValidateRequest(ODK_License_Request_Type, empty, + auto kdo_parse_func = [&](const std::string& oemcrypto_core_message, + ODK_LicenseRequest* core_license_request) { + bool ok = CoreLicenseRequestFromMessage(oemcrypto_core_message, + core_license_request); + if (!ok) return false; + + ok = CheckCounterInfoIsEqual(&counter_info, + &core_license_request->counter_info); + return ok; + }; + ValidateRequest(ODK_License_Request_Type, extra_fields, odk_prepare_func, kdo_parse_func); } @@ -550,23 +678,38 @@ TEST(OdkTest, RenewalRequestRoundtrip) { } TEST(OdkTest, ProvisionRequestRoundtrip) { - uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX / 2; - uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0}; - memset(device_id, 0xff, device_id_length); + ODK_MessageCounterInfo counter_info; + counter_info.master_generation_number = 0x12345678abcdffff; + counter_info.provisioning_count = 12; + counter_info.license_count = 50; + counter_info.decrypt_count = 340; + counter_info.major_version = ODK_MAJOR_VERSION; + counter_info.minor_version = ODK_MINOR_VERSION; + counter_info.patch_version = 4; + memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor)); + memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model)); + memset(counter_info.extra, 0xee, sizeof(counter_info.extra)); + // Fake device_id_length for older servers, since we removed device id from + // the v18 request + uint32_t fake_device_id_length = 64; std::vector extra_fields = { - {ODK_UINT32, &device_id_length, "device_id_length"}, - {ODK_DEVICEID, device_id, "device_id"}, + {ODK_UINT32, &(fake_device_id_length), "fake_device_id_length"}, + {ODK_MESSAGECOUNTER, &counter_info, "counter_info"}, }; + auto odk_prepare_func = [&](uint8_t* const buf, size_t* size, const ODK_NonceValues* nonce_values) { return ODK_PrepareCoreProvisioningRequest(buf, SIZE_MAX, size, nonce_values, - device_id, device_id_length); + &counter_info); }; auto kdo_parse_func = [&](const std::string& oemcrypto_core_message, ODK_ProvisioningRequest* core_provisioning_request) { bool ok = CoreProvisioningRequestFromMessage(oemcrypto_core_message, core_provisioning_request); + if (!ok) return false; + ok = CheckCounterInfoIsEqual(&counter_info, + &core_provisioning_request->counter_info); return ok; }; ValidateRequest(ODK_Provisioning_Request_Type, @@ -574,6 +717,47 @@ TEST(OdkTest, ProvisionRequestRoundtrip) { kdo_parse_func); } +TEST(OdkTest, ProvisionRequest40Roundtrip) { + uint32_t device_info_length = ODK_DEVICE_INFO_LEN_MAX / 2; + uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0}; + memset(device_info, 0xaa, device_info_length); + ODK_MessageCounterInfo counter_info; + counter_info.master_generation_number = 0x12345678abcdffff; + counter_info.provisioning_count = 12; + counter_info.license_count = 50; + counter_info.decrypt_count = 340; + counter_info.major_version = ODK_MAJOR_VERSION; + counter_info.minor_version = ODK_MINOR_VERSION; + counter_info.patch_version = 4; + memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor)); + memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model)); + memset(counter_info.extra, 0xee, sizeof(counter_info.extra)); + std::vector extra_fields = { + {ODK_UINT32, &device_info_length, "device_info_length"}, + {ODK_DEVICEINFO, device_info, "device_info"}, + {ODK_MESSAGECOUNTER, &counter_info, "counter_info"}, + }; + auto odk_prepare_func = [&](uint8_t* const buf, size_t* size, + const ODK_NonceValues* nonce_values) { + return ODK_PrepareCoreProvisioning40Request( + buf, SIZE_MAX, size, nonce_values, device_info, device_info_length, + &counter_info); + }; + auto kdo_parse_func = + [&](const std::string& oemcrypto_core_message, + ODK_Provisioning40Request* core_provisioning_request) { + bool ok = CoreProvisioning40RequestFromMessage( + oemcrypto_core_message, core_provisioning_request); + if (!ok) return false; + ok = CheckCounterInfoIsEqual(&counter_info, + &core_provisioning_request->counter_info); + return ok; + }; + ValidateRequest(ODK_Provisioning40_Request_Type, + extra_fields, odk_prepare_func, + kdo_parse_func); +} + TEST(OdkTest, RenewedProvisionRequestRoundtrip) { uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX / 2; uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0}; @@ -618,9 +802,9 @@ TEST(OdkTest, ParseLicenseErrorNonce) { params.core_message.nonce_values.nonce = 0; OEMCryptoResult err = ODK_ParseLicense( buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); EXPECT_EQ(OEMCrypto_ERROR_INVALID_NONCE, err); delete[] buf; } @@ -635,9 +819,9 @@ TEST(OdkTest, ParseLicenseErrorUsageEntry) { params.usage_entry_present = false; OEMCryptoResult err = ODK_ParseLicense( buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err); delete[] buf; } @@ -653,9 +837,9 @@ TEST(OdkTest, ParseLicenseNullSubstring) { &buf_size); OEMCryptoResult result = ODK_ParseLicense( buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); EXPECT_EQ(OEMCrypto_SUCCESS, result); delete[] buf; } @@ -671,9 +855,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) { &buf_size); OEMCryptoResult err = ODK_ParseLicense( buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err); delete[] buf; @@ -687,9 +871,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) { &buf_size); err = ODK_ParseLicense( buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err); delete[] buf; } @@ -710,20 +894,50 @@ TEST(OdkTest, ParseRenewalErrorTimer) { delete[] buf; } -TEST(OdkTest, ParsePrivisioningErrorDeviceId) { - ODK_ProvisioningResponseParams params; - ODK_SetDefaultProvisioningResponseParams(¶ms); - uint8_t* buf = nullptr; - uint32_t buf_size = 0; - ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf, - &buf_size); - // temporarily mess up with device_id - params.device_id[0] = 0; - OEMCryptoResult err = ODK_ParseProvisioning( - buf, buf_size + 16, buf_size, &(params.core_message.nonce_values), - params.device_id, params.device_id_length, &(params.parsed_provisioning)); - EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err); - delete[] buf; +TEST(OdkTest, ProvisionResponseFromProto) { + std::string serialized_provisioning_resp; + EXPECT_NO_FATAL_FAILURE( + SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp)); + ODK_ProvisioningRequest core_request = { + .api_minor_version = ODK_MINOR_VERSION, + .api_major_version = ODK_MAJOR_VERSION, + .nonce = 0xdeadbeef, + .session_id = 0xcafebabe, + }; + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + std::string oemcrypto_core_message; + EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( + features, serialized_provisioning_resp, core_request, + OEMCrypto_RSA_Private_Key, &oemcrypto_core_message)); +} + +// Verify de-serialize common request. +TEST(OdkTest, ParseCoreCommonRequestFromMessage) { + std::string serialized_provisioning_resp; + EXPECT_NO_FATAL_FAILURE( + SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp)); + ODK_ProvisioningRequest core_request = { + .api_minor_version = ODK_MINOR_VERSION, + .api_major_version = ODK_MAJOR_VERSION, + .nonce = 0xdeadbeef, + .session_id = 0xcafebabe, + }; + const CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + std::string oemcrypto_core_message; + EXPECT_TRUE(CreateCoreProvisioningResponseFromProto( + features, serialized_provisioning_resp, core_request, + OEMCrypto_RSA_Private_Key, &oemcrypto_core_message)); + ODK_CommonRequest odk_common_request; + ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message, + &odk_common_request)); + EXPECT_EQ(odk_common_request.message_type, 6u); + EXPECT_EQ(odk_common_request.message_length, 48u); + EXPECT_EQ(odk_common_request.api_minor_version, ODK_MINOR_VERSION); + EXPECT_EQ(odk_common_request.api_major_version, ODK_MAJOR_VERSION); + EXPECT_EQ(odk_common_request.nonce, 0xdeadbeef); + EXPECT_EQ(odk_common_request.session_id, 0xcafebabe); } class OdkVersionTest : public ::testing::Test, @@ -735,8 +949,12 @@ class OdkVersionTest : public ::testing::Test, GetParam().response_major_version; params->core_message.nonce_values.api_minor_version = GetParam().response_minor_version; - features_ = - CoreMessageFeatures::DefaultFeatures(GetParam().maximum_major_version); + if (GetParam().maximum_major_version > 0) { + features_ = CoreMessageFeatures::DefaultFeatures( + GetParam().maximum_major_version); + } else { + features_ = CoreMessageFeatures::kDefaultFeatures; + } } CoreMessageFeatures features_; }; @@ -756,17 +974,36 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) { auto odk_parse_func = [&](const uint8_t* buf, size_t size) { return ODK_ParseLicense( buf, size + kExtraPayloadSize, size, params.initial_license_load, - params.usage_entry_present, &(params.timer_limits), + params.usage_entry_present, 0, &(params.timer_limits), &(params.clock_values), &(params.core_message.nonce_values), - &(params.parsed_license)); + &(params.parsed_license), nullptr); }; + + ODK_Packing_ParsedLicense parsed_license; + parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv; + parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys; + parsed_license.pst = params.parsed_license.pst; + parsed_license.srm_restriction_data = + params.parsed_license.srm_restriction_data; + parsed_license.license_type = params.parsed_license.license_type; + parsed_license.nonce_required = params.parsed_license.nonce_required; + parsed_license.timer_limits = params.parsed_license.timer_limits; + parsed_license.watermarking = params.parsed_license.watermarking; + parsed_license.dtcp2_required = params.parsed_license.dtcp2_required; + parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base; + parsed_license.key_array_length = params.parsed_license.key_array_length; + std::vector key_array; + for (size_t i = 0; i < params.parsed_license.key_array_length; i++) { + key_array.push_back(params.parsed_license.key_array[i]); + } + parsed_license.key_array = key_array.data(); const std::string request_hash_string( reinterpret_cast(request_hash_read), sizeof(request_hash_read)); auto kdo_prepare_func = [&](const ODK_LicenseRequest& core_request, std::string* oemcrypto_core_message) { - return CreateCoreLicenseResponse(features_, params.parsed_license, - core_request, request_hash_string, + return CreateCoreLicenseResponse(features_, parsed_license, core_request, + request_hash_string, oemcrypto_core_message); }; ValidateResponse(GetParam(), &(params.core_message), @@ -774,6 +1011,84 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) { kdo_prepare_func); } +// Serialize and de-serialize license response with more keys than +// ODK_MAX_NUM_KEYS. +TEST_P(OdkVersionTest, LicenseResponseRoundtripMoreThanMaxKeys) { + ODK_LicenseResponseParams params; + ODK_SetDefaultLicenseResponseParams(¶ms, + GetParam().response_major_version); + SetRequestVersion(¶ms); + // For v17, we do not use the hash to verify the request. However, the server + // needs to be backwards compatible, so it still needs to pass the hash into + // CreateCoreLiceseseResponse below. Save a copy of params.request_hash as it + // will be zero out during the test + uint8_t request_hash_read[ODK_SHA256_HASH_SIZE]; + memcpy(request_hash_read, params.request_hash, sizeof(request_hash_read)); + uint8_t* buf = nullptr; + uint32_t buf_size = 0; + ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf, + &buf_size); + + uint8_t* zero = new uint8_t[buf_size]{}; + size_t bytes_read = 0; + // zero-out input + EXPECT_EQ(OEMCrypto_SUCCESS, + ODK_IterFields(ODK_READ, zero, buf_size, &bytes_read, + params.extra_fields)); + + // Parse buf with odk + const OEMCryptoResult parse_result = ODK_ParseLicense( + buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, + params.usage_entry_present, 0, &(params.timer_limits), + &(params.clock_values), &(params.core_message.nonce_values), + &(params.parsed_license), nullptr); + EXPECT_EQ(OEMCrypto_SUCCESS, parse_result); + + size_t size_out = 0; + if (parse_result != OEMCrypto_SUCCESS) { + ODK_IterFields(ODK_FieldMode::ODK_DUMP, buf, buf_size, &size_out, + params.extra_fields); + } + + ODK_Packing_ParsedLicense parsed_license; + parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv; + parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys; + parsed_license.pst = params.parsed_license.pst; + parsed_license.srm_restriction_data = + params.parsed_license.srm_restriction_data; + parsed_license.license_type = params.parsed_license.license_type; + parsed_license.nonce_required = params.parsed_license.nonce_required; + parsed_license.timer_limits = params.parsed_license.timer_limits; + parsed_license.watermarking = params.parsed_license.watermarking; + parsed_license.dtcp2_required = params.parsed_license.dtcp2_required; + parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base; + parsed_license.key_array_length = ODK_MAX_NUM_KEYS + 1; + std::vector key_array; + for (size_t i = 0; i < ODK_MAX_NUM_KEYS + 1; i++) { + OEMCrypto_KeyObject key = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; + key_array.push_back(key); + } + parsed_license.key_array = key_array.data(); + const std::string request_hash_string( + reinterpret_cast(request_hash_read), + sizeof(request_hash_read)); + + // serialize odk output to oemcrypto_core_message + std::string oemcrypto_core_message; + ODK_LicenseRequest core_request = {}; + core_request.api_major_version = GetParam().request_major_version; + core_request.api_minor_version = GetParam().request_minor_version; + core_request.nonce = params.core_message.nonce_values.nonce; + core_request.session_id = params.core_message.nonce_values.session_id; + bool result = + CreateCoreLicenseResponse(features_, parsed_license, core_request, + request_hash_string, &oemcrypto_core_message); + EXPECT_FALSE(result); + + delete[] buf; + delete[] zero; +} + TEST_P(OdkVersionTest, RenewalResponseRoundtrip) { ODK_RenewalResponseParams params; ODK_SetDefaultRenewalResponseParams(¶ms); @@ -806,7 +1121,8 @@ TEST_P(OdkVersionTest, RenewalResponseRoundtrip) { TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) { ODK_ProvisioningResponseParams params; - ODK_SetDefaultProvisioningResponseParams(¶ms); + ODK_SetDefaultProvisioningResponseParams(¶ms, + GetParam().response_major_version); SetRequestVersion(¶ms); // save a copy of params.device_id as it will be zero out during the test const uint32_t device_id_length = params.device_id_length; @@ -821,8 +1137,12 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) { }; auto kdo_prepare_func = [&](ODK_ProvisioningRequest& core_request, std::string* oemcrypto_core_message) { + // use device_id for V17 and V16 core_request.device_id.assign(reinterpret_cast(device_id), device_id_length); + // use counter info for V18 + memcpy(&core_request.counter_info, ¶ms.counter_info, + sizeof(params.counter_info)); return CreateCoreProvisioningResponse(features_, params.parsed_provisioning, core_request, oemcrypto_core_message); }; @@ -831,12 +1151,30 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) { kdo_prepare_func); } +TEST_P(OdkVersionTest, Provision40ResponseRoundtrip) { + ODK_Provisioning40ResponseParams params; + ODK_SetDefaultProvisioning40ResponseParams(¶ms); + SetRequestVersion(¶ms); + + auto odk_parse_func = [&](const uint8_t* buf, size_t size) { + OEMCryptoResult err = ODK_ParseProvisioning40( + buf, size + 16, size, &(params.core_message.nonce_values)); + return err; + }; + auto kdo_prepare_func = [&](ODK_Provisioning40Request& core_request, + std::string* oemcrypto_core_message) { + return CreateCoreProvisioning40Response(features_, core_request, + oemcrypto_core_message); + }; + ValidateResponse( + GetParam(), &(params.core_message), params.extra_fields, odk_parse_func, + kdo_prepare_func); +} + // If the minor version is positive, we can test an older minor version. const uint16_t kOldMinor = ODK_MINOR_VERSION > 0 ? ODK_MINOR_VERSION - 1 : 0; // Similarly, if this isn't the first major version, we can test an older major // version. -// TODO(b/163416999): Remove it in the future. This will be unecessarily -// complicated after we upgrade to version 17. const uint16_t kOldMajor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION ? ODK_MAJOR_VERSION - 1 : ODK_FIRST_VERSION; @@ -862,17 +1200,25 @@ std::vector TestCases() { {ODK_MAJOR_VERSION, kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor}, // If the server is restricted to v16, then the response can be at // most 16.5 + // These tests cases must be updated whenever we roll the minor version + // number. {16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5}, + {17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2}, + {18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 2}, // Here are some known good versions. Make extra sure they work. - {16, 16, 3, 16, 3}, - {16, 16, 4, 16, 4}, - {16, 16, 5, 16, 5}, - {17, 16, 3, 16, 3}, - {17, 16, 4, 16, 4}, - {17, 16, 5, 16, 5}, - {17, 17, 0, 17, 0}, - {17, 17, 1, 17, 1}, - {17, 17, 2, 17, 2}, + {ODK_MAJOR_VERSION, 16, 3, 16, 3}, + {ODK_MAJOR_VERSION, 16, 4, 16, 4}, + {ODK_MAJOR_VERSION, 16, 5, 16, 5}, + {ODK_MAJOR_VERSION, 17, 1, 17, 1}, + {ODK_MAJOR_VERSION, 17, 2, 17, 2}, + {ODK_MAJOR_VERSION, 18, 1, 18, 1}, + {ODK_MAJOR_VERSION, 18, 2, 18, 2}, + {0, 16, 3, 16, 3}, + {0, 16, 4, 16, 4}, + {0, 16, 5, 16, 5}, + {0, 17, 1, 17, 1}, + {0, 17, 2, 17, 2}, + {0, 18, 2, 18, 2}, // Change to 19 when the default version is updated. }; return test_cases; } @@ -888,11 +1234,14 @@ TEST(OdkSizeTest, LicenseRequest) { uint16_t api_major_version = 0; uint32_t nonce = 0; uint32_t session_id = 0; + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce, session_id}; EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, ODK_PrepareCoreLicenseRequest(message, message_length, - &core_message_length, &nonce_values)); + &core_message_length, &nonce_values, + &counter_info)); // the core_message_length should be appropriately set EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length); } @@ -949,13 +1298,14 @@ TEST(OdkSizeTest, ProvisioningRequest) { uint16_t api_major_version = 0; uint32_t nonce = 0; uint32_t session_id = 0; - uint32_t device_id_length = 0; + ODK_MessageCounterInfo counter_info; + memset(&counter_info, 0, sizeof(counter_info)); ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce, session_id}; EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - ODK_PrepareCoreProvisioningRequest( - message, message_length, &core_message_length, &nonce_values, - nullptr, device_id_length)); + ODK_PrepareCoreProvisioningRequest(message, message_length, + &core_message_length, + &nonce_values, &counter_info)); // the core_message_length should be appropriately set EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length); } @@ -971,6 +1321,37 @@ TEST(OdkTest, CheckReleaseVersion) { << "Version mismatch in odk_structs.h"; } +TEST(OdkOverflowTest, SubtractU64) { + uint64_t result = 0; + EXPECT_FALSE(odk_sub_overflow_u64(10, 5, &result)); + EXPECT_EQ(result, static_cast(10 - 5)); + EXPECT_TRUE(odk_sub_overflow_u64(5, 10, &result)); +} + +TEST(OdkOverflowTest, AddU64) { + uint64_t result = 0; + EXPECT_FALSE(odk_add_overflow_u64(2, 2, &result)); + EXPECT_EQ(result, static_cast(2 + 2)); + EXPECT_TRUE(odk_add_overflow_u64(0xffffffffffffffff, 1, &result)); + EXPECT_TRUE(odk_add_overflow_u64(1, 0xffffffffffffffff, &result)); +} + +TEST(OdkOverflowTest, AddUX) { + size_t result = 0; + EXPECT_FALSE(odk_add_overflow_ux(2, 2, &result)); + EXPECT_EQ(result, static_cast(2 + 2)); + EXPECT_TRUE(odk_add_overflow_ux(SIZE_MAX, 1, &result)); + EXPECT_TRUE(odk_add_overflow_ux(1, SIZE_MAX, &result)); +} + +TEST(OdkOverflowTest, MultiplyUX) { + size_t result = 0; + EXPECT_FALSE(odk_mul_overflow_ux(2, 7, &result)); + EXPECT_EQ(result, static_cast(2 * 7)); + EXPECT_TRUE(odk_mul_overflow_ux(SIZE_MAX >> 1, 4, &result)); + EXPECT_TRUE(odk_mul_overflow_ux(4, SIZE_MAX >> 1, &result)); +} + } // namespace } // namespace wvodk_test diff --git a/oemcrypto/odk/test/odk_test.gypi b/oemcrypto/odk/test/odk_test.gypi index 4eb3b186..1b5c5e7f 100644 --- a/oemcrypto/odk/test/odk_test.gypi +++ b/oemcrypto/odk/test/odk_test.gypi @@ -6,6 +6,7 @@ 'sources': [ 'odk_golden_v16.cpp', 'odk_golden_v17.cpp', + 'odk_golden_v18.cpp', 'odk_test.cpp', 'odk_test_helper.cpp', 'odk_test_helper.h', diff --git a/oemcrypto/odk/test/odk_test_helper.cpp b/oemcrypto/odk/test/odk_test_helper.cpp index dab9afa3..db9b2f2c 100644 --- a/oemcrypto/odk/test/odk_test_helper.cpp +++ b/oemcrypto/odk/test/odk_test_helper.cpp @@ -8,7 +8,10 @@ #include #include #include +#include +#include #include +#include #include #include @@ -75,6 +78,7 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params, .length = 3, .data = {0, 0, 0}, }}, + .renewal_delay_base = OEMCrypto_License_Start, .key_array_length = 3, .key_array = { @@ -203,6 +207,11 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params, ".cmi_descriptor_data"}); } } + if (odk_major_version >= 18) { + params->extra_fields.push_back( + {ODK_UINT32, &(params->parsed_license.renewal_delay_base), + ".renewal_delay_base"}); + } params->extra_fields.push_back({ODK_UINT32, &(params->parsed_license.key_array_length), ".key_array_length"}); @@ -288,7 +297,7 @@ void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params) { } void ODK_SetDefaultProvisioningResponseParams( - ODK_ProvisioningResponseParams* params) { + ODK_ProvisioningResponseParams* params, uint32_t odk_major_version) { ODK_SetDefaultCoreFields(&(params->core_message), ODK_Provisioning_Response_Type); params->device_id_length = ODK_DEVICE_ID_LEN_MAX / 2; @@ -301,17 +310,34 @@ void ODK_SetDefaultProvisioningResponseParams( .enc_private_key_iv = {.offset = 2, .length = 3}, .encrypted_message_key = {.offset = 4, .length = 5}, }; - params->extra_fields = { - {ODK_UINT32, &(params->device_id_length), "device_id_length"}, - {ODK_DEVICEID, params->device_id, "device_id"}, - {ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"}, + + params->extra_fields = {}; + // V17 uses device_id + if (odk_major_version <= 17) { + params->extra_fields.push_back( + {ODK_UINT32, &(params->device_id_length), "device_id_length"}); + params->extra_fields.push_back( + {ODK_DEVICEID, params->device_id, "device_id"}); + } + + params->extra_fields.push_back( + {ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"}); + params->extra_fields.push_back( {ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key, - "enc_private_key"}, + "enc_private_key"}); + params->extra_fields.push_back( {ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key_iv, - "enc_private_key_iv"}, + "enc_private_key_iv"}); + params->extra_fields.push_back( {ODK_SUBSTRING, &(params->parsed_provisioning).encrypted_message_key, - "encrypted_message_key"}, - }; + "encrypted_message_key"}); +} + +void ODK_SetDefaultProvisioning40ResponseParams( + ODK_Provisioning40ResponseParams* params) { + ODK_SetDefaultCoreFields(&(params->core_message), + ODK_Provisioning_Response_Type); + params->extra_fields = {}; } size_t ODK_FieldLength(ODK_FieldType type) { @@ -330,6 +356,10 @@ size_t ODK_FieldLength(ODK_FieldType type) { return sizeof(uint32_t) + sizeof(uint32_t); case ODK_DEVICEID: return ODK_DEVICE_ID_LEN_MAX; + case ODK_MESSAGECOUNTER: + return ODK_MESSAGECOUNTERINFO_SIZE; + case ODK_DEVICEINFO: + return ODK_DEVICE_INFO_LEN_MAX; case ODK_RENEWALDATA: return ODK_KEYBOX_RENEWAL_DATA_SIZE; case ODK_HASH: @@ -343,6 +373,9 @@ size_t ODK_AllocSize(ODK_FieldType type) { if (type == ODK_SUBSTRING) { return sizeof(OEMCrypto_Substring); } + if (type == ODK_MESSAGECOUNTER) { + return sizeof(ODK_MessageCounterInfo); + } return ODK_FieldLength(type); } @@ -388,6 +421,7 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) { break; } case ODK_DEVICEID: + case ODK_DEVICEINFO: case ODK_RENEWALDATA: case ODK_HASH: { const size_t field_len = ODK_FieldLength(field->type); @@ -396,6 +430,27 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) { break; } + case ODK_MESSAGECOUNTER: { + // Size required in field->value, which may get padding from the compiler. + const size_t src_len = ODK_AllocSize(field->type); + // Size taken up in serialized message buffer, which is tightly packed. + const size_t dest_len = ODK_FieldLength(field->type); + const uint8_t* const write_src = static_cast(field->value); + + // Copy data from field to buf, fixing endian-ness + ODK_MessageCounterInfo info; + memcpy(&info, write_src, src_len); + info.master_generation_number = + oemcrypto_htobe64(info.master_generation_number); + info.provisioning_count = oemcrypto_htobe32(info.provisioning_count); + info.license_count = oemcrypto_htobe32(info.license_count); + info.decrypt_count = oemcrypto_htobe32(info.decrypt_count); + info.major_version = oemcrypto_htobe16(info.major_version); + info.minor_version = oemcrypto_htobe16(info.minor_version); + info.patch_version = oemcrypto_htobe16(info.patch_version); + memcpy(buf, &info, dest_len); + break; + } default: return ODK_ERROR_CORE_MESSAGE; } @@ -448,6 +503,7 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, break; } case ODK_DEVICEID: + case ODK_DEVICEINFO: case ODK_RENEWALDATA: case ODK_HASH: { const size_t field_len = ODK_FieldLength(field->type); @@ -455,6 +511,55 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, memcpy(id, buf, field_len); break; } + case ODK_MESSAGECOUNTER: { + // Size required in field->value, which may get padding from the compiler. + const size_t dest_len = ODK_AllocSize(field->type); + // Size taken up in serialized message buffer, which is tightly packed. + const size_t src_len = ODK_FieldLength(field->type); + uint8_t* const read_dest = static_cast(field->value); + + // Copy data from buf to field, fixing endian-ness + uint8_t temp_buf[sizeof(ODK_MessageCounterInfo)] = {0}; + memcpy(temp_buf, buf, src_len); + + size_t index = 0; + ODK_MessageCounterInfo info; + uint64_t* u64 = reinterpret_cast(&temp_buf[index]); + info.master_generation_number = oemcrypto_be64toh(*u64); + index += sizeof(uint64_t); + + uint32_t* u32 = reinterpret_cast(&temp_buf[index]); + info.provisioning_count = oemcrypto_be32toh(*u32); + index += sizeof(uint32_t); + + u32 = reinterpret_cast(&temp_buf[index]); + info.license_count = oemcrypto_be32toh(*u32); + index += sizeof(uint32_t); + + u32 = reinterpret_cast(&temp_buf[index]); + info.decrypt_count = oemcrypto_be32toh(*u32); + index += sizeof(uint32_t); + + uint16_t* u16 = reinterpret_cast(&temp_buf[index]); + info.major_version = oemcrypto_be16toh(*u16); + index += sizeof(uint16_t); + + u16 = reinterpret_cast(&temp_buf[index]); + info.minor_version = oemcrypto_be16toh(*u16); + index += sizeof(uint16_t); + + u16 = reinterpret_cast(&temp_buf[index]); + info.patch_version = oemcrypto_be16toh(*u16); + index += sizeof(uint16_t); + + memcpy(info.soc_vendor, &temp_buf[index], sizeof(info.soc_vendor)); + index += sizeof(info.soc_vendor); + memcpy(info.chipset_model, &temp_buf[index], sizeof(info.chipset_model)); + index += sizeof(info.chipset_model); + memcpy(info.extra, &temp_buf[index], sizeof(info.extra)); + memcpy(read_dest, &info, dest_len); + break; + } default: return ODK_ERROR_CORE_MESSAGE; } @@ -508,6 +613,8 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, break; } case ODK_DEVICEID: + case ODK_MESSAGECOUNTER: + case ODK_DEVICEINFO: case ODK_RENEWALDATA: case ODK_HASH: { const size_t field_len = ODK_FieldLength(field->type); diff --git a/oemcrypto/odk/test/odk_test_helper.h b/oemcrypto/odk/test/odk_test_helper.h index f825af13..b0042332 100644 --- a/oemcrypto/odk/test/odk_test_helper.h +++ b/oemcrypto/odk/test/odk_test_helper.h @@ -21,6 +21,8 @@ enum ODK_FieldType { ODK_UINT64, ODK_SUBSTRING, ODK_DEVICEID, + ODK_DEVICEINFO, + ODK_MESSAGECOUNTER, ODK_RENEWALDATA, ODK_HASH, // The "stressable" types are the ones we can put in a stress test that packs @@ -71,10 +73,17 @@ struct ODK_ProvisioningResponseParams { ODK_CoreMessage core_message; uint8_t device_id[ODK_DEVICE_ID_LEN_MAX]; uint32_t device_id_length; + uint32_t padding_u32; + ODK_MessageCounterInfo counter_info; ODK_ParsedProvisioning parsed_provisioning; std::vector extra_fields; }; +struct ODK_Provisioning40ResponseParams { + ODK_CoreMessage core_message; + std::vector extra_fields; +}; + // Default values in core_message for testing void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message, ODK_MessageType message_type); @@ -82,7 +91,9 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params, uint32_t odk_major_version); void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params); void ODK_SetDefaultProvisioningResponseParams( - ODK_ProvisioningResponseParams* params); + ODK_ProvisioningResponseParams* params, uint32_t odk_major_version); +void ODK_SetDefaultProvisioning40ResponseParams( + ODK_Provisioning40ResponseParams* params); size_t ODK_FieldLength(ODK_FieldType type); size_t ODK_AllocSize(ODK_FieldType type); @@ -92,8 +103,8 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field); // Load buf to ODK_Field OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, const ODK_Field* field); OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, const ODK_Field* field); -OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf, - const size_t size_in, size_t* size_out, +OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf, size_t size_in, + size_t* size_out, const std::vector& fields); void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n, const std::vector& fields); diff --git a/oemcrypto/odk/test/odk_timer_test.cpp b/oemcrypto/odk/test/odk_timer_test.cpp index 84139608..b595d980 100644 --- a/oemcrypto/odk/test/odk_timer_test.cpp +++ b/oemcrypto/odk/test/odk_timer_test.cpp @@ -6,7 +6,9 @@ #include "OEMCryptoCENCCommon.h" #include "gtest/gtest.h" #include "odk.h" +#include "odk_structs.h" #include "odk_structs_priv.h" +#include "odk_test_helper.h" namespace { @@ -23,6 +25,99 @@ constexpr uint64_t kRentalClockStart = 1000u; // renewal is not loaded. constexpr uint64_t kGracePeriod = 5u; +constexpr uint32_t kExtraPayloadSize = 128u; + +constexpr uint32_t kSystemTime = 20u; + +namespace wvodk_test { + +TEST(OdkTimerBasicTest, ParseLicenseTimerSet) { + // playback timer is successfully started + ::wvodk_test::ODK_LicenseResponseParams params; + ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION); + params.parsed_license.renewal_delay_base = OEMCrypto_License_Load; + params.parsed_license.timer_limits.soft_enforce_rental_duration = false; + params.parsed_license.timer_limits.soft_enforce_playback_duration = false; + params.parsed_license.timer_limits.earliest_playback_start_seconds = 10; + params.parsed_license.timer_limits.total_playback_duration_seconds = 0; + params.parsed_license.timer_limits.rental_duration_seconds = 10; + params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0; + OEMCryptoResult result = + ODK_InitializeClockValues(¶ms.clock_values, kSystemTime); + EXPECT_EQ(OEMCrypto_SUCCESS, result); + params.clock_values.time_of_license_request_signed = 5; + params.clock_values.status = kActive; + + uint8_t* buf = nullptr; + uint32_t buf_size = 0; + ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf, + &buf_size); + + result = ODK_ParseLicense( + buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, + params.usage_entry_present, kSystemTime, &(params.timer_limits), + &(params.clock_values), &(params.core_message.nonce_values), + &(params.parsed_license), nullptr); + EXPECT_EQ(ODK_SET_TIMER, result); + delete[] buf; +} + +TEST(OdkTimerBasicTest, ParseLicenseTimerDisabled) { + // playback timer is successfully started + ::wvodk_test::ODK_LicenseResponseParams params; + ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION); + params.parsed_license.renewal_delay_base = OEMCrypto_License_Load; + params.parsed_license.timer_limits.soft_enforce_rental_duration = true; + params.parsed_license.timer_limits.earliest_playback_start_seconds = 3; + params.parsed_license.timer_limits.total_playback_duration_seconds = 0; + params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0; + params.clock_values.time_of_first_decrypt = 10; + params.clock_values.time_of_license_request_signed = 5; + params.clock_values.status = kActive; + + uint8_t* buf = nullptr; + uint32_t buf_size = 0; + ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf, + &buf_size); + + OEMCryptoResult result = ODK_ParseLicense( + buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, + params.usage_entry_present, kSystemTime, &(params.timer_limits), + &(params.clock_values), &(params.core_message.nonce_values), + &(params.parsed_license), nullptr); + EXPECT_EQ(ODK_DISABLE_TIMER, result); + delete[] buf; +} + +TEST(OdkTimerBasicTest, ParseRenewalTimerExpired) { + // playback timer is successfully started + ::wvodk_test::ODK_LicenseResponseParams params; + ODK_SetDefaultLicenseResponseParams(¶ms, ODK_MAJOR_VERSION); + + params.parsed_license.renewal_delay_base = OEMCrypto_License_Load; + params.parsed_license.timer_limits.rental_duration_seconds = 5; + params.parsed_license.timer_limits.earliest_playback_start_seconds = 3; + OEMCryptoResult result = + ODK_InitializeClockValues(¶ms.clock_values, kSystemTime); + EXPECT_EQ(OEMCrypto_SUCCESS, result); + params.clock_values.time_of_license_request_signed = 5; + + uint8_t* buf = nullptr; + uint32_t buf_size = 0; + ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf, + &buf_size); + + result = ODK_ParseLicense( + buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load, + params.usage_entry_present, kSystemTime, &(params.timer_limits), + &(params.clock_values), &(params.core_message.nonce_values), + &(params.parsed_license), nullptr); + EXPECT_EQ(ODK_TIMER_EXPIRED, result); + delete[] buf; +} + +} // namespace wvodk_test + TEST(OdkTimerBasicTest, NullTest) { // Assert that nullptr does not cause a core dump. ODK_InitializeClockValues(nullptr, 0u); diff --git a/oemcrypto/test/GEN_api_lock_file.c b/oemcrypto/test/GEN_api_lock_file.c index 37e577e6..2a29201b 100644 --- a/oemcrypto/test/GEN_api_lock_file.c +++ b/oemcrypto/test/GEN_api_lock_file.c @@ -304,3 +304,65 @@ OEMCryptoResult _oecc120(OEMCrypto_SESSION session, const uint8_t* message, // OEMCrypto_GetOEMKeyToken defined in v17.2 OEMCryptoResult _oecc130(OEMCrypto_SESSION key_session, uint8_t* key_token, size_t* key_token_length); + +// OEMCrypto_SetMaxAPIVersion defined in v18.1 +OEMCryptoResult _oecc132(uint32_t max_version); + +// OEMCrypto_GetKeyHandle defined in v18.1 +OEMCryptoResult _oecc133(OEMCrypto_SESSION session, + const uint8_t* content_key_id, + size_t content_key_id_length, + OEMCryptoCipherMode cipher_mode, uint8_t* key_handle, + size_t* key_handle_length); + +// OEMCrypto_DecryptCENC defined in v18.1 +OEMCryptoResult _oecc134( + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription* samples, // an array of samples. + size_t samples_length, // the number of samples. + const OEMCrypto_CENCEncryptPatternDesc* pattern); + +// OEMCrypto_Generic_Encrypt defined in v18.1 +OEMCryptoResult _oecc135(const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); + +// OEMCrypto_Generic_Decrypt defined in v18.1 +OEMCryptoResult _oecc136(const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* in_buffer, + size_t in_buffer_length, const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* out_buffer); + +// OEMCrypto_Generic_Sign defined in v18.1 +OEMCryptoResult _oecc137(const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + OEMCrypto_SharedMemory* signature, + size_t* signature_length); + +// OEMCrypto_Generic_Verify defined in v18.1 +OEMCryptoResult _oecc138(const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SharedMemory* buffer, + size_t buffer_length, OEMCrypto_Algorithm algorithm, + const OEMCrypto_SharedMemory* signature, + size_t signature_length); + +// OEMCrypto_GetSignatureHashAlgorithm defined in v18.1 +OEMCryptoResult _oecc139(OEMCrypto_SESSION session, + OEMCrypto_SignatureHashAlgorithm* algorithm); + +// OEMCrypto_GetDeviceInformation defined in v18.1 +OEMCryptoResult _oecc131(uint8_t* device_info, size_t* device_info_length); + +// OEMCrypto_GetDeviceSignedCsrPayload defined in v18.1 +OEMCryptoResult _oecc141(const uint8_t* challenge, size_t challenge_length, + const uint8_t* encoded_device_info, + size_t encoded_device_info_length, + uint8_t* signed_csr_payload, + size_t* signed_csr_payload_length); + +// OEMCrypto_EnterTestMode defined in v18.1 +OEMCryptoResult _oecc140(void); diff --git a/oemcrypto/test/fuzz_tests/README.md b/oemcrypto/test/fuzz_tests/README.md index f4e86710..e1b7b9ca 100644 --- a/oemcrypto/test/fuzz_tests/README.md +++ b/oemcrypto/test/fuzz_tests/README.md @@ -23,7 +23,7 @@ OEMCrypto implementations on linux. The options to select are `Job type: libfuzzer_asan_oemcrypto` and `Fuzzer: fuzzer name you are looking for` - Example: [load_license_fuzz](https://clusterfuzz.corp.google.com/fuzzer-stats?group_by=by-day&date_start=2020-07-11&date_end=2020-07-17&fuzzer=libFuzzer_oemcrypto_load_license_fuzz&job=libfuzzer_asan_oemcrypto) + Example: [load_license_fuzz](https://clusterfuzz.corp.google.com/fuzzer-stats?group_by=by-day&date_start=2022-07-11&date_end=2022-07-17&fuzzer=libFuzzer_oemcrypto_load_license_fuzz&job=libfuzzer_asan_oemcrypto) ### Issues filed by clusterfuzz - Fixing those issues diff --git a/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests b/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests index e1648604..249616b3 100755 --- a/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests +++ b/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests @@ -23,5 +23,6 @@ export PYTHONPATH="$PYTHONPATH:$CDM_DIR/third_party" python3 $CDM_DIR/third_party/gyp/__init__.py --format=ninja \ --depth=$(pwd) \ --include=oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi \ + -Dopk_config_dir=$CDM_DIR/oemcrypto/opk/ports/linux/ta/common \ oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp ninja -C out/Default diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0567e5f52c00fed0ad7858164434b02d8e629064 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0567e5f52c00fed0ad7858164434b02d8e629064 deleted file mode 100644 index 08541f45..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0567e5f52c00fed0ad7858164434b02d8e629064 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/618cdf5927b2b092d9d7b5e93c30af8708270f11 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/06ae1005d93d4a19b67d090a020ae37db54e6e3e similarity index 53% rename from oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/618cdf5927b2b092d9d7b5e93c30af8708270f11 rename to oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/06ae1005d93d4a19b67d090a020ae37db54e6e3e index dc58149e..d2cfb477 100644 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/618cdf5927b2b092d9d7b5e93c30af8708270f11 and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/06ae1005d93d4a19b67d090a020ae37db54e6e3e differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0f5cc252aaf43eaa1570ca07d174a0f96333c592 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0f5cc252aaf43eaa1570ca07d174a0f96333c592 deleted file mode 100644 index 6f71c2eb..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0f5cc252aaf43eaa1570ca07d174a0f96333c592 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0fdcae4df7bc325099fb4b3b01a1c9290229f86c b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0fdcae4df7bc325099fb4b3b01a1c9290229f86c deleted file mode 100644 index 6f61946d..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/0fdcae4df7bc325099fb4b3b01a1c9290229f86c and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/1ee4b9ce1a4acc41e912487383ad77f3ccaa97fb b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/1ee4b9ce1a4acc41e912487383ad77f3ccaa97fb deleted file mode 100644 index cab8c502..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/1ee4b9ce1a4acc41e912487383ad77f3ccaa97fb and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2d7246bd48ed8b68599445c98bb822c87f86acd1 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2d7246bd48ed8b68599445c98bb822c87f86acd1 deleted file mode 100644 index 0aded9db..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2d7246bd48ed8b68599445c98bb822c87f86acd1 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2f64b8ffa25844924fe24678067feee9be80f4ec b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2f64b8ffa25844924fe24678067feee9be80f4ec deleted file mode 100644 index 7aac2f96..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/2f64b8ffa25844924fe24678067feee9be80f4ec and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/3acf30d485a4370ceb8e64785094a50b768e1ca4 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/3acf30d485a4370ceb8e64785094a50b768e1ca4 deleted file mode 100644 index 57edbd78..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/3acf30d485a4370ceb8e64785094a50b768e1ca4 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/461c08228ae6a0eaa191d24eea1823b46f4a9d67 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/461c08228ae6a0eaa191d24eea1823b46f4a9d67 deleted file mode 100644 index 591c0e9d..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/461c08228ae6a0eaa191d24eea1823b46f4a9d67 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/4b69b92f45febc4dbf5b8fb9a216a290ba51d478 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/4b69b92f45febc4dbf5b8fb9a216a290ba51d478 deleted file mode 100644 index 0a09fb4f..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/4b69b92f45febc4dbf5b8fb9a216a290ba51d478 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5891055a8932cac4c24862377ab912ff6d775247 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5891055a8932cac4c24862377ab912ff6d775247 new file mode 100644 index 00000000..77e52073 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5891055a8932cac4c24862377ab912ff6d775247 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/592f446db007b4db2d056983a7bb098bf021babe b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/592f446db007b4db2d056983a7bb098bf021babe new file mode 100644 index 00000000..72a258ee Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/592f446db007b4db2d056983a7bb098bf021babe differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5db53de009652f61b1ed21ee988d0156ce287033 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5db53de009652f61b1ed21ee988d0156ce287033 deleted file mode 100644 index dc80cb88..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/5db53de009652f61b1ed21ee988d0156ce287033 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/642df2594991f9b5720fce364d0001d8c56d3a89 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/642df2594991f9b5720fce364d0001d8c56d3a89 new file mode 100644 index 00000000..e81aa3f6 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/642df2594991f9b5720fce364d0001d8c56d3a89 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/6449230f671fe77b73dc6e0d40f542c0720628f2 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/6449230f671fe77b73dc6e0d40f542c0720628f2 new file mode 100644 index 00000000..8a8e73c4 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/6449230f671fe77b73dc6e0d40f542c0720628f2 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/78e527f05b03c2ecd8a0ffc2baeb5dab57088934 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/78e527f05b03c2ecd8a0ffc2baeb5dab57088934 deleted file mode 100644 index bd4f8760..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/78e527f05b03c2ecd8a0ffc2baeb5dab57088934 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7e120b1ec852c448490b9b060a5f35deb486c360 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7e120b1ec852c448490b9b060a5f35deb486c360 deleted file mode 100644 index 9bed2849..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7e120b1ec852c448490b9b060a5f35deb486c360 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7f701c0f31e68192bc8c829f343fa2326aa4d3dc b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7f701c0f31e68192bc8c829f343fa2326aa4d3dc deleted file mode 100644 index 7cd10afe..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7f701c0f31e68192bc8c829f343fa2326aa4d3dc and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/134a0d85fbcbe367e66d69127114bece71add806 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/81d43836885e32dc8c2b187cb9545bd5c01dfef5 similarity index 54% rename from oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/134a0d85fbcbe367e66d69127114bece71add806 rename to oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/81d43836885e32dc8c2b187cb9545bd5c01dfef5 index 70ed9c59..9fc97a34 100644 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/134a0d85fbcbe367e66d69127114bece71add806 and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/81d43836885e32dc8c2b187cb9545bd5c01dfef5 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8243212a7a7160c91e2f9717b855b568f9a34233 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8243212a7a7160c91e2f9717b855b568f9a34233 deleted file mode 100644 index 352ae2ed..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8243212a7a7160c91e2f9717b855b568f9a34233 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/85bff933def1ce530a1febd93ef2890ed4bcdcb5 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/85bff933def1ce530a1febd93ef2890ed4bcdcb5 deleted file mode 100644 index 1e5f3405..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/85bff933def1ce530a1febd93ef2890ed4bcdcb5 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8aeedd64cffd1f59badda7c7e62150d0e7ed4065 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8aeedd64cffd1f59badda7c7e62150d0e7ed4065 new file mode 100644 index 00000000..24fd910f Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/8aeedd64cffd1f59badda7c7e62150d0e7ed4065 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/903224efa0cc5213ac2aefdf1191d05c703343f6 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/903224efa0cc5213ac2aefdf1191d05c703343f6 new file mode 100644 index 00000000..96f694c0 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/903224efa0cc5213ac2aefdf1191d05c703343f6 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a06905d0b9421966c527b5ef2ac68bdce1e0cfe5 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a06905d0b9421966c527b5ef2ac68bdce1e0cfe5 deleted file mode 100644 index 02ccf562..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a06905d0b9421966c527b5ef2ac68bdce1e0cfe5 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a3ea4b0c65a01f18d11ad39862b9ef501ed25423 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a3ea4b0c65a01f18d11ad39862b9ef501ed25423 new file mode 100644 index 00000000..70c6fdcd Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a3ea4b0c65a01f18d11ad39862b9ef501ed25423 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a5daf115b5376cc8052df9ae1bb7693d0c6c64a5 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a5daf115b5376cc8052df9ae1bb7693d0c6c64a5 new file mode 100644 index 00000000..f026287a Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/a5daf115b5376cc8052df9ae1bb7693d0c6c64a5 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b26b7f292dee13cf6e0366f48ea199ee86a0c201 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b26b7f292dee13cf6e0366f48ea199ee86a0c201 new file mode 100644 index 00000000..5b187710 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b26b7f292dee13cf6e0366f48ea199ee86a0c201 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b452f7b6c615035d63a9825c5c17e049f54648ef b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b452f7b6c615035d63a9825c5c17e049f54648ef deleted file mode 100644 index c708d1e6..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/b452f7b6c615035d63a9825c5c17e049f54648ef and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb3b1f380ed32d09a2c2811b68bc7ff5960fb0ff b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb3b1f380ed32d09a2c2811b68bc7ff5960fb0ff new file mode 100644 index 00000000..ae1d6cd2 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb3b1f380ed32d09a2c2811b68bc7ff5960fb0ff differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb8c2201cf10fd7d24fc0c8009a44525f426b033 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb8c2201cf10fd7d24fc0c8009a44525f426b033 deleted file mode 100644 index 8f98344f..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bb8c2201cf10fd7d24fc0c8009a44525f426b033 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bd3c74122b8b6ba809feaa063c0e0caf081def4d b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bd3c74122b8b6ba809feaa063c0e0caf081def4d new file mode 100644 index 00000000..5f3c553c Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bd3c74122b8b6ba809feaa063c0e0caf081def4d differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7dcdad1c2df1656678947b2009a9fcea44f4025d b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bea0876bed5520626024667d4f9dc0a4f485aa76 similarity index 54% rename from oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7dcdad1c2df1656678947b2009a9fcea44f4025d rename to oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bea0876bed5520626024667d4f9dc0a4f485aa76 index e3202611..e75a2852 100644 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/7dcdad1c2df1656678947b2009a9fcea44f4025d and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/bea0876bed5520626024667d4f9dc0a4f485aa76 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e26757270b3d149d1ce10bef32ed0b3a5794977c b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c1fa9299a3e1e9d51a2239488cb2e7333b58a9e5 similarity index 54% rename from oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e26757270b3d149d1ce10bef32ed0b3a5794977c rename to oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c1fa9299a3e1e9d51a2239488cb2e7333b58a9e5 index d8911528..2ed91aa5 100644 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e26757270b3d149d1ce10bef32ed0b3a5794977c and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c1fa9299a3e1e9d51a2239488cb2e7333b58a9e5 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c7a7cd07925450628efa677165d403510d89bf51 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c7a7cd07925450628efa677165d403510d89bf51 deleted file mode 100644 index 5442bebb..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c7a7cd07925450628efa677165d403510d89bf51 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c862e8c9d33f4b01c20a9dc77849e5c5856f2474 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c862e8c9d33f4b01c20a9dc77849e5c5856f2474 new file mode 100644 index 00000000..25938308 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c862e8c9d33f4b01c20a9dc77849e5c5856f2474 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c96ae0dca69ceb11a79855a19786a559d6b255e3 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c96ae0dca69ceb11a79855a19786a559d6b255e3 new file mode 100644 index 00000000..c4692d01 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/c96ae0dca69ceb11a79855a19786a559d6b255e3 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-5919435528601600 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-5919435528601600 deleted file mode 100644 index 58dc14ff..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-5919435528601600 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-6406770604638208 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d0a0d8d0c842875b97e89957095af3c71f7e9744 similarity index 54% rename from oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-6406770604638208 rename to oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d0a0d8d0c842875b97e89957095af3c71f7e9744 index 1a0f23cf..2e0d879e 100644 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/clusterfuzz-testcase-minimized-oemcrypto_load_license_fuzz-6406770604638208 and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d0a0d8d0c842875b97e89957095af3c71f7e9744 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d7014f417415314dd83162570bcafd7935875f00 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d7014f417415314dd83162570bcafd7935875f00 deleted file mode 100644 index 3df5267a..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/d7014f417415314dd83162570bcafd7935875f00 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/df85865da57cab1bcbf9a081b850c3c8525098f6 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/df85865da57cab1bcbf9a081b850c3c8525098f6 new file mode 100644 index 00000000..f6752016 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/df85865da57cab1bcbf9a081b850c3c8525098f6 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e44281948ed00f87ec981eb880561d983c0c16c3 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e44281948ed00f87ec981eb880561d983c0c16c3 new file mode 100644 index 00000000..60819761 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e44281948ed00f87ec981eb880561d983c0c16c3 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e598a949c6b14e1a3f96bcdf1b3d9335b07a6085 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e598a949c6b14e1a3f96bcdf1b3d9335b07a6085 deleted file mode 100644 index b54027c5..00000000 Binary files a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/e598a949c6b14e1a3f96bcdf1b3d9335b07a6085 and /dev/null differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ecffb38d73f504442070cf4f754d9d2cd87a87d7 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ecffb38d73f504442070cf4f754d9d2cd87a87d7 new file mode 100644 index 00000000..0d43c08c Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ecffb38d73f504442070cf4f754d9d2cd87a87d7 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ef6f1be8c575823ab46f6cf0e38717809d180301 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ef6f1be8c575823ab46f6cf0e38717809d180301 new file mode 100644 index 00000000..fa031685 Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/ef6f1be8c575823ab46f6cf0e38717809d180301 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/f0d0117a070069c19108d17b834c6aa44ba11ab2 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/f0d0117a070069c19108d17b834c6aa44ba11ab2 new file mode 100644 index 00000000..afa4721f Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/f0d0117a070069c19108d17b834c6aa44ba11ab2 differ diff --git a/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/fa7ec04e797198608d77692abd2c13e98e6e6d28 b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/fa7ec04e797198608d77692abd2c13e98e6e6d28 new file mode 100644 index 00000000..a1bbac3b Binary files /dev/null and b/oemcrypto/test/fuzz_tests/corpus/oemcrypto_load_license_fuzz_seed_corpus/fa7ec04e797198608d77692abd2c13e98e6e6d28 differ diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_deactivate_usage_entry_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_deactivate_usage_entry_fuzz.cc index 47f39ef8..9644106e 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_deactivate_usage_entry_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_deactivate_usage_entry_fuzz.cc @@ -11,7 +11,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::LicenseWithUsageEntryFuzz entry; entry.Initialize(); entry.CreateUsageTableHeader(); - entry.InstallTestRSAKey(); + entry.InstallTestDrmKey(); entry.session().CreateNewUsageEntry(); entry.session().GenerateNonce(); std::vector encrypted_usage_header; diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_cenc_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_cenc_fuzz.cc index d67c2b45..7519959c 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_cenc_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_cenc_fuzz.cc @@ -6,6 +6,7 @@ #include "FuzzedDataProvider.h" #include "OEMCryptoCENC.h" +#include "oec_session_util.h" #include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_structs.h" @@ -167,10 +168,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Load license and call decrypt_cenc API. const wvoec::MessageKeyData& key = license_api_fuzz.session().license().keys[0]; - OEMCrypto_SelectKey(session_id, key.key_id, key.key_id_length, - fuzzed_structure.cipher_mode); - OEMCrypto_DecryptCENC(session_id, sample_descriptions.data(), - sample_descriptions.size(), &fuzzed_structure.pattern); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session_id, key.key_id, key.key_id_length, + fuzzed_structure.cipher_mode, key_handle); + OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + sample_descriptions.data(), sample_descriptions.size(), + &fuzzed_structure.pattern); // Free all output buffers. FreeOutputBuffers(sample_descriptions.size()); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_hash_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_hash_fuzz.cc index 3ee5523b..e894884d 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_hash_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_decrypt_hash_fuzz.cc @@ -59,10 +59,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { fuzzed_data.ConsumeRemainingBytes(); license_api_fuzz.LoadLicense(); - OEMCrypto_SelectKey(session_id, content_key_id.data(), content_key_id.size(), - OEMCrypto_CipherMode_CENC); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session_id, content_key_id.data(), + content_key_id.size(), + OEMCrypto_CipherMode_CENC, key_handle); OEMCrypto_SetDecryptHash(session_id, frame_number, hash.data(), hash.size()); - OEMCrypto_DecryptCENC(session_id, &sample, 1, &pattern); + OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), &sample, 1, + &pattern); OEMCrypto_GetHashErrorCode(session_id, failed_frame_number); license_api_fuzz.Terminate(); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc index a5d058e3..50929b1a 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc @@ -29,7 +29,8 @@ void InitializeFuzz(SessionUtil& session_util) { wvoec::global_features.Initialize(); OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); OEMCrypto_Initialize(); - session_util.EnsureTestKeys(); + OEMCrypto_EnterTestMode(); + session_util.EnsureTestROT(); } void SessionFuzz::Initialize() { @@ -44,7 +45,7 @@ void SessionFuzz::Terminate() { void OEMCryptoLicenseAPIFuzz::Initialize() { session_fuzz_.Initialize(); - session_fuzz_.InstallTestRSAKey(); + session_fuzz_.InstallTestDrmKey(); session_fuzz_.session().GenerateNonce(); } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h index a60a9cf0..a322ebcf 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h +++ b/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h @@ -44,8 +44,8 @@ class SessionFuzz { void Terminate(); - void InstallTestRSAKey() { - session_util_.InstallTestRSAKey(&session_); + void InstallTestDrmKey() { + session_util_.InstallTestDrmKey(&session_); } Session& session() { return session_; } @@ -153,7 +153,7 @@ class LicenseWithUsageEntryFuzz { void CreateUsageTableHeader(); - void InstallTestRSAKey() { session_fuzz_.InstallTestRSAKey(); } + void InstallTestDrmKey() { session_fuzz_.InstallTestDrmKey(); } void LoadLicense(); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gypi b/oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gypi index f8abdecd..d4db9501 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gypi +++ b/oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gypi @@ -63,7 +63,7 @@ '-D_POSIX_C_SOURCE=200809L', ], 'cflags_cc': [ - '-std=c++11', + '-std=c++14', ], 'ldflags': [ '-fPIC', diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generate_certificate_key_pair_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generate_certificate_key_pair_fuzz.cc index cff4bd23..f66353a7 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generate_certificate_key_pair_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generate_certificate_key_pair_fuzz.cc @@ -19,6 +19,38 @@ wvoec::OEMCryptoProvisioningAPIFuzz& provisioning_api_fuzz = extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { wvoec::RedirectStdoutToFile(); provisioning_api_fuzz.Initialize(); + +#ifdef SECOND_STAGE + + const uint32_t session_id = provisioning_api_fuzz.session().session_id(); + + size_t public_key_length = 0; + size_t public_key_signature_length = 0; + size_t wrapped_private_key_length = 0; + OEMCrypto_PrivateKeyType key_type = OEMCrypto_RSA_Private_Key; + OEMCryptoResult result = OEMCrypto_GenerateCertificateKeyPair( + session_id, nullptr, &public_key_length, nullptr, + &public_key_signature_length, nullptr, &wrapped_private_key_length, + &key_type); + wvoec::CheckStatusAndExitFuzzerOnFailure(result, + OEMCrypto_ERROR_SHORT_BUFFER); + + std::vector public_key(public_key_length); + std::vector public_key_signature(public_key_signature_length); + std::vector wrapped_private_key(wrapped_private_key_length); + result = OEMCrypto_GenerateCertificateKeyPair( + session_id, public_key.data(), &public_key_length, + public_key_signature.data(), &public_key_signature_length, + wrapped_private_key.data(), &wrapped_private_key_length, &key_type); + wvoec::CheckStatusAndExitFuzzerOnFailure(result, OEMCrypto_SUCCESS); + + result = OEMCrypto_InstallOemPrivateKey(session_id, key_type, + wrapped_private_key.data(), + wrapped_private_key_length); + wvoec::CheckStatusAndExitFuzzerOnFailure(result, OEMCrypto_SUCCESS); + +#endif + return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generate_rsa_signature_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generate_rsa_signature_fuzz.cc index 1537323d..f30eed87 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generate_rsa_signature_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generate_rsa_signature_fuzz.cc @@ -25,7 +25,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::SessionFuzz session_fuzz; session_fuzz.Initialize(); - session_fuzz.InstallTestRSAKey(); + session_fuzz.InstallTestDrmKey(); OEMCrypto_GenerateRSASignature( session_fuzz.session().session_id(), message.data(), message.size(), signature.data(), &fuzzed_structure.signature_length, diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generic_decrypt_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generic_decrypt_fuzz.cc index 953a1d26..a38cf8b4 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generic_decrypt_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generic_decrypt_fuzz.cc @@ -15,7 +15,7 @@ namespace { wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz = *new wvoec::OEMCryptoLicenseAPIFuzz; -} // namespace +} // namespace extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { wvoec::RedirectStdoutToFile(); @@ -55,11 +55,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Select key and decrypt. wvoec::Session& session = license_api_fuzz.session(); - OEMCrypto_SelectKey(session.session_id(), session.license().keys[1].key_id, - session.license().keys[1].key_id_length, - fuzzed_structure.cipher_mode); - OEMCrypto_Generic_Decrypt(session.session_id(), encrypted_buffer.data(), - encrypted_buffer.size(), iv.data(), - fuzzed_structure.algorithm, clear_buffer.data()); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session.session_id(), + session.license().keys[1].key_id, + session.license().keys[1].key_id_length, + fuzzed_structure.cipher_mode, key_handle); + OEMCrypto_Generic_Decrypt(key_handle.data(), key_handle.size(), + encrypted_buffer.data(), encrypted_buffer.size(), + iv.data(), fuzzed_structure.algorithm, + clear_buffer.data()); return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generic_encrypt_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generic_encrypt_fuzz.cc index dc2632a9..e40c2bb7 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generic_encrypt_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generic_encrypt_fuzz.cc @@ -15,7 +15,7 @@ namespace { wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz = *new wvoec::OEMCryptoLicenseAPIFuzz; -} // namespace +} // namespace extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { wvoec::RedirectStdoutToFile(); @@ -55,11 +55,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Select key and encrypt. wvoec::Session& session = license_api_fuzz.session(); - OEMCrypto_SelectKey(session.session_id(), session.license().keys[0].key_id, - session.license().keys[0].key_id_length, - fuzzed_structure.cipher_mode); - OEMCrypto_Generic_Encrypt( - session.session_id(), clear_buffer.data(), clear_buffer.size(), iv.data(), - fuzzed_structure.algorithm, encrypted_buffer.data()); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session.session_id(), + session.license().keys[0].key_id, + session.license().keys[0].key_id_length, + fuzzed_structure.cipher_mode, key_handle); + OEMCrypto_Generic_Encrypt(key_handle.data(), key_handle.size(), + clear_buffer.data(), clear_buffer.size(), iv.data(), + fuzzed_structure.algorithm, + encrypted_buffer.data()); return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generic_sign_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generic_sign_fuzz.cc index 58962124..a01b3bb1 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generic_sign_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generic_sign_fuzz.cc @@ -15,7 +15,7 @@ namespace { wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz = *new wvoec::OEMCryptoLicenseAPIFuzz; -} // namespace +} // namespace extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { wvoec::RedirectStdoutToFile(); @@ -42,16 +42,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Select key and sign. wvoec::Session& session = license_api_fuzz.session(); - OEMCrypto_SelectKey(session.session_id(), session.license().keys[2].key_id, - session.license().keys[2].key_id_length, - fuzzed_structure.cipher_mode); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session.session_id(), + session.license().keys[2].key_id, + session.license().keys[2].key_id_length, + fuzzed_structure.cipher_mode, key_handle); size_t signature_length = 0; - OEMCrypto_Generic_Sign(session.session_id(), clear_buffer.data(), - clear_buffer.size(), fuzzed_structure.algorithm, - nullptr, &signature_length); + OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer.data(), clear_buffer.size(), + fuzzed_structure.algorithm, nullptr, + &signature_length); std::vector signature(signature_length); - OEMCrypto_Generic_Sign(session.session_id(), clear_buffer.data(), - clear_buffer.size(), fuzzed_structure.algorithm, - signature.data(), &signature_length); + OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer.data(), clear_buffer.size(), + fuzzed_structure.algorithm, signature.data(), + &signature_length); return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_generic_verify_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_generic_verify_fuzz.cc index 57383344..a7698fc7 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_generic_verify_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_generic_verify_fuzz.cc @@ -6,6 +6,7 @@ #include "FuzzedDataProvider.h" #include "OEMCryptoCENC.h" +#include "oec_session_util.h" #include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_structs.h" @@ -50,11 +51,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Select key and verify. wvoec::Session& session = license_api_fuzz.session(); - OEMCrypto_SelectKey(session.session_id(), session.license().keys[3].key_id, - session.license().keys[3].key_id_length, - fuzzed_structure.cipher_mode); - OEMCrypto_Generic_Verify(session.session_id(), buffer.data(), buffer.size(), - fuzzed_structure.algorithm, signature.data(), - signature.size()); + std::vector key_handle; + wvoec::GetKeyHandleIntoVector(session.session_id(), + session.license().keys[3].key_id, + session.license().keys[3].key_id_length, + fuzzed_structure.cipher_mode, key_handle); + OEMCrypto_Generic_Verify(key_handle.data(), key_handle.size(), buffer.data(), + buffer.size(), fuzzed_structure.algorithm, + signature.data(), signature.size()); return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_get_device_information_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_get_device_information_fuzz.cc new file mode 100644 index 00000000..191fe381 --- /dev/null +++ b/oemcrypto/test/fuzz_tests/oemcrypto_get_device_information_fuzz.cc @@ -0,0 +1,31 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. + +#include + +#include "FuzzedDataProvider.h" +#include "OEMCryptoCENC.h" +#include "oemcrypto_fuzz_helper.h" + +extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { + wvoec::RedirectStdoutToFile(); + wvoec::SessionUtil session_util; + wvoec::InitializeFuzz(session_util); + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fuzzed_data(data, size); + + // device_info and device_info_length parameters + size_t device_info_length_data = fuzzed_data.ConsumeIntegralInRange( + 0, wvoec::MAX_FUZZ_OUTPUT_LENGTH); + std::vector device_info(device_info_length_data); + size_t* const device_info_length = + fuzzed_data.ConsumeBool() ? &device_info_length_data : nullptr; + + OEMCrypto_GetDeviceInformation(device_info.data(), device_info_length); + + return 0; +} diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_get_device_signed_csr_payload_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_get_device_signed_csr_payload_fuzz.cc new file mode 100644 index 00000000..b30fa600 --- /dev/null +++ b/oemcrypto/test/fuzz_tests/oemcrypto_get_device_signed_csr_payload_fuzz.cc @@ -0,0 +1,50 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. + +#include + +#include "FuzzedDataProvider.h" +#include "OEMCryptoCENC.h" +#include "oemcrypto_fuzz_helper.h" + +extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { + wvoec::RedirectStdoutToFile(); + wvoec::SessionUtil session_util; + wvoec::InitializeFuzz(session_util); + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // Split data using separator. + const std::vector inputs = + wvoec::SplitFuzzedData(data, size); + if (inputs.size() < 3) { + return 0; + } + + const std::vector challenge(inputs[0].data, + inputs[0].data + inputs[0].size); + + const std::vector encoded_device_info( + inputs[1].data, inputs[1].data + inputs[1].size); + + // signed_csr_payload and signed_csr_payload_length parameters + FuzzedDataProvider signed_csr_payload_fuzzed_data(inputs[2].data, + inputs[2].size); + size_t signed_csr_payload_length_data = + signed_csr_payload_fuzzed_data.ConsumeIntegralInRange( + 0, wvoec::MAX_FUZZ_OUTPUT_LENGTH); + std::vector signed_csr_payload(signed_csr_payload_length_data); + size_t* const signed_csr_payload_length = + signed_csr_payload_fuzzed_data.ConsumeBool() + ? &signed_csr_payload_length_data + : nullptr; + + OEMCrypto_GetDeviceSignedCsrPayload( + challenge.data(), challenge.size(), encoded_device_info.data(), + encoded_device_info.size(), signed_csr_payload.data(), + signed_csr_payload_length); + + return 0; +} diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_select_key_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_get_key_handle_fuzz.cc similarity index 62% rename from oemcrypto/test/fuzz_tests/oemcrypto_select_key_fuzz.cc rename to oemcrypto/test/fuzz_tests/oemcrypto_get_key_handle_fuzz.cc index 0bf0a18a..9d70470e 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_select_key_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_get_key_handle_fuzz.cc @@ -2,6 +2,8 @@ // source code may only be used and distributed under the Widevine // License Agreement. +#include + #include "FuzzedDataProvider.h" #include "OEMCryptoCENC.h" #include "oemcrypto_fuzz_helper.h" @@ -27,12 +29,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { const OEMCryptoCipherMode cipher_mode = wvoec::ConvertDataToValidEnum(fuzzed_data, OEMCrypto_CipherMode_MaxValue); + // key_handle and key_handle_length parameters + size_t key_handle_length_data = fuzzed_data.ConsumeIntegralInRange( + 0, wvoec::MAX_FUZZ_OUTPUT_LENGTH); + std::vector key_handle(key_handle_length_data); + size_t* const key_handle_length = + fuzzed_data.ConsumeBool() ? &key_handle_length_data : nullptr; + const std::vector content_key_id = fuzzed_data.ConsumeRemainingBytes(); - OEMCrypto_SelectKey(license_api_fuzz.session().session_id(), - content_key_id.data(), content_key_id.size(), - cipher_mode); + OEMCrypto_GetKeyHandle(license_api_fuzz.session().session_id(), + content_key_id.data(), content_key_id.size(), + cipher_mode, key_handle.data(), key_handle_length); return 0; } diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc index 20b16f02..3dc3b07a 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc @@ -7,14 +7,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::RedirectStdoutToFile(); - if (size < sizeof(ODK_ParsedLicense) + sizeof(wvoec::MessageData)) { + if (size < sizeof(ODK_Packing_ParsedLicense) + sizeof(wvoec::MessageData)) { return 0; } wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz; license_api_fuzz.Initialize(); license_api_fuzz.license_messages().SignAndVerifyRequest(); - // Interpreting input fuzz data as unencrypted (core_response + license - // message data) from license server. + // Interpreting input fuzz data as unencrypted core_response + response_data + + // key_array from license server. license_api_fuzz.license_messages().InjectFuzzedResponseData(data, size); // Convert OEMCrypto_LicenseType in core_response to a valid enum value. diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_load_usage_entry_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_load_usage_entry_fuzz.cc index de64eb1f..d39ef006 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_load_usage_entry_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_load_usage_entry_fuzz.cc @@ -36,7 +36,7 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, size_t max_size, unsigned int seed) { entry.CreateUsageTableHeader(); entry.session().open(); - entry.InstallTestRSAKey(); + entry.InstallTestDrmKey(); if (LoadUsageEntryWithFuzzedData(entry.session().session_id(), data, size) != OEMCrypto_SUCCESS) { entry.session().CreateNewUsageEntry(); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_move_usage_entry_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_move_usage_entry_fuzz.cc index 1abd6fe4..0c65ed0d 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_move_usage_entry_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_move_usage_entry_fuzz.cc @@ -12,7 +12,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::LicenseWithUsageEntryFuzz entry; entry.Initialize(); entry.CreateUsageTableHeader(); - entry.InstallTestRSAKey(); + entry.InstallTestDrmKey(); entry.session().CreateNewUsageEntry(); std::vector encrypted_usage_header; entry.session().UpdateUsageEntry(&encrypted_usage_header); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp index 0fd1787e..f5ac0112 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp +++ b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp @@ -67,11 +67,20 @@ ], }, { - 'target_name': 'oemcrypto_opk_generate_certificate_key_pair_fuzz', + 'target_name': 'oemcrypto_opk_generate_certificate_key_pair_first_stage_fuzz', 'sources': [ 'oemcrypto_generate_certificate_key_pair_fuzz.cc', ], }, + { + 'target_name': 'oemcrypto_opk_generate_certificate_key_pair_second_stage_fuzz', + 'sources': [ + 'oemcrypto_generate_certificate_key_pair_fuzz.cc', + ], + 'defines': [ + 'SECOND_STAGE', + ], + }, { 'target_name': 'oemcrypto_opk_generate_rsa_signature_fuzz', 'sources': [ @@ -108,6 +117,24 @@ 'oemcrypto_get_boot_certificate_chain_fuzz.cc', ], }, + { + 'target_name': 'oemcrypto_opk_get_device_information_fuzz', + 'sources': [ + 'oemcrypto_get_device_information_fuzz.cc', + ], + }, + { + 'target_name': 'oemcrypto_opk_get_device_signed_csr_payload_fuzz', + 'sources': [ + 'oemcrypto_get_device_signed_csr_payload_fuzz.cc', + ], + }, + { + 'target_name': 'oemcrypto_opk_get_key_handle_fuzz', + 'sources': [ + 'oemcrypto_get_key_handle_fuzz.cc', + ], + }, { 'target_name': 'oemcrypto_opk_get_random_fuzz', 'sources': [ @@ -198,12 +225,6 @@ 'oemcrypto_reuse_usage_entry_fuzz.cc', ], }, - { - 'target_name': 'oemcrypto_opk_select_key_fuzz', - 'sources': [ - 'oemcrypto_select_key_fuzz.cc', - ], - }, { 'target_name': 'oemcrypto_opk_shrink_usage_table_header_fuzz', 'sources': [ diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi index 0a655fce..4e7efc74 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi +++ b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gypi @@ -27,12 +27,12 @@ '-g3', ], 'cflags_c': [ - '-std=c99', + '-std=c11', '-D_POSIX_C_SOURCE=200809L', ], 'cflags_cc' : [ '-frtti', - '-std=c++11', + '-std=c++14', ], 'ldflags': [ '-fPIC', @@ -47,6 +47,13 @@ ], 'defines': [ 'OPK_LOG_LEVEL=LOG_NONE', + 'OPK_CONFIG_SOC_VENDOR_NAME=test', + 'OPK_CONFIG_SOC_MODEL_NAME=test', + 'OPK_CONFIG_TEE_OS_NAME=TEE_Simulator', + 'OPK_CONFIG_TEE_OS_VERSION=0.0.0', + 'OPK_CONFIG_DEVICE_FORM_FACTOR=oemcrypto_opk_fuzztests', + 'OPK_CONFIG_IMPLEMENTER_NAME=Widevine', + 'FACTORY_BUILD_ONLY', ], 'conditions': [ ['generate_code_coverage_report=="true"', { diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_report_usage_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_report_usage_fuzz.cc index e943acdb..8b636545 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_report_usage_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_report_usage_fuzz.cc @@ -19,7 +19,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::LicenseWithUsageEntryFuzz entry; entry.Initialize(); entry.CreateUsageTableHeader(); - entry.InstallTestRSAKey(); + entry.InstallTestDrmKey(); entry.session().CreateNewUsageEntry(); entry.session().GenerateNonce(); std::vector encrypted_usage_header; diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_reuse_usage_entry_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_reuse_usage_entry_fuzz.cc index eea4a09a..700e67b7 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_reuse_usage_entry_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_reuse_usage_entry_fuzz.cc @@ -12,7 +12,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { wvoec::LicenseWithUsageEntryFuzz entry; entry.Initialize(); entry.CreateUsageTableHeader(); - entry.InstallTestRSAKey(); + entry.InstallTestDrmKey(); entry.session().CreateNewUsageEntry(); entry.session().close(); diff --git a/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp b/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp index 2fa9a5fe..c970e505 100644 --- a/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp +++ b/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gyp @@ -44,11 +44,20 @@ ], }, { - 'target_name': 'oemcrypto_generate_certificate_key_pair_fuzz', + 'target_name': 'oemcrypto_generate_certificate_key_pair_first_stage_fuzz', 'sources': [ 'oemcrypto_generate_certificate_key_pair_fuzz.cc', ], }, + { + 'target_name': 'oemcrypto_generate_certificate_key_pair_second_stage_fuzz', + 'sources': [ + 'oemcrypto_generate_certificate_key_pair_fuzz.cc', + ], + 'defines': [ + 'SECOND_STAGE', + ], + }, { 'target_name': 'oemcrypto_generate_rsa_signature_fuzz', 'sources': [ @@ -85,6 +94,24 @@ 'oemcrypto_get_boot_certificate_chain_fuzz.cc', ], }, + { + 'target_name': 'oemcrypto_get_device_information_fuzz', + 'sources': [ + 'oemcrypto_get_device_information_fuzz.cc', + ], + }, + { + 'target_name': 'oemcrypto_get_device_signed_csr_payload_fuzz', + 'sources': [ + 'oemcrypto_get_device_signed_csr_payload_fuzz.cc', + ], + }, + { + 'target_name': 'oemcrypto_get_key_handle_fuzz', + 'sources': [ + 'oemcrypto_get_key_handle_fuzz.cc', + ], + }, { 'target_name': 'oemcrypto_get_random_fuzz', 'sources': [ @@ -175,12 +202,6 @@ 'oemcrypto_reuse_usage_entry_fuzz.cc', ], }, - { - 'target_name': 'oemcrypto_select_key_fuzz', - 'sources': [ - 'oemcrypto_select_key_fuzz.cc', - ], - }, { 'target_name': 'oemcrypto_shrink_usage_table_header_fuzz', 'sources': [ diff --git a/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gypi b/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gypi index ddf927dc..0a9e92f1 100644 --- a/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gypi +++ b/oemcrypto/test/fuzz_tests/partner_oemcrypto_fuzztests.gypi @@ -69,7 +69,7 @@ '-D_POSIX_C_SOURCE=200809L', ], 'cflags_cc': [ - '-std=c++11', + '-std=c++14', '-frtti', ], 'ldflags': [ diff --git a/oemcrypto/test/oec_decrypt_fallback_chain.cpp b/oemcrypto/test/oec_decrypt_fallback_chain.cpp index cbf552bf..6cb7aac0 100644 --- a/oemcrypto/test/oec_decrypt_fallback_chain.cpp +++ b/oemcrypto/test/oec_decrypt_fallback_chain.cpp @@ -49,11 +49,12 @@ namespace wvoec { // Decrypts the given array of samples. Handles fallback behavior correctly if // the OEMCrypto implementation does not accept multiple samples. OEMCryptoResult DecryptFallbackChain::Decrypt( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription* samples, - size_t samples_length, OEMCryptoCipherMode cipher_mode, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription* samples, size_t samples_length, + OEMCryptoCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc* pattern) { - OEMCryptoResult sts = - OEMCrypto_DecryptCENC(session_id, samples, samples_length, pattern); + OEMCryptoResult sts = OEMCrypto_DecryptCENC(key_handle, key_handle_length, + samples, samples_length, pattern); // No need for a fallback. Abort early. if (sts != OEMCrypto_ERROR_BUFFER_TOO_LARGE) { @@ -65,7 +66,8 @@ OEMCryptoResult DecryptFallbackChain::Decrypt( // Fall back to decrypting individual samples. for (size_t i = 0; i < samples_length; ++i) { - sts = DecryptSample(session_id, samples[i], cipher_mode, pattern); + sts = DecryptSample(key_handle, key_handle_length, samples[i], cipher_mode, + pattern); if (sts != OEMCrypto_SUCCESS) return sts; } @@ -75,10 +77,11 @@ OEMCryptoResult DecryptFallbackChain::Decrypt( // Decrypts the given sample. Handles fallback behavior correctly if the // OEMCrypto implementation does not accept full samples. OEMCryptoResult DecryptFallbackChain::DecryptSample( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, - OEMCryptoCipherMode cipher_mode, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, OEMCryptoCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc* pattern) { - OEMCryptoResult sts = OEMCrypto_DecryptCENC(session_id, &sample, 1, pattern); + OEMCryptoResult sts = + OEMCrypto_DecryptCENC(key_handle, key_handle_length, &sample, 1, pattern); // No need for a fallback. Abort early. if (sts != OEMCrypto_ERROR_BUFFER_TOO_LARGE) { @@ -99,7 +102,8 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample( fake_sample.subsamples = &subsample; fake_sample.subsamples_length = 1; - sts = DecryptSubsample(session_id, fake_sample, pattern, cipher_mode); + sts = DecryptSubsample(key_handle, key_handle_length, fake_sample, pattern, + cipher_mode); if (sts != OEMCrypto_SUCCESS) return sts; fake_sample.buffers.input_data += length; @@ -116,10 +120,12 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample( // Decrypts the given subsample. Handles fallback behavior correctly if the // OEMCrypto implementation does not accept full subsamples. OEMCryptoResult DecryptFallbackChain::DecryptSubsample( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, const OEMCrypto_CENCEncryptPatternDesc* pattern, OEMCryptoCipherMode cipher_mode) { - OEMCryptoResult sts = OEMCrypto_DecryptCENC(session_id, &sample, 1, pattern); + OEMCryptoResult sts = + OEMCrypto_DecryptCENC(key_handle, key_handle_length, &sample, 1, pattern); // No need for a fallback. Abort early. if (sts != OEMCrypto_ERROR_BUFFER_TOO_LARGE) { @@ -149,7 +155,8 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( subsample.num_bytes_encrypted == 0) fake_subsample.subsample_flags |= OEMCrypto_LastSubsample; - sts = DecryptSubsampleHalf(session_id, fake_sample, pattern, cipher_mode); + sts = DecryptSubsampleHalf(key_handle, key_handle_length, fake_sample, + pattern, cipher_mode); if (sts != OEMCrypto_SUCCESS) return sts; // Advance the buffers for the other half, in case they're needed. @@ -171,7 +178,8 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( if (subsample.subsample_flags & OEMCrypto_LastSubsample) fake_subsample.subsample_flags |= OEMCrypto_LastSubsample; - sts = DecryptSubsampleHalf(session_id, fake_sample, pattern, cipher_mode); + sts = DecryptSubsampleHalf(key_handle, key_handle_length, fake_sample, + pattern, cipher_mode); if (sts != OEMCrypto_SUCCESS) return sts; } @@ -182,13 +190,15 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( // an OEMCrypto_ERROR_BUFFER_TOO_LARGE produced here will be returned to the // caller. OEMCryptoResult DecryptFallbackChain::DecryptSubsampleHalf( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, const OEMCrypto_CENCEncryptPatternDesc* pattern, OEMCryptoCipherMode cipher_mode) { if (ShouldGenerateCorpus()) { WriteDecryptCencCorpus(cipher_mode, &sample, pattern, 1); } - return OEMCrypto_DecryptCENC(session_id, &sample, 1, pattern); + return OEMCrypto_DecryptCENC(key_handle, key_handle_length, &sample, 1, + pattern); // In a real CDM, you would want some fallback here to handle the case where // the buffer is too big for the OEMCrypto implementation. But in the case of // the tests, we won't be passing a buffer that's too big unless we are trying diff --git a/oemcrypto/test/oec_decrypt_fallback_chain.h b/oemcrypto/test/oec_decrypt_fallback_chain.h index aafbb071..0bbee74a 100644 --- a/oemcrypto/test/oec_decrypt_fallback_chain.h +++ b/oemcrypto/test/oec_decrypt_fallback_chain.h @@ -32,23 +32,27 @@ namespace wvoec { class DecryptFallbackChain { public: static OEMCryptoResult Decrypt( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription* samples, - size_t samples_length, OEMCryptoCipherMode cipher_mode, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription* samples, size_t samples_length, + OEMCryptoCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc* pattern); private: static OEMCryptoResult DecryptSample( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, OEMCryptoCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc* pattern); static OEMCryptoResult DecryptSubsample( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, const OEMCrypto_CENCEncryptPatternDesc* pattern, OEMCryptoCipherMode cipher_mode); static OEMCryptoResult DecryptSubsampleHalf( - OEMCrypto_SESSION session_id, const OEMCrypto_SampleDescription& sample, + const uint8_t* key_handle, size_t key_handle_length, + const OEMCrypto_SampleDescription& sample, const OEMCrypto_CENCEncryptPatternDesc* pattern, OEMCryptoCipherMode cipher_mode); diff --git a/oemcrypto/test/oec_device_features.cpp b/oemcrypto/test/oec_device_features.cpp index 9db9c007..22640539 100644 --- a/oemcrypto/test/oec_device_features.cpp +++ b/oemcrypto/test/oec_device_features.cpp @@ -24,13 +24,27 @@ void DeviceFeatures::Initialize() { generic_crypto = false; usage_table = false; supports_rsa_3072 = false; + supports_secp256r1 = false; api_version = 0; derive_key_method = NO_METHOD; OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); - if (OEMCrypto_SUCCESS != OEMCrypto_Initialize()) { - printf("OEMCrypto_Initialize failed. All tests will fail.\n"); + const OEMCryptoResult init_status = OEMCrypto_Initialize(); + if (OEMCrypto_SUCCESS != init_status) { + printf("OEMCrypto_Initialize failed %d. All tests will fail.\n", + init_status); return; } + const OEMCryptoResult api_status = OEMCrypto_SetMaxAPIVersion(kCurrentAPI); + if (api_status != OEMCrypto_SUCCESS && + api_status != OEMCrypto_ERROR_NOT_IMPLEMENTED) { + // Log error, but continue assuming no error. + printf("OEMCrypto_SetMaxAPIVersion returned %d\n", api_status); + } + const OEMCryptoResult test_mode_status = OEMCrypto_EnterTestMode(); + if (OEMCrypto_SUCCESS != test_mode_status) { + printf("OEMCrypto_EnterTestMode returned %d. Tests might fail.\n", + test_mode_status); + }; uint8_t buffer[1]; uint8_t iv[16] = {}; size_t size = 0; @@ -46,21 +60,16 @@ void DeviceFeatures::Initialize() { printf("--- ERROR: Could not open session: %d ----\n", result); } // If the device uses a keybox, check to see if loading a certificate is - // installed. - if (provisioning_method == OEMCrypto_Keybox || - provisioning_method == OEMCrypto_OEMCertificate || - provisioning_method == OEMCrypto_BootCertificateChain) { - // Devices with a keybox or OEM Certificate are required to support loading - // a DRM certificate. - loads_certificate = true; - } else { - // Other devices are either broken, or they have a baked in certificate. - loads_certificate = false; - } + // installed. Devices with a keybox or OEM Certificate are required to support + // loading a DRM certificate. Other devices are either broken, or they have a + // baked in certificate. + loads_certificate = provisioning_method == OEMCrypto_Keybox || + provisioning_method == OEMCrypto_OEMCertificate || + provisioning_method == OEMCrypto_BootCertificateChain; printf("loads_certificate = %s.\n", loads_certificate ? "true" : "false"); generic_crypto = (OEMCrypto_ERROR_NOT_IMPLEMENTED != - OEMCrypto_Generic_Encrypt(session, buffer, 0, iv, + OEMCrypto_Generic_Encrypt(buffer, 0, buffer, 0, iv, OEMCrypto_AES_CBC_128_NO_PADDING, buffer)); printf("generic_crypto = %s.\n", generic_crypto ? "true" : "false"); supports_cas = @@ -70,21 +79,28 @@ void DeviceFeatures::Initialize() { OEMCrypto_CloseSession(session); api_version = OEMCrypto_APIVersion(); printf("api_version = %u.\n", api_version); + if (api_version < kCoreMessagesAPI) { + printf("--------- WARNING: minimum API is %d ----------\n", api_version); + printf("--------- Expect most tests will fail. --------\n"); + } // These unit tests only work with new usage tables. We do not test v12 // usage tables. - if (api_version > 12) usage_table = OEMCrypto_SupportsUsageTable(); + usage_table = OEMCrypto_SupportsUsageTable(); printf("usage_table = %s.\n", usage_table ? "true" : "false"); PickDerivedKey(); - if (api_version >= 13) { - uint32_t supported_cert = OEMCrypto_SupportedCertificates(); - if (supported_cert & OEMCrypto_Supports_RSA_CAST) { - cast_receiver = true; - } - if (supported_cert & OEMCrypto_Supports_RSA_3072bit) { - supports_rsa_3072 = true; - } + const uint32_t supported_cert = OEMCrypto_SupportedCertificates(); + if (supported_cert & OEMCrypto_Supports_RSA_CAST) { + cast_receiver = true; + } + if (supported_cert & OEMCrypto_Supports_RSA_3072bit) { + supports_rsa_3072 = true; + } + if (supported_cert & OEMCrypto_Supports_ECC_secp256r1) { + supports_secp256r1 = true; } printf("cast_receiver = %s.\n", cast_receiver ? "true" : "false"); + printf("supports_rsa_3072 = %s.\n", supports_rsa_3072 ? "true" : "false"); + printf("supports_secp256r1 = %s.\n", supports_secp256r1 ? "true" : "false"); resource_rating = OEMCrypto_ResourceRatingTier(); printf("resource_rating = %u, security level %u.\n", resource_rating, static_cast(OEMCrypto_SecurityLevel())); @@ -101,7 +117,6 @@ void DeviceFeatures::Initialize() { switch (derive_key_method) { case NO_METHOD: printf("NO_METHOD: Cannot derive known session keys.\n"); - // Note: cast_receiver left unchanged because set by user on command line. uses_keybox = false; loads_certificate = false; generic_crypto = false; @@ -140,23 +155,9 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) { provisioning_method == OEMCrypto_BootCertificateChain) FilterOut(&filter, "OEMCryptoLoadsCert*"); if (!generic_crypto) FilterOut(&filter, "*GenericCrypto*"); - if (!cast_receiver) FilterOut(&filter, "*CastReceiver*"); - if (!supports_cas) FilterOut(&filter, "*CasOnly*"); if (derive_key_method == NO_METHOD) FilterOut(&filter, "*SessionTest*"); - if (provisioning_method - != OEMCrypto_OEMCertificate) FilterOut(&filter, "*Prov30*"); - if (provisioning_method != OEMCrypto_BootCertificateChain) - FilterOut(&filter, "*Prov40*"); - if (!supports_rsa_3072) FilterOut(&filter, "*RSAKey3072*"); - if (api_version < 9) FilterOut(&filter, "*API09*"); - if (api_version < 10) FilterOut(&filter, "*API10*"); - if (api_version < 11) FilterOut(&filter, "*API11*"); - if (api_version < 12) FilterOut(&filter, "*API12*"); - if (api_version < 13) FilterOut(&filter, "*API13*"); - if (api_version < 14) FilterOut(&filter, "*API14*"); - if (api_version < 15) FilterOut(&filter, "*API15*"); - if (api_version < 16) FilterOut(&filter, "*API16*"); if (api_version < 17) FilterOut(&filter, "*API17*"); + if (api_version < 18) FilterOut(&filter, "*API18*"); // clang-format on // Some tests may require root access. If user is not root, filter these tests // out. @@ -175,38 +176,32 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) { } void DeviceFeatures::PickDerivedKey() { - if (api_version >= 12) { - switch (provisioning_method) { - case OEMCrypto_OEMCertificate: - derive_key_method = TEST_PROVISION_30; - return; - case OEMCrypto_DrmCertificate: - if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { - derive_key_method = LOAD_TEST_RSA_KEY; - } - return; - case OEMCrypto_Keybox: - // Fall through to api_version < 12 case. - break; - case OEMCrypto_BootCertificateChain: - derive_key_method = TEST_PROVISION_40; - return; - case OEMCrypto_ProvisioningError: - printf( - "ERROR: OEMCrypto_GetProvisioningMethod() returns " - "OEMCrypto_ProvisioningError\n"); - // Then fall through to api_version < 12 case. - break; - } - } - if (uses_keybox) { - // If device uses a keybox, try to load the test keybox. - if (OEMCrypto_ERROR_NOT_IMPLEMENTED != - OEMCrypto_LoadTestKeybox(nullptr, 0)) { - derive_key_method = LOAD_TEST_KEYBOX; - } - } else if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { - derive_key_method = LOAD_TEST_RSA_KEY; + switch (provisioning_method) { + case OEMCrypto_OEMCertificate: + derive_key_method = TEST_PROVISION_30; + return; + case OEMCrypto_DrmCertificate: + if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { + derive_key_method = LOAD_TEST_RSA_KEY; + } + return; + case OEMCrypto_Keybox: + if (OEMCrypto_ERROR_NOT_IMPLEMENTED != + OEMCrypto_LoadTestKeybox(nullptr, 0)) { + derive_key_method = LOAD_TEST_KEYBOX; + } + return; + case OEMCrypto_BootCertificateChain: + derive_key_method = TEST_PROVISION_40; + return; + case OEMCrypto_ProvisioningError: + printf( + "ERROR: OEMCrypto_GetProvisioningMethod() returns " + "OEMCrypto_ProvisioningError\n"); + if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) { + derive_key_method = LOAD_TEST_RSA_KEY; + } + return; } } diff --git a/oemcrypto/test/oec_device_features.h b/oemcrypto/test/oec_device_features.h index a65eef19..ec0a8fc1 100644 --- a/oemcrypto/test/oec_device_features.h +++ b/oemcrypto/test/oec_device_features.h @@ -10,7 +10,7 @@ namespace wvoec { // These tests are designed to work for this version: -constexpr unsigned int kCurrentAPI = 17; +constexpr unsigned int kCurrentAPI = 18; // The API version when Core Messages were introduced. constexpr unsigned int kCoreMessagesAPI = 16; // The API version when we stopped encrypting key control blocks. @@ -47,6 +47,7 @@ class DeviceFeatures { bool cast_receiver; // Device supports alternate rsa signature padding. bool usage_table; // Device saves usage information. bool supports_rsa_3072; // Device supports 3072 bit RSA keys. + bool supports_secp256r1; // Device supports secp256r1 ECC keys. bool supports_level_1; // Device supports Level 1 security. uint32_t resource_rating; // Device's resource rating tier. bool supports_crc; // Supported decrypt hash type CRC. diff --git a/oemcrypto/test/oec_key_deriver.h b/oemcrypto/test/oec_key_deriver.h index 4741da49..57d8fc1d 100644 --- a/oemcrypto/test/oec_key_deriver.h +++ b/oemcrypto/test/oec_key_deriver.h @@ -19,6 +19,7 @@ namespace wvoec { constexpr size_t kMaxTestRSAKeyLength = 2000; // Rough estimate. constexpr size_t kMaxCoreProvRequest = 150; // Rough estimate. +constexpr size_t kMaxX509CertLength = 4000; // Rough estimate. // This structure will be signed to simulate a provisioning response from the // server. @@ -31,6 +32,15 @@ struct RSAPrivateKeyMessage { uint32_t nonce; }; +// This structure simulates a provisioning 4.0 response from the server. +// However, OEMCrypto doesn't need to load this response, since it doesn't have +// any secrets to be handled. It is just a dummy struct for the tests to +// compile. +struct Prov40CertMessage { + uint8_t device_certificate[kMaxX509CertLength]; + uint32_t nonce; +}; + // Holds an encryption key and can encrypt a provisioning message. It also can // encrypt short buffers using CBC, such as content keys in a license. class Encryptor { diff --git a/oemcrypto/test/oec_session_util.cpp b/oemcrypto/test/oec_session_util.cpp index edeb798e..9e442fb9 100644 --- a/oemcrypto/test/oec_session_util.cpp +++ b/oemcrypto/test/oec_session_util.cpp @@ -7,6 +7,7 @@ #include "oec_session_util.h" +#include #include #include #include @@ -44,6 +45,8 @@ using namespace std; +using testing::AnyOf; + // GTest requires PrintTo to be in the same namespace as the thing it prints, // which is std::vector in this case. namespace std { @@ -108,8 +111,8 @@ void EncryptCTR(const vector& in_buffer, const uint8_t* key, // the plaintext of that key so that it can encrypt the test data. It resizes // the provided vectors and fills them with the expected and actual decrypt // results. Returns the result of OEMCrypto_DecryptCENC(). -OEMCryptoResult DecryptCTR(OEMCrypto_SESSION session_id, const uint8_t* key, - vector* expected_data, +OEMCryptoResult DecryptCTR(const vector& key_handle, + const uint8_t* key, vector* expected_data, vector* actual_data) { vector encrypted_data(kTestSubsampleSectionSize); expected_data->resize(encrypted_data.size()); @@ -129,7 +132,8 @@ OEMCryptoResult DecryptCTR(OEMCrypto_SESSION session_id, const uint8_t* key, OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; // Decrypt the data - return OEMCrypto_DecryptCENC(session_id, &sample_description, 1, &pattern); + return OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); } } // namespace @@ -262,11 +266,9 @@ RoundTrip:: gen_signature.resize(gen_signature_length); } if (!verify_request || result != OEMCrypto_SUCCESS) return result; - if (global_features.api_version >= kCoreMessagesAPI) { - std::string core_message(reinterpret_cast(data.data()), - core_message_length); - FillAndVerifyCoreRequest(core_message); - } + std::string core_message(reinterpret_cast(data.data()), + core_message_length); + FillAndVerifyCoreRequest(core_message); VerifyRequestSignature(data, gen_signature, core_message_length); return result; } @@ -382,14 +384,6 @@ void ProvisioningRoundTrip::FillAndVerifyCoreRequest( EXPECT_EQ(global_features.api_version, core_request_.api_major_version); EXPECT_EQ(session()->nonce(), core_request_.nonce); EXPECT_EQ(session()->session_id(), core_request_.session_id); - size_t device_id_length = core_request_.device_id.size(); - std::vector device_id(device_id_length); - EXPECT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetDeviceID(device_id.data(), &device_id_length)); - EXPECT_EQ(core_request_.device_id.size(), device_id_length); - std::string device_id_string(reinterpret_cast(device_id.data()), - device_id_length); - EXPECT_EQ(device_id_string, core_request_.device_id); } void ProvisioningRoundTrip::CreateDefaultResponse() { @@ -441,17 +435,13 @@ void ProvisioningRoundTrip:: } void ProvisioningRoundTrip::SignResponse() { - if (global_features.api_version >= kCoreMessagesAPI) { - CoreMessageFeatures features = - CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); - ASSERT_TRUE( - oemcrypto_core_message::serialize::CreateCoreProvisioningResponse( - features, core_response_, core_request_, - &serialized_core_message_)); - // Resizing for huge core message length unit tests. - serialized_core_message_.resize( - std::max(required_core_message_size_, serialized_core_message_.size())); - } + CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreProvisioningResponse( + features, core_response_, core_request_, &serialized_core_message_)); + // Resizing for huge core message length unit tests. + serialized_core_message_.resize( + std::max(required_core_message_size_, serialized_core_message_.size())); // Make the message buffer a just big enough, or the // required size, whichever is larger. const size_t message_size = @@ -521,30 +511,6 @@ OEMCryptoResult ProvisioningRoundTrip::LoadResponse(Session* session) { return sts; } -#ifdef TEST_OEMCRYPTO_V15 -// If this platform supports v15 functions, then will test with them: -# define OEMCrypto_RewrapDeviceRSAKey_V15 OEMCrypto_RewrapDeviceRSAKey -# define OEMCrypto_RewrapDeviceRSAKey30_V15 OEMCrypto_RewrapDeviceRSAKey30 - -#else -// If this platform does not support v15 functions, we just need to stub these -// out so that the tests compile. -OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30_V15( - OEMCrypto_SESSION, const uint32_t*, const uint8_t*, size_t, const uint8_t*, - size_t, const uint8_t*, uint8_t*, size_t*) { - LOGE("Support for v15 functions not included. Define TEST_OEMCRYPTO_V15."); - return OEMCrypto_ERROR_NOT_IMPLEMENTED; -} - -OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey_V15( - OEMCrypto_SESSION, const uint8_t*, size_t, const uint8_t*, size_t, - const uint32_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, - size_t*) { - LOGE("Support for v15 functions not included. Define TEST_OEMCRYPTO_V15."); - return OEMCrypto_ERROR_NOT_IMPLEMENTED; -} -#endif - template const T* ProvisioningRoundTrip::RemapPointer(const T* response_pointer) const { const uint8_t* original_pointer = @@ -561,33 +527,12 @@ const T* ProvisioningRoundTrip::RemapPointer(const T* response_pointer) const { OEMCryptoResult ProvisioningRoundTrip::LoadResponseNoRetry( Session* session, size_t* wrapped_key_length) { EXPECT_NE(session, nullptr); - if (global_features.api_version >= kCoreMessagesAPI) { - VerifyEncryptAndSignResponseLengths(); - return OEMCrypto_LoadProvisioning( - session->session_id(), encrypted_response_.data(), - encrypted_response_.size(), serialized_core_message_.size(), - response_signature_.data(), response_signature_.size(), - wrapped_rsa_key_.data(), wrapped_key_length); - } else if (global_features.provisioning_method == OEMCrypto_Keybox) { - VerifyEncryptAndSignResponseLengths(); - return OEMCrypto_RewrapDeviceRSAKey_V15( - session->session_id(), encrypted_response_.data(), - encrypted_response_.size(), response_signature_.data(), - response_signature_.size(), RemapPointer(&response_data_.nonce), - RemapPointer(response_data_.rsa_key), - encrypted_response_data_.rsa_key_length, - RemapPointer(response_data_.rsa_key_iv), wrapped_rsa_key_.data(), - wrapped_key_length); - } else { - return OEMCrypto_RewrapDeviceRSAKey30_V15( - session->session_id(), &encrypted_response_data_.nonce, - RemapPointer(response_data_.enc_message_key), - response_data_.enc_message_key_length, - RemapPointer(response_data_.rsa_key), - encrypted_response_data_.rsa_key_length, - RemapPointer(response_data_.rsa_key_iv), wrapped_rsa_key_.data(), - wrapped_key_length); - } + VerifyEncryptAndSignResponseLengths(); + return OEMCrypto_LoadProvisioning( + session->session_id(), encrypted_response_.data(), + encrypted_response_.size(), serialized_core_message_.size(), + response_signature_.data(), response_signature_.size(), + wrapped_rsa_key_.data(), wrapped_key_length); } void ProvisioningRoundTrip::VerifyLoadFailed() { @@ -596,6 +541,223 @@ void ProvisioningRoundTrip::VerifyLoadFailed() { ASSERT_EQ(zero, wrapped_rsa_key_); } +void Provisioning40RoundTrip::PrepareSession(bool is_oem_key) { + const size_t buffer_size = 5000; // Make sure it is large enough. + std::vector public_key(buffer_size); + size_t public_key_size = buffer_size; + std::vector public_key_signature(buffer_size); + size_t public_key_signature_size = buffer_size; + std::vector wrapped_private_key(buffer_size); + size_t wrapped_private_key_size = buffer_size; + OEMCrypto_PrivateKeyType key_type; + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_GenerateCertificateKeyPair( + session()->session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type)); + wrapped_private_key.resize(wrapped_private_key_size); + public_key.resize(public_key_size); + + if (is_oem_key) { + wrapped_oem_key_ = wrapped_private_key; + oem_public_key_ = public_key; + oem_key_type_ = key_type; + } else { + wrapped_drm_key_ = wrapped_private_key; + drm_public_key_ = public_key; + drm_key_type_ = key_type; + } +} + +void Provisioning40RoundTrip::FillAndVerifyCoreRequest( + const std::string& core_message_string) { + EXPECT_TRUE( + oemcrypto_core_message::deserialize::CoreProvisioning40RequestFromMessage( + core_message_string, &core_request_)); + EXPECT_EQ(global_features.api_version, core_request_.api_major_version); + EXPECT_EQ(session()->nonce(), core_request_.nonce); + EXPECT_EQ(session()->session_id(), core_request_.session_id); +} + +void Provisioning40RoundTrip::VerifyRequestSignature( + const vector& data, const vector& generated_signature, + size_t /* core_message_length */) { + ASSERT_NO_FATAL_FAILURE( + session()->VerifySignature(data, generated_signature.data(), + generated_signature.size(), kSign_RSASSA_PSS)); +} + +OEMCryptoResult Provisioning40RoundTrip::LoadOEMCertResponse() { + EXPECT_GE(wrapped_oem_key_.size(), 0UL); + return OEMCrypto_InstallOemPrivateKey( + session()->session_id(), oem_key_type_, + reinterpret_cast(wrapped_oem_key_.data()), + wrapped_oem_key_.size()); +} + +OEMCryptoResult Provisioning40RoundTrip::LoadDRMCertResponse() { + EXPECT_GE(wrapped_drm_key_.size(), 0UL); + return OEMCrypto_LoadDRMPrivateKey(session()->session_id(), drm_key_type_, + wrapped_drm_key_.data(), + wrapped_drm_key_.size()); +} + +void Provisioning40CastRoundTrip::PrepareSession() { + const size_t buffer_size = 5000; // Make sure it is large enough. + std::vector public_key(buffer_size); + size_t public_key_size = buffer_size; + std::vector public_key_signature(buffer_size); + size_t public_key_signature_size = buffer_size; + std::vector wrapped_private_key(buffer_size); + size_t wrapped_private_key_size = buffer_size; + OEMCrypto_PrivateKeyType key_type; + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_GenerateCertificateKeyPair( + session()->session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type)); + wrapped_private_key.resize(wrapped_private_key_size); + public_key.resize(public_key_size); + + wrapped_drm_key_ = wrapped_private_key; + drm_public_key_ = public_key; + drm_key_type_ = key_type; +} + +void Provisioning40CastRoundTrip::LoadDRMPrivateKey() { + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadDRMPrivateKey(session()->session_id(), drm_key_type_, + wrapped_drm_key_.data(), + wrapped_drm_key_.size())); +} + +void Provisioning40CastRoundTrip::FillAndVerifyCoreRequest( + const std::string& core_message_string) { + EXPECT_TRUE( + oemcrypto_core_message::deserialize::CoreProvisioning40RequestFromMessage( + core_message_string, &core_request_)); + EXPECT_EQ(global_features.api_version, core_request_.api_major_version); + EXPECT_EQ(session()->nonce(), core_request_.nonce); + EXPECT_EQ(session()->session_id(), core_request_.session_id); +} + +void Provisioning40CastRoundTrip::VerifyRequestSignature( + const vector& data, const vector& generated_signature, + size_t /* core_message_length */) { + ASSERT_NO_FATAL_FAILURE( + session()->VerifySignature(data, generated_signature.data(), + generated_signature.size(), kSign_RSASSA_PSS)); +} + +// Creates a prov2 response +void Provisioning40CastRoundTrip::CreateDefaultResponse() { + uint32_t algorithm_n = htonl(allowed_schemes_); + memcpy(response_data_.rsa_key, "SIGN", 4); + memcpy(response_data_.rsa_key + 4, &algorithm_n, 4); + memcpy(response_data_.rsa_key + 8, encoded_rsa_key_.data(), + encoded_rsa_key_.size()); + response_data_.rsa_key_length = 8 + encoded_rsa_key_.size(); + response_data_.nonce = session_->nonce(); + response_data_.enc_message_key_length = 0; + core_response_.key_type = OEMCrypto_RSA_Private_Key; + core_response_.enc_private_key = + FindSubstring(response_data_.rsa_key, response_data_.rsa_key_length); + core_response_.enc_private_key_iv = FindSubstring( + response_data_.rsa_key_iv, sizeof(response_data_.rsa_key_iv)); + core_response_.encrypted_message_key = FindSubstring( + response_data_.enc_message_key, response_data_.enc_message_key_length); +} + +void Provisioning40CastRoundTrip::EncryptAndSignResponse() { + session()->key_deriver().PadAndEncryptProvisioningMessage( + &response_data_, &encrypted_response_data_); + core_response_.enc_private_key.length = + encrypted_response_data_.rsa_key_length; + SignResponse(); +} + +void Provisioning40CastRoundTrip::SignResponse() { + CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION); + + // Create prov 2 request struct from prov 4 request + oemcrypto_core_message::ODK_ProvisioningRequest core_request_prov2; + core_request_prov2.api_minor_version = core_request_.api_minor_version; + core_request_prov2.api_major_version = core_request_.api_major_version; + core_request_prov2.nonce = core_request_.nonce; + core_request_prov2.session_id = core_request_.session_id; + memcpy(&core_request_prov2.counter_info, &core_request_.counter_info, + sizeof(core_request_.counter_info)); + + ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreProvisioningResponse( + features, core_response_, core_request_prov2, &serialized_core_message_)); + // Resizing for huge core message length unit tests. + serialized_core_message_.resize( + std::max(required_core_message_size_, serialized_core_message_.size())); + // Make the message buffer a just big enough, or the + // required size, whichever is larger. + const size_t message_size = + std::max(required_message_size_, serialized_core_message_.size() + + sizeof(encrypted_response_data_)); + // Stripe the encrypted message. + encrypted_response_.resize(message_size); + for (size_t i = 0; i < encrypted_response_.size(); i++) { + encrypted_response_[i] = i & 0xFF; + } + ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size()); + memcpy(encrypted_response_.data(), serialized_core_message_.data(), + serialized_core_message_.size()); + ASSERT_GE(encrypted_response_.size(), + serialized_core_message_.size() + sizeof(encrypted_response_data_)); + memcpy(encrypted_response_.data() + serialized_core_message_.size(), + reinterpret_cast(&encrypted_response_data_), + sizeof(encrypted_response_data_)); + session()->key_deriver().ServerSignBuffer(encrypted_response_.data(), + encrypted_response_.size(), + &response_signature_); + SetEncryptAndSignResponseLengths(); +} + +OEMCryptoResult Provisioning40CastRoundTrip::LoadResponse(Session* session) { + EXPECT_NE(session, nullptr); + // Write corpus for oemcrypto_load_provisioning_fuzz. Fuzz script expects + // unencrypted response from provisioning server as input corpus data. + // Data will be encrypted and signed again explicitly by fuzzer script after + // mutations. + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_load_provisioning_fuzz_seed_corpus"); + // Corpus for license response fuzzer should be in the format: + // unencrypted (core_response + response_data). + AppendToFile(file_name, reinterpret_cast(&core_response_), + sizeof(ODK_ParsedProvisioning)); + AppendToFile(file_name, reinterpret_cast(&response_data_), + sizeof(response_data_)); + } + size_t wrapped_key_length = 0; + OEMCryptoResult sts = LoadResponseNoRetry(session, &wrapped_key_length); + if (sts != OEMCrypto_ERROR_SHORT_BUFFER) return sts; + wrapped_rsa_key_.assign(wrapped_key_length, 0); + sts = LoadResponseNoRetry(session, &wrapped_key_length); + if (sts == OEMCrypto_SUCCESS) { + wrapped_rsa_key_.resize(wrapped_key_length); + } + return sts; +} + +OEMCryptoResult Provisioning40CastRoundTrip::LoadResponseNoRetry( + Session* session, size_t* wrapped_key_length) { + EXPECT_NE(session, nullptr); + VerifyEncryptAndSignResponseLengths(); + return OEMCrypto_LoadProvisioning( + session->session_id(), encrypted_response_.data(), + encrypted_response_.size(), serialized_core_message_.size(), + response_signature_.data(), response_signature_.size(), + wrapped_rsa_key_.data(), wrapped_key_length); +} + void LicenseRoundTrip::VerifyRequestSignature( const vector& data, const vector& generated_signature, size_t core_message_length) { @@ -678,16 +840,14 @@ void LicenseRoundTrip::CreateDefaultResponse() { // Fill in the default core_response_ fields, except the substrings, which are // filled in the next function. core_response_.nonce_required = - ((wvoec::kControlNonceEnabled | wvoec::kControlNonceOrEntry | - wvoec::kControlNonceRequired) & - control_) - ? 1 - : 0; + (wvoec::kControlNonceEnabled | wvoec::kControlNonceOrEntry | + wvoec::kControlNonceRequired) & + control_; core_response_.license_type = license_type_; FillCoreResponseSubstrings(); } -void LicenseRoundTrip::ConvertDataToValidBools(ODK_ParsedLicense* t) { +void LicenseRoundTrip::ConvertDataToValidBools(ODK_Packing_ParsedLicense* t) { t->nonce_required = ConvertByteToValidBoolean(&t->nonce_required); t->timer_limits.soft_enforce_playback_duration = ConvertByteToValidBoolean( &t->timer_limits.soft_enforce_playback_duration); @@ -706,19 +866,19 @@ void LicenseRoundTrip::InjectFuzzedTimerLimits( void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data, size_t size) { - // Interpreting fuzz data as unencrypted core_response + message_data + // Interpreting fuzz data as unencrypted core_response + response_data + + // key_array FuzzedData fuzzed_data(data, size); // Copy core_response from data. fuzzed_data.Fill(&core_response_, sizeof(core_response_)); - // Maximum number of keys could be kMaxNumKeys(30). key_array_length can be - // any random value as it is read from fuzz data. - // Key data array(MessageKeyData keys[kMaxNumKeys]) will be looped over - // key_array_length number of times during LoadLicense. If key_array_length is - // more than kMaxNumKeys, setting it to max value of kMaxNumKeys as we should - // not go out of bounds of this array length. For corpus, this value is - // already hard coded to 4. + // Copy response_data from data. + fuzzed_data.Fill(&response_data_, sizeof(response_data_)); + + // If key_array_length is more than kMaxNumKeys, we set it to kMaxNumKeys to + // prevent it from going out of bounds. For corpus, this value is already hard + // coded to 4. if (core_response_.key_array_length > kMaxNumKeys) { core_response_.key_array_length = kMaxNumKeys; } @@ -726,6 +886,13 @@ void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data, // For corpus data, this value gets set to 4, but we need to test other // scenarios too, hence reading key_array_length value. set_num_keys(core_response_.key_array_length); + + // Copy key_array from data. + key_array_.resize(num_keys_); + core_response_.key_array = key_array_.data(); + fuzzed_data.Fill(core_response_.key_array, + num_keys_ * sizeof(*core_response_.key_array)); + ConvertDataToValidBools(&core_response_); // TODO(b/157520981): Once assertion bug is fixed, for loop can be removed. @@ -746,9 +913,7 @@ void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data, } } - // Copy response_data from data and set nonce to match one in request to pass - // nonce validations. - fuzzed_data.Fill(&response_data_, sizeof(response_data_)); + // Set nonce to match one in request to pass nonce validations. for (uint32_t i = 0; i < num_keys_; ++i) { response_data_.keys[i].control.nonce = htonl(session()->nonce()); } @@ -795,27 +960,30 @@ void LicenseRoundTrip::FillCoreResponseSubstrings() { sizeof(response_data_.srm_restriction_data)); } core_response_.key_array_length = num_keys_; + key_array_.clear(); for (unsigned int i = 0; i < num_keys_; i++) { - core_response_.key_array[i].key_id = FindSubstring( - response_data_.keys[i].key_id, response_data_.keys[i].key_id_length); - core_response_.key_array[i].key_data_iv = FindSubstring( - response_data_.keys[i].key_iv, sizeof(response_data_.keys[i].key_iv)); - core_response_.key_array[i].key_data = - FindSubstring(response_data_.keys[i].key_data, - response_data_.keys[i].key_data_length); + OEMCrypto_KeyObject obj; + obj.key_id = FindSubstring(response_data_.keys[i].key_id, + response_data_.keys[i].key_id_length); + obj.key_data_iv = FindSubstring(response_data_.keys[i].key_iv, + sizeof(response_data_.keys[i].key_iv)); + obj.key_data = FindSubstring(response_data_.keys[i].key_data, + response_data_.keys[i].key_data_length); if (core_request().api_major_version < kClearControlBlockAPIMajor || (core_request().api_major_version == kClearControlBlockAPIMajor && core_request().api_minor_version < kClearControlBlockAPIMinor)) { - core_response_.key_array[i].key_control_iv = + obj.key_control_iv = FindSubstring(response_data_.keys[i].control_iv, sizeof(response_data_.keys[i].control_iv)); } else { - core_response_.key_array[i].key_control_iv = FindSubstring(nullptr, 0); + obj.key_control_iv = FindSubstring(nullptr, 0); } - core_response_.key_array[i].key_control = - FindSubstring(&response_data_.keys[i].control, - sizeof(response_data_.keys[i].control)); + obj.key_control = FindSubstring(&response_data_.keys[i].control, + sizeof(response_data_.keys[i].control)); + key_array_.push_back(obj); } + core_response_.key_array = key_array_.data(); + core_response_.key_array_length = static_cast(key_array_.size()); } void LicenseRoundTrip::EncryptResponse(bool force_clear_kcb) { @@ -864,26 +1032,22 @@ void LicenseRoundTrip::EncryptResponse(bool force_clear_kcb) { void LicenseRoundTrip::CreateCoreLicenseResponseWithFeatures( const CoreMessageFeatures& features) { - if (api_version_ < kCoreMessagesAPI) { - serialized_core_message_.resize(0); - } else { - if (core_request_.api_major_version == 0) { - // If we don't have a valid request, then we should at least set the - // version number of the request so that CreateCoreLicenseResponse can - // compute the version number of the response. - core_request_.api_major_version = ODK_MAJOR_VERSION; - core_request_.api_minor_version = ODK_MINOR_VERSION; - } - std::string request_hash_string( - reinterpret_cast(request_hash_), sizeof(request_hash_)); - ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse( - features, core_response_, core_request_, request_hash_string, - &serialized_core_message_)); - // Resize serialize core message to be just big enough or required core - // message size, whichever is larger. - serialized_core_message_.resize( - std::max(required_core_message_size_, serialized_core_message_.size())); + if (core_request_.api_major_version == 0) { + // If we don't have a valid request, then we should at least set the + // version number of the request so that CreateCoreLicenseResponse can + // compute the version number of the response. + core_request_.api_major_version = ODK_MAJOR_VERSION; + core_request_.api_minor_version = ODK_MINOR_VERSION; } + std::string request_hash_string(reinterpret_cast(request_hash_), + sizeof(request_hash_)); + ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse( + features, core_response_, core_request_, request_hash_string, + &serialized_core_message_)); + // Resize serialize core message to be just big enough or required core + // message size, whichever is larger. + serialized_core_message_.resize( + std::max(required_core_message_size_, serialized_core_message_.size())); } void LicenseRoundTrip::SignEncryptedResponse() { @@ -944,11 +1108,14 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session, const std::string file_name = GetFileName("oemcrypto_load_license_fuzz_seed_corpus"); // Corpus for license response fuzzer should be in the format: - // core_response + response_data. + // core_response + response_data + key_array. AppendToFile(file_name, reinterpret_cast(&core_response_), - sizeof(ODK_ParsedLicense)); + sizeof(core_response_)); AppendToFile(file_name, reinterpret_cast(&response_data_), sizeof(response_data_)); + AppendToFile( + file_name, reinterpret_cast(core_response_.key_array), + core_response_.key_array_length * sizeof(*core_response_.key_array)); } // Some tests adjust the offset to be beyond the length of the message. Here, @@ -966,22 +1133,10 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session, reinterpret_cast(&encrypted_response_data_), reinterpret_cast(&encrypted_response_data_) + sizeof(encrypted_response_data_)); - OEMCryptoResult result; - if (api_version_ < kCoreMessagesAPI) { - result = OEMCrypto_LoadKeys( - session->session_id(), double_message.data(), - encrypted_response_.size(), response_signature_.data(), - response_signature_.size(), core_response_.enc_mac_keys_iv, - core_response_.enc_mac_keys, core_response_.key_array_length, - core_response_.key_array, core_response_.pst, - core_response_.srm_restriction_data, - static_cast(core_response_.license_type)); - } else { - result = OEMCrypto_LoadLicense( - session->session_id(), double_message.data(), - encrypted_response_.size(), serialized_core_message_.size(), - response_signature_.data(), response_signature_.size()); - } + OEMCryptoResult result = OEMCrypto_LoadLicense( + session->session_id(), double_message.data(), encrypted_response_.size(), + serialized_core_message_.size(), response_signature_.data(), + response_signature_.size()); if (verify_keys && result == OEMCrypto_SUCCESS) { // Give the session object a copy of the license truth data so that it can // call SelectKey, use key control information, and so that it has key data @@ -1006,7 +1161,7 @@ OEMCryptoResult LicenseRoundTrip::ReloadResponse(Session* session) { // This function verifies that the key control block reported by OEMCrypto agree // with the truth key control block. Failures in this function probably -// indicate the OEMCrypto_LoadLicense/LoadKeys did not correctly process the key +// indicate the OEMCrypto_LoadLicense did not correctly process the key // control block. void LicenseRoundTrip::VerifyTestKeys(Session* session) { for (unsigned int i = 0; i < num_keys_; i++) { @@ -1291,15 +1446,16 @@ void EntitledMessage::VerifyDecrypt() { for (unsigned int i = 0; i < num_keys_; i++) { const EntitledContentKeyData* const key_data = &entitled_key_data_[i]; - OEMCryptoResult result = OEMCrypto_SelectKey( + vector key_handle; + OEMCryptoResult result = GetKeyHandleIntoVector( entitled_key_session_, key_data->content_key_id, - key_data->content_key_id_length, OEMCrypto_CipherMode_CENC); + key_data->content_key_id_length, OEMCrypto_CipherMode_CENC, key_handle); ASSERT_EQ(result, OEMCrypto_SUCCESS) << "For key " << i; vector expected_data; vector actual_data; - result = DecryptCTR(entitled_key_session_, key_data->content_key_data, - &expected_data, &actual_data); + result = DecryptCTR(key_handle, key_data->content_key_data, &expected_data, + &actual_data); EXPECT_EQ(result, OEMCrypto_SUCCESS) << "For key " << i; EXPECT_EQ(actual_data, expected_data) << "For key " << i; } @@ -1310,22 +1466,14 @@ void RenewalRoundTrip::VerifyRequestSignature( size_t core_message_length) { ASSERT_EQ(HMAC_SHA256_SIGNATURE_SIZE, generated_signature.size()); std::vector expected_signature; - if (license_messages_->api_version() < kCoreMessagesAPI) { - // For v15 or earlier, we only sign the message body. Ignore the core - // message. - std::vector subdata(data.begin() + core_message_length, - data.end()); - session()->key_deriver().ClientSignBuffer(subdata, &expected_signature); - } else { - session()->key_deriver().ClientSignBuffer(data, &expected_signature); - } + session()->key_deriver().ClientSignBuffer(data, &expected_signature); ASSERT_EQ(expected_signature, generated_signature); } void RenewalRoundTrip::FillAndVerifyCoreRequest( const std::string& core_message_string) { - if (license_messages_->api_version() < kCoreMessagesAPI || is_release_) { - // For v15 or for a release, we expect that no core request was created. + if (is_release_) { + // For a release we expect that no core request was created. EXPECT_FALSE( oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage( core_message_string, &core_request_)); @@ -1342,17 +1490,9 @@ void RenewalRoundTrip::FillAndVerifyCoreRequest( } void RenewalRoundTrip::CreateDefaultResponse() { - if (license_messages_->api_version() < kCoreMessagesAPI || is_release_) { + if (is_release_) { uint32_t control = 0; uint32_t nonce = 0; - // If this is a v15 device, and a v15 license, and the license used a nonce, - // then the response should require a new nonce, too. - if (global_features.api_version < kCoreMessagesAPI && - (license_messages_->control() & wvoec::kControlNonceEnabled)) { - control = wvoec::kControlNonceEnabled; - session_->GenerateNonce(); - nonce = session_->nonce(); - } // A single key object with no key id should update all keys. constexpr size_t index = 0; response_data_.keys[index].key_id_length = 0; @@ -1374,29 +1514,19 @@ void RenewalRoundTrip::CreateDefaultResponse() { void RenewalRoundTrip::EncryptAndSignResponse() { // Renewal messages are not encrypted. encrypted_response_data_ = response_data_; - // Either create a KeyRefreshObject for a call to RefreshKeys or a core - // response for a call to LoadRenewal. - if (license_messages_->api_version() < kCoreMessagesAPI) { - refresh_object_.key_id = FindSubstring(nullptr, 0); - refresh_object_.key_control_iv = FindSubstring(nullptr, 0); - refresh_object_.key_control = - FindSubstring(&response_data_.keys[0].control, - sizeof(response_data_.keys[0].control)); - serialized_core_message_.resize(0); - } else { - // TODO(b/191724203): Test renewal server has different version from license - // server. - ASSERT_NE(license_messages_, nullptr); - CoreMessageFeatures features = - CoreMessageFeatures::DefaultFeatures(license_messages_->api_version()); - ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreRenewalResponse( - features, core_request_, renewal_duration_seconds_, - &serialized_core_message_)); - // Resize serialize core message to be just big enough or required core - // message size, whichever is larger. - serialized_core_message_.resize( - std::max(required_core_message_size_, serialized_core_message_.size())); - } + // Create a core response for a call to LoadRenewal. + // TODO(b/191724203): Test renewal server has different version from license + // server. + ASSERT_NE(license_messages_, nullptr); + CoreMessageFeatures features = + CoreMessageFeatures::DefaultFeatures(license_messages_->api_version()); + ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreRenewalResponse( + features, core_request_, renewal_duration_seconds_, + &serialized_core_message_)); + // Resize serialize core message to be just big enough or required core + // message size, whichever is larger. + serialized_core_message_.resize( + std::max(required_core_message_size_, serialized_core_message_.size())); // Make the message buffer a just big enough, or the // required size, whichever is larger. const size_t message_size = @@ -1468,17 +1598,10 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(Session* session) { sizeof(encrypted_response_data_)); } VerifyEncryptAndSignResponseLengths(); - if (license_messages_->api_version() < kCoreMessagesAPI) { - return OEMCrypto_RefreshKeys( - session->session_id(), encrypted_response_.data(), - encrypted_response_.size(), response_signature_.data(), - response_signature_.size(), 1, &refresh_object_); - } else { - return OEMCrypto_LoadRenewal( - session->session_id(), encrypted_response_.data(), - encrypted_response_.size(), serialized_core_message_.size(), - response_signature_.data(), response_signature_.size()); - } + return OEMCrypto_LoadRenewal( + session->session_id(), encrypted_response_.data(), + encrypted_response_.size(), serialized_core_message_.size(), + response_signature_.data(), response_signature_.size()); } std::unordered_map, @@ -1589,29 +1712,27 @@ void Session::GenerateDerivedKeysFromSessionKey() { enc_context); } -void Session::TestDecryptCTR(bool select_key_first, +void Session::TestDecryptCTR(bool get_fresh_key_handle_first, OEMCryptoResult expected_result, size_t key_index) { - OEMCryptoResult select_result = OEMCrypto_SUCCESS; - if (select_key_first) { + OEMCryptoResult getkeyhandle_result = OEMCrypto_SUCCESS; + if (get_fresh_key_handle_first) { // Select the key (from FillSimpleMessage) - select_result = OEMCrypto_SelectKey( - session_id(), license_.keys[key_index].key_id, - license_.keys[key_index].key_id_length, OEMCrypto_CipherMode_CENC); + getkeyhandle_result = GetKeyHandle(key_handle_, key_index); } vector unencrypted_data; vector output_buffer; const OEMCryptoResult decrypt_result = - DecryptCTR(session_id(), license_.keys[key_index].key_data, + DecryptCTR(key_handle_, license_.keys[key_index].key_data, &unencrypted_data, &output_buffer); // We only have a few errors that we test are reported. ASSERT_NO_FATAL_FAILURE( - TestDecryptResult(expected_result, select_result, decrypt_result)) - << "Either SelectKey or DecryptCENC should return " << expected_result - << ", but they returned " << select_result << " and " << decrypt_result - << ", respectively."; + TestDecryptResult(expected_result, getkeyhandle_result, decrypt_result)) + << "Either GetKeyHandle or DecryptCENC should return " << expected_result + << ", but they returned " << getkeyhandle_result << " and " + << decrypt_result << ", respectively."; if (expected_result == OEMCrypto_SUCCESS) { // No error. ASSERT_EQ(unencrypted_data, output_buffer); } else { @@ -1623,11 +1744,10 @@ void Session::TestDecryptEntitled(OEMCryptoResult expected_result, OEMCrypto_SESSION session_id, const uint8_t* content_key_id, size_t content_key_id_length) { - OEMCryptoResult select_result = OEMCrypto_SUCCESS; // Select the key (from FillSimpleMessage) - select_result = - OEMCrypto_SelectKey(session_id, content_key_id, content_key_id_length, - OEMCrypto_CipherMode_CENC); + const OEMCryptoResult getkeyhandle_result = + GetKeyHandleIntoVector(session_id, content_key_id, content_key_id_length, + OEMCrypto_CipherMode_CENC, key_handle_); vector unencrypted_data; vector output_buffer; @@ -1644,55 +1764,61 @@ void Session::TestDecryptEntitled(OEMCryptoResult expected_result, EncryptCTR(unencrypted_data, content_key_id, &sample_description.iv[0], &encrypted_data); // Try to decrypt the data with oemcrypto session id. - const OEMCryptoResult decrypt_result = - OEMCrypto_DecryptCENC(session_id, &sample_description, 1, &pattern); + const OEMCryptoResult decrypt_result = OEMCrypto_DecryptCENC( + key_handle_.data(), key_handle_.size(), &sample_description, 1, &pattern); // We only have a few errors that we test are reported. ASSERT_NO_FATAL_FAILURE( - TestDecryptResult(expected_result, select_result, decrypt_result)) + TestDecryptResult(expected_result, getkeyhandle_result, decrypt_result)) << "Either SelectKey or DecryptCENC should return " << expected_result - << ", but they returned " << select_result << " and " << decrypt_result - << ", respectively."; + << ", but they returned " << getkeyhandle_result << " and " + << decrypt_result << ", respectively."; +} + +OEMCryptoResult Session::GetKeyHandle(vector& key_handle, + size_t key_index, + OEMCryptoCipherMode cipher_mode) { + return GetKeyHandleIntoVector(session_id(), license_.keys[key_index].key_id, + license_.keys[key_index].key_id_length, + cipher_mode, key_handle); } void Session::TestDecryptResult(OEMCryptoResult expected_result, - OEMCryptoResult actual_select_result, + OEMCryptoResult actual_getkeyhandle_result, OEMCryptoResult actual_decrypt_result) { // In most cases, we expect the result to come from either the select key or // from the decrypt call. if (expected_result == OEMCrypto_SUCCESS) { // No error. - ASSERT_EQ(OEMCrypto_SUCCESS, actual_select_result); + ASSERT_EQ(OEMCrypto_SUCCESS, actual_getkeyhandle_result); ASSERT_EQ(OEMCrypto_SUCCESS, actual_decrypt_result); } else if (expected_result == OEMCrypto_ERROR_KEY_EXPIRED || expected_result == OEMCrypto_ERROR_INSUFFICIENT_HDCP || expected_result == OEMCrypto_ERROR_ANALOG_OUTPUT) { // Key expired or output problems may be reported from select key or // decrypt, but must be reported. - ASSERT_TRUE(actual_select_result == expected_result || + ASSERT_TRUE(actual_getkeyhandle_result == expected_result || actual_decrypt_result == expected_result); - } else if (expected_result == OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION && - global_features.api_version >= kCoreMessagesAPI) { + } else if (expected_result == OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION) { // OEMCrypto is allowed to report either this warning or // OEMCrypto_ERROR_INSUFFICIENT_HDCP depending on if it can disable // restricted displays. ASSERT_TRUE( - actual_select_result == OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION || - actual_select_result == OEMCrypto_ERROR_INSUFFICIENT_HDCP || + actual_getkeyhandle_result == + OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION || + actual_getkeyhandle_result == OEMCrypto_ERROR_INSUFFICIENT_HDCP || actual_decrypt_result == OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION || actual_decrypt_result == OEMCrypto_ERROR_INSUFFICIENT_HDCP); } else { // OEM's can fine tune other error codes for debugging. - ASSERT_TRUE(actual_select_result != OEMCrypto_SUCCESS || + ASSERT_TRUE(actual_getkeyhandle_result != OEMCrypto_SUCCESS || actual_decrypt_result != OEMCrypto_SUCCESS); } } -void Session::TestSelectExpired(size_t key_index) { +void Session::TestGetKeyHandleExpired(size_t key_index) { if (global_features.api_version >= 13) { - OEMCryptoResult status = OEMCrypto_SelectKey( - session_id(), license().keys[key_index].key_id, - license().keys[key_index].key_id_length, OEMCrypto_CipherMode_CENC); - // It is OK for SelectKey to succeed with an expired key, but if there is + OEMCryptoResult status = GetKeyHandle(key_handle_, key_index); + // It is OK for GetKeyHandle to succeed with an expired key, but if there is // an error, it must be OEMCrypto_ERROR_KEY_EXIRED. if (status != OEMCrypto_SUCCESS) { ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); @@ -1852,8 +1978,15 @@ void Session::VerifyRsaSignature(const vector& message, const util::RsaSignatureAlgorithm algorithm = padding_scheme == kSign_RSASSA_PSS ? util::kRsaPssDefault : util::kRsaPkcs1Cast; - const OEMCryptoResult result = public_rsa_->VerifySignature( - message.data(), message.size(), signature, signature_length, algorithm); + OEMCrypto_SignatureHashAlgorithm hash_algorithm = OEMCrypto_SHA1; + if (algorithm == util::kRsaPssDefault) { + ASSERT_THAT( + OEMCrypto_GetSignatureHashAlgorithm(session_id(), &hash_algorithm), + AnyOf(OEMCrypto_SUCCESS, OEMCrypto_ERROR_NOT_IMPLEMENTED)); + } + const OEMCryptoResult result = + public_rsa_->VerifySignature(message.data(), message.size(), signature, + signature_length, algorithm, hash_algorithm); ASSERT_EQ(result, OEMCrypto_SUCCESS) << "RSA signature check failed"; } @@ -1886,10 +2019,7 @@ bool Session::GenerateRsaSessionKey(vector* session_key, } *session_key = wvutil::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1"); *enc_session_key = public_rsa_->EncryptSessionKey(*session_key); - if (enc_session_key->empty()) { - return false; - } - return true; + return !enc_session_key->empty(); } bool Session::GenerateEccSessionKey(vector* session_key, @@ -2114,4 +2244,25 @@ void WriteRequestApiCorpus(size_t signature_length, size_t core_message_length, AppendToFile(file_name, reinterpret_cast(data.data()), data.size()); } + +OEMCryptoResult GetKeyHandleIntoVector(OEMCrypto_SESSION session, + const uint8_t* key_id, + size_t key_id_length, + OEMCryptoCipherMode cipher_mode, + vector& key_handle) { + size_t key_handle_length = 0; + const OEMCryptoResult result = OEMCrypto_GetKeyHandle( + session, key_id, key_id_length, cipher_mode, nullptr, &key_handle_length); + if (result == OEMCrypto_SUCCESS) { + LOGE( + "OEMCrypto_GetKeyHandle returned SUCCESS despite getting no key handle " + "buffer"); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } else if (result != OEMCrypto_ERROR_SHORT_BUFFER) { + return result; + } + key_handle.resize(key_handle_length); + return OEMCrypto_GetKeyHandle(session, key_id, key_id_length, cipher_mode, + key_handle.data(), &key_handle_length); +} } // namespace wvoec diff --git a/oemcrypto/test/oec_session_util.h b/oemcrypto/test/oec_session_util.h index 1105ed4b..e13bb519 100644 --- a/oemcrypto/test/oec_session_util.h +++ b/oemcrypto/test/oec_session_util.h @@ -27,8 +27,6 @@ #include "oemcrypto_types.h" #include "pst_report.h" -using namespace std; - // GTest requires PrintTo to be in the same namespace as the thing it prints, // which is std::vector in this case. namespace std { @@ -38,13 +36,15 @@ void PrintTo(const vector& value, ostream* os); } // namespace std namespace wvoec { + +using namespace std; + // OEMCrypto Fuzzing: Set max signture length to 1mb. const size_t MB = 1024 * 1024; -// Make sure this is larger than kMaxKeysPerSession, in oemcrypto_test.cpp +// Make sure this is larger than kMaxKeysPerSession. constexpr size_t kMaxNumKeys = 30; -namespace { #if defined(TEST_SPEED_MULTIPLIER) // Can slow test time limits when // debugging is slowing everything. constexpr int kSpeedMultiplier = TEST_SPEED_MULTIPLIER; @@ -57,7 +57,6 @@ constexpr uint32_t kDuration = 2 * kSpeedMultiplier; constexpr uint32_t kLongDuration = 5 * kSpeedMultiplier; constexpr int32_t kTimeTolerance = 3 * kSpeedMultiplier; constexpr int64_t kUsageTableTimeTolerance = 10 * kSpeedMultiplier; -} // namespace // Note: The API does not specify a maximum key id length. We specify a // maximum just for these tests, so that we have a fixed message size. @@ -158,7 +157,7 @@ class RoundTrip { required_request_signature_size_(0), encrypted_response_length_(0), response_signature_length_(0) {} - virtual ~RoundTrip() {} + virtual ~RoundTrip() = default; // Have OEMCrypto sign a request message and then verify the signature and the // core message. @@ -306,7 +305,7 @@ class ProvisioningRoundTrip size_t* wrapped_key_length); // This takes a pointer in the response_data_ and remaps it to the same // pointer within the encrypted message. This is used for backwards - // compatibliity testing, so that a v15 oemcrypto will accept range checks. + // compatibility testing, so that a v15 oemcrypto will accept range checks. template const T* RemapPointer(const T* response_pointer) const; @@ -319,18 +318,119 @@ class ProvisioningRoundTrip std::vector wrapped_rsa_key_; }; +class Provisioning40RoundTrip + : public RoundTrip< + /* CoreRequest */ oemcrypto_core_message::ODK_Provisioning40Request, + OEMCrypto_PrepAndSignProvisioningRequest, + /* CoreResponse */ ODK_ParsedProvisioning, + /* ResponseData */ Prov40CertMessage> { + public: + Provisioning40RoundTrip(Session* session) + : RoundTrip(session), allowed_schemes_(kSign_RSASSA_PSS) {} + void PrepareSession(bool is_oem_key); + + // Not used. Use Load*CertResponse() below to load OEM/DRM response + // respectively. + void CreateDefaultResponse() override{}; + void EncryptAndSignResponse() override{}; + OEMCryptoResult LoadResponse(Session* session) override { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + + OEMCryptoResult LoadOEMCertResponse(); + OEMCryptoResult LoadDRMCertResponse(); + + const std::vector& wrapped_oem_key() { return wrapped_oem_key_; } + const std::vector& oem_public_key() { return oem_public_key_; } + OEMCrypto_PrivateKeyType oem_key_type() { return oem_key_type_; } + const std::vector& wrapped_drm_key() { return wrapped_drm_key_; } + const std::vector& drm_public_key() { return drm_public_key_; } + OEMCrypto_PrivateKeyType drm_key_type() { return drm_key_type_; } + void set_allowed_schemes(uint32_t allowed_schemes) { + allowed_schemes_ = allowed_schemes; + } + + protected: + bool RequestHasNonce() override { return true; } + void VerifyRequestSignature(const vector& data, + const vector& generated_signature, + size_t core_message_length) override; + // Verify the values of the core response. + virtual void FillAndVerifyCoreRequest( + const std::string& core_message_string) override; + + uint32_t allowed_schemes_; + std::vector wrapped_oem_key_; + std::vector oem_public_key_; + OEMCrypto_PrivateKeyType oem_key_type_; + std::vector wrapped_drm_key_; + std::vector drm_public_key_; + OEMCrypto_PrivateKeyType drm_key_type_; +}; + +class Provisioning40CastRoundTrip + : public RoundTrip< + /* CoreRequest */ oemcrypto_core_message::ODK_Provisioning40Request, + OEMCrypto_PrepAndSignProvisioningRequest, + /* CoreResponse */ ODK_ParsedProvisioning, + /* ResponseData */ RSAPrivateKeyMessage> { + public: + Provisioning40CastRoundTrip(Session* session, + const std::vector& encoded_rsa_key) + : RoundTrip(session), encryptor_(), + encoded_rsa_key_(encoded_rsa_key) {} + + void PrepareSession(); + void LoadDRMPrivateKey(); + void CreateDefaultResponse() override; + void SignResponse(); + void EncryptAndSignResponse() override; + OEMCryptoResult LoadResponse() override { return LoadResponse(session_); } + OEMCryptoResult LoadResponse(Session* session) override; + OEMCryptoResult LoadResponseNoRetry(Session* session, size_t* wrapped_key_length) ; + + // Returned + const std::vector& wrapped_drm_key() { return wrapped_drm_key_; } + const std::vector& wrapped_rsa_key() { return wrapped_rsa_key_; } + const std::vector& drm_public_key() { return drm_public_key_; } + OEMCrypto_PrivateKeyType drm_key_type() { return drm_key_type_; } + void set_allowed_schemes(uint32_t allowed_schemes) { + allowed_schemes_ = allowed_schemes; + } + + protected: + bool RequestHasNonce() override { return true; } + void VerifyRequestSignature(const vector& data, + const vector& generated_signature, + size_t core_message_length) override; + // Verify the values of the core response. + virtual void FillAndVerifyCoreRequest( + const std::string& core_message_string) override; + + uint32_t allowed_schemes_; + Encryptor encryptor_; + std::vector wrapped_oem_key_; + std::vector oem_public_key_; + OEMCrypto_PrivateKeyType oem_key_type_; + std::vector wrapped_drm_key_; + std::vector drm_public_key_; + OEMCrypto_PrivateKeyType drm_key_type_; + std::vector encoded_rsa_key_; + std::vector wrapped_rsa_key_; +}; + class LicenseRoundTrip : public RoundTrip< /* CoreRequest */ oemcrypto_core_message::ODK_LicenseRequest, OEMCrypto_PrepAndSignLicenseRequest, - /* CoreResponse */ ODK_ParsedLicense, + /* CoreResponse */ ODK_Packing_ParsedLicense, /* ResponseData */ MessageData> { public: LicenseRoundTrip(Session* session) : RoundTrip(session), control_(wvoec::kControlNonceEnabled), num_keys_(4), - pst_(""), + pst_(), minimum_srm_version_(0), update_mac_keys_(true), api_version_(kCurrentAPI), @@ -349,7 +449,7 @@ class LicenseRoundTrip void InjectFuzzedResponseData(const uint8_t* data, size_t size); // Used for OEMCrypto Fuzzing: Convert boolean flags in parsed_license to // valid bytes to avoid errors from msan. - void ConvertDataToValidBools(ODK_ParsedLicense* t); + void ConvertDataToValidBools(ODK_Packing_ParsedLicense* t); // Create a license with four keys. Each key is responsible for one of generic // encrypt (key 0), decrypt (key 1), sign (key 2) and verify (key 3). Each key // is allowed only one type of operation. @@ -444,6 +544,9 @@ class LicenseRoundTrip // CreateDefaultResponse. OEMCrypto_LicenseType license_type_; uint8_t request_hash_[ODK_SHA256_HASH_SIZE]; + // Used to hold and add/update key information to be transferred into the core + // response later on. + std::vector key_array_; }; class RenewalRoundTrip @@ -466,7 +569,7 @@ class RenewalRoundTrip void EncryptAndSignResponse() override; void InjectFuzzedResponseData(OEMCrypto_Renewal_Response_Fuzz& fuzzed_data, const uint8_t* renewal_response, - const size_t renewal_response_size); + size_t renewal_response_size); OEMCryptoResult LoadResponse() override { return LoadResponse(session_); } OEMCryptoResult LoadResponse(Session* session) override; uint64_t renewal_duration_seconds() const { @@ -571,7 +674,7 @@ class Session { // and also fill out enc_key_, mac_key_server_, and mac_key_client_. void GenerateDerivedKeysFromSessionKey(); // Encrypt some data and pass to OEMCrypto_DecryptCENC to verify decryption. - void TestDecryptCTR(bool select_key_first = true, + void TestDecryptCTR(bool get_fresh_key_handle_first = true, OEMCryptoResult expected_result = OEMCrypto_SUCCESS, size_t key_index = 0); // Encrypt some data and pass to OEMCrypto_DecryptCENC to verify decryption @@ -580,9 +683,9 @@ class Session { OEMCrypto_SESSION session = 0, const uint8_t* content_key_id = nullptr, size_t content_key_id_length = 0); - // Verify that an attempt to select an expired key either succeeds, or gives - // an actionable error code. - void TestSelectExpired(size_t key_index); + // Verify that an attempt to get a key handle for an expired key either + // succeeds or gives an actionable error code. + void TestGetKeyHandleExpired(size_t key_index); // Calls OEMCrypto_GetOEMPublicCertificate and OEMCrypto_LoadOEMPrivateKey and // loads the OEM cert's public rsa key into public_rsa_. void LoadOEMCert(bool verify_cert = false); @@ -593,7 +696,7 @@ class Session { vector* wrapped_key, bool force); // Loads the default test RSA public key into public_rsa_. void SetTestRsaPublicKey(); - // Loads the specified DRM public key into the appropriate key. + // Loads the specified DRM or OEM public key into the appropriate key. // The provided key is serialized as an ASN.1 DER encoded PrivateKeyInfo. void SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type, const uint8_t* buffer, size_t length); @@ -604,7 +707,7 @@ class Session { // The provided key is serialized as an ASN.1 DER encoded PrivateKeyInfo. void SetEccPublicKeyFromPrivateKeyInfo(const uint8_t* buffer, size_t length); - // Loads the specified DRM public key into the appropriate key. + // Loads the specified DRM or OEM public key into the appropriate key. // The provided key is serialized as an ASN.1 DER encoded SubjectPublicKey. void SetPublicKeyFromSubjectPublicKey(OEMCrypto_PrivateKeyType key_type, const uint8_t* buffer, size_t length); @@ -721,16 +824,29 @@ class Session { void set_license(const MessageData& license) { license_ = license; } + // Gives access to the last key handle used by the Session. Useful if a test + // case uses one of the decrypt test functions above and then wants to perform + // further crypto operations using the same key handle. Also useful if a test + // case needs to inject a specific erroneous key handle into the decrypt test + // functions. + vector& key_handle() { return key_handle_; } + const KeyDeriver& key_deriver() const { return key_deriver_; } void set_mac_keys(const uint8_t* mac_keys) { key_deriver_.set_mac_keys(mac_keys); } + bool IsPublicKeySet() { + return public_rsa_ != nullptr || public_ec_ != nullptr; + } private: + OEMCryptoResult GetKeyHandle( + vector& key_handle, size_t key_index = 0, + OEMCryptoCipherMode cipher_mode = OEMCrypto_CipherMode_CENC); // This compares the actual result with the expected result. If OEMCrypto is // an older version, we allow it to report an equivalent error code. void TestDecryptResult(OEMCryptoResult expected_result, - OEMCryptoResult actual_select_result, + OEMCryptoResult actual_getkeyhandle_result, OEMCryptoResult actual_decryt_result); bool open_ = false; @@ -756,6 +872,7 @@ class Session { static std::mutex ephemeral_key_map_lock_; vector pst_report_buffer_; MessageData license_ = {}; + vector key_handle_; vector encrypted_usage_entry_; uint32_t usage_entry_number_ = 0; @@ -773,6 +890,19 @@ template void GetDefaultRequestSignatureAndCoreMessageLengths( uint32_t& session_id, const size_t& small_size, size_t* gen_signature_length, size_t* core_message_length); +// Loads the key matching the given |key_id| into the |session| in OEMCrypto for +// the given |cipher_mode| and returns a handle to that key. This function +// handles negotiating the size of the |key_handle| buffer. For non-bypassing +// systems, this is equivalent to the old SelectKey call and will deselect any +// previous keys selected in the session. For bypassing systems, multiple key +// handles may be valid simultaneously, but this call may invalidate any +// previous handles. +OEMCryptoResult GetKeyHandleIntoVector(OEMCrypto_SESSION session, + const uint8_t* key_id, + size_t key_id_length, + OEMCryptoCipherMode cipher_mode, + vector& key_handle); + } // namespace wvoec #endif // CDM_OEC_SESSION_UTIL_H_ diff --git a/oemcrypto/test/oemcrypto_basic_test.cpp b/oemcrypto/test/oemcrypto_basic_test.cpp new file mode 100644 index 00000000..9747ea54 --- /dev/null +++ b/oemcrypto/test/oemcrypto_basic_test.cpp @@ -0,0 +1,654 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_basic_test.h" + +#include "clock.h" +#include "jsmn.h" +#include "log.h" +#include "oemcrypto_corpus_generator_helper.h" +#include "oemcrypto_resource_test.h" +#include "test_sleep.h" + +namespace wvoec { +void OEMCryptoClientTest::SetUp() { + ::testing::Test::SetUp(); + wvutil::TestSleep::SyncFakeClock(); + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name()); + OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + const OEMCryptoResult api_status = OEMCrypto_SetMaxAPIVersion(kCurrentAPI); + OEMCrypto_EnterTestMode(); + if (api_status != OEMCrypto_SUCCESS && + api_status != OEMCrypto_ERROR_NOT_IMPLEMENTED) { + // Log error, but continue assuming no error. + LOGE("OEMCrypto_SetMaxAPIVersion returned %d", api_status); + } +} + +void OEMCryptoClientTest::TearDown() { + OEMCrypto_Terminate(); + ::testing::Test::TearDown(); +} + +const uint8_t* OEMCryptoClientTest::find(const vector& message, + const vector& substring) { + vector::const_iterator pos = search( + message.begin(), message.end(), substring.begin(), substring.end()); + if (pos == message.end()) { + return nullptr; + } + return &(*pos); +} + +OEMCryptoResult OEMCryptoClientTest::CopyBuffer( + OEMCrypto_SESSION session, OEMCrypto_SharedMemory* input_buffer, + size_t input_buffer_size, + const OEMCrypto_DestBufferDesc* dest_buffer_descriptor, + uint8_t subsample_flags) { + if (ShouldGenerateCorpus() && input_buffer != nullptr && + dest_buffer_descriptor != nullptr) { + const std::string file_name = + GetFileName("oemcrypto_copy_buffer_fuzz_seed_corpus"); + + OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure; + fuzzed_structure.dest_buffer_desc.type = dest_buffer_descriptor->type; + switch (fuzzed_structure.dest_buffer_desc.type) { + case OEMCrypto_BufferType_Clear: + fuzzed_structure.dest_buffer_desc.buffer_config = + dest_buffer_descriptor->buffer.clear.clear_buffer_length; + break; + + case OEMCrypto_BufferType_Secure: + fuzzed_structure.dest_buffer_desc.buffer_config = + dest_buffer_descriptor->buffer.secure.secure_buffer_length; + break; + + case OEMCrypto_BufferType_Direct: + fuzzed_structure.dest_buffer_desc.buffer_config = + dest_buffer_descriptor->buffer.direct.is_video; + break; + } + fuzzed_structure.subsample_flags = subsample_flags; + + // Corpus for copy buffer fuzzer should be in the format: + // (dest_buffer_descriptor | subsample_flags | input_buffer). + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, reinterpret_cast(&input_buffer), + input_buffer_size); + } + return OEMCrypto_CopyBuffer(session, input_buffer, input_buffer_size, + dest_buffer_descriptor, subsample_flags); +} + +const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) { + switch (value) { + case HDCP_NONE: + return "No HDCP supported, no secure data path"; + case HDCP_V1: + return "HDCP version 1.x"; + case HDCP_V1_0: + return "HDCP version 1.0"; + case HDCP_V1_1: + return "HDCP version 1.1"; + case HDCP_V1_2: + return "HDCP version 1.2"; + case HDCP_V1_3: + return "HDCP version 1.3"; + case HDCP_V1_4: + return "HDCP version 1.4"; + case HDCP_V2: + return "HDCP version 2.0"; + case HDCP_V2_1: + return "HDCP version 2.1"; + case HDCP_V2_2: + return "HDCP version 2.2"; + case HDCP_V2_3: + return "HDCP version 2.3"; + case HDCP_NO_DIGITAL_OUTPUT: + return "No HDCP device attached/using local display with secure path"; + default: + return ""; + } +} + +// Return a printable string from data. If all the characters are printable, +// then just use the string. Otherwise, convert to hex. +std::string MaybeHex(const uint8_t* data, size_t length) { + for (size_t i = 0; i < length; i++) { + if (!isprint(data[i])) return "0x" + wvutil::HexEncode(data, length); + } + return std::string(reinterpret_cast(data), length); +} +std::string MaybeHex(const std::vector& data) { + return MaybeHex(data.data(), data.size()); +} + +/// @addtogroup basic +/// @{ + +TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { + Session s; + s.open(); + OEMCrypto_DestBufferDesc output_descriptor; + int secure_fd = kHugeRandomNumber; + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_FreeSecureBuffer(s.session_id(), &output_descriptor, + secure_fd)); + s.close(); +} + +/** + * Verifies initialization and logs version information. + * This test is first, because it might give an idea why other + * tests are failing when the device has the wrong keybox installed. + * + * The log message should be updated by Widevine with every release so that it + * is easier to verify which version of the tests a partner is running. Widevine + * should change the API version number when the API changes, but the unit tests + * might be updated more frequently, and are only tracked by the date of the + * last change. + */ +TEST_F(OEMCryptoClientTest, VersionNumber) { + const std::string log_message = + "OEMCrypto unit tests for API 18.2. Tests last updated 2023-04-12"; + cout << " " << log_message << "\n"; + cout << " " + << "These tests are part of Android U." + << "\n"; + LOGI("%s", log_message.c_str()); + // If any of the following fail, then it is time to update the log message + // above. + EXPECT_EQ(ODK_MAJOR_VERSION, 18); + EXPECT_EQ(ODK_MINOR_VERSION, 2); + EXPECT_EQ(kCurrentAPI, static_cast(ODK_MAJOR_VERSION)); + OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); + EXPECT_GT(level, OEMCrypto_Level_Unknown); + EXPECT_LE(level, OEMCrypto_Level3); + cout << " OEMCrypto Security Level is L" << level << endl; + uint32_t version = OEMCrypto_APIVersion(); + uint32_t minor_version = OEMCrypto_MinorAPIVersion(); + cout << " OEMCrypto API version is " << version << "." + << minor_version << endl; + if (OEMCrypto_SupportsUsageTable()) { + cout << " OEMCrypto supports usage tables" << endl; + } else { + cout << " OEMCrypto does not support usage tables" << endl; + } + if (version >= 15) { + const uint32_t tier = OEMCrypto_ResourceRatingTier(); + cout << " Resource Rating Tier: " << tier << endl; + } + if (version >= 17) { + OEMCryptoResult sts = OEMCrypto_ProductionReady(); + if (sts != OEMCrypto_SUCCESS) { + LOGW("Device is not production ready, returns %d", sts); + } + std::string build_info; + size_t buf_length = 0; + sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + build_info.resize(buf_length); + sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); + } + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + if (build_info.size() != buf_length) { + build_info.resize(buf_length); + } + cout << " BuildInformation: " << build_info << endl; + OEMCrypto_WatermarkingSupport support = OEMCrypto_GetWatermarkingSupport(); + cout << " WatermarkingSupport: " << support << endl; + } + ASSERT_GE(version, 8u); + ASSERT_LE(version, kCurrentAPI); +} + +/** + * The resource rating is a number from 1 to 4. The first three levels + * were initially defined in API 15 and they were expanded in API 16. + */ +TEST_F(OEMCryptoClientTest, ResourceRatingAPI15) { + ASSERT_GE(OEMCrypto_ResourceRatingTier(), 1u); + ASSERT_LE(OEMCrypto_ResourceRatingTier(), 4u); +} + +/** + * OEMCrypto must declare what type of provisioning scheme it uses. + */ +TEST_F(OEMCryptoClientTest, ProvisioningDeclaredAPI12) { + OEMCrypto_ProvisioningMethod provisioning_method = + OEMCrypto_GetProvisioningMethod(); + cout << " Provisioning method = " + << ProvisioningMethodName(provisioning_method) << endl; + ASSERT_NE(OEMCrypto_ProvisioningError, provisioning_method); +} + +TEST_F(OEMCryptoClientTest, CheckHDCPCapabilityAPI09) { + OEMCryptoResult sts; + OEMCrypto_HDCP_Capability current, maximum; + sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + printf(" Current HDCP Capability: 0x%02x = %s.\n", + static_cast(current), HDCPCapabilityAsString(current)); + printf(" Maximum HDCP Capability: 0x%02x = %s.\n", + static_cast(maximum), HDCPCapabilityAsString(maximum)); +} + +TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) { + // This just tests some trivial functionality of the SRM update functions. + uint16_t version = 0; + OEMCryptoResult current_result = OEMCrypto_GetCurrentSRMVersion(&version); + if (current_result == OEMCrypto_SUCCESS) { + printf(" Current SRM Version: %d.\n", version); + EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_GetCurrentSRMVersion(nullptr)); + } else if (current_result == OEMCrypto_LOCAL_DISPLAY_ONLY) { + printf(" Current SRM Status: Local Display Only.\n"); + } else { + EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result); + } +} + +TEST_F(OEMCryptoClientTest, CheckNullBuildInformationAPI17) { + OEMCryptoResult sts; + std::string build_info; + sts = OEMCrypto_BuildInformation(&build_info[0], nullptr); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); + size_t buf_length = 0; + sts = OEMCrypto_BuildInformation(nullptr, &buf_length); + // Previous versions of the test expected the wrong error code. + // Although OEMCrypto_ERROR_INVALID_CONTEXT is still accepted by + // the tests, vendors should return OEMCrypto_ERROR_SHORT_BUFFER if + // |buffer| is null and |buf_length| is zero, assigning + // the correct length to |buf_length|. + // TODO(231514699): Remove case for ERROR_INVALID_CONTEXT. + ASSERT_TRUE(OEMCrypto_ERROR_SHORT_BUFFER == sts || + OEMCrypto_ERROR_INVALID_CONTEXT == sts); + if (sts == OEMCrypto_ERROR_INVALID_CONTEXT) { + printf( + "Warning: OEMCrypto_BuildInformation should return " + "ERROR_SHORT_BUFFER.\n"); + } + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + constexpr size_t kZero = 0; + ASSERT_GT(buf_length, kZero); + } +} + +TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { + std::string build_info; + OEMCryptoResult sts = OEMCrypto_BuildInformation(&build_info[0], nullptr); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); + size_t buf_length = 0; + // OEMCrypto must allow |buffer| to be null so long as |buffer_length| + // is provided and initially set to zero. + sts = OEMCrypto_BuildInformation(nullptr, &buf_length); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + build_info.resize(buf_length); + const size_t max_final_size = buf_length; + sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + ASSERT_LE(buf_length, max_final_size); + build_info.resize(buf_length); + + jsmn_parser p; + jsmn_init(&p); + std::vector tokens; + int32_t num_tokens = + jsmn_parse(&p, build_info.c_str(), build_info.size(), nullptr, 0); + EXPECT_GT(num_tokens, 0) + << "Failed to parse BuildInformation as JSON, parse returned " + << num_tokens << "for following build info: " << build_info; + + tokens.resize(num_tokens); + jsmn_init(&p); + int32_t jsmn_result = jsmn_parse(&p, build_info.c_str(), build_info.size(), + tokens.data(), num_tokens); + EXPECT_GE(jsmn_result, 0) + << "Failed to parse BuildInformation as JSON, parse returned " + << jsmn_result << "for following build info: " << build_info; + + std::map expected; + expected["soc_vendor"] = JSMN_STRING; + expected["soc_model"] = JSMN_STRING; + expected["ta_ver"] = JSMN_STRING; + expected["uses_opk"] = JSMN_PRIMITIVE; + expected["tee_os"] = JSMN_STRING; + expected["tee_os_ver"] = JSMN_STRING; + + // for values in token + // build string from start,end + // check for existence in map + // check if value matches expectation + // remove from map + for (int i = 0; i < jsmn_result; i++) { + jsmntok_t token = tokens[i]; + std::string key = build_info.substr(token.start, token.end - token.start); + if (expected.find(key) != expected.end()) { + EXPECT_EQ(expected.find(key)->second, tokens[i + 1].type) + << "Type is incorrect for key " << key; + expected.erase(key); + } + } + + // if map is not empty, return false + if (expected.size() > 0) { + std::string missing; + for (auto e : expected) { + missing.append(e.first); + missing.append(" "); + } + FAIL() << "JSON does not contain all required keys. Missing keys: [" + << missing << "] in string " << build_info; + } +} + +TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) { + size_t sessions_count; + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); + ASSERT_EQ(0u, sessions_count); + size_t maximum; + OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + printf(" Max Number of Sessions: %zu.\n", maximum); + size_t required_max = GetResourceValue(kMaxConcurrentSession); + ASSERT_GE(maximum, required_max); +} + +TEST_F(OEMCryptoClientTest, CheckUsageTableSizeAPI16) { + const size_t maximum = OEMCrypto_MaximumUsageTableHeaderSize(); + printf(" Max Usage Table Size: %zu.\n", maximum); + // A maximum of 0 means the table is constrained by dynamic memory allocation. + if (maximum > 0) { + ASSERT_GE(maximum, RequiredUsageSize()); + } +} + +// +// initialization tests +// +TEST_F(OEMCryptoClientTest, NormalInitTermination) { + // Should be able to terminate OEMCrypto, and then restart it. + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate()); + OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + (void)OEMCrypto_SetMaxAPIVersion(kCurrentAPI); + (void)OEMCrypto_EnterTestMode(); +} + +TEST_F(OEMCryptoClientTest, CheckDTCP2CapabilityAPI17) { + OEMCryptoResult sts; + OEMCrypto_DTCP2_Capability capability; + sts = OEMCrypto_GetDTCP2Capability(&capability); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + switch (capability) { + case OEMCrypto_NO_DTCP2: + printf(" Current DTCP Support: DTCP2 not supported.\n"); + break; + case OEMCrypto_DTCP2_V1: + printf( + " Current DTCP Support: Version 1 (or higher) of " + "DTCP2 is supported.\n"); + break; + } +} + +// +// Session Tests +// +TEST_F(OEMCryptoClientTest, NormalSessionOpenClose) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.close()); +} + +TEST_F(OEMCryptoClientTest, TwoSessionsOpenClose) { + Session s1; + Session s2; + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(s1.close()); + ASSERT_NO_FATAL_FAILURE(s2.close()); +} + +// This test verifies that OEMCrypto can open approximately as many sessions as +// it claims. +TEST_F(OEMCryptoClientTest, MaxSessionsOpenCloseAPI10) { + size_t sessions_count; + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); + ASSERT_EQ(0u, sessions_count); + size_t max_sessions; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetMaxNumberOfSessions(&max_sessions)); + // We expect OEMCrypto implementations support at least this many sessions. + size_t required_number = GetResourceValue(kMaxConcurrentSession); + ASSERT_GE(max_sessions, required_number); + // We allow GetMaxNumberOfSessions to return an estimate. This tests with a + // pad of 5%. Even if it's just an estimate, we still require 8 sessions. + size_t max_sessions_with_pad = max(max_sessions * 19 / 20, required_number); + vector sessions; + // Limit the number of sessions for testing. + const size_t kMaxNumberOfSessionsForTesting = 0x100u; + for (size_t i = 0; i < kMaxNumberOfSessionsForTesting; i++) { + OEMCrypto_SESSION session_id; + OEMCryptoResult sts = OEMCrypto_OpenSession(&session_id); + // GetMaxNumberOfSessions might be an estimate. We allow OEMCrypto to report + // a max that is less than what is actually supported. Assume the number + // returned is |max|. OpenSessions shall not fail if number of active + // sessions is less than |max|; OpenSessions should fail with + // OEMCrypto_ERROR_TOO_MANY_SESSIONS if too many sessions are open. + if (sts != OEMCrypto_SUCCESS) { + ASSERT_EQ(OEMCrypto_ERROR_TOO_MANY_SESSIONS, sts); + ASSERT_GE(i, max_sessions_with_pad); + break; + } + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); + ASSERT_EQ(i + 1, sessions_count); + sessions.push_back(session_id); + } + for (size_t i = 0; i < sessions.size(); i++) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CloseSession(sessions[i])); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); + ASSERT_EQ(sessions.size() - i - 1, sessions_count); + } + if (sessions.size() == kMaxNumberOfSessionsForTesting) { + printf( + " MaxSessionsOpenClose: reaches " + "kMaxNumberOfSessionsForTesting(%zu). GetMaxNumberOfSessions = %zu. " + "ERROR_TOO_MANY_SESSIONS not tested.", + kMaxNumberOfSessionsForTesting, max_sessions); + } +} + +TEST_F(OEMCryptoClientTest, GenerateNonce) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + s.GenerateNonce(); +} + +// Prevent a nonce flood even if each nonce is in a different session. +TEST_F(OEMCryptoClientTest, PreventNonceFlood2API16) { + int error_counter = 0; + const int64_t test_start = wvutil::Clock().GetCurrentTime(); + // More than 200 nonces per second should generate an error. + // To allow for some slop, we actually test for more. + const int flood_cutoff = 200; + const int loop_count = flood_cutoff * 2; + for (int i = 0; i < loop_count; i++) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + s.GenerateNonce(&error_counter); + } + const int64_t test_end = wvutil::Clock().GetCurrentTime(); + int valid_counter = loop_count - error_counter; + // Either oemcrypto should enforce a delay, or it should return an error from + // GenerateNonce -- in either case the number of valid nonces is rate + // limited. We add two seconds to allow for round off error in both + // test_start and test_end. + EXPECT_LE(valid_counter, flood_cutoff * (test_end - test_start + 2)); + error_counter = 0; + // After a pause, we should be able to regenerate nonces. + wvutil::TestSleep::Sleep(2); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + s.GenerateNonce(&error_counter); + EXPECT_EQ(0, error_counter); +} + +// Prevent a nonce flood even if some nonces are in a different session. This +// is different from the test above because there are several session open at +// the same time. We want to make sure you can't get a flood of nonces by +// opening a flood of sessions. +TEST_F(OEMCryptoClientTest, PreventNonceFlood3API16) { + int request_counter = 0; + int error_counter = 0; + const int64_t test_start = wvutil::Clock().GetCurrentTime(); + // More than 200 nonces per second should generate an error. + // To allow for some slop, we actually test for more. + const int flood_cutoff = 200; + const size_t session_count = GetResourceValue(kMaxConcurrentSession); + const size_t loop_count = 2 * flood_cutoff / session_count + 1; + for (size_t i = 0; i < loop_count; i++) { + std::vector s(session_count); + for (size_t j = 0; j < session_count; j++) { + ASSERT_NO_FATAL_FAILURE(s[j].open()); + request_counter++; + s[j].GenerateNonce(&error_counter); + } + } + const int64_t test_end = wvutil::Clock().GetCurrentTime(); + int valid_counter = request_counter - error_counter; + // Either oemcrypto should enforce a delay, or it should return an error from + // GenerateNonce -- in either case the number of valid nonces is rate + // limited. We add two seconds to allow for round off error in both + // test_start and test_end. + EXPECT_LE(valid_counter, flood_cutoff * (test_end - test_start + 2)); + error_counter = 0; + // After a pause, we should be able to regenerate nonces. + wvutil::TestSleep::Sleep(2); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + s.GenerateNonce(&error_counter); + EXPECT_EQ(0, error_counter); +} + +// This verifies that CopyBuffer works, even before a license has been loaded. +TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + const int kDataSize = 256; + vector input_buffer(kDataSize); + GetRandBytes(input_buffer.data(), input_buffer.size()); + vector output_buffer(kDataSize); + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; + dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); + dest_buffer_descriptor.buffer.clear.clear_buffer_length = + output_buffer.size(); + ASSERT_EQ(OEMCrypto_SUCCESS, + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + ASSERT_EQ(input_buffer, output_buffer); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, + CopyBuffer(s.session_id(), nullptr, input_buffer.size(), + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + ASSERT_EQ( + OEMCrypto_ERROR_INVALID_CONTEXT, + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + nullptr, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + dest_buffer_descriptor.buffer.clear.clear_buffer = nullptr; + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); + dest_buffer_descriptor.buffer.clear.clear_buffer_length = + output_buffer.size() - 1; + ASSERT_NE(OEMCrypto_SUCCESS, + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); +} + +// This verifies that CopyBuffer works on the maximum required buffer size. +TEST_F(OEMCryptoClientTest, ClearCopyTestLargeSubsample) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + size_t max_size = GetResourceValue(kMaxSubsampleSize); + vector input_buffer(max_size); + GetRandBytes(input_buffer.data(), input_buffer.size()); + vector output_buffer(max_size); + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; + dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); + dest_buffer_descriptor.buffer.clear.clear_buffer_length = + output_buffer.size(); + ASSERT_EQ(OEMCrypto_SUCCESS, + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + ASSERT_EQ(input_buffer, output_buffer); +} + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryCopyBufferForOutOfRangeHandleLength) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector input_buffer; + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; + + size_t buffer_length = KiB; + input_buffer.resize(buffer_length); + int secure_fd; + if (OEMCrypto_AllocateSecureBuffer(s.session_id(), buffer_length, + &dest_buffer_descriptor, + &secure_fd) != OEMCrypto_SUCCESS) { + LOGI("Secure buffers are not supported."); + return; + } + + dest_buffer_descriptor.buffer.secure.secure_buffer_length = + kHugeInputBufferLength; + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), buffer_length, + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, + secure_fd); +} + +TEST_F(OEMCryptoClientTest, ClearCopyTestInvalidSubsampleFlag) { + uint8_t oemcrypto_invalid_subsample_flag = 85; + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + size_t max_size = GetResourceValue(kMaxSubsampleSize); + vector input_buffer(max_size); + GetRandBytes(input_buffer.data(), input_buffer.size()); + vector output_buffer(max_size); + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; + dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); + dest_buffer_descriptor.buffer.clear.clear_buffer_length = + output_buffer.size(); + ASSERT_NO_FATAL_FAILURE( + CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), + &dest_buffer_descriptor, oemcrypto_invalid_subsample_flag)); +} + +TEST_F(OEMCryptoClientTest, CanLoadTestKeys) { + ASSERT_NE(DeviceFeatures::NO_METHOD, global_features.derive_key_method) + << "Session tests cannot run with out a test keybox or RSA cert."; +} + +/// @} +} // namespace wvoec diff --git a/oemcrypto/test/oemcrypto_basic_test.h b/oemcrypto/test/oemcrypto_basic_test.h new file mode 100644 index 00000000..2cbe235b --- /dev/null +++ b/oemcrypto/test/oemcrypto_basic_test.h @@ -0,0 +1,41 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_BASIC_TEST_ +#define CDM_OEMCRYPTO_BASIC_TEST_ + +#include + +#include + +#include "OEMCryptoCENC.h" +#include "oemcrypto_session_tests_helper.h" + +namespace wvoec { + +const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value); + +std::string MaybeHex(const uint8_t* data, size_t length); +std::string MaybeHex(const std::vector& data); + +/** Tests for just basic client functionality. */ +class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { + protected: + OEMCryptoClientTest() {} + + void SetUp() override; + void TearDown() override; + const uint8_t* find(const std::vector& message, + const std::vector& substring); + OEMCryptoResult CopyBuffer( + OEMCrypto_SESSION session, OEMCrypto_SharedMemory* input_buffer, + size_t input_buffer_size, + const OEMCrypto_DestBufferDesc* dest_buffer_descriptor, + uint8_t subsample_flags); +}; +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_BASIC_TEST_ diff --git a/oemcrypto/test/oemcrypto_cast_test.cpp b/oemcrypto/test/oemcrypto_cast_test.cpp new file mode 100644 index 00000000..6dc25527 --- /dev/null +++ b/oemcrypto/test/oemcrypto_cast_test.cpp @@ -0,0 +1,977 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_cast_test.h" + +#include "oemcrypto_usage_table_test.h" + +using ::testing::Range; + +namespace wvoec { + +// The alternate padding is only required for cast receivers, but all devices +// should forbid the alternate padding for regular certificates. +TEST_F(OEMCryptoLoadsCertificateAlternates, DisallowForbiddenPaddingAPI09) { + LoadWithAllowedSchemes(kSign_RSASSA_PSS, + true); // Use default padding scheme + DisallowForbiddenPadding(kSign_PKCS1_Block1, 50); +} + +// The alternate padding is only required for cast receivers, but if a device +// does load an alternate certificate, it should NOT use it for generating +// a license request signature. +TEST_F(OEMCryptoLoadsCertificateAlternates, TestSignaturePKCS1) { + // Try to load an RSA key with alternative padding schemes. This signing + // scheme is used by cast receivers. + LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); + // If the device is a cast receiver, then this scheme is required. + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } + // If the key loaded with no error, then we will verify that it is not used + // for forbidden padding schemes. + if (key_loaded_) { + // The other padding scheme should fail. + DisallowForbiddenPadding(kSign_RSASSA_PSS, 83); + DisallowDeriveKeys(); + if (global_features.cast_receiver) { + // A signature with a valid size should succeed. + TestSignature(kSign_PKCS1_Block1, 83); + TestSignature(kSign_PKCS1_Block1, 50); + } + // A signature with padding that is too big should fail. + DisallowForbiddenPadding(kSign_PKCS1_Block1, 84); // too big. + } +} + +// This test verifies RSA signing with the alternate padding scheme used by +// Android cast receivers, PKCS1 Block 1. These tests are not required for +// other devices, and should be filtered out by DeviceFeatures::Initialize for +// those devices. +class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { + protected: + void SetUp() override { + OEMCryptoLoadsCertificateAlternates::SetUp(); + if (!global_features.cast_receiver) { + GTEST_SKIP() << "OEMCrypto does not support CAST Receiver functionality"; + } + } + + vector encode(uint8_t type, const vector& substring) { + vector result; + result.push_back(type); + if (substring.size() < 0x80) { + uint8_t length = substring.size(); + result.push_back(length); + } else if (substring.size() < 0x100) { + result.push_back(0x81); + uint8_t length = substring.size(); + result.push_back(length); + } else { + result.push_back(0x82); + uint16_t length = substring.size(); + result.push_back(length >> 8); + result.push_back(length & 0xFF); + } + result.insert(result.end(), substring.begin(), substring.end()); + return result; + } + vector concat(const vector& a, const vector& b) { + vector result = a; + result.insert(result.end(), b.begin(), b.end()); + return result; + } + + // This encodes the RSA key used in the PKCS#1 signing tests below. + void BuildRSAKey() { + vector field_n = + encode(0x02, wvutil::a2b_hex("00" + "df271fd25f8644496b0c81be4bd50297" + "ef099b002a6fd67727eb449cea566ed6" + "a3981a71312a141cabc9815c1209e320" + "a25b32464e9999f18ca13a9fd3892558" + "f9e0adefdd3650dd23a3f036d60fe398" + "843706a40b0b8462c8bee3bce12f1f28" + "60c2444cdc6a44476a75ff4aa24273cc" + "be3bf80248465f8ff8c3a7f3367dfc0d" + "f5b6509a4f82811cedd81cdaaa73c491" + "da412170d544d4ba96b97f0afc806549" + "8d3a49fd910992a1f0725be24f465cfe" + "7e0eabf678996c50bc5e7524abf73f15" + "e5bef7d518394e3138ce4944506aaaaf" + "3f9b236dcab8fc00f87af596fdc3d9d6" + "c75cd508362fae2cbeddcc4c7450b17b" + "776c079ecca1f256351a43b97dbe2153")); + vector field_e = encode(0x02, wvutil::a2b_hex("010001")); + vector field_d = + encode(0x02, wvutil::a2b_hex("5bd910257830dce17520b03441a51a8c" + "ab94020ac6ecc252c808f3743c95b7c8" + "3b8c8af1a5014346ebc4242cdfb5d718" + "e30a733e71f291e4d473b61bfba6daca" + "ed0a77bd1f0950ae3c91a8f901118825" + "89e1d62765ee671e7baeea309f64d447" + "bbcfa9ea12dce05e9ea8939bc5fe6108" + "581279c982b308794b3448e7f7b95229" + "2df88c80cb40142c4b5cf5f8ddaa0891" + "678d610e582fcb880f0d707caf47d09a" + "84e14ca65841e5a3abc5e9dba94075a9" + "084341f0edad9b68e3b8e082b80b6e6e" + "8a0547b44fb5061b6a9131603a5537dd" + "abd01d8e863d8922e9aa3e4bfaea0b39" + "d79283ad2cbc8a59cce7a6ecf4e4c81e" + "d4c6591c807defd71ab06866bb5e7745")); + vector field_p = + encode(0x02, wvutil::a2b_hex("00" + "f44f5e4246391f482b2f5296e3602eb3" + "4aa136427710f7c0416d403fd69d4b29" + "130cfebef34e885abdb1a8a0a5f0e9b5" + "c33e1fc3bfc285b1ae17e40cc67a1913" + "dd563719815ebaf8514c2a7aa0018e63" + "b6c631dc315a46235716423d11ff5803" + "4e610645703606919f5c7ce2660cd148" + "bd9efc123d9c54b6705590d006cfcf3f")); + vector field_q = + encode(0x02, wvutil::a2b_hex("00" + "e9d49841e0e0a6ad0d517857133e36dc" + "72c1bdd90f9174b52e26570f373640f1" + "c185e7ea8e2ed7f1e4ebb951f70a5802" + "3633b0097aec67c6dcb800fc1a67f9bb" + "0563610f08ebc8746ad129772136eb1d" + "daf46436450d318332a84982fe5d28db" + "e5b3e912407c3e0e03100d87d436ee40" + "9eec1cf85e80aba079b2e6106b97bced")); + vector field_exp1 = + encode(0x02, wvutil::a2b_hex("00" + "ed102acdb26871534d1c414ecad9a4d7" + "32fe95b10eea370da62f05de2c393b1a" + "633303ea741b6b3269c97f704b352702" + "c9ae79922f7be8d10db67f026a8145de" + "41b30c0a42bf923bac5f7504c248604b" + "9faa57ed6b3246c6ba158e36c644f8b9" + "548fcf4f07e054a56f768674054440bc" + "0dcbbc9b528f64a01706e05b0b91106f")); + vector field_exp2 = + encode(0x02, wvutil::a2b_hex("6827924a85e88b55ba00f8219128bd37" + "24c6b7d1dfe5629ef197925fecaff5ed" + "b9cdf3a7befd8ea2e8dd3707138b3ff8" + "7c3c39c57f439e562e2aa805a39d7cd7" + "9966d2ece7845f1dbc16bee99999e4d0" + "bf9eeca45fcda8a8500035fe6b5f03bc" + "2f6d1bfc4d4d0a3723961af0cdce4a01" + "eec82d7f5458ec19e71b90eeef7dff61")); + vector field_invq = + encode(0x02, wvutil::a2b_hex("57b73888d183a99a6307422277551a3d" + "9e18adf06a91e8b55ceffef9077c8496" + "948ecb3b16b78155cb2a3a57c119d379" + "951c010aa635edcf62d84c5a122a8d67" + "ab5fa9e5a4a8772a1e943bafc70ae3a4" + "c1f0f3a4ddffaefd1892c8cb33bb0d0b" + "9590e963a69110fb34db7b906fc4ba28" + "36995aac7e527490ac952a02268a4f18")); + + // Header of rsa key is constant. + encoded_rsa_key_ = wvutil::a2b_hex( + // 0x02 0x01 0x00 == integer, size 1 byte, value = 0 + // (field=version) + "020100" + // 0x30, sequence, size = d = 13 (field=pkeyalg) + // AlgorithmIdentifier + "300d" + // 0x06 = object identifier. length = 9 + // (this should be 1.2.840.113549.1.1.1) (field=algorithm) + "0609" + "2a" // 1*0x40 + 2 = 42 = 0x2a. + "8648" // 840 = 0x348, 0x03 *2 + 0x80 + (0x48>>15) = 0x86. + // 0x48 -> 0x48 + "86f70d" // 113549 = 0x1668d -> (110 , 1110111, 0001101) + // -> (0x80+0x06, 0x80+0x77, 0x0d) + "01" // 1 + "01" // 1 + "01" // 1 + "05" // null object. (field=parameter?) + "00" // size of null object + ); + + vector pkey = wvutil::a2b_hex("020100"); // integer, version = 0. + pkey = concat(pkey, field_n); + pkey = concat(pkey, field_e); + pkey = concat(pkey, field_d); + pkey = concat(pkey, field_p); + pkey = concat(pkey, field_q); + pkey = concat(pkey, field_exp1); + pkey = concat(pkey, field_exp2); + pkey = concat(pkey, field_invq); + pkey = encode(0x30, pkey); + pkey = encode(0x04, pkey); + + encoded_rsa_key_ = concat(encoded_rsa_key_, pkey); + encoded_rsa_key_ = encode(0x30, encoded_rsa_key_); // 0x30=sequence + } + + // This is used to test a signature from the file pkcs1v15sign-vectors.txt. + void TestSignature(RSA_Padding_Scheme scheme, const vector& message, + const vector& correct_signature) { + OEMCryptoResult sts; + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + + // The application will compute the SHA-1 Hash of the message, so this + // test must do that also. + uint8_t hash[SHA_DIGEST_LENGTH]; + if (!SHA1(message.data(), message.size(), hash)) { + dump_boringssl_error(); + FAIL() << "boringssl error creating SHA1 hash."; + } + + // The application will prepend the digest info to the hash. + // SHA-1 digest info prefix = 0x30 0x21 0x30 ... + vector digest = wvutil::a2b_hex("3021300906052b0e03021a05000414"); + digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH); + + // OEMCrypto will apply the padding, and encrypt to generate the + // signature. + size_t signature_length = 0; + sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), + digest.size(), nullptr, + &signature_length, scheme); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + ASSERT_NE(static_cast(0), signature_length); + + vector signature(signature_length); + sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), + digest.size(), signature.data(), + &signature_length, scheme); + + ASSERT_EQ(OEMCrypto_SUCCESS, sts) + << "Failed to sign with padding scheme=" << (int)scheme + << ", size=" << message.size(); + signature.resize(signature_length); + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + + // Verify that the signature matches the official test vector. + ASSERT_EQ(correct_signature.size(), signature_length); + signature.resize(signature_length); + ASSERT_EQ(correct_signature, signature); + + // Also verify that our verification algorithm agrees. This is not + // needed to test OEMCrypto, but it does verify that this test is valid. + ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(digest, signature.data(), + signature_length, scheme)); + ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature( + digest, correct_signature.data(), correct_signature.size(), scheme)); + } +}; + +// CAST Receivers should report that they support cast certificates. +TEST_F(OEMCryptoCastReceiverTest, SupportsCertificatesAPI13) { + ASSERT_NE(0u, + OEMCrypto_Supports_RSA_CAST & OEMCrypto_SupportedCertificates()); +} + +// # PKCS#1 v1.5 Signature Example 15.1 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_1) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "f45d55f35551e975d6a8dc7ea9f48859" + "3940cc75694a278f27e578a163d839b3" + "4040841808cf9c58c9b8728bf5f9ce8e" + "e811ea91714f47bab92d0f6d5a26fcfe" + "ea6cd93b910c0a2c963e64eb1823f102" + "753d41f0335910ad3a977104f1aaf6c3" + "742716a9755d11b8eed690477f445c5d" + "27208b2e284330fa3d301423fa7f2d08" + "6e0ad0b892b9db544e456d3f0dab85d9" + "53c12d340aa873eda727c8a649db7fa6" + "3740e25e9af1533b307e61329993110e" + "95194e039399c3824d24c51f22b26bde" + "1024cd395958a2dfeb4816a6e8adedb5" + "0b1f6b56d0b3060ff0f1c4cb0d0e001d" + "d59d73be12"); + vector signature = wvutil::a2b_hex( + "b75a5466b65d0f300ef53833f2175c8a" + "347a3804fc63451dc902f0b71f908345" + "9ed37a5179a3b723a53f1051642d7737" + "4c4c6c8dbb1ca20525f5c9f32db77695" + "3556da31290e22197482ceb69906c46a" + "758fb0e7409ba801077d2a0a20eae7d1" + "d6d392ab4957e86b76f0652d68b83988" + "a78f26e11172ea609bf849fbbd78ad7e" + "dce21de662a081368c040607cee29db0" + "627227f44963ad171d2293b633a392e3" + "31dca54fe3082752f43f63c161b447a4" + "c65a6875670d5f6600fcc860a1caeb0a" + "88f8fdec4e564398a5c46c87f68ce070" + "01f6213abe0ab5625f87d19025f08d81" + "dac7bd4586bc9382191f6d2880f6227e" + "5df3eed21e7792d249480487f3655261"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} +// # PKCS#1 v1.5 Signature Example 15.2 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_2) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "c14b4c6075b2f9aad661def4ecfd3cb9" + "33c623f4e63bf53410d2f016d1ab98e2" + "729eccf8006cd8e08050737d95fdbf29" + "6b66f5b9792a902936c4f7ac69f51453" + "ce4369452dc22d96f037748114662000" + "dd9cd3a5e179f4e0f81fa6a0311ca1ae" + "e6519a0f63cec78d27bb726393fb7f1f" + "88cde7c97f8a66cd66301281dac3f3a4" + "33248c75d6c2dcd708b6a97b0a3f325e" + "0b2964f8a5819e479b"); + vector signature = wvutil::a2b_hex( + "afa7343462bea122cc149fca70abdae7" + "9446677db5373666af7dc313015f4de7" + "86e6e394946fad3cc0e2b02bedba5047" + "fe9e2d7d099705e4a39f28683279cf0a" + "c85c1530412242c0e918953be000e939" + "cf3bf182525e199370fa7907eba69d5d" + "b4631017c0e36df70379b5db8d4c695a" + "979a8e6173224065d7dc15132ef28cd8" + "22795163063b54c651141be86d36e367" + "35bc61f31fca574e5309f3a3bbdf91ef" + "f12b99e9cc1744f1ee9a1bd22c5bad96" + "ad481929251f0343fd36bcf0acde7f11" + "e5ad60977721202796fe061f9ada1fc4" + "c8e00d6022a8357585ffe9fdd59331a2" + "8c4aa3121588fb6cf68396d8ac054659" + "9500c9708500a5972bd54f72cf8db0c8"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.3 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_3) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "d02371ad7ee48bbfdb2763de7a843b94" + "08ce5eb5abf847ca3d735986df84e906" + "0bdbcdd3a55ba55dde20d4761e1a21d2" + "25c1a186f4ac4b3019d3adf78fe63346" + "67f56f70c901a0a2700c6f0d56add719" + "592dc88f6d2306c7009f6e7a635b4cb3" + "a502dfe68ddc58d03be10a1170004fe7" + "4dd3e46b82591ff75414f0c4a03e605e" + "20524f2416f12eca589f111b75d639c6" + "1baa80cafd05cf3500244a219ed9ced9" + "f0b10297182b653b526f400f2953ba21" + "4d5bcd47884132872ae90d4d6b1f4215" + "39f9f34662a56dc0e7b4b923b6231e30" + "d2676797817f7c337b5ac824ba93143b" + "3381fa3dce0e6aebd38e67735187b1eb" + "d95c02"); + vector signature = wvutil::a2b_hex( + "3bac63f86e3b70271203106b9c79aabd" + "9f477c56e4ee58a4fce5baf2cab4960f" + "88391c9c23698be75c99aedf9e1abf17" + "05be1dac33140adb48eb31f450bb9efe" + "83b7b90db7f1576d33f40c1cba4b8d6b" + "1d3323564b0f1774114fa7c08e6d1e20" + "dd8fbba9b6ac7ad41e26b4568f4a8aac" + "bfd178a8f8d2c9d5f5b88112935a8bc9" + "ae32cda40b8d20375510735096536818" + "ce2b2db71a9772c9b0dda09ae10152fa" + "11466218d091b53d92543061b7294a55" + "be82ff35d5c32fa233f05aaac7585030" + "7ecf81383c111674397b1a1b9d3bf761" + "2ccbe5bacd2b38f0a98397b24c83658f" + "b6c0b4140ef11970c4630d44344e76ea" + "ed74dcbee811dbf6575941f08a6523b8"); + TestSignature(kSign_PKCS1_Block1, message, signature); +}; + +// # PKCS#1 v1.5 Signature Example 15.4 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_4) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "29035584ab7e0226a9ec4b02e8dcf127" + "2dc9a41d73e2820007b0f6e21feccd5b" + "d9dbb9ef88cd6758769ee1f956da7ad1" + "8441de6fab8386dbc693"); + vector signature = wvutil::a2b_hex( + "28d8e3fcd5dddb21ffbd8df1630d7377" + "aa2651e14cad1c0e43ccc52f907f946d" + "66de7254e27a6c190eb022ee89ecf622" + "4b097b71068cd60728a1aed64b80e545" + "7bd3106dd91706c937c9795f2b36367f" + "f153dc2519a8db9bdf2c807430c451de" + "17bbcd0ce782b3e8f1024d90624dea7f" + "1eedc7420b7e7caa6577cef43141a726" + "4206580e44a167df5e41eea0e69a8054" + "54c40eefc13f48e423d7a32d02ed42c0" + "ab03d0a7cf70c5860ac92e03ee005b60" + "ff3503424b98cc894568c7c56a023355" + "1cebe588cf8b0167b7df13adcad82867" + "6810499c704da7ae23414d69e3c0d2db" + "5dcbc2613bc120421f9e3653c5a87672" + "97643c7e0740de016355453d6c95ae72"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.5 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_5) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex("bda3a1c79059eae598308d3df609"); + vector signature = wvutil::a2b_hex( + "a156176cb96777c7fb96105dbd913bc4" + "f74054f6807c6008a1a956ea92c1f81c" + "b897dc4b92ef9f4e40668dc7c556901a" + "cb6cf269fe615b0fb72b30a513386923" + "14b0e5878a88c2c7774bd16939b5abd8" + "2b4429d67bd7ac8e5ea7fe924e20a6ec" + "662291f2548d734f6634868b039aa5f9" + "d4d906b2d0cb8585bf428547afc91c6e" + "2052ddcd001c3ef8c8eefc3b6b2a82b6" + "f9c88c56f2e2c3cb0be4b80da95eba37" + "1d8b5f60f92538743ddbb5da2972c71f" + "e7b9f1b790268a0e770fc5eb4d5dd852" + "47d48ae2ec3f26255a3985520206a1f2" + "68e483e9dbb1d5cab190917606de31e7" + "c5182d8f151bf41dfeccaed7cde690b2" + "1647106b490c729d54a8fe2802a6d126"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.6 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_6) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "c187915e4e87da81c08ed4356a0cceac" + "1c4fb5c046b45281b387ec28f1abfd56" + "7e546b236b37d01ae71d3b2834365d3d" + "f380b75061b736b0130b070be58ae8a4" + "6d12166361b613dbc47dfaeb4ca74645" + "6c2e888385525cca9dd1c3c7a9ada76d" + "6c"); + vector signature = wvutil::a2b_hex( + "9cab74163608669f7555a333cf196fe3" + "a0e9e5eb1a32d34bb5c85ff689aaab0e" + "3e65668ed3b1153f94eb3d8be379b8ee" + "f007c4a02c7071ce30d8bb341e58c620" + "f73d37b4ecbf48be294f6c9e0ecb5e63" + "fec41f120e5553dfa0ebebbb72640a95" + "37badcb451330229d9f710f62e3ed8ec" + "784e50ee1d9262b42671340011d7d098" + "c6f2557b2131fa9bd0254636597e88ec" + "b35a240ef0fd85957124df8080fee1e1" + "49af939989e86b26c85a5881fae8673d" + "9fd40800dd134eb9bdb6410f420b0aa9" + "7b20efcf2eb0c807faeb83a3ccd9b51d" + "4553e41dfc0df6ca80a1e81dc234bb83" + "89dd195a38b42de4edc49d346478b9f1" + "1f0557205f5b0bd7ffe9c850f396d7c4"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.7 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_7) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "abfa2ecb7d29bd5bcb9931ce2bad2f74" + "383e95683cee11022f08e8e7d0b8fa05" + "8bf9eb7eb5f98868b5bb1fb5c31ceda3" + "a64f1a12cdf20fcd0e5a246d7a1773d8" + "dba0e3b277545babe58f2b96e3f4edc1" + "8eabf5cd2a560fca75fe96e07d859def" + "b2564f3a34f16f11e91b3a717b41af53" + "f6605323001aa406c6"); + vector signature = wvutil::a2b_hex( + "c4b437bcf703f352e1faf74eb9622039" + "426b5672caf2a7b381c6c4f0191e7e4a" + "98f0eebcd6f41784c2537ff0f99e7498" + "2c87201bfbc65eae832db71d16dacadb" + "0977e5c504679e40be0f9db06ffd848d" + "d2e5c38a7ec021e7f68c47dfd38cc354" + "493d5339b4595a5bf31e3f8f13816807" + "373df6ad0dc7e731e51ad19eb4754b13" + "4485842fe709d378444d8e36b1724a4f" + "da21cafee653ab80747f7952ee804dea" + "b1039d84139945bbf4be82008753f3c5" + "4c7821a1d241f42179c794ef7042bbf9" + "955656222e45c34369a384697b6ae742" + "e18fa5ca7abad27d9fe71052e3310d0f" + "52c8d12ea33bf053a300f4afc4f098df" + "4e6d886779d64594d369158fdbc1f694"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.8 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_8) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "df4044a89a83e9fcbf1262540ae3038b" + "bc90f2b2628bf2a4467ac67722d8546b" + "3a71cb0ea41669d5b4d61859c1b4e47c" + "ecc5933f757ec86db0644e311812d00f" + "b802f03400639c0e364dae5aebc5791b" + "c655762361bc43c53d3c7886768f7968" + "c1c544c6f79f7be820c7e2bd2f9d73e6" + "2ded6d2e937e6a6daef90ee37a1a52a5" + "4f00e31addd64894cf4c02e16099e29f" + "9eb7f1a7bb7f84c47a2b594813be02a1" + "7b7fc43b34c22c91925264126c89f86b" + "b4d87f3ef131296c53a308e0331dac8b" + "af3b63422266ecef2b90781535dbda41" + "cbd0cf22a8cbfb532ec68fc6afb2ac06"); + vector signature = wvutil::a2b_hex( + "1414b38567ae6d973ede4a06842dcc0e" + "0559b19e65a4889bdbabd0fd02806829" + "13bacd5dc2f01b30bb19eb810b7d9ded" + "32b284f147bbe771c930c6052aa73413" + "90a849f81da9cd11e5eccf246dbae95f" + "a95828e9ae0ca3550325326deef9f495" + "30ba441bed4ac29c029c9a2736b1a419" + "0b85084ad150426b46d7f85bd702f48d" + "ac5f71330bc423a766c65cc1dcab20d3" + "d3bba72b63b3ef8244d42f157cb7e3a8" + "ba5c05272c64cc1ad21a13493c3911f6" + "0b4e9f4ecc9900eb056ee59d6fe4b8ff" + "6e8048ccc0f38f2836fd3dfe91bf4a38" + "6e1ecc2c32839f0ca4d1b27a568fa940" + "dd64ad16bd0125d0348e383085f08894" + "861ca18987227d37b42b584a8357cb04"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.9 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_9) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "ea941ff06f86c226927fcf0e3b11b087" + "2676170c1bfc33bda8e265c77771f9d0" + "850164a5eecbcc5ce827fbfa07c85214" + "796d8127e8caa81894ea61ceb1449e72" + "fea0a4c943b2da6d9b105fe053b9039a" + "9cc53d420b7539fab2239c6b51d17e69" + "4c957d4b0f0984461879a0759c4401be" + "ecd4c606a0afbd7a076f50a2dfc2807f" + "24f1919baa7746d3a64e268ed3f5f8e6" + "da83a2a5c9152f837cb07812bd5ba7d3" + "a07985de88113c1796e9b466ec299c5a" + "c1059e27f09415"); + vector signature = wvutil::a2b_hex( + "ceeb84ccb4e9099265650721eea0e8ec" + "89ca25bd354d4f64564967be9d4b08b3" + "f1c018539c9d371cf8961f2291fbe0dc" + "2f2f95fea47b639f1e12f4bc381cef0c" + "2b7a7b95c3adf27605b7f63998c3cbad" + "542808c3822e064d4ad14093679e6e01" + "418a6d5c059684cd56e34ed65ab605b8" + "de4fcfa640474a54a8251bbb7326a42d" + "08585cfcfc956769b15b6d7fdf7da84f" + "81976eaa41d692380ff10eaecfe0a579" + "682909b5521fade854d797b8a0345b9a" + "864e0588f6caddbf65f177998e180d1f" + "102443e6dca53a94823caa9c3b35f322" + "583c703af67476159ec7ec93d1769b30" + "0af0e7157dc298c6cd2dee2262f8cddc" + "10f11e01741471bbfd6518a175734575"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.10 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_10) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "d8b81645c13cd7ecf5d00ed2c91b9acd" + "46c15568e5303c4a9775ede76b48403d" + "6be56c05b6b1cf77c6e75de096c5cb35" + "51cb6fa964f3c879cf589d28e1da2f9d" + "ec"); + vector signature = wvutil::a2b_hex( + "2745074ca97175d992e2b44791c323c5" + "7167165cdd8da579cdef4686b9bb404b" + "d36a56504eb1fd770f60bfa188a7b24b" + "0c91e881c24e35b04dc4dd4ce38566bc" + "c9ce54f49a175fc9d0b22522d9579047" + "f9ed42eca83f764a10163997947e7d2b" + "52ff08980e7e7c2257937b23f3d279d4" + "cd17d6f495546373d983d536efd7d1b6" + "7181ca2cb50ac616c5c7abfbb9260b91" + "b1a38e47242001ff452f8de10ca6eaea" + "dcaf9edc28956f28a711291fc9a80878" + "b8ba4cfe25b8281cb80bc9cd6d2bd182" + "5246eebe252d9957ef93707352084e6d" + "36d423551bf266a85340fb4a6af37088" + "0aab07153d01f48d086df0bfbec05e7b" + "443b97e71718970e2f4bf62023e95b67"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.11 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_11) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "e5739b6c14c92d510d95b826933337ff" + "0d24ef721ac4ef64c2bad264be8b44ef" + "a1516e08a27eb6b611d3301df0062dae" + "fc73a8c0d92e2c521facbc7b26473876" + "7ea6fc97d588a0baf6ce50adf79e600b" + "d29e345fcb1dba71ac5c0289023fe4a8" + "2b46a5407719197d2e958e3531fd54ae" + "f903aabb4355f88318994ed3c3dd62f4" + "20a7"); + vector signature = wvutil::a2b_hex( + "be40a5fb94f113e1b3eff6b6a33986f2" + "02e363f07483b792e68dfa5554df0466" + "cc32150950783b4d968b639a04fd2fb9" + "7f6eb967021f5adccb9fca95acc8f2cd" + "885a380b0a4e82bc760764dbab88c1e6" + "c0255caa94f232199d6f597cc9145b00" + "e3d4ba346b559a8833ad1516ad5163f0" + "16af6a59831c82ea13c8224d84d0765a" + "9d12384da460a8531b4c407e04f4f350" + "709eb9f08f5b220ffb45abf6b75d1579" + "fd3f1eb55fc75b00af8ba3b087827fe9" + "ae9fb4f6c5fa63031fe582852fe2834f" + "9c89bff53e2552216bc7c1d4a3d5dc2b" + "a6955cd9b17d1363e7fee8ed7629753f" + "f3125edd48521ae3b9b03217f4496d0d" + "8ede57acbc5bd4deae74a56f86671de2"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.12 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_12) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "7af42835917a88d6b3c6716ba2f5b0d5" + "b20bd4e2e6e574e06af1eef7c81131be" + "22bf8128b9cbc6ec00275ba80294a5d1" + "172d0824a79e8fdd830183e4c00b9678" + "2867b1227fea249aad32ffc5fe007bc5" + "1f21792f728deda8b5708aa99cabab20" + "a4aa783ed86f0f27b5d563f42e07158c" + "ea72d097aa6887ec411dd012912a5e03" + "2bbfa678507144bcc95f39b58be7bfd1" + "759adb9a91fa1d6d8226a8343a8b849d" + "ae76f7b98224d59e28f781f13ece605f" + "84f6c90bae5f8cf378816f4020a7dda1" + "bed90c92a23634d203fac3fcd86d68d3" + "182a7d9ccabe7b0795f5c655e9acc4e3" + "ec185140d10cef053464ab175c83bd83" + "935e3dabaf3462eebe63d15f573d269a"); + vector signature = wvutil::a2b_hex( + "4e78c5902b807914d12fa537ae6871c8" + "6db8021e55d1adb8eb0ccf1b8f36ab7d" + "ad1f682e947a627072f03e627371781d" + "33221d174abe460dbd88560c22f69011" + "6e2fbbe6e964363a3e5283bb5d946ef1" + "c0047eba038c756c40be7923055809b0" + "e9f34a03a58815ebdde767931f018f6f" + "1878f2ef4f47dd374051dd48685ded6e" + "fb3ea8021f44be1d7d149398f98ea9c0" + "8d62888ebb56192d17747b6b8e170954" + "31f125a8a8e9962aa31c285264e08fb2" + "1aac336ce6c38aa375e42bc92ab0ab91" + "038431e1f92c39d2af5ded7e43bc151e" + "6ebea4c3e2583af3437e82c43c5e3b5b" + "07cf0359683d2298e35948ed806c063c" + "606ea178150b1efc15856934c7255cfe"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.13 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_13) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "ebaef3f9f23bdfe5fa6b8af4c208c189" + "f2251bf32f5f137b9de4406378686b3f" + "0721f62d24cb8688d6fc41a27cbae21d" + "30e429feacc7111941c277"); + vector signature = wvutil::a2b_hex( + "c48dbef507114f03c95fafbeb4df1bfa" + "88e0184a33cc4f8a9a1035ff7f822a5e" + "38cda18723915ff078244429e0f6081c" + "14fd83331fa65c6ba7bb9a12dbf66223" + "74cd0ca57de3774e2bd7ae823677d061" + "d53ae9c4040d2da7ef7014f3bbdc95a3" + "61a43855c8ce9b97ecabce174d926285" + "142b534a3087f9f4ef74511ec742b0d5" + "685603faf403b5072b985df46adf2d25" + "29a02d40711e2190917052371b79b749" + "b83abf0ae29486c3f2f62477b2bd362b" + "039c013c0c5076ef520dbb405f42cee9" + "5425c373a975e1cdd032c49622c85079" + "b09e88dab2b13969ef7a723973781040" + "459f57d5013638483de2d91cb3c490da" + "81c46de6cd76ea8a0c8f6fe331712d24"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.14 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_14) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "c5a2711278761dfcdd4f0c99e6f5619d" + "6c48b5d4c1a80982faa6b4cf1cf7a60f" + "f327abef93c801429efde08640858146" + "1056acc33f3d04f5ada21216cacd5fd1" + "f9ed83203e0e2fe6138e3eae8424e591" + "5a083f3f7ab76052c8be55ae882d6ec1" + "482b1e45c5dae9f41015405327022ec3" + "2f0ea2429763b255043b1958ee3cf6d6" + "3983596eb385844f8528cc9a9865835d" + "c5113c02b80d0fca68aa25e72bcaaeb3" + "cf9d79d84f984fd417"); + vector signature = wvutil::a2b_hex( + "6bd5257aa06611fb4660087cb4bc4a9e" + "449159d31652bd980844daf3b1c7b353" + "f8e56142f7ea9857433b18573b4deede" + "818a93b0290297783f1a2f23cbc72797" + "a672537f01f62484cd4162c3214b9ac6" + "28224c5de01f32bb9b76b27354f2b151" + "d0e8c4213e4615ad0bc71f515e300d6a" + "64c6743411fffde8e5ff190e54923043" + "126ecfc4c4539022668fb675f25c07e2" + "0099ee315b98d6afec4b1a9a93dc3349" + "6a15bd6fde1663a7d49b9f1e639d3866" + "4b37a010b1f35e658682d9cd63e57de0" + "f15e8bdd096558f07ec0caa218a8c06f" + "4788453940287c9d34b6d40a3f09bf77" + "99fe98ae4eb49f3ff41c5040a50cefc9" + "bdf2394b749cf164480df1ab6880273b"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.15 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_15) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "9bf8aa253b872ea77a7e23476be26b23" + "29578cf6ac9ea2805b357f6fc3ad130d" + "baeb3d869a13cce7a808bbbbc969857e" + "03945c7bb61df1b5c2589b8e046c2a5d" + "7e4057b1a74f24c711216364288529ec" + "9570f25197213be1f5c2e596f8bf8b2c" + "f3cb38aa56ffe5e31df7395820e94ecf" + "3b1189a965dcf9a9cb4298d3c88b2923" + "c19fc6bc34aacecad4e0931a7c4e5d73" + "dc86dfa798a8476d82463eefaa90a8a9" + "192ab08b23088dd58e1280f7d72e4548" + "396baac112252dd5c5346adb2004a2f7" + "101ccc899cc7fafae8bbe295738896a5" + "b2012285014ef6"); + vector signature = wvutil::a2b_hex( + "27f7f4da9bd610106ef57d32383a448a" + "8a6245c83dc1309c6d770d357ba89e73" + "f2ad0832062eb0fe0ac915575bcd6b8b" + "cadb4e2ba6fa9da73a59175152b2d4fe" + "72b070c9b7379e50000e55e6c269f665" + "8c937972797d3add69f130e34b85bdec" + "9f3a9b392202d6f3e430d09caca82277" + "59ab825f7012d2ff4b5b62c8504dbad8" + "55c05edd5cab5a4cccdc67f01dd6517c" + "7d41c43e2a4957aff19db6f18b17859a" + "f0bc84ab67146ec1a4a60a17d7e05f8b" + "4f9ced6ad10908d8d78f7fc88b76adc8" + "290f87daf2a7be10ae408521395d54ed" + "2556fb7661854a730ce3d82c71a8d493" + "ec49a378ac8a3c74439f7cc555ba13f8" + "59070890ee18ff658fa4d741969d70a5"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.16 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_16) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "32474830e2203754c8bf0681dc4f842a" + "fe360930378616c108e833656e5640c8" + "6856885bb05d1eb9438efede679263de" + "07cb39553f6a25e006b0a52311a063ca" + "088266d2564ff6490c46b5609818548f" + "88764dad34a25e3a85d575023f0b9e66" + "5048a03c350579a9d32446c7bb96cc92" + "e065ab94d3c8952e8df68ef0d9fa456b" + "3a06bb80e3bbc4b28e6a94b6d0ff7696" + "a64efe05e735fea025d7bdbc4139f3a3" + "b546075cba7efa947374d3f0ac80a68d" + "765f5df6210bca069a2d88647af7ea04" + "2dac690cb57378ec0777614fb8b65ff4" + "53ca6b7dce6098451a2f8c0da9bfecf1" + "fdf391bbaa4e2a91ca18a1121a7523a2" + "abd42514f489e8"); + vector signature = wvutil::a2b_hex( + "6917437257c22ccb5403290c3dee82d9" + "cf7550b31bd31c51bd57bfd35d452ab4" + "db7c4be6b2e25ac9a59a1d2a7feb627f" + "0afd4976b3003cc9cffd8896505ec382" + "f265104d4cf8c932fa9fe86e00870795" + "9912389da4b2d6b369b36a5e72e29d24" + "c9a98c9d31a3ab44e643e6941266a47a" + "45e3446ce8776abe241a8f5fc6423b24" + "b1ff250dc2c3a8172353561077e850a7" + "69b25f0325dac88965a3b9b472c494e9" + "5f719b4eac332caa7a65c7dfe46d9aa7" + "e6e00f525f303dd63ab7919218901868" + "f9337f8cd26aafe6f33b7fb2c98810af" + "19f7fcb282ba1577912c1d368975fd5d" + "440b86e10c199715fa0b6f4250b53373" + "2d0befe1545150fc47b876de09b00a94"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.17 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_17) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "008e59505eafb550aae5e845584cebb0" + "0b6de1733e9f95d42c882a5bbeb5ce1c" + "57e119e7c0d4daca9f1ff7870217f7cf" + "d8a6b373977cac9cab8e71e420"); + vector signature = wvutil::a2b_hex( + "922503b673ee5f3e691e1ca85e9ff417" + "3cf72b05ac2c131da5603593e3bc259c" + "94c1f7d3a06a5b9891bf113fa39e59ff" + "7c1ed6465e908049cb89e4e125cd37d2" + "ffd9227a41b4a0a19c0a44fbbf3de55b" + "ab802087a3bb8d4ff668ee6bbb8ad89e" + "6857a79a9c72781990dfcf92cd519404" + "c950f13d1143c3184f1d250c90e17ac6" + "ce36163b9895627ad6ffec1422441f55" + "e4499dba9be89546ae8bc63cca01dd08" + "463ae7f1fce3d893996938778c1812e6" + "74ad9c309c5acca3fde44e7dd8695993" + "e9c1fa87acda99ece5c8499e468957ad" + "66359bf12a51adbe78d3a213b449bf0b" + "5f8d4d496acf03d3033b7ccd196bc22f" + "68fb7bef4f697c5ea2b35062f48a36dd"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.18 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_18) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "6abc54cf8d1dff1f53b17d8160368878" + "a8788cc6d22fa5c2258c88e660b09a89" + "33f9f2c0504ddadc21f6e75e0b833beb" + "555229dee656b9047b92f62e76b8ffcc" + "60dab06b80"); + vector signature = wvutil::a2b_hex( + "0b6daf42f7a862147e417493c2c401ef" + "ae32636ab4cbd44192bbf5f195b50ae0" + "96a475a1614f0a9fa8f7a026cb46c650" + "6e518e33d83e56477a875aca8c7e714c" + "e1bdbd61ef5d535239b33f2bfdd61771" + "bab62776d78171a1423cea8731f82e60" + "766d6454265620b15f5c5a584f55f95b" + "802fe78c574ed5dacfc831f3cf2b0502" + "c0b298f25ccf11f973b31f85e4744219" + "85f3cff702df3946ef0a6605682111b2" + "f55b1f8ab0d2ea3a683c69985ead93ed" + "449ea48f0358ddf70802cb41de2fd83f" + "3c808082d84936948e0c84a131b49278" + "27460527bb5cd24bfab7b48e071b2417" + "1930f99763272f9797bcb76f1d248157" + "5558fcf260b1f0e554ebb3df3cfcb958"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.19 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_19) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "af2d78152cf10efe01d274f217b177f6" + "b01b5e749f1567715da324859cd3dd88" + "db848ec79f48dbba7b6f1d33111ef31b" + "64899e7391c2bffd69f49025cf201fc5" + "85dbd1542c1c778a2ce7a7ee108a309f" + "eca26d133a5ffedc4e869dcd7656596a" + "c8427ea3ef6e3fd78fe99d8ddc71d839" + "f6786e0da6e786bd62b3a4f19b891a56" + "157a554ec2a2b39e25a1d7c7d37321c7" + "a1d946cf4fbe758d9276f08563449d67" + "414a2c030f4251cfe2213d04a5410637" + "87"); + vector signature = wvutil::a2b_hex( + "209c61157857387b71e24bf3dd564145" + "50503bec180ff53bdd9bac062a2d4995" + "09bf991281b79527df9136615b7a6d9d" + "b3a103b535e0202a2caca197a7b74e53" + "56f3dd595b49acfd9d30049a98ca88f6" + "25bca1d5f22a392d8a749efb6eed9b78" + "21d3110ac0d244199ecb4aa3d735a83a" + "2e8893c6bf8581383ccaee834635b7fa" + "1faffa45b13d15c1da33af71e89303d6" + "8090ff62ee615fdf5a84d120711da53c" + "2889198ab38317a9734ab27d67924cea" + "74156ff99bef9876bb5c339e93745283" + "e1b34e072226b88045e017e9f05b2a8c" + "416740258e223b2690027491732273f3" + "229d9ef2b1b3807e321018920ad3e53d" + "ae47e6d9395c184b93a374c671faa2ce"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +// # PKCS#1 v1.5 Signature Example 15.20 +TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_20) { + BuildRSAKey(); + LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); + vector message = wvutil::a2b_hex( + "40ee992458d6f61486d25676a96dd2cb" + "93a37f04b178482f2b186cf88215270d" + "ba29d786d774b0c5e78c7f6e56a956e7" + "f73950a2b0c0c10a08dbcd67e5b210bb" + "21c58e2767d44f7dd4014e3966143bf7" + "e3d66ff0c09be4c55f93b39994b8518d" + "9c1d76d5b47374dea08f157d57d70634" + "978f3856e0e5b481afbbdb5a3ac48d48" + "4be92c93de229178354c2de526e9c65a" + "31ede1ef68cb6398d7911684fec0babc" + "3a781a66660783506974d0e14825101c" + "3bfaea"); + vector signature = wvutil::a2b_hex( + "927502b824afc42513ca6570de338b8a" + "64c3a85eb828d3193624f27e8b1029c5" + "5c119c9733b18f5849b3500918bcc005" + "51d9a8fdf53a97749fa8dc480d6fe974" + "2a5871f973926528972a1af49e3925b0" + "adf14a842719b4a5a2d89fa9c0b6605d" + "212bed1e6723b93406ad30e86829a5c7" + "19b890b389306dc5506486ee2f36a8df" + "e0a96af678c9cbd6aff397ca200e3edc" + "1e36bd2f08b31d540c0cb282a9559e4a" + "dd4fc9e6492eed0ccbd3a6982e5faa2d" + "dd17be47417c80b4e5452d31f72401a0" + "42325109544d954c01939079d409a5c3" + "78d7512dfc2d2a71efcc3432a765d1c6" + "a52cfce899cd79b15b4fc3723641ef6b" + "d00acc10407e5df58dd1c3c5c559a506"); + TestSignature(kSign_PKCS1_Block1, message, signature); +} + +TEST_P(OEMCryptoSessionTestLoadCasKeysWithHDCP, CasOnlyLoadCasKeysAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } + // Test parameterized by HDCP version. + LoadCasKeysWithHDCP(static_cast(GetParam())); +} +INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestLoadCasKeysWithHDCP, + Range(1, 6)); +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_cast_test.h b/oemcrypto/test/oemcrypto_cast_test.h new file mode 100644 index 00000000..b6e2116c --- /dev/null +++ b/oemcrypto/test/oemcrypto_cast_test.h @@ -0,0 +1,228 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_CAST_TEST_ +#define CDM_OEMCRYPTO_CAST_TEST_ + +#include + +#include + +#include "OEMCryptoCENC.h" +#include "oemcrypto_provisioning_test.h" +#include "oemcrypto_session_tests_helper.h" + +namespace wvoec { + +const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value); + +std::string MaybeHex(const uint8_t* data, size_t length); +std::string MaybeHex(const std::vector& data); + +// This test attempts to use alternate algorithms for loaded device certs. +class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { + protected: + void DisallowForbiddenPadding(RSA_Padding_Scheme scheme, size_t size) { + OEMCryptoResult sts; + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + + // Sign a Message + vector licenseRequest(size); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); + size_t signature_length = 256; + vector signature(signature_length); + sts = OEMCrypto_GenerateRSASignature( + s.session_id(), licenseRequest.data(), licenseRequest.size(), + signature.data(), &signature_length, scheme); + // Allow OEMCrypto to request a full buffer. + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + ASSERT_NE(static_cast(0), signature_length); + signature.assign(signature_length, 0); + sts = OEMCrypto_GenerateRSASignature( + s.session_id(), licenseRequest.data(), licenseRequest.size(), + signature.data(), &signature_length, scheme); + } + + EXPECT_NE(OEMCrypto_SUCCESS, sts) + << "Signed with forbidden padding scheme=" << (int)scheme + << ", size=" << (int)size; + const vector zero(signature.size(), 0); + ASSERT_EQ(zero, signature); // signature should not be computed. + } + + void TestSignature(RSA_Padding_Scheme scheme, size_t size) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + + vector licenseRequest(size); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); + size_t signature_length = 0; + OEMCryptoResult sts = OEMCrypto_GenerateRSASignature( + s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr, + &signature_length, scheme); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + ASSERT_NE(static_cast(0), signature_length); + + std::vector signature(signature_length, 0); + sts = OEMCrypto_GenerateRSASignature( + s.session_id(), licenseRequest.data(), licenseRequest.size(), + signature.data(), &signature_length, scheme); + + ASSERT_EQ(OEMCrypto_SUCCESS, sts) + << "Failed to sign with padding scheme=" << (int)scheme + << ", size=" << size; + signature.resize(signature_length); + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature( + licenseRequest, signature.data(), signature_length, scheme)); + } + + void DisallowDeriveKeys() { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + s.GenerateNonce(); + vector session_key; + vector enc_session_key; + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key)); + vector mac_context; + vector enc_context; + s.FillDefaultContext(&mac_context, &enc_context); + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_DeriveKeysFromSessionKey( + s.session_id(), enc_session_key.data(), + enc_session_key.size(), mac_context.data(), + mac_context.size(), enc_context.data(), enc_context.size())); + } + + // If force is true, we assert that the key loads successfully. + void LoadWithAllowedSchemes(uint32_t schemes, bool force) { + // prov 2 or prov 3 + if (global_features.provisioning_method == OEMCrypto_Keybox || + global_features.provisioning_method == OEMCrypto_OEMCertificate) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.set_allowed_schemes(schemes); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + OEMCryptoResult sts = provisioning_messages.LoadResponse(); + key_loaded_ = (OEMCrypto_SUCCESS == sts); + if (key_loaded_) { + uint8_t* ptr = provisioning_messages.response_data().rsa_key; + size_t len = provisioning_messages.response_data().rsa_key_length; + encoded_rsa_key_ = std::vector(ptr, ptr + len); + wrapped_drm_key_ = provisioning_messages.wrapped_rsa_key(); + drm_key_type_ = OEMCrypto_RSA_Private_Key; + EXPECT_GT(wrapped_drm_key_.size(), 0u); + EXPECT_EQ(nullptr, find(wrapped_drm_key_, encoded_rsa_key_)); + } + if (force) { + EXPECT_EQ(OEMCrypto_SUCCESS, sts); + } + } else if (global_features.provisioning_method == + OEMCrypto_BootCertificateChain) { + Session s1; + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s1)); + + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s2.session_id(), oem_key_type_, + wrapped_oem_key_.data(), + wrapped_oem_key_.size()), + OEMCrypto_SUCCESS); + Provisioning40CastRoundTrip prov_cast(&s2, encoded_rsa_key_); + prov_cast.set_allowed_schemes(schemes); + ASSERT_NO_FATAL_FAILURE(prov_cast.PrepareSession()); + ASSERT_NO_FATAL_FAILURE(prov_cast.LoadDRMPrivateKey()); + + ASSERT_NO_FATAL_FAILURE(s2.SetPublicKeyFromSubjectPublicKey( + prov_cast.drm_key_type(), prov_cast.drm_public_key().data(), + prov_cast.drm_public_key().size())); + ASSERT_NO_FATAL_FAILURE(prov_cast.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(s2.GenerateDerivedKeysFromSessionKey()); + ASSERT_NO_FATAL_FAILURE(prov_cast.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(prov_cast.EncryptAndSignResponse()); + OEMCryptoResult sts = prov_cast.LoadResponse(); + key_loaded_ = (OEMCrypto_SUCCESS == sts); + if (key_loaded_) { + uint8_t* ptr = prov_cast.response_data().rsa_key; + size_t len = prov_cast.response_data().rsa_key_length; + encoded_rsa_key_ = std::vector(ptr, ptr + len); + wrapped_drm_key_ = prov_cast.wrapped_rsa_key(); + drm_key_type_ = OEMCrypto_RSA_Private_Key; + EXPECT_GT(wrapped_drm_key_.size(), 0u); + EXPECT_EQ(nullptr, find(wrapped_drm_key_, encoded_rsa_key_)); + } + if (force) { + EXPECT_EQ(OEMCrypto_SUCCESS, sts); + } + } else { + FAIL() << "Unsupported provisioning method"; + } + } + + bool key_loaded_ = false; +}; + +// Used to test the different HDCP versions. This test is parameterized by the +// required HDCP version in the key control block. +class OEMCryptoSessionTestLoadCasKeysWithHDCP : public OEMCryptoSessionTests, + public WithParamInterface { + protected: + void LoadCasKeysWithHDCP(OEMCrypto_HDCP_Capability version) { + OEMCryptoResult sts; + OEMCrypto_HDCP_Capability current, maximum; + sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_control((version << wvoec::kControlHDCPVersionShift) | + wvoec::kControlObserveHDCP | + wvoec::kControlHDCPRequired); + license_messages.set_license_type(OEMCrypto_EntitlementLicense); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + + uint32_t key_session_id; + sts = OEMCrypto_CreateEntitledKeySession(s.session_id(), &key_session_id); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + EntitledMessage entitled_message_1(&license_messages); + entitled_message_1.FillKeyArray(); + entitled_message_1.SetEntitledKeySession(key_session_id); + + if (((version <= HDCP_V2_3 || current >= HDCP_V1_0) && version > current) || + (current == HDCP_V1 && version >= HDCP_V1_0)) { + ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys( + /*load_even=*/true, /*load_odd=*/true, + OEMCrypto_ERROR_INSUFFICIENT_HDCP)) + << "Failed when current HDCP = " << HDCPCapabilityAsString(current) + << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) + << ", license HDCP = " << HDCPCapabilityAsString(version); + } else { + ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys( + /*load_even=*/true, /*load_odd=*/true, OEMCrypto_SUCCESS)) + << "Failed when current HDCP = " << HDCPCapabilityAsString(current) + << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) + << ", license HDCP = " << HDCPCapabilityAsString(version); + } + } +}; +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_CAST_TEST_ diff --git a/oemcrypto/test/oemcrypto_corpus_generator_helper.h b/oemcrypto/test/oemcrypto_corpus_generator_helper.h index 7b7b399b..e3a73b43 100644 --- a/oemcrypto/test/oemcrypto_corpus_generator_helper.h +++ b/oemcrypto/test/oemcrypto_corpus_generator_helper.h @@ -14,7 +14,7 @@ namespace wvoec { const uint8_t kFuzzDataSeparator[] = {'-', '_', '^', '_'}; void AppendToFile(const std::string& file_name, const char* message, - const size_t message_size); + size_t message_size); // Function to append separator "-_^_" between contents of corpus file. void AppendSeparator(const std::string& file_name); diff --git a/oemcrypto/test/oemcrypto_decrypt_test.cpp b/oemcrypto/test/oemcrypto_decrypt_test.cpp new file mode 100644 index 00000000..22c810c0 --- /dev/null +++ b/oemcrypto/test/oemcrypto_decrypt_test.cpp @@ -0,0 +1,686 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_decrypt_test.h" + +#include "test_sleep.h" + +using ::testing::Combine; +using ::testing::Range; +using ::testing::Values; + +namespace wvoec { + +// Cannot decrypt without first getting a key handle. +TEST_P(OEMCryptoLicenseTest, FailDecryptWithoutGettingAHandle) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// Cannot decrypt with an old key handle. +TEST_P(OEMCryptoLicenseTest, FailDecryptWithOldKeyHandle) { + Session donor_session; + LicenseRoundTrip license_messages2(&donor_session); + ASSERT_NO_FATAL_FAILURE(donor_session.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&donor_session)); + ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(donor_session.TestDecryptCTR()); + + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + // Inject the donor session's key handle into |session_| and then close the + // donor, which should render the handle invalid. + session_.key_handle() = donor_session.key_handle(); + donor_session.close(); + + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// SelectKey should fail if we attempt to select a key that has not been loaded. +// Also, the error should be NO_CONTENT_KEY. +// This test should pass for v15 devices, except that the exact error code was +// not specified until v16. +TEST_P(OEMCryptoLicenseTest, SelectKeyNotThereAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + const char* key_id = "no_key"; + vector key_handle; + OEMCryptoResult sts = GetKeyHandleIntoVector( + session_.session_id(), reinterpret_cast(key_id), + strlen(key_id), OEMCrypto_CipherMode_CENC, key_handle); + if (sts != OEMCrypto_SUCCESS) { + EXPECT_EQ(OEMCrypto_ERROR_NO_CONTENT_KEY, sts); + } else { + // Delayed error code. If select key was a success, then we should + // eventually see the error when we decrypt. + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + // Generate test data + for (size_t i = 0; i < in_buffer.size(); i++) in_buffer[i] = i % 256; + + // Create the pattern description (always 0,0 for CTR) + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + + // Try to decrypt the data + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_EQ(sts, OEMCrypto_ERROR_NO_CONTENT_KEY); + } +} + +// 'cens' mode is no longer supported in v16 +TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + vector key_handle; + OEMCryptoResult sts; + sts = GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + // Create a non-zero pattern to indicate this is 'cens' + OEMCrypto_CENCEncryptPatternDesc pattern = {1, 9}; + + // Try to decrypt the data + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); +} + +// 'cbc1' mode is no longer supported in v16 +TEST_P(OEMCryptoLicenseTest, RejectCbc1API16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + vector key_handle; + OEMCryptoResult sts; + sts = GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CBCS, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + // Create a zero pattern to indicate this is 'cbc1' + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + + // Try to decrypt the data + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); +} + +TEST_P(OEMCryptoLicenseTest, RejectCbcsWithBlockOffset) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + vector key_handle; + OEMCryptoResult sts; + sts = GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CBCS, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + subsample_description.block_offset = 5; // Any value 1-15 will do. + + // Create a non-zero pattern to indicate this is 'cbcs'. + OEMCrypto_CENCEncryptPatternDesc pattern = {1, 9}; + + // Try to decrypt the data + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); +} + +TEST_P(OEMCryptoLicenseTest, RejectOversizedBlockOffset) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + vector key_handle; + OEMCryptoResult sts; + sts = GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + subsample_description.block_offset = 0xFF; // Anything 16+ + + // Create a zero pattern to indicate this is 'cenc'. + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + + // Try to decrypt the data + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_NE(OEMCrypto_SUCCESS, sts); + + // Try again with the minimum invalid value + subsample_description.block_offset = 16; + sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + EXPECT_NE(OEMCrypto_SUCCESS, sts); +} + +TEST_P(OEMCryptoSessionTestDecryptWithHDCP, DecryptAPI09) { + // Test parameterized by HDCP version. + DecryptWithHDCP(static_cast(GetParam())); +} +INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestDecryptWithHDCP, + Range(1, 6)); + +// If the license does not allow a hash, then we should not compute one. +TEST_P(OEMCryptoLicenseTest, HashForbiddenAPI15) { + uint32_t hash_type = OEMCrypto_SupportsDecryptHash(); + // If hash is not supported, or is vendor defined, don't try to test it. + if (hash_type != OEMCrypto_CRC_Clear_Buffer) return; + + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + uint32_t frame_number = 1; + uint32_t hash = 42; + // It is OK to set the hash before loading the keys + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_SetDecryptHash(session_.session_id(), frame_number, + reinterpret_cast(&hash), + sizeof(hash))); + // It is OK to select the key and decrypt. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); + // But the error code should be bad. + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_GetHashErrorCode(session_.session_id(), &frame_number)); +} + +// This test verifies OEMCrypto_SetDecryptHash for out of range frame number. +TEST_P(OEMCryptoLicenseTest, DecryptHashForOutOfRangeFrameNumber) { + uint32_t frame_number = kHugeRandomNumber; + uint32_t hash = 42; + ASSERT_NO_FATAL_FAILURE(OEMCrypto_SetDecryptHash( + session_.session_id(), frame_number, + reinterpret_cast(&hash), sizeof(hash))); +} + +// +// Decrypt Tests -- these test Decrypt CTR mode only. +// +TEST_P(OEMCryptoLicenseTest, Decrypt) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); +} + +// Verify that a zero duration means infinite license duration. +TEST_P(OEMCryptoLicenseTest, DecryptZeroDuration) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = 0; + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) { + // This subsample size is larger than a few encrypt/skip patterns. Most + // test cases use a pattern length of 160, so we'll run through at least two + // full patterns if we have more than 320 -- round up to 400. + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 400}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// When the pattern length is 10 blocks, there is a discrepancy between the +// HLS and the CENC standards for samples of size 160*N+16, for N = 1, 2, 3... +// We require the CENC standard for OEMCrypto, and let a layer above us break +// samples into pieces if they wish to use the HLS standard. +TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 160 + 16}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// Test that a single block can be decrypted. +TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 16}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests the ability to decrypt multiple subsamples with no offset. +// There is no offset within the block, used by CTR mode. +TEST_P(OEMCryptoSessionTestsDecryptTests, NoOffset) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {25, 160}, + {50, 256}, + {25, 160}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests an offset into the block for the second encrypted subsample. +// This should only work for CTR mode, for CBC mode an error is expected in +// the decrypt step. +// If this test fails for CTR mode, then it is probably handling the +// block_offset incorrectly. +TEST_P(OEMCryptoSessionTestsDecryptTests, EvenOffset) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {25, 8}, + {25, 32}, + {25, 50}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + // CTR Mode is self-inverse -- i.e. We can pick the encrypted data and + // compute the unencrypted data. By picking the encrypted data to be all 0, + // it is easier to re-encrypt the data and debug problems. Similarly, we + // pick an iv = 0. + memset(initial_iv_, 0, KEY_IV_SIZE); + TestSample& sample = samples_[0]; // There is only one sample in this test + sample.truth_buffer.assign(sample.description.buffers.input_data_length, 0); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + if (decrypt_inplace_) { + const size_t total_size = sample.description.buffers.input_data_length; + // In case of decrypt_inplace_, encrypted_buffer contains padded bytes + // which is used for buffer overrun validation. Do not copy the padded + // bytes to truth_buffer. + sample.truth_buffer.assign(sample.encrypted_buffer.begin(), + sample.encrypted_buffer.begin() + total_size); + } else { + sample.truth_buffer = + sample.encrypted_buffer; // truth_buffer_ = encrypted zero buffer. + } + // Run EncryptData to re-encrypt this buffer. For CTR mode, we should get + // back to zeros. + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// If the EvenOffset test passes, but this one doesn't, then DecryptCENC might +// be using the wrong definition of block offset. Adding the block offset to +// the block boundary should give you the beginning of the encrypted data. +// This should only work for CTR mode, for CBC mode, the block offset must be +// 0, so an error is expected in the decrypt step. +// Another way to view the block offset is with the formula: +// block_boundary + block_offset = beginning of subsample. +TEST_P(OEMCryptoSessionTestsDecryptTests, OddOffset) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {10, 50}, + {10, 75}, + {10, 75}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests that the algorithm used to increment the counter for +// AES-CTR mode is correct. There are two possible implementations: +// 1) increment the counter as if it were a 128 bit number, +// 2) increment the low 64 bits as a 64 bit number and leave the high bits +// alone. +// For CENC, the algorithm we should use is the second one. OpenSSL defaults to +// the first. If this test is not passing, you should look at the way you +// increment the counter. Look at the example code in ctr128_inc64 above. +// If you start with an IV of 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, after you +// increment twice, you should get 0xFFFFFFFFFFFFFFFF0000000000000000. +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) { + memcpy(initial_iv_, + wvutil::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE").data(), + KEY_IV_SIZE); + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 256}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests the case where an encrypted sample is not an even number of +// blocks. For CTR mode, the partial block is encrypted. For CBC mode the +// partial block should be a copy of the clear data. +TEST_P(OEMCryptoSessionTestsDecryptTests, PartialBlock) { + // Note: for more complete test coverage, we want a sample size that is in + // the encrypted range for some tests, e.g. (3,7), and in the skip range for + // other tests, e.g. (7, 3). 3*16 < 50 and 7*16 > 50. + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 50}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// Based on the resource rating, OEMCrypto should be able to handle the maximum +// amount of data that can be passed to it. This is the lesser of: +// +// 1) The maximum total sample size +// 2) The maximum number of subsamples multiplied by the maximum subsample size +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSampleAPI16) { + const size_t max_sample_size = GetResourceValue(kMaxSampleSize); + const size_t max_subsample_size = GetResourceValue(kMaxSubsampleSize); + const size_t max_num_subsamples = GetResourceValue(kMaxNumberSubsamples); + + // The +1 on this line ensures that, even in cases where max_sample_size is + // not evenly divisible by max_num_subsamples and thus the division gets + // truncated, (max_num_subsamples * subsample_size) will be greater than + // max_sample_size. + const size_t subsample_size = + std::min(max_sample_size / max_num_subsamples + 1, max_subsample_size); + size_t bytes_remaining = max_sample_size; + std::vector subsample_sizes; + while (bytes_remaining > 0 && subsample_sizes.size() < max_num_subsamples) { + const size_t this_subsample_size = + std::min(subsample_size, bytes_remaining); + const size_t clear_size = this_subsample_size / 2; + const size_t encrypted_size = this_subsample_size - clear_size; + + subsample_sizes.push_back({clear_size, encrypted_size}); + bytes_remaining -= this_subsample_size; + } + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes(subsample_sizes)); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryCheckDecryptCENCStatusForHugeNumberOfSubSamples) { + size_t number_of_subsamples = 10000; + std::vector subsample_sizes; + while (number_of_subsamples-- > 0) { + subsample_sizes.push_back({100, 100}); + } + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + OEMCryptoResult result = + OEMCrypto_DecryptCENC(key_handle_.data(), key_handle_.size(), + sample_descriptions.data(), 1, &pattern_); + LOGD("Large number of subsamples test has return code %d", result); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryCheckDecryptCENCStatusForHugeSubSample) { + std::vector subsample_sizes; + subsample_sizes.push_back({100000, 100000}); + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + OEMCryptoResult result = + OEMCrypto_DecryptCENC(key_handle_.data(), key_handle_.size(), + sample_descriptions.data(), 1, &pattern_); + LOGD("Large subsample test has return code %d", result); +} + +// Based on the resource rating, OEMCrypto should be able to handle the maximum +// subsample size. +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) { + const size_t max = GetResourceValue(kMaxSubsampleSize); + const size_t half_max = max / 2; + // This test assumes that the maximum sample size is always more than three + // times the maximum subsample size. + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {max, 0}, + {0, max}, + {half_max, max - half_max}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// There are probably no frames this small, but we should handle them anyway. +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {5, 5}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// Test the case where there is only a clear subsample and no encrypted +// subsample. +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) { + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {256, 0}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests the ability to decrypt multiple samples at once. +TEST_P(OEMCryptoSessionTestsDecryptTests, MultipleSamples) { + ASSERT_NO_FATAL_FAILURE(SetSampleSizes({ + { + {52, 160}, + {25, 256}, + {25, 320}, + }, + { + {300, 64}, + {50, 160}, + {2, 160}, + {24, 160}, + {128, 256}, + }, + { + {70, 320}, + {160, 160}, + }, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// This tests that calling OEMCrypto_Idle and OEMCrypto_Wake once or multiple +// times doesn't break anything. +TEST_P(OEMCryptoSessionTestsDecryptTests, IdleAndWake) { + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); + ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); + ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); + ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); +} + +// This tests that after an idle and a wake, decryption can continue in an +// open session. +TEST_P(OEMCryptoSessionTestsDecryptTests, ContinueDecryptionAfterIdleAndWake) { + // This subsample size is larger than a few encrypt/skip patterns. Most + // test cases use a pattern length of 160, so we'll run through at least two + // full patterns if we have more than 320 -- round up to 400. + ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ + {0, 400}, + })); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); + FreeSecureBuffers(); + // Set state to idle then wake again and try to reencrypt/decrypt + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); + ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); +} + +// Used to construct a specific pattern. +constexpr OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt, + size_t skip) { + return {encrypt, skip}; +} + +INSTANTIATE_TEST_SUITE_P( + CTRTests, OEMCryptoSessionTestsDecryptTests, + Combine(Values(MakePattern(0, 0)), Values(OEMCrypto_CipherMode_CENC), + ::testing::ValuesIn(global_features.GetOutputTypes()))); + +// Decrypt in place for CBC tests was only required in v13. +INSTANTIATE_TEST_SUITE_P( + CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests, + Combine( + Values(MakePattern(3, 7), MakePattern(9, 1), + // HLS edge cases. We should follow the CENC spec, not HLS spec. + MakePattern(1, 9), MakePattern(1, 0), + // AV1 patterns not already covered above. + MakePattern(5, 5), MakePattern(10, 0)), + Values(OEMCrypto_CipherMode_CBCS), + ::testing::ValuesIn(global_features.GetOutputTypes()))); + +// A request to decrypt data to a clear buffer when the key control block +// requires a secure data path. +TEST_P(OEMCryptoLicenseTest, DecryptSecureToClear) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(wvoec::kControlObserveDataPath | + wvoec::kControlDataPathSecure); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// Test that key duration is honored. +TEST_P(OEMCryptoLicenseTest, KeyDuration) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); + wvutil::TestSleep::Sleep(kShortSleep); // Should still be valid key. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false, OEMCrypto_SUCCESS)); + wvutil::TestSleep::Sleep(kLongSleep); // Should be expired key. + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); + ASSERT_NO_FATAL_FAILURE(session_.TestGetKeyHandleExpired(0)); +} + +INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseTest, + Range(kCurrentAPI - 2, kCurrentAPI + 1)); + +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_decrypt_test.h b/oemcrypto/test/oemcrypto_decrypt_test.h new file mode 100644 index 00000000..9f9b5005 --- /dev/null +++ b/oemcrypto/test/oemcrypto_decrypt_test.h @@ -0,0 +1,427 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_DECRYPT_TEST_ +#define CDM_OEMCRYPTO_DECRYPT_TEST_ + +#include + +#include "OEMCryptoCENC.h" +#include "log.h" +#include "oec_decrypt_fallback_chain.h" +#include "oemcrypto_basic_test.h" +#include "oemcrypto_license_test.h" + +namespace wvoec { + +// Used to test the different HDCP versions. This test is parameterized by the +// required HDCP version in the key control block. +class OEMCryptoSessionTestDecryptWithHDCP : public OEMCryptoSessionTests, + public WithParamInterface { + protected: + void DecryptWithHDCP(OEMCrypto_HDCP_Capability version) { + OEMCryptoResult sts; + OEMCrypto_HDCP_Capability current, maximum; + sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_control((version << wvoec::kControlHDCPVersionShift) | + wvoec::kControlObserveHDCP | + wvoec::kControlHDCPRequired); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + + if (((version <= HDCP_V2_3 || current >= HDCP_V1_0) && version > current) || + (current == HDCP_V1 && version >= HDCP_V1_0)) { + if (global_features.api_version >= 16) { + // Can provide either OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION or + // OEMCrypto_ERROR_INSUFFICIENT_HDCP. TestDecryptCTR allows either to be + // reported if OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION is expected. + ASSERT_NO_FATAL_FAILURE( + s.TestDecryptCTR(true, OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION)) + << "Failed when current HDCP = " << HDCPCapabilityAsString(current) + << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) + << ", license HDCP = " << HDCPCapabilityAsString(version); + } else { + ASSERT_NO_FATAL_FAILURE( + s.TestDecryptCTR(true, OEMCrypto_ERROR_INSUFFICIENT_HDCP)) + << "Failed when current HDCP = " << HDCPCapabilityAsString(current) + << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) + << ", license HDCP = " << HDCPCapabilityAsString(version); + } + } else { + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(true, OEMCrypto_SUCCESS)) + << "Failed when current HDCP = " << HDCPCapabilityAsString(current) + << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) + << ", license HDCP = " << HDCPCapabilityAsString(version); + } + } +}; + +struct SubsampleSize { + size_t clear_size; + size_t encrypted_size; + SubsampleSize(size_t clear, size_t encrypted) + : clear_size(clear), encrypted_size(encrypted) {} +}; + +// Struct for holding the data for one test sample in the decrypt tests. +struct TestSample { + // Encrypted data -- this is input to OEMCrypto, and output from EncryptData. + std::vector encrypted_buffer; + std::vector clear_buffer; // OEMCrypto store clear output here. + std::vector truth_buffer; // Truth data for clear text. + OEMCrypto_SampleDescription description; + std::vector subsamples; + int secure_buffer_fid; +}; + +// A class of tests that test decryption for a variety of patterns and modes. +// This test is parameterized by three parameters: +// 1. The pattern used for pattern decryption. +// 2. The cipher mode for decryption: either CTR or CBC. +// 3. A boolean that determines if decrypt in place should be done. When the +// output buffer is clear, it should be possible for the input and output +// buffers to be the same. +class OEMCryptoSessionTestsDecryptTests + : public OEMCryptoLicenseTestAPI16, + public WithParamInterface> { + protected: + void SetUp() override { + OEMCryptoLicenseTestAPI16::SetUp(); + pattern_ = ::testing::get<0>(GetParam()); + cipher_mode_ = ::testing::get<1>(GetParam()); + decrypt_inplace_ = ::testing::get<2>(GetParam()).decrypt_inplace; + output_buffer_type_ = ::testing::get<2>(GetParam()).type; + verify_crc_ = global_features.supports_crc; + // Pick a random key. + EXPECT_EQ(GetRandBytes(key_, sizeof(key_)), 1); + // Pick a random starting iv. Some tests override this before using it. + EXPECT_EQ(GetRandBytes(initial_iv_, sizeof(initial_iv_)), 1); + } + + void TearDown() override { + FreeSecureBuffers(); + OEMCryptoLicenseTestAPI16::TearDown(); + } + + void SetSubsampleSizes(std::vector subsample_sizes) { + // This is just sugar for having one sample with the given subsamples in it. + SetSampleSizes({subsample_sizes}); + } + + void SetSampleSizes(std::vector> sample_sizes) { + ASSERT_GT(sample_sizes.size(), 0u); + samples_.clear(); + samples_.reserve(sample_sizes.size()); + + // Convert all the size arrays to TestSample structs + for (const std::vector& subsample_sizes : sample_sizes) { + // This could be one line if we had C++17 + samples_.emplace_back(); + TestSample& sample = samples_.back(); + + ASSERT_GT(subsample_sizes.size(), 0u); + sample.subsamples.reserve(subsample_sizes.size()); + + // Convert all the sizes to subsample descriptions and tally the total + // sample size + size_t sample_size = 0; + size_t current_block_offset = 0; + for (const SubsampleSize& size : subsample_sizes) { + sample.subsamples.push_back(OEMCrypto_SubSampleDescription{ + size.clear_size, size.encrypted_size, + 0, // Subsample Flags, to be filled in after the loop + current_block_offset}); + + // Update the rolling variables + sample_size += size.clear_size + size.encrypted_size; + if (cipher_mode_ == OEMCrypto_CipherMode_CENC) { + current_block_offset = + (current_block_offset + size.encrypted_size) % AES_BLOCK_SIZE; + } + } + + // Set the subsample flags now that all the subsamples are processed + sample.subsamples.front().subsample_flags |= OEMCrypto_FirstSubsample; + sample.subsamples.back().subsample_flags |= OEMCrypto_LastSubsample; + + // Set related information on the sample description + sample.description.subsamples = sample.subsamples.data(); + sample.description.subsamples_length = sample.subsamples.size(); + sample.description.buffers.input_data_length = sample_size; + } + } + + // Set up the input buffer and either a clear or secure output buffer for each + // test sample. This should be called after SetSubsampleSizes(). + void MakeBuffers() { + for (TestSample& sample : samples_) { + const size_t total_size = sample.description.buffers.input_data_length; + ASSERT_GT(total_size, 0u); + sample.encrypted_buffer.clear(); + sample.truth_buffer.clear(); + sample.clear_buffer.clear(); + sample.encrypted_buffer.resize(total_size); + sample.truth_buffer.resize(total_size); + for (size_t i = 0; i < total_size; i++) sample.truth_buffer[i] = i % 256; + + OEMCrypto_DestBufferDesc& output_descriptor = + sample.description.buffers.output_descriptor; + output_descriptor.type = output_buffer_type_; + switch (output_descriptor.type) { + case OEMCrypto_BufferType_Clear: + if (decrypt_inplace_) { + // Add some padding to verify there is no overrun. + sample.encrypted_buffer.resize(total_size + kBufferOverrunPadding, + 0xaa); + output_descriptor.buffer.clear.clear_buffer = + sample.encrypted_buffer.data(); + } else { + // Add some padding to verify there is no overrun. + sample.clear_buffer.resize(total_size + kBufferOverrunPadding, + 0xaa); + output_descriptor.buffer.clear.clear_buffer = + sample.clear_buffer.data(); + } + output_descriptor.buffer.clear.clear_buffer_length = total_size; + break; + + case OEMCrypto_BufferType_Secure: + output_descriptor.buffer.secure.secure_buffer_length = total_size; + ASSERT_EQ(OEMCrypto_AllocateSecureBuffer( + session_.session_id(), total_size, &output_descriptor, + &sample.secure_buffer_fid), + OEMCrypto_SUCCESS); + ASSERT_NE(output_descriptor.buffer.secure.secure_buffer, nullptr); + // It is OK if OEMCrypto changes the maximum size, but there must + // still be enough room for our data. + ASSERT_GE(output_descriptor.buffer.secure.secure_buffer_length, + total_size); + output_descriptor.buffer.secure.offset = 0; + break; + + case OEMCrypto_BufferType_Direct: + output_descriptor.buffer.direct.is_video = false; + break; + } // switch (output_descriptor.type) + } // sample loop + } + + void FreeSecureBuffers() { + for (TestSample& sample : samples_) { + OEMCrypto_DestBufferDesc& output_descriptor = + sample.description.buffers.output_descriptor; + if (output_descriptor.type == OEMCrypto_BufferType_Secure) { + ASSERT_EQ(OEMCrypto_FreeSecureBuffer(session_.session_id(), + &output_descriptor, + sample.secure_buffer_fid), + OEMCrypto_SUCCESS); + } + } + } + + void EncryptData() { + AES_KEY aes_key; + AES_set_encrypt_key(key_, AES_BLOCK_SIZE * 8, &aes_key); + + for (TestSample& sample : samples_) { + uint8_t iv[KEY_IV_SIZE]; // Current IV + memcpy(iv, initial_iv_, KEY_IV_SIZE); + memcpy(sample.description.iv, initial_iv_, KEY_IV_SIZE); + + size_t buffer_index = 0; // byte index into in and out. + size_t block_offset = 0; // byte index into current block. + for (const OEMCrypto_SubSampleDescription& subsample : + sample.subsamples) { + // Copy clear content. + if (subsample.num_bytes_clear > 0) { + memcpy(&sample.encrypted_buffer[buffer_index], + &sample.truth_buffer[buffer_index], subsample.num_bytes_clear); + buffer_index += subsample.num_bytes_clear; + } + + // The IV resets at the start of each subsample in the 'cbcs' schema. + if (cipher_mode_ == OEMCrypto_CipherMode_CBCS) { + memcpy(iv, initial_iv_, KEY_IV_SIZE); + } + + size_t pattern_offset = 0; + const size_t subsample_end = + buffer_index + subsample.num_bytes_encrypted; + while (buffer_index < subsample_end) { + const size_t size = + min(subsample_end - buffer_index, AES_BLOCK_SIZE - block_offset); + const size_t pattern_length = pattern_.encrypt + pattern_.skip; + const bool skip_block = + (pattern_offset >= pattern_.encrypt) && (pattern_length > 0); + if (pattern_length > 0) { + pattern_offset = (pattern_offset + 1) % pattern_length; + } + // CBC mode should just copy a partial block at the end. If there + // is a partial block at the beginning, an error is returned, so we + // can put whatever we want in the output buffer. + if (skip_block || ((cipher_mode_ == OEMCrypto_CipherMode_CBCS) && + (size < AES_BLOCK_SIZE))) { + memcpy(&sample.encrypted_buffer[buffer_index], + &sample.truth_buffer[buffer_index], size); + block_offset = 0; // Next block should be complete. + } else { + if (cipher_mode_ == OEMCrypto_CipherMode_CENC) { + uint8_t aes_output[AES_BLOCK_SIZE]; + AES_encrypt(iv, aes_output, &aes_key); + for (size_t n = 0; n < size; n++) { + sample.encrypted_buffer[buffer_index + n] = + aes_output[n + block_offset] ^ + sample.truth_buffer[buffer_index + n]; + } + if (size + block_offset < AES_BLOCK_SIZE) { + // Partial block. Don't increment iv. Compute next block + // offset. + block_offset = block_offset + size; + } else { + EXPECT_EQ(block_offset + size, + static_cast(AES_BLOCK_SIZE)); + // Full block. Increment iv, and set offset to 0 for next + // block. + ctr128_inc64(1, iv); + block_offset = 0; + } + } else { + uint8_t aes_input[AES_BLOCK_SIZE]; + for (size_t n = 0; n < size; n++) { + aes_input[n] = sample.truth_buffer[buffer_index + n] ^ iv[n]; + } + AES_encrypt(aes_input, &sample.encrypted_buffer[buffer_index], + &aes_key); + memcpy(iv, &sample.encrypted_buffer[buffer_index], + AES_BLOCK_SIZE); + // CBC mode should always start on block boundary. + block_offset = 0; + } + } + buffer_index += size; + } // encryption loop + } // per-subsample loop + } // per-sample loop + } + + void LoadLicense() { + uint32_t control = wvoec::kControlNonceEnabled; + if (verify_crc_) control |= kControlAllowHashVerification; + if (output_buffer_type_ == OEMCrypto_BufferType_Secure) + control |= kControlObserveDataPath | kControlDataPathSecure; + license_messages_.set_control(control); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_response() + .timer_limits.initial_renewal_duration_seconds = kDuration; + memcpy(license_messages_.response_data().keys[0].key_data, key_, + sizeof(key_)); + license_messages_.response_data().keys[0].cipher_mode = cipher_mode_; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_EQ(GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + cipher_mode_, key_handle_), + OEMCrypto_SUCCESS); + } + + void TestDecryptCENC() { ASSERT_EQ(DecryptCENC(), OEMCrypto_SUCCESS); } + + void ValidateDecryptedData() { + for (TestSample& sample : samples_) { + if (sample.description.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + const size_t total_size = sample.description.buffers.input_data_length; + // To verify there is no buffer overrun after decrypting, look at the + // padded bytes just after the data buffer that was written. It + // should not have changed from the original 0xaa that we set in + // MakeBuffer function. + if (decrypt_inplace_) { + EXPECT_EQ(std::count(sample.encrypted_buffer.begin() + total_size, + sample.encrypted_buffer.end(), 0xaa), + static_cast(kBufferOverrunPadding)) + << "Buffer overrun."; + sample.encrypted_buffer.resize(total_size); // Remove padding. + // We expect encrypted buffer to have been changed by OEMCrypto. + EXPECT_EQ(sample.encrypted_buffer, sample.truth_buffer); + } else { + EXPECT_EQ(std::count(sample.clear_buffer.begin() + total_size, + sample.clear_buffer.end(), 0xaa), + static_cast(kBufferOverrunPadding)) + << "Buffer overrun."; + sample.clear_buffer.resize(total_size); // Remove padding. + EXPECT_EQ(sample.clear_buffer, sample.truth_buffer); + } + } + } + if (verify_crc_) { + uint32_t frame; + ASSERT_EQ(OEMCrypto_GetHashErrorCode(session_.session_id(), &frame), + OEMCrypto_SUCCESS); + } + } + + OEMCryptoResult DecryptCENC() { + // OEMCrypto only supports providing a decrypt hash for one sample. + if (samples_.size() > 1) verify_crc_ = false; + + // If supported, check the decrypt hashes. + if (verify_crc_) { + const TestSample& sample = samples_[0]; + + uint32_t hash = + util::wvcrc32(sample.truth_buffer.data(), sample.truth_buffer.size()); + OEMCrypto_SetDecryptHash(session_.session_id(), 1, + reinterpret_cast(&hash), + sizeof(hash)); + } + + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + + // Perform decryption using the test data that was previously set up. + OEMCryptoResult result = DecryptFallbackChain::Decrypt( + key_handle_.data(), key_handle_.size(), sample_descriptions.data(), + sample_descriptions.size(), cipher_mode_, &pattern_); + if (result != OEMCrypto_SUCCESS) return result; + ValidateDecryptedData(); + return result; + } + + // Parameters of test case + OEMCrypto_CENCEncryptPatternDesc pattern_; + OEMCryptoCipherMode cipher_mode_; + bool decrypt_inplace_; // If true, input and output buffers are the same. + OEMCryptoBufferType output_buffer_type_; + + bool verify_crc_; + uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key. + uint8_t initial_iv_[KEY_IV_SIZE]; // Starting IV for every sample. + std::vector samples_; + std::vector key_handle_; +}; + +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_DECRYPT_TEST_ \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_generic_crypto_test.cpp b/oemcrypto/test/oemcrypto_generic_crypto_test.cpp new file mode 100644 index 00000000..867b4f8e --- /dev/null +++ b/oemcrypto/test/oemcrypto_generic_crypto_test.cpp @@ -0,0 +1,577 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include + +#include "oemcrypto_usage_table_test.h" + +using ::testing::Range; + +namespace wvoec { + +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyLoad) { EncryptAndLoadKeys(); } + +// Test that the Generic_Encrypt function works correctly. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncrypt) { + EncryptAndLoadKeys(); + unsigned int key_index = 0; + vector expected_encrypted; + EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector encrypted(clear_buffer_.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericEncrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); + ASSERT_EQ(expected_encrypted, encrypted); +} + +// Test that the Generic_Encrypt function fails when not allowed. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadEncrypt) { + EncryptAndLoadKeys(); + BadEncrypt(0, OEMCrypto_HMAC_SHA256, buffer_size_); + // The buffer size must be a multiple of 16, so subtracting 10 is bad. + BadEncrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_ - 10); + BadEncrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); + BadEncrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); + BadEncrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); +} + +// Test that the Generic_Encrypt works if the input and output buffers are the +// same. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncryptSameBufferAPI12) { + EncryptAndLoadKeys(); + unsigned int key_index = 0; + vector expected_encrypted; + EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + // Input and output are same buffer: + vector buffer = clear_buffer_; + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericEncrypt(key_handle.data(), key_handle.size(), buffer.data(), + buffer.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + buffer.data())); + ASSERT_EQ(expected_encrypted, buffer); +} + +TEST_P( + OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeyEncryptForHugeBufferWithBufferLengthNotMultipleOf16) { + EncryptAndLoadKeys(); + unsigned int key_index = 0; + vector expected_encrypted; + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector buffer(17); + ASSERT_NO_FATAL_FAILURE(OEMCrypto_Generic_Encrypt( + key_handle.data(), key_handle.size(), buffer.data(), buffer.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); +} + +// Test Generic_Decrypt works correctly. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecrypt) { + EncryptAndLoadKeys(); + unsigned int key_index = 1; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector resultant(encrypted.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericDecrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); + ASSERT_EQ(clear_buffer_, resultant); +} + +// Test that Generic_Decrypt works correctly when the input and output buffers +// are the same. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecryptSameBufferAPI12) { + EncryptAndLoadKeys(); + unsigned int key_index = 1; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector buffer = encrypted; + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericDecrypt(key_handle.data(), key_handle.size(), buffer.data(), + buffer.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + buffer.data())); + ASSERT_EQ(clear_buffer_, buffer); +} + +// Test that Generic_Decrypt fails to decrypt to an insecure buffer if the key +// requires a secure data path. +TEST_P(OEMCryptoGenericCryptoTest, GenericSecureToClear) { + license_messages_.set_control(wvoec::kControlObserveDataPath | + wvoec::kControlDataPathSecure); + license_messages_.CreateResponseWithGenericCryptoKeys(); + EncryptAndLoadKeys(); + unsigned int key_index = 1; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector resultant(encrypted.size()); + ASSERT_NE(OEMCrypto_SUCCESS, + GenericDecrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); + ASSERT_NE(clear_buffer_, resultant); +} + +// Test that the Generic_Decrypt function fails when not allowed. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadDecrypt) { + EncryptAndLoadKeys(); + BadDecrypt(1, OEMCrypto_HMAC_SHA256, buffer_size_); + // The buffer size must be a multiple of 16, so subtracting 10 is bad. + BadDecrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_ - 10); + BadDecrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); + BadDecrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); + BadDecrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); +} + +TEST_P(OEMCryptoGenericCryptoTest, GenericKeySign) { + EncryptAndLoadKeys(); + unsigned int key_index = 2; + vector expected_signature; + SignBuffer(key_index, clear_buffer_, &expected_signature); + + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + size_t gen_signature_length = 0; + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, + GenericSign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, nullptr, &gen_signature_length)); + ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); + vector signature(SHA256_DIGEST_LENGTH); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericSign(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + &gen_signature_length)); + ASSERT_EQ(expected_signature, signature); +} + +// Test that the Generic_Sign function fails when not allowed. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadSign) { + EncryptAndLoadKeys(); + BadSign(0, OEMCrypto_HMAC_SHA256); // Can't sign with encrypt key. + BadSign(1, OEMCrypto_HMAC_SHA256); // Can't sign with decrypt key. + BadSign(3, OEMCrypto_HMAC_SHA256); // Can't sign with verify key. + BadSign(2, OEMCrypto_AES_CBC_128_NO_PADDING); // Bad signing algorithm. +} + +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyVerify) { + EncryptAndLoadKeys(); + unsigned int key_index = 3; + vector signature; + SignBuffer(key_index, clear_buffer_, &signature); + + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericVerify(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, + signature.data(), signature.size())); +} + +// Test that the Generic_Verify function fails when not allowed. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadVerify) { + EncryptAndLoadKeys(); + BadVerify(0, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); + BadVerify(1, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); + BadVerify(2, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); + BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, true); + BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH - 1, false); + BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH + 1, false); + BadVerify(3, OEMCrypto_AES_CBC_128_NO_PADDING, SHA256_DIGEST_LENGTH, false); +} + +// Test Generic_Encrypt with the maximum buffer size. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncryptLargeBuffer) { + ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); + EncryptAndLoadKeys(); + unsigned int key_index = 0; + vector expected_encrypted; + EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector encrypted(clear_buffer_.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericEncrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); + ASSERT_EQ(expected_encrypted, encrypted); +} + +// Test Generic_Decrypt with the maximum buffer size. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecryptLargeBuffer) { + // Some applications are known to pass in a block that is almost 400k. + ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); + EncryptAndLoadKeys(); + unsigned int key_index = 1; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector resultant(encrypted.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericDecrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); + ASSERT_EQ(clear_buffer_, resultant); +} + +// Test Generic_Sign with the maximum buffer size. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeySignLargeBuffer) { + ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); + EncryptAndLoadKeys(); + unsigned int key_index = 2; + vector expected_signature; + SignBuffer(key_index, clear_buffer_, &expected_signature); + + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + size_t gen_signature_length = 0; + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, + GenericSign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, nullptr, &gen_signature_length)); + ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); + vector signature(SHA256_DIGEST_LENGTH); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericSign(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + &gen_signature_length)); + ASSERT_EQ(expected_signature, signature); +} + +// Test Generic_Verify with the maximum buffer size. +TEST_P(OEMCryptoGenericCryptoTest, GenericKeyVerifyLargeBuffer) { + ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); + EncryptAndLoadKeys(); + unsigned int key_index = 3; + vector signature; + SignBuffer(key_index, clear_buffer_, &signature); + + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericVerify(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, + signature.data(), signature.size())); +} + +// Test Generic_Encrypt when the key duration has expired. +TEST_P(OEMCryptoGenericCryptoTest, KeyDurationEncrypt) { + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + license_messages_.CreateResponseWithGenericCryptoKeys(); + EncryptAndLoadKeys(); + vector expected_encrypted; + EncryptBuffer(0, clear_buffer_, &expected_encrypted); + unsigned int key_index = 0; + vector encrypted(clear_buffer_.size()); + + vector key_handle; + // Should be valid key at the start. + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericEncrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); + ASSERT_EQ(expected_encrypted, encrypted); + + wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. + encrypted.assign(clear_buffer_.size(), 0); + OEMCryptoResult status = OEMCrypto_Generic_Encrypt( + key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data()); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); + ASSERT_NE(encrypted, expected_encrypted); + ASSERT_NO_FATAL_FAILURE(session_.TestGetKeyHandleExpired(key_index)); +} + +// Test Generic_Decrypt when the key duration has expired. +TEST_P(OEMCryptoGenericCryptoTest, KeyDurationDecrypt) { + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + license_messages_.CreateResponseWithGenericCryptoKeys(); + EncryptAndLoadKeys(); + + // Should be valid key at the start. + unsigned int key_index = 1; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector resultant(encrypted.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + GenericDecrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); + ASSERT_EQ(clear_buffer_, resultant); + + wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. + resultant.assign(encrypted.size(), 0); + OEMCryptoResult status = GenericDecrypt( + key_handle.data(), key_handle.size(), encrypted.data(), encrypted.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); + ASSERT_NE(clear_buffer_, resultant); + ASSERT_NO_FATAL_FAILURE(session_.TestGetKeyHandleExpired(key_index)); +} + +// Test Generic_Sign when the key duration has expired. +TEST_P(OEMCryptoGenericCryptoTest, KeyDurationSign) { + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + license_messages_.CreateResponseWithGenericCryptoKeys(); + EncryptAndLoadKeys(); + + unsigned int key_index = 2; + vector expected_signature; + vector signature(SHA256_DIGEST_LENGTH); + size_t signature_length = signature.size(); + SignBuffer(key_index, clear_buffer_, &expected_signature); + + vector key_handle; + // Should be valid key at the start. + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericSign(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + &signature_length)); + ASSERT_EQ(expected_signature, signature); + + wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. + signature.assign(SHA256_DIGEST_LENGTH, 0); + OEMCryptoResult status = + GenericSign(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + &signature_length); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); + ASSERT_NE(expected_signature, signature); + ASSERT_NO_FATAL_FAILURE(session_.TestGetKeyHandleExpired(key_index)); +} + +// Test Generic_Verify when the key duration has expired. +TEST_P(OEMCryptoGenericCryptoTest, KeyDurationVerify) { + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + license_messages_.CreateResponseWithGenericCryptoKeys(); + EncryptAndLoadKeys(); + + unsigned int key_index = 3; + vector signature; + SignBuffer(key_index, clear_buffer_, &signature); + + vector key_handle; + // Should be valid key at the start. + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + ASSERT_EQ( + OEMCrypto_SUCCESS, + GenericVerify(key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, + signature.data(), signature.size())); + + wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. + OEMCryptoResult status = OEMCrypto_Generic_Verify( + key_handle.data(), key_handle.size(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + signature.size()); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); + ASSERT_NO_FATAL_FAILURE(session_.TestGetKeyHandleExpired(key_index)); +} + +const unsigned int kLongKeyId = 2; + +// Test that short key ids are allowed. +class OEMCryptoGenericCryptoKeyIdLengthTest + : public OEMCryptoGenericCryptoTest { + protected: + void SetUp() override { + OEMCryptoGenericCryptoTest::SetUp(); + license_messages_.set_num_keys(5); + license_messages_.set_control(wvoec::kControlAllowDecrypt); + license_messages_.core_response() + .timer_limits.total_playback_duration_seconds = kDuration; + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + SetUniformKeyIdLength(16); // Start with all key ids being 16 bytes. + // But, we are testing that the key ids do not have to have the same + // length. + // 12 bytes (common key id length). + license_messages_.SetKeyId(0, "123456789012"); + license_messages_.SetKeyId(1, "12345"); // short key id. + // 16 byte key id. (default) + license_messages_.SetKeyId(2, "1234567890123456"); + license_messages_.SetKeyId(3, "12345678901234"); // 14 byte. (uncommon) + license_messages_.SetKeyId(4, "1"); // very short key id. + ASSERT_EQ(2u, kLongKeyId); + ASSERT_NO_FATAL_FAILURE(license_messages_.FillCoreResponseSubstrings()); + } + + // Make all four keys have the same length. + void SetUniformKeyIdLength(size_t key_id_length) { + for (size_t i = 0; i < license_messages_.num_keys(); i++) { + string key_id; + key_id.resize(key_id_length, i + 'a'); + license_messages_.SetKeyId(i, key_id); + } + ASSERT_NO_FATAL_FAILURE(license_messages_.FillCoreResponseSubstrings()); + } + + void TestWithKey(unsigned int key_index) { + ASSERT_LT(key_index, license_messages_.num_keys()); + EncryptAndLoadKeys(); + vector encrypted; + // To make sure OEMCrypto is not expecting the key_id to be zero padded, + // we will create a buffer that is padded with 'Z'. Then, we use fill + // the buffer with the longer of the three keys. If OEMCrypto is paying + // attention to the key id length, it should pick out the correct key. + vector key_id_buffer( + session_.license().keys[kLongKeyId].key_id_length + 5, + 'Z'); // Fill a bigger buffer with letter 'Z'. + memcpy(key_id_buffer.data(), session_.license().keys[kLongKeyId].key_id, + session_.license().keys[kLongKeyId].key_id_length); + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), key_id_buffer.data(), + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + vector resultant(encrypted.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_Generic_Decrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, + resultant.data())); + ASSERT_EQ(clear_buffer_, resultant); + } +}; + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, MediumKeyId) { TestWithKey(0); } + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, ShortKeyId) { TestWithKey(1); } + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, LongKeyId) { TestWithKey(2); } + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, FourteenByteKeyId) { + TestWithKey(3); +} + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, VeryShortKeyId) { + TestWithKey(4); +} + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, UniformShortKeyId) { + SetUniformKeyIdLength(5); + TestWithKey(2); +} + +TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, UniformLongKeyId) { + SetUniformKeyIdLength(kTestKeyIdMaxLength); + TestWithKey(2); +} + +INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoGenericCryptoTest, + Range(kCoreMessagesAPI, kCurrentAPI + 1)); + +INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoGenericCryptoKeyIdLengthTest, + Range(kCoreMessagesAPI, kCurrentAPI + 1)); + +/// @} +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_license_test.cpp b/oemcrypto/test/oemcrypto_license_test.cpp new file mode 100644 index 00000000..fedd8f9b --- /dev/null +++ b/oemcrypto/test/oemcrypto_license_test.cpp @@ -0,0 +1,970 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_license_test.h" + +#include "platform.h" +#include "test_sleep.h" + +using ::testing::Range; + +namespace wvoec { + +// Function to test APIs that expect a buffer length as input +// by passing huge buffer lengths up to end_buffer_length and test that the API +// doesn't crash. +void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, + size_t start_buffer_length, + size_t end_buffer_length, + bool check_status) { + OEMCryptoResult sts = OEMCrypto_SUCCESS; + for (size_t buffer_length = start_buffer_length; + buffer_length < end_buffer_length && + (sts == OEMCrypto_SUCCESS || sts == OEMCrypto_ERROR_SHORT_BUFFER || + !check_status); + buffer_length *= 2) { + sts = f(buffer_length); + if (check_status && sts != OEMCrypto_SUCCESS && + sts != OEMCrypto_ERROR_SHORT_BUFFER) { + LOGI("Test exits huge buffer loop for length:%zu, status:%d", + buffer_length, sts); + } + } +} + +// Function to test APIs that expect a buffer length as input +// by passing huge buffer lengths up to kHugeInputBufferLength and test that +// the API doesn't crash. +void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, bool check_status) { + TestHugeLengthDoesNotCrashAPI(f, 1, kHugeInputBufferLength, check_status); +} + +// This test verifies that OEMCrypto can load the total number of keys required +// for the reported resource level. +void TestMaxKeys(SessionUtil* util, size_t num_keys_per_session) { + const size_t max_total_keys = GetResourceValue(kMaxTotalKeys); + ASSERT_LE(num_keys_per_session, kMaxNumKeys) << "Update test constants."; + std::vector> sessions; + std::vector> licenses; + size_t total_keys = 0; + for (size_t i = 0; total_keys < max_total_keys; i++) { + sessions.push_back(std::unique_ptr(new Session())); + licenses.push_back(std::unique_ptr( + new LicenseRoundTrip(sessions[i].get()))); + const size_t num_keys = + std::min(max_total_keys - total_keys, num_keys_per_session); + licenses[i]->set_num_keys(static_cast(num_keys)); + total_keys += num_keys; + ASSERT_NO_FATAL_FAILURE(sessions[i]->open()); + ASSERT_NO_FATAL_FAILURE(util->InstallTestDrmKey(sessions[i].get())); + ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest()); + } + for (size_t i = 0; i < licenses.size(); i++) { + ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse()); + } + constexpr bool kSelectKeyFirst = true; + for (size_t i = 0; i < licenses.size(); i++) { + for (size_t key_index = 0; key_index < licenses[i]->num_keys(); + key_index++) { + ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR( + kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); + } + } + // Second call to decrypt for each session. + for (size_t i = 0; i < licenses.size(); i++) { + for (size_t key_index = 0; key_index < licenses[i]->num_keys(); + key_index++) { + ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR( + kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); + } + } +} + +TEST_F(OEMCryptoSessionTestKeyboxTest, TestKeyboxIsValid) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryPrepareLicenseRequestForHugeRequestMessageLength) { + TestPrepareLicenseRequestForHugeBufferLengths( + [](size_t message_size, LicenseRoundTrip* license_messages) { + license_messages->set_message_size(message_size); + }, + kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryPrepareLicenseRequestForHugeCoreMessageLength) { + TestPrepareLicenseRequestForHugeBufferLengths( + [](size_t core_message_size, LicenseRoundTrip* license_messages) { + license_messages->set_core_message_size(core_message_size); + }, + kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryPrepareLicenseRequestForHugeSignatureLength) { + // There is a limit of signature length that gets validated. Hence not + // checking status as we would like to test it for all possible signature + // lengths. + TestPrepareLicenseRequestForHugeBufferLengths( + [](size_t length, LicenseRoundTrip* license_messages) { + license_messages->set_request_signature_size(length); + }, + !kCheckStatus); +} + +// Verify that a license may be signed. +TEST_P(OEMCryptoLicenseTest, SignLicenseRequest) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); +} + +// Verify that a large license request may be signed. +TEST_P(OEMCryptoLicenseTest, SignLargeLicenseRequest) { + const size_t max_size = GetResourceValue(kLargeMessageSize); + license_messages_.set_message_size(max_size); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); +} + +// Verify that a license may be loaded without a nonce. +TEST_P(OEMCryptoLicenseTest, LoadKeyNoNonce) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(0); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); +} + +// Verify that a preloaded license may be loaded without first signing the +// request. This test is important for the preloaded licenses used by ATSC and +// CAS. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithNoRequest) { + if (license_api_version_ > global_features.api_version) { + // We should not attempt to preload a license with an API higher than that + // of OEMCrypto. + license_api_version_ = global_features.api_version; + license_messages_.set_api_version(license_api_version_); + } + license_messages_.set_control(0); + // Notice that we do not call SignAndVerifyRequest -- we do not need a request + // in order to generate a response for a preloaded license. + // The test code uses the core request to create the core response. + license_messages_.core_request().api_major_version = + global_features.api_version; + license_messages_.core_request().api_minor_version = 0; + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + + // Load license in a different session, which did not create the request. + Session session2; + ASSERT_NO_FATAL_FAILURE(session2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session2)); + ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse(&session2)); + ASSERT_NO_FATAL_FAILURE(session2.TestDecryptCTR(true, OEMCrypto_SUCCESS)); +} + +// Verify that a license may be reloaded without a nonce, but with a nonzero +// rental duration. In order to start the rental clock, we sign a placeholder +// license instead. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithNoRequestRentalDuration) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(0); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // It is not recommended for a license without a nonce to have a nonzero + // rental duration. But there are content providers that have licenses with + // this policy. + license_messages_.core_response().timer_limits.rental_duration_seconds = + kDuration; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + + // Load license in a different session, which did not create the request. + Session session2; + ASSERT_NO_FATAL_FAILURE(session2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session2)); + // However, in order to start the rental clock, we have to sign something. So + // we will sign a placeholder license request. + LicenseRoundTrip dummy_license(&session2); + ASSERT_NO_FATAL_FAILURE(dummy_license.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse(&session2)); + ASSERT_NO_FATAL_FAILURE(session2.TestDecryptCTR(true, OEMCrypto_SUCCESS)); +} + +// Verify that a license may be loaded with a nonce. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithNonce) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); +} + +// Verify that a second license may not be loaded in a session. +TEST_P(OEMCryptoLicenseTest, LoadKeyNoNonceTwiceAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(0); + license_messages_.skip_nonce_check(); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + // A second load, should NOT succeed. + ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); +} + +// Verify that a second license may not be loaded in a session. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithNonceTwiceAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + // A second load, should NOT succeed. + ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); +} + +// This tests load license with an 8k license response. +TEST_P(OEMCryptoLicenseTest, LoadKeyLargeBuffer) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + const size_t max_size = GetResourceValue(kLargeMessageSize); + license_messages_.set_message_size(max_size); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +//---------------------------------------------------------------------------// +//---------------------------------------------------------------------------// +// Each of the following LoadKeyWithBadRange_* tests is similar. They verify +// that OEMCrypto_LoadLicense checks the range of all the pointers. It should +// reject a message if the pointer does not point into the message buffer. +//---------------------------------------------------------------------------// +//---------------------------------------------------------------------------// +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_enc_mac_keys) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().enc_mac_keys.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_enc_mac_keys_iv) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().enc_mac_keys_iv.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_id) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().key_array[0].key_id.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_data) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().key_array[1].key_data.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_data_iv) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().key_array[1].key_data_iv.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_control) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().key_array[2].key_control.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_control_iv) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().key_array[2].key_control_iv.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_pst) { + license_messages_.set_control(wvoec::kControlNonceOrEntry); + license_messages_.set_pst("my_pst"); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // See the comment in LicenseRoundTrip::LoadResponse for why we increment by + // the message size. + license_messages_.core_response().pst.offset += + sizeof(license_messages_.response_data()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + // If we have a pst, then we need a usage entry. + ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} +//---------------------------------------------------------------------------// +//---------------------------------------------------------------------------// + +// Test that LoadKeys fails when a key is loaded with no key control block. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithNullKeyControl) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_response().key_array[2].key_control.offset = 0; + license_messages_.core_response().key_array[2].key_control.length = 0; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +// Verify that LoadKeys fails when a key's nonce is wrong. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadNonce) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + for (unsigned int i = 0; i < license_messages_.num_keys(); i++) + license_messages_.response_data().keys[i].control.nonce ^= 42; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// Verify that LoadKeys fails when the core message's nonce is wrong. +TEST_F(OEMCryptoLicenseTestAPI16, LoadKeyWithBadNonce2) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_request().nonce ^= 42; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// Verify that LoadKeys fails when the core message's session is wrong. +TEST_F(OEMCryptoLicenseTestAPI16, LoadKeyWithBadNonce3) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_request().session_id++; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// Verify that LoadKeys fails when an attempt is made to use a nonce twice. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithRepeatNonce) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + const uint32_t nonce = session_.nonce(); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + // This is the first attempt. It should succeed. + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + // Now, open a new session and try to load a license with the same nonce. + session_.close(); + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session_)); + license_messages_.skip_nonce_check(); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + // Repeat the nonce. + license_messages_.core_request().nonce = nonce; + for (unsigned int i = 0; i < license_messages_.num_keys(); i++) + license_messages_.response_data().keys[i].control.nonce = htonl(nonce); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// This tests that a nonce cannot be used in new session. This is similar to +// the previous test, but does not use the nonce in the first session. The nonce +// should be tied to a session, so generating a nonce in the first session and +// then using it in the second session should fail. +TEST_P(OEMCryptoLicenseTest, LoadKeyNonceReopenSession) { + ASSERT_NO_FATAL_FAILURE(session_.GenerateNonce()); + uint32_t nonce = session_.nonce(); + // Do not use the nonce now. Close session and use it after re-opening. + ASSERT_NO_FATAL_FAILURE(session_.close()); + + // Actually, this isn't the same session. OEMCrypto opens a new session, but + // we are guarding against the possibility that it re-uses the session data + // and might not clear out the nonce correctly. + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session_)); + license_messages_.skip_nonce_check(); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_request().nonce = nonce; + for (unsigned int i = 0; i < license_messages_.num_keys(); i++) + license_messages_.response_data().keys[i].control.nonce = htonl(nonce); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// This tests that a nonce cannot be used in wrong session. This is similar to +// the previous test, except we do not close session 1 before we open session 2. +TEST_P(OEMCryptoLicenseTest, LoadKeyNonceWrongSession) { + // First, open a session and generate a nonce. We don't use the nonce in this + // session. + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s2)); + ASSERT_NO_FATAL_FAILURE(s2.GenerateNonce()); + uint32_t nonce = s2.nonce(); + + // Do not use the nonce. Also, leave the session open. We want to make sure + // that session_ and s2 do NOT share a nonce. This is different from + // the LoadKeyNonceReopenSession in that we do not close s1. + + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.core_request().nonce = nonce; + for (unsigned int i = 0; i < license_messages_.num_keys(); i++) + license_messages_.response_data().keys[i].control.nonce = htonl(nonce); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); +} + +// LoadKeys should fail if the key control block as a bad verification string. +TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadVerification) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + license_messages_.response_data().keys[1].control.verification[2] = 'Z'; + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +// This test verifies that LoadKeys still works when the message is not aligned +// in memory on a word (2 or 4 byte) boundary. +TEST_P(OEMCryptoLicenseTest, LoadKeyUnalignedMessageAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + + std::vector buffer(1, '0'); // A string of 1 byte long. + size_t offset = buffer.size(); + ASSERT_EQ(1u, offset); + // We assume that vectors are allocated on as a small chunk of data that is + // aligned on a word boundary. I.e. we assume buffer is word aligned. Next, + // we append the message to buffer after the single padding byte. + buffer.insert(buffer.end(), + license_messages_.encrypted_response_buffer().begin(), + license_messages_.encrypted_response_buffer().end()); + // Thus, buffer[offset] is NOT word aligned. + const uint8_t* unaligned_message = &buffer[offset]; + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadLicense( + session_.session_id(), unaligned_message, + license_messages_.encrypted_response_buffer().size(), + license_messages_.serialized_core_message().size(), + license_messages_.response_signature().data(), + license_messages_.response_signature().size())); +} + +// Verifies that a session can't reload a license without being closed and +// reopened. +TEST_P(OEMCryptoLicenseTest, LoadLicenseAgainFailureAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); +} + +TEST_P(OEMCryptoLicenseTest, LoadKeysBadSignatureAPI16) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + license_messages_.response_signature()[0] ^= 42; + ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, + license_messages_.LoadResponse()); +} +// LoadKeys should fail if we try to load keys with no keys. +TEST_P(OEMCryptoLicenseTest, LoadKeyNoKeys) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(0); + license_messages_.set_num_keys(0); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} + +// Like the previous test, except we ask for a nonce first. +TEST_P(OEMCryptoLicenseTest, LoadKeyNoKeyWithNonce) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_num_keys(0); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +} +/// @} + +/// @addtogroup security +/// @{ + +// Following two tests will test huge values for num bytes clear, num bytes +// encrypted, input data length and clear address, clear address_length. +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForHugeNumBytesClearAndBuffers) { + TestDecryptCENCForHugeBufferLengths( + [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description->subsamples); + sub_samples[0].num_bytes_clear = + sub_samples[0].num_bytes_clear + message_size; + }, + !kCheckStatus); +} + +TEST_P(OEMCryptoLicenseTest, + DecryptCENCForNumBytesClearPlusEncryptedOverflowsSize) { + LoadLicense(); + vector key_handle; + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + + size_t input_buffer_size = 1; + vector in_buffer(input_buffer_size); + vector out_buffer(in_buffer.size()); + + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description.subsamples); + // If Decrypt cenc API does not check for overflow on clear + encrypted + // addition operation. This will result in 1 which will match with input data + // length, which causes validation to pass. + sub_samples[0].num_bytes_clear = 2; + sub_samples[0].num_bytes_encrypted = ~0; + + // Create the pattern description (always 0,0 for CTR) + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + // Try to decrypt the data + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern)); +} + +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForHugeNumBytesEncryptedAndBuffers) { + TestDecryptCENCForHugeBufferLengths( + [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description->subsamples); + sub_samples[0].num_bytes_encrypted = + sub_samples[0].num_bytes_encrypted + message_size; + }, + !kCheckStatus); +} + +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForHugeSecureHandleLength) { + TestDecryptCENCForHugeBufferLengths( + [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description->subsamples); + // TestDecryptCENCForHugeBufferLengths alloctes huge secure handle + // buffer. + sample_description->buffers.output_descriptor.type = + OEMCrypto_BufferType_Secure; + sub_samples[0].num_bytes_clear = + sub_samples[0].num_bytes_clear + message_size; + }, + !kCheckStatus); +} + +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesClear) { + TestDecryptCENCForOutOfRangeOffsetsAndLengths( + [](OEMCrypto_SampleDescription* sample_description) { + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description->subsamples); + sub_samples[0].num_bytes_clear = sub_samples[0].num_bytes_clear + 1; + }, + !kDecryptCENCSecureBuffer); +} + +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesEncryptedAPI16) { + TestDecryptCENCForOutOfRangeOffsetsAndLengths( + [](OEMCrypto_SampleDescription* sample_description) { + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description->subsamples); + sub_samples[0].num_bytes_encrypted = + sub_samples[0].num_bytes_encrypted + 1; + }, + !kDecryptCENCSecureBuffer); +} + +TEST_P(OEMCryptoLicenseTest, + OEMCryptoMemoryDecryptCENCForOutOfRangeSecureBufferOffset) { + TestDecryptCENCForOutOfRangeOffsetsAndLengths( + [](OEMCrypto_SampleDescription* sample_description) { + sample_description->buffers.output_descriptor.type = + OEMCrypto_BufferType_Secure; + sample_description->buffers.output_descriptor.buffer.secure.offset = + sample_description->buffers.output_descriptor.buffer.secure + .secure_buffer_length + + 1; + }, + kDecryptCENCSecureBuffer); +} + +// After loading keys, we should be able to query the key control block. If we +// attempt to query a key that has not been loaded, the error should be +// NO_CONTENT_KEY. +TEST_P(OEMCryptoLicenseTest, QueryKeyControl) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + // Note: successful cases are tested in VerifyTestKeys. + KeyControlBlock block; + size_t size = sizeof(block) - 1; + OEMCryptoResult sts = OEMCrypto_QueryKeyControl( + session_.session_id(), license_messages_.response_data().keys[0].key_id, + license_messages_.response_data().keys[0].key_id_length, + reinterpret_cast(&block), &size); + if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { + return; + } + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + const char* key_id = "no_key"; + size = sizeof(block); + ASSERT_EQ(OEMCrypto_ERROR_NO_CONTENT_KEY, + OEMCrypto_QueryKeyControl( + session_.session_id(), reinterpret_cast(key_id), + strlen(key_id), reinterpret_cast(&block), &size)); +} + +// This case tests against the issue where certain 16.4.x SDK versions return a +// clear key control block (KCB) in the license response. An OEMCrypto v17.1+ +// implementation should be able to handle the clear KCB in the 16.4.x response +// and load the license correctly. +TEST_F(OEMCryptoSessionTests, ClearKcbAPI17) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + // Set odk version in the license response to be 16.4 + oemcrypto_core_message::features::CoreMessageFeatures features = {}; + features.maximum_major_version = 16; + features.maximum_minor_version = 4; + constexpr bool kForceClearKcb = true; + ASSERT_NO_FATAL_FAILURE( + license_messages.EncryptAndSignResponseWithCoreMessageFeatures( + features, kForceClearKcb)); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + + KeyControlBlock block; + size_t size = sizeof(block); + OEMCryptoResult sts = OEMCrypto_QueryKeyControl( + s.session_id(), license_messages.response_data().keys[0].key_id, + license_messages.response_data().keys[0].key_id_length, + reinterpret_cast(&block), &size); + if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { + return; + } + ASSERT_EQ(OEMCrypto_SUCCESS, sts); +} + +// If the device says it supports anti-rollback in the hardware, then it should +// accept a key control block with the anti-rollback hardware bit set. +// Otherwise, it should reject that key control block. +TEST_P(OEMCryptoLicenseTest, AntiRollbackHardwareRequired) { + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + license_messages_.set_control(wvoec::kControlRequireAntiRollbackHardware); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + OEMCryptoResult sts = license_messages_.LoadResponse(); + if (OEMCrypto_IsAntiRollbackHwPresent()) { + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + } else { + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, sts); + } +} + +// This test verifies that OEMCrypto can load the number of keys required for +// the reported resource level. +TEST_P(OEMCryptoLicenseTest, MinimumKeys) { + const size_t num_keys = GetResourceValue(kMaxKeysPerSession); + ASSERT_LE(num_keys, kMaxNumKeys) << "Test constants need updating."; + license_messages_.set_num_keys(static_cast(num_keys)); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + + constexpr bool kSelectKeyFirst = true; + for (size_t key_index = 0; key_index < num_keys; key_index++) { + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); + } +} + +// This test verifies that OEMCrypto can load the total number of keys required +// for the reported resource level. This maximizes keys per session. +TEST_P(OEMCryptoLicenseTest, MaxTotalKeysPerSession) { + const size_t max_num_keys = GetResourceValue(kMaxKeysPerSession); + TestMaxKeys(this, max_num_keys); +} + +// This test verifies that OEMCrypto can load the total number of keys required +// for the reported resource level. This maximizes number of sessions. +TEST_P(OEMCryptoLicenseTest, MaxTotalKeysManySessions) { + const size_t max_total_keys = GetResourceValue(kMaxTotalKeys); + const size_t max_sessions = GetResourceValue(kMaxConcurrentSession); + const size_t max_num_keys = max_total_keys / max_sessions + 1; + TestMaxKeys(this, max_num_keys); +} + +// This test verifies that the minimum patch level can be required. The device +// should accept a key control block with the current patch level, and it should +// reject any key control blocks with a future patch level. +TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { + uint8_t patch_level = OEMCrypto_Security_Patch_Level(); + printf(" Current Patch Level: %u.\n", patch_level); + { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_control(patch_level + << wvoec::kControlSecurityPatchLevelShift); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + EXPECT_EQ(global_features.api_version, license_messages.api_version()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + } + // Reject any future patch levels. + if (patch_level < 0x3F) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_control((patch_level + 1) + << wvoec::kControlSecurityPatchLevelShift); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, license_messages.LoadResponse()); + } + // Accept an old patch level. + if (patch_level > 0) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_control((patch_level - 1) + << wvoec::kControlSecurityPatchLevelShift); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + } +} + +// +// Load, Refresh Keys Test +// + +// Refresh keys should work if the license uses a nonce. +TEST_P(OEMCryptoRefreshTest, RefreshWithNonce) { + LoadLicense(); + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); +} + +// Refresh keys should work if the license does not use a nonce. +TEST_P(OEMCryptoRefreshTest, RefreshNoNonce) { + license_messages_.set_control(0); + LoadLicense(); + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); +} + +// Refresh keys should NOT work if a license has not been loaded. +TEST_P(OEMCryptoRefreshTestAPI16, RefreshNoLicense) { + Session s; + s.open(); + constexpr size_t message_size = kMaxCoreMessage + 42; + std::vector data(message_size); + for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF; + size_t gen_signature_length = 0; + size_t core_message_length = 0; + OEMCryptoResult sts = OEMCrypto_PrepAndSignRenewalRequest( + s.session_id(), data.data(), data.size(), &core_message_length, nullptr, + &gen_signature_length); + ASSERT_LT(core_message_length, message_size); + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + vector gen_signature(gen_signature_length); + sts = OEMCrypto_PrepAndSignRenewalRequest( + s.session_id(), data.data(), data.size(), &core_message_length, + gen_signature.data(), &gen_signature_length); + } + ASSERT_NE(OEMCrypto_SUCCESS, sts); +} + +// Refresh keys should fail if the nonce is not in the session. +TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadNonce) { + LoadLicense(); + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + renewal_messages.core_request().nonce ^= 42; + LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE); +} + +// Refresh keys should fail if the session_id does not match the license. +TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadSessionID) { + LoadLicense(); + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + renewal_messages.core_request().session_id += 1; + LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE); +} + +// Refresh keys should handle the maximum message size. +TEST_P(OEMCryptoRefreshTest, RefreshLargeBuffer) { + LoadLicense(); + RenewalRoundTrip renewal_messages(&license_messages_); + const size_t max_size = GetResourceValue(kLargeMessageSize); + renewal_messages.set_message_size(max_size); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); +} + +// This situation would occur if an app only uses one key in the license. When +// that happens, SelectKey would be called before the first decrypt, and then +// would not need to be called again, even if the license is refreshed. +TEST_P(OEMCryptoRefreshTest, RefreshWithNoSelectKey) { + LoadLicense(); + + // Call select key before the refresh. No calls below to TestDecryptCTR with + // select key set to true. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true)); + + // This should still be valid key, even if the refresh failed, because this + // is before the original license duration. + wvutil::TestSleep::Sleep(kShortSleep); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false)); + + // This should be after duration of the original license, but before the + // expiration of the refresh message. This should fail until we have loaded + // the renewal. + wvutil::TestSleep::Sleep(kShortSleep + kLongSleep); + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); + + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); + + // After we've loaded the renewal, decrypt should succeed again. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false)); +} + +// Test that playback clock is correctly started and that the license can be +// renewed. +TEST_P(OEMCryptoRefreshTest, RenewLicenseLoadSuccess) { + license_messages_.core_response().renewal_delay_base = OEMCrypto_License_Load; + timer_limits_.rental_duration_seconds = kDuration; // 2 seconds. + timer_limits_.initial_renewal_duration_seconds = kLongDuration; // 5 seconds. + // First version to support Renew on Load. + constexpr uint32_t kFeatureVersion = 18; + + // Loading the license should start the playback clock. + LoadLicense(); + // Sleep until just after rental window is over. + wvutil::TestSleep::Sleep(kDuration + kShortSleep); + if (license_api_version_ < kFeatureVersion || + global_features.api_version < kFeatureVersion) { + // If the feature is not supported, then we expect failure because the + // playback clock was not started and we are outside the rental window. + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(true, OEMCrypto_ERROR_KEY_EXPIRED)); + return; + } else { + // If the feature is supported, we expect decrypt to work because we are + // still within the initial renewal window, and the playback clock should + // have started. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); + } + // This is after the initial renewal duration, so we expect failure before + // loading the renewal. + wvutil::TestSleep::Sleep(kShortSleep + kLongSleep); + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); + + RenewalRoundTrip renewal_messages(&license_messages_); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); + + // After we've loaded the renewal, decrypt should succeed again. + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false)); +} + +TEST_P(OEMCryptoRefreshTest, RenewLicenseLoadOutsideRentalDuration) { + license_messages_.core_response().renewal_delay_base = OEMCrypto_License_Load; + timer_limits_.rental_duration_seconds = kDuration; // 2 seconds. + timer_limits_.initial_renewal_duration_seconds = kLongDuration; // 5 seconds. + + // Sleep until just after rental window is over. + wvutil::TestSleep::Sleep(kDuration + kShortSleep); + // Loading the license should start the playback clock. + LoadLicense(); + // If the license is loaded after the rental duration window, we expect + // failure. + ASSERT_NO_FATAL_FAILURE( + session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoRefreshTest, + Range(kCurrentAPI - 1, kCurrentAPI + 1)); + +// These tests only work when the license has a core message. +INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoRefreshTestAPI16, + Range(kCoreMessagesAPI, kCurrentAPI + 1)); + +/// @} +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_license_test.h b/oemcrypto/test/oemcrypto_license_test.h new file mode 100644 index 00000000..a2860503 --- /dev/null +++ b/oemcrypto/test/oemcrypto_license_test.h @@ -0,0 +1,410 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_LICENSE_TEST_ +#define CDM_OEMCRYPTO_LICENSE_TEST_ + +#include + +#include "OEMCryptoCENC.h" +#include "clock.h" +#include "log.h" +#include "oemcrypto_basic_test.h" +#include "oemcrypto_corpus_generator_helper.h" +#include "oemcrypto_resource_test.h" +#include "wvcrc32.h" + +namespace wvoec { + +using ::testing::WithParamInterface; + +// Used for testing oemcrypto APIs with huge buffers. +typedef const std::function oemcrypto_function; +void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, + size_t start_buffer_length, + size_t end_buffer_length, bool check_status); +void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, bool check_status); + +void TestMaxKeys(SessionUtil* util, size_t num_keys_per_session); + +class OEMCryptoSessionTests : public OEMCryptoClientTest { + public: + vector encrypted_usage_header_; + + protected: + OEMCryptoSessionTests() {} + + void SetUp() override { + OEMCryptoClientTest::SetUp(); + EnsureTestROT(); + if (global_features.usage_table) { + CreateUsageTableHeader(); + } + } + + void CreateUsageTableHeader(bool expect_success = true) { + size_t header_buffer_length = 0; + OEMCryptoResult sts = + OEMCrypto_CreateUsageTableHeader(nullptr, &header_buffer_length); + if (expect_success) { + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + } else { + ASSERT_NE(OEMCrypto_SUCCESS, sts); + if (sts != OEMCrypto_ERROR_SHORT_BUFFER) return; + } + encrypted_usage_header_.resize(header_buffer_length); + sts = OEMCrypto_CreateUsageTableHeader(encrypted_usage_header_.data(), + &header_buffer_length); + if (expect_success) { + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + encrypted_usage_header_.resize(header_buffer_length); + } else { + ASSERT_NE(OEMCrypto_SUCCESS, sts); + } + } + + void TestPrepareLicenseRequestForHugeBufferLengths( + const std::function f, + bool check_status) { + auto oemcrypto_function = [&](size_t message_length) { + Session s; + s.open(); + InstallTestDrmKey(&s); + LicenseRoundTrip license_messages(&s); + f(message_length, &license_messages); + OEMCryptoResult result = + license_messages.SignAndCreateRequestWithCustomBufferLengths(); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); + } + + OEMCryptoResult LoadLicense(Session& s, LicenseRoundTrip& license_messages) { + InstallTestDrmKey(&s); + license_messages.SignAndVerifyRequest(); + license_messages.CreateDefaultResponse(); + license_messages.EncryptAndSignResponse(); + return license_messages.LoadResponse(); + } +}; + +class OEMCryptoSessionTestKeyboxTest : public OEMCryptoSessionTests {}; + +// This class is for testing a single license with the default API version +// of 16. +class OEMCryptoLicenseTestAPI16 : public OEMCryptoSessionTests { + public: + OEMCryptoLicenseTestAPI16() + : license_api_version_(kCurrentAPI), license_messages_(&session_) {} + + void SetUp() override { + OEMCryptoSessionTests::SetUp(); + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session_)); + } + + void TearDown() override { + ASSERT_NO_FATAL_FAILURE(session_.close()); + OEMCryptoSessionTests::TearDown(); + } + + protected: + Session session_; + uint32_t license_api_version_; + LicenseRoundTrip license_messages_; +}; + +// This class is used to test a license that is from a server with the specified +// version parameter. Up to two versions old. +class OEMCryptoLicenseTest : public OEMCryptoLicenseTestAPI16, + public WithParamInterface { + protected: + void SetUp() override { + // The only difference between this class and its parent is that we use a + // different license api: + license_api_version_ = GetParam(); + license_messages_.set_api_version(license_api_version_); + OEMCryptoLicenseTestAPI16::SetUp(); + } + + void LoadLicense() { + license_messages_.SignAndVerifyRequest(); + license_messages_.CreateDefaultResponse(); + license_messages_.EncryptAndSignResponse(); + license_messages_.LoadResponse(); + } + + void TestDecryptCENCForHugeBufferLengths( + const std::function f, + bool check_status) { + LoadLicense(); + auto oemcrypto_function = [&](size_t message_length) { + vector key_handle; + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + + size_t input_buffer_size = 1; + vector in_buffer(input_buffer_size + message_length); + vector out_buffer(in_buffer.size()); + + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + GenerateSimpleSampleDescription( + in_buffer, out_buffer, &sample_description, &subsample_description); + + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description.subsamples); + // Actual tests modifies either of these fields to match clear + encrypted + // = in_buffer.size(). + sub_samples[0].num_bytes_clear = 0; + sub_samples[0].num_bytes_encrypted = input_buffer_size; + + // Create the pattern description (always 0,0 for CTR) + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + int secure_fd = 0; + f(message_length, &sample_description); + if (sample_description.buffers.output_descriptor.type == + OEMCrypto_BufferType_Secure) { + OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( + session_.session_id(), in_buffer.size(), + &sample_description.buffers.output_descriptor, &secure_fd); + if (sts != OEMCrypto_SUCCESS) { + LOGI("Secure buffers are not supported."); + return sts; + } + } + // Try to decrypt the data + OEMCryptoResult result = + OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), + &sample_description, 1, &pattern); + if (sample_description.buffers.output_descriptor.type == + OEMCrypto_BufferType_Secure) { + OEMCrypto_FreeSecureBuffer( + session_.session_id(), + &sample_description.buffers.output_descriptor, secure_fd); + } + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); + } + + void TestDecryptCENCForOutOfRangeOffsetsAndLengths( + const std::function f, + bool update_secure_buffer) { + LoadLicense(); + vector key_handle; + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + + vector in_buffer(256); + vector out_buffer(in_buffer.size()); + + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + // Create the pattern description (always 0,0 for CTR) + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + int secure_fd = 0; + if (update_secure_buffer) { + OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( + session_.session_id(), in_buffer.size(), + &sample_description.buffers.output_descriptor, &secure_fd); + if (sts != OEMCrypto_SUCCESS) { + LOGI("Secure buffers are not supported."); + return; + } + } + f(&sample_description); + // Try to decrypt the data + OEMCryptoResult result = OEMCrypto_DecryptCENC( + key_handle.data(), key_handle.size(), &sample_description, 1, &pattern); + if (update_secure_buffer) { + OEMCrypto_FreeSecureBuffer(session_.session_id(), + &sample_description.buffers.output_descriptor, + secure_fd); + } + ASSERT_NE(OEMCrypto_SUCCESS, result); + } +}; + +// Test usage table functionality. +class LicenseWithUsageEntry { + public: + LicenseWithUsageEntry(const std::string& pst = "my_pst") + : session_(), + license_messages_(&session_), + generic_crypto_(false), + time_license_received_(0), + time_first_decrypt_(0), + time_last_decrypt_(0), + active_(true) { + license_messages_.set_pst(pst); + } + + void MakeAndLoadOnline(OEMCryptoSessionTests* test) { + MakeAndLoad(test, + wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired); + } + + // If status in not a nullptr, then creating a new entry is allowed to fail, + // and its error code is stored in status. + void MakeOfflineAndClose(OEMCryptoSessionTests* test, + OEMCryptoResult* status = nullptr) { + MakeAndLoad(test, wvoec::kControlNonceOrEntry, status); + if (status != nullptr && *status != OEMCrypto_SUCCESS) { + ASSERT_NO_FATAL_FAILURE(session_.close()); + return; + } + ASSERT_NO_FATAL_FAILURE( + session_.UpdateUsageEntry(&(test->encrypted_usage_header_))); + ASSERT_NO_FATAL_FAILURE(GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(session_.close()); + } + + // If status in not a nullptr, then creating a new entry is allowed to fail, + // and its error code is stored in status. + void MakeAndLoad(SessionUtil* util, uint32_t control, + OEMCryptoResult* status = nullptr) { + license_messages_.set_control(control); + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(util->InstallTestDrmKey(&session_)); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + if (generic_crypto_) { + ASSERT_NO_FATAL_FAILURE( + license_messages_.CreateResponseWithGenericCryptoKeys()); + } else { + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + } + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry(status)); + if (status != nullptr && *status != OEMCrypto_SUCCESS) return; + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + time_license_received_ = wvutil::Clock().GetCurrentTime(); + } + + void OpenAndReload(SessionUtil* util) { + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(session_.ReloadUsageEntry()); + ASSERT_NO_FATAL_FAILURE(util->InstallTestDrmKey(&session_)); + ASSERT_NO_FATAL_FAILURE(session_.GenerateDerivedKeysFromSessionKey()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + } + + // Test decrypt, and update the decrypt times for the pst report. + void TestDecryptCTR(bool select_key_first = true, + OEMCryptoResult expected_result = OEMCrypto_SUCCESS) { + session_.TestDecryptCTR(select_key_first, expected_result); + time_last_decrypt_ = wvutil::Clock().GetCurrentTime(); + if (time_first_decrypt_ == 0) time_first_decrypt_ = time_last_decrypt_; + } + + void DeactivateUsageEntry() { + active_ = false; + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_deactivate_usage_entry_fuzz_seed_corpus"); + AppendToFile(file_name, pst().c_str(), pst().length()); + } + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_DeactivateUsageEntry( + session_.session_id(), + reinterpret_cast(pst().c_str()), pst().length())); + } + + void GenerateVerifyReport(OEMCrypto_Usage_Entry_Status status) { + ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst())); + Test_PST_Report expected(pst(), status); + ASSERT_NO_FATAL_FAILURE( + session_.VerifyReport(expected, time_license_received_, + time_first_decrypt_, time_last_decrypt_)); + // The PST report was signed above. Below we verify that the entire message + // that is sent to the server will be signed by the right mac keys. + RenewalRoundTrip renewal_messages(&license_messages_); + renewal_messages.set_is_release(!active_); + ASSERT_NO_FATAL_FAILURE(renewal_messages.SignAndVerifyRequest()); + } + + void ReloadUsageEntry() { + session_.ReloadUsageEntry(); + session_.set_mac_keys(license_messages_.response_data().mac_keys); + } + + const std::string& pst() const { return license_messages_.pst(); } + void set_pst(const std::string& pst) { license_messages_.set_pst(pst); } + LicenseRoundTrip& license_messages() { return license_messages_; } + Session& session() { return session_; } + void set_generic_crypto(bool generic_crypto) { + generic_crypto_ = generic_crypto; + } + + private: + Session session_; + LicenseRoundTrip license_messages_; + bool generic_crypto_; + int64_t time_license_received_; + int64_t time_first_decrypt_; + int64_t time_last_decrypt_; + bool active_; +}; + +class OEMCryptoRefreshTest : public OEMCryptoLicenseTest { + protected: + void SetUp() override { + OEMCryptoLicenseTest::SetUp(); + // These values allow us to run a few simple duration tests or just start + // playback right away. All times are in seconds since the license was + // signed. + // Soft expiry false means timers are strictly enforce. + timer_limits_.soft_enforce_rental_duration = true; + timer_limits_.soft_enforce_playback_duration = false; + // Playback may begin immediately. + timer_limits_.earliest_playback_start_seconds = 0; + // First playback may be within the first two seconds. + timer_limits_.rental_duration_seconds = kDuration; + // Once started, playback may last two seconds without a renewal. + timer_limits_.initial_renewal_duration_seconds = kDuration; + // Total playback is not limited. + timer_limits_.total_playback_duration_seconds = 0; + } + + void LoadLicense() { + license_messages_.core_response().timer_limits = timer_limits_; + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + } + + void MakeRenewalRequest(RenewalRoundTrip* renewal_messages) { + ASSERT_NO_FATAL_FAILURE(renewal_messages->SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(renewal_messages->CreateDefaultResponse()); + } + + void LoadRenewal(RenewalRoundTrip* renewal_messages, + OEMCryptoResult expected_result) { + ASSERT_NO_FATAL_FAILURE(renewal_messages->EncryptAndSignResponse()); + ASSERT_EQ(expected_result, renewal_messages->LoadResponse()); + } + + ODK_TimerLimits timer_limits_; +}; + +// This class is for the refresh tests that should only be run on licenses with +// a core message. +class OEMCryptoRefreshTestAPI16 : public OEMCryptoRefreshTest {}; + +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_LICENSE_TEST_ \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_provisioning_test.cpp b/oemcrypto/test/oemcrypto_provisioning_test.cpp new file mode 100644 index 00000000..5504e768 --- /dev/null +++ b/oemcrypto/test/oemcrypto_provisioning_test.cpp @@ -0,0 +1,1228 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_provisioning_test.h" + +#include "log.h" +#include "platform.h" +#include "test_sleep.h" + +namespace wvoec { + +// This test is used to print the device ID to stdout. +TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) { + OEMCryptoResult sts; + uint8_t dev_id[128] = {0}; + size_t dev_id_len = 128; + sts = OEMCrypto_GetDeviceID(dev_id, &dev_id_len); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + cout << " NormalGetDeviceId: dev_id = " + << MaybeHex(dev_id, dev_id_len) << " len = " << dev_id_len << endl; +} + +TEST_F(OEMCryptoKeyboxTest, GetDeviceIdShortBuffer) { + OEMCryptoResult sts; + uint8_t dev_id[128]; + for (int i = 0; i < 128; ++i) { + dev_id[i] = 0x55; + } + dev_id[127] = '\0'; + size_t dev_id_len = 0; + sts = OEMCrypto_GetDeviceID(dev_id, &dev_id_len); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + // On short buffer error, function should return minimum buffer length + ASSERT_GT(dev_id_len, 0u); + // Should also return short buffer if passed a zero length and a null buffer. + dev_id_len = 0; + sts = OEMCrypto_GetDeviceID(nullptr, &dev_id_len); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + // On short buffer error, function should return minimum buffer length + ASSERT_GT(dev_id_len, 0u); +} + +TEST_F(OEMCryptoKeyboxTest, NormalGetKeyData) { + OEMCryptoResult sts; + uint8_t key_data[256]; + size_t key_data_len = sizeof(key_data); + sts = OEMCrypto_GetKeyData(key_data, &key_data_len); + + uint32_t* data = reinterpret_cast(key_data); + printf(" NormalGetKeyData: system_id = %u = 0x%04X, version=%u\n", + htonl(data[1]), htonl(data[1]), htonl(data[0])); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); +} + +TEST_F(OEMCryptoKeyboxTest, GetKeyDataNullPointer) { + OEMCryptoResult sts; + uint8_t key_data[256]; + sts = OEMCrypto_GetKeyData(key_data, nullptr); + ASSERT_NE(OEMCrypto_SUCCESS, sts); +} + +// This test makes sure the installed keybox is valid. It doesn't really check +// that it is a production keybox. That must be done by an integration test. +TEST_F(OEMCryptoKeyboxTest, ProductionKeyboxValid) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); +} + +// This tests GenerateDerivedKeys with an 8k context. +TEST_F(OEMCryptoKeyboxTest, GenerateDerivedKeysFromKeyboxLargeBuffer) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + const size_t max_size = GetResourceValue(kLargeMessageSize); + vector mac_context(max_size); + vector enc_context(max_size); + // Stripe the data so the two vectors are not identical, and not all zeroes. + for (size_t i = 0; i < max_size; i++) { + mac_context[i] = i % 0x100; + enc_context[i] = (3 * i) % 0x100; + } + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_GenerateDerivedKeys( + s.session_id(), mac_context.data(), mac_context.size(), + enc_context.data(), enc_context.size())); +} + +// This verifies that the device really does claim to have a certificate. +// It should be filtered out for devices that have a keybox. +TEST_F(OEMCryptoProv30Test, DeviceClaimsOEMCertificate) { + ASSERT_EQ(OEMCrypto_OEMCertificate, OEMCrypto_GetProvisioningMethod()); +} + +TEST_F(OEMCryptoProv30Test, GetDeviceId) { + OEMCryptoResult sts; + std::vector dev_id(128, 0); + size_t dev_id_len = dev_id.size(); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + ASSERT_GT(dev_id_len, 0u); + dev_id.resize(dev_id_len); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + } + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + dev_id.resize(dev_id_len); + cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id) + << " len = " << dev_id_len << endl; +} + +// The OEM certificate must be valid. +TEST_F(OEMCryptoProv30Test, CertValidAPI15) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxOrOEMCertValid()); +} + +TEST_F(OEMCryptoProv30Test, OEMCertValid) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + bool kVerify = true; + ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert(kVerify)); // Load and verify. +} + +// This verifies that the OEM Certificate cannot be used for other RSA padding +// schemes. Those schemes should only be used by cast receiver certificates. +TEST_F(OEMCryptoProv30Test, OEMCertForbiddenPaddingScheme) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert()); + OEMCryptoResult sts; + // Sign a Message + vector data(500); + GetRandBytes(data.data(), data.size()); + size_t signature_length = 0; + // We need a size one vector to pass as a pointer. + vector signature(1, 0); + vector zero(1, 0); + + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, + kSign_PKCS1_Block1); + if (OEMCrypto_ERROR_SHORT_BUFFER == sts) { + // The OEMCrypto could complain about buffer length first, so let's + // resize and check if it's writing to the signature again. + signature.resize(signature_length, 0); + zero.resize(signature_length, 0); + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), + data.size(), signature.data(), + &signature_length, kSign_PKCS1_Block1); + } + EXPECT_NE(OEMCrypto_SUCCESS, sts) + << "OEM Cert Signed with forbidden kSign_PKCS1_Block1."; + ASSERT_EQ(zero, signature); // signature should not be computed. +} + +// Calling OEMCrypto_GetOEMPublicCertificate should not change the session's +// private key. +TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) { + if (wrapped_drm_key_.size() == 0) { + // If we don't have a wrapped key yet, create one. + // This wrapped key will be shared by all sessions in the test. + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + } + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + // Install the DRM Cert's RSA key. + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey()); + // Request the OEM Cert. -- This should NOT load the OEM Private key. + vector public_cert; + size_t public_cert_length = 0; + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, + OEMCrypto_GetOEMPublicCertificate(nullptr, &public_cert_length)); + ASSERT_LT(0u, public_cert_length); + public_cert.resize(public_cert_length); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetOEMPublicCertificate( + public_cert.data(), &public_cert_length)); + // Derive keys from the session key -- this should use the DRM Cert's key. + // It should NOT use the OEM Private key because that key should not have + // been loaded. + ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey()); + // Now fill a message and try to load it. + LicenseRoundTrip license_messages(&s); + license_messages.set_control(0); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); +} + +// This verifies that the device really does claim to have BCC. +// It should be filtered out for devices that have a keybox or factory OEM +// cert. +TEST_F(OEMCryptoProv40Test, DeviceClaimsBootCertificateChain) { + ASSERT_EQ(OEMCrypto_GetProvisioningMethod(), OEMCrypto_BootCertificateChain); +} + +// Verifies that short buffer error returns when the buffer is short. +TEST_F(OEMCryptoProv40Test, GetBootCertificateChainShortBuffer) { + std::vector bcc; + size_t bcc_size = 0; + std::vector additional_signature; + size_t additional_signature_size = 0; + ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, + additional_signature.data(), + &additional_signature_size), + OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_NE(bcc_size, 0uL); +} + +// Verifies BCC can be successfully returned. +TEST_F(OEMCryptoProv40Test, GetBootCertificateChainSuccess) { + std::vector bcc; + size_t bcc_size = 0; + std::vector additional_signature; + size_t additional_signature_size = 0; + ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, + additional_signature.data(), + &additional_signature_size), + OEMCrypto_ERROR_SHORT_BUFFER); + + bcc.resize(bcc_size); + additional_signature.resize(additional_signature_size); + ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, + additional_signature.data(), + &additional_signature_size), + OEMCrypto_SUCCESS); +} + +// Verifies that short buffer error returns when the buffer is short. +TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairShortBuffer) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + std::vector public_key; + size_t public_key_size = 0; + std::vector public_key_signature; + size_t public_key_signature_size = 0; + std::vector wrapped_private_key; + size_t wrapped_private_key_size = 0; + OEMCrypto_PrivateKeyType key_type; + + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type), + OEMCrypto_ERROR_SHORT_BUFFER); + + ASSERT_NE(public_key_size, 0uL); + ASSERT_NE(public_key_signature_size, 0uL); + ASSERT_NE(wrapped_private_key_size, 0uL); +} + +// Verifies a pair of key can be successfully returned. +TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairSuccess) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + std::vector public_key; + size_t public_key_size = 0; + std::vector public_key_signature; + size_t public_key_signature_size = 0; + std::vector wrapped_private_key; + size_t wrapped_private_key_size = 0; + OEMCrypto_PrivateKeyType key_type; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type), + OEMCrypto_ERROR_SHORT_BUFFER); + public_key.resize(public_key_size); + public_key_signature.resize(public_key_signature_size); + wrapped_private_key.resize(wrapped_private_key_size); + + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type), + OEMCrypto_SUCCESS); + public_key.resize(public_key_size); + public_key_signature.resize(public_key_signature_size); + wrapped_private_key.resize(wrapped_private_key_size); + // Parse the public key generated to make sure it is correctly formatted. + ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey( + key_type, public_key.data(), public_key_size)); +} + +// Verifies the generated key pairs are different on each call. +TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairsAreDifferent) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + // Large buffer to make sure it is large enough. + size_t public_key_size1 = 10000; + std::vector public_key1(public_key_size1); + size_t public_key_signature_size1 = 10000; + std::vector public_key_signature1(public_key_signature_size1); + size_t wrapped_private_key_size1 = 10000; + std::vector wrapped_private_key1(wrapped_private_key_size1); + OEMCrypto_PrivateKeyType key_type1; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key1.data(), &public_key_size1, + public_key_signature1.data(), &public_key_signature_size1, + wrapped_private_key1.data(), &wrapped_private_key_size1, &key_type1), + OEMCrypto_SUCCESS); + EXPECT_NE(public_key_size1, 0UL); + EXPECT_NE(public_key_signature_size1, 0UL); + EXPECT_NE(wrapped_private_key_size1, 0UL); + public_key1.resize(public_key_size1); + public_key_signature1.resize(public_key_signature_size1); + wrapped_private_key1.resize(wrapped_private_key_size1); + + size_t public_key_size2 = 10000; + std::vector public_key2(public_key_size2); + size_t public_key_signature_size2 = 10000; + std::vector public_key_signature2(public_key_signature_size2); + size_t wrapped_private_key_size2 = 10000; + std::vector wrapped_private_key2(wrapped_private_key_size2); + OEMCrypto_PrivateKeyType key_type2; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key2.data(), &public_key_size2, + public_key_signature2.data(), &public_key_signature_size2, + wrapped_private_key2.data(), &wrapped_private_key_size2, &key_type2), + OEMCrypto_SUCCESS); + EXPECT_NE(public_key_size2, 0UL); + EXPECT_NE(public_key_signature_size2, 0UL); + EXPECT_NE(wrapped_private_key_size2, 0UL); + public_key2.resize(public_key_size2); + public_key_signature2.resize(public_key_signature_size2); + wrapped_private_key2.resize(wrapped_private_key_size2); + + EXPECT_NE(public_key1, public_key2); + EXPECT_NE(public_key_signature1, public_key_signature2); + EXPECT_NE(wrapped_private_key1, wrapped_private_key2); +} + +TEST_F(OEMCryptoProv40Test, GetDeviceInformationAPI18) { + std::vector device_info; + size_t device_info_length = 0; + OEMCryptoResult sts = + OEMCrypto_GetDeviceInformation(device_info.data(), &device_info_length); + ASSERT_EQ(sts, OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_NE(device_info_length, 0uL); + device_info.resize(device_info_length); + ASSERT_EQ( + OEMCrypto_GetDeviceInformation(device_info.data(), &device_info_length), + OEMCrypto_SUCCESS); + EXPECT_NE(device_info_length, 0uL); +} + +TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadAPI18) { + std::vector challenge(64, 0xaa); + // TODO: add cppbor support for oemcrypto tests for all targets. Before that, + // use hex values which are equivalent of the commented cppbor statement. + // std::vector device_info = cppbor::Map() + // .add("manufacturer", "google") + // .add("fused", 0) + // .add("other", "ignored") + // .canonicalize() + // .encode(); + // + std::vector device_info = { + 0xa3, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x0, 0x65, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x67, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, + 0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x72, 0x66, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65}; + std::vector signed_csr_payload; + size_t signed_csr_payload_length = 0; + OEMCryptoResult sts = OEMCrypto_GetDeviceSignedCsrPayload( + challenge.data(), challenge.size(), device_info.data(), + device_info.size(), signed_csr_payload.data(), + &signed_csr_payload_length); + ASSERT_EQ(sts, OEMCrypto_ERROR_SHORT_BUFFER); + ASSERT_NE(signed_csr_payload_length, 0uL); + signed_csr_payload.resize(signed_csr_payload_length); + ASSERT_EQ(OEMCrypto_GetDeviceSignedCsrPayload( + challenge.data(), challenge.size(), device_info.data(), + device_info.size(), signed_csr_payload.data(), + &signed_csr_payload_length), + OEMCrypto_SUCCESS); + EXPECT_NE(signed_csr_payload_length, 0uL); +} + +TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadInvalid) { + std::vector signed_csr_payload; + size_t signed_csr_payload_length = 0; + std::vector challenge(64, 0xaa); + std::vector device_info = { + 0xa3, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x0, 0x65, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x67, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, + 0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x72, 0x66, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65}; + std::vector challenge_empty; + OEMCryptoResult sts = OEMCrypto_GetDeviceSignedCsrPayload( + challenge_empty.data(), challenge_empty.size(), device_info.data(), + device_info.size(), signed_csr_payload.data(), + &signed_csr_payload_length); + if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) return; + ASSERT_EQ(sts, OEMCrypto_ERROR_INVALID_CONTEXT); + + // Oversized challenge + std::vector challenge_long(65, 0xaa); + sts = OEMCrypto_GetDeviceSignedCsrPayload( + challenge_long.data(), challenge_long.size(), device_info.data(), + device_info.size(), signed_csr_payload.data(), + &signed_csr_payload_length); + ASSERT_EQ(sts, OEMCrypto_ERROR_INVALID_CONTEXT); + + std::vector device_empty; + sts = OEMCrypto_GetDeviceSignedCsrPayload( + challenge.data(), challenge.size(), device_empty.data(), + device_empty.size(), signed_csr_payload.data(), + &signed_csr_payload_length); + ASSERT_EQ(sts, OEMCrypto_ERROR_INVALID_CONTEXT); +} + +// Verifies that an OEM private key can be installed. +TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeySuccess) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + // First generate a key pair. + // Large buffer to make sure it is large enough. + size_t public_key_size = 10000; + std::vector public_key(public_key_size); + size_t public_key_signature_size = 10000; + std::vector public_key_signature(public_key_signature_size); + size_t wrapped_private_key_size = 10000; + std::vector wrapped_private_key(wrapped_private_key_size); + OEMCrypto_PrivateKeyType key_type; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type), + OEMCrypto_SUCCESS); + public_key.resize(public_key_size); + public_key_signature.resize(public_key_signature_size); + wrapped_private_key.resize(wrapped_private_key_size); + + // Install the generated private key. + ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, + wrapped_private_key.data(), + wrapped_private_key_size), + OEMCrypto_SUCCESS); +} + +// If data is empty or random, the API should return non-success status. +TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyInvalidDataFail) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + + // Empty key fails. + std::vector wrapped_private_key; + OEMCrypto_PrivateKeyType key_type = OEMCrypto_RSA_Private_Key; + ASSERT_NE(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, + wrapped_private_key.data(), + wrapped_private_key.size()), + OEMCrypto_SUCCESS); + + // Random key data fails. + wrapped_private_key = {1, 2, 3}; + ASSERT_NE(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, + wrapped_private_key.data(), + wrapped_private_key.size()), + OEMCrypto_SUCCESS); +} + +// Verifies that an OEM private key can be installed, and used by +// GenerateCertificateKeyPair call. +TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + // First generate a key pair. + size_t public_key_size1 = 10000; + std::vector public_key1(public_key_size1); + size_t public_key_signature_size1 = 10000; + std::vector public_key_signature1(public_key_signature_size1); + size_t wrapped_private_key_size1 = 10000; + std::vector wrapped_private_key1(wrapped_private_key_size1); + OEMCrypto_PrivateKeyType key_type1; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key1.data(), &public_key_size1, + public_key_signature1.data(), &public_key_signature_size1, + wrapped_private_key1.data(), &wrapped_private_key_size1, &key_type1), + OEMCrypto_SUCCESS); + EXPECT_NE(public_key_size1, 0UL); + EXPECT_NE(public_key_signature_size1, 0UL); + EXPECT_NE(wrapped_private_key_size1, 0UL); + public_key1.resize(public_key_size1); + public_key_signature1.resize(public_key_signature_size1); + wrapped_private_key1.resize(wrapped_private_key_size1); + + // Install the generated private key. + ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type1, + wrapped_private_key1.data(), + wrapped_private_key_size1), + OEMCrypto_SUCCESS); + + // Now calling GenerateCertificateKeyPair should use wrapped_private_key to + // sign the newly generated public key. + size_t public_key_size2 = 10000; + std::vector public_key2(public_key_size2); + size_t public_key_signature_size2 = 10000; + std::vector public_key_signature2(public_key_signature_size2); + size_t wrapped_private_key_size2 = 10000; + std::vector wrapped_private_key2(wrapped_private_key_size2); + OEMCrypto_PrivateKeyType key_type2; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key2.data(), &public_key_size2, + public_key_signature2.data(), &public_key_signature_size2, + wrapped_private_key2.data(), &wrapped_private_key_size2, &key_type2), + OEMCrypto_SUCCESS); + EXPECT_NE(public_key_size2, 0UL); + EXPECT_NE(public_key_signature_size2, 0UL); + EXPECT_NE(wrapped_private_key_size2, 0UL); + public_key2.resize(public_key_size2); + public_key_signature2.resize(public_key_signature_size2); + wrapped_private_key2.resize(wrapped_private_key_size2); + + // Verify public_key_signature2 with public_key1. + if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) { + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey( + public_key1.data(), public_key1.size())); + ASSERT_NO_FATAL_FAILURE( + s.VerifyRsaSignature(public_key2, public_key_signature2.data(), + public_key_signature2.size(), kSign_RSASSA_PSS)); + } else if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) { + ASSERT_NO_FATAL_FAILURE(s.SetEccPublicKeyFromSubjectPublicKey( + public_key1.data(), public_key1.size())); + ASSERT_NO_FATAL_FAILURE(s.VerifyEccSignature(public_key2, + public_key_signature2.data(), + public_key_signature2.size())); + } +} + +/** Verify that the private key from an OEM Cert cannot be loaded as a DRM + * cert. + */ +TEST_F(OEMCryptoProv40Test, OEMPrivateKeyCannotBeDRMKey) { + // Create an OEM Cert and save it for alter. + Session s1; + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s1)); + ASSERT_EQ(s1.IsPublicKeySet(), true); + s1.close(); + const std::vector wrapped_oem_key1 = wrapped_oem_key_; + // Now create a new OEM cert, load the second key, and try to load key1 + // as the DRM key. + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s2)); + s2.close(); + // Load the current key as the OEM key in session 3. + Session s3; + ASSERT_NO_FATAL_FAILURE(s3.open()); + // Now try to load key 1 as a DRM key. That should fail. + ASSERT_EQ(OEMCrypto_ERROR_INVALID_KEY, + OEMCrypto_LoadDRMPrivateKey(s3.session_id(), oem_key_type_, + wrapped_oem_key1.data(), + wrapped_oem_key1.size())); +} + +/** The private key for a DRM Cert cannot be loaded as an OEM Certificate. */ +TEST_F(OEMCryptoProv40Test, DRMPrivateKeyCannotBeOEMKey) { + // Create a DRM cert and save it for later. + Session s1; + // Make sure the drm private key exists. + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s1)); + ASSERT_NE(wrapped_drm_key_.size(), 0u); + // Now try to load the drm private key as an OEM key. + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_KEY, + OEMCrypto_InstallOemPrivateKey( + s2.session_id(), drm_key_type_, + reinterpret_cast(wrapped_drm_key_.data()), + wrapped_drm_key_.size())); +} + +TEST_F(OEMCryptoProv40Test, GetDeviceId) { + OEMCryptoResult sts; + std::vector dev_id; + size_t dev_id_len = dev_id.size(); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + ASSERT_GT(dev_id_len, 0u); + dev_id.resize(dev_id_len); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + } + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + dev_id.resize(dev_id_len); + cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id) + << " len = " << dev_id_len << endl; + // Device id should be stable. Query again. + std::vector dev_id2(dev_id_len); + sts = OEMCrypto_GetDeviceID(dev_id2.data(), &dev_id_len); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(dev_id2, dev_id); +} + +// Verifies provisioning stage 1 OEM cert provisioning round trip works +TEST_F(OEMCryptoProv40Test, ProvisionOemCert) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s)); + ASSERT_EQ(s.IsPublicKeySet(), true); +} + +// Verifies both provisioning stages OEM and DRM cert provisioning round trip +// works +TEST_F(OEMCryptoProv40Test, ProvisionDrmCert) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_EQ(s.IsPublicKeySet(), true); +} + +TEST_P(OEMCryptoProv40CastTest, ProvisionCastWorks) { + // Generate an OEM key first, to load into next session + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + size_t public_key_size = 10000; + std::vector public_key(public_key_size); + size_t public_key_signature_size = 10000; + std::vector public_key_signature(public_key_signature_size); + size_t wrapped_private_key_size = 10000; + std::vector wrapped_private_key(wrapped_private_key_size); + OEMCrypto_PrivateKeyType key_type; + ASSERT_EQ( + OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type), + OEMCrypto_SUCCESS); + public_key.resize(public_key_size); + public_key_signature.resize(public_key_signature_size); + wrapped_private_key.resize(wrapped_private_key_size); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Install OEM key and get cast RSA + Session s1; + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s1.session_id(), key_type, + wrapped_private_key.data(), + wrapped_private_key_size), + OEMCrypto_SUCCESS); + + ASSERT_NO_FATAL_FAILURE(CreateProv4CastKey(&s1, GetParam())); +} + +INSTANTIATE_TEST_SUITE_P(Prov4CastProvisioningBasic, OEMCryptoProv40CastTest, + testing::Values(true, false)); + +TEST_F(OEMCryptoLoadsCertificate, PrepAndSignLicenseRequestCounterAPI18) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + s.GenerateNonce(); + + size_t core_message_length = 100; + std::vector message(128, 0); + std::vector signature(256, 0); + size_t signature_length = signature.size(); + + OEMCryptoResult result = OEMCrypto_PrepAndSignLicenseRequest( + s.session_id(), message.data(), message.size(), &core_message_length, + signature.data(), &signature_length); + + ASSERT_EQ(OEMCrypto_SUCCESS, result); +} + +// This test verifies that we can create a wrapped RSA key, and then reload it. +TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); +} + +TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { + s.LoadOEMCert(true); + } else { + EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); + s.GenerateDerivedKeysFromKeybox(keybox_); + } + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); +} + +// This tests a large message size. The size is larger than we required in v15. +TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { + s.LoadOEMCert(true); + } else { + EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); + s.GenerateDerivedKeysFromKeybox(keybox_); + } + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + const size_t max_size = GetResourceValue(kLargeMessageSize); + provisioning_messages.set_message_size(max_size); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); +} + +// This creates a wrapped RSA key, and then does the sanity check that the +// unencrypted key is not found in the wrapped key. The wrapped key should be +// encrypted. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvision) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + // We should not be able to find the rsa key in the wrapped key. It should + // be encrypted. + EXPECT_EQ(nullptr, find(provisioning_messages.wrapped_rsa_key(), + provisioning_messages.encoded_rsa_key())); +} + +// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning +// message. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + // Encrypt and sign once, so that we can use the size of the response. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + provisioning_messages.core_response().enc_private_key.offset = + provisioning_messages.encrypted_response_buffer().size() + 1; + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning +// message. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + // Encrypt and sign once, so that we can use the size of the response. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + provisioning_messages.core_response().enc_private_key_iv.offset = + provisioning_messages.encrypted_response_buffer().size() + 1; + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning +// message. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + // Encrypt and sign once, so that we can use the size of the response. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + // If the offset is before the end, but the offset+length is bigger, then + // the message should be rejected. + provisioning_messages.core_response().enc_private_key.offset = + provisioning_messages.encrypted_response_buffer().size() - 5; + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning +// message. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + // Encrypt and sign once, so that we can use the size of the response. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + // If the offset is before the end, but the offset+length is bigger, then + // the message should be rejected. + provisioning_messages.core_response().enc_private_key_iv.offset = + provisioning_messages.encrypted_response_buffer().size() - 5; + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning +// message. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) { + if (global_features.provisioning_method != OEMCrypto_OEMCertificate) { + GTEST_SKIP() << "Test for Prov 3.0 devices only."; + } + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + // Encrypt and sign once, so that we can use the size of the response. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + // If the offset is before the end, but the offset+length is bigger, then + // the message should be rejected. + provisioning_messages.core_response().encrypted_message_key.offset = + provisioning_messages.encrypted_response_buffer().size() + 1; + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Test that RewrapDeviceRSAKey verifies the message signature. +// TODO(b/144186970): This test should also run on Prov 3.0 devices. +TEST_F(OEMCryptoLoadsCertificate, + CertificateProvisionBadSignatureKeyboxTestAPI16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + provisioning_messages.response_signature()[4] ^= 42; // bad signature. + ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, + provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Test that RewrapDeviceRSAKey verifies the nonce is current. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonce_API16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + provisioning_messages.core_request().nonce ^= 42; // bad nonce. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, + provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Test that RewrapDeviceRSAKey verifies the RSA key is valid. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + provisioning_messages.response_data().rsa_key[4] ^= 42; // bad key. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Test that RewrapDeviceRSAKey verifies the RSA key is valid. +// TODO(b/144186970): This test should also run on Prov 3.0 devices. +TEST_F(OEMCryptoLoadsCertificate, + CertificateProvisionBadRSAKeyKeyboxTestAPI16) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + size_t rsa_offset = + provisioning_messages.core_response().enc_private_key.offset; + // Offsets are relative to the message body, after the core message. + rsa_offset += provisioning_messages.serialized_core_message().size(); + rsa_offset += 4; // Change the middle of the key. + provisioning_messages.encrypted_response_buffer()[rsa_offset] ^= 42; + ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, + provisioning_messages.LoadResponse()); + provisioning_messages.VerifyLoadFailed(); +} + +// Test that RewrapDeviceRSAKey accepts the maximum message size. +TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBuffer) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + const size_t max_size = GetResourceValue(kLargeMessageSize); + provisioning_messages.set_message_size(max_size); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + // We should not be able to find the rsa key in the wrapped key. It should + // be encrypted. + EXPECT_EQ(nullptr, find(provisioning_messages.wrapped_rsa_key(), + provisioning_messages.encoded_rsa_key())); +} + +// Test that a wrapped RSA key can be loaded. +TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); +} + +class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate { + public: + void TestKey(const uint8_t* key, size_t key_length) { + encoded_rsa_key_.assign(key, key + key_length); + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + + LicenseRoundTrip license_messages(&s); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); + } +}; + +// Test a 3072 bit RSA key certificate. +TEST_F(OEMCryptoLoadsCertVariousKeys, TestLargeRSAKey3072) { + if (!global_features.supports_rsa_3072) { + GTEST_SKIP() << "OEMCrypto does not support RSA 3072"; + } + TestKey(kTestRSAPKCS8PrivateKeyInfo3_3072, + sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072)); +} + +// Test an RSA key certificate which has a private key generated using the +// Carmichael totient. +TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelRSAKey) { + TestKey(kTestKeyRSACarmichael_2048, sizeof(kTestKeyRSACarmichael_2048)); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroNormalDer) { + TestKey(kCarmichaelNonZeroNormalDer, kCarmichaelNonZeroNormalDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroShortDer) { + TestKey(kCarmichaelNonZeroShortDer, kCarmichaelNonZeroShortDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroNormalDer) { + TestKey(kCarmichaelZeroNormalDer, kCarmichaelZeroNormalDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroShortDer) { + TestKey(kCarmichaelZeroShortDer, kCarmichaelZeroShortDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroNormalDer) { + TestKey(kDualNonZeroNormalDer, kDualNonZeroNormalDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroShortDer) { + TestKey(kDualNonZeroShortDer, kDualNonZeroShortDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroNormalDer) { + TestKey(kDualZeroNormalDer, kDualZeroNormalDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroShortDer) { + TestKey(kDualZeroShortDer, kDualZeroShortDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerNonZeroNormalDer) { + TestKey(kEulerNonZeroNormalDer, kEulerNonZeroNormalDerLen); +} + +TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) { + TestKey(kEulerZeroNormalDer, kEulerZeroNormalDerLen); +} + +// This tests that two sessions can use different RSA keys simultaneously. +TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + Session s1; // Session s1 loads the default rsa key, but doesn't use it + // until after s2 uses its key. + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + + Session s2; // Session s2 uses a different rsa key. + encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048, + kTestRSAPKCS8PrivateKeyInfo4_2048 + + sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048)); + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + LicenseRoundTrip license_messages2(&s2); + ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(s2.TestDecryptCTR()); + s2.close(); + + // After s2 has loaded its rsa key, we continue using s1's key. + LicenseRoundTrip license_messages1(&s1); + ASSERT_NO_FATAL_FAILURE(license_messages1.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages1.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages1.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages1.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR()); +} + +// This tests the maximum number of DRM private keys that OEMCrypto can load +TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) { + const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys); + std::vector> sessions; + std::vector> licenses; + + // It should be able to load up to kMaxTotalDRMPrivateKeys keys + for (size_t i = 0; i < max_total_keys; i++) { + sessions.push_back(std::unique_ptr(new Session())); + licenses.push_back(std::unique_ptr( + new LicenseRoundTrip(sessions[i].get()))); + const size_t key_index = i % kTestRSAPKCS8PrivateKeys_2048.size(); + encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeys_2048[key_index].begin(), + kTestRSAPKCS8PrivateKeys_2048[key_index].end()); + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + ASSERT_NO_FATAL_FAILURE(sessions[i]->open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(sessions[i].get())); + } + + // Attempts to load one more key than the kMaxTotalDRMPrivateKeys + if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { + Session s; + const size_t buffer_size = 5000; // Make sure it is large enough. + std::vector public_key(buffer_size); + size_t public_key_size = buffer_size; + std::vector public_key_signature(buffer_size); + size_t public_key_signature_size = buffer_size; + std::vector wrapped_private_key(buffer_size); + size_t wrapped_private_key_size = buffer_size; + OEMCrypto_PrivateKeyType key_type; + OEMCryptoResult result = OEMCrypto_GenerateCertificateKeyPair( + s.session_id(), public_key.data(), &public_key_size, + public_key_signature.data(), &public_key_signature_size, + wrapped_private_key.data(), &wrapped_private_key_size, &key_type); + // Key creation is allowed to fail due to resource restriction + if (result != OEMCrypto_SUCCESS) { + ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES || + result == OEMCrypto_ERROR_TOO_MANY_KEYS); + } + } else { + Session s; + encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo2_2048, + kTestRSAPKCS8PrivateKeyInfo2_2048 + + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); + Session ps; + ProvisioningRoundTrip provisioning_messages(&ps, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + OEMCryptoResult result = provisioning_messages.LoadResponse(); + // Key loading is allowed to fail due to resource restriction + if (result != OEMCrypto_SUCCESS) { + ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES || + result == OEMCrypto_ERROR_TOO_MANY_KEYS); + } + } + // Verifies that the DRM keys which are already loaded should still function + for (size_t i = 0; i < licenses.size(); i++) { + ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse()); + ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR()); + } +} + +// Devices that load certificates, should at least support RSA 2048 keys. +TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) { + ASSERT_NE(0u, + OEMCrypto_Supports_RSA_2048bit & OEMCrypto_SupportedCertificates()) + << "Supported certificates is only " << OEMCrypto_SupportedCertificates(); +} + +// This test is not run by default, because it takes a long time and +// is used to measure RSA performance, not test functionality. +TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { + const std::chrono::milliseconds kTestDuration(5000); + OEMCryptoResult sts; + std::chrono::steady_clock clock; + wvutil::TestSleep::Sleep(kShortSleep); // Make sure we are not nonce limited. + + auto start_time = clock.now(); + int count = 15; + for (int i = 0; i < count; i++) { // Only 20 nonce available. + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + } + auto delta_time = clock.now() - start_time; + const double provision_time = + delta_time / std::chrono::milliseconds(1) / count; + + Session session; + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + start_time = clock.now(); + count = 0; + while (clock.now() - start_time < kTestDuration) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + const size_t size = 50; + vector licenseRequest(size); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); + size_t signature_length = 0; + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), + licenseRequest.size(), nullptr, + &signature_length, kSign_RSASSA_PSS); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + ASSERT_NE(static_cast(0), signature_length); + + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_generate_rsa_signature_fuzz_seed_corpus"); + OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure; + fuzzed_structure.padding_scheme = kSign_RSASSA_PSS; + fuzzed_structure.signature_length = signature_length; + // Cipher mode and algorithm. + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, + reinterpret_cast(licenseRequest.data()), + licenseRequest.size()); + } + + std::vector signature(signature_length, 0); + sts = OEMCrypto_GenerateRSASignature( + s.session_id(), licenseRequest.data(), licenseRequest.size(), + signature.data(), &signature_length, kSign_RSASSA_PSS); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + count++; + } + delta_time = clock.now() - start_time; + const double license_request_time = + delta_time / std::chrono::milliseconds(1) / count; + + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_)); + vector session_key; + vector enc_session_key; + ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key)); + vector mac_context; + vector enc_context; + s.FillDefaultContext(&mac_context, &enc_context); + + enc_session_key = wvutil::a2b_hex( + "7789c619aa3b9fa3c0a53f57a4abc6" + "02157c8aa57e3c6fb450b0bea22667fb" + "0c3200f9d9d618e397837c720dc2dadf" + "486f33590744b2a4e54ca134ae7dbf74" + "434c2fcf6b525f3e132262f05ea3b3c1" + "198595c0e52b573335b2e8a3debd0d0d" + "d0306f8fcdde4e76476be71342957251" + "e1688c9ca6c1c34ed056d3b989394160" + "cf6937e5ce4d39cc73d11a2e93da21a2" + "fa019d246c852fe960095b32f120c3c2" + "7085f7b64aac344a68d607c0768676ce" + "d4c5b2d057f7601921b453a451e1dea0" + "843ebfef628d9af2784d68e86b730476" + "e136dfe19989de4be30a4e7878efcde5" + "ad2b1254f80c0c5dd3cf111b56572217" + "b9f58fc1dacbf74b59d354a1e62cfa0e" + "bf"); + start_time = clock.now(); + while (clock.now() - start_time < kTestDuration) { + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_DeriveKeysFromSessionKey( + s.session_id(), enc_session_key.data(), + enc_session_key.size(), mac_context.data(), + mac_context.size(), enc_context.data(), enc_context.size())); + count++; + } + delta_time = clock.now() - start_time; + const double derive_keys_time = + delta_time / std::chrono::milliseconds(1) / count; + + OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); + printf("PERF:head, security, provision (ms), lic req(ms), derive keys(ms)\n"); + printf("PERF:stat, %u, %8.3f, %8.3f, %8.3f\n", + static_cast(level), provision_time, license_request_time, + derive_keys_time); +} + +// Test DeriveKeysFromSessionKey using the maximum size for the HMAC context. +TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { + vector session_key; + vector enc_session_key; + ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); + const size_t max_size = GetResourceValue(kLargeMessageSize); + vector mac_context(max_size); + vector enc_context(max_size); + // Stripe the data so the two vectors are not identical, and not all zeroes. + for (size_t i = 0; i < max_size; i++) { + mac_context[i] = i % 0x100; + enc_context[i] = (3 * i) % 0x100; + } + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_DeriveKeysFromSessionKey( + session_.session_id(), enc_session_key.data(), + enc_session_key.size(), mac_context.data(), mac_context.size(), + enc_context.data(), enc_context.size())); +} + +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_provisioning_test.h b/oemcrypto/test/oemcrypto_provisioning_test.h new file mode 100644 index 00000000..b44369c5 --- /dev/null +++ b/oemcrypto/test/oemcrypto_provisioning_test.h @@ -0,0 +1,169 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_PROVISIONING_TEST_ +#define CDM_OEMCRYPTO_PROVISIONING_TEST_ + +#include + +#include "OEMCryptoCENC.h" +#include "oec_extra_test_keys.h" +#include "oemcrypto_basic_test.h" +#include "oemcrypto_license_test.h" +#include "oemcrypto_resource_test.h" + +namespace wvoec { + +// Tests using this class are only used for devices with a keybox. They are not +// run for devices with an OEM Certificate. +class OEMCryptoKeyboxTest : public OEMCryptoClientTest { + void SetUp() override { + OEMCryptoClientTest::SetUp(); + OEMCryptoResult sts = OEMCrypto_IsKeyboxValid(); + // If the production keybox is valid, use it for these tests. Most of the + // other tests will use a test keybox anyway, but it's nice to check the + // device ID for the real keybox if we can. + if (sts == OEMCrypto_SUCCESS) return; + printf("Production keybox is NOT valid. All tests use test keybox.\n"); + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_LoadTestKeybox(reinterpret_cast(&kTestKeybox), + sizeof(kTestKeybox))); + } +}; + +// This class is for tests that have an OEM Certificate instead of a keybox. +class OEMCryptoProv30Test : public OEMCryptoClientTest { + void SetUp() override { + OEMCryptoClientTest::SetUp(); + if (global_features.provisioning_method != OEMCrypto_OEMCertificate) { + GTEST_SKIP() << "Test for Prov 3.0 devices only."; + } + } +}; + +// This class is for tests that have boot certificate chain instead of a keybox. +class OEMCryptoProv40Test : public OEMCryptoClientTest { + void SetUp() override { + OEMCryptoClientTest::SetUp(); + if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) { + GTEST_SKIP() << "Test for Prov 4.0 devices only."; + } + } +}; + +class OEMCryptoProv40CastTest : public OEMCryptoClientTest, + public testing::WithParamInterface { + void SetUp() override { + OEMCryptoClientTest::SetUp(); + if (!global_features.cast_receiver) { + GTEST_SKIP() << "Test for cast devices only."; + } + if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) { + GTEST_SKIP() << "Test for Prov 4.0 devices only."; + } + } +}; + +// +// Certificate Root of Trust Tests +// +class OEMCryptoLoadsCertificate : public OEMCryptoSessionTestKeyboxTest { + protected: + void TestPrepareProvisioningRequestForHugeBufferLengths( + const std::function f, + bool check_status) { + auto oemcrypto_function = [&](size_t message_length) { + Session s; + s.open(); + if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { + s.LoadOEMCert(true); + } else { + s.GenerateDerivedKeysFromKeybox(keybox_); + } + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + f(message_length, &provisioning_messages); + return provisioning_messages + .SignAndCreateRequestWithCustomBufferLengths(); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); + } + + void TestLoadProvisioningForHugeBufferLengths( + const std::function f, + bool check_status, bool update_core_message_substring_values) { + auto oemcrypto_function = [&](size_t message_length) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + provisioning_messages.SignAndVerifyRequest(); + provisioning_messages.CreateDefaultResponse(); + if (update_core_message_substring_values) { + // Make provisioning message big enough so that updated core message + // substring offset and length values from tests are still able to read + // valid data from provisioning_message buffer rather than some garbage + // data. + provisioning_messages.set_message_size( + sizeof(provisioning_messages.response_data()) + message_length); + } + f(message_length, &provisioning_messages); + provisioning_messages + .EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength(); + OEMCryptoResult result = provisioning_messages.LoadResponse(); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); + } + + void TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths( + const std::function f) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + provisioning_messages.SignAndVerifyRequest(); + provisioning_messages.CreateDefaultResponse(); + size_t message_length = sizeof(provisioning_messages.response_data()); + f(message_length, &provisioning_messages); + provisioning_messages + .EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength(); + OEMCryptoResult result = provisioning_messages.LoadResponse(); + s.close(); + // Verifying error is not due to signature failure which can be caused due + // to test code. + ASSERT_NE(OEMCrypto_ERROR_SIGNATURE_FAILURE, result); + ASSERT_NE(OEMCrypto_SUCCESS, result); + } +}; + +// These tests are run by all L1 devices that load and use certificates. It is +// also run by a few L3 devices that use a baked in certificate, but cannot load +// a certificate. +class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate { + protected: + void SetUp() override { + OEMCryptoLoadsCertificate::SetUp(); + ASSERT_NO_FATAL_FAILURE(session_.open()); + if (global_features.derive_key_method == + DeviceFeatures::LOAD_TEST_RSA_KEY) { + ASSERT_NO_FATAL_FAILURE(session_.SetRsaPublicKeyFromPrivateKeyInfo( + encoded_rsa_key_.data(), encoded_rsa_key_.size())); + } else { + InstallTestDrmKey(&session_); + } + } + + void TearDown() override { + ASSERT_NO_FATAL_FAILURE(session_.close()); + OEMCryptoLoadsCertificate::TearDown(); + } + + Session session_; +}; + +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_PROVISIONING_TEST_ \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_resource_test.h b/oemcrypto/test/oemcrypto_resource_test.h new file mode 100644 index 00000000..9a5c0b0f --- /dev/null +++ b/oemcrypto/test/oemcrypto_resource_test.h @@ -0,0 +1,62 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_RESOURCE_TEST_ +#define CDM_OEMCRYPTO_RESOURCE_TEST_ + +#include + +#include "OEMCryptoCENC.h" +#include "oemcrypto_types.h" + +namespace wvoec { +constexpr size_t kBufferOverrunPadding = 16; + +// Resource tiers: +constexpr size_t KiB = 1024; +constexpr size_t MiB = 1024 * 1024; +// Huge input buffer length used for OEMCryptoMemory* tests. +constexpr size_t kHugeInputBufferLength = 100 * MiB; +constexpr bool kCheckStatus = true; +constexpr bool kUpdateCoreMessageSubstringValues = true; +constexpr bool kDecryptCENCSecureBuffer = true; +constexpr size_t kHugeRandomNumber = 541236; +// With OEMCrypto v15 and above, we have different resource requirements +// depending on the resource rating reported by OEMCrypto. This function looks +// up the required value for the specified resource for the target OEMCrypto +// library. +template +T GetResourceValue(T (&resource_values)[N]) { + if (global_features.resource_rating < 1) return resource_values[0]; + if (global_features.resource_rating > N) return resource_values[N - 1]; + return resource_values[global_features.resource_rating - 1]; +} + +// After API 16, we require 300 entries in the usage table. Before API 16, we +// required 200. +inline size_t RequiredUsageSize() { + return global_features.api_version < 16 ? 200 : 300; +} + +// These are the maximum sizes we test. That means it is the minimum size that +// OEMCrypto must support. +// clang-format off +const size_t kMaxSampleSize[] = { 1*MiB, 2*MiB, 4*MiB, 16*MiB}; +const size_t kMaxNumberSubsamples[] = { 10, 16, 32, 64}; +const size_t kMaxSubsampleSize[] = { 100*KiB, 500*KiB, 1*MiB, 4*MiB}; +const size_t kMaxGenericBuffer[] = { 10*KiB, 100*KiB, 500*KiB, 1*MiB}; +const size_t kMaxConcurrentSession[] = { 10, 20, 30, 40}; +const size_t kMaxKeysPerSession[] = { 4, 20, 20, 30}; +const size_t kMaxTotalKeys[] = { 16, 40, 80, 90}; +const size_t kLargeMessageSize[] = { 8*KiB, 8*KiB, 16*KiB, 32*KiB}; +const size_t kMaxTotalDRMPrivateKeys[] = { 2, 4, 6, 8}; +// Note: Frame rate and simultaneous playback are specified by resource rating, +// but are tested at the system level, so there are no unit tests for frame +// rate. Similarly, number of subsamples for AV1 +// const size_t kAV1NumberSubsamples[] = { 72, 144, 288, 576}; +// clang-format on +} // namespace wvoec +#endif // CDM_OEMCRYPTO_RESOURCE_TEST_ diff --git a/oemcrypto/test/oemcrypto_security_test.cpp b/oemcrypto/test/oemcrypto_security_test.cpp new file mode 100644 index 00000000..af9b0462 --- /dev/null +++ b/oemcrypto/test/oemcrypto_security_test.cpp @@ -0,0 +1,1213 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO(b/253779846) Change it to include a header instead +#include "oemcrypto_test.cpp" + +using ::testing::Bool; +using ::testing::Combine; +using ::testing::Range; +using ::testing::tuple; +using ::testing::Values; +using ::testing::WithParamInterface; +using namespace std; + +namespace wvoec { + +/// @addtogroup security +/// @{ + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryAllocateSecureBufferForHugeBufferSize) { + Session s; + s.open(); + auto oemcrypto_function = [&s](size_t buffer_size) { + OEMCrypto_DestBufferDesc output_descriptor; + int secure_fd; + OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( + s.session_id(), buffer_size, &output_descriptor, &secure_fd); + if (sts == OEMCrypto_SUCCESS) { + OEMCrypto_FreeSecureBuffer(s.session_id(), &output_descriptor, secure_fd); + } + return sts; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); + s.close(); +} + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLength) { + auto oemcrypto_function = [](size_t keybox_length) { + vector keybox_buffer(keybox_length); + size_t wrapped_keybox_length = keybox_length + 50; + vector wrapped_keybox_buffer(wrapped_keybox_length); + vector transport_key_buffer(20); + memcpy(keybox_buffer.data(), &kTestKeybox, sizeof(kTestKeybox)); + return OEMCrypto_WrapKeyboxOrOEMCert( + keybox_buffer.data(), keybox_length, wrapped_keybox_buffer.data(), + &wrapped_keybox_length, transport_key_buffer.data(), + transport_key_buffer.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, sizeof(kTestKeybox), + kHugeInputBufferLength, kCheckStatus); +} + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeWrappedKeyboxLength) { + auto oemcrypto_function = [](size_t buffer_length) { + size_t wrapped_keybox_length = buffer_length; + vector wrapped_keybox_buffer(wrapped_keybox_length); + vector transport_key_buffer(20); + return OEMCrypto_WrapKeyboxOrOEMCert( + reinterpret_cast(&kTestKeybox), sizeof(kTestKeybox), + wrapped_keybox_buffer.data(), &wrapped_keybox_length, + transport_key_buffer.data(), transport_key_buffer.size()); + }; + // API expects keybox length and wrapped keybox length to be equal. We would + // like to test for various values of wrapped keybox lengths, hence skipping + // status check. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeTransportKey) { + auto oemcrypto_function = [](size_t transport_key_length) { + size_t wrapped_keybox_length = sizeof(&kTestKeybox) + 50; + vector wrapped_keybox_buffer(wrapped_keybox_length); + vector transport_key_buffer(transport_key_length); + return OEMCrypto_WrapKeyboxOrOEMCert( + reinterpret_cast(&kTestKeybox), sizeof(kTestKeybox), + wrapped_keybox_buffer.data(), &wrapped_keybox_length, + transport_key_buffer.data(), transport_key_buffer.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F( + OEMCryptoClientTest, + OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLengthStartingFromLength1) { + auto oemcrypto_function = [](size_t keybox_length) { + vector keybox_buffer(keybox_length); + size_t wrapped_keybox_length = keybox_length + 50; + vector wrapped_keybox_buffer(wrapped_keybox_length); + vector transport_key_buffer(20); + return OEMCrypto_WrapKeyboxOrOEMCert( + keybox_buffer.data(), keybox_length, wrapped_keybox_buffer.data(), + &wrapped_keybox_length, transport_key_buffer.data(), + transport_key_buffer.size()); + }; + // Cannot check status as keybox will not be valid for this test. + // We still want to test what happens if buffer lengths is less that keybox + // length. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +// Test that set sandbox doesn't crash for a large sandbox id leangth. +TEST_F(OEMCryptoClientTest, OEMCryptoMemorySetSandboxForHugeSandboxIdLength) { + auto oemcrypto_function = [](size_t buffer_length) { + vector buffer(buffer_length); + return OEMCrypto_SetSandbox(buffer.data(), buffer.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForHugeBufferLengths) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector input_buffer; + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; + + auto oemcrypto_function = [&s, &dest_buffer_descriptor, + &input_buffer](size_t buffer_length) { + input_buffer.resize(buffer_length); + int secure_fd; + OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( + s.session_id(), buffer_length, &dest_buffer_descriptor, &secure_fd); + if (sts != OEMCrypto_SUCCESS) { + LOGI("Secure buffers are not supported."); + return sts; + } + + dest_buffer_descriptor.buffer.secure.secure_buffer_length = buffer_length; + OEMCryptoResult status = OEMCrypto_CopyBuffer( + s.session_id(), input_buffer.data(), buffer_length, + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, + secure_fd); + return status; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoClientTest, + OEMCryptoMemoryCopyBufferDirectForHugeBufferLengths) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector input_buffer; + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Direct; + dest_buffer_descriptor.buffer.direct.is_video = false; + + auto oemcrypto_function = [&s, &dest_buffer_descriptor, + &input_buffer](size_t buffer_length) { + input_buffer.resize(buffer_length); + OEMCryptoResult status = OEMCrypto_CopyBuffer( + s.session_id(), input_buffer.data(), buffer_length, + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + return status; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForOutOfRangeOffset) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector input_buffer; + OEMCrypto_DestBufferDesc dest_buffer_descriptor; + dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; + + size_t buffer_length = KiB; + input_buffer.resize(buffer_length); + int secure_fd; + if (OEMCrypto_AllocateSecureBuffer(s.session_id(), buffer_length, + &dest_buffer_descriptor, + &secure_fd) != OEMCrypto_SUCCESS) { + LOGI("Secure buffers are not supported."); + return; + } + + dest_buffer_descriptor.buffer.secure.secure_buffer_length = buffer_length; + auto oemcrypto_function = [&s, &dest_buffer_descriptor, &input_buffer, + &buffer_length](size_t offset) { + dest_buffer_descriptor.buffer.secure.offset = offset; + return OEMCrypto_CopyBuffer( + s.session_id(), input_buffer.data(), buffer_length, + &dest_buffer_descriptor, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); + OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, + secure_fd); +} + +/******** Dangerous Tests - DO NOT RUN ***********/ +/*The following tests try to test InstallKeybox API with random buffers of +varying length in order to catch any overflow issues. These tests override the +actual keybox on the device. Remove the if and endif statement to run these +tests on a device ONLY IF YOU ARE ABLE TO RECOVER THE KEYBOX on the device.*/ +#if 0 +TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryInstallKeyboxForHugeKeyboxBuffer) { + auto f = [](size_t keybox_length) { + vector keybox(keybox_length); + memcpy(keybox.data(), &kTestKeybox, sizeof(kTestKeybox)); + return OEMCrypto_InstallKeyboxOrOEMCert(keybox.data(), keybox.size()); + }; + // Starting at sizeof(kTestKeybox) as we are copying valid keybox + // at beginning of generated buffers. + TestHugeLengthDoesNotCrashAPI(f, sizeof(kTestKeybox), kHugeInputBufferLength, + kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, + OEMCryptoMemoryInstallKeyboxForHugeKeyboxBufferStartingFromLength1) { + auto f = [](size_t keybox_length) { + vector keybox(keybox_length); + return OEMCrypto_InstallKeyboxOrOEMCert(keybox.data(), keybox.size()); + }; + // We are testing for keybox lengths starting from 1 which would return error, + // hence skipping status check. + TestHugeLengthDoesNotCrashAPI(f, !kCheckStatus); +} +#endif + +TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBuffer) { + auto f = [](size_t keybox_length) { + vector keybox(keybox_length); + memcpy(keybox.data(), &kTestKeybox, sizeof(kTestKeybox)); + return OEMCrypto_LoadTestKeybox(keybox.data(), keybox.size()); + }; + // Starting at sizeof(kTestKeybox) as we are copying valid keybox + // at beginning of generated buffers. + TestHugeLengthDoesNotCrashAPI(f, sizeof(kTestKeybox), kHugeInputBufferLength, + kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, + OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBufferStartingFromLength1) { + auto f = [](size_t keybox_length) { + vector keybox(keybox_length); + return OEMCrypto_LoadTestKeybox(keybox.data(), keybox.size()); + }; + // We are testing for keybox lengths starting from 1 which would return error, + // hence skipping status check. + TestHugeLengthDoesNotCrashAPI(f, !kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetDeviceIdForHugeIdLength) { + auto oemcrypto_function = [](size_t input_length) { + size_t device_id_length = input_length; + vector device_id(device_id_length); + return OEMCrypto_GetDeviceID(device_id.data(), &device_id_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetKeyIdForHugeIdLength) { + auto oemcrypto_function = [](size_t input_length) { + size_t key_data_length = input_length; + vector key_data(key_data_length); + return OEMCrypto_GetKeyData(key_data.data(), &key_data_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, + OEMCryptoMemoryGenerateDerivedKeysForHugeMacContextLength) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector mac_context; + vector enc_context; + s.FillDefaultContext(&mac_context, &enc_context); + + auto oemcrypto_function = [&s, &mac_context, + &enc_context](size_t buffer_length) { + mac_context.resize(buffer_length); + return OEMCrypto_GenerateDerivedKeys(s.session_id(), mac_context.data(), + mac_context.size(), enc_context.data(), + enc_context.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoKeyboxTest, + OEMCryptoMemoryGenerateDerivedKeysForHugeEncContextLength) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + vector mac_context; + vector enc_context; + s.FillDefaultContext(&mac_context, &enc_context); + + auto oemcrypto_function = [&s, &mac_context, + &enc_context](size_t buffer_length) { + enc_context.resize(buffer_length); + return OEMCrypto_GenerateDerivedKeys(s.session_id(), mac_context.data(), + mac_context.size(), enc_context.data(), + enc_context.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) { + if (wrapped_rsa_key_.size() == 0) { + // If we don't have a wrapped key yet, create one. + // This wrapped key will be shared by all sessions in the test. + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + } + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + // Install the DRM Cert's RSA key. + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); + ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey()); + + auto oemcrypto_function = [](size_t input_length) { + size_t public_cert_length = input_length; + vector public_cert(public_cert_length); + return OEMCrypto_GetOEMPublicCertificate(public_cert.data(), + &public_cert_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryCreateUsageTableHeaderForHugeHeaderBufferLength) { + auto oemcrypto_function = [](size_t buffer_length) { + size_t header_buffer_length = buffer_length; + vector usage_table_header(header_buffer_length); + return OEMCrypto_CreateUsageTableHeader(usage_table_header.data(), + &header_buffer_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoMemoryLicenseTest, + OEMCryptoMemoryPrepareRenewalRequestForHugeBufferLength) { + RenewalRoundTrip renewal_messages(&license_messages_); + auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { + renewal_messages.set_message_size(buffer_length); + return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoMemoryLicenseTest, + OEMCryptoMemoryPrepareRenewalRequestForHugeSignatureLength) { + RenewalRoundTrip renewal_messages(&license_messages_); + auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { + renewal_messages.set_request_signature_size(buffer_length); + return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoMemoryLicenseTest, + OEMCryptoMemoryPrepareRenewalRequestForHugeCoreMessageLength) { + RenewalRoundTrip renewal_messages(&license_messages_); + auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { + renewal_messages.set_core_message_size(buffer_length); + return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +// This verifies that entitled content keys API does not crash for unreasonable +// input message buffer lengths. +TEST_F(OEMCryptoMemoryLicenseTest, + OEMCryptoMemoryLoadEntitledKeysForHugeBufferLength) { + auto oemcrypto_function = [&](size_t buffer_length) { + size_t entitled_key_data_length = + entitled_message_.entitled_key_data_size(); + vector message(entitled_key_data_length); + memcpy(message.data(), entitled_message_.entitled_key_data(), + entitled_key_data_length); + message.resize(buffer_length); + return entitled_message_.LoadKeys(message); + }; + // We are not constructing a valid message for load entitled content keys. + // Hence skipping status check. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryLoadLicenseForHugeSignatureLength) { + auto oemcrypto_function = [&](size_t signature_size) { + Session s; + LicenseRoundTrip license_messages(&s); + s.open(); + InstallTestDrmKey(&s); + license_messages.SignAndVerifyRequest(); + license_messages.CreateDefaultResponse(); + license_messages.EncryptAndSignResponse(); + vector signature(signature_size); + OEMCryptoResult result = OEMCrypto_LoadLicense( + s.session_id(), license_messages.encrypted_response_buffer().data(), + license_messages.encrypted_response_buffer().size(), + license_messages.serialized_core_message().size(), signature.data(), + signature_size); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, OEMCryptoMemoryLoadRenewalForHugeResponseLength) { + auto oemcrypto_function = [&](size_t message_size) { + Session s; + LicenseRoundTrip license_messages(&s); + s.open(); + LoadLicense(s, license_messages); + + RenewalRoundTrip renewal_messages(&license_messages); + renewal_messages.SignAndVerifyRequest(); + renewal_messages.CreateDefaultResponse(); + renewal_messages.set_message_size(message_size); + renewal_messages.EncryptAndSignResponse(); + OEMCryptoResult result = renewal_messages.LoadResponse(); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryLoadRenewalForHugeSignatureLength) { + auto oemcrypto_function = [&](size_t signature_size) { + Session s; + LicenseRoundTrip license_messages(&s); + s.open(); + LoadLicense(s, license_messages); + + RenewalRoundTrip renewal_messages(&license_messages); + renewal_messages.SignAndVerifyRequest(); + renewal_messages.CreateDefaultResponse(); + renewal_messages.EncryptAndSignResponse(); + vector signature(signature_size); + OEMCryptoResult result = OEMCrypto_LoadRenewal( + s.session_id(), renewal_messages.encrypted_response_buffer().data(), + renewal_messages.encrypted_response_buffer().size(), + renewal_messages.serialized_core_message().size(), signature.data(), + signature_size); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryLoadRenewalForHugeCoreMessageLength) { + auto oemcrypto_function = [&](size_t core_message_size) { + Session s; + LicenseRoundTrip license_messages(&s); + s.open(); + LoadLicense(s, license_messages); + + RenewalRoundTrip renewal_messages(&license_messages); + renewal_messages.SignAndVerifyRequest(); + renewal_messages.CreateDefaultResponse(); + renewal_messages.set_core_message_size(core_message_size); + renewal_messages.EncryptAndSignResponse(); + OEMCryptoResult result = renewal_messages.LoadResponse(); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_id_length. +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryQueryKeyControlForHugeKeyIdLength) { + Session session; + LicenseRoundTrip license_messages(&session); + session.open(); + LoadLicense(session, license_messages); + OEMCrypto_SESSION session_id = session.session_id(); + vector valid_key_id( + license_messages.response_data().keys[0].key_id, + license_messages.response_data().keys[0].key_id + kTestKeyIdMaxLength); + auto oemcrypto_function = [&session_id, + &valid_key_id](size_t additional_key_id_length) { + vector key_id(valid_key_id); + key_id.resize(valid_key_id.size() + additional_key_id_length); + KeyControlBlock block; + size_t size = sizeof(block); + return OEMCrypto_QueryKeyControl(session_id, key_id.data(), key_id.size(), + reinterpret_cast(&block), &size); + }; + // We do not want to stop as soon as API results in an error as it would + // return error on first iteration as key_id is invalid. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_control_block +// length. +TEST_F(OEMCryptoSessionTests, + OEMCryptoMemoryQueryKeyControlForHugeKeyControlBlockLength) { + Session session; + LicenseRoundTrip license_messages(&session); + session.open(); + LoadLicense(session, license_messages); + OEMCrypto_SESSION session_id = session.session_id(); + uint8_t* key_id = license_messages.response_data().keys[0].key_id; + size_t key_id_length = license_messages.response_data().keys[0].key_id_length; + auto oemcrypto_function = [&session_id, &key_id, + &key_id_length](size_t buffer_length) { + size_t key_control_block_length = buffer_length; + vector key_control_block(key_control_block_length); + return OEMCrypto_QueryKeyControl(session_id, key_id, key_id_length, + key_control_block.data(), + &key_control_block_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +// This test verifies that OEMCrypto_SetDecryptHash doesn't crash for a very +// large hash buffer. +TEST_F(OEMCryptoMemoryLicenseTest, + OEMCryptoMemoryDecryptHashForHugeHashBuffer) { + uint32_t session_id = session_.session_id(); + auto f = [session_id](size_t hash_length) { + uint32_t frame_number = 1; + vector hash_buffer(hash_length); + return OEMCrypto_SetDecryptHash(session_id, frame_number, + hash_buffer.data(), hash_buffer.size()); + }; + TestHugeLengthDoesNotCrashAPI(f, kCheckStatus); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryDecryptCENCForHugeNumberOfSubSamples) { + auto oemcrypto_function = [&](size_t number_of_subsamples) { + std::vector subsample_sizes; + while (number_of_subsamples-- > 0) { + subsample_sizes.push_back({1, 1}); + } + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + OEMCryptoResult result = DecryptCENC(); + FreeSecureBuffers(); + // Closing the session and opening it for next iteration. + // If it is last iteration, session will be closed in teardown method of + // class. + session_.close(); + session_.open(); + InstallTestDrmKey(&session_); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); + + // Avoid double free when test teardown calls FreeSecureBuffers() + MakeBuffers(); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryDecryptCENCForHugeNumberOfSamples) { + auto oemcrypto_function = [&](size_t number_of_samples) { + std::vector> samples; + std::vector subsample_sizes; + subsample_sizes.push_back({1, 1}); + while (number_of_samples-- > 0) { + samples.push_back(subsample_sizes); + } + SetSampleSizes(samples); + LoadLicense(); + MakeBuffers(); + EncryptData(); + OEMCryptoResult result = DecryptCENC(); + FreeSecureBuffers(); + // Closing the session and opening it for next iteration. + // If it is last iteration, session will be closed in teardown method of + // class. + session_.close(); + session_.open(); + InstallTestDrmKey(&session_); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); + + // Avoid double free when test teardown calls FreeSecureBuffers() + MakeBuffers(); +} + +TEST_F(OEMCryptoLoadsCertificate, + OEMCryptoMemoryLoadProvisioningForHugeSignatureLength) { + auto oemcrypto_function = [&](size_t signature_size) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + provisioning_messages.SignAndVerifyRequest(); + provisioning_messages.CreateDefaultResponse(); + provisioning_messages.EncryptAndSignResponse(); + vector signature(signature_size); + size_t wrapped_private_key_length = 0; + // Find wrapped_private_key_length. + OEMCrypto_LoadProvisioning( + s.session_id(), + provisioning_messages.encrypted_response_buffer().data(), + provisioning_messages.encrypted_response_buffer().size(), + provisioning_messages.serialized_core_message().size(), + signature.data(), signature_size, nullptr, &wrapped_private_key_length); + std::vector wrapped_rsa_key(wrapped_private_key_length); + OEMCryptoResult result = OEMCrypto_LoadProvisioning( + s.session_id(), + provisioning_messages.encrypted_response_buffer().data(), + provisioning_messages.encrypted_response_buffer().size(), + provisioning_messages.serialized_core_message().size(), + signature.data(), signature_size, wrapped_rsa_key.data(), + &wrapped_private_key_length); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoLoadsCertificate, + OEMCryptoMemoryLoadProvisioningForHugeWrappedRsaKeyLength) { + auto oemcrypto_function = [&](size_t buffer_length) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + provisioning_messages.SignAndVerifyRequest(); + provisioning_messages.CreateDefaultResponse(); + provisioning_messages.EncryptAndSignResponse(); + size_t wrapped_private_key_length = buffer_length; + vector wrapped_private_key(wrapped_private_key_length); + OEMCryptoResult result = OEMCrypto_LoadProvisioning( + s.session_id(), + provisioning_messages.encrypted_response_buffer().data(), + provisioning_messages.encrypted_response_buffer().size(), + provisioning_messages.serialized_core_message().size(), + provisioning_messages.response_signature().data(), + provisioning_messages.response_signature().size(), + wrapped_private_key.data(), &wrapped_private_key_length); + s.close(); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoLoadsCertificate, + OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLength) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) { + Session s; + s.open(); + vector wrapped_rsa_key_buffer = wrapped_rsa_key_; + wrapped_rsa_key_buffer.resize(wrapped_rsa_key_length); + OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey( + s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size()); + s.close(); + return result; + }; + // It is hard to generate varying length valid wrapped rsa key with valid + // signature. Hence we just call function with random data and do not check + // status to test API with varying length wrapped rsa key. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, wrapped_rsa_key_.size(), + kHugeInputBufferLength, !kCheckStatus); +} + +TEST_F( + OEMCryptoLoadsCertificate, + OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLengthStartingFromLength1) { + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); + auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) { + Session s; + s.open(); + vector wrapped_rsa_key_buffer(wrapped_rsa_key_length); + OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey( + s.session_id(), OEMCrypto_RSA_Private_Key, + wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size()); + s.close(); + return result; + }; + // It is hard to generate varying length valid wrapped rsa key with valid + // signature. Hence we just call function with random data and do not check + // status to test API with varying length wrapped rsa key. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoUsesCertificate, + OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) { + vector session_key; + vector enc_session_key; + ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); + vector mac_context; + vector enc_context; + session_.FillDefaultContext(&mac_context, &enc_context); + OEMCrypto_SESSION session_id = session_.session_id(); + auto oemcrypto_function = [&session_id, &enc_context, &mac_context, + &enc_session_key](size_t buffer_length) { + mac_context.resize(buffer_length); + return OEMCrypto_DeriveKeysFromSessionKey( + session_id, enc_session_key.data(), enc_session_key.size(), + mac_context.data(), mac_context.size(), enc_context.data(), + enc_context.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoUsesCertificate, + OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) { + vector session_key; + vector enc_session_key; + ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); + vector mac_context; + vector enc_context; + session_.FillDefaultContext(&mac_context, &enc_context); + OEMCrypto_SESSION session_id = session_.session_id(); + auto oemcrypto_function = [&session_id, &enc_context, &mac_context, + &enc_session_key](size_t buffer_length) { + enc_context.resize(buffer_length); + return OEMCrypto_DeriveKeysFromSessionKey( + session_id, enc_session_key.data(), enc_session_key.size(), + mac_context.data(), mac_context.size(), enc_context.data(), + enc_context.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_F(OEMCryptoUsesCertificate, + OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) { + vector session_key; + vector enc_session_key; + ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); + vector mac_context; + vector enc_context; + session_.FillDefaultContext(&mac_context, &enc_context); + OEMCrypto_SESSION session_id = session_.session_id(); + auto oemcrypto_function = [&session_id, &session_key, &enc_context, + &mac_context, + &enc_session_key](size_t buffer_length) { + session_key.resize(buffer_length); + return OEMCrypto_DeriveKeysFromSessionKey( + session_id, enc_session_key.data(), enc_session_key.size(), + mac_context.data(), mac_context.size(), enc_context.data(), + enc_context.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_F(OEMCryptoLoadsCertificateAlternates, + OEMCryptoMemoryGenerateRSASignatureForHugeBuffer) { + OEMCryptoResult sts; + LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); + // If the device is a cast receiver, then this scheme is required. + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } + if (key_loaded_) { + // If the key did load, then it should be processed correctly. + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); + + vector message_buffer(10); + size_t signature_length = 0; + sts = OEMCrypto_GenerateRSASignature(s.session_id(), message_buffer.data(), + message_buffer.size(), nullptr, + &signature_length, kSign_PKCS1_Block1); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + ASSERT_NE(static_cast(0), signature_length); + vector signature(signature_length); + + auto oemcrypto_function = [&](size_t buffer_length) { + message_buffer.resize(buffer_length); + return OEMCrypto_GenerateRSASignature( + s.session_id(), message_buffer.data(), message_buffer.size(), + signature.data(), &signature_length, kSign_PKCS1_Block1); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); + s.close(); + } +} + +TEST_F(OEMCryptoLoadsCertificateAlternates, + OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) { + LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); + // If the device is a cast receiver, then this scheme is required. + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } + if (key_loaded_) { + // If the key did load, then it should be processed correctly. + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); + + vector message_buffer(50); + vector signature; + auto oemcrypto_function = [&](size_t signature_length) { + signature.resize(signature_length); + return OEMCrypto_GenerateRSASignature( + s.session_id(), message_buffer.data(), message_buffer.size(), + signature.data(), &signature_length, kSign_PKCS1_Block1); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); + s.close(); + } +} + +TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemorySelectKeyForHugeKeyIdLength) { + EncryptAndLoadKeys(); + OEMCrypto_SESSION session_id = session_.session_id(); + auto oemcrypto_function = [session_id](size_t key_id_length) { + vector key_id(key_id_length); + vector key_handle; + return GetKeyHandleIntoVector(session_id, key_id.data(), key_id.size(), + OEMCrypto_CipherMode_CENC, key_handle); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeyEncryptForHugeBuffer) { + EncryptAndLoadKeys(); + unsigned int key_index = 0; + vector expected_encrypted; + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + OEMCrypto_SESSION session_id = session_.session_id(); + auto& iv = iv_; + auto oemcrypto_function = [&session_id, &iv](size_t buffer_length) mutable { + vector buffer(buffer_length); + return OEMCrypto_Generic_Encrypt( + key_handle.data(), key_handle.size(), buffer.data(), buffer.size(), iv, + OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 16, kHugeInputBufferLength, + kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeyDecryptForHugeBuffer) { + EncryptAndLoadKeys(); + unsigned int key_index = 1; + vector key_handle; + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + OEMCrypto_SESSION session_id = session_.session_id(); + auto iv = iv_; + auto oemcrypto_function = [&session_id, &iv](size_t buffer_length) { + vector encrypted(buffer_length); + vector resultant(encrypted.size()); + + return OEMCrypto_Generic_Decrypt(key_handle.data(), key_handle.size(), + encrypted.data(), encrypted.size(), iv, + OEMCrypto_AES_CBC_128_NO_PADDING, + resultant.data()); + }; + // API expects length to be multiple of 16. Starting from 16. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 16, kHugeInputBufferLength, + kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemoryGenericKeySignForHugeBuffer) { + EncryptAndLoadKeys(); + unsigned int key_index = 2; + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC), + key_handle); + vector signature(SHA256_DIGEST_LENGTH); + size_t signature_length = signature.size(); + OEMCrypto_SESSION session_id = session_.session_id(); + auto oemcrypto_function = [&session_id, &signature, + &signature_length](size_t buffer_length) { + vector buffer(buffer_length); + return OEMCrypto_Generic_Sign( + key_handle.data(), key_handle.size(), buffer.data(), buffer.size(), + OEMCrypto_HMAC_SHA256, signature.data(), &signature_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeySignForHugeSignatureLength) { + EncryptAndLoadKeys(); + unsigned int key_index = 2; + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC), + key_handle); + OEMCrypto_SESSION session_id = session_.session_id(); + auto clear_buffer = clear_buffer_; + auto oemcrypto_function = [&session_id, + &clear_buffer](size_t signature_length) { + vector signature(signature_length); + size_t gen_signature_length = signature_length; + return OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer.data(), clear_buffer.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + &gen_signature_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeyVerifyForHugeBuffer) { + EncryptAndLoadKeys(); + unsigned int key_index = 3; + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + auto oemcrypto_function = [&](size_t buffer_length) { + vector buffer(buffer_length); + vector signature; + SignBuffer(key_index, buffer, &signature); + return GenericVerify(key_handle.data(), key_handle.size(), buffer.data(), + buffer.size(), OEMCrypto_HMAC_SHA256, signature.data(), + signature.size()); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoGenericCryptoTest, + OEMCryptoMemoryGenericKeyVerifyForHugeSignatureLength) { + EncryptAndLoadKeys(); + unsigned int key_index = 3; + vector signature; + SignBuffer(key_index, clear_buffer_, &signature); + + vector key_handle; + ASSERT_EQ( + OEMCrypto_SUCCESS, + GetKeyHandleIntoVector(session_.session_id(), + session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle)); + OEMCrypto_SESSION session_id = session_.session_id(); + auto clear_buffer = clear_buffer_; + auto oemcrypto_function = [&session_id, &clear_buffer, + &signature](size_t signature_length) { + return OEMCrypto_Generic_Verify(key_handle.data(), key_handle.size(), + clear_buffer.data(), clear_buffer.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + signature_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryUpdateUsageEntryForHugeHeaderBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + if (buffer_length < encrypted_usage_header_.size()) { + return OEMCrypto_ERROR_SHORT_BUFFER; + } + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + size_t header_buffer_length = 0; + size_t entry_buffer_length = 0; + // Header buffer length varies as generation_numbers size changes on every + // call. Hence, we need to call update usage entry in every loop to get + // latest value of header_buffer_length. + OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, + nullptr, &entry_buffer_length); + vector encrypted_usage_entry(entry_buffer_length); + vector header_buffer(encrypted_usage_header_); + header_buffer.resize(buffer_length); + return OEMCrypto_UpdateUsageEntry( + s.session_id(), header_buffer.data(), &buffer_length, + encrypted_usage_entry.data(), &entry_buffer_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryUpdateUsageEntryForHugeUsageEntryBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + size_t header_buffer_length = 0; + size_t entry_buffer_length = 0; + // Header buffer length varies as generation_numbers size changes on every + // call. Hence, we need to call update usage entry in every loop to get + // latest value of header_buffer_length. + OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, + nullptr, &entry_buffer_length); + vector header_buffer(encrypted_usage_header_); + header_buffer.resize(header_buffer_length); + vector encrypted_usage_entry(buffer_length); + return OEMCrypto_UpdateUsageEntry( + s.session_id(), header_buffer.data(), &header_buffer_length, + encrypted_usage_entry.data(), &buffer_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryDeactivateUsageEntryForHugePstBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + std::string pst("pst"); + pst.resize(buffer_length); + entry.license_messages().set_pst(pst); + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + return OEMCrypto_DeactivateUsageEntry( + s.session_id(), reinterpret_cast(pst.c_str()), + pst.length()); + }; + // The test setup assertions fails if pst length goes beyond kMaxPSTLength. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, kMaxPSTLength, + kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryLoadUsageTableHeaderForHugeHeader) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + if (buffer_length < encrypted_usage_header_.size()) { + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + vector header_buffer(encrypted_usage_header_); + header_buffer.resize(buffer_length); + return OEMCrypto_LoadUsageTableHeader(header_buffer.data(), + header_buffer.size()); + }; + // We cannot generate an encrypted usage header of varying length with + // valid signature. Hence irrespective of return status, we call API for + // varying buffer lengths. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, + encrypted_usage_header_.size(), + kHugeInputBufferLength, !kCheckStatus); +} + +TEST_P( + OEMCryptoUsageTableTest, + OEMCryptoMemoryLoadUsageTableHeaderForHugeHeaderStartingHeaderLengthFrom1) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + vector header_buffer(buffer_length); + return OEMCrypto_LoadUsageTableHeader(header_buffer.data(), + header_buffer.size()); + }; + // We cannot generate an encrypted usage header of varying length with + // valid signature. Hence irrespective of return status, we call API for + // varying buffer lengths. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryLoadUsageEntryForHugeUsageEntryBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + Session& s = entry.session(); + // Make first entry 0. + entry.MakeOfflineAndClose(this); + if (buffer_length < s.encrypted_usage_entry().size()) { + return OEMCrypto_ERROR_SHORT_BUFFER; + } + Session s2; + s2.open(); + InstallTestDrmKey(&s2); + vector encrypted_usage_entry(buffer_length); + memcpy(encrypted_usage_entry.data(), s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size()); + const uint32_t usage_entry_number = s.usage_entry_number(); + return OEMCrypto_LoadUsageEntry(s2.session_id(), usage_entry_number, + encrypted_usage_entry.data(), + encrypted_usage_entry.size()); + }; + // We cannot generate an encrypted usage enctry of varying length with + // valid signature. Hence irrespective of return status, we call API for + // varying buffer lengths. + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugeReportBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + s.UpdateUsageEntry(&encrypted_usage_header_); + size_t length = 0; + OEMCrypto_ReportUsage(s.session_id(), + reinterpret_cast(entry.pst().c_str()), + entry.pst().length(), nullptr, &length); + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_report_usage_fuzz_seed_corpus"); + AppendToFile(file_name, reinterpret_cast(&length), + sizeof(length)); + AppendToFile(file_name, entry.pst().c_str(), entry.pst().length()); + } + vector pst_report_buffer(buffer_length); + return OEMCrypto_ReportUsage( + s.session_id(), reinterpret_cast(entry.pst().c_str()), + entry.pst().length(), pst_report_buffer.data(), &buffer_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugePstBuffer) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + s.UpdateUsageEntry(&encrypted_usage_header_); + size_t length = 0; + OEMCrypto_ReportUsage(s.session_id(), + reinterpret_cast(entry.pst().c_str()), + entry.pst().length(), nullptr, &length); + vector pst_report_buffer(length); + vector pst(buffer_length); + return OEMCrypto_ReportUsage(s.session_id(), pst.data(), pst.size(), + pst_report_buffer.data(), &length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); +} + +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryShrinkUsageTableHeaderForHugeHeaderBufferLength) { + if (!wvoec::global_features.usage_table) { + GTEST_SKIP() << "Usage tables are not supported."; + } + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + auto oemcrypto_function = [&](size_t buffer_length) { + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + size_t header_buffer_length = buffer_length; + encrypted_usage_header_.resize(header_buffer_length); + return OEMCrypto_ShrinkUsageTableHeader(1, encrypted_usage_header_.data(), + &header_buffer_length); + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); +} +/// @} + +} // namespace wvoec diff --git a/oemcrypto/test/oemcrypto_security_tests.gypi b/oemcrypto/test/oemcrypto_security_tests.gypi new file mode 100644 index 00000000..fda1b75d --- /dev/null +++ b/oemcrypto/test/oemcrypto_security_tests.gypi @@ -0,0 +1,69 @@ +# Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +# source code may only be used and distributed under the Widevine License +# Agreement. +# +# Include this in any custom security test targets. +# Does not include the test runner main. +{ + 'variables': { + 'test_opk_serialization_version%' : 'false', + 'static_libcpp%' : 'false', + }, + 'sources': [ + 'oec_device_features.cpp', + 'oec_decrypt_fallback_chain.cpp', + 'oec_key_deriver.cpp', + 'oec_session_util.cpp', + 'oemcrypto_corpus_generator_helper.cpp', + 'oemcrypto_session_tests_helper.cpp', + 'oemcrypto_security_test.cpp', + ], + 'conditions': [ + ['test_opk_serialization_version=="true"', { + 'sources+' : [ + 'oemcrypto_serialization_version_test.cpp', + ], + }], + ['static_libcpp=="true"', { + 'ldflags+':[ + '-static-libstdc++', + ], + }], + ], + 'include_dirs': [ + '<(util_dir)/include', + '<(util_dir)/test', + '<(oemcrypto_dir)/include', + '<(oemcrypto_dir)/ref/src', + '<(oemcrypto_dir)/test', + '<(oemcrypto_dir)/test/fuzz_tests', + '<(oemcrypto_dir)/odk/include', + '<(oemcrypto_dir)/util/include', + ], + 'defines': [ + 'OEMCRYPTO_TESTS', + ], + 'conditions': [ + ['support_ota_keybox_functions=="true"', { + 'sources': [ + '<(oemcrypto_dir)/test/ota_keybox_test.cpp', + ], + }], + ['generate_code_coverage_report=="true"', { + # Include flags to generate source based code coverage reports. + 'cflags': [ + '-fprofile-instr-generate', + '-fcoverage-mapping', + ], + 'ldflags': [ + '-fprofile-instr-generate', + '-fcoverage-mapping', + ], + }], + ], + 'dependencies': [ + '<(oemcrypto_dir)/odk/src/odk.gyp:odk', + '<(oemcrypto_dir)/util/oec_ref_util.gyp:oec_ref_util', + ], + 'includes': [ '../../util/libssl_dependency.gypi' ], +} diff --git a/oemcrypto/test/oemcrypto_serialization_version_test.cpp b/oemcrypto/test/oemcrypto_serialization_version_test.cpp index 31bfacb5..9bc71ec5 100644 --- a/oemcrypto/test/oemcrypto_serialization_version_test.cpp +++ b/oemcrypto/test/oemcrypto_serialization_version_test.cpp @@ -9,6 +9,7 @@ #include "OEMCryptoCENC.h" #include "log.h" +#include "odk_structs.h" #include "oec_test_data.h" using namespace std; @@ -26,6 +27,7 @@ class OEMCryptoTest : public ::testing::Test { LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name()); OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + OEMCrypto_EnterTestMode(); } void TearDown() override { diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.cpp b/oemcrypto/test/oemcrypto_session_tests_helper.cpp index f84e37c2..2a3d5250 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.cpp +++ b/oemcrypto/test/oemcrypto_session_tests_helper.cpp @@ -20,16 +20,23 @@ const uint8_t* find(const vector& message, return &(*pos); } -// This creates a wrapped RSA key. -void SessionUtil::CreateWrappedRSAKey() { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - wrapped_rsa_key_ = provisioning_messages.wrapped_rsa_key(); +void SessionUtil::CreateWrappedDRMKey() { + if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { + // Have the device create a wrapped key. + CreateProv4DRMKey(); + } else { + // Create a wrapped RSA key from encoded_rsa_key_. + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); + wrapped_drm_key_ = provisioning_messages.wrapped_rsa_key(); + drm_key_type_ = OEMCrypto_RSA_Private_Key; + drm_public_key_.clear(); + } } void SessionUtil::InstallKeybox(const wvoec::WidevineKeybox& keybox, @@ -48,7 +55,7 @@ void SessionUtil::InstallKeybox(const wvoec::WidevineKeybox& keybox, } } -void SessionUtil::EnsureTestKeys() { +void SessionUtil::EnsureTestROT() { switch (global_features.derive_key_method) { case DeviceFeatures::LOAD_TEST_KEYBOX: keybox_ = kTestKeybox; @@ -73,51 +80,132 @@ void SessionUtil::EnsureTestKeys() { // This makes sure that the derived keys (encryption key and two mac keys) // are installed in OEMCrypto and in the test session. -void SessionUtil::InstallTestRSAKey(Session* s) { - if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { - if (wrapped_rsa_key_.size() == 0) { +void SessionUtil::InstallTestDrmKey(Session* s) { + if (global_features.loads_certificate) { + if (wrapped_drm_key_.size() == 0) { // If we don't have a wrapped key yet, create one. // This wrapped key will be shared by all sessions in the test. - const size_t buffer_size = 5000; // Make sure it is large enough. - std::vector public_key(buffer_size); - size_t public_key_size = buffer_size; - std::vector public_key_signature(buffer_size); - size_t public_key_signature_size = buffer_size; - std::vector wrapped_private_key(buffer_size); - size_t wrapped_private_key_size = buffer_size; - OEMCrypto_PrivateKeyType key_type; - // Assume OEM cert has been loaded. - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GenerateCertificateKeyPair( - s->session_id(), public_key.data(), &public_key_size, - public_key_signature.data(), &public_key_signature_size, - wrapped_private_key.data(), &wrapped_private_key_size, - &key_type)); - // Assume the public key has been verified by the server and the DRM cert - // is returned. - wrapped_private_key.resize(wrapped_private_key_size); - public_key.resize(public_key_size); - wrapped_rsa_key_ = wrapped_private_key; - drm_public_key_ = public_key; - key_type_ = key_type; + ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey()); } - ASSERT_NO_FATAL_FAILURE(s->LoadWrappedDrmKey(key_type_, wrapped_rsa_key_)); - ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromSubjectPublicKey( - key_type_, drm_public_key_.data(), drm_public_key_.size())); - return; + // Load the wrapped drm test key. + ASSERT_NO_FATAL_FAILURE( + s->LoadWrappedDrmKey(drm_key_type_, wrapped_drm_key_)); + if (drm_public_key_.size() > 0) { + ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromSubjectPublicKey( + drm_key_type_, drm_public_key_.data(), drm_public_key_.size())); + } else { + ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromPrivateKeyInfo( + drm_key_type_, encoded_rsa_key_.data(), encoded_rsa_key_.size())); + } + } else { + // Test RSA key should be loaded. + ASSERT_NO_FATAL_FAILURE(s->SetTestRsaPublicKey()); + } +} + +// Generate OEM key pair, craft a provisioning 4.0 OEM cert request, sign it +// with the OEM private key and verify the signature. Finally, install OEM +// private to session s. +void SessionUtil::CreateProv4OEMKey(Session* s) { + ASSERT_NE(s, nullptr); + if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) { + FAIL() << "Provisioning 4.0 is required."; + } + Provisioning40RoundTrip provisioning_messages(s); + // Generate key pair. + ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(true)); + // Need OEM public key to verify the signed request. + ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromSubjectPublicKey( + provisioning_messages.oem_key_type(), + provisioning_messages.oem_public_key().data(), + provisioning_messages.oem_public_key().size())); + // Save the generated keys, which will be used by DRM cert provisioning later. + wrapped_oem_key_ = provisioning_messages.wrapped_oem_key(); + oem_public_key_ = provisioning_messages.oem_public_key(); + oem_key_type_ = provisioning_messages.oem_key_type(); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + // Install OEM private key into the session. + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadOEMCertResponse()); +} + +// Generate DRM key pair, craft a provisioning 4.0 DRM cert request, sign it +// with the OEM private key and verify the signature. Finally, install DRM +// private to session s. An OEM cert needs to be installed first. It is also +// done in this function. +void SessionUtil::CreateProv4DRMKey() { + if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) { + FAIL() << "Provisioning 4.0 is required."; + } + // Provision OEM key first. + if (wrapped_oem_key_.size() == 0) { + Session oem_session; + ASSERT_NO_FATAL_FAILURE(oem_session.open()); + ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&oem_session)); + } + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_InstallOemPrivateKey( + s.session_id(), oem_key_type_, + reinterpret_cast(wrapped_oem_key_.data()), + wrapped_oem_key_.size())); + ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey( + oem_key_type_, oem_public_key_.data(), oem_public_key_.size())); + + // Provision DRM key. + Provisioning40RoundTrip provisioning_messages(&s); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(false)); + // Need DRM public key to verify DRM request signature. + ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey( + provisioning_messages.drm_key_type(), + provisioning_messages.drm_public_key().data(), + provisioning_messages.drm_public_key().size())); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadDRMCertResponse()); + wrapped_drm_key_ = provisioning_messages.wrapped_drm_key(); + drm_key_type_ = provisioning_messages.drm_key_type(); + drm_public_key_ = provisioning_messages.drm_public_key(); +} + +// Requires stage 1 prov4 to be complete, ie OEM key is available +void SessionUtil::CreateProv4CastKey(Session* s, + bool load_drm_before_prov_req) { + if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) { + FAIL() << "Provisioning 4.0 is required."; } - if (global_features.loads_certificate) { - if (wrapped_rsa_key_.size() == 0) { - // If we don't have a wrapped key yet, create one. - // This wrapped key will be shared by all sessions in the test. - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - } - // Load the wrapped rsa test key. - ASSERT_NO_FATAL_FAILURE(s->LoadWrappedRsaDrmKey(wrapped_rsa_key_)); + Provisioning40CastRoundTrip prov_cast(s, encoded_rsa_key_); + + // Calls GenerateCertificateKeyPair(). Generated keys stored in + // prov_cast.drm_public_key_ and prov_cast.wrapped_drm_key_ + ASSERT_NO_FATAL_FAILURE(prov_cast.PrepareSession()); + + // Can choose to load DRM key before preparing the provisioning request, or + // after + if (load_drm_before_prov_req) { + ASSERT_NO_FATAL_FAILURE(prov_cast.LoadDRMPrivateKey()); } - // Test RSA key should be loaded. - ASSERT_NO_FATAL_FAILURE(s->SetTestRsaPublicKey()); + ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromSubjectPublicKey( + prov_cast.drm_key_type(), prov_cast.drm_public_key().data(), + prov_cast.drm_public_key().size())); + ASSERT_NO_FATAL_FAILURE(prov_cast.SignAndVerifyRequest()); + if (!load_drm_before_prov_req) { + ASSERT_NO_FATAL_FAILURE(prov_cast.LoadDRMPrivateKey()); + } + + // Generate derived keys in order to verify and decrypt response. + // We are cheating a little bit here since this GenerateDerivedKeys helper + // simulates work on both client side (calls + // OEMCrypto_GenerateDerivedKeysFromSessionKey) and server side (sets + // key_deriver() keys used to create response) + ASSERT_NO_FATAL_FAILURE(s->GenerateDerivedKeysFromSessionKey()); + + // Response is provisioning 2 with CAST key + ASSERT_NO_FATAL_FAILURE(prov_cast.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(prov_cast.EncryptAndSignResponse()); + + // Should parse and load successfully + ASSERT_EQ(OEMCrypto_SUCCESS, prov_cast.LoadResponse()); } } // namespace wvoec diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.h b/oemcrypto/test/oemcrypto_session_tests_helper.h index 6ceb03a4..1b352392 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.h +++ b/oemcrypto/test/oemcrypto_session_tests_helper.h @@ -1,3 +1,6 @@ +#ifndef CDM_OEMCRYPTO_SESSION_TESTS_HELPER_ +#define CDM_OEMCRYPTO_SESSION_TESTS_HELPER_ + #include #include #include @@ -17,8 +20,10 @@ class SessionUtil { kTestRSAPKCS8PrivateKeyInfo2_2048 + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)) {} - // Create a new wrapped DRM Certificate. - void CreateWrappedRSAKey(); + // Create a new wrapped DRM Certificate. This creates a new one, even if one + // already exists. For provisioning 2 or 3, it uses encoded_rsa_key_ to + // specify the key. For Prov 4.0, the key is generated by OEMCrypto. + void CreateWrappedDRMKey(); // This is used to force installation of a keybox. This overwrites the // production keybox -- it does NOT use OEMCrypto_LoadTestKeybox. @@ -26,15 +31,33 @@ class SessionUtil { // This loads the test keybox or the test RSA key, using LoadTestKeybox or // LoadTestRSAKey as needed. - void EnsureTestKeys(); + void EnsureTestROT(); - void InstallTestRSAKey(Session* s); + // Install a DRM private key in to the session. If a key has not been created, + // tehn CreateWrappedDRMKey is used to create one first. Works with Prov 2-4. + void InstallTestDrmKey(Session* s); + // Create and install an OEM Cert private key. After creation, the key is + // saved to oem_public_key_. Only for provisioning 4.0 + void CreateProv4OEMKey(Session* s); + + // Create a new DRM Cert. Only for provisioning 4.0 + void CreateProv4DRMKey(); + + void CreateProv4CastKey(Session *s, bool load_drm_before_prov_req); + + // Used by prov2.0, prov3.0, and prov 4.0 std::vector encoded_rsa_key_; - std::vector wrapped_rsa_key_; - OEMCrypto_PrivateKeyType key_type_; + std::vector wrapped_drm_key_; + OEMCrypto_PrivateKeyType drm_key_type_; std::vector drm_public_key_; wvoec::WidevineKeybox keybox_; + + // Used by prov4.0 + std::vector wrapped_oem_key_; + std::vector oem_public_key_; + OEMCrypto_PrivateKeyType oem_key_type_; }; } // namespace wvoec +#endif // CDM_OEMCRYPTO_SESSION_TESTS_HELPER_ diff --git a/oemcrypto/test/oemcrypto_test.cpp b/oemcrypto/test/oemcrypto_test.cpp index 6a8356ae..4452e939 100644 --- a/oemcrypto/test/oemcrypto_test.cpp +++ b/oemcrypto/test/oemcrypto_test.cpp @@ -12,6 +12,11 @@ * @defgroup basic Basic Functionality Tests * Basic functionality tests. * + * @defgroup provision Provisioning Tests + * Test for provisioning and certificate key processing. These tests cover + * Provsioning 2.0, 3.0 and 4.0. Tests for the wrong provisioning scheme should + * be skipped. + * * @defgroup license License Request Tests * Test for requesting and loading licenses. * @@ -23,6 +28,21 @@ * * @defgroup usage_table Usage Table Tests * Tests that use the usage table. + * + * @defgroup entitle Entitlement License tests + * Tests for entitlement licenses. + * + * @defgroup cas Conditional Access System Tests + * Tests for OEMCrypto implementations that support MediaCAS. + * + * @defgroup cast Cast Test + * Tests for OEMCrypto implementations that support being a Cast receiver. + * + * @defgroup generic Generic Crypto Tests + * Tests for the Generic Crypto functionality. + * + * @defgroup security Security Tests + * Buffer overflow tests, off-by-one tests, and other security tests. */ #include @@ -53,20 +73,22 @@ #include "oec_extra_test_keys.h" #include "oec_session_util.h" #include "oec_test_data.h" +#include "oemcrypto_basic_test.h" #include "oemcrypto_corpus_generator_helper.h" #include "oemcrypto_fuzz_structs.h" +#include "oemcrypto_license_test.h" +#include "oemcrypto_provisioning_test.h" +#include "oemcrypto_resource_test.h" #include "oemcrypto_session_tests_helper.h" #include "oemcrypto_types.h" +#include "oemcrypto_usage_table_test.h" #include "platform.h" #include "string_conversions.h" #include "test_sleep.h" #include "wvcrc32.h" -using ::testing::Bool; -using ::testing::Combine; using ::testing::Range; using ::testing::tuple; -using ::testing::Values; using ::testing::WithParamInterface; using namespace std; @@ -101,1614 +123,10 @@ void PrintTo(const tuple -T GetResourceValue(T (&resource_values)[N]) { - if (global_features.resource_rating < 1) return resource_values[0]; - if (global_features.resource_rating > N) return resource_values[N - 1]; - return resource_values[global_features.resource_rating - 1]; -} - -// Used for testing oemcrypto APIs with huge buffers. -typedef const std::function oemcrypto_function; -// Function to test APIs that expect a buffer length as input -// by passing huge buffer lengths upto end_buffer_length and test that the API -// doesn't crash. -void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, - size_t start_buffer_length, - size_t end_buffer_length, - bool check_status) { - OEMCryptoResult sts = OEMCrypto_SUCCESS; - for (size_t buffer_length = start_buffer_length; - buffer_length < end_buffer_length && - (sts == OEMCrypto_SUCCESS || sts == OEMCrypto_ERROR_SHORT_BUFFER || - !check_status); - buffer_length *= 2) { - sts = f(buffer_length); - if (check_status && sts != OEMCrypto_SUCCESS && - sts != OEMCrypto_ERROR_SHORT_BUFFER) { - LOGI("Test exits huge buffer loop for length:%zu, status:%d", - buffer_length, sts); - } - } -} - -// Function to test APIs that expect a buffer length as input -// by passing huge buffer lengths upto kHugeInputBufferLength and test that -// the API doesn't crash. -void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, bool check_status) { - TestHugeLengthDoesNotCrashAPI(f, 1, kHugeInputBufferLength, check_status); -} - -// After API 16, we require 300 entries in the usage table. Before API 16, we -// required 200. -size_t RequiredUsageSize() { - return global_features.api_version < 16 ? 200 : 300; -} - -// These are the maximum sizes we test. That means it is the minimum size that -// OEMCrypto must support. -// clang-format off -const size_t kMaxSampleSize[] = { 1*MiB, 2*MiB, 4*MiB, 16*MiB}; -const size_t kMaxNumberSubsamples[] = { 10, 16, 32, 64}; -const size_t kMaxSubsampleSize[] = { 100*KiB, 500*KiB, 1*MiB, 4*MiB}; -const size_t kMaxGenericBuffer[] = { 10*KiB, 100*KiB, 500*KiB, 1*MiB}; -const size_t kMaxConcurrentSession[] = { 10, 20, 30, 40}; -const size_t kMaxKeysPerSession[] = { 4, 20, 20, 30}; -const size_t kMaxTotalKeys[] = { 16, 40, 80, 90}; -const size_t kLargeMessageSize[] = { 8*KiB, 8*KiB, 16*KiB, 32*KiB}; -const size_t kMaxTotalDRMPrivateKeys[] = { 2, 4, 6, 8}; -// Note: Frame rate and simultaneous playback are specified by resource rating, -// but are tested at the system level, so there are no unit tests for frame -// rate. Similarly, number of subsamples for AV1 -// const size_t kAV1NumberSubsamples[] = { 72, 144, 288, 576}; -// clang-format on - -// Return a printable string from data. If all the characters are printable, -// then just use the string. Otherwise, convert to hex. -std::string MaybeHex(const uint8_t* data, size_t length) { - for (size_t i = 0; i < length; i++) { - if (!isprint(data[i])) return "0x" + wvutil::HexEncode(data, length); - } - return std::string(reinterpret_cast(data), length); -} -std::string MaybeHex(const std::vector& data) { - return MaybeHex(data.data(), data.size()); -} -} // namespace - -class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { - protected: - OEMCryptoClientTest() {} - - void SetUp() override { - ::testing::Test::SetUp(); - wvutil::TestSleep::SyncFakeClock(); - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name()); - OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); - } - - void TearDown() override { - OEMCrypto_Terminate(); - ::testing::Test::TearDown(); - } - - const uint8_t* find(const vector& message, - const vector& substring) { - vector::const_iterator pos = search( - message.begin(), message.end(), substring.begin(), substring.end()); - if (pos == message.end()) { - return nullptr; - } - return &(*pos); - } - - OEMCryptoResult CopyBuffer( - OEMCrypto_SESSION session, OEMCrypto_SharedMemory* input_buffer, - size_t input_buffer_size, - const OEMCrypto_DestBufferDesc* dest_buffer_descriptor, - uint8_t subsample_flags) { - if (ShouldGenerateCorpus() && input_buffer != nullptr && - dest_buffer_descriptor != nullptr) { - const std::string file_name = - GetFileName("oemcrypto_copy_buffer_fuzz_seed_corpus"); - - OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure; - fuzzed_structure.dest_buffer_desc.type = dest_buffer_descriptor->type; - switch (fuzzed_structure.dest_buffer_desc.type) { - case OEMCrypto_BufferType_Clear: - fuzzed_structure.dest_buffer_desc.buffer_config = - dest_buffer_descriptor->buffer.clear.clear_buffer_length; - break; - - case OEMCrypto_BufferType_Secure: - fuzzed_structure.dest_buffer_desc.buffer_config = - dest_buffer_descriptor->buffer.secure.secure_buffer_length; - break; - - case OEMCrypto_BufferType_Direct: - fuzzed_structure.dest_buffer_desc.buffer_config = - dest_buffer_descriptor->buffer.direct.is_video; - break; - } - fuzzed_structure.subsample_flags = subsample_flags; - - // Corpus for copy buffer fuzzer should be in the format: - // (dest_buffer_descriptor | subsample_flags | input_buffer). - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, reinterpret_cast(&input_buffer), - input_buffer_size); - } - return OEMCrypto_CopyBuffer(session, input_buffer, input_buffer_size, - dest_buffer_descriptor, subsample_flags); - } -}; - -TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { - Session s; - s.open(); - OEMCrypto_DestBufferDesc output_descriptor; - int secure_fd = kHugeRandomNumber; - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_FreeSecureBuffer(s.session_id(), &output_descriptor, - secure_fd)); - s.close(); -} - -/// @addtogroup basic +/// @addtogroup security /// @{ -/** - * Verifies initialization and logs version information. - * This test is first, because it might give an idea why other - * tests are failing when the device has the wrong keybox installed. - */ -TEST_F(OEMCryptoClientTest, VersionNumber) { - const std::string log_message = - "OEMCrypto unit tests for API 17.1. Tests last updated 2022-06-17"; - cout << " " << log_message << "\n"; - cout << " " - << "These tests are part of Android T." - << "\n"; - LOGI("%s", log_message.c_str()); - // If any of the following fail, then it is time to update the log message - // above. - EXPECT_EQ(ODK_MAJOR_VERSION, 17); - EXPECT_EQ(ODK_MINOR_VERSION, 2); - EXPECT_EQ(kCurrentAPI, 17u); - OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); - EXPECT_GT(level, OEMCrypto_Level_Unknown); - EXPECT_LE(level, OEMCrypto_Level3); - cout << " OEMCrypto Security Level is L" << level << endl; - uint32_t version = OEMCrypto_APIVersion(); - uint32_t minor_version = OEMCrypto_MinorAPIVersion(); - cout << " OEMCrypto API version is " << version << "." - << minor_version << endl; - if (OEMCrypto_SupportsUsageTable()) { - cout << " OEMCrypto supports usage tables" << endl; - } else { - cout << " OEMCrypto does not support usage tables" << endl; - } - if (version >= 15) { - const uint32_t tier = OEMCrypto_ResourceRatingTier(); - cout << " Resource Rating Tier: " << tier << endl; - } - if (version >= 17) { - OEMCryptoResult sts = OEMCrypto_ProductionReady(); - if (sts != OEMCrypto_SUCCESS) { - LOGW("Device is not production ready, returns %d", sts); - } - sts = OEMCrypto_SUCCESS; - std::string build_info; - size_t buf_length = 0; - sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - build_info.resize(buf_length); - sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length); - } - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - if (build_info.size() != buf_length) { - build_info.resize(buf_length); - } - cout << " BuildInformation: " << build_info << endl; - OEMCrypto_WatermarkingSupport support = OEMCrypto_GetWatermarkingSupport(); - cout << " WatermarkingSupport: " << support << endl; - } - ASSERT_GE(version, 8u); - ASSERT_LE(version, kCurrentAPI); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryAllocateSecureBufferForHugeBufferSize) { - Session s; - s.open(); - auto oemcrypto_function = [&s](size_t buffer_size) { - OEMCrypto_DestBufferDesc output_descriptor; - int secure_fd; - OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( - s.session_id(), buffer_size, &output_descriptor, &secure_fd); - if (sts == OEMCrypto_SUCCESS) { - OEMCrypto_FreeSecureBuffer(s.session_id(), &output_descriptor, secure_fd); - } - return sts; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); - s.close(); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLength) { - auto oemcrypto_function = [](size_t keybox_length) { - vector keybox_buffer(keybox_length); - size_t wrapped_keybox_length = keybox_length + 50; - vector wrapped_keybox_buffer(wrapped_keybox_length); - vector transport_key_buffer(20); - memcpy(keybox_buffer.data(), &kTestKeybox, sizeof(kTestKeybox)); - return OEMCrypto_WrapKeyboxOrOEMCert( - keybox_buffer.data(), keybox_length, wrapped_keybox_buffer.data(), - &wrapped_keybox_length, transport_key_buffer.data(), - transport_key_buffer.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, sizeof(kTestKeybox), - kHugeInputBufferLength, kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeWrappedKeyboxLength) { - auto oemcrypto_function = [](size_t buffer_length) { - size_t wrapped_keybox_length = buffer_length; - vector wrapped_keybox_buffer(wrapped_keybox_length); - vector transport_key_buffer(20); - return OEMCrypto_WrapKeyboxOrOEMCert( - reinterpret_cast(&kTestKeybox), sizeof(kTestKeybox), - wrapped_keybox_buffer.data(), &wrapped_keybox_length, - transport_key_buffer.data(), transport_key_buffer.size()); - }; - // API expects keybox length and wrapped keybox length to be equal. We would - // like to test for various values of wrapped keybox lengths, hence skipping - // status check. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeTransportKey) { - auto oemcrypto_function = [](size_t transport_key_length) { - size_t wrapped_keybox_length = sizeof(&kTestKeybox) + 50; - vector wrapped_keybox_buffer(wrapped_keybox_length); - vector transport_key_buffer(transport_key_length); - return OEMCrypto_WrapKeyboxOrOEMCert( - reinterpret_cast(&kTestKeybox), sizeof(kTestKeybox), - wrapped_keybox_buffer.data(), &wrapped_keybox_length, - transport_key_buffer.data(), transport_key_buffer.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F( - OEMCryptoClientTest, - OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLengthStartingFromLength1) { - auto oemcrypto_function = [](size_t keybox_length) { - vector keybox_buffer(keybox_length); - size_t wrapped_keybox_length = keybox_length + 50; - vector wrapped_keybox_buffer(wrapped_keybox_length); - vector transport_key_buffer(20); - return OEMCrypto_WrapKeyboxOrOEMCert( - keybox_buffer.data(), keybox_length, wrapped_keybox_buffer.data(), - &wrapped_keybox_length, transport_key_buffer.data(), - transport_key_buffer.size()); - }; - // Cannot check status as keybox will not be valid for this test. - // We still want to test what happens if buffer lengths is less that keybox - // length. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -/** - * The resource rating is a number from 1 to 4. The first three levels - * were initially defined in API 15 and they were expanded in API 16. - */ -TEST_F(OEMCryptoClientTest, ResourceRatingAPI15) { - ASSERT_GE(OEMCrypto_ResourceRatingTier(), 1u); - ASSERT_LE(OEMCrypto_ResourceRatingTier(), 4u); -} - -/** - * OEMCrypto must declare what type of provisioning scheme it uses. - */ -TEST_F(OEMCryptoClientTest, ProvisioningDeclaredAPI12) { - OEMCrypto_ProvisioningMethod provisioning_method = - OEMCrypto_GetProvisioningMethod(); - cout << " Provisioning method = " - << ProvisioningMethodName(provisioning_method) << endl; - ASSERT_NE(OEMCrypto_ProvisioningError, provisioning_method); -} - -const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) { - switch (value) { - case HDCP_NONE: - return "No HDCP supported, no secure data path"; - case HDCP_V1: - return "HDCP version 1.x"; - case HDCP_V1_0: - return "HDCP version 1.0"; - case HDCP_V1_1: - return "HDCP version 1.1"; - case HDCP_V1_2: - return "HDCP version 1.2"; - case HDCP_V1_3: - return "HDCP version 1.3"; - case HDCP_V1_4: - return "HDCP version 1.4"; - case HDCP_V2: - return "HDCP version 2.0"; - case HDCP_V2_1: - return "HDCP version 2.1"; - case HDCP_V2_2: - return "HDCP version 2.2"; - case HDCP_V2_3: - return "HDCP version 2.3"; - case HDCP_NO_DIGITAL_OUTPUT: - return "No HDCP device attached/using local display with secure path"; - default: - return ""; - } -} - -TEST_F(OEMCryptoClientTest, CheckHDCPCapabilityAPI09) { - OEMCryptoResult sts; - OEMCrypto_HDCP_Capability current, maximum; - sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - printf(" Current HDCP Capability: 0x%02x = %s.\n", - static_cast(current), HDCPCapabilityAsString(current)); - printf(" Maximum HDCP Capability: 0x%02x = %s.\n", - static_cast(maximum), HDCPCapabilityAsString(maximum)); -} - -TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) { - // This just tests some trivial functionality of the SRM update functions. - uint16_t version = 0; - OEMCryptoResult current_result = OEMCrypto_GetCurrentSRMVersion(&version); - if (current_result == OEMCrypto_SUCCESS) { - printf(" Current SRM Version: %d.\n", version); - EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_GetCurrentSRMVersion(nullptr)); - } else if (current_result == OEMCrypto_LOCAL_DISPLAY_ONLY) { - printf(" Current SRM Status: Local Display Only.\n"); - } else { - EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result); - } -} - -TEST_F(OEMCryptoClientTest, CheckNullBuildInformationAPI17) { - OEMCryptoResult sts; - std::string build_info; - sts = OEMCrypto_BuildInformation(&build_info[0], nullptr); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); - size_t buf_length = 0; - sts = OEMCrypto_BuildInformation(nullptr, &buf_length); - // Previous versions of the test expected the wrong error code. - // Although OEMCrypto_ERROR_INVALID_CONTEXT is still accepted by - // the tests, vendors should return OEMCrypto_ERROR_SHORT_BUFFER if - // |buffer| is null and |buf_length| is zero, assigning - // the correct length to |buf_length|. - // TODO(231514699): Remove case for ERROR_INVALID_CONTEXT. - ASSERT_TRUE(OEMCrypto_ERROR_SHORT_BUFFER == sts || - OEMCrypto_ERROR_INVALID_CONTEXT == sts); - if (sts == OEMCrypto_ERROR_INVALID_CONTEXT) { - printf( - "Warning: OEMCrypto_BuildInformation should return " - "ERROR_SHORT_BUFFER.\n"); - } - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - constexpr size_t kZero = 0; - ASSERT_GT(buf_length, kZero); - } -} - -TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) { - size_t sessions_count; - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); - ASSERT_EQ(0u, sessions_count); - size_t maximum; - OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - printf(" Max Number of Sessions: %zu.\n", maximum); - size_t required_max = GetResourceValue(kMaxConcurrentSession); - ASSERT_GE(maximum, required_max); -} - -TEST_F(OEMCryptoClientTest, CheckUsageTableSizeAPI16) { - const size_t maximum = OEMCrypto_MaximumUsageTableHeaderSize(); - printf(" Max Usage Table Size: %zu.\n", maximum); - // A maximum of 0 means the table is constrained by dynamic memory allocation. - if (maximum > 0) { - ASSERT_GE(maximum, RequiredUsageSize()); - } -} - -// -// initialization tests -// -TEST_F(OEMCryptoClientTest, NormalInitTermination) { - // Should be able to terminate OEMCrypto, and then restart it. - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate()); - OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); -} - -// Test that set sandbox doesn't crash for a large sandbox id leangth. -TEST_F(OEMCryptoClientTest, OEMCryptoMemorySetSandboxForHugeSandboxIdLength) { - auto oemcrypto_function = [](size_t buffer_length) { - vector buffer(buffer_length); - return OEMCrypto_SetSandbox(buffer.data(), buffer.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, CheckDTCP2CapabilityAPI17) { - OEMCryptoResult sts; - OEMCrypto_DTCP2_Capability capability; - sts = OEMCrypto_GetDTCP2Capability(&capability); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - switch (capability) { - case OEMCrypto_NO_DTCP2: - printf(" Current DTCP Support: DTCP2 not supported.\n"); - break; - case OEMCrypto_DTCP2_V1: - printf( - " Current DTCP Support: Version 1 (or higher) of " - "DTCP2 is supported.\n"); - break; - } -} - -// -// Session Tests -// -TEST_F(OEMCryptoClientTest, NormalSessionOpenClose) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.close()); -} - -TEST_F(OEMCryptoClientTest, TwoSessionsOpenClose) { - Session s1; - Session s2; - ASSERT_NO_FATAL_FAILURE(s1.open()); - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(s1.close()); - ASSERT_NO_FATAL_FAILURE(s2.close()); -} - -// This test verifies that OEMCrypto can open approximately as many sessions as -// it claims. -TEST_F(OEMCryptoClientTest, MaxSessionsOpenCloseAPI10) { - size_t sessions_count; - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); - ASSERT_EQ(0u, sessions_count); - size_t max_sessions; - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetMaxNumberOfSessions(&max_sessions)); - // We expect OEMCrypto implementations support at least this many sessions. - size_t required_number = GetResourceValue(kMaxConcurrentSession); - ASSERT_GE(max_sessions, required_number); - // We allow GetMaxNumberOfSessions to return an estimate. This tests with a - // pad of 5%. Even if it's just an estimate, we still require 8 sessions. - size_t max_sessions_with_pad = max(max_sessions * 19 / 20, required_number); - vector sessions; - // Limit the number of sessions for testing. - const size_t kMaxNumberOfSessionsForTesting = 0x100u; - for (size_t i = 0; i < kMaxNumberOfSessionsForTesting; i++) { - OEMCrypto_SESSION session_id; - OEMCryptoResult sts = OEMCrypto_OpenSession(&session_id); - // GetMaxNumberOfSessions might be an estimate. We allow OEMCrypto to report - // a max that is less than what is actually supported. Assume the number - // returned is |max|. OpenSessions shall not fail if number of active - // sessions is less than |max|; OpenSessions should fail with - // OEMCrypto_ERROR_TOO_MANY_SESSIONS if too many sessions are open. - if (sts != OEMCrypto_SUCCESS) { - ASSERT_EQ(OEMCrypto_ERROR_TOO_MANY_SESSIONS, sts); - ASSERT_GE(i, max_sessions_with_pad); - break; - } - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); - ASSERT_EQ(i + 1, sessions_count); - sessions.push_back(session_id); - } - for (size_t i = 0; i < sessions.size(); i++) { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CloseSession(sessions[i])); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetNumberOfOpenSessions(&sessions_count)); - ASSERT_EQ(sessions.size() - i - 1, sessions_count); - } - if (sessions.size() == kMaxNumberOfSessionsForTesting) { - printf( - " MaxSessionsOpenClose: reaches " - "kMaxNumberOfSessionsForTesting(%zu). GetMaxNumberOfSessions = %zu. " - "ERROR_TOO_MANY_SESSIONS not tested.", - kMaxNumberOfSessionsForTesting, max_sessions); - } -} - -// Verify that GetRandom does work, and does some sanity checks on how random -// the data is. Basically, we say that calling GetRandom twice should not -// generate much overlap. -TEST_F(OEMCryptoClientTest, GetRandomLargeBuffer) { - // 32 bytes. Not very large, but that's all we really need in one call. - const size_t size = 32; - uint8_t data1[size]; - uint8_t data2[size]; - memset(data1, 0, size); - memset(data2, 0, size); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetRandom(data1, size)); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetRandom(data2, size)); - // We don't have enough data to see that the data is really random, - // so we'll just do a spot check that two calls don't return the same values. - int count = 0; - for (size_t i = 0; i < size; i++) { - if (data1[i] == data2[i]) count++; - } - ASSERT_LE(count, 6); // P(count > 6) = 4.3e-11 -} - -// Verify that GetRandom doesn't crash for large input lengths. -TEST_F(OEMCryptoClientTest, OEMCryptoMemoryGetRandomForHugeBuffer) { - auto oemcrypto_function = [](size_t buffer_length) { - vector buffer(buffer_length); - // TODO(ellurubharath, fredgc): Need to re-evaluate this on a real device - // as GetRandom can be slow. - return OEMCrypto_GetRandom(buffer.data(), buffer.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, GenerateNonce) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - s.GenerateNonce(); -} - -// Prevent a nonce flood even if each nonce is in a different session. -TEST_F(OEMCryptoClientTest, PreventNonceFlood2API16) { - int error_counter = 0; - const int64_t test_start = wvutil::Clock().GetCurrentTime(); - // More than 200 nonces per second should generate an error. - // To allow for some slop, we actually test for more. - const int flood_cutoff = 200; - const int loop_count = flood_cutoff * 2; - for (int i = 0; i < loop_count; i++) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - s.GenerateNonce(&error_counter); - } - wvutil::TestSleep::SyncFakeClock(); - const int64_t test_end = wvutil::Clock().GetCurrentTime(); - int valid_counter = loop_count - error_counter; - // Either oemcrypto should enforce a delay, or it should return an error from - // GenerateNonce -- in either case the number of valid nonces is rate - // limited. We add two seconds to allow for round off error in both - // test_start and test_end. - EXPECT_LE(valid_counter, flood_cutoff * (test_end - test_start + 2)); - error_counter = 0; - // After a pause, we should be able to regenerate nonces. - wvutil::TestSleep::Sleep(2); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - s.GenerateNonce(&error_counter); - EXPECT_EQ(0, error_counter); -} - -// Prevent a nonce flood even if some nonces are in a different session. This -// is different from the test above because there are several session open at -// the same time. We want to make sure you can't get a flood of nonces by -// opening a flood of sessions. -TEST_F(OEMCryptoClientTest, PreventNonceFlood3API16) { - int request_counter = 0; - int error_counter = 0; - const int64_t test_start = wvutil::Clock().GetCurrentTime(); - // More than 200 nonces per second should generate an error. - // To allow for some slop, we actually test for more. - const int flood_cutoff = 200; - const size_t session_count = GetResourceValue(kMaxConcurrentSession); - const size_t loop_count = 2 * flood_cutoff / session_count + 1; - for (size_t i = 0; i < loop_count; i++) { - std::vector s(session_count); - for (size_t j = 0; j < session_count; j++) { - ASSERT_NO_FATAL_FAILURE(s[j].open()); - request_counter++; - s[j].GenerateNonce(&error_counter); - } - } - wvutil::TestSleep::SyncFakeClock(); - const int64_t test_end = wvutil::Clock().GetCurrentTime(); - int valid_counter = request_counter - error_counter; - // Either oemcrypto should enforce a delay, or it should return an error from - // GenerateNonce -- in either case the number of valid nonces is rate - // limited. We add two seconds to allow for round off error in both - // test_start and test_end. - EXPECT_LE(valid_counter, flood_cutoff * (test_end - test_start + 2)); - error_counter = 0; - // After a pause, we should be able to regenerate nonces. - wvutil::TestSleep::Sleep(2); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - s.GenerateNonce(&error_counter); - EXPECT_EQ(0, error_counter); -} - -// This verifies that CopyBuffer works, even before a license has been loaded. -TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - const int kDataSize = 256; - vector input_buffer(kDataSize); - GetRandBytes(input_buffer.data(), input_buffer.size()); - vector output_buffer(kDataSize); - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; - dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); - dest_buffer_descriptor.buffer.clear.clear_buffer_length = - output_buffer.size(); - ASSERT_EQ(OEMCrypto_SUCCESS, - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - ASSERT_EQ(input_buffer, output_buffer); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - CopyBuffer(s.session_id(), nullptr, input_buffer.size(), - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - ASSERT_EQ( - OEMCrypto_ERROR_INVALID_CONTEXT, - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - nullptr, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - dest_buffer_descriptor.buffer.clear.clear_buffer = nullptr; - ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); - dest_buffer_descriptor.buffer.clear.clear_buffer_length = - output_buffer.size() - 1; - ASSERT_NE(OEMCrypto_SUCCESS, - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); -} - -// This verifies that CopyBuffer works on the maximum required buffer size. -TEST_F(OEMCryptoClientTest, ClearCopyTestLargeSubsample) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - size_t max_size = GetResourceValue(kMaxSubsampleSize); - vector input_buffer(max_size); - GetRandBytes(input_buffer.data(), input_buffer.size()); - vector output_buffer(max_size); - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; - dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); - dest_buffer_descriptor.buffer.clear.clear_buffer_length = - output_buffer.size(); - ASSERT_EQ(OEMCrypto_SUCCESS, - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - ASSERT_EQ(input_buffer, output_buffer); -} - -TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForHugeBufferLengths) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector input_buffer; - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; - - auto oemcrypto_function = [&s, &dest_buffer_descriptor, - &input_buffer](size_t buffer_length) { - input_buffer.resize(buffer_length); - int secure_fd; - OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( - s.session_id(), buffer_length, &dest_buffer_descriptor, &secure_fd); - if (sts != OEMCrypto_SUCCESS) { - LOGI("Secure buffers are not supported."); - return sts; - } - - dest_buffer_descriptor.buffer.secure.secure_buffer_length = buffer_length; - OEMCryptoResult status = OEMCrypto_CopyBuffer( - s.session_id(), input_buffer.data(), buffer_length, - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, - secure_fd); - return status; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryCopyBufferDirectForHugeBufferLengths) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector input_buffer; - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Direct; - dest_buffer_descriptor.buffer.direct.is_video = false; - - auto oemcrypto_function = [&s, &dest_buffer_descriptor, - &input_buffer](size_t buffer_length) { - input_buffer.resize(buffer_length); - OEMCryptoResult status = OEMCrypto_CopyBuffer( - s.session_id(), input_buffer.data(), buffer_length, - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - return status; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForOutOfRangeOffset) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector input_buffer; - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; - - size_t buffer_length = KiB; - input_buffer.resize(buffer_length); - int secure_fd; - if (OEMCrypto_AllocateSecureBuffer(s.session_id(), buffer_length, - &dest_buffer_descriptor, - &secure_fd) != OEMCrypto_SUCCESS) { - LOGI("Secure buffers are not supported."); - return; - } - - dest_buffer_descriptor.buffer.secure.secure_buffer_length = buffer_length; - auto oemcrypto_function = [&s, &dest_buffer_descriptor, &input_buffer, - &buffer_length](size_t offset) { - dest_buffer_descriptor.buffer.secure.offset = offset; - return OEMCrypto_CopyBuffer( - s.session_id(), input_buffer.data(), buffer_length, - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); - OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, - secure_fd); -} - -TEST_F(OEMCryptoClientTest, - OEMCryptoMemoryCopyBufferForOutOfRangeHandleLength) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector input_buffer; - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Secure; - - size_t buffer_length = KiB; - input_buffer.resize(buffer_length); - int secure_fd; - if (OEMCrypto_AllocateSecureBuffer(s.session_id(), buffer_length, - &dest_buffer_descriptor, - &secure_fd) != OEMCrypto_SUCCESS) { - LOGI("Secure buffers are not supported."); - return; - } - - dest_buffer_descriptor.buffer.secure.secure_buffer_length = - kHugeInputBufferLength; - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), buffer_length, - &dest_buffer_descriptor, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - OEMCrypto_FreeSecureBuffer(s.session_id(), &dest_buffer_descriptor, - secure_fd); -} - -TEST_F(OEMCryptoClientTest, ClearCopyTestInvalidSubsampleFlag) { - uint8_t oemcrypto_invalid_subsample_flag = 85; - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - size_t max_size = GetResourceValue(kMaxSubsampleSize); - vector input_buffer(max_size); - GetRandBytes(input_buffer.data(), input_buffer.size()); - vector output_buffer(max_size); - OEMCrypto_DestBufferDesc dest_buffer_descriptor; - dest_buffer_descriptor.type = OEMCrypto_BufferType_Clear; - dest_buffer_descriptor.buffer.clear.clear_buffer = output_buffer.data(); - dest_buffer_descriptor.buffer.clear.clear_buffer_length = - output_buffer.size(); - ASSERT_NO_FATAL_FAILURE( - CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), - &dest_buffer_descriptor, oemcrypto_invalid_subsample_flag)); -} - -TEST_F(OEMCryptoClientTest, CanLoadTestKeys) { - ASSERT_NE(DeviceFeatures::NO_METHOD, global_features.derive_key_method) - << "Session tests cannot run with out a test keybox or RSA cert."; -} - -// Tests using this class are only used for devices with a keybox. They are not -// run for devices with an OEM Certificate. -class OEMCryptoKeyboxTest : public OEMCryptoClientTest { - void SetUp() override { - OEMCryptoClientTest::SetUp(); - OEMCryptoResult sts = OEMCrypto_IsKeyboxValid(); - // If the production keybox is valid, use it for these tests. Most of the - // other tests will use a test keybox anyway, but it's nice to check the - // device ID for the real keybox if we can. - if (sts == OEMCrypto_SUCCESS) return; - printf("Production keybox is NOT valid. All tests use test keybox.\n"); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_LoadTestKeybox(reinterpret_cast(&kTestKeybox), - sizeof(kTestKeybox))); - } -}; - -/******** Dangerous Tests - DO NOT RUN ***********/ -/*The following tests try to test InstallKeybox API with random buffers of -varying length in order to catch any overflow issues. These tests override the -actual keybox on the device. Remove the if and endif statement to run these -tests on a device ONLY IF YOU ARE ABLE TO RECOVER THE KEYBOX on the device.*/ -#if 0 -TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryInstallKeyboxForHugeKeyboxBuffer) { - auto f = [](size_t keybox_length) { - vector keybox(keybox_length); - memcpy(keybox.data(), &kTestKeybox, sizeof(kTestKeybox)); - return OEMCrypto_InstallKeyboxOrOEMCert(keybox.data(), keybox.size()); - }; - // Starting at sizeof(kTestKeybox) as we are copying valid keybox - // at beginning of generated buffers. - TestHugeLengthDoesNotCrashAPI(f, sizeof(kTestKeybox), kHugeInputBufferLength, - kCheckStatus); -} - -TEST_F(OEMCryptoKeyboxTest, - OEMCryptoMemoryInstallKeyboxForHugeKeyboxBufferStartingFromLength1) { - auto f = [](size_t keybox_length) { - vector keybox(keybox_length); - return OEMCrypto_InstallKeyboxOrOEMCert(keybox.data(), keybox.size()); - }; - // We are testing for keybox lengths starting from 1 which would return error, - // hence skipping status check. - TestHugeLengthDoesNotCrashAPI(f, !kCheckStatus); -} -#endif - -TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBuffer) { - auto f = [](size_t keybox_length) { - vector keybox(keybox_length); - memcpy(keybox.data(), &kTestKeybox, sizeof(kTestKeybox)); - return OEMCrypto_LoadTestKeybox(keybox.data(), keybox.size()); - }; - // Starting at sizeof(kTestKeybox) as we are copying valid keybox - // at beginning of generated buffers. - TestHugeLengthDoesNotCrashAPI(f, sizeof(kTestKeybox), kHugeInputBufferLength, - kCheckStatus); -} - -TEST_F(OEMCryptoKeyboxTest, - OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBufferStartingFromLength1) { - auto f = [](size_t keybox_length) { - vector keybox(keybox_length); - return OEMCrypto_LoadTestKeybox(keybox.data(), keybox.size()); - }; - // We are testing for keybox lengths starting from 1 which would return error, - // hence skipping status check. - TestHugeLengthDoesNotCrashAPI(f, !kCheckStatus); -} - -// This test is used to print the device ID to stdout. -TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) { - OEMCryptoResult sts; - uint8_t dev_id[128] = {0}; - size_t dev_id_len = 128; - sts = OEMCrypto_GetDeviceID(dev_id, &dev_id_len); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - cout << " NormalGetDeviceId: dev_id = " - << MaybeHex(dev_id, dev_id_len) << " len = " << dev_id_len << endl; -} - -TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetDeviceIdForHugeIdLength) { - auto oemcrypto_function = [](size_t input_length) { - size_t device_id_length = input_length; - vector device_id(device_id_length); - return OEMCrypto_GetDeviceID(device_id.data(), &device_id_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoKeyboxTest, GetDeviceIdShortBuffer) { - OEMCryptoResult sts; - uint8_t dev_id[128]; - for (int i = 0; i < 128; ++i) { - dev_id[i] = 0x55; - } - dev_id[127] = '\0'; - size_t dev_id_len = 0; - sts = OEMCrypto_GetDeviceID(dev_id, &dev_id_len); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - // On short buffer error, function should return minimum buffer length - ASSERT_GT(dev_id_len, 0u); - // Should also return short buffer if passed a zero length and a null buffer. - dev_id_len = 0; - sts = OEMCrypto_GetDeviceID(nullptr, &dev_id_len); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - // On short buffer error, function should return minimum buffer length - ASSERT_GT(dev_id_len, 0u); -} - -TEST_F(OEMCryptoKeyboxTest, NormalGetKeyData) { - OEMCryptoResult sts; - uint8_t key_data[256]; - size_t key_data_len = sizeof(key_data); - sts = OEMCrypto_GetKeyData(key_data, &key_data_len); - - uint32_t* data = reinterpret_cast(key_data); - printf(" NormalGetKeyData: system_id = %u = 0x%04X, version=%u\n", - htonl(data[1]), htonl(data[1]), htonl(data[0])); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); -} - -TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetKeyIdForHugeIdLength) { - auto oemcrypto_function = [](size_t input_length) { - size_t key_data_length = input_length; - vector key_data(key_data_length); - return OEMCrypto_GetKeyData(key_data.data(), &key_data_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_F(OEMCryptoKeyboxTest, GetKeyDataNullPointer) { - OEMCryptoResult sts; - uint8_t key_data[256]; - sts = OEMCrypto_GetKeyData(key_data, nullptr); - ASSERT_NE(OEMCrypto_SUCCESS, sts); -} - -// This test makes sure the installed keybox is valid. It doesn't really check -// that it is a production keybox. That must be done by an integration test. -TEST_F(OEMCryptoKeyboxTest, ProductionKeyboxValid) { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); -} - -// This tests GenerateDerivedKeys with an 8k context. -TEST_F(OEMCryptoKeyboxTest, GenerateDerivedKeysFromKeyboxLargeBuffer) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - const size_t max_size = GetResourceValue(kLargeMessageSize); - vector mac_context(max_size); - vector enc_context(max_size); - // Stripe the data so the two vectors are not identical, and not all zeroes. - for (size_t i = 0; i < max_size; i++) { - mac_context[i] = i % 0x100; - enc_context[i] = (3 * i) % 0x100; - } - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GenerateDerivedKeys( - s.session_id(), mac_context.data(), mac_context.size(), - enc_context.data(), enc_context.size())); -} - -TEST_F(OEMCryptoKeyboxTest, - OEMCryptoMemoryGenerateDerivedKeysForHugeMacContextLength) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector mac_context; - vector enc_context; - s.FillDefaultContext(&mac_context, &enc_context); - - auto oemcrypto_function = [&s, &mac_context, - &enc_context](size_t buffer_length) { - mac_context.resize(buffer_length); - return OEMCrypto_GenerateDerivedKeys(s.session_id(), mac_context.data(), - mac_context.size(), enc_context.data(), - enc_context.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoKeyboxTest, - OEMCryptoMemoryGenerateDerivedKeysForHugeEncContextLength) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - vector mac_context; - vector enc_context; - s.FillDefaultContext(&mac_context, &enc_context); - - auto oemcrypto_function = [&s, &mac_context, - &enc_context](size_t buffer_length) { - enc_context.resize(buffer_length); - return OEMCrypto_GenerateDerivedKeys(s.session_id(), mac_context.data(), - mac_context.size(), enc_context.data(), - enc_context.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// This class is for tests that have an OEM Certificate instead of a keybox. -class OEMCryptoProv30Test : public OEMCryptoClientTest {}; - -// This verifies that the device really does claim to have a certificate. -// It should be filtered out for devices that have a keybox. -TEST_F(OEMCryptoProv30Test, DeviceClaimsOEMCertificate) { - ASSERT_EQ(OEMCrypto_OEMCertificate, OEMCrypto_GetProvisioningMethod()); -} - -TEST_F(OEMCryptoProv30Test, GetDeviceId) { - OEMCryptoResult sts; - std::vector dev_id(128, 0); - size_t dev_id_len = dev_id.size(); - sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - ASSERT_GT(dev_id_len, 0u); - dev_id.resize(dev_id_len); - sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); - } - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - dev_id.resize(dev_id_len); - cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id) - << " len = " << dev_id_len << endl; -} - -// The OEM certificate must be valid. -TEST_F(OEMCryptoProv30Test, CertValidAPI15) { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxOrOEMCertValid()); -} - -TEST_F(OEMCryptoProv30Test, OEMCertValid) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - bool kVerify = true; - ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert(kVerify)); // Load and verify. -} - -/// @} - -/// @addtogroup license -/// @{ - -// This verifies that the OEM Certificate cannot be used for other RSA padding -// schemes. Those schemes should only be used by cast receiver certificates. -TEST_F(OEMCryptoProv30Test, OEMCertForbiddenPaddingScheme) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert()); - OEMCryptoResult sts; - // Sign a Message - vector data(500); - GetRandBytes(data.data(), data.size()); - size_t signature_length = 0; - // We need a size one vector to pass as a pointer. - vector signature(1, 0); - vector zero(1, 0); - - sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), - signature.data(), &signature_length, - kSign_PKCS1_Block1); - if (OEMCrypto_ERROR_SHORT_BUFFER == sts) { - // The OEMCrypto could complain about buffer length first, so let's - // resize and check if it's writing to the signature again. - signature.resize(signature_length, 0); - zero.resize(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), - data.size(), signature.data(), - &signature_length, kSign_PKCS1_Block1); - } - EXPECT_NE(OEMCrypto_SUCCESS, sts) - << "OEM Cert Signed with forbidden kSign_PKCS1_Block1."; - ASSERT_EQ(zero, signature); // signature should not be computed. -} - -// Calling OEMCrypto_GetOEMPublicCertificate should not change the session's -// private key. -TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) { - if (wrapped_rsa_key_.size() == 0) { - // If we don't have a wrapped key yet, create one. - // This wrapped key will be shared by all sessions in the test. - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - } - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // Install the DRM Cert's RSA key. - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey()); - // Request the OEM Cert. -- This should NOT load the OEM Private key. - vector public_cert; - size_t public_cert_length = 0; - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_GetOEMPublicCertificate(nullptr, &public_cert_length)); - ASSERT_LT(0u, public_cert_length); - public_cert.resize(public_cert_length); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetOEMPublicCertificate( - public_cert.data(), &public_cert_length)); - // Derive keys from the session key -- this should use the DRM Cert's key. It - // should NOT use the OEM Private key because that key should not have been - // loaded. - ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey()); - // Now fill a message and try to load it. - LicenseRoundTrip license_messages(&s); - license_messages.set_control(0); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); -} - -TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) { - if (wrapped_rsa_key_.size() == 0) { - // If we don't have a wrapped key yet, create one. - // This wrapped key will be shared by all sessions in the test. - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - } - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // Install the DRM Cert's RSA key. - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey()); - - auto oemcrypto_function = [](size_t input_length) { - size_t public_cert_length = input_length; - vector public_cert(public_cert_length); - return OEMCrypto_GetOEMPublicCertificate(public_cert.data(), - &public_cert_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// This class is for tests that have boot certificate chain instead of a keybox. -class OEMCryptoProv40Test : public OEMCryptoClientTest {}; - -// This verifies that the device really does claim to have BCC. -// It should be filtered out for devices that have a keybox or factory OEM cert. -TEST_F(OEMCryptoProv40Test, DeviceClaimsBootCertificateChain) { - ASSERT_EQ(OEMCrypto_GetProvisioningMethod(), OEMCrypto_BootCertificateChain); -} - -// Verifies that short buffer error returns when the buffer is short. -TEST_F(OEMCryptoProv40Test, GetBootCertificateChainShortBuffer) { - std::vector bcc; - size_t bcc_size = 0; - std::vector additional_signature; - size_t additional_signature_size = 0; - ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, - additional_signature.data(), - &additional_signature_size), - OEMCrypto_ERROR_SHORT_BUFFER); - ASSERT_NE(bcc_size, 0uL); -} - -// Verifies BCC can be successfully returned. -TEST_F(OEMCryptoProv40Test, GetBootCertificateChainSuccess) { - std::vector bcc; - size_t bcc_size = 0; - std::vector additional_signature; - size_t additional_signature_size = 0; - ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, - additional_signature.data(), - &additional_signature_size), - OEMCrypto_ERROR_SHORT_BUFFER); - - bcc.resize(bcc_size); - additional_signature.resize(additional_signature_size); - ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size, - additional_signature.data(), - &additional_signature_size), - OEMCrypto_SUCCESS); -} - -// Verifies that short buffer error returns when the buffer is short. -TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairShortBuffer) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - std::vector public_key; - size_t public_key_size = 0; - std::vector public_key_signature; - size_t public_key_signature_size = 0; - std::vector wrapped_private_key; - size_t wrapped_private_key_size = 0; - OEMCrypto_PrivateKeyType key_type; - - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key.data(), &public_key_size, - public_key_signature.data(), &public_key_signature_size, - wrapped_private_key.data(), &wrapped_private_key_size, &key_type), - OEMCrypto_ERROR_SHORT_BUFFER); - - ASSERT_NE(public_key_size, 0uL); - ASSERT_NE(public_key_signature_size, 0uL); - ASSERT_NE(wrapped_private_key_size, 0uL); -} - -// Verifies a pair of key can be successfully returned. -TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairSuccess) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - std::vector public_key; - size_t public_key_size = 0; - std::vector public_key_signature; - size_t public_key_signature_size = 0; - std::vector wrapped_private_key; - size_t wrapped_private_key_size = 0; - OEMCrypto_PrivateKeyType key_type; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key.data(), &public_key_size, - public_key_signature.data(), &public_key_signature_size, - wrapped_private_key.data(), &wrapped_private_key_size, &key_type), - OEMCrypto_ERROR_SHORT_BUFFER); - public_key.resize(public_key_size); - public_key_signature.resize(public_key_signature_size); - wrapped_private_key.resize(wrapped_private_key_size); - - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key.data(), &public_key_size, - public_key_signature.data(), &public_key_signature_size, - wrapped_private_key.data(), &wrapped_private_key_size, &key_type), - OEMCrypto_SUCCESS); - public_key.resize(public_key_size); - public_key_signature.resize(public_key_signature_size); - wrapped_private_key.resize(wrapped_private_key_size); - // Parse the public key generated to make sure it is correctly formatted. - ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey( - key_type, public_key.data(), public_key_size)); -} - -// Verifies the generated key pairs are different on each call. -TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairsAreDifferent) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // Large buffer to make sure it is large enough. - size_t public_key_size1 = 10000; - std::vector public_key1(public_key_size1); - size_t public_key_signature_size1 = 10000; - std::vector public_key_signature1(public_key_signature_size1); - size_t wrapped_private_key_size1 = 10000; - std::vector wrapped_private_key1(wrapped_private_key_size1); - OEMCrypto_PrivateKeyType key_type1; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key1.data(), &public_key_size1, - public_key_signature1.data(), &public_key_signature_size1, - wrapped_private_key1.data(), &wrapped_private_key_size1, &key_type1), - OEMCrypto_SUCCESS); - EXPECT_NE(public_key_size1, 0UL); - EXPECT_NE(public_key_signature_size1, 0UL); - EXPECT_NE(wrapped_private_key_size1, 0UL); - public_key1.resize(public_key_size1); - public_key_signature1.resize(public_key_signature_size1); - wrapped_private_key1.resize(wrapped_private_key_size1); - - size_t public_key_size2 = 10000; - std::vector public_key2(public_key_size2); - size_t public_key_signature_size2 = 10000; - std::vector public_key_signature2(public_key_signature_size2); - size_t wrapped_private_key_size2 = 10000; - std::vector wrapped_private_key2(wrapped_private_key_size2); - OEMCrypto_PrivateKeyType key_type2; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key2.data(), &public_key_size2, - public_key_signature2.data(), &public_key_signature_size2, - wrapped_private_key2.data(), &wrapped_private_key_size2, &key_type2), - OEMCrypto_SUCCESS); - EXPECT_NE(public_key_size2, 0UL); - EXPECT_NE(public_key_signature_size2, 0UL); - EXPECT_NE(wrapped_private_key_size2, 0UL); - public_key2.resize(public_key_size2); - public_key_signature2.resize(public_key_signature_size2); - wrapped_private_key2.resize(wrapped_private_key_size2); - - EXPECT_NE(public_key1, public_key2); - EXPECT_NE(public_key_signature1, public_key_signature2); - EXPECT_NE(wrapped_private_key1, wrapped_private_key2); -} - -// Verifies the an OEM private key can be installed. -TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeySuccess) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // First generate a key pair. - // Large buffer to make sure it is large enough. - size_t public_key_size = 10000; - std::vector public_key(public_key_size); - size_t public_key_signature_size = 10000; - std::vector public_key_signature(public_key_signature_size); - size_t wrapped_private_key_size = 10000; - std::vector wrapped_private_key(wrapped_private_key_size); - OEMCrypto_PrivateKeyType key_type; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key.data(), &public_key_size, - public_key_signature.data(), &public_key_signature_size, - wrapped_private_key.data(), &wrapped_private_key_size, &key_type), - OEMCrypto_SUCCESS); - public_key.resize(public_key_size); - public_key_signature.resize(public_key_signature_size); - wrapped_private_key.resize(wrapped_private_key_size); - - // Install the generated private key. - ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, - wrapped_private_key.data(), - wrapped_private_key_size), - OEMCrypto_SUCCESS); -} - -// If data is empty or random, the API should return non-success status. -TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyInvalidDataFail) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - - // Empty key fails. - std::vector wrapped_private_key; - OEMCrypto_PrivateKeyType key_type = OEMCrypto_RSA_Private_Key; - ASSERT_NE(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, - wrapped_private_key.data(), - wrapped_private_key.size()), - OEMCrypto_SUCCESS); - - // Random key data fails. - wrapped_private_key = {1, 2, 3}; - ASSERT_NE(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type, - wrapped_private_key.data(), - wrapped_private_key.size()), - OEMCrypto_SUCCESS); -} - -// Verifies the an OEM private key can be installed, and used by -// GenerateCertificateKeyPair call. -TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // First generate a key pair. - size_t public_key_size1 = 10000; - std::vector public_key1(public_key_size1); - size_t public_key_signature_size1 = 10000; - std::vector public_key_signature1(public_key_signature_size1); - size_t wrapped_private_key_size1 = 10000; - std::vector wrapped_private_key1(wrapped_private_key_size1); - OEMCrypto_PrivateKeyType key_type1; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key1.data(), &public_key_size1, - public_key_signature1.data(), &public_key_signature_size1, - wrapped_private_key1.data(), &wrapped_private_key_size1, &key_type1), - OEMCrypto_SUCCESS); - EXPECT_NE(public_key_size1, 0UL); - EXPECT_NE(public_key_signature_size1, 0UL); - EXPECT_NE(wrapped_private_key_size1, 0UL); - public_key1.resize(public_key_size1); - public_key_signature1.resize(public_key_signature_size1); - wrapped_private_key1.resize(wrapped_private_key_size1); - - // Install the generated private key. - ASSERT_EQ(OEMCrypto_InstallOemPrivateKey(s.session_id(), key_type1, - wrapped_private_key1.data(), - wrapped_private_key_size1), - OEMCrypto_SUCCESS); - - // Now calling GenerateCertificateKeyPair should use wrapped_private_key to - // sign the newly generated public key. - size_t public_key_size2 = 10000; - std::vector public_key2(public_key_size2); - size_t public_key_signature_size2 = 10000; - std::vector public_key_signature2(public_key_signature_size2); - size_t wrapped_private_key_size2 = 10000; - std::vector wrapped_private_key2(wrapped_private_key_size2); - OEMCrypto_PrivateKeyType key_type2; - ASSERT_EQ( - OEMCrypto_GenerateCertificateKeyPair( - s.session_id(), public_key2.data(), &public_key_size2, - public_key_signature2.data(), &public_key_signature_size2, - wrapped_private_key2.data(), &wrapped_private_key_size2, &key_type2), - OEMCrypto_SUCCESS); - EXPECT_NE(public_key_size2, 0UL); - EXPECT_NE(public_key_signature_size2, 0UL); - EXPECT_NE(wrapped_private_key_size2, 0UL); - public_key2.resize(public_key_size2); - public_key_signature2.resize(public_key_signature_size2); - wrapped_private_key2.resize(wrapped_private_key_size2); - - // Verify public_key_signature2 with public_key1. - if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) { - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey( - public_key1.data(), public_key1.size())); - ASSERT_NO_FATAL_FAILURE( - s.VerifyRsaSignature(public_key2, public_key_signature2.data(), - public_key_signature2.size(), kSign_RSASSA_PSS)); - } else if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) { - ASSERT_NO_FATAL_FAILURE(s.SetEccPublicKeyFromSubjectPublicKey( - public_key1.data(), public_key1.size())); - ASSERT_NO_FATAL_FAILURE(s.VerifyEccSignature(public_key2, - public_key_signature2.data(), - public_key_signature2.size())); - } -} - -TEST_F(OEMCryptoProv40Test, GetDeviceId) { - OEMCryptoResult sts; - std::vector dev_id; - size_t dev_id_len = dev_id.size(); - sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - ASSERT_GT(dev_id_len, 0u); - dev_id.resize(dev_id_len); - sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); - } - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - dev_id.resize(dev_id_len); - cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id) - << " len = " << dev_id_len << endl; - // Device id should be stable. Query again. - std::vector dev_id2(dev_id_len); - sts = OEMCrypto_GetDeviceID(dev_id2.data(), &dev_id_len); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(dev_id2, dev_id); -} - -// -// AddKey Tests -// -// These tests will use either a test keybox or a test certificate to derive -// session keys. -class OEMCryptoSessionTests : public OEMCryptoClientTest { - public: - vector encrypted_usage_header_; - - protected: - OEMCryptoSessionTests() {} - - void SetUp() override { - OEMCryptoClientTest::SetUp(); - EnsureTestKeys(); - if (global_features.usage_table) { - CreateUsageTableHeader(); - } - } - - void CreateUsageTableHeader(bool expect_success = true) { - size_t header_buffer_length = 0; - OEMCryptoResult sts = - OEMCrypto_CreateUsageTableHeader(nullptr, &header_buffer_length); - if (expect_success) { - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - } else { - ASSERT_NE(OEMCrypto_SUCCESS, sts); - if (sts != OEMCrypto_ERROR_SHORT_BUFFER) return; - } - encrypted_usage_header_.resize(header_buffer_length); - sts = OEMCrypto_CreateUsageTableHeader(encrypted_usage_header_.data(), - &header_buffer_length); - if (expect_success) { - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - encrypted_usage_header_.resize(header_buffer_length); - } else { - ASSERT_NE(OEMCrypto_SUCCESS, sts); - } - } - - void TestPrepareLicenseRequestForHugeBufferLengths( - const std::function f, - bool check_status) { - auto oemcrypto_function = [&](size_t message_length) { - Session s; - s.open(); - InstallTestRSAKey(&s); - LicenseRoundTrip license_messages(&s); - f(message_length, &license_messages); - OEMCryptoResult result = - license_messages.SignAndCreateRequestWithCustomBufferLengths(); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); - } - - OEMCryptoResult LoadLicense(Session& s, LicenseRoundTrip& license_messages) { - InstallTestRSAKey(&s); - license_messages.SignAndVerifyRequest(); - license_messages.CreateDefaultResponse(); - license_messages.EncryptAndSignResponse(); - return license_messages.LoadResponse(); - } -}; - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryCreateUsageTableHeaderForHugeHeaderBufferLength) { - auto oemcrypto_function = [](size_t buffer_length) { - size_t header_buffer_length = buffer_length; - vector usage_table_header(header_buffer_length); - return OEMCrypto_CreateUsageTableHeader(usage_table_header.data(), - &header_buffer_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -class OEMCryptoSessionTestKeyboxTest : public OEMCryptoSessionTests {}; - -TEST_F(OEMCryptoSessionTestKeyboxTest, TestKeyboxIsValid) { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); -} - -// This class is for testing a single license with the default API version -// of 16. -class OEMCryptoLicenseTestAPI16 : public OEMCryptoSessionTests { - public: - OEMCryptoLicenseTestAPI16() - : license_api_version_(kCurrentAPI), license_messages_(&session_) {} - - void SetUp() override { - OEMCryptoSessionTests::SetUp(); - ASSERT_NO_FATAL_FAILURE(session_.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_)); - } - - void TearDown() override { - ASSERT_NO_FATAL_FAILURE(session_.close()); - OEMCryptoSessionTests::TearDown(); - } - - protected: - Session session_; - uint32_t license_api_version_; - LicenseRoundTrip license_messages_; -}; - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryPrepareLicenseRequestForHugeRequestMessageLength) { - TestPrepareLicenseRequestForHugeBufferLengths( - [](size_t message_size, LicenseRoundTrip* license_messages) { - license_messages->set_message_size(message_size); - }, - kCheckStatus); -} - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryPrepareLicenseRequestForHugeCoreMessageLength) { - TestPrepareLicenseRequestForHugeBufferLengths( - [](size_t core_message_size, LicenseRoundTrip* license_messages) { - license_messages->set_core_message_size(core_message_size); - }, - kCheckStatus); -} - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryPrepareLicenseRequestForHugeSignatureLength) { - // There is a limit of signature length that gets validated. Hence not - // checking status as we would like to test it for all possible signature - // lengths. - TestPrepareLicenseRequestForHugeBufferLengths( - [](size_t length, LicenseRoundTrip* license_messages) { - license_messages->set_request_signature_size(length); - }, - !kCheckStatus); -} - class OEMCryptoLicenseOverflowTest : public OEMCryptoSessionTests, public WithParamInterface { public: @@ -1729,7 +147,7 @@ class OEMCryptoLicenseOverflowTest : public OEMCryptoSessionTests, LicenseRoundTrip license_messages(&s); license_messages.set_api_version(license_api_version_); s.open(); - InstallTestRSAKey(&s); + InstallTestDrmKey(&s); bool verify_keys_loaded = true; license_messages.SignAndVerifyRequest(); license_messages.CreateDefaultResponse(); @@ -1762,7 +180,7 @@ class OEMCryptoLicenseOverflowTest : public OEMCryptoSessionTests, LicenseRoundTrip license_messages(&s); license_messages.set_api_version(license_api_version_); s.open(); - InstallTestRSAKey(&s); + InstallTestDrmKey(&s); license_messages.SignAndVerifyRequest(); license_messages.CreateDefaultResponse(); size_t message_length = sizeof(license_messages.response_data()); @@ -1839,245 +257,10 @@ class OEMCryptoMemoryLicenseTest : public OEMCryptoLicenseTestAPI16 { } }; -// This class is used to test a license that is from a server either that is -// current or one version old. -class OEMCryptoLicenseTest : public OEMCryptoLicenseTestAPI16, - public WithParamInterface { - protected: - void SetUp() override { - // The only difference between this class and its parent is that we use a - // different license api: - license_api_version_ = GetParam(); - license_messages_.set_api_version(license_api_version_); - OEMCryptoLicenseTestAPI16::SetUp(); - } +/// @} - void LoadLicense() { - license_messages_.SignAndVerifyRequest(); - license_messages_.CreateDefaultResponse(); - license_messages_.EncryptAndSignResponse(); - license_messages_.LoadResponse(); - } - - void TestDecryptCENCForHugeBufferLengths( - const std::function f, - bool check_status) { - LoadLicense(); - auto oemcrypto_function = [&](size_t message_length) { - OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CENC); - - size_t input_buffer_size = 1; - vector in_buffer(input_buffer_size + message_length); - vector out_buffer(in_buffer.size()); - - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - GenerateSimpleSampleDescription( - in_buffer, out_buffer, &sample_description, &subsample_description); - - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description.subsamples); - // Actual tests modifies either of these fields to match clear + encrypted - // = in_buffer.size(). - sub_samples[0].num_bytes_clear = 0; - sub_samples[0].num_bytes_encrypted = input_buffer_size; - - // Create the pattern description (always 0,0 for CTR) - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - int secure_fd = 0; - f(message_length, &sample_description); - if (sample_description.buffers.output_descriptor.type == - OEMCrypto_BufferType_Secure) { - OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( - session_.session_id(), in_buffer.size(), - &sample_description.buffers.output_descriptor, &secure_fd); - if (sts != OEMCrypto_SUCCESS) { - LOGI("Secure buffers are not supported."); - return sts; - } - } - // Try to decrypt the data - OEMCryptoResult result = OEMCrypto_DecryptCENC( - session_.session_id(), &sample_description, 1, &pattern); - if (sample_description.buffers.output_descriptor.type == - OEMCrypto_BufferType_Secure) { - OEMCrypto_FreeSecureBuffer( - session_.session_id(), - &sample_description.buffers.output_descriptor, secure_fd); - } - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); - } - - void TestDecryptCENCForOutOfRangeOffsetsAndLengths( - const std::function f, - bool update_secure_buffer) { - LoadLicense(); - OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CENC); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Create the pattern description (always 0,0 for CTR) - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - int secure_fd = 0; - if (update_secure_buffer) { - OEMCryptoResult sts = OEMCrypto_AllocateSecureBuffer( - session_.session_id(), in_buffer.size(), - &sample_description.buffers.output_descriptor, &secure_fd); - if (sts != OEMCrypto_SUCCESS) { - LOGI("Secure buffers are not supported."); - return; - } - } - f(&sample_description); - // Try to decrypt the data - OEMCryptoResult result = OEMCrypto_DecryptCENC( - session_.session_id(), &sample_description, 1, &pattern); - if (update_secure_buffer) { - OEMCrypto_FreeSecureBuffer(session_.session_id(), - &sample_description.buffers.output_descriptor, - secure_fd); - } - ASSERT_NE(OEMCrypto_SUCCESS, result); - } -}; - -// This class is used to test a license that is only for v15 license. -class OEMCryptoLicenseTestAPI15 : public OEMCryptoLicenseTestAPI16 { - void SetUp() override { - // The only difference between this class and its parent is that we use a - // different license api: - license_api_version_ = 15; - license_messages_.set_api_version(license_api_version_); - OEMCryptoLicenseTestAPI16::SetUp(); - } -}; - -// This class is used to test each key control block verification string in the -// range kc09-kc1?. This test is parameterized by the API number in the key -// control lock. -class OEMCryptoLicenseTestRangeAPI : public OEMCryptoLicenseTest {}; - -// Verify that a license may be signed. -TEST_P(OEMCryptoLicenseTest, SignLicenseRequest) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); -} - -// Verify that a large license request may be signed. -TEST_P(OEMCryptoLicenseTest, SignLargeLicenseRequest) { - const size_t max_size = GetResourceValue(kLargeMessageSize); - license_messages_.set_message_size(max_size); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); -} - -// Verify that a license may be loaded without a nonce. -TEST_P(OEMCryptoLicenseTest, LoadKeyNoNonce) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(0); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); -} - -// Verify that a preloaded license may be loaded without first signing the -// request. This test is important for the preloaded licenses used by ATSC and -// CAS. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithNoRequest) { - if (license_api_version_ > global_features.api_version) { - // We should not attempt to preload a license with an API higher than that - // of OEMCrypto. - license_api_version_ = global_features.api_version; - license_messages_.set_api_version(license_api_version_); - } - license_messages_.set_control(0); - // Notice that we do not call SignAndVerifyRequest -- we do not need a request - // in order to generate a response for a preloaded license. - // The test code uses the core request to create the core response. - license_messages_.core_request().api_major_version = - global_features.api_version; - license_messages_.core_request().api_minor_version = 0; - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - - // Load license in a different session, which did not create the request. - Session session2; - ASSERT_NO_FATAL_FAILURE(session2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session2)); - ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse(&session2)); - ASSERT_NO_FATAL_FAILURE(session2.TestDecryptCTR(true, OEMCrypto_SUCCESS)); -} - -// Verify that a license may be reloaded without a nonce, but with a nonzero -// rental duration. In order to start the rental clock, we sign a dummy license -// instead. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithNoRequestRentalDuration) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(0); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // It is not recommended for a license without a nonce to have a nonzero - // rental duration. But there are content providers that have licenses with - // this policy. - license_messages_.core_response().timer_limits.rental_duration_seconds = - kDuration; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - - // Load license in a different session, which did not create the request. - Session session2; - ASSERT_NO_FATAL_FAILURE(session2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session2)); - // However, in order to start the rental clock, we have to sign something. So - // we will sign a dummy license request. - LicenseRoundTrip dummy_license(&session2); - ASSERT_NO_FATAL_FAILURE(dummy_license.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse(&session2)); - ASSERT_NO_FATAL_FAILURE(session2.TestDecryptCTR(true, OEMCrypto_SUCCESS)); -} - -// Verify that a license may be loaded with a nonce. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithNonce) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); -} - -// Verify that a second license may not be loaded in a session. -TEST_P(OEMCryptoLicenseTest, LoadKeyNoNonceTwiceAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(0); - license_messages_.skip_nonce_check(); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - // A second load, should NOT succeed. - ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); -} - -// Verify that a second license may not be loaded in a session. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithNonceTwiceAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - // A second load, should NOT succeed. - ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); -} +/// @addtogroup entitle +/// @{ class OEMCryptoEntitlementLicenseTest : public OEMCryptoLicenseTest { protected: @@ -2108,6 +291,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest, LoadEntitlementKeysAPI17) { } TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } LoadEntitlementLicense(); uint32_t key_session_id = 0; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession( @@ -2158,6 +344,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest, */ TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysNoEntitlementKeysAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } license_messages_.set_license_type(OEMCrypto_EntitlementLicense); ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); @@ -2194,6 +383,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest, TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysWrongEntitlementKeysAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } LoadEntitlementLicense(); uint32_t key_session_id = 0; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession( @@ -2228,6 +420,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest, TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysWrongEntitledKeySessionAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } LoadEntitlementLicense(); uint32_t key_session_id = 0; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession( @@ -2266,6 +461,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest, TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysOemcryptoSessionAPI17) { + if (!global_features.supports_cas) { + GTEST_SKIP() << "OEMCrypto does not support CAS"; + } LoadEntitlementLicense(); uint32_t key_session_id = 0; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession( @@ -2282,35 +480,10 @@ TEST_P(OEMCryptoEntitlementLicenseTest, INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoEntitlementLicenseTest, Range(kCoreMessagesAPI, kCurrentAPI + 1)); -TEST_F(OEMCryptoMemoryLicenseTest, - OEMCryptoMemoryPrepareRenewalRequestForHugeBufferLength) { - RenewalRoundTrip renewal_messages(&license_messages_); - auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { - renewal_messages.set_message_size(buffer_length); - return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} +/// @} -TEST_F(OEMCryptoMemoryLicenseTest, - OEMCryptoMemoryPrepareRenewalRequestForHugeSignatureLength) { - RenewalRoundTrip renewal_messages(&license_messages_); - auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { - renewal_messages.set_request_signature_size(buffer_length); - return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoMemoryLicenseTest, - OEMCryptoMemoryPrepareRenewalRequestForHugeCoreMessageLength) { - RenewalRoundTrip renewal_messages(&license_messages_); - auto oemcrypto_function = [&renewal_messages](size_t buffer_length) { - renewal_messages.set_core_message_size(buffer_length); - return renewal_messages.SignAndCreateRequestWithCustomBufferLengths(); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} +/// @addtogroup security +/// @{ TEST_F(OEMCryptoMemoryLicenseTest, OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyIdLength) { @@ -2492,569 +665,12 @@ TEST_F(OEMCryptoMemoryLicenseTest, !kCheckStatus); } -// This verifies that entitled content keys API does not crash for unreasonable -// input message buffer lengths. -TEST_F(OEMCryptoMemoryLicenseTest, - OEMCryptoMemoryLoadEntitledKeysForHugeBufferLength) { - auto oemcrypto_function = [&](size_t buffer_length) { - size_t entitled_key_data_length = - entitled_message_.entitled_key_data_size(); - vector message(entitled_key_data_length); - memcpy(message.data(), entitled_message_.entitled_key_data(), - entitled_key_data_length); - message.resize(buffer_length); - return entitled_message_.LoadKeys(message); - }; - // We are not constructing a valid message for load entitled content keys. - // Hence skipping status check. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -// This tests load license with an 8k license response. -TEST_P(OEMCryptoLicenseTest, LoadKeyLargeBuffer) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - const size_t max_size = GetResourceValue(kLargeMessageSize); - license_messages_.set_message_size(max_size); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// Verify that you can't use LoadKeys on a v16 license. -TEST_F(OEMCryptoLicenseTestAPI16, UseWrongLoadAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - // After the license round trip was create for v16, we now tell it to use v15 - // so it call LoadKeys instead of LoadLicense. This means the license request - // was made from a v16 device, and the response was created and signed by a - // v16 server. So OEMCrypto should only accept it if we load it using - // LoadLicense. A call to LoadKeys should fail. - license_messages_.set_api_version(kCoreMessagesAPI - 1); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -//---------------------------------------------------------------------------// -//---------------------------------------------------------------------------// -// Each of the following LoadKeyWithBadRange_* tests is similar. They verify -// that OEMCrypto_LoadLicense checks the range of all the pointers. It should -// reject a message if the pointer does not point into the message buffer. -//---------------------------------------------------------------------------// -//---------------------------------------------------------------------------// -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_enc_mac_keys) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().enc_mac_keys.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_enc_mac_keys_iv) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().enc_mac_keys_iv.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_id) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().key_array[0].key_id.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_data) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().key_array[1].key_data.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_data_iv) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().key_array[1].key_data_iv.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_control) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().key_array[2].key_control.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_key_control_iv) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().key_array[2].key_control_iv.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadRange_pst) { - license_messages_.set_control(wvoec::kControlNonceOrEntry); - license_messages_.set_pst("my_pst"); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // See the comment in LicenseRoundTrip::LoadResponse for why we increment by - // the message size. - license_messages_.core_response().pst.offset += - sizeof(license_messages_.response_data()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - // If we have a pst, then we need a usage entry. - ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} -//---------------------------------------------------------------------------// -//---------------------------------------------------------------------------// - -// The IV should not be identical to the data right before the encrypted mac -// keys. This requirement was added in 15.2, so it frequently fails on -// production devices. -// This test is being restricted to v16 devices on rvc-dev branch because we -// only required v15.1 on Android for Q. -TEST_F(OEMCryptoLicenseTestAPI15, LoadKeyWithSuspiciousIVAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - - // This is suspicious: the data right before the mac keys is identical to the - // iv. - memcpy(license_messages_.response_data().padding, - license_messages_.response_data().mac_key_iv, - sizeof(license_messages_.response_data().padding)); - - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// Test that LoadKeys fails when a key is loaded with no key control block. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithNullKeyControl) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_response().key_array[2].key_control.offset = 0; - license_messages_.core_response().key_array[2].key_control.length = 0; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// Verify that LoadKeys fails when a key's nonce is wrong. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadNonce) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - for (unsigned int i = 0; i < license_messages_.num_keys(); i++) - license_messages_.response_data().keys[i].control.nonce ^= 42; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// Verify that LoadKeys fails when the core message's nonce is wrong. -TEST_F(OEMCryptoLicenseTestAPI16, LoadKeyWithBadNonce2) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_request().nonce ^= 42; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// Verify that LoadKeys fails when the core message's session is wrong. -TEST_F(OEMCryptoLicenseTestAPI16, LoadKeyWithBadNonce3) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_request().session_id++; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// Verify that LoadKeys fails when an attempt is made to use a nonce twice. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithRepeatNonce) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - const uint32_t nonce = session_.nonce(); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - // This is the first attempt. It should succeed. - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - // Now, open a new session and try to load a license with the same nonce. - session_.close(); - ASSERT_NO_FATAL_FAILURE(session_.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_)); - license_messages_.skip_nonce_check(); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - // Repeat the nonce. - license_messages_.core_request().nonce = nonce; - for (unsigned int i = 0; i < license_messages_.num_keys(); i++) - license_messages_.response_data().keys[i].control.nonce = htonl(nonce); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// This tests that a nonce cannot be used in new session. This is similar to -// the previous test, but does not use the nonce in the first session. The nonce -// should be tied to a session, so generating a nonce in the first session and -// then using it in the second session should fail. -TEST_P(OEMCryptoLicenseTest, LoadKeyNonceReopenSession) { - ASSERT_NO_FATAL_FAILURE(session_.GenerateNonce()); - uint32_t nonce = session_.nonce(); - // Do not use the nonce now. Close session and use it after re-opening. - ASSERT_NO_FATAL_FAILURE(session_.close()); - - // Actually, this isn't the same session. OEMCrypto opens a new session, but - // we are guarding against the possiblity that it re-uses the session data - // and might not clear out the nonce correctly. - ASSERT_NO_FATAL_FAILURE(session_.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_)); - license_messages_.skip_nonce_check(); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_request().nonce = nonce; - for (unsigned int i = 0; i < license_messages_.num_keys(); i++) - license_messages_.response_data().keys[i].control.nonce = htonl(nonce); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// This tests that a nonce cannot be used in wrong session. This is similar to -// the previous test, except we do not close session 1 before we open session 2. -TEST_P(OEMCryptoLicenseTest, LoadKeyNonceWrongSession) { - // First, open a session and generate a nonce. We don't use the nonce in this - // session. - Session s2; - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s2)); - ASSERT_NO_FATAL_FAILURE(s2.GenerateNonce()); - uint32_t nonce = s2.nonce(); - - // Do not use the nonce. Also, leave the session open. We want to make sure - // that session_ and s2 do NOT share a nonce. This is different from - // the LoadKeyNonceReopenSession in that we do not close s1. - - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_request().nonce = nonce; - for (unsigned int i = 0; i < license_messages_.num_keys(); i++) - license_messages_.response_data().keys[i].control.nonce = htonl(nonce); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages_.LoadResponse()); -} - -// LoadKeys should fail if the key control block as a bad verification string. -TEST_P(OEMCryptoLicenseTest, LoadKeyWithBadVerification) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.response_data().keys[1].control.verification[2] = 'Z'; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// This test verifies that LoadKeys still works when the message is not aligned -// in memory on a word (2 or 4 byte) boundary. -TEST_P(OEMCryptoLicenseTest, LoadKeyUnalignedMessageAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - - std::vector buffer(1, '0'); // A string of 1 byte long. - size_t offset = buffer.size(); - ASSERT_EQ(1u, offset); - // We assume that vectors are allocated on as a small chunk of data that is - // aligned on a word boundary. I.e. we assume buffer is word aligned. Next, - // we append the message to buffer after the single padding byte. - buffer.insert(buffer.end(), - license_messages_.encrypted_response_buffer().begin(), - license_messages_.encrypted_response_buffer().end()); - // Thus, buffer[offset] is NOT word aligned. - const uint8_t* unaligned_message = &buffer[offset]; - if (license_api_version_ < kCoreMessagesAPI) { - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadKeys( - session_.session_id(), unaligned_message, - license_messages_.encrypted_response_buffer().size(), - license_messages_.response_signature().data(), - license_messages_.response_signature().size(), - license_messages_.core_response().enc_mac_keys_iv, - license_messages_.core_response().enc_mac_keys, - license_messages_.core_response().key_array_length, - license_messages_.core_response().key_array, - license_messages_.core_response().pst, - license_messages_.core_response().srm_restriction_data, - static_cast( - license_messages_.core_response().license_type))); - } else { - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadLicense( - session_.session_id(), unaligned_message, - license_messages_.encrypted_response_buffer().size(), - license_messages_.serialized_core_message().size(), - license_messages_.response_signature().data(), - license_messages_.response_signature().size())); - } -} - -// Verifies that a session can't reload a license without being closed and -// reopened. -TEST_P(OEMCryptoLicenseTest, LoadLicenseAgainFailureAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_EQ(OEMCrypto_ERROR_LICENSE_RELOAD, license_messages_.LoadResponse()); -} - -TEST_P(OEMCryptoLicenseTestRangeAPI, LoadKeys) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - // Re-set the API version. The function VerifyRequestSignature sets the api to - // be a sane value. But in this test, we want to verify an unsupported version - // is rejected. - license_messages_.set_api_version(license_api_version_); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - - // If this is a future API, then LoadKeys should fail. - if (global_features.api_version < license_api_version_) { - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()) - << "Load License succeeded for future api kc" << license_api_version_; - } else { - // Otherwise, LoadKeys should succeed. - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()) - << "Load License failed for key control block kc" - << license_api_version_; - } -} - -// Range of API versions to test. This should start several versions old, and -// go to the current API + 2. We use +2 because we want to test at least 1 -// future API, and the ::testing::Range is not inclusive. -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseTestRangeAPI, - Range(10, kCurrentAPI + 2)); - -TEST_P(OEMCryptoLicenseTest, LoadKeysBadSignatureAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - license_messages_.response_signature()[0] ^= 42; - ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, - license_messages_.LoadResponse()); -} /// @} -/// @addtogroup decrypt +/// @addtogroup entitle /// @{ -// LoadKeys should fail if we try to load keys with no keys. -TEST_P(OEMCryptoLicenseTest, LoadKeyNoKeys) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(0); - license_messages_.set_num_keys(0); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// Like the previous test, except we ask for a nonce first. -TEST_P(OEMCryptoLicenseTest, LoadKeyNoKeyWithNonce) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_num_keys(0); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); -} - -// Following two tests will test huge values for num bytes clear, num bytes -// encrypted, input data length and clear address, clear address_length. -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForHugeNumBytesClearAndBuffers) { - TestDecryptCENCForHugeBufferLengths( - [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description->subsamples); - sub_samples[0].num_bytes_clear = - sub_samples[0].num_bytes_clear + message_size; - }, - !kCheckStatus); -} - -TEST_P(OEMCryptoLicenseTest, - DecryptCENCForNumBytesClearPlusEncryptedOverflowsSize) { - LoadLicense(); - OEMCrypto_SelectKey(session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, - OEMCrypto_CipherMode_CENC); - - size_t input_buffer_size = 1; - vector in_buffer(input_buffer_size); - vector out_buffer(in_buffer.size()); - - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description.subsamples); - // If Decrypt cenc API does not check for overflow on clear + encrypted - // addition operation. This will result in 1 which will match with input data - // length, which causes validation to pass. - sub_samples[0].num_bytes_clear = 2; - sub_samples[0].num_bytes_encrypted = ~0; - - // Create the pattern description (always 0,0 for CTR) - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - // Try to decrypt the data - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern)); -} - -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForHugeNumBytesEncryptedAndBuffers) { - TestDecryptCENCForHugeBufferLengths( - [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description->subsamples); - sub_samples[0].num_bytes_encrypted = - sub_samples[0].num_bytes_encrypted + message_size; - }, - !kCheckStatus); -} - -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForHugeSecureHandleLength) { - TestDecryptCENCForHugeBufferLengths( - [](size_t message_size, OEMCrypto_SampleDescription* sample_description) { - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description->subsamples); - // TestDecryptCENCForHugeBufferLengths alloctes huge secure handle - // buffer. - sample_description->buffers.output_descriptor.type = - OEMCrypto_BufferType_Secure; - sub_samples[0].num_bytes_clear = - sub_samples[0].num_bytes_clear + message_size; - }, - !kCheckStatus); -} - -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesClear) { - TestDecryptCENCForOutOfRangeOffsetsAndLengths( - [](OEMCrypto_SampleDescription* sample_description) { - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description->subsamples); - sub_samples[0].num_bytes_clear = sub_samples[0].num_bytes_clear + 1; - }, - !kDecryptCENCSecureBuffer); -} - -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesEncryptedAPI16) { - TestDecryptCENCForOutOfRangeOffsetsAndLengths( - [](OEMCrypto_SampleDescription* sample_description) { - OEMCrypto_SubSampleDescription* sub_samples = - const_cast( - sample_description->subsamples); - sub_samples[0].num_bytes_encrypted = - sub_samples[0].num_bytes_encrypted + 1; - }, - !kDecryptCENCSecureBuffer); -} - -TEST_P(OEMCryptoLicenseTest, - OEMCryptoMemoryDecryptCENCForOutOfRangeSecureBufferOffset) { - TestDecryptCENCForOutOfRangeOffsetsAndLengths( - [](OEMCrypto_SampleDescription* sample_description) { - sample_description->buffers.output_descriptor.type = - OEMCrypto_BufferType_Secure; - sample_description->buffers.output_descriptor.buffer.secure.offset = - sample_description->buffers.output_descriptor.buffer.secure - .secure_buffer_length + - 1; - }, - kDecryptCENCSecureBuffer); -} - -// Cannot decrypt without first selecting a key. -TEST_P(OEMCryptoLicenseTest, FailDecryptWithoutSelect) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE( - session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// SelectKey should fail if we attempt to select a key that has not been loaded. -// Also, the error should be NO_CONTENT_KEY. -// This test should pass for v15 devices, except that the exact error code was -// not specified until v16. -TEST_P(OEMCryptoLicenseTest, SelectKeyNotThereAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - const char* key_id = "no_key"; - OEMCryptoResult sts = OEMCrypto_SelectKey( - session_.session_id(), reinterpret_cast(key_id), - strlen(key_id), OEMCrypto_CipherMode_CENC); - if (sts != OEMCrypto_SUCCESS) { - EXPECT_EQ(OEMCrypto_ERROR_NO_CONTENT_KEY, sts); - } else { - // Delayed error code. If select key was a success, then we should - // eventually see the error when we decrypt. - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Generate test data - for (size_t i = 0; i < in_buffer.size(); i++) in_buffer[i] = i % 256; - - // Create the pattern description (always 0,0 for CTR) - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_EQ(sts, OEMCrypto_ERROR_NO_CONTENT_KEY); - } -} - -TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyAPI17) { +TEST_P(OEMCryptoLicenseTest, GetKeyHandleEntitledKeyAPI17) { license_messages_.set_license_type(OEMCrypto_EntitlementLicense); ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); @@ -3071,11 +687,12 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyAPI17) { entitled_message_1.SetContentKeyId(0, content_key_id); ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true)); + vector key_handle; ASSERT_EQ( OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(key_session_id, - reinterpret_cast(content_key_id), - strlen(content_key_id), OEMCrypto_CipherMode_CENC)); + GetKeyHandleIntoVector( + key_session_id, reinterpret_cast(content_key_id), + strlen(content_key_id), OEMCrypto_CipherMode_CENC, key_handle)); } // SelectEntitledKey should fail if we attempt to select a key that has not been @@ -3172,10 +789,9 @@ TEST_P(OEMCryptoLicenseTest, // Close the OEMCrypto session. session_.close(); // All entitled key sessions associated with the OEMCrypto session should - // already be been destroyed, - OEMCryptoResult sts = OEMCrypto_RemoveEntitledKeySession(key_session_id_1); - EXPECT_TRUE(sts == OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION || - sts == OEMCrypto_ERROR_INVALID_SESSION); + // already be destroyed. + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_RemoveEntitledKeySession(key_session_id_1)); // Open a new session just for OEMCryptoLicenseTest TearDown. session_.open(); } @@ -3289,8 +905,8 @@ TEST_P(OEMCryptoLicenseTest, strlen(content_key_id_1))); } -// Decrypt should fail if the license is entitlement license, and the decrypt -// call is made with oemcrypto session id (should use entitled key session id +// Decrypt should fail if the license is entitlement license, and the key handle +// is requested from the oemcrypto session (should use entitled key session id // instead). TEST_P(OEMCryptoLicenseTest, RejectOecSessionDecryptWithEntitlementLicenseAPI17) { @@ -3303,35 +919,31 @@ TEST_P(OEMCryptoLicenseTest, uint32_t key_session_id; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession( session_.session_id(), &key_session_id)); - // Construct and load content keys to entitled key session. - EntitledMessage entitled_message(&license_messages_); - entitled_message.FillKeyArray(); - entitled_message.SetEntitledKeySession(key_session_id); - const char* content_key_id = "content_key_id"; - entitled_message.SetContentKeyId(0, content_key_id); - ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true)); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled( - OEMCrypto_SUCCESS, key_session_id, - reinterpret_cast(content_key_id), - strlen(content_key_id))); - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - ASSERT_NO_FATAL_FAILURE(GenerateSimpleSampleDescription( - in_buffer, out_buffer, &sample_description, &subsample_description)); - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + // Skip the rest of this test on platforms that do not support separate + // entitlement and entitled sessions. if (global_features.supports_cas || session_.session_id() != key_session_id) { - // Try to decrypt the data with oemcrypto session id. - EXPECT_EQ(OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, - 1, &pattern), - OEMCrypto_ERROR_INVALID_CONTEXT); + // Construct and load content keys to entitled key session. + EntitledMessage entitled_message(&license_messages_); + entitled_message.FillKeyArray(); + entitled_message.SetEntitledKeySession(key_session_id); + constexpr char kContentKeyId[] = "content_key_id"; + const size_t content_key_id_length = strlen(kContentKeyId); + entitled_message.SetContentKeyId(0, kContentKeyId); + ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true)); + ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled( + OEMCrypto_SUCCESS, key_session_id, + reinterpret_cast(kContentKeyId), + content_key_id_length)); + + // Try to get a key handle with the oemcrypto session id. + vector key_handle; + EXPECT_NE(GetKeyHandleIntoVector( + session_.session_id(), + reinterpret_cast(kContentKeyId), + content_key_id_length, OEMCrypto_CipherMode_CENC, key_handle), + OEMCrypto_SUCCESS); } - // Decrypt the data with entitled key session id succeed. - EXPECT_EQ( - OEMCrypto_DecryptCENC(key_session_id, &sample_description, 1, &pattern), - OEMCrypto_SUCCESS); } // This verifies that an entitled key session can be reassociated to an @@ -3342,11 +954,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) { ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - // Setup another session. - Session session2; - ASSERT_NO_FATAL_FAILURE(session2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session2)); - ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey()); + // Setup an entitled key session in the first OEMCrypto session. uint32_t key_session_id; OEMCryptoResult sts = OEMCrypto_CreateEntitledKeySession( @@ -3357,7 +965,12 @@ TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) { entitled_message.SetEntitledKeySession(key_session_id); ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true)); - // Now reassociate the entitled key session to the second OEMCrypto session. + // Setup another session. + Session session2; + ASSERT_NO_FATAL_FAILURE(session2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session2)); + // session2 does not have entitlement keys. Re-associating the entitled key + // session to session2 should fail OEMCryptoResult status = OEMCrypto_ReassociateEntitledKeySession( key_session_id, session2.session_id()); if (status == OEMCrypto_ERROR_NOT_IMPLEMENTED && @@ -3365,225 +978,45 @@ TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) { GTEST_SKIP() << "Skipping test because " "OEMCrypto_ReassociateEntitledKeySession not implemented."; } - ASSERT_EQ(OEMCrypto_SUCCESS, status); - // session2 does not have entitlement keys. - ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(false)); + EXPECT_NE(OEMCrypto_SUCCESS, status); + + // session2 loads the correct entitlement keys. + LicenseRoundTrip license_messages2(&session2); + license_messages2.set_license_type(OEMCrypto_EntitlementLicense); + ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); + // Re-associating to session2 should succeed. + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession( + key_session_id, session2.session_id())); // Now reassociate the entitled key session back to the first OEMCrypto // session. ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession( key_session_id, session_.session_id())); ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true)); + + // session3 has unmatched key policies + Session session3; + ASSERT_NO_FATAL_FAILURE(session3.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session3)); + LicenseRoundTrip license_messages3(&session3); + license_messages3.set_license_type(OEMCrypto_EntitlementLicense); + license_messages3.set_control(license_messages_.control() + 1); + ASSERT_NO_FATAL_FAILURE(license_messages3.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages3.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages3.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages3.LoadResponse()); + // Re-associating to session3 should fail. + EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession( + key_session_id, session3.session_id())); } -// 'cens' mode is no longer supported in v16 -TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); +/// @} - OEMCryptoResult sts; - sts = OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Create a non-zero pattern to indicate this is 'cens' - OEMCrypto_CENCEncryptPatternDesc pattern = {1, 9}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); -} - -// 'cbc1' mode is no longer supported in v16 -TEST_P(OEMCryptoLicenseTest, RejectCbc1API16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - OEMCryptoResult sts; - sts = OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CBCS); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Create a zero pattern to indicate this is 'cbc1' - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); -} - -TEST_P(OEMCryptoLicenseTest, RejectCbcsWithBlockOffset) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - OEMCryptoResult sts; - sts = OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CBCS); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - subsample_description.block_offset = 5; // Any value 1-15 will do. - - // Create a non-zero pattern to indicate this is 'cbcs'. - OEMCrypto_CENCEncryptPatternDesc pattern = {1, 9}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); -} - -TEST_P(OEMCryptoLicenseTest, RejectOversizedBlockOffset) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - OEMCryptoResult sts; - sts = OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - subsample_description.block_offset = 0xFF; // Anything 16+ - - // Create a zero pattern to indicate this is 'cenc'. - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_NE(OEMCrypto_SUCCESS, sts); - - // Try again with the minimum invalid value - subsample_description.block_offset = 16; - sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, - &pattern); - EXPECT_NE(OEMCrypto_SUCCESS, sts); -} - -// After loading keys, we should be able to query the key control block. If we -// attempt to query a key that has not been loaded, the error should be -// NO_CONTENT_KEY. -TEST_P(OEMCryptoLicenseTest, QueryKeyControl) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - // Note: successful cases are tested in VerifyTestKeys. - KeyControlBlock block; - size_t size = sizeof(block) - 1; - OEMCryptoResult sts = OEMCrypto_QueryKeyControl( - session_.session_id(), license_messages_.response_data().keys[0].key_id, - license_messages_.response_data().keys[0].key_id_length, - reinterpret_cast(&block), &size); - if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { - return; - } - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - const char* key_id = "no_key"; - size = sizeof(block); - ASSERT_EQ(OEMCrypto_ERROR_NO_CONTENT_KEY, - OEMCrypto_QueryKeyControl( - session_.session_id(), reinterpret_cast(key_id), - strlen(key_id), reinterpret_cast(&block), &size)); -} - -// This case tests against the issue where certain 16.4.x SDK versions return a -// clear key control block (KCB) in the license response. An OEMCrypto v17.1+ -// implementation should be able to handle the clear KCB in the 16.4.x response -// and load the license correctly. -TEST_F(OEMCryptoSessionTests, ClearKcbAPI17) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - // Set odk version in the license response to be 16.4 - oemcrypto_core_message::features::CoreMessageFeatures features = {}; - features.maximum_major_version = 16; - features.maximum_minor_version = 4; - constexpr bool kForceClearKcb = true; - ASSERT_NO_FATAL_FAILURE( - license_messages.EncryptAndSignResponseWithCoreMessageFeatures( - features, kForceClearKcb)); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - - KeyControlBlock block; - size_t size = sizeof(block); - OEMCryptoResult sts = OEMCrypto_QueryKeyControl( - s.session_id(), license_messages.response_data().keys[0].key_id, - license_messages.response_data().keys[0].key_id_length, - reinterpret_cast(&block), &size); - if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) { - return; - } - ASSERT_EQ(OEMCrypto_SUCCESS, sts); -} - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryLoadLicenseForHugeSignatureLength) { - auto oemcrypto_function = [&](size_t signature_size) { - Session s; - LicenseRoundTrip license_messages(&s); - s.open(); - InstallTestRSAKey(&s); - license_messages.SignAndVerifyRequest(); - license_messages.CreateDefaultResponse(); - license_messages.EncryptAndSignResponse(); - vector signature(signature_size); - OEMCryptoResult result = OEMCrypto_LoadLicense( - s.session_id(), license_messages.encrypted_response_buffer().data(), - license_messages.encrypted_response_buffer().size(), - license_messages.serialized_core_message().size(), signature.data(), - signature_size); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} +/// @addtogroup security +/// @{ TEST_P(OEMCryptoLicenseOverflowTest, OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyIdLength) { @@ -3975,1709 +1408,15 @@ TEST_P(OEMCryptoLicenseOverflowTest, INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseOverflowTest, Range(kCurrentAPI - 1, kCurrentAPI + 1)); -TEST_F(OEMCryptoSessionTests, OEMCryptoMemoryLoadRenewalForHugeResponseLength) { - auto oemcrypto_function = [&](size_t message_size) { - Session s; - LicenseRoundTrip license_messages(&s); - s.open(); - LoadLicense(s, license_messages); - - RenewalRoundTrip renewal_messages(&license_messages); - renewal_messages.SignAndVerifyRequest(); - renewal_messages.CreateDefaultResponse(); - renewal_messages.set_message_size(message_size); - renewal_messages.EncryptAndSignResponse(); - OEMCryptoResult result = renewal_messages.LoadResponse(); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryLoadRenewalForHugeSignatureLength) { - auto oemcrypto_function = [&](size_t signature_size) { - Session s; - LicenseRoundTrip license_messages(&s); - s.open(); - LoadLicense(s, license_messages); - - RenewalRoundTrip renewal_messages(&license_messages); - renewal_messages.SignAndVerifyRequest(); - renewal_messages.CreateDefaultResponse(); - renewal_messages.EncryptAndSignResponse(); - vector signature(signature_size); - OEMCryptoResult result = OEMCrypto_LoadRenewal( - s.session_id(), renewal_messages.encrypted_response_buffer().data(), - renewal_messages.encrypted_response_buffer().size(), - renewal_messages.serialized_core_message().size(), signature.data(), - signature_size); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryLoadRenewalForHugeCoreMessageLength) { - auto oemcrypto_function = [&](size_t core_message_size) { - Session s; - LicenseRoundTrip license_messages(&s); - s.open(); - LoadLicense(s, license_messages); - - RenewalRoundTrip renewal_messages(&license_messages); - renewal_messages.SignAndVerifyRequest(); - renewal_messages.CreateDefaultResponse(); - renewal_messages.set_core_message_size(core_message_size); - renewal_messages.EncryptAndSignResponse(); - OEMCryptoResult result = renewal_messages.LoadResponse(); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_id_length. -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryQueryKeyControlForHugeKeyIdLength) { - Session session; - LicenseRoundTrip license_messages(&session); - session.open(); - LoadLicense(session, license_messages); - OEMCrypto_SESSION session_id = session.session_id(); - vector valid_key_id( - license_messages.response_data().keys[0].key_id, - license_messages.response_data().keys[0].key_id + kTestKeyIdMaxLength); - auto oemcrypto_function = [&session_id, - &valid_key_id](size_t additional_key_id_length) { - vector key_id(valid_key_id); - key_id.resize(valid_key_id.size() + additional_key_id_length); - KeyControlBlock block; - size_t size = sizeof(block); - return OEMCrypto_QueryKeyControl(session_id, key_id.data(), key_id.size(), - reinterpret_cast(&block), &size); - }; - // We do not want to stop as soon as API results in an error as it would - // return error on first iteration as key_id is invalid. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_control_block -// length. -TEST_F(OEMCryptoSessionTests, - OEMCryptoMemoryQueryKeyControlForHugeKeyControlBlockLength) { - Session session; - LicenseRoundTrip license_messages(&session); - session.open(); - LoadLicense(session, license_messages); - OEMCrypto_SESSION session_id = session.session_id(); - uint8_t* key_id = license_messages.response_data().keys[0].key_id; - size_t key_id_length = license_messages.response_data().keys[0].key_id_length; - auto oemcrypto_function = [&session_id, &key_id, - &key_id_length](size_t buffer_length) { - size_t key_control_block_length = buffer_length; - vector key_control_block(key_control_block_length); - return OEMCrypto_QueryKeyControl(session_id, key_id, key_id_length, - key_control_block.data(), - &key_control_block_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// If the device says it supports anti-rollback in the hardware, then it should -// accept a key control block with the anti-rollback hardware bit set. -// Otherwise, it should reject that key control block. -TEST_P(OEMCryptoLicenseTest, AntiRollbackHardwareRequired) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(wvoec::kControlRequireAntiRollbackHardware); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - OEMCryptoResult sts = license_messages_.LoadResponse(); - if (OEMCrypto_IsAntiRollbackHwPresent()) { - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - } else { - ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, sts); - } -} - -// This test verifies that OEMCrypto can load the number of keys required for -// the reported resource level. -TEST_P(OEMCryptoLicenseTest, MinimumKeys) { - const size_t num_keys = GetResourceValue(kMaxKeysPerSession); - ASSERT_LE(num_keys, kMaxNumKeys) << "Test constants need updating."; - license_messages_.set_num_keys(static_cast(num_keys)); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - constexpr bool kSelectKeyFirst = true; - for (size_t key_index = 0; key_index < num_keys; key_index++) { - ASSERT_NO_FATAL_FAILURE( - session_.TestDecryptCTR(kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); - } -} - -// This test verifies that OEMCrypto can load the total number of keys required -// for the reported resource level. -void TestMaxKeys(SessionUtil* util, size_t num_keys_per_session) { - const size_t max_total_keys = GetResourceValue(kMaxTotalKeys); - ASSERT_LE(num_keys_per_session, kMaxNumKeys) << "Update test constants."; - std::vector> sessions; - std::vector> licenses; - size_t total_keys = 0; - for (size_t i = 0; total_keys < max_total_keys; i++) { - sessions.push_back(std::unique_ptr(new Session())); - licenses.push_back(std::unique_ptr( - new LicenseRoundTrip(sessions[i].get()))); - const size_t num_keys = - std::min(max_total_keys - total_keys, num_keys_per_session); - licenses[i]->set_num_keys(static_cast(num_keys)); - total_keys += num_keys; - ASSERT_NO_FATAL_FAILURE(sessions[i]->open()); - ASSERT_NO_FATAL_FAILURE(util->InstallTestRSAKey(sessions[i].get())); - ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest()); - } - for (size_t i = 0; i < licenses.size(); i++) { - ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse()); - } - constexpr bool kSelectKeyFirst = true; - for (size_t i = 0; i < licenses.size(); i++) { - for (size_t key_index = 0; key_index < licenses[i]->num_keys(); - key_index++) { - ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR( - kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); - } - } - // Second call to decrypt for each session. - for (size_t i = 0; i < licenses.size(); i++) { - for (size_t key_index = 0; key_index < licenses[i]->num_keys(); - key_index++) { - ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR( - kSelectKeyFirst, OEMCrypto_SUCCESS, key_index)); - } - } -} - -// This test verifies that OEMCrypto can load the total number of keys required -// for the reported resource level. This maximizes keys per session. -TEST_P(OEMCryptoLicenseTest, MaxTotalKeysPerSession) { - const size_t max_num_keys = GetResourceValue(kMaxKeysPerSession); - TestMaxKeys(this, max_num_keys); -} - -// This test verifies that OEMCrypto can load the total number of keys required -// for the reported resource level. This maximizes number of sessions. -TEST_P(OEMCryptoLicenseTest, MaxTotalKeysManySessions) { - const size_t max_total_keys = GetResourceValue(kMaxTotalKeys); - const size_t max_sessions = GetResourceValue(kMaxConcurrentSession); - const size_t max_num_keys = max_total_keys / max_sessions + 1; - TestMaxKeys(this, max_num_keys); -} - -// This test verifies that the minimum patch level can be required. The device -// should accept a key control block with the current patch level, and it should -// reject any key control blocks with a future patch level. -TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { - uint8_t patch_level = OEMCrypto_Security_Patch_Level(); - printf(" Current Patch Level: %u.\n", patch_level); - { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_control(patch_level - << wvoec::kControlSecurityPatchLevelShift); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - EXPECT_EQ(global_features.api_version, license_messages.api_version()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - } - // Reject any future patch levels. - if (patch_level < 0x3F) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_control((patch_level + 1) - << wvoec::kControlSecurityPatchLevelShift); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, license_messages.LoadResponse()); - } - // Accept an old patch level. - if (patch_level > 0) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_control((patch_level - 1) - << wvoec::kControlSecurityPatchLevelShift); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - } -} - -// Used to test the different HDCP versions. This test is parameterized by the -// required HDCP version in the key control block. -class OEMCryptoSessionTestDecryptWithHDCP : public OEMCryptoSessionTests, - public WithParamInterface { - protected: - void DecryptWithHDCP(OEMCrypto_HDCP_Capability version) { - OEMCryptoResult sts; - OEMCrypto_HDCP_Capability current, maximum; - sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_control((version << wvoec::kControlHDCPVersionShift) | - wvoec::kControlObserveHDCP | - wvoec::kControlHDCPRequired); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - - if (((version <= HDCP_V2_3 || current >= HDCP_V1_0) && version > current) || - (current == HDCP_V1 && version >= HDCP_V1_0)) { - if (global_features.api_version >= 16) { - // Can provide either OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION or - // OEMCrypto_ERROR_INSUFFICIENT_HDCP. TestDecryptCTR allows either to be - // reported if OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION is expected. - ASSERT_NO_FATAL_FAILURE( - s.TestDecryptCTR(true, OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION)) - << "Failed when current HDCP = " << HDCPCapabilityAsString(current) - << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) - << ", license HDCP = " << HDCPCapabilityAsString(version); - } else { - ASSERT_NO_FATAL_FAILURE( - s.TestDecryptCTR(true, OEMCrypto_ERROR_INSUFFICIENT_HDCP)) - << "Failed when current HDCP = " << HDCPCapabilityAsString(current) - << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) - << ", license HDCP = " << HDCPCapabilityAsString(version); - } - } else { - ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(true, OEMCrypto_SUCCESS)) - << "Failed when current HDCP = " << HDCPCapabilityAsString(current) - << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) - << ", license HDCP = " << HDCPCapabilityAsString(version); - } - } -}; - -TEST_P(OEMCryptoSessionTestDecryptWithHDCP, DecryptAPI09) { - // Test parameterized by HDCP version. - DecryptWithHDCP(static_cast(GetParam())); -} -INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestDecryptWithHDCP, - Range(1, 6)); - -// Used to test the different HDCP versions. This test is parameterized by the -// required HDCP version in the key control block. -class OEMCryptoSessionTestLoadCasKeysWithHDCP : public OEMCryptoSessionTests, - public WithParamInterface { - protected: - void LoadCasKeysWithHDCP(OEMCrypto_HDCP_Capability version) { - OEMCryptoResult sts; - OEMCrypto_HDCP_Capability current, maximum; - sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_control((version << wvoec::kControlHDCPVersionShift) | - wvoec::kControlObserveHDCP | - wvoec::kControlHDCPRequired); - license_messages.set_license_type(OEMCrypto_EntitlementLicense); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - - uint32_t key_session_id; - sts = OEMCrypto_CreateEntitledKeySession(s.session_id(), &key_session_id); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - EntitledMessage entitled_message_1(&license_messages); - entitled_message_1.FillKeyArray(); - entitled_message_1.SetEntitledKeySession(key_session_id); - - if (((version <= HDCP_V2_3 || current >= HDCP_V1_0) && version > current) || - (current == HDCP_V1 && version >= HDCP_V1_0)) { - ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys( - /*load_even=*/true, /*load_odd=*/true, - OEMCrypto_ERROR_INSUFFICIENT_HDCP)) - << "Failed when current HDCP = " << HDCPCapabilityAsString(current) - << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) - << ", license HDCP = " << HDCPCapabilityAsString(version); - } else { - ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys( - /*load_even=*/true, /*load_odd=*/true, OEMCrypto_SUCCESS)) - << "Failed when current HDCP = " << HDCPCapabilityAsString(current) - << ", maximum HDCP = " << HDCPCapabilityAsString(maximum) - << ", license HDCP = " << HDCPCapabilityAsString(version); - } - } -}; - -TEST_P(OEMCryptoSessionTestLoadCasKeysWithHDCP, CasOnlyLoadCasKeysAPI17) { - // Test parameterized by HDCP version. - LoadCasKeysWithHDCP(static_cast(GetParam())); -} -INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestLoadCasKeysWithHDCP, - Range(1, 6)); /// @} -/// @addtogroup renewal +/// @addtogroup cas /// @{ -// -// Load, Refresh Keys Test -// -class OEMCryptoRefreshTest : public OEMCryptoLicenseTest { - protected: - void SetUp() override { - OEMCryptoLicenseTest::SetUp(); - // These values allow us to run a few simple duration tests or just start - // playback right away. All times are in seconds since the license was - // signed. - // Soft expiry false means timers are strictly enforce. - timer_limits_.soft_enforce_rental_duration = true; - timer_limits_.soft_enforce_playback_duration = false; - // Playback may begin immediately. - timer_limits_.earliest_playback_start_seconds = 0; - // First playback may be within the first two seconds. - timer_limits_.rental_duration_seconds = kDuration; - // Once started, playback may last two seconds without a renewal. - timer_limits_.initial_renewal_duration_seconds = kDuration; - // Total playback is not limited. - timer_limits_.total_playback_duration_seconds = 0; - } +/// @} - void LoadLicense() { - license_messages_.core_response().timer_limits = timer_limits_; - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - } - - void MakeRenewalRequest(RenewalRoundTrip* renewal_messages) { - ASSERT_NO_FATAL_FAILURE(renewal_messages->SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(renewal_messages->CreateDefaultResponse()); - } - - void LoadRenewal(RenewalRoundTrip* renewal_messages, - OEMCryptoResult expected_result) { - ASSERT_NO_FATAL_FAILURE(renewal_messages->EncryptAndSignResponse()); - ASSERT_EQ(expected_result, renewal_messages->LoadResponse()); - } - - ODK_TimerLimits timer_limits_; -}; - -// This class is for the refresh tests that should only be run on licenses with -// a core message. -class OEMCryptoRefreshTestAPI16 : public OEMCryptoRefreshTest {}; - -// Refresh keys should work if the license uses a nonce. -TEST_P(OEMCryptoRefreshTest, RefreshWithNonce) { - LoadLicense(); - RenewalRoundTrip renewal_messages(&license_messages_); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); -} - -// Refresh keys should work if the license does not use a nonce. -TEST_P(OEMCryptoRefreshTest, RefreshNoNonce) { - license_messages_.set_control(0); - LoadLicense(); - RenewalRoundTrip renewal_messages(&license_messages_); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); -} - -// Refresh keys should NOT work if a license has not been loaded. -TEST_P(OEMCryptoRefreshTestAPI16, RefreshNoLicense) { - Session s; - s.open(); - constexpr size_t message_size = kMaxCoreMessage + 42; - std::vector data(message_size); - for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF; - size_t gen_signature_length = 0; - size_t core_message_length = 0; - OEMCryptoResult sts = OEMCrypto_PrepAndSignRenewalRequest( - s.session_id(), data.data(), data.size(), &core_message_length, nullptr, - &gen_signature_length); - ASSERT_LT(core_message_length, message_size); - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - vector gen_signature(gen_signature_length); - sts = OEMCrypto_PrepAndSignRenewalRequest( - s.session_id(), data.data(), data.size(), &core_message_length, - gen_signature.data(), &gen_signature_length); - } - ASSERT_NE(OEMCrypto_SUCCESS, sts); -} - -// Refresh keys should fail if the nonce is not in the session. -TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadNonce) { - LoadLicense(); - RenewalRoundTrip renewal_messages(&license_messages_); - MakeRenewalRequest(&renewal_messages); - renewal_messages.core_request().nonce ^= 42; - LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE); -} - -// Refresh keys should fail if the session_id does not match the license. -TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadSessionID) { - LoadLicense(); - RenewalRoundTrip renewal_messages(&license_messages_); - MakeRenewalRequest(&renewal_messages); - renewal_messages.core_request().session_id += 1; - LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE); -} - -// Refresh keys should handle the maximum message size. -TEST_P(OEMCryptoRefreshTest, RefreshLargeBuffer) { - LoadLicense(); - RenewalRoundTrip renewal_messages(&license_messages_); - const size_t max_size = GetResourceValue(kLargeMessageSize); - renewal_messages.set_message_size(max_size); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); -} - -// This situation would occur if an app only uses one key in the license. When -// that happens, SelectKey would be called before the first decrypt, and then -// would not need to be called again, even if the license is refreshed. -TEST_P(OEMCryptoRefreshTest, RefreshWithNoSelectKey) { - LoadLicense(); - - // Call select key before the refresh. No calls below to TestDecryptCTR with - // select key set to true. - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true)); - - // This should still be valid key, even if the refresh failed, because this - // is before the original license duration. - wvutil::TestSleep::Sleep(kShortSleep); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false)); - - // This should be after duration of the original license, but before the - // expiration of the refresh message. This should fail until we have loaded - // the renewal. - wvutil::TestSleep::Sleep(kShortSleep + kLongSleep); - ASSERT_NO_FATAL_FAILURE( - session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); - - RenewalRoundTrip renewal_messages(&license_messages_); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); - - // After we've loaded the renewal, decrypt should succeed again. - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false)); -} - -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoRefreshTest, - Range(kCurrentAPI - 1, kCurrentAPI + 1)); - -// These tests only work when the license has a core message. -INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoRefreshTestAPI16, - Range(kCoreMessagesAPI, kCurrentAPI + 1)); - -// If the license does not allow a hash, then we should not compute one. -TEST_P(OEMCryptoLicenseTest, HashForbiddenAPI15) { - uint32_t hash_type = OEMCrypto_SupportsDecryptHash(); - // If hash is not supported, or is vendor defined, don't try to test it. - if (hash_type != OEMCrypto_CRC_Clear_Buffer) return; - - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - uint32_t frame_number = 1; - uint32_t hash = 42; - // It is OK to set the hash before loading the keys - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_SetDecryptHash(session_.session_id(), frame_number, - reinterpret_cast(&hash), - sizeof(hash))); - // It is OK to select the key and decrypt. - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); - // But the error code should be bad. - ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, - OEMCrypto_GetHashErrorCode(session_.session_id(), &frame_number)); -} - -// This test verifies that OEMCrypto_SetDecryptHash doesn't crash for a very -// large hash buffer. -TEST_F(OEMCryptoMemoryLicenseTest, - OEMCryptoMemoryDecryptHashForHugeHashBuffer) { - uint32_t session_id = session_.session_id(); - auto f = [session_id](size_t hash_length) { - uint32_t frame_number = 1; - vector hash_buffer(hash_length); - return OEMCrypto_SetDecryptHash(session_id, frame_number, - hash_buffer.data(), hash_buffer.size()); - }; - TestHugeLengthDoesNotCrashAPI(f, kCheckStatus); -} - -// This test verifies OEMCrypto_SetDecryptHash for out of range frame number. -TEST_P(OEMCryptoLicenseTest, DecryptHashForOutOfRangeFrameNumber) { - uint32_t frame_number = kHugeRandomNumber; - uint32_t hash = 42; - ASSERT_NO_FATAL_FAILURE(OEMCrypto_SetDecryptHash( - session_.session_id(), frame_number, - reinterpret_cast(&hash), sizeof(hash))); -} - -// -// Decrypt Tests -- these test Decrypt CTR mode only. -// -TEST_P(OEMCryptoLicenseTest, Decrypt) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); -} - -// Verify that a zero duration means infinite license duration. -TEST_P(OEMCryptoLicenseTest, DecryptZeroDuration) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = 0; - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR()); -} - -struct SubsampleSize { - size_t clear_size; - size_t encrypted_size; - SubsampleSize(size_t clear, size_t encrypted) - : clear_size(clear), encrypted_size(encrypted) {} -}; - -// Struct for holding the data for one test sample in the decrypt tests. -struct TestSample { - // Encrypted data -- this is input to OEMCrypto, and output from EncryptData. - std::vector encrypted_buffer; - std::vector clear_buffer; // OEMCrypto store clear output here. - std::vector truth_buffer; // Truth data for clear text. - OEMCrypto_SampleDescription description; - std::vector subsamples; - int secure_buffer_fid; -}; - -// A class of tests that test decryption for a variety of patterns and modes. -// This test is parameterized by three parameters: -// 1. The pattern used for pattern decryption. -// 2. The cipher mode for decryption: either CTR or CBC. -// 3. A boolean that determines if decrypt in place should be done. When the -// output buffer is clear, it should be possible for the input and output -// buffers to be the same. -class OEMCryptoSessionTestsDecryptTests - : public OEMCryptoLicenseTestAPI16, - public WithParamInterface> { - protected: - void SetUp() override { - OEMCryptoLicenseTestAPI16::SetUp(); - pattern_ = ::testing::get<0>(GetParam()); - cipher_mode_ = ::testing::get<1>(GetParam()); - decrypt_inplace_ = ::testing::get<2>(GetParam()).decrypt_inplace; - output_buffer_type_ = ::testing::get<2>(GetParam()).type; - verify_crc_ = global_features.supports_crc; - // Pick a random key. - EXPECT_EQ(GetRandBytes(key_, sizeof(key_)), 1); - // Pick a random starting iv. Some tests override this before using it. - EXPECT_EQ(GetRandBytes(initial_iv_, sizeof(initial_iv_)), 1); - } - - void TearDown() override { - FreeSecureBuffers(); - OEMCryptoLicenseTestAPI16::TearDown(); - } - - void SetSubsampleSizes(std::vector subsample_sizes) { - // This is just sugar for having one sample with the given subsamples in it. - SetSampleSizes({subsample_sizes}); - } - - void SetSampleSizes(std::vector> sample_sizes) { - ASSERT_GT(sample_sizes.size(), 0u); - samples_.clear(); - samples_.reserve(sample_sizes.size()); - - // Convert all the size arrays to TestSample structs - for (const std::vector& subsample_sizes : sample_sizes) { - // This could be one line if we had C++17 - samples_.emplace_back(); - TestSample& sample = samples_.back(); - - ASSERT_GT(subsample_sizes.size(), 0u); - sample.subsamples.reserve(subsample_sizes.size()); - - // Convert all the sizes to subsample descriptions and tally the total - // sample size - size_t sample_size = 0; - size_t current_block_offset = 0; - for (const SubsampleSize& size : subsample_sizes) { - sample.subsamples.push_back(OEMCrypto_SubSampleDescription{ - size.clear_size, size.encrypted_size, - 0, // Subsample Flags, to be filled in after the loop - current_block_offset}); - - // Update the rolling variables - sample_size += size.clear_size + size.encrypted_size; - if (cipher_mode_ == OEMCrypto_CipherMode_CENC) { - current_block_offset = - (current_block_offset + size.encrypted_size) % AES_BLOCK_SIZE; - } - } - - // Set the subsample flags now that all the subsamples are processed - sample.subsamples.front().subsample_flags |= OEMCrypto_FirstSubsample; - sample.subsamples.back().subsample_flags |= OEMCrypto_LastSubsample; - - // Set related information on the sample description - sample.description.subsamples = sample.subsamples.data(); - sample.description.subsamples_length = sample.subsamples.size(); - sample.description.buffers.input_data_length = sample_size; - } - } - - // Set up the input buffer and either a clear or secure output buffer for each - // test sample. This should be called after SetSubsampleSizes(). - void MakeBuffers() { - for (TestSample& sample : samples_) { - const size_t total_size = sample.description.buffers.input_data_length; - ASSERT_GT(total_size, 0u); - sample.encrypted_buffer.clear(); - sample.truth_buffer.clear(); - sample.clear_buffer.clear(); - sample.encrypted_buffer.resize(total_size); - sample.truth_buffer.resize(total_size); - for (size_t i = 0; i < total_size; i++) sample.truth_buffer[i] = i % 256; - - OEMCrypto_DestBufferDesc& output_descriptor = - sample.description.buffers.output_descriptor; - output_descriptor.type = output_buffer_type_; - switch (output_descriptor.type) { - case OEMCrypto_BufferType_Clear: - if (decrypt_inplace_) { - // Add some padding to verify there is no overrun. - sample.encrypted_buffer.resize(total_size + kBufferOverrunPadding, - 0xaa); - output_descriptor.buffer.clear.clear_buffer = - sample.encrypted_buffer.data(); - } else { - // Add some padding to verify there is no overrun. - sample.clear_buffer.resize(total_size + kBufferOverrunPadding, - 0xaa); - output_descriptor.buffer.clear.clear_buffer = - sample.clear_buffer.data(); - } - output_descriptor.buffer.clear.clear_buffer_length = total_size; - break; - - case OEMCrypto_BufferType_Secure: - output_descriptor.buffer.secure.secure_buffer_length = total_size; - ASSERT_EQ(OEMCrypto_AllocateSecureBuffer( - session_.session_id(), total_size, &output_descriptor, - &sample.secure_buffer_fid), - OEMCrypto_SUCCESS); - ASSERT_NE(output_descriptor.buffer.secure.secure_buffer, nullptr); - // It is OK if OEMCrypto changes the maximum size, but there must - // still be enough room for our data. - ASSERT_GE(output_descriptor.buffer.secure.secure_buffer_length, - total_size); - output_descriptor.buffer.secure.offset = 0; - break; - - case OEMCrypto_BufferType_Direct: - output_descriptor.buffer.direct.is_video = false; - break; - } // switch (output_descriptor.type) - } // sample loop - } - - void FreeSecureBuffers() { - for (TestSample& sample : samples_) { - OEMCrypto_DestBufferDesc& output_descriptor = - sample.description.buffers.output_descriptor; - if (output_descriptor.type == OEMCrypto_BufferType_Secure) { - ASSERT_EQ(OEMCrypto_FreeSecureBuffer(session_.session_id(), - &output_descriptor, - sample.secure_buffer_fid), - OEMCrypto_SUCCESS); - } - } - } - - void EncryptData() { - AES_KEY aes_key; - AES_set_encrypt_key(key_, AES_BLOCK_SIZE * 8, &aes_key); - - for (TestSample& sample : samples_) { - uint8_t iv[KEY_IV_SIZE]; // Current IV - memcpy(iv, initial_iv_, KEY_IV_SIZE); - memcpy(sample.description.iv, initial_iv_, KEY_IV_SIZE); - - size_t buffer_index = 0; // byte index into in and out. - size_t block_offset = 0; // byte index into current block. - for (const OEMCrypto_SubSampleDescription& subsample : - sample.subsamples) { - // Copy clear content. - if (subsample.num_bytes_clear > 0) { - memcpy(&sample.encrypted_buffer[buffer_index], - &sample.truth_buffer[buffer_index], subsample.num_bytes_clear); - buffer_index += subsample.num_bytes_clear; - } - - // The IV resets at the start of each subsample in the 'cbcs' schema. - if (cipher_mode_ == OEMCrypto_CipherMode_CBCS) { - memcpy(iv, initial_iv_, KEY_IV_SIZE); - } - - size_t pattern_offset = 0; - const size_t subsample_end = - buffer_index + subsample.num_bytes_encrypted; - while (buffer_index < subsample_end) { - const size_t size = - min(subsample_end - buffer_index, AES_BLOCK_SIZE - block_offset); - const size_t pattern_length = pattern_.encrypt + pattern_.skip; - const bool skip_block = - (pattern_offset >= pattern_.encrypt) && (pattern_length > 0); - if (pattern_length > 0) { - pattern_offset = (pattern_offset + 1) % pattern_length; - } - // CBC mode should just copy a partial block at the end. If there - // is a partial block at the beginning, an error is returned, so we - // can put whatever we want in the output buffer. - if (skip_block || ((cipher_mode_ == OEMCrypto_CipherMode_CBCS) && - (size < AES_BLOCK_SIZE))) { - memcpy(&sample.encrypted_buffer[buffer_index], - &sample.truth_buffer[buffer_index], size); - block_offset = 0; // Next block should be complete. - } else { - if (cipher_mode_ == OEMCrypto_CipherMode_CENC) { - uint8_t aes_output[AES_BLOCK_SIZE]; - AES_encrypt(iv, aes_output, &aes_key); - for (size_t n = 0; n < size; n++) { - sample.encrypted_buffer[buffer_index + n] = - aes_output[n + block_offset] ^ - sample.truth_buffer[buffer_index + n]; - } - if (size + block_offset < AES_BLOCK_SIZE) { - // Partial block. Don't increment iv. Compute next block - // offset. - block_offset = block_offset + size; - } else { - EXPECT_EQ(block_offset + size, - static_cast(AES_BLOCK_SIZE)); - // Full block. Increment iv, and set offset to 0 for next - // block. - ctr128_inc64(1, iv); - block_offset = 0; - } - } else { - uint8_t aes_input[AES_BLOCK_SIZE]; - for (size_t n = 0; n < size; n++) { - aes_input[n] = sample.truth_buffer[buffer_index + n] ^ iv[n]; - } - AES_encrypt(aes_input, &sample.encrypted_buffer[buffer_index], - &aes_key); - memcpy(iv, &sample.encrypted_buffer[buffer_index], - AES_BLOCK_SIZE); - // CBC mode should always start on block boundary. - block_offset = 0; - } - } - buffer_index += size; - } // encryption loop - } // per-subsample loop - } // per-sample loop - } - - void LoadLicense() { - uint32_t control = wvoec::kControlNonceEnabled; - if (verify_crc_) control |= kControlAllowHashVerification; - if (output_buffer_type_ == OEMCrypto_BufferType_Secure) - control |= kControlObserveDataPath | kControlDataPathSecure; - license_messages_.set_control(control); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - license_messages_.core_response() - .timer_limits.initial_renewal_duration_seconds = kDuration; - memcpy(license_messages_.response_data().keys[0].key_data, key_, - sizeof(key_)); - license_messages_.response_data().keys[0].cipher_mode = cipher_mode_; - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_EQ(OEMCrypto_SelectKey( - session_.session_id(), session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, cipher_mode_), - OEMCrypto_SUCCESS); - } - - void TestDecryptCENC() { ASSERT_EQ(DecryptCENC(), OEMCrypto_SUCCESS); } - - void ValidateDecryptedData() { - for (TestSample& sample : samples_) { - if (sample.description.buffers.output_descriptor.type == - OEMCrypto_BufferType_Clear) { - const size_t total_size = sample.description.buffers.input_data_length; - // To verify there is no buffer overrun after decrypting, look at the - // padded bytes just after the data buffer that was written. It - // should not have changed from the original 0xaa that we set in - // MakeBuffer function. - if (decrypt_inplace_) { - EXPECT_EQ(std::count(sample.encrypted_buffer.begin() + total_size, - sample.encrypted_buffer.end(), 0xaa), - static_cast(kBufferOverrunPadding)) - << "Buffer overrun."; - sample.encrypted_buffer.resize(total_size); // Remove padding. - // We expect encrypted buffer to have been changed by OEMCrypto. - EXPECT_EQ(sample.encrypted_buffer, sample.truth_buffer); - } else { - EXPECT_EQ(std::count(sample.clear_buffer.begin() + total_size, - sample.clear_buffer.end(), 0xaa), - static_cast(kBufferOverrunPadding)) - << "Buffer overrun."; - sample.clear_buffer.resize(total_size); // Remove padding. - EXPECT_EQ(sample.clear_buffer, sample.truth_buffer); - } - } - } - if (verify_crc_) { - uint32_t frame; - ASSERT_EQ(OEMCrypto_GetHashErrorCode(session_.session_id(), &frame), - OEMCrypto_SUCCESS); - } - } - - OEMCryptoResult DecryptCENC() { - // OEMCrypto only supports providing a decrypt hash for one sample. - if (samples_.size() > 1) verify_crc_ = false; - - // If supported, check the decrypt hashes. - if (verify_crc_) { - const TestSample& sample = samples_[0]; - - uint32_t hash = - util::wvcrc32(sample.truth_buffer.data(), sample.truth_buffer.size()); - OEMCrypto_SetDecryptHash(session_.session_id(), 1, - reinterpret_cast(&hash), - sizeof(hash)); - } - - // Build an array of just the sample descriptions. - std::vector sample_descriptions; - sample_descriptions.reserve(samples_.size()); - for (TestSample& sample : samples_) { - // This must be deferred until this point in case the test modifies the - // buffer before testing decrypt. - sample.description.buffers.input_data = sample.encrypted_buffer.data(); - // Append to the description array. - sample_descriptions.push_back(sample.description); - } - - // Perform decryption using the test data that was previously set up. - OEMCryptoResult result = DecryptFallbackChain::Decrypt( - session_.session_id(), sample_descriptions.data(), - sample_descriptions.size(), cipher_mode_, &pattern_); - if (result != OEMCrypto_SUCCESS) return result; - ValidateDecryptedData(); - return result; - } - - // Parameters of test case - OEMCrypto_CENCEncryptPatternDesc pattern_; - OEMCryptoCipherMode cipher_mode_; - bool decrypt_inplace_; // If true, input and output buffers are the same. - OEMCryptoBufferType output_buffer_type_; - - bool verify_crc_; - uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key. - uint8_t initial_iv_[KEY_IV_SIZE]; // Starting IV for every sample. - std::vector samples_; -}; - -TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) { - // This subsample size is larger than a few encrypt/skip patterns. Most - // test cases use a pattern length of 160, so we'll run through at least two - // full patterns if we have more than 320 -- round up to 400. - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 400}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// When the pattern length is 10 blocks, there is a discrepancy between the -// HLS and the CENC standards for samples of size 160*N+16, for N = 1, 2, 3... -// We require the CENC standard for OEMCrypto, and let a layer above us break -// samples into pieces if they wish to use the HLS standard. -TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 160 + 16}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// Test that a single block can be decrypted. -TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 16}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests the ability to decrypt multiple subsamples with no offset. -// There is no offset within the block, used by CTR mode. -TEST_P(OEMCryptoSessionTestsDecryptTests, NoOffset) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {25, 160}, - {50, 256}, - {25, 160}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests an offset into the block for the second encrypted subsample. -// This should only work for CTR mode, for CBC mode an error is expected in -// the decrypt step. -// If this test fails for CTR mode, then it is probably handling the -// block_offset incorrectly. -TEST_P(OEMCryptoSessionTestsDecryptTests, EvenOffset) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {25, 8}, - {25, 32}, - {25, 50}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - // CTR Mode is self-inverse -- i.e. We can pick the encrypted data and - // compute the unencrypted data. By picking the encrypted data to be all 0, - // it is easier to re-encrypt the data and debug problems. Similarly, we - // pick an iv = 0. - memset(initial_iv_, 0, KEY_IV_SIZE); - TestSample& sample = samples_[0]; // There is only one sample in this test - sample.truth_buffer.assign(sample.description.buffers.input_data_length, 0); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - if (decrypt_inplace_) { - const size_t total_size = sample.description.buffers.input_data_length; - // In case of decrypt_inplace_, encrypted_buffer contains padded bytes - // which is used for buffer overrun validation. Do not copy the padded - // bytes to truth_buffer. - sample.truth_buffer.assign(sample.encrypted_buffer.begin(), - sample.encrypted_buffer.begin() + total_size); - } else { - sample.truth_buffer = - sample.encrypted_buffer; // truth_buffer_ = encrypted zero buffer. - } - // Run EncryptData to re-encrypt this buffer. For CTR mode, we should get - // back to zeros. - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// If the EvenOffset test passes, but this one doesn't, then DecryptCENC might -// be using the wrong definition of block offset. Adding the block offset to -// the block boundary should give you the beginning of the encrypted data. -// This should only work for CTR mode, for CBC mode, the block offset must be -// 0, so an error is expected in the decrypt step. -// Another way to view the block offset is with the formula: -// block_boundary + block_offset = beginning of subsample. -TEST_P(OEMCryptoSessionTestsDecryptTests, OddOffset) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {10, 50}, - {10, 75}, - {10, 75}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests that the algorithm used to increment the counter for -// AES-CTR mode is correct. There are two possible implementations: -// 1) increment the counter as if it were a 128 bit number, -// 2) increment the low 64 bits as a 64 bit number and leave the high bits -// alone. -// For CENC, the algorithm we should use is the second one. OpenSSL defaults to -// the first. If this test is not passing, you should look at the way you -// increment the counter. Look at the example code in ctr128_inc64 above. -// If you start with an IV of 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, after you -// increment twice, you should get 0xFFFFFFFFFFFFFFFF0000000000000000. -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) { - memcpy(initial_iv_, - wvutil::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE").data(), - KEY_IV_SIZE); - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 256}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests the case where an encrypted sample is not an even number of -// blocks. For CTR mode, the partial block is encrypted. For CBC mode the -// partial block should be a copy of the clear data. -TEST_P(OEMCryptoSessionTestsDecryptTests, PartialBlock) { - // Note: for more complete test coverage, we want a sample size that is in - // the encrypted range for some tests, e.g. (3,7), and in the skip range for - // other tests, e.g. (7, 3). 3*16 < 50 and 7*16 > 50. - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 50}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// Based on the resource rating, OEMCrypto should be able to handle the maximum -// amount of data that can be passed to it. This is the lesser of: -// -// 1) The maximum total sample size -// 2) The maximum number of subsamples multiplied by the maximum subsample size -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSampleAPI16) { - const size_t max_sample_size = GetResourceValue(kMaxSampleSize); - const size_t max_subsample_size = GetResourceValue(kMaxSubsampleSize); - const size_t max_num_subsamples = GetResourceValue(kMaxNumberSubsamples); - - // The +1 on this line ensures that, even in cases where max_sample_size is - // not evenly divisible by max_num_subsamples and thus the division gets - // truncated, (max_num_subsamples * subsample_size) will be greater than - // max_sample_size. - const size_t subsample_size = - std::min(max_sample_size / max_num_subsamples + 1, max_subsample_size); - size_t bytes_remaining = max_sample_size; - std::vector subsample_sizes; - while (bytes_remaining > 0 && subsample_sizes.size() < max_num_subsamples) { - const size_t this_subsample_size = - std::min(subsample_size, bytes_remaining); - const size_t clear_size = this_subsample_size / 2; - const size_t encrypted_size = this_subsample_size - clear_size; - - subsample_sizes.push_back({clear_size, encrypted_size}); - bytes_remaining -= this_subsample_size; - } - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes(subsample_sizes)); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -TEST_P(OEMCryptoSessionTestsDecryptTests, - OEMCryptoMemoryDecryptCENCForHugeNumberOfSubSamples) { - auto oemcrypto_function = [&](size_t number_of_subsamples) { - std::vector subsample_sizes; - while (number_of_subsamples-- > 0) { - subsample_sizes.push_back({1, 1}); - } - SetSubsampleSizes(subsample_sizes); - LoadLicense(); - MakeBuffers(); - EncryptData(); - OEMCryptoResult result = DecryptCENC(); - FreeSecureBuffers(); - // Closing the session and opening it for next iteration. - // If it is last iteration, session will be closed in teardown method of - // class. - session_.close(); - session_.open(); - InstallTestRSAKey(&session_); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); - - // Avoid double free when test teardown calls FreeSecureBuffers() - MakeBuffers(); -} - -TEST_P(OEMCryptoSessionTestsDecryptTests, - OEMCryptoMemoryCheckDecryptCENCStatusForHugeNumberOfSubSamples) { - size_t number_of_subsamples = 10000; - std::vector subsample_sizes; - while (number_of_subsamples-- > 0) { - subsample_sizes.push_back({100, 100}); - } - SetSubsampleSizes(subsample_sizes); - LoadLicense(); - MakeBuffers(); - EncryptData(); - // Build an array of just the sample descriptions. - std::vector sample_descriptions; - sample_descriptions.reserve(samples_.size()); - for (TestSample& sample : samples_) { - // This must be deferred until this point in case the test modifies the - // buffer before testing decrypt. - sample.description.buffers.input_data = sample.encrypted_buffer.data(); - // Append to the description array. - sample_descriptions.push_back(sample.description); - } - OEMCryptoResult result = OEMCrypto_DecryptCENC( - session_.session_id(), sample_descriptions.data(), 1, &pattern_); - LOGD("Large number of subsamples test has return code %d", result); -} - -TEST_P(OEMCryptoSessionTestsDecryptTests, - OEMCryptoMemoryCheckDecryptCENCStatusForHugeSubSample) { - std::vector subsample_sizes; - subsample_sizes.push_back({100000, 100000}); - SetSubsampleSizes(subsample_sizes); - LoadLicense(); - MakeBuffers(); - EncryptData(); - // Build an array of just the sample descriptions. - std::vector sample_descriptions; - sample_descriptions.reserve(samples_.size()); - for (TestSample& sample : samples_) { - // This must be deferred until this point in case the test modifies the - // buffer before testing decrypt. - sample.description.buffers.input_data = sample.encrypted_buffer.data(); - // Append to the description array. - sample_descriptions.push_back(sample.description); - } - OEMCryptoResult result = OEMCrypto_DecryptCENC( - session_.session_id(), sample_descriptions.data(), 1, &pattern_); - LOGD("Large subsample test has return code %d", result); -} - -TEST_P(OEMCryptoSessionTestsDecryptTests, - OEMCryptoMemoryDecryptCENCForHugeNumberOfSamples) { - auto oemcrypto_function = [&](size_t number_of_samples) { - std::vector> samples; - std::vector subsample_sizes; - subsample_sizes.push_back({1, 1}); - while (number_of_samples-- > 0) { - samples.push_back(subsample_sizes); - } - SetSampleSizes(samples); - LoadLicense(); - MakeBuffers(); - EncryptData(); - OEMCryptoResult result = DecryptCENC(); - FreeSecureBuffers(); - // Closing the session and opening it for next iteration. - // If it is last iteration, session will be closed in teardown method of - // class. - session_.close(); - session_.open(); - InstallTestRSAKey(&session_); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); - - // Avoid double free when test teardown calls FreeSecureBuffers() - MakeBuffers(); -} - -// Based on the resource rating, OEMCrypto should be able to handle the maximum -// subsample size. -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) { - const size_t max = GetResourceValue(kMaxSubsampleSize); - const size_t half_max = max / 2; - // This test assumes that the maximum sample size is always more than three - // times the maximum subsample size. - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {max, 0}, - {0, max}, - {half_max, max - half_max}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// There are probably no frames this small, but we should handle them anyway. -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {5, 5}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// Test the case where there is only a clear subsample and no encrypted -// subsample. -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) { - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {256, 0}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencryptedNoKey) { - // Do not try to compute the CRC because we have not loaded a license. - verify_crc_ = false; - // Single clear subsample - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {400, 0}, - })); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - // Clear data should be copied even if there is no key selected, and no - // license loaded. - // ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests the ability to decrypt multiple samples at once. -TEST_P(OEMCryptoSessionTestsDecryptTests, MultipleSamples) { - ASSERT_NO_FATAL_FAILURE(SetSampleSizes({ - { - {52, 160}, - {25, 256}, - {25, 320}, - }, - { - {300, 64}, - {50, 160}, - {2, 160}, - {24, 160}, - {128, 256}, - }, - { - {70, 320}, - {160, 160}, - }, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// This tests that calling OEMCrypto_Idle and OEMCrypto_Wake once or multiple -// times doesn't break anything. -TEST_P(OEMCryptoSessionTestsDecryptTests, IdleAndWake) { - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); - ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); - ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); - ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); -} - -// This tests that after an idle and a wake, decryption can continue in an -// open session. -TEST_P(OEMCryptoSessionTestsDecryptTests, ContinueDecryptionAfterIdleAndWake) { - // This subsample size is larger than a few encrypt/skip patterns. Most - // test cases use a pattern length of 160, so we'll run through at least two - // full patterns if we have more than 320 -- round up to 400. - ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({ - {0, 400}, - })); - ASSERT_NO_FATAL_FAILURE(LoadLicense()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); - FreeSecureBuffers(); - // Set state to idle then wake again and try to reencrypt/decrypt - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_Idle(OEMCrypto_IdleState::OEMCrypto_CpuSuspend, 0)); - ASSERT_NO_FATAL_FAILURE(OEMCrypto_Wake()); - ASSERT_NO_FATAL_FAILURE(MakeBuffers()); - ASSERT_NO_FATAL_FAILURE(EncryptData()); - ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); -} - -// Used to construct a specific pattern. -constexpr OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt, - size_t skip) { - return {encrypt, skip}; -} - -INSTANTIATE_TEST_SUITE_P( - CTRTests, OEMCryptoSessionTestsDecryptTests, - Combine(Values(MakePattern(0, 0)), Values(OEMCrypto_CipherMode_CENC), - ::testing::ValuesIn(global_features.GetOutputTypes()))); - -// Decrypt in place for CBC tests was only required in v13. -INSTANTIATE_TEST_SUITE_P( - CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests, - Combine( - Values(MakePattern(3, 7), MakePattern(9, 1), - // HLS edge cases. We should follow the CENC spec, not HLS spec. - MakePattern(1, 9), MakePattern(1, 0), - // AV1 patterns not already covered above. - MakePattern(5, 5), MakePattern(10, 0)), - Values(OEMCrypto_CipherMode_CBCS), - ::testing::ValuesIn(global_features.GetOutputTypes()))); - -// A request to decrypt data to a clear buffer when the key control block -// requires a secure data path. -TEST_P(OEMCryptoLicenseTest, DecryptSecureToClear) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.set_control(wvoec::kControlObserveDataPath | - wvoec::kControlDataPathSecure); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - ASSERT_NO_FATAL_FAILURE( - session_.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// Test that key duration is honored. -TEST_P(OEMCryptoLicenseTest, KeyDuration) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS)); - wvutil::TestSleep::Sleep(kShortSleep); // Should still be valid key. - ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false, OEMCrypto_SUCCESS)); - wvutil::TestSleep::Sleep(kLongSleep); // Should be expired key. - ASSERT_NO_FATAL_FAILURE( - session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); - ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(0)); -} - -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseTest, - Range(kCoreMessagesAPI, kCurrentAPI + 1)); - -// -// Certificate Root of Trust Tests -// -class OEMCryptoLoadsCertificate : public OEMCryptoSessionTestKeyboxTest { - protected: - void TestPrepareProvisioningRequestForHugeBufferLengths( - const std::function f, - bool check_status) { - auto oemcrypto_function = [&](size_t message_length) { - Session s; - s.open(); - if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { - s.LoadOEMCert(true); - } else { - s.GenerateDerivedKeysFromKeybox(keybox_); - } - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - f(message_length, &provisioning_messages); - return provisioning_messages - .SignAndCreateRequestWithCustomBufferLengths(); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); - } - - void TestLoadProvisioningForHugeBufferLengths( - const std::function f, - bool check_status, bool update_core_message_substring_values) { - auto oemcrypto_function = [&](size_t message_length) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - provisioning_messages.SignAndVerifyRequest(); - provisioning_messages.CreateDefaultResponse(); - if (update_core_message_substring_values) { - // Make provisioning message big enough so that updated core message - // substring offset and length values from tests are still able to read - // valid data from provisioning_message buffer rather than some garbage - // data. - provisioning_messages.set_message_size( - sizeof(provisioning_messages.response_data()) + message_length); - } - f(message_length, &provisioning_messages); - provisioning_messages - .EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength(); - OEMCryptoResult result = provisioning_messages.LoadResponse(); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status); - } - - void TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths( - const std::function f) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - provisioning_messages.SignAndVerifyRequest(); - provisioning_messages.CreateDefaultResponse(); - size_t message_length = sizeof(provisioning_messages.response_data()); - f(message_length, &provisioning_messages); - provisioning_messages - .EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength(); - OEMCryptoResult result = provisioning_messages.LoadResponse(); - s.close(); - // Verifying error is not due to signature failure which can be caused due - // to test code. - ASSERT_NE(OEMCrypto_ERROR_SIGNATURE_FAILURE, result); - ASSERT_NE(OEMCrypto_SUCCESS, result); - } -}; - -// This test verifies that we can create a wrapped RSA key, and then reload it. -TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) { - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); -} - -TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { - s.LoadOEMCert(true); - } else { - EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); - s.GenerateDerivedKeysFromKeybox(keybox_); - } - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); -} - -// This tests a large message size. The size is larger than we required in v15. -TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { - s.LoadOEMCert(true); - } else { - EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); - s.GenerateDerivedKeysFromKeybox(keybox_); - } - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - const size_t max_size = GetResourceValue(kLargeMessageSize); - provisioning_messages.set_message_size(max_size); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); -} - -// This creates a wrapped RSA key, and then does the sanity check that the -// unencrypted key is not found in the wrapped key. The wrapped key should be -// encrypted. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvision) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - // We should not be able to find the rsa key in the wrapped key. It should - // be encrypted. - EXPECT_EQ(nullptr, find(provisioning_messages.wrapped_rsa_key(), - provisioning_messages.encoded_rsa_key())); -} - -// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning -// message. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - // Encrypt and sign once, so that we can use the size of the response. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - provisioning_messages.core_response().enc_private_key.offset = - provisioning_messages.encrypted_response_buffer().size() + 1; - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning -// message. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - // Encrypt and sign once, so that we can use the size of the response. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - provisioning_messages.core_response().enc_private_key_iv.offset = - provisioning_messages.encrypted_response_buffer().size() + 1; - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning -// message. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - // Encrypt and sign once, so that we can use the size of the response. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - // If the offset is before the end, but the offset+length is bigger, then - // the message should be rejected. - provisioning_messages.core_response().enc_private_key.offset = - provisioning_messages.encrypted_response_buffer().size() - 5; - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning -// message. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - // Encrypt and sign once, so that we can use the size of the response. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - // If the offset is before the end, but the offset+length is bigger, then - // the message should be rejected. - provisioning_messages.core_response().enc_private_key_iv.offset = - provisioning_messages.encrypted_response_buffer().size() - 5; - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning -// message. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - // Encrypt and sign once, so that we can use the size of the response. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - // If the offset is before the end, but the offset+length is bigger, then - // the message should be rejected. - provisioning_messages.core_response().encrypted_message_key.offset = - provisioning_messages.encrypted_response_buffer().size() + 1; - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Test that RewrapDeviceRSAKey verifies the message signature. -// TODO(b/144186970): This test should also run on Prov 3.0 devices. -TEST_F(OEMCryptoLoadsCertificate, - CertificateProvisionBadSignatureKeyboxTestAPI16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - provisioning_messages.response_signature()[4] ^= 42; // bad signature. - ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, - provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Test that RewrapDeviceRSAKey verifies the nonce is current. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonce_API16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - provisioning_messages.core_request().nonce ^= 42; // bad nonce. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, - provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Test that RewrapDeviceRSAKey verifies the RSA key is valid. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - provisioning_messages.response_data().rsa_key[4] ^= 42; // bad key. - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_NE(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Test that RewrapDeviceRSAKey verifies the RSA key is valid. -// TODO(b/144186970): This test should also run on Prov 3.0 devices. -TEST_F(OEMCryptoLoadsCertificate, - CertificateProvisionBadRSAKeyKeyboxTestAPI16) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - size_t rsa_offset = - provisioning_messages.core_response().enc_private_key.offset; - // Offsets are relative to the message body, after the core message. - rsa_offset += provisioning_messages.serialized_core_message().size(); - rsa_offset += 4; // Change the middle of the key. - provisioning_messages.encrypted_response_buffer()[rsa_offset] ^= 42; - ASSERT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE, - provisioning_messages.LoadResponse()); - provisioning_messages.VerifyLoadFailed(); -} - -// Test that RewrapDeviceRSAKey accepts the maximum message size. -TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBuffer) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - const size_t max_size = GetResourceValue(kLargeMessageSize); - provisioning_messages.set_message_size(max_size); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadResponse()); - // We should not be able to find the rsa key in the wrapped key. It should - // be encrypted. - EXPECT_EQ(nullptr, find(provisioning_messages.wrapped_rsa_key(), - provisioning_messages.encoded_rsa_key())); -} +/// @addtogroup security +/// @{ TEST_F(OEMCryptoLoadsCertificate, OEMCryptoMemoryLoadProvisioningForHugeResponseLength) { @@ -5810,6 +1549,9 @@ TEST_F(OEMCryptoLoadsCertificate, TEST_F( OEMCryptoLoadsCertificate, OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyLengthProv30) { + if (global_features.provisioning_method != OEMCrypto_OEMCertificate) { + GTEST_SKIP() << "Test for Prov 3.0 devices only."; + } TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths( [](size_t response_message_length, ProvisioningRoundTrip* provisioning_messages) { @@ -5823,6 +1565,9 @@ TEST_F( TEST_F( OEMCryptoLoadsCertificate, OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyOffsetProv30) { + if (global_features.provisioning_method != OEMCrypto_OEMCertificate) { + GTEST_SKIP() << "Test for Prov 3.0 devices only."; + } TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths( [](size_t response_message_length, ProvisioningRoundTrip* provisioning_messages) { @@ -5833,275 +1578,10 @@ TEST_F( }); } -TEST_F(OEMCryptoLoadsCertificate, - OEMCryptoMemoryLoadProvisioningForHugeSignatureLength) { - auto oemcrypto_function = [&](size_t signature_size) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - provisioning_messages.SignAndVerifyRequest(); - provisioning_messages.CreateDefaultResponse(); - provisioning_messages.EncryptAndSignResponse(); - vector signature(signature_size); - size_t wrapped_private_key_length = 0; - // Find wrapped_private_key_length. - OEMCrypto_LoadProvisioning( - s.session_id(), - provisioning_messages.encrypted_response_buffer().data(), - provisioning_messages.encrypted_response_buffer().size(), - provisioning_messages.serialized_core_message().size(), - signature.data(), signature_size, nullptr, &wrapped_private_key_length); - std::vector wrapped_rsa_key(wrapped_private_key_length); - OEMCryptoResult result = OEMCrypto_LoadProvisioning( - s.session_id(), - provisioning_messages.encrypted_response_buffer().data(), - provisioning_messages.encrypted_response_buffer().size(), - provisioning_messages.serialized_core_message().size(), - signature.data(), signature_size, wrapped_rsa_key.data(), - &wrapped_private_key_length); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} +/// @} -TEST_F(OEMCryptoLoadsCertificate, - OEMCryptoMemoryLoadProvisioningForHugeWrappedRsaKeyLength) { - auto oemcrypto_function = [&](size_t buffer_length) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - provisioning_messages.SignAndVerifyRequest(); - provisioning_messages.CreateDefaultResponse(); - provisioning_messages.EncryptAndSignResponse(); - size_t wrapped_private_key_length = buffer_length; - vector wrapped_private_key(wrapped_private_key_length); - OEMCryptoResult result = OEMCrypto_LoadProvisioning( - s.session_id(), - provisioning_messages.encrypted_response_buffer().data(), - provisioning_messages.encrypted_response_buffer().size(), - provisioning_messages.serialized_core_message().size(), - provisioning_messages.response_signature().data(), - provisioning_messages.response_signature().size(), - wrapped_private_key.data(), &wrapped_private_key_length); - s.close(); - return result; - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// Test that a wrapped RSA key can be loaded. -TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); -} - -TEST_F(OEMCryptoLoadsCertificate, - OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLength) { - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) { - Session s; - s.open(); - vector wrapped_rsa_key_buffer = wrapped_rsa_key_; - wrapped_rsa_key_buffer.resize(wrapped_rsa_key_length); - OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey( - s.session_id(), OEMCrypto_RSA_Private_Key, - wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size()); - s.close(); - return result; - }; - // It is hard to generate varying length valid wrapped rsa key with valid - // signature. Hence we just call function with random data and do not check - // status to test API with varying length wrapped rsa key. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, wrapped_rsa_key_.size(), - kHugeInputBufferLength, !kCheckStatus); -} - -TEST_F( - OEMCryptoLoadsCertificate, - OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLengthStartingFromLength1) { - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) { - Session s; - s.open(); - vector wrapped_rsa_key_buffer(wrapped_rsa_key_length); - OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey( - s.session_id(), OEMCrypto_RSA_Private_Key, - wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size()); - s.close(); - return result; - }; - // It is hard to generate varying length valid wrapped rsa key with valid - // signature. Hence we just call function with random data and do not check - // status to test API with varying length wrapped rsa key. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate { - public: - void TestKey(const uint8_t* key, size_t key_length) { - encoded_rsa_key_.assign(key, key + key_length); - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - LicenseRoundTrip license_messages(&s); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); - } -}; - -// Test a 3072 bit RSA key certificate. -TEST_F(OEMCryptoLoadsCertVariousKeys, TestLargeRSAKey3072) { - TestKey(kTestRSAPKCS8PrivateKeyInfo3_3072, - sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072)); -} - -// Test an RSA key certificate which has a private key generated using the -// Carmichael totient. -TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelRSAKey) { - TestKey(kTestKeyRSACarmichael_2048, sizeof(kTestKeyRSACarmichael_2048)); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroNormalDer) { - TestKey(kCarmichaelNonZeroNormalDer, kCarmichaelNonZeroNormalDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroShortDer) { - TestKey(kCarmichaelNonZeroShortDer, kCarmichaelNonZeroShortDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroNormalDer) { - TestKey(kCarmichaelZeroNormalDer, kCarmichaelZeroNormalDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroShortDer) { - TestKey(kCarmichaelZeroShortDer, kCarmichaelZeroShortDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroNormalDer) { - TestKey(kDualNonZeroNormalDer, kDualNonZeroNormalDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroShortDer) { - TestKey(kDualNonZeroShortDer, kDualNonZeroShortDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroNormalDer) { - TestKey(kDualZeroNormalDer, kDualZeroNormalDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroShortDer) { - TestKey(kDualZeroShortDer, kDualZeroShortDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerNonZeroNormalDer) { - TestKey(kEulerNonZeroNormalDer, kEulerNonZeroNormalDerLen); -} - -TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) { - TestKey(kEulerZeroNormalDer, kEulerZeroNormalDerLen); -} - -// This tests that two sessions can use different RSA keys simultaneously. -TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - Session s1; // Session s1 loads the default rsa key, but doesn't use it - // until after s2 uses its key. - ASSERT_NO_FATAL_FAILURE(s1.open()); - ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - Session s2; // Session s2 uses a different rsa key. - encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048, - kTestRSAPKCS8PrivateKeyInfo4_2048 + - sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048)); - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - LicenseRoundTrip license_messages2(&s2); - ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(s2.TestDecryptCTR()); - s2.close(); - - // After s2 has loaded its rsa key, we continue using s1's key. - LicenseRoundTrip license_messages1(&s1); - ASSERT_NO_FATAL_FAILURE(license_messages1.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages1.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages1.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages1.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR()); -} - -// This tests the maximum number of DRM private keys that OEMCrypto can load -TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) { - const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys); - std::vector> sessions; - std::vector> licenses; - - // It should be able to load up to kMaxTotalDRMPrivateKeys keys - for (size_t i = 0; i < max_total_keys; i++) { - sessions.push_back(std::unique_ptr(new Session())); - licenses.push_back(std::unique_ptr( - new LicenseRoundTrip(sessions[i].get()))); - const size_t key_index = i % kTestRSAPKCS8PrivateKeys_2048.size(); - encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeys_2048[key_index].begin(), - kTestRSAPKCS8PrivateKeys_2048[key_index].end()); - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - ASSERT_NO_FATAL_FAILURE(sessions[i]->open()); - ASSERT_NO_FATAL_FAILURE(sessions[i]->SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_NO_FATAL_FAILURE( - sessions[i]->LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - } - - // Attempts to load one more key than the kMaxTotalDRMPrivateKeys - Session s; - encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo2_2048, - kTestRSAPKCS8PrivateKeyInfo2_2048 + - sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); - Session ps; - ProvisioningRoundTrip provisioning_messages(&ps, encoded_rsa_key_); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - OEMCryptoResult result = provisioning_messages.LoadResponse(); - // Key loading is allowed to fail due to resource restriction - if (result != OEMCrypto_SUCCESS) { - ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES || - result == OEMCrypto_ERROR_TOO_MANY_KEYS); - } - // Verifies that the DRM keys which are already loaded should still function - for (size_t i = 0; i < licenses.size(); i++) { - ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse()); - ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR()); - } -} - -// Devices that load certificates, should at least support RSA 2048 keys. -TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) { - ASSERT_NE(0u, - OEMCrypto_Supports_RSA_2048bit & OEMCrypto_SupportedCertificates()) - << "Supported certificates is only " << OEMCrypto_SupportedCertificates(); -} +/// @addtogroup security +/// @{ TEST_F(OEMCryptoLoadsCertificate, OEMCryptoMemoryPrepareProvisioningRequestForHugeRequestMessageLength) { @@ -6130,4172 +1610,10 @@ TEST_F(OEMCryptoLoadsCertificate, kCheckStatus); } -// These tests are run by all L1 devices that load and use certificates. It is -// also run by a few L3 devices that use a baked in certificate, but cannot load -// a certificate. -class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate { - protected: - void SetUp() override { - OEMCryptoLoadsCertificate::SetUp(); - ASSERT_NO_FATAL_FAILURE(session_.open()); - if (global_features.derive_key_method == - DeviceFeatures::LOAD_TEST_RSA_KEY) { - ASSERT_NO_FATAL_FAILURE(session_.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - } else { - InstallTestRSAKey(&session_); - } - } - - void TearDown() override { - ASSERT_NO_FATAL_FAILURE(session_.close()); - OEMCryptoLoadsCertificate::TearDown(); - } - - Session session_; -}; - -// This test is not run by default, because it takes a long time and -// is used to measure RSA performance, not test functionality. -TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { - const std::chrono::milliseconds kTestDuration(5000); - OEMCryptoResult sts; - std::chrono::steady_clock clock; - wvutil::TestSleep::Sleep(kShortSleep); // Make sure we are not nonce limited. - - auto start_time = clock.now(); - int count = 15; - for (int i = 0; i < count; i++) { // Only 20 nonce available. - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - } - auto delta_time = clock.now() - start_time; - const double provision_time = - delta_time / std::chrono::milliseconds(1) / count; - - Session session; - ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); - start_time = clock.now(); - count = 0; - while (clock.now() - start_time < kTestDuration) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - const size_t size = 50; - vector licenseRequest(size); - GetRandBytes(licenseRequest.data(), licenseRequest.size()); - size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), - licenseRequest.size(), nullptr, - &signature_length, kSign_RSASSA_PSS); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_NE(static_cast(0), signature_length); - - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generate_rsa_signature_fuzz_seed_corpus"); - OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure; - fuzzed_structure.padding_scheme = kSign_RSASSA_PSS; - fuzzed_structure.signature_length = signature_length; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, - reinterpret_cast(licenseRequest.data()), - licenseRequest.size()); - } - - std::vector signature(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), - signature.data(), &signature_length, kSign_RSASSA_PSS); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - count++; - } - delta_time = clock.now() - start_time; - const double license_request_time = - delta_time / std::chrono::milliseconds(1) / count; - - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - vector session_key; - vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - s.FillDefaultContext(&mac_context, &enc_context); - - enc_session_key = wvutil::a2b_hex( - "7789c619aa3b9fa3c0a53f57a4abc6" - "02157c8aa57e3c6fb450b0bea22667fb" - "0c3200f9d9d618e397837c720dc2dadf" - "486f33590744b2a4e54ca134ae7dbf74" - "434c2fcf6b525f3e132262f05ea3b3c1" - "198595c0e52b573335b2e8a3debd0d0d" - "d0306f8fcdde4e76476be71342957251" - "e1688c9ca6c1c34ed056d3b989394160" - "cf6937e5ce4d39cc73d11a2e93da21a2" - "fa019d246c852fe960095b32f120c3c2" - "7085f7b64aac344a68d607c0768676ce" - "d4c5b2d057f7601921b453a451e1dea0" - "843ebfef628d9af2784d68e86b730476" - "e136dfe19989de4be30a4e7878efcde5" - "ad2b1254f80c0c5dd3cf111b56572217" - "b9f58fc1dacbf74b59d354a1e62cfa0e" - "bf"); - start_time = clock.now(); - while (clock.now() - start_time < kTestDuration) { - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_DeriveKeysFromSessionKey( - s.session_id(), enc_session_key.data(), - enc_session_key.size(), mac_context.data(), - mac_context.size(), enc_context.data(), enc_context.size())); - count++; - } - delta_time = clock.now() - start_time; - const double derive_keys_time = - delta_time / std::chrono::milliseconds(1) / count; - - OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel(); - printf("PERF:head, security, provision (ms), lic req(ms), derive keys(ms)\n"); - printf("PERF:stat, %u, %8.3f, %8.3f, %8.3f\n", - static_cast(level), provision_time, license_request_time, - derive_keys_time); -} - -// Test DeriveKeysFromSessionKey using the maximum size for the HMAC context. -TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { - vector session_key; - vector enc_session_key; - ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); - const size_t max_size = GetResourceValue(kLargeMessageSize); - vector mac_context(max_size); - vector enc_context(max_size); - // Stripe the data so the two vectors are not identical, and not all zeroes. - for (size_t i = 0; i < max_size; i++) { - mac_context[i] = i % 0x100; - enc_context[i] = (3 * i) % 0x100; - } - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_DeriveKeysFromSessionKey( - session_.session_id(), enc_session_key.data(), - enc_session_key.size(), mac_context.data(), mac_context.size(), - enc_context.data(), enc_context.size())); -} - -TEST_F(OEMCryptoUsesCertificate, - OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) { - vector session_key; - vector enc_session_key; - ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - session_.FillDefaultContext(&mac_context, &enc_context); - OEMCrypto_SESSION session_id = session_.session_id(); - auto oemcrypto_function = [&session_id, &enc_context, &mac_context, - &enc_session_key](size_t buffer_length) { - mac_context.resize(buffer_length); - return OEMCrypto_DeriveKeysFromSessionKey( - session_id, enc_session_key.data(), enc_session_key.size(), - mac_context.data(), mac_context.size(), enc_context.data(), - enc_context.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoUsesCertificate, - OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) { - vector session_key; - vector enc_session_key; - ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - session_.FillDefaultContext(&mac_context, &enc_context); - OEMCrypto_SESSION session_id = session_.session_id(); - auto oemcrypto_function = [&session_id, &enc_context, &mac_context, - &enc_session_key](size_t buffer_length) { - enc_context.resize(buffer_length); - return OEMCrypto_DeriveKeysFromSessionKey( - session_id, enc_session_key.data(), enc_session_key.size(), - mac_context.data(), mac_context.size(), enc_context.data(), - enc_context.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_F(OEMCryptoUsesCertificate, - OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) { - vector session_key; - vector enc_session_key; - ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - session_.FillDefaultContext(&mac_context, &enc_context); - OEMCrypto_SESSION session_id = session_.session_id(); - auto oemcrypto_function = [&session_id, &session_key, &enc_context, - &mac_context, - &enc_session_key](size_t buffer_length) { - session_key.resize(buffer_length); - return OEMCrypto_DeriveKeysFromSessionKey( - session_id, enc_session_key.data(), enc_session_key.size(), - mac_context.data(), mac_context.size(), enc_context.data(), - enc_context.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -// This test attempts to use alternate algorithms for loaded device certs. -class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { - protected: - void DisallowForbiddenPadding(RSA_Padding_Scheme scheme, size_t size) { - OEMCryptoResult sts; - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - // Sign a Message - vector licenseRequest(size); - GetRandBytes(licenseRequest.data(), licenseRequest.size()); - size_t signature_length = 256; - vector signature(signature_length); - sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), - signature.data(), &signature_length, scheme); - // Allow OEMCrypto to request a full buffer. - if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - ASSERT_NE(static_cast(0), signature_length); - signature.assign(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), - signature.data(), &signature_length, scheme); - } - - EXPECT_NE(OEMCrypto_SUCCESS, sts) - << "Signed with forbidden padding scheme=" << (int)scheme - << ", size=" << (int)size; - const vector zero(signature.size(), 0); - ASSERT_EQ(zero, signature); // signature should not be computed. - } - - void TestSignature(RSA_Padding_Scheme scheme, size_t size) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - vector licenseRequest(size); - GetRandBytes(licenseRequest.data(), licenseRequest.size()); - size_t signature_length = 0; - OEMCryptoResult sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr, - &signature_length, scheme); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_NE(static_cast(0), signature_length); - - std::vector signature(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature( - s.session_id(), licenseRequest.data(), licenseRequest.size(), - signature.data(), &signature_length, scheme); - - ASSERT_EQ(OEMCrypto_SUCCESS, sts) - << "Failed to sign with padding scheme=" << (int)scheme - << ", size=" << size; - signature.resize(signature_length); - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature( - licenseRequest, signature.data(), signature_length, scheme)); - } - - void DisallowDeriveKeys() { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - s.GenerateNonce(); - vector session_key; - vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key)); - vector mac_context; - vector enc_context; - s.FillDefaultContext(&mac_context, &enc_context); - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_DeriveKeysFromSessionKey( - s.session_id(), enc_session_key.data(), - enc_session_key.size(), mac_context.data(), - mac_context.size(), enc_context.data(), enc_context.size())); - } - - // If force is true, we assert that the key loads successfully. - void LoadWithAllowedSchemes(uint32_t schemes, bool force) { - Session s; - ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); - provisioning_messages.set_allowed_schemes(schemes); - provisioning_messages.PrepareSession(keybox_); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse()); - OEMCryptoResult sts = provisioning_messages.LoadResponse(); - key_loaded_ = (OEMCrypto_SUCCESS == sts); - if (key_loaded_) { - uint8_t* ptr = provisioning_messages.response_data().rsa_key; - size_t len = provisioning_messages.response_data().rsa_key_length; - encoded_rsa_key_ = std::vector(ptr, ptr + len); - wrapped_rsa_key_ = provisioning_messages.wrapped_rsa_key(); - EXPECT_GT(wrapped_rsa_key_.size(), 0u); - EXPECT_EQ(nullptr, find(wrapped_rsa_key_, encoded_rsa_key_)); - } - if (force) { - EXPECT_EQ(OEMCrypto_SUCCESS, sts); - } - } - - bool key_loaded_ = false; -}; - -TEST_F(OEMCryptoLoadsCertificateAlternates, - OEMCryptoMemoryGenerateRSASignatureForHugeBuffer) { - OEMCryptoResult sts; - LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); - // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) { - ASSERT_TRUE(key_loaded_); - } - if (key_loaded_) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - vector message_buffer(10); - size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), message_buffer.data(), - message_buffer.size(), nullptr, - &signature_length, kSign_PKCS1_Block1); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_NE(static_cast(0), signature_length); - vector signature(signature_length); - - auto oemcrypto_function = [&](size_t buffer_length) { - message_buffer.resize(buffer_length); - return OEMCrypto_GenerateRSASignature( - s.session_id(), message_buffer.data(), message_buffer.size(), - signature.data(), &signature_length, kSign_PKCS1_Block1); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); - s.close(); - } -} - -TEST_F(OEMCryptoLoadsCertificateAlternates, - OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) { - LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); - // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) { - ASSERT_TRUE(key_loaded_); - } - if (key_loaded_) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - vector message_buffer(50); - vector signature; - auto oemcrypto_function = [&](size_t signature_length) { - signature.resize(signature_length); - return OEMCrypto_GenerateRSASignature( - s.session_id(), message_buffer.data(), message_buffer.size(), - signature.data(), &signature_length, kSign_PKCS1_Block1); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); - s.close(); - } -} - -// The alternate padding is only required for cast receivers, but all devices -// should forbid the alternate padding for regular certificates. -TEST_F(OEMCryptoLoadsCertificateAlternates, DisallowForbiddenPaddingAPI09) { - LoadWithAllowedSchemes(kSign_RSASSA_PSS, true); // Use default padding scheme - DisallowForbiddenPadding(kSign_PKCS1_Block1, 50); -} - -// The alternate padding is only required for cast receivers, but if a device -// does load an alternate certificate, it should NOT use it for generating -// a license request signature. -TEST_F(OEMCryptoLoadsCertificateAlternates, TestSignaturePKCS1) { - // Try to load an RSA key with alternative padding schemes. This signing - // scheme is used by cast receivers. - LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); - // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) { - ASSERT_TRUE(key_loaded_); - } - // If the key loaded with no error, then we will verify that it is not used - // for forbidden padding schemes. - if (key_loaded_) { - // The other padding scheme should fail. - DisallowForbiddenPadding(kSign_RSASSA_PSS, 83); - DisallowDeriveKeys(); - if (global_features.cast_receiver) { - // A signature with a valid size should succeed. - TestSignature(kSign_PKCS1_Block1, 83); - TestSignature(kSign_PKCS1_Block1, 50); - } - // A signature with padding that is too big should fail. - DisallowForbiddenPadding(kSign_PKCS1_Block1, 84); // too big. - } -} - -// This test verifies RSA signing with the alternate padding scheme used by -// Android cast receivers, PKCS1 Block 1. These tests are not required for -// other devices, and should be filtered out by DeviceFeatures::Initialize for -// those devices. -class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { - protected: - vector encode(uint8_t type, const vector& substring) { - vector result; - result.push_back(type); - if (substring.size() < 0x80) { - uint8_t length = substring.size(); - result.push_back(length); - } else if (substring.size() < 0x100) { - result.push_back(0x81); - uint8_t length = substring.size(); - result.push_back(length); - } else { - result.push_back(0x82); - uint16_t length = substring.size(); - result.push_back(length >> 8); - result.push_back(length & 0xFF); - } - result.insert(result.end(), substring.begin(), substring.end()); - return result; - } - vector concat(const vector& a, const vector& b) { - vector result = a; - result.insert(result.end(), b.begin(), b.end()); - return result; - } - - // This encodes the RSA key used in the PKCS#1 signing tests below. - void BuildRSAKey() { - vector field_n = - encode(0x02, wvutil::a2b_hex("00" - "df271fd25f8644496b0c81be4bd50297" - "ef099b002a6fd67727eb449cea566ed6" - "a3981a71312a141cabc9815c1209e320" - "a25b32464e9999f18ca13a9fd3892558" - "f9e0adefdd3650dd23a3f036d60fe398" - "843706a40b0b8462c8bee3bce12f1f28" - "60c2444cdc6a44476a75ff4aa24273cc" - "be3bf80248465f8ff8c3a7f3367dfc0d" - "f5b6509a4f82811cedd81cdaaa73c491" - "da412170d544d4ba96b97f0afc806549" - "8d3a49fd910992a1f0725be24f465cfe" - "7e0eabf678996c50bc5e7524abf73f15" - "e5bef7d518394e3138ce4944506aaaaf" - "3f9b236dcab8fc00f87af596fdc3d9d6" - "c75cd508362fae2cbeddcc4c7450b17b" - "776c079ecca1f256351a43b97dbe2153")); - vector field_e = encode(0x02, wvutil::a2b_hex("010001")); - vector field_d = - encode(0x02, wvutil::a2b_hex("5bd910257830dce17520b03441a51a8c" - "ab94020ac6ecc252c808f3743c95b7c8" - "3b8c8af1a5014346ebc4242cdfb5d718" - "e30a733e71f291e4d473b61bfba6daca" - "ed0a77bd1f0950ae3c91a8f901118825" - "89e1d62765ee671e7baeea309f64d447" - "bbcfa9ea12dce05e9ea8939bc5fe6108" - "581279c982b308794b3448e7f7b95229" - "2df88c80cb40142c4b5cf5f8ddaa0891" - "678d610e582fcb880f0d707caf47d09a" - "84e14ca65841e5a3abc5e9dba94075a9" - "084341f0edad9b68e3b8e082b80b6e6e" - "8a0547b44fb5061b6a9131603a5537dd" - "abd01d8e863d8922e9aa3e4bfaea0b39" - "d79283ad2cbc8a59cce7a6ecf4e4c81e" - "d4c6591c807defd71ab06866bb5e7745")); - vector field_p = - encode(0x02, wvutil::a2b_hex("00" - "f44f5e4246391f482b2f5296e3602eb3" - "4aa136427710f7c0416d403fd69d4b29" - "130cfebef34e885abdb1a8a0a5f0e9b5" - "c33e1fc3bfc285b1ae17e40cc67a1913" - "dd563719815ebaf8514c2a7aa0018e63" - "b6c631dc315a46235716423d11ff5803" - "4e610645703606919f5c7ce2660cd148" - "bd9efc123d9c54b6705590d006cfcf3f")); - vector field_q = - encode(0x02, wvutil::a2b_hex("00" - "e9d49841e0e0a6ad0d517857133e36dc" - "72c1bdd90f9174b52e26570f373640f1" - "c185e7ea8e2ed7f1e4ebb951f70a5802" - "3633b0097aec67c6dcb800fc1a67f9bb" - "0563610f08ebc8746ad129772136eb1d" - "daf46436450d318332a84982fe5d28db" - "e5b3e912407c3e0e03100d87d436ee40" - "9eec1cf85e80aba079b2e6106b97bced")); - vector field_exp1 = - encode(0x02, wvutil::a2b_hex("00" - "ed102acdb26871534d1c414ecad9a4d7" - "32fe95b10eea370da62f05de2c393b1a" - "633303ea741b6b3269c97f704b352702" - "c9ae79922f7be8d10db67f026a8145de" - "41b30c0a42bf923bac5f7504c248604b" - "9faa57ed6b3246c6ba158e36c644f8b9" - "548fcf4f07e054a56f768674054440bc" - "0dcbbc9b528f64a01706e05b0b91106f")); - vector field_exp2 = - encode(0x02, wvutil::a2b_hex("6827924a85e88b55ba00f8219128bd37" - "24c6b7d1dfe5629ef197925fecaff5ed" - "b9cdf3a7befd8ea2e8dd3707138b3ff8" - "7c3c39c57f439e562e2aa805a39d7cd7" - "9966d2ece7845f1dbc16bee99999e4d0" - "bf9eeca45fcda8a8500035fe6b5f03bc" - "2f6d1bfc4d4d0a3723961af0cdce4a01" - "eec82d7f5458ec19e71b90eeef7dff61")); - vector field_invq = - encode(0x02, wvutil::a2b_hex("57b73888d183a99a6307422277551a3d" - "9e18adf06a91e8b55ceffef9077c8496" - "948ecb3b16b78155cb2a3a57c119d379" - "951c010aa635edcf62d84c5a122a8d67" - "ab5fa9e5a4a8772a1e943bafc70ae3a4" - "c1f0f3a4ddffaefd1892c8cb33bb0d0b" - "9590e963a69110fb34db7b906fc4ba28" - "36995aac7e527490ac952a02268a4f18")); - - // Header of rsa key is constant. - encoded_rsa_key_ = wvutil::a2b_hex( - // 0x02 0x01 0x00 == integer, size 1 byte, value = 0 (field=version) - "020100" - // 0x30, sequence, size = d = 13 (field=pkeyalg) AlgorithmIdentifier - "300d" - // 0x06 = object identifier. length = 9 - // (this should be 1.2.840.113549.1.1.1) (field=algorithm) - "0609" - "2a" // 1*0x40 + 2 = 42 = 0x2a. - "8648" // 840 = 0x348, 0x03 *2 + 0x80 + (0x48>>15) = 0x86. - // 0x48 -> 0x48 - "86f70d" // 113549 = 0x1668d -> (110 , 1110111, 0001101) - // -> (0x80+0x06, 0x80+0x77, 0x0d) - "01" // 1 - "01" // 1 - "01" // 1 - "05" // null object. (field=parameter?) - "00" // size of null object - ); - - vector pkey = wvutil::a2b_hex("020100"); // integer, version = 0. - pkey = concat(pkey, field_n); - pkey = concat(pkey, field_e); - pkey = concat(pkey, field_d); - pkey = concat(pkey, field_p); - pkey = concat(pkey, field_q); - pkey = concat(pkey, field_exp1); - pkey = concat(pkey, field_exp2); - pkey = concat(pkey, field_invq); - pkey = encode(0x30, pkey); - pkey = encode(0x04, pkey); - - encoded_rsa_key_ = concat(encoded_rsa_key_, pkey); - encoded_rsa_key_ = encode(0x30, encoded_rsa_key_); // 0x30=sequence - } - - // This is used to test a signature from the file pkcs1v15sign-vectors.txt. - void TestSignature(RSA_Padding_Scheme scheme, const vector& message, - const vector& correct_signature) { - OEMCryptoResult sts; - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_)); - - // The application will compute the SHA-1 Hash of the message, so this - // test must do that also. - uint8_t hash[SHA_DIGEST_LENGTH]; - if (!SHA1(message.data(), message.size(), hash)) { - dump_boringssl_error(); - FAIL() << "boringssl error creating SHA1 hash."; - } - - // The application will prepend the digest info to the hash. - // SHA-1 digest info prefix = 0x30 0x21 0x30 ... - vector digest = wvutil::a2b_hex("3021300906052b0e03021a05000414"); - digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH); - - // OEMCrypto will apply the padding, and encrypt to generate the signature. - size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), - digest.size(), nullptr, - &signature_length, scheme); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_NE(static_cast(0), signature_length); - - vector signature(signature_length); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), - digest.size(), signature.data(), - &signature_length, scheme); - - ASSERT_EQ(OEMCrypto_SUCCESS, sts) - << "Failed to sign with padding scheme=" << (int)scheme - << ", size=" << message.size(); - signature.resize(signature_length); - ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo( - encoded_rsa_key_.data(), encoded_rsa_key_.size())); - - // Verify that the signature matches the official test vector. - ASSERT_EQ(correct_signature.size(), signature_length); - signature.resize(signature_length); - ASSERT_EQ(correct_signature, signature); - - // Also verify that our verification algorithm agrees. This is not needed - // to test OEMCrypto, but it does verify that this test is valid. - ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(digest, signature.data(), - signature_length, scheme)); - ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature( - digest, correct_signature.data(), correct_signature.size(), scheme)); - } -}; - -// CAST Receivers should report that they support cast certificates. -TEST_F(OEMCryptoCastReceiverTest, SupportsCertificatesAPI13) { - ASSERT_NE(0u, - OEMCrypto_Supports_RSA_CAST & OEMCrypto_SupportedCertificates()); -} - -// # PKCS#1 v1.5 Signature Example 15.1 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_1) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "f45d55f35551e975d6a8dc7ea9f48859" - "3940cc75694a278f27e578a163d839b3" - "4040841808cf9c58c9b8728bf5f9ce8e" - "e811ea91714f47bab92d0f6d5a26fcfe" - "ea6cd93b910c0a2c963e64eb1823f102" - "753d41f0335910ad3a977104f1aaf6c3" - "742716a9755d11b8eed690477f445c5d" - "27208b2e284330fa3d301423fa7f2d08" - "6e0ad0b892b9db544e456d3f0dab85d9" - "53c12d340aa873eda727c8a649db7fa6" - "3740e25e9af1533b307e61329993110e" - "95194e039399c3824d24c51f22b26bde" - "1024cd395958a2dfeb4816a6e8adedb5" - "0b1f6b56d0b3060ff0f1c4cb0d0e001d" - "d59d73be12"); - vector signature = wvutil::a2b_hex( - "b75a5466b65d0f300ef53833f2175c8a" - "347a3804fc63451dc902f0b71f908345" - "9ed37a5179a3b723a53f1051642d7737" - "4c4c6c8dbb1ca20525f5c9f32db77695" - "3556da31290e22197482ceb69906c46a" - "758fb0e7409ba801077d2a0a20eae7d1" - "d6d392ab4957e86b76f0652d68b83988" - "a78f26e11172ea609bf849fbbd78ad7e" - "dce21de662a081368c040607cee29db0" - "627227f44963ad171d2293b633a392e3" - "31dca54fe3082752f43f63c161b447a4" - "c65a6875670d5f6600fcc860a1caeb0a" - "88f8fdec4e564398a5c46c87f68ce070" - "01f6213abe0ab5625f87d19025f08d81" - "dac7bd4586bc9382191f6d2880f6227e" - "5df3eed21e7792d249480487f3655261"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} -// # PKCS#1 v1.5 Signature Example 15.2 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_2) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "c14b4c6075b2f9aad661def4ecfd3cb9" - "33c623f4e63bf53410d2f016d1ab98e2" - "729eccf8006cd8e08050737d95fdbf29" - "6b66f5b9792a902936c4f7ac69f51453" - "ce4369452dc22d96f037748114662000" - "dd9cd3a5e179f4e0f81fa6a0311ca1ae" - "e6519a0f63cec78d27bb726393fb7f1f" - "88cde7c97f8a66cd66301281dac3f3a4" - "33248c75d6c2dcd708b6a97b0a3f325e" - "0b2964f8a5819e479b"); - vector signature = wvutil::a2b_hex( - "afa7343462bea122cc149fca70abdae7" - "9446677db5373666af7dc313015f4de7" - "86e6e394946fad3cc0e2b02bedba5047" - "fe9e2d7d099705e4a39f28683279cf0a" - "c85c1530412242c0e918953be000e939" - "cf3bf182525e199370fa7907eba69d5d" - "b4631017c0e36df70379b5db8d4c695a" - "979a8e6173224065d7dc15132ef28cd8" - "22795163063b54c651141be86d36e367" - "35bc61f31fca574e5309f3a3bbdf91ef" - "f12b99e9cc1744f1ee9a1bd22c5bad96" - "ad481929251f0343fd36bcf0acde7f11" - "e5ad60977721202796fe061f9ada1fc4" - "c8e00d6022a8357585ffe9fdd59331a2" - "8c4aa3121588fb6cf68396d8ac054659" - "9500c9708500a5972bd54f72cf8db0c8"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.3 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_3) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "d02371ad7ee48bbfdb2763de7a843b94" - "08ce5eb5abf847ca3d735986df84e906" - "0bdbcdd3a55ba55dde20d4761e1a21d2" - "25c1a186f4ac4b3019d3adf78fe63346" - "67f56f70c901a0a2700c6f0d56add719" - "592dc88f6d2306c7009f6e7a635b4cb3" - "a502dfe68ddc58d03be10a1170004fe7" - "4dd3e46b82591ff75414f0c4a03e605e" - "20524f2416f12eca589f111b75d639c6" - "1baa80cafd05cf3500244a219ed9ced9" - "f0b10297182b653b526f400f2953ba21" - "4d5bcd47884132872ae90d4d6b1f4215" - "39f9f34662a56dc0e7b4b923b6231e30" - "d2676797817f7c337b5ac824ba93143b" - "3381fa3dce0e6aebd38e67735187b1eb" - "d95c02"); - vector signature = wvutil::a2b_hex( - "3bac63f86e3b70271203106b9c79aabd" - "9f477c56e4ee58a4fce5baf2cab4960f" - "88391c9c23698be75c99aedf9e1abf17" - "05be1dac33140adb48eb31f450bb9efe" - "83b7b90db7f1576d33f40c1cba4b8d6b" - "1d3323564b0f1774114fa7c08e6d1e20" - "dd8fbba9b6ac7ad41e26b4568f4a8aac" - "bfd178a8f8d2c9d5f5b88112935a8bc9" - "ae32cda40b8d20375510735096536818" - "ce2b2db71a9772c9b0dda09ae10152fa" - "11466218d091b53d92543061b7294a55" - "be82ff35d5c32fa233f05aaac7585030" - "7ecf81383c111674397b1a1b9d3bf761" - "2ccbe5bacd2b38f0a98397b24c83658f" - "b6c0b4140ef11970c4630d44344e76ea" - "ed74dcbee811dbf6575941f08a6523b8"); - TestSignature(kSign_PKCS1_Block1, message, signature); -}; - -// # PKCS#1 v1.5 Signature Example 15.4 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_4) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "29035584ab7e0226a9ec4b02e8dcf127" - "2dc9a41d73e2820007b0f6e21feccd5b" - "d9dbb9ef88cd6758769ee1f956da7ad1" - "8441de6fab8386dbc693"); - vector signature = wvutil::a2b_hex( - "28d8e3fcd5dddb21ffbd8df1630d7377" - "aa2651e14cad1c0e43ccc52f907f946d" - "66de7254e27a6c190eb022ee89ecf622" - "4b097b71068cd60728a1aed64b80e545" - "7bd3106dd91706c937c9795f2b36367f" - "f153dc2519a8db9bdf2c807430c451de" - "17bbcd0ce782b3e8f1024d90624dea7f" - "1eedc7420b7e7caa6577cef43141a726" - "4206580e44a167df5e41eea0e69a8054" - "54c40eefc13f48e423d7a32d02ed42c0" - "ab03d0a7cf70c5860ac92e03ee005b60" - "ff3503424b98cc894568c7c56a023355" - "1cebe588cf8b0167b7df13adcad82867" - "6810499c704da7ae23414d69e3c0d2db" - "5dcbc2613bc120421f9e3653c5a87672" - "97643c7e0740de016355453d6c95ae72"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.5 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_5) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex("bda3a1c79059eae598308d3df609"); - vector signature = wvutil::a2b_hex( - "a156176cb96777c7fb96105dbd913bc4" - "f74054f6807c6008a1a956ea92c1f81c" - "b897dc4b92ef9f4e40668dc7c556901a" - "cb6cf269fe615b0fb72b30a513386923" - "14b0e5878a88c2c7774bd16939b5abd8" - "2b4429d67bd7ac8e5ea7fe924e20a6ec" - "662291f2548d734f6634868b039aa5f9" - "d4d906b2d0cb8585bf428547afc91c6e" - "2052ddcd001c3ef8c8eefc3b6b2a82b6" - "f9c88c56f2e2c3cb0be4b80da95eba37" - "1d8b5f60f92538743ddbb5da2972c71f" - "e7b9f1b790268a0e770fc5eb4d5dd852" - "47d48ae2ec3f26255a3985520206a1f2" - "68e483e9dbb1d5cab190917606de31e7" - "c5182d8f151bf41dfeccaed7cde690b2" - "1647106b490c729d54a8fe2802a6d126"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.6 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_6) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "c187915e4e87da81c08ed4356a0cceac" - "1c4fb5c046b45281b387ec28f1abfd56" - "7e546b236b37d01ae71d3b2834365d3d" - "f380b75061b736b0130b070be58ae8a4" - "6d12166361b613dbc47dfaeb4ca74645" - "6c2e888385525cca9dd1c3c7a9ada76d" - "6c"); - vector signature = wvutil::a2b_hex( - "9cab74163608669f7555a333cf196fe3" - "a0e9e5eb1a32d34bb5c85ff689aaab0e" - "3e65668ed3b1153f94eb3d8be379b8ee" - "f007c4a02c7071ce30d8bb341e58c620" - "f73d37b4ecbf48be294f6c9e0ecb5e63" - "fec41f120e5553dfa0ebebbb72640a95" - "37badcb451330229d9f710f62e3ed8ec" - "784e50ee1d9262b42671340011d7d098" - "c6f2557b2131fa9bd0254636597e88ec" - "b35a240ef0fd85957124df8080fee1e1" - "49af939989e86b26c85a5881fae8673d" - "9fd40800dd134eb9bdb6410f420b0aa9" - "7b20efcf2eb0c807faeb83a3ccd9b51d" - "4553e41dfc0df6ca80a1e81dc234bb83" - "89dd195a38b42de4edc49d346478b9f1" - "1f0557205f5b0bd7ffe9c850f396d7c4"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.7 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_7) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "abfa2ecb7d29bd5bcb9931ce2bad2f74" - "383e95683cee11022f08e8e7d0b8fa05" - "8bf9eb7eb5f98868b5bb1fb5c31ceda3" - "a64f1a12cdf20fcd0e5a246d7a1773d8" - "dba0e3b277545babe58f2b96e3f4edc1" - "8eabf5cd2a560fca75fe96e07d859def" - "b2564f3a34f16f11e91b3a717b41af53" - "f6605323001aa406c6"); - vector signature = wvutil::a2b_hex( - "c4b437bcf703f352e1faf74eb9622039" - "426b5672caf2a7b381c6c4f0191e7e4a" - "98f0eebcd6f41784c2537ff0f99e7498" - "2c87201bfbc65eae832db71d16dacadb" - "0977e5c504679e40be0f9db06ffd848d" - "d2e5c38a7ec021e7f68c47dfd38cc354" - "493d5339b4595a5bf31e3f8f13816807" - "373df6ad0dc7e731e51ad19eb4754b13" - "4485842fe709d378444d8e36b1724a4f" - "da21cafee653ab80747f7952ee804dea" - "b1039d84139945bbf4be82008753f3c5" - "4c7821a1d241f42179c794ef7042bbf9" - "955656222e45c34369a384697b6ae742" - "e18fa5ca7abad27d9fe71052e3310d0f" - "52c8d12ea33bf053a300f4afc4f098df" - "4e6d886779d64594d369158fdbc1f694"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.8 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_8) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "df4044a89a83e9fcbf1262540ae3038b" - "bc90f2b2628bf2a4467ac67722d8546b" - "3a71cb0ea41669d5b4d61859c1b4e47c" - "ecc5933f757ec86db0644e311812d00f" - "b802f03400639c0e364dae5aebc5791b" - "c655762361bc43c53d3c7886768f7968" - "c1c544c6f79f7be820c7e2bd2f9d73e6" - "2ded6d2e937e6a6daef90ee37a1a52a5" - "4f00e31addd64894cf4c02e16099e29f" - "9eb7f1a7bb7f84c47a2b594813be02a1" - "7b7fc43b34c22c91925264126c89f86b" - "b4d87f3ef131296c53a308e0331dac8b" - "af3b63422266ecef2b90781535dbda41" - "cbd0cf22a8cbfb532ec68fc6afb2ac06"); - vector signature = wvutil::a2b_hex( - "1414b38567ae6d973ede4a06842dcc0e" - "0559b19e65a4889bdbabd0fd02806829" - "13bacd5dc2f01b30bb19eb810b7d9ded" - "32b284f147bbe771c930c6052aa73413" - "90a849f81da9cd11e5eccf246dbae95f" - "a95828e9ae0ca3550325326deef9f495" - "30ba441bed4ac29c029c9a2736b1a419" - "0b85084ad150426b46d7f85bd702f48d" - "ac5f71330bc423a766c65cc1dcab20d3" - "d3bba72b63b3ef8244d42f157cb7e3a8" - "ba5c05272c64cc1ad21a13493c3911f6" - "0b4e9f4ecc9900eb056ee59d6fe4b8ff" - "6e8048ccc0f38f2836fd3dfe91bf4a38" - "6e1ecc2c32839f0ca4d1b27a568fa940" - "dd64ad16bd0125d0348e383085f08894" - "861ca18987227d37b42b584a8357cb04"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.9 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_9) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "ea941ff06f86c226927fcf0e3b11b087" - "2676170c1bfc33bda8e265c77771f9d0" - "850164a5eecbcc5ce827fbfa07c85214" - "796d8127e8caa81894ea61ceb1449e72" - "fea0a4c943b2da6d9b105fe053b9039a" - "9cc53d420b7539fab2239c6b51d17e69" - "4c957d4b0f0984461879a0759c4401be" - "ecd4c606a0afbd7a076f50a2dfc2807f" - "24f1919baa7746d3a64e268ed3f5f8e6" - "da83a2a5c9152f837cb07812bd5ba7d3" - "a07985de88113c1796e9b466ec299c5a" - "c1059e27f09415"); - vector signature = wvutil::a2b_hex( - "ceeb84ccb4e9099265650721eea0e8ec" - "89ca25bd354d4f64564967be9d4b08b3" - "f1c018539c9d371cf8961f2291fbe0dc" - "2f2f95fea47b639f1e12f4bc381cef0c" - "2b7a7b95c3adf27605b7f63998c3cbad" - "542808c3822e064d4ad14093679e6e01" - "418a6d5c059684cd56e34ed65ab605b8" - "de4fcfa640474a54a8251bbb7326a42d" - "08585cfcfc956769b15b6d7fdf7da84f" - "81976eaa41d692380ff10eaecfe0a579" - "682909b5521fade854d797b8a0345b9a" - "864e0588f6caddbf65f177998e180d1f" - "102443e6dca53a94823caa9c3b35f322" - "583c703af67476159ec7ec93d1769b30" - "0af0e7157dc298c6cd2dee2262f8cddc" - "10f11e01741471bbfd6518a175734575"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.10 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_10) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "d8b81645c13cd7ecf5d00ed2c91b9acd" - "46c15568e5303c4a9775ede76b48403d" - "6be56c05b6b1cf77c6e75de096c5cb35" - "51cb6fa964f3c879cf589d28e1da2f9d" - "ec"); - vector signature = wvutil::a2b_hex( - "2745074ca97175d992e2b44791c323c5" - "7167165cdd8da579cdef4686b9bb404b" - "d36a56504eb1fd770f60bfa188a7b24b" - "0c91e881c24e35b04dc4dd4ce38566bc" - "c9ce54f49a175fc9d0b22522d9579047" - "f9ed42eca83f764a10163997947e7d2b" - "52ff08980e7e7c2257937b23f3d279d4" - "cd17d6f495546373d983d536efd7d1b6" - "7181ca2cb50ac616c5c7abfbb9260b91" - "b1a38e47242001ff452f8de10ca6eaea" - "dcaf9edc28956f28a711291fc9a80878" - "b8ba4cfe25b8281cb80bc9cd6d2bd182" - "5246eebe252d9957ef93707352084e6d" - "36d423551bf266a85340fb4a6af37088" - "0aab07153d01f48d086df0bfbec05e7b" - "443b97e71718970e2f4bf62023e95b67"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.11 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_11) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "e5739b6c14c92d510d95b826933337ff" - "0d24ef721ac4ef64c2bad264be8b44ef" - "a1516e08a27eb6b611d3301df0062dae" - "fc73a8c0d92e2c521facbc7b26473876" - "7ea6fc97d588a0baf6ce50adf79e600b" - "d29e345fcb1dba71ac5c0289023fe4a8" - "2b46a5407719197d2e958e3531fd54ae" - "f903aabb4355f88318994ed3c3dd62f4" - "20a7"); - vector signature = wvutil::a2b_hex( - "be40a5fb94f113e1b3eff6b6a33986f2" - "02e363f07483b792e68dfa5554df0466" - "cc32150950783b4d968b639a04fd2fb9" - "7f6eb967021f5adccb9fca95acc8f2cd" - "885a380b0a4e82bc760764dbab88c1e6" - "c0255caa94f232199d6f597cc9145b00" - "e3d4ba346b559a8833ad1516ad5163f0" - "16af6a59831c82ea13c8224d84d0765a" - "9d12384da460a8531b4c407e04f4f350" - "709eb9f08f5b220ffb45abf6b75d1579" - "fd3f1eb55fc75b00af8ba3b087827fe9" - "ae9fb4f6c5fa63031fe582852fe2834f" - "9c89bff53e2552216bc7c1d4a3d5dc2b" - "a6955cd9b17d1363e7fee8ed7629753f" - "f3125edd48521ae3b9b03217f4496d0d" - "8ede57acbc5bd4deae74a56f86671de2"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.12 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_12) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "7af42835917a88d6b3c6716ba2f5b0d5" - "b20bd4e2e6e574e06af1eef7c81131be" - "22bf8128b9cbc6ec00275ba80294a5d1" - "172d0824a79e8fdd830183e4c00b9678" - "2867b1227fea249aad32ffc5fe007bc5" - "1f21792f728deda8b5708aa99cabab20" - "a4aa783ed86f0f27b5d563f42e07158c" - "ea72d097aa6887ec411dd012912a5e03" - "2bbfa678507144bcc95f39b58be7bfd1" - "759adb9a91fa1d6d8226a8343a8b849d" - "ae76f7b98224d59e28f781f13ece605f" - "84f6c90bae5f8cf378816f4020a7dda1" - "bed90c92a23634d203fac3fcd86d68d3" - "182a7d9ccabe7b0795f5c655e9acc4e3" - "ec185140d10cef053464ab175c83bd83" - "935e3dabaf3462eebe63d15f573d269a"); - vector signature = wvutil::a2b_hex( - "4e78c5902b807914d12fa537ae6871c8" - "6db8021e55d1adb8eb0ccf1b8f36ab7d" - "ad1f682e947a627072f03e627371781d" - "33221d174abe460dbd88560c22f69011" - "6e2fbbe6e964363a3e5283bb5d946ef1" - "c0047eba038c756c40be7923055809b0" - "e9f34a03a58815ebdde767931f018f6f" - "1878f2ef4f47dd374051dd48685ded6e" - "fb3ea8021f44be1d7d149398f98ea9c0" - "8d62888ebb56192d17747b6b8e170954" - "31f125a8a8e9962aa31c285264e08fb2" - "1aac336ce6c38aa375e42bc92ab0ab91" - "038431e1f92c39d2af5ded7e43bc151e" - "6ebea4c3e2583af3437e82c43c5e3b5b" - "07cf0359683d2298e35948ed806c063c" - "606ea178150b1efc15856934c7255cfe"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.13 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_13) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "ebaef3f9f23bdfe5fa6b8af4c208c189" - "f2251bf32f5f137b9de4406378686b3f" - "0721f62d24cb8688d6fc41a27cbae21d" - "30e429feacc7111941c277"); - vector signature = wvutil::a2b_hex( - "c48dbef507114f03c95fafbeb4df1bfa" - "88e0184a33cc4f8a9a1035ff7f822a5e" - "38cda18723915ff078244429e0f6081c" - "14fd83331fa65c6ba7bb9a12dbf66223" - "74cd0ca57de3774e2bd7ae823677d061" - "d53ae9c4040d2da7ef7014f3bbdc95a3" - "61a43855c8ce9b97ecabce174d926285" - "142b534a3087f9f4ef74511ec742b0d5" - "685603faf403b5072b985df46adf2d25" - "29a02d40711e2190917052371b79b749" - "b83abf0ae29486c3f2f62477b2bd362b" - "039c013c0c5076ef520dbb405f42cee9" - "5425c373a975e1cdd032c49622c85079" - "b09e88dab2b13969ef7a723973781040" - "459f57d5013638483de2d91cb3c490da" - "81c46de6cd76ea8a0c8f6fe331712d24"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.14 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_14) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "c5a2711278761dfcdd4f0c99e6f5619d" - "6c48b5d4c1a80982faa6b4cf1cf7a60f" - "f327abef93c801429efde08640858146" - "1056acc33f3d04f5ada21216cacd5fd1" - "f9ed83203e0e2fe6138e3eae8424e591" - "5a083f3f7ab76052c8be55ae882d6ec1" - "482b1e45c5dae9f41015405327022ec3" - "2f0ea2429763b255043b1958ee3cf6d6" - "3983596eb385844f8528cc9a9865835d" - "c5113c02b80d0fca68aa25e72bcaaeb3" - "cf9d79d84f984fd417"); - vector signature = wvutil::a2b_hex( - "6bd5257aa06611fb4660087cb4bc4a9e" - "449159d31652bd980844daf3b1c7b353" - "f8e56142f7ea9857433b18573b4deede" - "818a93b0290297783f1a2f23cbc72797" - "a672537f01f62484cd4162c3214b9ac6" - "28224c5de01f32bb9b76b27354f2b151" - "d0e8c4213e4615ad0bc71f515e300d6a" - "64c6743411fffde8e5ff190e54923043" - "126ecfc4c4539022668fb675f25c07e2" - "0099ee315b98d6afec4b1a9a93dc3349" - "6a15bd6fde1663a7d49b9f1e639d3866" - "4b37a010b1f35e658682d9cd63e57de0" - "f15e8bdd096558f07ec0caa218a8c06f" - "4788453940287c9d34b6d40a3f09bf77" - "99fe98ae4eb49f3ff41c5040a50cefc9" - "bdf2394b749cf164480df1ab6880273b"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.15 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_15) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "9bf8aa253b872ea77a7e23476be26b23" - "29578cf6ac9ea2805b357f6fc3ad130d" - "baeb3d869a13cce7a808bbbbc969857e" - "03945c7bb61df1b5c2589b8e046c2a5d" - "7e4057b1a74f24c711216364288529ec" - "9570f25197213be1f5c2e596f8bf8b2c" - "f3cb38aa56ffe5e31df7395820e94ecf" - "3b1189a965dcf9a9cb4298d3c88b2923" - "c19fc6bc34aacecad4e0931a7c4e5d73" - "dc86dfa798a8476d82463eefaa90a8a9" - "192ab08b23088dd58e1280f7d72e4548" - "396baac112252dd5c5346adb2004a2f7" - "101ccc899cc7fafae8bbe295738896a5" - "b2012285014ef6"); - vector signature = wvutil::a2b_hex( - "27f7f4da9bd610106ef57d32383a448a" - "8a6245c83dc1309c6d770d357ba89e73" - "f2ad0832062eb0fe0ac915575bcd6b8b" - "cadb4e2ba6fa9da73a59175152b2d4fe" - "72b070c9b7379e50000e55e6c269f665" - "8c937972797d3add69f130e34b85bdec" - "9f3a9b392202d6f3e430d09caca82277" - "59ab825f7012d2ff4b5b62c8504dbad8" - "55c05edd5cab5a4cccdc67f01dd6517c" - "7d41c43e2a4957aff19db6f18b17859a" - "f0bc84ab67146ec1a4a60a17d7e05f8b" - "4f9ced6ad10908d8d78f7fc88b76adc8" - "290f87daf2a7be10ae408521395d54ed" - "2556fb7661854a730ce3d82c71a8d493" - "ec49a378ac8a3c74439f7cc555ba13f8" - "59070890ee18ff658fa4d741969d70a5"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.16 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_16) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "32474830e2203754c8bf0681dc4f842a" - "fe360930378616c108e833656e5640c8" - "6856885bb05d1eb9438efede679263de" - "07cb39553f6a25e006b0a52311a063ca" - "088266d2564ff6490c46b5609818548f" - "88764dad34a25e3a85d575023f0b9e66" - "5048a03c350579a9d32446c7bb96cc92" - "e065ab94d3c8952e8df68ef0d9fa456b" - "3a06bb80e3bbc4b28e6a94b6d0ff7696" - "a64efe05e735fea025d7bdbc4139f3a3" - "b546075cba7efa947374d3f0ac80a68d" - "765f5df6210bca069a2d88647af7ea04" - "2dac690cb57378ec0777614fb8b65ff4" - "53ca6b7dce6098451a2f8c0da9bfecf1" - "fdf391bbaa4e2a91ca18a1121a7523a2" - "abd42514f489e8"); - vector signature = wvutil::a2b_hex( - "6917437257c22ccb5403290c3dee82d9" - "cf7550b31bd31c51bd57bfd35d452ab4" - "db7c4be6b2e25ac9a59a1d2a7feb627f" - "0afd4976b3003cc9cffd8896505ec382" - "f265104d4cf8c932fa9fe86e00870795" - "9912389da4b2d6b369b36a5e72e29d24" - "c9a98c9d31a3ab44e643e6941266a47a" - "45e3446ce8776abe241a8f5fc6423b24" - "b1ff250dc2c3a8172353561077e850a7" - "69b25f0325dac88965a3b9b472c494e9" - "5f719b4eac332caa7a65c7dfe46d9aa7" - "e6e00f525f303dd63ab7919218901868" - "f9337f8cd26aafe6f33b7fb2c98810af" - "19f7fcb282ba1577912c1d368975fd5d" - "440b86e10c199715fa0b6f4250b53373" - "2d0befe1545150fc47b876de09b00a94"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.17 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_17) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "008e59505eafb550aae5e845584cebb0" - "0b6de1733e9f95d42c882a5bbeb5ce1c" - "57e119e7c0d4daca9f1ff7870217f7cf" - "d8a6b373977cac9cab8e71e420"); - vector signature = wvutil::a2b_hex( - "922503b673ee5f3e691e1ca85e9ff417" - "3cf72b05ac2c131da5603593e3bc259c" - "94c1f7d3a06a5b9891bf113fa39e59ff" - "7c1ed6465e908049cb89e4e125cd37d2" - "ffd9227a41b4a0a19c0a44fbbf3de55b" - "ab802087a3bb8d4ff668ee6bbb8ad89e" - "6857a79a9c72781990dfcf92cd519404" - "c950f13d1143c3184f1d250c90e17ac6" - "ce36163b9895627ad6ffec1422441f55" - "e4499dba9be89546ae8bc63cca01dd08" - "463ae7f1fce3d893996938778c1812e6" - "74ad9c309c5acca3fde44e7dd8695993" - "e9c1fa87acda99ece5c8499e468957ad" - "66359bf12a51adbe78d3a213b449bf0b" - "5f8d4d496acf03d3033b7ccd196bc22f" - "68fb7bef4f697c5ea2b35062f48a36dd"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.18 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_18) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "6abc54cf8d1dff1f53b17d8160368878" - "a8788cc6d22fa5c2258c88e660b09a89" - "33f9f2c0504ddadc21f6e75e0b833beb" - "555229dee656b9047b92f62e76b8ffcc" - "60dab06b80"); - vector signature = wvutil::a2b_hex( - "0b6daf42f7a862147e417493c2c401ef" - "ae32636ab4cbd44192bbf5f195b50ae0" - "96a475a1614f0a9fa8f7a026cb46c650" - "6e518e33d83e56477a875aca8c7e714c" - "e1bdbd61ef5d535239b33f2bfdd61771" - "bab62776d78171a1423cea8731f82e60" - "766d6454265620b15f5c5a584f55f95b" - "802fe78c574ed5dacfc831f3cf2b0502" - "c0b298f25ccf11f973b31f85e4744219" - "85f3cff702df3946ef0a6605682111b2" - "f55b1f8ab0d2ea3a683c69985ead93ed" - "449ea48f0358ddf70802cb41de2fd83f" - "3c808082d84936948e0c84a131b49278" - "27460527bb5cd24bfab7b48e071b2417" - "1930f99763272f9797bcb76f1d248157" - "5558fcf260b1f0e554ebb3df3cfcb958"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.19 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_19) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "af2d78152cf10efe01d274f217b177f6" - "b01b5e749f1567715da324859cd3dd88" - "db848ec79f48dbba7b6f1d33111ef31b" - "64899e7391c2bffd69f49025cf201fc5" - "85dbd1542c1c778a2ce7a7ee108a309f" - "eca26d133a5ffedc4e869dcd7656596a" - "c8427ea3ef6e3fd78fe99d8ddc71d839" - "f6786e0da6e786bd62b3a4f19b891a56" - "157a554ec2a2b39e25a1d7c7d37321c7" - "a1d946cf4fbe758d9276f08563449d67" - "414a2c030f4251cfe2213d04a5410637" - "87"); - vector signature = wvutil::a2b_hex( - "209c61157857387b71e24bf3dd564145" - "50503bec180ff53bdd9bac062a2d4995" - "09bf991281b79527df9136615b7a6d9d" - "b3a103b535e0202a2caca197a7b74e53" - "56f3dd595b49acfd9d30049a98ca88f6" - "25bca1d5f22a392d8a749efb6eed9b78" - "21d3110ac0d244199ecb4aa3d735a83a" - "2e8893c6bf8581383ccaee834635b7fa" - "1faffa45b13d15c1da33af71e89303d6" - "8090ff62ee615fdf5a84d120711da53c" - "2889198ab38317a9734ab27d67924cea" - "74156ff99bef9876bb5c339e93745283" - "e1b34e072226b88045e017e9f05b2a8c" - "416740258e223b2690027491732273f3" - "229d9ef2b1b3807e321018920ad3e53d" - "ae47e6d9395c184b93a374c671faa2ce"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// # PKCS#1 v1.5 Signature Example 15.20 -TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_20) { - BuildRSAKey(); - LoadWithAllowedSchemes(kSign_PKCS1_Block1, true); - vector message = wvutil::a2b_hex( - "40ee992458d6f61486d25676a96dd2cb" - "93a37f04b178482f2b186cf88215270d" - "ba29d786d774b0c5e78c7f6e56a956e7" - "f73950a2b0c0c10a08dbcd67e5b210bb" - "21c58e2767d44f7dd4014e3966143bf7" - "e3d66ff0c09be4c55f93b39994b8518d" - "9c1d76d5b47374dea08f157d57d70634" - "978f3856e0e5b481afbbdb5a3ac48d48" - "4be92c93de229178354c2de526e9c65a" - "31ede1ef68cb6398d7911684fec0babc" - "3a781a66660783506974d0e14825101c" - "3bfaea"); - vector signature = wvutil::a2b_hex( - "927502b824afc42513ca6570de338b8a" - "64c3a85eb828d3193624f27e8b1029c5" - "5c119c9733b18f5849b3500918bcc005" - "51d9a8fdf53a97749fa8dc480d6fe974" - "2a5871f973926528972a1af49e3925b0" - "adf14a842719b4a5a2d89fa9c0b6605d" - "212bed1e6723b93406ad30e86829a5c7" - "19b890b389306dc5506486ee2f36a8df" - "e0a96af678c9cbd6aff397ca200e3edc" - "1e36bd2f08b31d540c0cb282a9559e4a" - "dd4fc9e6492eed0ccbd3a6982e5faa2d" - "dd17be47417c80b4e5452d31f72401a0" - "42325109544d954c01939079d409a5c3" - "78d7512dfc2d2a71efcc3432a765d1c6" - "a52cfce899cd79b15b4fc3723641ef6b" - "d00acc10407e5df58dd1c3c5c559a506"); - TestSignature(kSign_PKCS1_Block1, message, signature); -} - -// This class is for testing the generic crypto functionality. -class OEMCryptoGenericCryptoTest : public OEMCryptoRefreshTest { - protected: - // buffer_size_ must be a multiple of encryption block size, 16. We'll use a - // reasonable number of blocks for most of the tests. - OEMCryptoGenericCryptoTest() : buffer_size_(160) {} - - void SetUp() override { - OEMCryptoRefreshTest::SetUp(); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE( - license_messages_.CreateResponseWithGenericCryptoKeys()); - InitializeClearBuffer(); - } - - void InitializeClearBuffer() { - clear_buffer_.assign(buffer_size_, 0); - for (size_t i = 0; i < clear_buffer_.size(); i++) { - clear_buffer_[i] = 1 + i % 250; - } - for (size_t i = 0; i < wvoec::KEY_IV_SIZE; i++) { - iv_[i] = i; - } - } - - void ResizeBuffer(size_t new_size) { - buffer_size_ = new_size; - InitializeClearBuffer(); // Re-initialize the clear buffer. - } - - void EncryptAndLoadKeys() { - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - } - - // Encrypt the buffer with the specified key made in - // CreateResponseWithGenericCryptoKeys. - void EncryptBuffer(unsigned int key_index, const vector& in_buffer, - vector* out_buffer) { - EncryptBufferWithKey(session_.license().keys[key_index].key_data, in_buffer, - out_buffer); - } - // Encrypt the buffer with the specified key. - void EncryptBufferWithKey(const uint8_t* key_data, - const vector& in_buffer, - vector* out_buffer) { - AES_KEY aes_key; - ASSERT_EQ(0, AES_set_encrypt_key(key_data, AES_BLOCK_SIZE * 8, &aes_key)); - uint8_t iv_buffer[wvoec::KEY_IV_SIZE]; - memcpy(iv_buffer, iv_, wvoec::KEY_IV_SIZE); - out_buffer->resize(in_buffer.size()); - ASSERT_GT(in_buffer.size(), 0u); - ASSERT_EQ(0u, in_buffer.size() % AES_BLOCK_SIZE); - AES_cbc_encrypt(in_buffer.data(), out_buffer->data(), in_buffer.size(), - &aes_key, iv_buffer, AES_ENCRYPT); - } - - // Sign the buffer with the specified key made in - // CreateResponseWithGenericCryptoKeys. - void SignBuffer(unsigned int key_index, const vector& in_buffer, - vector* signature) { - SignBufferWithKey(session_.license().keys[key_index].key_data, in_buffer, - signature); - } - - // Sign the buffer with the specified key. - void SignBufferWithKey(const uint8_t* key_data, - const vector& in_buffer, - vector* signature) { - unsigned int md_len = SHA256_DIGEST_LENGTH; - signature->resize(SHA256_DIGEST_LENGTH); - HMAC(EVP_sha256(), key_data, wvoec::MAC_KEY_SIZE, in_buffer.data(), - in_buffer.size(), signature->data(), &md_len); - } - - OEMCryptoResult GenericEncrypt(OEMCrypto_SESSION session, - const uint8_t* clear_buffer, - size_t clear_buffer_length, const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer) { - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generic_encrypt_fuzz_seed_corpus"); - OEMCrypto_Generic_Api_Fuzz fuzzed_structure; - fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; - fuzzed_structure.algorithm = algorithm; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, reinterpret_cast(iv), - wvoec::KEY_IV_SIZE); - AppendSeparator(file_name); - AppendToFile(file_name, reinterpret_cast(clear_buffer), - clear_buffer_length); - } - return OEMCrypto_Generic_Encrypt(session, clear_buffer, clear_buffer_length, - iv, algorithm, out_buffer); - } - - OEMCryptoResult GenericDecrypt(OEMCrypto_SESSION session, - const uint8_t* encrypted_buffer, - size_t encrypted_buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer) { - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generic_decrypt_fuzz_seed_corpus"); - OEMCrypto_Generic_Api_Fuzz fuzzed_structure; - fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; - fuzzed_structure.algorithm = algorithm; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, reinterpret_cast(iv), - wvoec::KEY_IV_SIZE); - AppendSeparator(file_name); - AppendToFile(file_name, reinterpret_cast(encrypted_buffer), - encrypted_buffer_length); - } - return OEMCrypto_Generic_Decrypt(session, encrypted_buffer, - encrypted_buffer_length, iv, algorithm, - out_buffer); - } - - OEMCryptoResult GenericVerify(OEMCrypto_SESSION session, - const uint8_t* clear_buffer, - size_t clear_buffer_length, - OEMCrypto_Algorithm algorithm, - const uint8_t* signature, - size_t signature_length) { - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generic_verify_fuzz_seed_corpus"); - OEMCrypto_Generic_Api_Fuzz fuzzed_structure; - fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; - fuzzed_structure.algorithm = algorithm; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, reinterpret_cast(clear_buffer), - clear_buffer_length); - AppendSeparator(file_name); - AppendToFile(file_name, reinterpret_cast(signature), - signature_length); - } - return OEMCrypto_Generic_Verify(session, clear_buffer, clear_buffer_length, - algorithm, signature, signature_length); - } - - OEMCryptoResult GenericSign(OEMCrypto_SESSION session, - const uint8_t* clear_buffer, - size_t clear_buffer_length, - OEMCrypto_Algorithm algorithm, uint8_t* signature, - size_t* signature_length) { - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_generic_sign_fuzz_seed_corpus"); - OEMCrypto_Generic_Api_Fuzz fuzzed_structure; - fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; - fuzzed_structure.algorithm = algorithm; - // Cipher mode and algorithm. - AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), - sizeof(fuzzed_structure)); - AppendToFile(file_name, reinterpret_cast(clear_buffer), - clear_buffer_length); - } - return OEMCrypto_Generic_Sign(session, clear_buffer, clear_buffer_length, - algorithm, signature, signature_length); - } - - // This asks OEMCrypto to encrypt with the specified key, and expects a - // failure. - void BadEncrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, - size_t buffer_length) { - OEMCryptoResult sts; - vector expected_encrypted; - EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); - sts = OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - vector encrypted(buffer_length); - sts = GenericEncrypt(session_.session_id(), clear_buffer_.data(), - buffer_length, iv_, algorithm, encrypted.data()); - EXPECT_NE(OEMCrypto_SUCCESS, sts); - expected_encrypted.resize(buffer_length); - EXPECT_NE(encrypted, expected_encrypted); - } - - // This asks OEMCrypto to decrypt with the specified key, and expects a - // failure. - void BadDecrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, - size_t buffer_length) { - OEMCryptoResult sts; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - sts = OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - vector resultant(encrypted.size()); - sts = GenericDecrypt(session_.session_id(), encrypted.data(), buffer_length, - iv_, algorithm, resultant.data()); - EXPECT_NE(OEMCrypto_SUCCESS, sts); - EXPECT_NE(clear_buffer_, resultant); - } - - // This asks OEMCrypto to sign with the specified key, and expects a - // failure. - void BadSign(unsigned int key_index, OEMCrypto_Algorithm algorithm) { - OEMCryptoResult sts; - vector expected_signature; - SignBuffer(key_index, clear_buffer_, &expected_signature); - - sts = OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - size_t signature_length = (size_t)SHA256_DIGEST_LENGTH; - vector signature(SHA256_DIGEST_LENGTH); - sts = GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), algorithm, signature.data(), - &signature_length); - EXPECT_NE(OEMCrypto_SUCCESS, sts); - EXPECT_NE(signature, expected_signature); - } - - // This asks OEMCrypto to verify a signature with the specified key, and - // expects a failure. - void BadVerify(unsigned int key_index, OEMCrypto_Algorithm algorithm, - size_t signature_size, bool alter_data) { - OEMCryptoResult sts; - vector signature; - SignBuffer(key_index, clear_buffer_, &signature); - if (alter_data) { - signature[0] ^= 42; - } - if (signature.size() < signature_size) { - signature.resize(signature_size); - } - - sts = OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - sts = GenericVerify(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), algorithm, signature.data(), - signature_size); - EXPECT_NE(OEMCrypto_SUCCESS, sts); - } - - // This must be a multiple of encryption block size. - size_t buffer_size_; - vector clear_buffer_; - vector encrypted_buffer_; - uint8_t iv_[wvoec::KEY_IV_SIZE]; -}; - -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyLoad) { EncryptAndLoadKeys(); } - -// Test that the Generic_Encrypt function works correctly. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncrypt) { - EncryptAndLoadKeys(); - unsigned int key_index = 0; - vector expected_encrypted; - EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector encrypted(clear_buffer_.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericEncrypt(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); - ASSERT_EQ(expected_encrypted, encrypted); -} - -// Test that the Generic_Encrypt function fails when not allowed. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadEncrypt) { - EncryptAndLoadKeys(); - BadEncrypt(0, OEMCrypto_HMAC_SHA256, buffer_size_); - // The buffer size must be a multiple of 16, so subtracting 10 is bad. - BadEncrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_ - 10); - BadEncrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); - BadEncrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); - BadEncrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); -} - -// Test that the Generic_Encrypt works if the input and output buffers are the -// same. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncryptSameBufferAPI12) { - EncryptAndLoadKeys(); - unsigned int key_index = 0; - vector expected_encrypted; - EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - // Input and output are same buffer: - vector buffer = clear_buffer_; - ASSERT_EQ( - OEMCrypto_SUCCESS, - GenericEncrypt(session_.session_id(), buffer.data(), buffer.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); - ASSERT_EQ(expected_encrypted, buffer); -} - -TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemorySelectKeyForHugeKeyIdLength) { - EncryptAndLoadKeys(); - OEMCrypto_SESSION session_id = session_.session_id(); - auto oemcrypto_function = [session_id](size_t key_id_length) { - vector key_id(key_id_length); - return OEMCrypto_SelectKey(session_id, key_id.data(), key_id.size(), - OEMCrypto_CipherMode_CENC); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_P(OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeyEncryptForHugeBuffer) { - EncryptAndLoadKeys(); - unsigned int key_index = 0; - vector expected_encrypted; - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - OEMCrypto_SESSION session_id = session_.session_id(); - auto& iv = iv_; - auto oemcrypto_function = [&session_id, &iv](size_t buffer_length) mutable { - vector buffer(buffer_length); - return OEMCrypto_Generic_Encrypt(session_id, buffer.data(), buffer.size(), - iv, OEMCrypto_AES_CBC_128_NO_PADDING, - buffer.data()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 16, kHugeInputBufferLength, - kCheckStatus); -} - -TEST_P( - OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeyEncryptForHugeBufferWithBufferLengthNotMultipleOf16) { - EncryptAndLoadKeys(); - unsigned int key_index = 0; - vector expected_encrypted; - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - OEMCrypto_SESSION session_id = session_.session_id(); - vector buffer(17); - ASSERT_NO_FATAL_FAILURE(OEMCrypto_Generic_Encrypt( - session_id, buffer.data(), buffer.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); -} - -// Test Generic_Decrypt works correctly. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecrypt) { - EncryptAndLoadKeys(); - unsigned int key_index = 1; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector resultant(encrypted.size()); - ASSERT_EQ( - OEMCrypto_SUCCESS, - GenericDecrypt(session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); - ASSERT_EQ(clear_buffer_, resultant); -} - -TEST_P(OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeyDecryptForHugeBuffer) { - EncryptAndLoadKeys(); - unsigned int key_index = 1; - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - OEMCrypto_SESSION session_id = session_.session_id(); - auto iv = iv_; - auto oemcrypto_function = [&session_id, &iv](size_t buffer_length) { - vector encrypted(buffer_length); - vector resultant(encrypted.size()); - - return OEMCrypto_Generic_Decrypt( - session_id, encrypted.data(), encrypted.size(), iv, - OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); - }; - // API expects length to be multiple of 16. Starting from 16. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 16, kHugeInputBufferLength, - kCheckStatus); -} - -// Test that Generic_Decrypt works correctly when the input and output buffers -// are the same. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecryptSameBufferAPI12) { - EncryptAndLoadKeys(); - unsigned int key_index = 1; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector buffer = encrypted; - ASSERT_EQ( - OEMCrypto_SUCCESS, - GenericDecrypt(session_.session_id(), buffer.data(), buffer.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); - ASSERT_EQ(clear_buffer_, buffer); -} - -// Test that Generic_Decrypt fails to decrypt to an insecure buffer if the key -// requires a secure data path. -TEST_P(OEMCryptoGenericCryptoTest, GenericSecureToClear) { - license_messages_.set_control(wvoec::kControlObserveDataPath | - wvoec::kControlDataPathSecure); - license_messages_.CreateResponseWithGenericCryptoKeys(); - EncryptAndLoadKeys(); - unsigned int key_index = 1; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector resultant(encrypted.size()); - ASSERT_NE( - OEMCrypto_SUCCESS, - GenericDecrypt(session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); - ASSERT_NE(clear_buffer_, resultant); -} - -// Test that the Generic_Decrypt function fails when not allowed. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadDecrypt) { - EncryptAndLoadKeys(); - BadDecrypt(1, OEMCrypto_HMAC_SHA256, buffer_size_); - // The buffer size must be a multiple of 16, so subtracting 10 is bad. - BadDecrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_ - 10); - BadDecrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); - BadDecrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); - BadDecrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, buffer_size_); -} - -TEST_P(OEMCryptoGenericCryptoTest, GenericKeySign) { - EncryptAndLoadKeys(); - unsigned int key_index = 2; - vector expected_signature; - SignBuffer(key_index, clear_buffer_, &expected_signature); - - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - size_t gen_signature_length = 0; - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, nullptr, - &gen_signature_length)); - ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); - vector signature(SHA256_DIGEST_LENGTH); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &gen_signature_length)); - ASSERT_EQ(expected_signature, signature); -} - -TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemoryGenericKeySignForHugeBuffer) { - EncryptAndLoadKeys(); - unsigned int key_index = 2; - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector signature(SHA256_DIGEST_LENGTH); - size_t signature_length = signature.size(); - OEMCrypto_SESSION session_id = session_.session_id(); - auto oemcrypto_function = [&session_id, &signature, - &signature_length](size_t buffer_length) { - vector buffer(buffer_length); - return OEMCrypto_Generic_Sign(session_id, buffer.data(), buffer.size(), - OEMCrypto_HMAC_SHA256, signature.data(), - &signature_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_P(OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeySignForHugeSignatureLength) { - EncryptAndLoadKeys(); - unsigned int key_index = 2; - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - OEMCrypto_SESSION session_id = session_.session_id(); - auto clear_buffer = clear_buffer_; - auto oemcrypto_function = [&session_id, - &clear_buffer](size_t signature_length) { - vector signature(signature_length); - size_t gen_signature_length = signature_length; - return OEMCrypto_Generic_Sign(session_id, clear_buffer.data(), - clear_buffer.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &gen_signature_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// Test that the Generic_Sign function fails when not allowed. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadSign) { - EncryptAndLoadKeys(); - BadSign(0, OEMCrypto_HMAC_SHA256); // Can't sign with encrypt key. - BadSign(1, OEMCrypto_HMAC_SHA256); // Can't sign with decrypt key. - BadSign(3, OEMCrypto_HMAC_SHA256); // Can't sign with verify key. - BadSign(2, OEMCrypto_AES_CBC_128_NO_PADDING); // Bad signing algorithm. -} - -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyVerify) { - EncryptAndLoadKeys(); - unsigned int key_index = 3; - vector signature; - SignBuffer(key_index, clear_buffer_, &signature); - - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericVerify(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature.size())); -} - -TEST_P(OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeyVerifyForHugeBuffer) { - EncryptAndLoadKeys(); - unsigned int key_index = 3; - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - auto oemcrypto_function = [&](size_t buffer_length) { - vector buffer(buffer_length); - vector signature; - SignBuffer(key_index, buffer, &signature); - return GenericVerify(session_.session_id(), buffer.data(), buffer.size(), - OEMCrypto_HMAC_SHA256, signature.data(), - signature.size()); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_P(OEMCryptoGenericCryptoTest, - OEMCryptoMemoryGenericKeyVerifyForHugeSignatureLength) { - EncryptAndLoadKeys(); - unsigned int key_index = 3; - vector signature; - SignBuffer(key_index, clear_buffer_, &signature); - - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - OEMCrypto_SESSION session_id = session_.session_id(); - auto clear_buffer = clear_buffer_; - auto oemcrypto_function = [&session_id, &clear_buffer, - &signature](size_t signature_length) { - return OEMCrypto_Generic_Verify(session_id, clear_buffer.data(), - clear_buffer.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// Test that the Generic_Verify function fails when not allowed. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyBadVerify) { - EncryptAndLoadKeys(); - BadVerify(0, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); - BadVerify(1, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); - BadVerify(2, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); - BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, true); - BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH - 1, false); - BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH + 1, false); - BadVerify(3, OEMCrypto_AES_CBC_128_NO_PADDING, SHA256_DIGEST_LENGTH, false); -} - -// Test Generic_Encrypt with the maximum buffer size. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyEncryptLargeBuffer) { - ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); - EncryptAndLoadKeys(); - unsigned int key_index = 0; - vector expected_encrypted; - EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector encrypted(clear_buffer_.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericEncrypt(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); - ASSERT_EQ(expected_encrypted, encrypted); -} - -// Test Generic_Decrypt with the maximum buffer size. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyDecryptLargeBuffer) { - // Some applications are known to pass in a block that is almost 400k. - ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); - EncryptAndLoadKeys(); - unsigned int key_index = 1; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector resultant(encrypted.size()); - ASSERT_EQ( - OEMCrypto_SUCCESS, - GenericDecrypt(session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); - ASSERT_EQ(clear_buffer_, resultant); -} - -// Test Generic_Sign with the maximum buffer size. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeySignLargeBuffer) { - ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); - EncryptAndLoadKeys(); - unsigned int key_index = 2; - vector expected_signature; - SignBuffer(key_index, clear_buffer_, &expected_signature); - - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - size_t gen_signature_length = 0; - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, nullptr, - &gen_signature_length)); - ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); - vector signature(SHA256_DIGEST_LENGTH); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &gen_signature_length)); - ASSERT_EQ(expected_signature, signature); -} - -// Test Generic_Verify with the maximum buffer size. -TEST_P(OEMCryptoGenericCryptoTest, GenericKeyVerifyLargeBuffer) { - ResizeBuffer(GetResourceValue(kMaxGenericBuffer)); - EncryptAndLoadKeys(); - unsigned int key_index = 3; - vector signature; - SignBuffer(key_index, clear_buffer_, &signature); - - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericVerify(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature.size())); -} - -// Test Generic_Encrypt when the key duration has expired. -TEST_P(OEMCryptoGenericCryptoTest, KeyDurationEncrypt) { - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - license_messages_.CreateResponseWithGenericCryptoKeys(); - EncryptAndLoadKeys(); - vector expected_encrypted; - EncryptBuffer(0, clear_buffer_, &expected_encrypted); - unsigned int key_index = 0; - vector encrypted(clear_buffer_.size()); - - // Should be valid key at the start. - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericEncrypt(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data())); - ASSERT_EQ(expected_encrypted, encrypted); - - wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. - encrypted.assign(clear_buffer_.size(), 0); - OEMCryptoResult status = OEMCrypto_Generic_Encrypt( - session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); - ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); - ASSERT_NE(encrypted, expected_encrypted); - ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(key_index)); -} - -// Test Generic_Decrypt when the key duration has expired. -TEST_P(OEMCryptoGenericCryptoTest, KeyDurationDecrypt) { - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - license_messages_.CreateResponseWithGenericCryptoKeys(); - EncryptAndLoadKeys(); - - // Should be valid key at the start. - unsigned int key_index = 1; - vector encrypted; - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector resultant(encrypted.size()); - ASSERT_EQ( - OEMCrypto_SUCCESS, - GenericDecrypt(session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); - ASSERT_EQ(clear_buffer_, resultant); - - wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. - resultant.assign(encrypted.size(), 0); - OEMCryptoResult status = - GenericDecrypt(session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); - ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); - ASSERT_NE(clear_buffer_, resultant); - ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(key_index)); -} - -// Test Generic_Sign when the key duration has expired. -TEST_P(OEMCryptoGenericCryptoTest, KeyDurationSign) { - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - license_messages_.CreateResponseWithGenericCryptoKeys(); - EncryptAndLoadKeys(); - - unsigned int key_index = 2; - vector expected_signature; - vector signature(SHA256_DIGEST_LENGTH); - size_t signature_length = signature.size(); - SignBuffer(key_index, clear_buffer_, &expected_signature); - - // Should be valid key at the start. - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericSign(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &signature_length)); - ASSERT_EQ(expected_signature, signature); - - wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. - signature.assign(SHA256_DIGEST_LENGTH, 0); - OEMCryptoResult status = GenericSign( - session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, signature.data(), &signature_length); - ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); - ASSERT_NE(expected_signature, signature); - ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(key_index)); -} - -// Test Generic_Verify when the key duration has expired. -TEST_P(OEMCryptoGenericCryptoTest, KeyDurationVerify) { - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - license_messages_.CreateResponseWithGenericCryptoKeys(); - EncryptAndLoadKeys(); - - unsigned int key_index = 3; - vector signature; - SignBuffer(key_index, clear_buffer_, &signature); - - // Should be valid key at the start. - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), - session_.license().keys[key_index].key_id, - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - ASSERT_EQ(OEMCrypto_SUCCESS, - GenericVerify(session_.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature.size())); - - wvutil::TestSleep::Sleep(kLongSleep + kShortSleep); // Should be expired key. - OEMCryptoResult status = OEMCrypto_Generic_Verify( - session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, signature.data(), signature.size()); - ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, status); - ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(key_index)); -} - -const unsigned int kLongKeyId = 2; - -// Test that short key ids are allowed. -class OEMCryptoGenericCryptoKeyIdLengthTest - : public OEMCryptoGenericCryptoTest { - protected: - void SetUp() override { - OEMCryptoGenericCryptoTest::SetUp(); - license_messages_.set_num_keys(5); - license_messages_.set_control(wvoec::kControlAllowDecrypt); - license_messages_.core_response() - .timer_limits.total_playback_duration_seconds = kDuration; - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - SetUniformKeyIdLength(16); // Start with all key ids being 16 bytes. - // But, we are testing that the key ids do not have to have the same length. - // 12 bytes (common key id length). - license_messages_.SetKeyId(0, "123456789012"); - license_messages_.SetKeyId(1, "12345"); // short key id. - // 16 byte key id. (default) - license_messages_.SetKeyId(2, "1234567890123456"); - license_messages_.SetKeyId(3, "12345678901234"); // 14 byte. (uncommon) - license_messages_.SetKeyId(4, "1"); // very short key id. - ASSERT_EQ(2u, kLongKeyId); - ASSERT_NO_FATAL_FAILURE(license_messages_.FillCoreResponseSubstrings()); - } - - // Make all four keys have the same length. - void SetUniformKeyIdLength(size_t key_id_length) { - for (size_t i = 0; i < license_messages_.num_keys(); i++) { - string key_id; - key_id.resize(key_id_length, i + 'a'); - license_messages_.SetKeyId(i, key_id); - } - ASSERT_NO_FATAL_FAILURE(license_messages_.FillCoreResponseSubstrings()); - } - - void TestWithKey(unsigned int key_index) { - ASSERT_LT(key_index, license_messages_.num_keys()); - EncryptAndLoadKeys(); - vector encrypted; - // To make sure OEMCrypto is not expecting the key_id to be zero padded, we - // will create a buffer that is padded with 'Z'. - // Then, we use fill the buffer with the longer of the three keys. If - // OEMCrypto is paying attention to the key id length, it should pick out - // the correct key. - vector key_id_buffer( - session_.license().keys[kLongKeyId].key_id_length + 5, - 'Z'); // Fill a bigger buffer with letter 'Z'. - memcpy(key_id_buffer.data(), session_.license().keys[kLongKeyId].key_id, - session_.license().keys[kLongKeyId].key_id_length); - EncryptBuffer(key_index, clear_buffer_, &encrypted); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(session_.session_id(), key_id_buffer.data(), - session_.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC)); - vector resultant(encrypted.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_Generic_Decrypt( - session_.session_id(), encrypted.data(), encrypted.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); - ASSERT_EQ(clear_buffer_, resultant); - } -}; - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, MediumKeyId) { TestWithKey(0); } - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, ShortKeyId) { TestWithKey(1); } - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, LongKeyId) { TestWithKey(2); } - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, FourteenByteKeyId) { - TestWithKey(3); -} - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, VeryShortKeyId) { - TestWithKey(4); -} - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, UniformShortKeyId) { - SetUniformKeyIdLength(5); - TestWithKey(2); -} - -TEST_P(OEMCryptoGenericCryptoKeyIdLengthTest, UniformLongKeyId) { - SetUniformKeyIdLength(kTestKeyIdMaxLength); - TestWithKey(2); -} - -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoGenericCryptoTest, - Range(kCoreMessagesAPI, kCurrentAPI + 1)); - -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoGenericCryptoKeyIdLengthTest, - Range(kCoreMessagesAPI, kCurrentAPI + 1)); /// @} -/// @addtogroup usage_table +/// @addtogroup cast /// @{ -// Test usage table functionality. -class LicenseWithUsageEntry { - public: - LicenseWithUsageEntry(const std::string& pst = "my_pst") - : session_(), - license_messages_(&session_), - generic_crypto_(false), - time_license_received_(0), - time_first_decrypt_(0), - time_last_decrypt_(0), - active_(true) { - license_messages_.set_pst(pst); - } - - void MakeAndLoadOnline(OEMCryptoSessionTests* test) { - MakeAndLoad(test, - wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired); - } - - // If status in not a nullptr, then creating a new entry is allowed to fail, - // and its error code is stored in status. - void MakeOfflineAndClose(OEMCryptoSessionTests* test, - OEMCryptoResult* status = nullptr) { - MakeAndLoad(test, wvoec::kControlNonceOrEntry, status); - if (status != nullptr && *status != OEMCrypto_SUCCESS) { - ASSERT_NO_FATAL_FAILURE(session_.close()); - return; - } - ASSERT_NO_FATAL_FAILURE( - session_.UpdateUsageEntry(&(test->encrypted_usage_header_))); - ASSERT_NO_FATAL_FAILURE(GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(session_.close()); - } - - // If status in not a nullptr, then creating a new entry is allowed to fail, - // and its error code is stored in status. - void MakeAndLoad(SessionUtil* util, uint32_t control, - OEMCryptoResult* status = nullptr) { - license_messages_.set_control(control); - ASSERT_NO_FATAL_FAILURE(session_.open()); - ASSERT_NO_FATAL_FAILURE(util->InstallTestRSAKey(&session_)); - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - if (generic_crypto_) { - ASSERT_NO_FATAL_FAILURE( - license_messages_.CreateResponseWithGenericCryptoKeys()); - } else { - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - } - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry(status)); - if (status != nullptr && *status != OEMCrypto_SUCCESS) return; - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - time_license_received_ = wvutil::Clock().GetCurrentTime(); - } - - void OpenAndReload(SessionUtil* util) { - ASSERT_NO_FATAL_FAILURE(session_.open()); - ASSERT_NO_FATAL_FAILURE(session_.ReloadUsageEntry()); - ASSERT_NO_FATAL_FAILURE(util->InstallTestRSAKey(&session_)); - ASSERT_NO_FATAL_FAILURE(session_.GenerateDerivedKeysFromSessionKey()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - } - - // Test decrypt, and update the decrypt times for the pst report. - void TestDecryptCTR(bool select_key_first = true, - OEMCryptoResult expected_result = OEMCrypto_SUCCESS) { - session_.TestDecryptCTR(select_key_first, expected_result); - time_last_decrypt_ = wvutil::Clock().GetCurrentTime(); - if (time_first_decrypt_ == 0) time_first_decrypt_ = time_last_decrypt_; - } - - void DeactivateUsageEntry() { - active_ = false; - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_deactivate_usage_entry_fuzz_seed_corpus"); - AppendToFile(file_name, pst().c_str(), pst().length()); - } - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_DeactivateUsageEntry( - session_.session_id(), - reinterpret_cast(pst().c_str()), pst().length())); - } - - void GenerateVerifyReport(OEMCrypto_Usage_Entry_Status status) { - ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst())); - Test_PST_Report expected(pst(), status); - ASSERT_NO_FATAL_FAILURE( - session_.VerifyReport(expected, time_license_received_, - time_first_decrypt_, time_last_decrypt_)); - // The PST report was signed above. Below we verify that the entire message - // that is sent to the server will be signed by the right mac keys. - RenewalRoundTrip renewal_messages(&license_messages_); - renewal_messages.set_is_release(!active_); - ASSERT_NO_FATAL_FAILURE(renewal_messages.SignAndVerifyRequest()); - } - - void ReloadUsageEntry() { - session_.ReloadUsageEntry(); - session_.set_mac_keys(license_messages_.response_data().mac_keys); - } - - const std::string& pst() const { return license_messages_.pst(); } - void set_pst(const std::string& pst) { license_messages_.set_pst(pst); } - LicenseRoundTrip& license_messages() { return license_messages_; } - Session& session() { return session_; } - void set_generic_crypto(bool generic_crypto) { - generic_crypto_ = generic_crypto; - } - - private: - Session session_; - LicenseRoundTrip license_messages_; - bool generic_crypto_; - int64_t time_license_received_; - int64_t time_first_decrypt_; - int64_t time_last_decrypt_; - bool active_; -}; - -class OEMCryptoUsageTableTest : public OEMCryptoGenericCryptoTest { - public: - void SetUp() override { OEMCryptoGenericCryptoTest::SetUp(); } - - virtual void ShutDown() { - ASSERT_NO_FATAL_FAILURE(session_.close()); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate()); - } - - virtual void Restart() { - OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); - EnsureTestKeys(); - ASSERT_NO_FATAL_FAILURE(session_.open()); - } - - void PrintDotsWhileSleep(int64_t total_seconds, int64_t interval_seconds) { - int64_t dot_time = interval_seconds; - int64_t elapsed_time = 0; - const int64_t start_time = wvutil::Clock().GetCurrentTime(); - do { - wvutil::TestSleep::Sleep(1); - elapsed_time = wvutil::Clock().GetCurrentTime() - start_time; - if (elapsed_time >= dot_time) { - cout << "."; - cout.flush(); - dot_time += interval_seconds; - } - } while (elapsed_time < total_seconds); - cout << endl; - } - - OEMCryptoResult LoadUsageTableHeader( - const vector& encrypted_usage_header) { - return OEMCrypto_LoadUsageTableHeader(encrypted_usage_header.data(), - encrypted_usage_header.size()); - } -}; - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryUpdateUsageEntryForHugeHeaderBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - if (buffer_length < encrypted_usage_header_.size()) { - return OEMCrypto_ERROR_SHORT_BUFFER; - } - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - size_t header_buffer_length = 0; - size_t entry_buffer_length = 0; - // Header buffer length varies as generation_numbers size changes on every - // call. Hence, we need to call update usage entry in every loop to get - // latest value of header_buffer_length. - OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, - nullptr, &entry_buffer_length); - vector encrypted_usage_entry(entry_buffer_length); - vector header_buffer(encrypted_usage_header_); - header_buffer.resize(buffer_length); - return OEMCrypto_UpdateUsageEntry( - s.session_id(), header_buffer.data(), &buffer_length, - encrypted_usage_entry.data(), &entry_buffer_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryUpdateUsageEntryForHugeUsageEntryBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - size_t header_buffer_length = 0; - size_t entry_buffer_length = 0; - // Header buffer length varies as generation_numbers size changes on every - // call. Hence, we need to call update usage entry in every loop to get - // latest value of header_buffer_length. - OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, - nullptr, &entry_buffer_length); - vector header_buffer(encrypted_usage_header_); - header_buffer.resize(header_buffer_length); - vector encrypted_usage_entry(buffer_length); - return OEMCrypto_UpdateUsageEntry( - s.session_id(), header_buffer.data(), &header_buffer_length, - encrypted_usage_entry.data(), &buffer_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryDeactivateUsageEntryForHugePstBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - std::string pst("pst"); - pst.resize(buffer_length); - entry.license_messages().set_pst(pst); - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - return OEMCrypto_DeactivateUsageEntry( - s.session_id(), reinterpret_cast(pst.c_str()), - pst.length()); - }; - // The test setup assertions fails if pst length goes beyond kMaxPSTLength. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, kMaxPSTLength, - kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryLoadUsageTableHeaderForHugeHeader) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - if (buffer_length < encrypted_usage_header_.size()) { - return OEMCrypto_ERROR_SHORT_BUFFER; - } - - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - vector header_buffer(encrypted_usage_header_); - header_buffer.resize(buffer_length); - return OEMCrypto_LoadUsageTableHeader(header_buffer.data(), - header_buffer.size()); - }; - // We cannot generate an encrypted usage header of varying length with - // valid signature. Hence irrespective of return status, we call API for - // varying buffer lengths. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, - encrypted_usage_header_.size(), - kHugeInputBufferLength, !kCheckStatus); -} - -TEST_P( - OEMCryptoUsageTableTest, - OEMCryptoMemoryLoadUsageTableHeaderForHugeHeaderStartingHeaderLengthFrom1) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - vector header_buffer(buffer_length); - return OEMCrypto_LoadUsageTableHeader(header_buffer.data(), - header_buffer.size()); - }; - // We cannot generate an encrypted usage header of varying length with - // valid signature. Hence irrespective of return status, we call API for - // varying buffer lengths. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryLoadUsageEntryForHugeUsageEntryBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - Session& s = entry.session(); - // Make first entry 0. - entry.MakeOfflineAndClose(this); - if (buffer_length < s.encrypted_usage_entry().size()) { - return OEMCrypto_ERROR_SHORT_BUFFER; - } - Session s2; - s2.open(); - InstallTestRSAKey(&s2); - vector encrypted_usage_entry(buffer_length); - memcpy(encrypted_usage_entry.data(), s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size()); - const uint32_t usage_entry_number = s.usage_entry_number(); - return OEMCrypto_LoadUsageEntry(s2.session_id(), usage_entry_number, - encrypted_usage_entry.data(), - encrypted_usage_entry.size()); - }; - // We cannot generate an encrypted usage enctry of varying length with - // valid signature. Hence irrespective of return status, we call API for - // varying buffer lengths. - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryLoadUsageEntryForHugeInvalidUsageEntryNumber) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - // Make first entry 0. - entry.MakeOfflineAndClose(this); - Session s; - s.open(); - InstallTestRSAKey(&s); - const uint32_t usage_entry_number = kHugeRandomNumber; - ASSERT_NO_FATAL_FAILURE(OEMCrypto_LoadUsageEntry( - s.session_id(), usage_entry_number, s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); -} - -TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugeReportBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - s.UpdateUsageEntry(&encrypted_usage_header_); - size_t length = 0; - OEMCrypto_ReportUsage(s.session_id(), - reinterpret_cast(entry.pst().c_str()), - entry.pst().length(), nullptr, &length); - if (ShouldGenerateCorpus()) { - const std::string file_name = - GetFileName("oemcrypto_report_usage_fuzz_seed_corpus"); - AppendToFile(file_name, reinterpret_cast(&length), - sizeof(length)); - AppendToFile(file_name, entry.pst().c_str(), entry.pst().length()); - } - vector pst_report_buffer(buffer_length); - return OEMCrypto_ReportUsage( - s.session_id(), reinterpret_cast(entry.pst().c_str()), - entry.pst().length(), pst_report_buffer.data(), &buffer_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugePstBuffer) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - s.UpdateUsageEntry(&encrypted_usage_header_); - size_t length = 0; - OEMCrypto_ReportUsage(s.session_id(), - reinterpret_cast(entry.pst().c_str()), - entry.pst().length(), nullptr, &length); - vector pst_report_buffer(length); - vector pst(buffer_length); - return OEMCrypto_ReportUsage(s.session_id(), pst.data(), pst.size(), - pst_report_buffer.data(), &length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus); -} - -TEST_P(OEMCryptoUsageTableTest, - OEMCryptoMemoryShrinkUsageTableHeaderForHugeHeaderBufferLength) { - if (!wvoec::global_features.usage_table) { - GTEST_SKIP() << "Usage tables are not supported."; - } - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - auto oemcrypto_function = [&](size_t buffer_length) { - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - size_t header_buffer_length = buffer_length; - encrypted_usage_header_.resize(header_buffer_length); - return OEMCrypto_ShrinkUsageTableHeader(1, encrypted_usage_header_.data(), - &header_buffer_length); - }; - TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus); -} - -// Test an online or streaming license with PST. This license requires a valid -// nonce and can only be loaded once. -TEST_P(OEMCryptoUsageTableTest, OnlineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - - // test repeated report generation - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - // Flag the entry as inactive. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // It should report as inactive. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - // Decrypt should fail. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); - // We could call DeactivateUsageEntry multiple times. The state should not - // change. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // It should report as inactive. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); -} - -// Test the usage report when the license is loaded but the keys are never used -// for decryption. -TEST_P(OEMCryptoUsageTableTest, OnlineLicenseUnused) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // No decrypt. We do not use this license. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - // Flag the entry as inactive. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // It should report as inactive. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); - // Decrypt should fail. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); - // We could call DeactivateUsageEntry multiple times. The state should not - // change. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // It should report as inactive. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); -} - -// Test that the usage table has been updated and saved before a report can be -// generated. -TEST_P(OEMCryptoUsageTableTest, ForbidReportWithNoUpdate) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - // Cannot generate a report without first updating the file. - ASSERT_NO_FATAL_FAILURE( - s.GenerateReport(entry.pst(), OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // Now it's OK. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - // Flag the entry as inactive. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - // Cannot generate a report without first updating the file. - ASSERT_NO_FATAL_FAILURE( - s.GenerateReport(entry.pst(), OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE)); - // Decrypt should fail. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// Test an online license with a license renewal. -TEST_P(OEMCryptoUsageTableTest, OnlineLicenseWithRefreshAPI16) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - - RenewalRoundTrip renewal_messages(&entry.license_messages()); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); -} - -// Verify that a streaming license cannot be reloaded. -TEST_P(OEMCryptoUsageTableTest, RepeatOnlineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s.close()); - Session s2; - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s2)); - s2.LoadUsageEntry(s); // Use the same entry. - ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s2)); -} - -// An offline license should not load on the first call if the nonce is bad. -TEST_P(OEMCryptoUsageTableTest, OnlineBadNonce) { - Session s; - LicenseRoundTrip license_messages(&s); - license_messages.set_api_version(license_api_version_); - license_messages.set_control(wvoec::kControlNonceEnabled | - wvoec::kControlNonceRequired); - license_messages.set_pst("my-pst"); - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - for (uint32_t i = 0; i < license_messages.num_keys(); i++) - license_messages.response_data().keys[i].control.nonce ^= 42; - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages.LoadResponse()); -} - -// A license with non-zero replay control bits needs a valid pst. -TEST_P(OEMCryptoUsageTableTest, OnlineEmptyPST) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_api_version(license_api_version_); - license_messages.set_control(wvoec::kControlNonceEnabled | - wvoec::kControlNonceRequired); - // DO NOT SET PST: license_messages.set_pst(pst); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); -} - -// A license with non-zero replay control bits needs a valid pst. -TEST_P(OEMCryptoUsageTableTest, OnlineMissingEntry) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_api_version(license_api_version_); - license_messages.set_control(wvoec::kControlNonceEnabled | - wvoec::kControlNonceRequired); - license_messages.set_pst("my-pst"); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - // ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); -} - -// Sessions should have at most one entry at a time. This tests different -// orderings of CreateNewUsageEntry and LoadUsageEntry calls. -TEST_P(OEMCryptoUsageTableTest, CreateAndLoadMultipleEntriesAPI16) { - // Entry Count: we start each test with an empty header. - uint32_t usage_entry_number; - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - Session& s = entry.session(); - // Make first entry 0. - ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); - - // Load an entry, then try to create a second. - ASSERT_NO_FATAL_FAILURE(s.open()); - // Reload entry 0. - ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); - // Create new entry 1 should fail. - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_CreateNewUsageEntry(entry.session().session_id(), - &usage_entry_number)); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Create an entry, then try to load a second. - Session s2; - ASSERT_NO_FATAL_FAILURE(s2.open()); - // Create entry 1. - ASSERT_NO_FATAL_FAILURE(s2.CreateNewUsageEntry()); - // Try to reload entry 0. - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageEntry(s2.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - ASSERT_NO_FATAL_FAILURE(s2.close()); - - // Reload an entry and a license, then try to load the same entry again. - // This reloads entry 0. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Create an entry, then try to create a second entry. - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(s2.CreateNewUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_CreateNewUsageEntry( - s2.session_id(), &usage_entry_number)); -} - -// An entry can be loaded in only one session at a time. -TEST_P(OEMCryptoUsageTableTest, LoadEntryInMultipleSessions) { - // Entry Count: we start each test with an empty header. - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - Session& s = entry.session(); - // Make first entry 0. - ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); - const uint32_t usage_entry_number = s.usage_entry_number(); - EXPECT_EQ(usage_entry_number, 0u); // Should be only entry in this test. - - // Load an entry, then try to create a second. - ASSERT_NO_FATAL_FAILURE(s.open()); - // Reload entry 0. - ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); - - // Create an entry, then try to load a second. - Session s2; - ASSERT_NO_FATAL_FAILURE(s2.open()); - // Try to load entry 0 into session 2. - ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_LoadUsageEntry(s2.session_id(), usage_entry_number, - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); -} - -// Test generic encrypt when the license uses a PST. -TEST_P(OEMCryptoUsageTableTest, GenericCryptoEncrypt) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.set_generic_crypto(true); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - OEMCryptoResult sts; - unsigned int key_index = 0; - vector expected_encrypted; - EncryptBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, - &expected_encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, - s.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - vector encrypted(clear_buffer_.size()); - sts = OEMCrypto_Generic_Encrypt( - s.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - EXPECT_EQ(expected_encrypted, encrypted); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - encrypted.assign(clear_buffer_.size(), 0); - sts = OEMCrypto_Generic_Encrypt( - s.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); - ASSERT_NE(OEMCrypto_SUCCESS, sts); - EXPECT_NE(encrypted, expected_encrypted); -} - -// Test generic decrypt when the license uses a PST. -TEST_P(OEMCryptoUsageTableTest, GenericCryptoDecrypt) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.set_generic_crypto(true); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - OEMCryptoResult sts; - unsigned int key_index = 1; - vector encrypted; - EncryptBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, - &encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, - s.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - vector resultant(encrypted.size()); - sts = OEMCrypto_Generic_Decrypt( - s.session_id(), encrypted.data(), encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - EXPECT_EQ(clear_buffer_, resultant); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - resultant.assign(encrypted.size(), 0); - sts = OEMCrypto_Generic_Decrypt( - s.session_id(), encrypted.data(), encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); - ASSERT_NE(OEMCrypto_SUCCESS, sts); - EXPECT_NE(clear_buffer_, resultant); -} - -// Test generic sign when the license uses a PST. -TEST_P(OEMCryptoUsageTableTest, GenericCryptoSign) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.set_generic_crypto(true); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - OEMCryptoResult sts; - unsigned int key_index = 2; - vector expected_signature; - SignBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, - &expected_signature); - - sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, - s.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - size_t gen_signature_length = 0; - sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - nullptr, &gen_signature_length); - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); - vector signature(SHA256_DIGEST_LENGTH); - sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &gen_signature_length); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(expected_signature, signature); - - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - signature.assign(SHA256_DIGEST_LENGTH, 0); - gen_signature_length = SHA256_DIGEST_LENGTH; - sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), &gen_signature_length); - ASSERT_NE(OEMCrypto_SUCCESS, sts); - ASSERT_NE(signature, expected_signature); -} - -// Test generic verify when the license uses a PST. -TEST_P(OEMCryptoUsageTableTest, GenericCryptoVerify) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.set_generic_crypto(true); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - OEMCryptoResult sts; - unsigned int key_index = 3; - vector signature; - SignBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, - &signature); - - sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, - s.license().keys[key_index].key_id_length, - OEMCrypto_CipherMode_CENC); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_.data(), - clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - signature.data(), signature.size()); - ASSERT_NE(OEMCrypto_SUCCESS, sts); -} - -// Test that an offline license can be loaded. -TEST_P(OEMCryptoUsageTableTest, OfflineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); -} - -// Test that an offline license can be loaded and that the license can be -// renewed. -TEST_P(OEMCryptoUsageTableTest, OfflineLicenseRefresh) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoad(this, wvoec::kControlNonceOrEntry); - Session& s = entry.session(); - - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - // License renewal message is signed by client and verified by the server. - RenewalRoundTrip renewal_messages(&entry.license_messages()); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); -} - -// Test that an offline license can be reloaded in a new session. -TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); -} - -// Test that an offline license can be reloaded in a new session, and then -// refreshed. -TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicenseWithRefresh) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - RenewalRoundTrip renewal_messages(&entry.license_messages()); - MakeRenewalRequest(&renewal_messages); - LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); -} - -// Verify that we can still reload an offline license after OEMCrypto_Terminate -// and Initialize are called. This is as close to a reboot as we can do in a -// unit test. -TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicenseWithTerminate) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - ShutDown(); // This calls OEMCrypto_Terminate. - Restart(); // This calls OEMCrypto_Initialize. - ASSERT_EQ(OEMCrypto_SUCCESS, LoadUsageTableHeader(encrypted_usage_header_)); - - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); -} - -// If we attempt to load a second license with the same usage entry as the -// first, but it has different mac keys, then the attempt should fail. This is -// how we verify that we are reloading the same license. -TEST_P(OEMCryptoUsageTableTest, BadReloadOfflineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - - // Offline license with new mac keys should fail. - Session s2; - LicenseRoundTrip license_messages2(&s2); - // Copy the response, and then change the mac keys. - license_messages2.response_data() = entry.license_messages().response_data(); - license_messages2.core_response() = entry.license_messages().core_response(); - license_messages2.response_data().mac_keys[7] ^= 42; - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s2)); - // This is a valid license: it is correctly signed. - license_messages2.EncryptAndSignResponse(); - // Load the usage entry should be OK. - ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); - ASSERT_NO_FATAL_FAILURE(s2.close()); - - // Now we go back to the original license response. It should load OK. - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); -} - -// An offline license should not load on the first call if the nonce is bad. -TEST_P(OEMCryptoUsageTableTest, OfflineBadNonce) { - Session s; - LicenseRoundTrip license_messages(&s); - license_messages.set_api_version(license_api_version_); - license_messages.set_control(wvoec::kControlNonceOrEntry); - license_messages.set_pst("my-pst"); - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - for (size_t i = 0; i < license_messages.num_keys(); i++) - license_messages.response_data().keys[i].control.nonce ^= 42; - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages.LoadResponse()); -} - -// An offline license needs a valid pst. -TEST_P(OEMCryptoUsageTableTest, OfflineEmptyPST) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - LicenseRoundTrip license_messages(&s); - license_messages.set_api_version(license_api_version_); - license_messages.set_control(wvoec::kControlNonceOrEntry); - // DO NOT SET PST: license_messages.set_pst(pst); - ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); - ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); -} - -// If we try to reload a license with a different PST, the attempt should fail. -TEST_P(OEMCryptoUsageTableTest, ReloadOfflineWrongPST) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - - Session s2; - LicenseRoundTrip license_messages2(&s2); - license_messages2.response_data() = entry.license_messages().response_data(); - license_messages2.core_response() = entry.license_messages().core_response(); - // Change the middle of the pst. - license_messages2.response_data().pst[3] ^= 'Z'; - ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s2)); - // This is a valid license: it is correctly signed. - license_messages2.EncryptAndSignResponse(); - // Load the usage entry should be OK. - ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); - ASSERT_NE(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); -} - -// Once a license has been deactivated, the keys can no longer be used for -// decryption. However, we can still generate a usage report. -TEST_P(OEMCryptoUsageTableTest, DeactivateOfflineLicense) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - // Reload the offline license. - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR()); // Should be able to decrypt. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. - // After deactivate, should not be able to decrypt. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Offline license can not be reused if it has been deactivated. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s)); - s.close(); - - // But we can still generate a report. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // Sending a release from an offline license that has been deactivate will - // only work if the license server can handle v16 licenses. This is a rare - // condition, so it is OK to break it during the transition months. - entry.license_messages().set_api_version(global_features.api_version); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - // We could call DeactivateUsageEntry multiple times. The state should not - // change. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); -} - -// The usage report should indicate that the keys were never used for -// decryption. -TEST_P(OEMCryptoUsageTableTest, DeactivateOfflineLicenseUnused) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - // No Decrypt. This license is unused. - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. - // After deactivate, should not be able to decrypt. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Offline license can not be reused if it has been deactivated. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s)); - s.close(); - - // But we can still generate a report. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // Sending a release from an offline license that has been deactivate will - // only work if the license server can handle v16 licenses. This is a rare - // condition, so it is OK to break it during the transition months. - entry.license_messages().set_api_version(global_features.api_version); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); - // We could call DeactivateUsageEntry multiple times. The state should not - // change. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); -} - -TEST_P(OEMCryptoUsageTableTest, SecureStop) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s.close()); - // When we generate a secure stop without loading the license first, it - // should assume the server does not support core messages. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - // It should report as inactive. - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); -} - -// Test update usage table fails when passed a null pointer. -TEST_P(OEMCryptoUsageTableTest, UpdateFailsWithNullPtr) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - size_t header_buffer_length = encrypted_usage_header_.size(); - size_t entry_buffer_length = s.encrypted_usage_entry().size(); - vector buffer(entry_buffer_length); - // Now try to pass in null pointers for the buffers. This should fail. - ASSERT_NE( - OEMCrypto_SUCCESS, - OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, - buffer.data(), &entry_buffer_length)); - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_UpdateUsageEntry( - s.session_id(), encrypted_usage_header_.data(), - &header_buffer_length, nullptr, &entry_buffer_length)); -} - -// Class used to test usage table defragmentation. -class OEMCryptoUsageTableDefragTest : public OEMCryptoUsageTableTest { - protected: - void ReloadLicense(LicenseWithUsageEntry* entry) { - Session& s = entry->session(); - ASSERT_NO_FATAL_FAILURE(entry->OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry->TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry->GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(s.close()); - } - - void FailReloadLicense(LicenseWithUsageEntry* entry, - OEMCryptoResult expected_result) { - Session& s = entry->session(); - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_EQ(expected_result, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - - ASSERT_NE(OEMCrypto_SUCCESS, entry->license_messages().LoadResponse()); - ASSERT_NO_FATAL_FAILURE(s.close()); - } - - void ShrinkHeader(uint32_t new_size, - OEMCryptoResult expected_result = OEMCrypto_SUCCESS) { - // We call OEMCrypto_ShrinkUsageTableHeader once with a zero length buffer, - // so that OEMCrypto can tell us how big the buffer should be. - size_t header_buffer_length = 0; - OEMCryptoResult sts = OEMCrypto_ShrinkUsageTableHeader( - new_size, nullptr, &header_buffer_length); - // If we are expecting success, then the first call shall return - // SHORT_BUFFER. However, if we are not expecting success, this first call - // may return either SHORT_BUFFER or the expect error. - if (expected_result == OEMCrypto_SUCCESS) { - ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); - } else if (sts != OEMCrypto_ERROR_SHORT_BUFFER) { - // If we got any thing from the first call, it should be the expected - // error, and we don't need to call a second time. - ASSERT_EQ(expected_result, sts); - return; - } - // If the first call resulted in SHORT_BUFFER, we should resize the buffer - // and try again. - ASSERT_LT(0u, header_buffer_length); - encrypted_usage_header_.resize(header_buffer_length); - sts = OEMCrypto_ShrinkUsageTableHeader( - new_size, encrypted_usage_header_.data(), &header_buffer_length); - // For the second call, we always demand the expected result. - ASSERT_EQ(expected_result, sts); - if (sts == OEMCrypto_SUCCESS) { - encrypted_usage_header_.resize(header_buffer_length); - } - } -}; - -// Verify that usage table entries can be moved around in the table. -TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntries) { - const size_t ENTRY_COUNT = 10; - vector entries(ENTRY_COUNT); - for (size_t i = 0; i < ENTRY_COUNT; i++) { - entries[i].set_pst("pst " + std::to_string(i)); - ASSERT_NO_FATAL_FAILURE(entries[i].MakeOfflineAndClose(this)) - << "On license " << i << " pst=" << entries[i].pst(); - wvutil::TestSleep::SyncFakeClock(); - } - for (size_t i = 0; i < ENTRY_COUNT; i++) { - ASSERT_NO_FATAL_FAILURE(entries[i].OpenAndReload(this)) - << "On license " << i << " pst=" << entries[i].pst(); - ASSERT_NO_FATAL_FAILURE(entries[i].session().close()) - << "On license " << i << " pst=" << entries[i].pst(); - } - // Move 4 to 1. - ASSERT_NO_FATAL_FAILURE( - entries[4].session().MoveUsageEntry(1, &encrypted_usage_header_)); - // Shrink header to 3 entries 0, 1 was 4, 2. - ASSERT_NO_FATAL_FAILURE(ShrinkHeader(3)); - ShutDown(); - Restart(); - ASSERT_EQ(OEMCrypto_SUCCESS, LoadUsageTableHeader(encrypted_usage_header_)); - wvutil::TestSleep::SyncFakeClock(); - ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[0])); - // Now has index 1. - ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[4])); - ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[2])); - // When 4 was moved to 1, it increased the gen. number in the header. - ASSERT_NO_FATAL_FAILURE( - FailReloadLicense(&entries[1], OEMCrypto_ERROR_GENERATION_SKEW)); - // Index 3 is beyond the end of the table. - ASSERT_NO_FATAL_FAILURE( - FailReloadLicense(&entries[3], OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// A usage table entry cannot be moved into an entry where an open session is -// currently using the entry. -TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntriesToOpenSession) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); - // s0 currently open on index 0. Expect this to fail: - ASSERT_NO_FATAL_FAILURE(entry1.session().MoveUsageEntry( - 0, &encrypted_usage_header_, OEMCrypto_ERROR_ENTRY_IN_USE)); -} - -TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntriesToInvalidHugeEntryIndex) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - entry0.session().open(); - entry0.ReloadUsageEntry(); - ASSERT_NO_FATAL_FAILURE( - OEMCrypto_MoveEntry(entry0.session().session_id(), kHugeRandomNumber)); -} - -// The usage table cannot be shrunk if any session is using an entry that would -// be deleted. -TEST_P(OEMCryptoUsageTableDefragTest, ShrinkOverOpenSessions) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); - entry1.session().open(); - ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry()); - // Since s0 and s1 are open, we can't shrink. - ASSERT_NO_FATAL_FAILURE(ShrinkHeader(1, OEMCrypto_ERROR_ENTRY_IN_USE)); - entry1.session().close(); // Can shrink after closing s1, even if s0 is open. - ASSERT_NO_FATAL_FAILURE(ShrinkHeader(1, OEMCrypto_SUCCESS)); -} - -// Verify the usage table size can be increased. -TEST_P(OEMCryptoUsageTableDefragTest, EnlargeHeader) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - - // Can only shrink the header -- not make it bigger. - ASSERT_NO_FATAL_FAILURE(ShrinkHeader(4, OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// A new header can only be created while no entries are in use. -TEST_P(OEMCryptoUsageTableDefragTest, CreateNewHeaderWhileUsingOldOne) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); - const bool kExpectFailure = false; - ASSERT_NO_FATAL_FAILURE(CreateUsageTableHeader(kExpectFailure)); -} - -// Verify that a usage table entry can only be loaded into the correct index of -// the table. -TEST_P(OEMCryptoUsageTableDefragTest, ReloadUsageEntryWrongIndex) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - entry0.MakeOfflineAndClose(this); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - entry1.MakeOfflineAndClose(this); - - entry0.session().set_usage_entry_number(1); - ASSERT_NO_FATAL_FAILURE( - FailReloadLicense(&entry0, OEMCrypto_ERROR_INVALID_SESSION)); -} - -// Verify that a usage table entry cannot be loaded if it has been altered. -TEST_P(OEMCryptoUsageTableDefragTest, ReloadUsageEntryBadData) { - LicenseWithUsageEntry entry; - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - vector data = s.encrypted_usage_entry(); - ASSERT_LT(0UL, data.size()); - data[0] ^= 42; - // Error could be signature or verification error. - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - data.data(), data.size())); -} - -// This verifies we can actually create the required number of usage table -// entries. -TEST_P(OEMCryptoUsageTableDefragTest, ManyUsageEntries) { - // OEMCrypto is required to store at least 300 entries in the usage table - // header, but it is allowed to store more. This test verifies that if we keep - // adding entries, the error indicates a resource limit. It then verifies - // that all of the successful entries are still valid after we throw out the - // last invalid entry. - - // After API 16, we require 300 entries in the usage table. Before API 16, we - // required 200. - const size_t required_capacity = RequiredUsageSize(); - - // We try to make a much large header, and assume there is an error at some - // point. - const size_t attempt_count = required_capacity * 5; - // Count of how many entries we successfully create. - size_t successful_count = 0; - - // These entries have licenses tied to them. - std::vector> entries; - // Store the status of the last attempt to create an entry. - OEMCryptoResult status = OEMCrypto_SUCCESS; - while (successful_count < attempt_count && status == OEMCrypto_SUCCESS) { - wvutil::TestSleep::SyncFakeClock(); - LOGD("Creating license for entry %zu", successful_count); - entries.push_back( - std::unique_ptr(new LicenseWithUsageEntry())); - entries.back()->set_pst("pst " + std::to_string(successful_count)); - ASSERT_NO_FATAL_FAILURE(entries.back()->MakeOfflineAndClose(this, &status)) - << "Failed creating license for entry " << successful_count; - if (status != OEMCrypto_SUCCESS) { - // Remove the failed session. - entries.resize(entries.size() - 1); - break; - } - EXPECT_EQ(entries.back()->session().usage_entry_number(), successful_count); - successful_count++; - // We don't create a license for each entry. For every license, we'll - // create 10 empty entries. - constexpr size_t filler_count = 10; - for (size_t i = 0; i < filler_count; i++) { - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry(&status)) - << "Failed creating entry " << successful_count; - if (status != OEMCrypto_SUCCESS) break; - EXPECT_EQ(s.usage_entry_number(), successful_count); - successful_count++; - } - } - LOGD("successful_count = %zu", successful_count); - if (status != OEMCrypto_SUCCESS) { - // If we failed to create this many entries because of limited resources, - // then the error returned should be insufficient resources. - EXPECT_EQ(OEMCrypto_ERROR_INSUFFICIENT_RESOURCES, status) - << "Failed to create license " << successful_count - << ", with wrong error code."; - } - EXPECT_GE(successful_count, required_capacity); - wvutil::TestSleep::SyncFakeClock(); - // Shrink the table a little. - constexpr size_t small_number = 5; - size_t smaller_size = successful_count - small_number; - ASSERT_NO_FATAL_FAILURE(ShrinkHeader(static_cast(smaller_size))); - // Throw out the last license if it was in the part of the table that was - // shrunk. - if (entries.back()->session().usage_entry_number() >= smaller_size) { - entries.pop_back(); - } - // Create a few more license - for (size_t i = 0; i < small_number; i++) { - wvutil::TestSleep::SyncFakeClock(); - entries.push_back( - std::unique_ptr(new LicenseWithUsageEntry())); - entries.back()->set_pst("new pst " + std::to_string(smaller_size + i)); - entries.back()->MakeOfflineAndClose(this); - } - // Make sure that all of the licenses can be reloaded. - for (size_t i = 0; i < entries.size(); i++) { - wvutil::TestSleep::SyncFakeClock(); - Session& s = entries[i]->session(); - ASSERT_NO_FATAL_FAILURE(entries[i]->OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entries[i]->GenerateVerifyReport(kUnused)); - ASSERT_NO_FATAL_FAILURE(entries[i]->TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entries[i]->GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(s.close()); - } -} - -// Verify that usage entries can be created in the position of existing entry -// indexes. -TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryAPI17) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); - const uint32_t number = entry0.session().usage_entry_number(); - entry0.session().close(); - entry1.session().open(); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number)); -} - -// Verify that usage entries cannot replace an entry that is currently in -// use by a session. -TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryIndexInUseAPI17) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); - const uint32_t number = entry0.session().usage_entry_number(); - entry1.session().open(); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number)); -} - -// Verify that usage entries cannot be created if the usage entry index is -// too large. -TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryWithInvalidIndexAPI17) { - LicenseWithUsageEntry entry0; - entry0.set_pst("pst 0"); - LicenseWithUsageEntry entry1; - entry1.set_pst("pst 1"); - - entry0.session().open(); - ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); - const uint32_t number = entry0.session().usage_entry_number(); - entry0.session().close(); - entry1.session().open(); - ASSERT_EQ( - OEMCrypto_ERROR_UNKNOWN_FAILURE, - OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number + 42)); -} - -// Verify that usage entries cannot be created if the session already has an -// entry. -TEST_P(OEMCryptoUsageTableDefragTest, - ReuseUsageEntrySessionAlreadyHasEntryAPI17) { - LicenseWithUsageEntry entry; - entry.set_pst("pst 0"); - - // Create 5 entries in the table. - for (int i = 0; i < 5; i++) { - entry.session().open(); - ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); - entry.session().close(); - } - entry.session().open(); - ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); - const uint32_t number = entry.session().usage_entry_number(); - ASSERT_EQ( - OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES, - OEMCrypto_ReuseUsageEntry(entry.session().session_id(), number - 3)); -} - -// This verifies that the usage table header can be loaded if the generation -// number is off by one, but not off by two. -TEST_P(OEMCryptoUsageTableTest, ReloadUsageTableWithSkew) { - // This also tests a few other error conditions with usage table headers. - LicenseWithUsageEntry entry; - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - - // Reload the license, and save the header. - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - vector old_usage_header_2_ = encrypted_usage_header_; - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - vector old_usage_header_1_ = encrypted_usage_header_; - vector old_usage_entry_1 = s.encrypted_usage_entry(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s.close()); - - ShutDown(); - Restart(); - // Null pointer generates error. - ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadUsageTableHeader( - nullptr, old_usage_header_2_.size())); - ASSERT_NO_FATAL_FAILURE(s.open()); - // Cannot load an entry if header didn't load. - ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Modified header generates error. - vector bad_header = encrypted_usage_header_; - bad_header[3] ^= 42; - ASSERT_NE(OEMCrypto_SUCCESS, LoadUsageTableHeader(bad_header)); - ASSERT_NO_FATAL_FAILURE(s.open()); - // Cannot load an entry if header didn't load. - ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Old by 2 generation numbers is error. - ASSERT_EQ(OEMCrypto_ERROR_GENERATION_SKEW, - LoadUsageTableHeader(old_usage_header_2_)); - ASSERT_NO_FATAL_FAILURE(s.open()); - // Cannot load an entry if header didn't load. - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - s.encrypted_usage_entry().data(), - s.encrypted_usage_entry().size())); - ASSERT_NO_FATAL_FAILURE(s.close()); - - // Old by 1 generation numbers is just warning. - ASSERT_EQ(OEMCrypto_WARNING_GENERATION_SKEW, - LoadUsageTableHeader(old_usage_header_1_)); - // Everything else should still work. The old entry goes with the old header. - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - old_usage_entry_1.data(), - old_usage_entry_1.size())); - ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s)); - ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey()); - ASSERT_EQ(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse()); -} - -TEST_P(OEMCryptoUsageTableTest, LoadAndReloadEntries) { - constexpr size_t kEntryCount = 10; - std::vector entries(kEntryCount); - - for (LicenseWithUsageEntry& entry : entries) { - entry.license_messages().set_api_version(license_api_version_); - } - - for (size_t i = 0; i < kEntryCount; ++i) { - const std::string create_description = - "Creating entry #" + std::to_string(i); - // Create and update a new entry. - LicenseWithUsageEntry& new_entry = entries[i]; - ASSERT_NO_FATAL_FAILURE(new_entry.MakeOfflineAndClose(this)) - << create_description; - // Reload all entries, starting with the most recently created. - for (size_t j = 0; j <= i; ++j) { - const std::string reload_description = - "Reloading entry #" + std::to_string(i - j) + - ", after creating entry #" + std::to_string(i); - LicenseWithUsageEntry& old_entry = entries[i - j]; - ASSERT_NO_FATAL_FAILURE(old_entry.session().open()); - ASSERT_NO_FATAL_FAILURE(old_entry.ReloadUsageEntry()) - << reload_description; - ASSERT_NO_FATAL_FAILURE( - old_entry.session().UpdateUsageEntry(&encrypted_usage_header_)) - << reload_description; - ASSERT_NO_FATAL_FAILURE(old_entry.session().close()); - } - } -} - -// A usage report with the wrong pst should fail. -TEST_P(OEMCryptoUsageTableTest, GenerateReportWrongPST) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE( - s.GenerateReport("wrong_pst", OEMCrypto_ERROR_WRONG_PST)); -} - -// Test usage table timing. -TEST_P(OEMCryptoUsageTableTest, TimingTest) { - LicenseWithUsageEntry entry1; - entry1.license_messages().set_api_version(license_api_version_); - Session& s1 = entry1.session(); - entry1.set_pst("my_pst_1"); - ASSERT_NO_FATAL_FAILURE(entry1.MakeOfflineAndClose(this)); - - LicenseWithUsageEntry entry2; - entry2.license_messages().set_api_version(license_api_version_); - Session& s2 = entry2.session(); - entry2.set_pst("my_pst_2"); - ASSERT_NO_FATAL_FAILURE(entry2.MakeOfflineAndClose(this)); - - LicenseWithUsageEntry entry3; - entry3.license_messages().set_api_version(license_api_version_); - Session& s3 = entry3.session(); - entry3.set_pst("my_pst_3"); - ASSERT_NO_FATAL_FAILURE(entry3.MakeOfflineAndClose(this)); - - ASSERT_NO_FATAL_FAILURE(entry1.MakeOfflineAndClose(this)); - ASSERT_NO_FATAL_FAILURE(entry2.MakeOfflineAndClose(this)); - ASSERT_NO_FATAL_FAILURE(entry3.MakeOfflineAndClose(this)); - - wvutil::TestSleep::Sleep(kLongSleep); - ASSERT_NO_FATAL_FAILURE(entry1.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - - ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); - - wvutil::TestSleep::Sleep(kLongSleep); - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); - - wvutil::TestSleep::Sleep(kLongSleep); - ASSERT_NO_FATAL_FAILURE(entry1.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s1.close()); - ASSERT_NO_FATAL_FAILURE(s2.close()); - - wvutil::TestSleep::Sleep(kLongSleep); - // This is as close to reboot as we can simulate in code. - ShutDown(); - wvutil::TestSleep::Sleep(kShortSleep); - Restart(); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageTableHeader(encrypted_usage_header_.data(), - encrypted_usage_header_.size())); - - // After a reboot, we should be able to reload keys, and generate reports. - wvutil::TestSleep::Sleep(kLongSleep); - ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s2.close()); - - ASSERT_NO_FATAL_FAILURE(s1.open()); - ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry()); - ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE(entry3.OpenAndReload(this)); - - wvutil::TestSleep::Sleep(kLongSleep); - ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry1.GenerateVerifyReport(kInactiveUsed)); - ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry2.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry3.GenerateVerifyReport(kUnused)); -} - -// Verify the times in the usage report. For performance reasons, we allow the -// times in the usage report to be off by as much as kUsageTimeTolerance, which -// is 10 seconds. This acceptable error is called slop. This test needs to run -// long enough that the reported values are distinct, even after accounting for -// this slop. -TEST_P(OEMCryptoUsageTableTest, VerifyUsageTimes) { - LicenseWithUsageEntry entry; - entry.license_messages().set_api_version(license_api_version_); - entry.MakeAndLoadOnline(this); - Session& s = entry.session(); - - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - - const int64_t kDotIntervalInSeconds = 5; - const int64_t kIdleInSeconds = 20; - const int64_t kPlaybackLoopInSeconds = 2 * 60; - - cout << "This test verifies the elapsed time reported in the usage table " - "for a 2 minute simulated playback." - << endl; - cout << "The total time for this test is about " - << kPlaybackLoopInSeconds + 2 * kIdleInSeconds << " seconds." << endl; - cout << "Wait " << kIdleInSeconds - << " seconds to verify usage table time before playback." << endl; - - PrintDotsWhileSleep(kIdleInSeconds, kDotIntervalInSeconds); - - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); - cout << "Start simulated playback..." << endl; - - int64_t dot_time = kDotIntervalInSeconds; - int64_t playback_time = 0; - const int64_t start_time = wvutil::Clock().GetCurrentTime(); - do { - ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - wvutil::TestSleep::Sleep(kShortSleep); - playback_time = wvutil::Clock().GetCurrentTime() - start_time; - ASSERT_LE(0, playback_time); - if (playback_time >= dot_time) { - cout << "."; - cout.flush(); - dot_time += kDotIntervalInSeconds; - } - } while (playback_time < kPlaybackLoopInSeconds); - cout << "\nSimulated playback time = " << playback_time << " seconds.\n"; - - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - EXPECT_NEAR(s.pst_report().seconds_since_first_decrypt() - - s.pst_report().seconds_since_last_decrypt(), - playback_time, kUsageTableTimeTolerance); - - // We must update the usage entry BEFORE sleeping, not after. - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - - cout << "Wait another " << kIdleInSeconds - << " seconds " - "to verify usage table time since playback ended." - << endl; - PrintDotsWhileSleep(kIdleInSeconds, kDotIntervalInSeconds); - - // At this point, this is what we expect: - // idle playback loop idle - // |-----|-------------------------|-----| - // |<--->| = seconds_since_last_decrypt - // |<----------------------------->| = seconds_since_first_decrypt - // |<------------------------------------| = seconds_since_license_received - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); -} - -// This test class is only used to roll back the wall clock. It is used to -// verify that OEMCrypto's system clock is monotonic. It is should only be run -// on a device that allows an application to set the clock. -class OEMCryptoUsageTableTestWallClock : public OEMCryptoUsageTableTest { - public: - void SetUp() override { OEMCryptoUsageTableTest::SetUp(); } - - void TearDown() override { - wvutil::TestSleep::ResetRollback(); - OEMCryptoUsageTableTest::TearDown(); - } -}; - -// NOTE: This test needs root access since clock_settime messes with the system -// time in order to verify that OEMCrypto protects against rollbacks in usage -// entries. Therefore, this test is filtered if not run as root. -// We don't test roll-forward protection or instances where the user rolls back -// the time to the last decrypt call since this requires hardware-secure clocks -// to guarantee. -// -// This test overlaps two tests in parallel because they each have several -// seconds of sleeping, then we roll the system clock back, and then we sleep -// some more. -// For the first test, we use entry1. The playback duration is 6 short -// intervals. We play for 3, roll the clock back 2, and then play for 3 more. -// We then sleep until after the allowed playback duration and try to play. If -// OEMCrypto allows the rollback, then there is only 5 intervals, which is -// legal. But if OEMCrypto forbids the rollback, then there is 8 intervals of -// playback, which is not legal. -// -// For the second test, we use entry2. The rental duration is 6 short -// intervals. The times are the same as for entry1, except we do not start -// playback for entry2 until the end. - -// clang-format off -// [--][--][--][--][--][--][--] -- playback or rental limit. -// -// Here's what the system clock sees with rollback: -// [--][--][--] 3 short intervals of playback or sleep -// <------> Rollback 2 short intervals. -// [--][--][--] 3 short intervals of playback or sleep -// [--] 1 short intervals of sleep. -// -// Here's what the system clock sees without rollback: -// [--][--][--] 3 short intervals of playback or sleep -// [--][--][--] 3 short intervals of playback or sleep -// [--][--]X 2 short intervals of sleep. -// -// |<---------------------------->| 8 short intervals from license received -// until pst reports generated. -// clang-format on - -TEST_P(OEMCryptoUsageTableTestWallClock, TimeRollbackPrevention) { - cout << "This test temporarily rolls back the system time in order to verify " - << "that the usage report accounts for the change. After the test, it " - << "rolls the clock back forward." << endl; - constexpr int kRollBackTime = kShortSleep * 2; - constexpr int kPlaybackCount = 3; - constexpr int kTotalTime = kShortSleep * 8; - - LicenseWithUsageEntry entry1; - entry1.license_messages() - .core_response() - .timer_limits.total_playback_duration_seconds = 7 * kShortSleep; - entry1.MakeOfflineAndClose(this); - Session& s1 = entry1.session(); - ASSERT_NO_FATAL_FAILURE(entry1.OpenAndReload(this)); - - LicenseWithUsageEntry entry2; - entry2.license_messages() - .core_response() - .timer_limits.rental_duration_seconds = 7 * kShortSleep; - entry2.MakeOfflineAndClose(this); - Session& s2 = entry2.session(); - ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); - - // Start with three short intervals of playback for entry1. - for (int i = 0; i < kPlaybackCount; i++) { - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - wvutil::TestSleep::Sleep(kShortSleep); - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - } - - cout << "Rolling the system time back..." << endl; - ASSERT_TRUE(wvutil::TestSleep::RollbackSystemTime(kRollBackTime)); - - // Three more short intervals of playback after the rollback. - for (int i = 0; i < kPlaybackCount; i++) { - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - wvutil::TestSleep::Sleep(kShortSleep); - ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); - } - - // One short interval of sleep to push us past the 6 interval duration. - wvutil::TestSleep::Sleep(2 * kShortSleep); - - // Should not be able to continue playback in entry1. - ASSERT_NO_FATAL_FAILURE( - entry1.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); - // Should not be able to start playback in entry2. - ASSERT_NO_FATAL_FAILURE( - entry2.TestDecryptCTR(true, OEMCrypto_ERROR_KEY_EXPIRED)); - - // Now we look at the usage reports: - ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); - - ASSERT_NO_FATAL_FAILURE(s1.GenerateReport(entry1.pst())); - wvutil::Unpacked_PST_Report report1 = s1.pst_report(); - EXPECT_EQ(report1.status(), kActive); - EXPECT_GE(report1.seconds_since_license_received(), kTotalTime); - EXPECT_GE(report1.seconds_since_first_decrypt(), kTotalTime); - - ASSERT_NO_FATAL_FAILURE(s2.GenerateReport(entry2.pst())); - wvutil::Unpacked_PST_Report report2 = s2.pst_report(); - EXPECT_EQ(report2.status(), kUnused); - EXPECT_GE(report2.seconds_since_license_received(), kTotalTime); -} - -// Verify that a large PST can be used with usage table entries. -TEST_P(OEMCryptoUsageTableTest, PSTLargeBuffer) { - std::string pst(kMaxPSTLength, 'a'); // A large PST. - LicenseWithUsageEntry entry(pst); - entry.MakeOfflineAndClose(this); - Session& s = entry.session(); - - ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR()); // Should be able to decrypt. - ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. - // After deactivate, should not be able to decrypt. - ASSERT_NO_FATAL_FAILURE( - entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); - ASSERT_NO_FATAL_FAILURE(s.close()); -} - -// Verify that a usage entry with an invalid session cannot be used. -TEST_P(OEMCryptoUsageTableTest, UsageEntryWithInvalidSession) { - std::string pst("pst"); - LicenseWithUsageEntry entry; - entry.license_messages().set_pst(pst); - - entry.session().open(); - ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); - entry.session().close(); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_DeactivateUsageEntry( - entry.session().session_id(), - reinterpret_cast(pst.c_str()), pst.length())); - - entry.session().open(); - ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); - entry.session().close(); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_MoveEntry(entry.session().session_id(), 0)); -} - -// Verify that a usage entry with an invalid session cannot be used. -TEST_P(OEMCryptoUsageTableTest, ReuseUsageEntryWithInvalidSessionAPI17) { - std::string pst("pst"); - LicenseWithUsageEntry entry; - entry.license_messages().set_pst(pst); - - entry.session().open(); - ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); - entry.session().close(); - ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_ReuseUsageEntry(entry.session().session_id(), 0)); -} - -INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoUsageTableTest, - Range(kCoreMessagesAPI, kCurrentAPI + 1)); - -// These tests only work when the license has a core message. -INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableDefragTest, - Values(kCurrentAPI)); - -// These tests only work when the license has a core message. -INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableTestWallClock, - Values(kCurrentAPI)); - /// @} } // namespace wvoec diff --git a/oemcrypto/test/oemcrypto_test_android.cpp b/oemcrypto/test/oemcrypto_test_android.cpp index afaebdc5..4e3ab9b9 100644 --- a/oemcrypto/test/oemcrypto_test_android.cpp +++ b/oemcrypto/test/oemcrypto_test_android.cpp @@ -10,13 +10,14 @@ // On Android, these features are not optional. This set of unit tests // verify that these features are implemented. // -// In the file oemcrypto_test.cpp, the unit tests only verify correct +// In the other oemcrypto test files, the unit tests only verify correct // functionality for functions that are implemented. Android devices must pass -// unit tests in both files. +// unit tests in this file also. #include -#include "oec_test_data.h" #include "OEMCryptoCENC.h" +#include "oec_device_features.h" +#include "oec_test_data.h" namespace wvoec { @@ -26,6 +27,8 @@ class OEMCryptoAndroidLMPTest : public ::testing::Test { void SetUp() override { OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + OEMCrypto_SetMaxAPIVersion(kCurrentAPI); + OEMCrypto_EnterTestMode(); } void TearDown() override { OEMCrypto_Terminate(); } @@ -69,18 +72,18 @@ TEST_F(OEMCryptoAndroidLMPTest, RewrapDeviceRSAKeyImplemented) { TEST_F(OEMCryptoAndroidLMPTest, GenericCryptoImplemented) { ASSERT_NE( OEMCrypto_ERROR_NOT_IMPLEMENTED, - OEMCrypto_Generic_Encrypt(0, nullptr, 0, nullptr, + OEMCrypto_Generic_Encrypt(nullptr, 0, nullptr, 0, nullptr, OEMCrypto_AES_CBC_128_NO_PADDING, nullptr)); ASSERT_NE( OEMCrypto_ERROR_NOT_IMPLEMENTED, - OEMCrypto_Generic_Decrypt(0, nullptr, 0, nullptr, + OEMCrypto_Generic_Decrypt(nullptr, 0, nullptr, 0, nullptr, OEMCrypto_AES_CBC_128_NO_PADDING, nullptr)); ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED, - OEMCrypto_Generic_Sign(0, nullptr, 0, OEMCrypto_HMAC_SHA256, - nullptr, nullptr)); + OEMCrypto_Generic_Sign(nullptr, 0, nullptr, 0, + OEMCrypto_HMAC_SHA256, nullptr, nullptr)); ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED, - OEMCrypto_Generic_Verify(0, nullptr, 0, OEMCrypto_HMAC_SHA256, - nullptr, 0)); + OEMCrypto_Generic_Verify(nullptr, 0, nullptr, 0, + OEMCrypto_HMAC_SHA256, nullptr, 0)); } // Android requires support of usage table. The usage table is used for Secure @@ -110,9 +113,10 @@ TEST_F(OEMCryptoAndroidMNCTest, MinVersionNumber10) { // If they are not using Provisioning 2.0, then they must use Provisioning 3.0. TEST_F(OEMCryptoAndroidMNCTest, LoadsTestKeyboxImplemented) { if (OEMCrypto_Keybox == OEMCrypto_GetProvisioningMethod()) { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestKeybox( - reinterpret_cast(&kTestKeybox), - sizeof(kTestKeybox))); + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_LoadTestKeybox(reinterpret_cast(&kTestKeybox), + sizeof(kTestKeybox))); } else { // Android should use keybox or provisioning 3.0. ASSERT_EQ(OEMCrypto_OEMCertificate, OEMCrypto_GetProvisioningMethod()); diff --git a/oemcrypto/test/oemcrypto_test_main.cpp b/oemcrypto/test/oemcrypto_test_main.cpp index 8a702cf4..0779b11c 100644 --- a/oemcrypto/test/oemcrypto_test_main.cpp +++ b/oemcrypto/test/oemcrypto_test_main.cpp @@ -46,7 +46,13 @@ int main(int argc, char** argv) { } wvutil::g_cutoff = static_cast(verbosity); wvoec::global_features.Initialize(); - wvoec::global_features.set_cast_receiver(is_cast_receiver); + if (is_cast_receiver) { + // Turn it on if passed in on the command line. Do not turn these tests off + // automtically -- instead, we'll let the caller filter them out if they + // need to. These tests will normally only run if the device claims to + // support being a cast receiver. + wvoec::global_features.set_cast_receiver(is_cast_receiver); + } // Init GTest after device properties has been initialized. ::testing::InitGoogleTest(&argc, argv); // If the user requests --no_filter, we don't change the filter, otherwise, we diff --git a/oemcrypto/test/oemcrypto_unittests.gypi b/oemcrypto/test/oemcrypto_unittests.gypi index c644a755..3ccd422e 100644 --- a/oemcrypto/test/oemcrypto_unittests.gypi +++ b/oemcrypto/test/oemcrypto_unittests.gypi @@ -17,7 +17,15 @@ 'oec_session_util.cpp', 'oemcrypto_corpus_generator_helper.cpp', 'oemcrypto_session_tests_helper.cpp', + 'oemcrypto_basic_test.cpp', + 'oemcrypto_cast_test.cpp', + 'oemcrypto_decrypt_test.cpp', + 'oemcrypto_generic_crypto_test.cpp', + 'oemcrypto_license_test.cpp', + 'oemcrypto_provisioning_test.cpp', + 'oemcrypto_usage_table_test.cpp', 'oemcrypto_test.cpp', + '<(jsmn_dir)/jsmn.c', ], 'conditions': [ ['test_opk_serialization_version=="true"', { @@ -40,6 +48,8 @@ '<(oemcrypto_dir)/test/fuzz_tests', '<(oemcrypto_dir)/odk/include', '<(oemcrypto_dir)/util/include', + '<(json_dir)/single_include', + '<(jsmn_dir)', ], 'defines': [ 'OEMCRYPTO_TESTS', @@ -50,6 +60,17 @@ '<(oemcrypto_dir)/test/ota_keybox_test.cpp', ], }], + ['generate_code_coverage_report=="true"', { + # Include flags to generate source based code coverage reports. + 'cflags': [ + '-fprofile-instr-generate', + '-fcoverage-mapping', + ], + 'ldflags': [ + '-fprofile-instr-generate', + '-fcoverage-mapping', + ], + }], ], 'dependencies': [ '<(oemcrypto_dir)/odk/src/odk.gyp:odk', diff --git a/oemcrypto/test/oemcrypto_usage_table_test.cpp b/oemcrypto/test/oemcrypto_usage_table_test.cpp new file mode 100644 index 00000000..d2ac143f --- /dev/null +++ b/oemcrypto/test/oemcrypto_usage_table_test.cpp @@ -0,0 +1,1703 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// + +#include "oemcrypto_usage_table_test.h" + +using ::testing::Range; +using ::testing::Values; + +namespace wvoec { + +// Test that successive calls to PrepAndSignProvisioningRequest only increase +// the provisioning count in the ODK message +TEST_F(OEMCryptoSessionTests, Provisioning_IncrementCounterAPI18) { + // local struct to hold count values from core message + typedef struct counts { + uint32_t prov; + uint32_t lic; + uint32_t decrypt; + uint64_t mgn; + } counts; + + // prep and sign provisioning2 request, then extract counter values + auto provision2 = [&](counts* c) { + Session s; + ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_); + provisioning_messages.PrepareSession(keybox_); + provisioning_messages.SignAndVerifyRequest(); + c->prov = + provisioning_messages.core_request().counter_info.provisioning_count; + c->lic = provisioning_messages.core_request().counter_info.license_count; + c->decrypt = + provisioning_messages.core_request().counter_info.decrypt_count; + c->mgn = provisioning_messages.core_request() + .counter_info.master_generation_number; + }; + + // prep and sign provisioning4 request, then extract counter values + auto provision4 = [&](counts* c) { + // Same as SessionUtil::CreateProv4OEMKey, but we can't extract counter + // values using that function + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + Provisioning40RoundTrip provisioning_messages(&s); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(true)); + ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey( + provisioning_messages.oem_key_type(), + provisioning_messages.oem_public_key().data(), + provisioning_messages.oem_public_key().size())); + wrapped_oem_key_ = provisioning_messages.wrapped_oem_key(); + oem_public_key_ = provisioning_messages.oem_public_key(); + oem_key_type_ = provisioning_messages.oem_key_type(); + ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest()); + ASSERT_EQ(OEMCrypto_SUCCESS, provisioning_messages.LoadOEMCertResponse()); + c->prov = + provisioning_messages.core_request().counter_info.provisioning_count; + c->lic = provisioning_messages.core_request().counter_info.license_count; + c->decrypt = + provisioning_messages.core_request().counter_info.decrypt_count; + c->mgn = provisioning_messages.core_request() + .counter_info.master_generation_number; + }; + + if (global_features.provisioning_method == OEMCrypto_OEMCertificate || + global_features.provisioning_method == OEMCrypto_DrmCertificate) { + GTEST_SKIP() << "Provisioning method does not increment prov counter"; + } else if (global_features.provisioning_method == OEMCrypto_Keybox) { + counts c1, c2; + provision2(&c1); + provision2(&c2); + + ASSERT_TRUE(c2.prov > c1.prov); + ASSERT_TRUE(c2.lic == c1.lic); + ASSERT_TRUE(c2.decrypt == c1.decrypt); + ASSERT_TRUE(c2.mgn == c1.mgn); + } else if (global_features.provisioning_method == + OEMCrypto_BootCertificateChain) { + counts c1, c2; + provision4(&c1); + provision4(&c2); + + ASSERT_TRUE(c2.prov > c1.prov); + ASSERT_TRUE(c2.lic == c1.lic); + ASSERT_TRUE(c2.decrypt == c1.decrypt); + ASSERT_TRUE(c2.mgn == c1.mgn); + } +} + +// Test that successive calls to PrepAndSignLicenseRequest only increase +// the license count in the ODK message +TEST_F(OEMCryptoSessionTests, License_IncrementCounterAPI18) { + Session s; + s.open(); + LicenseRoundTrip license_messages(&s); + InstallTestDrmKey(&s); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + uint32_t prov_count1 = + license_messages.core_request().counter_info.provisioning_count; + uint32_t lic_count1 = + license_messages.core_request().counter_info.license_count; + uint32_t decrypt_count1 = + license_messages.core_request().counter_info.decrypt_count; + uint64_t master_generation_number1 = + license_messages.core_request().counter_info.master_generation_number; + + Session s2; + s2.open(); + LicenseRoundTrip license_messages2(&s2); + InstallTestDrmKey(&s2); + ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); + uint32_t prov_count2 = + license_messages2.core_request().counter_info.provisioning_count; + uint32_t lic_count2 = + license_messages2.core_request().counter_info.license_count; + uint32_t decrypt_count2 = + license_messages2.core_request().counter_info.decrypt_count; + uint64_t master_generation_number2 = + license_messages2.core_request().counter_info.master_generation_number; + + ASSERT_TRUE(prov_count2 == prov_count1); + ASSERT_TRUE(lic_count2 > lic_count1); + ASSERT_TRUE(decrypt_count2 == decrypt_count1); + ASSERT_TRUE(master_generation_number2 == master_generation_number1); +} + +// Test that the license request includes the master generation number, and that +// it is incremented correctly after usage table modification (save offline +// license) and decrypt. Also test that decrypt count increments. +TEST_F(OEMCryptoSessionTests, MasterGeneration_IncrementCounterAPI18) { + if (!OEMCrypto_SupportsUsageTable()) { + GTEST_SKIP() << "Usage table not supported, so master generation number " + "does not need to be checked."; + } + Session s1; + s1.open(); + LicenseRoundTrip license_messages(&s1); + InstallTestDrmKey(&s1); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + uint32_t prov_count1 = + license_messages.core_request().counter_info.provisioning_count; + uint32_t lic_count1 = + license_messages.core_request().counter_info.license_count; + uint32_t decrypt_count1 = + license_messages.core_request().counter_info.decrypt_count; + uint64_t master_generation_number1 = + license_messages.core_request().counter_info.master_generation_number; + + // do the same as ReloadOfflineLicense to push the master generation number + // up + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(kCurrentAPI); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + + Session s2; + s2.open(); + LicenseRoundTrip license_messages2(&s2); + InstallTestDrmKey(&s2); + ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); + uint32_t prov_count2 = + license_messages2.core_request().counter_info.provisioning_count; + uint32_t lic_count2 = + license_messages2.core_request().counter_info.license_count; + uint32_t decrypt_count2 = + license_messages2.core_request().counter_info.decrypt_count; + uint64_t master_generation_number2 = + license_messages2.core_request().counter_info.master_generation_number; + + ASSERT_TRUE(prov_count2 == prov_count1); + ASSERT_TRUE(lic_count2 > lic_count1); + ASSERT_TRUE(decrypt_count2 > decrypt_count1); + ASSERT_TRUE(master_generation_number2 > master_generation_number1); +} +TEST_P(OEMCryptoUsageTableTest, + OEMCryptoMemoryLoadUsageEntryForHugeInvalidUsageEntryNumber) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + // Make first entry 0. + entry.MakeOfflineAndClose(this); + Session s; + s.open(); + InstallTestDrmKey(&s); + const uint32_t usage_entry_number = kHugeRandomNumber; + ASSERT_NO_FATAL_FAILURE(OEMCrypto_LoadUsageEntry( + s.session_id(), usage_entry_number, s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); +} + +// Test an online or streaming license with PST. This license requires a +// valid nonce and can only be loaded once. +TEST_P(OEMCryptoUsageTableTest, OnlineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + + // test repeated report generation + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + // Flag the entry as inactive. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + // Decrypt should fail. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); +} + +// Test the usage report when the license is loaded but the keys are never +// used for decryption. +TEST_P(OEMCryptoUsageTableTest, OnlineLicenseUnused) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // No decrypt. We do not use this license. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + // Flag the entry as inactive. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); + // Decrypt should fail. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); +} + +// Test that the usage table has been updated and saved before a report can be +// generated. +TEST_P(OEMCryptoUsageTableTest, ForbidReportWithNoUpdate) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + // Cannot generate a report without first updating the file. + ASSERT_NO_FATAL_FAILURE( + s.GenerateReport(entry.pst(), OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // Now it's OK. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + // Flag the entry as inactive. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + // Cannot generate a report without first updating the file. + ASSERT_NO_FATAL_FAILURE( + s.GenerateReport(entry.pst(), OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE)); + // Decrypt should fail. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// Test an online license with a license renewal. +TEST_P(OEMCryptoUsageTableTest, OnlineLicenseWithRefreshAPI16) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + + RenewalRoundTrip renewal_messages(&entry.license_messages()); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); +} + +// Verify that a streaming license cannot be reloaded. +TEST_P(OEMCryptoUsageTableTest, RepeatOnlineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s.close()); + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s2)); + s2.LoadUsageEntry(s); // Use the same entry. + ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s2)); +} + +// An offline license should not load on the first call if the nonce is bad. +TEST_P(OEMCryptoUsageTableTest, OnlineBadNonce) { + Session s; + LicenseRoundTrip license_messages(&s); + license_messages.set_api_version(license_api_version_); + license_messages.set_control(wvoec::kControlNonceEnabled | + wvoec::kControlNonceRequired); + license_messages.set_pst("my-pst"); + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + for (uint32_t i = 0; i < license_messages.num_keys(); i++) + license_messages.response_data().keys[i].control.nonce ^= 42; + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages.LoadResponse()); +} + +// A license with non-zero replay control bits needs a valid pst. +TEST_P(OEMCryptoUsageTableTest, OnlineEmptyPST) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_api_version(license_api_version_); + license_messages.set_control(wvoec::kControlNonceEnabled | + wvoec::kControlNonceRequired); + // DO NOT SET PST: license_messages.set_pst(pst); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); +} + +// A license with non-zero replay control bits needs a valid pst. +TEST_P(OEMCryptoUsageTableTest, OnlineMissingEntry) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_api_version(license_api_version_); + license_messages.set_control(wvoec::kControlNonceEnabled | + wvoec::kControlNonceRequired); + license_messages.set_pst("my-pst"); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + // ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); +} + +// Sessions should have at most one entry at a time. This tests different +// orderings of CreateNewUsageEntry and LoadUsageEntry calls. +TEST_P(OEMCryptoUsageTableTest, CreateAndLoadMultipleEntriesAPI16) { + // Entry Count: we start each test with an empty header. + uint32_t usage_entry_number; + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + Session& s = entry.session(); + // Make first entry 0. + ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); + + // Load an entry, then try to create a second. + ASSERT_NO_FATAL_FAILURE(s.open()); + // Reload entry 0. + ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); + // Create new entry 1 should fail. + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_CreateNewUsageEntry(entry.session().session_id(), + &usage_entry_number)); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Create an entry, then try to load a second. + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + // Create entry 1. + ASSERT_NO_FATAL_FAILURE(s2.CreateNewUsageEntry()); + // Try to reload entry 0. + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageEntry(s2.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + ASSERT_NO_FATAL_FAILURE(s2.close()); + + // Reload an entry and a license, then try to load the same entry again. + // This reloads entry 0. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Create an entry, then try to create a second entry. + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(s2.CreateNewUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_CreateNewUsageEntry( + s2.session_id(), &usage_entry_number)); +} + +// An entry can be loaded in only one session at a time. +TEST_P(OEMCryptoUsageTableTest, LoadEntryInMultipleSessions) { + // Entry Count: we start each test with an empty header. + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + Session& s = entry.session(); + // Make first entry 0. + ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); + const uint32_t usage_entry_number = s.usage_entry_number(); + EXPECT_EQ(usage_entry_number, 0u); // Should be only entry in this test. + + // Load an entry, then try to create a second. + ASSERT_NO_FATAL_FAILURE(s.open()); + // Reload entry 0. + ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); + + // Create an entry, then try to load a second. + Session s2; + ASSERT_NO_FATAL_FAILURE(s2.open()); + // Try to load entry 0 into session 2. + ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_LoadUsageEntry(s2.session_id(), usage_entry_number, + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); +} + +// Test generic encrypt when the license uses a PST. +TEST_P(OEMCryptoUsageTableTest, GenericCryptoEncrypt) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.set_generic_crypto(true); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + OEMCryptoResult sts; + unsigned int key_index = 0; + vector expected_encrypted; + EncryptBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, + &expected_encrypted); + vector key_handle; + sts = + GetKeyHandleIntoVector(s.session_id(), s.license().keys[key_index].key_id, + s.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + vector encrypted(clear_buffer_.size()); + sts = OEMCrypto_Generic_Encrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data()); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + EXPECT_EQ(expected_encrypted, encrypted); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + encrypted.assign(clear_buffer_.size(), 0); + sts = OEMCrypto_Generic_Encrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data()); + ASSERT_NE(OEMCrypto_SUCCESS, sts); + EXPECT_NE(encrypted, expected_encrypted); +} + +// Test generic decrypt when the license uses a PST. +TEST_P(OEMCryptoUsageTableTest, GenericCryptoDecrypt) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.set_generic_crypto(true); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + OEMCryptoResult sts; + unsigned int key_index = 1; + vector encrypted; + EncryptBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, + &encrypted); + vector key_handle; + sts = + GetKeyHandleIntoVector(s.session_id(), s.license().keys[key_index].key_id, + s.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + vector resultant(encrypted.size()); + sts = OEMCrypto_Generic_Decrypt( + key_handle.data(), key_handle.size(), encrypted.data(), encrypted.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + EXPECT_EQ(clear_buffer_, resultant); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + resultant.assign(encrypted.size(), 0); + sts = OEMCrypto_Generic_Decrypt( + key_handle.data(), key_handle.size(), encrypted.data(), encrypted.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); + ASSERT_NE(OEMCrypto_SUCCESS, sts); + EXPECT_NE(clear_buffer_, resultant); +} + +// Test generic sign when the license uses a PST. +TEST_P(OEMCryptoUsageTableTest, GenericCryptoSign) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.set_generic_crypto(true); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + OEMCryptoResult sts; + unsigned int key_index = 2; + vector expected_signature; + SignBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, + &expected_signature); + + vector key_handle; + sts = + GetKeyHandleIntoVector(s.session_id(), s.license().keys[key_index].key_id, + s.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + size_t gen_signature_length = 0; + sts = OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, nullptr, + &gen_signature_length); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); + vector signature(SHA256_DIGEST_LENGTH); + sts = OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + &gen_signature_length); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(expected_signature, signature); + + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + signature.assign(SHA256_DIGEST_LENGTH, 0); + gen_signature_length = SHA256_DIGEST_LENGTH; + sts = OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + &gen_signature_length); + ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_NE(signature, expected_signature); +} + +// Test generic verify when the license uses a PST. +TEST_P(OEMCryptoUsageTableTest, GenericCryptoVerify) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.set_generic_crypto(true); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + OEMCryptoResult sts; + unsigned int key_index = 3; + vector signature; + SignBufferWithKey(s.license().keys[key_index].key_data, clear_buffer_, + &signature); + + vector key_handle; + sts = + GetKeyHandleIntoVector(s.session_id(), s.license().keys[key_index].key_id, + s.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + sts = OEMCrypto_Generic_Verify(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + signature.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + sts = OEMCrypto_Generic_Verify(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), + signature.size()); + ASSERT_NE(OEMCrypto_SUCCESS, sts); +} + +// Test that an offline license can be loaded. +TEST_P(OEMCryptoUsageTableTest, OfflineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this)); +} + +// Test that an offline license can be loaded and that the license can be +// renewed. +TEST_P(OEMCryptoUsageTableTest, OfflineLicenseRefresh) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoad(this, wvoec::kControlNonceOrEntry); + Session& s = entry.session(); + + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + // License renewal message is signed by client and verified by the server. + RenewalRoundTrip renewal_messages(&entry.license_messages()); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); +} + +// Test that an offline license can be reloaded in a new session. +TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); +} + +// Test that an offline license can be reloaded in a new session, and then +// refreshed. +TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicenseWithRefresh) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + RenewalRoundTrip renewal_messages(&entry.license_messages()); + MakeRenewalRequest(&renewal_messages); + LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); +} + +// Verify that we can still reload an offline license after +// OEMCrypto_Terminate and Initialize are called. This is as close to a reboot +// as we can do in a unit test. +TEST_P(OEMCryptoUsageTableTest, ReloadOfflineLicenseWithTerminate) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + ShutDown(); // This calls OEMCrypto_Terminate. + Restart(); // This calls OEMCrypto_Initialize. + ASSERT_EQ(OEMCrypto_SUCCESS, LoadUsageTableHeader(encrypted_usage_header_)); + + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); +} + +// If we attempt to load a second license with the same usage entry as the +// first, but it has different mac keys, then the attempt should fail. This +// is how we verify that we are reloading the same license. +TEST_P(OEMCryptoUsageTableTest, BadReloadOfflineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + + // Offline license with new mac keys should fail. + Session s2; + LicenseRoundTrip license_messages2(&s2); + // Copy the response, and then change the mac keys. + license_messages2.response_data() = entry.license_messages().response_data(); + license_messages2.core_response() = entry.license_messages().core_response(); + license_messages2.response_data().mac_keys[7] ^= 42; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s2)); + // This is a valid license: it is correctly signed. + license_messages2.EncryptAndSignResponse(); + // Load the usage entry should be OK. + ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); + ASSERT_NO_FATAL_FAILURE(s2.close()); + + // Now we go back to the original license response. It should load OK. + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); +} + +// An offline license should not load on the first call if the nonce is bad. +TEST_P(OEMCryptoUsageTableTest, OfflineBadNonce) { + Session s; + LicenseRoundTrip license_messages(&s); + license_messages.set_api_version(license_api_version_); + license_messages.set_control(wvoec::kControlNonceOrEntry); + license_messages.set_pst("my-pst"); + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + for (size_t i = 0; i < license_messages.num_keys(); i++) + license_messages.response_data().keys[i].control.nonce ^= 42; + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, license_messages.LoadResponse()); +} + +// An offline license needs a valid pst. +TEST_P(OEMCryptoUsageTableTest, OfflineEmptyPST) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + LicenseRoundTrip license_messages(&s); + license_messages.set_api_version(license_api_version_); + license_messages.set_control(wvoec::kControlNonceOrEntry); + // DO NOT SET PST: license_messages.set_pst(pst); + ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse()); + ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse()); + ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages.LoadResponse()); +} + +// If we try to reload a license with a different PST, the attempt should +// fail. +TEST_P(OEMCryptoUsageTableTest, ReloadOfflineWrongPST) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + + Session s2; + LicenseRoundTrip license_messages2(&s2); + license_messages2.response_data() = entry.license_messages().response_data(); + license_messages2.core_response() = entry.license_messages().core_response(); + // Change the middle of the pst. + license_messages2.response_data().pst[3] ^= 'Z'; + ASSERT_NO_FATAL_FAILURE(s2.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s2)); + // This is a valid license: it is correctly signed. + license_messages2.EncryptAndSignResponse(); + // Load the usage entry should be OK. + ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); + ASSERT_NE(OEMCrypto_SUCCESS, license_messages2.LoadResponse()); +} + +// Once a license has been deactivated, the keys can no longer be used for +// decryption. However, we can still generate a usage report. +TEST_P(OEMCryptoUsageTableTest, DeactivateOfflineLicense) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + // Reload the offline license. + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR()); // Should be able to decrypt. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. + // After deactivate, should not be able to decrypt. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Offline license can not be reused if it has been deactivated. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s)); + s.close(); + + // But we can still generate a report. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // Sending a release from an offline license that has been deactivate will + // only work if the license server can handle v16 licenses. This is a rare + // condition, so it is OK to break it during the transition months. + entry.license_messages().set_api_version(global_features.api_version); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); +} + +// The usage report should indicate that the keys were never used for +// decryption. +TEST_P(OEMCryptoUsageTableTest, DeactivateOfflineLicenseUnused) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + // No Decrypt. This license is unused. + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. + // After deactivate, should not be able to decrypt. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Offline license can not be reused if it has been deactivated. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_NE(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse(&s)); + s.close(); + + // But we can still generate a report. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // Sending a release from an offline license that has been deactivate will + // only work if the license server can handle v16 licenses. This is a rare + // condition, so it is OK to break it during the transition months. + entry.license_messages().set_api_version(global_features.api_version); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUnused)); +} + +TEST_P(OEMCryptoUsageTableTest, SecureStop) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s.close()); + // When we generate a secure stop without loading the license first, it + // should assume the server does not support core messages. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(entry.ReloadUsageEntry()); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); +} + +// Test update usage table fails when passed a null pointer. +TEST_P(OEMCryptoUsageTableTest, UpdateFailsWithNullPtr) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + size_t header_buffer_length = encrypted_usage_header_.size(); + size_t entry_buffer_length = s.encrypted_usage_entry().size(); + vector buffer(entry_buffer_length); + // Now try to pass in null pointers for the buffers. This should fail. + ASSERT_NE( + OEMCrypto_SUCCESS, + OEMCrypto_UpdateUsageEntry(s.session_id(), nullptr, &header_buffer_length, + buffer.data(), &entry_buffer_length)); + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_UpdateUsageEntry( + s.session_id(), encrypted_usage_header_.data(), + &header_buffer_length, nullptr, &entry_buffer_length)); +} + +// Class used to test usage table defragmentation. +class OEMCryptoUsageTableDefragTest : public OEMCryptoUsageTableTest { + protected: + void ReloadLicense(LicenseWithUsageEntry* entry) { + Session& s = entry->session(); + ASSERT_NO_FATAL_FAILURE(entry->OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry->TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry->GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(s.close()); + } + + void FailReloadLicense(LicenseWithUsageEntry* entry, + OEMCryptoResult expected_result) { + Session& s = entry->session(); + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_EQ(expected_result, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + + ASSERT_NE(OEMCrypto_SUCCESS, entry->license_messages().LoadResponse()); + ASSERT_NO_FATAL_FAILURE(s.close()); + } + + void ShrinkHeader(uint32_t new_size, + OEMCryptoResult expected_result = OEMCrypto_SUCCESS) { + // We call OEMCrypto_ShrinkUsageTableHeader once with a zero length + // buffer, so that OEMCrypto can tell us how big the buffer should be. + size_t header_buffer_length = 0; + OEMCryptoResult sts = OEMCrypto_ShrinkUsageTableHeader( + new_size, nullptr, &header_buffer_length); + // If we are expecting success, then the first call shall return + // SHORT_BUFFER. However, if we are not expecting success, this first call + // may return either SHORT_BUFFER or the expect error. + if (expected_result == OEMCrypto_SUCCESS) { + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); + } else if (sts != OEMCrypto_ERROR_SHORT_BUFFER) { + // If we got any thing from the first call, it should be the expected + // error, and we don't need to call a second time. + ASSERT_EQ(expected_result, sts); + return; + } + // If the first call resulted in SHORT_BUFFER, we should resize the buffer + // and try again. + ASSERT_LT(0u, header_buffer_length); + encrypted_usage_header_.resize(header_buffer_length); + sts = OEMCrypto_ShrinkUsageTableHeader( + new_size, encrypted_usage_header_.data(), &header_buffer_length); + // For the second call, we always demand the expected result. + ASSERT_EQ(expected_result, sts); + if (sts == OEMCrypto_SUCCESS) { + encrypted_usage_header_.resize(header_buffer_length); + } + } +}; + +// Verify that usage table entries can be moved around in the table. +TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntries) { + const size_t ENTRY_COUNT = 10; + vector entries(ENTRY_COUNT); + for (size_t i = 0; i < ENTRY_COUNT; i++) { + entries[i].set_pst("pst " + std::to_string(i)); + ASSERT_NO_FATAL_FAILURE(entries[i].MakeOfflineAndClose(this)) + << "On license " << i << " pst=" << entries[i].pst(); + wvutil::TestSleep::SyncFakeClock(); + } + for (size_t i = 0; i < ENTRY_COUNT; i++) { + ASSERT_NO_FATAL_FAILURE(entries[i].OpenAndReload(this)) + << "On license " << i << " pst=" << entries[i].pst(); + ASSERT_NO_FATAL_FAILURE(entries[i].session().close()) + << "On license " << i << " pst=" << entries[i].pst(); + } + // Move 4 to 1. + ASSERT_NO_FATAL_FAILURE( + entries[4].session().MoveUsageEntry(1, &encrypted_usage_header_)); + // Shrink header to 3 entries 0, 1 was 4, 2. + ASSERT_NO_FATAL_FAILURE(ShrinkHeader(3)); + ShutDown(); + Restart(); + ASSERT_EQ(OEMCrypto_SUCCESS, LoadUsageTableHeader(encrypted_usage_header_)); + wvutil::TestSleep::SyncFakeClock(); + ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[0])); + // Now has index 1. + ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[4])); + ASSERT_NO_FATAL_FAILURE(ReloadLicense(&entries[2])); + // When 4 was moved to 1, it increased the gen. number in the header. + ASSERT_NO_FATAL_FAILURE( + FailReloadLicense(&entries[1], OEMCrypto_ERROR_GENERATION_SKEW)); + // Index 3 is beyond the end of the table. + ASSERT_NO_FATAL_FAILURE( + FailReloadLicense(&entries[3], OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// A usage table entry cannot be moved into an entry where an open session is +// currently using the entry. +TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntriesToOpenSession) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); + // s0 currently open on index 0. Expect this to fail: + ASSERT_NO_FATAL_FAILURE(entry1.session().MoveUsageEntry( + 0, &encrypted_usage_header_, OEMCrypto_ERROR_ENTRY_IN_USE)); +} + +TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntriesToInvalidHugeEntryIndex) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + entry0.session().open(); + entry0.ReloadUsageEntry(); + ASSERT_NO_FATAL_FAILURE( + OEMCrypto_MoveEntry(entry0.session().session_id(), kHugeRandomNumber)); +} + +// The usage table cannot be shrunk if any session is using an entry that +// would be deleted. +TEST_P(OEMCryptoUsageTableDefragTest, ShrinkOverOpenSessions) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); + entry1.session().open(); + ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry()); + // Since s0 and s1 are open, we can't shrink. + ASSERT_NO_FATAL_FAILURE(ShrinkHeader(1, OEMCrypto_ERROR_ENTRY_IN_USE)); + entry1.session().close(); // Can shrink after closing s1, even if s0 is open. + ASSERT_NO_FATAL_FAILURE(ShrinkHeader(1, OEMCrypto_SUCCESS)); +} + +// Verify the usage table size can be increased. +TEST_P(OEMCryptoUsageTableDefragTest, EnlargeHeader) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + + // Can only shrink the header -- not make it bigger. + ASSERT_NO_FATAL_FAILURE(ShrinkHeader(4, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// A new header can only be created while no entries are in use. +TEST_P(OEMCryptoUsageTableDefragTest, CreateNewHeaderWhileUsingOldOne) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.ReloadUsageEntry()); + const bool kExpectFailure = false; + ASSERT_NO_FATAL_FAILURE(CreateUsageTableHeader(kExpectFailure)); +} + +// Verify that a usage table entry can only be loaded into the correct index +// of the table. +TEST_P(OEMCryptoUsageTableDefragTest, ReloadUsageEntryWrongIndex) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + entry0.MakeOfflineAndClose(this); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + entry1.MakeOfflineAndClose(this); + + entry0.session().set_usage_entry_number(1); + ASSERT_NO_FATAL_FAILURE( + FailReloadLicense(&entry0, OEMCrypto_ERROR_INVALID_SESSION)); +} + +// Verify that a usage table entry cannot be loaded if it has been altered. +TEST_P(OEMCryptoUsageTableDefragTest, ReloadUsageEntryBadData) { + LicenseWithUsageEntry entry; + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + vector data = s.encrypted_usage_entry(); + ASSERT_LT(0UL, data.size()); + data[0] ^= 42; + // Error could be signature or verification error. + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + data.data(), data.size())); +} + +// This verifies we can actually create the required number of usage table +// entries. +TEST_P(OEMCryptoUsageTableDefragTest, ManyUsageEntries) { + // OEMCrypto is required to store at least 300 entries in the usage table + // header, but it is allowed to store more. This test verifies that if we + // keep adding entries, the error indicates a resource limit. It then + // verifies that all of the successful entries are still valid after we + // throw out the last invalid entry. + + // After API 16, we require 300 entries in the usage table. Before API 16, + // we required 200. + const size_t required_capacity = RequiredUsageSize(); + + // We try to make a much large header, and assume there is an error at some + // point. + const size_t attempt_count = required_capacity * 5; + // Count of how many entries we successfully create. + size_t successful_count = 0; + + // These entries have licenses tied to them. + std::vector> entries; + // Store the status of the last attempt to create an entry. + OEMCryptoResult status = OEMCrypto_SUCCESS; + while (successful_count < attempt_count && status == OEMCrypto_SUCCESS) { + wvutil::TestSleep::SyncFakeClock(); + LOGD("Creating license for entry %zu", successful_count); + entries.push_back( + std::unique_ptr(new LicenseWithUsageEntry())); + entries.back()->set_pst("pst " + std::to_string(successful_count)); + ASSERT_NO_FATAL_FAILURE(entries.back()->MakeOfflineAndClose(this, &status)) + << "Failed creating license for entry " << successful_count; + if (status != OEMCrypto_SUCCESS) { + // Remove the failed session. + entries.resize(entries.size() - 1); + break; + } + EXPECT_EQ(entries.back()->session().usage_entry_number(), successful_count); + successful_count++; + // We don't create a license for each entry. For every license, we'll + // create 10 empty entries. + constexpr size_t filler_count = 10; + for (size_t i = 0; i < filler_count; i++) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry(&status)) + << "Failed creating entry " << successful_count; + if (status != OEMCrypto_SUCCESS) break; + EXPECT_EQ(s.usage_entry_number(), successful_count); + successful_count++; + } + } + LOGD("successful_count = %zu", successful_count); + if (status != OEMCrypto_SUCCESS) { + // If we failed to create this many entries because of limited resources, + // then the error returned should be insufficient resources. + EXPECT_EQ(OEMCrypto_ERROR_INSUFFICIENT_RESOURCES, status) + << "Failed to create license " << successful_count + << ", with wrong error code."; + } + EXPECT_GE(successful_count, required_capacity); + wvutil::TestSleep::SyncFakeClock(); + // Shrink the table a little. + constexpr size_t small_number = 5; + size_t smaller_size = successful_count - small_number; + ASSERT_NO_FATAL_FAILURE(ShrinkHeader(static_cast(smaller_size))); + // Throw out the last license if it was in the part of the table that was + // shrunk. + if (entries.back()->session().usage_entry_number() >= smaller_size) { + entries.pop_back(); + } + // Create a few more license + for (size_t i = 0; i < small_number; i++) { + wvutil::TestSleep::SyncFakeClock(); + entries.push_back( + std::unique_ptr(new LicenseWithUsageEntry())); + entries.back()->set_pst("new pst " + std::to_string(smaller_size + i)); + entries.back()->MakeOfflineAndClose(this); + } + // Make sure that all of the licenses can be reloaded. + for (size_t i = 0; i < entries.size(); i++) { + wvutil::TestSleep::SyncFakeClock(); + Session& s = entries[i]->session(); + ASSERT_NO_FATAL_FAILURE(entries[i]->OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entries[i]->GenerateVerifyReport(kUnused)); + ASSERT_NO_FATAL_FAILURE(entries[i]->TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entries[i]->GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(s.close()); + } +} + +// Verify that usage entries can be created in the position of existing entry +// indexes. +TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryAPI17) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); + const uint32_t number = entry0.session().usage_entry_number(); + entry0.session().close(); + entry1.session().open(); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number)); +} + +// Verify that usage entries cannot replace an entry that is currently in +// use by a session. +TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryIndexInUseAPI17) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); + const uint32_t number = entry0.session().usage_entry_number(); + entry1.session().open(); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number)); +} + +// Verify that usage entries cannot be created if the usage entry index is +// too large. +TEST_P(OEMCryptoUsageTableDefragTest, ReuseUsageEntryWithInvalidIndexAPI17) { + LicenseWithUsageEntry entry0; + entry0.set_pst("pst 0"); + LicenseWithUsageEntry entry1; + entry1.set_pst("pst 1"); + + entry0.session().open(); + ASSERT_NO_FATAL_FAILURE(entry0.session().CreateNewUsageEntry()); + const uint32_t number = entry0.session().usage_entry_number(); + entry0.session().close(); + entry1.session().open(); + ASSERT_EQ( + OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_ReuseUsageEntry(entry1.session().session_id(), number + 42)); +} + +// Verify that usage entries cannot be created if the session already has an +// entry. +TEST_P(OEMCryptoUsageTableDefragTest, + ReuseUsageEntrySessionAlreadyHasEntryAPI17) { + LicenseWithUsageEntry entry; + entry.set_pst("pst 0"); + + // Create 5 entries in the table. + for (int i = 0; i < 5; i++) { + entry.session().open(); + ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); + entry.session().close(); + } + entry.session().open(); + ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); + const uint32_t number = entry.session().usage_entry_number(); + ASSERT_EQ( + OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES, + OEMCrypto_ReuseUsageEntry(entry.session().session_id(), number - 3)); +} + +// This verifies that the usage table header can be loaded if the generation +// number is off by one, but not off by two. +TEST_P(OEMCryptoUsageTableTest, ReloadUsageTableWithSkew) { + // This also tests a few other error conditions with usage table headers. + LicenseWithUsageEntry entry; + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + + // Reload the license, and save the header. + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + vector old_usage_header_2_ = encrypted_usage_header_; + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + vector old_usage_header_1_ = encrypted_usage_header_; + vector old_usage_entry_1 = s.encrypted_usage_entry(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s.close()); + + ShutDown(); + Restart(); + // Null pointer generates error. + ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadUsageTableHeader( + nullptr, old_usage_header_2_.size())); + ASSERT_NO_FATAL_FAILURE(s.open()); + // Cannot load an entry if header didn't load. + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Modified header generates error. + vector bad_header = encrypted_usage_header_; + bad_header[3] ^= 42; + ASSERT_NE(OEMCrypto_SUCCESS, LoadUsageTableHeader(bad_header)); + ASSERT_NO_FATAL_FAILURE(s.open()); + // Cannot load an entry if header didn't load. + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Old by 2 generation numbers is error. + ASSERT_EQ(OEMCrypto_ERROR_GENERATION_SKEW, + LoadUsageTableHeader(old_usage_header_2_)); + ASSERT_NO_FATAL_FAILURE(s.open()); + // Cannot load an entry if header didn't load. + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + s.encrypted_usage_entry().data(), + s.encrypted_usage_entry().size())); + ASSERT_NO_FATAL_FAILURE(s.close()); + + // Old by 1 generation numbers is just warning. + ASSERT_EQ(OEMCrypto_WARNING_GENERATION_SKEW, + LoadUsageTableHeader(old_usage_header_1_)); + // Everything else should still work. The old entry goes with the old + // header. + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), + old_usage_entry_1.data(), + old_usage_entry_1.size())); + ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&s)); + ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey()); + ASSERT_EQ(OEMCrypto_SUCCESS, entry.license_messages().LoadResponse()); +} + +TEST_P(OEMCryptoUsageTableTest, LoadAndReloadEntries) { + constexpr size_t kEntryCount = 10; + std::vector entries(kEntryCount); + + for (LicenseWithUsageEntry& entry : entries) { + entry.license_messages().set_api_version(license_api_version_); + } + + for (size_t i = 0; i < kEntryCount; ++i) { + const std::string create_description = + "Creating entry #" + std::to_string(i); + // Create and update a new entry. + LicenseWithUsageEntry& new_entry = entries[i]; + ASSERT_NO_FATAL_FAILURE(new_entry.MakeOfflineAndClose(this)) + << create_description; + // Reload all entries, starting with the most recently created. + for (size_t j = 0; j <= i; ++j) { + const std::string reload_description = + "Reloading entry #" + std::to_string(i - j) + + ", after creating entry #" + std::to_string(i); + LicenseWithUsageEntry& old_entry = entries[i - j]; + ASSERT_NO_FATAL_FAILURE(old_entry.session().open()); + ASSERT_NO_FATAL_FAILURE(old_entry.ReloadUsageEntry()) + << reload_description; + ASSERT_NO_FATAL_FAILURE( + old_entry.session().UpdateUsageEntry(&encrypted_usage_header_)) + << reload_description; + ASSERT_NO_FATAL_FAILURE(old_entry.session().close()); + } + } +} + +// A usage report with the wrong pst should fail. +TEST_P(OEMCryptoUsageTableTest, GenerateReportWrongPST) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE( + s.GenerateReport("wrong_pst", OEMCrypto_ERROR_WRONG_PST)); +} + +// Test usage table timing. +TEST_P(OEMCryptoUsageTableTest, TimingTest) { + LicenseWithUsageEntry entry1; + entry1.license_messages().set_api_version(license_api_version_); + Session& s1 = entry1.session(); + entry1.set_pst("my_pst_1"); + ASSERT_NO_FATAL_FAILURE(entry1.MakeOfflineAndClose(this)); + + LicenseWithUsageEntry entry2; + entry2.license_messages().set_api_version(license_api_version_); + Session& s2 = entry2.session(); + entry2.set_pst("my_pst_2"); + ASSERT_NO_FATAL_FAILURE(entry2.MakeOfflineAndClose(this)); + + LicenseWithUsageEntry entry3; + entry3.license_messages().set_api_version(license_api_version_); + Session& s3 = entry3.session(); + entry3.set_pst("my_pst_3"); + ASSERT_NO_FATAL_FAILURE(entry3.MakeOfflineAndClose(this)); + + ASSERT_NO_FATAL_FAILURE(entry1.MakeOfflineAndClose(this)); + ASSERT_NO_FATAL_FAILURE(entry2.MakeOfflineAndClose(this)); + ASSERT_NO_FATAL_FAILURE(entry3.MakeOfflineAndClose(this)); + + wvutil::TestSleep::Sleep(kLongSleep); + ASSERT_NO_FATAL_FAILURE(entry1.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + + ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); + + wvutil::TestSleep::Sleep(kLongSleep); + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); + + wvutil::TestSleep::Sleep(kLongSleep); + ASSERT_NO_FATAL_FAILURE(entry1.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s1.close()); + ASSERT_NO_FATAL_FAILURE(s2.close()); + + wvutil::TestSleep::Sleep(kLongSleep); + // This is as close to reboot as we can simulate in code. + ShutDown(); + wvutil::TestSleep::Sleep(kShortSleep); + Restart(); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadUsageTableHeader(encrypted_usage_header_.data(), + encrypted_usage_header_.size())); + + // After a reboot, we should be able to reload keys, and generate reports. + wvutil::TestSleep::Sleep(kLongSleep); + ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(entry2.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s2.close()); + + ASSERT_NO_FATAL_FAILURE(s1.open()); + ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry()); + ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE(entry3.OpenAndReload(this)); + + wvutil::TestSleep::Sleep(kLongSleep); + ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry1.GenerateVerifyReport(kInactiveUsed)); + ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry2.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry3.GenerateVerifyReport(kUnused)); +} + +// Verify the times in the usage report. For performance reasons, we allow +// the times in the usage report to be off by as much as kUsageTimeTolerance, +// which is 10 seconds. This acceptable error is called slop. This test needs +// to run long enough that the reported values are distinct, even after +// accounting for this slop. +TEST_P(OEMCryptoUsageTableTest, VerifyUsageTimes) { + LicenseWithUsageEntry entry; + entry.license_messages().set_api_version(license_api_version_); + entry.MakeAndLoadOnline(this); + Session& s = entry.session(); + + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + + const int64_t kDotIntervalInSeconds = 5; + const int64_t kIdleInSeconds = 20; + const int64_t kPlaybackLoopInSeconds = 2 * 60; + + cout << "This test verifies the elapsed time reported in the usage table " + "for a 2 minute simulated playback." + << endl; + cout << "The total time for this test is about " + << kPlaybackLoopInSeconds + 2 * kIdleInSeconds << " seconds." << endl; + cout << "Wait " << kIdleInSeconds + << " seconds to verify usage table time before playback." << endl; + + PrintDotsWhileSleep(kIdleInSeconds, kDotIntervalInSeconds); + + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kUnused)); + cout << "Start simulated playback..." << endl; + + int64_t dot_time = kDotIntervalInSeconds; + int64_t playback_time = 0; + const int64_t start_time = wvutil::Clock().GetCurrentTime(); + do { + ASSERT_NO_FATAL_FAILURE(entry.TestDecryptCTR()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + wvutil::TestSleep::Sleep(kShortSleep); + playback_time = wvutil::Clock().GetCurrentTime() - start_time; + ASSERT_LE(0, playback_time); + if (playback_time >= dot_time) { + cout << "."; + cout.flush(); + dot_time += kDotIntervalInSeconds; + } + } while (playback_time < kPlaybackLoopInSeconds); + cout << "\nSimulated playback time = " << playback_time << " seconds.\n"; + + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + EXPECT_NEAR(s.pst_report().seconds_since_first_decrypt() - + s.pst_report().seconds_since_last_decrypt(), + playback_time, kUsageTableTimeTolerance); + + // We must update the usage entry BEFORE sleeping, not after. + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + + cout << "Wait another " << kIdleInSeconds + << " seconds " + "to verify usage table time since playback ended." + << endl; + PrintDotsWhileSleep(kIdleInSeconds, kDotIntervalInSeconds); + + // At this point, this is what we expect: + // idle playback loop idle + // |-----|-------------------------|-----| + // |<--->| = seconds_since_last_decrypt + // |<----------------------------->| = seconds_since_first_decrypt + // |<------------------------------------| = seconds_since_license_received + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); +} + +// This test class is only used to roll back the wall clock. It is used to +// verify that OEMCrypto's system clock is monotonic. It is should only be +// run on a device that allows an application to set the clock. +class OEMCryptoUsageTableTestWallClock : public OEMCryptoUsageTableTest { + public: + void SetUp() override { OEMCryptoUsageTableTest::SetUp(); } + + void TearDown() override { + wvutil::TestSleep::ResetRollback(); + OEMCryptoUsageTableTest::TearDown(); + } +}; + +// NOTE: This test needs root access since clock_settime messes with the +// system time in order to verify that OEMCrypto protects against rollbacks in +// usage entries. Therefore, this test is filtered if not run as root. We +// don't test roll-forward protection or instances where the user rolls back +// the time to the last decrypt call since this requires hardware-secure +// clocks to guarantee. +// +// This test overlaps two tests in parallel because they each have several +// seconds of sleeping, then we roll the system clock back, and then we sleep +// some more. +// For the first test, we use entry1. The playback duration is 6 short +// intervals. We play for 3, roll the clock back 2, and then play for 3 more. +// We then sleep until after the allowed playback duration and try to play. If +// OEMCrypto allows the rollback, then there is only 5 intervals, which is +// legal. But if OEMCrypto forbids the rollback, then there is 8 intervals of +// playback, which is not legal. +// +// For the second test, we use entry2. The rental duration is 6 short +// intervals. The times are the same as for entry1, except we do not start +// playback for entry2 until the end. + +// clang-format off +// [--][--][--][--][--][--][--] -- playback or rental limit. +// +// Here's what the system clock sees with rollback: +// [--][--][--] 3 short intervals of playback or sleep +// <------> Rollback 2 short intervals. +// [--][--][--] 3 short intervals of playback or sleep +// [--] 1 short intervals of sleep. +// +// Here's what the system clock sees without rollback: +// [--][--][--] 3 short intervals of playback or sleep +// [--][--][--] 3 short intervals of playback or sleep +// [--][--]X 2 short intervals of sleep. +// +// |<---------------------------->| 8 short intervals from license received +// until pst reports generated. +// clang-format on + +TEST_P(OEMCryptoUsageTableTestWallClock, TimeRollbackPrevention) { + cout << "This test temporarily rolls back the system time in order to " + "verify " + << "that the usage report accounts for the change. After the test, it " + << "rolls the clock back forward." << endl; + constexpr int kRollBackTime = kShortSleep * 2; + constexpr int kPlaybackCount = 3; + constexpr int kTotalTime = kShortSleep * 8; + + LicenseWithUsageEntry entry1; + entry1.license_messages() + .core_response() + .timer_limits.total_playback_duration_seconds = 7 * kShortSleep; + entry1.MakeOfflineAndClose(this); + Session& s1 = entry1.session(); + ASSERT_NO_FATAL_FAILURE(entry1.OpenAndReload(this)); + + LicenseWithUsageEntry entry2; + entry2.license_messages() + .core_response() + .timer_limits.rental_duration_seconds = 7 * kShortSleep; + entry2.MakeOfflineAndClose(this); + Session& s2 = entry2.session(); + ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this)); + + // Start with three short intervals of playback for entry1. + for (int i = 0; i < kPlaybackCount; i++) { + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + wvutil::TestSleep::Sleep(kShortSleep); + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + } + + cout << "Rolling the system time back..." << endl; + ASSERT_TRUE(wvutil::TestSleep::RollbackSystemTime(kRollBackTime)); + + // Three more short intervals of playback after the rollback. + for (int i = 0; i < kPlaybackCount; i++) { + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + wvutil::TestSleep::Sleep(kShortSleep); + ASSERT_NO_FATAL_FAILURE(entry1.TestDecryptCTR()); + } + + // One short interval of sleep to push us past the 6 interval duration. + wvutil::TestSleep::Sleep(2 * kShortSleep); + + // Should not be able to continue playback in entry1. + ASSERT_NO_FATAL_FAILURE( + entry1.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED)); + // Should not be able to start playback in entry2. + ASSERT_NO_FATAL_FAILURE( + entry2.TestDecryptCTR(true, OEMCrypto_ERROR_KEY_EXPIRED)); + + // Now we look at the usage reports: + ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s2.UpdateUsageEntry(&encrypted_usage_header_)); + + ASSERT_NO_FATAL_FAILURE(s1.GenerateReport(entry1.pst())); + wvutil::Unpacked_PST_Report report1 = s1.pst_report(); + EXPECT_EQ(report1.status(), kActive); + EXPECT_GE(report1.seconds_since_license_received(), kTotalTime); + EXPECT_GE(report1.seconds_since_first_decrypt(), kTotalTime); + + ASSERT_NO_FATAL_FAILURE(s2.GenerateReport(entry2.pst())); + wvutil::Unpacked_PST_Report report2 = s2.pst_report(); + EXPECT_EQ(report2.status(), kUnused); + EXPECT_GE(report2.seconds_since_license_received(), kTotalTime); +} + +// Verify that a large PST can be used with usage table entries. +TEST_P(OEMCryptoUsageTableTest, PSTLargeBuffer) { + std::string pst(kMaxPSTLength, 'a'); // A large PST. + LicenseWithUsageEntry entry(pst); + entry.MakeOfflineAndClose(this); + Session& s = entry.session(); + + ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this)); + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR()); // Should be able to decrypt. + ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); // Then deactivate. + // After deactivate, should not be able to decrypt. + ASSERT_NO_FATAL_FAILURE( + entry.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kInactiveUsed)); + ASSERT_NO_FATAL_FAILURE(s.close()); +} + +// Verify that a usage entry with an invalid session cannot be used. +TEST_P(OEMCryptoUsageTableTest, UsageEntryWithInvalidSession) { + std::string pst("pst"); + LicenseWithUsageEntry entry; + entry.license_messages().set_pst(pst); + + entry.session().open(); + ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); + entry.session().close(); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_DeactivateUsageEntry( + entry.session().session_id(), + reinterpret_cast(pst.c_str()), pst.length())); + + entry.session().open(); + ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); + entry.session().close(); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_MoveEntry(entry.session().session_id(), 0)); +} + +// Verify that a usage entry with an invalid session cannot be used. +TEST_P(OEMCryptoUsageTableTest, ReuseUsageEntryWithInvalidSessionAPI17) { + std::string pst("pst"); + LicenseWithUsageEntry entry; + entry.license_messages().set_pst(pst); + + entry.session().open(); + ASSERT_NO_FATAL_FAILURE(entry.session().CreateNewUsageEntry()); + entry.session().close(); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_ReuseUsageEntry(entry.session().session_id(), 0)); +} + +INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoUsageTableTest, + Range(kCoreMessagesAPI, kCurrentAPI + 1)); + +// These tests only work when the license has a core message. +INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableDefragTest, + Values(kCurrentAPI)); + +// These tests only work when the license has a core message. +INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableTestWallClock, + Values(kCurrentAPI)); + +} // namespace wvoec \ No newline at end of file diff --git a/oemcrypto/test/oemcrypto_usage_table_test.h b/oemcrypto/test/oemcrypto_usage_table_test.h new file mode 100644 index 00000000..ce5d7ab9 --- /dev/null +++ b/oemcrypto/test/oemcrypto_usage_table_test.h @@ -0,0 +1,337 @@ +// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. +// +// Test data for OEMCrypto unit tests. +// +#ifndef CDM_OEMCRYPTO_USAGE_TABLE_TEST_ +#define CDM_OEMCRYPTO_USAGE_TABLE_TEST_ + +#include +#include +#include + +#include "OEMCryptoCENC.h" +#include "log.h" +#include "oemcrypto_basic_test.h" +#include "oemcrypto_license_test.h" +#include "test_sleep.h" + +namespace wvoec { + +// This class is for testing the generic crypto functionality. +class OEMCryptoGenericCryptoTest : public OEMCryptoRefreshTest { + protected: + // buffer_size_ must be a multiple of encryption block size, 16. We'll use a + // reasonable number of blocks for most of the tests. + OEMCryptoGenericCryptoTest() : buffer_size_(160) {} + + void SetUp() override { + OEMCryptoRefreshTest::SetUp(); + ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); + ASSERT_NO_FATAL_FAILURE( + license_messages_.CreateResponseWithGenericCryptoKeys()); + InitializeClearBuffer(); + } + + void InitializeClearBuffer() { + clear_buffer_.assign(buffer_size_, 0); + for (size_t i = 0; i < clear_buffer_.size(); i++) { + clear_buffer_[i] = 1 + i % 250; + } + for (size_t i = 0; i < wvoec::KEY_IV_SIZE; i++) { + iv_[i] = i; + } + } + + void ResizeBuffer(size_t new_size) { + buffer_size_ = new_size; + InitializeClearBuffer(); // Re-initialize the clear buffer. + } + + void EncryptAndLoadKeys() { + ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); + ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); + } + + // Encrypt the buffer with the specified key made in + // CreateResponseWithGenericCryptoKeys. + void EncryptBuffer(unsigned int key_index, const vector& in_buffer, + vector* out_buffer) { + EncryptBufferWithKey(session_.license().keys[key_index].key_data, in_buffer, + out_buffer); + } + // Encrypt the buffer with the specified key. + void EncryptBufferWithKey(const uint8_t* key_data, + const vector& in_buffer, + vector* out_buffer) { + AES_KEY aes_key; + ASSERT_EQ(0, AES_set_encrypt_key(key_data, AES_BLOCK_SIZE * 8, &aes_key)); + uint8_t iv_buffer[wvoec::KEY_IV_SIZE]; + memcpy(iv_buffer, iv_, wvoec::KEY_IV_SIZE); + out_buffer->resize(in_buffer.size()); + ASSERT_GT(in_buffer.size(), 0u); + ASSERT_EQ(0u, in_buffer.size() % AES_BLOCK_SIZE); + AES_cbc_encrypt(in_buffer.data(), out_buffer->data(), in_buffer.size(), + &aes_key, iv_buffer, AES_ENCRYPT); + } + + // Sign the buffer with the specified key made in + // CreateResponseWithGenericCryptoKeys. + void SignBuffer(unsigned int key_index, const vector& in_buffer, + vector* signature) { + SignBufferWithKey(session_.license().keys[key_index].key_data, in_buffer, + signature); + } + + // Sign the buffer with the specified key. + void SignBufferWithKey(const uint8_t* key_data, + const vector& in_buffer, + vector* signature) { + unsigned int md_len = SHA256_DIGEST_LENGTH; + signature->resize(SHA256_DIGEST_LENGTH); + HMAC(EVP_sha256(), key_data, wvoec::MAC_KEY_SIZE, in_buffer.data(), + in_buffer.size(), signature->data(), &md_len); + } + + OEMCryptoResult GenericEncrypt(const uint8_t* key_handle, + size_t key_handle_length, + const uint8_t* clear_buffer, + size_t clear_buffer_length, const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + uint8_t* out_buffer) { + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_generic_encrypt_fuzz_seed_corpus"); + OEMCrypto_Generic_Api_Fuzz fuzzed_structure; + fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; + fuzzed_structure.algorithm = algorithm; + // Cipher mode and algorithm. + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, reinterpret_cast(iv), + wvoec::KEY_IV_SIZE); + AppendSeparator(file_name); + AppendToFile(file_name, reinterpret_cast(clear_buffer), + clear_buffer_length); + } + return OEMCrypto_Generic_Encrypt(key_handle, key_handle_length, + clear_buffer, clear_buffer_length, iv, + algorithm, out_buffer); + } + + OEMCryptoResult GenericDecrypt( + const uint8_t* key_handle, size_t key_handle_length, + const uint8_t* encrypted_buffer, size_t encrypted_buffer_length, + const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) { + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_generic_decrypt_fuzz_seed_corpus"); + OEMCrypto_Generic_Api_Fuzz fuzzed_structure; + fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; + fuzzed_structure.algorithm = algorithm; + // Cipher mode and algorithm. + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, reinterpret_cast(iv), + wvoec::KEY_IV_SIZE); + AppendSeparator(file_name); + AppendToFile(file_name, reinterpret_cast(encrypted_buffer), + encrypted_buffer_length); + } + return OEMCrypto_Generic_Decrypt(key_handle, key_handle_length, + encrypted_buffer, encrypted_buffer_length, + iv, algorithm, out_buffer); + } + + OEMCryptoResult GenericVerify(const uint8_t* key_handle, + size_t key_handle_length, + const uint8_t* clear_buffer, + size_t clear_buffer_length, + OEMCrypto_Algorithm algorithm, + const uint8_t* signature, + size_t signature_length) { + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_generic_verify_fuzz_seed_corpus"); + OEMCrypto_Generic_Api_Fuzz fuzzed_structure; + fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; + fuzzed_structure.algorithm = algorithm; + // Cipher mode and algorithm. + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, reinterpret_cast(clear_buffer), + clear_buffer_length); + AppendSeparator(file_name); + AppendToFile(file_name, reinterpret_cast(signature), + signature_length); + } + return OEMCrypto_Generic_Verify(key_handle, key_handle_length, clear_buffer, + clear_buffer_length, algorithm, signature, + signature_length); + } + + OEMCryptoResult GenericSign(const uint8_t* key_handle, + size_t key_handle_length, + const uint8_t* clear_buffer, + size_t clear_buffer_length, + OEMCrypto_Algorithm algorithm, uint8_t* signature, + size_t* signature_length) { + if (ShouldGenerateCorpus()) { + const std::string file_name = + GetFileName("oemcrypto_generic_sign_fuzz_seed_corpus"); + OEMCrypto_Generic_Api_Fuzz fuzzed_structure; + fuzzed_structure.cipher_mode = OEMCrypto_CipherMode_CENC; + fuzzed_structure.algorithm = algorithm; + // Cipher mode and algorithm. + AppendToFile(file_name, reinterpret_cast(&fuzzed_structure), + sizeof(fuzzed_structure)); + AppendToFile(file_name, reinterpret_cast(clear_buffer), + clear_buffer_length); + } + return OEMCrypto_Generic_Sign(key_handle, key_handle_length, clear_buffer, + clear_buffer_length, algorithm, signature, + signature_length); + } + + // This asks OEMCrypto to encrypt with the specified key, and expects a + // failure. + void BadEncrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, + size_t buffer_length) { + OEMCryptoResult sts; + vector expected_encrypted; + EncryptBuffer(key_index, clear_buffer_, &expected_encrypted); + vector key_handle; + sts = GetKeyHandleIntoVector( + session_.session_id(), session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + vector encrypted(buffer_length); + sts = GenericEncrypt(key_handle.data(), key_handle.size(), + clear_buffer_.data(), buffer_length, iv_, algorithm, + encrypted.data()); + EXPECT_NE(OEMCrypto_SUCCESS, sts); + expected_encrypted.resize(buffer_length); + EXPECT_NE(encrypted, expected_encrypted); + } + + // This asks OEMCrypto to decrypt with the specified key, and expects a + // failure. + void BadDecrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, + size_t buffer_length) { + OEMCryptoResult sts; + vector encrypted; + EncryptBuffer(key_index, clear_buffer_, &encrypted); + vector key_handle; + sts = GetKeyHandleIntoVector( + session_.session_id(), session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + vector resultant(encrypted.size()); + sts = GenericDecrypt(key_handle.data(), key_handle.size(), encrypted.data(), + buffer_length, iv_, algorithm, resultant.data()); + EXPECT_NE(OEMCrypto_SUCCESS, sts); + EXPECT_NE(clear_buffer_, resultant); + } + + // This asks OEMCrypto to sign with the specified key, and expects a + // failure. + void BadSign(unsigned int key_index, OEMCrypto_Algorithm algorithm) { + OEMCryptoResult sts; + vector expected_signature; + SignBuffer(key_index, clear_buffer_, &expected_signature); + + vector key_handle; + sts = GetKeyHandleIntoVector( + session_.session_id(), session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + size_t signature_length = (size_t)SHA256_DIGEST_LENGTH; + vector signature(SHA256_DIGEST_LENGTH); + sts = GenericSign(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), algorithm, + signature.data(), &signature_length); + EXPECT_NE(OEMCrypto_SUCCESS, sts); + EXPECT_NE(signature, expected_signature); + } + + // This asks OEMCrypto to verify a signature with the specified key, and + // expects a failure. + void BadVerify(unsigned int key_index, OEMCrypto_Algorithm algorithm, + size_t signature_size, bool alter_data) { + OEMCryptoResult sts; + vector signature; + SignBuffer(key_index, clear_buffer_, &signature); + if (alter_data) { + signature[0] ^= 42; + } + if (signature.size() < signature_size) { + signature.resize(signature_size); + } + + vector key_handle; + sts = GetKeyHandleIntoVector( + session_.session_id(), session_.license().keys[key_index].key_id, + session_.license().keys[key_index].key_id_length, + OEMCrypto_CipherMode_CENC, key_handle); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + sts = GenericVerify(key_handle.data(), key_handle.size(), + clear_buffer_.data(), clear_buffer_.size(), algorithm, + signature.data(), signature_size); + EXPECT_NE(OEMCrypto_SUCCESS, sts); + } + + // This must be a multiple of encryption block size. + size_t buffer_size_; + vector clear_buffer_; + vector encrypted_buffer_; + uint8_t iv_[wvoec::KEY_IV_SIZE]; +}; + +class OEMCryptoUsageTableTest : public OEMCryptoGenericCryptoTest { + public: + void SetUp() override { OEMCryptoGenericCryptoTest::SetUp(); } + + virtual void ShutDown() { + ASSERT_NO_FATAL_FAILURE(session_.close()); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate()); + } + + virtual void Restart() { + OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox)); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); + (void)OEMCrypto_SetMaxAPIVersion(kCurrentAPI); + (void)OEMCrypto_EnterTestMode(); + EnsureTestROT(); + ASSERT_NO_FATAL_FAILURE(session_.open()); + } + + void PrintDotsWhileSleep(int64_t total_seconds, int64_t interval_seconds) { + int64_t dot_time = interval_seconds; + int64_t elapsed_time = 0; + const int64_t start_time = wvutil::Clock().GetCurrentTime(); + do { + wvutil::TestSleep::Sleep(1); + elapsed_time = wvutil::Clock().GetCurrentTime() - start_time; + if (elapsed_time >= dot_time) { + cout << "."; + cout.flush(); + dot_time += interval_seconds; + } + } while (elapsed_time < total_seconds); + cout << endl; + } + + OEMCryptoResult LoadUsageTableHeader( + const vector& encrypted_usage_header) { + return OEMCrypto_LoadUsageTableHeader(encrypted_usage_header.data(), + encrypted_usage_header.size()); + } +}; + +} // namespace wvoec + +#endif // CDM_OEMCRYPTO_USAGE_TABLE_TEST_ \ No newline at end of file diff --git a/oemcrypto/test/ota_keybox_test.cpp b/oemcrypto/test/ota_keybox_test.cpp index 359da3a8..d1a94641 100644 --- a/oemcrypto/test/ota_keybox_test.cpp +++ b/oemcrypto/test/ota_keybox_test.cpp @@ -13,6 +13,7 @@ #include "oec_key_deriver.h" #include "oec_session_util.h" #include "oec_test_data.h" +#include "oemcrypto_basic_test.h" #include "oemcrypto_session_tests_helper.h" #include "oemcrypto_types.h" #include "platform.h" @@ -140,19 +141,6 @@ constexpr size_t kInitialOtaKeyboxRequestSize = 8 * 1024; // 8 kB. // |use_test_key| parameter of OEMCrypto_GenerateOTARequest() is true. constexpr uint32_t kUseTestKey = 1; -// TODO(fredgc): duplicate code. Move to common util package. -// Return a printable string from data. If all the characters are printable, -// then just use the string. Otherwise, convert to hex. -std::string MaybeHex(const uint8_t* data, size_t length) { - for (size_t i = 0; i < length; i++) { - if (!isprint(data[i])) return "0x" + wvutil::HexEncode(data, length); - } - return std::string(reinterpret_cast(data), length); -} -std::string MaybeHex(const std::vector& data) { - return MaybeHex(data.data(), data.size()); -} - std::vector GetModelKey(const std::vector& device_id) { std::vector keymint_key( TestKeyPKCS8, TestKeyPKCS8 + wvutil::ArraySize(TestKeyPKCS8)); diff --git a/oemcrypto/util/include/oemcrypto_key_handle.h b/oemcrypto/util/include/oemcrypto_key_handle.h new file mode 100644 index 00000000..9db90430 --- /dev/null +++ b/oemcrypto/util/include/oemcrypto_key_handle.h @@ -0,0 +1,63 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +// +// Implements utility functions for serializing and deserializing the fake key +// handles used by the Ref and Testbed. +// +#ifndef WVOEC_UTIL_KEY_HANDLE_H_ +#define WVOEC_UTIL_KEY_HANDLE_H_ + +#include +#include +#include + +#include "OEMCryptoCENC.h" +#include "log.h" + +namespace wvoec { +namespace util { +// Size of a key handle, which for this implementation is just a session ID. +constexpr size_t kKeyHandleSize = sizeof(OEMCrypto_SESSION); + +OEMCryptoResult SerializeSessionToKeyHandle(OEMCrypto_SESSION session, + uint8_t* key_handle, + size_t* key_handle_length) { + if (key_handle_length == nullptr) { + LOGE("Null key handle length"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + if (key_handle == nullptr || *key_handle_length < kKeyHandleSize) { + *key_handle_length = kKeyHandleSize; + return OEMCrypto_ERROR_SHORT_BUFFER; + } + + *key_handle_length = kKeyHandleSize; + memcpy(key_handle, &session, kKeyHandleSize); + return OEMCrypto_SUCCESS; +} + +OEMCryptoResult DeserializeKeyHandleToSession(const uint8_t* key_handle, + size_t key_handle_length, + OEMCrypto_SESSION* session) { + if (key_handle == nullptr) { + LOGE("Null key handle"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + if (session == nullptr) { + LOGE("Null session"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + if (key_handle_length != kKeyHandleSize) { + LOGE("Invalid key handle length"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + + memcpy(session, key_handle, kKeyHandleSize); + return OEMCrypto_SUCCESS; +} +} // namespace util +} // namespace wvoec +#endif // WVOEC_UTIL_KEY_HANDLE_H_ diff --git a/oemcrypto/util/include/oemcrypto_rsa_key.h b/oemcrypto/util/include/oemcrypto_rsa_key.h index e1d6db17..35b93ab4 100644 --- a/oemcrypto/util/include/oemcrypto_rsa_key.h +++ b/oemcrypto/util/include/oemcrypto_rsa_key.h @@ -122,6 +122,8 @@ class RsaPublicKey { // private equivalent of this public key. // The signature algorithm can be specified via the |algorithm| field. // See RsaSignatureAlgorithm for details on each algorithm. + // For RSASSA-PSS, the hash algorithm can be specified via |hash_algorithm|. + // This parameter is ignored for other signature algorithms. // // Returns: // OEMCrypto_SUCCESS if signature is valid @@ -129,15 +131,17 @@ class RsaPublicKey { // OEMCrypto_ERROR_UNKNOWN_FAILURE if any error occurs OEMCryptoResult VerifySignature( const uint8_t* message, size_t message_length, const uint8_t* signature, - size_t signature_length, - RsaSignatureAlgorithm algorithm = kRsaPssDefault) const; + size_t signature_length, RsaSignatureAlgorithm algorithm = kRsaPssDefault, + OEMCrypto_SignatureHashAlgorithm hash_algorithm = OEMCrypto_SHA1) const; OEMCryptoResult VerifySignature( const std::string& message, const std::string& signature, - RsaSignatureAlgorithm algorithm = kRsaPssDefault) const; + RsaSignatureAlgorithm algorithm = kRsaPssDefault, + OEMCrypto_SignatureHashAlgorithm hash_algorithm = OEMCrypto_SHA1) const; OEMCryptoResult VerifySignature( const std::vector& message, const std::vector& signature, - RsaSignatureAlgorithm algorithm = kRsaPssDefault) const; + RsaSignatureAlgorithm algorithm = kRsaPssDefault, + OEMCrypto_SignatureHashAlgorithm hash_algorithm = OEMCrypto_SHA1) const; // Encrypts the OEMCrypto session key used for deriving other keys. // On success, |enc_session_key_size| is populated with the number @@ -195,10 +199,10 @@ class RsaPublicKey { bool InitFromSslHandle(const RSA* rsa_handle, uint32_t allowed_schemes); // Signature specialization functions. - OEMCryptoResult VerifySignaturePss(const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length) const; + OEMCryptoResult VerifySignaturePss( + const uint8_t* message, size_t message_length, const uint8_t* signature, + size_t signature_length, + OEMCrypto_SignatureHashAlgorithm hash_algorithm) const; OEMCryptoResult VerifySignaturePkcs1Cast(const uint8_t* message, size_t message_length, const uint8_t* signature, diff --git a/oemcrypto/util/src/oemcrypto_oem_cert.cpp b/oemcrypto/util/src/oemcrypto_oem_cert.cpp index 1741d442..3f0bb698 100644 --- a/oemcrypto/util/src/oemcrypto_oem_cert.cpp +++ b/oemcrypto/util/src/oemcrypto_oem_cert.cpp @@ -207,7 +207,9 @@ OEMCryptoResult OemCertificate::GetPublicCertificate( return OEMCrypto_ERROR_SHORT_BUFFER; } *public_cert_length = cert_data.size(); - memcpy(public_cert, cert_data.data(), cert_data.size()); + if (public_cert != nullptr) { + memcpy(public_cert, cert_data.data(), cert_data.size()); + } return OEMCrypto_SUCCESS; } diff --git a/oemcrypto/util/src/oemcrypto_rsa_key.cpp b/oemcrypto/util/src/oemcrypto_rsa_key.cpp index ec4e6bb3..b700a687 100644 --- a/oemcrypto/util/src/oemcrypto_rsa_key.cpp +++ b/oemcrypto/util/src/oemcrypto_rsa_key.cpp @@ -92,7 +92,7 @@ bool ParseRsaPrivateKeyInfo(const uint8_t* buffer, size_t length, } ScopedBio bio; // Check allowed scheme type. - if (!memcmp("SIGN", buffer, 4)) { + if (memcmp("SIGN", buffer, 4) == 0) { uint32_t allowed_schemes_bno; memcpy(&allowed_schemes_bno, reinterpret_cast(&buffer[4]), 4); @@ -399,7 +399,8 @@ std::vector RsaPublicKey::Serialize() const { OEMCryptoResult RsaPublicKey::VerifySignature( const uint8_t* message, size_t message_length, const uint8_t* signature, - size_t signature_length, RsaSignatureAlgorithm algorithm) const { + size_t signature_length, RsaSignatureAlgorithm algorithm, + OEMCrypto_SignatureHashAlgorithm hash_algorithm) const { if (signature == nullptr || signature_length == 0) { LOGE("Signature is missing"); return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -411,7 +412,7 @@ OEMCryptoResult RsaPublicKey::VerifySignature( switch (algorithm) { case kRsaPssDefault: return VerifySignaturePss(message, message_length, signature, - signature_length); + signature_length, hash_algorithm); case kRsaPkcs1Cast: return VerifySignaturePkcs1Cast(message, message_length, signature, signature_length); @@ -422,7 +423,8 @@ OEMCryptoResult RsaPublicKey::VerifySignature( OEMCryptoResult RsaPublicKey::VerifySignature( const std::string& message, const std::string& signature, - RsaSignatureAlgorithm algorithm) const { + RsaSignatureAlgorithm algorithm, + OEMCrypto_SignatureHashAlgorithm hash_algorithm) const { if (signature.empty()) { LOGE("Signature should not be empty"); return OEMCrypto_ERROR_INVALID_CONTEXT; @@ -430,18 +432,19 @@ OEMCryptoResult RsaPublicKey::VerifySignature( return VerifySignature(reinterpret_cast(message.data()), message.size(), reinterpret_cast(signature.data()), - signature.size(), algorithm); + signature.size(), algorithm, hash_algorithm); } OEMCryptoResult RsaPublicKey::VerifySignature( const std::vector& message, const std::vector& signature, - RsaSignatureAlgorithm algorithm) const { + RsaSignatureAlgorithm algorithm, + OEMCrypto_SignatureHashAlgorithm hash_algorithm) const { if (signature.empty()) { LOGE("Signature should not be empty"); return OEMCrypto_ERROR_INVALID_CONTEXT; } return VerifySignature(message.data(), message.size(), signature.data(), - signature.size(), algorithm); + signature.size(), algorithm, hash_algorithm); } OEMCryptoResult RsaPublicKey::EncryptSessionKey( @@ -664,7 +667,8 @@ bool RsaPublicKey::InitFromSslHandle(const RSA* rsa_handle, OEMCryptoResult RsaPublicKey::VerifySignaturePss( const uint8_t* message, size_t message_length, const uint8_t* signature, - size_t signature_length) const { + size_t signature_length, + OEMCrypto_SignatureHashAlgorithm hash_algorithm) const { // Step 0: Ensure the signature algorithm is supported by key. if (!(allowed_schemes_ & kSign_RSASSA_PSS)) { LOGE("RSA key cannot verify using PSS"); @@ -680,14 +684,34 @@ OEMCryptoResult RsaPublicKey::VerifySignaturePss( LOGE("Failed to set PKEY RSA key"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - // Step 2a: Setup a EVP MD CTX for PSS Verification. + // Step 2a: Choose the correct digest algorithm. + const EVP_MD* digest = nullptr; + switch (hash_algorithm) { + case OEMCrypto_SHA1: + digest = EVP_sha1(); + break; + case OEMCrypto_SHA2_256: + digest = EVP_sha256(); + break; + case OEMCrypto_SHA2_384: + digest = EVP_sha384(); + break; + case OEMCrypto_SHA2_512: + digest = EVP_sha512(); + break; + } + if (digest == nullptr) { + LOGE("Unrecognized hash algorithm %d", hash_algorithm); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + // Step 2b: Setup an EVP MD CTX for PSS Verification. ScopedEvpMdCtx md_ctx = EVP_MD_CTX_new(); if (!md_ctx) { LOGE("Failed to allocate MD CTX"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } EVP_PKEY_CTX* pkey_ctx = nullptr; // Ownership is maintained by |md_ctx| - int res = EVP_DigestVerifyInit(md_ctx.get(), &pkey_ctx, EVP_sha1(), nullptr, + int res = EVP_DigestVerifyInit(md_ctx.get(), &pkey_ctx, digest, nullptr, pkey.get()); if (res != 1) { LOGE("Failed to initialize MD CTX for verification"); @@ -697,7 +721,7 @@ OEMCryptoResult RsaPublicKey::VerifySignaturePss( LOGE("PKEY CTX is unexpectedly null"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - // Step 2b: Configure OEMCrypto RSASSA-PSS options. + // Step 2c: Configure OEMCrypto RSASSA-PSS options. res = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING); if (res != 1) { LOGE("Failed to set PSS padding"); @@ -787,7 +811,9 @@ OEMCryptoResult RsaPublicKey::EncryptOaep(const uint8_t* message, return OEMCrypto_ERROR_SHORT_BUFFER; } *enc_message_length = enc_size; - memcpy(enc_message, encrypt_buffer.data(), enc_size); + if (enc_message != nullptr) { + memcpy(enc_message, encrypt_buffer.data(), enc_size); + } return OEMCrypto_SUCCESS; } diff --git a/platforms/example-runtime-client-info/settings.gypi b/platforms/example-runtime-client-info/settings.gypi index 766c2aec..2c8ad053 100644 --- a/platforms/example-runtime-client-info/settings.gypi +++ b/platforms/example-runtime-client-info/settings.gypi @@ -35,8 +35,8 @@ ], # These are flags passed to the compiler for C++ only. 'cflags_cc': [ - # Compile using the C++11 standard. - '-std=c++11', + # Compile using the C++14 standard. + '-std=c++14', # CE CDM does not use exceptions or RTTI. '-fno-exceptions', '-fno-rtti', diff --git a/platforms/example/no_oemcrypto.cpp b/platforms/example/no_oemcrypto.cpp index 03253cbd..3659f566 100644 --- a/platforms/example/no_oemcrypto.cpp +++ b/platforms/example/no_oemcrypto.cpp @@ -141,15 +141,17 @@ OEMCryptoResult OEMCrypto_QueryKeyControl( return OEMCrypto_ERROR_NOT_IMPLEMENTED; } -OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session UNUSED, - const uint8_t* content_key_id UNUSED, - size_t content_key_id_length UNUSED, - OEMCryptoCipherMode cipher_mode UNUSED) { +OEMCryptoResult OEMCrypto_GetKeyHandle(OEMCrypto_SESSION session UNUSED, + const uint8_t* content_key_id UNUSED, + size_t content_key_id_length UNUSED, + OEMCryptoCipherMode cipher_mode UNUSED, + uint8_t* key_handle UNUSED, + size_t* key_handle_length UNUSED) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } OEMCryptoResult OEMCrypto_DecryptCENC( - OEMCrypto_SESSION session UNUSED, + const uint8_t* key_handle UNUSED, size_t key_handle_length UNUSED, const OEMCrypto_SampleDescription* samples UNUSED, size_t samples_length UNUSED, const OEMCrypto_CENCEncryptPatternDesc* pattern UNUSED) { @@ -166,7 +168,7 @@ OEMCryptoResult OEMCrypto_CopyBuffer( } OEMCryptoResult OEMCrypto_Generic_Encrypt( - OEMCrypto_SESSION session UNUSED, + const uint8_t* key_handle UNUSED, size_t key_handle_length UNUSED, const OEMCrypto_SharedMemory* in_buffer UNUSED, size_t in_buffer_length UNUSED, const uint8_t* iv UNUSED, OEMCrypto_Algorithm algorithm UNUSED, @@ -175,7 +177,7 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt( } OEMCryptoResult OEMCrypto_Generic_Decrypt( - OEMCrypto_SESSION session UNUSED, + const uint8_t* key_handle UNUSED, size_t key_handle_length UNUSED, const OEMCrypto_SharedMemory* in_buffer UNUSED, size_t in_buffer_length UNUSED, const uint8_t* iv UNUSED, OEMCrypto_Algorithm algorithm UNUSED, @@ -184,7 +186,7 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt( } OEMCryptoResult OEMCrypto_Generic_Sign( - OEMCrypto_SESSION session UNUSED, + const uint8_t* key_handle UNUSED, size_t key_handle_length UNUSED, const OEMCrypto_SharedMemory* buffer UNUSED, size_t buffer_length UNUSED, OEMCrypto_Algorithm algorithm UNUSED, OEMCrypto_SharedMemory* signature UNUSED, size_t* signature_length UNUSED) { @@ -192,7 +194,7 @@ OEMCryptoResult OEMCrypto_Generic_Sign( } OEMCryptoResult OEMCrypto_Generic_Verify( - OEMCrypto_SESSION session UNUSED, + const uint8_t* key_handle UNUSED, size_t key_handle_length UNUSED, const OEMCrypto_SharedMemory* buffer UNUSED, size_t buffer_length UNUSED, OEMCrypto_Algorithm algorithm UNUSED, const OEMCrypto_SharedMemory* signature UNUSED, @@ -308,6 +310,12 @@ OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(void) { return OEMCrypto_WatermarkingError; } +OEMCryptoResult OEMCrypto_GetSignatureHashAlgorithm( + OEMCrypto_SESSION session UNUSED, + OEMCrypto_SignatureHashAlgorithm* algorithm UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + OEMCryptoResult OEMCrypto_LoadProvisioning( OEMCrypto_SESSION session UNUSED, const uint8_t* message UNUSED, size_t message_length UNUSED, size_t core_message_length UNUSED, @@ -493,3 +501,25 @@ OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session UNUSED, size_t* key_token_length UNUSED) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } + +OEMCryptoResult OEMCrypto_GetDeviceInformation( + uint8_t* device_info UNUSED, size_t* device_info_length UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult OEMCrypto_GetDeviceSignedCsrPayload( + const uint8_t* challenge UNUSED, size_t challenge_length UNUSED, + const uint8_t* encoded_device_info UNUSED, + size_t encoded_device_info_length UNUSED, + uint8_t* signed_csr_payload UNUSED, + size_t* signed_csr_payload_length UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult OEMCrypto_SetMaxAPIVersion(uint32_t max_version UNUSED) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +OEMCryptoResult OEMCrypto_EnterTestMode(void) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} diff --git a/platforms/example/settings.gypi b/platforms/example/settings.gypi index 11c0720a..509f8e60 100644 --- a/platforms/example/settings.gypi +++ b/platforms/example/settings.gypi @@ -42,8 +42,8 @@ ], # These are flags passed to the compiler for C++ only. 'cflags_cc': [ - # Compile using the C++11 standard. - '-std=c++11', + # Compile using the C++14 standard. + '-std=c++14', # CE CDM does not use exceptions or RTTI. '-fno-exceptions', '-fno-rtti', diff --git a/third_party/boringssl/kit/BORINGSSL_REVISION b/third_party/boringssl/kit/BORINGSSL_REVISION index a6c6a067..f1e146e6 100644 --- a/third_party/boringssl/kit/BORINGSSL_REVISION +++ b/third_party/boringssl/kit/BORINGSSL_REVISION @@ -1 +1 @@ -731d6cbef936e60a04738edf4eb4fc93e187706a +e1b8685770d0e82e5a4a3c5d24ad1602e05f2e83 diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/chacha/chacha-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/chacha/chacha-armv8-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-aarch64/crypto/chacha/chacha-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/chacha/chacha-armv8-apple.S index 31db8258..61974285 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/chacha/chacha-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/chacha/chacha-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -65,7 +65,7 @@ Lshort: ldp x24,x25,[x3] // load key ldp x26,x27,[x3,#16] ldp x28,x30,[x4] // load counter -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x24,x24,#32 ror x25,x25,#32 ror x26,x26,#32 @@ -226,7 +226,7 @@ Loop: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -283,7 +283,7 @@ Less_than_64: add x15,x15,x16,lsl#32 add x17,x17,x19,lsl#32 add x20,x20,x21,lsl#32 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -349,7 +349,7 @@ ChaCha20_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -647,7 +647,7 @@ Loop_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -727,7 +727,7 @@ Ltail_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -845,7 +845,7 @@ L512_or_more_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -1358,7 +1358,7 @@ Loop_upper_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1872,7 +1872,7 @@ Loop_lower_neon: add x1,x1,#64 add v21.4s,v21.4s,v25.4s -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1989,4 +1989,8 @@ Ldone_512_neon: AARCH64_VALIDATE_LINK_REGISTER ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/apple-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-apple.S b/third_party/boringssl/kit/apple-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-apple.S new file mode 100644 index 00000000..7fce1759 --- /dev/null +++ b/third_party/boringssl/kit/apple-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-apple.S @@ -0,0 +1,3021 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +.section __TEXT,__const + +.align 7 +Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +Linc: +.long 1,2,3,4 +Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC + +.text + + +.align 6 +Lpoly_hash_ad_internal: +.cfi_startproc + cbnz x4, Lpoly_hash_intro + ret + +Lpoly_hash_intro: + cmp x4, #16 + b.lt Lpoly_hash_ad_tail + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b Lpoly_hash_ad_internal + +Lpoly_hash_ad_tail: + cbz x4, Lpoly_hash_ad_ret + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the AAD + sub x4, x4, #1 + +Lpoly_hash_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, x4] + mov v20.b[0], w11 + subs x4, x4, #1 + b.ge Lpoly_hash_tail_16_compose + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lpoly_hash_ad_ret: + ret +.cfi_endproc + + +///////////////////////////////// +// +// void chacha20_poly1305_seal(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *seal_data); +// +.globl _chacha20_poly1305_seal +.private_extern _chacha20_poly1305_seal + +.align 6 +_chacha20_poly1305_seal: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, Lchacha20_consts@PAGE + add x11, x11, Lchacha20_consts@PAGEOFF + + ld1 {v24.16b - v27.16b}, [x11] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + ldr x12, [x5, #56] // The total cipher text length includes extra_in_len + add x12, x12, x2 + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x12 + + cmp x2, #128 + b.le Lseal_128 // Optimization for smaller buffers + + // Initially we prepare 5 ChaCha20 blocks. Four to encrypt up to 4 blocks (256 bytes) of plaintext, + // and one for the Poly1305 R and S keys. The first four blocks (A0-A3..D0-D3) are computed vertically, + // the fifth block (A4-D4) horizontally. + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + sub x5, x5, #32 + + mov x6, #10 + +.align 5 +Lseal_init_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.hi Lseal_init_rounds + + add v15.4s, v15.4s, v25.4s + mov x11, #4 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + and v4.16b, v4.16b, v27.16b + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + mov x16, v4.d[0] // Move the R key to GPRs + mov x17, v4.d[1] + mov v27.16b, v9.16b // Store the S key + + bl Lpoly_hash_ad_internal + + mov x3, x0 + cmp x2, #256 + b.le Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #256 + + mov x6, #4 // In the first run of the loop we need to hash 256 bytes, therefore we hash one block for the first 4 rounds + mov x7, #6 // and two blocks for the remaining 6, for a total of (1 * 4 + 2 * 6) * 16 = 256 + +Lseal_main_loop: + adrp x11, Lchacha20_consts@PAGE + add x11, x11, Lchacha20_consts@PAGEOFF + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + sub x5, x5, #32 +.align 5 +Lseal_main_loop_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.ge Lseal_main_loop_rounds + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + subs x7, x7, #1 + b.gt Lseal_main_loop_rounds + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + cmp x2, #320 + b.le Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #320 + + mov x6, #0 + mov x7, #10 // For the remainder of the loop we always hash and encrypt 320 bytes per iteration + + b Lseal_main_loop + +Lseal_tail: + // This part of the function handles the storage and authentication of the last [0,320) bytes + // We assume A0-A4 ... D0-D4 hold at least inl (320 max) bytes of the stream data. + cmp x2, #64 + b.lt Lseal_tail_64 + + // Store and authenticate 64B blocks per iteration + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + // Shift the state left by 64 bytes for the next iteration of the loop + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + + mov v1.16b, v2.16b + mov v6.16b, v7.16b + mov v11.16b, v12.16b + mov v16.16b, v17.16b + + mov v2.16b, v3.16b + mov v7.16b, v8.16b + mov v12.16b, v13.16b + mov v17.16b, v18.16b + + mov v3.16b, v4.16b + mov v8.16b, v9.16b + mov v13.16b, v14.16b + mov v18.16b, v19.16b + + b Lseal_tail + +Lseal_tail_64: + ldp x3, x4, [x5, #48] // extra_in_len and extra_in_ptr + + // Here we handle the last [0,64) bytes of plaintext + cmp x2, #16 + b.lt Lseal_tail_16 + // Each iteration encrypt and authenticate a 16B block + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b}, [x0], #16 + + sub x2, x2, #16 + + // Shift the state left by 16 bytes for the next iteration of the loop + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + + b Lseal_tail_64 + +Lseal_tail_16: + // Here we handle the last [0,16) bytes of ciphertext that require a padded block + cbz x2, Lseal_hash_extra + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the plaintext/extra in + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask that will only mask the ciphertext bytes + not v22.16b, v20.16b + + mov x6, x2 + add x1, x1, x2 + + cbz x4, Lseal_tail_16_compose // No extra data to pad with, zero padding + + mov x7, #16 // We need to load some extra_in first for padding + sub x7, x7, x2 + cmp x4, x7 + csel x7, x4, x7, lt // Load the minimum of extra_in_len and the amount needed to fill the register + mov x12, x7 + add x3, x3, x7 + sub x4, x4, x7 + +Lseal_tail16_compose_extra_in: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x7, x7, #1 + b.gt Lseal_tail16_compose_extra_in + + add x3, x3, x12 + +Lseal_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x1, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt Lseal_tail_16_compose + + and v0.16b, v0.16b, v21.16b + eor v20.16b, v20.16b, v0.16b + mov v21.16b, v20.16b + +Lseal_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt Lseal_tail_16_store + + // Hash in the final ct block concatenated with extra_in + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lseal_hash_extra: + cbz x4, Lseal_finalize + +Lseal_hash_extra_loop: + cmp x4, #16 + b.lt Lseal_hash_extra_tail + ld1 {v20.16b}, [x3], #16 + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b Lseal_hash_extra_loop + +Lseal_hash_extra_tail: + cbz x4, Lseal_finalize + eor v20.16b, v20.16b, v20.16b // Use T0 to load the remaining extra ciphertext + add x3, x3, x4 + +Lseal_hash_extra_load: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x4, x4, #1 + b.gt Lseal_hash_extra_load + + // Hash in the final padded extra_in blcok + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lseal_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +Lseal_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +Lseal_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi Lseal_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + // Only the first 32 bytes of the third block (counter = 0) are needed, + // so skip updating v12 and v17. + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl Lpoly_hash_ad_internal + b Lseal_tail +.cfi_endproc + + +///////////////////////////////// +// +// void chacha20_poly1305_open(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *aead_data); +// +.globl _chacha20_poly1305_open +.private_extern _chacha20_poly1305_open + +.align 6 +_chacha20_poly1305_open: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, Lchacha20_consts@PAGE + add x11, x11, Lchacha20_consts@PAGEOFF + + ld1 {v24.16b - v27.16b}, [x11] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x2 + + cmp x2, #128 + b.le Lopen_128 // Optimization for smaller buffers + + // Initially we prepare a single ChaCha20 block for the Poly1305 R and S keys + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + + mov x6, #10 + +.align 5 +Lopen_init_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.hi Lopen_init_rounds + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + + and v0.16b, v0.16b, v27.16b + mov x16, v0.d[0] // Move the R key to GPRs + mov x17, v0.d[1] + mov v27.16b, v5.16b // Store the S key + + bl Lpoly_hash_ad_internal + +Lopen_ad_done: + mov x3, x1 + +// Each iteration of the loop hash 320 bytes, and prepare stream for 320 bytes +Lopen_main_loop: + + cmp x2, #192 + b.lt Lopen_tail + + adrp x11, Lchacha20_consts@PAGE + add x11, x11, Lchacha20_consts@PAGEOFF + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + sub x5, x5, #32 + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + lsr x4, x2, #4 // How many whole blocks we have to hash, will always be at least 12 + sub x4, x4, #10 + + mov x7, #10 + subs x6, x7, x4 + subs x6, x7, x4 // itr1 can be negative if we have more than 320 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are full + + cbz x7, Lopen_main_loop_rounds_short + +.align 5 +Lopen_main_loop_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +Lopen_main_loop_rounds_short: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x7, x7, #1 + b.gt Lopen_main_loop_rounds + subs x6, x6, #1 + b.ge Lopen_main_loop_rounds_short + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + // We can always safely store 192 bytes + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #192 + + mov v0.16b, v3.16b + mov v5.16b, v8.16b + mov v10.16b, v13.16b + mov v15.16b, v18.16b + + cmp x2, #64 + b.lt Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v4.16b + mov v5.16b, v9.16b + mov v10.16b, v14.16b + mov v15.16b, v19.16b + + cmp x2, #64 + b.lt Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + b Lopen_main_loop + +Lopen_tail: + + cbz x2, Lopen_finalize + + lsr x4, x2, #4 // How many whole blocks we have to hash + + cmp x2, #64 + b.le Lopen_tail_64 + cmp x2, #128 + b.le Lopen_tail_128 + +Lopen_tail_192: + // We need three more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + mov v17.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v21.16b, v21.16b, v21.16b + ins v23.s[0], v25.s[0] + ins v21.d[0], x15 + + add v22.4s, v23.4s, v21.4s + add v21.4s, v22.4s, v21.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + mov x7, #10 + subs x6, x7, x4 // itr1 can be negative if we have more than 160 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are hashing + sub x4, x4, x7 + + cbz x7, Lopen_tail_192_rounds_no_hash + +Lopen_tail_192_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +Lopen_tail_192_rounds_no_hash: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x7, x7, #1 + b.gt Lopen_tail_192_rounds + subs x6, x6, #1 + b.ge Lopen_tail_192_rounds_no_hash + + // We hashed 160 bytes at most, may still have 32 bytes left +Lopen_tail_192_hash: + cbz x4, Lopen_tail_192_hash_done + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b Lopen_tail_192_hash + +Lopen_tail_192_hash_done: + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v12.4s, v12.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v17.4s, v17.4s, v30.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #128 + b Lopen_tail_64_store + +Lopen_tail_128: + // We need two more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v22.16b, v22.16b, v22.16b + ins v23.s[0], v25.s[0] + ins v22.d[0], x15 + add v22.4s, v22.4s, v23.4s + + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +Lopen_tail_128_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #4 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #12 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #4 + subs x6, x6, #1 + b.gt Lopen_tail_128_rounds + cbz x4, Lopen_tail_128_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b Lopen_tail_128_rounds + +Lopen_tail_128_rounds_done: + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + b Lopen_tail_64_store + +Lopen_tail_64: + // We just need a single block + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + ins v23.s[0], v25.s[0] + add v15.4s, v15.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +Lopen_tail_64_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.gt Lopen_tail_64_rounds + cbz x4, Lopen_tail_64_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b Lopen_tail_64_rounds + +Lopen_tail_64_rounds_done: + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v15.4s, v15.4s, v23.4s + +Lopen_tail_64_store: + cmp x2, #16 + b.lt Lopen_tail_16 + + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + st1 {v20.16b}, [x0], #16 + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + sub x2, x2, #16 + b Lopen_tail_64_store + +Lopen_tail_16: + // Here we handle the last [0,16) bytes that require a padded block + cbz x2, Lopen_finalize + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the ciphertext + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask + not v22.16b, v20.16b + + add x7, x1, x2 + mov x6, x2 + +Lopen_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x7, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt Lopen_tail_16_compose + + and v20.16b, v20.16b, v21.16b + // Hash in the final padded block + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + eor v20.16b, v20.16b, v0.16b + +Lopen_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt Lopen_tail_16_store + +Lopen_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +Lopen_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +Lopen_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi Lopen_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl Lpoly_hash_ad_internal + +Lopen_128_store: + cmp x2, #64 + b.lt Lopen_128_store_64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + +Lopen_128_store_64: + + lsr x4, x2, #4 + mov x3, x1 + +Lopen_128_hash_64: + cbz x4, Lopen_tail_64_store + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b Lopen_128_hash_64 +.cfi_endproc + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-armv8-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-armv8-apple.S index 13950f17..7e9cf402 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -634,7 +634,7 @@ _aes_hw_ctr32_encrypt_blocks: // // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8, w8 #endif add w10, w8, #1 @@ -796,4 +796,8 @@ Lctr32_done: ret #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-apple.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-apple.S new file mode 100644 index 00000000..068b3a91 --- /dev/null +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-apple.S @@ -0,0 +1,1567 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +#if __ARM_MAX_ARCH__ >= 8 + + +.text +.globl _aes_gcm_enc_kernel +.private_extern _aes_gcm_enc_kernel + +.align 4 +_aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + add x4, x0, x1, lsr #3 // end_input_ptr + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 // byte_len - 1 + ldr q18, [x8, #0] // load rk0 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr q25, [x8, #112] // load rk7 + add x5, x5, x0 + lsr x12, x11, #32 + fmov d2, x10 // CTR block 2 + orr w11, w11, w11 + rev w12, w12 // rev_ctr32 + fmov d1, x10 // CTR block 1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + add w12, w12, #1 // increment rev_ctr32 + rev w9, w12 // CTR block 1 + fmov d3, x10 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 1 + add w12, w12, #1 // CTR block 1 + ldr q19, [x8, #16] // load rk1 + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + ldr q20, [x8, #32] // load rk2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + orr x9, x11, x9, lsl #32 // CTR block 3 + fmov v3.d[1], x9 // CTR block 3 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q21, [x8, #48] // load rk3 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q24, [x8, #96] // load rk6 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q23, [x8, #80] // load rk5 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q22, [x8, #64] // load rk4 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + ldr q29, [x8, #176] // load rk11 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + ldr q26, [x8, #128] // load rk8 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + add w12, w12, #1 // CTR block 3 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + ldr q27, [x8, #144] // load rk9 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + ldr q28, [x8, #160] // load rk10 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + b.lt Lenc_finish_first_blocks // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + b.eq Lenc_finish_first_blocks // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Lenc_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v2.16b, v31.16b // AES block 2 - round N-1 + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + aese v3.16b, v31.16b // AES block 3 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + b.ge Lenc_tail // handle tail + + ldp x19, x20, [x0, #16] // AES block 1 - load plaintext + rev w9, w12 // CTR block 4 + ldp x6, x7, [x0, #0] // AES block 0 - load plaintext + ldp x23, x24, [x0, #48] // AES block 3 - load plaintext + ldp x21, x22, [x0, #32] // AES block 2 - load plaintext + add x0, x0, #64 // AES input_ptr update + eor x19, x19, x13 // AES block 1 - round N low + eor x20, x20, x14 // AES block 1 - round N high + fmov d5, x19 // AES block 1 - mov low + eor x6, x6, x13 // AES block 0 - round N low + eor x7, x7, x14 // AES block 0 - round N high + eor x24, x24, x14 // AES block 3 - round N high + fmov d4, x6 // AES block 0 - mov low + cmp x0, x5 // check if we have <= 8 blocks + fmov v4.d[1], x7 // AES block 0 - mov high + eor x23, x23, x13 // AES block 3 - round N low + eor x21, x21, x13 // AES block 2 - round N low + fmov v5.d[1], x20 // AES block 1 - mov high + fmov d6, x21 // AES block 2 - mov low + add w12, w12, #1 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov d7, x23 // AES block 3 - mov low + eor x22, x22, x14 // AES block 2 - round N high + fmov v6.d[1], x22 // AES block 2 - mov high + eor v4.16b, v4.16b, v0.16b // AES block 0 - result + fmov d0, x10 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + eor v5.16b, v5.16b, v1.16b // AES block 1 - result + fmov d1, x10 // CTR block 5 + orr x9, x11, x9, lsl #32 // CTR block 5 + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + st1 { v4.16b}, [x2], #16 // AES block 0 - store result + fmov v7.d[1], x24 // AES block 3 - mov high + orr x9, x11, x9, lsl #32 // CTR block 6 + eor v6.16b, v6.16b, v2.16b // AES block 2 - result + st1 { v5.16b}, [x2], #16 // AES block 1 - store result + add w12, w12, #1 // CTR block 6 + fmov d2, x10 // CTR block 6 + fmov v2.d[1], x9 // CTR block 6 + st1 { v6.16b}, [x2], #16 // AES block 2 - store result + rev w9, w12 // CTR block 7 + orr x9, x11, x9, lsl #32 // CTR block 7 + eor v7.16b, v7.16b, v3.16b // AES block 3 - result + st1 { v7.16b}, [x2], #16 // AES block 3 - store result + b.ge Lenc_prepretail // do prepretail + +Lenc_main_loop: // main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + fmov v3.d[1], x9 // CTR block 4k+3 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] // AES block 4k+7 - load plaintext + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] // AES block 4k+6 - load plaintext + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b // PRE 1 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x23, x23, x13 // AES block 4k+7 - round N low + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d10, v17.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + eor x22, x22, x14 // AES block 4k+6 - round N high + mov d8, v4.d[1] // GHASH block 4k - mid + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] // AES block 4k+5 - load plaintext + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor x19, x19, x13 // AES block 4k+5 - round N low + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + eor x21, x21, x13 // AES block 4k+6 - round N low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + movi v8.8b, #0xc2 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + fmov d5, x19 // AES block 4k+5 - mov low + ldp x6, x7, [x0, #0] // AES block 4k+4 - load plaintext + b.lt Lenc_main_loop_continue // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Lenc_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Lenc_main_loop_continue: + shl d8, d8, #56 // mod_constant + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + add w12, w12, #1 // CTR block 4k+3 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + add x0, x0, #64 // AES input_ptr update + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + rev w9, w12 // CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor x6, x6, x13 // AES block 4k+4 - round N low + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + eor x7, x7, x14 // AES block 4k+4 - round N high + fmov d4, x6 // AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b // MODULO - fold into mid + eor x20, x20, x14 // AES block 4k+5 - round N high + eor x24, x24, x14 // AES block 4k+7 - round N high + add w12, w12, #1 // CTR block 4k+8 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + fmov d7, x23 // AES block 4k+7 - mov low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + fmov v5.d[1], x20 // AES block 4k+5 - mov high + fmov d6, x21 // AES block 4k+6 - mov low + cmp x0, x5 // LOOP CONTROL + fmov v6.d[1], x22 // AES block 4k+6 - mov high + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b // AES block 4k+4 - result + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + rev w9, w12 // CTR block 4k+9 + add w12, w12, #1 // CTR block 4k+9 + eor v5.16b, v5.16b, v1.16b // AES block 4k+5 - result + fmov d1, x10 // CTR block 4k+9 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + fmov v1.d[1], x9 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + rev w9, w12 // CTR block 4k+10 + st1 { v4.16b}, [x2], #16 // AES block 4k+4 - store result + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + fmov v7.d[1], x24 // AES block 4k+7 - mov high + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 // AES block 4k+5 - store result + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + eor v6.16b, v6.16b, v2.16b // AES block 4k+6 - result + fmov d2, x10 // CTR block 4k+10 + st1 { v6.16b}, [x2], #16 // AES block 4k+6 - store result + fmov v2.d[1], x9 // CTR block 4k+10 + rev w9, w12 // CTR block 4k+11 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + orr x9, x11, x9, lsl #32 // CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b // AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 // AES block 4k+7 - store result + b.lt Lenc_main_loop + +Lenc_prepretail: // PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + fmov v3.d[1], x9 // CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + add w12, w12, #1 // CTR block 4k+3 + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v9.16b // karatsuba tidy up + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + eor v10.16b, v10.16b, v11.16b + b.lt Lenc_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + b.eq Lenc_finish_prepretail // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + +Lenc_finish_prepretail: + eor v10.16b, v10.16b, v4.16b + eor v10.16b, v10.16b, v9.16b + pmull v4.1q, v10.1d, v8.1d + ext v10.16b, v10.16b, v10.16b, #8 + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + eor v11.16b, v11.16b, v4.16b + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b + +Lenc_tail: // TAIL + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 // AES block 4k+4 - load plaintext + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + cmp x5, #48 + fmov d4, x6 // AES block 4k+4 - mov low + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v5.16b, v4.16b, v0.16b // AES block 4k+4 - result + b.gt Lenc_blocks_more_than_3 + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + movi v9.8b, #0 + sub w12, w12, #1 + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt Lenc_blocks_more_than_2 + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + b.gt Lenc_blocks_more_than_1 + sub w12, w12, #1 + b Lenc_blocks_less_than_1 +Lenc_blocks_more_than_3: // blocks left > 3 + st1 { v5.16b}, [x2], #16 // AES final-3 block - store result + ldp x6, x7, [x0], #16 // AES final-2 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-3 block + eor x6, x6, x13 // AES final-2 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor x7, x7, x14 // AES final-2 block - round N high + mov d22, v4.d[1] // GHASH final-3 block - mid + fmov d5, x6 // AES final-2 block - mov low + fmov v5.d[1], x7 // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + mov d10, v17.d[1] // GHASH final-3 block - mid + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b // AES final-2 block - result +Lenc_blocks_more_than_2: // blocks left > 2 + st1 { v5.16b}, [x2], #16 // AES final-2 block - store result + ldp x6, x7, [x0], #16 // AES final-1 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-2 block + eor x6, x6, x13 // AES final-1 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + fmov d5, x6 // AES final-1 block - mov low + eor x7, x7, x14 // AES final-1 block - round N high + fmov v5.d[1], x7 // AES final-1 block - mov high + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + eor v5.16b, v5.16b, v2.16b // AES final-1 block - result + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid +Lenc_blocks_more_than_1: // blocks left > 1 + st1 { v5.16b}, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ldp x6, x7, [x0], #16 // AES final block - load input low & high + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + eor x6, x6, x13 // AES final block - round N low + mov d22, v4.d[1] // GHASH final-1 block - mid + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor x7, x7, x14 // AES final block - round N high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + fmov d5, x6 // AES final block - mov low + fmov v5.d[1], x7 // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + eor v5.16b, v5.16b, v3.16b // AES final block - result + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low +Lenc_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] // load existing bytes where the possibly partial last block is to be stored + mvn x14, xzr // rkN_h = 0xffffffffffffffff + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + fmov d0, x6 // ctr0b is mask for last block + fmov v0.d[1], x7 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + bif v5.16b, v18.16b, v0.16b // insert existing bytes in top end of result before storing + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + mov d8, v4.d[1] // GHASH final block - mid + rev w9, w12 + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + str w9, [x16, #12] // store the updated counter + st1 { v5.16b}, [x2] // store all 16B + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _aes_gcm_dec_kernel +.private_extern _aes_gcm_dec_kernel + +.align 4 +_aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ldr q26, [x8, #128] // load rk8 + sub x5, x5, #1 // byte_len - 1 + ldr q25, [x8, #112] // load rk7 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add x4, x0, x1, lsr #3 // end_input_ptr + ldr q24, [x8, #96] // load rk6 + lsr x12, x11, #32 + ldr q23, [x8, #80] // load rk5 + orr w11, w11, w11 + ldr q21, [x8, #48] // load rk3 + add x5, x5, x0 + rev w12, w12 // rev_ctr32 + add w12, w12, #1 // increment rev_ctr32 + fmov d3, x10 // CTR block 3 + rev w9, w12 // CTR block 1 + add w12, w12, #1 // CTR block 1 + fmov d1, x10 // CTR block 1 + orr x9, x11, x9, lsl #32 // CTR block 1 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + fmov d2, x10 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 3 + ldr q18, [x8, #0] // load rk0 + fmov v3.d[1], x9 // CTR block 3 + add w12, w12, #1 // CTR block 3 + ldr q22, [x8, #64] // load rk4 + ldr q19, [x8, #16] // load rk1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q20, [x8, #32] // load rk2 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q27, [x8, #144] // load rk9 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q28, [x8, #160] // load rk10 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + ldr q29, [x8, #176] // load rk11 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + b.lt Ldec_finish_first_blocks // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + b.eq Ldec_finish_first_blocks // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Ldec_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v2.16b, v31.16b // AES block 2 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + aese v3.16b, v31.16b // AES block 3 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + b.ge Ldec_tail // handle tail + + ldr q4, [x0, #0] // AES block 0 - load ciphertext + ldr q5, [x0, #16] // AES block 1 - load ciphertext + rev w9, w12 // CTR block 4 + eor v0.16b, v4.16b, v0.16b // AES block 0 - result + eor v1.16b, v5.16b, v1.16b // AES block 1 - result + rev64 v5.16b, v5.16b // GHASH block 1 + ldr q7, [x0, #48] // AES block 3 - load ciphertext + mov x7, v0.d[1] // AES block 0 - mov high + mov x6, v0.d[0] // AES block 0 - mov low + rev64 v4.16b, v4.16b // GHASH block 0 + add w12, w12, #1 // CTR block 4 + fmov d0, x10 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + mov x19, v1.d[0] // AES block 1 - mov low + orr x9, x11, x9, lsl #32 // CTR block 5 + mov x20, v1.d[1] // AES block 1 - mov high + eor x7, x7, x14 // AES block 0 - round N high + eor x6, x6, x13 // AES block 0 - round N low + stp x6, x7, [x2], #16 // AES block 0 - store result + fmov d1, x10 // CTR block 5 + ldr q6, [x0, #32] // AES block 2 - load ciphertext + add x0, x0, #64 // AES input_ptr update + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + add w12, w12, #1 // CTR block 6 + eor x19, x19, x13 // AES block 1 - round N low + orr x9, x11, x9, lsl #32 // CTR block 6 + eor x20, x20, x14 // AES block 1 - round N high + stp x19, x20, [x2], #16 // AES block 1 - store result + eor v2.16b, v6.16b, v2.16b // AES block 2 - result + cmp x0, x5 // check if we have <= 8 blocks + b.ge Ldec_prepretail // do prepretail + +Ldec_main_loop: // main loop start + mov x21, v2.d[0] // AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev w9, w12 // CTR block 4k+7 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x23, v3.d[0] // AES block 4k+3 - mov low + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov v3.d[1], x9 // CTR block 4k+7 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor x22, x22, x14 // AES block 4k+2 - round N high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x21, x21, x13 // AES block 4k+2 - round N low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor x23, x23, x13 // AES block 4k+3 - round N low + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor x24, x24, x14 // AES block 4k+3 - round N high + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + add w12, w12, #1 // CTR block 4k+7 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + rev w9, w12 // CTR block 4k+8 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + add w12, w12, #1 // CTR block 4k+8 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + b.lt Ldec_main_loop_continue // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Ldec_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_main_loop_continue: + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + ldr q4, [x0, #0] // AES block 4k+4 - load ciphertext + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + ldr q5, [x0, #16] // AES block 4k+5 - load ciphertext + eor v0.16b, v4.16b, v0.16b // AES block 4k+4 - result + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + ldr q7, [x0, #48] // AES block 4k+7 - load ciphertext + ldr q6, [x0, #32] // AES block 4k+6 - load ciphertext + mov x7, v0.d[1] // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + add x0, x0, #64 // AES input_ptr update + mov x6, v0.d[0] // AES block 4k+4 - mov low + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b // AES block 4k+5 - result + rev w9, w12 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + cmp x0, x5 // LOOP CONTROL + add w12, w12, #1 // CTR block 4k+9 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + mov x20, v1.d[1] // AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b // AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + mov x19, v1.d[0] // AES block 4k+5 - mov low + fmov d1, x10 // CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + fmov v1.d[1], x9 // CTR block 4k+9 + rev w9, w12 // CTR block 4k+10 + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + rev64 v5.16b, v5.16b // GHASH block 4k+5 + eor x20, x20, x14 // AES block 4k+5 - round N high + stp x6, x7, [x2], #16 // AES block 4k+4 - store result + eor x19, x19, x13 // AES block 4k+5 - round N low + stp x19, x20, [x2], #16 // AES block 4k+5 - store result + rev64 v4.16b, v4.16b // GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + b.lt Ldec_main_loop + +Ldec_prepretail: // PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + mov x21, v2.d[0] // AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + rev w9, w12 // CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + mov x23, v3.d[0] // AES block 4k+3 - mov low + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + fmov v3.d[1], x9 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + b.lt Ldec_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + b.eq Ldec_finish_prepretail // branch if AES-192 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_finish_prepretail: + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor x22, x22, x14 // AES block 4k+2 - round N high + eor x23, x23, x13 // AES block 4k+3 - round N low + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + add w12, w12, #1 // CTR block 4k+7 + eor x21, x21, x13 // AES block 4k+2 - round N low + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor x24, x24, x14 // AES block 4k+3 - round N high + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + +Ldec_tail: // TAIL + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 // AES block 4k+4 - load ciphertext + eor v0.16b, v5.16b, v0.16b // AES block 4k+4 - result + mov x6, v0.d[0] // AES block 4k+4 - mov low + mov x7, v0.d[1] // AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + cmp x5, #48 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + b.gt Ldec_blocks_more_than_3 + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + movi v11.8b, #0 + cmp x5, #32 + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt Ldec_blocks_more_than_2 + sub w12, w12, #1 + mov v3.16b, v1.16b + cmp x5, #16 + b.gt Ldec_blocks_more_than_1 + sub w12, w12, #1 + b Ldec_blocks_less_than_1 +Ldec_blocks_more_than_3: // blocks left > 3 + rev64 v4.16b, v5.16b // GHASH final-3 block + ld1 { v5.16b}, [x0], #16 // AES final-2 block - load ciphertext + stp x6, x7, [x2], #16 // AES final-3 block - store result + mov d10, v17.d[1] // GHASH final-3 block - mid + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor v0.16b, v5.16b, v1.16b // AES final-2 block - result + mov d22, v4.d[1] // GHASH final-3 block - mid + mov x6, v0.d[0] // AES final-2 block - mov low + mov x7, v0.d[1] // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor x6, x6, x13 // AES final-2 block - round N low + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + eor x7, x7, x14 // AES final-2 block - round N high +Ldec_blocks_more_than_2: // blocks left > 2 + rev64 v4.16b, v5.16b // GHASH final-2 block + ld1 { v5.16b}, [x0], #16 // AES final-1 block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + stp x6, x7, [x2], #16 // AES final-2 block - store result + eor v0.16b, v5.16b, v2.16b // AES final-1 block - result + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + mov x6, v0.d[0] // AES final-1 block - mov low + mov x7, v0.d[1] // AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + movi v8.8b, #0 // suppress further partial tag feed in + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + eor x6, x6, x13 // AES final-1 block - round N low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid + eor x7, x7, x14 // AES final-1 block - round N high +Ldec_blocks_more_than_1: // blocks left > 1 + stp x6, x7, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ld1 { v5.16b}, [x0], #16 // AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + mov d22, v4.d[1] // GHASH final-1 block - mid + eor v0.16b, v5.16b, v3.16b // AES final block - result + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + mov x6, v0.d[0] // AES final block - mov low + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + mov x7, v0.d[1] // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + eor x6, x6, x13 // AES final block - round N low + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor x7, x7, x14 // AES final block - round N high +Ldec_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x14, xzr // rkN_h = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + ldp x4, x5, [x2] // load existing bytes we need to not overwrite + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + fmov d0, x9 // ctr0b is mask for last block + and x6, x6, x9 + mov v0.d[1], x10 + bic x4, x4, x9 // mask out low existing bytes + rev w9, w12 + bic x5, x5, x10 // mask out high existing bytes + orr x6, x6, x4 + and x7, x7, x10 + orr x7, x7, x5 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + mov d8, v4.d[1] // GHASH final block - mid + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + stp x6, x7, [x2] + str w9, [x16, #12] // store the updated counter + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/armv8-mont.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/armv8-mont-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/armv8-mont.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/armv8-mont-apple.S index 2493ae08..9f1b8105 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/armv8-mont.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/armv8-mont-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1430,4 +1430,8 @@ Lmul4x_done: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 4 -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/bn-armv8-apple.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/bn-armv8-apple.S new file mode 100644 index 00000000..9334ed42 --- /dev/null +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/bn-armv8-apple.S @@ -0,0 +1,101 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl _bn_add_words +.private_extern _bn_add_words +.align 4 +_bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Ladd_tail +Ladd_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + adcs x4, x4, x6 + adcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Ladd_loop + +Ladd_tail: + cbz x3, Ladd_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + adcs x4, x4, x6 + str x4, [x0], #8 + +Ladd_exit: + cset x0, cs + ret + + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl _bn_sub_words +.private_extern _bn_sub_words +.align 4 +_bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Lsub_tail +Lsub_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + sbcs x4, x4, x6 + sbcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Lsub_loop + +Lsub_tail: + cbz x3, Lsub_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + sbcs x4, x4, x6 + str x4, [x0], #8 + +Lsub_exit: + cset x0, cc + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghash-neon-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghash-neon-armv8-apple.S similarity index 97% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghash-neon-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghash-neon-armv8-apple.S index 5441afc0..d4cc16f7 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghash-neon-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghash-neon-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -340,4 +340,8 @@ Lmasks: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghashv8-armv8-apple.S similarity index 96% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghashv8-armv8-apple.S index dcef3c56..829c1e17 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/ghashv8-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -119,7 +119,7 @@ _gcm_gmult_v8: movi v19.16b,#0xe1 ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... shl v19.2d,v19.2d,#57 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v3.16b,v17.16b,v17.16b,#8 @@ -144,7 +144,7 @@ _gcm_gmult_v8: eor v18.16b,v18.16b,v2.16b eor v0.16b,v0.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -183,14 +183,14 @@ _gcm_ghash_v8: ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi ld1 {v16.2d},[x2],#16 //load [rotated] I[0] shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b rev64 v0.16b,v0.16b #endif ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] b.lo Lodd_tail_v8 //x3 was less than 32 ld1 {v17.2d},[x2],x12 //load [rotated] I[1] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v7.16b,v17.16b,v17.16b,#8 @@ -222,13 +222,13 @@ Loop_mod2x_v8: eor v18.16b,v0.16b,v2.16b eor v1.16b,v1.16b,v17.16b ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b #endif eor v1.16b,v1.16b,v18.16b pmull v18.1q,v0.1d,v19.1d //1st phase of reduction -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ins v2.d[0],v1.d[1] @@ -278,7 +278,7 @@ Lodd_tail_v8: eor v0.16b,v0.16b,v18.16b Ldone_v8: -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -297,7 +297,7 @@ Lgcm_ghash_v8_4x: shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b @@ -341,7 +341,7 @@ Loop4x: eor v16.16b,v4.16b,v0.16b ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 ext v3.16b,v16.16b,v16.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v7.16b,v7.16b @@ -424,7 +424,7 @@ Lthree: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d,v6.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v4.16b,v4.16b @@ -476,7 +476,7 @@ Ltwo: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v4.16b,v4.16b #endif @@ -519,7 +519,7 @@ Lone: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v4.16b,v4.16b #endif @@ -559,7 +559,7 @@ Ldone4x: eor v0.16b,v0.16b,v18.16b ext v0.16b,v0.16b,v0.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif st1 {v0.2d},[x0] //write out Xi @@ -570,4 +570,8 @@ Ldone4x: .align 2 .align 2 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256-armv8-asm-apple.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256-armv8-asm-apple.S new file mode 100644 index 00000000..b18602f9 --- /dev/null +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256-armv8-asm-apple.S @@ -0,0 +1,1738 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.section __TEXT,__const +.align 5 +Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +Lone: +.quad 1,0,0,0 +Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.text + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl _ecp_nistz256_mul_mont +.private_extern _ecp_nistz256_mul_mont + +.align 4 +_ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_sqr_mont +.private_extern _ecp_nistz256_sqr_mont + +.align 4 +_ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_div_by_2 +.private_extern _ecp_nistz256_div_by_2 + +.align 4 +_ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_mul_by_2 +.private_extern _ecp_nistz256_mul_by_2 + +.align 4 +_ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_mul_by_3 +.private_extern _ecp_nistz256_mul_by_3 + +.align 4 +_ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl _ecp_nistz256_sub +.private_extern _ecp_nistz256_sub + +.align 4 +_ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl _ecp_nistz256_neg +.private_extern _ecp_nistz256_neg + +.align 4 +_ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 + +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 + +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... + +.align 4 +__ecp_nistz256_add_to: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + + +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret + +.globl _ecp_nistz256_point_double +.private_extern _ecp_nistz256_point_double + +.align 5 +_ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + mov x8,x14 + ldr x13,[x13,#24] + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _ecp_nistz256_point_add +.private_extern _ecp_nistz256_point_add + +.align 5 +_ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b Ldouble_shortcut + +.align 4 +Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl _ecp_nistz256_point_add_affine +.private_extern _ecp_nistz256_point_add_affine + +.align 5 +_ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,Lpoly@PAGE + add x13,x13,Lpoly@PAGEOFF + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adrp x23,Lone_mont@PAGE-64 + add x23,x23,Lone_mont@PAGEOFF-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl _ecp_nistz256_ord_mul_mont +.private_extern _ecp_nistz256_ord_mul_mont + +.align 4 +_ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,Lord@PAGE + add x23,x23,Lord@PAGEOFF + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl _ecp_nistz256_ord_sqr_mont +.private_extern _ecp_nistz256_ord_sqr_mont + +.align 4 +_ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,Lord@PAGE + add x23,x23,Lord@PAGEOFF + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b Loop_ord_sqr + +.align 4 +Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl _ecp_nistz256_select_w5 +.private_extern _ecp_nistz256_select_w5 + +.align 4 +_ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // x10 := x0 + // w9 := 0; loop counter and incremented internal index + mov x10, x0 + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + movi v20.16b, #0 + movi v21.16b, #0 + +Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v27] := Load a (3*256-bit = 6*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // continue loading ... + ld1 {v26.2d, v27.2d}, [x1],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + bit v20.16b, v26.16b, v3.16b + bit v21.16b, v27.16b, v3.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz w9, #4, Lselect_w5_loop + + // Write [v16-v21] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x10],#64 + st1 {v20.2d, v21.2d}, [x10] + + ret + + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl _ecp_nistz256_select_w7 +.private_extern _ecp_nistz256_select_w7 + +.align 4 +_ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // w9 := 0; loop counter and incremented internal index + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + +Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v25] := Load a (2*256-bit = 4*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz w9, #6, Lselect_w7_loop + + // Write [v16-v19] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x0] + + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-apple.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-apple.S new file mode 100644 index 00000000..8214e116 --- /dev/null +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-apple.S @@ -0,0 +1,321 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.text +.globl _beeu_mod_inverse_vartime +.private_extern _beeu_mod_inverse_vartime + +.align 4 +_beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp x25,x26,[x1] + ldp x27,x28,[x1,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp x0,x1,[x2] + ldp x2,x30,[x2,#16] + + // A = a3..a0 := n + mov x21, x0 + mov x22, x1 + mov x23, x2 + mov x24, x30 + + // X = x4..x0 := 1 + mov x3, #1 + eor x4, x4, x4 + eor x5, x5, x5 + eor x6, x6, x6 + eor x7, x7, x7 + + // Y = y4..y0 := 0 + eor x8, x8, x8 + eor x9, x9, x9 + eor x10, x10, x10 + eor x11, x11, x11 + eor x12, x12, x12 + +Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + orr x14, x25, x26 + orr x14, x14, x27 + + // reverse the bit order of x25. This is needed for clz after this macro + rbit x15, x25 + + orr x14, x14, x28 + cbz x14,Lbeeu_loop_end + + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in x25 + // ( = number of leading 0s in x15; see the "rbit" instruction in TEST_B_ZERO) + clz x13, x15 + + // If there is no shift, goto shift_A_Y + cbz x13, Lbeeu_shift_A_Y + + // Shift B right by "x13" bits + neg x14, x13 + lsr x25, x25, x13 + lsl x15, x26, x14 + + lsr x26, x26, x13 + lsl x19, x27, x14 + + orr x25, x25, x15 + + lsr x27, x27, x13 + lsl x20, x28, x14 + + orr x26, x26, x19 + + lsr x28, x28, x13 + + orr x27, x27, x20 + + + // Shift X right by "x13" bits, adding n whenever X becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_X: + tbz x3, #0, Lshift1_0 + adds x3, x3, x0 + adcs x4, x4, x1 + adcs x5, x5, x2 + adcs x6, x6, x30 + adc x7, x7, x14 +Lshift1_0: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x3, x4, x3, #1 + extr x4, x5, x4, #1 + extr x5, x6, x5, #1 + extr x6, x7, x6, #1 + lsr x7, x7, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "x13" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and x13 is decreased while executing the X loop. + // - SHIFT256(B, x13) is performed before right-shifting X; they are independent + +Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of x21 + // x13 := number of trailing 0s in x21 (= number of leading 0s in x15) + rbit x15, x21 + clz x13, x15 + + // If there is no shift, goto |B-A|, X+Y update + cbz x13, Lbeeu_update_B_X_or_A_Y + + // Shift A right by "x13" bits + neg x14, x13 + lsr x21, x21, x13 + lsl x15, x22, x14 + + lsr x22, x22, x13 + lsl x19, x23, x14 + + orr x21, x21, x15 + + lsr x23, x23, x13 + lsl x20, x24, x14 + + orr x22, x22, x19 + + lsr x24, x24, x13 + + orr x23, x23, x20 + + + // Shift Y right by "x13" bits, adding n whenever Y becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_Y: + tbz x8, #0, Lshift1_1 + adds x8, x8, x0 + adcs x9, x9, x1 + adcs x10, x10, x2 + adcs x11, x11, x30 + adc x12, x12, x14 +Lshift1_1: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x8, x9, x8, #1 + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_Y + +Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs x14, x25, x21 + sbcs x15, x26, x22 + sbcs x19, x27, x23 + sbcs x20, x28, x24 + bcs Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs x21, x21, x25 + sbcs x22, x22, x26 + sbcs x23, x23, x27 + sbcs x24, x24, x28 + + adds x8, x8, x3 + adcs x9, x9, x4 + adcs x10, x10, x5 + adcs x11, x11, x6 + adc x12, x12, x7 + b Lbeeu_loop + +Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov x25, x14 + mov x26, x15 + mov x27, x19 + mov x28, x20 + + adds x3, x3, x8 + adcs x4, x4, x9 + adcs x5, x5, x10 + adcs x6, x6, x11 + adc x7, x7, x12 + b Lbeeu_loop + +Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub x14, x21, #1 + orr x14, x14, x22 + orr x14, x14, x23 + orr x14, x14, x24 + cbnz x14, Lbeeu_err + + // If Y>n ==> Y:=Y-n +Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // (x14 = 0 from above) + subs x3, x8, x0 + sbcs x4, x9, x1 + sbcs x5, x10, x2 + sbcs x6, x11, x30 + sbcs x7, x12, x14 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel x8, x3, x8, cs + csel x9, x4, x9, cs + csel x10, x5, x10, cs + csel x11, x6, x11, cs + csel x12, x7, x12, cs + bcs Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs x8, x0, x8 + sbcs x9, x1, x9 + sbcs x10, x2, x10 + sbcs x11, x30, x11 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp x8, x9, [x3] + stp x10, x11, [x3,#16] + // return 1 (success) + mov x0, #1 + b Lbeeu_finish + +Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha1-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha1-armv8-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha1-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha1-armv8-apple.S index 05eb9201..94c4fc58 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha1-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha1-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -51,7 +51,7 @@ Loop: movz w28,#0x7999 sub x2,x2,#1 movk w28,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x3,x3,#32 #else rev32 x3,x3 @@ -69,7 +69,7 @@ Loop: ror w21,w21,#2 add w23,w23,w4 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x5,x5,#32 #else rev32 x5,x5 @@ -94,7 +94,7 @@ Loop: ror w24,w24,#2 add w21,w21,w6 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x7,x7,#32 #else rev32 x7,x7 @@ -119,7 +119,7 @@ Loop: ror w22,w22,#2 add w24,w24,w8 // future e+=X[i] add w20,w20,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x9,x9,#32 #else rev32 x9,x9 @@ -144,7 +144,7 @@ Loop: ror w20,w20,#2 add w22,w22,w10 // future e+=X[i] add w23,w23,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x11,x11,#32 #else rev32 x11,x11 @@ -169,7 +169,7 @@ Loop: ror w23,w23,#2 add w20,w20,w12 // future e+=X[i] add w21,w21,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x13,x13,#32 #else rev32 x13,x13 @@ -194,7 +194,7 @@ Loop: ror w21,w21,#2 add w23,w23,w14 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x15,x15,#32 #else rev32 x15,x15 @@ -219,7 +219,7 @@ Loop: ror w24,w24,#2 add w21,w21,w16 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x17,x17,#32 #else rev32 x17,x17 @@ -1232,4 +1232,8 @@ Lconst: .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha256-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha256-armv8-apple.S similarity index 97% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha256-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha256-armv8-apple.S index c9b79916..f4a5283c 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha256-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha256-armv8-apple.S @@ -8,11 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -48,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -100,7 +101,7 @@ Loop: ldr w19,[x30],#4 // *K++ eor w28,w21,w22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w3,w3 // 0 #endif ror w16,w24,#6 @@ -123,7 +124,7 @@ Loop: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w4,w4 // 1 #endif ldp w5,w6,[x1],#2*4 @@ -148,7 +149,7 @@ Loop: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w5,w5 // 2 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -172,7 +173,7 @@ Loop: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w6,w6 // 3 #endif ldp w7,w8,[x1],#2*4 @@ -197,7 +198,7 @@ Loop: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w7,w7 // 4 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -221,7 +222,7 @@ Loop: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8,w8 // 5 #endif ldp w9,w10,[x1],#2*4 @@ -246,7 +247,7 @@ Loop: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w9,w9 // 6 #endif add w22,w22,w17 // h+=Sigma0(a) @@ -270,7 +271,7 @@ Loop: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w10,w10 // 7 #endif ldp w11,w12,[x1],#2*4 @@ -295,7 +296,7 @@ Loop: add w20,w20,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w20,w20,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w11,w11 // 8 #endif add w20,w20,w17 // h+=Sigma0(a) @@ -319,7 +320,7 @@ Loop: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w12,w12 // 9 #endif ldp w13,w14,[x1],#2*4 @@ -344,7 +345,7 @@ Loop: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w13,w13 // 10 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -368,7 +369,7 @@ Loop: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w14,w14 // 11 #endif ldp w15,w0,[x1],#2*4 @@ -394,7 +395,7 @@ Loop: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w15,w15 // 12 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -419,7 +420,7 @@ Loop: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w0,w0 // 13 #endif ldp w1,w2,[x1] @@ -445,7 +446,7 @@ Loop: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w1,w1 // 14 #endif ldr w6,[sp,#12] @@ -471,7 +472,7 @@ Loop: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w2,w2 // 15 #endif ldr w7,[sp,#0] @@ -1208,4 +1209,8 @@ Loop_hw: ret #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha512-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha512-armv8-apple.S similarity index 60% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha512-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha512-armv8-apple.S index 97b3230e..d005b0d0 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/sha512-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/sha512-armv8-apple.S @@ -8,11 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -48,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -64,6 +65,17 @@ .align 6 _sha512_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:_OPENSSL_armcap_P +#else + adrp x16,_OPENSSL_armcap_P@PAGE +#endif + ldr w16,[x16,_OPENSSL_armcap_P@PAGEOFF] + tst w16,#ARMV8_SHA512 + b.ne Lv8_entry +#endif AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -89,7 +101,7 @@ Loop: ldr x19,[x30],#8 // *K++ eor x28,x21,x22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x3,x3 // 0 #endif ror x16,x24,#14 @@ -112,7 +124,7 @@ Loop: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x4,x4 // 1 #endif ldp x5,x6,[x1],#2*8 @@ -137,7 +149,7 @@ Loop: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x5,x5 // 2 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -161,7 +173,7 @@ Loop: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x6,x6 // 3 #endif ldp x7,x8,[x1],#2*8 @@ -186,7 +198,7 @@ Loop: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x7,x7 // 4 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -210,7 +222,7 @@ Loop: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x8,x8 // 5 #endif ldp x9,x10,[x1],#2*8 @@ -235,7 +247,7 @@ Loop: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x9,x9 // 6 #endif add x22,x22,x17 // h+=Sigma0(a) @@ -259,7 +271,7 @@ Loop: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x10,x10 // 7 #endif ldp x11,x12,[x1],#2*8 @@ -284,7 +296,7 @@ Loop: add x20,x20,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x20,x20,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x11,x11 // 8 #endif add x20,x20,x17 // h+=Sigma0(a) @@ -308,7 +320,7 @@ Loop: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x12,x12 // 9 #endif ldp x13,x14,[x1],#2*8 @@ -333,7 +345,7 @@ Loop: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x13,x13 // 10 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -357,7 +369,7 @@ Loop: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x14,x14 // 11 #endif ldp x15,x0,[x1],#2*8 @@ -383,7 +395,7 @@ Loop: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x15,x15 // 12 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -408,7 +420,7 @@ Loop: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x0,x0 // 13 #endif ldp x1,x2,[x1] @@ -434,7 +446,7 @@ Loop: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x1,x1 // 14 #endif ldr x6,[sp,#24] @@ -460,7 +472,7 @@ Loop: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x2,x2 // 15 #endif ldr x7,[sp,#0] @@ -1078,4 +1090,529 @@ LK512: .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#endif // !OPENSSL_NO_ASM +.text +#ifndef __KERNEL__ + +.align 6 +sha512_block_armv8: +Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adrp x3,LK512@PAGE + add x3,x3,LK512@PAGEOFF + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b Loop_hw + +.align 4 +Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret + +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/vpaes-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/vpaes-armv8-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/vpaes-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/vpaes-armv8-apple.S index 6dfc25d9..3beb563d 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/fipsmodule/vpaes-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/fipsmodule/vpaes-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1229,4 +1229,8 @@ Lctr32_done: AARCH64_VALIDATE_LINK_REGISTER ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-aarch64/crypto/test/trampoline-armv8.S b/third_party/boringssl/kit/apple-aarch64/crypto/test/trampoline-armv8-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-aarch64/crypto/test/trampoline-armv8.S rename to third_party/boringssl/kit/apple-aarch64/crypto/test/trampoline-armv8-apple.S index 325da9b1..5e1b1ee1 100644 --- a/third_party/boringssl/kit/ios-aarch64/crypto/test/trampoline-armv8.S +++ b/third_party/boringssl/kit/apple-aarch64/crypto/test/trampoline-armv8-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -755,4 +755,8 @@ _abi_test_clobber_v15_upper: fmov v15.d[1], xzr ret -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/chacha/chacha-armv4.S b/third_party/boringssl/kit/apple-arm/crypto/chacha/chacha-armv4-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/chacha/chacha-armv4.S rename to third_party/boringssl/kit/apple-arm/crypto/chacha/chacha-armv4-apple.S index cadf2b62..c42b0d22 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/chacha/chacha-armv4.S +++ b/third_party/boringssl/kit/apple-arm/crypto/chacha/chacha-armv4-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1495,4 +1495,8 @@ OPENSSL_armcap_P: .indirect_symbol _OPENSSL_armcap_P .long 0 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/aesv8-armx32.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/aesv8-armv7-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/aesv8-armx32.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/aesv8-armv7-apple.S index 87b4b0ae..3695e57c 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/aesv8-armx32.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/aesv8-armv7-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -806,4 +806,8 @@ Lctr32_done: ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/armv4-mont.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/armv4-mont-apple.S similarity index 98% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/armv4-mont.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/armv4-mont-apple.S index e549d1f1..a552fb57 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/armv4-mont.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/armv4-mont-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -979,4 +979,8 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/bsaes-armv7.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/bsaes-armv7-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/bsaes-armv7.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/bsaes-armv7-apple.S index 8329a8c2..a72b437b 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/bsaes-armv7.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/bsaes-armv7-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1533,4 +1533,8 @@ Lctr_enc_bzero:@ wipe key schedule [if any] @ out to retain a constant-time implementation. #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghash-armv4.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghash-armv4-apple.S similarity index 96% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghash-armv4.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghash-armv4-apple.S index 36f4cceb..762ada8f 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghash-armv4.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghash-armv4-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -255,4 +255,8 @@ Lgmult_neon: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghashv8-armx32.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghashv8-armv7-apple.S similarity index 96% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghashv8-armx32.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghashv8-armv7-apple.S index dcac580e..36d8937c 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/ghashv8-armx32.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/ghashv8-armv7-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -257,4 +257,8 @@ Ldone_v8: .align 2 .align 2 #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha1-armv4-large.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha1-armv4-large-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha1-armv4-large.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha1-armv4-large-apple.S index 82ac8df4..fc0a2627 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha1-armv4-large.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha1-armv4-large-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1515,4 +1515,8 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha256-armv4.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha256-armv4-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha256-armv4.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha256-armv4-apple.S index 0cf36482..26e58cf7 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha256-armv4.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha256-armv4-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2843,4 +2843,8 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha512-armv4.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha512-armv4-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha512-armv4.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha512-armv4-apple.S index 21913cb2..95ff7743 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/sha512-armv4.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/sha512-armv4-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1896,4 +1896,8 @@ OPENSSL_armcap_P: .long 0 .private_extern _OPENSSL_armcap_P #endif -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/vpaes-armv7.S b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/vpaes-armv7-apple.S similarity index 99% rename from third_party/boringssl/kit/ios-arm/crypto/fipsmodule/vpaes-armv7.S rename to third_party/boringssl/kit/apple-arm/crypto/fipsmodule/vpaes-armv7-apple.S index 6aead7ca..31690229 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/fipsmodule/vpaes-armv7.S +++ b/third_party/boringssl/kit/apple-arm/crypto/fipsmodule/vpaes-armv7-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1262,4 +1262,8 @@ Lctr32_done: vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/ios-arm/crypto/test/trampoline-armv4.S b/third_party/boringssl/kit/apple-arm/crypto/test/trampoline-armv4-apple.S similarity index 96% rename from third_party/boringssl/kit/ios-arm/crypto/test/trampoline-armv4.S rename to third_party/boringssl/kit/apple-arm/crypto/test/trampoline-armv4-apple.S index 9d74f553..2516f66a 100644 --- a/third_party/boringssl/kit/ios-arm/crypto/test/trampoline-armv4.S +++ b/third_party/boringssl/kit/apple-arm/crypto/test/trampoline-armv4-apple.S @@ -8,7 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -373,4 +373,8 @@ _abi_test_clobber_d15: vmov s31, r0 bx lr -#endif // !OPENSSL_NO_ASM +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/chacha/chacha-x86.S b/third_party/boringssl/kit/apple-x86/crypto/chacha/chacha-x86-apple.S similarity index 98% rename from third_party/boringssl/kit/mac-x86/crypto/chacha/chacha-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/chacha/chacha-x86-apple.S index ef535b21..8d0de1db 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/chacha/chacha-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/chacha/chacha-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -971,4 +977,8 @@ Lssse3_data: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/aesni-x86.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/aesni-x86-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/aesni-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/aesni-x86-apple.S index 00f6003d..8a55e3fd 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/aesni-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/aesni-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2473,4 +2479,8 @@ Lkey_const: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/bn-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/bn-586-apple.S similarity index 97% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/bn-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/bn-586-apple.S index ede2e76d..a169595a 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/bn-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/bn-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -985,4 +991,8 @@ L028aw_end: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/co-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/co-586-apple.S similarity index 98% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/co-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/co-586-apple.S index 015dffaa..0d4554c2 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/co-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/co-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1254,4 +1260,8 @@ L_bn_sqr_comba4_begin: popl %edi popl %esi ret +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-ssse3-x86.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-ssse3-x86-apple.S similarity index 93% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-ssse3-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-ssse3-x86-apple.S index 86566790..9d3bac5c 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-ssse3-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-ssse3-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -286,4 +292,8 @@ Lreverse_bytes: .align 4,0x90 Llow4_mask: .long 252645135,252645135,252645135,252645135 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-x86.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-x86-apple.S similarity index 94% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-x86-apple.S index c1e0d539..e39452fa 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/ghash-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/ghash-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -320,4 +326,8 @@ Lbswap: .byte 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 .byte 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 .byte 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/md5-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/md5-586-apple.S similarity index 96% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/md5-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/md5-586-apple.S index f4c4b50c..7ff200e0 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/md5-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/md5-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -682,4 +688,8 @@ L000start: popl %edi popl %esi ret +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha1-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha1-586-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha1-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha1-586-apple.S index 3213a621..8951d0c6 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha1-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha1-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -3802,4 +3808,8 @@ LK_XX_XX: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha256-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha256-586-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha256-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha256-586-apple.S index c81cb9af..b9afaf00 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha256-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha256-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -5565,4 +5571,8 @@ L013avx_00_47: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha512-586.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha512-586-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha512-586.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha512-586-apple.S index 8c33cf59..b3a53f3a 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/sha512-586.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/sha512-586-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2835,4 +2841,8 @@ L001K512: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/vpaes-x86.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/vpaes-x86-apple.S similarity index 97% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/vpaes-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/vpaes-x86-apple.S index 00c0190d..476529a1 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/vpaes-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/vpaes-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -678,4 +684,8 @@ L022cbc_abort: popl %ebx popl %ebp ret +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/x86-mont.S b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/x86-mont-apple.S similarity index 95% rename from third_party/boringssl/kit/mac-x86/crypto/fipsmodule/x86-mont.S rename to third_party/boringssl/kit/apple-x86/crypto/fipsmodule/x86-mont-apple.S index 7850a37a..a977cec2 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/fipsmodule/x86-mont.S +++ b/third_party/boringssl/kit/apple-x86/crypto/fipsmodule/x86-mont-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -482,4 +488,8 @@ L000just_leave: L_OPENSSL_ia32cap_P$non_lazy_ptr: .indirect_symbol _OPENSSL_ia32cap_P .long 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86/crypto/test/trampoline-x86.S b/third_party/boringssl/kit/apple-x86/crypto/test/trampoline-x86-apple.S similarity index 90% rename from third_party/boringssl/kit/mac-x86/crypto/test/trampoline-x86.S rename to third_party/boringssl/kit/apple-x86/crypto/test/trampoline-x86-apple.S index fd40b957..17d84feb 100644 --- a/third_party/boringssl/kit/mac-x86/crypto/test/trampoline-x86.S +++ b/third_party/boringssl/kit/apple-x86/crypto/test/trampoline-x86-apple.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -166,4 +172,8 @@ _abi_test_clobber_xmm7: L_abi_test_clobber_xmm7_begin: pxor %xmm7,%xmm7 ret +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__APPLE__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/chacha/chacha-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/chacha/chacha-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/chacha/chacha-x86_64-apple.S index 782ddf4b..583c4e37 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/chacha/chacha-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/chacha/chacha-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -15,6 +15,7 @@ +.section __DATA,__const .p2align 6 L$zero: .long 0,0,0,0 @@ -44,6 +45,7 @@ L$incz: L$sixteen: .long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .globl _ChaCha20_ctr32 .private_extern _ChaCha20_ctr32 @@ -1623,3 +1625,7 @@ L$8x_epilogue: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-apple.S index f988089d..cd6d6a79 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-apple.S @@ -7,11 +7,11 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif -.data +.section __DATA,__const .p2align 4 one: @@ -3066,3 +3066,7 @@ _aes256gcmsiv_kdf: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-apple.S index 6813510c..5f04f7fd 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -16,6 +16,7 @@ chacha20_poly1305_constants: +.section __DATA,__const .p2align 6 L$chacha20_consts: .byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' @@ -53,6 +54,7 @@ L$and_masks: .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +.text .p2align 6 @@ -8876,3 +8878,7 @@ L$seal_avx2_exit: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-apple.S similarity index 95% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-apple.S index e497c35f..08e2830e 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -221,7 +221,7 @@ L$resume_ctr32: movbeq 0(%r14),%r12 vaesenc %xmm1,%xmm14,%xmm14 vmovups 160-128(%rcx),%xmm1 - cmpl $11,%ebp + cmpl $11,%r10d jb L$enc_tail vaesenc %xmm15,%xmm9,%xmm9 @@ -305,6 +305,9 @@ L$enc_tail: vpaddb %xmm2,%xmm1,%xmm0 movq %r13,112+8(%rsp) leaq 96(%rdi),%rdi + + prefetcht0 512(%rdi) + prefetcht0 576(%rdi) vaesenclast %xmm5,%xmm11,%xmm11 vpaddb %xmm2,%xmm0,%xmm5 movq %r12,120+8(%rsp) @@ -317,7 +320,7 @@ L$enc_tail: vaesenclast %xmm3,%xmm14,%xmm14 vpaddb %xmm2,%xmm7,%xmm3 - addq $0x60,%r10 + addq $0x60,%rax subq $0x6,%rdx jc L$6x_done @@ -349,41 +352,49 @@ L$6x_done: .p2align 5 _aesni_gcm_decrypt: - xorq %r10,%r10 + + xorq %rax,%rax cmpq $0x60,%rdx jb L$gcm_dec_abort - leaq (%rsp),%rax + pushq %rbp + + + movq %rsp,%rbp pushq %rbx - pushq %rbp pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + vzeroupper + movq 16(%rbp),%r12 vmovdqu (%r8),%xmm1 addq $-128,%rsp movl 12(%r8),%ebx leaq L$bswap_mask(%rip),%r11 leaq -128(%rcx),%r14 movq $0xf80,%r15 - vmovdqu (%r9),%xmm8 + vmovdqu (%r12),%xmm8 andq $-128,%rsp vmovdqu (%r11),%xmm0 leaq 128(%rcx),%rcx - leaq 32+32(%r9),%r9 - movl 240-128(%rcx),%ebp + leaq 32(%r9),%r9 + movl 240-128(%rcx),%r10d vpshufb %xmm0,%xmm8,%xmm8 andq %r15,%r14 @@ -396,7 +407,7 @@ _aesni_gcm_decrypt: L$dec_no_key_aliasing: vmovdqu 80(%rdi),%xmm7 - leaq (%rdi),%r14 + movq %rdi,%r14 vmovdqu 64(%rdi),%xmm4 @@ -409,7 +420,7 @@ L$dec_no_key_aliasing: vmovdqu 48(%rdi),%xmm5 shrq $4,%rdx - xorq %r10,%r10 + xorq %rax,%rax vmovdqu 32(%rdi),%xmm6 vpshufb %xmm0,%xmm7,%xmm7 vmovdqu 16(%rdi),%xmm2 @@ -427,6 +438,7 @@ L$dec_no_key_aliasing: call _aesni_ctr32_ghash_6x + movq 16(%rbp),%r12 vmovups %xmm9,-96(%rsi) vmovups %xmm10,-80(%rsi) vmovups %xmm11,-64(%rsi) @@ -435,35 +447,35 @@ L$dec_no_key_aliasing: vmovups %xmm14,-16(%rsi) vpshufb (%r11),%xmm8,%xmm8 - vmovdqu %xmm8,-64(%r9) + vmovdqu %xmm8,(%r12) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp - movq -40(%rax),%r14 + popq %r15 - movq -32(%rax),%r13 + popq %r14 - movq -24(%rax),%r12 + popq %r13 - movq -16(%rax),%rbp + popq %r12 - movq -8(%rax),%rbx + popq %rbx - leaq (%rax),%rsp + popq %rbp L$gcm_dec_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .p2align 5 _aesni_ctr32_6x: vmovdqu 0-128(%rcx),%xmm4 vmovdqu 32(%r11),%xmm2 - leaq -1(%rbp),%r13 + leaq -1(%r10),%r13 vmovups 16-128(%rcx),%xmm15 leaq 32-128(%rcx),%r12 vpxor %xmm4,%xmm1,%xmm9 @@ -556,11 +568,12 @@ L$handle_ctr32_2: .p2align 5 _aesni_gcm_encrypt: + #ifdef BORINGSSL_DISPATCH_TEST movb $1,_BORINGSSL_function_hit+2(%rip) #endif - xorq %r10,%r10 + xorq %rax,%rax @@ -568,20 +581,26 @@ _aesni_gcm_encrypt: cmpq $288,%rdx jb L$gcm_enc_abort - leaq (%rsp),%rax + pushq %rbp + + + movq %rsp,%rbp pushq %rbx - pushq %rbp pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + vzeroupper vmovdqu (%r8),%xmm1 @@ -593,7 +612,7 @@ _aesni_gcm_encrypt: leaq 128(%rcx),%rcx vmovdqu (%r11),%xmm0 andq $-128,%rsp - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d andq %r15,%r14 andq %rsp,%r15 @@ -604,7 +623,7 @@ _aesni_gcm_encrypt: subq %r15,%rsp L$enc_no_key_aliasing: - leaq (%rsi),%r14 + movq %rsi,%r14 @@ -632,10 +651,11 @@ L$enc_no_key_aliasing: call _aesni_ctr32_6x - vmovdqu (%r9),%xmm8 - leaq 32+32(%r9),%r9 + movq 16(%rbp),%r12 + leaq 32(%r9),%r9 + vmovdqu (%r12),%xmm8 subq $12,%rdx - movq $192,%r10 + movq $192,%rax vpshufb %xmm0,%xmm8,%xmm8 call _aesni_ctr32_ghash_6x @@ -811,29 +831,31 @@ L$enc_no_key_aliasing: vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 vpxor %xmm7,%xmm2,%xmm2 vpxor %xmm2,%xmm8,%xmm8 + movq 16(%rbp),%r12 vpshufb (%r11),%xmm8,%xmm8 - vmovdqu %xmm8,-64(%r9) + vmovdqu %xmm8,(%r12) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp - movq -40(%rax),%r14 + popq %r15 - movq -32(%rax),%r13 + popq %r14 - movq -24(%rax),%r12 + popq %r13 - movq -16(%rax),%rbp + popq %r12 - movq -8(%rax),%rbx + popq %rbx - leaq (%rax),%rsp + popq %rbp L$gcm_enc_abort: - movq %r10,%rax .byte 0xf3,0xc3 + +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -847,4 +869,9 @@ L$one_lsb: .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-x86_64-apple.S index 7633880e..244ee21a 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/aesni-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1260,6 +1260,8 @@ L$ctr32_enc_done: pxor %xmm0,%xmm13 movdqu 80(%rdi),%xmm15 pxor %xmm0,%xmm14 + prefetcht0 448(%rdi) + prefetcht0 512(%rdi) pxor %xmm0,%xmm15 .byte 102,15,56,220,209 .byte 102,15,56,220,217 @@ -2478,6 +2480,7 @@ L$key_expansion_256b: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -2500,4 +2503,9 @@ L$key_rcon1b: .byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-apple.S similarity index 95% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-apple.S index 7f92fc51..d305be63 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -23,7 +23,7 @@ .p2align 4 _gcm_gmult_ssse3: -L$gmult_seh_begin: + movdqu (%rdi),%xmm0 movdqa L$reverse_bytes(%rip),%xmm10 movdqa L$low4_mask(%rip),%xmm2 @@ -199,7 +199,7 @@ L$oop_row_3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -L$gmult_seh_end: + @@ -212,7 +212,7 @@ L$gmult_seh_end: .private_extern _gcm_ghash_ssse3 .p2align 4 _gcm_ghash_ssse3: -L$ghash_seh_begin: + movdqu (%rdi),%xmm0 movdqa L$reverse_bytes(%rip),%xmm10 @@ -411,10 +411,11 @@ L$oop_row_6: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -L$ghash_seh_end: + +.section __DATA,__const .p2align 4 @@ -423,4 +424,9 @@ L$reverse_bytes: L$low4_mask: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-x86_64-apple.S index fd767a05..b26ad842 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/ghash-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -19,6 +19,7 @@ .p2align 4 _gcm_init_clmul: + L$_init_clmul: movdqu (%rsi),%xmm2 pshufd $78,%xmm2,%xmm2 @@ -172,6 +173,7 @@ L$_init_clmul: .byte 0xf3,0xc3 + .globl _gcm_gmult_clmul .private_extern _gcm_gmult_clmul @@ -232,6 +234,7 @@ L$_gmult_clmul: .p2align 5 _gcm_ghash_clmul: + L$_ghash_clmul: movdqa L$bswap_mask(%rip),%xmm10 @@ -613,6 +616,7 @@ L$done: .byte 0xf3,0xc3 + .globl _gcm_init_avx .private_extern _gcm_init_avx @@ -723,6 +727,7 @@ L$init_start_avx: .byte 0xf3,0xc3 + .globl _gcm_gmult_avx .private_extern _gcm_gmult_avx @@ -1111,6 +1116,8 @@ L$tail_no_xor_avx: .byte 0xf3,0xc3 + +.section __DATA,__const .p2align 6 L$bswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -1122,4 +1129,9 @@ L$7_mask: .byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/md5-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/md5-x86_64-apple.S similarity index 98% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/md5-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/md5-x86_64-apple.S index 06e3ba06..60afa5af 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/md5-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/md5-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -694,3 +694,7 @@ L$epilogue: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256-x86_64-asm-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256-x86_64-asm-apple.S index 36057aa1..a766757b 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256-x86_64-asm-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -15,6 +15,7 @@ +.section __DATA,__const .p2align 6 L$poly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 @@ -33,6 +34,7 @@ L$ord: .quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 L$ordK: .quad 0xccd1c8aaee00bc4f +.text @@ -4465,3 +4467,7 @@ L$add_affinex_epilogue: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-apple.S similarity index 95% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-apple.S index ae7293ac..3a71b379 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -325,4 +325,8 @@ L$beeu_finish: +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rdrand-x86_64-apple.S similarity index 82% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rdrand-x86_64-apple.S index 664c0674..08cd93fd 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rdrand-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -60,3 +60,7 @@ L$err: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rsaz-avx2-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rsaz-avx2-apple.S index bebc699a..258b6243 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/rsaz-avx2-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1733,6 +1733,7 @@ L$oop_gather_1024: L$SEH_end_rsaz_1024_gather5: +.section __DATA,__const .p2align 6 L$and_mask: .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1745,4 +1746,9 @@ L$inc: .long 2,2,2,2, 3,3,3,3 .long 4,4,4,4, 4,4,4,4 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha1-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha1-x86_64-apple.S index d50851ed..2a6a6928 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha1-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1298,6 +1298,7 @@ L$oop_shaext: leaq 64(%rsi),%r8 paddd %xmm4,%xmm1 cmovneq %r8,%rsi + prefetcht0 512(%rsi) movdqa %xmm0,%xmm8 .byte 15,56,201,229 movdqa %xmm0,%xmm2 @@ -5448,6 +5449,7 @@ L$epilogue_avx2: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -5463,4 +5465,9 @@ K_XX_XX: .byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha256-x86_64-apple.S similarity index 93% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha256-x86_64-apple.S index d94268d3..c17a8cd3 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha256-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha256-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -24,6 +24,8 @@ _sha256_block_data_order: movl 0(%r11),%r9d movl 4(%r11),%r10d movl 8(%r11),%r11d + testl $536870912,%r11d + jnz L$shaext_shortcut andl $1073741824,%r9d andl $268435968,%r10d orl %r9d,%r10d @@ -1737,6 +1739,7 @@ L$epilogue: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K256: @@ -1780,6 +1783,216 @@ K256: .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text + +.p2align 6 +sha256_block_data_order_shaext: + +L$shaext_shortcut: + leaq K256+128(%rip),%rcx + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa 512-128(%rcx),%xmm7 + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm7,%xmm8 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp L$oop_shaext + +.p2align 4 +L$oop_shaext: + movdqu (%rsi),%xmm3 + movdqu 16(%rsi),%xmm4 + movdqu 32(%rsi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%rsi),%xmm6 + + movdqa 0-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 + movdqa %xmm2,%xmm10 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + nop + movdqa %xmm1,%xmm9 +.byte 15,56,203,202 + + movdqa 32-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + leaq 64(%rsi),%rsi +.byte 15,56,204,220 +.byte 15,56,203,202 + + movdqa 64-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + + movdqa 96-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 128-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 160-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 192-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 224-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 256-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 288-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 320-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 352-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 384-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 416-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + + movdqa 448-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa %xmm8,%xmm7 +.byte 15,56,203,202 + + movdqa 480-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + decq %rdx + nop +.byte 15,56,203,202 + + paddd %xmm10,%xmm2 + paddd %xmm9,%xmm1 + jnz L$oop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm7 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + + movdqu %xmm1,(%rdi) + movdqu %xmm2,16(%rdi) + .byte 0xf3,0xc3 + + .p2align 6 sha256_block_data_order_ssse3: @@ -3969,3 +4182,7 @@ L$epilogue_avx: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha512-x86_64-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha512-x86_64-apple.S index 5732f439..f6d0e197 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/sha512-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/sha512-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1735,6 +1735,7 @@ L$epilogue: .byte 0xf3,0xc3 +.section __DATA,__const .p2align 6 K512: @@ -1822,6 +1823,7 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .p2align 6 sha512_block_data_order_avx: @@ -2988,3 +2990,7 @@ L$epilogue_avx: #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/vpaes-x86_64-apple.S similarity index 98% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/vpaes-x86_64-apple.S index 31cf3290..08df86a9 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/vpaes-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1018,6 +1018,7 @@ _vpaes_preheat: +.section __DATA,__const .p2align 6 _vpaes_consts: L$k_inv: @@ -1127,4 +1128,9 @@ L$ctr_add_two: .byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 .p2align 6 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont-apple.S similarity index 99% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont-apple.S index d354b2d4..c0c8a056 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1254,3 +1254,7 @@ L$mulx4x_epilogue: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .p2align 4 #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont5-apple.S similarity index 95% rename from third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S rename to third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont5-apple.S index e1fd9c9d..1aa66fc1 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/fipsmodule/x86_64-mont5-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -206,6 +206,7 @@ L$mul_body: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -329,6 +330,7 @@ L$outer: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -697,6 +699,7 @@ mul4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -904,6 +907,7 @@ L$outer4x: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -2066,187 +2070,6 @@ L$sqr4x_sub_entry: .byte 0xf3,0xc3 -.globl _bn_from_montgomery -.private_extern _bn_from_montgomery - -.p2align 5 -_bn_from_montgomery: - - testl $7,%r9d - jz bn_from_mont8x - xorl %eax,%eax - .byte 0xf3,0xc3 - - - - -.p2align 5 -bn_from_mont8x: - -.byte 0x67 - movq %rsp,%rax - - pushq %rbx - - pushq %rbp - - pushq %r12 - - pushq %r13 - - pushq %r14 - - pushq %r15 - -L$from_prologue: - - shll $3,%r9d - leaq (%r9,%r9,2),%r10 - negq %r9 - movq (%r8),%r8 - - - - - - - - - leaq -320(%rsp,%r9,2),%r11 - movq %rsp,%rbp - subq %rdi,%r11 - andq $4095,%r11 - cmpq %r11,%r10 - jb L$from_sp_alt - subq %r11,%rbp - leaq -320(%rbp,%r9,2),%rbp - jmp L$from_sp_done - -.p2align 5 -L$from_sp_alt: - leaq 4096-320(,%r9,2),%r10 - leaq -320(%rbp,%r9,2),%rbp - subq %r10,%r11 - movq $0,%r10 - cmovcq %r10,%r11 - subq %r11,%rbp -L$from_sp_done: - andq $-64,%rbp - movq %rsp,%r11 - subq %rbp,%r11 - andq $-4096,%r11 - leaq (%r11,%rbp,1),%rsp - movq (%rsp),%r10 - cmpq %rbp,%rsp - ja L$from_page_walk - jmp L$from_page_walk_done - -L$from_page_walk: - leaq -4096(%rsp),%rsp - movq (%rsp),%r10 - cmpq %rbp,%rsp - ja L$from_page_walk -L$from_page_walk_done: - - movq %r9,%r10 - negq %r9 - - - - - - - - - - - movq %r8,32(%rsp) - movq %rax,40(%rsp) - -L$from_body: - movq %r9,%r11 - leaq 48(%rsp),%rax - pxor %xmm0,%xmm0 - jmp L$mul_by_1 - -.p2align 5 -L$mul_by_1: - movdqu (%rsi),%xmm1 - movdqu 16(%rsi),%xmm2 - movdqu 32(%rsi),%xmm3 - movdqa %xmm0,(%rax,%r9,1) - movdqu 48(%rsi),%xmm4 - movdqa %xmm0,16(%rax,%r9,1) -.byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 - movdqa %xmm1,(%rax) - movdqa %xmm0,32(%rax,%r9,1) - movdqa %xmm2,16(%rax) - movdqa %xmm0,48(%rax,%r9,1) - movdqa %xmm3,32(%rax) - movdqa %xmm4,48(%rax) - leaq 64(%rax),%rax - subq $64,%r11 - jnz L$mul_by_1 - -.byte 102,72,15,110,207 -.byte 102,72,15,110,209 -.byte 0x67 - movq %rcx,%rbp -.byte 102,73,15,110,218 - leaq _OPENSSL_ia32cap_P(%rip),%r11 - movl 8(%r11),%r11d - andl $0x80108,%r11d - cmpl $0x80108,%r11d - jne L$from_mont_nox - - leaq (%rax,%r9,1),%rdi - call __bn_sqrx8x_reduction - call __bn_postx4x_internal - - pxor %xmm0,%xmm0 - leaq 48(%rsp),%rax - jmp L$from_mont_zero - -.p2align 5 -L$from_mont_nox: - call __bn_sqr8x_reduction - call __bn_post4x_internal - - pxor %xmm0,%xmm0 - leaq 48(%rsp),%rax - jmp L$from_mont_zero - -.p2align 5 -L$from_mont_zero: - movq 40(%rsp),%rsi - - movdqa %xmm0,0(%rax) - movdqa %xmm0,16(%rax) - movdqa %xmm0,32(%rax) - movdqa %xmm0,48(%rax) - leaq 64(%rax),%rax - subq $32,%r9 - jnz L$from_mont_zero - - movq $1,%rax - movq -48(%rsi),%r15 - - movq -40(%rsi),%r14 - - movq -32(%rsi),%r13 - - movq -24(%rsi),%r12 - - movq -16(%rsi),%rbp - - movq -8(%rsi),%rbx - - leaq (%rsi),%rsp - -L$from_epilogue: - .byte 0xf3,0xc3 - - .p2align 5 bn_mulx4x_mont_gather5: @@ -2501,6 +2324,7 @@ mulx4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%rdi),%rdi @@ -2651,6 +2475,7 @@ L$mulx4x_outer: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%rdi),%rdi @@ -3599,6 +3424,15 @@ _bn_scatter5: cmpl $0,%esi jz L$scatter_epilogue + + + + + + + + + leaq (%rdx,%rcx,8),%rdx L$scatter: movq (%rdi),%rax @@ -3767,6 +3601,7 @@ L$gather: por %xmm3,%xmm5 por %xmm5,%xmm4 leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 movq %xmm0,(%rdi) @@ -3780,9 +3615,15 @@ L$gather: L$SEH_end_bn_gather5: +.section __DATA,__const .p2align 6 L$inc: .long 0,0, 1,1 .long 2,2, 2,2 .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/mac-x86_64/crypto/test/trampoline-x86_64.S b/third_party/boringssl/kit/apple-x86_64/crypto/test/trampoline-x86_64-apple.S similarity index 91% rename from third_party/boringssl/kit/mac-x86_64/crypto/test/trampoline-x86_64.S rename to third_party/boringssl/kit/apple-x86_64/crypto/test/trampoline-x86_64-apple.S index 5f20aa78..966ec0ae 100644 --- a/third_party/boringssl/kit/mac-x86_64/crypto/test/trampoline-x86_64.S +++ b/third_party/boringssl/kit/apple-x86_64/crypto/test/trampoline-x86_64-apple.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__APPLE__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -25,7 +25,7 @@ .private_extern _abi_test_trampoline .p2align 4 _abi_test_trampoline: -L$abi_test_trampoline_seh_begin: + @@ -38,27 +38,26 @@ L$abi_test_trampoline_seh_begin: subq $120,%rsp -L$abi_test_trampoline_seh_prolog_alloc: + movq %r8,48(%rsp) movq %rbx,64(%rsp) -L$abi_test_trampoline_seh_prolog_rbx: + movq %rbp,72(%rsp) -L$abi_test_trampoline_seh_prolog_rbp: + movq %r12,80(%rsp) -L$abi_test_trampoline_seh_prolog_r12: + movq %r13,88(%rsp) -L$abi_test_trampoline_seh_prolog_r13: + movq %r14,96(%rsp) -L$abi_test_trampoline_seh_prolog_r14: + movq %r15,104(%rsp) -L$abi_test_trampoline_seh_prolog_r15: -L$abi_test_trampoline_seh_prolog_end: + movq 0(%rsi),%rbx movq 8(%rsi),%rbp movq 16(%rsi),%r12 @@ -182,7 +181,7 @@ L$call_done: .byte 0xf3,0xc3 -L$abi_test_trampoline_seh_end: + .globl _abi_test_clobber_rax @@ -441,10 +440,10 @@ _abi_test_clobber_xmm15: .p2align 4 _abi_test_bad_unwind_wrong_register: -L$abi_test_bad_unwind_wrong_register_seh_begin: + pushq %r12 -L$abi_test_bad_unwind_wrong_register_seh_push_r13: + @@ -452,7 +451,7 @@ L$abi_test_bad_unwind_wrong_register_seh_push_r13: popq %r12 .byte 0xf3,0xc3 -L$abi_test_bad_unwind_wrong_register_seh_end: + @@ -465,10 +464,10 @@ L$abi_test_bad_unwind_wrong_register_seh_end: .p2align 4 _abi_test_bad_unwind_temporary: -L$abi_test_bad_unwind_temporary_seh_begin: + pushq %r12 -L$abi_test_bad_unwind_temporary_seh_push_r12: + movq %r12,%rax incq %rax @@ -482,7 +481,7 @@ L$abi_test_bad_unwind_temporary_seh_push_r12: popq %r12 .byte 0xf3,0xc3 -L$abi_test_bad_unwind_temporary_seh_end: + @@ -511,3 +510,7 @@ _abi_test_set_direction_flag: .byte 0xf3,0xc3 #endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/boringssl.gypi b/third_party/boringssl/kit/boringssl.gypi index b84f4ba4..5135144a 100644 --- a/third_party/boringssl/kit/boringssl.gypi +++ b/third_party/boringssl/kit/boringssl.gypi @@ -1,6 +1,16 @@ -# Copyright (c) 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Copyright (c) 2015, Google Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # This file is created by generate_build_files.py. Do not edit manually. @@ -57,34 +67,30 @@ 'src/crypto/asn1/a_bool.c', 'src/crypto/asn1/a_d2i_fp.c', 'src/crypto/asn1/a_dup.c', - 'src/crypto/asn1/a_enum.c', 'src/crypto/asn1/a_gentm.c', 'src/crypto/asn1/a_i2d_fp.c', 'src/crypto/asn1/a_int.c', 'src/crypto/asn1/a_mbstr.c', 'src/crypto/asn1/a_object.c', 'src/crypto/asn1/a_octet.c', - 'src/crypto/asn1/a_print.c', 'src/crypto/asn1/a_strex.c', 'src/crypto/asn1/a_strnid.c', 'src/crypto/asn1/a_time.c', 'src/crypto/asn1/a_type.c', 'src/crypto/asn1/a_utctm.c', - 'src/crypto/asn1/a_utf8.c', 'src/crypto/asn1/asn1_lib.c', 'src/crypto/asn1/asn1_par.c', 'src/crypto/asn1/asn_pack.c', - 'src/crypto/asn1/charmap.h', 'src/crypto/asn1/f_int.c', 'src/crypto/asn1/f_string.c', 'src/crypto/asn1/internal.h', + 'src/crypto/asn1/posix_time.c', 'src/crypto/asn1/tasn_dec.c', 'src/crypto/asn1/tasn_enc.c', 'src/crypto/asn1/tasn_fre.c', 'src/crypto/asn1/tasn_new.c', 'src/crypto/asn1/tasn_typ.c', 'src/crypto/asn1/tasn_utl.c', - 'src/crypto/asn1/time_support.c', 'src/crypto/base64/base64.c', 'src/crypto/bio/bio.c', 'src/crypto/bio/bio_mem.c', @@ -111,33 +117,39 @@ 'src/crypto/chacha/internal.h', 'src/crypto/cipher_extra/cipher_extra.c', 'src/crypto/cipher_extra/derive_key.c', - 'src/crypto/cipher_extra/e_aesccm.c', 'src/crypto/cipher_extra/e_aesctrhmac.c', 'src/crypto/cipher_extra/e_aesgcmsiv.c', 'src/crypto/cipher_extra/e_chacha20poly1305.c', + 'src/crypto/cipher_extra/e_des.c', 'src/crypto/cipher_extra/e_null.c', 'src/crypto/cipher_extra/e_rc2.c', 'src/crypto/cipher_extra/e_rc4.c', 'src/crypto/cipher_extra/e_tls.c', 'src/crypto/cipher_extra/internal.h', 'src/crypto/cipher_extra/tls_cbc.c', - 'src/crypto/cmac/cmac.c', 'src/crypto/conf/conf.c', 'src/crypto/conf/conf_def.h', 'src/crypto/conf/internal.h', - 'src/crypto/cpu-aarch64-fuchsia.c', - 'src/crypto/cpu-aarch64-linux.c', - 'src/crypto/cpu-aarch64-win.c', - 'src/crypto/cpu-arm-linux.c', - 'src/crypto/cpu-arm-linux.h', - 'src/crypto/cpu-arm.c', - 'src/crypto/cpu-intel.c', - 'src/crypto/cpu-ppc64le.c', + 'src/crypto/cpu_aarch64_apple.c', + 'src/crypto/cpu_aarch64_freebsd.c', + 'src/crypto/cpu_aarch64_fuchsia.c', + 'src/crypto/cpu_aarch64_linux.c', + 'src/crypto/cpu_aarch64_openbsd.c', + 'src/crypto/cpu_aarch64_win.c', + 'src/crypto/cpu_arm.c', + 'src/crypto/cpu_arm_freebsd.c', + 'src/crypto/cpu_arm_linux.c', + 'src/crypto/cpu_arm_linux.h', + 'src/crypto/cpu_arm_openbsd.c', + 'src/crypto/cpu_intel.c', 'src/crypto/crypto.c', 'src/crypto/curve25519/curve25519.c', + 'src/crypto/curve25519/curve25519_64_adx.c', 'src/crypto/curve25519/curve25519_tables.h', 'src/crypto/curve25519/internal.h', 'src/crypto/curve25519/spake25519.c', + 'src/crypto/des/des.c', + 'src/crypto/des/internal.h', 'src/crypto/dh_extra/dh_asn1.c', 'src/crypto/dh_extra/params.c', 'src/crypto/digest_extra/digest_extra.c', @@ -153,7 +165,6 @@ 'src/crypto/engine/engine.c', 'src/crypto/err/err.c', 'src/crypto/err/internal.h', - 'src/crypto/evp/digestsign.c', 'src/crypto/evp/evp.c', 'src/crypto/evp/evp_asn1.c', 'src/crypto/evp/evp_ctx.c', @@ -163,6 +174,7 @@ 'src/crypto/evp/p_ec_asn1.c', 'src/crypto/evp/p_ed25519.c', 'src/crypto/evp/p_ed25519_asn1.c', + 'src/crypto/evp/p_hkdf.c', 'src/crypto/evp/p_rsa.c', 'src/crypto/evp/p_rsa_asn1.c', 'src/crypto/evp/p_x25519.c', @@ -178,12 +190,12 @@ 'src/crypto/fipsmodule/bn/rsaz_exp.h', 'src/crypto/fipsmodule/cipher/internal.h', 'src/crypto/fipsmodule/delocate.h', - 'src/crypto/fipsmodule/des/internal.h', + 'src/crypto/fipsmodule/dh/internal.h', 'src/crypto/fipsmodule/digest/internal.h', 'src/crypto/fipsmodule/digest/md32_common.h', 'src/crypto/fipsmodule/ec/internal.h', - 'src/crypto/fipsmodule/ec/p256-x86_64-table.h', - 'src/crypto/fipsmodule/ec/p256-x86_64.h', + 'src/crypto/fipsmodule/ec/p256-nistz-table.h', + 'src/crypto/fipsmodule/ec/p256-nistz.h', 'src/crypto/fipsmodule/ec/p256_table.h', 'src/crypto/fipsmodule/ecdsa/internal.h', 'src/crypto/fipsmodule/fips_shared_support.c', @@ -193,13 +205,16 @@ 'src/crypto/fipsmodule/rand/getrandom_fillin.h', 'src/crypto/fipsmodule/rand/internal.h', 'src/crypto/fipsmodule/rsa/internal.h', + 'src/crypto/fipsmodule/service_indicator/internal.h', 'src/crypto/fipsmodule/sha/internal.h', 'src/crypto/fipsmodule/tls/internal.h', - 'src/crypto/hkdf/hkdf.c', 'src/crypto/hpke/hpke.c', 'src/crypto/hrss/hrss.c', 'src/crypto/hrss/internal.h', 'src/crypto/internal.h', + 'src/crypto/kyber/internal.h', + 'src/crypto/kyber/keccak.c', + 'src/crypto/kyber/kyber.c', 'src/crypto/lhash/internal.h', 'src/crypto/lhash/lhash.c', 'src/crypto/mem.c', @@ -234,9 +249,10 @@ 'src/crypto/rand_extra/rand_extra.c', 'src/crypto/rand_extra/windows.c', 'src/crypto/rc4/rc4.c', - 'src/crypto/refcount_c11.c', - 'src/crypto/refcount_lock.c', + 'src/crypto/refcount.c', + 'src/crypto/rsa_extra/internal.h', 'src/crypto/rsa_extra/rsa_asn1.c', + 'src/crypto/rsa_extra/rsa_crypt.c', 'src/crypto/rsa_extra/rsa_print.c', 'src/crypto/siphash/siphash.c', 'src/crypto/stack/stack.c', @@ -258,6 +274,7 @@ 'src/crypto/x509/i2d_pr.c', 'src/crypto/x509/internal.h', 'src/crypto/x509/name_print.c', + 'src/crypto/x509/policy.c', 'src/crypto/x509/rsa_pss.c', 'src/crypto/x509/t_crl.c', 'src/crypto/x509/t_req.c', @@ -299,12 +316,6 @@ 'src/crypto/x509/x_x509a.c', 'src/crypto/x509v3/ext_dat.h', 'src/crypto/x509v3/internal.h', - 'src/crypto/x509v3/pcy_cache.c', - 'src/crypto/x509v3/pcy_data.c', - 'src/crypto/x509v3/pcy_lib.c', - 'src/crypto/x509v3/pcy_map.c', - 'src/crypto/x509v3/pcy_node.c', - 'src/crypto/x509v3/pcy_tree.c', 'src/crypto/x509v3/v3_akey.c', 'src/crypto/x509v3/v3_akeya.c', 'src/crypto/x509v3/v3_alt.c', @@ -322,8 +333,6 @@ 'src/crypto/x509v3/v3_lib.c', 'src/crypto/x509v3/v3_ncons.c', 'src/crypto/x509v3/v3_ocsp.c', - 'src/crypto/x509v3/v3_pci.c', - 'src/crypto/x509v3/v3_pcia.c', 'src/crypto/x509v3/v3_pcons.c', 'src/crypto/x509v3/v3_pmaps.c', 'src/crypto/x509v3/v3_prn.c', @@ -352,6 +361,7 @@ 'src/include/openssl/conf.h', 'src/include/openssl/cpu.h', 'src/include/openssl/crypto.h', + 'src/include/openssl/ctrdrbg.h', 'src/include/openssl/curve25519.h', 'src/include/openssl/des.h', 'src/include/openssl/dh.h', @@ -372,6 +382,8 @@ 'src/include/openssl/hpke.h', 'src/include/openssl/hrss.h', 'src/include/openssl/is_boringssl.h', + 'src/include/openssl/kdf.h', + 'src/include/openssl/kyber.h', 'src/include/openssl/lhash.h', 'src/include/openssl/md4.h', 'src/include/openssl/md5.h', @@ -394,11 +406,13 @@ 'src/include/openssl/ripemd.h', 'src/include/openssl/rsa.h', 'src/include/openssl/safestack.h', + 'src/include/openssl/service_indicator.h', 'src/include/openssl/sha.h', 'src/include/openssl/siphash.h', 'src/include/openssl/span.h', 'src/include/openssl/stack.h', 'src/include/openssl/thread.h', + 'src/include/openssl/time.h', 'src/include/openssl/trust_token.h', 'src/include/openssl/type_check.h', 'src/include/openssl/x509.h', @@ -406,186 +420,203 @@ 'src/include/openssl/x509v3.h', 'src/third_party/fiat/curve25519_32.h', 'src/third_party/fiat/curve25519_64.h', + 'src/third_party/fiat/curve25519_64_adx.h', + 'src/third_party/fiat/curve25519_64_msvc.h', 'src/third_party/fiat/p256_32.h', 'src/third_party/fiat/p256_64.h', + 'src/third_party/fiat/p256_64_msvc.h', ], - 'boringssl_ios_aarch64_files': [ - 'ios-aarch64/crypto/chacha/chacha-armv8.S', - 'ios-aarch64/crypto/fipsmodule/aesv8-armx64.S', - 'ios-aarch64/crypto/fipsmodule/armv8-mont.S', - 'ios-aarch64/crypto/fipsmodule/ghash-neon-armv8.S', - 'ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S', - 'ios-aarch64/crypto/fipsmodule/sha1-armv8.S', - 'ios-aarch64/crypto/fipsmodule/sha256-armv8.S', - 'ios-aarch64/crypto/fipsmodule/sha512-armv8.S', - 'ios-aarch64/crypto/fipsmodule/vpaes-armv8.S', - 'ios-aarch64/crypto/test/trampoline-armv8.S', + 'boringssl_apple_aarch64_files': [ + 'apple-aarch64/crypto/chacha/chacha-armv8-apple.S', + 'apple-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/aesv8-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/armv8-mont-apple.S', + 'apple-aarch64/crypto/fipsmodule/bn-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/ghash-neon-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/ghashv8-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/p256-armv8-asm-apple.S', + 'apple-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-apple.S', + 'apple-aarch64/crypto/fipsmodule/sha1-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/sha256-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/sha512-armv8-apple.S', + 'apple-aarch64/crypto/fipsmodule/vpaes-armv8-apple.S', + 'apple-aarch64/crypto/test/trampoline-armv8-apple.S', ], - 'boringssl_ios_arm_files': [ - 'ios-arm/crypto/chacha/chacha-armv4.S', - 'ios-arm/crypto/fipsmodule/aesv8-armx32.S', - 'ios-arm/crypto/fipsmodule/armv4-mont.S', - 'ios-arm/crypto/fipsmodule/bsaes-armv7.S', - 'ios-arm/crypto/fipsmodule/ghash-armv4.S', - 'ios-arm/crypto/fipsmodule/ghashv8-armx32.S', - 'ios-arm/crypto/fipsmodule/sha1-armv4-large.S', - 'ios-arm/crypto/fipsmodule/sha256-armv4.S', - 'ios-arm/crypto/fipsmodule/sha512-armv4.S', - 'ios-arm/crypto/fipsmodule/vpaes-armv7.S', - 'ios-arm/crypto/test/trampoline-armv4.S', + 'boringssl_apple_arm_files': [ + 'apple-arm/crypto/chacha/chacha-armv4-apple.S', + 'apple-arm/crypto/fipsmodule/aesv8-armv7-apple.S', + 'apple-arm/crypto/fipsmodule/armv4-mont-apple.S', + 'apple-arm/crypto/fipsmodule/bsaes-armv7-apple.S', + 'apple-arm/crypto/fipsmodule/ghash-armv4-apple.S', + 'apple-arm/crypto/fipsmodule/ghashv8-armv7-apple.S', + 'apple-arm/crypto/fipsmodule/sha1-armv4-large-apple.S', + 'apple-arm/crypto/fipsmodule/sha256-armv4-apple.S', + 'apple-arm/crypto/fipsmodule/sha512-armv4-apple.S', + 'apple-arm/crypto/fipsmodule/vpaes-armv7-apple.S', + 'apple-arm/crypto/test/trampoline-armv4-apple.S', + ], + 'boringssl_apple_x86_files': [ + 'apple-x86/crypto/chacha/chacha-x86-apple.S', + 'apple-x86/crypto/fipsmodule/aesni-x86-apple.S', + 'apple-x86/crypto/fipsmodule/bn-586-apple.S', + 'apple-x86/crypto/fipsmodule/co-586-apple.S', + 'apple-x86/crypto/fipsmodule/ghash-ssse3-x86-apple.S', + 'apple-x86/crypto/fipsmodule/ghash-x86-apple.S', + 'apple-x86/crypto/fipsmodule/md5-586-apple.S', + 'apple-x86/crypto/fipsmodule/sha1-586-apple.S', + 'apple-x86/crypto/fipsmodule/sha256-586-apple.S', + 'apple-x86/crypto/fipsmodule/sha512-586-apple.S', + 'apple-x86/crypto/fipsmodule/vpaes-x86-apple.S', + 'apple-x86/crypto/fipsmodule/x86-mont-apple.S', + 'apple-x86/crypto/test/trampoline-x86-apple.S', + ], + 'boringssl_apple_x86_64_files': [ + 'apple-x86_64/crypto/chacha/chacha-x86_64-apple.S', + 'apple-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-apple.S', + 'apple-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/aesni-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/ghash-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/md5-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/p256-x86_64-asm-apple.S', + 'apple-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-apple.S', + 'apple-x86_64/crypto/fipsmodule/rdrand-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/rsaz-avx2-apple.S', + 'apple-x86_64/crypto/fipsmodule/sha1-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/sha256-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/sha512-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/vpaes-x86_64-apple.S', + 'apple-x86_64/crypto/fipsmodule/x86_64-mont-apple.S', + 'apple-x86_64/crypto/fipsmodule/x86_64-mont5-apple.S', + 'apple-x86_64/crypto/test/trampoline-x86_64-apple.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_mul.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_square.S', ], 'boringssl_linux_aarch64_files': [ - 'linux-aarch64/crypto/chacha/chacha-armv8.S', - 'linux-aarch64/crypto/fipsmodule/aesv8-armx64.S', - 'linux-aarch64/crypto/fipsmodule/armv8-mont.S', - 'linux-aarch64/crypto/fipsmodule/ghash-neon-armv8.S', - 'linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S', - 'linux-aarch64/crypto/fipsmodule/sha1-armv8.S', - 'linux-aarch64/crypto/fipsmodule/sha256-armv8.S', - 'linux-aarch64/crypto/fipsmodule/sha512-armv8.S', - 'linux-aarch64/crypto/fipsmodule/vpaes-armv8.S', - 'linux-aarch64/crypto/test/trampoline-armv8.S', + 'linux-aarch64/crypto/chacha/chacha-armv8-linux.S', + 'linux-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/aesv8-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/armv8-mont-linux.S', + 'linux-aarch64/crypto/fipsmodule/bn-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/ghash-neon-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/ghashv8-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/p256-armv8-asm-linux.S', + 'linux-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-linux.S', + 'linux-aarch64/crypto/fipsmodule/sha1-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/sha256-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/sha512-armv8-linux.S', + 'linux-aarch64/crypto/fipsmodule/vpaes-armv8-linux.S', + 'linux-aarch64/crypto/test/trampoline-armv8-linux.S', ], 'boringssl_linux_arm_files': [ - 'linux-arm/crypto/chacha/chacha-armv4.S', - 'linux-arm/crypto/fipsmodule/aesv8-armx32.S', - 'linux-arm/crypto/fipsmodule/armv4-mont.S', - 'linux-arm/crypto/fipsmodule/bsaes-armv7.S', - 'linux-arm/crypto/fipsmodule/ghash-armv4.S', - 'linux-arm/crypto/fipsmodule/ghashv8-armx32.S', - 'linux-arm/crypto/fipsmodule/sha1-armv4-large.S', - 'linux-arm/crypto/fipsmodule/sha256-armv4.S', - 'linux-arm/crypto/fipsmodule/sha512-armv4.S', - 'linux-arm/crypto/fipsmodule/vpaes-armv7.S', - 'linux-arm/crypto/test/trampoline-armv4.S', + 'linux-arm/crypto/chacha/chacha-armv4-linux.S', + 'linux-arm/crypto/fipsmodule/aesv8-armv7-linux.S', + 'linux-arm/crypto/fipsmodule/armv4-mont-linux.S', + 'linux-arm/crypto/fipsmodule/bsaes-armv7-linux.S', + 'linux-arm/crypto/fipsmodule/ghash-armv4-linux.S', + 'linux-arm/crypto/fipsmodule/ghashv8-armv7-linux.S', + 'linux-arm/crypto/fipsmodule/sha1-armv4-large-linux.S', + 'linux-arm/crypto/fipsmodule/sha256-armv4-linux.S', + 'linux-arm/crypto/fipsmodule/sha512-armv4-linux.S', + 'linux-arm/crypto/fipsmodule/vpaes-armv7-linux.S', + 'linux-arm/crypto/test/trampoline-armv4-linux.S', 'src/crypto/curve25519/asm/x25519-asm-arm.S', 'src/crypto/poly1305/poly1305_arm_asm.S', ], - 'boringssl_linux_ppc64le_files': [ - 'linux-ppc64le/crypto/fipsmodule/aesp8-ppc.S', - 'linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S', - 'linux-ppc64le/crypto/test/trampoline-ppc.S', - ], 'boringssl_linux_x86_files': [ - 'linux-x86/crypto/chacha/chacha-x86.S', - 'linux-x86/crypto/fipsmodule/aesni-x86.S', - 'linux-x86/crypto/fipsmodule/bn-586.S', - 'linux-x86/crypto/fipsmodule/co-586.S', - 'linux-x86/crypto/fipsmodule/ghash-ssse3-x86.S', - 'linux-x86/crypto/fipsmodule/ghash-x86.S', - 'linux-x86/crypto/fipsmodule/md5-586.S', - 'linux-x86/crypto/fipsmodule/sha1-586.S', - 'linux-x86/crypto/fipsmodule/sha256-586.S', - 'linux-x86/crypto/fipsmodule/sha512-586.S', - 'linux-x86/crypto/fipsmodule/vpaes-x86.S', - 'linux-x86/crypto/fipsmodule/x86-mont.S', - 'linux-x86/crypto/test/trampoline-x86.S', + 'linux-x86/crypto/chacha/chacha-x86-linux.S', + 'linux-x86/crypto/fipsmodule/aesni-x86-linux.S', + 'linux-x86/crypto/fipsmodule/bn-586-linux.S', + 'linux-x86/crypto/fipsmodule/co-586-linux.S', + 'linux-x86/crypto/fipsmodule/ghash-ssse3-x86-linux.S', + 'linux-x86/crypto/fipsmodule/ghash-x86-linux.S', + 'linux-x86/crypto/fipsmodule/md5-586-linux.S', + 'linux-x86/crypto/fipsmodule/sha1-586-linux.S', + 'linux-x86/crypto/fipsmodule/sha256-586-linux.S', + 'linux-x86/crypto/fipsmodule/sha512-586-linux.S', + 'linux-x86/crypto/fipsmodule/vpaes-x86-linux.S', + 'linux-x86/crypto/fipsmodule/x86-mont-linux.S', + 'linux-x86/crypto/test/trampoline-x86-linux.S', ], 'boringssl_linux_x86_64_files': [ - 'linux-x86_64/crypto/chacha/chacha-x86_64.S', - 'linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S', - 'linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S', - 'linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/aesni-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/ghash-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/md5-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S', - 'linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S', - 'linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/rsaz-avx2.S', - 'linux-x86_64/crypto/fipsmodule/sha1-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/sha256-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/sha512-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S', - 'linux-x86_64/crypto/fipsmodule/x86_64-mont.S', - 'linux-x86_64/crypto/fipsmodule/x86_64-mont5.S', - 'linux-x86_64/crypto/test/trampoline-x86_64.S', + 'linux-x86_64/crypto/chacha/chacha-x86_64-linux.S', + 'linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.S', + 'linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/aesni-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/ghash-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/md5-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/p256-x86_64-asm-linux.S', + 'linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.S', + 'linux-x86_64/crypto/fipsmodule/rdrand-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/rsaz-avx2-linux.S', + 'linux-x86_64/crypto/fipsmodule/sha1-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/sha256-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/sha512-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/vpaes-x86_64-linux.S', + 'linux-x86_64/crypto/fipsmodule/x86_64-mont-linux.S', + 'linux-x86_64/crypto/fipsmodule/x86_64-mont5-linux.S', + 'linux-x86_64/crypto/test/trampoline-x86_64-linux.S', 'src/crypto/hrss/asm/poly_rq_mul.S', - ], - 'boringssl_mac_x86_files': [ - 'mac-x86/crypto/chacha/chacha-x86.S', - 'mac-x86/crypto/fipsmodule/aesni-x86.S', - 'mac-x86/crypto/fipsmodule/bn-586.S', - 'mac-x86/crypto/fipsmodule/co-586.S', - 'mac-x86/crypto/fipsmodule/ghash-ssse3-x86.S', - 'mac-x86/crypto/fipsmodule/ghash-x86.S', - 'mac-x86/crypto/fipsmodule/md5-586.S', - 'mac-x86/crypto/fipsmodule/sha1-586.S', - 'mac-x86/crypto/fipsmodule/sha256-586.S', - 'mac-x86/crypto/fipsmodule/sha512-586.S', - 'mac-x86/crypto/fipsmodule/vpaes-x86.S', - 'mac-x86/crypto/fipsmodule/x86-mont.S', - 'mac-x86/crypto/test/trampoline-x86.S', - ], - 'boringssl_mac_x86_64_files': [ - 'mac-x86_64/crypto/chacha/chacha-x86_64.S', - 'mac-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S', - 'mac-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S', - 'mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/aesni-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/ghash-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/md5-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S', - 'mac-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S', - 'mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/rsaz-avx2.S', - 'mac-x86_64/crypto/fipsmodule/sha1-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/sha256-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/sha512-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S', - 'mac-x86_64/crypto/fipsmodule/x86_64-mont.S', - 'mac-x86_64/crypto/fipsmodule/x86_64-mont5.S', - 'mac-x86_64/crypto/test/trampoline-x86_64.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_mul.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_square.S', ], 'boringssl_win_aarch64_files': [ - 'win-aarch64/crypto/chacha/chacha-armv8.S', - 'win-aarch64/crypto/fipsmodule/aesv8-armx64.S', - 'win-aarch64/crypto/fipsmodule/armv8-mont.S', - 'win-aarch64/crypto/fipsmodule/ghash-neon-armv8.S', - 'win-aarch64/crypto/fipsmodule/ghashv8-armx64.S', - 'win-aarch64/crypto/fipsmodule/sha1-armv8.S', - 'win-aarch64/crypto/fipsmodule/sha256-armv8.S', - 'win-aarch64/crypto/fipsmodule/sha512-armv8.S', - 'win-aarch64/crypto/fipsmodule/vpaes-armv8.S', - 'win-aarch64/crypto/test/trampoline-armv8.S', + 'win-aarch64/crypto/chacha/chacha-armv8-win.S', + 'win-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-win.S', + 'win-aarch64/crypto/fipsmodule/aesv8-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/armv8-mont-win.S', + 'win-aarch64/crypto/fipsmodule/bn-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/ghash-neon-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/ghashv8-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/p256-armv8-asm-win.S', + 'win-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-win.S', + 'win-aarch64/crypto/fipsmodule/sha1-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/sha256-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/sha512-armv8-win.S', + 'win-aarch64/crypto/fipsmodule/vpaes-armv8-win.S', + 'win-aarch64/crypto/test/trampoline-armv8-win.S', ], 'boringssl_win_x86_files': [ - 'win-x86/crypto/chacha/chacha-x86.asm', - 'win-x86/crypto/fipsmodule/aesni-x86.asm', - 'win-x86/crypto/fipsmodule/bn-586.asm', - 'win-x86/crypto/fipsmodule/co-586.asm', - 'win-x86/crypto/fipsmodule/ghash-ssse3-x86.asm', - 'win-x86/crypto/fipsmodule/ghash-x86.asm', - 'win-x86/crypto/fipsmodule/md5-586.asm', - 'win-x86/crypto/fipsmodule/sha1-586.asm', - 'win-x86/crypto/fipsmodule/sha256-586.asm', - 'win-x86/crypto/fipsmodule/sha512-586.asm', - 'win-x86/crypto/fipsmodule/vpaes-x86.asm', - 'win-x86/crypto/fipsmodule/x86-mont.asm', - 'win-x86/crypto/test/trampoline-x86.asm', + 'win-x86/crypto/chacha/chacha-x86-win.asm', + 'win-x86/crypto/fipsmodule/aesni-x86-win.asm', + 'win-x86/crypto/fipsmodule/bn-586-win.asm', + 'win-x86/crypto/fipsmodule/co-586-win.asm', + 'win-x86/crypto/fipsmodule/ghash-ssse3-x86-win.asm', + 'win-x86/crypto/fipsmodule/ghash-x86-win.asm', + 'win-x86/crypto/fipsmodule/md5-586-win.asm', + 'win-x86/crypto/fipsmodule/sha1-586-win.asm', + 'win-x86/crypto/fipsmodule/sha256-586-win.asm', + 'win-x86/crypto/fipsmodule/sha512-586-win.asm', + 'win-x86/crypto/fipsmodule/vpaes-x86-win.asm', + 'win-x86/crypto/fipsmodule/x86-mont-win.asm', + 'win-x86/crypto/test/trampoline-x86-win.asm', ], 'boringssl_win_x86_64_files': [ - 'win-x86_64/crypto/chacha/chacha-x86_64.asm', - 'win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.asm', - 'win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.asm', - 'win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/aesni-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/ghash-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/md5-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/p256-x86_64-asm.asm', - 'win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.asm', - 'win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/rsaz-avx2.asm', - 'win-x86_64/crypto/fipsmodule/sha1-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/sha256-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/sha512-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm', - 'win-x86_64/crypto/fipsmodule/x86_64-mont.asm', - 'win-x86_64/crypto/fipsmodule/x86_64-mont5.asm', - 'win-x86_64/crypto/test/trampoline-x86_64.asm', + 'win-x86_64/crypto/chacha/chacha-x86_64-win.asm', + 'win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-win.asm', + 'win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/aesni-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/ghash-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/md5-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/p256-x86_64-asm-win.asm', + 'win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-win.asm', + 'win-x86_64/crypto/fipsmodule/rdrand-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/rsaz-avx2-win.asm', + 'win-x86_64/crypto/fipsmodule/sha1-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/sha256-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/sha512-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/vpaes-x86_64-win.asm', + 'win-x86_64/crypto/fipsmodule/x86_64-mont-win.asm', + 'win-x86_64/crypto/fipsmodule/x86_64-mont5-win.asm', + 'win-x86_64/crypto/test/trampoline-x86_64-win.asm', ], } } diff --git a/third_party/boringssl/kit/crypto_test_data.cc b/third_party/boringssl/kit/crypto_test_data.cc index b722b1ec..7730c646 100644 --- a/third_party/boringssl/kit/crypto_test_data.cc +++ b/third_party/boringssl/kit/crypto_test_data.cc @@ -19,6 +19,7 @@ * crypto/cipher_extra/test/aes_128_cbc_sha1_tls_tests.txt \ * crypto/cipher_extra/test/aes_128_ccm_bluetooth_tests.txt \ * crypto/cipher_extra/test/aes_128_ccm_bluetooth_8_tests.txt \ + * crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt \ * crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt \ * crypto/cipher_extra/test/aes_128_gcm_randnonce_tests.txt \ * crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt \ @@ -46,24 +47,35 @@ * crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt \ * crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt \ * crypto/curve25519/ed25519_tests.txt \ - * crypto/cmac/cavp_3des_cmac_tests.txt \ - * crypto/cmac/cavp_aes128_cmac_tests.txt \ - * crypto/cmac/cavp_aes192_cmac_tests.txt \ - * crypto/cmac/cavp_aes256_cmac_tests.txt \ * crypto/ecdh_extra/ecdh_tests.txt \ * crypto/evp/evp_tests.txt \ * crypto/evp/scrypt_tests.txt \ * crypto/fipsmodule/aes/aes_tests.txt \ - * crypto/fipsmodule/bn/bn_tests.txt \ - * crypto/fipsmodule/bn/miller_rabin_tests.txt \ + * crypto/fipsmodule/bn/test/exp_tests.txt \ + * crypto/fipsmodule/bn/test/gcd_tests.txt \ + * crypto/fipsmodule/bn/test/miller_rabin_tests.txt \ + * crypto/fipsmodule/bn/test/mod_exp_tests.txt \ + * crypto/fipsmodule/bn/test/mod_inv_tests.txt \ + * crypto/fipsmodule/bn/test/mod_mul_tests.txt \ + * crypto/fipsmodule/bn/test/mod_sqrt_tests.txt \ + * crypto/fipsmodule/bn/test/product_tests.txt \ + * crypto/fipsmodule/bn/test/quotient_tests.txt \ + * crypto/fipsmodule/bn/test/shift_tests.txt \ + * crypto/fipsmodule/bn/test/sum_tests.txt \ + * crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt \ + * crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt \ + * crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt \ + * crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt \ * crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt \ - * crypto/fipsmodule/ec/p256-x86_64_tests.txt \ + * crypto/fipsmodule/ec/p256-nistz_tests.txt \ * crypto/fipsmodule/ecdsa/ecdsa_sign_tests.txt \ * crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt \ * crypto/fipsmodule/modes/gcm_tests.txt \ * crypto/fipsmodule/rand/ctrdrbg_vectors.txt \ * crypto/hmac_extra/hmac_tests.txt \ * crypto/hpke/hpke_test_vectors.txt \ + * crypto/kyber/keccak_tests.txt \ + * crypto/kyber/kyber_tests.txt \ * crypto/pkcs8/test/empty_password.p12 \ * crypto/pkcs8/test/no_encryption.p12 \ * crypto/pkcs8/test/nss.p12 \ @@ -109,6 +121,48 @@ * crypto/x509/test/many_names1.pem \ * crypto/x509/test/many_names2.pem \ * crypto/x509/test/many_names3.pem \ + * crypto/x509/test/policy_intermediate_any.pem \ + * crypto/x509/test/policy_intermediate_duplicate.pem \ + * crypto/x509/test/policy_intermediate_invalid.pem \ + * crypto/x509/test/policy_intermediate_mapped_any.pem \ + * crypto/x509/test/policy_intermediate_mapped_oid3.pem \ + * crypto/x509/test/policy_intermediate_mapped.pem \ + * crypto/x509/test/policy_intermediate_require_duplicate.pem \ + * crypto/x509/test/policy_intermediate_require_no_policies.pem \ + * crypto/x509/test/policy_intermediate_require.pem \ + * crypto/x509/test/policy_intermediate_require1.pem \ + * crypto/x509/test/policy_intermediate_require2.pem \ + * crypto/x509/test/policy_intermediate.pem \ + * crypto/x509/test/policy_leaf_any.pem \ + * crypto/x509/test/policy_leaf_duplicate.pem \ + * crypto/x509/test/policy_leaf_invalid.pem \ + * crypto/x509/test/policy_leaf_none.pem \ + * crypto/x509/test/policy_leaf_oid1.pem \ + * crypto/x509/test/policy_leaf_oid2.pem \ + * crypto/x509/test/policy_leaf_oid3.pem \ + * crypto/x509/test/policy_leaf_oid4.pem \ + * crypto/x509/test/policy_leaf_oid5.pem \ + * crypto/x509/test/policy_leaf_require.pem \ + * crypto/x509/test/policy_leaf_require1.pem \ + * crypto/x509/test/policy_leaf.pem \ + * crypto/x509/test/policy_root_cross_inhibit_mapping.pem \ + * crypto/x509/test/policy_root.pem \ + * crypto/x509/test/policy_root2.pem \ + * crypto/x509/test/pss_sha1_explicit.pem \ + * crypto/x509/test/pss_sha1_mgf1_syntax_error.pem \ + * crypto/x509/test/pss_sha1.pem \ + * crypto/x509/test/pss_sha224.pem \ + * crypto/x509/test/pss_sha256_explicit_trailer.pem \ + * crypto/x509/test/pss_sha256_mgf1_sha384.pem \ + * crypto/x509/test/pss_sha256_mgf1_syntax_error.pem \ + * crypto/x509/test/pss_sha256_omit_nulls.pem \ + * crypto/x509/test/pss_sha256_salt_overflow.pem \ + * crypto/x509/test/pss_sha256_salt31.pem \ + * crypto/x509/test/pss_sha256_unknown_mgf.pem \ + * crypto/x509/test/pss_sha256_wrong_trailer.pem \ + * crypto/x509/test/pss_sha256.pem \ + * crypto/x509/test/pss_sha384.pem \ + * crypto/x509/test/pss_sha512.pem \ * crypto/x509/test/some_names1.pem \ * crypto/x509/test/some_names2.pem \ * crypto/x509/test/some_names3.pem \ @@ -348,47 +402,52 @@ static const size_t kLen4 = 2122; static const char *kData4[] = { "# From the Bluetooth Mesh Profile Specification v1.0.\n#\n# The relevant AES-CCM calls are:\n#\n# KEY: EncryptionKey\n# NONCE: Network Nonce\n# IN: DST || TransportPDU\n# AD: (none)\n# CT: EncTransportPDU\n# TAG: NetMIC\n#\n# KEY: DevKey if present, otherwise AppKey\n# NONCE: Application Nonce\n# IN: Access Payload\n# AD: Label UUID, if present\n# CT: EncAccessPayload\n# TAG: TransMIC\n\n# Section 8.3.1.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00800000011201000012345678\nIN: fffd034b50057e400000010000\nAD:\nCT: b5e5bfdacbaf6cb7fb6bff871f\nTAG: 035444ce83a670df\n\n# Section 8.3.2\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00800148202345000012345678\nIN: 120104320308ba072f\nAD:\nCT: 79d7dbc0c9b4d43eeb\nTAG: ec129d20a620d01e\n\n# Section 8.3.3.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00802b38322fe3000012345678\nIN: 120104fa0205a6000a\nAD:\nCT: 53273086b8c5ee00bd\nTAG: d9cfcc62a2ddf572\n\n# Section 8.3.4.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000021201000012345678\nIN: 23450100\nAD:\nCT: b0e5d0ad\nTAG: 970d579a4e88051c\n\n# Section 8.3.5.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800148342345000012345678\nIN: 120102001234567800\nAD:\nCT: 5c39da1792b1fee9ec\nTAG: 74b786c56d3a9dee\n\n# Section 8.3.7.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 008b0148352345000012345678\nIN: 000300a6ac00000002\nAD:\nCT: 0d0d730f94d7f3509d\nTAG: f987bb417eb7c05f\n\n# Section 8.3.9.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 008b0148362345000012345678\nIN: 000300a6ac00000003\nAD:\nCT: d85d806bbed248614f\nTAG: 938067b0d983bb7b\n\n# Section 8.3.10.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000031201000012345678\nIN: 23450101\nAD:\nCT: 7777ed35\nTAG: 5afaf66d899c1e3d\n\n# Section 8.3.12.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000041201000012345678\nIN: 23450101\nAD:\nCT: ae214660\nTAG: 87599c2426ce9a35\n\n# Section 8.3.14.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000051201000012345678\nIN: 23450100\nAD:\nCT: 7d3ae62a\nTAG: 3c75dff683dce24e\n\n# Section 8.3.24.\nKEY: 63964771734fbd76e3b40519d1d94a48\nNONCE: 010007080d1234973612345677\nIN: ea0a00576f726c64\nAD: f4a002c7fb1e4ca0a469a021de0db875\nCT: de1547118463123e\nTAG: 5f6a17b99dbca387\n", }; -static const size_t kLen5 = 22032; +static const size_t kLen5 = 2239; static const char *kData5[] = { + "# These test vectors were derived from those found in\n# the Bluetooth Mesh Profile Specification v1.0. That document doesn't use\n# 16-byte tags, so the tags have been updated here. Note that the first four or\n# eight bytes of the tag is not equal to the tag from those vectors because CCM\n# authenticates the expected tag length.\n\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00800000011201000012345678\nIN: fffd034b50057e400000010000\nAD:\nCT: b5e5bfdacbaf6cb7fb6bff871f\nTAG: b0d6dd827d35bf372fa6425dcd17d356\n\n# Section 8.3.2\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00800148202345000012345678\nIN: 120104320308ba072f\nAD:\nCT: 79d7dbc0c9b4d43eeb\nTAG: 281508e50d58dbbd27c39597800f4733\n\n# Section 8.3.3.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 00802b38322fe3000012345678\nIN: 120104fa0205a6000a\nAD:\nCT: 53273086b8c5ee00bd\nTAG: d52b87a8ce6290a772d472b8c62bdc13\n\n# Section 8.3.4.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000021201000012345678\nIN: 23450100\nAD:\nCT: b0e5d0ad\nTAG: 6078e0ddbb7cd43faea57c7051e5b4ae\n\n# Section 8.3.5.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800148342345000012345678\nIN: 120102001234567800\nAD:\nCT: 5c39da1792b1fee9ec\nTAG: a9233958aced64f2343b9d610e876440\n\n# Section 8.3.7.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 008b0148352345000012345678\nIN: 000300a6ac00000002\nAD:\nCT: 0d0d730f94d7f3509d\nTAG: dda1694adb791652fb6ae04682f19b29\n\n# Section 8.3.9.\nKEY: 0953fa93e7caac9638f58820220a398e\nNONCE: 008b0148362345000012345678\nIN: 000300a6ac00000003\nAD:\nCT: d85d806bbed248614f\nTAG: ef7f4d55e47d21522ebe3d5bc735a5c5\n\n# Section 8.3.10.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000031201000012345678\nIN: 23450101\nAD:\nCT: 7777ed35\nTAG: 35d84e18784c4bf3cb1b4c191dc555cc\n\n# Section 8.3.12.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000041201000012345678\nIN: 23450101\nAD:\nCT: ae214660\nTAG: d146b28beafe7f984f9430502d07aafe\n\n# Section 8.3.14.\nKEY: be635105434859f484fc798e043ce40e\nNONCE: 00800000051201000012345678\nIN: 23450100\nAD:\nCT: 7d3ae62a\nTAG: 52ee03ab84e1a33365e8a61275665f71\n\n# Section 8.3.24.\nKEY: 63964771734fbd76e3b40519d1d94a48\nNONCE: 010007080d1234973612345677\nIN: ea0a00576f726c64\nAD: f4a002c7fb1e4ca0a469a021de0db875\nCT: de1547118463123e\nTAG: 14604c1ddb4f5987064b1736f3923962\n", +}; +static const size_t kLen6 = 22032; + +static const char *kData6[] = { "KEY: 067b841a2540cb467b75f2188f5da4b5aeb7e0e44582a2b668b5b1ff39e21c4e65745470fb1be1aa909c62fabcf0e6ac\nNONCE: 10e0ecb00da5345127407150\nIN: \nAD: \nCT: \nTAG: a82a891565e466957ad5a499d45b579d31acaf582f54d518f8f9c128936dac4c\n\nKEY: c9d9ef2c808c3f8b22f659c12147104b08cec2390a84f0c4b887ca4c247c8c9dd45e72f48b30b67a8545750387232344\nNONCE: 58bddf96158a3a588bf3ec05\nIN: \nAD: 5d\nCT: \nTAG: 3580c1601d1c9a5b1595d3dee35b0cd9e1b115d8b0abee557b2c207b8d0df5ee\n\nKEY: f755dc6786e21f39b595389a51d36673e1ffb94ffc066c03873eb31839be6fa319fd31c8bea29f03ff28831861e60b6e\nNONCE: bd6c80797f1f4c563b06fd3b\nIN: \nAD: 78d88005136e312639572343a2d0daf7483d8235291ee3ac002469456b075243dc03380c387030d546c2b1\nCT: \nTAG: dede80d810fc449a769c79a5ecd2c0d68e9e0fae567781e623ab2098c88d8a86\n\nKEY: 43a0a28fef8b89b8fb0f76de01d802935ad561e27ca9c9fa629347be676a6af758501b6a652f369045da5fef751b56bb\nNONCE: 0f6472f1e589c16ca5ad45b2\nIN: \nAD: 78e4eafccfc87631f0314c442ba4c07bca36f996a5b3408f9e445d6009a87ded16b33a4af9537a4619cab70d\nCT: \nTAG: 11fa62dd8374aabe728ebf7e9aa1c02cf8f2dbc29f9aaf1940313f0b7c3e0301\n\nKEY: acf8e5f1bd64e6289370650b5b3fd773320025c8b229fd335d9461768cd0a17b4bcc946919932efdc9fc84a7f50768bf\nNONCE: 1aecfc90d28bcdcc5a8e3578\nIN: \nAD: 6daedbdc69133b56f6a8f098f9f70cdb7e129e51115df385a6d86204a53412cd999cf2e69f45e168efed4742b6\nCT: \nTAG: fbe0511ba0ec5709def9966a9b05facf171cddd81ee2cd56e7afc867af465f31\n\nKEY: 2773c92e6cddc9a5e5dcaf3893080fd2153f009d807df0b175c76615645f2087539e299d8411b27badb749a9845c5e29\nNONCE: 6d04ed129299651aec0465f8\nIN: \nAD: 44219577e361a7a4681172d120a2d653a53ec74bc487ccde4954835943bca413d55c65dc665310148654d8c1e2e6bc2f06ec344473120ad1f95739b993a57f9ec0b3299cc088f385894fff876fc2ce8ce6b77ca253f177ba615101e84e17ad0e60704cff195dcd50eb48c77de409797e0b1c8c4c5b9215a4a0399954a008267b\nCT: \nTAG: 6ab61ac4493e58e48d071d994a000f1c1f498d22f83c8d2af56b03c155afc57e\n\nKEY: 23189bf23bc4b734410d1c7ae321c42e144a25347a8029bb925e3d8ac1b92f4eb97227c1dece86ae9dea7d127eb33f9b\nNONCE: 30681944cd5d78f46d36ed8a\nIN: 59\nAD: \nCT: 92\nTAG: 986aa8438da3cf4a98f478f90d24908c6a4e848f299873e649b256f5499d89d9\n\nKEY: 463d1148325c5f57af670877068a78203571b8b19f40e9f0373156b7448ab315df86c77d7c85ba6e54b9bc329399f687\nNONCE: cc9d015a4b5a888b36b14d05\nIN: 28\nAD: 6a\nCT: 05\nTAG: f66e8dc794b142944fa46d5c04a3e3fe00291668374846d763f2beeffd4ca4a0\n\nKEY: 937eaab44e7c7d2cd5bbb053c12e6255e0aaa42cbe7d83025b7a2887eff8f098d019c80af849b0ed7da54a5ba5b39200\nNONCE: 2b160d24df579836e1572ea2\nIN: 9a\nAD: 35841a33ba3a6ed3d89a1f76d06c61613d09834847e5a41f8616748e30c14335e5baa43d49fceaf85aeb22\nCT: 80\nTAG: 5e5799c147be0329dbcabf7ecdba6ac595ebc2d06b9d757426fbb31e8b39f62a\n\nKEY: 68a746f382fcc11c02af7b352b9d710c137a9f59bc5886dc374ca88cdc01b86fe5678fde16cfa846846539f67a429276\nNONCE: b94346c033ac1a3d709c4f09\nIN: ad\nAD: ad61c9168debf9974e19759088944e888346aff99f3e2e4522549c8ae332a0f41922972fb7c1d5ff24e7ae4b\nCT: 46\nTAG: 62ae92ff64710a9f260da2562e246356e9d749c3584fb9f40d9572307ccbbd31\n\nKEY: 6622579d1d6350fd5dff432b69d172cc51f99bdaff50b0a1c0f4cda8d5904581ba8657ba61c6936407243d7fb64b00da\nNONCE: a880caa7157a13540d2b724f\nIN: 2a\nAD: 95a23eafcff892deecaf093109d30290d819851ad5c91061510e54baa2b039b114c815da20f0e3ba2ba4875bdd\nCT: ce\nTAG: 33f09666f9fd1d92f137d9f3f7092b47b2bd71a7e3139dcd19a803a6b17f2a3a\n\nKEY: 91ce9dd87c7d11d2c4da41863b6851c40fba786a612e0fbf0d1956a71286dfc61fa10bf7d148cecd72b6ceeb82b68d3f\nNONCE: a50dc3d8fd63d3076cc70ff6\nIN: da\nAD: 9ce8e1a777c159ec775abbd67d85e84f3550c3296e848dec18b61bbd713a98a033805bfe6e2f2a011dd7fd754708e524168142aeee579cae19c7eab78fa7c42fa335f0c725baf556160beef9e4afd1050a2c8813be6bd14cc6982116d0229d53e9b4de923abf6ba99bdffe1d5f21748ae74caddb077d9f7488b394436222beca\nCT: 2b\nTAG: 1541cd745bc0259dd72a212474f5c7b8c121dd0289d674e5ba8d56a220d1f1d0\n\nKEY: 1ad577d3b47e3fff8528e336a43a7ffef72f811e05b5c69ccfe777b10f29061e289178e394a1c87ba483c7f98ea5431d\nNONCE: 1fcaa4757a9e48ed2cb3be62\nIN: 46d30dac550103006c292a9ac05d31\nAD: \nCT: 37616eba30c55595fa0ad5d50f91ca\nTAG: 5c3ac4010f75adf90f81e775b07ab939e7551a9b8e0486ba33766728ed498245\n\nKEY: 6df310dc1847b42c68e50b03d154b73d7f3823354b32759c5369bce1a1b4cd63ccdb911c2dc792acf84b8b8f3fdfb89d\nNONCE: 92e6759a31dd556ff9124d73\nIN: 6daba76658db642209e276ff7c8d46\nAD: 32\nCT: ce1814c03037078b6be3252460af48\nTAG: 46e61913f2a1ff6e77faade9a7cd37a82eff3ebec4276fbddff9266b9c9bd873\n\nKEY: f848c2300995f5c98dcd0db24574d7c61459ca64c084421c6ad156e80e398904417ee745245ddae91be20fb07e66bdb6\nNONCE: 3b177e11063445717f417d14\nIN: bbf225131c821a6a60817cc65bf699\nAD: 4c5ab4fdbe0018344629349feed5d8c3ae0c5b64f2b093576a2aaa1225e7a50eca01a9962c9b4f8fc5c12a\nCT: 1538957e78f3ab0fed77906153d715\nTAG: 2c7760d47407ad7b0d5b85fa4967eaa7b6c0bb6eb16619adde7a191abfdf3da3\n\nKEY: d406cac07630ce2c071732a0ec95f55123486d2677465768dc7db13f90902cf172f92e19f57f5cf7c68cd7bde7ee4b4b\nNONCE: 766aede0120b634a4be6fa12\nIN: 3804d40090a38d4c97a5fff631068c\nAD: 7707b7d0f266284e84c2ecdd5a18832650c3e27d66697616c9e9bb2f8a09a3295de0119582ca3614b9608548\nCT: 91e96462a5dfbe8b7af201158a36dc\nTAG: 56623e5813070a0e2f5184aed83b9863301ca02e3108f7afc478d48305e397f8\n\nKEY: 42bb22a317ed9f9df8119746e9a1257217e5b0144051ca56f39587021d969bc0acc02795f3bd201031e8c05af08ad079\nNONCE: 0a9f6bace71a1ab21f4917df\nIN: 013f7b8c75307158f4f300450e7a78\nAD: cd95a649ae215fe73442a6991e157232cbcabecff6042b87d41557e35b97606d606c3ded54f5d3db7aa2773f67\nCT: e588dbcecbdb7667dccf7fe34f8387\nTAG: b04461748109ed9068c7e9c0446528ef09b01613c3b3aa1ffeed6685ebb550f5\n\nKEY: e1cfcbaba3a04b5108ce2a87099a6aae936ee38acd92b7e6b7df0e3bcb9ad18fc579b5d470ef3e04c23459f509852458\nNONCE: 112dd267174bcd81e6fbd924\nIN: 288a1e44b406aebec7b418674f81e7\nAD: 7809d8011c5a963df14fb8981e874119c60b7a9d897d13a05651759db5835deffdd991fbf98b9aa71c79e48bd701b228ba248b6bed874b02da7fcf28a04c38b81c0ff628846015258af30dbf28ea4f3283f664f888fca545f5fc57dccc4ad1dd476c52fba341182ecf783706c5c458bf0ee5ec83454afba78eb8b5ca17af88ec\nCT: 80f4e1012d76f6180ca00fd32c8fec\nTAG: 6de00bf2fd3c88ab34ca9390f7e559875e43e0f938303816a3a75a35729bc453\n\nKEY: 84172547d8608bd9e788a7bb60df2982963716e45f8e63f0c5033327d85c920c5e3776e314246b1694b739c39abfa29f\nNONCE: a3f1643bb504b7ce9e5b43c2\nIN: 7e76323eb13e64da9b240a57c95c855b\nAD: \nCT: 966487c18f025d67b42a04c30d3ff4c3\nTAG: 8bb03d893f0ce8ea4a6a47245bc7f20c72acf8caa466edd01365d0f74c929463\n\nKEY: 02dee8f2e63b37fe3cbae9101fed0946e05e5090510bef3324a82e3f27456a45ab1b6cdeddb1fe515ad07aefeee6ccbc\nNONCE: 64723d21365d62926d5c2262\nIN: 4f1f132c50a01ad48882ce88655b33f7\nAD: d8\nCT: b102082e14cd9ecc0895f7a6f08ab522\nTAG: 2c09651c1a51cb8a375746236fe258a36e725936ccedbc4dfafee6c3084a4716\n\nKEY: 5db57cf6301bab815d38879b35c9db72fd40ac576d259ad5074d0828364050554e9fc08335b5f2bf066b09e50fbe6ba4\nNONCE: 36e5340d844de213c312177a\nIN: 41a6e910b14388740ea351eb1df980c9\nAD: 8316a6b9b155b2de5e724f7593ecdcee442eaef7b9ad204eda4744a5e648c2dd84f48ee81397e485953465\nCT: ee21d4d47042415ca27d2ecb11b13d79\nTAG: 5015da5a3339389d39d0fcafb56ef4005b342e69ba47930e84408d33aadf5f2a\n\nKEY: a493dd6de6fd6584599096442dd9345f6f2d8fc2d426c78eee2b992b4071aba4ce463f3ca293c84b2faf3e8644b6ec25\nNONCE: 4f9be6f788ee960adc650d86\nIN: 4de6e244251091cf13762d20685e9085\nAD: d15da312b7522c18384acdbf6348b5e105557f1790a6a203a65acd73397524681666743f3145048775ad84e3\nCT: bb1296457daa39d889c8f986938d6a39\nTAG: b93548cea90c34d03d6f5683ae2cc78814531b803d42cfe57623fd4bdc8f084c\n\nKEY: 8cc59ebe2c7375a70915c48d2978a1f720bc0aa2775ce9189ae7b3d5dda9a81e56cde0e0a29939599409b71f0b65f346\nNONCE: b0ab041f37ea1e594f1eddb3\nIN: cd0aeaf6806cb99e6bc1c8c5d830de8c\nAD: 8f4b5a9609df757826dbe7e51bb6a2c6f45f601263cf668836193513cf008ab6b36a7d5447039f1268821ec37e\nCT: 5d5375b9d9cff6d0c1dbd14221509a0d\nTAG: d8850bbc838e068b817c24d018f8f1e1cb8aac0a68392a700f48099f81b6c37c\n\nKEY: f3e9c507478d3f99dbf3e2421e45929b096ab3f3d4aa4ef9c338c5a1a2425c9936b7df602502d33cbafcf781350da77e\nNONCE: d4872a30c9d1fa9001a25afe\nIN: 25e05ea69a956b12a9be4ef03ae9d30c\nAD: 8b346c20e7c64b805d9c8d325829201753069c60b3f221f31474f55cb20315373ccd7c2a8f215e9efc407ae91b05d8b6d693a3780fdd65d7715cdded86c3d6204055812f3fce897f829d1df9ffaaf48885291701ac1765090c383162dd13d6bac88baa0cb2d748363bbb79843a1594ec6d8778854a63b7c9ffeb6d1fb17e90f1\nCT: 61325c7e0d29e9ad50b9c0fec02d7ef4\nTAG: 4b2d0caece46ce2496445883c03234e900189c22b54390b399d78ee4ebfbb7d4\n\nKEY: 3d9b651e65e9239c9e33aafb091b348161ab797901fd0468aed", "d014e4d5683c8f3f54f20ea6bb07bb25dd258df7bcd5e\nNONCE: 32bcf856a14437114e7814cc\nIN: 08a667c2923f87a7db6502478d32280bdc\nAD: \nCT: 5e8e02cc91c732356bb9f1fc599426a379\nTAG: 5449e878d558beff4bc7dfbb5f0195444705cfb259773b4faec524fbaca37ea0\n\nKEY: 2124cedb5f3f2558f8b9a2304a29c0df6102333cb4aa10625aa82cd76ab645c73f3b7cbf7c96cacdcb9e0b738e40c042\nNONCE: 7ae419446a3a105beb2fbcc5\nIN: a305dc4a2e50cc8e7a65a4b10b73849636\nAD: 70\nCT: fcaea620f7e9ed1337214c4b432d9869d2\nTAG: bfc739c8504a4d9033ab1915f46c1bf65c5382fe9ed1c134026ba32c63ca131e\n\nKEY: b027feb1aced8fb3af27a9fd7f531c30991ec1abd9f230a3e5d6ee9fc6a77747013f8e14dcdbd07b0083d0ce23dfa711\nNONCE: a30a6520f933ff5265e6e305\nIN: a705f842d542cb6957fbce21854755c6dc\nAD: 447bdaf34dfab9cc3dd7777ebaf80077f391093bac9817bf02ad98db9d3f271282ecaf0ff19652f92076d1\nCT: 3ddcb07c121b498f1abb73bedb527d4df4\nTAG: 55957a0e884dea22d6ace10e5936cdac891f5b54225349ede5c44715f1064b5e\n\nKEY: ffefb7770a7cf125395703985823f3e926f3722ca0764518fd2b8996577bec03648c8d542af1c6e36b51174b0ba88316\nNONCE: 4c31394b4b24f6251a839891\nIN: f026a1d352c37b204c6c1138abee9a9a75\nAD: 1e7c0f71a3aacd87ea785521ea31f93b1efd0bdf97952e0b84ecd50c706806deffc19caea312b5a9988454d2\nCT: 23c8bae37db93ed9f55f2903e04b7c6a8e\nTAG: 89d0a7e7d921dea5bb54c28e79b612688e42506aa69b141de830c8d63bdefcee\n\nKEY: 453cf5e4f48ce5a961c94af0e1639c156965970f561ac17fe08d5b75975abe3db87412640972e463290800666be80441\nNONCE: b3e3f9708a86c7cdf139e496\nIN: 53f1b11de497cc6ecb411a777dc3d60197\nAD: afe29e074dcce850ac6640230e6b9f66a64587c5fbe8679144e065d3b1700c721833ba8f918e926c9142f5f362\nCT: 15d5f597be46a19566a72c5e843b77f70c\nTAG: a561c3375c096a116a721e9404e555a2deaf3f677a8611694281663274708f58\n\nKEY: 3d497f81d0652d475bcd85cf53bda13f79ef0afeaec09dd679a6e5ea58f87ba6576269f836096d5ac034594b17073331\nNONCE: 3fb1664830821e2b524890c8\nIN: bd75c313f5c8f6007a2185bc39d0af01bb\nAD: 50744ed959e2b8ba5b5f4807e2997ea0b96ebfcdeaa1c6b33853219844592e82ad67abf6ccbb272cfdba6a3e45c07fec4d4a0ebe4235f11d916771a764d9a129d39f6b84f0b5fb4cdf789ca2f5ea306b25d047a9b1a1e2e90905b6fba472e70b2fa25c96602cfa0031f31c68954d7487507081b8e70f8aa1342cb8b4a98ce9c2\nCT: abe3869ac43fd8b429ee8b8539c970bc86\nTAG: 33fcd301c2bf624bccb92a986c2dd5f2ecafc32649ff550eb5312fc81cbce46e\n\nKEY: 353c3e9f87b40fc0281869c68d9d9bee5c95771dd79998c059bc5ceda71f139fe447cfdf340e9eac57f232b9d230e45d\nNONCE: cc7a4b46b02f4e7f96fd34e3\nIN: 44bcb61332930f606276268ddbf3287bcaedb5b25704489cbee63ec839d7a69533dbfb6e95fe5b4694eb485beb1437f0777774868ecf45c8a5b3edafa1d62a\nAD: \nCT: d038d67b8b690519fafa7467c9fb94135f9bf0bcd8247cd2c30da62ddf37a6d9a3a9bdcf8ec081fb4469c0fc2798e2e30afede7cda384438fd01e5d672dcb8\nTAG: db2c685a59cdf304c1fb57b66966a5ca1cc3536fe21eb1113c25868428640c7d\n\nKEY: 3b3786e38e110ec0c8b05fbdb3d9b6d117d1ebcdc0e7d942249fea6baafa31fe5caac227979fc833b104641e8e9ed01e\nNONCE: 53bf31912a3ededc01c91f84\nIN: 6de5890028382aafb186042864c5cca1a77ff80ba4f7f0942dcffa1579711093fb652c8d475dfca81a976be8ca77eb9c7a6b49dca1425610c945bf404ba65b\nAD: a9\nCT: 886939354fa117139f5e077baa186825ee7e2955c3a74f88af3a86b260ee9f9959a90409e7d602e36cea31e606aeaa8b9229e28f7fa58ace6fd217e5cce1e7\nTAG: 91a769003ec900dbb40ea9c9b959882d822421b510ba85ca826bc4af3b5c42e0\n\nKEY: 5a75c97f3583983bbc5eee4a882b766a6708d798a46f71e63b7509af69afd7cf86f9b42df04b626940914007078a8b9b\nNONCE: 426e8bcbcffb6b425706dae0\nIN: c24fa29a66197cad518c5a1a76abd9446a8f24c2dd81e953bfc5c00544c119d67986781a1c754224af234b0ec5e44e78610a4420eb78c283e9a56637c35c24\nAD: 6376835513967e4ccaff9a0c56b4d27a2bd0d013cd54abf95fe9a162d036af285ebc9567a16ed5abfa69aa\nCT: bc4daeef3ccdf9abdaa75591781685eee3fd7825bfe63132817a7e0f93817f22bfca30ed775a773f5bb290aac3a381a01085e861cab7b9fe4c5143138e17a5\nTAG: 79c779bfcb974ad9a8ac88dce5027df5691a3a1163a5d5893b4cdb1663b17aa1\n\nKEY: d1b301c029fe3b81e4b97e08e84dbc03b138f422161c0e74ccbda3172c034b99610f09a9e611f0e9a3ca40af4fcb3c56\nNONCE: 4032c79eb3ee4b63e44fa932\nIN: 71bcf5a5198787b85a66221c22e7bdb9d038dd3e10000555ec9271e54bfefc460ef4e71729ff7ae52859015b49f45df89ddf183fe1e19de3acb032dbaa4d57\nAD: f1cd18ff1e5ad2b65de41e083b5175966625ebebb3031e1027761e407dae4e8e193ffe7dea52ff61147f1b4e\nCT: 7c521a703b7d1cbd086bdc316d4f2ff0852c462eeaa1d7a586c561354be9ed412d9d9bd1f78cc85468750f1af09b7b17dc1ee84c926760d63504cd3a1dfa3a\nTAG: 831f3552890d997f0a8f2d832b6e92e26f6e865424699f0364a82d86ab7734d0\n\nKEY: fdd24bf37b36666a4f641115581ab4bd6b896dd3017006031b3675beed33f21a314363e3a07bbbf4359d9ac02eec847f\nNONCE: 7767cff1a096a9f7d8a9b32c\nIN: e62b7695dd41baf49d1b356e64c6d5504784380b75724b86f5f3185d1a530664aea0e5f9aeef347e1ea4754acaa7f3c233638db234c0e93db02e0bf988e7ab\nAD: 2d650f3daed2564b0df86fa23ed0343634663adfae2c422f80f9d5674bbb63e824f01ad3994834f889133bbc0e\nCT: a51f50a6ce77a22ec472bc18c37d08fb28e77efe55065b600e3edbd9ac97f0fd0eec93cd312ec7ef886cb04e1849526f0a38b14d862bcd578b99bf9a007c2e\nTAG: 89d83264364c9c84ba705e5549abcd496abed3900f65e3daa012275fed18a7da\n\nKEY: 0f88e2d00d2c4bd682f1591ea5f4c1a1090180e1195809cb363b27c863360a85b27814e6a724effa44f298430d6c9628\nNONCE: 6e2e62ecb2aa47c7e5921d25\nIN: 91efc710a57adb57017725cfa26d17d3e2993c5ee66942ca42e770a83763e9df8a455bd408dc1e2661cf301f1dd669cd6d5b4d92a886be0f54527779bae8f9\nAD: d060cbe84271e85f25a3dcb6dbf299551f0dcd5783e3df80468636e491c0100f3ec8316f24240482a88bc430a398b0ecaee5c48a274ffb2d835e200bc39ec0aa86a1c90c9e2dcb4217595d48826a81de90eb949846a33fc26bf8886ca0554e1b8f12cbeee36e65e33cbbf610c2d24264619fa93c44c88e0e3d9d368fdece461b\nCT: 10d99b98ed67d85a44fa57e706a8b028c61ef17f35f6713613d158cad90e826f90ef036a2190ba123f9b68b352ca94fbebf8ea947e569ad45f00e6a36975f8\nTAG: e345bebcc4a8ac01528bc5f317e5c378236b292c2baab6ae8654245da35d90d6\n\nKEY: 1ccec52c77239bdf6ca50e5b702943b23015d08cb1d9bac592b3dec4c96be904110713e52e114a8bc294df26530a758a\nNONCE: 38554b7c40027afe9721e14a\nIN: dac91fcdb3768df8d5ae9ddba1fe5917c084a5d9e6b14eee9a609cab2da34ec9f95cf2d10fff77108477e694c76f362e29b9a9287d8b190a748ed0a929967ff8\nAD: \nCT: e6bcb38b3bfd0b428a14bb3aca01a4a9e54b0853f10bd7750f5bb58d0e7dd18006f8929d7d862e5d6601ef63be8442334b4d51a99219cfedaa31f7ab19028459\nTAG: c4f05d9415840c2325dabbcd12dbeda31e47637437514c606dedfb8ce622edd0\n\nKEY: c82ad4c6f248bc51d3a51b958ecc2460a3c64d669f6c485c2309d26abb3fa84644a0d8c28da8091f90184b53cd556413\nNONCE: 35a29938fb7a31225b08d0e4\nIN: bb0045cec5587e50b148b140b6969612425243ed1412e812aa9f4b471ed34ced6dfa9e0acf3e31455893e4ee7e66b4661c6e1f80b7d6f1159c11387ce579b80f\nAD: 12\nCT: 5f1854fc2fb11fd721755445a1efa5a28607a725ad71cda9a3464860a6a0efe3f58727c0e0cd315f867611232abd72034dfc2b9deace8cf6cb507b1cd4032b59\nTAG: e40429ca19a88da73a7654d7ed8e0621ac2e504b0245615e262ac70bd05a3f47\n\nKEY: b01bec74fe97e5af7db2a0b1432f8b4c069447d2b56dc2668371387f753b03465412213999d2394a4b79873db06c590a\nNONCE: fec7de97d54dec8d36c9f253\nIN: 88ab078d03ffacd128edbceea7ace2e6465f4076097445a5db7f0e61ed817b6e24f22874489049bee0c58d0aa2b42b4db0bbef6ec88d032da9c82ebef57c424d\nAD: cf0ceb3e80a76d1a75f6e070f5d3fee1cd1e2699434f96e7cb3adce12d4a3148dd433b08c68b9d66962f24\nCT: 8aa3c7478b0cd86fa30870957fb5307345f89346a869d508da9d3a4fe36fb3d6a9b0c3c1bc2d44c8ea31ec028012098d6032085af0b54603dc2fa65ff091fdd6\nTAG: acb670172ec3754064b366566bdccf5056eae132e2041f1a285c5883e7eff4f3\n\nKEY: 699a94f6e6eb457b186af58c25118fcea81c8f0ad265e7c16bd6cdca15c9db64bb9a537580ca0474a4b4d54d47412d88\nNONCE: ac3fb6525f4357d831529407\nIN: a7300aa94f3d357cdb272f0a739979e08aad9551dd3bfcd0b5aca6a0972a71b502639e79e1b9e0d22db2f3220b982800d9cebbac3d10d9bf86ea25d3d417fc57\nAD: 19c3d34bb9d57d0f63f14bdd3da06a43a5afe6a8c505f038cb403515876a2765c2d61aa7e4c84e11c999b81d\nCT: 8b472f1069ace78172611369b03073f751e5206dcd2ce3b45c431095f303e70c59bfad3af8006e66e4a68f8fa2ffa534bd76bdef089d07dd38988cbf723393c6\nTAG: 8e7c3c2c41b1117928ca1cd0cd48c25c319c18e009804c007d1aab0967c0d0d4\n\nKEY: f3a7b8c2a39531d5fb3c97bc9224168aa835973f48243d6f046d00937ed428e5d672e22af26e734f0c24f989fe62621a\nNONCE: 65c61af60769672f0eeda005\nIN: 59667fceb2594e002c844a47d2b3935d2c99570b1639f0887fb082499e1d36f9699ff9ef53be3b4236136aa9e441abdc63dfe536e6fc9fa8f332baa1dad577ad\nAD: f79036742501f1ac19dbb2984e09cf5000bc4bc0424082376c307b8f1e5bf74dd29c802139d7ea93d55d336464\nCT: 9375a81f016c2dc59a8e99dc33fc0db7ef99ab2f9ade4b0ba000a614ff2bd13bfbee2d4a2338109c98c1147edca6023cea43570adc503da98379326ace89d796\nTAG: f563869420699dfa0aa84751526bd75af1473bd88311001e49230b09b8ef2797", "\n\nKEY: 27611a8f11cb57d08648ec816b5f3c45882dae394200cdfc803d1a52bb03f225206574ea63b63423da6972bf5a994332\nNONCE: a7f617fe7a52dd76ee443dff\nIN: d6ccb950515a4a2de7c3cf5a73b568f32fe30567bb22b3b46feb7ef07205d3215a3d689b96d4b9dbaac5a5bd6ecac6ba50314b19b37179fff2557c869950e162\nAD: 777282a98b2f262ed9456fed3610a2028bcc4433eb8f028597d3bfa220bdb0c04882de03a276d0191cd1a125270ce1630c1b94e2ec0021ce5c494d2e0bdb8745e6e94a387cbb31a0898965174bcff8bba105f94dbf080059b49dee71c3194fefe679ef6c00065154ea809293b088c0c3f2ed7824aac72319a4c4ad85ea990844\nCT: 41eacc31aa3c3a282ae7638d48fc7541d2f129e4cb3455df7e60259be9a814c8e1642ea826ac1ec7ed1fcc216a6624e79845521e7a8b16702566f27f7a7f3317\nTAG: b959992feb7005410f9ea6963525e3d9244f038731ffab8da8c4ebc72489f17a\n\nKEY: 0d9322713cd132c339c38ec7a75862860de304c70486b89b0f587095c66bfd1abe56f0b34f9ca0dac577fd4262616600\nNONCE: 3298d02dd4eb85a98cb935e3\nIN: 5dfedb1d168fe262d35f78d797560b2634f71d40f438c21cdcb8e73cf9884c11570554f55a6abd23d0e7775a9ab385ae6c9bbd67f08d1aec57347a8fad5a4b8c7b042b03c25facbffc76f0b1ce2e6c07d427eaebe71255d661ac8e8bfe8867e2d947d496ce2318a601d0beed02426311ca678d036deb3b4c65b1f89bd644a410\nAD: \nCT: ff09fe27f12a87d5208bf246378ee0740e848262442b8b9c7670c8a73fe6732192cde43c1a1246743ed49e15ec63c87dc06eb3e0c92c1f286108b2c7e0754dcf1b9c3fc87efe3683289daabf2db71d8742061f93098788c3c6f26328b86e358507a03af296d2c29009562cad3763399e0e2b89ed440f756c16214c8ab7ddfb84\nTAG: 5076c80fc76c67d6e4f9b9d470cc184db62ea7da49cae44cb3ce9e46c2f2ca9e\n\nKEY: 2695671fe86f1658d8b01ec856fb4c9d09a0c51a1b994fc87a3f72bec12052537b7429f11f7eb4aef0b128302ec8f336\nNONCE: 9739e577595418c47b9c10b7\nIN: c723c39be334a0761db795076e81e3dd85e37a57258c7e0e10fe0f48dc31bd5e683430aa70531b7c8e3a904e49bec838e760d07afa9f86b2cf78ae90f612c4560632acb7ea2d89fb1fd5396d0337111c429cdba99c6a52e863e8603aac24a83302ebf86ae69a212cb938e12085cbf73a28f75e4422995a5ec8705b12d4aa8b6d\nAD: 31\nCT: 1569b20732ee6395e605217e1cb419ce57496ba6f6e889bdfa3c93575e969eb7a0410c7930b7ea146e88577376d84f0e824b62890eb84bfe768a1513a12c2958ad1835bc1eabe602cf40f7812c7dd7da955567242cd7512090fca685fdd7306bd98a908b09464961114abbdcd610c153637400a1f81825cfdf06505947fe54ee\nTAG: d07e14a62a32ef1933abc2127cc5bfc1e43bbca663e460409c6faa3a4ccf99f3\n\nKEY: 1785ef6e7016733dd1952b3268639f231e7afa973c0a3db8780b81084c67a1783200149a1ed849ca8b5c14c7b1798b4b\nNONCE: cdf48b73c3c8d8625e52fe11\nIN: 14002f17e056d7f5524537cee6c2061e2741c01a6f9a82e2cb1747887875860d51bebf8d9b63950a051f6b228ad7567227f8a45b9fa7c4ab47eab410125303defa7e3141bd9bc5bf4ed56550801ff3bfc2dfaaf499c192b1e18879b2f59e1230778132818df8f6ad8a3dce9a1d11c98075b8b4e560edd9b5ea180f0424ab3706\nAD: a35e86e22e9a3df65e4c08e5175b4216fa9895a1be6252de911cf98349841494617eefaa007759dad7f337\nCT: 99eae989435578cb57715a7457da31b807b8078a59c2332a0a866eee9da5188baed3f517b6808095f0067e9b4b91cc1424a464f0a09fc946adbe4135a17b0e8e545d2046f81cdfdb233aa3520797319c0884ccbade8235c32d195e7b802017f88ddd86fb630de19eb97f4bf91029c001fc8f1cd2189a8ee6c120e9f1682a8703\nTAG: 1848f0b163e7b0d270e2a0ced288ea6525697170aae15038f3dcbb4ea49ef843\n\nKEY: ba9aed2bfa90eaed9b27a697bb44c715c0209cae6b2c4ddffc684bcf07ab51b0e096dbcfa26c18fc24b63408317da567\nNONCE: 4b850d6bfa64520f1aa1e79e\nIN: 5bcc2ea4d729c84340c5ceb827f239578971c595e915f0bd9d49ed51d723f8d0e8362e69fd11466230bda0dad57ad724307edcc621ebde1e57fa91fee206d81d2bb6ead94b4a804f74b6cae979f66bdfa4ad93d107ccf114c59cd3d261aa6e2fc0dfbd0df5f7c18e80d0699cc1712abbefab5029e35549d2919d0f937d444051\nAD: f80c759062e9ed0ee597406aedbcda9a14261d66a9546f1c939d20cb1d0d0974fe7a9b33d8c93287a6a8d60a\nCT: dae4fc873d302c51e55910e67482bb80ac68e9bc6ef77cb3e57a31d85fe75f9071d0b64026ba16d0b68fa9c0b7e958cf7682bcd329c4174ea0e3f3f9d2e65d82aae1350a53ea7cdcf9ab848b85cd731751f0e2917628e5066f5b1ddebc7dbda5d2d37e46a7a7ee62bb49c4431af730f9cd3da4c1d0e5f8593d8c99803f781bee\nTAG: 58b42e9117fc8cc2ba5cff74b0d92e8b381a444fa837018b15e9514fc4319fb4\n\nKEY: 37235623acb0d650f905f106dc3bfe6fd83192e53056de8795ed8d20c6e58e5efd84584007ecb17de9e76b392e12fcd7\nNONCE: dc441f1c743a92c4b975c6b6\nIN: 960ceb8d80774bd88b7c5f17042ad2e4baac71b4021c548458cffcd9a049291cb0df93076c115b54f9af878745acebc6e8f04666d053b1ed980728043c4fe7f67b2bcb0341d8a4973ed126342f9add14279f8402cbbffcecfc847379dca8a68ba4f2f26141acfca7f3ef558dbaf04629f0f46e43246b19d875be452f14e7bf56\nAD: 32579218062560f15ff966932838460f99099782e79f1f8c41cd9f6eb59b4c2c3d2dae9cd199fe66d74c7a9940\nCT: 49ad8e24a31e90ab1f8dc37dc51dff0f93f1420e79eb108f90f800274a5aa573f64e274cd52f1dbfdee363e4f86e1457bfb8f87ce57aefd34c3a5a3a93db4ebde3f73a3b4c202c993903ab378ae71042ad238e94f400c7ac1891a9890b19d445eb1db60773a3ea165f7c4b2bb2071faaf588daebac7ce09ebfc88f4d9232d9ca\nTAG: 82f908b837a5768598982f860ecea16aee84427371c4de1f1314749b70ffc173\n\nKEY: e7fc36c9fe87a38f9bb4ca67723267e80e16bf39740eb1090234a473d68aed9c96fe2f96e539795eb042276aec5d7505\nNONCE: 83d768746d40dcd695e49ff4\nIN: e61f0e02a70249b62ec9a8fdbaf6622c9c6316599daff421f1b19815707b67587d196b7e1452c7d7609f108ea946675ac5d97ed215b92a451aa6a11717ab7819f84848151007f37e2cdc8aa99969c3d5652aeeb65fc21b621865f47f44eb2c528ee1142d11f513761a6bb2d169126503db5b263a410cadd2773ff931a032a885\nAD: 59114e9f21b380ae6068609ac36688e6aa7c2533cbfe07013ad1b6663bfa42e39f20e62b45c0faa256c1d33caa9f59b1e30d8502bb7148d051451b3d0265cb9fd0d82e4f4e0489ac606956762d8e7b70abd7eca413ddb708f119c342b3d0d5df673769d8df281656d909b68b6f6438edd60339fd84ff69918b6036ad12a0a588\nCT: 4f12807736c9ab32a2be2e00c9a0236394a8bcfcec6037e7582af462a73bf10aa73bd90e2bc24b97f7001ccf653574aea294bc7b30b77540f475e0e846ab78ffcfa1fef28058e540fea43d9017d4efa05c837611b2eacf0034f26cb7903eff7874973c6da7843892bfc676170a75f839e297dc7f04c74b40f4bda20a45b2a352\nTAG: 9b05aab44ba4d1451f14e087be626232ed11c4ed04081f0d4d47ab593fc619b1\n\n", }; -static const size_t kLen6 = 2413; - -static const char *kData6[] = { - "# These tests are versions of the tests from the corresponding AES-GCM test\n# file, but with the nonce appended to the tag.\n\nKEY: d480429666d48b400633921c5407d1d1\nNONCE:\nIN:\nAD:\nCT:\nTAG: 7d7daf44850921a34e636b01adeb104f3388c676dc754acfa66e172a\n\nKEY: 3881e7be1bb3bbcaff20bdb78e5d1b67\nNONCE:\nIN: 0a2714aa7d\nAD: c60c64bbf7\nCT: 5626f96ecb\nTAG: ff4c4f1d92b0abb1d0820833d9eb83c7dcf5b7ae2d7552e2297fcfa9\n\nKEY: ea4f6f3c2fed2b9dd9708c2e721ae00f\nNONCE:\nIN: 8d6c08446cb10d9a2075\nAD: 5c65d4f261d2c54ffe6a\nCT: 0f51f7a83c5b5aa796b9\nTAG: 70259cddfe8f9a15a5c5eb485af578fbf975809ddb5172382745634f\n\nKEY: 31d93fd51c2d6450cf35d9edd71413f4\nNONCE:\nIN: e78eba6c58f93cc2374932fc21e54f695f2daeda3bd1e0121a77d178e3bf5c0e824a99042e8f2522df829d014e4d35a756780e8c07f53ca8fb78db6fb76754ad461665051c4572b2514804d0a9cbae1a1a013b796565eee13a7832ab8834b8406b1185332552d38754dde2344ff4f6e4823390964ba2dc43de136f2235b1d919e0f4ad60813d30f0ac1dad35abe3bee9479337c7b430841d2c722f12aeaf931cedd8a82053f697fff8d07f0af6013da7da58a5dfcf45561943e7ccdfd8d11fbe96a68a5a27982e47346500c0284caf8e6b63c6621e80503a7365d6693dc9a249093dc45221cfd88562e25910034c2c123e44e3b09d8a8a15547285d2596b98c7a0ee9d10b2cdb032d08a6caee1212420b6854181a583c15e046aa202dd\nAD: a4fdd42aad5475ffc1b122170024486406033c8640233cd9b23c286fdd40c5b69eee39cfbf965f7a10c73663f9804e6821c4f62980f8362a580bab446325b009a004b60b1dbd12566b55b42e58d8037d86c1050cd6ecaaac2fb0ef616a15bc5bcd8252fd459165795c500bbb2fb1476e5cfef9549db733be65bde391c810d099e3745a2cc7a94debe1f4ff6653b338123ef7d2f9a602bc9a4bbe757a63f932a802014f2f06c6688faf14332a355b1025f33687124399f55b6a5adb4864727ec6c5334c41d78d1463400925f6c29c0f611f35c9640045a740dad5b4f0dcb632e7f9a3478b526aa9f97cd9f8d3ad094b7922890e7b6d9c67fcc4f747d04ddcd115fba0a8f0433c6fb1bf6011a9cd153f866c76b26d427a25aebc60d10540\nCT: 8d668fb50efda82552aeb5d075ff3977c37929d73f6639289e7c6da8c89c664df80b2387e788d12398d62d3c0ed2f9f918010d41021c464d54f016c4e10e85e29ba3a45793df2ebd6cdf30045363434387bb0d20439f4986e6eb7ae9fd85fe776f7b8035025624c2413ca8491cc6e79fe901b9c40ff3a0e37a7c7e88b56de4fee65861865162821e046846d253982e4ecd17bd26214b0923a4297d4ed9423395d856940829ca5ee74488c3b4d8aa3c5ceade17d8a3f2e45d3ba91360ac1c76d6a29f8243bf49c1d75aa41ba239fa6f3b123e198ba799e3b70c674607c5371894800954eda0264b3b82606433f71371dabc5f1fb3d703232533662920a241f613c38d16b0bad24f4aa3b336af89cdcd2f371e1bed7aaa47c56d17100a01\nTAG: 594ee5c93636cfb5fde940e3d561440a28f6f0c288c9f92e80252e1e\n", -}; -static const size_t kLen7 = 175688; +static const size_t kLen7 = 2413; static const char *kData7[] = { - "# This is the example from\n# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#section-8\n\nKEY: ee8e1ed9ff2540ae8f2ba9f50bc2f27c\nNONCE: 752abad3e0afb5f434dc4310\nIN: \"Hello world\"\nAD: \"example\"\nCT: 5d349ead175ef6b1def6fd\nTAG: 4fbcdeb7e4793f4a1d7e4faa70100af1\n\n# Test vectors from\n# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: \nAD: \nCT: \nTAG: dc20e2d83f25705bb49e439eca56de25\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000\nAD: \nCT: b5d839330ac7b786\nTAG: 578782fff6013b815b287c22493a364c\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000\nAD: \nCT: 7323ea61d05932260047d942\nTAG: a4978db357391a0bc4fdec8b0d106639\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000\nAD: \nCT: 743f7c8077ab25f8624e2e948579cf77\nTAG: 303aaf90f6fe21199c6068577437a0c4\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000000000000000000002000000000000000000000000000000\nAD: \nCT: 84e07e62ba83a6585417245d7ec413a9fe427d6315c09b57ce45f2e3936a9445\nTAG: 1a8e45dcd4578c667cd86847bf6155ff\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nAD: \nCT: 3fd24ce1f5a67b75bf2351f181a475c7b800a5b4d3dcf70106b1eea82fa1d64df42bf7226122fa92e17a40eeaac1201b\nTAG: 5e6e311dbf395d35b0fe39c2714388f8\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: \nCT: 2433668f1058190f6d43e360f4f35cd8e475127cfca7028ea8ab5c20f7ab2af02516a2bdcbc08d521be37ff28c152bba36697f25b4cd169c6590d1dd39566d3f\nTAG: 8a263dd317aa88d56bdf3936dba75bb8\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000\nAD: 01\nCT: 1e6daba35669f427\nTAG: 3b0a1a2560969cdf790d99759abd1508\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000\nAD: 01\nCT: 296c7889fd99f41917f44620\nTAG: 08299c5102745aaa3a0c469fad9e075a\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000\nAD: 01\nCT: e2b0c5da79a901c1745f700525cb335b\nTAG: 8f8936ec039e4e4bb97ebd8c4457441f\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000000000000000000003000000000000000000000000000000\nAD: 01\nCT: 620048ef3c1e73e57e02bb8562c416a319e73e4caac8e96a1ecb2933145a1d71\nTAG: e6af6a7f87287da059a71684ed3498e1\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: 01\nCT: 50c8303ea93925d64090d07bd109dfd9515a5a33431019c17d93465999a8b0053201d723120a8562b838cdff25bf9d1e\nTAG: 6a8cc3865f76897c2e4b245cf31c51f2\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nAD: 01\nCT: 2f5c64059db55ee0fb847ed513003746aca4e61c711b5de2e7a77ffd02da42feec601910d3467bb8b36ebbaebce5fba30d36c95f48a3e7980f0e7ac299332a80\nTAG: cdc46ae475563de037001ef84ae21744\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000\nAD: 010000000000000000000000\nCT: a8fe3e87\nTAG: 07eb1f84fb28f8cb73de8e99e2f48a14\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0300000000000000000000000000000004000000\nAD: 010000000000000000000000000000000200\nCT: 6bb0fecf5ded9b77f902c7d5da236a4391dd0297\nTAG: 24afc9805e976f451e6d87f6fe106514\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 030000000000000000000000000000000400\nAD: 0100000000000000000000000000000002000000\nCT: 44d0aaf6fb2f1f34add5e8064e83e12a2ada\nTAG: bff9b2ef00fb47920cc72a0c0f13b9fd\n\n# Random vectors generated by the reference code.\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4\nNONCE: f46e44bb3da0015c94f70887\nIN: \nAD: \nCT: \nTAG: a4194b79071b01a87d65f706e3949578\n\nKEY: 36864200e0eaf5284d884a0e77d31646\nNONCE: bae8e37fc83441b16034566b\nIN: 7a806c46bb91c3c5aedb64a6c590bc84d1\nAD: a5e269e4b47801afc0\nCT: 8092e6d6d729f5ee7e808d77f3b7a89647\nTAG: dec23ae31e3e97bb364fa18ad85cae0b\n\nKEY: 577e34699b9e671fdd4fbdc66f146545\nNONCE: fc880c94a95198874296d5cc\nIN: 1fd161320b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f19549586\nAD: 0f046787f3ea22c127aaf195d1894728b3fe\nCT: 7520668ef1b845aabf245e66ca687ca7c5b4f00de71afea392cda124893746ddd4e6\nTAG: db5ad3b398513fe5c8d868e68becd5a8\n\nKEY: d1473c528b8426a582995929a1499e9a\nNONCE: d8780c8d63d0ab4149c09f57\nIN: 2c614b4745914474e7c7c9882e5386fd9f92ec489c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f614\nAD: 55bfac8308a2d40d8c8451178082355c9e940fea2f582950a70d5a\nCT: bdbec524ca37355074899f01b7247b1abc24565b997e000f231f0664be655d8cb75f18112cfaa722e1b2e261710036ff919014\nTAG: 45b9ece29df0dd93941f9454404c8d87\n\nKEY: 1db2316fd568378da107b52b0da55210\nNONCE: cc1c1b0abde3b2f204d1e9f8\nIN: b06bc47f9745b3d1ae06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nAD: f901cfe8a69615a93fdf7a98cad481796245709fb18853f68d833640e42a3c02c25b6486\nCT: d75a5a40ae0ac4343f1a52ee16108332b3563616c207c2b22be277a219e497b7e5bbd5bdecaed87a5216e3e49149ac50a7959957264c222577a07c73fc81f0e579a0fa93\nTAG: b70c26c56e34c7740824f9dfcb8ae6e4\n\nKEY: 9e146d7b233987bddfc240871d7576f7\nNONCE: 028ec6eb5ea7e298342a94d4\nIN: b202b370ef9768ec6561c4fe6b7e7296fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de192eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e555\nAD: 40db1872504e1cced532ce4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e7\nCT: 23dea4fb871ab1df6cfb674d2e7efbc969033a11d694c6580aa3e780e4d1db5f1145924b974ce98ea041ecca53c36207fa644b0ae789965084d1ef845cae33aff734113b3eb4d9f1863b780b0f97fb5e3c5ea991cf\nTAG: 81da1dfc98517d4cee3ee885a266e814\n\nKEY: 2834321f7aa0f70b7282b4f33df23f16\nNONCE: 7541ac15c8417abaf17a282a\nIN: c7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b469b0901f2b5da3a956a6e278c940e82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27ff1de\nAD: a3b2a7d832ed8ab959d82ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafad\nCT: 06d3e558b2f7f8e225d76a41a11122aa29eef02c226616f5264c9c1b821748a8115dd4868dfeacc5d167ceedc824f1f7136e7d7fae783bad83dec468c98747524fc2fcd7b86cbfd1c07078fd1b4b9caaae970c729ee3f2ecfebf048c5aba174fc4eab117bacf\nTAG: 5ece142ce1074a09ab8ce810222a471d\n\nKEY: f0f484fae982019a8ea22efd1358adf7\nNONCE: ad4f5fa0d2acd2f1ee095cdf\nIN: c13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0adb4c74\nAD: b73839e13455fd91ddf7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119\nCT: 90046c5ca4a6db850c5cddb14227b5902257e7ed8bc55f85ca24f51558f95037a0567d485b7606d2ec1802de069926e4f69e5ade9453080f84c045438d890290ed69b5e140788d07ed3d38b067900c222ad55b298e240590cb816d90a43ec52203f11ff9496b3dc32d7ac316ac8465496e41b4be5200dd\nTAG: 76ae0503f7b43b1d2db24817f2b61ee7\n\nKEY: ae0c8a20b679dc40c9908f88fecfafd6\nNONCE: 88b0ebec6a2ac13421012874\nIN: c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b9d0f8621\nAD: 664df31eb95b5e17567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361c91452e7d463338474a400ef9efcaa648e93f\nCT: f729ca77733cca181ba8801e001924e20a1d164cc4440a6217a1178dd6b1210837367cf84aa41f92f4123d6740910586f819389d5c750ab15768aed1b163bde5b1fe8862d1621b11485b47182d32bd304ddbf275524c4ece4cfb1361db53dd63e21ac62bb54", - "a77bb5063c869b5f5de1f1b4356845aac79ee6f66d21ff271e02e8bbbae1372b4b8ff\nTAG: 52856b3369ecbb7201b1b0f75872e5e2\n\nKEY: 38f8784a1598bca461211195d7844de5\nNONCE: 6b91cccc96d89e6471bca6b7\nIN: 374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc2d2c51dc42\nAD: 6b38c308cc574839129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e76\nCT: 350bc8baf35cad823df06eadbb0e30e1e4b5bb8171d14c330e8c488f1076d94b8cb7baa3268a5bf164e23563180b9793ed06bb80079288cd348eeaa8eb33cf31ccf89dec998408baae4c3a7b3d3bd14aa76e99d645da0fba0c29a7ea4baeed741de3a5df5ff4044d9b057c4f3ef1825dd0a47aa0b5e92cfe0321c07333479dc86bed7b7b91e6ef368401392d973404e2914b7d2cb49448c55e\nTAG: c974e989ae2b86e92c5da9b0c9b068e0\n\nKEY: 59b17f09c56d170ed1ef10d2fadf01e0\nNONCE: c78473d06a1685ef0bb112e4\nIN: ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f5945c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b1a8a8b1f4ab8\nAD: 5be5a4a089f0ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26\nCT: 6b07754b096556462756de94e5941610f1bfd93e6222899516e00eb1830f557d6f629bc61abe0c247ab6aa0f4f816f79544ceb034b5d9e86ab8679ad67f6dbef521f6180a07b0bbbcf174cd9234848f18b8ebba7d6ae3d607e027cb220c7582eb6d496a980ae3883fab88a1dd9e5312842450fcf68640546b49c24a3ffc0c8c4f539e8f9a34a3bbff44b1bb4cdb339d8879fa4e0c2145954e34fbede7483d25a0494c1b9e5b1f70aee7e\nTAG: 064c9d25f8795d8151b33f9d32d3ac6d\n\nKEY: 995577faa109071bee1c87d5e6772ca5\nNONCE: 5fdec02348a625b49c3c881a\nIN: ab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e5f2eea2c79702d\nAD: ec4cfbee3d1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e\nCT: 0610980d938c2f2619bb8b4408156fb53f595d857feae649a6700af296d0411cbb80a6c0b7e2447cc54c3bd3bcfae38b7bb10fa5b91e25686d4482b14a2b62d386175f9f247e48fc3b2215b2da1c065bb00f9f59e8afafc9ef205f5245d27085021f41b9e40c00abaea48286fd914e558f822659207e965855eabf52723148d84b0a2692c48d76f30f3cb530b1beb58ffc4824517cb6772e957bd56394c1d8b70c9fa2b70a670f3fe36d8802b2043905e469b558575c75012901dc\nTAG: cb51baaa4672b8ae9745ecee08784d3b\n\nKEY: 58ebf03ce7ed2f8d5487936311922884\nNONCE: bfd31cf828f3d0ce78f3c698\nIN: 1932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75eab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5322e47a85cc58e75\nAD: 3f00d6f0d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6\nCT: b741fd48fa7634435db2cb05392004d0b588bc7e9ddf79526706e575415c8b3d48a606c5f155130deb77ec7aff93719396797bf6628531d9d061727bcea2b348060b64122cd1a94f999ad1f681847e57c05da0deabd2fe010212dc60ec980ed0ba78ee9160b3776ae9174c6f8b7231d6754a4143c8af129411063315c6517134ca26d5a94a2e8c6e8b7ad9b8e78b694d5251deb34dabc455dd9f2a2b3fb6f67222de61e917a645d366462d6d94cd265f919f237f06f1986fac17bfaf3a97c24b99af884d0fca5d3307caf9bd\nTAG: 35777ae50d32c572cb0cd778cbaf55e1\n\nKEY: b86fc55f4abb9b65ee1897c262533ccc\nNONCE: d118b0f493c849a7aa7f35d2\nIN: 43f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db067856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e82911e842e5c9ae8fb79b\nAD: ecf42c3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763\nCT: 87454e6cefc24ba38f01bb791333dd0006cfce165a4247833b182efcdb484b0818aa80f70f29d0ec093455344b8f169262f17be2d1635293bdcca90e21f2c210146f90398f44b35e3f2203c7b5bfecdbd973b568d8ed8444d43cba08d44984a295f62c174ca9ca69c173bb7c43f103ff53a886284af46fde5cbe07b391f9c0b82eec218faecb43dc75372478f2ee1bb267602672a4ff5989ec7251034dd2cfb49677fc82c8b209820be1ed2c429a0491beedbe8c1fc78bd62590ba71fd5da363d6da000e8b7e5bae223c0cf8397d3b5ce7141e8b301ea5a737ae480dc9\nTAG: ad696ab700dd5b71d79f4f6f69034185\n\nKEY: edaf7d79c1b83d973f9ba3b29a9b9408\nNONCE: 418f73743ff0546f0d929001\nIN: 0cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a028d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64ad6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a7f567087a5fec5ad1ee3\nAD: e4be5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c461b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad\nCT: 9372586624f9a52a91e7ce12f380ca13840f11fad8d9edf10c869042c29514515673b3dfcfe956e8d3550baae1815bb4cd41ed27c7485c723354e557d18119b27431d7527f0d84c6e76baf9afa35a215624c339ad888f27c338240e603b232cd247e77eb1475adcb87d0443265ac0de45b16c67fdab07a0c0dd203d97ac2e19248492c561912e9087cd5fb73445695b43b8dd8c7515f9c958dc64068e31d3cb615038f5eea84a74b5d0c3415b6b1309ea8092614f2bd944a6c3a9e002a95e524efa497c9d3cbdaa764f8cf8aa9fcc7f7d68a623930bebb74e5c234322651edda21e20eb12c16a76839f31f3b30d6\nTAG: 33a31cae0292d0185aa10ba1c2288cda\n\nKEY: 01dadfe4cc0681384b489f38d25e83c2\nNONCE: c563485fb361f81d44aea205\nIN: e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2cc7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86a2ba1e9cd195a8ecadd315\nAD: 870d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a\nCT: 119f74936eaffdc3e5e7e072ce81e0e1ca91054cbfca127b8c4a94ada042a2452b39cdd02ab897da765cc0f8d84089a8cc5af662c1c96aefafeead785ad042b506fc72556182566263e90009a86503595dca0924d87ea6ac61d4e931025420436a8716d0ce379c5e3437b26a12531c0a1abb3a693f3202f5770f1dd7ec1eada8c2d6c747a7161d19ffbb897710a17e7740fc232fcc244f456e962ebe71f7ded8ca73e07dd44f00fbd023b8a72f9005f9bd4d0d44135294258ec14665309e9edcc82d98227474a9202552d31f1d2e7374d49929c2885696e5e3edc1983432f1dbad351f9cae3cd56855878d9a076c6d3a27f2718e32658f2392215915c020db\nTAG: 5689d9a73d52266977bfe5c1bb1bca09\n\nKEY: 34091633f4aaf225aa02ba9c57b910a7\nNONCE: 6535f0cba67fbab0e6fa0bc8\nIN: 76217fc9a546a97dabc9be41209bd", - "b582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b590a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b57817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021\nAD: b9948afd8818888585a6957eb59680a55a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076\nCT: 3260de6acddb17f93ff06dc7a8955f5d363bcee255bfd40fe5e92e13c7a1c682c6385736284c5cd858ce6ed251b92f5eb10f83970525f56a1ba0b8edba790ddb015307cce877c53a831aaf56f375fb20e58199f6ddb91efdf9983f263c9a746fa2d66bd4790531f85e7ad9a07cbcc00e9c122ddba77b1cc2b37b734a0ffbc29188685227ff42bf33c2e912eb592de1a45381cf6c5c9a36af93af26168c376e8902299e810e07a8ba2e23670c5221110ad4296a581151185553fe366bb4057e61b7a788f12cdfa635d9d6b8ca47a5596a765d58bb7f877242c2e0145d47c300175d7af62a29846830922308b6b69cce8413810184b27a8184bca2d8ef16316f13\nTAG: 7dc47ef9283971e1745fa3ff698c6a04\n\nKEY: d829975798d4f24ad243e4aad474fd5e\nNONCE: 59e25a6dd133944918709e33\nIN: f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f510e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531\nAD: ce0e6219f75c4c31873d4915b1af3a51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3c\nCT: 98bfa05d1dc27d721378bcc25af4899c9c88fcd54d56662282f9b820e540444dbdc57bdc63b60680262aaeb8387e149fc2a759c0246f771dd9a13209c4eaae9f8c7e43439535afd85c9b12fbfc10f8f9f417079857b9e061cd24b7099726528f4ef529d14097239bafdce4d9b51860ad091c8a7d1faf39d44523973cd1df0377339485a89036d62cad090ffb9d05c7c7d79b01a22b7ee5e485e76ca9be9f037a94366968003b73915b027b161ab90fbc6ab78f6ef261ec5789d668fa2b28b1b1937da1d2337507997fd0d80387495d6953b08ac0a3fcd24f1fbea3df9218a9f0f1112d7bd4bb03ffb9dc790306db5e03d67201ab904df0e4ae283ab3d62bf48a6d79a5faac2ab33aa0599c0a6de5677ca0\nTAG: 767e68b063ed300e63df9933d6e10f2e\n\nKEY: e9e41d154c4c1bca018bbc4d744655af\nNONCE: 04ee2cd524db41170f0946df\nIN: 225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c\nAD: 7bc7b15c68437005a4973a06818738adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a49\nCT: e3a3521e3e99ec595a3d9d0839d8d0cb4c0929e44f693df016da34e0d8a1f3f6aae28fa0ac0f38d46ef06a683adb04df301ebcd6ef0abf9ae3cc220cfdbf36ce8c023714d203ba785e9abb05095c4bf7f07a13f9409a5759428e6c97cd4a8b2e1a471676807cf76131ae471fa4e8d15225e9996ce4c7630c4b0a5ebd85db4bcbd79bdcb641a626773560b591adae5bf582f3e92299a60d081aacac117235d6d8094e97b034d120c6759394ede2a8b67e47864e1f50669e8e926ab6fc5cc696e70bb016de92707d4800b25ad14f9c457baa1e21b4bfef0dfa6d849e0951c81583a711242ba2383efc85381ec7228b8e7950a375df405f820ab5dec8b37572897c6af443667e09d48a18c9bca0322efa409e04f57741305ea7d51ed9018cb5d0f00b5d\nTAG: 8aa9505e89a01281f033e9658ddb35c1\n\nKEY: 7b1fdb1a720b9510d7d8819b6d946dd8\nNONCE: 5c73be515c6ec00a10a69661\nIN: c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d2\nAD: 078f1c67d44d6e86eff0c96a146bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d\nCT: db79e91f4458befa47953312aeaf6aad01c3fb6e2cfa19b0ba21ce6698896e62e7ad2cef344cd324b3f0d317d9fe7ce713d4cf1743adcbfefb65e61ab6b323c5f16762ac527882f214539e034719047f9d3c0bc80480b7f76481e2fa26262b0bf426f1599d3d0947492769ccd65433fe70340d8f74fe31540b48c053eab97984f5f670651746b68617f603ef23117e9a8df0266851ef895b58b847e911508dcdc590f6188aabf37be430bbc72746ed7f5f47f45c90e2400d5be0e323824c5b86a2a0ea7c2156f482f7e0ff42923d6f7efc7f4f2cc77915bf85091216bb0f8c35f5274c0c8469ef03ee78b82cb6a5b510e16793f38fa2582ce249370ddf480e212f1cbcd77f89810b41effc9c87b0a80e5a22059b36e1dad294cd158f03d80ef3ed31b5f3b095cacbe5782986a69d5ff7621609\nTAG: 221274b4be8a4fcc765c2ac319b5186e\n\nKEY: 50109c383071e4a61ce18f495d98b6c4\nNONCE: bcffd0fc2496b7eb0ba612e2\nIN: a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18\nAD: b4c98f6d51fee205805a50c163beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf\nCT: e7a4a201f58f66ddc0b8dfdf95c859879144dfa896406f43cbdc6adc148e0ea8f9a82170c5ab54c77dd0fa6dc209b623f0f5cd4ae358af96ec27c78e7245855e94ed1a1182f9d26d45e0872da3fab9fa9ee3e58aa168925d7f779feb77608067ff45b7ec7f2ef7a48a06ee22747ab96e1b485ce144bb3cf97d1e3cd28823628a2f8e3785d9af28b76c53c3d4c741d1ec56f2bd10939f6c79578c308c5e509ba8b13c820f5912d4ae169da4e04f86ff9b1cb9faa432545f7999ca1014f77c08ae9033712dbbc0e99db6eb604e774d5df8f6b928a0bb59e4c662d778d195aa95194a0cdf7688b309abe223048937691440e5a78cfe0cb75d229634aa49ee54a81fc9a6478c8fa310d524bb15ee8f54f572dee30e44eeb9603c8593f8a7007a1b0dcf2e301becf300f20d2e868b104154651446316414b5b5e9432134c0eba97b4cefb90c32\nTAG: f304266924eef673246b3c14389a82a9\n\nKEY: 670cd4d988845b1d41cfeeb1ea740db1\nNONCE: 29c12f66a74e6234ebccf4df\nIN: 706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6", - "113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a2e\nAD: fffbc936ddfedc527b2c9cb69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0\nCT: cc573518606d6416256cb233c66352086706f7f321fb5d69dc75dc6e11b9f7d053bd722b8d74f6edb023e283ac048570dc23dc34e1d344619dc648199b6bd3627590c7acfc738f10d896c0e3fbc3d3b9ef75c20c616d1dc96a6c3661b4f245ace3083590b1d97b936ede9994b08bf19189f573919eceeff80c25ba1584a1a8744efc1b2efcc264afa045dad460d4a97553d33aadbf6dde24790853a342349446741d65d3551ed343e9dce6b6cf6131c9bb3524597d0ce95e6971c01581fa140caf86ee4b53d17befeeeda4f5ce5b255a429c27a169aa075153bd4f1924df1750332aecbd365d8f65a2fd17f6abe9a054b3a2abf02a5b2031282715386c166dcce653bf3f3fb67aa119459bd5ef3bad4ea97aef40335884175d7fb9bbb3bb7f3114cd68c8136e8d02aa204d282403a34a89305725e2e022a9db9857112350e965d51b7b3de7339cfd3f202d18a07155b5bbd11fd64b\nTAG: e3c4a624a012f660f21be3776f20b440\n\nKEY: fc5b726bbc23a67015c35a1be5dd125a\nNONCE: f812b7661106827f31a1e4c7\nIN: e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bbb55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a3d5b\nAD: dc41779816b352803f282410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755\nCT: d64bf4eddf29f08aff3db1225ccc9df5fa92315d70bec762a001a21f564483c43d9fc25e26ef1cd8426f215f4fba46a4fdf5ea96e6ebafddfbbe15ec5a7f8aa6058f8f3b5c48339fae17738b374bda2ae9f0b95d721342d968ccaf1ded6cc9e0d25e4074b722c876565c73a80f9ac25c8ab7c9967b79e5f924697b65ac4f6cd8f1dd6adb5a3c943c5b43d0563ce8656dbe39dacf220e600b82af2b5ef9de009b51fe6ac5707d3b0a15e87ac4c27501e88e9fa4fb84d10cc489b2738fcc751ee5aef230d4b9e4529cd3c580e2c248ce92184fdcccf8d94a5da4ac34acb13156dbc3e676bd26c68e1065990a73adefaa4a58db57dfab709af8539f449d3c49e7172c6ae686e494a92386ab28caf37ebd026d0e670ea85a010a6fe8312fe5a71fe6f0c7c52dc80b2dc39489ccc39c10a7d3d64ad66ccd44638c8c9d83e1b88930d8da56e978090dffb1e04a08303fccf1dbdb1bb160e0f80d4493eccebd984f898ce877454f84b0\nTAG: d69dab4de29ca8e91f2e74888f80b841\n\nKEY: e63611c19ca5deb1db80f97a3f5149a8\nNONCE: ad2cd6491caceee3e19782e6\nIN: 6354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cbc3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6d70275\nAD: fa9f177cd36c990d4b22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50e\nCT: c22ffa587dd3b6425b81890f8eff36af3c64549c5a5f3e1deb44a7f14c6a179b1f76dd01d546a4273fd6d47b6f9e3ac5e9b641982d1002fda49af071d1dcd88ae5d0ad778d846d3db243ee067f17a91bfd808ddca26bfb67ad28303be8f582de507fb89bfc79c10513327c883bb4c6b97729c1d4aa32ce50703636b2fda0f592174f2ea36b26691e6355ad20bd116619dc728895bbc0cd281f58aff68d39e16087d3cc02ef04dcc93e9bf7695cb15a8f2db51df2e22a2f04be96021b4008f50c94cef256995207ef1dd9c0137d4cf63aba4a0d28aa5ff7240bf20895f8e9585c8c16437edb41e51f6ce5a4f965f0abae8bdb7c7abba2ba82eb5ba1dffe56411e51aa87617c62f7f6af3189647340865f92a16987ab784b1d6549099b1a02b369198ae9f8339e9e197f41e2798076b5b5fa61aa7fd7620bbcb8828b2332829d554f21b83d018b59f785e3a2db359b36fea9a8f085cfb668b3a7d80ad38b85e24472e72916bfa2887036d480f6ca48acfcc7c0f471a9501e\nTAG: bd674531985fa355e1ef3b3dbf8f70b3\n\nKEY: bd7d9a251a127a4dd736d0f74e68755c\nNONCE: 4226110c276cb7870cf1c7b8\nIN: 6617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948e63eabbd\nAD: d2f357cff8c172e6652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a98\nCT: 7db6315e1ce8ae23774c2e8826811bc31b2d17c869691248a5b49398465319576c56c2a64e22ab0108c92b52d9a6096f33841643099cf47aa1defed63b7855f3a4586dfb8691c982eaf102aa87888d09b6dade960bf166e48d58999dd08a0802e109186495833a8d8bc5d6d3159824d1b89d4084cb831b8526dfd1c620b4fb6000e45bfc1a101984f3cc51d54c793ab8f034066922905c532dd60c7d96f06989d10c82844f4b20e872538f27333e6d8656b46fd819936124617cddddac8a64d2a81a0cbf21fe91293c8ad6af63536d10c11a63297b620350a6f76e76afbbf2d8c63428d46c9ca123b5022e6d67fccba1011b57aceb10da0878bd873422438cd949df47533eebacee697f9856222344bc9c4876f8435e0b999676d141135a6f42ace8f99b16d86e427f1ea4d4ef524835385ee1cda9f4049c3f6f9226a69b08528bc3970166f6f9067ac30f9d24b7da6bbec4e58286b3b1c5a7711ea7965ecabd02375b38a603d49c12131019a9b2affb801c91d54896c8c29e09f62a5fc0b100b80ed54b70f568d7\nTAG: 9fb615a8c354e10560c3cd37ceb3c3d7\n\nKEY: 71bd6158a17dbba101f840c6638ca058\nNONCE: 9434c5b842d5dc501c774114\nIN: 2982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d5205995c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d505", - "99a3b2bbea36250ace162989e3c21249115a402c544aa82c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd126cc8d0d268\nAD: 16561102778d04ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72\nCT: 6da55c8a9c5a29eaf8dd627d7048f0e6cf1d52063bd0a7f8d073e66fc406f37fb397f789e4bea1da21a94ef944a2a0fb9a35a7acee3d3687d8d713090a1f2dc3d118ca10c85f5542f9f6f40a4a79bd8816efc75cddd4a7adc9ba91483ca70daea0c65e975be46f690a2182602b29d7c04991d2fb61f154f8bedc194ffec5983b12c4f4d9abc0a415a517f4b8923a2ccf1d5213952133b82621dfd4a8379cca916f6ed9e58dc94baaa1c1c7d8491c3341e0751d90d131f20722bf2c44d097dfcb6eb49385dfb8c86dc47a7dce3ffc3eb89f32b4f106bf48c0d69aab448ba315145dd7ebadeff3798bfd004369595f48c9e7be596fc181bac4573d994f6d7a778f353e3aff64c3bd5169e8525edb96f1e97a5617345fbac9f58c0885d52ba25a019a4e01deb3ac14c4739c0bc73f28d4a05bc5b0be11477395f706d45ca0f7fd92697e6a8c5eae587dc9cadf62c4e8c283041211c3e51a23b84bf00d3bd4be490cbe9277268fff3f652ac9eea2734fcb016639f3b673b0eddb2691b10713fd5bd606deda19d9429ab17539dfac05b5ef87c018564cea21fcce7a\nTAG: 9f64a1a1ec8b09b1e64b258744ac5f7e\n\nKEY: bb5e6c7b672e7c5d720c2035dfe8d42e\nNONCE: daa56f54bd2dab11ce5ebc2f\nIN: 95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c857a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6f584f4ab378a\nAD: 3dc7d6102a17877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c67\nCT: d5c7b4282f37776c03c6efe2af410b10caef49943001460800fdb6408f3c7a9f7f32d8db36dcdd0694170975536447d84c56f84c966c28decdd607237bc7ddb15176ca20be0993f309d2749db68666b2efbeb4c68cb3982a68f67114c0dab61eb9d4cf4c23f1847fc36bd561b0469ace73c80b0347af5e88f051ec6cb19ff8335dc56cd3bc6cc81893c9234457c0d8189cf1234a6c8a262926402eef262c4c5149fb68053480ab2b1512a91d50c48dabe637aa410d6a164dbe4f8c1e1c0efce8687dc858386c92ed7fd8b8692d67ddf453558d28998ca1b57a6c178f12f4b64479b3367e8dfe53f809fa7baaf8d1efbe3c9e2d83b0377cffd8d8dc172a1eb260762c873af724248011d9e0cef6971ec12e81d70aec923664ff7f7cda9d60b3464ab14488b243930845e38e93a8683787641b85476816dc73d17a593b68935e4cf71d81ed7dcc9202db65e235dd69c1f2ad4fde4d566970923a24bdee799258a3198ff2e126870252584a1949439b7e32318af204ba164f9f3488a669800703f988fe56ea6b0b2cf662c43e103e2e63b377a85fd8024d3b40ff47f30fd3dd6a0e07e751d07d5b0e4afea2\nTAG: ab140e2a4dfe81a064944610e0cda2cb\n\nKEY: 97b507a2e09cbf5c31f7be6dffc78d88\nNONCE: 3f607f0ec3ddbaaae6b087e8\nIN: 731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309bbcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe16670d77b08988\nAD: 0c962e558fa573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894\nCT: ff28b33337262980b3adc761b8713f01770dabbc1f458516c721c6a19317ed1f1d6520fa7b2859cc577fd92fa3525273f4a87c99575940e941914ed586e7aa5637c4fd2d98e7d198b52924619dd68a214389cd486fbf006ed9c72e6066d92d2278abf1fbf4b4ea1f3d945bb1653eb3c217d7201d5aa40d34c8488532d9818b06e4c0e97c4cca7c9e2ef19ab5a397db27d4465f41585ab60342a3102837cf43c95db008f0689ae7a7970c2ce9fd685e2811393931a4d169701068b6575b47e88bbfba48281ad4b297fc3b265c0590be6b0208f6a27594b0454e55893c68203233b60d08e25fa66d63e76a869a4b84d153c81f1faf46f9a3130f7ba4718a75366af23e4377d60901b960a4926b850f4d4052d6ef1a5c54ffb388acbabecf069a5841a76cf15ced838239a8392149ab2d904b482bc661b3cbf4c74b711778cd61bc38499120b87f0f45f8a5aad51c84595b991d7fe37582b1ff963063770cd0ec9d98d78ef323c8bc939cf3b6035a5e1f5d54cf9af44d49f9cb01b7d1e91c2e0da110a33e372b07402605ae81bb4ef5505ef51b3dc23ef5e48f3f16711d2d72bea5ac90e85a37c97ba2d1a4f5117a616b3865d97a65a08265ea0c8fbf\nTAG: fd76a9ef5ce12640f3e782a40c6d0fa4\n\nKEY: f46e56f5394bacb222b30fcb3f5d5547\nNONCE: 6fc37c122d6865751212d4f5\nIN: 7651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6addae1c3199da8877\nAD: 8d920a6c79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f\nCT: 4877203ae9162588de263a70fd978343e6e2c7efc107064c1a314e210e01633eab9cc234a86f0815e515eb2148fe67023dc7c67616a575c0c1adff2ca1bd7867ca351963728cbcb6a41b5928e83b6ad97e458773e543138f87698c86e6a84725cc6330e3550d40dd3103d0aca5139b2e7f7f7060e34c383280a9276aa44d915460cb664d132056955b2df063a03fe4f844122bc02455ff1558377d8c15419e34417e3c0d5d69b69943027fe32384cd53e121f885293f17cb3f2637261f3c9bf6321406f3f4e59dcd37972e3073573aa5d9f78e021d07b7036405f193c65a2f8d47f9a2193623d403706364f514b1beda6930925c1afa9f294ae625673e41647a94830dbfc45a4d9029d5e028e8997d9f251aa7da65b48e1abe8bca5453482aa6d1dc1168bf4a6ab5644d623ba15dbf10b0f46536b35e30fcc5086184d0eda2af5016f370c9931f1634331458c51b575553686b511f073a2650a1ae9cd2a64d8ccb14194a659bd533e91cac42690d661c5038d0182cd8e52bc751662", - "508d2253460fcfcc4428ba7a55f1db80bc11af7576e6b9ac2a35929bed35ca82fe497a65c24d04c96e6d9fb3bd66fb54f01483b766b614a97e370ff406713d4b811e1327fa52692355e1d307fd2ac67a4\nTAG: e7208823f0abf2571f81c015eac317d9\n\nKEY: 4675ade296a8c507fba35f62c82d9230\nNONCE: 51fa718d52a0279ba9971490\nIN: 32b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd823d72dea41a1c1f1611fbab63d339a8dd47a3a31b7790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205cd0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d5465e4e10e9cedaa39\nAD: db35fdd7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726\nCT: e1e44ceef4e08b85ca5fddf58c4d6eeb9785e0ed50be7856e74dc1cfcfcfe92f0e59a4fa62db0ca641b0be4da12a70fb443ffc46c8f5f28ce467cb484a7a302dde2d459da83d8ca6707fb0c6eda6312e37c095276f9e65b44fc9a0ed7546e0224d639a7ae396403b0db8be55276fbc380181cfb32c357e99a4ce0c33e464d1feab4a409651752a05f2dacaf85125005b92a195628bd314205b8d2aa1aba19d32c789d91e565944478e90cd1d4e10c475b79ee5e7f7aa22456773febc5d0684ee0a26ab27cd391fbfa1168ad28f46b114d31c7a3794cc216626eb41655990ecdd93f97a7594330a78426da7f2e8aa21871a1207f769dad7db7dd794382a0f50dd8dc76ec3245576b99a32314d3b6a4046a56fbe178fc4cdf8bf39c86a6ef320f4cc63e5abb6ac53f6b336fff96a22dbe2e836c3ea9f4b39ed58d01d45937c8b5af0df6a44bb78bdd59c1f1ac6643fc710e27a4fcfca031b6435ec2850289605e29db5911cd2b930a4fc28bce98b30cb2b6b9504ebd561e65efa52759e64b435b99ad26b7653c6bdd21c964d20c5761bc3eac9e2986cee13068c627721a90862fe387382af2895efde343e3c9f13a3ed019a144533af765424c7c80795cb30ec132e7aeb9a0c0c75f2b885a4024325a491eabbd30f81592377e040cb9034\nTAG: 5100a3a60ed7d5837ed8adaf78c625b3\n\nKEY: e198729362ba96f79d5e0d89fc404b38\nNONCE: 36737445756c6060d9e95d16\nIN: 38a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3eddd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe85940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37597c9a73eb47abcd2aec\nAD: 1b2a8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee871638\nCT: 500fd0ba2adea1fc2ced2dce635c5296edc590f961c26c6fe285f4ad84f6e85719ea6bbefff398991c03a423931ff493ea47f97a8aafcb1ec7a34101ee8a378dac29f027c312306f74b6f92a6eabc829c3117ff77b6859e67b37d05d48b2c12bd30251d32ef30ddaa17894373063e2a593ad5139fba87d38a045e2e4e0470dd4c5555ffe6fc70e564502be523737bcd392d0c41e70a594b29f949838f9bfdb6e87fba327c430b75164555d7a01d7bccc33f2736864a2200e4b2c4d7b7192cd22f7549a9dc3ddda269d78a4d98a344cec44508bd930a14edffafbd1f25cfab8a29b75d07d705c3291de774af867e2e595ca8fa2bfb9fb3cf2511552f1c872fcc8b0878c4eec0fd079c7b17bcac2931181897ad50c03880102109a42c34c70d64ae942c73693f85a6d1230a734fb35f70c02c93813700e21b2abc304631ea9d5392c67864eeb47948b7e377bb51e3a5070524aa0abcbe0a624038f6e1b3c062b7661e1471d6cc3dd18143d6237c0e32e80791d39becf94974bd765bcf6bc5a3d764584b025317f64a67d13234399e8e9d10dfee9a77ba887cce119e09c812661b487561acbc718bd200ef97f76a4664fffe64b367bc36f7d03930f020e0b1db0d8d36103da1dc8dc6e0df00b2276d25c8312222c13d8a070b108a1b3a83247d41940681c59e08243a12c623c2f2d2a\nTAG: 7c3eba9d36b26d27a7a0325d8c23923b\n\nKEY: 2167ee6f77730766fe8b4ca6c8f02708\nNONCE: 96bcf14cca5d7c2184dc6eef\nIN: 47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc95fc19c449bfc10443c5c1\nAD: 6388d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f47\nCT: 73c6a7d5e4fe14e991680acff32d660639e46cd0ec231ad155750e53d6597bec3070f5e828e420cc2044d5bdaea5acfb48cba1e9dc52258fcc5e937861e9a970cbd04f10fec4bebd6d8cf81a8925e5ae48d8024f7c62e35aa370994760c827a534e0a309655b3085a2ed8619dd0dfe0560c7dd5e175fc5a5971cdd50aeffa073e206d81d1932f350d9b3f40d4eb6929bf7957d25b1b12d6eeade7aae4b7277b6a1896aa0983ad5a5e5cb5e8e86b1eff15ed0b48149872ee4439acfc6fd6381f3d9527f1d1a1452927beaa3e3ff188681408041aea39f28bea779ac28b83a4eaff7406b08df2e60d66121c853800e56b3659329503bc122e6c47c1e1dab53986b2058685409c4a81b057fb6655de0f84ca770ed5600db097efbadc14f07d80cb892ef3ab12ff72e9d60718dfab82625a79168ac262b4069c0ff14bc5ea3baaa4c0559ef23f2535ab273e3bee0b2d1b4049f20e708fac2430af82a1a5d148164c19a956a3db8e44c8fc7c51af9458c066719884f0a192464c668d37372d5ffa4e2a4eff429cd57eff1b374d501e06b9d3cbf8480642bbd141b208ead6fe46d436507099ce460000aa033528a8d813f3cda11c8c03b427228c5b24b1f0fd15f704d7958aebc580bd5d3034667853a67fa51eef18d102d65507047b12a939f8a2cac8bedc027db855f89ffdad34bc726f6c6641e3c8ac8041003f65cce96cac54d\nTAG: d93bb140c5ad0362ef819fe04daf051f\n\nKEY: 1b63e84a8114f73f918aba186239947b\nNONCE: bbe2973181d9b48e801e3a55\nIN: 97b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b6", - "8d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae170e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e\nAD: 7754de0ce06145d6b247742ab582584c3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9c\nCT: c1e60f8dbda68c60024730deae746fe9fdcbfb9a3c1f26301a87a3c6bea9f8807ae294b62cb48ebacb01943818bbec06f1c842a3d42aed5a75c8103e07180d76f7e17377afdc4ed56905522be60c9dc5eabd5bd8b9a720b661f631dc214ec1a387016f57085ee3472df5a0d0366210aabfdb1ce23ed9480f8f1eead8780e33af36f9a49b8050749507a8b34b0695606b2cb78788c3da4ef316ecbf9500c257e8acfd36bf600a7ec4f8d2c690db5af0809c5799dc7b7788199601573d8d1a91a7c08cd4bee88885d73998c554ce520fdfe4153af13bcaa485477bcb5f55fffa54a4c71c5e61e1c3551ff7fa39cacafffc5cb00608be2b2d803bdfe43bfc256a7c04f536f4a9c383e6b4a3a0695d7e386f6ca8c8a35a77fc9b1d14e202bab53bfe6bd1d1efe3a4715bd150369403b6696374b4498186fed144f5a6edb9e3a863cdb4de5a6a404a0fc3702192cacfb36538e832b4aebba8c3726224f781c51c1529722d905286a1e01a9bebc54001980acfb9922d91122c9b125d4f6376599f0280651fe9efefad310e97fb06670f4b42df4b3ab1a078df2bf9b880fb91b292984416b70809c09e001e30d285a027f9b370e0764715187b797cb4965e7639a9bbaf915456cc4cc45505853ddfc54a38dc46743adf92afe7f37b174f0108468d772fb2b7ea00e8276663f6c29d3d83f3bf47ed8b1cc86bbe8639a564d936a3b065c4\nTAG: 0a6307fd5192f65b8786f7bef96c17b4\n\nKEY: c1ead957027a7303f01622d129eeb876\nNONCE: 04daa5b792d6d2cc4ba08cab\nIN: 47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe28b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327\nAD: dacc20b8d41590570fd882012b1207ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc22126\nCT: 1f2614433c137c7579ff19ed5be8e7897eca62f05797266174d4edb5fa4a22c11466b17d97d961564dbf9d1c45d9b6568d330761b9bc04dfdd31da08d3ddd4e5efd3924f53128ed541a6aab87912af60615da6dfc925b67b1aa3f1d285e25514f502eb5e92c7521da3492043fb06172ca74796b811ca42b349e337615f898233944644d229d05f133e35f879471a04efc3321094716c10b6f81ac7d0604096f287655362439e47641307ef49338a70bc87402b1c5ebd931300be51980ae8dec0345beefc59bd250bc53d39b7eed62f93087f3ba83b29ab094ab8d3143b63e905d209150c544e433d5ce41f00b65e0a976f5138db6ba5193245056734c7209ffb256a2f1ac9840f1bbe2e82c04120f591da86e253acf25b3876ab9e6f434489c43f606f264d1672cfd8a43282b41c34357497aa4f3a8c318f93694b4a04f1a0773ed064d4f426350dc7bdf4a59be0fd4154097c09841ec0df9c0e8f2dd31abd8513925d5d3da72624567a609975a815e9ba51df408bee244b4619f8ce981a6be726da484513cac67c2a4f597f6ac8ab0e96d86394cfcb5b6ccf2440a53a7181788a3de730c2e84e64a4131d0e02b8db2ec11f2af61218ce1255310756d98a0d594f09bd1440adea74720ff2745db30741e8f4f7bae0701443f55a078ee3c3bb63411fac0d7c7c0d0cb05ea56f40cf4137de20d9c5224fd4e6c4c6e8a5868116dc850ab713b001713d13e6ae5098c379b72e\nTAG: f1271cba346522f88ce93726cfde016f\n\nKEY: 2a7e7959ff156f3e69dcf4c3db8ccc25\nNONCE: 6d666d3700475874d600d6e7\nIN: f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b6\nAD: 6d3a702bcf31e90cd2ff6a350a94689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e\nCT: bce5fbc1719b18299c54d224c2a0212cc904f9f58e7c0d8bbf1b09df0c2c08347cb36f2c8d145b5ebc4896a398b6aeeb2db0ba5aa3df6624a64bce91db2ce843a7549714a20404e869497e593990a1a6e62edaa9827288464bd7b37d2d2f8ecb6d67137f2113982d4ea3c23cb0f4609f04bfd73efddd2e4f05c4561fdd3615d82ccef83c940d39f4f7d548cac2ed181e4a60d1f280e25ef8b617796580069ab2fe8caa3ae4e3722eae649e390d9375b6f1b153e6c542a84eb70241e2272f2530940fa3e0df70528ba07747866fe51c3f844c050cc110cbba10d1f8d3321958e1e833c3f4543d4f8b3d20c8fbb7eb1fec4de7e99464c52d97e7bae8608419f1920c27ea0f479bcbbc61cd5cea10971ae2aac0a73daf4e90c47a023d620c2cb246d5e35908535bb5a0fcad54250a29fe53c1a0090794091fb5b3704c6ed52c8fef11271836250f39d8fd9ac5977cc91175e285192f07fd163d62216fd5530da9a048ea458c47efce109723029992b155809eb73a34b8bd24fa647b006a17e1e315b8a6fcb0e5af6871b4bc6f5d690b3edd10fdcc5391648a64d05f3355bc2a13cbb74d1892eafaad1611c23ff96e7e80f0df0819999977f9a2097617cfd13e8fbef089bedb532b331146d793d224d8f12bf8fa63b3b3d9fa8414d63a7618ce7a4f9c52d8c1b2ccd019e4510dbb3bf71f14c2e13452dc7cf859d18f54d6edad075c37a6ed2f05ce6dfa48421670b757d6a138813503a6ea964707560658861a5b95330e\nTAG: 85713c984bb8b5acea392525719dc9c1\n\nKEY: 5de639113d920e239a0d1581e179f9e9\nNONCE: 0b5bc077c27b08427f0ec327\nIN: 545c1a235b88be7e8451a5b", - "f405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc5\nAD: 846f6eb4aa086447f4a7e5e8eef4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dab\nCT: 04c79662edd08ad017cd48a6dc415f564a67d3d9eb48f1c7910074e6c3ae2d253a5acfa661377ec6ca3ba6693e77f2c97a9484bfbbc3bd261fdd25512a9c1e0d2058b0cd365fdab9c14f602945e142025009f87c13dd1dda03b0c49f76cbc3a93d928eee67627efcd146ab2fbc19d26955a646201800366fb17efa420b7c148399b262164c598cf1b011308989b7dcb699110338649603b58af4cdb5e7c2a306164d7e588fe115b4751ba0a83cf849c869b0155b3f934ebe5382e46db1d2d977769caa63dcbbee9f33568261c6c89856f75d597973d3b2a48508f2773d19252e04350b3c88a6696c3af860f9dc7cfc35e6e96279c92591c09dee7c23c02078e3a51af668ece6c870b7f0f65f6b0f38018be91876011b616fc5630d12ce936b6ab725b808108a472ffe55a5ddce340e5de8a279974c39c64a7f5986ec1e48116bec1b6d040e4e291f429c522ff61dfe74f2f4a075e0a6912bb6a6aa945db933eaa90d9165dfacf087a58245b54c2814086ad5f54795f1c9125988dcf15f906671bdf25da87d145dfb22c0683636c61c44ea9b3120d894e02b0d6f8d021ed8423b0c533a043f263ea3b1b06b5d5d7dba17bcccb1485cc5830e7e5b8520f9a1943a3560083e65806f9a633baa6aa7d5b99e5c5d69db446cb39716c415dde4ba0be14108ce32fbe50ec0605b0845e9469aca76dff75ae1f847dc5e14ce8b5455af8c2f6bbabf889efe1dd6ab408d983f51b143558c73fafd09132e22113b36426535b53ff2294acefa9258a58893d7b3a252f5a7d4\nTAG: 07153351dc975adbfb8b30d77c1be155\n\nKEY: f0f31be89acf8d7fcdb2a063de5a9812\nNONCE: a3d6aca502708d448a869bcb\nIN: bd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5bee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158\nAD: 2c9c6974f2442b87c02cb723f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcc\nCT: 57e32933293f67159efa04c375a4d7b8c8a050b0cc39031a3df3bd4bc82839ae1210da5f10b0723e111ce7d1699c78143671d7986f83fff90992ccfe9fa4367ef9c944cd571a3057a65cc1ae7fd7ccf2c722f11a9ae6756ef0a422ba7cb15a02e27aac6faf78fa2c2b08b228b1be5d3e62a5e995f9d3c5f1cbda1a6ed3f551581cf6693d678f2323e2ca7437715dad965024c8d5eabf68e7ee3ec090f56deadb47dff68e93fd8a38ec2b34d0e774f07793cb03d38921632e42b4a092175f6d602ec637aeb1f134067fb54594f33be2d9dbbae16ec25ea7b86a1a88346e0335d7bd2822a3d209a6561ea396c6128a86307da1c14d25b45e593504fbe38bae1a42689b2b53cf17bca92b4896c2fbdb4625d960bc03da9072910eae59aa17070a368a30e69d072cccc53fca2824fcd83ebf6d65e78c44dcf3333a00cf7eea5b3d311a674be8f46b696376f1fc5d70b727773582bd4a59111cdc41d69d58c52505e51e08e46d75372999f27628631c5d7497607adf4a1c27caf618a6dde1039dd33aa7834eb5164e67a208d473f558b97c3442ab23d22081ce024fe616e00e09a7d14386ec3e0089a0feedac7e6c841da57a13358712b75280f72afd0a28a3f5555e024b59d14ed108ea4fb77510c031fb438e6cdc7b4b6125a387e76081ab8568216a6776b7b52d311f48e882d62abc81453d65c0f5effc4abacec68dda303ecd225ed8afcd5638a9c4f5488d9f8963624934c1abb56ba0071bf11d64a52443aa0f3b607557ff340937a53fa50031775550925b2e8f40c744c36317797a952d70207cff0646\nTAG: 429a50441cf373d8d1cc4b37e15266df\n\nKEY: e4ffeb5ff128eb3c798dcdec4c665a4e\nNONCE: 7b30ac120aace497d03de3d7\nIN: 26638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e1315fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4ebf3\nAD: 14fd627004e9a78d1334822040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce49107\nCT: 7ef2888ba3ecb4c9e0b96414504cd46365885b6fca375534e3dc43d4fe31b61acff2cf2d0b698061ecc1addc1519e00b1f3e59756cf70380e9d83352ebde4fd680fd995157fc12054376c690ee01a11875b3e833de136a8e16ae08e80101caac4e7a43042abd81cae91d2d0f98ec0b6fd7e6232fe351df92aa847cc11044a3e07f3f4d8b8b64f039fac77c95f9057cfefa11cc795fec334051a81dfb7e08cc09496934508423cb75f8b051b811179e37ee63346ff3ce1f1012117b0ad3c03fd113f7f932da558244d5809e6af429084e70b206f4dcddcdfd549246a", - "548d51df1fa68274416b27cc2c12b3a6a86d9bb80184d41a3971c9dc0ed906aec4ec85e9eaf4e8dab1704f6ac3f7602b0aadd1ae4ad91755ef9a08e231535eeab932524b2c228d10b9cca1f88215ab56bf776183b9c14b2888dc7dca590f48ba6fc7e974352da98077d0d3f5de4159025270eae300fba5457611cfc4b52846ea1fdfb29ebe4c260ef2d0d61de644cf8c7390a66d15f806299ecfdac0d6ca83def3873f960bd5b41d05e9a718fa0329e2304dd210f20228d7da87f08bf477deabeb93304133eb38439f49e821ca66474ba065c8c6ceff51717b36297eb17bc739feb166455b79d83ef6b12506c5a877f9e7237ace4e451a17969de2ccefb65af407a1df71ac99856d485aebc6492441366fbabdd11c9ca559bade381672c8497cdc86175d2f186272c9b675cecb365f97dd547d14ebb2bd306d80d83b40e3d4a5ec37812b787b31b2464917aca278bc5c3ac7e78ba6ea0bf3744b70012ba4cb5f1b91703504ab5b0134d5c8071ce1f16218c51207448c894cc1b\nTAG: d338cecd6bdd210923d8ed507612ff85\n\nKEY: 58ac0726e0bca5d30bf4d0a231fd1242\nNONCE: 0b9b60c3a690e0ce0106c1bc\nIN: fc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61ff7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e10628630\nAD: 0bfdb282f9e2db0a43c18132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b\nCT: b03db471a65de5cf871ac198ddfedd14e66b6fcb6c42c782a4d3c156beb2024a1dd2cf5efbd87884b029f42c94067a42a165c1e00018f11cbd79f65da02c62fb443ea8a345c34b6411112844eff3572427e45e061913bd578624100e33908ab9737140ae0fea83069fd008af952c776459c6cbd4ab9b02156b3992c0691614567056865b9f39b526f28d11b7707f35ad09d1eb0d2f6adc7c66f8832d8783478166036d082af1a44025a733781cb389612e3c124c31c35ea2a7833bddd053625d96d2ac3fdc69dbb64b9b7fcbcff6c6fb891d974184734d3bb4081d7609d7206067157954b4c6ab68e4a450f01f5941e1702830a58667b947352f1931ef721739be452aa083ea17344cc0a3b5820a90b35bf45ea00fc06df7229080b82b79c3930067f6045c619624958f77096f304d9f31effe42ef405ee4745f1b6c101225062a5bb38665efc428313038a3db8863dcc72de12c8ae41eb1a7b8eb02bd5bfb1f1ccdb1db877ecff08606963d97958ee7cb85b99c5f2ac4f91a922e180d7f3a3b265168d02829b98b7a72c2a2910c0c8c654e354f2e19a53618e4e46501ba8c13e8ee0081901108a75d6b7f601385cf6dbe3f74b3634331aed8eb903119ee96877f90d491dd5d38abd5f002c3cdbd57b04a7ed13fa09c9e2058744e1fa24d3fd87a863a7dd73cca389e40b7aad29a95d6f7eb705827f7308aa4ec9b07b1c98c225f366cc33586bd08e20773bbe0878711b6210392900b8fc933a6a661b8d6fd1a8338d06ec364f9025f1a79ff94bf448b998908c22be5cd6c1aff929037af9b642ff228865137dbe2f3f3813923245c3edc8edd76eefa02d40e7850e502e92e9511571f85fb17\nTAG: 34213558263a230e66e80c4095fbab97\n\nKEY: 7b9f65509a00841930c4087093c0e049\nNONCE: 45003751c40e59eeb10f62ec\nIN: 33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0cba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8eb8ff9\nAD: 7b4f599c829e412edfae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25eff\nCT: 5ba4306c0fc5cbc0028d54a82d2ec3039f78ecefbf3ed98f5b4f83d1b562be3c5ae66756dcd2027a515360274837682ed07c5f1a0dedcfe3d1e63457f9d4020d2b3d57d63401284eac89ef0cd16bef79aa949a5b3c76dab5342e8042e2e0d411816d311aaabd8aa10bd6c18f72620f824156bc71add704e0ac4bc1d4761f9bd1e31f800d0487f3bec7a788b0cea75cc0bb4ebb927e824bbc718236b089c752de68b4fb5b4bc1ca67e166c23274de9992fd30e0752ca561a4c5f469dd123ad45870dc013a47247396afa45ca5b02fbda0fa1c2a89180214814c5bce704ac4dda5be49af225f3a745391d669d7877d1ce173058433b02b714b7f9b43095820b73069e8c3fe621c45e00e41152a413e15bc750fdc517568f021645b6ccc541a9d61237090cfa6e374942adaa1f18d073e627195164fe981853e324d2e97c35819a00cc4d668ab1b8dc86188ba2f5fa76b3ba2303bcad2ce06195d6e853f7e0d257e386764067f244020d9660ce04bea8d61c5a940f502bb68ab6a62fe2e7492c3aaf355d313f4e2e2ca148fa46673848e59d744567bbbf38ab0ec0c799712053d0bc25532ff00f02a3149e6bd9df268ef8e1fa31762efab8102f6fed5768b9abd9bbbac89b40000394158c4c5d2bfe5f3dcbcb5126afb0f753e2a60c8aecc67782fe64f2f35fcc45e6ca4b6751c40adea4998140048456944bb8e2345daa95e989ce48378f8c607182d76b25d12f731b5029c245e804ae19d170a27f35634c64a1bcdd48a6b573959521d388e023650f427cd1839c77e0d56b4511d1986dbafda63cf43b6fe929129602a5314d6216e662cd1659d8d7bc6c271589aa4e01ce45970efd85297f00eb2470567e69a67bdd20fa4ed8b497879fb\nTAG: 15966db2d710d52510c55082f0c3cdb9\n\nKEY: b4cba7822382ec3aa42a95221eda5980\nNONCE: c488bf7ad0031e1ed9870968\nIN: 19cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c", - "7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d8039a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e96599fe335e0\nAD: 6fff534915999ba3c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f800\nCT: 0fd6ce7a1a51060fd105fc1e5d7c8fcaf4550de865dc0f990217c9e32d354a951bee16f53be1f9768f48d7f76c9f2ece7fc56b9e8c27ede94b5a3250ef27874eeb2dd09d2e50810afb7b9a50985fe28b7aee74303b178a0b74c5422d4f46a59e55bf55d7eb0d16314668b13952998205eb422daedb9f99dc7e04e11e8e077289d1402a1d12608e096afc6283643ca77813730bcee2321cf769c5cdbe5c80836db9814843a0ec72d49ea89ddf5e48e27f1e172423412b78fd91da54b776a132df29fffc5c8b41615fc491c43ffa4596430e55806bacb7e88abde1e20ae43260a1258e7d89ba46fecd08b7330409a08449ade364fb84ad1dff4e71434a3369a1d20158d02949edb9716b021271f73517bd985949d2dd62474a36e57b2682218ffa2d5a982c668a52776343d06ec4bd122d5a1bd5ab5b691e4462d8c52226f834290258a83ecf0847246c92d4339ada867f107589bd8af55cb96461aae47a879f5d81c3931fd653d68cd5139be7ea9b98ad8feb9b453f617cf7b8a4c9def78335d009d4139e66e10f642030b5a66fb44d2c07c8c689383136d580b399f685137b3054e40fd7c90f37ea30d52e09832b66251cc9c31156729e9cc5fa37463d89bf3b61a8f8657f6501ddc3cf1505fad36d4d9075f7a366050de98eeeae0c407b31a5ade0b29b1a7a3cc251ec8a918cc8239c3208b377f2e9a7df8aba3e086c33390bbdb4498ee5d194e43a67206e797d22a7c64849d1eb3921a8323d8a0c7d242f3ad65e52b992007c996dc642b858fb7ea7b1d8d6cb10ed3e9af7595367c26d4b01d6c178a15179ed45d44d83d7709503c85985bc1e2cf6200f4d0ff02e57ae4c53c012633935871028e3c7bf0f5035140290f4cc02afce10718198dac233a6dd7ab4065f07242e173b\nTAG: 8ba94213b2a8696d7e203e6bfefc1c99\n\nKEY: 4233eba54fe7537d0127b1a062526d33\nNONCE: fed44fbd3475daf5c046123b\nIN: efcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99dc75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c20da68ee6ee\nAD: 4e0126b67d2a31e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124\nCT: 4b9b468ed1b1b3ff8242f0d2f204e94b0312443ffce789fa9be7c56054c2392868d8826129462bba1b715d87d58eb5521a258af3e9e06d90e26702106242ad01ac6b64908f747306dc4ca142597d3021df591b60cfc2d260d9883f01078ce4db4b11eca4b7b4329962a6e5445857423776b22b802bd0eea8d7ce7d1d47d49a805d9f557b8d67926848668d8bd04cd2a9eaa0b118b9e680e23266785f3641630d2649d952501972d92f2c6e5e7ff9e8805ab3fea94e4d069487ab6767da42a6312c74a7191310cbf58995a94158987a0d3e6778f3f44f21c9e6c1b08029d368daaada4fbefbccca7f49e2f8c6d754286287ea93f69c72f3234acb2e4059aee4ff341730c9deccdda06fb67ab67b81cf5e5213b7c86b03c00ad8e447915284d5fe4e30ee2fe0fb2ac2e5a58c0623c80b40e6ebc2b96a2d5e045419fad0dbd611fc136ca032e71ba2523b5cc45f115389a9c9ef0a28d9b949b84ba637a32fcd3a8687c70c7d0bc4f27949b37d20ed349ad0bf1985e33f74b6974dff70ff72205085c766469b4c32bbd93365e207110b55d477347db18fd003c925b64aa4366212585e882fb5a5643d79cb6a9057e977b554948bf8129ae67ab02ca57d5052cfec2949e86f3c6fbf7fe0e1aeee3ccba5752bac7abce9a396fb6e5ea3af059ecb15937f34aba7fc8edb267ad1ee18c49e5e6f057ea5b0156093c6b042d2e7b2b29bfc9548f91515a6272aa8b2bebc5a0b0d9d610b6c911a69c38d15c2ab3b1d774d68c6d5515012a083dd0cc2fbb420456b8aa174be28502c2bf22c7af3a89686e2997f2015eeb7c33ba40b676b61c84702a3c5c51120dc290e58724d082281b496881a54839e6f0d622dfafec125b381da4823240cd960d63a6890c11fdb9f56a9fc8dc172c98a3764eedf804d1f5f56d4d9fad2d414bc4c58466f\nTAG: cd1e49972dc4c4e0ad3bcdcf16e692e8\n\nKEY: f79000afa6ad2a10b0dbfa4f34e47542\nNONCE: 0437dd10d487f42d2cc40041\nIN: af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05e83596b9ab4cbfae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf00c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea32b0a22b260ad\nAD: 3ffa73ff1c5c481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b37\nCT: 47d6bd87f0ed8dd258b32f01e5c72457dd1d17982f1671310cb329e18fef89f25826f7a6a9abb54d4d216ba214503aed4d7fe36daba69482e4ace4b7c7a91de5a93774732e0bfa001947d8c403165473d77b6b0d53bece68a76cf", - "544583980084ea5ad532b599206b2d618be4e56cc22be645a727a93fd73c434239bc9c0b2d1621e3ba63e625327cdbfb8f7b13997c3d981c340182aa59a4e8cd204c5c86e8c531019f4900410c6870a1bce9c5e4f81bd8134c983f203f7644577da19117a7432c9a7713cf1bfd3bcb055b8601f4f44d33b1191ae1e32ae868bb37ff5efb1a7f67d94d993c0c50074346a6b41da521633be46e299916425fd46bbf4593b1c02df98f68debfcb43fff6a1d7ad6c4b48296207d74a9504670b50368f2f6a2d89f6fa98b39e13cd46fcfa746dc533c8327a0b07cc89b654ff8ceee471eb42f1f07b0abde3ab49478563501e076622c0248bf8e82576e968657fb0efa23a03c3e3013098e86e44a40d21fe0e640cae3da3a461038907f9610d6dce7a1242417bd43d26ba6aeb1e6e3d0e54c1b9839d019ed409eaf801ebb6fb25949a4961b35fbdcac81c9f87ba8e4f7103984ca6d8fbd3d3aa7b13a9ef1bcdfbe4f6d4e6cc48e5cddcb057027f98ffad2a90a7d4fae9427be8e77fb6c30ac38cae71a36b28fb47045fda28a027b1301fa5071a262c5d1e0a695d3244218a88c7182590698b690c42a3cae97ece7b7266aca88dd8fa8f56ef08c28d806e7398691c31f292caf1443508c494007f5de45a95643534f3f0fdd20790f0aff8d9bb432cce36bc857884a28d2dfca0667a2d7a0b0255fe68a2f9cbc28cacfa489fad9d3101a5a6bac3c39fab9a8223bf5de787fc3d9849626cc50466355df2da389c5ed8301e24d2fb6ce3e8081d32340739326b706466897cd40265cbc347121b6e12e04c218420ab7ee760e9eb6b43fb4e4c530\nTAG: a2d58dfc6f1a7aabcc28cdcda713735a\n\nKEY: 5dacb5173b30a28c99e00eb11181879c\nNONCE: bf1fb59bee4e3964b300ce57\nIN: b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14acd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae9061ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd42bdf685c73f9c\nAD: 31abdf1d28419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a651\nCT: 173cedc6203b5de9f4950c055399328756c886ba5f8eb4d3dc4cfb5e7681aec1c9ae238d0dbff2af21fdcfc244d20fc310ab0f53894d0f9d7204de4c3fe8d366b3fe075d7c7bddc79a256d54125d493426f56c0f56b0688921a0f9c6128ea6ccb405e7551750780d03f1e4c5d9ed1daa253a35178e85f5214684ed17614dfa8cbbc17c3620b080531dcf8434b7b38d1d45b45759f2f0e1c694d39e9387479aed05dfdada1672b8fb01935ea13a057884341ea164f1e59f8069aa5578845ce60775e4a6166b99eae120212cfaa30de04ed140759dd071c15a3536421b0e0dde31e6cb7d8e7e71aef462db4564803d1f8301f0cd5befffc1c0afd74ee5957d76c0a6bf85e2e57711c0ecde9427cbae0c214a09b69fe55ec49857df822ceee98d3d2cc2194b48fff88d5c4209b8a5aaedaf5c289884f442db3e5a8e441a4da134c3453665e8309b61dfb007cd48fe7f2c1bc612853917a06370cfbf3cff5c6c4d745f134cd5952986ab100dc17436cef8daf917096adb9a0d49889b75cf0306d31b6d6902817e747918ff92f479bee78bf2070a0011aab7c0e734395430604e6c8c2a73c17c4bf10a1146ebde04b04bb12fc6a189faf983e6cab5553ffb92f34a89e8166ecd024d89115e6b77395eec93d62aa3daa2f5b6db3723d25ac747f0833ba89350b23c2f874181a6e64fd3ecf4c07396c8d90be0cc78139d20891eb729e5f22f99d07758fdc00e76e9b082cb456c1e5a7b7704153e16b564f0bddd142d47b51e63a3c540dff5f32eeb786c48b3256b9d655f3098e649af178dcca88413ba50f0f332001d4d686f566250fcec1eaa4b3615604c9f3e8fb1704018d609904af5d2558117f43ffa74171722974053fd468e02f047703224cad8f7eeca77f8aabf9adcdb2e3e6df4f805b2a900591977b7180a029c8b359fe41b31cdce8a748f6967872355688e932bc64a43a12222001bbb4d83fab619db8f933e\nTAG: 5609b0874958433df52176247da18dac\n\nKEY: 87b8cd45737c8446b21301be1d5d02ca\nNONCE: 6af5432cffee125756ae7bbe\nIN: 2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f972148e9a0bc6c897d4fd\nAD: c82bf439bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3\nCT: cfc53c8980c557908f7d3a2c15e7f65da940cd319594b7d8baed9ad7edba0a46987775b004b5fd0c10306677eefeb8105cf124d0c64a2dac05364138fa2c4e49dfccb963a89956f97bb0340a14573e559d9f937b51fda46206f7ec3361ce566ac2ccb418290e070ff2655cbe89e762466c1559fba756c62de1c963afa1ad18ea47a1cf3d021f46bae6c060b19aaebabc900229086dc26fae9fc9da70af5af3acb02b6d5a570e95ba0d2f789fa077fe06553670ddd0c4e8965a3f5532e93e7fb0ab7e0b9f90cc9b483f1fb79ffa67d0cf53596eac25679ab4f8ea75b93f3bd84d8b8270d6d5ae62a5fe8995e9b0384365ad813edbe7fd9743665338cde61f8d0bf82481b9da29f6682795e7178fc79e676c8e3ff641ae25c667f92c849a642abe974d97718f0aca305b57ce7974172477e90e16d804c450b332339c61c327d78abccdba272b85f4da54154f59ce8dd5bd89e38a515bbca07d1526eac34437c66496f05e8582ce654ced3ee07d4e770da1799aa9b6fd42402a47c6d5e0c61592f11e798cfa3bfc20dd601e86e05fe6ed45a475a1b54261f368877e1207029f50b6d54e19c132c5732ec34552c2c559c135ebbebc7be00233126d5e0dc5e20b7bb37f6b25df2ae5ff44ab390ddfa91435c6d8ec09c4916ce8dd3e10509094cb4fab2ee9f67c3eb351ef221f3e67b7ff3dd7292ce01eab7e298343de449a2d4a0a168860bedfa0754717bf6fa0f5e37930db0e70c66976d34c0afd3ed623df2a10b9c02b2e9220534688e640de5d53f3707c2c9ea3d", - "e7d339e5530504b3a821cd3097784f325ababae463e9e1b34ab0830d5411c9e04bd48a321be1f8b973fbbc6dc03dc7ca2c31b3d9a800ec9d425881468dd9d8ca7f67ba2ed500d1674118d42ccaa6bb18f0a2c4e5ead86234255d850f58f9ee7ef7f70e2eacba6a053ec2e78c27a45faeb4c90e28687ce0d7cd7f8146a6ce8ab3887408e85563889373b606cd5c968437bddb632d69e8e8fdb\nTAG: dce7df76d7d0c0be7f560dcb5a4a00cb\n\nKEY: ad3ff84d1442224006550f6006be543f\nNONCE: 7712c5edceaaeb3360ac7ae2\nIN: e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf836acfa3e2adfcb7f880\nAD: c53c1a8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d4\nCT: f59b5a5d01cf45a8d91c8c53b3d8feb5440b6cb9537d9feb0da69c33827d1a5542e1d2db34f25c399714324b7d31476022778a82a10668a281bcf6e5ef368a2c525a7bc59f46fb9e747424741e8894f86fc157dd748370212f848d23b13dd658c1e2ac1bf99abdf93b53a35b5bcd89cc4406953376187af45ab811e99db9ac2a367f8a55b0fb4acac9a9bcbc1858061860230508de9a777bbfb0f74b2c69a79dc332a4f03d156596576792f43dac2099b1d4af11fa6088a086a25364f62c24969a515e74f29661cc4764842a47cbeda7ff9ef515c7510c16566536273d62109397626a3c2b601bf272e31462ada51a01a69e6fe174082966fc25b6b8b034add7d394717f08df992771696bd51c25c8feb47ce637e23e89feac9679dc753eae62c0ffe7b62d9855ec470904df6bf7b6fb246cd6ca77bf2848f1074f146652461307c5d51b46977ac39c42ac5857b64f9b347a45062500de41a19f2bb03fdb241b309a5b685f408aa4e38e60c667fd4bad4fc3ab9d8b4f2a8735b50d2fb7d7177d2ef9e5c783ccdbbc8e923832117d3ea8cabf40891e8c912d703f37649096ed0e41e0e53cdb19da6467bb1ace8064c7862b6c4829959f7a0780860a598f3c725f3f956259ffd20e9088dcc639a0c947d85a51f6c77e911355ba77fe43e49a1137fccf2d951d4083c7232d095f2e2d003bce91ef9cc9aaeeb046a35bf1b548c78719c553e6ebac55a77509a3f02d71a9fb84ee16a8fdc6b8b1c917f800e053e655860ab17c0254327cfc3dcc9267e2b78dc2082e54895faea0349d9df3eab4b0bd62f5d6114903d8851aa3cc9068f6b03d7924dd6c4fcc08237f05551d528c01f33720c53867cdd375fec867f71fb3b4688eb18ac3647baaa94d2a72391f47e819b4f41e98904322d1b57d4a485fe9c966d4e0967eb415feff49d1baa38ed2505dee1b76bf1fad013918bc282761f9431b1ea4b3ae826470ef72399c86643a308043a2206df7eb354671846962693183df96ba170898fbf304b0ed34b1fd\nTAG: 90f99dbe53f5a8531b2a0e8dca2b7492\n\nKEY: 39ef8200a13e35000b40e9b0b392c982\nNONCE: a4377557abca18c1f3bf774f\nIN: 4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17cb28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea3679bb9a78d035bd8ea9e8\nAD: ad709f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176\nCT: c1545634e7b0db1afb8a166c9f0d81a561841a583d04fec4f1994c7764582f7b11f832ec2de523e4f6ea3a7c1608e1d1a037b7975bea51524bc8f001ea34a2387f7510967cd57be0436529c08144c232ba1f532863255a55b2ea6f860b7db366ec8ea366e62187837ee8aa47cd9a8d687fafc31680c4af60493da7adb7ccb8f751ce6a6e30ec1f78bd169571fcc0f208d3966cd90660b8f7c2969bcaa8368172cff0d0fd27d732d9f7869d764efb36e55ffb96a1f3d8f1e6e5916e3e97e1f5a12f8dd965466a26274804f19dcbc7ec872cf662854501f37ef5fe348c543511feb61dfd96c5d429c83c7ed70a1d5beafc241c697a564897c9fa9819fe91dce3234d7632ffe73dd1f7c3cf0bf6d170334d2c4104a6ff5dd92038ad91e69f2685ccc380a9fdbdfe7f9f47c3a05ed97be25e299b8e71905f71c68b492be8545433c99b64f2d53a9239dde92359cfadb7fed301b8d8162baea533be9c9ea11964ca6f34e4d81b968546988afba059fa4b4e6d9e436137a9d991cfb867949c1bf87b1d61a5429d4bf549e66ca88b309cc65963baccc5449361dcab294d8c817717f848b942dd11fb1a8015a89e9bed4cdf51b4ff3ace0ab474fcfe16ba2da81b59a5dd7958913c92b4f6f067d2d350111c23c477138ebb40a99e0e55e6f609d74565c77bf8460e6360f4bb54220176baffdc96e4c37529ca3a38b3ef959d3ddb3b2759141032e54aaa8e6b2bdc928f01974f1311fdb15ace49d7d5a026e77fcdb5e9d7442f7bfd04584078804fb3aff740af89401771047af2483153b4c79923980cbc5695ebcfebc32ddc522f9da5b1220961555aeeaa2d578538691ef8b9f12b5833cc4f3b18d7c0d8b068e294c82efb95badbf590a3b4094c38f334d7ed32934f7012b87ec4a49bc0c2b7fb98365f22962d1e45d99e190655ce4213275b1e422976bbe36104027b96ce3e52ff931548e10e006c75747c59e3f7136db301eada16585ef15f4589180b368babe64b114e36686282d195d622e89f04d56f17c718d72bc6c577796a639e634a97e7877258\nTAG: 9563db087214b10c64e7cbbb9dd21a83\n\nKEY: abbe5e520c0ee79153c976d71e5c6dd5\nNONCE: 76f4857ba2d63e04d6b69a2d\nIN: 5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb7", - "14e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a78843256913cad2727f9dbc3a8bd51daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c7550220b0b5f3c6fa8db73\nAD: 16337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2\nCT: 76e3480cee9d48b31d5b1e9a01e79e713cfeb73d742f1fc1e8f99c8e0cd82e267c45f4270077e86996a7e5440a781861dbfdb9759a6ce3991fbe6006d0de04658423f54154c8e5945dad96addb8bee044308cdf062ef21fcab25eb9a91f100945f347c865211a1087c01f245448322e77b826a22287df3434af7bee91d7a278fa59689656f7d93270898fc68594a4bea223d365aae03f0dd18a2e525f0c142b28776bd9f66fa2c046e57394488d5526fda62704e90f50e9752bf9d7652b010f8407de91eeb3068b830d0cc9294bee9629161df4cc7a1a216e55dae077864999ae72020346e813ca8fcdf99e417f26b82653908d0d6eb50ec65814f61b1825cc29c4679a9097e9afe294775e498489ca6839096f7bf0b60d3ebd016d83076184b272db1775f5eb3205015fd45fabf0bba9a990518c8d6d0c478221768fd83776253dc843eea8bfb66fbd2b9977632ca0aac7efc9528115fe4394f460d91c1b74fceed2952c6abc46b61fed85eb7414410731106e1a7be792eeac86fd4bf2b1ff2e496417fd8c0c2865e80837b2b73a690a6d9b7fea83687adb3a004a0d9fc9791c572d916a1b72f3ff5485f7d24e08c65a86079dc2bea698c43a3b2f2e5a8f335da4376aeae4d7fcb509bedbfa0e8fd25a711af45225d764534edcee4bca8e1470cc7d187b0bd9c26866baf8169289653aeae9b36277ca22c2a0ce3f69b3a40dd55e745b0b7467c2ef6a8a10151297eac1365ee475239d8f254806c8d92354757df8cb12d3dcfba83e05c303bc157c7be49da40ee072774ea7e4ac7044768418e64d965eb76d14bbd73be18d14701cdb6f8ee32cc1fef468047ef0ac649fb77843f0bb751f543339922bf34eeddb8140220e6b45ef1cd180697c651a352d05c77b705436f61ec9d35f185c5ce83b210c4a4336483f49ecd538dcc42a22b4f77ecdbb8cc36b8a499ed5c39de1fb6e03b0769639670fb2517c57f183eaf56148e1625adea1efb9b888e8fc3d83ba05c35f8509bd4e16285911462d77d9b270ae278cb902f6ff7970211cd53f1c310cd14a1787009cfd041c29933edb6e672d1d5\nTAG: 8954449b3f6a09e92ef2e33cb57c695d\n\nKEY: 100c6c8d1e88b842aed09cd16a5d78d4\nNONCE: e2d7712e40234292dd1aa27e\nIN: cbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c\nAD: 0e2825fa3a69b798030cadfb168a1f88dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b073571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0\nCT: 4b7337e4cacd72909775b7b8b77e3a73dca810b4642310f33a58f5548f4876d20b828a303cd85241581372f94d2582f79030e13ce68835836fe194bf8e68c22a39feb10825b80b4e2c69ce430b9b56536334616ea3f4610ed7a8136102fc22e634d5fae28cf518630c5f159ec3bda66fab0896f789c7431c9f6033c52e7082b4b65caf82df07266b39a4f0b93867f0e94e3f5065fa626b4ae90dc70cb3cb5d9225bebdf7de553d364efec3eed41c15481d2ab7f8453af13ee769c6a0af2c0a04b61f74302211e1d201ba91eb73ab2a199c4929b903e91172e4c7256d6b138903a4707f2840952c07f9ed10597d023efabc587d2753b28cb809d678b8306ab50bce2f80b9c5758e8d3bb3be07e7645ee858288eac7072272390dbd2915742ebe44de3e56caa0a9c7ef8d42df94173657a4bcbd183fc3a8ad1764606a8bc98793e240fc5e18f3f86cd082dc4eb11576fd29097ee7109d444aac300dbc930bd1d6d2b7f3c69cc02ccc54a86a627603f3e1f11859efef34bf5d11b16d11f9e5b6e985bbfd3e4e3bdb94a48cc0af7eb6c212c3fd621ea6203a5c2192fe1c25ddafa33ea774da1445191f5bb266683cd150cecbe6e820ce3c8a210bdfe407d203a8d9445c216adf892a0999a026bd8d958589f3a6aefcb5ddacca2285f2dc20ea31f43d6759ed5f46c988587f93d6b90d335bb51c76a3fea6f7513385cb3c1b8087e88dde0cc6ce55e7464e6b0b32e777a4e34416c4ecbe1610658ec0a05550d1dd5cb51b15fc3365f32b948dc28342b2b7ffefe63f4842399d6df28b966510e4aaaf5b5f7e4c470ff065fd30d56d085429f89093a291fd7e516b8e962b0fd2faccb0be3e4c62dcb7e75fa5514f79a07a8f4044cb253074b8085bb925dc8302ad9f7fd0d41e960a55f25f31f4bebe6a04775906b59f124a64f5d55caa55e1b858d1383ac7e4b39fb959cfd61acbf0d64ec6733d15e96137821417829c999ad93fa735f543fc73a94d942384aae4e330cca4a7d694627684267d3a6d74d6c140f84a3e10cf58158ccb3ee9c7ad700b08bdc46698707957e523a81f9e683527bd16ebea1\nTAG: 9ee21a6ce2424d9ab143ceb318e16819\n\nKEY: a646ee4b0e0dd43479849864311c3f74\nNONCE: 3f2a6cf9d0dad34111493f0e\nIN: 55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8", - "c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a566e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce9\nAD: 7d000237e72e6de6176fec75f5baa6d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c1\nCT: 796320131f438a93c019b4caa40e9f183ab467d30ac181aa5f2a0e07295f1d07946c4f2994a3ed2ad8522d5ef3fcdaf6d58e1eb03f479859b262ca1cb6e950c24b70a5da75b13055022602f39370a48337464ee1100fa9f6a45bbf793226c358fd91ae1b71eefbece73420bfc804a8d6499f044cf250a9c680445aa54639308c10631644ec3367cef458ab24d0dbcea8168563c062af8f282eed1ac778670400c03d30dc4e1a8f3172555ef633adc99b197f16bcdea6c24b2634fc189b8dcd3a52b56b2aa5099c10a830aff238d1bffba89603352946048fb8e9ee72ce2c13e4fb717d83a31ebb67d99049ed49e58d36513fc399f0e05e3693857e00df98707c66c67b87a2a6aa63fa68fc829cc3813f831f06933ed182e103bff8fdb16a6ab5b9ea8f390a2248c9923756f3536f0e699e3af05e7a3483169cb19fbed3f86335a2fc071af6ddcda9c702a584493294d37bfbf1c2d35a3db8b4b905a3f08dc0e691e6d5264446978fa6d85d37bfa0f7c57630afb61e9c67bc130fbadff95cf8d25fdb00e10f4ac451f6780fb763eb5fe9c34abbdfa44e72346a4ba258180c134e9fc5e336e0aed9a0bc7ec3dc22fd0a38b245a512ab7cf0aa888e2b36f02ce8952a0eb69dc28afd70fe9f1bd20b12586d839cd86ea95cb03c8cebb0af0a6d8ca82d6fe853e5664d30db557e28faa695a903e12efb6b6bcaa9c30584121a662ff4a1a6850e9b005dcd194bfc418df2a8919749d8a82fc33ee741ba855caa9f60402bcb9896549ae11131730d7a7bd1011633f759b302cfd8a51afcb29ddd9600927867776e961d8c2a7ce403e1723d11fa92d587c9ceff9f4920bb4ec52ada70ff98d7c1d4b7f84cefba39031f757a86d78c04433b7085a9cbd44ee1cc8c4dc2dec2a938871bf40b2ed113e4234dc5331d536331c5f8552ee39f288028d8d7036d9acf9ff96e385a099a44f51e46cb73a4e9aad3e5b40573018a2023d683f4ee886236d9b3a50edeb69549462a4a496845d08f01e1de332bb2e3d5ab3e9a2adad675fab9eab0205462a097f4ca75bf59363ffa1e2f9dbd2831fa3ccf8b540de72eb613a549129e8d40b8f672b200420afdfb\nTAG: 7d11d1e35aa29774756505f036a0c857\n\nKEY: 9c73a26fa433bd4437c1018263e7db4b\nNONCE: 580a120d1d29775d9d5ced67\nIN: 10ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e0746027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de\nAD: 874a859c5637b754a4e7c1ddc3f34dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f\nCT: 26e09e3c1c694166c798b8eb3f290e8709de7cacafadef90be45e751ec6f0477f6f72e19bc0343258babd08efb5ff4f82a3aa8e8b50f93c4bed2d1c0bbc07443606487a54f4eae3dd09b3b02232276c8de51b05ac31c64bc960c8d14b953db9e84c05fa9d2c3a286413fadb00f1812ff0a9f49b91de3660fa87e8aa73f11e0bbbecb8ca9be494919631431e29bcadf6883af673149c038a820549883e5d63ec5ddbb5d49817643f29c9665a3b416f67d28c4dbfcfce80132b3e120816c156947a003e36dddf1ac9652f196944c176d6369c25dd136c7880b20e13611dfe52971eafa0055f25cb8969ec688078cc8e7c2395ec27d7d38f0db653b6ab4c987dc9ba33d5cf5d1c05f7fbe19e639ae6baf87792bbd0adb236e4dbf302e93f26ccb2d7a47c8bcacb8f6ca4ed5302a2f461cbb0312d3bff43149a70b8271572797b52bf30cf5ae808b225829e4638fd9f2368021c6205b505406145632a9842ee338a796c435608ad5a92361a19d52b7f8b348d7fa16b3d7775c58e94069aa01bf470338dc28411563e610563ee8a8fc01fff824f63500599a7490f74a59e3ee4612b76871830066c4e3eafcd448822b4c08acf4935f59942bc3cc83e497ee8ad641bf329f6f0d9cf18d40794fe7146987dd6e29c3c862f5252a8767d966e0141b6cf0d166f18b658d8343b698d0a91f5fdba3ac2c32ac24935968959b67f06b985605bff2fc4afc2fb86d6b4e70bb606bc8009f9ab59fe6f6720fdef5f530eede5ee0cc48071fb9d5eb0ac468c820d161a6d09f7d319e3c0da450a9bc6a6bcd37c1f59b3817fc85dbe85ce050d72758f3e01b3e0fe62dd55447b479fb7a09b29122bdeb315589b568ff9a20850b0bfd20f220c05222d784dab107691974e426c83aa12dfdb5693f6c05c423a7c88b72104c0aba00939f9b7d0f92920f8b166512f7ca4d437082011b38fcc3596a125363eb5872722eca03132c8a141227fdf679b8f323ebfe227dded8a2871c1945e0bcfdd8b6c631e293858fa44ea16499144e72797cf82ec32c966c60de4aa921f3b754075a4956c00540cb5800dc97fd0de66936458022ba2498dbee43a99cd8e7c6ca2aadd1f63209d2a24c84a27c13b9d5dff7cd27\nTAG: 68ef1df2583bc3743bd612442589dc24\n\nKEY: 6269b478e1d79f3727831086620e79dd\nNONCE: 357fea1c84ec4de0bf7d6afa\nIN: 2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496ba", - "f4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a98e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c3\nAD: 0377ed6ab683ea82545de480b5f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d0340473\nCT: 096e0130b0e57de1c25d51c748ac53ab8eb5f834ca5efcbfb9f9f950393a6bdc9475bc98a224ea22fefa19fb1d9dd5cb06f0bbcc266c78f169dcde51a7864c5a5c5996175b511dd11c6faee4f7afce3c499bea2188dd443c654486ac5a1b4d113e38cc5c2bd730c3ed87696caa6feef8f466a3323679fde56da63048433d78321388125a9a59d8728c40485299fb0a8012dccecfeabbb7a0343d03fcd770c1b5ff13116ba845b90c715403b5b7588094dd554cdcc1a166ed872c75a7719c83e71b9703ee90e4909e18822d5d2e64a851bdc30b2915371903d6748b89af3da42d041d4752fa1b1947ee12c5106404bb6a7a3d47629841da3ca1652666fe15b9ac2ebeba651baed43e6991139f90cd7ad9abbdc89222086da0b9ca7f4e7838fdea61fb815c534a878d7cccae9fc07aba48ba6fa7bd3a3b448e99267eaff2834a2db3084f28685052d2973eb7c74bb319a232eb0e1bef7d2827081310aaf1368656f7c64b1ab1ef3d4197b350154e18595aba352dfcbb7c0187d8ce67a78cdef6af01b3cc7f0f76d8a9de741c87823f1e6e734dc60cae88078e233e4e8a525148a56572d67ddfbbeb9409ac01076b84d9998e2d10ed62e2288f440f5b54fd7a5a1812bca2ffb9319e56b674ea4804ba0f6d92d7aa7a5e1a9f403c3c6fa8dca86ca4149f2d0348150395ffdd382698d0efb7421fe0ef930b5522ffbf122149a5ccb8bb6c3bcaaf935d839b9b820e0f199043105cebb966a6a4e588a99d20d89c61166c257cd6bfa545f0af914416f8fdd53cffc1d99b27b6c3160205c8b71af69cb398b5cf8f72154f612ee0778fca187a574babfcb6a9dd61624f8d6ae247b7c15be83d6cedad267f847a63f58e4ed7136de31126ba114e5bb94e932e3a10be4da821f091ac27b0c3c73d7fa6215bc5b85bf8227f10dc99706644f11c3a0d5ae282477513304c2cbdc1b5dfc6d6314da4b20eaa43a784fb8435c0be578c409291866073c31bb6a210b587ac009ccfc9fcd342e07854fb664b6cab7506d5248f8377314e5fd6dd17ed871ceb5336a5ff7137aa45d211b06a4cb0170ed25838ba8fc1041f516a127c245ccfbed4ccbbff11c0bd557551f86dea82db1f01ab97b9b19a6cf94e405834161421ef056d96f3482b2bda2e\nTAG: 143dbbcbbcb66c7ef3ac9e730360669d\n\nKEY: 58cdc99ac30e78d6238b5478982a2b4c\nNONCE: e58537a34e5ebc37ea72f321\nIN: f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d4351c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac257071132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132\nAD: 7840ceed28a572c5186f25462a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c\nCT: 9662e1becc3ba86c8edcfb3ee94d3ccf2cd37f7aa1988bd4cb374cb5f3cf4373cbda8c71832fcced0531c35d035fe6de0f0086740a62b07e81b3a0f98fd89f22243a4e2e81263c3d4846a3e54977ce7617702e43adf44783e279b174591fd1fb231f2d5e460a866568c867c8e762716959fdada879c77b7aa613ff15ddae4727cb3a2abf192fb74cd6b1eb5b632953422cae683ec87d6eb69a57c2021232181e8f74883355447643d9fdbf23b00f7ce602bcb1ac3144387610e045049c7cb1bf1babfc18b21ee05da3173bf2a0d8833698e7b3ba5e72996f6dc43db0228c81ce3f1c644090b922bfd72dfc81b60a8378cecd2ce14b9a53a16867476e08bb99f0708477e1c6af6d262f543ba4b3cd5f3309940fb31691b9e50ed2f3159afbe8f3c95a8447af98a76ddf5a531939232273c669231091f15e8f819183d8d13624bbfd6cfb9bf781bc74a9b4ad631de4694e8db879e38508a3b3e26158ae3a897ef6c9ecdc5f64d870964f1d0bd924f2e919e4a3c7ff5beabf589ca4be4093b2a95eddca2f7e09a02d639ba872060d7db147476cc83153f7a5227a1ef58f08dcdf9f821110512424c7e84d62931a73010576f898974cf24f9361d1abb0ea3e84c79925c87544cb11140481fad00dd75581526c0b9d49d74a05398e58d8e94c6c86976dfba9d00440c2bc61aa2de1cb9569bb9c4226c05cf31ecbd4854c2ccc99c1ed9f31a270c0ac57bd43e6c5194f8b2efe49d34095baab0bfe8c3c372b9bb77b974deafa462b08f9e05e027c3ad53a24206eeb5bd4973cad46c0a8157c47ed9ab9d6b0abc571223d4e3c34675f89dc0374da151e2dd6e4dda27479499910a7836a4b638dd32ef7ab1c5712db101aea462c6ea2447f39d38efbf64794c466165723063eec9566f874cff9d6d2e96e51f5c6e0f7349bf4e667e4b3bde503a412a165c8d1381d7024772a273911ddc4186a7c1e9818519d9935cb22452468938fa0321c1bdad488dfa0601680e06404b0533ef7a8bdd0c00fea49fda059f2deb7504fcbf980e13d6c67b0bc3960ede0fde107fc571304a87fb19ceab00ec6cf4e0087b5365e8d43cb08c256de2300b565474076826f381182e6d2e0e9d77be0bcf58ca80f4faa685435604637cd6fc65366dc46d92ca0fb569a5a9b6440e089cd1d8522b20a42\nTAG: 6def2aab9f94f8ceed77295e25f81309\n\nKEY: 283d86e8371cf7b34cc9988005575c8e\nNONCE: 98ad34184dac039f04f84e5e\nIN: 8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97", - "132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d896ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177afcd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa8434\nAD: 73cea023d2c6afdb625b6411ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e\nCT: e8df4f21bb8d95211c75b194c30b1f3816715a063b202f8db645da8b826fb45e9af541ca9cbdc7c383d4b5179707f6665f8b2a74c5026243c3c5d9c32e6d309892323440ac0d945875c2665a60be211981d5dcf46a211a4e7b58e0062dc43b87ad3a9c52751f649c2fec404b9f858f4cb3ac9b534c850a8994f26136eb70e90ac44f623aa3bd362069d32a85c65292455946df893376868cfe3b06ef638e56c7defb9b4f0a162bdc8aed6a023836ecc08ed826ae9b818f3db6501ebbf3035159b6341ae703512a8fb8fc3ac0140c3ccfb1ced1ea4b7ff545ef63f76010acd708778d0424b770ffd36f2ddb6009ce5dcc498a9bb8eaec3fbbefc39da3da2f7f07470d051837398160c1c85ac695a519358feb3af9274fd3f6b1d936eb400e0bc5ffcf44ee9c78c730e4f449a008dcc912b6f9fd5d17f5d6dac025be318d5aae77b8858c1effcade42dd360e13b13f35baa64d37535a0ec8cd3a73d0c175be0246da3722db1b64f750c51d6e8da7db1ba8891fb688294124c989cf7d14108ab90a968f0729b6d7c6cc777e470e946b0fdc7b6dabfc6dd7be52b51ba1849cfce2ef2ca70c4a51523a1b0410e8a1a8e1cbfe7f1eb3fe456da81b4de6fb15ae13a39fb5b1c2b4aa9857543c3fb240965578f6b27ab7c69f74af7ec068e8c9238dd4848bf2345ab153730dfa9d1f57060e3e5f88a351f83cc78bab6149bc093ce2b29c706cbf85d35ad1c036d2103c89f1401f4f383d9345759a7be3f72da2eeab56564d98e2514d99192d82ba37ff5ef49a8770712c41e74c08227e3a2f9b516904ecc23c8368e3b46133094121209d57be76dbfee3ea7dc3240bbf1bace4369b09ed97a9080a3dfd93887152d1c03aa267ddbd97568b0538879c8970a62a4cb016e7e80b47bb21645d6a57f9ddb080551a9ca9cdd4fd0cc575bdeaa013150a8a04d05f3ccd19ab0979c9fda569e362f6bdd4b67268a88d88d0fcb9d68c47a0df0bb64048baa0554cf2b0cb4c27bfc0ce8d4a35113aa30ba03f88c73695a5d6c3495b5a15ba407ad75bab597a46170594beb34b7966d6bc7dc4ec2611cc15dd60c475c7d7b1f0922931d00dc93bce697dd4a4f72066d64b1aba029129d3a26c5ed44d19df383802733ca71de86e0a2f8d0ab04307d1a8da7c6f3dbe509fe29935bfc2c09712cd35c229e495ab3b80a447a168d044d163ae\nTAG: 05b8694f3ab53f8a0763d0c0a1c5a64a\n\nKEY: 6611562d15bc2b910f4edcc981c457c0\nNONCE: c20bd2710668b59242f7547d\nIN: 2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e334b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72fa399\nAD: 26a47e0b75a771783631e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e4\nCT: 57d4e97b3ec3681ea9dd4fc9ad0aac302b477f081ea56e613c53b9cb9cc467a2042657905b7a5b308bbff6803d33c1e4671d126ecbbcf6739842ec4d552d377dcd25b9089d96d284118ebafd0cf8fc097c35124d900cd69a2fc1f97fe3cb69c6648aa069eec68893ef2d4d8820ffae86677fcaefc50b64c4b53c9f591a0f6a3320afc569b6eb7637e5ca07c2aabc26f85521837f0e3a6435ef5cf9d2ccf4edecc5e0984601f88023f6199456e965457e638c1d6ea87f5041d10c187eaf4dbcd0cbd6e6ecd6043629819af18635caaefe6b0535d8fbacb59a00f4c0bfa8711d32131003a051eabc95c0e7119e0ba819022cd01590edcfaa7543dfd2809768b1e03ba070db5f1cf726d425a6f623d83c454c78118a6dc32ee47528979f6d478a58ee75bedc95e9e74fcbb96fae77353e6f9c8be5727250748627d3187f9408eb131efd62a90a19bb2b19b3b3a478518e49d98609116bdb9b7de7777c8f0bbfdb2d1a9c4788d81fcb548ed51d1be85a603c1744792163bd18aac3d7f20e97e32f806e7a049d3f51384e324055bfd57c5116e48007077e295e0f3d3edbc6f4be1b08d42533327ae6c7464cc45ed184912c1624caec44a0958fbdab3a2a9eb13a6e6e4ac98e40979f4ae4fd7a8560b623bfcc326435df878d643f394d177013f737fbd4971f734876d515a4f2c71fee5a36a632c93095674310a60809240fe03d7c1584a446d536fb6316c9354bd007a4de1b12e155ea6216790ab5694268081f0df280f6402373a50e2d2da82d7399ab88fc9020109e93716fd3b7d83b14bac73e37a60ea805aabc557774c26c3ff906d5946514e222747fe6962500f90765702fa16d7490d92", - "55d74dcc2c097dfac75e9f7f8c090f4d8e8cdcf4449bf5f7d45988f363e4751ffc24cca95d120714c2db59277837ea38e3b385d7d3811bc4fb755e6cd29919654bf3dea7bbe3375bef1a20cc55170ff514522886fa4716d6f99bfbe5801d1f93ce5bf82fee322e54ae1a2342659dbbdea49ff1b20274ce3dd2220945e5142f3152b4c9fc88dec89762b773ea1c87643ebf52b6f6f5f26bc1b8fbd459ef011033f3611646b50ed0b43bcfe2716dc780b8b5757d199e26657aa870fb149bd3f44db61f07a2692ab06ad8e30d40e8f6eaf4daf6a637c38a9e415b73b0bec06eba1a7e5b34d141244eaac717339b6ab052286bfc083ddbfd4ed0a70942bdf73f81b08ac\nTAG: a7bf4e198482bf1ddb65779e97c2fd2e\n\nKEY: 8a7302e5e5e5a3f660bd83aedbf1e2a8\nNONCE: 8ca05db202082d8a59d11b14\nIN: f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e2eebc2\nAD: 343a402e3efdf91f7d63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df466423\nCT: 18e79588195948d25b9beea1b2d1f990e7b87368d4af8c88e6f928f375d98bff2ce973c1e5ac525e1f08fe6e7c29a976181cb5a2a0cf40e3bb24881bcc5391f9c129daeb6c85c5cd8bc1f47f9f92bd25f4b5fb474f7c0b49828dbace32f5f9bfd968cf3871cc4072252f5b600d88a857b4c86c85ace62e56aade90109a118e9813e984dd3027fa4ff6162421e3abd22eb6246c1f9328d85ea7004ea3259fa355031c660c0880893705aa7d672996107fd46c7e6f7ea2d455fd8183a40d41ccb0d50ba627b483f8ec6fc3713010a73dd52053e033a26e5a0daf7bfe3fce8858e63e18ef1201644dc0cea8e723a24e7558ee33e904a0489c3daceac911d2aa83a63f893aa6516f343aec8a9e46c869b38f10d4ba7c4875ad3b092be565669ccdf8370ffaf7c1efddc33f67e5751668f3d75b619369c863c7d3f24b052a46af2fe66a9dea52e2c36dcdc7ed8093d0244179ab7af3c73942e63827e4b301cbc0bc2c1bec14d690e8af1f5c72270f71693d0fd9c065d9267be22d647728d39737761fc46b0a01f98b5a304325ea8967f6983dcfdf9ae87c224fc71bd9a1aec353b28208786124269dd56519e4b0cb058975ebc9803e35cf6d38824b93c78db05f2fd2797af1acbef3c2a74737e15f9d2c8f3b8e6e964043ef53f4ae5a58825fcfb1b525e38ba542836090c5a663a370e9762c89893028572b08fb0005529d44936763486307267e4095a05ea8895de7c20965974b20784c57a175dc71ea738121b24e96e3ff1e7d583894324e17207bd0a72b0baa89987b6884c6133bb3320c35ea3033dbb7051f89000977f055f3a7f1c38ddd0808ce5eccf615532f1fa4fcedf772bc7423209b3eb98de47371b382c72fd8aae5005f42a31126e14317703083b5f83dbe9d61778e221da54899e81f936a9973f0f5cc6aad85aa831071959b307278d085fc830cc6085f5701879aef6736df39a6555fe3546779284f618860924fb02567bda44dc97a4f1277e40171218fd1569ddaf68c4f58697232abcdfa6cde9bf44dc39b0a3e000dc89c7cf8298a5576a57c7047f2103a1dc31ce8267d879d15c41f23addf662f8fa49661669edc1ec06ab426591b406def208ca2854210e9647d9ea5d4bca84c5a687e9f3238fbd7288774f72d947e85ee26094ddbeaca7e135379f678a13aa866a14fd4e9d63de6d33f01e9a668bc3e4a238b9920df22db04ebd5447857422dbc16200144fd306062f605bf9138f817\nTAG: 0b8c9441aae6ac2cea3cbb71a0ac7683\n\nKEY: 44f4f7c9ef9a5fae05c10b2e7ac41afd\nNONCE: 55e84c213e1d5f58f4c7aae4\nIN: f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f682257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f32487920261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a5168b8e6\nAD: c75f25ac1087b315ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0db\nCT: 4e009626a3c4e6ee3a4b55ba06416193a63584551b8d4ed1e88f2b83f549129f329780515703fd0ef24a1039ade05d2dc4a25eb47a3e134579bfd6087b5c0feb9aa9d82e89706658eb54170c992411875bbe176dd0d25c06c2e58cee97e5444a1328b927a3616c32bae60cd8a28a58c35f7aeafc891ae5285759b24fa4b2cb59aa4263a864b89f14316181a5b8e", - "654408eaf85f87b71ac0d14fa023a12cf4c18bbbbed4c0dcd5a93669183a56e3947b9cb72019cdc810af9df3ea68ce836f8a2a80074de9e8e444ac0e7982e0c029926c3ae96fa84711ee5c42ac6528648664deed439d7d7de9c6b207d9ad0f434c59f69690ee14b21c9e1827fd873d51cd2e377fac049d8d59219945de18e262f389709a291fcbcc491b2146ee372882efc0b48fb47c767bf0709cd5450c79948c2f35d1ac0c92ecdf9c338c1d80e5a7e7c9a2cabc78edc331fab75feaeb2e91be109bad562f2d7262be42fcb5bdad42736b9c94a1d5bb2f2d0a3e347b565ff59325a67bf074874639270ee8ea7260bbb7ffb018b88cb61c0f4b476111a6f317dfd7d0f8b9347227b9a260474a448abe10ca0a9615b2eb1708d07b3157f0cb641768ef759512b9d52c86b49925720335ab843db61b9a020cf95afadfd48bc739966d7b13148cd1bd426914700486568dfc1942c6bfcaec6eb4a47ff1531f4a3efdc57ef5c6945f009851925acc31551afad8dbde7d349e43101043af62aafaeb5cf67b6642c9c928a6feb55390a49e019af97b137375245794d794d72a2657f0400954676212428a10c8b75d9d0d64b0d23dec4c7efe5ba1e599f4ef051a050943ba517cf6b6ec438aea973509d1919b903cbcf551f4f2e328cba5b55dd9a5d03eb9e471d63e5ac422c47941d9fd7a27d00c6779ca609ba3dd58c0412e7e4b0740ac9064a6ed4d024918debd342acd03c7be1a6e7c49fea94f0069b19c363095b9ec9b7fbafeae5ff1fa68ae47db3641dd98b7a6d921843707f1795e610198df9b86ea45efdb5ba3fcd37737a06881300733a0a4f1558d562577dcefa0a9e76d17fb3d80385b442f1c07a381bbda05b5854c9c76c10d2c4ffe6e8c808309474ec30d88632a794be4e7002ab9d16eac7e5155b3944089bd482009722150e0e06ed0ec3df814b5fa516bfa019f3064b78ee714a03608167374ab4a290bccc10c76b247086c31f9b4de06d001fcc7158fba4569b71b6774a46a3c1f7f80d00ea315433156fa587ae49204be74d06a949e60867b3d5d38c93eabc1fbf\nTAG: a6f01e3b9b29802f017892ef0080642e\n\nKEY: c3e4bd36e2de49d855196d82175ac395\nNONCE: 16571d209cd5a8579b05fbb0\nIN: bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3febe9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c98345399a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3e040d46d24\nAD: 29ff2b38d4e35a3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f42483\nCT: 9debc22195c3c01c571b369ac186ea10068cf99ae63fcc98c40ec69b3a04503c783cde85be74648786d5a7fe51c74f821992c0a0cdae23f4ed7318a42a6230f7c31045faeb40e880046d6e6bec6857a1e618fb360363872047781c05c38ddd8363c923762e4591f6a906d47e6d74ce365d36e41a3a6efe6e9dcba165a0c081fda577c01eafb1f83d116270c5e467dc7346647b9c0bb1e3b1da43b9cfd5a0f4cb0d3deaab5f3fe8401665fcfe742e686de8c050e8fdf7f594ee4b6c74ed0b210d92ef26e45da5a390f9290643a77b57af4800b25eb4f3ecd45e5eae5aa0dd37097bf24dfc0d1b7315d1787356e84e819de3e099f6bcdd3a269b2001d1da51681f14069ce8375d2f6b543e6fe0e9ceef03119ad96683ac884ca852fb0f88d41102f275d5040bd7f237a123d7a7b7d186d77b2a64b54568b11e70be4cd22324fcb072bd6f59d2a1da48a720feca38f8c164b9f6fc187c0a7bef39e4243aeb8c5d87d460dd9288e3de113250738faa5e82b2b4e672fce93f5294f81716aa8a5fcd43565db4b580ed18e41577fe2bf2c62518c1d4d4c324ae26a65a4bab6e5edfbb98a8eca18b34206705bfb7377c06dce7fed8e76b17c0cd2f061a77900d970594d36bcb15a92d2a09d54806d031c98942cecc0ed7f72c92df73b14740e661de31fdcfbc36f8fc89164b7614c505ce3b909376e827c857cf2b0ef3df86683aadad3112ba20126b36c5bc2c121737fbbbaa14165d511d50612c8d3946c5fd8e1a257a5c7f684dbd3b160d849b7172f4648c935c08d38733792a171cf20ed4b2bcaf98e39d09675b5918e5fe12b4e2be36e4b8463bfe708669c1d01a625d4f572e9f30a5c88d05494711e673c3d23b1003e94d4a75b9477395e8a16944ef0a1726d0388fdbbbed94faa5e78deb16ec471ed75d92772a4e437fa49af393ceaff5606aca86769c860864f62eb9c5801eae1d1fdc79654ed09f2b858718c48f05968a7a09b834c1ab0f31231795d0efe8394b3302fc0f75ac9e7c18e21abbaf6054f7442dd235451d3b884cfa25f6b7018fb18c2bfd5bb0e6d0075c2eb4f9002e30fc7d420268bad52dd916be28663a8ea3b2a0bbe653256314acebec85c7e5d2c1c163b0a15aba1cb8da585c83016d4c3f1c0aed13c20a9539438eef3a426565cd8040b2918d154e689d871a55f19b505ff94f3042b3e7466e21585800952004906abb3d13414134008c7ce1def619eea9cb22f3a44ba7070035d4cfc1d5bffa9e31b6390b4d1da2c76bf687b9bdf899fd23ce6921fa93a47e4156a514\nTAG: 232db78e53f788a11aac05af1041dfc0\n\nKEY: 64f49aea2a19ccab66841c438df5ff78\nNONCE: 34ccad859bfdd89fa9af0b99\nIN: 214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fdf56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480ec6e78bc1358c72bbae8fd8dc8403880", - "6efbfbca520a9bf9ea1df8ac365a0a95a9865ab3b3556\nAD: ad8da691b07926db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfc\nCT: 2873303a8c1b9d3230e38c46f680a7ba273e654fee766beb451f311b3192f16a385ff3c70f124e20f6ebba3bcc288ecaddb2243d3c707b0cf50d09d3c89e67d2a2beebd0ca0be6efebf9dfc519f5149e7c4f0c5fa8ef05cac1d2246f2616c179b4cdb02bfe3d7f394d885dd30f429da8041cbe79fc35dea5d90b903ec27cd09861422d3f185b887ce5e1b1d42d77c254fa003f90d62d980ddb63593e8700a20eb0b7bd930d38ae937ec326116f0b9983c69c322589e79778707856eac07ec42f3497767860d4e072ed28a79e263297896797ace5d32595c8b039ea3684b763a297b30eda2a63e178a713a03ebed0e0bb54c3eeaf41d8940edd2e448533a0258036e41211c835ebde50e9b7fef5c189834dc89cb7aa566c40ec7265c068aa50939e9976d1dfc4cddeb630a4a1f78a9134e10be1868ecd92628d3f8d827f432123dabeb9f45ba4576ae932ed42c6447a7b9f3c9b252719735898c76db75ee8f0fa655fa023cc33fb1ac8974774ce6f23409cfa7a4e936b57b0beffbc6895731a450eed1b4cc795813bb5517997037169af20da701d42d0c9b169e4155a92b4ecee3df6ca6c4a22474c01fc0aad8866e5fc33a8b3ec5a002ada29dd4d284ccd8141e4180df300eed91ab9063bf331cb476d6bbad14fd7b6ec10a3e72833595579d134a642cc556b4e9613499627f0af51f6b22c0f963e4063838809510bcfb801880e455d7b4df9db1841cc2168d659d1997a251368f1c15673ce127033602bd0fd9988eb1bd63e47e8ea863bfce945cd077e486dafa43c7f5e35232c0ee1d00d040dcda1ded51a06ecea68ac635a8faa35361f32d19586450e7a7b7ab1a8861d9f0f4d9508cd2df522dcf04a00ef2dab9ad5ce9dfcd6b018d0f072e9a17cdfbf3772d38da7b799feef2b6bf7cb4f8cfa53a49cbbda15128a17e77f8f7b4d14e64e358a11cd01d5d2137d8719f8b9f66ecb62d97faa3d2f56ba50bf4b9a28bc896c36260748d803fef6e5a6d6f24a00550ed66a2ce672b8d1daa10097c88f81669d09da72a5e62b29494681b7d2389063605e1de349a83ef50b8d57c024b2d558d206a73e49ca7fccf2b1ca685156e63bb591125910e9f72ab2e8d3ed50883ef0bf6d6571cea0f5acaa11e393d15607373f25fc340b9ed6b58322187d6c8fe4ec47666e1ca34526992e7056cc7567397e7ba0c26e1a049eecc356158827f3867171b4c77d408aa24c51513b0dcade9fe2bdf6ec856d4a44112fce5b4c55300c24aa2e9cb7d289744562dd44afa68dc2f14dd25c65d3af78d4bbb781aad5f9fa05367e02327b644563dbd992\nTAG: cebb4182450367713b8f5b047314d8c6\n\nKEY: d12cbb53bab8c9884eb83f1d2dec7fae\nNONCE: cbb6af3402bf462f965e2c22\nIN: 81c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521cade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa58697121394f11a1b\nAD: 1d9caf4e3eb2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302\nCT: 7f22ef21a372702a9fead4339e38ecfa2abe757d8ff986e7287a479a864bc1012d4621203289c8731b189937d50fd6ee79db7ee84a157acbe801bb56e1225dabf13a25b26703ec364f98fac1243ab4a4cada7080a4acb8509969ed8a2e9f309e7e465c43f55d2dc829e2ecd63b8eeb6bb01a621f86b4cd32c9c243c200670e0d9bf71b221de296e3364ca2ed5c73751b74db151176626a69010f136a32a14d47612488f90750316ea7088578bcb84805d331c77d3041af756f2ebfcc4c95c328ab03cd3424f689e410706df8b2e87ffbe24f8025c1ce48e2ff6a0a240f23b09a0378155c2fab57db5d8c0daa296b813ad148e94c8d627715cd2fe8f861e414b3c7f482eaa5ae1eefc6ff86ee30109e27bd75557d70598d7c65bf9bffbecf44a44339b09ffb88a722fd8c19f196b9822ae79cb66fa1c712cbef821d996fec59f5a95c197f70fd34db9e2349a372f43bec0dea764fcd71ff931d34fcdc8d9c9321e6d8984211db1c1987032ad85e1b03519f433ef9db8811fcb24940a320697c739136a77f66e97332b75b33b9097cfa9e224b262c19053ca32afa76a96524861a8aceaa98771efab10c0665533619befac9bca499ad88c9d0f089a7026583e132ccf3a542adffd56996331ded9917d363659562a6b7e45231667b8b3069f327d829489279058b9b89bb7902c1127d7e8d150634b580274b47354edcde999922654def16ed4378f313115f4013d8ffadbde1c8f8c918ff7257175f14ead903c03d5190aeedb2dc9e762e34b3f80d7ee460bbd14ae9c3182660608f033ea073548956b72275f74f704a349a87edb015e6154fba7c0ef4a32a4dc206dc42d5d261ecae22a9f455c409304131859477435b30ba3fad46bd5f69971ba74f1fe82a6d5604e5d7eeae0dc8ff5a170865134c5fbac13bf6cd007a16af86c42dcc887b90664ee5e48edffea8ba46fd84c844cbade00906c36d84373178369fcfb9226654233d2c5339099ae4e723a0c0516742e42e3c40994bd06086e6f030acef01727e7f600f7109000bddbdbba16b9543174c98810d5ef0c95598ededb7ab628323faef1ea4028c0ca414a7cc33239c84de86d53a242b4e8c3f9a20e3a826f0ade00c440b2f792b946a97758a073fbc811f3e22de8acfc9ef1b1a946f6c3cf9eaf4add2ba403941b446686d9bc0524590e2bef8f552dd54d9f69053f647ff0e2371b244d15cf1a5302680ece820df552b374bcd23f784a9c4bd486a71fcdaaf3812efa5a39366542b163294da6a2887796b6d863529dfe76ad88e2b47931de5194a63b9f07f6ec63081c3f97e9c0379c5f44e7496dd23b4c186e3613fdf0d\nTAG: dcb7fd2d779be6e82ba1ad90bc79ca3f\n\nKEY: b243593177cd099dbacd5f8efb412a95\nNONCE: 132b8ab31815dfb463451fbf\nIN: f63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b3614ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc76", - "2d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac532fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fdcacdf99a3852e9ca\nAD: 9516be08987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f0\nCT: 3497d7dab267c401f6754a95b885561c8dbce6c1bdeb8c6877810d6e77afe8e2071ee088890dfa18d8b4de635ebd88188bd1ff3539c7da99905bc955e64fbac216a0776d6ee45169e9959f4aebc6ef987f7d5fefe73aadfc2c6da56155d53b795df61504680886b9ea8bc59558160d9d63e2dec0c5d7795073c04b6191c725d5a881f71cd049b9ba42333f1082ab9733fef2230cfed44c7d827a7e6a8cb07ea58cd8ce96baf00df43ac95e35eb585ba99165b9cc6649b306c3399da8a03134dd45a1b9f1e4ab3aa0399c577104316af55587d5eeb0348271d2467b920a083b4bef6a21033f8428ea816718880da3c29f4332b19030d4270d20a4271169f179df4dcb07e15db1b3d4acb2d9cc9ac90e9877ddc09ee0bdc202e9fe23a844be123fc5b08068c9a6428988de1f2f26f06beaa020f725c072c842c97fa8069d944f80518ad2276cb4aabfea20db3256d35f9533d70c6723e5696cc159127ca671db02bcda89aa17dbf47c33eb863923c0a88f3bba8f79bdfb6eb2d15fcfa9acb68018d4d33417585299e92fe3e4a131dfd123a4edb72c988796c6dec3169cba26ac712cbcd92abc4e1f327f05838abf03bcfdb218d56e2d795eab3d08d5beba1b3492e72626d86b9990e777ffd91ccb30f99713d89d0532a032bf12192a1ac2368dda2c131febae2c11bffd83311fce6d20521e92d458a285fb548ef27158e593f306d99f2e5e521522192037e94aaab02713e3242bb412b362508ff0d4823ca0ff6190c71e31f4ff06f40f8d467182ad43848ee8b8c39280d535c7cde50571f40c366d97f5de703b808aacb5a7369df763518424137d42c59d91fdd365d025f1a747b95eba9f0ff580926891e39ffa2943e28e4cb3981d2cc62e9b975048df0d0708bb7067a67bf1ef6d03692fc5501bb09d562ea9ff3078e454227ae4d6084d21e08cf6c147b205d74fa81b72c1684f60923bc024c072608ea21ce48fa46c41495761d68744953c87c6e064b33d8d43135e43fd5f67322a1d2d9ab0e07e9f8862d6d252197a4fba914aaf4092a4d499a5996d40f143b8f3eae95a5a64b23a17495834e3246f3d0a06756d80bdfee94f2c03c8e5ce0043e9094465f6a3307f8b6f098edd85f863d2de3867b644fb0ff335b83d26958c88960f9913ca3159b61391fb67dd6770321a6971e1fff607c9ab6a2765f4795f53fb8aeb26944f728dc6f66de97136b50d722affbe78e59f00cdeda54e23f46647d024f384ca01f46a39e660df4cf9a2576fa353c7b243c401b429262b14112866fad6e802ad42fa2e509ddeb1ddc70d24e4eff5f7e94b4e9772cfb52b88d81272462087a446b770db1aeeddcf81cf9075b419acf4a3c3cc\nTAG: a4b1933381318aee1af76925720ffbdb\n\nKEY: 5d44b6e557031ed28b60f3a9e73293d0\nNONCE: 3f57c9c636ff9336cee08635\nIN: 8c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de062de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b344a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83130f197a6f35def3e8e2c6598e6c0a8ee\nAD: 6b0da01dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2\nCT: 68b1872409e4d6bcc2d218c7a844ec2a78969d25b766a5272ee09a3f0dfe20abba0ea4cf75437e4b759e8586be4defc5146b303b162c4209406c93884c06a163a5743fa6ebb8f649ad8de37194633d18fc4d0bbbb1c74e8297f48e1f532e5ef9ee7c15f07b2e96cfdbce6f583e267658a795ec9c4dcd9916d5dcc08fb5c28277e56dd366a26f92f9680930d63493e2995ce350e6286c2d597273b7ecdd27d2c05b725e32d6c48f7f577ed4098d318fb822cd6413437c44a9ec8feb54959a2e6403484a8aed34e0527cee6838844dc987d933af12b370cc888b6f6ff2a25754caefc1c665751321ab9b9f19bfc17e6903c99dd87fd502065a8ecfc1c29950dd0007ee2f9c3fc752cbe7e661f06ff22a266f564e351a7137a", - "1b96616e31be24c7a13e62b04646ce0a68791e0e1a099b862435065cf7d3203fb32d7d7d8ac4a77642d69f7c27a46973b6bedd5e840f887209d19cbe50504c0a251056c8a83100092a627f73edb421a3f1aa12edfc78d3fc474cd2583808e38d63baf1c5b4b5cb34665e10d4af806bf3abbcf4432df6c9caa76cf0e17a5e0e9af7c8868daff22d84b7b6eb4f299b750ff18b9b17d7412ccafe3e55e5b02af9ad87c03799c2282a9c6377ba42e840440d8c1b19bcd1c8fc35f02fc505a3ce97562b9e660fd488b53c30edb98b91949188903ba2078193c2de05e61c9da7bc056624104471a8231b7fcfdfda4d804b8819888a2c9bde680bae59e438d89778c5a04dff214e9b14ac5b031c378c8beee5ba9b1f91dba760d7621c24c30aee28c4b49e183632d8b450ee6895a47b96cc3c1917af685905691d1ca588db5a21674391238d76ae101c3e83d94dfee4a0656baf4d6cf277e0c7b0512e4ec13d12a5af44c7d19820fe7a74f5d5875321d528976f35a5634e15dcb35a54836370569d5609de0360ea4d2f1937dcb2d68b20cc5a04c13c04d5379a7dcbcb6b711712d7b3b20d255156b7e61e99803a4d767f0438c4fcb166920744c20a08e48dcf5de4ec325439485b51e4c0f08cd22ecf60ace34b93844c2c12bc7b46a8f6b8dbf4de311f1039504a46d9616b41fd58388f458bdb8bb9821a33379cba4f36b416c2eae02f42b736c1cb6e673b9b9dbd230b6a23d944124469bbd2c545f5ab72fa4b3a47b4d0bb0271d615de6c7f182cc92165a84032f59c14f181c093b017a1c7e5887db249b5ea2db39faf7a3cfba08538b91520fc1f3af697c5f4dea7274cd86dc073920280b488a3f66969cfea020a312be1fd111c7847296ec5f5cc91f00188c07c05e4e49cd0667ee16345f794219ed3a80602cc11940aaf9a927805a040419abd20ad8ba0a05c7ca9936997549ed5a3c7e7d9f582c735a424895c5f1aed9a3a2ad3cf7d9f32d3e\nTAG: aa69fb97b939fb73703ad4cec6c24fd6\n\nKEY: 714f39851c1fe09297c8c69dff0e62be\nNONCE: 3383bb6aceea0cbc71cc7783\nIN: cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a94494f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f4fe1fd1359a433240225\nAD: 1d90b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23\nCT: cc11a071e11cf36750fad572fdfefa377b8f0ed6cc47bb8015cb51f0eeb531e5779d233ed224022c5f7ff3181ad1d6a9f7564f41ee919f0435fe49b4266157a68061a1c5d06d8a8075b55efab8c9530266955c179f0a57684459835931cfb2eb1244a730797dcfcd31e7a414ed42990e9a55d439fbb803f2828f92cffb247f8d96896f9b37ce2d029aa15873bf13144cf35eb70d8e27a013513774ede1d37e4aa007a48a12f37385842cb716f60401f638efd2841db6165819eb3c2c58708d92a454344fa64c2d740cb34d4b7dbbc1d86d9e0083432e0e90c074b617402b68e3199d6fc43c454a842da725b49eabf8459b4db90e6553e17f979fc8d6bd03ac382f3a85eb40b64e21787e8e8170372eb0202fd4d78b39fb940829e11270bf6ccce0fb28adcfa8b60659e54a03c7b22491c62982e5673d66791bf6db75edf3836449e918b0c9059de644039063d78b66769d8358349acbaa7f1bef02fbfe49be375f652952f66665df26964b8b8b327683731cf825ad45118fb98f119db977828d96618a4a2fe82105eba7d1c3bca35775dc57a207b5b07c24305829d911bd7d30e3c19b030f6d34f6858593f3a0dbd928fca4b1ca21ce9ea8b63b149aa444bc696864fe2bdcbfdfca33a656db422cd007649d3a3e895b909fac7f9f0d9b15920b1d9dbcb343a2a0fd9382154430f818a9b347dda83e1c1038eb5259ca8714e2f8d3ec13c8c7a96c537fe599b30fe8780c82242f674817e815d56c92e765f3c67bb9591e27640d4880e04fc6afe5f1482422b0de4282df77df798ab7d32372f22dd3dfb0035182fdfd524dc315b0c7607639fcee3b1e12421025964a27bb5926f28c97cd7d74cdb26a779b656491f057eeb3be3eea0097b787ca5d1b1d5abf42fe76b16e565b2c1d15579e761efdcaf04fb18e7a97215e4dd53a164b336921390fed9c4fc1cd0cb0825d4b5c7061db0f4f1cdd950f13646c662bc6837ce2e455bee1758a59fec54d758eb49f040384f27ab6abfbeb7ec52a1a1b3ce63f6b4ded32a41a64b8cade579db95b7d90dcb875e83424d03e9f3bcc2dc45952860f1845632c7550802c957657c9342dc32c64c558944fbaf5f2b6a04b5d48794d140bf4f9de2fcdb1b77a0602f1c97fabb0f2b92b05b6894e665a8fad01dfb2764f673f61b9c6cae68272a5b12a9a8347782c69f5f9c3d4ff932cd713a1e2a49759114563d94261ebd7c0a723a5837a1912cbcc98b6481f6d7bebaf29276bbbd6d0a83bdefe2a0f3d4d60d88d4575e3cff73eba09aa290c2060434f85955597a3431c376f64489f50dd9d1be65b72158b1d6875649da95579b5c88e3d445c7bb95a4ed9452e18ef33bd7dbcd25c5ad6c769a651204e082026742b15b49554133e1539fc516089ce27940c89eb1a68846f13f3\nTAG: 26c14eb5587ec540185a067635e64c29\n\nKEY: a406f8b8ee46d958d10d8724d90bb26e\nNONCE: 2b38be1c0e8258de3a095418\nIN: 26486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43f62ac96f76e13ab5928147c5e6378", - "8bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ece22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6a4c6732e0887f40b5017de\nAD: 54e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585f\nCT: 4f90cb1e30d5c2c97f46ec00cd8203ca8dc808dc0e862cfdb35b1e92a24f0093fb6b68eea43f04ff1332f942b03aa2dcbe03aafd18b292cbec3cd66d7ab26af3f274a97e599f520a6bb59f5c56fbe858821eaecc297e0cca632addaa5aee071a6cf84910006f158cd1e8a38f185e95dd7f6ad09303636bb6356e400ae70338a8eeae7c22440babe6d9595b2ca008c2e7a471e70e66c49548bab632e87ed36894c6eb97c7de858382cb060277edc91e19b288870b2a472df769393accb07f34a8cd94922582ce351da199a8c5c426b2884bba07fe38da6289ee55537952d53ffced29cf053a9e1b9b37d2e0e3c219f48fe885410e6bf78fea15719f20091e654d44c786f9494e4a71b20f968bbab6f5305af7b8668867cae10eb93904a0e3ec3478fca8d6a231c9b4b84cfc3394716b366c0b1a1bbb8012a298e3a00831791e489b7a2dac6c26ca9e5ad4ab58c4cd71215cdfa2422f49a7b30698ece44972a6dc7dcf9ac40f241085599e71957bc719dc51555312fff4e963832017371980b5087d0f6373e5b52d66d7003525cabcd56bfcc00041bb9f0522a4dc86ecb444497b97d882d122dd8ca1806f1e0c8ed3b1b4810dcfee9b2803d08f43151f5a968c18266d0b956ce26005628780a1c4fe0e25b7dd55e6d4cb6b1427fc56afb278a8cf91d83b952908c295947a5cbfa183816a9fc4400db94a5990e53d99da1694de5941364e7828515544b1074de41c253a3b7bc4b72a3a0173138a025fe758f8d834c7c814f1440407cd1a98aaf15f7f8d5055aa8237c6d93beb53dc84cd4712d0535fd90c180a40ba6cf9880d5104480c18cd9734354c9321eb3ad583caa5eb05edcf288ca5793e288436c175e56c001b473c1486bf36f9d75d71461339f1e063035ded3246166644761816559ba9cc9c26f61f6d02adaa3b4b398fb80906ddbfca2fdfbe57df724adf1f76f995ef7d52468ee2f89785d59c0c8557ab45f07e0da644c0fa9b5a9e1a2280d34a0f65b463e53d09146bd629134b12262f18471eda27ebb5ace095864abe17b95f238c0823dbd11245d89c195eb9ee65f6f97819def971189e43354d4fd811fce3c430cbd4686e50e562ab1e8de214832db1a09a64f9339b8f6dcfd53280a33071e89616148914de8b456408fc18a9f46f61a782857b1e11dfb5f956a5889d60c53dc826ab92153cdad4d935ccd978516c383371352f63edb7211c3da54cf2eafb7ee65f6aa98aa7813de42ec43a4e3c91bc2eac8cbd27fd0a39f109dcc94365bb223f9be11120a9767cfc73e2c315846b675f5e1eabad4e7a970aada798993fb2b11248be37b451a6f8be3ab93dbb0b3a181c49f0b43b402f05221bc97a6c2b5ba9d1e5860a234cbd2c7dcac97ff395ea8ad34229c3b0624eef42f611f90449476d76e816fe391edb539f9adbccd9628dac1e8925\nTAG: d4c3aab4d275dca02cd7912eb71daca0\n", + "# These tests are versions of the tests from the corresponding AES-GCM test\n# file, but with the nonce appended to the tag.\n\nKEY: d480429666d48b400633921c5407d1d1\nNONCE:\nIN:\nAD:\nCT:\nTAG: 7d7daf44850921a34e636b01adeb104f3388c676dc754acfa66e172a\n\nKEY: 3881e7be1bb3bbcaff20bdb78e5d1b67\nNONCE:\nIN: 0a2714aa7d\nAD: c60c64bbf7\nCT: 5626f96ecb\nTAG: ff4c4f1d92b0abb1d0820833d9eb83c7dcf5b7ae2d7552e2297fcfa9\n\nKEY: ea4f6f3c2fed2b9dd9708c2e721ae00f\nNONCE:\nIN: 8d6c08446cb10d9a2075\nAD: 5c65d4f261d2c54ffe6a\nCT: 0f51f7a83c5b5aa796b9\nTAG: 70259cddfe8f9a15a5c5eb485af578fbf975809ddb5172382745634f\n\nKEY: 31d93fd51c2d6450cf35d9edd71413f4\nNONCE:\nIN: e78eba6c58f93cc2374932fc21e54f695f2daeda3bd1e0121a77d178e3bf5c0e824a99042e8f2522df829d014e4d35a756780e8c07f53ca8fb78db6fb76754ad461665051c4572b2514804d0a9cbae1a1a013b796565eee13a7832ab8834b8406b1185332552d38754dde2344ff4f6e4823390964ba2dc43de136f2235b1d919e0f4ad60813d30f0ac1dad35abe3bee9479337c7b430841d2c722f12aeaf931cedd8a82053f697fff8d07f0af6013da7da58a5dfcf45561943e7ccdfd8d11fbe96a68a5a27982e47346500c0284caf8e6b63c6621e80503a7365d6693dc9a249093dc45221cfd88562e25910034c2c123e44e3b09d8a8a15547285d2596b98c7a0ee9d10b2cdb032d08a6caee1212420b6854181a583c15e046aa202dd\nAD: a4fdd42aad5475ffc1b122170024486406033c8640233cd9b23c286fdd40c5b69eee39cfbf965f7a10c73663f9804e6821c4f62980f8362a580bab446325b009a004b60b1dbd12566b55b42e58d8037d86c1050cd6ecaaac2fb0ef616a15bc5bcd8252fd459165795c500bbb2fb1476e5cfef9549db733be65bde391c810d099e3745a2cc7a94debe1f4ff6653b338123ef7d2f9a602bc9a4bbe757a63f932a802014f2f06c6688faf14332a355b1025f33687124399f55b6a5adb4864727ec6c5334c41d78d1463400925f6c29c0f611f35c9640045a740dad5b4f0dcb632e7f9a3478b526aa9f97cd9f8d3ad094b7922890e7b6d9c67fcc4f747d04ddcd115fba0a8f0433c6fb1bf6011a9cd153f866c76b26d427a25aebc60d10540\nCT: 8d668fb50efda82552aeb5d075ff3977c37929d73f6639289e7c6da8c89c664df80b2387e788d12398d62d3c0ed2f9f918010d41021c464d54f016c4e10e85e29ba3a45793df2ebd6cdf30045363434387bb0d20439f4986e6eb7ae9fd85fe776f7b8035025624c2413ca8491cc6e79fe901b9c40ff3a0e37a7c7e88b56de4fee65861865162821e046846d253982e4ecd17bd26214b0923a4297d4ed9423395d856940829ca5ee74488c3b4d8aa3c5ceade17d8a3f2e45d3ba91360ac1c76d6a29f8243bf49c1d75aa41ba239fa6f3b123e198ba799e3b70c674607c5371894800954eda0264b3b82606433f71371dabc5f1fb3d703232533662920a241f613c38d16b0bad24f4aa3b336af89cdcd2f371e1bed7aaa47c56d17100a01\nTAG: 594ee5c93636cfb5fde940e3d561440a28f6f0c288c9f92e80252e1e\n", }; -static const size_t kLen8 = 67908; +static const size_t kLen8 = 177276; static const char *kData8[] = { + "# This is the example from\n# https://www.rfc-editor.org/rfc/rfc8452.html#section-8\n\nKEY: ee8e1ed9ff2540ae8f2ba9f50bc2f27c\nNONCE: 752abad3e0afb5f434dc4310\nIN: \"Hello world\"\nAD: \"example\"\nCT: 5d349ead175ef6b1def6fd\nTAG: 4fbcdeb7e4793f4a1d7e4faa70100af1\n\n# Test vectors from\n# https://www.rfc-editor.org/rfc/rfc8452.html#appendix-C\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: \nAD: \nCT: \nTAG: dc20e2d83f25705bb49e439eca56de25\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000\nAD: \nCT: b5d839330ac7b786\nTAG: 578782fff6013b815b287c22493a364c\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000\nAD: \nCT: 7323ea61d05932260047d942\nTAG: a4978db357391a0bc4fdec8b0d106639\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000\nAD: \nCT: 743f7c8077ab25f8624e2e948579cf77\nTAG: 303aaf90f6fe21199c6068577437a0c4\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000000000000000000002000000000000000000000000000000\nAD: \nCT: 84e07e62ba83a6585417245d7ec413a9fe427d6315c09b57ce45f2e3936a9445\nTAG: 1a8e45dcd4578c667cd86847bf6155ff\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nAD: \nCT: 3fd24ce1f5a67b75bf2351f181a475c7b800a5b4d3dcf70106b1eea82fa1d64df42bf7226122fa92e17a40eeaac1201b\nTAG: 5e6e311dbf395d35b0fe39c2714388f8\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: \nCT: 2433668f1058190f6d43e360f4f35cd8e475127cfca7028ea8ab5c20f7ab2af02516a2bdcbc08d521be37ff28c152bba36697f25b4cd169c6590d1dd39566d3f\nTAG: 8a263dd317aa88d56bdf3936dba75bb8\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000\nAD: 01\nCT: 1e6daba35669f427\nTAG: 3b0a1a2560969cdf790d99759abd1508\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000\nAD: 01\nCT: 296c7889fd99f41917f44620\nTAG: 08299c5102745aaa3a0c469fad9e075a\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000\nAD: 01\nCT: e2b0c5da79a901c1745f700525cb335b\nTAG: 8f8936ec039e4e4bb97ebd8c4457441f\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000000000000000000003000000000000000000000000000000\nAD: 01\nCT: 620048ef3c1e73e57e02bb8562c416a319e73e4caac8e96a1ecb2933145a1d71\nTAG: e6af6a7f87287da059a71684ed3498e1\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: 01\nCT: 50c8303ea93925d64090d07bd109dfd9515a5a33431019c17d93465999a8b0053201d723120a8562b838cdff25bf9d1e\nTAG: 6a8cc3865f76897c2e4b245cf31c51f2\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nAD: 01\nCT: 2f5c64059db55ee0fb847ed513003746aca4e61c711b5de2e7a77ffd02da42feec601910d3467bb8b36ebbaebce5fba30d36c95f48a3e7980f0e7ac299332a80\nTAG: cdc46ae475563de037001ef84ae21744\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000\nAD: 010000000000000000000000\nCT: a8fe3e87\nTAG: 07eb1f84fb28f8cb73de8e99e2f48a14\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0300000000000000000000000000000004000000\nAD: 010000000000000000000000000000000200\nCT: 6bb0fecf5ded9b77f902c7d5da236a4391dd0297\nTAG: 24afc9805e976f451e6d87f6fe106514\n\nKEY: 01000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 030000000000000000000000000000000400\nAD: 0100000000000000000000000000000002000000\nCT: 44d0aaf6fb2f1f34add5e8064e83e12a2ada\nTAG: bff9b2ef00fb47920cc72a0c0f13b9fd\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4\nNONCE: f46e44bb3da0015c94f70887\nIN: \nAD: \nCT: \nTAG: a4194b79071b01a87d65f706e3949578\n\nKEY: 36864200e0eaf5284d884a0e77d31646\nNONCE: bae8e37fc83441b16034566b\nIN: 7a806c\nAD: 46bb91c3c5\nCT: af60eb\nTAG: 711bd85bc1e4d3e0a462e074eea428a8\n\nKEY: aedb64a6c590bc84d1a5e269e4b47801\nNONCE: afc0577e34699b9e671fdd4f\nIN: bdc66f146545\nAD: fc880c94a95198874296\nCT: bb93a3e34d3c\nTAG: d6a9c45545cfc11f03ad743dba20f966\n\nKEY: d5cc1fd161320b6920ce07787f86743b\nNONCE: 275d1ab32f6d1f0434d8848c\nIN: 1177441f195495860f\nAD: 046787f3ea22c127aaf195d1894728\nCT: 4f37281f7ad12949d0\nTAG: 1d02fd0cd174c84fc5dae2f60f52fd2b\n\nKEY: b3fed1473c528b8426a582995929a149\nNONCE: 9e9ad8780c8d63d0ab4149c0\nIN: 9f572c614b4745914474e7c7\nAD: c9882e5386fd9f92ec489c8fde2be2cf97e74e93\nCT: f54673c5ddf710c745641c8b\nTAG: c1dc2f871fb7561da1286e655e24b7b0\n\nKEY: 2d4ed87da44102952ef94b02b805249b\nNONCE: ac80e6f61455bfac8308a2d4\nIN: 0d8c8451178082355c9e940fea2f58\nAD: 2950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0a\nCT: c9ff545e07b88a015f05b274540aa1\nTAG: 83b3449b9f39552de99dc214a1190b0b\n\nKEY: bde3b2f204d1e9f8b06bc47f9745b3d1\nNONCE: ae06556fb6aa7890bebc18fe\nIN: 6b3db4da3d57aa94842b9803a96e07fb6de7\nAD: 1860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nCT: 6298b296e24e8cc35dce0bed484b7f30d580\nTAG: 3e377094f04709f64d7b985310a4db84\n\nKEY: f901cfe8a69615a93fdf7a98cad48179\nNONCE: 6245709fb18853f68d833640\nIN: e42a3c02c25b64869e146d7b233987bddfc240871d\nAD: 7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296fa859c21\nCT: 391cc328d484a4f46406181bcd62efd9b3ee197d05\nTAG: 2d15506c84a9edd65e13e9d24a2a6e70\n\n# Random vectors generated by the reference code.\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4\nNONCE: f46e44bb3da0015c94f70887\nIN: \nAD: \nCT: \nTAG: a4194b79071b01a87d65f706e3949578\n\nKEY: 36864200e0eaf5284d884a0e77d31646\nNONCE: bae8e37fc83441b16034566b\nIN: 7a806c46bb91c3c5aedb64a6c590bc84d1\nAD: a5e269e4b47801afc0\nCT: 8092e6d6d729f5ee7e808d77f3b7a89647\nTAG: dec23ae31e3e97bb364fa18ad85cae0b\n\nKEY: 577e34699b9e671fdd4fbdc66f146545\nNONCE: fc880c94a95198874296d5cc\nIN: 1fd161320b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f19549586\nAD: 0f046787f3ea22c127aaf195d1894728b3fe\nCT: 7520668ef1b845aabf245e66ca687ca7c5b4f00de71afea392cda124893746ddd4e6\nTAG: db5ad3b398513fe5c8d868e68becd5a8\n\nKEY: d1473c528b8426a582995929a1499e9a\nNONCE: d8780c8d63d0ab4149c09f57\nIN: 2c614b4745914474e7c7c9882e5386fd9f92ec489c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f614\nAD: 55bfac8308a2d40d8c8451178082355c9e940fea2f582950a70d5a\nCT: bdbec524ca37355074899f01b7247b1abc24565b997e000f231f0664be655d8cb75f18112cfaa722e1b2e261710036ff919014\nTAG: 45b9ece29df0dd93941f9454404c8d87\n\nKEY: 1db2316fd568378da107b52b0da55210\nNONCE: cc1c1b0abde3b2f204d1e9f8\nIN: b06bc47f9745b3d1ae06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nAD: f901cfe8a69615a93fdf7a98cad481796245709fb18853f68d833640e42a3c02c25b6486\nCT: d75a5a40ae0ac4343f1a52ee16108332b3563616c207c2b22be277a219e497b7e5bbd5bdecaed87a5216e3e49149ac50a7959957264c222577a07c73fc81f0e579a0fa93\nTAG: b70c26c56e34c7740824f9dfcb8ae6e4\n\nKEY: 9e146d7b233987bddfc240871d7576f7\nNONCE: 028ec6eb5ea7e298342a94d4\nIN: b202b370ef9768ec6561c4fe6b7e7296fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de192eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e555\nAD: 40db1872504e1cced532ce4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e7\nCT: 23dea4fb871ab1df6cfb674d2e7efbc969033a11d694c6580aa3e780e4d1db5f1145924b974ce98ea041ecca53c36207fa644b0ae789965084d1ef845cae33aff734113b3eb4d9f1863b780b0f97fb5e3c5ea991cf\nTAG: 81da1dfc98517d4cee3ee885a266e814\n\nKEY: 2834321f7aa0f70b7282b4f33df23f16\nNONCE: 7541ac15c8417abaf17a282a\nIN: c7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b469b0901f2b5da3a956a6e278c940e82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27ff1de\nAD: a3b2a7d832ed8ab959d82ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafad\nCT: 06d3e558b2f7f8e225d76a41a11122aa29eef02c226616f5264c9c1b821748a8115dd", + "4868dfeacc5d167ceedc824f1f7136e7d7fae783bad83dec468c98747524fc2fcd7b86cbfd1c07078fd1b4b9caaae970c729ee3f2ecfebf048c5aba174fc4eab117bacf\nTAG: 5ece142ce1074a09ab8ce810222a471d\n\nKEY: f0f484fae982019a8ea22efd1358adf7\nNONCE: ad4f5fa0d2acd2f1ee095cdf\nIN: c13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0adb4c74\nAD: b73839e13455fd91ddf7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119\nCT: 90046c5ca4a6db850c5cddb14227b5902257e7ed8bc55f85ca24f51558f95037a0567d485b7606d2ec1802de069926e4f69e5ade9453080f84c045438d890290ed69b5e140788d07ed3d38b067900c222ad55b298e240590cb816d90a43ec52203f11ff9496b3dc32d7ac316ac8465496e41b4be5200dd\nTAG: 76ae0503f7b43b1d2db24817f2b61ee7\n\nKEY: ae0c8a20b679dc40c9908f88fecfafd6\nNONCE: 88b0ebec6a2ac13421012874\nIN: c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b9d0f8621\nAD: 664df31eb95b5e17567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361c91452e7d463338474a400ef9efcaa648e93f\nCT: f729ca77733cca181ba8801e001924e20a1d164cc4440a6217a1178dd6b1210837367cf84aa41f92f4123d6740910586f819389d5c750ab15768aed1b163bde5b1fe8862d1621b11485b47182d32bd304ddbf275524c4ece4cfb1361db53dd63e21ac62bb54a77bb5063c869b5f5de1f1b4356845aac79ee6f66d21ff271e02e8bbbae1372b4b8ff\nTAG: 52856b3369ecbb7201b1b0f75872e5e2\n\nKEY: 38f8784a1598bca461211195d7844de5\nNONCE: 6b91cccc96d89e6471bca6b7\nIN: 374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc2d2c51dc42\nAD: 6b38c308cc574839129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e76\nCT: 350bc8baf35cad823df06eadbb0e30e1e4b5bb8171d14c330e8c488f1076d94b8cb7baa3268a5bf164e23563180b9793ed06bb80079288cd348eeaa8eb33cf31ccf89dec998408baae4c3a7b3d3bd14aa76e99d645da0fba0c29a7ea4baeed741de3a5df5ff4044d9b057c4f3ef1825dd0a47aa0b5e92cfe0321c07333479dc86bed7b7b91e6ef368401392d973404e2914b7d2cb49448c55e\nTAG: c974e989ae2b86e92c5da9b0c9b068e0\n\nKEY: 59b17f09c56d170ed1ef10d2fadf01e0\nNONCE: c78473d06a1685ef0bb112e4\nIN: ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f5945c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b1a8a8b1f4ab8\nAD: 5be5a4a089f0ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26\nCT: 6b07754b096556462756de94e5941610f1bfd93e6222899516e00eb1830f557d6f629bc61abe0c247ab6aa0f4f816f79544ceb034b5d9e86ab8679ad67f6dbef521f6180a07b0bbbcf174cd9234848f18b8ebba7d6ae3d607e027cb220c7582eb6d496a980ae3883fab88a1dd9e5312842450fcf68640546b49c24a3ffc0c8c4f539e8f9a34a3bbff44b1bb4cdb339d8879fa4e0c2145954e34fbede7483d25a0494c1b9e5b1f70aee7e\nTAG: 064c9d25f8795d8151b33f9d32d3ac6d\n\nKEY: 995577faa109071bee1c87d5e6772ca5\nNONCE: 5fdec02348a625b49c3c881a\nIN: ab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e5f2eea2c79702d\nAD: ec4cfbee3d1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e\nCT: 0610980d938c2f2619bb8b4408156fb53f595d857feae649a6700af296d0411cbb80a6c0b7e2447cc54c3bd3bcfae38b7bb10fa5b91e25686d4482b14a2b62d386175f9f247e48fc3b2215b2da1c065bb00f9f59e8afafc9ef205f5245d27085021f41b9e40c00abaea48286fd914e558f822659207e965855eabf52723148d84b0a2692c48d76f30f3cb530b1beb58ffc4824517cb6772e957bd56394c1d8b70c9fa2b70a670f3fe36d8802b2043905e469b558575c75012901dc\nTAG: cb51baaa4672b8ae9745ecee08784d3b\n\nKEY: 58ebf03ce7ed2f8d5487936311922884\nNONCE: bfd31cf828f3d0ce78f3c698\nIN: 1932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75eab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5322e47a85cc58e75\nAD: 3f00d6f0d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6\nCT: b741fd48fa7634435db2cb05392004d0b588bc7e9ddf79526706e575415c8b3d48a606c5f155130deb77ec7aff93719396797bf6628531d9d061727bcea2b348060b64122cd1a94f999ad1f681847e57c05da0deabd2fe010212dc60ec980ed0ba78ee9160b3776ae9174c6f8b7231d6754a4143c8af129411063315c6517134ca26d5a94a2e8c6e8b7ad9b8e78b694d5251deb34dabc455dd9f2a2b3fb6f67222de61e917a645d366462d6d94cd265f919f237f06f1986fac17bfaf3a97c24b99af884d0fca5d3307caf9bd\nTAG: 35777ae50d32c572cb0cd778cbaf55e1\n\nKEY: b86fc55f4abb9b65ee1897c262533ccc\nNONCE: d118b0f493c849a7aa7f35d2\nIN: 43f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db067856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e82911e842e5c9ae8fb79b\nAD: ecf42c3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763\nCT: 87454e6cefc24ba38f01bb791333dd0006cfce165a4247833b182efcdb484b0818aa80f70f29d0ec093455344b8f169262f17be2d1635293bdcca90e21f2c210146f90398f44b35e3f2203c7b5bfecdbd973b568d8ed8444d43cba08d44984a295f62c174ca9ca69c173bb7c43f103ff53a886284af46fde5cbe07b391f9c0b82eec218faecb43dc75372478f2ee1bb267602672a4ff5989ec7251034dd2cfb49677fc82c8b209820be1ed2c429a0491beedbe8c1fc78bd62590ba71fd5da363d6da000e8b7e5bae223c0cf8397d3b5ce7141e8b301ea5a737ae480dc9\nTAG: ad696ab700dd5b71d79f4f6f69034185\n\nKEY: edaf7d79c1b83d973f9ba3b29a9b9408\nNONCE: 418f73743ff0546f0d929001\nIN: 0cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a028d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64ad6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a7f567087a5fec5ad1ee3\nAD: e4be5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c461b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad\nCT: 9372586624f9a52a91e7ce12f380ca13840f11fad8d9edf10c869042c29514515673b3dfcfe956e8d3550baae1815bb4cd41ed27c7485c723354e557d18119b27431d7527f0d84c6e76baf9afa35a215624c339ad888f27c338240e603b232cd247e77eb1475adcb87d0443265ac0de45b16c67fdab07a0c0dd203d97ac2e19248492c561912e9087cd5fb73445695b43b8dd8c7515f9c958dc64068e31d3cb615038f5eea84a74b5d0c3415b6b1309ea8092614f2bd944a6c3a9e002a95e524efa497c9d3cbdaa764f8cf8aa9fcc7f7d68a623930beb", + "b74e5c234322651edda21e20eb12c16a76839f31f3b30d6\nTAG: 33a31cae0292d0185aa10ba1c2288cda\n\nKEY: 01dadfe4cc0681384b489f38d25e83c2\nNONCE: c563485fb361f81d44aea205\nIN: e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2cc7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86a2ba1e9cd195a8ecadd315\nAD: 870d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a\nCT: 119f74936eaffdc3e5e7e072ce81e0e1ca91054cbfca127b8c4a94ada042a2452b39cdd02ab897da765cc0f8d84089a8cc5af662c1c96aefafeead785ad042b506fc72556182566263e90009a86503595dca0924d87ea6ac61d4e931025420436a8716d0ce379c5e3437b26a12531c0a1abb3a693f3202f5770f1dd7ec1eada8c2d6c747a7161d19ffbb897710a17e7740fc232fcc244f456e962ebe71f7ded8ca73e07dd44f00fbd023b8a72f9005f9bd4d0d44135294258ec14665309e9edcc82d98227474a9202552d31f1d2e7374d49929c2885696e5e3edc1983432f1dbad351f9cae3cd56855878d9a076c6d3a27f2718e32658f2392215915c020db\nTAG: 5689d9a73d52266977bfe5c1bb1bca09\n\nKEY: 34091633f4aaf225aa02ba9c57b910a7\nNONCE: 6535f0cba67fbab0e6fa0bc8\nIN: 76217fc9a546a97dabc9be41209bdb582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b590a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b57817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021\nAD: b9948afd8818888585a6957eb59680a55a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076\nCT: 3260de6acddb17f93ff06dc7a8955f5d363bcee255bfd40fe5e92e13c7a1c682c6385736284c5cd858ce6ed251b92f5eb10f83970525f56a1ba0b8edba790ddb015307cce877c53a831aaf56f375fb20e58199f6ddb91efdf9983f263c9a746fa2d66bd4790531f85e7ad9a07cbcc00e9c122ddba77b1cc2b37b734a0ffbc29188685227ff42bf33c2e912eb592de1a45381cf6c5c9a36af93af26168c376e8902299e810e07a8ba2e23670c5221110ad4296a581151185553fe366bb4057e61b7a788f12cdfa635d9d6b8ca47a5596a765d58bb7f877242c2e0145d47c300175d7af62a29846830922308b6b69cce8413810184b27a8184bca2d8ef16316f13\nTAG: 7dc47ef9283971e1745fa3ff698c6a04\n\nKEY: d829975798d4f24ad243e4aad474fd5e\nNONCE: 59e25a6dd133944918709e33\nIN: f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f510e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531\nAD: ce0e6219f75c4c31873d4915b1af3a51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3c\nCT: 98bfa05d1dc27d721378bcc25af4899c9c88fcd54d56662282f9b820e540444dbdc57bdc63b60680262aaeb8387e149fc2a759c0246f771dd9a13209c4eaae9f8c7e43439535afd85c9b12fbfc10f8f9f417079857b9e061cd24b7099726528f4ef529d14097239bafdce4d9b51860ad091c8a7d1faf39d44523973cd1df0377339485a89036d62cad090ffb9d05c7c7d79b01a22b7ee5e485e76ca9be9f037a94366968003b73915b027b161ab90fbc6ab78f6ef261ec5789d668fa2b28b1b1937da1d2337507997fd0d80387495d6953b08ac0a3fcd24f1fbea3df9218a9f0f1112d7bd4bb03ffb9dc790306db5e03d67201ab904df0e4ae283ab3d62bf48a6d79a5faac2ab33aa0599c0a6de5677ca0\nTAG: 767e68b063ed300e63df9933d6e10f2e\n\nKEY: e9e41d154c4c1bca018bbc4d744655af\nNONCE: 04ee2cd524db41170f0946df\nIN: 225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c\nAD: 7bc7b15c68437005a4973a06818738adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a49\nCT: e3a3521e3e99ec595a3d9d0839d8d0cb4c0929e44f693df016da34e0d8a1f3f6aae28fa0ac0f38d46ef06a683adb04df301ebcd6ef0abf9ae3cc220cfdbf36ce8c023714d203ba785e9abb05095c4bf7f07a13f9409a5759428e6c97cd4a8b2e1a471676807cf76131ae471fa4e8d15225e9996ce4c7630c4b0a5ebd85db4bcbd79bdcb641a626773560b591adae5bf582f3e92299a60d081aacac117235d6d8094e97b034d120c6759394ede2a8b67e47864e1f50669e8e926ab6fc5cc696e70bb016de92707d4800b25ad14f9c457baa1e21b4bfef0dfa6d849e0951c81583a711242ba2383efc85381ec7228b8e7950a375df405f820ab5dec8b37572897c6af443667e09d48a18c9bca0322efa409e04f57741305ea7d51ed9018cb5d0f00b5d\nTAG: 8aa9505e89a01281f033e9658ddb35c1\n\nKEY: 7b1fdb1a720b9510d7d8819b6d946dd8\nNONCE: 5c73be515c6ec00a10a69661\nIN: c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d2\nAD: 078f1c67d44d6e86eff0c96a146bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d\nCT: db79e91f4458befa47953312aeaf6aad01c3fb6e2cfa19b0ba21ce6698896e62e7ad2cef344cd324b3f0d317d9fe7ce713d4cf1743adcbfefb65e61ab6b323c5f16762ac527882f214539e034719047f9d3c0bc80480b7f76481e2fa26262b0bf426f1599d3d0947492769ccd65433fe70340d8f74fe31540b48c053eab97984f5f670651746b68617f603ef23117e9a8df0266851ef895b58b847e911508dcdc590f6188aabf37be430bbc72746ed7f5f47f45c90e2400d5be0e323824c5b86a2a0ea7c2156f482f7e0ff42923d6f7efc7f4f2cc77915bf85091216bb0f8c35f5274c0c8469ef03ee78b82cb6a5b510e16793f38fa2582ce249370ddf480e212f1cbcd77f89810b41effc9c87b0a80e5a22059b36e1dad294cd158f03d80ef3ed31b5f3b095cacbe5782986a69d5ff7621609\nTAG: 221274b4be8a4fcc765c2ac319b5186e\n\nKEY: 50109c383071e4a61ce18f495d98b6c4\nNONCE: bcffd0fc2496b7eb0ba612e2\nIN: a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f", + "443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18\nAD: b4c98f6d51fee205805a50c163beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf\nCT: e7a4a201f58f66ddc0b8dfdf95c859879144dfa896406f43cbdc6adc148e0ea8f9a82170c5ab54c77dd0fa6dc209b623f0f5cd4ae358af96ec27c78e7245855e94ed1a1182f9d26d45e0872da3fab9fa9ee3e58aa168925d7f779feb77608067ff45b7ec7f2ef7a48a06ee22747ab96e1b485ce144bb3cf97d1e3cd28823628a2f8e3785d9af28b76c53c3d4c741d1ec56f2bd10939f6c79578c308c5e509ba8b13c820f5912d4ae169da4e04f86ff9b1cb9faa432545f7999ca1014f77c08ae9033712dbbc0e99db6eb604e774d5df8f6b928a0bb59e4c662d778d195aa95194a0cdf7688b309abe223048937691440e5a78cfe0cb75d229634aa49ee54a81fc9a6478c8fa310d524bb15ee8f54f572dee30e44eeb9603c8593f8a7007a1b0dcf2e301becf300f20d2e868b104154651446316414b5b5e9432134c0eba97b4cefb90c32\nTAG: f304266924eef673246b3c14389a82a9\n\nKEY: 670cd4d988845b1d41cfeeb1ea740db1\nNONCE: 29c12f66a74e6234ebccf4df\nIN: 706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a2e\nAD: fffbc936ddfedc527b2c9cb69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0\nCT: cc573518606d6416256cb233c66352086706f7f321fb5d69dc75dc6e11b9f7d053bd722b8d74f6edb023e283ac048570dc23dc34e1d344619dc648199b6bd3627590c7acfc738f10d896c0e3fbc3d3b9ef75c20c616d1dc96a6c3661b4f245ace3083590b1d97b936ede9994b08bf19189f573919eceeff80c25ba1584a1a8744efc1b2efcc264afa045dad460d4a97553d33aadbf6dde24790853a342349446741d65d3551ed343e9dce6b6cf6131c9bb3524597d0ce95e6971c01581fa140caf86ee4b53d17befeeeda4f5ce5b255a429c27a169aa075153bd4f1924df1750332aecbd365d8f65a2fd17f6abe9a054b3a2abf02a5b2031282715386c166dcce653bf3f3fb67aa119459bd5ef3bad4ea97aef40335884175d7fb9bbb3bb7f3114cd68c8136e8d02aa204d282403a34a89305725e2e022a9db9857112350e965d51b7b3de7339cfd3f202d18a07155b5bbd11fd64b\nTAG: e3c4a624a012f660f21be3776f20b440\n\nKEY: fc5b726bbc23a67015c35a1be5dd125a\nNONCE: f812b7661106827f31a1e4c7\nIN: e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bbb55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a3d5b\nAD: dc41779816b352803f282410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755\nCT: d64bf4eddf29f08aff3db1225ccc9df5fa92315d70bec762a001a21f564483c43d9fc25e26ef1cd8426f215f4fba46a4fdf5ea96e6ebafddfbbe15ec5a7f8aa6058f8f3b5c48339fae17738b374bda2ae9f0b95d721342d968ccaf1ded6cc9e0d25e4074b722c876565c73a80f9ac25c8ab7c9967b79e5f924697b65ac4f6cd8f1dd6adb5a3c943c5b43d0563ce8656dbe39dacf220e600b82af2b5ef9de009b51fe6ac5707d3b0a15e87ac4c27501e88e9fa4fb84d10cc489b2738fcc751ee5aef230d4b9e4529cd3c580e2c248ce92184fdcccf8d94a5da4ac34acb13156dbc3e676bd26c68e1065990a73adefaa4a58db57dfab709af8539f449d3c49e7172c6ae686e494a92386ab28caf37ebd026d0e670ea85a010a6fe8312fe5a71fe6f0c7c52dc80b2dc39489ccc39c10a7d3d64ad66ccd44638c8c9d83e1b88930d8da56e978090dffb1e04a08303fccf1dbdb1bb160e0f80d4493eccebd984f898ce877454f84b0\nTAG: d69dab4de29ca8e91f2e74888f80b841\n\nKEY: e63611c19ca5deb1db80f97a3f5149a8\nNONCE: ad2cd6491caceee3e19782e6\nIN: 6354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cbc3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6d70275\nAD: fa9f177cd36c990d4b22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50e\nCT: c22ffa587dd3b6425b81890f8eff36af3c64549c5a5f3e1deb44a7f14c6a179b1f76dd01d546a4273fd6d47b6f9e3ac5e9b641982d1002fda49af071d1dcd88ae5d0ad778d846d3db243ee067f17a91bfd808ddca26bfb67ad28303be8f582de507fb89bfc79c10513327c883bb4c6b97729c1d4aa32ce50703636b2fda0f592174f2ea36b26691e6355ad20bd116619dc728895bbc0cd281f58aff68d39e16087d3cc02ef04dcc93e9bf7695cb15a8f2db51df2e22a2f04be96021b4008f50c94cef256995207ef1dd9c0137d4cf63aba4a0d28aa5ff7240bf20895f8e9585c8c16437edb41e51f6ce5a4f965f0abae8bdb7c7abba2ba82eb5ba1dffe56411e51aa87617c62f7f6af3189647340865f92a16987ab784b1d6549099b1a02b369198ae9f8339e9e197f41e2798076b5b5fa61aa7fd7620bbcb8828b2332829d554f21b83d018b59f785e3a2db359b36fea9a8f085cfb668b3a7d80ad38b85e24472e72916bfa2887036d480f6ca48acfcc7c0f471a9501e\nTAG: bd674531985fa355e1ef3b3dbf8f70b3\n\nKEY: bd7d9a251a127a4dd736d0f74e68755c\nNONCE: 4226110c276cb7870cf1c7b8\nIN: 6617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948e63eabbd\nAD: d2f357cff8c172e6652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a98\nCT: 7db6315", + "e1ce8ae23774c2e8826811bc31b2d17c869691248a5b49398465319576c56c2a64e22ab0108c92b52d9a6096f33841643099cf47aa1defed63b7855f3a4586dfb8691c982eaf102aa87888d09b6dade960bf166e48d58999dd08a0802e109186495833a8d8bc5d6d3159824d1b89d4084cb831b8526dfd1c620b4fb6000e45bfc1a101984f3cc51d54c793ab8f034066922905c532dd60c7d96f06989d10c82844f4b20e872538f27333e6d8656b46fd819936124617cddddac8a64d2a81a0cbf21fe91293c8ad6af63536d10c11a63297b620350a6f76e76afbbf2d8c63428d46c9ca123b5022e6d67fccba1011b57aceb10da0878bd873422438cd949df47533eebacee697f9856222344bc9c4876f8435e0b999676d141135a6f42ace8f99b16d86e427f1ea4d4ef524835385ee1cda9f4049c3f6f9226a69b08528bc3970166f6f9067ac30f9d24b7da6bbec4e58286b3b1c5a7711ea7965ecabd02375b38a603d49c12131019a9b2affb801c91d54896c8c29e09f62a5fc0b100b80ed54b70f568d7\nTAG: 9fb615a8c354e10560c3cd37ceb3c3d7\n\nKEY: 71bd6158a17dbba101f840c6638ca058\nNONCE: 9434c5b842d5dc501c774114\nIN: 2982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d5205995c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d50599a3b2bbea36250ace162989e3c21249115a402c544aa82c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd126cc8d0d268\nAD: 16561102778d04ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72\nCT: 6da55c8a9c5a29eaf8dd627d7048f0e6cf1d52063bd0a7f8d073e66fc406f37fb397f789e4bea1da21a94ef944a2a0fb9a35a7acee3d3687d8d713090a1f2dc3d118ca10c85f5542f9f6f40a4a79bd8816efc75cddd4a7adc9ba91483ca70daea0c65e975be46f690a2182602b29d7c04991d2fb61f154f8bedc194ffec5983b12c4f4d9abc0a415a517f4b8923a2ccf1d5213952133b82621dfd4a8379cca916f6ed9e58dc94baaa1c1c7d8491c3341e0751d90d131f20722bf2c44d097dfcb6eb49385dfb8c86dc47a7dce3ffc3eb89f32b4f106bf48c0d69aab448ba315145dd7ebadeff3798bfd004369595f48c9e7be596fc181bac4573d994f6d7a778f353e3aff64c3bd5169e8525edb96f1e97a5617345fbac9f58c0885d52ba25a019a4e01deb3ac14c4739c0bc73f28d4a05bc5b0be11477395f706d45ca0f7fd92697e6a8c5eae587dc9cadf62c4e8c283041211c3e51a23b84bf00d3bd4be490cbe9277268fff3f652ac9eea2734fcb016639f3b673b0eddb2691b10713fd5bd606deda19d9429ab17539dfac05b5ef87c018564cea21fcce7a\nTAG: 9f64a1a1ec8b09b1e64b258744ac5f7e\n\nKEY: bb5e6c7b672e7c5d720c2035dfe8d42e\nNONCE: daa56f54bd2dab11ce5ebc2f\nIN: 95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c857a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6f584f4ab378a\nAD: 3dc7d6102a17877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c67\nCT: d5c7b4282f37776c03c6efe2af410b10caef49943001460800fdb6408f3c7a9f7f32d8db36dcdd0694170975536447d84c56f84c966c28decdd607237bc7ddb15176ca20be0993f309d2749db68666b2efbeb4c68cb3982a68f67114c0dab61eb9d4cf4c23f1847fc36bd561b0469ace73c80b0347af5e88f051ec6cb19ff8335dc56cd3bc6cc81893c9234457c0d8189cf1234a6c8a262926402eef262c4c5149fb68053480ab2b1512a91d50c48dabe637aa410d6a164dbe4f8c1e1c0efce8687dc858386c92ed7fd8b8692d67ddf453558d28998ca1b57a6c178f12f4b64479b3367e8dfe53f809fa7baaf8d1efbe3c9e2d83b0377cffd8d8dc172a1eb260762c873af724248011d9e0cef6971ec12e81d70aec923664ff7f7cda9d60b3464ab14488b243930845e38e93a8683787641b85476816dc73d17a593b68935e4cf71d81ed7dcc9202db65e235dd69c1f2ad4fde4d566970923a24bdee799258a3198ff2e126870252584a1949439b7e32318af204ba164f9f3488a669800703f988fe56ea6b0b2cf662c43e103e2e63b377a85fd8024d3b40ff47f30fd3dd6a0e07e751d07d5b0e4afea2\nTAG: ab140e2a4dfe81a064944610e0cda2cb\n\nKEY: 97b507a2e09cbf5c31f7be6dffc78d88\nNONCE: 3f607f0ec3ddbaaae6b087e8\nIN: 731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309bbcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe16670d77b08988\nAD: 0c962e558fa573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894\nCT: ff28b33337262980b3adc761b8713f01770dabbc1f458516c721c6a19317ed1f1d6520fa7b2859cc577fd92fa3525273f4a87c99575940e941914ed586e7aa5637c4fd2d98e7d198b52924619dd68a214389cd486fbf006ed9c72e6066d92d2278abf1fbf4b4ea1f3d945bb1653eb3c217d7201d5aa40d34c8488532d9818b06e4c0e97c4cca7c9e2ef19ab5a397db27d4465f41585ab60342a3102837cf43c95db008f0689ae7a7970c2ce9fd685e2811393931a4d169701068b6575b47e88bbfba48281ad4b297fc3b265c0590be6b0208f6a27594b0454e55893c68203233b60d08e25fa66d63e76a869a4b84d153c81f1faf46f9a3130f7ba4718a75366af23e4377d60901b960a4926b850f4d4052d6ef1a5c54ffb388acbabecf069a5841a76cf15ced838239a8392149ab2d904b482bc661b3cbf4c74b711778cd61bc38499120b87f0f45f8a5aad51c84595b991d7fe37582b1ff963063770cd0ec9d98d78ef323c8bc939cf3b6035a5e1f5d54cf9af44d49f9cb01b7d1e91c2e0da110a33e372b07402605ae81bb4ef5505ef51b3dc23ef5e48f3f16711d2d72bea5ac90e85a37c97ba2d1a4f5117a616b3865d97a65a08265ea0c8fbf\nTAG: fd76a9ef5ce12640f3e782a40c6d0fa4\n\nKEY: f46e56f5394bacb222b30fcb3f5d5547\nNONCE: 6fc37c122d6865751212d4f5\nIN: 7651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab", + "2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6addae1c3199da8877\nAD: 8d920a6c79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f\nCT: 4877203ae9162588de263a70fd978343e6e2c7efc107064c1a314e210e01633eab9cc234a86f0815e515eb2148fe67023dc7c67616a575c0c1adff2ca1bd7867ca351963728cbcb6a41b5928e83b6ad97e458773e543138f87698c86e6a84725cc6330e3550d40dd3103d0aca5139b2e7f7f7060e34c383280a9276aa44d915460cb664d132056955b2df063a03fe4f844122bc02455ff1558377d8c15419e34417e3c0d5d69b69943027fe32384cd53e121f885293f17cb3f2637261f3c9bf6321406f3f4e59dcd37972e3073573aa5d9f78e021d07b7036405f193c65a2f8d47f9a2193623d403706364f514b1beda6930925c1afa9f294ae625673e41647a94830dbfc45a4d9029d5e028e8997d9f251aa7da65b48e1abe8bca5453482aa6d1dc1168bf4a6ab5644d623ba15dbf10b0f46536b35e30fcc5086184d0eda2af5016f370c9931f1634331458c51b575553686b511f073a2650a1ae9cd2a64d8ccb14194a659bd533e91cac42690d661c5038d0182cd8e52bc751662508d2253460fcfcc4428ba7a55f1db80bc11af7576e6b9ac2a35929bed35ca82fe497a65c24d04c96e6d9fb3bd66fb54f01483b766b614a97e370ff406713d4b811e1327fa52692355e1d307fd2ac67a4\nTAG: e7208823f0abf2571f81c015eac317d9\n\nKEY: 4675ade296a8c507fba35f62c82d9230\nNONCE: 51fa718d52a0279ba9971490\nIN: 32b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd823d72dea41a1c1f1611fbab63d339a8dd47a3a31b7790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205cd0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d5465e4e10e9cedaa39\nAD: db35fdd7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726\nCT: e1e44ceef4e08b85ca5fddf58c4d6eeb9785e0ed50be7856e74dc1cfcfcfe92f0e59a4fa62db0ca641b0be4da12a70fb443ffc46c8f5f28ce467cb484a7a302dde2d459da83d8ca6707fb0c6eda6312e37c095276f9e65b44fc9a0ed7546e0224d639a7ae396403b0db8be55276fbc380181cfb32c357e99a4ce0c33e464d1feab4a409651752a05f2dacaf85125005b92a195628bd314205b8d2aa1aba19d32c789d91e565944478e90cd1d4e10c475b79ee5e7f7aa22456773febc5d0684ee0a26ab27cd391fbfa1168ad28f46b114d31c7a3794cc216626eb41655990ecdd93f97a7594330a78426da7f2e8aa21871a1207f769dad7db7dd794382a0f50dd8dc76ec3245576b99a32314d3b6a4046a56fbe178fc4cdf8bf39c86a6ef320f4cc63e5abb6ac53f6b336fff96a22dbe2e836c3ea9f4b39ed58d01d45937c8b5af0df6a44bb78bdd59c1f1ac6643fc710e27a4fcfca031b6435ec2850289605e29db5911cd2b930a4fc28bce98b30cb2b6b9504ebd561e65efa52759e64b435b99ad26b7653c6bdd21c964d20c5761bc3eac9e2986cee13068c627721a90862fe387382af2895efde343e3c9f13a3ed019a144533af765424c7c80795cb30ec132e7aeb9a0c0c75f2b885a4024325a491eabbd30f81592377e040cb9034\nTAG: 5100a3a60ed7d5837ed8adaf78c625b3\n\nKEY: e198729362ba96f79d5e0d89fc404b38\nNONCE: 36737445756c6060d9e95d16\nIN: 38a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3eddd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe85940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37597c9a73eb47abcd2aec\nAD: 1b2a8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee871638\nCT: 500fd0ba2adea1fc2ced2dce635c5296edc590f961c26c6fe285f4ad84f6e85719ea6bbefff398991c03a423931ff493ea47f97a8aafcb1ec7a34101ee8a378dac29f027c312306f74b6f92a6eabc829c3117ff77b6859e67b37d05d48b2c12bd30251d32ef30ddaa17894373063e2a593ad5139fba87d38a045e2e4e0470dd4c5555ffe6fc70e564502be523737bcd392d0c41e70a594b29f949838f9bfdb6e87fba327c430b75164555d7a01d7bccc33f2736864a2200e4b2c4d7b7192cd22f7549a9dc3ddda269d78a4d98a344cec44508bd930a14edffafbd1f25cfab8a29b75d07d705c3291de774af867e2e595ca8fa2bfb9fb3cf2511552f1c872fcc8b0878c4eec0fd079c7b17bcac2931181897ad50c03880102109a42c34c70d64ae942c73693f85a6d1230a734fb35f70c02c93813700e21b2abc304631ea9d5392c67864eeb47948b7e377bb51e3a5070524aa0abcbe0a624038f6e1b3c062b7661e1471d6cc3dd18143d6237c0e32e80791d39becf94974bd765bcf6bc5a3d764584b025317f64a67d13234399e8e9d10dfee9a77ba887cce119e09c812661b487561acbc718bd200ef97f76a4664fffe64b367bc36f7d03930f020e0b1db0d8d36103da1dc8dc6e0df00b2276d25c8312222c13d8a070b108a1b3a83247d41940681c59e08243a12c623c2f2d2a\nTAG: 7c3eba9d36b26d27a7a0325d8c23923b\n\nKEY: 2167ee6f77730766fe8b4ca6c8f02708\nNONCE: 96bcf14cca5d7c2184dc6eef\nIN: 47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc95fc19c449bfc10443c5c1\nAD: 6388d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c", + "77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f47\nCT: 73c6a7d5e4fe14e991680acff32d660639e46cd0ec231ad155750e53d6597bec3070f5e828e420cc2044d5bdaea5acfb48cba1e9dc52258fcc5e937861e9a970cbd04f10fec4bebd6d8cf81a8925e5ae48d8024f7c62e35aa370994760c827a534e0a309655b3085a2ed8619dd0dfe0560c7dd5e175fc5a5971cdd50aeffa073e206d81d1932f350d9b3f40d4eb6929bf7957d25b1b12d6eeade7aae4b7277b6a1896aa0983ad5a5e5cb5e8e86b1eff15ed0b48149872ee4439acfc6fd6381f3d9527f1d1a1452927beaa3e3ff188681408041aea39f28bea779ac28b83a4eaff7406b08df2e60d66121c853800e56b3659329503bc122e6c47c1e1dab53986b2058685409c4a81b057fb6655de0f84ca770ed5600db097efbadc14f07d80cb892ef3ab12ff72e9d60718dfab82625a79168ac262b4069c0ff14bc5ea3baaa4c0559ef23f2535ab273e3bee0b2d1b4049f20e708fac2430af82a1a5d148164c19a956a3db8e44c8fc7c51af9458c066719884f0a192464c668d37372d5ffa4e2a4eff429cd57eff1b374d501e06b9d3cbf8480642bbd141b208ead6fe46d436507099ce460000aa033528a8d813f3cda11c8c03b427228c5b24b1f0fd15f704d7958aebc580bd5d3034667853a67fa51eef18d102d65507047b12a939f8a2cac8bedc027db855f89ffdad34bc726f6c6641e3c8ac8041003f65cce96cac54d\nTAG: d93bb140c5ad0362ef819fe04daf051f\n\nKEY: 1b63e84a8114f73f918aba186239947b\nNONCE: bbe2973181d9b48e801e3a55\nIN: 97b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b68d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae170e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e\nAD: 7754de0ce06145d6b247742ab582584c3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9c\nCT: c1e60f8dbda68c60024730deae746fe9fdcbfb9a3c1f26301a87a3c6bea9f8807ae294b62cb48ebacb01943818bbec06f1c842a3d42aed5a75c8103e07180d76f7e17377afdc4ed56905522be60c9dc5eabd5bd8b9a720b661f631dc214ec1a387016f57085ee3472df5a0d0366210aabfdb1ce23ed9480f8f1eead8780e33af36f9a49b8050749507a8b34b0695606b2cb78788c3da4ef316ecbf9500c257e8acfd36bf600a7ec4f8d2c690db5af0809c5799dc7b7788199601573d8d1a91a7c08cd4bee88885d73998c554ce520fdfe4153af13bcaa485477bcb5f55fffa54a4c71c5e61e1c3551ff7fa39cacafffc5cb00608be2b2d803bdfe43bfc256a7c04f536f4a9c383e6b4a3a0695d7e386f6ca8c8a35a77fc9b1d14e202bab53bfe6bd1d1efe3a4715bd150369403b6696374b4498186fed144f5a6edb9e3a863cdb4de5a6a404a0fc3702192cacfb36538e832b4aebba8c3726224f781c51c1529722d905286a1e01a9bebc54001980acfb9922d91122c9b125d4f6376599f0280651fe9efefad310e97fb06670f4b42df4b3ab1a078df2bf9b880fb91b292984416b70809c09e001e30d285a027f9b370e0764715187b797cb4965e7639a9bbaf915456cc4cc45505853ddfc54a38dc46743adf92afe7f37b174f0108468d772fb2b7ea00e8276663f6c29d3d83f3bf47ed8b1cc86bbe8639a564d936a3b065c4\nTAG: 0a6307fd5192f65b8786f7bef96c17b4\n\nKEY: c1ead957027a7303f01622d129eeb876\nNONCE: 04daa5b792d6d2cc4ba08cab\nIN: 47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe28b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327\nAD: dacc20b8d41590570fd882012b1207ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc22126\nCT: 1f2614433c137c7579ff19ed5be8e7897eca62f05797266174d4edb5fa4a22c11466b17d97d961564dbf9d1c45d9b6568d330761b9bc04dfdd31da08d3ddd4e5efd3924f53128ed541a6aab87912af60615da6dfc925b67b1aa3f1d285e25514f502eb5e92c7521da3492043fb06172ca74796b811ca42b349e337615f898233944644d229d05f133e35f879471a04efc3321094716c10b6f81ac7d0604096f287655362439e47641307ef49338a70bc87402b1c5ebd931300be51980ae8dec0345beefc59bd250bc53d39b7eed62f93087f3ba83b29ab094ab8d3143b63e905d209150c544e433d5ce41f00b65e0a976f5138db6ba5193245056734c7209ffb256a2f1ac9840f1bbe2e82c04120f591da86e253acf25b3876ab9e6f434489c43f606f264d1672cfd8a43282b41c34357497aa4f3a8c318f93694b4a04f1a0773ed064d4f426350dc7bdf4a59be0fd4154097c09841ec0df9c0e8f2dd31abd8513925d5d3da72624567a609975a815e9ba51df408bee244b4619f8ce981a6be726da484513cac67c2a4f597f6ac8ab0e96d86394cfcb5b6ccf2440a53a7181788a3de730c2e84e64a4131d0e02b8db2ec11f2af61218ce1255310756d98a0d594f09bd1440adea74720ff2745db30741e8f4f7bae0701443f55a078ee3c3bb63411fac0d7c7c0d0cb05ea56f40cf4137de20d9c5224fd4e6c4c6e8a5868116dc850ab713b001713d13e6ae5098c379b72e\nTAG: f1271cba346522f88ce93726cfde016f\n\nKEY: 2a7e7959ff156f3e69dcf4c3db8ccc25\nNONCE: 6d666d3700475874d600d6e7\nIN: f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b6\nAD: 6d3a702bcf31e90cd2ff6a350a94689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c", + "4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e\nCT: bce5fbc1719b18299c54d224c2a0212cc904f9f58e7c0d8bbf1b09df0c2c08347cb36f2c8d145b5ebc4896a398b6aeeb2db0ba5aa3df6624a64bce91db2ce843a7549714a20404e869497e593990a1a6e62edaa9827288464bd7b37d2d2f8ecb6d67137f2113982d4ea3c23cb0f4609f04bfd73efddd2e4f05c4561fdd3615d82ccef83c940d39f4f7d548cac2ed181e4a60d1f280e25ef8b617796580069ab2fe8caa3ae4e3722eae649e390d9375b6f1b153e6c542a84eb70241e2272f2530940fa3e0df70528ba07747866fe51c3f844c050cc110cbba10d1f8d3321958e1e833c3f4543d4f8b3d20c8fbb7eb1fec4de7e99464c52d97e7bae8608419f1920c27ea0f479bcbbc61cd5cea10971ae2aac0a73daf4e90c47a023d620c2cb246d5e35908535bb5a0fcad54250a29fe53c1a0090794091fb5b3704c6ed52c8fef11271836250f39d8fd9ac5977cc91175e285192f07fd163d62216fd5530da9a048ea458c47efce109723029992b155809eb73a34b8bd24fa647b006a17e1e315b8a6fcb0e5af6871b4bc6f5d690b3edd10fdcc5391648a64d05f3355bc2a13cbb74d1892eafaad1611c23ff96e7e80f0df0819999977f9a2097617cfd13e8fbef089bedb532b331146d793d224d8f12bf8fa63b3b3d9fa8414d63a7618ce7a4f9c52d8c1b2ccd019e4510dbb3bf71f14c2e13452dc7cf859d18f54d6edad075c37a6ed2f05ce6dfa48421670b757d6a138813503a6ea964707560658861a5b95330e\nTAG: 85713c984bb8b5acea392525719dc9c1\n\nKEY: 5de639113d920e239a0d1581e179f9e9\nNONCE: 0b5bc077c27b08427f0ec327\nIN: 545c1a235b88be7e8451a5bf405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc5\nAD: 846f6eb4aa086447f4a7e5e8eef4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dab\nCT: 04c79662edd08ad017cd48a6dc415f564a67d3d9eb48f1c7910074e6c3ae2d253a5acfa661377ec6ca3ba6693e77f2c97a9484bfbbc3bd261fdd25512a9c1e0d2058b0cd365fdab9c14f602945e142025009f87c13dd1dda03b0c49f76cbc3a93d928eee67627efcd146ab2fbc19d26955a646201800366fb17efa420b7c148399b262164c598cf1b011308989b7dcb699110338649603b58af4cdb5e7c2a306164d7e588fe115b4751ba0a83cf849c869b0155b3f934ebe5382e46db1d2d977769caa63dcbbee9f33568261c6c89856f75d597973d3b2a48508f2773d19252e04350b3c88a6696c3af860f9dc7cfc35e6e96279c92591c09dee7c23c02078e3a51af668ece6c870b7f0f65f6b0f38018be91876011b616fc5630d12ce936b6ab725b808108a472ffe55a5ddce340e5de8a279974c39c64a7f5986ec1e48116bec1b6d040e4e291f429c522ff61dfe74f2f4a075e0a6912bb6a6aa945db933eaa90d9165dfacf087a58245b54c2814086ad5f54795f1c9125988dcf15f906671bdf25da87d145dfb22c0683636c61c44ea9b3120d894e02b0d6f8d021ed8423b0c533a043f263ea3b1b06b5d5d7dba17bcccb1485cc5830e7e5b8520f9a1943a3560083e65806f9a633baa6aa7d5b99e5c5d69db446cb39716c415dde4ba0be14108ce32fbe50ec0605b0845e9469aca76dff75ae1f847dc5e14ce8b5455af8c2f6bbabf889efe1dd6ab408d983f51b143558c73fafd09132e22113b36426535b53ff2294acefa9258a58893d7b3a252f5a7d4\nTAG: 07153351dc975adbfb8b30d77c1be155\n\nKEY: f0f31be89acf8d7fcdb2a063de5a9812\nNONCE: a3d6aca502708d448a869bcb\nIN: bd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5bee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158\nAD: 2c9c6974f2442b87c02cb723f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcc\nCT: 57e32933293f67159efa04c375a4d7b8c8a050b0cc39031a3df3bd4bc82839ae1210da5f10b0723e111ce7d1699c78143671d7986f83fff90992ccfe9fa4367ef9c944cd571a3057a65cc1ae7fd7ccf2c722f11a9ae6756ef0a422ba7cb15a02e27aac6faf78fa2c2b08b228b1be5d3e62a5e995f9d3c5f1cbda1a6ed3f551581cf6693d678f2323e2ca7437715dad965024c8d5eabf68e7ee3ec090f56deadb47dff68e93fd8a38ec2b34d0e774f07793cb03d38921632e42b4a092175f6d602ec637aeb1f134067fb54594f33be2d9dbbae16ec25ea7b86a1a88346e0335d7bd2822a3d209a6561ea396c6128a86307da1c14d25b45e593504fbe38bae1a42689b2b53cf17bca92b4896c2fbdb4625d960bc03da9072910eae59aa17070a368a30e69d072cccc53fca2824fcd83ebf6d65e78c44dcf3333a00cf7eea5b3d311a674be8f46b696376f1fc5d70b727773582bd4a59111cdc41d69d58c52505e51e08e46d75372999f27628631c5d7497607adf4a1c27caf618a6dde1039dd33aa7834eb5164e67a208d473f558b97c3442ab23d22081ce024fe616e00e09a7d14386ec3e0089a0feedac7e6c841da57a13358712b75280f72afd0a28a3f5555e024b59d14ed108ea4fb77510c031fb438e6cdc7b4b6125a387e76081ab8568216a6776b7b52d311f48e882d62abc81453d65c0f5effc4abacec68dda303ecd225ed8afcd5638a9c4f5488d9f8963624934c1abb56ba0071bf11d64a52443aa0f3b607557ff340937a53fa50031775550925b2e8f40c744c36317797a952d70207cff0646\nTAG: 429a50441cf373d8d1cc4b37e15266df\n\nKEY: e4ffeb5ff128eb3c798dcdec4c665a4e\nNONCE: 7b30ac120aace497d03de3d7\nIN: 26638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e1315fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d", + "2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4ebf3\nAD: 14fd627004e9a78d1334822040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce49107\nCT: 7ef2888ba3ecb4c9e0b96414504cd46365885b6fca375534e3dc43d4fe31b61acff2cf2d0b698061ecc1addc1519e00b1f3e59756cf70380e9d83352ebde4fd680fd995157fc12054376c690ee01a11875b3e833de136a8e16ae08e80101caac4e7a43042abd81cae91d2d0f98ec0b6fd7e6232fe351df92aa847cc11044a3e07f3f4d8b8b64f039fac77c95f9057cfefa11cc795fec334051a81dfb7e08cc09496934508423cb75f8b051b811179e37ee63346ff3ce1f1012117b0ad3c03fd113f7f932da558244d5809e6af429084e70b206f4dcddcdfd549246a548d51df1fa68274416b27cc2c12b3a6a86d9bb80184d41a3971c9dc0ed906aec4ec85e9eaf4e8dab1704f6ac3f7602b0aadd1ae4ad91755ef9a08e231535eeab932524b2c228d10b9cca1f88215ab56bf776183b9c14b2888dc7dca590f48ba6fc7e974352da98077d0d3f5de4159025270eae300fba5457611cfc4b52846ea1fdfb29ebe4c260ef2d0d61de644cf8c7390a66d15f806299ecfdac0d6ca83def3873f960bd5b41d05e9a718fa0329e2304dd210f20228d7da87f08bf477deabeb93304133eb38439f49e821ca66474ba065c8c6ceff51717b36297eb17bc739feb166455b79d83ef6b12506c5a877f9e7237ace4e451a17969de2ccefb65af407a1df71ac99856d485aebc6492441366fbabdd11c9ca559bade381672c8497cdc86175d2f186272c9b675cecb365f97dd547d14ebb2bd306d80d83b40e3d4a5ec37812b787b31b2464917aca278bc5c3ac7e78ba6ea0bf3744b70012ba4cb5f1b91703504ab5b0134d5c8071ce1f16218c51207448c894cc1b\nTAG: d338cecd6bdd210923d8ed507612ff85\n\nKEY: 58ac0726e0bca5d30bf4d0a231fd1242\nNONCE: 0b9b60c3a690e0ce0106c1bc\nIN: fc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61ff7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e10628630\nAD: 0bfdb282f9e2db0a43c18132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b\nCT: b03db471a65de5cf871ac198ddfedd14e66b6fcb6c42c782a4d3c156beb2024a1dd2cf5efbd87884b029f42c94067a42a165c1e00018f11cbd79f65da02c62fb443ea8a345c34b6411112844eff3572427e45e061913bd578624100e33908ab9737140ae0fea83069fd008af952c776459c6cbd4ab9b02156b3992c0691614567056865b9f39b526f28d11b7707f35ad09d1eb0d2f6adc7c66f8832d8783478166036d082af1a44025a733781cb389612e3c124c31c35ea2a7833bddd053625d96d2ac3fdc69dbb64b9b7fcbcff6c6fb891d974184734d3bb4081d7609d7206067157954b4c6ab68e4a450f01f5941e1702830a58667b947352f1931ef721739be452aa083ea17344cc0a3b5820a90b35bf45ea00fc06df7229080b82b79c3930067f6045c619624958f77096f304d9f31effe42ef405ee4745f1b6c101225062a5bb38665efc428313038a3db8863dcc72de12c8ae41eb1a7b8eb02bd5bfb1f1ccdb1db877ecff08606963d97958ee7cb85b99c5f2ac4f91a922e180d7f3a3b265168d02829b98b7a72c2a2910c0c8c654e354f2e19a53618e4e46501ba8c13e8ee0081901108a75d6b7f601385cf6dbe3f74b3634331aed8eb903119ee96877f90d491dd5d38abd5f002c3cdbd57b04a7ed13fa09c9e2058744e1fa24d3fd87a863a7dd73cca389e40b7aad29a95d6f7eb705827f7308aa4ec9b07b1c98c225f366cc33586bd08e20773bbe0878711b6210392900b8fc933a6a661b8d6fd1a8338d06ec364f9025f1a79ff94bf448b998908c22be5cd6c1aff929037af9b642ff228865137dbe2f3f3813923245c3edc8edd76eefa02d40e7850e502e92e9511571f85fb17\nTAG: 34213558263a230e66e80c4095fbab97\n\nKEY: 7b9f65509a00841930c4087093c0e049\nNONCE: 45003751c40e59eeb10f62ec\nIN: 33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0cba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8eb8ff9\nAD: 7b4f599c829e412edfae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25eff\nCT: 5ba4306c0fc5cbc0028d54a82d2ec3039f78ecefbf3ed98f5b4f83d1b562be3c5ae66756dcd2027a515360274837682ed07c5f1a0dedcfe3d1e63457f9d4020d2b3d57d63401284eac89ef0cd16bef79aa949a5b3c76dab5342e8042e2e0d411816d311aaabd8aa10bd6c18f72620f824156bc71add704e0ac4bc1d4761f9bd1e31f800d0487f3bec7a788b0cea75cc0bb4ebb927e824bbc718236b089c752de68b4fb5b4bc1ca67e166c23274de9992fd30e0752ca561a4c5f469dd123ad45870dc013a47247396afa45ca5b02fbda0fa1c2a89180214814c5bce704ac4dda5be49af225f3a745391d669d7877d1ce173058433b02b714b7f9b43095820b73069e8c3fe621c45e00e41152a413e15bc750fdc517568f021645b6ccc541a9d61237090cfa6e374942adaa1f18d073e627195164fe981853e3", + "24d2e97c35819a00cc4d668ab1b8dc86188ba2f5fa76b3ba2303bcad2ce06195d6e853f7e0d257e386764067f244020d9660ce04bea8d61c5a940f502bb68ab6a62fe2e7492c3aaf355d313f4e2e2ca148fa46673848e59d744567bbbf38ab0ec0c799712053d0bc25532ff00f02a3149e6bd9df268ef8e1fa31762efab8102f6fed5768b9abd9bbbac89b40000394158c4c5d2bfe5f3dcbcb5126afb0f753e2a60c8aecc67782fe64f2f35fcc45e6ca4b6751c40adea4998140048456944bb8e2345daa95e989ce48378f8c607182d76b25d12f731b5029c245e804ae19d170a27f35634c64a1bcdd48a6b573959521d388e023650f427cd1839c77e0d56b4511d1986dbafda63cf43b6fe929129602a5314d6216e662cd1659d8d7bc6c271589aa4e01ce45970efd85297f00eb2470567e69a67bdd20fa4ed8b497879fb\nTAG: 15966db2d710d52510c55082f0c3cdb9\n\nKEY: b4cba7822382ec3aa42a95221eda5980\nNONCE: c488bf7ad0031e1ed9870968\nIN: 19cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d8039a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e96599fe335e0\nAD: 6fff534915999ba3c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f800\nCT: 0fd6ce7a1a51060fd105fc1e5d7c8fcaf4550de865dc0f990217c9e32d354a951bee16f53be1f9768f48d7f76c9f2ece7fc56b9e8c27ede94b5a3250ef27874eeb2dd09d2e50810afb7b9a50985fe28b7aee74303b178a0b74c5422d4f46a59e55bf55d7eb0d16314668b13952998205eb422daedb9f99dc7e04e11e8e077289d1402a1d12608e096afc6283643ca77813730bcee2321cf769c5cdbe5c80836db9814843a0ec72d49ea89ddf5e48e27f1e172423412b78fd91da54b776a132df29fffc5c8b41615fc491c43ffa4596430e55806bacb7e88abde1e20ae43260a1258e7d89ba46fecd08b7330409a08449ade364fb84ad1dff4e71434a3369a1d20158d02949edb9716b021271f73517bd985949d2dd62474a36e57b2682218ffa2d5a982c668a52776343d06ec4bd122d5a1bd5ab5b691e4462d8c52226f834290258a83ecf0847246c92d4339ada867f107589bd8af55cb96461aae47a879f5d81c3931fd653d68cd5139be7ea9b98ad8feb9b453f617cf7b8a4c9def78335d009d4139e66e10f642030b5a66fb44d2c07c8c689383136d580b399f685137b3054e40fd7c90f37ea30d52e09832b66251cc9c31156729e9cc5fa37463d89bf3b61a8f8657f6501ddc3cf1505fad36d4d9075f7a366050de98eeeae0c407b31a5ade0b29b1a7a3cc251ec8a918cc8239c3208b377f2e9a7df8aba3e086c33390bbdb4498ee5d194e43a67206e797d22a7c64849d1eb3921a8323d8a0c7d242f3ad65e52b992007c996dc642b858fb7ea7b1d8d6cb10ed3e9af7595367c26d4b01d6c178a15179ed45d44d83d7709503c85985bc1e2cf6200f4d0ff02e57ae4c53c012633935871028e3c7bf0f5035140290f4cc02afce10718198dac233a6dd7ab4065f07242e173b\nTAG: 8ba94213b2a8696d7e203e6bfefc1c99\n\nKEY: 4233eba54fe7537d0127b1a062526d33\nNONCE: fed44fbd3475daf5c046123b\nIN: efcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99dc75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c20da68ee6ee\nAD: 4e0126b67d2a31e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124\nCT: 4b9b468ed1b1b3ff8242f0d2f204e94b0312443ffce789fa9be7c56054c2392868d8826129462bba1b715d87d58eb5521a258af3e9e06d90e26702106242ad01ac6b64908f747306dc4ca142597d3021df591b60cfc2d260d9883f01078ce4db4b11eca4b7b4329962a6e5445857423776b22b802bd0eea8d7ce7d1d47d49a805d9f557b8d67926848668d8bd04cd2a9eaa0b118b9e680e23266785f3641630d2649d952501972d92f2c6e5e7ff9e8805ab3fea94e4d069487ab6767da42a6312c74a7191310cbf58995a94158987a0d3e6778f3f44f21c9e6c1b08029d368daaada4fbefbccca7f49e2f8c6d754286287ea93f69c72f3234acb2e4059aee4ff341730c9deccdda06fb67ab67b81cf5e5213b7c86b03c00ad8e447915284d5fe4e30ee2fe0fb2ac2e5a58c0623c80b40e6ebc2b96a2d5e045419fad0dbd611fc136ca032e71ba2523b5cc45f115389a9c9ef0a28d9b949b84ba637a32fcd3a8687c70c7d0bc4f27949b37d20ed349ad0bf1985e33f74b6974dff70ff72205085c766469b4c32bbd93365e207110b55d477347db18fd003c925b64aa4366212585e882fb5a5643d79cb6a9057e977b554948bf8129ae67ab02ca57d5052cfec2949e86f3c6fbf7fe0e1aeee3ccba5752bac7abce9a396fb6e5ea3af059ecb15937f34aba7fc8edb267ad1ee18c49e5e6f057ea5b0156093c6b042d2e7b2b29bfc9548f91515a6272aa8b2bebc5a0b0d9d610b6c911a69c38d15c2ab3b1d774d68c6d5515012a083dd0cc2fbb420456b8aa174be28502c2bf22c7af3a89686e2997f2015eeb7c33ba40b676b61c84702a3c5c51120dc290e58724d082281b496881a54839e6f0d622dfafec125b381da4823240cd960d63a6890c11fdb9f56a9fc8dc172c98a3764eedf804d1f5f56d4d9fad2d414bc4c58466f\nTAG: cd1e49972dc4c4e0ad3bcdcf16e692e8\n\nKEY: f79000afa6ad2a10b0dbfa4f34e47542\nNONCE: 0437dd10d487f42d2cc40041\nIN: af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05e83596b9ab4cb", + "fae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf00c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea32b0a22b260ad\nAD: 3ffa73ff1c5c481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b37\nCT: 47d6bd87f0ed8dd258b32f01e5c72457dd1d17982f1671310cb329e18fef89f25826f7a6a9abb54d4d216ba214503aed4d7fe36daba69482e4ace4b7c7a91de5a93774732e0bfa001947d8c403165473d77b6b0d53bece68a76cf544583980084ea5ad532b599206b2d618be4e56cc22be645a727a93fd73c434239bc9c0b2d1621e3ba63e625327cdbfb8f7b13997c3d981c340182aa59a4e8cd204c5c86e8c531019f4900410c6870a1bce9c5e4f81bd8134c983f203f7644577da19117a7432c9a7713cf1bfd3bcb055b8601f4f44d33b1191ae1e32ae868bb37ff5efb1a7f67d94d993c0c50074346a6b41da521633be46e299916425fd46bbf4593b1c02df98f68debfcb43fff6a1d7ad6c4b48296207d74a9504670b50368f2f6a2d89f6fa98b39e13cd46fcfa746dc533c8327a0b07cc89b654ff8ceee471eb42f1f07b0abde3ab49478563501e076622c0248bf8e82576e968657fb0efa23a03c3e3013098e86e44a40d21fe0e640cae3da3a461038907f9610d6dce7a1242417bd43d26ba6aeb1e6e3d0e54c1b9839d019ed409eaf801ebb6fb25949a4961b35fbdcac81c9f87ba8e4f7103984ca6d8fbd3d3aa7b13a9ef1bcdfbe4f6d4e6cc48e5cddcb057027f98ffad2a90a7d4fae9427be8e77fb6c30ac38cae71a36b28fb47045fda28a027b1301fa5071a262c5d1e0a695d3244218a88c7182590698b690c42a3cae97ece7b7266aca88dd8fa8f56ef08c28d806e7398691c31f292caf1443508c494007f5de45a95643534f3f0fdd20790f0aff8d9bb432cce36bc857884a28d2dfca0667a2d7a0b0255fe68a2f9cbc28cacfa489fad9d3101a5a6bac3c39fab9a8223bf5de787fc3d9849626cc50466355df2da389c5ed8301e24d2fb6ce3e8081d32340739326b706466897cd40265cbc347121b6e12e04c218420ab7ee760e9eb6b43fb4e4c530\nTAG: a2d58dfc6f1a7aabcc28cdcda713735a\n\nKEY: 5dacb5173b30a28c99e00eb11181879c\nNONCE: bf1fb59bee4e3964b300ce57\nIN: b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14acd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae9061ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd42bdf685c73f9c\nAD: 31abdf1d28419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a651\nCT: 173cedc6203b5de9f4950c055399328756c886ba5f8eb4d3dc4cfb5e7681aec1c9ae238d0dbff2af21fdcfc244d20fc310ab0f53894d0f9d7204de4c3fe8d366b3fe075d7c7bddc79a256d54125d493426f56c0f56b0688921a0f9c6128ea6ccb405e7551750780d03f1e4c5d9ed1daa253a35178e85f5214684ed17614dfa8cbbc17c3620b080531dcf8434b7b38d1d45b45759f2f0e1c694d39e9387479aed05dfdada1672b8fb01935ea13a057884341ea164f1e59f8069aa5578845ce60775e4a6166b99eae120212cfaa30de04ed140759dd071c15a3536421b0e0dde31e6cb7d8e7e71aef462db4564803d1f8301f0cd5befffc1c0afd74ee5957d76c0a6bf85e2e57711c0ecde9427cbae0c214a09b69fe55ec49857df822ceee98d3d2cc2194b48fff88d5c4209b8a5aaedaf5c289884f442db3e5a8e441a4da134c3453665e8309b61dfb007cd48fe7f2c1bc612853917a06370cfbf3cff5c6c4d745f134cd5952986ab100dc17436cef8daf917096adb9a0d49889b75cf0306d31b6d6902817e747918ff92f479bee78bf2070a0011aab7c0e734395430604e6c8c2a73c17c4bf10a1146ebde04b04bb12fc6a189faf983e6cab5553ffb92f34a89e8166ecd024d89115e6b77395eec93d62aa3daa2f5b6db3723d25ac747f0833ba89350b23c2f874181a6e64fd3ecf4c07396c8d90be0cc78139d20891eb729e5f22f99d07758fdc00e76e9b082cb456c1e5a7b7704153e16b564f0bddd142d47b51e63a3c540dff5f32eeb786c48b3256b9d655f3098e649af178dcca88413ba50f0f332001d4d686f566250fcec1eaa4b3615604c9f3e8fb1704018d609904af5d2558117f43ffa74171722974053fd468e02f047703224cad8f7eeca77f8aabf9adcdb2e3e6df4f805b2a900591977b7180a029c8b359fe41b31cdce8a748f6967872355688e932bc64a43a12222001bbb4d83fab619db8f933e\nTAG: 5609b0874958433df52176247da18dac\n\nKEY: 87b8cd45737c8446b21301be1d5d02ca\nNONCE: 6af5432cffee125756ae7bbe\nIN: 2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f972148e9a0bc6c897d4fd\nAD: c82bf439bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032", + "a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3\nCT: cfc53c8980c557908f7d3a2c15e7f65da940cd319594b7d8baed9ad7edba0a46987775b004b5fd0c10306677eefeb8105cf124d0c64a2dac05364138fa2c4e49dfccb963a89956f97bb0340a14573e559d9f937b51fda46206f7ec3361ce566ac2ccb418290e070ff2655cbe89e762466c1559fba756c62de1c963afa1ad18ea47a1cf3d021f46bae6c060b19aaebabc900229086dc26fae9fc9da70af5af3acb02b6d5a570e95ba0d2f789fa077fe06553670ddd0c4e8965a3f5532e93e7fb0ab7e0b9f90cc9b483f1fb79ffa67d0cf53596eac25679ab4f8ea75b93f3bd84d8b8270d6d5ae62a5fe8995e9b0384365ad813edbe7fd9743665338cde61f8d0bf82481b9da29f6682795e7178fc79e676c8e3ff641ae25c667f92c849a642abe974d97718f0aca305b57ce7974172477e90e16d804c450b332339c61c327d78abccdba272b85f4da54154f59ce8dd5bd89e38a515bbca07d1526eac34437c66496f05e8582ce654ced3ee07d4e770da1799aa9b6fd42402a47c6d5e0c61592f11e798cfa3bfc20dd601e86e05fe6ed45a475a1b54261f368877e1207029f50b6d54e19c132c5732ec34552c2c559c135ebbebc7be00233126d5e0dc5e20b7bb37f6b25df2ae5ff44ab390ddfa91435c6d8ec09c4916ce8dd3e10509094cb4fab2ee9f67c3eb351ef221f3e67b7ff3dd7292ce01eab7e298343de449a2d4a0a168860bedfa0754717bf6fa0f5e37930db0e70c66976d34c0afd3ed623df2a10b9c02b2e9220534688e640de5d53f3707c2c9ea3de7d339e5530504b3a821cd3097784f325ababae463e9e1b34ab0830d5411c9e04bd48a321be1f8b973fbbc6dc03dc7ca2c31b3d9a800ec9d425881468dd9d8ca7f67ba2ed500d1674118d42ccaa6bb18f0a2c4e5ead86234255d850f58f9ee7ef7f70e2eacba6a053ec2e78c27a45faeb4c90e28687ce0d7cd7f8146a6ce8ab3887408e85563889373b606cd5c968437bddb632d69e8e8fdb\nTAG: dce7df76d7d0c0be7f560dcb5a4a00cb\n\nKEY: ad3ff84d1442224006550f6006be543f\nNONCE: 7712c5edceaaeb3360ac7ae2\nIN: e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf836acfa3e2adfcb7f880\nAD: c53c1a8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d4\nCT: f59b5a5d01cf45a8d91c8c53b3d8feb5440b6cb9537d9feb0da69c33827d1a5542e1d2db34f25c399714324b7d31476022778a82a10668a281bcf6e5ef368a2c525a7bc59f46fb9e747424741e8894f86fc157dd748370212f848d23b13dd658c1e2ac1bf99abdf93b53a35b5bcd89cc4406953376187af45ab811e99db9ac2a367f8a55b0fb4acac9a9bcbc1858061860230508de9a777bbfb0f74b2c69a79dc332a4f03d156596576792f43dac2099b1d4af11fa6088a086a25364f62c24969a515e74f29661cc4764842a47cbeda7ff9ef515c7510c16566536273d62109397626a3c2b601bf272e31462ada51a01a69e6fe174082966fc25b6b8b034add7d394717f08df992771696bd51c25c8feb47ce637e23e89feac9679dc753eae62c0ffe7b62d9855ec470904df6bf7b6fb246cd6ca77bf2848f1074f146652461307c5d51b46977ac39c42ac5857b64f9b347a45062500de41a19f2bb03fdb241b309a5b685f408aa4e38e60c667fd4bad4fc3ab9d8b4f2a8735b50d2fb7d7177d2ef9e5c783ccdbbc8e923832117d3ea8cabf40891e8c912d703f37649096ed0e41e0e53cdb19da6467bb1ace8064c7862b6c4829959f7a0780860a598f3c725f3f956259ffd20e9088dcc639a0c947d85a51f6c77e911355ba77fe43e49a1137fccf2d951d4083c7232d095f2e2d003bce91ef9cc9aaeeb046a35bf1b548c78719c553e6ebac55a77509a3f02d71a9fb84ee16a8fdc6b8b1c917f800e053e655860ab17c0254327cfc3dcc9267e2b78dc2082e54895faea0349d9df3eab4b0bd62f5d6114903d8851aa3cc9068f6b03d7924dd6c4fcc08237f05551d528c01f33720c53867cdd375fec867f71fb3b4688eb18ac3647baaa94d2a72391f47e819b4f41e98904322d1b57d4a485fe9c966d4e0967eb415feff49d1baa38ed2505dee1b76bf1fad013918bc282761f9431b1ea4b3ae826470ef72399c86643a308043a2206df7eb354671846962693183df96ba170898fbf304b0ed34b1fd\nTAG: 90f99dbe53f5a8531b2a0e8dca2b7492\n\nKEY: 39ef8200a13e35000b40e9b0b392c982\nNONCE: a4377557abca18c1f3bf774f\nIN: 4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17cb28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea3679bb9a78d035bd8ea9e8\nAD: ad709f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176\nCT: c1545634e7b0db1afb8a166c9f0d81a561841a583d04fec4f1994c7764582f7b11f832ec2de523e4f6ea3a7c1608e1d1a037b7975bea51524bc8f001ea34a2387f7510967cd57", + "be0436529c08144c232ba1f532863255a55b2ea6f860b7db366ec8ea366e62187837ee8aa47cd9a8d687fafc31680c4af60493da7adb7ccb8f751ce6a6e30ec1f78bd169571fcc0f208d3966cd90660b8f7c2969bcaa8368172cff0d0fd27d732d9f7869d764efb36e55ffb96a1f3d8f1e6e5916e3e97e1f5a12f8dd965466a26274804f19dcbc7ec872cf662854501f37ef5fe348c543511feb61dfd96c5d429c83c7ed70a1d5beafc241c697a564897c9fa9819fe91dce3234d7632ffe73dd1f7c3cf0bf6d170334d2c4104a6ff5dd92038ad91e69f2685ccc380a9fdbdfe7f9f47c3a05ed97be25e299b8e71905f71c68b492be8545433c99b64f2d53a9239dde92359cfadb7fed301b8d8162baea533be9c9ea11964ca6f34e4d81b968546988afba059fa4b4e6d9e436137a9d991cfb867949c1bf87b1d61a5429d4bf549e66ca88b309cc65963baccc5449361dcab294d8c817717f848b942dd11fb1a8015a89e9bed4cdf51b4ff3ace0ab474fcfe16ba2da81b59a5dd7958913c92b4f6f067d2d350111c23c477138ebb40a99e0e55e6f609d74565c77bf8460e6360f4bb54220176baffdc96e4c37529ca3a38b3ef959d3ddb3b2759141032e54aaa8e6b2bdc928f01974f1311fdb15ace49d7d5a026e77fcdb5e9d7442f7bfd04584078804fb3aff740af89401771047af2483153b4c79923980cbc5695ebcfebc32ddc522f9da5b1220961555aeeaa2d578538691ef8b9f12b5833cc4f3b18d7c0d8b068e294c82efb95badbf590a3b4094c38f334d7ed32934f7012b87ec4a49bc0c2b7fb98365f22962d1e45d99e190655ce4213275b1e422976bbe36104027b96ce3e52ff931548e10e006c75747c59e3f7136db301eada16585ef15f4589180b368babe64b114e36686282d195d622e89f04d56f17c718d72bc6c577796a639e634a97e7877258\nTAG: 9563db087214b10c64e7cbbb9dd21a83\n\nKEY: abbe5e520c0ee79153c976d71e5c6dd5\nNONCE: 76f4857ba2d63e04d6b69a2d\nIN: 5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb714e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a78843256913cad2727f9dbc3a8bd51daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c7550220b0b5f3c6fa8db73\nAD: 16337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2\nCT: 76e3480cee9d48b31d5b1e9a01e79e713cfeb73d742f1fc1e8f99c8e0cd82e267c45f4270077e86996a7e5440a781861dbfdb9759a6ce3991fbe6006d0de04658423f54154c8e5945dad96addb8bee044308cdf062ef21fcab25eb9a91f100945f347c865211a1087c01f245448322e77b826a22287df3434af7bee91d7a278fa59689656f7d93270898fc68594a4bea223d365aae03f0dd18a2e525f0c142b28776bd9f66fa2c046e57394488d5526fda62704e90f50e9752bf9d7652b010f8407de91eeb3068b830d0cc9294bee9629161df4cc7a1a216e55dae077864999ae72020346e813ca8fcdf99e417f26b82653908d0d6eb50ec65814f61b1825cc29c4679a9097e9afe294775e498489ca6839096f7bf0b60d3ebd016d83076184b272db1775f5eb3205015fd45fabf0bba9a990518c8d6d0c478221768fd83776253dc843eea8bfb66fbd2b9977632ca0aac7efc9528115fe4394f460d91c1b74fceed2952c6abc46b61fed85eb7414410731106e1a7be792eeac86fd4bf2b1ff2e496417fd8c0c2865e80837b2b73a690a6d9b7fea83687adb3a004a0d9fc9791c572d916a1b72f3ff5485f7d24e08c65a86079dc2bea698c43a3b2f2e5a8f335da4376aeae4d7fcb509bedbfa0e8fd25a711af45225d764534edcee4bca8e1470cc7d187b0bd9c26866baf8169289653aeae9b36277ca22c2a0ce3f69b3a40dd55e745b0b7467c2ef6a8a10151297eac1365ee475239d8f254806c8d92354757df8cb12d3dcfba83e05c303bc157c7be49da40ee072774ea7e4ac7044768418e64d965eb76d14bbd73be18d14701cdb6f8ee32cc1fef468047ef0ac649fb77843f0bb751f543339922bf34eeddb8140220e6b45ef1cd180697c651a352d05c77b705436f61ec9d35f185c5ce83b210c4a4336483f49ecd538dcc42a22b4f77ecdbb8cc36b8a499ed5c39de1fb6e03b0769639670fb2517c57f183eaf56148e1625adea1efb9b888e8fc3d83ba05c35f8509bd4e16285911462d77d9b270ae278cb902f6ff7970211cd53f1c310cd14a1787009cfd041c29933edb6e672d1d5\nTAG: 8954449b3f6a09e92ef2e33cb57c695d\n\nKEY: 100c6c8d1e88b842aed09cd16a5d78d4\nNONCE: e2d7712e40234292dd1aa27e\nIN: cbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c\nAD: 0e2825fa3a69b798030cadfb168a1f88dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b073571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0\nCT: 4b7337e4cacd72909775b7b8b77e3a73dca810b4642310f33a58f5548f4876d20b828a303cd85241581372f94d2582f79030e13ce68835836fe194bf8e68c22a39feb10825b80b4e2c69ce430b9b56536334616ea3f4610ed7a8136102fc22e634d5fae28cf518630c5f159ec3bda66fab0896f789c7431c9f6033c52e7082b4b65caf82df07266b39a4f0b93867f0e94e3f5065fa626b4ae90dc70cb3cb5d9225bebdf7de553d364efec3eed41c15481d2ab7f8453af13ee769c6a0af2c0a04b61f74302211e1d201ba91eb73ab2a199c4929b903e91172e4c7256d6b13890", + "3a4707f2840952c07f9ed10597d023efabc587d2753b28cb809d678b8306ab50bce2f80b9c5758e8d3bb3be07e7645ee858288eac7072272390dbd2915742ebe44de3e56caa0a9c7ef8d42df94173657a4bcbd183fc3a8ad1764606a8bc98793e240fc5e18f3f86cd082dc4eb11576fd29097ee7109d444aac300dbc930bd1d6d2b7f3c69cc02ccc54a86a627603f3e1f11859efef34bf5d11b16d11f9e5b6e985bbfd3e4e3bdb94a48cc0af7eb6c212c3fd621ea6203a5c2192fe1c25ddafa33ea774da1445191f5bb266683cd150cecbe6e820ce3c8a210bdfe407d203a8d9445c216adf892a0999a026bd8d958589f3a6aefcb5ddacca2285f2dc20ea31f43d6759ed5f46c988587f93d6b90d335bb51c76a3fea6f7513385cb3c1b8087e88dde0cc6ce55e7464e6b0b32e777a4e34416c4ecbe1610658ec0a05550d1dd5cb51b15fc3365f32b948dc28342b2b7ffefe63f4842399d6df28b966510e4aaaf5b5f7e4c470ff065fd30d56d085429f89093a291fd7e516b8e962b0fd2faccb0be3e4c62dcb7e75fa5514f79a07a8f4044cb253074b8085bb925dc8302ad9f7fd0d41e960a55f25f31f4bebe6a04775906b59f124a64f5d55caa55e1b858d1383ac7e4b39fb959cfd61acbf0d64ec6733d15e96137821417829c999ad93fa735f543fc73a94d942384aae4e330cca4a7d694627684267d3a6d74d6c140f84a3e10cf58158ccb3ee9c7ad700b08bdc46698707957e523a81f9e683527bd16ebea1\nTAG: 9ee21a6ce2424d9ab143ceb318e16819\n\nKEY: a646ee4b0e0dd43479849864311c3f74\nNONCE: 3f2a6cf9d0dad34111493f0e\nIN: 55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a566e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce9\nAD: 7d000237e72e6de6176fec75f5baa6d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c1\nCT: 796320131f438a93c019b4caa40e9f183ab467d30ac181aa5f2a0e07295f1d07946c4f2994a3ed2ad8522d5ef3fcdaf6d58e1eb03f479859b262ca1cb6e950c24b70a5da75b13055022602f39370a48337464ee1100fa9f6a45bbf793226c358fd91ae1b71eefbece73420bfc804a8d6499f044cf250a9c680445aa54639308c10631644ec3367cef458ab24d0dbcea8168563c062af8f282eed1ac778670400c03d30dc4e1a8f3172555ef633adc99b197f16bcdea6c24b2634fc189b8dcd3a52b56b2aa5099c10a830aff238d1bffba89603352946048fb8e9ee72ce2c13e4fb717d83a31ebb67d99049ed49e58d36513fc399f0e05e3693857e00df98707c66c67b87a2a6aa63fa68fc829cc3813f831f06933ed182e103bff8fdb16a6ab5b9ea8f390a2248c9923756f3536f0e699e3af05e7a3483169cb19fbed3f86335a2fc071af6ddcda9c702a584493294d37bfbf1c2d35a3db8b4b905a3f08dc0e691e6d5264446978fa6d85d37bfa0f7c57630afb61e9c67bc130fbadff95cf8d25fdb00e10f4ac451f6780fb763eb5fe9c34abbdfa44e72346a4ba258180c134e9fc5e336e0aed9a0bc7ec3dc22fd0a38b245a512ab7cf0aa888e2b36f02ce8952a0eb69dc28afd70fe9f1bd20b12586d839cd86ea95cb03c8cebb0af0a6d8ca82d6fe853e5664d30db557e28faa695a903e12efb6b6bcaa9c30584121a662ff4a1a6850e9b005dcd194bfc418df2a8919749d8a82fc33ee741ba855caa9f60402bcb9896549ae11131730d7a7bd1011633f759b302cfd8a51afcb29ddd9600927867776e961d8c2a7ce403e1723d11fa92d587c9ceff9f4920bb4ec52ada70ff98d7c1d4b7f84cefba39031f757a86d78c04433b7085a9cbd44ee1cc8c4dc2dec2a938871bf40b2ed113e4234dc5331d536331c5f8552ee39f288028d8d7036d9acf9ff96e385a099a44f51e46cb73a4e9aad3e5b40573018a2023d683f4ee886236d9b3a50edeb69549462a4a496845d08f01e1de332bb2e3d5ab3e9a2adad675fab9eab0205462a097f4ca75bf59363ffa1e2f9dbd2831fa3ccf8b540de72eb613a549129e8d40b8f672b200420afdfb\nTAG: 7d11d1e35aa29774756505f036a0c857\n\nKEY: 9c73a26fa433bd4437c1018263e7db4b\nNONCE: 580a120d1d29775d9d5ced67\nIN: 10ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e0746027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de\nAD: 874a859c5637b754a4e7c1ddc3f34dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f\nCT: 26e09e3c1c694166c798b8eb3f290e8709de7cacafadef90be45e751ec6f0477f6f72e19bc0343258babd08efb5ff4f82a3aa8e8b50f93c4bed2d1c0bbc07443606487a54f4eae3dd09b3b02232276c8de51b05ac31c64bc960c8d14b953db9e84c05fa9d2c3a286413fadb00f1812ff0a9f49b91de3660fa87e8aa73f11e0bbbecb8ca9be494919631431e29bcadf6883af673149c038a820549883e5d63ec5ddbb5d49817643f29c9665a3b416f67d28c4dbfcfce80132b3e120816c156947a003e36dddf1ac9652f196944c176d6369c25dd136c7880b20e13611dfe52971eafa0055f25cb8969ec688078cc8e7c2395ec27d7d38f0db653b6ab4c987dc9ba33d5cf5d", + "1c05f7fbe19e639ae6baf87792bbd0adb236e4dbf302e93f26ccb2d7a47c8bcacb8f6ca4ed5302a2f461cbb0312d3bff43149a70b8271572797b52bf30cf5ae808b225829e4638fd9f2368021c6205b505406145632a9842ee338a796c435608ad5a92361a19d52b7f8b348d7fa16b3d7775c58e94069aa01bf470338dc28411563e610563ee8a8fc01fff824f63500599a7490f74a59e3ee4612b76871830066c4e3eafcd448822b4c08acf4935f59942bc3cc83e497ee8ad641bf329f6f0d9cf18d40794fe7146987dd6e29c3c862f5252a8767d966e0141b6cf0d166f18b658d8343b698d0a91f5fdba3ac2c32ac24935968959b67f06b985605bff2fc4afc2fb86d6b4e70bb606bc8009f9ab59fe6f6720fdef5f530eede5ee0cc48071fb9d5eb0ac468c820d161a6d09f7d319e3c0da450a9bc6a6bcd37c1f59b3817fc85dbe85ce050d72758f3e01b3e0fe62dd55447b479fb7a09b29122bdeb315589b568ff9a20850b0bfd20f220c05222d784dab107691974e426c83aa12dfdb5693f6c05c423a7c88b72104c0aba00939f9b7d0f92920f8b166512f7ca4d437082011b38fcc3596a125363eb5872722eca03132c8a141227fdf679b8f323ebfe227dded8a2871c1945e0bcfdd8b6c631e293858fa44ea16499144e72797cf82ec32c966c60de4aa921f3b754075a4956c00540cb5800dc97fd0de66936458022ba2498dbee43a99cd8e7c6ca2aadd1f63209d2a24c84a27c13b9d5dff7cd27\nTAG: 68ef1df2583bc3743bd612442589dc24\n\nKEY: 6269b478e1d79f3727831086620e79dd\nNONCE: 357fea1c84ec4de0bf7d6afa\nIN: 2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496baf4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a98e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c3\nAD: 0377ed6ab683ea82545de480b5f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d0340473\nCT: 096e0130b0e57de1c25d51c748ac53ab8eb5f834ca5efcbfb9f9f950393a6bdc9475bc98a224ea22fefa19fb1d9dd5cb06f0bbcc266c78f169dcde51a7864c5a5c5996175b511dd11c6faee4f7afce3c499bea2188dd443c654486ac5a1b4d113e38cc5c2bd730c3ed87696caa6feef8f466a3323679fde56da63048433d78321388125a9a59d8728c40485299fb0a8012dccecfeabbb7a0343d03fcd770c1b5ff13116ba845b90c715403b5b7588094dd554cdcc1a166ed872c75a7719c83e71b9703ee90e4909e18822d5d2e64a851bdc30b2915371903d6748b89af3da42d041d4752fa1b1947ee12c5106404bb6a7a3d47629841da3ca1652666fe15b9ac2ebeba651baed43e6991139f90cd7ad9abbdc89222086da0b9ca7f4e7838fdea61fb815c534a878d7cccae9fc07aba48ba6fa7bd3a3b448e99267eaff2834a2db3084f28685052d2973eb7c74bb319a232eb0e1bef7d2827081310aaf1368656f7c64b1ab1ef3d4197b350154e18595aba352dfcbb7c0187d8ce67a78cdef6af01b3cc7f0f76d8a9de741c87823f1e6e734dc60cae88078e233e4e8a525148a56572d67ddfbbeb9409ac01076b84d9998e2d10ed62e2288f440f5b54fd7a5a1812bca2ffb9319e56b674ea4804ba0f6d92d7aa7a5e1a9f403c3c6fa8dca86ca4149f2d0348150395ffdd382698d0efb7421fe0ef930b5522ffbf122149a5ccb8bb6c3bcaaf935d839b9b820e0f199043105cebb966a6a4e588a99d20d89c61166c257cd6bfa545f0af914416f8fdd53cffc1d99b27b6c3160205c8b71af69cb398b5cf8f72154f612ee0778fca187a574babfcb6a9dd61624f8d6ae247b7c15be83d6cedad267f847a63f58e4ed7136de31126ba114e5bb94e932e3a10be4da821f091ac27b0c3c73d7fa6215bc5b85bf8227f10dc99706644f11c3a0d5ae282477513304c2cbdc1b5dfc6d6314da4b20eaa43a784fb8435c0be578c409291866073c31bb6a210b587ac009ccfc9fcd342e07854fb664b6cab7506d5248f8377314e5fd6dd17ed871ceb5336a5ff7137aa45d211b06a4cb0170ed25838ba8fc1041f516a127c245ccfbed4ccbbff11c0bd557551f86dea82db1f01ab97b9b19a6cf94e405834161421ef056d96f3482b2bda2e\nTAG: 143dbbcbbcb66c7ef3ac9e730360669d\n\nKEY: 58cdc99ac30e78d6238b5478982a2b4c\nNONCE: e58537a34e5ebc37ea72f321\nIN: f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d4351c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac257071132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132\nAD: 7840ceed28a572c5186f25462a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c\nCT: 9662e1becc3ba86c8edcfb3ee94d3ccf2cd37f7aa1988bd4cb374cb5f3cf4373cbda8c71832fcced0531c35d035fe6de0f0086740a62b07e81b3a0f98fd89f22243a4e2e81263c3d4846a3e54977ce7617702e43adf44783e279b174591fd1fb231f2d5e460a866568c867c8e762716959fdada879c77b7aa613ff15dda", + "e4727cb3a2abf192fb74cd6b1eb5b632953422cae683ec87d6eb69a57c2021232181e8f74883355447643d9fdbf23b00f7ce602bcb1ac3144387610e045049c7cb1bf1babfc18b21ee05da3173bf2a0d8833698e7b3ba5e72996f6dc43db0228c81ce3f1c644090b922bfd72dfc81b60a8378cecd2ce14b9a53a16867476e08bb99f0708477e1c6af6d262f543ba4b3cd5f3309940fb31691b9e50ed2f3159afbe8f3c95a8447af98a76ddf5a531939232273c669231091f15e8f819183d8d13624bbfd6cfb9bf781bc74a9b4ad631de4694e8db879e38508a3b3e26158ae3a897ef6c9ecdc5f64d870964f1d0bd924f2e919e4a3c7ff5beabf589ca4be4093b2a95eddca2f7e09a02d639ba872060d7db147476cc83153f7a5227a1ef58f08dcdf9f821110512424c7e84d62931a73010576f898974cf24f9361d1abb0ea3e84c79925c87544cb11140481fad00dd75581526c0b9d49d74a05398e58d8e94c6c86976dfba9d00440c2bc61aa2de1cb9569bb9c4226c05cf31ecbd4854c2ccc99c1ed9f31a270c0ac57bd43e6c5194f8b2efe49d34095baab0bfe8c3c372b9bb77b974deafa462b08f9e05e027c3ad53a24206eeb5bd4973cad46c0a8157c47ed9ab9d6b0abc571223d4e3c34675f89dc0374da151e2dd6e4dda27479499910a7836a4b638dd32ef7ab1c5712db101aea462c6ea2447f39d38efbf64794c466165723063eec9566f874cff9d6d2e96e51f5c6e0f7349bf4e667e4b3bde503a412a165c8d1381d7024772a273911ddc4186a7c1e9818519d9935cb22452468938fa0321c1bdad488dfa0601680e06404b0533ef7a8bdd0c00fea49fda059f2deb7504fcbf980e13d6c67b0bc3960ede0fde107fc571304a87fb19ceab00ec6cf4e0087b5365e8d43cb08c256de2300b565474076826f381182e6d2e0e9d77be0bcf58ca80f4faa685435604637cd6fc65366dc46d92ca0fb569a5a9b6440e089cd1d8522b20a42\nTAG: 6def2aab9f94f8ceed77295e25f81309\n\nKEY: 283d86e8371cf7b34cc9988005575c8e\nNONCE: 98ad34184dac039f04f84e5e\nIN: 8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d896ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177afcd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa8434\nAD: 73cea023d2c6afdb625b6411ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e\nCT: e8df4f21bb8d95211c75b194c30b1f3816715a063b202f8db645da8b826fb45e9af541ca9cbdc7c383d4b5179707f6665f8b2a74c5026243c3c5d9c32e6d309892323440ac0d945875c2665a60be211981d5dcf46a211a4e7b58e0062dc43b87ad3a9c52751f649c2fec404b9f858f4cb3ac9b534c850a8994f26136eb70e90ac44f623aa3bd362069d32a85c65292455946df893376868cfe3b06ef638e56c7defb9b4f0a162bdc8aed6a023836ecc08ed826ae9b818f3db6501ebbf3035159b6341ae703512a8fb8fc3ac0140c3ccfb1ced1ea4b7ff545ef63f76010acd708778d0424b770ffd36f2ddb6009ce5dcc498a9bb8eaec3fbbefc39da3da2f7f07470d051837398160c1c85ac695a519358feb3af9274fd3f6b1d936eb400e0bc5ffcf44ee9c78c730e4f449a008dcc912b6f9fd5d17f5d6dac025be318d5aae77b8858c1effcade42dd360e13b13f35baa64d37535a0ec8cd3a73d0c175be0246da3722db1b64f750c51d6e8da7db1ba8891fb688294124c989cf7d14108ab90a968f0729b6d7c6cc777e470e946b0fdc7b6dabfc6dd7be52b51ba1849cfce2ef2ca70c4a51523a1b0410e8a1a8e1cbfe7f1eb3fe456da81b4de6fb15ae13a39fb5b1c2b4aa9857543c3fb240965578f6b27ab7c69f74af7ec068e8c9238dd4848bf2345ab153730dfa9d1f57060e3e5f88a351f83cc78bab6149bc093ce2b29c706cbf85d35ad1c036d2103c89f1401f4f383d9345759a7be3f72da2eeab56564d98e2514d99192d82ba37ff5ef49a8770712c41e74c08227e3a2f9b516904ecc23c8368e3b46133094121209d57be76dbfee3ea7dc3240bbf1bace4369b09ed97a9080a3dfd93887152d1c03aa267ddbd97568b0538879c8970a62a4cb016e7e80b47bb21645d6a57f9ddb080551a9ca9cdd4fd0cc575bdeaa013150a8a04d05f3ccd19ab0979c9fda569e362f6bdd4b67268a88d88d0fcb9d68c47a0df0bb64048baa0554cf2b0cb4c27bfc0ce8d4a35113aa30ba03f88c73695a5d6c3495b5a15ba407ad75bab597a46170594beb34b7966d6bc7dc4ec2611cc15dd60c475c7d7b1f0922931d00dc93bce697dd4a4f72066d64b1aba029129d3a26c5ed44d19df383802733ca71de86e0a2f8d0ab04307d1a8da7c6f3dbe509fe29935bfc2c09712cd35c229e495ab3b80a447a168d044d163ae\nTAG: 05b8694f3ab53f8a0763d0c0a1c5a64a\n\nKEY: 6611562d15bc2b910f4edcc981c457c0\nNONCE: c20bd2710668b59242f7547d\nIN: 2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e334b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72fa399\nAD: 26a47e0b75a771783631e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf", + "81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e4\nCT: 57d4e97b3ec3681ea9dd4fc9ad0aac302b477f081ea56e613c53b9cb9cc467a2042657905b7a5b308bbff6803d33c1e4671d126ecbbcf6739842ec4d552d377dcd25b9089d96d284118ebafd0cf8fc097c35124d900cd69a2fc1f97fe3cb69c6648aa069eec68893ef2d4d8820ffae86677fcaefc50b64c4b53c9f591a0f6a3320afc569b6eb7637e5ca07c2aabc26f85521837f0e3a6435ef5cf9d2ccf4edecc5e0984601f88023f6199456e965457e638c1d6ea87f5041d10c187eaf4dbcd0cbd6e6ecd6043629819af18635caaefe6b0535d8fbacb59a00f4c0bfa8711d32131003a051eabc95c0e7119e0ba819022cd01590edcfaa7543dfd2809768b1e03ba070db5f1cf726d425a6f623d83c454c78118a6dc32ee47528979f6d478a58ee75bedc95e9e74fcbb96fae77353e6f9c8be5727250748627d3187f9408eb131efd62a90a19bb2b19b3b3a478518e49d98609116bdb9b7de7777c8f0bbfdb2d1a9c4788d81fcb548ed51d1be85a603c1744792163bd18aac3d7f20e97e32f806e7a049d3f51384e324055bfd57c5116e48007077e295e0f3d3edbc6f4be1b08d42533327ae6c7464cc45ed184912c1624caec44a0958fbdab3a2a9eb13a6e6e4ac98e40979f4ae4fd7a8560b623bfcc326435df878d643f394d177013f737fbd4971f734876d515a4f2c71fee5a36a632c93095674310a60809240fe03d7c1584a446d536fb6316c9354bd007a4de1b12e155ea6216790ab5694268081f0df280f6402373a50e2d2da82d7399ab88fc9020109e93716fd3b7d83b14bac73e37a60ea805aabc557774c26c3ff906d5946514e222747fe6962500f90765702fa16d7490d9255d74dcc2c097dfac75e9f7f8c090f4d8e8cdcf4449bf5f7d45988f363e4751ffc24cca95d120714c2db59277837ea38e3b385d7d3811bc4fb755e6cd29919654bf3dea7bbe3375bef1a20cc55170ff514522886fa4716d6f99bfbe5801d1f93ce5bf82fee322e54ae1a2342659dbbdea49ff1b20274ce3dd2220945e5142f3152b4c9fc88dec89762b773ea1c87643ebf52b6f6f5f26bc1b8fbd459ef011033f3611646b50ed0b43bcfe2716dc780b8b5757d199e26657aa870fb149bd3f44db61f07a2692ab06ad8e30d40e8f6eaf4daf6a637c38a9e415b73b0bec06eba1a7e5b34d141244eaac717339b6ab052286bfc083ddbfd4ed0a70942bdf73f81b08ac\nTAG: a7bf4e198482bf1ddb65779e97c2fd2e\n\nKEY: 8a7302e5e5e5a3f660bd83aedbf1e2a8\nNONCE: 8ca05db202082d8a59d11b14\nIN: f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e2eebc2\nAD: 343a402e3efdf91f7d63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df466423\nCT: 18e79588195948d25b9beea1b2d1f990e7b87368d4af8c88e6f928f375d98bff2ce973c1e5ac525e1f08fe6e7c29a976181cb5a2a0cf40e3bb24881bcc5391f9c129daeb6c85c5cd8bc1f47f9f92bd25f4b5fb474f7c0b49828dbace32f5f9bfd968cf3871cc4072252f5b600d88a857b4c86c85ace62e56aade90109a118e9813e984dd3027fa4ff6162421e3abd22eb6246c1f9328d85ea7004ea3259fa355031c660c0880893705aa7d672996107fd46c7e6f7ea2d455fd8183a40d41ccb0d50ba627b483f8ec6fc3713010a73dd52053e033a26e5a0daf7bfe3fce8858e63e18ef1201644dc0cea8e723a24e7558ee33e904a0489c3daceac911d2aa83a63f893aa6516f343aec8a9e46c869b38f10d4ba7c4875ad3b092be565669ccdf8370ffaf7c1efddc33f67e5751668f3d75b619369c863c7d3f24b052a46af2fe66a9dea52e2c36dcdc7ed8093d0244179ab7af3c73942e63827e4b301cbc0bc2c1bec14d690e8af1f5c72270f71693d0fd9c065d9267be22d647728d39737761fc46b0a01f98b5a304325ea8967f6983dcfdf9ae87c224fc71bd9a1aec353b28208786124269dd56519e4b0cb058975ebc9803e35cf6d38824b93c78db05f2fd2797af1acbef3c2a74737e15f9d2c8f3b8e6e964043ef53f4ae5a58825fcfb1b525e38ba542836090c5a663a370e9762c89893028572b08fb0005529d44936763486307267e4095a05ea8895de7c20965974b20784c57a175dc71ea738121b24e96e3ff1e7d583894324e17207bd0a72b0baa89987b6884c6133bb3320c35ea3033dbb7051f89000977f055f3a7f1c38ddd0808ce5eccf615532f1fa4fcedf772bc7423209b3eb98de47371b382c72fd8aae5005f42a31126e14317703083b5f83dbe9d61778e221da54899e81f936a9973f0f5cc6aad85aa831071959b307278d085fc830cc6085f5701879aef6736df39a6555fe3546779284f618860924fb02567bda44dc97a4f1277e40171218fd1569ddaf68c4f58697232abcdfa6cde9bf44dc39b0a3e000dc89c7cf8298a5576a57c7047f2103a1dc31ce8267d879d15c41f23addf662f8fa49661669edc1ec06ab426591b406def208ca2854210e9647d9ea5d4bca84c5a687e9f3238fbd7288774f72d947e85ee26094ddbeaca7e135379f678a13aa866a14fd4e9d63de6d33f01e9a668bc3e4a238b9920df22db04ebd5447857422dbc16200144fd306062f605bf9138f817\nTAG: 0b8c9441aae6ac2cea3cbb71a0ac7683\n\nKEY: 44f4f7c9ef9a5fae05c10b2e7ac41afd\nNONCE: 55e84c213e1d5f58f4c7aae4\nIN: f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f682257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f", + "6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f32487920261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a5168b8e6\nAD: c75f25ac1087b315ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0db\nCT: 4e009626a3c4e6ee3a4b55ba06416193a63584551b8d4ed1e88f2b83f549129f329780515703fd0ef24a1039ade05d2dc4a25eb47a3e134579bfd6087b5c0feb9aa9d82e89706658eb54170c992411875bbe176dd0d25c06c2e58cee97e5444a1328b927a3616c32bae60cd8a28a58c35f7aeafc891ae5285759b24fa4b2cb59aa4263a864b89f14316181a5b8e654408eaf85f87b71ac0d14fa023a12cf4c18bbbbed4c0dcd5a93669183a56e3947b9cb72019cdc810af9df3ea68ce836f8a2a80074de9e8e444ac0e7982e0c029926c3ae96fa84711ee5c42ac6528648664deed439d7d7de9c6b207d9ad0f434c59f69690ee14b21c9e1827fd873d51cd2e377fac049d8d59219945de18e262f389709a291fcbcc491b2146ee372882efc0b48fb47c767bf0709cd5450c79948c2f35d1ac0c92ecdf9c338c1d80e5a7e7c9a2cabc78edc331fab75feaeb2e91be109bad562f2d7262be42fcb5bdad42736b9c94a1d5bb2f2d0a3e347b565ff59325a67bf074874639270ee8ea7260bbb7ffb018b88cb61c0f4b476111a6f317dfd7d0f8b9347227b9a260474a448abe10ca0a9615b2eb1708d07b3157f0cb641768ef759512b9d52c86b49925720335ab843db61b9a020cf95afadfd48bc739966d7b13148cd1bd426914700486568dfc1942c6bfcaec6eb4a47ff1531f4a3efdc57ef5c6945f009851925acc31551afad8dbde7d349e43101043af62aafaeb5cf67b6642c9c928a6feb55390a49e019af97b137375245794d794d72a2657f0400954676212428a10c8b75d9d0d64b0d23dec4c7efe5ba1e599f4ef051a050943ba517cf6b6ec438aea973509d1919b903cbcf551f4f2e328cba5b55dd9a5d03eb9e471d63e5ac422c47941d9fd7a27d00c6779ca609ba3dd58c0412e7e4b0740ac9064a6ed4d024918debd342acd03c7be1a6e7c49fea94f0069b19c363095b9ec9b7fbafeae5ff1fa68ae47db3641dd98b7a6d921843707f1795e610198df9b86ea45efdb5ba3fcd37737a06881300733a0a4f1558d562577dcefa0a9e76d17fb3d80385b442f1c07a381bbda05b5854c9c76c10d2c4ffe6e8c808309474ec30d88632a794be4e7002ab9d16eac7e5155b3944089bd482009722150e0e06ed0ec3df814b5fa516bfa019f3064b78ee714a03608167374ab4a290bccc10c76b247086c31f9b4de06d001fcc7158fba4569b71b6774a46a3c1f7f80d00ea315433156fa587ae49204be74d06a949e60867b3d5d38c93eabc1fbf\nTAG: a6f01e3b9b29802f017892ef0080642e\n\nKEY: c3e4bd36e2de49d855196d82175ac395\nNONCE: 16571d209cd5a8579b05fbb0\nIN: bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3febe9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c98345399a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3e040d46d24\nAD: 29ff2b38d4e35a3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f42483\nCT: 9debc22195c3c01c571b369ac186ea10068cf99ae63fcc98c40ec69b3a04503c783cde85be74648786d5a7fe51c74f821992c0a0cdae23f4ed7318a42a6230f7c31045faeb40e880046d6e6bec6857a1e618fb360363872047781c05c38ddd8363c923762e4591f6a906d47e6d74ce365d36e41a3a6efe6e9dcba165a0c081fda577c01eafb1f83d116270c5e467dc7346647b9c0bb1e3b1da43b9cfd5a0f4cb0d3deaab5f3fe8401665fcfe742e686de8c050e8fdf7f594ee4b6c74ed0b210d92ef26e45da5a390f9290643a77b57af4800b25eb4f3ecd45e5eae5aa0dd37097bf24dfc0d1b7315d1787356e84e819de3e099f6bcdd3a269b2001d1da51681f14069ce8375d2f6b543e6fe0e9ceef03119ad96683ac884ca852fb0f88d41102f275d5040bd7f237a123d7a7b7d186d77b2a64b54568b11e70be4cd22324fcb072bd6f59d2a1da48a720feca38f8c164b9f6fc187c0a7bef39e4243aeb8c5d87d460dd9288e3de113250738faa5e82b2b4e672fce93f5294f81716aa8a5fcd43565db4b580ed18e41577fe2bf2c62518c1d4d4c324ae26a65a4bab6e5edfbb98a8eca18b34206705bfb7377c06dce7fed8e76b17c0cd2f061a77900d970594d36bcb15a92d2a09d54806d031c98942cecc0ed7f72c92df73b14740e661de31fdcfbc36f8fc89164b7614c505ce3b909376e827c857cf2b0ef3df86683aadad3112ba20126b36c5bc2c121737fbbbaa14165d511d50612c8d3946c5fd8e1a257a5c7f684dbd3b160d849b7172f4648c935c08d38733792a171cf20ed4b2bcaf98e39d09675b5918e5fe12b4e2be36e4b8463bfe708669c1d01a625d4f572e9f30a5c88d05494711e673c3d23b1003e94d4a75b9477395e8a16944ef0a1726d0388fdbbbed94faa5e78deb16ec471ed75d92772a4e437fa49af393ceaff5606aca86769c860864f62eb9c5801eae1d1fdc79654ed09f2b858718c48f05968a7a09b834c1ab0f31231795d0efe8394b3302fc0f75ac9e7c18e21abbaf6054f7442dd235451d3b884cfa25f6b7018fb18c2bfd5bb0e6d0075c2eb4f9002e30fc7d420268bad52dd916be28663a8ea3b2a0bbe653256314acebec85c7e5d2c1c163b0a15aba1cb8da585c83016d4c3f1c0aed13c20a9539438eef3a426565cd8040b2918d154e689d871a55f19b505ff94f3042b3e7466e21585800952004906abb3d13414134008c7ce1def619eea9cb22f3a44ba7070035d4cfc1d5bffa9e31b6390b4d1da2c76bf687b9bdf899fd23ce6921fa93a47e4156a514\nTAG: 232db78e53f788a11aac05af1041dfc0\n\nKEY: 64f49aea2a19ccab66841c438df5ff78\nNONCE: 34ccad859bfdd89fa9af0b99\nIN: 214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5", + "c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fdf56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480ec6e78bc1358c72bbae8fd8dc84038806efbfbca520a9bf9ea1df8ac365a0a95a9865ab3b3556\nAD: ad8da691b07926db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfc\nCT: 2873303a8c1b9d3230e38c46f680a7ba273e654fee766beb451f311b3192f16a385ff3c70f124e20f6ebba3bcc288ecaddb2243d3c707b0cf50d09d3c89e67d2a2beebd0ca0be6efebf9dfc519f5149e7c4f0c5fa8ef05cac1d2246f2616c179b4cdb02bfe3d7f394d885dd30f429da8041cbe79fc35dea5d90b903ec27cd09861422d3f185b887ce5e1b1d42d77c254fa003f90d62d980ddb63593e8700a20eb0b7bd930d38ae937ec326116f0b9983c69c322589e79778707856eac07ec42f3497767860d4e072ed28a79e263297896797ace5d32595c8b039ea3684b763a297b30eda2a63e178a713a03ebed0e0bb54c3eeaf41d8940edd2e448533a0258036e41211c835ebde50e9b7fef5c189834dc89cb7aa566c40ec7265c068aa50939e9976d1dfc4cddeb630a4a1f78a9134e10be1868ecd92628d3f8d827f432123dabeb9f45ba4576ae932ed42c6447a7b9f3c9b252719735898c76db75ee8f0fa655fa023cc33fb1ac8974774ce6f23409cfa7a4e936b57b0beffbc6895731a450eed1b4cc795813bb5517997037169af20da701d42d0c9b169e4155a92b4ecee3df6ca6c4a22474c01fc0aad8866e5fc33a8b3ec5a002ada29dd4d284ccd8141e4180df300eed91ab9063bf331cb476d6bbad14fd7b6ec10a3e72833595579d134a642cc556b4e9613499627f0af51f6b22c0f963e4063838809510bcfb801880e455d7b4df9db1841cc2168d659d1997a251368f1c15673ce127033602bd0fd9988eb1bd63e47e8ea863bfce945cd077e486dafa43c7f5e35232c0ee1d00d040dcda1ded51a06ecea68ac635a8faa35361f32d19586450e7a7b7ab1a8861d9f0f4d9508cd2df522dcf04a00ef2dab9ad5ce9dfcd6b018d0f072e9a17cdfbf3772d38da7b799feef2b6bf7cb4f8cfa53a49cbbda15128a17e77f8f7b4d14e64e358a11cd01d5d2137d8719f8b9f66ecb62d97faa3d2f56ba50bf4b9a28bc896c36260748d803fef6e5a6d6f24a00550ed66a2ce672b8d1daa10097c88f81669d09da72a5e62b29494681b7d2389063605e1de349a83ef50b8d57c024b2d558d206a73e49ca7fccf2b1ca685156e63bb591125910e9f72ab2e8d3ed50883ef0bf6d6571cea0f5acaa11e393d15607373f25fc340b9ed6b58322187d6c8fe4ec47666e1ca34526992e7056cc7567397e7ba0c26e1a049eecc356158827f3867171b4c77d408aa24c51513b0dcade9fe2bdf6ec856d4a44112fce5b4c55300c24aa2e9cb7d289744562dd44afa68dc2f14dd25c65d3af78d4bbb781aad5f9fa05367e02327b644563dbd992\nTAG: cebb4182450367713b8f5b047314d8c6\n\nKEY: d12cbb53bab8c9884eb83f1d2dec7fae\nNONCE: cbb6af3402bf462f965e2c22\nIN: 81c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521cade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa58697121394f11a1b\nAD: 1d9caf4e3eb2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302\nCT: 7f22ef21a372702a9fead4339e38ecfa2abe757d8ff986e7287a479a864bc1012d4621203289c8731b189937d50fd6ee79db7ee84a157acbe801bb56e1225dabf13a25b26703ec364f98fac1243ab4a4cada7080a4acb8509969ed8a2e9f309e7e465c43f55d2dc829e2ecd63b8eeb6bb01a621f86b4cd32c9c243c200670e0d9bf71b221de296e3364ca2ed5c73751b74db151176626a69010f136a32a14d47612488f90750316ea7088578bcb84805d331c77d3041af756f2ebfcc4c95c328ab03cd3424f689e410706df8b2e87ffbe24f8025c1ce48e2ff6a0a240f23b09a0378155c2fab57db5d8c0daa296b813ad148e94c8d627715cd2fe8f861e414b3c7f482eaa5ae1eefc6ff86ee30109e27bd75557d70598d7c65bf9bffbecf44a44339b09ffb88a722fd8c19f196b9822ae79cb66fa1c712cbef821d996fec59f5a95c197f70fd34db9e2349a372f43bec0dea764fcd71ff931d34fcdc8d9c9321e6d8984211db1c1987032ad85e1b03519f433ef9db8811fcb2494", + "0a320697c739136a77f66e97332b75b33b9097cfa9e224b262c19053ca32afa76a96524861a8aceaa98771efab10c0665533619befac9bca499ad88c9d0f089a7026583e132ccf3a542adffd56996331ded9917d363659562a6b7e45231667b8b3069f327d829489279058b9b89bb7902c1127d7e8d150634b580274b47354edcde999922654def16ed4378f313115f4013d8ffadbde1c8f8c918ff7257175f14ead903c03d5190aeedb2dc9e762e34b3f80d7ee460bbd14ae9c3182660608f033ea073548956b72275f74f704a349a87edb015e6154fba7c0ef4a32a4dc206dc42d5d261ecae22a9f455c409304131859477435b30ba3fad46bd5f69971ba74f1fe82a6d5604e5d7eeae0dc8ff5a170865134c5fbac13bf6cd007a16af86c42dcc887b90664ee5e48edffea8ba46fd84c844cbade00906c36d84373178369fcfb9226654233d2c5339099ae4e723a0c0516742e42e3c40994bd06086e6f030acef01727e7f600f7109000bddbdbba16b9543174c98810d5ef0c95598ededb7ab628323faef1ea4028c0ca414a7cc33239c84de86d53a242b4e8c3f9a20e3a826f0ade00c440b2f792b946a97758a073fbc811f3e22de8acfc9ef1b1a946f6c3cf9eaf4add2ba403941b446686d9bc0524590e2bef8f552dd54d9f69053f647ff0e2371b244d15cf1a5302680ece820df552b374bcd23f784a9c4bd486a71fcdaaf3812efa5a39366542b163294da6a2887796b6d863529dfe76ad88e2b47931de5194a63b9f07f6ec63081c3f97e9c0379c5f44e7496dd23b4c186e3613fdf0d\nTAG: dcb7fd2d779be6e82ba1ad90bc79ca3f\n\nKEY: b243593177cd099dbacd5f8efb412a95\nNONCE: 132b8ab31815dfb463451fbf\nIN: f63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b3614ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc762d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac532fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fdcacdf99a3852e9ca\nAD: 9516be08987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f0\nCT: 3497d7dab267c401f6754a95b885561c8dbce6c1bdeb8c6877810d6e77afe8e2071ee088890dfa18d8b4de635ebd88188bd1ff3539c7da99905bc955e64fbac216a0776d6ee45169e9959f4aebc6ef987f7d5fefe73aadfc2c6da56155d53b795df61504680886b9ea8bc59558160d9d63e2dec0c5d7795073c04b6191c725d5a881f71cd049b9ba42333f1082ab9733fef2230cfed44c7d827a7e6a8cb07ea58cd8ce96baf00df43ac95e35eb585ba99165b9cc6649b306c3399da8a03134dd45a1b9f1e4ab3aa0399c577104316af55587d5eeb0348271d2467b920a083b4bef6a21033f8428ea816718880da3c29f4332b19030d4270d20a4271169f179df4dcb07e15db1b3d4acb2d9cc9ac90e9877ddc09ee0bdc202e9fe23a844be123fc5b08068c9a6428988de1f2f26f06beaa020f725c072c842c97fa8069d944f80518ad2276cb4aabfea20db3256d35f9533d70c6723e5696cc159127ca671db02bcda89aa17dbf47c33eb863923c0a88f3bba8f79bdfb6eb2d15fcfa9acb68018d4d33417585299e92fe3e4a131dfd123a4edb72c988796c6dec3169cba26ac712cbcd92abc4e1f327f05838abf03bcfdb218d56e2d795eab3d08d5beba1b3492e72626d86b9990e777ffd91ccb30f99713d89d0532a032bf12192a1ac2368dda2c131febae2c11bffd83311fce6d20521e92d458a285fb548ef27158e593f306d99f2e5e521522192037e94aaab02713e3242bb412b362508ff0d4823ca0ff6190c71e31f4ff06f40f8d467182ad43848ee8b8c39280d535c7cde50571f40c366d97f5de703b808aacb5a7369df763518424137d42c59d91fdd365d025f1a747b95eba9f0ff580926891e39ffa2943e28e4cb3981d2cc62e9b975048df0d0708bb7067a67bf1ef6d03692fc5501bb09d562ea9ff3078e454227ae4d6084d21e08cf6c147b205d74fa81b72c1684f60923bc024c072608ea21ce48fa46c41495761d68744953c87c6e064b33d8d43135e43fd5f67322a1d2d9ab0e07e9f8862d6d252197a4fba914aaf4092a4d499a5996d40f143b8f3eae95a5a64b23a17495834e3246f3d0a06756d80bdfee94f2c03c8e5ce0043e9094465f6a3307f8b6f098edd85f863d2de3867b644fb0ff335b83d26958c88960f9913ca3159b61391fb67dd6770321a6971e1fff607c9ab6a2765f4795f53fb8aeb26944f728dc6f66de97136b50d722affbe78e59f00cdeda54e23f46647d024f384ca01f46a39e660df4cf9a2576fa353c7b243c401b429262b14112866fad6e802ad42fa2e509ddeb1ddc70d24e4eff5f7e94b4e9772cfb52b88d81272462087a446b770db1aeeddcf81cf9075b419acf4a3c3cc\nTAG: a4b1933381318aee1af76925720ffbdb\n\nKEY: 5d44b6e557031ed28b60f3a9e73293d0\nNONCE: 3f57c9c636ff9336cee08635\nIN: 8c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de062de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b344a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83", + "130f197a6f35def3e8e2c6598e6c0a8ee\nAD: 6b0da01dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2\nCT: 68b1872409e4d6bcc2d218c7a844ec2a78969d25b766a5272ee09a3f0dfe20abba0ea4cf75437e4b759e8586be4defc5146b303b162c4209406c93884c06a163a5743fa6ebb8f649ad8de37194633d18fc4d0bbbb1c74e8297f48e1f532e5ef9ee7c15f07b2e96cfdbce6f583e267658a795ec9c4dcd9916d5dcc08fb5c28277e56dd366a26f92f9680930d63493e2995ce350e6286c2d597273b7ecdd27d2c05b725e32d6c48f7f577ed4098d318fb822cd6413437c44a9ec8feb54959a2e6403484a8aed34e0527cee6838844dc987d933af12b370cc888b6f6ff2a25754caefc1c665751321ab9b9f19bfc17e6903c99dd87fd502065a8ecfc1c29950dd0007ee2f9c3fc752cbe7e661f06ff22a266f564e351a7137a1b96616e31be24c7a13e62b04646ce0a68791e0e1a099b862435065cf7d3203fb32d7d7d8ac4a77642d69f7c27a46973b6bedd5e840f887209d19cbe50504c0a251056c8a83100092a627f73edb421a3f1aa12edfc78d3fc474cd2583808e38d63baf1c5b4b5cb34665e10d4af806bf3abbcf4432df6c9caa76cf0e17a5e0e9af7c8868daff22d84b7b6eb4f299b750ff18b9b17d7412ccafe3e55e5b02af9ad87c03799c2282a9c6377ba42e840440d8c1b19bcd1c8fc35f02fc505a3ce97562b9e660fd488b53c30edb98b91949188903ba2078193c2de05e61c9da7bc056624104471a8231b7fcfdfda4d804b8819888a2c9bde680bae59e438d89778c5a04dff214e9b14ac5b031c378c8beee5ba9b1f91dba760d7621c24c30aee28c4b49e183632d8b450ee6895a47b96cc3c1917af685905691d1ca588db5a21674391238d76ae101c3e83d94dfee4a0656baf4d6cf277e0c7b0512e4ec13d12a5af44c7d19820fe7a74f5d5875321d528976f35a5634e15dcb35a54836370569d5609de0360ea4d2f1937dcb2d68b20cc5a04c13c04d5379a7dcbcb6b711712d7b3b20d255156b7e61e99803a4d767f0438c4fcb166920744c20a08e48dcf5de4ec325439485b51e4c0f08cd22ecf60ace34b93844c2c12bc7b46a8f6b8dbf4de311f1039504a46d9616b41fd58388f458bdb8bb9821a33379cba4f36b416c2eae02f42b736c1cb6e673b9b9dbd230b6a23d944124469bbd2c545f5ab72fa4b3a47b4d0bb0271d615de6c7f182cc92165a84032f59c14f181c093b017a1c7e5887db249b5ea2db39faf7a3cfba08538b91520fc1f3af697c5f4dea7274cd86dc073920280b488a3f66969cfea020a312be1fd111c7847296ec5f5cc91f00188c07c05e4e49cd0667ee16345f794219ed3a80602cc11940aaf9a927805a040419abd20ad8ba0a05c7ca9936997549ed5a3c7e7d9f582c735a424895c5f1aed9a3a2ad3cf7d9f32d3e\nTAG: aa69fb97b939fb73703ad4cec6c24fd6\n\nKEY: 714f39851c1fe09297c8c69dff0e62be\nNONCE: 3383bb6aceea0cbc71cc7783\nIN: cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a94494f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f4fe1fd1359a433240225\nAD: 1d90b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23\nCT: cc11a071e11cf36750fad572fdfefa377b8f0ed6cc47bb8015cb51f0eeb531e5779d233ed224022c5f7ff3181ad1d6a9f7564f41ee919f0435fe49b4266157a68061a1c5d06d8a8075b55efab8c9530266955c179f0a57684459835931cfb2eb1244a730797dcfcd31e7a414ed42990e9a55d439fbb803f2828f92cffb247f8d96896f9b37ce2d029aa15873bf13144cf35eb70d8e27a013513774ede1d37e4aa007a48a12f37385842cb716f60401f638efd2841db6165819eb3c2c58708d92a454344fa64c2d740cb34d4b7dbbc1d86d9e0083432e0e90c074b617402b68e3199d6fc43c454a842da725b49eabf8459b4db90e6553e17f979fc8d6bd03ac382f3a85eb40b64e21787e8e8170372eb0202fd4d78b39fb940829e11270bf6ccce0fb28adcfa8b60659e54a03c7b22491c62982e5673d66791bf6db75edf3836449e918b0c9059de644039063d78b66769d8358349acbaa7f1bef02fbfe49be375f652952f66665df26964b8b8b327683731cf825ad45118fb98f119db977828d96618a4a2fe82105eba7d1c3bca35775dc57a207b5b07c24305829d911bd7d30e3c19b030f6d34f6858593f3a0dbd928fca4b1ca21ce9ea8b63b149aa444bc696864fe2bdcbfdfca33a656db422cd007649d3a3e895b909fac7f9f0d9b15920b1d9dbcb343a2a0fd9382154430f818a9b347dda83e1c1038eb5259ca8714e2f8d3ec13c8c7a96c537fe599b30fe8780c82242f674817e815d56c92e765f3c67bb9591e27640d4880e04fc6afe5f1482422b0de4282df77df798ab7d32372f22dd3dfb0035182fdfd524dc315b0c7607639fcee3b1e12421025964a27bb5926f28c97cd7d74cdb26a779b656491f057eeb3be3eea0097b787ca5d1b1d5abf42fe76b16e565b2c1d15579e761efdcaf04fb18e7a97215e4dd53a164b336921390fed9c4fc1cd0cb0825d4b5c7061db0f4f1cdd950f13646c662bc6837ce2e455bee1758a59fec54d758eb49f040384f27ab6abfbeb7ec52a1a1b3ce63f6b4ded32a41a64b8cade579db95b7d90dcb875e83424d03e9f3bcc2dc45952860f1845632c7550802c957657c9342dc32c64c558944fbaf5f2b6a04b5d48794d140bf4f9de2fcdb1b77a0602f1c97fabb0f2b92b05b6894e665a8fad01dfb2764f673f61b9c6cae68272a5b12a9a8347782c69f5f9c3d4ff932cd713a1e2a49759114563d94261ebd7c0a723a5837a1912cbcc98b6481f6d7bebaf29276bbbd6d0a83bdefe2a0f3d4d60d88d4575e3cff73eba09aa290c2060434f85955597a3431c376f64489f50dd9d1be65b72158b1d6875649da95579b5c88e3d445c7bb95a4ed9452e18ef33bd7dbcd25c5ad6c769a651204e082026742b15b49554133e1539fc516089ce27940c89eb1a68846f13f3\nTAG: 26c14eb5587ec540185a067635e", + "64c29\n\nKEY: a406f8b8ee46d958d10d8724d90bb26e\nNONCE: 2b38be1c0e8258de3a095418\nIN: 26486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43f62ac96f76e13ab5928147c5e63788bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ece22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6a4c6732e0887f40b5017de\nAD: 54e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585f\nCT: 4f90cb1e30d5c2c97f46ec00cd8203ca8dc808dc0e862cfdb35b1e92a24f0093fb6b68eea43f04ff1332f942b03aa2dcbe03aafd18b292cbec3cd66d7ab26af3f274a97e599f520a6bb59f5c56fbe858821eaecc297e0cca632addaa5aee071a6cf84910006f158cd1e8a38f185e95dd7f6ad09303636bb6356e400ae70338a8eeae7c22440babe6d9595b2ca008c2e7a471e70e66c49548bab632e87ed36894c6eb97c7de858382cb060277edc91e19b288870b2a472df769393accb07f34a8cd94922582ce351da199a8c5c426b2884bba07fe38da6289ee55537952d53ffced29cf053a9e1b9b37d2e0e3c219f48fe885410e6bf78fea15719f20091e654d44c786f9494e4a71b20f968bbab6f5305af7b8668867cae10eb93904a0e3ec3478fca8d6a231c9b4b84cfc3394716b366c0b1a1bbb8012a298e3a00831791e489b7a2dac6c26ca9e5ad4ab58c4cd71215cdfa2422f49a7b30698ece44972a6dc7dcf9ac40f241085599e71957bc719dc51555312fff4e963832017371980b5087d0f6373e5b52d66d7003525cabcd56bfcc00041bb9f0522a4dc86ecb444497b97d882d122dd8ca1806f1e0c8ed3b1b4810dcfee9b2803d08f43151f5a968c18266d0b956ce26005628780a1c4fe0e25b7dd55e6d4cb6b1427fc56afb278a8cf91d83b952908c295947a5cbfa183816a9fc4400db94a5990e53d99da1694de5941364e7828515544b1074de41c253a3b7bc4b72a3a0173138a025fe758f8d834c7c814f1440407cd1a98aaf15f7f8d5055aa8237c6d93beb53dc84cd4712d0535fd90c180a40ba6cf9880d5104480c18cd9734354c9321eb3ad583caa5eb05edcf288ca5793e288436c175e56c001b473c1486bf36f9d75d71461339f1e063035ded3246166644761816559ba9cc9c26f61f6d02adaa3b4b398fb80906ddbfca2fdfbe57df724adf1f76f995ef7d52468ee2f89785d59c0c8557ab45f07e0da644c0fa9b5a9e1a2280d34a0f65b463e53d09146bd629134b12262f18471eda27ebb5ace095864abe17b95f238c0823dbd11245d89c195eb9ee65f6f97819def971189e43354d4fd811fce3c430cbd4686e50e562ab1e8de214832db1a09a64f9339b8f6dcfd53280a33071e89616148914de8b456408fc18a9f46f61a782857b1e11dfb5f956a5889d60c53dc826ab92153cdad4d935ccd978516c383371352f63edb7211c3da54cf2eafb7ee65f6aa98aa7813de42ec43a4e3c91bc2eac8cbd27fd0a39f109dcc94365bb223f9be11120a9767cfc73e2c315846b675f5e1eabad4e7a970aada798993fb2b11248be37b451a6f8be3ab93dbb0b3a181c49f0b43b402f05221bc97a6c2b5ba9d1e5860a234cbd2c7dcac97ff395ea8ad34229c3b0624eef42f611f90449476d76e816fe391edb539f9adbccd9628dac1e8925\nTAG: d4c3aab4d275dca02cd7912eb71daca0\n", +}; +static const size_t kLen9 = 67908; + +static const char *kData9[] = { "# The AES-128-GCM test cases from cipher_tests.txt have been merged into this\n# file.\n\nKEY: d480429666d48b400633921c5407d1d1\nNONCE: 3388c676dc754acfa66e172a\nIN: \nAD: \nCT: \nTAG: 7d7daf44850921a34e636b01adeb104f\n\nKEY: 3881e7be1bb3bbcaff20bdb78e5d1b67\nNONCE: dcf5b7ae2d7552e2297fcfa9\nIN: 0a2714aa7d\nAD: c60c64bbf7\nCT: 5626f96ecb\nTAG: ff4c4f1d92b0abb1d0820833d9eb83c7\n\nKEY: ea4f6f3c2fed2b9dd9708c2e721ae00f\nNONCE: f975809ddb5172382745634f\nIN: 8d6c08446cb10d9a2075\nAD: 5c65d4f261d2c54ffe6a\nCT: 0f51f7a83c5b5aa796b9\nTAG: 70259cddfe8f9a15a5c5eb485af578fb\n\nKEY: cdbc90e60aab7905bdffdfd8d13c0138\nNONCE: 9d987184c4b4e873d4774931\nIN: cb75a0f9134c579bebbd27fe4a3011\nAD: 7dc79f38e1df9383e5d3a1378b56ef\nCT: c6a899758b6c11208241627c8a0096\nTAG: 7525125e650d397d0e176fa21315f09a\n\nKEY: 819bc8d2f41996baca697441f982ad37\nNONCE: 08b7a15f388fafb16711ce19\nIN: 9b1ddd177d2842a701b794450e3c81f151f195a1\nAD: 277c372784559784b0e047c6f8b7e9efb6f7491e\nCT: de9b9c8fe09f705f558c62dc6d40b75e3aa625b6\nTAG: 52e2d2f153a4235eb6fac87ff6b96926\n\nKEY: 682769d52fa0bfeaebe0d0c898d3cda7\nNONCE: 6af0738b249d09547837883c\nIN: 3461523cd98a6e8bdddd01150812e6c58d5cfa25d385cdbbc4\nAD: abe8302d7d5595698d9f31011c24d4d180a637597098361354\nCT: aa3ecb46b9330554b36d0cf6f6ac4cf5e27bfd5f602da1b3c9\nTAG: 0ba547961eba5c58726c418f51d31311\n\nKEY: e2b30b9b040bce7902c54ca7eec00d09\nNONCE: 28ccf218e8de56ea91422a25\nIN: 483080d7e2fb42580dfb862d2d266fad9fdce7cdcdb1158d415f84b6e269\nAD: 9f06fbe67eb2ace15c8011032feeaf72fdf6d316e1e08ef4cc0a176588af\nCT: 67e1980ced4cd232ce893938e40b0798b17a1692476342e520b480a18570\nTAG: 9994185d4329cfa5f4bbeb170ef3a54b\n\nKEY: eaafa992ef6dbcc29cc58b6b8684f7c7\nNONCE: 1ded022dbc56e9ad733e880f\nIN: 900951f487221c7125aa140104b776ba77e7b656194933fa4b94a6d7f9722aad51b2fe\nAD: 863ceb297cb90c445dbcf2fcffe85b71db88d8c935158f697023e2cea103ec39766679\nCT: e0b3aaa890e45f1c39ad4f13ba7592f5251d6a02ca40fe3633651b35fba74a579f48c5\nTAG: 5c95fd941b272bafbd757553f394991b\n\nKEY: a43859049b2702e8807ac55b0ad27b0e\nNONCE: bbe8c571342cac7fcc5d66cd\nIN: 8673d6ee2903265c92446ce110d5bb30aa2dd1b1ac5558029f23974acb8a2fbf4c74858fc73d6104\nAD: f77c998ad3ace0839a8657e350bed15ffbd58f152a0dc04ffc227d6beb5738ad061d0f83c2a26999\nCT: 40e201a513979b093637445275b2db5ed4cb1fa050af0e20e43b21af6bc56dec654541e55b295b72\nTAG: 41bbef45727d19ee544fba5b360312f0\n\nKEY: 68fd608c8697243d30bd3f1f028c5b74\nNONCE: 319a210b33c523d8bc39fbea\nIN: 2c088f38f7a58e68bdd92632da84770303cd1ff115d6364479fb0aa706571f68d51be745f5c1d1b44fa1501cd5\nAD: 1417a65249b85a918622472a49df50bdb2766aae7bc74a6230b056549851b3c2f0cef727dc805ba2160727fbb2\nCT: 9d376b147620c2ac6a5eaa8ee44f82f179f61c9bc8acdd21680a7ff03acec953437a3cc9660c7ecb1204563944\nTAG: 05a4fb5be11e3edd89e34d0b7132d0fa\n\nKEY: 6edd3bd2aa318f78b4a51103cb08d489\nNONCE: ef0027b144691bc9716fbeca\nIN: e98f2f99680dc748fe0b57390df38a99950faaf555a888d463d005ef4e4b1c22663d3d3daa812b20ae35ac934c2e187cbba7\nAD: 97337902507391de0f15c88462aa5ffc5e4760543850719ccd8a0cfef89484d8095c23ff8c1d06eae4ff6d758c95e65cc3b5\nCT: 3c54842c2099b73daa9c3f1cb64bb913c0527955d923510f3f3046df471c1365db97333bc5a86dc7c5f23047e938fac976c0\nTAG: 375b2a25421434e5e3a021d434fb2d04\n\nKEY: f70482d53d3ef70cdc3cd3c4a37aeb2b\nNONCE: e69d3de363e225749cb1666f\nIN: 4cb68874e69125e1a6f6e68669b48317e1b361d0f7f95ec4cf613b7da2c835832010e8f95eaef4e6800b79bd86cd7cda869d2df258c267\nAD: d72975f15721bd0957f5cb1edecaad2d1ef047afb0e779035f777f94cd7ed1bdf8ca9d4f357d2a1e195f195e7483dea1476133235f7e6b\nCT: caa1e48decbda18e314057c5ec32f8733a5cf03ed0d05c3654531bf56faa70751a6c7f70fbd7d39f7e9775a772aba8fe7731cd0230beab\nTAG: 47d909cbdd1c7f8b485fc3232bb7185f\n\nKEY: 98a12fe16a02ec2a4b3a45c82138ae82\nNONCE: 4b3404684825dfcf81966e96\nIN: 899710fc8333c0d2d87f4496436349259cf57c592e98ec1e3c54c037bc7ef24d039a8c573ec7868e8ce9610b0404ea1b553ae10cc8cec26468cc975c\nAD: ea1a99cee666bf56c8c3667ef4c73c2e1e6534800d6e39a97de3bd5d39068bb3e2f74f96c03463afa18f1ee88c21209bae87f37e5d0269b68db370fe\nCT: 0431b7fc4889ae401eab5edba07a60f9682fe58419d4140cbf4f20c62d79d8a3cc1f23fabead0e96e1c8c90929756ea1efab508336e1d0ed552eafd0\nTAG: 01053ceeb4f9c797eef9426930573d23\n\nKEY: 6538e8c8753928960ffc9356d43306b6\nNONCE: eee386a2b1e310665e335746\nIN: a92eb9a93a90fdbb2c74dea91d273a48efe9582f8af7a4e3a377b114770a69ca45421959fcf36107815e53dc61b7bf018fc42965fb71d1eafce0961d7698fabbd4\nAD: c5e572e464718398374c8b45ff8749cd9f517bbd97767f77a96cd021176c49c0acec8b055ef761f49aa6d910375a45b2f572cd5420b99153971a682b377ac88f09\nCT: f36353de609d0b5246f64a519d89a4dfcd9d53325a2d2cf910e7692e68391b0357b056b944e0b53e41568f304bea8822f9ff7a0375a5a8087509799226862f707f\nTAG: f7f9b891089d02cac1181337d95b6725\n\nKEY: cabdcf541aebf917bac019f13925d267\nNONCE: 2c34c00c42dae382279d7974\nIN: 88cc1e07dfde8e08082e6766e0a88103384742af378d7b6b8a87fce036af7441c13961c25afea7f6e56193f54bee0011cb78642c3ab9e6d5b2e35833ec16cd355515af1a190f\nAD: dd10e371b22e15671c31afee552bf1dea07cbbf685e2caa0e0363716a276e120c6c0eb4acb1a4d1ba73fde6615f708aaa46bc76c7ff345a4f76bda117fe56f0dc9b939040ddd\nCT: 049453baf1578787d68ed5478726c0b8a636337a0b8a82b86836f91cde25e6e44c345940e819a0c505751e603cb8f8c4fe98719185562794a185e5dec415c81f2f162cdcd650\nTAG: dce7198728bfc1b5f949b9b5374199c6\n\nKEY: fd1dd6a237a12d7f64f68eb96890c872\nNONCE: 459ced97ebc385ab3a8da8d5\nIN: 04a9709fdc0a4edb423fe8cf61c33a40043f1a585d5458c7512ec8e4e066a0f95e2e6609abf3c95a5d3ae2c738269533855daedd92eca20bdedbbd5677cd4eee84b7a1efae0904364f1e54\nAD: d253b829a2fbc5877b0fbe92e7b79f38886a49ca889ae72b91f2c3aebe257a3ffe0d390b5d320bea22d6a5536cd9213612f5ed6e3b0ea33ac91cfee284cb25eaaf6b85b15f7ca894317182\nCT: 4a565d3ba4f2ec461c9bd8dd0f96bc00d2a561bfb56443c8cf47681bdf1c61f55854bea060c4219696cac79c09aa9400a7e5c59c6b6ca556f38c619a662905fc5f0e8437b906af6138e3fb\nTAG: be5f93201d7980af4c5bceb24ac1d238\n\nKEY: b09a4d99112e1637d7f89a058988b417\nNONCE: 74348f7126c0cac836e9de5d\nIN: 6b3c4cfd1eb139b62d91ed5d1d8b0f3b52278d5c48787ce46f12b9f026e3eed1bfbc8c6684c6662f06614c69440b3d7cff7c46b2e4aebaa4b5b89236a3cc75535bc600104f240d01de91e0fb3bcad02c\nAD: 7883ad259fa5d856ce283419f6da371b444b9b64ea0ddb371b17ec0a9ada27b0eb61b53bd3605f21a848b1e7ed91162f3d51f25481f32d61ec902a7f2cbd6938a7ce466a37e4467e4ec2b2c82b4e66ca\nCT: 5e1b783b20fd740310333eddde99a06b5740428cb1a910812219fabd394b72a22a6e3ca31df0afae0a965f0bc0ae631feeaa5ce4c9a38cd5233140b8557bde9f878e65e8932b9e3c3f6e57a73cda36cc\nTAG: 784b73ee7824adf7279c0a18e46d9a2b\n\nKEY: 284bd8c4b5d7b16aebce1b12988fa1d3\nNONCE: 7ff05007c5d018b17562f803\nIN: 903416331583dcbd31420906c64dc76e14d0c5044d728cd9b605b531ddc350fdaadeabe67d08f0b4c7179f82a1044696716cd96459506453141e9ec3130e893d8c2ff9b8b4c241b73866ca4fc1f712d17d7a88bf4a\nAD: d0a1f92f80094c1fad630ca584edd953bf44cdde404f22c8e476df8708a97a0712e7fbd8054caa7d65144d0be3b30442d0dfa5469ba720afe1d00aa6bb53c79c1c178ed42fce596eeb6c638c8a8dedf76a431976c5\nCT: 9bc3708f70a68fc16bcc33099325c821a0ae9a2fd0a6a98382fa21b42ddb3a9ac6c34a13c4805d3beb92586cdf0f4dce3885793d49abce33190685e7009a79242dd93594722a1ceaa44886371c30bcc8312fa2bf67\nTAG: 3fd8a4d760d5b878852b1ca2d34dde6e\n\nKEY: 6d76dd7dea607a5cf5c21cd44c21a315\nNONCE: c1d13e56b080a500f1cb80bd\nIN: cb959b92e777f835afc4ae4149b190638851238b7b13c9bf65343adb3130e8ad2356101037f30997d4a5fcc0a1d6415210179fdec881236a799f6e90dd43ea3817819b432611eaafd072368b9c7036c7a88c8b7774a8ed986134\nAD: 92a2bc3b6b6ca9de0cef10d8bdeaadf6f54782cdb2b09e66cce8cb5b56895636e982f7a3c7bd9d221ade62c9ecf68bde70becf683804386606ab1c48ac764c4e11620064545c5beaa5911c118856dfc5cdb8df50052b01762c6c\nCT: 522ba9bfb47efc624cd8933fc9e17784919d2b3ccfaeec46af414c1b316355f65b9f9fd7f0be6ac3064b4016e43b8fb2028459f0fa0d81fb6656be0ab8fd841d05d24682b4a57c7c59d89af384db22c2f77ce10abc4d1c352a1a\nTAG: 5ea4a77381679876e0e272b53519d533\n\nKEY: 1dbcbe45a47e527e3b6f9c5c9c89e675\nNONCE: 98f2da8ed8aa23e137148913\nIN: bb23b884c897103b7850b83f65b2fea85264784737d40f93ecf867bfdba1052f41f10d2c5607127da2c10c23b1fbd3a05ce378a9583b1a29c0efbf78a84b382698346e27469330a898b341ec1554d7bf408cf979d81807c0cc78260afdb214\nAD: 46f1bde51f6c97a9dae712e653fcac4da639d93a10b39350956681e121fb9ea969d9dc8ef6ddfb2203fad7ab7e3ef7b71eb90b5089844d60d666e8b55388d8afb261f92b6252f4d56240fe8c6c48bfde63e54bd994ff17e0bf9380ebfb653b\nCT: 0d90e869d2f4c85b511fdf85b947ba3ab75c6b1845d8191634770413d7574a6fbd9d86897cb3d3b5d3d8e6f74fac3bd2a9b783cb16cfbec55dd7d2f7fc5c39fe85d39bf186a3fdd3564bc27d86f", "4019ae0cb73f5f516b602331433689c1b08\nTAG: 8777f2002d5a5214a7bd8ef5a3ccfbbb\n\nKEY: fe33f47136506e5cc14114eb62d26d64\nNONCE: 9534a10af0c96d8981eaf6b3\nIN: 3ca38385513eaf1fcd03ac837e4db95c0ed1a2528b7ab3ac8e09ecc95698d52b7d90bf974bf96d8f791aa595965e2527aa466fb76da53b5743eda30bb3ebd9f6a8a7721fbfe71fe637d99a7b4b622e6da89e0824ac8aea299ea15e43250d2eccb0d4d553\nAD: 50b7bd342df76bea99b2e9118a525c0f7041c7acdf4a3b17912b5cbb9650900246ed945cfc7db2b34a988af822c763451ac2e769ec67361eded9bcab37ac41f04cdb1d2471c9520a02db9673daaf07001570f9d9f4ac38f09da03ff1c56fdefe16a855ac\nCT: 927fe3c924d914a7aae6695ddad54961142b7dd5ff4c0ba5ca3e0cf3d73bdb576afd59bd2b54d820d2a5da03286c124507a48008c571c28a0ce76f0ed68dbac3a61848e7e2162be8e0bee8147b9bf60da625cdab8601bfb37dfcd165f533e94a32c26952\nTAG: 9bd47a4a2acaf865a8a260179aabf8ad\n\nKEY: dec1b34b7b81fb19586c6ec948ecf462\nNONCE: d9faf07e72e3c39a0165fecd\nIN: f7b0bbe9f0ff4dcf162792e9ee14d1ed286114f411c834ad06b143cadbbe10a6fbc86f6664e0e07ff7c6876d4543e5b01ff5ddb629f896c30c8cefd56c15d9f24dfd2ed590304a6aae24caac5870ddafc0e672ac3aacae1867891942998c712d45efbfa4d99a8a6f03\nAD: d3c4fc4838cb3cda3937455229ddaf1cb9102e815cb9f519a5434677c68b11a0bae1280faee82f1a5bee593e669e6f81d5ece3675b8af63f1491bb298531aacc940f53678ba56ae96fc66be92b904bc35f2d5b68b3ed98569a4d04e8f8a9689ad9fa4b51db0938a9f3\nCT: 2f44ecf549077b98ba551819538097bb80304a55c48ef853e20ed8c3f808dc8cb5eb41c2463d19fed2606b59cee4b458958ea75715f7654146df4519dc63524a0569a00d7bbc4b32a372f82d955be5f190d09d35c267da1017e8b16096ae84f8a671b45aaf0d1ca59c\nTAG: bc3af80cf9388d35deadecff5455d515\n\nKEY: 021add6030bd9f3fed8b0d1f16f83783\nNONCE: 4e460f51fe6b5eb9558c4571\nIN: d9aa1d0db5de536cfbacb59bb75c592ae3f34a5f9c5ff4f22d14e8e4bd0754af19570221893797f60c89a251cd6a19c2953662dca51264afc21099ed5c80077b0e10a5295b3c4c6fe47d3c1c84fee69ebf7d8a7d9b1b338dae162e657e6cf5277ca70d47b9290aa7efe67b0ce574\nAD: 38d99cfd7578d40ffa1749d5fe83500362ceee76c5af38935806837b2f2d1b3422a5057bf617b07868dd95d8e5f4a24e74f96177d53a0275450b429a2b1f364805030765e376151ae35001d6a4872200142fdce82017f3e976ab0edac1a08d2649d297648320e7dd9143b554fa3d\nCT: 8863ad51578fd1c9dc40702e34236adee885955f0478ad9a094a6941f95f900e466882dcd5b86e1563ba89aa105f56f3ba5ed860ec3338ee1b750a2f9332acb3f0f61718de7e40fb80442d046b35f147f178bd05362f0559a20a53ebbf78e920fe14c9d80d1c9fb21bee152f8ab2\nTAG: 614539247fdcf1a2aa851102d25bb3bc\n\nKEY: 311c2045d5486bfadd698e5e14faa58a\nNONCE: f1cd8b373cec6451ae405618\nIN: bd154e428369aac5c13128d29bd3031364939abd071c34bacac6ea7292b657b794b2e717d9bcb5d7d01496d805283fffd8f7de6a3493ddd8d1dd7f58835a44d43ea22d95468d1239ca5567d6c80bdf432fce2afc544a731a2852ef733667b9f8f4f8923eaa9de3aa32addddf99b607efce966f\nAD: f70cb7e67b2842207df55fc7582013bbddff8c7f3bd9ebbaf43827aa40f8490e65397934ee6a412de6272cd568566ea172789a006a92e5920140ca5f93f292b47dc262cefc66b75543f94365c08795b7c5e9c6c29b7dc67b2532fbf8a6487d40a3eff504e75c3f2bb2cc3969621028e2112e67\nCT: f88f4ef0431d0f23911aaa38a4022e700d3a33c31e0c7bdebe00f62ca3b55d358385de25ceb0538242871eb9c24530e557d7981fa0182436e1e49272d52689541f09517fd147a8da0f0d2bb32d54911a36eded0b87bcba54d6842edf461b45839df1cab5176e2c82c871b3be4ec1bced67ec5d\nTAG: ae8d847f106e914ffadbdfe7cb57beba\n\nKEY: ceab57de6220b2c80e67f0c088e97b36\nNONCE: 8cf438aeb0cb29dd67506b9c\nIN: ce2a7a5663449cf6e0068085e3c373c5ca6f027544e327bbc09ac00f1571268bee186d51a00bbc16da7429e4d3d5235d8d54ac96b6ecb2fb7d77a6e5b9e70d431dd4dce78ceb972e9e4b63059e350efaff841c2c42bc29c139b7fd070097556b6281b58e074d5271d9f66c6744ec6dd3b9db2f4a21aeeb7d\nAD: 03e464d111ac9228d39d22a00120c6ee671fe5bbf462b1ee3fdf348b34999518998ac4e175ed48189c29b49b5527c27c43094eecbeaeacd3cdb48cd15aa82573e884a7b97bbcdad610a6955f7d8b04f6f98a13a907bc2bec4c940b77582b248f5fced1771f810977b2d0a4fa48bd4d78e4bc383bb92743fd\nCT: 1fa9c379c78b92fa3c1e478443ae38d7b4b50235448ce2a88467514bc9db95844ec1baf4dbdbd1b0720e377d05d82c3b58b52af8c9c50417b39ad225e373c7ff18ac5a6ea5d182b255f1c8a2766e31e3e4e3d55dc08dfc64b818ead40a0e824b06ab24f0dc9f4f0c383db7cd4d40016b31701bb401b126dd\nTAG: a9a885578467430504731d1a8f537e3c\n\nKEY: 585bbac0ab4508afb8b72d84167551aa\nNONCE: 774c82af194277a5506e45ba\nIN: d788112213d2b8b5b66b056e8b3e344a7876f6193b59a480c51fc04d3ec2e5166344c833187b14117276fd671a20937a4553181c29d3d85afe385dd86093708226f082a2ea4ec3288f372c772ca7ceae86b746ff428e8add17b0f34f8553e3db63f55224c39edf41f138a2c28be49d56aa8b4c93502b9794a16310f78b\nAD: a29665261a8eb58c88803bcf623dd1a14e76af49ec5db72a267f2ebcbc479385fb6b32bafcb1239515d74a8282b228e83daf282d1ab228099b315bbed0f0e6b3427e029cc28c025460a8bf0914bd584c13e7de7830ab77fb4a9258dfdc9fdaa96ca941546477f04cea19a365a27de34e23e154e7419aefb0be0e871bbe\nCT: 24f2856e4e40c0b2b8b47e43d94c1faba498884f59d2ae1cdf58c73770279c96feeee3025ec698cd8f0ae25bf0c9fbf2b350674c317e52bad50aa6ed9845e194f294eb71ff192604af50ac7192f308583a3edaf6c7aeb588990be81b801dc916ffd621dd4016e2b76e9078c89fac9da39f3a88f6548006a48b0199a732\nTAG: a5c8f9daa30b045bd3e1c1b01f438518\n\nKEY: c5d727d159dd328b4160ff45a183226b\nNONCE: 881c0802db519ce1595573ff\nIN: 88b4be77bb8a2f37bc5e84ef9da92a4b8c3777dbcccfed13b97e93c19674c8c3f13119363ace377a14e5f36501ba9a3898fc09340886d91bf0a17ef0d028f2a92ec150071623a4a5db8e56e99e764629679943ea879ec7634fad1480e8617fe834c26210276d7db208b13f9b4c2060f2867aacb1b47c8e110830beff721dd8d120de\nAD: 5f6513ad3d490f784dd68ca1df41e8c8e1ab9a240ea8e9bc22d0b1d7353da94d5d37c94f0dcd1a2dedd6d8e1c79a383e7e214cbb6ee2ccb7c6d894ffce5d01b6cf13876ae2648d36adccd88710d7d2ab6d43826d37ee0ee3b434972a2cb8f4db1c3304cee0a352bbef76f05de0e6f55a410eea5e697afb197f2483f0200d0abee224\nCT: 66bbee209eb11c675ecd3303c38cf1087b010c532e1357732c4911ca9db78c67805c95c829194cd413b635a900a08454c6eb9cfa3597ab531fc9ddfdc5b02b290be2a618df7d03b1ab465d6d03e8b87a430bf4e80d8cb9916145cf2d2342a91fc79defa151b1f3c695608e76ca2abc4c0383897f1cbb9d4bd9969b2f33813e2b5502\nTAG: 43daa08e6eac70e3238ce655adb65005\n\nKEY: 16af56326046c92afca49fe173d643ad\nNONCE: d32a935b4e56472d92d9f2ce\nIN: c49c8e5769670384d23d9af9834026395d3f3bd32d88e61ed06b2e00e52a5ae4fe3867993c2af95203cd4006470a89677864431fb9edbed17412913bad4bb3eaff0fccaa150c9b13f83b9bf06698af844841a640d6f94d845296638ac27fb5ed87c310dbbd36415161310b284b8f84b4e025267906e0a4c822b76a682d44a70f9afde9bcf48ac2\nAD: f713886f4086026779a7e479fa646cb33574e6c977d70b8da49c8fdbb395dc7c149a59e219db8e4fff053cb00e2a1df9850fce94e52fd34661fd3d4cd8ad3ffe0b4bc7ccfbbf42eeef3e30ce13cdfd77dbd067ae9f5aebfa068f6b7ae2c17ad956dc03511dfcc38eac9fa3c0c0e9a340f5c58e39d868b77dede54fea1173216c0bb8f0a6c2990f\nCT: d5d7d1ed0ae3e3481e2ccee201857ce1f427734fbb4fbe82a2b90601104008b8ad4daf74514b8ab3e42b6f6b509159ca04489b1175ce1e3fe33d36ea521e0aedff8c69fd00aa588d7a2eb9d2d551e2b8fea321f573e2a1df147535a873d540a3169d3ebc099ea6c33cefc04a2d55dc2d47237b95ad269fcdcd3c3750af426beb4edfe7837b413f\nTAG: cbe0fb9509c224bb0e8e33f7ef9b49e6\n\nKEY: b3df227e6dc2c846095e2a3b825d7645\nNONCE: 578bc24ca3845e23204df661\nIN: bf69be81cf0b340b006badc9f644d10376f4f9a7a78c997edb8729e3786447f21e97e4c1e0c0c74e01ef655d0a84ffc04ff7c6712ad65adc9a0da2e3078d4c9e796c9bcd71e7a9da26b987990d366b5e00a23a93652e10942e07a6aa01375af27080c9cbab5f554497abc48260937a6fe895361e79cd3d5e78c1a65c6723d4a4fbe9b3dcae3c05699cf6d3fb\nAD: 00898eedad307fc017917a3296bcedabaad8a505edd34e93d92f3b61797ddccf3fc31144ef70f255be3b0c165c97eb8706f14c495f4aa9b3f15d2dafd65bf6741d67fe240967efbf0e75e610db9a8f722035e039b5e9246d258084a04c12ee8ad1668032f8caec737481fd894dba2ef702d3e6089acbb0fe0bdd6daa2a5cd47fc62603499fe3ea37365072e5\nCT: cfeb249551a695ddfec5f789e7f0a9f916abc8ee01d6233c32744c10a09b5b19ff9ed15e9f10de8f93c8ca1ae3c34e26fdbbb7f3b0f5f8b064501830d3cc982da99b294ce51bd33085c98b0ac0bfe44a8f4a5a26511afa3461aa88b770f076fe119ec90f33d8c9e7777f30b8cc95864f06e04dd8e328ad7a2c7dab83b03abfdde065bcd0c7d6dd47389108c4\nTAG: 3dedd1054f1a29286a51817264317b83\n\nKEY: 58a57f04d1d5cbdd1bfbe01dd5f7e915\nNONCE: 47affabd7dbb4cce76661081\nIN: 5f82d481a6a3856c6f0be2aca54d666f16de88294a4d763134dd51ef03661bab45da94b9871d94e5b574a52214b22c92cf9690ecbffca9b108fe796abed9e608778c0b99d7bea1daec08dae89d5f7229c04fd52cc906b5f5b9fc0f0fc1e0b2272dcf4865286ee22bd9edcce1afadb579ec72cdf6038cfc75c2dbab5a1fd64b6f8e200d1ad0afcf25863293fdb7276648de\nAD: 4b662822b48005fbd85bb99e6a946eaa74403909f646d914a236eecc5f4558b60b2efb1584b1f32d936b90428dda6568515801d21d24d6fb622e6463897c70be01f81fef741d6dd5c6556d16", "3c3f048abe49f21817b41850ce79d7ec1fdfeba32935b58d898e964fa4b36f79c0f1f560b0afec3887ab325e1a025fa7662f9baf8e08a9ee714b8369621a2f1e6d2e96896a\nCT: 31ab08ce0aaa883628f4b33369e5f6e5a54ee4a6596f25ecd54eeea30e81b41d357cb6c671adb6acd3d4e6654feb2ab1f3259692502efb33c5121e0852cbcb2dc5d9a4c65752debe9c4bf5e995fc909a2881621d46cc220806703795e61c0fe74c99e3c1230521b1f97bcbf4e95326e2d581f0cc879a2fc06ef88226a4413f9e9985edc913c418cc198c4df13cd46afc24\nTAG: 1e54066c6cc37f35c62b47426b609457\n\nKEY: 64011470970333b7b677d4ad8ebf3ea2\nNONCE: 17031c5133a426d96de93123\nIN: 882cac1ece2d22a1db7f8339332379eb68516c8b7dcb3c089a5bfecceb49f48a169215313686eb5708135f379d89962af478cae865841e0c97ab47a57a456f634282c4e03c99abf7f7cc4e8360deb48160288f06e96cb09114877f9d91dae98828285626a1528aac87f39cfb8ad3db344fe4318aeef6f6ba14bd1edf9caab548c09f8eea091229a90dbc4b0fa34fda2bf13d300a1f9c\nAD: 0394bb920cf58806b909d90c046402c745f6876af85d8a281081e22a1908f8475126594b39a0e191a070bda7c78d30dc4867e69ea522cfc962fa5f9915daea9133e998eab22f32a18957a3cf7d91c6f3d54cea94875d60be694ee841fef01e69bf5997ba4f25e846558431eb592605265f235211c2bb2d4807278f4b9c314039d0768df24e9c098c6a01c689d6a143073fb1a29f4400\nCT: dd347d6a3d4a71b2bcae0a0c690ca311f012c6ceda4f7fc054b8f9b59bad54237b64b93331b99f1305801640a68e7d50cef581a57ff2564c90995a8dbf57fa8cff046d0b946af5f68e0aa3d73262965622fe6d35c78f949a6cf9e4f62ba71accbf403b690e31f610305faa6737a19efba1e1ee97084cff2d125bd69a5a4ff99aa399df650452daa835b3e54114b295f00d94fc60e2f8\nTAG: e5e72cda6755bfb3a44377945adb5ca1\n\nKEY: 4852e546fdea545d7dd12493a687e895\nNONCE: 7a3e136cd961191570c1b0b7\nIN: 30c10d7a63b614bcae1b79b07c252dc55f322554ac34ca664910fe4a0c9a33e30698e124d91cbb55cf34e931807cbe591a87667f2284c1c18dacd108163aa7a82e274ae659c4ea144191e3fc0f82d4cac929969a50b98ed9fbee52cdf465a1f0535d7d7df15a9a6eff3f4a14e254571cc47f82716d7a835dfa839213677c4da8c8623517244891993ad5956f65d318d9bba16f1eb54d2974a741ac\nAD: c5ded7f545d2eaccbc2cf5cbd1b38b0ec3b6bbc054ba25a16efdd448e5a47b0085974e469c1b0df22441340170d6677f5158e4ccd71446d7ac73dcf5fcfe4ad7248c4ddcfab4c8ccab0968d74d66d9c9561650eb98c088d87766440fc9967e8463febcd12ed07f7e44fef47cabf05274002d0014c4e31f230a41171868db68bf5a83c902724397ed181dd8c6768a898e0c78f6aeb886df95442e99\nCT: f798de4998683da7fa9ca030a23dbc493f36c48bb52cd1113c3ea97ef2b67433c00195000777fa3b75a3f689a66b148159524a1fe9576587948760b279cda56164a23748564ec66ea51368ba2a900c97169eb33cf1e557f46100193575737dba670175035f0d921675d45415c6591cae079698e6b1f74e82d4b9216c20e907b148a1d514b2cf653d2e4994f7f668dcfe88dc49c29c544de96d8dd0\nTAG: 3663fb2672223154981b4c580ed3d2d9\n\nKEY: a65b520a2ab67a24fb8fc669c41f2753\nNONCE: 3bd6c7e8d29242abecc4c108\nIN: 9d1559d283f7a38847088116f2156b19a8feab0731f04d0d499c6b0d21b8563a89a9c284230c1298b28a622cbdd38dbceb098ab896a7259caaabfcc7b0d9ea797178c18aaaa351c7f516342dcb9d3e91405882c8faa9a28f7c67f3db8913b31c0dcd56472d8ebbfb20cda2896a66bff2706b12ae0d9bc8c6c123c02f1f0bbaa418c1806482423eac72d718cad0dbccd208eb81663a9d9043d6ae7a52cf32b1fa\nAD: 2538529cc6eec03f70df2ab085027ce015279484981422f31e58aeee31e79703d72752af2b8822dce9b385f1530f19e692e00e20ef973d333f4bd585ecf122bd4ed9b0626cef46baff0302c71411d27e372361f36c7245096faff21f0236f3dd675646760d5687b3cf1544dbcaa863f1267bce04bca976616b890c7c6ff3448d16072c3938f9b62377609950ff7818cbdd21fba2560bf1954a93517962181b18\nCT: c3194fbb5c319a94c0f61c432a730ce7611a005cfc78266ac4e5d7c95351e71d613f06f52d9d008b9d886f4d9a57bcc232d47e0c75ab755dfccc057a9c7558d7fb696a8c29843a8b9199e2406d23cd6507d35a872fa54cb95e2cb9af45405ebc6b6ee353e8a80debc393329bb9499c61c6344a6380c118f30fcd76376a9765517652e1b21ecafa63c0d19c1875658f1eda89c15ac2daf1a6f526ca72ee792a4f\nTAG: fc16cd532c926ba01e2e6b15327bfb3a\n\nKEY: 84215d2c8f86e5b7bf93cb0620da6bb7\nNONCE: b35e99ce89dffd1ec616ed92\nIN: dfe500919f97713f6d9c4f53913175b162b8b7587d85d5b63f0cd5f51def23119e2e02c224142ecfba7f0a519aaea3c28be20b9c2a9c98eb145afd4db523b7f0b822e67dad630846b2a192bb146dcbeae00198c81b80c290d881125c24a6b01ec901b8912bad5b081ec7d97d6997b33052ec287f692489df928ce36cba1e3d6a41cf10c697a9e1f4aaf75dc5be054b98965ec3ce173be7e127c4c5387048ae6ab5a8d247f3\nAD: 6bf6222e64a46c90f83f47305554d090bc8d3838b7a856f0e5e1d92c4e7231eda6af1d9eb7ff6ce914f2256a3b0c853453b9bc75e46109cf8d7e8a9dca224e022d3d1a139d00476775622799541edf9d53eb645a40f6d98ea559e181d96e4df0141e51fe067542300581c0424f534d2c2e3b1b27153c0cd496a1c03301226beeed2b5cce0710d1f485e68b44a918b63fd8db610c7ff894514e272b6ed7ae33a38907e0698b\nCT: 6c6faa54df62ba5659d45f64a5f014684138c93bf152da8a495e9d067b13a30b9fb84847f56231b2da4d87e6cd509a3e38a9ff47589c627e5b5a1196e27fc7afaa14a8432c2d10d8fbfd5d6d394e4b947c456420708a76c2aa638df7de119c160636fc8dfba32227c5de12e5ef429da933ab04e77b489f2eb761d0c753738647ad6793cad64b8942f621ac67b13bd0cab106ffeff21f24c79de69424e50ae550f2241d4029\nTAG: 202b232472d050b9bbc68b59a0c02040\n\nKEY: 7c02b6bc3db61e23736c5f36faddd942\nNONCE: b958decc680d5f79ea7b8632\nIN: 7e5992ed0474f4224b8da1d038eeb78413fc2f9614fab7120043e75986a4bf1114a80703780a149fcc8dfd115b768f45917065c85176a3f00be40b427fe3765d3919a5b741708624e29bcae876d251fd46dd8d36a8ef66f671c25f984761cf7f75f4329de7093937cdabe32f130b77531ab1aa0a1bc38fbe2758c2664eded828b2589fc5c34d9a0d57a5a4463163736f419b65f0543f50207fff4cf1065a551bc00ffe9466538b673b2a\nAD: 76e430fce1a7d8340104e6001f1c2048d457ac335c5453e48727244b75c3c4f04f55afbb5ce55ba6f8632dbc168ed715b83968a32e5b8e91cb24abc9efee6dcb7a8bed9394a546f0b9efc5823ecaa192df061eb41c671bd863498c2130f322074a711ee43791a1cc02b5cacccf25119ecdd99233abf3b131c83ddb8c62c93a0d653e91499e7481303adc8dbac615ec464eb8640ea138f6236b0ee31cea060f97ea9145a22d15e28eaf6b\nCT: 14cfd190ae0521f94ee6b36bfcc403139782bfac3d33fe95c81f53e83c7d0c9a8fdebbddd79746b550a383ece1b5c93316b2fdf5aa36b4e97f739f78ccd2de9963ee7fb4d77b581cf676bb679b2dc4a48d977b45564f21181dc60ecee84d736f2324196c20327495d18973660ccb5dae69b79853d12e48ee0706c8ed821b7f722e46f35c8dee2b7b55ebee01dd3ea1e8ef80493cab6b27c264a67596cee06c15062e3a96b140d0d9ba38\nTAG: b6c47410e6f4a2f2b172c6a4490732f8\n\nKEY: 1f58ccb33649d0dc91c50f2aedc95cbc\nNONCE: b3a392b1fff0157e95f82a44\nIN: 738e04dc5a8188d775262c2cdaa04468844755dc912a4edf9db308efb3c229b8e46b2b34aee2c6330219bcd29d3493e3cead142cef5f192b043502b8a4cf0419f9b3f5e001a640541c84141e36d585b05a2f702356bd39bda518c42b461564326969983d22c3ac5a2aa214807ede803d57a61c9547505dd7e08402cc43e6ed1574a48366cf5b5573afcc7aa3c4d4721b362d20a58cbf251315f2b5f9e2c97c5ef6bff44beaa5004e5b7c7f28295df2\nAD: 93f7f5054605edc769efc30b35018ee6c929a83bc6454352c69ba9c72e4b4ea6f51c9ed06f314b5682be6a701c719087765d0a7022e5c9d495f28a9053bd435b8b834045c3670856149b08dae742b372a15a0184375d50eb09877bf94f63859e64228606791c516e76c5695a4e529b9dc5f76eff1d4641a22597e4460aea4eff107348077d4ed2d6262744b0a2d6610f25264d905133309ace10bb52f7138674c25e5d43ededbd87c13dc8fd9d3b1b\nCT: a002b47b18d1febaf64842fe9011484d618a2e855c4efcccc7d08f02dc9b53d0bd4fc8013e01e21fbf2d9bc7fdda69e68be0c06d32003d045dca6bd251c0bb8c2cbe3693b252265c8694295772b767f83661ecefd57353f6f1c442f9d21ed98c55cbe1db8171ef7b54fe3e3a1a253b4dd48416b5fbc7c18d73692e9fc90dc75d4b88de1fa47c9ad33ddfa4e582d3fc61ca2a8b1eab898b9992c8e56d170730454ca50cd4f28d2759388cb8e302be10\nTAG: ac502a9a52fb3a68a7e90dc639c7ad42\n\nKEY: c67510714f556ea1744af9207917eb60\nNONCE: 71b347a21653cec3d113087a\nIN: 7040fde3513cf7f1886d7be9c0f371a3b75415e94c3bdfbef485081199bec4494beeee76dcea05b6601ebd4c8fe231fa16d3b0f046eb3e9c9ed8baef25bb0ff6bc85469b2eb41b929fe904735f819b241b01230c68c0b61577899426bf0dd30e085cccb4ac290244d8c1cd7514412a3ebc51aecb6bb4be1a5a4a8d2ff3fc99191f7d7d0b44fe2cc4ec34deccf901f54e3dbe19d2dfe663855fa9d93a01ab14faed7f00c14834f63e1d153441c6fabb3cf22506e8\nAD: 6d28b410c788dba025c387f5b94c0bc392c69ef646b9cdce53dc169326359de26a721703d9a7c5017631a469da13b2d9ad9115de7d06922ed6f093792ac25ae2e27993ad6be5217dc4f6c51e18f230d4eabb01a474704b71b1407d9cff921bd98e28bb60c4fc019b4d609667c747e83eef779ee62000b6800ba2666f415dccb12d43af4f585d3185d66ba2ecf0b0fcddf762445dd1b6154591dd069f03977243b45b113b6f9b110f9fdd96f0b74e2c9843a45c6a\nCT: f2a2cdb4f890241f44e00b3373769542cc3dd24c3d07502ed162dfa10be9906871051b991f36b2d5c4240df483c2ad704be14b9efe79ca704e8eeb9dc250e75a92ebf5800c59fb9a6a32228fa1121d21e0b423b77e20010d36b9e6c68dbc000f69bddbd521a1f7bbc9d7e431e4e46e5094be96a928c6729293d2d805c468a3993fb7439f192b1142272a78585e3b7fcedd2f7cced52ab2bc42e2521603b89ba76", @@ -399,14 +458,14 @@ static const char *kData8[] = { "397440f1a4a0c7c9c2773c0a0cd3b890effb010dbcc00237dbed1177b86bf60913309bfda9376b4192da59a360afc5bcfaf8be16ea8313de97b417aaddceadc63a1c3a355693616413ed4101ad68f6e6aaa99c839dd2a9ff536\nAD: 18e3195358bae4ccf43ff8daa34902fe48f99fc1371d34060aaa442a43016a1d756f795fa5c9c4a828525554571e18c27134f46094790dd1e68471ee40c17bfa02f175b2c2f7f2aef20f00e4d71926560b58f015de19c871d808acdd341675d8fc19d1e6d4028e1e8926df500c4685c14729c6a056898cf919bf3ae429fa3ca8746495716d78c9a8f2ecde596f985b1c25ad0e73aa305a86259319176b4c4f3bb231fdaa478a856f46416ddb10a14ed23c96dcb86f5bea3114568a44d8fc6ff4bb47fd0e2538b70d964842910a682e7bc7c7263249832c21b7083a1e8b143828de0f3dea8b404cbd82efb19a11e4d60aeef13abd86621ccbc3d8f220715730eabbe04a6bf0e11a4f78cd2c4369ce2447a76f4fa48ef8d322a8a28a67039c24c4bfbf\nCT: 6beeb306c71318cedabe3877ec916ce2074b2c3f1df887cc3a3e8019c10d353854b6b65c947359138d5decc62a42d50921dc8f6cf63a16062af47aa8cd50d0b2dcbc3300ba0d7d069a5e4b4fe03bbf7062c6001e276be116fdd00d15a6399d1b0db71c58f396f8bc7e51c2b1f47430d4ebd6c5d05328b29aa79bcb26927ea5a40c82715aa0e36cc83ca6d250812c1305c02ed4291a25762cd709cb3d808031b5f918ce253f622c1afcb83c43707edc493d18ec6f0dba4353a1cde7184db65654088fa13baf45f7643f0dfedf4058e6095156b791ed30827c556a7721658314356e7a3f3c62cd62fe938b008cda56ceca71442fa0ffeb78b13c5847a3ee9668bcd2a01c753bd797c240378505d1e8f2b8905428b23bf589de9af390f94f21630d1826\nTAG: df5a21a399354b2b3346a9eb6820b81f\n\nKEY: 06a4c6a8aa189134f5784a525d46ff10\nNONCE: 0f765d3893af99f5c3e6d9e1\nIN: 706b754094869313523493089e591d34868b708cbde9bd8b42cba8175d1fdb6a8769bb9ec156d44bcb8f9cbf2685a0dc18b5a802dcf7a12570bb9042a0aa53dfb19af8c0f13763f388d9626a480d6d435dd90fbdbb4292d9015a5633252aa0583498d6f7ec54460d8589c1d6a6d16a349d10ec6070e1cc52e5fb996f810d333675a7130e4f3db9f4db0e3fd3541d32e0b2efbd40ba70cd59295bc8d08481f0f137832b01bac1778ffd7450376e174067b3ec23d0495cbf936bdc176cabc3f42e2991947a4fa87dd8343c32fa3d7ac0e2d22660a0c128a00e1b51a8742fdb2aff44540e39e588c5920ea16293aaa522513c944d3b77f3a0e90bd9105319c170886202e336893d100b0a25aa609a49a8255f78233561f7b88256386d1c3c002c3ee68f2775585c65\nAD: 18e2ed6d500b176e49f7e1b5074c0b7dbfdefdf00a63d9fa2fea8c5e78a1c4ae00f17b23442933543ac864097629e112a099f3dce6d5beb1e3f3c8e19522c6b8f615cbe23444bc91a802edf8a08995a55125da805ebb073fd89863996ef708f7293069a744ad95db8c17cbcfedc331119e85020df8852d74b8092fd38ad424f3da41b4775beac19536ed801ac1069925b12303d8ad2c52c36ca5b4ec95e96f02ebc5725ee6cdc099e666d9055b789e39ded77a8fdca0fe2d94b8039be55b6a75209cbee4fc7864957402b50427db71bc75a0b1e3d2ed6ea20f12a980c5ee916067d0dde7d686570d075da4df7088fe5dccf0d440064a96998da6f318b603d513104c723f27484780bdad586ee358d821b480f9569e4dbdd1a45ab9056f8d8e5a879789a0d65338\nCT: 5f3627bd53f8da0bbe6f3c9246d6f96fe9abb91cdecf66ddd42f833d98f4d4634c2e1e1ad4088c84c22191bdb9d99ef227320e455dd112c4a9e9cca95724fcc9ae024ed12bf60a802d0b87b99d9bf22590786567c2962171d2b05bec9754c627608e9eba7bccc70540aa4da72e1e04b26d8f968b10230f707501c0091a8ac118f86e87aae1ac00257aee29c3345bd3839154977acd378fc1b2197f5c1fd8e12262f9c2974fb92dc481eeb51aadd44a8851f61b93a84ba57f2870df0423d289bfdcfe634f9ecb7d7c6110a95b49418a2dd6663377690275c205b3efa79a0a77c92567fb429d8ee437312a39df7516dc238f7b9414938223d7ec24d256d3fb3a5954a7c75dbd79486d49ba6bb38a7ccce0f58700260b71319adf98ab8684e34913abe2d9d97193e2\nTAG: e690e89af39ff367f5d40a1b7c7ccd4f\n\nKEY: 31323334353637383930313233343536\nNONCE: 31323334353637383930313233343536\nIN: 48656c6c6f2c20576f726c64\nAD:\nCT: cec189d0e8419b90fb16d555\nTAG: 32893832a8d609224d77c2e56a922282\n\n# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\n\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: \"\"\nCT: \"\"\nAD: \"\"\nTAG: 58e2fccefa7e3061367f1d57a4e7455a\n\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 00000000000000000000000000000000\nCT: 0388dace60b6a392f328c2b971b2fe78\nAD: \"\"\nTAG: ab6e47d42cec13bdf53a67b21257bddf\n\nKEY: feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbaddecaf888\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985\nAD: \"\"\nTAG: 4d5c2af327cd64a62cf35abd2ba6fab4\n\nKEY: feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbaddecaf888\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 5bc94fbc3221a5db94fae95ae7121a47\n\nKEY: feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbad\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 3612d2e79e3b0785561be14aaca2fccb\n\nKEY: feffe9928665731c6d6a8f9467308308\nNONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 619cc5aefffe0bfa462af43c1699d050\n\n# local add-ons, primarily streaming ghash tests\n\n# 128 bytes AD\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: \"\"\nCT: \"\"\nAD: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nTAG: 5fea793a2d6f974d37e68e0cb8ff9492\n\n# 48 bytes plaintext\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0\nAD: \"\"\nTAG: 9dd0a376b08e40eb00c35f29f9ea61a4\n\n# 80 bytes plaintext\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291\nAD: \"\"\nTAG: 98885a3a22bd4742fe7b72172193b163\n\n# 128 bytes plaintext\nKEY: 00000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40\nAD: \"\"\nTAG: cac45f60e31efd3b5a43b98a22ce1aa1\n\n# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nKEY: 00000000000000000000000000000000\nNONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nIN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af", "24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606\nAD: \"\"\nTAG: 566f8ef683078bfdeeffa869d751a017\n\n# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nKEY: 00000000000000000000000000000000\nNONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nIN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c\nAD: \"\"\nTAG: 8b307f6b33286d0ab026a9ed3fe1e85f\n\n# 80 bytes plaintext, submitted by Intel\nKEY: 843ffcf5d2b72694d19ed01d01249412\nNONCE: dbcca32ebf9b804617c3aa9e\nIN: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f\nAD: 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f\nCT: 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5\nTAG: 3b629ccfbc1119b7319e1dce2cd6fd6d\n", }; -static const size_t kLen9 = 2196; - -static const char *kData9[] = { - "# Test vectors from NIST: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\n\nKEY: 000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nAD:\nTAG: cd33b28ac773f74ba00ed1f312572435\nIN:\nCT:\n\nKEY: 000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nAD:\nTAG: 2ff58d80033927ab8ef4d4587514f0fb\nIN: 00000000000000000000000000000000\nCT: 98e7247c07f0fe411c267e4384b0f600\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbaddecaf888\nAD:\nTAG: 9924a7c8587336bfb118024db8674a14\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbaddecaf888\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 2519498e80f1478f37ba55bd6d27618c\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbad\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 65dcc57fcf623a24094fcca40d3533f8\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: dcf566ff291c25bbb8568fc3d376a6d9\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b\n", -}; -static const size_t kLen10 = 469493; +static const size_t kLen10 = 2196; static const char *kData10[] = { + "# Test vectors from NIST: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\n\nKEY: 000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nAD:\nTAG: cd33b28ac773f74ba00ed1f312572435\nIN:\nCT:\n\nKEY: 000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nAD:\nTAG: 2ff58d80033927ab8ef4d4587514f0fb\nIN: 00000000000000000000000000000000\nCT: 98e7247c07f0fe411c267e4384b0f600\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbaddecaf888\nAD:\nTAG: 9924a7c8587336bfb118024db8674a14\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbaddecaf888\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 2519498e80f1478f37ba55bd6d27618c\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: cafebabefacedbad\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 65dcc57fcf623a24094fcca40d3533f8\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c\nNONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: dcf566ff291c25bbb8568fc3d376a6d9\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b\n", +}; +static const size_t kLen11 = 469493; + +static const char *kData11[] = { "# Generated by\n# go run make_legacy_aead_tests.go -cipher aes256 -mac sha1 -implicit-iv\n#\n# Note: aead_test's input format splits the ciphertext and tag positions of the\n# sealed input. But these legacy AEADs are MAC-then-encrypt and so the 'TAG' may\n# also include padding. We write the byte length of the MAC to 'TAG_LEN' and\n# include the unencrypted MAC in the 'DIGEST' tag above # each test case.\n# each test case.\n\n# Test with non-minimal padding.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660\nNONCE: \nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: d88861dcbb\nTAG: 181ebd603365ed262b8f2faf5b86ab90a8930bfc0c55cb9f1c88defe20893b2d5eb8ee6809c2452f302315\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with bad padding values.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660\nNONCE: \nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: d88861dcbb\nTAG: 181ebd603365ed262b8f2f9292c597b813c031f09b7a7144e557dd\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with no padding.\n# DIGEST: c6105cc86e18eb8376c16ea37693db5c07b77137\nKEY: 8503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f0\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c748\nAD: 1df3f4183aa23fd8d7efd8\nCT: c90e0c2567341ea7e9d968dbde46ecb46ad78dc8be7d47672068de66d6e7eae14b500b94927f24ff6a4f7b07\nTAG: ec90d128ef465f4a3645fd0b2601fbe2b0bceae2\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with maximal padding (0 mod 64).\n# DIGEST: ceb2d295bd0efd37c6c34dab1854c80e986174fc\nKEY: 37446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d4120\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba\nAD: 2fd6773e0d0c302a5f47e0\nCT: 000893d3434c5be7cbf9daffd81f03545f735cb70d1bd16eab26e07da7ee29b4c607d9a57077d74437e5b01a89c808c7ceca0d3838e5c6ee9947f1d4ee1d5e5e\nTAG: 6d8dc4edeeea81cb503d7389da209ae335876393fdab048965c7eb1a1403d05f8ef059788d08c2e906444388fd416a87bf8706f78d35797453b242618f4a99f47c3756116ec0318d96435032225ff82b902b9b6985189ca438e466154ded91676676c645926e2cf8a5d6f3bfafbb713d646cfd35b091f68e5ac2e7ec10badf1fd80767e6953abeecdc89beb2180dc92be21631164ef801147917e0c8d7841bdcdb52ea03344ab5f2bf3d5157794f5be79f51eb1efdacc0b77b27b72e2ce03d05473203522e3c2c196390d77dc28a35951f3aebd72ee58021d55e521dd029719a7660408ed0da5ab41830102bceb514b0b172d0ee10937111edba82b47e719c3beb3ce49a665accdc1c5bf028d465b5e1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (1 mod 64).\n# DIGEST: a07054c760cc66fc704edf950201005031f3faac\nKEY: 446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2f\nAD: d6773e0d0c302a5f47e037\nCT: a1e92776d0ffcfed03d1be956169f606733755d5a7011620c7ced6a825d8e59627e75692a41a1f2a86e62fc6052873b5458616414584e36bad698cf4c44909e0a2\nTAG: 6e0b32528feac2d7f69abb480efc7aae6cd1c5f8a654bcd10ec5be08b58f5a2198bddd83439d69ba9f55408cdf087e8a7f33fca6859638c5a4e8bc6961afee7534d8ffd95249d554b02e5beb81100be5e10abf679300f4ba514c03f4fbbba3cc62bd13dc8c8b9a726a9f217446c6e3b89cadb40488b177926c88c9d22a6c4ad9deca67f0d976fe62cd24c3cbb2e51dd16ee2e7bfe91d867b77c77a9a65c387e2682d946e617d0128034f5fe436eb7fa88aca82526d71dfefbdeeeb5a2c15d57fce0cf12e6ce0b101ef92d9ca540447e0bb65bc04b6a02e4e6d9378c6eebcd6d530c4ae14243beebb18403e8bcd434c2d88cc121e2df182edc3e1f52b060b1aecc48490c6cf3260299449945c803891\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (2 mod 64).\n# DIGEST: d059c266cf6233af730b7a229b19356a4c6fcf06\nKEY: 6f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5d\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6\nAD: 773e0d0c302a5f47e03744\nCT: f414f0321370af1490839677747893befa438051fef5f02fef488d7b84dc03140b3a5dc3a57041be4c8b688633110fc07251d877de0d6242928e4d937e3cc58ed611\nTAG: 4ee98ac6f10e179314a251a9db190037c47b9fdfc66321d83a995f6dccc5259801b18c3f466f7f4939b7d2d7196e0b161aaa013721e81bb9707b974b904f670e4aa495357b562a254908417b65fa69e86c42b3efdd423838575db08465a7f4889c85201629f6350c0865b5b0cfbac4f51ea1eacc8f9768014975d780438c3bd77f7f18612080abdeac9331e1a068c8f3a345d0026c5723bdbc48643c1a733a5b7ca9078424522db9491bc38d2644dab2d75499715707cd83ed655343ca73672d480f1420754fbbfeae0fba05be3b5235a5fa48bda9f39df0b298351d8f4da3fb8a2feab8b1aca9335eb31ab03f40ab19f668bb864c798ae08de37bf848fe2e898172d26fa23f383787d7199a6990\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (3 mod 64).\n# DIGEST: 8aac0687e33041fcc18da154b41f20a6af2bfb28\nKEY: 5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd677\nAD: 3e0d0c302a5f47e037446f\nCT: b51ab2f8c4ba3e8638d454ea72da5e3cb15336c347c442b8e1ade85c5cbd0dde790dc707d60d452d5b88d72e718f13cd0e0f4c9149b72e8d6be869d817a3232513c958\nTAG: dc8feba112517f6a820ca12de43c5d64c51cca713d3702a2b4a5cdbe86a90946a7369ec26ea8b5b35df329bfc6e29ef50c2774649134bd6e3f3fb38ef13d9c7fbe066e9cac4fb88dd0c02b677472ebbb2d0679dffedcaf13fccef6a25aed3a272ec01e7680becf80a624518e1333d28c97487b06e0581cc80c94989db4e93489f3dece9eab6dbbee73aeab572d1ee7705d18b899d9c62d7a370311e64131a801400b580d3c8f7af88be485b84fbdd89f7f7dacb29afeb56658f3d8e49f27adc542e412b0fd652b9f60575bf61622d7306c54bed50b43d89cdaecf1981ede09f9ea36fd174118ac178ade5f26ba04fcbd2eb035f030e2139506456ff8d342a4e59bd55dfafebda23a66cacfe6d1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (4 mod 64).\n# DIGEST: 53658226c112b86438dd27b58a71f9e36fc73c1e\nKEY: 91d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce99\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nAD: 0d0c302a5f47e037446f58\nCT: 87bf1af7e4987cdab35bfe32adc6b1be286751426cf926217f2c699bc095bde7b6ff3d6cc96b79328ab776547c2cb756d9de8c1245d21619a51dba8364ef6914590f15f8\nTAG: 55b9a1ee198080846389dd088016acab73622b1e2f902b0776846c74d99c27e67c7bbb55b2ac0efff91af0f6cb2ddcc0b5b8bab768048bb1662bb343d2f3a164bd4ca4850fbf8111b29e9be7bb836e2a8ac50ec2cb0b1c4529e50904007372284ec9187ea27d8faa03fc9535ba744155d06c06a0a97d96c03de71c13c95f185f426615f1368be346aa5ebf80049ac6771763235f2ee44dc910a01035c53caf8f9fa6f51fe3ad094513a8db177b6a66e24d21e1e40a23aa3629fffad45f84a58a29ef9237fac5eb6f5deb3825de6f399e46b2b2b91faf64ce45d164155e4dc757f6005c7c3e7fb3d8829623fd7c6ca48b923be90c38f5209c6d94696d2b2b7ebc5dfbf2cfa1a37e8ed038e830\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (5 mod 64).\n# DIGEST: 6b7d5268b0b5037afb5be5af6a0ceb34e7656ac4\nKEY: d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d\nAD: 0c302a5f47e037446f5891\nCT: 44237c388c3d017300db0fc9827f9b575e59bd971a0fd89cde4aeb1763912b49d50e92ba19d7594ef6da27320ac2bd1db3bcfe56b68a9ea8e2347d69890fa1fdc8bed782ad\nTAG: c1068d84aa962e7b89090993378806194ffbf677e7a66524d2ebfa7bdc52d76d09b914168eec4a5fde0953d4567affd3a4e0e48190e7a84471efe8ad1ce577c21df93b9d641c865d90ea1e6069bd703c4ee372379a4ec94f7e99867179561d41e9053977cc985b98f7a9fbc675d77052809b89b8f23f993e191ed1a07f97b89d05de948107f94245f216c413288eb4e40f3cee9c00c15926657d9ef9187ab405ee8000b4bd84d", "5771464401d59156a97eea7b23b4a6e9f1587cd3b75826a621b699515829dfc57740ad5719c43e88d835e13ebf703a0966779d31dc26866e0e9d27e3376137c92c97af49a876eed425d3980f1904f013143faeccb4fc920185ec2325361e5b318434487f9\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (6 mod 64).\n# DIGEST: 63efe7af502231420ed5aecce9a28446b257828d\nKEY: 7df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8f\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c\nAD: 302a5f47e037446f5891d7\nCT: 2f25b5a3b01af5411466c8aa5d8ece037434d5e12b62306f2732cb063d0dcdfc2725e67118a242a5576d470fcaf9be6d811bf2789cc66f5561d0542438b5432fe713187a879f\nTAG: d80e1f4edc2137f430d36a5ac93680c973fd7c64a03f7c2ce1b7e33085fe94da70ee26f47998947310508448cc70daa595687eaa540e48f048132de108a045da6d71170e39bb45160a344a2fdb5cb56ab020b9c0842ef2a1a5c83b4d63359fb8d71506d1e611fafa29e77d0669474d135e37bd8aefc3e17f024093186ff80fef73889e887b8d6672256dd592946ea84becc08c29445c8d978e896b1dad5e2608e347e54a97f3f757d7362f95f4cedebed07ab45b05713f7119c38d15a0f22d4259893f5e2401267543b3f78b52d54dd2d608173119e2dc7fe01f66589628e95fd7528958e993b21e4db664b8cba2f776d5cc305c42553da936d580c17d6f5090ff04e106c6488b5b18dd\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (7 mod 64).\n# DIGEST: 1a555c300a1d1bd5b03cdd6bf2a678621624eb05\nKEY: f660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c30\nAD: 2a5f47e037446f5891d77d\nCT: bbf934979c5d9da5c8b27d0341a164d640f12956a392303b0f1665935b5c39de458f53e0a6f824cc56081db1615fc67ffff0d300d1564666b81bb37da59e4da30de9d6a19df74e\nTAG: 9c18b0f9ee6a167a23566325eb330660997193385214abaf945dc18fb8252fbab8330b9809a6f1b300ae5a0c9d841fdd6f77e8d65f1cd0b221fb9b94b5e5d7215e6f501f490a7fa0a754efa7f2d9f5b927a5da2bea736e73af067e5d988901032d503ef3ab89894d03e48a096e7c31fe64bbc2c13f02d878590659ee7606d9212898d4d246e52b03c5646b1c3fbd43baaeda6548156987fc8f490f5763da18198bf0754d20f16dcf7df6bd35ca4bd95cd5c95a60427fc541aaf1f6923ff150de825cff9900ac9492350770bdd13fc4d0ac858ccdf36efbaeeb572aa45ca5470a04a7fa1ce5954d58771730b7202def47b303e560e81ebba2080d044a0851043c5af1a05c30a5a448eb\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (8 mod 64).\n# DIGEST: de9156349b578f2f44945ec6a676a67a829daea1\nKEY: 60ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2ea\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a\nAD: 5f47e037446f5891d77df6\nCT: 9b9bb61ca4d5aab8d0342d2b174e8f39b8e21db0fb7146025fb298016df3bab4363bb47f5b1fa038587df98851d09d473a68c959ead8062c52b9d6de86bd6a0fc9a2daab4667c621\nTAG: 897472da6d837ec173c2ae738721306e8d3c9e5353b65d1ecb3be3d0039739de379c9b06f42af8e952aa9acb4780a6de888dc8c54fe9a2eec19ae4a864b3b9696d712153bb66c49825ec5c891e30915c4b7b66b190525195429426ad694467dab09e8c2f9f21ffae4d54b74c0c5ed9a05963651dfcb9560677693429c63f3024043385ab0a31066243d42b80d2aa9854005504d6c8b9b7f736a8731c5dea0f3fc9007aae0c6edcd0a91dd1bbc5750de12ee13d4a77379cd3b2c2bbac885fa17338011b7b81cec6711fd5d65178f20a06f5475e09c202deef57939161ca8ed3e4aa9b010277acddc4478d1afb64138b276e265182ef2dea321b4f136c5c439ef6d099621813209a43\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (9 mod 64).\n# DIGEST: 12812df3aa7f3bbc899f6f248f5590e02570c292\nKEY: ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f\nAD: 47e037446f5891d77df660\nCT: 33ac574b7962d03b7816c0199a7f661a485832b9023867a749fc4bfe8ff0485571744f801139afd8215863b23e2d68ee7a254c60d8029e0f1ee10a1b947a4984f37f98a6767f52661e\nTAG: 3ee493d8cc764880f4ae7fc3c189b95bfe11d89640e3c9ddb55b230ba0d142d53fe18be8b955cf0d0d237c3b295459fc4c723b27ba8a29ed8dd5c80fb9839e30bc92e6afbf28ef6f72d1c28e5452460f986444678e7ea982d8bae63b69788012bd43aa66e5a521840c79831ae74426fb16f0917c5d2747b9c31fe43ecee604f26afddb093a9f1f1205a4451d50080ed0a9208a88ed6dbde37a674932bca837c46dd8725982c2ef6ac54511151c4cd59e511ca3835ea9bdbbd2e0842dc9674a854b8d4b063d0685086cdf917a7b7983dcc28af2addf3bc302034e365da1a87334a68477aa34a3a878d926d4c17f50316749d917e172e47597d060403a0279ee68dcd864652f37c6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (10 mod 64).\n# DIGEST: f3c89f21c327fca4aa400fabea9e39780378e901\nKEY: 82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad40\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47\nAD: e037446f5891d77df660ed\nCT: 8517e13ca00214ebfc748efd3a233e8b64801dcce99f9fee3d271357220dff7b1678c1cd6392a6ade62146c0e783248918a7cb69dd26dea525bd9060f380dba75e502bdc19581ebc3295\nTAG: d1f1280699f5514e4a56b08a5c3146142ef8e44c18ccac74577ec0feffbc29884da82212cba95b31d8464954498340f35e9a3d84256e8628368edd166d4b429fcb76e0072d2f5276ed8dc7bd5f34e754f6577ba00ee7ad74e9c89c4f82af0a7716d6ac77c39643909dedcc9356ba42f07874031878229a076da9ac7b0e49b2d170239089ceaf84392e889e7bceb3e383d0f744e229c53e8654ef0099a11773885efc456883e4a973557852f70c0e35668f3f212260e131962087416e668c9f995f226152251f5873fb89047a9dfa65b9fd0116486092b1092c4ee33e7625772944c06a2969b162986cd46d2b4185af2658c25c69a7a599d17f37be0fe1c8250cd7df5e6cf304\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (11 mod 64).\n# DIGEST: e8e41988fad6c8b44c56544964cfe0a347b35b1e\nKEY: 933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409a\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e0\nAD: 37446f5891d77df660ed82\nCT: b1cf0005c93547664e09031d923c4ef9ad663a808189cd8aaa68fbada340d8bb13330499131ef3788cd91e9527702a2388802fdd2e91998a53ffbb466bb7e362d06677edd673cae71418a6\nTAG: 7cad97328236aee512598d1a4c7d51b2154218fddf0ef21724921c1afe61fed1b7a1d1b56b8099dafff77362c4154e4bd7089fb0908ab1de49244a053997a0d04229250e52bc1ecf4550da5753a35108b6752f907ddf7a77fefbdb5d7290b02ae231d019d04ad9a5295336639e7e6c81ea46863d2bc3c4fca7d0f3b05237306759b156ac1fd10b044730987d04a943f0f598704f2191f6c627299b92a2c01a4004111c21f650376c3f28fc9793eddaefd74a2bb3cc5dea73685c954c63b71f2924ebcf9853ff084117cc84a0785d96d8d55d02723a2082ecd8c4b49b8d4068071593aff50c2e08fe7c49f6de1d7586e299b42ec723063f2341fd9b3445cf40893cf8c2bfa5\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (12 mod 64).\n# DIGEST: d1c7b2c04dc25fe7b742a1d659aec20e1475ee4f\nKEY: 3f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae0\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037\nAD: 446f5891d77df660ed8293\nCT: 7195b9643e0f7a4293c865db36442d4fe2cf3ea2c648dc88cd5636fe5e6bcea3d1197966e800da8c78bcb8830f3fa97671aebce98549e62827adf612e70f946673b07e2f953c8fe5e0b97aa1\nTAG: 3a909a9fa57e720bea6251ebbc1a71bbae1fd894f6bbd16e11abe51bbd1293abc0ad4c152a08b4acfac7a65b723fc6bd6923db66bbf202e184e8dbba150e6021ad1310ab4752cd4ae874409688996fdf88636084db7762b9578bb0c98d77c5156a82a97a3f6989db2359d252ff7c6405bd4834708c88d4481b35eabe2f7069bf8bac374fa382f4225659b41dd2a8006c0ff8d7c77c8d157e0373f45fcc0abc804a9f8a6b816f2b729befd606dc61e7f763f18121f56255662e36d120b27adfc8e1b528bd8ced5386cdb62cc73e58cc7918d27253297e9cbb9c740c7765cb014cf7bf160cbf09e00d32d31d462f356791bcf1286bb9023254afa6c41fe3d165f1bf7e6c002ef64ecdf3b5e073fb569028032e6713\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (13 mod 64).\n", "# DIGEST: 116e20ff1e79e0af464d473b1e7c187f4dd66007\nKEY: 62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae021\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e03744\nAD: 6f5891d77df660ed82933f\nCT: 1d50f3eb1cd76d8e08a9f386db0cdc3eddfc694e8502ccae47ab431c2935fc461254b80386c87690b01c22f38ea9bd118d2e0ed316ac249437a3e9c30f6c1f767c150216ec90e6c8913ff3d469\nTAG: e44bfe162cbba654362d1c86088564b14120815f181932e9f111d6da5efb5f4caad61f1161d1d148cc429ad34fcad9128bab101c7cc004fb8f0b516216a809a6599b5144b4c5828cf159fcecac46a86ba0698a6e5267610bad10cd7ce9079b6c691c2ecd522dbe3563074f2ac85712e58cca41761aa94449199a8b440016e68eb8bc9db3ff2c2bd9c64d9d3c71566bfb5d234af1a144859431f16ce6d65b4cc604e9cbf4e5539c192f07a2981b55582376bedc07aa20f5a841c9f500915fef353c37446511da3affd743fc551d5c22454797b3eb957770f1ca16da138c71bf5c00ab7893ae83b3f499a2c42f55551a986555925337e0604227ebf1c65312f0b1a8cdf2d06b5daf3e5ea97ceeb2f33421d0b44b\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (14 mod 64).\n# DIGEST: c081d0d09b2c9eb39a372ef4a7b0246a0956b0f9\nKEY: be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f\nAD: 5891d77df660ed82933f62\nCT: 4d754c684658bcc89208bcd75f24dc8e18b70a28b8a2201535e60ab755fb20e1ddfa98742d257eadd02d96c6a65f880d058312311efdf67f9a106beff9f5ace0ac6af586aefbb5e8b4850e584bb7\nTAG: a9bc9bdf2c16ace8cd471c2bcfbc2cf933fc1886faeec62d4809ed5cc4dd4fcb6ca6c42f31bab300264b278dc0b10fe8a54005b590160b410dcdfa3db413dd04a72c897b262ed0fe4ad6683fc5229010f1d2bc939e61a2c9e0480ef3e03e90f74a3edd8bb523271adc45d097b197ca9034bff48677efa763e1ae7528d3f775f827b9c56ba7f042d7f9413b4c5d01972e86976ab3a398afae27faf3cd19ef1b24b5342f9d067e7702bf1ae9679540a72f7a12cdbfbac234d596856b3bfdc2190dff0b50f45b4355cfa25ebf8d1d16528fe6c4baf9b0e5a50f95c4091704e939c8ffe69183c2695ecb1f12f24fdf288a8e8bdf3fe510bae70c46d0214303d5503d21366c4eec24cc2808542a203d81789efbb6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (15 mod 64).\n# DIGEST: 6f7bb1f9e2772eb909c315e653e4737cfed78a18\nKEY: 8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae0211641\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f58\nAD: 91d77df660ed82933f62be\nCT: 25bc47e58e7d4f3a417c95768699c92240a2be0e86232a41fe02d64f66716023996772e1118be48e685042f989dcd9cdc574614c9c3989f1885b4b71dfd5b1c32c1321ca41ca1e6ff1828e677e30fe\nTAG: c96a78b9ca68054bc1ed2a150dff9f9585174f343d3df80350982002b4c95106b72813a90028f2855faef235909686607f39655ec48f4024e170c9f9574b0c81b63c8df7af6b4d0f0633853a09c334379952bbaead7415125f541a01e320c5f5d9806b71c3ba71890e3229e751f25ac82c245596b5fa688f1b13844d91169354bf0cc03cccf576c2216aeb9eeab33e2a9f8bad2145d36cf0e7585a02296a7a3b434f4efeeaa4d7ed65befda32b287d9d0946e25dbc0edc22de871184ae8c76777528b917585be784d5e0674b1e5693d0b8cbe8253f8db67c879e1d2b7ddd5df4777a15509f813eb4d0f5a935aa011daaf0cc1ba2ebba9a20a74847e9c53b648f6fce4c08b6e7babc1919e6de22210a6f05\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (16 mod 64).\n# DIGEST: 172f4992e692a88f49628e5d3937959be01aed2e\nKEY: c55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417d\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891\nAD: d77df660ed82933f62be8d\nCT: f1ab85a35a17541efb4f906e7fc85e64efec6ab40d59d3da920c4ec09797c3ad47820e9d934e51e3f4d097c4a555575939bfaeb8cfea062b64816a160d6e4d1ff02a5fded435ab9aa2daf22fa7d676fa\nTAG: 14684ce099f4f0e11e785320debb89c79c03e8bb8751860d3779b4b553f6dedabdb23119d2866ad63fc974a6c6442b734394cb6705309a4d3889e90c4a222bbd14624cd89a9c3f904367c418140375dd592107f839ca94d43d09495a8dc8273201bd8f5a447bdf57506421a975ff4db3aab7878ff18e5b73c8f072a8d092461257d0182710ee9df9f86ac5ad321eac7ee96dddb27ecf561db222ed1c7c183c2ecdf4c7f57cf295638de3c4176ea244100d51c006282e98af1a8fd540daf0ca6f2fc0b88c550b4ab638760d95f2f9d09612da198616cd13fbfa1ad12a3fd30ac9956491cb11539a1be43175fb1452393f13f8d03501c89cf5962730125a7e185dc089b41124fc1e7f69b1fad46bd661c1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (17 mod 64).\n# DIGEST: 00133da1f7c63fd5f0eec364e9a359be02c1d3da\nKEY: 5b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d7\nAD: 7df660ed82933f62be8dc5\nCT: 5d6bfe91cd2273a9b986397a38e81be5fbbcd0403ef51873c2c467a9fbadc7bf540e83c538a43dc0e0ab780a4c4b1f5b77ced74f65b61f8b8b58b26fa3e8cba568bb717dc7071bf82dd8c68b068e739706\nTAG: 2ab9e654859c35e065f763d949d43c65dc85dc5d918850809ad8efaed6569d4b3ad064bef3427ae4c3be571fb914cefe2362169bed5b4c0cb17d2106fd6993d20ab8a8b70edb5f5d59b3357c8499c36e2b0b67edf7f334ff02d599031f43252b8d30d39affbd2093a6687c771b672329e14901ad9128f063267d3ab332ea31a79d37cb24ad0fd2d07f23b13d4643d1d9c529e1dd0490c851b0009fc1192f2438a48aba5a39be2ee925b1a38647197ead5cdea3499daa5abf9f4503d3581115a6847363348d5e7933948dce867752cde69ecc401012674ad75e12245dee86d775989275a5fc635c66d42c01b7646e180d28798905a3beb210c049be35b522ad580e1ca29f81b9469448749fce961ba6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (18 mod 64).\n# DIGEST: 60a6821269be6c5b985576b245f106128eb0b325\nKEY: 436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0c\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77d\nAD: f660ed82933f62be8dc55b\nCT: 16e3c681ba1ece3bdbfb1da491f877e806ddac5f1ae96bc406bd195c9d48bcd4a9b700a8ced21d824bfb99eb057e401c3529818725b51e96c576e8009bfe4866e98f550a23ef4748ff761a4d1c44ccb5eba0\nTAG: a30286b3d06306818a268db0e5116abc2c7361c5a32d334d8ce5f4007aaeab750980018b435c79391151fdd33df2a97dc2cf62c4426ce45be43f7e4949be735bcd33f0e81cc6b5a3c2255fbac9ff5a8fd7e7b57554d7ef00640d92b605c9afb0c19dd5ca4c79c409d85c197e8f21d79e91df01a817bf68e8718bc771028c945471ae003c0a210c572b79d772560031b5d3e5495aa8d9bd6fa3f8ae9976ed7e7f8d7275030d2f12ed5ab05276ebebafcac7d0ca41f9d860583f800e4f1b9658b12fab31fd63f6a5e4b80463918f8295ae11d7b97f9b5f89b8166861aec8f1b1417163a6a8adce23ce66c9a4306acae7ca75435cbaece814d6010a3e335bd7db9783812052179d5337d1c353be6e0b\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (19 mod 64).\n# DIGEST: e2593f3b6741a9ed9fa188fc06efd057556ee624\nKEY: 6965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df6\nAD: 60ed82933f62be8dc55b43\nCT: 9b51ba0eebf72bbcd7a1b8452a49f30bf2d96bf0cde4d9e5efe7f1903eb4e09f53aec649c5a8ad7e7fc6c28a0dcf4bd3556f4377bbf8b3f9c79dffa5978692559f732c109a7a02390746f5975d5a0aac4d04ce\nTAG: 636f7bcc9b0b5320643f4b6acbecd60a0a89d2511621ab47fa4c9af610fa1ff9c6cc5cb8fb64493d6a4dca0e94a90794f31698cb1c5bb5658e8b6a63a2cc9b2f1f297240d3d6c62087e32f5d5e9f9d608eccf4b41253933c7391983db1138012a5f5caa5abde25c8a16fc33cccb0604421d985f198c48552650f5dd299bf9163c136c042c9a35cdf7120a702bf460d739ab264fe1f58453ff4990f7315379ff074e01730e7cace8d45a5d0355c0acc409db8fbc759516ad56818b37700548aca769719937103787311b6dbc8488d9e68ee439cec3075bafb725f44734326df9b10d6a4f7133ba84489a9985febc96200276a1fb513f8a3c062466cbe63e7ad668cade7ea70c3b8cd040a6162be\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with max", @@ -466,9 +525,9 @@ static const char *kData10[] = { "02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c2\nAD: 7f4372480974454879c41d\nCT: fcbf4939de59426da2002fcb8e3a4d07604a168e9ffb5f13afcfbdc45325e3ecf0659ea736f9dbf61cec1dbed1024eff9e3bcb721c28d004549fd84e2cdeae36dc5e5abba4f0102835740bb877858814fa38290344addefb47ae583171a510719d9aa18c8f8a5e01396fecf1a982e162edf1047f56e8e4a839c5560473f389a4c7ea8fd5e03c7f2d31ccbc094f04e2a510aa57fe30f37cda765ddcd2bec89ab3f1f5f2ca423c68664c3303520c71439230116409dd84b4a26c1a102e521253ccd455793b0d883b1569b5013653b1c606143fcba7252a70d2a2026b989d1f67fdd594d2b33bde1bf7ee9bcb6c013ea8886e0ec1341039b8d8fbb4d865754a62d0e2a1151c917368e93fed0cb29e2d63ae176cbd95991db0a2864b27b6cf5782093bbe0ae117c7b2931f678bcb07aaae3d955b61e7ebbab8e84442295700cebf1a8f7d846fe788baa0660608bcbfa59c4bc9e5d163654aea99635f9bb63b8074478fc97b4981f5e5d35430b1e18332370dc5f4e94616b0270112dc446335d10a169e8a6923765647607ba9ad65c6f6f008cdf041af2e136b398bd1d1f67044f8360d9c1e90012e594a353d8e45aefac62173fd1b03ee5e4aa6961d83cbf1096dfa02f36ef62ceea5bf88f95301464d0046cc8ae3bfa611caa0c63d07\nTAG: 850f8608529bdc90c222092bfab0239a3b07b9cb1f\nTAG_LEN: 20\n\n# DIGEST: e654b4c78e1c0061eea2996fc126c9bfd41eb6d9\nKEY: 3b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813e8\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f43724809\nAD: 74454879c41de9ac9f9823\nCT: 3a35e98cfbeeabc993af7e952b148ceb87a110d851bf2d036e5eed8482b39b881b3180dc50ce782a8cbe2c586863c5d038fc4f37d4a96ce8732abb984ae90bbccb86f7766e9712e43d3ec40fdd7a1c88cfbf14743908c78dd4c19d449db7557e0c30127d35a49503d8dce6c9a9e6f07e1c86d7e365162ec05a8b4ed301645f8274999a6c5beafc5b27dd68608aeb2efdd9cb00c6236bb143e7d91709a3fea0e865330680a854d47ae3b6067002a01aec6bdab9e60c19ca66cc39d4a44ada1e21720bd5bd87cdfb31b8a9bfac77feeafc9f8e92c4131d73a3cfb64efae2e8d14fed99c2bc88f63f88079d30b78df18ac03db855338986c0fd1614dc6afaea71130290bf52270999f3392128bc48fb0a6d6425c383b637f4c293e177f479f6a2d6323ed545bbd564f743850a121da96256a8daf163fd80835558b21e0286cf008e7cd87bab94222fd7faa395ee2ba19aa3abf5d000e7514a35357941b97e4ef433c30972e995b0991c862cefdf79712cbd3655ceb43e1e5f5b0d3f5e275bfad98a667d997333d704e4d70acc488b6829d18d1263b841307d592f760a66761e800b4676d64546a1d8630d97218a7c5f555d4a90cf58eee4bd1e1fc0e15f8f64d336edf9ca00183169f237a924e7efd5a339f3cc1bb90b4c513bb9969ecdc9beb5c5\nTAG: b24af9f27ebc204aace6315a197550907bf6079b848eb1dca1a96192ee7c8107\nTAG_LEN: 20\n\n# DIGEST: 654b8591c7f0506261713e9ce7a6fd24a6b9357e\nKEY: 61792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813e8d454817c21\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c4\nAD: 1de9ac9f98233b5a7379a5\nCT: 7e1b59c791aeef6577c7ac69f8624352b7c2c7d1c8b14a7a0daf8240cc9d71ff1298eebf18ab6d469e1a327bbc3bb539df445ddcf7dccacb54f0a4ce6cf18bec20101bcd62bb2b30d8426a1e3ba949dcb69767aab5b8d2228267d784bde55bf887403188cd39453d32d50428bb9846212e4bbd3843161dc830646ba6e251ffad5d1b382101c7a3c87163867391fe44a58639e8a29fbd34cce657d321d004f842e0efa9d4cf03f557bf07a1201ac36258a4810dc101c427e19bb79f0800f27732094ee1dbab2abfc061fd4a1e84b2d36e560a38465cd4c8bc04bc27ffe90f1ce5999fc78d9432ed98c8dac4047a61547b6205bebe2191782ca63e50bb29c9bea553f5de0e9051cef35e3122c00e0d3a2468ecb2a898225c5f65fae573b17a15e013655a2ddc62adfe61ce5a7e352539c6d27c9726d2ca5492ee25b6d8233e32383100d131abce97b33dfe18a415156917ead8fe854c53bde97c0202e782679ac46f05afe1b9ad6b41bcb65bc8a80682ea8092bba0c47a9a03d08004a11756d9274ff83d5d468475c8a4a56f81cd1367040a3f75fd998b5fb3380cf8c1630fdb948fa2d0930fa5b009abc755f4bf70a59847969500d43e2db40ee517c9a6826e8e3746b3d40f9a6e7b35362550cabfa601a887bfabfd28476b3d7eb8917d66bbe9d21bfebb5a\nTAG: 22e74d37769a86785c57bb760e8a28de7a7ca3207fef4e80c284b4\nTAG_LEN: 20\n\n# DIGEST: 1eaad32c8d0cefaa5e2c503bb2185a73e6387fac\nKEY: 16430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813e8d454817c212d3a0063be\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98\nAD: 233b5a7379a561792c0f31\nCT: 26234359615c88fbbf5fddd43d4832a57bda2037e2177b264309e2e50c28efc28c5ed5cbf6dea046a14caa64d499352ecba0eb2d4bd376c6b1e14048033e21b9ec63f500a70c53be60099d9c9e46ea8f250d3d20c834c3c0638a9245377fe2b76b74ea14bca6b4bdc7e8d86ca59f397fe72b8c4cbb8edc3dca7f9f234529034fe5f1441210a8ad9b4694fe013f7e4a906fc400a27279f2a1a31700750e2209f6296ed808c893a42214b46f765c9d01cee46df18b02d5493c3a1da3a6258e89e47934ade4da2fa9eef7f5b1887a60585684b1c5c2ac60d94a62d79694b063444fa36674ecde12095e9203d281da3118d058f547ede5e4b67a11ab55c1b42fe01a94a601ba031c5b0b4088563344cc28d640bf2e7c81a259211b130bb9ba9ad93090c0e11cc939b99046fe7f25132672c3714f9973513af628f21942da6b459a60e31fe1bb9bf4f6259d8c9fa07d796a264f94d64122d186a0220d9f44b040396c9c187d5ad1d806ca613a4d0f5038a8b77177f39361f9107bea7700ba835dcd38cb48a6c5af0bfbb07b7a2543f1c661", "f1dec06acadf8860fa2220c67bbc9c97c44cb7cc58831563153149713ca2db85af46932a8de891da1d4662e52ed5b7c1c15d5557a0930c7177c2046b50aaf14874512cd9ed62efabe5704573a4f44a4ddf71202a6ea8c706842299\nTAG: 8eb60165231c67e88b0abd1d7c1c3dcab1b7006d4d3f\nTAG_LEN: 20\n\n# DIGEST: 862c0517b3658e9b9cd27db608d49e24e9b4667d\nKEY: a058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813e8d454817c212d3a0063be26e0636617\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98233b5a7379\nAD: a561792c0f3116430e8b6e\nCT: 6f2cea3b4aa1b3ae78d31e47c0c1e03df944352b9bd5483cfc09577aab2095a0a7e977e9c1c6451625d85d162c1653423609f141aac93123b2a0bd093c5bcdd9a49b27ace4dbe6acb486446f437c27e619a0f69405afc83240f087feb029fdf8f3f25a8a262b4a3efc4bc80512a96a45cca61d46e42132abd34c2821e7ff588c742062c01eacf9d1689f11648ebe326a91fe79275b5b1fb2af4d1440ff4a9ad35381daf2a2c0aa928216351c5b89ea33bf225d34efd7ec2c81c5af325b138a5f4ac50c5aca196d1b32ce8352431a8f08cb3b59d2f8de5c850e2a06d00c1d7f7027b4aa6757eb0c9fd3035063669a5ff8db2402818c88a7137ee309ef2735dd575e43b7508c81306dc50da65aa2276dbcd98537636ef06d1736f14e2babbc39457dc8d101d22e5516d652151c2092812814e9f73dd6cc805e670ca36e62799b42bc07fa1d93b9332c43a4b759e53ae138fd2b2b419b21a332ea304fb7db57e860509855b2a540cc909aff57e1433f295e8052c7609a88170feb7623cee8ee651ae1dca4b1afa427e2e43569d5b7f2ea688d2e2afb33f1dc0666c4b0df8aee281cbcbf5e964beb3851f7b929e5a4e06766746f22d4fa1a32913c0f449b4da8aac6294348f711d4d75bca509516668944d2a162a53a31229528e54e4bfbe13cef013efcd6687e890d292e42119529c92c\nTAG: 76c80a678b6cd735a2d01acc18dbd90bc3997f57efc2c5c78c22fe4dd13f06fb91\nTAG_LEN: 20\n\n", }; -static const size_t kLen11 = 469480; +static const size_t kLen12 = 469480; -static const char *kData11[] = { +static const char *kData12[] = { "# Generated by\n# go run make_legacy_aead_tests.go -cipher aes256 -mac sha1\n#\n# Note: aead_test's input format splits the ciphertext and tag positions of the\n# sealed input. But these legacy AEADs are MAC-then-encrypt and so the 'TAG' may\n# also include padding. We write the byte length of the MAC to 'TAG_LEN' and\n# include the unencrypted MAC in the 'DIGEST' tag above # each test case.\n# each test case.\n\n# Test with non-minimal padding.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nNONCE: 0d0c302a5f47e037446f5891d77df660\nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: d88861dcbb\nTAG: 181ebd603365ed262b8f2faf5b86ab90a8930bfc0c55cb9f1c88defe20893b2d5eb8ee6809c2452f302315\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with bad padding values.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nNONCE: 0d0c302a5f47e037446f5891d77df660\nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: d88861dcbb\nTAG: 181ebd603365ed262b8f2f9292c597b813c031f09b7a7144e557dd\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with no padding.\n# DIGEST: c6105cc86e18eb8376c16ea37693db5c07b77137\nKEY: 8503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371e\nNONCE: b8da7dac997deafd64b1fc65de39f4f0\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c748\nAD: 1df3f4183aa23fd8d7efd8\nCT: c90e0c2567341ea7e9d968dbde46ecb46ad78dc8be7d47672068de66d6e7eae14b500b94927f24ff6a4f7b07\nTAG: ec90d128ef465f4a3645fd0b2601fbe2b0bceae2\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with maximal padding (0 mod 64).\n# DIGEST: ceb2d295bd0efd37c6c34dab1854c80e986174fc\nKEY: 37446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11b\nNONCE: e112a72933c7b54ed4fad0be905d4120\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba\nAD: 2fd6773e0d0c302a5f47e0\nCT: 000893d3434c5be7cbf9daffd81f03545f735cb70d1bd16eab26e07da7ee29b4c607d9a57077d74437e5b01a89c808c7ceca0d3838e5c6ee9947f1d4ee1d5e5e\nTAG: 6d8dc4edeeea81cb503d7389da209ae335876393fdab048965c7eb1a1403d05f8ef059788d08c2e906444388fd416a87bf8706f78d35797453b242618f4a99f47c3756116ec0318d96435032225ff82b902b9b6985189ca438e466154ded91676676c645926e2cf8a5d6f3bfafbb713d646cfd35b091f68e5ac2e7ec10badf1fd80767e6953abeecdc89beb2180dc92be21631164ef801147917e0c8d7841bdcdb52ea03344ab5f2bf3d5157794f5be79f51eb1efdacc0b77b27b72e2ce03d05473203522e3c2c196390d77dc28a35951f3aebd72ee58021d55e521dd029719a7660408ed0da5ab41830102bceb514b0b172d0ee10937111edba82b47e719c3beb3ce49a665accdc1c5bf028d465b5e1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (1 mod 64).\n# DIGEST: a07054c760cc66fc704edf950201005031f3faac\nKEY: 446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be1\nNONCE: 12a72933c7b54ed4fad0be905d41203f\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2f\nAD: d6773e0d0c302a5f47e037\nCT: a1e92776d0ffcfed03d1be956169f606733755d5a7011620c7ced6a825d8e59627e75692a41a1f2a86e62fc6052873b5458616414584e36bad698cf4c44909e0a2\nTAG: 6e0b32528feac2d7f69abb480efc7aae6cd1c5f8a654bcd10ec5be08b58f5a2198bddd83439d69ba9f55408cdf087e8a7f33fca6859638c5a4e8bc6961afee7534d8ffd95249d554b02e5beb81100be5e10abf679300f4ba514c03f4fbbba3cc62bd13dc8c8b9a726a9f217446c6e3b89cadb40488b177926c88c9d22a6c4ad9deca67f0d976fe62cd24c3cbb2e51dd16ee2e7bfe91d867b77c77a9a65c387e2682d946e617d0128034f5fe436eb7fa88aca82526d71dfefbdeeeb5a2c15d57fce0cf12e6ce0b101ef92d9ca540447e0bb65bc04b6a02e4e6d9378c6eebcd6d530c4ae14243beebb18403e8bcd434c2d88cc121e2df182edc3e1f52b060b1aecc48490c6cf3260299449945c803891\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (2 mod 64).\n# DIGEST: d059c266cf6233af730b7a229b19356a4c6fcf06\nKEY: 6f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112\nNONCE: a72933c7b54ed4fad0be905d41203f5d\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6\nAD: 773e0d0c302a5f47e03744\nCT: f414f0321370af1490839677747893befa438051fef5f02fef488d7b84dc03140b3a5dc3a57041be4c8b688633110fc07251d877de0d6242928e4d937e3cc58ed611\nTAG: 4ee98ac6f10e179314a251a9db190037c47b9fdfc66321d83a995f6dccc5259801b18c3f466f7f4939b7d2d7196e0b161aaa013721e81bb9707b974b904f670e4aa495357b562a254908417b65fa69e86c42b3efdd423838575db08465a7f4889c85201629f6350c0865b5b0cfbac4f51ea1eacc8f9768014975d780438c3bd77f7f18612080abdeac9331e1a068c8f3a345d0026c5723bdbc48643c1a733a5b7ca9078424522db9491bc38d2644dab2d75499715707cd83ed655343ca73672d480f1420754fbbfeae0fba05be3b5235a5fa48bda9f39df0b298351d8f4da3fb8a2feab8b1aca9335eb31ab03f40ab19f668bb864c798ae08de37bf848fe2e898172d26fa23f383787d7199a6990\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (3 mod 64).\n# DIGEST: 8aac0687e33041fcc18da154b41f20a6af2bfb28\nKEY: 5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a7\nNONCE: 2933c7b54ed4fad0be905d41203f5dce\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd677\nAD: 3e0d0c302a5f47e037446f\nCT: b51ab2f8c4ba3e8638d454ea72da5e3cb15336c347c442b8e1ade85c5cbd0dde790dc707d60d452d5b88d72e718f13cd0e0f4c9149b72e8d6be869d817a3232513c958\nTAG: dc8feba112517f6a820ca12de43c5d64c51cca713d3702a2b4a5cdbe86a90946a7369ec26ea8b5b35df329bfc6e29ef50c2774649134bd6e3f3fb38ef13d9c7fbe066e9cac4fb88dd0c02b677472ebbb2d0679dffedcaf13fccef6a25aed3a272ec01e7680becf80a624518e1333d28c97487b06e0581cc80c94989db4e93489f3dece9eab6dbbee73aeab572d1ee7705d18b899d9c62d7a370311e64131a801400b580d3c8f7af88be485b84fbdd89f7f7dacb29afeb56658f3d8e49f27adc542e412b0fd652b9f60575bf61622d7306c54bed50b43d89cdaecf1981ede09f9ea36fd174118ac178ade5f26ba04fcbd2eb035f030e2139506456ff8d342a4e59bd55dfafebda23a66cacfe6d1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (4 mod 64).\n# DIGEST: 53658226c112b86438dd27b58a71f9e36fc73c1e\nKEY: 91d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a729\nNONCE: 33c7b54ed4fad0be905d41203f5dce99\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nAD: 0d0c302a5f47e037446f58\nCT: 87bf1af7e4987cdab35bfe32adc6b1be286751426cf926217f2c699bc095bde7b6ff3d6cc96b79328ab776547c2cb756d9de8c1245d21619a51dba8364ef6914590f15f8\nTAG: 55b9a1ee198080846389dd088016acab73622b1e2f902b0776846c74d99c27e67c7bbb55b2ac0efff91af0f6cb2ddcc0b5b8bab768048bb1662bb343d2f3a164bd4ca4850fbf8111b29e9be7bb836e2a8ac50ec2cb0b1c4529e50904007372284ec9187ea27d8faa03fc9535ba744155d06c06a0a97d96c03de71c13c95f185f426615f1368be346aa5ebf80049ac6771763235f2ee44dc910a01035c53caf8f9fa6f51fe3ad094513a8db177b6a66e24d21e1e40a23aa3629fffad45f84a58a29ef9237fac5eb6f5deb3825de6f399e46b2b2b91faf64ce45d164155e4dc757f6005c7c3e7fb3d8829623fd7c6ca48b923be90c38f5209c6d94696d2b2b7ebc5dfbf2cfa1a37e8ed038e830\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (5 mod 64).\n# DIGEST: 6b7d5268b0b5037afb5be5af6a0ceb34e7656ac4\nKEY: d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933\nNONCE: c7b54ed4fad0be905d41203f5dce998f\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d\nAD: 0c302a5f47e037446f5891\nCT: 44237c388c3d017300db0fc9827f9b575e59bd971a0fd89cde4aeb1763912b49d50e92ba19d7594ef6da27320ac2bd1db3bcfe56b68a9ea8e2347d69890fa1fdc8bed782ad\nTAG: c1068d84aa962e7b89090993378806194ffbf677e7a66524d2ebfa7bdc52d76d09b914168eec4a5fde0953d4567affd3a4e0e48190e7a84471efe8ad1ce577c21df93b9d641c865d90ea1e6069bd703c4ee372379a4ec94f7e99867179561d41e9053977cc985b98f7a9fbc675d77052809b89b8f23f993e191ed1a07f97b89d05de948107f94245f216c413288eb4e40f3cee9c00c15926657d9ef9187ab405ee8000b4bd84d5771464401d59", "156a97eea7b23b4a6e9f1587cd3b75826a621b699515829dfc57740ad5719c43e88d835e13ebf703a0966779d31dc26866e0e9d27e3376137c92c97af49a876eed425d3980f1904f013143faeccb4fc920185ec2325361e5b318434487f9\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (6 mod 64).\n# DIGEST: 63efe7af502231420ed5aecce9a28446b257828d\nKEY: 7df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7\nNONCE: b54ed4fad0be905d41203f5dce998f8f\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c\nAD: 302a5f47e037446f5891d7\nCT: 2f25b5a3b01af5411466c8aa5d8ece037434d5e12b62306f2732cb063d0dcdfc2725e67118a242a5576d470fcaf9be6d811bf2789cc66f5561d0542438b5432fe713187a879f\nTAG: d80e1f4edc2137f430d36a5ac93680c973fd7c64a03f7c2ce1b7e33085fe94da70ee26f47998947310508448cc70daa595687eaa540e48f048132de108a045da6d71170e39bb45160a344a2fdb5cb56ab020b9c0842ef2a1a5c83b4d63359fb8d71506d1e611fafa29e77d0669474d135e37bd8aefc3e17f024093186ff80fef73889e887b8d6672256dd592946ea84becc08c29445c8d978e896b1dad5e2608e347e54a97f3f757d7362f95f4cedebed07ab45b05713f7119c38d15a0f22d4259893f5e2401267543b3f78b52d54dd2d608173119e2dc7fe01f66589628e95fd7528958e993b21e4db664b8cba2f776d5cc305c42553da936d580c17d6f5090ff04e106c6488b5b18dd\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (7 mod 64).\n# DIGEST: 1a555c300a1d1bd5b03cdd6bf2a678621624eb05\nKEY: f660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b5\nNONCE: 4ed4fad0be905d41203f5dce998f8fb2\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c30\nAD: 2a5f47e037446f5891d77d\nCT: bbf934979c5d9da5c8b27d0341a164d640f12956a392303b0f1665935b5c39de458f53e0a6f824cc56081db1615fc67ffff0d300d1564666b81bb37da59e4da30de9d6a19df74e\nTAG: 9c18b0f9ee6a167a23566325eb330660997193385214abaf945dc18fb8252fbab8330b9809a6f1b300ae5a0c9d841fdd6f77e8d65f1cd0b221fb9b94b5e5d7215e6f501f490a7fa0a754efa7f2d9f5b927a5da2bea736e73af067e5d988901032d503ef3ab89894d03e48a096e7c31fe64bbc2c13f02d878590659ee7606d9212898d4d246e52b03c5646b1c3fbd43baaeda6548156987fc8f490f5763da18198bf0754d20f16dcf7df6bd35ca4bd95cd5c95a60427fc541aaf1f6923ff150de825cff9900ac9492350770bdd13fc4d0ac858ccdf36efbaeeb572aa45ca5470a04a7fa1ce5954d58771730b7202def47b303e560e81ebba2080d044a0851043c5af1a05c30a5a448eb\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (8 mod 64).\n# DIGEST: de9156349b578f2f44945ec6a676a67a829daea1\nKEY: 60ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54e\nNONCE: d4fad0be905d41203f5dce998f8fb2ea\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a\nAD: 5f47e037446f5891d77df6\nCT: 9b9bb61ca4d5aab8d0342d2b174e8f39b8e21db0fb7146025fb298016df3bab4363bb47f5b1fa038587df98851d09d473a68c959ead8062c52b9d6de86bd6a0fc9a2daab4667c621\nTAG: 897472da6d837ec173c2ae738721306e8d3c9e5353b65d1ecb3be3d0039739de379c9b06f42af8e952aa9acb4780a6de888dc8c54fe9a2eec19ae4a864b3b9696d712153bb66c49825ec5c891e30915c4b7b66b190525195429426ad694467dab09e8c2f9f21ffae4d54b74c0c5ed9a05963651dfcb9560677693429c63f3024043385ab0a31066243d42b80d2aa9854005504d6c8b9b7f736a8731c5dea0f3fc9007aae0c6edcd0a91dd1bbc5750de12ee13d4a77379cd3b2c2bbac885fa17338011b7b81cec6711fd5d65178f20a06f5475e09c202deef57939161ca8ed3e4aa9b010277acddc4478d1afb64138b276e265182ef2dea321b4f136c5c439ef6d099621813209a43\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (9 mod 64).\n# DIGEST: 12812df3aa7f3bbc899f6f248f5590e02570c292\nKEY: ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4\nNONCE: fad0be905d41203f5dce998f8fb2eaad\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f\nAD: 47e037446f5891d77df660\nCT: 33ac574b7962d03b7816c0199a7f661a485832b9023867a749fc4bfe8ff0485571744f801139afd8215863b23e2d68ee7a254c60d8029e0f1ee10a1b947a4984f37f98a6767f52661e\nTAG: 3ee493d8cc764880f4ae7fc3c189b95bfe11d89640e3c9ddb55b230ba0d142d53fe18be8b955cf0d0d237c3b295459fc4c723b27ba8a29ed8dd5c80fb9839e30bc92e6afbf28ef6f72d1c28e5452460f986444678e7ea982d8bae63b69788012bd43aa66e5a521840c79831ae74426fb16f0917c5d2747b9c31fe43ecee604f26afddb093a9f1f1205a4451d50080ed0a9208a88ed6dbde37a674932bca837c46dd8725982c2ef6ac54511151c4cd59e511ca3835ea9bdbbd2e0842dc9674a854b8d4b063d0685086cdf917a7b7983dcc28af2addf3bc302034e365da1a87334a68477aa34a3a878d926d4c17f50316749d917e172e47597d060403a0279ee68dcd864652f37c6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (10 mod 64).\n# DIGEST: f3c89f21c327fca4aa400fabea9e39780378e901\nKEY: 82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fa\nNONCE: d0be905d41203f5dce998f8fb2eaad40\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47\nAD: e037446f5891d77df660ed\nCT: 8517e13ca00214ebfc748efd3a233e8b64801dcce99f9fee3d271357220dff7b1678c1cd6392a6ade62146c0e783248918a7cb69dd26dea525bd9060f380dba75e502bdc19581ebc3295\nTAG: d1f1280699f5514e4a56b08a5c3146142ef8e44c18ccac74577ec0feffbc29884da82212cba95b31d8464954498340f35e9a3d84256e8628368edd166d4b429fcb76e0072d2f5276ed8dc7bd5f34e754f6577ba00ee7ad74e9c89c4f82af0a7716d6ac77c39643909dedcc9356ba42f07874031878229a076da9ac7b0e49b2d170239089ceaf84392e889e7bceb3e383d0f744e229c53e8654ef0099a11773885efc456883e4a973557852f70c0e35668f3f212260e131962087416e668c9f995f226152251f5873fb89047a9dfa65b9fd0116486092b1092c4ee33e7625772944c06a2969b162986cd46d2b4185af2658c25c69a7a599d17f37be0fe1c8250cd7df5e6cf304\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (11 mod 64).\n# DIGEST: e8e41988fad6c8b44c56544964cfe0a347b35b1e\nKEY: 933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0\nNONCE: be905d41203f5dce998f8fb2eaad409a\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e0\nAD: 37446f5891d77df660ed82\nCT: b1cf0005c93547664e09031d923c4ef9ad663a808189cd8aaa68fbada340d8bb13330499131ef3788cd91e9527702a2388802fdd2e91998a53ffbb466bb7e362d06677edd673cae71418a6\nTAG: 7cad97328236aee512598d1a4c7d51b2154218fddf0ef21724921c1afe61fed1b7a1d1b56b8099dafff77362c4154e4bd7089fb0908ab1de49244a053997a0d04229250e52bc1ecf4550da5753a35108b6752f907ddf7a77fefbdb5d7290b02ae231d019d04ad9a5295336639e7e6c81ea46863d2bc3c4fca7d0f3b05237306759b156ac1fd10b044730987d04a943f0f598704f2191f6c627299b92a2c01a4004111c21f650376c3f28fc9793eddaefd74a2bb3cc5dea73685c954c63b71f2924ebcf9853ff084117cc84a0785d96d8d55d02723a2082ecd8c4b49b8d4068071593aff50c2e08fe7c49f6de1d7586e299b42ec723063f2341fd9b3445cf40893cf8c2bfa5\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (12 mod 64).\n# DIGEST: d1c7b2c04dc25fe7b742a1d659aec20e1475ee4f\nKEY: 3f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be\nNONCE: 905d41203f5dce998f8fb2eaad409ae0\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037\nAD: 446f5891d77df660ed8293\nCT: 7195b9643e0f7a4293c865db36442d4fe2cf3ea2c648dc88cd5636fe5e6bcea3d1197966e800da8c78bcb8830f3fa97671aebce98549e62827adf612e70f946673b07e2f953c8fe5e0b97aa1\nTAG: 3a909a9fa57e720bea6251ebbc1a71bbae1fd894f6bbd16e11abe51bbd1293abc0ad4c152a08b4acfac7a65b723fc6bd6923db66bbf202e184e8dbba150e6021ad1310ab4752cd4ae874409688996fdf88636084db7762b9578bb0c98d77c5156a82a97a3f6989db2359d252ff7c6405bd4834708c88d4481b35eabe2f7069bf8bac374fa382f4225659b41dd2a8006c0ff8d7c77c8d157e0373f45fcc0abc804a9f8a6b816f2b729befd606dc61e7f763f18121f56255662e36d120b27adfc8e1b528bd8ced5386cdb62cc73e58cc7918d27253297e9cbb9c740c7765cb014cf7bf160cbf09e00d32d31d462f356791bcf1286bb9023254afa6c41fe3d165f1bf7e6c002ef64ecdf3b5e073fb569028032e6713\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (13 mod 64).\n# DIGEST: 116", "e20ff1e79e0af464d473b1e7c187f4dd66007\nKEY: 62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be90\nNONCE: 5d41203f5dce998f8fb2eaad409ae021\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e03744\nAD: 6f5891d77df660ed82933f\nCT: 1d50f3eb1cd76d8e08a9f386db0cdc3eddfc694e8502ccae47ab431c2935fc461254b80386c87690b01c22f38ea9bd118d2e0ed316ac249437a3e9c30f6c1f767c150216ec90e6c8913ff3d469\nTAG: e44bfe162cbba654362d1c86088564b14120815f181932e9f111d6da5efb5f4caad61f1161d1d148cc429ad34fcad9128bab101c7cc004fb8f0b516216a809a6599b5144b4c5828cf159fcecac46a86ba0698a6e5267610bad10cd7ce9079b6c691c2ecd522dbe3563074f2ac85712e58cca41761aa94449199a8b440016e68eb8bc9db3ff2c2bd9c64d9d3c71566bfb5d234af1a144859431f16ce6d65b4cc604e9cbf4e5539c192f07a2981b55582376bedc07aa20f5a841c9f500915fef353c37446511da3affd743fc551d5c22454797b3eb957770f1ca16da138c71bf5c00ab7893ae83b3f499a2c42f55551a986555925337e0604227ebf1c65312f0b1a8cdf2d06b5daf3e5ea97ceeb2f33421d0b44b\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (14 mod 64).\n# DIGEST: c081d0d09b2c9eb39a372ef4a7b0246a0956b0f9\nKEY: be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d\nNONCE: 41203f5dce998f8fb2eaad409ae02116\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f\nAD: 5891d77df660ed82933f62\nCT: 4d754c684658bcc89208bcd75f24dc8e18b70a28b8a2201535e60ab755fb20e1ddfa98742d257eadd02d96c6a65f880d058312311efdf67f9a106beff9f5ace0ac6af586aefbb5e8b4850e584bb7\nTAG: a9bc9bdf2c16ace8cd471c2bcfbc2cf933fc1886faeec62d4809ed5cc4dd4fcb6ca6c42f31bab300264b278dc0b10fe8a54005b590160b410dcdfa3db413dd04a72c897b262ed0fe4ad6683fc5229010f1d2bc939e61a2c9e0480ef3e03e90f74a3edd8bb523271adc45d097b197ca9034bff48677efa763e1ae7528d3f775f827b9c56ba7f042d7f9413b4c5d01972e86976ab3a398afae27faf3cd19ef1b24b5342f9d067e7702bf1ae9679540a72f7a12cdbfbac234d596856b3bfdc2190dff0b50f45b4355cfa25ebf8d1d16528fe6c4baf9b0e5a50f95c4091704e939c8ffe69183c2695ecb1f12f24fdf288a8e8bdf3fe510bae70c46d0214303d5503d21366c4eec24cc2808542a203d81789efbb6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (15 mod 64).\n# DIGEST: 6f7bb1f9e2772eb909c315e653e4737cfed78a18\nKEY: 8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41\nNONCE: 203f5dce998f8fb2eaad409ae0211641\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f58\nAD: 91d77df660ed82933f62be\nCT: 25bc47e58e7d4f3a417c95768699c92240a2be0e86232a41fe02d64f66716023996772e1118be48e685042f989dcd9cdc574614c9c3989f1885b4b71dfd5b1c32c1321ca41ca1e6ff1828e677e30fe\nTAG: c96a78b9ca68054bc1ed2a150dff9f9585174f343d3df80350982002b4c95106b72813a90028f2855faef235909686607f39655ec48f4024e170c9f9574b0c81b63c8df7af6b4d0f0633853a09c334379952bbaead7415125f541a01e320c5f5d9806b71c3ba71890e3229e751f25ac82c245596b5fa688f1b13844d91169354bf0cc03cccf576c2216aeb9eeab33e2a9f8bad2145d36cf0e7585a02296a7a3b434f4efeeaa4d7ed65befda32b287d9d0946e25dbc0edc22de871184ae8c76777528b917585be784d5e0674b1e5693d0b8cbe8253f8db67c879e1d2b7ddd5df4777a15509f813eb4d0f5a935aa011daaf0cc1ba2ebba9a20a74847e9c53b648f6fce4c08b6e7babc1919e6de22210a6f05\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (16 mod 64).\n# DIGEST: 172f4992e692a88f49628e5d3937959be01aed2e\nKEY: c55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d4120\nNONCE: 3f5dce998f8fb2eaad409ae02116417d\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891\nAD: d77df660ed82933f62be8d\nCT: f1ab85a35a17541efb4f906e7fc85e64efec6ab40d59d3da920c4ec09797c3ad47820e9d934e51e3f4d097c4a555575939bfaeb8cfea062b64816a160d6e4d1ff02a5fded435ab9aa2daf22fa7d676fa\nTAG: 14684ce099f4f0e11e785320debb89c79c03e8bb8751860d3779b4b553f6dedabdb23119d2866ad63fc974a6c6442b734394cb6705309a4d3889e90c4a222bbd14624cd89a9c3f904367c418140375dd592107f839ca94d43d09495a8dc8273201bd8f5a447bdf57506421a975ff4db3aab7878ff18e5b73c8f072a8d092461257d0182710ee9df9f86ac5ad321eac7ee96dddb27ecf561db222ed1c7c183c2ecdf4c7f57cf295638de3c4176ea244100d51c006282e98af1a8fd540daf0ca6f2fc0b88c550b4ab638760d95f2f9d09612da198616cd13fbfa1ad12a3fd30ac9956491cb11539a1be43175fb1452393f13f8d03501c89cf5962730125a7e185dc089b41124fc1e7f69b1fad46bd661c1\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (17 mod 64).\n# DIGEST: 00133da1f7c63fd5f0eec364e9a359be02c1d3da\nKEY: 5b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f\nNONCE: 5dce998f8fb2eaad409ae02116417dae\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d7\nAD: 7df660ed82933f62be8dc5\nCT: 5d6bfe91cd2273a9b986397a38e81be5fbbcd0403ef51873c2c467a9fbadc7bf540e83c538a43dc0e0ab780a4c4b1f5b77ced74f65b61f8b8b58b26fa3e8cba568bb717dc7071bf82dd8c68b068e739706\nTAG: 2ab9e654859c35e065f763d949d43c65dc85dc5d918850809ad8efaed6569d4b3ad064bef3427ae4c3be571fb914cefe2362169bed5b4c0cb17d2106fd6993d20ab8a8b70edb5f5d59b3357c8499c36e2b0b67edf7f334ff02d599031f43252b8d30d39affbd2093a6687c771b672329e14901ad9128f063267d3ab332ea31a79d37cb24ad0fd2d07f23b13d4643d1d9c529e1dd0490c851b0009fc1192f2438a48aba5a39be2ee925b1a38647197ead5cdea3499daa5abf9f4503d3581115a6847363348d5e7933948dce867752cde69ecc401012674ad75e12245dee86d775989275a5fc635c66d42c01b7646e180d28798905a3beb210c049be35b522ad580e1ca29f81b9469448749fce961ba6\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (18 mod 64).\n# DIGEST: 60a6821269be6c5b985576b245f106128eb0b325\nKEY: 436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5d\nNONCE: ce998f8fb2eaad409ae02116417dae0c\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77d\nAD: f660ed82933f62be8dc55b\nCT: 16e3c681ba1ece3bdbfb1da491f877e806ddac5f1ae96bc406bd195c9d48bcd4a9b700a8ced21d824bfb99eb057e401c3529818725b51e96c576e8009bfe4866e98f550a23ef4748ff761a4d1c44ccb5eba0\nTAG: a30286b3d06306818a268db0e5116abc2c7361c5a32d334d8ce5f4007aaeab750980018b435c79391151fdd33df2a97dc2cf62c4426ce45be43f7e4949be735bcd33f0e81cc6b5a3c2255fbac9ff5a8fd7e7b57554d7ef00640d92b605c9afb0c19dd5ca4c79c409d85c197e8f21d79e91df01a817bf68e8718bc771028c945471ae003c0a210c572b79d772560031b5d3e5495aa8d9bd6fa3f8ae9976ed7e7f8d7275030d2f12ed5ab05276ebebafcac7d0ca41f9d860583f800e4f1b9658b12fab31fd63f6a5e4b80463918f8295ae11d7b97f9b5f89b8166861aec8f1b1417163a6a8adce23ce66c9a4306acae7ca75435cbaece814d6010a3e335bd7db9783812052179d5337d1c353be6e0b\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (19 mod 64).\n# DIGEST: e2593f3b6741a9ed9fa188fc06efd057556ee624\nKEY: 6965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce\nNONCE: 998f8fb2eaad409ae02116417dae0cef\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df6\nAD: 60ed82933f62be8dc55b43\nCT: 9b51ba0eebf72bbcd7a1b8452a49f30bf2d96bf0cde4d9e5efe7f1903eb4e09f53aec649c5a8ad7e7fc6c28a0dcf4bd3556f4377bbf8b3f9c79dffa5978692559f732c109a7a02390746f5975d5a0aac4d04ce\nTAG: 636f7bcc9b0b5320643f4b6acbecd60a0a89d2511621ab47fa4c9af610fa1ff9c6cc5cb8fb64493d6a4dca0e94a90794f31698cb1c5bb5658e8b6a63a2cc9b2f1f297240d3d6c62087e32f5d5e9f9d608eccf4b41253933c7391983db1138012a5f5caa5abde25c8a16fc33cccb0604421d985f198c48552650f5dd299bf9163c136c042c9a35cdf7120a702bf460d739ab264fe1f58453ff4990f7315379ff074e01730e7cace8d45a5d0355c0acc409db8fbc759516ad56818b37700548aca769719937103787311b6dbc8488d9e68ee439cec3075bafb725f44734326df9b10d6a4f7133ba84489a9985febc96200276a1fb513f8a3c062466cbe63e7ad668cade7ea70c3b8cd040a6162be\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding ", @@ -528,47 +587,48 @@ static const char *kData11[] = { "ef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c2\nAD: 7f4372480974454879c41d\nCT: fcbf4939de59426da2002fcb8e3a4d07604a168e9ffb5f13afcfbdc45325e3ecf0659ea736f9dbf61cec1dbed1024eff9e3bcb721c28d004549fd84e2cdeae36dc5e5abba4f0102835740bb877858814fa38290344addefb47ae583171a510719d9aa18c8f8a5e01396fecf1a982e162edf1047f56e8e4a839c5560473f389a4c7ea8fd5e03c7f2d31ccbc094f04e2a510aa57fe30f37cda765ddcd2bec89ab3f1f5f2ca423c68664c3303520c71439230116409dd84b4a26c1a102e521253ccd455793b0d883b1569b5013653b1c606143fcba7252a70d2a2026b989d1f67fdd594d2b33bde1bf7ee9bcb6c013ea8886e0ec1341039b8d8fbb4d865754a62d0e2a1151c917368e93fed0cb29e2d63ae176cbd95991db0a2864b27b6cf5782093bbe0ae117c7b2931f678bcb07aaae3d955b61e7ebbab8e84442295700cebf1a8f7d846fe788baa0660608bcbfa59c4bc9e5d163654aea99635f9bb63b8074478fc97b4981f5e5d35430b1e18332370dc5f4e94616b0270112dc446335d10a169e8a6923765647607ba9ad65c6f6f008cdf041af2e136b398bd1d1f67044f8360d9c1e90012e594a353d8e45aefac62173fd1b03ee5e4aa6961d83cbf1096dfa02f36ef62ceea5bf88f95301464d0046cc8ae3bfa611caa0c63d07\nTAG: 850f8608529bdc90c222092bfab0239a3b07b9cb1f\nTAG_LEN: 20\n\n# DIGEST: e654b4c78e1c0061eea2996fc126c9bfd41eb6d9\nKEY: 3b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b\nNONCE: 66262c0f0368fe9d0cb746bbd55813e8\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f43724809\nAD: 74454879c41de9ac9f9823\nCT: 3a35e98cfbeeabc993af7e952b148ceb87a110d851bf2d036e5eed8482b39b881b3180dc50ce782a8cbe2c586863c5d038fc4f37d4a96ce8732abb984ae90bbccb86f7766e9712e43d3ec40fdd7a1c88cfbf14743908c78dd4c19d449db7557e0c30127d35a49503d8dce6c9a9e6f07e1c86d7e365162ec05a8b4ed301645f8274999a6c5beafc5b27dd68608aeb2efdd9cb00c6236bb143e7d91709a3fea0e865330680a854d47ae3b6067002a01aec6bdab9e60c19ca66cc39d4a44ada1e21720bd5bd87cdfb31b8a9bfac77feeafc9f8e92c4131d73a3cfb64efae2e8d14fed99c2bc88f63f88079d30b78df18ac03db855338986c0fd1614dc6afaea71130290bf52270999f3392128bc48fb0a6d6425c383b637f4c293e177f479f6a2d6323ed545bbd564f743850a121da96256a8daf163fd80835558b21e0286cf008e7cd87bab94222fd7faa395ee2ba19aa3abf5d000e7514a35357941b97e4ef433c30972e995b0991c862cefdf79712cbd3655ceb43e1e5f5b0d3f5e275bfad98a667d997333d704e4d70acc488b6829d18d1263b841307d592f760a66761e800b4676d64546a1d8630d97218a7c5f555d4a90cf58eee4bd1e1fc0e15f8f64d336edf9ca00183169f237a924e7efd5a339f3cc1bb90b4c513bb9969ecdc9beb5c5\nTAG: b24af9f27ebc204aace6315a197550907bf6079b848eb1dca1a96192ee7c8107\nTAG_LEN: 20\n\n# DIGEST: 654b8591c7f0506261713e9ce7a6fd24a6b9357e\nKEY: 61792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f03\nNONCE: 68fe9d0cb746bbd55813e8d454817c21\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c4\nAD: 1de9ac9f98233b5a7379a5\nCT: 7e1b59c791aeef6577c7ac69f8624352b7c2c7d1c8b14a7a0daf8240cc9d71ff1298eebf18ab6d469e1a327bbc3bb539df445ddcf7dccacb54f0a4ce6cf18bec20101bcd62bb2b30d8426a1e3ba949dcb69767aab5b8d2228267d784bde55bf887403188cd39453d32d50428bb9846212e4bbd3843161dc830646ba6e251ffad5d1b382101c7a3c87163867391fe44a58639e8a29fbd34cce657d321d004f842e0efa9d4cf03f557bf07a1201ac36258a4810dc101c427e19bb79f0800f27732094ee1dbab2abfc061fd4a1e84b2d36e560a38465cd4c8bc04bc27ffe90f1ce5999fc78d9432ed98c8dac4047a61547b6205bebe2191782ca63e50bb29c9bea553f5de0e9051cef35e3122c00e0d3a2468ecb2a898225c5f65fae573b17a15e013655a2ddc62adfe61ce5a7e352539c6d27c9726d2ca5492ee25b6d8233e32383100d131abce97b33dfe18a415156917ead8fe854c53bde97c0202e782679ac46f05afe1b9ad6b41bcb65bc8a80682ea8092bba0c47a9a03d08004a11756d9274ff83d5d468475c8a4a56f81cd1367040a3f75fd998b5fb3380cf8c1630fdb948fa2d0930fa5b009abc755f4bf70a59847969500d43e2db40ee517c9a6826e8e3746b3d40f9a6e7b35362550cabfa601a887bfabfd28476b3d7eb8917d66bbe9d21bfebb5a\nTAG: 22e74d37769a86785c57bb760e8a28de7a7ca3207fef4e80c284b4\nTAG_LEN: 20\n\n# DIGEST: 1eaad32c8d0cefaa5e2c503bb2185a73e6387fac\nKEY: 16430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb7\nNONCE: 46bbd55813e8d454817c212d3a0063be\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98\nAD: 233b5a7379a561792c0f31\nCT: 26234359615c88fbbf5fddd43d4832a57bda2037e2177b264309e2e50c28efc28c5ed5cbf6dea046a14caa64d499352ecba0eb2d4bd376c6b1e14048033e21b9ec63f500a70c53be60099d9c9e46ea8f250d3d20c834c3c0638a9245377fe2b76b74ea14bca6b4bdc7e8d86ca59f397fe72b8c4cbb8edc3dca7f9f234529034fe5f1441210a8ad9b4694fe013f7e4a906fc400a27279f2a1a31700750e2209f6296ed808c893a42214b46f765c9d01cee46df18b02d5493c3a1da3a6258e89e47934ade4da2fa9eef7f5b1887a60585684b1c5c2ac60d94a62d79694b063444fa36674ecde12095e9203d281da3118d058f547ede5e4b67a11ab55c1b42fe01a94a601ba031c5b0b4088563344cc28d640bf2e7c81a259211b130bb9ba9ad93090c0e11cc939b99046fe7f25132672c3714f9973513af628f21942da6b459a60e31fe1bb9bf4f6259d8c9fa07d796a264f94d64122d186a0220d9f44b040396c9c187d5ad1d806ca613a4d0f5038a8b77177f39361f9107bea7700ba835dcd38cb48a6c5af0bfbb07b7a2543f1c661f1dec06acadf8", "860fa2220c67bbc9c97c44cb7cc58831563153149713ca2db85af46932a8de891da1d4662e52ed5b7c1c15d5557a0930c7177c2046b50aaf14874512cd9ed62efabe5704573a4f44a4ddf71202a6ea8c706842299\nTAG: 8eb60165231c67e88b0abd1d7c1c3dcab1b7006d4d3f\nTAG_LEN: 20\n\n# DIGEST: 862c0517b3658e9b9cd27db608d49e24e9b4667d\nKEY: a058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813\nNONCE: e8d454817c212d3a0063be26e0636617\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98233b5a7379\nAD: a561792c0f3116430e8b6e\nCT: 6f2cea3b4aa1b3ae78d31e47c0c1e03df944352b9bd5483cfc09577aab2095a0a7e977e9c1c6451625d85d162c1653423609f141aac93123b2a0bd093c5bcdd9a49b27ace4dbe6acb486446f437c27e619a0f69405afc83240f087feb029fdf8f3f25a8a262b4a3efc4bc80512a96a45cca61d46e42132abd34c2821e7ff588c742062c01eacf9d1689f11648ebe326a91fe79275b5b1fb2af4d1440ff4a9ad35381daf2a2c0aa928216351c5b89ea33bf225d34efd7ec2c81c5af325b138a5f4ac50c5aca196d1b32ce8352431a8f08cb3b59d2f8de5c850e2a06d00c1d7f7027b4aa6757eb0c9fd3035063669a5ff8db2402818c88a7137ee309ef2735dd575e43b7508c81306dc50da65aa2276dbcd98537636ef06d1736f14e2babbc39457dc8d101d22e5516d652151c2092812814e9f73dd6cc805e670ca36e62799b42bc07fa1d93b9332c43a4b759e53ae138fd2b2b419b21a332ea304fb7db57e860509855b2a540cc909aff57e1433f295e8052c7609a88170feb7623cee8ee651ae1dca4b1afa427e2e43569d5b7f2ea688d2e2afb33f1dc0666c4b0df8aee281cbcbf5e964beb3851f7b929e5a4e06766746f22d4fa1a32913c0f449b4da8aac6294348f711d4d75bca509516668944d2a162a53a31229528e54e4bfbe13cef013efcd6687e890d292e42119529c92c\nTAG: 76c80a678b6cd735a2d01acc18dbd90bc3997f57efc2c5c78c22fe4dd13f06fb91\nTAG_LEN: 20\n\n", }; -static const size_t kLen12 = 23568; +static const size_t kLen13 = 23568; -static const char *kData12[] = { +static const char *kData13[] = { "KEY: a5060fecb0a738d8ff6dd50009a757c6e58db73228534d03f32c26baa1c209f402c3e03a6947c1d9421d63ce43f6df26d30ce783f5ed0d6b88edd389d9f92d8d\nNONCE: b52227e92203630a79ec7f5c\nIN: \nAD: \nCT: \nTAG: e61a28f5df7061b4236834d2034d2b62cb63c660b7de696c26b345e66b34d222\n\nKEY: d676047046bd5be9263ae39caaa0f688abb1bc67c083658894da6aeeff80b6d58ffc7ca1a1c88f49e629bf5544b2cc7669367202b158fce83fc4a4826dd90a7c\nNONCE: eabef87a00fd99ebb6ed6d25\nIN: \nAD: 83\nCT: \nTAG: 473cf728899cd5fdd54f18d6f934c3901f7ca118fc5ab2cbb837feefa7852a67\n\nKEY: 5eaef3b8e068fbb652bd37df4dfad6490095642cd49761a35476dffc2b5b5f75236d0351d96a9028660788893323a777ea8a2ac88bb5e500b334af02b1c2a648\nNONCE: 34d049342b9db5ffa039eac0\nIN: \nAD: 7578949699d44dec9188a7f7e14b0a23637cddb9107dbb1f8e2a968aad0443356d7eeceff4316ba7b2e8fe\nCT: \nTAG: 4d2612c21357638bada9290d2a272f10fb5f070337bf87bae396a1e7253633ae\n\nKEY: eb7b3d7eeb5f26010915a36837dc83da2bad07eba714566584bf1ce62fa9b61210b0ead7182bc28c8f0427699bf04786583fa32f3c3a8a6582cdc254930043bc\nNONCE: 3bee5ebcdfc72f4ab0023211\nIN: \nAD: efecb57e79a326c6b2ce0ae74d7656992a005fbb8da5a55b9595fc5348a5489ee2e69541ec0e8a727a560625\nCT: \nTAG: f457db1e274adabe5fc898fb1eb7c4a5a8e9a2b66f964d0958aa058c1f9e15ba\n\nKEY: 1c1abffa8a2667a8c1ab347860528162d316d58e3966050dc140fd360e6ff7c557520a8982aae97c5db5495d8951eaa485e1cac4cd8f448a13d071d759885474\nNONCE: 4fdce4e59bfdf5d9b57c78e9\nIN: \nAD: 55125cefc919379b3b4b2a24ee1794f44ac66fd99b8b68f98d4abd45ba50a5b76e5375d08abe3b8b8d3c576bc8\nCT: \nTAG: c021d2c73737e54ac6e7f61f9bb44818e5bdbf8d81d43842fd25a535790fafba\n\nKEY: 366cf53bc185473acf62610b74231e53aace84e9c5d6fbf71fc24db4f42956065d3eec01ecc72a6c89266565ff530075f4532c860e3192e866b41aee98c5c42a\nNONCE: 9ff54bd7b10f4fdfd8db76c7\nIN: \nAD: 853ef59ae873bf0bfe1465e9dd8c2cddfcf123d213ba4f599d984e4ea69d3c85a23508ec7941ca740a9157ca2a788e9b519291240b307d6c5a8c6860a96b4be698659d19e31ab0ac7ae6ba31dcd609c1db67ad580fe4422e42d368c3e93a56f2a087b0d587188462310c2ebe58ecfcf7178412223808eeb2eda76446168730fe\nCT: \nTAG: 12d869dc4bd4ac4ce9ed643cccda9e11a1ade65c76f7c1535fa4ec2bcc5eb4c3\n\nKEY: 147b41369bed390f0a9561586fd975474e3b3bbf7f7ebb7a35e5cc43b516c044dce93e154ac790a109709ac5299bb17b709a913d33fd57ebfef2b48ed66393b3\nNONCE: 85b81732d2863b41d2551763\nIN: 73\nAD: \nCT: bc\nTAG: 47fd81f6eed8d3c66afe06d788ffe40717847785f4b4c617d75a11171690a60c\n\nKEY: 9bf35c1194659c1da634eab6707c55b853c8f61d087187162e926adbae02f8bd4d15bae5b05865d0e2236d64715fc39f32e4e3679a0309396c37eab13d1c637b\nNONCE: 8da14a98ee741a5fce0de732\nIN: 10\nAD: 8e\nCT: 17\nTAG: b76af41002a946af4947f98f42a873b7da0871f482990a70bda8f005274ca179\n\nKEY: 0befac10caec674c9f23676d121f065dbcc8c91852dd5eb4e80c41076995a2138077592fec665954d21fd6787234d32d3d54bf9c220cf2bf018b374bde29926e\nNONCE: a96bfb49f3a136840a0e32ff\nIN: 59\nAD: 236adab55e1bb8a8db384c01bb2afd30ff35da71f955fb217b8305a45ee075e7f8d863d4c0e5dbe36e297c\nCT: ac\nTAG: 7bb634357e0835b02a0642352a834ff6598c2ded1af8e8ab60b9ef0641fe863d\n\nKEY: acc672aecf6f10119ee77070abbc2b4fade7e910efd1f93a5716161f88606469a49df05b40332b390d3ac289abfdf6bf7c37c033b1671082922d939139de0d42\nNONCE: af0f57b55f1a73794b3ce5cc\nIN: ee\nAD: f385a50ef027e532635878a4df0deb23369774be47c42f17cbd44925b668f628338ea5f8256c5ad8219c13cf\nCT: 71\nTAG: 13a5296075ef23216c2f2e83b940d24e8e1e6a01967af96599360f11499ac0a6\n\nKEY: 6195ef5ce3ee01188c48b04ce7a28b3ddd04b78711a6d1233121fc8ec3db3a7a0e496d1b6a416675b1e666b9a3df167efb8ade29e4f22fc77111f32ba8bd1ec2\nNONCE: 092070b2f8b65fcfe646f6bc\nIN: 26\nAD: 98526dba4437d88f657c0b7ce2a2be44ef4951711a40747a7d14b195e4c0eae97247256bba7dbd93d6a8f738c1\nCT: 83\nTAG: b6aad3f91a26a38245031d6a7eb97be0d386939d4536b2a27c90a2ddb891de73\n\nKEY: 40335487f9958dfc00b76ff06dfec162ae5c6be4e26918bd12e3f21760cb0bd364521a11f5bfae11dee989627525ab5295ee404bce476c280d13d238dea1bd40\nNONCE: ecf77c7c827a34efd8cdf79d\nIN: 34\nAD: f6e661254bf235c7d5b8ee330cb754087480dec5fe4c31dee65d1ab4479642101404bb563522937fb2e41d3aa8a4d269a222e6e0bcfd07ec4b29c1185f99fff7cb5bd2ca8c5b38742270e586c8db19138b446833f2ee07a11dae5b6a1a4c28657f3380e84bffe1bafeccad57d9cfea3da7f728119ec5bb18b79e002954f4379c\nCT: 5c\nTAG: f3420d4cecae2c1ad79d977abbe408045bd87525c0da2b93e0af3e6c53ba7d74\n\nKEY: bf32ef44c7ca9851f397e70df736d7e0e6243cfd875ebb81d76ad7612dbcfd084cab6b0d67c6a6e8b567c93fd0c3abb78ae121fdb3051a62ccfa045692d3453c\nNONCE: 46e0cc64d6e431c1efc2bd2d\nIN: 959348a8ad6912d7d6c8eae52f19b1\nAD: \nCT: 55e8cb6fd958f18b3c19451c5c79a7\nTAG: af09194071cb0ed4488d27e79700f938ce77386e5d772f9853b17b719f2b1ebc\n\nKEY: a6b5b8b051edf5cea0353ead88ea887fab048ef32f8303275e93d8f926da0d4b0e34b9447cf44fa70c24c9ab964380065398336bbb20be167fc6cd5e591ef50e\nNONCE: 371363612c4675a2e59ebd39\nIN: 443d16621b0cf9a12552216f9558ca\nAD: 32\nCT: b7f432eeda8e4b8a25f0445f17ca7c\nTAG: 649934922826febab4d59dfb52a7558e6d30d56e273602b98f3c55fd8e24f4da\n\nKEY: 075b75434269a3fcc57922ee8cc55b5bbe1b90516a3b71838ade73d41ed1d1f33ae1e0e86f88f6ed7e091cae3ccb05144b3ef239831554d6e79ff97c4d8f150e\nNONCE: 754d5c4ccbfb291133859de3\nIN: 62a151add825077c59459fbf82b708\nAD: c8db27487de71124a95eb6359270a8363908159200333b46ee74e2709b308878779686bd43c24e9ecabfc3\nCT: 2ffb9a9f65c9fe3daad13768ab56bf\nTAG: 4430a90fed7d4b5b2adf5a60d6854956be4feef497781ac7d864a04259e99516\n\nKEY: e787fdeca1095f2f2760a1c5e0f302e07d6b08de39ce31fe6a0db2f76e4626eb0968768ae04d37082c114573c307699707630b8c7ceef60abe3b7831d2adcd6e\nNONCE: 9dc9bcfe8b4e2ea059e349bb\nIN: 3ad57105144e544f95b82d485f80bb\nAD: 96bce5dcaf4a90f6638a7e30cfd840a1e8dbc60cb70ab9592803f8799f909cafe71a83c2d884e1e289cc61e7\nCT: e504109cdbf57b0e8a87080379e00d\nTAG: 1798a64b5261761ecd88f36eaf7f86ed3db62100aed20dc6e337bc93c459487e\n\nKEY: b43ab650bdd201cf05e0436afe89ac54867383f04c5ed2faea5db8e6784c720d905234f1f5443c550ca14edd8d697fa2d9e288aa58c9a337b30e6d41cfa56545\nNONCE: 4e3dd3efe527902b9de45a5f\nIN: e386663e249b241fb8249cfec33ac2\nAD: 3cf7a396e1bd034ea77a54ffca789f206f94263d90d98bf3e69cb42205fc5c95cfbd0481b0ec490ea447299159\nCT: 94aacf00092723e778d25ba78e9d27\nTAG: bd5fcf90b9532e7abfa858aed90d5170f08edcdd28ff2c673e0ab45b8c0a0f39\n\nKEY: b22a7c5bb38715025cd59cc0feed9ad8e51101200000168052b294fb1ead545a517dee636a7acd22b8283afb33d30adbe02c1c8557715eea7147f3d98a97cbb9\nNONCE: 3b4244c9ad9fedd3f10fdf7a\nIN: da79e1ed131856cec3250fde7bda4b\nAD: 4b77472ade3f06500169405b86a793d63cfa58f57bde0dd706f369b391142c2fa8a3e6345ccf0a9c29b2182f578e22f55c576f155a05be5e81997fbe06410034ecddd871e5ed94b5eeffc6dbd90a8e66449da01f8ef47d28a4a4bd253ffc427f868867c73b5c709b01732bd8035b1a23ff0a903def1eb136fc90d8b3c8279769\nCT: 5d8ad7abc047bfdf9d9cd0b0aaa53e\nTAG: 41d050d518d0e51ce16bc2920aa6c76eb8eabd4ed76373c59618c6354885f47a\n\nKEY: 04b3fd8126d65f851f47b3dea22cd6e32506f21effaa3e29820ac7825e01b51c5a2816f0298154f2d8addefa2fdc34c0635d4d6b80ad23eb320c4d4f2aa1de1c\nNONCE: fae1b1da40471dbdcec64d4e\nIN: 509f116ef7435b0640cf141d5b958aaf\nAD: \nCT: ecf553eba80e6dd1fae2eab24d772a89\nTAG: 11473566e80cff5d7421f65949c34301f34de378e91ad50928cf2caeadc466d4\n\nKEY: 413d154dadc7d8869e9e0f24b3320019a04b7a37620dd9e7aa40b5c08d70dea03c12ccf7faad7009e972680e81544b647650c6ff033f56e5bcdac9a35bd7f804\nNONCE: 6a4404adae3f4a7bd2bef95c\nIN: 3539fe02b75981fad4f8762772b3c11f\nAD: eb\nCT: 3f8a96905609a4ef1a95fdb87337503d\nTAG: 8ee076fd624d90e1f6336a92165e80408ca6f0e165b201547d351177c95e8d51\n\nKEY: ddc10df673e720c00f28fdfb69f1b8fba99696f23b6f29704a0114444cc0c8a6c8606e8d37fa95aabfd65b29c655678fcec50966c8758a3fb15332a1854a8eac\nNONCE: 06331613842b4af86c13f8a2\nIN: 55d74bcfc3d1cfc716c6e6b7153c6369\nAD: acc264344ae79959f9dd5130664273ba6f345c3fc7bc33c6c1ce33312bfbd5f181a3c7a24f15e7acf72ccf\nCT: 20650d9e846eb42854692d438b21d5e8\nTAG: 973857523e7ff600cf9bcfcc98403b34ab38d939a6d76716beac42678ca5f5bd\n\nKEY: be0c884db54cf761fc24ff3dd572362910dedacece5e1d93a916df277f923f78e7dcd908e60beb0043503c5b4877a9d962a7de37cacc7387a7553949b52894ec\nNONCE: 3f027a93e2716668c7634195\nIN: 1ba8f3a87ac6738167aac1491b602ddd\nAD: d06dd1b9360a68afa3de5d239b6d91d212c5c555567545a4f133bf5a3b0f26addb9379e1cc1cd690cd427c57\nCT: 3596cc50ae72db932dd83bbc8661641d\nTAG: 44a1834b1587d0f88e34137dcebbca059dfb8f65ddab18f338a8a30152167be0\n\nKEY: 2ee848726730c64332877a4f88ad7fb241a73b71fbee8eeb4d9d6485855ea32b487e03968e1a7b9e8ac8ab7fbd84257efbce0aa207aeefa67302d5847e0d9c05\nNONCE: 526b0a79b6359d133ad51011\nIN: a0c0477e8a9ebfd275b674ed33230d42\nAD: ded2f0f3f28aea28b17aa58d4b906c6a9b3078f97ffe95b7e161b0c3dbf", "66879bea7603a046da4945c802ac8b3\nCT: b1691c8275f12f7d9af85e71dde9dd5d\nTAG: 65a5742dcbc49295c4805387e0a15f986ae47e51add9389dfabb6468a6e83013\n\nKEY: f4a7c0e29ff510c034778e47bb30a468a92140a707936d381b1554d421af107c578e74c53ea08c7f7d93cf67612061359ae458408a9c79250f776ca4192016c0\nNONCE: 025bc10dc99346c4d0766a7d\nIN: d449a2e812429beb5c466d344f5b5eec\nAD: 304dbf9a59bfd33b777d8dec9dddce4c365e72aed851210eb964c1da18119bd13248266a67408e88ac2eadfc54def0fb57f23743d376b11293377565d253d2bffe0309f2946cb78d4e9536dde4691fe1eef9ce2dc916a773d06b42fe2b014e7974d4aeffce25a0902c9b44265e5d6d26809b5f24875e80cc13f1f8872b04a237\nCT: f366e7b66683f52586e1c363c15b7fb1\nTAG: e0e1bb733471f150ddce1b83f3fc2d88589d286ca052574b7f0735bb598362d2\n\nKEY: eb78ea626b219e12937057155884547cb7578718f569dc8f2b370c0fea80e7f0d0f5cb590f0b7341d20c775bcd6a3c818e23b6cea949cf99eb94a23a81cd2249\nNONCE: 75a10f16d429b809cf12b9ef\nIN: 6b0203316e8108ff01b12df91ba6644382\nAD: \nCT: 7ee07054f76471115be159259340c24391\nTAG: ab970669d1603767d588a93cf215673ad307244f9179f46fca56e97f64a5fbac\n\nKEY: 3221167926be262b7bd0591f56be6bf030365d45ab84a93a94ea41a5e07735b17245ad43787e8791e7ceaa0472b562ed17e3b609c66c868c9b08304c8bb328b1\nNONCE: a94d8417d2bb0323bcfd354d\nIN: cec81bac7b85c441b6261163d67921eb49\nAD: dd\nCT: ddd8860fa9e2e8087db30c9da1ec9f9487\nTAG: 26a3b9bc4d4cd802cc22e7647a19fc2a5092293c9f5b1c84bdab7245a6d8f4ab\n\nKEY: 4b16e2d62294f76cd2a6c8e0928279d9de40f0b169ef9465738cbfa064c520128ee89cf657da27e4e532d8c4709d992970bfc9daab2f31b3a67e53200d3d6710\nNONCE: e746d498b9031007332447f7\nIN: 16841e3fc1f53990d33f7ba525dab121a0\nAD: a785917bc9f3aaadfd170abe83bb30c0c5d595fc8b491d983131aeab1a7b8d8771f1a963c251976152dd63\nCT: 6bcf5eac15ef74cb8a706856f62eb5e8c7\nTAG: 9dc84b06e8ec8921be4bc7762e8cebb61a95ac5660022520f9438e8f77b45796\n\nKEY: ff2f5944111226df1d9a300533d3e871694fe15a418b2090265cd8c0111b249dfb7ee86bd9228f7ea5d89d8afcf10bf69942ee4c29bfa8409b63c00c2213629e\nNONCE: 477060f0c61555873bbeb225\nIN: f091891c43e2374c2755a88a11b04beb4a\nAD: f1323fd1ac4de9719dc5966dae45dd7b8ddbee3f8da4f4f4d5f25d06bdb8ebf57328dde76d0bdb9bdc5f6b12\nCT: e0d96f6f3ed0493a289d4c3b79238b9ed6\nTAG: 71276c05b52bab0063108dbf4e8ff57cf3e15079055a309d725f14bb86671ce1\n\nKEY: 1ce841bcf2ad8accc458a2d94774c3aa53a99e7dbec587376212101303ca2b42272a23fe28514be190b82e503e7772a3713800f4360fdb767e85ea5e1f7b8eca\nNONCE: a2f8afc5ceb5382882907630\nIN: 620fece1e843d1d0b5c5a541a6f615a81d\nAD: ded910647464d0fbb0a5d93ffb9839de3360c675179c5991ad3470285d79071436025111153628c563ad1b595e\nCT: 34431c3422e009373c50f3ee6c5b3fcc2d\nTAG: 6e4e8a3967307f47e233a36ce05a4826a698fada2ac19543bab7c9ac4f79451b\n\nKEY: 6bafd28a32690851fda667eb2d3c5993f13df52b2e97630527f26c498fd5019f26177a78f27c0c41616d2a4a73757fcaf9cd92a7da8498f90315d41e7479d90a\nNONCE: 75166c506c8e1d10da4da8b9\nIN: 697bea4d6eed5e6ed243cf01cc79bfd3a5\nAD: c0fa663961c3f7e09a8c7bc73e252a232977dd6c9483f02067b34fe695f341d05338ea2002952439ce08295ee5c12f38dafffeb5716908d3f1d4bfbf9eb0e4077bf8e534f19568ed04fca3bbff95da9088cb939f7a20cc97cc0994f9308e184219bf12c8af0d66df436c296ad39832d661b88c98cbb168c751719ac1383c9124\nCT: 8f37885b9602725385fd9a244ab2a156ea\nTAG: 7fa5cedd330887900f4a44d098e04d5eca16cf94e21f897fa54b0fc116b711b6\n\nKEY: 815786c7744d15afe1d6ab452cb6696fead8b88269ba3eb35c458f6248bad77b404acc744ebb74612c4f97deaccb99a7bcc6ad41917d61057c05b30c581dc4a0\nNONCE: 12342e4704f02336ebfc91df\nIN: 7f15e696b49ae5104ced5bebbf58a9d8ddcfaf46ddce9df88fe0d58a2f8546feeb83b975c66e4dafddb7fd9d17e80127e70af06b3b8b13c3390f1f50a227e7\nAD: \nCT: 22e7c5d54a7b622c47a9edb77cfe7c094e500b0ef9595bc346de736e0088e5934dc07160aea34f24d3ab21440878213d28059551cbfdaa418af40d344674f7\nTAG: 8c271ea5c15aa771c900388267efb2f435f001c2e83f4ec297e77c608de2d579\n\nKEY: 66d87d2b18e46257476456a1f87123424477decf196b88b09acfd3ca74bdebef4c98f1b93803098a141e0acc3ce8eede065417a0c1eda9b4614558d2383762b6\nNONCE: 1ec0ca1d3b09ef186ac4bb1a\nIN: cbb59e14098c2a8ab7e84ace913515c74e056e0fb272c7b88d0dddfb62e395afb695647d97d1071eb09cc1e1776b609fceaf4e30e92640379bb8f0e762ca9c\nAD: ec\nCT: 832804b8003b0ca1b4eff1dc4da6f6a9649e5a582854bb72cd74357476bf38d81ea3bc8ac0463f21fe37683bcbe07360d0ec2d7ab90b588adf669099303ac1\nTAG: 9fecafc768fca71ffe7d640dbb7a052d97d6c8e2fc86001d71feaf284ab609f0\n\nKEY: fbff97085351f4500e73190ac139dd3ac91e268042b5926b57e0394c750b10348b47641d195d5fb5b0846256ab229f102538b81e209db5d93b4d55f30c453d9c\nNONCE: d4868c918de2af7d3e3f57d3\nIN: 4f14aa5a680d66ae15ce0ce4739888f64d827def862572f9a6cd620badbe4ee9d75f4f9bc1f73d409f519a657f53a50d50e68e22f33a8ef5aa08b1212889e5\nAD: c41253e96696a948ce500030af27086842aacb79c04cc02a42b858a65c630065a5292bb9b2e69ea5fe5a7a\nCT: 08596ac0550574e352edc13d7e390d8fd0a57406dd61e1543066b4aa0ea06670f356e26ada0d6c61c1e41de1b4fd7a251c961fae44b23523ce227eec99a338\nTAG: 72f58de3e6697c8419ef518748fe0bb3cb930907c71b6d682c5e61068206d991\n\nKEY: c78c550aba82b571d39ce21d6ecf5e5f7c2a7bf921c6162c64ec1fdff4d0b8c41bfcea0e2486cc86b9ed9e9ceb73c4ec228a2ecbcfa0379174e76475cc21ae31\nNONCE: b5adf4de19980a71cb8ae8e6\nIN: 3d5e43ce95ff9d7f797f27b904c07291a35678fe76a9c57f0c0cba724f38acbb22c6c185db864a2a17b7ef2d67a04810ee5a45fd5a4e28a15a1ae16971451d\nAD: b5eeb9a18d436ada7bd5601944784f50fb0a989397b5c781a2cdf29337315dc7664f3c1cbf17f37fd0cc8b30\nCT: f91f1f20d06ad4480ff233480228994cfa052f9bf3038d06d997d31eb68bffa4960341b93eb5ed2260341e6816519c47bf231db2a41ad8a9719f4de6a33de5\nTAG: 6e5eabda421961e26dc17a7e1f750425235df4eaf9a97934c1e1b4439fc22791\n\nKEY: 17b90dec44546d9dbc489e55a01f2cc64452a9b0e50506a8ad7c81bc6fb21328285cafed901a7204048866ff3bd543003fdcbeb3e9e2f3d580f9062362879633\nNONCE: f0c0cb247d210031f9b233bc\nIN: 75b9b524cbfd1287259da116f536aff56112a406f069aa08f545b5372d45b66d7a5d05e02728c4bc2c779609dfe251386f78c5f48b9dad90b363d324826cd6\nAD: 8a604a9b06ad595ce0b9ad1644a596c7d3cde81490abc80840c764c40d6df08fc71d1e8196eae0802f8c8dfc24\nCT: 23ad62a668f942e613c3b5a7828142048f1f6a67f7f0e0cc8bf3fffb2d1dd967da472d080353dc9c23b900a566f20afb850e4a47688ee507faa6178fef2afd\nTAG: e9e82d3221f964d9e6c09d761afa3f05d1316d39c82618a82dafa23607bb40a3\n\nKEY: d5c09fe24201fcc3ad4c9a9c4b759345f643e930301c3714f62c8dd4974bb15a026b217ac637b4f0e8d6ef40f36be967c50aaea83b2e72df18eeb9576865f1d8\nNONCE: 9cfa0df1fe0910b33ee9849d\nIN: bfeb3d86ce3f4c5ccd0c3945e1da0e75dd057aa5b4e1f070593394f4a0227abedac0b77478e04d498506245b162e909cb711d8b875d33f9c4578e80a0e2113\nAD: b874a8523799554436a1174ab124677dc2ae2042a436c85065c50d5b5e7519623379ffed9a9c2b84b9626214b13c1806b65a432ba79066ff28ed94d17628f5ff84618593954389181e997ebd245d31f520539e250b31c86b99992983820f79e74aeaacb3a95e690e2841aba5a384d0333ebaa5d1fde06b4b8e3e1cabc6639459\nCT: afa649ea47db94936f89612ece681bb175664a97aa6faae5745f49ac9fcbfd4287b73cb58e8d8aa12eccf309182f075098f339db697fc60540481dad0cd82e\nTAG: 9909335130df0326650823de5a4f5b6f45e6941a6a72ceaf80ef32fe67363944\n\nKEY: a13c4654606f532a8df47c367dab1b214166e4f7188c20560831ac30ba5e58d316d29764e4c716ec0126657c926ba2e4541da062447228ae61340a951101b4a0\nNONCE: a2df3417ebb86bbb2f954939\nIN: f1954e59a319547d32e81f846e0c79db41c681166b43eb9c10458948606ced50a44df26fad5654a7c25d3fb52539cf25fcc1c11707c4b5aca7910a76e2374740\nAD: \nCT: 374726a4691f178a4c0a6f96108ba30c4ca8a30242c14e84380969473879d4a5de580fab4cf6ef6e465560a15028ba78a1a88f9e62322cb698b15ccce6ba83a8\nTAG: 683e5a3e61d9d9c8b170f1d4eaa4f74dcbecb1a4cb1551dc364bbb336d4e4109\n\nKEY: 0c1751677a9b7373e0c2ceab2c8e4dab50af22e2230be3187c21ed46069168d173c28a7474d8f7c3cab39401663405aebdcc474ce136e1fff9cfc520bfe17ca6\nNONCE: 38bc2efcd97998de1528b064\nIN: 8a3c6212240bdcb86da98f0e3ab3e9e78f7f61f0627ea088ab283e739a0bed5c360eeed26cea43ec09b4f3556049a1d7f8ef86abfd1118f9c0e34cc6eea4544a\nAD: 20\nCT: a1a9f7f4750be3d89fc4f25917f8ffa7dd462ce712ddf61792a01b1840bc8e428000372252f1b41055416a961db3be8fbe774f0a0a71a82e79e74927522703a0\nTAG: ae24708df0d5893a902765f6c6c2eebae0c11312936cd415bf4a74bb8498a367\n\nKEY: 154c21eb43d8d556e5f782ddd64d577ac8066fa172c2936fc2b2e875aa437f941819d9ecfaefa2e388fdeea81a0ece8dcb7647f2c68da48884aeb1315b577c09\nNONCE: e14d1bd8681373d41702a762\nIN: a2c880fcda87d9d4681a735a6790d93a1c9c68e55b87d5f7b3146665a6b2051398eb9895e1f5d522841668b9915633aa8cb40048c619baf6d63ca2da486cdeb8\nAD: b0b725cf634349ce1d3ac49d48313a09697efd9996cc5afd06b1d0817181d0374db05825dc2f08207bfb3b\nCT: 1cc0db5980863df7a40c78e323a78be6c6d556d4e3b5f930d8d0f2c6a10c6477e31c000d3f0563b4", "6e1a4aa566a4ef4b433e17e94c43338b51a7a3f862739b6e\nTAG: fe005424112de2a5ca6e68ada40984df1ae5ac666cf5fee19e9a0f203dd69f52\n\nKEY: c34482341724ee431b5272ee2964b245d7657778f7927cad4b5a1bc30a176b1eb88a83ac9faf58215a72855edf94f8e86fade58c5b5907994bb8381c9f21b753\nNONCE: 4934d9afc32fc7e2d8851594\nIN: aa3d32adc47b0b84d1b038ddcaeb007a7d5c96cc06a943eba5da6d0d367625330556e67da099c84086b3f46bb4b72986e076eb426913e415cd20bee34e434bd0\nAD: 076a7bc587b306f3da3ba88e66a55cb8125bbf8aa000dda266e950f381e35ac938ac86f8a15a83022a25f28b\nCT: cf017d87da8927e42c1f10fd3d73cf483bae43f4e110363159a9fbb7cba363930a0364cd42a5de2c70171edc4caf15bfc7238f7087bf1402b32c7bdb1f493393\nTAG: 3961efea656aab1b83082522b801fafdae346f7d4be70db1981283f323e5b5dd\n\nKEY: 363e10d8b3fe349014d6222761bba7af86545dcd1812fe2e5ada564c5008f8ea1850f374208e87362afa135f20f9e79dd0ad32f86448263416086d3afc5d37c0\nNONCE: cc545928edd3b21c0e8bc0f1\nIN: b68e3a54d17dab6eb41b03de2df14e792201d78a9c1cbf341da421da82b026ff471d4305ede5c6baae162a098c73da5cab93f30d6d540b4eaa0ee772448dade8\nAD: e21498edf4e25ada2dd6a382eceaf737623e501db34f5c5bd5c963f45818b146a6e45aa92db2a2069e55d46a4c\nCT: e4920c1fddb5dfed2268781fbb17e9ad2ea88bf2a0f116fbb7b309b25a5b9f989e1abc334999ab175b65f87e874d8ba80792044b458dc27d2b24c989d24385e1\nTAG: f0dcfa064cdf042e0b9a0443d634c38695dd09b99dadc647195fc2ad53dde547\n\nKEY: ae93f58aefa94e4e0622f2e962529fd2efdab840fd0bce62e163ca0fb004ec3b22e246073614203d9b63fe2842ef5903ed08b3e52abf7ea18acbe16fa8f66368\nNONCE: c9ac237c87270f2d88b91b64\nIN: a75f49778a6c03b0f8915f5d09efe99c5f4e9cd928713882e6b9b78bab3541812db41792b893c7e2259debc6c660ce708851912a5b9eaf91416d86b5de114ce1\nAD: a4b198a329e9c5bb6d9f31a6415811eb33c79422b0db130b78d788c38c0b9a5122688cbc50fea811afa20789465f9ee4362336cc3701ece701179af96eb7c86d5a00ed8582f24364393287d5dbc3e83a82b7a585cee5b152b5da40aa45ccd46dc841004778998c7efe9eb43c9762d1c8581eee64e18c5a961bda5aafdd5cfec8\nCT: 453fad9395106a703ccbfe811bf775f1827ea960c71d79242d2ea0e3e31b14baa76eb6d107dfc6e484f4e5146f8cad5b389e4c0fa18260c96a193edbc8091a36\nTAG: b67082c21557b31392a9821fbce4b93706f96856d2581c92e7fb65dd2166624f\n\nKEY: a145adafac46280e1cee8696903c5f3866540f27f17a519637373d95dca4ac5ac0bfd85ca6e1f8df8ae3fcfc9158421581669db52c20a3e19c5d251952f63218\nNONCE: 90bd43611f235ff225b23208\nIN: cbe5f3a5b7a94b8665cac1a4d173a225679e1a3926d8596b5adc0ef4fd00f7d93a432ff141cc04f877be60b6a17fff40ac845a91bcee3b483862f67d9a76ef498ce5e49c361bfc018e401aff47b397e96b2982d4fdcd043ca09905be9634e83dc22a667c955bc992ec96ca1b76f73631767f64fc7151284d5aa81c1aa42eb3aa\nAD: \nCT: 604f718dbce17dfca1fc5e0f400151cb65bea9d7d8f26d56687a76a23f89201aab01ef928006d15493f5b1501bb99c517cf123acd956ab575e687298488a88d5739c266e67ca6a20a5dbe5f5f27ac778816f04e7b1764cb716477f3aa01482cb6b25fe034ab5d942013164aa124608cacf13d6cc9487446cfba54315fc6bfc42\nTAG: 8e3e1a01945bfd9e1aa4eff1cdd0a6da6d8fdd5446e6d732a673effe8e44d76a\n\nKEY: 63ac8e2561341587bc066c87cd23f7f33e6023bdc1521a91d6ce63d3ab213825d95d674928b56da1741aad8e85a8b703239ad74e0304ad555eeadebf4ae30aa6\nNONCE: 4f3073c3b780ebb146e136c7\nIN: 7f9a05b1aead29b4d5361c2606e5db8a48122858842679cd46f8386ef9359f998cd2c6c266791429624ff634a160d08faf1523b650c30b2fcd71517da5f377000251ef23cfd2510a0630215ad45fa6d2313f9add040a07df8259b82d3f29cf1ab8477cd114c9ee579d3e2ce60c5da2f3375b68b4d6e0913d39dac9399c00bd32\nAD: 22\nCT: d4ed811c8db932348e0c311e9278ef22f22cec8af88b3ac0cef77f13bbd9b8cca037c1ea87590a0ce3f3e7b3ffe1dcc4c7cd9e721baa5f126a3e0afb26dcfa02bf44428846c0f1e07ba0e026c23a39877de1e69e16a2766ff4fa3d4e8d3a97ba28f407f459ae3520dd840e8f9e149ea582048dc6e3d0227bd86a9c26ddd59895\nTAG: 0abc9111229bcb725953d139a2dcb1aa0cb9d3d6c01ef4733482dc5edcc88958\n\nKEY: 355454fbe12f125edbc13550a7494f37efbe12b843058d29f892e1524289c2868ef0050a75a232d3083c381289e4950e352d68d64bf05f0608d694763c36641c\nNONCE: 0a344bb3da1c4260f2daf256\nIN: 362e97f8ef09f30e5db2f21d40568d347d9bc42d4c94a563484b12eb109886ccfd2c61c40dfe93eb836bb6aa4f828e77c137485da2df494cbeb6a9a0192c3777b4d7a927fba11a8eaf604b85a81ac4719ce8b595a74656286fd0b80d1ad3f3393e6038b258af97af9a77f6760d486d9caf5a451ba26dee51bda0f76d75bfc26e\nAD: c7c2e8196f37185b44515480d5d9451d79d07df4c1256bff6382f942727ce9b3a4f81ae964d8af2cd9f638\nCT: 32a67922947fd6b1c1bfaf3e1d41397173b97095e55307cae1c574daca275778d4aa4313fb1fe5b3997ff18800903ce044c7d0976abbb03b6cc1f7498d8b56d00672bd74f7cb152b677c632ef7a6f6fc13e95e82b6e35d663eb47f27c229c81174fd7c62c94c414e47216af2580fe822643e54907af77ae18e903fe856a02173\nTAG: 72d0fe5baee8090c5f8e79890b77f6d72a4213a7d1a81e0d1f1c9e6731e44d54\n\nKEY: 664478c9d30d2cbc39351ec3b3494f3edb81e32e48bd4ef05969da07e770e4181a9ada3b2f83b46f40fc2d9ad35fd8ee6864ff3d70436d6cca3f8e0563cc3b06\nNONCE: 7313df9679181ffad2972a6b\nIN: 142f073f2ce443c68822f120b5009e39bea3453017dc04c1b091adfddcb2a7e361c2b79eab1bf0818bc86e9d7964834d3775698b56a11ee07a0c9c03cb7bb895bf1a1dde3975c3662d233052824f1539f58cd6ad5cadb58fecaf2b34935ff711c45a639d642fb8fc3a52929b1296683bb13e67f2cc8ed9090126cdf28a4395c6\nAD: d0d78b94505793af546912f3780699dd72e288c775bfc75da6e306defcd868f6d40c6d6ce34fab9c11574ef5\nCT: cb913e40ea5dfe76beae612e9732d23ce352789987134822b2324db585179bf90d0ee20bee102e93a49a55fc978d19e99ba316cf8d9a10d2f2bcb75da4b135d1fcb8057edc33a180586015d8829a128f8fdc87b72497016c280f54f4d974c2c7e9d32ae137eaa1bcb670be237269fa73c3a0f273da9e70d89600ae7c231fc9d4\nTAG: dcc158c254ff7e131ad854a2158d51c643c281dfd7df342d5481384ab236a685\n\nKEY: 409d1b4e1c187c8b1c053e999f2af648583e1045d56d553cce9270d08c5643ef365eb35e3bdeaedcd164b0122ad185e71c75146a9807104d9b65b56d9bc1dc55\nNONCE: 1cce3f08a5aa5824d063a6f2\nIN: a255239e4065f3effe6aa5e88814d516236d016c51cd8eb35af7cee86418966559802f8ff7ac39c6a45acc1f1b18cc28d7cc32ae66dff43289fe44c3a2a72fbadf3a7249d76c1ba9671dfc420ddf513539f2da5f31030f2b6775c57432c2c3486621d841e80dd4894229debc12ef47d74716838f2d807e208f0fdaf733bce76e\nAD: 8f34f8b676e71844841c6a7b63fef1ad3061f2449c1044e1a281595da2d9e9fd141aea7350bd8cf9774d375e67\nCT: 969fc2c64261db415e51eee8cc5e0cf5185b8e3325dea516a70e32115a5b72233a44458c40f2daff3594d71e42ca2e3fc1c444ce171d22ef40009d798456613fa4b76beaa6d469e235997a302ac468c8bcfb8ef5de5cda58d7e554a9eab6cb568945dc37f28b0dbd674c083dfbd2e42fda1b42d0c1966e9652a21b32af71e2d5\nTAG: fa0789a83c255412501944a67bdceaff3f01d9a23b0c749be38abc956e2acae6\n\nKEY: e6fd8144cdb305bf9e62a2c901764c62902f354409d8c5b9c8cbfc0ba8ac7d0859ff8994e573e46784395d89c355a91a313f601b56e86ed3fd10ba428a5481ce\nNONCE: bae080718d3e5c5998542f15\nIN: 2258ffcd6fcf91b1723f8db0047525d61cc8ffc440acf3290690685d16384292493807312b7dfc23ac9d9c3ee1405baab21a3770a05875cfe325268b65fc877463e3208c842ea4a32cf144cc46d57afd91f6b6b5d85fb2dedb0702f0c4e7f742cf4c9b4aec02f07267ec1f7b96a5a3ef25f6c1b4c27bd829e86583e239cd854b\nAD: 51ae57749b7757718aef9b9c47da5794659516e7f98bc80e6c18c89253f8617963331f54d4f009f087d1d2bd69a083f3a4b98f2a51ce24ffc6079774f7c7b01638b6131bfccebe21fea67bc839c259a50fcc0a16a69ada3c5adee4097d9e053a03266cb9b4b39ee2a465ec1aa058e61a0b9888b93bfcfd103f91ca3a7b274a10\nCT: 5b2fe8eea3313cc04d5ec75d75d05b3242b6e3b65c6fa1761716780c9529ff8ca523096dd037c5bda27984aa93c702ce9c01c63569a90657cc6373ad5d4473028b7eef69dd79c44c38d0063e8a8b7f1aa2bf6b646711ecd4eea3fa27408e089d9c4c4aceedff29a25baa6a9069eb7eac83a53212c0b387d700547c46cdc525e3\nTAG: 60319de093aec5c0bb8d5f17e950b0f4df0dfd20ad96490f6f12db461b2a4a84\n\n", }; -static const size_t kLen13 = 2511; - -static const char *kData13[] = { - "# These tests are versions of the tests from the corresponding AES-GCM test\n# file, but with the nonce appended to the tag.\n\nKEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01\nNONCE:\nIN:\nAD:\nCT:\nTAG: d7cba289d6d19a5af45dc13857016bac5bf11a0951f0bfc7ea5c9e58\n\nKEY: 73ad7bbbbc640c845a150f67d058b279849370cd2c1f3c67c4dd6c869213e13a\nNONCE:\nIN: f0535fe211\nAD: e91428be04\nCT: e9b8a896da\nTAG: 9115ed79f26a030c14947b3e454db9e7a330a184fc245812f4820caa\n\nKEY: 80e2e561886eb2a953cf923aaac1653ed2db0111ee62e09cb20d9e2652bd3476\nNONCE:\nIN: 96669d2d3542a4d49c7c\nAD: e51e5bce7cbceb660399\nCT: 4521953e7d39497e4563\nTAG: 2083e3c0d84d663066bbe2961b08dcf75daf201589654da8884c3c68\n\nKEY: 31dbefe589b661af00a6fbad426e013f30f448c763f957bbcbaf9c09764f4a95\nNONCE:\nIN: 908bd801b70d85085dd480e1207a4a4b7ef179dac495a9befb16afe5adf7cb6f6d734882e6e96f587d38bfc080341dc8d5428a5fe3498b9d5faa497f60646bcb1155d2342f6b26381795daeb261d4ab1415f35c6c8ac9c8e90ea34823122df25c6ddae365cc66d92fc2fe2941f60895e00233b2e5968b01e2811c8c6f7a0a229f1c301a72715bd5c35234c1be81ef7d5cc2779e146314d3783a7aa72d87a8f107654b93cb66e3648c26fc9e4a2f0378fa178c586d096092f6a80e2e03708da72d6e4d7316c2384a522459a4ad369c82d192f6f695b0d90fcc47c6f86b8bbc6f2f4ea303aa64f5ce8b8710da62482147bcc29c8238116549256a7a011fd9c78bbb8c40e278740dc156c2cc99c3591fec2918cdeb5240fb428\nAD: 5a32d7044f003b2ffefffe5896933f4d8d64909fa03e321a1bdf063099b9f89752d72e877291d8da12340c5dd570d7d42984ffab5177824fc5483b4faf488504e6822e371dca9af541c6a97312b9cbf341b4198b0902cd2985ac10a8b5b5fe9691bb29a88344f863c980e4e871a72a8b74f92eef68c176e9d2ef037898ff567298e186af52ec62eb7429a8004ac46b945678b82859396d36d388ec3d67653aec35cf1da2684bbc6c78a5f9e3ce1b355af3b207f64e0fa73501c5d48a14638d0906c87eaa876debcf1a532c1475d80ed3d4b96458d2236eb9f67988863bc6d5c16b96b93d898683d248d7bc601b5035fc365481b89465e37a8f7dd64635e19a0282639cecde72c6b1638e0aa6e56f9c00d031cdadc59ce37e\nCT: aeab9db30a579ca54195e54a9e6c787f40100c6d12ceee35643f36ae45f618cc9bb66aa4c0fae0ec2686cb4101a5b23a46877460c7e020b38b0d8d1f533ecfa99df03d346bc854a578276d7d5685ad1fb03655683a64aae4159c9efa6781f053057e0811226c7c533967a94587f4025353b28cc3a2ce5763783b4c31e7818b8ad9195bc03be8f294f9f6ceac578f9d30b22b1f5a68d647d46cf6db4a9c3a8a5c06fa97c9efb4578f501ea96db1f40942e3f24c44a7e4070a6b931c39947d9692930b67767357015de51a39e46fff94b6019e4bc1ad9d216a571ba0dc88859c49d2c487ca657384e49b4d382d86a60c8d5195320909c4e82fc077a3b22bd4eccf0f067e66ec78eed642b2d16f0f304f60f1d9ba69e205c982\nTAG: 17ca09e3084504fc22e914ee28312c8e147fe99bba0f606c57242314\n", -}; -static const size_t kLen14 = 178545; +static const size_t kLen14 = 2511; static const char *kData14[] = { - "# Test vectors from\n# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: \nAD: \nCT: \nTAG: 07f5f4169bbf55a8400cd47ea6fd400f\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000\nAD: \nCT: c2ef328e5c71c83b\nTAG: 843122130f7364b761e0b97427e3df28\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000\nAD: \nCT: 9aab2aeb3faa0a34aea8e2b1\nTAG: 8ca50da9ae6559e48fd10f6e5c9ca17e\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000\nAD: \nCT: 85a01b63025ba19b7fd3ddfc033b3e76\nTAG: c9eac6fa700942702e90862383c6c366\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000000000000000000002000000000000000000000000000000\nAD: \nCT: 4a6a9db4c8c6549201b9edb53006cba821ec9cf850948a7c86c68ac7539d027f\nTAG: e819e63abcd020b006a976397632eb5d\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nAD: \nCT: c00d121893a9fa603f48ccc1ca3c57ce7499245ea0046db16c53c7c66fe717e39cf6c748837b61f6ee3adcee17534ed5\nTAG: 790bc96880a99ba804bd12c0e6a22cc4\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: \nCT: c2d5160a1f8683834910acdafc41fbb1632d4a353e8b905ec9a5499ac34f96c7e1049eb080883891a4db8caaa1f99dd004d80487540735234e3744512c6f90ce\nTAG: 112864c269fc0d9d88c61fa47e39aa08\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000\nAD: 01\nCT: 1de22967237a8132\nTAG: 91213f267e3b452f02d01ae33e4ec854\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000\nAD: 01\nCT: 163d6f9cc1b346cd453a2e4c\nTAG: c1a4a19ae800941ccdc57cc8413c277f\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000\nAD: 01\nCT: c91545823cc24f17dbb0e9e807d5ec17\nTAG: b292d28ff61189e8e49f3875ef91aff7\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000000000000000000003000000000000000000000000000000\nAD: 01\nCT: 07dad364bfc2b9da89116d7bef6daaaf6f255510aa654f920ac81b94e8bad365\nTAG: aea1bad12702e1965604374aab96dbbc\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: 01\nCT: c67a1f0f567a5198aa1fcc8e3f21314336f7f51ca8b1af61feac35a86416fa47fbca3b5f749cdf564527f2314f42fe25\nTAG: 03332742b228c647173616cfd44c54eb\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nAD: 01\nCT: 67fd45e126bfb9a79930c43aad2d36967d3f0e4d217c1e551f59727870beefc98cb933a8fce9de887b1e40799988db1fc3f91880ed405b2dd298318858467c89\nTAG: 5bde0285037c5de81e5b570a049b62a0\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000\nAD: 010000000000000000000000\nCT: 22b3f4cd\nTAG: 1835e517741dfddccfa07fa4661b74cf\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0300000000000000000000000000000004000000\nAD: 010000000000000000000000000000000200\nCT: 43dd0163cdb48f9fe3212bf61b201976067f342b\nTAG: b879ad976d8242acc188ab59cabfe307\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 030000000000000000000000000000000400\nAD: 0100000000000000000000000000000002000000\nCT: 462401724b5ce6588d5a54aae5375513a075\nTAG: cfcdf5042112aa29685c912fc2056543\n\n# Random vectors generated by the reference code.\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200\nNONCE: e0eaf5284d884a0e77d31646\nIN: \nAD: \nCT: \nTAG: 169fbb2fbf389a995f6390af22228a62\n\nKEY: bae8e37fc83441b16034566b7a806c46bb91c3c5aedb64a6c590bc84d1a5e269\nNONCE: e4b47801afc0577e34699b9e\nIN: 671fdd4fbdc66f146545fc880c94a95198\nAD: 874296d5cc1fd16132\nCT: 9209cfae7372e0a3ec2e5d072d5e26b7b9\nTAG: f3acb73908e54cddf7be1864914e13cf\n\nKEY: 0b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f195495860f04\nNONCE: 6787f3ea22c127aaf195d189\nIN: 4728b3fed1473c528b8426a582995929a1499e9ad8780c8d63d0ab4149c09f572c61\nAD: 4b4745914474e7c7c9882e5386fd9f92ec48\nCT: 8ad7deb4be91cdc4e75c77de1c746d816212b109c5a485c6cb79e3005d2e94355104\nTAG: d71002b6a9de0addb173f49e34edab61\n\nKEY: 9c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f61455\nNONCE: bfac8308a2d40d8c84511780\nIN: 82355c9e940fea2f582950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0abde3b2f204d1e9f8b06bc47f9745b3d1ae\nAD: 06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb\nCT: ced477a00135f16006e100b9d7521f9e1bddbc7d339cc41333abe3cc79dd8e3a18e310dd1dd53ac664673ab9090d5dc07b4859\nTAG: fdfb01ef873060efc7c3c32adf3b46cc\n\nKEY: 6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nNONCE: f901cfe8a69615a93fdf7a98\nIN: cad481796245709fb18853f68d833640e42a3c02c25b64869e146d7b233987bddfc240871d7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296\nAD: fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de1\nCT: 01fcded8e89997d446236c8e3a77ba755b85b9b5ab8fa8f355be587a3954c4a4231a7c8c198b72525ce4304125a4dabd1574453437f6584790d8cd90d5957b0d5c804a6e\nTAG: ecb5e6b6e75d241c221a2f4dbd7d0448\n\nKEY: 92eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e5\nNONCE: 5540db1872504e1cced532ce\nIN: 4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e72834321f7aa0f70b7282b4f33df23f167541ac15c8417abaf17a282ac7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2\nAD: aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b469b0901f2b5da3a956a6e278c940e\nCT: c49082d9a1bb49356f1a9b75b443832a56387066b617b939b60381db47711bfd174324e8d20c9713d562fb8f5c698dab02b5c00ecb652c182ac5544648599fd7fdd042009ed44961efd975972ae3c9aed8a4f58ddb\nTAG: 75639e5472bec58e96b358cbe429c4ac\n\nKEY: 82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27f\nNONCE: f1dea3b2a7d832ed8ab959d8\nIN: 2ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafadf0f484fae982019a8ea22efd1358adf7ad4f5fa0d2acd2f1ee095cdfc13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8\nAD: ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f\nCT: 6841f9ffed11d165b18917ed0aeed507bfdbea3a57beac2f2e08625e9929d3f2d84373ac3b21813f7dde1b25c93129b541fc640e09f5233cd9f0587edad70b73c423011cccae55a9deff9f29308fbdfc9a73f5fff4a7b0ad308ca9b545223adcf724d3d8b127\nTAG: 479bf5015121d25bf2346429a5c569b4\n\nKEY: 2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0a\nNONCE: db4c74b73839e13455fd91dd\nIN: f7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119ae0c8a20b679dc40c9908f88fecfafd688b0ebec6a2ac13421012874c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b\nAD: 8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436\nCT: 97d729cde56ec1f95bfbc16ca5dec6a208543c3255f7a2b97fbf5fcbbb34908ace9ce13bd9e90474ed620715a5e9e43c34802b85feebc4d4a23d1bc8b4b5a6c11da7158765c40d2c863185c5551cb2b10eb0b45c61b939f8274ad84fe0a74e163bfd6afc5759946362adc74b4a7f705827323f8291ec38\nTAG: ea1c9094241c5b75ea880723ccb17ca7\n\nKEY: 006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b\nNONCE: 9d0f8621664df31eb95b5e17\nIN: 567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361", - "c91452e7d463338474a400ef9efcaa648e93f38f8784a1598bca461211195d7844de56b91cccc96d89e6471bca6b7374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34\nAD: aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e\nCT: 85f7411a7f8ab505a7c10c5c1fb9bdabcd9a7826465de96e3b7c762830ce133b33d8956756ec29c00b429d30047040043cd5b3bd87dff60e09e4d7c3a95bcbfa2603ac964be32a82250741e19b6786638be28709ddeae496cba7558b7acbc5545b259e6a1b2ac1f5135f5719987dc547f97f68ffb7b9eac892527a4bf0ffbf59f77327ee763c54d6\nTAG: 3a8cb8fdab2c79aceaef6680daaf3ecc\n\nKEY: 78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc\nNONCE: 2d2c51dc426b38c308cc5748\nIN: 39129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e7659b17f09c56d170ed1ef10d2fadf01e0c78473d06a1685ef0bb112e4ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e\nAD: 746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f594\nCT: 142722bf554b8c70e8e76e52b9c0e0bb19b618f7bbc7ffbc91a66031f418d031d3c111eddb9f1ff7c2e64191be8dad4f8cd175079d2ada20c8880d0565c56afe5c9742753cbd50b93620b081f0877f045d0be91ff05a603fdc87e1940ac1e1f0c9aa96d5aaf4a58e0393ced4fad8e83171fa71c397817cd48ce6991e3b73d3356ef0448be1bd8114feff5f23db3b9cacdcfb4d25fd4dbfcae7\nTAG: e489f6c52120c8cfdc0f164b3440de99\n\nKEY: 5c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b\nNONCE: 1a8a8b1f4ab85be5a4a089f0\nIN: ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26995577faa109071bee1c87d5e6772ca55fdec02348a625b49c3c881aab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982\nAD: f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f\nCT: d8355d51bcd69356ec74b9b8657cec57335731cebfe83202c1557fd208480a2c25747625bcc70533d1ef75d2bfbeb9354066a8650f59a575e836339dd45d0d8a5cac221954b77cabba5e95da7437665fe9b48257148b7e8a88cb2cc4e0912f511aba0a013aaaf09255ec13b27cd9cd05ea11fe2ff21c9ab8a3fe86090dfe13166b172ba08e76d30ad48bef0e2325da08835ecc468cc40222db0552834ae94458366f28f6ba63b3e656bf\nTAG: 0c7f16d3294d5ef185c2d06ed719ed8d\n\nKEY: 322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e\nNONCE: 5f2eea2c79702dec4cfbee3d\nIN: 1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e58ebf03ce7ed2f8d5487936311922884bfd31cf828f3d0ce78f3c6981932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75e\nAD: ab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64\nCT: e8d083e25f9332d30bfe60ac071f502909b26393440a848d1f81c3f5fd521de98cd9ad1fc3e806724f5b3732582853cf280f1b99cffdc6b46874d42adb8784cf9ab8e158531b4dbbd76391d48727b585fca0610777fa8ec6a2a7f070627f1ed254e430e55472622289f44089ff22f02b7f3c5e45e228b7b03a5d1e1abdc18b154124f8cdd3b2229e4720cbc1bd3cc3f86f3a6a745de0bffa2536027ee03d447b306ae69b1232e964ca27a6d252c1582422c99373ca2b9541a27081\nTAG: f6b8a72d4235589f7811ee1c6f8d2167\n\nKEY: b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5\nNONCE: 322e47a85cc58e753f00d6f0\nIN: d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6b86fc55f4abb9b65ee1897c262533cccd118b0f493c849a7aa7f35d243f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db06\nAD: 7856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019\nCT: 00d34f899f0a8b40fdfe9fcec98a96c5995b4524b144545026aaa55f629c3befbb8ff794b726e759e18b7198bb2fd2a866379418e6dc4f9fa9e4edc84d21454a5cd212f68a7df321b18e9eb2c537e0cf2e0bf65e80218b841ae8a994ea3f6832d667430dc314567267d7f31519fd856d73eaa1d3bfca419abc5001b25cc1fdf860812b077fda4b01abbe8f8a81a16ad2ab5d9299ea9a0d81aa26e1a573504d5fbdf29e6b2098ce975f2f3c8c212939569c8ea8ed63c4847f2d0fd16f47bcb30bd7e00956ab8a9deddc54e009\nTAG: 6152a0401a33257c8148e65440601d5c\n\nKEY: a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e829\nNONCE: 11e842e5c9ae8fb79becf42c\nIN: 3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763edaf7d79c1b83d973f9ba3b29a9b9408418f73743ff0546f0d9290010cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a0\nAD: 28d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64a\nCT: 11bd92445b4e43dca339491c8100cf933795ef7cf4c3c4d6c42ae5b729ca22869d443505fbb49ccd29b44046569da104f7ddaf325e71e7f30487e83acd012bd492cb4e98342ac7d64843eb499744b3d17db402d51b5bf8cbcb8995fad4a81dad4221ca30ceb3590df41e124c327fd31aa53c86514a12e22c477489871bfeb38cf71cb3a959f4167402576f142bd88b1221281a94661c8d643f89fc92dffef322ce97f8c19b133e55f8020232dbdf42e4527d9f133b8a5934bf0a2df3754d6455a9d765182691ab94ec7a2e68f3ff59805c7457428ee4af8388f91e88b3\nTAG: 8f1bd0ef9d08299f494054ab9409f663\n\nKEY: d6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a\nNONCE: 7f567087a5fec5ad1ee3e4be\nIN: 5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c461b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad01dadfe4cc0681384b489f38d25e83c2c563485fb361f81d44aea205e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667\nAD: b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2c\nCT: ddc900dd582d322c567e3fd7eb23069b9e559bb16639cc79ffc6f3deb6e92cbf71ee66c839b4115e883390646245a42480ae6c638fe7fa04b575b4a8341050e2f3de075f2f19ad9b24d9cc1c39a659b0ffc362d46354da6bee0e41319221cf7cb160017d589413e5c1f07e5f626c2a1f8ae9e8b9ba0320a2de9e1b5f7baa4d551c090521d8ee0b30c8c709fbc00f1fdce999f1f96883e3b83b363cc47665e5a21fcf25afb6aa2bbcd0a374618c3dd8b8f97f21037946dde9bfdc7e907ac39e64f1a5ec8dda60a47148bd066f907a25b9caeb3804c0423836a8d9c35bc58c57882c5b23e00c7f4e3b1743cb14f102\nTAG: 8ac7e104a0165df543c7454223a01f90\n\nKEY: c7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86\nNONCE: a2ba1e9cd195a8ecadd31587\nIN: 0d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a34091633f4aaf225aa02ba9c57b910a76535f0cba67fbab0e6fa0bc876217fc9a546a97dabc9be41209bdb582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8\nAD: 729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b5", - "90a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b5\nCT: d0e58d936c8b83c253ae9bd29f45afaaba9712647b3da6c6ffd40a9390a4476a0e74a2f2d458c88056bcc0a57fb64597a7c8a5e2be39669dec53c6bf0f7b4a2bacaff9aef36b43fe37b80cccc7d42cc283ba1c1eca739167c07754edec14375d86e88668b156d04c989bcf3fdc70e8a25aa3e6052d6befe3072ec0993d6b520c722dda62b6879324eb4ae016e54d139d816be7fb1bf9c0168d8f7225bc8ed9b7509b45cdb2c8a1db4b3619120c824d0bad7deb7fd0dfdb3674ab15a712f6196a5a840ee8895670cf3b20b8a5e43caa41c5524bf47c2ed4ae7027c2b566dc3e2548244057b880da2a3f1abe5e4eff090f9358970da6568bdb5f8288f9d25829\nTAG: 057ab8d811b5c3819781752230badd5c\n\nKEY: 7817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021b9948afd\nNONCE: 8818888585a6957eb59680a5\nIN: 5a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076d829975798d4f24ad243e4aad474fd5e59e25a6dd133944918709e33f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f51\nAD: 0e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e\nCT: 5eb6120cae6df4766b40ffb4d204ade5ae08aa2cda263b39ec7b47756ed7e6b7837fdcde8d01a2bf01367e9398e25991f9da11bc9f8de8e6c1b4e922af05d20d683edb4a245e22eb6cc4fec2375e8d81f9f27af5f118a16fde654b4ceabe770fb3a00bc7a88763b670b5e3a6ca06aea1824e20b9c1a304c4bdb62643fea73030ef6d18ee2e22095b4c73abc51abc4883f2bcce14033608ff7e1ce72ab3382c29069eb75426d283a4a71348123be19f480dba1d1677055de9e82d683c2d6413a6a4e0c6d58f7f2188ca5c8b916aa49975b80630d27a89ac284b971478376ad6e55dc64098951bec2ca7d77ebe790b1ed7fe7f33fe571d8613f143e3d3ab6bc613\nTAG: 6f3f79c6231d7e45ebc1ccbe5d110a0b\n\nKEY: 4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531ce0e62\nNONCE: 19f75c4c31873d4915b1af3a\nIN: 51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3ce9e41d154c4c1bca018bbc4d744655af04ee2cd524db41170f0946df225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49\nAD: bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f\nCT: 27bf7ffbf2c9733c3da8947db11ac8801475451b0a65c96a2a3934bf45ff54fd5fb21ff0d51c83ddf0f49b005d424620b04d0c731cb214f4beb6d353a6d6b7bf1a706b070faf5146b562c9f4e6c0ba5dc9ef9ccde79cd162bcdd887dc02bc95e29dd606d22845f35d0cd6d5eb1f1b154607c0c5c2e8c7dac005eeb17c238e3d4d1e1caab72b20a9d7b2676e6491eb84e9cab903bb0c05751a33642e145de8391ca9e598ffe2e579486ce32d5d76a35d440836ede088267e8cecf4b660fc5eaf05f68872b6cd9427607b146e15fae406ae7089ae446cc2172b8ac9e42cbc27d4e5ee38c21d3fd6d4d52b2d43462756d93995b9333a079dc1f2bea9ac4248c448d932c5c0f6b76da4698d15a64f761a7380b\nTAG: 7efb02056e18e98960cc5718edd07cb2\n\nKEY: 1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c7bc7\nNONCE: b15c68437005a4973a068187\nIN: 38adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a497b1fdb1a720b9510d7d8819b6d946dd85c73be515c6ec00a10a69661c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361\nAD: abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a\nCT: 92aa5661d04af60245f6f56153cd86c6a61d5584473979eef596d6d0c205db9e4d928ba4827dbb08d5b34946b8f3e58ff62a976461ea5639fe2ee79839f99f83cde00e3fa3258e21754fa91a17e0d1fa22cc76fbce0bebb7adad09f99bd12e70e519048d96c1f97a183d8ae66445e63a4a1f936821fa7b58f569a16e25a0d0b202231a79eca0e8a2ed21755f496d8b7a9f59f6bfcf47ee4bf35788935cfb1b5ec2af2ce11c002b2843090e2267d5fc5e26f927e8836d6a97dea2a7e508f82a4cb7df375110217f88f4376782626039af166b080e181d8a310ea7fbb4fb11d5b24367f63ae83475269281aa09b7bd259a348fca28f2e1d7938127c888c68bad2608f89a2440add0c644de2b5f08d3477641675cdb428393758317c273536942caad42\nTAG: 4a43c15d469378383e9a9a26dca7083a\n\nKEY: 03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d207\nNONCE: 8f1c67d44d6e86eff0c96a14\nIN: 6bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d50109c383071e4a61ce18f495d98b6c4bcffd0fc2496b7eb0ba612e2a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820\nAD: a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474\nCT: d64a6980718a5fe833da2e6c1a119f2f16a5bf3cc5089168520603d37998d5fab07a9e18ebdc0b8417cb6a4d34357f8d598753affd51e93b451269dc24354d197885ce9a3b2f575fdc9c572b05bd7bc8df091a6675185ac15bd1c4f2cc0a8a412ff72baa6fbe95065bf2111910f4f004f6c39cd8e7ff5bab5f86abdb231406763233354734807fe0346ff6ad23a1c9c81b9942b370e02bd79eacf703ebcd53a54a5782f13ad3591801d1ece15c6deb56bb5e32d959ed1363875c57cd9d42881dc1799e652bd554059ce059a9d00a126de35f0285d5d82bfdc383b1b37d77cc1180184b2180aa35d46f816fcf125c9e8e3bbdd67c8770da26b89c7e406f02ec515edca3910de72fc76ddad8344ae36fec1d72315e1a568ee69a08154696e4545ec5ca53b3c0f5ec9cfe82792380c1b9a151a8d6\nTAG: a258557d32e1924b3eafceb7b73e43d2\n\nKEY: f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18\nNONCE: b4c98f6d51fee205805a50c1\nIN: 63beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf670cd4d988845b1d41cfeeb1ea740db129c12f66a74e6234ebccf4df706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221\nAD: e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048\nCT: 2ac34bf9d0d909a32322cbfb765875297c50110ad859857c641ffba8efd60ca003b8f32d157b6fd8fcfb1c6037b13285be884ae2dbcbc9194e8757560807a14b2219b9f2dac11af7dbbb2f504e3d8ad47ff73657a4d1283c78bcd", - "410acc1399a529f239440db4b72a48bb3ed984565d180015fa7ca9c0ff0281a2e14807cb90631c75506585c18cefa5cba7e0c943e44e85f60d47927339e3685c1fbf1bf497684a6075e0984ddce22e9c130d3cae99ab35394c315bf8e1040a830344c63d3719cd250ce04d818df0e20650f66613439c0c5153b2fad41e10b296e6fb0feb8977532079ceba9361227f69005c9e696f9b04d724074f4aae59dca55c74e87049c8f6bf1b8642e7c4dc73688260c540be50e8d4997d4b68346a0ea7749747dc72e26ac3bff58802cd60e63b3d8c509d0ce0d9886c50ae7f3a1621a077db155ceceba926919\nTAG: 67a891187fe42bd1bc7a6037513760a2\n\nKEY: 362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a\nNONCE: 2efffbc936ddfedc527b2c9c\nIN: b69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0fc5b726bbc23a67015c35a1be5dd125af812b7661106827f31a1e4c7e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bb\nAD: b55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6\nCT: ae05b44cd3cd86c828e53930c4a80e01c59a8c1c9ff4b327122cfd325cc4ea0ef4f70e3ac48ede66f4ba7fae9024dd5d78dba260d06f8888aa236e7de50f57ef48ee4b553d42b41ccb8716c59f69f30afad97778f3e48df1d5a57aab3d471fd5079633b3972e2703a86c4e24d0a035b3625a5c7380b963496f9439542b15f4013002445fba9a9f4e9f1a15c5a6bd2894c0f540d264481bd3fb6b8b63d503866edf178d8d6cf007f9c6337bfd900f5c4712d82049a2f82e43fba589a372d44f57c3d260df6f5393d3b182eecdb503e4e35018667e91c4d4362122de3d88971691e7ed05ba7341cb9cd39cc12e12ea114abb6f7cf1bdb9906d3086147a1c22c67a74fb712ba6aba1ae12167a9d77a4e5fc0c19312d20080cb2d39a3a9a8cef7cd286739d5387e1728a2c8450ccca03d0c89332120555f97652d122192374bb4e05bc5839c4c2761de9e2f732a803171a97445f3d70fd\nTAG: 7e339b51b4e6395ea01ddd2272e5b185\n\nKEY: f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a\nNONCE: 3d5bdc41779816b352803f28\nIN: 2410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755e63611c19ca5deb1db80f97a3f5149a8ad2cd6491caceee3e19782e66354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cb\nAD: c3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc\nCT: 98ce773c72c6d7d40fb8aaafcda02ed688644ac8e9ac868315cfd9db521870b40ef9decb01673aaae0c8f6403f61389c9454784f007bde6a50c3c69cce30efa5d851cde2f019bc9a9bebb79c19b29304ed908db6e45445ca7f785433abfdca7c553e8f6aa4e6670e839b5a9204648fdad4a35c0a6e44151afeff135e7e080626854e68c0afb5bc6be9aeff91d71b33d294ff1c04fda6291ef535972f3020ec70cd31b156a1468c105655561d8755a4a88c380f6c56ec1e1f49c2670454f1493262a753da4d40343b04f91aaa3e69fa4abdc625869f72839623ed8764692c23e1131f6567a1936cb43c238e0dcc2aa093a728fadd5b0e7d04505b9fedb9212218f1b5452183e8cfb366e7583dedc590f16d713948a85bc4462134eff25eb9703b34b5bdbdc63299575cb0e076f3cc7afe35ff3021658d83b526f7b8018cec38d3da93a0ed388ade0941c740da975dc433b74b1b528ff92bf5484149166f97b44e81d083bc40e5\nTAG: fb61d2ad676a0e8961aa9f00a164f294\n\nKEY: 5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6\nNONCE: d70275fa9f177cd36c990d4b\nIN: 22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50ebd7d9a251a127a4dd736d0f74e68755c4226110c276cb7870cf1c7b86617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433\nAD: bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5\nCT: e919008704bfbe7657974c9e499a3cbcedaee7b813752ddf49a69cfe3ef39a8d6e1ffb1f3bee7065e8b74b28b25b5054d9a0e86ba50d9e6aa4babd075dac7b7a8a0141f0adf9c274eebbd381a3a5f89c287019db217f5b644862319f799ec3f1ffe71e26c1b501eaa56c97a0d679f2c85158531ea41080b4c690ebf7a02ec2016ba260dd6c5fe1cc5084c94ddfb2b897cf597ff36adc11957ee4e4e3f7f7fee3b15df6930ee9bd7a1c1d6a74316194cc4b9e2483acb675def10dbdafc7093c18f46ee3ae155a385a2bf4dfd33db9eb33202d82070cbbf9df7bd6e679f2ef866eb37654c82669434b25764ab8ecf1cbab63ba7b1fdbd5e53bf24f679e321708cae599664a4e5585723df96638bbccc0db568ca8aac82c072e6548cfca1fd978ee1d732f46c6723340625d3a5ae89cb098a35a5ddfea382f1efc3c4b0528af42007c47c76e9baba69833e0219baaf4448308e9bb1eef5512ea41b8c774cbd044b2cd69c6f1c13fa6ae950e48d14cd05d8c5a97cfe4334f7f\nTAG: ed970cb4c8e9493e2b5b16c99aa6932f\n\nKEY: e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948\nNONCE: e63eabbdd2f357cff8c172e6\nIN: 652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a9871bd6158a17dbba101f840c6638ca0589434c5b842d5dc501c7741142982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d520599\nAD: 5c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d50599a3b2bbea36250ace162989e3c21249115a402c544aa82\nCT: 5fb2516faf226ba7767500f7bb3fbb0750b535b2e4e61f4b1a8f8ac58fd0bfc20d6c83b6d646de135d151ca50d10b7816bc0086e0e45021b3e5ef2560be8a8dd5efad693a7a15192614e2c977d9c7c21792c8226d89171b3020dec505a38162ecd1fb3dbffede31ec80875b5a5c84038fa33895e9f10242885a6a59fe07be083c7d7f904ca636f1d8d812e33d3776fc705d5a658984544a6554176b2cacb0aeca55d3c53cb065769e8bd13096aa7bc86ff923a856d9b6dca7146efc39ab1eb41a3f84bc3240ca7b4882ff937bbb21f3242e98bbc6858a1aaa21f5a603dffaf680d21c9c32e383d4a56c6cbda51dda0db76498c2d3e8dd746662c804f968476f5600c4dc32a2bbd966659b097679a9d604", - "e93b0a0de11935a9945b92821f985a25d065242fa120048d4760d58acf930ad57091bcbca236fcfa1bc6cd5f84dc7d19197a2c349138679a6bb13727a207c46bf733a3a86e52907886cbf6bfccf82fda3dad1b94ae819bdd847f5860b9e9711fb7de0d50868ddf792b3383efb1a2002ac57648af7bcd48b\nTAG: 2205942e6c43fcc24e7a8e0e80c3d494\n\nKEY: c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd12\nNONCE: 6cc8d0d26816561102778d04\nIN: ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72bb5e6c7b672e7c5d720c2035dfe8d42edaa56f54bd2dab11ce5ebc2f95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea\nAD: 51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c85\nCT: d02e8bb096fe307bfb5d5f359e8895f775c126e43289fd30f631559a2edf6d5000974faac0b24b7aec5e6633f862009c0f3e17aeed6fc86154a365a99200d5855a39743f219cccfeaa317b7c9866831e2f61ac7a9553e6b6ab5e5c16ef2711cb0ea9a46a483c057316e4c82b62a895e6d4ed5dd9d3d43576443ffc769630f93b37cef9fe9a79dea94b84ffd991e4429ae6de76fa6d6a9f65479842070271cde06c6e49d21acf98f4ea3e2c28eb67275446e3bcd797bd610cb9aa302430993ef3453c4ae6133f66f766cefbfa5c566bcd43a357fbc502819224352ec68c6da3d596935dfd0dc79655373a588ba08beb1ae21cf222a00e53495946f9ffa7a3edc6dc20559b401c2c5a35ff461bc12bf656b7ab86bb63fd72e7828f3915156a93c4718eb5164e359ae22086f43bb1ac868ab6a3d0631baf4ecb8688a48fa802571606ddc8215af784b04f6823439f0d5cc409c1622ae2a586fe413e4492eae627eee9578e5ef9c891a23341561a9c0f342d824a0347eaae52da91827f55269ffda3ec959613cfe9fbe022f7a8f8f8ba2dd39833ffba261746cca9\nTAG: 7380475e9d2ff3d9df01b6c895d00dbd\n\nKEY: 7a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6\nNONCE: f584f4ab378a3dc7d6102a17\nIN: 877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c6797b507a2e09cbf5c31f7be6dffc78d883f607f0ec3ddbaaae6b087e8731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96\nAD: bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309b\nCT: 7a0f153b5f7976c608206d8791dce0f90cebdc0250b484d7e4669334e8f034165bf4a794dfb989206217c13d4de15e75e7e01a24d2c988212adca2056fa7bdf33a1ff69f6ffff29b78d1560ec21cb4cc96deb9b41437dfe044600724d8ea124f741a5605233143e54d8a58f68d5a7900ed57b734c61d264e71eee4477ffe4d833756c3f65c64ae8fd832296f61a2a7dae5a8cc2c7b3f0cb87900c8c1d885d42420e2a65c414bff138594d00250e8dc451ea319893fdd63f55cad85f9f76ab9806e687fa5e2c1096f13a09ca7febd28cdafc7d0a0592865e568a58b3622876aabdc9a0c0f7924c3173aa0b218e28ad98384ebf5baf7448f316ffd82c5d7b7a51125e65aa78291a342dd30d767e19fb996e961c78d171263e0bc8529c2e3ec6d9430454705a05bd841237a68dc4b7b3039bb3a0a1c22213c9fe6c11d41d39d3cfece07527e0ebacb593add061207c5b1fd221bce69cb5121050f805e2c759423c97a5952962f625c528ff8c11f6550d435d7fbaeffe4155d266f9d0e138ae25cae2030e31fceef9e39666da4fb7e196ab3859532bdcfc10f7ecbcbb8863e7a0c005e9bd7fd9f52dfe03c94\nTAG: d6de820a9b85168257da829272d6271b\n\nKEY: bcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe\nNONCE: 16670d77b089880c962e558f\nIN: a573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894f46e56f5394bacb222b30fcb3f5d55476fc37c122d6865751212d4f57651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c\nAD: 74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a\nCT: e62cb3363816bdbd4153221411b5599b453820d675b5824ea1ef57c2a1bee7563a092976ce33c918a33c67e4628d5661acf2ea7e353bd4cce6a87557593e0ebcece6510b63b9a4a2d2c055e28b464a752b919c593623ee4c2a6bbc2b2a95f884513e446b10e2f0ea6ec98c10d893088084f7519f912afa35a693bd312335cbe2a95e4bb4cff6dfb6c2b632ef01b48d102f244bd0df83d54cda5060a01f3c3c3c8b4dd7077d0f3eeb89cddcddd23ed391697996bfa741dda4462efd006be7bf15c3b2d63aadc3cdcd862e3d09d0ca675e397055307fca30641f62fdba74ccef65682701b9551814139f4ee4eaba2f1739966925b56cbd6c3b16e94980484d32f51a216e17f07deaf70694745829564e486f53bf5cdd38ee660be09a8860be35873f14ce269adc17ce7c2ceb7941810b978a0db7e7d472f23e8ee80c9faef243cafd019d689aafaf0dab91e4b7afd5808f30753b46061057f302b8ca383c6dd7fb35b3282ffcc98487c9616a451386c1204d75337b28390e9968b24800c5a66449831da8ea3bf3aeacf2e6608b96c3291752cd049b168b1ed1f812a6f4901f30363a09b90b4b7f8af22468708c550cf77c30ca4385441d3c74e5f78c\nTAG: dfa7cc77acedf8de5a7a0375472f3c07\n\nKEY: 3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6a\nNONCE: ddae1c3199da88778d920a6c\nIN: 79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f4675ade296a8c507fba35f62c82d923051fa718d52a0279ba997149032b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd8\nAD: 23d72dea41a1c1f1611fbab63d339a8dd47a3a31b7", - "790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205c\nCT: 44234f12f5df525e7f45d785a5503ef1a78398d9e756eec0b97c426af4661471c57baba5b76a19da18984c8824b0e6573ed324758918543618ece2163e969b07fdb6c1a65164e09f1382653b5cc4823deba6ba403046860421529013e79c703e2b467fc15e4a39b5e9caf9f521a0428b1e68fa51b60492cb6c021bab35107c452c94747b59034da681b1f253d594494983df44e7b394e3c9fa190802fef8fb178a2828ea7ef2aa41cd56779036565da68642da9456079fd3bc8718b218725f657db994a19a0a01ebc51f7bb1dea2c7d476417876a7ccf8b517b968b2243e327eb6288f02858c3d679e599c2d603c80b33fc3603f689b91ce117a8481074f11540f6d75c2bbb5d3c8a3a9d7b5699acef00ce981d6c5fda7a8fcf5ea77a365873d185de9f302be3ccc4567b98b74cb695a323cc6ac162a06556f8c0a9b218407a909d7b173b2f1ad4a497fec9f8ffbb2436a4101f57746cdc24ceeb234fd8dc6f04e488227d4a2a42142bb6122b1b59087dc902e8d11e81852aae897227dbcfe872b537e57849d51968d1aa2dcaa63d6de8faeeb5753cfd8af808c69a2a7e831b34ad8e78c97b6a162401cb85247e9d89bcd593242e8c93f9378c1880a4b3c45aa434a5f6d16182035dea99a4c\nTAG: f53384a5ef6edc2cbcfda00cb7456d78\n\nKEY: d0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d\nNONCE: 5465e4e10e9cedaa39db35fd\nIN: d7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726e198729362ba96f79d5e0d89fc404b3836737445756c6060d9e95d1638a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3ed\nAD: dd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe8\nCT: 90ccaad48bdd13c3df79d9679465dd0d794b0a0ce4ded4add7f3e2952bf8593c295d17fc43b4c44e56971e0fdb116bae0e7e3203bd02647e8feddbee667ca469ba3b0351a968d746ffe033a60a26b12b525d280353605b71f46cfe3758d9efee4fbb8333945dd794eedca6279fcf5a31003cbce29d748e39ff654bbdf1bed5e7516212dd1ac27e0ac5a121bb5f95c124dc92520b25b8de80874d5d230214c30a8a17196fd23fd91b00e64bb0fb78ea22f15363bc532549252e0f2fc90944ceef75f7c320e3ec75fd148cd130cdf48f88f85cfacde2b6b80ec0f45d0defa941fa89350429da61aea18d25a2d9dd156197dedbc7f736208390274143f63a4f8d2f1dc557c544e364dd3923e54eb79cada64c69c7deffd3ad75f8660b90ea15a2a818d6c5f0d6bd43519eec6cd43618c35b468e10d17b79865e591a0bf1324941a5066c7d1c12dadb77d4993685ac8dcbd2c284f62273888c453808ef40c5d09b054f8459a43c0fbf5c714e8c7b8985ea932ace7a79987b0a9be926335b87d37bc182400a38a847362b3e74b08a952c8c64ca72f1b79d6e0b52cfbe28012c1aa424da95c5a2e8b8c49dc2f305cef00e50b92d320cbec992ca1656848860e0bd790bac5298b7a09b7586c866fed3dcb53afd2f7b313272f1c4b458e1b1bee6\nTAG: 1139d5d9f7e52a51d258d95a9a51b5a3\n\nKEY: 5940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37\nNONCE: 597c9a73eb47abcd2aec1b2a\nIN: 8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee8716382167ee6f77730766fe8b4ca6c8f0270896bcf14cca5d7c2184dc6eef47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27\nAD: b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38\nCT: af56537eae418deb9f7da2500111c077ca99da5e835705385924845547a592cd3910dd419e6fa4b9b2d7c21d42ce2797873a494a735cfbb4277143dd25592a1f70ad8d29a42b55f697807994a1c0338543bb56543609e052e52e1b7ac473ce717711fd7ce4c269291764c11615637b29bee0a8001ce82003ac91f410153fed863f7aa1071a76b5583852f6e8bb7b565eac8042e0ed76704ddcb2c03504b9c79b1e66c179a9e91d2cd890380421d84e05a70e05c4aae13fa600e57a78d7668e94f87d7bef00b055118480e4944131a39c7b6066161a3815137a3b0e89cc0db03775507b4d3325ee4449946b33892e064954294c6ce83c97fbd7f11f203fd1af49a478cd3eed3cca766ca3b9d3402dcaa4ab9729f209ad46daf17a584d6187659b039176deb9e08a0cc78db16e4122dc5f81ae4f5ee23a7140d2041cc81c8c43568fdd45c9ce4aaefdf7bf2f650f478f7581202b548164c4c160d3e2d5762569341170304e965e09474130e397bda5326b2aa07067a4fc8275a1cbcc43777414185b243ff67f8947b16db687a5b15bd5f685ce250be6ff21355ada2e125b64b57d57b94d6461ed19e77bba9234ba891d8da2008493a07d4f8c76e71973bb9ef87eb048c453cf66bce0e820966d9f62d39deb43c7a2c25335184e0e5ddc1b191138e71b155d39271becbdf097bdfaf1\nTAG: febaae3a1e94e47bf92a1171c91aff8e\n\nKEY: 888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc\nNONCE: 95fc19c449bfc10443c5c163\nIN: 88d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f471b63e84a8114f73f918aba186239947bbbe2973181d9b48e801e3a5597b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b68d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae17\nAD: 0e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72\nCT: fcc", - "54b58b1330cc5e87305ad574eb3ddc760f12a0dbc5075d8b7e825cb52237f48845a1099527fcd5e483f2d99a06a413eaaab04e641bf7ee3e6f08575658da3e48af76b849ca68443b61f260118bf7730d9a4b965c4d55d391c66c87ac9a065f32e784758be031f9f24901737da41fb0b800e61c5d3e75024ce3cbc03c9b0a318b90821623cb50e487fc15ffe6e3b1ba69b98ab10564bb72f868faa2e4f446e5331065f36d30942022038d11dd040d872aecd22163affa37003302cee8da8b02fc1ece3c3b6a29bc515609faaa460032a09adc496bbcc70ae7d35b78c8f97f4b5a55b9fc03a00561bdbdf883edac8761a8c31275c4833ca06a212dcc4fdabaa022c7e7daaaa7435b5c7014fa3866bb77890ef0955afb267417706ccaf3ccd9e633ed9892fb5049600597e9b85f73f7fb065bcc748237f33a0c300298dc4cf37781fe632adac9fdc0f3388d315a1816f315c96b8d75c7143795f56e0e51f09443396dd7e291828cdb0bb70125e90211c68530f33e0b2ef8bceb42905b908fb3f64dcf48ba8ec4abbcfc3da2bc6f04dc8bd993a438cf3e64efafbdad932e01ab3000b6bc819e1c205242220ea72ecd4cb38e54ab7c483a58956f992304512bbeaf7fc0f987098c25797d734cdf74a3bf06a5ec90cbe1e12e59fc47e8ddc4ec0ffcd90e0db824e44bebe661a88a94b335bfd2d957186723d9e0d50544e68547c\nTAG: 9c7a7696965ac3b4d1b175a1136fff97\n\nKEY: d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e7754de0c\nNONCE: e06145d6b247742ab582584c\nIN: 3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9cc1ead957027a7303f01622d129eeb87604daa5b792d6d2cc4ba08cab47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe2\nAD: 8b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d\nCT: 3fe29eb90fe4d85b070d118e2ee7b5820ba5aa019b5aa64c04485305771ab03b7dbfbf9cefc1f1d4ac7b91e82e460e1e4bff9d6ec7cb61138fd3521a9a13aebaf082907b6bd82fb0cddd4c6d2af72b054c2742ded0241e2db9573ea7cb76b56b14c7bbb2a983b9032bb701a83f7328da550e6fe2c07026a81989d030610afa859b1622c8743e957d3441f044339d5936921104f0d98c427fee9430dc1689261c63f0a02beb9095623480ba798fd13ec536d678550f10f71f2dced90edef6e3db5699a27f20d2382b06adf5df7108d44b5610bd49a7270d1021b93cb167b15cfbafc875c9188211fa31aac4dd9f4abff49cf18c466731d3d343aa04851abf731137c83e8815a04cb48957b7514f5b8d27d1bcfb3f8bb805603062fa4f2a1e50734b2e52ca9e99bf834001dc6f57fca600bc49d0e95c2ca80581a66176f182cbf9602e683b2480492d1e6b0f6119930a85e09f4e56b861c8c287da0b4028c055e3f325802260b7666b38da47960acbf10f9206e68ef247a78b0f9b7b5bc50aa6f5a47684d1e64c79ff28f1bb21bf3e67f7d6ea5c2074b45bfa7d905b989fd262afb2253b172415c16706b9c88a322787a3001460848391863b71aba1d23dda76adb560e7a03c81271330bbf36b6b21d1c8965f8973afa9772b7590b9de18a9c961bac11590825abb5a7fbe78f4d120e6eff290b8b3e4b36222a0fa1de8a5ba2501\nTAG: 0948cf55a922d9ca8061356f5a829236\n\nKEY: 09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327dacc20\nNONCE: b8d41590570fd882012b1207\nIN: ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc221262a7e7959ff156f3e69dcf4c3db8ccc256d666d3700475874d600d6e7f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9\nAD: db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212\nCT: d412afdcb77bfba94aa9a2a3a3a016369706fa4ab1efb2bdbf4c657fee4ca85b1c497a4a85e1330854fbff098c2f8450b7a95c4642b970518293a8d6e3f66ea0467cb05b7f2eb5b406e3ba36e153d97c9bf9bf45780e6576840888355f6084adc7ef517ec42e11271d2b72f2675553e21521e4a6b8f92f15fdaee335a4b8141e42a7204e35a96a3bbad2b955e1d9fbf02f735cd1c31f1fbc069b89361a9e0e18c75a587f7f5279a9005f8338412e71eb6e7e644586b9e6aeb6397744cbac0f60b086f7e36b7147c27c077d7038797c6da35bd3812b68dde48917b6695537490992c847a544092c9e16f3715abb930080c10dd8bfc26d51e7fa4b8cbb785d3ca64a2a5e21a10312dc4b55710d7b2dbb727b285b087c542c0e4d9055e16cdbc90954a91dc417ab19eddf8084c765ad1a2636b542411c15f36953f9e6a177089fcb9bc45f0f2256f7b461ff5551a5518c5c33f8fffb282d4698d1ad630cef7bd6c0577624a642eabe3ac0f78386d8dd1429f02a9c206037bdd6ef066ec15fdcf52aaedc1771f3f424e417751b3ee9f8a71ca47a45bb1b8608f68aa1cb29afac84fedb11f579b848e76a5664a8978d5ef26bd087bc28822216454a193a9c4f19126a108cc00b25f9cbe0bfbe704834153bc6dca55f32c4ea87ea6774768c5a36e5e39be927c2e1d4055fd279d99d1b3a8741a4320436791de823c96cba601c0ba9f36f65eec9d3117c6d73bdfecd4a3556f84c\nTAG: 8ab0f495275a56e3a0d77f255a615fbf\n\nKEY: 501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b66d3a\nNONCE: 702bcf31e90cd2ff6a350a94\nIN: 689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e5de639113d920e239a0d1581e179f9e90b5bc077c27b08427f0ec327545c1a235b88be7e8451a5bf405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc\nAD: 673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33", - "c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0\nCT: d0bace68d76a5be6b31bd038b921b6377f8022e09bfd90a8a94d55c9147b07e9857891b8f4f43ef410378fc0a54966918bae5fde49658e1f6d307908b5346b9d776c1a6dffe52213286fcb298c741d04e9280a4b108419fe9dc938fc5b3810183bb7004a3eb05cd1fa81646e7e64e76e69ddba6d086a020f7c89ceaa7ad53b13b01c5c1addb818eca6d4e060b60e31320267e199af494739f67544542baafb577d2bfc36d7f92b8236dfc6dd5613c9b81681f10ebdc97e49432309d8d46ee1770bfa256b871f9bf76afd426fda88b91fa9a407d6364c181a1f04f17083751944a6925292fb42defb24c215b0128c6f500a642cfd230c89ae2ce117a29adc5c09f7dd4d97a34b9fb4e55802d325a1a13d0f6e664fd5f5a35f22c96c5b567d2297c5832f928ea7041b11f7ee546dfa03bc03385b231c0503657f0119b545faec4010fb67469f2b9bf69f4ab89abd70c339893fd145758b3ae47b44fcd36c20d361e597ca573317b04a5d00997755c97ab20f9b0592aaa8d10a940be50f33c9fab16bb0fbec7d92d21c378a3badc8c2137fb989c9b6111ab8228c427338e0685ccf979afa9e887f06cd840c2795a9e08ed641990f0c29d061c4f93ce6a15836b34dd428d5906714315cd9bd2f636bf9deb8a6371ead07502a46500f987f2ac124428256044948fc4a2cf778012d349ff5f9e3847c8b71793e8acdb96b68eb034d08f6b06db00c72e10bb6574fdccdf39a775628bc387b9ee026866854f52d91cc62659c\nTAG: 54c66aab6e2939029293205527852b9f\n\nKEY: 428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc584\nNONCE: 6f6eb4aa086447f4a7e5e8ee\nIN: f4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dabf0f31be89acf8d7fcdb2a063de5a9812a3d6aca502708d448a869bcbbd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f\nAD: 9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5b\nCT: abc04db39ba31976883d21f55078e5e4f5ead60c56b232124dd035215a124a489249ba560da193cc3152352f241070313d8e8b693bdc7f72e91c34a5713688a6a8ed1d3a3fdd0c5f118fc83df42b8ae307e39b35021b4479fe240be8e161407bd82950dee7d9a13d397cfc10d38ff3736f47a4da0ddf2cba1501c18674a71d1a1c948e038632d65ab51fa41347c583bcf2d13b2d22201957f607e57dab80e8a1bdd2b9cfe95b204976c1fd5f5e9fa304d3f9761b63d0f5dbc7a129bbcfd97c437b7d3bfbaca571a50192cf309a209dc29d51a18cee2ea9790309795ace41ce20c12eebfc6db620c398d3229e773f44048d596bdfacad90e277518ad0b2f8841eba71551f79fd891cd1aa84c6c87224bccac2c95d9ec27d3d0278b274dfa30a3fa8684f7cf50bbb80c49ab4b4ead2943e87a31dcf29df040f1dde7e2bdb097d230bdefa5d541572b9e759edcf498d0db993f5904e838d53230e231cfb57266fe0128c2d8ed81d6be4b0a14c286e9ed109fffd1cd4d5d5b8b280c238e7e276095659da7db5bb400c157901b111036ca13af2c7763fc33fb45f857d4250ac1145678dfa99960c03327cd39f521d71b582a85da13fbf2905faadd0c4b7bdc818761947a5fc42215657959c335d0dd01c8562bcc6338dd183d51e8b3261b90e0642853912da5a19e3c74a6c109e845fb700ca20c5c9c4a185b1060a830c7ddda040de695df1ac085d7a0b0d433a5530e5a5fce1bced424383520ad85c40d709389a4b3e151e4e8b3c68bc5f62bc9acd0885fedf11fe\nTAG: d340ff2101c55bc874a152a64dbfbe91\n\nKEY: ee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158\nNONCE: 2c9c6974f2442b87c02cb723\nIN: f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcce4ffeb5ff128eb3c798dcdec4c665a4e7b30ac120aace497d03de3d726638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e13\nAD: 15fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d\nCT: 829f34b0c9a9dd142c05e45001836bd524075423cd40507819ffc9db5f5149cfd97cb6584c280f936c8fa3c0237673ff858aeab5f678be466c8b0f9356cd48d0a4bf55f5826115100316d5b11dac5cbe21b817f8e5b2587971d4a1f47695f1f917a87fd64356336481b92922244639cb2455c3bd0b338b24727f14c3b68a92ced6a6a58fd2c07aae4b5206f5fe355de532b996e6348d357906ed4736734b62bd27f8e832690b2e63a2fac998b7af27cc98aa64386594eabf12d5989716e8c36169ac8f548433c6cecc114279cef1a62906bb69233a3d74462f4a35528a98651a0325c06c3667ec31f7b66bb9941b843c6faf6ee56a813b03f3bc8775bcaf1efa10cb4ce784c99ea79d49ae57e4a77d7b069f8456b66ddd04a8addfcc441fc3577b5ce2e38eecebe4963e78dd5728e347654403ea249f70817e545528780668c69bd5186cbfa73e9e7cf3813952377f748c6736988a0faf9f06112dad90733847dae8ea272ac49f1290a417f4eb09f6960e0bbd90c098b3d6bd1f49802325e255ad104cd18a90189aa486eedfad8ca999f533ccfc30e63b31809a2f0dd6bacf29e7a4de79813dac86e3b324e7cc89abfe98e91e02a37e3a5d224207958fe4627aa5861cc1d58515e2da73eaa171e29bd436786a8c54c449bf620b0d91a0c001272b5d047a93289e2d6a31ccb14347b019473214c9dc066d867fd3cc9fbec4c1ea887c6e009bbda41f5e888bbb14587c04c406566abe1a7f473f052a17c3604e837d1358255c70098a4993fb0cc25cf89326044f11a7f4e6e320afc5c8ae457425427d5a08\nTAG: ef86f2b8d839c403d817a7a4b73b727e\n\nKEY: 7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4eb\nNONCE: f314fd627004e9a78d133482\nIN: 2040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce4910758ac0726e0bca5d30bf4d0a231fd12420b9b60c3a690e0ce0106c1bcfc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61f", - "f7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde\nAD: 1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d\nCT: 93ebed6f7254c65c204278a9acae0b123dc19d8e226e41511f349961b1939ca83970b9696f31a7fcac5f5e3d4931b0a592ac27fec71b4e5679a56ad1bc3be37d4bdaa50bfdd0d00545d4b77e757ce7a0c8abfedc9585199ecab1226763a81f9a8c6853462c483f29798a9b28073a57689c5514e356f9fdc3f7bf8ee0688e8cb781af3a365ba940f7ed36ca68f6622fc6b6310a4dd7f8587853f58ef485c82359840e2784460109b4921e4b7ab014b28571938e18b4525bb4d5de35e77cf44573b167883feb3c730945e9ab71a2b755cc315ba99ab96f8d4a8f46589f2e8906b269519da3a2dad2a7075629c82096f028ba47c33e264f55b8898ac5681d396b8e6d23616c1f8db24ece718c2938f88c82da1fa940ecfb402fb300041f9d30e5d47e2d74a4d9822d35aeb6223a4457d621286444f732bed704d529df95627e153246e0688fa97399d96033a06091e77db420c8007ccc33386c28fb76a697dd99ffab76705a7f55797357e563cb607e531938380dfa64800391f06e5cfdd3dad5f91eb7f2138d54cefe9edc0dd3f4d674f5f5aa315f0e1b7922a37821c6cabcc9d81fd002d159d73b0598ddd21b66d3db416b789a40fe886027f1a13d802e54a6bcf691ab029560b67307ecd373f2f9ef2ea2c334fef7d25799088106bbee9fe2b88d06bb23ed0510284c5e1289c1b65a27e4f0fe33f18a0065411ea9e09e65b589a2372f37d0f8f4e07d95f6e8f30fa882726d29f41782b3d5abbd4a9f2dc62419c684a4c8aa92c4adc71c4db805c29b0e561760ea3deadb7d41e7a07a67fed68b8a0f4460e5535e9e0b9f7a754d6f2398fcf399a277\nTAG: 7ec06820957f6a0e0f4a8f7ae0be696b\n\nKEY: 0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e1062\nNONCE: 86300bfdb282f9e2db0a43c1\nIN: 8132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b7b9f65509a00841930c4087093c0e04945003751c40e59eeb10f62ec33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735\nAD: 565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0c\nCT: 84cdf98efa641c2c008e2b2f6a8b59e20e95aab15c276a21569a1ccf8b7494b6c9585220620944517f167e38db24bce3c81fba1743bc6a51abe0ba858d763420ddb06a9a36eb417fdbce903c9528f1db76a70f73e50e22154e8807aff8e05fe6d3d28e3f09135486b33e59ef353e30a294be4870a79664d86ea84dc581ae58ba8aa6355ac8289855e7aca0940669cf5e7b00eeb5a5e9c7ca1dd483c6664def93e76244636eec70296965eca0f6c34f1d9923295e343ff9affdfd51492066cc4d5d762db2864db889441dfaf9c2354acd97c823071098b8b9da9b2a91ea98d6391e40ee4e13b7c5773ad7124c1dc22d4e2dd6142eb665be2e936a20edcba8badec6081a07e54649ed2c371a7f22d4898fcf8cd9916c7033925908c2a03c02000a456ce2beec2b2f94c0f92b9a7885c9231886993600e734948b34fa025b733ccef10a8b66d52dc53b850d2632e1d1573256430661d1aa716fb32dc525e80c96afc19808449391dad1165de6668f9743ae1da522c9a953374fdfe214329c00cf359b40bf9f3edc4144da66e3eb9ded0885a1d3b441cdea692ce0e324686e7b2128bb28f6e4256b4ca1463f93f67743a53509deee18be4f9f0604c3491559612b4052370e4fca33482aa0d2370baad1b7e64a1e6088ba87fda91c83f274ef9501385a96b4df53d0ade464abbc8022498f9df1b2608e42b1905d1dc08c3e4bbc7e3b830145a8ea9d7bbf64cec752ea11195947b587cb5abc811307a66b24df8c95756ca4ec7e7bdce47679a2327f08b94849a7760c702ce07072ad7621e0bbb0fb78e3f6a7739de57c29d49057a7ffece9c013384df796ac954f61590c472eebc27a7adfcebe3ffe\nTAG: 18d8a0469f1ba110dbf77ecae36e63c0\n\nKEY: ba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8\nNONCE: eb8ff97b4f599c829e412edf\nIN: ae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25effb4cba7822382ec3aa42a95221eda5980c488bf7ad0031e1ed987096819cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10\nAD: a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d803\nCT: 5d0cafef15ec06bb165c248fe447bfbdb89207ec1331c65a5d88d419576ad9d423d20d660c95b48bc437fe243a6f860f260894e0230b702af0aaa4260746008ad679676a92003a10ccc12654251de9d2cb09f7294c2fe8c2f4764efbe3984e7265abcffc2cb3e30c5611c3f9eaba13e847fd73fb3aef12c8512b44283935c51d48032865bd6efba3ee4e1f07dea2e26022958f6a966fc4059c81fbec916bf4486429f55732fe3e927bd4109a8bc9ecb820d2c137790b0e296df28f2701ef5cba2c5ef0c7732849c75f59f81460333255f139fcbb30376c21ca317db1f849f79b1826c8f3cc0852e00b0dfb94bf3601afa09c27c130b5088c05619dacf00f36e7c01a9f4a2f24d8be1ae778fef1d367b04313f8cec89c708a57bb332b63e60d15d5b4abb2d5b0bd0dca886e0014051053a5e946750be4a9553549d9102b0d8c08bf9f850a6e06aee7030536ecfba48aa577c7d361405", - "6d790c9130544c172bb4cb386fd3988f149cd77ee8275b0fe434e589b64c13885e9ef4047627dc192a6ad646ac6d62f482eca0183d23f65a29937e9e53a1235f66436897da1213607cd850c32cda9828010e6fc3a93f5f9c709ff259921ce890435b6454c046fb01c76513cc99f66a5c2da8f16525b68e3cc66cd6a7674e674bb0cd8487953ea9048a170ac8e81b616e78d0b8460b729d885f4716b741c04e6236d2171017a5d433754aedba3aa7a39675402337db7081f45ea37374a8f86ce8898ea837583a300c0f74c6292d37e7c6d19c190394dbe777e454c344d7e16bc51c0d93465f05327ff29303d80177b9098b4a4d809fcb103a8c199e3e8f827b237408a242a80ab388d29ea12ee8a0fc313367ad213f7e696f90331c7ab9a5730cfa1\nTAG: 359febfe67037a485d7ccaa4f1b6286e\n\nKEY: 9a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e9659\nNONCE: 9fe335e06fff534915999ba3\nIN: c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f8004233eba54fe7537d0127b1a062526d33fed44fbd3475daf5c046123befcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a\nAD: 9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99d\nCT: 28c9024090abbe09b35c4e289dc1b9574ff5172edb28f34e9133539dc98b4557168bcedb11a94c1ea84eb4b803661e405eb007c17cec80afb3121f27f185a197b4ea3f0ba231e538ae3c312e2522218ca2a73402ea7cffd3c1413c0ca2206caa91722cb048e1ec15e63f6c55e563dfcb4c3404a9c380608da0e903bf8037ee1d740275d568a2a3f9ee232d88950b233287b2bdcbace62efd1425c43efbaa8d12f66852cb5f1b665e7f4cb6fb5e3746cd5e8d612bbda8c031fe5ed7f4f3b5741b2aff9bdb150f637fece13ea1f2f5d32718560a49c841f3923d993b1f5f65715aae6b651e7d8f75ff34a9d1737b9e3f9a0375861458faba779ef9f4b72ebf42097e1e0fab5b925fe85f54d40f940f7ace96125273da94c9e394fa9a80680f6567207ee40ffabc8c152bc6956dadba45eff644213178a7a24882ab59ccfec9fc525ea9e37064ff5566e9ef2c56a9d634f59cfbb0b593d3fb19262436b68f57029d83205ed6c466885d7ce9a33046bda7dad9e2ca92691b3d5f1e48348b17aecc311479c4b147f4d61ac14640006a7c0d83b45372073752f9abdb5d1908dc3ec05f85e70324088e360003dc774bb68347c2acd4322fc1733d36e68cadfa95030dfcb9f73165786a30a7e841717ed8b20bcce47ac9b4900fb6d35c917b291a9b5dfc4ec2679846447a1dd140f48699b792a2969384c7e8914522286765a3013e229d3f3e30b130efd498a1cb56cdd493a5fc8bd9726a8784956ee379f907cf2280745379784bf1f177318cac159ce656c4321eac7ae00adea35e209b38c0ce622a1d4451a2dc6e0c3d2679543cdbed19310976d0748db13e341c396089d977546e956c96199828a8cb72ace556a2ece3edd3efec2493a13d61701a1bd525841933e8398ddbe16cd96a2c\nTAG: a1cefe9bdf19616e49e6dae07c8a73fa\n\nKEY: c75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c2\nNONCE: 0da68ee6ee4e0126b67d2a31\nIN: e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124f79000afa6ad2a10b0dbfa4f34e475420437dd10d487f42d2cc40041af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05\nAD: e83596b9ab4cbfae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf0\nCT: 2a59d868291bda6113708e551c89d1d4fd3fbc81017975fc0b99d8dcffd757f19fa4acd4acd47c90100e27eb228ee59ff1910911f8129b8a2cdc59ec38b73cd096271e55fd097329768d102f4398c4f70c52d7b15fcd66a94d0e910a5b6b8bdbb857592ee42871055be1b957013695288e52ad934c6f802677aa89c08654fd932039417bdbe062a5242d5d38b79ac834c7e7fc920bc3981dfb780c9f10f5f761a49a3b95693ee764a97d4de73077838b5ee04ac09e10c72669f7c151446497c9e2c3153938efcc62feeb9b82e605b4bd76ad97b7401ada9bad71718539d47e6edd058c23b5c4f3bdf69d74ee58b7d1c94ef660e4e6b1d43b97cf9e8d191178160bdf0e4fb6db2e9aaa2563322e4413f3b5d57d0f1082d160ae2bb2d3cf6ac17d75f73ca1c80365648a394edcf62f520d2bb648d7c963b1d7deb6eece9583ebd2b2bc2cccc5415c774d9f25c00d221e1f0c2829e288721a9e416df098392f67643d52a9fb0f2f47ca97664aacfa837105e5da4b86774223bbd238a060648f689c59aea623cc688c1aecdffb13d9471fa07352ec02ffaddf080733f07d10ba61eaaa9f8e0d89b6144af9d4a0094bf9fbdfa6b35e9f342a7140ee4c931ffc0126eb8b4cf6e227fc6bfe386e81a32593acafc6d44925f1cf21924720972729e2e9daae0e74f55045d17c25c4c3b8454f912a0f6f6ffd43119ec4f3046d921d20f24662d25d0aa34d95c3a5aeff05ef1a8905ffcdb1b9e55ea22e59a3f5d60106db64b998f0e9683a16c5d82c53b424220690794bdedef384d91bc9a58563fadac76b50e80b64dbf695a38540a9167cf025ee64d28e26fb3dc7e9f33979b33eb887e55d996741d9569642769ddf6332e369674296d510181023a1a3e4ea7327af5838048458ac90a71732fe29e2edc9c477fb6d8827ab4f83ef8626\nTAG: ddeec4a2536869f8f89ac38951bba13d\n\nKEY: 0c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea3\nNONCE: 2b0a22b260ad3ffa73ff1c5c\nIN: 481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187", - "ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b375dacb5173b30a28c99e00eb11181879cbf1fb59bee4e3964b300ce57b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14a\nAD: cd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae906\nCT: a56a09a3c7cac593f40fd3af345c1c84d29a7905a05087553640f0727283d1fd270773b6af7537bea2eae40f603567132c199e7f74b7eb98f1d7e73a7b6474d1b0b0eec43dbc33ef6e17e07afbb94848fb78d53729f358c2eefaeae4b92724fe0d6fe97075644ad5b12d1ed93f8c07aeabe373b5bca66b52117018955edf01c238a937c4d5e7993fda05799533a5a15889637628e158604a99b2a21b24dfc2af7ec0013390e6e7259b7ac92f232bdd375fa99a4f6c45f54ab231f6d60fc36809efd3d213813be1f3e1b91ff3091469590f6cc439ff359b0706ec0d0667f58c34ba549e9727d9045adffd0481fdd13c4069160eb871afb2d408e4dfcf6b70a7c2e21e4e54f44b2daa3676ee998515dfc4c8518288b46d92ea835d5e9a0c8c391020aa6efb8b30a580601178e486957918ed9f11fbd2021ed7830c3019c935ce19dfbe95c525c8498803eed097d565b94d047112d494518f7af094705f3fb83b22d9064450701ddbd8cfb209a4c68fbc1667099e605b7cf853d5a78b92df4f6194a7644017434f2658a7529941d3cf71865f8e29238709b373e68fe1e800ee858d8286d80acf4f1d8cdc2668f40338f48dcf5774e5da72644bd9513018688509c444f821c0c648802cefc572c6821005db0fdba6f4eed0f122ac57a213750632ad2eee0018f9f240f2bcd1cdc03d4c8a6585d955dcee93cab5d7041148385a77533a41eb9eb55d7be87432e5508e798aa4e4fd4a06e83bfe355cc698bd16f9b5ebfd17145edb7bfb3c57a0faff18df6075d98ce7a53eb4de7563768e3257ac225de47b8a52ad65699f8c7efa64676a268f9dc97c46bb23dbb335e79be532e0419583e0f8753a38d2de790a3160d0fd63ad5840601a78057708655cde8dfb08060cc0f233688227eeb4a0f20d5e9d58bd858ca3e338ab402011ad975503cd5c86ba3f12a05a26f0b0f79c9a\nTAG: ca40f0179157bae889d49b5697a0e26e\n\nKEY: 1ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd\nNONCE: 42bdf685c73f9c31abdf1d28\nIN: 419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a65187b8cd45737c8446b21301be1d5d02ca6af5432cffee125756ae7bbe2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5\nAD: 358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea\nCT: 2422ea9d13895921401f84f25a5b011eccf2670b1f12985d4e2c4106829a7ec3c7c75f11e348829a8285b34c745d8892bd1efd02c27a6764311962302524f787866520a562ffc9f0a644c242107a7ff868e20ee2f2da9d41e2e85ef00815e6dc2f242a2fe8986d40e37a59f53c88a168d230745a57714c3e313f8be3f4b780c61c0638c3637add213b1cfd5d07255116d9fe58dad2941f8bd7aa7c37ff7a041419e02b8575b46be6dcb23bd5594c713c93f8415e5da427dccb6f3b6d649ebde09f4f627beff5647bcceb10413f0a58f04d3a03d3a59b4d9f578508a21bdb609a7291bd8863e091907f83eba365e5df61991836fbc8df69fb7d6ecc15c85c8dcf99f771b19c995ea85578ff39ad5e1eeca002dcf843f471198d1d4359845944fdcbeedefd158ba9dfc2045910a911905579a35a4d7749361b8197fd69ee1c988cb7c1a6f5a5db2e926b4b2a0cc8c5a6c01fe1d04ece3bd7d2707c00e001aa097e6fea51bf87654f389fa4caebebd513527c186125fdebb3672316b57d12be3619e125d642719ac96ca97dfb7d2380800e48d8fc29b4e50c81e6238ffed2a3e788182cb6ac51023c587a66b3617734d18f6c2e4c959b84f04609eb81eec83ce7f8589683682c683762355f9a8c72d1423d67da7b654c00fadac8fd2dc4ba22017228acb6b287101719726d0b1d97e9ca2fa67235e768732756cf2662a078c5ca753275d1261011127ba47265e7565422a9da627085f40fe22b680286408004ee5db318b0869f8f8ead0e3d1b4a564e250b6ce61304bdaddd2686041c505b91a8e3dfe411e932549ee9956adabba04add4808a2ebbf0ed92394fbb00c1466ab06f964a325a877bccbc47e0d2ab4e24243164ab4166aee41b9222b8b42ce81668ae8d1ee8ca5a0c2698616183cd4c025b6210a33aa7b72dff37ec40f749fdc0e879a5135967f47ac95bb65c411f0306335afe6d7a2247823decb050578\nTAG: c867f21b1b4c62500ab27499d11eff4a\n\nKEY: 16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f97214\nNONCE: 8e9a0bc6c897d4fdc82bf439\nIN: bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3ad3ff84d1442224006550f6006be543f7712c5edceaaeb3360ac7ae2e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1\nAD: f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a", - "8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7\nCT: c43a2c260b2421b4f4d0016112a6a90d09f5505f982a66355ba55284f15e24734afdf58bffda6878ed052c5c97c01ef9214e19057b87db04ecb9e8a72dcdd04e6c8194283edbdec0b3182f73a009b5b7ee42edaf82d827bbd49b21f9b33b013fa934d710d38d156f35491004a9f29b7fb11fa60be85179d970a95f6a4321c2250d3300186c186adbc9151f94a916531107237c9f51f1ca4a16067111b3357d26c9caee90656bfd4317c2d52e97b87f7adccd296a295b45a173780db1011d3dc010b8b951a14e0057451cde7984a62b3e29dada4cba1cd5bbdb32acdfdd6160fd41ae42c40a3f294057ba27737f815592ee1ca89a57db35ada5077be4ce805555bfe57293552296a15a9be89473af043f193217ca228afc044e6e9a8ad57fbab59ec12c8358361f38eb9c00b33aa97c90f51a5014fa497c102b7f6dc0e0678e99e7ab7b98cd2521ea98ba31ede92cf621e36addf622adc7b0f77d8df828dd511b9e74f0925c8c7df1ce56cc2e5ad79feb27de705d780c2b77c931aba6a032d99f658f73fd9b9872959cac0137e9af2a565ceb6f73b011ab3aa14132422c14692f7bb3255cc96a3d63dd167028d4221fe4a66f0a010f35ee42d97326f3638fd15cad7d9afa2208efc4e2f0203d1254d93bf532961ab24df78a6a33eedb0d250869244c17074a283ea083c211528e91a13e0c585a85cf5887b09734a5aee9a01a0de3ffaefbf3791d1b1e478ac1c369e9e0e4ba825ac6590aa011cfa0ed15f9fdcb0f386fe1a796dc243862a292844b90d32db05ad0eb8f2839fb386085b7aebe12e7477d5eb5ef9b6603004b3c2ecc6e961059b11495d07ab2a164c64cb0d6f3c94555a5c3fe5cc687601c03861eec326b63b614cfef131a89058d0b320f1076023884882aeda8f28daa0a3dc96ff9ee982925db55fef48586f407f576c5e5b9a723f1f10427304c19aa1d39b70a12a9c9f07ae6b76faeb66f4b26cc00febae63ecfc629968268acceb5aadaca\nTAG: 59e3b0e92ae4aa57a2fc4a19b74e06ce\n\nKEY: d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf83\nNONCE: 6acfa3e2adfcb7f880c53c1a\nIN: 8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d439ef8200a13e35000b40e9b0b392c982a4377557abca18c1f3bf774f4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4\nAD: c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17c\nCT: 9d4764aa97244b3506582c24cf82947430e6749bbf3a907a941d398b39950dea9c21aa637a6d5030d9b070ff6c810a0f63cbeb107bfe1d91a2b3a71c2683c2d2716759a74f9c022b88afe5f36182153e5378c12f94174e5014743da44601908df428d105362d6299f2989ffbb67d45b65cb2a35e888d823605d2215f325ee59332a066b8139e01ac2ad5165d858fa809343fedaad3ceff19c50b218da9c1ececd713bdd657b02955afa4a90dc2f426cfee4de4b1e097fad3c5183fdc84725db9263bbc207579175ca3171e7cde14b652fa50c2032d59f2832196750731c2268c6f807625e8bce39faed8f85dfe5fe1cfd5d60434a753159b7196cc69c2eed5f50907299a53092d3f3d41bf7c8e4213d9d543bc235e50ec2f569840abb26490f1b0167ac423ee0a680a70797821fbfe7dee33d9ed120a95c6a75596e04eff2263c1c635da44322d18cf720bc90a113790b9e9d5141dfda46fa2c9eeec5afdd43ca5c0ded8a5abae0d3243ab2f81f3ace681a07a59afe8949061e21f8ad0a9d50e3c8d36a6270dfe9eb08451323f71793a5942ee7484cb1eb033037b209bc8c61b38ea28e9f9c2a4cdb629331a1517606feeaa0eb45c69958df6a5e48204489730fa83aeed0b2fa3e555437fe460980e8813e0521d88100088bdf6192257be14eb151d6f4b5c6b0bc9ca6a0ca2e2944d6d51e3bf4fed6cb7722971768da931c1f1e50872f25ca12e72bc984f48010481924fdaf3c744bd098d2153487617e321e665ec9a1346209695ef6b1e0e79f0c4fce7d33f57087512559a8290d8679555ea7f1554ac6374468f3865a2bfec31f27cbbc6adac1d484ca6da48119d88295cacf38b427f792f25f7d3c341a904dd9d3774e355edc0db3748d65506f2a0bef5d8abd37c31daba869dedbf19e3aff557b0466352db1f5820f3b494304604fb6fe42df9dae1c21429ea37258cc087cf72675a15a8159e33855dce7a09a77ba8ff296ccdfbcfacc7adb6b7b020de0bc302a7fbd1e3b8d51c5b1f520d384aba\nTAG: c22896658ca6cede859de01b80632d9e\n\nKEY: b28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea36\nNONCE: 79bb9a78d035bd8ea9e8ad70\nIN: 9f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176abbe5e520c0ee79153c976d71e5c6dd576f4857ba2d63e04d6b69a2d5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb714e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f\nAD: 3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a788432569", - "13cad2727f9dbc3a8bd5\nCT: 8cf78ff0f64a19abecbf693d8575602631303858623968c8c4522c5351ac552dd3694b0a04fa270eb9652dbe58c07cacc2bfbc927f22bf561bd4cd2d639a00b240f41d6af836ec3f93dc0610f08d59514c49351e25cfbbe1ad05e8cb21e25f144d926b5752f96ed7dd05c816cc95f5c3a008716c8a18ada661ecc497c6e34540b8924ab0560c57e7190ab567762bc5ece63883ab5522c8e84efa3dbbf71179d6f286127f01e8b909b61a16fb2433798613fae1ba08524d734662bca15dc70a550740d1b741c0cb46528d061c786f129cd49a7f5b9c1f742c906fe7592e70a5185b6b1ab669498bac981f846dfd2401be46c0972f8945adaedbc7c54cd40c8dfa781c0faeb6b2c0150bfef21ecab2995da3426be508f21278a668e81b25938dfe2f8e1f85c8e69468e38ba924ffae71c1e1c990656d42c8069d120c75e840a2df0ddcc88a77fac1a4ee56d3bb00cd53daebc0c981571d0e3f467d2940b4b92c359afdfcecaaa4331ac45f0afd902e8c5815266d195e303eb16960fcc21162f025d5258786963250aad37610c6b191e479bd5ed29b8cfba9df43131feff2571fc87209b69d15b6c380a8623428f01944d6d5e56422fbec4f7720b607901f06f4433fb252ecc251660e6f9160fefff8af8b866c2edb11f6419a6bf91c5fd557851d469c256f511b9acc8e71750587e4ec0482bf4ddb0b73ed82cce239a4d9c6b330527cd8d529675c2c556456b10ebceec05e7971580b553b8a5f720f8ed38123f56869753624f4a6cf9036c3566cb4f6ca8e0f36d914758f07e7f447c67c8b40d703270d035d1cd39b22c291333ac1f628d2ce4697f82ff6c043ede6dba39c03e250efbdab3ed5e73c28e194269d8657862829f7b43192f95766f77a7b9b4c154a787d0050cf11099d372c3f97add6c9cf4a467df0922f7d9e1b17e552b453e80aa050d8a3e4fbf9aaa4c01a463b796cadf65b492f301ef03476bcffdf96a4f5bc933d0d4286bd9e2ac9822957ac9a69fe34b3701d913cabe970dbfa5830e083add43682f261c3aa80fa2beff7942c\nTAG: dc5369a6b0814d58060d033aba87a030\n\nKEY: 1daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c\nNONCE: 7550220b0b5f3c6fa8db7316\nIN: 337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2100c6c8d1e88b842aed09cd16a5d78d4e2d7712e40234292dd1aa27ecbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef\nAD: 903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07\nCT: c6610234579809d78c1caa28765c5b05f33a0c5d99660ef94296ba00937522ff4efd86f760d3398a9029877192dee574ee7b882c5ba28d1c388444137c2ac96c6eb4cace7ffe3916bf196afc67b68e4daf0e191450b04284f930f6ebe924cec498e0cf2925bce9d25bb08e872352bbb9aee31a9ca45e41dedd3e931e3ca1ec79aad5390c7f81e8b9473aeb2fc6553bd0ef87a42dd15ae2edeacc148aad6615f3bda730e50f5ae8e44f3639c94242252c2b4b44441f6974652cf783cebfaa2f69e795609a94db16948bb30ab58377c9509ea682a21c408e3b057becf82dc73f1addbdc9b98d659e26092d4f5bc1ef819f9079e0c66bfb684839c0cf1c2e9503afd1ca7de025d4a3a86ac9578bae2d2f6452c2952b57452157d88794a4a872786794a29acb6e4cb511f8cca95cfbd33aebfdd224ba7ace8c12fee32eae1ce60ae0ab6e39766fed2c385ab3888780601cc18a3361468e057d19f97e94ca3bf814bad74f93b8c18364774435a83de1fa867b684a1f2ba8baba24583f8e3808ea7bf238409110959a90c93ae68d8e3fddd8951019e9d6699e868e8f1d156e57eb1d4e8688ef064f18bb8bda91f961d1dca461220f88646bafb0c0bb3e65be33c445f265c0c4e843eb155b5040ddda3a5d104a6d89dd0523e89bf3cc7125774562b5d7a9a386f8e227e6ad71ea9c0361a4e83d9509478a14e9ed8614ce0c39bc9d1ea361cff583ce5bea53cd84083b45ee18e6d4bf3ffec402657c01d54c6db3533ae6ce428317cc3c0a2b2621ca7f82d83cbbbe6571ea87686e20b0d24eaf8489c573353ea3b879b4e7a1f6d87370ff8437c9767d4f99f244d15ee3eab3a1ded233a26c1abf8f010a89d7da628f350cc93529b130ec1085abb62a857bcd8859f738b511f5dde072e723d8fa88fc21dd6d464358df9f972e55a659c5794e7eceda8b780af6ab65ce18814d5c3b38085be841df3b52b8cda8efb8a33fc52d6952fc3c70c42da59aa4eeb61e11ad4b1ba20568da6ddb31a8f1bde37e8c63c440ee90688186b9f222bd4cb369d9e077d0071dd9d6557f5b901829af6a3cb4825c76f05c\nTAG: 78ea2271c0bccf96f0d64594820543cc\n\nKEY: c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c0e2825fa\nNONCE: 3a69b798030cadfb168a1f88\nIN: dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b073571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0a646ee4b0e0dd43479849864311c3f743f2a6cf9d0dad34111493f0e55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9\nAD: a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a56\nCT: a6c4079486af388ff129e360fef12e039e54e4900d091be16df1d3712dea1578f11cb12716431f5c6d26a0719012bb89d1a3515e0821258b65157b8e5a8ab7354ad6efe2530337c8974f3f89f674f5dbfd3e8b34d6d425031e4591b37991b5e76acf5c5c13bd47c28c6a55a81", - "bc2f2297fe42e1500f03ac1d97a348cb9c39da8a95b1a5c4b3bd47c56988c19c1d8c6a10a35322acb4338027d2a32cb32f5ce70d4d967fb30052b86f538f1e756bc10492931b40bdb6a579885b94de17cbe917b454db89536a021c4fb230037a4d808ef71159630f48855b47fa90ead1c54903dd925e88516f0cc0968827acd6e57df044c485ed9872e57308e8c5a8992d5d7bba05f7ce949f83dffde903ad093f8fed3ee11a1c6ab031089d77a965e5a89f877b7c4b23c3118ae50e7e21d75e133ac98fba316019b4c2866257d02e6dc8ae5b476517daf7df313093c176a2ca6bd8312bcc96e4fd78fa94313a6ac1b053e72bb622dabc5fa216ebb3a99c4e760737a29d5f452176efd9720197432cf17e8182bf1af60608359195341fb0246baa0087a7af0a5155f32895a06adf69fd01e6f86fb46377e50dc67d5115dda5b0322eeadc8d7b3bc5d0658eaac577725b2656d4cb7803f28df819df0eabfb4d8a7de150887d168f1ab7e5fe0ecd71cb98e35918c8b739059eafdd254f9bc03064d3e27c4b41ae04c2ccb13042a839f82fe9335df59c6991b7e8f6c821026a0d39accd5ca8007aac60ea324eaba577eceea25b4f31504cd64929576513da857f6c9551347457530fca38b173a6e7fbb7219fe861397e0bb50cacf6368929a5a429f1bcc47f6db2517ec62a40bb8310486612d6362870c3980ebf3223216d9df538649b25a704bbf12374442cb489af02020e6886092b0410f922c7680d5fa89effa7780e31f9222348467acdf049ff39ce3df27006406642c01669b819ab61ad05b096270fa75bbad04e8b09b1c4f75b12761b2e2129559625f46bd1005ce39a4b543f34960f0e7c67cae9074b29ba86867a9b35f0a94d716fc7103266b7d14164473b1d4e19a7cb157fe5e04e83dea1bc886947c\nTAG: c3bb19a713afccf40080a1923350cf11\n\nKEY: 6e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce97d0002\nNONCE: 37e72e6de6176fec75f5baa6\nIN: d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c19c73a26fa433bd4437c1018263e7db4b580a120d1d29775d9d5ced6710ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e074\nAD: 6027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40\nCT: 10327cff240fa05d2aa15a7b299b925a0ad1740957c4fd23ebe24e8a1f36cff5c19007d4fda60dd9d3231258021cf2d11d9ffd32bb221a620d68f2b0077a64a6d575c3802844500b2e6d08ee659006018b6512651a5b903b6d438eaabbd41d0366529788a33dd43a0144637b4a66371a7e58898c4b6d1205a239928c3c3e00907f50a79e2a99f2f675cfffe191f0c584b0e93d72f2a2aa8a400226852fb97ff0cb6d361342185500e3a0db1c9836bb8981d7b4152a399f84a047e5dcbe7c0dde2a85496d4fafd8990f70f28025519dc56ab2fdc150c215bac333af39a981ce5ec484d3cfb06ceeb68471d730e9a6a82d03a4b29dc8ba5ade90c55f6431109bd8c8be337033ca49c4f75fcc2b93a3103638d8516622625749dc4ab0dca45e02abbb2931895f3720bf0d915a6f2802b9a402a5a9c1f47419df6ac9fbe2356cc6c51924bc7c6d9399a92688fc6d75a41f69e4f91fd375df325a75dfdbea2084ee9dbead62754b4b97cd7fa075f6c016678053a8d6cc4de4dddc2c2689efcab3281f1b7f353b3e8710fe396e874784fa54c034aedf078524ecbb18f5bed06a88887797afb0442670224c3bc3e0b347480b7d84268ecd792641b697cc7ed431ff0db957252ee3ce4ab0dbbd47638c15fd0ea8a25d3f3ea75a81dc9986b240ef3189f323a342857ac59900bb8e3bc429435b4c00cce3aa6c516d0c68456a12929359b0bb9b02b349e63c4dc8bf2ed107d94af97af04c14ed454f3920e1f354378c20b3be5c12adaac6d96eed1df0496172a71b585e3f5e39484578475e6c257868b3d0bb45cf229c0752697ab66106a675311318733b02335ce46b1e035a92557d2ddc9536634cbc516800fddfe358d8848198045d746a5b6e00db3d2d0b22f7e4c4d5cde136f62db48968eb360a6d8b645022066ec54f2f2f05b3b8c9af2097986464ab60ad9f05cb63cd194e501507babb6103b96daee90c70efa78c609f95a20e85b26f2d9bb503274dc40aa0aeadc485a2859b3497f4688df1b2eeae81787375dbe3f9fc6ac8b4bfa339b92495d175ad6bc67856b58c1233ee1b0c2b524668750a48c0704e56da23fcb015be58239cdbe228\nTAG: d5bc1db867fb362965c9ec4e686d95e4\n\nKEY: fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de874a\nNONCE: 859c5637b754a4e7c1ddc3f3\nIN: 4dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f6269b478e1d79f3727831086620e79dd357fea1c84ec4de0bf7d6afa2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496baf4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5\nAD: fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a9\nCT: 29e739b7162cd3504c7a70f3efea5d6c2282bbf1fdd75224729aab622d59b2f680c92de483a46d2e8c45460c8f3efca1fb374ae8a04ab84aeee0c083a09ddae6cbdd1803e19b27fc1bbc4ea58ded24f9f630c16c04b605d107a5fbf640ff1225c919dce7b6f73b1a18aaa37e3d0c757e006", - "2c0de6c516302f246f246051e1a0462db91e5ed5e1d178c3b384ff9d1ab3244b861b4c34e21a7ab194cc3d48d11588f53604609af8029a6ffd166c08a8f669da73f465efa2f0f54dc0e09916fe8903d0ceaab4e55494a043160e6962ca21ec86e1c159532691b34d507024a345aff411b46a1a32f7844ae3e1e250bc17c0c3edf4516231bc574d742b0b2411ceaa3c4cba1d910843534e34e3d405be0f51a304c80a858664142d285e84b8e008fa7247fc0583dc7b8de3dc9015f4d8e24505d1eadf4e7c598e628ca6b5c70dc6fa5c1734cefb418d62cb08b7d5fe81543d3d1b438ecac5359a0f1052e2efea3107b2da554ff669360db0062052917abc854ccae73623175f7e5ad37484609bda0b6ee3cc87667fac9d1d3de9fcd104b190c62e544be71e9badc2440e8b451532781dff81b5a7ec4f80d3686bed8f7747714e994adbb4612406499a6bc3925ab62d566660265ccf2d635c875ac6fec640b515b86ec5a7eeecd34b86d1f2eb6ecc5858cdaedc552175c707d12b677cad0a4b12bb4e717163002607eefddf63ba2581a2b1afca4865b97816e61813bc7ea99f8f69fa5bb8e306d5e6db15293ec2f7a9c4d8ba2d4ff6e258270c9ac7bf4887171434d034875b590fe20b959e0955034687679ddf98a5c777dfc06f11137b52121249ceac90f5eeeb6f1ac59ccc26198388eb8b5deb918cacaccf1e48145486c37bb2a11d371e095a250c86efacb85921129c2e19c9dc09c66173f394f568c47fe4ef0cd3a98a138b1750f3aca91f7677604613b6b0ccc92d6ba8a0c3cae6b7b22be761ce2922ab273debcbe3f68b662038e232430b3e7d3e4142617fea44c0683f0b7eb03950060ced6325409293422d058d88f0b81118183a05a13db7af89429731c8a37aa83328019626a6f2d87ee49f9b4cb39021093e4886d373a292fcf711945f9d572d734f422c92d8fa6e01c4dd778\nTAG: 73f6e44d8a2f3cc357707de856d2ce9f\n\nKEY: 8e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c303\nNONCE: 77ed6ab683ea82545de480b5\nIN: f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d034047358cdc99ac30e78d6238b5478982a2b4ce58537a34e5ebc37ea72f321f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d43\nAD: 51c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac2570\nCT: 441def04eda7baf0e6edf24863166860ed05c9c3cd0d0c71a383b4dffdd6b5a59a18936779e63c8ce5a3ebcadef82c75d3f241f62d66125b4b4be0b8ae58e42d45421cc68b42ee062d1f6c12a75a80e854a1e44af9813e9be4ee85ea3a9f34534930cb4c51108160e4df6874b900cd293815a1d5bf2b064fef51d0fdce0e077cc26c4d405231b50a1c26ec03a8e956c9605cbb9b4ae68143342f6fa46a651cb39aa783abd0f6359365815aa8084102d856d860f7f6d9344f3d1e65b0af8c7d50f83afd151139808f651e23897331b58dbef7d301dad4ced88feb5db48b6b2e05e1c8cfb58610ac3c58cffcb411dce628c1975d5718631c1c1230ebdd40e6fbb6c2442937f95bd3d6578189fa72cbc963b922d17399439bad035a64f39e78c4aa7f0c4793173131d11c7693aca45c04e0f255daf0b1ab45c3e0d90dbe38ac08782f19325039127454e589953859ef87cb2e4edf1522f946b59b8251a1c154acfb50f0a7b0a349537e17e5de09037e385f51ec4f388517bb1ed1cdf891cf4fb39ecfef69eb553929c82941e078e0f4527614a002a8b8093e1c1ffc8882ece4e7f23951df6347d13b0e4ebdfa76b4fbc6baeda7411883fa74c8e0f567065e4bca86570fe31fc3738fce1469c9539a398a182756d26829b42e7d2f4b48fd35aa2738144a8df7e08678768cfa2e6ddf887558215bb44437939dc911af50cfddd936346155a3e543fbbabdf571cfbf34fe781e5db5b85791ddc465966c001b06efa95e5050f0a422d3026d48604f074f900ec66ae3b8f7b9faa7f438d28e6233428d74dcccebea033f2b57e8a9e77abd8f4fc7f35680062027a20a88c3fe2de501dac972f0296222e6f4ba0943a9d562771d757a8fd002fb032a8bd30f05b6aa0926e4a86c6f7555d3f1816c68db915d71ab2ef9492b97f0741be24e07108fa3e02167b72b5976c83faa4450b52de247f7c54ba7d0e65e44575a5a53bfc37e807983fad7ca5bba4331abb1aa30c1444e131b83af8d72e51dd248feca5e025f6ff0852f929c672c18b47d9e057def886f852ae26d137492d24f8a2c903b84d88b92a3f6679d4039aa4e4292374b66edef378a7410ac091ec61561cbabd788f090d418333794dca3f9744b25b9b8c2b065ec71e9297c0b\nTAG: 4a780eb826dde2371feaef229222cd73\n\nKEY: 71132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132\nNONCE: 7840ceed28a572c5186f2546\nIN: 2a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c283d86e8371cf7b34cc9988005575c8e98ad34184dac039f04f84e5e8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d89\nAD: 6ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177af", - "cd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036\nCT: 5493a45a3f9edc2fd6c8bf53d3f11be1262ce77f5845c1d47b306e486e6316abbc78fabfdc7ee8da152ded9f36b7ef3ca0ba8e55fcfd865d449fd6d44c99f16ff0280cc8e596889d737d0fcd4211e1e5ea7974698985ead5b8def15a8779674a6cea0715525269d2cae64ecdd8870b9f1ec78d6377edb9c975565eeda60448eb1c871bef0d951514640cbcac4e663942594f0bcf4da56fc56b961464d1777a177b3355ef3b5618f247035761f2cb7dec1fe2bc2ba3f825ce545e51b610613bea6c125a347aea55f8f4f5cd5400e689cba199105170bfecc8f0edce6a9d521cd1707cfb5d12f8f5a9dd2debc5907d05513a949e102e7f29d5ff7ad22eb57d429eaeddcaa2915333f88193f668067a695085853f7be8c0af38d774b3d6cb4ab415d70df8aa02e7461803f597108b27d4838d58b1476c10b570c4f8fd71ed9baef88c140163d5ba69a3c10df451c12a5c5cf66c2ee546c6da004dd5d671946df34987a19650ed8ce9e7ada14f3213d642a9b28d0e376e5e37907b7cceb86d0403b19fdb48b3b732633d498d847c2fd24e0260ab74dce88818941c6f8d9e73daeb7652c55c729c3eee7137a5b80899b036eef89aa02bb730ec277d26bd6498e7d4a2b8208d035498b8e0ff403b2ccd0ce6e9899e984a062b5bed1508f23d485642843ce34b5a8322efb9af3e5c0797c2f519d7ac054304b59461866413b0db05791fa9f16661fcd3d9d86291a48cd61d4696ee685a9aca33b93eef112e2dc772d6e304f150042fb49fa95edee661617d7ffc5624b346a82847249c06ca6174d8a408ad46d3c3073e7815c5e86ce31a82587695b2b6c89ef52c20a0ee8adb24263df1a52b4b3bb68b6bf775ba0029b36edf2406c2509ff633fb4e7b28e0a4d5260d48c364cf99ba662b65e3ac150fb3039f1d267e152f569d708c100121565d72e0f728823abad3a1969a4ca856e9f0f4cb0315f973471a4464ecb348950f95f8efc5700d5f2f0bfa9e4c951a9f37b576695d93a8ae5f2d59f0842f3ea895fb38f0f34f56dc498fc0a5d8816e8346f90215d68e86e69d656b1283d349200ee4935ce5acab7eb08b2e1af57a603a42ba3ce811d8b8c6d6af9796dccf549276ad7183f16a99c61e0208cccc2c80507ece9c3c44419e01a2e23abe2513ec13187d54fd422efbfe17\nTAG: 975dfc03c9b1ef9a854d62ed2a0b628a\n\nKEY: b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa84\nNONCE: 3473cea023d2c6afdb625b64\nIN: 11ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e6611562d15bc2b910f4edcc981c457c0c20bd2710668b59242f7547d2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e\nAD: 86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e33\nCT: 0353acae65a2b86f88795b91e2feb614ab78a508c57854ce78e70667db42d0e8d1288b7e5b55ae50e95a1e3362b0ac3e592ac497791cabcc70f68bde6cb9830323bdb3d7c47d35684ae9a81dcf551698258d0d132eab80cd8926b71dd784f7d87f18158eee49bbc220e57f77c65258a5191ed15d10cf306c4fd22ca91d92f28bb0c602baee0bfe31de77350ad2637d3ea7f7ec04f4708a64c55bf0674dbbb4e9ec7e5ea2db16e3aae57cb3611d46ecc06d4796a109a14a0f714753e979a4b0090c99622c28b62680d437a9f4133dd20ffbbeff73e3a9b47b7c788abf42eaadd7b7284bce8b6ea4cd3bfdb2320f7f3016ebf3f06fe255555c44f95693db7de6470e27165e5ab0640e674c321591d4fbc941b2560a62a42535274d3a7f635c922416f7d9a5b9d22843fe601b296aba676802eb55ece3dc9315d27f56433821c18e760ed64d47b1ad6590abc0d75e7d078aba97d697358112347e39b15c3d21248cb839b23b6fe4957dec22b1e25efb4d537bb0cc8b23894436990583627acf4def3a293a4b9f03a3e8beae184f9d11b79d632797b45e972cb9812b91beb1d861c27728b5cfdf9e370f363a6d85120aa1c21f39e5d52f24430bcb019d328855d7d77082a9a331b788a3bf9dabb65f70c20b64aa3ad3625dcf5cc3153380ac7e61cba17698c387650c8c73db3e9988c10d093bbf5e0695a75772805fd5b2fb8eb7b0aa91b453ca2413e36b285800873339311b63a67bb541d7002d5db39b016c03522023ee6551195aed5154ffbcf126a3618c0431d707104438f2b8964a3e0602a8e22f509e390ecba15c999b14a677e49ca95251d0b5980bdcc7e95714fe28a99023af2c564defd802e1f24e544a040ea295af20e9bbe89df72169265cf183961e78b21020b863f3012c6e4087634bf720884e001ec183711ee6ce14f653fd483c0c1a2719b9dc9b5c64955ba8ff8d5755b0f1dad0d949800b1cca343276efcf6e7633dee3675c8812790fdacecb8ad1e458002ce0396a9d7a4fe030da5582b8ebfe390498407abfa4d1d6fd109ef6811d00f7cf422580f63b8de9dcf66d760bd2c925c82e521c9edfaaa6539e78be6acfcbc6a3183dd29009ea6b51f84528056061b010dc59789cfeff60c15bef4de847e6c3c4cc1e127d6d1176aff9f7e208a1bb70d85ae3a1a581ef08dd6197149abe068fcc5482\nTAG: dc652a0e99481d728e090f5b4c9a70b7\n\nKEY: 4b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72f\nNONCE: a39926a47e0b75a771783631\nIN: e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e48a7302e5e5e5a3f660bd83aedbf1e2a88ca05db202082d8a59d11b14f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92\nAD: 116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70", - "f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817\nCT: a8afc66ca05ccec231d39098ce3f8982dd55b80226a821f1a97919ff7389b464d8cfff1c65f784eda92bf2cb963e41ff5997ed60d23a80401a2a73a54ce880fd8c56284eacdafbad1ae72c4be9ccb761dba1a0dfb0983656b9749e05dad17c99fe2786fc21d3159f378db39dc227d2379f3851e94183df5c4cb858223a7cb43b68651cb3689b886a4ef24fe879205d0ccfd81872b6dbb0e7c9c5fdc0313130254f86e80d7cb044649051fe74425fe55e7472d396d8e15380386de6f8ccd303a9899fcaa63641f0e6bdba3ca3361566a2f89dac8ac9410032eadcc2d82123eecc677c7b16c100d54d8a297dbf30c6e9479278e513b500e74beba4b4a04038fdd68c96d5939a4041def41a6fb35510b86328cb2b8f6e80d9acfb555631acf856975464b770ded81661558b150b0896ac28f2946c63c9823c4efdf9595e867490e638ef495ffdd3045e0ffabfa669732f6fb3a4869b290006259bb4e19d49c5e88b02440dcac361b7bf6c60b09b5b597e9abde536b4ed29b1b01f386a5e18260d707d6ed9b67be012d0485fc6830c24bf4b384d2eff6de8b38b88603aaff7cb61b0812b4472a63758883bf5efd35680c85e4443b56e6f3097037ac92857ed2ce434cf5f28213539be251b28d3c8c5ee7c04dc6f4a3bf12ca24ce79a022bef0f4de9789c8dfbd8df1c7faf10f8379113bba9a3cc4f48e7d984f37c5626705c5f04c72e85902db3ee40dcdeed4156f68149b8b54722b93a926dd2bd546d1dbfedd4ea34847166fa4b6b325534d88e66e48aad81758dc45e461fe001a6e400b68d2974852950a0fe218933fb601c95ef818a85130c434e559997d5d534105441d0eaa142dad3e4ee686554c83128a1266c68c6186ae2a7935eb5a7dee455fc41025741a539fd84d5acaa60c9151987031f61cb3951c96b646ad3f9027f63768053e7a7fde524dc7bafbcca2819ecfb802cfa9367cfe54a1f0be9f949a471801b81d7b5d72be9d377c97cf452eaeeb243006f9dd1381c0e77f4215a8f4d62f959b83fa9e8012c121906f0bd2b688444da3e2377855976b5c68c888e0a244ccebc9f22f4051d030bc95e256fa95cf1e7a958a88d6fe5ce111b287c24e0e71e4928f7572b34d2f6bfce3a2c6fc89be7d54a1a7c222d5cb8fc3a108c20a1e1e55e6a2f3018c6bb2baae63c3cfbece1fe0959456c1506987fdb5b83acb5e4cd2112a0b18c8d0c0afe438917\nTAG: 21d5eb52605d2ac429b971fe32cc050c\n\nKEY: fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e\nNONCE: 2eebc2343a402e3efdf91f7d\nIN: 63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df46642344f4f7c9ef9a5fae05c10b2e7ac41afd55e84c213e1d5f58f4c7aae4f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f6\nAD: 82257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f324879\nCT: 90cc04db6cb6754eb81e088d126829648e5b3ac91b89162b3046635f95d19586eb89646d9412ff3c28321504696d8d8bd7567214345c1e694eeed1ab5e3648300eef27739ba0c286e5f6fe389ac4b05f13e92dcf747aff418c97726e7f0820ea4e93121cc2152d92f2711f64e7a4c66e74c21ad58f80218c292e6d152fe5364fd2b186ddc811f8418d5ee5f7a03ecf98e69dbef146af1fc4d7eda7c261bc1d4d3781ef2ad9a9b316eac55758f97a73c67031886e867d98e1f7c126f19e0aae251d92781ba3ad6c949e677f6f71a0d26e45a8bfbd9c7a8b8fe4d63e687a2a476683f72203f24827a0ebd3162305f4c6e180eb3a7bf5ece592af7831b52479021ab76223e7d0714e0a08d5a621756b84d977ac5a13124e9206caae9c6a2cba1257a81903045414fd6e2403b2d68f07becc2e7a130366c0397a406ba261dd800c647fd087f50702d25177d1cf0097552365cb9a729e27ad9c1e4a61031374d362e309c29f649c7774756c46befc17a7c403a821ed254fe7f16542af8060c5743ce91f6cce0ebc68072c305a1f6d0d97db2541aeb87759804e15308e2955a0e6110c3613495115d1066e3701102531e04c1128ef2dd4434850a6c808cc827c27caf9d2d33ce1646228c26f6d9e7a0d05363694198bddf4f1603dab87e5b01363b3cb4daeb0eecedefe2614bf6d09b01813bb0995615d06efa5172b11d08a46a577fa99aecb30e310e84bc3049205534e836a44fa2de79134e6e7d7fc6e19f841e3f31fd5a8c91c7251b7c14960e2efecb2945dd64926a3d7052574a9f8ffc0f9a6c62025f58275a4ce3a084e73c1094834c65f59e09d4dd16bc75e26810506f0df6e59ac486439ebae613356bc5d8245e15a2c0d8997d80235e7475f6841b6e28cff61d9f5ab11a718b7b60c125118d3f77559aa539c1f15abfb32126ef7a9104c6902b5f872663539f78b002aa11f2224f2b724e346e9fef6b84deec427a05576a51aad885e0fa15e083ff25a1f97b7968dcbbced7b5f3da137e0b48c5bbf783c7125f6a1c7f2e707212bd608bd09d12104ee593838842b127a5b8050a0d411417a5b88ffcbaccd32d1642ff00ba22e42e8827b5be97318bd0a69b06839dce80ef50ca43778a60dcd7193af7ba5da86149f7fc716c22fbcb0b1671b968da755f527dd2ae05ef2b6b8809ce38c9cb8b7095d7b3a9afd16284334da5f0d85b70068646f4ca3c6c39a2ea1d146b84662219827f756b2d1ec641f\nTAG: 8c7269eae0df5ed6c8f452fd89c09707\n\nKEY: 20261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a\nNONCE: 5168b8e6c75f25ac1087b315\nIN: ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0dbc3e4bd36e2de49d855196d82175ac39516571d209cd", - "5a8579b05fbb0bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3feb\nAD: e9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c983453\nCT: ac56114a0ed27060f87c7698d659d16b05219d9e013ff22dc90ad469646177feeda9b41531c83ba781c641c740c273a43cac138450eca6c9ff42a2d715de22e0c0e1954842230a0dcc887a42acf1fe75d204ef881af3de7733ebd84a3bed530b34b737a35394097db372f19953b5f9ce288ff8785da5926be93ab67de884d8ace761393c2d3c4d308964a90cc49d9a5a31e55fd20230dd71498d1875476ce257f175135a22e1df34cfec1f31dc788e7c00a483692f1fab826f92ff497253f9e56efc70244346e7fb32180cdb689c6a404c64e391419ccebd9034cab1431be1bb2bd4defe4770d1d9b0cae785592a28ecd3e9dc8993512088186cbea448c8b26ca1c64d623c2535cca60d92a3840a01a9b2b0a7f359d1c597a550b62eb6ffd3d454df319c6c5846c26ccb5ed59e0d3e58aa63615bbcdf4861d85c1635fac7756818a3bd47f5e2bf2b3d14e13ba409379cb62a1b2bb420870879fa522f573eb9b1624d5efbf67f92e50892de2ae454950f97e2b181bae56498585f3b19cd9ea603b6131dfd3995ea29d0bb99f5e6eb6bbb35571d6ac9e52fe02750b97f024b9328ec1dec6aa3a21e391804bf7aba5d3b7bff48760f4fed880259c43ad007208a04a20ca0864c47f9e56b0c969b8a84fb7eabbd58e0d91c44bf8a6ff12225d2c0768c078cb0bf6f0dd67977d801634dd8162500d6440ceee0bfa8750e9411d5a579efb30c34842438105ae2eae6430ae6a98cfba882c974f0f6c870718e4700dd9fe27b98599918896a600b3ee48ec41da20079efff705861c245d31a5d827ad148d0a75cd02b5b7df3484317ff0c2a0a600b22b13bb3b96f2d1c95a5884210e486763cf8d96af48c5bcda8c3ce650d2968981fb003ed3afbd43fbb06502b547f3961e6ec636a12a551a9863b9b89f21dc9485e62a43fc1059d65e1ccab12620ec3a98f2237294567239882c5183c596050b88c38f8be62b364e937ac92ce5f7f8e540af6507f04452ffffb67b51d0e336f57ba71c771c35febbece8e7b0d4eebf2dc0c43df1f42433a3c83a38941d6bbe12e7110f7f266cacbb6fb07d52618e4992a5930e1d416d6e4d1b41a0ddc4ab4a592096bba9437050e2064e0c17d1572c44ea52bd071a8dea305a9d633b0ee963245474fdbb3f274e119e59eb50b63b58fb05ba74242d3ef63cb3e3c98576d2986bcee85d094bd5528d8f43415f627365b08316c11abc433661b83a36129da0550507dd62051a8f5e01c043a04f849899668b3ebd468404811\nTAG: 1dc7ba2dcd3727f14ebee62ecdf66429\n\nKEY: 99a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3\nNONCE: e040d46d2429ff2b38d4e35a\nIN: 3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f4248364f49aea2a19ccab66841c438df5ff7834ccad859bfdd89fa9af0b99214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376\nAD: b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fdf56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480e\nCT: d560de73e9674b561fbb54c6e4267d3101479c2fc269745be89c470109068cb01c6e3a4a7a9ec284606db6e735df2269ea16863673fc35c911fdd6201a1baf9e0b562a847274c2defcc0fb5c165662d0bcbe6b01fe595217d482ddb616ee87138424f5438069abda9dcedd48b29125937e3266cc9d468ca38fec9920ecc81952101c8aff3d3ad2ba4953bdcf26642311ec8c4a880870bc81ac647351a49183e182acd38585cafad3a37a0171c0a0545bb3ee6a67a2da41cdf2397c529064b09dfe0105917e1da7c3df24d2dac6bf06f58efcb38752ffb79e93031cbef73e6c0ad68fb7a192900aa8a23bbb7c6bc15fba8d80058bcf9656323da4c10f19198d9db3b42499621e1d60de8a16046853fa03b783dbd076d0f51fe40e9ce60f4e22aee657246d3ac80913bd495cbcbbaeb778a485bcc6c596af305429afa5f09736e7a78b335f484bbd70a3359a7aa2f4c336f5780f3186fd1753e4673e5234e3f8b803f4199bd859d65267857f8e0391b4e8253fa644a10bf9f68a664bf7573628490b1baa17c23aef5f0414067d2186c08e27eb9d1034aae6361054f2f9bdcb877e72837c70816fabf38e6976c8a5b20ef3a150a5d1ffc997a248ae199d598a01b5bf7da1d6f7a57f982026527e950f33ae33cea9d64e56a3a2d26ed2f2cf0a5d08e6a03db5c483aaa0049514e013b915056c4570c4606e6baefe7c6a74ae301d7b9b6b980d85bb500c8a61c05b38e79db47d2d3b88db098737def0d995267c931a2ef21bfc0d970652a3be8de5f42c20fa43e1f7bbdc34b3b5d2fbe3c396037fa885ec6213748de5a6b64634757aa519573aff1cb78a3191dda039a3c64940b816fd010a584a463cc17789c732d7a099fb423dcc9c20fa1c0f10436bf67f9796c1bab8c85ed76c2cae84ae599f7519991367d69948b757a312cdef01c535f1172ccee7be47fbab14362dc0f3fc89c7a71ec9138b40eec235f585e39b008d1f29a1be9332b2882f6d053acec077ebcb6393ed1dc46d069134d2c37c7f14c0fc9f9e280a6e2598ed8a070edcf9b79a042561dbf3666bc49863c29712d45c41d434172649baca0c2b43e3364cdee11f9da14eaccf8a853998a2a9637b268b6dbbb342575481c37014631180737f970fcb8b8fd5050ebbff873b5bf124b315799c94da41b8b5a4d57210c4e", - "dc26ce74738b2fda9c02b3fdac251b2b317d8edd345ce4a3e074255e8c49d8bd02376ee2aa194513963a220529e6c14611288b788b68e74f6dc206ad094e322fa3002d62101dc4d572ef00c1567f0e7a4\nTAG: 799c10bc86be84658d0b03751a29c71b\n\nKEY: c6e78bc1358c72bbae8fd8dc84038806efbfbca520a9bf9ea1df8ac365a0a95a\nNONCE: 9865ab3b3556ad8da691b079\nIN: 26db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfcd12cbb53bab8c9884eb83f1d2dec7faecbb6af3402bf462f965e2c2281c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd\nAD: 770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521c\nCT: e6ae771db203f1e58b0336c9c655013940053c2a40cc7a6a27e707860b179d7895a16f7a754c2cbf2e0fcf610a3ce97be5e7459cff4684b6b2848f2a39e6c4572c1d7a41f23646eed5909228adf1052adb34b9c44e5ca8b2bfc18a80675e29749e72410851eecaf261868b6b69e7d9dacd5f019de1580549fda721e383b86eb0c51c2eac4600a4a27b5f663a7c89c81401fd452027819b93281b559153c74e5354c320cbad932cab5d261308e241e85c0967a189de09eeced69c834b4c64dadb9447a824bb38d8b8a3fa4128bd8392cd34b0999b4ff0511bfb9fd434a1a0bb3c507c2828d98ecaa9f2dd5a020320f6f31324fd8ba8c175db5284628d1cfc4816054587a6cdd5f9e6d6de2cbce9396e874df36bcc347ef48ee9e6ef7e6cbe976e4361651cf8f92866cc3a54701af59ba03fb8d23024d6be73e1938836c31b303c687c28b1785c5f9b97f3b09b7ec3d83d8e38dcd18c3409db665bf74b85abc540f678bae40157eabb69332abb9c47995f4c412a04f9b99214581f1d18e0662e77a2ef6520a23b5a031153d5586f169923dbcf08d403e37184c5f7977320cb33b8a0d5d7bbb25d7a8477054874a14e3d34b92f7877aed42f595dba8830757f8e92f21d5feab414ecc9e3933f082bf46fcebee2ce5246c2fe839fabd94d4f6bdf875cfa67867f9376281b1e5385d1677a595b018617f44c6113f6178e5446cd28facc9a53bad29cb5b3a3b0cd29186c24339ea008ead440041c6bd0e93b92ab37e3692ed13769d147a1be8335feca11a533156a3e416908d044a5a74454f10d3e59e5f9868c56c517ba1d9642c41c6a764e74540611545ca90219ef4a0db0d25e92196d700f4e57a6778d20b6acf7d1db8060ab534ef409fe35c30c300418641368f0a3ed2407027c126e967406809524860cd88906f046a069a22245d9b2065cc5fc313a7ad79bc7035cb681a39387493b6be51c813748c008269f0681e88616ecec8a01416e4ee8b7a6e4fae2af9648ebb89523434eeae6e5713eb8037bf173e467a6da7d6cd3d357e3962aaca14c03b04046a4f893106e199062360217afe40f40214d28e87eaadc175ccc11d172f6cd42e97c1f331e246f7660fe22717d7f1e24752b1b01398e4c8bead71d8f6aa2d230c6392ae21d43bd88258c1219d491b8de12d53bb9fb917eecb0c254a4e9007f789699de1dc90d35250c6ec4631ced06cef9dc0b0416148835be0be3dc4749d4c2edaff37d7607c9a3e872f723583a1566ee1fa7be77b848fbc4d741ccef311fa5ccb7c18f19295e53cd1da935d663f0b26f776db6d479b4cf3d\nTAG: 4fb43763c09a6af54ef7103ea40de1ba\n\nKEY: ade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa586\nNONCE: 97121394f11a1b1d9caf4e3e\nIN: b2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302b243593177cd099dbacd5f8efb412a95132b8ab31815dfb463451fbff63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b3614ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc762d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb\nAD: 20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac5\nCT: 0d8f126c444afe37e40d85b6f0c9f02b2232faf975d238cdb227a17ef28e18afa6d88d7d23b99826de9f6e7390f67c2ab722e1be3e5d9f3a2abe41e508abbd22897ec36a70d02fa54db8004fa3dcdfc729d58ee12ec5b1c", - "85346289f2112c059ecfcfeb6e4723904ef1c5e3bd123d302f6e4cc393cf62513cb3e2df3ea822692edd0d8533d6103f22940cc82116c4ff1e5121f0ceb08ee581f40ac68e23c7e9a168661e6d93259e614a3f962fa2ebcfa3a4736f3490d401afc9e6aaa8a8d00ad6926b3a99c6cd2b3b05767cc5b45901d0c4301a68c0783bf1611e2cb95d6859293b615975be7e1d829f13eb4fe601b4d66af3f28171b02d09f820dc77ffdd22537ee2ef0cc291f785c466ea45a0dab45e782e7ec3d4bf0622680791883f89f9926009f6b6bc3fda4276b79d5d9070914e75488c033d47c58defe6b538c58b106fdcc8957619e008f6b508a87d85d4a46364535e76a890716a215fe5f2ecf50d8fc0d8f68d2ee0345497f94525c588eb3d21d66caf1cebec2685020523998cf6e24b5fbc384c32cad31a2345fd88c8b820276d5917d71e69d54b44ff96c8411f1a7b6267e20d67e35cf274cd9031dc157d5638f5fb8faebab2f5fc976fc928bffd8b60ac8d8932b8ac076a000675cc05aeb4d8306d65c6060a46bc200193d56249e605a7b10fa28f7a04a72055cdfc6ced9a220ac50d3c36ceb4ba5405945307f2d332a9a14487d7a74ed0c379623e2fdb04324e515e1d5ede3af27fc5f06baf8d354f6b68621e372347817cd3acb05df1817511c978537722f9a4967db31d24336704d8d7f974afedb487ffc6e877bb948f0c30fd64be7608723eb732a6be38394891e8cb789cc9ec2e09b8cc2ca76b56ee7e1d5e4c0bf76f28d705c61104b508b1c4c7c1a1cfec10f25676ea55f73c95af3fd34bcde939652fa91f5fb9d8b783dcacca1332230e2104cdbb905511e8479da129ad64acbb569809ae2a19e71bf7fd6acc18e7087bd49997e3d57eb19f30afd1a76c42ebadcc7f8d231c0c28c7a0850ae5463d1730def54c24a803bc1e889c0719e364492cb737378f7390e5ae506d36a7f42bd86a6184cd6cf0300331d0f54cd6f5b53200d59eeb8cbec25830eb74b0e1d931073dbd991c8a818d9d7f2b8691fa2b523bf73d9c7f101cb1d83699b9f5e1b3545f8efbb8eea286728045202ec8f81c71bbbb6e888698c69b92563615ee7d07f66c2495cbeeaf15825fdb3a3dbaff7347f5b52f6f886d80464aeca6e35cef31b6909bac29079ee1403f53a6ec45204694e967bcb318f91f4af5e868be46df4082f4e77c627bb34b017c0f9d9889184f8e88d62613335\nTAG: 3350bc1b6fa4c20bc1c0a28bc766778f\n\nKEY: 32fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fd\nNONCE: cacdf99a3852e9ca9516be08\nIN: 987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f05d44b6e557031ed28b60f3a9e73293d03f57c9c636ff9336cee086358c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de0\nAD: 62de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b34\nCT: df417e819076b3a8ae2fa8f0ca968d5be1f31c4c44d02f29f9f1f69c8d2c269835426ea9735aaf95da0cf92b45d512ee8e4b073b40504cfbe9efc62770a0000706f16f7cc350080e52da3501675907b2f657091c1b5980d22bd7dc519203a80c674418500224900d74a11ef87d9f60296ff5074674552263b7b6b249c8adde311b98b4181a3730c101c4ab9bd29c044272751197498e8baff4a8f2558de20d4920ce21f4dbecb64e258d078974dc6c2d574ebc8c8ff32505db2ccd349e82808c44eca7f4ade2ffe9ab1ff2815fd282985a8de28147e547023f0254105d2d35aedc5e2083bad31e05ba905c1b3c53f354aec095add4c5cb40c51adb6a2c290a867ed58b05b14170f8cbaea863ec74a3abb66baf60608721b96c63da4b4d966d1291a3293539ead11167ce4e45f0f62cfef30962d2c979073cd7d0e89899397cc0ecbd858da7de3975fce6ca3bd6759581787c5559bd41dcdc177f6ff4a5cfe5b82236d467f93abf5b2abbd30a90cb25b4ae6723c92621820704542f9d5215258962c67ce9e9e2427c58b5819a709488236f12c1f2a7f5c915a4cf2f8eb3c103a4ab9769f76102a8f8fd73aad7c7b6146768f3a3f53b8e276a8634fc50446d5e0cfaa589a4a7fba9a8095f9567506dd6d2fed0c1e3146dbdb74cd116c13bc5a7ace595a2b42e0e3d46c5232cd92799d6ebfbc06c9d0536db35295cc4f7a7a28bf8ef3c649833d5f330196de4826462dd418f95450cd431454cef7afa6f2f4294ab69bb3e588d3b9300a593ea80890e9d678869e963e75bbf281b61f9f7cb9a3f9a773f2343ea306bea4609b03df78e57d5b9f682e0c0b10b57f360e1b0b9058c12f653b3e1fce60579b7c2ebdbedf0090fac36e72099ccf58d1bd5d7c26701f29f656261e8c2e7d5ae97b224293ac133b2cbee65401f8d256d5106c14da8c837ff48f2479432d5addda274e72ef5810fc3a42ef9b27e75c89bc4d72d6670f855f228609eadf8dda76ade9804c642b140117fce06bc441cf92429d2d3b03bee775c1a52dc409fa4e7a5d3e39f9d9a250a288a29c9de6abfd0303f676a98025a7954fcaf6406d765a260e08ae5948326173f44f2d7cfb5ca9777221f0c984699a9cd1d20c9dedda95b8f066736b372d23116fffd55f7b03d4c7f63a8be3e7806718fa6a961a68db681edbdeb4281c0901c2ecc895f9da0cb04cbb03b5f1323e00c827dafd4d42ff767ffb7531e412d5ce11e0dc469f7bd87549ecab2ed21ee8deb164f67e64bfcd85d858f79c20c8bd4c37d7be76ad6d3c040a3a27c13f70f14b895178ccb02858764e315158ef6cdb827b69dcb24a3f54c2816a75be64496c139d541302b0b71849fdd92e0b83d\nTAG: d8f838951f98deb27747a870cf55713f\n\nKEY: 4a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83130f197a6f35def\nNONCE: 3e8e2c6598e6c0a8ee6b0da0\nIN: 1dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2714f39851c1fe09297c8c69dff0e62be3383bb6aceea0cbc71cc7783cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95", - "613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b\nAD: 7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a944\nCT: ac837bdf77bb97a1bac4cdde49ef8d6c7024f5f25a7bdcf924fa87b0c77ddd66bdb67c9b8798922f5378c0405be67d5da47f7c245c5f7330accaf74d5bec6a8667c911384d9c77e9d3ca38d88bf87deaca62b58d092bbabe64895b944fa9f6bca0aa17a55031fa19ab0c324948816c57f67adf84077b277e71a7db9a6ac537a95e54d3cd4c9517bcdb7e9e1ccc8e7dc252c27c89b9c20c9876ce7c01b17b80a05c6f75006cdd1e081ade6f9353c66f7113613a5f72d82dd28a65efb74d0d1c92793d652edf23bf7c70f6dcfd5d40b2799b60c2a6fb53beb02571c78001381fc97d4a9292a0eb7a4a0a67cdf20b4810aebe5aa4a6d20fc30e2971924a09f106d0b5b7fcf181321b6f8442f91fb7ff3b5610353500b9d6f8a36301e7cb12d94d1aab6ec0f797fdb57232c02d5fb4b2ffc7d0cd2336ff96a4a811cd1aa02248f4a48c7646591507f9e02f8f441cacee92b5bb3cfcb7a5dbb02993d0fb1818e0ec4cb719a6b43d82e15ce576f95912ebeac7a7aa377a50d1190799b00a6da2fe7cd7231c3fecfd4e6913df0b46887ae8412cd2c9de49ad7a4e8f55e7f53239649b566c4940db50e0ba9a915acbdf0ed97905b0c70930d49c5c31cb398fa4f52222d3cdbd9374ae9d7d979991fa50a2cefeee88b3943578f99b9a46e58900378ef22880c862103ab7e0c2066685571b28c3407cfef5bc0c9b176be8dacf6130bbc44389aac32cd0011aaedcb752e16a1f99838030f7364c17441de87d5ec670a25a2b55a77a57f2304233b3d9d1f4c7b145e7e145eb8607f2d9b6159e954f14b02609830fe54ce1a7dab775b49d77a0ed503773c81e3c53f50e0cb676387dec6e506494ea7843fe533aa7f09dd1d4c960dca585a1590035a9c36cc9f821b4a8aaff6548fddce5250efc4211b0ad0ad4dbc3dc5038218e58851da4848f399f8d7938da211484139000dbf8b6c6314312586311ca1d8639fcdbb20b6a6a608c23027eb46938cd6bb869ea2d3b327728f31012de124a9b57dc96d5d98154b98045943a24e4f788e48bbcf0dc20598fb91627f09495c8fd5bce762b1193fdcf9c45174005d589ba6ad971b5d7ee13e1aab89447a14f9d750621184cdf55ef4ac2f7fedd7b8fe89e0fefb4382ea18cc4feb62e9650e9ba5a12f9366584ec774f5aa09793293b558293991de7fd1793bc44341a5b59cdb45095d5b53a4b847512dd2ea621f9778b4c0f33cb7bdbee1061505f08f1f2919cafc5d6e45206cc35e89e1d366b7abfff3da64f6cfc0d0b855bf5d425a85d93ecb01186697f60a7a47870ee2a6a50cdf134a67a51565d28974dbaa9c62ffc960b70fcdadf79dc489741095ef3052df69c55b99c95a44728d30e267a02922c7a6ef2523ec379239a5148eef6\nTAG: 09a43ea9d67cec2b3f35d401141af9a8\n\nKEY: 94f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f\nNONCE: 4fe1fd1359a4332402251d90\nIN: b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23a406f8b8ee46d958d10d8724d90bb26e2b38be1c0e8258de3a09541826486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113\nAD: ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43f62ac96f76e13ab5928147c5e63788bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ec\nCT: c5311b1a6e3d93da070ee0fc2c1007558db64bfdabdc23c832d151472513482314e7d9385918abe772970c7d8b3ae4eb0d12965e6d7f6d01f6c97d06b51d3be812dfb290592578713ed6342a690ac115c29d471826f37f7f7b46936ab9f431cc0e4029579036bc6311574205810fecd3a17ebccd0f15752152276d5169b48b0a4fa93613fde13997517956f84500edd7eac1082ab6b69bf43f56fb9046cefe8425140db5f6bd3bb201b3345b2138c7f42120a3009ccc19e2d95ddb2b4384205d2aecb47c89cb43fab6c353f781caafae280e93dff5bd213640c41cfcd81b9dfd1be05ce21758c5474c38bd24819e5d085241dd54c8d2cbb5b21a616e47c05d4c64c0f397fc16d52d008fe4e83c040a6304c41a448784fb0c54f8a66fb00b240b9d66e8db234d14534dcdd6b3ba78db0403cf0219406ca858fef6bcb259fb69c53c6f964f450bcd12997955d0190ccbb2d9ae6b3562d85dc7de2bf1bd5a8d49651fe5de73243d7f89ac8796387e0a04c74d5834e47afb6b7444df7d27592fbfdeca72428582703ae52aab48c1b587b12fad6c887e451a54ef81481e3d8b4da1e3fc09404a7c209db8c880c40b3fedc579fdf19f956bfb36d5b2d1affa0a3631681084ae4e41e3a0fed84e056bc72b6c0eb1f5449935f7c2d3de07a2a5fb65af65f91d2c1d730edb80b437cba66fea779449b68c557c5f8bc6a2581b6808a98a1acb9e6de414377f5b08fd5cfeb4806e8699e50236dc8100a88f4f55d887caaa6ae8ca09c23019126b62b5c3186b459c39ee397076c825b6e28ab62d8286743f9d07182cfc634eb4512ec3beb04ba81bc20294b16fb6d42301a74fa95f95510155a15eb953eaa51d82fc363c0c63d1cf401a3ccc0c577474f99f7c4f187316fb85e1db38dac1df4b5e7c710be5b5949dbb1925723d042944eac09dbfd74d7e876f5931f619bfba1ea9580bf4e", - "6c2540fd68d5aa9cd21203ba207f0f62e325c1e054271933563063acb4d932eef201bf3312763dddf6992fbd128cb8fc8b7936acbe8712ad398c5a8719b9efbe0927b9f637f323c4bea80901091608ab76e483b5ef666560937705bff96d430e6e17b0b24c755de19bb88aa81077852c92a96e902d538b4e11b78a4b5d1f5669aacdfe5125d806a21c06ccf4980edee24e41b7e17672fed0ace9b19e4d55415d097f0b5874d60dbe311871abaf47220893c398d5595ee16275eecc6d15f39aa5e2181ad1448345406a4c77a34c3fac77b4c506cf393791d69e113270adf0393cad689a07056e388ea3bbd00ee5878e1120c869531a8b4745ca2debc1e008493d17bb3777992cfcaa165188b4801122af5422acfa0a1807a2a35e793ebdd95aa9e025edc065cf9ae85972a5f42da193cd9b653373a6e15d647b8d26207f3230e50bb49\nTAG: e2df8917d70683fb6e6ea67db55367b0\n\nKEY: e22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6\nNONCE: a4c6732e0887f40b5017de54\nIN: e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585ffb8f86b254d0e08d0a0f5a499ef1b2bb0216e486229f5deb16d1e95332b8673652a86a6e3fa0e479987b2bdb1909fb772c6836d15cc57d97f29acf335ec1873c1bc6e714b689db855c8ba59289fe792d93774dd83313e3fdf11bfd6a40d6c8b57a5989e844cdf2fb38c239f6116c1c3aafb9356ad4b07ab37f7fb089cd424a8c1f19e5a13f085ec8cd74c3c9f0aefccd6fe5340eb1e419d15285b6b0d3b57a5545f6e28b75bf4795d995a20dc7a618f0f77a174e3eaafe221f8da0cb071473c507054243a7f9eee7d5c77b071602936fd5bc411e9923fc82016cf5345454285e9c1396696e05d984649a2955d7446a1d3966adda11bddbf3dbc11e093c15b7d4fa2a7a0c33fa28dd3242738d7a77775cbeb8176a6e9a4e4e58e03f631a67c3229d57302fe5967c7e3362ff926fd584edc32905a350b390391f7fc3343f22498bd198ad56cc2827926b0c4700cc352bb990876db7c17e2d32b5b0af617554a1f76c32b94cf7728e89bc208f22e986e7d2faef190f820918afa4e08cc46adf0704aab761cbb9791aa12eb31a7785d7716c3f0a46afbe2a44a52e5d0944fbe207ac78d54c407679814cc03d9c9ea28f1e518a10e0cf034d1ffa27b67c9f027d738e0a96a381571bb52afe2e983b34f9159f05d4ac9973d996c4612b7c60407a66925068fd98ba6b7742a219d8bed4ceb720a8541f4cd9eb990384f8f8698515ed3692\nAD: 8eb26d00d61388ca0f06d45cd697e36f11e25f618eaee0562dbba21d10abfd0bbfe232e6efca4947adfa7fc59de529652d11847d3cca84ad147f8905bfd0743be43cd21a9ece92d2d7397f74b1632ec2b1e398565e3f37039f1e147c061b51d59eb31bd16bf830b7824d1ec5e79441e5c5e5131062171467a037c350fd16f58854e3dfd9c1224d26fd600b006d4bcae123a7a9d4e98c47b9e9e3fdbc22abce09b3c24a5a060e371ee70110227c9a8b6049f194dc4f74cc97d01247d76b460774acf7c5d4a8fb4f01888e29ffc517839c234836cf513951435f226e635ff8b02b18225402b026566e951449023fcf7f6bc2285dac1b7dd83028697dac70927db01c22921f6a7a6304052e58c8e87819bbb75de9cbe6239cb1ae8fd4849eb4f48759aed59d5a0ec3108b3131b0b74a4f860e37d02e04b9501e5e3c306cb25820abc50cdfbb05f8e5e2d2b94c58190c5d950f804786fb2ef97eb013f6f049b38fc57561b9cdfce5ae30516050d13d0ad8c1d750b51a552520785a9dd03c68203d91e72e3bab17cd67989bd103532071676718e889b94ee12856547a6d0a6c88c236d7fc7b0d8f222592d00aad4e813f8c738bc10c0b1fbf23bdb2baa56b1047348ed172a15dffd0bab088e2b406f040ef81d3362d0f86d129fde70ffaf87ef3c4554fa43850d1816407b4d5b0459bc622414a2d9cf2809e60e467fde6ecb7f4d9\nCT: 98763c2423882eb5a1e9075920b2245f2243341f6dd2dceae7780aa738fab65c7d86f41dd4a64283752db5e86cecaed0ac1afe966171e94f2c30d63a93ff11343ce15ff3bf464d88a6912fbba42c08e6225cfaa63c6da17a6354a34362fda3d993920050dfb99c84a235726aa4cbd66260b0e5675bfe89078e33e76ef537d2071d5801758c6cf07557c0e8bfe0a49aa6e212d69617d1a22ff15a26ae28f4d724d6b537ed34af62672cc9d48836f284cbc7eaae8cd15b46b8e233c94bf3036713f2679e23e0bd829dde5b3a5d7a2d65193f55a45def3d52830cfb1ce3f8208c1425d8171a053ab076c2377f7c26b37970bc3c937db75181a47467b9735be331a0f30a7f3ae135a533153ecd0a5e0cc1568e303a6ba6065c0dca8162a33df7c5b69542938c88e2141e2aa697c48e72ec0573065e9d9a9945cfd070d45218f646e5cf0c0ba145ed1fc7b7cf96c64e3a4671eb6b51ac8eb79bf0b4abd56fffa2ad8a93c001e2baf0b65e257782d7b7e3a837cbae16d40183a8b629467f77f2c7f8640da57904ab75a642e99fe4b45ba7ee488f889b07ce7a4e74540c3e0e0e67f88d473509295a66e27d4ebda1d4d3313add2555477aebf7fb84edbfdba18afc6f04c4af6a90730518a8ce28c12ab90921c413bb822e63cae113e5254039cdcad2dbfecfd97c183679c6c4691c99ba771b1389384259b966f358f871343b4bc5f9a92d8f27588202ae1269658ed91bae33deec6a6a35b9fbc523cc11cbc15024f4dd386b8f41c3fc7097d717099e722e6243a13bc475d5f2b1b2569f14cae6710c8650bfd78520caeceb035f58adae811c0fe9857c8cec59a01123e5eb2774190943c2cc7d535af77ea1f79cdce94e23de21004c73fb8469c230e25fe245c8a5a6314736166a7fe4e1bb0f91ee8d60daa0e576b9b7c6b5957d4bd8d8b928d36aa46fbdf742dd602f9cda2ed1608255d6dc962cc6d3f270d6a42f5185b38e6f0085f39dd17260f0580b62d49cdb668e3e5f76d47dd1deaba0db5b315ed6deb62e6e4388a74ff21903d7bed3c3e87585675a608668bc031aa83e7546cee77bacf9d3f5cbcf00ca71d6f6c86751a5db0d7f7065324d33458b7fe66e2b63bf9d8b514006d14da70f0d64f171a7bc11b2fa5955b85090701260a13cb52b930681e10e9daf89bdffacb9c13b9b60319e3be0ed29f7b7d4723ac5af888375c9e23bc97d3b189ec778eaefb3e4649d1b1ea96979c8f004064abefdfb3479e924dd974ff6478beb1034124b1cf27fc739872bd24bf257df2068475f0b144e61411481a48739e2691e535b64066acce2e0fee9c239c4015014dd38570b01646bbe97a389a3604312f06bcf7ae288790b73434288ba0c90d7015bc1bbcd5a0fe84564cd6a692df04d53716bb96d769074d758bf1199f716cfe5c4c542f9852435fc9675a80b4d\nTAG: 9f62d794a54433e79c71a5a5cc8d282e\n\n# Counter wrapping tests\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 000000000000000000000000000000004db923dc793ee6497c76dcc03a98e108\nAD:\nCT: f3f80f2cf0cb2dd9c5984fcda908456cc537703b5ba70324a6793a7bf218d3ea\nTAG: ffffffff000000000000000000000000\n\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: eb3640277c7ffd1303c7a542d02d3e4c0000000000000000\nAD:\nCT: 18ce4f0b8cb4d0cac65fea8f79257b20888e53e72299e56d\nTAG: ffffffff000000000000000000000000\n", + "# These tests are versions of the tests from the corresponding AES-GCM test\n# file, but with the nonce appended to the tag.\n\nKEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01\nNONCE:\nIN:\nAD:\nCT:\nTAG: d7cba289d6d19a5af45dc13857016bac5bf11a0951f0bfc7ea5c9e58\n\nKEY: 73ad7bbbbc640c845a150f67d058b279849370cd2c1f3c67c4dd6c869213e13a\nNONCE:\nIN: f0535fe211\nAD: e91428be04\nCT: e9b8a896da\nTAG: 9115ed79f26a030c14947b3e454db9e7a330a184fc245812f4820caa\n\nKEY: 80e2e561886eb2a953cf923aaac1653ed2db0111ee62e09cb20d9e2652bd3476\nNONCE:\nIN: 96669d2d3542a4d49c7c\nAD: e51e5bce7cbceb660399\nCT: 4521953e7d39497e4563\nTAG: 2083e3c0d84d663066bbe2961b08dcf75daf201589654da8884c3c68\n\nKEY: 31dbefe589b661af00a6fbad426e013f30f448c763f957bbcbaf9c09764f4a95\nNONCE:\nIN: 908bd801b70d85085dd480e1207a4a4b7ef179dac495a9befb16afe5adf7cb6f6d734882e6e96f587d38bfc080341dc8d5428a5fe3498b9d5faa497f60646bcb1155d2342f6b26381795daeb261d4ab1415f35c6c8ac9c8e90ea34823122df25c6ddae365cc66d92fc2fe2941f60895e00233b2e5968b01e2811c8c6f7a0a229f1c301a72715bd5c35234c1be81ef7d5cc2779e146314d3783a7aa72d87a8f107654b93cb66e3648c26fc9e4a2f0378fa178c586d096092f6a80e2e03708da72d6e4d7316c2384a522459a4ad369c82d192f6f695b0d90fcc47c6f86b8bbc6f2f4ea303aa64f5ce8b8710da62482147bcc29c8238116549256a7a011fd9c78bbb8c40e278740dc156c2cc99c3591fec2918cdeb5240fb428\nAD: 5a32d7044f003b2ffefffe5896933f4d8d64909fa03e321a1bdf063099b9f89752d72e877291d8da12340c5dd570d7d42984ffab5177824fc5483b4faf488504e6822e371dca9af541c6a97312b9cbf341b4198b0902cd2985ac10a8b5b5fe9691bb29a88344f863c980e4e871a72a8b74f92eef68c176e9d2ef037898ff567298e186af52ec62eb7429a8004ac46b945678b82859396d36d388ec3d67653aec35cf1da2684bbc6c78a5f9e3ce1b355af3b207f64e0fa73501c5d48a14638d0906c87eaa876debcf1a532c1475d80ed3d4b96458d2236eb9f67988863bc6d5c16b96b93d898683d248d7bc601b5035fc365481b89465e37a8f7dd64635e19a0282639cecde72c6b1638e0aa6e56f9c00d031cdadc59ce37e\nCT: aeab9db30a579ca54195e54a9e6c787f40100c6d12ceee35643f36ae45f618cc9bb66aa4c0fae0ec2686cb4101a5b23a46877460c7e020b38b0d8d1f533ecfa99df03d346bc854a578276d7d5685ad1fb03655683a64aae4159c9efa6781f053057e0811226c7c533967a94587f4025353b28cc3a2ce5763783b4c31e7818b8ad9195bc03be8f294f9f6ceac578f9d30b22b1f5a68d647d46cf6db4a9c3a8a5c06fa97c9efb4578f501ea96db1f40942e3f24c44a7e4070a6b931c39947d9692930b67767357015de51a39e46fff94b6019e4bc1ad9d216a571ba0dc88859c49d2c487ca657384e49b4d382d86a60c8d5195320909c4e82fc077a3b22bd4eccf0f067e66ec78eed642b2d16f0f304f60f1d9ba69e205c982\nTAG: 17ca09e3084504fc22e914ee28312c8e147fe99bba0f606c57242314\n", }; -static const size_t kLen15 = 64853; +static const size_t kLen15 = 180399; static const char *kData15[] = { + "# Test vectors from\n# https://www.rfc-editor.org/rfc/rfc8452.html#appendix-C\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: \nAD: \nCT: \nTAG: 07f5f4169bbf55a8400cd47ea6fd400f\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000\nAD: \nCT: c2ef328e5c71c83b\nTAG: 843122130f7364b761e0b97427e3df28\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000\nAD: \nCT: 9aab2aeb3faa0a34aea8e2b1\nTAG: 8ca50da9ae6559e48fd10f6e5c9ca17e\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000\nAD: \nCT: 85a01b63025ba19b7fd3ddfc033b3e76\nTAG: c9eac6fa700942702e90862383c6c366\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0100000000000000000000000000000002000000000000000000000000000000\nAD: \nCT: 4a6a9db4c8c6549201b9edb53006cba821ec9cf850948a7c86c68ac7539d027f\nTAG: e819e63abcd020b006a976397632eb5d\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nAD: \nCT: c00d121893a9fa603f48ccc1ca3c57ce7499245ea0046db16c53c7c66fe717e39cf6c748837b61f6ee3adcee17534ed5\nTAG: 790bc96880a99ba804bd12c0e6a22cc4\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: \nCT: c2d5160a1f8683834910acdafc41fbb1632d4a353e8b905ec9a5499ac34f96c7e1049eb080883891a4db8caaa1f99dd004d80487540735234e3744512c6f90ce\nTAG: 112864c269fc0d9d88c61fa47e39aa08\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000\nAD: 01\nCT: 1de22967237a8132\nTAG: 91213f267e3b452f02d01ae33e4ec854\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000\nAD: 01\nCT: 163d6f9cc1b346cd453a2e4c\nTAG: c1a4a19ae800941ccdc57cc8413c277f\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000\nAD: 01\nCT: c91545823cc24f17dbb0e9e807d5ec17\nTAG: b292d28ff61189e8e49f3875ef91aff7\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0200000000000000000000000000000003000000000000000000000000000000\nAD: 01\nCT: 07dad364bfc2b9da89116d7bef6daaaf6f255510aa654f920ac81b94e8bad365\nTAG: aea1bad12702e1965604374aab96dbbc\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nAD: 01\nCT: c67a1f0f567a5198aa1fcc8e3f21314336f7f51ca8b1af61feac35a86416fa47fbca3b5f749cdf564527f2314f42fe25\nTAG: 03332742b228c647173616cfd44c54eb\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nAD: 01\nCT: 67fd45e126bfb9a79930c43aad2d36967d3f0e4d217c1e551f59727870beefc98cb933a8fce9de887b1e40799988db1fc3f91880ed405b2dd298318858467c89\nTAG: 5bde0285037c5de81e5b570a049b62a0\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 02000000\nAD: 010000000000000000000000\nCT: 22b3f4cd\nTAG: 1835e517741dfddccfa07fa4661b74cf\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 0300000000000000000000000000000004000000\nAD: 010000000000000000000000000000000200\nCT: 43dd0163cdb48f9fe3212bf61b201976067f342b\nTAG: b879ad976d8242acc188ab59cabfe307\n\nKEY: 0100000000000000000000000000000000000000000000000000000000000000\nNONCE: 030000000000000000000000\nIN: 030000000000000000000000000000000400\nAD: 0100000000000000000000000000000002000000\nCT: 462401724b5ce6588d5a54aae5375513a075\nTAG: cfcdf5042112aa29685c912fc2056543\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200\nNONCE: e0eaf5284d884a0e77d31646\nIN: \nAD: \nCT: \nTAG: 169fbb2fbf389a995f6390af22228a62\n\nKEY: bae8e37fc83441b16034566b7a806c46bb91c3c5aedb64a6c590bc84d1a5e269\nNONCE: e4b47801afc0577e34699b9e\nIN: 671fdd\nAD: 4fbdc66f14\nCT: 0eaccb\nTAG: 93da9bb81333aee0c785b240d319719d\n\nKEY: 6545fc880c94a95198874296d5cc1fd161320b6920ce07787f86743b275d1ab3\nNONCE: 2f6d1f0434d8848c1177441f\nIN: 195495860f04\nAD: 6787f3ea22c127aaf195\nCT: a254dad4f3f9\nTAG: 6b62b84dc40c84636a5ec12020ec8c2c\n\nKEY: d1894728b3fed1473c528b8426a582995929a1499e9ad8780c8d63d0ab4149c0\nNONCE: 9f572c614b4745914474e7c7\nIN: c9882e5386fd9f92ec\nAD: 489c8fde2be2cf97e74e932d4ed87d\nCT: 0df9e308678244c44b\nTAG: c0fd3dc6628dfe55ebb0b9fb2295c8c2\n\nKEY: a44102952ef94b02b805249bac80e6f61455bfac8308a2d40d8c845117808235\nNONCE: 5c9e940fea2f582950a70d5a\nIN: 1db2316fd568378da107b52b\nAD: 0da55210cc1c1b0abde3b2f204d1e9f8b06bc47f\nCT: 8dbeb9f7255bf5769dd56692\nTAG: 404099c2587f64979f21826706d497d5\n\nKEY: 9745b3d1ae06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb\nNONCE: 6de71860f762ebfbd08284e4\nIN: 21702de0de18baa9c9596291b08466\nAD: f37de21c7ff901cfe8a69615a93fdf7a98cad481796245709f\nCT: 793576dfa5c0f88729a7ed3c2f1bff\nTAG: b3080d28f6ebb5d3648ce97bd5ba67fd\n\nKEY: b18853f68d833640e42a3c02c25b64869e146d7b233987bddfc240871d7576f7\nNONCE: 028ec6eb5ea7e298342a94d4\nIN: b202b370ef9768ec6561c4fe6b7e7296fa85\nAD: 9c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac7\nCT: 857e16a64915a787637687db4a9519635cdd\nTAG: 454fc2a154fea91f8363a39fec7d0a49\n\nKEY: 3c535de192eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23\nNONCE: 688089e55540db1872504e1c\nIN: ced532ce4159b035277d4dfbb7db62968b13cd4eec\nAD: 734320ccc9d9bbbb19cb81b2af4ecbc3e72834321f7aa0f70b7282b4f33df23f167541\nCT: 626660c26ea6612fb17ad91e8e767639edd6c9faee\nTAG: 9d6c7029675b89eaf4ba1ded1a286594\n\n# Random vectors generated by the reference code.\n\nKEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200\nNONCE: e0eaf5284d884a0e77d31646\nIN: \nAD: \nCT: \nTAG: 169fbb2fbf389a995f6390af22228a62\n\nKEY: bae8e37fc83441b16034566b7a806c46bb91c3c5aedb64a6c590bc84d1a5e269\nNONCE: e4b47801afc0577e34699b9e\nIN: 671fdd4fbdc66f146545fc880c94a95198\nAD: 874296d5cc1fd16132\nCT: 9209cfae7372e0a3ec2e5d072d5e26b7b9\nTAG: f3acb73908e54cddf7be1864914e13cf\n\nKEY: 0b6920ce07787f86743b275d1ab32f6d1f0434d8848c1177441f195495860f04\nNONCE: 6787f3ea22c127aaf195d189\nIN: 4728b3fed1473c528b8426a582995929a1499e9ad8780c8d63d0ab4149c09f572c61\nAD: 4b4745914474e7c7c9882e5386fd9f92ec48\nCT: 8ad7deb4be91cdc4e75c77de1c746d816212b109c5a485c6cb79e3005d2e94355104\nTAG: d71002b6a9de0addb173f49e34edab61\n\nKEY: 9c8fde2be2cf97e74e932d4ed87da44102952ef94b02b805249bac80e6f61455\nNONCE: bfac8308a2d40d8c84511780\nIN: 82355c9e940fea2f582950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0abde3b2f204d1e9f8b06bc47f9745b3d1ae\nAD: 06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb\nCT: ced477a00135f16006e100b9d7521f9e1bddbc7d339cc41333abe3cc79dd8e3a18e310dd1dd53ac664673ab9090d5dc07b4859\nTAG: fdfb01ef873060efc7c3c32adf3b46cc\n\nKEY: 6de71860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nNONCE: f901cfe8a69615a93fdf7a98\nIN: cad481796245709fb18853f68d833640e42a3c02c25b64869e146d7b233987bddfc240871d7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296\nAD: fa859c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac73c535de1\nCT: 01fcded8e89997d446236c8e3a77ba755b85b9b5ab8fa8f355be587a3954c4a4231a7c8c198b72525ce4304125a4dabd1574453437f6584790d8cd90d5957b0d5c804a6e\nTAG: ecb5e6b6e75d241c221a2f4dbd7d0448\n\nKEY: 92eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23688089e5\nNONCE: 5540db1872504e1cced532ce\nIN: 4159b035277d4dfbb7db62968b13cd4eec734320ccc9d9bbbb19cb81b2af4ecbc3e72834321f7aa0f70b7282b4f33df23f167541ac15c8417abaf17a282ac7a57252ff224ae7911a905b8c699b20e40c1e9569a6b2\nAD: aa0232d4b10bb6f20406135861c19795b95f9597f9b72c20931c41164f1b46", + "9b0901f2b5da3a956a6e278c940e\nCT: c49082d9a1bb49356f1a9b75b443832a56387066b617b939b60381db47711bfd174324e8d20c9713d562fb8f5c698dab02b5c00ecb652c182ac5544648599fd7fdd042009ed44961efd975972ae3c9aed8a4f58ddb\nTAG: 75639e5472bec58e96b358cbe429c4ac\n\nKEY: 82593eb58f56f6d3681fb00dedf7f612c4cb3193b73ab35f9a5a9cc8d13aa27f\nNONCE: f1dea3b2a7d832ed8ab959d8\nIN: 2ee795df8e1ef530cc6fd9a1f10543b44c49383921d74fe0c71d50da4adb9e9c7e5491a488ceb5c384ebafadf0f484fae982019a8ea22efd1358adf7ad4f5fa0d2acd2f1ee095cdfc13310241243fa53b8c2610d1924b1d55cb6d9cb6a5b98a72127255967b8\nAD: ff23623c5453e61cecf9e624e5c803250c382481d3c10febfa54d03894ba8f9ed72637fcf5631f7b7312cc74e6ff63ecb240349a575f\nCT: 6841f9ffed11d165b18917ed0aeed507bfdbea3a57beac2f2e08625e9929d3f2d84373ac3b21813f7dde1b25c93129b541fc640e09f5233cd9f0587edad70b73c423011cccae55a9deff9f29308fbdfc9a73f5fff4a7b0ad308ca9b545223adcf724d3d8b127\nTAG: 479bf5015121d25bf2346429a5c569b4\n\nKEY: 2cd817f2afbaaf21815bf08ac1e8f87520244b4a3fc492c7120296607ef64d0a\nNONCE: db4c74b73839e13455fd91dd\nIN: f7f81d460034b9c41eaf0cc6040a84e17e6108372f1ca50656793554ea1d05181310711d0e60d4d556b2bedb24d7b622c01fe8025119ae0c8a20b679dc40c9908f88fecfafd688b0ebec6a2ac13421012874c80685c481b41323a1724ea96c1df644a595e8cc73955e6f661e0fa30737d78e7cec11629b\nAD: 8f1fa4bbd8e8e655f50019859514dbc4cbcf944f95084e45337d9d9d8972bd8da92b4eb5a75c0b284305601de859f8d1fac6d6b3fdd42210fdcf696119e436\nCT: 97d729cde56ec1f95bfbc16ca5dec6a208543c3255f7a2b97fbf5fcbbb34908ace9ce13bd9e90474ed620715a5e9e43c34802b85feebc4d4a23d1bc8b4b5a6c11da7158765c40d2c863185c5551cb2b10eb0b45c61b939f8274ad84fe0a74e163bfd6afc5759946362adc74b4a7f705827323f8291ec38\nTAG: ea1c9094241c5b75ea880723ccb17ca7\n\nKEY: 006a5a863859d5b70806197fdb9f0da3e4c31b0c7545809808bf7683757cd11b\nNONCE: 9d0f8621664df31eb95b5e17\nIN: 567d680b1a26980772e8ad3e9b2e2de537414368c4f97adff1408d36c1dfee65b78375c7361c91452e7d463338474a400ef9efcaa648e93f38f8784a1598bca461211195d7844de56b91cccc96d89e6471bca6b7374aa5ec4b2f5fba66c17a435970411f2af3d6e33c0d094f74fcb77beb6cbbac1f3a8a19f69ca087f94a5b80d5e3692e0d10ec34\nAD: aa67269c824b382d6238bcfaaed586177b852f816c31e9966744188f02647d881990d98c3eabd477557a739262bb3f682f64d2208faf98097586053a32cbf37e\nCT: 85f7411a7f8ab505a7c10c5c1fb9bdabcd9a7826465de96e3b7c762830ce133b33d8956756ec29c00b429d30047040043cd5b3bd87dff60e09e4d7c3a95bcbfa2603ac964be32a82250741e19b6786638be28709ddeae496cba7558b7acbc5545b259e6a1b2ac1f5135f5719987dc547f97f68ffb7b9eac892527a4bf0ffbf59f77327ee763c54d6\nTAG: 3a8cb8fdab2c79aceaef6680daaf3ecc\n\nKEY: 78413a2d89613a81966e8d654cac0aa34107947a036f403bda53e74bc524e7bc\nNONCE: 2d2c51dc426b38c308cc5748\nIN: 39129e5e6251f41dec9cff7ccf256c38e4994e15ca976d3185ae17030ad3751e56367f86886acc32e27fe04d0b89cc89b0206f281aa2d80f9be19928dabf07417e7659b17f09c56d170ed1ef10d2fadf01e0c78473d06a1685ef0bb112e4ec7e6ce0cbc601fc8a2dd64045c8fada4a28c0c6f0ec98542e365279d00ffdf5e2eae3b663c4b79342f2f265db30a86d6e1b325318d7f7a622b36e\nAD: 746875b71165defd5ca1afc0a92db6ef4fb9e20b81018a5293899f1e0d06b18a2e65f7616638f79a0db3f2cfdcc0eac2ee1e2e454958e2e6d214a20ad13156f97d0f2cf4276b09f594\nCT: 142722bf554b8c70e8e76e52b9c0e0bb19b618f7bbc7ffbc91a66031f418d031d3c111eddb9f1ff7c2e64191be8dad4f8cd175079d2ada20c8880d0565c56afe5c9742753cbd50b93620b081f0877f045d0be91ff05a603fdc87e1940ac1e1f0c9aa96d5aaf4a58e0393ced4fad8e83171fa71c397817cd48ce6991e3b73d3356ef0448be1bd8114feff5f23db3b9cacdcfb4d25fd4dbfcae7\nTAG: e489f6c52120c8cfdc0f164b3440de99\n\nKEY: 5c11f6b20b7bede26d6c2f0e5cf2786eea66e18d6ece02156f9233bdfc57c75b\nNONCE: 1a8a8b1f4ab85be5a4a089f0\nIN: ac762060a336aa502f5a1df1e0a647fb9d5d932dc0654e0725122f6a567681a7d1cb7625ed0404d540d8b3145c911280d2a0ff9d1c53e27677be0436faeb39009fe5751c0b37c7a5f1137a26995577faa109071bee1c87d5e6772ca55fdec02348a625b49c3c881aab162f20ba0b834e8159d9bf20ee0c5d14da0221961c4fc7d9b44c7822f32298d30775cf974172ebfdb36cfb2881ccb15e5f69ed27880b920f4a092815357e03d982\nAD: f75590af08b447f0f8466b031ed2409e9f5eb479affd9e18017a369486914c63a7494168d91df157f5e56fbc4ab6ee5a8f3af1fbe1bf9324338a1f4acad45fc7137676797c89620b15feb8512544771f280f\nCT: d8355d51bcd69356ec74b9b8657cec57335731cebfe83202c1557fd208480a2c25747625bcc70533d1ef75d2bfbeb9354066a8650f59a575e836339dd45d0d8a5cac221954b77cabba5e95da7437665fe9b48257148b7e8a88cb2cc4e0912f511aba0a013aaaf09255ec13b27cd9cd05ea11fe2ff21c9ab8a3fe86090dfe13166b172ba08e76d30ad48bef0e2325da08835ecc468cc40222db0552834ae94458366f28f6ba63b3e656bf\nTAG: 0c7f16d3294d5ef185c2d06ed719ed8d\n\nKEY: 322cbaac9c4d7cfb4c326824825ba5b5f5190fcde0d399ef1f52b82abb5a8b1e\nNONCE: 5f2eea2c79702dec4cfbee3d\nIN: 1f5cc11e085d2254f8b37f8030bd285d6aa1cc53868d18ecfdd963153485dce5a3e3e8cb0a3cf8074571f7a2e9e841229466463f506a2bc90f2d6413128efee043e01eccb930fbc002563510e499457161083ed7997e58ebf03ce7ed2f8d5487936311922884bfd31cf828f3d0ce78f3c6981932268108a369048cdc0a75c062c0ed02e27bbd11754e621ff67c511ed98c6fadc3e95e7100644ebe1aa147a7e99f25ce5c2edb8ab6446749441027a211b8d04a6247299dfea9d75e\nAD: ab257a625aeb51f74e0b47b302fb5c0475ab23e99f4d93ecf07694497ff6b27c9848805af93a5615bc71486b26fc9da67cf60c8d3a396bc0164985fab2c64bbaa4dd0fdc22c9d9e433e8c70dcdeeebf230c7a3cb3e5d0d48573a64\nCT: e8d083e25f9332d30bfe60ac071f502909b26393440a848d1f81c3f5fd521de98cd9ad1fc3e806724f5b3732582853cf280f1b99cffdc6b46874d42adb8784cf9ab8e158531b4dbbd76391d48727b585fca0610777fa8ec6a2a7f070627f1ed254e430e55472622289f44089ff22f02b7f3c5e45e228b7b03a5d1e1abdc18b154124f8cdd3b2229e4720cbc1bd3cc3f86f3a6a745de0bffa2536027ee03d447b306ae69b1232e964ca27a6d252c1582422c99373ca2b9541a27081\nTAG: f6b8a72d4235589f7811ee1c6f8d2167\n\nKEY: b068daf90f56b15579767ecdd420c0858fabe23abc0b313b97a9c1ceddcb59d5\nNONCE: 322e47a85cc58e753f00d6f0\nIN: d032d4c5110c8f22e98895279a30a86da0ef71cea6ef2738fe3e747ee54d2e96e3afb8916281f6369ab1a397ca0a18c6c0e9a0c4edeaa4190ce6422bd116ac254a12235eb66fb5cc7ef55b721d3d2db4c67c38bbbb0bcac9234ea7d733f200e6b86fc55f4abb9b65ee1897c262533cccd118b0f493c849a7aa7f35d243f9438f1858da62bdd03fd5a8c7b01d8097d7ce319a41f80104968a46599e9a3289a29a16b245877898f345f92fa70d3e613c38e6e4ebbf0bcb64c1c41f8b83ec8e9f159d4b830d9a1b79f2ad90db06\nAD: 7856eb8621e52ab3060e8d72dfe782b62364c163fa00b49aa6fbe4210fb7208c642b7a6735b1a8b2f1dbc4b3d4952985ef207a3eb0a07b1341700762e9f9d1c3438fc6633da2fbade15844cb1813d258aa5bfa4ac129d693792a89622a0c686f05d87019\nCT: 00d34f899f0a8b40fdfe9fcec98a96c5995b4524b144545026aaa55f629c3befbb8ff794b726e759e18b7198bb2fd2a866379418e6dc4f9fa9e4edc84d21454a5cd212f68a7df321b18e9eb2c537e0cf2e0bf65e80218b841ae8a994ea3f6832d667430dc314567267d7f31519fd856d73eaa1d3bfca419abc5001b25cc1fdf860812b077fda4b01abbe8f8a81a16ad2ab5d9299ea9a0d81aa26e1a573504d5fbdf29e6b2098ce975f2f3c8c212939569c8ea8ed63c4847f2d0fd16f47bcb30bd7e00956ab8a9deddc54e009\nTAG: 6152a0401a33257c8148e65440601d5c\n\nKEY: a266f91387d96bf2baae0262782b9c23162f5271cfa3144265deefe2c569e829\nNONCE: 11e842e5c9ae8fb79becf42c\nIN: 3afe389acfdc9a34bec7b45705ba68e205b83b33f50b7852fbb7f4ae5dfdfdfb3cfee8a03c96a036388aa8f7809bd47eaa073f92905d0d5f199d466cc0ebd9bceb207f4209bf9925c6109973194742dc8d813f3cb212bbd8d92d7eef645fb0f8245811876dee5f241763edaf7d79c1b83d973f9ba3b29a9b9408418f73743ff0546f0d9290010cf3a665c443b85255759ec6248021e4b6eb825c398b5af7b5257efb7afc481abc20d90249bed5b30d44f725c78ad0ce2821f86838874dceb6b6207ad6fa34579126de720ce34bdfd2058d92b8bbbb3f1bec607de3f0a0\nAD: 28d8f6e13d0d4d2d3861e1a26d79cb68d3fef68127e8458eb599915022da751e271cd047cc712fae5b0459ae7815a24f4edf806889fc462c83181111f4de5bbb7e66a701460f508eaf73798c3ca9c08cc1a046472f4b18c69b7ed249a96f9bfa05a276499a5f499c586027c64a\nCT: 11bd92445b4e43dca339491c8100cf933795ef7cf4c3c4d6c42ae5b729ca22869d443505fbb49ccd29b44046569da104f7ddaf325e71e7f30487e83acd012bd492cb4e98342ac7d64843eb499744b3d17db402d51b5bf8cbcb8995fad4a81dad4221ca30ceb3590df41e124c327fd31aa53c86514a12e22c477489871bfeb38cf71cb3a959f4167402576f142bd88b1221281a94661c8d643f89fc92dffef322ce97f8c19b133e55f8020232dbdf42e4527d9f133b8a5934bf0a2df3754d6455a9d765182691ab94ec7a2e68f3ff59805c7457428ee4af8388f91e88b3\nTAG: 8f1bd0ef9d08299f494054ab9409f663\n\nKEY: d6a68dcb52a50aa6d1b1d4d202e6f184f01daa08fbd643523f4f73ae6b8d764a\nNONCE: 7f567087a5fec5ad1ee3e4be\nIN: 5b677b87109e69eae9a635ac2ea185ba08ebce3ba4be06d53b2da081c5030f5a746fea7bbdda340e10eccd47238340b9244b9442c0efae7644cff53c7abd8445163e891cf30bc8e26eea01f0c46", + "1b4796c2106e1ffdfdd1bac29f7d3c72c8ca7f625008d8d333d2a2092c08ef83c8002ed90e2ad01dadfe4cc0681384b489f38d25e83c2c563485fb361f81d44aea205e5bb4c1912d00d8f99f8d7a931e55ae72f749147fbd97699ec730bfb01b8261f1f94696278fc703263cc789b283460af9d74647a8c039ad2184674e78f6a355a26eefc6fcd4cd32d96d245d583836312652fd9e6694ac5644eeb4c2bd667\nAD: b52e5af14bcb108c8e277728d6d6116e8ed1981993771b8bb783bb351982f9f8c2a0e7c20a5a863c6d71b7145b73d7e6d84d47780d66847244d0b8ef559f2297f39e26501d8a2aae8c36189580292da842c4d0d06a21d21ab175e34589e3b814d8a00ac1d8a3b2eca2a91b21e36c55fc6dad8c0a1b2c\nCT: ddc900dd582d322c567e3fd7eb23069b9e559bb16639cc79ffc6f3deb6e92cbf71ee66c839b4115e883390646245a42480ae6c638fe7fa04b575b4a8341050e2f3de075f2f19ad9b24d9cc1c39a659b0ffc362d46354da6bee0e41319221cf7cb160017d589413e5c1f07e5f626c2a1f8ae9e8b9ba0320a2de9e1b5f7baa4d551c090521d8ee0b30c8c709fbc00f1fdce999f1f96883e3b83b363cc47665e5a21fcf25afb6aa2bbcd0a374618c3dd8b8f97f21037946dde9bfdc7e907ac39e64f1a5ec8dda60a47148bd066f907a25b9caeb3804c0423836a8d9c35bc58c57882c5b23e00c7f4e3b1743cb14f102\nTAG: 8ac7e104a0165df543c7454223a01f90\n\nKEY: c7bcb2108b2e21fafeaa26a2d4881b183b899210b474bdc43a8f0b8464075d86\nNONCE: a2ba1e9cd195a8ecadd31587\nIN: 0d5740c4e22eab0783de87d541fa834647c3fc6543c60d5df31c19c6ca38707649fa8dcfc3c0ccc16b1bb60283d7ae2778a8f83ba07b905e23cb06d5656f614f1efcb346f34e190bcc636cdca229b64af9ae4b1f05b58f1ffd1a077a51bbf9ede69ac3954de7daf569cc8de12282cac09b9a49dfb92dcc409b8c63f2ae4a34091633f4aaf225aa02ba9c57b910a76535f0cba67fbab0e6fa0bc876217fc9a546a97dabc9be41209bdb582d8d8a62865df7398d4f7e9ac681bcd102e31bfd40cfb8e9352b1e8ff7a7b81cfe2a62849e8b77dcfb645d2046404a83442133e245bd1df35d69dba9ee097dbc867cde7b431565c72fec31719318dd27c3e47dc5f8\nAD: 729ea794668d8724a1d4115adcee0725e4c1e3ce16ed9e31bd5a409cd074c0277e21a0b431d3b30ddd361ecd176a8d86927c2f6693105d7d3c47d9be8bd90d0b2fb20587623b2e838624b590a5c9f0e6d519b35eb5332b16bd2c2f9534e376ba68316efdb963d63e2c87cb0716973297d986bbd885a7306e2bdca0855447b5\nCT: d0e58d936c8b83c253ae9bd29f45afaaba9712647b3da6c6ffd40a9390a4476a0e74a2f2d458c88056bcc0a57fb64597a7c8a5e2be39669dec53c6bf0f7b4a2bacaff9aef36b43fe37b80cccc7d42cc283ba1c1eca739167c07754edec14375d86e88668b156d04c989bcf3fdc70e8a25aa3e6052d6befe3072ec0993d6b520c722dda62b6879324eb4ae016e54d139d816be7fb1bf9c0168d8f7225bc8ed9b7509b45cdb2c8a1db4b3619120c824d0bad7deb7fd0dfdb3674ab15a712f6196a5a840ee8895670cf3b20b8a5e43caa41c5524bf47c2ed4ae7027c2b566dc3e2548244057b880da2a3f1abe5e4eff090f9358970da6568bdb5f8288f9d25829\nTAG: 057ab8d811b5c3819781752230badd5c\n\nKEY: 7817285801341c10baf67bb5f71b75a11856d2551eb47e60025a0021b9948afd\nNONCE: 8818888585a6957eb59680a5\nIN: 5a5c42458f2d0e0f39bcbada0ba0b6e72340193500e22d243e32be0e7d7bc5c632ef3dc7e79ad5acc895cbba3111d8d1faa69bfe2ce634fc0d7b12242dd8bb105c6ce54cc9718921378c906ff5e61f48fa259b25bd10fee96856a206a928b450a0098089d5cb7378c2935c4537172076d829975798d4f24ad243e4aad474fd5e59e25a6dd133944918709e33f84b4daf4bc6d3ba1e0b9e364dcad5834024066ab5c8e672a999bbf23a83956623943e0011e3a2883d23a767b280ad84e2d7fe5811099395edd269077162310481ff304128271d4ce5c84ea738fde318cb2528bc5cd448c67837cb7dedb632d47e8f90e351b0a8942da2f78e2065cdf827a85f51\nAD: 0e22156bfd971ab3f123e9774bf3ff7c224af19bc79e812839eeb3f1c14f89e5666c16c44a5483efbe449237508ab2436939098640931fe3b928cb3a9378b6b9fc2a54c6bf59f34b16f06d5ef132ae2a7161034f26a6e07badc61ea51a94a20e4692a0a0525726f3de9bd1d6151fa6a0ea3acef3634847cfbc98d2e0bb9ae89e\nCT: 5eb6120cae6df4766b40ffb4d204ade5ae08aa2cda263b39ec7b47756ed7e6b7837fdcde8d01a2bf01367e9398e25991f9da11bc9f8de8e6c1b4e922af05d20d683edb4a245e22eb6cc4fec2375e8d81f9f27af5f118a16fde654b4ceabe770fb3a00bc7a88763b670b5e3a6ca06aea1824e20b9c1a304c4bdb62643fea73030ef6d18ee2e22095b4c73abc51abc4883f2bcce14033608ff7e1ce72ab3382c29069eb75426d283a4a71348123be19f480dba1d1677055de9e82d683c2d6413a6a4e0c6d58f7f2188ca5c8b916aa49975b80630d27a89ac284b971478376ad6e55dc64098951bec2ca7d77ebe790b1ed7fe7f33fe571d8613f143e3d3ab6bc613\nTAG: 6f3f79c6231d7e45ebc1ccbe5d110a0b\n\nKEY: 4f91a78c56558ac92b4f33fb1d96b1ade26cf4b2fec779bfbf6709e531ce0e62\nNONCE: 19f75c4c31873d4915b1af3a\nIN: 51c2ef5e89218ac4060dd12be216654eff2991e8d7bce6f6a437966f80c59c527679b8983e75c617c917fa9b63bc60748f5ca179645afdfe6a126a73d3fbcd41a9df6d734e8783aff3a5134ecacbb289f93febbd8eb493693264026f8678e9fdb779038ac13199459caf9c4e86f4cf8306af6dc04d9dbb678d3ce9e41d154c4c1bca018bbc4d744655af04ee2cd524db41170f0946df225d156dcdca3e52139561b61c26bfc56bc90c21cffa69468863afb66c3e1524303f8f42103e435fa2fe2c2956feffe5b06ed20bdba730d675166f13118a193b06d7985d54d46e4150468df1252d7cd144afc99ce99b93ce9526ea4dec2cde1d0d72fb82f55db65ec2035e387e7923d98490cacc793046afaa2e49\nAD: bed34cd7e4eaa52e75bac5e86f9e9eb81028cbe8a515870edb9a151334e1f961949855565abc51af9a1bbac0222e9bd217d3e3a642b0f3df8e7c47c2c9d5a801cc8028c425b3becbe31df39d30637c38f981d268017da818010189c93d2d135024f239407623496c5435f04f9cae86e63ef46fcf9787c946b400249d8476f82dee274cc0cd3714973f\nCT: 27bf7ffbf2c9733c3da8947db11ac8801475451b0a65c96a2a3934bf45ff54fd5fb21ff0d51c83ddf0f49b005d424620b04d0c731cb214f4beb6d353a6d6b7bf1a706b070faf5146b562c9f4e6c0ba5dc9ef9ccde79cd162bcdd887dc02bc95e29dd606d22845f35d0cd6d5eb1f1b154607c0c5c2e8c7dac005eeb17c238e3d4d1e1caab72b20a9d7b2676e6491eb84e9cab903bb0c05751a33642e145de8391ca9e598ffe2e579486ce32d5d76a35d440836ede088267e8cecf4b660fc5eaf05f68872b6cd9427607b146e15fae406ae7089ae446cc2172b8ac9e42cbc27d4e5ee38c21d3fd6d4d52b2d43462756d93995b9333a079dc1f2bea9ac4248c448d932c5c0f6b76da4698d15a64f761a7380b\nTAG: 7efb02056e18e98960cc5718edd07cb2\n\nKEY: 1b6e0ebc443d681af25ee26a8ed475136ed8bfaeaa8315a4cd198961518c7bc7\nNONCE: b15c68437005a4973a068187\nIN: 38adcaa250949af910aeb807096595b3af54bacbedd966f83f784f651f7a2044461a94f1a6925e6d2064e72319dae75d3883a50afb6be1395d429f24029dc9b8cc021f15e305e5418d844aa4a89ddd299bf2e8c698a8f6a6cf0165c37bcf2e5885d73bb81ca15a33ea75da5946678dfcd546d475149dd1a2dab0e11cc8b07c0b06105a497b1fdb1a720b9510d7d8819b6d946dd85c73be515c6ec00a10a69661c59fcd7a005dd08f3cad722bf3560f356c624404f3be55a02b3301ed756f557a51593ba90d18a1c13e227c8d5180fefdde4957484dcb81d08ee3331a6fa74c9c549ae13b2dc2a80ca0435710eb9f0dc2c908d896957b87325180d397c37ea7cf65db45960c4d791bf8cf798bd7626b13bc5e6b45b45be1a8ff687572ece86d1f5361\nAD: abaedc1a7f9d9ff8003bca97af7dcc42b4399f9da4a0e7e829c0e12f4d41607303f60d1df5949fca0dd9ef171678e013b88789ac1f51a8160687d842c273a2dda93c5fba1eb5bed7476ba96a12e70cabba43d509b311e9d000212c81c483b7e9e7bae1d9869a125558b2c7ef8f838bdfe97af413b460bd9dc5e372afcb105832ee4c406d74781d3e9f2aa581ba4fe458989a\nCT: 92aa5661d04af60245f6f56153cd86c6a61d5584473979eef596d6d0c205db9e4d928ba4827dbb08d5b34946b8f3e58ff62a976461ea5639fe2ee79839f99f83cde00e3fa3258e21754fa91a17e0d1fa22cc76fbce0bebb7adad09f99bd12e70e519048d96c1f97a183d8ae66445e63a4a1f936821fa7b58f569a16e25a0d0b202231a79eca0e8a2ed21755f496d8b7a9f59f6bfcf47ee4bf35788935cfb1b5ec2af2ce11c002b2843090e2267d5fc5e26f927e8836d6a97dea2a7e508f82a4cb7df375110217f88f4376782626039af166b080e181d8a310ea7fbb4fb11d5b24367f63ae83475269281aa09b7bd259a348fca28f2e1d7938127c888c68bad2608f89a2440add0c644de2b5f08d3477641675cdb428393758317c273536942caad42\nTAG: 4a43c15d469378383e9a9a26dca7083a\n\nKEY: 03679744edb73ba31c7d9d37920d4d57a766104afc9c96650e5a602ba885d207\nNONCE: 8f1c67d44d6e86eff0c96a14\nIN: 6bad3420c7dd0c64d800ea5ab7ff472d0f61bdf2e5634e06cb4f3c022dff8c4b46f2a47fdca2d04572b67f24125c66a551a1f150a02f635e1e99895807efa8001f46388365c48e4afe49c04f6681510f7e4cdfa02deb3e60eed745cf6d7ca6b773e1537d057a043cf517e5388dbbc44ff4bd68d2a7243587f8929ef07df5d001a6099bebedf8f26f49323209496d50109c383071e4a61ce18f495d98b6c4bcffd0fc2496b7eb0ba612e2a4cca8eee2a3daa0c21d854d49ca73cf5b24b38940dc2b44a2a6623e8404fc30c4e3aaf759425ebff85cb1c661744adf34c6c5d538f3210dcd0270a3d12784effc48734b53c1a228db291e2e5573b6ba2aed0a7296c1bbfdd1f4a86d6057d5534675a3f4897fe3a1200c54af7e09b97b0a2ab9f25d5ed375e7bac921f28f7b6983a41580362dcf0820\nAD: a2dfe82989ccf0a998286623617453722bea0b6e8fba504b93cd043c7e6c7cccfbccea43f7e87502026f94cc7035c5e84cc14a5fef9bf2be53dc379053725a9a29c4e86252369bf6dfd3cf2801af7447fd0529e94beba961ed65dcfd492398123faa55346edfc3ecff720966b74fd0ff28f443ca67f88b8f5a4a73007f79ef782bef601a0827888c4c74f7777279c625de8a4b51db94f94f846474\nCT: d64a6980718a5fe833da2e6c1a119f2f16a5bf3cc5089168520603d37998d5fab07a9e18e", + "bdc0b8417cb6a4d34357f8d598753affd51e93b451269dc24354d197885ce9a3b2f575fdc9c572b05bd7bc8df091a6675185ac15bd1c4f2cc0a8a412ff72baa6fbe95065bf2111910f4f004f6c39cd8e7ff5bab5f86abdb231406763233354734807fe0346ff6ad23a1c9c81b9942b370e02bd79eacf703ebcd53a54a5782f13ad3591801d1ece15c6deb56bb5e32d959ed1363875c57cd9d42881dc1799e652bd554059ce059a9d00a126de35f0285d5d82bfdc383b1b37d77cc1180184b2180aa35d46f816fcf125c9e8e3bbdd67c8770da26b89c7e406f02ec515edca3910de72fc76ddad8344ae36fec1d72315e1a568ee69a08154696e4545ec5ca53b3c0f5ec9cfe82792380c1b9a151a8d6\nTAG: a258557d32e1924b3eafceb7b73e43d2\n\nKEY: f8563001339afb3db339ab997cd1eb1eb7b03b228162a480e129c66ad47dbd18\nNONCE: b4c98f6d51fee205805a50c1\nIN: 63beb176b754366e13c57c18433228a81089be18b534ee5f9567d529c802d34bbca36807bf845a9d14dd141c5de85607a4b4c5521e5aa717f78fe78612b770a4677cacd77a425e2496ae50ab2e559526c37ea723f2b8d14bd8314e4cc3727bfb835ea4062e87870b13d94d52c25f0c631668292f184fc048dfeed7a9d1a88cc5c4662030700cd8c257784009b4da9039909f73840b600eaf670cd4d988845b1d41cfeeb1ea740db129c12f66a74e6234ebccf4df706ed30fc736cb5cc0db17ed108229e87d6b039da5c4f0568a4cbef9d513dfbc0af9313f02d5129cf616487934f741a0a60bf11fdc8d29ec81eb37577726f54f3e35bb10ef98b1d15bd5726fe501a9249e409eccae128df61762447962ba2a63f30b59ea25e18895d2fd11431606caf6b45b908b08cf2e150c031e20e6cc649699fed5785cfc6a0e22bd8bd8c6d25221\nAD: e9c9a8d2869d236388fdcdcff990cc940ddefd06da0524a351ae6113b29db9822adf9cb548d92f23e3951ae8522ab113579232e58578e80bd2fe3e1d06414a27ce0ae2e40d87745a8991dd5bd2e8ecbcad8b903195c15ac2eaf9bfe0104bae32f772a7d7416c5671350524419a6df6ed5e1df32b961ea39b164eb7e1353b046100998ba6853674ebd5ba011691a270c046096143daa84752f872e1ae32ac07c4f0d2a048\nCT: 2ac34bf9d0d909a32322cbfb765875297c50110ad859857c641ffba8efd60ca003b8f32d157b6fd8fcfb1c6037b13285be884ae2dbcbc9194e8757560807a14b2219b9f2dac11af7dbbb2f504e3d8ad47ff73657a4d1283c78bcd410acc1399a529f239440db4b72a48bb3ed984565d180015fa7ca9c0ff0281a2e14807cb90631c75506585c18cefa5cba7e0c943e44e85f60d47927339e3685c1fbf1bf497684a6075e0984ddce22e9c130d3cae99ab35394c315bf8e1040a830344c63d3719cd250ce04d818df0e20650f66613439c0c5153b2fad41e10b296e6fb0feb8977532079ceba9361227f69005c9e696f9b04d724074f4aae59dca55c74e87049c8f6bf1b8642e7c4dc73688260c540be50e8d4997d4b68346a0ea7749747dc72e26ac3bff58802cd60e63b3d8c509d0ce0d9886c50ae7f3a1621a077db155ceceba926919\nTAG: 67a891187fe42bd1bc7a6037513760a2\n\nKEY: 362d12b108943a7007bb6cc117135b165cbf42b92df2f191f06085518ebd1a9a\nNONCE: 2efffbc936ddfedc527b2c9c\nIN: b69345e0c497cc4951aae5be2748209607a51a1380fd389a14ede9cd4cbacbf822597b1c500cb0549f08a35bb0b1a00c5e25c175318dc771b03501bbe45fc52b2ceb4c04b8213fdce3882e0967ba268cf786ea0acdfca0a7f3f2f4f9ed5f499ff70230158adeb5a741da266573742c527bcc8de42747df891f58632f92a110a981a29052bd17979be21e53067de3baf4c34bfbaf56ef5b3171efa1ae60a1a51f51e0fc5b726bbc23a67015c35a1be5dd125af812b7661106827f31a1e4c7e0bc265efe59c9d6620387755a0bc17a11527fe136b765895e6386b9939c548bbe6d3b35eb92a90c05d0931e5dabad4d42ebee5af45be0106aa68888375a2619f7418a14570d1dedb76e8ab52a0a87eda2570d2c1d903ed9ecfdc62c23c47cb7e234dc617af0843a9f375a58f930337a88379b2b0553c4db974ad74eb46d637ea4e7c7aaafce16971682b772e1d85bb4a7272bc56be9bb\nAD: b55625a5085e601a5dd60701bb07f69c755a57808d022ca0a407bc3d35c848d6fbfa6bf816d470d9a82d43511c13fd0f496e59646e65c84d7652589c542ae2e73c5b7aee83b9ee8381af1ea1f930444676d8e3335b271cb354e9cd3b17e7f1511787fb618aae930c14cd302bdf3a55b2bb12a61e7b930dc39aeef36447bbb2f4d9f5fb55797627fe1d0b94c04c6817de6cf1e7d6e2660c6f49c0ab4b31cd5b367b912933d3d1f0a6b8b9556fc6\nCT: ae05b44cd3cd86c828e53930c4a80e01c59a8c1c9ff4b327122cfd325cc4ea0ef4f70e3ac48ede66f4ba7fae9024dd5d78dba260d06f8888aa236e7de50f57ef48ee4b553d42b41ccb8716c59f69f30afad97778f3e48df1d5a57aab3d471fd5079633b3972e2703a86c4e24d0a035b3625a5c7380b963496f9439542b15f4013002445fba9a9f4e9f1a15c5a6bd2894c0f540d264481bd3fb6b8b63d503866edf178d8d6cf007f9c6337bfd900f5c4712d82049a2f82e43fba589a372d44f57c3d260df6f5393d3b182eecdb503e4e35018667e91c4d4362122de3d88971691e7ed05ba7341cb9cd39cc12e12ea114abb6f7cf1bdb9906d3086147a1c22c67a74fb712ba6aba1ae12167a9d77a4e5fc0c19312d20080cb2d39a3a9a8cef7cd286739d5387e1728a2c8450ccca03d0c89332120555f97652d122192374bb4e05bc5839c4c2761de9e2f732a803171a97445f3d70fd\nTAG: 7e339b51b4e6395ea01ddd2272e5b185\n\nKEY: f8e9ab310482ee241fc221634b5094481ea232931d696c889d3d37e1c53cf74a\nNONCE: 3d5bdc41779816b352803f28\nIN: 2410580b0c03e861f4f7fc98f8a4cd9a4fec0c0b27d92023c081c7927e7599cdf59031444e74fc15dfc12d3c144762b8e448b7ef6772612a2e7bc34a048bc33dc56e99949d569df7e296b66cbb37c66dfd2ad8e7aadc350f8350cd68e8c4e2461290e30f9449dbaf4fdc89221cd75493d33f903d365ec418b327e3dd6fc381a8e06c48868823a42bcd082ab16b2c666b71038273427ba1ceaa57905c655f0ec4d25401c07c679ff5367a9755e63611c19ca5deb1db80f97a3f5149a8ad2cd6491caceee3e19782e66354b76422dd47ba1e715dbd271a07fcdf69b5240e58186b82b1ac443000cca1b0c79dede1cf998643565650e998bf4760dafa08afde120368ff9fdcc2311f78d803c8324e385ade4ccd2eb2ef51aa1884a496ec024221566c8c882992fbb830d4923a5c5d7b99c7e6e7a8aae5926d143e19bed7faeaf7c77bfe7c9f05fdddf75df3df2425bb94a63f54bfb1320bd32e7fc2774be67a22f2410ff3c295cb\nAD: c3fe566b8c9710807722198f03f56f0abb02ca55de5174d7f9ffa61c0bffb88730886c028451062d6220586bdbf5ff91ad6b1033f2c9d6cf3c3c7bb58a070e8bb1c3a39e3d04952961849cf55e64033ec929f30b9ead497d14b6c89ff6a4c008dab0104e7e20df6d6f11474ab680e5bec789623b2b693950a5d17dbc5b49cf80ab033b1910a9afc4231254f88ca13f37f1214753f32547ee0decad4bb93fe229b6c8a14564081d8ce5d47cd45022bb74475a709d84dc\nCT: 98ce773c72c6d7d40fb8aaafcda02ed688644ac8e9ac868315cfd9db521870b40ef9decb01673aaae0c8f6403f61389c9454784f007bde6a50c3c69cce30efa5d851cde2f019bc9a9bebb79c19b29304ed908db6e45445ca7f785433abfdca7c553e8f6aa4e6670e839b5a9204648fdad4a35c0a6e44151afeff135e7e080626854e68c0afb5bc6be9aeff91d71b33d294ff1c04fda6291ef535972f3020ec70cd31b156a1468c105655561d8755a4a88c380f6c56ec1e1f49c2670454f1493262a753da4d40343b04f91aaa3e69fa4abdc625869f72839623ed8764692c23e1131f6567a1936cb43c238e0dcc2aa093a728fadd5b0e7d04505b9fedb9212218f1b5452183e8cfb366e7583dedc590f16d713948a85bc4462134eff25eb9703b34b5bdbdc63299575cb0e076f3cc7afe35ff3021658d83b526f7b8018cec38d3da93a0ed388ade0941c740da975dc433b74b1b528ff92bf5484149166f97b44e81d083bc40e5\nTAG: fb61d2ad676a0e8961aa9f00a164f294\n\nKEY: 5fb0fd2e46ebc9940ccebcce3b674a6934d4dd57ce0fba9a1407beb06af6d1f6\nNONCE: d70275fa9f177cd36c990d4b\nIN: 22ff63aca475feb17de03d3a52b4119f9b277649f6f53f223e29e03493c938688be81151e268928380b407039fb38494cf235ddc823e8cb12f42b50b2feb52be05a38893d154b37cd1cf2f635413d7819354e29e195bd01517992b51efcc91e10932dd6f8a859c5bfd77f2e3efda25caf034a91053da8936e1975fcbecf2ee9784bfae7f903df4ad32e088a869aade322c7d14fc4143c50c59112c8178d00a0424f4003748d28956c9d3a6c57a8e0405d6509147b50ebd7d9a251a127a4dd736d0f74e68755c4226110c276cb7870cf1c7b86617944662737762aa77bb255d24ef951b69adc74314c72f37f32dc091ccfff067a89b834b1cf0b58cc22f7dd6970104dffa1f60b2ba837ca6ff834d07c71ac4eb40416f0f50303dbf6d0b4b0b9d9afa8da46c6753008f093a188cefe67f051c8bb3b6121841e2ba25b8b801db329b8da7d0bfffc29a3810d2d165e854a9eb34b6fcfc7c05bcdecf8f20b12c69f5641441156dd85b910557d1355e9d07030278b494691433\nAD: bd5de2858d8bbe2e3071ff450f113ca78f385cf77e6dc0a6c3888e3144be91404deed2afe438240270e9493811343c62c2ef0e785921f1ccb2d2d029c5f0365f46bd55bfa8f89d1d4c30c5f6598fe3f9111df847b27a06f7641494e4eb7dba8a5296f90bcee8cf11c1f1fc16c52868e8f2db2dea75b91dbfa023d5555371e1461283e3f1695e028ea00bb35b6e81bff8f128af2d81df6fd2c7f6f42bbe9dab30a59ea4788a53cf9d6a2b1e9cdcc9f1883b37c91eb8bea7659fab41d47f6fb5\nCT: e919008704bfbe7657974c9e499a3cbcedaee7b813752ddf49a69cfe3ef39a8d6e1ffb1f3bee7065e8b74b28b25b5054d9a0e86ba50d9e6aa4babd075dac7b7a8a0141f0adf9c274eebbd381a3a5f89c287019db217f5b644862319f799ec3f1ffe71e26c1b501eaa56c97a0d679f2c85158531ea41080b4c690ebf7a02ec2016ba260dd6c5fe1cc5084c94ddfb2b897cf597ff36adc11957ee4e4e3f7f7fee3b15df6930ee9bd7a1c1d6a74316194cc4b9e2483acb675def10dbdafc7093c18f46ee3ae155a385a2bf4dfd33db9eb33202d82070cbbf9df7bd6e679f2ef866eb37654c82669434b25764ab8ecf1cbab63ba7b1fdbd5e53bf24f679e321708cae599664a4e5585723df96638bbccc0db568ca8aac82c072e6548cfca1fd978ee1d732f46c6723340625d3a5ae89cb098a35a5ddfea382f1efc3c4b0528af42007c47c76e9baba69833e0219baaf4448308e9bb1eef5512ea41b8c774cbd044b2cd69c6f1c13fa6ae950e48d14cd05d8c5a97cfe4334f7f\nTAG: ed970cb4c", + "8e9493e2b5b16c99aa6932f\n\nKEY: e453777b589188805e883e9e15ae1de4e80860bffaef45a1e0a01f88b5d7d948\nNONCE: e63eabbdd2f357cff8c172e6\nIN: 652cd3b420533b8527a6ef26c8ed75d349dca2106050d80cb22835c15861a22d8c7cf8c2c2df9407eccb0c21dc7078de4b8b91e82d94a9916c9a284c7e49c8c7d001721a9031530474452588e09411c66023c9c81b7891ed271d371d60dc70f0c04ac93bc694e5b638f7ce901011e1a17059892a98d596666d102d9f7e0de426449906081651f88157063729176f4608f2d506c9637086f8a56821538a6241d8ba5e0f37ad3ebfd0b9f3b3bf0ce18c095c4533cfe33f6a9871bd6158a17dbba101f840c6638ca0589434c5b842d5dc501c7741142982cde70d98014e925eb46493b0bf91a569139be22c42cd33ba1f8c2bc884b2501a0f49d6309344874325345a98481287ccc6d29978d1e5be73740fdf2f3a3fdd0d7c0642be7a22e0c98f0886ed51bac87ceb0f2caa79cf702ffe880daea115b8af6546a7bc18469e07a3f8d8b8a825648684e2b4e9412cfa0f895cfa162ae0fbc11f8cc4a3252b2acf89e8ac67de0adb91e36dd510f9d8ed4eef92047d015b2ebaed1f3f0412d81fb5bc82f548dca18d520599\nAD: 5c22beae86894c88aa7b50cc82029abff7c8a56d0a6a594fb502ac9f11cf10f8ba9967497e0b70551a6440e15285d53befaaeea2dd2e743cc056bbee79e47350bfb49178454aee0c78372db372d99ddb910dfa8db6556b61d64e8ec833fe4737b13269583459a39bba6a1202fc709595fc0161f537bd825b3245bfc238a6c7d3b2295d1857129df86db0891e022199c793b319ae965cff94b078e467343796992992d388aa210d50599a3b2bbea36250ace162989e3c21249115a402c544aa82\nCT: 5fb2516faf226ba7767500f7bb3fbb0750b535b2e4e61f4b1a8f8ac58fd0bfc20d6c83b6d646de135d151ca50d10b7816bc0086e0e45021b3e5ef2560be8a8dd5efad693a7a15192614e2c977d9c7c21792c8226d89171b3020dec505a38162ecd1fb3dbffede31ec80875b5a5c84038fa33895e9f10242885a6a59fe07be083c7d7f904ca636f1d8d812e33d3776fc705d5a658984544a6554176b2cacb0aeca55d3c53cb065769e8bd13096aa7bc86ff923a856d9b6dca7146efc39ab1eb41a3f84bc3240ca7b4882ff937bbb21f3242e98bbc6858a1aaa21f5a603dffaf680d21c9c32e383d4a56c6cbda51dda0db76498c2d3e8dd746662c804f968476f5600c4dc32a2bbd966659b097679a9d604e93b0a0de11935a9945b92821f985a25d065242fa120048d4760d58acf930ad57091bcbca236fcfa1bc6cd5f84dc7d19197a2c349138679a6bb13727a207c46bf733a3a86e52907886cbf6bfccf82fda3dad1b94ae819bdd847f5860b9e9711fb7de0d50868ddf792b3383efb1a2002ac57648af7bcd48b\nTAG: 2205942e6c43fcc24e7a8e0e80c3d494\n\nKEY: c0bf7b2cdf2d0ee20653b1e07cb42f9d1d0575ea7220ec01bb31deed93fafd12\nNONCE: 6cc8d0d26816561102778d04\nIN: ba7d68de3d942d313a63f1ee6c3a37397348f01bc83fb878bb1035748038047cca0c07710b9d76e129f9b881037786907560e4ae9592c02967df22af893b3ad409a3b9587454afe0375846cc8ad94963c7dc61849ee4ec1406dc7915ee5477bb73a43035d67e822e45d3169db88b269824228149abd333af8e41d2be455bfa449bc2ef48f0fbcaeade0f6b62d99e318a2ca44506670fb1397c47d1931136cffc72ea33a0e1e97745e938ce654b9b961fd4680117388dabdbfa134c9dec8206797e72bb5e6c7b672e7c5d720c2035dfe8d42edaa56f54bd2dab11ce5ebc2f95ef01bf080ee82e8ebda43598dca58db3acabd7b3cfbf5183d07bbdae49004f5154d6bafbe1114baaf4c624688178234a6176756718e79bde83422752e7a9ee87648b182f8ebdd96213b640b76118b577064f871d627d2a7218ad19d45499ed3d4d9bddefdc282e66d1d708daaa558ced4edf38ee6f3a9add0f2126e94a707261234932d0e3674fa085a7e2688b854bbb9bedb328940b5d35fd0eb85f5a56f1406d7a8eb7316a17eafdd7b87ee85d812a740041c8ff6057a462ea\nAD: 51bd07df0a0b0374f5b4ff65ba48587cb83d20010e67f36106e99a5b733b8627d541ddc084ad0374432ac165b4e81c8601e7c180850e54d8db89c092d356dd617439f36d65422a45d116914390320eb1ed0736e47afd5131b7422234a36c5efc5fd578fd6674176a7ac0f73b63a3f5188aa9a7773a27f50e103c2faf3e0488acd1265055999bab1150ebf49bf03728bce3ceb49307e2af7bd5f9ac307a8d249f55514325a6ab58fd2daa5194b07fab933db72806ff4159075e140d89fc3e5d6b684be014b5f0ea1c85\nCT: d02e8bb096fe307bfb5d5f359e8895f775c126e43289fd30f631559a2edf6d5000974faac0b24b7aec5e6633f862009c0f3e17aeed6fc86154a365a99200d5855a39743f219cccfeaa317b7c9866831e2f61ac7a9553e6b6ab5e5c16ef2711cb0ea9a46a483c057316e4c82b62a895e6d4ed5dd9d3d43576443ffc769630f93b37cef9fe9a79dea94b84ffd991e4429ae6de76fa6d6a9f65479842070271cde06c6e49d21acf98f4ea3e2c28eb67275446e3bcd797bd610cb9aa302430993ef3453c4ae6133f66f766cefbfa5c566bcd43a357fbc502819224352ec68c6da3d596935dfd0dc79655373a588ba08beb1ae21cf222a00e53495946f9ffa7a3edc6dc20559b401c2c5a35ff461bc12bf656b7ab86bb63fd72e7828f3915156a93c4718eb5164e359ae22086f43bb1ac868ab6a3d0631baf4ecb8688a48fa802571606ddc8215af784b04f6823439f0d5cc409c1622ae2a586fe413e4492eae627eee9578e5ef9c891a23341561a9c0f342d824a0347eaae52da91827f55269ffda3ec959613cfe9fbe022f7a8f8f8ba2dd39833ffba261746cca9\nTAG: 7380475e9d2ff3d9df01b6c895d00dbd\n\nKEY: 7a97196f184755c637c4f3b8bdeac41fe1bb892b86047e88facc04e2d88532b6\nNONCE: f584f4ab378a3dc7d6102a17\nIN: 877db95465015e3122681258437f11d14b83f1159a52486b4c3bc6037ed33de9e856d3c89fc5838aee587c606cc0dbed9a58faad042d51042e086545fd9639b18650bd531065684076cd188f11508d48e2a7ee585e8c8e9061970a2d381374e0bb5ccfc8972a01d9587872ff0c925315d10ccd8b9cc6b1450c5400cee4e2edf25ad952f31da22c7f241f97d966bf491ff2b8f889dc798a24e184c64290656711a826290917db99e2c2bc679c92d309a1856867d9428ca2fe5ed2a3d0476810cca53b18526de0e88508a67c6797b507a2e09cbf5c31f7be6dffc78d883f607f0ec3ddbaaae6b087e8731cebc792dc840ba136374a9b654b5d61735d2d85a70646be9c470918201b9c8f756e971cfc12e0a93acf386809f769ed64a19f47f266f3504d47725672b2aafa611456987fd1db71d16a4d1289ad442f0877da4f192d814f9302a1207a8e8e48ed90f6b5434b35d47dac6a0446156781ca1fa41f7bb772d1eee48919b4e8371cf49fbf452187245a16b51daf82e35b77e80869eb84ee9ecd90312dd3e6e6023ebec1a21b4279bdf21402969101cd1dfefd0a730d3341571bdcfd36abc675744f96\nAD: bc7445f77f90f261b1ae207f93d17828d39eafae394ecc2e65bca79562a706c279bcc6d038edb9d7a344ab1a5021f9a597b223d7a1a99e1268dceab20c23e0208b9a898e99d83b2e788c1b7faaff2aa6145f8918f53cba3168db274d65f2e419fc233927599f7ad96890bc1cd4f983276b126f7d10b894a67237c7b67e8d633d62b39d788cc43b2f8a05d87e656ba86feaa3a729b0be2abec99bb40d177900f20b559c4e0ae2034409bc9b86c54644cab932e997fe0554e7eaef7b247aa00f9e1ec07aa9af3a86470075324d02c32425309b\nCT: 7a0f153b5f7976c608206d8791dce0f90cebdc0250b484d7e4669334e8f034165bf4a794dfb989206217c13d4de15e75e7e01a24d2c988212adca2056fa7bdf33a1ff69f6ffff29b78d1560ec21cb4cc96deb9b41437dfe044600724d8ea124f741a5605233143e54d8a58f68d5a7900ed57b734c61d264e71eee4477ffe4d833756c3f65c64ae8fd832296f61a2a7dae5a8cc2c7b3f0cb87900c8c1d885d42420e2a65c414bff138594d00250e8dc451ea319893fdd63f55cad85f9f76ab9806e687fa5e2c1096f13a09ca7febd28cdafc7d0a0592865e568a58b3622876aabdc9a0c0f7924c3173aa0b218e28ad98384ebf5baf7448f316ffd82c5d7b7a51125e65aa78291a342dd30d767e19fb996e961c78d171263e0bc8529c2e3ec6d9430454705a05bd841237a68dc4b7b3039bb3a0a1c22213c9fe6c11d41d39d3cfece07527e0ebacb593add061207c5b1fd221bce69cb5121050f805e2c759423c97a5952962f625c528ff8c11f6550d435d7fbaeffe4155d266f9d0e138ae25cae2030e31fceef9e39666da4fb7e196ab3859532bdcfc10f7ecbcbb8863e7a0c005e9bd7fd9f52dfe03c94\nTAG: d6de820a9b85168257da829272d6271b\n\nKEY: bcf5462aa20caa950ec9653939b043c2e94f0ede1b91df0068fdc903431008fe\nNONCE: 16670d77b089880c962e558f\nIN: a573b2052d3106dafe00e3acca3df673fa559f950bdf9972e20b9612b5c4c96d50997261be7f2fa978b793d5b61e74b82541c8c02305431a6b7495f948622075b5d18992d976737e1f6f38aadf90bfb46f7bb9a7871620218564360729844329f4cd2f0c77bbbf17661529f88c80d1e000eafdbb937411cbd4295ae697baaa6c9a31206c5711bcf31f2dcb50cddb4619d48388a57475df684f4a00d432560540ea4d4d337ce0284467851e86447b1f04246fb2167625a0b3cc16873841d23551653aa1678ba76689664e16c7354c87d5fb7d40287894f46e56f5394bacb222b30fcb3f5d55476fc37c122d6865751212d4f57651092066aa20eb70114f269b08e4ece1b804fa3f2c5e4b94981d41b3503fd127fb21c1ba24cb871dc6f19c2a674561900f73e292f618e1b3a285ec79bc7784e3481cfe36e1117fc620aabeb088585aef6632a7228a5f901c62f248b9ae12c7a6e7e5052d9739bfe303758989af254b78d5a42c74b13def0516611a1c0323e18070147f67cf0613cb22d83dc29c176b6823166c35202c46e85484640221fea9441b1e9f4ddfa4c0a2f4b2599c6fc73856e3c18a5905f85dc919883f3fe9dbbffc50e89e8b71b9a36c\nAD: 74290718e0b89aef1ec21fae49d280d3776d3ef79368634716cafc8f2eefb3f449c438c14deebb705a42e85274cecd11932c9a84f0dee48e8a2175b57820c1042adcfc42ac9a39341af5ff6edab2d25eba8f0219d3737bd4e7ebcfb3883877130c85e5be6a7b87cdaf4d37075eb2f0bd0d1a61567a362e8f66302e56668590b49b5c76eef962d1c310f8bbfdf8f57f3f82b9b2f72ef49cf487a4e8618476db71c6e0813e908126f9958ed5453067c6797eadb432d07de49dc2e50a266eaf6174cd1b18ab707a53dd47b564518b7bda452bc451a25ad2aaed6f2e7a\nCT: e62cb3363816bdbd4153221411b5599b453820d675b5824ea1ef57c2a1bee7563a092976ce33c918a33c67e4628d5661acf2ea7e353bd4cce6a87557593e0ebcece6510b63b9a4a2d", + "2c055e28b464a752b919c593623ee4c2a6bbc2b2a95f884513e446b10e2f0ea6ec98c10d893088084f7519f912afa35a693bd312335cbe2a95e4bb4cff6dfb6c2b632ef01b48d102f244bd0df83d54cda5060a01f3c3c3c8b4dd7077d0f3eeb89cddcddd23ed391697996bfa741dda4462efd006be7bf15c3b2d63aadc3cdcd862e3d09d0ca675e397055307fca30641f62fdba74ccef65682701b9551814139f4ee4eaba2f1739966925b56cbd6c3b16e94980484d32f51a216e17f07deaf70694745829564e486f53bf5cdd38ee660be09a8860be35873f14ce269adc17ce7c2ceb7941810b978a0db7e7d472f23e8ee80c9faef243cafd019d689aafaf0dab91e4b7afd5808f30753b46061057f302b8ca383c6dd7fb35b3282ffcc98487c9616a451386c1204d75337b28390e9968b24800c5a66449831da8ea3bf3aeacf2e6608b96c3291752cd049b168b1ed1f812a6f4901f30363a09b90b4b7f8af22468708c550cf77c30ca4385441d3c74e5f78c\nTAG: dfa7cc77acedf8de5a7a0375472f3c07\n\nKEY: 3509f704954bff2b50f5cabd420148967ff830b0c4804ad5081b42f842276c6a\nNONCE: ddae1c3199da88778d920a6c\nIN: 79114e667faf28fce2f7924c4288399e5b4968c711f03d721e885fea0668574ae965e9996aab6b30b6eac785cdebc45a305b806ea90663927b8dbe8116292ddcc56938c0b1b1639e8068db1e4cfd101af5478dd63fe0209125ce92e3f7f7fa43dffecc07ae1621f32af975dcbe3f34f1dc75c75fcbc4c23ee8b8900c2719f4a9f50e57b1f9a9d9172fc746112f12b17b85b0371d0472d3c193c37e837d8201fe7d3ce588ab7e27e8457c34d399edfe3af2142a2baae6c6ec74863f6415ce30b17c17599860bf9a59be41a6011104b9cd0b8241ca52d1f7910cd3a3ae8693e47f4675ade296a8c507fba35f62c82d923051fa718d52a0279ba997149032b3a91b1dae9cddd5a89400de90ffad1e1a126c41459c512c261f089787fcc18c4583abd4c9e8b7844389db3d13e8bd5fdb68bd76c3878344241eca6916049795716b257636f1d25230db71bb10725fe4b9217d5643ea14754a69739cb62c7e99c5157bfb8c153cd754a2ed10bbd574c718b8dad2a556793e00d8d5a59bdd486e768f2e61ea822822532f8b4d77b3446eff2cdfb7d88d37b3e7ab0686679e02497abc04ef7a240d456bf999cff4268bfa6e366831559de7775ed6a6d4f02d489d4c305f25cd96f2239f2725961d5cd8\nAD: 23d72dea41a1c1f1611fbab63d339a8dd47a3a31b7790a605d3bbddfdfb66ca6277a9a3e4036e8662d6560d05a7ee8a674e33d6433aed82fa26e5a1f5a2f47c28092ced2d182eabb9962aa8b10a567ec3705be6889e1415713b9ef08731393cee91370cb1d3bcbadf5710eb841d37992a7aa3573facad94e806d0019194b2cf9c41db281f6ea462e2ab7364b8660b956e145a13b77962c3191b2e46ab764392910cb7410d740aec3ff2ab8b643ae7e65d34f895189bb41902fbf2c5476301600932728008ce33380845f22b7db3a7b9accc8cf0793bf6ba37d405a6bcc8cc622f1cb205c\nCT: 44234f12f5df525e7f45d785a5503ef1a78398d9e756eec0b97c426af4661471c57baba5b76a19da18984c8824b0e6573ed324758918543618ece2163e969b07fdb6c1a65164e09f1382653b5cc4823deba6ba403046860421529013e79c703e2b467fc15e4a39b5e9caf9f521a0428b1e68fa51b60492cb6c021bab35107c452c94747b59034da681b1f253d594494983df44e7b394e3c9fa190802fef8fb178a2828ea7ef2aa41cd56779036565da68642da9456079fd3bc8718b218725f657db994a19a0a01ebc51f7bb1dea2c7d476417876a7ccf8b517b968b2243e327eb6288f02858c3d679e599c2d603c80b33fc3603f689b91ce117a8481074f11540f6d75c2bbb5d3c8a3a9d7b5699acef00ce981d6c5fda7a8fcf5ea77a365873d185de9f302be3ccc4567b98b74cb695a323cc6ac162a06556f8c0a9b218407a909d7b173b2f1ad4a497fec9f8ffbb2436a4101f57746cdc24ceeb234fd8dc6f04e488227d4a2a42142bb6122b1b59087dc902e8d11e81852aae897227dbcfe872b537e57849d51968d1aa2dcaa63d6de8faeeb5753cfd8af808c69a2a7e831b34ad8e78c97b6a162401cb85247e9d89bcd593242e8c93f9378c1880a4b3c45aa434a5f6d16182035dea99a4c\nTAG: f53384a5ef6edc2cbcfda00cb7456d78\n\nKEY: d0b6e7fcbf3a6eb1d3bf2fb91e98593959077e8bb76adecdee2fcb008cfc335d\nNONCE: 5465e4e10e9cedaa39db35fd\nIN: d7b9533c5b8f2e5bdb427d8bf42c5b83cc11d2ac5ac96f6cf95090c5f439bc5d4828238a86c5d444ba0aad7b6c5917f673010f0717007a77064bc4d29dca0ae96b381cc89d04d5731a0f985a1e8071a0fff733889d0f2475ae9277b0ac5f7b68a0533f16f904ca15969cb24c24faf7a155ad51917187c5ec8cfc95352481f0e9002eee9467035b3d618b7f6cf9faae1de33af239e6ed4038706b735431195f355a27d1e7098ddd1f34fbb0bd3449b8c7a069b486984d09d50a90a099934eecec7372fc137b5274afe57bc0cd6f49b1e17638fdc8602d31fa975c4f0223349d40a86c36fcbf43124a4726e198729362ba96f79d5e0d89fc404b3836737445756c6060d9e95d1638a030ee5fd954f5a9cc662014ce7420fcddd9f2ab800823246ad30ff0d0f7789fe11807703a731675ceaa31b5835ae039fc0d111f5725ce4df0b9a075a8bd1c1112f90bd64c668d1d9e794228aaec7c17dc664ac88668cd06ef9c425f2815891ee4b737b18b138001eb6c353bd5fb7ec26b2d26a12ad2fa707adafd884be4251bfcf5e5e8f3979e46d90a57107e7e4d04c658f6224d1a288bdafe8e34df1541c702f29a1db2af2279380d49109f17abc4161a6052f4ef0f6657c7322eee44f4cae949dbca447cbbceb9f10c5be6de1d8886766794a3ed\nAD: dd736ac7acd3bb87cf11e88f246fcec505f595902d1121f68557657f81340261684fde901c079dd73f7c9e1d4bdf90613e7790f334884b668ee04c29750d2baa21ba94f2407a512dbd8450ad4dfc0de22dcbb291045e0fe43fde0cf1396cd3bb959f2dcc1f7ea681d0e7cbcc73e7fffdea35f6dbde8ba0079ad97c8767bf76aa008864375aa0b02b89d8bf2ce7aecb2403648e6069e209f7283f1cc180c166786d02d984afdc4f8eb9479522362fce0633996c758d99049b25c89a79f7257627e2a9557363a290a0a3673407a298ac1cc034793cb7ff44833c569780bb8be9e937a3a758f1c570ec1c4865efe8\nCT: 90ccaad48bdd13c3df79d9679465dd0d794b0a0ce4ded4add7f3e2952bf8593c295d17fc43b4c44e56971e0fdb116bae0e7e3203bd02647e8feddbee667ca469ba3b0351a968d746ffe033a60a26b12b525d280353605b71f46cfe3758d9efee4fbb8333945dd794eedca6279fcf5a31003cbce29d748e39ff654bbdf1bed5e7516212dd1ac27e0ac5a121bb5f95c124dc92520b25b8de80874d5d230214c30a8a17196fd23fd91b00e64bb0fb78ea22f15363bc532549252e0f2fc90944ceef75f7c320e3ec75fd148cd130cdf48f88f85cfacde2b6b80ec0f45d0defa941fa89350429da61aea18d25a2d9dd156197dedbc7f736208390274143f63a4f8d2f1dc557c544e364dd3923e54eb79cada64c69c7deffd3ad75f8660b90ea15a2a818d6c5f0d6bd43519eec6cd43618c35b468e10d17b79865e591a0bf1324941a5066c7d1c12dadb77d4993685ac8dcbd2c284f62273888c453808ef40c5d09b054f8459a43c0fbf5c714e8c7b8985ea932ace7a79987b0a9be926335b87d37bc182400a38a847362b3e74b08a952c8c64ca72f1b79d6e0b52cfbe28012c1aa424da95c5a2e8b8c49dc2f305cef00e50b92d320cbec992ca1656848860e0bd790bac5298b7a09b7586c866fed3dcb53afd2f7b313272f1c4b458e1b1bee6\nTAG: 1139d5d9f7e52a51d258d95a9a51b5a3\n\nKEY: 5940c08a09430a9fd36376e28e127f81789e8a605405de9c452cf8c7131cbe37\nNONCE: 597c9a73eb47abcd2aec1b2a\nIN: 8522f154e672ae25f8494ff35d2573b343213a2fbb07a417d8a60510e7eb1ac5ecf229429f330809c84b0c1ac8f7e28c7f7414db905be8f5fdb5a2f818ba8440b8c9c20f8951b8e9b75eccee79b096ab09f4ec99ec394c7295b30d29060790d3dfc17d1321b8288f3be38b17901a48470784d00c5b53f895fecd4053de78d074fffc16c302a4f2718327bd96445318ad247c99c0ad4d06405b6509ba8f6bf47755f0b297c4616790b25edbac2fddc89b8d509d6955cdf66d30f2bdccac6f856a3206c53c550a9970ec450097ae4cb6f5606e64c750042060c477203479aa4da10edd4d28ad3df96d613194646abde78eee8716382167ee6f77730766fe8b4ca6c8f0270896bcf14cca5d7c2184dc6eef47bf9fffa3f4815f8fd7838c0fec7e9c08bca51970460bc013145f2d651bac1cbceda192014a5f27c991ed3e7127903fd49a5b3a4dea1194ccc10eb62f911586314ada3aab0f8a5d53c90560da3681bd9157892ffb1a381ed33afe203e3c09748487a0b71b8703f6e5f84d9195db08e4c4338343fb8e968d9f5a5b1606b6b20fe60cec3b54b49ef7bfc81bdbb2926ccc79697d916c3b622871dfe9344699c509f9b2775abc12c486e71a008cd525d8610f51948f75bf96bb94c59c98f2e9f35e8513e43898754f7338d7fffb87e538fe6512832e5c2b08cfe952985fac27\nAD: b0e81a4edf9fe8b9f2eb79758a99fed7907343e6be072bc93fbfb5a539142a18af4e4710283deeeba4e0c1c1cdde7e886e7d04f817a5efbe89d12cabb34153856af1cc98c4df21cbc1da3e34f0ab74842a8757a189336487d3ec77f842b10e2efe3e1e232fc1dc89d16dec865cf6e9f422e7b9d7a4e421d79657eafec5451e04174b3372340d6fa8cbd23fc0215e9b6d70a9781ff3b8ae049bd31a363d3fd465f235ce463f720e4bca114d21d3dc407a66f28df01549d168544478404256715161cacaf06d955f525546d384a44ee0570d8c70319bd33aa07b5ce0a891c467957d5ca4d2523d9958a8b4b3e5d3b0dbd1f6a1df3acd38\nCT: af56537eae418deb9f7da2500111c077ca99da5e835705385924845547a592cd3910dd419e6fa4b9b2d7c21d42ce2797873a494a735cfbb4277143dd25592a1f70ad8d29a42b55f697807994a1c0338543bb56543609e052e52e1b7ac473ce717711fd7ce4c269291764c11615637b29bee0a8001ce82003ac91f410153fed863f7aa1071a76b5583852f6e8bb7b565eac8042e0ed76704ddcb2c03504b9c79b1e66c179a9e91d2cd890380421d84e05a70e05c4aae13fa600e57a78d7668e94f87d7bef00b055118480e4944131a39c7b6066161a3815137a3b0e89cc0db03775507b4d3325ee4449946b33892e064954294c6ce83c97fbd7f11f203fd1af49a478cd3eed3cca766ca3b9d3402dcaa4ab9729f209ad46daf17a584d6187659b039176deb9e08a0cc78db16e4122dc5f81ae4f5ee23a7140d2041cc81c8c43568fdd45c9ce4aaefdf7bf2f650f478f7581202b548164c4c160d3e2d5762569341170304e965e09474130e397bda5326b2aa07067a4fc8275a1cbcc43777414185b243ff67f8947b16db687a5b15bd5f685ce250be6ff21355ada2e125", + "b64b57d57b94d6461ed19e77bba9234ba891d8da2008493a07d4f8c76e71973bb9ef87eb048c453cf66bce0e820966d9f62d39deb43c7a2c25335184e0e5ddc1b191138e71b155d39271becbdf097bdfaf1\nTAG: febaae3a1e94e47bf92a1171c91aff8e\n\nKEY: 888d8383ca76d177685ea6d2d65bd717203ccf794d613b2f4d50894cb12754bc\nNONCE: 95fc19c449bfc10443c5c163\nIN: 88d98f7a8343cc89faa48882e8a60f83e817f17f68eb338289e2deeacc6bb5ab6d25635b9e0d29fa87ab97e5f29ecc47641e5a4e0d5f11d04bb25c7dcf21e7a93de1880ad022c838b5c957616764bcd2a66f1098ae4926a93e1726384171cbd9503e03b72c77a2721003d3b391f2aadcb32bd62e492528ea3ef5e85761cec47b846d32988468391db2f23fbfeee39cd89a45e71e4d4b29c6fdd8abd1399faef491211e902b0a99b451c58211c56b1a63dc2e8a57e6efab94ca95818a78fdbdb533f286b83725980b9bbac766d3b3ebfde01532e7ab1414eb6d52ad3b1908cf58ba67449cff1d605708d5fe6b21c769f99874249d98ecbb3c62956ebf6f471b63e84a8114f73f918aba186239947bbbe2973181d9b48e801e3a5597b01d166bd2ec933b48bb7376ef131fb792f2a26edd267a713570c1dcac5a223646f6b52b0774ce323efe526b12f1ae59ec70bf6ff62f857374299cf4ae182015cc0cc2545b68d483689c82f4356dd8a06cae383848cbe75f08c5deb198c7effb10973b21fcb72cd53f6baeea5e23b7bf4508825111ab94535ed5ab9b51266d6eee98faf47b6a3acfee64c4a6598baacf1831a0549105d47b72434f498d54ca59041f07d22f3d6b177fe53b5bd874548daff7acab799c3253435551d963110d49fe1d2212b7e17df5b98a0884d9b7153253ebb73c0fe44485d78821a07b5e69bd446eae17\nAD: 0e8aa718709f258a2a2476886757fc36fda2cd5230288b9a47d4a94b96c8cce880d1d06466aa1b331c0b893504fb8d6047b82549bfe807401d795d784584d608e419a7be990bf099694c788f11c29cb9655057ff12b4ee4b579bf7a52a36e9be42f06fd3ea2a8774cf70c946407db105cc88bd95f5b1f347bb8b4467e08058153edc70fe78bc8fc06f462ba5b16c5a56ce8a357700b43ce1fc8210c17af00f0ac8a19f8a73fb47815113c960138b2238031a74b610a1c45e3769155f6cdb7749d801b8f90ab5cd658f8f28443de9bd2e92098ad7915a6c68342255cc5f1abd5bba34316a297246dd2bc0f3975bf0037c3d17ceb9d9c9262b0797a6b5a90c72\nCT: fcc54b58b1330cc5e87305ad574eb3ddc760f12a0dbc5075d8b7e825cb52237f48845a1099527fcd5e483f2d99a06a413eaaab04e641bf7ee3e6f08575658da3e48af76b849ca68443b61f260118bf7730d9a4b965c4d55d391c66c87ac9a065f32e784758be031f9f24901737da41fb0b800e61c5d3e75024ce3cbc03c9b0a318b90821623cb50e487fc15ffe6e3b1ba69b98ab10564bb72f868faa2e4f446e5331065f36d30942022038d11dd040d872aecd22163affa37003302cee8da8b02fc1ece3c3b6a29bc515609faaa460032a09adc496bbcc70ae7d35b78c8f97f4b5a55b9fc03a00561bdbdf883edac8761a8c31275c4833ca06a212dcc4fdabaa022c7e7daaaa7435b5c7014fa3866bb77890ef0955afb267417706ccaf3ccd9e633ed9892fb5049600597e9b85f73f7fb065bcc748237f33a0c300298dc4cf37781fe632adac9fdc0f3388d315a1816f315c96b8d75c7143795f56e0e51f09443396dd7e291828cdb0bb70125e90211c68530f33e0b2ef8bceb42905b908fb3f64dcf48ba8ec4abbcfc3da2bc6f04dc8bd993a438cf3e64efafbdad932e01ab3000b6bc819e1c205242220ea72ecd4cb38e54ab7c483a58956f992304512bbeaf7fc0f987098c25797d734cdf74a3bf06a5ec90cbe1e12e59fc47e8ddc4ec0ffcd90e0db824e44bebe661a88a94b335bfd2d957186723d9e0d50544e68547c\nTAG: 9c7a7696965ac3b4d1b175a1136fff97\n\nKEY: d4af4e662935bc7de08739ed8340397b78f0f7dd4f96a2fe50579a1e7754de0c\nNONCE: e06145d6b247742ab582584c\nIN: 3b9c868cb0311b02273fe15f7a87403140b7b3bb49342cf26a5e68226a2927457c0f6b06f429c6cf5746b91ce5220e3b20cfca713664f5ec98b972fc3bb098f52c973a917f3b68dffe955a4fc670fa9c2ce686ceda47e060b291fc5a39fafc9489d18c3c3c08e580e492e35f058682e75e06c4141c38fd94b23eaf1048557c668f26da84f08718d850d65f8ab7a4e94c66fca8bf5ca345e8a966dff970fefbbcb88f3cc6b791ac03cad7708492675a2b4c54198b3f5f8906f3bcf2a56ba04666698c820309745aac83b45fa89e794d56a16fb3d00c923632c1d68fce42296729aba6ca2fdb2155a8000baf146e461c9cc1ead957027a7303f01622d129eeb87604daa5b792d6d2cc4ba08cab47c3a0209195dc19edd01f1a4b54fbeec73c422b1c06558f3d70a2f96651db1e0364b7aab14d496a81b169e244f0f0657254faea172e9409bee2934fc622a7b2079f8368f53313790e1c06144f7f140468266fd6269b4f442a06606bdc9097d4547665f7fa192f67f0a14ff3a9f04092386d705a0a7d3a566b7c2e2b6ec9b6e6caa258ed2bef1ea747c6c80c0b494a5fc66906f5bec5da4aa884d38a6dc74af82aa94083106f6b8e182b529f94f4c389d6730b313ee8e656637ac064fed06561ea32b4dd3a3a128f3458c6e9b500cf3e578011e6b1ece6ed3fbd896119511f89db1e1719ca22a30b779c26803b278dadb4446fe2\nAD: 8b5f96d3c91d0280dfb3976508eda8e803de1205ef65b3f7e4a41005165c5f3267b60a679095c25deb7c229ae7631c9df61ed198a9e7d9f6267bf288ecb88ab82dc3f210867490cf9c248828c73db475a757979894c16382fa1a9e5a06c081fec99aba123f6ebda65e07378026986b97a75e0f3bb74cc26f4b813d73c4c7fbdbfd5fdc4903a51d3064783309e497d14db09564a75551adc83197a30e3584a258722dc95fc187964f3207579f5d0caaa98d9dbd547cf2b854c4e820ee2fb4c4a1c83ef814e6bc48ad7cef6efb11b7dfdd41de49f1ba2317849f153115457b6dd839b6b5c84e8bd11419c553d51cb00bfc28e7c82718db654b4f8cc7f37b4ba96d\nCT: 3fe29eb90fe4d85b070d118e2ee7b5820ba5aa019b5aa64c04485305771ab03b7dbfbf9cefc1f1d4ac7b91e82e460e1e4bff9d6ec7cb61138fd3521a9a13aebaf082907b6bd82fb0cddd4c6d2af72b054c2742ded0241e2db9573ea7cb76b56b14c7bbb2a983b9032bb701a83f7328da550e6fe2c07026a81989d030610afa859b1622c8743e957d3441f044339d5936921104f0d98c427fee9430dc1689261c63f0a02beb9095623480ba798fd13ec536d678550f10f71f2dced90edef6e3db5699a27f20d2382b06adf5df7108d44b5610bd49a7270d1021b93cb167b15cfbafc875c9188211fa31aac4dd9f4abff49cf18c466731d3d343aa04851abf731137c83e8815a04cb48957b7514f5b8d27d1bcfb3f8bb805603062fa4f2a1e50734b2e52ca9e99bf834001dc6f57fca600bc49d0e95c2ca80581a66176f182cbf9602e683b2480492d1e6b0f6119930a85e09f4e56b861c8c287da0b4028c055e3f325802260b7666b38da47960acbf10f9206e68ef247a78b0f9b7b5bc50aa6f5a47684d1e64c79ff28f1bb21bf3e67f7d6ea5c2074b45bfa7d905b989fd262afb2253b172415c16706b9c88a322787a3001460848391863b71aba1d23dda76adb560e7a03c81271330bbf36b6b21d1c8965f8973afa9772b7590b9de18a9c961bac11590825abb5a7fbe78f4d120e6eff290b8b3e4b36222a0fa1de8a5ba2501\nTAG: 0948cf55a922d9ca8061356f5a829236\n\nKEY: 09513c60bebaa087fefe7934112ead9e90d8599e184692ce235fbf5327dacc20\nNONCE: b8d41590570fd882012b1207\nIN: ef4f33e3526fa3c64c4cb725091dd621bd6f2ce69c29ca39aaf172f05400ddc7af2af0fdab161af935409e3d5b9a8fb915a4ff8b7c0d4baf8f0a103be99ee7d21eed37e258bf79e18a81cd42fef0dfa465e04cb70fd8165f16203e8ed49bc2c3e88476aec77b466debaa6d888cf8cf013e8672d781fc5a8bbcddadf023d7208ed5f6f0ee2e3418158b653431fef54f821f38a69202897126f9a24a5793cb38fe5e8b3f77034e080dd8e4acc7fd22a12ab64a47f98f588e756fe691ab4c7f4557dd9b77e28f997d687a068925d18fab49f3acc072b33fb4d8c7a60f9a639b4b1d785c062e5d386261ff9e7066ed81cebf6f483466c0747dc221262a7e7959ff156f3e69dcf4c3db8ccc256d666d3700475874d600d6e7f69a2d094c9c55669bb4b1f72583d23aeea9b858372c61516fb3f096736cccc3ecd74b98606a404a5a6195fe0899916c463092a749274e91831ef63b254a4c70b737bd8bc070b805ee42e5714b07dd4fa39da758de787340c0109e55ff4aaa19b05eb8e2b2ce171e4f9854d6aa56536b35359a7163557056ccca870012954737810bcc6ba226f6f38b774da0edd4c3e2d64ba4d6415d6528d7227a5a0ab222092c7035a8fabd3897bf9f59eca8692373b676b817d57f83aeb4f866c553b2ae1def7d7760cd152d18d43178b351ab4e23272bf157ec2832fd92b4d4e9085cf51da487779d82011745d0982ddc348613d55143bfecafa431a4b7cca9\nAD: db82856c297682e62ecd1794a6ffe02a9e9b69814a6cebe50418e9bfc9e494b04afb9c0d6db479a8bf1c5d88be4c6b81246d8f4ecde7e3d4c6aa777277f705ef81962ff56d8174255519c00ccca0098e9370b675f736c86816dab838d7887b1d9bd638613a07b7122a9d55b4a7cedddda3b2337d3ec7bd20e499daa467c04a9d52ca1a02d119a62c6dade203a0bba45d3f9366e3f59a4abcaa62b6c08255d60798b9b0bd6205f2e24253dc75e8aedcc1bb3a525548479fa5363bc8176075ab004e7e73d0ac5f5e8717d3389f3287eea904f91fe63b5cd860091a42a101c1a1e6b13b31e2a7382f718dde735feba88ecb1ab41d042c4ce0106fc78b2397eeab842a8e0e5eb83b31d212\nCT: d412afdcb77bfba94aa9a2a3a3a016369706fa4ab1efb2bdbf4c657fee4ca85b1c497a4a85e1330854fbff098c2f8450b7a95c4642b970518293a8d6e3f66ea0467cb05b7f2eb5b406e3ba36e153d97c9bf9bf45780e6576840888355f6084adc7ef517ec42e11271d2b72f2675553e21521e4a6b8f92f15fdaee335a4b8141e42a7204e35a96a3bbad2b955e1d9fbf02f735cd1c31f1fbc069b89361a9e0e18c75a587f7f5279a9005f8338412e71eb6e7e644586b9e6aeb6397744cbac0f60b086f7e36b7147c27c077d7038797c6da35bd3812b68dde48917b6695537490992c847a544092c9e16f3715abb930080c10dd8bfc26d51e7fa4b8cbb785d3ca64a2a5e21a10312dc4b55710d7b2dbb727b285b087c542c0e4d9055e16cdbc90954a91dc417ab19eddf8084c765ad1a2636b542411c15f36953f9e6a177089fcb9bc45f0f2256f7b461ff5551a5518c5c33f8fffb282d4698d1ad630cef7bd6c0577624a642eabe3ac0f78386d8dd1429f02a9c206037bdd6ef066ec15fdcf52aaedc1771f3f424e417751b3ee9f8a71ca47a45bb1b8608f68aa1cb29afac84fedb11f579b848e76a5664a8978d5", + "ef26bd087bc28822216454a193a9c4f19126a108cc00b25f9cbe0bfbe704834153bc6dca55f32c4ea87ea6774768c5a36e5e39be927c2e1d4055fd279d99d1b3a8741a4320436791de823c96cba601c0ba9f36f65eec9d3117c6d73bdfecd4a3556f84c\nTAG: 8ab0f495275a56e3a0d77f255a615fbf\n\nKEY: 501f265508ce73dddb94729433f2388d1925992f4cc6ce78d9be734466b66d3a\nNONCE: 702bcf31e90cd2ff6a350a94\nIN: 689aad4381aa79708817b7e8110cb9a8fc8cfb42a277210526da057e93d32c609be4efb1fa4254c1cba3cb3c2bcb5dcd23d1acfe671c4fbc2b632dcb8ebaa952d7f6ee68e52a59d4933e27a54363c24f4cdb4c4f7ad2cb7c666f9afb811c06df7bfdc93f25edabc314a9a1118c2e0a7cfd219c10a28b5de83dfc3114dda3fd31a3256fc3c915714f1b7e83c6e66273b28944f7e9668de94b8e2536701ead59f9f7f7043070ffad0ff6fddea1d9f92a7af2ce3fb8d130203d0e9550d29785063562c59fe2a699172f32126f6176e9313376203cc1ed15812dce9e304582533a212b3eaf209ea16c8f83db448686c0fcdf5dcfd957fface636fc31ecf5be0072e19e93250e5de639113d920e239a0d1581e179f9e90b5bc077c27b08427f0ec327545c1a235b88be7e8451a5bf405d0dd66664a3bd284f74e4393f969380bb63010081457effe00a972bc6e4895ff82dd4a50e302261734da0efd66b0db1dee74601aa414cd9e2a4c149956bfd63fe0fd1f63f3dabbb6aaa2c651405e36286d00bd0a3c9bcdb8932c6e01300f453ec1ec28724b8934d26c1405f311b67fb8e97ee14624e2d6837bdd38a491a019592526095ca9169b4657d65486470ec12dbc793a42df7d7d9cae29135bbc499425775996633ea60ca5c6711e3aafdbef89ff1bc41d20550c219c82a8841ebbb8e152fdcc55dd689c7768a97720e23a7f9a80b173e679c0e2986e4dc00970fad5f8706a674bfc71901952b7b02189e95dc7207902abc\nAD: 673d09046fe2326168dd702a76328ca26fc1abffef071f58f968c165700845a997a2013b71c5d83cf6b6ed8d76a1b6d1417d22fe63691e88d3774ddf4ee205f352b765dce99ca0a996d33f95f853ba54f2f9ac3e6d1c068567695d06ee8f3c9865f034dc4b397a15cda23a872a075257c10ad8e2c6d3017ca9183ac2d8b80068a88ffa995045b96df11faeaceb7b41ad716122f08cdf72f9d4970e5315a8bdbe6e93316fb0dd8d1b805ea4861e99cf67a5c8cd3d24eeff142cae3c53eae387b4f51a45bbd808b7ca1c3b69042c33c8a4dfc93246e07dd93bd12c40dc532f3738084e47d38983f6b529e3f61ab8b17e0b588da524d0ca67092112be6868d5ae35102478ebd35213e7b545c859effd6a8240e0\nCT: d0bace68d76a5be6b31bd038b921b6377f8022e09bfd90a8a94d55c9147b07e9857891b8f4f43ef410378fc0a54966918bae5fde49658e1f6d307908b5346b9d776c1a6dffe52213286fcb298c741d04e9280a4b108419fe9dc938fc5b3810183bb7004a3eb05cd1fa81646e7e64e76e69ddba6d086a020f7c89ceaa7ad53b13b01c5c1addb818eca6d4e060b60e31320267e199af494739f67544542baafb577d2bfc36d7f92b8236dfc6dd5613c9b81681f10ebdc97e49432309d8d46ee1770bfa256b871f9bf76afd426fda88b91fa9a407d6364c181a1f04f17083751944a6925292fb42defb24c215b0128c6f500a642cfd230c89ae2ce117a29adc5c09f7dd4d97a34b9fb4e55802d325a1a13d0f6e664fd5f5a35f22c96c5b567d2297c5832f928ea7041b11f7ee546dfa03bc03385b231c0503657f0119b545faec4010fb67469f2b9bf69f4ab89abd70c339893fd145758b3ae47b44fcd36c20d361e597ca573317b04a5d00997755c97ab20f9b0592aaa8d10a940be50f33c9fab16bb0fbec7d92d21c378a3badc8c2137fb989c9b6111ab8228c427338e0685ccf979afa9e887f06cd840c2795a9e08ed641990f0c29d061c4f93ce6a15836b34dd428d5906714315cd9bd2f636bf9deb8a6371ead07502a46500f987f2ac124428256044948fc4a2cf778012d349ff5f9e3847c8b71793e8acdb96b68eb034d08f6b06db00c72e10bb6574fdccdf39a775628bc387b9ee026866854f52d91cc62659c\nTAG: 54c66aab6e2939029293205527852b9f\n\nKEY: 428bd480abeda17764af5b6ed4902977f21fd06e53061ed8b5bf49ea381cc584\nNONCE: 6f6eb4aa086447f4a7e5e8ee\nIN: f4997366a2f8f827238ed0cb5b691154f345b4586e1911469c0c81df93859ff0a39ffaf4930bd39aad2bdeed92d4580523e5244640b9e6d3609b022e4b4d0c631669e00571f8d602938eca0b3bf874c0706966e3d07902e392a6721b7dc57028b0bae7d93c40c803a03968b2142965ff03f92d6e729a0e079a9dde3bb30c9c10ce6a5627bb476cf1f879a51104f3ea6d0599bb288d2ba5e0103352372db8ad379cb629c82d212c1d1c6543a8070fb01f61f509c597e92a05f83ed49f2a1c1b3ecc64ad0a7d5884320f481dee5211716fc1c6ef96f34926cb5ea86eae04e934c6c0214eca8369928f2b0bc93c0865cc4e165f2eb1c381642560ade7956e5d69381537b796a11786e8f20d264f0dabf0f31be89acf8d7fcdb2a063de5a9812a3d6aca502708d448a869bcbbd3449eb7e893e3c96cd76039ca41036c8fa9e365709afa301c30b5430e004dd08900d75815936deaf9e7753d8efdbebe09c27426b55161bc0ab3fb00973d093ff6088ab6f309cdb1e40cd40d3f933e0023f0c210cc7ddeef2d29d82e0955019e482782462542e186467bdf9b866998a731583b0906ffb0174cb44499d2d5e3d1fa3577f7344c21362f77e94cfa981913d6592ad1f537c13067f8e7af921db28e93673ee38de0dfcd497d77162fcefc7868ee3f27c07b0d818eb553fdf7acae2db4eaf657853a26b0a760954331b8c91e763f568d65e658c6eb53a69ac6bc582c33f8146f6c8ad66d8a454be952425f3c0130e658bc1934db754d70774d73b40512e7a9782c4478e1f\nAD: 9bece80281dd6d8eed2cbca8d4bb08df65feaf79e9a35d075b18e69dd39ba1f47cbb694173432f5f0ef125a9b1902ca97820b6024ae5b49a880ee9e12ecf561ab5abdef81366019a8be495af1d664970178df68f38cd83b416d0076a522a9f3f795e2d2c19c75ada025cb1ef41513cf2c29df9a01e16379c101197da782066f9318d4fa0325bd584b04b1f9597070cc551693c964b2100191e1ed949c426fd2befebe5914cb567adf7518aa4574921516576bc33673e6ffe422c831e616bf6d03476af169d9c4208d7975460873e2792c209c089af7014768c0ae9fa8011c533fc890e366b04d1b79ee7d7aeec0fe89ddc7400d6fb8878ada40a76f65df17bf34919fb5ff7711ed698bbcd3ee4aa8dce8f879959011612a3661c5b\nCT: abc04db39ba31976883d21f55078e5e4f5ead60c56b232124dd035215a124a489249ba560da193cc3152352f241070313d8e8b693bdc7f72e91c34a5713688a6a8ed1d3a3fdd0c5f118fc83df42b8ae307e39b35021b4479fe240be8e161407bd82950dee7d9a13d397cfc10d38ff3736f47a4da0ddf2cba1501c18674a71d1a1c948e038632d65ab51fa41347c583bcf2d13b2d22201957f607e57dab80e8a1bdd2b9cfe95b204976c1fd5f5e9fa304d3f9761b63d0f5dbc7a129bbcfd97c437b7d3bfbaca571a50192cf309a209dc29d51a18cee2ea9790309795ace41ce20c12eebfc6db620c398d3229e773f44048d596bdfacad90e277518ad0b2f8841eba71551f79fd891cd1aa84c6c87224bccac2c95d9ec27d3d0278b274dfa30a3fa8684f7cf50bbb80c49ab4b4ead2943e87a31dcf29df040f1dde7e2bdb097d230bdefa5d541572b9e759edcf498d0db993f5904e838d53230e231cfb57266fe0128c2d8ed81d6be4b0a14c286e9ed109fffd1cd4d5d5b8b280c238e7e276095659da7db5bb400c157901b111036ca13af2c7763fc33fb45f857d4250ac1145678dfa99960c03327cd39f521d71b582a85da13fbf2905faadd0c4b7bdc818761947a5fc42215657959c335d0dd01c8562bcc6338dd183d51e8b3261b90e0642853912da5a19e3c74a6c109e845fb700ca20c5c9c4a185b1060a830c7ddda040de695df1ac085d7a0b0d433a5530e5a5fce1bced424383520ad85c40d709389a4b3e151e4e8b3c68bc5f62bc9acd0885fedf11fe\nTAG: d340ff2101c55bc874a152a64dbfbe91\n\nKEY: ee1a9d7db69fa33107543f111a1c416c92bb873bee9f01564b44922beb1c8158\nNONCE: 2c9c6974f2442b87c02cb723\nIN: f5f3c05c78a22b7ba6c3387fea2d07ff58ad55c67aa9ada12563fb296812d087ef3b2d47ea1adb6a7dab646bfd1aa9288c85685c7b41c14eed3c5a34e0642b20888c8d51a65a1c332f1cb5779296051065211e5ec624930f1a2bfb6c10d479059063a2a4614999b0327d00f875162440c29627f817057f5151ba9c9364f0a6a9be85fe7fb911efdfd5cbfd741bfc63564f0d73eaa7bbf4fa16de77fd807bb27a9afd9e62c86e7033b8a969cb0ba9a2240de1a8e8a3463c2fae49c89b3cbc97e59eb30c2ae35834c36c22bc056a34cbd339ea469f3d8f032b5ae10eb00003025e55d42c12d9738ea74703308633f2772e8cd3421d8fc9d334c2845870a2c68c553f4dacdbada3af4ea8f20df3891aab8db9510c299db2bfcce4ffeb5ff128eb3c798dcdec4c665a4e7b30ac120aace497d03de3d726638db82034a19df83e60cedacfdd511a937ed73adeb1565661a201197eaa7fe817bcd9b83a19052461f56c3480c0e0d3314c57aad4f02a9e10afb967f752fb144bb1ecce66ea05608ddc7c876ba95698b04e79a429d36739d31b52e47fb032b18e7686923700e735750628ac0effa74298bdf7b75c115c6ea30634a9636c7ec5a02aa467fd53292d8991fd2cd45078471ac3bd8dbe47ad901047522e82cadde3b4f9d0a1e2b8c6faec2da532a09c58acaf7207fa49c1de10f377bcadc903a3df381a10ebf7556465096a0506e7ea0e7f11e00411f226bf2897f85791d6e34641d8cd049d95d996bae9dee6b2417f558f102a04d758897c484e930cc97d13f540c00f950a1b384ae5139dfaad258e13\nAD: 15fe76b22a601f7a11d852a080c228065f423c380393ae13ba817f18afaf48f7df08ae376d62e770b0c98e49298bc1f6f1cd07b586128c42d2196d26bc6752fdb375a0edef255d139b35841f426f090f270d5153efe6dcbcc2f4d4fe19258284b98cf70483996003889958a7c993fce98ada15a8bf16137624a2e078fe16060b640155615ed55df21d9bd736df51970f11b06775760116ed1a624588052787f6e95c93cde1c4661c9efafa2d2f217e86dc941263c176bc9e15af02b922e23a1839cb4148f82e8d8888de16e17db10f659112ae0f28cee8c062f34f44304e32fd3713cfbc830699e6aab24aa1c829bd582d39c4262c625c45bcc81b5e07289eec77fdd1613a7e4955aa96ba05c45676e973b609aa6136f5e516e338d183db9523c3e2fa6d\nCT: 829f34b0c9a9dd142c05e45001836bd524075423cd40507819ffc9db5f5149cfd97cb6584c280f936c8fa3c0237673ff858aeab5f678be466c8b0f9356cd48d0a4bf55f5826115100316d5b11dac5cbe21b817f8e5b2587971d4a1f47695f1f917a87fd64356336481b92922244639cb2455c3b", + "d0b338b24727f14c3b68a92ced6a6a58fd2c07aae4b5206f5fe355de532b996e6348d357906ed4736734b62bd27f8e832690b2e63a2fac998b7af27cc98aa64386594eabf12d5989716e8c36169ac8f548433c6cecc114279cef1a62906bb69233a3d74462f4a35528a98651a0325c06c3667ec31f7b66bb9941b843c6faf6ee56a813b03f3bc8775bcaf1efa10cb4ce784c99ea79d49ae57e4a77d7b069f8456b66ddd04a8addfcc441fc3577b5ce2e38eecebe4963e78dd5728e347654403ea249f70817e545528780668c69bd5186cbfa73e9e7cf3813952377f748c6736988a0faf9f06112dad90733847dae8ea272ac49f1290a417f4eb09f6960e0bbd90c098b3d6bd1f49802325e255ad104cd18a90189aa486eedfad8ca999f533ccfc30e63b31809a2f0dd6bacf29e7a4de79813dac86e3b324e7cc89abfe98e91e02a37e3a5d224207958fe4627aa5861cc1d58515e2da73eaa171e29bd436786a8c54c449bf620b0d91a0c001272b5d047a93289e2d6a31ccb14347b019473214c9dc066d867fd3cc9fbec4c1ea887c6e009bbda41f5e888bbb14587c04c406566abe1a7f473f052a17c3604e837d1358255c70098a4993fb0cc25cf89326044f11a7f4e6e320afc5c8ae457425427d5a08\nTAG: ef86f2b8d839c403d817a7a4b73b727e\n\nKEY: 7f603bab7b77e7acaf5f144e9a301a221111ae8a3130b0a77f638dee2e05d4eb\nNONCE: f314fd627004e9a78d133482\nIN: 2040ceb4863196a75e5c5ee70861381d6cdf1363a893db2bdb201357c908284b91d690770205be495f788afec67f205edbcf47b78fdfb6e1ca53dfea501ef7fd48008ab05a58b65ef8e3b25cd3617dbe7482d0e846d04d00508192373abad114b6e5713f84de6928339d5c57e4abe88f0c0f0913324bdcc661fc85f391aaec28772df8faed4069573ab9ce2868039b7971b510e8b9239eeb066ddce13e2fc2579b159b08ca564de01fcc32abf19f388f0a8e810fb4de96e19d02010b75ca55d4d6db6c1a0d83d36a9d30a980f51e8263bbdf18cb768c5d912cb1ee8394763dbc7e9276830eecd1c92541ec53e9fcb5be036e8fc2da7c51e9b7978a7fb8e24182825d8a219167bb925dbf639edf4a25c42ab08a7ac8013696f7e10cf0efb57ce4910758ac0726e0bca5d30bf4d0a231fd12420b9b60c3a690e0ce0106c1bcfc47121253347bde0b02845afe64a46c74a401fea9f81cfa02d47f3c6008be65031e26b07d05253d0fbabed865397284b44ce2c38b2117f90f7d3bc60a0d9b04c6ec4b5108da61ff7f6d30083a33528281bf2b543bbb2eec909bc8706c892844e0702f224cafa9f2070adba7e3942023645427abbef47ffdb9ebf43b24aa7367deb7d05241cc5ffc0d1e07554545ddf0f6bdfad4657222fa561f3f92c83fbdcd5b0b93921842d2545b386eaced2fe37d0e5601bdb969125b006b21a8283d8cb5264ca2d8765d2bfe24fc04f8feac32293d88bf6a3bd7764847c72b07a9c3caadb47b96eea17199713eb48d03a8b37897defce70b258328f0547392e7e82e2a1be53c8e40d58235f610ced56019a0696b77b16ed8bcacde\nAD: 1c142bc3afee168755db6b8d81754dea34e20f6a0e35ed9da60bca3957a054916e0072e3c5329ebbe2bf8f224efe6d501e0105614f72c8e37f2cb7cef644baaf7bf32975cba8e519034427b49bd589d076e3a79b2a9c90170d1e503256389ea444036523d36486bc2d3a94c73afff7bb2b48d0d74b7607c3db43186b9f85102a49d4c0e3cfff1dcf8b5c0cba5ab2f28e1dcbfc858f57f585d5e7d4ee92eec6ebe152e4b160db923cb8d9c154b631e3340b61272e0726cbd88298a4a6dd1d01fabf67d9c66c4681019e13a0e0280e91dbc3cf20e583b4a401dfc57cd3bed42d7e889182a0b75072fb08f1be187b3c7990f9f17bd29d61b8d2bc93f1a78e84fc8c38c4184afac57f3c6915dfefb3e194afa3919fddb1efc685931e49129e3afa230681fa6e7c1d6a69be66d0317d\nCT: 93ebed6f7254c65c204278a9acae0b123dc19d8e226e41511f349961b1939ca83970b9696f31a7fcac5f5e3d4931b0a592ac27fec71b4e5679a56ad1bc3be37d4bdaa50bfdd0d00545d4b77e757ce7a0c8abfedc9585199ecab1226763a81f9a8c6853462c483f29798a9b28073a57689c5514e356f9fdc3f7bf8ee0688e8cb781af3a365ba940f7ed36ca68f6622fc6b6310a4dd7f8587853f58ef485c82359840e2784460109b4921e4b7ab014b28571938e18b4525bb4d5de35e77cf44573b167883feb3c730945e9ab71a2b755cc315ba99ab96f8d4a8f46589f2e8906b269519da3a2dad2a7075629c82096f028ba47c33e264f55b8898ac5681d396b8e6d23616c1f8db24ece718c2938f88c82da1fa940ecfb402fb300041f9d30e5d47e2d74a4d9822d35aeb6223a4457d621286444f732bed704d529df95627e153246e0688fa97399d96033a06091e77db420c8007ccc33386c28fb76a697dd99ffab76705a7f55797357e563cb607e531938380dfa64800391f06e5cfdd3dad5f91eb7f2138d54cefe9edc0dd3f4d674f5f5aa315f0e1b7922a37821c6cabcc9d81fd002d159d73b0598ddd21b66d3db416b789a40fe886027f1a13d802e54a6bcf691ab029560b67307ecd373f2f9ef2ea2c334fef7d25799088106bbee9fe2b88d06bb23ed0510284c5e1289c1b65a27e4f0fe33f18a0065411ea9e09e65b589a2372f37d0f8f4e07d95f6e8f30fa882726d29f41782b3d5abbd4a9f2dc62419c684a4c8aa92c4adc71c4db805c29b0e561760ea3deadb7d41e7a07a67fed68b8a0f4460e5535e9e0b9f7a754d6f2398fcf399a277\nTAG: 7ec06820957f6a0e0f4a8f7ae0be696b\n\nKEY: 0497a937c827b1591931dd17e83207cdbd56f1ec1270b14d9a7b1e2bed3e1062\nNONCE: 86300bfdb282f9e2db0a43c1\nIN: 8132b08093892211a8f7b210bcf36120851314cbd8a56f80f26dbfdcdf944fca9148c1d013844e897b034843fc0c8701120062102ae6a00aab0063a1651e0aa36aaf8acbc221ee7575748562288c08050a9a562ec43be7fb3e54dae418ae89476a1d5f81debb13eb6c5e0b4796abc8310e70a5e4a6619923dd6230a7b2a8dd36fbe3a29aff8a2ef35820ca68b07e00f63623db10a648014028d314e01cb537973d03420938dac988e7af001d571fdd7b1606a06430b5fa1770b2f30f53cb439a02771140e44356c3bdb7ebd5e7af10c344396bb3bacd58d32f07a26768afa741a2dae4e91cd8dec01505edf362f38b0fb06c40b8441746a8ec31d9aca6437d1b75b5afa120856e3d87d79ea5b71352edfb56a873d206e8fdc5d5f0bcf91c0ef1beb06718006bceb35f71dc0b7b9f65509a00841930c4087093c0e04945003751c40e59eeb10f62ec33f7a6d16717804519e930bccfce78c316cb720e109a75b30e11415fc5b398b76cebcdd758535798465a8662486745b6ee098f9008d0cccbf8ce2066b12ceed80cfac806178068d2ccdc00ab32d73faac0cba72b5ae75150c13dd0c16d85332d934e56c8f96bfa942fec689e9847283a307ab775ae09cdcdf1c0635f749186868537dcf0123baa295e29601052297aa4b3fbf16b31620aeacc12d08345df8d879343c098372a04d32fcd2470f4bdb3aeeac7afcdd8f95695796c64cd41bb0052905c8b95edbd0bca3e9115f119d29e109198e91b9a024c8a4d67ee864b71eab16d4545862403bdd0720346c43e94793b1ad3f02946989c6e30c978e4c62660c4b1120bd49017203c86f5b9f02bea17a249d6396e390df1abcb508388c735\nAD: 565ae471a3d24293cc33aeb1cfb05025fd4f17b9382a391d73a2611784358a9a003c1ba16f493f020b1f1545555ca165c00e3bb4a2b855d99a91d4f95534424d3b8b32ba66fbf3de63694b18efb4e0aa62e438eb3a7f50b0551ccb19eba8b63e19bef0e6468ea84b2fa62d0deb181e8c3b00a55198eb69ab7eee2352989013fbadbb26d1c1f5033b26f1ea886a0d1af6c76a78cd09a8b1f247d6f81d7d4e521f6649de7fa5b32b45be2cd803a1adc6fa89eea3a9d876ed1df0534890c9b41627556103964aba36e277d1cbe56bc14458e75c365a58646b7e498325bbe815e645a19bb33d2765a36a61e74eefc32ee9fef4162eb77574638dea2cbb9753e50b85eef07284ff84996a5969af62090ea20c6af307c1b2e56486f50c13d5c4087ed471dc737c4e40b7bdbe9d74ecbd6c8dd0892449496d0c\nCT: 84cdf98efa641c2c008e2b2f6a8b59e20e95aab15c276a21569a1ccf8b7494b6c9585220620944517f167e38db24bce3c81fba1743bc6a51abe0ba858d763420ddb06a9a36eb417fdbce903c9528f1db76a70f73e50e22154e8807aff8e05fe6d3d28e3f09135486b33e59ef353e30a294be4870a79664d86ea84dc581ae58ba8aa6355ac8289855e7aca0940669cf5e7b00eeb5a5e9c7ca1dd483c6664def93e76244636eec70296965eca0f6c34f1d9923295e343ff9affdfd51492066cc4d5d762db2864db889441dfaf9c2354acd97c823071098b8b9da9b2a91ea98d6391e40ee4e13b7c5773ad7124c1dc22d4e2dd6142eb665be2e936a20edcba8badec6081a07e54649ed2c371a7f22d4898fcf8cd9916c7033925908c2a03c02000a456ce2beec2b2f94c0f92b9a7885c9231886993600e734948b34fa025b733ccef10a8b66d52dc53b850d2632e1d1573256430661d1aa716fb32dc525e80c96afc19808449391dad1165de6668f9743ae1da522c9a953374fdfe214329c00cf359b40bf9f3edc4144da66e3eb9ded0885a1d3b441cdea692ce0e324686e7b2128bb28f6e4256b4ca1463f93f67743a53509deee18be4f9f0604c3491559612b4052370e4fca33482aa0d2370baad1b7e64a1e6088ba87fda91c83f274ef9501385a96b4df53d0ade464abbc8022498f9df1b2608e42b1905d1dc08c3e4bbc7e3b830145a8ea9d7bbf64cec752ea11195947b587cb5abc811307a66b24df8c95756ca4ec7e7bdce47679a2327f08b94849a7760c702ce07072ad7621e0bbb0fb78e3f6a7739de57c29d49057a7ffece9c013384df796ac954f61590c472eebc27a7adfcebe3ffe\nTAG: 18d8a0469f1ba110dbf77ecae36e63c0\n\nKEY: ba16e97c864307a55f341121b5e35c47530a9c3059db7000688bb568f4a87be8\nNONCE: eb8ff97b4f599c829e412edf\nIN: ae60ec1dc53e15d608021b6afa827f48869b9c9ca017a394d10f814c3172b38ff27ffce750085c288e257b6a2d7ffbbcce9e7acfb12cfcb630c84448329483739be37ecc1ad122603a4f286a48474134550b12ed8dfff73419494a8d251a98fdcf7c329b0e31b0f9379faa6bba2e4adbd429b199b7cc31d2805250082a88f94d3a120a3b07d0229d4a49e45f2729885e55cbb9ae08c88b65576fcb8a96ef23b629422ddbe7497fc2d4baf812bd03a7d5c03e79cf522938337ebd1c9cf3a61d331aba6b436c21ef47b030447e839b94b23e6ab10ac09a1243081544081a09cf35f6c7da3149fe3c8e41f90da05d88e31b32744214ac3a8a0a9098b11a38abbf01da170d3115fd4243f2be6eb8295b921e687755d0baa3fdddc1fd9e8d78992f08c50ea9caef49989872bf00b7f86c78293896dbe25effb4cba7822382ec3aa42a95221eda5980c488bf7ad0031e1ed987096819cd01ddbd03500b348a15fda2f9cb9a870df388e2e7f84386fa33fffd5287f", + "1cb795fcce3a24fe371ce42f2f34dd8db9d1826b6a454082ecd0dc684bdf35d3d7e7a9606cb5336c67238509f0386275d58cc3ce7fc98fd20c77ecd1bdd463ee40e612cc5b9082f3c12b83f16c32072834a64552549289ca767acb23c61b4030227277e0df6ee9acebddb0c3bd538040398ae57767c850066b40ac0c1d7f5de22747051d237f898306beee05273a99b20165c2d7267f65b5451605ad4301a82bc80268b49e3084957d8ea8fab59a6b31f47f76405f5575df8a16a5811a976a84ec23479daf4d1d2c1ef428a9ed39faeb5a625ecd25e04d37736230cf144eeab686180cc71aa713d522c9f2007aae4eab486171ab3a9c338265193d093fecd6feb1cc1d91d10\nAD: a5f2dca9243d12747b5fd3ed809c06f52872136814aed50d61ac932fdfcac2e9ceef817034647b2f4d61f5a0bde8ef9bef2789a49da799ad1b9bba440a29e3e15e4d97b99c0fa2abcf5cf0e05acc89da732eb79585cf1d6c11a6c65c2087f902ce230208b5f1ce6cde34711646b9db725858cecd3716906853acb06c30c7dcc3901eb407efe6c3a8e1e9f9aebfb1d7217cfc6571fdc4b86d17d66d6e392ebf03be924c0076b8d1f8bff15e192cc5e351351fdb6b26364d883581c3f8e769e9a5689d0ab2f308a1dc47d7032de91124b1ca3d42aa3a8d57ed92a97a2aedba2409b38023c55954d4d5d2630c4dcd5ac7277fabc3408f0265560d3de4114eeb0b10db4d5270725f4454dcb1c7fcc1e36013a155b03181e1a315aaa251e9ab00dfca8e9ef787799a23529fbe8f0f993dbc2338b9f300ed18a67bf92c600f22d803\nCT: 5d0cafef15ec06bb165c248fe447bfbdb89207ec1331c65a5d88d419576ad9d423d20d660c95b48bc437fe243a6f860f260894e0230b702af0aaa4260746008ad679676a92003a10ccc12654251de9d2cb09f7294c2fe8c2f4764efbe3984e7265abcffc2cb3e30c5611c3f9eaba13e847fd73fb3aef12c8512b44283935c51d48032865bd6efba3ee4e1f07dea2e26022958f6a966fc4059c81fbec916bf4486429f55732fe3e927bd4109a8bc9ecb820d2c137790b0e296df28f2701ef5cba2c5ef0c7732849c75f59f81460333255f139fcbb30376c21ca317db1f849f79b1826c8f3cc0852e00b0dfb94bf3601afa09c27c130b5088c05619dacf00f36e7c01a9f4a2f24d8be1ae778fef1d367b04313f8cec89c708a57bb332b63e60d15d5b4abb2d5b0bd0dca886e0014051053a5e946750be4a9553549d9102b0d8c08bf9f850a6e06aee7030536ecfba48aa577c7d3614056d790c9130544c172bb4cb386fd3988f149cd77ee8275b0fe434e589b64c13885e9ef4047627dc192a6ad646ac6d62f482eca0183d23f65a29937e9e53a1235f66436897da1213607cd850c32cda9828010e6fc3a93f5f9c709ff259921ce890435b6454c046fb01c76513cc99f66a5c2da8f16525b68e3cc66cd6a7674e674bb0cd8487953ea9048a170ac8e81b616e78d0b8460b729d885f4716b741c04e6236d2171017a5d433754aedba3aa7a39675402337db7081f45ea37374a8f86ce8898ea837583a300c0f74c6292d37e7c6d19c190394dbe777e454c344d7e16bc51c0d93465f05327ff29303d80177b9098b4a4d809fcb103a8c199e3e8f827b237408a242a80ab388d29ea12ee8a0fc313367ad213f7e696f90331c7ab9a5730cfa1\nTAG: 359febfe67037a485d7ccaa4f1b6286e\n\nKEY: 9a5b03db114ff04aef285642be0d552cca24b615bc1467ccf9818929c06e9659\nNONCE: 9fe335e06fff534915999ba3\nIN: c3e7ee9f964ff4c3774c1c63ceddf8674c9c43cd4874f34e22c5912e6f8eac3e889779e7b4ecb2af711665489274c3201a68d8bfe7c61e6e8134aa08d71ac2a23289eea43d1dee5b4fc4caa3cfb666d59b09c554bd924b6522cfaed157519de12d9bfa37b55fe8158d763e3c79b7b10db45bdae4ba18af925bc8528fc19e9af54ac81588682299cf0997eb9710fcc3597564d8f0b71e3249089673b3771ca110a28c1aad49f32301e0921286fe0cfdaed8f64956a4e2c0b22011bbeef46ecc6bfc29ce023b361b2db0488a2cdab32bb94024e757abccebcfa0a672acd77f9ba622a665314c4b520746ba4fa07488e9dc662f755311535f1f98558dfb2be88a86119850c49d4a0bc92e70994ab5d7f410ad20d61fdc93a08e460ff9628a5b242038a1d2905137d4729fa77ac0f74bf1d32fa7b025cc16f8004233eba54fe7537d0127b1a062526d33fed44fbd3475daf5c046123befcb6ee574ffb9620fec7644a10643908a2d3e283864e3011704c4b16dab7c5333545c60ec83b0f7c3e2dc8022ee5d1b8124f766bbd8fc95ae1a5bbbd2ba7eb5c41780627553b8ad99643d8abd43c56a32bc159ab97f1fa4622cba34b283317cabf0bc98931980f207efcfe6d4c4312cd9daff8d46b1f9eca45e0af42bb8b8ab25a9fe0caf1c61b40b1a8a3b35680abf456de109f42d87ef277ca178b4471936748f3232f9075b58c64c89614dde8a75dea86d3b9c2a6c4a71ccebf388becb7a2cbedd92b4ef95d2b72357b4d2ec099a3ff9fa9ebdfd1d9adff3329b0a4ab854f84e8c729538b0e65773a116a3e50685c96e52162e1b98367114d84e5476291fea3173ac3a846529d5af6ddd0d2272b54f534d4430179ce5bee98c3a9d3f6e9cd4d7cef5c79560674ed0b5418e21e9cf7ced787a\nAD: 9db3427d6153ed69d84ee4ca06c515d3822c6338868dbd97d0a21406275c003f493475d4350660a4f3afe49deacd9f299fc05aeab4029f57d05e21cff132cabf6de6ccb3082e0d8811dbe5188749a2ec8ad6b1c1efffc4031605c407e0c2ce57478b37a4834bff670b4dcfe8a32e6d09a0c80c7c99f7cc41378efdc0231901c7643bc8e0575040d1ac1bf4a79ba4c10bae1c0135ec4469bc8b6413a068ff97e88c4be959f8e426abf3cafa2bef9925aec0c1ee69eb60c7427dbf79656fb3846ae4ff059852e7686311b2778d06b5a7eab71ef92bd086ab0de7dc2a3d4c6070436991a68d81ef5b1c6eb024ccc6b2668c98e9b2ce452ab4751dbd57c2794798f5d9262e2df48788d92045b23a455a135c112e3baf06f2938a485f874a7d5a251770160dd9bf9c93c4e2a789edd07b8a7a4262adb303ff6ce9c551be29dc69f99d\nCT: 28c9024090abbe09b35c4e289dc1b9574ff5172edb28f34e9133539dc98b4557168bcedb11a94c1ea84eb4b803661e405eb007c17cec80afb3121f27f185a197b4ea3f0ba231e538ae3c312e2522218ca2a73402ea7cffd3c1413c0ca2206caa91722cb048e1ec15e63f6c55e563dfcb4c3404a9c380608da0e903bf8037ee1d740275d568a2a3f9ee232d88950b233287b2bdcbace62efd1425c43efbaa8d12f66852cb5f1b665e7f4cb6fb5e3746cd5e8d612bbda8c031fe5ed7f4f3b5741b2aff9bdb150f637fece13ea1f2f5d32718560a49c841f3923d993b1f5f65715aae6b651e7d8f75ff34a9d1737b9e3f9a0375861458faba779ef9f4b72ebf42097e1e0fab5b925fe85f54d40f940f7ace96125273da94c9e394fa9a80680f6567207ee40ffabc8c152bc6956dadba45eff644213178a7a24882ab59ccfec9fc525ea9e37064ff5566e9ef2c56a9d634f59cfbb0b593d3fb19262436b68f57029d83205ed6c466885d7ce9a33046bda7dad9e2ca92691b3d5f1e48348b17aecc311479c4b147f4d61ac14640006a7c0d83b45372073752f9abdb5d1908dc3ec05f85e70324088e360003dc774bb68347c2acd4322fc1733d36e68cadfa95030dfcb9f73165786a30a7e841717ed8b20bcce47ac9b4900fb6d35c917b291a9b5dfc4ec2679846447a1dd140f48699b792a2969384c7e8914522286765a3013e229d3f3e30b130efd498a1cb56cdd493a5fc8bd9726a8784956ee379f907cf2280745379784bf1f177318cac159ce656c4321eac7ae00adea35e209b38c0ce622a1d4451a2dc6e0c3d2679543cdbed19310976d0748db13e341c396089d977546e956c96199828a8cb72ace556a2ece3edd3efec2493a13d61701a1bd525841933e8398ddbe16cd96a2c\nTAG: a1cefe9bdf19616e49e6dae07c8a73fa\n\nKEY: c75a4cdd53afbef565031529cbce2ebbc5f98b71315ea7dcdea17c88e7c8b3c2\nNONCE: 0da68ee6ee4e0126b67d2a31\nIN: e1755e532178b048b572f806ab4bfb398247b393dff9c653a452a5ff88cec05ba1ee8ebf23e91b61b1f9adaaf771f448a57f4572d460b8304f8a2d6ba8a8b89e55d13e474233cc8da704c244c6862adba31219d994f302ac7161604d324100241fe6762ac262a5f7b5a07c67cf3f647d2d60846ade2dd33f886ebb59c50d95a4a0ae103438a65bc192d03f351e3e56b6da169480def2db510c83b6ca91534683cf334134afb2491026f7aa45978aa38b38d6a8d193e9609d3d0b3526a14f7b131f9371f56818247ce4fc6e1b17ec6e99b67123e7e34faaa8a8c63c1fb9004604e5ddb32702f9be2246ed7496dd27fa90ba90d90575c0cc45c0b9fcc945f21bfefbfbc82c53dba1feac88db291f74b6512d45cd7a4c5c886a458947f0a30ee04a6866ff5472f6c921d1949b8ddfd623f744bbe5f47950dc0c7c213545f7ab63e88124f79000afa6ad2a10b0dbfa4f34e475420437dd10d487f42d2cc40041af9ef3a4f52f80c9cb25970a4a4af8bc7dbd8fa566fa588d57bcb446b399336fe43ebac2a913d74d0a9f7d97044213390372d4272317fa41a62c50bc2b4d736a759c85124562323d86f1de14fbc3899472a0686a5dae4a3e429efb05681a1d7a36d397741270b2d97aefcc3d90309365a64a0e244d62a4fd3f288f706fb60557d9ba2bc8e29b4d68a299f13ee93d3c4ce0efb7fb26a3d2f828c1268a04d48e5ed520c5334ccad9df4799cb58ebe15284a41aec4c2b9157bd2851f968a279653b3c9a522df5e2752f75a3819d4610ceb4da666d19b347f09dde571ccf14b435569b9624d3f3207ba49b05f40bd818c7ffa733103f9210cb821ae8ce1fd5bb80a6d3d8dba865015b52ad9af765a8190713d13890440ef64474b61a840618759160c4c692b5bfae7cab08f941d633a22b92d8be39a614903ce0f96d05\nAD: e83596b9ab4cbfae18e4e8bf4ed0cc481ac402f27fc81a0b62b7843ed4387f2e994799e0c9532a1187fa6706d3179cd8e3bbde209f85836a176e43caa2dae384f0331092292872474d24fcdbe72be3067f542e7b099d31a0b09e0f2c31bd16caad1fe1af0f25845084268431b930685f6a16fab6a401a80590895a3422b94d056038935b1182ca3e6f4ededc86813d651efb0fa80e40700a0ceb602f3a67784b60b8d5c8522e42519c83e6f788d8133044061095806506cbd0bf3a7fb94e1d59435d3a5cd9a5a24db98f20035f0feed9b12b6cb4cc3e18c97aa890d61acfa167338b1cf79868f2a14711fcc241290709e800babf3ba7a868a528d44be867cca23f4f80b1f914ebc6abd630b4254c1b8e01241fcd817171e2d9969d2ba7c3f410a9d5b157ae0069b97ba1c973d944f11208777cdab373131ab5ebaa1304e394770c1d277913c54e7cf0\nCT: 2a59d868291bda6113708e551c89d1d4fd3fbc81017975fc0b99d8dcffd757f19fa4acd4acd47c90100e27eb228ee59ff1910911f8129b8a2cdc59ec38b73cd096271e55fd097329768d102f4398c4f70c52d7b15fcd66a94d0e910a5b6b8bdbb857592ee42871055be1b957013695288e5", + "2ad934c6f802677aa89c08654fd932039417bdbe062a5242d5d38b79ac834c7e7fc920bc3981dfb780c9f10f5f761a49a3b95693ee764a97d4de73077838b5ee04ac09e10c72669f7c151446497c9e2c3153938efcc62feeb9b82e605b4bd76ad97b7401ada9bad71718539d47e6edd058c23b5c4f3bdf69d74ee58b7d1c94ef660e4e6b1d43b97cf9e8d191178160bdf0e4fb6db2e9aaa2563322e4413f3b5d57d0f1082d160ae2bb2d3cf6ac17d75f73ca1c80365648a394edcf62f520d2bb648d7c963b1d7deb6eece9583ebd2b2bc2cccc5415c774d9f25c00d221e1f0c2829e288721a9e416df098392f67643d52a9fb0f2f47ca97664aacfa837105e5da4b86774223bbd238a060648f689c59aea623cc688c1aecdffb13d9471fa07352ec02ffaddf080733f07d10ba61eaaa9f8e0d89b6144af9d4a0094bf9fbdfa6b35e9f342a7140ee4c931ffc0126eb8b4cf6e227fc6bfe386e81a32593acafc6d44925f1cf21924720972729e2e9daae0e74f55045d17c25c4c3b8454f912a0f6f6ffd43119ec4f3046d921d20f24662d25d0aa34d95c3a5aeff05ef1a8905ffcdb1b9e55ea22e59a3f5d60106db64b998f0e9683a16c5d82c53b424220690794bdedef384d91bc9a58563fadac76b50e80b64dbf695a38540a9167cf025ee64d28e26fb3dc7e9f33979b33eb887e55d996741d9569642769ddf6332e369674296d510181023a1a3e4ea7327af5838048458ac90a71732fe29e2edc9c477fb6d8827ab4f83ef8626\nTAG: ddeec4a2536869f8f89ac38951bba13d\n\nKEY: 0c13e877fa5e8e0572f237b646f783db2f30274ba46c51d72d751c3bd4ef9ea3\nNONCE: 2b0a22b260ad3ffa73ff1c5c\nIN: 481d15ea2246b6da59e6271801edcbe277591b188386946abead76ac40d6f2f08a26129895e97ef25b59ac345f8d060d4d21819d78402279238541534d8734ca66427ecc2baa6741fd093a5895446979e30ca15eda06addb67bec10cf809081ce8a70af92b03f72536a8a11a1e9e3d257352cc284f41e2fc4a91d1bd1774512e09bdd150d1830be260ea418fd384be30f9da23fafdc2c0b5c632ea7fc7a6ea87d69139e9d104d634530a02c4ddae3a2e6854118369e5304202206c4d8fc963a61bb4f42ba6f937ce8281429db4103ef222c3a015f08fef15eb5b407b56165260dcdad08f1196e3d698ac5b7ddd403c28593329db77fad8ab7aacc450636a4f7f6714bbc6dbe10c421d151a7c135926c5388a56d2b66ffeae0508706ee55899aeceb3525367234e29c25dd5bb8b187ca4dd14f68ad317ee5ab3027b68b5b405880528bd35eda7f9c65eef9b375dacb5173b30a28c99e00eb11181879cbf1fb59bee4e3964b300ce57b597b958c63a056758714d69c241da18b480acab2bddaf692f4a57abf2265a0fb09b3352eceb6b26a667668363a615b5d078a4962c48658e3c92e43ca83dd0f71ada43a48d52b793a48e17b66097d06f9e3804202e3a8e832409d45f8b33762edb9982e79948fcbf7213118121cdfe834931feb8d6d5e3a677e3c35d6bdd1a0a51c9c0141dab8dc0ca83c7606f7a31084b9a9a985da6b93e23b215fe4373e597574357435cf7aae309c11ddef6b0f24437df2149ec8e8861e3546f2a950f900d74a8d736a96ca82b35bdf9548d6eb6c6235ec2d98ff0f196fd389234bb44de0a2718302a3c7110ffbad0451f4dce3eb2a189f63d52683509003cd6e0574b94c3db904f9b3113eb44725a5aae93aaf299d05b8aa942bb635cf5e68107a3277b8a70534e90976275809428e77e5163c18edb02334d739095da33d32502fc5b12c6b14a\nAD: cd316404d7c70f81cd5a035472154e92e8a8831a22c5b34ff4b40e2648df0e6b411ec8bbdd985da9992e3df5d1ebf2b912a1b250fd08553322b7f894cfde69cc37bc794b7de6b5136afb01f8377e0b293b57a50eca913320a0eb324a6009d41dfee2a416e6b9be33b55a2e85d59a88dac4d587e95e7352f004637bb3a798dda6d3a7164597a73e13819dd2be988c698bc7eafe6d7d32dd416e2cb252e21a7eb26ac4baea46a5ceb7b19db842b20d5998c5bc4b78836d0c6dcbf3ac8e2399b82d097232c553b837774960fade6bec8d0f452ba20bf72916117045596f4b83422b026c6b187c16e560ecb2d5dba5b6b0d7709c7b8e8b4d199d19fa0bbff8319dca9b308a836d0c1eb0c6f2a14c13c820d3b7213104491e6df75a1e61621a5c7be94f388afb47d7c5c211621fbabedda16ea22c837903b1088e6cc8751dece86bd749ea66126c1139d98d489dbdb93e6d8ae906\nCT: a56a09a3c7cac593f40fd3af345c1c84d29a7905a05087553640f0727283d1fd270773b6af7537bea2eae40f603567132c199e7f74b7eb98f1d7e73a7b6474d1b0b0eec43dbc33ef6e17e07afbb94848fb78d53729f358c2eefaeae4b92724fe0d6fe97075644ad5b12d1ed93f8c07aeabe373b5bca66b52117018955edf01c238a937c4d5e7993fda05799533a5a15889637628e158604a99b2a21b24dfc2af7ec0013390e6e7259b7ac92f232bdd375fa99a4f6c45f54ab231f6d60fc36809efd3d213813be1f3e1b91ff3091469590f6cc439ff359b0706ec0d0667f58c34ba549e9727d9045adffd0481fdd13c4069160eb871afb2d408e4dfcf6b70a7c2e21e4e54f44b2daa3676ee998515dfc4c8518288b46d92ea835d5e9a0c8c391020aa6efb8b30a580601178e486957918ed9f11fbd2021ed7830c3019c935ce19dfbe95c525c8498803eed097d565b94d047112d494518f7af094705f3fb83b22d9064450701ddbd8cfb209a4c68fbc1667099e605b7cf853d5a78b92df4f6194a7644017434f2658a7529941d3cf71865f8e29238709b373e68fe1e800ee858d8286d80acf4f1d8cdc2668f40338f48dcf5774e5da72644bd9513018688509c444f821c0c648802cefc572c6821005db0fdba6f4eed0f122ac57a213750632ad2eee0018f9f240f2bcd1cdc03d4c8a6585d955dcee93cab5d7041148385a77533a41eb9eb55d7be87432e5508e798aa4e4fd4a06e83bfe355cc698bd16f9b5ebfd17145edb7bfb3c57a0faff18df6075d98ce7a53eb4de7563768e3257ac225de47b8a52ad65699f8c7efa64676a268f9dc97c46bb23dbb335e79be532e0419583e0f8753a38d2de790a3160d0fd63ad5840601a78057708655cde8dfb08060cc0f233688227eeb4a0f20d5e9d58bd858ca3e338ab402011ad975503cd5c86ba3f12a05a26f0b0f79c9a\nTAG: ca40f0179157bae889d49b5697a0e26e\n\nKEY: 1ab6dffc716e27c3dec83e2bc2dce5192f3fcd3fc5f3b394885164f501afe5fd\nNONCE: 42bdf685c73f9c31abdf1d28\nIN: 419a911203ca879905ce7d0edf1c29f3874d02cf2b799163c9204149b96a19f7c0eecd64b6ba2bb686eb1d6f79e420d130fce85edc6bd6b07257427a9107bda792de711025d05962dca533c52a2a379ab8516010107bc7879bdb2447973f6d356cd3905e253023a863a3175f65e1988b3f8b92af2ee9b5717d87705649127dfc9c7388c9ddfff5e0dd7564fa76f9b3272000ab7722becf46c1c2d99a51db96dd32fc5fcadd683fb4f7d57eceaf332910e8d275c5f955f27e899eba77b87784968e889dfffd77367c3a4c2711a87e1aa5dce4025ec7aa3908b96cc5fe05de319ba6de6d57b170561b32d0fe4217b0739393fe730f4f62058fd3f950bc5ef151732e06fb92987302c684557befbfca5d15b72a22dc0a3a16bc128698a6fef64511d7945cb1ec973d66e81e2f6481316640afb0344d605cde7280e9e6107131d1b2fdcdb93c29673d0822b8fd1ae0f22fdd17b6f654a65187b8cd45737c8446b21301be1d5d02ca6af5432cffee125756ae7bbe2993033150f6ef19022bc5bd11c9ff9ac8ca8b17c594151ecb5ddadf8465c73969c432f4c273596d9cf7c53187932d3be41a145fbd6485ceb80b196079d89e3b5528c61946ba503844ce538a1892e62457abf4b6f90efde91d1747fb5bca839149814f757d418b9787822c76ad2ec6e5c84a07b0d7eab9f918b71e075cceab5d6ae5dccf54d4a15db9e415e44963c8ba68101df5894fc1664844c7ec11c300ae11cccb4ecee60431e36a2c4516db234378579638b758f10d80ed372da218123449a66aeafbb41bb8ff6564cbbc9c9f734daa1a9e409fa89decdd619ec8d1fa5918d3ffa0c780c0521eb514b2f23a4e95704f6a22657e7203bd1cc15332340414d02f7265023e0c9906147240d0495739bd33f7dee280e2cf905a706dcc838bc2fcea7e4afd823ae2dd3e2a98ff55f3ccc2b0f789e4d5019b93f213722ffe27aa583f6b9f77cabc4ee5\nAD: 358324f765547daecb7e2d4b371e1f77debc01b18be41313387181537b360f1090bcd9647ac7694907ca521f84f7865c3c82388c6aa80627ca9e4de08a163391b228be2a642df333374ec7182604bb80770f4a839aad778dceda56764f5888a95e88afbea46cd9eb4f506882cda4407461b1ea2f31a88bc7529fa923ed9387ff03dfaec545dd796243b7578640e0b8025aea75ce1b9ba918ab04572ef65463699d32125f71966242fbab007730e7f490338c60ed9ddefa539cc88d39b254e300b56da3c832065a35d961f74982fc895021fbee01e03e9534e54686376d8f9061cd4d033491b081f15639cb2056047d79f0dd7447c899b2aefc7d6bd03e57a1d7cd996fa282ad7493201920130df3007d13782f197b26ae0cf7d62cbc642d10b4202e1887b43faa4b71694b05d19daab60cf37b6a9b50c7d32b04138efc84414e87f6caca8626c2f764a945a26fca57907486c0db54ba1d898e2bea\nCT: 2422ea9d13895921401f84f25a5b011eccf2670b1f12985d4e2c4106829a7ec3c7c75f11e348829a8285b34c745d8892bd1efd02c27a6764311962302524f787866520a562ffc9f0a644c242107a7ff868e20ee2f2da9d41e2e85ef00815e6dc2f242a2fe8986d40e37a59f53c88a168d230745a57714c3e313f8be3f4b780c61c0638c3637add213b1cfd5d07255116d9fe58dad2941f8bd7aa7c37ff7a041419e02b8575b46be6dcb23bd5594c713c93f8415e5da427dccb6f3b6d649ebde09f4f627beff5647bcceb10413f0a58f04d3a03d3a59b4d9f578508a21bdb609a7291bd8863e091907f83eba365e5df61991836fbc8df69fb7d6ecc15c85c8dcf99f771b19c995ea85578ff39ad5e1eeca002dcf843f471198d1d4359845944fdcbeedefd158ba9dfc2045910a911905579a35a4d7749361b8197fd69ee1c988cb7c1a6f5a5db2e926b4b2a0cc8c5a6c01fe1d04ece3bd7d2707c00e001aa097e6fea51bf87654f389fa4caebebd513527c186125fdebb3672316b57d12be3619e125d642719ac96ca97dfb7d2380800e48d8fc29b4e50c81e6238ffed2a3e788182cb6ac51023c587a66b3617734d18f6c2e4c959b84f04609eb81eec83ce7f8589683682c683762355f9a8c72d1423d67da7b654c00fadac8fd2dc4ba22017228acb6b287101719726d0b1d97e9ca2fa67235e768732756cf2662a078c5ca753275d1261011127ba47265e7565422a9da627085f40fe22b680286408004ee5db318b0869f8f8ead0e3d1b4a564e250b6ce61304bdaddd2686041c505b91a8e3dfe411e932549ee9956adabba04add4808a2ebbf0ed92394fbb00c1466ab06f964a325a877bccbc47e0d2ab4e24243164ab4166aee41b9222b8b42ce81668ae8d", + "1ee8ca5a0c2698616183cd4c025b6210a33aa7b72dff37ec40f749fdc0e879a5135967f47ac95bb65c411f0306335afe6d7a2247823decb050578\nTAG: c867f21b1b4c62500ab27499d11eff4a\n\nKEY: 16e6d8c1f25bae57962529532ce48be6c1cdf0451deb047a1d27faa680f97214\nNONCE: 8e9a0bc6c897d4fdc82bf439\nIN: bae425cbebcf21c29c3cdfccd82245ccfae0524e2dc0b7164682891c85c9d6814c80fce1a63d588928b38dcc987d9df32f2a42ae4a1f9e8ac6bcf285bb08d164afef3ebfe6b299332f207409d271460847e9279d2f0b5c4638cdd989f868b4f0dab1f324e9b18c35e3bc5f798962b7d4f3b6bed6fc1c57055c489032a600951f8d06c14f5ce852d29be001592ff5c3678c0bd8251c883b333d5c670e52072fd68fd8d53e1a2f48dfd2880394541f4df82a9b6adf525c527550161e0d7dcd5d0bafaa4abdf1cc7ae189ada0a61890831eca952cd6e505d4df44650ed533591fc72a9cda1fdb1c4be99a31ac10d8f011ebbcbd8d83caf5d8c33a659d032d4e454ef069b2dd414fe19706681f83a479078f01d6330e2f57c2a3720e5caf67e44ffdbe461d967060e29f11d4661f23b27e90d521c1a9f4f03413ffe794cd9e39dc4c81f43d38778fac476585975b72e26dec8658f9cf6e4e028bc87c8d5d1fe47bd3ad3ff84d1442224006550f6006be543f7712c5edceaaeb3360ac7ae2e3618e093a797223283e0b9c36a841308146c122e3df15a43417bec5dc4224a10ab962fb11c53e3331f0a9967c008541bfd7d1beeed4b80c2371d5ab62cd098fcbed6f96f01fe9cb9f9f7b039bb010551e504252d0752afacdec2f2984d4ceaff99dfef99d57b4d4b1fa969a4e70aa0d868993474f7d4bdea01b9178feea95ce30c0f6b78f22c70da57d26677549e9284bb4a6717596c2c3b1a513ee888915b910c93cf1d94aa4013e891e1da11c41254af3c76a1f63d67f74a07f3176744f7e558f03a3525b4a385fc64e6ae48e5d96779d64b5f557ff453fd44cbe46a2ad96fb2f79ee6720e08bc8e463abe2a9f662540b5105e1252917d7ff63011106cb7a47829c86d374aba8536d1bdac2250045e098987f185ac00faa0b81630d94a41ac935088bd5829e46ea17bd0e19001fbd25208fb312b86349a9c60540dc2b5091c3b0902eda0254b9e8a447d4983ce8e1\nAD: f58832d2e9591c5b15a96f1fdbe23b608ca5ef909a656877d36f16ce276e38744ef11768030b479a4b2bec453dcdce933c78e3d4e7bd7e7a906eb74bf321fa75f307861ddc1be310289dedc87a8e325a3e4c6dceb1bdc6a02d1df4598f343ae8a06729502f5abe458be2325ff985b3cea0a166ab7530a560d1971c57c566197b5e004d9d38d831abec067235c0d2ead91b9319d6ed20e6bced57d71dd2dea6a2ec22efd29b146bd31617c9c08cbd26e9dd53e045d6f29a7dce57c61b3a5f6410dfea52c30baedd587cc15993be3ca8e125f61272150a02138c8c3b46922be9ae2d31ab7f25526b86cc0c73cdc400b5506dcd94bb783a97f39d37db162519549e642f9f087c3f41c8234fe01dc1cc8fb0ab3099fe2b8efc1017049d79b5b6ab9f57ba86d2ef73e2c694c180d2860766a4010d76407b15afe28a3866e48b6b688228d2f1fdbbfdfac9de426186e9f7121d1a98b11caa6193f9445939403cc960f2df0ce5d7\nCT: c43a2c260b2421b4f4d0016112a6a90d09f5505f982a66355ba55284f15e24734afdf58bffda6878ed052c5c97c01ef9214e19057b87db04ecb9e8a72dcdd04e6c8194283edbdec0b3182f73a009b5b7ee42edaf82d827bbd49b21f9b33b013fa934d710d38d156f35491004a9f29b7fb11fa60be85179d970a95f6a4321c2250d3300186c186adbc9151f94a916531107237c9f51f1ca4a16067111b3357d26c9caee90656bfd4317c2d52e97b87f7adccd296a295b45a173780db1011d3dc010b8b951a14e0057451cde7984a62b3e29dada4cba1cd5bbdb32acdfdd6160fd41ae42c40a3f294057ba27737f815592ee1ca89a57db35ada5077be4ce805555bfe57293552296a15a9be89473af043f193217ca228afc044e6e9a8ad57fbab59ec12c8358361f38eb9c00b33aa97c90f51a5014fa497c102b7f6dc0e0678e99e7ab7b98cd2521ea98ba31ede92cf621e36addf622adc7b0f77d8df828dd511b9e74f0925c8c7df1ce56cc2e5ad79feb27de705d780c2b77c931aba6a032d99f658f73fd9b9872959cac0137e9af2a565ceb6f73b011ab3aa14132422c14692f7bb3255cc96a3d63dd167028d4221fe4a66f0a010f35ee42d97326f3638fd15cad7d9afa2208efc4e2f0203d1254d93bf532961ab24df78a6a33eedb0d250869244c17074a283ea083c211528e91a13e0c585a85cf5887b09734a5aee9a01a0de3ffaefbf3791d1b1e478ac1c369e9e0e4ba825ac6590aa011cfa0ed15f9fdcb0f386fe1a796dc243862a292844b90d32db05ad0eb8f2839fb386085b7aebe12e7477d5eb5ef9b6603004b3c2ecc6e961059b11495d07ab2a164c64cb0d6f3c94555a5c3fe5cc687601c03861eec326b63b614cfef131a89058d0b320f1076023884882aeda8f28daa0a3dc96ff9ee982925db55fef48586f407f576c5e5b9a723f1f10427304c19aa1d39b70a12a9c9f07ae6b76faeb66f4b26cc00febae63ecfc629968268acceb5aadaca\nTAG: 59e3b0e92ae4aa57a2fc4a19b74e06ce\n\nKEY: d4a30afa6fe8b9ed0add15bc78ca371cf34d6feaf94bb7f6520b4379e7bfbf83\nNONCE: 6acfa3e2adfcb7f880c53c1a\nIN: 8b8fdfbf5272fc29b2be7d69ff0741df1ebba02e0525e29cf45063e5da740f6c33b1deffea0eb2323035a21b18fa010c6c3ca7cc0c8194627d828fd5a9898e2b55266d4377233badeaffa7c703fd710441e250d9a5d94d954911d66caa836e2413b190917c1802c3e587d514184498ff2e6e3df5405829262b36fa8971cf8595bd1cd87801ac4c99357da70e2e55ffc012a30cca44e4f5538ba92f17aed8c8a48f85c501df2f0639ac88a39cc024fdb6d29aac368728865db1a30ddb36d366927f04f00f8dd2229e1fe76db8e7ded1fd886a9342308ba99d80f86704c974da156d96c272b806aec6c0268378652c26bad18ab249e117f8643d234b965d45067f42b857f0888ec68aab64b3ebde8a55ee38464e5f35f8653c7f0ba7598ad26f9772b574d7e060377a4174922b1f8ce6b72a83f3a20d20625132ad7cb1429e26865ecce2a47e29740cef1a3d85bdb3e800d46692d6ef926395aefba588294ff410dd523db596a7c17bf7d439ef8200a13e35000b40e9b0b392c982a4377557abca18c1f3bf774f4bf8ab0b9080dceb2323953aa0e621954d87737bba6f562dbb0de271d6f1b88d7c1a712f613b099d2bbe0784a8304467cb168ffde2625edd9f38be5660020ed3e95b49e0a0ca9dc2bd0de2e40fb275b4813289327de0926df3c73865e7689fbad0a6c79ea615fc84345529cf2ef68b37b7e9fa5d538f4dd848ba66adb4745079acabac63de8d2ce9a2b19cc718162e9fdce49de7fa4b820043ae234d8afd23a45ee3a5db124e0f9252111c367beebfab55b2c784581b63a1caf4ab24bf5af45b986f457ddafbe87791788e7c7536595d965d5fcf21e3b13873b00357dfd7851f9e0f198ff950d69979157089be26b22800c3dfc713a5147b0ca4905793a2817281fb112deac286c41ffeb2bfb3fe1ddc9aaf4fb41fd5faf1df2e6e809f54b09f99bb8b61b555efdf4d8cb559fbe57a905d30184c2de6e154d501bc91f6033eb97295d96c1085b510cd57631e40e9ea3225e175162629b4\nAD: c44ede0ab5643af425a8f8614e621a581b559f0e7fb63f0c8ca09cc58c244ab2e0f750c6135fc26e433710351802c329edbe97877f912bdad914a051d859c588af925674f1f455a322671793887420bc79a11541589082ef12c975dfd0528294ccb086ecca86ca940ba05f937fb2eb91b4b925713e8ef7d10305bc937aa976c5eefb4142b0c18c1ecc6be979621c437c64e1bcfe6ae86d28a29fc894120da6ddba1e56181b6f54a9e9810a83c3b44b6fba10959139787a491f367658ede40e1289148f66d4677d0281ea3615ab399c7dd9e6e05b8a68fc8724089825fd5f6a38406b3eaf01b8dcb62afe181ed963a0d940f1521f4f501d3349e6aec453edee70f1cc640ba3bedf78ec91acabe75f7de38ab98253dcd18c6a866f4c2b8a94072b1f141c9ee3c43beed8a08d09c2f35f142b8352cf776c57d6684898fdf6653997dbcb2cfcdcc43d63b1d287beb8a17ebc74eb3c3875af2ee0446b2d75052ef95d37315fd55e346c3e8dff45f17c\nCT: 9d4764aa97244b3506582c24cf82947430e6749bbf3a907a941d398b39950dea9c21aa637a6d5030d9b070ff6c810a0f63cbeb107bfe1d91a2b3a71c2683c2d2716759a74f9c022b88afe5f36182153e5378c12f94174e5014743da44601908df428d105362d6299f2989ffbb67d45b65cb2a35e888d823605d2215f325ee59332a066b8139e01ac2ad5165d858fa809343fedaad3ceff19c50b218da9c1ececd713bdd657b02955afa4a90dc2f426cfee4de4b1e097fad3c5183fdc84725db9263bbc207579175ca3171e7cde14b652fa50c2032d59f2832196750731c2268c6f807625e8bce39faed8f85dfe5fe1cfd5d60434a753159b7196cc69c2eed5f50907299a53092d3f3d41bf7c8e4213d9d543bc235e50ec2f569840abb26490f1b0167ac423ee0a680a70797821fbfe7dee33d9ed120a95c6a75596e04eff2263c1c635da44322d18cf720bc90a113790b9e9d5141dfda46fa2c9eeec5afdd43ca5c0ded8a5abae0d3243ab2f81f3ace681a07a59afe8949061e21f8ad0a9d50e3c8d36a6270dfe9eb08451323f71793a5942ee7484cb1eb033037b209bc8c61b38ea28e9f9c2a4cdb629331a1517606feeaa0eb45c69958df6a5e48204489730fa83aeed0b2fa3e555437fe460980e8813e0521d88100088bdf6192257be14eb151d6f4b5c6b0bc9ca6a0ca2e2944d6d51e3bf4fed6cb7722971768da931c1f1e50872f25ca12e72bc984f48010481924fdaf3c744bd098d2153487617e321e665ec9a1346209695ef6b1e0e79f0c4fce7d33f57087512559a8290d8679555ea7f1554ac6374468f3865a2bfec31f27cbbc6adac1d484ca6da48119d88295cacf38b427f792f25f7d3c341a904dd9d3774e355edc0db3748d65506f2a0bef5d8abd37c31daba869dedbf19e3aff557b0466352db1f5820f3b494304604fb6fe42df9dae1c21429ea37258cc087cf72675a15a8159e33855dce7a09a77ba8ff296ccdfbcfacc7adb6b7b020de0bc302a7fbd1e3b8d51c5b1f520d384aba\nTAG: c22896658ca6cede859de01b80632d9e\n\nKEY: b28f523592ba049b5de3963baaf0eac3cd75f0f0543e0dab651061bac4e3ea36\nNONCE: 79bb9a78d035bd8ea9e8ad70\nIN: 9f6c13ae2d4638dbebe6b4cc0ff606af9720c708c20dc2d6f0e4ba002a0b41e136d2b10dd6a2f8d9fe8cbe91943339fad0c52a2881b188611955771d3f9a621af08b95dbb77879bf508963fe294c8b8807fb9d8458a56d7fa2a4c5d995113ea8a86da07c28dab43c997e9277f98009d67fcf2ba171016cdb7e6c449f6996d21563b4ab22e933ddfad5c50e9036db19adf88761150b2226e73043a49a8e9934094eb4363d61bfddb791f4c5bca194d451023aeb879092eb2d8c8c3a2a5b8", + "a832db6d73804c0c078c50a1414b684184780278cc90ac42618bb4144d5a415f582a77b247e4e8236bcb0692620757960f5103887683fd54f78095e8b098506c81008a7b443a533a0a71fae3f08bb4c28c7142576f459b1a2ccb5f65425515e691852e0da343291ca414c28c90426f7d5f9d7c78f84ad6eedc600137c4d86fa7db53b1d3fe9b16874b31275a740b5f640fffcb4351e4e32cd6bb7b6fc11f104b2513c0814c370b6a7558d7fc07c355da505a1777a2176abbe5e520c0ee79153c976d71e5c6dd576f4857ba2d63e04d6b69a2d5a3ad1a3cb88733fdbca5b027ae04137f917a650b4a556b5fff90f17bc12a890aaa8d61029f0c6663eba8326c1bfba5d9221876ce3365bfddb714e884bced0f1675b6ffee2b1e22929f23893f3dadf967b006e9cb7a9a0972422c74a0393a29f9c4e06c2586f393786ba078cc52499ca6e911e323915ebca1d1dd203189cda3af76f785538d9f1cf5e5dc5758a490cea8710a9610790f426a0c76e262eeb9facfcd7730b72802084152f71adcc2cd6a2bcdd0fec76ee3228947d2f9b1b6f614a7e609c8f250fd02e19a487365b0db8f2d53cc6843d0d2a2abf3cd2ce33125558046fe9ea2eadca7dcb9d0a20fb3ee274fd92360f8772a53937625b5aaf9f10e9c9452426cb42dce78cdfa2628aeb58c295b01e12b12ece1fc5f66e33cec966b52d6593e1d1e93ba3abbe0c917dda7c2b6b5d45fb4cf6588908208e9b264f7e8ff87cc5090f4ea9b1a5205c852c308783a6c5ba0629cacfdd38b50706097f\nAD: 3496b4171a3199a485cfb32fae763dd77234dd9e2c6544f057c9885e914325efa4ccc25099f81c95a4e968e5e031747422cbd48ebfed3236f878a2832b7fc6aad4db734868ba2623899e9e0689e618bac700ce17e6d0114a0f5b94d6a0c3373f803ba2337d530fb706b8afbe482eeb9e0f5582b2f502d3c774b2ba98ce5400a20cb7d9a32a351401bffc2214392166208de9fc8a6d329b7dccf10734b5b74ce122f2454fa551b586dea96fcad2c45b1bf562bd5751b757da829d57cfdfd8ecbcc410c00aff69764a4e532545838b38011f92e464d192ba315ef239dcd5041448f165a14d503a865a85dfe81c5d4dfd37fa6c316c09eb403bfdc2a8c1a0618477a5fede92cbb2abb71b425e201c6361b5509288675a4541f44b7fe052acb25d1d87660eecef0beed7851a2966947dbfb8714038621b6f34ca2874751aebe9e8084f6ed854ed5f151f81533614cb1fdc08d2f51e47537f6229e0b64d10b498f773fb67bde258cb74a78843256913cad2727f9dbc3a8bd5\nCT: 8cf78ff0f64a19abecbf693d8575602631303858623968c8c4522c5351ac552dd3694b0a04fa270eb9652dbe58c07cacc2bfbc927f22bf561bd4cd2d639a00b240f41d6af836ec3f93dc0610f08d59514c49351e25cfbbe1ad05e8cb21e25f144d926b5752f96ed7dd05c816cc95f5c3a008716c8a18ada661ecc497c6e34540b8924ab0560c57e7190ab567762bc5ece63883ab5522c8e84efa3dbbf71179d6f286127f01e8b909b61a16fb2433798613fae1ba08524d734662bca15dc70a550740d1b741c0cb46528d061c786f129cd49a7f5b9c1f742c906fe7592e70a5185b6b1ab669498bac981f846dfd2401be46c0972f8945adaedbc7c54cd40c8dfa781c0faeb6b2c0150bfef21ecab2995da3426be508f21278a668e81b25938dfe2f8e1f85c8e69468e38ba924ffae71c1e1c990656d42c8069d120c75e840a2df0ddcc88a77fac1a4ee56d3bb00cd53daebc0c981571d0e3f467d2940b4b92c359afdfcecaaa4331ac45f0afd902e8c5815266d195e303eb16960fcc21162f025d5258786963250aad37610c6b191e479bd5ed29b8cfba9df43131feff2571fc87209b69d15b6c380a8623428f01944d6d5e56422fbec4f7720b607901f06f4433fb252ecc251660e6f9160fefff8af8b866c2edb11f6419a6bf91c5fd557851d469c256f511b9acc8e71750587e4ec0482bf4ddb0b73ed82cce239a4d9c6b330527cd8d529675c2c556456b10ebceec05e7971580b553b8a5f720f8ed38123f56869753624f4a6cf9036c3566cb4f6ca8e0f36d914758f07e7f447c67c8b40d703270d035d1cd39b22c291333ac1f628d2ce4697f82ff6c043ede6dba39c03e250efbdab3ed5e73c28e194269d8657862829f7b43192f95766f77a7b9b4c154a787d0050cf11099d372c3f97add6c9cf4a467df0922f7d9e1b17e552b453e80aa050d8a3e4fbf9aaa4c01a463b796cadf65b492f301ef03476bcffdf96a4f5bc933d0d4286bd9e2ac9822957ac9a69fe34b3701d913cabe970dbfa5830e083add43682f261c3aa80fa2beff7942c\nTAG: dc5369a6b0814d58060d033aba87a030\n\nKEY: 1daac9ed308ed0d77d86aa657a6ea7f9c35e120553d26b2d3fad1bc256f1f71c\nNONCE: 7550220b0b5f3c6fa8db7316\nIN: 337934937b996d7a501a3d1fa7f6321369747329fa6bce98f68c769dfb3df84b2b1e14f1a58c3f6b65e03377b7058fda3c26adbc370ec72e58ccc953ff157d4863057e0df89328efb5023c1b79f0e29be2d7cac9f903bb782c4c8720e2ccffe83710871642e2acae2071ba2a0af880f14f41ebdf61a3e5449dec6e61e103385971b8300a31b652053496e9b3a2db7a7bfb03a054fcd912e3e1791f84cf484370e553d67cf99c6b1c9b93bbe6ad4a93c47ba9ef73d9f8506400a49a5609e7eae5e3ee9efc657729d1e615a592a8c9f14ba37f5d91649a8c59ade56769c3bcef0c004c7444c3dd24223ef7bc6a2ba2e5927608692d1fbbd3868d7fee0fd11ee40312ae06d20704e29a97ecd4265556432173d6248e9f273363211b5d505de9861eaf402a001ac18b485c7ad0e442bb5e648e20e0884ffcbbd2dda9b3aece535d964d2cfcd6f99a31a4f24d878575fc3ad7a7c19e76771929c45d0965702625cbdd2e99371147e41e950ef70a7393084682a2ee6ca9b611f3c7b38ca4f5fdf2100c6c8d1e88b842aed09cd16a5d78d4e2d7712e40234292dd1aa27ecbe63c433804b0111a2cc469e4f012d55e95e251139f5d6dbfc6dc8e8fb6bf5ecdd8dc89fcb6b2964755d1de9d8a0dc9d648619e185169ae5ccd61a6c2266c5177d8569ba4a09d4c231d48b8f8017365a411714be669fd31f5d17738739c75ba5abfc19d1eca16558cd69bf33f63f50417c92c29dd44ced6e9d9509057ce53a37cfd956bc33c6128fcaaa441fe3016389cf69bb589d323f18fce0a6cc7e77d9e33868ae21ecf8e491019f175f10013392c8fce3e6de3dbe9bb20ab69c2996967d171ea48b46abd36b9f4015723ec99ab940156e6b13ac06ec0f4a8ef74ee304e3072d9e14e844d2fef1e6fff116fbe9a74a7d90e79958a2f14c364418b7cc0d135e0fb8e68600f2e7aa26f9e15431ac9e5cf380b5fae8d715d1dbce4c0225e5c61e747029f62f4ea5de277bccb75580d6f5e5eff710ac8bed37e98b15677462946b2fb3fc0ffe720ea7c6bb70baa0e998fad6b747d5493506ffe69133608f2819d3fd9c8ef\nAD: 903de215b72677076dabb98cb1059d7d1b352f95a2d2c2903dff63743ec314e0313e46095197f6aeb2967c5a60f7f043b5167de03ffd320b64291bb7162b495f8379c883f17d642bd8bcad4caec8ac05150a5d449a22185058fd5c3a87a9f39b8a76afa529bb9e22641c8811c78fe3d3aaf2acbb88c47a1ac40dd686b80828fcbef0937e57a6272dc2e3ee18fb99410ac33a96d0800bf07dfea59e707cdc633c938feaa179a8d46940d1182fede7e1b9a3687548a0ca19bf53a641082da37082f257fe2fc83188c46cc58ff44a111ad32b6745dcacc4720dd960d2325443cb70615a4437eea2a409ee70c7fa3967a2fe97915ae852cbecd21d44b8db03d3d631c90e834a83428568e8250f5b8e2422007e8cefc12cfc28fc7f9a73f93afc1c3d2083e4c5cf6204753ef7fc4199c0d877859a90a1d3b16ddec6de134689accdca001fb1dbaca4fd492854446c4897afeeb68181890914744a387c198674d37ad98c4ff3fbb34ed656add39879af2e336e529c362d15399e40d2eedd9fca1f07\nCT: c6610234579809d78c1caa28765c5b05f33a0c5d99660ef94296ba00937522ff4efd86f760d3398a9029877192dee574ee7b882c5ba28d1c388444137c2ac96c6eb4cace7ffe3916bf196afc67b68e4daf0e191450b04284f930f6ebe924cec498e0cf2925bce9d25bb08e872352bbb9aee31a9ca45e41dedd3e931e3ca1ec79aad5390c7f81e8b9473aeb2fc6553bd0ef87a42dd15ae2edeacc148aad6615f3bda730e50f5ae8e44f3639c94242252c2b4b44441f6974652cf783cebfaa2f69e795609a94db16948bb30ab58377c9509ea682a21c408e3b057becf82dc73f1addbdc9b98d659e26092d4f5bc1ef819f9079e0c66bfb684839c0cf1c2e9503afd1ca7de025d4a3a86ac9578bae2d2f6452c2952b57452157d88794a4a872786794a29acb6e4cb511f8cca95cfbd33aebfdd224ba7ace8c12fee32eae1ce60ae0ab6e39766fed2c385ab3888780601cc18a3361468e057d19f97e94ca3bf814bad74f93b8c18364774435a83de1fa867b684a1f2ba8baba24583f8e3808ea7bf238409110959a90c93ae68d8e3fddd8951019e9d6699e868e8f1d156e57eb1d4e8688ef064f18bb8bda91f961d1dca461220f88646bafb0c0bb3e65be33c445f265c0c4e843eb155b5040ddda3a5d104a6d89dd0523e89bf3cc7125774562b5d7a9a386f8e227e6ad71ea9c0361a4e83d9509478a14e9ed8614ce0c39bc9d1ea361cff583ce5bea53cd84083b45ee18e6d4bf3ffec402657c01d54c6db3533ae6ce428317cc3c0a2b2621ca7f82d83cbbbe6571ea87686e20b0d24eaf8489c573353ea3b879b4e7a1f6d87370ff8437c9767d4f99f244d15ee3eab3a1ded233a26c1abf8f010a89d7da628f350cc93529b130ec1085abb62a857bcd8859f738b511f5dde072e723d8fa88fc21dd6d464358df9f972e55a659c5794e7eceda8b780af6ab65ce18814d5c3b38085be841df3b52b8cda8efb8a33fc52d6952fc3c70c42da59aa4eeb61e11ad4b1ba20568da6ddb31a8f1bde37e8c63c440ee90688186b9f222bd4cb369d9e077d0071dd9d6557f5b901829af6a3cb4825c76f05c\nTAG: 78ea2271c0bccf96f0d64594820543cc\n\nKEY: c117304024e03ccb6e4e35d4c2508014742ed3639e8d0d0a73b4e99c0e2825fa\nNONCE: 3a69b798030cadfb168a1f88\nIN: dbe56896bfb9a41e901a1bb61b8a95cfbb343266e894f101767efe874d9d45b4540d2d77e701e1d42fb03c32ca4b965d836b3fd34ea3ca2e958aa54f1b71e8c442783924c023c1b9fe0a45c88f4b66453fd335db8102e1de765ccfd7fd415ab7a08fe4e0b3d2a14f1564ffa3157a7da7cc9981029a45edf19bac8dc0f97286038b38fca85f280ff9a98eba85e328be65a657291692413319e0f045c07c657c903e51c0bf72093c615cdfa18368992cbfd4e11bd64054d34405d00bbfbdce63e315e3e99fccde073823c17d9790cced43408ba71e48b06f9bed959818d939f7c84b2d6c3861dd17e424dee0cd7942320c50ce637dd1349173b13b972d0808d24d5ebee528343bb0f0415aa123ba63206de27257b11ab15aa1a3d23d97bcde30cfc2c8f9bf0fc3cfa4a6fd61871744823d7a1f8fa7dfdabbe82e73e491045c9df0f23d9cb83ac7d1118b4653cf4961cdb7256b0", + "73571962b1956338d684bcbe4aa05aec761e0a14cdbae6d42897dbbb1c0a646ee4b0e0dd43479849864311c3f743f2a6cf9d0dad34111493f0e55461aa1daba988af83842804de0707b69bb27ad64f66247eca2701b9e697bd6d3ba32fd30c7948a1782f3d308387b3d66a8da9c412d4e17d8d7c8b3344f33a79e0aa40ac27ac3659eba14e951947fc2f2302953bc766ebbfdc41d1f4c26afe5fb41412aa776608d37d8addd0d7f0c82c61961024579d828aad7fc89493de8002620fc3d638cef981d8a843b658ec3ee27b01da0df91c0874edc83587a70f3dd5d6f7028cff83c107a72c4505ec4623b35ddc5fe3f758434a14685e74976693d8c67ec2f6dbb62f199c7eb3ae344c05b43985f6e5639f6f9bc321bcc436044b8f5b89dce923e85384e16e6eed7ea5f3e49abcc010655a3a29cf9fa60791cf7262671ce0fb2044383944d415a8acee77e88697a96d4af5f7794e1cc8960ec31a8727276ebaaa5fc44b1a240be8679d2d0c8d3ed8d950f8bea0daa64693d4e8e5e5be0567c0d878e4f9a830ab4c6153ebfd5b1019c659c8f456a636dfebd24dfcb7b3d50be807a14440f7aeb52c280b3dedfd7ced9\nAD: a6ecab35e7b603dd8253a5046e139e2cb9cb5d70ec87f9468915e24847576c1b4a529fbc4f2d84706c1be86b81436ecc4bbe4ec15ced347ccc68744a9275ecc9cc71a62b0f77391e2d37c7f36683d902a0f9ee37df8306427de4ddb01618f62629ad8deab26ede6af11b2409810b4963a1b752c7f6c71acb3c6c2f5f5fda91dd54410ac1637e55e547b25cdf5730ed4aeac8c0fc59a365376d84a35440aa2830cf614bb1012bdb644841e22329bb5798bf971b370dede894cc4f9395a54fe7936381b7281e60767bb2f8a17492ea63063882d29ead140e197d2647656ab981caf919583e869b844e61fe19e94518ce7ee5aec100b9acc2cb8de3dfd5cd3a776ff2f23319721b05e194b6acc9db40b280592e50b8b5d7d43a7065898f5af4ad8afa6d8b6559c81a9e8e923f6548b3f59c8ba30620d22865117e8a9856f66df128d82c7e15dd9f3ab3ccae9d2e30061224c7a606f87f9dc5d40c689cda06e5ae21e47563378b50c1ee7c664bd814c329036858bf9d3abfae22deef8b74d2fe6a56\nCT: a6c4079486af388ff129e360fef12e039e54e4900d091be16df1d3712dea1578f11cb12716431f5c6d26a0719012bb89d1a3515e0821258b65157b8e5a8ab7354ad6efe2530337c8974f3f89f674f5dbfd3e8b34d6d425031e4591b37991b5e76acf5c5c13bd47c28c6a55a81bc2f2297fe42e1500f03ac1d97a348cb9c39da8a95b1a5c4b3bd47c56988c19c1d8c6a10a35322acb4338027d2a32cb32f5ce70d4d967fb30052b86f538f1e756bc10492931b40bdb6a579885b94de17cbe917b454db89536a021c4fb230037a4d808ef71159630f48855b47fa90ead1c54903dd925e88516f0cc0968827acd6e57df044c485ed9872e57308e8c5a8992d5d7bba05f7ce949f83dffde903ad093f8fed3ee11a1c6ab031089d77a965e5a89f877b7c4b23c3118ae50e7e21d75e133ac98fba316019b4c2866257d02e6dc8ae5b476517daf7df313093c176a2ca6bd8312bcc96e4fd78fa94313a6ac1b053e72bb622dabc5fa216ebb3a99c4e760737a29d5f452176efd9720197432cf17e8182bf1af60608359195341fb0246baa0087a7af0a5155f32895a06adf69fd01e6f86fb46377e50dc67d5115dda5b0322eeadc8d7b3bc5d0658eaac577725b2656d4cb7803f28df819df0eabfb4d8a7de150887d168f1ab7e5fe0ecd71cb98e35918c8b739059eafdd254f9bc03064d3e27c4b41ae04c2ccb13042a839f82fe9335df59c6991b7e8f6c821026a0d39accd5ca8007aac60ea324eaba577eceea25b4f31504cd64929576513da857f6c9551347457530fca38b173a6e7fbb7219fe861397e0bb50cacf6368929a5a429f1bcc47f6db2517ec62a40bb8310486612d6362870c3980ebf3223216d9df538649b25a704bbf12374442cb489af02020e6886092b0410f922c7680d5fa89effa7780e31f9222348467acdf049ff39ce3df27006406642c01669b819ab61ad05b096270fa75bbad04e8b09b1c4f75b12761b2e2129559625f46bd1005ce39a4b543f34960f0e7c67cae9074b29ba86867a9b35f0a94d716fc7103266b7d14164473b1d4e19a7cb157fe5e04e83dea1bc886947c\nTAG: c3bb19a713afccf40080a1923350cf11\n\nKEY: 6e2aedf8329f42697cd7ae88fbdac408b1b8a6efe377670b244110cce97d0002\nNONCE: 37e72e6de6176fec75f5baa6\nIN: d75d0652ef7d1eb495797993afbb364cd663dba38c266d3721f0c522238bab60a95261445092ea645ebc25b6f2fe177297a0aecfc9fdc621fec0290b266c8ceeb3945376c4f9ad961b97b32b176bc1e806eb2d2e410e8ff7af12ef545493b1a61ab84e634ad86ca15fb9773765ec0271c204fd951621fb8ad69601c06c6ff6d151a156295371f7b207ce6d09ef47d106a9466fda667b7e0e2b9b2ef6caabd297dc82ebf2b03146c988790311ad7f4b8e41c1e04c1b9f40d4e3d8eb611f3ab06d12b97b75d3b490a4fe30b1c565243eb77d24c06b539e3d335b651e95ad957450c027698dcaa3ee3ff43de18fa735ecf7f404352c9406bb8358b9d3e47b7dc4f6a813d4f4f37225baee2c3c028b3974f4c0e8b1f0beff79fb0b04ccc5824b6ef8108bd9ead21729a9a9cb3ba8705bf77ec3c974a34b2d838784b243176b2c6e7a2010a785a96ca2ecec4fe57bf7f6dec0c9b72c52b8c53157d4f9fd259344cd556c637f921170135fbbc86d68af452dc575eebffee445f8f755c19c73a26fa433bd4437c1018263e7db4b580a120d1d29775d9d5ced6710ae2abed148d4008bade4539728768b1ed315de117a81fa0978c1ed9079188454c852652e8ccc4904ccf233458b19d0f17ba6525f3096d369fda3dcc84e092ea1236bb57a8bfbfa9ebde780843bcd967708ea20c61b60a11ac24b808029676a30dda9f5f6cd69aa6d7aa3b08cee0e89456bc4561dfbd751f9abd3ecbc161256a26084e5ae1d94dcd3f74ca30b4ff1857ab9e68cecf2f384da7d271c1d8b167250d901a2272551020c30bb9e9f9a8f9adb299956fb060a17522efb26363393885b4aec2c02b0a8c40835fa058166c7c3013908c1513e4bf9c71671798537cf05c994d2090fc768a12dce93a80d0a4cf1614d0101851ea6f87b528047f07d07ed78cd4e54fdcdd26bb4f83d297c402ab5e328c404118f52bcd5b6f36a18bd3186a19fdc522ec9838eb363818a48ff88651a2359447876d139c6b0b7d35e30dc0a3ebd3132e5e2a0c3916ea7e3667fa266a91d5906d1bfc005f166bd14f298856e85022c8274ef5160f87d989271d2eeff544501635f4f071089e074\nAD: 6027a29d52264520a6ff2f2ede11e8d196c706c8a06d87c5e3679be87b0c36026e38fd53da6bad38f9abefe48b56db84a445f223ee0ceb1fb1b797d2b589dff9b26bbfeaa1b21d662edc6f4e48c8d91025220a9f3e7f1965e0e6f7232e84348190e1b66f918b896e778d58a40c47439b2007b8574cb56a18f72677227f1aa09e36ee41aed2692b28b3244e9f54a7d317b1e5b1e7b7fc59506744a25e5087d273203aaa1dd0b9d627b240e518a866d531a90d4b3c44cc1ed9d9d1350f57e03c3f841017b46a68d6f1f8a6125f4b622a0132e64a85fb47883389dbbe1e3d26eca7ac8676a22b4bc79ad30eacc91b6d06603e916ed87bef76ae3627416af104d2794a7b86b561ef91deb0e3f97e07a37a3ae11073945f75933a5dd66b14aa98e826aa4180bf222a201f5ffd860be8a4b73d3b7353fee03be602e52440c7077fe0afb1dd5f3e823c170a4927c241a09b83e5da81c1fb748452701250896547e34e647470f5af70a23af895d71ba21904e1c6fab41f5af486d448b57eb5a3656089d39ea31ea9fe6c88bc40\nCT: 10327cff240fa05d2aa15a7b299b925a0ad1740957c4fd23ebe24e8a1f36cff5c19007d4fda60dd9d3231258021cf2d11d9ffd32bb221a620d68f2b0077a64a6d575c3802844500b2e6d08ee659006018b6512651a5b903b6d438eaabbd41d0366529788a33dd43a0144637b4a66371a7e58898c4b6d1205a239928c3c3e00907f50a79e2a99f2f675cfffe191f0c584b0e93d72f2a2aa8a400226852fb97ff0cb6d361342185500e3a0db1c9836bb8981d7b4152a399f84a047e5dcbe7c0dde2a85496d4fafd8990f70f28025519dc56ab2fdc150c215bac333af39a981ce5ec484d3cfb06ceeb68471d730e9a6a82d03a4b29dc8ba5ade90c55f6431109bd8c8be337033ca49c4f75fcc2b93a3103638d8516622625749dc4ab0dca45e02abbb2931895f3720bf0d915a6f2802b9a402a5a9c1f47419df6ac9fbe2356cc6c51924bc7c6d9399a92688fc6d75a41f69e4f91fd375df325a75dfdbea2084ee9dbead62754b4b97cd7fa075f6c016678053a8d6cc4de4dddc2c2689efcab3281f1b7f353b3e8710fe396e874784fa54c034aedf078524ecbb18f5bed06a88887797afb0442670224c3bc3e0b347480b7d84268ecd792641b697cc7ed431ff0db957252ee3ce4ab0dbbd47638c15fd0ea8a25d3f3ea75a81dc9986b240ef3189f323a342857ac59900bb8e3bc429435b4c00cce3aa6c516d0c68456a12929359b0bb9b02b349e63c4dc8bf2ed107d94af97af04c14ed454f3920e1f354378c20b3be5c12adaac6d96eed1df0496172a71b585e3f5e39484578475e6c257868b3d0bb45cf229c0752697ab66106a675311318733b02335ce46b1e035a92557d2ddc9536634cbc516800fddfe358d8848198045d746a5b6e00db3d2d0b22f7e4c4d5cde136f62db48968eb360a6d8b645022066ec54f2f2f05b3b8c9af2097986464ab60ad9f05cb63cd194e501507babb6103b96daee90c70efa78c609f95a20e85b26f2d9bb503274dc40aa0aeadc485a2859b3497f4688df1b2eeae81787375dbe3f9fc6ac8b4bfa339b92495d175ad6bc67856b58c1233ee1b0c2b524668750a48c0704e56da23fcb015be58239cdbe228\nTAG: d5bc1db867fb362965c9ec4e686d95e4\n\nKEY: fba584198cf82944ca5c806d3856240c4336fc1b451f44f31a97a978b3de874a\nNONCE: 859c5637b754a4e7c1ddc3f3\nIN: 4dd6231ff71f13e6a5b4e182e62331f3ed1d4692e35f6959b17ef4cc7f29859a67b60527aef9d08a333bb51c6e163e016858a4da2103df237e16acb93421859c83ba348faafa3eb31d0addec9c90f61a4382be25a85daf829e5b2751c9b7378cb9e840c92e174b1e9a32f3a5b48bf70b6de1637158a09714b473e1b3e339f9f915d27b310af2fa13c05edf4eb9b114c80ec2677fbde6b5c351b61fc0527c9206357bc1d1de800d8e6dbbd3f97d5b1220006280a42f51b7b4b4c67c56aac1483a5357a7a26528a1ad1ec39e0828117be1c6da36a60a7052f0dbc26846e4bee96a7cb6dd5a3dceb6a11d356e0177be9fca68d0f4b00a8db8afe8441abfd80be2d7d25ac10620dafbd92c0956c2b3ee4da7f3db8d028cd60036f78badd42e0e9767a6c8bf8bc3ed869a9954fb4db389e2f6e44667ec26fec930e6a687e3fbf10686c00539628bf50390fc167b1c31c1bd061e975a60affd238a229a0551214f20bb9e17f097462629d04a9ca6ba98cf3020f1fce170b9ce20440fd25c2cc143018aefa1748f6269b478e1d79f3", + "727831086620e79dd357fea1c84ec4de0bf7d6afa2f702a466807c0d2b8e4c81c402d566a0af16c065941b5f9b689a085ef4980131bb979a0b4300ca32f92d902516c3c9d799220e786d281d64f3a7b5cdc4721b5245444fa9291d4c58f9024387c4c4e4dac5ec5d7542986a2b97619a7db38720f392dc7539fdcc5bde53d2a4809b9223663d8876543a02431eaead9588ef68cc50e707e925f09eb53c7117fb2c8bfd07b578191b3af028d480a6f90fd891e03290d0d180bfa44953ac9388d08dbcdb238790bbe07df067a26acf6621b809a154242496baf4f7a07044c04dc02b5042c5365a71cc5ab9ee82630d97d1ed9b55be1711ac6b1b2a497eb1645c69ad15617a45751807a0e4cad1d0d965988752c65847bff53527bbd087f7d0f1b756563f38bf5905391836ddd47f57d84742c07a8000d4ad3fed2dc91f19e6226e7c3fc260e0ed4b23715cd01bf2c2fa59445d8a695bc759d5328c85db7cc6e2566ed0c5758ba2d12c1d285311208e1d4f66caf32afd1619a46e5296f435ff5bb24dd30d060aa462185b4e05afecb2ad221ce615b6867f5\nAD: fa46599e0a9f3c03555569f4ed86b73a35db18c622b4089ebf31da474873637e4b97aa71ba883368691ed48f8600098b05cbd218c1d4aee55a0e6ac862518a6602328e5dc9f193b0941797e863d6534de6013555f35ad8c32e9264fdee17e927db412e76f06922b36b4c1f5f0d4b998d9c10dc88f3ac0b8ee01b1a88e0b031562510395b9b5a063ae968fe3f87a3bffa2e55a7aab152c50ea8bd0c61682c0f9c0c186c3dd0287c7c5a8f50c2f0c796ad7afe3fb9b45d90e8d2443291947067f982f070643289a117c404124245273fe17aef4c48c1b9377f54e6ecfb43aafae2fe52eea2f2b8aa4fa5a7412c3380723dc99e63c0455736ceb0fdcf1caf6714937c75de252723a7a1b5c7bc5ab1430a8fc44d78467526be8b722e0a49c54e85b6da58e44ab4db4b7d1bd33e28c1aefa462f17caee6b45a6d5df43478f36ee54b1158399a861124a95cc759fbb5bd4572adcabd5073758e0f40d6e733a87cc9a3653dce1b59936d57beddf6b980bb7cdeabaf58d50eea9ad55dcc7af8369bb9ee8af923d4dba981d25efafc2d2352315e367a9\nCT: 29e739b7162cd3504c7a70f3efea5d6c2282bbf1fdd75224729aab622d59b2f680c92de483a46d2e8c45460c8f3efca1fb374ae8a04ab84aeee0c083a09ddae6cbdd1803e19b27fc1bbc4ea58ded24f9f630c16c04b605d107a5fbf640ff1225c919dce7b6f73b1a18aaa37e3d0c757e0062c0de6c516302f246f246051e1a0462db91e5ed5e1d178c3b384ff9d1ab3244b861b4c34e21a7ab194cc3d48d11588f53604609af8029a6ffd166c08a8f669da73f465efa2f0f54dc0e09916fe8903d0ceaab4e55494a043160e6962ca21ec86e1c159532691b34d507024a345aff411b46a1a32f7844ae3e1e250bc17c0c3edf4516231bc574d742b0b2411ceaa3c4cba1d910843534e34e3d405be0f51a304c80a858664142d285e84b8e008fa7247fc0583dc7b8de3dc9015f4d8e24505d1eadf4e7c598e628ca6b5c70dc6fa5c1734cefb418d62cb08b7d5fe81543d3d1b438ecac5359a0f1052e2efea3107b2da554ff669360db0062052917abc854ccae73623175f7e5ad37484609bda0b6ee3cc87667fac9d1d3de9fcd104b190c62e544be71e9badc2440e8b451532781dff81b5a7ec4f80d3686bed8f7747714e994adbb4612406499a6bc3925ab62d566660265ccf2d635c875ac6fec640b515b86ec5a7eeecd34b86d1f2eb6ecc5858cdaedc552175c707d12b677cad0a4b12bb4e717163002607eefddf63ba2581a2b1afca4865b97816e61813bc7ea99f8f69fa5bb8e306d5e6db15293ec2f7a9c4d8ba2d4ff6e258270c9ac7bf4887171434d034875b590fe20b959e0955034687679ddf98a5c777dfc06f11137b52121249ceac90f5eeeb6f1ac59ccc26198388eb8b5deb918cacaccf1e48145486c37bb2a11d371e095a250c86efacb85921129c2e19c9dc09c66173f394f568c47fe4ef0cd3a98a138b1750f3aca91f7677604613b6b0ccc92d6ba8a0c3cae6b7b22be761ce2922ab273debcbe3f68b662038e232430b3e7d3e4142617fea44c0683f0b7eb03950060ced6325409293422d058d88f0b81118183a05a13db7af89429731c8a37aa83328019626a6f2d87ee49f9b4cb39021093e4886d373a292fcf711945f9d572d734f422c92d8fa6e01c4dd778\nTAG: 73f6e44d8a2f3cc357707de856d2ce9f\n\nKEY: 8e21c6a4065bd95d14ac24cdaca55fa220b37dbf7d201b289178db041df9c303\nNONCE: 77ed6ab683ea82545de480b5\nIN: f15d0f948b50dac3b7233676de10bc93f529d5955ac70db7ce9b3f684283275898e74dc028b10623bd0cdaa6ebacc2b0bbb8aaf2e32b4d7d84ced724383443f493ec24948ef43a40bf94c1b97e0036e547eee4c59cc336d4205419d66374ac29cee8b274e1453299611c491f8303d00e0e445337a176f263462d0ea16c297effbc98a0790ace75c3c4965d09a32e38d0ee62c6277131f55abbf9d5c733910eccb8703634720f11429302c772c54ae4e0e2bebde2c251786f67fba677a6d9beba08d3d9436e28ec7d5cf016ba69cf20247ba4443c12ca056d3a11d1065b18a037add77642cb8aedab88117a1bf686b17efb241092ab2a17bc9562247c501479d77d0bb752dc5fbe2a4694d0309e68b885a434bbf2aa87ee6e97aa8fc715d9667977a75b37a42a1f4f27096887498ce460301d9ed2a32146a2000b1878654c85b5ebf2828161e3828e87319b838647f9973b860c6ce9f43cca21933ed4526fbcbe38d0169f60a85f9d84ad662b62bcb1088ffe9350382ba8c2748c79fd76bbf863f9a60b971fb6fa9446a3d034047358cdc99ac30e78d6238b5478982a2b4ce58537a34e5ebc37ea72f321f9e466031515c45461e66cc0550ac1b38ebd92d448d0745fb0be37eabb926f61facdc5bf3ae52caa0f923bd73c43a22b89902c0a4c43e12364d0286f328e125b8f5c9229fd955b5ccfbbc672275051df701e981e3208cdf832af70fb02325844120b5fc82f4f8981ed70989d78c69ab0ff75ab96c1ed69919859822ff20ab698e25f855cab4f01174c4feacd3b94003fdb1479150f0a9ed35de9dabe3b7c24a56685aafc396fddc9e6f1b35955b485c61f2659039b7254173364a57bc80418e2f6b7ae28dc8cc5402098b79c28806d135ad3d5a5d0503f32338334c9f6e63f29c61000ffa87668239ee2e1b0cd654c78d610509c5b83610b1fa85cec31a533fb329cbf0c543bed9ca26b97df5bb12ef4e6d252dbd955a2693d4903878b569bac70c4562712ee16a7da269d6bba8dd57b54246598e50453f47788a2038e206b4e34ccfd275c6f5f1de5687fce97d5707d8b697278a3e7c1f07ccfb11f23b343c5d8c7c08b1122b36f3286decc760474b6a27646f432e740420981b480ecc2e50bcec71691da9ff95d43\nAD: 51c1637f5348c5fabce63137ba3c82b93e7a187619ce9c2aef21b0e696becb4539fd581481c35255090bcd08de83c0c4d35065208f2d4c0efb7903757d5408d49703dc5e8c94cdb9623741468ec982231849c1423bfa1dfcaf6633afb5997b3353cb42c7e8f99906331322da4c579a43d663ad4f7bf9d9d7bd7c54b65273f08a76181fec9b20fa5b4dab9ef00e0f6660446140d3b07226976843998e94a69e1cfdeec41d7fbf1c1fb576ab99ccedc4f2fbd6d6bcf6227f8a93916c859b37ded15cb9bdd13d399a51784da099dab63a4c0ba22d27aae6177372c05c1e5a833f459caeceb28743db88fd2807f605f7448d9220b79e56a312f06994a0132e43bd47b82e0e858e8d2773a7a518746b094df8a6cc851e6ed7b98ea657188c6936fb4bf0911ccd09a67ae539626b4573e0da5a64a75b0cbc995aa664f4cef75baf574e03cb7b1cd4efb301974fa1270be36a64f55f19890bd21824fd44099c384b45903d5a85fbc785c2bf10542eeccd3ff9004a157396a126516049e26f579e32e51c1e9d8ce32dfefa3e2558f6706d31757161b9c17c8f8365b9ac2570\nCT: 441def04eda7baf0e6edf24863166860ed05c9c3cd0d0c71a383b4dffdd6b5a59a18936779e63c8ce5a3ebcadef82c75d3f241f62d66125b4b4be0b8ae58e42d45421cc68b42ee062d1f6c12a75a80e854a1e44af9813e9be4ee85ea3a9f34534930cb4c51108160e4df6874b900cd293815a1d5bf2b064fef51d0fdce0e077cc26c4d405231b50a1c26ec03a8e956c9605cbb9b4ae68143342f6fa46a651cb39aa783abd0f6359365815aa8084102d856d860f7f6d9344f3d1e65b0af8c7d50f83afd151139808f651e23897331b58dbef7d301dad4ced88feb5db48b6b2e05e1c8cfb58610ac3c58cffcb411dce628c1975d5718631c1c1230ebdd40e6fbb6c2442937f95bd3d6578189fa72cbc963b922d17399439bad035a64f39e78c4aa7f0c4793173131d11c7693aca45c04e0f255daf0b1ab45c3e0d90dbe38ac08782f19325039127454e589953859ef87cb2e4edf1522f946b59b8251a1c154acfb50f0a7b0a349537e17e5de09037e385f51ec4f388517bb1ed1cdf891cf4fb39ecfef69eb553929c82941e078e0f4527614a002a8b8093e1c1ffc8882ece4e7f23951df6347d13b0e4ebdfa76b4fbc6baeda7411883fa74c8e0f567065e4bca86570fe31fc3738fce1469c9539a398a182756d26829b42e7d2f4b48fd35aa2738144a8df7e08678768cfa2e6ddf887558215bb44437939dc911af50cfddd936346155a3e543fbbabdf571cfbf34fe781e5db5b85791ddc465966c001b06efa95e5050f0a422d3026d48604f074f900ec66ae3b8f7b9faa7f438d28e6233428d74dcccebea033f2b57e8a9e77abd8f4fc7f35680062027a20a88c3fe2de501dac972f0296222e6f4ba0943a9d562771d757a8fd002fb032a8bd30f05b6aa0926e4a86c6f7555d3f1816c68db915d71ab2ef9492b97f0741be24e07108fa3e02167b72b5976c83faa4450b52de247f7c54ba7d0e65e44575a5a53bfc37e807983fad7ca5bba4331abb1aa30c1444e131b83af8d72e51dd248feca5e025f6ff0852f929c672c18b47d9e057def886f852ae26d137492d24f8a2c903b84d88b92a3f6679d4039aa4e4292374b66edef378a7410ac091ec61561cbabd788f090d418333794dca3f9744b25b9b8c2b065ec71e9297c0b\nTAG: 4a780eb826dde2371feaef229222cd73\n\nKEY: 71132f8c05cf95b6b8d9b650328b561a08728a8903631efb21a94e7bee60d132\nNONCE: 7840ceed28a572c5186f2546\nIN: 2a64b5a93aa35c427594bb5a77d6fd2d8c40d614f5e0bb495a909f3fa2323c248c94715fa52017a2d51c866e81aacf2efd74f40b7457fdf93af32c1211e675a08eb4330f6e24c35f626da6692bd9a13bb18c42e6b2f5c978c431d25be0f38352cdfb5933e9581834c33b70b590fbbe3122a9076e619142e8c698c78f532ad369447843c58df0cb105f8f35d4ed7909ff94a3a2b0ec99be03c29c33372a1b9d8a6ec7c38ddcf4dde9bdcf8f0d63064a5072195002b953b16d2228e71af3938f5402c24e4f34e344c26624519898e0ed1f20980e36bf568b33e332887610d8da5a941a7a1bd8b8fa8795014ffc9688a53b4b9a60f527ce4a737e99624e600de8cefacc246473c9641a1166d6894d71b9552ef3342cd0a7e3b0b", + "65df836c6d8786f34c851ac4c72dadca8e9753a4e6a14deba129f4e442a13e3c82d405f84e281b95afe2cb066a2f49c126ecf9fa440d6f9860fd450f7cdbf5c2fbcb5aa2023755bba1705de94305e5b304af4ae8bbc937c6f477d421f5d72784f9b3c331a1f850c4201c6459270c6271b8bdf00f23389acc7bf4082e7453c9c283d86e8371cf7b34cc9988005575c8e98ad34184dac039f04f84e5e8ffea351a3e1a51221abcabf06f7aeb97525b07dd8cdc21b71c97132f3f6f41e5e01c97955f4d67793e8f1cc5910a264efa8384696969680de914bd1acc9c7e9a278ccadcf8c6a49877acf2ea3f7e5066285672bca4dca1583e0a60b82b18fa564c5a7b08a2a0dccb9170602c9f7cfef98024267553955cfea077cb646f2b564caf529a5b34b83d8a16f30e2ff3905106e224444287f3ef98a9e12cf2e3e04a7a42ca30e6116834c169f0778cfad274d43d969dc100b9e1a810346d8ab715670fac2e647829bf3b56f2b7e26bbf025e74a3e9af4930e182205fc09e9fdf1a2ea0da9aa5cdc21a41d191b8fc189ee5ba00a744acb351cd869cebac760b315e60756112bd20239203ace94bc29b232ac9cb361e5b7aea891b5827869112cde2b0e2493fc0c88fa72e92532ff7ba77d5ffa865e47893a7452f0a4b44092caf70e02d344447b7dfede0aeffda018f898a8872c6ce3102ebca9e933fcaf22b5c855f620b240c31acdabfb7fbf109d2e9604b465abf43d64b6a010ab928722119625bc046c4489a95628612995957c75510d89\nAD: 6ad2365603e6682558c185eec6749c983be4ae29a8a66728cb39eb5e95e7f7a459bae5cab7e75c587689a223f2533c28d44134b87f22e964e73c030782c8ac4ecb2a62e3890d0d96116a4a3d3aa340783e10a46d099d601a8ece1938a640c1d12b88ca4ff89f1ecc75f46a736b7a4143b671f3fc531b5cb08c3ee7c02e606097b0191605d9ca3099c6707c590c678c8ed7a3471aea52fefc7f56a736cb6675e004298903b43a357c28ea4f59ae0894a8ee0876f347682403eb4d45881e04258eefa1cae28f5a646e3f91cc08a935cd464f7edc1721f5b4e389f94d141ca4231573886c40b7df4e5779fc52daff710ce9cd40fb4dd32e92250592199696a13e742ce90aa6280275ee8c0eaf40c884bd846697c43fcd7221cba4f98b03a6584f4792e8bc16c2029cee9b4e80c5f1c91eb798345b10def038cef2f1246fd148cfd2e39042228726cb18029b2e38e570611aa75c72e6cdd5110a7ed6f5e5bcf1d1ca5e1b67462b36cebebcf6e21df8168177afcd1a31a9e498bf7da8586717ca491292b0df81bdeea3a1789bfe70b489b1d4e1ce52dff5cb7e71c009d6888b152c644b959036\nCT: 5493a45a3f9edc2fd6c8bf53d3f11be1262ce77f5845c1d47b306e486e6316abbc78fabfdc7ee8da152ded9f36b7ef3ca0ba8e55fcfd865d449fd6d44c99f16ff0280cc8e596889d737d0fcd4211e1e5ea7974698985ead5b8def15a8779674a6cea0715525269d2cae64ecdd8870b9f1ec78d6377edb9c975565eeda60448eb1c871bef0d951514640cbcac4e663942594f0bcf4da56fc56b961464d1777a177b3355ef3b5618f247035761f2cb7dec1fe2bc2ba3f825ce545e51b610613bea6c125a347aea55f8f4f5cd5400e689cba199105170bfecc8f0edce6a9d521cd1707cfb5d12f8f5a9dd2debc5907d05513a949e102e7f29d5ff7ad22eb57d429eaeddcaa2915333f88193f668067a695085853f7be8c0af38d774b3d6cb4ab415d70df8aa02e7461803f597108b27d4838d58b1476c10b570c4f8fd71ed9baef88c140163d5ba69a3c10df451c12a5c5cf66c2ee546c6da004dd5d671946df34987a19650ed8ce9e7ada14f3213d642a9b28d0e376e5e37907b7cceb86d0403b19fdb48b3b732633d498d847c2fd24e0260ab74dce88818941c6f8d9e73daeb7652c55c729c3eee7137a5b80899b036eef89aa02bb730ec277d26bd6498e7d4a2b8208d035498b8e0ff403b2ccd0ce6e9899e984a062b5bed1508f23d485642843ce34b5a8322efb9af3e5c0797c2f519d7ac054304b59461866413b0db05791fa9f16661fcd3d9d86291a48cd61d4696ee685a9aca33b93eef112e2dc772d6e304f150042fb49fa95edee661617d7ffc5624b346a82847249c06ca6174d8a408ad46d3c3073e7815c5e86ce31a82587695b2b6c89ef52c20a0ee8adb24263df1a52b4b3bb68b6bf775ba0029b36edf2406c2509ff633fb4e7b28e0a4d5260d48c364cf99ba662b65e3ac150fb3039f1d267e152f569d708c100121565d72e0f728823abad3a1969a4ca856e9f0f4cb0315f973471a4464ecb348950f95f8efc5700d5f2f0bfa9e4c951a9f37b576695d93a8ae5f2d59f0842f3ea895fb38f0f34f56dc498fc0a5d8816e8346f90215d68e86e69d656b1283d349200ee4935ce5acab7eb08b2e1af57a603a42ba3ce811d8b8c6d6af9796dccf549276ad7183f16a99c61e0208cccc2c80507ece9c3c44419e01a2e23abe2513ec13187d54fd422efbfe17\nTAG: 975dfc03c9b1ef9a854d62ed2a0b628a\n\nKEY: b0667e8a6471d9f4eb559d0fa3854fa6f80288a03ac298a31f69168eceb6fa84\nNONCE: 3473cea023d2c6afdb625b64\nIN: 11ff8fdd9cf47bae5c529c6022638e9bf385cac0b72a046efe306c3463df27276fd63c88b771f84cc9a8bd3be7ea05df941502d7a437ef4a3ea22b2e4ab8509904f352b83cc3865c489bddc6340bba4f2b4c382744467a3ce3896bfa9a0a6a4f8d6beba39613df508c29b074f9f68e8723f2c2fe02a5dcf68965227059e2b1dd75bbe2b80f963cf501d5c73663204490fb843a3793c585769ee10b764077b70654dcc7b9b3fbe7f4b146ca8c6b8e164774ac3421fc2969445f77b77cf63ff50f04e2439895121f1b9c4941b7cadf3a92101cd9d4ec6a07d70d2742e6b3b87981e992c549691a82e250c0fab11bdc287ec357f182a6c2244db8b39a0cae9cccfd1fb32de73901ba3e695574477c37b66d170ecf64130df3cd94049bf9b3cb388907f3dd9389c71c344058b30091eee2fe06f6be3eb7ab6b7e269d2f33431a51d30a39ea8b280571565701dc1c048f07f4b5f9e04a8dc4555e28919acfca9caf597a394120794b6a09aedf866271998401397a4e8e11a25a061878f624f78c321bbe8149bb60887735fb3c0d96dd7f022cef066afda0ec9cf4e41a82c4beb6cb29715e6611562d15bc2b910f4edcc981c457c0c20bd2710668b59242f7547d2202864ae65d2cafe5775f3025eda387030e910075e3664006c28969808975b9a72c905c86415833a1d1d86b8297aab682420a036208839f9e811a6a68b5bfcd01c7310e4b05f5f77ba1dc08f18e57a2044b20ce84acba0450b9b8ddb378d0135f779b1286948985ddf57a7954cc1f21252a06270ae34adb052c124787ed72511f4dde5ab0a708df4b307a9cd392160ce24119be4eef4af0025ca4047b07593293fc17889932588fbb67e72382f8ae826eb9f0e4b866f683814adb2407353c851f64475da9f740f71ccd7176d3d970d8618febf5ade20dcf51918e8a08e57cc4c4278565f6c2780c68e43970968ad018f3d04fa375aaaa5cf10f1cf11cf203ab299fc270ac41a19929f831beb3a3221a429059dbd4a00bcf55768a9f89fb35c8c911698edcf59ba3c2398801401e0e0949dbf587509d9bbfcce3a8bf5023bd751811d25de25693a43f14b01011d6030fc0d3017bdf8be8c84a7c088e0c09048b88cf0ec74181eb904b91919947c57933e5e5ed9b46550c951113e8e2a0e06efe5fd5b4d182e33738ffd16f571cb126cadf79dbab4f307e\nAD: 86eed9d3e2f3edda6b76234b7b80f7dd2815963274fb85d776bce13fbc60f1db9199c3e1158815c15b4d1858dc66053fdd4c128397972cb9ec05c87d16f53ce5bddede8ee959b5af5f8955b9cc11a26e53b9b42855cd11b570ae35d85e1877264c949e27c6ca797f77c0e5afa40d0f2a08881820b88f85bcc59edd24963771e9357f66f874c11a684f7987d876412f3cdbd7b9b3a26008d551732d9964deaef66cf4692507fde97239f15e2caf990f59a62693d0e723a50286e20cd347e6b98774805615100f599f6f85a5370af468b41633b85cdd8bcc7236296c50a530bd238ca0ce520e8a29f8ebbe27760eefa1ec14f91d6b751b30bf67cdc762486550793b4663dc38f378bc36eaaf157ed6846641a7fdd07ea45fb1342fe04d700ccb0bc9acda5eb00fbfb4aa3540fd675364c0f8f119df2de15ec2a816e76248c11b9c3e7769f98ee8d4cba3a525168e187df2f548a940e097805d735109d8ccb6119fc366caa17cb46be148d406a770a24067cc9c8c40bca0b544458b47d0ce451e4a4eb9c23716666a965ff26287823a699739e5a6ea844cbb5dbc111473d88d611b906fdbf51e86c5a90a68f97e33\nCT: 0353acae65a2b86f88795b91e2feb614ab78a508c57854ce78e70667db42d0e8d1288b7e5b55ae50e95a1e3362b0ac3e592ac497791cabcc70f68bde6cb9830323bdb3d7c47d35684ae9a81dcf551698258d0d132eab80cd8926b71dd784f7d87f18158eee49bbc220e57f77c65258a5191ed15d10cf306c4fd22ca91d92f28bb0c602baee0bfe31de77350ad2637d3ea7f7ec04f4708a64c55bf0674dbbb4e9ec7e5ea2db16e3aae57cb3611d46ecc06d4796a109a14a0f714753e979a4b0090c99622c28b62680d437a9f4133dd20ffbbeff73e3a9b47b7c788abf42eaadd7b7284bce8b6ea4cd3bfdb2320f7f3016ebf3f06fe255555c44f95693db7de6470e27165e5ab0640e674c321591d4fbc941b2560a62a42535274d3a7f635c922416f7d9a5b9d22843fe601b296aba676802eb55ece3dc9315d27f56433821c18e760ed64d47b1ad6590abc0d75e7d078aba97d697358112347e39b15c3d21248cb839b23b6fe4957dec22b1e25efb4d537bb0cc8b23894436990583627acf4def3a293a4b9f03a3e8beae184f9d11b79d632797b45e972cb9812b91beb1d861c27728b5cfdf9e370f363a6d85120aa1c21f39e5d52f24430bcb019d328855d7d77082a9a331b788a3bf9dabb65f70c20b64aa3ad3625dcf5cc3153380ac7e61cba17698c387650c8c73db3e9988c10d093bbf5e0695a75772805fd5b2fb8eb7b0aa91b453ca2413e36b285800873339311b63a67bb541d7002d5db39b016c03522023ee6551195aed5154ffbcf126a3618c0431d707104438f2b8964a3e0602a8e22f509e390ecba15c999b14a677e49ca95251d0b5980bdcc7e95714fe28a99023af2c564defd802e1f24e544a040ea295af20e9bbe89df72169265cf183961e78b21020b863f3012c6e4087634bf720884e001ec183711ee6ce14f653fd483c0c1a2719b9dc9b5c64955ba8ff8d5755b0f1dad0d949800b1cca343276efcf6e7633dee3675c8812790fdacecb8ad1e458002ce0396a9d7a4fe030da5582b8ebfe390498407abfa4d1d6fd109ef6811d00f7cf422580f63b8de9dcf66d760bd2c925c82e521c9edfaaa6539e78be6acfcbc6a3183dd29009ea6b51f84528056061b010dc59789cfeff60c15bef4de847e6c3c4cc1e127d6d1176aff9f7e208a1bb70d85ae3a1a581ef08dd6197149abe068fcc5482\nTAG: dc652a0e99481d728e090f5b4c9a70b7\n\nKEY: 4b7b8c13178f9678888cf894bbae601f4d3869d6fe444db9b35aed803549b72f\nNONCE: a39926a47e0b75a7", + "71783631\nIN: e6ba553a0aaeedb236216bff95050ad4b259ed60c071e1db318c1df201f2eefd8e73d66aae5835fe869503783504d803ad07f2989abec14a443e3e935684336a437c83d0c95ce9759d995e2cc454706d24b810fee5e32f4120aab927911f7bf11a7d0f2150b1ca4ce7f216403f3a7d622887675278a748d2523af6305c9979deac0da24f4397f57f38c8a860413d6ab4581d48e70b4113aa1a963b3a97b4c4a599be2afebab197e5e41d148b65ad2488af0fb9cdc59222a52ebe6a0ada339bd8b8c0195fba21d46c12d57eb7b98ba85fc494863645b0b32d9b8b4391436e887f6b481d849c2c5f6afe5496626c267a3982daba9af1a16400cf81bad5c1398d605308427340118734e476d808338de39e08549482a24729190041a303f61c4928ffd7a3bb2b46c92aab059c8ac1dc4affe52c6e2d3d55ce623716855934e80d3d401bf4532505c21ac85b738797d08d69e424e521b479f407c7822e5e408247251538a6c31bcc7fa0484dd8a40ad34f0fb66666e143193c9cad455012c3345953ef63b13b3b2469322b7094e8140487c76761733025bac8d71c3f406b0cebc28c499bddaa34ee6c03a82a52e48a7302e5e5e5a3f660bd83aedbf1e2a88ca05db202082d8a59d11b14f6accb8d8d24709709210cea12a34265c3ce7efd84dc8ca309f44016d13ff653f253d33d180cdeeaab7370808e1b8b9138172fd96dac39588ceda91c4208a3707f90f2f336a2cdc1ff3fa7aabf010776833fcfe43c3bf19e9a480495064ad435d3072ce131283d38937301b29d0a063c3bf04ad6664f063462aaa39f1123a010d6f20487a6b12ea1500abfb655a21a4b3eccea51368722f105f94f642765e7765e71199ec5b59c2db6eca6ba9d6150c2e7efb8635493d19953f9485c7e49f24efd2c68d18b1302da88d8bdd26fc7eb6a1abdea09907c02bcd80fd1da76800f18673f88922ddc6eb0740bca0b70f7d1e6ffcaf017421322c2945b155f582cac5d6ae6d4e5411ab895b953a2eadc3224c4dfa1d8f9fa592c123c2d5e1d449c92276dc21711b101bd40865822bb622dd90d6c66becaea70fe9f914032ffa17dbbe16c0681c9359a9b156314618f887486974951cedc90dfe9c04aa845d3f4b4dbb60b2e3271c456487045133c240b9c415124dcbb57671374eb27625e2697021c71f5f51237def9d88fc2181b6bac76eeeaec365ce443fcee15650150e57f92\nAD: 116bf9c3b52f03b09fe4827b876bfa3c3d7b84afd90972dcabaa971b625fe750cc04188436bc374689249454a4e54a70f2f8adc56af2be48217575460fad76faa4ed3b74f1cb6d3fdf8ca28723057c75ff1e8a74f9da266e9c594fb6c921b9995c926bca308124494c868fa6739f4a6ac663db6312ae34ef43ba21a122deef296cd77452843649ed67a99103e1aa77aa23a3e41ddce3b9fc80e13b1875f31eab3f75f89ded007be22d438d4564fdbced99cd49b372b81b49914595d1ac5d531b0dfc38c6ee18206e44d1c1e25fbc1c027a152ebcd22a6f909178fead243083b4f885ac2af83863c0ad73921098519b56c81e29dbabb7647818aad5a8bd0e09793d6aee040bc9cecccb7e69712e5317ab75a68085ffa0411f82e385377bf1486d5d61dd543ffb20758d3f9bf04a5f97131079ee01a13878ef0c7f466e8f91e9bdea970eccd28d552f8a5f110fec1ff3749e282cd45c1caa6d06e8c426bc28b2a5797407f885b176534ada9720f0d8ff65d40b4f4589bbec0a1620172941e5f0f42d44283358f2cbd0a4abebeb346d01178f46be79a1551e0dfe1dfcaa0c305cf5daef3090c2321dafb6de0481c00df6937590165bb817\nCT: a8afc66ca05ccec231d39098ce3f8982dd55b80226a821f1a97919ff7389b464d8cfff1c65f784eda92bf2cb963e41ff5997ed60d23a80401a2a73a54ce880fd8c56284eacdafbad1ae72c4be9ccb761dba1a0dfb0983656b9749e05dad17c99fe2786fc21d3159f378db39dc227d2379f3851e94183df5c4cb858223a7cb43b68651cb3689b886a4ef24fe879205d0ccfd81872b6dbb0e7c9c5fdc0313130254f86e80d7cb044649051fe74425fe55e7472d396d8e15380386de6f8ccd303a9899fcaa63641f0e6bdba3ca3361566a2f89dac8ac9410032eadcc2d82123eecc677c7b16c100d54d8a297dbf30c6e9479278e513b500e74beba4b4a04038fdd68c96d5939a4041def41a6fb35510b86328cb2b8f6e80d9acfb555631acf856975464b770ded81661558b150b0896ac28f2946c63c9823c4efdf9595e867490e638ef495ffdd3045e0ffabfa669732f6fb3a4869b290006259bb4e19d49c5e88b02440dcac361b7bf6c60b09b5b597e9abde536b4ed29b1b01f386a5e18260d707d6ed9b67be012d0485fc6830c24bf4b384d2eff6de8b38b88603aaff7cb61b0812b4472a63758883bf5efd35680c85e4443b56e6f3097037ac92857ed2ce434cf5f28213539be251b28d3c8c5ee7c04dc6f4a3bf12ca24ce79a022bef0f4de9789c8dfbd8df1c7faf10f8379113bba9a3cc4f48e7d984f37c5626705c5f04c72e85902db3ee40dcdeed4156f68149b8b54722b93a926dd2bd546d1dbfedd4ea34847166fa4b6b325534d88e66e48aad81758dc45e461fe001a6e400b68d2974852950a0fe218933fb601c95ef818a85130c434e559997d5d534105441d0eaa142dad3e4ee686554c83128a1266c68c6186ae2a7935eb5a7dee455fc41025741a539fd84d5acaa60c9151987031f61cb3951c96b646ad3f9027f63768053e7a7fde524dc7bafbcca2819ecfb802cfa9367cfe54a1f0be9f949a471801b81d7b5d72be9d377c97cf452eaeeb243006f9dd1381c0e77f4215a8f4d62f959b83fa9e8012c121906f0bd2b688444da3e2377855976b5c68c888e0a244ccebc9f22f4051d030bc95e256fa95cf1e7a958a88d6fe5ce111b287c24e0e71e4928f7572b34d2f6bfce3a2c6fc89be7d54a1a7c222d5cb8fc3a108c20a1e1e55e6a2f3018c6bb2baae63c3cfbece1fe0959456c1506987fdb5b83acb5e4cd2112a0b18c8d0c0afe438917\nTAG: 21d5eb52605d2ac429b971fe32cc050c\n\nKEY: fa26696ef7a8128ca03a7eb4a199edccfd4bc1d653ea8501d1f9f9dd6c92252e\nNONCE: 2eebc2343a402e3efdf91f7d\nIN: 63416068044d204c941276faa61238721f7049662f3721f8d04c908cbb612fbfed2b050efdd69e018be0f463c3e089a063d7b5d9a2ac4eb3bf63599597e714c917c004804a689b2c2ec187b73a38d60d9edb3be9f99d3b452813a3fcad782ccad3bb63c89d4abd18450f61bc94314d9395415503724791a22d1af865d3d5f5296411b6d54bdc0e7ae878447228b2f21cc7ad624a69d56a3694e1a383e7049ab75bdd479ab122d2a50e595fe370041e8a5d9e28dc3b266bcc40b9d54cda53d4049b62feced54620ae0d6cc3c74de3a5bad614f1d8d0c6a74674c9071b8c0b96352c774c034ed7fdc3b8790c43e6b7be8c227fc2b78a381215d97bfa3274e3b52187fbbdf68efee0aa66d2f2da263a0dde580ff19cdeb2c29a6392502f589ca7739e8f8f585791a3f77c1968bed4a713fc5b94e8d3c6830c19291f9cd846ecca2bc05bf262aac54bc45409c2a064c3de28e79831c32f5ec4bcce979b885c9facb99d0c54484154d545ae67d4afaeb545b5aa5541dd0af3416381cbe075cceb49820ad0d52f68c31875169c126b6b1047d63fea674a0420ac808e2ac64adbb8412f8d03a6a5cea014c835b57267cc4ceeb10191df46642344f4f7c9ef9a5fae05c10b2e7ac41afd55e84c213e1d5f58f4c7aae4f0b16170b11b798e138354821fae367a2c17638f1c7d96e343014410c4b4c47a620f79624dd7f3a8de28fccfa365ea904e2aa625a7f3453bdcc990c5bb2d6b0b972bf3349e15497d71349e495c1116f2dfd9adcba45b1a4473566d8eefb1b68054aa7274d4e0ee81f8e61be7adf3c0409176f0b566d8631425835d1f4dba59e7c0d14bbec2ba93c6413fcbc3649b8886cfa6efdd27b8187f1912d17776c7508a54999718de52351352194a81b2b0cd83a5d16348f2e39f22d833985882cd9fd27c1ace4f75a28bc48ac2da52dddfcc4fe428e3f46908d68accd60a17f65e678fa55537afd06fbabddd56ea1574b50d93dc76d56b04e05629e2bc98021ef9107ed8770ae00f1ff294f57edb583b4b361bcc6afe3c545c14adf343f2d019a283e9ecee5505ce2c70206924d63c8b574c798ae0970547c1114f2f82af5a6bd4c1a33c9cb49fb126117d06a63375ff67f7091e6128eebb98cd43a698e3f441e80203262b47c82a65d9d35826794b6f647badcbfff169c53fb70c151dd0c57234dc522d47b4b8470652a86ac09b7dbc44ce8a90a0a2a9fce1b70c1a54cdf59015b89de2331253f6\nAD: 82257a0db5c6ed9e12ed5a54101524647847ad87fa961ca6276eb05a355fb14a77735c930fa47cc66887bb687b20c7518dbd9af90e13cfe622e9b0036979b9cd9336da11e88a189ac81581e7d85c2fb1fe3aeb32629e23deb168db993fadaa37b1fec1224188d4f50ee3b8f9ab567b8baf1e3a3d8bf807edba9045338ca14d26fcbabbe7d8a5a1ac02d7c407c17a541fb41004f199262ffd72c3d0deea8296a08af1fd7506e7b72f18a7d322e4116021bfd44dfdd4f6dff5b772ee32f49e098445e68b3a2cb58832d20486d5aeee424752b237d46f1cf8194f7a46459767d1a104f6d35a9616eb47208b8894d998a51519d514b689ac3ca19fdb1efabd1dd33cd4298ae4d0ff819e78480ab7867b2f4868db26c9604323edd258c4f6c977fc4d1398e3ba6300c37a9a13838ea9c5eb18ee193c3566ddf3853fffc0ac665cb952bf76cd2d35106b934f5f8da9aa6672e8f9559777ca7a56592fa536e8cb7be5821961e740483563e6ae2de1b98749752314cebc390beebd4d269f0deb0ca3156bfbf6973da50b8e4dc4eb2a03ee0bfe73f21b3b0f2716a4662a71e8cb04ab44f52ac930eef1895b57151175727f81fa074a8e5366d5b7449185e4829f324879\nCT: 90cc04db6cb6754eb81e088d126829648e5b3ac91b89162b3046635f95d19586eb89646d9412ff3c28321504696d8d8bd7567214345c1e694eeed1ab5e3648300eef27739ba0c286e5f6fe389ac4b05f13e92dcf747aff418c97726e7f0820ea4e93121cc2152d92f2711f64e7a4c66e74c21ad58f80218c292e6d152fe5364fd2b186ddc811f8418d5ee5f7a03ecf98e69dbef146af1fc4d7eda7c261bc1d4d3781ef2ad9a9b316eac55758f97a73c67031886e867d98e1f7c126f19e0aae251d92781ba3ad6c949e677f6f71a0d26e45a8bfbd9c7a8b8fe4d63e687a2a476683f72203f24827a0ebd3162305f4c6e180eb3a7bf5ece592af7831b52479021ab76223e7d0714e0a08d5a621756b84d977ac5a13124e9206caae9c6a2cba1257a81903045414fd6e2403b2d68f07becc2e7a130366c0397a406ba261dd800c647fd087f50702d25177d1cf0097552365cb9a729e27ad9c1e4a61031374d362e309c29f649c7774756c46befc17a7c403a821ed254fe7f16542af8060c5743ce91f6cce0ebc68072c305a1f6d0d97db2541aeb87759804e15308e2955a0e6110c3613495115d1066e3701102531e04c1128ef2dd4434850a6c808cc827c27caf9d2d33ce1646228c26f6d9e7a0d05363694198bddf4f1603dab87e5b01363b3cb4daeb0eecedefe2614bf6d09b0181", + "3bb0995615d06efa5172b11d08a46a577fa99aecb30e310e84bc3049205534e836a44fa2de79134e6e7d7fc6e19f841e3f31fd5a8c91c7251b7c14960e2efecb2945dd64926a3d7052574a9f8ffc0f9a6c62025f58275a4ce3a084e73c1094834c65f59e09d4dd16bc75e26810506f0df6e59ac486439ebae613356bc5d8245e15a2c0d8997d80235e7475f6841b6e28cff61d9f5ab11a718b7b60c125118d3f77559aa539c1f15abfb32126ef7a9104c6902b5f872663539f78b002aa11f2224f2b724e346e9fef6b84deec427a05576a51aad885e0fa15e083ff25a1f97b7968dcbbced7b5f3da137e0b48c5bbf783c7125f6a1c7f2e707212bd608bd09d12104ee593838842b127a5b8050a0d411417a5b88ffcbaccd32d1642ff00ba22e42e8827b5be97318bd0a69b06839dce80ef50ca43778a60dcd7193af7ba5da86149f7fc716c22fbcb0b1671b968da755f527dd2ae05ef2b6b8809ce38c9cb8b7095d7b3a9afd16284334da5f0d85b70068646f4ca3c6c39a2ea1d146b84662219827f756b2d1ec641f\nTAG: 8c7269eae0df5ed6c8f452fd89c09707\n\nKEY: 20261a84a5458cde6565e41daec0b05d1e46a6a34858d546eea8258a399ed89a\nNONCE: 5168b8e6c75f25ac1087b315\nIN: ab57ea5e8e39f743a826b70e584c4bfb2bec961b6769e2b92151cc1a0d8bfc27a9d5d9c7b43c51019418bb19fa882e53fa0f59d6761ff7ca75cf098f613086f9403a8a66b07bd1fde46c5316403de21d4f839a2e67bfecc2f3bc9c8f28b455f0fdb75f28a18852e6e44184e5c104a2dd2e21f429b46004a595ee8e2b008c2e0c31c12a05bb9de15011003d43c342330f5852bd3ebfb7bc4adec6fd7e3d77c1534e0eec7e2fade24d89fe42dd9d8b5bff5ad4f5f8f010ec0903b42048e8ba6f4b9274c6364d0119c718e6d038ed716b21b7f2297317e3869767a2b841505ae4aea6dca5e2b2813868faabd7a299061148f69b0ccaf4a555cb728b562bed9f66fc8d60be4c48c60504afadb1593078c36d54bc878a6a981ef283bab6f4ef6128f78a594b3caa6774a8e6246ca32e84a95ea5774b7c76599e1cf25b68210c2c52f465e3ecbcb91d609f211c12a737936d84551ceb0eaf37f92152f6e93918f4a19bfd09f16518004897d9f0728e9c1bc901fa85f8fcf77bc59c2f96ada344fb9a20890b74520a99e9241d9091742def14a46c524e2c494aa57c1dbafb8feec5d71247a6ac10db9ee768bd2f7cfe1f6da9fca9aab42da2b8e0dbc3e4bd36e2de49d855196d82175ac39516571d209cd5a8579b05fbb0bee133dc3379bf7894511cf88ca955f3ba1f794ed7abb0771d9d319b4f4db940963fdab1e831ae6d5c6daa96c44f3c2ce6fe2772d665a212d3203a593f412a557613d4e465b5eef977a2b62490e28aafdb716e7be6d040f731409c54e4bb38989349d842984116baf0502d21c910ac86e3046e6753b9f8771fec297eba18ed382b17fb1ef0eb20052d36080ae162e9b8dcf67e7e3d2add03d752f612b94ebf4c5b0f242a39acb092e32fd044b8e9ddc6abd0d10985c3b25ca4c9ba476d4fa55766f416d5d1cca614bd1d153432ce59e82a3a86b6fe830e1c0f9e64dbdcbe0457ce90464dbe56d2cf66a7eb6f43760e04a784466dbf7b153b2b96439db92180103df8f4fabb5734bfd661bf8faef2b400102229a9895fbeb1f89e6da6c82b5201055264fed0089eec72892c10fb2ffb4928cfa8df0d2c6680a5299899d521d43972ab8ddd613e074d60fd27a061ff821e8c410cc6a019cc0279f602582b752df3877915fbf14de225bdc2ab1fb177fa1724883b523faabe7e7da1d697f081447c406ee8a2c1a9f23cfcdba8fc0be440f2aae9f6fa5c35c54e7003254734947fb7e1abe7f8040289307d31bd6fe8e862a2d9dd3feb\nAD: e9073e1a183a740755059b92b0e8d8a66f5904f1470d3b04d98ed4a62b90245767507e54ca11afcd113960568c916381caf4c963c1d8e9aa4c7ea0ea5aff12af63caa8a5e1f128e70f3c1387b50757e43ebd3e7ef2de43809f781cd733193daa2eaa5dfa0c8b161e9e4480d92df163c2619b571f42ebd706d48a6693d4a5071733544d2d4fc771d7fd97941f83c920673f0b8d82dff24402a14ae971000c5c8747b9a10d32d622b2b1c3aac7cf9804be165d3d8c46d2b69bbd059bfcbc1f23dcac4bf5eb5fa92dc93a7f3b2199cee31bf2c0414fa2ffef1ea34ef109cf4e171460aec158118e3bb3a0a8a18ba60e48f890add45f3fd3193a47611baa3abd36f1069ad52ea464c10f5cb49ba753e43f9a0d1d9bb038e8d450c41491cb350be288aa2f95a479ea3868a4ce1f3265e186fb6c4f54e57f285576c6f700d9cf035d296d4519c6e31693f5e0b6437383c77bb2d235c0d5404a82515115cd260cabef6f2f020bfd20d2ee21566def190d0a6a76bfa14874565f99738fb0863054b4f0c3624b68447358da5bc47f195bb468703da3ead51cf02ea001c57608ca98328068212406b9f3821e98b7481860dc5d9533f2afb7f74b9144363e6f54032c983453\nCT: ac56114a0ed27060f87c7698d659d16b05219d9e013ff22dc90ad469646177feeda9b41531c83ba781c641c740c273a43cac138450eca6c9ff42a2d715de22e0c0e1954842230a0dcc887a42acf1fe75d204ef881af3de7733ebd84a3bed530b34b737a35394097db372f19953b5f9ce288ff8785da5926be93ab67de884d8ace761393c2d3c4d308964a90cc49d9a5a31e55fd20230dd71498d1875476ce257f175135a22e1df34cfec1f31dc788e7c00a483692f1fab826f92ff497253f9e56efc70244346e7fb32180cdb689c6a404c64e391419ccebd9034cab1431be1bb2bd4defe4770d1d9b0cae785592a28ecd3e9dc8993512088186cbea448c8b26ca1c64d623c2535cca60d92a3840a01a9b2b0a7f359d1c597a550b62eb6ffd3d454df319c6c5846c26ccb5ed59e0d3e58aa63615bbcdf4861d85c1635fac7756818a3bd47f5e2bf2b3d14e13ba409379cb62a1b2bb420870879fa522f573eb9b1624d5efbf67f92e50892de2ae454950f97e2b181bae56498585f3b19cd9ea603b6131dfd3995ea29d0bb99f5e6eb6bbb35571d6ac9e52fe02750b97f024b9328ec1dec6aa3a21e391804bf7aba5d3b7bff48760f4fed880259c43ad007208a04a20ca0864c47f9e56b0c969b8a84fb7eabbd58e0d91c44bf8a6ff12225d2c0768c078cb0bf6f0dd67977d801634dd8162500d6440ceee0bfa8750e9411d5a579efb30c34842438105ae2eae6430ae6a98cfba882c974f0f6c870718e4700dd9fe27b98599918896a600b3ee48ec41da20079efff705861c245d31a5d827ad148d0a75cd02b5b7df3484317ff0c2a0a600b22b13bb3b96f2d1c95a5884210e486763cf8d96af48c5bcda8c3ce650d2968981fb003ed3afbd43fbb06502b547f3961e6ec636a12a551a9863b9b89f21dc9485e62a43fc1059d65e1ccab12620ec3a98f2237294567239882c5183c596050b88c38f8be62b364e937ac92ce5f7f8e540af6507f04452ffffb67b51d0e336f57ba71c771c35febbece8e7b0d4eebf2dc0c43df1f42433a3c83a38941d6bbe12e7110f7f266cacbb6fb07d52618e4992a5930e1d416d6e4d1b41a0ddc4ab4a592096bba9437050e2064e0c17d1572c44ea52bd071a8dea305a9d633b0ee963245474fdbb3f274e119e59eb50b63b58fb05ba74242d3ef63cb3e3c98576d2986bcee85d094bd5528d8f43415f627365b08316c11abc433661b83a36129da0550507dd62051a8f5e01c043a04f849899668b3ebd468404811\nTAG: 1dc7ba2dcd3727f14ebee62ecdf66429\n\nKEY: 99a0547e21cf8509a0214ff0e5cb956130d03617e50f59e300a0ef211b4150e3\nNONCE: e040d46d2429ff2b38d4e35a\nIN: 3c0035f9d3eb509dcce14170381d68de8fb8f0d6463a2cd293ce08c958e186031a942315977a1ec5ff66e47bec07bfdaacf844fd2c4fa939c5a8b1f3fb489f25ca7b10d87a7cb6d5ff299a57a1b8c6c78b429dae9e9b1c1cec8e14cc3bc2119df31d75e9e5e3df7b368cf4a6ec4b324500d428ddfda32e2f330fe089494502251392e554599451e4ffca96fcfa6ccbcb50828840c98266a10de53f0f8bbdbe21dee0861224aac7713d8a93979043d1550895e06e1848565f5f6bcfac2faa3eb21b423215cb39564b8138b00a15be5392ef1ff451da000186d9807c48a98e2ec6b7e045a139902b920c5ce782b111b8bd44596a7ac8f468a6b718cb7679d5d420f28510505a52004c412e6489f586d302939f3e007e320a0de6cf9d4ad38cdc3c852907cf7a1a083117bdf3e1bc4300befa1180f4c019faa73bf31c43bea814990cdd01b17b167f21b5de9541aecf6bead4bdcaca96fa390aaf6850a54a4293ac4460de361b3d58d5eadeecc6b5dfb57a36215d03c85a4805ee8af03df7627d42479357724349343862c960061c33abf5a9a8dbc2d562f3738f2ce34d68340707da09f78ba191e230521c0ff28c3c285075832c00e326c842296e6a4ac56946f4248364f49aea2a19ccab66841c438df5ff7834ccad859bfdd89fa9af0b99214eddb37dbfdefd2a3127354843f6b545f729391e0d19089255c9e0aa9bc0da87d001445c7d80393d1885f759fa8211231a50d1840e7d145899937ea7af1a3b963493fecd40448383706a33337ded7c51b4fc118a1ac975a4071f26a9a30a0976f369ae3a9724b05cbe75fedf84fd1bb6e77e07a76ceca71d5c035e61181c50e2dc976fbc64e1f4f9e6e12856bd3597b475f0b6a94e559477599a51bef1fb3a45106fcf0ca0468117274ee4e3f3f489e3a4ff9f6279e18c38928a00976464431227ade20b45c509675619ccedb4f0b24c2ffefd72b3fdbb3ccfffc26da5945a3906c8824d17a930633f8208d6d1564d5a69c4887812d91ebfd18d482470220a338de30b9cd7945a93460ffaaf686a31621c86b4620bd24776a54db32bed6809270ee19460c34bfe99c7fd18c5d7e9616efb6a156d4b28a0823df5a858a096ec388e2fde49a2c8c071fea73a23dc4dfddf751d100fdc57e346c9e690d2ab620a0dab87e3c1fc02f5f727eec6a1853067e7bec923dfb3c988c3e8f108adf1ddcb9b8804e7f3e9fc8191d059af53c95836314f0c933676044b85dbb950c953603589762c10fd76dfe2b301986468b3f65415badfa5d1f0c0816c6376\nAD: b96c76c847741396adfed41fc14ff53c3d1745b70ce64f18fc2fe2ca445a7fba83780e265b390c4058856bf8befb36437abcdc25a758e77e0fc90971fab13c77d76751e19280e43851e7d39aaa0aed21bc32f7aaf25756111cd6ddc6b6f9b8d15acb4a25493f247b5bf134b2bcc2e5c2f91c78bad248357f18fb3278811e045a59170c9f0ed7f58707ea78c42e69a912a8321238ee63eb079aadf9030c4f718decddee4077183a2e5bf59a2a1eba07b8c4ec35cf9fa3a37a5c332a14c3711198f2bc9bc686b5dc6d3d7b6de1a8ab00b1fefeb107157f85aa8974c04edf757974a757090f4cadabe2283a29b317a831d8ae999173f07be4b4f665eaaa26093fcdda81fee6e170ed09f2944fd40f9f3ef47b406db52a55cc9350e78364e64220c9741f8e41745bfc1be8c6244c57f15b1912e55c6711ebaecbdae4c08c70768bda7750f142cdda19b298607e75688eaa8fa8f47f7746ab67442da283b1b9b9d12ddff796306cd690c0c32615007ee840844c7da285fd", + "f56f004de5b7965450d48fc97a2cd2b774993a2bb28868fb241b051341a727fc12778baf3869fabd208aa3c55f81c247554d11eb5d847123a6ad3b177dd6ef950ef4371a6c0c294ecaab63beff193aa751ab480e\nCT: d560de73e9674b561fbb54c6e4267d3101479c2fc269745be89c470109068cb01c6e3a4a7a9ec284606db6e735df2269ea16863673fc35c911fdd6201a1baf9e0b562a847274c2defcc0fb5c165662d0bcbe6b01fe595217d482ddb616ee87138424f5438069abda9dcedd48b29125937e3266cc9d468ca38fec9920ecc81952101c8aff3d3ad2ba4953bdcf26642311ec8c4a880870bc81ac647351a49183e182acd38585cafad3a37a0171c0a0545bb3ee6a67a2da41cdf2397c529064b09dfe0105917e1da7c3df24d2dac6bf06f58efcb38752ffb79e93031cbef73e6c0ad68fb7a192900aa8a23bbb7c6bc15fba8d80058bcf9656323da4c10f19198d9db3b42499621e1d60de8a16046853fa03b783dbd076d0f51fe40e9ce60f4e22aee657246d3ac80913bd495cbcbbaeb778a485bcc6c596af305429afa5f09736e7a78b335f484bbd70a3359a7aa2f4c336f5780f3186fd1753e4673e5234e3f8b803f4199bd859d65267857f8e0391b4e8253fa644a10bf9f68a664bf7573628490b1baa17c23aef5f0414067d2186c08e27eb9d1034aae6361054f2f9bdcb877e72837c70816fabf38e6976c8a5b20ef3a150a5d1ffc997a248ae199d598a01b5bf7da1d6f7a57f982026527e950f33ae33cea9d64e56a3a2d26ed2f2cf0a5d08e6a03db5c483aaa0049514e013b915056c4570c4606e6baefe7c6a74ae301d7b9b6b980d85bb500c8a61c05b38e79db47d2d3b88db098737def0d995267c931a2ef21bfc0d970652a3be8de5f42c20fa43e1f7bbdc34b3b5d2fbe3c396037fa885ec6213748de5a6b64634757aa519573aff1cb78a3191dda039a3c64940b816fd010a584a463cc17789c732d7a099fb423dcc9c20fa1c0f10436bf67f9796c1bab8c85ed76c2cae84ae599f7519991367d69948b757a312cdef01c535f1172ccee7be47fbab14362dc0f3fc89c7a71ec9138b40eec235f585e39b008d1f29a1be9332b2882f6d053acec077ebcb6393ed1dc46d069134d2c37c7f14c0fc9f9e280a6e2598ed8a070edcf9b79a042561dbf3666bc49863c29712d45c41d434172649baca0c2b43e3364cdee11f9da14eaccf8a853998a2a9637b268b6dbbb342575481c37014631180737f970fcb8b8fd5050ebbff873b5bf124b315799c94da41b8b5a4d57210c4edc26ce74738b2fda9c02b3fdac251b2b317d8edd345ce4a3e074255e8c49d8bd02376ee2aa194513963a220529e6c14611288b788b68e74f6dc206ad094e322fa3002d62101dc4d572ef00c1567f0e7a4\nTAG: 799c10bc86be84658d0b03751a29c71b\n\nKEY: c6e78bc1358c72bbae8fd8dc84038806efbfbca520a9bf9ea1df8ac365a0a95a\nNONCE: 9865ab3b3556ad8da691b079\nIN: 26db63a9d188d3f237aec1f8558702b0942b209f7e6096b79154d2eb844b05dea8c81bd041962e0c9e8d1c64cadc5a46c2d8768f57ffc27a1d5003776acfb5f51d372510d26eca840dddc3fe79e9414bb76aabe249c7f89a43050b85dc6b5b9e13aebaa98aed4cd0816685b20619fd22c860317b1ffec8f7e78c36224bb3922208dc25d23f023139fafb2264f9546bf57767d3117b483807cc5a1e0fc2c691f3891f54897b46c01b6f55f4bcb86af20764bdb9c7631faa5aaccd555e68a86a9491fa87718d5a9112e4ee3c2364b5f339efbae59db73eace1dffe4439a64d1baee99e6aa0fe380cf686aef739a456ad66dcd149ba8ff6767e54b1a3cc645b245c2b2ab3607334af0cbd8847c3931b02acf12209ea79af189fd9c6c01871650a009274762d07a4ca60fb9a31adf4c877c73d0819f4a97c0cad91ea5bd7d5c8ef59b35f2b24060fd8c6b4afee8c4758034aac99519757ffeb6fcbe40b2783f4aedffc9d0da49f3f98dc25a66f2c6695b864bc40c2fd5511c7fe681d98304be4c3e9bd7289c9caaf6282f7c5c7ee4efab267d7d746673049ff79ccd7bd019ba994417e22a67f856310d8abad147ce68fea094e52969f9738ed6cf9cc9eaad35612400b622da255c9758d42f52dfcd12cbb53bab8c9884eb83f1d2dec7faecbb6af3402bf462f965e2c2281c74421411edd762ea8b7b6bc4a44132c51c2db09f47a03ad2a1a17d73ad2a395e6762cb077a8be977f3925ec333dd56ecda27d4d228b1832196da7755e48517fa0582abad802b62cf231e0a2748b61855970912e1fe92435efcbaf5fe34ff2c0f90113966704701337ec6c0434fe2c36e3300a4387cd0514ee01e31628b9879fc666284150489282c1083079f8abde0a2e500737dad91b3a7c4ec1f4eac35dcacf971283825a37b65464e7a8fd66e2ee6721d4a118854f674edf89d376c0006fea01d278b7985237e78965f0987404efcc6576d1fb28db9f7fc1eeaa6b42949e11dbb0c137d501ff08b34f0dabb7edb6900c48e647ea0cdfb4c4ef3178548a592ae28eb119f1dc7b2f6dbabfa2ee4cd7b7b117f1f90af318e121084cd6b93ace98ee7750dabda5ce2b883f582e7c5d91ad42e7ea1fe8454a5da83a169c32d73a4c1c185a02275b4ba921b071ace5fd34a2076b226d71c229d8be6c58270a3ddb04a554e4d395df00604dba7882d89d9048b3e16c692e636c724580da376f8212a6b9c443ec303fa70cbb1994d12a1574bd93b946c1a005df40a3722fe2c2e7fdf51ce2b895c6cf07d893a41a33a6906af87af0abf948bae5ad258e80a0fc0afbcd\nAD: 770a8a32c90e0949a1151e20e81cbd163b7d1ed843008c813ec3bf44d363e37ec41c094458ab8f7457339a51810fad8d63611ec1a93282c301eadcb4bcfe4d0b370d6f8670516cbeaf9b361c92252d14e062bfe2e63b439c7d4b1d65dc8a62263374d718831fcb4bdcc0bc59a18530f7dffbecc96bffae9e0214ea7f2a319e5c07dc0c8232e7863df7d081a3486a1378240a9966a632c5e73fe4800481c4f430126c4b5ec71963c08d471e01b6296b64a593cf78f108d2ee866af38028e3a4571f5582207706932019646a1476115cad80d0b20695c84131e11cb9689a6bfc40f820e96bdb151adacfe447f06516dabb2f766b8ff5619a15efed41650211e4f4e114ba0b071ae0a6b635bf0e1cdaff2a2a1517e7427f8f1c25ad5d7cbdcb433987a25a2962130299f1de3b68503fed81c3c98dd774402bd83809367ceff45958e7627ee8dabf50f6ff6aae34a8c7ce471c705255099f602c2792468b5e8527b74948f4871ad5296c5c50b8d4ccb6ff8c2f44917baa7b70aed81302624fc405d3c550791ceadd2aef796a0db59c01a5496ad0b72f7a90ebb1eb2fbb2cd8d8f09a2fae46937f27a7a9c3cca3360b08143043d378c450de9676a94ea5b9371cff1fa3b067069393331324c7d283bdd750ca521c\nCT: e6ae771db203f1e58b0336c9c655013940053c2a40cc7a6a27e707860b179d7895a16f7a754c2cbf2e0fcf610a3ce97be5e7459cff4684b6b2848f2a39e6c4572c1d7a41f23646eed5909228adf1052adb34b9c44e5ca8b2bfc18a80675e29749e72410851eecaf261868b6b69e7d9dacd5f019de1580549fda721e383b86eb0c51c2eac4600a4a27b5f663a7c89c81401fd452027819b93281b559153c74e5354c320cbad932cab5d261308e241e85c0967a189de09eeced69c834b4c64dadb9447a824bb38d8b8a3fa4128bd8392cd34b0999b4ff0511bfb9fd434a1a0bb3c507c2828d98ecaa9f2dd5a020320f6f31324fd8ba8c175db5284628d1cfc4816054587a6cdd5f9e6d6de2cbce9396e874df36bcc347ef48ee9e6ef7e6cbe976e4361651cf8f92866cc3a54701af59ba03fb8d23024d6be73e1938836c31b303c687c28b1785c5f9b97f3b09b7ec3d83d8e38dcd18c3409db665bf74b85abc540f678bae40157eabb69332abb9c47995f4c412a04f9b99214581f1d18e0662e77a2ef6520a23b5a031153d5586f169923dbcf08d403e37184c5f7977320cb33b8a0d5d7bbb25d7a8477054874a14e3d34b92f7877aed42f595dba8830757f8e92f21d5feab414ecc9e3933f082bf46fcebee2ce5246c2fe839fabd94d4f6bdf875cfa67867f9376281b1e5385d1677a595b018617f44c6113f6178e5446cd28facc9a53bad29cb5b3a3b0cd29186c24339ea008ead440041c6bd0e93b92ab37e3692ed13769d147a1be8335feca11a533156a3e416908d044a5a74454f10d3e59e5f9868c56c517ba1d9642c41c6a764e74540611545ca90219ef4a0db0d25e92196d700f4e57a6778d20b6acf7d1db8060ab534ef409fe35c30c300418641368f0a3ed2407027c126e967406809524860cd88906f046a069a22245d9b2065cc5fc313a7ad79bc7035cb681a39387493b6be51c813748c008269f0681e88616ecec8a01416e4ee8b7a6e4fae2af9648ebb89523434eeae6e5713eb8037bf173e467a6da7d6cd3d357e3962aaca14c03b04046a4f893106e199062360217afe40f40214d28e87eaadc175ccc11d172f6cd42e97c1f331e246f7660fe22717d7f1e24752b1b01398e4c8bead71d8f6aa2d230c6392ae21d43bd88258c1219d491b8de12d53bb9fb917eecb0c254a4e9007f789699de1dc90d35250c6ec4631ced06cef9dc0b0416148835be0be3dc4749d4c2edaff37d7607c9a3e872f723583a1566ee1fa7be77b848fbc4d741ccef311fa5ccb7c18f19295e53cd1da935d663f0b26f776db6d479b4cf3d\nTAG: 4fb43763c09a6af54ef7103ea40de1ba\n\nKEY: ade6526c970a82fffd925ff945be16639864e4189c3269838d3268264b1aa586\nNONCE: 97121394f11a1b1d9caf4e3e\nIN: b2d855d51392454b7f4f2b6f29f422d111cc378262c986e3117e81f6eb6340323427389ba2d174f4edcf5de47be0b3fa820783b8dcd35f18451f8256d6f703bc16e666367c93f8db0be18c98d4e93dd6db2f4eef2447cbde251fa226ef4b6c4183d06cd1090e46cee182743c1573b3fc885e9da0262d715dec1d66954ef49c3a7d54f935156a51cbb1b837229eb5619658db860835fa5c926e0b87c9ac50ac76fa6696e149127aed1b91bb623d232da5df30b9ef43b4ed018f59a803b995748e941adb785535d69b8eb9e4ebad17c4e2bfbe6d2706eaf90e29867133b4a58c3e42cb51b494dcb197dd55862ca0f274883686b1e492b35cc20e2cc6e531c15bea94af9040702513d7d929195ca34266c38ca79f3f5b0c06a1002bf40770fc223be269945e56f11a608276bc4b82cc228248ab46acafe801d330c28039f7614e59cae505931ae9fa387768c2fd9ffd537a0704fb30aef78b1be4aaaa6f7574da1274d3e84dab83297acd00885acfd32300a36d0e8e5ad2777e4c0f718f91564c60ff117e17a8c57d2a8310fb1fc62729720728f2991b4d05317537883f016711e07ae1b3e6d876d52a44bd246c427587fb91d1456711ef0c7970eaa33db3347397cb76b95713919c73188ce13a6a292d798844067c0302b243593177cd099dbacd5f8efb412a95132b8ab31815dfb463451fbff63388d8dc46c29d2c1fd937c668025c833d7d96b021035d530fc404e1c6a3677b8a318c9a81e295c12c88fba75f1e17973732275846ed9103287714236edd60bd9cda0d4cd2695234bc69cd09e1b4db3cc73461e524e0934ab0cbd730a46a67b36", + "14ff4973bb8643ac7d555a8b764bcf87f0bcc8d19cc9ddd3fe27a376b5a6affbc95cc6ba966f8ca697c5727dd3f942c4a3b6215c00bf37c50bc95b1e35dc762d8db2f0f5d30d9b35ddf005d8a89d2b106fa4e921ead057158c3fce0bf1e6e10085619777bbcb643b5fd86b9b39c1f11a68cce6115d2db8c01e6746c81da9dbea30559b1bbc2457c258955f2d37862fc492b4f590fdb8cf648707b17a2b613c5f08dc457a1443bd56399e34254c92b91093ea0208a98189429147771d1bc49296a070e052af3fa195f612fd2487eb49ded95f2c670b3ef23464684f12ae66f02d886ba14a360a852b9b84f9b5590a514701fbe42299b54b9e8c1e7b83c7ace9badd9beeb0f88707b79da375aa7c2eb9623c7a1c553c521a9c7a6a3e73f0d7cae3f95362d25f6ba2313a505a90442012f58f6d9cc55563a1e1026cc1ef0e69c119dcc4577eb775f5d1dd60cd60ff5b35dce6eedee48f80d33227f6354a128f9cff56fe1340067c9eb\nAD: 20e24e143b9881f8d646947b121df798b4917bc19a76e96babe9554d9617b4f092471baab93ea7ebcd8a05cb2d267be93b4dadb29d4ca937238910180ae497ab4c7c4b234661293c8cf7f2b6ed3e0a738ca8ba0b558fb24ccebdf3b3e9714e6d7b50c847b72ed81e3893bdca85bf46767335b41d68b62961f3304003247ed25b15e3e54d6942d35fa24b7320355d4e8e038ddcc295bbd6ef3b24e9332a710dd7ef673d3cddce10f683d0ba14dea984f61ecd580a684f3bc97cd50e14b86fcb2024367ea4e21a8d01f1aa6993a458bcbf1279fb45ec4510a9295b20e82cad0c79a5f61356509be41525bc938fbfa09306a94610fb9b9c8bae1e051bd6fc6533b8b47bcee4a9b81b492e1295c25ca91b9b5898487e468d64d275f52a6700fed0d7b593234b3e0010480e12fd8f5d7999c1b8b05c7b9dde7bada3cc6926095a8fa8747da64db55ebb3efa167b7663f1cb5883593955a2252586f942c8aa3a1e12ecbcc73e1aa5831c00e5e211c7461120f84d4482033a238b80016d71e51dc297043f67877102f69d7bbdacd03c1896bc24cffb24d4529aa7d8d4d5e5ad3a990a36e1fc84c7f8e91fdf2119a36f5b521125976ac9ede1d1b74e3a31a9428cc36c94e6b3a34ca1ddafda11ab46cb4501dfe4b58cdf384576d651b9aac5\nCT: 0d8f126c444afe37e40d85b6f0c9f02b2232faf975d238cdb227a17ef28e18afa6d88d7d23b99826de9f6e7390f67c2ab722e1be3e5d9f3a2abe41e508abbd22897ec36a70d02fa54db8004fa3dcdfc729d58ee12ec5b1c85346289f2112c059ecfcfeb6e4723904ef1c5e3bd123d302f6e4cc393cf62513cb3e2df3ea822692edd0d8533d6103f22940cc82116c4ff1e5121f0ceb08ee581f40ac68e23c7e9a168661e6d93259e614a3f962fa2ebcfa3a4736f3490d401afc9e6aaa8a8d00ad6926b3a99c6cd2b3b05767cc5b45901d0c4301a68c0783bf1611e2cb95d6859293b615975be7e1d829f13eb4fe601b4d66af3f28171b02d09f820dc77ffdd22537ee2ef0cc291f785c466ea45a0dab45e782e7ec3d4bf0622680791883f89f9926009f6b6bc3fda4276b79d5d9070914e75488c033d47c58defe6b538c58b106fdcc8957619e008f6b508a87d85d4a46364535e76a890716a215fe5f2ecf50d8fc0d8f68d2ee0345497f94525c588eb3d21d66caf1cebec2685020523998cf6e24b5fbc384c32cad31a2345fd88c8b820276d5917d71e69d54b44ff96c8411f1a7b6267e20d67e35cf274cd9031dc157d5638f5fb8faebab2f5fc976fc928bffd8b60ac8d8932b8ac076a000675cc05aeb4d8306d65c6060a46bc200193d56249e605a7b10fa28f7a04a72055cdfc6ced9a220ac50d3c36ceb4ba5405945307f2d332a9a14487d7a74ed0c379623e2fdb04324e515e1d5ede3af27fc5f06baf8d354f6b68621e372347817cd3acb05df1817511c978537722f9a4967db31d24336704d8d7f974afedb487ffc6e877bb948f0c30fd64be7608723eb732a6be38394891e8cb789cc9ec2e09b8cc2ca76b56ee7e1d5e4c0bf76f28d705c61104b508b1c4c7c1a1cfec10f25676ea55f73c95af3fd34bcde939652fa91f5fb9d8b783dcacca1332230e2104cdbb905511e8479da129ad64acbb569809ae2a19e71bf7fd6acc18e7087bd49997e3d57eb19f30afd1a76c42ebadcc7f8d231c0c28c7a0850ae5463d1730def54c24a803bc1e889c0719e364492cb737378f7390e5ae506d36a7f42bd86a6184cd6cf0300331d0f54cd6f5b53200d59eeb8cbec25830eb74b0e1d931073dbd991c8a818d9d7f2b8691fa2b523bf73d9c7f101cb1d83699b9f5e1b3545f8efbb8eea286728045202ec8f81c71bbbb6e888698c69b92563615ee7d07f66c2495cbeeaf15825fdb3a3dbaff7347f5b52f6f886d80464aeca6e35cef31b6909bac29079ee1403f53a6ec45204694e967bcb318f91f4af5e868be46df4082f4e77c627bb34b017c0f9d9889184f8e88d62613335\nTAG: 3350bc1b6fa4c20bc1c0a28bc766778f\n\nKEY: 32fdb97a8841d0bf58207131e0c55361d7f87aa4c8eca24c999b7a74ec23f9fd\nNONCE: cacdf99a3852e9ca9516be08\nIN: 987911d111d30398b1d730d6c7d0bbfcac487e9a810a9a17ebf0bde09b3dd7a9a430a3bbfe41b3b3a146fd7960870b1b28db45111c71c6c9ba731de849382d679ac46be434e2e95fef2b04ccaf21afa763bbc15e23ff44aaff7ee793941a8954e42917f759ffb0745c34e9cd324e9c527b6560e52007e46ce0d46aa8165a0e6885e96ff7d6d84d186b313cf7b726213bf9c3fcc3535be589d336f84925fabe762d14ad033dff5b7f39f5948f5f939bc345c4db77d9cea9cce1220ccfac396d1e4201780f8d37c6167600a17c18cccbec04f605d86dcbc3125dc3cf5b40039c3dec4355beeffd72ff221a4de57f0aef322369c1755468b5748541049f3f1d790adbb460d78cbf5e3d2787d5921f598f3d9a92ac289b58c46edbe1c64a6cb2a796aeb17259a2569af4c19bd69da1018352b63b2b3a901bbf0c754ed3b0609227644fffa7a997762aae36ffcd700089d74cf3b9ec2f5c9a3908ace5a7048c90ed8d775a88693742f5738cf2a791e67ec747e31a1387f0c0da3a77b28b720bebeb7a9f6e76d0454f79225514a9d0d8e488a7cced170b4b89b1b39091bb470832e3d3fcd144fe86c661ed6d290c4e73fda61c708004561dc71493c9dd4a66134308577fb7cce84891458e2dc4581603898bcf74cf5da7cb1f3590ff570ec6e559d6f05d44b6e557031ed28b60f3a9e73293d03f57c9c636ff9336cee086358c15ae3d5af075f8d9ecb494b00aff1dbe9703c80bb669b522a00cfb1c400598c6b494b40c87041a99d461017ef4381d3db7df5a017564ca988018c4f36282213de60c841944b6d213d8fe2015cd535184b1619866106c39a09f71a70f78f2cb8fff2f377d87390eb31b73db093000006239a8a3494a563618af189ab3af3556050b68c4abf48cf4d02013f9ed69b52d8c6bfd5188a56f4699b03f60f218539a1638c9890c7a77f5bb18d7c4ffe27314461a29c91526cff0f713a9be95b608a2ff36783474cc9db1454df62fc7efe08ca97418d982d74555c0c15fa671f99fa73559ff54ebd092756e7d9477ffdf2de14e1c9d4900fe401d1fead7fde27cd37d016cdc56464f76193af1c252d4efd60f6f3c0644ccd1ac67d968140ae08db759aa7af205563d4402927cb791f8cd845777043b975ddb1ebc66be4333b7b60293952368767aab30e1a52e1691a35f684c8587bdacc8b374963c1864619ff4a204753b44860f595ecfb275dd0b94153a065f3cc3235a7525921d16684524794cf45a9902364c80ba5649b90c1b42ecf2f17c4e3b7a888c6a2cb30240c6baec3170b309714aae3005846a19c6292e5b7d2772af24f14bd7f6cc7eb89e0489400b4c18b9372aeacd92918e4b2d11165f2de0\nAD: 62de882f42ee7c4b5ed2fa54f66d0b4dae63db4d9a777b404b1befa704a48a3be7b8511fe716f77c890fea23fdd05a9d4a57eb0f130d7383a023ec6668e6714f84337dce5f8a9f46b9ba17480288fe89752961c6e7cd6d32d435c5930d5228be9aa002f01f0ddc79bde0abd76e4294563d5410c81c56644620a002a7facc871ee7b5fc73ed03ae0cd253439688cac4e6147fff75fad37ddd52971895702dc280273b8e7e99f8d1e93a2712bd9a6515c9b1dffcf7800ec13e08cc732a15ed3c51ab8177b3b1b1dc25e387ee2d0a69d7e2f7f77555bdd75a75400bee511dc5c30aa7eca46b05c9af4e94adee1c0bd84085af86a85a15e81d607ffcd6f7670bc11705b46e43b6beea7e1eba5804e24229185b15fc1fcafaa7de15ab336fa2ba7d94852f20de7543b4acb4e75f523863649578527752050bebaba444fe6b57c0304cc4820f0034f66b778d907264e5b8c8c0357648875dea1506c00413109ff2f25d9f1c3aea724a5b7f39ea1b08b9329c07dd8b0efa2e0e6fbf3f04708b833c2e14b6f5400b4b3d6463bc256e42c8a427f7a0d8b71aee9825169b9613dcbcf7cc364a87ba64e60501bb01d8f55eb5141ed945666f69b536662705d12f3839c45917ab7c932b8609a97ebbdf042fafda951753abc765002ae60eb1c9dcb2f95175ddae0d5b34\nCT: df417e819076b3a8ae2fa8f0ca968d5be1f31c4c44d02f29f9f1f69c8d2c269835426ea9735aaf95da0cf92b45d512ee8e4b073b40504cfbe9efc62770a0000706f16f7cc350080e52da3501675907b2f657091c1b5980d22bd7dc519203a80c674418500224900d74a11ef87d9f60296ff5074674552263b7b6b249c8adde311b98b4181a3730c101c4ab9bd29c044272751197498e8baff4a8f2558de20d4920ce21f4dbecb64e258d078974dc6c2d574ebc8c8ff32505db2ccd349e82808c44eca7f4ade2ffe9ab1ff2815fd282985a8de28147e547023f0254105d2d35aedc5e2083bad31e05ba905c1b3c53f354aec095add4c5cb40c51adb6a2c290a867ed58b05b14170f8cbaea863ec74a3abb66baf60608721b96c63da4b4d966d1291a3293539ead11167ce4e45f0f62cfef30962d2c979073cd7d0e89899397cc0ecbd858da7de3975fce6ca3bd6759581787c5559bd41dcdc177f6ff4a5cfe5b82236d467f93abf5b2abbd30a90cb25b4ae6723c92621820704542f9d5215258962c67ce9e9e2427c58b5819a709488236f12c1f2a7f5c915a4cf2f8eb3c103a4ab9769f76102a8f8fd73aad7c7b6146768f3a3f53b8e276a8634fc50446d5e0cfaa589a4a7fba9a8095f9567506dd6d2fed0c1e3146dbdb74cd116c13bc5a7ace595a2b42e0e3d46c5232cd92799d6ebfbc06c9d0536db35295cc4f7a7a28bf8ef3c649833d5f330196de4826462dd418f95450cd431454cef7afa6f2f4294ab69bb3e588d3b9300a593ea80890e9d678869e963e75bbf281b61f9f7cb9a3f9a773f2343ea306bea4609b03df78e57d5b9f682e0c0b10b57f360e1b0b9058c12f653b3e1fce60579b7c2ebdbedf0090fac36e72099ccf58d1bd5d7c26701f29f656261e8c2e7d5ae97b224293ac133b2cbee65401f8d256d5106c14da8c837ff48f2479432d5addda274e72ef5810fc3a42ef9b27e75c89bc4d72d6670f855f228609eadf8dda76ade9804c642b140117fce06bc441cf92429d2d3b03bee775c1a52dc409fa4e7a5d3e39f9d9a250a288a29c9de6abfd0303f676a98025a795", + "4fcaf6406d765a260e08ae5948326173f44f2d7cfb5ca9777221f0c984699a9cd1d20c9dedda95b8f066736b372d23116fffd55f7b03d4c7f63a8be3e7806718fa6a961a68db681edbdeb4281c0901c2ecc895f9da0cb04cbb03b5f1323e00c827dafd4d42ff767ffb7531e412d5ce11e0dc469f7bd87549ecab2ed21ee8deb164f67e64bfcd85d858f79c20c8bd4c37d7be76ad6d3c040a3a27c13f70f14b895178ccb02858764e315158ef6cdb827b69dcb24a3f54c2816a75be64496c139d541302b0b71849fdd92e0b83d\nTAG: d8f838951f98deb27747a870cf55713f\n\nKEY: 4a78b60c327676e4ca2ac1ab5333899dedfc91f66f4f8ed83130f197a6f35def\nNONCE: 3e8e2c6598e6c0a8ee6b0da0\nIN: 1dcf6d8aa5fab8310cae71d02d2ebbbff4fbbada8a7db0725cb2e20723d2a3e5471d05b2319f571ae68ec953f26ddc167b8fe8bd801d6c58730f4dddc6c94bdb1e6d1e0f11b6d59e28f145e75a3b4d7aea2f78eec4677c8be45307910c67ecc10fed65ce585c6addf789ce485033d82e745f91472b7103370b162bc60504dab311ddc428b141c105e9343c2cd7527e43baf01b9bfb4e1b85918bd596696b2353425d03941d9a5aa6d72c57f1c42175b4120269551db41dec9b893d24d76a503f13ac1095ff824b0c3f7836e8b934b112440fb8157d35cf92c196de10fed9046722f83ad58546c9b27b9cb6e853dfffd89ab7724e140c0f1326302cb2224f587e6c7f27111e97ecc0dcc7d89a88e133970a22e4aacb12ce388393bed30d263ed1c080c1d56b0777e7ce2ce19a6b8db174aced748f71fbd52dfd415ef6fecba1e4ca7f207757967b3a6ad1c2e9f7c6a58ddae8555205e5c6bf64b209bee6372f196682db52dfbb37440be658d1398659a3b779843c381c5673c4eb97ce0133597c5667fd183a78e5daf15c56ad726f6d368dcf37ea737af668ca7131d4027b6260c748822e7a387b611ccb6edc4860fc4302493e66651772a39f5c98f46da64a9b1219babdc1cf6ef4c6557ced9b85ff3b918053dac001fbdcceef7485953527e1181670e62886f46371d2714f39851c1fe09297c8c69dff0e62be3383bb6aceea0cbc71cc7783cd1fac364236fecd9fd8aaf59de7680afcf90de01e9adeae58c034c25c8ed25b58e82e4fdcdcc2e69d1054dc753425e98cd50644eb74b1b6d62c769b61bf74d41a319eb35878bc837bac60af425c0a36b150655ac82f8e8fd61121790a3bb9389e121ed0fbb061cd593603a763e0b8ecb357b5c453b20239ad2e44ee0ef0e4cb717db95613c3be18aab77c708f5e91af8006e11b6ddebb8b0ef98c06dc3c97d008e058bf3e534582c24a1485f68214cdd88167814802c89d5c07a7453aff1010d6db0b778d9d8fc64b5bf3bb84cb97cef38a4b30a7deee12f0af806833c8c6d35a7f995b414eb0d9a900e3e56afaf2dd0d162063c4dd52bc6ffa56cfece2ed90bc7c9f4276459c9bd128ee40a5aa514de786ec15d04a16adddd64c7613ec9eed738fd36e24fbcbdcd0d3318fab948f47314a5400d71c5ee07a8c1fa17e4a4c08f4a467291cec1e8266342a42646d138331b08498f2dc3fda0374ef736d05c2a363fe08dc71ec799f0256ac9114743f40641ed8d9a039c57cd409bff29bde518657cb305a875cc6c0a58fe9ea3452df3e3802cf316a0c1f477179f6cdcb39c7c9424c07997500989a600887dd9f04c92226df10e9a8301818a5ec2f0b7b06b6d1443dec46f478a9271498b956b72060dd2b3021b004358b\nAD: 7eb6a083ff2facc3e9500278352790ccb6f9df67dccf7a03c33a34c6f33c1b4dc4ced2d5f69e5f68e79c582bf0db7751b774019d9399329f1a6692c5c527a646c9bb866e69d4f1ba4e6065cf0c5b09e941c5bb6e96d7edcb19a5cc02411507701b65987dc206ffbfaba4f06cf394976bdde1ac343e368ec1083813417cd0a325aa0e88913958974fcc911478a460b79b9978e33b21064ffdc1fc4df1e314948df71af9a6e0a40907e6b35ec6304bcaada85b456298637b6fa582ef331e2815fef135dcb66870107b2149c5aaa790f7127c0f0819b83bec46c0f6d30edb61b6fdf4f35f4b5345f1c684f41eed8088aa2f1d42c920a06092058e7c225d10fe1e5befb4dc593badee754fa12b843a6e9f67ea0e0616eaca697b22f526fb79a2ec259076971185678aaebc6449ba3bd284230ee621bc02ef1f5ff23651a6116cbb7770ec7385a44f4d54e7cb04aecd59a99660a1021eb6abb5d2cffd76e6e7380c22d0224e499e0c7b69aa0e7dd6deb47b22b1f1fb882dc35eb944a495fc3f6345b08da8f7185c3be95952bd7c982d9c8b2410a1cf1f5164961f6d1db6160d252e631f77b02d4e23dcd655e7e875b9b703fd27c57008184772c73fb5dc626ba43f54cbdc2937de7b4c470235098cb0a3e699baaa8e2adc09f8182ae1f168aa86a790688795003c3598293ca269a944\nCT: ac837bdf77bb97a1bac4cdde49ef8d6c7024f5f25a7bdcf924fa87b0c77ddd66bdb67c9b8798922f5378c0405be67d5da47f7c245c5f7330accaf74d5bec6a8667c911384d9c77e9d3ca38d88bf87deaca62b58d092bbabe64895b944fa9f6bca0aa17a55031fa19ab0c324948816c57f67adf84077b277e71a7db9a6ac537a95e54d3cd4c9517bcdb7e9e1ccc8e7dc252c27c89b9c20c9876ce7c01b17b80a05c6f75006cdd1e081ade6f9353c66f7113613a5f72d82dd28a65efb74d0d1c92793d652edf23bf7c70f6dcfd5d40b2799b60c2a6fb53beb02571c78001381fc97d4a9292a0eb7a4a0a67cdf20b4810aebe5aa4a6d20fc30e2971924a09f106d0b5b7fcf181321b6f8442f91fb7ff3b5610353500b9d6f8a36301e7cb12d94d1aab6ec0f797fdb57232c02d5fb4b2ffc7d0cd2336ff96a4a811cd1aa02248f4a48c7646591507f9e02f8f441cacee92b5bb3cfcb7a5dbb02993d0fb1818e0ec4cb719a6b43d82e15ce576f95912ebeac7a7aa377a50d1190799b00a6da2fe7cd7231c3fecfd4e6913df0b46887ae8412cd2c9de49ad7a4e8f55e7f53239649b566c4940db50e0ba9a915acbdf0ed97905b0c70930d49c5c31cb398fa4f52222d3cdbd9374ae9d7d979991fa50a2cefeee88b3943578f99b9a46e58900378ef22880c862103ab7e0c2066685571b28c3407cfef5bc0c9b176be8dacf6130bbc44389aac32cd0011aaedcb752e16a1f99838030f7364c17441de87d5ec670a25a2b55a77a57f2304233b3d9d1f4c7b145e7e145eb8607f2d9b6159e954f14b02609830fe54ce1a7dab775b49d77a0ed503773c81e3c53f50e0cb676387dec6e506494ea7843fe533aa7f09dd1d4c960dca585a1590035a9c36cc9f821b4a8aaff6548fddce5250efc4211b0ad0ad4dbc3dc5038218e58851da4848f399f8d7938da211484139000dbf8b6c6314312586311ca1d8639fcdbb20b6a6a608c23027eb46938cd6bb869ea2d3b327728f31012de124a9b57dc96d5d98154b98045943a24e4f788e48bbcf0dc20598fb91627f09495c8fd5bce762b1193fdcf9c45174005d589ba6ad971b5d7ee13e1aab89447a14f9d750621184cdf55ef4ac2f7fedd7b8fe89e0fefb4382ea18cc4feb62e9650e9ba5a12f9366584ec774f5aa09793293b558293991de7fd1793bc44341a5b59cdb45095d5b53a4b847512dd2ea621f9778b4c0f33cb7bdbee1061505f08f1f2919cafc5d6e45206cc35e89e1d366b7abfff3da64f6cfc0d0b855bf5d425a85d93ecb01186697f60a7a47870ee2a6a50cdf134a67a51565d28974dbaa9c62ffc960b70fcdadf79dc489741095ef3052df69c55b99c95a44728d30e267a02922c7a6ef2523ec379239a5148eef6\nTAG: 09a43ea9d67cec2b3f35d401141af9a8\n\nKEY: 94f159c5d19a22469924c5fbfd198b8add28b37cf7bc3258fb4b906f2ecd672f\nNONCE: 4fe1fd1359a4332402251d90\nIN: b2e081fc4457b3387c1033affd15747b79dad1d6d3b69c076d4dc5c209ba1cdd383a5196fc21fbc49fc65c69b85ec299b1daa26a4bd2e5ec2559cb230b21c3bb62e2831830a2b86da2abaa289d98eb04eaf3cf8d583ffc7291c3201df2c09b7d900a4bce0972e390fc980eb67cfe654ba3b9c579f997e319496b57819b36dd2b4484b88ea3cc1ba777b10ecaf526a08afd9e2b3b32b2bc02932af5d09c2ee3fdcfa18d6261808e418c4bb80be4315a5581d405841341bf2775d8d0adc21c10b9ffdc0ea4b22e22f61b46f844d8caeda0aeb7e1c3f84d337898af24fa68d60e2f19ff815713e1587e0d6e68d64cd088ed432c45637e1767913343d899b2f8c01bdb83253219878a5b3a4e6166e02387124e711a56e49da1893b4f72198c6339943262cdfccba33428009dff70a0c8c79af248d081ca04edb2ad4f35ed1819f0846dfade107c7e9f4094c014087c719517d943e524b86047d24aef8b901a7b1ec4e839400b717e758520cfc7a2dbced0ef491eef6aa2695b2ab9a92296b6e75251f124168c36a6555c4a465cf84a7b36f3277859dd5bb0f10f84cbc944b87e37b6b8ff6958bf1f0546839effd30995853c734a11c062414fe841113d0ae62597cd12ef80dbd4dc4f72e065171c8394e45dc6f87c86154e9846c1eb58f560b8c503848eacf05107c445a6a06420e67e2297a9975d23a406f8b8ee46d958d10d8724d90bb26e2b38be1c0e8258de3a09541826486ad28af8f2fa8c7befc95510589baf81a88f3823e87eaa8e40759cf0853547301de1e87b2eeccd76967bb364278174823c1cb1963f34fab537915031cead844dbb1c614eda56e9952b1eb4cb153d06c59c8da3b10af499b1c15ab0f03559fea13b81bd35fa5eb9a5431e12ab87c3c094861154d3d8eda448af7e15017103ad3dc7e9991b10cbe61cb33d2ff90121f4e40bd5d9e9c34b89679b6e1b54e38f00b128093af3e4ca9830a1a4d7a5e9db067c9c51fa26232945fa3e1e31e28c5000e1965cc7aa11a051305e68be9d60fb92f46eb2b701b3f959819f525ebefd5339bebfb64636d680a2a4f32afce85e287f8936bf62676c37ba810754186e30b812b1196e8661e345fb5b09b8dbe5f96e0010c5e3dd0a4e983149f4a058437cd46e3b32ca04c51ae3a4a39a7e15768a8fc379563450c616a5c7d7d98c46c0b934c894727532a9e713d330d294a2753f0f46049c88eed68711e9c49632144d5cb14d76848a6f7741d36c969edecdde52cbfb57a628678d31befa7ae3198343deae760d5c92c31f3c045b3e932e9051cd201d2dae66ca0368b94445d662acd6442c39eb945c8a4b46129a8cf5bbb2b27927729406f9b081695ce148a10226bc345c648fe557b7f8db4604fd0704831e5bdef6694afe716ddc3a8d69ccad4113\nAD: ebe1684346b493db264417cde9c0e48db46aed1984f72903e94b72cc2b2f151fec80b32523f96f61485f026d63734ff80015a1cad4b21ed1ba057627b387eaecdfc6d7a195b7d46e485bc137726d96c4ba51e1656c3f234174759ad922f3493077d65c149d1e871855490b6fa5924f6270cf15920838b66e3250a99ff7a55ecc9944cf3fd204081a61ce05bb989e5abeae4b2f24801e7f2223d5ce05c2b61f32344a0370c22751293bb898061ff50d6364ea0275bece795be21c9dc0b2749ff68a6d15896d4692474bd46fb256d1d012e45e7a58d880fba240ac6b89d2087da1ff7d41df44c768fee5bdf51f36b090bbf85e7ecb69f61312463eb0b4b1a04a153f593f8d43", + "f62ac96f76e13ab5928147c5e63788bba4f076d12eb6dd15842e2c40fc9f1ad5dcb80bd95d9d41222953776b3304badd650afc783b7342196ab551a474579d95f826f53d15b96ac98a10c2c6d50a7b9b947cda9fb8d8d7dc7def72c5283a93112d2b58487a25debc9ca06946bb0a52a1e4ed3bcf0fb8decae49fa6607c55501f01b7441671f08c814023f7d46f4bc596d709d305ce320b1b0160bf35c8f17622c65b8e5c97b3fe7327e8e22384f6c400e551dd438d6d3d0f9ba6101abd1bc2486ba249b4cc83c47982c1210328968f2b28e4a7c4880d598d5b47aca2093965622ba7b4e4062c86d81070ecaad93d5e47ec\nCT: c5311b1a6e3d93da070ee0fc2c1007558db64bfdabdc23c832d151472513482314e7d9385918abe772970c7d8b3ae4eb0d12965e6d7f6d01f6c97d06b51d3be812dfb290592578713ed6342a690ac115c29d471826f37f7f7b46936ab9f431cc0e4029579036bc6311574205810fecd3a17ebccd0f15752152276d5169b48b0a4fa93613fde13997517956f84500edd7eac1082ab6b69bf43f56fb9046cefe8425140db5f6bd3bb201b3345b2138c7f42120a3009ccc19e2d95ddb2b4384205d2aecb47c89cb43fab6c353f781caafae280e93dff5bd213640c41cfcd81b9dfd1be05ce21758c5474c38bd24819e5d085241dd54c8d2cbb5b21a616e47c05d4c64c0f397fc16d52d008fe4e83c040a6304c41a448784fb0c54f8a66fb00b240b9d66e8db234d14534dcdd6b3ba78db0403cf0219406ca858fef6bcb259fb69c53c6f964f450bcd12997955d0190ccbb2d9ae6b3562d85dc7de2bf1bd5a8d49651fe5de73243d7f89ac8796387e0a04c74d5834e47afb6b7444df7d27592fbfdeca72428582703ae52aab48c1b587b12fad6c887e451a54ef81481e3d8b4da1e3fc09404a7c209db8c880c40b3fedc579fdf19f956bfb36d5b2d1affa0a3631681084ae4e41e3a0fed84e056bc72b6c0eb1f5449935f7c2d3de07a2a5fb65af65f91d2c1d730edb80b437cba66fea779449b68c557c5f8bc6a2581b6808a98a1acb9e6de414377f5b08fd5cfeb4806e8699e50236dc8100a88f4f55d887caaa6ae8ca09c23019126b62b5c3186b459c39ee397076c825b6e28ab62d8286743f9d07182cfc634eb4512ec3beb04ba81bc20294b16fb6d42301a74fa95f95510155a15eb953eaa51d82fc363c0c63d1cf401a3ccc0c577474f99f7c4f187316fb85e1db38dac1df4b5e7c710be5b5949dbb1925723d042944eac09dbfd74d7e876f5931f619bfba1ea9580bf4e6c2540fd68d5aa9cd21203ba207f0f62e325c1e054271933563063acb4d932eef201bf3312763dddf6992fbd128cb8fc8b7936acbe8712ad398c5a8719b9efbe0927b9f637f323c4bea80901091608ab76e483b5ef666560937705bff96d430e6e17b0b24c755de19bb88aa81077852c92a96e902d538b4e11b78a4b5d1f5669aacdfe5125d806a21c06ccf4980edee24e41b7e17672fed0ace9b19e4d55415d097f0b5874d60dbe311871abaf47220893c398d5595ee16275eecc6d15f39aa5e2181ad1448345406a4c77a34c3fac77b4c506cf393791d69e113270adf0393cad689a07056e388ea3bbd00ee5878e1120c869531a8b4745ca2debc1e008493d17bb3777992cfcaa165188b4801122af5422acfa0a1807a2a35e793ebdd95aa9e025edc065cf9ae85972a5f42da193cd9b653373a6e15d647b8d26207f3230e50bb49\nTAG: e2df8917d70683fb6e6ea67db55367b0\n\nKEY: e22480e24a29b2910b227930344f6a00916bb215e57e1f3155fa9437603fabc6\nNONCE: a4c6732e0887f40b5017de54\nIN: e46035c45b6ebf14c5088c5f15f552a4d233de7d3750d7736838a5cd4a7b41df1b71e6c5e6a7dc63519ec43bcb4fc603168352b8b8e261c15e76e73556aaffa32193c1f5641b2eab29497c80eb06543c1b0f1787bc616a4e6618f751dd0a2b28a87fcabf405e97efa91becc8ac1b036a2ca244e13dcbae589f0d6bf8e19bf91caff673f2a80de93a6fd5da1e63516e2760ca12a64c8175071de22b26ce72ff9e15e5c55fb253cae55a3f48c0b507bfd423f66ebdecd0b6227d0e67c4347f2a4819a6825dfc2651e97c1da629e92bed3827a15dec0f0c8743731baef8035fb0a790f49e5b2a7339485df313a9633496fd9e7a9904ec566bf20b8dbc0e3c1e4572411da7835b5eb5cd51313b78a1d6ed96bd9aff2fba37e86d475d95fd7e14c6fe8ab23645b15e7823b7bc9d0a02fbd9a43c05a6c660b6690891c4d055af21b50a5500d72c91695536eb1a3852caceae05803486c64535747df691ebc62e888bce8a5c820569b3d80edb4e29027e737fcdc4f49f6eae43b4bf68a5731fbd09778d6b205bd8b3ab4cf251ff31dd94f2033118ff0c4154c78af27570d12def873fcf4de7ccb6b6cc8924dc63f8104e9a3323ddd32006d8ec3aa530818e299490dfa0a9d811fb3bbb5f624f26dd7d0d7a87a7e7748af5ee4f4bbeb150ea4078b504aadaf92b8f9edfb701c6df7ca615416f61bd770d5fc6675db01394a26f585ffb8f86b254d0e08d0a0f5a499ef1b2bb0216e486229f5deb16d1e95332b8673652a86a6e3fa0e479987b2bdb1909fb772c6836d15cc57d97f29acf335ec1873c1bc6e714b689db855c8ba59289fe792d93774dd83313e3fdf11bfd6a40d6c8b57a5989e844cdf2fb38c239f6116c1c3aafb9356ad4b07ab37f7fb089cd424a8c1f19e5a13f085ec8cd74c3c9f0aefccd6fe5340eb1e419d15285b6b0d3b57a5545f6e28b75bf4795d995a20dc7a618f0f77a174e3eaafe221f8da0cb071473c507054243a7f9eee7d5c77b071602936fd5bc411e9923fc82016cf5345454285e9c1396696e05d984649a2955d7446a1d3966adda11bddbf3dbc11e093c15b7d4fa2a7a0c33fa28dd3242738d7a77775cbeb8176a6e9a4e4e58e03f631a67c3229d57302fe5967c7e3362ff926fd584edc32905a350b390391f7fc3343f22498bd198ad56cc2827926b0c4700cc352bb990876db7c17e2d32b5b0af617554a1f76c32b94cf7728e89bc208f22e986e7d2faef190f820918afa4e08cc46adf0704aab761cbb9791aa12eb31a7785d7716c3f0a46afbe2a44a52e5d0944fbe207ac78d54c407679814cc03d9c9ea28f1e518a10e0cf034d1ffa27b67c9f027d738e0a96a381571bb52afe2e983b34f9159f05d4ac9973d996c4612b7c60407a66925068fd98ba6b7742a219d8bed4ceb720a8541f4cd9eb990384f8f8698515ed3692\nAD: 8eb26d00d61388ca0f06d45cd697e36f11e25f618eaee0562dbba21d10abfd0bbfe232e6efca4947adfa7fc59de529652d11847d3cca84ad147f8905bfd0743be43cd21a9ece92d2d7397f74b1632ec2b1e398565e3f37039f1e147c061b51d59eb31bd16bf830b7824d1ec5e79441e5c5e5131062171467a037c350fd16f58854e3dfd9c1224d26fd600b006d4bcae123a7a9d4e98c47b9e9e3fdbc22abce09b3c24a5a060e371ee70110227c9a8b6049f194dc4f74cc97d01247d76b460774acf7c5d4a8fb4f01888e29ffc517839c234836cf513951435f226e635ff8b02b18225402b026566e951449023fcf7f6bc2285dac1b7dd83028697dac70927db01c22921f6a7a6304052e58c8e87819bbb75de9cbe6239cb1ae8fd4849eb4f48759aed59d5a0ec3108b3131b0b74a4f860e37d02e04b9501e5e3c306cb25820abc50cdfbb05f8e5e2d2b94c58190c5d950f804786fb2ef97eb013f6f049b38fc57561b9cdfce5ae30516050d13d0ad8c1d750b51a552520785a9dd03c68203d91e72e3bab17cd67989bd103532071676718e889b94ee12856547a6d0a6c88c236d7fc7b0d8f222592d00aad4e813f8c738bc10c0b1fbf23bdb2baa56b1047348ed172a15dffd0bab088e2b406f040ef81d3362d0f86d129fde70ffaf87ef3c4554fa43850d1816407b4d5b0459bc622414a2d9cf2809e60e467fde6ecb7f4d9\nCT: 98763c2423882eb5a1e9075920b2245f2243341f6dd2dceae7780aa738fab65c7d86f41dd4a64283752db5e86cecaed0ac1afe966171e94f2c30d63a93ff11343ce15ff3bf464d88a6912fbba42c08e6225cfaa63c6da17a6354a34362fda3d993920050dfb99c84a235726aa4cbd66260b0e5675bfe89078e33e76ef537d2071d5801758c6cf07557c0e8bfe0a49aa6e212d69617d1a22ff15a26ae28f4d724d6b537ed34af62672cc9d48836f284cbc7eaae8cd15b46b8e233c94bf3036713f2679e23e0bd829dde5b3a5d7a2d65193f55a45def3d52830cfb1ce3f8208c1425d8171a053ab076c2377f7c26b37970bc3c937db75181a47467b9735be331a0f30a7f3ae135a533153ecd0a5e0cc1568e303a6ba6065c0dca8162a33df7c5b69542938c88e2141e2aa697c48e72ec0573065e9d9a9945cfd070d45218f646e5cf0c0ba145ed1fc7b7cf96c64e3a4671eb6b51ac8eb79bf0b4abd56fffa2ad8a93c001e2baf0b65e257782d7b7e3a837cbae16d40183a8b629467f77f2c7f8640da57904ab75a642e99fe4b45ba7ee488f889b07ce7a4e74540c3e0e0e67f88d473509295a66e27d4ebda1d4d3313add2555477aebf7fb84edbfdba18afc6f04c4af6a90730518a8ce28c12ab90921c413bb822e63cae113e5254039cdcad2dbfecfd97c183679c6c4691c99ba771b1389384259b966f358f871343b4bc5f9a92d8f27588202ae1269658ed91bae33deec6a6a35b9fbc523cc11cbc15024f4dd386b8f41c3fc7097d717099e722e6243a13bc475d5f2b1b2569f14cae6710c8650bfd78520caeceb035f58adae811c0fe9857c8cec59a01123e5eb2774190943c2cc7d535af77ea1f79cdce94e23de21004c73fb8469c230e25fe245c8a5a6314736166a7fe4e1bb0f91ee8d60daa0e576b9b7c6b5957d4bd8d8b928d36aa46fbdf742dd602f9cda2ed1608255d6dc962cc6d3f270d6a42f5185b38e6f0085f39dd17260f0580b62d49cdb668e3e5f76d47dd1deaba0db5b315ed6deb62e6e4388a74ff21903d7bed3c3e87585675a608668bc031aa83e7546cee77bacf9d3f5cbcf00ca71d6f6c86751a5db0d7f7065324d33458b7fe66e2b63bf9d8b514006d14da70f0d64f171a7bc11b2fa5955b85090701260a13cb52b930681e10e9daf89bdffacb9c13b9b60319e3be0ed29f7b7d4723ac5af888375c9e23bc97d3b189ec778eaefb3e4649d1b1ea96979c8f004064abefdfb3479e924dd974ff6478beb1034124b1cf27fc739872bd24bf257df2068475f0b144e61411481a48739e2691e535b64066acce2e0fee9c239c4015014dd38570b01646bbe97a389a3604312f06bcf7ae288790b73434288ba0c90d7015bc1bbcd5a0fe84564cd6a692df04d53716bb96d769074d758bf1199f716cfe5c4c542f9852435fc9675a80b4d\nTAG: 9f62d794a54433e79c71a5a5cc8d282e\n\n# Counter wrapping tests\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 000000000000000000000000000000004db923dc793ee6497c76dcc03a98e108\nAD:\nCT: f3f80f2cf0cb2dd9c5984fcda908456cc537703b5ba70324a6793a7bf218d3ea\nTAG: ffffffff000000000000000000000000\n\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE", + ": 000000000000000000000000\nIN: eb3640277c7ffd1303c7a542d02d3e4c0000000000000000\nAD:\nCT: 18ce4f0b8cb4d0cac65fea8f79257b20888e53e72299e56d\nTAG: ffffffff000000000000000000000000\n", +}; +static const size_t kLen16 = 64853; + +static const char *kData16[] = { "# The AES-256-GCM test cases from cipher_tests.txt have been merged into this\n# file.\n\nKEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01\nNONCE: 5bf11a0951f0bfc7ea5c9e58\nIN: \nAD: \nCT: \nTAG: d7cba289d6d19a5af45dc13857016bac\n\nKEY: 73ad7bbbbc640c845a150f67d058b279849370cd2c1f3c67c4dd6c869213e13a\nNONCE: a330a184fc245812f4820caa\nIN: f0535fe211\nAD: e91428be04\nCT: e9b8a896da\nTAG: 9115ed79f26a030c14947b3e454db9e7\n\nKEY: 80e2e561886eb2a953cf923aaac1653ed2db0111ee62e09cb20d9e2652bd3476\nNONCE: 5daf201589654da8884c3c68\nIN: 96669d2d3542a4d49c7c\nAD: e51e5bce7cbceb660399\nCT: 4521953e7d39497e4563\nTAG: 2083e3c0d84d663066bbe2961b08dcf7\n\nKEY: 881cca012ef9d6f1241b88e4364084d8c95470c6022e59b62732a1afcc02e657\nNONCE: 172ec639be736062bba5c32f\nIN: 8ed8ef4c09360ef70bb22c716554ef\nAD: 98c115f2c3bbe22e3a0c562e8e67ff\nCT: 06a761987a7eb0e57a31979043747d\nTAG: cf07239b9d40a759e0f4f8ef088f016a\n\nKEY: a6efd2e2b0056d0f955e008ca88ca59fb21a8f5fc0e9aa6d730fbfc5a28b5f90\nNONCE: f6775dca7cd8674c16fdb4ee\nIN: 5dc495d949f4b2c8a709092b120ac8078cdfd104\nAD: 86a597f5e2c398fff963fcfe126eae1bc13f097f\nCT: 04416e23586ee364b1cf3fb75405f8ef28fddbde\nTAG: e7b9d5ecb2cf30162a28c8f645f62f87\n\nKEY: 8d6ed9a6d410989e3bd37874edb5a89f9ab355fa395967dcbbfa216ec9ce3f45\nNONCE: 55debbb289b9439eb47834ab\nIN: 52939c7416220822a77435a46687f134cebc70a2f1a4c33d37\nAD: 7790af913d84a04c1b72d4484ea2e09fdaa802d8b1733b8470\nCT: d7bddae8929ed6bbc9ac077e2415d9fbafae4a0432f8f7eb6b\nTAG: e6383b16ed9c32521dcaeef3a7b9b67f\n\nKEY: 525429d45a66b9d860c83860111cc65324ab91ff77938bbc30a654220bb3e526\nNONCE: 31535d82b9b46f5ad75a1629\nIN: 677eca74660499acf2e2fd6c7800fd6da2d0273a31906a691205b5765b85\nAD: 513bc218acee89848e73ab108401bfc4f9c2aa70310a4e543644c37dd2f3\nCT: f1e6032ee3ce224b2e8f17f91055c81a480398e07fd9366ad69d84dca712\nTAG: e39da5658f1d2994a529646d692c55d8\n\nKEY: 630b506aa4b15c555cf279dc4a7ee9add213219d2c68163ceaeda903fb892c30\nNONCE: 79eca200a5cdf92b28be5a7a\nIN: b12e6f1f8160cd65278c48f68ad53c8c82fd17c2c39bbb109f077c17fdcb8a0b3a5dbf\nAD: 46cb18593b3b26ba75e4cb20a252caef31d00be31093d2369e93572a393d650c68313f\nCT: 9a9ad1f78b4d411afe450d2e46347a7df98f39daa4fd478b9ab6e6b417878bcd52743a\nTAG: 55453a003b021c8a247379cdc4fa6da6\n\nKEY: d10bb6641e9ba0a3f1b016317831ad4232f81c2137adac0940ecd7fa36de0563\nNONCE: 99c922d37c95ebeda8e81ae8\nIN: 8b9089df5bb048cebbe709cb61e178ec768515a0031288d95b7cc4dfffeb51b836e126a237ec50cc\nAD: f1cbf6c83493b2087d9f88e02121a114f45ed51817e46ffc0b66a783350eae89c6700db3f3be5f4a\nCT: 8a838c51a8ef8134481e9951033295ae686624aa4df72f869d140980347a5e69a6d7cb3d7119b303\nTAG: 9152bef766579a3e9a1e36abd7ebb64c\n\nKEY: ca665229adcc7554f1b1c8f50e7444c6d4059c525f9c0da1406ffb35d50cae97\nNONCE: 8e2df19123ce0ad41df416d4\nIN: 12365eaac86b270e9c61b3ae7702a6f3583ef4accb80a98454c56e34e2ab97d8afa23ddee34e7e3a522497f985\nAD: bf539d8e9e3a02f3e5834970e7efd40cc7cb340a075041428d6a69ed9fa5105e4bc63720be9a7040ce5b4af6e1\nCT: 96027efdcd4433df8e7f6181c05be365cdce550b09d45cfc96fe258eab6d55976a9306a0070c9589ef08cf7a42\nTAG: ec9fb5e79cdf8ad4c8a79c900975159d\n\nKEY: 5033338bf7526cca0425f4a620424662ebc58364c8d985d130e525fd1f598f3f\nNONCE: b40842b30758aa3eef7cda62\nIN: 69a62b8c5f9b81cebee3a9345f4e49ea089b0d9c1cc57b4ef707956d0287de83fcca6d8f5270a9393e00693075028189bda7\nAD: 3efe0ed6fbafa61070388abc59c0d06589309736b02418df5534c8c594d61a2afefbee17af8283d01634b6ca3e8e2aeadff8\nCT: d6184677a21978b6443d99d7de1fd01c6b6334cf01b7e7d58456267453f4de96708b62301172c8c87e970f91c5301e0ff61e\nTAG: f8ac7aef208712845d137b8b176c89f1\n\nKEY: f33c39140999a2cb69e43129cb5df18fffeb3513ec3560792e9909784daee43b\nNONCE: 70608463f1dfabb1fc4451e9\nIN: e2802c4d290468177fdb031a717345753cd7c3028ed07dea428db84e7c50c3eb7b24f7381a167b4ee31bf88dcaf5251fdb90ecbb74ac2f\nAD: 10a6f463dc59d4791b3c2b4c93cbe2dec579a154962cb2c4cc77664e8c2b106c574fe115fd43dad94b8b1bf2f74820e28435b4444b2b82\nCT: a27419a46037323c033d7cf2a716777fedc02a5ddd8bfbdbca82ffbdea3037bc1cc80df7c5e502b32276ae88ad6fd0f0cfe72604648812\nTAG: b1ae330d47fd399aaaa687e141e23fc7\n\nKEY: 2121056225a7b2316a93c4bfeb970486fa9c586c14ba8b40be5844a31e9449c0\nNONCE: b4b7d1e8fa7d0e2334c92315\nIN: 2038e2c6cdf5282f081292448f8febbb60a1520fa3771cbfef387f48c5915a1438ab709628e8d4c81623ddbc2f6f159c3c9a8922905c4994269898b8\nAD: b07f66508a39c4932b04c16172d6462d78273cd9463e52284bb73e3b8b8e7047bdf10c5ace1f903e5a5eacbf67c9351f82c74bda140df2fe0480c80a\nCT: 7b54618ae09b37ee72e51873c82cdd20b6dca37c334af89548f52f34df3a757e632cc0d453fc97270898eb50ce2f2a98c4cbd4cbb22a5b7c7564406b\nTAG: de3a9e2aab2439675c4f7f0b61216d5a\n\nKEY: efb15235bc91771aa32d51472877b0eb364de2f88766908eebc6e6b57a702099\nNONCE: 1a510b42dc20d1d0fb34fb52\nIN: 4eff604dd4bba67f143dab0728b8597e269d4e0ecb4ce80c9850afc645d96da239d9db360605bb4268d74e1fe3431a44242ae862fa2340c076db13315f615b85f0\nAD: e8dad34f727e77444a96cf06425640f1fc80fe3b01dafd1d91476140afe8204286d01b0ebdadc0270a3d218516ff5f08a69a7ba251ac325983caccbe0d9e1de359\nCT: 989fef0145e2fe93b9f99fd90123632d83d9df8f37d8e1f80dac329dbe0c214c2191009e31232538fec63a29665f0fc1c77dc86b2f5f2050b86b3ae48e85d63116\nTAG: 6816304faeb45da4e4772f5c35730f8a\n\nKEY: 998c22912d5687fc3faac262a902783fcb0c738520b5c4135a8dd2cdbd7b0dfb\nNONCE: eeb535c5bd6edfd696655b60\nIN: 1f6ae10d425923c882b7d2f556571acfc10333ec665b07bfad9f8948a3b8c5e5f163a4e99d4726da1a35359c657c848f327b7fd9b5f61987440ab12b9399db24715715a2d1c8\nAD: 9a3c76dbaeb69a6481a89318caeb6358267ef51a1a364a48387bf77526837c9c70afb6f105cd47d2b976dbda7d2b6bfea7b76b135810c53437472f7b80ffc8ce4dc95c7e5045\nCT: 87f4e2c80a4f15f92a8e94f468e70fe7f0e0f83c0a7799a1d465043d25210ac6f0f39a5e9765b4daca637864d1bcc090d2ef33ddfccded2d2dad61dab443b3cfcc683147c490\nTAG: 0744d928a5b5ec95f3087cc2623f0031\n\nKEY: e12effa8da2c90a5d35d257c07d1b467991bd5f75fecd7129aea4e26b9e27ff1\nNONCE: 4edd0b4cc349d37eb77f5576\nIN: 21dc87984edca46a629ed95ffb04471397da8806c525a781d9a71818422e344e4af577f38e7cdbc556d4766770a9a3c95bea59ad497fe0127816ec4dcecb6b999486719b0b86cdb2c9d09e\nAD: bc158e6570fb0a08d73367dba65b80a8c8e57ba6c7b99493ebdaef0424e18d8ab1f7c88670cf51c4d91b77eb9ce0f89a46ed1316141e4299ec6c3d6e712ec9e92d3db44640402aa4ac00ba\nCT: 07ab8c623d683ff83030392e2864edd4b8e3d296d60579a226a8d2aff6bc5af3c4598a18cc1e8d7db4ac8eb56a082af864ac52a324851dd29af51a0945cee4bf303ea111b9b627aabf5ff8\nTAG: 53e69b7be969c39560c016c6bc1aa4e1\n\nKEY: 3d9723c9235939df8647529b7e4a57b8536476d5b71b424e2c27ba4d0b82b0e8\nNONCE: 60163d2eb7822af7fad64c04\nIN: b44face0f45e4a8da19aa0c5cbe3aa960ed6b74fe3d3d9201f52523dfe7651756b2ce482e759c87bde4ec670a0e808fb4883e437c7cbcf2f6470352174327824200cb0897edc4def1736f51e229addaa\nAD: a4b2b7bf36a70a5246feee52c474058100bc618fb0e3d32e8c1f76153edec47fab3045dcc7eed9ca1886bb2593703c9ffb8883c45386d2f4e3fbb0b7c722d19f2eca94767174d9127450549e8993ae33\nCT: 66fa63ded066ac67bf218af7bc21169a875f4bd695f44fbdff906f0a9b8a067be721fd260571c53a8b51661c8d49fe178dcb28c31deb3fa71b096b387f9fc8f3657d280404c05d2b6443eba7e60b562e\nTAG: 59d5450872510c4bfb590d9497524331\n\nKEY: 75b0a20935c4a5e2126ac7420d632bfda8d41bc947c2402bed4759b6e617ff92\nNONCE: 0c3edf0dcd1125d7e263b897\nIN: 8edc98e70030e40bea1548f6f56b4561272be0c333f3b7ae53ff3e27c35a91b1aa42d39e6305ec4811e75931e5cae2261d88a6f7d6c5b05bfb48802264e9cac782411f1de579e29d464ba56840b126a3fad07f01c4\nAD: 7e35081ef652424da6304852243ce43ff711da17f7881d5e0433b1ad7535e755a8531b93d67ce99ffe66e59fbb24f6b42655524b39f2c84daa5cdacb5e7916266c05711a118b2128930b95de83ff1a67e53337474a\nCT: 858dc74dbec6fdbe4ef15a3596ff7201c8f4fcca765bf5452f678b1493a66ed9852a6fa174a73099acf951a35699f33289ec50625538c01eaa456dc658013a29e4d133b856eb969c1f221f99e11fadc98b0ee08243\nTAG: 3d8f17838c4fc69f04d7e2b76eebbc0b\n\nKEY: 7a3823191abcebadb7970d1b65c2a8dab8a908151737bd5400b3b6c0d59e3b08\nNONCE: e32eb00e5106097e2ef0e8ba\nIN: 220db5400dce604adee4cb698cdc02d2ca61622bbdeebe347b0bfef55cc45319b940f93773a9878725c5f55485d7a26363251b9ce0d3da1f8f6e34ad5329dc9f752ec7dc12b2d259ac89a8059085996a431a56cc2dc2400a26b4\nAD: a83b6dc78931cb7500eddcf77792e810c1edbd5f4e33f85018807a8539a3cace094fb794fa9ea058e82c830d42d5a6b3e22b7785698774aec5c73edd92731c51106a23c569c0c0fef18d13da1562a9a42aa435b243c4fbc9fe42\nCT: 5ce6ec0e1d67ced5a6aa46c909b9b8907b372be03331dd0940ceb6d87e928c14a1a1e8ef9096c9b63ab4cd93242ec7be7e38b80643f9c52e7e90ffa06b8f2d238fa63dcd97af74ae37802d124623b8a272e68ca18b3432b7c017\nTAG: e21c61d604253bc5b5d58283756b9eb3\n\nKEY: 53ff6d", "c0af3e89fc2de7370caa433f539d068609fcfed6400a5b9fda4c83e3aa\nNONCE: 91a824c5e023283959858062\nIN: fc23e07b4018460279f8392e86423ecfe465b25b60382f58995ef5fa1f9ca235e4bf87112554aa0e72836831d7b5f39125df11518b8aeb1809d804419beb05ae013482213012e4ce980ddd1c58e11608b775d12b450ecace83e678c69d2c5d\nAD: b3a1db2d467780480f166859e0e7aab212738b85e88237c2782496c9c503347de02f3dad6bfc671fda71a04ff1e4661767c11303daa0c36d944346d39e3e29ec63d695cdcd83b2b57181582c5ac692b13e4299ab5e86c59d09c2dc6194ebe9\nCT: 88af588ec33bdac2cc748a01ee3eec97e5bbfdf69de1d66176f42b66383bbffa8b185cdedc25b11a62237d334d68120fccfd68c2f9447b3b8e1f623f33f7f97ad8815d29bf11bc0c65641ba8fca4a087783f4694fb1d574450191825f84402\nTAG: 2c4973323e635a885f78ee106eddf19e\n\nKEY: ca2b4d335598f26d3d3607e62b9ef853d3543e741350f92f3050894721d3d450\nNONCE: 2431b5cee8c3ecec4caad278\nIN: 75e29e46350d1fa99403b1e5baa414e41a8e714910f313f8e850cf3076508ff650011af766b51283fbd5626166d775fd4b4cb7124d26d77b41eb17bf642bf67a34c1caf0fa9b43eec12103f864e56c5ccdc81b89c1a35e394362688d05dd94eda3d05dd2\nAD: 31c3ce532bc1bae65b5ced69449129b112019cc6078268b853dd17c41832ecae07f9c6b068ef6cba2b55f352904afd6096ff8432081aed408d9340c319fd8e2029c389b6e3a4bdc38853444c3f7be9385ff1ca27e59c43b542e99799bb4ce56b8e26d6c1\nCT: 90c13ec26d01b7b96bdd6816d3ee57df57efeabdb15ba602229ff71d71793fe8081eb1b462e8b2967bc4af96fd6dc72cee3d2b6495c7f04c9068b2ad0b073e11cd5999df541ad705c6315eefa8da49c5dbc258f7ba922908489c1ce672971c3bfb6e8482\nTAG: 3a7741a094be92b838850c32e4b06c6d\n\nKEY: 49fbbdb5ae21cd955be7f7603cb8563ea0b02b77a9ea14016baa5cffc55d20c9\nNONCE: c0a4463350506d2af9e35d8f\nIN: f31003aaf5d8fd6261c01c5bb1e7bf6af248e0be3cf8aac67ccaeb0b7468a40d98be526a8e4f692dd23763563e601915ebcb59ecbf03bf9c665c4c5313c318939a911888fd427d5297b9b2fd91dd33eb7ed38e2f0f6ab74ec263989cdd9915811a022d4a46ed35eef0\nAD: 17e01af2386531ce67d5bc3325d8f83b53a87b38f1c305f99c0798380a7e59d3ecddf33a5ad23a82e33f0fa34eb2438b17e958451439774ab642fafd3794f80a0ee1b9bc165f32df705a6175310670ba54af3a204e446db35170ab02670086c47a475c22d1f14cbe44\nCT: bd661836d1b74244baca62d7d1cb6717e17e2fb0bcbc8d36b3265a983d557c562b0be60708499d0e7e9626825bc049db79a0ef4d2393fef6024d849089455e55693fd4da3d910eac11496492a645e4376855732765e1b3580461a2a2533cebb482736ac928cba175bb\nTAG: 4596e3802109c899f27f6cfcbdceac5d\n\nKEY: 30d0e4f6425e38c92ac34dcaa06a815166f301289ca9cb0ed08156617d87bdf4\nNONCE: 525618ac9e317405c7d44367\nIN: 06f2204ca864dd3f7c9d0290f6fe3d0337eb9442cd5d2b586d1d5c30e58951fc2f4e99831ac7bca4356db4609a0428c482f2580b9e8cf5fd00d86d474fd88ac3b2413f44c1ff66e59e7538c090b2444396f02004ff636aca05ec40439f4e3f470a24916fa4033cb60127223addc1\nAD: 23c1a3e1083904f7226be7242027abb7af9d62f1115340cd4a57611be88303955cbcbeba44eab5488c80aed3e063c70cb7bbdd9ac289c8c8977868c3702be63d0358836838a97b31f6aee148f2b8615ad7c5dc0de7c48db7752e5f1ae8637f8c70335bbecf1313ae1b972ffb9442\nCT: afe3e71953bad46ad28113b7c8f2092fdebaeb81626bf94bd7e9dd59e000e8ba31c1ce7f728fe19dbbb42322e54aab278e3c29beb59b2d085e65cb8e54ea45d6a9fb1f561bac0bb74afe18cc8de51abf962c2fbc974c7ed54ccf2c063ff148b3e6cccdaa65cc89ab19fcd9cd0436\nTAG: e9f5edea1fdfc31cd5da693b50b72094\n\nKEY: 661309741227606892db13ab553070b456c5e421cca59087144873ae6d59e590\nNONCE: 9f07692c017e1391a981e70e\nIN: 40b5f8081b5dd173203e02e90a6c171fc41f804b2903ea18109edcf77c03dba687b47ca389c55389bd7b0ac59bfaefaf43b5f97065df6a5375c1fbb95d95cad589c2a45cd9e1e7960b1d13622440f7180aa565863b4f9dfe26ed336ff4318653e1a520bdb830e01db78a7e598f251834d0c9bb\nAD: e8540d084f24b80414af554f470048b29a5af8adb2f9d55c9759e5ff1595ca74884af67027324587131d90c77ca72b2d15b66564549ce93df7f667d0218a6e874848563a33886c6a0c5a9d00fa435dfabaa9053243b4c8c25779a4dbf79eb4b8530a7c7bf4263ea824713a90cee92dec78c449\nCT: d543f49e6cbe26f1d8a6e058769d5b16e6f8255a28b4d73ba2cbdf664bbc5ded73f9dea12a11b86b6a6acd578f685afabc232dbe9ff8431a5318ec7f0202959a310595b147353a7ca89c9d1fc2d2b92ea610cf6d9ad2716df2dfed70f5b74d498edab114058c22c96873a2a64abc254c82af46\nTAG: 31a8441886d0e4c6bfcd6d74f6a5ee5e\n\nKEY: a248b0d683973d205ef2d3f86468cf5a343d6ad7c5aaac0b9b6b2a412eed3552\nNONCE: 8f62ffac4027f4dfeacf3df2\nIN: c2d7d29256832def577392acb9fe4f249eb4859025ea55cc0c4a67806caba3e1cb81bc7f5717d94e1c91ff06607b23c238daafcb0fa96905616f02205b702508970fe3bfca87270ed1102a9ab96df57ebdcfd86ef6e9c4c4242b4febd82b0220b0d6f76d8c2d0fba33ca49279907f6bcf7e8401d1419ed58\nAD: c738cdbde6dc277ab81dae20fbbb4a50d71bcf0ac1ee0ec6a39747ccd87be40b1f0f2c37f2c6b32ea99722979fcfddd0ddc2e4ff34a2e6113b591cbfda317c6f4b021ad30325276f8d8dd78f757618b53297fec091f029f9b00850b35f3863a3801c882422b318b4a1bdd89002f928371ea05c6fabcb1792\nCT: 7a837df292ad2e58f21b89da43a74de411e1746556fe47db55a136757513bd249384bf67887a5c1f605e7f7e3057596e17039701ea351e5ccaf0fd4882559e87197144632977cf07cf9e86784a959fa7399476a4fd196d7c507fe3876d759e2b37bd37edb3c12b89716f29ddc8b64974263a1ec1b6364b0e\nTAG: 291098a2376a0faa5da6fb2606b4f2a4\n\nKEY: 80634a8baea1c4fe5dedb664c9b5d714422dd1726d642e60d15e02364195206e\nNONCE: 725ee5023ae08fece15d621a\nIN: 4d1d8855b4d155e77bd1bf34b3d049ef09b2b94f4e604306406b015a2d520e8772b084ed668b868e32c7563085f2a82e7d99219da549e507aff9515e45a045c7cd5292c0e09a3a38c769acfd0a11826b27d8bf05184971670200e79c49754debbfc57d9ebc661b25f22f241c4d143bd922f7b0981a48c6a63462cb5cfd\nAD: 12b3fa94a64454dc5b47433df1ce0a7dd5e8066d05b2433c6cbcb83087bb7d22d153a19c05aeb76141431c5f9801cb13531691655939c0c812611c6a30083ed3ec27e63e6868f186be559c48367a00b18085ffb8c7727638e833a7b907ff8465e3a01d654b52432767b18b855c05a9cfb5d4aabae19164f0dc2ca6346c\nCT: 6b01e934916823f391cd0d2829c224a12eeddc79f18351d2484ef6cb5d492ec9ec4d8c4bd3354f01d538bbd81327f6360a7d157feee64b539489bfdd1be4d7f724d2a6dfa1af91e4108dbfffd529afa71388b07e5079236644da289ae236100b2fbeda0c17bf2a01e76cd1f88081682c2d074223fb8a41d59e70a37870\nTAG: 55762e95d897a33c4c75106449112986\n\nKEY: 4f2edc967b11983f05ef5ee2a4364039ac02dbcccef3f3719913ae2719c8217c\nNONCE: 255f8209b0c67a6277bdb42e\nIN: f8217163bcaf77c1383089e396b271e22c517e8ccda244256cc39315fab7d0c291078d90e9b6e336992f015282caa1ec0ea858a179c9735b7a2f0d50f6f1eecaf3b9308772279ebb95f8aa53826e9dd60fb354de0c50c10001c98812b59d7c0f36daa1aecda6782ca36130fbb559363fe07704b0b91ea85be319ada027e47840c764\nAD: 1dc7065f1585384b88be47598ca484782716c78f49b3b6bf5d24a5b0d24fbd7831f18d77d80951d2c4fafb6f939d46362a69b558afadb3bb4d8aa27f7fcf3dd9624e1e075fce9bb239926d51ea9dff03619d64d5828103a414e360adcda8fd864fca55c21df86c76972c3765ab1d68ce89f708e7e5a3e06cd4de08573cf750c6f5f9\nCT: 6719849b7cea3f7f2a8e4de13d7a864d581b7c638f49fb06378a768d2034548179963c33f0ad099254c2edda9ef771daf5d299f58850033e2e449d7bc21ca3f7d3b7408429b596da615c8582886a6d8c1a9ba81fec4a41a38b7cbf1a80ee0ec8bd71451e727051fbf2a1d1e3c6ca98ee113e47650ba4fe80451e79b04abc8bb99a2a\nTAG: 2ac7f962553a8007de3369c7795bc876\n\nKEY: 51c5cf1f0c76ec96f4a5f9aa50a36185521f3ba259145ac6cb4da3cd12467696\nNONCE: c751e5e7e3d75874acfd2bfa\nIN: fcda42cd098b7936f4bebaa37d5850cb0fdd6526966b1b5734f23d5050ee44466627576e1144957929123198e40b64eaef74476870afecd7b70f7583208603a1b5247074c6c77e10b9bbd41a3d468ff41db89895b0e9ca95be77526ddb30d4c5eb0796ba97d7d5c56d0eece344dde3ebd7de586226c00da224b04e74d9abe832686797df067c52\nAD: 343ae5e73fd1da48dce92ba7b86d21de0a203ba8587536fbaf4646bc45051a7feb343e38916f6c4c75b65f940045e830857c7b62b34a44622a36b34268b8a397892ed3e4de5df3fa7384d4ca50202b5b0833f921349c877931f4b735cec45db6b95410c8042ba49c1a39870276e0165f09c73b14bdf7f36d19084f958695c7ad2cc56f0487eae9\nCT: 04192659d6a2f1b7be472372c8f969a7de388c97d37b4a89653593e48b630947d2160b569379698e94de49b21572ef0b4dd330487a8be814a84e959a1a8e3cf33dcc9f7464fd44814d0cd7ab85e4c01c9d015f42ce3723c8ef8c311222b0c78eb83d81696c217992be725faf27701b4922c6e6099442787ddde2b7572500a5320a4d0c787b786e\nTAG: 23c7a866574976dca8f401c4b5b58292\n\nKEY: 1cec3efc0311d623f34b6853b3dc97e470fa728cdfd65993d9d48fdc192b28e9\nNONCE: 320fe742ef171b7b8cb615cc\nIN: 722e503a97166a07974dcbf136fbaec6c03668fa52495b040383433ca59f6311103f2fc6a95ba4c925f8637167537321eff6949aa3051269fc094393a7b17d1ac8d29af052760835665b0ee89adda5dae7738656af9e8513c96e8a532a46ef34cd7430832d2be51c586a14e9aaec2458c1911bbc0f90b496737e838a12ff37d3db058bda9360d7d33e11629a\nAD: fd5ccf6b6948c3eb96543aa40f107fafe94e5206c326dd8900ea510c6b61d1bcf746151a75404e31406c8e991fbf6e660db7c18e243fd2608aa22dd7ca9de88f277037661ce6dea4ff0a86809dbfe1708cd47d3061a34657cad143e6577549c9944e08", "1f79c276300bb406378b26f349a91fa87de02a1405d712c516ae11b4bcf30ac9d56e677d03eb33e3be\nCT: 363c1d6b806a6d97e2fddf53b242378e1d2b818828863fbb3f856f7737d63998a84e02d6c91e1df5f5eb6cf89f7ef53e16d10ad52f82362292d3acafaa02c23be7da7616a8b8daf8ee3ae74ee1078742c4ddc3e5a110e510417b9f43fbcbb00e17af3301b2fbcb784fb0a05b66469e771fbd78114fce3c4352c42928bf5a0ecc49228a3c930b0790bde7ad7b\nTAG: 669482999be99149f9b723b60fec62d3\n\nKEY: d3465cdecaecbf25943b7bbf8084ccabc15474a4228c46cbe652a99be24a861b\nNONCE: 04fc836de3a1420b8e7136ca\nIN: 81e0e984ce0a4074a44524f93e375eabc650a847a42393f5c524c65523368d38a7e2b677fe08502dd3bc42311775016b5689c660cc0ca8cb33a09b89f3ed3d02fa0fb75ca5bf0dc3c27c546b369ab5e7731f93bc074d37ee50d6f8366f6c8a45f73ac92b05c4aa552ecc5266041dc122a0df69a36ad625a26edb57bfff43a84e527ea0d9d3cf076f8de9eda28eb09de3ff\nAD: e4adc14ac4bbf3ae7ec7d97f5c0e6090bf8127a75e8b70e9b86496a62a759dba5a4eef64a8c679c362785501260d29b58e1af647782564947950428dbf14edab8e6841c7afaf9e7949b560419c44bae30315c597f6f6e02204da7ec605a4d9a8753de1268bb0b1c84c972b4e7296da5c969781feeb35a44d2aef799ed228aa399ea04e21cf9f7d5600a2c07b047aa78388\nCT: d7995e7b610eede708526c05c584039d48b9b4356fc71b0c37ec2559309a688a7c69ac9655f94e178cd2311db58587863b0fbb990554dc9a6aa849571f945c61e5611ae7e1a96903be725a1aa75adc381b86e43fbc68a36f44e0e0cb8fe5c494caa91f758597b6ef3b80a879154cd8a7e5f570893b4f768105b24b58efb67c5f07c6db60e0f48eba9563f17d38aaf0847e\nTAG: cc3fe61642c2d7fcbd579048fdfb19ec\n\nKEY: 1a0dfe2a6bc6a69659c68942ad0858e1df905890f47dab728ab9c73f742f469f\nNONCE: f8f76b014116ba61392597de\nIN: d93eead436e835a061ca061e3a53c3f9c66c6f011b21682b8a6fed098bde2018a2462aa5ab542c69bfa2805612cf6146c9150888b9720db1dcd0f359c1fa3416df4cd225dd0b0d949e917adfb3e83bf5ba2b967d48908e6b6d8aabc545335014d951a67390d7b5c7cd7dcbcf66e4e3f02aa4e5e9cccaf73e75622bad006c63433d36cb1c6aa4aa253dd1b2eacac75c548aa6648ecf9d\nAD: 56ca2d5340629ca75de4e98921da352941559bd79f47ef0ab42d1d5857059352f96ee877f5458f090ca237e4eef5b08a53311c8dfd4c4582f18a93aaa8cf75080734cb2ea3389c9c74d2b04ead614eb54512ea93f0e3434e9a9366454b303a8129d6ce6cf96b1d6dd4f751311c736b517dcb50a6f6e0962c46637b4f5aaf0f34bff518cbd551a7aad3fa615708b17cf6d8fbc864f580\nCT: 8dc4d8483dc665b174ba32d6b6244da5f2a8fcc4b1865d662ec23057838b332a07ff073ecc893d413696f3fffc6dca5d107a5673f14abe8e0457a02e61138380d25e269686cbbd23cb7da3060f482f62bf80a40dcc2e711ecf5f7836ca14e456c4b73a48bef90749024393f5f8af01b73302e81bc37c4110dc26174702231d831cd14231905d2dd3f375cf2bef0425084d5b19f1039f\nTAG: 825e7b7e195f65c454ce9fdd637138c1\n\nKEY: 03cec87d0a947822493b5b67b918b5c6a6bbdebe45d016ec5cb6779c3ddfb35d\nNONCE: eb7d261a6b56a179c88e88ad\nIN: 2326102c58524326759ad399222c5b5a563cd01a29809d6aed4d49772a4723cfdf30c9f85f031063e838f543c201412d6f085a8f5435b0b2fe94659aaf70cf7bde99309239ed5b815b48342d4f81011f5aefe10ba105ac15601c64a91076c29c3cdafaa12bdd5706dd7305b48e923873cf06944b5027b210c59d79856f602bd6481980ea909152216756d77362c59d57673cedb91ee6f56a40061e\nAD: 4d0fbeb69c1869d2d23198ec49b3dc23149005a84aace7025293c3afb8cb2e38c167a822e25c2fdf667d3677f4e94ed6574529c987de506d26b7ffccf3b7a36d9adac48bca76084710338eeb5bfca9df1bf6b403e33e90761a0b3152afac333071a5ef4f54010b945d03b51f123865673e8877f41ca23359e60518f076cc64232b306bd858634417e92e546ede4ac6231635c9cfcf43aab1f8fc1e\nCT: 06746f993843901ce72f2fcd4af7d15e64b3102d2f9bec0fe72cdd0b97e43177a1a2238c9c1dfc3311f701196653249e767a73dbe819b660cee07a5f3bb8f25823875fb4b4d34a5a3a212d2e166311bbe11fb1d36f4e725c3b74054ed7fffb7082203ccb5e9d65873cb8a1ce28d5c6e2b6555c1a864a725e6c7d5555d37dcaf1d0884264be72d38cc4b65bc2f0d039d542c5055da56c57e084b804\nTAG: d36a4b6d2f592d4f0d347d906fc319cc\n\nKEY: 7f4b4bfa26719d9610c80ba3f474c43127f4aa3414fb070fc2f389e5219886e1\nNONCE: b144d4df961d4f1c25342d12\nIN: 638982b95d66ddb689b7b92e3adb683ac0ac19480148bac9db550be034cd18dbd10f2459c915e99c385cd8dc4dc6ec48b75f97e818030fc2d8fcdf66d66b80df64f0ca4af91bba83a74f3946b17af405bbbc6e216435641f5633ad3ee24c1a2ed1b39f649acce59ee56c282a3aebaee6e97f96b34cfc63d5b0482fec20d755f399dd5f61688fe55878713cc55d562c2d72236eb674a340d1a64932cdd8534a06\nAD: f2fe3d27bfc278cdcf16fffc541846d428b31534ec5cf51c30c8b6d988dc36cd6c0d41a4485a3f4469e92ea0fc7e694065bd8130c2854c95549630bd9cbaab2205f27a6efdc2c918c3be53f2d12f8f7cc8e6a81dc8be7cccd217be1fa2e6887cea7d637d2e2a390f50d2c5be10a32a9b380a400cddbdd40eac67f1fe9ba6033d4bfa88c563eaf57272c8a7052916cf4460f31ad026a0ac2588a45d082fbb5c0e\nCT: 0d4de3489e09c7239972b675063579e409acbb663bea76bee8fb3f7e8785158ebe1c26db9219a9b97ea29e74762999518613249c3a87fbcd0128f651e2db8e2167f10ab532eced3464b56bcaa09780e5ece18182a6e092477ad933bd8de015c80e67c6802257a97a647fe2b1e9ab6a76c1cbf7d905deeb824aba2a34095f84b276d55ff940d6ab788c16cd63d9b16e0908d718c851a3230b0a37257751df5a38\nTAG: 9f0a882d4456847f44c7287c8ff3ba04\n\nKEY: 9799ae8045d58250e4d9c3b0ccc8897a04b5b9fb164e54019dc58d7d77b65459\nNONCE: 0f20d002dbcd06528a23d5e0\nIN: 8f323018b1b636617c935791e1c8023f887da67974080af07378b533a7573424f1de9193c5d38f55e9af870f6c60ab49c80d7d1ad1f18f1a34893fd2892d49c315ee668c431f5f35e3f60ecfd534b4b09b64cc77cd16b0e1b8882872cd109a5ca377518e5b660d75052e9a4228e3935705b6bf6b4f4249346b7bf4afb891641a76621cd315cd75de391c898959be945ccca7a96073f2569f217617b08502f7d569bd2f80e0\nAD: 3f1e297bd91a276a4a4b613add617b0488414a57ede2ac75d10934e03be58ec518a418e98a4dbb39d2365889db7c5f389b2a16d8c702cf21b888a4cbf77b356df48a30298c825fb86128de45d7fa0e5f4b0b7bf82a2c4cad2470f33c231802263901fbda54a6edbf2df638716492157ec1407e7fc2eb6c663d9a215afbec3612778b8115e78a5fd68cf6ce66c12c0ca26e5c1f7ab079bc09c3bc7b673d21835671a13dd2a0\nCT: 9a5758dad7997a766db05d698b43fd491bdcec21352032cc023bcf10e136523219745a56f0360efee75a37de55da23cc7d8184a50ccebb110bcb960dcf6b25fe731e21f26290281d9c1c7715c4e6ff3dc0026cce52929163ba222f123d4f50e1d3cf67725fb4737f4010ee2b5b163ca6251c50efe05c5ab0b1ff57b97ffa24c98653f5c82690d40c791047a3d5e553a0142fa2f4346cfcd1c849a9647885c0daaac9efe222\nTAG: 5b85501a476217f100be680b2f5882cb\n\nKEY: a26c0e3864a7dd3b589d17a74a7c9c1f7e8f9adb4aafa0e75c083d10956b6bf6\nNONCE: b54a2a43ca3f84aef3824375\nIN: 6fd4ec60613646490791d82de30ded1a12e61fd270f1642d2221272dbb150ef63ef2604213e203b740dfc9c4bcdf722b3c85aa20abb1197949de710d7e8311956c8649524afc72a9bf5eddf0b284c7fc6d48a741b82c215a0dcd73bb8afd08d5532a6f7f99b5c6beb2ad793d6da53a81e6523b2240729924ddac996a723421f57125f928990daa7a55a5b6b53d7361d9728f66590d969659aacd9aa5c0ec627d991b55e9fd0bf9c3210f\nAD: d6d8b570eca29a48a4d408d5b27ec6aec291d70cfefcd02bbfe8d8ba8aeb6db770bfd723d2c3a4859f1992767d24e7b33e3e241874292af640e2bd22a5b77e0e9e1e0d5e485041cac41d4694ac929ae1fbc08e7591e1cef689028f5db26f95fc9e0868887fb9c635579fc6335757697f63b4f2b46664ae338eafdd827988c8f2ebad80ea9787871ed8d6b302d5dbf7e8019f2e139c59036cb5964a3701ec049b839e19e33e68b83539c8\nCT: 2420e09adb24098038b2750c946551a5f6a5bdf23b126947348ddb5e938b3fcb874b33fbac6407095e05ce62df999e7234cd2b4e413009c71d855b23993cd58c1e26ba0deed891dc88f099fdf852cec0aab45f488a90edd8feb6f4c837036945bd304edbf7a2737921a2f8c1b00a1daaf9e25b908a65a8f69963fc767bc975b5b7bcc215ce37009009dc90b5c7edb1a1174a10ad28f4c1d1a2241e7ffc215edef4f847ceedf7b64f2d15\nTAG: 20521b35310385ae66557740b435d204\n\nKEY: 53ef3dc7a10e435650dd20550cf3ec2b997afc8d9e79cca8f7062622afac3496\nNONCE: 257a205ed0f84016183f4613\nIN: 081e2769935f945419aa06fb5fa7d8412efd1f9b52a45863808022850836c1974d53d2b2c5c0cd420711a71e6d1a09e984366b8b677e6c61bbce8f3adf9f5a9fb5860887617a08c923171d681c4fbc6d569690f6a183d42b52a80ef0693862efd22bf83b7b4014a7008424c356b5022df1842309b3a4a2caee0fd3f4d3fc52a17d53959daccf8e0ca889578ee2905dd8c17d52e76712dc104344148e8184c82af8165ea8386f91de585b54fc8535c3\nAD: 5b73ae02bf4a70e57f5d48fbf45f85b8496ae8514c8aeb779c184f9cf823d8c1883c9e5a42b2c099d959c2298ace2d86c4479059256d6a4325e109fa4b6c4ce90f84a8228316e80aa86de9b5e111d88b2be447a29297b35ca90a8eb280d4c0fe92a1d593cb966cb0010bc06831efb0c72c1e222b031e900ef06ab8da542a5abe2870a0efbe92351d5915ab545b14900e41a27c5ca9d75d6277afafe7ae861131c2767eb314c0c3da5c264f8f2b4ac7\nCT: 20ecb6cda861b660656d692c626436227bd4ac17a9bc71f6c84a1917ef3b5a0f6ba370f00fa2e7f1bd5aa8d6c15032572090482c23e4ab7376ef1f4dfb77f79d5dc065792fe3476c9c37614e32f493e461981b519dd7d10234c2c69264ffe5be06a8e14c81022b652c8cfa24adcc7c7536a55a2fc41e9ffcd09e1c483541cba814eafd5e09e9e44477018a41b073e387c9257c07d97e40f0761fe295d015e1f2df5be65b13f34b6ef0fe1b109ad109\nTAG: c129ba4", @@ -578,9 +638,9 @@ static const char *kData15[] = { "2d59740c9b9d4b97075b874015251ad55483068b00f87502b18182b140db07c70a80fd884fd79b7b5fef1d307ca4db0ff046494443e1cae83478d275c31402035f1fc24e26214b78d9a4dac78d074150012f9fee810a121d87a16d8e1eec5700e9facba350029788480a259d9f30df1c2b8df7691629314391719853c0b68614134f6028865700b1fc4e7f34ff28f449c6abc3027f38d7a7f6d84b8f27f7cc5afa09478c809eec346bb58244ab42a3bef61a14ae7640d76591343983de9fe5f1b985ce56c9fcfb2e3f6220779ca6f92a6b8aa726573b38ed7663ebe4c85066ae3f488ea3309593fa41dba8efd2b8f44b9fa8f7a427823c1228093a3\nTAG: f1832022e06228c36181856325d4eb68\n\nKEY: 3828b138f72f8fe793d46c55ad413bab31a51e7a9093cdd10fddb4739e28e678\nNONCE: a60413c0ab529ccf3de58468\nIN: fec017c1c51da5ce9dcd8e84cdc03a43145b31edfd039c7c85d8811a2f58efe7a2d7590149a98cf0b5af82d3e0a325223bc9d5585ceb1afc4cdd96024be6c8064c2abac14f68e65de49e25e3e967500ce5b4504d00a9cbad1e86bbdcf65c01a7a92de27583b7b92122b6a4923b7192994a1edf00b75d14a982f92559dbc2d5e427a75ad29715375d90193ddbb39b9a52c1a23d75629c539e0a6ce822c7c08fc77dcd3adc357893215df4694673a16d34513de21217ce86897c8f0575d213ce0c66eb1d1985fe73dd86da3ab5e89df4243e1be9dd95af94f878995d02929ee42a062100d6d4d3884730f54593d5ff7b7ae53e03d4f0e10f6f4c3077206499ab7d4de1e825d532d0918f\nAD: e2b16ff2b6c73c9374704ffb4cdfe7bad9eeee32157f2eedf427f99c2cce80c5aa4d9145e85af0cb08e6ed477cbe79ee168ded5c0895f9f4f939c21916b3dd5c9d268b3aabdefb85d953bce9b70732fc9acf6c7b727f78d8c9aaca9e022d7cf0f95583e81744227d87fa34ae19de44d202ba01e3d03993f38c9b2fb00b54dfb677d67e6f5a15f46c29eb5597ae3d5384b37bbeca3f3d825e2b7cceaaeb36a8c1273062259608956dd0c79877cc460d0268de27355e34b9d8d1188c062ac5e10a73f2d70fd0636304b3de06cffeedd246e2db19b8b66785f9f9c62b8f0198f29d37a4ab5280f4aa0320559810f89a1618844d0ad5f3a4f5a0e834ab31e56798b7158217f834d372c36f\nCT: 88ea11ef6b6ee6fb0be77bcbf227e77508922550ef0d7534bf05668ae5fcab2f4defe643747716e7e000950e36c6cb24b79987389a150382c091d39ddf841b0a5e31d763d9c59753a3ef36a23b81f38e6e715357395ce715d30c14d6ab5b7454804ecf633daa39b6107f562fae6a646efb25c1119dd17955bb9e640105a21566345408f72f2acc8f2726a0be465551f9ae566da559fc0b92c36764c5ca20a18a316c02e606030a53450e7ae1146050a48a64c600d33cb84389b0bdac7ff45d3d1f2f669a6e365ef722d76d2fe9bef2df93c58bbdd6965e18111b5de0f4a62dbb874161bf8adfa61e9cdecd97b4fff668b3efeb3e32eeb929cf58d94ad8077c0a2ca79e80877c5d9329\nTAG: 9b47afc5816b7229213cd3c9135545ed\n\nKEY: 91ea63dc27d9d6bbc279ec6cecdce6c45ff0b247cfb8e26b6ab15f9b63b031a4\nNONCE: 80a134fac73eca30459d5964\nIN: a848e41c77ac8c733370435b5b6a9960af36031e96260d5703ce15b003606875a7901cd11e4571bf88dda29a627c0b98065a8b4e6d382852dfa4f47d86fa08e48ad8f5a98e55c305900b83200d44029f304abd21e0264115192a3fd7b0eb69b9f8ca7865b3be93f4ba5a28468fd7bbb584c32ae867f5146efbeb1412d3ac36c30cb308c327a6f207e30f561d6efe0a535446c693e14176e9e714ffb5a5b1075812909a362a6c4bbe18322e15690c2c9cf5a18e0120c11551cb7055b5aee97e7a56d7c24fdf1214641c8eacb196d74f3d96a7fbecdd4fe52dc7b6ead9041cafd5a3fdf91fd3614e63189b488d4d7c1ea3c6351d112a2223b29d390ac3ab7f09a60bbd3df6e0d606d902aa44244334\nAD: 47940a0694183b2fcb5e760c9ef6dbe4cbff6ccf33208337a981138f9d35c03f8adbd810e94636acaebef6791b531a65e99b03fc78e7eb48036615874e97cf762fa6ca5d880bb2c2f644f1aed70c667880f98834d501caa277cb8ef1095ff882e79c3a92ea8982abebf63ea9ed7e9a24d32cb81d5d98e891974e3d636a59e165984e00f05a040d33f07b39eccb924fb24780a422a6b2b7bddb5b316beddcf6fad20e4cee7d0141c2f7c4e4f759db8691dc7b8525ccbc3ee6071a2ead63e750d6d92dde7eb1303d5b1194702b6c3e0c2e6f9649e60eeddec9c1f71cf309af0672cd2ffcf94ba7e6c3d7cee020a224a9a956274d1d36ba16030e215d90a165756666eff066a8e51bf7d4babe8b7d8d\nCT: b90449af99327afb1124bb24f1c8b5cb878423b0370d5f7cd297b28cc4135ee77d6f1913a221cfeee119bafa873072bfa79e303fe377bbed05add41ce3a42ca4632b98f40a36227de1a9ba84d6176c01eca9d33d954d0ebdf4e40f136e0f6a56156fbb33b344a8a433941fd6e08774bd00075aedb0e396c2bc37d1250541248dbeb899e1b5170cdfeaf7b89995b049428bb277c501354f8cd48fb58f6f04f956dfd099c48778dbdbb4c95b7c9d6797cf6d3bcd1d00e88cea885ee4a10d94356509e148990a0e10dd89103a9d5c8434a7bdbed6c0ac1271e0709eba144abf3cf075c020e9f7835d5a98fb2439b399e377ae6e19fc5f32df9ddfb9e936190d3e9c62de99835249d1f32ca3f92ecd44\nTAG: 6ccaf7c142d86b83e4d0b4289b49c4d4\n\nKEY: 1344db082889367fd48c5f06bc39f9cb9e3ad4b92fa484ccf49418dd4caa2e19\nNONCE: c04a98e7e29326b5330818d4\nIN: b0e12e3122c1ebfdcadded5a45163a6208548e9bdf95cfd18ea504e5d2e97372e58dbfe460a57b724d38f3bc0ce02a54015779bcf127343474d7d4c1402d598bee56897203b903da5b819e2218bd0d1a2af11c542544f02c46969cd2bfac683b76a8de61698ccba63361a1a0b570adf69d24e9a7e466873c8c12e25e0bcead7828386179a4d65d5bbdb800eb52fc01b67498d7b5f9864270162158a8572eccf541b07833f001848672098c57708eb479855799567c318b1aa097efa70db0d8a8d36fe0ac22ebcc2870baacac690a79e07ab286acad9f7a877939cf2989cd6200eb86dfa7a41e969a3683ceacc7c97d1cd5487f13c439a9777a67770687657d38267a347a0b6d3aa3cf64e7f31017246e4369da\nAD: c96db14dbc2aa0ce3ac63794f75c7e78037dac6763282edb307821a7938de4baa3d2e35a8cfe0c8724c2a8d870d0a462ea157e15aacc69a3c881d9c819225ea8be479872d55e655c897936c95b9ab340820264567495fc5e4e3354f42b84e191b470ca9f4d8fc25d011bf9c9e73e1590e1bb919dd2f288b26935fbfb8c93e54331dc8edad5e1cc4aec103c2f3320d59870c1770319f105ee790b704ed655be423e63ab040f1153f41e7070ae3a0f34d217c4649c180c84814463902d99a9396f8c7c85a3a4c8ae2f01737649fae478a40fc72303a108822775e9c421f945cc0eea992730790a9aa0c0d014518dab371b52d30b5a560f34946a9344cfb8a19b09ee9b123bcb8f642780697508f04983b790dd2d\nCT: ffda075dbde7b874995230e1324f17894689baaa7f1354e26100befb546ea23dc74807818e43a3cee00ec1bbb95c82180489ae5f3a1c482dec28f96ecaf5ca4655ff7f33c814197cb1973cf02a0b720a5c44068d8ddff0789fc1e7f20ef408c1a438133fce4f7a3e8c85d95a381b94e949ce47a85895c4be7cbfad468e52a160dee34b8ddeef2ab280eaaed4990ecec790ac16de3c74aac6fe2d5e28ea2b66a921c894a3971cee4a2158054c3567e0d941f867ded5ed1d21d8ab090848fb3eddfb1559bf11815db52b8eed871cfc117980f297da79da31da32de3f162a03d95090d3329da3662df29e6ec9b236e0f7c1d7d957cfd54d5efc99c694b9dece989912388254798513d881e5943ce830729a8e2ddf\nTAG: 81c55fe9aa2de0d63efe3f74a3d8096f\n\nKEY: 31dbefe589b661af00a6fbad426e013f30f448c763f957bbcbaf9c09764f4a95\nNONCE: 147fe99bba0f606c57242314\nIN: 908bd801b70d85085dd480e1207a4a4b7ef179dac495a9befb16afe5adf7cb6f6d734882e6e96f587d38bfc080341dc8d5428a5fe3498b9d5faa497f60646bcb1155d2342f6b26381795daeb261d4ab1415f35c6c8ac9c8e90ea34823122df25c6ddae365cc66d92fc2fe2941f60895e00233b2e5968b01e2811c8c6f7a0a229f1c301a72715bd5c35234c1be81ef7d5cc2779e146314d3783a7aa72d87a8f107654b93cb66e3648c26fc9e4a2f0378fa178c586d096092f6a80e2e03708da72d6e4d7316c2384a522459a4ad369c82d192f6f695b0d90fcc47c6f86b8bbc6f2f4ea303aa64f5ce8b8710da62482147bcc29c8238116549256a7a011fd9c78bbb8c40e278740dc156c2cc99c3591fec2918cdeb5240fb428\nAD: 5a32d7044f003b2ffefffe5896933f4d8d64909fa03e321a1bdf063099b9f89752d72e877291d8da12340c5dd570d7d42984ffab5177824fc5483b4faf488504e6822e371dca9af541c6a97312b9cbf341b4198b0902cd2985ac10a8b5b5fe9691bb29a88344f863c980e4e871a72a8b74f92eef68c176e9d2ef037898ff567298e186af52ec62eb7429a8004ac46b945678b82859396d36d388ec3d67653aec35cf1da2684bbc6c78a5f9e3ce1b355af3b207f64e0fa73501c5d48a14638d0906c87eaa876debcf1a532c1475d80ed3d4b96458d2236eb9f67988863bc6d5c16b96b93d898683d248d7bc601b5035fc365481b89465e37a8f7dd64635e19a0282639cecde72c6b1638e0aa6e56f9c00d031cdadc59ce37e\nCT: aeab9db30a579ca54195e54a9e6c787f40100c6d12ceee35643f36ae45f618cc9bb66aa4c0fae0ec2686cb4101a5b23a46877460c7e020b38b0d8d1f533ecfa99df03d346bc854a578276d7d5685ad1fb03655683a64aae4159c9efa6781f053057e0811226c7c533967a94587f4025353b28cc3a2ce5763783b4c31e7818b8ad9195bc03be8f294f9f6ceac578f9d30b22b1f5a68d647d46cf6db4a9c3a8a5c06fa97c9efb4578f501ea96db1f40942e3f24c44a7e4070a6b931c39947d9692930b67767357015de51a39e46fff94b6019e4bc1ad9d216a571ba0dc88859c49d2c487ca657384e49b4d382d86a60c8d5195320909c4e82fc077a3b22bd4eccf0f067e66ec78eed642b2d16f0f304f60f1d9ba69e205c982\nTAG: 17ca09e3084504fc22e914ee28312c8e\n\nKEY: 0ecc44c9036961fba57c841ace4ca3c547c51d9f126567bf41626765cfcbd53b\nNONCE: aa98b6ddff7e4b2041f29d70\nIN: e49a2a5713f507bfa00c140dfbefc0c43e37bcb932e0741db03f0055da61cd837b6e2d8f99115d70750fb23685a17121b52e98a37c87204e0207729fd9219d11a48e57970d790338793cf329f7b239512a44dd4409fe9d157f92123dfc5cba24af106442644dedda87e1d9e95fd395f2f0ad8f7d27f313e6ce1a07d9845dec5ad732e6e4749b3a161527c8ce42331f5de1d700650072fb68e9c7645a0e0e529d0563d2727e3fb38ed341f74ef1ad95a0216a440e1384d0e7ef71cde38ce", "cdc9e2b2d563f19014c40c1f92ea0af3b4f6da9146d433ae85f647153db326a28ef6ea2e0ebac0cc1aff157067c7dba7cc4317d56920ee9deab5764368e7e5b3ce8bebd0fa129f869b15897c09659c53188bf8efb7b6ac7d265c9b85fe96166\nAD: df41db4ef5350d4afcaa88b4a577b3370b96699bbd73e59aeebca6ea856cf22694a9399ae7f97a3bec226d82f5598f8949dfb92530dcfe77770f066f2af988fba5543b8ba7655bc43f8dca032981a34a1beff695c6908169d475c55b2119fe5578623f68a9dd85b653656881b0db4006d3336fdfc784d1805e48ff478fdc196601f044c9d33fca3ddde2db0102f90fff0b370f520e00e3786c2a9b0b4a9a7ea6f9d866f77d870c8ef0f3a8bedef17949a32598512af665679dfbe71e1c3efc3dee8f5d4499e20dc63281191751f67e51f201973a6675896484527d66bed94d6aaceff65fbc4192cec19452b8873f22d72bf2f4981fe656285cb24be5c58e77dafd3e096166b230f18d3f4197fe16f6ec84c060ce0793ae6848311a18b7\nCT: b15b2bc4b9e8ecc5d9c4a6359a805b7590bdb4bfaa9b3fc4d7676d721edc4b3b1ef71b18a3d78f1b31a477cf25e55b278eb3ed774805ae8e5a2a0204f7291d9587663c4d8b1b744154f3b7cef796e0b91590161f3bde82f1d8139cb8d017606ae6d0552ba144788fd8caf435ab09a43a1f4057776af49bad98fc35cefefb159cfebfed76f2e4d18b7be143677ff8b3d6e2b440fe68475b5a1193bcd19ab157d0d2257f33de8e50091ea3388648c3410aa68c830566a0413d92454e4eff433c3edc74e8f7516ec17b2c01cf57a2d7c48db97b706b8d7da0b68051f2d6a87c417f46cf217a48611980890f669d39b478c35d834ed2c79299df2381a1215d6db303cb63e2795fe517649874226e0a6dbfe2c86370b9fbdd8c5de349bfa25f\nTAG: 7082c7ef72c82d23e0ba524132acd208\n\nKEY: c05dc14b5def43f2e8f86c3008ef44e4dc6513768812e9218b2b216818c4cec6\nNONCE: 5cfe0dca6e599ed9aa89ba97\nIN: 8a06e2997b8e5f8040b22e07978c83c48d0f90bd2b2f8b426b43feea0b614d3b0681745ea4224cabcaa25ca45c3053a6300c47ffa4f72e838db135ae35c27939aad4cf7f75fb61daa3148d869057598e4e8b44c6fb19b0d9281e18676d8bc137489bb77a51a3a8f807a896d558f00040e8729ea9bbdc7db6102c8b99c8a1eacb0735577bc6533cd1d8147013935b6344116090a1bdef1f2e38a877a50c8fc0f394bafede31375c57476ba06d95ae734e6dae771a32e5091dff71d845c5f7385b9b9069ced12fcfea34a510880b088bb0016e94a5932c89baee038cbafbf06b3d09426afd2d5dd5e392636362e9ffa9186b5c753eb84f82f68fb1286ed06c58a5a936cad018ebc4269037b49f2ea0349373adea99f06062e5dbb0bf94f2883f5c0556\nAD: f2a3f7af8ea984bbd85953f14202c6e478f98d0bcaacd414329ec480d0c29fb4c1a052d3228c883928448f0bef12cee5b69829b4a3eb4680084131867cfc3d3af84fcc0d80c2292d3fe02405634f6cfb20b0fb90345da3a557fb30582175c32e432be66ad096f9425ff4060df54d6741fd6567a1e2fc5f6f3ed95cefc806ff64ae91ae82920b5c829ea026f83fd90d760e240da3c9ddaafe4d08507f4af1049056dc6d09657779a3dbd889d851e97d4ac60dc66df2d24979ba8947a7890a304bb301d0d42b67824e0c68fc882e90cb6deee50c2e3d9f0da59ab23c997b05635a0d56c71fc39aa0e6b19c43a7fe12d4e4145453cd7fbd8a3f33bf5451addf05052df7ef044a33513bc5f1a4cfc8b68015664bb5c8e4bf54a85efff109ee96af75d4a5\nCT: 2cf630548d6f2b449057c7861920308958199f77b123a142c6b7c89c4982f4ed0efa2fe899914ddbf4543e70865a5e683b0721d6c8443df2e697acf31e11c8809aba94196409020a7c64d396fe136826455aec973af23a6c7733cb567f5ea550e50e0b796623a97807d042855568e3c568990cfc818c31a1bf415337f43e9baed57fada2fb2ad3c3543f2b7f2777e03f84040c1c854c310ab1cc5dc7f2a5fb213af79ac068b46c7d9475bea126adf079e2100bb57904a931faf248e0f7d5832ca83ea8a283e0136979737132afb1f4ab38d307ac0774814f4d5ecdc4aad79185c05f8a706f579b78f2c1c7004cb38e6cd22c2080735b34c3f6134955ed3bc36b1ad5c8e33209c9f3c658fb07b59b6002b2526cd8d853a5c624b7108573d7df60c827\nTAG: 3dcdabcd1c82002a551cea41921570e5\n\nKEY: b33f449deccc2ef0d7616f22b4a00fcd84c51a8383782f66f1696bc6405005ee\nNONCE: 6afa8baf923f986b5779ac6a\nIN: b0af85a6deae5fcaa94778bce015ce2da7400ab768f3e114cc1b645fb2716789e2aeb96894fda6da5bc24fcf2466124720d6ba99e5475d77e5bcf2c2f8c8e5becf5eb73ad650861bbdeb51ba5ee789c227478934200fc18f36e4fe392c99d4c3fe0b38b40d2e84f831b8ef9bce9ac1362c755943521ecf5b5cf8fbcdf08f2d47ff7cd62838597dd342695a1b037bcede69500bf70bf1edbb40a17b44695bd8ff8bc8664b3211a6bbfdcbd1bffbfb1a2ea0141cfbc6ac841c803b137be5eeb2666c46c09cc1c4fa82be43bfd56e7a2b8ceeecb6efc1933a90213a0e1bc7aca2af35f2d1dad5f0d9002561064a699f1ce76c39d9c2224ae596e88a1517e19c2115370768d50107f3f2a55051838ae5897acf2ac0814ccd864eee2f6b5d7a6728c6ac6e6a57327102\nAD: 2134f74e882a44e457c38b6580cd58ce20e81267baeb4a9d50c41ababc2a91ddf300c39963643d3c0797b628c75a5fc39c058d319e7d6deb836334dbe8e1fe3cc5704b90c712e1fb60a3c8b58d474a73d65fae886394f8b2c029e420b923f2af4d54c9de3c7fa2bccaa1e96664ccf681cacbbf9845069a4bfd6c135c4392d7d6be338eca414e3a45f50510718e2a5a3e5815eafa0c50172cf5f147510645d2269929843bbbab682deb5823d4cdf42bd250bdbd20c43e2919d7a6e48973f43a4cab73454b97cdca96721ebd83b6dbaaec7e12cf0dae678a57c431b81421657037dd47dccbee73a41f56495fd7c25c75744fe8f55cbd1eac4a174d8f7dd6f6ba57b3e53449a9ce7806517e3e07cf6546a0fa62c7b1fa244d42eee64a3182461792edb628e567b23a\nCT: 0fe35823610ea698aeb5b571f3ebbaf0ac3586ecb3b24fcc7c56943d4426f7fdf4e4a53fb430751456d41551f8e5502faa0e1ac5f452b27b13c1dc63e9231c6b192f8dd2978300293298acb6293459d3204429e374881085d49ed6ad76f1d85e3f6dd5455a7a5a9d7127386a30f80658395dc8eb158e5ca052a7137feef28aa247e176cceb9c031f73fb8d48139e3bdb30e2e19627f7fc3501a6d6287e2fb89ad184cefa1774585aa663586f289c778462eee3cd88071140274770e4ed98b9b83cd4fa659fcdd2d1fde7e58333c6cf7f83fe285b97ad8f276a375fafa15f88e6167f5f2bfb95af1aefee80b0620a9bc09402ab79036e716f0c8d518ae2fa15094f6ea4c5e8b283f97cc27f2f1d0b6367b4b508c7bad16f1539325751bd785e9e08cd508bdb3b84\nTAG: 1976d7e121704ce463a8d4fe1b93d90f\n\n# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\n\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: \"\"\nCT: \"\"\nAD: \"\"\nTAG: 530f8afbc74536b9a963b4f1c4cb738b\n\nKEY: 0000000000000000000000000000000000000000000000000000000000000000\nNONCE: 000000000000000000000000\nIN: 00000000000000000000000000000000\nCT: cea7403d4d606b6e074ec5d3baf39d18\nAD: \"\"\nTAG: d0d1c8a799996bf0265b98b5d48ab919\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbaddecaf888\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nAD: \"\"\nTAG: b094dac5d93471bdec1a502270e3cc6c\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbaddecaf888\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 76fc6ece0f4e1768cddf8853bb2d551b\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nNONCE: cafebabefacedbad\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: 3a337dbf46a792c45e454913fe2ea8f2\n\nKEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nNONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nIN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCT: 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f\nAD: feedfacedeadbeeffeedfacedeadbeefabaddad2\nTAG: a44a8266ee1c8eb0c8b5d4cf5ae9f19a\n", }; -static const size_t kLen16 = 69162; +static const size_t kLen17 = 69162; -static const char *kData16[] = { +static const char *kData17[] = { "# Test vector from RFC 8439 Section 2.8.1.\n\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: 070000004041424344454647\nIN: \"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.\"\nAD: 50515253c0c1c2c3c4c5c6c7\nCT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116\nTAG: 1ae10b594f09e26a7e902ecbd0600691\n\n# Test padding AD with 15 zeros in the tag calculation.\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: 070000004041424344454647\nIN: \"123456789abcdef0\"\nAD: \"1\"\nCT: ae49da6934cb77822c83ed9852e46c9e\nTAG: dac9c841c168379dcf8f2bb8e22d6da2\n\n# Test padding IN with 15 zeros in the tag calculation.\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: 070000004041424344454647\nIN: \"1\"\nAD: \"123456789abcdef0\"\nCT: ae\nTAG: 3ed2f824f901a8994052f852127c196a\n\n# Test padding AD with 1 zero in the tag calculation.\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: 070000004041424344454647\nIN: \"123456789abcdef0\"\nAD: \"123456789abcdef\"\nCT: ae49da6934cb77822c83ed9852e46c9e\nTAG: 2e9c9b1689adb5ec444002eb920efb66\n\n# Test padding IN with 1 zero in the tag calculation.\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: 070000004041424344454647\nIN: \"123456789abcdef\"\nAD: \"123456789abcdef0\"\nCT: ae49da6934cb77822c83ed9852e46c\nTAG: 05b2937f8bbc64fed21f0fb74cd7147c\n\n# Test maximal nonce value.\nKEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nNONCE: ffffffffffffffffffffffff\nIN: \"123456789abcdef0\"\nAD: \"123456789abcdef0\"\nCT: e275aeb341e1fc9a70c4fd4496fc7cdb\nTAG: 41acd0560ea6843d3e5d4e5babf6e946\n\nKEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6\nNONCE: 000000003de9c0da2bd7f91e\nIN: \"\"\nAD: \"\"\nCT: \"\"\nTAG: 5a6e21f4ba6dbee57380e79e79c30def\n\nKEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5\nNONCE: 000000001e8b4c510f5ca083\nIN: 8c8419bc27\nAD: 34ab88c265\nCT: 1a7c2f33f5\nTAG: 2a63876a887f4f080c9df418813fc1fd\n\nKEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007\nNONCE: 00000000cd7cf67be39c794a\nIN: 86d09974840bded2a5ca\nAD: 87e229d4500845a079c0\nCT: e3e446f7ede9a19b62a4\nTAG: 356d9eda66d08016b853d87c08b5c1b3\n\nKEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3\nNONCE: 000000001d12d6d91848f2ea\nIN: 537a645387f22d6f6dbbea568d3feb\nAD: bef267c99aec8af56bc238612bfea6\nCT: 281a366705c5a24b94e56146681e44\nTAG: 59143dab187449060a3ec2a1681613cc\n\nKEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685\nNONCE: 000000002bca0e59e39508d3\nIN: b76733895c871edd728a45ed1a21f15a9597d49d\nAD: cc1243ea54272db602fb0853c8e7027c56338b6c\nCT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858\nTAG: 219b4252deb16a43b292165aabc5d5ce\n\nKEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c\nNONCE: 0000000013ce7382734c4a71\nIN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb\nAD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9\nCT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f\nTAG: 7ae32f186cf9ec59b41b764b34307d4f\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a84138648a5919a\n\nKEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14\nNONCE: 00000000c7f2f7a233104a2d\nIN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338\nAD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb\nCT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe\nTAG: 63c2b4e0973096299488b0a66ffa54c1\n\nKEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc\nNONCE: 0000000088049f44ba61b88f\nIN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89\nAD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc\nCT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638\nTAG: 4461139c4055333106cf7f7556fd4171\n\nKEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48\nNONCE: 00000000066215be6567377a\nIN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d\nAD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb\nCT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346\nTAG: b2ad07b86aca1b3ab34033c12d6a08cc\n\nKEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde\nNONCE: 000000003f2d44e7b352360f\nIN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344\nAD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb\nCT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943\nTAG: 6de01091d749f189c4e25aa315b31495\n\nKEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a\nNONCE: 000000001b9cd73d2fc3cb8e\nIN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f\nAD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c\nCT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd\nTAG: 0887ec7d5e1a4e532746ec247a30825a\n\nKEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97\nNONCE: 00000000d69e54badec11560\nIN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276\nAD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9\nCT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320\nTAG: a27f18846f5a4f7fcc724656c91cf4f3\n\nKEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639\nNONCE: 0000000088b54b28d6da8c81\nIN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284\nAD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575\nCT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d\nTAG: 854cbb42bade86a09597482c8604681a\n\nKEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13\nNONCE: 00000000c5c8009459b9e31a\nIN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab\nAD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce\nCT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0\nTAG: 2865d2a26f413cc92416340f9491e1be\n\nKEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020\nNONCE: 00000000ce5cf6fef84d0010\nIN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2\nAD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142\nCT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba\nTAG: 1414f1b91966340417c38226ccca9d3d\n\nKEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4\nNONCE: 000000008b6ba494c540fba4\nIN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365a", "fc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5\nAD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f\nCT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945\nTAG: c5ca34599c6a8b357c6723ee12b24da8\n\nKEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d\nNONCE: 00000000d3875d1b6c808353\nIN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c\nAD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280\nCT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e\nTAG: e84211b6cfd43543f8b1b4db07a494d1\n\nKEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c\nNONCE: 0000000040b32e3fdc646453\nIN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14\nAD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd\nCT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51\nTAG: 55e025a1eb87bc84d4be00c775c92ad2\n\nKEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866\nNONCE: 000000009559bd08718b75af\nIN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9\nAD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2\nCT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37\nTAG: ab1d8a5a1f3eda9b5609c0028737477f\n\nKEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf\nNONCE: 00000000d9dae2ea8d2ffc31\nIN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23\nAD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06\nCT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef\nTAG: 1c6bdff7d8b9554dc7bf40e50b37d352\n\nKEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507\nNONCE: 000000008a81c92b37221f2f\nIN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97\nAD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075\nCT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661\nTAG: 689a141bc11159d306dad7a4ecf6ad9d\n\nKEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a\nNONCE: 000000003c4c6f0281841aff\nIN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83\nAD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92\nCT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40\nTAG: 780cc54bb6f1c9b78545c1562cd9d550\n\nKEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466\nNONCE: 000000006255bf5c71bb27d1\nIN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44\nAD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3\nCT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe\nTAG: 2ecccea4607d14dbb2d2475792aeb468\n\nKEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638\nNONCE: 00000000a28a6dedf3f2b01a\nIN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212\nAD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2\nCT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf\nTAG: 17ec6cf2b172f01e3c456ad047196805\n\nKEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9\nNONCE: 0000000056fb4923a97e9320\nIN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd\nAD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf\nCT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787\nTAG: d29a8968067aeb457ffc114c3a9efb95\n\nKEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54\nNONCE: 000000002f4a5ca096a4faf8\nIN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd\nAD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7\nCT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc01683", "8dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86\nTAG: 28a5284696ed82714eaa94c9ebe6e815\n\nKEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0\nNONCE: 00000000b5e35fe3398efa34\nIN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc\nAD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5\nCT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf\nTAG: 4ef49e8a0c2ef85826d7f03e81c577f2\n\nKEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401\nNONCE: 00000000f0c4a213a6168aab\nIN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98\nAD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd\nCT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43\nTAG: fad7d5a5193dfb121c68529ba8c0c35d\n\nKEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b\nNONCE: 000000007968379a8ce88117\nIN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa\nAD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3\nCT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c\nTAG: 96ae06cd7c72456e5568a42317046158\n\nKEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714\nNONCE: 00000000fdd913a321c40eb0\nIN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814\nAD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca\nCT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e\nTAG: bcf523a9bcf772e157941753c6d7401e\n\nKEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29\nNONCE: 00000000a6c191f6d1818f8e\nIN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303\nAD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815\nCT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092\nTAG: bd05336ed6426de412aac37661953052\n\nKEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99\nNONCE: 000000007b3ae31f8f938251\nIN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d\nAD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485\nCT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74\nTAG: d48657033095db3f873c33445fec8d35\n\nKEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7\nNONCE: 000000002358ae0ce3fb8e9f\nIN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac\nAD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f\nCT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23\nTAG: 298f84c8312029a7b1f38c5ea6021f57\n\nKEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83\nNONCE: 00000000263a2fc06a2872e7\nIN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3\nAD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af79", @@ -591,32 +651,33 @@ static const char *kData16[] = { "16b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70\nAD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860\nCT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50\nTAG: 0fa4cb2bab84336409aa4349ab99a8bd\n\nKEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0\nNONCE: 00000000a0f73297b87f5deb\nIN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d\nAD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3\nCT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc\nTAG: 9bd8b7743c056bb2334833afd6143e18\n\nKEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b\nNONCE: 00000000e7a87e6bf6b5a354\nIN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895\nAD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8\nCT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6\nTAG: ee1ec36804e1d5cdbddb52608c711fd8\n\nKEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4\nNONCE: 00000000db37c0a405b4626d\nIN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422\nAD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6\nCT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f\nTAG: 296a397d280d026fc3627f4718971be9\n\n# Tag truncation tests.\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19", "ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c2\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f3\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f37465\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a84\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a8413\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a841386\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a84138648\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a84138648a5\n\nKEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865\nNONCE: 000000005d9856060c54ab06\nIN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e\nAD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51\nCT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36\nTAG: d3f7b9c295f374651a84138648a591\n", }; -static const size_t kLen17 = 17493; +static const size_t kLen18 = 17493; -static const char *kData17[] = { +static const char *kData18[] = { "# Test vectors generated from libsodium with this code:\n#\n# #include \n# #include \n# #include \n#\n# void hexdump(const uint8_t *in, size_t in_len) {\n# for (size_t i = 0; i < in_len; i++) {\n# printf(\"%02x\", in[i]);\n# }\n# printf(\"\\n\");\n# }\n#\n# int main() {\n# uint8_t nonce[24];\n# uint8_t key[32];\n# uint8_t m[64], c[64];\n# uint8_t ad[16], tag[16];\n#\n# for (size_t ad_len = 0; ad_len < sizeof(ad); ad_len += 4) {\n# for (size_t m_len = 0; m_len < sizeof(m); m_len += 5) {\n# randombytes(nonce, sizeof(nonce));\n# randombytes(key, sizeof(key));\n# randombytes(m, m_len);\n# randombytes(ad, ad_len);\n#\n# unsigned long long tag_len = sizeof(tag);\n#\n# if (crypto_aead_xchacha20poly1305_ietf_encrypt_detached(\n# c, tag, &tag_len, m, m_len, ad, ad_len, NULL, nonce, key)) {\n# abort();\n# }\n#\n# printf(\"KEY: \");\n# hexdump(key, sizeof(key));\n# printf(\"NONCE: \");\n# hexdump(nonce, sizeof(nonce));\n# printf(\"IN: \");\n# hexdump(m, m_len);\n# printf(\"AD: \");\n# hexdump(ad, ad_len);\n# printf(\"CT: \");\n# hexdump(c, m_len);\n# printf(\"TAG: \");\n# hexdump(tag, sizeof(tag));\n# printf(\"\\n\");\n# }\n# }\n#\n# return 0;\n# }\n\nKEY: 1f4774fbe6324700d62dd6a104e7b3ca7160cfd958413f2afdb96695475f007e\nNONCE: 029174e5102710975a8a4a936075eb3e0f470d436884d250\nIN:\nAD:\nCT:\nTAG: f55cf0949af356f977479f1f187d7291\n\nKEY: eb27969c7abf9aff79348e1e77f1fcba7508ceb29a7471961b017aef9ceaf1c2\nNONCE: 990009311eab3459c1bee84b5b860bb5bdf93c7bec8767e2\nIN: e7ec3d4b9f\nAD:\nCT: 66bd484861\nTAG: 07e31b4dd0f51f0819a0641c86380f32\n\nKEY: 4b6d89dbd7d019c0e1683d4c2a497305c778e2089ddb0f383f2c7fa2a5a52153\nNONCE: 97525eb02a8d347fcf38c81b1be5c3ba59406241cf251ba6\nIN: 074db54ef9fbc680b41a\nAD:\nCT: 1221898afd6f516f770f\nTAG: 75e7182e7d715f5a32ee6733fd324539\n\nKEY: 766997b1dc6c3c73b1f50e8c28c0fcb90f206258e685aff320f2d4884506c8f4\nNONCE: 30e7a9454892ef304776b6dc3d2c2f767ed97041b331c173\nIN: b8250c93ac6cf28902137b4522cc67\nAD:\nCT: e2a13eeff8831a35d9336cb3b5c5d9\nTAG: 62fdf67735cad0172f9b88603b5f3c13\n\nKEY: 6585031b5649fcabd9d4971d4ac5646fc7dca22f991dfa7dac39647001004e20\nNONCE: 705ee25d03fec430e24c9c6ccaa633f5b86dd43682778278\nIN: 9a4ca0633886a742e0241f132e8f90794c34dfd4\nAD:\nCT: 0a8e6fd4cd1640be77c4c87dde4ae6222c887ed7\nTAG: edc4fbc91dfa07021e74ae0d9d1c98dc\n\nKEY: dfc6f7c86a10a319ebcb6362997e585f55b67f3434f47dc4039c2d67973e3077\nNONCE: 6097f30fd75229d928454c7d59a2d2c58bfddcb14c16438e\nIN: 74c946a7f0733377e852a23087506a28dccef86e101a4359c0\nAD:\nCT: 6e8ea0bb4c2f1323841d8e236816c61c3295866b75cefb5c25\nTAG: f16c0e9487ca7de5e7cb2a1b8bb370fc\n\nKEY: 59b8d488773767c4804d918709cfec6c69a193371145bb94f183899851aaadac\nNONCE: ad5bdf8f190ca2d2cc02a75bb62aa22274cb3c98fe2d25f2\nIN: 066b9ed10f16d3dc132b409aae02d8cac209dd9b4fb789c4d34725ab2a1f\nAD:\nCT: 2bbd4542489006df66ad1462a932524642b139ddcbf86b6b480e9e6d976c\nTAG: ca4835419ba029bc57010a8cc8bca80c\n\nKEY: 8c0cb4633cf8dc6b4b9552d1035f85517cb1ba4c36bcbc43338a8c6c7d15ce20\nNONCE: 8418b9655a0376fadefa3cdf8805815c4f7b56f467a74a95\nIN: 50c205a9c5d4088ba8e59a96fcd837f5170669854547678288199f1078ff2a81f0b19a\nAD:\nCT: 8b55a12df1a85dd3fb19c34ab047a85849d15a30225bb5360bad1f0a8f5f2bd49f5898\nTAG: bce13201df6e4a7e6d896262e45d969d\n\nKEY: b45386a75a5772e34bd193e1946f69ebfb90c37ae4581d39c9669d75e4584f50\nNONCE: 9fb763d0926585b5f726af9b8e3babdb331e9aa97f8d99ed\nIN: 64df0e341145d9e4a0d090153591a74893bc36cb9dae1e9570d8fee62e907cf004f9d8a360343483\nAD:\nCT: 3146d8a5c898edd832ec9d126e93b3a433ec97dc47dce0e1985bda88c88c6aeca46fc7d9a68e30ab\nTAG: 44fdb0d69abd8068442cb2ea6df8b2f2\n\nKEY: f2efbd358dd353639a162be39a957d27c0175d5ab72aeba4a266aeda434e4a58\nNONCE: 65a6f7ebe48de78beb183b518589a0afacf71b40a949fa59\nIN: f7473947996e6682a3b9c720f03cfaf26bbcdaf76c83342d2ad922435e227a5d1eacbd9bd6ea1727ec19fb0e42\nAD:\nCT: 778a0fb701b9d671ccfaf1454e8928158ede9bb4395119356a8133036840c1bcbb8fe5e19922fbbcf8b18596e7\nTAG: 9d195a89fdd29ca271405d3330f996f9\n\nKEY: 9dd674fb4a30a7bb85fc78050479ab0e2c3cc9f9f5b8689a7a67413aca304b21\nNONCE: ad9e8fe15940694725f232e88f79cda7c82fe1b8aae58ba4\nIN: 7272bb6609cbd1399a0b89f6ea255165f99330aeb170ac88fccdd8e226df0952407e35718fb5edc9e987faabb271cc69f7e7\nAD:\nCT: 846901650cb38974463a18c367676e1579ebdaf3e96b57224e842f5d5f678f3270b9a15f01241795662befb3db0768800e25\nTAG: 900004db3613acbeb33d65d74dd437d7\n\nKEY: 280cbe7380a0d8bb4d8dd4476012f2eeb388a37b8b71067969abb99f6a888007\nNONCE: 2e1854617c67002599e6b077a812c326deb22fe29d093cbb\nIN: d0901ec3d31ece2832685ff577f383bdff26c31341ea254acee7c5929a5df74fea2aa964524dc680b2f55fbd4fea900e956c304cc4ac3c\nAD:\nCT: 546370726cc63068d3520d67f4f57f65d03b9ecec21c2a8c7b1133089ad28b07025a7181bddeb4a49f514fac1a44f64ee3af33d778fb98\nTAG: 39084e33e42a1b05f58da65ba487d138\n\nKEY: 887564f75afa78f595cdadcea7340d20f5c5a2df169d0ad14b15fe32ce337004\nNONCE: 54c11df13d1f444da80b0964caeb59474b17b23a650a33f5\nIN: f0f008eece79ecb24b715dff8a3456dfe253924b99f98f2f1b18564cced50925fca860d1c2d4785bdf4a964c76c3079efa6b37c4ba2cacc534fb590c\nAD:\nCT: 32bb077268568d569b39e8ccdeeeb447ef424eaa2ffab565209a19b16a25952f897e5405bb0d67d8c9005d1c0b32687164d17fa4d0f412b80414c025\nTAG: 0bac7c0f8dce12917fbd4ed1738ac0cc\n\nKEY: 21c6aa88eb1a320d251f71a4b312ca75347040990d869a1dd2a1982c30fda2c7\nNONCE: 7dead2f1a3d9d45a9124a40efe8994300976991a4417ef4d\nIN:\nAD: e1bf7de4\nCT:\nTAG: 341e9d0687006f981bced2f985f953e6\n\nKEY: 0c97b9a65ffcd80b8f7c20c3904d0d6dd8809a7f97d7f46d39a12c198a85da5d\nNONCE: 1f2c1dbc5f52fc9c8f9ca7695515d01d15904b86f703fba3\nIN: ecaf65b66d\nAD: bd8a6f18\nCT: 8d1b2b0e38\nTAG: 27a7c7ac8bda627085414f0f31206a07\n\nKEY: 4ab5e3595f39c4379a924e5f8ebcf3279075c08d18daff01d9ddfa40e03faf12\nNONCE: 94e6ddc294f5f1531924ec018823343ebcc220a88ea5ee33\nIN: c91b73abe5316c3effc6\nAD: c576f6ea\nCT: abe960fbc64b339c53b1\nTAG: 7ebae48a2ff10117069324f04619ad6f\n\nKEY: a1e6146c71c2ea22300e9063455f621e15bd5bf1a3762e17f845e1aba5dd5a9c\nNONCE: 82ddb6929abff8a9ad03dfb86c0bb3e7c092d45ebfa60a1b\nIN: f011f32ccc2955158c117f53cf7b12\nAD: 5d14bc05\nCT: 44592321c665f51e9ffea052df1fea\nTAG: d556798b97f9b647729801419424affc\n\nKEY: 7a1af30362c27fd55b8c24b7fca324d350decee1d1f8fae56b66253a9dd127dd\nNONCE: 61201d6247992002e24e1a893180d4f0c19a3ae4cc74bf0c\nIN: 5c7150b6a4daa362e62f82f676fdc4c4b558df64\nAD: 00c49210\nCT: 27d9e2730b6809c08efbd4b0d24639c7b67486f3\nTAG: 5889fdee25379960038778e36b2cedb2\n\nKEY: 0b3fd9073e545ac44a7967263ead139c9547f7a54f06228fd3c8609fa2620784\nNONCE: 6450e1097d6f9ea76eb42e8e65972d501041c3a58baf8770\nIN: d679ae442b0351e5bff9906b099d45aab4f6aea5306a7a794f\nAD: 318d292b\nCT: a3f9ee45316d7b0f948a26145ee4fd0552bc6dc25e577e777a\nTAG: 0068a401a194b8417ec0e198baa81830\n\nKEY: 047c7d378fe80c02ee48df6f679a859253aed534fdcdd87023eb3d2f93fcafe3\nNONCE: ed240b0ff6f8ac585b3ea1ab2dab8080fc2f6401b010c5d0\nIN: 7288afb4e0fa5c58602090a75c10d84b5f5f1c0e03498519afe457251aa7\nAD: e4310302\nCT: 87906b14ca3e32ab01523b31ae0bb74590ce9e1df0811e743a2c7a93415a\nTAG: 3a0abeab93792b1ffe768d316da74741\n\nKEY: 1ad4e42acc5dfd07eb0a2456e9103cd0e150a36c667eb2f2b73c0d1ac1089ce3\nNONCE: 48efb52387284c5d38b4940c75f0c39a3f81f60bfebb48cb\nIN: da7edb5b3193b4484f09efa85fcf85600968ecdc537d3829a469c866ee67b0df677866\nAD: 446be8e3\nCT: b76457ca99e95b6539b12f1d6bdac55a6d5c6469b1ff274459363ec05241f7e6e5d3ce\nTAG: 06880ee508ce929da5a81f8b9de0031c\n\nKEY: 702a554c1b703d4dd69ad51234293ab787a01e15bdb3ce88bf89e18c01a67164\nNONCE: ea535d9c371241b9850b8b4a596b63db79eea60bd2cd9fbb\nIN: a97156e9b39d05c00b811552d22088d7ee090a117a7f08adac574820d592021f16207720d49fb5fd\nAD: ba5790e3\nCT: 8d0b2b04479c33287096f0c6276a73f6c037edc1a2b28f8d3b2b8e6d4c5f9dc5113309dd3ecb15e6\nTAG: 3cf303305e12924d29c223976699fb73\n\nKEY: 1bb7303fefa4d8d344bb9a215901b2314324bf1f3aeb9df5d1c1532c3a55ebf1\nNONCE: a304551e5f0dc98995ddfee6215a9995023a3696debfd302\nIN: 6cf6819ce3e7ed9d4f85f4a5699701dbcaf3161adc210c0b7825ddfd83d6d7c685db62f68b3801ccc8a786066d\nAD: 901c5feb\nCT: bc5ef09c111f76e54f897e6fce4aee1d25b6ed934f641ed5262d0c5eed45f610a6aea3b58b7771e34256d43a16\nTAG: b83f73f7995ba1b243dbf48ddfeb8e3a\n\nKEY: 24b294f6cbac10d87158d1c6aca83b337d596132afac7633f69a3b3e58823f11\nNONCE: 805772ff619cc6fcc5ec0e9965435d6f74a2290c055ec754\nIN: 65e8581286868caabcec1a9814db00b805edc660b94ee3babc6ce19a3ca868bd322105484d59b4ce02ced4071bc16642a1f2\nAD: 7ae1", "c561\nCT: fe1d463b1466e8e411f0b0700f90760472ee5141f3e5afef43fd729f1623dca75cd4d00576765b335f8b2b77b00527599cb3\nTAG: 111d8540fd5ec04b9ba16ed810133026\n\nKEY: 38e63e8b6402ac3f6d1641a1e3b74d2074be0fe41129975a3ff62b74ca52af05\nNONCE: 228d671b036710cbdaa72e9bf1d9ed6982b0bb3428a69fd6\nIN: 20a8d18878924d09aac32853c10e73dbd741134b7050ae6999839f2dbc727cb0052b5497c4bbd2a89e716278f15c81b871953614a49693\nAD: e9e6ac73\nCT: 80e0fe8eb26e5df229c6d939c944d440a37aa3cabf76eab5b9a420095513021ea4241ab367f6f44a20817b14631549ae6c96aa963970e1\nTAG: 1e80fbafcc7168e0494fce4cd76d692c\n\nKEY: 4325dd8406fdb8431a81f1b5db3603995256de36121019724cca2190c87a6e83\nNONCE: dcbf3077b36d5d678d668fd2d0c99284c780b55c4658ea75\nIN: 4f599ad04f79be9add10fdc649b8be53e1062ea5e9c2bed22265dc6fb30d5ab4fd4425b38ff14d8e68013405bec1eff8c9ef3069902e492aac73dcd9\nAD: 6fa0d757\nCT: 7decbdc7043495c59ecc64e720436bb0708b586a46f8745f74391477f5a2520905dfcebc3765a330999013d309dfaa997bf70bab6a0b8f4f2a2a3cdf\nTAG: 051ec4ecce208d9be0cd17f434e13be3\n\nKEY: 2d3d9ed4bc9eb9668733bafbb73e88be2cd17021c3a23be69b981d9f0df71df1\nNONCE: 84cae69639240c82b58895997511f145e474ebe1b008f391\nIN:\nAD: 64db597c26a4c3da\nCT:\nTAG: 2a22c4a962d46a719014ab7b0ffaf6d3\n\nKEY: 09ec4e79a02db53b19b54dd2d3592afc92c74ef57d1e0f51f3726a6631b1b73f\nNONCE: 2907ced16e0777fedb1e2de30df11b3fd712af41dd714a4b\nIN: b6e50cd4ea\nAD: b5488e9b7f339b7b\nCT: 0163e75330\nTAG: e29401c6d756adcc516580ae656852aa\n\nKEY: 9d5ac25a417b8a57b85332979e8a7cbad23617bb27772bbccc2acb0acae7b755\nNONCE: ff152421688dd6af7fef87817b508493a32d97a06fbda4f3\nIN: 92f4b9bc809be77e6a0d\nAD: 892b793f7a6e0727\nCT: bcc594f59de8ee8c22c6\nTAG: 1a8275816c0d32a1b6cfd41fa3889558\n\nKEY: eccf80c5f744d2ecc932f95ade0d9fe9327e19795023db1846d68d04720a2401\nNONCE: abc050fad8876589633b222d6a0f2e0bf709f73610aa23ee\nIN: 45a380e438405314510c166bac6840\nAD: c32c9a1ce6852046\nCT: 9fa452dc9ca04c16ff7bde9925e246\nTAG: 3d5e826162fa78de3fc043af26044a08\n\nKEY: b1912d6bc3cff47f0c3beccff85d7cd915b70ab88d0d3a8a59e994e1b0da8ac8\nNONCE: d8756090a42eea14ff25be890e66bfe4949fad498776ea20\nIN: e2f85df2ebcfa6045bd521abfe8af37fc88a0be1\nAD: 4576bb59b78032c8\nCT: 5eb6324aa48e0a4f72f5cb0a4917faf93af4209c\nTAG: 774f8077f039588495045fee07950e14\n\nKEY: 85162b111c9f3163f57c2cbc311a1e9aeed9dd6136b5784bc9c0b5052f8bffbd\nNONCE: 23cdb8b546bb8a5a746b24446f0ab4199f0543d915ff51f1\nIN: dc81000077d5743beef09ac91663885d984212bbccf3dbe6f3\nAD: 3084f3e9c4d0a15f\nCT: 692d17ae0b524ec6edc0cf49b69ac90c99bed44691f7ae63b7\nTAG: efe72ff84b3bccb4d83a27ddc574bc21\n\nKEY: b05ca358d8ca79f51283d83e2673bfb741c379ba271a773b8dd9c6a108e758d3\nNONCE: 9a53ad79f535c6e9da011463063c896f2ec7645e6e3548fc\nIN: 44e793742c774020e7349c996418042dc0dc30ee2bfd2654008c8929a436\nAD: 71ab5948c5e0f4c6\nCT: c5eddb7aeaa175b5f3dab68cf746f2acaf56fc62b29804629e25e2d63879\nTAG: bec3b7a8b8dad22ff3d14d26273294d2\n\nKEY: abb5136a01354c765a96e832df58bec3b088bd19dc4d6bd6674f2f02007ebdaa\nNONCE: 71267ac9f4fe5caa1d52cd85948a170a778f0141d54dbffe\nIN: afb526fe41c4e2a767ce77c4145b9d054268f5f3b279237dec97f8bc46f9d158868b86\nAD: 047baa2b04748b62\nCT: 0032d4c1e65da2266539464c5d3c2b1618454a6af0e7f1e3cfc87845c75f2f4ae8b03f\nTAG: b526a95a33f17ab61f2cdfc1e2dd486a\n\nKEY: bb826ed38008a0d7fb34c0c1a1a1149d2cad16b691d5129cc83f5eff2b3e5748\nNONCE: 4e02fe0915d81e9d5a62e5b3551b9db882e3873c0aaa230d\nIN: 20270d291a8d9791b0f5e35a64387bb4237bad61169841d7e1667c994ad49869c7d5580ffa752a2d\nAD: db852a275081e29b\nCT: d740012efb7e1bb986ce2c535134a45f658b92163c109bdecf1ce5b836879fe9e006a56be1fac8d7\nTAG: 21e931042e7df80695262198a06286c9\n\nKEY: 938d2c59f6f3e2e7316726537932372e05e8c1b5577aae0ee870bf712ff001ab\nNONCE: fb4d71cf7eb2f70df9759a64c76a36b75203f88bf64f4edb\nIN: 8910415d674a93c54c8f5e4aa88e59648d9a0a5039a66837d58ab14f0665a5f6d9af9b839f9033d0fe8bc58f19\nAD: a3fca278a63bf944\nCT: 1905c6987a702980b7f87f1ed2d3ae073abe1401b23434f3db43b5c37c979c2068ce9a92afedcdc218003848ea\nTAG: 1bd712f64777381f68be5ccc73f364a3\n\nKEY: dd0521842f498d23236692a22db0eb2f0f14fef57577e5fb194503e206b0973d\nNONCE: 519e0eee8f86c75c7a364e0905a5d10d82073e11b91083a5\nIN: 61ff13acb99c5a7fd1921ec787c8de23c1a712ff002b08cecc644a78c47341eab78e7680380c93c7d53d5e56ef050d6ff192\nAD: bb5c4e5ae8f7e461\nCT: 9bfdb0fd195fa5d37da3416b3b1e8f67bd2a456eb0317c02aabf9aac9d833a19bda299e6388e7b7119be235761477a34d49e\nTAG: 0f0c03b8423583cb8305a74f622fa1f9\n\nKEY: 189bd84be3fb02723539b29cf76d41507c8b85b7217777ee1fb8f84a24aa7fee\nNONCE: ef1bf39f22ba2edf86853505c24fafdf62c1a067963c63ba\nIN: d5f96e240b5dd77b9fb2bf11c154fcbff312a791c3eb0717684e4fd84bf943e788050b47e76c427f42f3e5344b2636091603ba3b1d7a91\nAD: 93368a8e0900c7b6\nCT: c55a8b7f587bee4f97514582c5115582abffd6312914d76c2568be6836f62ba098789ed897c9a7508a5dc214bf8c218664f29941ccdfd6\nTAG: 78f87352dcb1143038c95dc6e7352cfd\n\nKEY: 23a2dbfcd02d265805169fa86e6927c7d49c9a24d2707884e18955e32dafc542\nNONCE: 305c7851f46f23ea8d832d5ed09d266714fd14f82ba0f69c\nIN: 224de94a938d49cad46144e657e548bd86690a1b57b81558095eace59df1c552600dea389aaa609304fbc1eadf2241f2118c8bdf04522e1898efe1d4\nAD: 0075b20502bd29b2\nCT: 8e10c59369bbb0d72958100b05788498f59588795e075b8bce21d92d320206348b04010ced9b8cd3d651e825488915ce4a6e4f1af2f4d2f77b955376\nTAG: c39f0595ae8112dea6ef96df1c12458b\n\nKEY: 264e3c3f47bdf795cdde57d9a30be5a4da8b18463c0e3e05df28b7bf4e56410b\nNONCE: 3ee09b6e205c261bf48ac53a9ba0afa460a5d5c0f2d80be8\nIN:\nAD: 8eeec09d8972cb8ab0069554\nCT:\nTAG: 245a034d84edab9fa6f0decb6b984766\n\nKEY: d8ba98a272b5f91797b04b114311c3b92b7f2e3bb72edb7f78ed311b9f8ea2ad\nNONCE: 481de9a06eee76a501e3c2b9d7423d90596193ad9d8a6564\nIN: 9ee1a3134d\nAD: 928653701f6d6c8429b08c0d\nCT: 459a07898f\nTAG: 9188ec8d8e3bd91dcfda48fcc76773f7\n\nKEY: ac9afd627a745df682bb003517056f07876eb94d2f8c610c61b6ac0d34ec4ec0\nNONCE: eaae7b8704530db1e8c3dcc968a00604a333c7c27ba51b16\nIN: f7c3f6ee2e9c03394dc8\nAD: 796620b367d5f041821baf69\nCT: d4a69005790cc91d8d34\nTAG: e4c83def113afcf83a1ea8cb204a0eae\n\nKEY: ea1a07c1fd60a5421f1fb6c43b4318090e290c97aa3bfa037e6fc5ee00fd47d4\nNONCE: 37327805cce92b38a669affbca1de92e068727fcf6fbb09a\nIN: 7002ca765b91913ee719e7521ef5ac\nAD: 64e7c48fc3041eac0734737f\nCT: 9d8857a8c52a9ab3bf44b024b191b6\nTAG: d072c31714a7d0fe1596fd443a96e715\n\nKEY: b3beb34fe0229fc8f49b354e941025bde6a788f25017a60e8a49591ed5d7e7da\nNONCE: dd0e9fec76de1f6efb022b12164f7e9248b8e8c01d14ac02\nIN: acf360d7529a42be1f132f74745a940da9e823f2\nAD: 1489ca8d852f0a8547dbe8bc\nCT: 2e8718372d6e8167213cf112dc41c80377244f5a\nTAG: e4f31e8f84b9356999dc60989009e698\n\nKEY: 9357cecd10bab8d2e42ed88c0386204827c3b76e9e51150d09fd4e3b4e0e1e6f\nNONCE: 81f2106a5379e0ed861cf76b3cf95afb17515478b5cbcae9\nIN: ee51a0f25d091288b5e2b91ad11d491329e48b35a18a3a8685\nAD: b80cb677f4b409cd1537363b\nCT: f681f19fa8de1fdea3538001a46f30fa6333b76d6439337e68\nTAG: afad5e6d282d9df6d8119c32237b3e60\n\nKEY: 9f868600fbf81e40398b7dfb201fcae35d34bba10908860b0b2bf8b942b4e8fa\nNONCE: 2ddcc13c97185614095d437900b8c0a9170e0a4a50e46ba5\nIN: 133fa3ac176fee6df67472752e41c6834f13300c0064ff5b190f903b7ac7\nAD: 0d61321fbee8bb1f3f5cb454\nCT: b93abb311ec0bf018dc300c7d511b42ade72780373186e231820b44f22f0\nTAG: f8bd2f649a337783ff911e37966037bd\n\nKEY: 05affcdfce0a28539924370db8d80a78b835254778ec41acbff52bfab092fa33\nNONCE: 3edaeb185f7273b1a7cccba54f84c5f7d6583433b49d3694\nIN: 7657581faad266cc1037962a380c8aa5306f88000427d0a05397696b503790ad2643c6\nAD: d7c213e9e6f4a40f3e5b662c\nCT: 5eb19080aadc89f2329da4f5c41dc60568651c424c1b05d827f2bfb8dbff42c5a08224\nTAG: 2da20087b5674f0b967d1baa664bbd82\n\nKEY: 645ed60ec74ddfe1f02694792db4436c262d20405d8645cd9755d64876219799\nNONCE: d83665b44c1fdf567299f2b8501e9c0e7ae2dda0bb8f2c82\nIN: ceee69d32ad4667a00909964d9611bf34fd98be41ad7f0feaaaff8169060d64cf310c13bcb9394cf\nAD: 57379f8f44191ec9cf3b1a07\nCT: 4496a0666f0f895ebce224b448a04502f2ae7b354d868b7c54295bf051162e82c530c767d1ffd2cc\nTAG: 1ffc56da4fb961ffdfabe66d82ec8f29\n\nKEY: 06624c9a75bb7dbe224a3f23791281f53c40b407a14161a3f82f34924623dc02\nNONCE: e647b8b4739bf542a81d72d695e1cd6ba348fa593987ac47\nIN: 2658763f8d70e8c3303582d66ba3d736ce9d407e9507f6c6627e382d0144da157d73d0aee10ef034083cdd9013\nAD: 75536443a6c2189a57d553bb\nCT: 305cab5c2f9a6edccac307d6965febe3c86f2a1e31ac8c74e88924a10c2a29106bce980c803b7886985bba8ec5\nTAG: 8c12bb58c84175b9f601b704d0f8a25c\n\nKEY: 63aeb46083100bbcc430f4f09bcc34410df9cfd5883d629e4af8645ffabb89c2\nNONCE: b09830874dc549195a5d6da93b9dcc12aa1ec8af201c96bd\nIN: 1b3c9050e0a062f5a5cff7bec8706864c", "f8648142ec5cb1f9867ace384e9b2bba33aab8dc83e83b2d2fac70cd5189f2b5ab5\nAD: 7dcc05b0940198bd5c68cdf1\nCT: d8b22e5d381de08a50b163c00dbbca6c07d61c80199cebd52234c7bd4f7ed0a90d47ef05617cdb8e3f782875ae629c0f0ad6\nTAG: 194077f0e6d415bf7307d171e8484a9c\n\nKEY: 4826c1bf8b48088fece4008922173c500ff45790f945b1027f36110da4fecc92\nNONCE: 3a78fc7397944d762303b0a75974ac92a60e250bf112600a\nIN: d26e3a2b92120ff8056bb992660cc8a2364792589c16a518b8d232b8184aed05ba8d4fd0b2ad2b928cd873e11905a21ffece5f1e63c974\nAD: 904d2cd3e50f7bfb9352f142\nCT: 21f4cf679662fad36f57945fc0c0753c3791261eb58d643278dfe1f14bfb585c5a01370ba96f18dc3f6b6945a2c6997330b24f12f5219a\nTAG: 95397c54428f9d069c511b5c82e0151c\n\nKEY: ec526c03d8a08e8a63751112428a76399c399e8b83d98c9247c73164805ac8fe\nNONCE: 2cc1a6ae89c2a091415fa2964b44a0e5da629d40d77b77f1\nIN: 567377f5b6df5442e70bc9a31bc450bd4febfcf89d7ca611353c7e612d8b7e36e859f6365ec7e5e99e9e0e882532666dd7203d06f6e25439ed871237\nAD: 35575b56716868b66cd21e24\nCT: 6b738274fe974438f1f5fca8ef1ee7df664f1e72bc54ccd3fb58c4a3df67ef9a73261df41ffe9c52aeafc8be4f6524baf9efb1558d4a57defec7bee3\nTAG: 92599d4b14a795e8c375ec2a8960b4dc\n\n", }; -static const size_t kLen18 = 96825; - -static const char *kData18[] = { - "# RC4 tests (from rc4test)\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 0123456789abcdef\nCiphertext = 75b7878099e0c596\n\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 0000000000000000\nCiphertext = 7494c2e7104b0879\n\nCipher = RC4\nKey = 00000000000000000000000000000000\nPlaintext = 0000000000000000\nCiphertext = de188941a3375d3a\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext = 0000000000000000000000000000000000000000\nCiphertext = d6a141a7ec3c38dfbd615a1162e1c7ba36b67858\n\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678\nCiphertext = 66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext = 00000000000000000000\nCiphertext = d6a141a7ec3c38dfbd61\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext =\nCiphertext =\n\n\n# DES EDE3 ECB tests\nCipher = DES-EDE3\nKey = 2eaf97304cfaeb822c04a7b7bef328c7b82fef2ae81b06b5\nPlaintext = b3ed255d4f5e2d6d9a1aa2bc03489064d28fe1431eceee183b7231fad3273140\nCiphertext = 629d608789e51dff699343d061ec01d94c0681c7698ab617ea0145f37304c8e2\n\nCipher = DES-EDE3\nKey = 72f52e1ded0a88eac6c88d2901b27c2fd6e9f3f3387432ee\nPlaintext = 60de7b5667a1ad5995f178553d695d9b0fb537562876faa9b6cc50d05a1271ac\nCiphertext = 09875b215ed2499318c2d99c48209ca5f288830cc6edb9538190fa3ca31fa175\n\nCipher = DES-EDE3\nKey = 4cd30f1e14d485dbc05c69b65ebf44e556056a2261c9e714\nPlaintext = 7ae59441bbd665d8867273386fc72a8cd62cc5bc6bb7cbd57fc1f5dcdc73adfd\nCiphertext = 004d0daad970bfee944c8779927867b964dd0afaae7a830c2b8e7fdcaeac2158\n\nCipher = DES-EDE3\nKey = 7a07ac63adfaf1b26860ce39edfc402758bc4d1edda156ab\nPlaintext = ed4f18cf10bfcbd4354710df053d3e2b776860137349471b8dcf526b8eea8b22\nCiphertext = a1fc1014abda7e198ac8e096a368f65d9b59e1eddf5d97715015a2408dd8e799\n\nCipher = DES-EDE3\nKey = 37c443ab336fed59b0efae51ea7f5d07b7040868beefcd99\nPlaintext = a10a180cc94b75fc9d6556dfc0a816b71020dc3906f9d59d9dd4c839dfc1c1d3\nCiphertext = 0a874652b621618635138a7d4b33bb624f91a39ef1422b3e0490311ac6df3602\n\nCipher = DES-EDE3\nKey = 1ff1a7f4839d484e308d9b8c2c052b126def413d5fb8e0c5\nPlaintext = 4f28ef6683d36c80556ff240b247a3967aec23f859e3afb93aefad93b1e9964b\nCiphertext = 87a8f3fb4c51b3caf19c4ac51363d92025acc053e538c1502d347a618314a4bd\n\nCipher = DES-EDE3\nKey = 5642c4d1859a85b342e3f253fd8bd835e856c451e63673e5\nPlaintext = 687af9b298db752b47982f64ad9bff52a9ae487aa5e5c08f902035b0633225bf\nCiphertext = ca2ed48392ba5d70879ac8772180c3028ef946b6ac1df0348f206ce16bc449bd\n\nCipher = DES-EDE3\nKey = 30f9d27472f9deee309dbca76ba29ca174c39d0631084735\nPlaintext = 85db2c266902932c8e46d0207459b203f90955adcd7506b49bc82e2796de764f\nCiphertext = bbb5940b45add7c587cc9fcfc40674bac7e081baf71285891c65ed9573947a07\n\nCipher = DES-EDE3\nKey = ebc5a73005b77a812c3f4f61669ba859939852580fa61cbc\nPlaintext = 808d22c60b883a986dcb0860e8d92a75441cca0a2a4b06dd78dbcbec198b38d9\nCiphertext = 75d39d30862431ab07227e22b4c8218f1fbc2a3816daebc555c1b999c86d15c9\n\nCipher = DES-EDE3\nKey = 2e8eb05dd8a2b7a5a61a6b8a3830b12da2c4b1bea1e884d5\nPlaintext = cc7569d005afd1a365f5c5836c14475fc15091199902af4a78460d56c16f91ca\nCiphertext = 64db8af7a30363051a017cc92ed67ac6c0e2e1ffda0c94bbf0eeb803ba6b3d22\n\nCipher = DES-EDE3\nKey = 2e8eb05dd8a2b7a5a61a6b8a3830b12da2c4b1bea1e884d5\nPlaintext =\nCiphertext =\n\n\n# DES EDE3 CBC tests (from destest)\nCipher = DES-EDE3-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210\nIV = fedcba9876543210\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675\n\nCipher = DES-EDE3-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210\nIV = fedcba9876543210\nPlaintext =\nCiphertext =\n\n\n# DES EDE CBC tests\nCipher = DES-EDE-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 7948C0DA4FE91CD815DCA96DBC9B60A857EB954F4DEB08EB98722642AE69257B\n\nCipher = DES-EDE-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext =\nCiphertext =\n\n\n# DES EDE tests\nCipher = DES-EDE\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F\n\nCipher = DES-EDE\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext =\nCiphertext =\n\n\n# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)\nCipher = AES-128-ECB\nKey = 000102030405060708090A0B0C0D0E0F\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = 69C4E0D86A7B0430D8CDB78070B4C55A\n\nCipher = AES-128-ECB\nKey = 000102030405060708090A0B0C0D0E0F\nPlaintext =\nCiphertext =\n\n\n# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)\nCipher = AES-256-ECB\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = 8EA2B7CA516745BFEAFC49904B496089\n\nCipher = AES-256-ECB\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nPlaintext =\nCiphertext =\n\n\n# AES tests from NIST document SP800-38A\n# For all ECB encrypts and decrypts, the transformed sequence is\n# AES-bits-ECB:key::plaintext:ciphertext:encdec\n# ECB-AES128.Encrypt and ECB-AES128.Decrypt\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 3AD77BB40D7A3660A89ECAF32466EF97\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = F5D3D58503B9699DE785895A96FDBAAF\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 43B1CD7F598ECE23881B00E3ED030688\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 7B0C785E27E8AD3F8223207104725DD4\n\n\n# ECB-AES256.Encrypt and ECB-AES256.Decrypt\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = F3EED1BDB5D2A03C064B5A7E3DB181F8\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 591CCB10D410ED26DC5BA74A31362870\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = B6ED21B99CA6F4F9F153E7B1BEAFED1D\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 23304B7A39F9F3FF067D8D8F9E24ECC7\n\n\n# For all CBC encrypts and decrypts, the transformed sequence is\n# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec\n# CBC-AES128.Encrypt and CBC-AES128.Decrypt\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 7649ABAC8119B246CEE98E9B12E9197D\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 7649ABAC8119B246CEE98E9B12E9197D\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 5086CB9B507219EE95DB113A917678B2\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 5086CB9B507219EE95DB113A917678B2\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 73BED6B8E3C1743B7116E69E22229516\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 73BED6B8E3C1743B7116E69E22229516\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 3FF1CAA1681FAC09120ECA307586E1A7\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 73BED6B8E3C1743B7116E69E22229516\nPlaintext =\nCiphertext =\n\n\n# CBC-AES256.Encrypt and CBC-AES256.Decrypt\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = F58C4C04D6E5F1BA779EABFB5F7BFBD6\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = F58C4C04D6E5F1BA779EABFB5F7BFBD6\nPlaintext = AE2D8A571E03AC", - "9C9EB76FAC45AF8E51\nCiphertext = 9CFC4E967EDB808D679F777BC6702C7D\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 9CFC4E967EDB808D679F777BC6702C7D\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 39F23369A9D9BACFA530E26304231461\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 39F23369A9D9BACFA530E26304231461\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = B2EB05E2C39BE9FCDA6C19078C6A9D1B\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 39F23369A9D9BACFA530E26304231461\nPlaintext =\nCiphertext =\n\n\n# AES Counter test vectors from RFC 3686\nCipher = AES-128-CTR\nKey = AE6852F8121067CC4BF7A5765577F39E\nIV = 00000030000000000000000000000001\nPlaintext = 53696E676C6520626C6F636B206D7367\nCiphertext = E4095D4FB7A7B3792D6175A3261311B8\n\nCipher = AES-128-CTR\nKey = 7E24067817FAE0D743D6CE1F32539163\nIV = 006CB6DBC0543B59DA48D90B00000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = 5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28\n\nCipher = AES-128-CTR\nKey = 7691BE035E5020A8AC6E618529F9A0DC\nIV = 00E0017B27777F3F4A1786F000000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223\nCiphertext = C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F\n\nCipher = AES-256-CTR\nKey = 776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104\nIV = 00000060DB5672C97AA8F0B200000001\nPlaintext = 53696E676C6520626C6F636B206D7367\nCiphertext = 145AD01DBF824EC7560863DC71E3E0C0\n\nCipher = AES-256-CTR\nKey = 776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104\nIV = 00000060DB5672C97AA8F0B200000001\nPlaintext =\nCiphertext =\n\nCipher = AES-256-CTR\nKey = F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884\nIV = 00FAAC24C1585EF15A43D87500000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C\n\nCipher = AES-256-CTR\nKey = FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D\nIV = 001CC5B751A51D70A1C1114800000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223\nCiphertext = EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8\n\nCipher = AES-256-CTR\nKey = FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D\nIV = 001CC5B751A51D70A1C1114800000001\nPlaintext =\nCiphertext =\n\n# Regression test for https://github.com/openssl/openssl/issues/1916.\nCipher = AES-128-CTR\nKey = 7E24067817FAE0D743D6CE1F32539163\nIV = 00000000000000007FFFFFFFFFFFFFFF\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = A2D459477E6432BD74184B1B5370D2243CDC202BC43583B2A55D288CDBBD1E03\n\n\n# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD =\nTag = 58e2fccefa7e3061367f1d57a4e7455a\n\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78\nAAD =\nTag = ab6e47d42cec13bdf53a67b21257bddf\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985\nAAD =\nTag = 4d5c2af327cd64a62cf35abd2ba6fab4\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 5bc94fbc3221a5db94fae95ae7121a47\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbad\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 3612d2e79e3b0785561be14aaca2fccb\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 619cc5aefffe0bfa462af43c1699d050\n\nCipher = AES-128-GCM\nKey = 3de7b368783bd7287f2b9b731814c876\nIV = 90dedcfff100eb1f1db9d935\nPlaintext = 8d766795cadc0961c0f448c62df3827eef3a8664599b3adbaab0cfd63875bceb8f992b4f7447dca10ddd716aa0bc4fe925e1aa3e3fd1d5c430c650fe3546d6b9a24d576a857c5f04e8c0a3b149df277aa19cfa64ee235891d3b8ec0e840d268b1e70dd8a4bf97628a0c7aea38aa21eeb8fb1a8437f2abfee05e0d2c30659e312ec03d30da51b7c19073a2341c17df806e27e796d581143d39e4de8d3f8d46aa6d6fc1a98d94fa69b92dab751d930cc12de21fb1a7468af09e3c12ff6c3db3967d10cf140bc46f17a16e24b010b6cba5ebf777341c52042596ee53008389c48d9690ab9f5625795c3e588f72f7a1670b2b25a9f4eee1c8845ac90f1bf47ae4ea4b607a50aca88ed304cbb700d02d5486139b0bc81ec042e574abf986972fa008b83ef22dbfe720c2f2f6355c87c975932cec545ebed657e5e7570c503e9aa7f0b87d0b2648e421ed1d34749637c95d1e931af8925236387e50454f0ba2e22ed05f90450fad46f4eb7ddb08656511dd065c0f852a7e42f618a961a6c6bec42226c6b6043580b009ec9837cf99844cb74794a82c269ff648e0bae9ae50256a0ad98ad9f5a35057b3004ac96f469f9ee966dadc16dc47616586cf242706df96bb2f7ee43d3bd1c65d2eac7b82ef242e77ab509afb9639e5f3995380e926305729ca762c487f4411ec2a9c688b8347e5287216dbb38c3fe2281a89fcb47ee2ee7ddf79bfa3ab61cd56a00981019bbcea8aa0444eb75958e5fa56ea0036d2de4950a7db886f4a318b433bd41e00905ab158171e0ef13172293bdf70064b9dc7b243bf9dc927589bf9e99468d1cb330639dbff1850cc51929b8971b0b2ede9d06bc5f6ba39d4551b587f09bf6f8206e8f1524f55714612581d6aa45d8fb83425f84a736576deeecafdcbfbb8670d14cd2ab2a7f8b7f374c07881b7bac2605fd5ff7ff7cf43e30cf49910961a9079c0343b8601be8c3e9fe38f49fdab0b7e1a8c1536cf84e4d80d26ae5ec37570839b5cda02929221898d611525c3a88fc444167ffc532b256cdd0a8f31ff08097d75b629fab99c9e1062d1d9962b211e15ec8709934029c4934e64db8d7a2f32e23dc541be306e9a57a3419115994cbc3a8f8d5ea2a6f45b9ea9ac0e51ed0c6680fa029f4552a6c8665aab00ab77928342e7284c321e9500ad4774ef1fed0f596d5aea371fe1793271aef38cde55547f34701a525526e83a72673385a85f44db511bc87ce1f831fc6ccf8204ca4f4a20eac09897aae93684f14ede21bcaf40a09c08012b92600d6a839ebdf8bdca7b34192c6c50bad8796b3be3c375dbae6217815d2c75cc878d39b4e842d4eaa5f5df2242cf230e44a240e18e47827f089b18bf880fd41a2516eac8e6ba3fc2db64a4bc28789860d7b18d9edeae8b3059f4d945b15d0ee27b1f74842dd1df117fe83a8fdade23a47c93902eedc4d33f2dbfcd1996e6dc1458409fde2302830e8d44c58c5ae67486b9950dd938f14c38bc4c9484fdc4ded93a0f90875773453fc14d428cd6e7beb0c705d61229d2b3df09632ebb30b325fefe2aebbf2a7aa8e4ad46277ca4b8b078818b63d04e7652057f6cbbab7c43ac355537e0d3918b4a73c00dbe6b30a27ee7a6fa213d3347ae478e8edc323404b8322b9c7b0173ed61c38ed25f3576a675d527d22edd51d6dfa5767560d3a50a91226338e8c4e6436eedbcd3d2efe9dc1e686b15d2f57d553abcfda57dc316ca453a690f20148f0dfa20c1c4a58240aaf7195095fedfa56d839d0230d55ce9a8ca1b9d1acd6fe98d583148ba0f4a4e3413c76e6ec57ddb79428d3a90079f64d3321c791f60d501c3fd02c8403f0f5e6c6836bbc96430c1b48e83350c3a3cfd017f15bee3e4bb1295d821dc98b85ab3145555cce2c34a8142fe50f8db19918b514a165d12ff6301fb2296788760ac0b6d9e3a57770ad5111cde5d24b6321918cb0b0887a282b827a8749733171914b000e7d3c0edad1d42ca60da37f0698554bb2a1749f73b3120dbeaa32951f8217a781a200467d", - "5b569d16f56fc9b7dff0ac524f03fee0617f4c692d94613b1e13b18075dc9f0d32811d4a8949a95f6b5fa46aeb83597adb409e68b2a0177c36dcc95dcb2e7dd4fb7337ff97c013364fe139e185014948fa698741d822044fa3f6978b16afd18138c845587c405ebf7a6cd1c28610ce67e992ed49e406658a0a202feed9709500d064b6f53eecfca57dd4b38363ce3aae9d59126d8ae7e140a373851188ae28c909181d0ac64770df70dd2475809350cb367825b59d521d5e457b4e36aea6dedd90a2266898b753b57fa359d43cd388e7d6c7ed90bc4c2af34ceafe88a3af6ac376fec35f1240f08af4f3eb30bc53dd68e5762e6d39e6b16f63003fbe0bee828d0d7adc58c41e857c2c44702215b202701fc696eae021af19c79e59c3e32627cd571f5db99b17f1772b5d746196befabb0b7446687827f3315b391d5dff069b1c39c00bb143218ef458e3b397e1c99640d57fc8db2e0083d3d22ed4111a8fc9e0e6f55fe6a56e946dbee43909bdd7d516fdf756ed8099ba80b1e17a5e279119345104379a36962ca9c8b2a53c414d79eb09fe79862ca749a9eabd9185ad1df57215945882f5894868a134bfc35c835e040e77ecf077d6a98a73ee022963d70b036be3fe5718280ae52c5d751211b22950c0597aaedd35af41f7dd5999e5f7ee34a37edcf97df54a46742b0252b196eaee454ff0c30685b15f8de087de208906be1d971f0fd89f7cdff2af0bdc96759d6889fba9ef092ad1c8deab0404562a7f3977d211c28dfd1573aebd5427a8773f03986101703fa19cd4ab96a381c76a747f63b63f7a9a3a08e251cdc593a024f63b443b76d17dd9e151809da3c582fbd334fa6dd0221b6d410c6a78ba95bb0154bb8999f619f2e084a6b9755ceee4ca3c7e0481a47776c8814f13054e627e37630d593bd09d5f10a049c66c9999f4b0b037e81ef70615d674c7c7975972994a053c069675fad3fae5ae3e779233b70254fb87f25d44c104afc3d5911b8b695173f9337130e39a02cf97356cb817f6cd23f55ef74dd06bd24ce5887a7001ef576262ffaa99f9bb5e3f55bda2aa0f199115909af48bb4d6b1a0a0847774515302cafebe75aad1f63362b1f38141e8721851c3ef1a247931b3b450581eb5d09027b9e3ba60ae9801d629b74991b7fd65520eac561d47115a85141d9a757bc75710bedff1630561ae05254ea541a7ff1846ed5e164834417556dd562c45543c88d8030bb56451fd5b3cbf10fb0164c5288789d2aac7e7a836e79bc3dd401a8e3e05aa6714ffb2dfddb3037c35fa1ebed62a073b2da42133f2620ae88de5e3f46cc69f2b9b3c9b88e39b8b108059ac6bd493be5f7a39f6b53ee825f4593b77ec9238f5ab804d533f48803e7d8187291ee25cfac4da5d8c9279517adfb09c422f6d704711726c73828a5082b4c7b3d85611b8f496d3e0f78c5c4f1dd1c722b1b11d55861f232beee6aaef8a00fd2eeeb45f182af191ca6de8eaa25ceda5451416fbf6d1abc0670b8c10e2815076f271044c690bdcb64856b91265bac202043a28f6bbeb807535aad4bd89e572a9427c826b170d3862f4cca70ddffb4769d6593a1cc6c42fd06cf68642835fe474a23e6f63df316f8361bab959b768d78e20c03c2a99913c162a9662bd9981eee55922f36792de0af68da04ab49dca72e3d9b0de79df828b433bcf6be073f851a36418c03a717d54d48c1014ccb793577c8393b7cb53cad6bc7060a54cc6363734f6ad388763519ca09b533078d3cfa61d7bdd4c4dd0ffe64d68d501b55903d3f4a1f310a3826ac2ca700de01d656188dcf577fd1b63e305614b8d13471f6f84a5d4b12c5e119870a63d1e3dbd39d3b5c26b09f9d80f8a59ce836b20bc933496923d278a022c00f3aac204d07d2e5075bbcef1e4820d633a3a2b35974f72a033484a91a1d6a9913239c93e5783b01833073c98f358e3465efd5087af37ad60b7285550e776d67ea7019e788776c5a456102358c32eb4e7c28096af88b9a20d8ce379ba3928a10ffd539c106f4927e7ac0f382c74017d6e4438fb128c660affd45e9bb68452de72b574eeffe3ce239d0718908c3800bc7e8ecd2fc7d9754171506017fd7868594c9373a96579fed475a28811649ce5dc8a3107bd0d8578748878ce4998684620931dc3981a2499568c2f61174c3b3fc46a7010468e8ff75c08cd43ac764d95e2ad1659f9db62e9554f811e0f43bb74779d923c8c243d12a5314d3c0c6ec84fe60e1d2b2e2b20d3e64054d62049ef9233ff55223a319c285e4e3f4c98dc95b2ca81230d7fed9bb99fd7d97430eb32c9c11647992bd85dcb47cfd58ea3e221d095bcf9374a6baa7c8333581f62b9e489282483023fdd18451f09bec764146b587209160b3d1d7a3d2e145fdb640c4bc382541e0d84255122d51a710887ebe1ccf29d41b4dd7fd7368d68ada250d3968d6f0971f0849c13c09abadb9db8b08960a18f84f0346ea0aa71227afa55b90cabc062d549b616400d36450b19adb67d7358e48c043fa1135abfca89374c906f8d1a6a845debf6b37f055d390b029c7f4524958bdf8d7e2755dde3b957f0926f9d3b8821ba96044d3cad2d637b973bfb657fcc06ff44c17965acf572ab7a0c87604c7dd1cfd136a0ad02b22e8ef320e101ea09772588e8c5b4d88f40fe1be18d27146a2b9559491949671700cebff9a709f297c2621ca9d5d1749623abc20a326ff5be55cb9435c03bf49b147b1e0a4a918bfdc3642df90b396a474f81d75c953d87b3f3b4e31fced630bd7c481c63acbb84dd31249101ac5277a36dcdfc80d8d9a2e928e9b2d65bb257bce97ccda83b187da8a7886dc96eab93d0864d88c358105f9cfe1ad0f0a8508b5b3985ff95de652e684da970b57669aa3fdfbe590a631522abe8246393639709a9a6cd549e78e3c2d1acf84643e9f554c5e076f75a5c1dce1be20a66722d0b896837b7036509ab8d473d5d2b7a8374d6a575f69d54afe3e7e18f4faf4e917be8a74e55c271b96d966e0c0b883f84b3ef2e4f278daeda2efd3ce770801d2c4bda5eb9b646deeab9fa55324e917e63e4eb6aeb4176cb4e43af3db61aea1546fbf16e76a12fcdbe726b565710e3f9866551023e5fbac0038678717e6ab4d3e92dcc53049e8cb65c00216d31a8869ff4d3539313fe2fd7ce0f53b255e3659e7dfc5f92b7627dd9ba42972f0ba72b888932d870ab97226040c4c0f4826be131fe1d2cdc21005ec2addd7796f0927501251ab26b0e5f3f9d2a1cb346a774e18bc233cc89aa69f5f70e3d5c17098eed350ec419c82837153b5c7f5813bf5918defc8df143063f3fe45125deded2b15892d5cebce589b60f2ada0f9d608983e8d107d8e6482b5f542c6650b014445e8c055aac142f16cfc59229fc9626f7aaa40cefacef777e494e13dfa93d27c201788ca9f60e572af8d65ffb513473dade5fe494cbf7377bd1ed03db2571d65af3be4b0bf27c1f069797bfb67ef0bd8a88c6286af6712c106df9c418d88054e3b46c88296a2e63894d6bee0dda8833c373d6a1b27637e1510fea3eb2fb34ae27354571369653a282a8d19f2c34f9e5ec34555b4ed24327dc5d246df13736bd41021697104f80c85bd0ae920e9aeb4e628fb8aec269d55858df149af298b06d61250b043c8a14a15f0646d0aaa18109d031c449e66dd7336044dbdec912b1bb615fae2a3df480bd64cbed74be65c8f1acac247e80bbaeb6f9dab38c6addf4f3b094d5934ef5c9749053b9159e280034e601731a12d6688ff27ee3581ae289de424d16676fb750d2ccd5b3f964dd77bdefc15bb204e2350632822384cc194cf9130f1ee81bfc3887d3366ec0b48cbbe0fe674281ae7445f03791887873659825680448f162452cef57d783821a73047078a8cf94c416850092ac772ef0b2e48517ef101ee0681b5259aa27fd56edf3c01e6dba6298ccc91b09bb304b637eccf8c673b816e74bd7f8ceffa6b17ab03df7ee9ca4098d24d044015a07df782a309cb6761528272632a6e1323c4e18284b463dfcabed708e4fc95cef133865cdbec8bfdde100621c65a92762cc3141ff37b66dea8fa6e3aad61dcbf3b512467c4773d36e58989e12a636389c1678c191137a5f7f59668c8a527dddcdd0c3fbb14cf48b8f3ea306850a5eda76c57aad06312d7bbfc18969d7b611f512358a7bdf959cc2f41de1c408133ef02b1fb2cdf8efe9973c27536434e56fc1bb4880db7fe901087b53ef3c0de18aafa47c25f1cd62c362f2e5da41c2dbff0e13adaba26c1e0829f027dc0320442e851eaed9507b70ac17180725349f6ea7b59bf39c095a9d10790e87221c7c2d24b8bca184ee95a3ef7449aad6c1d905f688498ae7a0cd1b01f76dabc342fb2be0295ca1484bece3c9b8a1b91e53de2d2587f3607a7f348f5cbefaa7a6dcf61bbbcae9444e2d25a77b016cbd1508c8cd319e9812b43b0bbca52df155d418dacb6ab1360a9e605fb53c6e20588a10bef42d884989e836b2ff16fbcdd2c1704f75dc8c1ac2cc6aeb92726f5d46e4784c70e1e249c102be6da506e5e3c2cef6a8bc4a60dac7adf3cacca8679f8f792ddc27613e44a70fd849b7617e042da46d65a3e6cf425f59b83cbae5b6e911142abd13a0a8cdf06d041435ee20e2ca417e905d2dc49c15b863ae5920ff7f9380a86bb0c86b69a000c157cd35245bf71f9dfdefbd1760af90ec3e554ebc511aebf650633221ca9157226f613f41406872765f8d7b916ff3877266f017b8d840dca0697ec3dffce7912ea9eafb62cc2f2d0a112c9bc0727444b47b62766bddf5b5f26d391f653b6894b069069979d0cf8cc7fc4143626a8420bc0a3866db3860096cc128d620ceff059d1614487004adbdf6b0c4428ac8897dcf16e6b11a692a6b465a92b40010f3480b444d4d2e24b0af8467666905c2a6233bdd6502521b621d3cdd4a5e1f268d65bf6a1879608ffd3abf635c5f0948f3cec7e087485c72b00258ba69783cfe7d611bc41c27814ef5674185791dbe626e1f276cf2c399a4eb264f19c77ee95d94252f546528f629188318e9ede65a927aafd2f2af56ff32c0ef39862d2f92268bc9400afa8ddeff591f3ef99681263a33b873bd9e01a59c8b281da30875245cbffee5268563c7f6f20b9e22d998934131dd219624d3cef6df2f3d2d6401833f72c619d6f763837141dbf93179d0f01375581ebe227185166aa7988eb9fd453d510ca6616cc013d551d23a33a4241e85aac3201284344977d496d768f5d920c5670b1d8bb608efc1b99abd261afb0a4ebe191605cc5c2e20523a13b3b94dd1fb24a27009d9a5b6329336f3516a327642386ba64c8769da1324a8a3d1f304cf0700df2b3e38215a954523e1d40ae96d0046e2929a815bf70785e94bc9b89246ab6aded60d65170eeb49b0ee0a57ee2e57db92409105c25f2d0c1a17b5556d06511bd0991a426258372c7f2b402dd533a75aa175524eb5d6b9575300b81fdb2258bd74429add8aa477bd1182db57107d411d16147defc3582861c68f5ce82e0a0316edd5d0f3cf36825a2c79a33e376cce2e63274b3b41bcbdd755845ad9ed2a3bdacb6fa3fa9484b7b60edeb1d9ef84772e78e39adca14c9fa0bb3ad1f1c17fb9449270e9b4c97b5b320839947fc73853fc58304ee9c9e86f3775f5469554d5006eb7ce9d02d5f900c771806c275ee7022e2b55d111338dd93ad51d14008df4c13d8c03fd9bb3689607e5cbdd499c3a372b487af74cb140f6300cd2dc2acda07277ea3dab57ecf0", - "9f1a8f2d6abf7c44fcdaa6dcb1f6e791164004b20b3b4c860f409c1483c7044b6fa445f7224606894e386ba08057a387b48920d4de203b1acc4dbe2b0b4cbdc3f7d7bbb097abbf81e01db09e120eab83def925a059cdb513efe6bc93f0579ebf75638df3c3d7f9eba3c36a169e9d88495c452888853640d93ee70f254f86e2d2d3fbb5e8883b36fbd2da105cf3a75cfe998068203186bb37f1d1ebead8ce1f9383b816f1da2fd0a9e01377b6ebfed4f05bec08b4ff9b90e385736fd13a3af7980c21b0dab58decea8e9545af5d0fb11bb51aeda2c8616960e8f6f84e6c2fc4f50d7e413afe030f75475509fbcf49cbe14445d267994fd3f38f41a1339f2895c0b2969a9bf9c59b85e629486c7bb5107c7a6b069793be7690f7a7c96c93b09a9d610594a156ab27a32d5557a5b1ec8920761cd2f559ad808dff3da64717ea5f10fba87b8ff2712ce322eb3c288939e0007f779a3920f45fdd533369f6f85a8cce21f91552fe03702ef81a926af0e402b418fbb25a6a3dad0ec18ec663126b3f48c341e2725abfeae865352d5ad275a9e3ca20393c64d118968023daac84bdc724a3c522d97a5878ed788cf8e44f80f8803d57584d8c8688cff24dd8c0e881b62d16ea30104d62007a4bec051da7fdc95d1df8556ebdf607383a0825ae503e24661ceb8ba773b793360c3f4ed3b761bd372570cb17e7c2030f07b0b45a7974e45ee6fcf5bd7ae9e9abde5421b42cff6af0c6eb7fc73f4deb67bb4e0b3dc9b4008da30c67071243cda649091a14b89bdacf2ae98dd230e932d9b277d6968c65e0006a8ff63f283f2cd9c21615dfd82e0b24af6ff559c97922a3d112ff0ef4af9d6583bec1f84d1aa8bbae705b9bcf458f5d93059b90fc2217ab27d0072a38aec3229d13266beb3015ac2389a06dec3120c6c04e540886091597919da293a4a8c0812d6cd336d5c5faeb64162ec0459e252d219bed78c4b6bb61c1213939bb3cca12a625ce5a45001d7408f6d40fa9466377caa43afe961b5c1602679220258fae72a8de2ac69c0dc97c90c270e306dbd8eb681ba9c092896b19a8d42665b94ff4d5b8b188f19f7c44abc8f88d4ad7b5df1cce3465de377072c70dd20dbd6779336f05ce328ad741d1e4606dce7065347df111c7d3282c8a3fa4a9458561c04d1056cd53ec5a8ddd6bd4434ac910c69cea0443fd09ee32d1256da44ab7896867a0c97fe4faa4a53b6db5cbfe3812a6667f04cd318f3da127a0dd46170cfbaadfcca863e0d4240ebec1cb2a5952881fe89804892d36dc5bd6484cc78db41bed868ed1b321a680a293bc29c420cffb5305d15fba05c76c2138b986f799b6a3d061658e498204c2b641f2f2ba73d633538eef6b5a01117951eedb7611742c120ff24261bea605e94d21e452ddb9ad27af08ed972b7d5e1eae010ec5d83e4505f6a2b7d9a0bb32a1fbba32a2a8c7823e736a69f516b781fb5354be4b0a67343c009a09b8f656c34ab895f9213531fdeee911d677d1cbc5e72c0fd1ad1f3b4b8bc735e14c3f75f1828ea28c90cda40e0cbdc40dec37031ff3d50305d5a8bba1d53d2f176895e53faa3067129a5c97505799967e55e4e9d87faf5920d71055009fd060ad06691b78583f63881b566d4a06b639c55796b23531ea79c6de24092c0e6fb4d3dc739f6d82ee3ee39f229de4c844aba36432d6119be0d2f02e5f72ef1d95fb2494522a7221e18e92cf22e00010ffd93b89fe60b6895a37fca91aa2fefa8debdae3147fe4f01a6adbfa0a59a5203516b2cc7de5faf821a2e72d43beafa30ac379791ad1e5da3286abecfc7a546b80191b7b892cdd01c25e95506471f5eb74568257439aea03300e80699909cc06db2fd607f3279651f7392f80bf4fc61d66f0dfed7b7db09744139d7374d3cdd18d153dede2a65f26130506acc51d5c721a7989485a145dac9565ef6d3cc938c5a51f31ccc88bb0739920ef8f0a01145f4ddccc74790a22a3099a4b57e31b3a01b4118c9e6c393c1304cc51ca1784db5633eb96ccdc88f8b732815b92c9072dbeb61a2cc1e6b2e7098d883e6174f5af7bd4f129389250926e041ba94d1ac543aab6525f151294060791fd26b668d09302c3482c78e5f3271c0150c437b4e78b1cff6f2b8660dc310965f2df14a1f2ad45cd2759433c4f3952402fefd79fff00dd309c3f09a58600223441c11693cdeeaf0a6100d38d612a759a8e01f753982803af30c7470f7bfd1ccf2c08aa0b187382d25868a9fdf729da10bb0aa0e1cd9c6e695eb2c80c6b6ce62737c3e655246edbce5b8f7ae21c473762db0969dc216a93d4db239f67dea74a1de21d50336793d1ae45e931d975bc706ea718a2ab10d66a59d9d23f76969d870ac279611246ed3aab0f79e11611b312624d78b88a9d1a49dc68d6968f7428c33f0a7a65675826422f7ac058101d2f85663de331345b3a25cf76b7c8fe0988a13278be9599b8e4708526b44a70bc31ac5c278ab739e3e6f0927b72507f34b0034e7fdf43364c466bb75b559e03d4d18c864714eb6061f83a6331b3f59dd62f39bfc2529d5cc68bb6ce63db1075105cbd7d7c4d4ab68c9e65a32092e34e76c3178382a965f49386bd4aae307128242a2ffe3022fd7dc1a824b330b9f032d55573c2f004a6905178a2479ba8a2d5b3140ed5f3e10d986265d8b4cf262295658f301b4d36281611d9c61624928da9abc51ff9a6eb481310511772fcb1c1786203d25295e4a319b9c6d65ccc966b4c5795e6e30b2b3ae8246c38b4a911d1904145de63dbd4470fac47f8ee3eeb3f58b5e665c26a316362382ccc6bf8db7699fa3334cb2ce61c746a7d3af24d8030df6759835f5890b7dd1de538cac1dfe843ad06eba2e887f08d9a49b39246fb26eff5cacc937d63c8d0136f7a8ed2af4cf473f3f0d9064f97fb4fe9938d631f7cea3c617c38771553eddd606ab80bf792f34b44111933796fe1fb8bb104223a4de9e16e17321ea7f8de3306e75a2bc79aa5e9c0ec8dde9b3dd1f2ae42a6a278410afa8fb62c16282f1e3dc1e2f8c28d4538a75b5da7645101253dd43aaa150b273f73e505d490490314606264c737bb344b616a80a4931825043a740ea4f75847e98cc99c6880d3085787903e54c63e90b60f03192234ab20cb41c70c6e82b00e0575a1bb0b0f435831c9ceb9dacd1fab8a7328eb3e28533d5bfbeace430e21758cac204631bf033752f947f78ac2bbd9423c2baf4dea22fcc65c96c332ece9abb20fed504643e82f3ba0fff213635910789a2fe1f2cedef68799fcf4a86d63ab0ccd395d6d4f393f7ee8905eb77df32d97592fb34ac86dcf20cbe5afbf9e9cff37bc34d75af046a09a1781cbf51ee2e0b0f40096d85413a30de974c4d1d16ec06c0fad00716c4e10f8dae46ef3cf27ccde74502b657d3dd26b5481d9787f5c6034083ff88807896da55fd2c951a28f15c8c9e6c86ab50c369e5ba4f6311de505c07c7b85573b5a539785820c672557cee4b58dcda948fb51c95674c23f1275b423ee5bf3a646df19bb5dfa22747857fb5c605669f334d116710bd9f1495e242bf47d6b607c1c9d9c706ee770808484ba552c978ef64daabb642a7caddf5a55facba474b8a63577ac817dc57e48ab072bc6a2cc5f5ae96edc45af41c896cecd8acfc36604db3b7fed9d2d17d429f94bd2542b194a3d3405f46c1021ecf6bb907fdfb4b53fe445d5adb18501aa772c9ba75619214384260306ab68a5ab59161b\nCiphertext = 66c03198b3422cf3fd8291080f6fb3ebd9ad863e41cdff169becde726946a342ffa0ee547a27bae28cc782d95a90b0a618f717e3beb577354bd91e00a7a57485588265ad2dd0ab946926fea7c754c42751ec7247ee84c17262c0ed092186ec57d6044f0ac9deb21da6714ec7452e441e687e138ff144ea95636286263685419afd35f002830765d810b6f60e8dee0e6879995e9272c798b067d5f99f49e460b86d67c641f48240b61a16dc7cc27b048e8b8e8e80016470ecd2fc4225e29bb127ab48dfe7e7d5a65542176dd7ad40c07ac8b92891d595bbd7afb63fb6f9e1c2aa2fc659aa101f9b6a5c346625acec86fccf17f0d45809f3b9ee81572e5627f1afeed4ba96c6d3ed7e9232358dec01a1231ae7b94ad4675239f3b456adccec439b3cdd45504c5475bbc77dfd242e5e9671d103ba71a4601a7322e0e295357f335fa8d5651d528dda66575d106308338993e615b1c5bd7e95bf3f755ff726b4ac6dd5a43ef061ac9783f8f2804c68f66486f5844969103a36278ee0d10798bf8a802d3fee3a31294bf00ee74f087749ab3325c027d42b55b197469a5312bdc5c9b316b20093154e66605941d58f4db8d46a815c06f209c1dce2363771b5a794dd8d17e93a2fa7b194c6a0b79793c06f002638e5e3052365221232cc4b30adf161cc6e7865cf02911e2ac9b0a75f000e7ef3aa4f3c7438433513da7246d421f208b179763651f18e22a793961e5976a74744696912f22915244fcfbefdc472baee0be1e591d6503f2d9511ee1eededd9f5547c95eb94de134d0c2186109935207a23b2b8420a5858d831ed78202be855cc6b98d6663c1c52e1a0022ed7ebe0eea6b107da4cf50c1c7fced9744a914a66d4604a081587ce4b7e0f96ed408b8a9a2964314b1334a123d5184889958e6467a6d16e7615e5364e09aab75994e2758345511113321a3436db79351c63a282095ec6b99b6d775a5c09ea3f3225716e39e14df260bdefb2ecfe9a65c73ab4b3712ec842e43ccdfb535e3685fa39b4912719e67bbe195e5f0fe6c3aaada2d81b669c4565921f6c183d708b50c3f7172ba841815e9351fe5fbfe2fb1fabeb7cec9bd1dcf2d6332372f1b972b5144aa7ed6c5a985132f9a54469097e2e981b9e75a7df48fa79d0736c6f8a201c7c7d0ac8ac6512a7089514bf58442dbae0529135a7f2455e0ee5716c6610bd7600b3159197bcb20ca055695a36597bf7d3b18ecd08031b4ce3a643951e231c7ad15481e32ed7a3edd2b379c8e96d3288d5b93b562972a04f1b7e0abcc5090cb8655422cf5e9dac0b49678138faec81c78f113255eaa6110e95406a7e7417a6e221a8ec7fb9d55643bd589ace2da70fcb41722e66e0efce932cd7a34218375b6dfa3df1747953b24a41f94e50b84bad4d130d5dab4194665338e06f102f46badc5dad7aa06edb01f8a31244dceebe5e2006d6ab4a31582ff46731b19071c08ad1db79ba018687f3e6afbe703b1de26c11bc8b62fd6b2fa3219fa7190379504820abc97ff6c034f7850e2c7fd335462725db6748fe45920c213c539356b691f22eb490faca24e99f0a044a9f727d0786566ad00635983692ef324bbf1f80c42b269e9d5a8df3249873c51521c81400c729ed7a5e73995928abe94d189cddf2774f1735bc2060bb2240e558699c365dee45fa68801e6a1745e03736ced1b89fc2755565e3b36c2102594d43c451122d94f4a263664bd26b2fb5bc7700319f6b08796864f92d0fdb41710910bbc13aa9cc7baac3b48a24e4f3573f315448c317c149ddb433d9ddd2a2f0cfc81c22d3dab31f184975355b41e4b36fd8f22e8efa01d61a5cbb0e4fcdd273cdf68ac73fee745faff44d44d93c5a111aefe4a5ca8e8e7c075ffdb738cc5b6466dff78ddd837c72c54941707b04d60bc126a3a2fae9540ec2e4672ae13de0d927a7bd363f8abb5a56364d6d564df90a46df9fd59e2c54d5bcb8280415257a6976d8fb24c33330af32600cd1559e0eb05d55b34be456d434bc", - "a98252fa531486ce2a24c8bdea1d57d93a550ec586920903a39ca61cbfbce79b8f3a5b1653794872b2c614458177e748f8dfd43840e5bb0d608c26389347673fd0b005f60f52c56731ee5faec6c8d0617fb53d5f2415c2e7906ea0e6d0066354b213b3e94f4dfc311e4ec6afa7e8d1c69a63cccf8326741456a5e0bd0a359b7a37c117f7892969ad7b70cba9bea0a975ada7cf67e0d7255be8d2c6e7b8788b9ff14c5d1449d6173e07b5f9d94560d46f474ab2a67056fe9f4a9fd617a617d23143adb4e7ea35f2d5cc1398fb9ed43ddcd10f28debb27eb13533110005e6c78ca4a874db68c65081ecb8bff1b64eb1e2d7b76a1da3b375dce8a92d32a6277ed847879345717b9649f27e846a701549311c7e69a96d61df616157a114bdf1663ad93a26c28e1a62ee4a7c72bccb9785639eaf1e569decf777bb0548ad9ee36788cfa1150eee3ca3c96f09052ba2300cfb7526b9424b6f7418c27a1e9bc13e4d9868e5c330c051c3885e44714bddf7cb090fbd0f36b826aacbe191dc8c35c219e19fe736198c29dc4fa1a98b5fb1805dc29ecd02f74d4510a3928448b5ee61b5991e46644850a4885bb1ee272883faf27962430de1922d0883e7e80215cf5fe7e8f3fd0e2a49bd50727af793cb7e5b40860e80a1fbb9d5b5696bdf2f741909ab5a713de47716332df6c4f78288edcd6ea130d895fdb2f29f94635bbf2061de55f1801bd6a24294aa199d78021a1ba771c651de4bc08f032fe6ad7a5caf6a6afc6de649b901f783a0ee0fea9b803beeb0f431400d0707f159d7dc29c0c334a918fa08a653137a4a8bc86066c8800e1d171f1dbddf1fab8a3eff6b5023da96f002e7e217e826fa378b15dc8a376db30228f5d6b629f331a162d63e53e5b5bd7ff9ec098b4314285908281930ff0a8aa86a6d89411e6b5bc6b9c9e931623ccca6741fd6d36311e6a8e323a37ad40b7a2797b84694e736d9c135e52d149c760e727598726378cd674b0f4df1c361de0a12a2b8232e611d789bfbea699e8e77b99f3449609caff3d6ef7233df8cfc624376c905eea46c6f77c0b01d288868a19db77e227dbb5bfea5cc3f49d219c7477f7f2b3447b0b8efe08eab8f69579d727555e547c13ec7ae13b83386f2adf634140c311b6e2759cfb9c8aca1c32bb7c002d0f46ecc526916589a29e328ded9679c2163838f071b5b85b35e5e7d99c3c45d25bb9d37d7bafb8350ad4695a6e0cb7ea7d93868c30bb54e301e21147696b7dda156226a5ef8c62121e6b2cad0c4e192116192012468eaad46bea69a140aa3cb9056dec87c911636a1e55695b9e5a27c63cd8c03f31570d4b7507d13731ea31f082b33c6db8dd6e22282f9790be41350a96abfc4dc3de78e0a698930f540dbda3fee923a463a4c4a66bf00bb2cdd6d22b62a47af96b78b1f0f0a174e4ec5b785b3820f47d3c8cc1691d4751ce4e4ab78a4551956158a36717dc35488e890d0631241906db565603205e054815aaaaf17945c3372dfc7193369871e2e88fb84c15a2b9071101e1208177fc18397e6af17b5843e1fa75392d8d3ed214975d50f2b19c24e83f010f8c394ec1edbb1cb912e61627d2760b0e630b986bba2ae113b8f3b51ba00ddc495520274a85e6f6fa7573ac4ec6e2a86a1da9199ceb007aa6f132e5ab8ab8fdca7c829f452ff17524fec475b8f485b29fc6f0d972eea4ce98e242b5d58f6ddc1b3a71256de1c584c9914a3cf1e469f0033165d934fae68a7559011dac7a4e0c72e3b398fab8f8cc2fb67963b0f9220f410e5ba13026a27288a1d49edfaa51e8f220503fb5ec476147cbea975994fffde3ddc51bb189c470078978d238f5287fb2629d23989875d74b006a4122f6a342c996d4a244e8c5e4b804a44c301ac4d6054181a07964b279e0a44c158364395a2ead40053d2f3350ea0529a57552ed835513f533ee0c4b94ef674f31851616a4fa2d0302d13cd4aabf5f96ce28219c0b5bc0e5410fe0fa387ba1009a6f2280f9e7bbe20c33be5eb411a5f6327714b3443b4152cbc54c4012473237dd98b0490fc4228ded74afc81be2a58a22e03ca987faef5310e474f4f5a183f6b7ebede5a8df8a0f94a87a41852826b29466fd761f40b416ad0f263dd34e5497867766a361af1654c3fcd6ee7e6bb3f72d64cc980f04305b63bd574f116d1aa35b4bd642cab0cde6a29139aaa163805c6c40384313d4ec6027c891023083988c1b0d2edbdd9b1afe102fbda285a6f897efff72a0d7fc19a3cb6756cfaa2371e13be3cd167cddb90d525cba7da69608b9995cef92a6424a14df6b860ef0f09830fd7189497a432347680de0f463c0aff82df8098cc4f7753f7680c8c7374d01046b05c63be73f3a1623be778fdb0bdb90d4fb4b458af2890d15f108b0927304c91c8d62cb148c35cc93797db3ef9bba1014d89859a91da0c0a971f330600d71565d30e9c9ea8c07e7f629e1a6d578da04d37e597261cae8ab7d9a952bbf71573f1bf70e064f36c032cc624e3c980e5ea46d36232d61a57fa598347b7fb6b28401e34628b051d6ca3dea190d1d3c343fcc83175f70f77a8fc5e8791b9788989df1e37cc4881648f4fc673772003079adae55c83cf02a894b98561e4a6e4416bea3df18d6f702ad5c4f40faedec6b53cfdb5b3a52d7d43b97ee23ccfa2d30c7264ec555b15f1d9e7e19cd9890a7e8e01ff21d3b8b451e50932f189a420d18e7c7e2f103332c78c84600e5e8fdedd84f055a8b39be9a52782d47c6205c0de41644b09c0931f2da269a7e58e669f3b61ebda28ab8e3f9b83ff3d2bce37864af494860b2f01b000abeb737fbeaf8f9fa6378366606dcd0fc33031b94f9a7a0e562c08ea720a671ff92520047f69b138b4e032c3828874ec4c29e49aab302089956566372b20c0216b601c3958ed9691bbd89f1df45c6613d469e3b9758a70c860fddf768b10a6bf70237a454a2c0b70dd5d02da612a91fc5731513012a4a6fbc16d01550bdfdccaeca22bba104ccf6aeb19f21d4cdd3da231af8ec5bf2a726ee9cc7c85b8ed46d2f6fa4f1b010b2561fb69690d5a9df76d729450a6e139962bdaa2bec0254c5a252b97e7ce7eab1817f454c6121130952b8c40628065dc9b77b0f953552f5aa3ff983b6a51a51dd87c2b51a18e14adb8c80e002d0b47c61cb357babbbe3ed51d371941a8f111837ecf0e45020cb941de170c4a1b5e61bb928b1b11a8d902febd2ba016771f171b8a7ae825fcc4642d95649d53675d0027822e4ff79ffd302bfab1a0ff26f3648c7ab00c10f8d95f21e40ca2b40691bd4be79bb9ccc0bf760a05be4728bbc0a64e585207d1d09393a80d5f574442d6a933966777ab05f699c4e84aabbf753059287e7261d972745906a4fd8967bfc80ae9b6ec2ee1b22a81775f4f24999987365ae2dfb6739902ed51b9a4394fdf29f216c34567102d9db301661b09b728a79e377cf4bdfcf5c83b110a2e267abf6d40947e643ae2ff0c244af168c9f33e7685474ac30611ef95f218e0dd280899a92a41e7a759d03ce3709c2a140ebd35e199f1dbb96f7351cbe1f3de8da8c49758a49b9e724ebd3220ed6f51112944f70c0d1e9178f68a2c9476a913de00abbd1f5bcffa646f926da77a9e9fbdf81cdeaf7f9b13e843afefbca81c93614f8f1675325965b5836b8a77620a5ff162e25366718d8da7781e1a7e01fe2e9e56cf958c6273473abf5c2c8c7fb209307544e1c0726d5571e521621b18b6da3064b473423536b1b76ed75b21b4ee205d7ab5f081bada63062706bd155672dccf84614210d72660095437c6bc2213d9c904a4ba1bfda14d350fa3dce7141e817a50859b1a74aa64560b2ebc67add9f945b6e85577589817078c8ae54a9fc311593d2cbdb6692b089ee6264cebcc7719753f80e30dbe48b64fcfd1037fb9ddab69a5ff9e5898bd8aa947d9ad827c26df67c6786edcacb3478a20bded1ad8c48018ae0d439bb5afad5d39bb8fbaf22d72ffd759c4fa2e94a5a89f41358ebdc4c3aea5110f1965a049fdadff9cf703eabe9628e2680fa4e70320d304ecaed13f513f27220db1916ca1500f1c2e091671fb71329dec0bd6e310c83e67af61b8ab60ee1a8d559a508d174648b1bca451ef0ab0ee2ef74f4fcfaad1cc5ea6cadb8f1bffcb1f2c05122011ebbf6abc16838e452fc47653821589da4cb5bbac10deeea3ba0e0a6241338e64cc78d7a923d018e8b5b51c4442070e5b0e6f1e8c2b83791e930899c5897a602c401c1b85827962ff56d19c06f5af033059bc7fb1bd29b65f66aa5b4397834e846935e523b16438a42c1f990ebe4f83182163ca5fc60a4c6d77fc182e81fcda943a962e9e7f00f6399728b48bbe38d8178fae3582c8d9998e49df5f28e32d541636df3cdc8ac00df45db12da2e5e76f366c1ea8667ba5f3542d21f58ead7c55d06a4b35251b8f77dd34d3de262947379107a06d2f4891ffa0ad3a3e5bb2bbbb978af4953310d4cbe5525ab344ebb98ed24d003600de8f3af36ff3d0a7efeada963845d573685bec2221403b994f97b1e714fd7dccc300b62c2a516e9c6780983062eddde0178e93fcbb2ed4f06f60767356a11d22ca37078fda1ddb3cb907d1020f62ba85d09044574ba28aa3df36988eb8a41e4305e5b0687abe43a90e4f68f0374b6b05049aff5b065d7688cbbfb0e96ab03df38903bfa1c269f43a114085eb4596aec87ced88701b42f0b7426389727308bf10aee9d8f15ebdc411ce1e764a290a12faa2d7c1126dc7b5076f219b826ac8d380b69af7f95d69fc3929a97f5c7da1db6270e9ee1f2a5f7fa3a1b6bfcca00463655121f681d3a627d03efdf0b5fd045fb153bc4488a9a8b7264373c710ebfdb1c267fdca37723b21d5c3eaef48e784bd76e27c133cbc24d114f610c79f2a1f2c30d87ddba395887030b65097ca5566eb0361e70615b46d4b86c2759f1cc2efa3915b4cebdf51a745fb3c6cec69a1fda2ec5e884dce228e30af362815d2d8b59a14f89606bc77439042109369a9648db7d71024ed6df06c8ebd22e8623f48feea77f48b5e88827fafa84b0564151a5997b7f29c4d3d18068e34f2690a293d54003d0ea8f3bab9387ca72212cedb5f4602ad047dbffae2ab3a4cd2865bf896cd96f78b90e4017eb7e3c7092320c0a37f81dd65a5c4817a4e7053e6d2bcb23b11e09f681587f3a9361e974ad54b88c72c296629b1ab754d25be15e87c414cff975fafb3d7cb68167b21f1889685a48966705222b525fa47143b00041df94817c275d93c2550fdd82471cb3cc1b5644338060b767e807bca902c180b3e535c77be2651b3962287b6d1f6403033de4e0aa3a20615ab59d290f4b167325959c1524ef216dda2ffce86b50cb6b56b62a20a043d9d78c704479c22340151df5a1907670f8d4f8c90d93f7b5d94d04a4d383914867aa3c0e5ac85fc299a4d2801a3f80f4b0f046fb62c1c8c539a83b21c7549df0afe200537b52c80ebdbad8a438e430cf876cbbfee9ceb1bc5270577c27d53b40ac153cab377a565b1a9fbdee8bf8e94839c0fc04f7f664383bc90d56ccd1cc01b465c250b158b5e6f321c20db245602d10aab80c553d52f17282b095b5e2234c6c689a84b096112100359816cef7e92029fdfc048058f847cd2f2369ceec9fd171a0487bd7acfed6b0319832df6d59affbfd460ce8d12e4171da0f094e872a2888fe74925c5ef0621c4edad337f7006086748913b24d4d48ce36e662fefbe672b6d476456b1fbac6d80030ab93da93acb4a7e10f95", - "5547e7e20a0abcdbf909f05a2ee2e0b7485fa16be652b9d9fbfbf01f082488a81022bdb69af9e6fbe753e9eb92a1762afbb4df49f83ffc0cf03db563aa96fc5ba1af6d4d7eede6067749e8ecec79b63e09742e29e99e1c960dfb0688b0222c49ed919379ac66e3fa1c72645122d1664721e78fefdd1224c0b886f6e214e37d268ca9acab76ab3adc9f5549e5dcdbb3d31ac34ac472894d004eed71f88ca2377fcfa48d3ae43805dc612891dadd06c263ed8617194f890bcbb964f010d277ddce1f6682e661577ecd51a4d5421f00935a5b24fef0ea1809fa5c4fe9cf8c453046f61136ec8872915d2462157d73a205d56d77bb83cf16b88cadf6430c0e5397fae1f91a6a11b177bf04b065a2e55df81d5c086ec8dc8a0a660eed37d41fe4d8b3e3f22238e2a63b6e4feee1fe9a140ed37b2be4193f75c2d038aac7f6b7dad2a3b37e5b9b660615ec1db77a9b7ab416f43e66c872b71cb67c9245c757dc87723ab3b9544fdd8a16c9486e8ec3c4a44cefd98535d6e5683426c1cc8c888b8e0c2e7528bd7eb89b80d9e00969efd2f0a0fb09845426edf0d1d9a0809648e7e46ea0a8c9988bf9df475be12a72c7326c1f2bf01afafb190cf6f649133c7dc14ecf9b8c971135bd303c8894bac637e08257d45e1b68edf550d896c41682c002396e8f1eb7c1e2f4e0ed9b8b7010fc7847e6fb1c5907c17b2d2b7cd24c96f47406bd04cfcb2099d82dc2902d6f91e2f8f3a05bc62019af536309e7847fc06c10dbf7272a1509079fd16bb16a85ae2e078f97f9ce66bba66d6329c7ee70f9688f6d91aa38b25c7f4884658a72ad8cbf96d7d7a9652673273ee1b3d4d17780dfe9ca865416e318bdcbe9efd8e071fcb15ceb0743df5af4f7d598b31e38677e65af61c1109fdbb11fb11e3952e6c3ae8abc3f894ccdf205ae55dafce1dd05dca6b899877f57d712223dde4e7fdec7e0ed4f0a29ad359e318eb36ddb42fb205adca400f5b2615947c4f0ede95788093a1152d88acbbbb272750823151e245354e658452a95f21fef05bbfd98a10c1c975ad1a08c59fa3efa9fc73588407a83d0b26a53f1b4115f83780bc70ee2619d7374ca45b9e200055df1b93977e17aca89a009110a6e74caec7f86114f91975bc6e8bcdc7267ed2920cf12cd7137840628e1b8a0ea181dfef18dc5f74e752f842ea91bdce4b420ee709bca72c4514e92bcff55902e5529d77fd95f5837c8f4fffce80c813630550a0dde24092a25f65eba90790a06f4d4c3e739aaa8194a147fb32e81c71d3e8def79251c33637661b0a621a2a6b302dea00d34a9dbe9b621c1dabd0464e85241aa6712d90b4287cb23c17bf1e4d0e6dbed372e6b49c4a843305b3b0e5cab0b0964a93ad0bbc99ee711afa7f2d0a296a375fdb3176c65a957ddd9b88e9d57df736acdeb02a71b924cc2e972f51ba68a597215678573bede9ca5b3a0a2461b2d3b9ea57a5af8c91d40779bf917ded32f14a66d96e28e1415fea1e9306654c6b84d8a64243a5271c1f11590423c718961aecf5f659b49f67efa78e02ef2524d0966ebcc446d73d49ab7ec31f0c009069d14ccd63f926169291b83a3e37610054b0b964741e2ed8771d20bfa225eac0280b4d5af0c09d3218bd497a035536f5af0816884d606f1a872b8161a266466b56e0be8b80a7bde65ac706eea8cacf1749e5e71ff9fa3e69ce878427a0728d44e666eff977026abfe18cf3ad156a943b917e72ad65725a9a8d60b7b5740494fa63143a7f2a94fe6d8b319be55d6fe1a988244deb798f345f30dcafdb6af9e9cee9e35733274bdf3896750897371563ed2516c4ca6c3c3c994b48cc94b67e8129d234a0e19dabe39e500214c0ed5f0e5d61b2f58d7355d147102d93b2689bc5185dd4c0a18efd11a307b887d4d0fa84fd992731b3a80dbd027dd36cd6933766c537e8e9e27d35d5187e8276b0f59fbe7b6d629d3416b782e7981d85e1e890853c3aa94a93c1667a55044ae42badefab979fe7d525c6a180307c5ee3a9c3933038028c3e1d15d1e78fbf53b6ea61ac5e02db0161719398a31570c55f73cb47ddec8f99e3e14af5adb8d5cd179f4204d080331e75bd391b19d38eb81f148c36af3e8a3ebe76209bb75c9741a89b5d0708bb0fbb0945fc6fcd6ce142d19faf0947c338dbc8d976963281866b5216421c00cbd77c0907d1e16f5e925319cf6c62f8c6e8eff0c2f831c504e7a1c0df09a54e2af708ceef39ed7d0f63d83429e9b0920c03cf85c2244f2fbac3958847113bed577dbde8992cd91be5833c75faedd5e2005d4f7b66fab8fa9305927406f863d1795dfe04028940b765bd79de6972dc7094fe1c2503a73d7b50208835216c23aab3e47094587549fdd74bb50ae21cd1354daab632fd0907e63f4c2b2d39d7fdc4fc216bfa742b4608238623cb7fa01bd851c1e7ad5ef5215173a71f363fbb7dae8092486f4a1549e32ae53b14c1343ff7fb5e2b1487d9c594a1b56e22625d275e41535534d225b7b2c9deeb0d30dba7188cf75d680d4545ed05044a0661c690a37fa14a73ba8c68357e2c948e290b5d9a4b51822824614ef2938d19ea4b650041f59f3b548f0a305b86f55e69760f37f09dfdad62651aa5fd84eef28a4431136b34a49c9bf1f2891364f86b0aae70b0414e821e3db1533b0f1db5fd232308bf118f858aab5ae974c10583f61b283a3870eb82aaa8ea3c4e2ee3c3a3d7169aa8e975ddee7f620f6c5bcf3eaaef0101b62cd54495cb8809052c9e3151690cff7c1efcc4f63b22472111a7c5d9d7d2a2be951510f60dec8c426f14700c8630f8a14dfd359addf5d9b7ae031a745ecb4e17321b385799c90f924c4780287ac187530a40b064064b9036cc46e3f87c4d23aeeed1bc22a5411c7c503594d5d1261eb9fc4da242493beee9f671485a978a32e965faf9b0e2c13f78e31e1630b72d35b4be691e90b3798e18223c1b514b39a8e1eeb7897c22fdee1e33fc76e2b2f9298ad4fd89f44163aaab23d754d98c7890e58708b81b3832aee31aeca85e76416133710aeba0e5d9f17695e607d09ae3f94be191553bc39c6df03cefb4ee05516fc02d66c9866e4eb0d89a662e309379a347159db2e070abceee226f2b8b62847ef7c51d69c5f12eb567fa13af4b4f90b3f3d9d4b6a3f68bc4dd77075081e2e99833c18b154d0d6ac360141de2a25af61d551f10a34e03e1419a37409b4c177c51a8d248157b411868eb607c34d2daaa453a0954fade5eac45d5f21f50efba8bbc9c87ff0435c70f064b42cb2d158384fe0a4d9c90030ace7723af0a6c8faecd8f97f9850e2a489a94ebcc655301e2e14711de9eb08726638a9ddb57160c5545c152a26860a17dd18172bfac138a300f60431fc49eff18c93f71400e887f878f4dd637cf5df8c1e2b12c0f87e31ba2754ac1748479eda0c4184b528554106128320dcce349939e5e6cd3434f86dc7adfee28c008a21ddf9d0dbc87ceb14cc3afbef1e06fb3f9908a4b14f5e6c43b23ba783b75a6cbfa2ebac6533661b8c1143a34e8e2a9723389c4b7087dc07701c53b169894551084aedbb423bcce2f470881fdc7240c26b3b76fd6cfeebf8eb2828b4741e5e8698b19fa0a44703cb4e4c8ed6a7e4d6063f5fab724e08a159f4f04a2f351dcfb6335ae6697dbeca25c76b55e6ec9045eaaa8706902df492b8c8cfbf68c4cc1be5d1e5a173262e38bde051656ea85ffe35d97f1b25f6a47381bc327a946f7cbf6210adfd957b2921\nAAD = 85ddde4720659e80e25168585a354eb1e021c0b5d2ee289f2314dd5aae52bdf1fd44755bb56a6e659111a1d4b4da73315bde01c7d2c15a4f7114aefd68c141049fac27acfdca24e65c51fb1c27d307cd948e13af2963166bbc9411401d124f1ddf20f890db5611385257f52aa05c09b467e3ae886decf5744ec3749e5879f2a60017f601bbee11a66604d5f3d521d2c48cea1794f77366f29c7bd12a8aa51d34a4f3fb52809561b527016bc6badf9d136156c330e1d69d1aab98c7caa9cb46e782a898b4c66e4ee3e2445fbfacaadf9a8f73c4cbcb2a1ceb604ba5637b51337fcbe0fc366da98e805ceeb29feaf05420113b16e1005079c0e88af33f5970b3d7a8b51d0d9f5120a0795063db508171b75ed07705ac6d6bfe4ecc59243091d48865536515e036860affa880bfc91aae2fd1700de15994792aefc4a176e5d49d0f9135c7d670f3cb8798bfbe83fe73de7427e0f3e6a2df561cfa15ffe6ae80d5016096c8875b0beac8cee8fb530fb421b9a8ada4d551a528d0a0b521086f5a2db371a3bf12a2ef861f831fcb44cb2baede907a9306d3e5a3af796e0a50ba2c8dd61fb03727df5f0654d837dabee2fd90eecb7b2e8f303b0d57f97dc6a52d8281574d8457c89c6a9f5d80e0bd86c90ed39b1db4253affee614e8cf1ff05166c66e7d2a2aa2fe8a81c4741339683debe189c126e7f553a5f2dc16fc16672f74aebf94c7e3041c758fbc6d0c7f71c192cfd0fb2ec52d0a0705b05815d567f3d19f9b5d553a2adce9a79159b0e38980851bf64e97f896c028a6df8363cf1f13f4654265a7b0c0b24198efcf4418c32772bafd3980dbc689fab12e85b3ef4a491e2e5ffaa2fadaaf3deb392105a42380797d3b41ef61303a6016b269ec9a9f6e3f26070ff33cb467435ecb325dc7e18728a5c2e882e720c8f876fef10f5bffd5a925cdc9689d934272019e90e3a3bbf63a295f207faa5c014e1517c7d5c18c3ed70e92304d51944dcd3604c999d4aa8d8dbf2a4c69cbbc08635c968a20dcb80f438d43c57851c4cafec0b9568dd6c19932fd3f1294afd16f019f20e40ec87f6f5dffc7717470614b2de6e9000969e6b7e561cf91c06dd379a09c6c25c7841330dc78fc5be1d9b86581a81f55c0289531128638441fc98a1ad9472d74e2be2f874aff2fcf9c941502f59f716185a4c39289ca368c6dbf5257b5dc5e57a420792c26e602e4ecbc4f17c8787004eb88ea091d6b6ddc3c85dc110b5d1f46f6e1d872723176f4c73664ecb4219258fedce19ae22360354fa4894fe51d69434c2e58e1ec665b5cc33bb295053c591b474b6ae178c8834667bef971604279440170ebf3e739a4ff19704e5886767f81edce95a3dd93d1147995e7eb6c794b7be136658ed23cec7c374705ec0d8479dfb44cc7213076668e5fbe6a508537a9157815c6e5187b89f\nTag = 469e3ef168a64945f76d7a2013f27b68\n\nCipher = AES-256-GCM\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD =\nTag = 530f8afbc74536b9a963b4f1c4cb738b\n\nCipher = AES-256-GCM\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nCiphertext = cea7403d4d606b6e074ec5d3baf39d18\nAAD =\nTag = d0d1c8a799996bf0265b98b5d48ab919\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5", - "c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nAAD =\nTag = b094dac5d93471bdec1a502270e3cc6c\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 76fc6ece0f4e1768cddf8853bb2d551b\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbad\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 3a337dbf46a792c45e454913fe2ea8f2\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a\n\n# local add-ons, primarily streaming ghash tests\n# 128 bytes aad\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nTag = 5fea793a2d6f974d37e68e0cb8ff9492\n\n# 48 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0\nAAD =\nTag = 9dd0a376b08e40eb00c35f29f9ea61a4\n\n# 80 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291\nAAD =\nTag = 98885a3a22bd4742fe7b72172193b163\n\n# 128 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40\nAAD =\nTag = cac45f60e31efd3b5a43b98a22ce1aa1\n\n# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nPlaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606\nAAD =\nTag = 566f8ef683078bfdeeffa869d751a017\n\n# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nPlaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c\nAAD =\nTag = 8b307f6b33286d0ab026a9ed3fe1e85f\n\n# 80 bytes plaintext, submitted by Intel\nCipher = AES-128-GCM\nKey = 843ffcf5d2b72694d19ed01d01249412\nIV = dbcca32ebf9b804617c3aa9e\nPlaintext = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f\nCiphertext = 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5\nAAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f\nTag = 3b629ccfbc1119b7319e1dce2cd6fd6d\n\nCipher = AES-128-GCM\nKey = 31323334353637383930313233343536\nIV = 31323334353637383930313233343536\nPlaintext = 48656c6c6f2c20576f726c64\nCiphertext = cec189d0e8419b90fb16d555\nTag = 32893832a8d609224d77c2e56a922282\nAAD =\n\nCipher = AES-256-GCM\nKey = 53a6f0d9b8a81818f2fd7525acd65acbaac82684cda4fd357b1ceb6146b31ee4\nIV = 05d8a92b5a510c3a3dacbbc0\nPlaintext = ac0ae17d3d0ee5935e18675c36d9e43967f6da38dddec14c7ec574ff8473e11ae5019e638232323c175b7672a7462df6709f5014bbe12a1370a1ffb570177927106f995dc8f35bd6e6228de7c16acb71e583c87477dcc7b17a908ce01543496c2cab8a14a21c43b18fab52d8a882dd1d999b4275db34c7f32bcba624d128580d7566a2da4bcfcc4136d58816c437d21e90456fc86381b946b8955f0448e83564165a629cb2edb978e5941010ee9153b054ee429b315058334ad7899aacedbc0bf423de69f57c633b56033c6531dde29258694045c46a797987471ae6af8fee8ad0c1be4149605064aaebafd1c5592e61beca9b5c7771410a276c3ae517490735ddd6af499ff705b9fa68d50650e60c19f5ae2c88dbb6d612afc7be28a5f55556a2163b6f66609f7d9ba7e97c074ea39a618727421fbfbb6453ffeefa643decf11404764515d28fce8ba66b8c85d077c47a54125a38bcb6b0adf6d248ba0a9ea129c887c66ef537c45e9fd3c17ce352e3936cf139e13a5946a7dc9dcb6423ca6a051bf560cfc572ef366940e71c81aa302cb9701f9a5206e9eacfe9835bdacb6425d058022a27fe73e5edeeba98c7a3edb761578ab2ad5a442c2dc1cb3c143c6f18dbe525fedd2a9cee0ada3b2c116465c5cca9a7e5d4374b2", - "9aa4ad8adaff8d6b0d1ac3990685240ce022faaa07241f9ff445566b9e0463350792cadcafd5fdf5c37706c0025b3c627185b356d39dcb2244b15566e6e3f8942f730fd6d855daa1456fe294f9156c4b5131e5bde7f2d938ceb6c7f5deb0f847a98b7fd11a3f5d0163eef9bbeb83cfc96dd8eedd447901ff4d3a35c0ea1f691b01385eb39fd265f756bbd77bb61b1741db0502947b4b985382a08a5916da809a8afd3fb1d78d9e16f8e37f51aba100d031d9da8613e9cd2cc621025b47150b3e76775ab23412d74334bcd79746cf601407481310a923047ac68a4e6a7f7b96bcd85bb6f24e38f03c80ad41a0a581b4246ea4715ee561cdc5384a51a6fc9ed8569ba6b12bcd95e6202ecf834dd9062ec539cc8cc4ed64ab9ff85998da0e63161e7391b14de47dfde41523b6c614618bf2fd1edd68a5de1c03c4181569b6c361d955c637abbf4efdb5dbf2f0dd2544329c44b77081a48f53231fa9d4cf6f2186427e469d0cfbcd698f7e7cf773240dd2b807a2fe699f0ceb4a2339e9cde01114b2aa5c3591a82a3a27b308e1e7f092af8ad97bbe7b28d78ecd80c0c0a28372193d66bdbadc0b58e4d5408acace53bd5e12101fcb25754f8c545340fbbd1328287044a29d18f40a24b4084febebe228b67cefd970df6d44ffdc033a50534e5977bda660c589c6e3c3a28b4c500b29ff4a1c3eaefb068784a29914ecab7868a43999833b0b37ae79afe58875a0425262e0ec7e10ee8a6bc1c97d332bc2a6195de239a166486a3c1ad8de3a026e5b1757f9a778a511024a260c9809ae3b22d78f18ac483281a796b1ccbfe7a9b9f357d12d340e20bdf2037e8bb91ef858cdf2eb9d7161a756d8c244c55524f8f5be2e4f18641bc4c2409c14816846c4655be716276d8356e516640da49e8412fcfc7ac0e084a079129b23e54952d8030e1f8ceaafcd322dfb4bd189bb5d940ac83231de0585783387d0642a245183f7a251779bdb12c63e9edbf3d0c94281140598fea9e73e951ce650c984cfb1398f8813abf8f8827af5eb64a65dfd1305bccc45086438ac439a9265790fb225c509ce3c9d39e25d2276d7f3c06d7cc28d33b2c21bb38b50dca5b10afc09da83ba12ee878e0f6054e8d3e78d731671de4f9d5a7b97298b01f37c7e78e5fcf5188554bcf5d42559d3b15153bb3cd5a0d1cc4a96d02ae8b1b115d1ff617b6ad894ce0585f46a2a5f4cc1b83065c1d7b5d2f25f3f4bf9966b4c7d7156931861d5edd199c126f1ee4ff6345023419d0a4c87f3388fcfbecbb6c1e2f4745922b88085d21d4551e4c127eb423db87a51c9f9a140f8a7415dbd70c4b0173e687a40f895404f2203e14ccd61e0e5b0d5aa3fbd1c8affb5807d787d840916ece24c56c50d3d9ed9f19d73f2c80c461b5b3c07dedcdb41402c3826a958d74be48382dc741dcf3e0eb8955397da33941fc47288147736d778914a57effbafccd4cf293e6ed1c7d19b55433bc0363e41546b3638a4c630eb35dc6a074f90185cb9daaa6eab54825a4daf76f49ad918e90e5777a826d6d5d52f32f7ceaf818f87251ab4d1b5406ae94e41cc97fe022b144f26335829d9c81725b3daead621a0df71313d18214ff8dc687a7ab86b8eec3070ee1ca9f62005a0cc15ca6e2f4fd893de8fd91f6210f6c96a576024678535c962a2dab06f56be377dfa74bca089adb7327abd05c3ad7646b5e9e6fc2f29916b34c8642f3c0caedb53b8f30c2a77d1757103b7ed156cdc703911366b02cde87ce7343886987f7a8c028921a7b87c5c0aca7ada34970a6d0d32eb1b177ed8e64c1fc6839b9d08acec19560bf4a815ca6187635f0cabb8bf062e8216d3b09b7abd99e956734129e16a7c4f3beb850fe2b1548729355f9015c9bba336d3e26a27b3d75d75722f7a8170d15ebf77f325c97778a5a9d7c76d3e101eeae354e54e6fa60b58cbdd900751854ede326b58fa5caca073c630f3719d6f52afe675f10d464e8b58e5fde75a4f225063ca48d76efd1b645e4bc89d98215beae765601f635a3bc8cfc08d74722f3d95ccb4cb4e3ea977d0c534a4abb866fb9a31771222cfd998231c30bd16b6844ef71038b67d72c910cca40db7260dff0b74162449a9e2cf15d7dfbfb3a685080e6c83ff4341c95819c0317502ed49af7ae688b52c9866518f74d69b4144500ab9d5a0829b9287d5fb67b78801119ddae7a76e80be8c4dbcec7866ffa7d081406e51cf617be061530b539cca7e1ef9118cc06e8eb2a01425b45947a1d2332e360acd0654bba8f1fa43ece68467690d36f6802a32f03f9ea056e57fd548dd4a3225ad5006c6c931aef1990639498dc88a23895ff1f75520a8009dbde4debc20ecc546e378eb7ed5ea3740d2244036588471d96e4751390b6b76b39816d853944cb5677b493b36de9736ba0fa404ad4b3a7d7c54d0c15072c040064b871401b25b88559d059a9519c7e2446b0d110a4aba9c12555e5f620680d1fea2359bc85cd15b5c0bfd6b3715d647514118cd60483dbc9c83e285192108f4ea6bcbee1f0935044610c68d052ccaba23258d09465d5521e2664d59358621ebbb8f28a4627362c8397f0a9852e5d8daf53a961d4ee66299e2b54d8adf5134ceedef57011f810aea76262422236c3e1a478a759584c7880fb3f32389c4bd4b637caad7b2bd6fd295aefb150754799434e99e0fd45c1cc4698ab14d1f63eeb06e53797cbdddd45e7f87e85b45a3dd0df6335c3b1addee87ba953bde29ed98042d745c1465a967ef922993798966e1c8b96ad6f68404136be0caa2264e24d8d93aa1b99da9316c7780904753d4e0b45cf282b43a0c91bc9ff83cb25cacea2ea72563b2e759b69cabbb6a50d6a0a5ba545622e5ce576cc301ba35afadbfd1e26668782e1d741feed8aae894b564a425141442fb8470b325cf7c8e1552973463bf4e67a2ad58d15417e418bb91d2df4b1310a0a70ac744bbb4245efd2ae642609079a44cbf6be19809a5ff7ad6847432368c9749cfb336ddcc0e6f52a699b910cd24671f38af5dc39268a3c87771f07d53bf220b7c2d5058cc7b0bcd492abfedf9bb295ec304107130f0e98dacaac6dab998b511f176d48daeb81db53643ad194690b6e28c5ed2927e09a1e959c494b90db401681f67bf1e23fe9ef4c903f666ef39332a91a25c63efe9bc518e9aff61842007dda72dcc0264aa47543c0a8b1f0d25749ddfbed487282241140d4c64def1831c4d75ca975fdb03258ddd013445e08bfb479a516b011fe3a12e4bfca439407c0022889e46914cd41a4d92a25eaa57a55bc7337e5fbbd11584dca34adb5643105c8171e53cf04b1412c3107e72330ebf1b52f524b4e72570cfdc0ab179991f3782d05091ea57b1a233048bf062e88939cfeefb61e8beaa90395faf61c4d974b23723a4a5cd39d70f92620f8f4f27bc99ca67bed7fb6e594913991ca3025480ad791bc94a0def36fca491a206440ec31e32bb85850c3606c875708309be63c2b4f5c477521aa08e1d059cedaafe4fbef5523b79f88b57d0c81bbdd09202095f10f13e2609e833ff41b862b2214c22e8f2b04a363b38d26bf95c07b184b9f909ad3a92122e158d3566d2204b22d4f2f3ce11a65544ccecb01a4a5ef62bc969fddcb648224a5c7bd94f8da9a7d4df393d880f537a377888874c19dad357a0564d303a5c1485c1451ea55d68779dc0c11c7c38025660684ba3f70cbbab00d15b34c0f2342207ad548eacb32ebad95292e85211a8669b586d05b0d0b9f278a35ea4d78e97fd5dafca6b72d8e1fbf3e704a60a8ec60befe2e3e4d3d37f9d33a0feb88add59f0171ddeba0b79a52feb9a1f4a7a6ee7c6927bd10968fba788a807409346a0fccd4f7daac3c8591fc689aed881829d479e8d360cdb5819d5eac718a6f860f2d9ef6a0d36ef6e10efbb37819bb7b03ab7649173447b2cd47f3433a2422b1611dff91cee0b10c6d060d4e84a9e3f4dc194514cb67f1e3985be05c845fc92b41955d0f61aeba6268789998bbf341a8b37af48f07b13a676a11d27330529cabcd52365842be559857cbc2a63a4ea1c77fa8619040e79705c5b51f473e13b73fc09c28598e070dbbb63ce884c2843ec365d4c5bebbf815ee3314dde0bab6b0a71a398e2d9ee8ba2f832863fae7eb0c18adcdd17f1dee0df29a8409acabf516c8e6dfea5a264c1c6657f774c86a14cf96eecac18a41b1650a9e652c6c9264b03aa2fd30e333a9f24cd6b0313358e3c00943a1de63ca970b7da2cb8a0fd1109cefbf12176f5dfb59457480428b194e88449bffd8b8d87d05d30f9ffe9ac3a7442b0df3418acf9165b14242489a54b6b47ea543fed5de74a00f61ab2af553b60d8d21c76c42052c72e4841bd94cf88185c39287c04d05f6336ae581cf7528a59b2874795caca79f5600ac64ad5820a91c711ae5a1c3762028242c5c8a9aae89177ec4db5785cd07402d45805a2e2e970059e4e6483074df1bcc01f57470fb66f45ab475ebb5343b727168e355a6c25d42384e39802d7b4a8c54ac94d82de12f8de13630ec8c19f008f98c505dbbfb21b363472e23d0147d1ac555f0981e2bfd07c62d097acf930094dcf239a40699421b207ac2575b7edf9b1d772ab066362820c182c2c5097a47d1dd25ca9e0dd9c3ae94e9a8f0dece74cdeeec3a17803d5e11f037820ea20364234079286a7c291f3424292b0eec3e956513cc6b078a76a3b8ab42c5fb5efdcea1d438f7ae08507275b48f9588a15be763ad094885269efa7330f6fc9d4746997c98d9f5feeb6dff2734d75afc6a11196b35bb9fd0c0af428cacef0df2c5ad4e5fb4559f0f93af2fafad6fb77f453238f409ec71a912350d7b62952e4858927f620d31569242615345265ff1cbbd7fdfaff35a45732628da663bfff3d3af3d7b537337754554458a2d1af0e16aa8ad9436096f42e243109cad32fac1adc58d714cd3d0d8483c783006991f3da263ef5ae1ff2ea06584e45849d64a07170675c29f0b2abcf1eedbb63b6f5d9dba600996c7d5edce9ac69448d05c0704fb9f84e831b60c376b8a5d33ea22030e2dd3dd421d8e0a810a77c085a3861fcba214a8baf592d624d673fb34f906581d923d80b06186db8ce5fbef2bb750166f7556adfe93d4951a825d55b0bf92c9f25776df784f6aec808ae221cc98d05ce988fe6a13ff96083dba15500e149409b54345274e3633fa8f6685d6fed40c20a5c5705f8b37099a5949846ca15def5a6a427eb4eec72747f116366adcb9b74d3de0b125bdee23ca98ee6312f41fa3d9bba43a8d343552c969c41f766ab4341a42ec4cd6f4d1d4c4b1f16979e5389fea36a150580418d95520506fe0cb1a1d861e09d21c57d88c46e10a3c5ad1aedc8f2743f5c06f10d6da9b2bb3ec783c6f5788ce9400795022cdcec197f9dd3ee4cd26531e7f057b6d9418a0c52ecdb35a24a2a079b3d396017feca8b31aa55e3d5ef79c9ea9ccc7e3d0b47f28f273276666fa1763b3a452672fedc94557d984c3353344a8bc9fc833dee685e33d63540d0801d8068cf66cc48ddcb0d42cec881eae36fc2614f96ad67fceb5c98ec33fbade0e3049178d503c13c2d5d71f32f4582d1cb0f47a2ace578b903796768a906998bed2995798251d7eb92faacc19255bf12c0024a94971c185841113faa288beb7e58d4a98289630fb3d230f936eb1b9d9c7b94b5ac9d3a211c0b454a26e29bdffb522548a65e8dde3730918fdf0575245e71ba013ce08f6e698342a61a81b1355d2483e97c06462cae1cdc7787f4", - "bcee4396a08dac9c14981f2a8f4614a31b019c83782d5d8370acf9db467d9d95e8efbe44274fefde5860c2333cf81593a2ada9f5bb6c2362ba97fd7c3e5bc836c327c66b57c0f023efc0c0ff6feae0e625df2f4e21057060170c844c86412700d7d337b1f7835a0dafee5206cbd76104c5a36623c7783213f8dd457b5e69a86b74030a27b3c30074242b1d97e65a233885a681ec5a8532bce9dca1998dc32c6b40dd997b99a6ed6288e0b9b09447e356bc5345b2133571e65d47db2c736a391970879103d4137cab6c0724b8e67064167cd5521f32135fb6ca43c1e118adcded8227c9dbfdc18cdce154108eba5d8c60e5362e8fffc5c9ae6ac2572188617e4ce0f432e2476c74a4227af64b58e0ebafaf0b1ce01723ecd36a2a4167b7991e28b6a9e81992fcaf7b4b906d0361add02104db83914f28baea26b50561faa46293ba5247e8263ac0347509c36405747866d2fa2beef44f366108f6a4047e282a477c28654511075ddfaad9b9844e18e67320a831e647d923b2720d65ddd9ece165c222231d3c3e7f0001d15e3c690e9831ceb369a8edf183133814bfd20dd25d50973bda58ad03c4cbda8008556fc653ef401ff76ee858c1f79a0b09b4232768e72dd06e42078923d5647cb310bb644feb24d6b7e9d1167c3676cd96f79965a066aca314089db60bdc40c2be4b69c569ec76b3bb74a43fe731bc869c9222ab5404304a513d4f7d2ec5af278f7c3d664fcde579bba7bd472bdc00a1eb4c46ff69fb7e45e5712919e8656a8887afa28cadd66461fc57f53d574c92105818a89f210d7e8aee6de2e78228b2cb03b850a6e77627f70f51bb919bddf61837a978dd4cec2db138c657214ac07b67134bd53b071e2bffa3608a0b0bac88b0ddcfc1ba4dea17191c9ad76ab8de72118893256a7e13e15a3bf98bb5757a78c58328cc4b380f3786f22c6be81884d213ec3cc2784583a47a4003a59ebea08bd06e290a892c937448e664dac672942b068b839593c442f6e1d22875e01859cd24c17d108696a3196ea4794ddfdf25721d3dd3e754d1ea884e5086479819452991403a39014297fcc734e56f8daae4d49d5c47016fc3ead550783df895542229ff3b034b5b722ae2a2b04ba70e42c174e9ddb89ffa60024aa16f297ac9383b2ccad53de4bbe4ea2fa3fe3d059d16b4b4fe9959ba3c4e58922e7fa2673f50be5b636ee7c79b445471ddf5b851ec3ac505980bb184c8fe44c7776ae9aab4e66ce31fe1bc00efced390a82f96b4866e31ba3ff832a25b1e1d00ec44bf525ae523b7102ba60c1d3a2e2bed004524afc90a064b325a258eb36315b1496c748f5407e922914787acb8b47bdc495e521518e0637eac4b1b4fe1adede145181ec7ef038d48c473d6f296b349d7cf874d329c71f272883eb7e77ff303957e159fd417d5055d82687448950dd149e1074a1785518ebaf7ac167e07f1f559893a20d133b59aa294efebdae1e19a30ec9a3e257203eb9a854096395825ef4d1e4ecf1f8daeadfa049ea6c435c50d67fd21c6f6b11a8be46502f0dda1715f5349df5330454316498660b7996432e679c73f1af33e529ac669496bde538890cc093122842e3e2e4bff937708dd4b1b1d3fc066a63824266461e4af9245032d690aac0ea5636c29606473820ee57b112e2bd68c0ce1936b7e76a7873cad678b26b560d7bb10a7dcad3f69bbf226faf2f572c105741a121fa1c55ff30b2d0b7339ed9aa4c9a3671e6e4b572800afcbc8764b16f0a61c4c1ff24c3b64992cd84f39d1a4d5532a7dbd9f7bc847258a33c509a945e53236cbc46b61fc6fad662c523eef0c1eaa4bc0a49610c8d09659e7bdfa858d2494dc3da0a54fcce229951d366fd17f4120f27ac77e5e6b777693641a853eacec09cc4dc08ff6ba22295acec61c5e6215eaf2a3a012461eaade8faa9cba630c5ce2bee6f1a4676d54b4a38b7b5cfb6c98106a4882ed88153a4f0bad3e0f3d04dc1ae5318e3b8f4ab1d122a548eed47f70edad1a164a9c5c3eb10fdecb24b0b68005b2e958980481834c4f673478d3f47d07836d3c1c513dd920042381f70f1a68671acee2fdd453a7552eba497af27127999a13a33104f0086390e01635d1a0b79d92dd43211c74047804e82d9ab26f97ee88e664871dab52a2a79443e39f06a6e8ac9d5e986252529b389d9ed0b2f55fb16ca65f6e90cc9a149065f499630f973996c1e2b6c53f2ab391b7d78cc6926b1684d066a3a74b86b3b633baaf3730acd28deaf18fb926e1ec9c1f8a2345103cc4cbec05345db57c5adcf062412f289607f5fa41194f69bc2f426a30c7a6f8d1027ee8dc96c9957e90fbd9b16475b82dfd8698195159bd7b4860004beb1fa85e6843eca1acbbb0b8c7ec0b865ed108e297a2d5f915304167e18d01e51497e6e3ea76ae99bcb849f7595fa74c2a6263e2bef65f1063bce05483980ed51eac5289307117f17e99d761337e9b1fb625a1b900e6179f3b02de57a0b5f52352298c8a2d2c816182ec169d2b9c0490097ad98e2edc99c6df683a4b5b6eb73ccee0aaf07e8cf8f2f632381ac407c5c578bc1c5a8d0915dc231b01b92dbd25c2bfd412995780582793736572f1e23ef690bfe6872c2572285cd737a4be91f4dcafef09232de77b315d73f5beb23d03625e031d2438081222b063c343f52565ae314ac47a4fe518b45d0c12f2ceabc5e05c20f607b97035afbe0e29249e47961d9cf9b385c065966b0c7ea91cfa9ed1b55a58b9aaa9de080ca05c6405fdf15bcef74177226eb225a47d532bcbc82a5ffed7fd86c2609b146d86f566d0b84f638d46d6eb696bfbbc62c4fc981a94c1d6ccb9f3f7ed7976ea7e8ff1d2a2d79986fb27f1401f25d5a83f64844fa9e839fc8855007b417b261d325b6e7cb124b27ede8ad18d2b6da8bfc4d4f50c3960d5a1c82e4557b16d05471602d2a31462e4bac9535c9a57389ae0613a674815c2ec10c19f529c9274896dfe49ab06889da517d482145ed8f57ba4b7c0434ce24090ef2459682a4f6342ecc382b4cd3409c3415bcb7f1bbaadfb7ec308eea8b6cb2912469b707c99a55c1754db0650616754735b85a41433a30b28e3946754f90caeb03c7579fc9982e6ec5501d6f23e0f2b6392acc435907d79ea11eb6955723a81c4f02bfc78e2eeb1d0408f8f06b4d2f6d20d90f7698c4e58bcfa993884424f8fcb602ef35d23737fb6aff220927e28c19043ae708fd9755256a8a1660d9c5827bab1b836a10aa23aea9c92fa3b25428b3791c5d25f3f1b63befd5480ac4192c966350edceea8938ecc608e0f063d16d427049ad62625f5177470e7a0d811e8d4273aea8f7377d51db07fc34d9f18497a0c2b5c0bc5e8778e06bf7460f0487eed54d661d74346eeada9090957159b86f8b68183e33d0c3fc134d87e068badd8789d4c7adb829fe08e4558bada5ef3f526afb2c7b6184244af0d07aa5cb525c519ed32298bb6241d900ead0532b0b1fc77a6577963e7a44627ed326741af254ab957ca0298a74323d2ee4f1bca70e20ff796491424e108e03c20f2eed7374c0aa2474a91f3ced6f46165c886a510734d606ceaa08822bfced69def33cea3662512fb42ecefee341d1b499b826ad882542374b032e907a7e6a4dddc4620a5d1002b5aee25711fd2dd6e9d4e90ee350f2889d6c1f4328e4b711fc919ef3c655311637b83b4eff39c157e0510807ec61714b843bc9eb22a0f4dac7e5cc07b8e9ed587b701d9aca2a239e76ac9a16338b74d50578956e06b1ac35ee3b822ca779922d89de7d915afd7d80831e8534b8f8a2eaed252fd862abc99aadde62d4520d9a7c3c3da86081fc36927de60e3479096a2b5025b9a789da01da969cfb0ab2f252c82db9e6663dce3888146b365080f649cf94f991312817147d8f0d1774d8d44ba4afd846060df2de1d1043659c3b94b1eff51fff84e5a81a0c635aedcf677285e0d722e3335449fd0f49a41264fb963ea5bba31dae469c789047812071d8853291fd8003cc31a8968ce7acb68a6e0172ba6ee0e9dedbebeb62143047336c5a91c77085afb01fc075938b306d7e36383ecdfda55b9b5dfdab53aa34000289c398f617a146c4a06404737600484d8d4ea960061ec2cb575dc485f65f275540d0ce7550da08417632b6f0f7d044f6f719ff839aa3e5c9db94d45225a1cf0bdb0c5bffa781572ad605ad37aa988240858c9493dee9f00ed281e93532d89aba5e9e59ec430cdd5edfdfc2ef65e094eeab71cc40b59c997943a0e0dbbc80f1e11834bf3b53153ba1c1f0ccf63b3c802439b2ef1430be6994300d9b2efe4b84e25bd3bf8a566d4851e7fff57cada544d722438e8980a31563ef0558fdd8db9bdd6f1a3e34f06104b680f63c1f80a08ec6ed74bca69bb1023fe63d24c7e7a14ce85db6e21173f2ddf14f233f3787a37e4b347e4d64907fc0a23c3da017c81c27df9fafd4695886d0ddec8c47982912eceef886ab5680a130bfacbf3c67bb4f0cc118274bdfed43bbc2ba56f048d6a390e48932469b30ac84fdfc2e812f32d00a85349bb22f2d8091e64282fca1b40811db756059de5d03861d6a22cfc6289097d23c26c5e3f000f9b34a0e1b28a1269d8673d09107b29ccaa1adc8939bdca312c69ae4a238f45410d8f1b27392d594ceea2a6b42899ee5c5857965b29bea1bc413da618899b1894f2adff3b3a7b05a626e50e42379f5d0e0a148ded33d815f59d1401b197a85656466eaf88ed30d1ad4a87985570291efbb3a2c6f22c0b111e65c843ca3c6179e94335f0f91d4696e1a31107948a042f55f264c32a35e719668483957c9c8e13fd01e5f751870a509f5f06ba41ad63cbd5f706f25b1e598f6c9709ee6bab627211bc38494962e930779ed4ea2a8471d309c4c4f0603238959cb13476b673489696c87ad9da5fef0d6467145a77ae0b1089c8626988278a85be3292680d9d7e4c6866f19b78595d611f15f9a5e37b3d145d5aff4a5b58a3286bd25a862904817afe8e9b9105584af15f54554ca5e7dceaa0fbd1111aae126d74f68bb6f0ce98094dc9a59a31d9526729efa171beda9ac5b7db9118aa94b9b5ad58dc20ae1c328e31269244d636139\nCiphertext = d248b9e47c303f735b0d29f6111a742d93509ae051466688d56b587104a74fab1b259da64475fc0d2c3e28d87ca4edfeaa5715c23dc0e5281eb0c0c14e22182bb02f9f7d3c24555cd6a3ff766c774e67730a920db5f85d47dc23bbbee460f0922cd7ddba81ccbe727b4b489e79a19db2d012dad2a732273dafabc0fbded3c47dbe5b6b585570c39eb62850dc47f4aa0c29bf5fadf334041fdd4658fa6cc29a81192a53dcf47c03ddca9d03b33b06e5b3808be77925b7e7d8cf51fa939e023161d969f92430917d73f3aa10b83d5b7402410280561a27c376ce0b5151a51be2ef4eb9057eed25a0715436233615dcad1559fdbd81042544441857cdf46d72f5f50ee552cfd3bf166c530e57fd97f34e2e71bff8a90b30b4c4cc3e843b0f06e4eb2ff82675e428f5303aa9141dbeb615cf6aca5540fd7cb756fe5f9b08a4abdc6eb90b2eaef51c21eb9ae79a0e44b0755b3ed48f5e6e57f3148ce02501528dd3dd2b0bbec2650710a183e38510990002ce6498dc5ce7bf33d699dd18b66c0f8031d958b11d678674c355a635f4b5e8d863785f5dc2f99eba9ce74595493c017697344b651dcc2a0b1d5386b73abd8bb2dc77a2d92173d3688d0d704da9e44a6385af9fb3a81db68822b1eac9ab284f0155c20", - "f6bc34af85d8518d0dfd32fdaece1379abca339a00e1326b624b3e4050be5db8dced5e6c4b88b82b6ee2a48c373d236ea3565ecc072e953ffe01b624c6ecbf534678aad9c3f8a07d7dd7232134b6b397d0c96ab5f795f9e3af65b96e7a765283d8081dab9f953113abe06e8d150bf9a8416d8932fac17b032dc346be43736dbf066ed239328803510f6f62bc8abc92f6df9a82c02cbf85de91739bc8d7805d392341be99798079419540dc952fa0d3ceca4b806ab1db3b717f0d720038343465a8bc0da8e8964e58634e8a2d6c99230af2ac7c89acd3f86a22075dc40818028f3c632b36a39c0e064e3ca2a078c617a3e73aaea56ef11114f9efaac90a3ec8f8d9b18921a80d74b09ada83efee127f41179dc6c19c7965f3e7f43e22f636534b123e9246172f9920f253d2a2652a5e8c337ff93b2d479bef5e96e972a9b9cd8af057c750bd711010d59ce065ad50fdd487b5dde616301d0ae6373b6f9efae99d8972f242dd7a6bc61caee70201869be202fd384a992478dfc133b84171f013244c5d17585934aed3b43b818926246227d255bf832ff481f5f8d074ab159a11d6d17ed0ac50f727b870db966e0373bd3b1eecbf9ed66aa66caf33ac57cffe4ac6df3cf7b0e54ac54be4f3d50f61b33557c2990c908a710c85000ef6fa62716960daf918ae3d81ee60b3813e65673bd911ce468510bd230b9c2d215afe86ec12e49e0ae87e4235baf3df237188f5e0af2e61c22a4bf77190dd5dc804b4cc330b360c3dc093ef208c37d299ea0cd2ba906084011e16ac5f4fc9646538d5b538a99546d34a4599c8529c1524fc4b394d6a9cd762855905233ed92e72c8b538372ffe2f0df7085eb074616c7e695d7de40779e384d5fdb49fe02385424ea991dc05c6ae813f76c673eb45d6105bcdcfdbf04dcdd20caa6e30efcf3537bcf72947e1ac37d1e8c600ba9238569a4b3afa590d61acceb2572da85885146a142c8f8c60afe4d53ee4d61f33c47e5a99da9a346bcfbd013754ef39a4d7f16c4c5fbfa53d7f180c16e2b64f97dcfd65349939b5fc167c7a78926f638f1893fe9a81e897beea3258a4175d14f41dc123ddd846e45a87f35154db8a5ac27c7a0fc95d3b3113cfa9e7c828f83a1f0d91ab7789c33be5f55ecbb8eb0c81bcc0fccc880011b21000e2f10773388b198ce79c5d694472d3ef6b2e55c342b29c70e4f33fe59e2e0bd3f9ef617733dd3329a0e426338d9c007bcdd382522cb96e59b223825a39b01b52809f5e8518f64b81c99022d8215b5c435d87cc1a57bd440b31a19b197b277b2072968595ccd64c135ae1b218046e27a7f2685d013ce3173efd07586dc72a28ac4792e804d44f9efd785ef005213df928560a20daa4c24ab07f081479270a0dcee3c26331c48a164e4b9d79a7c30c77ab06b00e9b72c190d35fb873bc095d5e6231a89b52a0737a99532079bcc72ee221b48f0d0d9ba9105f981beb4225f6efc1230d6da10fd2b58a65112a98e4bbbe1accd6e8589eb6d9c771bb911cccf42aa6cbc68d1976f0da7eff1e70277e8c5f83734ec1efb2b00708fef08e986bd6519a0fa4b5772e585ac8e37fd2a2af07aa382579498b3b75863fe792461492b8e71c4a1a2f4421705696a96601317cfff1632784b5d75fc2036ed3fa650354620781b9fcfd53f1927223fa045edf4abe7b2144512f3e3aee99f7ac3e46028bc2427aeb18e9cb40db57b696ea884658abc9b7bae0d8117f93074a3ef903528f8b55c7687cf9f0119a1f246cc9e993219c6384359e7e5e639bb294b264048060224ae168d7b9f1f795c07eaafcddb10b61ac2be3ab3e1fddf75c1f47559f38d24f0c773d0e8bc5fa85d7d33e3aa8d0f15583b8c1e7aab6f5d0e085b7175678bf11cfee8eb069b78220377819e3f4d28eb833d3d21efff543d5c6357fffb4a8fdd6ce399fca42e2d71c53c50f6b20bcbaa1650b57ff483837c39a37d5e978393c332b43021508b8ef27773164d69d0af3c0dfdc125cf30a7c49a7d8e5320d68a35e80cdfd62a0b7ce6a412f08c8062e35265fad5d1f226d590e9b068d09e48772711d7dbd786a38c0325b3d5665c2ff45ad0a20c174dc5739896ac727b34f11c7af299d36d30c69bbdc35770138cf891cfdd8123489fdef2dfaffa9c2548ebd60b0f0bcedff44691979b4e92b364753120364dc2e3b895095da828e8659575a85cca587ba05ca625480f977a6fe10181ab6ce005defbcd8894f8c71811909cd6b56eb7ffe327f46793a9e98bd7fe8951400276bb9c7607f8ba1e633034b73d7f0d040197c3f346394eba68c8accccefe05f59cb7ea9ab1ae2e172d8f466ee21c6531cec2c9dfeebc477a6d98195c28bccc1d5e23ae50e3a1ddd7de189e36ffe0e387df7be43427b194b16e18b42eacd517bba78edc9f56a2c7e89e6f13513718869da7c8c529bc337217a69e14e35cf97ff7db2c23700347f0a33ad25a299fc52b35f63949735ad864aa127053797541864b07168f89ffb7ba5c9a8bfbcb4248383a95f45461a7aee9c658c5679205f47144ba4a06175e746037b8cb6556f06405e0d537d0f2bcd898dd5fb987d96dbce33001a50abff5b9cb0161dbfe30f5df5a161ddd8a750b0cb33898c110415881fc81239f2e25440bca41a5bc46fbd3787e6c8fe8a463415cd9a82be368a02566da740dca8e40e686e1213d9c15de2d3556a1e1180b298ba3074b4ab93e469dd9a39ac0c8a173b04a5ad913e72e4d7b5ff520f108e1a1747c11b6b2fcfaa89b3ef7e669f8ad9620364b4f4f0f9ab274e76bdd631df033357a24723653e427324d907a9eceb3c375c43ee36cdeb046a6374be19ab04922da93d4dc07c5914df06fee97dd813f5fd501ca75e3c5ad53574837f2e51ba6a257134e8ee0f4127c59840ba8b1bb13592dcbe47aea50e453c7837e91bb12ad1c74fd0f149479bc0334c511a822145690a3a408caa32671ed05c2dd219ea360c67727c1fe6a6cd842301761e94bedc73f93de7091b8b6d2783a788313b2fa12595904bf5d1167a5ddc4ee151b1522de60b7293b72a62c4d08b396ed682b6a6262a212ddc8c70dbec1a972cedc09f593e21d843279561884f9759a593da7b17a147db7559f19d5d6f43ea98012872f974306037dc0d344c55403b35a5903f766359341bee5bccb696fc0fd1c7aa8803e4c2f9e6e23d386d3a202027c5792e355592efab9330af330392a7c91e3cacc4e645359edafd78b77829374cd4b644817322b7650696fa763a0cc7143f9ec7e2f6ab3c9ec2443b0c0b0a31e9eeafb7bb8c375232357f08256959a10a6d4bc98d6cd9314a2ce7feaa8c0eb1eeb15047f715d6ae9ebd64238d648ed6bc50617a360d8ff9a01aa0ce0e29338d34bb9612751445372ac6d74837c7d2d67729760216ee33476cce1a154086ec31d986cc5a14e86561c6929554fb280646164bb03e8e52588a1b947960a77d61c2d2499212a742e1a5b78805b5b64fed141d3c4834301b8a8bef31ce65edb539fd9469b590a6980d0d1bd29e34a09f87438059a09b1ea234d1bb29882e67599fc1e417db9d86332077cfb05fe440ad1243e26a67a0ea30e63cdee8850a543d76e810140547412fb1400ac87a10e3bc77d3918750a5cc3e7a0efbd736c7ed4139cd5855ddba47143362bf40b91fcbf27222017c1552360466483e67ed125745724cc713c713dcf7ef6ea3081d65d8d78b903382717848bee7410431e1040ec92373f75a1bf229816f55dcfffb6e6da33ed8e1e8b05f9348cdcd6938f053eb9f93e0de639e922627bf61a6688f9649bb9cdfce6236a176db8b9b53ce4b5f9eb9c0680c92128bd327aa7f04a745025faaf117a18d5664027ab0e3f5898b834e1a75cd4b4087637733416f8bac1ccd67cb4457005945676d03f76fd0453fdb9968643fec98d28da7c8cd7070a803b14a2459f073ea075fd023a896d3306fdabc54416e95907103cd2fb642e301c71cc48e8eabedaae356582761a14e0b3b0ef1de06002c2acf594c85820ae3a094e5b4680566b592221543c1dc5192d6b208e86b5aca91d4e3454564eedb3b8208169ce97e1632b864f1d9d4c4c4c0fd4bcc5206e8f6d64c7cdf212d718cb5b7c7ee21593ada3f33f5952e12bba4f46cb99044978fe75349c6ca735db35891351d7e5f02a93354bc45a9ec756453f053cb87430b3e9211807f81ad99b6fceb8ef1b2d655910e1f5fd22f2ee90e42abab230f8f39a8345eed6ad294a0d32416a253f829093ecae209bc1dbfadae04a373080f9ea8394a28ddfe1134309bb53ae571d2019ff2bd4be94f8176d90987fcebad323f0b2921b85b2610852973f383a2ff4a5fa82a77b13cfd50a33f29164a9ff409422cc4cbd772132856cbd08470b220ace957a6b8e02c8003d750539a38a8df19a5b662907b72e3098d77c2fc3ece0693b47ff19ce911a93b6adce75653d48ace6af10b8f1141437f9206658707b16794e349db3f1a02606ea167d0213ce3644f64ced64de3799b1729210fc31ba1811b0c226306f2466b230ae35e6d8fa11c8f932e27da8cb1bd311919bf9178ef08bb7a2b4ca2d2e6e9585ee9f916991cfcd4862f5de9fbbc63bee6edbdcfcec9173a252eb59fc6d6e58258ca8b2a4475acfc1e09a0c9566d23d92e9ada97de51895bfb0867c42025c8d089c65bba67f4dd84d7c5155a930329345cdf3b1d6e910e730df273e183190beb900344bbce8c3bdb13a7e4ecbe967a61d47921aa55bac2bbb24e3e03d386ddbfafb3b32235b5ed922ed6ac2c89ded1316b69079b826507d708a6cca14ce2244a67be90fb91ddcb0c97432703729bceb432bc856f5eb9d2f169800a04283b080f0e053670a21468df9414fda9f4153eaf1669a19ede7925f832280800f0063ceee34b9d3b0f8da2012525fa7927e76bda71954714d5f51405b920391eca2ad71160acef4091878b907974573b4cf1b377baca0340ab0e4ec546fcaa6130603ad633c3ef980e88d8f44ec5de743cdc6cd9e0e4cbdb97a5c076be9ada8f26bc54d711facec16a2401292cc167bb98cdd320ec9321414bd97498f6d9b54dbb45ffe4b3e3f88260657ee23e19de48a93595c8e3a289a02d76a27ceead05d591633464709aca117c26aa49b64667f2a3b6371984f813d7098fae7a6ba1841775b52314a06c80b4c994ef8100e233ab3115ba2c39b97f2d5082a145720ad0b12b8a7cb275ba848b3fae14fc0c82bf0353195c056b302e508982f73a8519cca722892482b9d9e6a58bfb4d862fa393eabe6aedeae1be5ed772ea3c94a0df1d9684a131c35246c68b32e46aaf89f3649e58b2e99bd6bb3923d3ab43cbf73b6b3d19fe3b62bef178f46c79ba85e23ee4b25bc561e8fa97f51605bc0b210b02aa28242e81dae9489076d259f17d25b93b0e8a2010584d907314e3bd55482f0fa43d37ae9535629d28d6f837360bb35ec869d2a959789dc49b9c8c515942a1e03650566b736551a5180a60279bdb0ff9c387beebeb9e59ed930b3746464a010a6f7ef1de3c7d76fc6899b1e5ed98213813ffb333d969ad72fd8537ef4e12ca7b78d35c24f44ac82da4a7116492ca2efd86ee6a4474014e72a5cfeee7f729b77cfdd1a5d10a03f3cf28f1d314fca36d31ef2ecb3cfccecbcdfd22367b0a0e04435654286ae3d4fee13f56bb7cdab40b4e1dd01f9ef857f94a67c1e237e24819949935ff3bd73b0461ee9020fd0a2db2cc6312ace97e4a8a33c295271453a12822db8d1438f22ed0d466150990dcb39ed042424eef7a12", - "10c83224c856923e3251484a81a15cddb4d7ada8bb7968dcc8f85e39ca99ece8ce2ed7753fcee6900cc9b7b5691f2d67ef9be13f70d195bbd0047908025df01b4f4d581fd59239836578627d9d585ebe9b053d807e9d3ba25405029a148938a746636decdade02b1afb5ccbf2f0e14a27c98a1e130d9208bbf7da4bb4e572927eb348568921d4a3309a2c24f367c935c2a8e1524c3024ff350ac7da8d2849586817bc9d46a08a21aef035a6151e608ed93b1556a484e455819f9ac2fb155020738962e7255a82a0854b31fe20cdd351c10a33eb693c9be1a51a932e04d0364ced41ee1bf800d0c12ab5eb37fe52563666e52827720e856d4f24eb06e0aba446910aabbe36513f2274362fedba4c19398433029495284ccb499bb559a9cdbc94a0d1b733136969a743945a04e1d2d4e77fed21550af35f22651c7de802eab7a3942d7ec55a3a5002bde8d5cccc1d4ac4bb7f4926615fcece543fe5d9092d2c4f50d94fd9868775a072f4a5bcf2e5fd10795f7f172a3341ce33505ba68e7ebedc9c1e9165864244ed31bbe5c308dceff858cc42010ad8c281a24689cf2dee8a549b1abab9981d70a912174944b403ce664d8608b2f723150f5c12164e4caf28676e7a25c3928ca2a4dbe96355ef8f282e57888d40715df07bd8b5895549ad957e758abf868def1c1f5e260d26498616e2ac962bcaa33b879874569f198a91ce4e50fc50da77fea1df9f9ea900c834dcdd462d338efcf8e612aedebf254fac596507d175d30a90543627cfcef6852c7cda8b430e255c4d6d417de31eb5dba123e3ce9e2269867d9a94fdcd8ccac40a9451953085109f5ae0c3e04daadb4a2a47b0e176917660eb3c9f1aae0ec6b00635fa387e056623947c0621f0a12e86fac1881ed1dc1b9f523388d6b6596a152b3e732c561972879dcd3f0232ef0773a4fb195a90c3186c4688ea58967ce7f18386b80bd38e90cfd4cb899337ab27cba8db6523e979b4c449645bb2f320ccd28578bc7ec38f47225273fa61a2e5df97c4d76c556fbe2b0fd30e615f5fc82c3de7194caed9f5946c151c22b7a0c48f4a7cf78aa153414f2913c5eb95e3dbcea7ca544272cd13a1c52fa87759aeb430aab144fab418c835344605df3a044825965ca15de6ba0e59b2080f5844b2d110d71587e19acf14264cec2de5b8c77d18893215d1c1da0a940e7c2ee429a99e2633c216aecb7675a2314a09044951ca5a8eac798f8878fb5ea65f4ddccac53ee0c786e597169079fb6e8ceb37a71580b0904a97450909ca454a690821e249aebb75449e582fe1b30f1fa9f6464bdef654daa5ede6d4f223f4589ea25a25f4672cfbe974d51008bce296628556f55d26646e40b59f40e3149273760b40806ace3b5171e0b79865c6adb53513da2f24c4115de243150cec76107b48ca8da19117f00b5870e67eb8357e43c1b7b593c9875795d46ede26a109e05406b69fda988947e49ab195f22454c3c743c2ec51b91370b4df8d38653b353e51bb83215d122bcfa591009c007bbb6124bc590fed3f9c5699180b3b1424ad02f7c90a149b77d22dea5c996aba675c2a1a20e206d9c25d9446247d495a26486c0d0bfb09d0b5a1a177a09fa749dc36cee73af0116a6b779c2b827512a04ff0f60b483edbcdb33d2a18339463c498ae67ffa9da0aa3f3beb6bc99212f9e6961afde89045520b1f3f2e2761666a333d76030f443f53322f099035584a60978ef8b49f46d7d4d8c5c758ea52a04b59c1a3a1c2f9df3f3b6f5c45cf4b3547043b18c1d615a2c965c3918d090cc72946e8fd0b938e60e03464f4bc71fb719a1d173b0931930e58bf7f6d4403971d36b40f83be6b57244a7029e1d41dc908764d57a5442557218b509faeda4e9fcf31debbc54ae671ef636871233f29e0013c0e33933543f4b59df1978ec89b109c3977b0cf938b7f6166d6c93be5e87684a703c8b7b5fe1a8bfe153a179b55575ff05e599b39e32ed10d958699a1ffe07136081f0719b18c69dc74f66f211103e9c544f3c81a88ba9f66a9bc7017d9ca9e2cd97634052694a598476b99daf1cdfb6122869375ca5873d32d5c1e07d9b5b380b4f09dbe04478cfb1a13853eafacfed70c8abcd444ed095f78d07c0e8b4093be95c3aa24b2e5b6bfe3a06e9d2d9fedfcfeac4cea2490627e6da6a5cca383351952f654ce2b0ad359c0f7f4ad3f8d1d4a030a947d4a2e417bb79102729115cc8b6558c3362b1d805fb48ce4858deff97677e60375ed13e150a12ee7dcc8ccc64d9710c7f516555c1f7a1a08f0d7c6fd21f864fcf28c8f748c40494e01fc32006f977a5100577f86a484d11b82c90cfe6b4d6b1902fef486cc6f3e033904e150e67283e49a5382961dabd244412ca9657b48796e476a82443167e277d5a65c0c563a6abca77d316e5d3ab639a1ecfb1110af2d29f146508bd9874486dbb56328d6f59479e2766692821660462aa60b6bc8a710707ceeb0ea6429e5113e03c9f41ce0d69c7589deb547527673e8a9f9a9a74e9e4bbcabf2e306b35504c1da99730ae86e94cd047b2e6ea5e97e63a492430d37ec446434fb3b066adde08b17d7d903ad194a4a863d6cfe181a45c8c97b5062bf7c4e44d69c0d1a7e1f5029b805b7c21d1b5e56e697999a32557870ebaae8d87dcb5ca5eea2c5547a16b3f30ef9df8df821028c106f86e091050ff8b6ea4171e59dc2592d405073bea53f8ea62edf112dfbc7ca69809db8005783d63557d3d90d123a944be395c1dc3b5e1476dff188346327769fea65f3cf9363e88ed67335870ec8ef13eb9d9ff5317c4e24dfce9d11699e5f47b4233cc8f9d1b915e716a5730a5898ee65d30b1628b484a5e82eda95a590964a8d8bc89dd3c5cf6c4f9137b8c6ee9d6a692e0c0d1d858dd5b3c12de48badade4d01bff312c56ce3ddb34b0fdde3b0c2706fc292b9fac7e1a0dcd0b6534c968117f7de15eba84d2754e4bcb8093a5440297605598659f686075e2b1b464b6b3ec68abb13cde263b1c607545c45746338b9b207b5c381da690f653b35e363e1249551ad938b9fd7b0a944151cda07127bf9ba76958e926472f4aa1de8512ce834cfcae5414b226f23acdb1fe5cf685d2201b78167ad35fc1da282744c2a43cc49d49242f968f7e06de14455e7ef5adedc5b33184346018114e2d1fc7a5349e378da9b2af5b328c213888652aca9f1145363809eca7c1fd8e64a5cc3255418736e048a731f3053db77971f67014e6121a8e464833e5dbd02ea6caf385e43e9f378bfba657986bf852b32adb55e35a2675bfc8d70d43a902032a61f59f57dad2dd7d7963322136233200cb9a90c952074e9ba0fc0654f1b6fd6f7f0eb77c0fa6d8143213ce6e8b0c178f73e17a7c64839f9bebca2fc955ea8ae406a13b80a9045fa8d129fd859faa46fd27c48bde7b890f98ee938c0d78889f84181ae2f5711304fe554d4251bbc6437ced59d577a2a1f26da736193c3674adb13cef9f4cb4aa6585c4d6874b0309ecde300493b1642c595746f09e03977c8902f3a4a877db1153b248f295a0ca2f1e437d15fcab8fd77c5f967304efb5c4920b990674ae61b954af40be17a8559dc377c591b68067fdcaf2d27bd9a22041b981a84be3de50d5962b58f8c4a22fa05192c5ac99a0a9423284fe62a3a59f085136cec72cda2a53af106a2eb5bda28b6e02c299118cd91714c2e7d045346c78d9ed1b41c73231a21e42c298949f70122277f4134ed5c56639edbf3c3e717310e3d1f03dc5a94e64c4ce148bc5c6bde64eb80b17d5979892786a31225eb89bf9f5a582bcf65b83ff7aa361ccd9238d144f6a22a3f77dd8a01382df4ee90a2057dd310a6b0c4b81dfc92a2cc0c606d3be8b18fbe64ddfdf2004eeabea892be2f914edd1edd8e8829dc7704d71bbaaf08c41824dd0f4b34c9eedead9e10e53bfc6fc0bd37417de0c5c71cff0754d672f29c262d8e27b524427e12bc4e4705ab311d3bedcb1ddd09a3ca0c268c05c64951b7d724a9dafe4d249aaabda91d68633aaab845bf78f9a22d467c7e0c5fc70fc9a318b01d7492efea7fffd329d70692e76647ae665c62b280da0d62f870a52e4dc4cd92c9150c96aab16f8c23475e3152d4debb41b6756f000c3d8aceef18b49e295be7a71da1eeadf4eb96509d45d7cc42af4b7013d8bb445f577e8d4cff92770b8ba0e451f3e24c6d981efdb68c7f2dfafee40b8a425955796e369f0d4da3e998c1626ae0fa583334475f1fdde68ca211c3f2e9afb003f553191702e11f8b731c89ea26059ea4466f2bd0a1a5601025ca9417006bca5c9a57dfdba44c603ef9ad38922623b40feda036d84425c47fa42973e348a180a7570e1215044c375313ab08d6f521052dda415707ebb74d6c4774e039bb04cadc2799224bde1802e2ee2a018032e3a341700c0fa2aa28bf93cc479231efe7da0e9f68e572415348c08cf648117e9b6d1267fef6617f5927252c86cc087775db3e30180feb5ce7e1ac9c3761161e07a4853aa6d97e525aa88302954cf9390fde81f8e11d97a11c79e3bad261364c18890dd1f8fc71127edefe3571518a42be611a46a0426a33221aa25a0ae6514daaf96038cb59aaba898de49e3b215a4464e0af614e638c2d9b6e676ec427fc906bc516331a18121f306a5246d179e2d3d0f38ab8393f7ea5a2d24585e7cca649637b9983924a15483c167e8780f8dd7aa1154cbf731745a8d8d54a8c4f8d854371bb8172303f9ba3c8c7cfe8c378ee56bc35c6376aafe907d3294ee9a8786281b7deff78ff125761f1a31d0e8fffe04a52a7574eeb8679670ca3bfb740167a559488d4337819613d32752d8a89013622f6a8d70f3c64b84a4215f4b7bb282a2d17c36a326167e3270757b8f1d9a0137bfc5ec278e8ca35a69e49779cfc25b95a89cc18732b5b9d1986b18878c57e118506909207207ad0b4edf32fb2b35b6e70546f45d0849bd139ffff9d8ae547787e7b51403b54f110e2ac65468cd0910d80a4e321deafd46e9af19609bee1efa41b762b8ace989dd681503539e7d9948664cf7a73ffac9ce2a34b514253c4f21bbccd38057a6d68732930dcdfc9a32219b53339d100db0037a8bbd101e71f5054f3\nAAD = 7b3b9c07148fcd897f657ecfcc87e530191536b8e77f9309e8d7323888b3b21477f2ab7c885c105d9c29ac96aed23b366f9fde4177401b7038c6770c7bd2ee8b4335105cc0eab9e367f0cea90d6f1ae3fa76cd21ceb9f3500ce7fb4b2a3f9e90f900a231ec693aeced7afb6821391d1f5b1b957895777aa7a2b71d9571c00336f26d54d756392cdb74bfb67d5a621d517db20441f74d0940180baf613b09452f64224f8af7bbc864ab4a8434ff624d0c0646ee07132fd376506951899bde975df8c836ab4ed9cc084f1f6d500ad56345d2f250a0d6991b9e458c62b6023191f341c8659e8a38c878cfac12b032674503df9c9bb01c4340c709eb6dd7c74907d769a317f4dd7317843c47bdb4c5e1f07f2380d464b0c47269389cc8a43a09adba86f6aa8f44c8fe514e73b5fe8d344769c1aa20a4538ecfbf47562ca79fa497b0f02f103f75522db9ead50d56dbe86997d6085f1b5aa7a4cab9e51a1247ce4f724a14983b6bafd17369fac973c6be268e20d800de870928e100990ebb0d3bedfceda36c64be3a729b603bce677a49e8caf282c9159b6e3e1e775129bd30dc3f5c9849535d86a27474be03bb5749b4c0115e2614f8feaa7405cc69b1de479b3b57e551f876a9c8c57ab9879cc68bb2", - "ea110b2e77e59dd6a65eaa67cc4d4b2f4d6e646b2a298d3c80fb43969275d4414734e74726145dab06124c040656c39a94846e8fd58d326f4f9eafe5b95d85254765a21993f55070fcb9e85db5d42ab6b9464ce66de3f236dd2a0a26c4e5535dbdcd6eb350209a65aee785c6647ad4103d092a8ac932470880eb314f7c98cdff34fdf35ee2d36f09bd443b5defad7a5acb9df55965421fd043def6f4771e1bb27385b30ba22c0d8972aead6b654085a7dd3b60c4004a0dae22e25100e54e0badd0cadf909799329ddff699de8066dd6c3822d80c73c52d87e6fcbdb2dbbf852e37804b1256e23e76dbe43f30be4a577bc23c7941a3d708d1e1f579e9c6eebc219c74768168f6790a41f883790e08cd1e88ad09a544eb97b3d1d5af67eea666b9c027e5c7c976921189b955a9e605f6cc9c012c1c2e197c5b02504cb9ffbcb0f3ed778d540d5194fdf5d38dba6340c93da7c5501a082689616f337d8b59c2a92c25e777515726e1d7f6cc9552693cc7c30f1294b37f97d49814250d6c1e3eb335c5d214ef3641739d508b87106eaaf367902433a148ca962ec694409acb82d7749e1c88938ad382d0ca6e6cbe8255746832fe737c3e71dae8397f260c98d4a292a126ec21935c24096d2f91ae114194af659455d8a4206197495a28474dd2809debf5f550d77ffac2b0db521559910c352f23472d7aa9f4dbbdb158f40aa36912cbd918ae4c642e76d78d57ade1075c4fe1086ddee3d554353b4693bbcef1cfa87e49890838c36156af0edf384b0413d6d7aa\nTag = 51cbcf4a2fd82f221de1bfebf86a8c24\n\n# OFB tests from OpenSSL upstream.\n\n# OFB-AES128\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 3B3FD92EB72DAD20333449F8E83CFB4A\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 50FE67CC996D32B6DA0937E99BAFEC60\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 7789508D16918F03F53C52DAC54ED825\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = D9A4DADA0892239F6B8B3D7680E15674\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 9740051E9C5FECF64344F7A82260EDCC\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = A78819583F0308E7A6BF36B1386ABF23\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 304C6528F659C77866A510D9C1D6AE5E\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = A78819583F0308E7A6BF36B1386ABF23\nPlaintext =\nCiphertext =\n\n\n# OFB-AES192\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = CDC80D6FDDF18CAB34C25909C99A4174\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = A609B38DF3B1133DDDFF2718BA09565E\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = FCC28B8D4C63837C09E81700C1100401\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 52EF01DA52602FE0975F78AC84BF8A50\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 8D9A9AEAC0F6596F559C6D4DAF59A5F2\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = BD5286AC63AABD7EB067AC54B553F71D\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 6D9F200857CA6C3E9CAC524BD9ACC92A\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = BD5286AC63AABD7EB067AC54B553F71D\nPlaintext =\nCiphertext =\n\n\n# OFB-AES256\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = DC7E84BFDA79164B7ECD8486985D3860\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = B7BF3A5DF43989DD97F0FA97EBCE2F4A\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = E1C656305ED1A7A6563805746FE03EDC\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 71AB47A086E86EEDF39D1C5BBA97C408\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 41635BE625B48AFC1666DD42A09D96E7\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 0126141D67F37BE8538F5A8BE740E484\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 41635BE625B48AFC1666DD42A09D96E7\nPlaintext =\nCiphertext =\n\n\n# AES-192 CBC-mode test from upstream OpenSSL.\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 4F021DB243BC633D7178183A9FA071E8\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 4F021DB243BC633D7178183A9FA071E8\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = B4D9ADA9AD7DEDF4E5E738763F69145A\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = B4D9ADA9AD7DEDF4E5E738763F69145A\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 571B242012FB7AE07FA9BAAC3DF102E0\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 571B242012FB7AE07FA9BAAC3DF102E0\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 08B0E27988598881D920A9E64F5615CD\n\n\n# AES-192-ECB tests from FIPS-197\nCipher = AES-192-ECB\nKey = 000102030405060708090A0B0C0D0E0F1011121314151617\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = DDA97CA4864CDFE06EAF70A0EC0D7191\n\n\n# AES-192-ECB tests from NIST document SP800-38A\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = BD334F1D6E45F25FF712A214571FA5CC\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 974104846D0AD3AD7734ECB3ECEE4EEF\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = EF7AFD2270E2E60ADCE0BA2FACE6444E\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 9A4B41BA738D6C72FB16691603C18E0E\n\n# DES ECB tests\n\nCipher = DES-ECB\nKey = 0000000000000000\nPlaintext = 0000000000000000\nCiphertext = 8CA64DE9C1B123A7\n\nCipher = DES-ECB\nKey = FFFFFFFFFFFFFFFF\nPlaintext = FFFFFFFFFFFFFFFF\nCiphertext = 7359B2163E4EDC58\n\nCipher = DES-ECB\nKey = 3000000000000000\nPlaintext = 1000000000000001\nCiphertext = 958E6E627A05557B\n\nCipher = DES-ECB\nKey = 1111111111111111\nPlaintext = 1111111111111111\nCiphertext = F40379AB9E0EC533\n\nCipher = DES-ECB\nKey = 0123456789ABCDEF\nPlaintext = 1111111111111111\nCiphertext = 17668DFC7292532D\n\nCipher = DES-ECB\nKey = 1111111111111111\nPlaintext = 0123456789ABCDEF\nCiphertext = 8A5AE1F81AB8F2DD\n\nCipher = DES-ECB\nKey = FEDCBA9876543210\nPlaintext = 0123456789ABCDEF\nCiphertext = ED39D950FA74BCC4\n\nCipher = DES-ECB\nKey = FEDCBA9876543210\nPlaintext =\nCiphertext =\n", -}; -static const size_t kLen19 = 455619; +static const size_t kLen19 = 100853; static const char *kData19[] = { + "# RC4 tests (from rc4test)\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 0123456789abcdef\nCiphertext = 75b7878099e0c596\n\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 0000000000000000\nCiphertext = 7494c2e7104b0879\n\nCipher = RC4\nKey = 00000000000000000000000000000000\nPlaintext = 0000000000000000\nCiphertext = de188941a3375d3a\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext = 0000000000000000000000000000000000000000\nCiphertext = d6a141a7ec3c38dfbd615a1162e1c7ba36b67858\n\nCipher = RC4\nKey = 0123456789abcdef0123456789abcdef\nPlaintext = 123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678\nCiphertext = 66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext = 00000000000000000000\nCiphertext = d6a141a7ec3c38dfbd61\n\nCipher = RC4\nKey = ef012345ef012345ef012345ef012345\nPlaintext =\nCiphertext =\n\n\n# DES EDE3 ECB tests\nCipher = DES-EDE3\nKey = 2eaf97304cfaeb822c04a7b7bef328c7b82fef2ae81b06b5\nPlaintext = b3ed255d4f5e2d6d9a1aa2bc03489064d28fe1431eceee183b7231fad3273140\nCiphertext = 629d608789e51dff699343d061ec01d94c0681c7698ab617ea0145f37304c8e2\n\nCipher = DES-EDE3\nKey = 72f52e1ded0a88eac6c88d2901b27c2fd6e9f3f3387432ee\nPlaintext = 60de7b5667a1ad5995f178553d695d9b0fb537562876faa9b6cc50d05a1271ac\nCiphertext = 09875b215ed2499318c2d99c48209ca5f288830cc6edb9538190fa3ca31fa175\n\nCipher = DES-EDE3\nKey = 4cd30f1e14d485dbc05c69b65ebf44e556056a2261c9e714\nPlaintext = 7ae59441bbd665d8867273386fc72a8cd62cc5bc6bb7cbd57fc1f5dcdc73adfd\nCiphertext = 004d0daad970bfee944c8779927867b964dd0afaae7a830c2b8e7fdcaeac2158\n\nCipher = DES-EDE3\nKey = 7a07ac63adfaf1b26860ce39edfc402758bc4d1edda156ab\nPlaintext = ed4f18cf10bfcbd4354710df053d3e2b776860137349471b8dcf526b8eea8b22\nCiphertext = a1fc1014abda7e198ac8e096a368f65d9b59e1eddf5d97715015a2408dd8e799\n\nCipher = DES-EDE3\nKey = 37c443ab336fed59b0efae51ea7f5d07b7040868beefcd99\nPlaintext = a10a180cc94b75fc9d6556dfc0a816b71020dc3906f9d59d9dd4c839dfc1c1d3\nCiphertext = 0a874652b621618635138a7d4b33bb624f91a39ef1422b3e0490311ac6df3602\n\nCipher = DES-EDE3\nKey = 1ff1a7f4839d484e308d9b8c2c052b126def413d5fb8e0c5\nPlaintext = 4f28ef6683d36c80556ff240b247a3967aec23f859e3afb93aefad93b1e9964b\nCiphertext = 87a8f3fb4c51b3caf19c4ac51363d92025acc053e538c1502d347a618314a4bd\n\nCipher = DES-EDE3\nKey = 5642c4d1859a85b342e3f253fd8bd835e856c451e63673e5\nPlaintext = 687af9b298db752b47982f64ad9bff52a9ae487aa5e5c08f902035b0633225bf\nCiphertext = ca2ed48392ba5d70879ac8772180c3028ef946b6ac1df0348f206ce16bc449bd\n\nCipher = DES-EDE3\nKey = 30f9d27472f9deee309dbca76ba29ca174c39d0631084735\nPlaintext = 85db2c266902932c8e46d0207459b203f90955adcd7506b49bc82e2796de764f\nCiphertext = bbb5940b45add7c587cc9fcfc40674bac7e081baf71285891c65ed9573947a07\n\nCipher = DES-EDE3\nKey = ebc5a73005b77a812c3f4f61669ba859939852580fa61cbc\nPlaintext = 808d22c60b883a986dcb0860e8d92a75441cca0a2a4b06dd78dbcbec198b38d9\nCiphertext = 75d39d30862431ab07227e22b4c8218f1fbc2a3816daebc555c1b999c86d15c9\n\nCipher = DES-EDE3\nKey = 2e8eb05dd8a2b7a5a61a6b8a3830b12da2c4b1bea1e884d5\nPlaintext = cc7569d005afd1a365f5c5836c14475fc15091199902af4a78460d56c16f91ca\nCiphertext = 64db8af7a30363051a017cc92ed67ac6c0e2e1ffda0c94bbf0eeb803ba6b3d22\n\nCipher = DES-EDE3\nKey = 2e8eb05dd8a2b7a5a61a6b8a3830b12da2c4b1bea1e884d5\nPlaintext =\nCiphertext =\n\n\n# DES EDE3 CBC tests (from destest)\nCipher = DES-EDE3-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210\nIV = fedcba9876543210\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675\n\nCipher = DES-EDE3-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210\nIV = fedcba9876543210\nPlaintext =\nCiphertext =\n\n\n# DES EDE CBC tests\nCipher = DES-EDE-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 7948C0DA4FE91CD815DCA96DBC9B60A857EB954F4DEB08EB98722642AE69257B\n\nCipher = DES-EDE-CBC\nKey = 0123456789abcdeff1e0d3c2b5a49786\nIV = fedcba9876543210\nPlaintext =\nCiphertext =\n\n\n# DES EDE tests\nCipher = DES-EDE\nKey = 0123456789abcdeff1e0d3c2b5a49786\nPlaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000\nCiphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F\n\nCipher = DES-EDE\nKey = 0123456789abcdeff1e0d3c2b5a49786\nPlaintext =\nCiphertext =\n\n\n# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)\nCipher = AES-128-ECB\nKey = 000102030405060708090A0B0C0D0E0F\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = 69C4E0D86A7B0430D8CDB78070B4C55A\n\nCipher = AES-128-ECB\nKey = 000102030405060708090A0B0C0D0E0F\nPlaintext =\nCiphertext =\n\n\n# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)\nCipher = AES-256-ECB\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = 8EA2B7CA516745BFEAFC49904B496089\n\nCipher = AES-256-ECB\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nPlaintext =\nCiphertext =\n\n\n# AES tests from NIST document SP800-38A\n# For all ECB encrypts and decrypts, the transformed sequence is\n# AES-bits-ECB:key::plaintext:ciphertext:encdec\n# ECB-AES128.Encrypt and ECB-AES128.Decrypt\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 3AD77BB40D7A3660A89ECAF32466EF97\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = F5D3D58503B9699DE785895A96FDBAAF\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 43B1CD7F598ECE23881B00E3ED030688\n\nCipher = AES-128-ECB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 7B0C785E27E8AD3F8223207104725DD4\n\n\n# ECB-AES256.Encrypt and ECB-AES256.Decrypt\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = F3EED1BDB5D2A03C064B5A7E3DB181F8\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 591CCB10D410ED26DC5BA74A31362870\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = B6ED21B99CA6F4F9F153E7B1BEAFED1D\n\nCipher = AES-256-ECB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 23304B7A39F9F3FF067D8D8F9E24ECC7\n\n\n# For all CBC encrypts and decrypts, the transformed sequence is\n# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec\n# CBC-AES128.Encrypt and CBC-AES128.Decrypt\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 7649ABAC8119B246CEE98E9B12E9197D\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 7649ABAC8119B246CEE98E9B12E9197D\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 5086CB9B507219EE95DB113A917678B2\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 5086CB9B507219EE95DB113A917678B2\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 73BED6B8E3C1743B7116E69E22229516\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 73BED6B8E3C1743B7116E69E22229516\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 3FF1CAA1681FAC09120ECA307586E1A7\n\nCipher = AES-128-CBC\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 73BED6B8E3C1743B7116E69E22229516\nPlaintext =\nCiphertext =\n\n\n# CBC-AES256.Encrypt and CBC-AES256.Decrypt\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = F58C4C04D6E5F1BA779EABFB5F7BFBD6\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = F58C4C04D6E5F1BA779EABFB5F7BFBD6\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 9CFC4E967EDB", + "808D679F777BC6702C7D\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 9CFC4E967EDB808D679F777BC6702C7D\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 39F23369A9D9BACFA530E26304231461\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 39F23369A9D9BACFA530E26304231461\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = B2EB05E2C39BE9FCDA6C19078C6A9D1B\n\nCipher = AES-256-CBC\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 39F23369A9D9BACFA530E26304231461\nPlaintext =\nCiphertext =\n\n\n# AES Counter test vectors from RFC 3686\nCipher = AES-128-CTR\nKey = AE6852F8121067CC4BF7A5765577F39E\nIV = 00000030000000000000000000000001\nPlaintext = 53696E676C6520626C6F636B206D7367\nCiphertext = E4095D4FB7A7B3792D6175A3261311B8\n\nCipher = AES-128-CTR\nKey = 7E24067817FAE0D743D6CE1F32539163\nIV = 006CB6DBC0543B59DA48D90B00000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = 5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28\n\nCipher = AES-128-CTR\nKey = 7691BE035E5020A8AC6E618529F9A0DC\nIV = 00E0017B27777F3F4A1786F000000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223\nCiphertext = C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F\n\nCipher = AES-256-CTR\nKey = 776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104\nIV = 00000060DB5672C97AA8F0B200000001\nPlaintext = 53696E676C6520626C6F636B206D7367\nCiphertext = 145AD01DBF824EC7560863DC71E3E0C0\n\nCipher = AES-256-CTR\nKey = 776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104\nIV = 00000060DB5672C97AA8F0B200000001\nPlaintext =\nCiphertext =\n\nCipher = AES-256-CTR\nKey = F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884\nIV = 00FAAC24C1585EF15A43D87500000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C\n\nCipher = AES-256-CTR\nKey = FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D\nIV = 001CC5B751A51D70A1C1114800000001\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223\nCiphertext = EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8\n\nCipher = AES-256-CTR\nKey = FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D\nIV = 001CC5B751A51D70A1C1114800000001\nPlaintext =\nCiphertext =\n\n# Regression test for https://github.com/openssl/openssl/issues/1916.\nCipher = AES-128-CTR\nKey = 7E24067817FAE0D743D6CE1F32539163\nIV = 00000000000000007FFFFFFFFFFFFFFF\nPlaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\nCiphertext = A2D459477E6432BD74184B1B5370D2243CDC202BC43583B2A55D288CDBBD1E03\n\n\n# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD =\nTag = 58e2fccefa7e3061367f1d57a4e7455a\n\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78\nAAD =\nTag = ab6e47d42cec13bdf53a67b21257bddf\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985\nAAD =\nTag = 4d5c2af327cd64a62cf35abd2ba6fab4\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 5bc94fbc3221a5db94fae95ae7121a47\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbad\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 3612d2e79e3b0785561be14aaca2fccb\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 619cc5aefffe0bfa462af43c1699d050\n\nCipher = AES-128-GCM\nKey = feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 619cc5aefffe0bfa462af43c1699d051\nOperation = InvalidDecrypt\n\nCipher = AES-128-GCM\nKey = 3de7b368783bd7287f2b9b731814c876\nIV = 90dedcfff100eb1f1db9d935\nPlaintext = 8d766795cadc0961c0f448c62df3827eef3a8664599b3adbaab0cfd63875bceb8f992b4f7447dca10ddd716aa0bc4fe925e1aa3e3fd1d5c430c650fe3546d6b9a24d576a857c5f04e8c0a3b149df277aa19cfa64ee235891d3b8ec0e840d268b1e70dd8a4bf97628a0c7aea38aa21eeb8fb1a8437f2abfee05e0d2c30659e312ec03d30da51b7c19073a2341c17df806e27e796d581143d39e4de8d3f8d46aa6d6fc1a98d94fa69b92dab751d930cc12de21fb1a7468af09e3c12ff6c3db3967d10cf140bc46f17a16e24b010b6cba5ebf777341c52042596ee53008389c48d9690ab9f5625795c3e588f72f7a1670b2b25a9f4eee1c8845ac90f1bf47ae4ea4b607a50aca88ed304cbb700d02d5486139b0bc81ec042e574abf986972fa008b83ef22dbfe720c2f2f6355c87c975932cec545ebed657e5e7570c503e9aa7f0b87d0b2648e421ed1d34749637c95d1e931af8925236387e50454f0ba2e22ed05f90450fad46f4eb7ddb08656511dd065c0f852a7e42f618a961a6c6bec42226c6b6043580b009ec9837cf99844cb74794a82c269ff648e0bae9ae50256a0ad98ad9f5a35057b3004ac96f469f9ee966dadc16dc47616586cf242706df96bb2f7ee43d3bd1c65d2eac7b82ef242e77ab509afb9639e5f3995380e926305729ca762c487f4411ec2a9c688b8347e5287216dbb38c3fe2281a89fcb47ee2ee7ddf79bfa3ab61cd56a00981019bbcea8aa0444eb75958e5fa56ea0036d2de4950a7db886f4a318b433bd41e00905ab158171e0ef13172293bdf70064b9dc7b243bf9dc927589bf9e99468d1cb330639dbff1850cc51929b8971b0b2ede9d06bc5f6ba39d4551b587f09bf6f8206e8f1524f55714612581d6aa45d8fb83425f84a736576deeecafdcbfbb8670d14cd2ab2a7f8b7f374c07881b7bac2605fd5ff7ff7cf43e30cf49910961a9079c0343b8601be8c3e9fe38f49fdab0b7e1a8c1536cf84e4d80d26ae5ec37570839b5cda02929221898d611525c3a88fc444167ffc532b256cdd0a8f31ff08097d75b629fab99c9e1062d1d9962b211e15ec8709934029c4934e64db8d7a2f32e23dc541be306e9a57a3419115994cbc3a8f8d5ea2a6f45b9ea9ac0e51ed0c6680fa029f4552a6c8665aab00ab77928342e7284c321e9500ad4774ef1fed0f596d5aea371fe1793271aef38cde55547f34701a525526e83a72673385a85f44db511bc87ce1f831fc6ccf8204ca4f4a20eac09897aae93684f14ede21bcaf40a09c08012b92600d6a839ebdf8bdca7b34192c6c50bad8796b3be3c375dbae6217815d2c75cc878d39b4e842d4eaa5f5df2242cf230e44a240e18e47827f089b18bf880fd41a2516eac8e6ba3fc2db64a4bc28789860d7b18d9edeae8b3059f4d945b15d0ee27b1f74842dd1df117fe83a8fdade23a47c93902eedc4d33f2dbfcd1996e6dc1458409fde2302830e8d44c58c5ae67486b9950dd938f14c38bc4c9484fdc4ded93a0f90875773453fc14d428cd6e7beb0c705d61229d2b3df09632ebb30b325fefe2aebbf2a7aa8e4ad46277ca4b8b078818b63d04e7652057f6cbbab7c43ac355537e0d3918b4a73c00dbe6b30a27ee7a6fa213d3347ae478e8edc323404b8322b9c7b0173ed61c38ed25f3576", + "a675d527d22edd51d6dfa5767560d3a50a91226338e8c4e6436eedbcd3d2efe9dc1e686b15d2f57d553abcfda57dc316ca453a690f20148f0dfa20c1c4a58240aaf7195095fedfa56d839d0230d55ce9a8ca1b9d1acd6fe98d583148ba0f4a4e3413c76e6ec57ddb79428d3a90079f64d3321c791f60d501c3fd02c8403f0f5e6c6836bbc96430c1b48e83350c3a3cfd017f15bee3e4bb1295d821dc98b85ab3145555cce2c34a8142fe50f8db19918b514a165d12ff6301fb2296788760ac0b6d9e3a57770ad5111cde5d24b6321918cb0b0887a282b827a8749733171914b000e7d3c0edad1d42ca60da37f0698554bb2a1749f73b3120dbeaa32951f8217a781a200467d5b569d16f56fc9b7dff0ac524f03fee0617f4c692d94613b1e13b18075dc9f0d32811d4a8949a95f6b5fa46aeb83597adb409e68b2a0177c36dcc95dcb2e7dd4fb7337ff97c013364fe139e185014948fa698741d822044fa3f6978b16afd18138c845587c405ebf7a6cd1c28610ce67e992ed49e406658a0a202feed9709500d064b6f53eecfca57dd4b38363ce3aae9d59126d8ae7e140a373851188ae28c909181d0ac64770df70dd2475809350cb367825b59d521d5e457b4e36aea6dedd90a2266898b753b57fa359d43cd388e7d6c7ed90bc4c2af34ceafe88a3af6ac376fec35f1240f08af4f3eb30bc53dd68e5762e6d39e6b16f63003fbe0bee828d0d7adc58c41e857c2c44702215b202701fc696eae021af19c79e59c3e32627cd571f5db99b17f1772b5d746196befabb0b7446687827f3315b391d5dff069b1c39c00bb143218ef458e3b397e1c99640d57fc8db2e0083d3d22ed4111a8fc9e0e6f55fe6a56e946dbee43909bdd7d516fdf756ed8099ba80b1e17a5e279119345104379a36962ca9c8b2a53c414d79eb09fe79862ca749a9eabd9185ad1df57215945882f5894868a134bfc35c835e040e77ecf077d6a98a73ee022963d70b036be3fe5718280ae52c5d751211b22950c0597aaedd35af41f7dd5999e5f7ee34a37edcf97df54a46742b0252b196eaee454ff0c30685b15f8de087de208906be1d971f0fd89f7cdff2af0bdc96759d6889fba9ef092ad1c8deab0404562a7f3977d211c28dfd1573aebd5427a8773f03986101703fa19cd4ab96a381c76a747f63b63f7a9a3a08e251cdc593a024f63b443b76d17dd9e151809da3c582fbd334fa6dd0221b6d410c6a78ba95bb0154bb8999f619f2e084a6b9755ceee4ca3c7e0481a47776c8814f13054e627e37630d593bd09d5f10a049c66c9999f4b0b037e81ef70615d674c7c7975972994a053c069675fad3fae5ae3e779233b70254fb87f25d44c104afc3d5911b8b695173f9337130e39a02cf97356cb817f6cd23f55ef74dd06bd24ce5887a7001ef576262ffaa99f9bb5e3f55bda2aa0f199115909af48bb4d6b1a0a0847774515302cafebe75aad1f63362b1f38141e8721851c3ef1a247931b3b450581eb5d09027b9e3ba60ae9801d629b74991b7fd65520eac561d47115a85141d9a757bc75710bedff1630561ae05254ea541a7ff1846ed5e164834417556dd562c45543c88d8030bb56451fd5b3cbf10fb0164c5288789d2aac7e7a836e79bc3dd401a8e3e05aa6714ffb2dfddb3037c35fa1ebed62a073b2da42133f2620ae88de5e3f46cc69f2b9b3c9b88e39b8b108059ac6bd493be5f7a39f6b53ee825f4593b77ec9238f5ab804d533f48803e7d8187291ee25cfac4da5d8c9279517adfb09c422f6d704711726c73828a5082b4c7b3d85611b8f496d3e0f78c5c4f1dd1c722b1b11d55861f232beee6aaef8a00fd2eeeb45f182af191ca6de8eaa25ceda5451416fbf6d1abc0670b8c10e2815076f271044c690bdcb64856b91265bac202043a28f6bbeb807535aad4bd89e572a9427c826b170d3862f4cca70ddffb4769d6593a1cc6c42fd06cf68642835fe474a23e6f63df316f8361bab959b768d78e20c03c2a99913c162a9662bd9981eee55922f36792de0af68da04ab49dca72e3d9b0de79df828b433bcf6be073f851a36418c03a717d54d48c1014ccb793577c8393b7cb53cad6bc7060a54cc6363734f6ad388763519ca09b533078d3cfa61d7bdd4c4dd0ffe64d68d501b55903d3f4a1f310a3826ac2ca700de01d656188dcf577fd1b63e305614b8d13471f6f84a5d4b12c5e119870a63d1e3dbd39d3b5c26b09f9d80f8a59ce836b20bc933496923d278a022c00f3aac204d07d2e5075bbcef1e4820d633a3a2b35974f72a033484a91a1d6a9913239c93e5783b01833073c98f358e3465efd5087af37ad60b7285550e776d67ea7019e788776c5a456102358c32eb4e7c28096af88b9a20d8ce379ba3928a10ffd539c106f4927e7ac0f382c74017d6e4438fb128c660affd45e9bb68452de72b574eeffe3ce239d0718908c3800bc7e8ecd2fc7d9754171506017fd7868594c9373a96579fed475a28811649ce5dc8a3107bd0d8578748878ce4998684620931dc3981a2499568c2f61174c3b3fc46a7010468e8ff75c08cd43ac764d95e2ad1659f9db62e9554f811e0f43bb74779d923c8c243d12a5314d3c0c6ec84fe60e1d2b2e2b20d3e64054d62049ef9233ff55223a319c285e4e3f4c98dc95b2ca81230d7fed9bb99fd7d97430eb32c9c11647992bd85dcb47cfd58ea3e221d095bcf9374a6baa7c8333581f62b9e489282483023fdd18451f09bec764146b587209160b3d1d7a3d2e145fdb640c4bc382541e0d84255122d51a710887ebe1ccf29d41b4dd7fd7368d68ada250d3968d6f0971f0849c13c09abadb9db8b08960a18f84f0346ea0aa71227afa55b90cabc062d549b616400d36450b19adb67d7358e48c043fa1135abfca89374c906f8d1a6a845debf6b37f055d390b029c7f4524958bdf8d7e2755dde3b957f0926f9d3b8821ba96044d3cad2d637b973bfb657fcc06ff44c17965acf572ab7a0c87604c7dd1cfd136a0ad02b22e8ef320e101ea09772588e8c5b4d88f40fe1be18d27146a2b9559491949671700cebff9a709f297c2621ca9d5d1749623abc20a326ff5be55cb9435c03bf49b147b1e0a4a918bfdc3642df90b396a474f81d75c953d87b3f3b4e31fced630bd7c481c63acbb84dd31249101ac5277a36dcdfc80d8d9a2e928e9b2d65bb257bce97ccda83b187da8a7886dc96eab93d0864d88c358105f9cfe1ad0f0a8508b5b3985ff95de652e684da970b57669aa3fdfbe590a631522abe8246393639709a9a6cd549e78e3c2d1acf84643e9f554c5e076f75a5c1dce1be20a66722d0b896837b7036509ab8d473d5d2b7a8374d6a575f69d54afe3e7e18f4faf4e917be8a74e55c271b96d966e0c0b883f84b3ef2e4f278daeda2efd3ce770801d2c4bda5eb9b646deeab9fa55324e917e63e4eb6aeb4176cb4e43af3db61aea1546fbf16e76a12fcdbe726b565710e3f9866551023e5fbac0038678717e6ab4d3e92dcc53049e8cb65c00216d31a8869ff4d3539313fe2fd7ce0f53b255e3659e7dfc5f92b7627dd9ba42972f0ba72b888932d870ab97226040c4c0f4826be131fe1d2cdc21005ec2addd7796f0927501251ab26b0e5f3f9d2a1cb346a774e18bc233cc89aa69f5f70e3d5c17098eed350ec419c82837153b5c7f5813bf5918defc8df143063f3fe45125deded2b15892d5cebce589b60f2ada0f9d608983e8d107d8e6482b5f542c6650b014445e8c055aac142f16cfc59229fc9626f7aaa40cefacef777e494e13dfa93d27c201788ca9f60e572af8d65ffb513473dade5fe494cbf7377bd1ed03db2571d65af3be4b0bf27c1f069797bfb67ef0bd8a88c6286af6712c106df9c418d88054e3b46c88296a2e63894d6bee0dda8833c373d6a1b27637e1510fea3eb2fb34ae27354571369653a282a8d19f2c34f9e5ec34555b4ed24327dc5d246df13736bd41021697104f80c85bd0ae920e9aeb4e628fb8aec269d55858df149af298b06d61250b043c8a14a15f0646d0aaa18109d031c449e66dd7336044dbdec912b1bb615fae2a3df480bd64cbed74be65c8f1acac247e80bbaeb6f9dab38c6addf4f3b094d5934ef5c9749053b9159e280034e601731a12d6688ff27ee3581ae289de424d16676fb750d2ccd5b3f964dd77bdefc15bb204e2350632822384cc194cf9130f1ee81bfc3887d3366ec0b48cbbe0fe674281ae7445f03791887873659825680448f162452cef57d783821a73047078a8cf94c416850092ac772ef0b2e48517ef101ee0681b5259aa27fd56edf3c01e6dba6298ccc91b09bb304b637eccf8c673b816e74bd7f8ceffa6b17ab03df7ee9ca4098d24d044015a07df782a309cb6761528272632a6e1323c4e18284b463dfcabed708e4fc95cef133865cdbec8bfdde100621c65a92762cc3141ff37b66dea8fa6e3aad61dcbf3b512467c4773d36e58989e12a636389c1678c191137a5f7f59668c8a527dddcdd0c3fbb14cf48b8f3ea306850a5eda76c57aad06312d7bbfc18969d7b611f512358a7bdf959cc2f41de1c408133ef02b1fb2cdf8efe9973c27536434e56fc1bb4880db7fe901087b53ef3c0de18aafa47c25f1cd62c362f2e5da41c2dbff0e13adaba26c1e0829f027dc0320442e851eaed9507b70ac17180725349f6ea7b59bf39c095a9d10790e87221c7c2d24b8bca184ee95a3ef7449aad6c1d905f688498ae7a0cd1b01f76dabc342fb2be0295ca1484bece3c9b8a1b91e53de2d2587f3607a7f348f5cbefaa7a6dcf61bbbcae9444e2d25a77b016cbd1508c8cd319e9812b43b0bbca52df155d418dacb6ab1360a9e605fb53c6e20588a10bef42d884989e836b2ff16fbcdd2c1704f75dc8c1ac2cc6aeb92726f5d46e4784c70e1e249c102be6da506e5e3c2cef6a8bc4a60dac7adf3cacca8679f8f792ddc27613e44a70fd849b7617e042da46d65a3e6cf425f59b83cbae5b6e911142abd13a0a8cdf06d041435ee20e2ca417e905d2dc49c15b863ae5920ff7f9380a86bb0c86b69a000c157cd35245bf71f9dfdefbd1760af90ec3e554ebc511aebf650633221ca9157226f613f41406872765f8d7b916ff3877266f017b8d840dca0697ec3dffce7912ea9eafb62cc2f2d0a112c9bc0727444b47b62766bddf5b5f26d391f653b6894b069069979d0cf8cc7fc4143626a8420bc0a3866db3860096cc128d620ceff059d1614487004adbdf6b0c4428ac8897dcf16e6b11a692a6b465a92b40010f3480b444d4d2e24b0af8467666905c2a6233bdd6502521b621d3cdd4a5e1f268d65bf6a1879608ffd3abf635c5f0948f3cec7e087485c72b00258ba69783cfe7d611bc41c27814ef5674185791dbe626e1f276cf2c399a4eb264f19c77ee95d94252f546528f629188318e9ede65a927aafd2f2af56ff32c0ef39862d2f92268bc9400afa8ddeff591f3ef99681263a33b873bd9e01a59c8b281da30875245cbffee5268563c7f6f20b9e22d998934131dd219624d3cef6df2f3d2d6401833f72c619d6f763837141dbf93179d0f01375581ebe227185166aa7988eb9fd453d510ca6616cc013d551d23a33a4241e85aac3201284344977d496d768f5d920c5670b1d8bb608efc1b99abd261afb0a4ebe191605cc5c2e20523a13b3b94dd1fb24a27009d9a5b6329336f3516a327642386ba64c8769da1324a8a3d1f304cf0700df2b3e38215a954523e1d40ae96d0046e2929a815bf70785e94bc9b89246ab6ad", + "ed60d65170eeb49b0ee0a57ee2e57db92409105c25f2d0c1a17b5556d06511bd0991a426258372c7f2b402dd533a75aa175524eb5d6b9575300b81fdb2258bd74429add8aa477bd1182db57107d411d16147defc3582861c68f5ce82e0a0316edd5d0f3cf36825a2c79a33e376cce2e63274b3b41bcbdd755845ad9ed2a3bdacb6fa3fa9484b7b60edeb1d9ef84772e78e39adca14c9fa0bb3ad1f1c17fb9449270e9b4c97b5b320839947fc73853fc58304ee9c9e86f3775f5469554d5006eb7ce9d02d5f900c771806c275ee7022e2b55d111338dd93ad51d14008df4c13d8c03fd9bb3689607e5cbdd499c3a372b487af74cb140f6300cd2dc2acda07277ea3dab57ecf09f1a8f2d6abf7c44fcdaa6dcb1f6e791164004b20b3b4c860f409c1483c7044b6fa445f7224606894e386ba08057a387b48920d4de203b1acc4dbe2b0b4cbdc3f7d7bbb097abbf81e01db09e120eab83def925a059cdb513efe6bc93f0579ebf75638df3c3d7f9eba3c36a169e9d88495c452888853640d93ee70f254f86e2d2d3fbb5e8883b36fbd2da105cf3a75cfe998068203186bb37f1d1ebead8ce1f9383b816f1da2fd0a9e01377b6ebfed4f05bec08b4ff9b90e385736fd13a3af7980c21b0dab58decea8e9545af5d0fb11bb51aeda2c8616960e8f6f84e6c2fc4f50d7e413afe030f75475509fbcf49cbe14445d267994fd3f38f41a1339f2895c0b2969a9bf9c59b85e629486c7bb5107c7a6b069793be7690f7a7c96c93b09a9d610594a156ab27a32d5557a5b1ec8920761cd2f559ad808dff3da64717ea5f10fba87b8ff2712ce322eb3c288939e0007f779a3920f45fdd533369f6f85a8cce21f91552fe03702ef81a926af0e402b418fbb25a6a3dad0ec18ec663126b3f48c341e2725abfeae865352d5ad275a9e3ca20393c64d118968023daac84bdc724a3c522d97a5878ed788cf8e44f80f8803d57584d8c8688cff24dd8c0e881b62d16ea30104d62007a4bec051da7fdc95d1df8556ebdf607383a0825ae503e24661ceb8ba773b793360c3f4ed3b761bd372570cb17e7c2030f07b0b45a7974e45ee6fcf5bd7ae9e9abde5421b42cff6af0c6eb7fc73f4deb67bb4e0b3dc9b4008da30c67071243cda649091a14b89bdacf2ae98dd230e932d9b277d6968c65e0006a8ff63f283f2cd9c21615dfd82e0b24af6ff559c97922a3d112ff0ef4af9d6583bec1f84d1aa8bbae705b9bcf458f5d93059b90fc2217ab27d0072a38aec3229d13266beb3015ac2389a06dec3120c6c04e540886091597919da293a4a8c0812d6cd336d5c5faeb64162ec0459e252d219bed78c4b6bb61c1213939bb3cca12a625ce5a45001d7408f6d40fa9466377caa43afe961b5c1602679220258fae72a8de2ac69c0dc97c90c270e306dbd8eb681ba9c092896b19a8d42665b94ff4d5b8b188f19f7c44abc8f88d4ad7b5df1cce3465de377072c70dd20dbd6779336f05ce328ad741d1e4606dce7065347df111c7d3282c8a3fa4a9458561c04d1056cd53ec5a8ddd6bd4434ac910c69cea0443fd09ee32d1256da44ab7896867a0c97fe4faa4a53b6db5cbfe3812a6667f04cd318f3da127a0dd46170cfbaadfcca863e0d4240ebec1cb2a5952881fe89804892d36dc5bd6484cc78db41bed868ed1b321a680a293bc29c420cffb5305d15fba05c76c2138b986f799b6a3d061658e498204c2b641f2f2ba73d633538eef6b5a01117951eedb7611742c120ff24261bea605e94d21e452ddb9ad27af08ed972b7d5e1eae010ec5d83e4505f6a2b7d9a0bb32a1fbba32a2a8c7823e736a69f516b781fb5354be4b0a67343c009a09b8f656c34ab895f9213531fdeee911d677d1cbc5e72c0fd1ad1f3b4b8bc735e14c3f75f1828ea28c90cda40e0cbdc40dec37031ff3d50305d5a8bba1d53d2f176895e53faa3067129a5c97505799967e55e4e9d87faf5920d71055009fd060ad06691b78583f63881b566d4a06b639c55796b23531ea79c6de24092c0e6fb4d3dc739f6d82ee3ee39f229de4c844aba36432d6119be0d2f02e5f72ef1d95fb2494522a7221e18e92cf22e00010ffd93b89fe60b6895a37fca91aa2fefa8debdae3147fe4f01a6adbfa0a59a5203516b2cc7de5faf821a2e72d43beafa30ac379791ad1e5da3286abecfc7a546b80191b7b892cdd01c25e95506471f5eb74568257439aea03300e80699909cc06db2fd607f3279651f7392f80bf4fc61d66f0dfed7b7db09744139d7374d3cdd18d153dede2a65f26130506acc51d5c721a7989485a145dac9565ef6d3cc938c5a51f31ccc88bb0739920ef8f0a01145f4ddccc74790a22a3099a4b57e31b3a01b4118c9e6c393c1304cc51ca1784db5633eb96ccdc88f8b732815b92c9072dbeb61a2cc1e6b2e7098d883e6174f5af7bd4f129389250926e041ba94d1ac543aab6525f151294060791fd26b668d09302c3482c78e5f3271c0150c437b4e78b1cff6f2b8660dc310965f2df14a1f2ad45cd2759433c4f3952402fefd79fff00dd309c3f09a58600223441c11693cdeeaf0a6100d38d612a759a8e01f753982803af30c7470f7bfd1ccf2c08aa0b187382d25868a9fdf729da10bb0aa0e1cd9c6e695eb2c80c6b6ce62737c3e655246edbce5b8f7ae21c473762db0969dc216a93d4db239f67dea74a1de21d50336793d1ae45e931d975bc706ea718a2ab10d66a59d9d23f76969d870ac279611246ed3aab0f79e11611b312624d78b88a9d1a49dc68d6968f7428c33f0a7a65675826422f7ac058101d2f85663de331345b3a25cf76b7c8fe0988a13278be9599b8e4708526b44a70bc31ac5c278ab739e3e6f0927b72507f34b0034e7fdf43364c466bb75b559e03d4d18c864714eb6061f83a6331b3f59dd62f39bfc2529d5cc68bb6ce63db1075105cbd7d7c4d4ab68c9e65a32092e34e76c3178382a965f49386bd4aae307128242a2ffe3022fd7dc1a824b330b9f032d55573c2f004a6905178a2479ba8a2d5b3140ed5f3e10d986265d8b4cf262295658f301b4d36281611d9c61624928da9abc51ff9a6eb481310511772fcb1c1786203d25295e4a319b9c6d65ccc966b4c5795e6e30b2b3ae8246c38b4a911d1904145de63dbd4470fac47f8ee3eeb3f58b5e665c26a316362382ccc6bf8db7699fa3334cb2ce61c746a7d3af24d8030df6759835f5890b7dd1de538cac1dfe843ad06eba2e887f08d9a49b39246fb26eff5cacc937d63c8d0136f7a8ed2af4cf473f3f0d9064f97fb4fe9938d631f7cea3c617c38771553eddd606ab80bf792f34b44111933796fe1fb8bb104223a4de9e16e17321ea7f8de3306e75a2bc79aa5e9c0ec8dde9b3dd1f2ae42a6a278410afa8fb62c16282f1e3dc1e2f8c28d4538a75b5da7645101253dd43aaa150b273f73e505d490490314606264c737bb344b616a80a4931825043a740ea4f75847e98cc99c6880d3085787903e54c63e90b60f03192234ab20cb41c70c6e82b00e0575a1bb0b0f435831c9ceb9dacd1fab8a7328eb3e28533d5bfbeace430e21758cac204631bf033752f947f78ac2bbd9423c2baf4dea22fcc65c96c332ece9abb20fed504643e82f3ba0fff213635910789a2fe1f2cedef68799fcf4a86d63ab0ccd395d6d4f393f7ee8905eb77df32d97592fb34ac86dcf20cbe5afbf9e9cff37bc34d75af046a09a1781cbf51ee2e0b0f40096d85413a30de974c4d1d16ec06c0fad00716c4e10f8dae46ef3cf27ccde74502b657d3dd26b5481d9787f5c6034083ff88807896da55fd2c951a28f15c8c9e6c86ab50c369e5ba4f6311de505c07c7b85573b5a539785820c672557cee4b58dcda948fb51c95674c23f1275b423ee5bf3a646df19bb5dfa22747857fb5c605669f334d116710bd9f1495e242bf47d6b607c1c9d9c706ee770808484ba552c978ef64daabb642a7caddf5a55facba474b8a63577ac817dc57e48ab072bc6a2cc5f5ae96edc45af41c896cecd8acfc36604db3b7fed9d2d17d429f94bd2542b194a3d3405f46c1021ecf6bb907fdfb4b53fe445d5adb18501aa772c9ba75619214384260306ab68a5ab59161b\nCiphertext = 66c03198b3422cf3fd8291080f6fb3ebd9ad863e41cdff169becde726946a342ffa0ee547a27bae28cc782d95a90b0a618f717e3beb577354bd91e00a7a57485588265ad2dd0ab946926fea7c754c42751ec7247ee84c17262c0ed092186ec57d6044f0ac9deb21da6714ec7452e441e687e138ff144ea95636286263685419afd35f002830765d810b6f60e8dee0e6879995e9272c798b067d5f99f49e460b86d67c641f48240b61a16dc7cc27b048e8b8e8e80016470ecd2fc4225e29bb127ab48dfe7e7d5a65542176dd7ad40c07ac8b92891d595bbd7afb63fb6f9e1c2aa2fc659aa101f9b6a5c346625acec86fccf17f0d45809f3b9ee81572e5627f1afeed4ba96c6d3ed7e9232358dec01a1231ae7b94ad4675239f3b456adccec439b3cdd45504c5475bbc77dfd242e5e9671d103ba71a4601a7322e0e295357f335fa8d5651d528dda66575d106308338993e615b1c5bd7e95bf3f755ff726b4ac6dd5a43ef061ac9783f8f2804c68f66486f5844969103a36278ee0d10798bf8a802d3fee3a31294bf00ee74f087749ab3325c027d42b55b197469a5312bdc5c9b316b20093154e66605941d58f4db8d46a815c06f209c1dce2363771b5a794dd8d17e93a2fa7b194c6a0b79793c06f002638e5e3052365221232cc4b30adf161cc6e7865cf02911e2ac9b0a75f000e7ef3aa4f3c7438433513da7246d421f208b179763651f18e22a793961e5976a74744696912f22915244fcfbefdc472baee0be1e591d6503f2d9511ee1eededd9f5547c95eb94de134d0c2186109935207a23b2b8420a5858d831ed78202be855cc6b98d6663c1c52e1a0022ed7ebe0eea6b107da4cf50c1c7fced9744a914a66d4604a081587ce4b7e0f96ed408b8a9a2964314b1334a123d5184889958e6467a6d16e7615e5364e09aab75994e2758345511113321a3436db79351c63a282095ec6b99b6d775a5c09ea3f3225716e39e14df260bdefb2ecfe9a65c73ab4b3712ec842e43ccdfb535e3685fa39b4912719e67bbe195e5f0fe6c3aaada2d81b669c4565921f6c183d708b50c3f7172ba841815e9351fe5fbfe2fb1fabeb7cec9bd1dcf2d6332372f1b972b5144aa7ed6c5a985132f9a54469097e2e981b9e75a7df48fa79d0736c6f8a201c7c7d0ac8ac6512a7089514bf58442dbae0529135a7f2455e0ee5716c6610bd7600b3159197bcb20ca055695a36597bf7d3b18ecd08031b4ce3a643951e231c7ad15481e32ed7a3edd2b379c8e96d3288d5b93b562972a04f1b7e0abcc5090cb8655422cf5e9dac0b49678138faec81c78f113255eaa6110e95406a7e7417a6e221a8ec7fb9d55643bd589ace2da70fcb41722e66e0efce932cd7a34218375b6dfa3df1747953b24a41f94e50b84bad4d130d5dab4194665338e06f102f46badc5dad7aa06edb01f8a31244dceebe5e2006d6ab4a31582ff46731b19071c08ad1db79ba018687f3e6afbe703b1de26c11bc8b62fd6b2fa3219fa7190379504820abc97ff6c034f7850e2c7fd335462725db6748fe45920c213c539356b691f22eb490faca24e99f0a044a9f727d0786566ad00635983692ef324bbf1f80c42b269e9d5a8df3249873c51521c81400c729ed7a5e73995928abe94d189", + "cddf2774f1735bc2060bb2240e558699c365dee45fa68801e6a1745e03736ced1b89fc2755565e3b36c2102594d43c451122d94f4a263664bd26b2fb5bc7700319f6b08796864f92d0fdb41710910bbc13aa9cc7baac3b48a24e4f3573f315448c317c149ddb433d9ddd2a2f0cfc81c22d3dab31f184975355b41e4b36fd8f22e8efa01d61a5cbb0e4fcdd273cdf68ac73fee745faff44d44d93c5a111aefe4a5ca8e8e7c075ffdb738cc5b6466dff78ddd837c72c54941707b04d60bc126a3a2fae9540ec2e4672ae13de0d927a7bd363f8abb5a56364d6d564df90a46df9fd59e2c54d5bcb8280415257a6976d8fb24c33330af32600cd1559e0eb05d55b34be456d434bca98252fa531486ce2a24c8bdea1d57d93a550ec586920903a39ca61cbfbce79b8f3a5b1653794872b2c614458177e748f8dfd43840e5bb0d608c26389347673fd0b005f60f52c56731ee5faec6c8d0617fb53d5f2415c2e7906ea0e6d0066354b213b3e94f4dfc311e4ec6afa7e8d1c69a63cccf8326741456a5e0bd0a359b7a37c117f7892969ad7b70cba9bea0a975ada7cf67e0d7255be8d2c6e7b8788b9ff14c5d1449d6173e07b5f9d94560d46f474ab2a67056fe9f4a9fd617a617d23143adb4e7ea35f2d5cc1398fb9ed43ddcd10f28debb27eb13533110005e6c78ca4a874db68c65081ecb8bff1b64eb1e2d7b76a1da3b375dce8a92d32a6277ed847879345717b9649f27e846a701549311c7e69a96d61df616157a114bdf1663ad93a26c28e1a62ee4a7c72bccb9785639eaf1e569decf777bb0548ad9ee36788cfa1150eee3ca3c96f09052ba2300cfb7526b9424b6f7418c27a1e9bc13e4d9868e5c330c051c3885e44714bddf7cb090fbd0f36b826aacbe191dc8c35c219e19fe736198c29dc4fa1a98b5fb1805dc29ecd02f74d4510a3928448b5ee61b5991e46644850a4885bb1ee272883faf27962430de1922d0883e7e80215cf5fe7e8f3fd0e2a49bd50727af793cb7e5b40860e80a1fbb9d5b5696bdf2f741909ab5a713de47716332df6c4f78288edcd6ea130d895fdb2f29f94635bbf2061de55f1801bd6a24294aa199d78021a1ba771c651de4bc08f032fe6ad7a5caf6a6afc6de649b901f783a0ee0fea9b803beeb0f431400d0707f159d7dc29c0c334a918fa08a653137a4a8bc86066c8800e1d171f1dbddf1fab8a3eff6b5023da96f002e7e217e826fa378b15dc8a376db30228f5d6b629f331a162d63e53e5b5bd7ff9ec098b4314285908281930ff0a8aa86a6d89411e6b5bc6b9c9e931623ccca6741fd6d36311e6a8e323a37ad40b7a2797b84694e736d9c135e52d149c760e727598726378cd674b0f4df1c361de0a12a2b8232e611d789bfbea699e8e77b99f3449609caff3d6ef7233df8cfc624376c905eea46c6f77c0b01d288868a19db77e227dbb5bfea5cc3f49d219c7477f7f2b3447b0b8efe08eab8f69579d727555e547c13ec7ae13b83386f2adf634140c311b6e2759cfb9c8aca1c32bb7c002d0f46ecc526916589a29e328ded9679c2163838f071b5b85b35e5e7d99c3c45d25bb9d37d7bafb8350ad4695a6e0cb7ea7d93868c30bb54e301e21147696b7dda156226a5ef8c62121e6b2cad0c4e192116192012468eaad46bea69a140aa3cb9056dec87c911636a1e55695b9e5a27c63cd8c03f31570d4b7507d13731ea31f082b33c6db8dd6e22282f9790be41350a96abfc4dc3de78e0a698930f540dbda3fee923a463a4c4a66bf00bb2cdd6d22b62a47af96b78b1f0f0a174e4ec5b785b3820f47d3c8cc1691d4751ce4e4ab78a4551956158a36717dc35488e890d0631241906db565603205e054815aaaaf17945c3372dfc7193369871e2e88fb84c15a2b9071101e1208177fc18397e6af17b5843e1fa75392d8d3ed214975d50f2b19c24e83f010f8c394ec1edbb1cb912e61627d2760b0e630b986bba2ae113b8f3b51ba00ddc495520274a85e6f6fa7573ac4ec6e2a86a1da9199ceb007aa6f132e5ab8ab8fdca7c829f452ff17524fec475b8f485b29fc6f0d972eea4ce98e242b5d58f6ddc1b3a71256de1c584c9914a3cf1e469f0033165d934fae68a7559011dac7a4e0c72e3b398fab8f8cc2fb67963b0f9220f410e5ba13026a27288a1d49edfaa51e8f220503fb5ec476147cbea975994fffde3ddc51bb189c470078978d238f5287fb2629d23989875d74b006a4122f6a342c996d4a244e8c5e4b804a44c301ac4d6054181a07964b279e0a44c158364395a2ead40053d2f3350ea0529a57552ed835513f533ee0c4b94ef674f31851616a4fa2d0302d13cd4aabf5f96ce28219c0b5bc0e5410fe0fa387ba1009a6f2280f9e7bbe20c33be5eb411a5f6327714b3443b4152cbc54c4012473237dd98b0490fc4228ded74afc81be2a58a22e03ca987faef5310e474f4f5a183f6b7ebede5a8df8a0f94a87a41852826b29466fd761f40b416ad0f263dd34e5497867766a361af1654c3fcd6ee7e6bb3f72d64cc980f04305b63bd574f116d1aa35b4bd642cab0cde6a29139aaa163805c6c40384313d4ec6027c891023083988c1b0d2edbdd9b1afe102fbda285a6f897efff72a0d7fc19a3cb6756cfaa2371e13be3cd167cddb90d525cba7da69608b9995cef92a6424a14df6b860ef0f09830fd7189497a432347680de0f463c0aff82df8098cc4f7753f7680c8c7374d01046b05c63be73f3a1623be778fdb0bdb90d4fb4b458af2890d15f108b0927304c91c8d62cb148c35cc93797db3ef9bba1014d89859a91da0c0a971f330600d71565d30e9c9ea8c07e7f629e1a6d578da04d37e597261cae8ab7d9a952bbf71573f1bf70e064f36c032cc624e3c980e5ea46d36232d61a57fa598347b7fb6b28401e34628b051d6ca3dea190d1d3c343fcc83175f70f77a8fc5e8791b9788989df1e37cc4881648f4fc673772003079adae55c83cf02a894b98561e4a6e4416bea3df18d6f702ad5c4f40faedec6b53cfdb5b3a52d7d43b97ee23ccfa2d30c7264ec555b15f1d9e7e19cd9890a7e8e01ff21d3b8b451e50932f189a420d18e7c7e2f103332c78c84600e5e8fdedd84f055a8b39be9a52782d47c6205c0de41644b09c0931f2da269a7e58e669f3b61ebda28ab8e3f9b83ff3d2bce37864af494860b2f01b000abeb737fbeaf8f9fa6378366606dcd0fc33031b94f9a7a0e562c08ea720a671ff92520047f69b138b4e032c3828874ec4c29e49aab302089956566372b20c0216b601c3958ed9691bbd89f1df45c6613d469e3b9758a70c860fddf768b10a6bf70237a454a2c0b70dd5d02da612a91fc5731513012a4a6fbc16d01550bdfdccaeca22bba104ccf6aeb19f21d4cdd3da231af8ec5bf2a726ee9cc7c85b8ed46d2f6fa4f1b010b2561fb69690d5a9df76d729450a6e139962bdaa2bec0254c5a252b97e7ce7eab1817f454c6121130952b8c40628065dc9b77b0f953552f5aa3ff983b6a51a51dd87c2b51a18e14adb8c80e002d0b47c61cb357babbbe3ed51d371941a8f111837ecf0e45020cb941de170c4a1b5e61bb928b1b11a8d902febd2ba016771f171b8a7ae825fcc4642d95649d53675d0027822e4ff79ffd302bfab1a0ff26f3648c7ab00c10f8d95f21e40ca2b40691bd4be79bb9ccc0bf760a05be4728bbc0a64e585207d1d09393a80d5f574442d6a933966777ab05f699c4e84aabbf753059287e7261d972745906a4fd8967bfc80ae9b6ec2ee1b22a81775f4f24999987365ae2dfb6739902ed51b9a4394fdf29f216c34567102d9db301661b09b728a79e377cf4bdfcf5c83b110a2e267abf6d40947e643ae2ff0c244af168c9f33e7685474ac30611ef95f218e0dd280899a92a41e7a759d03ce3709c2a140ebd35e199f1dbb96f7351cbe1f3de8da8c49758a49b9e724ebd3220ed6f51112944f70c0d1e9178f68a2c9476a913de00abbd1f5bcffa646f926da77a9e9fbdf81cdeaf7f9b13e843afefbca81c93614f8f1675325965b5836b8a77620a5ff162e25366718d8da7781e1a7e01fe2e9e56cf958c6273473abf5c2c8c7fb209307544e1c0726d5571e521621b18b6da3064b473423536b1b76ed75b21b4ee205d7ab5f081bada63062706bd155672dccf84614210d72660095437c6bc2213d9c904a4ba1bfda14d350fa3dce7141e817a50859b1a74aa64560b2ebc67add9f945b6e85577589817078c8ae54a9fc311593d2cbdb6692b089ee6264cebcc7719753f80e30dbe48b64fcfd1037fb9ddab69a5ff9e5898bd8aa947d9ad827c26df67c6786edcacb3478a20bded1ad8c48018ae0d439bb5afad5d39bb8fbaf22d72ffd759c4fa2e94a5a89f41358ebdc4c3aea5110f1965a049fdadff9cf703eabe9628e2680fa4e70320d304ecaed13f513f27220db1916ca1500f1c2e091671fb71329dec0bd6e310c83e67af61b8ab60ee1a8d559a508d174648b1bca451ef0ab0ee2ef74f4fcfaad1cc5ea6cadb8f1bffcb1f2c05122011ebbf6abc16838e452fc47653821589da4cb5bbac10deeea3ba0e0a6241338e64cc78d7a923d018e8b5b51c4442070e5b0e6f1e8c2b83791e930899c5897a602c401c1b85827962ff56d19c06f5af033059bc7fb1bd29b65f66aa5b4397834e846935e523b16438a42c1f990ebe4f83182163ca5fc60a4c6d77fc182e81fcda943a962e9e7f00f6399728b48bbe38d8178fae3582c8d9998e49df5f28e32d541636df3cdc8ac00df45db12da2e5e76f366c1ea8667ba5f3542d21f58ead7c55d06a4b35251b8f77dd34d3de262947379107a06d2f4891ffa0ad3a3e5bb2bbbb978af4953310d4cbe5525ab344ebb98ed24d003600de8f3af36ff3d0a7efeada963845d573685bec2221403b994f97b1e714fd7dccc300b62c2a516e9c6780983062eddde0178e93fcbb2ed4f06f60767356a11d22ca37078fda1ddb3cb907d1020f62ba85d09044574ba28aa3df36988eb8a41e4305e5b0687abe43a90e4f68f0374b6b05049aff5b065d7688cbbfb0e96ab03df38903bfa1c269f43a114085eb4596aec87ced88701b42f0b7426389727308bf10aee9d8f15ebdc411ce1e764a290a12faa2d7c1126dc7b5076f219b826ac8d380b69af7f95d69fc3929a97f5c7da1db6270e9ee1f2a5f7fa3a1b6bfcca00463655121f681d3a627d03efdf0b5fd045fb153bc4488a9a8b7264373c710ebfdb1c267fdca37723b21d5c3eaef48e784bd76e27c133cbc24d114f610c79f2a1f2c30d87ddba395887030b65097ca5566eb0361e70615b46d4b86c2759f1cc2efa3915b4cebdf51a745fb3c6cec69a1fda2ec5e884dce228e30af362815d2d8b59a14f89606bc77439042109369a9648db7d71024ed6df06c8ebd22e8623f48feea77f48b5e88827fafa84b0564151a5997b7f29c4d3d18068e34f2690a293d54003d0ea8f3bab9387ca72212cedb5f4602ad047dbffae2ab3a4cd2865bf896cd96f78b90e4017eb7e3c7092320c0a37f81dd65a5c4817a4e7053e6d2bcb23b11e09f681587f3a9361e974ad54b88c72c296629b1ab754d25be15e87c414cff975fafb3d7cb68167b21f1889685a48966705222b525fa47143b00041df94817c275d93c2550fdd82471cb3cc1b5644338060b767e807bca902c180b3e535c77be2651b3962287b6d1f6403033de4e0aa3a20615ab59d290f4b167325959c1524ef216dda2ffce86b50cb6b56b62a20a043d9d78c704479c22340151df5a190767", + "0f8d4f8c90d93f7b5d94d04a4d383914867aa3c0e5ac85fc299a4d2801a3f80f4b0f046fb62c1c8c539a83b21c7549df0afe200537b52c80ebdbad8a438e430cf876cbbfee9ceb1bc5270577c27d53b40ac153cab377a565b1a9fbdee8bf8e94839c0fc04f7f664383bc90d56ccd1cc01b465c250b158b5e6f321c20db245602d10aab80c553d52f17282b095b5e2234c6c689a84b096112100359816cef7e92029fdfc048058f847cd2f2369ceec9fd171a0487bd7acfed6b0319832df6d59affbfd460ce8d12e4171da0f094e872a2888fe74925c5ef0621c4edad337f7006086748913b24d4d48ce36e662fefbe672b6d476456b1fbac6d80030ab93da93acb4a7e10f955547e7e20a0abcdbf909f05a2ee2e0b7485fa16be652b9d9fbfbf01f082488a81022bdb69af9e6fbe753e9eb92a1762afbb4df49f83ffc0cf03db563aa96fc5ba1af6d4d7eede6067749e8ecec79b63e09742e29e99e1c960dfb0688b0222c49ed919379ac66e3fa1c72645122d1664721e78fefdd1224c0b886f6e214e37d268ca9acab76ab3adc9f5549e5dcdbb3d31ac34ac472894d004eed71f88ca2377fcfa48d3ae43805dc612891dadd06c263ed8617194f890bcbb964f010d277ddce1f6682e661577ecd51a4d5421f00935a5b24fef0ea1809fa5c4fe9cf8c453046f61136ec8872915d2462157d73a205d56d77bb83cf16b88cadf6430c0e5397fae1f91a6a11b177bf04b065a2e55df81d5c086ec8dc8a0a660eed37d41fe4d8b3e3f22238e2a63b6e4feee1fe9a140ed37b2be4193f75c2d038aac7f6b7dad2a3b37e5b9b660615ec1db77a9b7ab416f43e66c872b71cb67c9245c757dc87723ab3b9544fdd8a16c9486e8ec3c4a44cefd98535d6e5683426c1cc8c888b8e0c2e7528bd7eb89b80d9e00969efd2f0a0fb09845426edf0d1d9a0809648e7e46ea0a8c9988bf9df475be12a72c7326c1f2bf01afafb190cf6f649133c7dc14ecf9b8c971135bd303c8894bac637e08257d45e1b68edf550d896c41682c002396e8f1eb7c1e2f4e0ed9b8b7010fc7847e6fb1c5907c17b2d2b7cd24c96f47406bd04cfcb2099d82dc2902d6f91e2f8f3a05bc62019af536309e7847fc06c10dbf7272a1509079fd16bb16a85ae2e078f97f9ce66bba66d6329c7ee70f9688f6d91aa38b25c7f4884658a72ad8cbf96d7d7a9652673273ee1b3d4d17780dfe9ca865416e318bdcbe9efd8e071fcb15ceb0743df5af4f7d598b31e38677e65af61c1109fdbb11fb11e3952e6c3ae8abc3f894ccdf205ae55dafce1dd05dca6b899877f57d712223dde4e7fdec7e0ed4f0a29ad359e318eb36ddb42fb205adca400f5b2615947c4f0ede95788093a1152d88acbbbb272750823151e245354e658452a95f21fef05bbfd98a10c1c975ad1a08c59fa3efa9fc73588407a83d0b26a53f1b4115f83780bc70ee2619d7374ca45b9e200055df1b93977e17aca89a009110a6e74caec7f86114f91975bc6e8bcdc7267ed2920cf12cd7137840628e1b8a0ea181dfef18dc5f74e752f842ea91bdce4b420ee709bca72c4514e92bcff55902e5529d77fd95f5837c8f4fffce80c813630550a0dde24092a25f65eba90790a06f4d4c3e739aaa8194a147fb32e81c71d3e8def79251c33637661b0a621a2a6b302dea00d34a9dbe9b621c1dabd0464e85241aa6712d90b4287cb23c17bf1e4d0e6dbed372e6b49c4a843305b3b0e5cab0b0964a93ad0bbc99ee711afa7f2d0a296a375fdb3176c65a957ddd9b88e9d57df736acdeb02a71b924cc2e972f51ba68a597215678573bede9ca5b3a0a2461b2d3b9ea57a5af8c91d40779bf917ded32f14a66d96e28e1415fea1e9306654c6b84d8a64243a5271c1f11590423c718961aecf5f659b49f67efa78e02ef2524d0966ebcc446d73d49ab7ec31f0c009069d14ccd63f926169291b83a3e37610054b0b964741e2ed8771d20bfa225eac0280b4d5af0c09d3218bd497a035536f5af0816884d606f1a872b8161a266466b56e0be8b80a7bde65ac706eea8cacf1749e5e71ff9fa3e69ce878427a0728d44e666eff977026abfe18cf3ad156a943b917e72ad65725a9a8d60b7b5740494fa63143a7f2a94fe6d8b319be55d6fe1a988244deb798f345f30dcafdb6af9e9cee9e35733274bdf3896750897371563ed2516c4ca6c3c3c994b48cc94b67e8129d234a0e19dabe39e500214c0ed5f0e5d61b2f58d7355d147102d93b2689bc5185dd4c0a18efd11a307b887d4d0fa84fd992731b3a80dbd027dd36cd6933766c537e8e9e27d35d5187e8276b0f59fbe7b6d629d3416b782e7981d85e1e890853c3aa94a93c1667a55044ae42badefab979fe7d525c6a180307c5ee3a9c3933038028c3e1d15d1e78fbf53b6ea61ac5e02db0161719398a31570c55f73cb47ddec8f99e3e14af5adb8d5cd179f4204d080331e75bd391b19d38eb81f148c36af3e8a3ebe76209bb75c9741a89b5d0708bb0fbb0945fc6fcd6ce142d19faf0947c338dbc8d976963281866b5216421c00cbd77c0907d1e16f5e925319cf6c62f8c6e8eff0c2f831c504e7a1c0df09a54e2af708ceef39ed7d0f63d83429e9b0920c03cf85c2244f2fbac3958847113bed577dbde8992cd91be5833c75faedd5e2005d4f7b66fab8fa9305927406f863d1795dfe04028940b765bd79de6972dc7094fe1c2503a73d7b50208835216c23aab3e47094587549fdd74bb50ae21cd1354daab632fd0907e63f4c2b2d39d7fdc4fc216bfa742b4608238623cb7fa01bd851c1e7ad5ef5215173a71f363fbb7dae8092486f4a1549e32ae53b14c1343ff7fb5e2b1487d9c594a1b56e22625d275e41535534d225b7b2c9deeb0d30dba7188cf75d680d4545ed05044a0661c690a37fa14a73ba8c68357e2c948e290b5d9a4b51822824614ef2938d19ea4b650041f59f3b548f0a305b86f55e69760f37f09dfdad62651aa5fd84eef28a4431136b34a49c9bf1f2891364f86b0aae70b0414e821e3db1533b0f1db5fd232308bf118f858aab5ae974c10583f61b283a3870eb82aaa8ea3c4e2ee3c3a3d7169aa8e975ddee7f620f6c5bcf3eaaef0101b62cd54495cb8809052c9e3151690cff7c1efcc4f63b22472111a7c5d9d7d2a2be951510f60dec8c426f14700c8630f8a14dfd359addf5d9b7ae031a745ecb4e17321b385799c90f924c4780287ac187530a40b064064b9036cc46e3f87c4d23aeeed1bc22a5411c7c503594d5d1261eb9fc4da242493beee9f671485a978a32e965faf9b0e2c13f78e31e1630b72d35b4be691e90b3798e18223c1b514b39a8e1eeb7897c22fdee1e33fc76e2b2f9298ad4fd89f44163aaab23d754d98c7890e58708b81b3832aee31aeca85e76416133710aeba0e5d9f17695e607d09ae3f94be191553bc39c6df03cefb4ee05516fc02d66c9866e4eb0d89a662e309379a347159db2e070abceee226f2b8b62847ef7c51d69c5f12eb567fa13af4b4f90b3f3d9d4b6a3f68bc4dd77075081e2e99833c18b154d0d6ac360141de2a25af61d551f10a34e03e1419a37409b4c177c51a8d248157b411868eb607c34d2daaa453a0954fade5eac45d5f21f50efba8bbc9c87ff0435c70f064b42cb2d158384fe0a4d9c90030ace7723af0a6c8faecd8f97f9850e2a489a94ebcc655301e2e14711de9eb08726638a9ddb57160c5545c152a26860a17dd18172bfac138a300f60431fc49eff18c93f71400e887f878f4dd637cf5df8c1e2b12c0f87e31ba2754ac1748479eda0c4184b528554106128320dcce349939e5e6cd3434f86dc7adfee28c008a21ddf9d0dbc87ceb14cc3afbef1e06fb3f9908a4b14f5e6c43b23ba783b75a6cbfa2ebac6533661b8c1143a34e8e2a9723389c4b7087dc07701c53b169894551084aedbb423bcce2f470881fdc7240c26b3b76fd6cfeebf8eb2828b4741e5e8698b19fa0a44703cb4e4c8ed6a7e4d6063f5fab724e08a159f4f04a2f351dcfb6335ae6697dbeca25c76b55e6ec9045eaaa8706902df492b8c8cfbf68c4cc1be5d1e5a173262e38bde051656ea85ffe35d97f1b25f6a47381bc327a946f7cbf6210adfd957b2921\nAAD = 85ddde4720659e80e25168585a354eb1e021c0b5d2ee289f2314dd5aae52bdf1fd44755bb56a6e659111a1d4b4da73315bde01c7d2c15a4f7114aefd68c141049fac27acfdca24e65c51fb1c27d307cd948e13af2963166bbc9411401d124f1ddf20f890db5611385257f52aa05c09b467e3ae886decf5744ec3749e5879f2a60017f601bbee11a66604d5f3d521d2c48cea1794f77366f29c7bd12a8aa51d34a4f3fb52809561b527016bc6badf9d136156c330e1d69d1aab98c7caa9cb46e782a898b4c66e4ee3e2445fbfacaadf9a8f73c4cbcb2a1ceb604ba5637b51337fcbe0fc366da98e805ceeb29feaf05420113b16e1005079c0e88af33f5970b3d7a8b51d0d9f5120a0795063db508171b75ed07705ac6d6bfe4ecc59243091d48865536515e036860affa880bfc91aae2fd1700de15994792aefc4a176e5d49d0f9135c7d670f3cb8798bfbe83fe73de7427e0f3e6a2df561cfa15ffe6ae80d5016096c8875b0beac8cee8fb530fb421b9a8ada4d551a528d0a0b521086f5a2db371a3bf12a2ef861f831fcb44cb2baede907a9306d3e5a3af796e0a50ba2c8dd61fb03727df5f0654d837dabee2fd90eecb7b2e8f303b0d57f97dc6a52d8281574d8457c89c6a9f5d80e0bd86c90ed39b1db4253affee614e8cf1ff05166c66e7d2a2aa2fe8a81c4741339683debe189c126e7f553a5f2dc16fc16672f74aebf94c7e3041c758fbc6d0c7f71c192cfd0fb2ec52d0a0705b05815d567f3d19f9b5d553a2adce9a79159b0e38980851bf64e97f896c028a6df8363cf1f13f4654265a7b0c0b24198efcf4418c32772bafd3980dbc689fab12e85b3ef4a491e2e5ffaa2fadaaf3deb392105a42380797d3b41ef61303a6016b269ec9a9f6e3f26070ff33cb467435ecb325dc7e18728a5c2e882e720c8f876fef10f5bffd5a925cdc9689d934272019e90e3a3bbf63a295f207faa5c014e1517c7d5c18c3ed70e92304d51944dcd3604c999d4aa8d8dbf2a4c69cbbc08635c968a20dcb80f438d43c57851c4cafec0b9568dd6c19932fd3f1294afd16f019f20e40ec87f6f5dffc7717470614b2de6e9000969e6b7e561cf91c06dd379a09c6c25c7841330dc78fc5be1d9b86581a81f55c0289531128638441fc98a1ad9472d74e2be2f874aff2fcf9c941502f59f716185a4c39289ca368c6dbf5257b5dc5e57a420792c26e602e4ecbc4f17c8787004eb88ea091d6b6ddc3c85dc110b5d1f46f6e1d872723176f4c73664ecb4219258fedce19ae22360354fa4894fe51d69434c2e58e1ec665b5cc33bb295053c591b474b6ae178c8834667bef971604279440170ebf3e739a4ff19704e5886767f81edce95a3dd93d1147995e7eb6c794b7be136658ed23cec7c374705ec0d8479dfb44cc7213076668e5fbe6a508537a9157815c6e5187b89f\nTag = 469e3ef168a64945f76d7a2013f27b68\n\nCipher = AES-192-GCM\nKey = 000000000000000000000000000000000000000000000000\nIV = 000000000000000000000000\nAAD =\nTag = cd33b28ac773f74ba00ed1f312572435\nPlaintext =\nCiphertext =\n\nCipher = AES-192-GCM\nKey = 000000000000000000000000000000000000000000000", + "000\nIV = 000000000000000000000000\nAAD =\nTag = 2ff58d80033927ab8ef4d4587514f0fb\nPlaintext = 00000000000000000000000000000000\nCiphertext = 98e7247c07f0fe411c267e4384b0f600\n\nCipher = AES-192-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nIV = cafebabefacedbaddecaf888\nAAD =\nTag = 9924a7c8587336bfb118024db8674a14\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCiphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256\n\nCipher = AES-192-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nIV = cafebabefacedbaddecaf888\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 2519498e80f1478f37ba55bd6d27618c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710\n\nCipher = AES-192-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nIV = cafebabefacedbad\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 65dcc57fcf623a24094fcca40d3533f8\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7\n\nCipher = AES-192-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = dcf566ff291c25bbb8568fc3d376a6d9\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b\n\nCipher = AES-192-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = dcf566ff291c25bbb8568fc3d376a6d8\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b\nOperation = InvalidDecrypt\n\nCipher = AES-256-GCM\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD =\nTag = 530f8afbc74536b9a963b4f1c4cb738b\n\nCipher = AES-256-GCM\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nCiphertext = cea7403d4d606b6e074ec5d3baf39d18\nAAD =\nTag = d0d1c8a799996bf0265b98b5d48ab919\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nAAD =\nTag = b094dac5d93471bdec1a502270e3cc6c\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbaddecaf888\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 76fc6ece0f4e1768cddf8853bb2d551b\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = cafebabefacedbad\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = 3a337dbf46a792c45e454913fe2ea8f2\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a\n\nCipher = AES-256-GCM\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nIV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nCiphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f\nAAD = feedfacedeadbeeffeedfacedeadbeefabaddad2\nTag = a44a8266ee1c8eb0c8b5d4cf5ae9f19b\nOperation = InvalidDecrypt\n\n# local add-ons, primarily streaming ghash tests\n# 128 bytes aad\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext =\nCiphertext =\nAAD = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nTag = 5fea793a2d6f974d37e68e0cb8ff9492\n\n# 48 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0\nAAD =\nTag = 9dd0a376b08e40eb00c35f29f9ea61a4\n\n# 80 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291\nAAD =\nTag = 98885a3a22bd4742fe7b72172193b163\n\n# 128 bytes plaintext\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = 000000000000000000000000\nPlaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40\nAAD =\nTag = cac45f60e31efd3b5a43b98a22ce1aa1\n\n# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nPlaintext = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606\nAAD =\nTag = 566f8ef683078bfdeeffa869d751a017\n\n# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF\nCipher = AES-128-GCM\nKey = 00000000000000000000000000000000\nIV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nPlaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c\nAAD =\nTag = 8b307f6b33286d0ab026a9ed3fe1e85f\n\n# 80 bytes plaintext, submitted by Intel\nCipher = AES-128-GCM\nKey = 843ffcf5d2b72694d19ed01d01249412\nIV = dbcca32ebf9b804617c3aa9e\nPlaintext = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f\nCiphertext = 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5\nAAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f\nTag = 3b629ccfbc1119b7319e1dce2cd6fd6d\n\nCipher = AES-128-GCM\nKey = 31323334353637383930313233343536\nIV = 31323334353637383930313233343536\nPlaintext = 48656c6c6f2c20576f726c64\nCiphertext = cec189d0e8419b90fb16d555\nTag = 32893832a8d609224d77c2e56a922282\nAAD =\n\nCipher = AES-256-GCM\nKey = 53a6f0d9b8a81818f2fd7525acd65acbaac82684cda4fd357b1ceb6146b31ee4\nIV = 05d8a92b5a510c3a3dacbbc0\nPlaintext = ac0ae17d3d0ee5935e18675c36d9e43967f6da38dddec14c7ec574ff8473e11ae5019e638232323c175b7672a7462df6709f5014bbe12a1370a1ffb570177927106f995dc8f35bd6e6228de7c16acb71e583c87477dcc7b17a908ce01543496c2cab8a14a21c43b18fab52d8a882dd1d999b4275db34c7f32bcba624d128580d7566a2da4bcfcc4136d58816c437d21e90456fc86381b946b8955f0448e83564165a629cb2edb978e5941010ee9153b054ee429b315058334ad7899aacedbc0bf423de69f57c633b56033c6531dde29258694045c46a797987471ae6af8fee8ad0c1be4149605064aaebafd1c5592e61beca9b5c7771410a276c3ae517490735ddd6af499ff705b9fa68d50650e60c19f5ae2c88dbb6d612afc7be28a5f55556a2163b6f66609f7d9ba7e97c074ea39a618727421fbfbb6453ffeefa643decf11404764515d28fce8ba66b8c85d077c47a54125a38bcb6b0adf6d248ba0a9ea129c887c66ef537c45e9fd3c17ce352e3936cf139e13a5946a7dc9dcb6423ca6a051bf560cfc572ef366940e71c81aa302cb9701f9a5206e9eacfe9835bdacb6425d058022a27fe73e5edeeba98c7a3edb761578ab2ad5a442c2dc1cb3c143c6f18dbe525fedd2a9cee0ada3b2c116465c5cca9a7e5d4374b29aa4ad8adaff8d6b0d1ac3990685240ce022faaa07241f9ff445566b9e0463350792cadcafd5fdf5c37706c0025b3c627185b356d39dcb2244b15566e6e3f8942f730fd6d855daa1456fe294f9156c4b5131e5bde7f2d938ceb6c7f5deb0f847a98b7fd11a3f5d0163eef9bbeb83cfc96dd8eedd447901ff4d3a35c0ea1f691b01385eb39fd265f756bbd77bb61b1741db0502947b4b985382a08a5916da809a8afd3fb1d78d9e16f8e37f51aba100d031d9da8613e9cd2cc621025b47150b3e76775ab23412d74334bcd79746cf601407481310a923047ac68a4e6a7f7b96bcd85bb6f24e38f03c80ad41a0a581b4246ea4715ee561cdc5384a51a6fc9ed8569ba6b12bcd95e6202ecf834dd9062ec539cc8cc4ed64ab9ff85998da0e63161e7391b14de47dfde41523b6c614618bf2fd1edd68a5de1c03c4181569b6c361d955c637abbf4efdb5dbf2f0dd2544329c44b77081a48f53231fa9d4cf6f2186427e469d0cfbcd698f7e7cf773240dd2b807a2fe699f0ceb4a2339e9cde01114b2aa5c3591a82a3a27b308e1e7f092af8ad97bbe7b28d78ecd80c0c0a28372193d66bdbadc0b58e4d5408acace53bd5e12101fcb25754f8c545340fbbd1328287044a29d18f40a24b4084febebe228b67cefd970df6d44ffdc033a50534e5977bda660c589c6e3c3a28b4c500b29ff4a1c3eaefb068784a29914ecab7868a43999833b0b37ae79afe58875a0425262e0ec7e10ee8a6bc1c97d332bc2a6195de239a166486a3c1ad8de3a026e5b1757f9a778a511024a260c9809ae3b22d78f18ac483281a796b1ccbfe7a9b9f357d12d340e20bdf2037e8bb91ef858cdf2eb9d7161a756d8c244c55524f8f5be2e4f18641bc4c2409c14816846c4655be716276d8356e516640da49e8412fcfc7ac0e084a079129b23e54952d8030e1f8ceaafcd322dfb4bd189bb5d940ac83231de0585783387d0642a245183f7a251779bdb12c63e9edbf3d0c94281140598fea9e73e951ce650c984cfb1398f8813abf8f8827af5eb64a65dfd1305bccc45086438ac439a9265790fb225c509ce3c9d39e25d2276d7f3c06d7cc28d33b2c21bb38b50dca5b10afc09da83ba12ee878e0f6054e8d3e78d731671de4f9d5a7b97298b01f37c7e78e5fcf5188554bcf5d42559d3b15153bb3cd5a0d1cc4a96d02ae8b1b115d1ff617b6ad894ce0585f46a2a5f4cc1b83065c1d7b5d2f25f3f4bf9966b4c7d7156931861d5edd199c126f1ee4ff6345023419d0a4c87f3388fcfbecbb6c1e2f4745922b88085d21d4551e4c127eb423db87a51c9f9a140f8a7415dbd70c4b0173e687a40f895404f2203e14ccd61e0e5b0d5aa3fbd1c8affb5807d787d840916ece24c56c50d3d9ed9f19d73f2c80c461b5b3c07dedcdb41402c3826a958d74be48382dc741dcf3e0eb8955397da33941fc47288147736d778914a57effbafccd4cf293e6ed1c7d19b55433bc0363e41546b3638a4c630eb35dc6a074f90185cb9daaa6eab54825a4daf76f49ad918e90e5777a826d6d5d52f32f7ceaf818f87251ab4d1b5406ae94e41cc97fe022b144f26335829d9c81725b3daead621a0df71313d18214ff8dc687a7ab86b8eec3070ee1ca9f62005a0cc15ca6e2f4fd893de8fd91f6210f6c96a576024678535c962a2dab06f56be377dfa74bca089adb7327abd05c3ad7646b5e9e6fc2f29916b34c8642f3c0caedb53b8f30c2a77d1757103b7ed156cdc703911366b02cde87ce7343886987f7a8c028921a7b87c5c0aca7ada34970a6d0d32eb1b177ed8e64c1fc6839b9d08acec19560bf4a815ca6187635f0cabb8bf062e8216d3b09b7abd99e956734129e16a7c4f3beb850fe2b1548729355f9015c9bba336d3e26a27b3d75d75722f7a8170d15ebf77f325c97778a5a9d7c76d3e101eeae354e54e6fa60b58cbdd900751854ede326b58fa5caca073c630f3719d6f52afe675f10d464e8b58e5fde75a4f225063ca48d76efd1b645e4bc89d98215beae765601f635a3bc8cfc08d74722f3d95ccb4cb4e3ea977d0c534a4abb866fb9a31771222cfd998231c30bd16b6844ef71038b67d72c910cca40db7260dff0b74162449a9e2cf15d7dfbfb3a685080e6c83ff4341c95819c0317502ed49af7ae688b52c9866518f74d69b4144500ab9d5a0829b9287d5fb67b78801119ddae7a76e80be8c4dbcec7866ffa7d081406e51cf617be061530b539cca7e1ef9118cc06e8eb2a01425b45947a1d2332e360acd0654bba8f1fa43ece68467690d36f6802a32f03f9ea056e57fd548dd4a3225ad5006c6c931aef1990639498dc88a23895ff1f75520a8009dbde4debc20ecc546e378eb7ed5ea3740d2244036588471d96e4751390b6b76b39816d853944cb5677b493b36de9736ba0fa404ad4b3a7d7c54d0c15072c040064b871401b25b88559d059a9519c7e2446b0d110a4aba9c12555e5f620680d1fea2359bc85cd15b5c0bfd6b3715d647514118cd60483dbc9c83e285192108f4ea6bcbee1f0935044610c68d052ccaba23258d09465d5521e2664d59358621ebbb8f28a4627362c8397f0a9852e5d8daf53a961d4ee66299e2b54d8adf5134ceedef57011f810aea76262422236c3e1a478a759584c7880fb3f32389c4bd4b637caad7b2bd6fd295aefb150754799434e99e0fd45c1cc4698ab14d1f63eeb06e53797cbdddd45e7f87e85b45a3dd0df6335c3b1addee87ba953bde29ed98042d745c1465a967ef922993798966e1c8b96ad6f68404136be0caa2264e24d8d93aa1b99da9316c7780904753d4e0b45cf282b43a0c91bc9ff83cb25cacea2ea72563b2e759b69cabbb6a50d6a0a5ba545622e5ce576cc301ba35afadbfd1e26668782e1d741feed8aae894b564a425141442fb8470b325cf7c8e1552973463bf4e", + "67a2ad58d15417e418bb91d2df4b1310a0a70ac744bbb4245efd2ae642609079a44cbf6be19809a5ff7ad6847432368c9749cfb336ddcc0e6f52a699b910cd24671f38af5dc39268a3c87771f07d53bf220b7c2d5058cc7b0bcd492abfedf9bb295ec304107130f0e98dacaac6dab998b511f176d48daeb81db53643ad194690b6e28c5ed2927e09a1e959c494b90db401681f67bf1e23fe9ef4c903f666ef39332a91a25c63efe9bc518e9aff61842007dda72dcc0264aa47543c0a8b1f0d25749ddfbed487282241140d4c64def1831c4d75ca975fdb03258ddd013445e08bfb479a516b011fe3a12e4bfca439407c0022889e46914cd41a4d92a25eaa57a55bc7337e5fbbd11584dca34adb5643105c8171e53cf04b1412c3107e72330ebf1b52f524b4e72570cfdc0ab179991f3782d05091ea57b1a233048bf062e88939cfeefb61e8beaa90395faf61c4d974b23723a4a5cd39d70f92620f8f4f27bc99ca67bed7fb6e594913991ca3025480ad791bc94a0def36fca491a206440ec31e32bb85850c3606c875708309be63c2b4f5c477521aa08e1d059cedaafe4fbef5523b79f88b57d0c81bbdd09202095f10f13e2609e833ff41b862b2214c22e8f2b04a363b38d26bf95c07b184b9f909ad3a92122e158d3566d2204b22d4f2f3ce11a65544ccecb01a4a5ef62bc969fddcb648224a5c7bd94f8da9a7d4df393d880f537a377888874c19dad357a0564d303a5c1485c1451ea55d68779dc0c11c7c38025660684ba3f70cbbab00d15b34c0f2342207ad548eacb32ebad95292e85211a8669b586d05b0d0b9f278a35ea4d78e97fd5dafca6b72d8e1fbf3e704a60a8ec60befe2e3e4d3d37f9d33a0feb88add59f0171ddeba0b79a52feb9a1f4a7a6ee7c6927bd10968fba788a807409346a0fccd4f7daac3c8591fc689aed881829d479e8d360cdb5819d5eac718a6f860f2d9ef6a0d36ef6e10efbb37819bb7b03ab7649173447b2cd47f3433a2422b1611dff91cee0b10c6d060d4e84a9e3f4dc194514cb67f1e3985be05c845fc92b41955d0f61aeba6268789998bbf341a8b37af48f07b13a676a11d27330529cabcd52365842be559857cbc2a63a4ea1c77fa8619040e79705c5b51f473e13b73fc09c28598e070dbbb63ce884c2843ec365d4c5bebbf815ee3314dde0bab6b0a71a398e2d9ee8ba2f832863fae7eb0c18adcdd17f1dee0df29a8409acabf516c8e6dfea5a264c1c6657f774c86a14cf96eecac18a41b1650a9e652c6c9264b03aa2fd30e333a9f24cd6b0313358e3c00943a1de63ca970b7da2cb8a0fd1109cefbf12176f5dfb59457480428b194e88449bffd8b8d87d05d30f9ffe9ac3a7442b0df3418acf9165b14242489a54b6b47ea543fed5de74a00f61ab2af553b60d8d21c76c42052c72e4841bd94cf88185c39287c04d05f6336ae581cf7528a59b2874795caca79f5600ac64ad5820a91c711ae5a1c3762028242c5c8a9aae89177ec4db5785cd07402d45805a2e2e970059e4e6483074df1bcc01f57470fb66f45ab475ebb5343b727168e355a6c25d42384e39802d7b4a8c54ac94d82de12f8de13630ec8c19f008f98c505dbbfb21b363472e23d0147d1ac555f0981e2bfd07c62d097acf930094dcf239a40699421b207ac2575b7edf9b1d772ab066362820c182c2c5097a47d1dd25ca9e0dd9c3ae94e9a8f0dece74cdeeec3a17803d5e11f037820ea20364234079286a7c291f3424292b0eec3e956513cc6b078a76a3b8ab42c5fb5efdcea1d438f7ae08507275b48f9588a15be763ad094885269efa7330f6fc9d4746997c98d9f5feeb6dff2734d75afc6a11196b35bb9fd0c0af428cacef0df2c5ad4e5fb4559f0f93af2fafad6fb77f453238f409ec71a912350d7b62952e4858927f620d31569242615345265ff1cbbd7fdfaff35a45732628da663bfff3d3af3d7b537337754554458a2d1af0e16aa8ad9436096f42e243109cad32fac1adc58d714cd3d0d8483c783006991f3da263ef5ae1ff2ea06584e45849d64a07170675c29f0b2abcf1eedbb63b6f5d9dba600996c7d5edce9ac69448d05c0704fb9f84e831b60c376b8a5d33ea22030e2dd3dd421d8e0a810a77c085a3861fcba214a8baf592d624d673fb34f906581d923d80b06186db8ce5fbef2bb750166f7556adfe93d4951a825d55b0bf92c9f25776df784f6aec808ae221cc98d05ce988fe6a13ff96083dba15500e149409b54345274e3633fa8f6685d6fed40c20a5c5705f8b37099a5949846ca15def5a6a427eb4eec72747f116366adcb9b74d3de0b125bdee23ca98ee6312f41fa3d9bba43a8d343552c969c41f766ab4341a42ec4cd6f4d1d4c4b1f16979e5389fea36a150580418d95520506fe0cb1a1d861e09d21c57d88c46e10a3c5ad1aedc8f2743f5c06f10d6da9b2bb3ec783c6f5788ce9400795022cdcec197f9dd3ee4cd26531e7f057b6d9418a0c52ecdb35a24a2a079b3d396017feca8b31aa55e3d5ef79c9ea9ccc7e3d0b47f28f273276666fa1763b3a452672fedc94557d984c3353344a8bc9fc833dee685e33d63540d0801d8068cf66cc48ddcb0d42cec881eae36fc2614f96ad67fceb5c98ec33fbade0e3049178d503c13c2d5d71f32f4582d1cb0f47a2ace578b903796768a906998bed2995798251d7eb92faacc19255bf12c0024a94971c185841113faa288beb7e58d4a98289630fb3d230f936eb1b9d9c7b94b5ac9d3a211c0b454a26e29bdffb522548a65e8dde3730918fdf0575245e71ba013ce08f6e698342a61a81b1355d2483e97c06462cae1cdc7787f4bcee4396a08dac9c14981f2a8f4614a31b019c83782d5d8370acf9db467d9d95e8efbe44274fefde5860c2333cf81593a2ada9f5bb6c2362ba97fd7c3e5bc836c327c66b57c0f023efc0c0ff6feae0e625df2f4e21057060170c844c86412700d7d337b1f7835a0dafee5206cbd76104c5a36623c7783213f8dd457b5e69a86b74030a27b3c30074242b1d97e65a233885a681ec5a8532bce9dca1998dc32c6b40dd997b99a6ed6288e0b9b09447e356bc5345b2133571e65d47db2c736a391970879103d4137cab6c0724b8e67064167cd5521f32135fb6ca43c1e118adcded8227c9dbfdc18cdce154108eba5d8c60e5362e8fffc5c9ae6ac2572188617e4ce0f432e2476c74a4227af64b58e0ebafaf0b1ce01723ecd36a2a4167b7991e28b6a9e81992fcaf7b4b906d0361add02104db83914f28baea26b50561faa46293ba5247e8263ac0347509c36405747866d2fa2beef44f366108f6a4047e282a477c28654511075ddfaad9b9844e18e67320a831e647d923b2720d65ddd9ece165c222231d3c3e7f0001d15e3c690e9831ceb369a8edf183133814bfd20dd25d50973bda58ad03c4cbda8008556fc653ef401ff76ee858c1f79a0b09b4232768e72dd06e42078923d5647cb310bb644feb24d6b7e9d1167c3676cd96f79965a066aca314089db60bdc40c2be4b69c569ec76b3bb74a43fe731bc869c9222ab5404304a513d4f7d2ec5af278f7c3d664fcde579bba7bd472bdc00a1eb4c46ff69fb7e45e5712919e8656a8887afa28cadd66461fc57f53d574c92105818a89f210d7e8aee6de2e78228b2cb03b850a6e77627f70f51bb919bddf61837a978dd4cec2db138c657214ac07b67134bd53b071e2bffa3608a0b0bac88b0ddcfc1ba4dea17191c9ad76ab8de72118893256a7e13e15a3bf98bb5757a78c58328cc4b380f3786f22c6be81884d213ec3cc2784583a47a4003a59ebea08bd06e290a892c937448e664dac672942b068b839593c442f6e1d22875e01859cd24c17d108696a3196ea4794ddfdf25721d3dd3e754d1ea884e5086479819452991403a39014297fcc734e56f8daae4d49d5c47016fc3ead550783df895542229ff3b034b5b722ae2a2b04ba70e42c174e9ddb89ffa60024aa16f297ac9383b2ccad53de4bbe4ea2fa3fe3d059d16b4b4fe9959ba3c4e58922e7fa2673f50be5b636ee7c79b445471ddf5b851ec3ac505980bb184c8fe44c7776ae9aab4e66ce31fe1bc00efced390a82f96b4866e31ba3ff832a25b1e1d00ec44bf525ae523b7102ba60c1d3a2e2bed004524afc90a064b325a258eb36315b1496c748f5407e922914787acb8b47bdc495e521518e0637eac4b1b4fe1adede145181ec7ef038d48c473d6f296b349d7cf874d329c71f272883eb7e77ff303957e159fd417d5055d82687448950dd149e1074a1785518ebaf7ac167e07f1f559893a20d133b59aa294efebdae1e19a30ec9a3e257203eb9a854096395825ef4d1e4ecf1f8daeadfa049ea6c435c50d67fd21c6f6b11a8be46502f0dda1715f5349df5330454316498660b7996432e679c73f1af33e529ac669496bde538890cc093122842e3e2e4bff937708dd4b1b1d3fc066a63824266461e4af9245032d690aac0ea5636c29606473820ee57b112e2bd68c0ce1936b7e76a7873cad678b26b560d7bb10a7dcad3f69bbf226faf2f572c105741a121fa1c55ff30b2d0b7339ed9aa4c9a3671e6e4b572800afcbc8764b16f0a61c4c1ff24c3b64992cd84f39d1a4d5532a7dbd9f7bc847258a33c509a945e53236cbc46b61fc6fad662c523eef0c1eaa4bc0a49610c8d09659e7bdfa858d2494dc3da0a54fcce229951d366fd17f4120f27ac77e5e6b777693641a853eacec09cc4dc08ff6ba22295acec61c5e6215eaf2a3a012461eaade8faa9cba630c5ce2bee6f1a4676d54b4a38b7b5cfb6c98106a4882ed88153a4f0bad3e0f3d04dc1ae5318e3b8f4ab1d122a548eed47f70edad1a164a9c5c3eb10fdecb24b0b68005b2e958980481834c4f673478d3f47d07836d3c1c513dd920042381f70f1a68671acee2fdd453a7552eba497af27127999a13a33104f0086390e01635d1a0b79d92dd43211c74047804e82d9ab26f97ee88e664871dab52a2a79443e39f06a6e8ac9d5e986252529b389d9ed0b2f55fb16ca65f6e90cc9a149065f499630f973996c1e2b6c53f2ab391b7d78cc6926b1684d066a3a74b86b3b633baaf3730acd28deaf18fb926e1ec9c1f8a2345103cc4cbec05345db57c5adcf062412f289607f5fa41194f69bc2f426a30c7a6f8d1027ee8dc96c9957e90fbd9b16475b82dfd8698195159bd7b4860004beb1fa85e6843eca1acbbb0b8c7ec0b865ed108e297a2d5f915304167e18d01e51497e6e3ea76ae99bcb849f7595fa74c2a6263e2bef65f1063bce05483980ed51eac5289307117f17e99d761337e9b1fb625a1b900e6179f3b02de57a0b5f52352298c8a2d2c816182ec169d2b9c0490097ad98e2edc99c6df683a4b5b6eb73ccee0aaf07e8cf8f2f632381ac407c5c578bc1c5a8d0915dc231b01b92dbd25c2bfd412995780582793736572f1e23ef690bfe6872c2572285cd737a4be91f4dcafef09232de77b315d73f5beb23d03625e031d2438081222b063c343f52565ae314ac47a4fe518b45d0c12f2ceabc5e05c20f607b97035afbe0e29249e47961d9cf9b385c065966b0c7ea91cfa9ed1b55a58b9aaa9de080ca05c6405fdf15bcef74177226eb225a47d532bcbc82a5ffed7fd86c2609b146d86f566d0b84f638d46d6eb696bfbbc62c4fc981a94c1d6ccb9f3f7ed7976ea7e8ff1d2a2d79986fb27f1401f25d5a83f64844fa9e839fc8855007b417b261d325b6e7cb124b27ede8ad18d2b6da8bfc4d4f50c3960d5a1c82e", + "4557b16d05471602d2a31462e4bac9535c9a57389ae0613a674815c2ec10c19f529c9274896dfe49ab06889da517d482145ed8f57ba4b7c0434ce24090ef2459682a4f6342ecc382b4cd3409c3415bcb7f1bbaadfb7ec308eea8b6cb2912469b707c99a55c1754db0650616754735b85a41433a30b28e3946754f90caeb03c7579fc9982e6ec5501d6f23e0f2b6392acc435907d79ea11eb6955723a81c4f02bfc78e2eeb1d0408f8f06b4d2f6d20d90f7698c4e58bcfa993884424f8fcb602ef35d23737fb6aff220927e28c19043ae708fd9755256a8a1660d9c5827bab1b836a10aa23aea9c92fa3b25428b3791c5d25f3f1b63befd5480ac4192c966350edceea8938ecc608e0f063d16d427049ad62625f5177470e7a0d811e8d4273aea8f7377d51db07fc34d9f18497a0c2b5c0bc5e8778e06bf7460f0487eed54d661d74346eeada9090957159b86f8b68183e33d0c3fc134d87e068badd8789d4c7adb829fe08e4558bada5ef3f526afb2c7b6184244af0d07aa5cb525c519ed32298bb6241d900ead0532b0b1fc77a6577963e7a44627ed326741af254ab957ca0298a74323d2ee4f1bca70e20ff796491424e108e03c20f2eed7374c0aa2474a91f3ced6f46165c886a510734d606ceaa08822bfced69def33cea3662512fb42ecefee341d1b499b826ad882542374b032e907a7e6a4dddc4620a5d1002b5aee25711fd2dd6e9d4e90ee350f2889d6c1f4328e4b711fc919ef3c655311637b83b4eff39c157e0510807ec61714b843bc9eb22a0f4dac7e5cc07b8e9ed587b701d9aca2a239e76ac9a16338b74d50578956e06b1ac35ee3b822ca779922d89de7d915afd7d80831e8534b8f8a2eaed252fd862abc99aadde62d4520d9a7c3c3da86081fc36927de60e3479096a2b5025b9a789da01da969cfb0ab2f252c82db9e6663dce3888146b365080f649cf94f991312817147d8f0d1774d8d44ba4afd846060df2de1d1043659c3b94b1eff51fff84e5a81a0c635aedcf677285e0d722e3335449fd0f49a41264fb963ea5bba31dae469c789047812071d8853291fd8003cc31a8968ce7acb68a6e0172ba6ee0e9dedbebeb62143047336c5a91c77085afb01fc075938b306d7e36383ecdfda55b9b5dfdab53aa34000289c398f617a146c4a06404737600484d8d4ea960061ec2cb575dc485f65f275540d0ce7550da08417632b6f0f7d044f6f719ff839aa3e5c9db94d45225a1cf0bdb0c5bffa781572ad605ad37aa988240858c9493dee9f00ed281e93532d89aba5e9e59ec430cdd5edfdfc2ef65e094eeab71cc40b59c997943a0e0dbbc80f1e11834bf3b53153ba1c1f0ccf63b3c802439b2ef1430be6994300d9b2efe4b84e25bd3bf8a566d4851e7fff57cada544d722438e8980a31563ef0558fdd8db9bdd6f1a3e34f06104b680f63c1f80a08ec6ed74bca69bb1023fe63d24c7e7a14ce85db6e21173f2ddf14f233f3787a37e4b347e4d64907fc0a23c3da017c81c27df9fafd4695886d0ddec8c47982912eceef886ab5680a130bfacbf3c67bb4f0cc118274bdfed43bbc2ba56f048d6a390e48932469b30ac84fdfc2e812f32d00a85349bb22f2d8091e64282fca1b40811db756059de5d03861d6a22cfc6289097d23c26c5e3f000f9b34a0e1b28a1269d8673d09107b29ccaa1adc8939bdca312c69ae4a238f45410d8f1b27392d594ceea2a6b42899ee5c5857965b29bea1bc413da618899b1894f2adff3b3a7b05a626e50e42379f5d0e0a148ded33d815f59d1401b197a85656466eaf88ed30d1ad4a87985570291efbb3a2c6f22c0b111e65c843ca3c6179e94335f0f91d4696e1a31107948a042f55f264c32a35e719668483957c9c8e13fd01e5f751870a509f5f06ba41ad63cbd5f706f25b1e598f6c9709ee6bab627211bc38494962e930779ed4ea2a8471d309c4c4f0603238959cb13476b673489696c87ad9da5fef0d6467145a77ae0b1089c8626988278a85be3292680d9d7e4c6866f19b78595d611f15f9a5e37b3d145d5aff4a5b58a3286bd25a862904817afe8e9b9105584af15f54554ca5e7dceaa0fbd1111aae126d74f68bb6f0ce98094dc9a59a31d9526729efa171beda9ac5b7db9118aa94b9b5ad58dc20ae1c328e31269244d636139\nCiphertext = d248b9e47c303f735b0d29f6111a742d93509ae051466688d56b587104a74fab1b259da64475fc0d2c3e28d87ca4edfeaa5715c23dc0e5281eb0c0c14e22182bb02f9f7d3c24555cd6a3ff766c774e67730a920db5f85d47dc23bbbee460f0922cd7ddba81ccbe727b4b489e79a19db2d012dad2a732273dafabc0fbded3c47dbe5b6b585570c39eb62850dc47f4aa0c29bf5fadf334041fdd4658fa6cc29a81192a53dcf47c03ddca9d03b33b06e5b3808be77925b7e7d8cf51fa939e023161d969f92430917d73f3aa10b83d5b7402410280561a27c376ce0b5151a51be2ef4eb9057eed25a0715436233615dcad1559fdbd81042544441857cdf46d72f5f50ee552cfd3bf166c530e57fd97f34e2e71bff8a90b30b4c4cc3e843b0f06e4eb2ff82675e428f5303aa9141dbeb615cf6aca5540fd7cb756fe5f9b08a4abdc6eb90b2eaef51c21eb9ae79a0e44b0755b3ed48f5e6e57f3148ce02501528dd3dd2b0bbec2650710a183e38510990002ce6498dc5ce7bf33d699dd18b66c0f8031d958b11d678674c355a635f4b5e8d863785f5dc2f99eba9ce74595493c017697344b651dcc2a0b1d5386b73abd8bb2dc77a2d92173d3688d0d704da9e44a6385af9fb3a81db68822b1eac9ab284f0155c20f6bc34af85d8518d0dfd32fdaece1379abca339a00e1326b624b3e4050be5db8dced5e6c4b88b82b6ee2a48c373d236ea3565ecc072e953ffe01b624c6ecbf534678aad9c3f8a07d7dd7232134b6b397d0c96ab5f795f9e3af65b96e7a765283d8081dab9f953113abe06e8d150bf9a8416d8932fac17b032dc346be43736dbf066ed239328803510f6f62bc8abc92f6df9a82c02cbf85de91739bc8d7805d392341be99798079419540dc952fa0d3ceca4b806ab1db3b717f0d720038343465a8bc0da8e8964e58634e8a2d6c99230af2ac7c89acd3f86a22075dc40818028f3c632b36a39c0e064e3ca2a078c617a3e73aaea56ef11114f9efaac90a3ec8f8d9b18921a80d74b09ada83efee127f41179dc6c19c7965f3e7f43e22f636534b123e9246172f9920f253d2a2652a5e8c337ff93b2d479bef5e96e972a9b9cd8af057c750bd711010d59ce065ad50fdd487b5dde616301d0ae6373b6f9efae99d8972f242dd7a6bc61caee70201869be202fd384a992478dfc133b84171f013244c5d17585934aed3b43b818926246227d255bf832ff481f5f8d074ab159a11d6d17ed0ac50f727b870db966e0373bd3b1eecbf9ed66aa66caf33ac57cffe4ac6df3cf7b0e54ac54be4f3d50f61b33557c2990c908a710c85000ef6fa62716960daf918ae3d81ee60b3813e65673bd911ce468510bd230b9c2d215afe86ec12e49e0ae87e4235baf3df237188f5e0af2e61c22a4bf77190dd5dc804b4cc330b360c3dc093ef208c37d299ea0cd2ba906084011e16ac5f4fc9646538d5b538a99546d34a4599c8529c1524fc4b394d6a9cd762855905233ed92e72c8b538372ffe2f0df7085eb074616c7e695d7de40779e384d5fdb49fe02385424ea991dc05c6ae813f76c673eb45d6105bcdcfdbf04dcdd20caa6e30efcf3537bcf72947e1ac37d1e8c600ba9238569a4b3afa590d61acceb2572da85885146a142c8f8c60afe4d53ee4d61f33c47e5a99da9a346bcfbd013754ef39a4d7f16c4c5fbfa53d7f180c16e2b64f97dcfd65349939b5fc167c7a78926f638f1893fe9a81e897beea3258a4175d14f41dc123ddd846e45a87f35154db8a5ac27c7a0fc95d3b3113cfa9e7c828f83a1f0d91ab7789c33be5f55ecbb8eb0c81bcc0fccc880011b21000e2f10773388b198ce79c5d694472d3ef6b2e55c342b29c70e4f33fe59e2e0bd3f9ef617733dd3329a0e426338d9c007bcdd382522cb96e59b223825a39b01b52809f5e8518f64b81c99022d8215b5c435d87cc1a57bd440b31a19b197b277b2072968595ccd64c135ae1b218046e27a7f2685d013ce3173efd07586dc72a28ac4792e804d44f9efd785ef005213df928560a20daa4c24ab07f081479270a0dcee3c26331c48a164e4b9d79a7c30c77ab06b00e9b72c190d35fb873bc095d5e6231a89b52a0737a99532079bcc72ee221b48f0d0d9ba9105f981beb4225f6efc1230d6da10fd2b58a65112a98e4bbbe1accd6e8589eb6d9c771bb911cccf42aa6cbc68d1976f0da7eff1e70277e8c5f83734ec1efb2b00708fef08e986bd6519a0fa4b5772e585ac8e37fd2a2af07aa382579498b3b75863fe792461492b8e71c4a1a2f4421705696a96601317cfff1632784b5d75fc2036ed3fa650354620781b9fcfd53f1927223fa045edf4abe7b2144512f3e3aee99f7ac3e46028bc2427aeb18e9cb40db57b696ea884658abc9b7bae0d8117f93074a3ef903528f8b55c7687cf9f0119a1f246cc9e993219c6384359e7e5e639bb294b264048060224ae168d7b9f1f795c07eaafcddb10b61ac2be3ab3e1fddf75c1f47559f38d24f0c773d0e8bc5fa85d7d33e3aa8d0f15583b8c1e7aab6f5d0e085b7175678bf11cfee8eb069b78220377819e3f4d28eb833d3d21efff543d5c6357fffb4a8fdd6ce399fca42e2d71c53c50f6b20bcbaa1650b57ff483837c39a37d5e978393c332b43021508b8ef27773164d69d0af3c0dfdc125cf30a7c49a7d8e5320d68a35e80cdfd62a0b7ce6a412f08c8062e35265fad5d1f226d590e9b068d09e48772711d7dbd786a38c0325b3d5665c2ff45ad0a20c174dc5739896ac727b34f11c7af299d36d30c69bbdc35770138cf891cfdd8123489fdef2dfaffa9c2548ebd60b0f0bcedff44691979b4e92b364753120364dc2e3b895095da828e8659575a85cca587ba05ca625480f977a6fe10181ab6ce005defbcd8894f8c71811909cd6b56eb7ffe327f46793a9e98bd7fe8951400276bb9c7607f8ba1e633034b73d7f0d040197c3f346394eba68c8accccefe05f59cb7ea9ab1ae2e172d8f466ee21c6531cec2c9dfeebc477a6d98195c28bccc1d5e23ae50e3a1ddd7de189e36ffe0e387df7be43427b194b16e18b42eacd517bba78edc9f56a2c7e89e6f13513718869da7c8c529bc337217a69e14e35cf97ff7db2c23700347f0a33ad25a299fc52b35f63949735ad864aa127053797541864b07168f89ffb7ba5c9a8bfbcb4248383a95f45461a7aee9c658c5679205f47144ba4a06175e746037b8cb6556f06405e0d537d0f2bcd898dd5fb987d96dbce33001a50abff5b9cb0161dbfe30f5df5a161ddd8a750b0cb33898c110415881fc81239f2e25440bca41a5bc46fbd3787e6c8fe8a463415cd9a82be368a02566da740dca8e40e686e1213d9c15de2d3556a1e1180b298ba3074b4ab93e469dd9a39ac0c8a173b04a5ad913e72e4d7b5ff520f108e1a1747c11b6b2fcfaa89b3ef7e669f8ad9620364b4f4f0f9ab274e76bdd631df033357a24723653e427324d907a9eceb3c375c43ee36cdeb046a6374be19ab04922da93d4dc07c5914df06fee97dd813f5fd501ca75e3c5ad53574837f2e51ba6a257134e8ee0f4127c59840ba8b1bb13592dcbe47aea50e453c7837e91bb12ad1", + "c74fd0f149479bc0334c511a822145690a3a408caa32671ed05c2dd219ea360c67727c1fe6a6cd842301761e94bedc73f93de7091b8b6d2783a788313b2fa12595904bf5d1167a5ddc4ee151b1522de60b7293b72a62c4d08b396ed682b6a6262a212ddc8c70dbec1a972cedc09f593e21d843279561884f9759a593da7b17a147db7559f19d5d6f43ea98012872f974306037dc0d344c55403b35a5903f766359341bee5bccb696fc0fd1c7aa8803e4c2f9e6e23d386d3a202027c5792e355592efab9330af330392a7c91e3cacc4e645359edafd78b77829374cd4b644817322b7650696fa763a0cc7143f9ec7e2f6ab3c9ec2443b0c0b0a31e9eeafb7bb8c375232357f08256959a10a6d4bc98d6cd9314a2ce7feaa8c0eb1eeb15047f715d6ae9ebd64238d648ed6bc50617a360d8ff9a01aa0ce0e29338d34bb9612751445372ac6d74837c7d2d67729760216ee33476cce1a154086ec31d986cc5a14e86561c6929554fb280646164bb03e8e52588a1b947960a77d61c2d2499212a742e1a5b78805b5b64fed141d3c4834301b8a8bef31ce65edb539fd9469b590a6980d0d1bd29e34a09f87438059a09b1ea234d1bb29882e67599fc1e417db9d86332077cfb05fe440ad1243e26a67a0ea30e63cdee8850a543d76e810140547412fb1400ac87a10e3bc77d3918750a5cc3e7a0efbd736c7ed4139cd5855ddba47143362bf40b91fcbf27222017c1552360466483e67ed125745724cc713c713dcf7ef6ea3081d65d8d78b903382717848bee7410431e1040ec92373f75a1bf229816f55dcfffb6e6da33ed8e1e8b05f9348cdcd6938f053eb9f93e0de639e922627bf61a6688f9649bb9cdfce6236a176db8b9b53ce4b5f9eb9c0680c92128bd327aa7f04a745025faaf117a18d5664027ab0e3f5898b834e1a75cd4b4087637733416f8bac1ccd67cb4457005945676d03f76fd0453fdb9968643fec98d28da7c8cd7070a803b14a2459f073ea075fd023a896d3306fdabc54416e95907103cd2fb642e301c71cc48e8eabedaae356582761a14e0b3b0ef1de06002c2acf594c85820ae3a094e5b4680566b592221543c1dc5192d6b208e86b5aca91d4e3454564eedb3b8208169ce97e1632b864f1d9d4c4c4c0fd4bcc5206e8f6d64c7cdf212d718cb5b7c7ee21593ada3f33f5952e12bba4f46cb99044978fe75349c6ca735db35891351d7e5f02a93354bc45a9ec756453f053cb87430b3e9211807f81ad99b6fceb8ef1b2d655910e1f5fd22f2ee90e42abab230f8f39a8345eed6ad294a0d32416a253f829093ecae209bc1dbfadae04a373080f9ea8394a28ddfe1134309bb53ae571d2019ff2bd4be94f8176d90987fcebad323f0b2921b85b2610852973f383a2ff4a5fa82a77b13cfd50a33f29164a9ff409422cc4cbd772132856cbd08470b220ace957a6b8e02c8003d750539a38a8df19a5b662907b72e3098d77c2fc3ece0693b47ff19ce911a93b6adce75653d48ace6af10b8f1141437f9206658707b16794e349db3f1a02606ea167d0213ce3644f64ced64de3799b1729210fc31ba1811b0c226306f2466b230ae35e6d8fa11c8f932e27da8cb1bd311919bf9178ef08bb7a2b4ca2d2e6e9585ee9f916991cfcd4862f5de9fbbc63bee6edbdcfcec9173a252eb59fc6d6e58258ca8b2a4475acfc1e09a0c9566d23d92e9ada97de51895bfb0867c42025c8d089c65bba67f4dd84d7c5155a930329345cdf3b1d6e910e730df273e183190beb900344bbce8c3bdb13a7e4ecbe967a61d47921aa55bac2bbb24e3e03d386ddbfafb3b32235b5ed922ed6ac2c89ded1316b69079b826507d708a6cca14ce2244a67be90fb91ddcb0c97432703729bceb432bc856f5eb9d2f169800a04283b080f0e053670a21468df9414fda9f4153eaf1669a19ede7925f832280800f0063ceee34b9d3b0f8da2012525fa7927e76bda71954714d5f51405b920391eca2ad71160acef4091878b907974573b4cf1b377baca0340ab0e4ec546fcaa6130603ad633c3ef980e88d8f44ec5de743cdc6cd9e0e4cbdb97a5c076be9ada8f26bc54d711facec16a2401292cc167bb98cdd320ec9321414bd97498f6d9b54dbb45ffe4b3e3f88260657ee23e19de48a93595c8e3a289a02d76a27ceead05d591633464709aca117c26aa49b64667f2a3b6371984f813d7098fae7a6ba1841775b52314a06c80b4c994ef8100e233ab3115ba2c39b97f2d5082a145720ad0b12b8a7cb275ba848b3fae14fc0c82bf0353195c056b302e508982f73a8519cca722892482b9d9e6a58bfb4d862fa393eabe6aedeae1be5ed772ea3c94a0df1d9684a131c35246c68b32e46aaf89f3649e58b2e99bd6bb3923d3ab43cbf73b6b3d19fe3b62bef178f46c79ba85e23ee4b25bc561e8fa97f51605bc0b210b02aa28242e81dae9489076d259f17d25b93b0e8a2010584d907314e3bd55482f0fa43d37ae9535629d28d6f837360bb35ec869d2a959789dc49b9c8c515942a1e03650566b736551a5180a60279bdb0ff9c387beebeb9e59ed930b3746464a010a6f7ef1de3c7d76fc6899b1e5ed98213813ffb333d969ad72fd8537ef4e12ca7b78d35c24f44ac82da4a7116492ca2efd86ee6a4474014e72a5cfeee7f729b77cfdd1a5d10a03f3cf28f1d314fca36d31ef2ecb3cfccecbcdfd22367b0a0e04435654286ae3d4fee13f56bb7cdab40b4e1dd01f9ef857f94a67c1e237e24819949935ff3bd73b0461ee9020fd0a2db2cc6312ace97e4a8a33c295271453a12822db8d1438f22ed0d466150990dcb39ed042424eef7a1210c83224c856923e3251484a81a15cddb4d7ada8bb7968dcc8f85e39ca99ece8ce2ed7753fcee6900cc9b7b5691f2d67ef9be13f70d195bbd0047908025df01b4f4d581fd59239836578627d9d585ebe9b053d807e9d3ba25405029a148938a746636decdade02b1afb5ccbf2f0e14a27c98a1e130d9208bbf7da4bb4e572927eb348568921d4a3309a2c24f367c935c2a8e1524c3024ff350ac7da8d2849586817bc9d46a08a21aef035a6151e608ed93b1556a484e455819f9ac2fb155020738962e7255a82a0854b31fe20cdd351c10a33eb693c9be1a51a932e04d0364ced41ee1bf800d0c12ab5eb37fe52563666e52827720e856d4f24eb06e0aba446910aabbe36513f2274362fedba4c19398433029495284ccb499bb559a9cdbc94a0d1b733136969a743945a04e1d2d4e77fed21550af35f22651c7de802eab7a3942d7ec55a3a5002bde8d5cccc1d4ac4bb7f4926615fcece543fe5d9092d2c4f50d94fd9868775a072f4a5bcf2e5fd10795f7f172a3341ce33505ba68e7ebedc9c1e9165864244ed31bbe5c308dceff858cc42010ad8c281a24689cf2dee8a549b1abab9981d70a912174944b403ce664d8608b2f723150f5c12164e4caf28676e7a25c3928ca2a4dbe96355ef8f282e57888d40715df07bd8b5895549ad957e758abf868def1c1f5e260d26498616e2ac962bcaa33b879874569f198a91ce4e50fc50da77fea1df9f9ea900c834dcdd462d338efcf8e612aedebf254fac596507d175d30a90543627cfcef6852c7cda8b430e255c4d6d417de31eb5dba123e3ce9e2269867d9a94fdcd8ccac40a9451953085109f5ae0c3e04daadb4a2a47b0e176917660eb3c9f1aae0ec6b00635fa387e056623947c0621f0a12e86fac1881ed1dc1b9f523388d6b6596a152b3e732c561972879dcd3f0232ef0773a4fb195a90c3186c4688ea58967ce7f18386b80bd38e90cfd4cb899337ab27cba8db6523e979b4c449645bb2f320ccd28578bc7ec38f47225273fa61a2e5df97c4d76c556fbe2b0fd30e615f5fc82c3de7194caed9f5946c151c22b7a0c48f4a7cf78aa153414f2913c5eb95e3dbcea7ca544272cd13a1c52fa87759aeb430aab144fab418c835344605df3a044825965ca15de6ba0e59b2080f5844b2d110d71587e19acf14264cec2de5b8c77d18893215d1c1da0a940e7c2ee429a99e2633c216aecb7675a2314a09044951ca5a8eac798f8878fb5ea65f4ddccac53ee0c786e597169079fb6e8ceb37a71580b0904a97450909ca454a690821e249aebb75449e582fe1b30f1fa9f6464bdef654daa5ede6d4f223f4589ea25a25f4672cfbe974d51008bce296628556f55d26646e40b59f40e3149273760b40806ace3b5171e0b79865c6adb53513da2f24c4115de243150cec76107b48ca8da19117f00b5870e67eb8357e43c1b7b593c9875795d46ede26a109e05406b69fda988947e49ab195f22454c3c743c2ec51b91370b4df8d38653b353e51bb83215d122bcfa591009c007bbb6124bc590fed3f9c5699180b3b1424ad02f7c90a149b77d22dea5c996aba675c2a1a20e206d9c25d9446247d495a26486c0d0bfb09d0b5a1a177a09fa749dc36cee73af0116a6b779c2b827512a04ff0f60b483edbcdb33d2a18339463c498ae67ffa9da0aa3f3beb6bc99212f9e6961afde89045520b1f3f2e2761666a333d76030f443f53322f099035584a60978ef8b49f46d7d4d8c5c758ea52a04b59c1a3a1c2f9df3f3b6f5c45cf4b3547043b18c1d615a2c965c3918d090cc72946e8fd0b938e60e03464f4bc71fb719a1d173b0931930e58bf7f6d4403971d36b40f83be6b57244a7029e1d41dc908764d57a5442557218b509faeda4e9fcf31debbc54ae671ef636871233f29e0013c0e33933543f4b59df1978ec89b109c3977b0cf938b7f6166d6c93be5e87684a703c8b7b5fe1a8bfe153a179b55575ff05e599b39e32ed10d958699a1ffe07136081f0719b18c69dc74f66f211103e9c544f3c81a88ba9f66a9bc7017d9ca9e2cd97634052694a598476b99daf1cdfb6122869375ca5873d32d5c1e07d9b5b380b4f09dbe04478cfb1a13853eafacfed70c8abcd444ed095f78d07c0e8b4093be95c3aa24b2e5b6bfe3a06e9d2d9fedfcfeac4cea2490627e6da6a5cca383351952f654ce2b0ad359c0f7f4ad3f8d1d4a030a947d4a2e417bb79102729115cc8b6558c3362b1d805fb48ce4858deff97677e60375ed13e150a12ee7dcc8ccc64d9710c7f516555c1f7a1a08f0d7c6fd21f864fcf28c8f748c40494e01fc32006f977a5100577f86a484d11b82c90cfe6b4d6b1902fef486cc6f3e033904e150e67283e49a5382961dabd244412ca9657b48796e476a82443167e277d5a65c0c563a6abca77d316e5d3ab639a1ecfb1110af2d29f146508bd9874486dbb56328d6f59479e2766692821660462aa60b6bc8a710707ceeb0ea6429e5113e03c9f41ce0d69c7589deb547527673e8a9f9a9a74e9e4bbcabf2e306b35504c1da99730ae86e94cd047b2e6ea5e97e63a492430d37ec446434fb3b066adde08b17d7d903ad194a4a863d6cfe181a45c8c97b5062bf7c4e44d69c0d1a7e1f5029b805b7c21d1b5e56e697999a32557870ebaae8d87dcb5ca5eea2c5547a16b3f30ef9df8df821028c106f86e091050ff8b6ea4171e59dc2592d405073bea53f8ea62edf112dfbc7ca69809db8005783d63557d3d90d123a944be395c1dc3b5e1476dff188346327769fea65f3cf9363e88ed67335870ec8ef13eb9d9ff5317c4e24dfce9d11699e5f47b4233cc8f9d1b915e716a5730a5898ee65d30b1628b484a5e82eda95a590964a8d8bc89dd3c5cf6c4f9137b8c6ee9d6a692e0c0d1d858dd5b3c12de48badade4d01bff312c56ce3ddb34b0fdde", + "3b0c2706fc292b9fac7e1a0dcd0b6534c968117f7de15eba84d2754e4bcb8093a5440297605598659f686075e2b1b464b6b3ec68abb13cde263b1c607545c45746338b9b207b5c381da690f653b35e363e1249551ad938b9fd7b0a944151cda07127bf9ba76958e926472f4aa1de8512ce834cfcae5414b226f23acdb1fe5cf685d2201b78167ad35fc1da282744c2a43cc49d49242f968f7e06de14455e7ef5adedc5b33184346018114e2d1fc7a5349e378da9b2af5b328c213888652aca9f1145363809eca7c1fd8e64a5cc3255418736e048a731f3053db77971f67014e6121a8e464833e5dbd02ea6caf385e43e9f378bfba657986bf852b32adb55e35a2675bfc8d70d43a902032a61f59f57dad2dd7d7963322136233200cb9a90c952074e9ba0fc0654f1b6fd6f7f0eb77c0fa6d8143213ce6e8b0c178f73e17a7c64839f9bebca2fc955ea8ae406a13b80a9045fa8d129fd859faa46fd27c48bde7b890f98ee938c0d78889f84181ae2f5711304fe554d4251bbc6437ced59d577a2a1f26da736193c3674adb13cef9f4cb4aa6585c4d6874b0309ecde300493b1642c595746f09e03977c8902f3a4a877db1153b248f295a0ca2f1e437d15fcab8fd77c5f967304efb5c4920b990674ae61b954af40be17a8559dc377c591b68067fdcaf2d27bd9a22041b981a84be3de50d5962b58f8c4a22fa05192c5ac99a0a9423284fe62a3a59f085136cec72cda2a53af106a2eb5bda28b6e02c299118cd91714c2e7d045346c78d9ed1b41c73231a21e42c298949f70122277f4134ed5c56639edbf3c3e717310e3d1f03dc5a94e64c4ce148bc5c6bde64eb80b17d5979892786a31225eb89bf9f5a582bcf65b83ff7aa361ccd9238d144f6a22a3f77dd8a01382df4ee90a2057dd310a6b0c4b81dfc92a2cc0c606d3be8b18fbe64ddfdf2004eeabea892be2f914edd1edd8e8829dc7704d71bbaaf08c41824dd0f4b34c9eedead9e10e53bfc6fc0bd37417de0c5c71cff0754d672f29c262d8e27b524427e12bc4e4705ab311d3bedcb1ddd09a3ca0c268c05c64951b7d724a9dafe4d249aaabda91d68633aaab845bf78f9a22d467c7e0c5fc70fc9a318b01d7492efea7fffd329d70692e76647ae665c62b280da0d62f870a52e4dc4cd92c9150c96aab16f8c23475e3152d4debb41b6756f000c3d8aceef18b49e295be7a71da1eeadf4eb96509d45d7cc42af4b7013d8bb445f577e8d4cff92770b8ba0e451f3e24c6d981efdb68c7f2dfafee40b8a425955796e369f0d4da3e998c1626ae0fa583334475f1fdde68ca211c3f2e9afb003f553191702e11f8b731c89ea26059ea4466f2bd0a1a5601025ca9417006bca5c9a57dfdba44c603ef9ad38922623b40feda036d84425c47fa42973e348a180a7570e1215044c375313ab08d6f521052dda415707ebb74d6c4774e039bb04cadc2799224bde1802e2ee2a018032e3a341700c0fa2aa28bf93cc479231efe7da0e9f68e572415348c08cf648117e9b6d1267fef6617f5927252c86cc087775db3e30180feb5ce7e1ac9c3761161e07a4853aa6d97e525aa88302954cf9390fde81f8e11d97a11c79e3bad261364c18890dd1f8fc71127edefe3571518a42be611a46a0426a33221aa25a0ae6514daaf96038cb59aaba898de49e3b215a4464e0af614e638c2d9b6e676ec427fc906bc516331a18121f306a5246d179e2d3d0f38ab8393f7ea5a2d24585e7cca649637b9983924a15483c167e8780f8dd7aa1154cbf731745a8d8d54a8c4f8d854371bb8172303f9ba3c8c7cfe8c378ee56bc35c6376aafe907d3294ee9a8786281b7deff78ff125761f1a31d0e8fffe04a52a7574eeb8679670ca3bfb740167a559488d4337819613d32752d8a89013622f6a8d70f3c64b84a4215f4b7bb282a2d17c36a326167e3270757b8f1d9a0137bfc5ec278e8ca35a69e49779cfc25b95a89cc18732b5b9d1986b18878c57e118506909207207ad0b4edf32fb2b35b6e70546f45d0849bd139ffff9d8ae547787e7b51403b54f110e2ac65468cd0910d80a4e321deafd46e9af19609bee1efa41b762b8ace989dd681503539e7d9948664cf7a73ffac9ce2a34b514253c4f21bbccd38057a6d68732930dcdfc9a32219b53339d100db0037a8bbd101e71f5054f3\nAAD = 7b3b9c07148fcd897f657ecfcc87e530191536b8e77f9309e8d7323888b3b21477f2ab7c885c105d9c29ac96aed23b366f9fde4177401b7038c6770c7bd2ee8b4335105cc0eab9e367f0cea90d6f1ae3fa76cd21ceb9f3500ce7fb4b2a3f9e90f900a231ec693aeced7afb6821391d1f5b1b957895777aa7a2b71d9571c00336f26d54d756392cdb74bfb67d5a621d517db20441f74d0940180baf613b09452f64224f8af7bbc864ab4a8434ff624d0c0646ee07132fd376506951899bde975df8c836ab4ed9cc084f1f6d500ad56345d2f250a0d6991b9e458c62b6023191f341c8659e8a38c878cfac12b032674503df9c9bb01c4340c709eb6dd7c74907d769a317f4dd7317843c47bdb4c5e1f07f2380d464b0c47269389cc8a43a09adba86f6aa8f44c8fe514e73b5fe8d344769c1aa20a4538ecfbf47562ca79fa497b0f02f103f75522db9ead50d56dbe86997d6085f1b5aa7a4cab9e51a1247ce4f724a14983b6bafd17369fac973c6be268e20d800de870928e100990ebb0d3bedfceda36c64be3a729b603bce677a49e8caf282c9159b6e3e1e775129bd30dc3f5c9849535d86a27474be03bb5749b4c0115e2614f8feaa7405cc69b1de479b3b57e551f876a9c8c57ab9879cc68bb2ea110b2e77e59dd6a65eaa67cc4d4b2f4d6e646b2a298d3c80fb43969275d4414734e74726145dab06124c040656c39a94846e8fd58d326f4f9eafe5b95d85254765a21993f55070fcb9e85db5d42ab6b9464ce66de3f236dd2a0a26c4e5535dbdcd6eb350209a65aee785c6647ad4103d092a8ac932470880eb314f7c98cdff34fdf35ee2d36f09bd443b5defad7a5acb9df55965421fd043def6f4771e1bb27385b30ba22c0d8972aead6b654085a7dd3b60c4004a0dae22e25100e54e0badd0cadf909799329ddff699de8066dd6c3822d80c73c52d87e6fcbdb2dbbf852e37804b1256e23e76dbe43f30be4a577bc23c7941a3d708d1e1f579e9c6eebc219c74768168f6790a41f883790e08cd1e88ad09a544eb97b3d1d5af67eea666b9c027e5c7c976921189b955a9e605f6cc9c012c1c2e197c5b02504cb9ffbcb0f3ed778d540d5194fdf5d38dba6340c93da7c5501a082689616f337d8b59c2a92c25e777515726e1d7f6cc9552693cc7c30f1294b37f97d49814250d6c1e3eb335c5d214ef3641739d508b87106eaaf367902433a148ca962ec694409acb82d7749e1c88938ad382d0ca6e6cbe8255746832fe737c3e71dae8397f260c98d4a292a126ec21935c24096d2f91ae114194af659455d8a4206197495a28474dd2809debf5f550d77ffac2b0db521559910c352f23472d7aa9f4dbbdb158f40aa36912cbd918ae4c642e76d78d57ade1075c4fe1086ddee3d554353b4693bbcef1cfa87e49890838c36156af0edf384b0413d6d7aa\nTag = 51cbcf4a2fd82f221de1bfebf86a8c24\n\n# OFB tests from OpenSSL upstream.\n\n# OFB-AES128\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 3B3FD92EB72DAD20333449F8E83CFB4A\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = 50FE67CC996D32B6DA0937E99BAFEC60\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 7789508D16918F03F53C52DAC54ED825\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = D9A4DADA0892239F6B8B3D7680E15674\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 9740051E9C5FECF64344F7A82260EDCC\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = A78819583F0308E7A6BF36B1386ABF23\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 304C6528F659C77866A510D9C1D6AE5E\n\nCipher = AES-128-OFB\nKey = 2B7E151628AED2A6ABF7158809CF4F3C\nIV = A78819583F0308E7A6BF36B1386ABF23\nPlaintext =\nCiphertext =\n\n\n# OFB-AES192\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = CDC80D6FDDF18CAB34C25909C99A4174\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = A609B38DF3B1133DDDFF2718BA09565E\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = FCC28B8D4C63837C09E81700C1100401\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 52EF01DA52602FE0975F78AC84BF8A50\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 8D9A9AEAC0F6596F559C6D4DAF59A5F2\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = BD5286AC63AABD7EB067AC54B553F71D\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 6D9F200857CA6C3E9CAC524BD9ACC92A\n\nCipher = AES-192-OFB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = BD5286AC63AABD7EB067AC54B553F71D\nPlaintext =\nCiphertext =\n\n\n# OFB-AES256\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = DC7E84BFDA79164B7ECD8486985D3860\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = B7BF3A5DF43989DD97F0FA97EBCE2F4A\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = E1C656305ED1A7A6563805746FE03EDC\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 71AB47A086E86EEDF39D1C5BBA97C408\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 41635BE625B48AFC1666DD42A09D96E7\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 0126141D67F37BE8538F5A8BE740E484\n\nCipher = AES-256-OFB\nKey = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4\nIV = 41635BE625B48AFC1666DD42A09D96E7\nPlaintext =\nCiphertext =\n\n\n# AES-192 CBC-mode test from ", + "upstream OpenSSL.\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 000102030405060708090A0B0C0D0E0F\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = 4F021DB243BC633D7178183A9FA071E8\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 4F021DB243BC633D7178183A9FA071E8\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = B4D9ADA9AD7DEDF4E5E738763F69145A\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = B4D9ADA9AD7DEDF4E5E738763F69145A\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = 571B242012FB7AE07FA9BAAC3DF102E0\n\nCipher = AES-192-CBC\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nIV = 571B242012FB7AE07FA9BAAC3DF102E0\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 08B0E27988598881D920A9E64F5615CD\n\n\n# AES-192-ECB tests from FIPS-197\nCipher = AES-192-ECB\nKey = 000102030405060708090A0B0C0D0E0F1011121314151617\nPlaintext = 00112233445566778899AABBCCDDEEFF\nCiphertext = DDA97CA4864CDFE06EAF70A0EC0D7191\n\n\n# AES-192-ECB tests from NIST document SP800-38A\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = 6BC1BEE22E409F96E93D7E117393172A\nCiphertext = BD334F1D6E45F25FF712A214571FA5CC\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51\nCiphertext = 974104846D0AD3AD7734ECB3ECEE4EEF\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = 30C81C46A35CE411E5FBC1191A0A52EF\nCiphertext = EF7AFD2270E2E60ADCE0BA2FACE6444E\n\nCipher = AES-192-ECB\nKey = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B\nPlaintext = F69F2445DF4F9B17AD2B417BE66C3710\nCiphertext = 9A4B41BA738D6C72FB16691603C18E0E\n\n# DES ECB tests\n\nCipher = DES-ECB\nKey = 0000000000000000\nPlaintext = 0000000000000000\nCiphertext = 8CA64DE9C1B123A7\n\nCipher = DES-ECB\nKey = FFFFFFFFFFFFFFFF\nPlaintext = FFFFFFFFFFFFFFFF\nCiphertext = 7359B2163E4EDC58\n\nCipher = DES-ECB\nKey = 3000000000000000\nPlaintext = 1000000000000001\nCiphertext = 958E6E627A05557B\n\nCipher = DES-ECB\nKey = 1111111111111111\nPlaintext = 1111111111111111\nCiphertext = F40379AB9E0EC533\n\nCipher = DES-ECB\nKey = 0123456789ABCDEF\nPlaintext = 1111111111111111\nCiphertext = 17668DFC7292532D\n\nCipher = DES-ECB\nKey = 1111111111111111\nPlaintext = 0123456789ABCDEF\nCiphertext = 8A5AE1F81AB8F2DD\n\nCipher = DES-ECB\nKey = FEDCBA9876543210\nPlaintext = 0123456789ABCDEF\nCiphertext = ED39D950FA74BCC4\n\nCipher = DES-ECB\nKey = FEDCBA9876543210\nPlaintext =\nCiphertext =\n", +}; +static const size_t kLen20 = 455619; + +static const char *kData20[] = { "# Generated by\n# go run make_legacy_aead_tests.go -cipher 3des -mac sha1 -implicit-iv\n#\n# Note: aead_test's input format splits the ciphertext and tag positions of the\n# sealed input. But these legacy AEADs are MAC-then-encrypt and so the 'TAG' may\n# also include padding. We write the byte length of the MAC to 'TAG_LEN' and\n# include the unencrypted MAC in the 'DIGEST' tag above # each test case.\n# each test case.\n\n# Test with non-minimal padding.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nNONCE: \nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: 144c98ca1f\nTAG: 4a40ffe530b338e5173a8e62c8530b0c14b15046d12f2ca3158ad71effd0f46b29b3ae\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with bad padding values.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nNONCE: \nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: 144c98ca1f\nTAG: 4a40ffe530b338e5173a8e62c8530b0c14b1508045d58f4bdae400\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with no padding.\n# DIGEST: c6105cc86e18eb8376c16ea37693db5c07b77137\nKEY: 8503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371e\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c748\nAD: 1df3f4183aa23fd8d7efd8\nCT: 17944422f667bf1356c234189f9c6cf7af52b2832b2fbaa990ccef4e7f9bc3841e59e25c00e3686d5bd5c29f\nTAG: 3ebd1b0bee840e8a6e992421c62de5a8fda3a82f\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with maximal padding (0 mod 64).\n# DIGEST: ceb2d295bd0efd37c6c34dab1854c80e986174fc\nKEY: 37446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11b\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba\nAD: 2fd6773e0d0c302a5f47e0\nCT: f2ab16ba87c52d066c0637d387b89d700a66828ef231b480f39aa08ac2447c8ddd205d1a95da37f267c06a1338532de890904f9f19c930adfb684e81cc06bdf2\nTAG: 3ff610fb9e208ff6ad58b78c5b2cf54b997eb3f24ac0171229ff7ee9cd5070de5a604f78b35b6cd25b3f2ab487847ca1e3928bf7f19bd19c9c9a1015dabd2de426fe57d342009ae4a2e67fdea378f24ec8dec1e87b62b6f70626bfd71f8d8d5e5c5b935a76527ee8a9a3094d635dc2b01a31dc4df336aa023517d7c35e142ccd6a79bc689e335f187a5358a00a7d4eb168cca3f9c6523ad4d74609a5b5c9e36db6bdf8464c4c8497c501084afa17557d070a7671c9144c86b4de9d57f033bc6b59a7f1f4e947b6a2d69c85877de731f6eb3db71d9f4c2dc086a3303bcbcd2f5b71643058b7ce08ef5879e0578ec81ced96ce907d4f32e67fd4cd269de9b60e09ff74bad6c86356ee297475ea7fe75d75\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (1 mod 64).\n# DIGEST: a07054c760cc66fc704edf950201005031f3faac\nKEY: 446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be1\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2f\nAD: d6773e0d0c302a5f47e037\nCT: d7059edbabb5cfc2cd5c459abd74e136790aad50d988c6c9271428597617db171b89ab171a68b14f9d417bb81f9f7d2e2045aa47c0b5d166c8b2622bd914c4e752\nTAG: e3d17e303776640b3ab712f6068c44e0e3b5d375203a8b01ad47e6f4681011eff04a41d03ff073e61c630b5faacb744447226a35e7496204911ddd660792be62c5f34c918a0d8514872100c4637ca12bc9c13b1580aed10a68c9187377441bcdf213bf3aa72831f3498d990a7a5960e1e6795bb11e4c7910a881d76ac81320ae61b151b8dbde093bc9e56b8204463d8ec31dc32b3cad5cd8cb48b5f20e54c17469ce97c069051c8e4b2ae5dffc0c2651d868a9909187c2732056213e41e315e94d14a84a24a676155ba86ef0b96efee3e4765dfc750953dc9a7ed739422c7d988f290432320313848a2eb7723c7c85ca3590eb35e3058d0462ddaab0cd48730107d4031a216c6c2595d1ca0b3f1815\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (2 mod 64).\n# DIGEST: d059c266cf6233af730b7a229b19356a4c6fcf06\nKEY: 6f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6\nAD: 773e0d0c302a5f47e03744\nCT: 8864e31c8b2ce1bcd1745671da5bd66e1e366b0af66b91f605574c841084a5df358483c7839e4456ae5a442930f21d4bde67578186a91c0a603468339ffbe3bfc607\nTAG: d8a0bcddd40964405ef006e0083e67a607b9f926e6508880d7784248a626d56a0673ff990920960fb307ed9cf40c2a1cc3b632b1f94aeb30efa02123e66165b77aa4be5e2aaba4c4a52372b403cae2f78a3bffc1cae8dc6f53839de7f16b8984304abc4a81ffe1ffb42799b54dc43ca0b963be6299a404fd4b3acf65939ac319966aae0a941c74135705092567e1237044c88f79b02b68ef622f9c776bbc04dbc2f58338c129f25afcd8cad7a0e91f30339457075b68df4960c003ef574e3aaae870787ae9ddab96495861388b341aa63ab2721abb176c4f2e6d5704cae123c20f1394d6a12d51fd5782dcb59d075775dfeb72df846995b87b1d374c0d0b8a003ba60f713ad777b8d6ad42c5e373\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (3 mod 64).\n# DIGEST: 8aac0687e33041fcc18da154b41f20a6af2bfb28\nKEY: 5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a7\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd677\nAD: 3e0d0c302a5f47e037446f\nCT: 1d239b3880e2261806ee770e7296d573d308d9850c8bd90a0764822faf5f65770f98f18ce4738538f03ad9b289bd5fa1367258f00d3ed91e32885bc45c30a240cad8c2\nTAG: dbeb6d1a1165a902128a27d7f55f4d928b56a3b83fa430d47bc4f935219fcc6005487f1ab14df0a07a270645d1c2fc23efc9866ec7e4427fe0382b75215c0f994f09c4ac54bf360f8ec938b02c17c4104127d2cb1eb51a11455180931b8e473838e5b1e61cf5cd05947a5b154be5df49905e6e7c049d00f065f680b0e5f3f4a7e9dad37d493f13c7ba318ca2bae086136d67b17a6ebf28b45cebcbfe115a45dfa32786a8b8354d51acf58bc126a13146e0ca509a26cc32c3e8ecf5b9d6ce76a9f76d674316c42f3140d5139304479376db2a167c65da7250e6fefc9d3b37a2072180ab3202f1fc7dd7f4598d1d976b15945fa73e1be07a91186ce7c16c4249d9f7287baafc572673925e95caba\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (4 mod 64).\n# DIGEST: 53658226c112b86438dd27b58a71f9e36fc73c1e\nKEY: 91d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a729\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nAD: 0d0c302a5f47e037446f58\nCT: 719d9de3bc86d08510354817d0fb94340ab1ddeefdb95a1cf460f7c9b185837b5320dd862b4c319619a0b18dc75f1762cf7c9bed63713c31e39a6f7069563441b9e6f106\nTAG: 8b61062c9480ffa62f7b96e9f50249426d05bf237d25e2b676e0041d40ba97101843d9ebc978949eb7ba53b8989ed0e93e5b91f13365345baefa1d7f59b694f6ef0bef0adc1d6763978e12fe354e57b90127533f3f991ce611e31e88a97962f859ebbc0e50d130c323aff35581f1f45cb5c650299025a03d99026d6f6a844ed9d5fe66e15a9fca79726afdaa54c077d148d561ca9e77e427b8f8074714aaf8b011697524e4d91bbab69bc01c8346e9055d7269cf124b503f7ad38c384abfd91ca36159d8a41e6389212167278b830ea464f7dffc3e01c9807368d3457ad5f21b33bcb1afd41ab7d805c9ed2f2c32da9bd4b510366b362dd02f50666ab8e5a72486b3c0d6b9bafb38c9375dda42daef635a0007ef\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (5 mod 64).\n# DIGEST: 6b7d5268b0b5037afb5be5af6a0ceb34e7656ac4\nKEY: d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d\nAD: 0c302a5f47e037446f5891\nCT: 9adce31c760d09ff911ed98eeb7146e82017261c8017d9a5fae1127479f6fb54d081cacc1ab7150f05d13547b992c1fe36a6e8e55ef1fa3bcc45bca495a981000a0c0b4f62\nTAG: 51d033e8003b06bf819a4f7978d75abec450c6b11a00bdf27f549f6060390ff99e0feb9509c6ac882777da699f5d5332d1b838a0436101574789ba485769ea6f4d73a10db775f06331140b218fa2ddad7fecf381fb9e3d26b06b3577bdf57e2a8435ba0e5b1e305ddf28070d1749d11ec5504cd9aa51ffe9133152ff35de21e4bbc3b109a318075d924bbaf0e267a1abd3d7afd2d3d8f4d951d4e96fa63741087a975eee8156b01fe566f7f6a309257c17a0bd9faae4c2781aae72eeab1903602b09b69026540a84b4786b8dce2a3e5ca26c65eb7b220dfad400cd236a4435d7fb1be60b9074f2f226e810d54abe7ec0cf10e7c465059720baf93915dda8a56d5a012a990d72408d2c9ab9b8dc813eb2f1caec\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (6 mod 64).\n# DIGES", "T: 63efe7af502231420ed5aecce9a28446b257828d\nKEY: 7df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c\nAD: 302a5f47e037446f5891d7\nCT: b81f6e678c5a08244a5f578970d64f96f50ad5b5724a9287ee7b293308db34e03456f1745f79c594ecc480fb2a9412bd685e6c0df028eda06aaa15c90afa4ec01736450e3eb8\nTAG: 63b849636c212d353918c6e3044d298da268ccf1042987617860b58eb7ec8314ccd7762ebc39b62c0f0f1c346c8f4bbcbf3bd0134c0a7374de1868b08ba013398d8e4b578bb8d7359f2cff1629ede34da00138efa4a724d892fe4ed2b28613e66e0bb4830f66c14dccbf8656e615d66f267182662fee8a3e1fcde0941793f0bf2b00d6ab6e9fcb30553b620cf8e9e0a15f122808d739e698f88aa157baba12428541e928ed556517978f6c9f29c6ae8fe5b4e9ed6f0ce49351ac2a63e74bda9288a874a7fd5327c6856596a3271039dcf54affbaf29a5556f1fe1062279d2600b920f4e26c96e9e8fa696c521f60e9418975befa58ad564e730d1de312ca1b999a5e89b813743b1512659d809078243170ab\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (7 mod 64).\n# DIGEST: 1a555c300a1d1bd5b03cdd6bf2a678621624eb05\nKEY: f660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b5\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c30\nAD: 2a5f47e037446f5891d77d\nCT: 6b6f94bc2326760d257d8156de961acac0b32d7f4d0e20363532e76ce76641ba66a1aa7945b9ee58527039cf83fcb01d8ef85254566947347463e161ec8cdec74a839637288d09\nTAG: 77b18bca8ed1d056d9c974054598216bc15bae5b7d70f3bbe32b3deb92398b0ce25a1efc5eb6782fa5fbcdbb415ef43eca090fcad4d34d53b1fd89cdd760e6424715c7703c51e08b72cb3e3b8a30bff159d5126f1473f216d5c931ae03703d3baf311a59d7ef3d6db123f3e8c0ca26fd3f8809ca63265d2fac935bec32631af43626ed1ee9785c81d7bd0cbc0c5178e1ca7de5d12c3592a7880be6590072c4728b2afa1eaaeecdf7cadd8304c2d4b614af7af14efa00dda595be92de09c74b39df05d7d023db721f86992c57061a264dead21e24fa47816f43b77b8ccccde44bfc32a015134a2cfaf04c582fb839202b08b81543ea9358d5735e7c197762a6a39936e26de58690a02dfc273e6779e77708\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (8 mod 64).\n# DIGEST: de9156349b578f2f44945ec6a676a67a829daea1\nKEY: 60ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54e\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a\nAD: 5f47e037446f5891d77df6\nCT: 8f211be563f98f493745cca0e385e5b0113027efe3b0a880805427e363014323c4f6c7e6b30d2466c70ed56d63157f2c4f6dabe14d5a22c6c708ab3fb667a6c64ce5c8de22f5261b\nTAG: e5807ffa59e0005c9dd7eef0b854ee1b2cfccef9977f8a963167cc563d844f795c4ce4f9d03da95e4cfd2fc80c9efb6424df8cd3b7875a6ca129da8f509ab09d1f0eec0211e0ffe5492913fb688796a29a8eac54f374e8948991059f6e73a68eba75a892b3e2ed5ab9680eb0b308b07337e75ad5b406c260af5d27955aa820bd0435549700e960e66c211000885e19b804579acfa8c526603f8d743491d916fd4d0e250159e485a4db2fea39a8eb9443516518e6612aae97b1d9b7ac48066d5fbe2c1be3b2e20233a2fb4d39052ef4ca3bfc47e561aaac9c57a7dbff922d6d997821f6b09bf3b4c91bc6162b150e17bfa2544f93f2bebcb4d20322bf0357fdffeec8f75679e6627b4ffbf8e0bfee63c8\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (9 mod 64).\n# DIGEST: 12812df3aa7f3bbc899f6f248f5590e02570c292\nKEY: ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f\nAD: 47e037446f5891d77df660\nCT: eeb6afcfd2626da1230067ed9938f7df35e99d2ba1c91d0e91c3db53034a3dd2ce3352b06e3d1b9e8415ef4ced9b2257eb05bc86db8204a8bd943bde51423a09459fecd528faccb646\nTAG: a69c7d8db2c021284e73b3c07620022eb6f199509e34611ed671c3558ae7c103c78024d96c00c791f3450d1e0338598a246855811af4cc9ae1a6522487a4a77b57b58ce29038ab0a2036404eae59133512b9ea40e2d7176e1b36965a27ee2c898d6514872bec952a029d9d85bfb0c99d8b348db6a3bbfedb6d1a3128664c454b9ef29f075fecc469f233e18567fe16759b378600a1d71504231e6caee5688e9858e14fe6fe850d95d7c010865781f0457a22f53add7ef57071c7153d312ca303e4884b83c9acfe86686517d80ce271c148cf3ab6464a9751b66ac7682a5f885ad9301a5602c099e89977f06b41badd1c2ea1f7027a38b749e2ca1a3ff4e4889e6dbd3674a52c8e24d2c76f64a6bc77\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (10 mod 64).\n# DIGEST: f3c89f21c327fca4aa400fabea9e39780378e901\nKEY: 82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fa\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47\nAD: e037446f5891d77df660ed\nCT: e1eb2175bfee27951357b7536e2c3a4c607bf511d1922f6cce462fdf98de9dfbbea66d38884c270e29d08c5ace1d6bb7bcd2b46eaffc67a99e225927421a9894238cefa73bdb48694abf\nTAG: fc1d8ef98aa65ba8a288ca04990bfb373071633eb1e8f30847d3c19ebef66962cce12d015b045e10c9e0aa7f275137e00cb2c9a0508c0187827a74faca4bcd015620f1cdd8f72161bebbb8231ad4b705d1982db6f9fa1d2303c429469737a3141adf729729144f55223df1fb45705fb15adb5cd03c2936674a47d7f6aa5d2a4d9a017e57a4f5dd954504abb588866457730304878ca322f776e3c8e7becb8437002bc757d5b34b16d04ae4710553a624a3fca8866fb3d20672d6f4a2f937edecd58e68b7b0a8c39819ab48788956c1f3f5f4a15e7d13350090a20c61620c9181f03b4d68d7e4f336cb7e4a1a277df5101511150dd39fb43a84cfc480fd548035c8e9ec26602dd66d250fce39dfd8\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (11 mod 64).\n# DIGEST: e8e41988fad6c8b44c56544964cfe0a347b35b1e\nKEY: 933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e0\nAD: 37446f5891d77df660ed82\nCT: a799c4a6590a4c48735d1da9746e5441cb11b664daada5d4d68d3a0110c4ad8d5e96d7331d5f7a0d1df9af5da4208065b6bf31affdfcd4944e8ed55b0ba7b7911be1a9052fbd93d5fbe292\nTAG: 6a6e5ced88748f87682759b554d9685280e094e083d297dc5fd474c4a2605612b2f8b1c31dea24d58c25bcacfbf03b8b09dc662d6e1120868ae9a0f1dbd2799756136c2a26a22e3a61a0216e76e94393534586e1a59c570d8bdb37d5ee6d0762e60c7171fc7953e59d74b0f2ff4a061d27a7baa8ed138c51264b356d9a42b0768bca1c1c458acdc82bd621031e2ae7790596594d2f6eda2c8d58d4b53cf6990434da8aa9e9eafec648d52233e9b92994ca5cbc071dceeed57b02e36f93f8d22551660cc4c1e425aa77dcda3bf6c98bff7905becc075e1707e37453de8f300be5aabc96c1051fa46c796a2c8367a00af3c4dccc58bb7dc8aa2e21e0886eceb898080bbc7259648f2be9da0f1b56\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (12 mod 64).\n# DIGEST: d1c7b2c04dc25fe7b742a1d659aec20e1475ee4f\nKEY: 3f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037\nAD: 446f5891d77df660ed8293\nCT: 2b8ac97f05a67490bf16bc64381e9c49e7f348212d0645056ca5405e9e0a248b6918568481ceca70e20ae4b7c1f62700a2954188793b34504fa86decc73f667e5fae944211059dfa94ef072e\nTAG: 5f91838f37198290b43fc04a186db6a05261ea9916a1dd6450604ed8a7d0bb59751f6637f593ef1a7e3aab6421b7a0cc6b5b47477d36bf439806dd8156e2bc2e229bcbaed9a3beedfa383d674d3b91922e6248d1aa8ad62361a4bdcfd3d86daeb6d775a521916ecefa2244aefbb0cfc0ede1b1c0e0059a4d69850160d2f4f662ea2b77fb074a6de69feab87bb56f27edc3a42037a041007f0a08d204cbad0a9047f7798dad51e5c04126519b53772ad4f3017f9d9fe91920aa7585a5f2d95e7a8fe5c7b22fc696be10e308f939c34e52b7bc2e71b06a56e3ffa5a0ed529eaf5a8c4b6857b1f144f51fc8bbc858c88ede7ca325d231b34e4ae0e7ac8fec3e8f6a9bbc6f8975fec1e877f0d05046c3fd7a0e15ebb3\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (13 mod 64).\n# DIGEST: 116e20ff1e79e0af464d473b1e7c187f4dd66007\nKEY: 62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be90\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e03744\nAD: 6f5891d77df660ed82933f\nCT: 783a362232c871213daa72d58658aee2ceb4de66198", "df21e227326010be056d5c4d2481ffead6c80733603b132b256d1c52d64eb8b700d614dca0adeacc0c7a05d1a64ee7b5c8163d1eae17fdd\nTAG: ba611208a3cc40e2cc638c335fd508441aaa15c612a5100c960543d2ceef9709bbb3e70904f3f2efac3112fc61bdfe7accfb5f0e9d640812a4f5b0676d95b1d5298eddc97ce3aa16ee761491e9f424af39119c9f56322b10e8575697bc93d1f6a63007ae085bd20c83fc32a5d4e59ce8840f75b8c52f6aeda4fc34f11301d64e058b39ff765e1ec9997ec51aeb43b35cba9ad4b020e7dcee79ad532b897faee018dae1231ceafa1a5fca1ff1a01f863580c9c07b13354e31b0067a2fb16477150ab6d027fe88276767ebb46b1029c7d6dcacbf418f10d932dea2ea161ff8a4f6d79e0bdbf0a67227d5c9100a45fde25e2d4e360c0c0942e9ce13b570b5ea149dfe422fea36251e226b3f7eb709ed7c7339aaff\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (14 mod 64).\n# DIGEST: c081d0d09b2c9eb39a372ef4a7b0246a0956b0f9\nKEY: be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f\nAD: 5891d77df660ed82933f62\nCT: 894d8fc70288c7b8a5d12e63ed6e6e8c74b8d9837720762ccc519a42e024ee05e8f770180e5213a7c7ceac56cab05834d49847aa1432fcfad8286e092feddd421b33212e41716b3db5358903c11e\nTAG: c00612f3ee6619c87aa5c7958da77fdac74ea2ad1af9115fd003edc7bdb36f639dc2d89668f6c2440827a1e7bdb65acd172be229f8852d4b81d1d2ee1e167ff127fed768d0a6eb822c2fd88e733a0884f06e47d5f3a7e84e7f20d8b630c8e748a03f2eb807f3d6bf67d3f93ec97f22a3bfc477143f9e34049fd9143ad5e480bf538464fa847a5302e6d9ec3710122fe6c295191906d98d69e01e81a79de0538442a76a17fea214c74bec28c01370a0aed01e1a32a629857f5d48c3275b79a25d3fe549829e5d72d9d26c2e07fe133e214e40dfba4cd19ddccb01a6887bfba26db80b40eaee435a7619415af7be271739dc339fbe4a500db56613498b34c2b1f9dfbea13aff30c84fd1380ecd821b57cb3775\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (15 mod 64).\n# DIGEST: 6f7bb1f9e2772eb909c315e653e4737cfed78a18\nKEY: 8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f58\nAD: 91d77df660ed82933f62be\nCT: e5d56aea96fb40312e288074a21691ed29f17a547529d2427e8bcd5024e617411c08999a8a514adc83a14fe27c51b0f7d44f684fc60274c009274ff9af14d4b1277cc03453e02c0ceb26c796432f0d\nTAG: 07cea5df6c6594985f9af65319e2fcb1882f6d1d66fae0ab595ee72dc4a1118a7ef8ea450209809349b41664ee21afcb053e8edfa53bb1e66d9aefde4c48c6ff5b5e411c1228cbf5c1021d605311a20bd6708aa004d7da8bf72ddce1cbc9a12100969131d596cca0fe61c82208d0848ae0d098036a07600cc4b443e344b06d3162c8ebe14850239f77d178152fee009b1bd81a68bbf632082f9a62dbe60a1ba579077842c713ab4d5619b7abb15eb8fd3b1ee1506fe8df31bc90a63eeeefc0f23ab5ec83f4a1e9fa8833f15c90d6b68615ce297b466d5d67a87ac9fb10a2ffba5a91d31d1b18aaee8c00ff1a8b8df9584a33e946e85d8c6a6c8719421b75a8a56f964725abb4a4be790acbd60efde68671\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (16 mod 64).\n# DIGEST: 172f4992e692a88f49628e5d3937959be01aed2e\nKEY: c55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d4120\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891\nAD: d77df660ed82933f62be8d\nCT: 7923c66ac88a9d3a2c9d9e714d491372caea0658b4e5692a7df8da934dce8525d0974848545ce89a44a735eedb22f18b5b8f1455c0aeedea9cb8f5c0bb51addd065a83c4e825ff3993ff58cf0af7577b\nTAG: 06b8d51726fe8d46fce9a59b084c3924c4aa9575d3b3f9b9e31a098c2c0475e460a89639863652164b724927ef13d2c52faeba797d38ddcb9274dfc6478c06626ec55954ce17df075f0b089ef155daf416980039458b7979afeefe9fa3e365ca19637b05cd17987e25f20e62031c32d441a102c22efb3660e4e3c13800acbfba0e7dc99175e35338b87ebb56d09a3b4bca72774d87e9cf92ce8e66917835c765129c8946c7f42ad8acd9afc22acc44a89dbebf6f4b2a55c139312559e2aaf6115aa617ce07cb2a63c66cbaeeeb5c95ce617928f93031f6dcbd3ee30a6fcd4cd9606695b690d95fb8d126c4962f49f11910a6e9daa2227f46a249819074a06cb5ffd449bd5744f9d9c70dc14475fd4b9a\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (17 mod 64).\n# DIGEST: 00133da1f7c63fd5f0eec364e9a359be02c1d3da\nKEY: 5b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d7\nAD: 7df660ed82933f62be8dc5\nCT: e0b671d572a26f0553cdeca68a4d023615570ed0e9414e5783691fb6d1c2bc30bb4a7590d3138972345f3a55f2f90fdc8ad46555d41968a00a6462c2bc0931a18df5480e48cfcfcc00078314cabe0e44ce\nTAG: d01f174c6f726b83162a8a0734e1b1e9e9498fa067454e3a488cee1a04703987d5ce9a219b4ba168a809a181d6a291eae84f91705fc0701166400f24775bf5816a67ea6f011829ca07ef1aec6ac3b7ba0576c26b557b00fb76e84b6e633c48b8c425678ae12c922a7af7ce0484861efccf958ed418e2658b03b5c978fe624b16428c41a2a7ee1cc07c9d730b689cf92f2041b5e68908fc93d8221821106d73363e2d53df824a82841be5bdc0668c5b8759a1e79e193dac2e55e4cc083569fa727b952a45e71840fc330977e072457de678d3f3694e429131e25efd339421094512755604e1ec84efdb52259f6e8284bb7ebdf229cd3e4f1abfd6498e3b493b21184f8a42ba31f4f22dbeacbb1d977d\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (18 mod 64).\n# DIGEST: 60a6821269be6c5b985576b245f106128eb0b325\nKEY: 436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5d\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77d\nAD: f660ed82933f62be8dc55b\nCT: aa02a8b8deeb507cd2b2ee187af85b5afa85583c258df91df9cf5307316d03b5d8aad0441bacc27c4cb26c56239423f8e46746978c0edd3c21018f6b9a1c39278f71b462c6da999a6f4d9513a47cd7986c88\nTAG: 5cea96fc3da1457f7e66f324a3c634829a6382fb75efc614bf944cafda4c9cde5bf3118838487401497849d59f895d761b8b0da9f339123aeab5b237edd48d6c1ab4120da7769a7f8510bfca3d7313f0f38dc6c34fea81f60dd3e421afef2d9a61e6b0d7be96b357f1a293fe5c21d4ee858725a4c088f49a24930d846d2c0fad98002fa66a618367425cbae16fe570f3058fcfa2544f1d085ddbc6226e35c4355c916660f7f8fef4f5ab705c93b5182269adb8a4eeff4e62ee278c0588b96043f1ad24ca39a7ad458f541101e1d6cef99d742e2e4a124e4f3a57986d0192537d956231f4e49f5a87f5b7f5a4cdae6cc647b90177dc4d81232c62bad3d99036812f84b3208ed2edb8058f4973abd7\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (19 mod 64).\n# DIGEST: e2593f3b6741a9ed9fa188fc06efd057556ee624\nKEY: 6965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df6\nAD: 60ed82933f62be8dc55b43\nCT: 8b397fb4fa218359120058dbd145f4bd99def7e5e0a88249783128801b3828909ea19d9f5fb0f3e15ebd624fc32525796ccf9ec01b1da3acc6dec2a9306c57db4eeeeef4830575fd8166c13c23664d4df4cbac\nTAG: fe141cebcd20919976fe53fa1a9e186db43122704ac5dcfd23abc2da394907a9da4011bf32a3948b0ae848d6d010024c6f37191f6fe5cdc46430b915a9c5cc80329ab5d32797fc97bf3ca270d8b35c14e3091c99ca3947492613d183845ea5b80619d20c38434261dab80d4068449a0880eadc55f0b43cc344a875adfd23020b6e63c3015c887ef52c72750c09f60c7bc0dc29ac7a6494bf9771c4aa931aa440ad400c1cdff8f3d1bc4173977128d1eb57731e4b69d3e6d4715dc5d2a9cfdc2afeabf3513b3e3c107a83ac48f511750f887f59b10f40e8f2d197832dbb1febb82c29627232e3793c8a72d7033c86cf99fb54dd2e3ce099d4fdb50a63b06d5f595d5bf59474cb190245a36095bd\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (20 mod 64).\n# DIGEST: 17450a437efe239e1858ac4062f34024305372be\nKEY: 65aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce99\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660\nAD: ed82933f62be8dc55b4369\nCT: 24e568a27d8bce547f628bfa545c4b7ccffce40f73b5abd6e1b60d5efca7cd6d5feda872e172f64d9193d3d2d3381efb52c05f98d3e1fb689fb05d7017654eb57346f1b3dee23b0f166e50531626582115af7cf0\nTAG: 4dae8797b02d7f1d8dc42b10f18973c094880a10207d9479aa825", @@ -674,9 +735,9 @@ static const char *kData19[] = { "642aae9f7bc42060e\nTAG_LEN: 20\n\n# DIGEST: 6b7295febce7fba8d79d1e7ab8fdfc452191e2ba\nKEY: 454879c41de9ac9f98233b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e\nAD: 6da12dd4c27f4372480974\nCT: a1d0537c3bddc7459a37268608d30ee8e15377c922a4300d7e7f00084cb45a9ab7cfc7f89dfb68f3cf7defd102012361782e977e22c12ac1d91d1e093a21ab26bd171b426af9af7b2dec9d1f2dcf78f19748b39e9b0736e24b44dabf677296db10dc28cd37751d020e1780e5fb00142e972baffc546b9b55bd0067e22ffee4f10312a590394a296cf6fba3456b3c0a64b662d232f185a41762bbad664f977328bba56b62f489d33821d4d604265c388b5ea852968db95ab844c7cb9498bd28d4b055760f83fa94f2a35492a4dd03a1fe9f0c2947fedd44b96948447054e2da7fd3b9d95bfcd0cfe3d1c909e84c9f87ba2a50c33d588592ff3c7c7b56442d52683e222f2610b740a2187159b05f2b15afbba7a97ef2dcb30813b89393706011397f4aa3c537e91fab098ecbf3a87c2185b9001ff1a78e104fbeac85bea4ad609bf1571d83969934d483794944c2e6bea9d778d2deac2d6344106c1dc30d56251faaab3f4dda43a2ed8c3345d9773e4fa4effc5edc3a68cc423b539ed63e8b0605b58aa881906e38b38f02a4df3708e9de4333056c96a02ad6d235636da61fedc631f705e771af9f522109a4d3b34d684b3b175d28a389ea574215131aa68016ea9cf3664b0baa6491f85d3a4370f73967e4c23637fd1d\nTAG: 131597a4dd3057b4a44498ea09294f2df51a5e81adcb3318ccd5\nTAG_LEN: 20\n\n# DIGEST: 1dadffba439570155af2509a548764a93042d23a\nKEY: e9ac9f98233b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e97\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c2\nAD: 7f4372480974454879c41d\nCT: 98c951eccacf8dcba5b819312f0ed234ea1cc06abee5f70888558000c2857de7411feffdf379c187d327943c63ab697675557a62c68c13f48d3970531225d5fb6c1434a126cfd6ba80b8f6dda08b3e3629ed12f7bbb45f45148f8544f0a8eb70c849260916eb62baa1bd850e082ad69ca5817594e8f26f63a1909ff03f5696b7a52f146af246c0c6485ea5826c89471c04fd6c373e9d0fef06f4a7b01400962ebfa4ef4166dc895619864accfef9a4be874111cb333518b33a3a2565d032a2434931a16e000d01e35317338ddbc48317517367603697a225d81fc63fcc7d4b8463bbd24910b4972375a995e13baa148b644993b9a7bd706ae64da00f898599957e406c1ab15fd44b6e85b41d47ffaec8136a5dadab324cb0ce95c738a1f8d246af90d98a68b8ab7003d74aa29591b58ca7b2dc38f21f4cfbc04f2e239728e1350b0f074293a13970b264bee368ff98c6960a805346c19702983d3ddfb6306f24cc7f8224e553b0668180787e48ca8e5d851f84df71d5ce6fd7815d39d7e3941b8e0562af98e6e244216bf418d7ca2d9e29ecd3997573b2c4d92aea1a5a82f2272af1218b379ca40a28cc7ce09ad60028a5a6aac6ce145cc3936f89a5d34ba54aeec8d99f84ebf7367fa5fdc12def2294fd3fa3299ba1a59aacc0d7\nTAG: f65b77267d53b2dfc87a936ae08ef7a3f630176553\nTAG_LEN: 20\n\n# DIGEST: e654b4c78e1c0061eea2996fc126c9bfd41eb6d9\nKEY: 3b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f43724809\nAD: 74454879c41de9ac9f9823\nCT: 5a1c2b7a8d5bc74901521e1300567f30e2b7755f004ddcfd8fe64f471cbaec4bc6d445ea931bafe6ad78034d0ac1d3916f1e0405c2f2aa4b193c2cd599d34b86029840ad379b136aea5c2a74ea70e22e8c8d1e017a2f7d47f8ebac7b85087075c28d6d2846e357ce031abe09e03629a32cef0b205d631f36ec9a1c9c4e90a80900e01688c7298b99be65f204ebaf312364bfdf57d9e16b0142e879a47b9ae0e96fc62e90883624ee2dc110f3a83ab341f4558f360df399170bbae57cb2eb377a87aaed9755e8057d76609d447a33a8255450504b71439fc0d03e0fffb775019ebf921325b42ef56e1b454b5c87ba5daa1f0d0920e860eea43c913d417cd9e9b6676759a4e2c71b0180b432fe2aab4e4fcffb51b4198ffbedbfcdb4dd4e105847f5a5832e85744f34bf3b9929ffeb177ceb4c5e68585a3ff8fda6569921b3d093a2f1d77e710f78245eacd471af88da8ff8f268293845a9a8550ef34e2bbff9d6cf55b18987c71eb98803bac42b0e6c062015fafb754c6a75f927cac4a8adfcfa8ee05a3f115f1f90d734f78180aec2aa621fa7908d350b0cd8550895cf4b5c3cc75eb95fa574f9a91c1f5efa61f054bedd9267f10a08a21b19e63754de10a1bb0c4ffd8c5c08558882a2f98f1175920a71b981affffde44ae1c9281eee161c4c\nTAG: 28f3243632b13692a2f175644a0e192d8102dd9e2affc5c1\nTAG_LEN: 20\n\n# DIGEST: 654b8591c7f0506261713e9ce7a6fd24a6b9357e\nKEY: 61792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f03\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c4\nAD: 1de9ac9f98233b5a7379a5\nCT: 62d0c56ae3e695bafc3cfa3c2d8b9d17ac8ff3b84ccac28d568c1ac84e1574ea06f31605caf86d4e809e39e9c275eed4a8f27eb00dc78e1c10dae719519d949dbc22e00d8644bc3806e54e6531864ae4cb5694002e2a3d7146b39b0b38acadbf1651401805f6394831c608b0478d496cc939b24aa3d3e6d445faceb798a69ae1308a593244645e242829f64f7945d0af8af0eeb6d391c69c2d5bf7b00e42092b36c23362bdd627af43ca7336d88cc36e95ede07b83afb54c8758678d19e0ea7956d8f26776b0f4b6b637c1152853651b6c130f436ffa2d4fd0c344e7583c5e56d6262f43767a1011d8398", "311dd6e3d7f9ea89d3eb3f6a1a9cb98905c0761fc5be1d83005fb9ca039b877c30b402743bdf0109ee5de42eef860be676a399a206c08dca8e757f059f7d9611137039b9053430e7d6406abcbf7aed645110aae84f758fcf0d225738cc7c90ace5d83eb9fe65d1e65efa4f6c9d808060cb0f72605e3d7c70e0d13d84689aa1e44aa4dcb152f230d456eb6cf520898bb249262d30c64fde02d6894f72ddff201e4bc41c5fc1f394f2620f764d40098292b04aee45e26812f3abf9a020b5215beb7938e2c121e809ab825d22a2d560bb9bde47572ecb891dd49b38f41af9649dfbdc83ab9bceb444bacdfca2fcbefd623364d4e255e2c0f3164ad92\nTAG: 42174887a9a11a8ac5d1d13e83f8502a3cb0310bbf46b24ff42e3d\nTAG_LEN: 20\n\n# DIGEST: 1eaad32c8d0cefaa5e2c503bb2185a73e6387fac\nKEY: 16430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb7\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98\nAD: 233b5a7379a561792c0f31\nCT: cc269c9aed42c9ba90c768710fa03985372a219f391327e438b1593af29aaf2b66cf8fd60f137d8ce8438a7bcbf7c1c7010c06636f191802daa26fe12ac1c1458baefb2a51fc7361b2d98311c2eaa27e046fffbb76fc855ac01a1321672658e394043367e89478a789d662c88e91642af53824097326d991abd62d1ab818452fc152aa1bd05032027fbb691886d9269937f7f57e214a2186a191b2249ba6fe79b69a94623d85ef0db6b5c2363627ea15a614e6ee42ce0a26a90faaa3ec45451c69c7d472d98b0376a95503b16c6f17eeeb42e0ad5c8775584819aa01309e6071e6b9494da6ddcf992ec6bfc81e0031d74353afa042abfe62fae02792bb6dcae82694cb651689e4039208bf677c90ed6245606cae81732d9d32043e5435f8c40cb76b55a03593dda1271aaccdbc24f18c9a881c77e1dca0e62bfdd36208ee94370b166d66203dfb90c8602dfb48159410840c669c47e7514bf91ef603834bc213173458a87909979b3b77aaa77262e1a634fcb40241818f544f9d207e91ca1f46f77c5c4f606398938f764080dda0978c6b76ce76830a15098870e72b5c9f4975b495d2c5d969688b555773601ad8c857ca8c38565674539fa71a8acadac5415b563f55811b0c010ca1e6793ad08e6c830a0ec2b385402fb8af3b6f0ea0b70b458667953207e4d44f1959\nTAG: ecd2bdb2e683ff8bc7d20482e698ce2b608032094cc2\nTAG_LEN: 20\n\n# DIGEST: 862c0517b3658e9b9cd27db608d49e24e9b4667d\nKEY: a058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe9d0cb746bbd55813\nNONCE: \nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98233b5a7379\nAD: a561792c0f3116430e8b6e\nCT: def7eba4397065d05a7a1b742179c1d8eff65e7e4ac18bec49ed020a95497a58af4ce62679a36b77f95f72913c2a58184ea0c3b59b60784bdf63893a2a84f76ab2b6324a218361316971ebb1e2850b6c7baaf9130715580626bf298f60d862cc4b9c4f353a9e4c7536fd697ece9407eb8ad434c97e325cebd5aa0cf4a5342724f2950c8623aa3a5322f2e06a6b1d71a57b22a2f85ed1acacbeba192cb29ced37983e4231bb930c07f7266728c54e8fa9a0b7195975095fd714440e07d63aa87778061a361b4d44f0241a504089b738cdf3a6323b7a709d39637a2c61677c1f034214a4da6471a89425a5cc6040f37261b9a8e55589b2c24a01b4379dfe00ce758e9e617b6d15abcf0974be46d151c5d26e69c50d3fe68d1854b788d6a43e72a00b1602bb9e7557c4c298b99cccaa17fd950123d672978cd359e115eceb88480d59f5496a920949e09d0590283280d78df0ee068c475706701034b5b8686c60e2c4c4d4bafb2dd25c86293d472d195186f3fbaaaa000cf678295143aa290b011ec35e1eb2dcc6ad12593a934b60af7b570bc59569df2e99bf618aaa60e533265e2bfcfe3e01dd1620cd7d6df8b70726b5fa1191b0cdbe627f714744b2bf2abaddf800cc091ce5ee447f2a61ad36094743182ebbe236745bbeb27a946c8d8dba54dd3597fc4328bb3fa5f43371b531bb\nTAG: bcb4795a551fa0b1d147e2c8f70c31f20a60228963076b32bb\nTAG_LEN: 20\n\n", }; -static const size_t kLen20 = 455606; +static const size_t kLen21 = 455606; -static const char *kData20[] = { +static const char *kData21[] = { "# Generated by\n# go run make_legacy_aead_tests.go -cipher 3des -mac sha1\n#\n# Note: aead_test's input format splits the ciphertext and tag positions of the\n# sealed input. But these legacy AEADs are MAC-then-encrypt and so the 'TAG' may\n# also include padding. We write the byte length of the MAC to 'TAG_LEN' and\n# include the unencrypted MAC in the 'DIGEST' tag above # each test case.\n# each test case.\n\n# Test with non-minimal padding.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8e\nNONCE: d1c8e9ba2fd6773e\nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: 144c98ca1f\nTAG: 4a40ffe530b338e5173a8e62c8530b0c14b15046d12f2ca3158ad71effd0f46b29b3ae\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with bad padding values.\n# DIGEST: 7f3a0e20bde700d3c5596909282e5c3e764c99e7\nKEY: 86d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8e\nNONCE: d1c8e9ba2fd6773e\nIN: 936a91d0b5\nAD: d2c0267218cb7090c61713\nCT: 144c98ca1f\nTAG: 4a40ffe530b338e5173a8e62c8530b0c14b1508045d58f4bdae400\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with no padding.\n# DIGEST: c6105cc86e18eb8376c16ea37693db5c07b77137\nKEY: 8503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe47\nNONCE: 7e0cdd46be99371e\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c748\nAD: 1df3f4183aa23fd8d7efd8\nCT: 17944422f667bf1356c234189f9c6cf7af52b2832b2fbaa990ccef4e7f9bc3841e59e25c00e3686d5bd5c29f\nTAG: 3ebd1b0bee840e8a6e992421c62de5a8fda3a82f\nTAG_LEN: 20\nNO_SEAL: 01\nFAILS: 01\n\n# Test with maximal padding (0 mod 64).\n# DIGEST: ceb2d295bd0efd37c6c34dab1854c80e986174fc\nKEY: 37446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65\nNONCE: de39f4f03541a11b\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba\nAD: 2fd6773e0d0c302a5f47e0\nCT: f2ab16ba87c52d066c0637d387b89d700a66828ef231b480f39aa08ac2447c8ddd205d1a95da37f267c06a1338532de890904f9f19c930adfb684e81cc06bdf2\nTAG: 3ff610fb9e208ff6ad58b78c5b2cf54b997eb3f24ac0171229ff7ee9cd5070de5a604f78b35b6cd25b3f2ab487847ca1e3928bf7f19bd19c9c9a1015dabd2de426fe57d342009ae4a2e67fdea378f24ec8dec1e87b62b6f70626bfd71f8d8d5e5c5b935a76527ee8a9a3094d635dc2b01a31dc4df336aa023517d7c35e142ccd6a79bc689e335f187a5358a00a7d4eb168cca3f9c6523ad4d74609a5b5c9e36db6bdf8464c4c8497c501084afa17557d070a7671c9144c86b4de9d57f033bc6b59a7f1f4e947b6a2d69c85877de731f6eb3db71d9f4c2dc086a3303bcbcd2f5b71643058b7ce08ef5879e0578ec81ced96ce907d4f32e67fd4cd269de9b60e09ff74bad6c86356ee297475ea7fe75d75\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (1 mod 64).\n# DIGEST: a07054c760cc66fc704edf950201005031f3faac\nKEY: 446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de\nNONCE: 39f4f03541a11be1\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2f\nAD: d6773e0d0c302a5f47e037\nCT: d7059edbabb5cfc2cd5c459abd74e136790aad50d988c6c9271428597617db171b89ab171a68b14f9d417bb81f9f7d2e2045aa47c0b5d166c8b2622bd914c4e752\nTAG: e3d17e303776640b3ab712f6068c44e0e3b5d375203a8b01ad47e6f4681011eff04a41d03ff073e61c630b5faacb744447226a35e7496204911ddd660792be62c5f34c918a0d8514872100c4637ca12bc9c13b1580aed10a68c9187377441bcdf213bf3aa72831f3498d990a7a5960e1e6795bb11e4c7910a881d76ac81320ae61b151b8dbde093bc9e56b8204463d8ec31dc32b3cad5cd8cb48b5f20e54c17469ce97c069051c8e4b2ae5dffc0c2651d868a9909187c2732056213e41e315e94d14a84a24a676155ba86ef0b96efee3e4765dfc750953dc9a7ed739422c7d988f290432320313848a2eb7723c7c85ca3590eb35e3058d0462ddaab0cd48730107d4031a216c6c2595d1ca0b3f1815\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (2 mod 64).\n# DIGEST: d059c266cf6233af730b7a229b19356a4c6fcf06\nKEY: 6f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39\nNONCE: f4f03541a11be112\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6\nAD: 773e0d0c302a5f47e03744\nCT: 8864e31c8b2ce1bcd1745671da5bd66e1e366b0af66b91f605574c841084a5df358483c7839e4456ae5a442930f21d4bde67578186a91c0a603468339ffbe3bfc607\nTAG: d8a0bcddd40964405ef006e0083e67a607b9f926e6508880d7784248a626d56a0673ff990920960fb307ed9cf40c2a1cc3b632b1f94aeb30efa02123e66165b77aa4be5e2aaba4c4a52372b403cae2f78a3bffc1cae8dc6f53839de7f16b8984304abc4a81ffe1ffb42799b54dc43ca0b963be6299a404fd4b3acf65939ac319966aae0a941c74135705092567e1237044c88f79b02b68ef622f9c776bbc04dbc2f58338c129f25afcd8cad7a0e91f30339457075b68df4960c003ef574e3aaae870787ae9ddab96495861388b341aa63ab2721abb176c4f2e6d5704cae123c20f1394d6a12d51fd5782dcb59d075775dfeb72df846995b87b1d374c0d0b8a003ba60f713ad777b8d6ad42c5e373\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (3 mod 64).\n# DIGEST: 8aac0687e33041fcc18da154b41f20a6af2bfb28\nKEY: 5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4\nNONCE: f03541a11be112a7\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd677\nAD: 3e0d0c302a5f47e037446f\nCT: 1d239b3880e2261806ee770e7296d573d308d9850c8bd90a0764822faf5f65770f98f18ce4738538f03ad9b289bd5fa1367258f00d3ed91e32885bc45c30a240cad8c2\nTAG: dbeb6d1a1165a902128a27d7f55f4d928b56a3b83fa430d47bc4f935219fcc6005487f1ab14df0a07a270645d1c2fc23efc9866ec7e4427fe0382b75215c0f994f09c4ac54bf360f8ec938b02c17c4104127d2cb1eb51a11455180931b8e473838e5b1e61cf5cd05947a5b154be5df49905e6e7c049d00f065f680b0e5f3f4a7e9dad37d493f13c7ba318ca2bae086136d67b17a6ebf28b45cebcbfe115a45dfa32786a8b8354d51acf58bc126a13146e0ca509a26cc32c3e8ecf5b9d6ce76a9f76d674316c42f3140d5139304479376db2a167c65da7250e6fefc9d3b37a2072180ab3202f1fc7dd7f4598d1d976b15945fa73e1be07a91186ce7c16c4249d9f7287baafc572673925e95caba\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (4 mod 64).\n# DIGEST: 53658226c112b86438dd27b58a71f9e36fc73c1e\nKEY: 91d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f0\nNONCE: 3541a11be112a729\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e\nAD: 0d0c302a5f47e037446f58\nCT: 719d9de3bc86d08510354817d0fb94340ab1ddeefdb95a1cf460f7c9b185837b5320dd862b4c319619a0b18dc75f1762cf7c9bed63713c31e39a6f7069563441b9e6f106\nTAG: 8b61062c9480ffa62f7b96e9f50249426d05bf237d25e2b676e0041d40ba97101843d9ebc978949eb7ba53b8989ed0e93e5b91f13365345baefa1d7f59b694f6ef0bef0adc1d6763978e12fe354e57b90127533f3f991ce611e31e88a97962f859ebbc0e50d130c323aff35581f1f45cb5c650299025a03d99026d6f6a844ed9d5fe66e15a9fca79726afdaa54c077d148d561ca9e77e427b8f8074714aaf8b011697524e4d91bbab69bc01c8346e9055d7269cf124b503f7ad38c384abfd91ca36159d8a41e6389212167278b830ea464f7dffc3e01c9807368d3457ad5f21b33bcb1afd41ab7d805c9ed2f2c32da9bd4b510366b362dd02f50666ab8e5a72486b3c0d6b9bafb38c9375dda42daef635a0007ef\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (5 mod 64).\n# DIGEST: 6b7d5268b0b5037afb5be5af6a0ceb34e7656ac4\nKEY: d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f035\nNONCE: 41a11be112a72933\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d\nAD: 0c302a5f47e037446f5891\nCT: 9adce31c760d09ff911ed98eeb7146e82017261c8017d9a5fae1127479f6fb54d081cacc1ab7150f05d13547b992c1fe36a6e8e55ef1fa3bcc45bca495a981000a0c0b4f62\nTAG: 51d033e8003b06bf819a4f7978d75abec450c6b11a00bdf27f549f6060390ff99e0feb9509c6ac882777da699f5d5332d1b838a0436101574789ba485769ea6f4d73a10db775f06331140b218fa2ddad7fecf381fb9e3d26b06b3577bdf57e2a8435ba0e5b1e305ddf28070d1749d11ec5504cd9aa51ffe9133152ff35de21e4bbc3b109a318075d924bbaf0e267a1abd3d7afd2d3d8f4d951d4e96fa63741087a975eee8156b01fe566f7f6a309257c17a0bd9faae4c2781aae72eeab1903602b09b69026540a84b4786b8dce2a3e5ca26c65eb7b220dfad400cd236a4435d7fb1be60b9074f2f226e810d54abe7ec0cf10e7c465059720baf93915dda8a56d5a012a990d72408d2c9ab9b8dc813eb2f1caec\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (6 mod 64).\n# DIGEST: 63efe7af50", "2231420ed5aecce9a28446b257828d\nKEY: 7df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541\nNONCE: a11be112a72933c7\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c\nAD: 302a5f47e037446f5891d7\nCT: b81f6e678c5a08244a5f578970d64f96f50ad5b5724a9287ee7b293308db34e03456f1745f79c594ecc480fb2a9412bd685e6c0df028eda06aaa15c90afa4ec01736450e3eb8\nTAG: 63b849636c212d353918c6e3044d298da268ccf1042987617860b58eb7ec8314ccd7762ebc39b62c0f0f1c346c8f4bbcbf3bd0134c0a7374de1868b08ba013398d8e4b578bb8d7359f2cff1629ede34da00138efa4a724d892fe4ed2b28613e66e0bb4830f66c14dccbf8656e615d66f267182662fee8a3e1fcde0941793f0bf2b00d6ab6e9fcb30553b620cf8e9e0a15f122808d739e698f88aa157baba12428541e928ed556517978f6c9f29c6ae8fe5b4e9ed6f0ce49351ac2a63e74bda9288a874a7fd5327c6856596a3271039dcf54affbaf29a5556f1fe1062279d2600b920f4e26c96e9e8fa696c521f60e9418975befa58ad564e730d1de312ca1b999a5e89b813743b1512659d809078243170ab\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (7 mod 64).\n# DIGEST: 1a555c300a1d1bd5b03cdd6bf2a678621624eb05\nKEY: f660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a1\nNONCE: 1be112a72933c7b5\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c30\nAD: 2a5f47e037446f5891d77d\nCT: 6b6f94bc2326760d257d8156de961acac0b32d7f4d0e20363532e76ce76641ba66a1aa7945b9ee58527039cf83fcb01d8ef85254566947347463e161ec8cdec74a839637288d09\nTAG: 77b18bca8ed1d056d9c974054598216bc15bae5b7d70f3bbe32b3deb92398b0ce25a1efc5eb6782fa5fbcdbb415ef43eca090fcad4d34d53b1fd89cdd760e6424715c7703c51e08b72cb3e3b8a30bff159d5126f1473f216d5c931ae03703d3baf311a59d7ef3d6db123f3e8c0ca26fd3f8809ca63265d2fac935bec32631af43626ed1ee9785c81d7bd0cbc0c5178e1ca7de5d12c3592a7880be6590072c4728b2afa1eaaeecdf7cadd8304c2d4b614af7af14efa00dda595be92de09c74b39df05d7d023db721f86992c57061a264dead21e24fa47816f43b77b8ccccde44bfc32a015134a2cfaf04c582fb839202b08b81543ea9358d5735e7c197762a6a39936e26de58690a02dfc273e6779e77708\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (8 mod 64).\n# DIGEST: de9156349b578f2f44945ec6a676a67a829daea1\nKEY: 60ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11b\nNONCE: e112a72933c7b54e\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a\nAD: 5f47e037446f5891d77df6\nCT: 8f211be563f98f493745cca0e385e5b0113027efe3b0a880805427e363014323c4f6c7e6b30d2466c70ed56d63157f2c4f6dabe14d5a22c6c708ab3fb667a6c64ce5c8de22f5261b\nTAG: e5807ffa59e0005c9dd7eef0b854ee1b2cfccef9977f8a963167cc563d844f795c4ce4f9d03da95e4cfd2fc80c9efb6424df8cd3b7875a6ca129da8f509ab09d1f0eec0211e0ffe5492913fb688796a29a8eac54f374e8948991059f6e73a68eba75a892b3e2ed5ab9680eb0b308b07337e75ad5b406c260af5d27955aa820bd0435549700e960e66c211000885e19b804579acfa8c526603f8d743491d916fd4d0e250159e485a4db2fea39a8eb9443516518e6612aae97b1d9b7ac48066d5fbe2c1be3b2e20233a2fb4d39052ef4ca3bfc47e561aaac9c57a7dbff922d6d997821f6b09bf3b4c91bc6162b150e17bfa2544f93f2bebcb4d20322bf0357fdffeec8f75679e6627b4ffbf8e0bfee63c8\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (9 mod 64).\n# DIGEST: 12812df3aa7f3bbc899f6f248f5590e02570c292\nKEY: ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be1\nNONCE: 12a72933c7b54ed4\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f\nAD: 47e037446f5891d77df660\nCT: eeb6afcfd2626da1230067ed9938f7df35e99d2ba1c91d0e91c3db53034a3dd2ce3352b06e3d1b9e8415ef4ced9b2257eb05bc86db8204a8bd943bde51423a09459fecd528faccb646\nTAG: a69c7d8db2c021284e73b3c07620022eb6f199509e34611ed671c3558ae7c103c78024d96c00c791f3450d1e0338598a246855811af4cc9ae1a6522487a4a77b57b58ce29038ab0a2036404eae59133512b9ea40e2d7176e1b36965a27ee2c898d6514872bec952a029d9d85bfb0c99d8b348db6a3bbfedb6d1a3128664c454b9ef29f075fecc469f233e18567fe16759b378600a1d71504231e6caee5688e9858e14fe6fe850d95d7c010865781f0457a22f53add7ef57071c7153d312ca303e4884b83c9acfe86686517d80ce271c148cf3ab6464a9751b66ac7682a5f885ad9301a5602c099e89977f06b41badd1c2ea1f7027a38b749e2ca1a3ff4e4889e6dbd3674a52c8e24d2c76f64a6bc77\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (10 mod 64).\n# DIGEST: f3c89f21c327fca4aa400fabea9e39780378e901\nKEY: 82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112\nNONCE: a72933c7b54ed4fa\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47\nAD: e037446f5891d77df660ed\nCT: e1eb2175bfee27951357b7536e2c3a4c607bf511d1922f6cce462fdf98de9dfbbea66d38884c270e29d08c5ace1d6bb7bcd2b46eaffc67a99e225927421a9894238cefa73bdb48694abf\nTAG: fc1d8ef98aa65ba8a288ca04990bfb373071633eb1e8f30847d3c19ebef66962cce12d015b045e10c9e0aa7f275137e00cb2c9a0508c0187827a74faca4bcd015620f1cdd8f72161bebbb8231ad4b705d1982db6f9fa1d2303c429469737a3141adf729729144f55223df1fb45705fb15adb5cd03c2936674a47d7f6aa5d2a4d9a017e57a4f5dd954504abb588866457730304878ca322f776e3c8e7becb8437002bc757d5b34b16d04ae4710553a624a3fca8866fb3d20672d6f4a2f937edecd58e68b7b0a8c39819ab48788956c1f3f5f4a15e7d13350090a20c61620c9181f03b4d68d7e4f336cb7e4a1a277df5101511150dd39fb43a84cfc480fd548035c8e9ec26602dd66d250fce39dfd8\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (11 mod 64).\n# DIGEST: e8e41988fad6c8b44c56544964cfe0a347b35b1e\nKEY: 933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a7\nNONCE: 2933c7b54ed4fad0\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e0\nAD: 37446f5891d77df660ed82\nCT: a799c4a6590a4c48735d1da9746e5441cb11b664daada5d4d68d3a0110c4ad8d5e96d7331d5f7a0d1df9af5da4208065b6bf31affdfcd4944e8ed55b0ba7b7911be1a9052fbd93d5fbe292\nTAG: 6a6e5ced88748f87682759b554d9685280e094e083d297dc5fd474c4a2605612b2f8b1c31dea24d58c25bcacfbf03b8b09dc662d6e1120868ae9a0f1dbd2799756136c2a26a22e3a61a0216e76e94393534586e1a59c570d8bdb37d5ee6d0762e60c7171fc7953e59d74b0f2ff4a061d27a7baa8ed138c51264b356d9a42b0768bca1c1c458acdc82bd621031e2ae7790596594d2f6eda2c8d58d4b53cf6990434da8aa9e9eafec648d52233e9b92994ca5cbc071dceeed57b02e36f93f8d22551660cc4c1e425aa77dcda3bf6c98bff7905becc075e1707e37453de8f300be5aabc96c1051fa46c796a2c8367a00af3c4dccc58bb7dc8aa2e21e0886eceb898080bbc7259648f2be9da0f1b56\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (12 mod 64).\n# DIGEST: d1c7b2c04dc25fe7b742a1d659aec20e1475ee4f\nKEY: 3f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a729\nNONCE: 33c7b54ed4fad0be\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037\nAD: 446f5891d77df660ed8293\nCT: 2b8ac97f05a67490bf16bc64381e9c49e7f348212d0645056ca5405e9e0a248b6918568481ceca70e20ae4b7c1f62700a2954188793b34504fa86decc73f667e5fae944211059dfa94ef072e\nTAG: 5f91838f37198290b43fc04a186db6a05261ea9916a1dd6450604ed8a7d0bb59751f6637f593ef1a7e3aab6421b7a0cc6b5b47477d36bf439806dd8156e2bc2e229bcbaed9a3beedfa383d674d3b91922e6248d1aa8ad62361a4bdcfd3d86daeb6d775a521916ecefa2244aefbb0cfc0ede1b1c0e0059a4d69850160d2f4f662ea2b77fb074a6de69feab87bb56f27edc3a42037a041007f0a08d204cbad0a9047f7798dad51e5c04126519b53772ad4f3017f9d9fe91920aa7585a5f2d95e7a8fe5c7b22fc696be10e308f939c34e52b7bc2e71b06a56e3ffa5a0ed529eaf5a8c4b6857b1f144f51fc8bbc858c88ede7ca325d231b34e4ae0e7ac8fec3e8f6a9bbc6f8975fec1e877f0d05046c3fd7a0e15ebb3\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (13 mod 64).\n# DIGEST: 116e20ff1e79e0af464d473b1e7c187f4dd66007\nKEY: 62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933\nNONCE: c7b54ed4fad0be90\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e03744\nAD: 6f5891d77df660ed82933f\nCT: 783a362232c871213daa72d58658aee2ceb4de66198df21e22732601", "0be056d5c4d2481ffead6c80733603b132b256d1c52d64eb8b700d614dca0adeacc0c7a05d1a64ee7b5c8163d1eae17fdd\nTAG: ba611208a3cc40e2cc638c335fd508441aaa15c612a5100c960543d2ceef9709bbb3e70904f3f2efac3112fc61bdfe7accfb5f0e9d640812a4f5b0676d95b1d5298eddc97ce3aa16ee761491e9f424af39119c9f56322b10e8575697bc93d1f6a63007ae085bd20c83fc32a5d4e59ce8840f75b8c52f6aeda4fc34f11301d64e058b39ff765e1ec9997ec51aeb43b35cba9ad4b020e7dcee79ad532b897faee018dae1231ceafa1a5fca1ff1a01f863580c9c07b13354e31b0067a2fb16477150ab6d027fe88276767ebb46b1029c7d6dcacbf418f10d932dea2ea161ff8a4f6d79e0bdbf0a67227d5c9100a45fde25e2d4e360c0c0942e9ce13b570b5ea149dfe422fea36251e226b3f7eb709ed7c7339aaff\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (14 mod 64).\n# DIGEST: c081d0d09b2c9eb39a372ef4a7b0246a0956b0f9\nKEY: be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7\nNONCE: b54ed4fad0be905d\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f\nAD: 5891d77df660ed82933f62\nCT: 894d8fc70288c7b8a5d12e63ed6e6e8c74b8d9837720762ccc519a42e024ee05e8f770180e5213a7c7ceac56cab05834d49847aa1432fcfad8286e092feddd421b33212e41716b3db5358903c11e\nTAG: c00612f3ee6619c87aa5c7958da77fdac74ea2ad1af9115fd003edc7bdb36f639dc2d89668f6c2440827a1e7bdb65acd172be229f8852d4b81d1d2ee1e167ff127fed768d0a6eb822c2fd88e733a0884f06e47d5f3a7e84e7f20d8b630c8e748a03f2eb807f3d6bf67d3f93ec97f22a3bfc477143f9e34049fd9143ad5e480bf538464fa847a5302e6d9ec3710122fe6c295191906d98d69e01e81a79de0538442a76a17fea214c74bec28c01370a0aed01e1a32a629857f5d48c3275b79a25d3fe549829e5d72d9d26c2e07fe133e214e40dfba4cd19ddccb01a6887bfba26db80b40eaee435a7619415af7be271739dc339fbe4a500db56613498b34c2b1f9dfbea13aff30c84fd1380ecd821b57cb3775\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (15 mod 64).\n# DIGEST: 6f7bb1f9e2772eb909c315e653e4737cfed78a18\nKEY: 8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b5\nNONCE: 4ed4fad0be905d41\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f58\nAD: 91d77df660ed82933f62be\nCT: e5d56aea96fb40312e288074a21691ed29f17a547529d2427e8bcd5024e617411c08999a8a514adc83a14fe27c51b0f7d44f684fc60274c009274ff9af14d4b1277cc03453e02c0ceb26c796432f0d\nTAG: 07cea5df6c6594985f9af65319e2fcb1882f6d1d66fae0ab595ee72dc4a1118a7ef8ea450209809349b41664ee21afcb053e8edfa53bb1e66d9aefde4c48c6ff5b5e411c1228cbf5c1021d605311a20bd6708aa004d7da8bf72ddce1cbc9a12100969131d596cca0fe61c82208d0848ae0d098036a07600cc4b443e344b06d3162c8ebe14850239f77d178152fee009b1bd81a68bbf632082f9a62dbe60a1ba579077842c713ab4d5619b7abb15eb8fd3b1ee1506fe8df31bc90a63eeeefc0f23ab5ec83f4a1e9fa8833f15c90d6b68615ce297b466d5d67a87ac9fb10a2ffba5a91d31d1b18aaee8c00ff1a8b8df9584a33e946e85d8c6a6c8719421b75a8a56f964725abb4a4be790acbd60efde68671\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (16 mod 64).\n# DIGEST: 172f4992e692a88f49628e5d3937959be01aed2e\nKEY: c55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54e\nNONCE: d4fad0be905d4120\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891\nAD: d77df660ed82933f62be8d\nCT: 7923c66ac88a9d3a2c9d9e714d491372caea0658b4e5692a7df8da934dce8525d0974848545ce89a44a735eedb22f18b5b8f1455c0aeedea9cb8f5c0bb51addd065a83c4e825ff3993ff58cf0af7577b\nTAG: 06b8d51726fe8d46fce9a59b084c3924c4aa9575d3b3f9b9e31a098c2c0475e460a89639863652164b724927ef13d2c52faeba797d38ddcb9274dfc6478c06626ec55954ce17df075f0b089ef155daf416980039458b7979afeefe9fa3e365ca19637b05cd17987e25f20e62031c32d441a102c22efb3660e4e3c13800acbfba0e7dc99175e35338b87ebb56d09a3b4bca72774d87e9cf92ce8e66917835c765129c8946c7f42ad8acd9afc22acc44a89dbebf6f4b2a55c139312559e2aaf6115aa617ce07cb2a63c66cbaeeeb5c95ce617928f93031f6dcbd3ee30a6fcd4cd9606695b690d95fb8d126c4962f49f11910a6e9daa2227f46a249819074a06cb5ffd449bd5744f9d9c70dc14475fd4b9a\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (17 mod 64).\n# DIGEST: 00133da1f7c63fd5f0eec364e9a359be02c1d3da\nKEY: 5b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4\nNONCE: fad0be905d41203f\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d7\nAD: 7df660ed82933f62be8dc5\nCT: e0b671d572a26f0553cdeca68a4d023615570ed0e9414e5783691fb6d1c2bc30bb4a7590d3138972345f3a55f2f90fdc8ad46555d41968a00a6462c2bc0931a18df5480e48cfcfcc00078314cabe0e44ce\nTAG: d01f174c6f726b83162a8a0734e1b1e9e9498fa067454e3a488cee1a04703987d5ce9a219b4ba168a809a181d6a291eae84f91705fc0701166400f24775bf5816a67ea6f011829ca07ef1aec6ac3b7ba0576c26b557b00fb76e84b6e633c48b8c425678ae12c922a7af7ce0484861efccf958ed418e2658b03b5c978fe624b16428c41a2a7ee1cc07c9d730b689cf92f2041b5e68908fc93d8221821106d73363e2d53df824a82841be5bdc0668c5b8759a1e79e193dac2e55e4cc083569fa727b952a45e71840fc330977e072457de678d3f3694e429131e25efd339421094512755604e1ec84efdb52259f6e8284bb7ebdf229cd3e4f1abfd6498e3b493b21184f8a42ba31f4f22dbeacbb1d977d\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (18 mod 64).\n# DIGEST: 60a6821269be6c5b985576b245f106128eb0b325\nKEY: 436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fa\nNONCE: d0be905d41203f5d\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77d\nAD: f660ed82933f62be8dc55b\nCT: aa02a8b8deeb507cd2b2ee187af85b5afa85583c258df91df9cf5307316d03b5d8aad0441bacc27c4cb26c56239423f8e46746978c0edd3c21018f6b9a1c39278f71b462c6da999a6f4d9513a47cd7986c88\nTAG: 5cea96fc3da1457f7e66f324a3c634829a6382fb75efc614bf944cafda4c9cde5bf3118838487401497849d59f895d761b8b0da9f339123aeab5b237edd48d6c1ab4120da7769a7f8510bfca3d7313f0f38dc6c34fea81f60dd3e421afef2d9a61e6b0d7be96b357f1a293fe5c21d4ee858725a4c088f49a24930d846d2c0fad98002fa66a618367425cbae16fe570f3058fcfa2544f1d085ddbc6226e35c4355c916660f7f8fef4f5ab705c93b5182269adb8a4eeff4e62ee278c0588b96043f1ad24ca39a7ad458f541101e1d6cef99d742e2e4a124e4f3a57986d0192537d956231f4e49f5a87f5b7f5a4cdae6cc647b90177dc4d81232c62bad3d99036812f84b3208ed2edb8058f4973abd7\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (19 mod 64).\n# DIGEST: e2593f3b6741a9ed9fa188fc06efd057556ee624\nKEY: 6965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0\nNONCE: be905d41203f5dce\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df6\nAD: 60ed82933f62be8dc55b43\nCT: 8b397fb4fa218359120058dbd145f4bd99def7e5e0a88249783128801b3828909ea19d9f5fb0f3e15ebd624fc32525796ccf9ec01b1da3acc6dec2a9306c57db4eeeeef4830575fd8166c13c23664d4df4cbac\nTAG: fe141cebcd20919976fe53fa1a9e186db43122704ac5dcfd23abc2da394907a9da4011bf32a3948b0ae848d6d010024c6f37191f6fe5cdc46430b915a9c5cc80329ab5d32797fc97bf3ca270d8b35c14e3091c99ca3947492613d183845ea5b80619d20c38434261dab80d4068449a0880eadc55f0b43cc344a875adfd23020b6e63c3015c887ef52c72750c09f60c7bc0dc29ac7a6494bf9771c4aa931aa440ad400c1cdff8f3d1bc4173977128d1eb57731e4b69d3e6d4715dc5d2a9cfdc2afeabf3513b3e3c107a83ac48f511750f887f59b10f40e8f2d197832dbb1febb82c29627232e3793c8a72d7033c86cf99fb54dd2e3ce099d4fdb50a63b06d5f595d5bf59474cb190245a36095bd\nTAG_LEN: 20\nNO_SEAL: 01\n\n# Test with maximal padding (20 mod 64).\n# DIGEST: 17450a437efe239e1858ac4062f34024305372be\nKEY: 65aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be\nNONCE: 905d41203f5dce99\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660\nAD: ed82933f62be8dc55b4369\nCT: 24e568a27d8bce547f628bfa545c4b7ccffce40f73b5abd6e1b60d5efca7cd6d5feda872e172f64d9193d3d2d3381efb52c05f98d3e1fb689fb05d7017654eb57346f1b3dee23b0f166e50531626582115af7cf0\nTAG: 4dae8797b02d7f1d8dc42b10f18973c094880a10207d9479aa8252df66e855a7a4", @@ -734,9 +795,9 @@ static const char *kData20[] = { "060e\nTAG_LEN: 20\n\n# DIGEST: 6b7295febce7fba8d79d1e7ab8fdfc452191e2ba\nKEY: 454879c41de9ac9f98233b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6\nNONCE: 944f44d722271233\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e\nAD: 6da12dd4c27f4372480974\nCT: a1d0537c3bddc7459a37268608d30ee8e15377c922a4300d7e7f00084cb45a9ab7cfc7f89dfb68f3cf7defd102012361782e977e22c12ac1d91d1e093a21ab26bd171b426af9af7b2dec9d1f2dcf78f19748b39e9b0736e24b44dabf677296db10dc28cd37751d020e1780e5fb00142e972baffc546b9b55bd0067e22ffee4f10312a590394a296cf6fba3456b3c0a64b662d232f185a41762bbad664f977328bba56b62f489d33821d4d604265c388b5ea852968db95ab844c7cb9498bd28d4b055760f83fa94f2a35492a4dd03a1fe9f0c2947fedd44b96948447054e2da7fd3b9d95bfcd0cfe3d1c909e84c9f87ba2a50c33d588592ff3c7c7b56442d52683e222f2610b740a2187159b05f2b15afbba7a97ef2dcb30813b89393706011397f4aa3c537e91fab098ecbf3a87c2185b9001ff1a78e104fbeac85bea4ad609bf1571d83969934d483794944c2e6bea9d778d2deac2d6344106c1dc30d56251faaab3f4dda43a2ed8c3345d9773e4fa4effc5edc3a68cc423b539ed63e8b0605b58aa881906e38b38f02a4df3708e9de4333056c96a02ad6d235636da61fedc631f705e771af9f522109a4d3b34d684b3b175d28a389ea574215131aa68016ea9cf3664b0baa6491f85d3a4370f73967e4c23637fd1d\nTAG: 131597a4dd3057b4a44498ea09294f2df51a5e81adcb3318ccd5\nTAG_LEN: 20\n\n# DIGEST: 1dadffba439570155af2509a548764a93042d23a\nKEY: e9ac9f98233b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722\nNONCE: 271233a825264e97\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c2\nAD: 7f4372480974454879c41d\nCT: 98c951eccacf8dcba5b819312f0ed234ea1cc06abee5f70888558000c2857de7411feffdf379c187d327943c63ab697675557a62c68c13f48d3970531225d5fb6c1434a126cfd6ba80b8f6dda08b3e3629ed12f7bbb45f45148f8544f0a8eb70c849260916eb62baa1bd850e082ad69ca5817594e8f26f63a1909ff03f5696b7a52f146af246c0c6485ea5826c89471c04fd6c373e9d0fef06f4a7b01400962ebfa4ef4166dc895619864accfef9a4be874111cb333518b33a3a2565d032a2434931a16e000d01e35317338ddbc48317517367603697a225d81fc63fcc7d4b8463bbd24910b4972375a995e13baa148b644993b9a7bd706ae64da00f898599957e406c1ab15fd44b6e85b41d47ffaec8136a5dadab324cb0ce95c738a1f8d246af90d98a68b8ab7003d74aa29591b58ca7b2dc38f21f4cfbc04f2e239728e1350b0f074293a13970b264bee368ff98c6960a805346c19702983d3ddfb6306f24cc7f8224e553b0668180787e48ca8e5d851f84df71d5ce6fd7815d39d7e3941b8e0562af98e6e244216bf418d7ca2d9e29ecd3997573b2c4d92aea1a5a82f2272af1218b379ca40a28cc7ce09ad60028a5a6aac6ce145cc3936f89a5d34ba54aeec8d99f84ebf7367fa5fdc12def2294fd3fa3299ba1a59aacc0d7\nTAG: f65b77267d53b2dfc87a936ae08ef7a3f630176553\nTAG_LEN: 20\n\n# DIGEST: e654b4c78e1c0061eea2996fc126c9bfd41eb6d9\nKEY: 3b5a7379a561792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825\nNONCE: 264e977045318c9b\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f43724809\nAD: 74454879c41de9ac9f9823\nCT: 5a1c2b7a8d5bc74901521e1300567f30e2b7755f004ddcfd8fe64f471cbaec4bc6d445ea931bafe6ad78034d0ac1d3916f1e0405c2f2aa4b193c2cd599d34b86029840ad379b136aea5c2a74ea70e22e8c8d1e017a2f7d47f8ebac7b85087075c28d6d2846e357ce031abe09e03629a32cef0b205d631f36ec9a1c9c4e90a80900e01688c7298b99be65f204ebaf312364bfdf57d9e16b0142e879a47b9ae0e96fc62e90883624ee2dc110f3a83ab341f4558f360df399170bbae57cb2eb377a87aaed9755e8057d76609d447a33a8255450504b71439fc0d03e0fffb775019ebf921325b42ef56e1b454b5c87ba5daa1f0d0920e860eea43c913d417cd9e9b6676759a4e2c71b0180b432fe2aab4e4fcffb51b4198ffbedbfcdb4dd4e105847f5a5832e85744f34bf3b9929ffeb177ceb4c5e68585a3ff8fda6569921b3d093a2f1d77e710f78245eacd471af88da8ff8f268293845a9a8550ef34e2bbff9d6cf55b18987c71eb98803bac42b0e6c062015fafb754c6a75f927cac4a8adfcfa8ee05a3f115f1f90d734f78180aec2aa621fa7908d350b0cd8550895cf4b5c3cc75eb95fa574f9a91c1f5efa61f054bedd9267f10a08a21b19e63754de10a1bb0c4ffd8c5c08558882a2f98f1175920a71b981affffde44ae1c9281eee161c4c\nTAG: 28f3243632b13692a2f175644a0e192d8102dd9e2affc5c1\nTAG_LEN: 20\n\n# DIGEST: 654b8591c7f0506261713e9ce7a6fd24a6b9357e\nKEY: 61792c0f3116430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045\nNONCE: 318c9b66262c0f03\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c4\nAD: 1de9ac9f98233b5a7379a5\nCT: 62d0c56ae3e695bafc3cfa3c2d8b9d17ac8ff3b84ccac28d568c1ac84e1574ea06f31605caf86d4e809e39e9c275eed4a8f27eb00dc78e1c10dae719519d949dbc22e00d8644bc3806e54e6531864ae4cb5694002e2a3d7146b39b0b38acadbf1651401805f6394831c608b0478d496cc939b24aa3d3e6d445faceb798a69ae1308a593244645e242829f64f7945d0af8af0eeb6d391c69c2d5bf7b00e42092b36c23362bdd627af43ca7336d88cc36e95ede07b83afb54c8758678d19e0ea7956d8f26776b0f4b6b637c1152853651b6c130f436ffa2d4fd0c344e7583c5e56d6262f43767a1011d8398311dd6e3d7f9e", "a89d3eb3f6a1a9cb98905c0761fc5be1d83005fb9ca039b877c30b402743bdf0109ee5de42eef860be676a399a206c08dca8e757f059f7d9611137039b9053430e7d6406abcbf7aed645110aae84f758fcf0d225738cc7c90ace5d83eb9fe65d1e65efa4f6c9d808060cb0f72605e3d7c70e0d13d84689aa1e44aa4dcb152f230d456eb6cf520898bb249262d30c64fde02d6894f72ddff201e4bc41c5fc1f394f2620f764d40098292b04aee45e26812f3abf9a020b5215beb7938e2c121e809ab825d22a2d560bb9bde47572ecb891dd49b38f41af9649dfbdc83ab9bceb444bacdfca2fcbefd623364d4e255e2c0f3164ad92\nTAG: 42174887a9a11a8ac5d1d13e83f8502a3cb0310bbf46b24ff42e3d\nTAG_LEN: 20\n\n# DIGEST: 1eaad32c8d0cefaa5e2c503bb2185a73e6387fac\nKEY: 16430e8b6ea058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b6626\nNONCE: 2c0f0368fe9d0cb7\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98\nAD: 233b5a7379a561792c0f31\nCT: cc269c9aed42c9ba90c768710fa03985372a219f391327e438b1593af29aaf2b66cf8fd60f137d8ce8438a7bcbf7c1c7010c06636f191802daa26fe12ac1c1458baefb2a51fc7361b2d98311c2eaa27e046fffbb76fc855ac01a1321672658e394043367e89478a789d662c88e91642af53824097326d991abd62d1ab818452fc152aa1bd05032027fbb691886d9269937f7f57e214a2186a191b2249ba6fe79b69a94623d85ef0db6b5c2363627ea15a614e6ee42ce0a26a90faaa3ec45451c69c7d472d98b0376a95503b16c6f17eeeb42e0ad5c8775584819aa01309e6071e6b9494da6ddcf992ec6bfc81e0031d74353afa042abfe62fae02792bb6dcae82694cb651689e4039208bf677c90ed6245606cae81732d9d32043e5435f8c40cb76b55a03593dda1271aaccdbc24f18c9a881c77e1dca0e62bfdd36208ee94370b166d66203dfb90c8602dfb48159410840c669c47e7514bf91ef603834bc213173458a87909979b3b77aaa77262e1a634fcb40241818f544f9d207e91ca1f46f77c5c4f606398938f764080dda0978c6b76ce76830a15098870e72b5c9f4975b495d2c5d969688b555773601ad8c857ca8c38565674539fa71a8acadac5415b563f55811b0c010ca1e6793ad08e6c830a0ec2b385402fb8af3b6f0ea0b70b458667953207e4d44f1959\nTAG: ecd2bdb2e683ff8bc7d20482e698ce2b608032094cc2\nTAG_LEN: 20\n\n# DIGEST: 862c0517b3658e9b9cd27db608d49e24e9b4667d\nKEY: a058c4799eea80abde04ee1de13e937af8f1a6944f44d722271233a825264e977045318c9b66262c0f0368fe\nNONCE: 9d0cb746bbd55813\nIN: 936a91d0b5d2c0267218cb7090c6171386d641b87797b684e0fb56f97c3961d8afa22993a340b9b3c589c7481df3f4183aa23fd8d7efd88503f78b8ed1c8e9ba2fd6773e0d0c302a5f47e037446f5891d77df660ed82933f62be8dc55b436965aabe477e0cdd46be99371eb8da7dac997deafd64b1fc65de39f4f03541a11be112a72933c7b54ed4fad0be905d41203f5dce998f8fb2eaad409ae02116417dae0cef457b9e5e16dcc5b6f25607f00d033fb95fb09e4d00d6172e780ab8b700433a957a741c9eb80f2b021b1444769da00fcfab0f5f93b511060c9c5f3aacefe61b184ad2463939ed518ce97c3fdd293d72afc09ffdd4f41963249cd299b92e55ca24d8c078c49f78c7e713710a025cb8b9d71d2989ab33e978c4451e3be585a29a2af12feef71e1063b0b4e6e899200304bd3508132a027d1ff4c047b3ef4f57a74706de4b381c692ef164101b89b476f72b27f06f520c9267cf71408a41729bacb5877e72cdfcfa76aed06707a07c3dab699719fe882eee2fee55ed8b11534c870dc695b814bdf1a87bb1052c6755a7a116bfc9095da49db3d71f4b975c5d503f478b22dc8253bee6fd1b174c307f01be95abaa9bee5857772305daa4b550d75f05d8089850fea3711265bf782610460bfd24ba022e6da12dd4c27f4372480974454879c41de9ac9f98233b5a7379\nAD: a561792c0f3116430e8b6e\nCT: def7eba4397065d05a7a1b742179c1d8eff65e7e4ac18bec49ed020a95497a58af4ce62679a36b77f95f72913c2a58184ea0c3b59b60784bdf63893a2a84f76ab2b6324a218361316971ebb1e2850b6c7baaf9130715580626bf298f60d862cc4b9c4f353a9e4c7536fd697ece9407eb8ad434c97e325cebd5aa0cf4a5342724f2950c8623aa3a5322f2e06a6b1d71a57b22a2f85ed1acacbeba192cb29ced37983e4231bb930c07f7266728c54e8fa9a0b7195975095fd714440e07d63aa87778061a361b4d44f0241a504089b738cdf3a6323b7a709d39637a2c61677c1f034214a4da6471a89425a5cc6040f37261b9a8e55589b2c24a01b4379dfe00ce758e9e617b6d15abcf0974be46d151c5d26e69c50d3fe68d1854b788d6a43e72a00b1602bb9e7557c4c298b99cccaa17fd950123d672978cd359e115eceb88480d59f5496a920949e09d0590283280d78df0ee068c475706701034b5b8686c60e2c4c4d4bafb2dd25c86293d472d195186f3fbaaaa000cf678295143aa290b011ec35e1eb2dcc6ad12593a934b60af7b570bc59569df2e99bf618aaa60e533265e2bfcfe3e01dd1620cd7d6df8b70726b5fa1191b0cdbe627f714744b2bf2abaddf800cc091ce5ee447f2a61ad36094743182ebbe236745bbeb27a946c8d8dba54dd3597fc4328bb3fa5f43371b531bb\nTAG: bcb4795a551fa0b1d147e2c8f70c31f20a60228963076b32bb\nTAG_LEN: 20\n\n", }; -static const size_t kLen21 = 116191; +static const size_t kLen22 = 116191; -static const char *kData21[] = { +static const char *kData22[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-128-CBC kat_aes/CBCGFSbox128.rsp kat_aes/CBCKeySbox128.rsp kat_aes/CBCVarKey128.rsp kat_aes/CBCVarTxt128.rsp\"\n\n# File 1: kat_aes/CBCGFSbox128.rsp\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: f34481ec3cc627bacd5dc3fb08f273e6\nCiphertext: 0336763e966d92595a567cc9ce537f5e\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 9798c4640bad75c7c3227db910174e72\nCiphertext: a9a1631bf4996954ebc093957b234589\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 96ab5c2ff612d9dfaae8c31f30c42168\nCiphertext: ff4f8391a6a40ca5b25d23bedd44a597\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 6a118a874519e64e9963798a503f1d35\nCiphertext: dc43be40be0e53712f7e2bf5ca707209\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: cb9fceec81286ca3e989bd979b0cb284\nCiphertext: 92beedab1895a94faa69b632e5cc47ce\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: b26aeb1874e47ca8358ff22378f09144\nCiphertext: 459264f4798f6a78bacb89c15ed3d601\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 58c8e00b2631686d54eab84b91f0aca1\nCiphertext: 08a4e2efec8a8e3312ca7460b9040bbf\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0336763e966d92595a567cc9ce537f5e\nPlaintext: f34481ec3cc627bacd5dc3fb08f273e6\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a9a1631bf4996954ebc093957b234589\nPlaintext: 9798c4640bad75c7c3227db910174e72\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ff4f8391a6a40ca5b25d23bedd44a597\nPlaintext: 96ab5c2ff612d9dfaae8c31f30c42168\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: dc43be40be0e53712f7e2bf5ca707209\nPlaintext: 6a118a874519e64e9963798a503f1d35\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 92beedab1895a94faa69b632e5cc47ce\nPlaintext: cb9fceec81286ca3e989bd979b0cb284\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 459264f4798f6a78bacb89c15ed3d601\nPlaintext: b26aeb1874e47ca8358ff22378f09144\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 08a4e2efec8a8e3312ca7460b9040bbf\nPlaintext: 58c8e00b2631686d54eab84b91f0aca1\n\n# File 2: kat_aes/CBCKeySbox128.rsp\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 10a58869d74be5a374cf867cfb473859\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6d251e6944b051e04eaa6fb4dbf78465\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: caea65cdbb75e9169ecd22ebe6e54675\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6e29201190152df4ee058139def610bb\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: a2e2fa9baf7d20822ca9f0542f764a41\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c3b44b95d9d2f25670eee9a0de099fa3\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: b6364ac4e1de1e285eaf144a2415f7a0\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5d9b05578fc944b3cf1ccf0e746cd581\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 64cf9c7abc50b888af65f49d521944b2\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f7efc89d5dba578104016ce5ad659c05\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 47d6742eefcc0465dc96355e851b64d9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0306194f666d183624aa230a8b264ae7\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 3eb39790678c56bee34bbcdeccf6cdb5\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 858075d536d79ccee571f7d7204b1f67\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 64110a924f0743d500ccadae72c13427\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 35870c6a57e9e92314bcb8087cde72ce\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 18d8126516f8a12ab1a36d9f04d68e51\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6c68e9be5ec41e22c825b7c7affb4363\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: f530357968578480b398a3c251cd1093\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f5df39990fc688f1b07224cc03e86cea\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: da84367f325d42d601b4326964802e8e\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: bba071bcb470f8f6586e5d3add18bc66\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: e37b1c6aa2846f6fdb413f238b089f23\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 43c9f7e62f5d288bb27aa40ef8fe1ea8\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 6c002b682483e0cabcc731c253be5674\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3580d19cff44f1014a7c966a69059de5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 143ae8ed6555aba96110ab58893a8ae1\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 806da864dd29d48deafbe764f8202aef\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: b69418a85332240dc82492353956ae0c\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a303d940ded8f0baff6f75414cac5243\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 71b5c08a1993e1362e4d0ce9b22b78d5\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c2dabd117f8a3ecabfbb11d12194d9d0\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: e234cdca2606b81f29408d5f6da21206\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fff60a4740086b3b9c56195b98d91a7b\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 13237c49074a3da078dc1d828bb78c6f\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8146a08e2357f0caa30ca8c94d1a0544\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 3071a2a48fe6cbd04f1a129098e308f8\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4b98e06d356deb07ebb824e5713f7be3\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 90f42ec0f68385f2ffc5dfc03a654dce\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7a20a53d460fc9ce0423a7a0764c6cf2\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: febd9a24d8b65c1c787d50a4ed3619a9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f4a70d8af877f9b02b4c40df57d45b17\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 10a58869d74be5a374cf867cfb473859\nIV: 00000000000000000000000000000000\nCiphertext: 6d251e6944b051e04eaa6fb4dbf78465\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: caea65cdbb75e9169ecd22ebe6e54675\nIV: 00000000000000000000000000000000\nCiphertext: 6e29201190152df4ee058139def610bb\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: a2e2fa9baf7d20822ca9f0542f764a41\nIV: 00000000000000000000000000000000\nCiphertext: c3b44b95d9d2f25670eee9a0de099fa3\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: b6364ac4e1de1e285eaf144a2415f7a0\nIV: 00000000000000000000000000000000\nCiphertext: 5d9b05578fc944b3cf1ccf0e746cd581\nPlaintext: 00000000000000000000000", "000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 64cf9c7abc50b888af65f49d521944b2\nIV: 00000000000000000000000000000000\nCiphertext: f7efc89d5dba578104016ce5ad659c05\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 47d6742eefcc0465dc96355e851b64d9\nIV: 00000000000000000000000000000000\nCiphertext: 0306194f666d183624aa230a8b264ae7\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 3eb39790678c56bee34bbcdeccf6cdb5\nIV: 00000000000000000000000000000000\nCiphertext: 858075d536d79ccee571f7d7204b1f67\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 64110a924f0743d500ccadae72c13427\nIV: 00000000000000000000000000000000\nCiphertext: 35870c6a57e9e92314bcb8087cde72ce\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 18d8126516f8a12ab1a36d9f04d68e51\nIV: 00000000000000000000000000000000\nCiphertext: 6c68e9be5ec41e22c825b7c7affb4363\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: f530357968578480b398a3c251cd1093\nIV: 00000000000000000000000000000000\nCiphertext: f5df39990fc688f1b07224cc03e86cea\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: da84367f325d42d601b4326964802e8e\nIV: 00000000000000000000000000000000\nCiphertext: bba071bcb470f8f6586e5d3add18bc66\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: e37b1c6aa2846f6fdb413f238b089f23\nIV: 00000000000000000000000000000000\nCiphertext: 43c9f7e62f5d288bb27aa40ef8fe1ea8\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 6c002b682483e0cabcc731c253be5674\nIV: 00000000000000000000000000000000\nCiphertext: 3580d19cff44f1014a7c966a69059de5\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 143ae8ed6555aba96110ab58893a8ae1\nIV: 00000000000000000000000000000000\nCiphertext: 806da864dd29d48deafbe764f8202aef\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: b69418a85332240dc82492353956ae0c\nIV: 00000000000000000000000000000000\nCiphertext: a303d940ded8f0baff6f75414cac5243\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 71b5c08a1993e1362e4d0ce9b22b78d5\nIV: 00000000000000000000000000000000\nCiphertext: c2dabd117f8a3ecabfbb11d12194d9d0\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: e234cdca2606b81f29408d5f6da21206\nIV: 00000000000000000000000000000000\nCiphertext: fff60a4740086b3b9c56195b98d91a7b\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 13237c49074a3da078dc1d828bb78c6f\nIV: 00000000000000000000000000000000\nCiphertext: 8146a08e2357f0caa30ca8c94d1a0544\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 3071a2a48fe6cbd04f1a129098e308f8\nIV: 00000000000000000000000000000000\nCiphertext: 4b98e06d356deb07ebb824e5713f7be3\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 90f42ec0f68385f2ffc5dfc03a654dce\nIV: 00000000000000000000000000000000\nCiphertext: 7a20a53d460fc9ce0423a7a0764c6cf2\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: febd9a24d8b65c1c787d50a4ed3619a9\nIV: 00000000000000000000000000000000\nCiphertext: f4a70d8af877f9b02b4c40df57d45b17\nPlaintext: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey128.rsp\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: 80000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0edd33d3c621e546455bd8ba1418bec8\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: c0000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4bc3f883450c113c64ca42e1112a9e87\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: e0000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 72a1da770f5d7ac4c9ef94d822affd97\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: f0000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 970014d634e2b7650777e8e84d03ccd8\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: f8000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f17e79aed0db7e279e955b5f493875a7\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fc000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9ed5a75136a940d0963da379db4af26a\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fe000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c4295f83465c7755e8fa364bac6a7ea5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ff000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b1d758256b28fd850ad4944208cf1155\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ff800000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 42ffb34c743de4d88ca38011c990890b\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffc00000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9958f0ecea8b2172c0c1995f9182c0f3\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffe00000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 956d7798fac20f82a8823f984d06f7f5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fff00000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a01bf44f2d16be928ca44aaf7b9b106b\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fff80000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b5f1a33e50d40d103764c76bd4c6b6f8\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffc0000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2637050c9fc0d4817e2d69de878aee8d\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffe0000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 113ecbe4a453269a0dd26069467fb5b5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffff0000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 97d0754fe68f11b9e375d070a608c884\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffff8000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c6a0b3e998d05068a5399778405200b4\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffc000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: df556a33438db87bc41b1752c55e5e49\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffe000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 90fb128d3a1af6e548521bb962bf1f05\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffff000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 26298e9c1db517c215fadfb7d2a8d691\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffff800000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a6cb761d61f8292d0df393a279ad0380\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffc00000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 12acd89b13cd5f8726e34d44fd486108\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffe00000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 95b1703fc57ba09fe0c", "3580febdd7ed4\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffff00000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: de11722d893e9f9121c381becc1da59a\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffff80000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6d114ccb27bf391012e8974c546d9bf2\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffc0000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5ce37e17eb4646ecfac29b9cc38d9340\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffe0000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 18c1b6e2157122056d0243d8a165cddb\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffff0000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 99693e6a59d1366c74d823562d7e1431\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffff8000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6c7c64dc84a8bba758ed17eb025a57e3\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffc000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e17bc79f30eaab2fac2cbbe3458d687a\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffe000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1114bc2028009b923f0b01915ce5e7c4\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffff000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9c28524a16a1e1c1452971caa8d13476\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffff800000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ed62e16363638360fdd6ad62112794f0\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffc00000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5a8688f0b2a2c16224c161658ffd4044\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffe00000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 23f710842b9bb9c32f26648c786807ca\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffff00000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 44a98bf11e163f632c47ec6a49683a89\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffff80000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0f18aff94274696d9b61848bd50ac5e5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffc0000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 82408571c3e2424540207f833b6dda69\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffe0000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 303ff996947f0c7d1f43c8f3027b9b75\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffff0000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7df4daf4ad29a3615a9b6ece5c99518a\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffff8000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c72954a48d0774db0b4971c526260415\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffc000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1df9b76112dc6531e07d2cfda04411f0\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffe000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8e4d8e699119e1fc87545a647fb1d34f\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffff000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e6c4807ae11f36f091c57d9fb68548d1\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffff800000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8ebf73aad49c82007f77a5c1ccec6ab4\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffc00000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4fb288cc2040049001d2c7585ad123fc\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffe00000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 04497110efb9dceb13e2b13fb4465564\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffff00000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 75550e6cb5a88e49634c9ab69eda0430\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffff80000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b6768473ce9843ea66a81405dd50b345\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffc0000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cb2f430383f9084e03a653571e065de6\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffe0000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ff4e66c07bae3e79fb7d210847a3b0ba\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffff0000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7b90785125505fad59b13c186dd66ce3\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffff8000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8b527a6aebdaec9eaef8eda2cb7783e5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffc000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 43fdaf53ebbc9880c228617d6a9b548b\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffe000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 53786104b9744b98f052c46f1c850d0b\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffff000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b5ab3013dd1e61df06cbaf34ca2aee78\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffff800000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7470469be9723030fdcc73a8cd4fbb10\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffffc00000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a35a63f5343ebe9ef8167bcb48ad122e\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: ffffffffffffffe00000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fd8687f0757a210e9fdf181204c30863\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffff00000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7a181e84bd5457d26a88fbae96018fb0\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffff80000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 653317b9362b6f9b9e1a580e68d494b5\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffffc0000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 995c9dc0b689f03c45867b5faa5c18d1\n\nCipher: AES-128-CBC\nOperation: ENCRYPT\nKey: fffffffffffffffe0000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 77a4d96d56dda398b9aabecfc75729fd\n\nCipher: AES-128-C", @@ -753,9 +814,9 @@ static const char *kData21[] = { "0000000000000000\nCiphertext: b87c921b91829ef3b13ca541ee1130a6\nPlaintext: ffffffffffffffffffff800000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2e65eb6b6ea383e109accce8326b0393\nPlaintext: ffffffffffffffffffffc00000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9ca547f7439edc3e255c0f4d49aa8990\nPlaintext: ffffffffffffffffffffe00000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a5e652614c9300f37816b1f9fd0c87f9\nPlaintext: fffffffffffffffffffff00000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 14954f0b4697776f44494fe458d814ed\nPlaintext: fffffffffffffffffffff80000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7c8d9ab6c2761723fe42f8bb506cbcf7\nPlaintext: fffffffffffffffffffffc0000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: db7e1932679fdd99742aab04aa0d5a80\nPlaintext: fffffffffffffffffffffe0000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4c6a1c83e568cd10f27c2d73ded19c28\nPlaintext: ffffffffffffffffffffff0000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 90ecbe6177e674c98de412413f7ac915\nPlaintext: ffffffffffffffffffffff8000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 90684a2ac55fe1ec2b8ebd5622520b73\nPlaintext: ffffffffffffffffffffffc000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7472f9a7988607ca79707795991035e6\nPlaintext: ffffffffffffffffffffffe000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 56aff089878bf3352f8df172a3ae47d8\nPlaintext: fffffffffffffffffffffff000000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 65c0526cbe40161b8019a2a3171abd23\nPlaintext: fffffffffffffffffffffff800000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 377be0be33b4e3e310b4aabda173f84f\nPlaintext: fffffffffffffffffffffffc00000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9402e9aa6f69de6504da8d20c4fcaa2f\nPlaintext: fffffffffffffffffffffffe00000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 123c1f4af313ad8c2ce648b2e71fb6e1\nPlaintext: ffffffffffffffffffffffff00000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1ffc626d30203dcdb0019fb80f726cf4\nPlaintext: ffffffffffffffffffffffff80000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 76da1fbe3a50728c50fd2e621b5ad885\nPlaintext: ffffffffffffffffffffffffc0000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 082eb8be35f442fb52668e16a591d1d6\nPlaintext: ffffffffffffffffffffffffe0000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e656f9ecf5fe27ec3e4a73d00c282fb3\nPlaintext: fffffffffffffffffffffffff0000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2ca8209d63274cd9a29bb74bcd77683a\nPlaintext: fffffffffffffffffffffffff8000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 79bf5dce14bb7dd73a8e3611de7ce026\nPlaintext: fffffffffffffffffffffffffc000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3c849939a5d29399f344c4a0eca8a576\nPlaintext: fffffffffffffffffffffffffe000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ed3c0a94d59bece98835da7aa4f07ca2\nPlaintext: ffffffffffffffffffffffffff000000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 63919ed4ce10196438b6ad09d99cd795\nPlaintext: ffffffffffffffffffffffffff800000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7678f3a833f19fea95f3c6029e2bc610\nPlaintext: ffffffffffffffffffffffffffc00000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3aa426831067d36b92be7c5f81c13c56\nPlaintext: ffffffffffffffffffffffffffe00000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9272e2d2cdd11050998c845077a30ea0\nPlaintext: fffffffffffffffffffffffffff00000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 088c4b53f5ec0ff814c19adae7f6246c\nPlaintext: fffffffffffffffffffffffffff80000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4010a5e401fdf0a0354ddbcc0d012b17\nPlaintext: fffffffffffffffffffffffffffc0000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a87a385736c0a6189bd6589bd8445a93\nPlaintext: fffffffffffffffffffffffffffe0000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 545f2b83d9616dccf60fa9830e9cd287\nPlaintext: ffffffffffffffffffffffffffff0000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4b706f7f92406352394037a6d4f4688d\nPlaintext: ffffffffffffffffffffffffffff8000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b7972b3941c44b90afa7b264bfba7387\nPlaintext: ffffffffffffffffffffffffffffc000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6f45732cf10881546f0fd23896d2bb60\nPlaintext: ffffffffffffffffffffffffffffe000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2e3579ca15af27f64b3c955a5bfc30ba\nPlaintext: fffffffffffffffffffffffffffff000\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 34a2c5a91ae2aec99b7d1b5fa6780447\nPlaintext: fffffffffffffffffffffffffffff800\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a4d6616bd04f87335b0e53351227a9ee\nPlaintext: fffffffffffffffffffffffffffffc00\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7f692b03945867d16179a8cefc83ea3f\nPlaintext: fffffffffffffffffffffffffffffe00\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3bd141ee84a0e6414a26e7a4f281f8a2\nPlaintext: ffffffffffffffffffffffffffffff00\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d17", "88f572d98b2b16ec5d5f3922b99bc\nPlaintext: ffffffffffffffffffffffffffffff80\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0833ff6f61d98a57b288e8c3586b85a6\nPlaintext: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8568261797de176bf0b43becc6285afb\nPlaintext: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f9b0fda0c4a898f5b9e6f661c4ce4d07\nPlaintext: fffffffffffffffffffffffffffffff0\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8ade895913685c67c5269f8aae42983e\nPlaintext: fffffffffffffffffffffffffffffff8\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 39bde67d5c8ed8a8b1c37eb8fa9f5ac0\nPlaintext: fffffffffffffffffffffffffffffffc\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5c005e72c1418c44f569f2ea33ba54f3\nPlaintext: fffffffffffffffffffffffffffffffe\n\nCipher: AES-128-CBC\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3f5b8cc9ea855a0afa7347d23e8d664e\nPlaintext: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen22 = 116210; +static const size_t kLen23 = 116210; -static const char *kData22[] = { +static const char *kData23[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-128-CTR -swap-iv-plaintext kat_aes/CBCGFSbox128.rsp kat_aes/CBCKeySbox128.rsp kat_aes/CBCVarKey128.rsp kat_aes/CBCVarTxt128.rsp\"\n\n# File 1: kat_aes/CBCGFSbox128.rsp\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: f34481ec3cc627bacd5dc3fb08f273e6\nCiphertext: 0336763e966d92595a567cc9ce537f5e\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 9798c4640bad75c7c3227db910174e72\nCiphertext: a9a1631bf4996954ebc093957b234589\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 96ab5c2ff612d9dfaae8c31f30c42168\nCiphertext: ff4f8391a6a40ca5b25d23bedd44a597\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 6a118a874519e64e9963798a503f1d35\nCiphertext: dc43be40be0e53712f7e2bf5ca707209\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: cb9fceec81286ca3e989bd979b0cb284\nCiphertext: 92beedab1895a94faa69b632e5cc47ce\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: b26aeb1874e47ca8358ff22378f09144\nCiphertext: 459264f4798f6a78bacb89c15ed3d601\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 58c8e00b2631686d54eab84b91f0aca1\nCiphertext: 08a4e2efec8a8e3312ca7460b9040bbf\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0336763e966d92595a567cc9ce537f5e\nIV: f34481ec3cc627bacd5dc3fb08f273e6\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a9a1631bf4996954ebc093957b234589\nIV: 9798c4640bad75c7c3227db910174e72\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ff4f8391a6a40ca5b25d23bedd44a597\nIV: 96ab5c2ff612d9dfaae8c31f30c42168\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: dc43be40be0e53712f7e2bf5ca707209\nIV: 6a118a874519e64e9963798a503f1d35\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 92beedab1895a94faa69b632e5cc47ce\nIV: cb9fceec81286ca3e989bd979b0cb284\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 459264f4798f6a78bacb89c15ed3d601\nIV: b26aeb1874e47ca8358ff22378f09144\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 08a4e2efec8a8e3312ca7460b9040bbf\nIV: 58c8e00b2631686d54eab84b91f0aca1\n\n# File 2: kat_aes/CBCKeySbox128.rsp\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 10a58869d74be5a374cf867cfb473859\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6d251e6944b051e04eaa6fb4dbf78465\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: caea65cdbb75e9169ecd22ebe6e54675\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6e29201190152df4ee058139def610bb\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: a2e2fa9baf7d20822ca9f0542f764a41\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c3b44b95d9d2f25670eee9a0de099fa3\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: b6364ac4e1de1e285eaf144a2415f7a0\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5d9b05578fc944b3cf1ccf0e746cd581\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 64cf9c7abc50b888af65f49d521944b2\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f7efc89d5dba578104016ce5ad659c05\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 47d6742eefcc0465dc96355e851b64d9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0306194f666d183624aa230a8b264ae7\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 3eb39790678c56bee34bbcdeccf6cdb5\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 858075d536d79ccee571f7d7204b1f67\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 64110a924f0743d500ccadae72c13427\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 35870c6a57e9e92314bcb8087cde72ce\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 18d8126516f8a12ab1a36d9f04d68e51\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6c68e9be5ec41e22c825b7c7affb4363\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: f530357968578480b398a3c251cd1093\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f5df39990fc688f1b07224cc03e86cea\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: da84367f325d42d601b4326964802e8e\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: bba071bcb470f8f6586e5d3add18bc66\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: e37b1c6aa2846f6fdb413f238b089f23\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 43c9f7e62f5d288bb27aa40ef8fe1ea8\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 6c002b682483e0cabcc731c253be5674\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3580d19cff44f1014a7c966a69059de5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 143ae8ed6555aba96110ab58893a8ae1\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 806da864dd29d48deafbe764f8202aef\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: b69418a85332240dc82492353956ae0c\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a303d940ded8f0baff6f75414cac5243\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 71b5c08a1993e1362e4d0ce9b22b78d5\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c2dabd117f8a3ecabfbb11d12194d9d0\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: e234cdca2606b81f29408d5f6da21206\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fff60a4740086b3b9c56195b98d91a7b\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 13237c49074a3da078dc1d828bb78c6f\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8146a08e2357f0caa30ca8c94d1a0544\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 3071a2a48fe6cbd04f1a129098e308f8\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4b98e06d356deb07ebb824e5713f7be3\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 90f42ec0f68385f2ffc5dfc03a654dce\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7a20a53d460fc9ce0423a7a0764c6cf2\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: febd9a24d8b65c1c787d50a4ed3619a9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f4a70d8af877f9b02b4c40df57d45b17\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 10a58869d74be5a374cf867cfb473859\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6d251e6944b051e04eaa6fb4dbf78465\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: caea65cdbb75e9169ecd22ebe6e54675\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6e29201190152df4ee058139def610bb\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: a2e2fa9baf7d20822ca9f0542f764a41\nPlaintext: 00000000000000000000000000000000\nCiphertext: c3b44b95d9d2f25670eee9a0de099fa3\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: b6364ac4e1de1e285eaf144a2415f7a0\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5d9b05578fc944b3cf1ccf0e746cd581\nIV: 0000", "0000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 64cf9c7abc50b888af65f49d521944b2\nPlaintext: 00000000000000000000000000000000\nCiphertext: f7efc89d5dba578104016ce5ad659c05\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 47d6742eefcc0465dc96355e851b64d9\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0306194f666d183624aa230a8b264ae7\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 3eb39790678c56bee34bbcdeccf6cdb5\nPlaintext: 00000000000000000000000000000000\nCiphertext: 858075d536d79ccee571f7d7204b1f67\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 64110a924f0743d500ccadae72c13427\nPlaintext: 00000000000000000000000000000000\nCiphertext: 35870c6a57e9e92314bcb8087cde72ce\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 18d8126516f8a12ab1a36d9f04d68e51\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6c68e9be5ec41e22c825b7c7affb4363\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: f530357968578480b398a3c251cd1093\nPlaintext: 00000000000000000000000000000000\nCiphertext: f5df39990fc688f1b07224cc03e86cea\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: da84367f325d42d601b4326964802e8e\nPlaintext: 00000000000000000000000000000000\nCiphertext: bba071bcb470f8f6586e5d3add18bc66\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: e37b1c6aa2846f6fdb413f238b089f23\nPlaintext: 00000000000000000000000000000000\nCiphertext: 43c9f7e62f5d288bb27aa40ef8fe1ea8\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 6c002b682483e0cabcc731c253be5674\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3580d19cff44f1014a7c966a69059de5\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 143ae8ed6555aba96110ab58893a8ae1\nPlaintext: 00000000000000000000000000000000\nCiphertext: 806da864dd29d48deafbe764f8202aef\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: b69418a85332240dc82492353956ae0c\nPlaintext: 00000000000000000000000000000000\nCiphertext: a303d940ded8f0baff6f75414cac5243\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 71b5c08a1993e1362e4d0ce9b22b78d5\nPlaintext: 00000000000000000000000000000000\nCiphertext: c2dabd117f8a3ecabfbb11d12194d9d0\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: e234cdca2606b81f29408d5f6da21206\nPlaintext: 00000000000000000000000000000000\nCiphertext: fff60a4740086b3b9c56195b98d91a7b\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 13237c49074a3da078dc1d828bb78c6f\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8146a08e2357f0caa30ca8c94d1a0544\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 3071a2a48fe6cbd04f1a129098e308f8\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4b98e06d356deb07ebb824e5713f7be3\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 90f42ec0f68385f2ffc5dfc03a654dce\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7a20a53d460fc9ce0423a7a0764c6cf2\nIV: 00000000000000000000000000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: febd9a24d8b65c1c787d50a4ed3619a9\nPlaintext: 00000000000000000000000000000000\nCiphertext: f4a70d8af877f9b02b4c40df57d45b17\nIV: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey128.rsp\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: 80000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0edd33d3c621e546455bd8ba1418bec8\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: c0000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4bc3f883450c113c64ca42e1112a9e87\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: e0000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 72a1da770f5d7ac4c9ef94d822affd97\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: f0000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 970014d634e2b7650777e8e84d03ccd8\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: f8000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f17e79aed0db7e279e955b5f493875a7\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fc000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9ed5a75136a940d0963da379db4af26a\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fe000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c4295f83465c7755e8fa364bac6a7ea5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ff000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b1d758256b28fd850ad4944208cf1155\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ff800000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 42ffb34c743de4d88ca38011c990890b\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffc00000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9958f0ecea8b2172c0c1995f9182c0f3\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffe00000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 956d7798fac20f82a8823f984d06f7f5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fff00000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a01bf44f2d16be928ca44aaf7b9b106b\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fff80000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b5f1a33e50d40d103764c76bd4c6b6f8\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffc0000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2637050c9fc0d4817e2d69de878aee8d\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffe0000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 113ecbe4a453269a0dd26069467fb5b5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffff0000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 97d0754fe68f11b9e375d070a608c884\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffff8000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c6a0b3e998d05068a5399778405200b4\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffc000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: df556a33438db87bc41b1752c55e5e49\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffe000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 90fb128d3a1af6e548521bb962bf1f05\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffff000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 26298e9c1db517c215fadfb7d2a8d691\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffff800000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a6cb761d61f8292d0df393a279ad0380\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffc00000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 12acd89b13cd5f8726e34d44fd486108\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffe00000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ", "95b1703fc57ba09fe0c3580febdd7ed4\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffff00000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: de11722d893e9f9121c381becc1da59a\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffff80000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6d114ccb27bf391012e8974c546d9bf2\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffc0000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5ce37e17eb4646ecfac29b9cc38d9340\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffe0000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 18c1b6e2157122056d0243d8a165cddb\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffff0000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 99693e6a59d1366c74d823562d7e1431\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffff8000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6c7c64dc84a8bba758ed17eb025a57e3\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffc000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e17bc79f30eaab2fac2cbbe3458d687a\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffe000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1114bc2028009b923f0b01915ce5e7c4\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffff000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9c28524a16a1e1c1452971caa8d13476\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffff800000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ed62e16363638360fdd6ad62112794f0\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffc00000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5a8688f0b2a2c16224c161658ffd4044\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffe00000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 23f710842b9bb9c32f26648c786807ca\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffff00000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 44a98bf11e163f632c47ec6a49683a89\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffff80000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0f18aff94274696d9b61848bd50ac5e5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffc0000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 82408571c3e2424540207f833b6dda69\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffe0000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 303ff996947f0c7d1f43c8f3027b9b75\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffff0000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7df4daf4ad29a3615a9b6ece5c99518a\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffff8000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c72954a48d0774db0b4971c526260415\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffc000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1df9b76112dc6531e07d2cfda04411f0\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffe000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8e4d8e699119e1fc87545a647fb1d34f\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffff000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e6c4807ae11f36f091c57d9fb68548d1\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffff800000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8ebf73aad49c82007f77a5c1ccec6ab4\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffc00000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4fb288cc2040049001d2c7585ad123fc\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffe00000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 04497110efb9dceb13e2b13fb4465564\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffff00000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 75550e6cb5a88e49634c9ab69eda0430\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffff80000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b6768473ce9843ea66a81405dd50b345\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffc0000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cb2f430383f9084e03a653571e065de6\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffe0000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ff4e66c07bae3e79fb7d210847a3b0ba\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffff0000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7b90785125505fad59b13c186dd66ce3\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffff8000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8b527a6aebdaec9eaef8eda2cb7783e5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffc000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 43fdaf53ebbc9880c228617d6a9b548b\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffe000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 53786104b9744b98f052c46f1c850d0b\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffff000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b5ab3013dd1e61df06cbaf34ca2aee78\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffff800000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7470469be9723030fdcc73a8cd4fbb10\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffffc00000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a35a63f5343ebe9ef8167bcb48ad122e\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: ffffffffffffffe00000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fd8687f0757a210e9fdf181204c30863\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffff00000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7a181e84bd5457d26a88fbae96018fb0\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffff80000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 653317b9362b6f9b9e1a580e68d494b5\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffffc0000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 995c9dc0b689f03c45867b5faa5c18d1\n\nCipher: AES-128-CTR\nOperation: ENCRYPT\nKey: fffffffffffffffe0000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 77a4d96d56dda398b9aabecfc75729fd", @@ -772,9 +833,9 @@ static const char *kData22[] = { "laintext: 00000000000000000000000000000000\nCiphertext: b87c921b91829ef3b13ca541ee1130a6\nIV: ffffffffffffffffffff800000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2e65eb6b6ea383e109accce8326b0393\nIV: ffffffffffffffffffffc00000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9ca547f7439edc3e255c0f4d49aa8990\nIV: ffffffffffffffffffffe00000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a5e652614c9300f37816b1f9fd0c87f9\nIV: fffffffffffffffffffff00000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 14954f0b4697776f44494fe458d814ed\nIV: fffffffffffffffffffff80000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7c8d9ab6c2761723fe42f8bb506cbcf7\nIV: fffffffffffffffffffffc0000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: db7e1932679fdd99742aab04aa0d5a80\nIV: fffffffffffffffffffffe0000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4c6a1c83e568cd10f27c2d73ded19c28\nIV: ffffffffffffffffffffff0000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 90ecbe6177e674c98de412413f7ac915\nIV: ffffffffffffffffffffff8000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 90684a2ac55fe1ec2b8ebd5622520b73\nIV: ffffffffffffffffffffffc000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7472f9a7988607ca79707795991035e6\nIV: ffffffffffffffffffffffe000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 56aff089878bf3352f8df172a3ae47d8\nIV: fffffffffffffffffffffff000000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 65c0526cbe40161b8019a2a3171abd23\nIV: fffffffffffffffffffffff800000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 377be0be33b4e3e310b4aabda173f84f\nIV: fffffffffffffffffffffffc00000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9402e9aa6f69de6504da8d20c4fcaa2f\nIV: fffffffffffffffffffffffe00000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 123c1f4af313ad8c2ce648b2e71fb6e1\nIV: ffffffffffffffffffffffff00000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1ffc626d30203dcdb0019fb80f726cf4\nIV: ffffffffffffffffffffffff80000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 76da1fbe3a50728c50fd2e621b5ad885\nIV: ffffffffffffffffffffffffc0000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 082eb8be35f442fb52668e16a591d1d6\nIV: ffffffffffffffffffffffffe0000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e656f9ecf5fe27ec3e4a73d00c282fb3\nIV: fffffffffffffffffffffffff0000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2ca8209d63274cd9a29bb74bcd77683a\nIV: fffffffffffffffffffffffff8000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 79bf5dce14bb7dd73a8e3611de7ce026\nIV: fffffffffffffffffffffffffc000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3c849939a5d29399f344c4a0eca8a576\nIV: fffffffffffffffffffffffffe000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ed3c0a94d59bece98835da7aa4f07ca2\nIV: ffffffffffffffffffffffffff000000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 63919ed4ce10196438b6ad09d99cd795\nIV: ffffffffffffffffffffffffff800000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7678f3a833f19fea95f3c6029e2bc610\nIV: ffffffffffffffffffffffffffc00000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3aa426831067d36b92be7c5f81c13c56\nIV: ffffffffffffffffffffffffffe00000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9272e2d2cdd11050998c845077a30ea0\nIV: fffffffffffffffffffffffffff00000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 088c4b53f5ec0ff814c19adae7f6246c\nIV: fffffffffffffffffffffffffff80000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4010a5e401fdf0a0354ddbcc0d012b17\nIV: fffffffffffffffffffffffffffc0000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a87a385736c0a6189bd6589bd8445a93\nIV: fffffffffffffffffffffffffffe0000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 545f2b83d9616dccf60fa9830e9cd287\nIV: ffffffffffffffffffffffffffff0000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4b706f7f92406352394037a6d4f4688d\nIV: ffffffffffffffffffffffffffff8000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b7972b3941c44b90afa7b264bfba7387\nIV: ffffffffffffffffffffffffffffc000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6f45732cf10881546f0fd23896d2bb60\nIV: ffffffffffffffffffffffffffffe000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2e3579ca15af27f64b3c955a5bfc30ba\nIV: fffffffffffffffffffffffffffff000\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 34a2c5a91ae2aec99b7d1b5fa6780447\nIV: fffffffffffffffffffffffffffff800\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a4d6616bd04f87335b0e53351227a9ee\nIV: fffffffffffffffffffffffffffffc00\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7f692b03945867d16179a8cefc83ea3f\nIV: fffffffffffffffffffffffffffffe00\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3bd141ee84a0e6414a26e7a4f281f8a2\nIV: ffffffffffffffffffffffffffffff00\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 0000000000000000000000", "0000000000\nCiphertext: d1788f572d98b2b16ec5d5f3922b99bc\nIV: ffffffffffffffffffffffffffffff80\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0833ff6f61d98a57b288e8c3586b85a6\nIV: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8568261797de176bf0b43becc6285afb\nIV: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f9b0fda0c4a898f5b9e6f661c4ce4d07\nIV: fffffffffffffffffffffffffffffff0\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8ade895913685c67c5269f8aae42983e\nIV: fffffffffffffffffffffffffffffff8\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 39bde67d5c8ed8a8b1c37eb8fa9f5ac0\nIV: fffffffffffffffffffffffffffffffc\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5c005e72c1418c44f569f2ea33ba54f3\nIV: fffffffffffffffffffffffffffffffe\n\nCipher: AES-128-CTR\nOperation: DECRYPT\nKey: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3f5b8cc9ea855a0afa7347d23e8d664e\nIV: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen23 = 5321952; +static const size_t kLen24 = 5321952; -static const char *kData23[] = { +static const char *kData24[] = { "# Generated by \"make_cavp -cipher gcm kat_gcm/gcmDecrypt128.rsp kat_gcm/gcmEncryptExtIV128.rsp\"\n\n# File 1: kat_gcm/gcmDecrypt128.rsp\n\nKEY: cf063a34d4a9a76c2c86787d3f96db71\nNONCE: 113b9785971864c83b01c787\nCT: \nAD: \nTAG: 72ac8493e3a5228b5d130a69d2510e42\nIN: \n\nKEY: a49a5e26a2f8cb63d05546c2a62f5343\nNONCE: 907763b19b9b4ab6bd4f0281\nCT: \nAD: \nTAG: a2be08210d8c470a8df6e8fbd79ec5cf\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2ad0bf5aeb47a0c1a98da3dfdab4fded\nNONCE: 25f1b6091ee7040fea4ba854\nCT: \nAD: \nTAG: d7963d240317653e01cf5abe5d0966ae\nIN: \n\nKEY: d8cd400a0a73d114cd3ecf36537cab3d\nNONCE: 3c162c9f16a49b8fe6c92a81\nCT: \nAD: \nTAG: 4203aec165f9d397cf9009770a088c16\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a982a7bae2b3eae1b7832f16faf693b4\nNONCE: 78d2d2fa43850483ce933576\nCT: \nAD: \nTAG: ceabb89ee3179e25ed32d5a225006361\nIN: \n\nKEY: f9e3992196f7d7a21bd956f4b5a5ffce\nNONCE: 0794a6bdf5f198c9f193b9ba\nCT: \nAD: \nTAG: f8247fd5dc7bd6d40e96af32aa9c1889\nIN: \n\nKEY: c91aab7ebe13653a71a4232fd1beb793\nNONCE: 7799464b6de6383da0daec52\nCT: \nAD: \nTAG: 00c4f7033f3c05e9d531f3ca573dc98d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e7e4eefd0a3abd4ee1bef270d257eab7\nNONCE: f548f2a04a50a2f0342b2250\nCT: \nAD: \nTAG: 044159b8a18668167fbd28ac500c20fe\nIN: \n\nKEY: 1bd49e553457459aee1b5d83e7c216a2\nNONCE: 2b37cf40ed2685eb2a907cd0\nCT: \nAD: \nTAG: fcb41d17fdb023d4d14f84a387d3ad77\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 4d6486fa68ce5a14b9db7334ab4838cb\nNONCE: afad3f4190d56a1b8eb08e58\nCT: \nAD: \nTAG: 4bda04755b7ce9da020ce7467a5ced8f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: da5b59d5eb448fd6c08c350df9a82114\nNONCE: 15fb65d9fe2fa27f226312c0\nCT: \nAD: \nTAG: e407fccbb9f00eeb9cef4a520cff957c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 07d5a7d405b21c64d74cc0988693b784\nNONCE: 2eefd7990ea025925e9ca6f9\nCT: \nAD: \nTAG: 1439522d18c9eb129f1f776590027761\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 48760dec952010140ffc4b4078438b56\nNONCE: 930cc3ff276d7bbb74d187ef\nCT: \nAD: \nTAG: 8673dcb97934d54dc17de0037344737f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: ed7c50762dc0dc4aa5c8be4cf0a56b88\nNONCE: 50dfb73b5034cffb6709af8f\nCT: \nAD: \nTAG: cb02203ee8eccec446ed1c2cf68fd1c0\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: b5d4b3e80a56adbc780ff02c5da6a7ab\nNONCE: abc5b96c5e872502971dcc55\nCT: \nAD: \nTAG: 4e85677cc16e2b2fb50a2ca9c0ac1b9c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: eac258e99c55e6ae8ef1da26640613d7\nNONCE: 4e8df20faaf2c8eebe922902\nCT: \nAD: \nTAG: e39aeaebe86aa309a4d062d6274339\nIN: \n\nKEY: 3726cf02fcc6b8639a5497652c94350d\nNONCE: 55fef82cde693ce76efcc193\nCT: \nAD: \nTAG: 3d68111a81ed22d2ef5bccac4fc27f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f202299d5fd74f03b12d2119a6c4c038\nNONCE: eec51e7958c3f20a1bb71815\nCT: \nAD: \nTAG: a81886b3fb26e51fca87b267e1e157\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fd52925f39546b4c55ffb6b20c59898c\nNONCE: f5cf3227444afd905a5f6dba\nCT: \nAD: \nTAG: 1665b0f1a0b456e1664cfd3de08ccd\nIN: \n\nKEY: 39c070eaace1c6e30ab004bfbfa830fd\nNONCE: 6e55ff3bba561f17f338313c\nCT: \nAD: \nTAG: 4e3c2db540790f26a4704e72ef9b4f\nIN: \n\nKEY: 96b12ebb99edca96838f88caaa74abbc\nNONCE: 679feb33d6e35962518a63c1\nCT: \nAD: \nTAG: cbe9d90bb8600bb14e8ca81cde5b2e\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5b1a1ad45349cb7ec3afb613674c9381\nNONCE: 7ef3542c0ca2415f767eec7c\nCT: \nAD: \nTAG: fbc65cc7f1f4edbb746b47f950e472\nIN: \n\nKEY: b349f8d86e91144c86ed49a100358239\nNONCE: 3e3879e1a4ccf74cc442b9c5\nCT: \nAD: \nTAG: 0d935691c84813b8c1e5ba23ee621f\nIN: \n\nKEY: df4074001cf89ad0b046fceeea5a1ef2\nNONCE: 080fb68a083a219354a7cdcd\nCT: \nAD: \nTAG: eaa44ef28c446610b33dd2fdbdb8a0\nIN: \n\nKEY: 84816510accb68149ee65be220df3d9e\nNONCE: 99c41452f73f3a2dd48f2eaf\nCT: \nAD: \nTAG: 5d5f3c09d2498587c7230dbe5fd497\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 98740d9ac6cee9379253d4e6718a1de5\nNONCE: b723dd15270c767a31636117\nCT: \nAD: \nTAG: 199630b915021b98055f295d08befc\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 79b8cb97ec3e3f7536eeaffc64bdb372\nNONCE: e945122f1e4d960a2e9f9a41\nCT: \nAD: \nTAG: cb9c041f18070030399006d77954cb\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 26e7fb1c3b5448d7ad7b67aadaf360bb\nNONCE: 34bf017f9283236dee171e10\nCT: \nAD: \nTAG: 8756ca5c8aa644a852e5eb2c49bf39\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d6a515d24ef9099695b179c01bc1f4b1\nNONCE: b54a5bbbf6faae5f33b8c133\nCT: \nAD: \nTAG: 02b1243c92f6b059d00bd672dfb8e5\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9e9ec40db0a07f24c417d3c63d1b946b\nNONCE: 8605c97fa5d8f94798b845f9\nCT: \nAD: \nTAG: 10ce3c41553e7f5b413d1470ced09b\nIN: \n\nKEY: dc1b3fdce56baf77ddb22246ebb224db\nNONCE: 1394643db950ac42366cda3c\nCT: \nAD: \nTAG: 25bfdb151d21994e90b095230247\nIN: \n\nKEY: c1b668ee720eb90730d7c30e663e941b\nNONCE: b8f27f51092d65697a9740de\nCT: \nAD: \nTAG: d6acce523efdb3e7b28220896827\nIN: \n\nKEY: 7a25451203338a3a046902fc5169a9ac\nNONCE: 070a0b0fb560999c6b778aa5\nCT: \nAD: \nTAG: 51d73876b57dea6ef24e2740fc69\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8747e8b9058632721cab00c217e24fca\nNONCE: c44c7bbf8b4a48e2b64c4e41\nCT: \nAD: \nTAG: 2f7fccde59ec9e6ad2cbd6ced7c1\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 79d9e7d647dbe9926ba08f078b2c4768\nNONCE: b7fef625e03c6e97bb7988eb\nCT: \nAD: \nTAG: 8508fe578eacef69d8e1468cc905\nIN: \n\nKEY: 84ade1f350d68ceff9fe8a7ef120e7b6\nNONCE: 7617886bff63257768f54173\nCT: \nAD: \nTAG: 461ecfef2f3b746cc3a47c28a43a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f7a85574fb8be04e92d219cf3524877b\nNONCE: 9a3febc5d2bd389e0db3863c\nCT: \nAD: \nTAG: 69a1d7bbf81f830534312c641068\nIN: \n\nKEY: 18f42b8a3dca6e80777d5c681d8c4a32\nNONCE: ed425811547c5989ea6d4cb2\nCT: \nAD: \nTAG: 60b5712b52b56facc8758aec40c9\nIN: \n\nKEY: adeb972fe5160e14137c286b6e281163\nNONCE: 38e536e647b83fc429bbcabd\nCT: \nAD: \nTAG: 22e32a3c2637ac48c0deaf06435c\nIN: \n\nKEY: 0686f241ca82a590980929858c789d7a\nNONCE: c5d0737448692684c5ac1c8c\nCT: \nAD: \nTAG: 65eecbd0fe423c6e1608745ab677\nIN: \n\nKEY: f7d57c6e4699d4f242270f41781d39dc\nNONCE: a2842a9dd1b5874cb50e8707\nCT: \nAD: \nTAG: 09999cdc3dd28e818b88a6485c8d\nIN: \n\nKEY: 4df05ee5ee95c69938b4049a2be92504\nNONCE: afdefd136622128fd6c2c534\nCT: \nAD: \nTAG: 3a24e5f166d70627954b55029fc3\nIN: \n\nKEY: 0f4469766ea265d22cba4c7105bc49b0\nNONCE: 25ede41ed4c638195354713a\nCT: \nAD: \nTAG: 6dd4e9cc6ed04976f2cced5804b4\nIN: \n\nKEY: 24c7de158fcb0808b3cfda0e95706e6f\nNONCE: 88eb7f00a129040d05952d17\nCT: \nAD: \nTAG: 2d587fd20457566fed19cca36d2b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2610de38144b05876b0d0b34a1c7812e\nNONCE: 6673bf587f9f90df3a1715fd\nCT: \nAD: \nTAG: 7b13fff5e79951ebee51d12f8422\nIN: \n\nKEY: a830c905dad3a8e5aae739d7ab60a5dc\nNONCE: 54633aa565952e80fb0b9869\nCT: \nAD: \nTAG: 482d9381230cd015b2a16976b6\nIN: \n\nKEY: eb7ae9788a5dc09a7812e389c67138ea\nNONCE: 2ecd19b70ffe87cad58a0029\nCT: \nAD: \nTAG: c1ebf4e3594a722bab9f61e084\nIN: \n\nKEY: 9c247b33ffb3fe486f8f1c06b3db6563\nNONCE: 978769bc16a7dd3d90ab9d76\nCT: \nAD: \nTAG: 09acccba7e7be6b5687b478327\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 23281eec6b12fe1184e6c113788915b8\nNONCE: 78538fb690491381daa41ef5\nCT: \nAD: \nTAG: 80d9c8d781035be9f68de209ad\nIN: \n\nKEY: 443657744df4b5d5de80f27efe244b27\nNONCE: a637b48e67d1cf8f3ddf6d7c\nCT: \nAD: \nTAG: bf84664af0260e0b5b352e5cd9\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: b93ae43e8eb3e94b67b09b833e376327\nNONCE: 14ef4f357845d34ce06b170a\nCT: \nAD: \nTAG: 22c987ec9c91ce7714fbb794d8\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 6eff3644c83c75c0678cf4f6713561f7\nNONCE: e7bf04fab5909668065d2b43\nCT: \nAD: \nTAG: 2fab50a07c1a50ba8e4381dad9\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9613b9b4c70e5ab130534309059e99b7\nNONCE: 40414f80b586ecfb22860442\nCT: \nAD: \nTAG: 9cc1a298d9d57b6d4bcdf3e5b5\nIN: \n\nKEY: 400fcee6ea1b8b1fccffdbccef08a5e2\nNONCE: dc16236581a6da126550b08a\nCT: \nAD: \nTAG: 6ceeca2188cf4da42ed3f248df\nIN: \n\nKEY: d27c84466faf1a45a2435eb9293478e2\nNONCE: cdd7e1bdf60bd12885dc8fdc\nCT: \nAD: \nTAG: 5397381a8817ef557ac6c57a22\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8ed40d2b24f52dbf2fa8486c8fde62e9\nNONCE: 837f36e0f6fb34d08e8df9f9\nCT: \nAD: \nTAG: e6c787dfeae37a34dc49d52caa\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 34395d007dac4a4b83c943de4406d821\nNONCE: 4bbfe5f3276461e594b1fd2e\nCT: \nAD: \nTAG: 30daec9c07fa2e11a1acc28baa\nIN: \n\nKEY: 5a8321edf8d532d51299ecbaffc56cbc\nNONCE: c512db4e75e52950f89f458e\nCT: \nAD: \nTAG: 88fddfe667c3519963ebb6d0b7\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d9ed395776deb772a218db03abbd8606\nNONCE: 600075a6d85d86d6a3f6624a\nCT: \nAD: \nTAG: 7f486053d65559dca0a3761e00\nIN: \n\nKEY: 16b5d6282fa184deeb837c706f191079\nNONCE: ea09b0a8f65f3ac16d954c9a\nCT: \nAD: \nTAG: 6defe4a6354e1383111d96fcb3\nIN: \n\nKEY: 4c5a02440befba5820539ccf74b40355\nNONCE: 3852fd7da7a375a2a2227e9c\nCT: \nAD: \nTAG: 9f45b723d14708dad1edd831\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d4e885208426247f27428ede3b318e68\nNONCE: 5513f9ec35e2e72be3470f57\nCT: \nAD: \nTAG: 48d716f0f94ac7fbc291932e\nIN: \n\nKEY: 25954f34970b4fc834fff", "1552bea4896\nNONCE: b66b254e66240f0e8e262f01\nCT: \nAD: \nTAG: 5b5569b200c06bd24382ec73\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 303b5662bcf71ca82e07e10248c17629\nNONCE: 45f9c33e03f84fa88209858d\nCT: \nAD: \nTAG: e8b99255a0e953d57361db29\nIN: \n\nKEY: 8394912058620e935335f7627b18b1b3\nNONCE: 772149bd434c0b27ac45e672\nCT: \nAD: \nTAG: c7a43e2ee7e161a52583ad83\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2ca00481ac56aac664b28f29781a7e82\nNONCE: 14574966f3b12bc0502a3a55\nCT: \nAD: \nTAG: 938628eba4b72f79fd7b7396\nIN: \n\nKEY: 8ed5a13a5046d10379c75eaa3fd17bb2\nNONCE: 2b111cc8c84ff7f1c262ec1c\nCT: \nAD: \nTAG: 82e8bed016ae384ae75ac16c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 7041298fe906405905e8b4de1de3c0f0\nNONCE: e4fbdc72d00a331bfa326d59\nCT: \nAD: \nTAG: 17292560680114395372691a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: faeeee9bbaff25e221121d1122807009\nNONCE: e9e872d525c2315f49e2d94f\nCT: \nAD: \nTAG: 98146c72b9365016ff33b7e2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: df0a1dd37c0144e0bcff6e7deed857f0\nNONCE: eba039eaf7f2f48f761abc9c\nCT: \nAD: \nTAG: 973e0ff877b085ad8083d6c9\nIN: \n\nKEY: 27f19b4b2d23285d92480ca2dc3799dc\nNONCE: 335b2f88f2fc4b6188867558\nCT: \nAD: \nTAG: 8b1c43ade7a3c5af9a639e02\nIN: \n\nKEY: 6edf19775190943d196148165087ebe1\nNONCE: c2fcf9919d85407086c2be20\nCT: \nAD: \nTAG: dda2c0cfe5d922a3cfb15ab8\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9acca9099afc2ec75441587bdd96a469\nNONCE: ca178e969478e36621db60df\nCT: \nAD: \nTAG: 86a70322e57fd6cca64a6aa6\nIN: \n\nKEY: d0718716395e03f7fde7fb40f497f9cf\nNONCE: dd20e6b684a0f53d3785df71\nCT: \nAD: \nTAG: 70cfeb7a503a1869fa0dc0ee\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5fcbf7953da6781ae96852885ae01488\nNONCE: 34ca7d2a0aaf09fcb8a5b39a\nCT: \nAD: \nTAG: 142828e093e80e346008c2b6\nIN: \n\nKEY: a958dea10183955fb62b5cf0d6560efd\nNONCE: 9c6fd7fcb79ab149a2ef8416\nCT: \nAD: \nTAG: 0fa19df0ef498402\nIN: \n\nKEY: 2bd8c68da36fc74a66e8bc9c58c7b3d9\nNONCE: 0a0c9cee4e712ce526271644\nCT: \nAD: \nTAG: f94a128bb6c31902\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5f8441de9b68a525bd77a9f8db9ac1ec\nNONCE: 7b704888d905e11b3e8f6751\nCT: \nAD: \nTAG: 1920f39509e495ec\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 47a49ee87638b74b48dfc42b9892ff93\nNONCE: 927f32a1fdeed0da6c80c4c1\nCT: \nAD: \nTAG: 568ca20233ab20e1\nIN: \n\nKEY: 871616dda80c31ef677f770774f41d27\nNONCE: 94f9c4a7f7d69cfef745c085\nCT: \nAD: \nTAG: f779d3356f60d96c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e6a7ce1c109162cc24552b2de8355bd8\nNONCE: b140aa5f0f2312cf7b8696c1\nCT: \nAD: \nTAG: ea5f6c5b9224afcc\nIN: \n\nKEY: a90b62bfba34ca0cfb4d5ccd52ff7369\nNONCE: 5fd3cf7a9a1e2a15ad6a58e2\nCT: \nAD: \nTAG: 6f3dd881088a0b29\nIN: \n\nKEY: 6280067b5626d5d6bf35ab1c903c1d75\nNONCE: 99523c6f792e03276c44ba7a\nCT: \nAD: \nTAG: 3a68ccdb69008d9d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f40b500c70209092efa29a2a7e96ca64\nNONCE: 86d1047059ee2986bd96daf7\nCT: \nAD: \nTAG: c594ea04f674de69\nIN: \n\nKEY: 6cb7829e2295e60036bb967d06116601\nNONCE: 4dfb5fb2ea41fae7653e1438\nCT: \nAD: \nTAG: bb9b39fe673ffd18\nIN: \n\nKEY: 05cd9b0de53c072321ae4a1cdc2cafc3\nNONCE: c869859421df985bbc8c9c62\nCT: \nAD: \nTAG: 0f8ad033a0ae3cb2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fd025400ab17f5e35c3cae3aeed4ebc7\nNONCE: 6c3b7e178df39504d3ca2e31\nCT: \nAD: \nTAG: 5fd986d21ac0bb49\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: c7678eeb06cd24484b81a469c024c3d6\nNONCE: a1fea7d9afd9493a83b5d531\nCT: \nAD: \nTAG: 8c5828f475c4f902\nIN: \n\nKEY: 056c731555048f5831a4c7ba57f9022b\nNONCE: a8a13e93a33807811ed327f6\nCT: \nAD: \nTAG: c2d9d4fb79d675f3\nIN: \n\nKEY: c0395a8391049d30f7e0fa7afd1b0ec4\nNONCE: 381894100b3d786bfca314b7\nCT: \nAD: \nTAG: 2fef77ef639adc00\nIN: \n\nKEY: d1cb603b886e9deb62cbf5182caaeb35\nNONCE: cd23f90cfd17727ea0975ff2\nCT: \nAD: \nTAG: e319af65\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e626638a113c617077f5c4b2284921c5\nNONCE: c4a8864b4c3385a78cb8759f\nCT: \nAD: \nTAG: 039d51f8\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8f74a8b922fcf1a8eed7320df9f03fd6\nNONCE: 925ec6414e777062ac839f06\nCT: \nAD: \nTAG: bb0dc912\nIN: \n\nKEY: f59152b1d2991e7dfbd6b9cf91d2a9f1\nNONCE: 776f95b088803b537dfbe941\nCT: \nAD: \nTAG: 9163e80b\nIN: \n\nKEY: 72a9159c9f8f4953b6ab4fbad02c019a\nNONCE: 7ca4d31dba07c89b3d5cf059\nCT: \nAD: \nTAG: ee28643d\nIN: \n\nKEY: 6ca652634faee86176a8bbff37f5234c\nNONCE: 77bbe192e81594223b8869cb\nCT: \nAD: \nTAG: d054e86e\nIN: \n\nKEY: d06a1cebb4b1cf8b2f48126bffd4530b\nNONCE: ac7c4c669d5d7749d114448a\nCT: \nAD: \nTAG: c606dbcb\nIN: \n\nKEY: 42797f87d381cbbec3dddb8e7ee1b30e\nNONCE: c4be94c9b2f76132875374d0\nCT: \nAD: \nTAG: 40156799\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: accec0302ba0f854c2c5a6faf08f4972\nNONCE: 2722ce4848acc2b4cc9aafa2\nCT: \nAD: \nTAG: d90c055f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 117ecaafb5c844ceb9e505f8a33bfa79\nNONCE: cb95b76c9dbf4b6ee4fe6a46\nCT: \nAD: \nTAG: 641e2aa6\nIN: \n\nKEY: 453e89f0646d2532e3d0d019a7d7e302\nNONCE: 14732cb98fb4ad26c0ee9e1b\nCT: \nAD: \nTAG: 232f4035\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 121143f3835cb0d1f88f8f53a7abdb11\nNONCE: 601c15958cf77c0ea1c3862e\nCT: \nAD: \nTAG: 43c61d3d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: c5d7666d37ced3e4c2b9b738d4b38557\nNONCE: 012fa72716b777e0bc248f2d\nCT: \nAD: \nTAG: f4208947\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5d06c11668c4aa9899496b5d7f229b83\nNONCE: 0ca7102fff9fe056a5afa9f8\nCT: \nAD: \nTAG: d7a7af6d\nIN: \n\nKEY: b63a6afbc9906d23f1e9c0f487b6d919\nNONCE: 2b091d6b35e4f9ba5f9cfdb8\nCT: \nAD: \nTAG: d1eafd50\nIN: \n\nKEY: d1f6af919cde85661208bdce0c27cb22\nNONCE: 898c6929b435017bf031c3c5\nCT: \nAD: 7c5faa40e636bbc91107e68010c92b9f\nTAG: ae45f11777540a2caeb128be8092468a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2370e320d4344208e0ff5683f243b213\nNONCE: 04dbb82f044d30831c441228\nCT: \nAD: d43a8e5089eea0d026c03a85178b27da\nTAG: 2a049c049d25aa95969b451d93c31c6e\nIN: \n\nKEY: bc3ab28150fd4cb731d5f48ed2784173\nNONCE: 40408445c203c647312b8f01\nCT: \nAD: 53d2fc19963fc99a36a524e39cb68aa8\nTAG: 3f04dbd2f49909f73044175041fd9eff\nIN: \n\nKEY: 34537f1a0ba093aefedefe8b4b6b34e7\nNONCE: 9c5fc88eb388ef6776aa2182\nCT: \nAD: 4dd377d089c617dda1ecd42341d1878b\nTAG: c0fccde30ba354e23c05b5371c40d088\nIN: \n\nKEY: 54c3f935982de19de88d6384f9493389\nNONCE: 3d7eec1cdf3cd419511793ab\nCT: \nAD: 2ded8cbc69fa57678aadc7477f2a2173\nTAG: 74107fc192c94a7d85d0f9205f8b02c9\nIN: \n\nKEY: 790f8945b127a1a418d6d58b4378e0dc\nNONCE: f5694d77b816f2cef0ac80fc\nCT: \nAD: e5c71b82a60c97f050511a3b9a09e450\nTAG: 4c75effb688dccd0affe92c0e0391d64\nIN: \n\nKEY: f6ed6f0afea7e99ab320b525107715c9\nNONCE: 351e7dc999b9de77ce61b2f7\nCT: \nAD: c9101b64e0b6abc0e46828aec14d29cc\nTAG: 4f2ec2e1ab001443a60722671a9c9656\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2eccf9cda0e4e70f273ee8251120c768\nNONCE: 1d869f4b8497bc19d948cea6\nCT: \nAD: 1d86a6a21f23ee56ad0fa6c1de525906\nTAG: 37ffc390298c3ea8cceb382f394c2fc2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d61767f07b959e94f73c64cb5a5520b3\nNONCE: ecfa850395f8cf9348f1324f\nCT: \nAD: c3571bf1700b114bbf0c6bb2278d4d88\nTAG: 1065f86bc9e22197880ea87ac326a17f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9421cac15ce7d49ec7c088f7524a1ff5\nNONCE: b3d395bca123b265c05577cc\nCT: \nAD: eb6e06071dae4360e8347bfb72d9c188\nTAG: 1f04c228c7efc71f1706d10fd819f35e\nIN: \n\nKEY: 8580395a5d777c1690af79f6068e291b\nNONCE: cad1a0f2b76f064ca56be3cf\nCT: \nAD: 174388edf0b7f86fe634cb942c13754b\nTAG: 0067b03f2e0efc72cb08792fbe3b0267\nIN: \n\nKEY: 0c21da9c8b84d371fde59e6d1752113e\nNONCE: f8c13e58aaa329427438db8b\nCT: \nAD: b8b197789cfd085b09a47760c28c7e8a\nTAG: f8613cc5dcb4cc5c78f1f7c2d8084ec6\nIN: \n\nKEY: 162fc51e46e771222a04842f5546db8c\nNONCE: 13557e09e738eb895eca2d8d\nCT: \nAD: 691e71952c31a6b49b785f627c03e948\nTAG: 4f7ea723b1abd74e53fa356809275ca4\nIN: \n\nKEY: c46d9562d954801b8e99e4e57cbcc0ec\nNONCE: 30414c934b14e0bb0110ae44\nCT: \nAD: 41ae6a63855c1944446491e80670bf68\nTAG: 3e2366a2cf5632c1ecfde33f1f5f6d18\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2904df4dafcc6bbb8375baf6a7eede80\nNONCE: 6aae8ff4b1609f4026b47259\nCT: \nAD: c4afa7b21e5f41b892be52365a18584e\nTAG: e1810fe340207fa83815182bbad62bde\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a663a6aeac790c61e07e5f8ab843439d\nNONCE: e287d287051c82e2253e33f7\nCT: \nAD: d211a58e7d4884a26669b335c0af8d5c\nTAG: cdf52e39cced5c04ddaec8227826da\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 6dfa1a07c14f978020ace450ad663d18\nNONCE: 34edfa462a14c6969a680ec1\nCT: \nAD: 2a35c7f5f8578e919a581c60500c04f6\nTAG: 751f3098d59cf4ea1d2fb0853bde1c\nIN: \n\nKEY: 5f20eb8f6f579ec235b3403831fd58b1\nNONCE: b989444625a730876cc1a439\nCT: \nAD: 5881865ceb44bf171a7ba87d63f1fdcb\nTAG: 2d9c926c872c04bd0915f3e4ffccc5\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d1e376ecfa46321a3a4a187fc1524789\nNONCE: 7387c1af03adfffc53248ac8\nCT: \nAD: e9d8269ecf857dd6afd85fa90260a565\nTAG: 6a1da57b70e9c4fd006e4a669008d5\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f20681f4b61e72f8a6517e40b5860e0a\nNONCE: df80104736d5acba2348e5be\nCT: \nAD: e4247e85dafdabff95b6d8c27e8979a2\n", "TAG: 746ee686eddfac0785341bb616f90e\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 0f6ee618d0b66fa269398d5d3279931b\nNONCE: 7ac7c776a9a77aa8f7fc653b\nCT: \nAD: 2774b19121188965922c4a702c45fcfb\nTAG: 58d810fd408978d0f5eb33f06aa861\nIN: \n\nKEY: 9405240a2e0fbef7ac89f66f9188472f\nNONCE: 60718e8fb2866d27ddff8a78\nCT: \nAD: e86f19201889740743a9b95091283ab5\nTAG: 2984f343aff7e0ad84aa7134f77699\nIN: \n\nKEY: 9a5f24a325ac049169f7073b9583fa79\nNONCE: bf364dee6ac48e711aa2af2e\nCT: \nAD: 131339c8b9c785350efee37c0c37b6e5\nTAG: 69b1815c978cccdd146c51ad164429\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2b51c516898ded4dfedf1839eb09f059\nNONCE: 8080260add3b5d2182b3574a\nCT: \nAD: 303f4aa89c1ce37ff8b36940c65586e6\nTAG: 3750db28f9a09493ab60c9cb426e0b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 084877d61fd67442461c741afc4cf5f8\nNONCE: 798bce4a6b8663919dc922e0\nCT: \nAD: 056221633de809d2f48ff41c2d75d851\nTAG: a6c40f9765113e9dea6fd2f8bae96b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fe9cb0d7753d80686621fcf28705a39a\nNONCE: bd71586f2509814283ca1ec8\nCT: \nAD: 8676d9c9952340c31c9eb9e0d75c68d4\nTAG: d55ab183b959d697fb9145d37a7b27\nIN: \n\nKEY: 0ddee4104e896aae2849e8c4c5b97da4\nNONCE: 03d4bf8a036f974f92c77ed3\nCT: \nAD: 742838addd4a519d901736aa0a08d769\nTAG: cfb89c9ad51c348d65f7ce7cc4b72a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a22e58bd9a09eddaa630d499dd6d410c\nNONCE: ea9a7f75676dcc2f79b9147b\nCT: \nAD: 0a730acd7b5805ca0fbfdd5bef7690c5\nTAG: f3c63684015db6cc958bfb3ac84222\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8e5f16c84b0dd5357ad66f0540f1bf87\nNONCE: 6231ff08e050b7f7c5204842\nCT: \nAD: ab622472635a3ebae68aaaf8153df35a\nTAG: 1df90759291bfebd7cb239e75746ee\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 31c987a595a80a4c91de68805f66e5b9\nNONCE: 67edf7afbc125ecf99a804a2\nCT: \nAD: 8648a3452aaa3ff68d488de1abecef41\nTAG: 1c9199d9465ba5c9314911b4ad2057\nIN: \n\nKEY: 2d4fe4c17b1e86f0316846e642ff3a4d\nNONCE: a8b283438ad968e17fb5a755\nCT: \nAD: d0fdf6e1543d2b0f62c96c6e9c09c977\nTAG: 80149613bc962e4735acf317a3a4\nIN: \n\nKEY: aebb04a17265c4720d5a377c38efc460\nNONCE: b607be60340e557013e7adce\nCT: \nAD: 3cff96ceffa4c9a2193beeca9444e474\nTAG: a207fb626fb731c3234bad3573e8\nIN: \n\nKEY: 0807bf020df6ce3aba407e4d4f76ef6e\nNONCE: de63592624932a0805bce0a2\nCT: \nAD: 7c85c60c15301bfff6f2a4a3038b3c9f\nTAG: 5c83dce13c5bed35d8941f16627a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: efaa4666776ff4c6a87f563dd2e2794e\nNONCE: 9eb99f9741d9de6d3cbc9703\nCT: \nAD: 3addaaf513eb42606a24311ca7058846\nTAG: df02cfaace61423d45f64cec0e78\nIN: \n\nKEY: cf8d3e7cd62754bea5092409db3dc6c4\nNONCE: 5af3d5f1d144de8aca4bbda3\nCT: \nAD: 907083ee93cbf0b9b8421b8083bfcde8\nTAG: f19ebbc361dff17249251c9a7f5c\nIN: \n\nKEY: b894e7483c9f367b41af103f2860a6c8\nNONCE: 42d71d79e22740e1d1871ab5\nCT: \nAD: 8f78015bb82fbe032a6595e679198b47\nTAG: 96ce7b7f620b697f074f109c4488\nIN: \n\nKEY: 8299ee6ebdf1ea6e2561933b406de656\nNONCE: 98aade4ae4cda264b364987b\nCT: \nAD: 29a0fdb89ec5c5f969932e0aa0c170a8\nTAG: 60e0a7c2384f1d208abcfd4e4b3d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 29ac8dc4b69fb48289ceecd435ce3066\nNONCE: 2ecc8b95fae59fe59402bae5\nCT: \nAD: ec279eebc147897ea067a105c7e418c9\nTAG: d6f6127ec39852f18a7941948e41\nIN: \n\nKEY: 065bcae64ef1a982237e5977e73382ae\nNONCE: 164fed8cbe6d6cb0bbb6d608\nCT: \nAD: ed7da5abf307f9ceb18b630de9291b4a\nTAG: ac22e57ebf8ff258ffc77fa4bbb5\nIN: \n\nKEY: 1ad71eb24ea2a8055533fc1ec1b51b98\nNONCE: b27b640c3919a21da93e42c5\nCT: \nAD: 882acc108ee77afc6754089e864f0080\nTAG: dc36f18c131004e815c228a3fe9c\nIN: \n\nKEY: 54f06e8769711b40076d3cfc0239c324\nNONCE: d607633bd5336ce01c98f458\nCT: \nAD: e8f2f9edf850ade8e7cb55fba052e27a\nTAG: ff32f6d2418b2e646288bb105dcf\nIN: \n\nKEY: 8a473ce70b7694cb36efe5f5f268f1c4\nNONCE: 8236c764c7614dedabdd2dc0\nCT: \nAD: 4ea00a00b2bde6f183366b1ce8c33400\nTAG: 158bba897c1ab0cbce33355947fb\nIN: \n\nKEY: 4b42945e4361de3f6623b01872ff5f95\nNONCE: 5d7ec8f90b140049a8ef85f6\nCT: \nAD: 50feab5dce291d771df81b0124da29ed\nTAG: 90590e115ba688b50a66d59eb8b2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f2bad7d4f033b19c3b918da3021b3edb\nNONCE: 3825afbecc01cc66caddd402\nCT: \nAD: 49a6738279742410a0ce63276306c288\nTAG: 95a5980947205fe2225dbd39d098\nIN: \n\nKEY: 2c113bdd16d5f827bb84d9a9f1e2ced8\nNONCE: 97ce5737ca5305cebc3dbd0f\nCT: \nAD: 6833844c135173f2641190a5c81e2d38\nTAG: 9576596016c502bfb51adf861405\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 1dfee02fd2e411d8a95218059717e65e\nNONCE: 534f2db1833e2b95d17f4749\nCT: \nAD: 969f2d219986f9e3305b8be533ca164a\nTAG: 750e26041514a140374e857b19\nIN: \n\nKEY: 80a351296fdf716a59ce9cd3f3db1378\nNONCE: d57877a78eaea750131e1f62\nCT: \nAD: 89d5b612686f10f4523ad8721abb4a17\nTAG: 1445fe02c7eacc1968b5c2f436\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 44cdf8d44d4a85d4c718b6dfb3565f1f\nNONCE: 5fe0e438db113e46f73f0227\nCT: \nAD: 76fbc7e5d64be21cbb341b32ea61d8c6\nTAG: 98aaad6c40345751803926295d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5e86779506b46f0eabc6181b5a313222\nNONCE: ad02946f9f4e148462d14eea\nCT: \nAD: 89d777550c1c2148dbef73d7179d2bef\nTAG: dbfdb23c13eec51652128a223e\nIN: \n\nKEY: 0ea30aaa137345525472dbaa01918c86\nNONCE: 5ab6b70b7ede3b3fb08fcc39\nCT: \nAD: 64c3471c9ee1da88220ebae0a48cf98f\nTAG: cd171585c15995cedfcd148582\nIN: \n\nKEY: b0589030b2496a3b7ef823e2cc39bfd5\nNONCE: 6b9d5bc27d46fcdc6fbc39a9\nCT: \nAD: 7639433669bd4c1a1f3b1ac04fbf9cd8\nTAG: 83328a0e57afdf647e59a2d2c1\nIN: \n\nKEY: 81b27f066e5508f361cb98b3f378199c\nNONCE: 9ead7424a30cdc069b8668ed\nCT: \nAD: c19b80309e4aa34569f3058d13372b94\nTAG: a1127f3719147804e4eaeed8ca\nIN: \n\nKEY: 61a35d01df1b36fdbce2a6fc52b28305\nNONCE: 9d1708a0221d1d9bf3354a79\nCT: \nAD: 5ed9b0cd7a5e4072cce8f782a5438d1f\nTAG: 954fd6412d4b5f93d681c27baa\nIN: \n\nKEY: 15bbdcee8d262dfcf68f451e24bf26ca\nNONCE: c33f1f1eb456e6fb6d2277d3\nCT: \nAD: a3562c2071373e21cf346fee25cec4f2\nTAG: 1ce20f2935f8b8433a6820c228\nIN: \n\nKEY: eeda4ca996042630c017972b3bdaf09a\nNONCE: 0e02cd8bb87275df5287cee9\nCT: \nAD: 4ff3c0e013efca89e774b5794a8ba170\nTAG: 3b0e6daa01ad734c2eca681bf2\nIN: \n\nKEY: 75798e2e0ee570b06d4c47786336a099\nNONCE: e17c46acd0b0bbb15a5f9349\nCT: \nAD: e3779798212e7e9b4b2f387fbbbd95fe\nTAG: 1ab3d2c1cd55a89278224fc037\nIN: \n\nKEY: af2b060a94b20c9960f94fced963b2c5\nNONCE: dc8defbb5e45227e8576f45e\nCT: \nAD: 122f529fef4445f11a34111e10fd8b5d\nTAG: bb862654b76bd729ced4b4e9ad\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e1d07f1bc8f4a4b145badb96c85a82a6\nNONCE: 685e9636a2915adfc867889d\nCT: \nAD: 80c001fbf00b2bfd38ce903f0cd72db4\nTAG: ac9191dbb057b670dc76a194c2\nIN: \n\nKEY: ec4b3c2e077de7c2d62e28e3d05fe6c4\nNONCE: 704106b91d3a8f4dbee3ddbf\nCT: \nAD: f27dc1430cb30f8018cfc670eec9bb71\nTAG: d28d19fbedf2439140b0573083\nIN: \n\nKEY: 0dbbad4a54122500bb584787bfe94a86\nNONCE: dcad55f03d29103503858ff9\nCT: \nAD: 3c26ce754334b7fcc4576f4014349134\nTAG: 3251f275a3be44de87c5ff0544\nIN: \n\nKEY: d36cd8e8dd709b68433b4cef15efa4b8\nNONCE: dc859fa01cf3992fd5e74ba3\nCT: \nAD: 5983b73431118f294a4de08a4fbfbcc3\nTAG: 109412f2cd3dee2e75d9d90d\nIN: \n\nKEY: aa2717236879b0bfc29661187c0d2420\nNONCE: 1264dcda92ded29c03d846be\nCT: \nAD: 6b12dfb961f2e4d0ca2cea60666003af\nTAG: d69227a40670b13097d6f583\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 308a70f727df2e3c0f9da9f6607710b6\nNONCE: 1a790ff86fc2e6a428c9dd89\nCT: \nAD: fa18646779fa5a8ce9e271de0872f76d\nTAG: 68ffa9b8b2cc804935136712\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fb01d2721acc1c4a832232bb7ec59163\nNONCE: 6cd3cf1bc45c6f26b87b95a3\nCT: \nAD: 3fde68f37caf7e0f38c0281e3fb5e9a1\nTAG: f9da75272d67a6e180764a18\nIN: \n\nKEY: 8478e6653acf07ebb766bc941953aa23\nNONCE: 143b6fe40260052ddfc4537b\nCT: \nAD: 12f49ae610cea95e776f27f0ea433dc6\nTAG: 60aa4aefb53b800e1efd64bf\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f56ab97fbd0a2d8c6725f5a5ad117a2c\nNONCE: 266a436d9d05ee331a3ec858\nCT: \nAD: f31a01cd934b44208e9abe08c21f8be7\nTAG: b07258864aa6083fc15899e7\nIN: \n\nKEY: ba8a42bcc9d0bcbc9129d536d2364ebd\nNONCE: 6fc5c4ddb461acee4e3c2271\nCT: \nAD: 6bbb55b97c9cc3cfffa4f450b0debfee\nTAG: 3696c121fbb1def560c14182\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 827e4e3e9a4de530ae43510b94a55d54\nNONCE: d6c7fba9a73e76f6d1b015c6\nCT: \nAD: 3beff1d14cd6021b709d399d02015b05\nTAG: 2d58236b7e8113c821ddb4a0\nIN: \n\nKEY: 608ab3f94dd16b51c9afe4ba8dbdf852\nNONCE: a7b32bc6c976e8bd839f9af9\nCT: \nAD: eb212ef0a3a307024978a2c41a41d8a5\nTAG: 7aed47ba76b07717558bb87b\nIN: \n\nKEY: ef50e9ca5c53c2ddf49ccbd3c41a5a56\nNONCE: 817bee5ddedd26601cdb7cbc\nCT: \nAD: 75e26952eeaae53d83f77a3a502d3ca3\nTAG: 37245789deaada2d0dc5f2d4\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a9811b598adf0bbc34395b43829e86f6\nNONCE: c0def2f064789ad5d8f63799\nCT: \nAD: a735aab3b327ca3f575a09157b77a1c7\nTAG: 9f457e8e4757dae5cbd395bc\nIN: \n\nKEY: 3d906fa69252e00551b4a6347fe367ac\nNONCE: 067ea32f23e29d116fb0512b\nCT: \nAD: 4bf2a2096e27e75448cde7744b0209b", @@ -1426,9 +1487,9 @@ static const char *kData23[] = { "45795cf2a4ea1f33cbb4e1d769231b72a590ce3dc408ec7386a265d65102833edd8dd43b718e9ccf2655ccab0a6022dd81f6697544d9e8bd69c5e6511879686dc2d936cf9e4fb23ef1273fb61eb7bd62ab2b8c49fb916368d7f4a1fa081fd9b3633c1e4cf\nIN: 15ecba6f0f8a42236d020573bbc866d29a86dbff689694e0ba3087bcaade496eacf110d903cd99b81b808c6ecb6f36cb990b63\nAD: 6e848ab8f7f4971a52cbcd42eca24d33a8ba4a43a473444fe2a5f69cac5209779939349d7a73e65db30ff0adbdbf7f99db3f4a810764e4edde1a95b6138e08c7c939549d83aecd46a84a9b897b6896ab07a6a9de663376d6197d\nCT: 9c7d13e78bacc849c76072c527abba06046075fae2a3d13079f0f66635a521e0e1e822e05e009ce3aa788052f5600c00e71031\nTAG: cf632f67bc5092e0\n\nKEY: b4166038b75dec191fc0ddf8375ff4c7\nNONCE: 7f4ab1196310affe7d2d3c165f48c4a5652dc76e0baa1497727a87c49b445d350e810e8b73f9d53590fcc041a863971bf70c715f90bc594a5b98c521b0a91907b0058583f48aa10aba51c45937dfad510b5772e4875186954a575e906e48efa26bb1cf6201fec8f13a3a477da68fb6288b3573095d7027c1fea292d0ba2f2aa0\nIN: e4f6678ac787f6b6ea1c2f04ebae8afdb8941f1ca363f5654d4822358d6041af03979e269f070ba9f03e814114bedaea88a203\nAD: b9bf722d2eae013fa11c49f3475514f9592556abfc334cf9dfba3cfe37d0de7d7c996eb6712facb376651178585d4a60844f52e2590837c35acf169817b692bfae8d08ef374bba4bb0301005b4aae16c54f848b8226a312ad6b3\nCT: b16224062ade5afd4796e658b3beef0d13683e494aa0d745d930378d4b8bd0465f4e58b8ec9c85e97779a461a426e337abe399\nTAG: 3fc244c1caca2757\n\nKEY: d16e4e7ec43a42bd7156f259b369ce93\nNONCE: 34834e81b1ed4ea895cc76788c3adb48c2884b213a46f24a2012a5d06dd6a7175b61d9d4ffdc0e00c54163280b2ed247be68788866094b5b8846e0da034940f800cf3dd0ccd44163a085cb0194461fbde7d621e029fe3effbdde9d856d70fa3398ace4216a94d530b71408bdb9d3036ec81a8a21df120965629c13b796d7d9a7\nIN: 3c6791d91654bf4069f7ccce712fcfb82dac85f2669b80dae7d23f94ebcb280ef621ed8c5cc77fc582dc4f8240061b5e269a1a\nAD: 4bfeb3935a388f15b7418182f8b37c61487865f519c5e7dfbfa4c3b74e60398d82d449ed418ee301895bcd8ddf5a9d50b74037af9a261bad3633600ba7dc79f06a5f09f350ad43c90c27f744779e82f850e23fd79136adafb555\nCT: aa546ace6bd092399bdefe0ab0985f9c380006117be38648e3a0da80cf4d32ece831c06e532b9324fd1df14a6acf8d75275fc3\nTAG: 7068e4ca6ac26998\n\nKEY: c4a8b2c99b62a2a64f8086aab1fd6c43\nNONCE: 2e6d6f434c72c71560f05b55fb7c07e310260aec112aab0e64e8f87fe738fc1b23dea859bbefbe9545fb575fc0a6d45fef42af09dccc9fde0a52ee84afe8d1339641ee5e00239e42b310d9acfd428c2075d93112bcf9ebe728707966ec29b1f72e87cccf75a2255875bf78abf0cd6534520625ac7d0df18bd6a1fd613f894198\nIN: a77ccd123128b46d9144fc5a90ec64bce6b4b5efc5646c8d4961eebe253235baeb236d8af9d1d81ad2bd4c86db78c31c1c8c90\nAD: 23463bb91dcd4716b7364e71a2ebe5e1aaef3cba8ea4214dbd6a987c9850af86518747c4869e00ce244f418ce19f0113705999aac35ad0bbda719573d69101046b34df89774d0093684ad7ec66eb509d8e7c25f552956c488095\nCT: a3632572e59a7c558d5e1ee9f5c059a5e118964c14e3d4e953b5c15d105db76bf970ed17bcccd84162feecbb3fc93d7015143a\nTAG: 27ccd8eae70c6ec9\n\nKEY: 2633d1781ce54f74ac609a5b5209a01f\nNONCE: 7d0e90b7e9f36f760d2dcbd66f352df45f3917afdbe1d0a89cc44be0bd85cf8bf75edbdd33f1d16dad02824d81389210b0f146f3df63f9232d7035eb9e8297a09474985b3e038a5fa6840155d8848fc7c53061ba0f442b84408660a997176ca5bf3473103fd3c9a1de2580b9e539af872259ecae925a8ef50f5a176a069b1fb8\nIN: ae695828625b264e0b13d3c9a539f2cf306a7501cdd35b817b699b2d7c25cf20d2dceec3fa883019db807272fddfdca8e7f672\nAD: 584c3cad3035d1427d6f5f1b261e97a5ea7d97c0b88cedf3b1aa5e21e5916805a63964eab4449d8806e7af60618465cf39f82769b7528bba9bb9c04992cd7b9e26efe9be38e1bfeeb41678c52d5ba3508fd7a2b1e8478505bfde\nCT: fbc32a56885100a36c276ff368db9236906021a8cc7500f2b3e78a6ca01546827073ff1103145f139f4d116eb47b84e33c7160\nTAG: 49589b3a\n\nKEY: 62dc8e1a98863c7de64f30b74c01d530\nNONCE: e9f658589f973895510cb34eef99b0cf34fc311c20c21464e07c4d6d34a15fcad3ea9ef51ef05513fb700cbb92aeef35e4cdda47b2c06c1104e987afa1cd6f827e7bc5a8db6d0657345945c068cabfd6e6b57533c929fe5804e121809b8b43d050a211fbee319879b1ba4cc2768df3a92014839086a377663a1d1967d7c602e9\nIN: f2c54a35286a225389e853e51f3f64b6980a79262e5545856c053d558d87d7b739eb75f27587efe219eb82e9a176fa14419dbe\nAD: 5d78b486c29131866569768d5eedb61afc48de7d1a223d0cccc647cf35408bb932293f3bc1b51a504e13c27548d083c8e8a45d4e9d4dc923c3c2bde38d6cdeaed2929b67e371356f74f635b3b1183ee0db71476f2024e1f5e13c\nCT: fe0c3ae08418ef91b478360942a84a58f8d93df7fe5bde138f59cc23432f04b9637841ccf7a5d539a36f621a7d17e026d4cc2c\nTAG: e413041a\n\nKEY: 9cb4b060870a2563d9f38b7c84f45ad0\nNONCE: 6f268f644af70b43d71c881009a29d966d4d4b13e9a22dae30c299d69d195f92d7ac45579444358acb2de20b78afa3f258eae68f7abc68a664f375efe43f8d39c69668931dd0daba24c8fb74b0a0eca13434ee9573246d342a91514a2495b6c8fce8ec9ecfc93400601d80ac9c4711777a7cc00086d31cc536c05b961c4fc5e8\nIN: 0f75400a6deb4427878b0ac3a1cc3950b39531716cab167ba2113aac383627b173ccd942858b0a3dc5bea3144f9a52179a8565\nAD: 99932f2dcd9dd63a4af30ede3b00d8e12fd24f2328fb03a3251cb1ff9b67b9bfcfe5432e444d4d60a8ce6a39fa41a391c0bccf686d9ac044f72c60ee8f3f26b8355267343b31bc0d2886c84dc6bb1c7c20388c16d04fada74915\nCT: 872ffa67cc633f74ad29cb8b0595989c0c79a5028f629b2800d1412abf1df68a10142e760ecadafba3361f2d43afe79c29c168\nTAG: 15851c9b\n\nKEY: b9587f9d7f881ec94a096b7fddfdc5ce\nNONCE: 107ab768521c30b4778ff9191934249561b8df2e803190da64de20f05979d2376ff6c048aefca35b246a888319b21306f52d1f1f1913545f532a3cf1de4cd52b926321a5a27f501bda538e1418c4b07599a9f897cd6d37320d1e08ffd4a2697bdf91fd5123038ccafd38457e061e3c48def212f94a5efe259ff276ee86c91337\nIN: 5d69699972afef8d1a7fcbb513a87dfdcbfcf01c367d5a378a649cbf92812c6da38815270a9ba0af4be351ad8b062a73a7f63b\nAD: a9d648927fce9991ae15571e1f7810536b41714506ee0197b9471e06613bcb8636203c1c67b93af6d1545baa181c2a149ac471dbd54dbae9784848a4b7ac6894a67bf40ed892df9bc720376e866e92c05c16bc58db1286d5ccb4\nCT: ee550d3368a1115d9cbb1dc37715d7e16e827eabc7d73b537c4cb6fd437e7c88e4afac6ee8807046f0da4788b3b26eb31e4a58\nTAG: dcd71cee\n\nKEY: 1e0c8c8cd53c942ca29dd3d202eb343f\nNONCE: beaf4a32b50c86f92611d7ab665ba344a12f8e5b281580f043633e9bf515d572520b23bf9e5214c38ab43fa4ef2f1a1bca05bba703c5c529943f069ea6f6053e8af0c7eb751b628a82e3ac22ada6e17a12152ae2d5d4162f70e34a8d0685af1d174db91cdc1c103678245cd9483753aca6ac240e5909c18c84f0c090dede24ee\nIN: 2dba40b971012ee4f3b443fd815726065859a28a06d22a1c35cd04529c7b805999cde4ce370b2ed3ea675428dcf5a3a99f7622\nAD: b61a1b5501326d7e67387500835f788574d21fa80df4a9fc6184259a8f0fd8180ef988e12baa645b7500ee246ea52284722051ec4c345a803714f2bc8f02dad385c575128cc6247ca3d293e2b487327f69b0304d402f97dcfa5c\nCT: ce5e806ad840e78042c2e0da0ff3af376a1f7d38adcab0226da6d34887b2b3ae17efcafeb0e32f5070d7cdb850c9ab5b0d8614\nTAG: 6d82627c\n\nKEY: 2fadbffa3eae8caba795506e9d9db0ef\nNONCE: f67d45a1d51912eed0e80d5f5ae05ce4c2c381aee2c4a391823df6b44ad123802602160cd679bdf893dc3aaa547a604e7d1e94de79523891ad32fc0943c822cfb995e5efa197f37a885aab5fd91d47c5ccf852977d7e689f663c5e933a5a72eb4417fce7f3a635cdcaffd60bfa875ad6c2f72cf284831fe640a23fdda21fcf77\nIN: 2f01fb5b9036ab22af19b326769f332b3f6adffbaa9583474bcc5499e00413f9b273a76412ce7d268f12471c078600a2f15bef\nAD: b872df430bd4400030ec5c38289a4be8d4bae608023b6f3922aab24f75bc0d29c2fc378bfdf47a99d7d3d53e1ea2e9420c2752f5b9b6e06b18b9eebd2344e190c4c1ee0f60b14ca89b5c8d3a25c9546a2d013b22ee9fbf92a247\nCT: c1d0f6f53c885b6470372f7d7468eb42fa1f4e20b540a68cac91060050f430d27c50e85403428a75de816c4747776476ae4e3d\nTAG: 8a457c98\n\nKEY: 3f3ec6bb52cc9a725abbf7b9b3f9fa4d\nNONCE: a700805e157f5fd7cec77bc556c2ad7e662c4b55b284970175d0476189822855d44fdecbe28b3fe7a73a6040e6994b8460262b5b5ac1049dbcf4a5febe21eb8574d3a679cc480958852efe787746b4b85acb86757cc855b9db99193208029ad1446631e4a101a115122a98e861c62ef1e3d6587122353b5f958420dc7c80d751\nIN: 07029e02ff512e948112d4f51d5f86d04edd2003447aba21f3976a7200f765130b8971508acbdaa6191c7691dccdde8617a86b\nAD: c6ca6cc319e5296e2ee085036193bbfc4e25a6079dfce25171ef0a2dd569355c73c69cfba69dfac17834ed3226886c07e5461bd605e83be4edd20173f395b37093bef321949d8a0797987796b30aa3387bfd3137506d6fbe5080\nCT: 3b26164ad8088f7e16ae82bd48c7c09230b05a820ea8f89cb4ca54529ccfd74addc308d00ef18f6712d3beac1946ab7da0852e\nTAG: 7e25563d\n\nKEY: 2f2f448e677da243aed2046c864db4dd\nNONCE: e0e01fea2c7c412f6365486b8859d1955075d82f68fb217047db274042d5fec731765541c2111e2ebd17894fd38b82cfadaa34c16526c1bc2efd3b8d6eacd7c4643da5288f37a0c61e8eebf6da76d641ad4c6545c0d7a7d4ae4a23373687e08b8e2d9c457ceff49947bf59e96db4f7304665584d22a0bc858a49721987afa904\nIN: 07a1024ae506ac70abb723c606eea5f6df328195c2f5a3fb629dd2813251abc7d3874deccca999", "44caefcb83f5bbbf36566807\nAD: be09b05e89a7e910f21607bed4e950d120e9d935c715023febdcd4639de7e440189aac53009cfbcd2acb230688abca97165943c65b1e8ed24ca72c4b57084e0610040929b918922d0f1b8a0d25c8cce46889add73b0b6d8a89bf\nCT: 15e4f0f567861361eb342ca281bf1b860f6681b33ba7c547682c4e92d48805cccce12b4be0c3b13af464fba9e79c561e3f0f00\nTAG: e7a6dfb2\n\nKEY: c35b35f68743e2e4f88bb48059f2e21b\nNONCE: 2dfae4843d58be3cc005915c357c5bdfaf7c4e7817e0164b123ec1ad08187269c323568f2bb80c50100b0de276dee9c81ba98801b848bdfdd6185a1926b3eb6adf1df193a6609932a150e0eeee08ee58d3027c712cc729abf9e7bfd3d5b328aa2887109b606704cee0455bf7135a3b4179c8aa86ac31e5e3209c04921975fb83\nIN: b1f1dd264e4f26da74f839728cf70743ef435c016a6549b17b70ac93ac37b0e97bbc3fd092dc07f2b020527b781a38f8d2687c\nAD: 65556a625bfa8b96e71ab5eca7bacb87c9140828b8605d9f3e441628d76281d5a5aca1fec44f038162977cff46d64f965bc4f94214fc63cc56c496aa9aca5adb855faef1f54123633a5d4dc367ab3cceb0c9e42eff3d981945d6\nCT: dabfba195ac7f737153810c3b6db598e2e346af941108f6535b3cbd389428280daf4d86b78148197fd6e0831434a0fdda3bf93\nTAG: c85e1c09\n\nKEY: f6e086357ed6cb07dbb463aa500ae69c\nNONCE: 15b56fb043a72881081a72bce9298e21fe60aeaf1e4b4a85bde873930adecb48d4c8f17362aef0cdf2c3bbbdbc00ce29669b633f181bfcb85c44511c5754ca07595dbdcd335b0078ebf8b09f5190096a9078259168b5a5e1b79211b62d8f0c306e5a0c4e81ea0c6c78e63f5529b633c28494c6f0a42ffe51be150df24aed1602\nIN: fe49c833bfcb93c401b3483d7c7fc9fdaaf3a2146bcc36e0ffe37ef1ac6ce855d0fad3675c9c9fe7cb908589cddf43c4c35421\nAD: b3f36b821f294d33a90c4675aba4b32f32abc3683843ad1689acf130a43a3b21b3473d3a6c7cccecd4c767a7682a26fc524eb6c9688719acfd708c304d3db201b662f48610cbb6c1ae521f00de7904d668b95b812be2b4298807\nCT: e56f27f5aea684a8421f1d559b56d80b3790cf3fbb5cd309f2866ae628c8196605edaca9be512cf6a42e53aca4478405a95d6a\nTAG: d2d608be\n\nKEY: 0dbefe872ed2ea2a964fe991541ae834\nNONCE: 82f382aee615f224677e876367268b31c89981e816c7c5a5ed1c7fa50370ce6a6e13dc2d1ffefef5d317302e22874d28fc67e0cf4d6fdbf1b5c8ff5645256378eca8426454ea600376aadf02d17bc171e40faa2e62530235063e73ac50d06c2a88d9e5e35739cffe8ac70aa2c4f4e00716052f823e0dcdd2b4b5afacbc79f4c1\nIN: 8445831a7b481e187978afbf195eb65eac1ebf3acf1fa452da79248ea484c9bc00d233c2e3b827de9b46bad3726c315080ca7f\nAD: 72caa4d008c9f7f9667fb98501c7e44972f491a8723db27e4a404d377cb4456234f9b56b9235087e25016e00cc6e6be08de7d8739a546db4a78407cc9200404332955a3c68d1f3c6bebf9c74d2e9bc54dc1c56c6b62c72bad6d0\nCT: 800fa98daa36955ab30dd4044756cccf382210a6548069d2f740094c29bdd10ba9bb0db0ca7a7db5fdaf2217c59ff5e0bce136\nTAG: fbc8e65c\n\nKEY: 92666e547ca6722278bc41f78c606014\nNONCE: 2e9733e8dc10ca3964e96b56839fbce9969f5f821fdf2f278e5465b6cf3fac8ed407d04b602209a0c97c14b710f6a3f29f65a1599869139f8061824745ad4470406956d3018eec8ff2584164db279a5a5f724030fa8478e7dacb949e473dee12332fd611bd66b06faa380b57b530a5cac30f3aacd607233c22460240edad253d\nIN: 97ce2ebd1850551b96813179b2bad2270eccf7195fe70273c9b4045e68a501781e47f808cb248326cb6425635db1d516ec760f\nAD: 20d0f02f1346ed9c8a697a5b507ed482033a177d4a71bd694b1533e94b72aaf54e48be64b6f7a30b2c6e94a00159ad60ce84d677d035790591a00e8068275e5caebe185bdb14ad24ab41e8fa3d0f4e19f57a390707efcd191cd0\nCT: 44af16eb4079f52009592436a0f1d7373a992fb5679c048466804495b9e1264e8292afe33c2661e30d3c2fedab5963bf0c63f5\nTAG: 917b6024\n\nKEY: d3f7d84e2a2f2e45e19e7dd4432f6cbb\nNONCE: bf1b1afa5c28d0f6883a12a4eb984ee8edd3c75e91d44628eb1133bad58506285961fd3d2d3f671788895a55824022c4b5a2ee0e470124c9b7cc00d6082e95991deedff69e366e9eb96a9e814e58e89c58abb224dc13d78db68797bbccdacf082f8563cc4c40137203c206476668482d51eee902c7e3344e7355ac18b61d3e1a\nIN: e02d21da508ab1157ec2aee2c18a924a34b84d7746bba79da3662402c111d686fb5f50a8831f01623e1b22f1a79b2cd014d715\nAD: 951ea13d95700d0c97e12df456280532ef86260307cf95375211b7fb44c3eb50ddeb5ef350714ac2c620ef8f66eb0da1796915400210568360d571e58de7d30e06b812112069667370376812e4e593362226997fe2947ded6371\nCT: d948b5f4f415423b656abf715c9fc756f90117f694b32961fa8f4bf003cffd463716644eef0ce5919dca38788e0df24a7d1367\nTAG: 19a23818\n\nKEY: 357e9c3ab5323ff141bdf17228b80a61\nNONCE: de8cd40a5db81e8b7083807a8a5c16d4808f48c52a56c68b77edb01b563f80513518eac2672c8f5524aa6e3850337233c693dec99a547cf6599dc33a6d89763e5f91d9a74715c9a635ed1931403b2fbec8be85f287506ed4bd7da3c6e2b25e29becf9466f4abdf3b0daa4818a7f31563fb5be7aba7cbd53c6522331fc04d4573\nIN: 995142af8870fd1c805aa9919f76485dc1fed5ead1e8366633ef09db5595c1a305bd10d945409148744d3998aba6434172087f\nAD: 863ebc2231af641f620f618567007847057146db69b1066dc1c4464d251729eb6ea3871d3e997e71a963439e9d81691a7196ddd439748e795a2cc62b8382a61e79863259cb643851f9a271130e0f9f54e15f0dc3ec8b27084c39\nCT: fc12b78280d4a9eef7d536f2f5b3b3d63cf641e07f6b91332b9200d224632c5b1ee41ee136693bf0c26d569e998d9a09ad24f8\nTAG: c0f7d0e6\n\nKEY: 0e00c76561d2bd9b40c3c15427e2b08f\nNONCE: 492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e74cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496\nIN: fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956ca9c0195721476b85\nAD: d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba8f1f56c0\nCT: 4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2cf4fc97416ee52abe\nTAG: e20b6655\n\n", }; -static const size_t kLen24 = 154319; +static const size_t kLen25 = 154319; -static const char *kData24[] = { +static const char *kData25[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-192-CBC kat_aes/CBCGFSbox192.rsp kat_aes/CBCKeySbox192.rsp kat_aes/CBCVarKey192.rsp kat_aes/CBCVarTxt192.rsp\"\n\n# File 1: kat_aes/CBCGFSbox192.rsp\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 1b077a6af4b7f98229de786d7516b639\nCiphertext: 275cfc0413d8ccb70513c3859b1d0f72\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 9c2d8842e5f48f57648205d39a239af1\nCiphertext: c9b8135ff1b5adc413dfd053b21bd96d\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: bff52510095f518ecca60af4205444bb\nCiphertext: 4a3650c3371ce2eb35e389a171427440\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 51719783d3185a535bd75adc65071ce1\nCiphertext: 4f354592ff7c8847d2d0870ca9481b7c\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 26aa49dcfe7629a8901a69a9914e6dfd\nCiphertext: d5e08bf9a182e857cf40b3a36ee248cc\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 941a4773058224e1ef66d10e0a6ee782\nCiphertext: 067cd9d3749207791841562507fa9626\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 275cfc0413d8ccb70513c3859b1d0f72\nPlaintext: 1b077a6af4b7f98229de786d7516b639\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c9b8135ff1b5adc413dfd053b21bd96d\nPlaintext: 9c2d8842e5f48f57648205d39a239af1\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4a3650c3371ce2eb35e389a171427440\nPlaintext: bff52510095f518ecca60af4205444bb\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4f354592ff7c8847d2d0870ca9481b7c\nPlaintext: 51719783d3185a535bd75adc65071ce1\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d5e08bf9a182e857cf40b3a36ee248cc\nPlaintext: 26aa49dcfe7629a8901a69a9914e6dfd\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 067cd9d3749207791841562507fa9626\nPlaintext: 941a4773058224e1ef66d10e0a6ee782\n\n# File 2: kat_aes/CBCKeySbox192.rsp\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0956259c9cd5cfd0181cca53380cde06\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 15d20f6ebc7e649fd95b76b107e6daba967c8a9484797f29\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8e4e18424e591a3d5b6f0876f16f8594\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: a8a282ee31c03fae4f8e9b8930d5473c2ed695a347e88b7c\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 93f3270cfc877ef17e106ce938979cb0\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: cd62376d5ebb414917f0c78f05266433dc9192a1ec943300\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7f6c25ff41858561bb62f36492e93c29\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 502a6ab36984af268bf423c7f509205207fc1552af4a91e5\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8e06556dcbb00b809a025047cff2a940\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 25a39dbfd8034f71a81f9ceb55026e4037f8f6aa30ab44ce\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3608c344868e94555d23a120f8a5502d\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: e08c15411774ec4a908b64eadc6ac4199c7cd453f3aaef53\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 77da2021935b840b7f5dcc39132da9e5\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 3b375a1ff7e8d44409696e6326ec9dec86138e2ae010b980\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3b7c24f825e3bf9873c9f14d39a0e6f4\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 950bb9f22cc35be6fe79f52c320af93dec5bc9c0c2f9cd53\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 64ebf95686b353508c90ecd8b6134316\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 7001c487cc3e572cfc92f4d0e697d982e8856fdcc957da40\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ff558c5d27210b7929b73fc708eb4cf1\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: f029ce61d4e5a405b41ead0a883cc6a737da2cf50a6c92ae\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a2c3b2a818075490a7b4c14380f02702\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cfe4d74002696ccf7d87b14a2f9cafc9\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d2eafd86f63b109b91f5dbb3a3fb7e13\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9b9fdd1c5975655f539998b306a324af\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: d2926527e0aa9f37b45e2ec2ade5853ef807576104c7ace3\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: dd619e1cf204446112e0af2b9afa8f8c\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 982215f4e173dfa0fcffe5d3da41c4812c7bcc8ed3540f93\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d4f0aae13c8fe9339fbf9e69ed0ad74d\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 98c6b8e01e379fbd14e61af6af891596583565f2a27d59e9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 19c80ec4a6deb7e5ed1033dda933498f\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: b3ad5cea1dddc214ca969ac35f37dae1a9a9d1528f89bb35\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3cf5e1d21a17956d1dffad6a7c41c659\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 45899367c3132849763073c435a9288a766c8b9ec2308516\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 69fd12e8505f8ded2fdcb197a121b362\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ec250e04c3903f602647b85a401a1ae7ca2f02f67fa4253e\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8aa584e2cc4d17417a97cb9a28ba29c8\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: d077a03bd8a38973928ccafe4a9d2f455130bd0af5ae46a9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: abc786fb1edb504580c4d882ef29a0c7\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: d184c36cf0dddfec39e654195006022237871a47c33d3198\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2e19fb60a3e1de0166f483c97824a978\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 4c6994ffa9dcdc805b60c2c0095334c42d95a8fc0ca5b080\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7656709538dd5fec41e0ce6a0f8e207d\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: c88f5b00a4ef9a6840e2acaf33f00a3bdc4e25895303fa72\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a67cf333b314d411d3c0ae6e1cfcd8f5\n\nCipher: AES-192-CBC\nOpera", "tion: DECRYPT\nKey: e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd\nIV: 00000000000000000000000000000000\nCiphertext: 0956259c9cd5cfd0181cca53380cde06\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 15d20f6ebc7e649fd95b76b107e6daba967c8a9484797f29\nIV: 00000000000000000000000000000000\nCiphertext: 8e4e18424e591a3d5b6f0876f16f8594\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: a8a282ee31c03fae4f8e9b8930d5473c2ed695a347e88b7c\nIV: 00000000000000000000000000000000\nCiphertext: 93f3270cfc877ef17e106ce938979cb0\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: cd62376d5ebb414917f0c78f05266433dc9192a1ec943300\nIV: 00000000000000000000000000000000\nCiphertext: 7f6c25ff41858561bb62f36492e93c29\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 502a6ab36984af268bf423c7f509205207fc1552af4a91e5\nIV: 00000000000000000000000000000000\nCiphertext: 8e06556dcbb00b809a025047cff2a940\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 25a39dbfd8034f71a81f9ceb55026e4037f8f6aa30ab44ce\nIV: 00000000000000000000000000000000\nCiphertext: 3608c344868e94555d23a120f8a5502d\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: e08c15411774ec4a908b64eadc6ac4199c7cd453f3aaef53\nIV: 00000000000000000000000000000000\nCiphertext: 77da2021935b840b7f5dcc39132da9e5\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 3b375a1ff7e8d44409696e6326ec9dec86138e2ae010b980\nIV: 00000000000000000000000000000000\nCiphertext: 3b7c24f825e3bf9873c9f14d39a0e6f4\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 950bb9f22cc35be6fe79f52c320af93dec5bc9c0c2f9cd53\nIV: 00000000000000000000000000000000\nCiphertext: 64ebf95686b353508c90ecd8b6134316\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 7001c487cc3e572cfc92f4d0e697d982e8856fdcc957da40\nIV: 00000000000000000000000000000000\nCiphertext: ff558c5d27210b7929b73fc708eb4cf1\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: f029ce61d4e5a405b41ead0a883cc6a737da2cf50a6c92ae\nIV: 00000000000000000000000000000000\nCiphertext: a2c3b2a818075490a7b4c14380f02702\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79\nIV: 00000000000000000000000000000000\nCiphertext: cfe4d74002696ccf7d87b14a2f9cafc9\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570\nIV: 00000000000000000000000000000000\nCiphertext: d2eafd86f63b109b91f5dbb3a3fb7e13\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6\nIV: 00000000000000000000000000000000\nCiphertext: 9b9fdd1c5975655f539998b306a324af\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: d2926527e0aa9f37b45e2ec2ade5853ef807576104c7ace3\nIV: 00000000000000000000000000000000\nCiphertext: dd619e1cf204446112e0af2b9afa8f8c\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 982215f4e173dfa0fcffe5d3da41c4812c7bcc8ed3540f93\nIV: 00000000000000000000000000000000\nCiphertext: d4f0aae13c8fe9339fbf9e69ed0ad74d\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 98c6b8e01e379fbd14e61af6af891596583565f2a27d59e9\nIV: 00000000000000000000000000000000\nCiphertext: 19c80ec4a6deb7e5ed1033dda933498f\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: b3ad5cea1dddc214ca969ac35f37dae1a9a9d1528f89bb35\nIV: 00000000000000000000000000000000\nCiphertext: 3cf5e1d21a17956d1dffad6a7c41c659\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 45899367c3132849763073c435a9288a766c8b9ec2308516\nIV: 00000000000000000000000000000000\nCiphertext: 69fd12e8505f8ded2fdcb197a121b362\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: ec250e04c3903f602647b85a401a1ae7ca2f02f67fa4253e\nIV: 00000000000000000000000000000000\nCiphertext: 8aa584e2cc4d17417a97cb9a28ba29c8\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: d077a03bd8a38973928ccafe4a9d2f455130bd0af5ae46a9\nIV: 00000000000000000000000000000000\nCiphertext: abc786fb1edb504580c4d882ef29a0c7\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: d184c36cf0dddfec39e654195006022237871a47c33d3198\nIV: 00000000000000000000000000000000\nCiphertext: 2e19fb60a3e1de0166f483c97824a978\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 4c6994ffa9dcdc805b60c2c0095334c42d95a8fc0ca5b080\nIV: 00000000000000000000000000000000\nCiphertext: 7656709538dd5fec41e0ce6a0f8e207d\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: c88f5b00a4ef9a6840e2acaf33f00a3bdc4e25895303fa72\nIV: 00000000000000000000000000000000\nCiphertext: a67cf333b314d411d3c0ae6e1cfcd8f5\nPlaintext: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey192.rsp\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: 800000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: de885dc87f5a92594082d02cc1e1b42c\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: c00000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 132b074e80f2a597bf5febd8ea5da55e\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: e00000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6eccedf8de592c22fb81347b79f2db1f\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: f00000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 180b09f267c45145db2f826c2582d35c\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: f80000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: edd807ef7652d7eb0e13c8b5e15b3bc0\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fc0000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9978bcf8dd8fd72241223ad24b31b8a4\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fe0000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5310f654343e8f27e12c83a48d24ff81\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ff0000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 833f71258d53036b02952c76c744f5a1\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ff8000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: eba83ff200cff9318a92f8691a06b09f\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffc000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ff620ccbe9f3292abdf2176b09f04eba\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffe000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7ababc4b3f516c9aafb35f4140b548f9\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fff000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: aa187824d9c4582b0916493ecbde8c57\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fff800000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1c0ad553177fd5ea1092c9d626a29dc4\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKe", "y: fffc00000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a5dc46c37261194124ecaebd680408ec\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffe00000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e4f2f2ae23e9b10bacfa58601531ba54\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffff00000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b7d67cf1a1e91e8ff3a57a172c7bf412\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffff80000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 26706be06967884e847d137128ce47b3\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffc0000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b2f8b409b0585909aad3a7b5a219072a\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffe0000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5e4b7bff0290c78344c54a23b722cd20\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffff0000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 07093657552d4414227ce161e9ebf7dd\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffff8000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e1af1e7d8bc225ed4dffb771ecbb9e67\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffc000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ef6555253635d8432156cfd9c11b145a\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffe000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fb4035074a5d4260c90cbd6da6c3fceb\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffff000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 446ee416f9ad1c103eb0cc96751c88e1\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffff800000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 198ae2a4637ac0a7890a8fd1485445c9\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffc00000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 562012ec8faded0825fb2fa70ab30cbd\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffe00000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cc8a64b46b5d88bf7f247d4dbaf38f05\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffff00000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a168253762e2cc81b42d1e5001762699\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffff80000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1b41f83b38ce5032c6cd7af98cf62061\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffc0000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 61a89990cd1411750d5fb0dc988447d4\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffe0000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b5accc8ed629edf8c68a539183b1ea82\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffff0000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b16fa71f846b81a13f361c43a851f290\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffff8000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4fad6efdff5975aee7692234bcd54488\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffc000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ebfdb05a783d03082dfe5fdd80a00b17\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffe000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: eb81b584766997af6ba5529d3bdd8609\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffff000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0cf4ff4f49c8a0ca060c443499e29313\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffff800000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cc4ba8a8e029f8b26d8afff9df133bb6\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffc00000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fefebf64360f38e4e63558f0ffc550c3\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffe00000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 12ad98cbf725137d6a8108c2bed99322\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffff00000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6afaa996226198b3e2610413ce1b3f78\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffff80000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2a8ce6747a7e39367828e290848502d9\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffc0000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 223736e8b8f89ca1e37b6deab40facf1\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffe0000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c0f797e50418b95fa6013333917a9480\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffff0000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a758de37c2ece2a02c73c01fedc9a132\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffff8000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3a9b87ae77bae706803966c66c73adbd\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffffc000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d365ab8df8ffd782e358121a4a4fc541\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: fffffffffffe000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c8dcd9e6f75e6c36c8daee0466f0ed74\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffff000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c79a637beb1c0304f14014c037e736dd\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffff800000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 105f0a25e84ac930d996281a5f954dd9\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffffc00000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 42e4074b2927973e8d17ffa92f7fe615\n\nCipher: AES-192-CBC\nOperation: ENCRYPT\nKey: ffffffffffffe00000000000000000000000000000000000\n", @@ -1449,9 +1510,9 @@ static const char *kData24[] = { "0000\nCiphertext: 0882a16f44088d42447a29ac090ec17e\nPlaintext: fffffffffffffff00000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3a3c15bfc11a9537c130687004e136ee\nPlaintext: fffffffffffffff80000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 22c0a7678dc6d8cf5c8a6d5a9960767c\nPlaintext: fffffffffffffffc0000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b46b09809d68b9a456432a79bdc2e38c\nPlaintext: fffffffffffffffe0000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 93baaffb35fbe739c17c6ac22eecf18f\nPlaintext: ffffffffffffffff0000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c8aa80a7850675bc007c46df06b49868\nPlaintext: ffffffffffffffff8000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 12c6f3877af421a918a84b775858021d\nPlaintext: ffffffffffffffffc000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 33f123282c5d633924f7d5ba3f3cab11\nPlaintext: ffffffffffffffffe000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a8f161002733e93ca4527d22c1a0c5bb\nPlaintext: fffffffffffffffff000000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b72f70ebf3e3fda23f508eec76b42c02\nPlaintext: fffffffffffffffff800000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6a9d965e6274143f25afdcfc88ffd77c\nPlaintext: fffffffffffffffffc00000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a0c74fd0b9361764ce91c5200b095357\nPlaintext: fffffffffffffffffe00000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 091d1fdc2bd2c346cd5046a8c6209146\nPlaintext: ffffffffffffffffff00000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e2a37580116cfb71856254496ab0aca8\nPlaintext: ffffffffffffffffff80000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e0b3a00785917c7efc9adba322813571\nPlaintext: ffffffffffffffffffc0000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 733d41f4727b5ef0df4af4cf3cffa0cb\nPlaintext: ffffffffffffffffffe0000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a99ebb030260826f981ad3e64490aa4f\nPlaintext: fffffffffffffffffff0000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 73f34c7d3eae5e80082c1647524308ee\nPlaintext: fffffffffffffffffff8000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 40ebd5ad082345b7a2097ccd3464da02\nPlaintext: fffffffffffffffffffc000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7cc4ae9a424b2cec90c97153c2457ec5\nPlaintext: fffffffffffffffffffe000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 54d632d03aba0bd0f91877ebdd4d09cb\nPlaintext: ffffffffffffffffffff000000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d3427be7e4d27cd54f5fe37b03cf0897\nPlaintext: ffffffffffffffffffff800000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b2099795e88cc158fd75ea133d7e7fbe\nPlaintext: ffffffffffffffffffffc00000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a6cae46fb6fadfe7a2c302a34242817b\nPlaintext: ffffffffffffffffffffe00000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 026a7024d6a902e0b3ffccbaa910cc3f\nPlaintext: fffffffffffffffffffff00000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 156f07767a85a4312321f63968338a01\nPlaintext: fffffffffffffffffffff80000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 15eec9ebf42b9ca76897d2cd6c5a12e2\nPlaintext: fffffffffffffffffffffc0000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: db0d3a6fdcc13f915e2b302ceeb70fd8\nPlaintext: fffffffffffffffffffffe0000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 71dbf37e87a2e34d15b20e8f10e48924\nPlaintext: ffffffffffffffffffffff0000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c745c451e96ff3c045e4367c833e3b54\nPlaintext: ffffffffffffffffffffff8000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 340da09c2dd11c3b679d08ccd27dd595\nPlaintext: ffffffffffffffffffffffc000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8279f7c0c2a03ee660c6d392db025d18\nPlaintext: ffffffffffffffffffffffe000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a4b2c7d8eba531ff47c5041a55fbd1ec\nPlaintext: fffffffffffffffffffffff000000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 74569a2ca5a7bd5131ce8dc7cbfbf72f\nPlaintext: fffffffffffffffffffffff800000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3713da0c0219b63454035613b5a403dd\nPlaintext: fffffffffffffffffffffffc00000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8827551ddcc9df23fa72a3de4e9f0b07\nPlaintext: fffffffffffffffffffffffe00000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2e3febfd625bfcd0a2c06eb460da1732\nPlaintext: ffffffffffffffffffffffff00000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ee82e6ba488156f76496311da6941deb\nPl", "aintext: ffffffffffffffffffffffff80000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4770446f01d1f391256e85a1b30d89d3\nPlaintext: ffffffffffffffffffffffffc0000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: af04b68f104f21ef2afb4767cf74143c\nPlaintext: ffffffffffffffffffffffffe0000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cf3579a9ba38c8e43653173e14f3a4c6\nPlaintext: fffffffffffffffffffffffff0000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b3bba904f4953e09b54800af2f62e7d4\nPlaintext: fffffffffffffffffffffffff8000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fc4249656e14b29eb9c44829b4c59a46\nPlaintext: fffffffffffffffffffffffffc000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9b31568febe81cfc2e65af1c86d1a308\nPlaintext: fffffffffffffffffffffffffe000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9ca09c25f273a766db98a480ce8dfedc\nPlaintext: ffffffffffffffffffffffffff000000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b909925786f34c3c92d971883c9fbedf\nPlaintext: ffffffffffffffffffffffffff800000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 82647f1332fe570a9d4d92b2ee771d3b\nPlaintext: ffffffffffffffffffffffffffc00000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3604a7e80832b3a99954bca6f5b9f501\nPlaintext: ffffffffffffffffffffffffffe00000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 884607b128c5de3ab39a529a1ef51bef\nPlaintext: fffffffffffffffffffffffffff00000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 670cfa093d1dbdb2317041404102435e\nPlaintext: fffffffffffffffffffffffffff80000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7a867195f3ce8769cbd336502fbb5130\nPlaintext: fffffffffffffffffffffffffffc0000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 52efcf64c72b2f7ca5b3c836b1078c15\nPlaintext: fffffffffffffffffffffffffffe0000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4019250f6eefb2ac5ccbcae044e75c7e\nPlaintext: ffffffffffffffffffffffffffff0000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 022c4f6f5a017d292785627667ddef24\nPlaintext: ffffffffffffffffffffffffffff8000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e9c21078a2eb7e03250f71000fa9e3ed\nPlaintext: ffffffffffffffffffffffffffffc000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a13eaeeb9cd391da4e2b09490b3e7fad\nPlaintext: ffffffffffffffffffffffffffffe000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c958a171dca1d4ed53e1af1d380803a9\nPlaintext: fffffffffffffffffffffffffffff000\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 21442e07a110667f2583eaeeee44dc8c\nPlaintext: fffffffffffffffffffffffffffff800\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 59bbb353cf1dd867a6e33737af655e99\nPlaintext: fffffffffffffffffffffffffffffc00\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 43cd3b25375d0ce41087ff9fe2829639\nPlaintext: fffffffffffffffffffffffffffffe00\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6b98b17e80d1118e3516bd768b285a84\nPlaintext: ffffffffffffffffffffffffffffff00\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ae47ed3676ca0c08deea02d95b81db58\nPlaintext: ffffffffffffffffffffffffffffff80\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 34ec40dc20413795ed53628ea748720b\nPlaintext: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4dc68163f8e9835473253542c8a65d46\nPlaintext: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2aabb999f43693175af65c6c612c46fb\nPlaintext: fffffffffffffffffffffffffffffff0\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e01f94499dac3547515c5b1d756f0f58\nPlaintext: fffffffffffffffffffffffffffffff8\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9d12435a46480ce00ea349f71799df9a\nPlaintext: fffffffffffffffffffffffffffffffc\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cef41d16d266bdfe46938ad7884cc0cf\nPlaintext: fffffffffffffffffffffffffffffffe\n\nCipher: AES-192-CBC\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b13db4da1f718bc6904797c82bcf2d32\nPlaintext: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen25 = 154338; +static const size_t kLen26 = 154338; -static const char *kData25[] = { +static const char *kData26[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-192-CTR -swap-iv-plaintext kat_aes/CBCGFSbox192.rsp kat_aes/CBCKeySbox192.rsp kat_aes/CBCVarKey192.rsp kat_aes/CBCVarTxt192.rsp\"\n\n# File 1: kat_aes/CBCGFSbox192.rsp\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 1b077a6af4b7f98229de786d7516b639\nCiphertext: 275cfc0413d8ccb70513c3859b1d0f72\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 9c2d8842e5f48f57648205d39a239af1\nCiphertext: c9b8135ff1b5adc413dfd053b21bd96d\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: bff52510095f518ecca60af4205444bb\nCiphertext: 4a3650c3371ce2eb35e389a171427440\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 51719783d3185a535bd75adc65071ce1\nCiphertext: 4f354592ff7c8847d2d0870ca9481b7c\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 26aa49dcfe7629a8901a69a9914e6dfd\nCiphertext: d5e08bf9a182e857cf40b3a36ee248cc\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 941a4773058224e1ef66d10e0a6ee782\nCiphertext: 067cd9d3749207791841562507fa9626\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 275cfc0413d8ccb70513c3859b1d0f72\nIV: 1b077a6af4b7f98229de786d7516b639\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c9b8135ff1b5adc413dfd053b21bd96d\nIV: 9c2d8842e5f48f57648205d39a239af1\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4a3650c3371ce2eb35e389a171427440\nIV: bff52510095f518ecca60af4205444bb\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4f354592ff7c8847d2d0870ca9481b7c\nIV: 51719783d3185a535bd75adc65071ce1\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d5e08bf9a182e857cf40b3a36ee248cc\nIV: 26aa49dcfe7629a8901a69a9914e6dfd\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 067cd9d3749207791841562507fa9626\nIV: 941a4773058224e1ef66d10e0a6ee782\n\n# File 2: kat_aes/CBCKeySbox192.rsp\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0956259c9cd5cfd0181cca53380cde06\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 15d20f6ebc7e649fd95b76b107e6daba967c8a9484797f29\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8e4e18424e591a3d5b6f0876f16f8594\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: a8a282ee31c03fae4f8e9b8930d5473c2ed695a347e88b7c\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 93f3270cfc877ef17e106ce938979cb0\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: cd62376d5ebb414917f0c78f05266433dc9192a1ec943300\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7f6c25ff41858561bb62f36492e93c29\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 502a6ab36984af268bf423c7f509205207fc1552af4a91e5\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8e06556dcbb00b809a025047cff2a940\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 25a39dbfd8034f71a81f9ceb55026e4037f8f6aa30ab44ce\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3608c344868e94555d23a120f8a5502d\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: e08c15411774ec4a908b64eadc6ac4199c7cd453f3aaef53\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 77da2021935b840b7f5dcc39132da9e5\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 3b375a1ff7e8d44409696e6326ec9dec86138e2ae010b980\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3b7c24f825e3bf9873c9f14d39a0e6f4\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 950bb9f22cc35be6fe79f52c320af93dec5bc9c0c2f9cd53\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 64ebf95686b353508c90ecd8b6134316\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 7001c487cc3e572cfc92f4d0e697d982e8856fdcc957da40\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ff558c5d27210b7929b73fc708eb4cf1\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: f029ce61d4e5a405b41ead0a883cc6a737da2cf50a6c92ae\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a2c3b2a818075490a7b4c14380f02702\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cfe4d74002696ccf7d87b14a2f9cafc9\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d2eafd86f63b109b91f5dbb3a3fb7e13\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9b9fdd1c5975655f539998b306a324af\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: d2926527e0aa9f37b45e2ec2ade5853ef807576104c7ace3\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: dd619e1cf204446112e0af2b9afa8f8c\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 982215f4e173dfa0fcffe5d3da41c4812c7bcc8ed3540f93\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d4f0aae13c8fe9339fbf9e69ed0ad74d\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 98c6b8e01e379fbd14e61af6af891596583565f2a27d59e9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 19c80ec4a6deb7e5ed1033dda933498f\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: b3ad5cea1dddc214ca969ac35f37dae1a9a9d1528f89bb35\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3cf5e1d21a17956d1dffad6a7c41c659\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 45899367c3132849763073c435a9288a766c8b9ec2308516\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 69fd12e8505f8ded2fdcb197a121b362\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ec250e04c3903f602647b85a401a1ae7ca2f02f67fa4253e\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8aa584e2cc4d17417a97cb9a28ba29c8\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: d077a03bd8a38973928ccafe4a9d2f455130bd0af5ae46a9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: abc786fb1edb504580c4d882ef29a0c7\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: d184c36cf0dddfec39e654195006022237871a47c33d3198\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2e19fb60a3e1de0166f483c97824a978\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 4c6994ffa9dcdc805b60c2c0095334c42d95a8fc0ca5b080\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7656709538dd5fec41e0ce6a0f8e207d\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: c88f5b00a4ef9a6840e2acaf33f00a3bdc4e25895303fa72\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a67cf333b314d411d3c0ae6e1cfcd8f5\n\nCipher", ": AES-192-CTR\nOperation: DECRYPT\nKey: e9f065d7c13573587f7875357dfbb16c53489f6a4bd0f7cd\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0956259c9cd5cfd0181cca53380cde06\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 15d20f6ebc7e649fd95b76b107e6daba967c8a9484797f29\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8e4e18424e591a3d5b6f0876f16f8594\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: a8a282ee31c03fae4f8e9b8930d5473c2ed695a347e88b7c\nPlaintext: 00000000000000000000000000000000\nCiphertext: 93f3270cfc877ef17e106ce938979cb0\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: cd62376d5ebb414917f0c78f05266433dc9192a1ec943300\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7f6c25ff41858561bb62f36492e93c29\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 502a6ab36984af268bf423c7f509205207fc1552af4a91e5\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8e06556dcbb00b809a025047cff2a940\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 25a39dbfd8034f71a81f9ceb55026e4037f8f6aa30ab44ce\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3608c344868e94555d23a120f8a5502d\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: e08c15411774ec4a908b64eadc6ac4199c7cd453f3aaef53\nPlaintext: 00000000000000000000000000000000\nCiphertext: 77da2021935b840b7f5dcc39132da9e5\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 3b375a1ff7e8d44409696e6326ec9dec86138e2ae010b980\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3b7c24f825e3bf9873c9f14d39a0e6f4\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 950bb9f22cc35be6fe79f52c320af93dec5bc9c0c2f9cd53\nPlaintext: 00000000000000000000000000000000\nCiphertext: 64ebf95686b353508c90ecd8b6134316\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 7001c487cc3e572cfc92f4d0e697d982e8856fdcc957da40\nPlaintext: 00000000000000000000000000000000\nCiphertext: ff558c5d27210b7929b73fc708eb4cf1\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: f029ce61d4e5a405b41ead0a883cc6a737da2cf50a6c92ae\nPlaintext: 00000000000000000000000000000000\nCiphertext: a2c3b2a818075490a7b4c14380f02702\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79\nPlaintext: 00000000000000000000000000000000\nCiphertext: cfe4d74002696ccf7d87b14a2f9cafc9\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570\nPlaintext: 00000000000000000000000000000000\nCiphertext: d2eafd86f63b109b91f5dbb3a3fb7e13\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9b9fdd1c5975655f539998b306a324af\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: d2926527e0aa9f37b45e2ec2ade5853ef807576104c7ace3\nPlaintext: 00000000000000000000000000000000\nCiphertext: dd619e1cf204446112e0af2b9afa8f8c\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 982215f4e173dfa0fcffe5d3da41c4812c7bcc8ed3540f93\nPlaintext: 00000000000000000000000000000000\nCiphertext: d4f0aae13c8fe9339fbf9e69ed0ad74d\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 98c6b8e01e379fbd14e61af6af891596583565f2a27d59e9\nPlaintext: 00000000000000000000000000000000\nCiphertext: 19c80ec4a6deb7e5ed1033dda933498f\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: b3ad5cea1dddc214ca969ac35f37dae1a9a9d1528f89bb35\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3cf5e1d21a17956d1dffad6a7c41c659\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 45899367c3132849763073c435a9288a766c8b9ec2308516\nPlaintext: 00000000000000000000000000000000\nCiphertext: 69fd12e8505f8ded2fdcb197a121b362\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: ec250e04c3903f602647b85a401a1ae7ca2f02f67fa4253e\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8aa584e2cc4d17417a97cb9a28ba29c8\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: d077a03bd8a38973928ccafe4a9d2f455130bd0af5ae46a9\nPlaintext: 00000000000000000000000000000000\nCiphertext: abc786fb1edb504580c4d882ef29a0c7\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: d184c36cf0dddfec39e654195006022237871a47c33d3198\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2e19fb60a3e1de0166f483c97824a978\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 4c6994ffa9dcdc805b60c2c0095334c42d95a8fc0ca5b080\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7656709538dd5fec41e0ce6a0f8e207d\nIV: 00000000000000000000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: c88f5b00a4ef9a6840e2acaf33f00a3bdc4e25895303fa72\nPlaintext: 00000000000000000000000000000000\nCiphertext: a67cf333b314d411d3c0ae6e1cfcd8f5\nIV: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey192.rsp\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: 800000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: de885dc87f5a92594082d02cc1e1b42c\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: c00000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 132b074e80f2a597bf5febd8ea5da55e\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: e00000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6eccedf8de592c22fb81347b79f2db1f\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: f00000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 180b09f267c45145db2f826c2582d35c\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: f80000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: edd807ef7652d7eb0e13c8b5e15b3bc0\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fc0000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9978bcf8dd8fd72241223ad24b31b8a4\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fe0000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5310f654343e8f27e12c83a48d24ff81\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ff0000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 833f71258d53036b02952c76c744f5a1\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ff8000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: eba83ff200cff9318a92f8691a06b09f\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffc000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ff620ccbe9f3292abdf2176b09f04eba\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffe000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7ababc4b3f516c9aafb35f4140b548f9\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fff000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: aa187824d9c4582b0916493ecbde8c57\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fff800000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1c0ad553177fd5ea1092c9d626a29dc4\n\nCipher: AES-192-CTR\nOp", "eration: ENCRYPT\nKey: fffc00000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a5dc46c37261194124ecaebd680408ec\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffe00000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e4f2f2ae23e9b10bacfa58601531ba54\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffff00000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b7d67cf1a1e91e8ff3a57a172c7bf412\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffff80000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 26706be06967884e847d137128ce47b3\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffc0000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b2f8b409b0585909aad3a7b5a219072a\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffe0000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5e4b7bff0290c78344c54a23b722cd20\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffff0000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 07093657552d4414227ce161e9ebf7dd\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffff8000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e1af1e7d8bc225ed4dffb771ecbb9e67\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffc000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ef6555253635d8432156cfd9c11b145a\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffe000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fb4035074a5d4260c90cbd6da6c3fceb\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffff000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 446ee416f9ad1c103eb0cc96751c88e1\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffff800000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 198ae2a4637ac0a7890a8fd1485445c9\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffc00000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 562012ec8faded0825fb2fa70ab30cbd\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffe00000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cc8a64b46b5d88bf7f247d4dbaf38f05\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffff00000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a168253762e2cc81b42d1e5001762699\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffff80000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1b41f83b38ce5032c6cd7af98cf62061\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffc0000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 61a89990cd1411750d5fb0dc988447d4\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffe0000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b5accc8ed629edf8c68a539183b1ea82\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffff0000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b16fa71f846b81a13f361c43a851f290\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffff8000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4fad6efdff5975aee7692234bcd54488\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffc000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ebfdb05a783d03082dfe5fdd80a00b17\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffe000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: eb81b584766997af6ba5529d3bdd8609\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffff000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0cf4ff4f49c8a0ca060c443499e29313\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffff800000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cc4ba8a8e029f8b26d8afff9df133bb6\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffc00000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fefebf64360f38e4e63558f0ffc550c3\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffe00000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 12ad98cbf725137d6a8108c2bed99322\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffff00000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6afaa996226198b3e2610413ce1b3f78\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffff80000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2a8ce6747a7e39367828e290848502d9\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffc0000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 223736e8b8f89ca1e37b6deab40facf1\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffe0000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c0f797e50418b95fa6013333917a9480\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffff0000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a758de37c2ece2a02c73c01fedc9a132\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffff8000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3a9b87ae77bae706803966c66c73adbd\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffffc000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d365ab8df8ffd782e358121a4a4fc541\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: fffffffffffe000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c8dcd9e6f75e6c36c8daee0466f0ed74\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffff000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: c79a637beb1c0304f14014c037e736dd\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffff800000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 105f0a25e84ac930d996281a5f954dd9\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffffc00000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 42e4074b2927973e8d17ffa92f7fe615\n\nCipher: AES-192-CTR\nOperation: ENCRYPT\nKey: ffffffffffffe00000000000000000", @@ -1472,9 +1533,9 @@ static const char *kData25[] = { "000000000000000000000000000000\nCiphertext: 0882a16f44088d42447a29ac090ec17e\nIV: fffffffffffffff00000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3a3c15bfc11a9537c130687004e136ee\nIV: fffffffffffffff80000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 22c0a7678dc6d8cf5c8a6d5a9960767c\nIV: fffffffffffffffc0000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b46b09809d68b9a456432a79bdc2e38c\nIV: fffffffffffffffe0000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 93baaffb35fbe739c17c6ac22eecf18f\nIV: ffffffffffffffff0000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c8aa80a7850675bc007c46df06b49868\nIV: ffffffffffffffff8000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 12c6f3877af421a918a84b775858021d\nIV: ffffffffffffffffc000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 33f123282c5d633924f7d5ba3f3cab11\nIV: ffffffffffffffffe000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a8f161002733e93ca4527d22c1a0c5bb\nIV: fffffffffffffffff000000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b72f70ebf3e3fda23f508eec76b42c02\nIV: fffffffffffffffff800000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6a9d965e6274143f25afdcfc88ffd77c\nIV: fffffffffffffffffc00000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a0c74fd0b9361764ce91c5200b095357\nIV: fffffffffffffffffe00000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 091d1fdc2bd2c346cd5046a8c6209146\nIV: ffffffffffffffffff00000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e2a37580116cfb71856254496ab0aca8\nIV: ffffffffffffffffff80000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e0b3a00785917c7efc9adba322813571\nIV: ffffffffffffffffffc0000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 733d41f4727b5ef0df4af4cf3cffa0cb\nIV: ffffffffffffffffffe0000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a99ebb030260826f981ad3e64490aa4f\nIV: fffffffffffffffffff0000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 73f34c7d3eae5e80082c1647524308ee\nIV: fffffffffffffffffff8000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 40ebd5ad082345b7a2097ccd3464da02\nIV: fffffffffffffffffffc000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7cc4ae9a424b2cec90c97153c2457ec5\nIV: fffffffffffffffffffe000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 54d632d03aba0bd0f91877ebdd4d09cb\nIV: ffffffffffffffffffff000000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d3427be7e4d27cd54f5fe37b03cf0897\nIV: ffffffffffffffffffff800000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b2099795e88cc158fd75ea133d7e7fbe\nIV: ffffffffffffffffffffc00000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a6cae46fb6fadfe7a2c302a34242817b\nIV: ffffffffffffffffffffe00000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 026a7024d6a902e0b3ffccbaa910cc3f\nIV: fffffffffffffffffffff00000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 156f07767a85a4312321f63968338a01\nIV: fffffffffffffffffffff80000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 15eec9ebf42b9ca76897d2cd6c5a12e2\nIV: fffffffffffffffffffffc0000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: db0d3a6fdcc13f915e2b302ceeb70fd8\nIV: fffffffffffffffffffffe0000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 71dbf37e87a2e34d15b20e8f10e48924\nIV: ffffffffffffffffffffff0000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c745c451e96ff3c045e4367c833e3b54\nIV: ffffffffffffffffffffff8000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 340da09c2dd11c3b679d08ccd27dd595\nIV: ffffffffffffffffffffffc000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8279f7c0c2a03ee660c6d392db025d18\nIV: ffffffffffffffffffffffe000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a4b2c7d8eba531ff47c5041a55fbd1ec\nIV: fffffffffffffffffffffff000000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 74569a2ca5a7bd5131ce8dc7cbfbf72f\nIV: fffffffffffffffffffffff800000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3713da0c0219b63454035613b5a403dd\nIV: fffffffffffffffffffffffc00000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8827551ddcc9df23fa72a3de4e9f0b07\nIV: fffffffffffffffffffffffe00000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2e3febfd625bfcd0a2c06eb460da1732\nIV: ffffffffffffffffffffffff00000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ee82e6ba4", "88156f76496311da6941deb\nIV: ffffffffffffffffffffffff80000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4770446f01d1f391256e85a1b30d89d3\nIV: ffffffffffffffffffffffffc0000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: af04b68f104f21ef2afb4767cf74143c\nIV: ffffffffffffffffffffffffe0000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cf3579a9ba38c8e43653173e14f3a4c6\nIV: fffffffffffffffffffffffff0000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b3bba904f4953e09b54800af2f62e7d4\nIV: fffffffffffffffffffffffff8000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fc4249656e14b29eb9c44829b4c59a46\nIV: fffffffffffffffffffffffffc000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9b31568febe81cfc2e65af1c86d1a308\nIV: fffffffffffffffffffffffffe000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9ca09c25f273a766db98a480ce8dfedc\nIV: ffffffffffffffffffffffffff000000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b909925786f34c3c92d971883c9fbedf\nIV: ffffffffffffffffffffffffff800000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 82647f1332fe570a9d4d92b2ee771d3b\nIV: ffffffffffffffffffffffffffc00000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3604a7e80832b3a99954bca6f5b9f501\nIV: ffffffffffffffffffffffffffe00000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 884607b128c5de3ab39a529a1ef51bef\nIV: fffffffffffffffffffffffffff00000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 670cfa093d1dbdb2317041404102435e\nIV: fffffffffffffffffffffffffff80000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7a867195f3ce8769cbd336502fbb5130\nIV: fffffffffffffffffffffffffffc0000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 52efcf64c72b2f7ca5b3c836b1078c15\nIV: fffffffffffffffffffffffffffe0000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4019250f6eefb2ac5ccbcae044e75c7e\nIV: ffffffffffffffffffffffffffff0000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 022c4f6f5a017d292785627667ddef24\nIV: ffffffffffffffffffffffffffff8000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e9c21078a2eb7e03250f71000fa9e3ed\nIV: ffffffffffffffffffffffffffffc000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a13eaeeb9cd391da4e2b09490b3e7fad\nIV: ffffffffffffffffffffffffffffe000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: c958a171dca1d4ed53e1af1d380803a9\nIV: fffffffffffffffffffffffffffff000\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 21442e07a110667f2583eaeeee44dc8c\nIV: fffffffffffffffffffffffffffff800\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 59bbb353cf1dd867a6e33737af655e99\nIV: fffffffffffffffffffffffffffffc00\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 43cd3b25375d0ce41087ff9fe2829639\nIV: fffffffffffffffffffffffffffffe00\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6b98b17e80d1118e3516bd768b285a84\nIV: ffffffffffffffffffffffffffffff00\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ae47ed3676ca0c08deea02d95b81db58\nIV: ffffffffffffffffffffffffffffff80\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 34ec40dc20413795ed53628ea748720b\nIV: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4dc68163f8e9835473253542c8a65d46\nIV: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2aabb999f43693175af65c6c612c46fb\nIV: fffffffffffffffffffffffffffffff0\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e01f94499dac3547515c5b1d756f0f58\nIV: fffffffffffffffffffffffffffffff8\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9d12435a46480ce00ea349f71799df9a\nIV: fffffffffffffffffffffffffffffffc\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cef41d16d266bdfe46938ad7884cc0cf\nIV: fffffffffffffffffffffffffffffffe\n\nCipher: AES-192-CTR\nOperation: DECRYPT\nKey: 000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b13db4da1f718bc6904797c82bcf2d32\nIV: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen26 = 191479; +static const size_t kLen27 = 191479; -static const char *kData26[] = { +static const char *kData27[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-256-CBC kat_aes/CBCGFSbox256.rsp kat_aes/CBCKeySbox256.rsp kat_aes/CBCVarKey256.rsp kat_aes/CBCVarTxt256.rsp\"\n\n# File 1: kat_aes/CBCGFSbox256.rsp\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 014730f80ac625fe84f026c60bfd547d\nCiphertext: 5c9d844ed46f9885085e5d6a4f94c7d7\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 0b24af36193ce4665f2825d7b4749c98\nCiphertext: a9ff75bd7cf6613d3731c77c3b6d0c04\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 761c1fe41a18acf20d241650611d90f1\nCiphertext: 623a52fcea5d443e48d9181ab32c7421\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 8a560769d605868ad80d819bdba03771\nCiphertext: 38f2c7ae10612415d27ca190d27da8b4\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 91fbef2d15a97816060bee1feaa49afe\nCiphertext: 1bc704f1bce135ceb810341b216d7abe\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5c9d844ed46f9885085e5d6a4f94c7d7\nPlaintext: 014730f80ac625fe84f026c60bfd547d\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a9ff75bd7cf6613d3731c77c3b6d0c04\nPlaintext: 0b24af36193ce4665f2825d7b4749c98\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 623a52fcea5d443e48d9181ab32c7421\nPlaintext: 761c1fe41a18acf20d241650611d90f1\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 38f2c7ae10612415d27ca190d27da8b4\nPlaintext: 8a560769d605868ad80d819bdba03771\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1bc704f1bce135ceb810341b216d7abe\nPlaintext: 91fbef2d15a97816060bee1feaa49afe\n\n# File 2: kat_aes/CBCKeySbox256.rsp\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 46f2fb342d6f0ab477476fc501242c5f\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 28d46cffa158533194214a91e712fc2b45b518076675affd910edeca5f41ac64\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4bf3b0a69aeb6657794f2901b1440ad4\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 352065272169abf9856843927d0674fd\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 984ca75f4ee8d706f46c2d98c0bf4a45f5b00d791c2dfeb191b5ed8e420fd627\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4307456a9e67813b452e15fa8fffe398\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: b43d08a447ac8609baadae4ff12918b9f68fc1653f1269222f123981ded7a92f\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4663446607354989477a5c6f0f007ef4\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 1d85a181b54cde51f0e098095b2962fdc93b51fe9b88602b3f54130bf76a5bd9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 531c2c38344578b84d50b3c917bbb6e1\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: dc0eba1f2232a7879ded34ed8428eeb8769b056bbaf8ad77cb65c3541430b4cf\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fc6aec906323480005c58e7e1ab004ad\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a3944b95ca0b52043584ef02151926a8\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a74289fe73a4c123ca189ea1e1b49ad5\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b91d4ea4488644b56cf0812fa7fcf5fc\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ccd1bc3c659cd3c59bc437484e3c5c724441da8d6e90ce556cd57d0752663bbc\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 304f81ab61a80c2e743b94d5002a126b\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 13428b5e4c005e0636dd338405d173ab135dec2a25c22c5df0722d69dcc43887\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 649a71545378c783e368c9ade7114f6c\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 07eb03a08d291d1b07408bf3512ab40c91097ac77461aad4bb859647f74f00ee\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 47cb030da2ab051dfc6c4bf6910d12bb\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 90143ae20cd78c5d8ebdd6cb9dc1762427a96c78c639bccc41a61424564eafe1\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 798c7c005dee432b2c8ea5dfa381ecc3\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: b7a5794d52737475d53d5a377200849be0260a67a2b22ced8bbef12882270d07\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 637c31dc2591a07636f646b72daabbe7\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fca02f3d5011cfc5c1e23165d413a049d4526a991827424d896fe3435e0bf68e\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 179a49c712154bbffbe6e7a84a18e220\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558\nIV: 00000000000000000000000000000000\nCiphertext: 46f2fb342d6f0ab477476fc501242c5f\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 28d46cffa158533194214a91e712fc2b45b518076675affd910edeca5f41ac64\nIV: 00000000000000000000000000000000\nCiphertext: 4bf3b0a69aeb6657794f2901b1440ad4\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c\nIV: 00000000000000000000000000000000\nCiphertext: 352065272169abf9856843927d0674fd\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 984ca75f4ee8d706f46c2d98c0bf4a45f5b00d791c2dfeb191b5ed8e420fd627\nIV: 00000000000000000000000000000000\nCiphertext: 4307456a9e67813b452e15fa8fffe398\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: b43d08a447ac8609baadae4ff12918b9f68fc1653f1269222f123981ded7a92f\nIV: 00000000000000000000000000000000\nCiphertext: 4663446607354989477a5c6f0f007ef4\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 1d85a181b54cde51f0e098095b2962fdc93b51fe9b88602b3f54130bf76a5bd9\nIV: 00000000000000000000000000000000\nCiphertext: 531c2c38344578b84d50b3c917bbb6e1\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: dc0eba1f2232a7879ded34ed8428eeb8769b056bbaf8ad77cb65c3541430b4cf\nIV: 00000000000000000000000000000000\nCiphertext: fc6aec906323480005c58e7e1ab004ad\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9\nIV: 00000000000000000000000000000000\nCiphertext:", " a3944b95ca0b52043584ef02151926a8\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e\nIV: 00000000000000000000000000000000\nCiphertext: a74289fe73a4c123ca189ea1e1b49ad5\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707\nIV: 00000000000000000000000000000000\nCiphertext: b91d4ea4488644b56cf0812fa7fcf5fc\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: ccd1bc3c659cd3c59bc437484e3c5c724441da8d6e90ce556cd57d0752663bbc\nIV: 00000000000000000000000000000000\nCiphertext: 304f81ab61a80c2e743b94d5002a126b\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 13428b5e4c005e0636dd338405d173ab135dec2a25c22c5df0722d69dcc43887\nIV: 00000000000000000000000000000000\nCiphertext: 649a71545378c783e368c9ade7114f6c\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 07eb03a08d291d1b07408bf3512ab40c91097ac77461aad4bb859647f74f00ee\nIV: 00000000000000000000000000000000\nCiphertext: 47cb030da2ab051dfc6c4bf6910d12bb\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 90143ae20cd78c5d8ebdd6cb9dc1762427a96c78c639bccc41a61424564eafe1\nIV: 00000000000000000000000000000000\nCiphertext: 798c7c005dee432b2c8ea5dfa381ecc3\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: b7a5794d52737475d53d5a377200849be0260a67a2b22ced8bbef12882270d07\nIV: 00000000000000000000000000000000\nCiphertext: 637c31dc2591a07636f646b72daabbe7\nPlaintext: 00000000000000000000000000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: fca02f3d5011cfc5c1e23165d413a049d4526a991827424d896fe3435e0bf68e\nIV: 00000000000000000000000000000000\nCiphertext: 179a49c712154bbffbe6e7a84a18e220\nPlaintext: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey256.rsp\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: 8000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e35a6dcb19b201a01ebcfa8aa22b5759\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: c000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b29169cdcf2d83e838125a12ee6aa400\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: e000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d8f3a72fc3cdf74dfaf6c3e6b97b2fa6\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: f000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1c777679d50037c79491a94da76a9a35\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: f800000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9cf4893ecafa0a0247a898e040691559\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fc00000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8fbb413703735326310a269bd3aa94b2\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fe00000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 60e32246bed2b0e859e55c1cc6b26502\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ff00000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ec52a212f80a09df6317021bc2a9819e\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ff80000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f23e5b600eb70dbccf6c0b1d9a68182c\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffc0000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a3f599d63a82a968c33fe26590745970\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffe0000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d1ccb9b1337002cbac42c520b5d67722\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fff0000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: cc111f6c37cf40a1159d00fb59fb0488\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fff8000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: dc43b51ab609052372989a26e9cdd714\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffc000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4dcede8da9e2578f39703d4433dc6459\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffe000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1a4c1c263bbccfafc11782894685e3a8\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffff000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 937ad84880db50613423d6d527a2823d\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffff800000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 610b71dfc688e150d8152c5b35ebc14d\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffc00000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 27ef2495dabf323885aab39c80f18d8b\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffe00000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 633cafea395bc03adae3a1e2068e4b4e\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffff00000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6e1b482b53761cf631819b749a6f3724\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffff80000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 976e6f851ab52c771998dbb2d71c75a9\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffc0000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 85f2ba84f8c307cf525e124c3e22e6cc\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffe0000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6bcca98bf6a835fa64955f72de4115fe\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffff0000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2c75e2d36eebd65411f14fd0eb1d2a06\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffff8000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: bd49295006250ffca5100b6007a0eade\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffc000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a190527d0ef7c70f459cd3940df316ec\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffe00", "0000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: bbd1097a62433f79449fa97d4ee80dbf\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffff000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 07058e408f5b99b0e0f061a1761b5b3b\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffff800000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5fd1f13fa0f31e37fabde328f894eac2\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffc00000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: fc4af7c948df26e2ef3e01c1ee5b8f6f\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffe00000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 829fd7208fb92d44a074a677ee9861ac\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffff00000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ad9fc613a703251b54c64a0e76431711\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffff80000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 33ac9eccc4cc75e2711618f80b1548e8\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffc0000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2025c74b8ad8f4cda17ee2049c4c902d\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffe0000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f85ca05fe528f1ce9b790166e8d551e7\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffff0000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6f6238d8966048d4967154e0dad5a6c9\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffff8000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f2b21b4e7640a9b3346de8b82fb41e49\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffc000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f836f251ad1d11d49dc344628b1884e1\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffe000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 077e9470ae7abea5a9769d49182628c3\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffff000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e0dcc2d27fc9865633f85223cf0d611f\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffff800000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: be66cfea2fecd6bf0ec7b4352c99bcaa\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffc00000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: df31144f87a2ef523facdcf21a427804\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffe00000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: b5bb0f5629fb6aae5e1839a3c3625d63\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffff00000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3c9db3335306fe1ec612bdbfae6b6028\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffff80000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3dd5c34634a79d3cfcc8339760e6f5f4\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffc0000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 82bda118a3ed7af314fa2ccc5c07b761\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffe0000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2937a64f7d4f46fe6fea3b349ec78e38\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffff0000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 225f068c28476605735ad671bb8f39f3\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffff8000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ae682c5ecd71898e08942ac9aa89875c\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffc000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5e031cb9d676c3022d7f26227e85c38f\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffe000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a78463fb064db5d52bb64bfef64f2dda\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffff000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8aa9b75e784593876c53a00eae5af52b\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffff800000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3f84566df23da48af692722fe980573a\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffffc00000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 31690b5ed41c7eb42a1e83270a7ff0e6\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffffe00000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 77dd7702646d55f08365e477d3590eda\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffff00000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4c022ac62b3cb78d739cc67b3e20bb7e\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffff80000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 092fa137ce18b5dfe7906f550bb13370\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffffc0000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3e0cdadf2e68353c0027672c97144dd3\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: ffffffffffffffe0000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: d8c4b200b383fc1f2b2ea677618a1d27\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffffff0000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 11825f99b0e9bb3477c1c0713b015aac\n\nCipher: AES-256-CBC\nOperation: ENCRYPT\nKey: fffffffffffffff8000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: f8b9fffb5c187f7ddc7", @@ -1500,9 +1561,9 @@ static const char *kData26[] = { "00000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4cc42fc1407b008fe350907c092e80ac\nPlaintext: ffffffffffffffffffff800000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 08b244ce7cbc8ee97fbba808cb146fda\nPlaintext: ffffffffffffffffffffc00000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 39b333e8694f21546ad1edd9d87ed95b\nPlaintext: ffffffffffffffffffffe00000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3b271f8ab2e6e4a20ba8090f43ba78f3\nPlaintext: fffffffffffffffffffff00000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9ad983f3bf651cd0393f0a73cccdea50\nPlaintext: fffffffffffffffffffff80000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8f476cbff75c1f725ce18e4bbcd19b32\nPlaintext: fffffffffffffffffffffc0000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 905b6267f1d6ab5320835a133f096f2a\nPlaintext: fffffffffffffffffffffe0000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 145b60d6d0193c23f4221848a892d61a\nPlaintext: ffffffffffffffffffffff0000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 55cfb3fb6d75cad0445bbc8dafa25b0f\nPlaintext: ffffffffffffffffffffff8000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7b8e7098e357ef71237d46d8b075b0f5\nPlaintext: ffffffffffffffffffffffc000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2bf27229901eb40f2df9d8398d1505ae\nPlaintext: ffffffffffffffffffffffe000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 83a63402a77f9ad5c1e931a931ecd706\nPlaintext: fffffffffffffffffffffff000000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6f8ba6521152d31f2bada1843e26b973\nPlaintext: fffffffffffffffffffffff800000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e5c3b8e30fd2d8e6239b17b44bd23bbd\nPlaintext: fffffffffffffffffffffffc00000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1ac1f7102c59933e8b2ddc3f14e94baa\nPlaintext: fffffffffffffffffffffffe00000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 21d9ba49f276b45f11af8fc71a088e3d\nPlaintext: ffffffffffffffffffffffff00000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 649f1cddc3792b4638635a392bc9bade\nPlaintext: ffffffffffffffffffffffff80000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e2775e4b59c1bc2e31a2078c11b5a08c\nPlaintext: ffffffffffffffffffffffffc0000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2be1fae5048a25582a679ca10905eb80\nPlaintext: ffffffffffffffffffffffffe0000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: da86f292c6f41ea34fb2068df75ecc29\nPlaintext: fffffffffffffffffffffffff0000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 220df19f85d69b1b562fa69a3c5beca5\nPlaintext: fffffffffffffffffffffffff8000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1f11d5d0355e0b556ccdb6c7f5083b4d\nPlaintext: fffffffffffffffffffffffffc000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 62526b78be79cb384633c91f83b4151b\nPlaintext: fffffffffffffffffffffffffe000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 90ddbcb950843592dd47bbef00fdc876\nPlaintext: ffffffffffffffffffffffffff000000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2fd0e41c5b8402277354a7391d2618e2\nPlaintext: ffffffffffffffffffffffffff800000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3cdf13e72dee4c581bafec70b85f9660\nPlaintext: ffffffffffffffffffffffffffc00000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: afa2ffc137577092e2b654fa199d2c43\nPlaintext: ffffffffffffffffffffffffffe00000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8d683ee63e60d208e343ce48dbc44cac\nPlaintext: fffffffffffffffffffffffffff00000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 705a4ef8ba2133729c20185c3d3a4763\nPlaintext: fffffffffffffffffffffffffff80000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0861a861c3db4e94194211b77ed761b9\nPlaintext: fffffffffffffffffffffffffffc0000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4b00c27e8b26da7eab9d3a88dec8b031\nPlaintext: fffffffffffffffffffffffffffe0000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5f397bf03084820cc8810d52e5b666e9\nPlaintext: ffffffffffffffffffffffffffff0000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 63fafabb72c07bfbd3ddc9b1203104b8\nPlaintext: ffffffffffffffffffffffffffff8000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 683e2140585b18452dd4ffbb93c95df9\nPlaintext: ffffffffffffffffffffffffffffc000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 286894e48e537f8763b56707d7d155c8\nPlaintext: ffffffffffffffffffffffffffffe000\n\nCiphe", "r: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a423deabc173dcf7e2c4c53e77d37cd1\nPlaintext: fffffffffffffffffffffffffffff000\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: eb8168313e1cfdfdb5e986d5429cf172\nPlaintext: fffffffffffffffffffffffffffff800\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 27127daafc9accd2fb334ec3eba52323\nPlaintext: fffffffffffffffffffffffffffffc00\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ee0715b96f72e3f7a22a5064fc592f4c\nPlaintext: fffffffffffffffffffffffffffffe00\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 29ee526770f2a11dcfa989d1ce88830f\nPlaintext: ffffffffffffffffffffffffffffff00\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0493370e054b09871130fe49af730a5a\nPlaintext: ffffffffffffffffffffffffffffff80\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9b7b940f6c509f9e44a4ee140448ee46\nPlaintext: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2915be4a1ecfdcbe3e023811a12bb6c7\nPlaintext: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7240e524bc51d8c4d440b1be55d1062c\nPlaintext: fffffffffffffffffffffffffffffff0\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: da63039d38cb4612b2dc36ba26684b93\nPlaintext: fffffffffffffffffffffffffffffff8\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 0f59cb5a4b522e2ac56c1a64f558ad9a\nPlaintext: fffffffffffffffffffffffffffffffc\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 7bfe9d876c6d63c1d035da8fe21c409d\nPlaintext: fffffffffffffffffffffffffffffffe\n\nCipher: AES-256-CBC\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: acdace8078a32b1a182bfa4987ca1347\nPlaintext: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen27 = 191498; +static const size_t kLen28 = 191498; -static const char *kData27[] = { +static const char *kData28[] = { "# Generated by \"make_cavp -cipher=aes -extra-labels=Cipher=AES-256-CTR -swap-iv-plaintext kat_aes/CBCGFSbox256.rsp kat_aes/CBCKeySbox256.rsp kat_aes/CBCVarKey256.rsp kat_aes/CBCVarTxt256.rsp\"\n\n# File 1: kat_aes/CBCGFSbox256.rsp\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 014730f80ac625fe84f026c60bfd547d\nCiphertext: 5c9d844ed46f9885085e5d6a4f94c7d7\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 0b24af36193ce4665f2825d7b4749c98\nCiphertext: a9ff75bd7cf6613d3731c77c3b6d0c04\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 761c1fe41a18acf20d241650611d90f1\nCiphertext: 623a52fcea5d443e48d9181ab32c7421\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 8a560769d605868ad80d819bdba03771\nCiphertext: 38f2c7ae10612415d27ca190d27da8b4\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 91fbef2d15a97816060bee1feaa49afe\nCiphertext: 1bc704f1bce135ceb810341b216d7abe\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5c9d844ed46f9885085e5d6a4f94c7d7\nIV: 014730f80ac625fe84f026c60bfd547d\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a9ff75bd7cf6613d3731c77c3b6d0c04\nIV: 0b24af36193ce4665f2825d7b4749c98\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 623a52fcea5d443e48d9181ab32c7421\nIV: 761c1fe41a18acf20d241650611d90f1\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 38f2c7ae10612415d27ca190d27da8b4\nIV: 8a560769d605868ad80d819bdba03771\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1bc704f1bce135ceb810341b216d7abe\nIV: 91fbef2d15a97816060bee1feaa49afe\n\n# File 2: kat_aes/CBCKeySbox256.rsp\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 46f2fb342d6f0ab477476fc501242c5f\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 28d46cffa158533194214a91e712fc2b45b518076675affd910edeca5f41ac64\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4bf3b0a69aeb6657794f2901b1440ad4\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 352065272169abf9856843927d0674fd\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 984ca75f4ee8d706f46c2d98c0bf4a45f5b00d791c2dfeb191b5ed8e420fd627\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4307456a9e67813b452e15fa8fffe398\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: b43d08a447ac8609baadae4ff12918b9f68fc1653f1269222f123981ded7a92f\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4663446607354989477a5c6f0f007ef4\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 1d85a181b54cde51f0e098095b2962fdc93b51fe9b88602b3f54130bf76a5bd9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 531c2c38344578b84d50b3c917bbb6e1\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: dc0eba1f2232a7879ded34ed8428eeb8769b056bbaf8ad77cb65c3541430b4cf\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fc6aec906323480005c58e7e1ab004ad\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a3944b95ca0b52043584ef02151926a8\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a74289fe73a4c123ca189ea1e1b49ad5\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b91d4ea4488644b56cf0812fa7fcf5fc\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ccd1bc3c659cd3c59bc437484e3c5c724441da8d6e90ce556cd57d0752663bbc\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 304f81ab61a80c2e743b94d5002a126b\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 13428b5e4c005e0636dd338405d173ab135dec2a25c22c5df0722d69dcc43887\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 649a71545378c783e368c9ade7114f6c\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 07eb03a08d291d1b07408bf3512ab40c91097ac77461aad4bb859647f74f00ee\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 47cb030da2ab051dfc6c4bf6910d12bb\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 90143ae20cd78c5d8ebdd6cb9dc1762427a96c78c639bccc41a61424564eafe1\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 798c7c005dee432b2c8ea5dfa381ecc3\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: b7a5794d52737475d53d5a377200849be0260a67a2b22ced8bbef12882270d07\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 637c31dc2591a07636f646b72daabbe7\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fca02f3d5011cfc5c1e23165d413a049d4526a991827424d896fe3435e0bf68e\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 179a49c712154bbffbe6e7a84a18e220\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: c47b0294dbbbee0fec4757f22ffeee3587ca4730c3d33b691df38bab076bc558\nPlaintext: 00000000000000000000000000000000\nCiphertext: 46f2fb342d6f0ab477476fc501242c5f\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 28d46cffa158533194214a91e712fc2b45b518076675affd910edeca5f41ac64\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4bf3b0a69aeb6657794f2901b1440ad4\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c\nPlaintext: 00000000000000000000000000000000\nCiphertext: 352065272169abf9856843927d0674fd\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 984ca75f4ee8d706f46c2d98c0bf4a45f5b00d791c2dfeb191b5ed8e420fd627\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4307456a9e67813b452e15fa8fffe398\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: b43d08a447ac8609baadae4ff12918b9f68fc1653f1269222f123981ded7a92f\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4663446607354989477a5c6f0f007ef4\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 1d85a181b54cde51f0e098095b2962fdc93b51fe9b88602b3f54130bf76a5bd9\nPlaintext: 00000000000000000000000000000000\nCiphertext: 531c2c38344578b84d50b3c917bbb6e1\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: dc0eba1f2232a7879ded34ed8428eeb8769b056bbaf8ad77cb65c3541430b4cf\nPlaintext: 00000000000000000000000000000000\nCiphertext: fc6aec906323480005c58e7e1ab004ad\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9\nPlaintext: 000000000000000000", "00000000000000\nCiphertext: a3944b95ca0b52043584ef02151926a8\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e\nPlaintext: 00000000000000000000000000000000\nCiphertext: a74289fe73a4c123ca189ea1e1b49ad5\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707\nPlaintext: 00000000000000000000000000000000\nCiphertext: b91d4ea4488644b56cf0812fa7fcf5fc\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: ccd1bc3c659cd3c59bc437484e3c5c724441da8d6e90ce556cd57d0752663bbc\nPlaintext: 00000000000000000000000000000000\nCiphertext: 304f81ab61a80c2e743b94d5002a126b\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 13428b5e4c005e0636dd338405d173ab135dec2a25c22c5df0722d69dcc43887\nPlaintext: 00000000000000000000000000000000\nCiphertext: 649a71545378c783e368c9ade7114f6c\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 07eb03a08d291d1b07408bf3512ab40c91097ac77461aad4bb859647f74f00ee\nPlaintext: 00000000000000000000000000000000\nCiphertext: 47cb030da2ab051dfc6c4bf6910d12bb\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 90143ae20cd78c5d8ebdd6cb9dc1762427a96c78c639bccc41a61424564eafe1\nPlaintext: 00000000000000000000000000000000\nCiphertext: 798c7c005dee432b2c8ea5dfa381ecc3\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: b7a5794d52737475d53d5a377200849be0260a67a2b22ced8bbef12882270d07\nPlaintext: 00000000000000000000000000000000\nCiphertext: 637c31dc2591a07636f646b72daabbe7\nIV: 00000000000000000000000000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: fca02f3d5011cfc5c1e23165d413a049d4526a991827424d896fe3435e0bf68e\nPlaintext: 00000000000000000000000000000000\nCiphertext: 179a49c712154bbffbe6e7a84a18e220\nIV: 00000000000000000000000000000000\n\n# File 3: kat_aes/CBCVarKey256.rsp\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: 8000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e35a6dcb19b201a01ebcfa8aa22b5759\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: c000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b29169cdcf2d83e838125a12ee6aa400\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: e000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d8f3a72fc3cdf74dfaf6c3e6b97b2fa6\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: f000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1c777679d50037c79491a94da76a9a35\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: f800000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 9cf4893ecafa0a0247a898e040691559\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fc00000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8fbb413703735326310a269bd3aa94b2\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fe00000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 60e32246bed2b0e859e55c1cc6b26502\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ff00000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ec52a212f80a09df6317021bc2a9819e\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ff80000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f23e5b600eb70dbccf6c0b1d9a68182c\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffc0000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a3f599d63a82a968c33fe26590745970\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffe0000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d1ccb9b1337002cbac42c520b5d67722\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fff0000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: cc111f6c37cf40a1159d00fb59fb0488\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fff8000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: dc43b51ab609052372989a26e9cdd714\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffc000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4dcede8da9e2578f39703d4433dc6459\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffe000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 1a4c1c263bbccfafc11782894685e3a8\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffff000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 937ad84880db50613423d6d527a2823d\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffff800000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 610b71dfc688e150d8152c5b35ebc14d\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffc00000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 27ef2495dabf323885aab39c80f18d8b\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffe00000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 633cafea395bc03adae3a1e2068e4b4e\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffff00000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6e1b482b53761cf631819b749a6f3724\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffff80000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 976e6f851ab52c771998dbb2d71c75a9\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffc0000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 85f2ba84f8c307cf525e124c3e22e6cc\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffe0000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6bcca98bf6a835fa64955f72de4115fe\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffff0000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2c75e2d36eebd65411f14fd0eb1d2a06\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffff8000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: bd49295006250ffca5100b6007a0eade\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffc000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a190527d0ef7c70f459cd3940df316ec\n\nCipher: AES-256-CTR\nOperation: ENC", "RYPT\nKey: ffffffe000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: bbd1097a62433f79449fa97d4ee80dbf\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffff000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 07058e408f5b99b0e0f061a1761b5b3b\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffff800000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5fd1f13fa0f31e37fabde328f894eac2\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffc00000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: fc4af7c948df26e2ef3e01c1ee5b8f6f\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffe00000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 829fd7208fb92d44a074a677ee9861ac\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffff00000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ad9fc613a703251b54c64a0e76431711\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffff80000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 33ac9eccc4cc75e2711618f80b1548e8\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffc0000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2025c74b8ad8f4cda17ee2049c4c902d\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffe0000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f85ca05fe528f1ce9b790166e8d551e7\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffff0000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 6f6238d8966048d4967154e0dad5a6c9\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffff8000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f2b21b4e7640a9b3346de8b82fb41e49\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffc000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: f836f251ad1d11d49dc344628b1884e1\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffe000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 077e9470ae7abea5a9769d49182628c3\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffff000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: e0dcc2d27fc9865633f85223cf0d611f\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffff800000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: be66cfea2fecd6bf0ec7b4352c99bcaa\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffc00000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: df31144f87a2ef523facdcf21a427804\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffe00000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: b5bb0f5629fb6aae5e1839a3c3625d63\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffff00000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3c9db3335306fe1ec612bdbfae6b6028\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffff80000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3dd5c34634a79d3cfcc8339760e6f5f4\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffc0000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 82bda118a3ed7af314fa2ccc5c07b761\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffe0000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 2937a64f7d4f46fe6fea3b349ec78e38\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffff0000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 225f068c28476605735ad671bb8f39f3\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffff8000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ae682c5ecd71898e08942ac9aa89875c\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffc000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 5e031cb9d676c3022d7f26227e85c38f\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffe000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: a78463fb064db5d52bb64bfef64f2dda\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffff000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 8aa9b75e784593876c53a00eae5af52b\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffff800000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3f84566df23da48af692722fe980573a\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffffc00000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 31690b5ed41c7eb42a1e83270a7ff0e6\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffffe00000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 77dd7702646d55f08365e477d3590eda\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffff00000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 4c022ac62b3cb78d739cc67b3e20bb7e\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffff80000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 092fa137ce18b5dfe7906f550bb13370\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffffc0000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 3e0cdadf2e68353c0027672c97144dd3\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: ffffffffffffffe0000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: d8c4b200b383fc1f2b2ea677618a1d27\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffffff0000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: 11825f99b0e9bb3477c1c0713b015aac\n\nCipher: AES-256-CTR\nOperation: ENCRYPT\nKey: fffffffffffffff8000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nIV: 00000000000000000000000000000000\nCiphertext: ", @@ -1528,9 +1589,9 @@ static const char *kData27[] = { "000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4cc42fc1407b008fe350907c092e80ac\nIV: ffffffffffffffffffff800000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 08b244ce7cbc8ee97fbba808cb146fda\nIV: ffffffffffffffffffffc00000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 39b333e8694f21546ad1edd9d87ed95b\nIV: ffffffffffffffffffffe00000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3b271f8ab2e6e4a20ba8090f43ba78f3\nIV: fffffffffffffffffffff00000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9ad983f3bf651cd0393f0a73cccdea50\nIV: fffffffffffffffffffff80000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8f476cbff75c1f725ce18e4bbcd19b32\nIV: fffffffffffffffffffffc0000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 905b6267f1d6ab5320835a133f096f2a\nIV: fffffffffffffffffffffe0000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 145b60d6d0193c23f4221848a892d61a\nIV: ffffffffffffffffffffff0000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 55cfb3fb6d75cad0445bbc8dafa25b0f\nIV: ffffffffffffffffffffff8000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7b8e7098e357ef71237d46d8b075b0f5\nIV: ffffffffffffffffffffffc000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2bf27229901eb40f2df9d8398d1505ae\nIV: ffffffffffffffffffffffe000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 83a63402a77f9ad5c1e931a931ecd706\nIV: fffffffffffffffffffffff000000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 6f8ba6521152d31f2bada1843e26b973\nIV: fffffffffffffffffffffff800000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e5c3b8e30fd2d8e6239b17b44bd23bbd\nIV: fffffffffffffffffffffffc00000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1ac1f7102c59933e8b2ddc3f14e94baa\nIV: fffffffffffffffffffffffe00000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 21d9ba49f276b45f11af8fc71a088e3d\nIV: ffffffffffffffffffffffff00000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 649f1cddc3792b4638635a392bc9bade\nIV: ffffffffffffffffffffffff80000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: e2775e4b59c1bc2e31a2078c11b5a08c\nIV: ffffffffffffffffffffffffc0000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2be1fae5048a25582a679ca10905eb80\nIV: ffffffffffffffffffffffffe0000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: da86f292c6f41ea34fb2068df75ecc29\nIV: fffffffffffffffffffffffff0000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 220df19f85d69b1b562fa69a3c5beca5\nIV: fffffffffffffffffffffffff8000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 1f11d5d0355e0b556ccdb6c7f5083b4d\nIV: fffffffffffffffffffffffffc000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 62526b78be79cb384633c91f83b4151b\nIV: fffffffffffffffffffffffffe000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 90ddbcb950843592dd47bbef00fdc876\nIV: ffffffffffffffffffffffffff000000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2fd0e41c5b8402277354a7391d2618e2\nIV: ffffffffffffffffffffffffff800000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 3cdf13e72dee4c581bafec70b85f9660\nIV: ffffffffffffffffffffffffffc00000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: afa2ffc137577092e2b654fa199d2c43\nIV: ffffffffffffffffffffffffffe00000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 8d683ee63e60d208e343ce48dbc44cac\nIV: fffffffffffffffffffffffffff00000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 705a4ef8ba2133729c20185c3d3a4763\nIV: fffffffffffffffffffffffffff80000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0861a861c3db4e94194211b77ed761b9\nIV: fffffffffffffffffffffffffffc0000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 4b00c27e8b26da7eab9d3a88dec8b031\nIV: fffffffffffffffffffffffffffe0000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 5f397bf03084820cc8810d52e5b666e9\nIV: ffffffffffffffffffffffffffff0000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 63fafabb72c07bfbd3ddc9b1203104b8\nIV: ffffffffffffffffffffffffffff8000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 683e2140585b18452dd4ffbb93c95df9\nIV: ffffffffffffffffffffffffffffc000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 286894e48e537f8763b56707d7d155c8\nIV: ffffffffffffffffffff", "ffffffffe000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: a423deabc173dcf7e2c4c53e77d37cd1\nIV: fffffffffffffffffffffffffffff000\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: eb8168313e1cfdfdb5e986d5429cf172\nIV: fffffffffffffffffffffffffffff800\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 27127daafc9accd2fb334ec3eba52323\nIV: fffffffffffffffffffffffffffffc00\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: ee0715b96f72e3f7a22a5064fc592f4c\nIV: fffffffffffffffffffffffffffffe00\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 29ee526770f2a11dcfa989d1ce88830f\nIV: ffffffffffffffffffffffffffffff00\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0493370e054b09871130fe49af730a5a\nIV: ffffffffffffffffffffffffffffff80\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 9b7b940f6c509f9e44a4ee140448ee46\nIV: ffffffffffffffffffffffffffffffc0\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 2915be4a1ecfdcbe3e023811a12bb6c7\nIV: ffffffffffffffffffffffffffffffe0\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7240e524bc51d8c4d440b1be55d1062c\nIV: fffffffffffffffffffffffffffffff0\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: da63039d38cb4612b2dc36ba26684b93\nIV: fffffffffffffffffffffffffffffff8\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 0f59cb5a4b522e2ac56c1a64f558ad9a\nIV: fffffffffffffffffffffffffffffffc\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: 7bfe9d876c6d63c1d035da8fe21c409d\nIV: fffffffffffffffffffffffffffffffe\n\nCipher: AES-256-CTR\nOperation: DECRYPT\nKey: 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext: 00000000000000000000000000000000\nCiphertext: acdace8078a32b1a182bfa4987ca1347\nIV: ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen28 = 5825374; +static const size_t kLen29 = 5825374; -static const char *kData28[] = { +static const char *kData29[] = { "# Generated by \"make_cavp -cipher gcm kat_gcm/gcmDecrypt256.rsp kat_gcm/gcmEncryptExtIV256.rsp\"\n\n# File 1: kat_gcm/gcmDecrypt256.rsp\n\nKEY: f5a2b27c74355872eb3ef6c5feafaa740e6ae990d9d48c3bd9bb8235e589f010\nNONCE: 58d2240f580a31c1d24948e9\nCT: \nAD: \nTAG: 15e051a5e4a5f5da6cea92e2ebee5bac\nIN: \n\nKEY: e5a8123f2e2e007d4e379ba114a2fb66e6613f57c72d4e4f024964053028a831\nNONCE: 51e43385bf533e168427e1ad\nCT: \nAD: \nTAG: 38fe845c66e66bdd884c2aecafd280e6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: c5ba3bf9ada560fb0301cd4e0b8b8a46a2aff2400395a72ed5804b3c755c4e59\nNONCE: de2b956e704063c000f28bbb\nCT: \nAD: \nTAG: 04eb9b20fd4548dc71594f20073a45a2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: c1d6162b585e2bac14d554d5675c6ddaa6b93be2eb07f8df86c9bb30f93ae688\nNONCE: f04dfce5c8e7713c71a70cc9\nCT: \nAD: \nTAG: 37fb4f33c82f6fce0c562896b3e10fc2\nIN: \n\nKEY: 70458edea4d95c8b3e069f14e1ad71d9186f482fe6d85088c71db58267e747ec\nNONCE: d6413ee8453a1729a658c6f4\nCT: \nAD: \nTAG: bd9e5e0c6ddc94acf65bf4e301d20a37\nIN: \n\nKEY: aa0bedc56b30418235aa94327062c34e0ddbf931e7bcb964b60678d411baf6cb\nNONCE: 8a7220c9a7e417e5da182bdb\nCT: \nAD: \nTAG: ae7e608491439940b4d1046c28361258\nIN: \n\nKEY: c11ce73ba45d5e33be3efd335c4d67d659284b3a824ae35d5982e9ea4c68145d\nNONCE: 1eeffdbab0745a757789018f\nCT: \nAD: \nTAG: d387f9e6bbbbf273746c9b5276a8618c\nIN: \n\nKEY: 639664a00278e45d18cd4ac1265a4fea39d1cd8d7907a0adb38723209c46a4bf\nNONCE: d838ba74c7ad57ee5266c5b7\nCT: \nAD: \nTAG: 3750f87de43cfa02ef882d6497da082d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: dc18f40a774ceeb930f0bb45070404783c66988a515db1a36ec0cc0d70fac2fd\nNONCE: 9c3a7dd947e6f50a6577c5ff\nCT: \nAD: \nTAG: 511924f2603d6d38920539fb10178989\nIN: \n\nKEY: 39aed23722e201752d2e53efe66c8f0f695658a63a9a8cecf4e25f02dd7da1d5\nNONCE: ce0108bc35e7ff7ba8408f3f\nCT: \nAD: \nTAG: 66acc084d5f62e639338131f5ab8f6c1\nIN: \n\nKEY: c5c19e080bbbce795754ae25e36dc7aea1589d823fe89835d0286e54de7f3153\nNONCE: 3109398abd423349b9b50adc\nCT: \nAD: \nTAG: 73c92b76997dbd9fe251436a7f61a666\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 831640f910ef709eb0ec3998ea5aa55470082de05ee20ed8b19f067d8af1308e\nNONCE: 443dcee827eb4cc49fe2b287\nCT: \nAD: \nTAG: 005ec26c2d708d5234b7937313dc7384\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 56567431c5210979a8dbb432966a81b3f1db5ec021f8aae0f0c3cce3678cc6fd\nNONCE: 45a97d48000ce1dab68de02e\nCT: \nAD: \nTAG: bbb295fd1e37c317f8130221af50496b\nIN: \n\nKEY: fdf71650d60cb7aa566cdd7ba66f462ed613a1c6c1dfdab0ba8e676fb7a8b935\nNONCE: a035553c5a9b88a67627dbcc\nCT: \nAD: \nTAG: 4a7361a05757e2cb60cc17ff8c5911b7\nIN: \n\nKEY: 3b19d8a4795b52e6dc4f8fd3c091c05a65c8f3cddc665ab473e6144011ae54a4\nNONCE: 23744265b6865b99bed99f11\nCT: \nAD: \nTAG: b7a67b6068d2b22c1b26f795ee1701be\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 31201b86ccb6cbcf289798225c55de5a1c936a18aec996b5b8dcceb33bf96b41\nNONCE: c2c6402f1f5ae89a6fa0fb65\nCT: \nAD: \nTAG: 0b0bebb86a5d60f1f1881cea155e33\nIN: \n\nKEY: 2878cdd980bd1289e2efef7f3116b0a2772d272412e1cfeaf20f90cc278820e9\nNONCE: 9ada69a2f393958cc3866bf9\nCT: \nAD: \nTAG: cff55846db838aaf5e08e88f8d7fe2\nIN: \n\nKEY: 1ee02b8c391d6559ceb1683221821e377d20fb186733d24d2becb73e4121e92b\nNONCE: 70181ecf28be85c68f4dbe86\nCT: \nAD: \nTAG: b90acb4d41e2df4c148d8837ca712b\nIN: \n\nKEY: e8cd41c3d9ee7dca4c5d66753384cd1a034f729595fbeb00042874fe704fe4a8\nNONCE: cab88d202761537e288dcd47\nCT: \nAD: \nTAG: 954296ab400209335f424eb22636a5\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 56fec15de81f78182f3f4d9cda32c3d7744568ab6e2285c7c3384bd17f0a4e22\nNONCE: 71e09145955273fd889cefda\nCT: \nAD: \nTAG: 3b2191283125d17f1f41558279630f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: f66d1d2bd210d75c555b856c5c61d9c09b035498a9896284c34d9312e35b1065\nNONCE: 10dda1bf8ebca4b0a1f3396d\nCT: \nAD: \nTAG: 6da9c30516fe1d60355a01211669dd\nIN: \n\nKEY: 421ad8416b0558e225e9e3de2ec1c7fc0ea5a3378291dfd4c43f85fb3fa63d59\nNONCE: 23a84ef01256fa90a44e502b\nCT: \nAD: \nTAG: 237b556e56c27f03ff2e893d46dc14\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5a848b232b428015fc1a86134774558bdb3180f8b853bc32be40b6e4f098a857\nNONCE: cc87b1468b8ee9a5a4e1d7e1\nCT: \nAD: \nTAG: 329be89d4cd62d3d3a755d0989f3e7\nIN: \n\nKEY: 9a865aa04969fe50bcb48b90d75ce72f1ced9337ef81acec5a633eac7544f86d\nNONCE: cf4962b18e6b8f6f4146a0e7\nCT: \nAD: \nTAG: da7e4d68f4f77271537786350f8fcc\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e106e692ae0285dad853a3232e150c1ccc602d74bf3bd91e0ffa36c33855d152\nNONCE: c4fe31cf2f36bf29080e6317\nCT: \nAD: \nTAG: 2523855a9d0bf9db28c39142aabb76\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: cfae5da8cabe9bd774713bc5b6c5a3ae42a872154636b6f976ee51e6a197a949\nNONCE: 033a03e2d701d1aafea3c399\nCT: \nAD: \nTAG: bb94014b3268e39eb71a2e3f5e65b2\nIN: \n\nKEY: 267b7087ad528cb9564c909b4fd8f9a80787ac2f85f23d10be6d0b2bfa043c09\nNONCE: cf8e3f28b1af597a76d0f538\nCT: \nAD: \nTAG: acec8a91da886b56075e5661fd5281\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 174162718b2e85482533322741309a4d3100c77e4178cd936b9881ab868b9bf9\nNONCE: 6a4abe063efd24fc960c56cb\nCT: \nAD: \nTAG: 1dc929a76cc0f4e28e65367e29002b\nIN: \n\nKEY: badd602c95d173fcb1334a32cd1437fbbfc21813bbefa8457b543a6f05c7ca80\nNONCE: c28a85678f63fd46edf03810\nCT: \nAD: \nTAG: 94f4cc2fb26c2d487b20b01441574f\nIN: \n\nKEY: 8ff59e7c71865c94b637a924132e5519137da18573ee797c981dfd41c70538e7\nNONCE: 80b277f8789d5f1165924d21\nCT: \nAD: \nTAG: fc1bd57ced8be952b9ff6017502ff6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 799c0a95a15bbe3915cd55ff2af71a437247c74092819c8f398f820b5829b4de\nNONCE: 53be11fdaa1cef09b7cbbdf7\nCT: \nAD: \nTAG: e81916926bbd1cf8d0378467dd99\nIN: \n\nKEY: d24580e7584b7fce9bce2e6a0d1d3bab184ac25171e57c9d67db832325202a96\nNONCE: 2d40c5487ea483e543238c93\nCT: \nAD: \nTAG: ed989ab0f70be34acf71f6ac6a00\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a8b15b30aa3f69190611031906cc125c98289fed2836f99b29e1d38b2c32c8ed\nNONCE: 317a4522cc374f32458142e2\nCT: \nAD: \nTAG: 4d421b1e0551f632b80f14cc433e\nIN: \n\nKEY: 8f85436046b48589390986646a5ed0e1587d431d1d10ec66d490f38c60ae9182\nNONCE: 6bbe054c533f5d659f5442fd\nCT: \nAD: \nTAG: edf25381a757cf747676fea43772\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9254c8375c3fe74b35a125a8e9f5109cf880f13ad03b7ff35ac0255efbc51a5d\nNONCE: 912705e60880ea3b9554dd69\nCT: \nAD: \nTAG: a5c899aea5e9483d9506682b6a66\nIN: \n\nKEY: 3a3908ae84d595b377fa7325374a7cf8ab6b70e62d21b8b5be75ae2e31334481\nNONCE: ec3ec0cec10bcbd3f2ea0002\nCT: \nAD: \nTAG: c122ee4d6df5f23f1e48732516e7\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 57eb6a05eb054b404f2d87623fe1340b052d20597e9331ef90ad684d4f660202\nNONCE: ee2468096c2befc44e16d351\nCT: \nAD: \nTAG: 0894132b1594df56b6114419cd4c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8704fce138b35ccf644ed70285300df5a7ddb19c3a1e244b6c6764c565812fc6\nNONCE: 8acfc17f01e8200da86009c1\nCT: \nAD: \nTAG: 914a956e661b064f91cfe779bf14\nIN: \n\nKEY: 6bdf1a1a465dc9777147de2f73527f193883ea5241d5cd209939290d73a3e149\nNONCE: c9e36c568487a78cf85269d6\nCT: \nAD: \nTAG: 34fbc5a0c2bb9bf937c4316838da\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 4da9edd0d5f7fe42bd0ff2d6342c9588625bf24ed3e3f5c1a456f2915ead961a\nNONCE: 3f1ece70c54dcc320de79733\nCT: \nAD: \nTAG: 083510a941749021d64ba5ec59d4\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 7a83b53a0b11f4477f673cad123ea5548903759e9d5d856235c59ff3af1caa8d\nNONCE: 7c3f82f7bf425398742916fc\nCT: \nAD: \nTAG: 7de106e354fe15c5111cb127335f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 4f17984fd466eede268b8ef75629cc7bac53b2dfcaf326700ac1a9841ea580fe\nNONCE: 2a9d7d283c33c953ed0fb90a\nCT: \nAD: \nTAG: 9befbbe25a1f2d7e8eb39689f39b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d7a5f32bc7ba818b26fdc03fc1a4de7d8837bcebc023b36591284a0973fde527\nNONCE: d590b0a69cea63c8c3293f2c\nCT: \nAD: \nTAG: 1080033d9a947bb879b1df5576c3\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 270b3ca4321ba7346226c89868483a6e6e679cd896f8e9d52cea9000e1939746\nNONCE: 3f29410035eeb93d03a7b2d1\nCT: \nAD: \nTAG: 7529cd4204b9a8e149034907e829\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 0bf97de28518991a5043c1b6d56d2ef87d38d195d47984fc1ccbfcb7f3860908\nNONCE: 1d76c092d2dd79a62b970403\nCT: \nAD: \nTAG: e63432142ef64756c38d693fd8fe\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 585daad086f48a3dffd89e3712f1f8033e8b168c107ddc7f3454690decc132d5\nNONCE: e2f2a83f6aaec072d8268cee\nCT: \nAD: \nTAG: d400ebadcef9ce147a3b00ea39\nIN: \n\nKEY: 42de0aed7e4b699546d351af85db208d79273393bde6318e33232850c65457e7\nNONCE: 82bd822d011e38319a76dfe2\nCT: \nAD: \nTAG: e262760567ca2ca6cbb3fa5703\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 00ae365607def9dd57d4f38f131ea9659abdd96eae6c52179b16796cf1ee53a0\nNONCE: 56d2485bb17cd4a6791ebd07\nCT: \nAD: \nTAG: 8460e8e8fbb4c8212c96fee330\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 27271e1fa38fadaae145b7fdb15c357c95cf7cbe77961561b59b0ad27df57b5b\nNONCE: 22fb1457c21627e8ddf5017c\nCT: \nAD: \nTAG: 0b6b620e9f5d1ba6e886d71e75\nIN: \n\nKEY: eb9fd8b60a524219cf09805e6aabf65ebb1730fe3b1ef0d91adf054", "44088d665\nNONCE: f8745cf1171199ee02607d59\nCT: \nAD: \nTAG: 65866a3b4455bd3ee58a88d7c3\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: cc72d5bdb02986acecd74dfcf20d880ae5bc14afd26db1b9f04fe08b85a4bf6e\nNONCE: b2d26145ed1be0cf782ea5fd\nCT: \nAD: \nTAG: 101f1e5c96748958462434cdd5\nIN: \n\nKEY: 4ac59235d7350ddad294fa9e0ea8e246a7c9f10689d2b0bd9e0145ecebf89885\nNONCE: cef0563a1797cc62589af02b\nCT: \nAD: \nTAG: a5299a6eaaf9b3ad82bd23b340\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 30fc4f8d634f404d1a66791d7c745d841c635320b7a1b28fbd26f3154b952d19\nNONCE: e7addadf0740e62ee32dd111\nCT: \nAD: \nTAG: 4c9a4fdecf2af9a609b67b6564\nIN: \n\nKEY: 3896ca84611b23bda4af5cc9fe0d62cf093019f1192a2c27cd7d2c1320102998\nNONCE: 0cc3ae5b56f3db71e2195e6e\nCT: \nAD: \nTAG: 0413fefe638d6613ad15ff5422\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9d4cfc649a6c146c20b17e44af835c42cafe4c8e1ebcba092c22d77fdb0a5478\nNONCE: a27cce894b2dc42f1754aae0\nCT: \nAD: \nTAG: b1259f4cae8c4708fd46e60c26\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: e7ad81d26e5a639b7e99d3b205ddb6a09598ac804b5913ee8b8e724e5b69d003\nNONCE: 08fc7f46f6f600feecefc008\nCT: \nAD: \nTAG: e51e2ed634294d73942a9aafd8\nIN: \n\nKEY: d9288c7e44440398e9c5b6156615bb0d63064cbcee22cee46e710cdf6753e2cf\nNONCE: dc37870991b27ae42dfd6c33\nCT: \nAD: \nTAG: 5408193318902ae3e92b4b6eca\nIN: \n\nKEY: 3e7c2c5dd3c9e092e45d0ee9eaa2f8c2714cf845f50be787cb6a3e65726a7a56\nNONCE: 0e39d519e9d6db4dc462f2ec\nCT: \nAD: \nTAG: bbf6cd3c840ba5347b281ccd99\nIN: \n\nKEY: 29ae533689bc22ea72580a42260b71128504ff55f4025f455fe656a7cd534c08\nNONCE: fd0a67e9cdea915eb367e069\nCT: \nAD: \nTAG: 6421e4d996407496e09231a96e\nIN: \n\nKEY: 7930342c63e26215a80eaa824ec382d452c6d71f81a7ac2667b1baf1b139cee8\nNONCE: 920cf0199c32cdcf419971ad\nCT: \nAD: \nTAG: 866e974b681af38f0a98074ec1\nIN: \n\nKEY: 96ad13bf2492f4675340e65b455bd0b884574f5b6c4fea774462496b8a0925ad\nNONCE: 2ddf6aa50c2ea9106ce0a951\nCT: \nAD: \nTAG: 10a471540cc7bae14273f2e2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: b1599e78f21b175a3038aacde9141f7198c301ff80276020c1974342baad1e55\nNONCE: abdd25c66d7821fde6ec0b76\nCT: \nAD: \nTAG: ab077a703bfb6646d5aef26b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 7c487e31244dcbf84ee6e7c03714302aa3e52ae1282f8de72c44d3777e73593c\nNONCE: 297e056784c12646ed2fa6c7\nCT: \nAD: \nTAG: 08c53ea6cc85662f0d9bb018\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: d9304fc27885ac2ac5cf871e9c5758ad66babbc50b26d1c3e32d00ebb4273525\nNONCE: c73d0831e8e23cec9ac4143c\nCT: \nAD: \nTAG: 2f19c7a022909777853ccd5a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9f6fed7d59ef1650244ee0966f647179968edb74f5d9b4ea412300979d2c9d9d\nNONCE: c0d8eafd572e76402bf2421b\nCT: \nAD: \nTAG: 157519d699f8f19b6ed0a4c9\nIN: \n\nKEY: 72eb01f911a998bd534b696b0ce99cbbe7788f1d5f3f1c07f5286daef7007ad0\nNONCE: 6930e168edf7be096aa92f77\nCT: \nAD: \nTAG: 8229b618c52079abd2d8cf96\nIN: \n\nKEY: e625dc4d57da4975c5e2bbdc3be61716c910975848f2a06a8a375c12ceff702a\nNONCE: 44925a2c8f2eaa0d02d33047\nCT: \nAD: \nTAG: 9a0f456312dce97e23d4af58\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 648914e5322383a1984b84726deeead89dd19c60556622d61ce649ba74b152b5\nNONCE: 8a070725978278d7e3e6fae4\nCT: \nAD: \nTAG: 40819c4375be0ec64543f5c2\nIN: \n\nKEY: b0a2fc05e05eb23b03f6fd073d1502fa071cfdde6e4a57f344d3b46587d44667\nNONCE: 6b05139925fca211928767ab\nCT: \nAD: \nTAG: b927b087690a7d2fdc5da1d7\nIN: \n\nKEY: 9a56a45297bf12c63db8207118c3570f05eebcc31a87ad20ac85fad9a9cfcbce\nNONCE: 2108bf02ae1b9191e5f20e06\nCT: \nAD: \nTAG: c1a03eeb46a080507fb39e33\nIN: \n\nKEY: 98f9da937717a7698eda75b5671ea209dde1b37506d2a5874b9ec57805310e73\nNONCE: 4db9d0d9cb66a80565af6c84\nCT: \nAD: \nTAG: eeef79af87fe6bc0d0476d16\nIN: \n\nKEY: b5c699b548cd0839a24eec8aee1b0a5bc42de0bec78aacaa9b18b666986891b4\nNONCE: 87e21a74da97bc02d7f9e0cc\nCT: \nAD: \nTAG: c4a584270a5b0bfe0ac979bb\nIN: \n\nKEY: cd3adadded7c7ae047ae38c93a73d029fdf4e12a8a0c2fbc6c5f354fe07b0fa9\nNONCE: acf47c06e93b5d042c8444b9\nCT: \nAD: \nTAG: f1391598e2172300fb5279dc\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: cf90a8f6731d71abaaa354076c69812a96145b4d283369b0c519ce1818c85cff\nNONCE: 718b1b2d8979f54e357bce92\nCT: \nAD: \nTAG: ea7dc6b16c9a870a560facbc\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 849ee5f331af0bbb2366033ca07c29fe8ec64b2e18f8d2af91d88c08b958763c\nNONCE: 23b34d13fa0e2c954e0a5974\nCT: \nAD: \nTAG: c4a18f7724ca968055aa0d8a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: caed02e544e9eb475360e9b3e4b6e7572605081790ec54ea39ab9bc67932e0fd\nNONCE: d2ffaa7f0b6c3c708238a1b0\nCT: \nAD: \nTAG: eb053ee206ab47cc\nIN: \n\nKEY: ddd2cc50ed30a394387adcef5dcfdb7405082d62b3a513902977301f22ccf851\nNONCE: 4dc0d75a392e1b1cd2e5b6d6\nCT: \nAD: \nTAG: 11e713078f660a45\nIN: \n\nKEY: ae166cba7907a50a2faeb8a1f835e0a21b6074f403d2fbf265ca8525663865c5\nNONCE: d70ea09bd1dc20d47625a7ce\nCT: \nAD: \nTAG: 8a0138d6b06dbee0\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 119c935ac47a3d2e2bbc2fe753c34727ea28e96c288a8b46a0c884066a85edc5\nNONCE: e04c72c0dfec84d52bcda87d\nCT: \nAD: \nTAG: 5ca9d3a5b75b519a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 166ebf390a9aa54e3c525b06497adcdc9b394ba25e65731c0004e9ff9793e0e5\nNONCE: 7e8e61d97c17a303510d581c\nCT: \nAD: \nTAG: 7c2a0b411cc8f2f5\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 7f3c7d35e06b60a0e948212da1170467a54b88a488e7edf4b7fbf9d03f645d4f\nNONCE: 3b21437bd320ffc3f90f835c\nCT: \nAD: \nTAG: 7e18457fe81b2302\nIN: \n\nKEY: 37875cda07364dae174c1b422e0daa8b949b6478332988504ef3f633d58df4ca\nNONCE: 746e59be002990d169b4a783\nCT: \nAD: \nTAG: 81be9ff1ddfb32bc\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 6e1eec50f2eb68da620a913a2a0d2250ad0541f3acf88fed2f890f840c0046ad\nNONCE: a75bf504651adadd31743464\nCT: \nAD: \nTAG: 49d75b1504d39ebb\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2864eb7a7025da05ea9ed75f07baf26d90b8eb93f2c57dec6dcc87e650f48f54\nNONCE: 98b764326898d43e443f441b\nCT: \nAD: \nTAG: 1996834986570afe\nIN: \n\nKEY: 8ef06b7a47655a6248c782291476d983d43e17cf419852868d488d2a6093f750\nNONCE: 40c3ceb10e9dddfe23569244\nCT: \nAD: \nTAG: ce828e8aa6056b7f\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 30ec395340ba1d05b9964dc932750e6bcfb3acabd1c07656ca3654128893d77c\nNONCE: 69d240b1d240c0c71cf10966\nCT: \nAD: \nTAG: 18b112b18cd0bd86\nIN: \n\nKEY: 18efa6f3395d20ddbd483924fabdbe105d70e69f4652b929207d9746b098ee11\nNONCE: 4f166cb3acc43383ec9b2bfd\nCT: \nAD: \nTAG: 4b34f4c59236dcbf\nIN: \n\nKEY: 540407922c1056e6e0df4c9a7af8360222cec57167161ad00121a5cc19bebd53\nNONCE: 6d9f32e3139a18fcd34c1e73\nCT: \nAD: \nTAG: f12553f984d4a1d0\nIN: \n\nKEY: ddd54500533cffd1af87c6f58d880d45c1d27c22ed283c110d04227658d443ac\nNONCE: 2cb369234c276e1838c9575a\nCT: \nAD: \nTAG: 7f43b5a32da7b9f2\nIN: \n\nKEY: 62450ce465840e8d49e7aab125f66817bf57ccb0553e5aa633150913406281eb\nNONCE: da552ec45463002256b07393\nCT: \nAD: \nTAG: dccb3788c2e2a66f\nIN: \n\nKEY: 5765ad16f4dbd4d4e6370dbfa18b8ef5ac37459e39556afaba9b553dea4c1b23\nNONCE: 59678f262588e4d526d9fc34\nCT: \nAD: \nTAG: a68f33ed\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: a29fa93614e9f714c73d3707d1142b2514fa8a14641f79ef14e9bf0e812f49fa\nNONCE: 68272acf71b1cdad4655dbdc\nCT: \nAD: \nTAG: b90e554a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 717d2a5396ae21560a895a7847f53c47956d155ca4dd2165137d3506ff48a7bf\nNONCE: 6ccd8086830f586fa3b0e777\nCT: \nAD: \nTAG: a618ac6a\nIN: \n\nKEY: 6ecf9a1db3e42ed91d2206646369d9eab43fab9efbf797a6b2633db3eebcff18\nNONCE: 7142907a03b12ba332d84107\nCT: \nAD: \nTAG: 57e1882b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 186361bee6c4d37b94b6c9389216db63b7cf7c5b28592c290c02c9aa0978b6e7\nNONCE: f1a7b61b6a503665049d36ae\nCT: \nAD: \nTAG: aa52f4e2\nIN: \n\nKEY: d8d3fd180da0136621d9a7ebb273bdc4ae48fa72997c7b902c2c512c2bcc11e6\nNONCE: 4f7692221b2e295220f6a1a9\nCT: \nAD: \nTAG: 7c16931d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2231071e59bbfa627f0881f04ea13290302674e05f405f75e3c62d787d07c2f3\nNONCE: 65b3758e6418f04afa2b4d9d\nCT: \nAD: \nTAG: a56259a6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fa1dc19ed84ffa40c94ffd1021208f50dffe16e9f0a53b5ee6be55163a408618\nNONCE: 09bb332baa725ca0c72a150b\nCT: \nAD: \nTAG: 76c71a63\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 0a7733e3c0e7017b17abc46e25047b3b5d5a3f95bd45e069953d08761b826e9e\nNONCE: 0257955c4f6b354ae46b5d44\nCT: \nAD: \nTAG: 04f4bffe\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 060ecdff8a7325d76017b93071797b2c299d6519d0605b565c8550c66875cdd5\nNONCE: a8f8288d9124ee73c6b89f47\nCT: \nAD: \nTAG: f493e8eb\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 9a9d85fff37716f90d4523586e99046e66cede008fd8acdb55ecefcd9228d7b8\nNONCE: 8a7296be2b691ea45bf4cf9d\nCT: \nAD: \nTAG: d63728a4\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 2344f2cb986326d931d768e8f9bf7cbf7aa0fe91fe5d7a9d8e0591e1144a064a\nNONCE: 0fd7ad08c13f0c97f5c85d75\nCT: \nAD: \nTAG: 6196202c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 17b00458ce181235bc704ea54cfed4a74d792350ea4e3e1dd4d1817b3720b4f6\nNONCE: c4ec09b35b857bea94a728a2\nCT: \nAD: \nTAG: acceb73a\nIN: \n\nKEY: 7e6c0a5cc37125408f8f11f5607054a3314924c36a7f1b1988c46cd06", "ebe4ffa\nNONCE: 299973ab4a56aaa8a67e6e59\nCT: \nAD: \nTAG: 1f450c0a\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 1b5b987676d7ce62c42d9103f7ee8b3964da272eaae5097a0e0b0a2678e6a382\nNONCE: 1828385a47e53ce3810c0bc0\nCT: \nAD: \nTAG: f938bdc2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 6dfdafd6703c285c01f14fd10a6012862b2af950d4733abb403b2e745b26945d\nNONCE: 3749d0b3d5bacb71be06ade6\nCT: \nAD: c0d249871992e70302ae008193d1e89f\nTAG: 4aa4cc69f84ee6ac16d9bfb4e05de500\nIN: \n\nKEY: 033360a08d0b2963ce4dcf807b772ac86ae3e8b8fabb9cd3a636f8ec54365646\nNONCE: 8dcaa63d13a2425395609914\nCT: \nAD: f9d15fc34984b8f4a7caa29a82b24c52\nTAG: 42bc9cc93a1c8592bd29c9ef9f907780\nIN: \n\nKEY: 4f1a5fc8e4689c493ef8e23a653e86e4d4c8972a2338653375b0f36a4feb91d7\nNONCE: 9b8221a631404088218fe487\nCT: \nAD: f09b0fc4e4ccb5e28dfcc0792a6800f3\nTAG: 31073f1a0050462a03c7ad0bbefaf93b\nIN: \n\nKEY: e70e4f6919b521dab68f0dff6b4aa57e443db4f8301186819d8611969af33b28\nNONCE: 63d5ff1ba0d5e69f5dc1c92f\nCT: \nAD: c29abcf1f61063c6765747da8980fde4\nTAG: 3d78ec2d237dfd57b8b125ff0912653a\nIN: \n\nKEY: 2c392a5eb1a9c705371beda3a901c7c61dca4d93b4291de1dd0dd15ec11ffc45\nNONCE: 0723fb84a08f4ea09841f32a\nCT: \nAD: 140be561b6171eab942c486a94d33d43\nTAG: aa0e1c9b57975bfc91aa137231977d2c\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 48f7b300acde77c3a00e8dcde06063761d2dc64809db5d39c7a671d2b2f7902e\nNONCE: 194e611ed5980b0e93a4a388\nCT: \nAD: 72ce59bdf0059bf33e03e5fc21f3a6df\nTAG: 7d26231fd58aea00331165c8adf912f3\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 94233d297c08899ccd69eeec3e4e258eacabee0cdc2c363c352e833200162599\nNONCE: 733fa0c7e0e692b0ea66a402\nCT: \nAD: b5bcc7ef6837b61253db277118fafc9d\nTAG: 024174b6f7fed276966d17b31cab2b47\nIN: \n\nKEY: c90ac1e868bb79467a58383f02440f9155d57dc719f0a22d0d6f088ebe7c18ae\nNONCE: 149a0b9691b35750f72e03e9\nCT: \nAD: 2426db7f430a090f5132c63d23504350\nTAG: 807b58bebd6de9752f62eec313def53b\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: efc390eb39011ec8078700f4de848298c26d750c9127fa79cb8c1089038da129\nNONCE: 13b65b7cf33db33b3d5afb1f\nCT: \nAD: 7e56ab79b176488969e51a58de554979\nTAG: 35ec21526ab815582d201582e7ddcd77\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 5c202933d7efedc1bdc4fcf72794bf448f6c22959978e1947e399d9f3386bf2b\nNONCE: fef59a2f3e7d9eae573ff06a\nCT: \nAD: 9cdab8e46ef227f113e1ce1dc7ee2733\nTAG: 76bf3a22f991625dda441975b4af8952\nIN: \n\nKEY: 577cd9f1a9f0f4b61455db0d5183536c2e5d000df5c812e140ca746ea9d05cbd\nNONCE: 7d6a93560b53453681028e45\nCT: \nAD: 7b4114eb668366fc26bc2078f04cac9a\nTAG: 294409118a4ac46ee9444464ac352cd6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 942c44274a9dabdb86328484ee933d0d632efb6a074323ab41fac267c0b25e48\nNONCE: 961645b7ec62bb4e4bda29f6\nCT: \nAD: 0e4f8509aaa009192fa04425b9d803b9\nTAG: 2fd7f29b68ec985ec564926484df7e3d\nIN: \n\nKEY: ebacc6cd567c245f37100d76f2898a471a435b07d605a3251835f450f9861da3\nNONCE: 164617867a09dd08d75b8675\nCT: \nAD: 7f5b2c707a8199c8795d7d440664e9cb\nTAG: c8881e8c4dd1d62a2cf6f8458b45c0af\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 415fbefbe947204a5a4412372922cd68ef7cab6b7f48d8da868f24c2426e755f\nNONCE: f939844564c5b26e18b907d8\nCT: \nAD: 462ef98fe991867d0888954adc772edf\nTAG: 811b9c99e66456002558c8a8392b04ff\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 8f82e4eb127be9b5a2dedf8f3f16ed46df0443eab39d604523b2a0909044426e\nNONCE: e0d06f20e17990d17abedfd3\nCT: \nAD: 81f78234cb6c9f8c8134a81e29712457\nTAG: bbde500c67c81f7d2ecb214b33f298b6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 3395a1485315c5b5e6353acb05ae9499c440a2e9f5c57494662f827235ea314c\nNONCE: 3b7e632571602456b49880f0\nCT: \nAD: f283f80226dacb69c8af089ec6b59e81\nTAG: 84c8beff4b0d160ee68ac613097f51\nIN: \n\nKEY: 737ef66d81c3c2610f77f90244b45c9fcbb3f46b41c8cfa959f1b64bf1af9a30\nNONCE: ee35b4f52756562c53f34710\nCT: \nAD: 591d20b3dad931c15958a6c08945f2c0\nTAG: 67786146498e15b97785ed29e3cf4d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 667eb074e723473425639188aeb1137645968b37fd51ac85ecf887630537e790\nNONCE: 66259c4c34952325039dae8f\nCT: \nAD: be4e71df8b90ae61fcfe2522fad707be\nTAG: 313f387ceb2fee4113a3b97a75a0cb\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 864c3c19d43a850bf696f546be59fa4939ee7a2b39fe0f3e56f6b777c4929d09\nNONCE: d53bb663a8d0aac07eddd12a\nCT: \nAD: 4ad4e048c24b370530f482a4d7a6d1ba\nTAG: fc0e69cd020693a0186da50cdc6f69\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 42b434401a46ab08b799571e8b2ff3834bf002ca910989ed86bafd5a6142d190\nNONCE: 81eb9cc03444f5d0dc3b76d9\nCT: \nAD: 82f75629976fd7ab11ef70c6f8f977f9\nTAG: bd1bb7d7cdb7f25a457b85e939c131\nIN: \n\nKEY: 7e4d9071738036cad1ddcaf8439d0f243aef78116dff67269fc3fec66b86384b\nNONCE: 3a7fbd41615e656a0ff3738a\nCT: \nAD: f4adfe43c17af941168fa4b879ebf209\nTAG: 48a7f7b1a1c05f20e9bf049bb562b2\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 345e15dfc70d4f0609cbc5724276f606ab3aa9d0ae4bcb5a6536dbfef8f5df62\nNONCE: 970bc624e62e6834b7f3fe5d\nCT: \nAD: 44a5fa62b3babf2c86064cc0a65b1cb8\nTAG: d7b83a03f18f6623bd41acc3f6f3aa\nIN: \n\nKEY: 6dcb770c7777225902bae16a6e77045ffe682a7985c265566c61c4ffb405a547\nNONCE: 1faf5b86290e23ff7411c146\nCT: \nAD: fbe8e5e071969c7baf0f4c1c2a830327\nTAG: 78a4078b4decc5e34d477e308f0cc7\nIN: \n\nKEY: ef9a0377ae02c600f6fdd5dd6f4f7a30954235539bc9b3fce0085b3b30d6c354\nNONCE: 33db5adfa43c37d002e82038\nCT: \nAD: 945b8a540c57923e7cd4ca319e40063d\nTAG: 3c0e1f73433c5d229e739fed399ff6\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 6ec5526e7cff0b75f9af20ea59e7cdbaa91a4194d51374527909a3bd6d8ba3bb\nNONCE: c23ff927bba76205628506bc\nCT: \nAD: 8ed268badda27f8fe5a16ce8a3d7fc2e\nTAG: 3079599fc1b2e66e1c9f668cf9c001\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: fdf860cfc7e769d262f1e0b0640a56e0081c75ea96376e4a51ff728dc4b11503\nNONCE: d29767af7bb47bc18fd7076b\nCT: \nAD: ee7e40f375e100fdaf39765d60429289\nTAG: 19f95691d2fc7d7724474ebb501738\nIN: \n\nKEY: b548e4934f5c64d3c0f0b78f7b4d8824aac46b3c8d2cc35ee4bfb254e4fcbaf7\nNONCE: 2eede1dc6447c7afc4415358\nCT: \nAD: 8bd50878c430718b7b3775fed76e5aeb\nTAG: a7186df4cec4bcf921ee8733359567\nIN: \n\nKEY: eb70ee93654a3ae49775d315e51c758bc0b61c1fa848089fc12c65419a00afc2\nNONCE: 87cd3cadd925b79636bf128a\nCT: \nAD: 80b04fb39d7b6096be12dec866de2d37\nTAG: 3f9902ce6dd2fefe0a9578276250f0\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: db8151b0d80c930331ed8c7ff7d8038b34ad20fbf537844f7ba9912b71213f1a\nNONCE: 32f9e46e555eeabf12bc59ce\nCT: \nAD: f2ba52d1e09c37eebdcf15250979643e\nTAG: 8817c90146b70b252c124e03ada704\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: 65b90acf1544349bfa1871163c92680139aa9a5e2b620c43b41cc59fe1cfc15c\nNONCE: 5cff688f2ba29cf9a6d94a7d\nCT: \nAD: 43d55cfde3d5832f0adbf3dc47943d00\nTAG: bb787f2450cda0c33b08579dca4e63\nIN: \n\nKEY: 34d3dd0a9cbec32dfe94c9707b48dff9e2ecdbee7ca28b3ca9dabbb3701ae493\nNONCE: f8e05f6e7a04cadca8b5c4fd\nCT: \nAD: 9e52b1a7c1fb736d659754e671caa840\nTAG: d6615a18f437f38311f5ac3a9f60\nIN: \n\nKEY: e8ad0a2b1bfceeac69ed3e075d4dc5fc03b3633919bc5edf0f1ffd9842424985\nNONCE: f8b5b6bde3fc26b7a553ecef\nCT: \nAD: ed8bc8a123b35e0e7ed3aa8f8820b0fd\nTAG: 008bb8ed513bf8d3210d1278382e\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: ac9d68e15be409d5998885b714bb51f0d5a75df29e4ed7be2c1c1e4c6db49ae4\nNONCE: 4bcd1869cdcb16adb45dfb98\nCT: \nAD: 9f81a65554c7185181fec88601051cfc\nTAG: a7ca610547cba6ec333371528c0c\nIN: \n\nKEY: e9a4f481187083070dc1956a7c34ee9b86791cd6e40353e3f868560ee77127c3\nNONCE: b7894710eb0cea0acf1838fc\nCT: \nAD: caf33a8552cd0caaf1333c9aed7eda13\nTAG: 326e875a09b9df1ada0321a005f2\nIN: \n\nKEY: 0220d839e195821944f343a71dde45006a2c3600df8883bc83a9fd60cc67771e\nNONCE: 8d22fe9571e9096c22f3fae9\nCT: \nAD: bad23a8f33857c447e89b0691b7fb03f\nTAG: 43c0cabf088b71fed4dabd63c2e8\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: b253cdbb8519abd630435f277d9d69f25c3fc7c87004e506092f05855854b9a9\nNONCE: 493bacee0dbe6edb5b77d1fd\nCT: \nAD: ccd5a9521aaa06b967316be581487a63\nTAG: 01afc617f6a2786dcf13ecc00bbe\nIN: \n\nKEY: a0cf288734824493aa3673f95e68d07e289d394a04f2e3e5881afab773f1e242\nNONCE: 2c18ee9f12c5229c0cfc3f43\nCT: \nAD: 0b89b94d636559adc46902e463514e12\nTAG: c933b5cee0de1a2cab183afe3ec5\nIN: \n\nKEY: 3271f86968b3fd49bf4ec0e572616e2b96edd4a530c519b542ca926b09a92efe\nNONCE: af184a643754b70eb60b15f1\nCT: \nAD: cd839a71cd04bac3bc3c17871b6853f0\nTAG: ee6ba4f92dcee9c20b734811318a\nIN: \n\nKEY: 31a3e5aa9da7b44c302cd716937584195adfd26f24a6c49720a50d49762df80f\nNONCE: 9a999c5f8dade4184aae1301\nCT: \nAD: 0d84dd614fc04e58a971a270bec5b8f6\nTAG: 230bc3c4cb7c46e73ce3662d1e15\nIN: \n\nKEY: 865f524ea89d3299b372c01f5c072c1fe07f78e86620fcab5e3e96cd3044962e\nNONCE: 8df4d357882c805d5a5a5d95\nCT: \nAD: f9b70b9d4bb6f9562b10cb65ba1c0a7d\nTAG: ab59a2107248e6651e3d6f3e116d\nFAILS: \nNO_SEAL: \nIN: \n\nKEY: c12c83994e125c98e588d93f968572460345c44b5f94deecd538f0e5e7b0fd66\nNONCE: b684791dd61b9d940a0dee14\nCT: \nAD: 57a128a7ac50137520ffce721271b8ca\nTAG: e322ccdcd7594", @@ -2244,9 +2305,9 @@ static const char *kData28[] = { "ac4f2cd8a71f0fb078323449c5bd4e3cac8422318b06b44c49ccb701d69831\nTAG: 7347166e\n\nKEY: 36f610b6f08b020f4d3ca0faba582222016aa4ae44c619efc3aa8a3d794c4678\nNONCE: 842b957ca5f56f3b3686269f17f7e5b712593b8f37fd6079459958e31e07955f1a1861204e4c9e5a6b70205a0f45a33229b948524f7102dbaaf4e7a66900006168ec0c99e766fe89da8ae72dcda8e071f4c2fe75ce3cf903dd7b53ddf5ef95a88663c381afea00abc5e6be5c6477a9c5152312cf54af7b0c718a5985e5e8c7ec\nIN: 78a7deed4eb613cf2b3e572a3ff47e6551c7908fded855fba64247493a7360505f1a08e7ab850d00d02b970e3a2b5da9bb6c33\nAD: 6f91e23494601696841fd9dc0a0e7fdcb6b32aaaf2ee7b84270a59aaa2bb13b5bd1990a9fe3b0534751f10c2058dd3a550fbab61bdb4525fe6bd45326419a48339398f3191e7ddb0d8f65f4b00b4f5b6ca4aba9e99edcd0ad05f\nCT: aab48f5510ad845ebe79e7689dbf7ffb1dc3c6a810c1b754576576675e77fa81eace7882045220baded90ac098c6c65f26613d\nTAG: b21bccec\n\nKEY: 14644de3b6efc121077952f76c3e76ce847306a355e734e0869b51506f6bd979\nNONCE: 84a47e799c51d8052b27644399a4b807487d64c06ea037b62af6a0b0d1212f4acfd1d080518c1a9fec5b2c8ba4699ad7df155715cd049f5085e86c0601fab79ef1472fbb35065e7dfee9e4077e0e365d185f3c88564abf1fd1c3d3bf1a209a5e24a2b027895ef1524fe199c31a4bf690ea3ce209cbb9ffcbac4c06461e010fb9\nIN: ed1a2abba7e782a8f3625f5abcf613cb3d353837fb88edc5b117fc35ab553e244a60dd2ed67aa6b8a99ade1bab69cf04405957\nAD: 7e223758e23e4bb99ee7406030a2db698d5e32c69d5f19170c052bd597bbfd4bbbdcebbdcc801b1bcad869da195a8c4452bedec0fcd91fedb6fa49c38e187e8b536b69da683ce4a322b81e70c93eb66c9010ca3be5d54200d87c\nCT: 80b8c3829d991e5b1331cf229d7448988ed6271efccfe84998acc67e924c73362337da0d697f4b4613d06a88bb4ae8fa81c2cb\nTAG: 38b59916\n\nKEY: eb3fe1c8bb57d72fea9f9e9cc3cc746d41742716dd3cbf574eee95162bd93f9f\nNONCE: 1ee1a2fe7dab975fffd19230d80804b45662855c0a5bbd2802e47b2d3fe55b0c15e2383e7070404ce46670c0a2840a6e14945c5bd9ac521bad8ca7effd6dbe71f74eca082a490d15088d7bbfeb9cbb1e8ee86d77b1db35b43a259a14ab6b771ac58ce36bf99d28417a04d2d3ff2d4380a6b23ccd6e68b0ae58a6fa54c973b6a0\nIN: 0ace576340e524019888cb4900fd9b52e5382e4e36ac9a969c5f6bdddfac12c2d991ea9e2ed5f68dc4a51d62dab83df8f838af\nAD: 28d402e6e8cce27e47a0eb03b5497915c3b71399fb95f4bc6d3255cad73508eed443cd44e59cacf9177dd3ac1cdca5233bce39621227951d11f2a2012930822ee929dc791f3eaf1a97e219db04d6f178b804de60224ab120abdd\nCT: 50096632df34a1f2d8848304e20060d999a5b1eda1932774e30f36026da8c6c0baca7f6e59a7c74018c5f51075008b74424bd2\nTAG: 7d9d2417\n\nKEY: 85ee354b4675a9c5d16e3d6f4118043bd92f209f016f49efab7ce3023b78112e\nNONCE: 5c3b5a95147880f9d14373bc3886e92036a0abcb49fb6768e2811761cfcddbcac813bea95a5b76fa1ce5fc726708ddeee5d1a9196d31eb1f0c1d4992ba37a9c4179d223c460ff2b512a9d3cf3562c586d793efd94a5e93d4b1e86ae96c3aa6711a291ec710dfbd7ec46b2ed4f4085df511fabcc5e42bded5214253d235f12d14\nIN: 1b56de101a75bb9d1a5e77590be302837d3921278e480347944b92975e819e7a233339f31ecf02b874842fb5a136c810a9a9ca\nAD: d2eb4e760ed4fb687b32c6bd073bffaf9631ed3ab83101cab236352d024cf422b917a7660a484be236e4d3b3fa3343d3f9e87d86c50834a213b7ca2a3212c254564e1c59551c7bd3e01710a7d8c8419320a6d3362489aa368424\nCT: 67dec658a84468cb86268099e03ce701e9936c27b50059b5c9e8743df7df5b828364ab7025f854cb9e3cfb27ca5b717502b838\nTAG: 65a1bfa1\n\nKEY: 6f79bf94da7dde3c86009934d9258f1b3fc2f5382aca9c9cb8e216eed235f34c\nNONCE: 83e413c8e6f76b32aeb2960c11aa9e522d3994e14c18609c634c9cc1cf94f2c49a5347d3f440367f08a3322eb3560675bc4715d03abbe0da4a75208775e8bdc3ff2d33daa301f53dd75a83f74c998245c1826ad41602c3fea313098d20a65e417e7c6ff954d9c9b2458a04ab4deddf07dd22bc409211dbd121f5a95215d40094\nIN: 738516823e8f5d23f3181b297eb70be633e3b0cdd61117384e474e3223658167ad6afd83d9839bc925876e4e41a001f678a06a\nAD: 02a59b404f7fceabc06e0988bcbfbca1d08f75a83f2cb9542edf106702e2c9964d7e37ef86fb368a9890a4f2ae7f58f336cb2df990cdaa2775959c99cf1d11a59abe348cc5a47f98c447e6500b1013b38418677bd582c5fbdcd8\nCT: 183cc63f537b301e928a1efa211818a128964e5d025c7dde9ccd69e6a8dddc2b9824520e31d52cde506062d225407520a00155\nTAG: bb1df68d\n\nKEY: 0c5aa8e0b1979183b997f29362ae83700d3ba6190a210fc90541b17e45a46668\nNONCE: 96a1f2559204788f6bb0ea50bd598614a7ce518ec4dab951e9517bc46357448a6b4aed200ee21a7543fbff861ed56321195675d9225cac72547d3e4880b9517672b86206e9acffba53d66526e919587e7b284a612aec391517e907f2bf6a625a990466d66cb14c690be17b7a22085ab032a05dbc16a99437670cfa2bb8a283d6\nIN: f460e28cb67fb2b0aa5315c25f8132e5a8298ae3077ee0bd918fe1acd6312a98a3412a3198c834beb932200281fe6128a08be3\nAD: 9c410a60931ef1cb5f6fa9c7da0a96ca537daac174fd4f1bf247de1e25d3dd44a37f54d58ca48d1ecdcf2ebff8959c2db0ac82244ac76243404adf45be72aff4b19be063c088e1810f9eb4b894f405c61691e2789297b17430b8\nCT: 3e12c2a17cad65077073385c055054bc8f72f1beca59b0636384d027dc1350d39a8f3c77f5bc26eb916287dd742bcd3a819299\nTAG: 154a3b39\n\nKEY: ace49b23bebdbb36cae24809c68cd4763c000c689c77d230256f6e5206ba178c\nNONCE: 34e829796c7d186b3c83c894b3f36f3f07d66261670f4c1f74c83b074b2b7e5fabd8756d2c9676bb52e9c7a62c7c26376128d1ffda5f9ad5d7b48724d46672eabf83ab9e6cd596510bd9ab3be81089c4262a9f8a88820c6e27a49593bf91b9dbc884b4548aa9ec4bed9e1d5be57d413553459f5d8e7cbca84ac89babb45f501c\nIN: 9c85b9c441034e26c5ebf04580cf617eea19a001098c910a7eac423af2f5fb2cee0335fde1fe56bdfd31af513e99e92d5ad7cd\nAD: 419583e7bd2f698ddbbdd429a81654c37b07dd2d80f34c9ac3d0f9ef7329f39fb5c21db57bdd496fd69097736989fd0f1d3c803ebbff7d128ac31873754f881247896907574bcecfdf2eb3a5e6996050eafd68f0401d0543fd46\nCT: 9141c922cb598ae9dd3aefd9593e2788870e9ac546fb3fbf5ba0bd1479216743cb603c4cc2fad030796f9cdb5b325ee4c33d8a\nTAG: 356fdb25\n\nKEY: 69e095a9ae4cd697869b845c4e848b7fe1511d1ee334ffa63ea427eee18a6b54\nNONCE: 7ae669a8b81bbcc2b72724a14169f1e2e1c114c0ff3ef33434a82d368272525398ae1a9aabb1c50ddebfca5e853dde04b46518bc94b91b51364c82301087ca30852ec7ac52f51ecda1c2ca2e099c040929f6d1236157011ddf7e928df7fb329a012752eb66cdb725e416e7a10108b2bd4f676b5ab85b8f33438c273bddb8cffa\nIN: b2727222246b940448a24741984ab6afe5e9474e60cbb8ce714110390f1c90b33ed0ec0267b86cc305b9807e370ca146bd61c4\nAD: 74a1899056c4ef9d848cd7c8d8ca377c6810912c62e428fe5acb60908abae48c887e7460943e9d6795fa6203b994e05799ab8edb55c29fcdccc3c41b3b74346f354a214d3abf891b8058e55461d3f68c3a2897bc514212aac91d\nCT: ddeaac80cb1db067d40143a382eedb2183809153db5b23528c476ae25c9db5d28d53dbab6f59ac5c016150f8384f5b84767189\nTAG: 0936e1ff\n\nKEY: 9c8e8c0638b76c552d1ce80028b707286bf2a84568d7021179be55708e820adb\nNONCE: f414375eb3faa866349ee5a6f11db10b2d2b32719906fb25f22ac2053e9f402c4cf545ae973336ada616d99fd57e7b2fbb6bb8f167fd907efbd9983515d509cbb6966778bccfdedacd9cb58b0a8fbf0a3900128f9f47317485e2c8e30a65f68e43ff8ed0b20c83681e750214b8f004f2529f1f3fb06554a47ffb8532edecf949\nIN: 8af304c8d9ff794d784cca9bafec22868cf7cf5c038b2afa7cefbd84be5d98b50d3009bad9d69083abf47b5068d59465c10389\nAD: 913b191b128e8d021ca46d29455b8082e7013ea49e1c931fe94adf3cfde26785ad9e9828eb48bdda066eb530c5af62481eca4401fe31eb320f6c52011db38f98144a0ea5f9fa6d5c373c76eead287e67e83f9dde0f2e27a6c40e\nCT: 63a8f8e0183e5c30532dd6d5235d6418828243e4ef9aab82ad537e20fa11fe188d440a7fd5a53669422c65fed98a00e4631f44\nTAG: 33491cd4\n\nKEY: d74eb3cfdd9fd9fe176415e1973a12f0110ef55568746e99d07d91b339cee79f\nNONCE: 06b5cc871a93bf13726836392a7e134f2b122f2238b086f18ec88f16d21f1914551a63a169e97c9dadabc9f488bf54a7883e618e59472041dd74ad356e7d92f8666af1b4b2cdb35fb0d722ac0b31d2fd475052507eafb98d5c2109b5f10254957fc9b4c6dbfb3bf4692771b4ed305d7521f5842d1aeaca0ffbab8247fc3b76bd\nIN: d654f510806c9ece9c12dc749cb9a08467cac2cad1afcf3b4a41a2e0873dea9bc0cf61b7aac2ebba93eb46ae6c5f11610d0b41\nAD: 9855a05c20be9b2416fa0032d94db428c949e68262f8a084ce3762f85c3edbe6175ef48279141822c101929aecf36e8a68e8fec8524945debb54e046b3c71a44630e569ec849691c7f0f9a74e374d27732df33578c5bde492907\nCT: af6f67769f0f099e6590e97dc6d605dea986772a68966408e81d49b1e8d24fd835daed0d4bda048c47d5ef87f22752e99e1446\nTAG: d449dec7\n\nKEY: b5f849da887e3c1878b6775aff7e49f5f31ed8cdf9f79ead5b36219eea87af80\nNONCE: 63f75fd55a8bf19eadfa23eb7a3e5c8fd13d79f6bb6ba414d2027fb08283f5108c11c2d49db52f4c68c11164c8a1585bf115512cbe5f5aa478c6c0e91864f5198862a694f0c2471aacd32ba57be1a33f04a56fdc60a3dcdde73c7714c10eb67b749433b1b3027b3c4b4f29fc57c3eaad9eefd033dc4d42bc75b36e7445a383db\nIN: c1a27f693387a1c8f5fd1eed0c5cf3111897dc8797b4e63e89bcea06cb19b734e354d9f539f5af700641f0f4acf91ab52147f0\nAD: 6dc78b3a5ea409838b533ebd77cf1d1b4808fef131275a0d4dcd94ca0f55b9dd86017bd664e036c2fa756c65a7a7d246229900fa468349eb2de18b5bf1af0f7da56ed0377a65f5e650ddf081c4a29eb985456b276b4d303b7832\nCT: 837a", "ff99c32f665841239e0897134461fc3e8faa8f9965eca5dae67b2934e0816f39d36c45ef8a0b8066ae4f9752e65ef3a6d9\nTAG: 94b73bcf\n\nKEY: cd670a8ac109d0f0e436ee42e490d5576bb7c13230f727b150b473bde659826d\nNONCE: 719191db1dc5ae92cf75cd8ff02ff036e78d6bef59714e5d40c24301443952148c61ab2e7e15d95f8d1792ee307a27c0112ec1b28c4a0416f76290b77d89088542d13649d17af09d6c5302438895534dedbb587f543c0d76b1e3e065ce6a261473d27dab6a928ad1fc786333dac512f3b521760dd1f67907292d868423a4f64b\nIN: c94ebec7d8aa421bfa9a0203520e02570338d12359c5b16d51050cd3f802351b17cad85b52ea9b42147f528a25e52c170c6308\nAD: abdf817a7ff3f28bd0b5ef0c2ec02ccde1799d4dea806580941f63b7840b2deedd3873ad1c3186ee3c6b6fa95062fcb56e33c6737532e7c326e116f2da4cc920c8bb354e8d2e27c1920962e16a4c89521c4e1699f2145f742d36\nCT: 286b594cf9a92b2d7348f0c75619e14916f2cafb990cc2d6aa07162d0703a9f7591e40eae402edfc64cafbedfc7ec2147acd51\nTAG: 22d3ec0f\n\n", }; -static const size_t kLen29 = 81764; +static const size_t kLen30 = 81764; -static const char *kData29[] = { +static const char *kData30[] = { "# Generated by \"make_cavp -extra-labels Cipher=DES-EDE3-CBC -cipher tdes kat_des/KAT_TDES/TCBCinvperm.rsp kat_des/KAT_TDES/TCBCpermop.rsp kat_des/KAT_TDES/TCBCsubtab.rsp kat_des/KAT_TDES/TCBCvarkey.rsp kat_des/KAT_TDES/TCBCvartext.rsp\"\n\n# File 1: kat_des/KAT_TDES/TCBCinvperm.rsp\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 95f8a5e5dd31d900\nCiphertext: 8000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: dd7f121ca5015619\nCiphertext: 4000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 2e8653104f3834ea\nCiphertext: 2000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 4bd388ff6cd81d4f\nCiphertext: 1000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 20b9e767b2fb1456\nCiphertext: 0800000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 55579380d77138ef\nCiphertext: 0400000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 6cc5defaaf04512f\nCiphertext: 0200000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0d9f279ba5d87260\nCiphertext: 0100000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: d9031b0271bd5a0a\nCiphertext: 0080000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 424250b37c3dd951\nCiphertext: 0040000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: b8061b7ecd9a21e5\nCiphertext: 0020000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: f15d0f286b65bd28\nCiphertext: 0010000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: add0cc8d6e5deba1\nCiphertext: 0008000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e6d5f82752ad63d1\nCiphertext: 0004000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: ecbfe3bd3f591a5e\nCiphertext: 0002000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: f356834379d165cd\nCiphertext: 0001000000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 2b9f982f20037fa9\nCiphertext: 0000800000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 889de068a16f0be6\nCiphertext: 0000400000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e19e275d846a1298\nCiphertext: 0000200000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 329a8ed523d71aec\nCiphertext: 0000100000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e7fce22557d23c97\nCiphertext: 0000080000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 12a9f5817ff2d65d\nCiphertext: 0000040000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: a484c3ad38dc9c19\nCiphertext: 0000020000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: fbe00a8a1ef8ad72\nCiphertext: 0000010000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 750d079407521363\nCiphertext: 0000008000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 64feed9c724c2faf\nCiphertext: 0000004000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: f02b263b328e2b60\nCiphertext: 0000002000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 9d64555a9a10b852\nCiphertext: 0000001000000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: d106ff0bed5255d7\nCiphertext: 0000000800000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e1652c6b138c64a5\nCiphertext: 0000000400000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e428581186ec8f46\nCiphertext: 0000000200000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: aeb5f5ede22d1a36\nCiphertext: 0000000100000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e943d7568aec0c5c\nCiphertext: 0000000080000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: df98c8276f54b04b\nCiphertext: 0000000040000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: b160e4680f6c696f\nCiphertext: 0000000020000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: fa0752b07d9c4ab8\nCiphertext: 0000000010000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: ca3a2b036dbc8502\nCiphertext: 0000000008000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 5e0905517bb59bcf\nCiphertext: 0000000004000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 814eeb3b91d90726\nCiphertext: 0000000002000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 4d49db1532919c9f\nCiphertext: 0000000001000000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 25eb5fc3f8cf0621\nCiphertext: 0000000000800000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: ab6a20c0620d1c6f\nCiphertext: 0000000000400000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 79e90dbc98f92cca\nCiphertext: 0000000000200000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 866ecedd8072bb0e\nCiphertext: 0000000000100000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 8b54536f2f3e64a8\nCiphertext: 0000000000080000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: ", "ea51d3975595b86b\nCiphertext: 0000000000040000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: caffc6ac4542de31\nCiphertext: 0000000000020000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 8dd45a2ddf90796c\nCiphertext: 0000000000010000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 1029d55e880ec2d0\nCiphertext: 0000000000008000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 5d86cb23639dbea9\nCiphertext: 0000000000004000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 1d1ca853ae7c0c5f\nCiphertext: 0000000000002000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: ce332329248f3228\nCiphertext: 0000000000001000\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 8405d1abe24fb942\nCiphertext: 0000000000000800\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e643d78090ca4207\nCiphertext: 0000000000000400\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 48221b9937748a23\nCiphertext: 0000000000000200\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: dd7c0bbd61fafd54\nCiphertext: 0000000000000100\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 2fbc291a570db5c4\nCiphertext: 0000000000000080\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: e07c30d7e4e26e12\nCiphertext: 0000000000000040\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0953e2258e8e90a1\nCiphertext: 0000000000000020\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 5b711bc4ceebf2ee\nCiphertext: 0000000000000010\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: cc083f1e6d9e85f6\nCiphertext: 0000000000000008\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: d2fd8867d50d2dfe\nCiphertext: 0000000000000004\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 06e7ea22ce92708f\nCiphertext: 0000000000000002\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 166b40b44aba4bd6\nCiphertext: 0000000000000001\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 8000000000000000\nPlaintext: 95f8a5e5dd31d900\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 4000000000000000\nPlaintext: dd7f121ca5015619\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 2000000000000000\nPlaintext: 2e8653104f3834ea\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 1000000000000000\nPlaintext: 4bd388ff6cd81d4f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0800000000000000\nPlaintext: 20b9e767b2fb1456\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0400000000000000\nPlaintext: 55579380d77138ef\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0200000000000000\nPlaintext: 6cc5defaaf04512f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0100000000000000\nPlaintext: 0d9f279ba5d87260\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0080000000000000\nPlaintext: d9031b0271bd5a0a\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0040000000000000\nPlaintext: 424250b37c3dd951\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0020000000000000\nPlaintext: b8061b7ecd9a21e5\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0010000000000000\nPlaintext: f15d0f286b65bd28\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0008000000000000\nPlaintext: add0cc8d6e5deba1\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0004000000000000\nPlaintext: e6d5f82752ad63d1\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0002000000000000\nPlaintext: ecbfe3bd3f591a5e\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0001000000000000\nPlaintext: f356834379d165cd\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000800000000000\nPlaintext: 2b9f982f20037fa9\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000400000000000\nPlaintext: 889de068a16f0be6\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000200000000000\nPlaintext: e19e275d846a1298\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000100000000000\nPlaintext: 329a8ed523d71aec\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000080000000000\nPlaintext: e7fce22557d23c97\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000040000000000\nPlaintext: 12a9f5817ff2d65d\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000020000000000\nPlaintext: a484c3ad38dc9c19\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000010000000000\nPlaintext: fbe00a8a1ef8ad72\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000008000000000\nPlaintext: 750d079407521363\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000004000000000\nPlaintext: 64feed9c724c2faf\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000002000000000\nPlaintext: f02b263b328e2b60\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000001000000000\nPlaintext: 9d64555a9a10b852\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000800000000\nPlaintext: d106ff0bed5255d7\n\nCipher: DES-ED", "E3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000400000000\nPlaintext: e1652c6b138c64a5\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000200000000\nPlaintext: e428581186ec8f46\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000100000000\nPlaintext: aeb5f5ede22d1a36\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000080000000\nPlaintext: e943d7568aec0c5c\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000040000000\nPlaintext: df98c8276f54b04b\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000020000000\nPlaintext: b160e4680f6c696f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000010000000\nPlaintext: fa0752b07d9c4ab8\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000008000000\nPlaintext: ca3a2b036dbc8502\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000004000000\nPlaintext: 5e0905517bb59bcf\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000002000000\nPlaintext: 814eeb3b91d90726\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000001000000\nPlaintext: 4d49db1532919c9f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000800000\nPlaintext: 25eb5fc3f8cf0621\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000400000\nPlaintext: ab6a20c0620d1c6f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000200000\nPlaintext: 79e90dbc98f92cca\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000100000\nPlaintext: 866ecedd8072bb0e\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000080000\nPlaintext: 8b54536f2f3e64a8\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000040000\nPlaintext: ea51d3975595b86b\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000020000\nPlaintext: caffc6ac4542de31\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000010000\nPlaintext: 8dd45a2ddf90796c\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000008000\nPlaintext: 1029d55e880ec2d0\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000004000\nPlaintext: 5d86cb23639dbea9\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000002000\nPlaintext: 1d1ca853ae7c0c5f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000001000\nPlaintext: ce332329248f3228\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000800\nPlaintext: 8405d1abe24fb942\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000400\nPlaintext: e643d78090ca4207\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000200\nPlaintext: 48221b9937748a23\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000100\nPlaintext: dd7c0bbd61fafd54\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000080\nPlaintext: 2fbc291a570db5c4\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000040\nPlaintext: e07c30d7e4e26e12\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000020\nPlaintext: 0953e2258e8e90a1\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000010\nPlaintext: 5b711bc4ceebf2ee\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000008\nPlaintext: cc083f1e6d9e85f6\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000004\nPlaintext: d2fd8867d50d2dfe\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000002\nPlaintext: 06e7ea22ce92708f\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0000000000000001\nPlaintext: 166b40b44aba4bd6\n\n# File 2: kat_des/KAT_TDES/TCBCpermop.rsp\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 104691348998013110469134899801311046913489980131\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 88d55e54f54c97b4\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 100710348998802010071034899880201007103489988020\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 0c0cc00c83ea48fd\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 10071034c898012010071034c898012010071034c8980120\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 83bc8ef3a6570183\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 104610348998802010461034899880201046103489988020\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: df725dcad94ea2e9\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 108691151919010110869115191901011086911519190101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: e652b53b550be8b0\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 108691151958010110869115195801011086911519580101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: af527120c485cbb0\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 5107b015195801015107b015195801015107b01519580101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 0f04ce393db926d5\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 1007b015191901011007b015191901011007b01519190101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: c9f00ffc74079067\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 310791549808010131079154980801013107915498080101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 7cfd82a593252b4e\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 310791949808010131079194980801013107919498080101\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: cb49a2f9e91363e3\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 10079115b908014010079115b908014010079115b9080140\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 00b588be70d23f56\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 310791159808014031079115980801403107911598080140\nIV: 0000000000000000\nPlaintext: 0000000000000000\nCiphertext: 406a9a6ab43399ae\n\nCipher: DES-EDE3-CBC\nOperation: ", @@ -2258,9 +2319,9 @@ static const char *kData29[] = { "CRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000020000000\nCiphertext: b160e4680f6c696f\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000010000000\nCiphertext: fa0752b07d9c4ab8\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000008000000\nCiphertext: ca3a2b036dbc8502\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000004000000\nCiphertext: 5e0905517bb59bcf\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000002000000\nCiphertext: 814eeb3b91d90726\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000001000000\nCiphertext: 4d49db1532919c9f\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000800000\nCiphertext: 25eb5fc3f8cf0621\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000400000\nCiphertext: ab6a20c0620d1c6f\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000200000\nCiphertext: 79e90dbc98f92cca\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000100000\nCiphertext: 866ecedd8072bb0e\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000080000\nCiphertext: 8b54536f2f3e64a8\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000040000\nCiphertext: ea51d3975595b86b\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000020000\nCiphertext: caffc6ac4542de31\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000010000\nCiphertext: 8dd45a2ddf90796c\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000008000\nCiphertext: 1029d55e880ec2d0\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000004000\nCiphertext: 5d86cb23639dbea9\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000002000\nCiphertext: 1d1ca853ae7c0c5f\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000001000\nCiphertext: ce332329248f3228\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000800\nCiphertext: 8405d1abe24fb942\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000400\nCiphertext: e643d78090ca4207\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000200\nCiphertext: 48221b9937748a23\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000100\nCiphertext: dd7c0bbd61fafd54\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000080\nCiphertext: 2fbc291a570db5c4\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000040\nCiphertext: e07c30d7e4e26e12\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000020\nCiphertext: 0953e2258e8e90a1\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000010\nCiphertext: 5b711bc4ceebf2ee\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000008\nCiphertext: cc083f1e6d9e85f6\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000004\nCiphertext: d2fd8867d50d2dfe\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000002\nCiphertext: 06e7ea22ce92708f\n\nCipher: DES-EDE3-CBC\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nPlaintext: 0000000000000001\nCiphertext: 166b40b44aba4bd6\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 95f8a5e5dd31d900\nPlaintext: 8000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: dd7f121ca5015619\nPlaintext: 4000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 2e8653104f3834ea\nPlaintext: 2000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 4bd388ff6cd81d4f\nPlaintext: 1000000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 20b9e767b2fb1456\nPlaintext: 0800000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 55579380d77138ef\nPlaintext: 0400000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 6cc5defaaf04512f\nPlaintext: 0200000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0d9f279ba5d87260\nPlaintext: 0100000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: d9031b0271bd5a0a\nPlaintext: 0080000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 424250b37c3dd951\nPlaintext: 0040000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: b8061b7ecd9a21e5\nPlaintext: 0020000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: f15d0f286b65bd28\nPlaintext: 0010000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: add0cc8d6e5deba1\nPlaintext: 0008000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e6d5f82752ad63d1\nPlaintext: 0004000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: ecbfe3bd3f591a5e\nPlaintext: 0002000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: f356834379d165cd\nPlaintext: 0001000000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 2b9f982f20037fa9\nPlaintext: 0000800000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nI", "V: 0000000000000000\nCiphertext: 889de068a16f0be6\nPlaintext: 0000400000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e19e275d846a1298\nPlaintext: 0000200000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 329a8ed523d71aec\nPlaintext: 0000100000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e7fce22557d23c97\nPlaintext: 0000080000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 12a9f5817ff2d65d\nPlaintext: 0000040000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: a484c3ad38dc9c19\nPlaintext: 0000020000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: fbe00a8a1ef8ad72\nPlaintext: 0000010000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 750d079407521363\nPlaintext: 0000008000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 64feed9c724c2faf\nPlaintext: 0000004000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: f02b263b328e2b60\nPlaintext: 0000002000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 9d64555a9a10b852\nPlaintext: 0000001000000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: d106ff0bed5255d7\nPlaintext: 0000000800000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e1652c6b138c64a5\nPlaintext: 0000000400000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e428581186ec8f46\nPlaintext: 0000000200000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: aeb5f5ede22d1a36\nPlaintext: 0000000100000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e943d7568aec0c5c\nPlaintext: 0000000080000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: df98c8276f54b04b\nPlaintext: 0000000040000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: b160e4680f6c696f\nPlaintext: 0000000020000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: fa0752b07d9c4ab8\nPlaintext: 0000000010000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: ca3a2b036dbc8502\nPlaintext: 0000000008000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 5e0905517bb59bcf\nPlaintext: 0000000004000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 814eeb3b91d90726\nPlaintext: 0000000002000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 4d49db1532919c9f\nPlaintext: 0000000001000000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 25eb5fc3f8cf0621\nPlaintext: 0000000000800000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: ab6a20c0620d1c6f\nPlaintext: 0000000000400000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 79e90dbc98f92cca\nPlaintext: 0000000000200000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 866ecedd8072bb0e\nPlaintext: 0000000000100000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 8b54536f2f3e64a8\nPlaintext: 0000000000080000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: ea51d3975595b86b\nPlaintext: 0000000000040000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: caffc6ac4542de31\nPlaintext: 0000000000020000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 8dd45a2ddf90796c\nPlaintext: 0000000000010000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 1029d55e880ec2d0\nPlaintext: 0000000000008000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 5d86cb23639dbea9\nPlaintext: 0000000000004000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 1d1ca853ae7c0c5f\nPlaintext: 0000000000002000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: ce332329248f3228\nPlaintext: 0000000000001000\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 8405d1abe24fb942\nPlaintext: 0000000000000800\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e643d78090ca4207\nPlaintext: 0000000000000400\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 48221b9937748a23\nPlaintext: 0000000000000200\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: dd7c0bbd61fafd54\nPlaintext: 0000000000000100\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 2fbc291a570db5c4\nPlaintext: 0000000000000080\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: e07c30d7e4e26e12\nPlaintext: 0000000000000040\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 0953e2258e8e90a1\nPlaintext: 0000000000000020\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 5b711bc4ceebf2ee\nPlaintext: 0000000000000010\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: cc083f1e6d9e85f6\nPlaintext: 0000000000000008\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: d2fd8867d50d2dfe\nPlaintext: 0000000000000004\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 06e7ea22ce92708f\nPlaintext: 0000000000000002\n\nCipher: DES-EDE3-CBC\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nIV: 0000000000000000\nCiphertext: 166b40b44aba4bd6\nPlaintext: 0000000000000001\n\n", }; -static const size_t kLen30 = 70010; +static const size_t kLen31 = 70010; -static const char *kData30[] = { +static const char *kData31[] = { "# Generated by \"make_cavp -extra-labels Cipher=DES-EDE3 -cipher tdes kat_des/KAT_TDES/TECBinvperm.rsp kat_des/KAT_TDES/TECBpermop.rsp kat_des/KAT_TDES/TECBsubtab.rsp kat_des/KAT_TDES/TECBvarkey.rsp kat_des/KAT_TDES/TECBvartext.rsp\"\n\n# File 1: kat_des/KAT_TDES/TECBinvperm.rsp\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 95f8a5e5dd31d900\nCiphertext: 8000000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: dd7f121ca5015619\nCiphertext: 4000000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 2e8653104f3834ea\nCiphertext: 2000000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 4bd388ff6cd81d4f\nCiphertext: 1000000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 20b9e767b2fb1456\nCiphertext: 0800000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 55579380d77138ef\nCiphertext: 0400000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 6cc5defaaf04512f\nCiphertext: 0200000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0d9f279ba5d87260\nCiphertext: 0100000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: d9031b0271bd5a0a\nCiphertext: 0080000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 424250b37c3dd951\nCiphertext: 0040000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: b8061b7ecd9a21e5\nCiphertext: 0020000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: f15d0f286b65bd28\nCiphertext: 0010000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: add0cc8d6e5deba1\nCiphertext: 0008000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e6d5f82752ad63d1\nCiphertext: 0004000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: ecbfe3bd3f591a5e\nCiphertext: 0002000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: f356834379d165cd\nCiphertext: 0001000000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 2b9f982f20037fa9\nCiphertext: 0000800000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 889de068a16f0be6\nCiphertext: 0000400000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e19e275d846a1298\nCiphertext: 0000200000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 329a8ed523d71aec\nCiphertext: 0000100000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e7fce22557d23c97\nCiphertext: 0000080000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 12a9f5817ff2d65d\nCiphertext: 0000040000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: a484c3ad38dc9c19\nCiphertext: 0000020000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: fbe00a8a1ef8ad72\nCiphertext: 0000010000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 750d079407521363\nCiphertext: 0000008000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 64feed9c724c2faf\nCiphertext: 0000004000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: f02b263b328e2b60\nCiphertext: 0000002000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 9d64555a9a10b852\nCiphertext: 0000001000000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: d106ff0bed5255d7\nCiphertext: 0000000800000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e1652c6b138c64a5\nCiphertext: 0000000400000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e428581186ec8f46\nCiphertext: 0000000200000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: aeb5f5ede22d1a36\nCiphertext: 0000000100000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e943d7568aec0c5c\nCiphertext: 0000000080000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: df98c8276f54b04b\nCiphertext: 0000000040000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: b160e4680f6c696f\nCiphertext: 0000000020000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: fa0752b07d9c4ab8\nCiphertext: 0000000010000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: ca3a2b036dbc8502\nCiphertext: 0000000008000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 5e0905517bb59bcf\nCiphertext: 0000000004000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 814eeb3b91d90726\nCiphertext: 0000000002000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 4d49db1532919c9f\nCiphertext: 0000000001000000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 25eb5fc3f8cf0621\nCiphertext: 0000000000800000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: ab6a20c0620d1c6f\nCiphertext: 0000000000400000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 79e90dbc98f92cca\nCiphertext: 0000000000200000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 866ecedd8072bb0e\nCiphertext: 0000000000100000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 8b54536f2f3e64a8\nCiphertext: 0000000000080000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: ea51d3975595b86b\nCiphertext: 0000000000040000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: caffc6ac4542de31\nCiphertext: 0000000000020000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 8dd45a2ddf90796c\nCiphertext: 0000000000010000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 1029d55e880ec2d0\nCiphertext: 0000000000008000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 5d86cb23639dbea9\nCiphertext: 0000000000004000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 1d1ca853ae7c0c5f\nCiphertext: 0000000000002000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: ce332329248f3228\nCiphertext: 0000000000001000\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 8405d1abe24fb942\nCiphertext: 0000000000000800\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101", "010101010101010101\nPlaintext: e643d78090ca4207\nCiphertext: 0000000000000400\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 48221b9937748a23\nCiphertext: 0000000000000200\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: dd7c0bbd61fafd54\nCiphertext: 0000000000000100\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 2fbc291a570db5c4\nCiphertext: 0000000000000080\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: e07c30d7e4e26e12\nCiphertext: 0000000000000040\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0953e2258e8e90a1\nCiphertext: 0000000000000020\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 5b711bc4ceebf2ee\nCiphertext: 0000000000000010\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: cc083f1e6d9e85f6\nCiphertext: 0000000000000008\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: d2fd8867d50d2dfe\nCiphertext: 0000000000000004\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 06e7ea22ce92708f\nCiphertext: 0000000000000002\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 166b40b44aba4bd6\nCiphertext: 0000000000000001\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 8000000000000000\nPlaintext: 95f8a5e5dd31d900\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 4000000000000000\nPlaintext: dd7f121ca5015619\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 2000000000000000\nPlaintext: 2e8653104f3834ea\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 1000000000000000\nPlaintext: 4bd388ff6cd81d4f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0800000000000000\nPlaintext: 20b9e767b2fb1456\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0400000000000000\nPlaintext: 55579380d77138ef\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0200000000000000\nPlaintext: 6cc5defaaf04512f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0100000000000000\nPlaintext: 0d9f279ba5d87260\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0080000000000000\nPlaintext: d9031b0271bd5a0a\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0040000000000000\nPlaintext: 424250b37c3dd951\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0020000000000000\nPlaintext: b8061b7ecd9a21e5\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0010000000000000\nPlaintext: f15d0f286b65bd28\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0008000000000000\nPlaintext: add0cc8d6e5deba1\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0004000000000000\nPlaintext: e6d5f82752ad63d1\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0002000000000000\nPlaintext: ecbfe3bd3f591a5e\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0001000000000000\nPlaintext: f356834379d165cd\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000800000000000\nPlaintext: 2b9f982f20037fa9\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000400000000000\nPlaintext: 889de068a16f0be6\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000200000000000\nPlaintext: e19e275d846a1298\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000100000000000\nPlaintext: 329a8ed523d71aec\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000080000000000\nPlaintext: e7fce22557d23c97\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000040000000000\nPlaintext: 12a9f5817ff2d65d\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000020000000000\nPlaintext: a484c3ad38dc9c19\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000010000000000\nPlaintext: fbe00a8a1ef8ad72\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000008000000000\nPlaintext: 750d079407521363\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000004000000000\nPlaintext: 64feed9c724c2faf\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000002000000000\nPlaintext: f02b263b328e2b60\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000001000000000\nPlaintext: 9d64555a9a10b852\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000800000000\nPlaintext: d106ff0bed5255d7\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000400000000\nPlaintext: e1652c6b138c64a5\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000200000000\nPlaintext: e428581186ec8f46\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000100000000\nPlaintext: aeb5f5ede22d1a36\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000080000000\nPlaintext: e943d7568aec0c5c\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000040000000\nPlaintext: df98c8276f54b04b\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000020000000\nPlaintext: b160e4680f6c696f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000010000000\nPlaintext: fa0752b07d9c4ab8\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000008000000\nPlaintext: ca3a2b036dbc8502\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000004000000\nPlaintext: 5e0905517bb59bcf\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000002000000\nPlaintext: 814eeb3b91d90726\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000001000000\nPlaintext: 4d49db1532919c9f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000800000\nPlaintext: 25eb5fc3f8cf0621\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000400000\nPlaintext: ab6a20c0620d1c6f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000200000\nPlaintext: 79e90dbc98f92cca\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000100000\nPlaintext: 866ecedd8072bb0e\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000080000\nPlai", "ntext: 8b54536f2f3e64a8\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000040000\nPlaintext: ea51d3975595b86b\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000020000\nPlaintext: caffc6ac4542de31\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000010000\nPlaintext: 8dd45a2ddf90796c\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000008000\nPlaintext: 1029d55e880ec2d0\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000004000\nPlaintext: 5d86cb23639dbea9\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000002000\nPlaintext: 1d1ca853ae7c0c5f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000001000\nPlaintext: ce332329248f3228\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000800\nPlaintext: 8405d1abe24fb942\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000400\nPlaintext: e643d78090ca4207\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000200\nPlaintext: 48221b9937748a23\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000100\nPlaintext: dd7c0bbd61fafd54\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000080\nPlaintext: 2fbc291a570db5c4\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000040\nPlaintext: e07c30d7e4e26e12\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000020\nPlaintext: 0953e2258e8e90a1\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000010\nPlaintext: 5b711bc4ceebf2ee\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000008\nPlaintext: cc083f1e6d9e85f6\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000004\nPlaintext: d2fd8867d50d2dfe\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000002\nPlaintext: 06e7ea22ce92708f\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0000000000000001\nPlaintext: 166b40b44aba4bd6\n\n# File 2: kat_des/KAT_TDES/TECBpermop.rsp\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 104691348998013110469134899801311046913489980131\nPlaintext: 0000000000000000\nCiphertext: 88d55e54f54c97b4\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100710348998802010071034899880201007103489988020\nPlaintext: 0000000000000000\nCiphertext: 0c0cc00c83ea48fd\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 10071034c898012010071034c898012010071034c8980120\nPlaintext: 0000000000000000\nCiphertext: 83bc8ef3a6570183\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 104610348998802010461034899880201046103489988020\nPlaintext: 0000000000000000\nCiphertext: df725dcad94ea2e9\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 108691151919010110869115191901011086911519190101\nPlaintext: 0000000000000000\nCiphertext: e652b53b550be8b0\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 108691151958010110869115195801011086911519580101\nPlaintext: 0000000000000000\nCiphertext: af527120c485cbb0\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 5107b015195801015107b015195801015107b01519580101\nPlaintext: 0000000000000000\nCiphertext: 0f04ce393db926d5\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 1007b015191901011007b015191901011007b01519190101\nPlaintext: 0000000000000000\nCiphertext: c9f00ffc74079067\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 310791549808010131079154980801013107915498080101\nPlaintext: 0000000000000000\nCiphertext: 7cfd82a593252b4e\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 310791949808010131079194980801013107919498080101\nPlaintext: 0000000000000000\nCiphertext: cb49a2f9e91363e3\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 10079115b908014010079115b908014010079115b9080140\nPlaintext: 0000000000000000\nCiphertext: 00b588be70d23f56\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 310791159808014031079115980801403107911598080140\nPlaintext: 0000000000000000\nCiphertext: 406a9a6ab43399ae\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 1007d015899801011007d015899801011007d01589980101\nPlaintext: 0000000000000000\nCiphertext: 6cb773611dca9ada\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 910791158998010191079115899801019107911589980101\nPlaintext: 0000000000000000\nCiphertext: 67fd21c17dbb5d70\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 9107d015891901019107d015891901019107d01589190101\nPlaintext: 0000000000000000\nCiphertext: 9592cb4110430787\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 1007d015989801201007d015989801201007d01598980120\nPlaintext: 0000000000000000\nCiphertext: a6b7ff68a318ddd3\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100794049819010110079404981901011007940498190101\nPlaintext: 0000000000000000\nCiphertext: 4d102196c914ca16\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010791049119040101079104911904010107910491190401\nPlaintext: 0000000000000000\nCiphertext: 2dfa9f4573594965\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010791049119010101079104911901010107910491190101\nPlaintext: 0000000000000000\nCiphertext: b46604816c0e0774\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010794049119040101079404911904010107940491190401\nPlaintext: 0000000000000000\nCiphertext: 6e7e6221a4f34e87\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 19079210981a010119079210981a010119079210981a0101\nPlaintext: 0000000000000000\nCiphertext: aa85e74643233199\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100791199819080110079119981908011007911998190801\nPlaintext: 0000000000000000\nCiphertext: 2e5a19db4d1962d6\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 10079119981a080110079119981a080110079119981a0801\nPlaintext: 0000000000000000\nCiphertext: 23a866a809d30894\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100792109819010110079210981901011007921098190101\nPlaintext: 0000000000000000\nCiphertext: d812d961f017d320\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100791159819010b100791159819010b100791159819010b\nPlaintext: 0000000000000000\nCiphertext: 055605816e58608f\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100480159819010110048015981901011004801598190101\nPlaintext: 0000000000000000\nCiphertext: abd88e8b1b7716f1\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100480159819010210048015981901021004801598190102\nPlaintext: 0000000000000000\nCiphertext: 537ac95be69da1e1\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100480159819010810048015981901081004801598190108\nPlaintext: 0000000000000000\nCiphertext: aed0f6ae3c25cdd8\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100291159810010410029115981001041002911598100104\nPlaintext: 0000000000000000\nCiphertext: b3e35a5ee53e7b8d\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100291159819010410029115981901041002911598190104\nPlaintext: 0000000000000000\nCiphertext: 61c79c71921a2ef8\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100291159810020110029115981002011002911598100201\nPlaintext: 0000000000000000\nCiphertext: e2f5728f0995013c\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 100291169810010110029116981001011002911698100101\nPlaintext: 0000000000000000\nCiphertext: 1aeac39a61f0a464\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 104691348998013110469134899801311046913489980131\nCiphertext: 88d55e54f54c97b4\nPlaintext: 0000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 100710348998802010071034899880201007103489988020\nCiphertext: 0c0cc00c83ea48fd\nPlaintext: 0000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 10071034c898012010071034c898012010071034c8980120\nCiphertext: 83bc8ef3a6570183\nPlaintext: 0000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 104610348998802010461034899880201046103489988020\nCiphertext: df725dcad94ea2e9\nPlaintext: 00", @@ -2271,9 +2332,9 @@ static const char *kData30[] = { "101010101010101010101010101\nPlaintext: 0000000000200000\nCiphertext: 79e90dbc98f92cca\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000100000\nCiphertext: 866ecedd8072bb0e\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000080000\nCiphertext: 8b54536f2f3e64a8\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000040000\nCiphertext: ea51d3975595b86b\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000020000\nCiphertext: caffc6ac4542de31\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000010000\nCiphertext: 8dd45a2ddf90796c\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000008000\nCiphertext: 1029d55e880ec2d0\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000004000\nCiphertext: 5d86cb23639dbea9\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000002000\nCiphertext: 1d1ca853ae7c0c5f\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000001000\nCiphertext: ce332329248f3228\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000800\nCiphertext: 8405d1abe24fb942\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000400\nCiphertext: e643d78090ca4207\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000200\nCiphertext: 48221b9937748a23\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000100\nCiphertext: dd7c0bbd61fafd54\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000080\nCiphertext: 2fbc291a570db5c4\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000040\nCiphertext: e07c30d7e4e26e12\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000020\nCiphertext: 0953e2258e8e90a1\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000010\nCiphertext: 5b711bc4ceebf2ee\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000008\nCiphertext: cc083f1e6d9e85f6\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000004\nCiphertext: d2fd8867d50d2dfe\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000002\nCiphertext: 06e7ea22ce92708f\n\nCipher: DES-EDE3\nOperation: ENCRYPT\nKey: 010101010101010101010101010101010101010101010101\nPlaintext: 0000000000000001\nCiphertext: 166b40b44aba4bd6\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 95f8a5e5dd31d900\nPlaintext: 8000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: dd7f121ca5015619\nPlaintext: 4000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 2e8653104f3834ea\nPlaintext: 2000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 4bd388ff6cd81d4f\nPlaintext: 1000000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 20b9e767b2fb1456\nPlaintext: 0800000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 55579380d77138ef\nPlaintext: 0400000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 6cc5defaaf04512f\nPlaintext: 0200000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0d9f279ba5d87260\nPlaintext: 0100000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: d9031b0271bd5a0a\nPlaintext: 0080000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 424250b37c3dd951\nPlaintext: 0040000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: b8061b7ecd9a21e5\nPlaintext: 0020000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: f15d0f286b65bd28\nPlaintext: 0010000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: add0cc8d6e5deba1\nPlaintext: 0008000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e6d5f82752ad63d1\nPlaintext: 0004000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: ecbfe3bd3f591a5e\nPlaintext: 0002000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: f356834379d165cd\nPlaintext: 0001000000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 2b9f982f20037fa9\nPlaintext: 0000800000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 889de068a16f0be6\nPlaintext: 0000400000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e19e275d846a1298\nPlaintext: 0000200000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 329a8ed523d71aec\nPlaintext: 0000100000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e7fce22557d23c97\nPlaintext: 0000080000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 12a9f5817ff2d65d\nPlaintext: 0000040000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: a484c3ad38dc9c19\nPlaintext: 0000020000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: fbe00a8a1ef8ad72\nPlaintext: 0000010000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 750d079407521363\nPlaintext: 0000008000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 64feed9c724c2faf\nPlaintext: 0000004000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: f02b263b328e2b60\nPlaintext: 0000002000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 9d64555a9a10b852\nPlaintext: 0000001000000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: d106ff0bed5255d7\nPlaintext: 0000000800000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e1652c6b138c64a5\nPlaintext: 0000000400000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e428581186ec8f46\nPlaintext: 0000000200000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: aeb5f5ede22d1a36\nPlaintext: 0000000100000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e943d7568aec0c5c\nPlaintext: 0000000080000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: df98c8276f54", "b04b\nPlaintext: 0000000040000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: b160e4680f6c696f\nPlaintext: 0000000020000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: fa0752b07d9c4ab8\nPlaintext: 0000000010000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: ca3a2b036dbc8502\nPlaintext: 0000000008000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 5e0905517bb59bcf\nPlaintext: 0000000004000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 814eeb3b91d90726\nPlaintext: 0000000002000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 4d49db1532919c9f\nPlaintext: 0000000001000000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 25eb5fc3f8cf0621\nPlaintext: 0000000000800000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: ab6a20c0620d1c6f\nPlaintext: 0000000000400000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 79e90dbc98f92cca\nPlaintext: 0000000000200000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 866ecedd8072bb0e\nPlaintext: 0000000000100000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 8b54536f2f3e64a8\nPlaintext: 0000000000080000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: ea51d3975595b86b\nPlaintext: 0000000000040000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: caffc6ac4542de31\nPlaintext: 0000000000020000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 8dd45a2ddf90796c\nPlaintext: 0000000000010000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 1029d55e880ec2d0\nPlaintext: 0000000000008000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 5d86cb23639dbea9\nPlaintext: 0000000000004000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 1d1ca853ae7c0c5f\nPlaintext: 0000000000002000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: ce332329248f3228\nPlaintext: 0000000000001000\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 8405d1abe24fb942\nPlaintext: 0000000000000800\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e643d78090ca4207\nPlaintext: 0000000000000400\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 48221b9937748a23\nPlaintext: 0000000000000200\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: dd7c0bbd61fafd54\nPlaintext: 0000000000000100\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 2fbc291a570db5c4\nPlaintext: 0000000000000080\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: e07c30d7e4e26e12\nPlaintext: 0000000000000040\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 0953e2258e8e90a1\nPlaintext: 0000000000000020\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 5b711bc4ceebf2ee\nPlaintext: 0000000000000010\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: cc083f1e6d9e85f6\nPlaintext: 0000000000000008\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: d2fd8867d50d2dfe\nPlaintext: 0000000000000004\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 06e7ea22ce92708f\nPlaintext: 0000000000000002\n\nCipher: DES-EDE3\nOperation: DECRYPT\nKey: 010101010101010101010101010101010101010101010101\nCiphertext: 166b40b44aba4bd6\nPlaintext: 0000000000000001\n\n", }; -static const size_t kLen31 = 444193; +static const size_t kLen32 = 444193; -static const char *kData31[] = { +static const char *kData32[] = { "# The contents of this file were generated from\n# http://ed25519.cr.yp.to/python/sign.input using the following Python script:\n#\n# import sys\n#\n# isFirst = True\n#\n# for line in sys.stdin.readlines():\n# (private, public, message, sig_and_message, _) = line.split(':')\n#\n# if not isFirst:\n# print\n# print \"PRIV:\", private\n# print \"PUB:\", public\n# print \"MESSAGE:\", message\n# print \"SIG:\", sig_and_message[:128]\n# isFirst = False\n\nPRIV: 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nPUB: d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nMESSAGE: \nSIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nPRIV: 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\nPUB: 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\nMESSAGE: 72\nSIG: 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nPRIV: c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\nPUB: fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\nMESSAGE: af82\nSIG: 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nPRIV: 0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057\nPUB: e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057\nMESSAGE: cbc77b\nSIG: d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c\n\nPRIV: 6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebbc0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7\nPUB: c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7\nMESSAGE: 5f4c8989\nSIG: 124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07\n\nPRIV: b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293ce253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01\nPUB: e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01\nMESSAGE: 18b6bec097\nSIG: b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09\n\nPRIV: 78ae9effe6f245e924a7be63041146ebc670dbd3060cba67fbc6216febc44546fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d\nPUB: fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d\nMESSAGE: 89010d855972\nSIG: 6ed629fc1d9ce9e1468755ff636d5a3f40a5d9c91afd93b79d241830f7e5fa29854b8f20cc6eecbb248dbd8d16d14e99752194e4904d09c74d639518839d2300\n\nPRIV: 691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f7998a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63\nPUB: 98a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63\nMESSAGE: b4a8f381e70e7a\nSIG: 6e0af2fe55ae377a6b7a7278edfb419bd321e06d0df5e27037db8812e7e3529810fa5552f6c0020985ca17a0e02e036d7b222a24f99b77b75fdd16cb05568107\n\nPRIV: 3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863\nPUB: f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863\nMESSAGE: 4284abc51bb67235\nSIG: d6addec5afb0528ac17bb178d3e7f2887f9adbb1ad16e110545ef3bc57f9de2314a5c8388f723b8907be0f3ac90c6259bbe885ecc17645df3db7d488f805fa08\n\nPRIV: edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd\nPUB: c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd\nMESSAGE: 672bf8965d04bc5146\nSIG: 2c76a04af2391c147082e33faacdbe56642a1e134bd388620b852b901a6bc16ff6c9cc9404c41dea12ed281da067a1513866f9d964f8bdd24953856c50042901\n\nPRIV: 4e7d21fb3b1897571a445833be0f9fd41cd62be3aa04040f8934e1fcbdcacd4531b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff\nPUB: 31b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff\nMESSAGE: 33d7a786aded8c1bf691\nSIG: 28e4598c415ae9de01f03f9f3fab4e919e8bf537dd2b0cdf6e79b9e6559c9409d9151a4c40f083193937627c369488259e99da5a9f0a87497fa6696a5dd6ce08\n\nPRIV: a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb644b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f\nPUB: 44b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f\nMESSAGE: 3486f68848a65a0eb5507d\nSIG: 77d389e599630d934076329583cd4105a649a9292abc44cd28c40000c8e2f5ac7660a81c85b72af8452d7d25c070861dae91601c7803d656531650dd4e5c4100\n\nPRIV: 5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef96fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257\nPUB: 6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257\nMESSAGE: 5a8d9d0a22357e6655f9c785\nSIG: 0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e\n\nPRIV: 940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd\nPUB: a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd\nMESSAGE: b87d3813e03f58cf19fd0b6395\nSIG: d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c\n\nPRIV: 9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291\nPUB: cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291\nMESSAGE: 55c7fa434f5ed8cdec2b7aeac173\nSIG: 6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06\n\nPRIV: d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5\nPUB: fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5\nMESSAGE: 0a688e79be24f866286d4646b5d81c\nSIG: f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f35503951fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00\n\nPRIV: 0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b\nPUB: 34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b\nMESSAGE: c942fa7ac6b23ab7ff612fdc8e68ef39\nSIG: 2a3d27dc40d0a8127949a3b7f908b3688f63b7f14f651aacd715940bdbe27a0809aac142f47ab0e1e44fa490ba87ce5392f33a891539caf1ef4c367cae54500c\n\nPRIV: f8148f7506b775ef46fdc8e8c756516812d47d6cfbfa318c27c9a22641e56f170445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372\nPUB: 0445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372\nMESSAGE: 7368724a5b0efb57d28d97622dbde725af\nSIG: 3653ccb21219202b8436fb41a32ba2618c4a133431e6e63463ceb3b6106c4d56e1d2ba165ba76eaad3dc39bffb130f1de3d8e6427db5b71938db4e272bc3e20b\n\nPRIV: 77f88691c4eff23ebb7364947092951a5ff3f10785b417e918823a552dab7c7574d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b\nPUB: 74d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b\nMESSAGE: bd8e05033f3a8bcdcbf4beceb70901c82e31\nSIG: fbe929d743a03c17910575492f3092ee2a2bf14a60a3fcacec74a58c7334510fc262db582791322d6c8c41f1700adb80027ecabc14270b703444ae3ee7623e0a\n\nPRIV: ab6f7aee6a0837b334ba5eb1b2ad7fcecfab7e323cab187fe2e0a95d80eff1325b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c\nPUB: 5b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c\nMESSAGE: 8171456f8b907189b1d779e26bc5afbb08c67a\nSIG: 73bca64e9dd0db88138eedfafcea8f5436cfb74bfb0e7733cf349baa0c49775c56d5934e1d38e36f39b7c5beb0a836510c45126f8ec4b6810519905b0ca07c09\n\nPRIV: 8d135de7c8411bbdbd1b31e5dc678f2ac7109e792b60f38cd24936e8a898c32d1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f\nPUB: 1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f\nMESSAGE: 8ba6a4c9a15a244a9c26bb2a59b1026f21348b49\nSIG: a1adc2bc6a2d980662677e7fdff6424de7dba50f5795ca90fdf3e96e256f3285cac71d3360482e993d0294ba4ec7440c61affdf35f", "e83e6e04263937db93f105\n\nPRIV: 0e765d720e705f9366c1ab8c3fa84c9a44370c06969f803296884b2846a652a47fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8\nPUB: 7fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8\nMESSAGE: 1d566a6232bbaab3e6d8804bb518a498ed0f904986\nSIG: bb61cf84de61862207c6a455258bc4db4e15eea0317ff88718b882a06b5cf6ec6fd20c5a269e5d5c805bafbcc579e2590af414c7c227273c102a10070cdfe80f\n\nPRIV: db36e326d676c2d19cc8fe0c14b709202ecfc761d27089eb6ea4b1bb021ecfa748359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85\nPUB: 48359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85\nMESSAGE: 1b0afb0ac4ba9ab7b7172cddc9eb42bba1a64bce47d4\nSIG: b6dcd09989dfbac54322a3ce87876e1d62134da998c79d24b50bd7a6a797d86a0e14dc9d7491d6c14a673c652cfbec9f962a38c945da3b2f0879d0b68a921300\n\nPRIV: c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c\nPUB: fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c\nMESSAGE: 507c94c8820d2a5793cbf3442b3d71936f35fe3afef316\nSIG: 7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c\n\nPRIV: 4e62627fc221142478aee7f00781f817f662e3b75db29bb14ab47cf8e84104d6b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107\nPUB: b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107\nMESSAGE: d3d615a8472d9962bb70c5b5466a3d983a4811046e2a0ef5\nSIG: 836afa764d9c48aa4770a4388b654e97b3c16f082967febca27f2fc47ddfd9244b03cfc729698acf5109704346b60b230f255430089ddc56912399d1122de70a\n\nPRIV: 6b83d7da8908c3e7205b39864b56e5f3e17196a3fc9c2f5805aad0f5554c142dd0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6\nPUB: d0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6\nMESSAGE: 6ada80b6fa84f7034920789e8536b82d5e4678059aed27f71c\nSIG: 16e462a29a6dd498685a3718b3eed00cc1598601ee47820486032d6b9acc9bf89f57684e08d8c0f05589cda2882a05dc4c63f9d0431d6552710812433003bc08\n\nPRIV: 19a91fe23a4e9e33ecc474878f57c64cf154b394203487a7035e1ad9cd697b0d2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23\nPUB: 2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23\nMESSAGE: 82cb53c4d5a013bae5070759ec06c3c6955ab7a4050958ec328c\nSIG: 881f5b8c5a030df0f75b6634b070dd27bd1ee3c08738ae349338b3ee6469bbf9760b13578a237d5182535ede121283027a90b5f865d63a6537dca07b44049a0f\n\nPRIV: 1d5b8cb6215c18141666baeefcf5d69dad5bea9a3493dddaa357a4397a13d4de94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835\nPUB: 94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835\nMESSAGE: a9a8cbb0ad585124e522abbfb40533bdd6f49347b55b18e8558cb0\nSIG: 3acd39bec8c3cd2b44299722b5850a0400c1443590fd4861d59aae7496acb3df73fc3fdf7969ae5f50ba47dddc435246e5fd376f6b891cd4c2caf5d614b6170c\n\nPRIV: 6a91b3227c472299089bdce9356e726a40efd840f11002708b7ee55b64105ac29d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e\nPUB: 9d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e\nMESSAGE: 5cb6f9aa59b80eca14f6a68fb40cf07b794e75171fba96262c1c6adc\nSIG: f5875423781b66216cb5e8998de5d9ffc29d1d67107054ace3374503a9c3ef811577f269de81296744bd706f1ac478caf09b54cdf871b3f802bd57f9a6cb9101\n\nPRIV: 93eaa854d791f05372ce72b94fc6503b2ff8ae6819e6a21afe825e27ada9e4fb16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5\nPUB: 16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5\nMESSAGE: 32fe27994124202153b5c70d3813fdee9c2aa6e7dc743d4d535f1840a5\nSIG: d834197c1a3080614e0a5fa0aaaa808824f21c38d692e6ffbd200f7dfb3c8f44402a7382180b98ad0afc8eec1a02acecf3cb7fde627b9f18111f260ab1db9a07\n\nPRIV: 941cac69fb7b1815c57bb987c4d6c2ad2c35d5f9a3182a79d4ba13eab253a8ad23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b\nPUB: 23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b\nMESSAGE: bb3172795710fe00054d3b5dfef8a11623582da68bf8e46d72d27cece2aa\nSIG: 0f8fad1e6bde771b4f5420eac75c378bae6db5ac6650cd2bc210c1823b432b48e016b10595458ffab92f7a8989b293ceb8dfed6c243a2038fc06652aaaf16f02\n\nPRIV: 1acdbb793b0384934627470d795c3d1dd4d79cea59ef983f295b9b59179cbb283f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a\nPUB: 3f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a\nMESSAGE: 7cf34f75c3dac9a804d0fcd09eba9b29c9484e8a018fa9e073042df88e3c56\nSIG: be71ef4806cb041d885effd9e6b0fbb73d65d7cdec47a89c8a994892f4e55a568c4cc78d61f901e80dbb628b86a23ccd594e712b57fa94c2d67ec26634878507\n\nPRIV: 8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9\nPUB: b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9\nMESSAGE: a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3\nSIG: 04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b\n\nPRIV: f2ab396fe8906e3e5633e99cabcd5b09df0859b516230b1e0450b580b65f616c8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b\nPUB: 8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b\nMESSAGE: 5a44e34b746c5fd1898d552ab354d28fb4713856d7697dd63eb9bd6b99c280e187\nSIG: a06a23d982d81ab883aae230adbc368a6a9977f003cebb00d4c2e4018490191a84d3a282fdbfb2fc88046e62de43e15fb575336b3c8b77d19ce6a009ce51f50c\n\nPRIV: 550a41c013f79bab8f06e43ad1836d51312736a9713806fafe6645219eaa1f9daf6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0\nPUB: af6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0\nMESSAGE: 8bc4185e50e57d5f87f47515fe2b1837d585f0aae9e1ca383b3ec908884bb900ff27\nSIG: 16dc1e2b9fa909eefdc277ba16ebe207b8da5e91143cde78c5047a89f681c33c4e4e3428d5c928095903a811ec002d52a39ed7f8b3fe1927200c6dd0b9ab3e04\n\nPRIV: 19ac3e272438c72ddf7b881964867cb3b31ff4c793bb7ea154613c1db068cb7ef85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f\nPUB: f85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f\nMESSAGE: 95872d5f789f95484e30cbb0e114028953b16f5c6a8d9f65c003a83543beaa46b38645\nSIG: ea855d781cbea4682e350173cb89e8619ccfddb97cdce16f9a2f6f6892f46dbe68e04b12b8d88689a7a31670cdff409af98a93b49a34537b6aa009d2eb8b4701\n\nPRIV: ca267de96c93c238fafb1279812059ab93ac03059657fd994f8fa5a09239c821017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26\nPUB: 017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26\nMESSAGE: e05f71e4e49a72ec550c44a3b85aca8f20ff26c3ee94a80f1b431c7d154ec9603ee02531\nSIG: ac957f82335aa7141e96b59d63e3ccee95c3a2c47d026540c2af42dc9533d5fd81827d1679ad187aeaf37834915e75b147a9286806c8017516ba43dd051a5e0c\n\nPRIV: 3dff5e899475e7e91dd261322fab09980c52970de1da6e2e201660cc4fce7032f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b\nPUB: f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b\nMESSAGE: 938f0e77621bf3ea52c7c4911c5157c2d8a2a858093ef16aa9b107e69d98037ba139a3c382\nSIG: 5efe7a92ff9623089b3e3b78f352115366e26ba3fb1a416209bc029e9cadccd9f4affa333555a8f3a35a9d0f7c34b292cae77ec96fa3adfcaadee2d9ced8f805\n\nPRIV: 9a6b847864e70cfe8ba6ab22fa0ca308c0cc8bec7141fbcaa3b81f5d1e1cfcfc34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930\nPUB: 34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930\nMESSAGE: 838367471183c71f7e717724f89d401c3ad9863fd9cc7aa3cf33d3c529860cb581f3093d87da\nSIG: 2ab255169c489c54c732232e37c87349d486b1eba20509dbabe7fed329ef08fd75ba1cd145e67b2ea26cb5cc51cab343eeb085fe1fd7b0ec4c6afcd9b979f905\n\nPRIV: 575be07afca5d063c238cd9b8028772cc49cda34471432a2e166e096e2219efc94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0\nPUB: 94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0\nMESSAGE: 33e5918b66d33d55fe717ca34383eae78f0af82889caf6696e1ac9d95d1ffb32cba755f9e3503e\nSIG: 58271d44236f3b98c58fd7ae0d2f49ef2b6e3affdb225aa3ba555f0e11cc53c23ad19baf24346590d05d7d5390582082cf94d39cad6530ab93d13efb39279506\n\nPRIV: 15ffb45514d43444d61fcb105e30e135fd268523dda20b82758b1794231104411772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8\nPUB: 1772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8\nMESSAGE: da9c5559d0ea51d255b6bd9d7638b876472f942b330fc0e2b30aea68d77368fce4948272991d257e\nSIG: 6828cd7624e793b8a4ceb96d3c2a975bf773e5ff6645f353614058621e58835289e7f31f42dfe6", "af6d736f2644511e320c0fa698582a79778d18730ed3e8cb08\n\nPRIV: fe0568642943b2e1afbfd1f10fe8df87a4236bea40dce742072cb21886eec1fa299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61\nPUB: 299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61\nMESSAGE: c59d0862ec1c9746abcc3cf83c9eeba2c7082a036a8cb57ce487e763492796d47e6e063a0c1feccc2d\nSIG: d59e6dfcc6d7e3e2c58dec81e985d245e681acf6594a23c59214f7bed8015d813c7682b60b3583440311e72a8665ba2c96dec23ce826e160127e18132b030404\n\nPRIV: 5ecb16c2df27c8cf58e436a9d3affbd58e9538a92659a0f97c4c4f994635a8cada768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d\nPUB: da768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d\nMESSAGE: 56f1329d9a6be25a6159c72f12688dc8314e85dd9e7e4dc05bbecb7729e023c86f8e0937353f27c7ede9\nSIG: 1c723a20c6772426a670e4d5c4a97c6ebe9147f71bb0a415631e44406e290322e4ca977d348fe7856a8edc235d0fe95f7ed91aefddf28a77e2c7dbfd8f552f0a\n\nPRIV: d599d637b3c30a82a9984e2f758497d144de6f06b9fba04dd40fd949039d7c846791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f\nPUB: 6791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f\nMESSAGE: a7c04e8ba75d0a03d8b166ad7a1d77e1b91c7aaf7befdd99311fc3c54a684ddd971d5b3211c3eeaff1e54e\nSIG: ebf10d9ac7c96108140e7def6fe9533d727646ff5b3af273c1df95762a66f32b65a09634d013f54b5dd6011f91bc336ca8b355ce33f8cfbec2535a4c427f8205\n\nPRIV: 30ab8232fa7018f0ce6c39bd8f782fe2e159758bb0f2f4386c7f28cfd2c85898ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37\nPUB: ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37\nMESSAGE: 63b80b7956acbecf0c35e9ab06b914b0c7014fe1a4bbc0217240c1a33095d707953ed77b15d211adaf9b97dc\nSIG: 9af885344cc7239498f712df80bc01b80638291ed4a1d28baa5545017a72e2f65649ccf9603da6eb5bfab9f5543a6ca4a7af3866153c76bf66bf95def615b00c\n\nPRIV: 0ddcdc872c7b748d40efe96c2881ae189d87f56148ed8af3ebbbc80324e38bdd588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85\nPUB: 588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85\nMESSAGE: 65641cd402add8bf3d1d67dbeb6d41debfbef67e4317c35b0a6d5bbbae0e034de7d670ba1413d056f2d6f1de12\nSIG: c179c09456e235fe24105afa6e8ec04637f8f943817cd098ba95387f9653b2add181a31447d92d1a1ddf1ceb0db62118de9dffb7dcd2424057cbdff5d41d0403\n\nPRIV: 89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832\nPUB: aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832\nMESSAGE: 4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c91411388bc7653e2d893d1eac2107d05\nSIG: 2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf753582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b\n\nPRIV: 0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b172e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01\nPUB: 72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01\nMESSAGE: 4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722cdead7d22aaead2bfaa1ad00b82957\nSIG: 87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05\n\nPRIV: c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab2390d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f\nPUB: 90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f\nMESSAGE: 783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89e38cfd3b4d0885661ca547fb9764abff\nSIG: fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe605fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b\n\nPRIV: b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429fffd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad\nPUB: fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad\nMESSAGE: 29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cbd771e184a9a75f316b648c6920db92b87b\nSIG: 58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb979666828f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607\n\nPRIV: 84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a22c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea\nPUB: 2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea\nMESSAGE: f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff724ff47d29344391dc536166b8671cbbf123\nSIG: 69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d3829d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500\n\nPRIV: b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeeceb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f\nPUB: eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f\nMESSAGE: 19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a30f7de9e5da4108c52a4ce70a3e114a52a3b3c5\nSIG: c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802\n\nPRIV: 960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c05e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a\nPUB: 5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a\nMESSAGE: f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d818357db938eac73e0af6d31206b3948f8c48a447308\nSIG: 27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01\n\nPRIV: eb77b2638f23eebc82efe45ee9e5a0326637401e663ed029699b21e6443fb48e9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc\nPUB: 9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc\nMESSAGE: 99e3d00934003ebafc3e9fdb687b0f5ff9d5782a4b1f56b9700046c077915602c3134e22fc90ed7e690fddd4433e2034dcb2dc99ab\nSIG: 18dc56d7bd9acd4f4daa78540b4ac8ff7aa9815f45a0bba370731a14eaabe96df8b5f37dbf8eae4cb15a64b244651e59d6a3d6761d9e3c50f2d0cbb09c05ec06\n\nPRIV: b625aa89d3f7308715427b6c39bbac58effd3a0fb7316f7a22b99ee5922f2dc965a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e\nPUB: 65a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e\nMESSAGE: e07241dbd3adbe610bbe4d005dd46732a4c25086ecb8ec29cd7bca116e1bf9f53bfbf3e11fa49018d39ff1154a06668ef7df5c678e6a\nSIG: 01bb901d83b8b682d3614af46a807ba2691358feb775325d3423f549ff0aa5757e4e1a74e9c70f9721d8f354b319d4f4a1d91445c870fd0ffb94fed64664730d\n\nPRIV: b1c9f8bd03fe82e78f5c0fb06450f27dacdf716434db268275df3e1dc177af427fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf\nPUB: 7fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf\nMESSAGE: 331da7a9c1f87b2ac91ee3b86d06c29163c05ed6f8d8a9725b471b7db0d6acec7f0f702487163f5eda020ca5b493f399e1c8d308c3c0c2\nSIG: 4b229951ef262f16978f7914bc672e7226c5f8379d2778c5a2dc0a2650869f7acfbd0bcd30fdb0619bb44fc1ae5939b87cc318133009c20395b6c7eb98107701\n\nPRIV: 6d8cdb2e075f3a2f86137214cb236ceb89a6728bb4a200806bf3557fb78fac6957a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda\nPUB: 57a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda\nMESSAGE: 7f318dbd121c08bfddfeff4f6aff4e45793251f8abf658403358238984360054f2a862c5bb83ed89025d2014a7a0cee50da3cb0e76bbb6bf\nSIG: a6cbc947f9c87d1455cf1a708528c090f11ecee4855d1dbaadf47454a4de55fa4ce84b36d73a5b5f8f59298ccf21992df492ef34163d87753b7e9d32f2c3660b\n\nPRIV: 47adc6d6bf571ee9570ca0f75b604ac43e303e4ab339ca9b53cacc5be45b2ccba3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be\nPUB: a3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be\nMESSAGE: ce497c5ff5a77990b7d8f8699eb1f5d8c0582f70cb7ac5c54d9d924913278bc654d37ea227590e15202217fc98dac4c0f3be2183d133315739\nSIG: 4e8c318343c306adbba60c92b75cb0569b9219d8a86e5d57752ed235fc109a43c2cf4e942cacf297279fbb28675347e08027722a4eb7395e00a17495d32edf0b\n\nPRIV: 3c19b50b0fe47961719c381d0d8da9b9869d312f13e3298b97fb22f0af29cbbe0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612\nPUB: 0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612\nMESSAGE: 8ddcd63043f55ec3bfc83dceae69d8f8b32f4cdb6e2aebd94b4314f8fe7287dcb62732c9052e7557fe63534338efb5b6254c5d41d2690cf5144f\nSIG: efbd41f26a5d62685516f882b6ec74e0d5a71830d203c231248f26e99a9c6578ec900d68cdb8fa7216ad0d24f9ecbc9ffa655351666582f626645395a31fa704\n\nPRIV: 34e1e9d539107eb86b393a5ccea1496d35bc7d5e9a8c5159d957", @@ -2330,55 +2391,9 @@ static const char *kData31[] = { "28bb92e9a0edec8951ce2009a88ee1b64d9b9e89f69051203384210a102a44d2d6703173b68507dceadd3bf6510df2a5cefd9c80e4f385b2f9e6215813ed32\nSIG: 9da60cc4a64d07dee1346bd3d3010995ce2738208ab35b34c2a8fd1787ae3a1e207fe784525154fae4f5794cd8503045fea85cf77fd92f6a70cd0c5a52c0810e\n\nPRIV: 1126496a582ce58d3d618dd8a3933547aa7a8a30fb54063b8dfdd31671c6c73de10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22\nPUB: e10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22\nMESSAGE: 6a4b52d730ddab829b2a179590cbd4c372498e9f439977c0a10dc13c0ae1736eaaff063371434fd0da80360ec5890607d2fae1c9a2e1ab0b7f3d667f5b1b9c418f18b10c9e6fd669d3ebec168efef44163e577a2ebd0f2cb768f80c23188e86069e4d10f410306cedd7a341a61e0f4f3bc25041bc2f922ed073e1e2f1b709c579d10630f33071754d707894a1c62190de18882c564dc4c01dc545dd8966404ed78fa3267a9469f63b6120abb65f9b3ba3eee28d79c2eb4e7020cc6987dfc5c29672f8c0fa3e690d584fe000c64f352610179621bfd5ff3eb30d18f1a0250416db93b1c1e93cf8a3646517560d1cc8fff822b51ef27b200e987b592390753453ef138bd3d29db7cb1b5f45e4795b89c53f49704192752237c6ab274849f9594ee9777f6efe70483129d067f97199d9ae36090703864f7ca4750a6f3b6ff83824c910484394d1e2eceba18446fe4e994ce07433a740ddd05f0e396d482894e6f14acf7b97bae6c7eb88703039fa785d60a3af78b13243a4f88dde1d998617f2e3fa7eafc2f435dd4ac1ea9c238407aa09b4eea8ed434927b406674ac270458cfb3bf29c347f94559613179b9502192321b88e9af0a90e9a4ab9eddaae382e3734d1415ebe32499c34e6fdeaf15b0d9787985e08dfe495460c54f6743d81ff16881e5e30c51f4b092373783f12423c3e1ae8591130a269980caa1cb5c\nSIG: b30eb56ca9b120bf849a3a9d56af033de8a590c9e1240c1e36dbc6cf0a71b78a11ec143fb9959a8f25b57711d6a90a67e01be3a4da2b69394869bb8d64b87e0f\n\nPRIV: 9c167aff3b1b788f133d422de8ca9a64316409f9e35bfe22032ec417ae9abc6defb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019\nPUB: efb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019\nMESSAGE: 68ac0fc2b607ba38e377fae845c808c8f9fa614eb1f31158a9620a937d3e301e85acaa69144bc349a39dfb582041c4a197ae99b4d4d59b7a2ca3d16228b5591cbf57c18a781efd19193c47b16c6023a3a8ba3d668f05a37f1e83b0d7febdd10f63e48ef7a20e015b1c6725d4c300a986c60e3a115469c8e52ba05b51c05d0af40d89fd9ed76f36950aee3c7819898a903cfe0361a91c69100b495141e86ee79d63d17403fb1a1629ef63cb7e9d2720cbfff0002b190bcdc26794124dd38d42bcaa7175405eb0bbcf8e37d65d05a37195b479371fa2bbbb167d91cee88235dd72ea88fc73ce3ce43d33b715f25f192ec215dac124899c5e7586e86340d8cbe53735defbe02e4cc9fde69fb9794d1db72b98c0f19766ee5138bbfa78909aa299b4913c499deaf54b4841d5044829984936700dcf92f36542b2fc7e86441b9925f5d0b78c17a85cfcfcb20b0fd751349c27463abde4d27df74265288713f96dea013b945521808b4996b1b2dc0338b6d236efd6d2b27dafda46ec5fa32b965e8bb5e8bb61bd966edeb774681e0ea8c17b8c99fa7d660f0f66c9bc6d95cbd7dc094724098eb05191b53a3df6566b9c90e0d7dff2943848b61a20d48c22b6d3c958e293d709c8f48110230ff51918562877daf6d920c85a82e07c451fe7ae9759c0a77e97bb298b5d0592a41d08f67a4ed5a1bb41e937b6a68aeb38fd5be9\nSIG: c9ae67fd6415dcbab292fab394ca6c3b7d90ca244dc6a7764e74fd202bf4b2905bd2030e6beb914c3c238db371b1cba6d9261aa392ec871a4b8b12fe9c1c970e\n\nPRIV: e9948805eb341b2867479c668fd3532c309941c0ad4cb2e54231756e6a1bdecb5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1\nPUB: 5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1\nMESSAGE: 91cffd7eb1cf6bd4756bce6a30af9dfba26ddd1cce0394c194a3e39cc3d1cbc221b7eb70bea18d29c267457176a3c9e53c18e47d10a67c464505197702e6b2470d38869db5174b158f9992e4435d02246f540258dedd3ce33df582555a681fb76ecaccb1c2989b177e3b7e454aaa529de59bf5a03123d571df2e7f7cb830805c58b74a653bac0e5a888e08dc2236d6cd496aa06d0d67cf3b335e218c49dedad82fc1be9ef20cac61905c30eb132d739b16ca8a8c906619c0e0d8b33985327e36f3d4b8fda387c186cc50443104db761f7ff9301270204a713e58902101fad000ce931647c577fdec148dca95cdc08918ebed037c60332fadf088f036083ebc92e173b7ddcc30c493f27e69cd17a20d30b78f83a72e4f5a747d86d96c5e1bb7a438166204013e2164d6aabc0d562f54015c365c80445607145e5692ee34f6353077fab7452d88ce3eb01d2b3797dc91b341a3a726301516baae18e851f74dfbdf0866bb2376867de55231e362c472c52116544cd4f81e93571c4ec820e7e653f4e21be0a942576c9de91e7d1251683d859de448f822dcf3d2cf55ede2f9c71b6063d1373061f8f5936b698d1384e65459ea2bc26ec96775ef425207432dda0ac1fe28526c5e4559349c3d8df9918230f4044683cc2c1b858d141ab8d0805bb9336067522aa89c810f3eaa7ac2d8dd28c3751225a19ecec8bcca52439946\nSIG: d3dc62d6ce9c766f2abaf9a7fbe09d6bdb07a4747b56080db09beb4a4e804a70d7ddf4119475c7be834f31956f4a71dad029cdf2363dd0365ce22dc27f078003\n\nPRIV: b01753efa73bb3de7aa778be7afcbff66a5d3e2c2f8b5aa2b048844050996965d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158\nPUB: d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158\nMESSAGE: 684e612f27eead0d34844cc81ba911c28aaf6d66e71229e8cc3462f7c7a050daa30cb74471150f07dad459b5a91358476c0598255d8a642dd7c0802811bd88e4cac597efe41ebd96cd0f3b5ce72db4be1a3dbd6b84f5446e3da600d3b1d2b460a009bd31cacd98a91518ce33e9a703d404288736ccc43103fc69e67974f31652fa3dadef3337f6c897a3d201303c8f03597b4a87c98f291ccd58a3f1e898332aa5993b47fcb5ddaa1c0868b643742d0e4a4b9cd427038b3b74999bc89ac3484c0ca13f25aae8e78ae1ccee6218accab81a4f694f5324a347629d49b55e4037504a9acc8df58c6841dddcd4fc4347f7b6f1fd9de0564577e6f329ed951a0a6b9124ff63e22eb36d3a8863bc1bf69cea24c605967e7d8948953f27d5c4c75f0849f872a3e3d16d422fa5a11e1b9a74df6f38b90f277d81fce8437a14d99d2bef189d7cac83ddc61377ed348b3c4fc09ec2b9005925d04a71e26d641667bdf549294331c6ea01cd5c0bd1b6a7ecfda20b0f1929582b74697cb262c3927d6b223f4b5f3043aa6eb4571a78e9da11c2b36f64552580caa7b5fa6b90f929e0162e608d1240d7242cd2f47025c03debe059b1dc94770232bc6765148480bb1d9f50da1ee6448cf9c88b19dd459932c06ed811c4a64a12d5938bd1c757bcfaeaee8933fe5fff21763de740482bcf1ba59afdc8fcf873c3d507bb394e32e45f736519\nSIG: 16b7421227ae09130685cbb1a0c60aa57a5e1afe1bbe6bacea0c281bcc8998e6824a772c3208a6b6b4d236695505c9be82700cf93a783985a39e16e377a7410e\n\nPRIV: 4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357\nPUB: c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357\nMESSAGE: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb\nSIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02\n\n\n# Additional test vectors from RFC 8032\n\nPRIV: f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\nPUB: 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\nMESSAGE: 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc27", "32e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nSIG: 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nPRIV: 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\nPUB: ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\nMESSAGE: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nSIG: dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n", }; -static const size_t kLen32 = 41961; - -static const char *kData32[] = { - "# This file has been modified to remove the 65536-byte long inputs.\r\n\r\n# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = TDES KeySize = 3 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:47 2011\r\n\r\n\r\nCount = 0\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 3bb96170d5df4cce\r\nKey2 = 25d5daa22a982f08\r\nKey3 = 52f4a110dcdc9e45\r\nMsg = 00\r\nMac = 96\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 1\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 9413d38685688f58\r\nKey2 = dc38b6b3cef125f1\r\nKey3 = 5b61f4f7a1c46ed6\r\nMsg = 00\r\nMac = fc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 2\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 101a2f13fbb69473\r\nKey2 = 76fb98f24073f4d5\r\nKey3 = 2ca2706d76d00b67\r\nMsg = 00\r\nMac = 53\r\nResult = P\r\n\r\nCount = 3\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 2f8a238552c1e367\r\nKey2 = f8131f1c26ab3289\r\nKey3 = 83d5b6ba253bea31\r\nMsg = 00\r\nMac = 95\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 4\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c1bafb5dc7100758\r\nKey2 = e9ef047a58b5ba89\r\nKey3 = 76cb4fb55ebcc1c7\r\nMsg = 00\r\nMac = f4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 5\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c82c29f1cb5851b6\r\nKey2 = 8b5b45dcbf0d8079\r\nKey3 = e6407057ae34ec0b\r\nMsg = 00\r\nMac = 03\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 6\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 6b455116f4f883d5\r\nKey2 = a81a206d25152aab\r\nKey3 = 86dc07b607202abc\r\nMsg = 00\r\nMac = 75\r\nResult = P\r\n\r\nCount = 7\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c873d5bc4598d0b0\r\nKey2 = 1c1523cb4f794c8a\r\nKey3 = cedf6797d523dcab\r\nMsg = 00\r\nMac = 2e\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 8\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 45ce943bd31fe9b5\r\nKey2 = 677cc47c13c24923\r\nKey3 = 6b2086f14934838a\r\nMsg = 00\r\nMac = 01\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 9\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 804f9ef7baf7dfc7\r\nKey2 = 9bb6494cb60b8c07\r\nKey3 = 2080fe52e0d3943d\r\nMsg = 00\r\nMac = c3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 10\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 73c10b833e1043ab\r\nKey2 = 16dcd343645d5207\r\nKey3 = 6426f7f88c3473c8\r\nMsg = 00\r\nMac = 8b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 11\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 310d54d96bc73452\r\nKey2 = bae34f158ceafb04\r\nKey3 = 4651c1b53de3da26\r\nMsg = 00\r\nMac = ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 12\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 0e3d49d0e692f20e\r\nKey2 = a9cd384a3b688c0e\r\nKey3 = 584ae5f794f8fe7f\r\nMsg = 00\r\nMac = 4b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 13\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = b0fda857ea402f0b\r\nKey2 = d567e9f48568f1e0\r\nKey3 = 0ec2ad452a547a91\r\nMsg = 00\r\nMac = 04\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 1ac1543b1591f270\r\nKey2 = dcda0e9870b9d949\r\nKey3 = 68ea9b1c4380ae9e\r\nMsg = 00\r\nMac = 43\r\nResult = P\r\n\r\nCount = 15\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = d0b008aea4454551\r\nKey2 = 9234a7731ab610b5\r\nKey3 = 2fb97a8ffbaedae6\r\nMsg = 00\r\nMac = 4c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 16\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 04793b0b0e976d0b\r\nKey2 = bf493e58fb73681f\r\nKey3 = 1f54a262d649b985\r\nMsg = 00\r\nMac = 77\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 17\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 043b759b578ae570\r\nKey2 = 5e522f19cb9de092\r\nKey3 = 2af2e90eb6dcc1fd\r\nMsg = 00\r\nMac = 77\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 18\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = e58520088910513d\r\nKey2 = 7c10196e1a310dd5\r\nKey3 = 5b043b2a1ab97f85\r\nMsg = 00\r\nMac = 1c\r\nResult = P\r\n\r\nCount = 19\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = f27fd0f189452c15\r\nKey2 = 04681651014916ab\r\nKey3 = 204046aeeffecd15\r\nMsg = 00\r\nMac = 0b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 20\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 860864a710ab0475\r\nKey2 = b9205751bfd91f7f\r\nKey3 = 3bf72abf13d97640\r\nMsg = 00\r\nMac = e890abe6ea126215\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 21\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = a7a1d57aabf1137c\r\nKey2 = fd0df2e35b8cdf2a\r\nKey3 = b386755bc2ab3d9d\r\nMsg = 00\r\nMac = f475587c2101eff2\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 22\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = c2c28a4c7698804c\r\nKey2 = ab25b53783dc0419\r\nKey3 = ab16341f4cead054\r\nMsg = 00\r\nMac = d335575aa3a4d8af\r\nResult = P\r\n\r\nCount = 23\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 7594a7aed3e986ba\r\nKey2 = 52a280e662d9e9da\r\nKey3 = 7649d3ad6838f2c2\r\nMsg = 00\r\nMac = 0e109f43557f250f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 24\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 0798d9ef158cd698\r\nKey2 = fff4ade09b169762\r\nKey3 = 5b6e6849ec2c238a\r\nMsg = 00\r\nMac = 05af623529b168a9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 25\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 254991cb4af76dc8\r\nKey2 = 2cf2e915918a025b\r\nKey3 = 2c61bfaee69b2676\r\nMsg = 00\r\nMac = 725ab7a770762894\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 26\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 9f68cbbf3bb5b3da\r\nKey2 = 31adb5a46e2cc8e3\r\nKey3 = f86ed9eaabb625da\r\nMsg = 00\r\nMac = 0422d94f874dda7e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 27\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 1fd51f70a77ac8e9\r\nKey2 = 5dd9986e974c08ec\r\nKey3 = fd61ce34a75279f7\r\nMsg = 00\r\nMac = a163a5d269b3cc3e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 28\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 078c57d6df9ba1d5\r\nKey2 = 08d94ac1b3d3c183\r\nKey3 = e90bf4fe7973c2c7\r\nMsg = 00\r\nMac = 9af3f01e20dc7c1e\r\nResult = P\r\n\r\nCount = 29\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 08df322f040e7c01\r\nKey2 = e92343e69d83eac7\r\nKey3 = fe94c1ec0da22c1a\r\nMsg = 00\r\nMac = 3d88c20a4f828c5b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 30\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = b2ecf41c8692c2b0\r\nKey2 = 8ff18c1f1f296454\r\nKey3 = 383dcbc4a28c7629\r\nMsg = 00\r\nMac = 17241dc726fa4c56\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 07d99d58f2ec1fd5\r\nKey2 = ea46c73bf4b60ed0\r\nKey3 = f20ec149c831aecb\r\nMsg = 00\r\nMac = f6a8a0b536fd97d3\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 3dfdc19426fbd56d\r\nKey2 = b03b7985b32af857\r\nKey3 = a807c7b3621ffdda\r\nMsg = 00\r\nMac = 3ef9b263ae1df460\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 33\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = fbc79bab46b97923\r\nKey2 = ece6da4c40f1e6e9\r\nKey3 = eaa76770ef517a40\r\nMsg = 00\r\nMac = b2da3efa7fc64abe\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 34\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 5ba4a1d5a80db5ef\r\nKey2 = 7ce6aeb9261cb00b\r\nKey3 = 8a5df23ea445e0c8\r\nMsg = 00\r\nMac = 51b2e75334d90889\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 35\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = e9c494e001027c86\r\nKey2 = c4649e58ea251904\r\nKey3 = 8025343dec34409e\r\nMsg = 00\r\nMac = 166123f1c59132a3\r\nResult = P\r\n\r\nCount = 36\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 6bce61e646452a46\r\nKey2 = 54ba8a020d0876fb\r\nKey3 = 34ea2f6149bad664\r\nMsg = 00\r\nMac = b0d0f625f06f2a3a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 37\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 2f38f79bc8e0ea4a\r\nKey2 = d09876f22ca43e10\r\nKey3 = 3b8fab02299d328c\r\nMsg = 00\r\nMac = b26d377a504b8985\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 38\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 51febf790815f1d0\r\nKey2 = 9152d5e32f6713fb\r\nKey3 = 4a40c2c8fdb9f2b5\r\nMsg = 00\r\nMac = a27978e62026743b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 39\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 10ba8fd6256ee9a4\r\nKey2 = fa8332a46ead52ab\r\nKey3 = b0e06e1fef04abb5\r\nMsg = 00\r\nMac = e1b0a228c142555c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 40\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = f2fbab6734769e9b\r\nKey2 = ab45910e5775ab0d\r\nKey3 = 5bd5ea0db015a89e\r\nMsg = 7efeb7d4d14b3f2b3df4b8a276b18b49\r\nMac = 5c\r\nResult = P\r\n\r\nCount = 41\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 5bc776ba64adf4ea\r\nKey2 = 195e04987c62a4f2\r\nKey3 = c1642fdc1a31705d\r\nMsg = d1fb4f35914404af9df3bf5c368c0e69\r\nMac = 4d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 42\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = b67c57f770202c6e\r\nKey2 = e91f4fb361bcae37\r\nKey3 = ada8d3df4fbcf4b9\r\nMsg = 9800db878187c87ea05bf92054b0e3e3\r\nMac = 8b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 43\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ce0bc48002fe7602\r\nKey2 = e702abe31c7a2313\r\nKey3 = d61964867f2579da\r\nMsg = 704e4e75be1623b21332c14555bf5edc\r\nMac = b0\r\nResult = F (2 - Key or Key2 changed", - ")\r\n\r\nCount = 44\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ad75e32cc11980f2\r\nKey2 = d0570429680e9486\r\nKey3 = c2379207f862dcfd\r\nMsg = 197de855b3962b1fdad687f9c4f1efd6\r\nMac = 44\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 45\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 9db504803d29f126\r\nKey2 = 07fe58b3da765bad\r\nKey3 = 6dc489516e9bb5f8\r\nMsg = 8f296b265fa575d146799f9e39d52965\r\nMac = 14\r\nResult = P\r\n\r\nCount = 46\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 991f0ed04079293d\r\nKey2 = 57077ff1baecd907\r\nKey3 = dcc7a719c4372967\r\nMsg = d9cfcc67520c5b2ceeb622c694a8e3fe\r\nMac = a3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 47\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = eca815d6b0371cf1\r\nKey2 = 597980cdb6c892df\r\nKey3 = 3dba0ed3ba16ae1c\r\nMsg = a03636db2fdc84722aeb9d98a6ed70d0\r\nMac = 78\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 48\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ea80a43d5886dfef\r\nKey2 = 08bf4f76a8893732\r\nKey3 = 4557a13752d6730d\r\nMsg = 0371a63ad722523ef297d8399b124593\r\nMac = be\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 49\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = e9fe73e640808c02\r\nKey2 = 9be6986446012091\r\nKey3 = 707023615462a40e\r\nMsg = 83bcb484dca73d49ac234ece3a5d2ad3\r\nMac = d6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 50\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 1fe9800ecb0dd9f1\r\nKey2 = dbbc6bc72c794c23\r\nKey3 = 899b08469b6bc8b5\r\nMsg = 95f4a41c4c64cd7310fba748aa267a14\r\nMac = 59\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 51\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 34546261a21c1c43\r\nKey2 = 0449eaeca4f29725\r\nKey3 = 4cc4e6525186802f\r\nMsg = d204de1e671d3e43670dd67fee114402\r\nMac = 6e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 52\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 048aa8701fb5fe26\r\nKey2 = d56bd53d83e60bd9\r\nKey3 = 6707d6523ebc32f4\r\nMsg = f4e9f92fd2c9313fb61a889eaa4ff283\r\nMac = d5\r\nResult = P\r\n\r\nCount = 53\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 6ec19b02976e5ba2\r\nKey2 = 13540732d997c2b6\r\nKey3 = 7f4068926183251c\r\nMsg = 963363ab7c82b634974954bd0fe2c307\r\nMac = d7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 54\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = f4ecea5d32e32c6e\r\nKey2 = 385710cd3eb0fe51\r\nKey3 = 5d4c8f7ccdf10154\r\nMsg = a298857dc60ad2f0a8fa878607b50c18\r\nMac = 4c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 55\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = b31ff49dd970f8e9\r\nKey2 = 164aefb00efb5461\r\nKey3 = 981629757f4532dc\r\nMsg = fc3957b2ed0558bce61d478be615b774\r\nMac = 90\r\nResult = P\r\n\r\nCount = 56\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 85384543d3aef157\r\nKey2 = 57ea916d9b2fd0c8\r\nKey3 = 1a85830473fbe6c4\r\nMsg = 87db0d9d69bc0cf69cabeb92570e482b\r\nMac = 53\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 57\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 9bf8fb0b464070f8\r\nKey2 = 10ea23c7e5a19bcb\r\nKey3 = 408c236e10863e2a\r\nMsg = f9c98cd8a7d27553da946427b8276349\r\nMac = 53\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 58\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 91b083e9c8e9803b\r\nKey2 = 76d0341cd54c38e5\r\nKey3 = 07bca7f44a3e76bc\r\nMsg = 7e5b64dc6bcbae6bb4496fc033947343\r\nMac = de\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = e6795b1ffe8f3e38\r\nKey2 = 4fdcea8c73c76e75\r\nKey3 = df0726ae4c079461\r\nMsg = 5265fb6a796d99a6beec6f71ba267b5d\r\nMac = e0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 60\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 375710c76202bff1\r\nKey2 = 3bb96170d5df4cce\r\nKey3 = 23d5daa22a982f08\r\nMsg = 52f5a110dddc9f44f8a534eef9df0b22\r\nMac = b1b9e11939228900\r\nResult = P\r\n\r\nCount = 61\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b59b855dce76adf4\r\nKey2 = be9bae10fe34fb1c\r\nKey3 = 0d49159bf804a4ea\r\nMsg = 869f3b62ee78bfeb5287168eacf69ccb\r\nMac = 169a389352793c8b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 62\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 615d792a7038fd89\r\nKey2 = 98ce972f016e75a8\r\nKey3 = c470255783b32f01\r\nMsg = e5aed6715aa4291f9c32baf6b8449b53\r\nMac = 73ac2da999bfdf5d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 63\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 1fb09443a1074564\r\nKey2 = 3d1aa82c086eba13\r\nKey3 = c137d0f4ea54d604\r\nMsg = 16f02efd285381d7657ca5cd99d9e25b\r\nMac = 38126d16957893ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 64\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 2e5d163461fea761\r\nKey2 = 9173bf75372fb640\r\nKey3 = 9e3d1c3dcdbfbc31\r\nMsg = b10fcb03443302ae929ff95a17b025fa\r\nMac = b70f2d761ca643c9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b9e5861c1c4013d3\r\nKey2 = d554806efd3801a1\r\nKey3 = 64d9bc3d646e76dc\r\nMsg = 0e6c9fced82669cffe7b5a6f09dceec8\r\nMac = 78ce4635e486635a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 66\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = ad2376516b974c70\r\nKey2 = cd3b5870c2312929\r\nKey3 = 1a731a7feacbf783\r\nMsg = 88eb7a0379da9d113343dc1fe0f3e6f7\r\nMac = 0c949483e7fa7d0c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 67\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 9ada194c100eeacb\r\nKey2 = da23ad9825c194d0\r\nKey3 = 3ef1f4c438dce031\r\nMsg = 0f9703a3454c25c0b1053de62b0ffc5b\r\nMac = c78a4ca3662527e5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 68\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = e375f870f4d55b02\r\nKey2 = 1b015791e3e337b3\r\nKey3 = 370dc45b15671c5b\r\nMsg = 5ad9dd3b112ea4cee1654d2dfabab01e\r\nMac = 22becbbe7bfcade5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = d61f4aeff4b5f2f8\r\nKey2 = 0486b53de3ecc297\r\nKey3 = 807fe92fc2fed376\r\nMsg = d094cf77a709c0fa5d6b4b7e9e86a2c2\r\nMac = 947d024d9d5359a8\r\nResult = P\r\n\r\nCount = 70\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c2c28a4c7698804c\r\nKey2 = ab25b53783dc0419\r\nKey3 = ab16341f4cead054\r\nMsg = 7295a7aed3e987baef19ad68c33ba5a5\r\nMac = 58de82acc10d556f\r\nResult = P\r\n\r\nCount = 71\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = f1ce4992c851e3a8\r\nKey2 = 835ec1abef97f2c8\r\nKey3 = 5b92384f20dcc2ad\r\nMsg = 9094935fcd7c389dd17b5b121cddadf9\r\nMac = 319c70370c172de3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 72\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c16ebcc1165d6892\r\nKey2 = 75268c4602f8c8bf\r\nKey3 = dab97f79544cf1cd\r\nMsg = b7ba1c66282cb6092ba601407ff9578a\r\nMac = d73c26311bd44a32\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 73\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = fe4a796720a46dbc\r\nKey2 = 98f45289e9f8b080\r\nKey3 = e05def5b25520d43\r\nMsg = 31c9eed491bb0cda9b8c0eb5afa31019\r\nMac = 8c2ce22633c62751\r\nResult = F (1 - Message changed)\r\n\r\nCount = 74\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = eefb40c715c4546d\r\nKey2 = 5b2325c8d9daa48a\r\nKey3 = d5ec4a6bc82a7a62\r\nMsg = 5a97259dfa081f040d3893da2f231ca3\r\nMac = a64113544f509be8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 75\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 0d0851311ca45db0\r\nKey2 = 3d7c458957c8c408\r\nKey3 = 98d37c9d51ab2f25\r\nMsg = 8be16380af3e2dbc6cf678c2e3331335\r\nMac = 8817baeaa909e33a\r\nResult = P\r\n\r\nCount = 76\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b7239438d61cd626\r\nKey2 = 082c6404cb3897b5\r\nKey3 = c4c732cdd5e043c2\r\nMsg = 7120f19169e7cbb913c7d1f0ceb006c0\r\nMac = 32841ad7621cc0fc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 77\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 73f449ef83df75e9\r\nKey2 = 5f3d2016bfd0703b\r\nKey3 = 31abc16b58b64af4\r\nMsg = 83ecbfcff3bc37f1305d83bc0290350c\r\nMac = 8f8ba8bfc74203fa\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 78\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 9b6ea461c7b9abe6\r\nKey2 = 4a08dcdc5b9e01fe\r\nKey3 = 6b850e9b6ebae9d6\r\nMsg = c538416fba487fac5c94449d0757f3e9\r\nMac = c13f372e9a061db8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 79\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c7aeeacb156dfbfb\r\nKey2 = ba43ef516232a7d3\r\nKey3 = 2c572aea62808c68\r\nMsg = a1bc9950759d0df4cffaf29345dfb340\r\nMac = d7dad4519b56a1eb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 80\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = cda4d34370234946\r\nKey2 = c408ea6bec07c78c\r\nKey3 = 19eff7f798fd6808\r\nMsg = d1fb0b68176269cf9fda18bf13efc054f0c24fd042b9e2ecaf75e86cb60484f6\r\nMac = d8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 81\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 02100be5627686a8\r\nKey2 = 7f0b38ec073e75ef\r\nKey3 = 373b1a64ba5416d9\r\nMsg = c60be37fb0bda4f46894690b3344643c772fbd2237db348adaa407ca2eae1654\r\nMac = fb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 82\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 7597571a6e7c6bc8\r\nKey2 = c143a2a461626b1a\r\nKey3 = 6b1307d910434cc7\r\nMsg = 49cb128641f7952dfdf34f338da268b2ef1482557b593e", - "c57f930164264ff83e\r\nMac = 90\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 83\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = ae89ad615201546b\r\nKey2 = ae20765745458fce\r\nKey3 = efd0867fba43dcb0\r\nMsg = e47d8659c9ad94971adedd6bce744206e1cfb65d042b942d93c4363cc73ec3e3\r\nMac = 95\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 84\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = b65886f13d6e8c4a\r\nKey2 = 0708e0b0730473a8\r\nKey3 = d04f2a86dc0b9e7a\r\nMsg = b97c12251d91512fe7b3a349a982409c7412f39494d970e77acbe9d3fac3dca7\r\nMac = 05\r\nResult = P\r\n\r\nCount = 85\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 3197a4a26261588a\r\nKey2 = 0dc4a75ec8b99b58\r\nKey3 = efb93e7620205289\r\nMsg = 65f4b3a00c1c1ef39445a69b2150b034705410140ff9dad0ce21740271cef04a\r\nMac = 57\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 86\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 62c4a16e946b4313\r\nKey2 = d09ea80e7fb33449\r\nKey3 = 164fdc04c2d5f116\r\nMsg = 898e824fdc89f21779156a9e58564c4b99004b95226c2ebb8aebd0b5365a6c6a\r\nMac = 93\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 87\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 6eeff20d3d5d5223\r\nKey2 = 258076b313611c1c\r\nKey3 = b013b957f70d9e62\r\nMsg = 2d7fec1a1e9ee85cf960e5dc4e239619ed85f4b14d32cbd42dfa79f77a27f2cd\r\nMac = 0a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 88\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 193e23e6fd8aa185\r\nKey2 = 1910cbdc549da804\r\nKey3 = 6b769b4923523425\r\nMsg = bd65798a1d02ab164e2d31b1387e505874779539046820bd429043c617854c36\r\nMac = d3\r\nResult = P\r\n\r\nCount = 89\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 150789ab37ef2ce9\r\nKey2 = 10cdf45dad9ed9e5\r\nKey3 = f475fd3e153898fe\r\nMsg = 044dd73a7d1ef37a437c09e9268708c82ebad189dc1e989ab3bd8d7ff75abc23\r\nMac = e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 90\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 48d9d08a6bdcc4f8\r\nKey2 = 1383641c08735d0e\r\nKey3 = 374a89c8cb73a7f4\r\nMsg = d62fb84f2a2442b52acf817d7f067edca031970bea092c35f29f9a931aa06dd6\r\nMac = 26\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 91\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 68f4620da8b00201\r\nKey2 = df1c8362345180d3\r\nKey3 = 26abda897f89d90d\r\nMsg = 0ac3f7f22d24b64aa584845d3a990bb69e5d2d4650640056c16c17c0b636045f\r\nMac = f9\r\nResult = P\r\n\r\nCount = 92\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 1c259df7492361b6\r\nKey2 = cd4acdb65b3e5b1c\r\nKey3 = 3b01addc2579ef64\r\nMsg = 607f4730a5ea9dabfbcd8586f680c3021c7ebc858e73354beb975d58713b0eb1\r\nMac = fa\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 93\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = f18a9dba9db5dff1\r\nKey2 = d5987013a4b69e38\r\nKey3 = dc16e0ce1351e3f4\r\nMsg = bfe99e184a7d7bf0b4ade8f402f2c49aa4948e74b2d5c905756ba5d32934dbbd\r\nMac = e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 94\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 8361bac48afb1091\r\nKey2 = da85400d107fbf8f\r\nKey3 = 31ec732cc29d7045\r\nMsg = 3a1ee70d4607325c13bff68e402e0a72742f6a63ae972c6dda74b6b2a3922f0c\r\nMac = 0e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 95\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = d0df1adf1cf72032\r\nKey2 = 1504d564ec1aea61\r\nKey3 = c42fada45d80a43e\r\nMsg = 3a53d9c7ae59e7811699fb0973e43256ed92162267c7ca4b57f5887ad5a24e02\r\nMac = 8a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 96\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 973bfe5b3be573da\r\nKey2 = 94b3ec7f343e46ab\r\nKey3 = dcaeabc8df405db6\r\nMsg = c8437dba76591a9031b3aa3b59fec0562d4eac439ca8efca57c3f2022b0ff775\r\nMac = 53\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 97\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = bc89867c43a74640\r\nKey2 = df347fb319464c80\r\nKey3 = fd92108a266bcdcd\r\nMsg = 1c9898ede16139560519e808ee9ddaf710a5bab30f54ed98230d1a44c189ea4f\r\nMac = f6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 98\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = fde925e301897f67\r\nKey2 = 54b3ab80f815df15\r\nKey3 = dc58928aa286c8e5\r\nMsg = b34f898d98a3aa0fa022b1b1d76953a5b3ecc88d60f2c79b59e1b1f636bc0d60\r\nMac = 0f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 8a704ffe43e951f8\r\nKey2 = 2346dc8501202a40\r\nKey3 = d67afed616230113\r\nMsg = b2b4cb5e90ebf4bd265093b7f5efd4d62dc60e29737aa496e14929724e40c74f\r\nMac = df\r\nResult = P\r\n\r\nCount = 100\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 8c1f29f440f7f8b5\r\nKey2 = 5b45fe8f1f688661\r\nKey3 = ba40f43d9e7cc86b\r\nMsg = 220817144a15a0a654fc1beaabce60270aa72df83591754ee7a5fbb40b7420d7\r\nMac = 80ac51c2ef7bd5d7\r\nResult = P\r\n\r\nCount = 101\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d66e76d97f94ea16\r\nKey2 = f15e3ed06dd94598\r\nKey3 = ae073d1a6e5bc819\r\nMsg = 233d547ab33790859ab0dbc7a93f3bbebb610bed9acbfbce1fff580e9a1e8ef9\r\nMac = 4cb8ce681e4bc7c8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 102\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 0437836df770e943\r\nKey2 = c96e2c43bffd5298\r\nKey3 = 8552fbc16215e0c4\r\nMsg = 4f87d730bdfc7a7c72525c6b26ee9cae9a219b30d9575fedbd913a07b615a616\r\nMac = ea79cbc28f4264db\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 103\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d849ba8570b6ef9d\r\nKey2 = f1405732aeb61f92\r\nKey3 = 73c8e51ff167f857\r\nMsg = fd03202d0bd109b6e4299c7390c1407cd21ffb110013e6381185dea8f8707de6\r\nMac = 71070b17d05dabef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 104\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 914cef7ab6d998dc\r\nKey2 = a767abc18cf485e9\r\nKey3 = a2624ff20b2a408a\r\nMsg = bc5ce4c0bf3ad1a93e5306c9d7dbb620dde8708efe84e78c2200f41a958cdef8\r\nMac = 3cf4aaf3d337c9c8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 105\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 757f52e626eabce0\r\nKey2 = 700d91f14554bcb0\r\nKey3 = 548640d0dfaec2ab\r\nMsg = 22a4cf581584346095783be0982744c6201ff040760f868ab63895058d1edb88\r\nMac = b008b1150535ef11\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d65d0e58d3133b34\r\nKey2 = 289e58704994a249\r\nKey3 = e3df20ae3d585e2f\r\nMsg = 94c8414cbbec52e2d73bb8f02ef687c91432495c0c744666317d02e6d46706d2\r\nMac = b1292e1c7074dcfc\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 107\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d77a4989f4a17f2a\r\nKey2 = 409d91d51fa4d045\r\nKey3 = 6bb652ea1526fd4f\r\nMsg = 7a08ce579ae7af8004421cff72715e0b137da81f47d8f84da34c3ed53c32c0f6\r\nMac = 8b3cb70477ca7ca8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 108\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = e670c17519d9c2f2\r\nKey2 = dcc8a132629b462f\r\nKey3 = 58c1d52543ad570d\r\nMsg = a6dbad96ad23ff61479df39b99f0673a09f2a7eaebbd34b95d05c4146fa989f2\r\nMac = c470ec40599a0a11\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 109\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 290d292a15b6268a\r\nKey2 = 2638d9ad83ad1f34\r\nKey3 = a7d9ba62735dc2d3\r\nMsg = ef995cbfc49b0ebccdbd37d9f40a431c385d33d4b8234d7f0d6211eaddfb709a\r\nMac = 67ae62fb8142bd8b\r\nResult = P\r\n\r\nCount = 110\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 4faba73bcd5b5dfe\r\nKey2 = 1c97ea85207a97a7\r\nKey3 = 19eff116100dc82f\r\nMsg = c48e53c6956432460584c7ee1577c1c38b7fae2ff288199be25bf64081154139\r\nMac = d68a4558e95a67e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 111\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d37c3dbc2f68baba\r\nKey2 = 918cb5e39237e016\r\nKey3 = f286b0739d38c4fb\r\nMsg = 2533361761ac80578fa262a50462045e3ec6e4d5d25c6e99a5c4ccf75f5affc0\r\nMac = c20f36e67732f864\r\nResult = P\r\n\r\nCount = 112\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = a0baa71c38d6d064\r\nKey2 = 8f58ba45cb494ab9\r\nKey3 = 853decc431f7b3cd\r\nMsg = 20e394c7cc90bdfa6186fc1ba6fff158dfc690e24ba4c9fbf11b68519d573a8a\r\nMac = 4ba956b98a99d7bf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 113\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = b69752407c68b6bf\r\nKey2 = 8fceb05201ec4320\r\nKey3 = 2a755e372373ef26\r\nMsg = e884d65c87411584a56956d5b27ca9725b473c205b64cff09400671f5ee0473a\r\nMac = 9f3de5e8cddc374d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 114\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 8c04e0f27f83b0ec\r\nKey2 = 042cfb6883348fe6\r\nKey3 = 404f5dfe587ab591\r\nMsg = 8a34cd562b111fe04fa0bf5e004faedaef99d0bab9344d966c8b3847486e6f40\r\nMac = 6c530215fb25015b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 115\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 429401ea49cd97b0\r\nKey2 = a8f1b6b63101cee0\r\nKey3 = 20bcd08c5d16e049\r\nMsg = 591d88123fc9a786b247e8d5ce155f136d6fe4084117c41f2056b67f9e3e1077\r\nMac = 6c414640b424cf56\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 116\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = c470255783b32f01\r\nKey2 = e3aed6705ba4291f\r\nKey3 = 7319100e54f432d3\r\nMsg = 01acc3282fe41b62f95f5dbfb7e7bfef694c5fe34ca87d31abe7e7bbf887b48c\r", - "\nMac = cd99df4814667454\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 117\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 73c10b833e1043ab\r\nKey2 = 18dcd343645d5207\r\nKey3 = 6426f7f88c3473c8\r\nMsg = 068e4a0b1a62dd64198f1b9ece814c2feeeee50ba814b70d7d42659952991b80\r\nMac = 1fc90834b7dd090b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 118\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 37eae98ff42afb25\r\nKey2 = f2231c028c29da9d\r\nKey3 = ef3da8d0c77fbf45\r\nMsg = f266cec01c5fc08c0bdabc9537bd1aa2df9f2b8ffbe5cc94722a3bca8de529ea\r\nMac = b3809c8b0eb9dd8d\r\nResult = P\r\n\r\nCount = 119\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 1358fb67155e0145\r\nKey2 = d02c54a1206b5d7f\r\nKey3 = 1c04ba46c74a5d49\r\nMsg = e38b4c3e7a82643beb3192426555ad9c9b2620d677373fc40c9ddbc4cd531347\r\nMac = b000e2ea1ef48a8f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 120\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f6b9a81067255b58\r\nKey2 = 927cfbc4cdec9285\r\nKey3 = dcd62345bfe03b92\r\nMsg = 246b66b10696adc45840\r\nMac = b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 121\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = fea186dc73d3807f\r\nKey2 = b8fec7387a197962\r\nKey3 = 4c91abe60db64ff1\r\nMsg = 8ba298364af144a8d5f3\r\nMac = a6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 122\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f264da8607ea439e\r\nKey2 = fdb9daa41fd34958\r\nKey3 = f85d6b859b9892bf\r\nMsg = 402006f6b18dbd11dcd1\r\nMac = 28\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 191c461adc4f7f4f\r\nKey2 = 75b932e68cb98cfd\r\nKey3 = cb2943857a1c9438\r\nMsg = 391deef3a9a41394d14a\r\nMac = 3c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 124\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = a2c2f713430ece92\r\nKey2 = df081ae9627a1351\r\nKey3 = c1ec469ba8c73b67\r\nMsg = 37a49535684637f67573\r\nMac = 40\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 7b61dac238ba3e83\r\nKey2 = d05e9ed34fc410ce\r\nKey3 = 98da194c100eeacb\r\nMsg = da22ad9825c195d1e297\r\nMac = 43\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 126\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 13aec10d13fd37c7\r\nKey2 = 89198c3bcd38b951\r\nKey3 = ecf843cdef7397cb\r\nMsg = b7625aa78d2961c0fee6\r\nMac = f1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 127\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = d94a68ec329d914a\r\nKey2 = 394a8acea420e952\r\nKey3 = ec04c8cb8602aec8\r\nMsg = e043f30a405c41938914\r\nMac = 6f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 128\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = d5cb7579582fb6a8\r\nKey2 = e67f3ba11383d61f\r\nKey3 = da370852e9b9c2a1\r\nMsg = 7d32f440151a7069fd73\r\nMac = b7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 92402f6eb54526b3\r\nKey2 = 924515d92ad5a1d0\r\nKey3 = 9ead2adfb025f81a\r\nMsg = fd44d8d0fea5cfdf3321\r\nMac = 2f\r\nResult = P\r\n\r\nCount = 130\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = a9daad97ad23fe61\r\nKey2 = 32e5988a37987a38\r\nKey3 = 31626d16a780c825\r\nMsg = d6cf17192f8ad745ab5b\r\nMac = 8f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 131\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 52c457d9d5d5ab94\r\nKey2 = 9d3875ba6d75fdba\r\nKey3 = 4fb91a863d15ce52\r\nMsg = 4effbf732e67af7203b3\r\nMac = 04\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 132\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 7304b65492fd0402\r\nKey2 = 62a4cb7c23708057\r\nKey3 = f2f7bf13839e01e5\r\nMsg = a630c0f362eef35b6a58\r\nMac = aa\r\nResult = P\r\n\r\nCount = 133\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 51b33425a1349792\r\nKey2 = dc5b8ca440eae6ad\r\nKey3 = 70adf49dd0a8f119\r\nMsg = af246a8a810cca5e657b\r\nMac = 0b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 134\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f22029ce51619e0d\r\nKey2 = 9d51bcc2089785e0\r\nKey3 = 689d62621abab3b0\r\nMsg = a9c9fb632423d367b3eb\r\nMac = 0c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 135\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 1ca226d0dc8c328a\r\nKey2 = f18a9dc176621f51\r\nKey3 = 3d765d20e03b4cea\r\nMsg = f9d9fb44919e47cdeaf8\r\nMac = b0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 136\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f3ce4992c851e3a8\r\nKey2 = 835ec1abef97f2c8\r\nKey3 = 5b92384f20dcc2ad\r\nMsg = 9094935fcd7c389dd17b\r\nMac = 3c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = bfd929cdd9c2089d\r\nKey2 = 8e49988abcfbf458\r\nKey3 = da73d986894fce4c\r\nMsg = 88018424fdb76c908bd6\r\nMac = 94\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 57bf2ca4e3629797\r\nKey2 = ef7f675443402546\r\nKey3 = 6e4f924038f8bc92\r\nMsg = dd4f0a872f4b7089d697\r\nMac = 5b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 139\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = ba86924908df08b3\r\nKey2 = 26b954ba52df2c98\r\nKey3 = bf38cb0e89b9f4cd\r\nMsg = a682e6fd64df4b9f4fe8\r\nMac = ea\r\nResult = P\r\n\r\nCount = 140\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 52859849a4b6c1d5\r\nKey2 = 380e73c7aefb0168\r\nKey3 = c479fef80eb6260d\r\nMsg = ee6857533675b5ed8d43\r\nMac = 43fd25f696cb0693\r\nResult = F (1 - Message changed)\r\n\r\nCount = 141\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 97ae01315d13ec52\r\nKey2 = c7674cc1ab0bbab3\r\nKey3 = b68fb99797b33b79\r\nMsg = ce9127f649bfff849826\r\nMac = 2dfe01d9bc07646b\r\nResult = P\r\n\r\nCount = 142\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 2b257032b0d9b0b3\r\nKey2 = 49f7c10e8a9bcd37\r\nKey3 = 20f4fb4679106ddc\r\nMsg = b2c62d03902c44253368\r\nMac = 14c5ccf5f9433a0f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 143\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 0b988c3d380e5b80\r\nKey2 = b86be99162029b54\r\nKey3 = e0bc9775838a58ea\r\nMsg = 61ababff3763183c348d\r\nMac = 28a2de26aa6b4074\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 144\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 26e9abbf201fe5b9\r\nKey2 = 7062a82f800d5183\r\nKey3 = cd45e654bf5d205e\r\nMsg = 020683e1f0392f4cac54\r\nMac = 6f1522d3c8186217\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 145\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 3443f4016dadcd86\r\nKey2 = 235dec80323e5838\r\nKey3 = fd583285e6efbc51\r\nMsg = e64eeb89828b4297601a\r\nMac = 5575a40dba5bc4c6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 76c7616785916470\r\nKey2 = 5b3d1f10e5252fda\r\nKey3 = 75a2d632a46ea18c\r\nMsg = ac7d701597f0ba879055\r\nMac = 06b98e161e6a6754\r\nResult = P\r\n\r\nCount = 147\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = f12367b568a758b5\r\nKey2 = 7b2f9770924f2c0d\r\nKey3 = 1f8ad9e9b97a088a\r\nMsg = b99de8168e8c13ea4aef\r\nMac = db534a059f930ee0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 148\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = f1adb67986923d8c\r\nKey2 = 02671957dcf75808\r\nKey3 = 52732ae970467019\r\nMsg = f759c3033d4ed34948d7\r\nMac = 2d9caabf50999ac6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 149\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 792f9770924f2c0d\r\nKey2 = 1f8ad9e9b97a088a\r\nKey3 = b99de9168f8c13ea\r\nMsg = 8bae64015d62f68565d1\r\nMac = a42f89527f5cb219\r\nResult = F (1 - Message changed)\r\n\r\nCount = 150\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 31ec790d4a8a131c\r\nKey2 = 562c8cdc07e331d3\r\nKey3 = f4a7467043924c4f\r\nMsg = 1798286c37c1504fc0d7\r\nMac = f0d6e2f7edce6349\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 151\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = adb692e376a12585\r\nKey2 = 8c8c4362ea97f810\r\nKey3 = 528f204c19f21a31\r\nMsg = 6543e675d34639a7f7eb\r\nMac = fac96e6804526535\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 152\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 62984a64ec7c4a92\r\nKey2 = feda64dfd9a24f9b\r\nKey3 = cbb04f7a1f26df31\r\nMsg = adb555fd5f5c6bdd9c4e\r\nMac = e8dee8714b285a00\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 153\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = ef0d58b55ddae95d\r\nKey2 = 80e07ca4aebcfd34\r\nKey3 = bf947ff4ab2904e5\r\nMsg = 1fe87a2f431f3718665a\r\nMac = 44a869aee76d79db\r\nResult = P\r\n\r\nCount = 154\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = aef4ceb55e3d37fe\r\nKey2 = bc0bb9d05bad972c\r\nKey3 = e0a29b2c7940ce9b\r\nMsg = 78ad5f3718acf9e8cc7c\r\nMac = dcc1d44200caf6f7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 155\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = a4403438f8fb254f\r\nKey2 = bac752cd83a170b5\r\nKey3 = 6bf71654f1854589\r\nMsg = 349566b6716e5f831d69\r\nMac = 7c08cc43ff4d8e07\r\nResult = F (1 - Message changed)\r\n\r\nCount = 156\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 2fc7f4c1ce042f73\r\nKey2 = 8346bf7a80b38640\r\nKey3 = 2ff74abfc197a732\r\nMsg = 43a32b8ab9b7ce4bbd1b\r\nMac = 8000a2612215014a\r\nResult = P\r\n\r\nCount = 157\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = c40ddc9e29ce041a\r\nKey2 = 583d6bc4c1a2abf2\r\nKey3 = 9b018fd5a4084a64\r\nMsg = 228", - "6a1eddd80737a724c\r\nMac = 0ff14761c982f890\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 158\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = bc327a0bcb2575df\r\nKey2 = 6b9483e6e0755d2a\r\nKey3 = 622cdc5b2916ab89\r\nMsg = e1be89af98ffd7d9257a\r\nMac = d6f4c8d96b3e2180\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 159\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 9e517cd616a48ada\r\nKey2 = 6d266192d5387a97\r\nKey3 = 8a081fda97c86b94\r\nMsg = 9e9fb0b2b77be6eeaae8\r\nMac = ba0b73fbffc0ab0b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 160\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = e0b9a826a85efe94\r\nKey2 = 4f615bce7cc1ba68\r\nKey3 = 3bb56d3d9816103e\r\nMsg = cfe9ee956cb1f5a60aa6ec79a3e454224b456879\r\nMac = 64\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 161\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 1e08a794a175b69e\r\nKey2 = f7d3ab46aeb9073e\r\nKey3 = 3e7cf8cea19d0891\r\nMsg = eb4f5b04517ee93e2c900e01948ac81ca56b2b26\r\nMac = 79\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 162\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8f26700dc140570b\r\nKey2 = 8325e3a889c823ad\r\nKey3 = 6b048aa73decf83b\r\nMsg = cefb55151933a488e2b3d421dea9720727188106\r\nMac = 85\r\nResult = P\r\n\r\nCount = 163\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 3443f4016dadcd86\r\nKey2 = 255dec80323e5838\r\nKey3 = fd583285e6efbc51\r\nMsg = e64eeb89828b4297601a5b3fcde60075fc2424ae\r\nMac = c0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 164\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 91a401cbb6460b16\r\nKey2 = 85438675f15b6e73\r\nKey3 = b09140318a767038\r\nMsg = 8c65cde13149d9d54a5bccc17747f1d5f3e807e3\r\nMac = 56\r\nResult = F (1 - Message changed)\r\n\r\nCount = 165\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = b78a16fb9b075d3b\r\nKey2 = dcabbf7a07150261\r\nKey3 = f7644a01d5dcea46\r\nMsg = abe2fd996bb6804ed3286c057df9cea6836a2dad\r\nMac = 09\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 166\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = ce8a467534cd679e\r\nKey2 = cb9ee6fb70a42f4f\r\nKey3 = 16c1e5c1459e4ac8\r\nMsg = 3c56ccfbe92023109983e740d6a53488b813ee87\r\nMac = c8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 401f0de0efd6dfa8\r\nKey2 = 16ae7c3bbc6e5b86\r\nKey3 = 4ffebf790815f1d0\r\nMsg = 9052d5e22e6712fab88e8dfaa928b6e015ca589c\r\nMac = 61\r\nResult = P\r\n\r\nCount = 168\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = d357bf5bef2cfba7\r\nKey2 = b757d3abf49b4ac2\r\nKey3 = 16388051da8a04a7\r\nMsg = b04e8f6d20924be8e4e2c6767f87b74377bdf90c\r\nMac = 72\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 169\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = f8ea68aba1bcd9e6\r\nKey2 = 4abaa4260d864573\r\nKey3 = a49840ab737af7b0\r\nMsg = 1fc99e586f87932445930a300eb28191d9c6215b\r\nMac = 19\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 170\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 94ec086d8c0110cd\r\nKey2 = 4ea11f327f70c245\r\nKey3 = c8d07adf7c7c5eb9\r\nMsg = 812dbc453a1fda59f73aceea3bc84d2c7a437dfc\r\nMac = b2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 171\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 9d575d582a9723c1\r\nKey2 = 294af47a54b051fe\r\nKey3 = 5131bff85bf12608\r\nMsg = 266e5305b96f497a956ae82b20367ebac0b14215\r\nMac = a9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 172\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 913d800ecd0dc762\r\nKey2 = 7f6ec476b6b07c15\r\nKey3 = 973262ab7c83b634\r\nMsg = 4670a266bebcdf95c62d36cda33d50e6650fcdcd\r\nMac = 4f\r\nResult = P\r\n\r\nCount = 173\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = b97ffe79d068ece5\r\nKey2 = 4a75fe2f67dae392\r\nKey3 = 45a4d9f17a9d70f8\r\nMsg = b53017500c100dea0511845597214484fc5f7f34\r\nMac = 6d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 174\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 7e1af10bcd86c283\r\nKey2 = 51cd37540e19021a\r\nKey3 = 988fd3c7250e2a6d\r\nMsg = da1919d4a2a7fcc34c88fb2065e52bf9dbc50731\r\nMac = 22\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 175\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8c0dc16eb9c80775\r\nKey2 = 6eeff20d3d5d5223\r\nKey3 = 258076b313611c1c\r\nMsg = b212b857f70c9f63d0c9d2ccd253c28d1534631f\r\nMac = 2e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 176\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 92c29eb0bf3e73a4\r\nKey2 = c6ecfbe6cd49bf4f\r\nKey3 = ef19d9d06d7a5e7f\r\nMsg = 969304e651ca62039088f8123085ac3263796b67\r\nMac = 57\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 177\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = a4432f52975e4316\r\nKey2 = 7f2086da04fddf4f\r\nKey3 = 8302139e79684329\r\nMsg = 5c9bcd197ea59e1b58b3da707b253491cc5a5ef8\r\nMac = ea\r\nResult = P\r\n\r\nCount = 178\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 5ae0b6d6c2855b7a\r\nKey2 = ec675d3e73bfd685\r\nKey3 = d3406b868fd3ae0e\r\nMsg = 89b9ecfef6f10e81f7956dbc7ca4a335047535a8\r\nMac = 70\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 179\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8f7f85649d5e08a4\r\nKey2 = ceda75687308e07a\r\nKey3 = 9215c4c19bdc0d46\r\nMsg = e53101e6eabcda32c13d7b1dd1d88e7c2ca3ddc2\r\nMac = 14\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 180\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 7061b5f46b98d394\r\nKey2 = 58c2ce3807623475\r\nKey3 = 0df8e3c432da8a37\r\nMsg = 1086953d352e94a51a6d4c59a2295e8fff5b311e\r\nMac = 554d4df88228eba3\r\nResult = P\r\n\r\nCount = 181\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 347a25a1ec433b52\r\nKey2 = ec75d97046152c10\r\nKey3 = 86b937b6ad1ccbf8\r\nMsg = 4fe6bd43c28143ea5d40919cb5330a7e674f5bd8\r\nMac = 3d0d841895fb7c65\r\nResult = F (1 - Message changed)\r\n\r\nCount = 182\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = b3701aa7da61512c\r\nKey2 = 46dacba40740e3c1\r\nKey3 = 8f79a4dcadbc315e\r\nMsg = 4612fb4586d7518d0d648894347ae7d49d043f29\r\nMac = e5dd4392afbeabe7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = b5b57acb2c7fd6cb\r\nKey2 = 70b02c9d8651c889\r\nKey3 = 07f485f7b00e45d9\r\nMsg = 9011231ec382ecaaae57f34de1ac6bbb50741014\r\nMac = d34581ad5a3e9e57\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 184\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 88985bdfd9852604\r\nKey2 = f7f829aec8a208b3\r\nKey3 = d5ba012ce6754554\r\nMsg = 6cad7f3b9f196839bbc5a7f755c09aa8e17c83d9\r\nMac = fc7c93552aa14ca2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 185\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = cd0815194319d552\r\nKey2 = 346bb634027668d9\r\nKey3 = c17f2a26257afbad\r\nMsg = e31b3d97ba6ee6f2e18f084215ca0a5ca0d816d7\r\nMac = af5772396bb63d20\r\nResult = F (1 - Message changed)\r\n\r\nCount = 186\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 236e5201dfc1081a\r\nKey2 = c81526bc85c7a2ce\r\nKey3 = ab91d0aee0d68931\r\nMsg = 1f36b9cbf3d4d4dfcc4ba7fafa7c229f0a9253f4\r\nMac = 27586cf856a41e82\r\nResult = P\r\n\r\nCount = 187\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 2e01198faeb6986e\r\nKey2 = 7cb564801f15bc5d\r\nKey3 = f2d3ef0d4fec61c1\r\nMsg = 27c8c90c9e46e14b8cbb0b7559bb166d65f58aeb\r\nMac = eaa7b4a171e449ef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 188\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = df575b851331b016\r\nKey2 = 33ec7326e9ef31e5\r\nKey3 = 1686c1ec8a3ea16d\r\nMsg = 1e4e01d38ff65d05646d544b52a6df49b897eacc\r\nMac = 45789bd32147c0ae\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 189\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 43b68c1f29ef5b94\r\nKey2 = a7dfa1cbe9ea3df1\r\nKey3 = 83d3c286e973ada1\r\nMsg = 0ca9b0f6465db0e101f8c14b2e73859d9c355b0a\r\nMac = da439a51157ff0d5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 190\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = bf91d679268c85ce\r\nKey2 = 46b9f7bf4aa1a2c2\r\nKey3 = f7fd15fda2cd6408\r\nMsg = 0c2933e39d7e601ee6f2519eaf01294853664262\r\nMac = 455cd46d3b452a55\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 191\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 0dad9d451f890b38\r\nKey2 = 3416e3c240a16ee6\r\nKey3 = 5b80d6aefd4ab5a4\r\nMsg = b6e1de9abef7525c5dabbdc85746958781d50139\r\nMac = 3445a869cca839fb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 192\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 96858f8f2ab56df2\r\nKey2 = 5edc3b04b94ca7cd\r\nKey3 = bf10614ce0491645\r\nMsg = ec9aa18b3e7da99dcbd7de7617a79130abe3348a\r\nMac = c744a1392fc656c2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 193\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 46ad6ebad9644a67\r\nKey2 = da684aa48f23d619\r\nKey3 = 43a2316b40a46e25\r\nMsg = cf97c2abe3d0fc89e05538b50147a3f405391219\r\nMac = 7ac08967edc5730b\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 68647694efb32023\r\nKey2 = 0d2938c8fe1a4057\r\nKey3 = f479f16e7552942f\r\nMsg = 33a9c750bb532d2d37ec86fa851aeb3cad1eaad8\r\nMac = 3873ae02210eb5fc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 195\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 58d62fd92af7437f\r\nKey2 = 89dfb51fc807cd6d\r\nKey3 = 024fd04f40d5d0e3\r", - "\nMsg = cc293c9e1780b401d2e7fceef6f69edcf0f70b86\r\nMac = 6574bfceaf04b4e1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 196\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 4b377f98df0b7598\r\nKey2 = bf73f4c2cb074001\r\nKey3 = dc9857f47fe6101f\r\nMsg = 9ba5dbe7a8ecfbedadd7889cd7f1ae073e01ee3b\r\nMac = aaaeb7223578bbad\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 197\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 91c8851934cdecc2\r\nKey2 = 582562aef1205e32\r\nKey3 = a12a70eacbad310e\r\nMsg = aa390a0ae33751b0bd8de5723df91d999aa70358\r\nMac = 67f76912ed61eaab\r\nResult = P\r\n\r\nCount = 198\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = dcc2bacbea0dcd10\r\nKey2 = c18ca45ed57f8f97\r\nKey3 = 5d58157a677f1951\r\nMsg = a7573e5b7dd7f4ce9e4480f603c14145a27f7c7a\r\nMac = 2b6af968464ac63f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 199\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = fe6d49702f044f40\r\nKey2 = 33321613da401004\r\nKey3 = 8c3438f74cc2680d\r\nMsg = b15a118b3132c20c31e6c9d09acdee0e15fcc59d\r\nMac = 9f28413a00da00ab\r\nResult = F (2 - Key or Key2 changed)\r\n", -}; -static const size_t kLen33 = 53587; +static const size_t kLen33 = 58307; static const char *kData33[] = { - "# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 128 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:37 2011\r\n\r\n\r\nCount = 0\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 27b5686c79b3d242f96d3892c6135b26\r\nMsg = 00\r\nMac = c98d11822b9b4d7a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 1\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b4542a22baa348ee2d11ef62d44cebab\r\nMsg = 00\r\nMac = f7a2a3f519fc462f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 2\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 7256e344f68b3e7f9dd6e04c5c65135c\r\nMsg = 00\r\nMac = d4d7fcc5f979230f\r\nResult = P\r\n\r\nCount = 3\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 7a2116595c5cf6482199d3312498006d\r\nMsg = 00\r\nMac = c3c4fa28709060b0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 4\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0341551d6c7e7c57f678068f0b41d1fe\r\nMsg = 00\r\nMac = 821030d4b7889fcf\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 5\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b67ba2aa4e9ea9871c3def87e2dd77f4\r\nMsg = 00\r\nMac = ea896182698ac145\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 6\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0091d39f3478d2c59bf874b96db9ce0f\r\nMsg = 00\r\nMac = fb12c5971b0f2f18\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 7\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 46a2e6bd3fd5336abf02eace3cd1e1f6\r\nMsg = 00\r\nMac = 9c6b46ef046ae1d1\r\nResult = P\r\n\r\nCount = 8\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 4b0fbd5e6f9298e5ced5ebdc60fc18a7\r\nMsg = 00\r\nMac = 221857badcbcd2be\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 9\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = fb20547da671acd4c6df37f6568a6428\r\nMsg = 00\r\nMac = ba0c9bfd3d9c0c95\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 10\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b787def50aaf446bf15c562434844562\r\nMsg = 00\r\nMac = ba60bdae64068330\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 11\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 67d77f50727c7cd5b38e0b175a888c88\r\nMsg = 00\r\nMac = 555923e6b5fbc504\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 6f552ef7d309bb98597b91cecc21e158\r\nMsg = 00\r\nMac = c2aa402c0443dfbd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 13\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 411871267919a145532cc401e753ebff\r\nMsg = 00\r\nMac = 167a31913228f45f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = abfe32efdf0464cb2eaafca8eac30d9b\r\nMsg = 00\r\nMac = 8edbc729b1923e10\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 15\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 85504d59a12f3e17edfb0b6337d4a081\r\nMsg = 00\r\nMac = 9045fd77cb26dcb2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 16\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 55f7565826b0e2ccc1368f4de32022de\r\nMsg = 00\r\nMac = f82395416a8dc209\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 17\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 43c8f984390debb0f26c6b9c2df8518c\r\nMsg = 00\r\nMac = b5d732086bf8feab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 18\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = da288d2014616f16a2abf5923dea49ad\r\nMsg = 00\r\nMac = e03b67b53fc7863f\r\nResult = P\r\n\r\nCount = 19\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = e2f962d076df051c2d291b47a902ea0c\r\nMsg = 00\r\nMac = df1456a7edeb4e42\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 20\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 191b53e0c7d90161e5e2014e9b8aea31\r\nMsg = 00\r\nMac = 1e210cff3c90bd2e2a27a78ef7662f61\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 21\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 54666bdf6db300ee10982d14dac828bc\r\nMsg = 00\r\nMac = 9fef67209b8da28049b80efe98f85f13\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 22\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9a143c21cc6c9528b9ddd7e4405682e1\r\nMsg = 00\r\nMac = 1c3c3b6d1d86ac5787234f8f6d707acc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 23\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 802047ee1309e548ae81e93a17bff9e7\r\nMsg = 00\r\nMac = 1472aecaa0a09e45893a14090ed9a17f\r\nResult = P\r\n\r\nCount = 24\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = ab79ce74c0959aea0fd0b28ea5d0afe2\r\nMsg = 00\r\nMac = fde8a95536cc334f7fc8881a187afc61\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 25\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 644ac6fdc1e713ecb7ff1e0bd5729a57\r\nMsg = 00\r\nMac = 95a93bb50703521e6c1a8be1aab6a646\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 26\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = b4571e56f66a857daffbdc99370ceddd\r\nMsg = 00\r\nMac = d2742ea62f1d6513c4eb0e533922f251\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 27\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = abff2b097d688293701ff2c49ba48eb3\r\nMsg = 00\r\nMac = 17e724f66d4a9ef5dfc0cf903f8ff04a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 28\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9d45f6d97d1573de3cb3488befaf5b7f\r\nMsg = 00\r\nMac = 96ec3cf234d6704483a93885bd67e6dc\r\nResult = P\r\n\r\nCount = 29\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 00d385629e5df815a5300e6635351934\r\nMsg = 00\r\nMac = cb23bb449ac26e2186b02f7428fa022b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 30\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 2f9109e7eea21b2615c81c03182ce603\r\nMsg = 00\r\nMac = 4532211f48124a9eacd795ea4313adaf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9f3830f5cd40a2396b6093b358cef1e9\r\nMsg = 00\r\nMac = f5ea59ec909a8ec2d8b11f5f276201fd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 32\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 17378e17c41586b88523a6b6af738dc4\r\nMsg = 00\r\nMac = 40cc8b388be6789aca584659acc7aa06\r\nResult = P\r\n\r\nCount = 33\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 064e8c88a0a0766186d75867b5ca3acd\r\nMsg = 00\r\nMac = b2f94222a68fcf803868b00404ad170f\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 34\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 1e39f1cba97dac4e4d4f3bce7fda72e5\r\nMsg = 00\r\nMac = 60763815c1075c31078a9b44fe4b8427\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 35\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 06f0e4618e0ea8fa5443b50ea005b672\r\nMsg = 00\r\nMac = 295c6cd08b1d668d9fa85ef851b1e029\r\nResult = P\r\n\r\nCount = 36\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 648d77b57770b67ecda1ce7951eaaeea\r\nMsg = 00\r\nMac = 2f3fbc6edf5827fce440b9a7ff8535b4\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 37\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 6f3938932b5c1280311e892280d8a822\r\nMsg = 00\r\nMac = df02edfb316350c81dbee385d6e1d8e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 38\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = f909903451d1f9f45ffcb93a407ffb50\r\nMsg = 00\r\nMac = d176620722c5327270ef30956d7ac02f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 39\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 181d92c7df1ebb0924719e066e08b95e\r\nMsg = 00\r\nMac = 144f688fa0d29faf787c48cd0765eecd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 40\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0c5b763b1e97b4f4dfc7059e4896ba58\r\nMsg = a0b3c6944b35f7208dfb40b4c4ba134a14dac928b679950793b3b6751221f178\r\nMac = d922ea85b3992a67\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 41\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 461d7d629778c8b05a688bee4fc01e9f\r\nMsg = 07571a6c9bcb6f97d626796bc74e551d1c45cce38afed761706f6264b7e751d3\r\nMac = 794b224a85396a27\r\nResult = P\r\n\r\nCount = 42\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = b91c6b09bf5a0487a9b5ea2fe0c1f3d2\r\nMsg = d31fd388e97727ba0a35d34ae05d9980e5974f6b3d86e2d4dd569b70f394a159\r\nMac = 2665ff2785bcb606\r\nResult = F (1 - Message changed)\r\n\r\nCount = 43\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0737836cf771e842a70f3eeed7206799\r\nMsg = fce631a9eb130178018ca88cec966ae53ecc83a51d0a73173c8a9af10b4d04d6\r\nMac = 1eee822e37dd1e84\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 44\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 120132c315bfc9c4fb93023f5d3500d7\r\nMsg = c2576ed3189eff3205f5e01dd8fe7c64f12dc73c807c22918f607f9e43fcc5ba\r\nMac = ddca15c8b5a80cb2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 45\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 5363bd7d867a9f9f0592dd9940a791e8\r\nMsg = f34e86b8803d386573b81045df945df8319a93b613de4c41904c8e1879844cee\r\nMac = 109dd7c920ebbf41\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 46\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 3fa1c7cffaa167557b250634e8052fa0\r\nMsg = 4255f8af18df7237e0abe98421aec9634443561752d893aaffe76380e829ef32\r\nMac = 0eceab8d28dd4a2a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 47\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6583a4ff27b6e109046d11b977c8293d\r\nMsg = b63be320f92", - "e01260fba37312224494a2764dfc928287c75dc1cafee7b698d48\r\nMac = fa0cced22e896b40\r\nResult = F (1 - Message changed)\r\n\r\nCount = 48\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 5949378fd3135dd02ee1929014000411\r\nMsg = 65c16f4e66b10c7c153be7ba2dbe3a6d4eed3b04fec44188edc229747d52f8c8\r\nMac = 9ef023345848680b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 49\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0e80fa889b1d96a0d23d236d4d642a27\r\nMsg = f6f094e46cdb2e45fe49b18aff1427ebdac9710fa7f47f75fc9ec7140613ef3e\r\nMac = a09774009934c9d4\r\nResult = P\r\n\r\nCount = 50\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1f88dfd4f5c52c22b1db47f9f4fb6e2f\r\nMsg = de433ebd1cdabeac46b94cc00d984f172923535ca8fdfeeb860546357dd8e266\r\nMac = bb17b3983faee0db\r\nResult = P\r\n\r\nCount = 51\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = ab0ab9e79ee53a6946a31ea807258dbb\r\nMsg = 89ddbb042aa2aea5207b312c9831fb48138aca90626ef7c5ce474d5797ae1b2b\r\nMac = 72f316d5bfcfcf6f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 52\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1eb19542a0064564e096e5d7d60acaa6\r\nMsg = ca25504f3f5559aa0e88199ce1551c9240b5c76f55b83bdbf2777cded54ad3af\r\nMac = d936b1fca0a96aec\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 53\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 33f11aa36d8ab0fc53486839a576b31e\r\nMsg = a58524e37c2504468f77a9c21b0e6d1a6b5e06fa051d5b8025ef97fa69417cf2\r\nMac = fd64f7cb283adce1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 54\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = a7b81d8245129aa451dcb7229de415e5\r\nMsg = 2b2ec02aba10aee056443cf90585caa2510b3b835454a99f1324567b0dcbe682\r\nMac = f4cd48f32c9dc66b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 55\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 3c1baf0d915e5aec92bb62babad0ba2c\r\nMsg = f8f2424c2dc0d0f3821af7244038da0832c547be4ff0850b98c04d4d44a716b1\r\nMac = e17ea6862129d6b9\r\nResult = P\r\n\r\nCount = 56\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 943a49073db6ae94a88844ed895f8fd9\r\nMsg = 8a15e5be479d3a39a459ca7b50457472cbf44f6a8324ee3d4096e2c3bf1d8190\r\nMac = adcce0ea2c8b11d9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 57\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = ebf8935f53dfb3bd40453c31f627c73e\r\nMsg = 7edddb03d861dc9796f8e069bde434681620f604db436f34b7a6a3beeec925b3\r\nMac = e8ea88729d49bea4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 58\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = f18e8feed77d1b80c31483fe69073d56\r\nMsg = 37c6206e23163c39a13f19de48cc25dc26e6f83cb376e8d2048ad7c141fa503d\r\nMac = 0d4f5cdb2a49b471\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = b4e41c7bfb8fcaa5236f656185c1496b\r\nMsg = 32758ae47884fcef766dd1fee1a7f55ca6f6691574e2ea097a68cd4072ef2e7d\r\nMac = bad08badb66c8e5f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 60\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 708484fba04972b815256c5dab12d5d4\r\nMsg = 97751b4893a83cfe6b760e10da795682e9668749c09036f9bfadce9dcbdd85e6\r\nMac = fa74b33267c5ffeca75e5e16978bd7b0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 61\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = d0df1bdf1df6203241722fb9c9c1cf74\r\nMsg = 0e41361ebfbe4e6580fb5751e58e98de8ee5d9849fe875026fdab15a85804c1d\r\nMac = de4992c9d33659620cc203848e42a279\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 62\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7c0b7db9811f10d00e476c7a0d92f6e0\r\nMsg = 1ee0ec466d46fd849b40c066b4fbbd22a20a4d80a008ac9af17e4fdfd106785e\r\nMac = baecdc91e9a1fc3572adf1e4232ae285\r\nResult = P\r\n\r\nCount = 63\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7b4c800f5071521119e4cc6deee8729f\r\nMsg = 775946f3014523b6ea37804585cadd35e74e9382ebc1022579fbebe407281b6e\r\nMac = 2f6697f5d067aecdb3ff5a09d9169b3b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7618d222630138cc14246e8fddcf98cf\r\nMsg = 432e3575a966958434da38dda3606f1f69adeaca536a7bf66c8b1e451edc3716\r\nMac = d7d78aac615ffc1bb32dfea41f2b8771\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = c8804fef18ef263c010c8a205e14516e\r\nMsg = f2d23bc605181e3894f61fa63d61ed4a610123ab7d3531c0b7579a58b74161ba\r\nMac = bfe5e2c10a5cecccd3de2529f340cf6b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = f98ac86ecb742c188852980b5150d100\r\nMsg = 4e6fd4fa7669ce9552154bd796644961b51067dc02303430150aacf671280031\r\nMac = 73df5f4d3ab9240d4fb2be775188adc0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 67\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 638d7d95ff5f57571261e23ffa081189\r\nMsg = 5f5bc4e32764bb00085667b7f1b15433f09c1f6fa48689f8f50dcaf5021f2864\r\nMac = 96b270629b2bfbf721f1a70eccf9abe0\r\nResult = P\r\n\r\nCount = 68\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = a5a20d8139472a4cb38993c5711ac2ca\r\nMsg = 73e1e75538f9a63e49a068189e3b0a1a1e65ca5d1295589bdafa3136deaa287c\r\nMac = 320647d53ccdf2335a9c9a3452c1cee5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 57656be54860414e8a62223381ca4405\r\nMsg = 3447e82ecec6c8b6fe1e44ed91f933e4a70c431911eb86eefe222d5ad78193df\r\nMac = 47c6b5a28d723129648aef418b74daa8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 70\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = e7b665600a2aa413e117c53816cbed34\r\nMsg = 5e4d49ab796025157add6d42258b9c506d9ce82bdd85c604360db0ff5aa4262c\r\nMac = e741166cfa2a58003dcae357d7a199b8\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 71\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 693cbb46bc8366086ec7cd7776f2c563\r\nMsg = 5a908ae85ff721ffc5096aeeda5ee83bddcf639e7be68d109394e5253c22dc9b\r\nMac = 9d56b03ef83082f601a9cc8730b0de42\r\nResult = F (1 - Message changed)\r\n\r\nCount = 72\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = b4190e3462e07fca26496adcb877724f\r\nMsg = 02097035a312cb02ea7f09fc1accc230a205e4a208e64a8f204291f581a12756\r\nMac = eb9604ec71aac0cacb63e0b369ae7664\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 73\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 4ae06c3b2940819e58eb24122a2988c9\r\nMsg = a2e7be3314238d7e4f604e134790bb15a87c09356c091b1aacb9f605b67475b5\r\nMac = 14b4507ae4b50cfe4989b544bede756c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 74\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 8d560de2e310ea69389221ce2e850625\r\nMsg = 04d9db45e4df19db757b9b95c25be43e822b8372ed148d49ce824a36da2b2f2e\r\nMac = 647f2874a083e82fa804b6c58c7b5c90\r\nResult = P\r\n\r\nCount = 75\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 0e1a79c5d734118c19eaba700f5da238\r\nMsg = 026470d57dad9893dc037b80978bf70c2e552fe46c8fe8c3ebf8338bda984d94\r\nMac = b936ff3bb8afb9e42351a2a3ad49d70a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 76\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = c88b1bc0050e19780ab53efbea175634\r\nMsg = 7207aa8fa87283f1f57019bf1c89645ff8fc36ab1102704e6d577671a9f7e098\r\nMac = c1dbd79e31c3b0bb824f16f735ccdfe6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 77\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = d87df10a53eb3ea24c003d2a65e44921\r\nMsg = fedd5813146a8c2af398d6066956829833b75e44b6e010e4f025ac0fad6f869b\r\nMac = 9dd7cbb34445bfb351d01e8cdb21d695\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 4d436a4a5c02b22ad49548b97216f277\r\nMsg = 2d73204f0b2d35806a8227206922ac9c18eff6ebddc73809179d67a702cf3e21\r\nMac = d2654d9bd6396075296cbe918d90670f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 79\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 8af7b74e35eb38f4086343bc329ab465\r\nMsg = ada1fa439c653d0cc88c0d129ba252e86c7d20a3087be93e920bf13d8e6f0391\r\nMac = 0fc9b177c874ea909b6beb1db1b802b4\r\nResult = P\r\n\r\nCount = 80\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 91ce6c87860aa84053f42e1abc16f489\r\nMsg = 4c287bc16196698d762d5fb428e801975fdaa29026b7b78dba968bfee0f534f27cfec57c6009c55c6261e0dbb14bddf76944d0c0648b910254df6c240e8a1a50\r\nMac = c1ce12f51aa823d0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 81\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = b7b774e5c9e2f6926660c48b8df52354\r\nMsg = 937273c7355e7b88a630d15be875234cacaa44e815f31997bf10b52c008cc3bb6d3724aaa0d7da0b391b252923d0eb6119575d346857d89af6af099883af5514\r\nMac = ff845eb2d77aa5a7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 82\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = d7572ed0e37261efa02f8c83e695efdc\r\nMsg = 85a327b0c7a31a4116e7fae0c0971e1578ab6fbdf90124b9ecacd0e70c909f51882cdca5a8b6b7e6b46d4660122bc9e1ae3932269f68e594075dbc293a2d4eb1\r\nMac = b8b3b7526419e069\r\nResult = P\r\n\r\nCount = 83\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 259129eb760f8a770410c160e4e13a6b\r\nMsg = 77d9c30", - "6aa257379053cf1f2043c388a301dac2a9e2bb89eb8bab6eb3f150fe391b7a3f628be6b4b649c5c108a108f0e0c55a0800b9954251ab07e94450a23d0\r\nMac = f9376f11cbec0ec0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 84\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6ccd61ed20f16ca7a78192f5b6ab5528\r\nMsg = 9211231ec382ecaaae57f34de1ac6bbb50741014a978160ce59c60491e64f30da0b8aa1442e42bc0f7e31973a0dd8c3c24eebeb7c329072ea7dd0b04bc163254\r\nMac = 94c275e6a4675d8a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 85\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 1cdc44c40efc3c0ed6fb84b0c2f78aec\r\nMsg = 818c636772036761af037c23aa8cb63e424f0ba0375b645de2f8f5af23d3ca3b9a5ca3951a6d02075a2c828eee326a2676ed8247164226b0267798632a519bf1\r\nMac = 74355397c7a29bb1\r\nResult = P\r\n\r\nCount = 86\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 2e523e9d8a5532127ec63b220838f11b\r\nMsg = e6d067907610109b8789e1ad00542539991677b9efc97a98d8bfcb50f3e334d0844323207fcb5a47e353e76d49dd573dbd17278dcc287b41dea8126cc7f07ab9\r\nMac = 7bd6745c6f73d92e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 87\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0eee5bc8994b723a580f67d45ccb194a\r\nMsg = 1dc4fcbc73dab4e73ed9d7606acdcd42b74972460c640fe50f028abdf255d9368fa3bc65b849ac31c8000eb47e5fade40ca167726aa927f2f043133d24ad0613\r\nMac = 486721355fff9cbc\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 88\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 388468d10bf0b770cc125f8b7d359261\r\nMsg = b9aaadfb3f60e48f1b421a9450129d75af2ce811ab0b1661680e9d5b147c38167ac7252ed40d916ae1e4519c3857d2c9dc2c538a106951b26d16433131438839\r\nMac = e13cef9392f4a80b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 89\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = edfe2e15edf0b0c28875651d4becfca5\r\nMsg = 70b1e2e4cf260b108f5a52d0d8234838ffd6ffe7b4acd78d7d6b95aa6342b598eaf402cb47396358ce61f8b4aa3a65bed0346e0036c3c5323f051f007aa58d0e\r\nMac = 7b70730219907d18\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 90\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6876df1a77e11165331a5ce2e0e6bea6\r\nMsg = 34b73ba208bbe1df06da768b0321243815df4ece555974dee2bf5732295f5ea9631939425e13c47681ae2ecb0bb85aa69be38560f5752a9d034222d91ad71044\r\nMac = 80e00df873439fe7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 91\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = e65d5fd5f446b4eab63d56b0a5eb1d29\r\nMsg = 554395f9b113c0f2a1f155de171d6c0a805c838beb90c3756e8b864dc52517c03d8cb894d1dceae092f0e8784c7775ac664ad7320afd246086b3bc9ef237171c\r\nMac = c60f8ced2efd52fe\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 92\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5bdbd06f4df6e15d644f3a635d7bb14f\r\nMsg = 4fcc7c2763a8dd5bfe74e34f512be8042af9ba1c73a944edfb616ad47a8d34cbcf192f3e8be3101bb3709b29c2dec39aee1913e3ac524ccb76ad50c2cc3a3e75\r\nMac = af33d5a2746bfa5c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 93\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 13bf2f72211cc8e16ac1986a22e19f60\r\nMsg = 8ee212ed4bd110ca6a91b37bca59e19ba842e3a1b50619bc6b07ec02a09303ca5c66ba56e870d0b627d95fe829431244fe4f9218c862418f14a92bd76b5a3a82\r\nMac = 18e8cd5bd42c75ea\r\nResult = P\r\n\r\nCount = 94\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = e9b913c2f0630562eb1c16b3b1ed8409\r\nMsg = 031105ff01daa66ff95834e47b6f5c683994084d0fcb84c140d1dfa2039a95933efe6a4f91af993d966e2e45677eb1e36159047928a38eeaeb5c9a64ea59f97d\r\nMac = f00a17da0fb9e6b6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 95\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6fa5a5991315702cba3beb33867c7bca\r\nMsg = bb0fabffbcc6935ca35755fd4bfbd192b6812cf75c4dc95bc3a175a1501be2065d7f57058cb7a5785a185dfff7e740a5551cf7c17e65051b2c6ef9509360e878\r\nMac = dcfd143f86442183\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 96\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 3f8c6d21ec05bc439bf82774f1812bd2\r\nMsg = d726deb8537bcd671ddbaff8fcc6968f951b71aa82dfc802a53aadb2bcc2ef9a35fd90064320798b311d6d32f7dd3cd90bca39d57991eddc36260d23b108aac3\r\nMac = 449e20567875d56f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 97\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 8ed1a4873bb37fafd4f8c2ee417443cf\r\nMsg = 1652c9539bff4b6e9f303f3e6b5d4b9ff7e85aa2a401ee8c2dc7b722dbaf6424f92ab9188882e2483405070e8666204f5a600b46949cdb830fd57433d63a55a1\r\nMac = 601eb06acc5a4e0a\r\nResult = P\r\n\r\nCount = 98\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 83a4669cb9961448cf418cb83a16098b\r\nMsg = 26d97c3e28460d46216da39e043e024ed08e387b1e5fcfd3f962472cf1bac4676b03039b3b93927075ff41c87fe1d4a56bd9fa4784d283942787cdbdd5457f1f\r\nMac = 01a42494a10691ce\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = c9e6d0b3dcd8ab50ba5ff31d9c1bd95d\r\nMsg = 0d32c1cd73569ab2b10c67c167875fe22625358ed3469b424c5e052d4e49af2c97dfe1f947c972a08c938b327e01adbc48a7f57a89b49f49fa0fca5b50a57a2e\r\nMac = 476add8ee51b5e3e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 100\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 17281acb525b13653000ab45d86e7010\r\nMsg = 225750ca982e5b34fc62e277eaaa0f248532abf374933e572b0278566cc7cf980df26abefb493ef57f8477cac0bd19408a22e71f4ded84906996d8e7a846b5c0\r\nMac = 0f2aa7f2dffcf7df34c84d101aa9bab5\r\nResult = P\r\n\r\nCount = 101\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = d3624653ad0ed144667df0e0e355c29e\r\nMsg = 39dd298acc45cb597f0733572677f7102536c0dd86fcfcc44895d29af92a5b6a87c20f1b53087d4c874f4083aad32e877142d20ad87b1d8b7295587bfd235d9f\r\nMac = 795da5a50f5b7df40317616b5a470c02\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 102\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 813b3d579664cebe50a8e7050a0b4e65\r\nMsg = 78ad6517a09b99c1113d175f3129aade4d4a2516ebe054f15bc833d08ffe5e2a2d60c976e1b4b14cf8edd2c72baadb2db8001fd2b8798d39ac5ce27d592f1def\r\nMac = 20f40553bedb6496233e0b53143b6d10\r\nResult = F (1 - Message changed)\r\n\r\nCount = 103\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 21095cdbe94afa27d84bcd68276993f3\r\nMsg = 10525eb2794d03409faeab22a6d4cc4ebc0421daacb0e865b0f94eb387722897c827e31676debec9d49c36837b6bc234a95bc10ddcc7b1e5a0d9a1dca550e93e\r\nMac = c0b806ce5eaceb51b53b028e6efea9c7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 104\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 6c769a4822523525bb36c02518475549\r\nMsg = 4af38908fa44b46873535b39f432d9b3e677f6d06d8719af3d15b936afe515fc13d62566481fd0108bd95f6e8dbe32b3c830b1f1127d868273610aa834ccfc70\r\nMac = c1934b9c74127cfd515521df330c0333\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 105\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 6b454930925ca09d39e1e39a2e78fbfc\r\nMsg = 2bc884394ab7050c14d66fb8901cac109c0126668d918a4419bfcc5d75fb6bc2ba07f6598d06cf8cffd62f3eb29f6a033eac7490d27aa4701f0fb9f9718d1b7f\r\nMac = db19b8ef218018e5a53abcc39b7c514a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 5df295be7c44d59c44fead3f1988356f\r\nMsg = 3d7370cc2d61af35bf7b2ba50a143b23bfa0d1eff66c5ace2d8de5a28d17883d708fff7721a2977ee2164b6e34022c22523a0649ff0e40bc8134040fee02a065\r\nMac = 81b3181acbc2d6d2960ec57441ff3c40\r\nResult = P\r\n\r\nCount = 107\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 387fc73be9f019913f2222d98053f95b\r\nMsg = 944daaa76249bd9d3bd517d01b074920b7d4434d1a2618af902e0228c3fca658244d990f8ca42208239c42d4827cf114140cabebc2a72bb3cf9277ef008c1c81\r\nMac = 5de79be9ff9c3c9d64f9cce35b188648\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 108\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 7424990dee834ad05f4218861ab21eae\r\nMsg = 49fd56dec210e903f6c703332637f9c267eab9333e2701a16c74ce5e0b5a16d9da68b9c5d67bb6770a3c9a90a7e93fdd5759b27bcf3a753fa39ee7545fb60026\r\nMac = 38b66049ee8ed81f3f8ce2b45a4001ad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 109\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 232407986ad4a8e438990fd04ffa35bf\r\nMsg = 9d88a7970d4c58cecc20ed1811298a5b37297419ca49c74fe216679dafc938a656cb92bafb78efb31f24e71c2d5b5f994f6dfd82862adfd2faeb8c408fd22aab\r\nMac = 313d46dda3ccb75f497f9069c9478b3a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 110\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = d9bd6ac153cb0bc4e19e59c45cfe0d6f\r\nMsg = c68094c26c7f017b79f126dc26b3bbcb95f97535ca412da5f7853e15fcb52f042e6492c857c22b26ffca5520eabca20ee2cec2f0b71ea60383ece49232065e0f\r\nMac = 3b17778955990ae58e03feda7fc43998\r\nResult = P\r\n\r\nCount = 111\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 857fa35c6f70f637a9a5e6f215c694fd\r\nMsg = a1fc1307757ed91665980e2d3cf9778d8bffc9a84cce6bd5c5a07e47af5c1b409869db8286c49d07dd5083f1826e3ec441ce8cd36c85fef8c55fff889e761286\r\nMac = e1ddd63db51d3035adfd309ddc186238\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 112\r\nKlen = 16 \r\nMlen", - " = 64\r\nTlen = 16\r\nKey = 501f5c58355d1800f155f272dd09afee\r\nMsg = fd3564848ceb5d8cddfd50732956d18b4af433efc2e2a914ff66aba1de7b9b816d81a936f534f47038dbf1def7c11144b7e99ecec5fee6a478899cbeb6677bfa\r\nMac = d995f9bae6150996cd9b798fcbc623c2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 113\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = c1d636989dfbcb0edc9f014cc82da6b5\r\nMsg = 20ef1bbf8a719497797f1f1bc4617179ea682a24a92f0831cd215a01473bb8207e13f26dea1a467bde1ed638a51359ccd11210c4d0a2fb70c0374e8984f81f17\r\nMac = e4972a59db04f78da1728cab051faa98\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = b4bc5a4d40716fb06a359ef9537726b7\r\nMsg = 36594fae7b487798d62c2c95ccbf51c984df5ca6343465b2dd147c8b36a34028e53fae61f51b36b28529143cbd3edd0c077158a07bc490a79a06270940f7ed27\r\nMac = cfb3fce039ee2bb94b6961ff86688237\r\nResult = F (1 - Message changed)\r\n\r\nCount = 115\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = dc796e5d9b712c798922eef315cb4728\r\nMsg = d5755c40f52364343d2613420441afe9da9a5329d3c1e5a123ee49f5eb8ad47253f104f5d9776e08e9a9f74fadd5472326cc7b7c7ce61a1492474bc9de614543\r\nMac = 315f0ce76352448bbd8a5012a9907a23\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 116\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = b82fd283922e730a07f7ddb87484f66f\r\nMsg = 94e47b82b728d639777d5d5843de2a5c364956cb4b21cabdced2529b10b3f4275f307fbc352866d7b094cfd7426ae801aac17ac72335c04adb8d791da69b3c4c\r\nMac = 86e6a8485b43f1b258eb59688af91fbb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 117\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = f6db7efdfe73dcb4a26b8448842b55e8\r\nMsg = a1fa1fcd5f095b2768e32cd733365a136a108e7493f212aaef27d86da253beb6154f103099344ee94db6304e41b4e856db0ca7fd7ab462f45a07d697b85cca1f\r\nMac = f998bba6c5d3efd78af9ef57e7a38f7b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 118\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 3c1ba92d096fba134dfb4ef412b2568d\r\nMsg = ba7725d74465f5d92454bff794e0be51c4d0af7d88f729834d57312c528d0a7d15694a7e0bdc334093173f1d2df1fd42e7891c6b192dc5ee527b2ffb92c66d22\r\nMac = cfe6022ad29a54627ae7c4f907ef4da1\r\nResult = P\r\n\r\nCount = 119\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 4a92337f017a85b136ba6766444bbe84\r\nMsg = b0a3a8aa5d4bdfbb4c5c52acdcc60405c379f752b077eed42f2d7777cc0329047b322b9837d5f655ea445b578d9dc7e990a3c6f97cccc6cad7951ee948194e62\r\nMac = 153eff3c035db2fdc752ebd22302adae\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 120\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 305ec69b23e4490e0f8a5241cb9c8c85\r\nMsg = c641cf589020b94026ae\r\nMac = 3bc054afa9771970\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 121\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 28929286bd1391468ac75f5c03689f74\r\nMsg = 3813592f268a7a863c3b\r\nMac = bf1b514d2f899620\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 122\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 1b3163e2d3a471b9823525abc7543c4c\r\nMsg = cada03e8c967f9732a81\r\nMac = 53702fa98e6f9a19\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = be1ed49e2cb0caf6b6a0940c58453b93\r\nMsg = 4a348c5ec996f7a97ef0\r\nMac = 3358d143dff4adfa\r\nResult = F (1 - Message changed)\r\n\r\nCount = 124\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = f18be18df045ba31b80f3283cee6a681\r\nMsg = 93006a06d7e6df775b19\r\nMac = f3252f061dce32f6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 125\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = b9dafe18a904ba761762ec3fe0e4120b\r\nMsg = 173887316279a47fc699\r\nMac = 884f5b21d478d60b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 126\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 31fee08df80cc1009e661230e25939fd\r\nMsg = aa54ff7466923b265fb5\r\nMac = 03dd2a9616f653a7\r\nResult = P\r\n\r\nCount = 127\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 65a28d970b2bc7afafb4069c26d264a4\r\nMsg = 1aa5a3a4e6c5e5394e50\r\nMac = e0423589b192caab\r\nResult = F (1 - Message changed)\r\n\r\nCount = 128\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 6dc38e37d1379732df4dd535db88d17a\r\nMsg = 0093c6d94aed50b398ad\r\nMac = 19b08e65d391c491\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = c5329fd99848e1cdcfa406ec09745ae2\r\nMsg = 6d83d0ad7cc7efd0d2ca\r\nMac = 8ec2709e1466f8d3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 130\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = e608914a930b9c300b677afcb8689d63\r\nMsg = 146629e70b37d8b83ee8\r\nMac = db78a639bb15c84c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 131\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 0a998d3d390f5a80ad398b2070489984\r\nMsg = a91c1a8d9d268ad153bb\r\nMac = 5643a8c99b99d944\r\nResult = P\r\n\r\nCount = 132\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 2b6f78ceace47509a43ceb6b761e7866\r\nMsg = 3c0a41a78240c9d2fc22\r\nMac = 811acef50d6c1913\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 133\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = ca481f557306f9ce386edd0cfde375a5\r\nMsg = 9f3488736ef6e2c3a51b\r\nMac = 57e8a0e5965399c0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 134\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = c0dd1cfb3add04cd67a8e59be7ac8dcf\r\nMsg = a7c559c82776f429ac31\r\nMac = 7e43a2b43d030ff4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 135\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = d3130d9e5ef516b6bf172953a37913a1\r\nMsg = cbe97e14c3100c9fc564\r\nMac = db9f674a2d0e9ed9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 136\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 9ec8661a880ebfd15fd8b04f2ae09dbd\r\nMsg = eff803e0fc809cc48587\r\nMac = febec8d41b6bdc1f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 137\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 6c2b091433833a0ed915354dcb70d982\r\nMsg = 90f1416768fca7dd48d0\r\nMac = f6ada24319e502ab\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 138\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = bc79d444dff9d9e722effab07b068cb7\r\nMsg = 07d5a925b724e2443936\r\nMac = f964302c270af24c\r\nResult = P\r\n\r\nCount = 139\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 1a15b24ba5d9648358f2c39c9da8512b\r\nMsg = 15b94910853a8f23dfb8\r\nMac = 8cdfbc13239e6aa1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 140\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 618fb69c8fb670250c306b3225687d17\r\nMsg = 7f54845a57d916866eff\r\nMac = c0d4db73891bb1efa232593407856808\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 141\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 8000aa080c127cbabfdfa5d9d9728c7b\r\nMsg = e53101e6eabcda32c13d\r\nMac = 5671badc409d4b170d4c861a0b3e1fec\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 142\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = b05b5557ab145cec2f00706dbc6a3c23\r\nMsg = 5e2f601395ec406fcf96\r\nMac = d00243508d25804548c4b4b512cb1906\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 143\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = e8b13346b61daedc1f9e3b49df8d1cd6\r\nMsg = 0593365419e0f75b6323\r\nMac = 871eb97850a776e7ad498467064484f9\r\nResult = P\r\n\r\nCount = 144\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = bc498326755503ff25d02805eb351722\r\nMsg = 9ece4c82fe9d38ef64ac\r\nMac = b5e88af50d1cff3d2b6d304edf042c43\r\nResult = F (1 - Message changed)\r\n\r\nCount = 145\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 4d248e73886a0e36b3ce7c6113477f4d\r\nMsg = 8de6fe3b24fd6c202ef0\r\nMac = c1a4f6d0ff7330171cfe570e900ce2c8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = b1b9fd78e3f8eaf4e8c91da62b2da534\r\nMsg = 482ea6f652067e8b791c\r\nMac = 63c6994c98bda91723f832020fa7d223\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 147\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 85e4e63341658144a99fbd17d94e3177\r\nMsg = 21ff834bec4ec6384522\r\nMac = 580c1e549a2ceca4743256a9cc972e84\r\nResult = P\r\n\r\nCount = 148\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 88b5448372548e6aab1b262630a28a47\r\nMsg = 36dbbff560ef04ea731b\r\nMac = 5fd17fd704baaf1ae6b3330ef2989dae\r\nResult = F (1 - Message changed)\r\n\r\nCount = 149\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 8cc76730ca47620d0b437112a2c93fd0\r\nMsg = c73be9f019913f2222d9\r\nMac = 2c73e2b5b84d8f4f3db1fc92831a03bf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 150\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 7b657c640f155f1ff461c83cd656614d\r\nMsg = be9c5e77bf1b9dcbd4f1\r\nMac = b660ec36c0c0b4d987439505f1bf57e8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 151\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = d5044e9f10bd274aad4f7e605bb828f2\r\nMsg = d0be84df789c98dd125b\r\nMac = a26e513b09f184caf8d76d76961d1466\r\nResult = F (1 - Message changed)\r\n\r\nCount = 152\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 24d6d4bdc9fc4cd05b2867e9123acf18\r\nMsg = 0f9703a3454c25c0b105\r\nMac = 41676ddadb7b960e0269c8a59a6d9b91\r\nResult = F (4 - Key or Key1 chan", - "ged)\r\n\r\nCount = 153\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 6aa049d06bf66d2e2b65541eaa3730d8\r\nMsg = c562ab24ae5cdb7654df\r\nMac = 0d4d1196158fec46bfa754a526ba4a25\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 154\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = cf3727509577f1932bd7a92589c11e67\r\nMsg = 831188efc5d1f6dc9bb8\r\nMac = b5d162c885d7d4f6f65f4188d6582240\r\nResult = P\r\n\r\nCount = 155\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 0bc2fdd890c19882640f8d4188b88b9d\r\nMsg = 296828cbee50f41d19b1\r\nMac = e583d77645a603d841eaafa8860bfa91\r\nResult = F (1 - Message changed)\r\n\r\nCount = 156\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 5bab8051e2520b75673068b9cda93cba\r\nMsg = f16cba03402f9924daa3\r\nMac = 97f7eab25dc3ab017a9affc0e400dcc3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 157\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 7ac46e3249ca28e1ef0531d80fd37c12\r\nMsg = 3e9ddb8121760bffb7c6\r\nMac = c6eb13d5087d05b4eba2e74b283b7fe3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 158\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 40f78f7ad3eede36e13bce222c6a4bc7\r\nMsg = 4fa8ad212ef73d37d48e\r\nMac = 3831419e62b51b7ced0d9117e48fabf6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 159\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = a1f82c9924411e98e6f93fa0d07559e2\r\nMsg = 7d4748147575bc0113ab\r\nMac = c23dbc58fe22b34f7b007590558a3080\r\nResult = P\r\n\r\nCount = 160\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 84760f98ec565d281496b1295b25150e\r\nMsg = 9ce942ec81f8226506d48788e3acf49fcab6da22\r\nMac = 606c2f459a9ce198\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 161\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 3b6dd5169350b230774b02b9b44f06bc\r\nMsg = adb1ad81dac0ebc650d48f7a9329755a83f293d0\r\nMac = d7ceaa858508c476\r\nResult = F (1 - Message changed)\r\n\r\nCount = 162\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = f98d00755bcb45e6822121fe7cb03c8e\r\nMsg = 7064a2491f716f4a2969815e4a281a54690ced9f\r\nMac = e14634c400b9f561\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 163\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 5d27cb435e7724a246f158576fdbac68\r\nMsg = ee8ed4c12b0cf7c03bf91fba31a6a7b2d64c36c4\r\nMac = c10b474c0077a39a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 098c12058a0bc5951fc092aba322e1a0\r\nMsg = a2b76835229017bd0e8167a40ea1e2e18cc5db0a\r\nMac = 1d44128c3db0f7b9\r\nResult = P\r\n\r\nCount = 165\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 74f7f6516a17d5386c289756240241ed\r\nMsg = 8eafce9ba466fd53eb87f499d7c76bd486db0e90\r\nMac = acd978e0065375b6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 166\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 013bba67d26c7e52ae48dda3b67c9c96\r\nMsg = 48c0d53b85e6fa4928d3e9953afb9b451bc91a48\r\nMac = ef41ce0d30baece9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 14cea4c46d837c9439b088fba0e9d85d\r\nMsg = 3477384c396a9e9efb3e169722cba779fef240c4\r\nMac = 902158426696c229\r\nResult = P\r\n\r\nCount = 168\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 24f7b08fc2e6af6402243e22ca0626f9\r\nMsg = 914cf55a3fc739b5f87ac7518cc4171b4499d951\r\nMac = b775a3c1dc11d074\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 169\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 35b5428d440503773f30748ff843be68\r\nMsg = a5e5804cfdded4d610d1b05b7313ece84f369ccc\r\nMac = 6dac0947366be803\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 170\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = c8afe4e5b1d019c2efdbeda65d874ba9\r\nMsg = f739e632436470b5a1db9fa9796ed384c0523f40\r\nMac = 04c8aceaa8f8c3a1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 171\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 05a7910edcd7252b37e6d3d080a9ee90\r\nMsg = 702db7761abb9b5de41a86c8659270570be9d52d\r\nMac = 889a990539cbc30a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 172\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 4c8b0850eab7b212ad96dc7a032f8855\r\nMsg = 2de32ff6ca41b4c97424b121b8ad4edb133c00ea\r\nMac = f5ce7f46d457ec37\r\nResult = P\r\n\r\nCount = 173\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 687bcb63755f2b5c7daf4a154e8525a8\r\nMsg = 02778ca34db1cb5df76cb1a7619448f67d63b26d\r\nMac = 49d48bb0a684c6f2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 174\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = f8c4e562fde4379b08e512b0132766a4\r\nMsg = 627868b46ba546252f4eaa1c25205ccff72902d7\r\nMac = 5459c0ac5bb6701a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 175\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = dd235b05c15479dfe0326ba206ac784e\r\nMsg = e044ec24ddc0605bca89925a4ebc0234811e2a0b\r\nMac = 5ed0a03da09555b3\r\nResult = P\r\n\r\nCount = 176\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 665c2d7d6e69c2ce8f0d06b41038b83c\r\nMsg = 4fcd7541000cfc223fe9da6a030c681d0fb926cf\r\nMac = 1f022feb38ae6131\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 177\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 2efb7cd914a59b6ad63b7d1812f254db\r\nMsg = 67c9fe3e163787705a20f2fc8c468c4f771991fe\r\nMac = a866d6a31c0b42e6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 178\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 74f6fd37ccb4b7702bb3a03b7322c0d5\r\nMsg = 011ecbe98c5cb7734476dedbb852e2474a5ad594\r\nMac = 707ec713b9bce5d5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 179\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = e673b3a954a00082cb7516ca9a54d9a1\r\nMsg = a6fbd41a838bdf0fab3e7b56c27a8c18dc4bf970\r\nMac = ad4dfde057b54a27\r\nResult = F (1 - Message changed)\r\n\r\nCount = 180\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = ce5bf070678cb07e963263b1562ff793\r\nMsg = 2bd10c4397a19fc79a307116a0847e0aaaefe813\r\nMac = 299e5910f128a1f091dfb6b70f6a60ea\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 181\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = bf144c9bb974729aaa1188ceefdf85e1\r\nMsg = 5e1ef2ad86ceaf5439fe87d2ec9bc41b52e5ba01\r\nMac = 58b4a32ae55966e42712721363ac9eda\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 182\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = a0cd07b684bb9e0e6692e320cec4510c\r\nMsg = 6e1e490a30f0c9e3d3b79f1c36aab742bd67c585\r\nMac = 24dd518ffffc1070f13d50d0bca42711\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 183\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = e3ceb929b52a6eec02b99b13bf30721b\r\nMsg = d2e8a3e86ae0b9edc7cc3116d929a16f13ee3643\r\nMac = 10f3d29e89e4039b85e16438b2b2a470\r\nResult = P\r\n\r\nCount = 184\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 4073251950e3331d03d67a2399576d28\r\nMsg = d5dfd0321b26e578fe987456ff061dc1cdaa4161\r\nMac = ed2823fb8fcae918064cef6211646e50\r\nResult = F (1 - Message changed)\r\n\r\nCount = 185\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = b08f47101365111133d974e8f0206507\r\nMsg = cefe484955fae117649ec158416a7439f29a596b\r\nMac = 3317717c6c0b138275090ea961c8d58f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 186\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 166fb8d0e110124c09013e05688605ee\r\nMsg = 24c65f715742da7d06046c783a35b2648180b4f2\r\nMac = d27901a86dbf0ed8bde0d69203646b7a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 187\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 20f6f56117758ba47a08dadf93a59056\r\nMsg = 7514e0f402e73d9c0b0576782011b2e6b2080a6a\r\nMac = 11cda489b6dc0ab48d111ee6cb26a829\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 7fa6ef35ad594a09cb74daf27e50a6b3\r\nMsg = ac0d616ed7dd3c3e86b3507d9f2bdc3a807d490e\r\nMac = fbad2fc6c9d0e5d21b25445f499eee10\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 189\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 815871a8300471dc325f8289d0d37211\r\nMsg = a8ff31e90556236cb4df078943c1f2528b42a7ce\r\nMac = 5544c93de980bcf653354ce08aa9dc3b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 190\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 06aa3f6fc20f867b42ec234a1bcb8665\r\nMsg = 25df5cc617e6e68be181694721a2a112a1bfb7c6\r\nMac = 2eeb7ab470caea3317a6336f5eee24a6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 191\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 860f8fdb021b1974d40e3d4bc41fa967\r\nMsg = 6c982a616510db422cc2f1beb955c3e7a88b6097\r\nMac = d2280a55cd0bcd18846b4e30db6322bb\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 192\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 15105c6285a9015d0edd414d6a806bd7\r\nMsg = f1cc55636836e67909ed3a581de20630226dd5af\r\nMac = e9cc5799a630c6f26087c1bd3b6f1791\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 193\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = b47aa890b03a8ac0dbc8f96c30fdf7db\r\nMsg = 58b06c99e0d0256cb1c556ec3b48a3bce73450a0\r\nMac = 3376cacc247686832736cea7e67e13af\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = dd057368033252d9bb2081a0b1a0229e\r\nMsg = 81de8f50fbe35f7ed95430e74d28666c885b6100\r\nMac = faa08c5a3a4ffdce81ca31873197d0", - "35\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 195\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = baf5afafd7d0c8ad42a44e4e0a90fd2c\r\nMsg = cc5a4209a6a60dcf12621e17150b4576b918732e\r\nMac = 5a43002d9144a1d5e48c2dc8dc167a52\r\nResult = P\r\n\r\nCount = 196\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = fa6405355bfb5065dc81e764d20277bb\r\nMsg = 5dd1febed8e94d4715e772c3295b48eaf471daee\r\nMac = 29e96ce5ba930134670b3c68b5c512f3\r\nResult = F (1 - Message changed)\r\n\r\nCount = 197\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = ad2e3d3af6195e74b3e43296b1f618d3\r\nMsg = ca776f79b8581014ae58a4d533b60483fd1fbbd0\r\nMac = b32ce1f493b126fccb9829d4dbe76382\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 198\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 04ae7190f0cabd117d30a359f80b720c\r\nMsg = b885e5e147f967032ab2552829a6e09210c44a45\r\nMac = 9386d73a01960ab399bb7d290674b21f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 199\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 51fdc65f6bb0d20a3c08ac1493ddddb2\r\nMsg = 1f0a56fb615b594d938bb8a27f4b2f5463ee9a61\r\nMac = 8506fb1b74806381e2654c8764464d8d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 200\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = cfb7e930b838dc3644f6c06f2ad0c8d1\r\nMsg = 611db4c194dbb54d80a4f4fa731cd9a6a330eaca734d3351f2cfebaba4bd541d86b3e35b4c1fa158edb0d15d610cd359a9c24878117f77f6b284f0363a576e0ef0\r\nMac = e9589a711f5d4a5a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 201\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = d179dfeead9d765d000462785459b1e2\r\nMsg = 795ee78ffdf302f3f1f2b31629ae918409cb42979afe3752dd14968d603678520e6b55884b5ebcce416248aa74b3cfe39dfedc2bb5246001503ca4d62cd7826f0a\r\nMac = f16ea84f554dfb54\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 202\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 22b7eb25e688672ab0e17206623094b0\r\nMsg = d830b16fa236a1dbe60f6db8d7e81a3ddb5f658c9f446e94639cae3699ec2ea6afb4fb152939d58df287271cf4b73c34e66eaf5265a623de47b135522c7aaf9f55\r\nMac = 16229efcb7523025\r\nResult = F (1 - Message changed)\r\n\r\nCount = 203\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = a64fa98b4662d801159f61eefd1c8bc5\r\nMsg = d5982c462ad40458660cd7b120ce07fce9afe812caedcebdee536ac19b5d561d679dee8ea85d62552c86093a2ac1f8d179dbd4fc006ee4b16ebe6afd2be134498e\r\nMac = 2f9a2fbcb96461fd\r\nResult = P\r\n\r\nCount = 204\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = e4fb10325d18666c382e6cc2442381e1\r\nMsg = dc28484ebfd293d62ac759d5754bdf502423e4d419fa79020805134b2ce3dff738c7556c91d810adbad8dd210f041296b73c2185d4646c97fc0a5b69ed49ac8c7c\r\nMac = 8f771ffe0c8d3445\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 205\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = fdcd3459061c36c9a0daa0dcab2b967f\r\nMsg = 1cfa3342540d03ec3fcc8378c021443ba3321fbc26dad7c5b859faba004a082a21d6d7a43d2836cc3820d1adbe4c55518714d48fd9346a254f702107da8212f605\r\nMac = 6635f9e17949a14e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 206\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = fc593384e6eebc508d181fc49ee10e56\r\nMsg = a6c891c9dd1fcc982c35bc74cfe71651bae424602519672b466d80e160af51eefccc5fcf76467a25bce1a10853a0209d9beffbeb53228fea5f1e77ddc956ade207\r\nMac = 7a6fd94e3928d2a0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 207\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 4e4ff248f591ca27665960d9357a8de1\r\nMsg = 198d5c9c4aa35d12b62e8c4bf6f3f141e6ebefd8ab396c71f55e32bc82b094cde409547383bcc4c5e5cd2cfd2d616c8ae273e260f2c98e93f7267424b8c2421bf3\r\nMac = 9140f91a0cf70762\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 208\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = f20826990acdf225d9451a3d22f89747\r\nMsg = 03d340904ace1cd52d4b72a96d96afd77aee68ac3936415005ed0d56f46036915b1e5f2994ad49effe7bf3ee46170642e5a16f2eea804e68fa520fb79529d6c09a\r\nMac = f30b668f16bfe6c4\r\nResult = P\r\n\r\nCount = 209\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = c231ea8b75c65de68c49b76e7a3128de\r\nMsg = 5b50879191a6debdb96c0bfaf9086b7dc6e25594416b08d2c75fe16cc347d2e3c7410fe3dc030a6c161ea22f6b80973bc43d42d8558f83b32a1bfa3c03757a4d62\r\nMac = 65ba53ef4711e807\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 210\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 8ef18639bc8c831dc0b4aeeca25eff4f\r\nMsg = 094c4d9baead7c5acd7dc58f3b4b4f57f1406b4e6af81a034d90cfa94c01760f4cacb4d2c63671d16d9594e1116b0dc2c39319523afac10175b1a485a240f7cf3f\r\nMac = d84f89e16c3b1633\r\nResult = P\r\n\r\nCount = 211\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = bab9d79aae4a1b282d8c5aa35d5c0876\r\nMsg = 02815f53c2be5f7246d4794895b4b15b6c3944819dfd3051b371f6d7d52d9f8ced84fd84095c33ea013c78aa5aa7176d6aa9bacabdafe9bab89cce4d7c183b9c0d\r\nMac = a01f976031bc8140\r\nResult = F (1 - Message changed)\r\n\r\nCount = 212\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 42b97f583f64d88358885c66add5d03a\r\nMsg = 187fe16a764c0987a28088f5cfcf55a6b9591b6395d2d41043e09932cbc4b8ae073d08d39da9799b316eef2ed89851a8cfc4dc1c6d3cbed95663e0ecf25403e61d\r\nMac = 0820b1ca0cd34e5f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 213\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 4fd555bd3a5253a90b68b5d4d46bd050\r\nMsg = 1ef253c61ac8ac66734ea80eefc1dc077edd660dc3518b5ecf709f10302925a72a3938e7449f2ae707506a67022dab63113242e9dff0d027aa3d22c8462a558165\r\nMac = 3770a6cc988a28eb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 214\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = d3a8eb3f9e5fb264ff098d85c28dd763\r\nMsg = e97a0986bf75e0e821f5adda80778863d9d479bd8ac3e7fe64a053f8016c465d581487278ef6923610a1463bdedcded62aeb22fb210dde9a0949947f8c6a6e7753\r\nMac = 4947e6e28dbba216\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 215\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 3043857fc40be37fb0bda4f46894690b\r\nMsg = 14874a8b59b0178c5ec89cd7316d909371969c1a1a1bc8a29f78341d39ce085e7e2aad7c350a3e7b691d3929bc4b7b47fef56be9fe7e7520a00abad5308505f8f6\r\nMac = 1a8c82e9109a68a5\r\nResult = F (1 - Message changed)\r\n\r\nCount = 216\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = b325d425c810d22deb3209f29c5c1377\r\nMsg = e44c4202499440c12109296a35dfb1f669f97e7f415cd251a5e36943e134a548f0f2e841fa3541151b374c04665053382a24b99d731b99f3d411aa22644f66cd07\r\nMac = 84faaeb5a9756a27\r\nResult = P\r\n\r\nCount = 217\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 7cb6a84e99f5573c1eb27c0078f2127b\r\nMsg = d7fa7be9c10252d6e41bc1a08195a344ef77b81785cea6b4ba453d398bf6ffb31d80e0d6a45a4af283676422b5ca94c76bfb4334f61ae0abe884278976a5a3bd21\r\nMac = 64fa7f9284c24f14\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 218\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 00341fb81209c2abdfe3a9d607b98277\r\nMsg = 74f6fd37ccb4b7702bb3a03b7322c0d5fcc657cb2c3f1361488d853589d2d6207359b65d62d896ed66f217395000c2fa0d11f956332f2d4bdae55251adfe903b41\r\nMac = 4cf05b6e583c70f9\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 219\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 647a5be8a66c83b4b238975388e15d00\r\nMsg = 0db33eda4188a9165147e24e40f79fee1985eb68d51627287e9c4ec995a77d89b27fb2fa6a6fd3fb7563f3e710b6d20ca145a25f9ac8116d9f628395eb769f75f0\r\nMac = e8ef4f3cd7442246\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 220\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c98fc3416457d9eed0fa7ab1dc1b8a6a\r\nMsg = 190ae57ab8bb70464e4a10c112a54c646438301b5662f3536c26d754a02451d1a9c76abd7dbf656115b2a2ac702ec2cadae30cf86e0f0f96da39897d6222889428\r\nMac = 1bea94a457b2886e9098bf3ded932a3a\r\nResult = P\r\n\r\nCount = 221\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 87428d5a53f750abdb335f70ee13b5d1\r\nMsg = 7bb0c2ecfd141e7e93a897b259732b6153af3542eb7289b1a18dc0aefeb4d129c9e0e27d7ef25d3afc9945277e75cb87cc7d1c9cb39e7e6ab2a49bbdf65e1c6d89\r\nMac = a854d2da46afb77a787f0606a69cf467\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 222\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c725d9ef0dc6cfca84865cf5cc91d403\r\nMsg = d3208eb695e84c7a9250378e18be2f231ca3ebe72ba68e3ea4ff7bcf25206b43439bbd497e400dde738507cb542c7d6f961fb8bee99f0c8a6d9daf022368cc78a2\r\nMac = 35d57445a5f10fd567595fc668293e95\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 223\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 13e3fe7856cd680593a85cda3d6ff873\r\nMsg = b208e5a1a852caef0795150cf8313ee0cff06e3d28d438c2351484005661cbdcea6d8a3466aef0c6a460da4d7dc902ec99c073d086704112085a76dab0994fcab0\r\nMac = efb2bef5aae555463ebbeebe69791459\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 224\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 9b8112c1fb29fba2c8b0d8f16481b993\r\nMsg = f54105a04a4a02a1a07e020a6a4f4176e9c92bf40018ccac434988c650550c87625b84bd232d0e5ec20e6f6c46ba061b22a7fe36098bc7bf031ec6d6c1214bdb2d\r\nMac = 673281bc0effe92adfac4fef49477ee2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 225\r\nKlen = 16 \r", - "\nMlen = 65\r\nTlen = 16\r\nKey = 82e71e3ad1bc9a12a46e460a05ad9c05\r\nMsg = 41fb3dd6df78fe267175297e208ac753d50aaabd9edbf5e45385dfb47988b3d966f31be7a6329fd89e2869bc6f7e4bac1e3a0300f193bdc21c03d9629c9fefaa64\r\nMac = 36f7df58abb54a053988cae066110ecb\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b46e219217ab73c34904e24c6d995b72\r\nMsg = 887d6576572a3d8f6a1649394248c4d09d15026ffa930c0659508bac4243e7360802af084f363c2bcc4c91a04c6e86f4f8b22615d7915564949ab60b8267cb91dd\r\nMac = 10c1d8054ac549ad24ae4af2d8de97e2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 227\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b66edcc59dc9d8e34bea3baf4bfc0d5e\r\nMsg = 57caadbb1a56cc5b8a5cf9584552e17e7af9542ba13e9c54695e0dc8f24eddb93d5a3678e10c8a80ff4f27b677d40bef5cb5f9b3a659cc4127970cd2c11ebf22d5\r\nMac = 0c5864eefc04a6cac4f053ab2f65f851\r\nResult = P\r\n\r\nCount = 228\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c607f631d792499ea43586b81fa3e2f2\r\nMsg = 21ed22abc7bbb62fb2d51d1fb8830ca95b16213f56291af976274934ab0d43805f71d9b906c44973f7d4b59b7a94d35c2220e7405dfcee98499c1c1dc92a89d7d9\r\nMac = 4e65b3d58492a0eebb66928a8214498f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 229\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = d9e9136339d361949242e4d8a0cd6917\r\nMsg = 419b9c9b093052577837862900e7de29273eb0678bf6238223b59176c78430b6f382f27bc8d9a95b53f26f1d12e545ccb434fa0a21b84fa7badb5872e208254fbd\r\nMac = 6c81094aded51ccd4da38d0412e7ca67\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 230\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 6f349dd8b69dd41c6f246a1685115772\r\nMsg = a5a3c8afe5b84e0c3ba4f708a87b596d1b7c8694dbe691d7240e4e4815ad5aa4ca7e5b82c50989d092b96e80aa35e97f99ed79e75cf3b8750d0d263dc208289cb2\r\nMac = cbf41299c35e65fa4e2626430f95051e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 231\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c15e4e552c9197184b3eb0a74f5fffe0\r\nMsg = 7c4699a7d9e2d9f31410f20029676f3c97f5793f6732f95f6d33fd7ecc205d27b8e89eda803316a3cb9951f12111b4a6aeac606b43835a469eede86eebf63e5e8b\r\nMac = 77e77de5c5600900e5b928d4be3d5f8c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 2eda9b2c6d7ad95b644a8739580ab4a4\r\nMsg = beadccddcf392ee56a8913f057da183ab06ec538e581b52c027ff7f63574b32d8bc4116efa1c56f4a4a851695a87f5fc5f7c47b46fe67b0400f2599fc80fe68d7f\r\nMac = 948e63657b8b6e2d130f6f25369d6160\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 233\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 233088b67b741f07859d122a6a406d89\r\nMsg = 5717ed57ca0b6921f04dcacad34e0f6210c36673dc9f4d92493ff733c6e5f1c2e56805ef622a5f496049ee0ef51a0d41e9d363febb87070be558e8af61e86dc76c\r\nMac = c778152b00760fcd85bced0f58861d13\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 234\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b7471a8b2e50fb319f198a09cdaeb319\r\nMsg = 385f9fb139dbf88561b7a500b0c7b835fe57e2698c6d9f76de4fae6dcd45c47fd8a0811ebbfba35f43c17aa360f09c767c1cd9b70bb671fa638e852ace97cc73de\r\nMac = 1a8b81be875a4814e3f988c274784a63\r\nResult = P\r\n\r\nCount = 235\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = adf072ebb71e3400a2175c96fb0007a3\r\nMsg = a49840ab727bf6b03015eaca3f15a2bb64fd27b51b27fe7a2e0559c287ac8fdd4294ca990799ff66974624b8a4539dade66cf7f06b35d8dd2f8a36e6ec0bc83533\r\nMac = ceac74b3af8750467e3b3c51624d96d1\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 236\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 1b1d471add4e7f4fe197e3a4a44d06ab\r\nMsg = da06bd1405028d93fefa3c037b5ad551879451a28314bae86a7591b359f56e4b4e26e6fb2fe7b1af0f930cc2ae785d113e8b16546d59dbae9f41e7827be1ac89aa\r\nMac = 16d0021b1f9c00b37fefb60af3358d87\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = af5d4991c189dada2cb552c3c52d599d\r\nMsg = 1bb1e0efa2d6811d2370a039a0c47c59683befbd46c04257f86a468ae25ba03304e865e62afae77a62b3cec7b3556aae0c60475a7bfb02c69f955c7f60cc8dacdd\r\nMac = d7056fe01f0ed1b20adbe05cbccc544b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 238\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = d149441e667b245d4640e04c53ca6f51\r\nMsg = cbb34794bc8bfdf93d3c8d9f87ec1482b516b48b1e8a89b5e3b5df70c423a243384215b4bc69c76c6b18c497cf82088af74839a8c98895869a16294dfc094360d7\r\nMac = 64f5e8dce5c3e0f9cc224e306de70b87\r\nResult = P\r\n\r\nCount = 239\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c2f5d4837f9f75fb440c3bccad7c2e69\r\nMsg = 6a84594c4b3865f047c96038060b5b413db0d4e081c62e405b815ecd9e3be651f8b9075dc8b032eb2f87c1416a5fe4195f51defe75f671f9a92d966ddf18724075\r\nMac = df8c8c61e8d604e24c7e3d0115dbe898\r\nResult = F (1 - Message changed)\r\n", -}; -static const size_t kLen34 = 69750; - -static const char *kData34[] = { - "# This file has been modified to remove the 65536-byte long inputs.\r\n\r\n# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 192 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:38 2011\r\n\r\n\r\nCount = 0\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 771887708683bcb3577fbd0e6c13cad39955eafdc226d17b\r\nMsg = 00\r\nMac = a0db9bb6e8891e92\r\nResult = P\r\n\r\nCount = 1\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 733fd349c56d1086794eb20ed59ddc89b065bb8533b968c6\r\nMsg = 00\r\nMac = c76f82937b457105\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 2\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 761d74be5fae170a1bdfa16081b44c1e49972e15ce0818df\r\nMsg = 00\r\nMac = c65feb3d5336dffa\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 3\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 40f4a2261f154280a311f5b172c7ae34243cf2c59b98d37e\r\nMsg = 00\r\nMac = 05d920e78520839e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 4\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = e27150ee958b998c8a7e8b9324ead937d15580d09d6ffc3a\r\nMsg = 00\r\nMac = cf60783b5defbe3f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 5\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = d9bf5efb694089b2de533b1a65c12ae96d8c5bd75bd67fa5\r\nMsg = 00\r\nMac = ccde2029fb26c8ff\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 6\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = bcc658b2e53d51ed00c567ded2a124f8d1f85fc72dce5f80\r\nMsg = 00\r\nMac = 35d0d9ccab5b0f41\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 7\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = e31fdf3891c9068f621430315fb1daf418c328baf5e6da97\r\nMsg = 00\r\nMac = 8802047c11abcf2a\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 8\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 16a10208e91807fc479607cbaa39fa9c7273d89ce403b796\r\nMsg = 00\r\nMac = fcedadeca37381c1\r\nResult = P\r\n\r\nCount = 9\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 50fec559910391abc23eb7f5eddbc26a1031c0abd0a29ad6\r\nMsg = 00\r\nMac = cdc41e9b491092ce\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 10\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 6e9e0ae953b1b486ecd6b766d7b961ab79bcdfe2ffe95e94\r\nMsg = 00\r\nMac = 5096b9fc700929c6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 11\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 48043c405ef221c281d1e88246b6e1dda77e072f9d10353d\r\nMsg = 00\r\nMac = cab96cfcaad5cc20\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 10c361934fd6ff77a5051879ff228b08d841660d48b4067e\r\nMsg = 00\r\nMac = 167e7227d59d65e1\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 13\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 867ab71470f2dc3f5f11f8bfa7272dfc9c888e8e03323103\r\nMsg = 00\r\nMac = 96d9e7b084448004\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 5b10c228b447968267293ede9131d9345daa18c11d71eff4\r\nMsg = 00\r\nMac = f7055fcd9e8a8fd0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 15\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 997b712cd9295dc43cc19b40679f218c27af3e8c638d2e5d\r\nMsg = 00\r\nMac = 79a13778151aaaba\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 16\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 465b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3\r\nMsg = 00\r\nMac = 945198b568ed3db3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 17\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = d233ef50e0ce1924abd315510464ce22de377026529085ce\r\nMsg = 00\r\nMac = 240698cd0183f002\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 18\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = eb6e828e01930a4b0afc8bda63160942ce32df7b2c38a8c9\r\nMsg = 00\r\nMac = c68fc388f0633ecf\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 19\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 471b8a2e5cb08c21d87e9eb7ecff1d6e6fc2335581769dc4\r\nMsg = 00\r\nMac = ab5e7c91c35a0e91\r\nResult = P\r\n\r\nCount = 20\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 8b404993b4c3f62a57e4aef272788206c8076acc32cf3a1d\r\nMsg = 00\r\nMac = 6a3beff4d1d0e84ea4d4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 21\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7cccb84fa5c1c795bc05a05ea5bc6497acd2de2d193fba72\r\nMsg = 00\r\nMac = 557b8efe4ca9c4e603f7\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 22\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f1d434dac8cefca05ba120a34840531bf1542c8fd03b1ff9\r\nMsg = 00\r\nMac = e2c299a2c5159eb777cb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 23\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7fac8beb476b470e13a404ded315db1b15a85c2783eb3017\r\nMsg = 00\r\nMac = 50faaf26afd61c5f616c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 24\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f5b4c2a9f096e13ab426dd8654fc7b8ae6a4a8d3daa16b9c\r\nMsg = 00\r\nMac = 535cde3d2c32788bf167\r\nResult = P\r\n\r\nCount = 25\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f72879cc3446de9a0a43ae1cf08935b8c83f9265b8cb2258\r\nMsg = 00\r\nMac = 4eeea4a1847f2a30010c\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 26\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7021eaab074be980543cc70c809186d93652d7674c10ddd9\r\nMsg = 00\r\nMac = d98c93f4e0228ff68cad\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 27\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7fd546397a9a0129861fb6815d419a307f90d259d55f3503\r\nMsg = 00\r\nMac = 13597bb97e38f400e686\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 28\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 563cfb49f1af034cd38d2112685a52ebce8dca93e84ca10f\r\nMsg = 00\r\nMac = 866bc21135b11ea1bc24\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 29\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 17e9555b9b4f89cb63f2e90aca95c27ead6a099bc41c4c05\r\nMsg = 00\r\nMac = b04b3bd1719d35e80e2d\r\nResult = P\r\n\r\nCount = 30\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = a65d24bd1ab92d8d294d654423412860e113c976f12ed76b\r\nMsg = 00\r\nMac = 83c1c0f3e89f6584bdd1\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 31\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 35555c801a2e7c68cd0c347e0f006be00fcce70fdd8d60ae\r\nMsg = 00\r\nMac = 7e3670cab617e79b3f57\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 138b3db9baca13bc66e893efee2b767ce6a912b172c2cda7\r\nMsg = 00\r\nMac = 4686805681afa38cb7c4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 33\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 1bc05440ee3e34d0f25e90ca1ecbb555d0fb92b311621d17\r\nMsg = 00\r\nMac = 1e9f80432b39f7318433\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 34\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 5776d94b577ed26820fb13c00ab0e2d1a1c3589bfdc45cbd\r\nMsg = 00\r\nMac = 4d5f56d3543abed97233\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 35\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 22e493c1f2e27c9be7bb07fc00fdd51089582d139b0a9f68\r\nMsg = 00\r\nMac = efe1c6493542a8412118\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 36\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = d52f030107a2becde77331fff0c24cd72ef62c0f46ae3e6b\r\nMsg = 00\r\nMac = d1b9c7f13b189cd828c7\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 37\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = be31363e5144d9ff49ee67efebeef6d9a97e22f8a3ceb209\r\nMsg = 00\r\nMac = 03228a1a80d5f3d87b56\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 38\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 6a46492ab7ae5f3dbf16ee7b8876e0b4f0449f3b4f8cd89a\r\nMsg = 00\r\nMac = f016af853140edf22d31\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 39\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 89ef2284d8245d87f88919d4d2f71a2df05ee21d85b7d689\r\nMsg = 00\r\nMac = acdbd54bfb1f20bb65cf\r\nResult = P\r\n\r\nCount = 40\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = f4e74acdeb91d0f0ab143823102d5baed1ffe168fdb5587a\r\nMsg = 00\r\nMac = 9c15bfd3c766f88190e54d395e5387\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 41\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = d9aa4efa5d75195a400018bd38f7d8cd53fdffe88df1837f\r\nMsg = 00\r\nMac = 4a11b22e871b051ea74db3f763f140\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 42\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 13439fb32b1514d48de6002f5d12e19e1ced4caf35042602\r\nMsg = 00\r\nMac = 1412aad5e6b7f0d924700b438e0aaa\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 43\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = ffead92a4a5dc1eec6d2e441de9a9e1b7a88c607c9a79079\r\nMsg = 00\r\nMac = 6fb18d51e9a30fe6b7a6f405b3d3b4\r\nResult = P\r\n\r\nCount = 44\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 176ad1686a81992e042d6497a305038ba0cabf74c6ecd8eb\r\nMsg = 00\r\nMac = f676bdc753ffdad36628b1724b967e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 45\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = acd58261bcb2eb6345af7290b1d216c3016af6697bf5ab88\r\nMsg = 00\r\nMac = a6ae95e5a23b5f5a2dd8c8a520b9a4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 46\r\nKlen = 24 \r\n", - "Mlen = 0\r\nTlen = 15\r\nKey = 0b5eb52135dc6d9c1f56a2571c1389852482e7aa3edc245a\r\nMsg = 00\r\nMac = a46221058177012b073c6ebc6aff1c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 47\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 7bd398d1b9b45f7a024e70e71c1ee7132795fbaa2d63306d\r\nMsg = 00\r\nMac = 119bc07d7f3da0be3a87844b425c0d\r\nResult = P\r\n\r\nCount = 48\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 47575b64fd4797cda8d67e9cf115ae850d7998c39d2f8709\r\nMsg = 00\r\nMac = 3f2010bdcb2fd70241475db9381570\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 49\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 68627d802cfc43bb1a987e1ef4401fa84e8a7b2b43759f50\r\nMsg = 00\r\nMac = 1e0e3333ca5790a7e7df0d6d4bf860\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 50\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 7f16b90a18deec135d32c836063cde963fc4e6daa1555476\r\nMsg = 00\r\nMac = 013e1d0bfc7a7a6c838ac98ce0da2e\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 51\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 3c89c59ab30eba6e5be8f69f597adc534cb52e94259780f6\r\nMsg = 00\r\nMac = 7f9f1bdba93d26cc3c1f022244bff6\r\nResult = P\r\n\r\nCount = 52\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = fdcf28931c91b4b79c8f8332b4eeb3f995eb1ed2fb1e8ab9\r\nMsg = 00\r\nMac = ad7f8852f1bfd65dfbce3bb39db59b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 53\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 8f570ddd0963a80abec82caf8883eaddfd63cee9f375fa7a\r\nMsg = 00\r\nMac = 82b16380d804b8eef855afb5eb839d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 54\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = cc1d70d3050f022442093e3210f5b45f1b610dc0f12fef74\r\nMsg = 00\r\nMac = d1dc61c2ef7e2cd1a4e43dc34c0ba5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 55\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = a8a1cf9547543045fa2f00edf79bd85436bc1ae1d746790b\r\nMsg = 00\r\nMac = 48fc14782a351553ea453a3ec2538f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 56\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 123ff732cccb535ec7a1c47a6b0ead68df31094d896709a1\r\nMsg = 00\r\nMac = 8f29dcec0a5d026d6fe4dc64cd1d4a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 57\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = ed06bd049d772cb6cc5a705faa734e87321dc8f2a4ea366a\r\nMsg = 00\r\nMac = e3fcf2590fa9ffe093bbfe8d3d7b0b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 58\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = fa18c0b348aad167b7050c0ef6e7caf0436750873c7e4929\r\nMsg = 00\r\nMac = 630915919b6108770f5c3deaece1af\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = f66296bf67b6e91d8ad629c1b260cb5ca1985273925e73fb\r\nMsg = 00\r\nMac = 729f983d3b49b2ebf24eb04368a851\r\nResult = P\r\n\r\nCount = 60\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 2f4a6501d8fe7b65f607757ddff6ed87ae0681b98b53331d\r\nMsg = 2361d2ed837c14b6c231daf0acf2623779e0d952e98e14149308807f79145c30\r\nMac = 9a8ad7bb37d79321\r\nResult = P\r\n\r\nCount = 61\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = e2d592cb412e65f9044257d78e7491f9f80c8b08102c2d5d\r\nMsg = 4163b7ad671761a3f27394776970b413e35a2c43ca85560cdd3c9b407bfadb4f\r\nMac = ab85ac3a4f92ee2c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 62\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1534e69565cbc541bfde6901bd6e598e41a7a703091c2240\r\nMsg = 85b78269899a4712eaa9c3de041f5a74766ec27dd5265da8a117c6f277baaa24\r\nMac = 6b177203b17cc7c2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 63\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = f0302d9a197a285909657d611ce12458b8d24652e91ffe8c\r\nMsg = 3fd6b98961f31c7b7fff0baf1cbb5884a9290ea7b5ee49915efb4b510b6ccd8c\r\nMac = d2d84fac8ecb665d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 2081442435626f7ce377132c46385510d9febfdd90c3f104\r\nMsg = c4185eb75fc23adff60d6380006a1c20fa2ff466ffddf67e99a421bfd729188b\r\nMac = 7373df1900b7a3df\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 715fb6fb464513f3650a9d0c3687980ab9caa9876d69dfeb\r\nMsg = d60b3402ad9f5f09375862ae7a370f0c744ffaf5001c80e3fd150730ab848689\r\nMac = ba39c81c18821872\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = a4d9f94e644fbcd97e0d993cb0af507eed259fbcf8fd7083\r\nMsg = 677acb68500d6cbbf77a3f34f58840f0c16044827641dc43d6767ce98f85dd5c\r\nMac = b129c1785acf17ba\r\nResult = P\r\n\r\nCount = 67\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 94b911cdc3137a6f7f32651b788eb82975660aea52b2c03b\r\nMsg = 549aa84bb182312dd016e3107f3b1f9c5b6a89b543561a450ccf713c76e66ad5\r\nMac = 7b92156f8b36d5eb\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 68\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = d3fff7b6f08dc4256239fc112890429fa00393e84e9b294f\r\nMsg = 15d1522654bcdce344b5d9753a0a6f31c859d547edf520478a8b5ae41506d5f7\r\nMac = 2d778849023fc9e9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 77bbda69ec034d73e02b06f0af30e2dab60ac80cb7822eb1\r\nMsg = 1e6ee96598bd014c95e9540f5cadfe6885cd094e04048e81633d1d634f065f09\r\nMac = d35f3c169f67b597\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 70\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 544a757bc50658d7e73b25688e7fef86fb1f9f08ffb33a70\r\nMsg = e473fe5656713b3b0e4fd12c640e8c542950577f446b01d09cbc41b6393ef81c\r\nMac = e1dad03ab8d2f432\r\nResult = F (1 - Message changed)\r\n\r\nCount = 71\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1bebfde2d5468ba0a3031bde629b11fd4094afcb205393fa\r\nMsg = cf27b30423bd7e40d6b3aeb4b1bc01b40aec081aa00f2e3bc63ff61ac4b684dc\r\nMac = 617fdf927d0e4e42\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 72\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = ab83567833d2f3461b5fbecc0e366694bb5ea00933b2b3e7\r\nMsg = 58d43b9f1581c590daab1a5c56d6fbcff749e489acc3ed51ee6aeeac0104e6ae\r\nMac = b29232e882dcb8ef\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 73\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0e0fece7b6b659b642668e8ba3dca330523e70279155f485\r\nMsg = d8c35129ca5a84e2e6723332217f0fd2e19fd06eb27d84a93b75276270f97335\r\nMac = d7ea4755260630e2\r\nResult = P\r\n\r\nCount = 74\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = b15763294afa61bc27e0785500ab5739136f51bc78b65562\r\nMsg = 8e8271b2758964fa71520f26aab6f870fa76ea4aa220475b3b379ec4ef8e80a7\r\nMac = 6357fb64482d171c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 75\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6dd6efd6f6caa63b729aa8186e308bc1bda06307c05a2c0a\r\nMsg = d2c9c1300f5a7520614550f9d23dcba6b41be6733426616f32912f155045282c\r\nMac = a12adaf849719778\r\nResult = P\r\n\r\nCount = 76\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 35631c844313ac335aa0d590fec472d805521f0905d44ca4\r\nMsg = 766f9ac761a06f4e006f405f7b3398aecad253f5cb8653e091e17427ff0fc1f9\r\nMac = 49090265af87c220\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 77\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 35008ef5baf263ae233758ca237dec1a51d67fcd3573094c\r\nMsg = a8f1b7b73100cfe1a03003331d9d55b75fb0d2596ede723fae9240581967ba38\r\nMac = af6c2ebe004c6d71\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6f383f798df8f4b9f0a99206cff82709c367340c7b3b0401\r\nMsg = 9668a011e5a3a613ddfd149b0e529e9e66665006f98e730400adb4a8226283af\r\nMac = f97fcc39e240b547\r\nResult = F (1 - Message changed)\r\n\r\nCount = 79\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 9071be7a11dcf7a062d582dd5932f047396fd9eb71982bcd\r\nMsg = a8a6703044010f8301ea33bd9a808ca35838c9f58683ae3925ab67b9e1fe1ccf\r\nMac = 9065cbc5249ff8b3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 80\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 36ad69f192ae4dcab771aeeacf01bbd32609bcbbea8ff9df\r\nMsg = 6e60fac7c027aed4632444a95824e61e2c50aa3ecdaf09ed9cec92cec35adf63\r\nMac = b6bf70e67b315c256f41\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 81\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 0cbb1d567bce009d1dc5bdb8115607213ed9a516389f728f\r\nMsg = 634efdf89ce2a9fcbd38bdc0b4cece54dfd7532880e0b4ce6eb3a4010b7cb1e7\r\nMac = 4f0af4ff9a9c9e844fe6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 82\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = ec65afd2d72bf477c7fdd9fbe3f1694c328088cb5f39d9a2\r\nMsg = 10d0e88b0db8d515bdff3a791c830b28e4e3ff4fa63f45b31a3f73dfb457bf82\r\nMac = 7172095284694f5ccdf5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 83\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = a76b981540ce229e73064af4474a7ca4a042d03a6e6bdcbf\r\nMsg = 740d4b25ca7221d0826057701a6bfd66c50a82f010a57be8c5efa0af0f761764\r\nMac = 94b657fb57cb2fd6ed3c\r\nResult = P\r\n\r\nCount = 84\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 36bf85bf63b28093d2dae511990a0bbd75184044b033c66d\r\nMsg = c1fbbae61b81ae", - "bacf151f1bccfb1584f3a211fe797996938c03e806392e14c1\r\nMac = 71796cf452f61db7f540\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 85\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 67b79d9ef1a47867c7d21f19f99ed1085f17a9f092fac689\r\nMsg = d354c54151c9dcdf0d0fd8c51413c2645efafb2bf6b680b25ad76d3825a4c04f\r\nMac = e324e8d377447b40629f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 86\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = eafa8699695431ab3cfa1e87ffeae4b822a391653d2e9d78\r\nMsg = bd647990f7afec76c8f726d1de806ca0cae6f708b5024b514f11c4320913724e\r\nMac = b0da9d38a1e821ef1f39\r\nResult = P\r\n\r\nCount = 87\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 1fc4fcbc73dab4e73ed9d7606acdcd42b74972460c640fe5\r\nMsg = c86553a60da69bec1924788fc3ab985158a2d4788f33c01abead80974d26dd67\r\nMac = 992fd0b735b9fa9255c1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 88\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 618041501dfcfdd2b60d71c04d635f6357ad8b0643af77aa\r\nMsg = e7e6b57e74ce7afbde3697e2a69d61ca615aa3dfd32fe31f5521e6ca79877613\r\nMac = c183b8f21cb2aac7201a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 89\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 53bcc9e9244e2fa1752c61e65aa5c592138447ef9287fdcb\r\nMsg = 92e962f0086591b6f61c2ce5af62480722ba6a640c3f53806c421de438358721\r\nMac = 105d286777da3f2a03a5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 90\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 6d2429921f90a22893cb65c4530e56068e9944d0b0f61fa7\r\nMsg = ea2ad7b7d3f80793391af0328fbb594d79898e1047210628bbc7441e135bfbe3\r\nMac = 482a75ec0ecf1ea59f5c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 91\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 3100d3c70e823fee9a1bf486ec1c56771acae35246535de1\r\nMsg = 4e6ddae0d805afcd10a055bce584c848d050fb29fe8f1c64b18e1abfe46b6578\r\nMac = b0deaf1bb6d0425d1810\r\nResult = P\r\n\r\nCount = 92\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 79aa6c03dde4bc5949921563264b440ebef71b3298da67b9\r\nMsg = 879954f977e945cd4db33d20e6749a6832677adbdd9c7e262e4acf632f665f45\r\nMac = 9863fe041d191777067d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 93\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 85467aa82c22ab019f9243c203b4371c95604dccee5d81ef\r\nMsg = b86edcc59dc9d8e34bea3baf4bfc0d5e117482a48e522c1b02a370e9124b379e\r\nMac = 54b2f4664eca96639f7a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 94\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = d37e7aa9215cb5c2c2fe81834f200192ada3dd0f4ccb9d69\r\nMsg = 064f85a23e049529c74c4f8267abbbe685b6a838841a9e304fdf14b835eee396\r\nMac = 536701771f51d2ec354f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 95\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 72e8c7d74cec3e248fe938a1159d8d969928e6da26b8cf96\r\nMsg = 58019989445d5ee855e0ffcf84e76f3383ae09cfad74276a3edaf05cbf8d714f\r\nMac = 182d3bf14cc391aef27b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 96\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 5f847950d2a5d44137110594d3c0afa995b36422ab36d044\r\nMsg = 70523bc397417e09d791a4976960e02636ca7144a5681cf7b116daa33eface2d\r\nMac = 5f0b325fbfaede23de5c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 97\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = b01e84220a7d514060a79088b754ac0beacb60e5b3a47020\r\nMsg = 036137cfed567fc5e234f18d6c2b8c7e9ae0f3fa526d6596e9a9ee7bf1abdf0d\r\nMac = dbe49af18c1e1bc99b73\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 98\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = d90ba47d7c9107b103cf167041dbd7b41d96016d93961917\r\nMsg = 2d53836a0437ccf27cdfe2bf2ad53f3082100a9f045cebe6b3031d21c9a6c5b6\r\nMac = 7252ee3b5eb76abeec9a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 02e5a1306f612bdec098458cff3e691d93f050ba11ba6273\r\nMsg = 4bef96da992ab9386a3463213773f3ca7164813a15e014ab819f153386fa04a3\r\nMac = 5fac9c1a1636b66e2f55\r\nResult = P\r\n\r\nCount = 100\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 4c99ce359b8b82b67ee990529a10f2ecceadad456925a57d\r\nMsg = 89ed296a3ac03fbfb71422b9211799150b9d766a8116bebd48bd0a5068132dbc\r\nMac = e0e9583d784f87e0b7dd8fd7494a81\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 101\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = f085fb257ab64013b43a59150864a31e76c9ae94913a56ef\r\nMsg = b90ef6b773f250d4dac6fb9e62babad69ab424c96a8c0625987c030a91d27d64\r\nMac = 96f1dc9a1c668bb203428181c016ec\r\nResult = P\r\n\r\nCount = 102\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 8109f3208d5cda0f12141e40c85959b72eff1a937dae7f4c\r\nMsg = 49ab30d5c01e91bf113764342cb8ad32e6af945341a9c6a0ee2319a910416fd6\r\nMac = d13777a33f9520793eb8cbcec047cd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 103\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 1eba29062320df7275a51aa090ab489571057e64f0ff6a52\r\nMsg = 754f03c2e298a699568d10c3e40390e0f8c398283ce1c35dbc4916fe479b87be\r\nMac = 87dcee48dfaa43e8223a2b338b220f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 104\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = a04b976fa01411bcc9a3863cec91f486944fdca6e8754615\r\nMsg = abf45f39904a8f5766763fe80fa189ed9c6c15bb1a7a8fa0ae3058c9e5b87c63\r\nMac = 577aa39884335a4f66dce2a612515b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 105\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = c6f0a3692c9280c48393b0dd763e5d0b90477f34ad69f192\r\nMsg = 737bab64c8a0fd6a07329bd729d2ec88685cb5404bd13a40e095a61846dbacbc\r\nMac = d61ad5f6d8aecb7b3fc1ddb1aff64d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 095eb52135dc6d9c1f56a2571c1389852482e7aa3edc245a\r\nMsg = 47c577d1a7e69828b5c3264738dd334be8d7678ec77bf1ccb5fec3843f85ffa1\r\nMac = 4fd309a62435edd9b1ac8861f904c1\r\nResult = P\r\n\r\nCount = 107\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 2f853c1ddb31694985ea5e47322bfc8567fd7a74a46b0597\r\nMsg = 5719e671686e87e931c2c0e5842e907bf584d226e040645eaebb896b53a28c7a\r\nMac = 75ed56da2db0ffa101578118e3f620\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 108\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 67f5adc0842d7e1a4f8591d678334c95ac83df95c4341c30\r\nMsg = 6c8aaf2f91ba87b61814ed689331264c7bf98c2223c426a4ebbf7b0db692a8d8\r\nMac = b7c591522e9a5a4f3af3aea24121b6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 109\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 8702cfd1ff87a749ceb0a7192f5a872740b7fc600845df4f\r\nMsg = d29b6a2d421abd00a59b756af34bd72a42f5557a2ed40f8a7ea59b2e05ff01d3\r\nMac = 33b597665d375c95464af2ad56465c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 110\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 64ec1fd6af554485856b7bb3c0ad16fcd9c4ec690914a09f\r\nMsg = 0418a0afc13d6215c7bd68b12a327587eb63c145120ea626fce59c16f7d66717\r\nMac = 80a85e77efe4f47d8938dd9c55d67e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 111\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = f2991112c2cbd3038ae37b772a5090690006009f0c1965dc\r\nMsg = 231d72c9325f8c17aef4efc94855803eb2fc1eea601c84a98e8f7053840f0591\r\nMac = 14269c545a0e3d56ac9cb195cb6197\r\nResult = F (1 - Message changed)\r\n\r\nCount = 112\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 2c6d7fb9e92d98a1dd92e96f6b4013954ce1aaa5de242e6f\r\nMsg = 87ec7423f1ebfc37ee83c85938d58259efd16e3c8e55fb871e9998baa9cac81a\r\nMac = 782b7ebbada87c3572a3918a03305f\r\nResult = P\r\n\r\nCount = 113\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = d95a1b24964bfea5dd5a65f5a1398c6f9d43b26d98b47816\r\nMsg = 92f9cf56188322d18cb41d723847e6d419cd163e2be71b78e7b8dbdd099a99b2\r\nMac = 2498787836840fe1411a17f153c546\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 62f2490ba0c658848859fcbea8cc6774e24c9de979dd29d0\r\nMsg = 0822e3e6ba982091d532cd5271fbde25305d1f6e71880f81c618f267a9f122e0\r\nMac = ffb6c2a6c73245138ce06e458cf914\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 115\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 1841161a3752de1491b2b2f519d8447636e149437478d2ff\r\nMsg = 238e36b73b474de88226d4298121393ac9162f1736040bcd717b6e8db85125ff\r\nMac = 4d1656a2c8632260aa55a097451fe7\r\nResult = P\r\n\r\nCount = 116\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = d7d9a5f750078f1a82dffe2c70e6b0016eb42d13e1a8aad1\r\nMsg = 28a107d22fcd0499e0ea5aceda6dbc288a5f1d9da003c626bfb9a6c27922e9bd\r\nMac = b67bc2e20c422f9c7c27a84ba0bcfe\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 117\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = dc3ca30782c9c0a7fe8923d4b8d31aaf21e63895f51fb2f1\r\nMsg = 8716298bc17ed51aa273711873e2c2863e7a5021e46a183e6c6c81f99c02918e\r\nMac = f41b1896a22db30dac50b6b3e5e2b8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 118\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 0b6b36339122610178c4bb72eb558abf15e5ed9ea0077a5c\r\nMsg = 52839f2f0853a30df14ec897a1914c685c1ac21470d00654c8c37", - "663bfb65fa7\r\nMac = 665f05a489f8ad0feea290401b4bf2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 119\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = e200414db0255ca3faa7f6b17a62523f2c75d99f6ae162e0\r\nMsg = e749041b314f8719e17a8cb26162e2c910b31116dd769083149238d67792f991\r\nMac = 713fb4d0c95743ee7da970cac7f771\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 120\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = ea77165284ada4599f0bc0a41db787310f53a1588282b866\r\nMsg = f3a1a6dc2092ae7099bda65f8af32aa19796254a13fd9e0e7319d50402598faad6ccae2a028604db0d44690ba3530bfc8bad062cd96635d9654647c57bb81537\r\nMac = 9c7c379b5f8ee87f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 121\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 18e2baabdcebcd25958eb53d1bd2a95ffb9b51a3c1d92a9f\r\nMsg = 1df7392e915726847822817cb542df6b14df16d7d3d3ea8d615fe9ee651c938a0234bef059d139c350d6b01192cecfe1d821aa0b668e5d4dd8d5ef9a1eb47db5\r\nMac = db521506073b8c9e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 122\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = d39f12a9c6b63c17f116bc003f4def172943350e29d60258\r\nMsg = 75225a26d63e91281fb37ace46354f81de99dedfde8b770ea47f08503aea87d8d7b190dda9e150ecd1a2a182b06676da61667a04864ff4374838ee6899d8961b\r\nMac = 65aa057a01b390ec\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b2212ca369c611b725eccc3daa58df412787a3475f418d82\r\nMsg = 3727bac9706f482f55bda86dc052aa6810e2c1137b97fc93a65838a2724a9531199726517b6fed53b24d062eec7c22227ad9379b24da7658c0cf7ecc0368cfc5\r\nMac = b869a9e06994fb39\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 124\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 25e5fd5c39e684696e71a6f81f843a196dcd030ce2c07afc\r\nMsg = 899b48338d5ec3bb4a681f76ef37b6e25357b50e9578d85204c3753d3b6ebccf908e3de8b02dab01839ddf1a560b1ff33857a17fa4244b96612bbdeaa7d4913c\r\nMac = cfb0650c7566dc49\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 49bc9d3bcf3c22daa8cf55c1b59d4bffddc2412d60518e98\r\nMsg = 980026395d0544975dffaaa2c56db1df5816cd80cde513dc76f6f81d21f15c383c97c7233c9af2423fb28922efed2f69aa47c30de17ae1c5be17acbd0ad6cb8e\r\nMac = a7ed2a35c89130ad\r\nResult = F (1 - Message changed)\r\n\r\nCount = 126\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = c53f21f1ce3a1792a2de14277eb97664d4c561b3fd4b0e32\r\nMsg = 66e15206c23751497bc2c8d734aa1136aec08bd4e80fe3408bb3929a84efa749f379c7eb441872929b71872d761e0b448e0126e9fed86eeba611694cd2df4cf5\r\nMac = 1b86a912a0ec9f94\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 127\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6286e3e53ffb9bb143fcae724b45f86a23bbd74c42518144\r\nMsg = 62766e9acd41285eeed9b4007340dbb611699624274ad1179e327076135d907638c60f0c773c4ea8d9b8352027ee78ea4f22198f083d2f5cb920e55b9738c582\r\nMac = 3c56ff841dca9662\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 128\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 9c5d43c1a1269cde199509a1eff67cc83a1759b71c9e7a6e\r\nMsg = d576565a938782fc7e9b095db6213002bf5bbfdcd761fd6d876adb2c7947702b8930a5f71ec332bfbb4ac9b9d13d90c2d808d5459d0dfe5ddeedbe3e14038fd1\r\nMac = cc7b2038ead10d8e\r\nResult = P\r\n\r\nCount = 129\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 512a23489b8d6b62b63e9188c0ee5016f20448c082eefe82\r\nMsg = 1fdbfff7941ba22dd8e1dd13a05a3bd8f2c8096894266536c40a983929d0a6340af5233bbec1477363294519d3f3d9c6d41b20f18f76adb54495d9d43bec5afd\r\nMac = b81c76829839cd43\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 130\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 20d22c3b6ab38c5995e22b341f359be25616b2b8c7269510\r\nMsg = a1c041d1d4e7cd6a953f2e4837e3e676ed48633a2f15828f5f3551d5ad2a19c838a49caf75529bd5d5f89b3da2c2e9922ad8dc5d20325a7b3fae9dcd305f3731\r\nMac = aac4d4f4172e1f05\r\nResult = P\r\n\r\nCount = 131\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22e29aa7547e5ed3a64611e04f1d55f7a397c1619669879c\r\nMsg = 773b577b95e29d36fb30779d2ea23e2ffed9e1b46aede42bbe03a904fe22ef8f874298b5f4a6afe63f6ca9522863eb5cdb1c8d4bcd445e43e7302875e6ba3592\r\nMac = 16bf98c7a5deff18\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 132\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b320edb777d317af6c933a6530d9f5cb78d2d3104ac02120\r\nMsg = b31d3f55909bb660628de9eb95b75df776455f2f535f461edcfdf8a0cffdb096d573fedea7400f8374e62e30879a8beb259b3bffb4c3813a235b4c59853400c1\r\nMac = a0d9a7da024326ea\r\nResult = F (1 - Message changed)\r\n\r\nCount = 133\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b9bcd0ae7100f991f4365ba0683b6d461979ffe86d0ecc24\r\nMsg = 19d0077952eba12a01db1d137050bd7e9102a31242eb38a5cfb3cf51b86c86cab57f6deef8e6eb9eb29c5dcdd852ffd627641013660b31abebd40fab60514159\r\nMac = 972119a55b125e0f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 134\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 00af010f462ad40a38eefb788b648e1cc292cd4bb08ebeff\r\nMsg = 573db0961531873316e87090f79e84f040c8358f8ca78fd9ea1ebeda82c1cff67c2ebbda1da0a1b233c1539cb4c0145da2a4a05431e06dac2c2731d59581a434\r\nMac = 92a67a99c128e173\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 135\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = e12f98507d6514c3b551d240595346bc9e9b6a987033b3c5\r\nMsg = 3927bac9706f482f55bda86dc052aa6810e2c1137b97fc93a65838a2724a9531199726517b6fed53b24d062eec7c22227ad9379b24da7658c0cf7ecc0368cfc5\r\nMac = ef48edc762db1d47\r\nResult = F (1 - Message changed)\r\n\r\nCount = 136\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 66fe8076d4e8538e18b84f965255d143f1c7d377e099c1c2\r\nMsg = b3fe18cbe086955384226c11c62c1dd14e7eabda573450d005b46fd9f9eccaff24dbf5d6d8530b5e25fd9f2a629df5c20a977247cab35255d71d992d85b04c14\r\nMac = cb67f0c1819ae458\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 82233a224ed122d7306bd6717a80fa1986964f9db41bd40b\r\nMsg = 65c46382a278490b9825d4f1907f3b9f196e136906067020b6b94ee398cb2f39ed07055dd0b151d974bb8d56ae3bc8b3b31d9054221514bd45d88a5f948ccfb1\r\nMac = 27e94d22e8961f92\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = d3e3bd80f45140cfc2f857a913a89f0c7dec86790feda4f9\r\nMsg = ff26ab66c6a10ef910f5b94589b24a7b6fae8e4396faa552b014603fcb5eee921bcfb81ffae989922debf24a6947ed6b1556c02e524b247c3966a7bc636a4fe9\r\nMac = d2d326c999095b39\r\nResult = P\r\n\r\nCount = 139\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 466fa94c2158c1cd84b83fb2f15ccfce804f611ad0fbc4fd\r\nMsg = 5ea068d4f363dc7f1badf97b77ec85412a06dc8d8e3f4364265c7956d4088f014c78fad6c94be720ffb4ce4150da4a3f427f288031e0bdd241dd7daf975acabe\r\nMac = d6023f6ffd3c788f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 140\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6f5a146524457615d81a605b38a5ff03edbc5c426ec7d551\r\nMsg = 9be3a736e7e72560bea45e9c8ee8bf37c279bf5b2ef16483adcc093208c05ee51a4db04632946ba2b96cdd9d15b33c25cce2eba4ede4f97aac29ebaa4cf6bbd3\r\nMac = af8fd676ee05154b82c3\r\nResult = P\r\n\r\nCount = 141\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = c62e6eb86b8daa37936086dd2c346e3b14be5054cdc2f3a4\r\nMsg = 559407bb6930d5adbdf19a7e285ba1dee5caa03ef54e3a3fc1b8c86a02f55921de9bf7d553c22d7ad915c6384329d664e70dffaefe22ed9c4e2c233706aafa04\r\nMac = e297ad7830c79d387ac2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 142\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 225557b0faca3d6cbaedec5c39c98f0ba0723f4070f2278c\r\nMsg = eb1383e84d4bfc5a9dad25374055b81eec74316b18f6e001b0623d470c027b7023456000fc61538b663cb7c0e98d77a7fc3ee2277816bacb4d9487c6741e3134\r\nMac = f07332a3b01d0e8026ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 143\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = c36acf733d310e3b9842b3006aa637ab092faf4a580043b5\r\nMsg = 1d674eb5d85945a6c7842042adebe549d4fe515501c06c1ba72961ee5bc98d8588afd6fd64893e21220db7ea6a973a420613130dde1d7f6a26677836d65bd0d3\r\nMac = d629ef50a784db860de4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 144\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 332e30ab63b197e79b86e4da732bad9250c0a5c9976a6c67\r\nMsg = fb41304f9f5b0f696ddb0e2f0f57bb091f8a31b5324d3cdf15c3bdf256d3502d06db2df9bea24c7ae08fcd641f199610427f3ecf24b92a7e00aef55aeba71516\r\nMac = 983e453f602db30e1f85\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 145\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b311796b0519a45c176f3ff458d4d818668093e82fb871f4\r\nMsg = ec1a1e9ee85cf960e5dc4e239619ed85f4b14d32cbd42dfa79f77a27f2cd740d08730de2eaeb91d0eacb8c498336e99b9a0c57c4045ef18749251dbfa733b4f4\r\nMac = cb2be0fd09f10deac5cc\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6311e7f0a7bcc11176fb411fe719d4e0782c8935524776f3\r\nMsg = 85f647d940a6d1acb6b7851912f807063515631eaabaa019dcfb993", - "e86f408266cace4c24940eda0083d8569364dc1afb816c0e5b95f3bafe7745e5ddfccd6b1\r\nMac = 776b9642c47fabd7e9c8\r\nResult = P\r\n\r\nCount = 147\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6d120cbf74df2efffe98397ee303ead4e91c5e7839b82885\r\nMsg = 27ea9ff8359463a7742cd9c9c269ee678f4ab22091fdaf29b9007a92658687cbd71c4166e68c5a1ef30160191f6d926abb28f1da01da9ae8019a520edd576346\r\nMac = 5a902959d73ac97ea071\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 148\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 8e09d421e09dac1d9d966f02a3a520972c6aed2003d907dc\r\nMsg = cb32cb87ed59ee959c011211ae7cd475c3b5feb21cbafdd0b17796d47dc4d4e61da345b399c2661182485be13dcee33a9eaa8cc4b9742361f4c36f1361381f1a\r\nMac = 1b2bc5956223b8801456\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 149\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 3eeb143d4a3c08ecd9f7df8eba42789b517dfe99e07958ed\r\nMsg = 3292b8548a35fe34136457bcff52b469eafdb1b86b6cc88bed35c4cfba43785c59d6b01c1acb6870ef1e3ccf7dad20b1733f51ab1bc48cdb2fdf7d86eda17a00\r\nMac = 3a85ae8fd368cf9846bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 150\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 606452c62290b43559a588bb03356f846cecb0ccaf0bdaf6\r\nMsg = 3cfbc77b8897b6a5613f62f6b1c89b0d68f272c6c19b9e0ec6331ef616702006e64322d3460a57d3a5074c719811cb5dd78900268890da0ac177b40d48773548\r\nMac = 325aa552529e66a13904\r\nResult = P\r\n\r\nCount = 151\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = eac3a1a6eb8efe983c6b37b6c2709f5a8851ab72cb23a66e\r\nMsg = 2801a813dfc3f1c753f4f342a113c09b8e9a7ac16483c31bfd0b746b1db692f805937eec44c16bfbd132154557afb17ed01c1f4c55fe67f0343a6329441fb955\r\nMac = 5b0b383c4870af31a9a1\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 152\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = e2d592cb412e65f9044257d78e7491f9f80c8b08102c2d5d\r\nMsg = 3f63b7ad671761a3f27394776970b413e35a2c43ca85560cdd3c9b407bfadb4f1edd0e6026572ca0d8274bdaa6870749b0a727aa8c5b7e9442100e0c9b057455\r\nMac = 0380cb126c63bb48bdb7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 153\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b7b86dff6746145aa7d5bba73ed6a46da5b1200bd3520357\r\nMsg = 8e7f7e7e3ac2286bef6822ef47f5f73f2ff512e599df17c3723f7a55d4144a367c774de67e7e52ca3760c37484da7a2531d1d590b5380de11c34c3fe447edc0d\r\nMac = e7aaf6f82894d8825d80\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 154\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 70a26d985e6b99bd3a37575f011f2b84ed84bebf99a52760\r\nMsg = a2cfbcfdcd90e0962f233d7fb70668c8c36cd5e195e2ef5c043268f47187cecffdd36000f96e1f509f00283effa040443b3db15cf73d55c30c65f0fd7cf9c219\r\nMac = 96d09f0a799cb52575d0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 155\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 5d678acdb2e6cc03537411ae2e95da120161ecb6c92d5e23\r\nMsg = 91dee0cd1d17d9342f4d346cee19f5f42e0c3b0498447ec4043c15bb2ae8fb8a7a02d2da489f28932c05fa4ea9c0760e0cf3052a97ed898edffce3247386b98c\r\nMac = 4a40b4f63330413918a7\r\nResult = P\r\n\r\nCount = 156\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 795846f9dbf36415640276642cccf87e3dbdf6519c5b2db8\r\nMsg = 4fc989f327e1a1cc7b8af618ee6ae6d25f78e2b76b681455336945655f13fd5a639bec3a004a88ad0e2df8547a0d315b8ba15f5269038638df6169d960f5ab5b\r\nMac = cc5efa5ef19f6cc63f83\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 157\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 61eab54142fe7e16787fd2d54829cd3c4bbd793e72f9ef9e\r\nMsg = 13f079b004d1fdf02121564f0a96b057f120899ce920169561d5e3aaeb16bb8e4347c7cf8c86f9acdc25ac26fb5d845a68409c0d9df0e089940fb7a88a76e62e\r\nMac = 920de91f34eabfc31648\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 158\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b64d00f3a4df754fa4ee6376922fb67ccce0c6209f677397\r\nMsg = 8003586af34bdd0acae4f5547394245027c2ffcdc9d1335311acc859e9a2a7b817755a601dad14495d32f1ad811a7e751ac07cf18716e1cb193c203e7551aa83\r\nMac = 79e8a0ca036d7b0bd2c0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 159\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 98f4596970e6515b5357f6c6396aac182d126decaddf567d\r\nMsg = 65737b65927aebcf6cefc7ca107fda8447e8bebf1f08a280d53a4b07f8e35904cc48cc08eda3c63a3475924bde1de6acebaa65fec5ee68ca22d3fe722bf33267\r\nMac = 05c51c2507108a3f8293\r\nResult = F (1 - Message changed)\r\n\r\nCount = 160\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f0409b050346fbd319c8630e4bc9dd6d055355fbb961f018\r\nMsg = 731db98bd990b2ea19f848fda3519b32bc1d2fcb2f4d42e13f655da8e1dc2af428c185fc01a5d55e20b49d643a254e8675d560301d2ea0c5984ecce39c655de9\r\nMac = d37deaceea7ea3b50aeb02636e5095\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 161\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f266cec01c5fc08c0bdabc9537bd1aa2df9f2b8ffbe5cc94\r\nMsg = e19cbaa489a0f65681c983cfee3a4b699339ccb096df06bc871398be9eb926d84426fd32d5d7fa4aa563a88b41afa822f761560d9897a9747cd85b3dc74b4adb\r\nMac = 8690d4f8153e56e3ab80c7e918679a\r\nResult = P\r\n\r\nCount = 162\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 6e12c112720ef346bbbe7d1c19483721b1c52c438dad40e3\r\nMsg = ab8b36f46d1749cde7dd9936df95cdc8e0b359b8963bff4e7bd59599b32408623354a15e29f287a79801866d434a0ee9cdf37f931e53a39509057c7f2b3b413c\r\nMac = be9e70fdd15f96a8b7457cb727caf6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 163\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = e9ed05813262fbe769c1104d8ba5c836dbd229a22a681de3\r\nMsg = 606452c62290b43559a588bb03356f846cecb0ccaf0bdaf67a18abd811d4315a966e2f3f87f6c2428814446563fa71864d97c8336b0e34bf9466ec95598398cd\r\nMac = 4b3ac19f4dfa04108283b0e2e3a8e6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 0c84328951c66e0f5341b741d2c2796d3524ef732c69e779\r\nMsg = 9071c45a99cb987aa79596a2014f54e6fe400a6bbd5de96e156cae87cf69762f1329d481213d213d42191312fd76911d8df4c6ad9304754909058cf477adfbaf\r\nMac = 1e1003ce7546009a3ba7f59dec236d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 165\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 3aa8ec246323db7a3953737928061c79757de2e921c27643\r\nMsg = 84e9cc9bb7f4fb62ae7396859fcf33da5ca6c80c311eb392107afeddebebe0d662a887879e4014187d2fe8feefb01e6fa0d35819d7cfbf139e99451423b62ee3\r\nMac = 4259d5f983a287fbd987e3badafb33\r\nResult = P\r\n\r\nCount = 166\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 66c07634c94dedb5d4c6f19e7cdeb954692ccf51fa242abc\r\nMsg = 4bbc9d3bcf3c22daa8cf55c1b59d4bffddc2412d60518e986899d6a3e2a781668b0c6b9b4ee0ddbbcd06bd643eb201fe7829699e4dc86e2a1b4876bf9e40494f\r\nMac = c40f872ea2f1a1b45ab5737c2e4f33\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 3b9d6b0652836457ec4f701f0dc0e5aed73d16585d61cb1b\r\nMsg = df7b23a4e4456e0152b24853fe0d5de4179974b2b9d4a1cdbefcbc01d8d311b5dda059136176ea698ab82acf20dd490be47130b1235cb48f8a6710473cfc923e\r\nMac = 602941735206bbe57ce1c2e3b9509d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 168\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 7253ef10bbc302f01aecf315f9a4122ba805dc4048c30ac1\r\nMsg = e12f98507d6514c3b551d240595346bc9e9b6a987033b3c50940442dc385634e2a28292856b97d5a78704388b2b6d0ff2ce7a19c64574deac593b98a7ce98bd8\r\nMac = 9e62a5b8851d3a0fcddf06fe116ac2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 169\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = d718af395ba3f5f4c6d15c24475ec7f0f74f3238c81d42d7\r\nMsg = 0c0d3d7ff5d1b707be9648f263b8f013fa439978e959efef57d471cae02dc8e08d9d58d40381169afa039936f1f773c72003c1c5af03018725ab2408236ee4ea\r\nMac = 75749ed44b76d7ac16c98d8b6bc18f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 170\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = ec98ec44f5a86715014783172e667a748f162c5c26a8b34a\r\nMsg = c0947efb86d54644087247f9fd95133a94075faf6250a2cc9f20df5393edbe1a4bdee20e90e877781a370a7f00cf9eee7373fc38acc54aba23b0df3f020356c9\r\nMac = d994553290066d778369b54ae06668\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 171\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 9fab32caed6e1cb27d2115cc641779127d4aa57db0955bd6\r\nMsg = 6e3e25db29da2c787bb37755ee770e2402fb8208da23389d36030439a143f971ecc880dfda90a8231ddebd2881981ca968ed45f3763a32ec8d2fe854fc2e4b4b\r\nMac = 4d3cbf9b68da0c5b49ab3b0913a2b1\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 172\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = aae24266e5981b2ed14213a29f961cbbf7f02f63a33c987e\r\nMsg = 8244cb416b3d09521ac2fd28c29084ff3d64761d46617b59e8b221de36702c2d3dc62e61375357b702cf8d4dd0f2bf2a1f91777fec0baf2c23e3e6865bae7358\r\nMac = ab8e9df7128f4857e0a1c24fbce473\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 173\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = b9bec4e88775777ff1eb3df671fe8ac03a693a1c26ea254f\r\nMsg = 8eaed4810702df8caa", - "12fe7e26e7ebbca11aa2de9f3169a8262c0e3c205a708f0071401aa8de09d28a5a6e590ebeb476341880c37bfee1a501229081eb27772d\r\nMac = 273b0d874010eac97ceda34232f7ee\r\nResult = P\r\n\r\nCount = 174\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 15120ac9468fa30c92ad87e7aba41ef552814e4ecbcb9350\r\nMsg = e3de6c6119d7db471136285d10b47a450221b16978569190ef6a22b055295603c9c1ed5da3bf96bdb43a5722cf4e2ea087cdf9b23b3093d250d44047be634b3f\r\nMac = 9a166994de85e5d60b154d49a867f4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 175\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f9b9633f12967f1841161a3752de1491b2b2f519d8447636\r\nMsg = fa14d3656f7f7610f3a629bce14648a593250c6f309c02c6c552bb42984ac58db920dbc7d98f59295f37f3e9b99da55ef074ed65801b390366669b4c7aa1c483\r\nMac = 2c9f3650866b97ecc5ed66929f41dd\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 176\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = e87275bc62ad067b121b83f220d4ee2b4245541283dfadcd\r\nMsg = 6475757f30dd0a96ad64bde5c2605a9d2ca82a7223a9ba4c39b6dd3f86a0f4bd02876d0a32ef8af1071664b603862f4b9de6bfc6e7154b136e7a72e661957bf4\r\nMac = d0bd2d3d35a22f37bf113090cebecd\r\nResult = F (1 - Message changed)\r\n\r\nCount = 177\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 8b63d3c794e5ba0e09e5d5a5c56670bc0e289b30171ccfa4\r\nMsg = 44da1657e4be60d887a097e29d03bdbf5920bb0504e654bd963f58c487951a72e395237a9d32281125ed3a533c543de208c99bd063853abf79ddab4692c3a497\r\nMac = 29d04b97ac302fefa80f71ea378e7e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 178\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 17039577fa27ef5ac3bf97572d9de5f8eac0aa58ff29b990\r\nMsg = b0329a0978e5a2d1bc85bdca333e7d0d1e9950217ee9547a84e76d3f49999451bf787288e8d12d40456c8214926c14e9b076032fe315c1633d5d21d85acfb1b8\r\nMac = 51b4bc8b479dbd60e5de94ba8b9d0f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 179\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = cf6b5edc515882f8a7954a5d8517b1a85e9559858527d0db\r\nMsg = fde631afc6c042d77b579dab9298862d943be673cea59eab4a0c1b5cfddc2aef42590e6d8786d18a4646d7e338c2b984c50a50adbeff0fd64e7096f02e8385ee\r\nMac = 5ee3547a06661661c46c3778b0823d\r\nResult = P\r\n\r\nCount = 180\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7b6f4f158422f33543ca90dd0a76cbb23c0dbef26ee140aa\r\nMsg = 6704dc39a259152d2dc3f08b8799ffecf4e1bc38\r\nMac = 5c12ff63244c64bd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 181\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7a381f75058b85680061eeaa0242d3a16a64a5ca50cb61fe\r\nMsg = 18b31ed5ba1c3ac562ff3ef274424b86c0815c26\r\nMac = eb8f3d508c9edb8b\r\nResult = P\r\n\r\nCount = 182\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 3662d7b7c93211535c862ef3dc2724c492cc1e53a58f23a3\r\nMsg = 8ac860504258c134c6835d4cfaabdb316c36d99e\r\nMac = bc1b870eab5bea9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 9eac76976750b7937b3bbc6986b4c726f0d0a63310db85d7\r\nMsg = 5de2265292780222349ac793eaa17c5a22902344\r\nMac = a69594e569230df0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 184\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = ed1531500f319e09227d6bd181786b3b446f081abff2e697\r\nMsg = 7a734243e53cee654be988f5c735b19bb11f3389\r\nMac = 9f2cc2a8c3d0a34f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 185\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 85d0d04cd3fd2fb34dc18fd55e645f7492d5280657577008\r\nMsg = df899dd6b99cc28d66604ca92431fa7f442a4927\r\nMac = 18fc40b25fb9c138\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 186\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 90b0c8b542c91c1b2dfdebb589a7eced6c9b7b43a7729840\r\nMsg = 38d1a87296529595acce251cb232db8ede65581b\r\nMac = 077570fd0efa770b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 187\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = eceacd807db82378e9bd7c79054878f09dcb5087c2e1c349\r\nMsg = 09bf4f77a9883733590a3cc7ee97f3c9b70f4db2\r\nMac = 58af901fe0fb5d29\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 16227835305b7586a3106d93da8bd70aa0025df69a0e85dc\r\nMsg = 1a223362dccc99472b2cd1d712ec6dadd60ef972\r\nMac = c26f3980d17f6c36\r\nResult = F (1 - Message changed)\r\n\r\nCount = 189\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = d18cf5dbf5b2094dd6ad85d975449e2dda35b184633235ca\r\nMsg = 7f557e74f53c344daf7495526d1270dfa8fd24ad\r\nMac = 5b7cf33ec05b1576\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 190\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = f1681287bc931a0d8f296e13b3584d6efcb6ca76aa90cc02\r\nMsg = 08c62ff9bd7bcf189f530d5065f8764532d2692f\r\nMac = d646e2ec15afb14d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 191\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 116f4855121d6aa53e8b8b43a2e23d468c8568c744f49de5\r\nMsg = ab91d1aa072947d22f0dc322355a022fe7f0747f\r\nMac = 489068c07931ee9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 192\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 0a23972e036d62199ec327b25a3cf4e14c29279c6449d3b8\r\nMsg = 2df3e80fb6ddc1fcc7615330b24fbaa4981441c8\r\nMac = 7842f16a0cc7bd6d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 193\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = becfa1c96686b04153fae144c187f034dac3ee6ed70d867c\r\nMsg = a3a114679ce30c8472149da9bf3a42b1ffb07e66\r\nMac = 74fe19b5183ed3a1\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 866b43c8fe3769ec0aeefd4dd02210488a354d67e82a81d7\r\nMsg = d9bd6ac153cb0bc4e19e59c45cfe0d6f4c9d20a3\r\nMac = a3a2ef83eba2a6f3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 195\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7e00aa080c127cbabfdfa5d9d9728c7b25358aecd26f5850\r\nMsg = ce1a38cd75b9e955483ab53fe59649d087ecd1d6\r\nMac = 8375c666d09bf259\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 196\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 4bbf4c9cb6758329b2d5a53c4fbfe2d3df4fb50e57b3699b\r\nMsg = 6429ea2cc8fdaf58100347d21da64375b3ab2058\r\nMac = 77e417a60bca9a9d\r\nResult = P\r\n\r\nCount = 197\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 274b394da9402d3eafdf733994ec58ab22d71829a9839957\r\nMsg = 2b3d7949805afd73234cd327a62951b32c51df2f\r\nMac = 8f9ce09fee15516d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 198\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = d4140d988448d557454c3434fd77f8597e6420566845e316\r\nMsg = b53017500c100dea0511845597214484fc5f7f34\r\nMac = b9e85ce9178b81c7\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 199\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 43d0d326c511e3bcf4f52660fc3c706a6a95c0ab550615f6\r\nMsg = 7c880698ef372304a663f0f02944500393585d42\r\nMac = 843f71e93b22f1e4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 200\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 273cc5013785baeb5abc79c8bde73af71085d7018e7be92a\r\nMsg = 086e6e3a21787acf7293446516b5f54da95a2988\r\nMac = 658a112d7a9e7a08c024\r\nResult = F (1 - Message changed)\r\n\r\nCount = 201\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 492bf7946bce1d3c6f168f4475e5bb3a67d5df2fa01e64bc\r\nMsg = f7b577f1396b23c27eb637e53d3d92460270b001\r\nMac = f2dffabed6871cca2e41\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 202\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 8e7d8a44244daa7df2b340993e32dac50e05d7b2e103be98\r\nMsg = 2c3c3582e026a3f29ffd21a92a8e1ee70f3a4147\r\nMac = 1bb40d091dde1903ac0a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 203\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = d2069266b0f180cb319e30ded7535bbe52d24be151de4bb5\r\nMsg = 392d567f0b8045359dedd1591517ded0171fdcda\r\nMac = c1ca2813ad38fd7f0f58\r\nResult = P\r\n\r\nCount = 204\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = f35c46bca9236830ff4bb057cd5764f02720ccb03b253937\r\nMsg = d4586dbdd5655cf659891f5b6015da524548dbbe\r\nMac = 4b6dcc78f6e0e9b7e35a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 205\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 509f1e38591e03a30a7409bc7e18595848253308c15edf40\r\nMsg = fd2109cac9f42fbb093a8675e5cd962c4c31df2f\r\nMac = 35387ef3967eed5b579b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 206\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0e9cf0ec43ca3fb7fb9a2b1999ae635d5041bf42f1b0bea1\r\nMsg = 65960c7fd43891ebdc7bf862b28d4822a8488270\r\nMac = 93c33247ca546a8c3fba\r\nResult = P\r\n\r\nCount = 207\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 51597a4c68cd228371e86c179fe04492642ad9b888405067\r\nMsg = cd8799124d94064f47d7eec59aff543b81ac66f4\r\nMac = 0eed36a27b40560b89db\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 208\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = f9f049328f5db22c41a501088e5759ef4d04db0c4b4f6d3f\r\nMsg = 7bdc26b5b4df58af539d91eb2ea10263a3e58b07\r\nMac = 68c45551f1367c989a9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 209\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5343dacb05a29b3119d6f19bdfbcd6674950e710fc70180a\r\nMsg = 057c2d386fb1693b845bef585e76e0fc", - "4971ffb3\r\nMac = 372a801d1cd33d1059ba\r\nResult = F (1 - Message changed)\r\n\r\nCount = 210\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5987fcfe8a1ee76afaef54cb22d8b2a20b116f72bfc7117f\r\nMsg = 8abbdf380c668c6ff34a4f128567bfaf256570db\r\nMac = 5a8089b3d9f6c72fc858\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 211\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 301e0712ce74a1ad02079aeb0ce35edacc33f9a5d907cf70\r\nMsg = b2d894833daef4070b764361685fc94a780a7292\r\nMac = 57a225eca09fb227f79e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 212\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 144840494d15b2b31ad63ee05bf579a5e9fb98f534a6309c\r\nMsg = 71bf573cf63b0022d8143780fc2d9c7dbd0505ac\r\nMac = d1b2baf05cdd5fecd1cb\r\nResult = P\r\n\r\nCount = 213\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = b4bc602dc860108aaff5b3befb948a561ac495a22af9085b\r\nMsg = 3fa85ca50cc4c4817e951b5a95ac006973324c2f\r\nMac = daa1246b82d2e14e3056\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 214\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = ff48804c82414ff67f9b917a4d5d062d439454aad8eb4b0f\r\nMsg = 6def37d9b73fed0390f260491f582d2215369811\r\nMac = d7712f7d5f0da5dec6b6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 215\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0273e421ee670be6322675f26f9014c040a76f0c869698f0\r\nMsg = d9de46934cb56e58899a31fd14ca64509131dc27\r\nMac = b3e79909c16c561eb7ca\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 216\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 27eb9812d3f7816fb6a1cfe474496e80750b1ed3959ec7f5\r\nMsg = 776ba7990086731ef7504947be74b3c455bfde5f\r\nMac = fc0f2dcf4e6fa041830d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 217\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = c56f710e39deed799ffde6d10e8aebfa2bab5e5e073d78e2\r\nMsg = f6fe0f16403182d012f8b6e02539c386075b4585\r\nMac = 6bcc4c1b06099220e9c0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 218\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0236ce1fd3ef645a64b4ee7048dd35942e6a09e8099884a8\r\nMsg = dbf06366f766e2811ecd5d4384d6d08336adc37e\r\nMac = 1de717c402baf964e817\r\nResult = P\r\n\r\nCount = 219\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5cf781067bc1ef948e929b7287279c71cae5143631ca57d6\r\nMsg = a7f3fb7ed1342862247fb4b1993788837cc87041\r\nMac = ee867d4c0f910e9d9288\r\nResult = F (1 - Message changed)\r\n\r\nCount = 220\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 3e19b6f3f3fa3c2551466c9e09f0391350682495426fbb08\r\nMsg = c7496322ede893ae368884a91f80c3bac3505c0d\r\nMac = 55b25da032db8f3b4293a4865df77e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 221\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 5717ed57ca0b6921f04dcacad34e0f6210c36673dc9f4d92\r\nMsg = 5e3ed45f07a6b3c225ba73d04d867f9c5b4aa703\r\nMac = 1b642dcc4fa08cbd36d109d55a8501\r\nResult = P\r\n\r\nCount = 222\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 8eca0fb8033e63e24a54a3e63bcf8e4ec331b04ddedfeeff\r\nMsg = e3807f6d8c6471ffe188df67d952a7d67021bf41\r\nMac = 9a37eda1e3331bf86d208b2c0338c9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 223\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 633f44dad6995a6af0302692142a47430491ae7b54f8b00c\r\nMsg = 3caa9b8b24097d29bd24b913692acf96cc78b998\r\nMac = a6665b3b158f37f587dfa0bde7f300\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 224\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 14ef8096666ddf28e0ac5f3458b52f3e0c601deae57fffc9\r\nMsg = 11d5cef384474f33c2d313e6e1050d8c7ae5b019\r\nMac = 2643bb3e1c01f406d90104c4437189\r\nResult = F (1 - Message changed)\r\n\r\nCount = 225\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 0c2e1951eeba1a9b6592202b1b8547f43fd755fbd844a874\r\nMsg = 9ad62bff38e28f75302b6527c1c107543f798817\r\nMac = f42ff7aa728c2d815ac7c701b59627\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 1ee2df7aa80e3a131e2aad9c17bcbf546d8b25e5a849db31\r\nMsg = c4e8594cd09be010b6934157e0557686310e8dbe\r\nMac = 34496d184bbdc0c9a57916ff64dc3c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 227\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 75650ce366757618af20205b69af7e5d4e82c398c00101e2\r\nMsg = 42a71eb81ad1c97ac53b88831b2d15f3c57e7cf8\r\nMac = 4c03394a98bb43e6197074abe63070\r\nResult = P\r\n\r\nCount = 228\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 386c659bc45d0a88acd54ef7eeaa3e140e1cafb1b01474a0\r\nMsg = f4fc5acff75d404849675b813cf7adcaeb8f3d56\r\nMac = 5cfb2fc8869304428fc012a14b616e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 229\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = ac192759625f4e42d1d1fa73dc0f62199142155615478f88\r\nMsg = d33f716df06e9047f8d718ab1faa06ec7b773bb7\r\nMac = bbf5b7207faa5b004216fa5caf3f93\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 230\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = efb497fb9b85d472e7c9d061aff501f7b1e3a311a86cfc69\r\nMsg = 1fd425560816aa21d6572150d1161cfb3bd61e6b\r\nMac = 2b7e14864d29437647cc1b27a8a0ad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 231\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 344fbbeaf82ede8a401df7cc121ed3da43be9bcadeeb5614\r\nMsg = 93febc9e16003cc8d6490ba5a6e64dd673a0f887\r\nMac = d34ef878392bc226f7ce1519f3bc23\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 4b6c6b6be3c04985bff49719c4e11be97d7757801dafadc3\r\nMsg = 754336f8cf27f4bcc7af5207ff02a662232d9a62\r\nMac = 5389c533cf43ca0332574802c2ace3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 233\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = fe5ddb0645387cc6535e5b7991e6428c4157a76bb41084fe\r\nMsg = 216d9eb896edc693520f99ac91f34cb54e76d719\r\nMac = b43388ba7859f803655d914b60ce90\r\nResult = P\r\n\r\nCount = 234\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = ed14373671cd8041e00874b5d098ea225eaf9c68bb51cecb\r\nMsg = 0569c6be9ddcfbb82618fdcfcab3dd60c20c49f5\r\nMac = c2c11297111a92a484868179c5931d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 235\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = f2faab6735779e9ac49716e7fcd3faac939366a7249f4f0a\r\nMsg = e7292269b07683acf5bea0b300782749074e2313\r\nMac = e10f324c19d79ed83256f15e302699\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 236\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 2bddd90daa1251a42a0e2fd2858568887f85e6d96d57daff\r\nMsg = 0f8b828c0e59effbdecc30abb6cae0d9af9c7636\r\nMac = 1aab0530749ac4c6432157730ee3ee\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 586233e492b76ade095e8f5ffc6df4bf6caad2a675953b2b\r\nMsg = 92af89c950d6221473a358dd0f280277bde7ab0c\r\nMac = 2a79121e68ea6b841e175ab5066388\r\nResult = F (1 - Message changed)\r\n\r\nCount = 238\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 5aea45c0995e950f333e29f4db82ea4c4c080ff82fe32bd6\r\nMsg = d9ff1c84bdb03114ebd5f471247a579311f4672b\r\nMac = dc58e7582cb555ea784036a8ba4b8b\r\nResult = P\r\n\r\nCount = 239\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 900c8283c7d50d6da79cc07d3dc7b76c2ef76100fa3ae2df\r\nMsg = 3f8c6d21ec05bc439bf82774f1812bd2dfe0d3c4\r\nMac = ec1fa18916f991d7276428b9c93c70\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 240\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = abbb803150cd7fdb9f3d571bc749debe72c825e45568aa5e\r\nMsg = bb5fd7f4fb020d38c13df3003a9bb852a86948f406c51624eaf81989b006\r\nMac = 799d598f32ebd9cc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 241\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 2fa619eed51bccdd2ce63580ebf85467ac9136f79256bf1b\r\nMsg = f92d1a6731f3bdd811fde1ed936de907ebbc4179670857859aafe788b91c\r\nMac = 6477feb7dd4c818a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 242\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = d0115f369d0f74073a46e3b9625660847dd7ac7571e40814\r\nMsg = 97da5d1f669dc60b6c6fe4369e01f3fbb9af30b483b23d885497c684d6ef\r\nMac = 3d7f0acc627b785b\r\nResult = P\r\n\r\nCount = 243\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 045c4b86eed865cd989f035afe8c257c400c11b1f72548c6\r\nMsg = 5a6233e492b76ade095e8f5ffc6df4bf6caad2a675953b2bdfa8513df1dd\r\nMac = b5a44479b0be31ce\r\nResult = F (1 - Message changed)\r\n\r\nCount = 244\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 4a83bf338fc0125ee1966df46d46a0d0b41e51569b3fa957\r\nMsg = 794a86f5b20d344ad86fd5523d08f1864737be57731440c29aa6b4257457\r\nMac = b45939cc01918eab\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 245\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = d9ccd93317441e9d6ccc358f31e7e2ccef8c921b23d74299\r\nMsg = 48754401bb69bed2cce8689e47210435878c7ce184d911f60d26b4aa5174\r\nMac = e0d1b6a530944550\r\nResult = P\r\n\r\nCount = 246\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 1e50fae752ac3a6e2b1755475e84441947e9f4b1d29546f4\r\nMsg = 34245df514f6c273d252271a980929e50a7cb0e77b05c7d46092abc30493\r\nMac = a0fd99f1405b027e\r\nResult = F (1 - Message changed)\r\n\r\nCount ", - "= 247\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 4f98838899bb47fd3b0fd5efcf55403996567a0fbe1abdda\r\nMsg = 0c8cc752ae8d487c621be129326513a5ccb4141e324d21aab399148c1a83\r\nMac = 1aef1b7bc7856c6e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 248\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = c98a22a667aafab0c94047e03837d51b11490693d5c57ea2\r\nMsg = e4fb1612e50607457dee8087ec41e57fcd7fc550497eaf1c8b0d47c773d8\r\nMac = 2c467fe37fee5342\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 249\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = bc6d4c46476ac1ea902be391b8a3f04e102aecead167f0e4\r\nMsg = 93b3314baf20e28a39e89592012c35adfaa3ee6d3d8e494051ee9944aaf4\r\nMac = 7f10757d2d36a55d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 250\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 5783548205826853ae740d35d6d69ab524c38fdfc5c51eb1\r\nMsg = 11c90809f9c53d2f77b56af0a42287ac6920e3d2921cceb824d496caf1a7\r\nMac = 07630c2fc52a24b2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 251\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9cac76976750b7937b3bbc6986b4c726f0d0a63310db85d7\r\nMsg = 5de2265292780222349ac793eaa17c5a22902344063f497aabb9dc038ce2\r\nMac = fd092bab159861c0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 252\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 616de0b0f868eec923bf9edebbbaa51d3faaa3f86b2a5687\r\nMsg = 38013d62558647bc21d293830aa3ba80ff3fb84a8e0938754c5213077771\r\nMac = b4e782780989dc11\r\nResult = F (1 - Message changed)\r\n\r\nCount = 253\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 5df77b26f3d34eba49d287addf0a38d20514e2b7e6059935\r\nMsg = 1930a8b428334df9fa1ac16890f3a6a93fcf9d6855d00b06ff831d8f6a70\r\nMac = a8ad975046cd7571\r\nResult = P\r\n\r\nCount = 254\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = c56f710e39deed799ffde6d10e8aebfa2bab5e5e073d78e2\r\nMsg = f6fe0f16403182d012f8b6e02539c386075b4585be5b18d6ae1c5f9ebdff\r\nMac = d0df47dda012655d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 255\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = fef8982f7342f1b953658453cd5ea413700eff00f1ee7d6f\r\nMsg = 269b6c1c95bc079398bb31e285a887c1832202d6ec257a2cf62468e29358\r\nMac = d2c90040bf66b2a6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 256\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = a34dfa24847c365291ce1b54bcf8d9a75d861e5133cc3a74\r\nMsg = 105d2b82676bf67ca9575ffd31d7d114e709826fccb6a5c3d3d7e26ff258\r\nMac = 5e60278f98b3135c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 257\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 520fe80cc4a3a5ad9c31f7010504923b7a7fd88292a64f98\r\nMsg = 2e1e0712ce74a1ad02079aeb0ce35edacc33f9a5d907cf70d0548d84ec3c\r\nMac = daf839ef84f1c81d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 258\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = da4775b8f7d654bc4cf2eb75ecf4831411bbc9a960ea2df0\r\nMsg = bfaccce3a9e66f45e454090ffedc348306dc2807951ce0bf100178612703\r\nMac = 3e2eb7f029e687be\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 259\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 15e3b3c5794fececd703ac58ccb22a78e15bbd55c579416b\r\nMsg = c6c3457ffcb6e66c085ecb69492deaa704e25aeeabb7b7795fdcc807b325\r\nMac = afd75cdc02222e65\r\nResult = P\r\n\r\nCount = 260\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = e0f2cdfb64bda8f02ab90620fc5a1943c4b536a99f3f8820\r\nMsg = fd0365ff6061e5f55c0e382f5861aad99c135f9511f33ace4bdcfe48c6e4\r\nMac = a1046d4b29fc50ed94a4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 261\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = c7aafe7d3b419fa4ea06143897054846ac4b25e4744b62ba\r\nMsg = f1baf3be69f69611fcd47256e43830a1b3fd8bd3952eb26ed679eda7a4e0\r\nMac = dbc419e1ddd5cfdc63a7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 262\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 58c219f2bc8ef2ed7a82cf70e4af4747e36a30809a5a6222\r\nMsg = 622642aa69b3efe14abe0a1d2ba20f3f76efddf62e6cafe2845c4dfaa501\r\nMac = 4e496c3d2d84d11923c2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 263\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = abccee975feb10f635d548a8502f7c8b6adbd2be74117257\r\nMsg = 4f37a460d180a12789779fc335326c983ad6b18295b47f1715b82b2dc704\r\nMac = 41b234e0173770c469b9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 264\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 0218eb619dbbde2e846218339aee4383792856496eb3b85c\r\nMsg = 28d3510a37d5f8481e7f22941c1fb1d6c70686fbad9747a23c9d5f18dfe2\r\nMac = 3cede44c942387d91767\r\nResult = P\r\n\r\nCount = 265\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 88b2514f368d51db283039efcde1891652a77daf68feec43\r\nMsg = 067a3a0434e92cac02710221fbb6dfcb7ef0264e2994905491317c8c3697\r\nMac = 128e652ce0a8f1a6194d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 266\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = f2a78c449621278e9e927fcd50742d042d98d5142380fd3d\r\nMsg = df899dd6b99cc28d66604ca92431fa7f442a4927d03b392e707b548b8ebf\r\nMac = 2eca3c42b5e5d0f3b9e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 267\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 01fbfbde7dfdd6f0a0c5244cf6c36eece4d6dedd8baa463b\r\nMsg = 485ef613bdab5473763bb269a0d8c7a4bf4850bba072a96f8fc39a31cbd0\r\nMac = 333eb331d6a0d46fa279\r\nResult = P\r\n\r\nCount = 268\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 6ce99c231d2ef0fd48c2375dca93f8bb0df97d4a44e835cf\r\nMsg = 32d71e59634126ac6c6156a80a0dfa0175b29e9f40a3169680b1c15830fc\r\nMac = 3e90350e115c425ba466\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 269\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = f7a93aab5707ca3d2362c5669198e0218493acc3cb7b02d3\r\nMsg = aeec40ca8964fd6a67d3dc871ebf1bfb72f52907f1d6ad441bf2cadcc6d8\r\nMac = 7381d65aa138c86713b5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 270\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 84f39f5207afcfd677a7544579f2b888a1eabdee4e835924\r\nMsg = b8d21e9c70bf63f04be311d50f84aad7e1bd2b0e517434ab978d68d01c5d\r\nMac = 4ab61c537f8b15f824cd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 271\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = d488bdda400932de56a9f105f0e74ee79c2ed869faaadc31\r\nMsg = e64949ed85de6359595f286e29014c26daa7759aee56e4194ee958774606\r\nMac = 2752bc490802b9dd8686\r\nResult = F (1 - Message changed)\r\n\r\nCount = 272\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 76ddfb075fce4be8854185c6899a88d06e24854506b31237\r\nMsg = 9d86ae7d70e839078babf7fd60480a4351690867c6a8af837d9ad465220c\r\nMac = 2522efecaa1ba11c0260\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 273\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 618041501dfcfdd2b60d71c04d635f6357ad8b0643af77aa\r\nMsg = e5e6b57e74ce7afbde3697e2a69d61ca615aa3dfd32fe31f5521e6ca7987\r\nMac = d958753757a11eacc848\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 274\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = dff6b9493de80447ee18ea7311fc9b8d74f77ac1ab21ce84\r\nMsg = d70aef3532bdc5293a3ebb11589ac1f801c9f93ea0d656e1d04068facf9f\r\nMac = 9a761e0e54767e414cf2\r\nResult = P\r\n\r\nCount = 275\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = d7780ba2dc5cc584472b64bc9f6246bedb27c70aca22c0a3\r\nMsg = 14691c1b47ff1547c1d2151913c2d1862d8f54782291ea202caa3d8ef07a\r\nMac = 78a2bf3a5fc87a14e090\r\nResult = P\r\n\r\nCount = 276\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 3bc5dba883e2e3b81df06760cc32f11009cf5a5503cbe864\r\nMsg = 9d043e368b41acb5eebb99197e15adbc3d19175a0bfcc97275e3e5efcfa5\r\nMac = f457293acf683c873add\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 277\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 7b3fba25c5ef410ecec62276b105ecc01c325dc2530e8364\r\nMsg = fda4bede287c57eea4448af5e99d41c7d307d1f202af7f387f874342a29c\r\nMac = 0cfb78ede5f4c185c33b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 278\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 38efdbbc5645f65414b9cb81d2f9e4f190cf6e6e05eaedbe\r\nMsg = 50422c5e6a0fb8231b3bb6e2f89607019be6ad92a4dae8e0fe3f9e486476\r\nMac = 0c1acd8e8527e2663486\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 279\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 94ea5b0aa6c8b07e379122006042c920077bd61610df6b4b\r\nMsg = 1d52f401f01058356d8c4c630f64c5322caa6063d6365ebf0040ec4ee12e\r\nMac = 2dec0d3bca617209b07a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 280\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 5584994f80640233ac8eb4d2f873e8c997499095250b48b3\r\nMsg = 91febca4f1ae7e27501400c44ce8681ec90f5a5637c962db142c9284b1d1\r\nMac = f0b3135c1748e823aed10c4694fc60\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 281\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 57e99653fdcab10135a2ee3bf45c1be69e9ed57bd74dfbad\r\nMsg = 51c88fd98a7d82043a1500fc3d8a66ba7ab7760467c7fd89cfeeb22dd257\r\nMac = c588ee1d4f330e51872065c02cae61\r\nResult = F (1 - Message changed)\r\n\r\nCount = 282\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f622d736124641bb7d53706bf2a69db2fc31461fb92818be\r\nMsg = f09569906", - "381138cc49e3fc2384c5d33c34abd3d617c487b52ec6ee7b510\r\nMac = 610e1c1f9ab35059580061b8662a81\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 283\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 9662baae49c26e5452f3304ceed3b78326d2020a99a63f69\r\nMsg = 1d93aca4e2e31f5ebb84fad580fe74f5b6d1d86ab30cd0c8031be4090be1\r\nMac = 3c5a4eb51ec58ef3468bb00e7cae8c\r\nResult = P\r\n\r\nCount = 284\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f2100615431349aba5c4f5a7f358fe7be579f4cb9e8f33d2\r\nMsg = aaf26bff7ad4116969c15d9206de6c737b7dda87619e3575d9b6b2efd8b0\r\nMac = 7396deeb4316fc6d84d3af119656f3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 285\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = a5993acbea8c55d7eb55d60596f83e1d9f2cf636d06240da\r\nMsg = 0bc1fede6a6ed9e1deda82612fbaa6e60f0b2461fd5d131e6a7206f41a07\r\nMac = 2f6b0a9f2a972d299bfa5892f8ea83\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 286\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 775846f9dbf36415640276642cccf87e3dbdf6519c5b2db8\r\nMsg = 4fc989f327e1a1cc7b8af618ee6ae6d25f78e2b76b681455336945655f13\r\nMac = 8b3cf3171912096763a2ebe5ea9e41\r\nResult = P\r\n\r\nCount = 287\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = b214b16bbac27ccc9773d3c8dd31275da4876c039740ca8d\r\nMsg = 7786a3e30acffd6dde375bd859dd6be2c9221b979d0c66d1d5ed6e00b73f\r\nMac = 1a73acbf4e9250610b74c727b9c42c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 288\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 032b4cfce8a1acd89de5f6f78794e2813bbcdb89959dafec\r\nMsg = 3f0bf0141dd3ace0fabeace61811eac5ec801deb7ffe3b0514d43db90bf0\r\nMac = c24066cbc00cb5c28e48141b627411\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 289\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = a053255875ed4b5193bd9c5fa4172a1f660ecfd2a394c2a5\r\nMsg = 14666eb960c6b4f8b6ccc49f79a039b12c02e0972c300f1e9d0a38c0a474\r\nMac = abce3abc224772a43c058016bf25bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 290\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 0ee87b40abaa99f598fba22c3e677a85ca3ec95c3a51aca8\r\nMsg = 1bff19aacb9c7d0a44a15ce686a2469e3934d086365d36f449484498353d\r\nMac = 4d565c2e12901845e77ed8b02746ca\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 291\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3384f8563cfd0fc8019bacc9b691c9ba4ae6dc8cf4c00629\r\nMsg = d31e959cf7842db351db407266ddae0b36e37f34270576724083e9989764\r\nMac = 96d0dbf51d96b532321da593383964\r\nResult = P\r\n\r\nCount = 292\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 375904fb9fcafb7f19877b145b0284cef61ac7a3d88f537c\r\nMsg = 441bd4db5e80c7db1b575a19b7bad021a719658a2c818566291d3cdd32fd\r\nMac = 3b8dac029f6658e44e5f5bb8f8ee40\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 293\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3c1ca347a7d3d8db8f704410c493d7a65718cb7bffec2dff\r\nMsg = 555fd02fad4f44484133f9472c050f9da27390fa2a3e48cb0be0d7020171\r\nMac = 32be39d874c15a0fffc7111f76bbc4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 294\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 8bed296a3ac03fbfb71422b9211799150b9d766a8116bebd\r\nMsg = 6df3de543cdb6d1adb6ca7df6b5a4510fc8379a4f2c87497ad1c2b9a69da\r\nMac = f24ff3218e7905d81c3e99c84bfd26\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 295\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 9530bb291d38f6bed10318081dde8fd178f02eb0e8b7d022\r\nMsg = 5f48624302d1acf7750994d45f0999ecd89a3861cd0268d5a51e672124b1\r\nMac = 0afed54c577e550eba7ac94a2d82d8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 296\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f5400b86ace6e3da5f090befb96fc05d0409bf41fc77b4e0\r\nMsg = 1c79b055fded54af5ad2f3253f93a090ec003863d9458d3ff718c4c13937\r\nMac = 59f94d4b13539a5f0a8672e4599bad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 297\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = c033e4a512297caecdbead892b11a9f7007af9a74bcab89e\r\nMsg = 3ce965d58856663d54269af4791ec57ef98227ea387d525769c23ab74674\r\nMac = 0dc19e37a255dabb61957f7f89ab06\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 298\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 2459f951d1255d093b72144b83b05ea3185d5123d1ca864d\r\nMsg = 661c6ff41af91a6d828a4d5d507f8a9130abe91412070950c5fa4c75c8d7\r\nMac = ac8e75b4465a52b3a7da3746f9875a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 299\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3b63415210361822e23cccf0faae88cd7642f44cec45fe37\r\nMsg = d7f78e950d2ab520a6f1e82ec6f206b2e8c71131c85234bd80500527f131\r\nMac = 15e59760acd3dd74155d6d3739c189\r\nResult = P\r\n", -}; -static const size_t kLen35 = 61387; - -static const char *kData35[] = { - "# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 256 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:45 2011\r\n\r\n\r\nCount = 0\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 45b74171271e1fdc19f9beadda58010d843af69dc2f4ad003dd74b9b570d5a98\r\nMsg = 00\r\nMac = dc0ee796\r\nResult = P\r\n\r\nCount = 1\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 2cb4239fffd13762fb5391f5a4760d12d96ea12666a793b4d651e9f4891c22c1\r\nMsg = 00\r\nMac = 2e19d6cf\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 2\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d88586da8b605a6fd5a45d316b89fea15e27ff4d92238397718e68b8e00ad605\r\nMsg = 00\r\nMac = 8ad78885\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 3\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 136ffda3359fee8c81e6dac131256f4bffc0d3c3e74f8aaf2f979a0fa5b8ed32\r\nMsg = 00\r\nMac = e430d0da\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 4\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = e1a7867476bee9928b7237ab7a3d502fbe3d2d45b6e4c41aa9f12b79099f019d\r\nMsg = 00\r\nMac = b6f00f90\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 5\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 5b4d945d55dea22e37821ec396476a4bfb617d2f392ad93afe67bcfda9cd9b72\r\nMsg = 00\r\nMac = 5076ef43\r\nResult = P\r\n\r\nCount = 6\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 23df62a79fd5866425427d0ccabf05b16590e8452ee22e028b51910926ad314a\r\nMsg = 00\r\nMac = 7bd29398\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 7\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = ce9da814595f76a7e52a1222c7c9a6579b3cc2e393ba51580ff6cc9b6ea2ad8a\r\nMsg = 00\r\nMac = ce872fd7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 8\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 507c4f32246d637fe08e454c638b014438109e1fca31f724d40ac6ec1aa20268\r\nMsg = 00\r\nMac = 282a7ec2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 9\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 537dfe9fc000468dde29800549b1cfaae67ad89d22c8264d7eadcd914ac54ef4\r\nMsg = 00\r\nMac = 7936b7d5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 10\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 1f57959cecbd377374477e33b34979814f260f77867392ed645998f73a3b06ae\r\nMsg = 00\r\nMac = b4b63264\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 11\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 3d272b4a1a1031369aff514e2df98d580f972b5abeacc05cb1288e6e473c0fed\r\nMsg = 00\r\nMac = 18b35edb\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 8774d1acf96362215a3d1e51e1a52a980685dec4f3afd2d438c03c00c04a79f9\r\nMsg = 00\r\nMac = 80eb7a84\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 13\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = f37155beb5eed8899d9ed4b5fa21b60b40af289f090a355d5bb1aee52957cd99\r\nMsg = 00\r\nMac = 6827f73d\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 14\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = fcb52c44379ae8083bdc7b827383df93cb1a7ecc21574730f9fe003b7302de23\r\nMsg = 00\r\nMac = ccad16d9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 15\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 83e231ecf8913ebce00e62b8f00c1abbaad710142fdb912c54664169f7af0e51\r\nMsg = 00\r\nMac = 8e393f56\r\nResult = P\r\n\r\nCount = 16\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 7d35e77450e2adf8805d5ad67de5835b2c5dccafe8440865c7e7a1501ed53a98\r\nMsg = 00\r\nMac = c6899710\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 17\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 87143071241bb65261fe7afcc102416e59b9e46ee0c9007308f0eec10e45f6d6\r\nMsg = 00\r\nMac = a1a4449e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 18\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d30d2d1670553c71ff0264ab861574dd03a103d954226d1b540f18fc47b3fc29\r\nMsg = 00\r\nMac = 217ac763\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 19\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d6983226b2c3a431abcceb77c8ec6b9bae80199115b28c5d7c56561e1b12944c\r\nMsg = 00\r\nMac = 26c717ce\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 20\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0cf53b4aae3e0a209e58385dd32d9cc6163265241332c332af4de4b99b4022fa\r\nMsg = 00\r\nMac = 1bfd19f6e1070186\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 21\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 5f988f38410d26d293ef32d74eaa81acca82545e767ab59dcc750a09849cebad\r\nMsg = 00\r\nMac = 7e52911c0d7987a2\r\nResult = P\r\n\r\nCount = 22\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = d8fd6e1dfcca8f656705aed7e356a576baf8907c8d10d54c833d62a8a6703624\r\nMsg = 00\r\nMac = 31b478b4b4adaae0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 23\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 49fd56dec210e903f6c703332637f9c267eab9333e2701a16c74ce5e0b5a16d9\r\nMsg = 00\r\nMac = c8be2b36c93684f3\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 24\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = fa282e1f3276a3e0c769f2ba25ce830591e860300cc03ab57abdb14c0374d060\r\nMsg = 00\r\nMac = 27b8111c3d9f14f1\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 25\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1c6942e914218135496e0d7910abe67b9f7f29bb09029bb37021865d7543c4f6\r\nMsg = 00\r\nMac = 466b7077bec98b7b\r\nResult = P\r\n\r\nCount = 26\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 08f199a8d7e3ea821dd3106e8947cd2e9d485342b25a64713db2b8a650a49ffd\r\nMsg = 00\r\nMac = 796deae0d06b1bf4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 27\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = febacddf3448c7464297ae53166793e2ed962de0d0947c5e5e17abe3cc103b07\r\nMsg = 00\r\nMac = 5e2d21aa3351a2a0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 28\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 59b9fb83b6a85f017bde6c0ff3ced955b9f343cc71b680c6b591302f52759412\r\nMsg = 00\r\nMac = 3e5428eca10808b6\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 29\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = f07e6655424125462a96390e02bfee9d89cb271bd9bbf22a9de45f6b7e949343\r\nMsg = 00\r\nMac = eed5aed01096226b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 30\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = a04f84bd79406c138d02698f003276d0449120bef4578d78fecabe8e070e1171\r\nMsg = 00\r\nMac = 18553226e5f9788a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1673a52494e9af02472c1777232aa3813c7c162593eca7112f34b3807009af5e\r\nMsg = 00\r\nMac = c5907fff58c68ee7\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1e4ffbed2d5a7bcda5e24a66048660629d57567f83307087a846db8246ff332a\r\nMsg = 00\r\nMac = 29599bc212927246\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 33\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 8b80c24ab4a3c24ced82ca8c69924553a37a139bfa2541c59e15188ab0fa5a34\r\nMsg = 00\r\nMac = 299746d93b0b4881\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 34\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = a00ebf59768f6437b48a91923f5effcf31c745b980f79f2edde9ed18dcf2ffa0\r\nMsg = 00\r\nMac = 61950ed83db6bf74\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 35\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 319d3f58fd7257901ff364fa68b86b1ba27c11962b2c5be8e33eb95548444322\r\nMsg = 00\r\nMac = 26793e8f8d5eb7c2\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 36\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 015a9d1f2df2c31f14cfbdc0bd68725fe8113a024f2a43312d963207fd6f0d88\r\nMsg = 00\r\nMac = b19fc2680b8b82b7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 37\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 003cff344c4e1932ac628440d819eaaafcc3ebe7c525cb7abb7a6716d2b76e05\r\nMsg = 00\r\nMac = 48a98dbf16257142\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 38\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1a581f36e1816d346f7bcc6df78316aa353111e447fee6f0bd05d562f30626ab\r\nMsg = 00\r\nMac = 587155c18ebbf8b8\r\nResult = P\r\n\r\nCount = 39\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = ebab54c4a22a16f7d9546bbf682b995a6ce944e949f1920eee058db95ab9c93f\r\nMsg = 00\r\nMac = 067927f063adfaac\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 40\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 58405ef8fb69e88221edc10a92c01cc44255aa7083096adb79bec3a8cec6d050\r\nMsg = b4aaf9ad1bde60a8d7e7cb16c1cf6b713df17d1507b028973068a95963a5ad5b\r\nMac = 42ffe65f\r\nResult = P\r\n\r\nCount = 41\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = ca0f404e3389e9527135f53eb58bca7726266b8086d33fb512e8143daad7633a\r\nMsg = 8f2a6b2185f73372ccaeaa7f93d30d1ca80a451ee0e46ccbbaf98c8f3f37aaf1\r\nMac = f2b311b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 42\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 67b896b88f07962e08471634ab7e522144d716a2969bde55a05c3c931f747a8d\r\nMsg = 0218eb619dbbde2e846218339aee4383792856496eb3b85cc43fa81446fedc5d\r\nMac = 69db1949\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 43\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 422994df8766f7a6a7ebfa2ca57ed6189d9e9e8455c8715c14f3f407b75dff4a\r\nMsg =", - " 12f0c45d06a138a964fb11b2d450620a2977bcd2952afe371cad6e3d48b009bc\r\nMac = fc5f1ccc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 44\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 3291be3aecd2e06cd2ee61a14d723450043d450567cbb0bf88ba32972d86dca3\r\nMsg = 343d5a4ad39acf81adcf24e9807618932abcb3bc076734f179174c77c8cb89e9\r\nMac = 3593d615\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 45\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a1885ce431cedbb60f7b3d96a06cbc60a964df156ea4b4191abc5a9f60a0c361\r\nMsg = eedd0d767a25b24ee25fe747718256af51d7b4bfe900adc069381a71a2dc7aad\r\nMac = c558f768\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 46\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 039188ec58fa55acde53c337fcfd0013f0c6efa55c60ce470112159bcaada11e\r\nMsg = 009f47f180e085776be6644aeac0070be64c289f84a7ba3dece7cdc54f0db354\r\nMac = 20d3639b\r\nResult = P\r\n\r\nCount = 47\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = f7d946f66e1cc4e5a79dfb5559cbea5a128545eac38e17ee7f3bac9a806faefa\r\nMsg = f250c49f9882f10db247adfdb2112c2589e1011f77c48e0f219dbf85e326f8a5\r\nMac = 90b4bfcb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 48\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a61f586ddbbe0219187f8f446d4b172f5e9bf855d1d5d6592ad8e03eb4d555d6\r\nMsg = 71c8eb0079559a306e236c49b7ce1b6cfe26c7888733eb7ec07690831a72c0c5\r\nMac = 78ce0135\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 49\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 7774802fd82fe96c05431acd40b49b1160d403c0db09b10f23d0bd0435022edc\r\nMsg = e75b6ca1b87e775b33536979422a1cf743f58c71b1599adb00050972c843cdf2\r\nMac = d885703e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 50\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = c4261ebb87a76aaa82a00392ee2e2318f0b52d5f2724e374847ad9ea5c8929c1\r\nMsg = a41bb1f256228302cd0548ae2148ff42774d18c2d6d3e38b36bc4938da13bac3\r\nMac = 857d8909\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 51\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 6219c19233c1b91d7785fde3b65df3bd2e1d74331ba62e4d365947a77cd243c4\r\nMsg = 68f17b9f57734784144112c79bf360ee324d37f9a7718137d954b15e796fa9db\r\nMac = 0e85de57\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 52\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 7e8cae1374d3a21bf2dd3786754668f17aa63dd5e3654cff9dd18041806d1968\r\nMsg = 2d335be62ecfed45183f5a04014c1a52afb7b918b9cc1f2be93b15c6e5240537\r\nMac = b56ee72c\r\nResult = P\r\n\r\nCount = 53\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = c2425ed20cd28fda67a2bcc0ab342a49d79d6b4eb196266cb0d116fc18895545\r\nMsg = b5f24c00cd15e377f444ae55e02b335379e7ae14e7c9bd05f0575d8981941553\r\nMac = 2e44c573\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 54\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 1f7871680bfa59a8a178604dc513b51a3d4c682cc4c421de594512e9dd062ad0\r\nMsg = fcb43224bf8989e1809d90481ba043328febaf4b6c1c05d18800ed98f4b71c52\r\nMac = bee03b92\r\nResult = F (1 - Message changed)\r\n\r\nCount = 55\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = d8a27558d070214d3f765cf969b2b8f09c0b14ebc492cb2539072b04db9f29fc\r\nMsg = fc69a1f0d0ba8eca9e7c0570cec9c76b511c74b2d8b65928444189675eb42fbc\r\nMac = fab3b2f6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 56\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 72354b455230b72a6dbfa5cf6c3726d7f8e65ca773f9d469e99d165743657b36\r\nMsg = aac60835c309d837aacc635931af95702a4784c214283ebbfb43c4e29973560b\r\nMac = 69519d9e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 57\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = ca92b095173076a40e24522297be27fd3a765c8d417f24c71a9f03b3fe3d8e20\r\nMsg = a96c4d5c89a364263c97a453308b9360bc0ed868602b9ff54fe13f162ad31ab2\r\nMac = c59a1a39\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 58\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = aa56f98e03f559eea02ad958e125f2312ff97bc3310079ce437b383f247a9b3f\r\nMsg = 01bf2aa8dc66ca44d16d4567f1adddd4461f78706ff15cf68ad937eb57aa62d5\r\nMac = 31171cfc\r\nResult = P\r\n\r\nCount = 59\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a0e317b790870e6703e6077dfb8ea327c12e29a17107284cb89d5effddb2d9a1\r\nMsg = eb4ea6b72dfc6657e835bf82054796183330c02a8db3c5b179abe37fd0a05675\r\nMac = 05d54199\r\nResult = F (1 - Message changed)\r\n\r\nCount = 60\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = e3de27949ff64066131c81bfee172b308f9bb0b31710678ec394837b79434605\r\nMsg = e41557341e8dae33568524f3f64b23426044c9db3526463ad16786af14f611b2\r\nMac = 975ad1d2fcff6a85\r\nResult = F (1 - Message changed)\r\n\r\nCount = 61\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 492dacdcb4a35fc438a6eaa35e26d2f683a1e85e92df28f213dfe1da6511161a\r\nMsg = 0515ad7b8576258645d37b7ac771745620e2e9e009cd778f34ed77a7dc5c30a6\r\nMac = 9f43dba2aad2f539\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 62\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = d71c50d55850d432cd8c8ff4ea427b3f19cbe14c785a7704202fcbcead0de5a5\r\nMsg = 7ffbc4a09583029cbb0acb6b13f08a189033da22c2ecf921f01d79ac68a9397b\r\nMac = 5d00ffc5f8cf1ddd\r\nResult = P\r\n\r\nCount = 63\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 557eb2e709d58915a8bada6433f2e5660247e0cb1588ea84a9d24028090eb396\r\nMsg = 003132645e3026f6a2b9d0644c16e5e4d1bf8b53a51f0e1b999bd45a67d19341\r\nMac = 6f3d9f50d09476ef\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 351d779277148ab4474843cc798942cacbe863eb1c1c9338dc25e251c12fda68\r\nMsg = 34bcdd3d0469c01d0d95a85ca705d887385bfde20596a90b47d902db826dbc8d\r\nMac = 79ded259f93456bc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = e1c17ce3d3c61468a7652a95128bc0f6c33d9ccc46e7490327f15f645a94040c\r\nMsg = 97829c60ca9a71c23eaf1c4b4fbd72043037ef0cd356b68e0db0d4f0f50cc54d\r\nMac = a93f0d16499f63ec\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = a9a86a4407b7ecebc89434baa65ef173e88bd2dad9899b717ca578867c2d916f\r\nMsg = 25a152850b4b80b19d8f0b504b2a8a241824b3a1fca8d85c8713b2c0c84b5e02\r\nMac = fe84ce3defe00f67\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 67\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = ed14373671cd8041e00874b5d098ea225eaf9c68bb51cecbe8083149bdda062a\r\nMsg = 38106cdc72b1ddd0fe11f23819096dd7479e95ee9730940c28f51e28eca653ed\r\nMac = 470404ed731640a7\r\nResult = P\r\n\r\nCount = 68\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 009f47f180e085776be6644aeac0070be64c289f84a7ba3dece7cdc54f0db354\r\nMsg = 2eced43c084a86f89f61e7237425137c167aac29e4cac4071afafd3f0c9dee1a\r\nMac = f67d432e5b6fc5e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 69\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = f250c49f9882f10db247adfdb2112c2589e1011f77c48e0f219dbf85e326f8a5\r\nMsg = ce61d6d8de1b299c9b063d1e1cb1faf7a616faa7c6673d7f9c0a1ebe7ae285fa\r\nMac = e1d950593abc14e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 70\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 001150b2dd572288b6fde466ec2c2a64c75a9d516b7096f7082bec9f52c20ad8\r\nMsg = 6dc38e37d1379732df4dd535db88d17aa59d7cf9e8d60ae695b4047b90d899f7\r\nMac = 2de6700fc1562ad3\r\nResult = P\r\n\r\nCount = 71\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 68e00d394855b6697da8213a120dc2213b3a8a1e88c9b93f5edef465a809974a\r\nMsg = d21aed2073e8ae9c0560f9dc1adb961d4f959fa12c0384a44c675192bea13477\r\nMac = 9594f10d5ce5e616\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 72\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = be0f6052baf658a3607d999b81401edf7e2afac2b143e1b908c8ea0ff38193d9\r\nMsg = e502f0b4710bfe517e783c4bbb85055c8471b04e12dd6776f276367fb5d36369\r\nMac = d409a879dccca77d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 73\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 7147b3c5ffb2660c45cd8d78a6fd44bdd5ba75349642b32ec88f6688a287297f\r\nMsg = cebe84df789c98dd125bf43cd993e2f089611b98d10be04904e2468d116dd2ab\r\nMac = 21cfc1e6c1c38df8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 74\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 205e751926038ef940c6599d84a9e1b4737bc826e9fcde544d43f2a10b5de931\r\nMsg = 86ffd5bd3bd1cae10706a61d247b2257b165f37cb53ff21761077a2295a9111b\r\nMac = 73d66ea826b84fc0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 75\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 8c8a502eafcfbb813dd1ea907b1660a41fcaa3f905aa93c22320f96ebfaf632a\r\nMsg = 626aed82974ef29a1ba0a6c6fefcbf34ca982e6214835183502f6a24ea2e500f\r\nMac = ca3d007ecd99be83\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 76\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 596db502a357e102566291b916b32b8a09e99d3739f5e6543a2cd8fb0c9a1cc2\r\nMsg = 22bade59214fa4b933cb5e3dc5f096e239af4c2f44f582b095c7fea6b8914bfd\r\nMac = ff4ec21d89d4762c\r\nResult = P\r\n\r\nCount = 77\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = f51f2fb4b3fd8045b70d34b600a2697cbf7503be0d8cfb5cdc60f9312e3e269", - "5\r\nMsg = 4d43702be4f0530319555d7f1a3356160f6cae48051f12e22a153d7e405c1149\r\nMac = 3d615ee77043d8b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 80a4b14f951490618ce53d39abd3d786b425d4f76b26a25052d98ebdb7e9e666\r\nMsg = 0b2a77b0175ffafee40cf83bd19e785dc7ec4319786c49b3e7a741142aea901d\r\nMac = aedcaa2e26d2f5a7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 79\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 39fb57fadff7cd9e1cfdba154422b71d693d08807d86da46ba63c929417ea549\r\nMsg = 567c7400f190d06e682b3dac5f751639a9007362b1a2a8b618800fbb9f6c08df\r\nMac = e29461fe8c6b3767\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 80\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 535ed61510eb268100be032b7a258e84bdb32448269d3000a76444ca74b4695c\r\nMsg = f7f28df82f910badc5f4b3860af28cbb6a1c7af3fafa6dae5398d8e0a14165def78be77ee6948f7a4d8a64167271ed0352203082368de1cd874bd3b2e351b281\r\nMac = 4a0fd541\r\nResult = F (1 - Message changed)\r\n\r\nCount = 81\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 713fd349c56d1086794eb20ed59ddc89b065bb8533b968c6dfa60bddd16646fd\r\nMsg = 4f3b91aeaaabfc7d4dd6821549d4eee2ea17f59aa196c67b422be2d46f3a2ec65494464c969b157985a6a30199a72dfb1c0b7be524e16ee9c43fd95e83e19192\r\nMac = bd4eab1e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 82\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 1f89d9ee93294aeaf3503d15a6dbef48708de48897a72b3545b9e3852eb7fe31\r\nMsg = ea0608b19f47676f0f342cc2742e003a6a74fa2850f41e0cf162235163887a3830dd8b13b45842b3c686ca239bdb9897e646ac9f440713a0d8c5b18532db3db2\r\nMac = 8bddd404\r\nResult = P\r\n\r\nCount = 83\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 2b50dbe8a5ed0c7cb69aa60a38d10cfa4553c73d58c0ce84b26504b0fd55038a\r\nMsg = 2586563b0102f662b5a8f9bfb0c1d107a4c27569d27bc066889213e3e830427ceafaae1ca543aecaca7f34c671fbadd518cc28d9e806bba43b2e220e5cf1aa45\r\nMac = 987514d4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 84\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 29a7ed3aa55c7eb7e5bf343ca0efbf8b2062ce67b086255551a8efa0ae16569f\r\nMsg = 2e6f2d21aa133a5061622f08ac64c6b3a3dc8154862033055c27c3a3d9e42dc885d2c9f91bd1d0212f301c3e140b2f5bfdd777be623bd162a6214ba8f60e2e49\r\nMac = 1bf45457\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 85\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982\r\nMsg = 65916ae3d88ab2add5c0c6910ea993d385cbd35c5077ea0d9db30e53f378abfcbb1e0649fe14204470d4dd53ae16650ec444cb4ef22fed86b0009b57ef71fb5e\r\nMac = 578f80b2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 86\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 47e49e5b57fbb834932fa32107697471119f1be3c3a6e71a8c474d4b1596e539\r\nMsg = b3cec7ad75e2bf6c87029a67365aa83cf797ae2f4d42e720ed4c48ba21ea08ee6aa3609f69a6909fff6222dbb45172d255146e4ce1c59b48a7895936a8646766\r\nMac = e6e64597\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 87\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f0b0aaacc25a791c236aed0e9b537fad00a15efa9c89b5068ac52c64639fb1de\r\nMsg = 9a5a9560baed3b8e0e90b92655d4e5f33889e5d7253d9f6c5aff71ea4069224cfbdd19ae3f0ecdfa65c27dc3bed721712784a09fdde243c193ab6a0ac2417e8d\r\nMac = 990bb31e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 88\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 14db1ffc1c87117fc72981706c0f90404acc98aabe950839baeb6f0b727bd6d4\r\nMsg = 3d736aeca5720f5c7bbb16df61f6d785facfa070aaa89c2d9e8af9450d62490ebd6a29c7c8e521e4a00fcca7515439f006c09056cfb7f976a1e6b98b9f799e40\r\nMac = a6786e52\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 89\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = c6f0a3692c9280c48393b0dd763e5d0b90477f34ad69f192ae4dcab771aeeacf\r\nMsg = 8439ff717e1e15161119494d368d7f3812601588265bbefbc6d48e22cc8a51688dd021500cee38fe6ec402f9aeb0762f92b2a73adece96e1c7b24be2aa9924ef\r\nMac = 70126cfa\r\nResult = P\r\n\r\nCount = 90\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 75225a26d63e91281fb37ace46354f81de99dedfde8b770ea47f08503aea87d8\r\nMsg = d729d8cd1631aacfe485b1f408a4fb60256e7a8ed6e5b53afc34be7e57f1643b549fa9ba2677779318688ece225cc149babd6259ec37fbb4adc03e8f6dd63f03\r\nMac = 5112f762\r\nResult = P\r\n\r\nCount = 91\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = ab72eef2aba30205c986e2052d6e2c67881d24ae5fceaa8fa77969539152527e\r\nMsg = 5251a0aadbc92b76705eb053d09b25b5ad38eebabfe1980d143ac90aa81f7723353059824c8d9befa5ded6f5b4973f407c7a1f4aa85d8337d82d34fd3933e9c7\r\nMac = 52f7a014\r\nResult = F (1 - Message changed)\r\n\r\nCount = 92\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 6906d6533fbc33f56e38e6a639798005daa228ebd2fc8f93803d26fef30b8e95\r\nMsg = 6341370e126097f9721a13c977eb4875cf1286e15c3adfa4e7597e0e13d93b6a8ff66c809067fd5e7f40c358ee170d4ed1657c2deb3015b886e79589678e0452\r\nMac = 1b6a021e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 93\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = cd9072aeffebbdfcce95b569c34158d0e130ef24dc99e3f98a4dd246949be269\r\nMsg = f882339f93ff114bfead78044aab1c7fe109dbf1bb2d968ad476403fdd2034cd3168ccfb0cf02f1ff7646ae3875ec349478749edf300b08be7005cc0d6bebc15\r\nMac = d16bcdc7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 94\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 3005c0100dff59e5e4b0e3b95abbbc79749dc49ba29a79b1fcf7613ecb6aa9c8\r\nMsg = 4c2c670f3ac1c4e33a8d43063c8983e20f1ce6a73299fef1e70a42a5882c061b1ebaaa8330ee1181d946541b1d84b8d57df8de1ac9013ade36d2c682b172f8f8\r\nMac = e5689100\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 95\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f32eefb301356fb1cad6dfa94864542b5f8cd8e98438bdbfbbb431f0c10f12b3\r\nMsg = dae6db62842a8a25123e50041b701ad17e2f63a0496443c3d905a9f943e6e4e2f3d369b693ddd0372ff11fe496af4b700378fc72fcc9915e7bc864b44c1d4f77\r\nMac = 280624c3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 96\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = b0212ca369c611b725eccc3daa58df412787a3475f418d820971af46773382c0\r\nMsg = 13ca022396285bf7b82a600b560208c54ee14f8496bce684895029027e6451a09f4eeb0af9b889dacfa4b7b934ae30c7d991523e23edd0528048a75bfc525335\r\nMac = 8e9759db\r\nResult = F (1 - Message changed)\r\n\r\nCount = 97\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 57a9d1ea216c69c6e360221f8c858a9d356598a8b253e2cf67f1116b5df5927f\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d381082f379b2cae385dd526b189cc10cdebbd33bf3d8db2b449ed49064d30d4b3a359110d\r\nMac = 41022947\r\nResult = P\r\n\r\nCount = 98\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 749f2fb720d321757473afc5d3a377a0eaacb425e5591026e3a1bae6a785b921\r\nMsg = 2e4f5149d67c955c409b63b04d95538808da6202e69a50ed4d3846da52fcbc76c7089a17758d9d94a63efd5ae7054dbc0bf5a28b7381f7e78debd0549bff1e11\r\nMac = 67b34b0a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 99\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f8ebad761b9e73c77faae3fd9390093fef595e77e6d7f6b35e2dfccbde925c44\r\nMsg = 18430f34d5b5fddbd228a910cab9c48e1ba2b5f57819eacbde756cc0c993b736a778c8008d37776a2915077af8ecfc76b8cd2ca621e9195bd0b27e31843d2890\r\nMac = 7a446398\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 100\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5bb9fb83b6a85f017bde6c0ff3ced955b9f343cc71b680c6b591302f52759412\r\nMsg = ee7e6655424125462a96390e02bfee9d89cb271bd9bbf22a9de45f6b7e949343def818dfc93d777528f609cd38be0a013b1eef816eb1f9593a850bb7aec5b9a7\r\nMac = 5e1fa5b9c9dcd90e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 101\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 57a9d1ea216c69c6e360221f8c858a9d356598a8b253e2cf67f1116b5df5927f\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d381082f379b2cae385dd526b189cc10cdebbd33bf3d8db2b449ed49064d30d4b3a359110d\r\nMac = 430229471a1cf1b5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 102\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 749f2fb720d321757473afc5d3a377a0eaacb425e5591026e3a1bae6a785b921\r\nMsg = 304f5149d67c955c409b63b04d95538808da6202e69a50ed4d3846da52fcbc76c7089a17758d9d94a63efd5ae7054dbc0bf5a28b7381f7e78debd0549bff1e11\r\nMac = 65b34b0ace2fc6bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 103\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f8ebad761b9e73c77faae3fd9390093fef595e77e6d7f6b35e2dfccbde925c44\r\nMsg = 18430f34d5b5fddbd228a910cab9c48e1ba2b5f57819eacbde756cc0c993b736a778c8008d37776a2915077af8ecfc76b8cd2ca621e9195bd0b27e31843d2890\r\nMac = 7a446398a5c59ec6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 104\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445\r\nMsg = c66d322247ebf272e6a353f9940b00847cf78e27f2bc0c81a696db411e47c0e9630137d3fa860a71158e23d80b699e8006e52345fb7273b2e084407f19394258\r\nMac = 129", - "e40ed97c02ff9\r\nResult = P\r\n\r\nCount = 105\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 8ea05a5033ab8b009664fa2800c24e217488ce6888cad14774ad75b2696e9470\r\nMsg = b3f09d990c2f41c8707368bba007803621ecd76540cdb8705435d74f4300eee04710a936f241c034709e625b0dd5dae1f6e86d034426819c365a05f5be420cdf\r\nMac = 08e5d5b3facd3b01\r\nResult = P\r\n\r\nCount = 106\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 016b5537198ed152670c5fcfb70ade276de97ce0cb771c5f6f66fcfe1dfd945e\r\nMsg = 7ad591e67c6a3ce3c9f871e328fc4ce3b6e7048e80691da551efdfa4c96b06a3af53bb7a88ecc32869c8f776098df4d71af91393da239c24e50436e04d35a2d9\r\nMac = 36df9931a14dca9b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 107\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22d5d4c3a3aa8d2fd5f25c08b83cea60e94058e8235ddd050646b02617f82854\r\nMsg = e86dd3216500273d0b6150227cf03adc20c8a5fed4a2799fdff759a327657a3ca554b6af16d9dc5cf3db4bf9a474bf1ef1996a06b9fe4794e634ab94a0141d44\r\nMac = f0246b4959d2fa89\r\nResult = F (1 - Message changed)\r\n\r\nCount = 108\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = c892b095173076a40e24522297be27fd3a765c8d417f24c71a9f03b3fe3d8e20\r\nMsg = a96c4d5c89a364263c97a453308b9360bc0ed868602b9ff54fe13f162ad31ab20f3fc51bd2346ae68a006afb50e846e8431dbf7bd0eb3c8f30326d26311a2eb8\r\nMac = 1d943a8b0c470221\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 109\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 2c87c0d64806fe303c5e97bccf48360f89374b6119319bfaf8defbe74adf58f1\r\nMsg = 37c6206e23163c39a13f19de48cc25dc26e6f83cb376e8d2048ad7c141fa503d594bd395f4d36c70aa1e8a5672910f735d4da49884574f833ef54760975b0790\r\nMac = 58cb614230d590f4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 110\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 028600eebf6b3eb04d8fac18399965aa8fb5f3954d3a657e188ba17f2e3bfc70\r\nMsg = 5b80d1cf745b14cb71cbc8dfe0bc7c7358f721c00099b3e250c41c2e1c9455c5ce55ce69f3f31090f9b1a1b7361e27f92d46d1e00d25f37b7b61f0b191385dd4\r\nMac = 02587102e6450de1\r\nResult = P\r\n\r\nCount = 111\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = ea1a626b623e9440e3f6f5c0b8b63b9967374ee82c1957fca5cd195ccfb2840b\r\nMsg = d082b2aad7058c3142021457d47d51d8ebaab62ab452f6039e771a1b0f3bd03355fe0656dfc7b75fade505bb05d689706867e75ec41da5c5ebd43d0844a670b1\r\nMac = c874df0a8aa87c5f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 112\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = d1155265fe296f374366dbd11f14466df1ea210cc88b0d1876509347e64815c2\r\nMsg = 3e3d3a464b2e6030be877f8db4c1c42bd2b8247adcf792ee833675a57f21594ade5be4399cc30ce373f68874f41584b4d7c8992b9082fc892307f645382c9483\r\nMac = 6bfdc96378f0c8f2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 113\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 9bcf914f787fd3cf62c6315a12feee358eaacf1f63ac802932b933c86b098a29\r\nMsg = 02c8b892b13f04d99b875b8aaa32136d19dd6b9c2a10d8871c66993a57ee91e3ebd0568e38348634ee5f5af4391f7da0356a1e7ba8424441f0db61683a002ba6\r\nMac = 365da451a2787193\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 35d5df6d714e2ba5b307c4d1908e108bc6fece682a23aa35e2de0e80d4cb3c5b\r\nMsg = 963ef1899cff6e0a6dcd80a27b63c20fdb8e9fa1ee3e14ed40ddb7c6b0dff969d29ba8f89159b82a19ac4240f402cd3b7279cd4c4ff4698c906f81edae8ff070\r\nMac = 33995a3d9c470cf4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 115\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 511ab5e28b6fda481fa5a0fb3709b249fbf29be56346378a4d3f67e1cd6f09a5\r\nMsg = e4cbbf14f27490843b0f9a17b4520d4bb2c89726f4c788cae4a3344a1a2198bc222e41907fd16a20ef5f6587f1ee3cb7850b97c633b0e0894e70a6647af53f60\r\nMac = 3b4aacb52525b58b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 116\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5e79f14d5f687ce62b82f856695af9f7dd350543ec763de75b593f1859e44c2a\r\nMsg = c0dfcb62fbc3a67ceb792b3428d040ed5e50999296702472b709a44f4c0b9bb1876f6e80866cc4d2d6ee2f0236440e029d18b2f27ea5bff14a24d53337877053\r\nMac = af30acca71feba3c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 117\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = cf8a477434cc679e52dc3f3f3520eb108239dad5bb363034bf0768c790343e70\r\nMsg = b891b1ab5a6919e0b99013e40fa7c910e55a480bd043d3d85b0b7d1342d3f777e1d2a6a4eb3ff81f5f71f99bb845217765c0708778f5be17a2294c2d5f369e0f\r\nMac = dc10e268f5f73bbc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 118\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 67d77f50727c7cd5b38e0b175a888c88687c97f2ccaa3daecc519116a7c5683c\r\nMsg = 02c5c55e7677c84a199d6e534772123c4e5c933622cfa8ef536e74cb3d745b717f53138aae9bfec54a1cb71ff04feb61d2f26aea65f37dae598f7b7fcebb978c\r\nMac = 885050ec166faef6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 119\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0091d39f3478d2c59bf874b96db9ce0f7e8b85a9b805e07dc96b219819d51663\r\nMsg = 7207aa8fa87283f1f57019bf1c89645ff8fc36ab1102704e6d577671a9f7e098482573c64ab24fe8007c697020353c411566bccb98b38c7784607045e61405b3\r\nMac = 96f639a86a2d698e\r\nResult = P\r\n\r\nCount = 120\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 0e6d99ee5137c8f6b9bb45a961be8a29358a91189cf9974f5bcf20d3b64c3b04\r\nMsg = 543ef4638f1322131402172d193bd304b34e3745ecedb9db16f35c0f5fa6\r\nMac = 33f10660\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 121\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 82421ddaaa5767a496f2b78f816cd1e1e6699f6e9e6576c34c909ba5f8dc06ba\r\nMsg = 4e2f0f91990b855a00d27fbb2e8db7184cd82909de361b52e7a75b16547d\r\nMac = 3f5ed151\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 122\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 134f20cb62084a98601f0e69d257fd2064beb47248caa79720a71d461ed07ce0\r\nMsg = c248fa87a6e48cdfafd1e5ac00f95fb1dfda861465747265796654dcff54\r\nMac = e7b21645\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 98505229c1927d13001b53850d0b7d56f49087afc6c2351190cc1b998e4d6883\r\nMsg = 9bee2e347f763c5c506876bb514b5ba1248abc6b3d17cd4c96537d4ea432\r\nMac = 2c212c7d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 124\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = cad710b48ea0bce4a897482a535aeeaeabebb42619578a9d1296927301b3bfa6\r\nMsg = c1db23e776272765a0fee49edcce28ff7702b9ff9b6e31a4c3ed0c497248\r\nMac = 7f27420d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 0bbf4f77a9883733590a3cc7ee97f3c9b70f4db255620e88cd5080badc73684c\r\nMsg = 7ff9ca86f820e4d57995d450611009ffaa726e6fbe4ce1558ca1e775daed\r\nMac = b2e5a268\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 126\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 6efabed650ce05ff22b67768e3bcc88c7746952106ecea92a38707af2b8a64a4\r\nMsg = 9cbce402511b890c8c9fa215b59c813b3e51b5dce01e776327f145623002\r\nMac = 03728e46\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 127\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = ca2843847a1c9539917206d344161dc40b379fd45dfa6a73ba6fa14defc40920\r\nMsg = d9365304c4363fba73feaa69d4cbb343a76eb2d29de6782ebb34d873006b\r\nMac = a94841ee\r\nResult = F (1 - Message changed)\r\n\r\nCount = 128\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = e5a1108da9cf587bcbdf051e216231bc27f0e6c1e97729b324d23768a89e0e77\r\nMsg = 536d4b6182a698d456e1fd9d522aab38cf05656f41a5e02cbd5e6f8cb85d\r\nMac = f52a4ba3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 008ee06bf9b19536190e87820af9cdddb40aac44b0c3b1e50074fc29fe5cdff2\r\nMsg = c1eb4c800c631d9f387d2e8e431677b7fc8f65235ad0cf9b118d2b0d67c8\r\nMac = ba255bd7\r\nResult = P\r\n\r\nCount = 130\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = ba0bfda3b03c736c121cf9a257db55060b621be5168619ec4182f13ef6a408c4\r\nMsg = 69be384eb107340d953753e6a860ea2710e662e8953de8eff8f465d086f3\r\nMac = 9f650d24\r\nResult = P\r\n\r\nCount = 131\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 7a88524accb59f1c6307a1719a011eff211df24645086c67710ef539f5d3f29a\r\nMsg = bebe346356681f27bc62f0b838a25268e3b04194b865bf83eef2c8928625\r\nMac = b2566e6a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 132\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 9c956d7bbe2028739d73a2f0a80af5f2f180de923d5571e65bee0b25b5dd890b\r\nMsg = e0d2ea49e3e4a5823efd1b229c705ec3bb5048a7658f10fba2671c5d2cf9\r\nMac = 480a14ab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 133\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 2090b970a71ce2cf399a0d9e1d3d72c4eb500004abcba1303b24bf9af16707cc\r\nMsg = 0e0ef2cd18533bee01f19870f2fb22176c7e04748db4dcb98f7a65cc9104\r\nMac = ddb6f30c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 134\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 66921951731e95bbd45c014af5cf623933350dd9a90d1a36465716f8239bf887\r\nMsg = 0de1e090eb47dd4fca966e5f8fa5616618701164370d8a43fae2eeaf3016\r\nMac = b91b3131\r\nResult = F (1 - Message cha", - "nged)\r\n\r\nCount = 135\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 43c1142877d9f450e12d7b6db47a85baca7eea7fde595393fb394c1f34369aa4\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d38108\r\nMac = b2de16cc\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 136\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = db4b6206d001af121051cec70195055fc1fd0dc06ccc74549bc440152aded5e7\r\nMsg = 94394feda0528fcc67124dd1d77f0ec0b911f08c3e01e0c0dbc40c1d57d2\r\nMac = 5f72de94\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 4d658be9cfcdb19f79abc78f4d7f986d02b43a03098b37c8ca56ebb331e62d51\r\nMsg = e28660f57b044a44a19ca40ff7b6469a41523e8d1cef22f4edaba58917ab\r\nMac = 11fa4d1e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 70b4cf3883fea8c6cd852a4293c7e5cb0586a6cd71294883b760cdbbfd07aeda\r\nMsg = 4cb9aa069475e54b25e5688a52dd4acd134169c858105f01a0a1b134c72d\r\nMac = b6b60815\r\nResult = F (1 - Message changed)\r\n\r\nCount = 139\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = f75bb63d52c35137448c58383afe47e026d536f67e3afdff87f29b10d3d6d9e0\r\nMsg = 4259e4fdf10acd8da40accd6354f4baef4859a2f5ebada0d2c5b1b26905f\r\nMac = 336ee1e8\r\nResult = P\r\n\r\nCount = 140\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = c938f6bcdeca02939fef931c969a25edcc3daf338d8286016e3c7ee78f9d52c7\r\nMsg = 47179ddaa9d7ef6b9a53c646325c80db69128c6fc4f92ccd345078383b9e\r\nMac = 5cbd65df0ca36898\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 141\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9540e4bdd8c7ab99f0b76dd9de24c340a60f7706f680448509d5dc35cb5930da\r\nMsg = 4715a9a66d10b2dc1869d90fcf9b7fa99e91b40abcb8fc356b5853c92024\r\nMac = dcbd4dae7cc60d46\r\nResult = P\r\n\r\nCount = 142\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = d5c396fc1ee960215e57cfeeea1e792fab9334f2c45dd93e74cc47023e6daa4c\r\nMsg = ce188965b4d347a6c36a6fa5a47296b32ff0fa27311266b16b1d56ebdda7\r\nMac = 1684fadaea17bc79\r\nResult = F (1 - Message changed)\r\n\r\nCount = 143\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 897193cbbccbead9957876b8b42a77b404aed32a3f63bb9ab5f08cfe4936f35a\r\nMsg = 87767f13bb4904d0df0d64eb22c9ddb65e81b5739baad86ad5e2c239ffde\r\nMac = 84ef6f59b770d42a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 144\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 86aa015253a7114e1770b6a48fdb3ef22e9d5abac25fdc145315c09f4e8b69bd\r\nMsg = 2595cb8d4d6aaa148596e8502ec80a030d82195f9e1d9a26ab0ec0101e67\r\nMac = 63e67c44ecc05dab\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 145\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = a082c12e97bddeb0c74c13aa4ba788f8a127c44fbac6682050271dbf7ad6cbc4\r\nMsg = 7fc97a698d7b0eed7d7602a5d13e956a538c71c4b45978a47439c05601ea\r\nMac = 3e1fe077fc7e903b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 146\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 18716638a2f6b4fb8dd2849fa9aab80b8dc846ee7e6b3cb0926101a814d8dd8f\r\nMsg = 6593194b9970545c5a910b2b4fcd46f0ddc7aa0bf873f0a339d5958d310c\r\nMac = c4556a75b754f6c9\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 147\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 6237aa30f1e3df239c96e7e50b69496da9305951024fb83a6fd01e96f6b2578c\r\nMsg = 0c5b7d1ba68654cd24871964f1b31ef7900dabc025baa02d37b55b35b4c4\r\nMac = 22c74fc64489ca5e\r\nResult = P\r\n\r\nCount = 148\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 32f60011bec76a79d2e837c611fad1cad486ee6f2aeeb74f1ea32a7e3899bdaa\r\nMsg = cf772bac3e767534b13efd381119b66f8a99b91aa52c8d3ab5f0a60073c9\r\nMac = 08d02ce41d4964b9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 149\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = cb6cee5ba7b799f16254a17b1870cdb85fe0ef3f42110c138742bd7734f0d504\r\nMsg = 40d3c65a00d9204b76e013975ffd729b351698105d47448da285a84de281\r\nMac = 4cc6718396dbe247\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 150\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9b8cdf91e848eeded2598ccdf084bf591ec2eb668236f555ca61a9d6b49959fd\r\nMsg = 7b3cc6f18a27047f4cdc35404e44eb8e51b1855d4bcd54ccafd1fcfaeef7\r\nMac = faf72c383b56a4ef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 151\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = e6fdbe9a1efe081bbcfeb25b844734fe60aa6b80a5b5f611982de1a331b88041\r\nMsg = 59a0f85349c3f378d56c509a0a45a1512b5072474b297f9c1a8c24890016\r\nMac = 020354f33df66723\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 152\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = da360852e8b8c3a1b65af9e8630ee5481aa91dce414166f8f3dacb75b142f12d\r\nMsg = 61d908e9663fb195afc259529fc229b14e87995f8d3591b125fcce816090\r\nMac = f8963157ef7c1ba3\r\nResult = P\r\n\r\nCount = 153\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = c9bf0e7e470d0ffc88593796c4cf9a61c6db81d343305ee06a0f0563bcc618c0\r\nMsg = 19378e17c41586b88523a6b6af738dc47e63ea64b4b83fa283f1e502add5\r\nMac = 550523c0347fbcf1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 154\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 7129ca274190400720bba27651f1ee0d5aa79116af9929418e198f9928a715b7\r\nMsg = 891e73a81d7574ce6f73e09e08cbaa0b9db242963f4469cdd2234512c061\r\nMac = 9982a14d261a4060\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 155\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = dfaa73c82a978548c99c0f1c34e1edc2c4edd42b73613511e4e6648ba364f9df\r\nMsg = 18044ac51ea97341061ae7d5bce017fd5cfb1554a384a75aa3919a74ba59\r\nMac = fd3a17e8c51a004f\r\nResult = P\r\n\r\nCount = 156\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 6f0be1905d1b5b607574ad93a1e7b4a536020fc6798acae862253916a0562707\r\nMsg = 8e502d5af4701025787e5b251121676182a0b26cdf52847f4d56d2ca0983\r\nMac = 73d76950066c77d0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 157\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = b9fe826b0138de8184a3002d8bb59d228862e4a14f8556f88282d8494d29068c\r\nMsg = c97ca1930b65064b70d12fc46af4d5e220e6009e729a28a13b0f9a11d3ca\r\nMac = b8bccd70bb90084f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 158\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 99c8f69fb91b17299461fd8d633bd516dcdb172760695ec476a5775377cdb7a4\r\nMsg = ef589e3b4ad9a7ba390574a2db5330baea64894f8f881cd67b842dd23393\r\nMac = 38e11613e67e0416\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 159\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = a86e8b43a1e81dce7b26420c0409628d145445d1c512e1c3df3270839475c668\r\nMsg = c71a0d1e20a7dc8e7adea91a408ecf3d512bcb15a6d8fc1435c6a7f915bd\r\nMac = 101c06c22819404a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 160\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = c5a850167a5bfdf56636ce9e56e2952855504e35cc4f5d24ee5e168853be82d8\r\nMsg = d4794f6f563d5f6445450b59c1ff95d24eadc9c02b68eaa5df64edf81475e5cba8d2bfab021a2fc8\r\nMac = bf99dc0b\r\nResult = P\r\n\r\nCount = 161\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 551e188cbb7c7d1ff33b4bd5bb6c60da184b18f44d68d5c30704df47d8be6fa2\r\nMsg = 2b421be47d07dcb12a0706f7490d05024fce8f433079e18ec78f4c8678f5f1551448c9a0fc70e8b9\r\nMac = 32aeb3d7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 162\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 000da8307f0e6112f0b8a8b1f927f62e8a9e5aefc0d37995088dd32e867148ac\r\nMsg = b89266f3a33e5b6883206e44f8e8e0cb01275039c304960e8630f0aa011c5c19d769443061a060d9\r\nMac = 1b5e30f0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 163\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = f4ae2113ce96435b27369fd4571ae2841a965c8ddbfe61023219eff9abd490e2\r\nMsg = 433ea4e1923267fe443e1e89d2472834b72ef97323ad6d82f3825ca9e1d06fbff8c232ed4c716ab4\r\nMac = 05b3c894\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = e7c78ef4c4b959ee00cb1a09d71221a43892ef8ad705edd27ed85d03a377907c\r\nMsg = 4da25d1e7064bc4b4903a77452952885a06ba0712544210d30c0182533182fcac90b71e9f71caf22\r\nMac = c15acf48\r\nResult = F (1 - Message changed)\r\n\r\nCount = 165\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 6f48b3bf240525adcb02985900fa29747e4b1265e5a8899abb0ee51cb0f90367\r\nMsg = 98bf67b6e342dd94c948e76aabb69e7d091d24fba54ae233e4181404768988963915a2495b42a4eb\r\nMac = 71bb5873\r\nResult = F (1 - Message changed)\r\n\r\nCount = 166\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = cb6cee5ba7b799f16254a17b1870cdb85fe0ef3f42110c138742bd7734f0d504\r\nMsg = 40d3c65a00d9204b76e013975ffd729b351698105d47448da285a84de281bc3307cfd80b39488213\r\nMac = 592e54d4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 167\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = bbab624862e268765e9e6a13df55cf7a2267520e4e66042ba0b4905dc554c3d0\r\nMsg = d43b841f174335f1347834590b0984a2cb35f7a00a0ee993157d2d4f8487489a12ceddd6ac5b69e0\r\nMac = 3480805a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 168\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 2fc9e8f409cc6c0156ccf9f00686ac7abba6cbe08982a737fa08c7035", - "6f54208\r\nMsg = c1cd63e24e41f69a146b448cee0a2107817c8105732745aed817541eede8ee6809e73ddbd0742d84\r\nMac = 91623558\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 169\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = c49dc812061fa4995aa7c160ed7cdf769dd1ef570d8fc9c7f8552101c5bdb711\r\nMsg = 74ec6f53d188be3bdb647f37619fa5848076c66d21bac164c381a4517b1dcd2a384a4fc44cab97e9\r\nMac = 07471b07\r\nResult = P\r\n\r\nCount = 170\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 84b6cd1c6618c42ba74e746075dc28700333578131ca6fde6971d2f0c6e31e6a\r\nMsg = dc79743d2360cc52cee202b9bde9abc7c09d9d0311d89c3722da36c7993feb42992e913744d2f74a\r\nMac = 3acba1e8\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 171\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = dd472b0bf50519020a182f122239d161d9659773b4df454eb378fedc250eb490\r\nMsg = bdf56403d5ff8df4ffca92eb40d54a79b5595abcd67b9e2ffcc5cbc621d7523be75a87a2dc360244\r\nMac = 3bb0894f\r\nResult = P\r\n\r\nCount = 172\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 00ebd245e8c0e0b60847da5c8f7a1f33604932b9cd47a845a1a44599645b62ba\r\nMsg = a238e542f1c22621aebbe331e71123ed7f2591e4192180ae378c2c24a31c42d10fcba3a3f82c65e6\r\nMac = 1d17d6ab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 173\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 2ecddb226ae668315eecf107c344926330b94077e029ac3bb67e6a077ee05361\r\nMsg = 38ee97f0dc635c7416a024e3af5c95dd1d496db8a5a5c3bcc20b9093ca906dfbcf0b9ebec3b450e4\r\nMac = 08834104\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 174\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 0a2978b5f20d3b5e5ed7ed5a78a093a51d5aa6e728077346f429c27f1c79b635\r\nMsg = 28313dfdc449628f4e2d6c895381844559067823cebb56cd41493ac0d29d6408e7d78d4a21637b08\r\nMac = b2635d7b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 175\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 7f2286d42b4f9eefed1087f3eb3dc814145be4a110c0e74176f83e7d4068cb7e\r\nMsg = 6c1aa088d1a6086d0e72636744a6840c80ab8223409c61b733f7ef6a4199ed0ccbe96f6c3453866e\r\nMac = 10bf9789\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 176\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = bb0fabffbcc6935ca35755fd4bfbd192b6812cf75c4dc95bc3a175a1501be206\r\nMsg = 9801da81a6d9861f26900401aeaec89a74e3d5aec0a5d612a11b6bb4e03ac1db322e65afb1fb5afb\r\nMac = 9ad23631\r\nResult = P\r\n\r\nCount = 177\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = ed1d11cc4876f58feefc463b52d8d36e69c4c2c9227b32fe356d1e2a1bb88466\r\nMsg = b16e6c44f429efdc06a892cede56296e12bf185d4b3c6953f7d31b1c3d59bce136d93aa95a3af61f\r\nMac = 29b26a75\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 178\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = a6fd8382447181bd300ec1ef039d3f353446d01fde490509c3ef52a992bf6fe4\r\nMsg = d41f8fbb6f968dda0c1b2cadbec04a6c72124eb5dc40b8d2b180fd3b17af915b5a374597e036d38d\r\nMac = 2b343893\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 179\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = df0821c9ea6ab329c626d11b4bc1ba7351ca934ece6aae483e3d0bef48601f78\r\nMsg = 84b9c150a1df00ba29386197d79d29a2ceb42fe6390c9e763169f75fe15c55dbe817f5c7fe80f557\r\nMac = 3a5026ef\r\nResult = F (1 - Message changed)\r\n\r\nCount = 180\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 0f1b73e54f4571b2d42aa5ab673f3e99b44f6c37a07a5d4edc7d6b1fba349401\r\nMsg = 3918467effb5d5dc009aaefce84d8cb4fe8f80eb608f4c678f5d0de02ea11e59078d38b04f10de73\r\nMac = 1c207499e0877bb2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 181\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 25a152850b4b80b19d8f0b504b2a8a241824b3a1fca8d85c8713b2c0c84b5e02\r\nMsg = b06f6b3f197bae7d8cde9daf38530e25bc51b68f9aa23ec0e95199b14bca96c91f3db15bf8432f71\r\nMac = b860013252ae83a4\r\nResult = P\r\n\r\nCount = 182\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 849d861aa5a37c6389f7bc2fc3b4860fac9d2277fa5e1a1f9415a6aaa5106886\r\nMsg = 191b53e0c7d90161e5e2014e9b8aea315b4bddf5750aba4be69c944d71896361f210f961ee6b38f9\r\nMac = c9dc7e167c2e442b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 29dd1ee0ffa12de3a1f2cb8e4e24d2e548794a5e7e372f946bfd733f3c564764\r\nMsg = 891c806e0700f6df72befe47ff088d917cc30763866810a2fcaa9f38b45953156c860b7303e8b15f\r\nMac = 2f7355b3994f45d9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 184\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6cd7349d96feffbcf6e95a96eacbbe8ddab702ef70052b7804f78518589df3f7\r\nMsg = bbe054fbef86db3ce7ad796e6d0add15455b9cff57fb787610b4e1ba05d5bcaed98564d16157ee70\r\nMac = 8a421387c53702d3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 185\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = a32e186c29f6f1852b483a37b50c02defeb2ce81488198bc082c17fd47a741f4\r\nMsg = e687143dc4d98dcc6a2dfe6ee0f85d565d1f46bb0fafe62a17d01720d6f4ccd86754b0626c9d0af5\r\nMac = d44d78445c5ed8de\r\nResult = F (1 - Message changed)\r\n\r\nCount = 186\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 338f8054d58c26c49360c3e87af56523acf6d89d03e56ff2f868002bc3e431ed\r\nMsg = d42b10d3a688c39edf543ae7330466eeb9e3b678ef073967ff83038d40ded1c200c4f03481fc5aff\r\nMac = b25bf6993f18d503\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 187\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 96e04382027fffcaf779c984be80da16f8437db0e39a7123d9048ff71954acb7\r\nMsg = 494c8f931029a4919e2dcbc16512a8bfe275382e7d29c9abb1d14a006caec59ab9b52a3e9ce54ef7\r\nMac = 5a94a03591ee9cc7\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 682f8bc1eafd4d369df384841a88db7b7fb96c9dd9abd6dedc9290a8d8d17d22\r\nMsg = 87b937b1d36e8a9ab33a1d3eed617030923acaabc7e620dfcb3c388936030fc67f647729c19e040b\r\nMac = 89347722a73d8bf9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 189\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 954222a9cabaa5a0a91100b158a3aeb655c4473d0b00afe6a7a78e0d278a01a9\r\nMsg = b9197eb50c8168d16b8a12bd261d553ffcc521d979b26fee820376252e452213d736c21471cf0179\r\nMac = e5d175fa24cf0fd6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 190\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 18349be2894d49290339b97f4db28c92b3e112ffac77100abbf9c093935b1a46\r\nMsg = 4b02fd5a46ac681a42424ac9723911af4e389ac73829f36f60916563e51cb2ec3d7d9b55d674a59f\r\nMac = 18c98fd13595f857\r\nResult = P\r\n\r\nCount = 191\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = f1f9fdfa9ae3ba8bc6fcdb2e15ae2c47e6292c2acb091fe03e325f298ffff3bd\r\nMsg = 75965cfbf66b0ba13274fce6537fd7aa4efa5d75195a400018bd38f7d8cd53fdffe88df1837fa06f\r\nMac = 935e4d4367aef07e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 192\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 4652bacedb47faee1be641ebf433157f416b4c7d9e8c7c6f7b17b47e70156993\r\nMsg = 17e6acda3c05c9549eadad55d8918f4870aec63a18802fa33175cf838fa2b9b17cb43270ff2a1444\r\nMac = 7ce4adc343a4498a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 193\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 200e4929c275557d9caab0ba3b0a153dd8010ff8f11ebc1f336dd0249d01dce6\r\nMsg = bd05d26ebfcb5f6e102e79976fbd038e02da6a64a6be90bb84bd092be5cb8ae447409e94afd89b8b\r\nMac = 5484fd10e83798c2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 194\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 8c6a6e77534976b4d74a0972742989dbc0f753281a5ff10a862e9048b813b4a9\r\nMsg = 869c482db2b0825cd09d295749359b99fde85240e5ddaebef642f4d249e096b77af2b59b4e37e452\r\nMac = 9e640a86d55be78d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 195\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = be3db75687360fc31c27752a5f32125cf04f8bbab694339ebcb57ff63fc7ba32\r\nMsg = 33dfb223c009001a7b3b81916bb094390c42c24a47884fc8a0410f05b2f57b67d8d9046b2ef4a8ea\r\nMac = c7666f25d2329fb6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 196\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 29e7acc4facc2618f242ec9260a8ec36c4c9dabb89bb8092f00855234b0c505a\r\nMsg = 09bf4f77a9883733590a3cc7ee97f3c9b70f4db255620e88cd5080badc73684c8b80393302ca8803\r\nMac = 424535e20d082087\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 197\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 23f0d00daef3177fbcda6e9953a5a37d5da395204d8af5fb05c74e03f71343da\r\nMsg = 2222135e545f2af53be42d7a463719447e0a6a305fbe8e43e6279a91eb8f3c5db1fdf081bcb77711\r\nMac = 52c42541e2e93f3e\r\nResult = P\r\n\r\nCount = 198\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6746d9a90e0e763679d5469a1bcffcc4f18f35f50c7714d14c7329b76ce7984e\r\nMsg = 68530f15423071410a349872c559669301096c827333adc4df9da477387c89870942d12513b7f475\r\nMac = 2bf36912e1139629\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 199\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6b1d94bc0c6e45fc905c509ea667853e4b2c5a8848dd914efcef14d95b12247d\r\nMsg = 207b649c46c1963723624d8428d4b64c08cd4091cc055175223d3758f880614149a9cf7f3725c790\r\nMac = 34f46b361bddf55c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 200\r\nKlen =", - " 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 5c77fe134af3fef72fcd16006097dc7dbc45ca10339ae3bc85e0993e4cdcefa1\r\nMsg = fab52c44379ae8083bdc7b827383df93cb1a7ecc21574730f9fe003b7302de237bed535d40832763e7a2cab5806de91d39aa3f38d167ae3250e48ed1f6ad45b5\r\nMac = 03f36c5a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 201\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 997c6b4b513bbdeaf701867bbe81bdee63de0d0d18c870bcc1e9ff7f627f093e\r\nMsg = 4c23d92665e88a4f6f732de384034d493d5df37b767a8260557de05688e8d60dcd0eba9cb8cc4bceb174dcbd3c0ab5a37db3b6ecfb6a3d90a4f54a9f1117e11e\r\nMac = 9e798c73\r\nResult = F (1 - Message changed)\r\n\r\nCount = 202\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 64e390edd97c0af1ba5165900828e0630606f83d4df5240e1b05c307ee9153ff\r\nMsg = 1ae71094fc1b304adfa3378c4efa8fb290526bb314714c9613beca2a709c91f7e3f6aa74561bfc7b8fcd12f910941eea3b593e85ba2fffb31e7420c6c6199868\r\nMac = 1977347f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 203\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 44e2f6d41e04b75f541e724c6f6325f27d7475b3676fa0247f28b36e58b6fdf5\r\nMsg = b9ac624288352617e4d375f33953b431cbf8f03f9ecbda9893330ff2d3c59db8705dc3ba4a6ef924309630ac48765b10b1c02ec0669126d76602c95012fa2f77\r\nMac = 2cba4713\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 204\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 8e0f75b7029d4afc2a86adb4a088b89ef9783965027c1176497ada0fdfd0cd99\r\nMsg = 21cd3ff946e2b3c1c61932205899502852b1333d1c79a3d4e5b6617996ffba17041e5b746ab967fb1632c7be62cbc2bbe60ecd5eec6ca4482424994f9a662cc6\r\nMac = b651d356\r\nResult = P\r\n\r\nCount = 205\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 35b1106d174acce103ecf5801b03d3c10d579c4ee491ebad25fb6f1f1787e0c8\r\nMsg = 960026395d0544975dffaaa2c56db1df5816cd80cde513dc76f6f81d21f15c383c97c7233c9af2423fb28922efed2f69aa47c30de17ae1c5be17acbd0ad6cb8e\r\nMac = 8a8f65a8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 206\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 71efa75961dfd60ad533082a8cfe111214eb02573adc4591c5d0e961640a3ab2\r\nMsg = 6bafbd22b75e21e1fa5444af283e69d53ac2f0412f717a2153f74eb1c195fc5127d240dbc96d2833c9957920a55c505a016a05e4a7ee549bccdbbf1095502e93\r\nMac = 88fea081\r\nResult = F (1 - Message changed)\r\n\r\nCount = 207\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 11752eb8aeffa364c9947092c1612461cc19b6c3a3ddd1817b5e6f7f3745a942\r\nMsg = 2d9109e7eea21b2615c81c03182ce6033c93783b13d698624392bd2a8a202bd0ffc860f29b31afa2f71c2bb85752c66ce8dbba244671288a4135ffe2e1a0209b\r\nMac = b5a26c1c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 208\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 279a6c226f6a48f3128626012baaa309d99065a59dc0a4c003a6e94d85e61638\r\nMsg = 9bff96ba07a52d9ea2415283321395cf57cb37c610fad7a482c74de9f5e3d7f520bf73d4a6fc8b5be023d774dd9680b6a7c68139c8a753a80d61c9978a493917\r\nMac = 5e281941\r\nResult = P\r\n\r\nCount = 209\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 0bcdcaa87ddf8bbe6db8411d14bb9064e4a121286cc8a6e97fce1844935f436b\r\nMsg = 3ec0aa8d30d5ed825b77dc7095f421b1e608158797a377ff8bed641bd387832f7c14818cabf9bd5ced6044cdc883ff7296272be693660ab234b2d870ba170131\r\nMac = 1da79d07\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 210\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 1b41d148e3c202d419ce16385139da196dede5be63987e6940a2bae86d62e567\r\nMsg = 13ecd70e2d76dd53a19b2e5fc0afe0c0793577ba8948b7d4ef3ab797a07a37927dbb33a18252b96f40e0f73a8d3298d67a6551f5854eb6a51019531a122ff8ae\r\nMac = 91bd49b2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 211\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = a1ccc9c992c8a307ad39504854456696f8eafd7c8da0c0c53b3a4485570e985e\r\nMsg = f68b0c3b4556c7f8866b3fa873ed2014418d6421d3f224512e5dae8c2d8dd92175e09508acbcc66ae62d536260cf790671ef66a1bded0343ace4117c1b8d7764\r\nMac = b9317feb\r\nResult = P\r\n\r\nCount = 212\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 4d8d0264ae6d8f7a7440dd760e0ded25a3a94cb0491fe81e7b55221ac8ed24f7\r\nMsg = 5faaf6b8ee8ed5b56bfc1a7f886f9f91a6566ceb99c39462ab675a3ae3be98f68787626fdf77e6243c2e96d1396a8a43417b1f6a51f7e5b0ffaeb889bce02c4b\r\nMac = 3f610010\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 213\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = bcf95051ae2ae84ac32a763d5477ccc4659a9ed3e25de5932939826dc90e2464\r\nMsg = fce924dd27db3e07837694c34f576c16084e5b0a254ca3af0582bf6026c73b47973ac924b02992490032cae987a887932539d3fa53cdfff711b03bd11ff464bb\r\nMac = 7b7e89ef\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 214\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 45ce953ad31ee9b53a9c948883bc86f4bbe0f0744085a9943cbad1066cd7b4f3\r\nMsg = edb1aaa7e8ac37bca99ff8eff5516464aa33fc2bebef8a727d43abf971108bc604aef019c3837aa2f3d429f22fda1f305319a70d99ed77f902663298f855316f\r\nMac = cbf4addd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 215\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = d60841cd71d7227ab56e767817760edba9ce2290f8da504b341ee2c1910b5018\r\nMsg = 365fea641559759d1e5b5581218486318b1c776de812b1aca6a9ba6b1c6e39c5cb6d5a44e3a474f709b8eac457e74f00a43ecd3d060cc7639696bd03730c70e7\r\nMac = 7406f935\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 216\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = d172f991eb697ffdefc57349dadbe51066d2744c39041cd55ca75024eead495d\r\nMsg = 6a91da64812b9bb41a026e727b4f77c384813da2948caed5a9846420c86a26b89f46b2fa6975b95d12452ca69bbfb65bc1c48a79d95c5e69ff4ab7316fe468e8\r\nMac = 6bd82bcc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 217\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 3725c7905bfaca415908c617b78f8deeeff286e0c2bba268d0de92c7664238a7\r\nMsg = fc4bbe329a86089ebe2a2f3320dad55a9bdac1133dd28ddc9ace9ed665885a2341ea9492d4cf4b7e1d0a95f308a9d613407b35b845cf515bbe7f2f35102d78a3\r\nMac = c8e11823\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 218\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = bb3087d1b5b0f6f14a532c3604c82874fb15e97a4b3883dfc50e71ffe5752d40\r\nMsg = 979a9f96112d1ea95eec2cdfdf48c55114472360aa7de24bb53761013af96b33f02b17ae470fece8aaf649d801b4040b7b5152f58a01e7852f565efc77b5dafe\r\nMac = 66466425\r\nResult = P\r\n\r\nCount = 219\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = eeb983439a03ee6a315ebf941e9368f90bb6845b03b31839d72a1946c17d2f19\r\nMsg = 6d5573c9279897d7d1602d8a95c04bb5ca3fad2dbe89a024b3651eb227e73bb559e7c0db08b215fd7efe64afcd24fb155989f2f8965d0e181389e6c4b8e244a9\r\nMac = 7f77d596\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 220\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6f0353a0ad95df6d3190a251435f62c30ed6b9cc0dd024c3c316565cad83d2e1\r\nMsg = 83011a83db0524628b55589ba0165523ce7c916465eaf185805b97ec7f00fc01b82a3e356a6bbb44f2f8deb6425239ac8e26d4d94871c5cf4fe7017c649672f4\r\nMac = 9e56e4574dd01fe8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 221\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 777a22c5fa2f864a9233587e3e9634172ce25006daacbba97b68e7429c8266a8\r\nMsg = 1f7d58d65c36142620172fda3197d3c629bc7bc584e1aaa0f8b6dd320588becaccc39ad124b515adeb941de49ac31c851c5172c4e1c322e42e13cb5ab7f8db2f\r\nMac = 498dafe2807ba34e\r\nResult = P\r\n\r\nCount = 222\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = e17736560b1a13aa8e536500ea6cdb9a6757309aadf25a6a9189055a309c3f8b\r\nMsg = 1a6b80d506147c3c02c89f50892bd1f04d34f9f21e8307140df43835d17495c56a13be7a045be5441de01d84ea19d579f76e9ffa0f92376b5b13c0eacd3050c9\r\nMac = 52d3fbc6e5821f1d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 223\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f31f2fb4b3fd8045b70d34b600a2697cbf7503be0d8cfb5cdc60f9312e3e2695\r\nMsg = 4f43702be4f0530319555d7f1a3356160f6cae48051f12e22a153d7e405c11494c31e6098e24225eb676094755c6d7e992ec0c8c1e2608e76a72d79d173a4e07\r\nMac = 71239a4c38fa04b3\r\nResult = F (1 - Message changed)\r\n\r\nCount = 224\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 10a678f591b4d87280f42d77a91635575e2e82ef610a7c9105c3a9418f932c24\r\nMsg = f7b577f1396b23c27eb637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f8202791e3c2d2bafe084a1204e34dd\r\nMac = 5b11c1407904c15e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 225\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b8728441226558fa9764824597fe254bf8c2623789541feaf6c007efeb0dd2b1\r\nMsg = 80a2be15809f12738f305be3a210ba0c933599c4b24b48257c60e8e3aae189dc6ec58ff1f9085a15405b26a3001a2ff5ff7e1932961490676c6d2cda8417979b\r\nMac = e73ed6c4f81b0ecd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22a877d974cdf4d65bbd77958b2b77fc5ddb33a221aca3ecb6d5ae76596f9db4\r\nMsg = ce2ce41f76ca7477972d38a3e8fad1122db34ee80c379fa01f884cf648d1670445a8bfab8490563438c21537ac2dbfbcd7bb24a132d6973cc62ba14089adf7e5\r\nMac = 0ff91813a56b98dd\r\nResult = F (1 - Message", - " changed)\r\n\r\nCount = 227\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 03fa02c4df99b8295f502e3145e2edd3ff16722b87092e708bc8d126cc1ec894\r\nMsg = ec9a9babb68e09c38617c9b16e8a2d92e711030bcda4b9e0ab35c4c2392b41692312dde30c91f32cd39cf5fe15ea0deaf3aa04a8157262acee78d7f94204d93a\r\nMac = e50d9a04f79cf9b4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 228\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0e12df1bf17e9645c5507bc2069ca4611dc0488c9996231dbcee1c73393b26c4\r\nMsg = 86814ce4a867f80ce9b618c6aecce37c89851508bbb095c8f7c055f569c47a30f79abe5ec75f12b601298718d6f96ea1c1ebbe7c0cb0b7fb973ec5e6d5c6a713\r\nMac = 05338bce9ed8f495\r\nResult = P\r\n\r\nCount = 229\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 51c88fd98a7d82043a1500fc3d8a66ba7ab7760467c7fd89cfeeb22dd25762a2\r\nMsg = 0e403cff47adee3ec5bb6b178dabfc7d53b60a04eaad33a2fedd9db705358a4c73ab2d982ddbbdc941f1c701d4cac89e5c56fbbe0f4170029ad25e931713ba63\r\nMac = 38c34175627b07e8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 230\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0feb23c7e4a19bcbd70bd300d76ec9045d696f8c9687f49ec4154400e231d2f0\r\nMsg = 0330ed97e44e8b15a49f29c72a7997d05d398a9d45dae41a6cc635258beb824362124691e86cb7fea46e4ab85bdf79e4eb30c492770bf6f0c42ea9bde37a0c01\r\nMac = 271a7c2e687d84c5\r\nResult = P\r\n\r\nCount = 231\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5d649799771f9074d18a2477ccd4d9e136e01451c1eb2e8bb370cb79e0486770\r\nMsg = d715bc0520dbb86543e76fede49dc6be2cce59d3c0db133ff31efcb63a85514fe080da88fa1e788b9e73feb0503c4142bdc67386ac0bacf9311ecada23ca7be8\r\nMac = 42de9f52567b4506\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 4c96d520d8d5a54eb73f8f558e328d1b3e5ba360161fb8444739a40a97a58a1b\r\nMsg = ee409b050346fbd319c8630e4bc9dd6d055355fbb961f018d3fda0c1eea6f61248f43709737fb18d4efc4faf34a96c2f73ece54200367292692e36870a0c94c5\r\nMac = 28610f524d88e727\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 233\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b186b9273d8cd77d68c05ec5389b2f6e2f267fe6cd6e7cb35a3233c0dfe0b1f4\r\nMsg = 0df3fc6396f851785fca9aa5ffb0cd98bdecf8bbae4c82641efcb34d319e7643ca9c5e22acbde800e0f700a95685c64ccf399173f9123438dc1181b676490cbf\r\nMac = 8d2f69b44614485a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 234\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 1b1374648d93aadb186326e4ca2b82fd37f7234712816fe4feb339a3a16880df\r\nMsg = 9a661677f1e07153e1c9c661c91901757f5b4d9938031f01a802773d6a9863b2a169c44be0d4546c4780e828ef37f3b389f84c1a41473131e9c88bcd530c7334\r\nMac = 72838b59593c011c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 235\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f70b8a4eee3518bba071af55f25f7b698a5b7dc8865cdaca6d1c7993657acc95\r\nMsg = 795ee1af7504621aac329f5081912de545fa11174f3979b14f11aa30df813a235b467fd8f3a14734fe5ac9e39105dcb25184673885cd19bc70ee5a53dd4e8149\r\nMac = 93542734d6cd43de\r\nResult = P\r\n\r\nCount = 236\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0c456d199abae4758734f506c4e9ccdb767e4fd156d5a4085726f3938a516d74\r\nMsg = 78f3bf568f1c3f2866eff8a246a70cf0faee4c3078f3fb27c4bdd53312bf50812bac2280118c0396e610b4110a22406084c18283a30ce7c0e49c769817170df9\r\nMac = c4c5be3c94fb7b9c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0a8725bd8c8eab9ed52ca47835837b9f00a6c8d834ab17105b01eb4eb30402e7\r\nMsg = d7867ff428c37836161a534d1d697fba43e86b0096c49b63d50afaf06ec772bda86eba7222796f087c5367d1547642b974d041cb496c5cf7984e8e126c9f741e\r\nMac = b5d40f8633965c33\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 238\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = ce9ea80e7fb235486b5f1d0321c68a0e44cd5f15e21f27c402754a2f7c138772\r\nMsg = c246453f5d0f4957e6418b4d17b748f5c30e7ee672b4af2e4e41e145400be94056f4e94768871849fb44c1ee65378fce32d007e0c7ee5635453d4de6b0c2aa4b\r\nMac = 33ae4c66895989ee\r\nResult = F (1 - Message changed)\r\n\r\nCount = 239\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f26fad377bf7d6b35d8ea2e0621b678dad85826fadd3ee684d9215086b77e555\r\nMsg = 63539f949990883ac4f3ef9158b382a30254023c301de9fcd3cd4faa638a0ecb241a2573a9555a5c96da2435aa02c73cfc12c10f84b565bfdea9c6274bb8d67c\r\nMac = 8cda222f03f92913\r\nResult = F (2 - Key or Key2 changed)\r\n", -}; -static const size_t kLen36 = 58307; - -static const char *kData36[] = { "# Tests from NIST CAVP SP 800-56A ECCCDH Primitive Test Vectors.\n# http://csrc.nist.gov/groups/STM/cavp/documents/components/ecccdhtestvectors.zip\n#\n# P-521 test vectors were fixed to have the right length.\n\nCurve = P-224\nPrivate = 8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd\nX = 8de2e26adf72c582d6568ef638c4fd59b18da171bdf501f1d929e048\nY = 4a68a1c2b0fb22930d120555c1ece50ea98dea8407f71be36efac0de\nPeerX = af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280\nPeerY = 882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7\nZ = 7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8\n\nCurve = P-224\nPrivate = 043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d\nX = 2f90f5c8eac9c7decdbb97b6c2f715ab725e4fe40fe6d746efbf4e1b\nY = 66897351454f927a309b269c5a6d31338be4c19a5acfc32cf656f45c\nPeerX = 13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46\nPeerY = eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4\nZ = ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09\n\nCurve = P-224\nPrivate = 5ad0dd6dbabb4f3c2ea5fe32e561b2ca55081486df2c7c15c9622b08\nX = 005bca45d793e7fe99a843704ed838315ab14a5f6277507e9bc37531\nY = 43e9d421e1486ae5893bfd23c210e5c140d7c6b1ada59d842c9a98de\nPeerX = 756dd806b9d9c34d899691ecb45b771af468ec004486a0fdd283411e\nPeerY = 4d02c2ca617bb2c5d9613f25dd72413d229fd2901513aa29504eeefb\nZ = 3fcc01e34d4449da2a974b23fc36f9566754259d39149790cfa1ebd3\n\nCurve = P-224\nPrivate = 0aa6ff55a5d820efcb4e7d10b845ea3c9f9bc5dff86106db85318e22\nX = 2f96754131e0968198aa78fbe8c201dc5f3581c792de487340d32448\nY = 61e8a5cd79615203b6d89e9496f9e236fe3b6be8731e743d615519c6\nPeerX = 0f537bf1c1122c55656d25e8aa8417e0b44b1526ae0523144f9921c4\nPeerY = f79b26d30e491a773696cc2c79b4f0596bc5b9eebaf394d162fb8684\nZ = 49129628b23afcef48139a3f6f59ff5e9811aa746aa4ff33c24bb940\n\nCurve = P-224\nPrivate = efe6e6e25affaf54c98d002abbc6328da159405a1b752e32dc23950a\nX = 355e962920bde043695f6bffb4b355c63da6f5de665ed46f2ec817e2\nY = 748e095368f62e1d364edd461719793b404adbdaacbcadd88922ff37\nPeerX = 2b3631d2b06179b3174a100f7f57131eeea8947be0786c3dc64b2239\nPeerY = 83de29ae3dad31adc0236c6de7f14561ca2ea083c5270c78a2e6cbc0\nZ = fcdc69a40501d308a6839653a8f04309ec00233949522902ffa5eac6\n\nCurve = P-224\nPrivate = 61cb2932524001e5e9eeed6df7d9c8935ee3322029edd7aa8acbfd51\nX = d50e4adabfd989d7dbc7cf4052546cc7c447a97630436997ad4b9536\nY = 5bea503473c5eaef9552d42c40b1f2f7ca292733b255b9bbe1b12337\nPeerX = 4511403de29059f69a475c5a6a5f6cabed5d9f014436a8cb70a02338\nPeerY = 7d2d1b62aa046df9340f9c37a087a06b32cf7f08a223f992812a828b\nZ = 827e9025cb62e0e837c596063f3b9b5a0f7afd8d8783200086d61ec1\n\nCurve = P-224\nPrivate = 8c7ace347171f92def98d845475fc82e1d1496da81ee58f505b985fa\nX = b1a8dcac89aca2799320b451df1c7ff4d97567abb68141c0d95fc2aa\nY = 3524950902b1510bdc987d860afc27ad871ceaea66935abd3c0a99a8\nPeerX = 314a0b26dd31c248845d7cc17b61cad4608259bed85a58d1f1ffd378\nPeerY = 66e4b350352e119eecada382907f3619fd748ea73ae4899dfd496302\nZ = 335ba51228d94acbed851ca7821c801d5cb1c7975d7aa90a7159f8fa\n\nCurve = P-224\nPrivate = 382feb9b9ba10f189d99e71a89cdfe44cb554cec13a212840977fb68\nX = abb6f1e3773ff8fc73aea2a0b107809ce70adcefed6e41fc5cb43045\nY = a963897ae906c10a055eeadb97ffdd6f748d3e5621e5fff304e48ba7\nPeerX = abe6843beec2fd9e5fb64730d0be4d165438ce922ed75dd80b4603e5\nPeerY = 6afe8673a96c4ba9900ad85995e631e436c6cc88a2c2b47b7c4886b8\nZ = 8c2e627594206b34f7356d3426eb3d79f518ef843fbe94014cceace3\n\nCurve = P-224\nPrivate = e0d62035101ef487c485c60fb4500eebe6a32ec64dbe97dbe0232c46\nX = 88537735e9b23e3e0e076f135a82d33f9bffb465f3abce8322a62a62\nY = b4c8c123673197875c0bd14ed097606d330fba2b9200ef65a44764d3\nPeerX = 13cf9d6d2c9aae8274c27d446afd0c888ffdd52ae299a35984d4f527\nPeerY = dcbee75b515751f8ee2ae355e8afd5de21c62a939a6507b538cbc4af\nZ = 632abb662728dbc994508873d5c527ca5ef923c0d31fa6c47ef4c825\n\nCurve = P-224\nPrivate = b96ade5b73ba72aa8b6e4d74d7bf9c58e962ff78eb542287c7b44ba2\nX = 37682926a54f70a4c1748f54d50d5b00138a055f924f2c65e5b0bbe4\nY = 596afefcdd640d29635015b89bdddd1f8c2723686d332e7a06ca8799\nPeerX = 965b637c0dfbc0cf954035686d70f7ec30929e664e521dbaa2280659\nPeerY = 82a58ff61bc90019bbcbb5875d3863db0bc2a1fa34b0ad4de1a83f99\nZ = 34641141aab05ef58bd376d609345901fb8f63477c6be9097f037f1f\n\nCurve = P-224\nPrivate = a40d7e12049c71e6522c7ff2384224061c3a457058b310557655b854\nX = 399801243bfe0c2da9b0a53c8ca57f2eee87aaa94a8e4d5e029f42ca\nY = aa49e6d4b47cee7a5c4ab71d5a67da84e0b9b425ce3e70da68c889e7\nPeerX = 73cc645372ca2e71637cda943d8148f3382ab6dd0f2e1a49da94e134\nPeerY = df5c355c23e6e232ebc3bee2ab1873ee0d83e3382f8e6fe613f6343c\nZ = 4f74ac8507501a32bfc5a78d8271c200e835966e187e8d00011a8c75\n\nCurve = P-224\nPrivate = ad2519bc724d484e02a69f05149bb047714bf0f5986fac2e222cd946\nX = df9c1e0ef15e53b9f626e2be1cbe893639c06f3e0439ee95d7d4b1e3\nY = 7a52a7386adda243efdf8941085c84e31239cab92b8017336748965e\nPeerX = 546578216250354e449e21546dd11cd1c5174236739acad9ce0f4512\nPeerY = d2a22fcd66d1abedc767668327c5cb9c599043276239cf3c8516af24\nZ = ad09c9ae4d2324ea81bb555b200d3c003e22a6870ee03b52df49e4de\n\nCurve = P-224\nPrivate = 3d312a9b9d8ed09140900bbac1e095527ebc9e3c6493bcf3666e3a29\nX = b4a0198dc8810e884425b750928b0c960c31f7a99663400b01a179df\nY = 812b601bfc0738242c6f86f830f27acd632ca618a0b5280c9d5769f7\nPeerX = 1d46b1dc3a28123cb51346e67baec56404868678faf7d0e8b2afa22a\nPeerY = 0ec9e65ec97e218373e7fc115c2274d5b829a60d93f71e01d58136c3\nZ = ef029c28c68064b8abd2965a38c404fb5e944ace57e8638daba9d3cd\n\nCurve = P-224\nPrivate = 8ce0822dc24c153995755ac350737ef506641c7d752b4f9300c612ed\nX = 00dfc7ec137690cd6d12fdb2fd0b8c5314582108769c2b722ffb3958\nY = 5eef3da4ba458127346bb64023868bddb7558a2ecfc813645f4ce9fe\nPeerX = 266d038cc7a4fe21f6c976318e827b82bb5b8f7443a55298136506e0\nPeerY = df123d98a7a20bbdf3943df2e3563422f8c0cf74d53aaabdd7c973ba\nZ = f83c16661dfcbad021cc3b5a5af51d9a18db4653866b3ff90787ce3e\n\nCurve = P-224\nPrivate = 0ff9b485325ab77f29e7bc379fed74bfac859482da0dee7528c19db2\nX = 7e603e6976db83c36011508fa695d1b515249e2e54b48fcbcfb90247\nY = 0179a600ce86adfca9b1b931fa5173d618da09e841803d19b0264286\nPeerX = eb0a09f7a1c236a61f595809ec5670efd92e4598d5e613e092cdfdca\nPeerY = 50787ae2f2f15b88bc10f7b5f0aee1418373f16153aebd1fba54288d\nZ = f51258c63f232e55a66aa25ebd597b2018d1052c02eeb63866758005\n\nCurve = P-224\nPrivate = 19cf5ff6306467f28b9fe0675a43c0582552c8c12e59ce7c38f292b1\nX = fc20e906e609c112cfc2e0fea6303882c5db94e87e022373ab2c082a\nY = aecdf1daa71782bc5a26bbbd8d7e8a76490e26abc17dffc774bd7341\nPeerX = 6b2f6b18a587f562ffc61bd9b0047322286986a78f1fd139b84f7c24\nPeerY = 7096908e4615266be59a53cd655515056ff92370a6271a5d3823d704\nZ = 7fdc969a186ff18429f2a276dac43beea21182d82ce2e5a0876552b1\n\nCurve = P-224\nPrivate = 90a15368e3532c0b1e51e55d139447c2c89bc160719d697291ea7c14\nX = c6837d506e976da7db3ad1267c359dff2ea6fb0b7f7f8e77024c59e9\nY = 67eb491d2fc8a530c46525d2a8b2d7c1df5fba1ae740a4649c683ee6\nPeerX = 328101ba826acd75ff9f34d5574ce0dbc92f709bad8d7a33c47940c1\nPeerY = df39f1ea88488c55d5538160878b9ced18a887ea261dd712d14024ff\nZ = 3d60ab6db2b3ffe2d29ccff46d056e54230cf34982e241556ed2920c\n\nCurve = P-224\nPrivate = 8e0838e05e1721491067e1cabc2e8051b290e2616eec427b7121897d\nX = e9150f770075626019e18f95473b71e6828041791d3f08d3faeeaa2b\nY = 475f70735eaae52308a3b763dc88efe18ab590ebafa035f6e08b001c\nPeerX = 0081e34270871e2ebbd94183f617b4ae15f0416dd634fe6e934cf3c0\nPeerY = 3a1e9f38a7b90b7317d26b9f6311063ab58b268cf489b2e50386d5d6\nZ = 9116d72786f4db5df7a8b43078c6ab9160d423513d35ea5e2559306d\n\nCurve = P-224\nPrivate = 38106e93f16a381adb1d72cee3da66ae462ad4bbfea9ecdf35d0814e\nX = 7be6c4c917829ab657dd79e8637d7aefd2f81f0de7654d957e97658d\nY = 430d22d9e8438310f61e0d43f25fa3e34585f432baad27db3021bf0d\nPeerX = 2623632fdf0bd856805a69aa186d4133ef5904e1f655a972d66cce07\nPeerY = 2cef9728dd06fb8b50150f529b695076d4507983912585c89bd0682e\nZ = 207c53dcefac789aaa0276d9200b3a940ce5f2296f4cb2e81a185d3d\n\nCurve = P-224\nPrivate = e5d1718431cf50f6cbd1bc8019fa16762dfa12c989e5999977fb4ea2\nX = 2ea4966e7f92ed7f5cc61fde792045f63b731d6e7d0de2577f2d8ece\nY = 1c4a7b1ede6f839162292df424be78e8176fb6f942a3c02391700f31\nPeerX = 8ee4d1dcc31dee4bf6fe21ca8a587721d910acfb122c16c2a77a8152\nPeerY = 4ebf323fff04eb477069a0ac68b345f6b1ae134efc31940e513cb99f\nZ = 10e467da34f48ad7072005bccd6da1b2ba3f71eafa1c393842f91d74\n\nCurve = P-224\nPrivate = 3d635691b62a9a927c633951c9369c8862bd2119d30970c2644727d6\nX =", " 438bbb980517afb20be1d674e3ac2b31cef07a9b23fb8f6e38e0d6c0\nY = 0be5f1c47d58d21b6ed28423b32f5a94750da47edcef33ea79942afd\nPeerX = 97dcbe6d28335882a6d193cc54a1063dd0775dc328565300bb99e691\nPeerY = dad11dd5ece8cfd9f97c9a526e4a1506e6355969ee87826fc38bcd24\nZ = 82fd2f9c60c4f999ac00bbe64bfc11da8ff8cda2e499fced65230bb1\n\nCurve = P-224\nPrivate = acf3c85bbdc379f02f5ea36e7f0f53095a9e7046a28685a8659bf798\nX = ff7511215c71d796bd646e8474be4416b91684ce0d269ef6f422013b\nY = b7bf5e79b5a9393bb9ea42c0bdb2d3c2dc806e1a7306aa58e4fdbea5\nPeerX = ce9126dd53972dea1de1d11efef900de34b661859c4648c5c0e534f7\nPeerY = e113b6f2c1659d07f2716e64a83c18bbce344dd2121fe85168eae085\nZ = 530f7e7fc932613b29c981f261cb036cba3f1df3864e0e1cba2685a2\n\nCurve = P-224\nPrivate = cffd62cb00a0e3163fbf2c397fadc9618210f86b4f54a675287305f0\nX = 04bf4d948f4430d18b4ed6c96dbaf981fa11a403ed16887f06754981\nY = 7c1326a9cef51f79d4e78303d6064b459f612584ac2fdf593d7d5d84\nPeerX = 84419967d6cfad41e75a02b6da605a97949a183a97c306c4b46e66a5\nPeerY = 5cc9b259718b1bc8b144fde633a894616ffd59a3a6d5d8e942c7cbb7\nZ = 49f6fd0139248ef4df2db05d1319bd5b1489e249827a45a8a5f12427\n\nCurve = P-224\nPrivate = 85f903e43943d13c68932e710e80de52cbc0b8f1a1418ea4da079299\nX = 970a4a7e01d4188497ceb46955eb1b842d9085819a9b925c84529d3d\nY = dfa2526480f833ea0edbd204e4e365fef3472888fe7d9691c3ebc09f\nPeerX = 7c9cac35768063c2827f60a7f51388f2a8f4b7f8cd736bd6bc337477\nPeerY = 29ee6b849c6025d577dbcc55fbd17018f4edbc2ef105b004d6257bcd\nZ = 8f7e34e597ae8093b98270a74a8dfcdbed457f42f43df487c5487161\n\nCurve = P-224\nPrivate = cce64891a3d0129fee0d4a96cfbe7ac470b85e967529057cfa31a1d9\nX = a6b29632db94da2125dc1cf80e03702687b2acc1122022fa2174765a\nY = 61723edd73e10daed73775278f1958ba56f1fc9d085ebc2b64c84fe5\nPeerX = 085a7642ad8e59b1a3e8726a7547afbecffdac1dab7e57230c6a9df4\nPeerY = f91c36d881fe9b8047a3530713554a1af4c25c5a8e654dcdcf689f2e\nZ = 71954e2261e8510be1a060733671d2e9d0a2d012eb4e09556d697d2a\n\nCurve = P-256\nPrivate = 7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534\nX = ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230\nY = 28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141\nPeerX = 700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287\nPeerY = db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac\nZ = 46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b\n\nCurve = P-256\nPrivate = 38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5\nX = 119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d0\nY = 8f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d\nPeerX = 809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae\nPeerY = b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3\nZ = 057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67\n\nCurve = P-256\nPrivate = 1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8\nX = d9f2b79c172845bfdb560bbb01447ca5ecc0470a09513b6126902c6b4f8d1051\nY = f815ef5ec32128d3487834764678702e64e164ff7315185e23aff5facd96d7bc\nPeerX = a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3\nPeerY = ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536\nZ = 2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec\n\nCurve = P-256\nPrivate = 207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d\nX = 24277c33f450462dcb3d4801d57b9ced05188f16c28eda873258048cd1607e0d\nY = c4789753e2b1f63b32ff014ec42cd6a69fac81dfe6d0d6fd4af372ae27c46f88\nPeerX = df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed\nPeerY = 422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4\nZ = 96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024\n\nCurve = P-256\nPrivate = 59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf\nX = a8c5fdce8b62c5ada598f141adb3b26cf254c280b2857a63d2ad783a73115f6b\nY = 806e1aafec4af80a0d786b3de45375b517a7e5b51ffb2c356537c9e6ef227d4a\nPeerX = 41192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb922\nPeerY = 1af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328\nZ = 19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62\n\nCurve = P-256\nPrivate = f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef\nX = 7b861dcd2844a5a8363f6b8ef8d493640f55879217189d80326aad9480dfc149\nY = c4675b45eeb306405f6c33c38bc69eb2bdec9b75ad5af4706aab84543b9cc63a\nPeerX = 33e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792\nPeerY = f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f\nZ = 664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3\n\nCurve = P-256\nPrivate = 3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190\nX = 9fb38e2d58ea1baf7622e96720101cae3cde4ba6c1e9fa26d9b1de0899102863\nY = d5561b900406edf50802dd7d73e89395f8aed72fba0e1d1b61fe1d22302260f0\nPeerX = 6a9e0c3f916e4e315c91147be571686d90464e8bf981d34a90b6353bca6eeba7\nPeerY = 40f9bead39c2f2bcc2602f75b8a73ec7bdffcbcead159d0174c6c4d3c5357f05\nZ = ca342daa50dc09d61be7c196c85e60a80c5cb04931746820be548cdde055679d\n\nCurve = P-256\nPrivate = d8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8\nX = 20f07631e4a6512a89ad487c4e9d63039e579cb0d7a556cb9e661cd59c1e7fa4\nY = 6de91846b3eee8a5ec09c2ab1f41e21bd83620ccdd1bdce3ab7ea6e02dd274f5\nPeerX = a9c0acade55c2a73ead1a86fb0a9713223c82475791cd0e210b046412ce224bb\nPeerY = f6de0afa20e93e078467c053d241903edad734c6b403ba758c2b5ff04c9d4229\nZ = 35aa9b52536a461bfde4e85fc756be928c7de97923f0416c7a3ac8f88b3d4489\n\nCurve = P-256\nPrivate = 0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d\nX = abb61b423be5d6c26e21c605832c9142dc1dfe5a5fff28726737936e6fbf516d\nY = 733d2513ef58beab202090586fac91bf0fee31e80ab33473ab23a2d89e58fad6\nPeerX = 94e94f16a98255fff2b9ac0c9598aac35487b3232d3231bd93b7db7df36f9eb9\nPeerY = d8049a43579cfa90b8093a94416cbefbf93386f15b3f6e190b6e3455fedfe69a\nZ = 605c16178a9bc875dcbff54d63fe00df699c03e8a888e9e94dfbab90b25f39b4\n\nCurve = P-256\nPrivate = 2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08\nX = 3d63e429cb5fa895a9247129bf4e48e89f35d7b11de8158efeb3e106a2a87395\nY = 0cae9e477ef41e7c8c1064379bb7b554ddcbcae79f9814281f1e50f0403c61f3\nPeerX = e099bf2a4d557460b5544430bbf6da11004d127cb5d67f64ab07c94fcdf5274f\nPeerY = d9c50dbe70d714edb5e221f4e020610eeb6270517e688ca64fb0e98c7ef8c1c5\nZ = f96e40a1b72840854bb62bc13c40cc2795e373d4e715980b261476835a092e0b\n\nCurve = P-256\nPrivate = 77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848\nX = ad5d13c3db508ddcd38457e5991434a251bed49cf5ddcb59cdee73865f138c9f\nY = 62cec1e70588aa4fdfc7b9a09daa678081c04e1208b9d662b8a2214bf8e81a21\nPeerX = f75a5fe56bda34f3c1396296626ef012dc07e4825838778a645c8248cff01658\nPeerY = 33bbdf1b1772d8059df568b061f3f1122f28a8d819167c97be448e3dc3fb0c3c\nZ = 8388fa79c4babdca02a8e8a34f9e43554976e420a4ad273c81b26e4228e9d3a3\n\nCurve = P-256\nPrivate = 42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e\nX = ab48caa61ea35f13f8ed07ffa6a13e8db224dfecfae1a7df8b1bb6ebaf0cb97d\nY = 1274530ca2c385a3218bddfbcbf0b4024c9badd5243bff834ebff24a8618dccb\nPeerX = 2db4540d50230756158abf61d9835712b6486c74312183ccefcaef2797b7674d\nPeerY = 62f57f314e3f3495dc4e099012f5e0ba71770f9660a1eada54104cdfde77243e\nZ = 72877cea33ccc4715038d4bcbdfe0e43f42a9e2c0c3b017fc2370f4b9acbda4a\n\nCurve = P-256\nPrivate = ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b\nX = 9a8cd9bd72e71752df91440f77c547509a84df98114e7de4f26cdb39234a625d\nY = d07cfc84c8e144fab2839f5189bb1d7c88631d579bbc58012ed9a2327da52f62\nPeerX = cd94fc9497e8990750309e9a8534fd114b0a6e54da89c4796101897041d14ecb\nPeerY = c3def4b5fe04faee0a11932229fff563637bfdee0e79c6deeaf449f85401c5c4\nZ = e4e7408d85ff0e0e9c838003f28cdbd5247cdce31f32f62494b70e5f1bc36307\n\nCurve = P-256\nPrivate = 43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604\nX = f989cf8ee956a82e7ebd9881cdbfb2fd946189b08db53559bc8cfdd48071eb14\nY = 5eff28f1a18a616b04b7d337868679f6dd84f9a7b3d7b6f8af276c19611a541d\nPeerX = 15b9e467af4d290c417402e040426fe4cf236bae72baa392ed89780dfccdb471\nPeerY = cdf4e9170fb904302b8fd93a820ba8cc7ed4efd3a6f2d6b05b80b2ff2aee4e77\nZ = ed56bcf695b734142c24ecb1fc1bb64d08f175eb243a31f37b3d9bb4407f3b96\n\nCurve = P-256\nPrivate = b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903\nX = 69c627", "625b36a429c398b45c38677cb35d8beb1cf78a571e40e99fe4eac1cd4e\nY = 81690112b0a88f20f7136b28d7d47e5fbc2ada3c8edd87589bc19ec9590637bd\nPeerX = 49c503ba6c4fa605182e186b5e81113f075bc11dcfd51c932fb21e951eee2fa1\nPeerY = 8af706ff0922d87b3f0c5e4e31d8b259aeb260a9269643ed520a13bb25da5924\nZ = bc5c7055089fc9d6c89f83c1ea1ada879d9934b2ea28fcf4e4a7e984b28ad2cf\n\nCurve = P-256\nPrivate = 4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8\nX = 5fe964671315a18aa68a2a6e3dd1fde7e23b8ce7181471cfac43c99e1ae80262\nY = d5827be282e62c84de531b963884ba832db5d6b2c3a256f0e604fe7e6b8a7f72\nPeerX = 19b38de39fdd2f70f7091631a4f75d1993740ba9429162c2a45312401636b29c\nPeerY = 09aed7232b28e060941741b6828bcdfa2bc49cc844f3773611504f82a390a5ae\nZ = 9a4e8e657f6b0e097f47954a63c75d74fcba71a30d83651e3e5a91aa7ccd8343\n\nCurve = P-256\nPrivate = 4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147\nX = c9b2b8496f1440bd4a2d1e52752fd372835b364885e154a7dac49295f281ec7c\nY = fbe6b926a8a4de26ccc83b802b1212400754be25d9f3eeaf008b09870ae76321\nPeerX = 2c91c61f33adfe9311c942fdbff6ba47020feff416b7bb63cec13faf9b099954\nPeerY = 6cab31b06419e5221fca014fb84ec870622a1b12bab5ae43682aa7ea73ea08d0\nZ = 3ca1fc7ad858fb1a6aba232542f3e2a749ffc7203a2374a3f3d3267f1fc97b78\n\nCurve = P-256\nPrivate = 1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e\nX = 59e1e101521046ad9cf1d082e9d2ec7dd22530cce064991f1e55c5bcf5fcb591\nY = 482f4f673176c8fdaa0bb6e59b15a3e47454e3a04297d3863c9338d98add1f37\nPeerX = a28a2edf58025668f724aaf83a50956b7ac1cfbbff79b08c3bf87dfd2828d767\nPeerY = dfa7bfffd4c766b86abeaf5c99b6e50cb9ccc9d9d00b7ffc7804b0491b67bc03\nZ = 1aaabe7ee6e4a6fa732291202433a237df1b49bc53866bfbe00db96a0f58224f\n\nCurve = P-256\nPrivate = dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3\nX = 30b9db2e2e977bcdc98cb87dd736cbd8e78552121925cf16e1933657c2fb2314\nY = 6a45028800b81291bce5c2e1fed7ded650620ebbe6050c6f3a7f0dfb4673ab5c\nPeerX = a2ef857a081f9d6eb206a81c4cf78a802bdf598ae380c8886ecd85fdc1ed7644\nPeerY = 563c4c20419f07bc17d0539fade1855e34839515b892c0f5d26561f97fa04d1a\nZ = 430e6a4fba4449d700d2733e557f66a3bf3d50517c1271b1ddae1161b7ac798c\n\nCurve = P-256\nPrivate = 5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76\nX = 46c9ebd1a4a3c8c0b6d572b5dcfba12467603208a9cb5d2acfbb733c40cf6391\nY = 46c913a27d044185d38b467ace011e04d4d9bbbb8cb9ae25fa92aaf15a595e86\nPeerX = ccd8a2d86bc92f2e01bce4d6922cf7fe1626aed044685e95e2eebd464505f01f\nPeerY = e9ddd583a9635a667777d5b8a8f31b0f79eba12c75023410b54b8567dddc0f38\nZ = 1ce9e6740529499f98d1f1d71329147a33df1d05e4765b539b11cf615d6974d3\n\nCurve = P-256\nPrivate = b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d\nX = 7c9e950841d26c8dde8994398b8f5d475a022bc63de7773fcf8d552e01f1ba0a\nY = cc42b9885c9b3bee0f8d8c57d3a8f6355016c019c4062fa22cff2f209b5cc2e1\nPeerX = c188ffc8947f7301fb7b53e36746097c2134bf9cc981ba74b4e9c4361f595e4e\nPeerY = bf7d2f2056e72421ef393f0c0f2b0e00130e3cac4abbcc00286168e85ec55051\nZ = 4690e3743c07d643f1bc183636ab2a9cb936a60a802113c49bb1b3f2d0661660\n\nCurve = P-256\nPrivate = fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535\nX = 38b54db85500cb20c61056edd3d88b6a9dc26780a047f213a6e1b900f76596eb\nY = 6387e4e5781571e4eb8ae62991a33b5dc33301c5bc7e125d53794a39160d8fd0\nPeerX = 317e1020ff53fccef18bf47bb7f2dd7707fb7b7a7578e04f35b3beed222a0eb6\nPeerY = 09420ce5a19d77c6fe1ee587e6a49fbaf8f280e8df033d75403302e5a27db2ae\nZ = 30c2261bd0004e61feda2c16aa5e21ffa8d7e7f7dbf6ec379a43b48e4b36aeb0\n\nCurve = P-256\nPrivate = 334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce\nX = 3f2bf1589abf3047bf3e54ac9a95379bff95f8f55405f64eca36a7eebe8ffca7\nY = 5212a94e66c5ae9a8991872f66a72723d80ec5b2e925745c456f5371943b3a06\nPeerX = 45fb02b2ceb9d7c79d9c2fa93e9c7967c2fa4df5789f9640b24264b1e524fcb1\nPeerY = 5c6e8ecf1f7d3023893b7b1ca1e4d178972ee2a230757ddc564ffe37f5c5a321\nZ = 2adae4a138a239dcd93c243a3803c3e4cf96e37fe14e6a9b717be9599959b11c\n\nCurve = P-256\nPrivate = 2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d\nX = 29c0807f10cbc42fb45c9989da50681eead716daa7b9e91fd32e062f5eb92ca0\nY = ff1d6d1955d7376b2da24fe1163a271659136341bc2eb1195fc706dc62e7f34d\nPeerX = a19ef7bff98ada781842fbfc51a47aff39b5935a1c7d9625c8d323d511c92de6\nPeerY = e9c184df75c955e02e02e400ffe45f78f339e1afe6d056fb3245f4700ce606ef\nZ = 2e277ec30f5ea07d6ce513149b9479b96e07f4b6913b1b5c11305c1444a1bc0b\n\nCurve = P-256\nPrivate = 85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0\nX = 9cf4b98581ca1779453cc816ff28b4100af56cf1bf2e5bc312d83b6b1b21d333\nY = 7a5504fcac5231a0d12d658218284868229c844a04a3450d6c7381abe080bf3b\nPeerX = 356c5a444c049a52fee0adeb7e5d82ae5aa83030bfff31bbf8ce2096cf161c4b\nPeerY = 57d128de8b2a57a094d1a001e572173f96e8866ae352bf29cddaf92fc85b2f92\nZ = 1e51373bd2c6044c129c436e742a55be2a668a85ae08441b6756445df5493857\n\nCurve = P-384\nPrivate = 3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1\nX = 9803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5f\nY = ba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99\nPeerX = a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066\nPeerY = ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a\nZ = 5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1\n\nCurve = P-384\nPrivate = 92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783\nX = ea4018f5a307c379180bf6a62fd2ceceebeeb7d4df063a66fb838aa35243419791f7e2c9d4803c9319aa0eb03c416b66\nY = 68835a91484f05ef028284df6436fb88ffebabcdd69ab0133e6735a1bcfb37203d10d340a8328a7b68770ca75878a1a6\nPeerX = 30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0\nPeerY = 25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757\nZ = a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff\n\nCurve = P-384\nPrivate = 12cf6a223a72352543830f3f18530d5cb37f26880a0b294482c8a8ef8afad09aa78b7dc2f2789a78c66af5d1cc553853\nX = fcfcea085e8cf74d0dced1620ba8423694f903a219bbf901b0b59d6ac81baad316a242ba32bde85cb248119b852fab66\nY = 972e3c68c7ab402c5836f2a16ed451a33120a7750a6039f3ff15388ee622b7065f7122bf6d51aefbc29b37b03404581b\nPeerX = 1aefbfa2c6c8c855a1a216774550b79a24cda37607bb1f7cc906650ee4b3816d68f6a9c75da6e4242cebfb6652f65180\nPeerY = 419d28b723ebadb7658fcebb9ad9b7adea674f1da3dc6b6397b55da0f61a3eddacb4acdb14441cb214b04a0844c02fa3\nZ = 3d2e640f350805eed1ff43b40a72b2abed0a518bcebe8f2d15b111b6773223da3c3489121db173d414b5bd5ad7153435\n\nCurve = P-384\nPrivate = 8dd48063a3a058c334b5cc7a4ce07d02e5ee6d8f1f3c51a1600962cbab462690ae3cd974fb39e40b0e843daa0fd32de1\nX = e38c9846248123c3421861ea4d32669a7b5c3c08376ad28104399494c84ff5efa3894adb2c6cbe8c3c913ef2eec5bd3c\nY = 9fa84024a1028796df84021f7b6c9d02f0f4bd1a612a03cbf75a0beea43fef8ae84b48c60172aadf09c1ad016d0bf3ce\nPeerX = 8bc089326ec55b9cf59b34f0eb754d93596ca290fcb3444c83d4de3a5607037ec397683f8cef07eab2fe357eae36c449\nPeerY = d9d16ce8ac85b3f1e94568521aae534e67139e310ec72693526aa2e927b5b322c95a1a033c229cb6770c957cd3148dd7\nZ = 6a42cfc392aba0bfd3d17b7ccf062b91fc09bbf3417612d02a90bdde62ae40c54bb2e56e167d6b70db670097eb8db854\n\nCurve = P-384\nPrivate = 84ece6cc3429309bd5b23e959793ed2b111ec5cb43b6c18085fcaea9efa0685d98a6262ee0d330ee250bc8a67d0e733f\nX = 3222063a2997b302ee60ee1961108ff4c7acf1c0ef1d5fb0d164b84bce71c431705cb9aea9a45f5d73806655a058bee3\nY = e61fa9e7fbe7cd43abf99596a3d3a039e99fa9dc93b0bdd9cad81966d17eeaf557068afa7c78466bb5b22032d1100fa6\nPeerX = eb952e2d9ac0c20c6cc48fb225c2ad154f53c8750b003fd3b4ed8ed1dc0defac61bcdde02a2bcfee7067d75d342ed2b0\nPeerY = f1828205baece82d1b267d0d7ff2f9c9e15b69a72df47058a97f3891005d1fb38858f5603de840e591dfa4f6e7d489e1\nZ = ce7ba454d4412729a32bb833a2d1fd2ae612d4667c3a900e069214818613447df8c611de66da200db7c375cf913e4405\n\nCurve = P-384\nPrivate = 68fce2121dc3a1e37b10f1dde309f9e2e18fac47cd1770951451c3484cdb77cb136d00e731260597cc2859601c01a25b\nX = 868be0e694841830e424d913d8e7d86b84ee1021d82b0ecf523f09fe89a76c0c95c49f2dfbcf829c1e39709d55efbb3b\nY = 9195eb183675b40fd", @@ -2388,40 +2403,186 @@ static const char *kData36[] = { "fd3e0faceb636b34ed17e044a9f249dae8fc132e937e2d9349cd2ed77bb1049ceb692a2ec5b17ad61502a64c\nY = 001ec91d3058573fa6c0564a02a1a010160c313bc7c73510dc983e5461682b5be00dbce7e2c682ad73f29ca822cdc111f68fabe33a7b384a648342c3cdb9f050bcdb\nPeerX = 017200b3f16a68cbaed2bf78ba8cddfb6cffac262bba00fbc25f9dc72a07ce59372904899f364c44cb264c097b647d4412bee3e519892d534d9129f8a28f7500fee7\nPeerY = 00baba8d672a4f4a3b63de48b96f56e18df5d68f7d70d5109833f43770d6732e06b39ad60d93e5b43db8789f1ec0aba47286a39ea584235acea757dbf13d53b58364\nZ = 0101e462e9d9159968f6440e956f11dcf2227ae4aea81667122b6af9239a291eb5d6cf5a4087f358525fcacfa46bb2db01a75af1ba519b2d31da33eda87a9d565748\n\nCurve = P-521\nPrivate = 005bacfff268acf6553c3c583b464ea36a1d35e2b257a5d49eb3419d5a095087c2fb4d15cf5bf5af816d0f3ff7586490ccd3ddc1a98b39ce63749c6288ce0dbdac7d\nX = 0036e488da7581472a9d8e628c58d6ad727311b7e6a3f6ae33a8544f34b09280249020be7196916fafd90e2ec54b66b5468d2361b99b56fa00d7ac37abb8c6f16653\nY = 011edb9fb8adb6a43f4f5f5fdc1421c9fe04fc8ba46c9b66334e3af927c8befb4307104f299acec4e30f812d9345c9720d19869dbfffd4ca3e7d2713eb5fc3f42615\nPeerX = 004efd5dbd2f979e3831ce98f82355d6ca14a5757842875882990ab85ab9b7352dd6b9b2f4ea9a1e95c3880d65d1f3602f9ca653dc346fac858658d75626f4d4fb08\nPeerY = 0061cf15dbdaa7f31589c98400373da284506d70c89f074ed262a9e28140796b7236c2eef99016085e71552ff488c72b7339fefb7915c38459cb20ab85aec4e45052\nZ = 0141d6a4b719ab67eaf04a92c0a41e2dda78f4354fb90bdc35202cc7699b9b04d49616f82255debf7bbec045ae58f982a66905fcfae69d689785e38c868eb4a27e7b\n\nCurve = P-521\nPrivate = 008e2c93c5423876223a637cad367c8589da69a2d0fc68612f31923ae50219df2452e7cc92615b67f17b57ffd2f52b19154bb40d7715336420fde2e89fee244f59dc\nX = 00fa3b35118d6c422570f724a26f90b2833b19239174cea081c53133f64db60d6940ea1261299c04c1f4587cdb0c4c39616479c1bb0c146799a118032dcf98f899c0\nY = 0069f040229006151fa32b51f679c8816f7c17506b403809dc77cd58a2aec430d94d13b6c916de99f355aa45fcfbc6853d686c71be496a067d24bfaea4818fc51f75\nPeerX = 0129891de0cf3cf82e8c2cf1bf90bb296fe00ab08ca45bb7892e0e227a504fdd05d2381a4448b68adff9c4153c87eacb78330d8bd52515f9f9a0b58e85f446bb4e10\nPeerY = 009edd679696d3d1d0ef327f200383253f6413683d9e4fcc87bb35f112c2f110098d15e5701d7ceee416291ff5fed85e687f727388b9afe26a4f6feed560b218e6bb\nZ = 00345e26e0abb1aac12b75f3a9cf41efe1c336396dffa4a067a4c2cfeb878c68b2b045faa4e5b4e6fa4678f5b603c351903b14bf9a6a70c439257199a640890b61d1\n\nCurve = P-521\nPrivate = 0004d49d39d40d8111bf16d28c5936554326b197353eebbcf47545393bc8d3aaf98f14f5be7074bfb38e6cc97b989754074daddb3045f4e4ce745669fdb3ec0d5fa8\nX = 012ec226d050ce07c79b3df4d0f0891f9f7adf462e8c98dbc1a2a14f5e53a3f5ad894433587cc429a8be9ea1d84fa33b1803690dae04da7218d30026157fc995cf52\nY = 004837dfbf3426f57b5c793269130abb9a38f618532211931154db4eeb9aede88e57290f842ea0f2ea9a5f74c6203a3920fe4e305f6118f676b154e1d75b9cb5eb88\nPeerX = 01a3c20240e59f5b7a3e17c275d2314ba1741210ad58b71036f8c83cc1f6b0f409dfdd9113e94b67ec39c3291426c23ffcc447054670d2908ff8fe67dc2306034c5c\nPeerY = 01d2825bfd3af8b1e13205780c137fe938f84fde40188e61ea02cead81badfdb425c29f7d7fb0324debadc10bbb93de68f62c35069268283f5265865db57a79f7bf7\nZ = 006fe9de6fb8e672e7fd150fdc5e617fabb0d43906354ccfd224757c7276f7a1010091b17ed072074f8d10a5ec971eb35a5cb7076603b7bc38d432cbc059f80f9488\n\nCurve = P-521\nPrivate = 011a5d1cc79cd2bf73ea106f0e60a5ace220813b53e27b739864334a07c03367efda7a4619fa6eef3a9746492283b3c445610a023a9cc49bf4591140384fca5c8bb5\nX = 00eb07c7332eedb7d3036059d35f7d2288d4377d5f42337ad3964079fb120ccd4c8bd384b585621055217023acd9a94fcb3b965bfb394675e788ade41a1de73e620c\nY = 00491a835de2e6e7deb7e090f4a11f2c460c0b1f3d5e94ee8d751014dc720784fd3b54500c86ebaef18429f09e8e876d5d1538968a030d7715dde99f0d8f06e29d59\nPeerX = 007e2d138f2832e345ae8ff65957e40e5ec7163f016bdf6d24a2243daa631d878a4a16783990c722382130f9e51f0c1bd6ff5ac96780e48b68f5dec95f42e6144bb5\nPeerY = 00b0de5c896791f52886b0f09913e26e78dd0b69798fc4df6d95e3ca708ecbcbcce1c1895f5561bbabaae372e9e67e6e1a3be60e19b470cdf673ec1fc393d3426e20\nZ = 01e4e759ecedce1013baf73e6fcc0b92451d03bdd50489b78871c333114990c9ba6a9b2fc7b1a2d9a1794c1b60d9279af6f146f0bbfb0683140403bfa4ccdb524a29\n\nCurve = P-521\nPrivate = 010c908caf1be74c616b625fc8c1f514446a6aec83b5937141d6afbb0a8c7666a7746fa1f7a6664a2123e8cdf6cd8bf836c56d3c0ebdcc980e43a186f938f3a78ae7\nX = 0031890f4c7abec3f723362285d77d2636f876817db3bbc88b01e773597b969ff6f013ea470c854ab4a7739004eb8cbea69b82ddf36acadd406871798ecb2ac3aa7f\nY = 00d8b429ae3250266b9643c0c765a60dc10155bc2531cf8627296f4978b6640a9e600e19d0037d58503fa80799546a814d7478a550aa90e5ebeb052527faaeae5d08\nPeerX = 00118c36022209b1af8ebad1a12b566fc48744576e1199fe80de1cdf851cdf03e5b9091a8f7e079e83b7f827259b691d0c22ee29d6bdf73ec7bbfd746f2cd97a357d\nPeerY = 00da5ff4904548a342e2e7ba6a1f4ee5f840411a96cf63e6fe622f22c13e614e0a847c11a1ab3f1d12cc850c32e095614ca8f7e2721477b486e9ff40372977c3f65c\nZ = 0163c9191d651039a5fe985a0eea1eba018a40ab1937fcd2b61220820ee8f2302e9799f6edfc3f5174f369d672d377ea8954a8d0c8b851e81a56fda95212a6578f0e\n\nCurve = P-521\nPrivate = 01b37d6b7288de671360425d3e5ac1ccb21815079d8d73431e9b74a6f0e7ae004a357575b11ad66642ce8b775593eba9d98bf25c75ef0b4d3a2098bbc641f59a2b77\nX = 00189a5ee34de7e35aefeaeef9220c18071b4c29a4c3bd9d954458bd3e82a7a34da34cff5579b8101c065b1f2f527cf4581501e28ef5671873e65267733d003520af\nY = 01eb4bc50a7b4d4599d7e3fa773ddb9eb252c9b3422872e544bdf75c7bf60f5166ddc11eb08fa7c30822dabaee373ab468eb2d922e484e2a527fff2ebb804b7d9a37\nPeerX = 01780edff1ca1c03cfbe593edc6c049bcb2860294a92c355489d9afb2e702075ade1c953895a456230a0cde905de4a3f38573dbfcccd67ad6e7e93f0b5581e926a5d\nPeerY = 00a5481962c9162962e7f0ebdec936935d0eaa813e8226d40d7f6119bfd940602380c86721e61db1830f51e139f210000bcec0d8edd39e54d73a9a129f95cd5fa979\nZ = 015d613e267a36342e0d125cdad643d80d97ed0600afb9e6b9545c9e64a98cc6da7c5aaa3a8da0bdd9dd3b97e9788218a80abafc106ef065c8f1c4e1119ef58d298b\n\nCurve = P-521\nPrivate = 00f2661ac762f60c5fff23be5d969ccd4ec6f98e4e72618d12bdcdb9b4102162333788c0bae59f91cdfc172c7a1681ee44d96ab2135a6e5f3415ebbcd55165b1afb0\nX = 00a8e25a6902d687b4787cdc94c364ac7cecc5c495483ed363dc0aa95ee2bd739c4c4d46b17006c728b076350d7d7e54c6822f52f47162a25109aaaba690cab696ec\nY = 0168d2f08fe19e4dc9ee7a195b03c9f7fe6676f9f520b6270557504e72ca4394a2c6918625e15ac0c51b8f95cd560123653fb8e8ee6db961e2c4c62cc54e92e2a2a9\nPeerX = 016dacffa183e5303083a334f765de724ec5ec9402026d4797884a9828a0d321a8cfac74ab737fe20a7d6befcfc73b6a35c1c7b01d373e31abc192d48a4241a35803\nPeerY = 011e5327cac22d305e7156e559176e19bee7e4f2f59e86f1a9d0b6603b6a7df1069bde6387feb71587b8ffce5b266e1bae86de29378a34e5c74b6724c4d40a719923\nZ = 014d6082a3b5ced1ab8ca265a8106f302146c4acb8c30bb14a4c991e3c82a9731288bdb91e0e85bda313912d06384fc44f2153fb13506fa9cf43c9aab5750988c943\n\nCurve = P-521\nPrivate = 00f430ca1261f09681a9282e9e970a9234227b1d5e58d558c3cc6eff44d1bdf53de16ad5ee2b18b92d62fc79586116b0efc15f79340fb7eaf5ce6c44341dcf8dde27\nX = 006c1d9b5eca87de1fb871a0a32f807c725adccde9b3967453a71347d608f0c030cd09e338cdecbf4a02015bc8a6e8d3e2595fe773ffc2fc4e4a55d0b1a2cc00323b\nY = 01141b2109e7f4981c952aa818a2b9f6f5c41feccdb7a7a45b9b4b672937771b008cae5f934dfe3fed10d383ab1f38769c92ce88d9be5414817ecb073a31ab368ccb\nPeerX = 00a091421d3703e3b341e9f1e7d58f8cf7bdbd1798d001967b801d1cec27e605c580b2387c1cb464f55ce7ac80334102ab03cfb86d88af76c9f4129c01bedd3bbfc4\nPeerY = 008c9c577a8e6fc446815e9d40baa66025f15dae285f19eb668ee60ae9c98e7ecdbf2b2a68e22928059f67db188007161d3ecf397e0883f0c4eb7eaf7827a62205cc\nZ = 0020c00747cb8d492fd497e0fec54644bf027d418ab686381f109712a99cabe328b9743d2225836f9ad66e5d7fed1de247e0da92f60d5b31f9e47672e57f710598f4\n\nCurve = P-521\nPrivate = 005dc33aeda03c2eb233014ee468dff753b72f73b00991043ea353828ae69d4cd0fadeda7bb278b535d7c57406ff2e6e473a5a4ff98e90f90d6dadd25100e8d85666\nX = 00c825ba307373cec8dd2498eef82e21fd9862168dbfeb83593980ca9f82875333899fe94f137daf1c4189eb502937c3a367ea7951ed8b0f3377fcdf2922021d46a5\nY = 016b8a2540d5e65493888bc337249e67c0a68774f3e8d81e3b4574a0125165f0bd58b8af9de74b35832539f95c3cd9f1b759408560aa6851ae3ac7555347b0d3b13b\nPeerX = 004f38816681771289ce0cb83a5e29a1ab06fc91f786994b23708ff08a08a0f675b809ae99e9f9967eb1a49f196057d69e50d6dedb4dd2d9a81c02bdcc8f7f518460\nPeerY = 009efb244c8b91087de1eed766500f0e81530752d469256ef79f6b965d8a2232a0c2dbc4e8e1d09214bab38485be6e357c4200d073b52f04e4a16fc6f5247187aecb\nZ = 00c2bfafcd7fbd3e2fd1c", "750fdea61e70bd4787a7e68468c574ee99ebc47eedef064e8944a73bcb7913dbab5d93dca660d216c553622362794f7a2acc71022bdb16f\n\nCurve = P-521\nPrivate = 00df14b1f1432a7b0fb053965fd8643afee26b2451ecb6a8a53a655d5fbe16e4c64ce8647225eb11e7fdcb23627471dffc5c2523bd2ae89957cba3a57a23933e5a78\nX = 004e8583bbbb2ecd93f0714c332dff5ab3bc6396e62f3c560229664329baa5138c3bb1c36428abd4e23d17fcb7a2cfcc224b2e734c8941f6f121722d7b6b94154576\nY = 01cf0874f204b0363f020864672fadbf87c8811eb147758b254b74b14fae742159f0f671a018212bbf25b8519e126d4cad778cfff50d288fd39ceb0cac635b175ec0\nPeerX = 01a32099b02c0bd85371f60b0dd20890e6c7af048c8179890fda308b359dbbc2b7a832bb8c6526c4af99a7ea3f0b3cb96ae1eb7684132795c478ad6f962e4a6f446d\nPeerY = 017627357b39e9d7632a1370b3e93c1afb5c851b910eb4ead0c9d387df67cde85003e0e427552f1cd09059aad0262e235cce5fba8cedc4fdc1463da76dcd4b6d1a46\nZ = 01aaf24e5d47e4080c18c55ea35581cd8da30f1a079565045d2008d51b12d0abb4411cda7a0785b15d149ed301a3697062f42da237aa7f07e0af3fd00eb1800d9c41\n", }; -static const size_t kLen37 = 136462; +static const size_t kLen34 = 139668; -static const char *kData37[] = { - "# Public key algorithm tests\n\n# Keys used for PKEY operations.\n\n# RSA 2048 bit key.\nPrivateKey = RSA-2048\nType = RSA\nInput = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The public half of the same key encoded as a SubjectPublicKeyInfo.\nPublicKey = RSA-2048-SPKI\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key but with a negative RSA modulus.\nPublicKey = RSA-2048-SPKI-Negative\nInput = 30820121300d06092a864886f70d01010105000382010e003082010902820100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = NEGATIVE_NUMBER\n\n# The same key but with missing parameters rather than a NULL.\nPublicKey = RSA-2048-SPKI-Invalid\nInput = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = DECODE_ERROR\n\n# The same key but with an incorrectly-encoded length prefix.\nPublicKey = RSA-2048-SPKI-Invalid2\nInput = 3083000122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = DECODE_ERROR\n\n# RSA 512 bit key.\nPrivateKey = RSA-512\nType = RSA\nInput = 30820154020100300d06092a864886f70d01010105000482013e3082013a020100024100dd20403d976a38c9d79152d87b5c8e9f05033eadd7b7de709bf5b0c4a5182a97d18483526b02362b992e154a9f37faa396ca2685cdab8fec09877ebe705f4dd70203010001024055bebcca655d7e39de8a6eaa9d636db682161907064039544755c53eeb99ec618c03a210dbc61471eaba10c5c365c9726d6b7a96f54d455f7d168d49367270e1022100f21a05d9fd6817301ce49ce10448f9bdd44f5ef5b7557cd7d83155db46382ae7022100e9d1f7157783db2feab1936954ddc4e83aa365695868144cda1be6813b61d791022100d6001eb0040920860ce41fafdf23ca6dfbdf74e6e9f98cf3164cf5c16f9e727d02206f6f73f4b52b10517be6f9bc5f87fa0a3bb817e2e711636b651f9af1c85d4f21022063eff2e57f5b4ca20342cfe793e25526624e3692f192461f9e1ce7f13f2d72c8\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# RSA 515 bit key.\nPrivateKey = RSA-515\nType = RSA\nInput = 30820157020100300d06092a864886f70d0101010500048201413082013d0201000241054fa166e205e658bbe8a2dc35311c0c2b75b7e4569fd9642c8bae809279271fc824f26baa1166ea46298ca63379ea76adbada2b61e5066820a35beaec1aca227f020301000102410266c972be0d30e53ac2acb1aa13b4bd0401cccf212452a66b4615f7e943831f67b4ca48560582d0ca886044aaaaf87945252a848c1947944186e6eb83969bf91102210309e631761842cc8a2ccfd372c20a9cba21de1a199c30ab440bc6b51079f4e825022101bf715c1db432627ca7c29a293b9210f2eff1e92d12f306ebaa5334f8ee03dcd30221018ac58a765f2b8f37d434081fe5ff92b81735ead2f263f4968ccf63d61fbe3d0d0221015b247a1159a2d5a25d0db049593c6405f77f3a278c521d066e290c2a2d8fb59d0221026224aa31fd95c14d24fd03b8a195bba4cc88df7c37f5370a5ab19f882f1404d6\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# EC P-256 key\nPrivateKey = P-256\nType = EC\nInput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above with the optional public key omitted.\nPrivateKey = P-256-MissingPublic\nType = EC\nInput = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above with redundant parameters.\nPrivateKey = P-256-ExtraParameters\nType = EC\nInput = 308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00a06082a8648ce3d030107a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\n# The key re-encodes with the parameters removed.\nOutput = 308187020100301306072a8648c", - "e3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key, but with the redundant parameters in the ECPrivateKey mismatched.\nPrivateKey = P-256-BadInnerParameters\nInput = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = GROUP_MISMATCH\n\n# The same key, but with the curve spelled explicitly.\nPrivateKey = P-256-ExplicitParameters\nType = EC\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nOutput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but with the optional cofactor omitted.\nPrivateKey = P-256-ExplicitParameters-NoCofactor\nType = EC\nInput = 3082015e0201003081e906072a8648ce3d02013081dd020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nOutput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but the cofactor is zero instead of one.\nPrivateKey = P-256-ExplicitParameters-CofactorZero\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020100046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = UNKNOWN_GROUP\n\n# The same as above, but the cofactor is two instead of one.\nPrivateKey = P-256-ExplicitParameters-CofactorTwo\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020102046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = UNKNOWN_GROUP\n\n# The public half of the same key encoded as a PublicKey.\nPublicKey = P-256-SPKI\nType = EC\nInput = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but with the curve explicitly spelled out.\nPublicKey = P-256-SPKI\nInput = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# The same as above, but with trailing data after the curve name.\nPublicKey = P-256-SPKI\nInput = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# A DSA private key.\nPrivateKey = DSA-1024\nType = DSA\nInput = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# A DSA public key.\nPublicKey = DSA-1024-SPKI\nType = DSA\nInput = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc55983", - "03818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above, but without the parameters.\nPublicKey = DSA-1024-SPKI-No-Params\nType = DSA\nInput = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# Private keys from RFC 8032.\nPrivateKey = Ed25519\nType = Ed25519\nInput = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nExpectRawPrivate = 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nExpectRawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\n\nPrivateKey = Ed25519-2\nType = Ed25519\nInput = 302e020100300506032b6570042204204ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb\nExpectRawPrivate = 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb\nExpectRawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\n\nPrivateKey = Ed25519-3\nType = Ed25519\nInput = 302e020100300506032b657004220420c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7\nExpectRawPrivate = c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7\nExpectRawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\n\nPrivateKey = Ed25519-4\nType = Ed25519\nInput = 302e020100300506032b657004220420f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5\nExpectRawPrivate = f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5\nExpectRawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\n\nPrivateKey = Ed25519-5\nType = Ed25519\nInput = 302e020100300506032b657004220420833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42\nExpectRawPrivate = 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42\nExpectRawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\n\n# Public keys from RFC 8032.\nPublicKey = Ed25519-SPKI\nType = Ed25519\nInput = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nExpectNoRawPrivate\nExpectRawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\n\nPublicKey = Ed25519-SPKI-2\nType = Ed25519\nInput = 302a300506032b65700321003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\nExpectNoRawPrivate\nExpectRawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\n\nPublicKey = Ed25519-SPKI-3\nType = Ed25519\nInput = 302a300506032b6570032100fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\nExpectNoRawPrivate\nExpectRawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\n\nPublicKey = Ed25519-SPKI-4\nType = Ed25519\nInput = 302a300506032b6570032100278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\nExpectNoRawPrivate\nExpectRawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\n\nPublicKey = Ed25519-SPKI-5\nType = Ed25519\nInput = 302a300506032b6570032100ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\nExpectNoRawPrivate\nExpectRawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\n\n# The first key, private and public, with invalid NULL parameters.\nPrivateKey = Ed25519-NULL\nInput = 3030020100300706032b65700500042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nError = DECODE_ERROR\n\nPublicKey = Ed25519-SPKI-NULL\nInput = 302c300706032b65700500032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nError = DECODE_ERROR\n\n# Sample public key from RFC 8410.\nPublicKey = Ed25519-SPKI-Spec\nType = Ed25519\nInput = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1\n\n# Sample private key from RFC 8410.\nPrivateKey = Ed25519-Spec\nType = Ed25519\nInput = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842\n\n\n# RSA tests\n\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\n# Digest too long\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too short\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too large for key.\nSign = RSA-512\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DIGEST_TOO_BIG_FOR_RSA_KEY\n\n# Mismatched digest\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99", - "b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = BAD_SIGNATURE\n\n# Corrupted signature\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae\nError = BLOCK_TYPE_IS_NOT_01\n\n# parameter missing (NOTE: this differs from upstream)\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c\nError = BAD_SIGNATURE\n\n# embedded digest too long\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# embedded digest too short\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# Garbage after DigestInfo\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274\nError = BAD_SIGNATURE\n\n# invalid tag for parameter\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 49525db4d44c755e560cba980b1d85ea604b0e077fcadd4ba44072a3487bbddb835016200a7d8739cce2dc3223d9c20cbdd25059ab02277f1f21318efd18e21038ec89aa9d40680987129e8b41ba33bceb86518bdf47268b921cce2037acabca6575d832499538d6f40cdba0d40bd7f4d8ea6ca6e2eec87f294efc971407857f5d7db09f6a7b31e301f571c6d82a5e3d08d2bb3a36e673d28b910f5bec57f0fcc4d968fd7c94d0b9226dec17f5192ad8b42bcab6f26e1bea1fdc3b958199acb00f14ebcb2a352f3afcedd4c09000128a603bbeb9696dea13040445253972d46237a25c7845e3b464e6984c2348ea1f1210a9ff0b00d2d72b50db00c009bb39f9\nError = BAD_SIGNATURE\n\n\n# RSA-PSS tests.\n\n# Zero salt length makes the output deterministic\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Verify of above signature\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# A non-zero salt length must be checked by round-tripping.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Check a salt length with a non-standard digest length, to verify things are\n# not just working due to defaults. (The current default is a maximum salt\n# length, but the ecosystem has converged on matching the digest length, so we\n# may change this in the future.)\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 42\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Auto-detected salt length\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Signing with salt length -1 means to match the digest length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nVerifyPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Signing with salt length -2 means to maximize the salt length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -2\nVerifyPSSSaltLength = 222 # 256 - 32 - 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Wrong digest\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"00000000000000000000000000000000\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDE\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abba", - "c37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too long\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF0\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Wrong salt length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong salt length using implicit hash length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-1\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA1\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-1, this input happens to succeed recovering a salt length, but it does\n# not match.\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-384\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA384\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-384, this input happens fail to recover the salt length altogether.\nError = SLEN_RECOVERY_FAILED\n\n# The salt length is too large for the modulus (signing).\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\n# The salt length is too large for the modulus (verifying).\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = DATA_TOO_LARGE\n\n# The hash is too large for the modulus (signing).\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\n# The hash is too large for the modulus (verifying).\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nOutput = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nError = DATA_TOO_LARGE\n\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nOutput = 457001d9ca50a93385fc5ec721c9dbbe7a0f2e9e4a2f846a30a8811dde66347b83901c7492039243537c7a667fafffd69049bcbd36afd0010d9b425e2d8785c1\nError = DATA_TOO_LARGE\n\n# Sample RSA-515 signature.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 00c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\n\n# The above, but with too few leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above, but with too many leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 0000c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above with an invalid leading byte. The top few bits of EM are required to\n# be cleared.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 007f803c832a2090aea04013d9fa9c1630732a1625232826d235f0950f7050d3fb0eb06ef9ea8b260fad68e1165a2d770a8c7fc7a8aaa68620b021fc19c97e0041\nError = FIRST_OCTET_INVALID\n\n# The above with an invalid trailing byte.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 03e68555035891eb08d96c0967db22328cd892ad2856d88516ecb946bfdba732bb029b5c0dfa2119ed7349897d2324e95e86d91d0c4afc82700a36db8933abbf58\nError = LAST_OCTET_INVALID\n\n# Non-zero salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e5706", - "92e511e139\n\n# Non-zero salt length, wrong salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 31\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\nError = SLEN_CHECK_FAILED\n\n# Non-zero salt length, match hash length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, auto-detected.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n\n# RSA decrypt\n\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a78\nOutput = \"Hello World\"\n\n# Corrupted ciphertext\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a79\nError = PKCS_DECODING_ERROR\n\n# OAEP padding\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5af\nOutput = \"Hello World\"\n\n# OAEP padding with label and custom hash.\nDecrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = 48b956c22b8e40cc38f0893672ddf488fc806cf1fcc6239c66dd8345eb543d6b5cac589e6c7ae86dac1c2436c4d72c48009a737b2c649e6000dbab17203e4d9c078bd70b649700a0830d4ddc396af0c48973177a229e48259d93247f04f76474c7611b530c66f020c4da2cc861c2e4104831ecc0336e0cb10d6520fdefd0b33606f5cdd736dd439583b9b6011cce99623c93caf5f76e21e9fefab414795dd5ac12cba551be74ebf266834fcffab182c5e7c9b6c064df154cb26ddfd4fe2fd87590005f4bf45e776a0082803e9f68995b8eeb4c6802c67b5ef349e5b2dc0cf7a12fc097030f2bd28f0253f17129b04c82993a12957728b35880fdd2f8d0cc469f\nOutput = \"Hello World\"\n\n# OAEP padding, corrupted ciphertext\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5ac\nError = OAEP_DECODING_ERROR\n\n# Test that RSA encryption successfully round-trips through decryption\n# with various parameters.\nEncrypt = RSA-2048\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = \"Hello World\"\nCheckDecrypt\n\n# Though we will never generate such a key, test that RSA keys where p < q work\n# properly.\nPrivateKey = RSA-Swapped\nType = RSA\nInput = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429\n\nSign = RSA-Swapped\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f\n\n# Though we will never generate such a key, test that RSA keys where p and q are\n# different sizes work properly.\nPrivateKey = RSA-PrimeMismatch\nType = RSA\nInput = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d244010", - "52b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c\n\nSign = RSA-PrimeMismatch\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 6192b1ce630c87d02e8245fd74d4f6ecac37eef979d188c8fa48c4d355fbe814e7dd3152f42bb020d769b540d11867af5b947387b8c99158d56901ff3708e423931178213916ae1002f162c9d497aacacdcb20e6ffe7ed40138a253fc943ddf3587433df5831a3ce46aeefce358a009bf6bad12d82d77424c2755d984d7da196\n\n\n# EC tests\n\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\nVerify = P-256-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\n# Digest too long\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest invalid\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1235\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Invalid signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7\nError = BAD_SIGNATURE\n\n# Garbage after signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800\nError = BAD_SIGNATURE\n\n# BER signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000\nError = BAD_SIGNATURE\n\n\n# Additional RSA-PSS and RSA-OAEP tests converted from\n# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip\n\nPublicKey = RSA-PSS-1\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a21370203010001\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = cd8b6538cb8e8de566b68bd067569dbf1ee2718e\nOutput = 9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e35befc17a1d160b9ce35fbd8eb16e7ee491d3fd\nOutput = 3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0652ec67bcee30f9d2699122b91c19abdba89f91\nOutput = 666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 39c21c4cceda9c1adf839c744e1212a6437575ec\nOutput = 4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 36dae913b77bd17cae6e7b09453d24544cebb33c\nOutput = 1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 45eef191f4f79c31fe5d2ede7e5098994e929d2d\nOutput = 2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58\n\nPublicKey = RSA-PSS-2\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818101d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c90203010001\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 5c81a3e2a658246628cd0ee8b00bb4c012bc9739\nOutput = 014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 27f71611446aa6eabf037f7dedeede3203244991\nOutput = 010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 03ecc2c33e93f05fc7224fcc0d461356cb897217\nOutput = 007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c30742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84df0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6c4\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 246c727b4b9494849dddb068d582e179ac20999c\nOutput = 009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b40b\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e8617ca3ea66ce6a58ede2d11af8c3ba8a6ba912\nOutput = 00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181ecf\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7a6fdc1a4e434ecbc35d657ad49a2f4fafd43bc8\nOutput = 00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab38096e55fcbe3285c7aa558851254faffa92c1c72", - "b78758663ef4582843139d7a6\n\nPublicKey = RSA-PSS-3\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818102f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4430203010001\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3552be69dd74bdc56d2cf8c38ef7bafe269040fe\nOutput = 0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103bd57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b16797f\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 609143ff7240e55c062aba8b9e4426a781919bc9\nOutput = 02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf78641169179556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11af\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0afd22f879a9cda7c584f4135f8f1c961db114c0\nOutput = 0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa760649cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548aea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e3802c\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 405dd56d395ef0f01b555c48f748cc32b210650b\nOutput = 0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7ba7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836b8\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a2c313b0440c8a0c47233b87f0a160c61af3eae7\nOutput = 021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd83\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f1bf6ca7b4bbdbb6bf20a4bf55728725d177154a\nOutput = 012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bde03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab854586c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e5538ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426ce\n\nPublicKey = RSA-PSS-4\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37050203010001\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f8b0abf70fec0bca74f0accbc24f75e6e90d3bfd\nOutput = 0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 04a10944bfe11ab801e77889f3fd3d7f4ff0b629\nOutput = 049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ba01243db223eb97fb86d746c3148adaaa0ca344\nOutput = 03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefca0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af4163599090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc6217461d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2aad\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 934bb0d38d6836daec9de82a9648d4593da67cd2\nOutput = 0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba4298cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d4f\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ec35d81abd1cceac425a935758b683465c8bd879\nOutput = 022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b320b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb0a\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 72ce251d17b04dd3970d6ff1fbe3624899e9e941\nOutput = 00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b627b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a028c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5afd9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd562e\n\nPublicKey = RSA-PSS-5\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d003081890281810d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c19916391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d0191871740525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5070203010001\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d98b7061943510bc3dd9162f7169aabdbdcd0222\nOutput = 0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad0452915a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec1d\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ae8e699f754988f4fd645e463302e49a2552072\nOutput = 08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e220ad17997c0dd6e706630ba3e84add4d5e7ab004e58074b549709565d43ad9e97b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d158ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a34e\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8d46c7c05534c1ba2cc7624500d48a4531604bff\nOutput = 05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6fd019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b979\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ee3de96783fd0a157c8b20bf5566124124dcfe65\nOutput = 0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb63903204a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e49fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19daea1\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1204df0b03c2724e2709c23fc71789a21b00ae4c\nOutput = 0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681fcd\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 29926bc3280c841f601acd0d6f17ea38023eddbc\nOutput = 02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c1339e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f244a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a81266d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e8f\n\nPublicKey = RSA-PSS-6\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48bf5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698d10203010001\n\nV", - "erify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ab464e8cb65ae5fdea47a53fa84b234d6bfd52f6\nOutput = 04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a96a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45fe42892335362eee018b5b161f2f9393031225c713012a576bc88e23052489868d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85d1\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 92d0bcae82b641f578f040f5151be8eda6d42299\nOutput = 0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f393ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa4773\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3569bd8fd2e28f2443375efa94f186f6911ffc2b\nOutput = 086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a26bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f23706d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df456\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7abbb7b42de335730a0b641f1e314b6950b84f98\nOutput = 0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c559329f\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 55b7eb27be7a787a59eb7e5fac468db8917a7725\nOutput = 02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a356b\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = de2fa0367ef49083ff89b9905d3fd646fcc12c38\nOutput = 0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385ce99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83cc9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081ef\n\nPublicKey = RSA-PSS-7\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818137c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee18ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29ab30203010001\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8be4afbdd76bd8d142c5f4f46dba771ee5d6d29d\nOutput = 187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc810520bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b23dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c60555823\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 402140dc605b2f5c5ec0d15bce9f9ba8857fe117\nOutput = 10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce79429b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db815ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570eb8\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3e885205892ff2b6b37c2c4eb486c4bf2f9e7f20\nOutput = 2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a911865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0df9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebfb898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460af1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1fc2201d0c442a4736cd8b2cd00c959c47a3bf42\nOutput = 32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffabddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe19\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e4351b66819e5a31501f89acc7faf57030e9aac5\nOutput = 07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d989db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2f1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 49f6cc58365e514e1a3f301f4de16f9fb5347ff2\nOutput = 18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed3248903f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d796aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130ec0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d33\n\nPublicKey = RSA-PSS-8\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f0203010001\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a1dd230d8ead860199b6277c2ecfe3d95f6d9160\nOutput = 0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f6e68e53c602c5c65fa67b5aa6d786e5524b12ab\nOutput = 2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d6f9fcd3ae27f32bb2c7c93536782eba52af1f76\nOutput = 2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0ca446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee290356b8c4a29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db4084f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f96\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ff2a53ce2e2d900d468e498f230a5f5dd0020de\nOutput = 1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b5328571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300ccc7\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 4eb309f7022ba0b03bb78601b12931ec7c1be8d3\nOutput = 33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1eec31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673ee\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 65033bc2f67d6aba7d526acb873b8d9241e5e4d9\nOutput = 1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517ff9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e69463e\n\nPublicKey = RSA-PSS-9\nType = RSA\nInput = 3081df300d06092a864886f70d01010105000381cd003081c90281c100e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b0203010001\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2715a49b8b0012cd7aee84c116446e6dfe3faec0\nOutput = 586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964", - "747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2dac956d53964748ac364d06595827c6b4f143cd\nOutput = 80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 28d98c46cccafbd3bc04e72f967a54bd3ea12298\nOutput = 484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f981817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b605952019782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecde3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0866d2ff5a79f25ef668cd6f31b42dee421e4c0e\nOutput = 84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074ae0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 6a5b4be4cd36cc97dfde9995efbf8f097a4a991a\nOutput = 82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de8454810274cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afec7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b9dfd1df76a461c51e6576c6c8ed0a923d1c50e7\nOutput = a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaadeacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc460895f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f\n\nPublicKey = RSA-PSS-10\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea57b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7adcd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e391900992070df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a511001a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae050203010001\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 9596bb630cf6a8d4ea4600422b9eba8b13675dd4\nOutput = 82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b503319399277fd6c1c8f1033cbf04199ea21716\nOutput = 14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 50aaede8536b2c307208b275a67ae2df196c7628\nOutput = 6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = aa0b72b8b371ddd10c8ae474425ccccf8842a294\nOutput = 34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = fad3902c9750622a2bc672622c48270cc57d3ea8\nOutput = 7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 122196deb5d122bd8c6fc781ff6924d7c695aade\nOutput = 6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f\n\nPrivateKey = RSA-OAEP-1\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67d00707d609d", - "fd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a\nOutput = 6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44\nOutput = 750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb\nOutput = d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755\nOutput = 52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439\nOutput = 8da89fd9e5f974a29feffb462b49180f6cf9e802\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255\nOutput = 26521050844271\n\nPrivateKey = RSA-OAEP-2\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818101947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a60055c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f4502030100010281800823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8ccd1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab245941d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe3902410159dbde04a33ef06fb608b80b190f4d3e22bcc13ac8e4a081033abfa416edb0b338aa08b57309ea5a5240e7dc6e54378c69414c31d97ddb1f406db3769cc41a430241012b652f30403b38b40995fd6ff41a1acc8ada70373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822df031ba0df0dafd5506f568bd70240436ef508de736519c2da4c580d98c82cb7452a3fb5efadc3b9c7789a1bc6584f795addbbd32439c74686552ecb6c2c307a4d3af7f539eec157248c7b31f1a2550241012b15a89f3dfb2b39073e73f02bdd0c1a7b379dd435f05cdde2eff9e462948b7cec62ee9050d5e0816e0785a856b49108dcb75f3683874d1ca6329a19013066ff02400270db17d5914b018d76118b24389a7350ec836b0063a21721236fd8edb6d89b51e7eeb87b611b7132cb7ea7356c23151c1e7751507c786d9ee1794170a8c8e8\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e\nOutput = 8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245\nOutput = 2d\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053\nOutput = 74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641\nOutput = a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec\nOutput = 2ef2b066f854c33f3bdcbb5994a435e73d6c6c\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a\nOutput = 8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0\n\nPrivateKey = RSA-OAEP-3\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818102b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c1652006a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cbfad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43e9020301000102818015b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd024101bf01d216d73595cf0270c2beb78d40a0d8447d31da919a983f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de7fad9d555160958b4454127e0e7eaf0241018d3399658166db3829816d7b295416759e9c91987f5b2d8aecd63b04b48bd7b2fcf229bb7f8a6dc88ba13dd2e39ad55b6d1a06160708f9700be80b8fd3744ce7024006c0a249d20a6f2ee75c88b494d53f6aae99aa427c88c28b163a769445e5f390cf40c274fd6ea6329a5ce7c7ce03a2158396ee2a7845786e09e2885a9728e4e5024100d1d27c29fedd92d86c348edd0ccbfac14f746e051ce1d1811df35d61f2ee1c97d4bf2804802f6427187ba8e90a8af44243b4079b03445e602e29fa5193e64fe90241008cb2f756bd8941b1d3b770e5ad31ee373b28acda69ff9b6f40fe578b9f1afb85836f9627d37acff73c2779e634bb26011c2c8f7f3361ae2a9ea65ed689e3639a\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80\nOutput = 087820b569e8fa8d\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5\nOutput = 4653acaf17196", - "0b01f52a7be63a3ab21dc368ec43b50d82ec3781e04\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a\nOutput = d94cd0e08fa404ed89\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0\nOutput = 6cc641b6b61e6f963974dad23a9013284ef1\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60\nOutput = df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730\nOutput = 3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1\n\nPrivateKey = RSA-OAEP-4\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d020100028181051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e357625991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57dde4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb03902030100010281800411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb3651c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d4567f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d04010241027458c19ec1636919e736c9af25d609a51b8f561d19c6bf6943dd1ee1ab8a4a3f232100bd40b88decc6ba235548b6ef792a11c9de823d0a7922c7095b6eba570102410210ee9b33ab61716e27d251bd465f4b35a1a232e2da00901c294bf22350ce490d099f642b5375612db63ba1f20386492bf04d34b3c22bceb909d13441b53b5139024039fa028b826e88c1121b750a8b242fa9a35c5b66bdfd1fa637d3cc48a84a4f457a194e7727e49f7bcc6e5a5a412657fc470c7322ebc37416ef458c307a8c09010241015d99a84195943979fa9e1be2c3c1b69f432f46fd03e47d5befbbbfd6b1d1371d83efb330a3e020942b2fed115e5d02be24fd92c9019d1cecd6dd4cf1e54cc899024101f0b7015170b3f5e42223ba30301c41a6d87cbb70e30cb7d3c67d25473db1f6cbf03e3f9126e3e97968279a865b2c2b426524cfc52a683d31ed30eb984be412ba\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8\nOutput = 4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e\nOutput = b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065\nOutput = bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4\nOutput = fb2ef112f5e766eb94019297934794f7be2f6fc1c58e\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2\nOutput = 28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9\nOutput = f22242751ec6b1\n\nPrivateKey = RSA-OAEP-5\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281810aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c47576b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10ed902030100010281810256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a268f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa217588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528acfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2c5024103b0d3962f6d17549cbfca11294348dcf0e7e39f8c2bc6824f2164b606d687860dae1e632393cfedf513228229069e2f60e4acd7e633a436063f82385f48993707024102e4c32e2f517269b7072309f00c0e31365f7ce28b236b82912df239abf39572cf0ed604b02982e53564c52d6a05397de5c052a2fddc141ef7189836346aeb331f024101e84b119d25161fa67b00256a5bd9b645d2b232ecb05b015180029a88622adc3f09b3aeacde6161ab7cde22c2ad26e7797df54e072cbd3b2673800b3e4338dbd5024100eb90aa1a40135b4cea07197cedc8819be1e7cbff2547662116f465a4a9f487ab12f3ba4fef13822265a65297d98b7bded9372e3ffe81a38b3e9600fed055754f0241012f7f8138f9404062eb85a42924520b38f5bb886a0196f48bb8dcea60fd92cc027f18e78158a34a5c5d5f860a0f6c04071a7d01312c065062f1eb48b79d1c83cb\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5\nOutput = af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad\nOutput = a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967\nOutput = 308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a8", - "2cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf\nOutput = 15c5b9ee1185\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723\nOutput = 21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a\nOutput = 541e37b68b6c8872b84c02\n\nPrivateKey = RSA-OAEP-6\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f02010002818112b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c166db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722af02030100010281810295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d33261904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3f9024104a6ce8b7358dfa69bdcf742617005afb5385f5f3a58a24ef74a22a8c05cb7cc38ebd4cc9d9a9d789a62cd0f60f0cb941d3423c9692efa4fe3adff290c4749a38b02410404c9a803371fedb4c5be39f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4bf7befd2dd536ac946db797fdbc4abe8f29349b91ed024103961c8f760aa2bd5154c7aafd77225b3bacd0139ae7b5948ea3311fccd86fb95c75afa767284b9b2de559572f15d8d044c7eb83a1be5fadf2cc377c0d8475294b0241022197e066742196aabc03fa2feeb4e70b15cb787d617acd31bb75c7bc234ad706f7c48d2182d1f0ff9c228dcf41967b6c0ba6d2c0ad110a1b857831ec245e2cb102410401c4c0c53d45dbdb5e9d96d0fecf4275df0974bc4a0736b4a74c3269053efb686ace2406e22c9e058ddb4ae540627ae2fdb08261e8e7e4bcbc994daafa305c45\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3\nOutput = 4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f\nOutput = 5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65\nOutput = b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8\nOutput = 684e3038c5c041f7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab\nOutput = 32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470\nOutput = 50ba14be8462720279c306ba\n\nPrivateKey = RSA-OAEP-7\nType = RSA\nInput = 30820278020100300d06092a864886f70d0101010500048202623082025e020100028181311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d0732b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec3119051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3730203010001028181070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e0276174487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc296800adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21b102410749262c111cd470ec2566e6b3732fc09329469aa19071d3b9c01906514c6f1d26baa14beab0971c8b7e611a4f79009d6fea776928ca25285b0de3643d1a3f8c71024106bc1e50e96c02bf636e9eea8b899bbebf7651de77dd474c3e9bc23bad8182b61904c7d97dfbebfb1e00108878b6e67e415391d67942c2b2bf9b4435f88b0cb023024103bc7ea7f0aab143abc6ce8b97118636a30172e4cfe02c8fa0dda3b7baaf90f8092982985525f488bdfcb4bd726e22639ac64a3092ab7ffcbf1d5334cfa50b5bf102410262a6aa29c2a3c67dc5346c06381afd987aa3cc93cfbfecf54fdd9f9d787d7f59a523d398979da137a2f6381fe94801f7c94da21518dc34cb40870c4697994ad90240649d4c17b6ee1721e772d0389a559c3d3cdf9550d457c46b037b74641b1d52166af8a213c8396206cdfba4422f18d6f61dbcb5d214c971bf482aeb976a7370c2\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1\nOutput = 47aae909\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6\nOutput = 1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b\nOutput = d976fc\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac\nOutput = d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478\nOutput = bb47231ca5ea1d3ad46c99345d9a8a61\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d", - "1f62574842216ae674115\nOutput = 2184827095d35c3f86f600e8e59754013296\n\nPrivateKey = RSA-OAEP-8\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281815bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427ca9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e230f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f4631359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212dff702030100010281810f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf633102410a02ef8448d9fad8bbd0d004c8c2aa9751ef9721c1b0d03236a54b0df947cbaed5a255ee9e8e20d491ea1723fe094704a9762e88afd16ebb5994412ca966dc4f9f0241092d362e7ed3a0bfd9e9fd0e6c0301b6df29159cf50cc83b9b0cf4d6eea71a61e002b46e0ae9f2de62d25b5d7452d498b81c9ac6fc58593d4c3fb4f5d72dfbb0a9024107c71410af103962db367404e37ae850baa4e9c29dd92145815294a67c7d1c6ded263aa030a9b633ae50303e14035d1af014123eba687820308d8ebc85b6957d7d024100ae2c75380c02c016ad05891b3301de881f28ae1171182b6b2c83bea7c515eca9ca298c7b1cab5817a597068fc85060de4da8a016378aae43c7f967bcc37904b902410598d1059e3ada4f6320752c09d805ff7d1f1ae0d017aeeee9cefa0d7dd7ff775e44b578322f6405d6211da19519666aa87fdc4cd8c88f6b6e3d67e961dcbba3d0\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61\nOutput = 050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d\nOutput = 4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f\nOutput = 8604ac56328c1ab5ad917861\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0\nOutput = fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2\nOutput = 4a5f4914bee25de3c69341de07\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210\nOutput = 8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be\n\nPrivateKey = RSA-OAEP-9\nType = RSA\nInput = 30820397020100300d06092a864886f70d0101010500048203813082037d0201000281c100cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d902b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2ab18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d02030100010281c0198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d7205368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1026100fc8d6c04bec4eb9a8192ca7900cbe536e2e8b519decf33b2459798c6909df4f176db7d23190fc72b8865a718af895f1bcd9145298027423b605e70a47cf58390a8c3e88fc8c48e8b32e3da210dfbe3e881ea5674b6a348c21e93f9e55ea65efd026100d200d45e788aacea606a401d0460f87dd5c1027e12dc1a0d7586e8939d9cf789b40f51ac0442961de7d21cc21e05c83155c1f2aa9193387cfdf956cb48d153ba270406f9bbba537d4987d9e2f9942d7a14cbfffea74fecdda928d23e259f5ee1026100db16802f79a2f0d45f358d69fd33e44b81fae828622e93a54253e997d01b0743759da0e812b4aa4e6c8beab2328d5431955a418a67ff26a8c5c807a5da354e05ef31cc8cf758f463732950b03e265726fb94e39d6a572a26244ab08db75752ad026100a0a317cfe7df1423f87a6dee8451f4e2b4a67e5497f29b4f1e4e830b9fadd9401167026f5596e5a39c97817e0f5f16e27e19ec9902e01d7ea6fb9aa3c760afee1e381b69de6ac9c07585a06ad9c4ba00bf75c8ad2fa898a479e80ae294fed2a102600b21f335c353342eb44c3aa24445780c2d655b940174cae38c7c8a4e6493c0ba9fd303748267b083b9a7a6cb61e42db362b8c9896db7064e02ad5ae61587da15b4649c90594909feb37dbcb654beb7268ec801e5a8b4aa3911bebd88542f05be\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72\nOutput = f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8\nOutput = 81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3\nOutput = fd326429df9b890e09b54b18b8f34f1e24\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858\nOutput = f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8", - "a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e\nOutput = 53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f\nOutput = b6b28ea2198d0c1008bc64\n\nPrivateKey = RSA-OAEP-10\nType = RSA\nInput = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb020301000102820100056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e7902818100ecf5aecd1e5515fffacbd75a2816c6ebf49018cdfb4638e185d66a7396b6f8090f8018c7fd95cc34b857dc17f0cc6516bb1346ab4d582cadad7b4103352387b70338d084047c9d9539b6496204b3dd6ea442499207bec01f964287ff6336c3984658336846f56e46861881c10233d2176bf15a5e96ddc780bc868aa77d3ce76902818100bc46c464fc6ac4ca783b0eb08a3c841b772f7e9b2f28babd588ae885e1a0c61e4858a0fb25ac299990f35be85164c259ba1175cdd7192707135184992b6c29b746dd0d2cabe142835f7d148cc161524b4a09946d48b828473f1ce76b6cb6886c345c03e05f41d51b5c3a90a3f24073c7d74a4fe25d9cf21c75960f3fc386318302818100c73564571d00fb15d08a3de9957a50915d7126e9442dacf42bc82e862e5673ff6a008ed4d2e374617df89f17a160b43b7fda9cb6b6b74218609815f7d45ca263c159aa32d272d127faf4bc8ca2d77378e8aeb19b0ad7da3cb3de0ae7314980f62b6d4b0a875d1df03c1bae39ccd833ef6cd7e2d9528bf084d1f969e794e9f6c10281802658b37f6df9c1030be1db68117fa9d87e39ea2b693b7e6d3a2f70947413eec6142e18fb8dfcb6ac545d7c86a0ad48f8457170f0efb26bc48126c53efd1d16920198dc2a1107dc282db6a80cd3062360ba3fa13f70e4312ff1a6cd6b8fc4cd9c5c3db17c6d6a57212f73ae29f619327bad59b153858585ba4e28b60a62a45e490281806f38526b3925085534ef3e415a836ede8b86158a2c7cbfeccb0bd834304fec683ba8d4f479c433d43416e63269623cea100776d85aff401d3fff610ee65411ce3b1363d63a9709eede42647cea561493d54570a879c18682cd97710b96205ec31117d73b5f36223fadd6e8ba90dd7c0ee61d44e163251e20c7f66eb305117cb8\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc\nOutput = 8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795\nOutput = e6ad181f053b58a904f2457510373e57\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede\nOutput = 510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8\nOutput = bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0\nOutput = a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46\nOutput = eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac\n\n\n# Single-shot signing tests.\n\nSignMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111", - "d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048-SPKI\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = P-256\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 304502204c66004635c267394bd6857c1e0b53b22a2bab1ca7dff9d5c1b42143858b3ea7022100ae81228510e03cd49a8863d2ebd1c05fe0c87eacd1150433132b909994cd0dbd\n\n# Digest can't be omitted in many algorithms.\nSignMessage = RSA-2048\nInput = \"Hello world\"\nError = NO_DEFAULT_DIGEST\n\nVerifyMessage = RSA-2048\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\nError = NO_DEFAULT_DIGEST\n\n# Signing test vectors from RFC 8032.\nSignMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nSignMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nSignMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nSignMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nSignMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Signing with public keys is not allowed.\nSignMessage = Ed25519-SPKI\nInput = \"\"\nError = NOT_A_PRIVATE_KEY\n\n# Verify test vectors from RFC 8032. Test verifying with both the public and\n# private key.\nVerifyMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-SPKI-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-SPKI-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681", - "e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-SPKI-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\nVerifyMessage = Ed25519-SPKI-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Length is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a10\nError = INVALID_SIGNATURE\n\n# Message is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"Hello world\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = INVALID_SIGNATURE\n\n# Ed25519 does not support configuring a digest.\nSignMessage = Ed25519\nInput = \"\"\nDigest = SHA256\nError = COMMAND_NOT_SUPPORTED\n\n# Ed25519 does not support signing a pre-hashed value.\nSign = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\nVerify = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\n\n# Derive tests.\n\nPrivateKey = ECDH-P256-Private\nType = EC\nInput = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534\n\nPublicKey = ECDH-P256-Peer\nType = EC\nInput = 3059301306072a8648ce3d020106082a8648ce3d03010703420004700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac\n\nDerive = ECDH-P256-Private\nDerivePeer = ECDH-P256-Peer\nOutput = 46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b\nSmallBufferTruncates\n\nPrivateKey = X25519-Private\nType = X25519\nInput = 302e020100300506032b656e04220420a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4\nExpectRawPrivate = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4\n\nPublicKey = X25519-Peer\nType = X25519\nInput = 302a300506032b656e032100e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c\nExpectRawPublic = e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c\n\nPublicKey = X25519-SmallOrderPeer\nType = X25519\nExpectRawPublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\nInput = 302a300506032b656e032100e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\n\nDerive = X25519-Private\nDerivePeer = X25519-Peer\nOutput = c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552\n\nDerive = X25519-Private\nDerivePeer = X25519-SmallOrderPeer\nError = INVALID_PEER_KEY\n", +static const char *kData34[] = { + "# Public key algorithm tests\n\n# Keys used for PKEY operations.\n\n# RSA 2048 bit key.\nPrivateKey = RSA-2048\nType = RSA\nInput = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The public half of the same key encoded as a SubjectPublicKeyInfo.\nPublicKey = RSA-2048-SPKI\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key but with a negative RSA modulus.\nPublicKey = RSA-2048-SPKI-Negative\nInput = 30820121300d06092a864886f70d01010105000382010e003082010902820100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = NEGATIVE_NUMBER\n\n# An RSA key with an even modulus\nPublicKey = RSA-2048-Even-Modulus\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44e0203010001\nError = BAD_RSA_PARAMETERS\n\n# The same key but with missing parameters rather than a NULL.\nPublicKey = RSA-2048-SPKI-Invalid\nInput = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = DECODE_ERROR\n\n# The same key but with an incorrectly-encoded length prefix.\nPublicKey = RSA-2048-SPKI-Invalid2\nInput = 3083000122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001\nError = DECODE_ERROR\n\n# RSA 512 bit key.\nPrivateKey = RSA-512\nType = RSA\nInput = 30820154020100300d06092a864886f70d01010105000482013e3082013a020100024100dd20403d976a38c9d79152d87b5c8e9f05033eadd7b7de709bf5b0c4a5182a97d18483526b02362b992e154a9f37faa396ca2685cdab8fec09877ebe705f4dd70203010001024055bebcca655d7e39de8a6eaa9d636db682161907064039544755c53eeb99ec618c03a210dbc61471eaba10c5c365c9726d6b7a96f54d455f7d168d49367270e1022100f21a05d9fd6817301ce49ce10448f9bdd44f5ef5b7557cd7d83155db46382ae7022100e9d1f7157783db2feab1936954ddc4e83aa365695868144cda1be6813b61d791022100d6001eb0040920860ce41fafdf23ca6dfbdf74e6e9f98cf3164cf5c16f9e727d02206f6f73f4b52b10517be6f9bc5f87fa0a3bb817e2e711636b651f9af1c85d4f21022063eff2e57f5b4ca20342cfe793e25526624e3692f192461f9e1ce7f13f2d72c8\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# RSA 515 bit key.\nPrivateKey = RSA-515\nType = RSA\nInput = 30820157020100300d06092a864886f70d0101010500048201413082013d0201000241054fa166e205e658bbe8a2dc35311c0c2b75b7e4569fd9642c8bae809279271fc824f26baa1166ea46298ca63379ea76adbada2b61e5066820a35beaec1aca227f020301000102410266c972be0d30e53ac2acb1aa13b4bd0401cccf212452a66b4615f7e943831f67b4ca48560582d0ca886044aaaaf87945252a848c1947944186e6eb83969bf91102210309e631761842cc8a2ccfd372c20a9cba21de1a199c30ab440bc6b51079f4e825022101bf715c1db432627ca7c29a293b9210f2eff1e92d12f306ebaa5334f8ee03dcd30221018ac58a765f2b8f37d434081fe5ff92b81735ead2f263f4968ccf63d61fbe3d0d0221015b247a1159a2d5a25d0db049593c6405f77f3a278c521d066e290c2a2d8fb59d0221026224aa31fd95c14d24fd03b8a195bba4cc88df7c37f5370a5ab19f882f1404d6\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# EC P-256 key\nPrivateKey = P-256\nType = EC\nInput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above with the optional public key omitted.\nPrivateKey = P-256-Mis", + "singPublic\nType = EC\nInput = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above with redundant parameters.\nPrivateKey = P-256-ExtraParameters\nType = EC\nInput = 308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00a06082a8648ce3d030107a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\n# The key re-encodes with the parameters removed.\nOutput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key, but with the redundant parameters in the ECPrivateKey mismatched.\nPrivateKey = P-256-BadInnerParameters\nInput = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = GROUP_MISMATCH\n\n# The same key, but with the curve spelled explicitly.\nPrivateKey = P-256-ExplicitParameters\nType = EC\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nOutput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but with the optional cofactor omitted.\nPrivateKey = P-256-ExplicitParameters-NoCofactor\nType = EC\nInput = 3082015e0201003081e906072a8648ce3d02013081dd020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nOutput = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but the cofactor is zero instead of one.\nPrivateKey = P-256-ExplicitParameters-CofactorZero\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020100046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = UNKNOWN_GROUP\n\n# The same as above, but the cofactor is two instead of one.\nPrivateKey = P-256-ExplicitParameters-CofactorTwo\nInput = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020102046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = UNKNOWN_GROUP\n\n# A zero ECDSA key, with the optional public key encoded.\nPrivateKey = P-256-Zero\nInput = 3047020100301306072a8648ce3d020106082a8648ce3d030107042d302b02010104200000000000000000000000000000000000000000000000000000000000000000a10403020000\nError = INVALID_PRIVATE_KEY\n\n# A zero ECDSA key, with the optional public key omitted.\nPrivateKey = P-256-Zero-NoPublic\nInput = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104200000000000000000000000000000000000000000000000000000000000000000\nError = INVALID_PRIVATE_KEY\n\n# The public half of the same key encoded as a PublicKey.\nPublicKey = P-256-SPKI\nType = EC\nInput = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same as above, but with the curve explicitly spelled out.\nPublicKey = P-256-SPKI\nInput = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# The same as above, but with trailing data after the curve name.\nPublicKey = P-256-SPKI\nInput = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# A DSA private key.\nPrivateKey = DSA-1024\nType = DSA\nInput = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ff", + "bc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# An invalid zero DSA private key.\nPrivateKey = DSA-1024-Zero\nInput = 308202450201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610403020100\nError = INVALID_PARAMETERS\n\n# A DSA public key.\nPublicKey = DSA-1024-SPKI\nType = DSA\nInput = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc5598303818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# The same key as above, but without the parameters.\nPublicKey = DSA-1024-SPKI-No-Params\nType = DSA\nInput = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\nExpectNoRawPrivate\nExpectNoRawPublic\n\n# Private keys from RFC 8032.\nPrivateKey = Ed25519\nType = Ed25519\nInput = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nExpectRawPrivate = 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nExpectRawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\n\nPrivateKey = Ed25519-2\nType = Ed25519\nInput = 302e020100300506032b6570042204204ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb\nExpectRawPrivate = 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb\nExpectRawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\n\nPrivateKey = Ed25519-3\nType = Ed25519\nInput = 302e020100300506032b657004220420c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7\nExpectRawPrivate = c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7\nExpectRawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\n\nPrivateKey = Ed25519-4\nType = Ed25519\nInput = 302e020100300506032b657004220420f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5\nExpectRawPrivate = f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5\nExpectRawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\n\nPrivateKey = Ed25519-5\nType = Ed25519\nInput = 302e020100300506032b657004220420833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42\nExpectRawPrivate = 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42\nExpectRawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\n\n# Public keys from RFC 8032.\nPublicKey = Ed25519-SPKI\nType = Ed25519\nInput = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nExpectNoRawPrivate\nExpectRawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\n\nPublicKey = Ed25519-SPKI-2\nType = Ed25519\nInput = 302a300506032b65700321003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\nExpectNoRawPrivate\nExpectRawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\n\nPublicKey = Ed25519-SPKI-3\nType = Ed25519\nInput = 302a300506032b6570032100fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\nExpectNoRawPrivate\nExpectRawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\n\nPublicKey = Ed25519-SPKI-4\nType = Ed25519\nInput = 302a300506032b6570032100278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\nExpectNoRawPrivate\nExpectRawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\n\nPublicKey = Ed25519-SPKI-5\nType = Ed25519\nInput = 302a300506032b6570032100ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\nExpectNoRawPrivate\nExpectRawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\n\n# The first key, private and public, with invalid NULL parameters.\nPrivateKey = Ed25519-NULL\nInput = 3030020100300706032b65700500042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nError = DECODE_ERROR\n\nPublicKey = Ed25519-SPKI-NULL\nInput = 302c300706032b65700500032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nError = DECODE_ERROR\n\n# Sample public key from RFC 8410.\nPublicKey = Ed25519-SPKI-Spec\nType = Ed25519\nInput = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1\n\n# Sample private key from RFC 8410.\nPrivateKey = Ed25519-Spec\nType = Ed25519\nInput = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842\n\n\n# RSA tests\n\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0", + "a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\n# Digest too long\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too short\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too large for key.\nSign = RSA-512\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DIGEST_TOO_BIG_FOR_RSA_KEY\n\n# Mismatched digest\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = BAD_SIGNATURE\n\n# Corrupted signature\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae\nError = BLOCK_TYPE_IS_NOT_01\n\n# parameter missing (NOTE: this differs from upstream)\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c\nError = BAD_SIGNATURE\n\n# embedded digest too long\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# embedded digest too short\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# Garbage after DigestInfo\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274\nError = BAD_SIGNATURE\n\n# invalid tag for parameter\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 49525db4d44c755e560cba980b1d85ea604b0e077fcadd4ba44072a3487bbddb835016200a7d8739cce2dc3223d9c20cbdd25059ab02277f1f21318efd18e21038ec89aa9d40680987129e8b41ba33bceb86518bdf47268b921cce2037acabca6575d832499538d6f40cdba0d40bd7f4d8ea6ca6e2eec87f294efc971407857f5d7db09f6a7b31e301f571c6d82a5e3d08d2bb3a36e673d28b910f5bec57f0fcc4d968fd7c94d0b9226dec17f5192ad8b42bcab6f26e1bea1fdc3b958199acb00f14ebcb2a352f3afcedd4c09000128a603bbeb9696dea13040445253972d46237a25c7845e3b464e6984c2348ea1f1210a9ff0b00d2d72b50db00c009bb39f9\nError = BAD_SIGNATURE\n\n\n# RSA-PSS tests.\n\n# Zero salt length makes the output deterministic\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Verify of above signature\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# A non-zero salt length must be checked by round-tripping.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Check a salt length with a non-standard digest length, to verify things are\n# not just working due to defaults. (The current default is a maximum salt\n# ", + "length, but the ecosystem has converged on matching the digest length, so we\n# may change this in the future.)\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 42\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Auto-detected salt length\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Signing with salt length -1 means to match the digest length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nVerifyPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Signing with salt length -2 means to maximize the salt length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -2\nVerifyPSSSaltLength = 222 # 256 - 32 - 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Wrong digest\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"00000000000000000000000000000000\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDE\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too long\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF0\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Wrong salt length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong salt length using implicit hash length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-1\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA1\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-1, this input happens to succeed recovering a salt length, but it does\n# not match.\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-384\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA384\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-384, this input happens fail to recover the salt length altogether.\nError = SLEN_RECOVERY_FAILED\n\n# The salt length is too large for the modulus (signing).\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\n# The salt length is too large for the modulus (verifying).\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = DATA_TOO_LARGE\n\n# The hash is too large for the modulus (signing).\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE_FOR_KEY_SIZE\n\n# The hash is too large for the modulus (verifying).\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nOutput = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nError = DATA_TOO_LARGE\n\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF012345", + "6789ABCDEF0123456789ABCDEF\"\nOutput = 457001d9ca50a93385fc5ec721c9dbbe7a0f2e9e4a2f846a30a8811dde66347b83901c7492039243537c7a667fafffd69049bcbd36afd0010d9b425e2d8785c1\nError = DATA_TOO_LARGE\n\n# Sample RSA-515 signature.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 00c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\n\n# The above, but with too few leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above, but with too many leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 0000c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above with an invalid leading byte. The top few bits of EM are required to\n# be cleared.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 007f803c832a2090aea04013d9fa9c1630732a1625232826d235f0950f7050d3fb0eb06ef9ea8b260fad68e1165a2d770a8c7fc7a8aaa68620b021fc19c97e0041\nError = FIRST_OCTET_INVALID\n\n# The above with an invalid trailing byte.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 03e68555035891eb08d96c0967db22328cd892ad2856d88516ecb946bfdba732bb029b5c0dfa2119ed7349897d2324e95e86d91d0c4afc82700a36db8933abbf58\nError = LAST_OCTET_INVALID\n\n# Non-zero salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, wrong salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 31\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\nError = SLEN_CHECK_FAILED\n\n# Non-zero salt length, match hash length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, auto-detected.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n\n# RSA decrypt\n\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a78\nOutput = \"Hello World\"\n\n# Corrupted ciphertext\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a79\nError = PKCS_DECODING_ERROR\n\n# OAEP padding\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5af\nOutput = \"Hello World\"\n\n# OAEP padding with label and custom hash.\nDecrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = 48b956c22b8e40cc38f0893672ddf488fc806cf1fcc6239c66dd8345eb543d6b5cac589e6c7ae86dac1c2436c4d72c48009a737b2c649e6000dbab17203e4d9c078bd70b649700a0830d4ddc396af0c48973177a229e48259d93247f04f76474c7611b530c66f020c4da2cc861c2e4104831ecc0336e0cb10d6520fdefd0b33606f5cdd736dd439583b9b6011cce99623c93caf5f76e21e9fefab414795dd5ac12cba551be74ebf266834fcffab182c5e7c9b6c064df154cb26ddfd4fe2fd87590005f4bf45e776a0082803e9f68995b8eeb4c6802c67b5ef349e5b2dc0cf7a12fc097030f2bd28f0253f17129b04c82993a12957728b35880fdd2f8d0cc469f\nOutput = \"Hello World\"\n\n# OAEP padding, corrupted ciphertext\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5ac\nError = OAEP_DECODING_ERROR\n\n# Test that RSA encryption successfully round-trips through decryption\n# with various parameters.\nEncrypt = RSA-2048\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = \"Hello World\"\nCheckDecrypt\n\n# Though we will never generate such a key, test that RSA keys where p < q work\n# properly.\nPrivateKey = RSA-Swapped\nType = RSA\nInput = 30820275020100300d06092a864886f7", + "0d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429\n\nSign = RSA-Swapped\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f\n\n# The input is 1 (mod p) and q - 1 (mod q). If the CRT implementation does not\n# account for p < q, the subtraction step will break. However, this test only\n# works when RSA blinding is disabled. When blinding is enabled, these values\n# are randomized and, instead, either this or the above test will hit this case\n# if repeated enough. (It hits it with probability (q-p)^2 / 2pq, or 1.8% here.)\nEncrypt = RSA-Swapped\nRSAPadding = None\nInput = 7ab490e1f5e718ff23a9e738f9867559e3a6ea72332e3bcc1b6f58585218ed815a865dab75e3f44ea550bdef815101d6039251a513fd99188c1916abb94b15ef72de793f6472a342b33a125cfc96a4fc89d140e337f5fe6ff937ed3f34b6b09f5227f598e12faddf4423254acbee748197bed26954502c7484c65e279fed7fed\nCheckDecrypt\n\n# Though we will never generate such a key, test that RSA keys where p and q are\n# different sizes work properly.\nPrivateKey = RSA-PrimeMismatch\nType = RSA\nInput = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d24401052b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c\n\nSign = RSA-PrimeMismatch\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 6192b1ce630c87d02e8245fd74d4f6ecac37eef979d188c8fa48c4d355fbe814e7dd3152f42bb020d769b540d11867af5b947387b8c99158d56901ff3708e423931178213916ae1002f162c9d497aacacdcb20e6ffe7ed40138a253fc943ddf3587433df5831a3ce46aeefce358a009bf6bad12d82d77424c2755d984d7da196\n\n\n# EC tests\n\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\nVerify = P-256-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\n# Digest too long\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest invalid\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1235\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Invalid signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7\nError = BAD_SIGNATURE\n\n# Garbage after signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800\nError = BAD_SIGNATURE\n\n# BER signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000\nError = BAD_SIGNATURE\n\n\n# Additional RSA-PSS and RSA-OAEP tests converted from\n# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip\n\nPublicKey = RSA-PSS-1\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a21370203010001\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = cd8b6538cb8e8de566b68bd067569dbf1ee2718e\nOutput = 9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e35befc17a1d160b9ce35fbd8eb16e7ee491d3fd\nOutput = 3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0652ec67bcee30f9d2699122b91c19abdba89f91\nOutput = 666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 39c21c4cceda9c1adf839c744e1212a6437575ec\nOutput = 4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 36dae913b77bd17cae6e7b09453d24544cebb33c\nOut", + "put = 1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 45eef191f4f79c31fe5d2ede7e5098994e929d2d\nOutput = 2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58\n\nPublicKey = RSA-PSS-2\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818101d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c90203010001\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 5c81a3e2a658246628cd0ee8b00bb4c012bc9739\nOutput = 014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 27f71611446aa6eabf037f7dedeede3203244991\nOutput = 010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 03ecc2c33e93f05fc7224fcc0d461356cb897217\nOutput = 007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c30742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84df0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6c4\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 246c727b4b9494849dddb068d582e179ac20999c\nOutput = 009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b40b\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e8617ca3ea66ce6a58ede2d11af8c3ba8a6ba912\nOutput = 00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181ecf\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7a6fdc1a4e434ecbc35d657ad49a2f4fafd43bc8\nOutput = 00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7a6\n\nPublicKey = RSA-PSS-3\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818102f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4430203010001\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3552be69dd74bdc56d2cf8c38ef7bafe269040fe\nOutput = 0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103bd57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b16797f\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 609143ff7240e55c062aba8b9e4426a781919bc9\nOutput = 02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf78641169179556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11af\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0afd22f879a9cda7c584f4135f8f1c961db114c0\nOutput = 0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa760649cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548aea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e3802c\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 405dd56d395ef0f01b555c48f748cc32b210650b\nOutput = 0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7ba7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836b8\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a2c313b0440c8a0c47233b87f0a160c61af3eae7\nOutput = 021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd83\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f1bf6ca7b4bbdbb6bf20a4bf55728725d177154a\nOutput = 012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bde03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab854586c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e5538ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426ce\n\nPublicKey = RSA-PSS-4\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37050203010001\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f8b0abf70fec0bca74f0accbc24f75e6e90d3bfd\nOutput = 0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 04a10944bfe11ab801e77889f3fd3d7f4ff0b629\nOutput = 049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ba01243db223eb97fb86d746c3148adaaa0ca344\nOutput = 03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefca0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af4163599090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc6217461d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2aad\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 934bb0d38d6836daec9de82a9648d4593da67cd2\nOutput = 0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba4298cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d4f\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ec35d81abd1cceac425a935758b683465c8bd879\nOutput = 022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b320b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb0a\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 72ce251d17b04dd3970d6ff1fbe3624899e9e941\nOutput = 00938dcb6d583046065f6", + "9c78da7a1f1757066a7fa75125a9d2929f0b79a60b627b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a028c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5afd9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd562e\n\nPublicKey = RSA-PSS-5\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d003081890281810d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c19916391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d0191871740525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5070203010001\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d98b7061943510bc3dd9162f7169aabdbdcd0222\nOutput = 0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad0452915a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec1d\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ae8e699f754988f4fd645e463302e49a2552072\nOutput = 08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e220ad17997c0dd6e706630ba3e84add4d5e7ab004e58074b549709565d43ad9e97b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d158ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a34e\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8d46c7c05534c1ba2cc7624500d48a4531604bff\nOutput = 05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6fd019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b979\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ee3de96783fd0a157c8b20bf5566124124dcfe65\nOutput = 0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb63903204a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e49fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19daea1\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1204df0b03c2724e2709c23fc71789a21b00ae4c\nOutput = 0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681fcd\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 29926bc3280c841f601acd0d6f17ea38023eddbc\nOutput = 02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c1339e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f244a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a81266d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e8f\n\nPublicKey = RSA-PSS-6\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48bf5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698d10203010001\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ab464e8cb65ae5fdea47a53fa84b234d6bfd52f6\nOutput = 04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a96a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45fe42892335362eee018b5b161f2f9393031225c713012a576bc88e23052489868d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85d1\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 92d0bcae82b641f578f040f5151be8eda6d42299\nOutput = 0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f393ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa4773\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3569bd8fd2e28f2443375efa94f186f6911ffc2b\nOutput = 086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a26bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f23706d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df456\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7abbb7b42de335730a0b641f1e314b6950b84f98\nOutput = 0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c559329f\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 55b7eb27be7a787a59eb7e5fac468db8917a7725\nOutput = 02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a356b\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = de2fa0367ef49083ff89b9905d3fd646fcc12c38\nOutput = 0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385ce99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83cc9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081ef\n\nPublicKey = RSA-PSS-7\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818137c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee18ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29ab30203010001\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8be4afbdd76bd8d142c5f4f46dba771ee5d6d29d\nOutput = 187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc810520bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b23dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c60555823\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 402140dc605b2f5c5ec0d15bce9f9ba8857fe117\nOutput = 10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce79429b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db815ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570eb8\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3e885205892ff2b6b37c2c4eb486c4bf2f9e7f20\nOutput = 2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a911865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0df9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebfb898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460af1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1fc2201d0c442a4736cd8b2cd00c959c47a3bf42\nOutput = 32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffabddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe19\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e4351b66819e5a31501f89acc7faf57030e9aac5\nOutput = 07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d989db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2f1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 49f6cc58365e514e1a3f301f4de16f9fb5347ff2\nOutput = 18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed3248903f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d796aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130ec0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d33\n\nPublicKey = RSA-PSS-8\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a", + "8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f0203010001\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a1dd230d8ead860199b6277c2ecfe3d95f6d9160\nOutput = 0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f6e68e53c602c5c65fa67b5aa6d786e5524b12ab\nOutput = 2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d6f9fcd3ae27f32bb2c7c93536782eba52af1f76\nOutput = 2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0ca446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee290356b8c4a29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db4084f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f96\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ff2a53ce2e2d900d468e498f230a5f5dd0020de\nOutput = 1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b5328571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300ccc7\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 4eb309f7022ba0b03bb78601b12931ec7c1be8d3\nOutput = 33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1eec31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673ee\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 65033bc2f67d6aba7d526acb873b8d9241e5e4d9\nOutput = 1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517ff9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e69463e\n\nPublicKey = RSA-PSS-9\nType = RSA\nInput = 3081df300d06092a864886f70d01010105000381cd003081c90281c100e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b0203010001\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2715a49b8b0012cd7aee84c116446e6dfe3faec0\nOutput = 586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2dac956d53964748ac364d06595827c6b4f143cd\nOutput = 80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 28d98c46cccafbd3bc04e72f967a54bd3ea12298\nOutput = 484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f981817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b605952019782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecde3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0866d2ff5a79f25ef668cd6f31b42dee421e4c0e\nOutput = 84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074ae0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 6a5b4be4cd36cc97dfde9995efbf8f097a4a991a\nOutput = 82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de8454810274cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afec7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b9dfd1df76a461c51e6576c6c8ed0a923d1c50e7\nOutput = a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaadeacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc460895f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f\n\nPublicKey = RSA-PSS-10\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea57b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7adcd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e391900992070df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a511001a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae050203010001\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 9596bb630cf6a8d4ea4600422b9eba8b13675dd4\nOutput = 82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b503319399277fd6c1c8f1033cbf04199ea21716\nOutput = 14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 50aaede8536b2c307208b275a67ae2df196c7628\nOutput = 6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bc", + "c10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = aa0b72b8b371ddd10c8ae474425ccccf8842a294\nOutput = 34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = fad3902c9750622a2bc672622c48270cc57d3ea8\nOutput = 7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 122196deb5d122bd8c6fc781ff6924d7c695aade\nOutput = 6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f\n\nPrivateKey = RSA-OAEP-1\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a\nOutput = 6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44\nOutput = 750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb\nOutput = d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755\nOutput = 52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439\nOutput = 8da89fd9e5f974a29feffb462b49180f6cf9e802\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255\nOutput = 26521050844271\n\nPrivateKey = RSA-OAEP-2\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818101947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a60055c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f4502030100010281800823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8ccd1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab245941d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe3902410159dbde04a33ef06fb608b80b190f4d3e22bcc13ac8e4a081033abfa416edb0b338aa08b57309ea5a5240e7dc6e54378c69414c31d97ddb1f406db3769cc41a430241012b652f30403b38b40995fd6ff41a1acc8ada70373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822df031ba0df0dafd5506f568bd70240436ef508de736519c2da4c580d98c82cb7452a3fb5efadc3b9c7789a1bc6584f795addbbd32439c74686552ecb6c2c307a4d3af7f539eec157248c7b31f1a2550241012b15a89f3dfb2b39073e73f02bdd0c1a7b379dd435f05cdde2eff9e462948b7cec62ee9050d5e0816e0785a856b49108dcb75f3683874d1ca6329a19013066ff02400270db17d5914b018d76118b24389a7350ec836b0063a21721236fd8edb6d89b51e7eeb87b611b7132cb7ea7356c23151c1e7751507c786d9ee1794170a8c8e8\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e\nOutput = 8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245\nOutput = 2d\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053\nOutput = 74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e\n", + "\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641\nOutput = a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec\nOutput = 2ef2b066f854c33f3bdcbb5994a435e73d6c6c\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a\nOutput = 8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0\n\nPrivateKey = RSA-OAEP-3\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818102b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c1652006a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cbfad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43e9020301000102818015b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd024101bf01d216d73595cf0270c2beb78d40a0d8447d31da919a983f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de7fad9d555160958b4454127e0e7eaf0241018d3399658166db3829816d7b295416759e9c91987f5b2d8aecd63b04b48bd7b2fcf229bb7f8a6dc88ba13dd2e39ad55b6d1a06160708f9700be80b8fd3744ce7024006c0a249d20a6f2ee75c88b494d53f6aae99aa427c88c28b163a769445e5f390cf40c274fd6ea6329a5ce7c7ce03a2158396ee2a7845786e09e2885a9728e4e5024100d1d27c29fedd92d86c348edd0ccbfac14f746e051ce1d1811df35d61f2ee1c97d4bf2804802f6427187ba8e90a8af44243b4079b03445e602e29fa5193e64fe90241008cb2f756bd8941b1d3b770e5ad31ee373b28acda69ff9b6f40fe578b9f1afb85836f9627d37acff73c2779e634bb26011c2c8f7f3361ae2a9ea65ed689e3639a\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80\nOutput = 087820b569e8fa8d\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5\nOutput = 4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a\nOutput = d94cd0e08fa404ed89\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0\nOutput = 6cc641b6b61e6f963974dad23a9013284ef1\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60\nOutput = df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730\nOutput = 3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1\n\nPrivateKey = RSA-OAEP-4\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d020100028181051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e357625991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57dde4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb03902030100010281800411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb3651c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d4567f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d04010241027458c19ec1636919e736c9af25d609a51b8f561d19c6bf6943dd1ee1ab8a4a3f232100bd40b88decc6ba235548b6ef792a11c9de823d0a7922c7095b6eba570102410210ee9b33ab61716e27d251bd465f4b35a1a232e2da00901c294bf22350ce490d099f642b5375612db63ba1f20386492bf04d34b3c22bceb909d13441b53b5139024039fa028b826e88c1121b750a8b242fa9a35c5b66bdfd1fa637d3cc48a84a4f457a194e7727e49f7bcc6e5a5a412657fc470c7322ebc37416ef458c307a8c09010241015d99a84195943979fa9e1be2c3c1b69f432f46fd03e47d5befbbbfd6b1d1371d83efb330a3e020942b2fed115e5d02be24fd92c9019d1cecd6dd4cf1e54cc899024101f0b7015170b3f5e42223ba30301c41a6d87cbb70e30cb7d3c67d25473db1f6cbf03e3f9126e3e97968279a865b2c2b426524cfc52a683d31ed30eb984be412ba\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8\nOutput = 4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e\nOutput = b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065\nOutput = bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4\nOutput = fb2ef112f5e766eb94019297934794f7be2f6fc1c58e\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97", + "c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2\nOutput = 28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9\nOutput = f22242751ec6b1\n\nPrivateKey = RSA-OAEP-5\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281810aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c47576b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10ed902030100010281810256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a268f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa217588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528acfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2c5024103b0d3962f6d17549cbfca11294348dcf0e7e39f8c2bc6824f2164b606d687860dae1e632393cfedf513228229069e2f60e4acd7e633a436063f82385f48993707024102e4c32e2f517269b7072309f00c0e31365f7ce28b236b82912df239abf39572cf0ed604b02982e53564c52d6a05397de5c052a2fddc141ef7189836346aeb331f024101e84b119d25161fa67b00256a5bd9b645d2b232ecb05b015180029a88622adc3f09b3aeacde6161ab7cde22c2ad26e7797df54e072cbd3b2673800b3e4338dbd5024100eb90aa1a40135b4cea07197cedc8819be1e7cbff2547662116f465a4a9f487ab12f3ba4fef13822265a65297d98b7bded9372e3ffe81a38b3e9600fed055754f0241012f7f8138f9404062eb85a42924520b38f5bb886a0196f48bb8dcea60fd92cc027f18e78158a34a5c5d5f860a0f6c04071a7d01312c065062f1eb48b79d1c83cb\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5\nOutput = af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad\nOutput = a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967\nOutput = 308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf\nOutput = 15c5b9ee1185\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723\nOutput = 21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a\nOutput = 541e37b68b6c8872b84c02\n\nPrivateKey = RSA-OAEP-6\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f02010002818112b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c166db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722af02030100010281810295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d33261904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3f9024104a6ce8b7358dfa69bdcf742617005afb5385f5f3a58a24ef74a22a8c05cb7cc38ebd4cc9d9a9d789a62cd0f60f0cb941d3423c9692efa4fe3adff290c4749a38b02410404c9a803371fedb4c5be39f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4bf7befd2dd536ac946db797fdbc4abe8f29349b91ed024103961c8f760aa2bd5154c7aafd77225b3bacd0139ae7b5948ea3311fccd86fb95c75afa767284b9b2de559572f15d8d044c7eb83a1be5fadf2cc377c0d8475294b0241022197e066742196aabc03fa2feeb4e70b15cb787d617acd31bb75c7bc234ad706f7c48d2182d1f0ff9c228dcf41967b6c0ba6d2c0ad110a1b857831ec245e2cb102410401c4c0c53d45dbdb5e9d96d0fecf4275df0974bc4a0736b4a74c3269053efb686ace2406e22c9e058ddb4ae540627ae2fdb08261e8e7e4bcbc994daafa305c45\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3\nOutput = 4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f\nOutput = 5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65\nOutput = b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8\nOutput = 684e3038c5c041f7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab\nOutput = 32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470\nOutput = 50ba14be8462720279c306ba\n\nPrivateKey = RSA-OAEP-7\nType = RSA\nInput = 30820278020100300d06092a864886f70d0101010500048202623082025e020100028181311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d0732b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec3119051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43dc1e1f9082540", + "58a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3730203010001028181070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e0276174487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc296800adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21b102410749262c111cd470ec2566e6b3732fc09329469aa19071d3b9c01906514c6f1d26baa14beab0971c8b7e611a4f79009d6fea776928ca25285b0de3643d1a3f8c71024106bc1e50e96c02bf636e9eea8b899bbebf7651de77dd474c3e9bc23bad8182b61904c7d97dfbebfb1e00108878b6e67e415391d67942c2b2bf9b4435f88b0cb023024103bc7ea7f0aab143abc6ce8b97118636a30172e4cfe02c8fa0dda3b7baaf90f8092982985525f488bdfcb4bd726e22639ac64a3092ab7ffcbf1d5334cfa50b5bf102410262a6aa29c2a3c67dc5346c06381afd987aa3cc93cfbfecf54fdd9f9d787d7f59a523d398979da137a2f6381fe94801f7c94da21518dc34cb40870c4697994ad90240649d4c17b6ee1721e772d0389a559c3d3cdf9550d457c46b037b74641b1d52166af8a213c8396206cdfba4422f18d6f61dbcb5d214c971bf482aeb976a7370c2\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1\nOutput = 47aae909\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6\nOutput = 1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b\nOutput = d976fc\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac\nOutput = d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478\nOutput = bb47231ca5ea1d3ad46c99345d9a8a61\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae674115\nOutput = 2184827095d35c3f86f600e8e59754013296\n\nPrivateKey = RSA-OAEP-8\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281815bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427ca9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e230f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f4631359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212dff702030100010281810f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf633102410a02ef8448d9fad8bbd0d004c8c2aa9751ef9721c1b0d03236a54b0df947cbaed5a255ee9e8e20d491ea1723fe094704a9762e88afd16ebb5994412ca966dc4f9f0241092d362e7ed3a0bfd9e9fd0e6c0301b6df29159cf50cc83b9b0cf4d6eea71a61e002b46e0ae9f2de62d25b5d7452d498b81c9ac6fc58593d4c3fb4f5d72dfbb0a9024107c71410af103962db367404e37ae850baa4e9c29dd92145815294a67c7d1c6ded263aa030a9b633ae50303e14035d1af014123eba687820308d8ebc85b6957d7d024100ae2c75380c02c016ad05891b3301de881f28ae1171182b6b2c83bea7c515eca9ca298c7b1cab5817a597068fc85060de4da8a016378aae43c7f967bcc37904b902410598d1059e3ada4f6320752c09d805ff7d1f1ae0d017aeeee9cefa0d7dd7ff775e44b578322f6405d6211da19519666aa87fdc4cd8c88f6b6e3d67e961dcbba3d0\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61\nOutput = 050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d\nOutput = 4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f\nOutput = 8604ac56328c1ab5ad917861\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0\nOutput = fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2\nOutput = 4a5f4914bee25de3c69341de07\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210\nOutput = 8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be\n\nPrivateKey = RSA-OAEP-9\nType = RSA\nInput = 30820397020100300d06092a864886f70d0101010500048203813082037d0201000281c100cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d902b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2ab18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d02030100010281c0198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d7205368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1026100fc8d6c04bec4eb9a8192ca7900cbe536e2e8b519decf33b2459798c6909df4f176db7d23190fc72b8865a718af895f1bcd9145298027423b605e70a47cf58390a8c3e88fc8c48e8b32e3da210dfbe3e881ea5674b6a348c21e93f9e55ea65efd026100d200d45e788aacea606a401d0460f87dd5c1027e12dc1a0d7586e8939d9cf789b40f51ac0442961de", + "7d21cc21e05c83155c1f2aa9193387cfdf956cb48d153ba270406f9bbba537d4987d9e2f9942d7a14cbfffea74fecdda928d23e259f5ee1026100db16802f79a2f0d45f358d69fd33e44b81fae828622e93a54253e997d01b0743759da0e812b4aa4e6c8beab2328d5431955a418a67ff26a8c5c807a5da354e05ef31cc8cf758f463732950b03e265726fb94e39d6a572a26244ab08db75752ad026100a0a317cfe7df1423f87a6dee8451f4e2b4a67e5497f29b4f1e4e830b9fadd9401167026f5596e5a39c97817e0f5f16e27e19ec9902e01d7ea6fb9aa3c760afee1e381b69de6ac9c07585a06ad9c4ba00bf75c8ad2fa898a479e80ae294fed2a102600b21f335c353342eb44c3aa24445780c2d655b940174cae38c7c8a4e6493c0ba9fd303748267b083b9a7a6cb61e42db362b8c9896db7064e02ad5ae61587da15b4649c90594909feb37dbcb654beb7268ec801e5a8b4aa3911bebd88542f05be\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72\nOutput = f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8\nOutput = 81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3\nOutput = fd326429df9b890e09b54b18b8f34f1e24\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858\nOutput = f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e\nOutput = 53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f\nOutput = b6b28ea2198d0c1008bc64\n\nPrivateKey = RSA-OAEP-10\nType = RSA\nInput = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb020301000102820100056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e7902818100ecf5aecd1e5515fffacbd75a2816c6ebf49018cdfb4638e185d66a7396b6f8090f8018c7fd95cc34b857dc17f0cc6516bb1346ab4d582cadad7b4103352387b70338d084047c9d9539b6496204b3dd6ea442499207bec01f964287ff6336c3984658336846f56e46861881c10233d2176bf15a5e96ddc780bc868aa77d3ce76902818100bc46c464fc6ac4ca783b0eb08a3c841b772f7e9b2f28babd588ae885e1a0c61e4858a0fb25ac299990f35be85164c259ba1175cdd7192707135184992b6c29b746dd0d2cabe142835f7d148cc161524b4a09946d48b828473f1ce76b6cb6886c345c03e05f41d51b5c3a90a3f24073c7d74a4fe25d9cf21c75960f3fc386318302818100c73564571d00fb15d08a3de9957a50915d7126e9442dacf42bc82e862e5673ff6a008ed4d2e374617df89f17a160b43b7fda9cb6b6b74218609815f7d45ca263c159aa32d272d127faf4bc8ca2d77378e8aeb19b0ad7da3cb3de0ae7314980f62b6d4b0a875d1df03c1bae39ccd833ef6cd7e2d9528bf084d1f969e794e9f6c10281802658b37f6df9c1030be1db68117fa9d87e39ea2b693b7e6d3a2f70947413eec6142e18fb8dfcb6ac545d7c86a0ad48f8457170f0efb26bc48126c53efd1d16920198dc2a1107dc282db6a80cd3062360ba3fa13f70e4312ff1a6cd6b8fc4cd9c5c3db17c6d6a57212f73ae29f619327bad59b153858585ba4e28b60a62a45e490281806f38526b3925085534ef3e415a836ede8b86158a2c7cbfeccb0bd834304fec683ba8d4f479c433d43416e63269623cea100776d85aff401d3fff610ee65411ce3b1363d63a9709eede42647cea561493d54570a879c18682cd97710b96205ec31117d73b5f36223fadd6e8ba90dd7c0ee61d44e163251e20c7f66eb305117cb8\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc\nOutput = 8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795\nOutput = e6ad181f053b58a904f2457510373e57\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e8", + "5a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede\nOutput = 510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8\nOutput = bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0\nOutput = a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46\nOutput = eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac\n\n\n# Single-shot signing tests.\n\nSignMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048-SPKI\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = P-256\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 304502204c66004635c267394bd6857c1e0b53b22a2bab1ca7dff9d5c1b42143858b3ea7022100ae81228510e03cd49a8863d2ebd1c05fe0c87eacd1150433132b909994cd0dbd\n\n# Digest can't be omitted in many algorithms.\nSignMessage = RSA-2048\nInput = \"Hello world\"\nError = NO_DEFAULT_DIGEST\n\nVerifyMessage = RSA-2048\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\nError = NO_DEFAULT_DIGEST\n\n# Signing test vectors from RFC 8032.\nSignMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nSignMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nSignMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nSignMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nSignMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Signing with public keys is not allowed.\nSignMessage = Ed25519-SPKI\nInput = \"\"\nError = NOT_A_PRIVATE_KEY\n\n# Verify test vectors from RFC 8032. Test verifying with both the public and\n# private key.\nVerifyMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac7290", + "86e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-SPKI-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-SPKI-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-SPKI-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\nVerifyMessage = Ed25519-SPKI-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Length is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a10\nError = INVALID_SIGNATURE\n\n# Message is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"Hello world\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = INVALID_SIGNATURE\n\n# Ed25519 does not support configuring a digest.\nSignMessage = Ed25519\nInput = \"\"\nDigest = SHA256\nError = COMMAND_NOT_SUPPORTED\n\n# Ed25519 does not support signing a pre-hashed value.\nSign = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\nVerify = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\n\n# Derive tests.\n\nPrivateKey = ECDH-P256-Private\nType = EC\nInput = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534\n\nPublicKey = ECDH-P256-Peer\nType = EC\nInput = 3059301306072a8648ce3d020106082a8648ce3d03010703420004700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac\n\nDerive = ECDH-P256-Private\nDerivePeer = ECDH-P256-Peer\nOutput = 46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b\nSmallBufferTruncates\n\nPrivateKey = X25519-Private\nType = X25519\nInput = 302e020100300506032b656e04220420a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4\nExpectRawPrivate = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4\n\nPublicKey = X25519-Peer\nType = X25519\nInput = 302a300506032b656e032100e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c\nExpectRawPublic = e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c\n\nPublicKey = X25519-SmallOrderPeer", + "\nType = X25519\nExpectRawPublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\nInput = 302a300506032b656e032100e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\n\nDerive = X25519-Private\nDerivePeer = X25519-Peer\nOutput = c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552\n\nDerive = X25519-Private\nDerivePeer = X25519-SmallOrderPeer\nError = INVALID_PEER_KEY\n", }; -static const size_t kLen38 = 1262; +static const size_t kLen35 = 1262; -static const char *kData38[] = { +static const char *kData35[] = { "#\n# Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.\n#\n# Licensed under the OpenSSL license (the \"License\"). You may not use\n# this file except in compliance with the License. You can obtain a copy\n# in the file LICENSE in the source distribution or at\n# https://www.openssl.org/source/license.html\n\nPassword = \"\"\nSalt = \"\"\nN = 16\nr = 1\np = 1\nKey = 77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906\n\nPassword = \"password\"\nSalt = \"NaCl\"\nN = 1024\nr = 8\np = 16\nKey = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640\n\nPassword = \"pleaseletmein\"\nSalt = \"SodiumChloride\"\nN = 16384\nr = 8\np = 1\nKey = 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887\n\n# NB: this test requires more than 1GB of memory to run so it is disabled by\n# default. Uncomment it to run.\n# Password = \"pleaseletmein\"\n# Salt = \"SodiumChloride\"\n# N = 1048576\n# r = 8\n# p = 1\n# Key = 2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4\n# MaxMemory = 10000000000\n", }; -static const size_t kLen39 = 2270; +static const size_t kLen36 = 2270; -static const char *kData39[] = { +static const char *kData36[] = { "# Test vectors from FIPS-197, Appendix C.\n\nMode = Raw\nKey = 000102030405060708090a0b0c0d0e0f\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = 69c4e0d86a7b0430d8cdb78070b4c55a\n\nMode = Raw\nKey = 000102030405060708090a0b0c0d0e0f1011121314151617\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = dda97ca4864cdfe06eaf70a0ec0d7191\n\nMode = Raw\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = 8ea2b7ca516745bfeafc49904b496089\n\n\n# Test vectors from\n# http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = 1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f1011121314151617\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = 96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nPlaintext = 00112233445566778899aabbccddeeff\nCiphertext = 64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f1011121314151617\nPlaintext = 00112233445566778899aabbccddeeff0001020304050607\nCiphertext = 031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nPlaintext = 00112233445566778899aabbccddeeff0001020304050607\nCiphertext = a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1\n\nMode = KeyWrap\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nPlaintext = 00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f\nCiphertext = 28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21\n\n\n# Test vectors from https://tools.ietf.org/html/rfc5649#section-6\n\nMode = KeyWrapWithPadding\nKey = 5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8\nPlaintext = c37b7e6492584340bed12207808941155068f738\nCiphertext = 138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a\n\nMode = KeyWrapWithPadding\nKey = 5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8\nPlaintext = 466f7250617369\nCiphertext = afbeb0f07dfbf5419200f2ccb50bb24f\n", }; -static const size_t kLen40 = 916997; +static const size_t kLen37 = 931; + +static const char *kData37[] = { + "# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n", +}; +static const size_t kLen38 = 26863; + +static const char *kData38[] = { + "# GCD tests.\n#\n# These test vectors satisfy gcd(A, B) = GCD and lcm(A, B) = LCM.\n\nGCD = 0\nA = 0\nB = 0\n# Just to appease the syntax-checker.\nLCM = 0\n\nGCD = 1\nA = 92ff140ac8a659b31dd904161f9213706a08a817ae845e522c3af0c9096699e059b47c8c2f16434b1c5766ebb384b79190f2b2a62c2378f45e116890e7bb407a\nB = 2f532c9e5902b0d68cd2ed69b2083bc226e8b04c549212c425a5287bb171c6a47fcb926c70cc0d34b8d6201c617aee66af865d31fdc8a2eeb986c19da8bb0897\nLCM = 1b2c97003e520b0bdd59d8c35a180b4aa36bce14211590435b990ad8f4c034ce3c77899581cb4ee1a022874203459b6d53859ab1d99ff755efa253fc0e5d8487bb000c13c566e8937f0fe90b95b68bc278610d4f232770b08d1f31bee55a03da47f2d0ebb9e7861c4f16cc22168b68593e9efcde00f54104b4c3e1a0b294d7f6\n\nGCD = a\nA = faaffa431343074f5c5d6f5788500d7bc68b86eb37edf166f699b4d75b76dae2cb7c8f6eccae8f18f6d510ef72f0b9633d5740c0bebb934d3be796bd9a53808e\nB = 2f48ec5aa5511283c2935b15725d30f62244185573203b48c7eb135b2e6db5c115c9446ac78b020574665b06a75eb287e0dbeb5da7c193294699b4c2129d2ac4\nLCM = 4a15f305e9622aa19bd8f39e968bfc16d527a47f7a5219d7b02c242c77ef8b608a4a6141f643ca97cedf07c0f1f3e8879d2568b056718aa15c0756899a08ccbe0a658bae67face96fa110edb91757bfa4828e8ff7c5d71b204f36238b12dd26f17be8ba9771f7068d63e41d423671f898f054b1187605754bc5546f2b02c5ac\n\nGCD = 16\nA = cf0b21bde98b41b479ac8071086687a6707e9efaacd4e5299668ce1be8b13290f27fd32ae68df87c292e8583a09d73ec8e8a04a65a487380dcd7dacca3b6e692\nB = 3be3f563f81d5ad5c1211db7eff430aa345e830ce07b4bde7d4d32dba3ac618d2034351e5435fd6c7f077971fb4a1e83a7396a74fdff7fce1267112851db2582\nLCM = 233a2188de2c017235024b182286f17562b2ee5ab9fdfe4efa2f61c4ff99fa44e1ead5bf6cde05bd7502ce78373c83e3f9dbab0c9bb8620a87c2640bce5d12c685af656df789bb3d0ba1edbaa98cf4f0166d422ab17aa6706f8132264d45b72827d6671a00a9186e723379e3a3bb7902d08865f357c74100059f83800241976\n\nGCD = 1\nA = dd7b7597d7c1eb399b1cea9b3042c14bd6022d31b1d2642a8f82fc32de6eadaf012fbbf349eaec4922a8468740ca73c6090833d6a69a380ed947b39c2f9b0b76\nB = 8e0dc8654e70eec55496038a8d3fff3c2086bc6dbfc0e2dbdf5bd7de03c5aef01a3982556ac3fc34fd5f13368be6cdc252c82367b7462e210f940f847d382dd9\nLCM = 7ae667df4bd4dd35bbec28719a9f1b5e1f396a9ab386c086742a6ab3014a3386d39f35b50624d0c5b4e6b206c2635c7de5ea69e2faa85dd616a7e36622962a07632839857aa49332942feccff2aee1c962e2f4e8ccfd738a5da5bf528b4c5a2440409350f5a17a39d234403e8482ccf838e0d2758ccfb8018198a51dbb407506\n\nGCD = 1\nA = 0\nB = 1\nLCM = 0\n\nGCD = 1\nA = 1\nB = 0\nLCM = 0\n\nGCD = 1\nA = 1\nB = 1\nLCM = 1\n\nGCD = 2b2\nA = dfccaa3549c1b59ab3e114fe87dc5d187719abad58c51724e972741eb895ab79a49f385f61d531ec5c88dbb505ae375093fa848165f71a5ed65e7832a42ade191a\nB = fa58a81f43088da45e659fc1117d0f1cd015aa096c8e5377cf1832191baf7cc28b5c24998b93b64f8900a0973faedb9babaaf1854345f011739da8f1175d9684c\nLCM = 5132f7ab7a982b9dc55114bd96800b7637f9742cf8a7a00a0d69d5e4574fc85792c89a1c52bcfc74b9d7f3f6164819466c46b2d622e280ced7ad1211604084a15dc1fd1951a05c8ce37122c0ec15891d818a70d3763670ea3195098de9b1ca50ea89893a9753fb9ea801541058f44801f7f50967124abfc864a2b01c41f94193c\n\nGCD = 8e\nA = 248d96a8a4cab0a1b194e08c1146868b094597cadbc35531f0ed2d77cba9f15cb5cc7c10e64ce054bf93396d25259d750b3de3aba65073db1fd2b852a6454ac1a\nB = 4c7bad8e1844901fd6a2ce2edc82e698d28ec95d6672ca148d85b49ecc78dd0a8b870e202244210bc98592b99ff6abbd20630f9eee7d46b15ccfae8d08b86799de\nLCM = 13b01f9d9c6c13e90c97e3d95bbce5a835c631b3de3bd4ff5df13ad850f5223dbdf71c53912275d0397df9335ef3a3ba8e4684c6b25962bb7b18bc74144cb5edf0196f79863a7ff032619a71646a92281f7baace7f223d254cb4d05ec19bf8d4c8ce4455a9d770daec89c0d3cf338cbdae39cf982b3c4568f5c9def4e1133d28a\n\nGCD = 3e55\nA = 2fa97382f46676b7a4cc2b8153f17b58792d24660e187d33ce55c81cc193ccb6e1e2b89feea1d5fd8faa36e13bf947fb48635e450a4d1488d0978324194a1f43c6\nB = ab08ad074139963bc18e5d87ba68db64ca6f4c279616c64039b02c55f2375b3bc04114e8e05e1ba92fb6470768f61d123845aea36774c18612736a220934561faf\nLCM = 82c7c377ecda2cb9228604cd287df5eff94edd4a539c3eb3b3fdd4b4a79d2f4eaf2b22f8286272d3dad2e370cfcd9ea4d93ebb3f049c52b8fa23b68a5bf79af989822e2cfb978f68c6a5058f47319dffcb455b089b06ae6db9e5c8a2b6e951d6e118bd2b4cd08b6e5733476a446a57387d940d1289ec00e24315821ed3a5daf2\n\nGCD = a7a\nA = 923706dfed67834a1e7e6c8e8e9f93bfbc0b43ca1f324886cf1f1380fb9b77109275d4b50af1b7689802fe9b3623ac46c7ba0e17e908c20278127b07a5c12d86ec\nB = 64473e878a29021fac1c1ce34a63eae1f4f83ee6851333b67213278b9a4a16f005cba0e8cdb410035bb580062f0e486c1a3a01f4a4edf782495f1dc3ebfa837d86\nLCM = 57785ca45b8873032f1709331436995525eed815c55140582ce57fd852116835deac7ca9d95ce9f280e246ea4d4f1b7140ab7e0dd6dc869de87f1b27372098b155ad0a1828fd387dff514acc92eae708609285edaab900583a786caf95153f71e6e6092c8c5ee727346567e6f58d60a5e01c2fa8ebcf86da9ea46876ecc58e914\n\nGCD = 42\nA = 0\nB = 42\nLCM = 0\n\nGCD = 42\nA = 42\nB = 0\nLCM = 0\n\nGCD = 42\nA = 42\nB = 42\nLCM = 42\n\nGCD = f60d\nA = ef7886c3391407529d5cf2e75ed53e5c3f74439ad2e2dc48a79bc1a5322789b4ced2914b97f8ff4b9910d212243b54001eb8b375365b9a87bd022dd3772c78a9fd63\nB = d1d3ec32fa3103911830d4ec9f629c5f75af7039e307e05bc2977d01446cd2cbeeb8a8435b2170cf4d9197d83948c7b8999d901fe47d3ce7e4d30dc1b2de8af0c6e4\nLCM = cc376ed2dc362c38a45a719b2ed48201dab3e5506e3f1314e57af229dc7f3a6a0dad3d21cfb148c23a0bbb0092d667051aa0b35cff5b5cc61a7c52dec4ed72f6783edf181b3bf0500b79f87bb95abc66e4055f259791e4e5eb897d82de0e128ecf8a091119475351d65b7f320272db190898a02d33f45f03e27c36cb1c45208037dc\n\nGCD = 9370\nA = 1ee02fb1c02100d1937f9749f628c65384ff822e638fdb0f42e27b10ee36e380564d6e861fcad0518f4da0f8636c1b9f5124c0bc2beb3ca891004a14cd7b118ddfe0\nB = 67432fd1482d19c4a1c2a4997eab5dbf9c5421977d1de60b739af94c41a5ad384cd339ebfaa43e5ad6441d5b9aaed5a9f7485025f4b4d5014e1e406d5bd838a44e50\nLCM = 159ff177bdb0ffbd09e2aa7d86de266c5de910c12a48cbe61f6fa446f63a2151194777555cd59903d24cb30965973571fb1f89c26f2b760526f73ded7ee8a34ebcecd1a3374a7559bcdb9ac6e78be17a62b830d6bb3982afdf10cf83d61fd0d588eab17d6abef8e6a7a5763fcb766d9a4d86adf5bb904f2dd6b528b9faec603987a0\n\nGCD = c5f\nA = 5a3a2088b5c759420ed0fb9c4c7685da3725b659c132a710ef01e79435e63d009d2931ea0a9ed9432f3d6b8851730c323efb9db686486614332c6e6ba54d597cf98\nB = 1b1eb33b006a98178bb35bbcf09c5bebd92d9ace79fa34c1567efa8d6cf6361547807cd3f8e7b8cd3ddb6209dccbae4b4c16c8c1ec19741a3a57f61571882b7aed7\nLCM = c5cbbbe9532d30d2a7dd7c1c8a6e69fd4fa4828a844d6afb44f3747fef584f7f1f3b835b006f8747d84f7699e88f6267b634e7aef78d6c7584829537d79514eec7d11219721f91015f5cefdc296261d85dba388729438991a8027de4827cd9eb575622e2912b28c9ce26d441e97880d18db025812cef5de01adeaec1322a9c9858\n\nGCD = e052\nA = 67429f79b2ec3847cfc7e662880ab1d94acdf04284260fcfffd67c2862d59704ed45bcc53700c88a5eea023bc09029e9fd114fc94c227fd47a1faa1a5ef117b09bd2\nB = 39faa7cbdeb78f9028c1d50ab34fbe6924c83a1262596f6b85865d4e19cc258b3c3af1ee2898e39e5bee5839e92eac6753bbbb0253bd576d1839a59748b778846a86\nLCM = 1ab071fb733ef142e94def10b26d69982128561669e58b20b80d39cf7c2759d26b4a65d73b7f940c6e8fc417180ef62d7e52ac24678137bd927cd8d004ad52b02affe176a1ecde903dbc26dcc705678f76dd8cd874c0c3fe737474309767507bbe70dd7fb671bbb3694cedf0dcdaa0c716250ddd6dfec525261572fa3e1387f7b906\n\nGCD = 3523\nA = 0\nB = 3523\nLCM = 0\n\nGCD = 3523\nA = 3523\nB = 0\nLCM = 0\n\nGCD = 3523\nA = 3523\nB = 3523\nLCM = 3523\n\nGCD = f035a941\nA = 16cd5745464dfc426726359312398f3c4486ed8aaeea6386a67598b10f744f336c89cdafcb18e643d55c3a62f4ab2c658a0d19ea3967ea1af3aee22e11f12c6df6e886f7\nB = 74df09f309541d26b4b39e0c01152b8ad05ad2dfe9dd2b6706240e9d9f0c530bfb9e4b1cad3d4a94342aab309e66dd42d9df01b47a45173b507e41826f24eb1e8bcc4459\nLCM = b181771d0e9d6b36fdfcbf01d349c7de6b7e305e1485ea2aa32938aa919a3eee9811e1c3c649068a7572f5d251b424308da31400d81ac4078463f9f71d7efd2e681f92b13a6ab3ca5c9063032dcbdf3d3a9940ce65e54786463bbc06544e1280f25bc7579d264f6f1590cf09d1badbf542ce435a14ab04d25d88ddbac7d22e8cae1c91f\n\nGCD = 33ad1b8f\nA = 1af010429a74e1b612c2fc4d7127436f2a5dafda99015ad15385783bd3af8d81798a57d85038bcf09a2a9e99df713b4d6fc1e3926910fbbf1f006133cb27dc5ebb9cca85\nB = 92a4f45a90965a4ef454f1cdd883d20f0f3be34d43588b5914677c39d577a052d1b25a522be1a656860a540970f99cbc8a3adf3e2139770f664b4b7b9379e13daf7d26c\nLCM = 4c715520ed920718c3b2f62821bc75e3ff9fd184f76c60faf2906ef68d28cd540d3d6c071fa8704edd519709c3b09dfaee12cb02ab01ad0f3af4f5923d5705ce6d18bcab705a97e21896bb5dd8acb36ee8ec98c254a4ddc744297827a33c241f09016a5f109248c83dd41e4cea73ce3eabb28d76678b7e15545b96d22da83c111b6b624\n\nGCD = dc0429aa\nA = ccb423cfb78d7150201a97114b6644e8e0bbbb33cadb0ef5da5d3c521a244", + "ec96e6d1538c64c10c85b2089bdd702d74c505adce9235aa4195068c9077217c0d431de7f96\nB = 710786f3d9022fc3acbf47ac901f62debcfda684a39234644bac630ab2d211111df71c0844b02c969fc5b4c5a15b785c96efd1e403514235dc9356f7faf75a0888de5e5a\nLCM = 6929af911850c55450e2f2c4c9a72adf284fe271cf26e41c66e1a2ee19e30d928ae824f13d4e2a6d7bb12d10411573e04011725d3b6089c28d87738749107d990162b485805f5eedc8f788345bcbb5963641f73c303b2d92f80529902d3c2d7899623958499c8a9133aae49a616c96a2c5482a37947f23af18c3247203ac2d0e760340e6\n\nGCD = 743166058\nA = 16cd476e8031d4624716238a3f85badd97f274cdfd9d53e0bd74de2a6c46d1827cc83057f3889588b6b7ca0640e7d743ed4a6eaf6f9b8df130011ecc72f56ef0af79680\nB = 86eba1fc8d761f22e0f596a03fcb6fe53ad15a03f5b4e37999f60b20966f78ba3280f02d3853f9ace40438ccfaf8faed7ace2f2bf089b2cdd4713f3f293bf602666c39f8\nLCM = 1a7a1b38727324d6ba0290f259b8e2b89c339b2445cada38a5a00ded1468ab069f40678ce76f7f78c7c6f97783cc8a49ef7e2a0c73abbac3abc66d1ce99566ce7f874a8949ca3442051e71967695dc65361184748c1908e1b587dc02ed899a524b34eb30b6f8db302432cfa1a8fbf2c46591e0ab3db7fd32c01b1f86c39832ee9f0c80\n\nGCD = 6612ba2c\nA = 0\nB = 6612ba2c\nLCM = 0\n\nGCD = 6612ba2c\nA = 6612ba2c\nB = 0\nLCM = 0\n\nGCD = 6612ba2c\nA = 6612ba2c\nB = 6612ba2c\nLCM = 6612ba2c\n\nGCD = 2272525aa08ccb20\nA = 11b9e23001e7446f6483fc9977140d91c3d82568dabb1f043a5620544fc3dda233b51009274cdb004fdff3f5c4267d34181d543d913553b6bdb11ce2a9392365fec8f9a3797e1200\nB = 11295529342bfb795f0611d03afb873c70bd16322b2cf9483f357f723b5b19f796a6206cf3ae3982daaeafcd9a68f0ce3355a7eba3fe4e743683709a2dd4b2ff46158bd99ff4d5a0\nLCM = 8d4cbf00d02f6adbaa70484bcd42ea932000843dcb667c69b75142426255f79b6c3b6bf22572597100c06c3277e40bf60c14c1f4a6822d86167812038cf1eefec2b0b19981ad99ad3125ff4a455a4a8344cbc609e1b3a173533db432bd717c72be25e05ed488d3970e7ed17a46353c5e0d91c8428d2fec7a93210759589df042cab028f545e3a00\n\nGCD = 3480bf145713d56f9\nA = 8cf8ef1d4f216c6bcec673208fd93b7561b0eb8303af57113edc5c6ff4e1eeae9ddc3112b943d947653ba2179b7f63505465126d88ad0a0a15b682f5c89aa4a2a51c768cd9fdeaa9\nB = a6fd114023e7d79017c552a9051ca827f3ffa9f31e2ee9d78f8408967064fcdc9466e95cc8fac9a4fa88248987caf7cf57af58400d27abd60d9b79d2fe03fad76b879eceb504d7f\nLCM = 1c05eee73a4f0db210a9007f94a5af88c1cdd2cba456061fd41de1e746d836fa4e0e972812842e0f44f10a61505f5d55760c48ba0d06af78bb6bde7da8b0080b29f82b1161e9c0b5458e05ac090b00f4d78b1cc10cf065124ba610e3acab092a36fe408525e21c0ddc7c9696ed4e48bd2f70423deecfe62cecc865c6088f265da0e5961d3f3a84f\n\nGCD = 917e74ae941fcaae\nA = 652f8a92d96cbf0a309629011d0fbaceb1266bc2e8243d9e494eead4cf7100c661b537a8bea93dec88cfc68597d88a976c125c3b4de19aba38d4ea9578202e59848d42652518348a\nB = 32e07b71979d57e8344e97c39680a61e07d692d824ae26b682156890792d8a766ee29a4968f461aaced5bf049044fba2f4120b1c1f05985676f975d4582e9e82750d73c532cd07b2\nLCM = 23620c7b897dc26c7717e32f3517ac70bf09fbe08f7255ab010cf4cf946f4e96304c425043452c5d5a0e841d3a3cfd9c2d84d9256f3b5974fe3ebfa9255fe20a710d3e6511606c0d85970381101c7f4986d65ad6a73a71507f146b11f903043cfa805cc0b14d4f3072da98bf22282f7762040406c02d5b3ef9e7587f63bab8b29c61d8e30911aa96\n\nGCD = 2b9adc82005b2697\nA = 19764a84f46045ef1bca571d3cbf49b4545998e64d2e564cc343a53bc7a0bcfbe0baa5383f2b346e224eb9ce1137d9a4f79e8e19f946a493ff08c9b423574d56cbe053155177c37\nB = 1bbd489ad2ab825885cdac571a95ab4924e7446ce06c0f77cf29666a1e20ed5d9bc65e4102e11131d824acad1592075e13024e11f12f8210d86ab52aa60deb250b3930aabd960e5a\nLCM = 1032a0c5fffc0425e6478185db0e5985c645dd929c7ebfeb5c1ee12ee3d7b842cfab8c9aa7ff3131ac41d4988fb928c0073103cea6bb2cc39808f1b0ad79a6d080eac5a0fc6e3853d43f903729549e03dba0a4405500e0096b9c8e00510c1852982baec441ed94efb80a78ed28ed526d055ad34751b831b8749b7c19728bf229357cc5e17eb8e1a\n\nGCD = 8d9d4f30773c4edf\nA = 0\nB = 8d9d4f30773c4edf\nLCM = 0\n\nGCD = 8d9d4f30773c4edf\nA = 8d9d4f30773c4edf\nB = 0\nLCM = 0\n\nGCD = 8d9d4f30773c4edf\nA = 8d9d4f30773c4edf\nB = 8d9d4f30773c4edf\nLCM = 8d9d4f30773c4edf\n\nGCD = 6ebd8eafb9a957a6c3d3d5016be604f9624b0debf04d19cdabccf3612bbd59e00\nA = 34dc66a0ffd5b8b5e0ffc858dfc4655753e59247c4f82a4d2543b1f7bb7be0e24d2bbf27bb0b2b7e56ee22b29bbde7baf0d7bfb96331e27ba029de9ffdff7bdb7dc4da836d0e58a0829367ec84ea256833fd4fe1456ad4dd920557a345e12000\nB = 1f3406a20e20ebf96ccb765f898889a19b7636608fd7dc7c212607b641399543f71111d60e42989de01eaa6ff19a86ea8fbde1a3d368c0d86dc899e8e250fc764090f337958ca493119cbb4ad70cbfae7097d06d4f90ec62fbdd3f0a4496e600\nLCM = ee502c50e3667946e9089d0a9a0382e7fd0b75a17db23b56a0eec997a112c4dbd56d188808f76fe90451e5605550c9559ef14a95014c6eb97e9c1c659b98515c41470142843de60f72fb4c235faa55b0a97d943221003d44e2c28928f0b84bf071256254897ed31a7fd8d174fc962bc1311f67900ac3abcad83a28e259812f1ee229511ab1d82d41f5add34693ba7519babd52eb4ec9de31581f5f2e40a000\n\nGCD = ef7399b217fc6a62b90461e58a44b22e5280d480b148ec4e3b4d106583f8e428\nA = 7025e2fe5f00aec73d90f5ad80d99ca873f71997d58e59937423a5e6ddeb5e1925ed2fd2c36a5a9fc560c9023d6332c5d8a4b333d3315ed419d60b2f98ccf28bbf5bf539284fd070d2690aeaac747a3d6384ee6450903a64c3017de33c969c98\nB = df0ac41dbabce1deeb0bceb1b65b1079850052ecf6534d0cff84a5a7fb5e63baee028d240f4419925154b96eaa69e8fbb1aae5102db7916234f290aa60c5d7e69406f02aeea9fe9384afbff7d878c9ac87cd31f7c35dff243b1441e09baff478\nLCM = 687669343f5208a6b2bb2e2efcac41ec467a438fde288cc5ef7157d130139ba65db9eb53e86a30c870bd769c0e0ab15a50f656cd9626621ae68d85eaff491b98da3ea5812062e4145af11ea5e1da457084911961ef2cd2ac45715f885ba94b4082aa76ffd1f32461f47c845b229d350bf36514c5ce3a7c782418746be342eca2721346ade73a59475f178c4f2448e1326110f5d26a0fef1a7a0c9288489e4dc8\n\nGCD = 84b917557acf24dff70cb282a07fc52548b6fbbe96ca8c46d0397c8e44d30573\nA = 81dbb771713342b33912b03f08649fb2506874b96125a1ac712bc94bfd09b679db7327a824f0a5837046f58af3a8365c89e06ff4d48784f60086a99816e0065a5f6f0f49066b0ff4c972a6b837b63373ca4bb04dcc21e5effb6dfe38271cb0fa\nB = 1da91553c0a2217442f1c502a437bb14d8c385aa595db47b23a97b53927b4493dd19f1bc8baf145bc10052394243089a7b88d19b6f106e64a5ab34acad94538ab504d1c8ebf22ac42048bbd1d4b0294a2e12c09fe2a3bd92756ba7578cb34b39\nLCM = 1d0530f8142754d1ee0249b0c3968d0ae7570e37dadbe4824ab966d655abf04cd6de5eb700eba89d8352dec3ae51f2a10267c32fbd39b788c7c5047fe69da3d7ad505435a6212f44899ba7e983bb780f62bcdee6f94b7dba8af7070a4cc008f351ae8be4579bc4a2e5c659ce000ad9c8cdc83723b32c96aeb0f5f4127f6347353d05525f559a8543cd389ad0af6f9d08a75b8c0b32419c097e6efe8746aee92e\n\nGCD = 66091477ea3b37f115038095814605896e845b20259a772f09405a8818f644aa\nA = cedac27069a68edfd49bd5a859173c8e318ba8be65673d9d2ba13c717568754ed9cbc10bb6c32da3b7238cff8c1352d6325668fd21b4e82620c2e75ee0c4b1aff6fb1e9b948bbdb1af83cecdf356299b50543b72f801b6a58444b176e4369e0\nB = 5f64ca1ba481f42c4c9cf1ffa0e515b52aa9d69ceb97c4a2897f2e9fa87f72bae56ee6c5227f354304994c6a5cc742d9f09b2c058521975f69ca5835bce898cf22b28457cd7e28870df14e663bb46c9be8f6662f4ff34d5c4ae17a888eba504e\nLCM = c163cb28642e19a40aa77887c63180c2c49fc10cda98f6f929c8131752ea30b5283a814a81681b69b9d1762e6c1a9db85f480bc17f998d235fd7e64c1caa70ef170c9e816d3e80f516b29f2c80cfb68bf208b4d5082ef078da4314b3f20c7d6c54b0aeb378096b029a7b61c0a4cd14aeddc01004c53915a4f692d2291752e5af46b23d7fa6dd61f2d56c6f4bf8e6119688abac8fd7aba80e846a7764bb3fca0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = 0\nB = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nLCM = 0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nB = 0\nLCM = 0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nB = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nLCM = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\n\nGCD = 120451d8307219aa0c96f328ad653ccd462e92423ca93ed8a3dde45bf5cb9b13cdaf9800e4d05dd71c4db6a129fb3280ee4ec96ec5297d881c1a8b5efccbd91fef21f5c5bf5fba42a4c8eaa358f620a074b7a17054527bdaa58d5acaa0dfdc48ecba1a10ebf4d57bb4215de406e6be13fed3fe493b1cd1e2d11a8d4ac03c47756\nA = 3f8179a8e1f0b342475a855c3e1bae402dd41424cf24a0b4d2e263c8efb08bde7d92eae8607fb5e88b1378f0f1bd0733f229a35be6b1383a48d32749d5d6b32427d26323b7ab05bb5781289e96bfbc21971439319b15f6c0fe93fdb35d0b67ec41443c59a081dd3cef047ac797fccb45bece84c0bb0bb7e1797259526d8ec9cc63ba4d32cfc692ccd3d243cb2b53ac216312f3a8e8c0daa09d21b6150d697639a5e52059414a417c607be8ec0eee2e708219ca", + "dbaf37a369c4485b01ed87bbc2\nB = 2c474e396a2dd9cd10b9d7313f69d3b4ca123e9fd853edd488339236d14c56453a1381958864a04d2624e81995dabcdd0ccf60db9917813f887de68da075d0ea4440001e18f470e43b38ee3440b49be651d709fbdef980e3e4149913f4ae2681124f54523f4881376ddb533b5219e804cc26f4c2e577be4e02613c4da80ba1215775b0a5178a965ad47bd2befb32493943ded1004ef66347b4983f8d1ba990d4a943505dfce6debcfb322842ed88106cd6dee9aa592ff0d2274bc727a6e1f14c\nLCM = 9c129cf649555bfd2d3d9c64dc6d6f022295e53bca5d2f218adaa66aa60eb4694429b7e83bf81b6df4459c5104023ab9a33f006ffcd8114507baa17e2ef6fe23ebdd4740f66879033da2041f2cb7ba517ad3526ffe75614ea9432c085f71b2d65a736bac7ba42b639e330b82733372083843dcb78b6a273ab20e0d4b7c8998a14048aa15bb20a0a0bd997917107274c89b4cec175fb98043d52e6c555bd9e0036566d052a6d4e7e276d1e8835e1f06e3ca46d47747ba586e95fb1a790d992834b7c3e136141eb8a434e6c12067246ac3c0a81c69e03b1ed28aa0b3173d6eff83d278c2f461a47a416f3f9a5dae3bb410fd18817bd4115e7f1e84b936cc02364\n\nGCD = 95aa569a2c76854300d7660847dd20fe0b8c445fdbcaa98465cee61aee76ad6a438e75a8c573198570ffb62bc07ec3a2be0ae0a1f631670fa88d6f75f3161e8b9a4d44b6801ffc884c7f469c5ed1f27b1edecce9f2977f9e92d1a3b230492fea7e6f2af739dc158a7fbd29856cbedb57b4119e64b27ab09eb1c2df01507d6e7fd\nA = 4c653b5bfec44e9be100c064dffe5d8cd59b0cf4cc56b03eabb4ef87cfda6506c9a756b811907fe9d8b783eb7a0b9e129773bf1da365ddb488d27b16fb983e89345d1ccdb4f06a67a11925c3f266373be5d7b0075189c6f3c2157e2da197058fe0a7bcc50adc34e99e254a29abbe2d5948d3157e1b0c3fca3d641760f7b9862843b63abef0b3d83fd486f4526b30382fda355575da30e9a106718a3921774c4d69f5311f8d737fe618f5236b4763fe1b2ee7f13184db67367d3903c535ff6d7b\nB = 2dcca83c99a28e9fd2f84e78973699baf2f04fd454094730948b22477834a0064817b86e0835e6d7b26e5b0b1dcf4ad91a07ac0780d6522df1fcac758cf5db6c2a5623d7c0f1afefd5718f7b6de639867d07a9ec525991304e9355d1635104bea837f74758d6aa2aab4e4afbb606af1d98de7417505e4710cd0589bdff9a0bf38a857cc59a5f1781043e694fc2337fd84bdeb28b13a222bb09328a81ec409ad586e74236393d27398cc24d412135e34247c589149e134b97f4bd538ac9a3424b\nLCM = 1760c0b0066aa0695767099e87e9388729ea89b8e8c36bddcd04d257591e741613c07b0e69447c0a468c33a745084171e06523d987d8db40a1433bf435325e8a724a0876503b34495170ff3671d42117a2e4f3a75b1d9dd809a34fa0fb26fe50d84f80a9b02e40190e5efb927a5a61a03f13edbce2e666af6c3a2a9bcb84e47e3090008753ff27c4b8cf06480f471379a93f5230923623a83b286b71a555cd5e5347282f664ed90b14b2c4de84a70375e488211a7b3931119ef3bbe029b712389fe784818a0bf29d80733ce9cc940c547aa1eb3f06d492eb676bf37802283c82ce76156dfaab5c2d5107e08062681b5fa169f6eb68e1ab8bd9b2005e90bd4fd\n\nGCD = 244b9b1290cf5b4ba2f810574c050651489f2d3a2b03e702b76ebfaf4e33de9bbe5da24c919e68d3a72eadd35982b3a89c6b18b38ff7082ac65263e52b6ec75a5717b971c98257b194c828bff0216a99536603b41a396ea2fb50f5ea7cf3edf10bb0d039123e78593ae9ffcbbba02e51e038533e83b6bc73c70551d6467f39809\nA = 41a0b1310669500681cdf888836f6c556758750f562d743ac780dd4c0d161856380e44fdbb1f8a2786bf45be6b0e7f1cb2cd85f6b9e50acc72793d92383c7d7fb796fc74d32e8fac8225bdc19ae47546d9c9c75f5f06ca684f07daccaf89ccf2cddeb7ec255d530c7dd1e71daf44cafdc9d30fbcb1cbaefae3480585f79f4177e3834a5bc91845e2e8cd8aeb27f484e5e5b2c3c076dbb6c23e91303f0a0fdde83cd33a8ea6ed1549e727b4d766c1017c169710fd98e1585d60f66e121f9180b3\nB = 251f5aeaa60b3959285f49540cdaf8e21451110bbddb9933bbbcaea3112f4eb45e435a3ba37c52d2ab79ce997a8f6c829b3aa561f2852924b8effb52396d09d2bf257ebb4fb56c7aa25648f69b06d2cd01e876c9f9c0679de9e6fffa79eb7e603723e5af7de46ee405a5a079229577b5b6fffb8d43e391fe6f4eb89638e64d6eff8026249aaa355a91625eb0bfd14caa81e4c3586aaa2e94fde143a44f223a91e226661d12f55dfcdb4215e5a64e14e968005733be6a71c465de312ca109b34a\nLCM = 431f918b274f3e43f446e4e85567883d6536a0332db662cef088f5a36b0f4b68372048174ba10fee94b9f8f1c2e189c974be2e6e8ae8e2ae108445326d40f63e38d8d4e2e46174589a3cbc9583e0036dc8146e79eee9e96f4436313b3f143dd0f5aceab05243def7f915169c360f55ef123977cf623c5ba432c3259c62fb5e37d5adab0f24b825aa4ada99ec4e83e9ca4698399e1ed633091ce5f9844c540a642cd264201116ed4168aa2105a5159f5df064f845830c469140f766c7319052ce59bd1ad7c3f2d8c30e54f147f6aeb5586c70c984302ba18d854a60aec01b394c7d66fa33fe18fe4a8cfb3238df219294e6e42190a30d28b10049a1b75853a4e\n\nGCD = 206695d52bc391a4db61bf8cb6ea96188333a9c78f477ee76976c2346dad682cf56ca6f176d86ef67d41ff5921b6162b0eca52359975872430dd14c45643eacdf028d830770714c033fd150669705851b2f02de932322d271d565d26768530c3f6cb84f0b3356f970b9070b26c050ead0417152c324c8ffe266d4e8b5b7bef3a\nA = 1114eb9f1a9d5947eb1399e57f5c980833489685023ed2fe537fe1276c1e026b9a19e6fff55aa889d6c4e977b6e6f3111e2ad463138637b50f42cf32e57d83f282de9e72f813e5969195159a666d74dcd689bd527c60199ae327f7bd548ac36868fea5fdf6f35d19b921e7c10b6448ca480de6826478cd0642d72f05af3f8e65ce42409fbd49f56e81946e89c8e83962c4edc0ed54600600a305e52d081aed3c351e450e11f8fb0ce5754c92cf765b71393b2b7a89c95df79b9ea1b3cb600862\nB = 1d8f3179ca7b5cc7119360c10de939ffa57c9043da2f2b0ca3009c9bdad9f19ed16e3c2c197bef4b527fa1bf2bbab98b77e26c329911db68bd63d3d0fbfc727a977395b9ad067106de3094d68e097830858c5ccfa505fc25e972bdee6f347e7d1163efacd3d29a791ec2a94ffeed467884ae04896efc5e7e5f43d8d76c147e3c9951a1999173bc4e5767d51268b92cc68487ba1295372143b538711e0a62bf0ac111cc750ca4dd6c318c9cbe106d7fc492261404b86a1ba728e2d25b1976dc42\nLCM = f9570211f694141bfb096560551080cbe02a80271b4505591aaea9e3b99ea1d5ac1c1f2378fd72799e117ac2a73381b1ad26314e39972164d93971479ee3ba21a4d98cef0bd299d540ce5826995dcee0de420dff73d30b23cbf3188c625c7696df517535bc5675d71faa00807efbebdca547933f4a37849d1c014484a77da6df0670c4974bcc91eb5f5fe5faf9dd095ef195ec32ad9eeebf0e63288b4032ed9e70b888afc642f4ff96f0b4c0a68787301c12e4527fe79bdfe72dd3844ab5e094a9295df6616f24d1b9eeebc2116177dacf91969dda73667bc421ef3ccd8d5c23dddc283f5d36568d31f2654926be67f78e181075bdc148f2b39c630b141ae8a\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 0\nB = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nLCM = 0\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nB = 0\nLCM = 0\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nB = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nLCM = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\n\nGCD = 2\nA = 14e95a85e59ade9ef39e2f400c65db18702fa5fc485b9bba479a5282b2206129160e54f73ef4917983c17b4c5ebff7be112a886de069706eee29ba902515cb038\nB = ddcfff1d39c90c599f55495bf71c1e7597c6b08b7430707f360c6a6e5137bbc7b403c6d9e2c34f3d2f29d5d32b869346853c2de239cc35381bdfb4a01569211a\nLCM = 90f38564ee72e55d362c04599e7d74f068c75f541b84e97abba2841f1a9f66b06b5c9009f6a4c2e319fced85270588de03ccebddbd9279aaecb13bdc1dbea7f42acaee751cb7da83779b8785cc86f41b94b13b5", + "4964208ca287d981634778d1096f20e76ca636c0717fd27e0800c43f599a5eded807421b502eaf9990a8c8ed8\n\nGCD = 4\nA = 3c719c1c363cdeb7b57c2aabb71f425da4c3e6d3e447204d555e7cf0f3d372bdda906f36078045044978dafc20171767c8b1464d52dfdf3e2ba8a4906da033a8\nB = 30fe0ef151ac51404e128c064d836b191921769dc02d9b09889ed40eb68d15bfdd2edea33580a1a4d7dcee918fefd5c776cbe80ca6131aa080d3989b5e77e1b24\nLCM = 2e4526157bbd765b0486d90bcd4728f890bc6dbd9a855c67ca5cb2d6b48f8e74e1d99485999e04b193afca58dbf282610185d6c0272007744ff26e00dbdc813929b47940b137dc56ba974da07d54a1c50ec4a5c2b26e83f47cf17f4ccce8c3687e8d1e91d7c491a599f3d057c73473723ce9eee52c20fe8ae1595447552a7ee8\n\nGCD = 10\nA = 44e04071d09119ea9783a53df35de4a989200133bb20280fdca6003d3ca63fdd9350ad1a1673d444d2f7c7be639824681643ec4f77535c626bd3ee8fa100e0bb0\nB = ca927a5a3124ce89accd6ac41a8441d352a5d42feb7f62687a5ebc0e181cc2679888ecc2d38516bdc3b3443550efccac81e53044ae9341ecace2598fe5ce67780\nLCM = 36805ba9b2412a0cb3fe4ed9bdabfa55515c9d615a3d0af268c45c5f6098d2de4a583f3791f1e3883c55d51ce23c5658fd0e8faa9a3709a1cfbd6a61dbab861690f27c86664f084c86cfd4a183b24aaadf59a6f8cbec04f1b0ded8a59b188cb46ae920052e3e099a570540dbc00f7d4a571eef08aa70d2d189a1804bf04e94a80\n\nGCD = 100\nA = 73725032b214a677687c811031555b0c51c1703f10d59b97a4d732b7feaec5726cb3882193419d3f057583b2bc02b297d76bb689977936febaae92638fdfc46a00\nB = 979f4c10f4dc60ad15068cedd62ff0ab293aeaa1d6935763aed41fe3e445de2e366e8661eadf345201529310f4b805c5800b99f351fddab95d7f313e3bb429d900\nLCM = 4460439b4be72f533e9c7232f7e99c48328b457969364c951868ceab56cb2cbbeda8be2e8e3cae45c0758048468b841fdb246b2086d19b59d17b389333166ab82ed785860620d53c44f7aaaff4625ee70fb8072df10fb4d1acb142eadc02978ff2bb07cea9f434e35424b3323a7bda3a1a57aa60c75e49ebb2f59fb653aa77da00\n\nGCD = 100000000\nA = f8b4f19e09f5862d79fb2931c4d616a1b8e0dd44781ca52902c8035166c8fca52d33a56ff484c365ec1257de7fa8ed2786163cfc051d5223b4aad859a049e8ba00000000\nB = 6e54cb41b454b080e68a2c3dd0fa79f516eb80239af2be8250ca9cd377ba501aabafc09146fad4402bdc7a49f2c3eec815e25f4c0a223f58e36709eefd92410500000000\nLCM = 6b3020a880ddeff9d17d3dc234da8771962de3322cd15ba7b1e4b1dd4a6a2a802a16c49653865c6fdf6c207cbe0940f8d81ef4cb0e159385fd709d515ee99d109ad9ad680031cbae4eab2ed62944babdade4e3036426b18920022f737897c7d751dce98d626cdda761fec48ad87a377fb70f97a0a15aa3d10d865785719cc5a200000000\n", +}; +static const size_t kLen39 = 18795; + +static const char *kData39[] = { + "# This file contains test vectors for whether B is a Miller-Rabin composite\n# witness for W. W must be odd and B must satisfy 1 <= B <= W-1.\n#\n# The following Python function may be used to check values.\n#\n# def is_miller_rabin_witness(w, b):\n# # Variable names taken from FIPS 186-4 C.3.1 but the algorithm skips a\n# # couple of optimizations in the FIPS formulation.\n# m = w - 1\n# a = 0\n# while m&1 == 0:\n# a += 1\n# m //= 2\n# # b is a composite witness for w iff the following are true:\n# # - b^m != 1 (mod w)\n# # - b^(m*2^j) != -1 (mod w), for 0 <= j < a\n# z = pow(b, m, w)\n# if z == 1:\n# # b^m = 1 (mod w)\n# return False\n# for j in range(a):\n# if z == w-1:\n# # b^(m*2^j) = -1 (mod w)\n# return False\n# z = (z * z) % w\n# # At this point, z is b^(w-1) (mod w). If z is not 1, w has failed the\n# # Fermat test and is composite. If z is 1, the value of z immediately\n# # before it became 1 is a non-trivial root of unity and w is composite.\n# return True\n\n# Exhaustively test a small prime.\n\nResult = PossiblyPrime\nW = 7\nB = 1\n\nResult = PossiblyPrime\nW = 7\nB = 2\n\nResult = PossiblyPrime\nW = 7\nB = 3\n\nResult = PossiblyPrime\nW = 7\nB = 4\n\nResult = PossiblyPrime\nW = 7\nB = 5\n\nResult = PossiblyPrime\nW = 7\nB = 6\n\n\n# Random large inputs which try to cover a few cases. The nontrivial square root\n# case appears to be difficult to hit randomly.\n\n# b^m = w-1\nResult = PossiblyPrime\nW = d6b4ffc7cf70b2a2fc5d6023015875504d40e3dcce7c2e6b762c3de7bb806a5074144e7054198dabf53d23108679ccc541d5a99efeb1d1abaf89e0dbcead2a8b\nB = fabbafdbec6494ddb5ea4bf458536e87082369b0e53a200ed413f3e64b2fddc7c57c565710fbe73fae5b188fce97d8dcca74c2b5d90906c96d3c2c358a735cd\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 52cc61c42b341ad56dc11495e7cb2fe31e506b9e99522efbf44cd7c28468d3833c5e360f3c77b0aa43c0495c4e14665ab0d7cee9294c722f0de47d4401828401\nB = 3bdc9639c0fc2e77ab48d46e0b4ac6529c11c900e8fe4d82d75767c0556feb23d3f42d4924d16876a743feb386b7b84c7fd16a6c252f662faf0024d19972e62f\n\n# b^m = w-1\nResult = PossiblyPrime\nW = cff9897aa7dce0f2afad262b2de57d301305de717f3539c537c4ce062f8cb70df13fbc1eb4a3b9f0958a8810d1ca9042b4f23334b285a15fee3fc66498761d4b\nB = 9ceb43132fddf9ee4104ea1cb3eb2253c1d7f803f05f0305de9e31a17dd75832f47b8bf189a9b7ca0905f2a7470d9c6349080f481ff1708696fa12d972e7d7ba\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 67d1825dad5344170e65247a87aef1634a1b32bdc22f2f04d9d2959767bb5a27610fba55cd607e0f9fdd9fbb0f7f98e40d5e1eb2f52318fb5be4dbfd30d38861\nB = 260fb14724ff80984736859d8755ee98b25bcb56db9fde1db001a1e1273374034c5b75fd60b3710c7a08ce7d390776f010f384d4e32943cf0c477497d53e9e05\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = ad0bc85b58aaa204177aa9431a40929beb1cbea2dd6f66a25cc54600013213b225ba881805661df43f4208965ada7aacc8095d07d3cbef1a7bbfaae8b745f731\nB = 3d9310f20e9c80269fa6830c7e1a6f02fc5c58646001a9ef6b8b3e496602ff22c3dcb2ddb6a221723fc1722ce237fb46f7a7bb2945e415c8839b15a972f076c9\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = b25c917f55f6c7b596921daba919f35039e5d805119c1587e99849dd7104460c86214f162a6f17aea847bc7f3859e59f2991d457059511972ef373d4bc75e309\nB = a1f10b261dee84619b0423201d46af19eef9ec0612cf947c4d5c36c0c4b28207f75967e69452eabad0a5dcd28f27f7a8a7ed9c8b3e5026c6e0ba5634d94c2d44\n\n# b^m = 1\nResult = PossiblyPrime\nW = d3eeb0eff05b6992e9fa61b02755e155f4aae28c6e45ddb874edd86acdd2d83d18a20e0e00d8b8bc94b92d14fc3f41ced6ababe8ac98c7730c075dbe0f699369\nB = 6b7717269c6225203681a1cacec87cacd83003ec6e9e3f04effcc4f86634770c0860e1f2770b8f303719a44949664a1094205a99d95a0856758fed66d690105e\n\n# b^m = 1\nResult = PossiblyPrime\nW = 64561b8d9aa50340c3a01ccb3e6e17f5023513661c012be288f3900a3ca76890e67290b9560fa1d480f9d2aacccca581b5690636665f243fa13aff5d0bff12d3\nB = 1f5ff70d3d60671ebc5fbfca731898a04438053dbc3c841e6335f487e457d92d9efb5d506d5bef6872d58d12b9a41c950bfc38d12ed977c90eacdd6535b811a0\n\n# b^m = 1\nResult = PossiblyPrime\nW = 69c63fbf44df21b0ed0ee929a740c12d1f3f064da0dcd9d509f31fa45fa27d1a759ab5a9f6f1040d7ee90a0b1e68f779273c41ea1c1198fd547ff6bd70c7e787\nB = 5f7996a9bbfd8fd88e472220b70077bfdacdd63d88885134431f024c2acb7126827b174eb093eb5313f07bb5461de9b0feb7d77ca2c39c2a323a150f33ea525f\n\n# End of iteration\nResult = Composite\nW = 28cc3e08c44571c6dcb98a9ab8b4f3e2b16e1f884997d94a3188bcbb7f1b7cdaecdae8329c013ec8f75dc00004da0039943e4262cd080b16a42910102e00dddb\nB = 512061ab1c69931c2fa0bb89d8d09f3c9209230bf927ddd6fb6a72075f967ed3c4dbb5f437bf4d31ca7344782b22011ad56609dc19aed65319bababfc13dd7\n\n# End of iteration\nResult = Composite\nW = 4eeb7b4d371c45fe8586fee3b1efd792176b70f6cc2698dfa1dd028366626febe0199c3c5f77a5c3cad0057a04767383051d41965255d03681b2a37edad34a9b\nB = 4afc2e85f84017b3fd6967a227eb74c8297b40ea02733d9513bff9b3f01081963f25872f4254afc4e9321eea35b2a1e42eadb186fcc84f2f30f4a994350b93b8\n\n# End of iteration\nResult = Composite\nW = 8e35a959555dd2eb66c65cee3c264071d20671f159e1f9896f1d0ceb041905fcf053eacc189de317c3ee6f93901223cbf30d5b7ddbbdab981790e2f6397e6803\nB = 44c0153759309ec4e5b1e59d57c1b126545ef7ea302b6e43561df4d16068b922389d6924f01c945d9080d1f93a0732599bdedae72d6d590839dc0884dd860441\n\n\n# 0x6c1 = 1729 = 7 * 13 * 19 is a Fermat pseudoprime.\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = b8\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 111\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 11d\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 19c\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 223\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 3aa\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 653\n\n\n# 1729 has a number of false witnesses.\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 78\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = eb\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 178\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 178\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 1aa\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 271\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 2b2\n\n\n# 1 and W-1 are always nonwitnesses.\nResult = PossiblyPrime\nW = 6c1\nB = 1\n\nResult = PossiblyPrime\nW = 6c1\nB = 6c0\n\n\n# https://kconrad.math.uconn.edu/blurbs/ugradnumthy/millerrabin.pdf, examples\n# 3.1 and 3.2 has a complete list of false witnesses for 65 = 0x41 and\n# 85 = 0x55.\n\n# b^m = 1\nResult = PossiblyPrime\nW = 41\nB = 1\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 8\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 12\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 2f\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 39\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 41\nB = 40\n\n# b^m = 1\nResult = PossiblyPrime\nW = 55\nB = 1\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = d\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 26\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 2f\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 48\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 55\nB = 54\n\n# Other witnesses for 65 and 85 will report composite:\n\n# Found non-trivial square root\nResult = Composite\nW = 41\nB = 2c\n\n# End of iteration\nResult = Composite\nW = 41\nB = 16\n\n# End of iteration\nResult = Composite\nW = 41\nB = 14\n\n# End of iteration\nResult = Composite\nW = 41\nB = 2\n\n# End of iteration\nResult = Composite\nW = 41\nB = 3a\n\n# End of iteration\nResult = Composite\nW = 55\nB = 40\n\n# End of iteration\nResult = Composite\nW = 55\nB = 7\n\n# End of iteration\nResult = Composite\nW = 55\nB = 23\n\n# End of iteration\nResult = Composite\nW = 55\nB = 2e\n\n# End of iteration\nResult = Composite\nW = 55\nB = 2a\n\n# W below is composite, but it is one of the worst case scenarios for\n# Miller-Rabin, from Wycheproof tests. 1/4 of witnesses report the value is\n# prime. Test that we correctly classify false and true witnesses.\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 379c6027f818b5164bc13dff", + "5e996ec7210976f33570d5c60275918b8988d97a63bb6582af85682c45667a8b94b7acab4d919ede00f5bd2ba7abc8634d66f8875fd930f35ec8013d37b958e65f07de015c0574e64198d73aab5466f3a971b74830b7f1671cb9277fbc95c1ba8c29dc903d8cea1b74c22ab9164f9c438ab9ba7d9919f832e40c3e36faca7343e2314669b0104d9c4f2e1b011cdbd9c686baef0\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 3cc4b644965b2133caffc2bb6258b1ecd5b586b900a09b010382fcef709e4cd37ee3e3182bf8d393c1ab6f9a933d46338b3d960923d8c9607c2b2763d5680230a2bc0c91138e9d0ecb35e7154a06aaa902d34b9b14964b81f4d8232641492d83b22cd805a115e75ddd8e63b864c00e4c90ba36a41e7966e97e063a60a6a6cfd53e1f62a57852c7443e88dcf6245557a4b65494c3e88e466ad75316aaa9727def\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 40c03b6ba22bd62c0379b1c36dfccd34d61e3d15f7af1d5f6a60ab972a9d0e956e2bb9e275294e0f1c879eb7a4555443429c99a8d74f7bd359a1046ac30072c04b0e2cbd005be15ff4ce0c93276de2c513fbc5771b5059904a87f180530f6773498114b5aaf70da01967d8294742e451df6377dd5e64b2a8968f4ba61b51a154317d63958ff3788defbeeebee21af5027c2291e8c5df8c0b66770d91b683cffe\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 3c7c71b84f0c6c3817f57511946315cec7d0120a9c30ceabda801fbaec329a8f10c7b9f0ae90a3dada9885bf73a3cabed86784af9682f3dea50a7817f65cfc9190cf997f12784223c4965ed6e52a1be26d4dde31741cd3d1a2e2f3a74040d0f3868eef849727aa855f66c94791194ad5d360298364e2de9ca9288e6423f644b01d52e1bd66a9f7f00bd7995a9ca2ed16f40e902852c6250a3b52bbbf5bfd33e8\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 36e6aa9acb399a50f52be0324dcef05f3cff3117f94538f6d0952b7d7be88ba4dc75d843ff7ff775e11f55c86ba6b2a6ddebd8850c33424b4d35c66321af426662e7074f0a2409a9ccf1c66ef7d823efc8240b8f3c7e9e8dd65a64e8a3ca5b26695ef17171ffe136c0593b179414c5b5ad0d66f2a25146c38b2f97e60b0472ed72de34bff1b6ac186f23645a1bbe909cdfc2b2d861eb44931568f1bb117d8a0c\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 278f2215d3ab836043fbfa472216bbdcedb775a6a0ed711754d05aa75089a9e5d8201e113d68656f37381e44483cd365f5d383bdca5ae8d1f2e6575d7873851cfff0e12b1cfe100a04cb300cbd924353fcbd3307d01242cf6a5e86e752c6f4586bcabf48b018bb97e65c3ed409fd6f67f98987517356d88344b3c8945ccd753148a37b648dd2db44d19522a69a9ad8eb23edc55340e85a198abf179ad731db41\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = afa1478bebbfe1157568f4ae53549b4c3a6a8771b816970bfac6ce5c8b962231db7a41da4d5f1d8bf504dcfe440325b54e1888bdae344eb969436a35e5c6ce5300d46313cb2fcb57fc83305f65f53d392de400e9231cbbc2ac8243defcaf7063c632b9601a81d83138274702ff336d727d3e82ccacce069843ac9c1c590c772c8c586b65c7085a1df5a47fc960d4098a22418b41f0062c77b5d55d17149d167\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 10f7030590b629e0313a61bdf46936a1f25db91b2b421f7ebb671f7844c22561b44b2f7699db61e5228ebb5817afad416325f9439eff7a82d8a630c504de12eaa44d97c79ee56e726ae74ee0b472f0d5fa8f20aee426e689cd33dd084f96bf4d928a21e815f7e8aaca4a5752f39c4a76bdfaa8227dc05d0dfa885d8b26d46fbcbf0d2e0d999d2c31ad84c306c9126539dbdf447f8dc707d29c7fa8021a767668\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 97dbb6a55c039ec926aaa5ff15a2917a2b4cafc3ca07c4c6b05f931d86c9bf60ee05cbbace194e5ca97682ec67c36394018d68c3536fbf13b50f8a7e31eaed87307759a0a48c6c58d21bc7c38b878c53db5d7a8e1fdd81abefc50470a3800852e74d76fdd1933e45f39ee97b8efb68837721890d867b32a894dd0ceb4c5844a05d384145865c10973ce748ccdd8fee73f1bf8611ce0535430b6b98fb36cad7a\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 225f58add44ed2b0a64a1d8452866d0f3c0cd45c8375e1bb33c188915c77fa11b81250b920245dda7f6126e5e0c79e6f98f89dc15db86394cf81b44f0d801e613fa4d5c6fef66fa31f26cfe6153f2e8159aad6b0351dcc0e93f9a68f649b2a77cff747b605b542d22419166befebec6cde3201e3c0cacaa2bc9d87073b8d1f1aa2b114d61de45ac8b0ad2141b43434a629ef284cd999fd82b310db7c57cf5c81\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 2780926c9cf7c1eb2aaa935d90b6d4dea44eeefdfcf9ccd4a33feb215e3a1cb2d358136a490fed18403947f3d98807819737c66e12d42c3cc8c0e246b96b3c3b0795ab875fbaf668b81b5b05bf23e258ea00a0a140a790f76e04ab619800b7597f614ffc1a1c94be2f3f1a71d64eb47d98e4653d76eabedacff3a97ecf590e6a1fd55096b7bc9314629f698d0fbe9b01a1f2bc0bf3a2c097f99f1fd222b52ed2\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 129cc5b0d9f8001b3895f1fcb4833779763636aeeeb3f980e63ea506202e6bde868444b6a58ff1dca08625f025a7e95a5eaaf1a8899eee640e3f05fbdb2867e2483bdc27c87b58684416e521c107f3667ed8dd23f0381edab767c5205a4378118bc011947cb6bdfe3fa4af50b8de876b555c9a0b2b0dae01261847f63e1e0cac2d032530bf19d5da60a04dfe22ce6343f60defbb94ccf0bdf010f89a4029720\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d", + "9a6cdcf912a2dd0a12ba7e87\nB = 4e2a47cf67c3331b1e9976f583f6339cf76a8d48682d01355c25b2aed90c5544e737ecfa849c17d27a64fad7e659ef48df9a3ac0410e5c7ca8d087fc3a3ba23e5a3f000be009fcc8227ead28158c5b5d66f2efb47111638ef61cea4984de42fbd476bc2236ad02154d3ce85805c45e49d16b496e313a4052a37d4b88a3b13e598d2074a3e36a37e90278601f2b2305e034f9bf3aea8e939c3ba274e8ff4d8a14\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 2455c4ab826e2ae72708a8ff51348ce4821cb86fa89e298c751c1754211c63b2e9a712d40f0235f310606fcf296726a86973f19f890d571f5b90f026e8d24d07bc0478a3c1333171587387f1f7fe4a770b593216f2743318aabacb3320c40a4e52b9f409e1176fe8db099e93a7991eb8568168e2e486fa5aa228bb1dce9df3290ef13fd21c331479bb0f8b7a7e7f03c5211ae8cc46fa4d0f46e86b2dadeddd5b\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 9951c2c02dd7deedce29bd0c78dd80066b1d69c0e6fe4a17f7d03c6a640d866d01fc8214bafb6737efd93d80a35b8993f5367ce287459b07954e9771ffbc72ccdd812d26a9bf4be0292a24eb5c3b56f09619b1c1b481f7566f7e50e65f69f5feb591bd107fec72a783429dbde6e2607f3db2c58d4b070a45b4d6b43537e19942ce890b04ae1e91069c04a96ed03ddb2f4fc456f136b98102c70a15700dbd911\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 4cb8217d229d5f95f6d94807a99363823655d6bba6bdafa4f0dbfe7a5c538aa79c918710aad4f55caaee5ab405ebdcef29dfb76cae99fca8d5a955b6315f71a3cb2d69a217ff45aed66ba87cdc5c0de5d512c6dd12e641e9fe6a2557dd2f03bf3a18650ff139efa179f0fbe69cbb4b54e50d13177bfe7bb90de36b548d5ccfef74b05d3c08a7e2a3bb4dc8d7eb338a7a1b068c433ea204d171eda5e7c6b6722c\n", +}; +static const size_t kLen40 = 71435; static const char *kData40[] = { + "# ModExp tests.\n#\n# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.\n\nModExp = 00\nA = -01\nE = 01\nM = 01\n\nModExp = 01\nA = -02\nE = 01\nM = 03\n\nModExp = 01\nA = -01\nE = 02\nM = 03\n\nModExp = 01\nA = -02\nE = 02\nM = 03\n\nModExp = 00\nA = -03\nE = 02\nM = 03\n\nModExp = 02\nA = -04\nE = 01\nM = 03\n\nModExp = 01\nA = -04\nE = 02\nM = 03\n\n# Regression test for carry propagation bug in sqr8x_reduction.\nModExp = 19324b647d967d644b3219\nA = 050505050505\nE = 02\nM = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# Cover the E = 0 case for small numbers.\nModExp = 01\nA = 86b49\nE = 00\nM = 30d26ecb\n\nModExp = 00\nA = 00\nE = 00\nM = 01\n\nModExp = 208f8aa0\nA = 86b49\nE = 2\nM = 30d26ecb\n\nModExp = 27308229\nA = 17591bb\nE = 6\nM = 30d26ecb\n\nModExp = 2bdf498f\nA = 21292626\nE = d\nM = 30d26ecb\n\nModExp = 11317167\nA = 4a655df24\nE = 10\nM = 30d26ecb\n\nModExp = 2e1b88e\nA = da6b761a86\nE = 35\nM = 30d26ecb\n\nModExp = 20a12ec3\nA = ea811\nE = 2\nM = 23bc042f\n\nModExp = c42ced\nA = 1011a6a\nE = 4\nM = 23bc042f\n\nModExp = 4637d79\nA = 28d9a601\nE = 8\nM = 23bc042f\n\nModExp = 20e5669b\nA = 72fe6bc20\nE = 11\nM = 23bc042f\n\nModExp = 142ab9e3\nA = 9a07b9363c\nE = 29\nM = 23bc042f\n\nModExp = 14c64646\nA = 822df\nE = 3\nM = 30915765\n\nModExp = 160e35a2\nA = 15ea542\nE = 5\nM = 30915765\n\nModExp = 2f23a488\nA = 34d2e02e\nE = e\nM = 30915765\n\nModExp = 28e67f93\nA = 636a32703\nE = 14\nM = 30915765\n\nModExp = 29bfeaa5\nA = c8646998e6\nE = 2c\nM = 30915765\n\nModExp = 30959e22\nA = 81dad\nE = 3\nM = 326dd68d\n\nModExp = 1a1da4fa\nA = 116adb9\nE = 5\nM = 326dd68d\n\nModExp = 272bf0d8\nA = 2d21ef08\nE = 8\nM = 326dd68d\n\nModExp = 29f5054b\nA = 76989850a\nE = 16\nM = 326dd68d\n\nModExp = e6c7b77\nA = b88ee70d2a\nE = 3e\nM = 326dd68d\n\nModExp = 369605e1\nA = cf26f\nE = 2\nM = 3ce082eb\n\nModExp = 168a3c5d\nA = 1f82caf\nE = 5\nM = 3ce082eb\n\nModExp = 125c4bb8\nA = 2e9c4c07\nE = 9\nM = 3ce082eb\n\nModExp = 1c5fe761\nA = 523ab37f1\nE = 14\nM = 3ce082eb\n\nModExp = 21703009\nA = dc832165e8\nE = 20\nM = 3ce082eb\n\nModExp = 1228d1e\nA = a5555\nE = 3\nM = 24665b27\n\nModExp = 5226af4\nA = 1077bd6\nE = 4\nM = 24665b27\n\nModExp = 1b14eac1\nA = 2db3a834\nE = f\nM = 24665b27\n\nModExp = 161727bc\nA = 6bd962cb6\nE = 19\nM = 24665b27\n\nModExp = 10d61d0d\nA = c10caed407\nE = 28\nM = 24665b27\n\nModExp = 233da406\nA = b125f\nE = 3\nM = 33509981\n\nModExp = 24032799\nA = 1656b7c\nE = 6\nM = 33509981\n\nModExp = 129ecebe\nA = 2e671504\nE = a\nM = 33509981\n\nModExp = 20c20bac\nA = 4d7a2de44\nE = 1f\nM = 33509981\n\nModExp = 2e3ce9d3\nA = c53b3def4d\nE = 31\nM = 33509981\n\nModExp = 12fadfd6\nA = b4cf8\nE = 2\nM = 36e9d4ae\n\nModExp = 457ac85\nA = 1b1c7e9\nE = 7\nM = 36e9d4ae\n\nModExp = 31debef4\nA = 3a973028\nE = d\nM = 36e9d4ae\n\nModExp = 2333ad93\nA = 552b97c45\nE = 11\nM = 36e9d4ae\n\nModExp = 99ba1fb\nA = 8bfb949cbb\nE = 28\nM = 36e9d4ae\n\nModExp = 27b691de\nA = 93492\nE = 3\nM = 298fdb16\n\nModExp = 3c2b70f\nA = 14e7b0d\nE = 4\nM = 298fdb16\n\nModExp = 1486cda7\nA = 29acff81\nE = c\nM = 298fdb16\n\nModExp = 11725275\nA = 507489205\nE = 13\nM = 298fdb16\n\nModExp = 24d14627\nA = e71c55606d\nE = 35\nM = 298fdb16\n\nModExp = 222b8d14\nA = 9b1a0\nE = 3\nM = 3db59d12\n\nModExp = 3b8bd47d\nA = 13f4e8d\nE = 7\nM = 3db59d12\n\nModExp = 17e72356\nA = 334774ce\nE = a\nM = 3db59d12\n\nModExp = 306447ca\nA = 47079ddd2\nE = 12\nM = 3db59d12\n\nModExp = 90bef3b\nA = a75d62616d\nE = 37\nM = 3db59d12\n\nModExp = 1\nA = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678\nE = 0\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 0\nA = 0\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9\nA = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 1\nA = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1\nE = 0\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 0\nA = 0\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0\nA = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 1\nA = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600\nE = 0\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c84", + "92c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 0\nA = 0\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff\nA = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 1\nA = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc\nE = 0\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 0\nA = 0\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f\nA = b4fde2908745ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 1\nA = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f\nE = 0\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 0\nA = 0\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9\nA = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 1\nA = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef\nE = 0\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 0\nA = 0\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e\nA = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 1\nA = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b", + "1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332\nE = 0\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 0\nA = 0\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8\nA = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 1\nA = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79\nE = 0\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 0\nA = 0\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9\nA = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 1\nA = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8\nE = 0\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 0\nA = 0\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa\nA = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 1\nA = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d\nE = 0\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 0\nA = 0\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca\nA = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726", + "bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\n# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in\n# order to test the const time precomputation scattering/gathering.\n\nModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b\nA = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898\nE = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f\nM = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d\n\nModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679\nA = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc\nE = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3\nM = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf\n\nModExp = 465ff295786a88496828fdc763e9292d557957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d\nA = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d\nE = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560\nM = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101\n\nModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd\nA = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9\nE = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c\nM = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479\n\nModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c\nA = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785\nE = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082\nM = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d\n\nModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e\nA = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059\nE = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902\nM = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9\n\nModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556\nA = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0\nE = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965\nM = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed\n\nModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510\nA = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468", + "426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83\nE = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693\nM = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11\n\nModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232\nA = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef\nE = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6\nM = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d\n\nModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e\nA = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286\nE = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0\nM = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7\n\n# See https://github.com/openssl/openssl/commit/e9e726506cd2a3fd9c0f12daf8cc1fe934c7dddb.\n# OpenSSL's test vectors do not include the expected value, so ModExp was\n# computed with Python 3.\nModExp = ccb051a34f9e26e381e50445632cbbd4abe56bc912020f3edd2db144aedb470095c4c33e3342d1dc4bb4056ba3078366af4cee507e85bb1b2e499ef25a933810f14faa8b1a9ce5e8d58f2789e27c887a4ff87fa59ff682727a3912a99aae6db8b3b8947d76c8454cffc6fb3f2422dca106c3845b0db68a06e5e9d7b90e552506579d812e7d96bfc6324feec90ea0800463346148f120e7caf403788539f5d87ee45aa5b313c340e0a323029f3a0bdb675510aefec171c01e2a94960cd507e461214028c86ed4e9fce31e7dbdf1a75fd6f973e2aed4a039e53a60a7aa62be8ee1f80a113833ab402d07e17151021cec29fa5b2e628ef9f2d7aa4bc86b6eec8faf\nA = 95564994a96c45954227b845a1e99cb939d5a1da99ee91acc962396ae999a9ee38603790448f2f7694c242a875f0cad0aae658eba085f312d2febbbd128dd2b58f7d1149f03724215d704344d0d62c587ae3c5939cba4b9b5f3dc5e8e911ef9a5ce1a5a749a4989d0d8368f6e1f8cdf3a362a6c97fb02047ff152b480a4ad9852d45efdf0770542992afca6a0590d52930434bba96017afbc9f99e112950a8b1a359473ec376f329bdae6a19f503be6d4be7393c4e43468831234e27e3838680b949390d2e416a3f9759e5349ab4c253f6f29f819a6fe4cbfd27ada34903300eda021f62839f5878a36f1bc3085375b00fd5fa3e68d316c0fdace87a97558465\nE = f95dc0f980fbd22e90caa5a387cc4a369f3f830d50dd321c40db8c09a7e1a241a536e096622d3280c0c1ba849c1f4a79bf490f60006d081e8cf69960189f0d312cd9e17073a3fba7881b21474a13b334116cb2f5dbf3189a6de3515d0840f053c776d3982d391b6d04d642dda5cc6d1640174c09875addb70595658f89efb439dc6fbd55f903aadd307982d3f659207f265e1ec6271b274521b7a5e28e8fd7a55df089292820477802a43cf5b6b94e999e8c9944ddebb0d0e95a60f88cb7e813ba110d20e1024774107dd02949031864923b3cb8c3f7250d6d1287b0a40db6a47bd5a469518eb65aa207ddc47d8c6e5fc8e0c105be8fc1d4b57b2e27540471d5\nM = fef15d5ce4625f1bccfbba49fc8439c72bf8202af039a2259678941b60bb4a8f2987e965d58fd8cf86a856674d519763d0e1211cc9f8596971050d56d9b35db3785866cfbca17cfdbed6060be3629d894f924a89fdc1efc624f80d41a22f19009503fcc3824ef62ccb9208430c26f2d8ceb2c63488ec4c07437aa4c96c43dd8b9289ed00a712ff66ee195dc71f5e4ead02172b63c543d69baf495f5fd63ba7bcc633bd309c016e37736da92129d0b053d4ab28d21ad7d8b6fab2a8bbdc8ee647d2fbcf2cf426cf892e6f5639e0252993965dfb73ccd277407014ea784aaa280cb7b03972bc8b0baa72360bdb44b82415b86b2f260f877791cd33ba8f2d65229b\n\n# The following inputs trigger an edge case between Montgomery reduction and the\n# \"almost\" reduction variant from https://eprint.iacr.org/2011/239\n\nModExp = 00\nA = 19c7bc9b97c6083cd7b8d1cd001452c9b67983247169c6532047eb7fc8933014dbf69fee7a358769f1429802c8ea89d4f9ca6ba6f368fbdb1fa5717b4a00\nE = bbc7e09147408571050e8d0c634682c5863b7e8a573626648902cff12e590c74f5a23ecce39732266bc15b8afbd6c48a48c83fbdc33947515cc0b6e4fb98ae2cd730e58f951fec8be7e2e3c74f4506c7fd7e29bdb28675fe8a59789ab1148e931a2ebd2d36f78bc241682a3d8083d8ff538858cd240c5a693936e5a391dc9d77118062a3f868c058440a4192267faaaba91112f45eee5842060febbf9353a6d3e7f7996573209136a5506062ea23d74067f08c613f3ff74bade25f8c3368e6dba84eae672eac11be1137fc514924fcab8c82e46d092bd047dcbadaa48c67a096ec1a04f392a8511e6acbad9954949b703e71ff837337b594055ae6f3c0fc154447a687c9ac8a2cdfd64a2e680c6ff21254735af7f5eb6b43f0bce86bda55a04143a991711081435ed4f4a89b23fc3a588022b7a8543db4bf5c8ac93603367c750ff2191f59a716340fab49bb7544759c8d846465eec1438e76395f73e7b5e945f31f1b87fefa854a0d208846eaab5fa27144fd039911608bab0eaee80f1d3553dfa2d9ba95268479b97a059613660df5ad79796e0b272244aca90ccc13449ec15c206eeed7b60405a4c5cfdf5da5d136c27fa9385d810ad198dfe794ffce9955e10520efea1e2eb794e379401b9affd863b9566ce941c4726755574a1b1946acf0090bfb93f37dd55f524485bbba7fa84b53addfde01ae1de9c57fe50d4b708dd0fa45d02af398b3d05c6d17f84c11e9aacdbe0b146cad6ddbd877731e26a17f3ebed459560d12ed7a6abc2ea6fe922e69d2622ef11b6b245b9ba8f0940faaa671a4beb727be5393a94dafaeff7221b29183e7418f4c5bb95a6a586c93dbc8ce0236d9dbe26c40513611b4141fed66599adbfb20fc30e09a4815e4159f65a6708f34584a7a77b3843941cd61a6917dcc3d07a3dfb5a2cb108bacea7e782f2111b4d22ecaaeff469ecd0da371df1ac5e9bf6df6ccba2d3a9f393d597499eaca2c206bfb81c3426c5fe45bcf16e38aecd246a319a1f37041c638b75a4839517e43a6d01bee7d85eaeedbce13cd15699d3ee42c7414cfed576590e4fb6ddb6edd3e1957efaf039bfe8b9dc75869b1f93abff15cae8b234161070fa3542303c2ed35ca66083d0ac299b81182317a2a3985269602b1fa1e822fcbda48e686d80b273f06b0a702ca7f42cbbbd2fc2b3601422c8bff6302eda3c61b293049636002649b16f3c1f0be2b6599d66493a4497cd795b10a2ab8220fafad24fa90e1bfcf39ecce337e705695c7a224bf9f445a287d6aab221341659ca4be7861f6ac4c9d33dac811e6\nM = 519b6e57781d40d897ec0c1b648d195526726b295438c9a70928ac25979563d72db91c8c42298a33b572edecdf40904c68a23337aa5341b56e92b0da5041\n\n# To fully exercise BN_mod_exp_mont_consttime codepaths, we generate inputs at\n# different bitwidths. rsaz-avx2.pl only runs at 1024-bit moduli, and\n# x86_64-mont5.pl unrolls 8 64-bit words at a time, so we want to capture both\n# multiples of 512- and non-multiples. Also include moduli that are not quite a\n# full word.\n\n# 512-bit\nModExp = 00\nA = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 8f42c9e9e351ba9b32ab0cf69da43f4acf7028d19cff6e5059ea0e3fcc97c97f36a31470044737d4c0c933ac441ecb29e32c81401523afdac7de9c3fd8493c97\n\n# 1024-bit\nModExp = 00\nA = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000002f\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 9da8dc26fdf4d2e49833b240ee552beb7a6e251caa91bfb5d6cafaf8ed9461877fda8f6ac299036d35806bc1ae7872e54eaac1ec6bee6d02c6621a9cf8883b3abc33c49b3e601203e0e86ef8f0562412cc689ee2670704583909ca6d7774c9f9f9f4d77d37fedef9cb51d207cb629ec02fa03b526fd6594bfa8f2da71238a0b7\n\n# 1025-bit\nModExp = 00\nA = 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 010223abfdda02e84e11cec8ee7fc784fa135733935f7b9054bb70f1f06d234d76dcf3beed55c7f39e955dc1fef2b65009240fd02f7a1b27a78fc2867144bf666efb929856db9f671c356c4c67a068a70fe83c52eebda03668872fd270d0794f0771d217fb6b93b12529a944f7f0496a9158757c55b8ee14f803f1d2d887e2f561\n\n# 1088-bit\nModExp = 00\nA = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = e91f6d748773cb212a23aa348125615123b1800c9ea222c9374c757702ae4140fa333790ed8f6bf60a1d7dda65c2767cc5f33e32e333d19fbfb5a2b85795757c9ca070268763a618e9d33873d28a89bf88acd209efbb15b80cd33b92a6b3a682e1c91782fc24fb86ddff4f809219c977b54b99359094bbcc51dfe17b992ab24b74a17950ad754281\n\n# 1472-bit\nModExp = 00\nA = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = a8770362f4bfe4fc1ab0e52705c11a9b6ba235d5a5f22197c2d68e27ed18426ede3316af706aa79bcf943dbd51459eb15ae1f9386216b3f3a847f94440a65b97659bc5ba2adb67173714ecaa886c0b926d7a64ea45576f9d2171784ce7e801724d5b0abfd93357d538ea7ad3ad89a74f4660bdb66dfb5f684dcf00402e3cdf0ab58afd867c943c8f47b80268a789456aa7c50a619dd2f9f5e3f74b5d810f0f8dadbf4ad5b917cdcb156c4c132611c8b3b035118a9e03551f\n\n# 1536-bit\nModExp = 00\nA = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 878cd000778f927b2f1a4b8bac86efd282079a7ac0d25e09ffd2f72fbc282e65e233929d2457c7b1d63c56fb706cdfa04fb87e654c578c98d7cf59c2293dc5641086b68db4867105981daaf147a0ee91f6932ef064deae4142c19e58d50c0686f0eaf778be72450f89a98b4680bbc5ffab942195e44dd20616150fd1deca058068ca31ab2f861e99082588f17a2025bf5e536150142fca3187a259c791fc721430f24d7e338f8dc02e693a7e694d42775e80f7f7c03600b6ae86b4aba2b0e991\n\n# 2048-bit\nModExp = 00\nA = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 9f40a7535c561208ecb38e17c9336d9bc8484d335901b2cd42759cf03689227f6992f10cb6b586d767fbcdf30e9d82a0eda60d2694ccd0194fa96b50b56e0cdeec1951ea9e58b07e334a7f108841a0ab28256917fecea561388807ed124a17386a7a7b501f9cbf3404247a76948d0561e48137d3f9669e36f175731796aeaf78851f7d866917f661422186a4814aa35c066b5a90b9cfc918af769a9f0bb30c12581027df64ac328a0f07dbd20adb704479f6d0f233a131828c71bab19c3c34795ea4fb68aa632c6f688e5b3b84413c9031d8dc251003a590dec0dd09bfa6109ed4570701439b6f265b84ac2170c317357b5fbe5535e2bbdd93c1aacfdaa28c85\n\n# 3072-bit\nModExp = 00\nA = 80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = c23dfd244a58a668d514498a705c8f8f548311b24f0f98b023d2d33632534c2ae948d6641d41fd7a29fbbd594bfc7fdd6e8162cbb3056af3075347b6fc8876458d33a9d0ffdbcdf482de0c73d1310fd8fa8f9f92dd0dbb0e2034e98a30f6c11b482f7476c5b593f673a322b1130daa4314e9074270dce1076436f0d56cf196afcbb235a9a7b3ac85b9062e85fc0e63a12c468c787019f6805f9faab64fc6a0babc80785d88740243f11366bffb40ccbe8b2bb7a99a2c8238a6f656bb0117d7b2602aa400f4d77de5f93c673f13264ca70de949454e3e3f261993c1aa427e8", + "ef4f507af744f71f3b4aaf3c981d44cc1bfb1eb1151168762b242b740573df698e500d99612e17dc760f7b3bf7c235e39e81ad7edbe6c07dbb8b139745bb394d61cb799bcafec5de074932b0b2d74797e779ac8d81f63a2b2e9baa229dfaa7f90f34ffade1d2ad022a3407d35eb2d7477c6ae8ad100f6e95c05b4f947c1fabfb11a17add384e6b4cd3a02fd9b43f46805c6c74e366b74aa3b766be7a5fbbd67fa81\n\n# 4096-bit\nModExp = 00\nA = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nM = 8030411ecbddcb0fe4e76fd6b5bf542e8b015d1610cf96130ded12ba2cda0641bd9692080f218ea8b0d751845b519d95b843542ec8d2a07f1f93afe3189b69a4f35c983011c7f7928c3df458cc3eae85c36e6934a4b1bc0a67c8a521de336642c49e10a7ffa8d0af911aacc19e3900449161940f139220e099a150dcaf0ff96ffff6e726c1ac139969103cf6a828ac3adf0301506aa02787b4f570d5dde53a34acab8fec6fa94760abf16ee99954371ad65a6e899daab87b95811d069404991de9abe064ebbddf886e970f10d260c899dda940191a82d4c8bd36651363aff5493f4f59e700007dcadf37ebea7fcfd7600d16617ffea0d9ae659446d851d93c564e50e558f734c894d735fa273770703dab62844d9f01badf632f3d14a00f739c022c9be95f54e9cea46ec6da7cb11f4602e06962951c48204726b7f120ddbd0eb3566dc8d1e6f195a9196e96db33322d088b43aecffe9b4df182dd016aca0bd14f1c56cd1a18b89165c027029862b09ffd78e92ab614349c4fd67f49cb12cd33d0728930d0538bda57acef1365a73cc8fbac7d463b9e3c3bae0bb6224b080cdb8b5cd47d546d53111fdc22b7ff679bcfe27192920ee163b2be337d8cccc93b4de7d2d31934b9c0e97af291dcc1135b4a473bd37114eec3ba75c411887b57799d3188e7353f33a4d31735ebfc9fcfc044985148dd96da3876a5ab7ea7a404b411\n\n\n# RSAZ 512-bit.\n#\n# These are regression tests for code which historically reached the RSAZ-512\n# code. That has since been removed, but the test vectors remain. Note that the\n# lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4\nA = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same as above except A is negative.\nModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd\nA = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25\nA = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n\n# RSAZ 1024-bit.\n# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7\nA = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023", + "db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# Same as above except A is negative.\nModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10\nA = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Regression test for CVE-2017-3738.\nModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df\nE = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff\n\n# Test vectors for CVE-2019-1551. (We do not carry the assembly file with the\n# bug, but we use the test vectors anyway.)\n\n# Original test vectors by OSS-Fuzz.\nModExp = 9d675d188a07e9bd1b32638cc8cfd5002ef89bd1a9648f806567b87939140a67977dc8da17323b8e4c6bc53875cda8b656df8f54cc32e44fd9c21d122ea3c0d6\nA = dea9b3e0b44ae67b2ac9b7c2b18eeb4dab206b014981a46ac409f195eeb6896f132cf8497c87d1188008ee511054ebb426203355b7d515dce9501cb759ac1373\nE = b01ae745b101e9e45ec05dcff72e7f8fc04c79ffe324301fda0b4f7be81d85c4e875c73fc6c5cb40000000000000000000000000000000000\nM = ffffffff01ffffffffffffffffffffffffffe2000000000000000000000000000010fab8d960706cd4c21818115650cad61d4f10da325dffffffff00ffff00ff\n\nModExp = 651f811b62ee8770e3598c340864dd6b0be9bb6376b6f933ab216fd55538e6ad1000cb2b3c64f54d554e004b6eec8138e6ecff00452d443a42041b72e6cd9ead\nA = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e\nE = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e09003e3e3e3e3e3e3e3e3e3e3e3e3e3e010900230a01230a2100ffffff0000adf300a58700000000ffffff00\nM = ffffff0b00000000000000000000000000ffffffff0000ffffffff00000a0000000a00000000000000000000ffffffff000000000000ffffffffffff000000ff\n\n# Test vectors for rsaz_512_sqr bug, with rcx/rbx=1\n\n# between first and second iteration\nModExp = 1\nA = 624e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d973b6\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000006f\n\n# between second and third iteration\nModExp = 1\nA = 11024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000f\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between third and fourth iteration\nModExp = 1\nA = 4171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d9736080000000000000000000000000000039\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fourth and fifth iteration\nModExp = 1\nA = 6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000006\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fifth and sixth iteration\nModExp = 1\nA = 44e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000000000000000000003c\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between sixth and seventh iteration\nModExp = 1\nA = 1024e6a171024e6a14ce297f2873536f959d8c3390d973608000000000000000000000000000000000000000000000000000000000000000000000000000000e\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between seventh and eighth iteration\nModExp = 1\nA = 626eee5e3c8653be47ed15e84b97cc7f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000187\nE = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f8\nM = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f9\n\n# Test vectors for rsaz_512_srq bug, with rcx/rbx=2\n\n# between first and second iteration\nModExp = 1\nA = 3c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf7c\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between second and third iteration\nModExp = 1\nA = 485c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000003f\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between third and forth iteration\nModExp = 1\nA = 59a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000004e\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between forth and fifth iteration\nModExp = 1\nA = 2939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000000000000000000000000000000000000024\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fifth and sixth iteration\nModExp = 1\nA = 640939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000000000000000000000000000000000000057\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between sixth and seventh iteration\nModExp = 1\nA = 25c40939a85c4093995e8efdb195e8efd8caf477ed8caf4780000000000000000000000000000000000000000000000000000000000000000000000000000021\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between seventh and eighth iteration\nModExp = 1\nA = 7b4919849931b28a14fcace213f2b3884fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84b6e67b66ce4d9c\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004c\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004d\n", +}; +static const size_t kLen41 = 4891; + +static const char *kData41[] = { + "# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA = 03\nM = 01\n\nModInv = 64\nA = 54\nM = e3\n\nModInv = 13\nA = 2b\nM = 30\n\nModInv = 2f\nA = 30\nM = 37\n\nModInv = 4\nA = 13\nM = 4b\n\nModInv = 1c47\nA = cd4\nM = 6a21\n\nModInv = 2b97\nA = 8e7\nM = 49c0\n\nModInv = 29b9\nA = fcb\nM = 3092\n\nModInv = a83\nA = 14bf\nM = 41ae\n\nModInv = 18f15fe1\nA = 11b5d53e\nM = 322e92a1\n\nModInv = 32f9453b\nA = 8af6df6\nM = 33d45eb7\n\nModInv = d696369\nA = c5f89dd5\nM = fc09c17c\n\nModInv = 622839d8\nA = 60c2526\nM = 74200493\n\nModInv = fb5a8aee7bbc4ef\nA = 24ebd835a70be4e2\nM = 9c7256574e0c5e93\n\nModInv = 846bc225402419c\nA = 23026003ab1fbdb\nM = 1683cbe32779c59b\n\nModInv = 5ff84f63a78982f9\nA = 4a2420dc733e1a0f\nM = a73c6bfabefa09e6\n\nModInv = 133e74d28ef42b43\nA = 2e9511ae29cdd41\nM = 15234df99f19fcda\n\nModInv = 46ae1fabe9521e4b99b198fc8439609023aa69be2247c0d1e27c2a0ea332f9c5\nA = 6331fec5f01014046788c919ed50dc86ac7a80c085f1b6f645dd179c0f0dc9cd\nM = 8ef409de82318259a8655a39293b1e762fa2cc7e0aeb4c59713a1e1fff6af640\n\nModInv = 444ccea3a7b21677dd294d34de53cc8a5b51e69b37782310a00fc6bcc975709b\nA = 679280bd880994c08322143a4ea8a0825d0466fda1bb6b3eb86fc8e90747512b\nM = e4fecab84b365c63a0dab4244ce3f921a9c87ec64d69a2031939f55782e99a2e\n\nModInv = 1ac7d7a03ceec5f690f567c9d61bf3469c078285bcc5cf00ac944596e887ca17\nA = 1593ef32d9c784f5091bdff952f5c5f592a3aed6ba8ea865efa6d7df87be1805\nM = 1e276882f90c95e0c1976eb079f97af075445b1361c02018d6bd7191162e67b2\n\nModInv = 639108b90dfe946f498be21303058413bbb0e59d0bd6a6115788705abd0666d6\nA = 9258d6238e4923d120b2d1033573ffcac691526ad0842a3b174dccdbb79887bd\nM = ce62909c39371d463aaba3d4b72ea6da49cb9b529e39e1972ef3ccd9a66fe08f\n\nModInv = aebde7654cb17833a106231c4b9e2f519140e85faee1bfb4192830f03f385e773c0f4767e93e874ffdc3b7a6b7e6a710e5619901c739ee8760a26128e8c91ef8cf761d0e505d8b28ae078d17e6071c372893bb7b72538e518ebc57efa70b7615e406756c49729b7c6e74f84aed7a316b6fa748ff4b9f143129d29dad1bff98bb\nA = a29dacaf5487d354280fdd2745b9ace4cd50f2bde41d0ee529bf26a1913244f708085452ff32feab19a7418897990da46a0633f7c8375d583367319091bbbe069b0052c5e48a7daac9fb650db5af768cd2508ec3e2cda7456d4b9ce1c39459627a8b77e038b826cd7e326d0685b0cd0cb50f026f18300dae9f5fd42aa150ee8b\nM = d686f9b86697313251685e995c09b9f1e337ddfaa050bd2df15bf4ca1dc46c5565021314765299c434ea1a6ec42bf92a29a7d1ffff599f4e50b79a82243fb24813060580c770d4c1140aeb2ab2685007e948b6f1f62e8001a0545619477d498132c907774479f6d95899e6251e7136f79ab6d3b7c82e4aca421e7d22fe7db19c\n\nModInv = 1ec872f4f20439e203597ca4de9d1296743f95781b2fe85d5def808558bbadef02a46b8955f47c83e1625f8bb40228eab09cad2a35c9ad62ab77a30e3932872959c5898674162da244a0ec1f68c0ed89f4b0f3572bfdc658ad15bf1b1c6e1176b0784c9935bd3ff1f49bb43753eacee1d8ca1c0b652d39ec727da83984fe3a0f\nA = 2e527b0a1dc32460b2dd94ec446c692989f7b3c7451a5cbeebf69fc0ea9c4871fbe78682d5dc5b66689f7ed889b52161cd9830b589a93d21ab26dbede6c33959f5a0f0d107169e2daaac78bac8cf2d41a1eb1369cb6dc9e865e73bb2e51b886f4e896082db199175e3dde0c4ed826468f238a77bd894245d0918efc9ca84f945\nM = b13133a9ebe0645f987d170c077eea2aa44e85c9ab10386d02867419a590cb182d9826a882306c212dbe75225adde23f80f5b37ca75ed09df20fc277cc7fbbfac8d9ef37a50f6b68ea158f5447283618e64e1426406d26ea85232afb22bf546c75018c1c55cb84c374d58d9d44c0a13ba88ac2e387765cb4c3269e3a983250fa\n\nModInv = 30ffa1876313a69de1e4e6ee132ea1d3a3da32f3b56f5cfb11402b0ad517dce605cf8e91d69fa375dd887fa8507bd8a28b2d5ce745799126e86f416047709f93f07fbd88918a047f13100ea71b1d48f6fc6d12e5c917646df3041b302187af641eaedf4908abc36f12c204e1526a7d80e96e302fb0779c28d7da607243732f26\nA = 31157208bde6b85ebecaa63735947b3b36fa351b5c47e9e1c40c947339b78bf96066e5dbe21bb42629e6fcdb81f5f88db590bfdd5f4c0a6a0c3fc6377e5c1fd8235e46e291c688b6d6ecfb36604891c2a7c9cbcc58c26e44b43beecb9c5044b58bb58e35de3cf1128f3c116534fe4e421a33f83603c3df1ae36ec88092f67f2a\nM = 53408b23d6cb733e6c9bc3d1e2ea2286a5c83cc4e3e7470f8af3a1d9f28727f5b1f8ae348c1678f5d1105dc3edf2de64e65b9c99545c47e64b770b17c8b4ef5cf194b43a0538053e87a6b95ade1439cebf3d34c6aa72a11c1497f58f76011e16c5be087936d88aba7a740113120e939e27bd3ddcb6580c2841aa406566e33c35\n\nModInv = 87355002f305c81ba0dc97ca2234a2bc02528cefde38b94ac5bd95efc7bf4c140899107fff47f0df9e3c6aa70017ebc90610a750f112cd4f475b9c76b204a953444b4e7196ccf17e93fdaed160b7345ca9b397eddf9446e8ea8ee3676102ce70eaafbe9038a34639789e6f2f1e3f352638f2e8a8f5fc56aaea7ec705ee068dd5\nA = 42a25d0bc96f71750f5ac8a51a1605a41b506cca51c9a7ecf80cad713e56f70f1b4b6fa51cbb101f55fd74f318adefb3af04e0c8a7e281055d5a40dd40913c0e1211767c5be915972c73886106dc49325df6c2df49e9eea4536f0343a8e7d332c6159e4f5bdb20d89f90e67597c4a2a632c31b2ef2534080a9ac61f52303990d\nM = d3d3f95d50570351528a76ab1e806bae1968bd420899bdb3d87c823fac439a4354c31f6c888c939784f18fe10a95e6d203b1901caa18937ba6f8be033af10c35fc869cf3d16bef479f280f53b3499e645d0387554623207ca4989e5de00bfeaa5e9ab56474fc60dd4967b100e0832eaaf2fcb2ef82a181567057b880b3afef62\n", +}; +static const size_t kLen42 = 340537; + +static const char *kData42[] = { + "# ModMul tests.\n#\n# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M.\n\nModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277\nA = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b\nB = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65\nA = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763\nB = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92\nA = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942\nB = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910\nA = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01\nB = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c\nA = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc\nB = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc\nA = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f\nB = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8\nA = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494\nB = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53\nA = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f\nB = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3\nA = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3\nB = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c\nA = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b\nB = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f5303a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398\nA = -44", + "2c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9\nB = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b\nA = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf\nB = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c\nA = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d\nB = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c\nA = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60\nB = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504\nA = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78\nB = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024\nA = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa\nB = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8\nA = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c\nB = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea\nA = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1\nB = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5a99c8a6afaa97d8e7d84f4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c\nA = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7\nB = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8\nA = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3df11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048\nB = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce731", + "26508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8\nA = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d\nB = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0\nA = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c\nB = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450\nA = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c\nB = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8\nA = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c\nB = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c\nA = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3\nB = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4\nA = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928\nB = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207\nA = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223\nB = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676\nA = -1bf5ae15f24c7c14eb59605136a3f679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52\nB = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1d04b831b712d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba\nA = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf\nB = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd64bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073", + "ff1a506d7460c57d54e10dc2991c028606a\nA = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de\nB = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed\nA = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f\nB = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc\nA = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414\nB = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c\nA = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65\nB = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c\nA = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad\nB = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130\nA = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c\nB = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768\nA = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39\nB = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e595c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f\nA = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9\nB = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e\nA = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb150408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845\nB = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c", + "8e0359c99d4bdc901a4\n\nModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227\nA = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45\nB = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c\nA = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382\nB = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad\nA = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7\nB = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda\nA = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf\nB = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec\nA = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8\nB = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5\nA = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf\nB = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4\nA = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4\nB = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a\nA = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822\nB = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26dfdb\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0\nA = -63bc10b8fbcb391dea305fe61b404d3bebd035", + "514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b\nB = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d\nA = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb\nB = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702\nA = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91\nB = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c\nA = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643\nB = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18\nA = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33\nB = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a\nA = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b\nB = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6\nA = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6\nB = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121dae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b6243ffbb7a979bf9664cc7ec41e75f267d58a7127\nA = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625\nB = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db69f781e169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0\nA = -75f903ed9bb0b6db8e3be16e797258f6", + "c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164\nB = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5\nA = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb\nB = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa\nA = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296\nB = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2\nA = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f\nB = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe\nA = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a\nB = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08\nA = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec\nB = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886\nA = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f\nB = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b\nA = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3\nB = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed", + "81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820\nA = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e\nB = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba\nA = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed\nB = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1\nA = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579\nB = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c\nA = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4\nB = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754\nA = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00\nB = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a\nA = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995\nB = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230\nA = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e\nB = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35\nA = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac", + "74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891\nB = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955\nA = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9\nB = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8\nA = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a\nB = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39\nA = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983\nB = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574\nA = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0\nB = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c\nA = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc\nB = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76c31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c\nA = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2\nB = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df502a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5b704b3181e5d0494937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04\nA = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023\nB = 160120a35ae3edac3", + "edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93\nA = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15\nB = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c\nA = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e\nB = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9\nA = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b\nB = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014\nA = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410\nB = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90\nA = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8\nB = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409\nA = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9\nB = 44c336d7739118340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8\nA = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d", + "65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924\nB = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea\nA = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19\nB = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea\nA = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996\nB = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d\nA = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9\nB = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2\nA = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3\nB = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c\nA = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e\nB = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8cddb5914e7657573804e63dc7b216b1a9aa175c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168\nA = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c\nB = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f19a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a", + "4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54\nA = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4\nB = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298\nA = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa\nB = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227\nA = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1\nB = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179\nA = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655\nB = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c\nA = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15\nB = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897\nA = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1\nB = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4\nA = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2\nB = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a2", + "0f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648\nA = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4\nB = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a\nA = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6\nB = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c\nA = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6\nB = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c\nA = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905\nB = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d\nA = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5\nB = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf\nA = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66\nB = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21\nA = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393\nB = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a\nA = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152\nB = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff90", + "4db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d\nA = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e\nB = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d\nA = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c\nB = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4\nA = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232\nB = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761\nA = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a\nB = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327\nA = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82\nB = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010\nA = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61\nB = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89\nA = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1\nB = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14\nA = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f\nB = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe\nA = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9\nB = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5\nA = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df\nB = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b8", + "5d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f\nA = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760\nB = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a\nA = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207\nB = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd\nA = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6\nB = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde\nA = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454\nB = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8\nA = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615\nB = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a\nA = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013\nB = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9\nA = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d\nB = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f\nA = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226\nB = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24\nA = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d3486949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a\nB = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0\nA = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e\nB = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16", + "\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23\nA = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928\nB = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9\nA = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3\nB = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f\nA = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0\nB = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65\nA = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807\nB = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308\nA = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983\nB = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa\nA = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7\nB = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f\nA = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72\nB = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173\nA = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df\nB = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848\nA = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40\nB = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7", + "ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146\nA = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa\nB = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02\nA = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c\nB = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c\nA = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7\nB = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343\nA = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd\nB = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35\nA = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d\nB = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a\nA = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50\nB = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff\nA = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a\nB = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7\nA = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967\nB = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fe", + "d1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453\nA = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8\nB = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c\nA = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745\nB = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149\nA = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261\nB = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656\nA = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228\nB = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e\nA = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d\nB = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e\nA = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5\nB = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb\nA = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99\nB = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a\nA = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8\nB = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc\nA = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f", + "1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984\nB = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc\nA = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275\nB = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472\nA = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6\nB = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d\nA = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1\nB = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd\nA = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1\nB = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f\nA = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e\nB = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad\nA = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334\nB = 1311b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d\nA = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e\nB = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4da9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f761", + "9eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca\nA = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431\nB = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f\nA = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864\nB = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d\nA = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5\nB = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233\nA = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244\nB = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e\nA = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65\nB = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135\nA = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9\nB = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c\nA = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1\nB = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb\nA = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f\nB = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102", + "c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511\nA = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5\nB = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79\nA = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15\nB = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e\nA = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db\nB = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b\nA = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840\nB = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d\nA = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c\nB = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec\nA = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b0702b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf\nB = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc\nA = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e413e23285066eab8e126c320bb6130a91d67ef26d4dabd\nB = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854", + "a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158\nA = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d\nB = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745\nA = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7\nB = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950\nA = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d\nB = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a\nA = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b\nB = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82\nA = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5\nB = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3\nA = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7\nB = 78ec7dbfa2b28e268619ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861\nA = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3\nB = -2023c544b6cdd8d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nMod", + "Mul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c\nA = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be\nB = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce\nA = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a\nB = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68\nA = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783\nB = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866\nA = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91\nB = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069\nA = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933\nB = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901\nA = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8\nB = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b\nA = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec\nB = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d3", + "8f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3\nA = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e\nB = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf\nA = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830\nB = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0\nA = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7\nB = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d\nA = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437\nB = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493\nA = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6\nB = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280\nA = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628\nB = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8\nA = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d", + "80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82\nB = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297\nA = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6\nB = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d\nA = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8\nB = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2\nA = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf\nB = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17\nA = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c\nB = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8\nA = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8\nB = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b\nA = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751ceab01cf9e49015d42371fac30d48ef5853b6894ca83\nB = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625f", + "d9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02\nA = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb\nB = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888\nA = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78\nB = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1\nA = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f\nB = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e\nA = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a\nB = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a\nA = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493\nB = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0\nA = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c\nB = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096\nA = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e\nB = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77\nA = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31\nB = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f\nA = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83\nB = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0\nA = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357\nB = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb4", + "75ee818199a390b6\nA = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae\nB = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca\nA = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6\nB = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe\nA = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32\nB = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0\nA = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92\nB = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc\nA = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756\nB = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1\nA = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf\nB = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6\nA = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a\nB = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f\nA = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87\nB = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928\nA = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58\nB = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304\nA = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5\nB = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a1b1b2d33cb610f1b398e0", + "3f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a\nA = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6\nB = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3\nA = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7\nB = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d\nA = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35\nB = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882\nA = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce\nB = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2\nA = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a\nB = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a\nA = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13\nB = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1\nA = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db\nB = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696\nA = -19d3e6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7\nB = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48\nA = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214\nB = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05e", + "d24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2\nA = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da\nB = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e\nA = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda\nB = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813\nA = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107\nB = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60\nA = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416\nB = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77\nA = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95\nB = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150\nA = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8\nB = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da\nA = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae\nB = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a9621b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de\nA = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda\nB = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210\nA = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20\nB = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784", + "c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80\nA = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf\nB = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab\nA = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d\nB = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80\nA = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4\nB = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba\nA = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b\nB = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94\nA = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b\nB = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a\nA = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b\nB = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8\nA = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa\nB = 1fc4dc77f4a18d4406a4ba536e500aff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819\nA = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197\nB = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095c6a509d0fa15dcf45de8d0e901\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200\nA = -464cb16fdd395e32f", + "dc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc\nB = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08\nA = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670\nB = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208\nA = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019\nB = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6\nA = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d\nB = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067\nA = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453\nB = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5\nA = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93\nB = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c\nA = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7\nB = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca\nA = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589\nB = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b2b63f84fb0023c81d031773f3652cd6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8\nA = -78a99d206b4", + "f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e\nB = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31\nA = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f\nB = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e\nA = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7\nB = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28\nA = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756\nB = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6\nA = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29\nB = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f\nA = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf\nB = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec\nA = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905\nB = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5\nA = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1\nB = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee6", + "5c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8\nA = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990\nB = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec\nA = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1\nB = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a\nA = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d\nB = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5\nA = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3\nB = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264\nA = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d\nB = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f\nA = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b\nB = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af\nA = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b\nB = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590\nA = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a", + "684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8\nB = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef\nA = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f\nB = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28\nA = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c\nB = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4\nA = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814\nB = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0\nA = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4\nB = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08\nA = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73\nB = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58\nA = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50\nB = -26ea5079ba7ed137a14d00d413d6f818e911cc183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a\nA = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae\nB ", + "= 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8\nA = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9\nB = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1\nA = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131\nB = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e\nA = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145\nB = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380\nA = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214\nB = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac\nA = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205\nB = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4\nA = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2de4\nB = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4\nA = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda7456", + "58bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373\nB = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846\nA = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f\nB = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04\nA = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a\nB = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074\nA = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc\nB = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590\nA = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4\nB = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb\nA = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353\nB = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e6526be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11\nA = 1112d291463b28ef45e879412e6607a3e20d50dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1\nB = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c44", + "87d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618\nA = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380\nB = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e\nA = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa\nB = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4\nA = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d\nB = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1\nA = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375\nB = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229\nA = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f\nB = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282\nA = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a812262309094ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e\nB = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc\nA = 60463fae1e9354559160d55a453c12d75775a53d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714\nB = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bc", + "fb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420\nA = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8\nB = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7\nA = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47\nB = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce\nA = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772\nB = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9ea62ef634\nA = 55cc58c9d8\nB = 6b49179821\nM = f753311ac9\n\nModMul = e9ab3a2aa60edd30108\nA = 5134a36c2bad180dd5bf\nB = 2ba6485656d041690666\nM = 9b9cc4409e86c8b0fbbf\n\nModMul = 621f9b797e866028b7bd1ff828bf29\nA = a202338dffe171c99434d84f3\nB = fb71eee7045b3e3ab5dd809dd\nM = b3e6e8d53b7249df670e3c59c55d33\n\nModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672\nA = c669426a92d3cb5b316e2b5b9\nB = ccaea3874008dcc92450d8b2f\nM = b04dd2bb325baed1940cd000e8cb2d786009ccd5\n\nModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0\nA = c3255cb24a813e27c3dc410f0\nB = b144f39e7c2d33605ba7bee16\nM = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077\n\nModMul = 6124d7d171\nA = 235b938139\nB = 3a56a22a28\nM = 83eb4af4e5\n\nModMul = 9c006f56095d442ba98c\nA = 207e14237c42e3764e5e\nB = 8a495a26872432fa8e33\nM = d0cf2b8ae5c67d6736b9\n\nModMul = 97387cfaef652932a230c82de59cac\nA = 82ae0fc5e943af5bb8c4adebb\nB = db1279be12d59ba3a9c036a61\nM = aa36dc1d13390169cd54d711eb511b\n\nModMul = 32ee73c98da657464c6fed4274df20b099689e00\nA = 9baf08248ee24bcb17714e420\nB = a7f0428147bfe098666180749\nM = ce0bc198331c9ed1d21f0d498326e8185d3d602d\n\nModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34\nA = b36249e259b303e453757721c\nB = f0c1db50670d92abd93bdc84b\nM = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9\n\nModMul = 2663b741ff\nA = 58c8e7f7f6\nB = c84681fc87\nM = e0a50dcb45\n\nModMul = 21af3c0b42328f41b81e\nA = 1f79f5b5bf78c9700d\nB = 5bd1734ba0f0e59c2a25\nM = 9ff3fdfb5c089244f327\n\nModMul = cbc280b5106c2c36cb31ad7e7c986c\nA = cadf6482b769e83ce7f7277dd\nB = f9862a06da1a9c89547b76c61\nM = cc36144c88139ce921d2fd1740bc4b\n\nModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b\nA = 9c51a5bacb5d9f055a9ac2962\nB = bfed5625b21b4e82d1f105a0b\nM = a47977acad7c5deeb683ccd265cb30cb193f22a9\n\nModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478\nA = 997c4a7b537d9500d73a205a4\nB = c679ce666af284a459ae5a26e\nM = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9\n\nModMul = 1a90c92fdb\nA = 94fa7bb475\nB = 564b0a3339\nM = a1501bdc75\n\nModMul = 5e7ae5470686bad7996a\nA = c725797912c6c5f30d94\nB = 3a7f4c99ee3f5fa9582c\nM = cc50c8b7408f09a74973\n\nModMul = 72a15b13bcd1b63747342a6be8f0f2\nA = c33357af48a2df569e3c11ce6\nB = a4b4c5c14d7796adab54b6cae\nM = e22a0fdca62a37f4c8a61c96a429b9\n\nModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6\nA = ce8d3adab8cbf15c332c0b289\nB = 9333f94eeb7d7a86b82becc51\nM = a532a76bd5cff409b580d54d12ef75ad8179b381\n\nModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14\nA = 9a2b56a54bd0727ab4be57ff2\nB = edf1781b4296567990773005a\nM = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1\n\nModMul = 917bcdb402\nA = 55c7dbd314\nB = 997b29ef79\nM = af5b4cbd0f\n\nModMul = 660c4bb2b771f523a4fd\nA = 43fe52461d5139620a11\nB = 1f8ec4b67de1db54ddda\nM = d0458e215b7e6903d96f\n\nModMul = 7aeff02c143e4426fcbcf32bd1277b\nA = a2671586369a990dde7829f36\nB = c7ff67937c900daccc0ab1d8c\nM = 8ad9c1d4d3cce681d1ae27c27982df\n\nModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07\nA = aea36cf51dd2ce06c66b7a407\nB = 80c9fe5bb0afd2bf8b3644f96\nM = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9\n\nModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0\nA = f67636b03821c8f13f21217a5\nB = 8473a29f4ae33f36a0d2c6dc0\nM = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5\n\nModMul = 17fe4644a2\nA = 912611576f\nB = 7a10d36b80\nM = c5fa605133\n\nModMul = 8159b23d4fd697b4fd35\nA = be2d646e76494439e60\nB = 60fa770d05ebc69772b2\nM = a6e7c940cd749925a85b\n\nModMul = 7c412dad5c9fff91357bf181caf2bf\nA = 80f476ed5acae75b34ed54c52\nB = fb818e2bdab3b5f4bd84db3d0\nM = d0339f7ee41337d8462d1a9c207d1d\n\nModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b\nA = ee9c92de52210e61adaa6eb4a\nB = 8ab55a85b1abab62d33e75fe3\nM = cd3faa6de4cb62fece4c3f94492d457834a6a041\n\nModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28\nA = bd162c90bed25e84dd5b6b77c\nB = d887ee03020c5df356f091db6\nM = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f\n\nModMul = 958951bd0f\nA = 12bd0d3375\nB = 668bb65b4e\nM = 9c617dfaad\n\nModMul = 8a109ebc9cbf86613e43\nA = a3e7019f1bbc35689a77\nB = 3189ecd3", + "fd4ffd0229ef\nM = ddadc50600dff2abc1af\n\nModMul = 2b4d9f85a398c852b3a0cc82524619\nA = c244fd157267f707319ba6c6d\nB = 8a07018a748992429bbdbf326\nM = bf3813fb54f749ea5627f59ce30e07\n\nModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f\nA = c9909dcfd3a59a3cfa538b267\nB = 8bbf89cd5a4e24adc2d8c646b\nM = c8f02682b9d480ea98faaca53b747ced33ed0419\n\nModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a\nA = 8019266c548982a520ab48eff\nB = d33c3e3b13576dcdb3ffaa796\nM = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1\n\nModMul = 3eaa4c99fd\nA = 6fc42faa85\nB = dd0b4e318e\nM = fd7f22301b\n\nModMul = 56b6b811ced3433755cb\nA = 145573d17cb0c996c69\nB = 9d3297d5ccc184896822\nM = dcfb3b383506239e83e1\n\nModMul = 34315b6bc6d3690c28060485ae331f\nA = b963a26973894cfb42fcb2d22\nB = e8523304bbcdff1a0ed4141bb\nM = d7a379aeac7d8cf94f19e7924d35d1\n\nModMul = 2ec9466e8b3357496f07e37ba24d36a237883846\nA = a75f3904e564997695b6707eb\nB = f9f47bd779834dc1f5fba0654\nM = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed\n\nModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044\nA = a38eceb9c551f0e69a544072c\nB = d5f8e7c2d534b2b8985bfd213\nM = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7\n\nModMul = 172f2e2e22\nA = 1584ff1055\nB = 2e0aee014d\nM = b904cb0bc9\n\nModMul = 122c10d3200270b9eaa1\nA = 86fd189e62a6dc1e4ba0\nB = 5235635f7b0336f5f235\nM = c93da97d0e95fb63dc4d\n\nModMul = 3e461e10ac4eb749512097fbf76616\nA = cf4ce10cbca07164f3812f89c\nB = b7e4639c233fbb0f923fb5104\nM = 949647857e1406871593fad5c30101\n\nModMul = 88117b59d9fed79dd6aaf083ee938215a995a221\nA = 94c888795567d434123d441a7\nB = c60ca79e61a352e34e0f78bee\nM = d2553a7c5dccd639a3927697a2e1af03845f2f25\n\nModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c\nA = c170eaddca5295d6ec6272dc2\nB = f94a5685ced7661df2efbd34e\nM = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd\n\nModMul = 1110cdbe5b\nA = 5db02b38f3\nB = 3369537903\nM = a8863f7979\n\nModMul = 90fcc5f3a346d3d4ea4c\nA = b93373680ea0feeb31d8\nB = 37f9dfaf0e180be64bd5\nM = d595cc29237d1c19e2db\n\nModMul = 8623a9997e514cf3c1d06c33c14053\nA = b396f5ede6212f1fdfc7e7b77\nB = 81a1ddc18306f2d2e84030148\nM = a6be32a91b34857842255ef8b1aafd\n\nModMul = 63f8f0254df06356f5cab8941b77619ad58025ed\nA = 806b2627b08d987438f920bae\nB = 83297039f4aa8efc1a185fea3\nM = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5\n\nModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438\nA = 930b04224bc097ac1d8bae8be\nB = b79496a80e45212c4663e5b64\nM = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1\n\nModMul = cd93b5b8b1\nA = 47a51b2d5a\nB = 86d6ba5155\nM = efb0ad3643\n\nModMul = 2037821ea789118bde0a\nA = a92215dcae19be637ff\nB = 93b9a3664a406737958f\nM = 9df360b69ed26f610253\n\nModMul = 3bf11785d28ceb668dc55b870faf7b\nA = bc8758854dc48e057cb6210de\nB = f03ca689620a77ecd8a6f0de3\nM = f3ff0747d6e5f34a0ba4200f579259\n\nModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf\nA = 993cd09f3e46423a8ba2053df\nB = feabee384158032dd013dc08d\nM = cd0b21388cb2033b1e792ec4078334df70b6c8f9\n\nModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650\nA = 90e5d18b017118177ffb080da\nB = f8e7e09032574f6c66e623ec8\nM = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11\n\nModMul = 8fcd412054\nA = 2e7f9b1a\nB = 6283de2c9a\nM = 9bff560ae7\n\nModMul = 57d0d3b79f1e2f3632fc\nA = 2f8cc403de5af54cfa39\nB = 3b798c3ead52878dfb2f\nM = 805e6cbde400d4b4bc9b\n\nModMul = 23331614e88633af879201f568c359\nA = f21f19da4b20980979a645dac\nB = ea752050b79883dcd69222536\nM = aed3faf4c88f7c4afe257c5ed90599\n\nModMul = 56dcf9ae1c787e773774df3c8762babb4675a212\nA = 9accf901fa599da05fa6ab5ff\nB = f7f6b9b1d7bae06237532e39f\nM = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5\n\nModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0\nA = 8e57680f213d088ff1a1e7db3\nB = afebecc9943b0093f87022940\nM = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb\n\nModMul = 143ae78a29\nA = 334abb952a\nB = 74203e7a50\nM = c9535a9505\n\nModMul = 897a2b57e69f5a1469ea\nA = 1ec8ca0ea4fed52bdbbf\nB = 3a6273cab05e478a57b8\nM = dcb33163a8ea42c1ae6d\n\nModMul = 4a2c10e90e2d37111db79a44d3e31b\nA = a90e7bbd63fc4af6de83029ee\nB = cf09c3dd50b41afc7045e057b\nM = 8ab85d47e4270116a64f97dc4f0f15\n\nModMul = 70f94276c9d85fd3f71edfaad6051456f754da85\nA = fa3e9ff6e1aa1fb78e51711cb\nB = b115ed197c50b7ec4040ca255\nM = ad63f69ef1346e7549ba71c13b24b279f53bc9bd\n\nModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac\nA = fc41a9ce06e882942f751be7a\nB = 881c05a51d1ba8134d126a48e\nM = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f\n\nModMul = 4e0051898a\nA = 2a06523f70\nB = 651b5044f0\nM = 9da4eb09b5\n\nModMul = cc8274c88d6affc3742f\nA = 9ccf0133f9628532f4f6\nB = c1d80907057be7a67b01\nM = d6e76e362da831f32685\n\nModMul = 568f15bed5c4405be9dd04673a9c46\nA = dd6029c3196feb6da7f0f4a48\nB = a5f6745f2cb64913d1d3236d8\nM = f62f02c9b9ca8993e3be9a02b444bf\n\nModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f\nA = 963c51a9415b03e85ccb09f25\nB = b1cffe333afe44311cb968ffe\nM = ab2128698d498e8d75455033cfbbf4487535773f\n\nModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf\nA = c3b33f391e78bee97ceddf313\nB = a9136f3af450fdeb245eff425\nM = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35\n\nModMul = 8735bd486d\nA = 563e15c52a\nB = 31293264e1\nM = 92f4b193df\n\nModMul = a541f69ca163b288dd0e\nA = a608b48c1dcaa18424b2\nB = 891b0b296e911068b00c\nM = d4140921f4b2c84f1eb1\n\nModMul = adc1b7cf65967b013d046866b4ed9d\nA = e97941448f65060cf63ecd486\nB = ca68936f76cb87a8fbdd37311\nM = ebbca2482fb82eeca2866057cf1179\n\nModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632\nA = c11f83f01bb964ffac93a2e30\nB = e05ee40eea39f4538d735193d\nM = b5e8b511738979dc740a6a1f7291cf4561787be7\n\nModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a\nA = acff8da571e1c96810bf95707\nB = cdd23e5504cc26d0c34a62b06\nM = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7\n\nModMul = 193f453197\nA = 8cb3078675\nB = a8fb003a87\nM = b60ff22f4b\n\nModMul = 849c26c8cf5cae426a80\nA = 5d1e3d2b4d038a0a34be\nB = 34f70325565bf0523314\nM = cbc189f9a732cad8f425\n\nModMul = 9a4e64ff530c53a4c6c5b6b5021920\nA = f53b81723cf74f520a61e614e\nB = 9d8ac2e6b839143fdd079a2ff\nM = a115375435151798f3644bede9d863\n\nModMul = aac303a4623e80158af1cb3331965cc8e3184edd\nA = cce0a88606ff962fdc37e72c9\nB = 9840a500a2051625c517104db\nM = b99dafdbd91ec3c05791031df5e193c03d6a441d\n\nModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf\nA = e6f48c027284856aaf3b96425\nB = b4c326f72a6a22fd4b93ba5b3\nM = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab\n\nModMul = 8b0929adbf\nA = 61fdf77ac0\nB = 8892f05400\nM = f12b3766eb\n\nModMul = 91b57f353307b173679d\nA = 33f8e73752072b4b5cfa\nB = b4c730f79f4f2c07945d\nM = d41be1d8d2e5753e3ae9\n\nModMul = af04c564adfeb120bc4770bc8c650c\nA = af151333b3d4cd1d29fd801db\nB = 9ccaac44ff91be11b30bdcdd0\nM = e0bd6e70d5f5ce08fbbfd48d43101f\n\nModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd\nA = a2fd08df2d4eab0cd6d29e213\nB = 92c9d26ae7c215b52199ee28b\nM = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3\n\nModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd\nA = 855f941d085305725da617f5d\nB = 8f09b7d2c36e0340523da5421\nM = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b\n\nModMul = 2d278e089\nA = 59d20a1716\nB = 8e2a58bc75\nM = b3d61ef699\n\nModMul = 2f937ce359d0f6cedd1\nA = 1019d11d26040ffd5b1d\nB = 7cdb6252087423d43e08\nM = e8f537323004447e669f\n\nModMul = 6567332e25af83089f7458786ab0ca\nA = bf9565e9f8a098894447b58fb\nB = fc867626f268c24cc0ab7bf8b\nM = 930f39183353363dcd822933a438ef\n\nModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9\nA = d0a42ce512629f0ffd233a9aa\nB = 97f6d3c4c655c7353a62d6ac4\nM = eac2ea84851f880214b8f40f881a2e56a6ba6f2d\n\nModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58\nA = c237eb242c40960861c938c08\nB = ab2f481f0d768eebd90d2574b\nM = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f\n\nModMul = c952f9aef\nA = 81973bbcb3\nB = 28ddee3bf7\nM = c4a40993c9\n\nModMul = 241dd53d93f7bdbbb2ee\nA = 2136eda4495c45c9f96c\nB = e74c4baa8ca3f6b7cd5b\nM = fff4594e7a5f0a1d3e15\n\nModMul = 5f861ed8b0aa835761613e6c869cfd\nA = bfc5c1572086079f5f5d18d1b\nB = 95902e14923c8010b7e905178\nM = a819c6c109d623f9b845aa23712c9b\n\nModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598\nA = fbe65d3852224a812c432672a\nB = d57a3f38da966d2471d70a048\nM = b9e6a626d3ad026d14248fc90c882bedd64a1f13\n\nModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed\nA = fd91701ed2151f8e994bf4ee1\nB = 88b66e735b76972bccd9db182\nM = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55\n\nModMul = cb74", + "3c97a1\nA = 9c69ca9b60\nB = 7488f48f5\nM = d67040ed0d\n\nModMul = 931b2bee1bc30725a31\nA = 650f567b544ce02303d4\nB = 5858da30dd1fae88a675\nM = 91ce30234bb29fb9e833\n\nModMul = 5b4f262cec958a20390b5e568ccdaf\nA = f7e240e8a077e8e87506db2f1\nB = f8653fe64e3bd414782f51634\nM = fdb8225eefc1620648737d31dfe1f7\n\nModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1\nA = eda8e9a9ea3cdae17bd50b1b4\nB = 992e8ef4a45593e4ceff67876\nM = 95e2f120cfcefbada1058af6c8853cbebedd5763\n\nModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466\nA = ca6c51ba2f410d09bf71d60fe\nB = 8bdfa8fe5ef3b2ad02bc63c4d\nM = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb\n\nModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d\nA = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee\nB = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca\nM = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb\n\nModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634\nA = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90\nB = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc\nM = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59\n\nModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76\nA = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651\nB = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035\nM = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb\n\nModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540\nA = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf\nB = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7\nM = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7\n\nModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db\nA = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c\nB = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d\nM = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401\n\nModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4\nA = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04\nB = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8\nM = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1\n\nModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658\nA = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0\nB = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590\nM = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227\n\nModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764\nA = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d\nB = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf\nM = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab\n\nModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2\nA = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23\nB = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321\nM = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93\n\nModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764\nA = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20\nB = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88\nM = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735\n\nModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233\nA = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f\nB = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538\nM = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793\n\nModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4\nA = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f\nB = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45\nM = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47\n\nModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9\nA = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2\nB = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94\nM = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3\n\nModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9\nA = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f\nB = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26\nM = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479\n\nModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d\nA = 6500f3cf686eec4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2\nB = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a\nM = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1\n\nModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113\nA = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4\nB = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb868dcf4e458b36f506ed7fe0ce5\nM = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817\n\nModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855\nA = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c\nB = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323\nM = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7\n\nModMul = 4452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6\nA = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d\nB = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f\nM = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b\n\nModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2\nA = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d", + "4b2\nB = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3\nM = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955\n\nModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df\nA = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876\nB = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300\nM = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9\n\nModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad\nA = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c\nB = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811\nM = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937\n\nModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6\nA = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110\nB = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b\nM = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025\n\nModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d\nA = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b\nB = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a\nM = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335\n\nModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66\nA = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9\nB = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173\nM = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1\n\nModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995\nA = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd\nB = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10\nM = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9\n\nModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c\nA = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nB = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nM = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09\n\nModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688\nA = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620\nB = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f\nM = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9\n\nModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15\nA = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee\nB = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec\nM = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9\n\nModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244\nA = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941\nB = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd\nM = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897\n\nModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6\nA = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6\nB = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80\nM = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923\n\nModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385\nA = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53\nB = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59\nM = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5\n\nModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f\nA = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee\nB = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7\nM = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed\n\n# Regression tests for CVE-2016-7055.\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nB = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nB = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\n\n# ModSquare tests.\n#\n# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.\n\n# Regression test for CVE-2017-3732.\nModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff\n\n# Regression test for CVE-2017-3736.\nModSquare = fe06fe0b06160c09\nA = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc\n# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff\nM = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff\n", +}; +static const size_t kLen43 = 12578; + +static const char *kData43[] = { + "# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\nA = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aa", + "bc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n", +}; +static const size_t kLen44 = 91889; + +static const char *kData44[] = { + "# Square tests.\n#\n# These test vectors satisfy A^2 = Square.\n\n# Regression test for a BN_sqr overflow bug.\nSquare = 4000000000000000800000000000000240000000000000000000000000000001fffffffffffffff8000000000000000400000000000000000000000000000000\nA = 80000000000000008000000000000001fffffffffffffffe0000000000000000\n\n# Regression test for a BN_sqr overflow bug.\nSquare = 40000000000000000000000080000001fffffffe000000004000000200000001fffffff800000004000000000000000000000000000000000000000000000000\nA = 80000000000000000000000080000001fffffffe000000000000000000000000\n\nSquare = c2fa18e1d110a4639781\nA = -df6a253c3f\n\nSquare = 4805f01d379f4ce8dc86ed269\nA = 21f253ddb5a6d\n\nSquare = 57def107babc1c2bffeff858947e69\nA = -95fbaee5a09c86d\n\nSquare = f3b01f7941961b3f5cc3361e3ac82423690\nA = -3e71292dd4ad3ed3b4\n\nSquare = 5e2d9c36d498ad1e8b6113f442ac513eaca74601\nA = 9b45cf6c7a43d910dcff\n\nSquare = 7b7c2eb3fe55615e422b41c6f725341527626398cdee4\nA = 2c7314e72a2ffeef170de2a\n\nSquare = af57c0ed328886642ed5d631b375fc89c03a99f1b427c6bbd1\nA = d3de077f8286a04daa9c497c9\n\nSquare = 4d9eac3058e6cbc0d12e639ced961c02ec1870afed62fdd44c67ce4\nA = -233da7e87ea4421ee8fe7e00c856\n\nSquare = 83c292d277fae28cfede74e8e80eba11dc132e16f78cdf64595c12c7dee4\nA = -b7a8aa7452678abd45d2ae6c349e2a\n\nSquare = c80e07dd01f9d19a5cf7f3c328ccf4de70fdd113de69382701294dd29674b9a90\nA = 389387eead58fef2c76b5cf920f35c5cc\n\nSquare = b9f69ca47ac855830fd7ed39c81822c520880c51c3ea60d3ccc106db37fc2b04c47831\nA = -da307c28ea67ca8d3117364ba93f0731bf9\n\nSquare = 81bbe3a13a22a73778233294ba0c132d9dddec111f768300f177468c204f8eab69b98e62d99\nA = -2d8f715bb32d410b4f475c4d000d56fec7cfc5\n\nSquare = f815ce34e9bc2e31e36e75cf49b2d15306d438a2a713b2a85b3ea156ba60c867c28cc65aa58fdf11\nA = fc02f2e1a26cd69f6a0e54cca4bbced739b43597\n\nSquare = 5f968707f58ea15c492ec9677be09c309d91164aafa754ab16ca47a411b5b2249858fb6f96135992e8a04\nA = 271b8eae3e96cc4900d4413d6c00b73736a5d89ed7e\n\nSquare = 4aa616aabcdc7ad48dcfd40d71e00a3789bbf549ff39b3e2ebb52017cb56014941961a5a6d52d7a9980fc99b49\nA = 8a3d3f15e6d7d2130aebd8cb99767defbe4c7704e3c1d\n\nSquare = 845e46db8c40f3f6f6f4928b5748618f021f9064c6522bcf2df004f8d2105e90cd354785c15a6cc32fcc77da2ea3001\nA = -2e0543ac8b8255ce30253cf2047a0ff353dea55a58551801\n\nSquare = 5dc5706dde9b326feb79941f08bd296ec3b6fb67270516b70fad9921438b9175f395310fb756b60d72d8e73e84ee8673cc40\nA = -9aefd7dfa709dec9e721f5c22867229435b2d6366462d0e438\n\nSquare = 63dc6565adba27974a66bdcc626596e16cf399541d679f754d9063ceeb320649bec09a940309dd1eae5fbba0b558939afae9689c9\nA = 27f8e071f70b0053d70eca9c6d1e28303b8da2d3c58083c2cc45d\n\nSquare = cf2176449bb8b215fc37288b904ca27d5d410780fd054d2a190a94b405f6aa41970b41ba3cc43eaabb97c2248e1e21457949070ec0f6a4\nA = -e645c7edc27512d4b3170d3c5430d0712a25c13afcc09c9b30bb11a\n\nSquare = 43194e5f12e828db6735824c194985108269ddec12c49a14658be3c2b7d298c2846da1aa3ecb7064e73c317af595601de59035faab6dc0fd911\nA = -20c3fb73a03217893fd4a9db6e53a3d83a8414d900213d0460dc91bf69\n\nSquare = fcee79e598f061157ca9416491f2eb069bb95a4d78a1d0538dab5c8008653db71b90ce3139e693ba284846be7b75d6b7aa80228420fe75599c12f090\nA = fe760dd61798c8f78e52b328fa27cfbe41b898de6e6bb4f4a684f038b5f4\n\nSquare = 4f0db9f9e6eff9fe7fc938f6d6f5e4fb017ffea0cea0f7c57f4fc1e5b2bdc00a1cb9c1e6c865e53309b6b73c4339b0bd485860ca9edde3019804902da6b61\nA = 23909968dd5d139994fe9baa0a7bbfa009b013df3859ff294c5872366eb7ecf\n\nSquare = 4441ff36d785d18208481470a5b8ba8cd65a45436c39190dde0b8a2b7d00bf67b185d98ab5c4a7853423778d6333abf6b115dc9567a9f9c71916d3f9db3af82c41\nA = 84307277f79cfdf33d83d7093f1fd8aeb94499a7075ca32733b68fcf88e819421\n\nSquare = 50ee0dba369b0fb61d75706652487ca08043eee712ebb51399122353f77f13745ce2ef0d8f0ea7b3fd94e928b0b2b42c2c9141b5697b13b6d1f3d66c6a9186625b87e40\nA = -23fc02d45c820c3a4250124cc457fa3886beabb41d3c1e26f711309604eb253c6da8\n\nSquare = da11876b316d4891a2d650692ca776f77afd32a1db08f591c9579fd1053a4a46cf78b4e4cf417eb99eb067ff701dbe3483dff22e7878d2ef2b234244cf7a29d93f62d6d6b611\nA = -ec463653389de3689fe1881679b83ca65134a1498a3543168dd4833a51b23edd3fb617\n\nSquare = b342b4aff7e5bad38f7f532f0f32a3672f7ea6521d23652fa09ef7aeffcffe52f056ab1b54a0f3a2147f43330fd199d1f290988c866f61360dc4928c84b3dcde8f395120008472100\nA = 358e27805e2a56195fab2ccbe3f931a4bd14023ee56c8a191697926f387c40decc578cef0\n\nSquare = bf4045fd680caa514e9c410fb4404e5e3a381abee023d5b509d6dc0b97386421f55090af8bab5ac08e9b2eb8a36a64c55960be9179d564c5429f4ec595d03d12111defafb7359b418902b1\nA = -dd450a0fa0914f0d65a1b555baaaf9380eaf8d58b272bf9d95435bad53b01337ac8de562cc7\n\nSquare = 86abcdf183ca059257c2f6bb91efc9853f4ab42801d3cde88df72d4c904be184e93d6bd1af6fc21a6836c93c4e0a1f728b3722d568572f7ade418274ef2e6ac3463c5cc50990f1017e01cfb91a9\nA = -2e6b4d9eeede7a72b8d0fcf6429c7e30cf291352e1bb43e92c14236716aadc02c02f75c7e6aa8d\n\nSquare = d5f37112733b097cab2bb11daa3d9481255060abd7bce42b752a7641a98e140922c375fcb68bf13d4326b374eabe3b01de0f8f6324b7b3e4142051c02d2f18ae2e748cf3c4bcc3fe157bc94227631d21\nA = ea087236372fbb01b80e57b1ae4edeeaa776355457e18165a5dc60ef4b6ddc0b127ef494dc44ae11\n\nSquare = 9e4db7885fa5f928ef236f99df3e7c8d17a5a21983ff882032817edd5658575f443eb9c5c97d95ee798a3809cda76d7a0ab9fde757a310e2f5cbb299ab88e92a5771027ab9f26816c02d0c97894da5976ec90\nA = 3253d712d4ada4c12dab41036fcf79b02e80d1a632ff6ccc44d3c1d08467a019cd6221507459b231c8c\n\nSquare = cf9c50ee8773ba94c9e943989a35513fc370adc3622beb125252bb92ff9b258b81a497700e3bb15bcb23a5b3082c095f7a5d6eef20433d689c20a5427b661d43fb0f9b7d1b16d1b73b8fd59ed319a26c5eb92fce90\nA = e68a0812d2de2a922f24c4e63b4c33e62f93943b7673e900d12405dedd0bc2a906daf8b4bc336bdeb52b4\n\nSquare = f3aa49c906844692d3bc0cf101adcba80351c2e744be01762a8c24804a9d8d5a4cc3c113ccf529eb79cb3304aefa74178afa53f235c5211192d4cd8610c3b42e246621acb3e5d1f9d86ff39a20a7fa9c568356de5b86919\nA = -3e7069ce11472563b0dbeb9a936884df66db83273a690c40e5d3b5f8926fb502d3988591abfaea7b7bd76a85\n\nSquare = 7c9a5057ca8095cdfa289b2d60eec80548f9ab2f3a996137ff9be403b529c4672e003d1eb074c76c0086e3d875cfbc90a40ccb61b799cc0401ba160d8d6b6ee46b2f14ed31c83de54cdf83458dcfc01e3234d9717b5f2c7e5079\nA = -b299da84ef84095d8191fd1cfe847b960729a3d1857082f05b2fa30ac45e90d2fdc778013b023f38db2c8e780b\n\nSquare = 488294b528e2c2da0145217ec69de2d021ca27f145f7321f06c03316fcc14bd4a9a900bd6a144086acad6d5ad32a6245f5a655e007742aa336430c6bfbe174278884d19fd93916ef57215069268ade899cb92dfed29628327b84d8240\nA = 220fa6eaae0238e78a91e43fd8c2fbd5db0c8501cb96d66265c8edcbd376814c39e4a6f21ec9a6472c6abe8c04818\n\nSquare = ebd685edd991dd5180706b72ce20ec4f6c5d9ce038cc8768f2ae2d0e676bd549d6d3f97f6c26f6e36bb664e8a7e6102192bccb354c024670085711db30159c6b7badab7c7c0b91925675ece3e23126ea6feaa28e977598a890e4e476ead100\nA = -f5b657cc38fd11ad2f1b188c61721b5ec6c9762c09dcbfac3edc1f07e675bc058e77eacd01a2b4139b1b00c40a6cb70\n\nSquare = d1b3ac1d7042c0200f80a989e053dee31cdddc835889a57482a0988afd82b0fe8d3667270a72967401c3e8d80dae349ccd4063f11cb24dd7f9a5aeaaa7c0bd7bf7991367b0d7b4d374dc9c5017da81ba39fadfc3b760f68da95ae1eaa2eea3fb040\nA = -39eca1bf5e4807fd6a9ccc9e3138a6fb390b10a330f0027f0ba9868beb77c93160b623de58054a4522183fb3e4e2d86b08\n\nSquare = 41c5e4bc851d48673e0a16336f0decbcb59dad36959b310cd1a042d24de00c587db47058c2d91d7f9982bdbf470c73f86e591a122b3fda71796e465513e10e3cdbd5e6bf035595644d588c091e23a57cc47b5173743b0dca965902918d61875f88735a59\nA = 81c2caee75e98f1822c854448302243feec55a5247bba948647f12d7e0bcde4b1dd6af63eb1ef948eec22a87d2f3213de75b\n\nSquare = e712c3705ef2779ec997c430f1f8b7689d7edbf2daa733dca89612bcb298180b882cdfe8e5cc1104b9f5d6d8f0978b46eef4f297dcc83fce4c39821ed3205e399328d69ad484d8b3189e207193203ef79b763f5e11778dc24839b4feaab291a0464cc66edbe10\nA = 3ccdebe5106ff5642b4ac0751bb799c27454f904fb72863d1055d1412b2359120ad196b768f6137dce4cb85cd29a990838a95c4\n\nSquare = b5063c05ac122d0d4b1e0d15c913f70f1309933ba737fccbc02d13a6c712e7b75fa757ac0e4fbe65977f17bbefde31c8fcf51f867a698233bf25bbdb1f03c104dcdbf1173886a48eb5a8b4d27cd841196de0b53466a3f1d28500fb4dbcee8d3458662443eb2aaa5de9\nA = d745c04ed95d4090ed66784339202f9d0e57bdc1a6f6b6ca09337153f0236cdf99b61db85604791b3a373885210f6aade8530c8d3\n\nSquare = 974463573c968f1734741dde2a800761fa749b553dd6499b920d3af9bab73a87f40c9cad39c51cfabcfa0895f1970281af063d80f89f4103624a75bcb0d23f5ef6c1cd9a10930118e1459ee8732728ceb7961f7d83cd2344a51e6229fe708bda46382e142706137facf7161\nA = -31323f98f0f73f", + "b66e541471774ce0e0fff53d69b2b726480b9ec7b0775b345ec4ec57c4334ab8ff4b388f4c7fbdfa3beeba0f3e0bcf\n\nSquare = 673a62011d769ff0333f69f10f00b28781fece47ddeed25fb0bf4f8d95dde4efff60690076aa520ebaa3ba63e6d445541b9586241141ecc37cd75b178389265224533055ec82a393e5dd61640d3f442adaab917c8fee1f8fc0ff8ca8d577e1d2d976c2a8b873f699aa92c272c164\nA = -a28fdafefdd393f993a8fc1ae321e420451dd0c5071410367d5a911b2a3a668bcae4452e134159e0b1974505f99865cd97cdb020bab0b6\n\nSquare = c4f34585a29667b582a3ee69b1a5f6c04746d105a57bc92763958c5add45c64b5c1cfeb1a321fc5194aab818c92ede5408afae0a2a74ed4c7757dae0bcc602169a805d525c5a63ca97391a9a7987a3eaf04bc44c89547c5d312f7193fc571851b1a8f8f091849f649ae91e15a050f5799\nA = 3822b607fccfbf0c5be97d4358bc682784e6453c71781fd3eef9d247485211c55d742279a35bf35e64ba8ec8cfe20dc0889688e2bc81fe0c5\n\nSquare = cfdf0eb68dc27d60840b8afa8daf96bf831002dadb2801c5d6f7ca558256bf3c7c5372fa00f2b3e300287745f8664dcf8e679fa35adfcac93839cec53b349553f31058a4db05af40b047bb367234dd78717aaeb80334f0deabb09d2d4d90394ec28cc3589b0aa78cf227ce8678b8bb5cd775e9\nA = -e6af13779d5a5eedfecb7c4d34009affee1f0bb65934ea9656ed6eae02271ac8a29104439000650a3a8cd7fecb171a7154c0e2bb2b1cb908cd3\n\nSquare = 6ec1b1333481c37be059ed7e088c862f869bb559b34360781f7263eeb206a210b90321aca198aa41c2a79e3a8d7df4336c75c87ba2ed4b02052a07b234afd9d2cb55413d4296645cd0dc8f987120acbc82fbfb089190f50e55eb1f509c86734dc14b2e8ae42ce880023dc7a014b02727b53d0e5f779\nA = -2a18acca3306bf06fd90da4ec2cbce995fb08beaec6d1cf4b30694d682c83e04b39f9a569eec52782b9eda7db0680165c77a1b0f54a1b995f8bd75\n\nSquare = 5382be4ee86b9d80dc2d4ec58606ac538ba7074d57e2011346f0dfb9a9d6677fe015e4015ed607906e9068a3c5601f0bb77186a9d147416ac68e344318cbae5c70c437c5e1dfc2d6c3c8725198937ac2d8e796f749bfe95c7fe6d0e460a633be2d86462d48290a2f8b344ebcda2f6ad353d6fd5f3355d819\nA = 9236f7ad22da9cdd8c187082c630098bf3a558b04856e876433c570a63d39863416c9890dd089f7665d6ba073b2ce90f88e7d04af96f1c82287903fb\n\nSquare = d68e15e8a46e001e47022daf63d2b33fee0f9d3dfefe9d204b0de6daea31dca4b287a60827bda9de2860c433b77186aca10bf3ac1d02a204ddf8bf070c3c20ea69d9638a865c8843e8e63211951e10a844f8527345c5bb5417e3301a19c929e6fc48902f0e0be8e393ecb3fe0e9de6188a72d102fbae846d05dc1\nA = 3a973dd50d4239f05d86ba25ee6ca8f8ef46424951a8bb89e7d1d6e066d6fcbabb3758ad9e1647a440e51976c0ce628d78b59a4d9e42fab0c723182b31f\n\nSquare = f03a448bc7405d2d54c0ea1a9016d8757d4af893024e542df80fcce448491d07a4b451d67c9e7d9a6c7c5a6155bf156d3cdf8103162d8e0265111655fc0ae46f4be944fdf275221b217274357977abf64316615dafb6ec84c5466f617c4e8d9ad4739f3e5050e583892db75366a4a7d2c4558436ed036a79084c7f9100\nA = f7fd0a9634d14d540daea21c7b804d37de49b7c13bde85c045859ddae1dd3142994e385f455becb7ee30576d55d4dc2f3d9d82e86032e170da1730b2c8a90\n\nSquare = af945dc2241029744548517dfd7858d42097076b06427419e74ab08071a23aaaa1f5daa6290287ce8e832a0524ba5581d64abf054408ecf6ed21a4f8289c1e4c7a8087384d268a1ccf7ed40e74922a619b5c1f2c08d810065710046190b7cfff33d4f67e58927477500eec54ba4f63a57532ed10c6b861fca9d46bfc3d32640\nA = -3500a8b6d244f1a21e10de7cfbeeb75d57ffa62e9dfbbdba8fe93d17488c56dc89787f13e660d0d7c7755242f8412d00988bfc7d3f6704782324c48691e7ca28\n\nSquare = a466e34dc7875aaf945c088bac23f3347a41f7cd039b0c9120c2517ada94b96bdd72d7c9bb55539af12931a3a39f6e09a4cd4311fba57dbfcc51bd17b03905e2560275c8bb3d786defeb131a634e86ecb793867355b048dbaf2db8b654a4d50aace6bc9d60de6934ce25ab58381f6ddbd1c063652e283c30a2dcd61d9d776d60e209\nA = -cd26a0c3d84e83d9f14dbe95cc39e3ed2e8861b76f4bf55ab120ea636d8f9efb0b6198986eb52075108d0a5c6ae0ee762f834f3db802c3f20bedf938f47b8bfb03\n\nSquare = 9f3f4d5110ea1bad21fae923825ba869a9982b753284f1946edea19f22cf0a49485b9336a2af7df8bf2641cb2083f4dce82202162d85a5779a4394213bf3bb3e47356bfc1150e66ddb6cd945092c9af14eeefd2d08b76c5e4a585ed8ef39202c42dbbceb25697f22f9508e7d954d3c1da103818aa6f63121f895e2c26d3d7463aea7ca749\nA = 327a2f6607c41ce920c14e9c9e8a059a931d71aeebc3e05e93107265a2810ec286819a4b2af9d2b70b754bdab6022b10ee6b81b32a7382cee99fb2bbcf6fe85af05e3\n\nSquare = 50ac4c46f2014a7a382b0d5ec9db4a67f34ffe9fd5410995810d3ea8d7d87d47442d0253c7eceb1799272bb5f5e7bd63174959f9844e5b4b65b6a4920166d83d01a5c2638b4d3b6db7fed99e28b9128dcb7c10be539114c5887842f8e5a7fb743298ec9642e50bd0979156cc6aea9ce802a0c1b14a2a1b7afe28dba534c9933209f14474b6e484\nA = -8fb585e01a0c62367dfa8a1953e553476b1564e843bdc2c5d964864ab2da56e0bfa7f5ce5b7850398451619a061de02ffbe0c336ecbeae818d32dcd40355fd11a7a3822\n\nSquare = 9214e31bb62f62a7f92d6c7f1453bc4430595a1765b7223a1e50ec30f934908c19fe82d7bb8ef1174bb6787aba9df1a38a84203630ae9f62e08fb4ac55ed329282315937d193992e9e12adec9727ef91df5a065cc5858062c765f34bd2630fd3f654a8f8421b75dc384477744efef3d6f0d15820c9328bf43a43409f6527dce48a92c3e1ef145b5e284\nA = -30587ef092cb9456caa844be9629d77ef1bfe21d2ffd5625ea353beb1f294e38a7fdddd5bf77cffe5caffaf609b8976756c9eb4908ca77b1630ac0d706503c46177c5d905e\n\nSquare = 54bf52644a244276ad3dac90661a1e21468f23a117a1fcc904c66119d86ce98a0b90fd4096708bcefa7a9df87c6bb85149305f193cf5505802172ef9ec343f662a4c895a9d19edeeed5d91e20abc894948fe59c1869928616392f3694d82aabee325b651e1170006ca1fc355212308442a5ec8a8fda4f5f90b7fef2aa731f3fe0f028143ead04490d78b2151\nA = 934b16f56700b455d5791ee8c119b5921976a829bb5d1fedb201e63c9ebb82afe4e29aaf0ae27148e4d34269c48dfa42131cc8b3b78e23ac3e7292eb0d715247a345c800f377\n\nSquare = 63b7884fbb6d5521c38f7deea5cc131ec6bea15a362322a8e27c762880836cffb69a069a168663908707bee9d83aad41c045bc84dadc6cd927ad62140f8c2fd001d34f0a7462bc939cc8996e17ebabafda95a73483c70191311a6fb7c670c76c9e2ed7e589e464617888d30cb7793e91672d7de9b3b4b1811b2c009dd1c690d44710bbab832d91f16f9b3564a0c49\nA = 27f17f0865513350381ea1aa1545439fde427ccc64385979bc787cfc4c7e6b624b2c77140da2c4176c55dbe43c506fac14b4cd7815e87f3120330dd3003bee087a371f85d6f4e9d\n\nSquare = 9d1c4239accb286c3c7868ad3b4dd97b93774fd0c65e04ca8dd405c0298ec6d1f52d60be6ddb5f8f0389cde756b49b23dd2f0de568a432fb99dbbd40db798261d1dd39bf5017e6dc74cb9ca91f8b2f892c7eaa28485c04a96add206c7c38943912de065be17b65292db5a144f82427016b5e0eb4ded2e4d0b7d12b01cb0b2b61e5e1bf22dcf1567a8b149cc0ef5299a8b1\nA = c88cc5a46bc1cffedad4f45e66fb55dc4347eb2a24a09878358d40fbdb03e738ca1d54a1d26a777915248fd730daffb0d3b5305684709db0f258f581fde06b11a33a3f76b3fa53e39\n\nSquare = 789545f15fded8fbf0b4275cec30c3ac65eb42ab8cc75670fbb2ab0b4cd90ed41a1290383b5f14bf87a88c67ff1e04d0f478fb11fefa64e86eae5777855ddeae451e166e23ec30227fb4021d51ec7cfe4ce531c78ba1bf6c797dc73f093b0a5a5aa59ad8de3234808e776d690007c8c332b3f03331dbdbb8645b91552091afc36c28c3229220b1a7966c7cf13db6bdbd4673440\nA = -2bec94112014c1a506417e659157192dca1df58f933510d7a8d6f6feda5031d799a66d2746c09f827199ad9fcbf11f323a636feff5806c9fecb2ac684c2870d60c8a72358562c4eaddb8\n\nSquare = caa64c9f6bd66f76c99604d1f2b8a29a9a10c0d6a41cf32b5bc40edd7a1d97b295c63aa62c30498f15d70e427d5612ec3f6a2c1f2997fa9283f48018435fa6092269dc2e4ad524cc6da9689302f5c398d79e2b2d19470ea8240db9df0bc0bdc911c4d53f4f24a7ce44ec76378794d16d367434b4f8b6184c7651db77fcbebb8fcc5d3a51ee9739922cf20d4a8888139fe4669a164400\nA = -e3c4a10a64b7e67d786aeb81bb7ea14655637ce963f46cce59bc0cb6b5a9cb9c92afec3d527119db97bd2605d315cf28198992b4b2206e5616d3c560bc8163f56cb1f5626a7ac6d8427520\n\nSquare = 429e4283af7f895fe732ee88e4904348ed01bf579a93cffb7aa8e135d41cb9be218f8b9a9cb4f556124105cf042de51f34c8162fdc7a981de88e005a014149c955068e87214c174daa40fbc618c536a6e507ebd313763fba197059d68c69bd39933d614b2c32f235cc955e335c4a37b9e98cd7f98c7f26ea2da932c7f82ffd95be22a7741da423123f8908cb188abc26afaf4ba6d47b56e11\nA = 20a5e2a911627544219a1639c3321bbcd6192a32129b248cf62351f85b7a719cb275a4e44368a74f4d1a307ffd27ea2cae4d8584a57070609a30fb4e365564908f3d501b53c1a54f0e37745e9\n\nSquare = 9bcc8d423c3fdfaaaabe24a910e6ac3619eaa15e23b9f317c844d39d164c952fdf5c4bd270a83f3902e54d3817fd78c96018a706c1f652025dde0b98afe35597e0d8782deaeed23337ef6b3edc9317d54e3c8a57e4e7e2695f9d2681bf82927bab193ca1f135bd0e542696772f08520faab61fb4ea6ff0d15bb91f21e68bd7f084a6b8f24a47ecc30a779ee86610387b29a1de94de517f81318001\nA = -c7b60f4c355f2ca3937ba3c124eea2cd8d3536226a44afcaa3d17abe931c09ccaabf25a1986b172fcf46fb02a0fc36f2c163b6e42cee047c54ab05e9d30f03f6943b9fbab83aa6da12d7898c001\n\nSquare = 45df25540de94883dbc182009c29fec43627d3e5758e6a07cf40064e0befa0df184528a84757b445dd079c2b0feded48b651ab18b4bede2a81796be45caad0125c3692560d19cd9a6c8c0de8383fea0bc1ab46f6aca4e9c36b26575cff88fdf1eb1e13182308295457374968", + "fe3a9ca34c6acd24c753fb84d41246614789dfe154faf34fc684cd15035dc9c1c6b0ea171e089e0f3236840e355bd123ac4\nA = -216f8a9a3e54d4afadf368c2693743efd3eaa4cbda7a87cd07f5b1a713eefd2548343e7f091ee4d9d6ed1d4343c06a0597db0eb5194b91bf2c858210557a8288c1aa7b0e0607a24dcff9de04146d8e\n\nSquare = 5cc707d97eb107c5c40c0f19fd432cbac9855f280082802dbe4deb45bfd193ac7a9149fd12c4ae6e9282411e2f1f2ca92135424f215b800634092ed4ff2859d16ab9fb8619ece41b50f8888d3e13773d38789e19158e18396096dd57fa5470f50b391c22378d980e59b4585f013e6db52c1e24c14ad83262fd37d42f52323896f7d4cb3e38868abea8a07e7ad3f90512eea001c5147645bf00396cb0e7a553f1\nA = 9a1d1b0beea76e7f32bde9f4f2c8bcff9094db2d32c04fb7ff43624b61033646e482aa0fadb9f8b4225b47121070b4ee5d6818d3606ed775aa631e0ed42da68c2a09dab26b6a4d09ac226cc09321fed9\n\nSquare = a32fd053eb90c365e77ff47573a24add3b25b4c301f4c662dfc1fa635af8e18e7947381989b37a9c9de2713ca438b9f85890b7b160fe251933aa7dad1c3839d502debb42ddc927fa0e9b40c80dc3d408889be567699a856b1c9cf3a393b3b818432e95feea825c17d0981b942236b3779f2acaaccaf9a5817ca47bd03045fc4de454d8f1d4377e218c5f7ece369aacc35369ab57a71652dd42621491834119afbe729\nA = 33190b787a2c3327b122d1f5823bdee5c93b19b586ce1bf79d801a19b2558aafc8f6274d0908bb7a8362f7f71d3fb52b8ffc87d458249caba7af3a516ce868e8a620e3126ad43d6aeffee11866fe77677b3\n\nSquare = 74215d33fa398e21c34034af6f9c7af6a3e01982320ec8cf23074a938f1a31543f80e6aece01de247668fe67f276cb4411db27666e1dc8fb2bfa4eb68cfd3563167d1ac4efa3361f920d8dd0fbb7f06362167f5ab5ecfb72956c20db934f67ff1c75aabb594c853fa61f43d219a3f5d0d45274005e3b167cfff5493b0f26d15f85d8e906a0a6e7645eac1f40c6dc637e6d1e061e5b9071a1227469cfb2c0f17ff983684100\nA = ac6c0b9c69785f35dbe244dc85a54313ef836ac67c853531ef5db45b28835ffe61dd258c5528b0acea50f5aa5c0f5d08dcb8d82ee19bc432fa8a45badadb50693fedc1cc79a17d63aa73fe9597f1d4ce8ddf0\n\nSquare = dce5cac967c47b8a58ed6f1bb1d1e6185e849400228afa2bfa05b9c2dd327b04a86f2a4da2d02ea102868ea0c4da0f3e5a40bd02c87a08aaa5cd8d9358b3a5ebd8c9fc2dbb1268c261f46d6717b0307b993deff0adc8190d32b4f2bf695eb2cc74a6a9a712c5a621c673219ff8a24ded0997508f8f9eb1ea872008c46e71fa97f55b839950e63130c38b49c0ce3ce724a0e8faa9738d2e28ce6e7fc7eab62b3561d2981f314f751\nA = -3b735400064b15fad81b08362b8557f8318c20656839ffb4d2513512015036ab0039442032f1cf515f8c10c9933afe4206a2f309e933d1561b06bc665af2f04f4d064e073eed2280053f56cbeb137a9482c0a077\n\nSquare = 6b619bcaf632f0d8b1d715e8850c0cbbd29ac6373a9a5e93dd1bbd2b82744a8a50a7446b48c6e215911ffafcda9ed7becaf5d26b7d6df7dc8798d53239f62a482f974bdb654750def1c941c49a24fcdfcfe73881b556a7b528d88daeeaea8d62b357211a1946c81cbf0819ad8d0188f60aaaab4ea2dfef7e9012ade7abeaaa4a23d7403c1248c36aa26b43b8e7de8a5aea639a0449f50359e9b4c1b125a548383af33703f8dfbc2528e4\nA = -a5ccc69663a8712c15f96e6fc746252af89a8c2a6317caef905dd2d8a6d4fe878ac7aa66cdb3c3721ba7dd36da310753dde9801b31d759339ac919a464ab52541bb2e0dc938752bf0f1ff7a9524eb98340d62576aa\n\nSquare = 77ea5b715823045afe13d10416dfd46a511141a7d1279ebd624f1de428cc04a4f246246e65c3f84344cebfa32864de9264b2e54d4b3010c4de9d3e6a27aae8f5f9e9d8e49fe26b73ac7e65bb216aa6a42db36ac03d749b5dc04192df819631593202a58264714628686507fc5655f169483b0ffecf45995cbc12faa105895564d287a9f4b220947d6c93786c85b2ee84a0a29183483f7c241d6a67fd0b1c38c7f74421355a14c6d9ed5720e24\nA = 2bcd67e6bde3f54c4ce0ea428418fc5c97272217c6c7de90549238ee322810dcc1bb9385967673aa3f9f5a5c05d987c6445135cf1efc26b3c17e55b93cc052761a77c9dcb5c22927b09e90a92e053ec1bc799bbe7597a\n\nSquare = 40d113460ca3e70545bf3613c2ba5de5d8485641ebf531a43b6b8bb76884ff4f348727ac6606e026981d2116ef1e60d4b37b44ed7e2003410d7d636b58aed2f92e962003f28342aa5f059d23b3d58a1ddfb47833ffe1d1deee0a7e78b8f7d9d6487f22376664f1ed9ddb5ee3d17f43afda296bead11680fd17576a122c2599fa9802ddd84a2115f9fda03aba898f66e303895f452077c920a322b6aaa0965f51fbb36f01b1d412c6ccf390da050d24\nA = -80d0699a46619db033461aa6060983def7deeb976d1a71f5c6ddb85e8b46dc70b7ddb1d254971d38ca87c7ee3905e63506c6db105dd683375f4239523cbf1874069266c2c0f4b37edcdd261c51088081d25813758bdbfc6\n\nSquare = ace99f98cba0d1dc1c758dc7211aa4078a2aeb6d3fff19bdfa6981ded0982b15bac792e6b542ae48a86f9b40c6de937e402e230fcfc390b10c3e60202dee1337ab39da7a342999487b8d8b0e494f2809cd1bfdb39209da5daa590f78ded211b6bbd3fca9013300b951d8906c9ce8d1c0dd9554d5d1d352f9784f822c928dd9700ef8a5fecf3771966abb1dc6a70b301461eb6b6087d6ab80a4b624205489584224cf6578f75acd8091fd621d02306504389\nA = -349936d60c9d77a0974dc8985930d8674976db6b3cbaa067554ca6b30b1de33f2d4e1c9564ce102ac6387755aabf42916f63632a375d995913f9d45ebda54bee3fdb7cedee46ebb5c8ae7764e4de323c17c797d3b529230cbd\n\nSquare = db6c73be2a59bdd35dd312240aef18dde4231c72aa28551bb370a87dded587accec2279bea24c930236f06f24d537fcf242497aafcbf72f085fd3ecf030cd750fb382efea0f82ad9d3195680324d73fa99d48802d085c150164aec0d29fdcc3262264bbe72311f89989cc71a4afdac6ab103ab4fbb6e973a42a1f8711bee463d198f727dc7bad848ff8fa77cd3b2f612d142ba46e95bd79a86a1fe4c2b8f9181be84825d05989695842113828a83b826e7d2c8c1\nA = ed01dd49d2e5d51fd30e9c578259cf107771b4ded6bf21f8b9b632fd360e34da740e0b1af6b5a67789fda5a44025af0f1547271ca8accc7a975d98ea7ec3d41c9697018d84ffb5d49b88d884ccdb011f715a199ddc44a4109261\n\nSquare = d6e38250ab89ffe11abaf8c5d07ba11e9053f1924ee1228f834111af16ed282389d04330cb0f47dbb186dee577aed82878ecb065b759312eaf167c4698eab5ed03a8657341bf5fb14a8e28e3b443a6b657c1f4379ff2549498a33922ea84f1fb19d10866fb0ad07ce1cc44c93cd4d9ec6bbb0e61c797750c6b5d7e8d55499655dde112f4747798f0e985fc2b937a44da9b04c2dc4b0816cfc57da1f80179db653c1ce287e786ed7eff7ad6d1383fc6de8c941d4af7bd1\nA = 3aa2e696ee570160b2a869c3f21c3f223959a185cda2274feea1c829af2234c70a504c959bcc49fe0313f4f5ffd27448e28aa0fc6ce24f36943d334c626459d7e6017339e787ab074879ebf697a93ad93835d69ab09294d007a0837\n\nSquare = fc39360cc0fe040b6f8340e0728c650e5e74cf1664f7b301e79986fe066f36e8df34d38d1a06b74a1bdc76867baeb3f39a9161acd200bc7532fa4aa0ea829377659646f073db82ee044279ae5fd797edd37d3261970819589853cb320887a085c4011c23d0da9b6d6f1b5911bb3399146c2912a967ab3b3f611f0bd52e00f418e6a6f0297fcf5c4a1f71c6bb8cc8e1c76694bb7301502d1d00c8b6c05bfabbf5d350590561abf3e2b1a82e98b56583e2e4e25cf707320a0e40\nA = fe1acf3d7b54e718c901c53f365894c22c8bb4182fee8a4c2558731e01e1519bfd1bf6e353483b8c4219453fa66f06063c6c99050068c15cd13cd1648ffc42b5badfc70f6fd4a0a5552fe637e54c4f92ca45c60cf9a0163978ac08d58\n\nSquare = 9abf1324ef65c726330f64643a024c466fad37604f4dd3dfc404d31c2a430fcfaa0c78283666c15a094d494b96d3c12de6e29a34d2c99f4f8cae8217bcd2a989d59807ac68c46d60600238a86155de499eeb35642d0f581045481b40e4f0a76905f9b6bc5b9585f77f8410b99333f7ea983c3f29f3fe66ca7b793b784a5a6a4f74512aa4385dd1e996832b1f41bb3af965be58c4ac5e867cdf8dc6a4f9d20a6f1e16e153fcbb45ae5fe8a798cb06a4ffe467d6b6aca2b31f335a344\nA = -31c243593ea611dffecc65d1439db345b2e89941113f9792c91a76b4890db6e4dbaf1482ee812e295d27956e48d07a14de38357f15b5931c5cc08d1d248df7bfee1cae5b5ce98984c5043a3e1a2b449ba1671bf1cfef91011e12bab94b6e\n\nSquare = 66aee3e4f43c672e0478c76e2092bef33e7c60afee5d4c7defbcc5c0c86d8fe956c90a740cebe604224cc3f518463b1208699b8ea2316315474991d0f120ae905a67028492cf46fff2ae244869db2a02d06aac6ac6eb054fb3c14c756d8a3e7ca64f06586e3e86e4477f185ed527a8aea6a3c741f3fd4b64a2ee77ff140190260c431cc53f411fb227377c02f85d0258a75bf6d44dccbb8bd04ebdafa115dd55b176b6eff5567e5b1bedcae15110826574053681fe25a695ac4540186e90\nA = -a221dfee30286adc076673cbcebd24a41a438a0a7a6a547c75d33149cb1a094a8425feaa5a23cc234a722db4cca8d5912fe1dfb6db4e92bd87c12f0d06b6d954fdb9b172955412b2eb5c9fa3b4df2933390384fd1f929a2b1a8dac479ec94c\n\nSquare = e880f8655b51739e34393c3e6d69d63e0256b1a887f7e69f40c78d21133b17e92277a136f5e37da2533ed599efad189975d22ad0340005ef58db0b471651d749dfbd48b3f7b3b8a42d4677048a855e99dae6c729d8bd7eef86911feca9f5490dd216b06d9e8d1ab695c1081e72449baad28dfe113744853382901e6bdab5413c67c52d6cbbb2e0bea711edbb3a219a4046e8739c04729cf8c8210028dbc4087737bc6c1d7e0c15ecf16774690168342b1372d3646d4d8696384bc932144c98529\nA = 3cfe075d4525a3c780d6d05f7bb708b2fdf7277a0f9967e0a209fee9d42136a0bbf98660d8ee8cb4720a8042da09f6271c45ad13db24eaac465f8207f78629e9085c1c890675f441c78efa38e5022b1b80afde5e3fd08e55648f2817631eb6cb3\n\nSquare = 8d6cf4eaf58099b1323fc598b7554b371f4afef5ab501dd162ab8429333d46916fe15dfc4ed6a99ca7fa7fc1aaa0cec3533b41e291fb7f69b560259507226eca87aabd07b1ae2eb93bb53f98fec508f051cc04db4a172901e06b74229c4fa3f550a81626c7a63fa99d41e46c2cf792287a5cf7bb68946971bd43c7c0356312cdc25e524665dd39a24b6464bbbe", + "64fe8e87ee313b860639728a9143c3a6118bc8b150dde6c10a13bea637fa8873c393e6338319c506aec6ee973b4b52a272a74bb62084\nA = -be46a8072aa44b3bff0f90c81474dd576756fca624c15f55a17e1d0bd2842467ae000b04f79f561690c93ca7118ce17ecf830a8da3678c15436876d2a74324d9714dc8ad8181904be657d7f1da3313b78448cc06e32299a09ed59bfc1961e8bd722\n\nSquare = fbaa4fcf9800673fbd3a132305ed3e14f4889518fb56ab82aa5e9b3529b74d7f9a467626d68f4709a2030264aaebcf05c0a0edb511e81f357d85b79d925a24605f1bcd4645915bb75d363654b676266329df532cdb39152fb360df1b9500e0c296014289650ff77faa78a604397a82b34d16484e94a8de123fe720e514c88f11ec276725111563db91477480c3245542ec6bd0bb2f4aaec02c6c4eb1769030a31b05da3798c224c9117f7c38d3e98a343fca03ab584ec2d7e6db60fdc4273c3d8e23cc1ce09\nA = -3f74b25f2a9c4d8d977e69a4e067f9fcec281136a508e365b282e5fc3b1d097bc6a0f59f7827fb90d4890b08840a0a1919032c67448f8f1a771f785a0f125a4aa4137c154fdb489dc1099d57bfcfc75f4ca5e69f93f2bb87ed09cc0dc620d3e76ecd03\n\nSquare = 5135becca97d93dd4b16a5a1105ba3a3e3fe02bd6a7c3cd182186fc63ed4351641182a2727ab6715e9672458dfbc31aded4781fa345054eb4c317872e2af6d4ed64b2ca7e8c25e1e664b5349df937118632a64e4ce439ffc625a5ad3358270dc83fdfa73c7afba03406094fa36d87517e5e2e1fee5526fd2dc00d9210a0f6c3745b3d4bceee5f8b03d976d696c57a09d1e08e4ce780972eca4f2ed6500c23bf5782c31f13059e48246180fd09db693d2fb5d48d51846ece8beee45cef7efc87c003b44d7b137a900\nA = 902fbe2127354a7df5cb7fd057f3d080a7bebbdb83c86a50560b8c287a37a841bb9c8421c63d359078d2948b6b57559f98fad8f8014f93c912cb70a6701c4dc4fc5e88aa413fcfb685c32975a8b72424742eeff8262d28cebad00c5fcf88baeafe8f6730\n\nSquare = b5976cf6a6560412aefa6704b126e0d987dfcedbb4da436c08ce17b1bf1b6e0bab9f934abb5c4186a5415fa38724fb8fa341d381319e7d768209ab108c8debd99075d31deb3e03ff7d23957d4f3204d543b7d9079cf337be3037b1cb4908fd8c104d92e52f041b4cb27c045a741f4d64009980e8d27af75d9493920ed98c7234777592d6577f2d1b3a0eec645ab4cee2f28d9e4efd3e4514db6796487ba68a462fa0e316e1420d6604db2b901de46553546cab42976fd0d459afd81196275cd88ec4dd448ff331bb35499\nA = 35e700e034950bdd7318d5b3c17e90a4772ecdacdb055b9391b31538eb823fc8a4599f029e78e4fe5299ba1a423a449dc257a431d189dd5dca275c02cc1f12417e111c73b731631d8a1741b907dd8f24de226ddf9e3044cf4064e8e51ebd55be774be7ad2bb\n\nSquare = b7de0f73397893a97928e266bc56299cc8d43b16a251992662646072b58fa578ca80f7be1e12619012b130e9514be803dc166b12ddfd26f558d36c2053ee6209b01458379e49469753300ef20f6b3dcd5383b121861c76ab25debb28c448ec33a81250d05f7eff80a5a4133d522d270fab29f739b607395a77278609aa5e1a55ef58d1d48492b71ee30a24a6505aab1a3ac22b9d143c9d6781fae14bbb980fe3a99dfa9a1a406611d7d0304493342f53faf5fd79f9c96b9583a219a1b22aad02dd58f32ee98146b3a8cf054bf9\nA = d8f4d3bcfc7eebd7068b851858c3668ce062a834927e165679b49132d4f780ca682876c65c7cf2e7ce34ed10e43696477da6301d13f92abb8c76e2424c4bc28a6565f15e59563d607b852dc946652b68fbfda1c3200ecc2976400ce7296b96e75fb059a4c8eb5\n\nSquare = 5ec02661f49fb9807bb73debc3c6eccdac1df1735e0d61fa7e0eee07471068a5809796a2af490c46a77d61f618b44a3168dde67aae1cf9e530382411056958d55bd18f0e76fe2c31c98b00f87fcb7f5691ed5b65424f82204156dc361ef6dec5d44cf690582599b3994ee47ef42850d5d2370a4169c5f73942657f85422ca24f66943877f73af493c865fbeb29574cc1cc730e9bbb097b598574f6b90257748e950bff867bcc01bf62f8df67d7aee1b6dc1d5db88826e86a3f9fcd8663e09cf8393ee71a09c43d0d38ba6ef643f4ab1\nA = -26ef9b6708a80d00f4d01e0f0a5546ed217085ff23519819ee89af430580ea1f086beb0eb51982682c6d3b922a2c92752dce63657836223a9d94964bd584bc8e37c6e30fdcaffbdb128344d51a92705e1c9f94205ca36452c15a08f7e62e0e02479ecd48085de8c7\n\nSquare = f6364409467a829abc2b13c93979dec84984caa12154b7cda2f4c8d91bf24ad7c45a968ffaac8d6722cc26e6aaf52dd29ea2f09370ba46d79684b7a06faedcd17136f35a58e5b550f3a2caef7b195d8409914fedd3c3154101bd735155098e8b10fbbb1b2e13555d2ab5d5b52b203d4efb27e498b240f37178f2e89b413f94859b0e8b2ec10b926c8c0b6f2937ee2d0355445364841c7e0539f7073b88c7d568edf1b253f3c10627e22c2ed731b7d4d199449cb0b5e7a66109932fe2c9cd741d75170deb9f98469049549c10a7a622bf6e91\nA = -fb0eec3246e99212879e51b17ea6615275818ecc5ea3058b13dbaba2576ef90e1519e3629b09fdaeb02661091c395c862b848f6326b9f536f7af45718c4412f09f19261b537bca36742d3ec66f964343516aae2ac27e249a15beb545b447e37b4062180f6c82809429\n\nSquare = bc4193ecb5dac900191e02be06297106155c6840c4908fbf6e41e9aae137d53c3d4ffb87f334f49837dc4ab7a66299994e4f5c9bf6ea03e7db663bdef066e94c610580a8896a9ae9c8f6587eb83d789683f5d6391bbac3a1dc1de60b4108428e6f5fdeaed6cd3e74fa01f85c6368023b61a413b69b14276b66f22653491e4f25790985053d075387cb13c79dcf963b6d880d01174314921afe1cc700c02efd2979dcbc59c417a6316db9ac45a2d60d2a036571bfbd75f9f5e42048ca086cfb4b818a9beca4a6e0ed51afa320ef3549151fb39e100\nA = 36e1f16043b4c9b4a304496c39dd63459d6521d2ac92916d348daca3f972835973fc8d21b07b09d8f5e3197b39a8f3fd0011168b815d67c48143c413e169ffe0f56ff2cf8b6596bd0a3b5b7a6b9a14ffb797f350b7e6aa7020d84d1d1b8006850139795abe2c74f03b8f0\n\nSquare = 4cbb5bc1dd7112326e2c94581f19efc8fb25339a299fa9c007114c3a22b395e9d39a8ffe21134e97ad1b87b97e667ba48b2a40af61afc81fb1e20e8e38c7ba666b146016af4dff3faf5de306591e5ce6eddc1173fdda6fe241a9f2fc6e054c41e56d296f8954377df0d140096b9e9d6a5a23a231db4dfab0cabfb11190c7a0d1c55ae35203836d433da96ca7339682bac0a7edb8b5b4dc267c6e83ac9b67a0d0d564717ee3c20aaf52c0a750f3aad94a12537c6971ee009d0f82ff576e984b06c7f7b357f5c049454e31326b952af17aa62104780e9ca1\nA = -8c279ebe466de3115b8740f3ff9c1f605b4eaa75512d82fdc8ca5ce84e11a68688154fd603ae1d607807dbfcbb822a8dc259098842c6a7b7ec350be29a3daa20fd5b093a56692e9d42e7a389c4ad2122a74205f835e268c9742d09ad36238c34e143f6e2ec69c0f490d29d1\n\nSquare = 4f771ade09cbd1a033d2bfc6036fe46ae6c12acc6f2b9bd52e7781693fa6358cf93089f23d1f0ee6fca476a43093b9b52446f3a7abd72ed0ce9b562dc438822ffd84bcd898ef9d092f1b0b7ff89c4fdb33d8715dd4a0d68ec49ad41338fbb62ca87867d847a4d99310641a37ea78b04c85606069d0c0950484ddbeedac8ec6f95124e7fd83da4e942d40103bc14474f5cb125fa0b06cf167f076979948003dd8dc3711923f5af5beb5f56c0a48ac0c5240b62738c1cdb06b87ac3dfa17befbe938ddc7281f6c248c41a1c7b99b93f69fac83a46eb298a9fd8b9\nA = -23a845bf2007ba8480e3ece0a1bbaf8bfccba6bf061e3fe1d8bcbcd6c761e650891c0958bac68618a1f55b27d2bc6e1e1b50afc29f58e2e034bdda8405e5378cb5bff0d84efcb458c5428fc607597d89d589d85d90f3da4b89a64c9d1623b98b10518a6f2e7d2295c37527026b\n\nSquare = ab45d12a4e15a294830741f4b9d4a14cc7dbed1c3454612047f890211c749d92ae0418f11cd44acbf1585b1f7323b33ac9a4b13c44e1a7e31b0dcc1c6dd4eaa12a655b5de08f3b948270a152db7d9e04dc54677075797bfad6a9a0e3958458d40e3df5e15028954bae99518de4dd3adfb2ec4b38897a8a4e4807849e1416aa4040c95a0e49a8d2889f6fb0537875f87516c3723e8d3b46da8da855929c67c0eb83daad62ceced52b4f52d2bf1c4e34f26bf16aa7da3afe0f5df76c0858ed98f21e1fc3d01e1572715b774bd5c2faabec5fa3fa59a7a1f32565a4f1f9\nA = d164d875e1f766b4567e9228241213e69d6b6c58620600166fac56938c5d9643932d01f1f4a2263dca4b9ad26dca1548e4b5b7e27581a63375d0e624f4e4c99b7fb9aeb25307c61142760bc4771e48c7ce38f5eb2408def632096fe40b80d488fe17a455d80edfc1c23c429775b5\n\nSquare = 5ae4e7dc5727543af39ed3d5e9ac086d1a2220421231b82f6f41caee7b9815b4049aea0d43ff499c6c9e1f226f8641351d03f37731c64686d9a9ce68e9234d6a762efcffdecd42f81044111599963d9b6873cc20bf4c8284fae03d2e4f238a14a74df4388fdc80fad0375a5d0d974da7854ede5896ed2ab25d2b49a3c39093600f73120e4fd2faf75381854f6ae80f81b977f62fc72f1fd01c278d183544052b77bd753dd88ffdf5c01745521fb8474b5c23b0b7dc709bafeb91cee0863a0c23ad7192c43cf15fc181d629853cb9b8334082c915dd3d04e3a0a81511d2e84\nA = 2622a7bf45ccd3cd567c757f4c5796b5a0fbca555bd0ac2759c24083172d82d6a887dcf93d9788fde052cb20a8963cb6db22bf5eee6151600f9d1896a7606b11a1b100cbc0925bce037bcea57e361efcc560a9abc495d7f7f45831c6429ac8f979dedc08c304f4da9c0d4d687376d5e\n\nSquare = 473cc933f5a650a4ae358c7f486d325c0e20c83b54838fc08b6ac3ff010f7c4b6a609bdf472974dfc5abda0c6b33c5ec7dc4628d85cb4276108e2b0bc4e19cba135533b3d7bb6a94332aea3165dccb230860d2353166b9905635e606185b014730e9dcf2c433e18cba83859fb2eac4aabef68c8314ef86dec2d534a184ebc4cb193643add0897341690cbe18bc2e775327fd7d71ffc7ebc49bad83cd68394eb276b2e615ec430180303010a454ef73b6a8f02bc48a1fc8a32f8150ef1b733f07da752b8e808000329f4924976bc8b8573927f18ca7c88c210845de6dcd0dee2904\nA = 870b2c4b054076d0d02877b19fe1210a8fad3422b00905a6db748239b8e807716ed9fee0d8c25496593717917edceb5db57f9960bddc1956b6652868d6ace82827bbbada5ae8c15efa26fda22657126c6300906f90e8fabfd58ddf312ce0eee760e0090fac44f00378c676115cd0639be\n\nSquare = b151124402d2f04b0e6599222d380dcf67b9716ef50d2d9ded0b21521b34a729417", + "1f71b41762511b7cca93d9f50e9e30083ef19144882928011dbb143807d1b88c55eea6b19f0c4180023be6da63a59b6bc027aff3f5abe2f65c73b2de1e71c5f4b248bc4547040764e83a860cb3f882bb8b5f7821f92802808fa37c50f2f94d8f56daca841f42d3362762ba843aedbd03d3cdda887f75ba92423965ab4256eb842ad755aa7a2af331b488186f891065b07f5a299c807dc24fc176e085a8024bbbf12f386ef49ccc91bd4ada0936b6de78088cf5952ae6c04f6916799378bc0ede0da4\nA = -35439da9e361700152a35ebdea253378a1febec5f288e5b2bb0bdf25b84751b47e4da5aad7453b70cfd6640d5832237d2115575c738482ac6036c5fc21a981c0a7f979c8d621a92c02166b777475618aa6362a0e225dd6138ead3b2766ed9785ee01e4950a863d2fa0b7f5cb4c9a108bb626\n\nSquare = 4ed7263ae5beb0069f24318b38afe951a5a058a2e960e67f086c9680d0cc6d713f943812070bf94152f7926bdab9e5908941261244542b832f458f05ed5dc048c8b9eb84c2a85efe717e257796b4ca816948a6c8ea209c0675efb2fb5af4622b44e36066593db01b17f4dee21d7c1337ff41436cd0e5a8d01e4030dcd3d49839e59996fbbf1d39bd205343a424f2395b4d3eacdeb9ed3235d8df0dd00a2573260af63db3116a7c65d1dc69684a05caebff34e3d2cba9d4869a953a7b1fce10ebd008cba021008ac3187bba846abd7b39a1b97c9c07d8080549e313dd58b716022de3c1920329\nA = -8e1141dcebae61d5c4d81697f001d792ee2e847c589816f923f0ed42bb4de0d8f911b8ca47ffe77f80b9da6896a9b42f0030a3276218868bbe1a3fa64fb0a577704339af5dd82e66780da6f58900da3f1d75ebfcc302f78ed66ea3c7a737898a29b1f2500686b43bae1e6571addd2842cdce4d\n\nSquare = b09f5e9472cbb75070a67d025957fd5ac3be89c41e4acbcd5f75780ca459562461082c3f19c5a4a416a668b0a55f31f74cf2ec44555ddc43fde64da0ba781adfac4520dd0f78d04d9d2fd33d8b49c72663a6bc845015523e2e4e7ccc69e5b748b8b891e4089420bf0a3f6032602824c7230b5ff95f85a688dcdcfc890af3384710a9fe32ecf9ad7c6cc5761f13079b19d7b2906c7e63c14b64fc88c6f4bd7c41c0356c777d35c3626d49db8cb2d1e89ce682c7fccc3a459b08c20c4e5fc3a8eced9b37d01bed5af6ce9baff0d2b435e6e62871fcb20cf9ec10d1897a5c76e73a441e07fbcc2d9f4e4\nA = 3528e6581de547de385c93ccf1086a17614f23356a918b25bc6d73656a2302b318963bb679c9a93357f4a4f614e74f2e5e88e9c8aed8a6fdd8434630f664ed15ebb6095cbff1593f188a12f4dd6087a85b202f6c24df68ac3b137406c88c5098faf47d1eeec0743b35baaec7dae29b5a44eb09daa\n\nSquare = 5d5dc40783411475a4aac7c1a1eb760f76fcc6ec68dfebb754251cf499870654cd309422935ec841e6be4f5a15078356235c2b8cbe1ae755cd6d814e811072bdb76156b83c7d2064a202ff90af1e0f88f5889e5729a3cffa9faf33c463b74d0ad21fbb4473d4d3ebfa8a52e9c209ded5ce5131b12b69747c365146fa17ee5810e0dbab992f9da28b6c323062484d62472232721d608cdb9b5a341a677e2d7a6e5a983247d9a4001e16687b489b10b18bbf205f982b7ceee27cc3e9c6641827ab7952373f15d36e5f177b82d7eebb3f5054e12cec82c5f520a2675afdec6cbf6235d358c2fe73344002e400\nA = -9a9a19fcdf11bba84b0395088c5d187d84d69b68b77bc6418f63c88bbd8dbbccfe02917d814f9e2241fa0709817a0c85bd554fe887babae7439d96248514c12d71587c906247b3e965e954cdd57f1e51f1979f73c3237509863169efdf281c1359488daad3d9eb990a50ecf4d3fd25d4820077832a0\n\nSquare = a4d69ed4c4c9c08116ec5cc49ad458f0fb2ca00f356aeb148f18037bc49621e14820f325af39f3954bddc9cf01de7ba1e443088545883a94c04ff41a7ed5f65676109c5b711b4115775489667e00aa1b77f6dee5ac5c1789bc71c9fc797abf41c7c5ae3e2c1cf82d5b49b6c0da25190dfa9360b99b2f63444d21ec6114038b8284bf598eed24a2ab2b9802d6edd5b0fdb52f60621a87a14612844ffc71ca98180ff0915cf75f47432f73d28dfd7a932a125095655f07f50722b1673df2cc4f7566a1c6035792ff3f02356b9b9d25e905121df768dc6a1884cf5483eeb813c1c009fe4ed043febd61800ba978a40\nA = -335b12e40bfe0b847ed6ec143490df33d2e64ef4363869cb78dec008cb5cd66ea671dba964a53e48267da288ef4040e06371e1209691b81df02f2c86a79cac85fdcbb6732a1e5309fbbdbcd899fdfed18518d47258c9e63ff7f116ef4a8f5c4867aedd907ccc7d222cf8087afebc108f2a0f197c717198\n\nSquare = 74dcdacc1a4f02a99e3642f54f9d917b117d2ae8d9c392f8b6dee53fac66ebe1680c8e8cc29f5330e0eed3f63d10980060799bc37b34c93dd7b384d4ba30a5b5d42a145acc412ae838d7b9b7137637546d1118f7cf3eadf88b785f0aa01da8638f027c56faa16aba8591b64b45dae6138c9a40309b2ad29c5029a867465f9c6de8fbc5fc4b0442c8a8946272667c7622454ed6f2a236103bed7697dba20db84b5154ff3fbc6b4b9eb67ee43bcaae741d87ee2093ee67defb8eebc4a4a22d97a4e2aa7d4c31a1c88abf4a440ba4e2a5e40c4d903ba5ee4d80b4e8dffb8864bcb9806e015c1ce16490068df87282393111\nA = acf70350e554732c1972903cce269b215e985ecb8d6eeaa67fd5398d0a1b57c0db63368c0f8c2288c3a0466e2b3db081106b90920c46462faf00b5bd654f7140a689b78ef656a26b82af8dd1988f166ea04e9aa777a094d892bc7da4bc7bcf0618526f496cddea6d67df7bb0de9e99a35a0b1b210ff07497\n\nSquare = 9668b9e40a8bdde3c93943a918ca71fa0009cb05a1f592b2bb2c6c6172b2950719bfd80cddaf45d044cbb6aa99715046088f40ec6812945885679231c07f4200023548ead086b834abd8c8f8294db28b203329553242fd2f778ef5cc5ed0b48c7356d8c2d782a01809ccdb6b012896617f11d963300e7bd38ff512829514d94343476818ddf9d712bc70cffe7f767a9fc75a5630e6250ed45e6831b4660eb49d47dd1b8b6a0dddf3fb3ff0e12834337f145f741f70a2aa43769af50f099e004269ac47fab79e060800dc74da88141adbc46c15c7330931e3a2bed9b958f78b30214f81a64d121f96fbcebf7569fec0cdc6b11\nA = 310e7a40667d9d5dc29744b123cdf6a663a1b995f62fa9d4d853cbae0dd23669f4778bb2040317ebf6a06ac6299b21067aece5c5c1afbe6e789d656745ad66464991cada0eb237c6ffe991cac4670bfc90eed5f8c75073f4f846ea244bca0e9502ff56f8e9bc9b6caf275aaef38e26566fef35329ca45392069\n\nSquare = 49e677c8b052b7db97542948542449af47e14248021f8d3d3f92b9af41c803072f71050f16dd848aebb270affc47e85427a7c73f227f0d63f140d0d293157af0d972eb5b38de494fbc78ad3a4c3d1ab40197bc4427752b6102d1ced6d6cbc9d7caa0d1bcc57e708535822180055ecc9d9667e0590274b778480a3720823e931ff6daef358b1a1a9092f1f05fbb5b10ad5707a124e8be63bc696f083eb74e5b4f0e3110de8f297ecd30dfd2bcb010dcad4e387520d3d00365fc51c2a3dfe064b1ac77a9295f66beffbe5dd4333e5cd823b0f36b0b94d66507b1d9381060980f62f38a62e38e5a75203233bb8d64089bfd100f3205f1\nA = 898b5f3655de74cec3b0fde2ab03fd18cdbcfc3eeea48ba39317d26917130c2b78e05237cb0454ece268f091cab699fbcd51ce341b53d6ec0cda5d0d5388bac25c6517214a39d03450ef8502e1675bfe8e57bb6086f10ce4cf8ce65eadc865b5bd8a00dc26394f3adb2ace609149e3582cf44246184b2adc0ffd9\n\nSquare = ad00f10fed55175159b2409dc80899f9113ba7c8099d0402ec0f520ab4aeeb46d36369494a4e6fa23675adb38148fd2efa082df5094c0acfb77a9ab6ba7a299298d69b04b58011c35325f46b765e580b5c05eca721904f1fcc355dbe39faa92af5c9a6dbc4ab80e62b815b45983d9506ebd52b9efa7a6b9da352d1e4fd6ffa81d3b4596a0c14fb825297da361461ff2240e4378340d2ae529932d78f3d9f6b3c6d65d717e66122e5f590c50ce0a5d81ad8e0f24e104c0913cd8d0eb2de4c8cf62a7535bab5502df3fba08bb4dfe73d89c8b00edaa7d5f3274be9959e7ab6b6dde54f2491728a1dc11fa8e1c6a95e67eb7617e9b7471ee40\nA = -349cc2a5658fdbe9ba5c350d3b25baa38b1ede01926694bd550d36883e53d8758e8f1ebe83e2f4560605510413a7d880929e2d9cbc2730b1736dc2689cf7bbcdc68a342b6398e547a9bd67cabe298796d76b98ed4c1dd9c22e36145892e8fcf2258529aed24252a70b6ca8fd2aad8a84becf7e1bf98b1e9bb024b8a8\n\nSquare = daa3835d3189ec9ade592e6076e76d441838077a9431273bdec02379b3a6ac38aecbbd57c3755ea58ddef8105ac28f2ecc8598ec0c4bfc9c1c80222fffc776722eb0621cdd8a0d55f08767fc2922282a76e529d81e4d6e21a2542b8c9a403709ed1132e3b52786b81e684591438fdddb5df2f0b72e6b39cd2db6c0cc55c759c2dc1b6ccc20a5cfd10c6fd345fc766035c7478570d4ac534db3fdb718e2bdad3d096b137bfc09a562043800957e2afe4fdcfe292881f6189edfce52370c0438c2822ce3b14d73b3eff32f7e5ca97e989326b4e3a8fa35544193f8590bbb0ddb1f914894ab87998090771a0be1fd23917cd792be86ea0b98e6eb24\nA = -ec953f1b7ba7d561edaaa23076987daf86f50e9a66c36f0993290549a9006dd9d424885c0fa77295cfe34fc81c5edce9e2371b3039ea18d8f998d1956196284e6d81eb1c62ecaa8cf3fcaca28ca7e64342803c8dc3c139080bdd4a1ff30d7288b085a579d9e90903bd363b48f2072bb6fbfbd9ba2cab30a8a63784d246\n\nSquare = b33f4f3ae453058f4e865ec78f0844bab7af66a97dc2f265ca73ae2232777474bfdda39e10652d7386c16f145272192af728893c3d8a8e92c60d77722b924c30269ff5a399a2449ce15e50320c528c22655ad06227ac4efe5a993179ec61c2fc9115f89d75b53961fd16f7797657f6fbf55662b019608a1d30f64a2c0838e0018b7526921fdd34fd462bfcb2462b7065e2bc7abd57d71371e45dfd8fcfcc00a71f7e45430820747c9a060b72e4f6d2919cbffd00beb0c31a2bdc32afe2cc540b38dd04a2b73ae5ba481a6e535f37a757bbd6aaa972986213afadfa47cb7a15a6f1d443f93cb0ed824a10b4b7d82cae524a096b65ccb39be3c37c07f59\nA = 358da59ef65f62f633675764e292e5a68879df24a4727eca1fc4d232b3a6d936976c92eeb11456b5e8c11319838c145c6529d2f3acc828e55b8274bfe9afb5db241b102715f8e8164e454ef39f13ff1b37cf367a5a66c4f743c750896b7c3c29026e448bb36c6c06b0d9a3d048086ef0c3cd922a02e794223f388b5d646db\n\nSquare = cd4246489f6f221f920acbd8bdcdd17f47d2b77268f72254de4190685c123e8c5eab8517fded1852e8316c9e549d3fa355142d91b2921a3c94aafd8862cd2235429340da38a2af131b8d002f17", + "662354f5805f6a7af7afb6dbd2f641036600614cea42bd8b24d86a5109eed29c0865a5f30c5291b1d1ef3223f9b9826dee773d98ce972da92daa19e843f84ca5f1cd77925a3c1117242ab0fb509b94a83f8de4fc8d21f856f37a4d025b3024bd0dbb6d8acfda4ab2993fd6eb7a7448d4f66ec725d37f0eb14eb242c0ff3f0c4572ba6b98a4ce905fe1b7ca3daca56c225171428c56af938fb66b37e99e54139157bbf41f536989ef813af738837afcd62290\nA = -e53ad05c88568f09f616797f0b7f2756fb543d691ec2a5b645c1e5892a247302826419a35b1348cfd2c1c569c23c31b4c46d6c57d4a488c29ab5beb77904d4adfcd0a01ea0a26bb0cc8790441cc2c8c900f030d7315b4319f1a3cf5685a140e03abe6b94730ad79e8de1f4a0cded86a3d6cfe2db267fa7dc9b2bb32872a90cc\n\nSquare = eea8028b26e0df090504d54da714a6f5f2695202e53cff479c78aedd47a8dc676243ec586740fde53b3eca9ca02b91031ce766242184109503fbe25b1b6d318e3cd5970fabd16dfa22984dd2e9f1e0f14c189170fc69c031d66663703e6235a942d51a4545bd7b0769d01d302ce2b00b83f01568a1e378f61fd0ca6201b0490330580cd9de85719e174a71915d7efbf65cd73d8f4e66f27e0dd3144d58ec09ed0f7ed7d1238ee596922807100fb7a11127944ddcdec6a9ca3bbf6df7301e354f3f049bfb7c275b43c3d8cda5907a932fba507c9145ea3166081c1b48fcc710ee32cd931f936c796b14f8a78a592e67753a7c9e428a01719c8ba82652f3a89fae110\nA = -3dcb44be1e54c5a5d7db48055ca9afa1ebe2ae648aa6e16ac497502a7deee09ffa124720fad0ab163ce8b3ea6a90f110ea52b67dbc424d0cf1e8c9726dfd9e45bebcefaa5cd5706edeed27896525f31c6bbea3d67ee97badefabf3e2532470b66e3ae3100f66ddf50cf02fc3a8e3f44c304251d3b6a7ca3a6e4bd5d16a41bd97a4\n\nSquare = 0\nA = 0\n\nSquare = 1\nA = 1\n\n# See https://github.com/openssl/openssl/commit/e9e726506cd2a3fd9c0f12daf8cc1fe934c7dddb\n# Test vectors from commit message.\n\nSquare = 15c72e32605a3061d11b10123c1874836df96999bd0c22bad3e7d4374724a82f912c5e616a187efe8f7c47fcf6945fe575be8e3d97ed17d47950b4653cb32899\nA = 4aaac91962056c84fba7334e1a6be678022181bafd3aa878899b2346ee210f45\n\nSquare = 48a699fe82f8b62bd2ed18878133575be8e3d97ed17d47950b4653cb32899\nA = 22181bafd3aa878899b2346ee210f45\n\nSquare = 15c72e32272c4471392debf018c679c8b85496496bf8254cd0204f36611e2be10cdb3db8f3c081d8c94ba0e1bacc5061191b83d47ff929f65be0aebfc13ae68d3eea7a7fdf2f575842f7ec656cab3cb56a28095be34756f264f24687bf37de062822309cd1d292f96fa698c972372f09771e97d3a868cda0dc421e8a00000001\nA = 4aaac9190000000062056c8400000000fba7334e000000001a6be67800000000022181ba00000000fd3aa87800000000899b234635dad283ee210f4500000001\n\n\n# Product tests.\n#\n# These test vectors satisfy A * B = Product.\n\nProduct = 5befab3320f8f90542f3120235abd926aac3805a19e343f690\nA = b057af553afb120db6b7764f8\nB = 857734c4c27a1d17f7cf59dee\n\nProduct = -ab1ce167f4b2945c55ae3f87df50ad07d4be87cf9f8aa07b0c\nA = ae7a6a87ea8981a567d0b3ecc\nB = -fb0fed5f8c737bcacef4d6cb1\n\nProduct = -c2606cd48e6b075c8da79eb4668e7157f1f175c2860fd4c475\nA = -c28dc31984d4583e9d45424c3\nB = ffc4581a5c3f885cf42767e67\n\nProduct = aa6805b5408aff7f914472756da07830dcad902834dbdd6944\nA = -ffa07ff9f503511954e5dd3f9\nB = -aaa7af472ad8957763f5a7c64\n\nProduct = 58ca2569173389df29b5ce4b784086055dee821a7243db7210\nA = af417d936f4690008811a1ae8\nB = 81b26b80b43aa65aa55ded52a\n\nProduct = -a043d31dfce8bd01724d31c863d0a64f1bf013509d77737c42\nA = fb5fae5edefb6997d44a1ecd6\nB = -a336e50c6f7845a1686cc88a3\n\nProduct = -b5d6a45ffce851b201239d938ba551bab7dcb59fc11fc35fce\nA = -f918faa58bb57a2ffb8b01f05\nB = bae08c3006fade695029a1df6\n\nProduct = 6f2fde7d1a18625d727c6345ed85e597d546d9228bf7f0564a\nA = -8d108d7a16f0696d4ceb24445\nB = -c9c764cae465207097ef8d2c2\n\nProduct = 93808b1140841dc9735cd61c6f855ddbbb83066689b0d7e1a0\nA = b386d08daf3fa2154e9c768d6\nB = d2557dceb2d02d04d9c578670\n\nProduct = -ad04212ca8cadb1f7861c5130ba3a747046a2a7e4a0c72b69a\nA = e4e5f7d1311e0c5f2e404d55b\nB = -c18057a328d8c7375afdfd4ee\n\nProduct = -685e75c232f2b4a0e455fe5ee8aea52f292ad8b8178320e692\nA = -a683312f132b2320632e74ef6\nB = a0758f12791453b4af354730b\n\nProduct = 6f588c53185c503dc5b0dc3002d3817ca2e7eb2370b3e9a647\nA = -d70c9b93170261091f0c53f27\nB = -848c86c51a186ac4c9080d3e1\n\nProduct = 5e3bc5a04e054a9a244bf7c86cae215072fdb70e9199989427\nA = 898b64ef09d7cf63966e1a3b5\nB = af638b12f26aa5d12e97439eb\n\nProduct = -8d8372b235b16108285203c03a8aef6fdd3c0e1a9fd31d4f68\nA = f6003dc83818c14fbe36c9998\nB = -9343f6cbcc81fa4c9399dce5f\n\nProduct = -5ee6509abeeb7af7fc5caef40d1822ad3150c8d74f522dc7c8\nA = -875ff6f56ca72cbdf614bb9ca\nB = b375a68a21dfb1f159c22fa14\n\nProduct = ada25be404a17385af5a330da799e5909da81bfa0715baa6f4\nA = -c9b8df392e76abc3eb7d5ce04\nB = -dc5ab818c70594dd917b4243d\n\nProduct = bb24422ee4656ddfcd50ec38201b15baf679d3b75e5cb878ca\nA = f8e12cf4defe388b78510f687\nB = c07ee817b4ae95c2915b88966\n\nProduct = -93da296ba164c7220a17330647aef0980c94eddd2cfa2a3b2d\nA = bc5dc74ddf7a1363d1c2b1f25\nB = -c8f069bad7f93cbfe6df51169\n\nProduct = -6b2e1d132c4e0b0dc9b7e7de7d424fda5180480cb5ff47c755\nA = -a8048acb66a8bb88df39266e7\nB = a34e0b265d71435ae8c92a463\n\nProduct = 6ccb2cd93783576a8602ae43f41c786008b6623a4cca0a010a\nA = -b071f1f54790c951c1dd2a1cf\nB = -9dd89bb4d9b546207e282e2d6\n\nProduct = 5c742ba47d0d64bd97509927ce957deedb855766cc24c60016\nA = b44f3f252c368096fa62747f2\nB = 83439b97dbac579fa4f7b7d23\n\nProduct = -7347ba65691c913286c2fb55e45b177f031c1d86ae0e9f654f\nA = 937cf0643ffa53cdea24d642f\nB = -c81881f78243dd5737a7d28e1\n\nProduct = -9bc0649a703674e59f83ff9b8a560e5cbf51f65ca310f80f95\nA = -b536f8d9769be6f62da941ae5\nB = dc0746fb101881ae0cacde6f1\n\nProduct = bf4992fc3a124de350f9fb90ea825cf663b1fa051282ef22e2\nA = -ff7eacc7de1bb01d668c693aa\nB = -bfaa6627f9fc7ba68ae41bb2d\n\nProduct = 7c8992d34cc0b63f1c953f68d4e12a99d3f3a34d16bd76caa9\nA = 9e0d5a850d078890a983c0ec9\nB = c9b72c118b3e1f1023a696ce1\n\nProduct = -a75840c95082b9a0ae0d6e0a4eb5e09288e4e2a66e9697d9cd\nA = b2b042a21045a74ef1a5091d9\nB = -efbf8b120b384e869692a1b15\n\nProduct = -a510b333bdb4ed7479c142e8fbe2b12f7671a42acbe16c0998\nA = -e7fd5e0bb5496b9d876c27f65\nB = b6262653b2be44501af1d85b8\n\nProduct = a1c1e90afc4684754155526e307fc6ed798746f347bae2c880\nA = -b84674832b26ded0a690a8ff0\nB = -e0b7bdf2fd05a038ed3640b78\n\nProduct = 5588e0c33bffbefcc5695ca0615abd383343f21a8a0d22b222\nA = 80cad81ad9a66ab6a1c2e5669\nB = aa0453a77c8af1584f54750d2\n\nProduct = -6460c2fcd6cf3304ab163ea883ac48e2031cd10f2e9014c0ab\nA = c49ad3d7c8848d4fbf913b10b\nB = -82b3dedbe3cc7cd532ad632e1\n\nProduct = -a18717330b711669e85abde8c4dce426529aa621ba3da2a477\nA = -cab4a9c0a331a5a5e826dda1f\nB = cbfee5041c13075dfe3399aa9\n\nProduct = 8ab6282ee892b53c083d319a9dcab48af97a1ac8493c0bfcad\nA = -f7d13e47f9aaac8c25f9bf75b\nB = -8f4aa95231c1e2336aa092297\n\nProduct = 8f2d1c23c78777ed371f13155445ca3c88cbc0a9b299bdf9d3\nA = 9d8248d00defce1ad081337c3\nB = e8b479295ecd9cef7301f24b1\n\nProduct = -86d5e0c5b581fe59819730b4b71e33d1f85f9ab504c7dbe2d6\nA = b21b45e88acff48562a19729a\nB = -c1cdfebccc763beeac394b997\n\nProduct = -484ca05aefa113bdfcb1bc623f730c9f9555b462a8ab4c9606\nA = -8c12b406c02c4417163c0956b\nB = 8422b15c80c1c087b17eedd92\n\nProduct = 614c3c91f60050c785fd229a3ad74674577a90cacb654e0a5c\nA = -93d45bce155a23a397506d96a\nB = -a87e339c3fd5aebede5fb1b36\n\nProduct = 9683285f194a7e4feeab196a36bdfc4f828035fd184b9cc692\nA = f196d8fe760fdcae7eb60e2f7\nB = 9f7d88a2163ad818bf3a6377e\n\nProduct = -988a64599c19cc64f3cadc1a83fea6550185f6cc3ab82af822\nA = d0584b2a306671e4d2c9d0c7b\nB = -bb6e7559df199c68d6df3a3c6\n\nProduct = -68456814cb0edd951196d04c853172afdd5787a5bd69a57876\nA = -cefce1b0a1fb22862418bb597\nB = 80f614139947aea5e76cd55fa\n\nProduct = b4b1cbf5d6566e7a57aee0cc5c9c8ec4ad885e8766aa7662a4\nA = -d68ed1bea046c6cad057e21db\nB = -d7988b9be54f6e332d019032c\n\nProduct = 6b09212675ff5257a1384371e17b37dcc268bbb141577902e4\nA = a8208053adc20a609d5d01404\nB = a2fa927c5458c4fe662d7a3b9\n\nProduct = -8361bc26f9bcf55f677e047d822d3004027da0d0455b244d10\nA = e82b6410b29020c2d6810a977\nB = -90ddfe0e7f0d6b9cdc0815f70\n\nProduct = -f1b6da00923fd513a83e32040a515649fbd362f69ebc016d9f\nA = -f9b697d9ec774a8d1ee5ea905\nB = f7ccb46a8869cb028492bed53\n\nProduct = d06206963f2e150bacdb32c823c3a47f013d5a267c3c0d0c88\nA = -ea8e63afa99c719897ad7f2ab\nB = -e36f11f55b6148d1b4f46e598\n\nProduct = af774a5eae6084df5ca499ef005642730adabf6a4f9533e2fd\nA = e4c7af7eea3ec9cc2443b7319\nB = c457bc264c8461789931baf85\n\nProduct = -76350f428bfbb95e6c253ec0f457aa84cebe8c7cb1af2a2120\nA = 8fd1ff97465775d44dee58ae0\nB = -d268a7d328f44baf80e35119f\n\nProduct = -787ae3f114f9a8dd4d249d5d3f3b0897b02564b9469416cefe\nA = -bc0b398bd0ec045b0cf147b7e\nB = a4050955c234e473257d0c641\n\nProduct = 9d6320b3d4aabac097a079b9", + "bd2aca7f1898bcab0f23409fd0\nA = -9d7a4ebac630cc0662b816fb5\nB = -ffda517d3eb3214986b04e290\n\nProduct = 80bab8bd800ac8c9dc3bb57dca306f10af6fd88c5d8314833c\nA = 834bc50140d6c6ab938dc58b6\nB = fafee47793cbc533b3c66af3a\n\nProduct = -b08920f5922226b1dec87151ae087d8a7e5c1aea8c9be148b6\nA = bfd5b1ad323c79428cb2db36a\nB = -eb956a10edebdd658e6810fcf\n\nProduct = -6d428e08e8350bb4b0fae3b662c82df2aef7beadaa17430dbb\nA = -a57da276998c548101f514e9f\nB = a9040c1909712e1149d295765\n\nProduct = a57da276998c548101f514e9f\nA = -a57da276998c548101f514e9f\nB = -1\n\nProduct = 14afb44ed3318a90203ea29d3e\nA = a57da276998c548101f514e9f\nB = 2\n\nProduct = -295f689da6631520407d453a7c\nA = a57da276998c548101f514e9f\nB = -4\n\nProduct = -867614005cc204a8d19720fe13\nA = -a57da276998c548101f514e9f\nB = d\n\nProduct = 12bf3b676f64e5929d38c35e803\nA = -a57da276998c548101f514e9f\nB = -1d\n\nProduct = 24d8f92c68303ed0b96f91a8167\nA = a57da276998c548101f514e9f\nB = 39\n\nProduct = -49b1f258d0607da172df23502ce\nA = a57da276998c548101f514e9f\nB = -72\n\nProduct = -6fd5e6ca25c3d51b2e529f22173\nA = -a57da276998c548101f514e9f\nB = ad\n\nProduct = 1276d4705b81b82da4c7e82559d7\nA = -a57da276998c548101f514e9f\nB = -1c9\n\nProduct = 1ddb9abfc5d4017f068a67b5f4fd\nA = a57da276998c548101f514e9f\nB = 2e3\n\nProduct = -3a8b41c914b1b4a4e341433601f7\nA = a57da276998c548101f514e9f\nB = -5a9\n\nProduct = -97c0f4ba414d6e7d4c8b7ced84d4\nA = -a57da276998c548101f514e9f\nB = eac\n\nProduct = 1198739e0c23639c176d46d13f7c8\nA = -a57da276998c548101f514e9f\nB = -1b38\n\nProduct = 159150954ee0dedf541e4dbac0ec3\nA = a57da276998c548101f514e9f\nB = 215d\n\nProduct = -441d4bc44c86f02ff12c3d91a1562\nA = a57da276998c548101f514e9f\nB = -695e\n\nProduct = -64726b76005ebee27592237ba5dde\nA = -a57da276998c548101f514e9f\nB = 9b62\n\nProduct = bbe4ec7cf7c5bbd198e0ea86bb658\nA = -a57da276998c548101f514e9f\nB = -122a8\n\nProduct = 21f717d05681fd2eb1796776a69ef7\nA = a57da276998c548101f514e9f\nB = 348a9\n\nProduct = -396ac788a1748bc6955f99be4d2c64\nA = a57da276998c548101f514e9f\nB = -58d1c\n\nProduct = -54a213eb083aed1a04f3d1b2da62e7\nA = -a57da276998c548101f514e9f\nB = 82eb9\n\nProduct = 1366fb9c20fb14b8b9a9be4b3e3dde1\nA = -a57da276998c548101f514e9f\nB = -1e037f\n\nProduct = 238d65fd26da4733e5d93ab2485d40b\nA = a57da276998c548101f514e9f\nB = 36ff15\n\nProduct = -38272a99be154d531e922be405aee9a\nA = a57da276998c548101f514e9f\nB = -56dd26\n\nProduct = -64651b62b6a454c08951632c7f2c398\nA = -a57da276998c548101f514e9f\nB = 9b4d68\n\nProduct = fb272e3597b816144f8b945ae6130e0\nA = -a57da276998c548101f514e9f\nB = -1848320\n\nProduct = 280d9f5ed7243712ecb9a7c6358bcb8b\nA = a57da276998c548101f514e9f\nB = 3df5795\n\nProduct = -2fbb6bb8e1ba78cefc47fbbc20e188ee\nA = a57da276998c548101f514e9f\nB = -49d6652\n\nProduct = -57f29c13691ffa1642d2860dab9d288e\nA = -a57da276998c548101f514e9f\nB = 880c2b2\n\nProduct = 139c19d7668e6aabf2d7206cb0723ed34\nA = -a57da276998c548101f514e9f\nB = -1e55aa4c\n\nProduct = 2950ce04bf0cf836d4fe94b88fb757d0a\nA = a57da276998c548101f514e9f\nB = 3fe968b6\n\nProduct = -5175239488dad05a58414251496d2a06c\nA = a57da276998c548101f514e9f\nB = -7e020414\n\nProduct = -945ff0ed38bc6020cf679cbd3e0758c6d\nA = -a57da276998c548101f514e9f\nB = e585e573\n\nProduct = 11c69ae98f6b27e95477986f796bc67c8c\nA = -a57da276998c548101f514e9f\nB = -1b7f653f4\n\nProduct = 209afe75e8fb5ac76d13c06b545f5d4d73\nA = a57da276998c548101f514e9f\nB = 3270154ad\n\nProduct = -386d64b215e41506514f4988ed237e4da2\nA = a57da276998c548101f514e9f\nB = -5749c891e\n\nProduct = -6c13cccdb1d140d0babd52707ea72fa278\nA = -a57da276998c548101f514e9f\nB = a72fb6288\n\nProduct = 136228a8a45540372b9b3cd7f82021f6546\nA = -a57da276998c548101f514e9f\nB = -1dfc08a2fa\n\nProduct = 1f0ad3babf9d132eaa08cf5cdb8f19dbf01\nA = a57da276998c548101f514e9f\nB = 30050f2e5f\n\nProduct = -50d615ce183258e95af77319b766fac81e2\nA = a57da276998c548101f514e9f\nB = -7d0bf92cde\n\nProduct = -817d358293b86a56a4e881e50257c549471\nA = -a57da276998c548101f514e9f\nB = c84efb12ef\n\nProduct = f09b9e80be251de474d726b16e25a6865fc\nA = -a57da276998c548101f514e9f\nB = -1743322a484\n\nProduct = 22996cb0f9c60e35dce49f3825f8a479db26\nA = a57da276998c548101f514e9f\nB = 3585acec11a\n\nProduct = -2b307a37c91791a61c0691858f5f783e4678\nA = a57da276998c548101f514e9f\nB = -42cf6be3e88\n\nProduct = -8826698fcba6c30d755fc523de1cc25301ae\nA = -a57da276998c548101f514e9f\nB = d29cc8af592\n\nProduct = ae37fc99fd419809310782714530d7428d77\nA = -a57da276998c548101f514e9f\nB = -10d8059d4a29\n\nProduct = 1d544a20f9bc7d95ab67d1f65743979f23bba\nA = a57da276998c548101f514e9f\nB = 2d5eadef1c06\n\nProduct = -367897184e9929a0294d320f10278889fbeb7\nA = a57da276998c548101f514e9f\nB = -54431582d0e9\n\nProduct = -943a509076a00060a2e7fa1cddb7468d734a1\nA = -a57da276998c548101f514e9f\nB = e54bb102f4bf\n\nProduct = fcce6e42879af5ad13545c0bcaab85b690cea\nA = -a57da276998c548101f514e9f\nB = -18711db522cd6\n\nProduct = 258c49f86d0cbb14ae9edbd3456be8cede2022\nA = a57da276998c548101f514e9f\nB = 3a1562c7c269e\n\nProduct = -4a8bbce59ad7daa51136d557f7fa16e9a2faad\nA = a57da276998c548101f514e9f\nB = -7350e780b0f33\n\nProduct = -82f53ec9333275d5cc271876a7db936db49280\nA = -a57da276998c548101f514e9f\nB = ca94ad312dd80\n\nProduct = 11daee4fcc713db5b2806e47fa5dff3b5b770eb\nA = -a57da276998c548101f514e9f\nB = -1b9ed6758f9635\n\nProduct = 17038cac4f0c94dc24985ea108ae6682e175752\nA = a57da276998c548101f514e9f\nB = 2399b8a9b1116e\n\nProduct = -37e5f14394bf347a3ed061769fe8e6424af4348\nA = a57da276998c548101f514e9f\nB = -567840a7569fb8\n\nProduct = -9253d4a32a88d8f725984514d969012ead7cc9a\nA = -a57da276998c548101f514e9f\nB = e25b246f733f26\n\nProduct = ace3648371c16a931d29004e79f5b9678391da5\nA = -a57da276998c548101f514e9f\nB = -10b717b27b6a13b\n\nProduct = 1faa5b45d04c143c339b09d3aad94d39b94ef960\nA = a57da276998c548101f514e9f\nB = 30fbd672e106aa0\n\nProduct = -3fdfe246d27aae0d08d63b2bc501461d2bff3b8d\nA = a57da276998c548101f514e9f\nB = -62cef5f078a8253\n\nProduct = -5b792bfaeff04ee3d948cb343a249d49eb344f57\nA = -a57da276998c548101f514e9f\nB = 8d805ac65649c49\n\nProduct = c5f824406161eec321da5a58e3e00d393b55abe9\nA = -a57da276998c548101f514e9f\nB = -1323dd41d2e1e077\n\nProduct = 2226dec8a57be8e84e42559007e2d101ccbe67f8d\nA = a57da276998c548101f514e9f\nB = 34d47842b5d0be53\n\nProduct = -340f50f812c7420b502000940788a700f6769788a\nA = a57da276998c548101f514e9f\nB = -508836d8e1193d36\n\nProduct = -a00f1d96e19c590479625c5329a87774b5964cc78\nA = -a57da276998c548101f514e9f\nB = f798fc858657f888\n\nProduct = cb94f830cba8997331912a6a31c34f1bef826d121\nA = -a57da276998c548101f514e9f\nB = -13aec7a5c52a0883f\n\nProduct = 16b45140b048d6dc0b9fc811df7ce7dd88357fff04\nA = a57da276998c548101f514e9f\nB = 231f27f3e347bd67c\n\nProduct = -2aa94179351b4e87de5849ab619d94f47450640199\nA = a57da276998c548101f514e9f\nB = -41fe3ec2189599cc7\n\nProduct = -5489401d3da93158d4284e557d74016c0a7cfd935a\nA = -a57da276998c548101f514e9f\nB = 82c5281df41bfc066\n\nProduct = ae04d5b212ecfc9a6d7df07794d565df52991fb70e\nA = -a57da276998c548101f514e9f\nB = -10d3139229f5d02432\n\nProduct = 27821bc811f45d63089790b41d307be978d4b19564c\nA = a57da276998c548101f514e9f\nB = 3d1da85cc012b3e234\n\nProduct = -3de3c9e9d7fa3020a578706339314890dccf63096c2\nA = a57da276998c548101f514e9f\nB = -5fbcfb28bfc9044bfe\n\nProduct = -627dcb299a6720044abcf11469bdfd3f951edbb5bf7\nA = -a57da276998c548101f514e9f\nB = 985b930517b78e6ba9\n\nProduct = cc0622441497a37fddf1856d5e2c99df52b99ea4573\nA = -a57da276998c548101f514e9f\nB = -13b9b88948fb7e95cad\n\nProduct = 1a5168e1a492210591ad1ed660adde9110390e4caf32\nA = a57da276998c548101f514e9f\nB = 28b631c6e04b6ab0d8e\n\nProduct = -4d8ec27b7460ce616421b9f5cae708c2ac241daa59b4\nA = a57da276998c548101f514e9f\nB = -77f99bdf1eb09da6dcc\n\nProduct = -55afd796db7bce822a00073fc8926d3bd0c79772f036\nA = -a57da276998c548101f514e9f\nB = 848cdd6212b9bb3620a\n\nProduct = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34\nA = -a57da276998c548101f514e9f\nB = -154c39567bd8be5f6b4c\n\nProduct = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c\nA = a57da276998c548101f514e9f\nB = 37c6e7ee89cf87674814\n\nProduct = -39002ecfd6d96661b336157ccef6536756ad2e9219be3\nA = a57da276998c548101f514e9f\nB = -582cdab09915a652203d\n\nProduct = -695f49fc891d53f396f0593efae3973082b76d4f9e944\nA = -a57da276998c548101f514e9f\nB = a30074dbce2246af043c\n\nProduct = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7\nA = -a57da276998c548101f514e9f\nB = -1224195afc7b394ae8cc9\n\nProduct = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af\nA = a57da276", + "998c548101f514e9f\nB = 26c6701c39334169e7bf1\n\nProduct = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100\nA = a57da276998c548101f514e9f\nB = -5436e84b4a29858a68f00\n\nProduct = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871\nA = -a57da276998c548101f514e9f\nB = c56e0f44fc63bca242eef\n\nProduct = da7fe3367ce640fa5941c033ac1874312f10ba5950da75\nA = -a57da276998c548101f514e9f\nB = -15200043166ff309f0426b\n\nProduct = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57\nA = a57da276998c548101f514e9f\nB = 25d057879db26fa29a5e49\n\nProduct = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857\nA = a57da276998c548101f514e9f\nB = -5e46be70de21949df67349\n\nProduct = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63\nA = -a57da276998c548101f514e9f\nB = 9238670897685a6c9cbdbd\n\nProduct = f623344788efb857db55c924e95a437effa4dc8bb2bcd24\nA = -a57da276998c548101f514e9f\nB = -17cc0ec84c228225a7cf45c\n\nProduct = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72\nA = a57da276998c548101f514e9f\nB = 20f9f925b3ed307edbb154e\n\nProduct = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f\nA = a57da276998c548101f514e9f\nB = -6c5cbfd29f3dae1dce99221\n\nProduct = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43\nA = -a57da276998c548101f514e9f\nB = 9136aa79080defd1bcf90dd\n\nProduct = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd\nA = -a57da276998c548101f514e9f\nB = -1d03b512470dc3052779f3e3\n\nProduct = 28388a244214abf046488a8d95308d95f021eae4b994a5a52\nA = a57da276998c548101f514e9f\nB = 3e37dce784274962ff862e6e\n\nProduct = -4da476e76119deef291c0f56934a912a0877278a19a561ee0\nA = a57da276998c548101f514e9f\nB = -781b2f2dc40094a7f8fed520\n\nProduct = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82\nA = -a57da276998c548101f514e9f\nB = 87772a4fb582acafd3e4ef3e\n\nProduct = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa\nA = -a57da276998c548101f514e9f\nB = -1563841bf7851ff158a395716\n\nProduct = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752\nA = a57da276998c548101f514e9f\nB = 3918c30b5568318a58e9be16e\n\nProduct = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a\nA = a57da276998c548101f514e9f\nB = -542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 0\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 542fb814f45924aa09a16f2a6\nB = 0\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 1\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 542fb814f45924aa09a16f2a6\nB = 1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899f571f257fa81c36a868d80e7fa2bcbda68a72ca3e31db8892b94d073e006433dd7128b7bf677d2b411532e5662cdff66d657673d58e03d4a338bae1a5513296f91d4d2b5b680527a2e12318e422ec2b7f05ea4fd3ef4780576488211dad5733685a8f0e5d2ecda549a15eebb235495e70d26b194c994cf16d98d356218d08a34d1593d90bc0d3572df0e84bdb1705c6c5e64ea4895599bb21bf219abdd4329813ecc198e708cee199c22f749bdeb0c206690e8420883f6c0661e47b29969986a7a72996ef63234c31aa39b7be37995d2898063ef5c3b672c43afbc1a065dec2671ae87e17639cfcd3148145a8323e1e9dc4f9c9daf981dd6aba4e8be01344c2eda185b87\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899aa73af54a4e1825aa6714016da99d9e3d0c02eb139716db437705cd9efabf0123b0831689735f4e488f226e577d4688d30914dd50ed368939452af0a7a094c065c6718bd54f53a808585fc1728c3bd1e7c968d76c6dca32f95a8323bacad31cdd4aae544d4208262c40bcf726c2f26cf1e60341c3e1e0c8ed4542555b9bf00488680b737a245cc9b7817231f1f6f1e614cdf43ea281fb850ebbb9305b1aa441a45dfdaa1e98b9d79d9ca511be070bfa94d8cd3cc750607c93e1b451a14e32356bd48d77860b37fd2e714827e770a5648ce8579a00ba5cae034502a8b03ba754994d9e002130cfdee6bfdf078dc8f6767b927c964197664c8e32bd3d31bd461ce\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46feff82a92989bca577998c68ee619d9ea9972c6f139e97f5bdde635152830bedf302873508d2ed73badb82f9e32e1f4d12ea8c8b1059aa6d15f8e17d649bf41467903ab40d220d50570b5a263f637c0fcebc0ca29f8a81e2a01bf39bcb60cb9229dfd40618f706b941836bc5c291dec45ee9193e74d3a4cc5f73054ca56fd774a359f17a687268587393b76204a37cd48dcb09d3daed57a7e6d7d93a0ca3d6de8557fc4ddbfe9cb163fd10b7fe5f270dc57aa2fb88cdca2a3795015a17fd352d85fb688a38fa54883d0cab67aab08dbabd58d307c601f0f810014d78b101ff0bddb6d550b2480782406a905b9201e70ef6c1cb9765e91c10c8f5d240c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33", + "f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e3812764dd3ebb7489e6e66058ca6ccf9c007f8c049eda369b2889cc411bca78d4f5b0e3a9e80243e87e112072b01922b595afdef4dd562e58ce917f11e69c8fe050de54fdb2d607d05f09afd6dd140e9d195b91d85269610a1e5d5036e8c9fea2d4fa693d80ecdc819b201c0aed27dfe0b92b4b3b9ecabb3b9548f0d27dc917ffb14308c4f970863e163f375852fcd9fb115640dc40534f8f51a7b903599117dca6c80924fa9a1aeb43cf5a9a3f67ae818b484feed51d7ef60b3656720891b13a983c02c281c8a0954f13b7bfaca844d2cb66de5c11ff507e39cf774c7c93b38e296a44f04e5ecf2819b57943fb0509774ddbcfeb\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899c7bedb01951b0f4fdb2c0fb64ad74707fda20027f4cee25da9b59be288d404cbd348f27600b87015d28f03cdf411f0e8c22deb9de5b3e0094f7820d78d59c90017cbd426297f8a32fb4b55b09362cf7cfb5910085acb24dbf618752b8b74c7e87f9cac44cb3b7486c43aa9b19a64d40a74eaf1de8b5f168b43d5750236aef753278c11294efd1adaddb6addb846f45fa55d7391898e8ec1c82bcf0008d9850c4c096571e8872e975dc8af1ba01bfbe8c8c27dc30cdaddd198936e4496579741a3a20e1b8e17241fe4abe5e98794e469180b742b2e1904940381f703f512885bda0340fe74e997ab269be00a3ca29bb937db2e06d8054e26dc13a5014ba51b175\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d88997cc097fe3f7ace3ffb0fcee52b45551165bb02354b229788b59128489879b1a0373e9862a17692464a2dfc5d09185a0f1c67d2359ba70b52b03f21c7b24feb96e25e1a2dc7f4723952bf203979f7c9e38790f881e2b35006157825555d4c867fce9ea0a3cc6f1c94ee308a68e33f64f286247465ffe854033e9c64f5d79d6d66dcb38ad03535b20376bf4c3cf26e07ef445192ba2baf08bb5286695a61ff6b5dc7aa1832017198d61a324b8c244572157323c7bb3a2fee226133e1b0e0f2ff067cf71fc24bf38d0e172f459b0cdf0707c5bc586390faacf428bfdeb04e850ee0c35f6807eb6ca8d3a473dcc2239541115a8b0d33ea33295ff8c13b2a\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46fc245133c3335163cce37555d36c555182e6d9a754b9aa9305c070083d0fe806d2c5eda4a976f749d6ef40515c425e6531a7f4d11926e49907b7a8a938205e0d6fefaacb145200cbe3deec686476bcdc1f6bb3535147ecb00818f2cd666ac0dd497f0fbc087bf05c6425b7752a02e2a695655d4310f04943a6178946a74dbe4688bd1eb3f1a166aef37e39f3e1d36b6d6d422ec0db264cae8d44869f57a92952bd74a026dd7cfc672803905f029c723487d4123a7520688fc9c68b2384be32e881f64d0ed7ae555bf00e5799740dd8c6accc40f3fe573f194f4848bb05aea8a5509f2dd10fce023093f1ef20267244a990d7ffd462f4e85a4\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f", + "8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e353744d86d954c06f3b84ef271b184ac9957a5f88b08b606fa6aa97afc4983a62f1e74aa3f242e14a3f4cf5ea415d1437818663556a29d117ea7df1cf1ee32f70d6d5566e25d53f892c42d3f92e481b622455fce36e400de09e2d435099695354ceee249c793b76b3c544d70164381e0420ef8b85609502afff9130729ba7851e0775dc5d8c606ba614e7607625fbc38908c88fac43e29ff9b8728f5809e63f20289246b5128016478437550a833c60edb0df43dd9a47654f2e4ef308d4a18cea57ea4b0c6d08add07f2e7adc427cf591c29dbd1f975432922e3f2b71c75e4d2557efccf626be7a0d522b658d420ae321\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7be8e75d54e5ba9405f671d624eaf8d7a115d0479f6fb773b940525fd46b69bc43c815b6bb1798813ca95790bc68032f0b9e73fc964a9922507d8aac25f859745939b828ef5ed326b226b555e5088f13531be16272a89ad41ae82c940935b5d8fe75dc520a230cc279a887bce01bae0a79356f044af13c6f4a5e53c00b2d03cfcbb0f93b26202441a207ec91576410ac1750e257906d945bfe9204b73fc417600bd191edcf2e3eb79acbf4f84dda372405b5e98397abe85c1593543cd7a5b17cb90e299f422f0ce107d86b56474e435dbbcbb5314fb579cd68d54777aa2d0ff9b6b96de62b4676edea5b09589698ed829cad22a52aaec732b79edf6af\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7739032d1f8bb68307f4adc912f1d9b83797606874d4f2c669fe0b263565c4898a07701585237aa444234719adb869c17142126611a9cbd6e689fabb2847bb9dc5e2dc89694621a7179df1fe7371deb9bbdf5fea0b271d86bcde2796a65331c27365fb97fa3647435c47e5c854a95718fa49072cc239d046ca0ac2bf453beb31070370d59483adb42b9876776e43fccb663887f1a999f625eb8e9c4cdd0a89099c42cdff06be29ad9ea66a957002925c9425a83c3e74096ca31324134f5d4a2b7d3b8d7fd8d72192049f79c670874f65201c068c5aac2008a7df4e5eba02d88be8ec23683513a9cffe06671a7c2fa5da7a7aa571914caba1e\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a808857c1bdb914ae0fec75b02d527263093a9d9b8a42289ec74dc73e0e46568a9e8ee117659597434048308c9b66fa7a539694285b1238a13d1163fbac33db147e5431af1c7aca5b1a118db4f6650ec6340491ef7a2d203b53e43d536639f980eb6e92a37bffb2149c5eb45d6718a9496f0784370674c1d29732b944a3c3885b68f0fd2a121f556dc82d1b942e7aabba780f087b9df359d86e2055248c3aabc568e93bba67d3ccca2c4240c876506d63bb05aad6fc4c77dfafff1731a46c6711bc60c4d23976268928bc63e1d133add0633c737bb508c81fa1ff3b452b49b992ebac930432d555ab8c62ae17357b1186e80689672f5a9f472c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e", + "404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6783ab6c7314a43e85a92955a5fbfbffcd31ef0913ba93563dab2b7f54d90fa21ca827ad15b5b1fb399a303f94837536b2813cb563f793fb780e91f8333a2de7bb9f10efdb652a504d6f242e7c15362d3a6eb6e3d1a5abb03023dfe964656979765a14fe8fc36af3d785030ce549b92a91dcb8e2aa13f5b89eb8449b31961a0f77117c8cac79af95ee69f6594e557af7bb017cd885027ff7c0cb1d2f99d1ed5eacb788f645c25150e737cf1184b546bb2d55f2014a18015ffe647580df6fe4d528ce983309baeac0347ae8739e2b1f6d1a83e12e4dbfea1cd81b11b8628837432ad1906c70323529b718c8c6e398e1dfa73\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f225bca564b7e6561b56e0edbb3a7f5934f382b916ab38423221d656357ce0e9bf1e9b04c0678b9c555e8365a0f977c95bd8dca1fb2ad2268193531ca36cbe7f40da8e1afe097e451dc2931b323ce731c03cc027a92ed8ae105c5e9c1bd385e238d989fadbf3aa54c097a8666df8a66b7e2d016e65a2a632603f2c84290ccd7346ada28dff79dd06c7f7989689aca4f494b977f984650f91327ab9936cb92675932440f135e54e4abeecf255d7061482b4c8d91769e02fc94b8acc43325d69541903c3ef7a7a8a5bd19bf886506d42bcf0efcb6197a8d178d6a60516a5aa771ae238a342dc61df8c18c6ba1ed952d4e0c3409c14639\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f2210cc134828c520a58df29ae28863a158a044937809d7d84d2940efbdddb448c64da5f1f31977e7865fd5529eac82fee3e804064a6315936295f8cb26f0de16a47373f5e8365939e280a57dacb508166a583a630c75730c2fe54971e70a35e224e7a1a21e3bd8f417a47c4796d34148cae15068e19eec637bed8f32846dc5aa7e8f50599e840903a8129206fc384e0b4085f9f1e7e3bf2fc67b62b02566ce73cb4b22d471cde35b4f0cccb74283cdded5748d62286f7ea5c184c1308d520ecc7c7f1535b1132708298bf94c0967bc8f8541bb2f2b3c81f11e50f1d8cba4ce3746ad5f85e6bacbefada657c9b386b991b2\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c36ad2daaf856508e861c7f68a2611a215a93e3a15f68f72bb80a4fe9f4cfb6c7f91639179342c633db0f70c9dd849b5b5767908b27e61b812659dcd1a0613433f2c0940be49010886bb384d4676bd523f9827c1a48c7649fbfa73e872a5160796813956979b0f3fd3af728dd48f8a7348090300e41b181c8acae08a3b3106b61f90b0421803e6eba0d68e9bc93d3b659fd6316ba2815cb4b3b6a74f1f3fd24b0c07f619d995ac2beada44188eb72d371a6894f90087eaabe148755409bbff60114bcfefbfe2182e6dc4218d0da75af80059bbb14e848c2e60790fb35bf1cb685cbb133b2baf3f2faefcc3f69e34102def4\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b", + "2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef9518c8ddd2bbd782e5f8cb06be77fc8d0c29f12d4ce67bb2478369710d003f0cb6f40a1341a5a5f2509d2d189084ea4346a44368a54f44c2be4c7b90c4d22976a31985927d0379b2e5d715a7e67eb3228943a07325a29316c695867e8f4ff676e00ffca0a6dfe8fe24652aef9e7f12616e8a54e367b90942f543a01dc7c1b8000ff991228ae83fe0131cfc235ba12ab2bdb33bd4ab0ba1b356bdbc6da4a70eed9fbf2c704e14ed6230eb5478dac0b02f4def1d8c076d1c0c0e2c4cdadb248de4acf961cee51dc41e545bd5a605a0860fb343c28ebf3f8814a9d5a7e0f3e9c93e742db76bc5671258d1da7758b41efead5\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n", +}; +static const size_t kLen45 = 163037; + +static const char *kData45[] = { + "# Quotient tests.\n#\n# These test vectors satisfy Quotient = A / B, rounded towards zero, and\n# Remainder = A - B * Quotient.\n\nQuotient = 1\nRemainder = 0\nA = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\nB = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\n\nQuotient = -2\nRemainder = 1\nA = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b\nB = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d\n\nQuotient = -4\nRemainder = -2\nA = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536\nB = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d\n\nQuotient = 8\nRemainder = -3\nA = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b\nB = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89\n\nQuotient = 10\nRemainder = 4\nA = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4\nB = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b\n\nQuotient = -20\nRemainder = 5\nA = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805\nB = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40\n\nQuotient = -40\nRemainder = -6\nA = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86\nB = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee\n\nQuotient = 80\nRemainder = -7\nA = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87\nB = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b\n\nQuotient = 100\nRemainder = 8\nA = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08\nB = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c\n\nQuotient = -200\nRemainder = 9\nA = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09\nB = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05\n\nQuotient = -400\nRemainder = -a\nA = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a\nB = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6\n\nQuotient = 800\nRemainder = -b\nA = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b\nB = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b\n\nQuotient = 1000\nRemainder = c\nA = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c\nB = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae\n\nQuotient = -2000\nRemainder = d\nA = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d\nB = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe\n\nQuotient = -4000\nRemainder = -e\nA = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e\nB = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8\n\nQuotient = 8000\nRemainder = -f\nA = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f\nB = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1\n\nQuotient = 10000\nRemainder = 10\nA = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010\nB = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2\n\nQuotient = -20000\nRemainder = 11\nA = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011\nB = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e\n\nQuotient = -40000\nRemainder = -12\nA = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012\nB = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166\n\nQuotient = 80000\nRemainder = -13\nA = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013\nB = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34\n\nQuotient = 100000\nRemainder = 14\nA = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014\nB = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194\n\nQuotient = -200000\nRemainder = 15\nA = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015\nB = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d\n\nQuotient = -400000\nRemainder = -16\nA = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608663e12291e9b0695449c1153800016\nB = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e\n\nQuotient = 800000\nRemainder = -17\nA = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017\nB = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec\n\nQuotient = 1000000\nRemainder = 18\nA = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018\nB = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd\n\nQuotient = -2000000\nRemainder = 19\nA = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019\nB = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5\n\nQuotient = -4000000\nRemainder = -1a\nA = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a\nB = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722\n\nQuotient = 8000000\nRemainder = -1b\nA = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b\nB = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a\n\nQuotient = 10000000\nRemainder = 1c\nA = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c\nB = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336\n\nQuotient = -20000000\nRemainder = 1d\nA = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d\nB = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9\n\nQuotient = -40000000\nRemainder = -1e\nA = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e\nB = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5\n\nQuotient = 80000000\nRemainder = -1f\nA = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f\nB = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b\n\nQuotient = 100000000\nRemainder = 20\nA = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c19", + "9bf5c8c951a0d0743d00000020\nB = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d\n\nQuotient = -200000000\nRemainder = 21\nA = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021\nB = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18\n\nQuotient = -400000000\nRemainder = -22\nA = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022\nB = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab\n\nQuotient = 800000000\nRemainder = -23\nA = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023\nB = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed\n\nQuotient = 1000000000\nRemainder = 24\nA = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024\nB = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719\n\nQuotient = -2000000000\nRemainder = 25\nA = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025\nB = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867\n\nQuotient = -4000000000\nRemainder = -26\nA = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026\nB = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226\n\nQuotient = 8000000000\nRemainder = -27\nA = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027\nB = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2\n\nQuotient = 10000000000\nRemainder = 28\nA = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028\nB = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34\n\nQuotient = -20000000000\nRemainder = 29\nA = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029\nB = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd\n\nQuotient = -40000000000\nRemainder = -2a\nA = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a\nB = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608\n\nQuotient = 80000000000\nRemainder = -2b\nA = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b\nB = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12\n\nQuotient = 100000000000\nRemainder = 2c\nA = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c\nB = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1\n\nQuotient = -200000000000\nRemainder = 2d\nA = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d\nB = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1\n\nQuotient = -400000000000\nRemainder = -2e\nA = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e\nB = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54\n\nQuotient = 800000000000\nRemainder = -2f\nA = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f\nB = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb\n\nQuotient = 1000000000000\nRemainder = 30\nA = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030\nB = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7\n\nQuotient = -2000000000000\nRemainder = 31\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13\n\nQuotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346\nRemainder = -16e346b6a4297\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 30c77f3380ccf\n\nQuotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2\nRemainder = -16ebc86eb88339\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -197b6f6ad5b75c\n\nQuotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a\nRemainder = 9bab19f12d81c3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = eb90162ecae18b\n\nQuotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240\nRemainder = 1e4f817a2f52b71\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -546c109fa8a9d7b\n\nQuotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b\nRemainder = -292e149300fdd1ad\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3246242094394c8c\n\nQuotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608\nRemainder = -dd3b3e32ddc79cb9\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e928618913898b2f\n\nQuotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241\nRemainder = 16e021603d30dde2\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 948887c1634f4b08f\n\nQuotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253\nRemainder = 407ccb4f0b814dc5c5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4ad17434071e1ce664\n\nQuotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293\nRemainder = -36f745b0f421d16db7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d71635bcc25183cdde\n\nQuotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82\nRemainder = -107334ab98e5099fec5f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -198a54e35fa0cfa328a9\n\nQuotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42\nRemainder = 170ebe9b83d4c43b79ab\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = f8e923a8bbc0242eafe3\n\nQuotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d\nRemainder = 4d404e93edb435dbd60af\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -52e36cee22274556059ea\n\nQuotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6\nRemainder = -3a2ea5f9d204dc31f21833\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a6734", + "26000000000031\nB = 3d3c79a115d9071b573d2d\n\nQuotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2\nRemainder = -17d02758f8fcadca911a95f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1cc65a75211f2826c9d0811\n\nQuotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac\nRemainder = 5c95323f3b8861261dc31ed\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c516e6e3fa6e3dc52cf5933\n\nQuotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5\nRemainder = 1fc63797594c56160536faa9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -462ee529b488d1db2b6c60e8\n\nQuotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714\nRemainder = -15e79293d5e055f906381a899\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 32765b0a34c88864d39bedaae\n\nQuotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b\nRemainder = -a158ccc7c055d64e7df3fbcf0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -10c061a37f6cbd11bf0c327643\n\nQuotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174\nRemainder = 21e766a0020ba429b330a325d5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9435cd2dc2a92c950bb9e69b83\n\nQuotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d\nRemainder = cafbe9caa1f83fd0dd3d5a6881\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7924e4dcf8f96da61f54bf83870\n\nQuotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497\nRemainder = -94ae72f78982ac1ff83f300cfe8\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3ad70d4b6b9b5f5b2eb65da67e1f\n\nQuotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155\nRemainder = -c83ac7582a02b47ee734e0f24dc5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14bbcff5423a260b21895327b18bc\n\nQuotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03\nRemainder = 8e07efb8ae4c9df39533042362081\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 93aebb72a81ba68e8881fd1a56a90\n\nQuotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90\nRemainder = 794801d9d5770a60e312b99d6b9f91\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7e408caf387a0ce9bbf4309c80755a\n\nQuotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68\nRemainder = -24227c242afedee2473c1a66a5cc29\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f622c665af7f8126eabfd90df8e9c5\n\nQuotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432\nRemainder = -dd290149e0e159f9ba6bb9f5a4b003d\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14a7623d1d9dfc177e913d3119d0d30a\n\nQuotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb\nRemainder = fb60aff5fdd2a2b794b0d973ac4d92a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d439da27b5e70342aa5cb365ece15665\n\nQuotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515\nRemainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -50700f9c0da59482165a47a3eda2bf07a\n\nQuotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3\nRemainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 383c5a4f1767e83fc382ad4f1c7c2b7ddb\n\nQuotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437\nRemainder = -1035512a2717a89062d48f1bfd213333ed0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1402b751a1e5f3fc46e22b43240d6ce9b27\n\nQuotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe873570ab\nRemainder = 72935d534bed5ba557b91ea023601f50b1d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9b4df766c608ff3efe5ea1f65cc850fa73c\n\nQuotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2\nRemainder = 249f6433af4e8e224eb570fd438197af62f3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6b382f812816c77d65c94c0c660b31a69b8f\n\nQuotient = -5f3ced1e42fbd3c6b2c6f1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8\nRemainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 31bc97372d17038fd842b72eaba2abb26df62\n\nQuotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335\nRemainder = -a1493bcbf57a8480461d62796aa8f8541ece4\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9\n\nQuotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c\nRemainder = 273e33521f4d74840a96b3fffe169f79d32855\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = ba7746f4400f812919a3dc86b00642e1487691\n\nQuotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f\nRemainder = 456ebf56c636d54e37709b9e799e83b7a08cb93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2\n\nQuotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633\nRemainder = -4f62c678137df301c4bef216e6aa910104e76ff\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06\n\nQuotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38\nRemainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1daecf01ec633610373b79e04c22cd7499012bc66\n\nQuotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe\nRemainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a1598a12a84e9cba42ea0e200e88d4599c9f615fe\n\nQuotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7\nRemainder = 4610b2b1305220bc0de584dd3f87d90109012a8077\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6\n\nQuotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516\nRemainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f\nA = -1280d26263c5", + "74f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b\n\nQuotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2\nRemainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026\n\nQuotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35\nRemainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b1b959a7b3262d7f4dff488315903aeaffd982b726d7\n\nQuotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada\nRemainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f\n\nQuotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd\nRemainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894\n\nQuotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e\nRemainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7\n\nQuotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546\nRemainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d\n\nQuotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162\nRemainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a\n\nQuotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062\nRemainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831\n\nQuotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf\nRemainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017\n\nQuotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec\nRemainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0\n\nQuotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9\nRemainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae\n\nQuotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00\nRemainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6\n\nQuotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485\nRemainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd\n\nQuotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9\nRemainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b\n\nQuotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502\nRemainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7\n\nQuotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb\nRemainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04\n\nQuotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab\nRemainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80\n\nQuotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532\nRemainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d\n\nQuotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83\nRemainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8\n\nQuotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778\nRemainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b\n\nQuotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2\nRemainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9\n\nQuotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012\nRemainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2\n\nQuotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d\nRemainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644\n\nQuotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73\nRemainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97\n\nQuotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb\nRemainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82\n\nQuotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a\nRemainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f", + "976b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff\n\nQuotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3\nRemainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046\n\nQuotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1\nRemainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f\n\nQuotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2\nRemainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b\n\nQuotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413\nRemainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40\n\nQuotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337\nRemainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575\n\nQuotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508\nRemainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714\n\nQuotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9\nRemainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d\n\nQuotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f\nRemainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694\n\nQuotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba\nRemainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6\n\nQuotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1\nRemainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb\n\nQuotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984\nRemainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235\n\nQuotient = 180054f8c36833d44cab9dd61e6d89d28605c564af\nRemainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018\n\nQuotient = -31412e97045c19ec38951b0e3884c66d1d7479437\nRemainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3\n\nQuotient = -8da1489ccf7203ecead94c67a5750884122b6e75\nRemainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467\n\nQuotient = e635f8bdbf80e99723aa5718d3fade4e573be2c\nRemainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed\n\nQuotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851\nRemainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f\n\nQuotient = -382586dfe93872abbe3a504fc62a8973913f96\nRemainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec8edea425\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52\n\nQuotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38\nRemainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c\n\nQuotient = a9f7e5f235bae0e3e29393ac5c99d510b009\nRemainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba\n\nQuotient = 16de125df5936181981b4c2d0051a8b4d211\nRemainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040\n\nQuotient = -268a52cd10ab4814268f66d9f44f71a98eb\nRemainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85\n\nQuotient = -8f051067ccb82b6a3dffedd0ff2ee97c46\nRemainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7\n\nQuotient = 9b7ee4c499386f922432fcb1a453ee2ec\nRemainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d\n\nQuotient = 23efb26228d7bcf281cd45f54572e2b3a\nRemainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 83cfc25e90a61cf8686e3d5857b2f95", + "8674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413\n\nQuotient = -2cfcae0e922f2d884bfa0a3346dc9812\nRemainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072\n\nQuotient = -4c0238ff3c18d4d58e543f020002802\nRemainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b\n\nQuotient = d41f9102a7785ce64f76b7d7b870b0\nRemainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d\n\nQuotient = 1616b432b3277e774aad92b0cf544c\nRemainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79\n\nQuotient = -320fd6a7375a42a3961362ae196d1\nRemainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb\n\nQuotient = -4bd06daed3f30345d269f51e4381\nRemainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5\n\nQuotient = d6fd01a0c5b55fbe36e58bbe77b\nRemainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d\n\nQuotient = 18bd9a8f5678d28cefd955cf99d\nRemainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa\n\nQuotient = -371239db55c79521206c9e60c0\nRemainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91\n\nQuotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee\nRemainder = 9f0e50ca76031b\nA = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9\nB = 1b1313037e30f4d9\n\nQuotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17\nRemainder = 93d7c547a9ba0a4a\nA = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1\nB = 9ff8df899ee3b3f1\n\nQuotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297\nRemainder = 6c97aace900389d0\nA = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48\nB = ec7123556af55a48\n\nQuotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315\nRemainder = 2903c7cc2651bfa8\nA = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e\nB = 4ea484a22ab0ad1e\n\nQuotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452\nRemainder = 4bdaf1f352e87aa5\nA = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb\nB = 5d42fe145e66ffeb\n\nQuotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29\nRemainder = 55422f1caf4a9a00\nA = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0\nB = 908ae83784ee35c0\n\nQuotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b873787206babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053\nRemainder = 124768541b600598\nA = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14\nB = 16d2c4a24099ca14\n\nQuotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae\nRemainder = 1ba15c46023500b9\nA = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243\nB = 40548136ce50f243\n\nQuotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac\nRemainder = 4cdfd72349c6110\nA = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0\nB = 3a74bba39671fcd0\n\nQuotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88\nRemainder = 2950443357cd7477\nA = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f\nB = 654686ff1368e96f\n\nQuotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5\nRemainder = 3013136f5f728b68\nA = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6\nB = fde3ee3bb61767d6\n\nQuotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0\nRemainder = 1f130dd2ead0d35e\nA = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de\nB = 5b22f9d795df09de\n\nQuotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8\nRemainder = acb8702f0113e0c4\nA = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4\nB = b48a6b29025983a4\n\nQuotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d\nRemainder = 3d1890c5e1555d74\nA = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121\nB = 61c602477f849121\n\nQuotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5\nRemainder = a93a0c5bd51004e4\nA = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf\nB = ef1412873b2d8cbf\n\nQuotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75\nRemainder = 1ce3e5eb13ac7958\nA = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2\nB = b552d4f7eee617b2\n\nQuotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c", + "792e5125e322c27daa73301024080d73ba3491484b659\nRemainder = 3286bdce6dc3a828\nA = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691\nB = 85735e9b78002691\n\nQuotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087\nRemainder = 135784870eb40c68\nA = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844\nB = 22d76a26aaf9b844\n\nQuotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a\nRemainder = 27b105741264f875\nA = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083\nB = 81a39fcadf738083\n\nQuotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed\nRemainder = 95f7434941f9d8\nA = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe\nB = 1ddd0ab110b89fe\n\nQuotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8\nRemainder = 327cf78eed336523\nA = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb\nB = 4ab08ad74f7be5cb\n\nQuotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95\nRemainder = 3b2f844440d7be00\nA = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680\nB = fa8e03d9ce6fc680\n\nQuotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516\nRemainder = b620b7a3b752b78\nA = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468\nB = 115100eddabfb468\n\nQuotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4\nRemainder = 53a0fcf5486c7a6f\nA = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b\nB = e340e9da9b305d3b\n\nQuotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d\nRemainder = e7751deb047d98\nA = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6\nB = 542fcd4a46dcff6\n\nQuotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0\nRemainder = 7c667ea307017c2\nA = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62\nB = 177907198f85cb62\n\nQuotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb\nRemainder = 429a380c9f8eeeba\nA = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67\nB = 432376698f8d2f67\n\nQuotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df\nRemainder = 37924fea665f5c92\nA = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9\nB = 9f8220509f5106b9\n\nQuotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88\nRemainder = de179463e3e91ad\nA = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5\nB = 2c0323980d8841d5\n\nQuotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3\nRemainder = 6bf69921db298b3e\nA = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9\nB = 83a458f0372a57c9\n\nQuotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539\nRemainder = 11c077beb8667d88\nA = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419\nB = 28d6ff55d5662419\n\nQuotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca\nRemainder = 1672a8aa119c3a1d\nA = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b\nB = 54df334dbfcfdd4b\n\nQuotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871\nRemainder = 44c3fdb374bc0c30\nA = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff2a3627d5b942300200c823d764b7a6c12d1c91b\nB = 764b7a6c12d1c91b\n\nQuotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613\nRemainder = 2718de2dd0796f08\nA = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c\nB = 51169b54c62b779c\n\nQuotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd\nRemainder = abf5f6c8ab6ed4f4\nA = e2bf43c91cdbb244790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1\nB = b682c7ee6ab5f5f1\n\nQuotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930\nRemainder = 6c3802d44dd4668f\nA = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f\nB = a71d9ad67ff2ff5f\n\nQuotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035\nRemainder = 660a35e1c1245910\nA = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac\nB = 90593662c86fb5ac\n\nQuotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7\nRemainder = 2e4aeafa2ad76832\nA = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d\nB = cafb4e30846cad1d\n\nQuotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a\nRemainder = 8395953f744cfb31\nA = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967\nB = c473dc8dfed98967\n\nQuotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26\nRemainder = b8ff45f31bdb58d8\nA = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08\nB = f9414ed2f4ba7e08\n\nQuotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6\nRemainder = 7856ec047cec8dc\nA = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14\nB = 2f4916d8b6201d14\n\nQuotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157\nRemainder = 83649246ade8bb4\nA = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72\nB = 84eabd4ea553a72\n\nQuotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811\nRemainder = 3daa032278ce53d0\nA = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba0", + "7b240886a6d5766cfb3ed0937a543\nB = 66cfb3ed0937a543\n\nQuotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd\nRemainder = c007da44faa80584\nA = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5\nB = c9e5b47ef8e63be5\n\nQuotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd\nRemainder = ef65a7789f54174\nA = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5\nB = 1a3d3a0050fa86f5\n\nQuotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5\nRemainder = 398e30aff5bd284\nA = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787\nB = afd12b2c999e787\n\nQuotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23\nRemainder = 378e44fdc7a5ec4c\nA = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a\nB = 7fae9be5dfd41a3a\n\nQuotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93\nRemainder = 39afe3275c01aae6\nA = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5\nB = a547d34edac1d3a5\n\nQuotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874\nRemainder = 63e5ed36ff73a42\nA = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca\nB = 459e52a6cfe4d9ca\n\nQuotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279\nRemainder = 19657d8ce516a138\nA = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557\nB = 1a41c1d517238557\n\nQuotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573\nRemainder = 1bab5b03c372daee\nA = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651\nB = add94e27f30ca651\n\nQuotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc\nRemainder = 18cd326996ccebc1\nA = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d\nB = 2663ec896e1d6c6d\n\nQuotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d\nRemainder = fe9b6b8ba7c30f8\nA = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6\nB = 6d80cf0c957788e6\n\nQuotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7\nRemainder = 169e15b4d5aa180a\nA = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89\nB = 2167f9ce5e233d89\n\nQuotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2\nRemainder = da381ae5c97a506\nA = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a\nB = 1274c5b4d821469a\n\nQuotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720\nRemainder = c41f9e7bf20b376c\nA = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec\nB = dae90967d9ab48ec\n\nQuotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0\nRemainder = 8e435da582e59809\nA = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739\nB = 904674f2ea3ff739\n\nQuotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771\nRemainder = 14135c686d2e9f70\nA = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f\nB = ea8f939c922b1e7f\n\nQuotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763\nRemainder = 230307c44cd55896\nA = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545\nB = 2633a0d905017545\n\nQuotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7bfabb2c\nRemainder = 40f5346f8775e20\nA = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0\nB = e3d7df32c15b75a0\n\nQuotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81\nRemainder = 2e495a881876da00\nA = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c\nB = 94331c1cfb1e941c\n\nQuotient = 5dce24b7a16d847b0c43cf365ea20bee9679fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6\nRemainder = d8ead1ae3126aded\nA = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47\nB = f4dd6e462bbc8f47\n\nQuotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a\nRemainder = 57131776937c5df9\nA = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f\nB = 793dc0907d9aa30f\n\nQuotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9\nRemainder = 5065b726dc6b3758\nA = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb\nB = cec4f0466c1c47cb\n\nQuotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba\nRemainder = 67f48d3584cf4fe5\nA = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73\nB = 73a6a288012c7c73\n\nQuotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf\nRemainder = a5356d04b64ee12\nA = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1\nB = 22664967d67dd5f1\n\nQuotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329\nRemainder = a34980d5046e2ed0\nA = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e\nB = cffee795d695f82e\n\nQuotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53\nRemainder = 36052bba2867f5f4\nA = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96\nB = c1bd491446a50b96\n\nQuotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0\nRemainder = dc8c7d087bf24b0\nA = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0\nB = a26129615a2432b0\n\nQuotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f\nRemain", + "der = 75c703f654ad630a\nA = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5\nB = a1cc13a7108327f5\n\nQuotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65\nRemainder = 453a3d59303ec3c\nA = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19\nB = 84afe4979b5bb19\n\nQuotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287\nRemainder = 5904e71034e3a02\nA = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95\nB = 70a6a40ab6c41d95\n\nQuotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a\nRemainder = 33431c3df719f946\nA = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea\nB = dec06757dbe61aea\n\nQuotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696\nRemainder = 31540f5e05e8b4df\nA = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d\nB = aba050665c090b5d\n\nQuotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5\nRemainder = 4ed4f2d12e4f4ba0\nA = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8\nB = e0adf6f71df7eef8\n\nQuotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af\nRemainder = 7e5661558c345eea\nA = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d\nB = de41a7dfc5c3576d\n\nQuotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897\nRemainder = 29e9c1627537e5a4\nA = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca\nB = 4671868b0526aeca\n\nQuotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87\nRemainder = 664d57c57d4952e\nA = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3\nB = 4bef9c961e2958e3\n\nQuotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4\nRemainder = 5ba8f49e0ca36ab4\nA = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44\nB = ff6d0277fe642f44\n\nQuotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25\nRemainder = 1ef621737e81780\nA = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920\nB = 4d8ea8637e50920\n\nQuotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f\nRemainder = 9ae7de3edb6c7edc\nA = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e\nB = c6b738c0bb282c3e\n\nQuotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477\nRemainder = 3ef5c6ee67e6f5da\nA = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09\nB = 77822f27d1e3cb09\n\nQuotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a\nRemainder = 7cf920ba2897f714\nA = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc\nB = ae0c1fe238c726cc\n\nQuotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343\nRemainder = 2689c40a54df34bc\nA = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662\nB = f05dc6676e51c662\n\nQuotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958\nRemainder = 53da0b15ac079ccd\nA = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85\nB = b54edbf4bbc9af85\n\nQuotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328\nRemainder = 3d051148ec43a72\nA = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2\nB = 3ed5a2e7edaeec2\n\nQuotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8\nRemainder = 1a1f4aeb882d7546\nA = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116\nB = 9196fe73d0e46116\n\nQuotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee\nRemainder = 4578107045b9cb81\nA = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b\nB = c3acc56b72ddbe9b\n\nQuotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce\nRemainder = 1b9861df51429a6\nA = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2\nB = 9672452618da9c2\n\nQuotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8\nRemainder = 2525d52ecdec8814\nA = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4\nB = 5fe5cdbd30726df4\n\nQuotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7\nRemainder = 14781a368471ecae\nA = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b\nB = 198221221724cc3b\n\nQuotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9\nRemainder = 6c754d5c167e1228\nA = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f\nB = 7137cf7eabda038f\n\nQuotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee\nRemainder = b14595005716bfe3\nA = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1\nB = c81ef51b30288cf1\n\nQuotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464\nRemainder = 10fae644af084f8a\nA = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092\nB = 1e1f583ae834b092\n\nQuotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532\nRemainder = baff11e6961c72e3\nA = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad\nB = d4929335a1623bad\n\nQuotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028\nRemainder = 29e33e0c2a515780\nA = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380\nB = 6199279c25d4e380\n\nQu", + "otient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90\nRemainder = 11d8f2f6d4c1f55c\nA = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c\nB = 651f629975faf91c\n\nQuotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589\nRemainder = 1ee700ffb0ea02d8\nA = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35\nB = 3bd460ee19887d35\n\nQuotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172\nRemainder = 74785b6874d8fa37\nA = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9\nB = 9b9f4f097027ddd9\n\nQuotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88\nRemainder = 9a836be71a24e72e\nA = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e\nB = bbc9a0bf08879b1e\n\nQuotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c\nRemainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171\n\nQuotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446\nRemainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd\n\nQuotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06\nRemainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450\n\nQuotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80\nRemainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02\n\nQuotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08\nRemainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40\n\nQuotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a\nRemainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485\n\nQuotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643\nRemainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4\n\nQuotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777\nRemainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1\n\nQuotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4\nRemainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95\n\nQuotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229\nRemainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492\n\nQuotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845\nRemainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f", + "7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26\n\nQuotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122\nRemainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15\n\nQuotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62\nRemainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020\n\nQuotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1\nRemainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e\n\nQuotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d\nRemainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d\n\nQuotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596\nRemainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a\n\nQuotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc\nRemainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a\n\nQuotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395\nRemainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571\n\nQuotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912\nRemainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc4936d273\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c\n\nQuotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286\nRemainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08\n\nQuotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8\nRemainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313\n\nQuotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b\nRemainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886", + "bbcb851448dc1ed4cd66d6598\n\nQuotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd\nRemainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8\n\nQuotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2\nRemainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6\n\nQuotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4\nRemainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71\n\nQuotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d\nRemainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9\n\nQuotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02\nRemainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5\n\nQuotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6\nRemainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253\n\nQuotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602\nRemainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410ddd1e0da\n\nQuotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb\nRemainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041\n\nQuotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780\nRemainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9\n\nQuotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef\nRemainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8\n\nQuotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6\nRemainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39\n\nQuotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c\nRemainder = -24f3431858d5aee412443feab243b465b849f5d", + "c97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d\n\nQuotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f\nRemainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c\n\nQuotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9\nRemainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751\n\nQuotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b\nRemainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8\n\nQuotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287\nRemainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5\n\nQuotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e\nRemainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5\n\nQuotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581\nRemainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396f5db2d979d272798ed30efa15d52289d0c72f42582ea56f\n\nQuotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9\nRemainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1\n\nQuotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e\nRemainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c\n\nQuotient = 4213d04b9f0b30026bd355404bee887b22b2cf9\nRemainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08\n\nQuotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8\nRemainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad58463", + "6352913b7429b99ecfbe\n\nQuotient = -448c4922b7a7d5e1efec2c3f41d0264b76\nRemainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514\n\nQuotient = 152474a1a76700598c18d9301866ec00\nRemainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da\n\nQuotient = 5665f53d5a7405c83a5ff382ec376\nRemainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7\n\nQuotient = -eeda035247bb13860f228d8f2c\nRemainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4\n\nQuotient = -5b37eb0c3e3f8f8d9ac6f4e4\nRemainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065\n\nQuotient = 1c7ac058af2e7bfbda9484\nRemainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e\n\nQuotient = 472df5f4393f33cc382\nRemainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc\n\nQuotient = -12b4e74d76bd306d9\nRemainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec61962e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7\n\nQuotient = -548c97fd02eca7\nRemainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1\n\nQuotient = 14622572f311\nRemainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320\n\nQuotient = 5cdbb03ee\nRemainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f\nA = ea87c57f6cdbfd4f836431be3e9950c90e", + "e8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a\n\nQuotient = -f16da1\nRemainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374\n\nQuotient = -71bc\nRemainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7\n\nQuotient = 10\nRemainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505", + "952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3", + "b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c9596207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8e", + "d469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eced809145e696ceaa0ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8", + "a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb944181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449\n\nQuotient = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91\nRemainder = 0\nA = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91\nB = 1\n\nQuotient = 3b5c3007d9c49498ff8437b6f0014d146b63c20b6c5b91febee47211f42109f6081204b21a8af99e9ab2b5165d536344fec16bd691fb3883ee7335e12d69afc8bff57641ac7a4cee350209a08301553854873da153ccf056427a2415e3ce72972afb5883393806ec2388169b513674c0935f67ec79c89dfc4bdc6f9cf877a10f\nRemainder = 1\nA = 76b8600fb3892931ff086f6de0029a28d6c78416d8b723fd7dc8e423e84213ec102409643515f33d35656a2cbaa6c689fd82d7ad23f67107dce66bc25ad35f917feaec8358f499dc6a0413410602aa70a90e7b42a799e0ac84f4482bc79ce52e55f6b10672700dd847102d36a26ce98126becfd8f3913bf897b8df39f0ef421f\nB = 2\n\nQuotient = 4f54d7e1ac8816945de169e9a2c497ff240e313c2b7d58612c8175e277f032cd4ee5dd640605028c59395a1eb4aa00772a8187a0568b93919aa5b95b0462e5bd31c1e507170039306e1b2f4f75f63ab0a3add0eb01217df61a74765fc37e941dedf10fe142ae317573a4f0c8ce408c213749a12f56add5d100d0973b019350a1\nRemainder = 0\nA = edfe87a5059843bd19a43dbce84dc7fd6c2a93b482780923858461a767d09867ecb1982c120f07a50bac0e5c1dfe01657f8496e103a2bab4cff12c110d28b1379545af154500ab914a518dee61e2b011eb0972c1036479e24f5d631f4a7bbc59c9d32fa3c80a94605aeed25a6ac1a463a5dce38e040981730271c5b104b9f1e3\nB = 3\n\nQuotient = 2922aed641a12010a3099f3c03f708962e2791dd860e65440acf3b982a4041804dcbedf45deefdae5130df96902056f8b2942069fc17bfb29f46a096a36e842ecb30d0800da13b6572c5b3a095038baa3107ca28094063571b517f7cda3659b63099c57a40d7dd2893b92d60b1fe2fb4594fc3a19b7d7957921437556db0e353\nRemainder = 0\nA = a48abb59068480428c267cf00fdc2258b89e477", + "6183995102b3cee60a9010601372fb7d177bbf6b944c37e5a40815be2ca5081a7f05efeca7d1a825a8dba10bb2cc342003684ed95cb16ce82540e2ea8c41f28a025018d5c6d45fdf368d966d8c26715e9035f74a24ee4b582c7f8bed1653f0e866df5e55e4850dd55b6c38d4c\nB = 4\n\nQuotient = 216236f9c82fe6f1c021853a21fde3e21e6de355cf193f16b403edf59a6a6ebeedb266d4c7a6683f5f6a434c7129f582d2a5a852269d66d2eda45a1e2f25286c665f6641ff8b55913603064cc7a157f755e515a426873e7bc6b9d699d1f316759c4505a67b7a025598f9d1af6ebff2ed0fe393db829f768178c1080ea004e4f4\nRemainder = 4\nA = a6eb12e0e8ef82b8c0a79a22a9f5736a982570ad0b7e3b718413a5cc041429baa47c0227e640093cdd13507e35d1cb8e1d3c499ac113021ea435c296ebb9ca1dffdcff49fdb8abd60e0f1f7fe626b7d4ad796c34c0a4386ae1a1310119bf704c0d591c4069620babfce1186d29bfbea14f71e3498d1d50875bc52849201878c8\nB = 5\n\nQuotient = b9fbd48d54b9b70374425aabe16d6a8a819944a43185c2fd07073e20358510ac3de13cff33fe6220ba952d88b2e0f3f7eddb8daf27462b476b5e127e72ea60fd56cc54bf14d2d92765d5d21652d8e16aad4423cd9789515d59aaa02d42d3e957dde50ed1c9a69e2295144a643a8104660ccaafba250854e7f28a686935738\nRemainder = b6d\nA = 8ec1cca67b888cfa26bcee98ee887c47507a253008032c2b37e50f2fb914a34c357f6351e368c2521f3781736d4dab43ce130640f1a55c3851e9b5320f34e772751fd70cab7bd7aebdaa9fc22297790661fecd7b4ed0e6f4275377f2bdcba89bf1d251e0074864618b6e1319eee807e054d193e2616ce52c09ab3d24c187332d\nB = c48\n\nQuotient = 5157f1bb35866dcaa3abb4abb73580d43d03536c3c7960aa95910db60f4d1ffada96c7d89dfcb290bd8c5bb154872e2dd6e50602fafb435193575a4cf253e4d22dbecf11f8f97408dcc83d6e591b1d5daa59825ed8cb08cf562fc50d62cd666b9720055dc11cd42278258e5bd8021aada0b39a340b6c5585bb6c9c84a9ff8\nRemainder = 3d2\nA = 469e999cc737f4d12c97d19a13ce331841f8232cb780602c18592e274ec8b503884566ffcf28a206288f1a9ab3a25bd74bd054781664a331922a96254d6155677836e7455a6690fcb1acd7550cdbca3e9124356ed7b644660092f8d2df06d22ae7f38ca8a4e7472aecce9ad73c47d3a93cc3ec9faeeacd3f59f70ae22c9614b2\nB = de4\n\nQuotient = 3566586b9f864dac5ed132d95d4ac6d1fd5ef6a2c67fee39ece89d615b4c681284b4dd5e27b90c6270b85b150fa2a63440e470b0f937b0eb83432be03eaeb37a0927a9c76b07fe40e3509c93a7b660b77ebbec9bca235d387a9a80a6432c77ddd8190c0ae8ea1d72331d5f4985467755b27573bf23109a01c02975e07daf3\nRemainder = 2a2f\nA = 9d68d0643f1d44b63aff6a83fca08c52bf800dc59260db9b7ff930eb1bc01a47966fa509abd7da21ad856f7cf536d32dc7c962afaca1c9e43bcde135e4c5b9cd9b3c8ad775e06fda06117f8cc03ffad8e5f4b456baba7eaa9c67af7a19c2f4d65120d51fa8d31d0cc1ec7502187cd784fd2d78514cbccff969123718de7cb30d\nB = 2f2a\n\nQuotient = e36f2fbcfe134fdf3137539006d6d9c03b8774883211f759b0258bb09585440d6ff440e799ffc434a2fc529773a455db9abf72d8c55903d9ae5abd5b2b5e9ccf23c015882cab8565c654532d9407a188a40d0cb026fb3bfda428d4bdfc14bec72b5cbd59540c42598f1371e9e61a86e6b4c957ea331baca764b771212495\nRemainder = 6eeb\nA = b669c646d1bbd7389fc642da6d2c440788fec53bd8409ee604222d08b1fc31b3d301e42a8168be0ac394e5f20eb51708b11e7b09d25043f19032310d6649d33eb6c9688506ebd56ebfd0d3f277511ad3caaba3642c53d27e8fb0eb991c75577f584c52b1ec44111b3a9bf5863c18d8a07b91d8ae0bdbbb3b05ec8d11380a9c3a\nB = cd53\n\nQuotient = a891f8a42093cd86d76cb11cf734a65dccd5b4d350328a7d2f2be76e2edb6b7dcf4c5e1915c65764c77ae73fd6e42eb8451253507e16f2e25ef80e5d1f27ea18dc976a9b12147ecb643b2ab060163307df818127b2e40dcea95a109d7841edc9288190587ac48ba9687ccd0d014d531bcf66ec401bbcbed777325fd1060c\nRemainder = 6e66\nA = 9077614b809f4b22707cf965a7e79217e13ca2011cf9e069babe2b4d908e318608f91da095864403b168d750d904fbfe11c9ed80ba9f60d57a8dac2754647002a0848fefb7a5aa8e04fd28dcb9c8e669de4ef794eab2abc93d68dcbf4400d86de603d199a3ee93050638fca7063ea99a9465dfb60d0568b99dfa1ed79da41522\nB = db65\n\nQuotient = 1b16f2e2ef7709fe285ede17beb7d9932caae2dd5fa0eebb541770ca1d53da4428820986cb7e79026eb8bc261eceb200b7696a4b90f675ea9af8389c60dde4d564c8adeba6b117edd05469d285670c0bc78afbc3ad047828cdc611fbcab403c0cb79665d6285b43fa04b77f0309bc7f74136778f8ec16899df040db34f4751\nRemainder = 68\nA = e91e7c26e2b562fe2568613656381d5581628e4705ede6660ca5b79b4a609748889707faf9295b57eecfbb1c0b1cb5cc2a5825b84878e8b9e3960f29b59580385a4af0aae375f8eb7fc66aa6a1fdc4a95e29048ce1e5760722c77cc1c95b1c4c16fdb3e59ed4961f8869711ff24c91ccbe2fb6e0617a5f242227e1e60b3ab673\nB = 89b\n\nQuotient = 37370826964cbd65a48598e73b519db77df6f520bcead8c0446f1288ac189403adb65603b2a68ab3cc232b667232f2e206b5bee0fd48fea8b3ff515f452b5ef0cac591b6ac8c8c509c59c6d3d4e3fa03e22578ff71f1c72ddad9d637ae0497ef0e2a4b261a72cb784f8283eb7e82b6a05aff0a2f61da4780e4e7cfcc4807\nRemainder = 3a29\nA = 16ad5614f9129c7952c5ee8057d8d12a70780144e616e3ed571b2e38a9ce482a52c436eb9ccb6e4f400321bf1f3ef4c8dc897cd91f868eb7018d084784c4840a1d078c8c6a75e950cb76cf2cd81b719ac04d2be5c9a830b1d1361f7ef6345af66a6d56c53234cd98f587b6762401674973df670addcc4a05ec0344d402453a25\nB = 6924\n\nQuotient = 9bb00032a27651eac898b8a567e19ed6448669c8514b5659c4b1103069d9289c6c00b38b44160e0efb2c635b7a64c8296c1c1b5c2cdb285b749e614eb9247c6defa06f8dac077b1e1c26059847de56a1a5ddf7fb1254662624f2ffe6edc48f3b318ffdc7ba2a81ef2d963b934120f58afba2b107a215b58f324e2d923f75\nRemainder = c03\nA = 74524695d4dc11023ff202ed2d165551ace0c126f7a51ebb3ff21ecd7c058cd4a6bda2254c55ce6ef76fd11807f92e80dad31bfd254f9a2e1ca89949f65a1fab8f6a4978c488f2dfa61df46c1faa418ff45250d82958e8f5fdd9426c44a3bcd7c4eeca276abae466787a5ff0ec482514e03434ee68fce24fc620e31265c3718c\nB = bf45\n\nQuotient = cecbbc189fb1d44c5511f742b63207bcba9c78d09342cdcd12a1b1bc3a95466e7fdd8c59329a9b18f7c793c43f08d52339a8202dfa3a9fa86a2426bf5a94e006849b45cbe9a5dd74ca43e2acdf1051be23359624e8f146b203864d03651d98165b783398a59b446314c9b01f79b1139c30df348b14ffd25b22d9d90866b\nRemainder = b265\nA = c3721776b9b5fea8608aa9d381d80ac603d27043089dac276832e7cde8d222ffe142f06c314e94c3b9f6148d029f260879b700e1d435b5f318c8c8caebe92236c9060c183783edec2845e6d4e816197196a0de3644544093b04ac6fb4c69d7446954fbabadcc5dc3309e9a3fcf70368ba7448455cec9c3dc78512a19ebb04f6\nB = f1f3\n\nQuotient = 4090a2c78cf8711388347149926610d624543765c9667567ad86eef9f9777f53c0cc0f9a989d9195a5e0da875c03e5c74614f95b8752f9ab89fa61c264b8b5d3e02b043fd539d36dbc6782f45a555d1f36751603d5c3423c7f27b3b5dcb91ddc81bf1563dd3abb0970de6109d76da1f4f9d5208ade2b131fc407c5b169c\nRemainder = 2a87\nA = 129d32cde3c648298f8e8e8123f2e8ee9cad3f909a5647ed09e91cb99549d177575f54a7a3ebbd4ed2b89940722927a8b9565ffbc13d8df6d2616d5b1925b87bbb6aa6d39f2b11d26d071fa30e63083ed5a5357ecf0ab1028cf0a43178486679e86fe4dcb071c49832c83c9de4599d672e5ecfc7c9190f1d7275f5a0abed80f\nB = 49ce\n\nQuotient = 43340591e68e228fb03e44a5f2046afe41a3d7ca99ea9ff1a445d75f95f2ff7f55fb914791613b5db7369121d416a5f92f834b0b5e9280b49a9e66be4c682019881e6e8883d7a923d2a5d309b9d265b01d6b8a4ee07f7552934f2de002cf961fd93f33641aaaccc7c367fb6798436eecc9bb22357087a9c482131e1065eb\nRemainder = 6332\nA = 42e75e3b8c23287044593d9fa4bc5df437a0f8e876d3105334a677b5ecebf653e8bd7e55dbbf6876005196e44980bc23df491949c59aa199cc9e0a111b58f954eaff2bd270214726e5c98de502ba71b42089fba51e8763f0c11f278faf4c61589ceb674d7c7c61f62f8d18ccd619c20243a508c26b934f06ddeec0421b372326\nB = fedc\n\nQuotient = 688c7120765f8ef7363f7ae1bb65bc568b16e32c59762f59f34a57f08839d19019313dfcc9e96d7415766bc0aa032b19ecea72c249bffa0538bb1ac06401657df2fbea5c46b18d8a79cee4029e5972d8361fb7e6c2c537673aecd727dbc758a3bca1a001765a216e9985eb7eea67ae979f3803f14587507ba0f8fa29957\nRemainder = 9970\nA = 688c0894053f1897a74844a2408400f0cec058157649d5e3c3f064a63049495647a124cb8beca38aa802564a3e428116c1d085d7d6fdb0453eb5e2054941017c8d7df7605c5546d8ec446a33ba56d47ec34781c70ade74a203859c3b049f7cdc63fde35fd658ab14781751f8fee8c42ff0a064b941960af4507d59309b50019\nB = ffff\n", +}; +static const size_t kLen46 = 85968; + +static const char *kData46[] = { + "# LShift1 tests.\n#\n# These test vectors satisfy A * 2 = LShift1\n\nLShift1 = 0\nA = 0\n\nLShift1 = 13116120bca5df64e13f314254\nA = 988b0905e52efb2709f98a12a\n\nLShift1 = -13116120bca5df64e13f314254\nA = -988b0905e52efb2709f98a12a\n\nLShift1 = 2622c241794bbec9c27e6284a8\nA = 13116120bca5df64e13f314254\n\nLShift1 = -2622c241794bbec9c27e6284a8\nA = -13116120bca5df64e13f314254\n\nLShift1 = 4c458482f2977d9384fcc50950\nA = 2622c241794bbec9c27e6284a8\n\nLShift1 = -4c458482f2977d9384fcc50950\nA = -2622c241794bbec9c27e6284a8\n\nLShift1 = 988b0905e52efb2709f98a12a2\nA = 4c458482f2977d9384fcc50951\n\nLShift1 = -988b0905e52efb2709f98a12a2\nA = -4c458482f2977d9384fcc50951\n\nLShift1 = 13116120bca5df64e13f3142544\nA = 988b0905e52efb2709f98a12a2\n\nLShift1 = -13116120bca5df64e13f3142544\nA = -988b0905e52efb2709f98a12a2\n\nLShift1 = 2622c241794bbec9c27e6284a8a\nA = 13116120bca5df64e13f3142545\n\nLShift1 = -2622c241794bbec9c27e6284a8a\nA = -13116120bca5df64e13f3142545\n\nLShift1 = 4c458482f2977d9384fcc509514\nA = 2622c241794bbec9c27e6284a8a\n\nLShift1 = -4c458482f2977d9384fcc509514\nA = -2622c241794bbec9c27e6284a8a\n\nLShift1 = 988b0905e52efb2709f98a12a28\nA = 4c458482f2977d9384fcc509514\n\nLShift1 = -988b0905e52efb2709f98a12a28\nA = -4c458482f2977d9384fcc509514\n\nLShift1 = 13116120bca5df64e13f31425450\nA = 988b0905e52efb2709f98a12a28\n\nLShift1 = -13116120bca5df64e13f31425450\nA = -988b0905e52efb2709f98a12a28\n\nLShift1 = 2622c241794bbec9c27e6284a8a0\nA = 13116120bca5df64e13f31425450\n\nLShift1 = -2622c241794bbec9c27e6284a8a0\nA = -13116120bca5df64e13f31425450\n\nLShift1 = 4c458482f2977d9384fcc5095142\nA = 2622c241794bbec9c27e6284a8a1\n\nLShift1 = -4c458482f2977d9384fcc5095142\nA = -2622c241794bbec9c27e6284a8a1\n\nLShift1 = 988b0905e52efb2709f98a12a286\nA = 4c458482f2977d9384fcc5095143\n\nLShift1 = -988b0905e52efb2709f98a12a286\nA = -4c458482f2977d9384fcc5095143\n\nLShift1 = 13116120bca5df64e13f31425450c\nA = 988b0905e52efb2709f98a12a286\n\nLShift1 = -13116120bca5df64e13f31425450c\nA = -988b0905e52efb2709f98a12a286\n\nLShift1 = 2622c241794bbec9c27e6284a8a18\nA = 13116120bca5df64e13f31425450c\n\nLShift1 = -2622c241794bbec9c27e6284a8a18\nA = -13116120bca5df64e13f31425450c\n\nLShift1 = 4c458482f2977d9384fcc50951430\nA = 2622c241794bbec9c27e6284a8a18\n\nLShift1 = -4c458482f2977d9384fcc50951430\nA = -2622c241794bbec9c27e6284a8a18\n\nLShift1 = 988b0905e52efb2709f98a12a2862\nA = 4c458482f2977d9384fcc50951431\n\nLShift1 = -988b0905e52efb2709f98a12a2862\nA = -4c458482f2977d9384fcc50951431\n\nLShift1 = 13116120bca5df64e13f31425450c6\nA = 988b0905e52efb2709f98a12a2863\n\nLShift1 = -13116120bca5df64e13f31425450c6\nA = -988b0905e52efb2709f98a12a2863\n\nLShift1 = 2622c241794bbec9c27e6284a8a18e\nA = 13116120bca5df64e13f31425450c7\n\nLShift1 = -2622c241794bbec9c27e6284a8a18e\nA = -13116120bca5df64e13f31425450c7\n\nLShift1 = 4c458482f2977d9384fcc50951431e\nA = 2622c241794bbec9c27e6284a8a18f\n\nLShift1 = -4c458482f2977d9384fcc50951431e\nA = -2622c241794bbec9c27e6284a8a18f\n\nLShift1 = 988b0905e52efb2709f98a12a2863c\nA = 4c458482f2977d9384fcc50951431e\n\nLShift1 = -988b0905e52efb2709f98a12a2863c\nA = -4c458482f2977d9384fcc50951431e\n\nLShift1 = 13116120bca5df64e13f31425450c7a\nA = 988b0905e52efb2709f98a12a2863d\n\nLShift1 = -13116120bca5df64e13f31425450c7a\nA = -988b0905e52efb2709f98a12a2863d\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4\nA = 13116120bca5df64e13f31425450c7a\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4\nA = -13116120bca5df64e13f31425450c7a\n\nLShift1 = 4c458482f2977d9384fcc50951431e8\nA = 2622c241794bbec9c27e6284a8a18f4\n\nLShift1 = -4c458482f2977d9384fcc50951431e8\nA = -2622c241794bbec9c27e6284a8a18f4\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2\nA = 4c458482f2977d9384fcc50951431e9\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2\nA = -4c458482f2977d9384fcc50951431e9\n\nLShift1 = 13116120bca5df64e13f31425450c7a4\nA = 988b0905e52efb2709f98a12a2863d2\n\nLShift1 = -13116120bca5df64e13f31425450c7a4\nA = -988b0905e52efb2709f98a12a2863d2\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4a\nA = 13116120bca5df64e13f31425450c7a5\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4a\nA = -13116120bca5df64e13f31425450c7a5\n\nLShift1 = 4c458482f2977d9384fcc50951431e94\nA = 2622c241794bbec9c27e6284a8a18f4a\n\nLShift1 = -4c458482f2977d9384fcc50951431e94\nA = -2622c241794bbec9c27e6284a8a18f4a\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2a\nA = 4c458482f2977d9384fcc50951431e95\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2a\nA = -4c458482f2977d9384fcc50951431e95\n\nLShift1 = 13116120bca5df64e13f31425450c7a56\nA = 988b0905e52efb2709f98a12a2863d2b\n\nLShift1 = -13116120bca5df64e13f31425450c7a56\nA = -988b0905e52efb2709f98a12a2863d2b\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4ae\nA = 13116120bca5df64e13f31425450c7a57\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4ae\nA = -13116120bca5df64e13f31425450c7a57\n\nLShift1 = 4c458482f2977d9384fcc50951431e95c\nA = 2622c241794bbec9c27e6284a8a18f4ae\n\nLShift1 = -4c458482f2977d9384fcc50951431e95c\nA = -2622c241794bbec9c27e6284a8a18f4ae\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2ba\nA = 4c458482f2977d9384fcc50951431e95d\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2ba\nA = -4c458482f2977d9384fcc50951431e95d\n\nLShift1 = 13116120bca5df64e13f31425450c7a576\nA = 988b0905e52efb2709f98a12a2863d2bb\n\nLShift1 = -13116120bca5df64e13f31425450c7a576\nA = -988b0905e52efb2709f98a12a2863d2bb\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aee\nA = 13116120bca5df64e13f31425450c7a577\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aee\nA = -13116120bca5df64e13f31425450c7a577\n\nLShift1 = 4c458482f2977d9384fcc50951431e95de\nA = 2622c241794bbec9c27e6284a8a18f4aef\n\nLShift1 = -4c458482f2977d9384fcc50951431e95de\nA = -2622c241794bbec9c27e6284a8a18f4aef\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbc\nA = 4c458482f2977d9384fcc50951431e95de\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbc\nA = -4c458482f2977d9384fcc50951431e95de\n\nLShift1 = 13116120bca5df64e13f31425450c7a577a\nA = 988b0905e52efb2709f98a12a2863d2bbd\n\nLShift1 = -13116120bca5df64e13f31425450c7a577a\nA = -988b0905e52efb2709f98a12a2863d2bbd\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef4\nA = 13116120bca5df64e13f31425450c7a577a\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef4\nA = -13116120bca5df64e13f31425450c7a577a\n\nLShift1 = 4c458482f2977d9384fcc50951431e95dea\nA = 2622c241794bbec9c27e6284a8a18f4aef5\n\nLShift1 = -4c458482f2977d9384fcc50951431e95dea\nA = -2622c241794bbec9c27e6284a8a18f4aef5\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6\nA = 4c458482f2977d9384fcc50951431e95deb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6\nA = -4c458482f2977d9384fcc50951431e95deb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ac\nA = 988b0905e52efb2709f98a12a2863d2bbd6\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ac\nA = -988b0905e52efb2709f98a12a2863d2bbd6\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5a\nA = 13116120bca5df64e13f31425450c7a577ad\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5a\nA = -13116120bca5df64e13f31425450c7a577ad\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb4\nA = 2622c241794bbec9c27e6284a8a18f4aef5a\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb4\nA = -2622c241794bbec9c27e6284a8a18f4aef5a\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6a\nA = 4c458482f2977d9384fcc50951431e95deb5\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6a\nA = -4c458482f2977d9384fcc50951431e95deb5\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad6\nA = 988b0905e52efb2709f98a12a2863d2bbd6b\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad6\nA = -988b0905e52efb2709f98a12a2863d2bbd6b\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5ae\nA = 13116120bca5df64e13f31425450c7a577ad7\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5ae\nA = -13116120bca5df64e13f31425450c7a577ad7\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5e\nA = 2622c241794bbec9c27e6284a8a18f4aef5af\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5e\nA = -2622c241794bbec9c27e6284a8a18f4aef5af\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6be\nA = 4c458482f2977d9384fcc50951431e95deb5f\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6be\nA = -4c458482f2977d9384fcc50951431e95deb5f\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7e\nA = 988b0905e52efb2709f98a12a2863d2bbd6bf\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7e\nA = -988b0905e52efb2709f98a12a2863d2bbd6bf\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5afe\nA = 13116120bca5df64e13f31425450c7a577ad7f\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5afe\nA = -13116120bca5df64e13f31", + "425450c7a577ad7f\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5fe\nA = 2622c241794bbec9c27e6284a8a18f4aef5aff\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5fe\nA = -2622c241794bbec9c27e6284a8a18f4aef5aff\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bfe\nA = 4c458482f2977d9384fcc50951431e95deb5ff\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bfe\nA = -4c458482f2977d9384fcc50951431e95deb5ff\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc\nA = 13116120bca5df64e13f31425450c7a577ad7fe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc\nA = -13116120bca5df64e13f31425450c7a577ad7fe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff8\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff8\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff0\nA = 4c458482f2977d9384fcc50951431e95deb5ff8\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff0\nA = -4c458482f2977d9384fcc50951431e95deb5ff8\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff0\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff0\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc0\nA = 13116120bca5df64e13f31425450c7a577ad7fe0\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc0\nA = -13116120bca5df64e13f31425450c7a577ad7fe0\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff82\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff82\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06\nA = 4c458482f2977d9384fcc50951431e95deb5ff83\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06\nA = -4c458482f2977d9384fcc50951431e95deb5ff83\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0c\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0c\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1a\nA = 13116120bca5df64e13f31425450c7a577ad7fe0d\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1a\nA = -13116120bca5df64e13f31425450c7a577ad7fe0d\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06c\nA = 4c458482f2977d9384fcc50951431e95deb5ff836\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06c\nA = -4c458482f2977d9384fcc50951431e95deb5ff836\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0da\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06d\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0da\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06d\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b6\nA = 13116120bca5df64e13f31425450c7a577ad7fe0db\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b6\nA = -13116120bca5df64e13f31425450c7a577ad7fe0db\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836e\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836e\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06de\nA = 4c458482f2977d9384fcc50951431e95deb5ff836f\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06de\nA = -4c458482f2977d9384fcc50951431e95deb5ff836f\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7c\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7c\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fa\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7d\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fa\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7d\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbec\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbec\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7da\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7da\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb6\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb6\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb6\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb6\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed82\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed82\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed83\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed83\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed832\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed832\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60ce\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60ce\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cf\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cf\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c\nA = 13116120bca5df64e13f31425450c7a577ad7fe", + "0dbed833e\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\n\nLShift1 = ab4e", + "80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\nA = -ab4e80e", + "4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\nA =", + " -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\n\n\n# LShift tests\n#\n# These test vectors satisfy A * 2^N = LShift.\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 6\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 7\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 8\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 9\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = c\n\nLShift = 18c9e", + "860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 10\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 11\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 12\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 13\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 14\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 15\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 16\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 17\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 18\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 19\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 20\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 21\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 22\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 23\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 24\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 25\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 26\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 27\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 28\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 29\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 30\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 31\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 32\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 33\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 34\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 35\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 36\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 37\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 38\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 39\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 40\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 41\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 42\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 43\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 44\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 45\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 46\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 47\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 48\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 49\n\nLShift = 3193d0c10abab29b96", + "0da016fa3266c117520db0bf45b2593c0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 50\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 51\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 52\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 53\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 54\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 55\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 56\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 57\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 58\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 59\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 60\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 61\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 62\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 63\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 64\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 6\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 7\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 8\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 9\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 10\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 11\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 12\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 13\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 14\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 15\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 16\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 17\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 18\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 19\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 20\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 21\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60", + "ffb11e600aa3088ec8e\nN = 22\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 23\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 24\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 25\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 26\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 27\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 28\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 29\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 30\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 31\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 32\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 33\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 34\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 35\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 36\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 37\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 38\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 39\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 40\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 41\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 42\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 43\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 44\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 45\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 46\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 47\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 48\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 49\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 50\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 51\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 52\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 53\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 54\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 55\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 56\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 57\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 58\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 59\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000000\nA = ", + "e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 60\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 61\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 62\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 63\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 64\n\n\n# RShift tests\n#\n# These test vectors satisfy A / 2^N = RShift, rounding towards zero.\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36380\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c70\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3638\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 6\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 7\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c7\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 8\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b363\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 9\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 10\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 11\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 12\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ec\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 13\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f6\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 14\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 15\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 16\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365e\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 17\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 18\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 19\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cb\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b36\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 20\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 21\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 22\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b3\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 23\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 24\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 25\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb6\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 26\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 27\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 28\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 29\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d59\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806ac\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5740356\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 30\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d5\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 31\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 32\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa574035\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 33\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 34\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 35\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 36\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 37\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 38\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 39\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae80\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5740\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d0\nA = d9ce8dff4f2f39c216ea39a461080552", + "ba01ab2d9b2f66c701\nN = 3d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae8\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa574\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 40\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 41\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 42\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 43\n\nRShift = d9ce8dff4f2f39c216ea39a461080552b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 44\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 45\n\nRShift = 3673a37fd3cbce7085ba8e6918420154a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 46\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 47\n\nRShift = d9ce8dff4f2f39c216ea39a461080552\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 48\n\nRShift = 6ce746ffa7979ce10b751cd2308402a9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 49\n\nRShift = 3673a37fd3cbce7085ba8e6918420154\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4b\n\nRShift = d9ce8dff4f2f39c216ea39a46108055\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4d\n\nRShift = 3673a37fd3cbce7085ba8e691842015\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4f\n\nRShift = d9ce8dff4f2f39c216ea39a4610805\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 50\n\nRShift = 6ce746ffa7979ce10b751cd2308402\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 51\n\nRShift = 3673a37fd3cbce7085ba8e69184201\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 52\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 53\n\nRShift = d9ce8dff4f2f39c216ea39a461080\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 54\n\nRShift = 6ce746ffa7979ce10b751cd230840\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 55\n\nRShift = 3673a37fd3cbce7085ba8e6918420\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 56\n\nRShift = 1b39d1bfe9e5e73842dd47348c210\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 57\n\nRShift = d9ce8dff4f2f39c216ea39a46108\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 58\n\nRShift = 6ce746ffa7979ce10b751cd23084\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 59\n\nRShift = 3673a37fd3cbce7085ba8e691842\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5a\n\nRShift = 1b39d1bfe9e5e73842dd47348c21\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5b\n\nRShift = d9ce8dff4f2f39c216ea39a4610\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5c\n\nRShift = 6ce746ffa7979ce10b751cd2308\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5d\n\nRShift = 3673a37fd3cbce7085ba8e69184\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5f\n\nRShift = d9ce8dff4f2f39c216ea39a461\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 60\n\nRShift = 6ce746ffa7979ce10b751cd230\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 61\n\nRShift = 3673a37fd3cbce7085ba8e6918\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 62\n\nRShift = 1b39d1bfe9e5e73842dd47348c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 63\n\nRShift = d9ce8dff4f2f39c216ea39a46\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 64\n", +}; +static const size_t kLen47 = 136825; + +static const char *kData47[] = { "# Sum tests.\n#\n# These test vectors satisfy A + B = Sum.\n\nSum = 0\nA = 0\nB = 0\n\nSum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nA = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nB = 0\n\nSum = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nA = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nB = 0\n\nSum = 0\nA = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nB = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\n\nSum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 23f85668bf4d0fa273d8c7f63c5fee57811062a674111e295a73a58e08dd0fd58eda1f473960559d5b96d1862164e96efded31f756df3f57c\n\nSum = c590e57ee64fceccd54e0bdc52476a756d32e794922dca0acc780d2c6af8852351102b40dfb97009f95e019a5bf38e5d127aa78bc34425edf96f763084a8b09f\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -4b5b16252ba2355e0b87f01baa721783c403607a4c1b5652c09a68e96926c8e314fa580bf0ad3f8f59bd70f14df86a4676661899b54c79a62\n\nSum = -c590e57ee64fcec882fef3ffd015a3fd9024d8f5f6d53eb537d6abdb0ff5e76a8fb08d5feed113fc9e74745d957adf32704a08339ba42efd5746c5d478e3f57b\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 908007a2f3c551c58958d1059427a0391d4d768f61cb802e4cb062c778354ea3eaa8f0dfbd14ca8203e07ae6d07269b58088a39f7608c5586\n\nSum = -c590e57ee64fceeb242f8a0893eaa0d2ccc3dc57ec40fe917cfde66618fba678ce0c8fffc566d4e8c7944d6443def8014fe8ee410a1b8dfd06cb0b436619e0dd\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1999301bd9877fe07ca711f308b2f1bc4a704fd194ec4dbc297355d6285340d6ad7e90cb0add1770aea19737a06750c3a7a6fa0b778ca995dc\n\nSum = c590e57ee64fcef321395bba088ca0a867e1e85a1ea77478f8783e6a6cf8f3e582bff83cb2d7d9fd549fcbb40dea22ac140351007030059500bdca81413600e9\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 219639ed8afc21e052422fff0ae5583231ebca2999404b099628093e6540b1dbc20b9c495aa7229b5965b19a5fcd653b3fa0eccab567c5b5e8\n\nSum = c590e57ee64fce834a00cc6282cb0eef49eac7a8d5b51988cb49253ed85ae261c76f2327a691fc63eceab02614807048b2816cdb9b89ca66a17b6ed1abdab580\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -4e40fea1cc899fb166dbc721a6639a28be4164ef92545307ed934796afcb9401d75c18d23352471709fbd049c50740ffeebe5590fa2d959581\n\nSum = -c590e57ee64fce1a17609c61ce02f1020c6eb6e241e3fdd01546ce7247725589de32db95f36718d410f9ce9a94fecc8fb205e876fde75ce83f4d01e1bd5d818d\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = b7739ed1cd3e67cf541943326cf76b4476f767465ee53b94c57c83de417ebee5673809b3bed1c8bac2fc4bce29a4e36d6d2083fdea1c12c974\n\nSum = -c590e57ee64fd03e2d08c3d8e5110d08e3d36557d82e0e49b408337a8c9d4298802ae5f0145a9587531a70d2f8af932b8262245428b5c549817d333f2dfaeeec\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -16ca20955a9d8a64cb2be217c089edecc02a75a1ea95fef584925742c18a234974c0a16ee7991e80bd8d4106db385eafaf421ac3373548aa3eb\n\nSum = c590e57ee64fd1bcac71b5b055e5934ba15dd7f56370063369c36e57a6b753269e085d0f4d38bfb711d5579dd1d89d07f266e727b232a497d5b0d9bfbc02d8a5\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 2eb21724781497ad2f57babeea62a20c3ec5d1559867a0968d74351a337db12c17bc8d1d5446b1115b5441530870f67da4275dfd9f3e2928da4\n\nSum = c590e57ee64fc7860b0be6ce861bc2f099db7fb623912b7b0729c019a8183c669c73efe02b195483a4cd2c78244cd59678ac4d62f6887fe686a3eed37ed460ff\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -74b7ff38760864efd658bd6699915be16cc058454b78495ade8be42c9f7470ca9b7a43655e1427ab1bc35a5693dac424a6ed92d10f85a9bea02\n\nSum = -c590e57ee64fc3126776e79d9fca06233bd2ef5570a65e4521183627bdbdbc555e9118508cf63f519bc0caedbffd5b1a913ee8c3603804820a9ce54b1207bdef\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = bbf238886916ca0ba32e9def9f9c8a8e401eb95dea96ef02df9fc25a186e52fbee9ad42b76ba6ca2c381d12cddd4292c5d355341a80c7688d12\n\nSum = -c590e57ee64fe6dfd728dfbe45aee52380b5a00cf1e05e9f09ac582e2714bb589caf2ad038111c5b1b5573a45706ab1f6fd5d5a1ee7ef4a9bf186dca8a9ede12\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -180e4c29718f394424cd5b03b6bdb8911c57fcfe435cfa66d10941f870f8c5eb1e1fd251f14af03f23ccc1841f014bb42a545f476dfeb12e9311\n\nSum = c590e57ee65004b3e18a5820de4a6d25e7c3d310003e0b8716bbfd51d5f0f3e87fdf8e00599d713397255281e66ef419a9d9bb228e8f052764f5f861ccca656f\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 35e2568ae9f1d1dfaccfc211e9c0c6eec9400a0de880a94309992528d428e77772f84e21d0287fa76cc6fb880481ebc43ad20524f895f35a1a6e\n\nSum = c590e57ee64f84896a5f11f575d34b6001f27d4b4d6e7cd9485260629f8f7f1c6ca6f6115b98d776774295dde4d59cdbbceccad097a0a054b501bfb47d81e85c\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -4a4820a05c39969774f623bf6c03ebe0c56dc45bb46e8d1e6b32ee0fc3c6168d26c4d1c0ec7b81f1ea76f164ebd00b2a2a00aacf40175bee62a5\n\nSum = -c590e57ee64edf1b2b57b4cbb92d778ea6b9d9878a0374d4ea81691b09811b105bb6dbf23a57d89264f0e6c83f8d00fe00681644feed56e15fc81103ab9b7dd6\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = efb65fa7b963533d48c77ef80fc7af4bcd72222cabb6232ccf3efeffdde537ce25a8e4129b91273a8654ade9a05ba3dd73740008eec82dd4cd2b\n\nSum = -c590e57ee650e25da7b60146e014f472bfff9809aa8f519db7943f69d9ad09ee75a3427c6127cce7bd27f224b9dec03111fb066956b4903f9f9740cce1aa4ba7\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1138c1cb69317d3aa341c9a4daeba71400f56aae62a98acff1f9f1aec88a4ef01ceac74246fcb531738de63a94fc8b3e9c5ea3fc64101083a00a6\n\nSum = c590e57ee653af8752322840ed720f628f9674c81073b58372e49ef26d4a2a9d46a0391bc170336614b27849de98709a4b321da4ddfb978e9f10df29154edb9f\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 3e0b5c732ba11e1074f0c69e48b78d724733c66368a21409c404debe97f444f4a352acbaef5f077d0e9479ce067043b30cd393f3fdf5d3bde909e\n\nSum = c590e57ee64bc13634cbd149aae35ee47bde6ea3663f74ff300cfdb2d845f902f017586c6d4f83f08c3b4f0c035055d13fc9d340b7b9ed164432aed44e8f4d7c\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -40d9b56339ce561876171a9d37aabd30fcd47dca1171e5467f14c6a9f616b04d67a4abcc8334d637731816e87e35feb10dd3f1b9e50f78ae0fd85\n\nSum = -c590e57ee6477eb692705f8da1357e71591336907a5e0a6e39715088d53b2610882765357563fd101bcf05ca545a0c718f52879fdf4f80cb9a12cf108eca60ed\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0f", "fcbd9704b01\nB = 8501af88f0ea16b3541e4cc9eb2bebef137d8d33cc4485772c43ed28f54a1fcc2012b2d347c8f126d7ae11eff2f00c37b4989c5be30bb4aa5ea14\n\nSum = -c590e57ee669b662e37f5abf13d00d2f0c1c9a8b99ec546361aad255f375bc2742a3487c351c5ba00efef09c77331577460a47c57125c620b643e9eaf36a146b\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -19e791587fec9007654cd8e66ab13c609d121c54fcbd84c6c7d1d7e7ec8ea4c2f65d64c5fb6e43106b8e2497b89124ce5afbcb5672ea1f19f9c96a\n\nSum = c590e57ee681dcbf1554f22c0b1ffead917dd414299cb37ce6967ffec9c333931e70358729843c8130ac95aba47fa1fa5da74000eff25eecae176f093a4effca\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 320ded8a5583fcfeb53e576bcbeac4f04d7135d9e86b2d9d154943c3b97bafb75e3e45e7a913523db81aa7af5589604d2794974e466f3d60deb4c9\n\nSum = c590e57ee5e505ae4a2e1f25a1ae9b7b4d17dd2cccc09f2416d964e55af6d0d31fe259c160f87646a72e6732d5110256b3b35425225d622b81418435c9dd8cc4\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -6ac92340d14f096abc24dad89a0c226c8ea322f5d4afebd1b7197c3ad46016112d87f4a1d51b2691b684fbfa9e627b806d6829de8f7b960f92be3d\n\nSum = -c590e57ee58c3ef1582bf7a516e36f92b60f5a587e2c8cb071d1d52ff215854e52de1519fd5204fa52292dfdc397d8d76b78005941358b63a3e6ca41b0eb09b7\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = c38fe032d37689f58750c36fa28ef6bb22b5969adc3fa13a98650107d8a4bd74d3f940f6da545ba32fae7b42d9b64761953ef1bbea358a2885414a\n\nSum = -c590e57ee80262967da4038a143f8ff2e78646108f25ff7183444ba507d76f9b05a34c8310e682c05495d0863ceff264964dbfa7c064adf6d26d2dca6e22ab13\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1b293c4f2a4955b07d4cf9cc1d45cc155d6bd2a769636d3db29854baaec92ab9ec084850b924e2cd6286b11e7fc09071d99e3a1729c2dfe94b26012\n\nSum = c590e57ee85427f08e8c89ffebfcc05c73370ad4cb77696c2b2f3878e6f6df341d4d931b5097aba49f14ac0312e7da1c843d6fd08119822e75e6e7a8c7bcb7b0\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 204591f038d1bd0df9200064d852185922827251e8123a7ba48f4e4c296d943de71ad69561129a9ac2052c9d5ebb92fde4eb7d91615e7dcee4c6caf\n\nSum = c590e57ee051ca1a363c47a4cc016c3de7f7e17985009b545528289e9fbc9086f4b42a73826eca0c278b0d1b4ef6d74b9a0bfcb7855d40fdb201fbad1074b927\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -5fe04b754c3268a406954183dba07d5b44ea6f2b785ec328cf159c866028f63efb7342f2178753e17d0b0071445b9e91d6d8957adcf041ec8fb91da\n\nSum = -c590e57edcd6e9ef06fe33f3817ba3d0c50c8122b77615c4b8fa50c5514f113d7ba53ce057d487bcbc373c4384d07b29a527b7ef785ca609474879b42a9a4c3a\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 978e4e284013a3b8aef1c8560a5682c81d92c8253b3c40bdb5ed911df117cf71a51767e8ccc4615e1f70c290929feb12a6e244c18888617aed5fec7\n\nSum = -c590e57f0436bdceb586a093522eb1630e0fc08f8790957aba1875a42b7676f9ca936e8f6f3478d6ef5cd590bf6ded0700440dcd769496822af8015f0a6ba2b6\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1de6eefd2a87326445c3f10ce85dd7404e415333ad6a60d2fec88caa6fdcb4b7fd0e7a9ba659533758a665b451f2572cd3c9cc2ccb27019330fb57b5\n\nSum = c590e57f1df3f004d5e49f49fa28603b26659f1fd35e0d8d7a2753591dbc12c51e6b588427dbe3faba2f0c1f2f0a2aea9ba1fcb2fe71c6ff40555058d23c8661\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 37a421334ae5311aedbd9fe500b3b5d09a0ecb466d793e87f10e2875c3b49eacb5b5e5bf712b89c5c842a397ed5046125ba6fca9e084508cf8cc3b60\n\nSum = c590e57e9a4abf4572fa7c4c9f73e9d3fd1227646fd6d15b51924bd7a5d417b01fe6b4273eaa6ece387422b81c8116f29702d7d66d2f6e8c3454807b3b7d413c\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -4c050f8c1804f1e26cf6d682289fc1eac97870ebbb1bc8f986d9d29f3ad005b0337b8f6d108f5fa14a467060174edeca359b5bc92b7c7f509df309c5\n\nSum = -c590e57e64216c306f17017ac9dd7085113e16c83168664dbb77c7ad3ddfc79b09f9ea0c474a0b497ca15e7fb258eed9666fd009f691a3b2d691c2c6b22ba3b3\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 822e62a11be86cb4428d4fd11473d28707e6dbf951364d23eece22b450bccfcb2adbf2f1cc6223d9b46e987947e1e696ac3926a2893f3d052744a74e\n\nSum = -c590e5806ab4d09773c4f94a4aac09f6ed7609eec1d0bafecb09e30f032f706e9adadc191ff9e6d7dccc821f7a8666a590e521749d24912c5a5ffeff246f7c85\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1846501c5e8c58b1b3e4149a0c7c4209f888178b7be5bce3dd681861f40242241add3e89c93c8ffc613bedf52e2936ad3fa59c6d6fa8eff334aff3184\n\nSum = c590e58248cbf5dd61ec57994fc862ab479dc6cda51cc17356c45cef66bbfdd12f5cc421940a561581c123fb17483beb7a1cce2596fa9ca76e722a6f4621eae9\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 3627c270bd6ece96a435da25521ebdd7e6bcd7f2c4a16481e3a0e1381d4a60a4a21e457da38bda1a1b080b498cbcb1784f42fd2520ea12aa36cb19fe8\n\nSum = c590e5771a85bdb1f26c0386ce837bec4b0af5656496efdf4f134d875f066dd6d477ca8f87ffb275da07da4dd1bed4232849a526836b47f2d69f2d53b6b3e2f1\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -7cbca111f98936aa83de74469daa6f3e9d4b85267bd9ac749cda77c78863eef47ea264bc56efba80b9508b32f8608117a1f5f82628931d27822bc6810\n\nSum = -c590e571c76afad23439f904e8a80fc28dcabb6cb732e361ed3eef471be6fa755e3fe746edbfe448c1f289ffed7dfc01fe9066d780564f57f93abbca9b9a995a\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = d1ee4d3ff56c5752a23c2b09397e72de2821c5ee51f6f258a10c6efd9fc76d290846619f28710f85979498b50afc14fc922747afd669644013dd5b1a7\n\nSum = -c590e598cd5d4a59ff5d6c97c6370fb517f1d492a7776f90063b0ddd6702e37c60fc78bb12857911cea37b7263584d7dc815676de6b8880200acea154b59b08b\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -19e70d7b88745dfe68b9cc4f5ef23feb436e282d48f98cf90c3a54f92d0645bee3a05f7ad6859ff918fc90c62b19c3b0cd43edbdaca0dbea4971e9658a\n\nSum = c590e5b5829e6fceb77830fbe999a98127b50302fd0f6a86ea4aea27b846747a07e6fcf5457676e6446137d6bdd8ff4fb7ca747b650b066d65d7dc1e172488e7\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 369c4ea0fd2c78c2ccdd2ee92b020319b3c3c0283fdd9cd5568b988a2aad30431dd35078aafb5db57d571177fd0978bddac2403c180606dc523db43de6\n\nSum = c590e52a3ab5d5c458634254e2f672a322000750741e969d2f6cd12d172480ad1455300e3a0575b068b85d50b58f9737be13073188d0f03b71494bd0fd2fea16\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -54ab99f90d329c2bda29744db303b1e1fec530aba9dd4143a4158969a2466189c93820888ae04b2508b137f01af03eaf6f19f9da19ee87b3fadc4060eb\n\nSum = -c590e4880579ef7241bde94e8c7847badc705f53828751f9975f0e66371d2ddff8740b143f32e88be8e686e2bf5a3ce03d864d7699a813b1777b9239af242c7d\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = f6e0d5df5f494184e07ff2789b494189fbb6c7f04d754f066af590bc6f6242aec332f315af601cfb76a76d4a7270cb692a0922b6a3e8556d922a4c1e84\n\nSum = -c590e6dbe54098694155509e38c61d503ab7e5237d2cdfc2b87fb57e3a8420fe37fe50a0dad4f0eae3d38fad6198e4ecaeae183a12078f53d09ac8099c715242\nA = -c590e5", "7ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -15cfef0c997b655e26f2c5b5cfa1505fbd443dd9d7babd1a0ad0dd636aedd4796c968aef2af9ad00d53fad15d9a005c61996f3cc4fe70c9c83dc3010741\n\nSum = c590e906254d013be2021ad591e76e26706a6815b8c484b6528fec65416e1066957002713e1183f1005f565983aad7aa031e549e6fc57094ca3e4383e7fdbc15\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 3873efd326a5702aca6857cadd04ab87ec67f75426f45e1d79414c026173ab94899cbeb85b5b75bd4001ce3505754cc9dfdccfaa63f6a6d43b80e8d7114\n\nSum = c590e0e0079190d7afd80acd6326fe93cc00903318608df31ee4493d11271dac7291bd142cca0e5dd7dda59dabd460a69b7855d9c2acb5f062de76665e07cbd7\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -49edebe3df9db276361a943c1c259b1591c20eeb453edc9cb941b86cca2e824fcc3455befdd7125dcbbbaf326ac12d960c6e01e1464fcf289657b687f2a\n\nSum = -c590d9ae456d66c1b132d844eb223867ba4560b36f53c42a616cf8cc657e6d252f813847fb9fc50127227684e5c0f5cd890eceb341d21e788e42f843e9b64080\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = bd0a0e2680fd9cc95ea214887ee6b6c889bc9fb7e1cab411c04c72f7d2a2b35818f7686393a21e10bd4810691852542e7ed60f8abdcd18e0787efba0a81\n\nSum = -c5910498291472fe1d0047d5bdd9e46deb3f26000e943fce8d83d700d9ae233ab3a28849bbb346803da142db6a471e9f79cd49571f40dbc46f7b727a4bb3016a\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1f1942c4a42c9200d9a6b16f2417c58d3cb0d544fd8780d5c22fad0038eb58ebce72498d4844f49dc082037f974ccb7b92b67c76116f0faa72ae7242b669\n\nSum = c59112d841ea109440e78563d9eefef201c81e86ae967083f8b7db80d1eaf58551d30519ca6dd79164fe69a29cf1ba22446cb2999f73292241005bf17b37528e\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 2d595b9a41c2b5e81734cd843e9bdc16353775472e3cec09c6afa53d0b35f71c4b425847d9561bfae749362a32cf961afbf8fca85ecce12f5c25a1c7078d\n\nSum = c590671f890ca06c74ac6d2c4d75aabeaaa55312e85a5e1ea9cef0e08e154e2b090eaba869e9f6e4a47ae10b9c1eb0f6ae4fb3ef12b3121d96066c6c8e592b6e\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -7e5f5d432e6516530102bef515977b0c963c50f4e42862df23f09e989c2451a80e2f083c0756a488a14dcaa8d65c000202b19017b837c9ca935f4b171f93\n\nSum = -c58ff0ae92ab03072154949a7143d45278ef77a0ba71a785d5a370e0d30a9b4b4f7e96a395d13e6afeebbd717365d471ee56ba11c472a63c0532558104bedfc5\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = f4d053a4cbca69aad9949b26ec03acc271ae7edd9ac1370aa3f059a34f040b382333dc54bfd04a17c4e7f361b2e0bffafc8ede5824195a9eaa4ad4b16b3c\n\nSum = -c5927a5fcc3b31abeca3998ad99c07626112288a6ad95b24929fed581040757fdce73881c48b02daf09986ea436a3f5ceb6833c31fa2e1691567601a26c7a6c9\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -194e0e5eb62da61a42b5bcd31470c3b603f3b318a18dd85f1d886e3928b3082307eaa5265049fa7960490dca2b80a3d167d227cd81713b596604e4d575bc8\n\nSum = c59395e94d495451e3fea153f3e4361a088004a7d5426c1b94aec44108ad6f5cecc3a80dda0cea9f51b882747258137e171bf021b4fc59f4dcf0106d4ba952fa\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 2b06a66f9858058ff3324e77975c3e2ce1b589bf329d48800af6fdbff850d920cee3667e6ec6408b5001b0b908c2b68ca398112318f9f7d1f10a1723907f9\n\nSum = c58bdb26c0fd6766f3affea389cbe7db25c06d5d56356d3d945347775bddf479ffc9e279e7d1ee88eddb239906749815ae4502fbbc6fe978a001ccdafd89cb10\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -50a582552676a974f6f8b829ed87afff17bf1e319d509785acd59d0cff5d55aecd75d8a540fb25b285ec06052ef3d000cb3a4e65ae0dcbfcf32f0dbe67ff1\n\nSum = -c581afe9b7ae86d4b7053f19649beea6cb935799a553f035f9b9a7fba6d5559e4ecdcd1637c73c8052c6cc52ee1c28d1e5aed9db7261b7356afd6e3dbc213684\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = f35952ea147fcd3fa2f15a7ced1af5a1e91b593fb521112f46cd585d894b10be8ecc13a5ec1baf63cb60678ab5e80c8a2dcc53069131ff4d3918e1d4f147d\n\nSum = -c5a19f36a65a6a8d52a53a63f99a1b957d6e376b7010ad14695d78d67b0d7c86881006188bd27bbf205c8c9c200dc8f5c08ab6b97dcd512f6cb93ed9a361ff9f\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -10b9b7c00a9bbbc7a5cc34ed2f5b3f57bc4e1c36c16acd5caf64054e5f92372d594c4119ac7d83d7590a42b94641a312390018db0286da0ce83f0dc9f1b49e\n\nSum = c5cd0e5da24b67a894402b0eee5dd586ab70e5beb0693e263a54995193663a9b770141379c1f097a49d1a889bbf0c348c6f40ed50bd7bdc11a7869c6106c6d80\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 3c28debbfb98d70940bcdfe1f3153085befc6f7719fbdf2da6848066b8504c1c4a876029f90b3f00ce263055293bf618a25834690cf36bbaa769fa36fc227f\n\nSum = c54e2c560a00226701b76cf03d5de27a8c69b38a6b85dad9f7c903d2e87f9a7d247522e72491460f6a529e5ca2aaaf690cb238b873ffb49d9fb0ecacfedd4e90\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -42b928dc4fac6a8948013ecf0cdddb994835c4cdc9676d14e510fe442e4fd2364196f04d94b82bdeb0e3fcc41cd7e9a19f7de82ecb15b7c020131eda92fc71\n\nSum = -c4bfb037f6e6e861efb090ee610c33e7568790259f747dc6e55d442aadd68c0cc93c7617f83980e8813c0fb7dd28c8aaca6ad8fdde5d2bfec9ae096faa9ef54e\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = d13546ef68e66f9b4edd40ab5e8c6ecf2a592999dac4802750d0a67ed75e42917a43bf79ec7d52c7c772a1899ebea7e3e6dda2c46d9e569622f65c2ed155b3\n\nSum = -c6aa2af8c9ae8be4aada83f66b7f31a8bce5e92c67d8938424a1405903e5502bffc4ee1e333da4bcfd0cb383b19a566372f877a8344b66dbceabc9786dd0e4f2\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1194579e35ebd131fdb15c75f1471529733ffdd2e89513d17f32b87d73765dca50e3446c117a681b409312a4ad2cf10c4a6c10791809c866edac9ac946099f1\n\nSum = c8aff66c9bdaa49eafac0f65d3ddff223b7a5471f7400431ca3a54615d600fc4a163f8fb648bddb5fd6915db1991611805040e0f86f152c8fd3333ef70d632e4\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = 31f10edb58ad5cd24aca136c7733ecc15c86b22bdf0c1eabd8c3f9030b2257546ad3f23f265df7ab4659381b2c9d9c556b2576ee42688739d6234239765e7e3\n\nSum = be1b6eb768e2cef388eebe31f9b21e51b38b351cc8175eba06d49eef04c2936f32167174dcb82297fd4180d0afb5da2c455d158c7a5bf01bdef8c295a4f20390\nA = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -77576c77d6cffde0210affd12b8a2047226b4327137e38d05d975e227eb56e028a04862956ddba34bc20188b711ad2668f4a114286eda3980d83d36347e4771\n\nSum = -ba32fca1d5cc5f31ecaf5407f376d3aef9f4abc04fd4c6893721d3e50e9141abf356eb2ff6f7a4f9b42983148670d2918e1dff7aa7ae33a6e9dadcb708b4f9dc\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = b5de8dd10836f9f9e501a2718f3eca72bbd3d8ee97a7bbdd58c40ec1e1ca8a3675fcea77b2e594194d9ff44e056b4c12033b725fb1c96ae75f62314d0bb5125\n\nSum = -e388afbf17c495f86aa7298a45f848eb57e5baaee42b1f7de8c2311bfbb8f74549712c05fd3bd11ab8874fb55abb22a37ba3512e733ecd5c472842e8e6f7b179\nA = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01\nB = -1df7ca403174c726dfa7bb5b398d88953233d15faadbdd36dc141c", @@ -2438,113 +2599,57 @@ static const char *kData40[] = { "fffffffffffffffffffff\nB = 1\n\nSum = 100000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 200000000000000000000000000000000000000000000000\nA = 1fffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 400000000000000000000000000000000000000000000000\nA = 3fffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 800000000000000000000000000000000000000000000000\nA = 7fffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 1000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 2000000000000000000000000000000000000000000000000\nA = 1ffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 4000000000000000000000000000000000000000000000000\nA = 3ffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 8000000000000000000000000000000000000000000000000\nA = 7ffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 10000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 20000000000000000000000000000000000000000000000000\nA = 1fffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 40000000000000000000000000000000000000000000000000\nA = 3fffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 80000000000000000000000000000000000000000000000000\nA = 7fffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffffff\nB = 1\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffffe\nB = 2\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffffc\nB = 4\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffff8\nB = 8\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffff0\nB = 10\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffffe0\nB = 20\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffffc0\nB = 40\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffff80\nB = 80\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffff00\nB = 100\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffe00\nB = 200\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffffc00\nB = 400\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffff800\nB = 800\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffff000\nB = 1000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffe000\nB = 2000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffffc000\nB = 4000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffff8000\nB = 8000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffff0000\nB = 10000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffe0000\nB = 20000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffffc0000\nB = 40000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffff80000\nB = 80000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffff00000\nB = 100000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffe00000\nB = 200000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffffc00000\nB = 400000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffff800000\nB = 800000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffff000000\nB = 1000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffe000000\nB = 2000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffffc000000\nB = 4000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffff8000000\nB = 8000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffff0000000\nB = 10000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffe0000000\nB = 20000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffffc0000000\nB = 40000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffff80000000\nB = 80000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffff00000000\nB = 100000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffe00000000\nB = 200000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffffc00000000\nB = 400000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffff800000000\nB = 800000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffff000000000\nB = 1000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffe000000000\nB = 2000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffffc000000000\nB = 4000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffff8000000000\nB = 8000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffff0000000000\nB = 10000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffe0000000000\nB = 20000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffffc0000000000\nB = 40000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffff80000000000\nB = 80000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffff00000000000\nB = 100000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffe00000000000\nB = 200000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffffc00000000000\nB = 400000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffff800000000000\nB = 800000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffff000000000000\nB = 1000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffe000000000000\nB = 2000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffffc000000000000\nB = 4000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffff8000000000000\nB = 8000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffff0000000000000\nB = 10000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffff", "fffffffffffffffffffffe0000000000000\nB = 20000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffffc0000000000000\nB = 40000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffff80000000000000\nB = 80000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffff00000000000000\nB = 100000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffe00000000000000\nB = 200000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffffc00000000000000\nB = 400000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffff800000000000000\nB = 800000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffff000000000000000\nB = 1000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffe000000000000000\nB = 2000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffffc000000000000000\nB = 4000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffff8000000000000000\nB = 8000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffff0000000000000000\nB = 10000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffe0000000000000000\nB = 20000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffffc0000000000000000\nB = 40000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffff80000000000000000\nB = 80000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffff00000000000000000\nB = 100000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffe00000000000000000\nB = 200000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffffc00000000000000000\nB = 400000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffff800000000000000000\nB = 800000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffff000000000000000000\nB = 1000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffe000000000000000000\nB = 2000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffffc000000000000000000\nB = 4000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffff8000000000000000000\nB = 8000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffff0000000000000000000\nB = 10000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffe0000000000000000000\nB = 20000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffffc0000000000000000000\nB = 40000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffff80000000000000000000\nB = 80000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffff00000000000000000000\nB = 100000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffe00000000000000000000\nB = 200000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffffc00000000000000000000\nB = 400000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffff800000000000000000000\nB = 800000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffff000000000000000000000\nB = 1000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffe000000000000000000000\nB = 2000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffffc000000000000000000000\nB = 4000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffff8000000000000000000000\nB = 8000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffff0000000000000000000000\nB = 10000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffe0000000000000000000000\nB = 20000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffffc0000000000000000000000\nB = 40000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffff80000000000000000000000\nB = 80000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffff00000000000000000000000\nB = 100000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffe00000000000000000000000\nB = 200000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffffc00000000000000000000000\nB = 400000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffff800000000000000000000000\nB = 800000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffff000000000000000000000000\nB = 1000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffe000000000000000000000000\nB = 2000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffffc000000000000000000000000\nB = 4000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffff8000000000000000000000000\nB = 8000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffff0000000000000000000000000\nB = 10000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffe0000000000000000000000000\nB = 20000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffffc0000000000000000000000000\nB = 40000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffff80000000000000000000000000\nB = 80000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffff00000000000000000000000000\nB = 100000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffe00000000000000000000000000\nB = 200000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffffc00000000000000000000000000\nB = 400000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffff800000000000000000000000000\nB = 800000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffff000000000000000000000000000\nB = 1000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffe000000000000000000000000000\nB = 2000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffffc000000000000000000000000000\nB = 4000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffff8000000000000000000000000000\nB = 8000000000000000000000000000\n\nSu", "m = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffff0000000000000000000000000000\nB = 10000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffe0000000000000000000000000000\nB = 20000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffffc0000000000000000000000000000\nB = 40000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffff80000000000000000000000000000\nB = 80000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffff00000000000000000000000000000\nB = 100000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffe00000000000000000000000000000\nB = 200000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffffc00000000000000000000000000000\nB = 400000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffff800000000000000000000000000000\nB = 800000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffff000000000000000000000000000000\nB = 1000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffe000000000000000000000000000000\nB = 2000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffffc000000000000000000000000000000\nB = 4000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffff8000000000000000000000000000000\nB = 8000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffff0000000000000000000000000000000\nB = 10000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffe0000000000000000000000000000000\nB = 20000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffffc0000000000000000000000000000000\nB = 40000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffff80000000000000000000000000000000\nB = 80000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffff00000000000000000000000000000000\nB = 100000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffe00000000000000000000000000000000\nB = 200000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffffc00000000000000000000000000000000\nB = 400000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffff800000000000000000000000000000000\nB = 800000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffff000000000000000000000000000000000\nB = 1000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffe000000000000000000000000000000000\nB = 2000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffffc000000000000000000000000000000000\nB = 4000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffff8000000000000000000000000000000000\nB = 8000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffff0000000000000000000000000000000000\nB = 10000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffe0000000000000000000000000000000000\nB = 20000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffffc0000000000000000000000000000000000\nB = 40000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffff80000000000000000000000000000000000\nB = 80000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffff00000000000000000000000000000000000\nB = 100000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffe00000000000000000000000000000000000\nB = 200000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffffc00000000000000000000000000000000000\nB = 400000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffff800000000000000000000000000000000000\nB = 800000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffff000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffe000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffffc000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffff8000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffff0000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffe0000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffffc0000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffff80000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffff00000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffe00000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffffc00000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffff800000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffff000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffe000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffffc000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffff8000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffff0000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffe0000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffffc0000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffff80000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffff00000000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000000\n\nSum = 1000000000000000000", - "00000000000000000000000000000000\nA = ffffffffe00000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffc00000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffff800000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffff000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffe000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffc000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffff8000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffff0000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffe0000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffc0000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffff80000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffff00000000000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffe00000000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffc00000000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffff800000000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffff000000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffe000000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffc000000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffff8000000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffff0000000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffe0000000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffc0000000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fff80000000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fff00000000000000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffe00000000000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffc00000000000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ff800000000000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ff000000000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fe000000000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fc000000000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = f8000000000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = f0000000000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = e0000000000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = c0000000000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = 80000000000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000000000\n\n\n# LShift1 tests.\n#\n# These test vectors satisfy A * 2 = LShift1\n\nLShift1 = 0\nA = 0\n\nLShift1 = 13116120bca5df64e13f314254\nA = 988b0905e52efb2709f98a12a\n\nLShift1 = -13116120bca5df64e13f314254\nA = -988b0905e52efb2709f98a12a\n\nLShift1 = 2622c241794bbec9c27e6284a8\nA = 13116120bca5df64e13f314254\n\nLShift1 = -2622c241794bbec9c27e6284a8\nA = -13116120bca5df64e13f314254\n\nLShift1 = 4c458482f2977d9384fcc50950\nA = 2622c241794bbec9c27e6284a8\n\nLShift1 = -4c458482f2977d9384fcc50950\nA = -2622c241794bbec9c27e6284a8\n\nLShift1 = 988b0905e52efb2709f98a12a2\nA = 4c458482f2977d9384fcc50951\n\nLShift1 = -988b0905e52efb2709f98a12a2\nA = -4c458482f2977d9384fcc50951\n\nLShift1 = 13116120bca5df64e13f3142544\nA = 988b0905e52efb2709f98a12a2\n\nLShift1 = -13116120bca5df64e13f3142544\nA = -988b0905e52efb2709f98a12a2\n\nLShift1 = 2622c241794bbec9c27e6284a8a\nA = 13116120bca5df64e13f3142545\n\nLShift1 = -2622c241794bbec9c27e6284a8a\nA = -13116120bca5df64e13f3142545\n\nLShift1 = 4c458482f2977d9384fcc509514\nA = 2622c241794bbec9c27e6284a8a\n\nLShift1 = -4c458482f2977d9384fcc509514\nA = -2622c241794bbec9c27e6284a8a\n\nLShift1 = 988b0905e52efb2709f98a12a28\nA = 4c458482f2977d9384fcc509514\n\nLShift1 = -988b0905e52efb2709f98a12a28\nA = -4c458482f2977d9384fcc509514\n\nLShift1 = 13116120bca5df64e13f31425450\nA = 988b0905e52efb2709f98a12a28\n\nLShift1 = -13116120bca5df64e13f31425450\nA = -988b0905e52efb2709f98a12a28\n\nLShift1 = 2622c241794bbec9c27e6284a8a0\nA = 13116120bca5df64e13f31425450\n\nLShift1 = -2622c241794bbec9c27e6284a8a0\nA = -13116120bca5df64e13f31425450\n\nLShift1 = 4c458482f2977d9384fcc5095142\nA = 2622c241794bbec9c27e6284a8a1\n\nLShift1 = -4c458482f2977d9384fcc5095142\nA = -2622c241794bbec9c27e6284a8a1\n\nLShift1 = 988b0905e52efb2709f98a12a286\nA = 4c458482f2977d9384fcc5095143\n\nLShift1 = -988b0905e52efb2709f98a12a286\nA = -4c458482f2977d9384fcc5095143\n\nLShift1 = 13116120bca5df64e13f31425450c\nA = 988b0905e52efb2709f98a12a286\n\nLShift1 = -13116120bca5df64e13f31425450c\nA = -988b0905e52efb2709f98a12a286\n\nLShift1 = 2622c241794bbec9c27e6284a8a18\nA = 13116120bca5df64e13f31425450c\n\nLShift1 = -2622c241794bbec9c27e6284a8a18\nA = -13116120bca5df64e13f31425450c\n\nLShift1 = 4c458482f2977d9384fcc50951430\nA = 2622c241794bbec9c27e6284a8a18\n\nLShift1 = -4c458482f2977d9384fcc50951430\nA = -2622c241794bbec9c27e6284a8a18\n\nLShift1 = 988b0905e52efb2709f98a12a2862\nA = 4c458482f2977d9384fcc50951431\n\nLShift1 = -988b0905e52efb2709f98a12a2862\nA = -4c458482f2977d9384fcc50951431\n\nLShift1 = 13116120bca5df6", - "4e13f31425450c6\nA = 988b0905e52efb2709f98a12a2863\n\nLShift1 = -13116120bca5df64e13f31425450c6\nA = -988b0905e52efb2709f98a12a2863\n\nLShift1 = 2622c241794bbec9c27e6284a8a18e\nA = 13116120bca5df64e13f31425450c7\n\nLShift1 = -2622c241794bbec9c27e6284a8a18e\nA = -13116120bca5df64e13f31425450c7\n\nLShift1 = 4c458482f2977d9384fcc50951431e\nA = 2622c241794bbec9c27e6284a8a18f\n\nLShift1 = -4c458482f2977d9384fcc50951431e\nA = -2622c241794bbec9c27e6284a8a18f\n\nLShift1 = 988b0905e52efb2709f98a12a2863c\nA = 4c458482f2977d9384fcc50951431e\n\nLShift1 = -988b0905e52efb2709f98a12a2863c\nA = -4c458482f2977d9384fcc50951431e\n\nLShift1 = 13116120bca5df64e13f31425450c7a\nA = 988b0905e52efb2709f98a12a2863d\n\nLShift1 = -13116120bca5df64e13f31425450c7a\nA = -988b0905e52efb2709f98a12a2863d\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4\nA = 13116120bca5df64e13f31425450c7a\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4\nA = -13116120bca5df64e13f31425450c7a\n\nLShift1 = 4c458482f2977d9384fcc50951431e8\nA = 2622c241794bbec9c27e6284a8a18f4\n\nLShift1 = -4c458482f2977d9384fcc50951431e8\nA = -2622c241794bbec9c27e6284a8a18f4\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2\nA = 4c458482f2977d9384fcc50951431e9\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2\nA = -4c458482f2977d9384fcc50951431e9\n\nLShift1 = 13116120bca5df64e13f31425450c7a4\nA = 988b0905e52efb2709f98a12a2863d2\n\nLShift1 = -13116120bca5df64e13f31425450c7a4\nA = -988b0905e52efb2709f98a12a2863d2\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4a\nA = 13116120bca5df64e13f31425450c7a5\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4a\nA = -13116120bca5df64e13f31425450c7a5\n\nLShift1 = 4c458482f2977d9384fcc50951431e94\nA = 2622c241794bbec9c27e6284a8a18f4a\n\nLShift1 = -4c458482f2977d9384fcc50951431e94\nA = -2622c241794bbec9c27e6284a8a18f4a\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2a\nA = 4c458482f2977d9384fcc50951431e95\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2a\nA = -4c458482f2977d9384fcc50951431e95\n\nLShift1 = 13116120bca5df64e13f31425450c7a56\nA = 988b0905e52efb2709f98a12a2863d2b\n\nLShift1 = -13116120bca5df64e13f31425450c7a56\nA = -988b0905e52efb2709f98a12a2863d2b\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4ae\nA = 13116120bca5df64e13f31425450c7a57\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4ae\nA = -13116120bca5df64e13f31425450c7a57\n\nLShift1 = 4c458482f2977d9384fcc50951431e95c\nA = 2622c241794bbec9c27e6284a8a18f4ae\n\nLShift1 = -4c458482f2977d9384fcc50951431e95c\nA = -2622c241794bbec9c27e6284a8a18f4ae\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2ba\nA = 4c458482f2977d9384fcc50951431e95d\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2ba\nA = -4c458482f2977d9384fcc50951431e95d\n\nLShift1 = 13116120bca5df64e13f31425450c7a576\nA = 988b0905e52efb2709f98a12a2863d2bb\n\nLShift1 = -13116120bca5df64e13f31425450c7a576\nA = -988b0905e52efb2709f98a12a2863d2bb\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aee\nA = 13116120bca5df64e13f31425450c7a577\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aee\nA = -13116120bca5df64e13f31425450c7a577\n\nLShift1 = 4c458482f2977d9384fcc50951431e95de\nA = 2622c241794bbec9c27e6284a8a18f4aef\n\nLShift1 = -4c458482f2977d9384fcc50951431e95de\nA = -2622c241794bbec9c27e6284a8a18f4aef\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbc\nA = 4c458482f2977d9384fcc50951431e95de\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbc\nA = -4c458482f2977d9384fcc50951431e95de\n\nLShift1 = 13116120bca5df64e13f31425450c7a577a\nA = 988b0905e52efb2709f98a12a2863d2bbd\n\nLShift1 = -13116120bca5df64e13f31425450c7a577a\nA = -988b0905e52efb2709f98a12a2863d2bbd\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef4\nA = 13116120bca5df64e13f31425450c7a577a\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef4\nA = -13116120bca5df64e13f31425450c7a577a\n\nLShift1 = 4c458482f2977d9384fcc50951431e95dea\nA = 2622c241794bbec9c27e6284a8a18f4aef5\n\nLShift1 = -4c458482f2977d9384fcc50951431e95dea\nA = -2622c241794bbec9c27e6284a8a18f4aef5\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6\nA = 4c458482f2977d9384fcc50951431e95deb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6\nA = -4c458482f2977d9384fcc50951431e95deb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ac\nA = 988b0905e52efb2709f98a12a2863d2bbd6\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ac\nA = -988b0905e52efb2709f98a12a2863d2bbd6\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5a\nA = 13116120bca5df64e13f31425450c7a577ad\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5a\nA = -13116120bca5df64e13f31425450c7a577ad\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb4\nA = 2622c241794bbec9c27e6284a8a18f4aef5a\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb4\nA = -2622c241794bbec9c27e6284a8a18f4aef5a\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6a\nA = 4c458482f2977d9384fcc50951431e95deb5\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6a\nA = -4c458482f2977d9384fcc50951431e95deb5\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad6\nA = 988b0905e52efb2709f98a12a2863d2bbd6b\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad6\nA = -988b0905e52efb2709f98a12a2863d2bbd6b\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5ae\nA = 13116120bca5df64e13f31425450c7a577ad7\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5ae\nA = -13116120bca5df64e13f31425450c7a577ad7\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5e\nA = 2622c241794bbec9c27e6284a8a18f4aef5af\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5e\nA = -2622c241794bbec9c27e6284a8a18f4aef5af\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6be\nA = 4c458482f2977d9384fcc50951431e95deb5f\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6be\nA = -4c458482f2977d9384fcc50951431e95deb5f\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7e\nA = 988b0905e52efb2709f98a12a2863d2bbd6bf\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7e\nA = -988b0905e52efb2709f98a12a2863d2bbd6bf\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5afe\nA = 13116120bca5df64e13f31425450c7a577ad7f\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5afe\nA = -13116120bca5df64e13f31425450c7a577ad7f\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5fe\nA = 2622c241794bbec9c27e6284a8a18f4aef5aff\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5fe\nA = -2622c241794bbec9c27e6284a8a18f4aef5aff\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bfe\nA = 4c458482f2977d9384fcc50951431e95deb5ff\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bfe\nA = -4c458482f2977d9384fcc50951431e95deb5ff\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc\nA = 13116120bca5df64e13f31425450c7a577ad7fe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc\nA = -13116120bca5df64e13f31425450c7a577ad7fe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff8\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff8\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff0\nA = 4c458482f2977d9384fcc50951431e95deb5ff8\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff0\nA = -4c458482f2977d9384fcc50951431e95deb5ff8\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff0\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff0\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc0\nA = 13116120bca5df64e13f31425450c7a577ad7fe0\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc0\nA = -13116120bca5df64e13f31425450c7a577ad7fe0\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff82\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff82\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06\nA = 4c458482f2977d9384fcc50951431e95deb5ff83\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06\nA = -4c458482f2977d9384fcc50951431e95deb5ff83\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0c\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0c\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1a\nA = 13116120bca5df64e13f31425450c7a577ad7fe0d\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1a\nA = -13116120bca5df64e13f31425450c7a577ad7fe0d\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b", - "\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06c\nA = 4c458482f2977d9384fcc50951431e95deb5ff836\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06c\nA = -4c458482f2977d9384fcc50951431e95deb5ff836\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0da\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06d\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0da\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06d\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b6\nA = 13116120bca5df64e13f31425450c7a577ad7fe0db\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b6\nA = -13116120bca5df64e13f31425450c7a577ad7fe0db\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836e\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836e\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06de\nA = 4c458482f2977d9384fcc50951431e95deb5ff836f\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06de\nA = -4c458482f2977d9384fcc50951431e95deb5ff836f\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7c\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7c\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fa\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7d\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fa\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7d\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbec\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbec\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7da\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7da\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb6\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb6\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb6\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb6\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed82\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed82\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed83\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed83\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed832\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed832\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60ce\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60ce\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cf\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cf\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e\nA = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf\n\nLShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\nA = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f\n\nLShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\nA = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f\n\nLShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\nA = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\n\nLShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\nA = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe\n\nLShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\nA = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\n\nLShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\nA = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc\n\nLShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0\nA = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8\n\nLShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0\nA = -4c458482f2977d9384fcc50951431e95deb5ff8", - "36fb60cfbf8\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000", - "00\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000\n\nLShift1 = 2ad3a0392d595", - "5b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\nA = 55a740725ab2ab6cc884759e59af", - "8be8d741ed19da09c30c838000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000\n\nLShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\nA = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\n\nLShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\nA = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000\n\nLShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\nA = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\n\nLShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\nA = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000\n\nLShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\nA = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\n\nLShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\nA = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000\n\nLShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000\nA = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\n\nLShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000\nA = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000\n\n\n# LShift tests\n#\n# These test vectors satisfy A * 2^N = LShift.\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 6\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 7\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 8\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 9\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 10\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 11\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 12\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 13\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 14\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 15\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 16\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 17\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 18\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 19\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 1f\n\nLShif", - "t = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 20\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 21\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 22\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 23\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 24\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 25\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 26\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 27\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 28\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 29\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 2f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 30\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 31\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 32\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 33\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 34\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 35\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 36\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 37\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 38\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 39\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 3f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 40\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 41\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 42\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 43\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 44\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 45\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 46\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 47\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 48\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 49\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4a\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 4f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 50\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 51\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 52\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 53\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 54\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 55\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 56\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 57\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 58\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 59\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5a\n\nLShift = 6327a1821", - "57565372c1b402df464cd822ea41b617e8b64b27800000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5b\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5c\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5d\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5e\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 5f\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 60\n\nLShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 61\n\nLShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 62\n\nLShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 63\n\nLShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000000\nA = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0\nN = 64\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 6\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 7\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 8\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 9\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 10\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 11\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 12\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 13\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 14\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 15\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 16\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 17\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 18\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 19\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 1f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 20\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 21\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 22\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 23\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 24\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 25\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 26\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 27\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 28\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 29\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 2f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 30\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 31\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 32\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 33\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN", - " = 34\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 35\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 36\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 37\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 38\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 39\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 3f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 40\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 41\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 42\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 43\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 44\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 45\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 46\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 47\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 48\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 49\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 4f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 50\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 51\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 52\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 53\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 54\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 55\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 56\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 57\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 58\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 59\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5a\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5b\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5c\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5d\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5e\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 5f\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 60\n\nLShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 61\n\nLShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 62\n\nLShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 63\n\nLShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000000\nA = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e\nN = 64\n\n\n# RShift tests\n#\n# These test vectors satisfy A / 2^N = RShift, rounding towards zero.\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36380\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c70\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3638\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 6\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 7\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c7\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 8\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b363\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 9\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403", - "565b365ecd8\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 10\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 11\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 12\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ec\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 13\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f6\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 14\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 15\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 16\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365e\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 17\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 18\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 19\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cb\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b36\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 1f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 20\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 21\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 22\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b3\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 23\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 24\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 25\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb6\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 26\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 27\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 28\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d596\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 29\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806acb\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d59\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806ac\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5740356\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 2f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01ab\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 30\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d5\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 31\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 32\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa574035\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 33\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 34\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 35\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae806\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 36\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57403\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 37\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba01\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 38\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d00\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 39\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae80\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5740\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3b\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d0\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3d\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae8\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa574\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 3f\n\nRShift = d9ce8dff4f2f39c216ea39a461080552ba\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 40\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95d\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 41\n\nRShift = 3673a37fd3cbce7085ba8e6918420154ae\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 42\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa57\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 43\n\nRShift = d9ce8dff4f2f39c216ea39a461080552b\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 44\n\nRShift = 6ce746ffa7979ce10b751cd2308402a95\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 45\n\nRShift = 3673a37fd3cbce7085ba8e6918420154a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 46\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa5\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 47\n\nRShift = d9ce8dff4f2f39c216ea39a461080552\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 48\n\nRShift = 6ce746ffa7979ce10b751cd2308402a9\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 49\n\nRShift = 3673a37fd3cbce7085ba8e6918420154\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4a\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100aa\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4b\n\nRShift = d9ce8dff4f2f39c216ea39a46108055\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4c\n\nRShift = 6ce746ffa7979ce10b751cd2308402a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4d\n\nRShift = 3673a37fd3cbce7085ba8e691842015\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100a\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 4f\n\nRShift = d9ce8dff4f2f39c216ea39a4610805\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 50\n\nRShift = 6ce746ffa7979ce10b751cd2308402\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 51\n\nRShift = 3673a37fd3cbce7085ba8e69184201\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 52\n\nRShift = 1b39d1bfe9e5e73842dd47348c2100\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 53\n\nRShift = d9ce8dff4f2f39c216ea39a461080\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\n", - "N = 54\n\nRShift = 6ce746ffa7979ce10b751cd230840\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 55\n\nRShift = 3673a37fd3cbce7085ba8e6918420\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 56\n\nRShift = 1b39d1bfe9e5e73842dd47348c210\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 57\n\nRShift = d9ce8dff4f2f39c216ea39a46108\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 58\n\nRShift = 6ce746ffa7979ce10b751cd23084\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 59\n\nRShift = 3673a37fd3cbce7085ba8e691842\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5a\n\nRShift = 1b39d1bfe9e5e73842dd47348c21\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5b\n\nRShift = d9ce8dff4f2f39c216ea39a4610\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5c\n\nRShift = 6ce746ffa7979ce10b751cd2308\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5d\n\nRShift = 3673a37fd3cbce7085ba8e69184\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5e\n\nRShift = 1b39d1bfe9e5e73842dd47348c2\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 5f\n\nRShift = d9ce8dff4f2f39c216ea39a461\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 60\n\nRShift = 6ce746ffa7979ce10b751cd230\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 61\n\nRShift = 3673a37fd3cbce7085ba8e6918\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 62\n\nRShift = 1b39d1bfe9e5e73842dd47348c\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 63\n\nRShift = d9ce8dff4f2f39c216ea39a46\nA = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701\nN = 64\n\n\n# Square tests.\n#\n# These test vectors satisfy A^2 = Square.\n\n# Regression test for a BN_sqr overflow bug.\nSquare = 4000000000000000800000000000000240000000000000000000000000000001fffffffffffffff8000000000000000400000000000000000000000000000000\nA = 80000000000000008000000000000001fffffffffffffffe0000000000000000\n\n# Regression test for a BN_sqr overflow bug.\nSquare = 40000000000000000000000080000001fffffffe000000004000000200000001fffffff800000004000000000000000000000000000000000000000000000000\nA = 80000000000000000000000080000001fffffffe000000000000000000000000\n\nSquare = c2fa18e1d110a4639781\nA = -df6a253c3f\n\nSquare = 4805f01d379f4ce8dc86ed269\nA = 21f253ddb5a6d\n\nSquare = 57def107babc1c2bffeff858947e69\nA = -95fbaee5a09c86d\n\nSquare = f3b01f7941961b3f5cc3361e3ac82423690\nA = -3e71292dd4ad3ed3b4\n\nSquare = 5e2d9c36d498ad1e8b6113f442ac513eaca74601\nA = 9b45cf6c7a43d910dcff\n\nSquare = 7b7c2eb3fe55615e422b41c6f725341527626398cdee4\nA = 2c7314e72a2ffeef170de2a\n\nSquare = af57c0ed328886642ed5d631b375fc89c03a99f1b427c6bbd1\nA = d3de077f8286a04daa9c497c9\n\nSquare = 4d9eac3058e6cbc0d12e639ced961c02ec1870afed62fdd44c67ce4\nA = -233da7e87ea4421ee8fe7e00c856\n\nSquare = 83c292d277fae28cfede74e8e80eba11dc132e16f78cdf64595c12c7dee4\nA = -b7a8aa7452678abd45d2ae6c349e2a\n\nSquare = c80e07dd01f9d19a5cf7f3c328ccf4de70fdd113de69382701294dd29674b9a90\nA = 389387eead58fef2c76b5cf920f35c5cc\n\nSquare = b9f69ca47ac855830fd7ed39c81822c520880c51c3ea60d3ccc106db37fc2b04c47831\nA = -da307c28ea67ca8d3117364ba93f0731bf9\n\nSquare = 81bbe3a13a22a73778233294ba0c132d9dddec111f768300f177468c204f8eab69b98e62d99\nA = -2d8f715bb32d410b4f475c4d000d56fec7cfc5\n\nSquare = f815ce34e9bc2e31e36e75cf49b2d15306d438a2a713b2a85b3ea156ba60c867c28cc65aa58fdf11\nA = fc02f2e1a26cd69f6a0e54cca4bbced739b43597\n\nSquare = 5f968707f58ea15c492ec9677be09c309d91164aafa754ab16ca47a411b5b2249858fb6f96135992e8a04\nA = 271b8eae3e96cc4900d4413d6c00b73736a5d89ed7e\n\nSquare = 4aa616aabcdc7ad48dcfd40d71e00a3789bbf549ff39b3e2ebb52017cb56014941961a5a6d52d7a9980fc99b49\nA = 8a3d3f15e6d7d2130aebd8cb99767defbe4c7704e3c1d\n\nSquare = 845e46db8c40f3f6f6f4928b5748618f021f9064c6522bcf2df004f8d2105e90cd354785c15a6cc32fcc77da2ea3001\nA = -2e0543ac8b8255ce30253cf2047a0ff353dea55a58551801\n\nSquare = 5dc5706dde9b326feb79941f08bd296ec3b6fb67270516b70fad9921438b9175f395310fb756b60d72d8e73e84ee8673cc40\nA = -9aefd7dfa709dec9e721f5c22867229435b2d6366462d0e438\n\nSquare = 63dc6565adba27974a66bdcc626596e16cf399541d679f754d9063ceeb320649bec09a940309dd1eae5fbba0b558939afae9689c9\nA = 27f8e071f70b0053d70eca9c6d1e28303b8da2d3c58083c2cc45d\n\nSquare = cf2176449bb8b215fc37288b904ca27d5d410780fd054d2a190a94b405f6aa41970b41ba3cc43eaabb97c2248e1e21457949070ec0f6a4\nA = -e645c7edc27512d4b3170d3c5430d0712a25c13afcc09c9b30bb11a\n\nSquare = 43194e5f12e828db6735824c194985108269ddec12c49a14658be3c2b7d298c2846da1aa3ecb7064e73c317af595601de59035faab6dc0fd911\nA = -20c3fb73a03217893fd4a9db6e53a3d83a8414d900213d0460dc91bf69\n\nSquare = fcee79e598f061157ca9416491f2eb069bb95a4d78a1d0538dab5c8008653db71b90ce3139e693ba284846be7b75d6b7aa80228420fe75599c12f090\nA = fe760dd61798c8f78e52b328fa27cfbe41b898de6e6bb4f4a684f038b5f4\n\nSquare = 4f0db9f9e6eff9fe7fc938f6d6f5e4fb017ffea0cea0f7c57f4fc1e5b2bdc00a1cb9c1e6c865e53309b6b73c4339b0bd485860ca9edde3019804902da6b61\nA = 23909968dd5d139994fe9baa0a7bbfa009b013df3859ff294c5872366eb7ecf\n\nSquare = 4441ff36d785d18208481470a5b8ba8cd65a45436c39190dde0b8a2b7d00bf67b185d98ab5c4a7853423778d6333abf6b115dc9567a9f9c71916d3f9db3af82c41\nA = 84307277f79cfdf33d83d7093f1fd8aeb94499a7075ca32733b68fcf88e819421\n\nSquare = 50ee0dba369b0fb61d75706652487ca08043eee712ebb51399122353f77f13745ce2ef0d8f0ea7b3fd94e928b0b2b42c2c9141b5697b13b6d1f3d66c6a9186625b87e40\nA = -23fc02d45c820c3a4250124cc457fa3886beabb41d3c1e26f711309604eb253c6da8\n\nSquare = da11876b316d4891a2d650692ca776f77afd32a1db08f591c9579fd1053a4a46cf78b4e4cf417eb99eb067ff701dbe3483dff22e7878d2ef2b234244cf7a29d93f62d6d6b611\nA = -ec463653389de3689fe1881679b83ca65134a1498a3543168dd4833a51b23edd3fb617\n\nSquare = b342b4aff7e5bad38f7f532f0f32a3672f7ea6521d23652fa09ef7aeffcffe52f056ab1b54a0f3a2147f43330fd199d1f290988c866f61360dc4928c84b3dcde8f395120008472100\nA = 358e27805e2a56195fab2ccbe3f931a4bd14023ee56c8a191697926f387c40decc578cef0\n\nSquare = bf4045fd680caa514e9c410fb4404e5e3a381abee023d5b509d6dc0b97386421f55090af8bab5ac08e9b2eb8a36a64c55960be9179d564c5429f4ec595d03d12111defafb7359b418902b1\nA = -dd450a0fa0914f0d65a1b555baaaf9380eaf8d58b272bf9d95435bad53b01337ac8de562cc7\n\nSquare = 86abcdf183ca059257c2f6bb91efc9853f4ab42801d3cde88df72d4c904be184e93d6bd1af6fc21a6836c93c4e0a1f728b3722d568572f7ade418274ef2e6ac3463c5cc50990f1017e01cfb91a9\nA = -2e6b4d9eeede7a72b8d0fcf6429c7e30cf291352e1bb43e92c14236716aadc02c02f75c7e6aa8d\n\nSquare = d5f37112733b097cab2bb11daa3d9481255060abd7bce42b752a7641a98e140922c375fcb68bf13d4326b374eabe3b01de0f8f6324b7b3e4142051c02d2f18ae2e748cf3c4bcc3fe157bc94227631d21\nA = ea087236372fbb01b80e57b1ae4edeeaa776355457e18165a5dc60ef4b6ddc0b127ef494dc44ae11\n\nSquare = 9e4db7885fa5f928ef236f99df3e7c8d17a5a21983ff882032817edd5658575f443eb9c5c97d95ee798a3809cda76d7a0ab9fde757a310e2f5cbb299ab88e92a5771027ab9f26816c02d0c97894da5976ec90\nA = 3253d712d4ada4c12dab41036fcf79b02e80d1a632ff6ccc44d3c1d08467a019cd6221507459b231c8c\n\nSquare = cf9c50ee8773ba94c9e943989a35513fc370adc3622beb125252bb92ff9b258b81a497700e3bb15bcb23a5b3082c095f7a5d6eef20433d689c20a5427b661d43fb0f9b7d1b16d1b73b8fd59ed319a26c5eb92fce90\nA = e68a0812d2de2a922f24c4e63b4c33e62f93943b7673e900d12405dedd0bc2a906daf8b4bc336bdeb52b4\n\nSquare = f3aa49c906844692d3bc0cf101adcba80351c2e744be01762a8c24804a9d8d5a4cc3c113ccf529eb79cb3304aefa74178afa53f235c5211192d4cd8610c3b42e246621acb3e5d1f9d86ff39a20a7fa9c568356de5b86919\nA = -3e7069ce11472563b0dbeb9a936884df66db83273a690c40e5d3b5f8926fb502d3988591abfaea7b7bd76a85\n\nSquare = 7c9a5057ca8095cdfa289b2d60eec80548f9ab2f3a996137ff9be403b529c4672e003d1eb074c76c0086e3d875cfbc90a40ccb61b799cc0401ba160d8d6b6ee46b2f14ed31c83de54cdf83458dcfc01e3234d9717b5f2c7e5079\nA = -b299da84ef84095d8191fd1cfe847b960729a3d1857082f05b2fa30ac45e90d2fdc778013b023f38db2c8e780b\n\nSquare = 488294b528e2c2da0145217ec69de2d021ca27f145f7321f06c03316fcc14bd4a9a900bd6a144086acad6d5ad32a6245f5a655e007742aa336430c6bfbe174278884d19fd93916ef57215069268ade899cb92dfed29628327b84d8240\nA = 220fa6eaae0238e78a91e43fd8c2fbd5db0c8501cb96d66265c8edcbd376814c39e4a6f21ec9a6472c6abe8c04818\n\nSquare = ebd685edd991dd5180706b72ce20ec4f6c5d9ce038cc8768f2ae2d0e676bd549d6d3f97f6c26f6e36bb664e8a7e6102192bccb354c024670085711db30159c6b7badab7c7c0b91925675ece3e23126ea6feaa28e977598a890e4e476ead100\nA = -f5b657cc3", - "8fd11ad2f1b188c61721b5ec6c9762c09dcbfac3edc1f07e675bc058e77eacd01a2b4139b1b00c40a6cb70\n\nSquare = d1b3ac1d7042c0200f80a989e053dee31cdddc835889a57482a0988afd82b0fe8d3667270a72967401c3e8d80dae349ccd4063f11cb24dd7f9a5aeaaa7c0bd7bf7991367b0d7b4d374dc9c5017da81ba39fadfc3b760f68da95ae1eaa2eea3fb040\nA = -39eca1bf5e4807fd6a9ccc9e3138a6fb390b10a330f0027f0ba9868beb77c93160b623de58054a4522183fb3e4e2d86b08\n\nSquare = 41c5e4bc851d48673e0a16336f0decbcb59dad36959b310cd1a042d24de00c587db47058c2d91d7f9982bdbf470c73f86e591a122b3fda71796e465513e10e3cdbd5e6bf035595644d588c091e23a57cc47b5173743b0dca965902918d61875f88735a59\nA = 81c2caee75e98f1822c854448302243feec55a5247bba948647f12d7e0bcde4b1dd6af63eb1ef948eec22a87d2f3213de75b\n\nSquare = e712c3705ef2779ec997c430f1f8b7689d7edbf2daa733dca89612bcb298180b882cdfe8e5cc1104b9f5d6d8f0978b46eef4f297dcc83fce4c39821ed3205e399328d69ad484d8b3189e207193203ef79b763f5e11778dc24839b4feaab291a0464cc66edbe10\nA = 3ccdebe5106ff5642b4ac0751bb799c27454f904fb72863d1055d1412b2359120ad196b768f6137dce4cb85cd29a990838a95c4\n\nSquare = b5063c05ac122d0d4b1e0d15c913f70f1309933ba737fccbc02d13a6c712e7b75fa757ac0e4fbe65977f17bbefde31c8fcf51f867a698233bf25bbdb1f03c104dcdbf1173886a48eb5a8b4d27cd841196de0b53466a3f1d28500fb4dbcee8d3458662443eb2aaa5de9\nA = d745c04ed95d4090ed66784339202f9d0e57bdc1a6f6b6ca09337153f0236cdf99b61db85604791b3a373885210f6aade8530c8d3\n\nSquare = 974463573c968f1734741dde2a800761fa749b553dd6499b920d3af9bab73a87f40c9cad39c51cfabcfa0895f1970281af063d80f89f4103624a75bcb0d23f5ef6c1cd9a10930118e1459ee8732728ceb7961f7d83cd2344a51e6229fe708bda46382e142706137facf7161\nA = -31323f98f0f73fb66e541471774ce0e0fff53d69b2b726480b9ec7b0775b345ec4ec57c4334ab8ff4b388f4c7fbdfa3beeba0f3e0bcf\n\nSquare = 673a62011d769ff0333f69f10f00b28781fece47ddeed25fb0bf4f8d95dde4efff60690076aa520ebaa3ba63e6d445541b9586241141ecc37cd75b178389265224533055ec82a393e5dd61640d3f442adaab917c8fee1f8fc0ff8ca8d577e1d2d976c2a8b873f699aa92c272c164\nA = -a28fdafefdd393f993a8fc1ae321e420451dd0c5071410367d5a911b2a3a668bcae4452e134159e0b1974505f99865cd97cdb020bab0b6\n\nSquare = c4f34585a29667b582a3ee69b1a5f6c04746d105a57bc92763958c5add45c64b5c1cfeb1a321fc5194aab818c92ede5408afae0a2a74ed4c7757dae0bcc602169a805d525c5a63ca97391a9a7987a3eaf04bc44c89547c5d312f7193fc571851b1a8f8f091849f649ae91e15a050f5799\nA = 3822b607fccfbf0c5be97d4358bc682784e6453c71781fd3eef9d247485211c55d742279a35bf35e64ba8ec8cfe20dc0889688e2bc81fe0c5\n\nSquare = cfdf0eb68dc27d60840b8afa8daf96bf831002dadb2801c5d6f7ca558256bf3c7c5372fa00f2b3e300287745f8664dcf8e679fa35adfcac93839cec53b349553f31058a4db05af40b047bb367234dd78717aaeb80334f0deabb09d2d4d90394ec28cc3589b0aa78cf227ce8678b8bb5cd775e9\nA = -e6af13779d5a5eedfecb7c4d34009affee1f0bb65934ea9656ed6eae02271ac8a29104439000650a3a8cd7fecb171a7154c0e2bb2b1cb908cd3\n\nSquare = 6ec1b1333481c37be059ed7e088c862f869bb559b34360781f7263eeb206a210b90321aca198aa41c2a79e3a8d7df4336c75c87ba2ed4b02052a07b234afd9d2cb55413d4296645cd0dc8f987120acbc82fbfb089190f50e55eb1f509c86734dc14b2e8ae42ce880023dc7a014b02727b53d0e5f779\nA = -2a18acca3306bf06fd90da4ec2cbce995fb08beaec6d1cf4b30694d682c83e04b39f9a569eec52782b9eda7db0680165c77a1b0f54a1b995f8bd75\n\nSquare = 5382be4ee86b9d80dc2d4ec58606ac538ba7074d57e2011346f0dfb9a9d6677fe015e4015ed607906e9068a3c5601f0bb77186a9d147416ac68e344318cbae5c70c437c5e1dfc2d6c3c8725198937ac2d8e796f749bfe95c7fe6d0e460a633be2d86462d48290a2f8b344ebcda2f6ad353d6fd5f3355d819\nA = 9236f7ad22da9cdd8c187082c630098bf3a558b04856e876433c570a63d39863416c9890dd089f7665d6ba073b2ce90f88e7d04af96f1c82287903fb\n\nSquare = d68e15e8a46e001e47022daf63d2b33fee0f9d3dfefe9d204b0de6daea31dca4b287a60827bda9de2860c433b77186aca10bf3ac1d02a204ddf8bf070c3c20ea69d9638a865c8843e8e63211951e10a844f8527345c5bb5417e3301a19c929e6fc48902f0e0be8e393ecb3fe0e9de6188a72d102fbae846d05dc1\nA = 3a973dd50d4239f05d86ba25ee6ca8f8ef46424951a8bb89e7d1d6e066d6fcbabb3758ad9e1647a440e51976c0ce628d78b59a4d9e42fab0c723182b31f\n\nSquare = f03a448bc7405d2d54c0ea1a9016d8757d4af893024e542df80fcce448491d07a4b451d67c9e7d9a6c7c5a6155bf156d3cdf8103162d8e0265111655fc0ae46f4be944fdf275221b217274357977abf64316615dafb6ec84c5466f617c4e8d9ad4739f3e5050e583892db75366a4a7d2c4558436ed036a79084c7f9100\nA = f7fd0a9634d14d540daea21c7b804d37de49b7c13bde85c045859ddae1dd3142994e385f455becb7ee30576d55d4dc2f3d9d82e86032e170da1730b2c8a90\n\nSquare = af945dc2241029744548517dfd7858d42097076b06427419e74ab08071a23aaaa1f5daa6290287ce8e832a0524ba5581d64abf054408ecf6ed21a4f8289c1e4c7a8087384d268a1ccf7ed40e74922a619b5c1f2c08d810065710046190b7cfff33d4f67e58927477500eec54ba4f63a57532ed10c6b861fca9d46bfc3d32640\nA = -3500a8b6d244f1a21e10de7cfbeeb75d57ffa62e9dfbbdba8fe93d17488c56dc89787f13e660d0d7c7755242f8412d00988bfc7d3f6704782324c48691e7ca28\n\nSquare = a466e34dc7875aaf945c088bac23f3347a41f7cd039b0c9120c2517ada94b96bdd72d7c9bb55539af12931a3a39f6e09a4cd4311fba57dbfcc51bd17b03905e2560275c8bb3d786defeb131a634e86ecb793867355b048dbaf2db8b654a4d50aace6bc9d60de6934ce25ab58381f6ddbd1c063652e283c30a2dcd61d9d776d60e209\nA = -cd26a0c3d84e83d9f14dbe95cc39e3ed2e8861b76f4bf55ab120ea636d8f9efb0b6198986eb52075108d0a5c6ae0ee762f834f3db802c3f20bedf938f47b8bfb03\n\nSquare = 9f3f4d5110ea1bad21fae923825ba869a9982b753284f1946edea19f22cf0a49485b9336a2af7df8bf2641cb2083f4dce82202162d85a5779a4394213bf3bb3e47356bfc1150e66ddb6cd945092c9af14eeefd2d08b76c5e4a585ed8ef39202c42dbbceb25697f22f9508e7d954d3c1da103818aa6f63121f895e2c26d3d7463aea7ca749\nA = 327a2f6607c41ce920c14e9c9e8a059a931d71aeebc3e05e93107265a2810ec286819a4b2af9d2b70b754bdab6022b10ee6b81b32a7382cee99fb2bbcf6fe85af05e3\n\nSquare = 50ac4c46f2014a7a382b0d5ec9db4a67f34ffe9fd5410995810d3ea8d7d87d47442d0253c7eceb1799272bb5f5e7bd63174959f9844e5b4b65b6a4920166d83d01a5c2638b4d3b6db7fed99e28b9128dcb7c10be539114c5887842f8e5a7fb743298ec9642e50bd0979156cc6aea9ce802a0c1b14a2a1b7afe28dba534c9933209f14474b6e484\nA = -8fb585e01a0c62367dfa8a1953e553476b1564e843bdc2c5d964864ab2da56e0bfa7f5ce5b7850398451619a061de02ffbe0c336ecbeae818d32dcd40355fd11a7a3822\n\nSquare = 9214e31bb62f62a7f92d6c7f1453bc4430595a1765b7223a1e50ec30f934908c19fe82d7bb8ef1174bb6787aba9df1a38a84203630ae9f62e08fb4ac55ed329282315937d193992e9e12adec9727ef91df5a065cc5858062c765f34bd2630fd3f654a8f8421b75dc384477744efef3d6f0d15820c9328bf43a43409f6527dce48a92c3e1ef145b5e284\nA = -30587ef092cb9456caa844be9629d77ef1bfe21d2ffd5625ea353beb1f294e38a7fdddd5bf77cffe5caffaf609b8976756c9eb4908ca77b1630ac0d706503c46177c5d905e\n\nSquare = 54bf52644a244276ad3dac90661a1e21468f23a117a1fcc904c66119d86ce98a0b90fd4096708bcefa7a9df87c6bb85149305f193cf5505802172ef9ec343f662a4c895a9d19edeeed5d91e20abc894948fe59c1869928616392f3694d82aabee325b651e1170006ca1fc355212308442a5ec8a8fda4f5f90b7fef2aa731f3fe0f028143ead04490d78b2151\nA = 934b16f56700b455d5791ee8c119b5921976a829bb5d1fedb201e63c9ebb82afe4e29aaf0ae27148e4d34269c48dfa42131cc8b3b78e23ac3e7292eb0d715247a345c800f377\n\nSquare = 63b7884fbb6d5521c38f7deea5cc131ec6bea15a362322a8e27c762880836cffb69a069a168663908707bee9d83aad41c045bc84dadc6cd927ad62140f8c2fd001d34f0a7462bc939cc8996e17ebabafda95a73483c70191311a6fb7c670c76c9e2ed7e589e464617888d30cb7793e91672d7de9b3b4b1811b2c009dd1c690d44710bbab832d91f16f9b3564a0c49\nA = 27f17f0865513350381ea1aa1545439fde427ccc64385979bc787cfc4c7e6b624b2c77140da2c4176c55dbe43c506fac14b4cd7815e87f3120330dd3003bee087a371f85d6f4e9d\n\nSquare = 9d1c4239accb286c3c7868ad3b4dd97b93774fd0c65e04ca8dd405c0298ec6d1f52d60be6ddb5f8f0389cde756b49b23dd2f0de568a432fb99dbbd40db798261d1dd39bf5017e6dc74cb9ca91f8b2f892c7eaa28485c04a96add206c7c38943912de065be17b65292db5a144f82427016b5e0eb4ded2e4d0b7d12b01cb0b2b61e5e1bf22dcf1567a8b149cc0ef5299a8b1\nA = c88cc5a46bc1cffedad4f45e66fb55dc4347eb2a24a09878358d40fbdb03e738ca1d54a1d26a777915248fd730daffb0d3b5305684709db0f258f581fde06b11a33a3f76b3fa53e39\n\nSquare = 789545f15fded8fbf0b4275cec30c3ac65eb42ab8cc75670fbb2ab0b4cd90ed41a1290383b5f14bf87a88c67ff1e04d0f478fb11fefa64e86eae5777855ddeae451e166e23ec30227fb4021d51ec7cfe4ce531c78ba1bf6c797dc73f093b0a5a5aa59ad8de3234808e776d690007c8c332b3f03331dbdbb8645b91552091afc36c28c3229220b1a7966c7cf13db6bdbd4673440\nA = -2bec94112014c1a506417e659157192dca1df58f933510d7a8d6f6feda5031d799a66d2746c09f827199ad9fcbf11f323a636feff5806c9fecb2ac684c2870d60c8a72358562c4eaddb8\n\nSquare = caa64c9f6bd66f76c99604d1f2", - "b8a29a9a10c0d6a41cf32b5bc40edd7a1d97b295c63aa62c30498f15d70e427d5612ec3f6a2c1f2997fa9283f48018435fa6092269dc2e4ad524cc6da9689302f5c398d79e2b2d19470ea8240db9df0bc0bdc911c4d53f4f24a7ce44ec76378794d16d367434b4f8b6184c7651db77fcbebb8fcc5d3a51ee9739922cf20d4a8888139fe4669a164400\nA = -e3c4a10a64b7e67d786aeb81bb7ea14655637ce963f46cce59bc0cb6b5a9cb9c92afec3d527119db97bd2605d315cf28198992b4b2206e5616d3c560bc8163f56cb1f5626a7ac6d8427520\n\nSquare = 429e4283af7f895fe732ee88e4904348ed01bf579a93cffb7aa8e135d41cb9be218f8b9a9cb4f556124105cf042de51f34c8162fdc7a981de88e005a014149c955068e87214c174daa40fbc618c536a6e507ebd313763fba197059d68c69bd39933d614b2c32f235cc955e335c4a37b9e98cd7f98c7f26ea2da932c7f82ffd95be22a7741da423123f8908cb188abc26afaf4ba6d47b56e11\nA = 20a5e2a911627544219a1639c3321bbcd6192a32129b248cf62351f85b7a719cb275a4e44368a74f4d1a307ffd27ea2cae4d8584a57070609a30fb4e365564908f3d501b53c1a54f0e37745e9\n\nSquare = 9bcc8d423c3fdfaaaabe24a910e6ac3619eaa15e23b9f317c844d39d164c952fdf5c4bd270a83f3902e54d3817fd78c96018a706c1f652025dde0b98afe35597e0d8782deaeed23337ef6b3edc9317d54e3c8a57e4e7e2695f9d2681bf82927bab193ca1f135bd0e542696772f08520faab61fb4ea6ff0d15bb91f21e68bd7f084a6b8f24a47ecc30a779ee86610387b29a1de94de517f81318001\nA = -c7b60f4c355f2ca3937ba3c124eea2cd8d3536226a44afcaa3d17abe931c09ccaabf25a1986b172fcf46fb02a0fc36f2c163b6e42cee047c54ab05e9d30f03f6943b9fbab83aa6da12d7898c001\n\nSquare = 45df25540de94883dbc182009c29fec43627d3e5758e6a07cf40064e0befa0df184528a84757b445dd079c2b0feded48b651ab18b4bede2a81796be45caad0125c3692560d19cd9a6c8c0de8383fea0bc1ab46f6aca4e9c36b26575cff88fdf1eb1e13182308295457374968fe3a9ca34c6acd24c753fb84d41246614789dfe154faf34fc684cd15035dc9c1c6b0ea171e089e0f3236840e355bd123ac4\nA = -216f8a9a3e54d4afadf368c2693743efd3eaa4cbda7a87cd07f5b1a713eefd2548343e7f091ee4d9d6ed1d4343c06a0597db0eb5194b91bf2c858210557a8288c1aa7b0e0607a24dcff9de04146d8e\n\nSquare = 5cc707d97eb107c5c40c0f19fd432cbac9855f280082802dbe4deb45bfd193ac7a9149fd12c4ae6e9282411e2f1f2ca92135424f215b800634092ed4ff2859d16ab9fb8619ece41b50f8888d3e13773d38789e19158e18396096dd57fa5470f50b391c22378d980e59b4585f013e6db52c1e24c14ad83262fd37d42f52323896f7d4cb3e38868abea8a07e7ad3f90512eea001c5147645bf00396cb0e7a553f1\nA = 9a1d1b0beea76e7f32bde9f4f2c8bcff9094db2d32c04fb7ff43624b61033646e482aa0fadb9f8b4225b47121070b4ee5d6818d3606ed775aa631e0ed42da68c2a09dab26b6a4d09ac226cc09321fed9\n\nSquare = a32fd053eb90c365e77ff47573a24add3b25b4c301f4c662dfc1fa635af8e18e7947381989b37a9c9de2713ca438b9f85890b7b160fe251933aa7dad1c3839d502debb42ddc927fa0e9b40c80dc3d408889be567699a856b1c9cf3a393b3b818432e95feea825c17d0981b942236b3779f2acaaccaf9a5817ca47bd03045fc4de454d8f1d4377e218c5f7ece369aacc35369ab57a71652dd42621491834119afbe729\nA = 33190b787a2c3327b122d1f5823bdee5c93b19b586ce1bf79d801a19b2558aafc8f6274d0908bb7a8362f7f71d3fb52b8ffc87d458249caba7af3a516ce868e8a620e3126ad43d6aeffee11866fe77677b3\n\nSquare = 74215d33fa398e21c34034af6f9c7af6a3e01982320ec8cf23074a938f1a31543f80e6aece01de247668fe67f276cb4411db27666e1dc8fb2bfa4eb68cfd3563167d1ac4efa3361f920d8dd0fbb7f06362167f5ab5ecfb72956c20db934f67ff1c75aabb594c853fa61f43d219a3f5d0d45274005e3b167cfff5493b0f26d15f85d8e906a0a6e7645eac1f40c6dc637e6d1e061e5b9071a1227469cfb2c0f17ff983684100\nA = ac6c0b9c69785f35dbe244dc85a54313ef836ac67c853531ef5db45b28835ffe61dd258c5528b0acea50f5aa5c0f5d08dcb8d82ee19bc432fa8a45badadb50693fedc1cc79a17d63aa73fe9597f1d4ce8ddf0\n\nSquare = dce5cac967c47b8a58ed6f1bb1d1e6185e849400228afa2bfa05b9c2dd327b04a86f2a4da2d02ea102868ea0c4da0f3e5a40bd02c87a08aaa5cd8d9358b3a5ebd8c9fc2dbb1268c261f46d6717b0307b993deff0adc8190d32b4f2bf695eb2cc74a6a9a712c5a621c673219ff8a24ded0997508f8f9eb1ea872008c46e71fa97f55b839950e63130c38b49c0ce3ce724a0e8faa9738d2e28ce6e7fc7eab62b3561d2981f314f751\nA = -3b735400064b15fad81b08362b8557f8318c20656839ffb4d2513512015036ab0039442032f1cf515f8c10c9933afe4206a2f309e933d1561b06bc665af2f04f4d064e073eed2280053f56cbeb137a9482c0a077\n\nSquare = 6b619bcaf632f0d8b1d715e8850c0cbbd29ac6373a9a5e93dd1bbd2b82744a8a50a7446b48c6e215911ffafcda9ed7becaf5d26b7d6df7dc8798d53239f62a482f974bdb654750def1c941c49a24fcdfcfe73881b556a7b528d88daeeaea8d62b357211a1946c81cbf0819ad8d0188f60aaaab4ea2dfef7e9012ade7abeaaa4a23d7403c1248c36aa26b43b8e7de8a5aea639a0449f50359e9b4c1b125a548383af33703f8dfbc2528e4\nA = -a5ccc69663a8712c15f96e6fc746252af89a8c2a6317caef905dd2d8a6d4fe878ac7aa66cdb3c3721ba7dd36da310753dde9801b31d759339ac919a464ab52541bb2e0dc938752bf0f1ff7a9524eb98340d62576aa\n\nSquare = 77ea5b715823045afe13d10416dfd46a511141a7d1279ebd624f1de428cc04a4f246246e65c3f84344cebfa32864de9264b2e54d4b3010c4de9d3e6a27aae8f5f9e9d8e49fe26b73ac7e65bb216aa6a42db36ac03d749b5dc04192df819631593202a58264714628686507fc5655f169483b0ffecf45995cbc12faa105895564d287a9f4b220947d6c93786c85b2ee84a0a29183483f7c241d6a67fd0b1c38c7f74421355a14c6d9ed5720e24\nA = 2bcd67e6bde3f54c4ce0ea428418fc5c97272217c6c7de90549238ee322810dcc1bb9385967673aa3f9f5a5c05d987c6445135cf1efc26b3c17e55b93cc052761a77c9dcb5c22927b09e90a92e053ec1bc799bbe7597a\n\nSquare = 40d113460ca3e70545bf3613c2ba5de5d8485641ebf531a43b6b8bb76884ff4f348727ac6606e026981d2116ef1e60d4b37b44ed7e2003410d7d636b58aed2f92e962003f28342aa5f059d23b3d58a1ddfb47833ffe1d1deee0a7e78b8f7d9d6487f22376664f1ed9ddb5ee3d17f43afda296bead11680fd17576a122c2599fa9802ddd84a2115f9fda03aba898f66e303895f452077c920a322b6aaa0965f51fbb36f01b1d412c6ccf390da050d24\nA = -80d0699a46619db033461aa6060983def7deeb976d1a71f5c6ddb85e8b46dc70b7ddb1d254971d38ca87c7ee3905e63506c6db105dd683375f4239523cbf1874069266c2c0f4b37edcdd261c51088081d25813758bdbfc6\n\nSquare = ace99f98cba0d1dc1c758dc7211aa4078a2aeb6d3fff19bdfa6981ded0982b15bac792e6b542ae48a86f9b40c6de937e402e230fcfc390b10c3e60202dee1337ab39da7a342999487b8d8b0e494f2809cd1bfdb39209da5daa590f78ded211b6bbd3fca9013300b951d8906c9ce8d1c0dd9554d5d1d352f9784f822c928dd9700ef8a5fecf3771966abb1dc6a70b301461eb6b6087d6ab80a4b624205489584224cf6578f75acd8091fd621d02306504389\nA = -349936d60c9d77a0974dc8985930d8674976db6b3cbaa067554ca6b30b1de33f2d4e1c9564ce102ac6387755aabf42916f63632a375d995913f9d45ebda54bee3fdb7cedee46ebb5c8ae7764e4de323c17c797d3b529230cbd\n\nSquare = db6c73be2a59bdd35dd312240aef18dde4231c72aa28551bb370a87dded587accec2279bea24c930236f06f24d537fcf242497aafcbf72f085fd3ecf030cd750fb382efea0f82ad9d3195680324d73fa99d48802d085c150164aec0d29fdcc3262264bbe72311f89989cc71a4afdac6ab103ab4fbb6e973a42a1f8711bee463d198f727dc7bad848ff8fa77cd3b2f612d142ba46e95bd79a86a1fe4c2b8f9181be84825d05989695842113828a83b826e7d2c8c1\nA = ed01dd49d2e5d51fd30e9c578259cf107771b4ded6bf21f8b9b632fd360e34da740e0b1af6b5a67789fda5a44025af0f1547271ca8accc7a975d98ea7ec3d41c9697018d84ffb5d49b88d884ccdb011f715a199ddc44a4109261\n\nSquare = d6e38250ab89ffe11abaf8c5d07ba11e9053f1924ee1228f834111af16ed282389d04330cb0f47dbb186dee577aed82878ecb065b759312eaf167c4698eab5ed03a8657341bf5fb14a8e28e3b443a6b657c1f4379ff2549498a33922ea84f1fb19d10866fb0ad07ce1cc44c93cd4d9ec6bbb0e61c797750c6b5d7e8d55499655dde112f4747798f0e985fc2b937a44da9b04c2dc4b0816cfc57da1f80179db653c1ce287e786ed7eff7ad6d1383fc6de8c941d4af7bd1\nA = 3aa2e696ee570160b2a869c3f21c3f223959a185cda2274feea1c829af2234c70a504c959bcc49fe0313f4f5ffd27448e28aa0fc6ce24f36943d334c626459d7e6017339e787ab074879ebf697a93ad93835d69ab09294d007a0837\n\nSquare = fc39360cc0fe040b6f8340e0728c650e5e74cf1664f7b301e79986fe066f36e8df34d38d1a06b74a1bdc76867baeb3f39a9161acd200bc7532fa4aa0ea829377659646f073db82ee044279ae5fd797edd37d3261970819589853cb320887a085c4011c23d0da9b6d6f1b5911bb3399146c2912a967ab3b3f611f0bd52e00f418e6a6f0297fcf5c4a1f71c6bb8cc8e1c76694bb7301502d1d00c8b6c05bfabbf5d350590561abf3e2b1a82e98b56583e2e4e25cf707320a0e40\nA = fe1acf3d7b54e718c901c53f365894c22c8bb4182fee8a4c2558731e01e1519bfd1bf6e353483b8c4219453fa66f06063c6c99050068c15cd13cd1648ffc42b5badfc70f6fd4a0a5552fe637e54c4f92ca45c60cf9a0163978ac08d58\n\nSquare = 9abf1324ef65c726330f64643a024c466fad37604f4dd3dfc404d31c2a430fcfaa0c78283666c15a094d494b96d3c12de6e29a34d2c99f4f8cae8217bcd2a989d59807ac68c46d60600238a86155de499eeb35642d0f581045481b40e4f0a76905f9b6bc5b9585f77f8410b99333f7ea983c3f29f3fe66ca7b793b784a5a6a4f74512aa4385dd1e996832b1f41bb3af965be58c4ac5e867cdf8dc6a4f9d20a6f1e16e153fcbb45ae5fe8a798cb06a4ffe467d6b6aca2b31f335a344\nA = -31c243593ea611dffecc65d1439db345b2e89941113f9792c", - "91a76b4890db6e4dbaf1482ee812e295d27956e48d07a14de38357f15b5931c5cc08d1d248df7bfee1cae5b5ce98984c5043a3e1a2b449ba1671bf1cfef91011e12bab94b6e\n\nSquare = 66aee3e4f43c672e0478c76e2092bef33e7c60afee5d4c7defbcc5c0c86d8fe956c90a740cebe604224cc3f518463b1208699b8ea2316315474991d0f120ae905a67028492cf46fff2ae244869db2a02d06aac6ac6eb054fb3c14c756d8a3e7ca64f06586e3e86e4477f185ed527a8aea6a3c741f3fd4b64a2ee77ff140190260c431cc53f411fb227377c02f85d0258a75bf6d44dccbb8bd04ebdafa115dd55b176b6eff5567e5b1bedcae15110826574053681fe25a695ac4540186e90\nA = -a221dfee30286adc076673cbcebd24a41a438a0a7a6a547c75d33149cb1a094a8425feaa5a23cc234a722db4cca8d5912fe1dfb6db4e92bd87c12f0d06b6d954fdb9b172955412b2eb5c9fa3b4df2933390384fd1f929a2b1a8dac479ec94c\n\nSquare = e880f8655b51739e34393c3e6d69d63e0256b1a887f7e69f40c78d21133b17e92277a136f5e37da2533ed599efad189975d22ad0340005ef58db0b471651d749dfbd48b3f7b3b8a42d4677048a855e99dae6c729d8bd7eef86911feca9f5490dd216b06d9e8d1ab695c1081e72449baad28dfe113744853382901e6bdab5413c67c52d6cbbb2e0bea711edbb3a219a4046e8739c04729cf8c8210028dbc4087737bc6c1d7e0c15ecf16774690168342b1372d3646d4d8696384bc932144c98529\nA = 3cfe075d4525a3c780d6d05f7bb708b2fdf7277a0f9967e0a209fee9d42136a0bbf98660d8ee8cb4720a8042da09f6271c45ad13db24eaac465f8207f78629e9085c1c890675f441c78efa38e5022b1b80afde5e3fd08e55648f2817631eb6cb3\n\nSquare = 8d6cf4eaf58099b1323fc598b7554b371f4afef5ab501dd162ab8429333d46916fe15dfc4ed6a99ca7fa7fc1aaa0cec3533b41e291fb7f69b560259507226eca87aabd07b1ae2eb93bb53f98fec508f051cc04db4a172901e06b74229c4fa3f550a81626c7a63fa99d41e46c2cf792287a5cf7bb68946971bd43c7c0356312cdc25e524665dd39a24b6464bbbe64fe8e87ee313b860639728a9143c3a6118bc8b150dde6c10a13bea637fa8873c393e6338319c506aec6ee973b4b52a272a74bb62084\nA = -be46a8072aa44b3bff0f90c81474dd576756fca624c15f55a17e1d0bd2842467ae000b04f79f561690c93ca7118ce17ecf830a8da3678c15436876d2a74324d9714dc8ad8181904be657d7f1da3313b78448cc06e32299a09ed59bfc1961e8bd722\n\nSquare = fbaa4fcf9800673fbd3a132305ed3e14f4889518fb56ab82aa5e9b3529b74d7f9a467626d68f4709a2030264aaebcf05c0a0edb511e81f357d85b79d925a24605f1bcd4645915bb75d363654b676266329df532cdb39152fb360df1b9500e0c296014289650ff77faa78a604397a82b34d16484e94a8de123fe720e514c88f11ec276725111563db91477480c3245542ec6bd0bb2f4aaec02c6c4eb1769030a31b05da3798c224c9117f7c38d3e98a343fca03ab584ec2d7e6db60fdc4273c3d8e23cc1ce09\nA = -3f74b25f2a9c4d8d977e69a4e067f9fcec281136a508e365b282e5fc3b1d097bc6a0f59f7827fb90d4890b08840a0a1919032c67448f8f1a771f785a0f125a4aa4137c154fdb489dc1099d57bfcfc75f4ca5e69f93f2bb87ed09cc0dc620d3e76ecd03\n\nSquare = 5135becca97d93dd4b16a5a1105ba3a3e3fe02bd6a7c3cd182186fc63ed4351641182a2727ab6715e9672458dfbc31aded4781fa345054eb4c317872e2af6d4ed64b2ca7e8c25e1e664b5349df937118632a64e4ce439ffc625a5ad3358270dc83fdfa73c7afba03406094fa36d87517e5e2e1fee5526fd2dc00d9210a0f6c3745b3d4bceee5f8b03d976d696c57a09d1e08e4ce780972eca4f2ed6500c23bf5782c31f13059e48246180fd09db693d2fb5d48d51846ece8beee45cef7efc87c003b44d7b137a900\nA = 902fbe2127354a7df5cb7fd057f3d080a7bebbdb83c86a50560b8c287a37a841bb9c8421c63d359078d2948b6b57559f98fad8f8014f93c912cb70a6701c4dc4fc5e88aa413fcfb685c32975a8b72424742eeff8262d28cebad00c5fcf88baeafe8f6730\n\nSquare = b5976cf6a6560412aefa6704b126e0d987dfcedbb4da436c08ce17b1bf1b6e0bab9f934abb5c4186a5415fa38724fb8fa341d381319e7d768209ab108c8debd99075d31deb3e03ff7d23957d4f3204d543b7d9079cf337be3037b1cb4908fd8c104d92e52f041b4cb27c045a741f4d64009980e8d27af75d9493920ed98c7234777592d6577f2d1b3a0eec645ab4cee2f28d9e4efd3e4514db6796487ba68a462fa0e316e1420d6604db2b901de46553546cab42976fd0d459afd81196275cd88ec4dd448ff331bb35499\nA = 35e700e034950bdd7318d5b3c17e90a4772ecdacdb055b9391b31538eb823fc8a4599f029e78e4fe5299ba1a423a449dc257a431d189dd5dca275c02cc1f12417e111c73b731631d8a1741b907dd8f24de226ddf9e3044cf4064e8e51ebd55be774be7ad2bb\n\nSquare = b7de0f73397893a97928e266bc56299cc8d43b16a251992662646072b58fa578ca80f7be1e12619012b130e9514be803dc166b12ddfd26f558d36c2053ee6209b01458379e49469753300ef20f6b3dcd5383b121861c76ab25debb28c448ec33a81250d05f7eff80a5a4133d522d270fab29f739b607395a77278609aa5e1a55ef58d1d48492b71ee30a24a6505aab1a3ac22b9d143c9d6781fae14bbb980fe3a99dfa9a1a406611d7d0304493342f53faf5fd79f9c96b9583a219a1b22aad02dd58f32ee98146b3a8cf054bf9\nA = d8f4d3bcfc7eebd7068b851858c3668ce062a834927e165679b49132d4f780ca682876c65c7cf2e7ce34ed10e43696477da6301d13f92abb8c76e2424c4bc28a6565f15e59563d607b852dc946652b68fbfda1c3200ecc2976400ce7296b96e75fb059a4c8eb5\n\nSquare = 5ec02661f49fb9807bb73debc3c6eccdac1df1735e0d61fa7e0eee07471068a5809796a2af490c46a77d61f618b44a3168dde67aae1cf9e530382411056958d55bd18f0e76fe2c31c98b00f87fcb7f5691ed5b65424f82204156dc361ef6dec5d44cf690582599b3994ee47ef42850d5d2370a4169c5f73942657f85422ca24f66943877f73af493c865fbeb29574cc1cc730e9bbb097b598574f6b90257748e950bff867bcc01bf62f8df67d7aee1b6dc1d5db88826e86a3f9fcd8663e09cf8393ee71a09c43d0d38ba6ef643f4ab1\nA = -26ef9b6708a80d00f4d01e0f0a5546ed217085ff23519819ee89af430580ea1f086beb0eb51982682c6d3b922a2c92752dce63657836223a9d94964bd584bc8e37c6e30fdcaffbdb128344d51a92705e1c9f94205ca36452c15a08f7e62e0e02479ecd48085de8c7\n\nSquare = f6364409467a829abc2b13c93979dec84984caa12154b7cda2f4c8d91bf24ad7c45a968ffaac8d6722cc26e6aaf52dd29ea2f09370ba46d79684b7a06faedcd17136f35a58e5b550f3a2caef7b195d8409914fedd3c3154101bd735155098e8b10fbbb1b2e13555d2ab5d5b52b203d4efb27e498b240f37178f2e89b413f94859b0e8b2ec10b926c8c0b6f2937ee2d0355445364841c7e0539f7073b88c7d568edf1b253f3c10627e22c2ed731b7d4d199449cb0b5e7a66109932fe2c9cd741d75170deb9f98469049549c10a7a622bf6e91\nA = -fb0eec3246e99212879e51b17ea6615275818ecc5ea3058b13dbaba2576ef90e1519e3629b09fdaeb02661091c395c862b848f6326b9f536f7af45718c4412f09f19261b537bca36742d3ec66f964343516aae2ac27e249a15beb545b447e37b4062180f6c82809429\n\nSquare = bc4193ecb5dac900191e02be06297106155c6840c4908fbf6e41e9aae137d53c3d4ffb87f334f49837dc4ab7a66299994e4f5c9bf6ea03e7db663bdef066e94c610580a8896a9ae9c8f6587eb83d789683f5d6391bbac3a1dc1de60b4108428e6f5fdeaed6cd3e74fa01f85c6368023b61a413b69b14276b66f22653491e4f25790985053d075387cb13c79dcf963b6d880d01174314921afe1cc700c02efd2979dcbc59c417a6316db9ac45a2d60d2a036571bfbd75f9f5e42048ca086cfb4b818a9beca4a6e0ed51afa320ef3549151fb39e100\nA = 36e1f16043b4c9b4a304496c39dd63459d6521d2ac92916d348daca3f972835973fc8d21b07b09d8f5e3197b39a8f3fd0011168b815d67c48143c413e169ffe0f56ff2cf8b6596bd0a3b5b7a6b9a14ffb797f350b7e6aa7020d84d1d1b8006850139795abe2c74f03b8f0\n\nSquare = 4cbb5bc1dd7112326e2c94581f19efc8fb25339a299fa9c007114c3a22b395e9d39a8ffe21134e97ad1b87b97e667ba48b2a40af61afc81fb1e20e8e38c7ba666b146016af4dff3faf5de306591e5ce6eddc1173fdda6fe241a9f2fc6e054c41e56d296f8954377df0d140096b9e9d6a5a23a231db4dfab0cabfb11190c7a0d1c55ae35203836d433da96ca7339682bac0a7edb8b5b4dc267c6e83ac9b67a0d0d564717ee3c20aaf52c0a750f3aad94a12537c6971ee009d0f82ff576e984b06c7f7b357f5c049454e31326b952af17aa62104780e9ca1\nA = -8c279ebe466de3115b8740f3ff9c1f605b4eaa75512d82fdc8ca5ce84e11a68688154fd603ae1d607807dbfcbb822a8dc259098842c6a7b7ec350be29a3daa20fd5b093a56692e9d42e7a389c4ad2122a74205f835e268c9742d09ad36238c34e143f6e2ec69c0f490d29d1\n\nSquare = 4f771ade09cbd1a033d2bfc6036fe46ae6c12acc6f2b9bd52e7781693fa6358cf93089f23d1f0ee6fca476a43093b9b52446f3a7abd72ed0ce9b562dc438822ffd84bcd898ef9d092f1b0b7ff89c4fdb33d8715dd4a0d68ec49ad41338fbb62ca87867d847a4d99310641a37ea78b04c85606069d0c0950484ddbeedac8ec6f95124e7fd83da4e942d40103bc14474f5cb125fa0b06cf167f076979948003dd8dc3711923f5af5beb5f56c0a48ac0c5240b62738c1cdb06b87ac3dfa17befbe938ddc7281f6c248c41a1c7b99b93f69fac83a46eb298a9fd8b9\nA = -23a845bf2007ba8480e3ece0a1bbaf8bfccba6bf061e3fe1d8bcbcd6c761e650891c0958bac68618a1f55b27d2bc6e1e1b50afc29f58e2e034bdda8405e5378cb5bff0d84efcb458c5428fc607597d89d589d85d90f3da4b89a64c9d1623b98b10518a6f2e7d2295c37527026b\n\nSquare = ab45d12a4e15a294830741f4b9d4a14cc7dbed1c3454612047f890211c749d92ae0418f11cd44acbf1585b1f7323b33ac9a4b13c44e1a7e31b0dcc1c6dd4eaa12a655b5de08f3b948270a152db7d9e04dc54677075797bfad6a9a0e3958458d40e3df5e15028954bae99518de4dd3adfb2ec4b38897a8a4e4807849e1416aa4040c95a0e49a8d2889f6fb0537875f87516c3723e8d3b46da8da855929c67c0eb83daad62ceced52b4f52d2bf1c4e34f26bf16aa7da3afe0f5df76c0858ed98f21e1fc3d01e1572715b774bd5c2faabec5fa3fa59a7a1f32565a4f1f9\nA = d164d875e1f766b4567e9228241213e69d6b6c58620600166fac56938c5d", - "9643932d01f1f4a2263dca4b9ad26dca1548e4b5b7e27581a63375d0e624f4e4c99b7fb9aeb25307c61142760bc4771e48c7ce38f5eb2408def632096fe40b80d488fe17a455d80edfc1c23c429775b5\n\nSquare = 5ae4e7dc5727543af39ed3d5e9ac086d1a2220421231b82f6f41caee7b9815b4049aea0d43ff499c6c9e1f226f8641351d03f37731c64686d9a9ce68e9234d6a762efcffdecd42f81044111599963d9b6873cc20bf4c8284fae03d2e4f238a14a74df4388fdc80fad0375a5d0d974da7854ede5896ed2ab25d2b49a3c39093600f73120e4fd2faf75381854f6ae80f81b977f62fc72f1fd01c278d183544052b77bd753dd88ffdf5c01745521fb8474b5c23b0b7dc709bafeb91cee0863a0c23ad7192c43cf15fc181d629853cb9b8334082c915dd3d04e3a0a81511d2e84\nA = 2622a7bf45ccd3cd567c757f4c5796b5a0fbca555bd0ac2759c24083172d82d6a887dcf93d9788fde052cb20a8963cb6db22bf5eee6151600f9d1896a7606b11a1b100cbc0925bce037bcea57e361efcc560a9abc495d7f7f45831c6429ac8f979dedc08c304f4da9c0d4d687376d5e\n\nSquare = 473cc933f5a650a4ae358c7f486d325c0e20c83b54838fc08b6ac3ff010f7c4b6a609bdf472974dfc5abda0c6b33c5ec7dc4628d85cb4276108e2b0bc4e19cba135533b3d7bb6a94332aea3165dccb230860d2353166b9905635e606185b014730e9dcf2c433e18cba83859fb2eac4aabef68c8314ef86dec2d534a184ebc4cb193643add0897341690cbe18bc2e775327fd7d71ffc7ebc49bad83cd68394eb276b2e615ec430180303010a454ef73b6a8f02bc48a1fc8a32f8150ef1b733f07da752b8e808000329f4924976bc8b8573927f18ca7c88c210845de6dcd0dee2904\nA = 870b2c4b054076d0d02877b19fe1210a8fad3422b00905a6db748239b8e807716ed9fee0d8c25496593717917edceb5db57f9960bddc1956b6652868d6ace82827bbbada5ae8c15efa26fda22657126c6300906f90e8fabfd58ddf312ce0eee760e0090fac44f00378c676115cd0639be\n\nSquare = b151124402d2f04b0e6599222d380dcf67b9716ef50d2d9ded0b21521b34a7294171f71b41762511b7cca93d9f50e9e30083ef19144882928011dbb143807d1b88c55eea6b19f0c4180023be6da63a59b6bc027aff3f5abe2f65c73b2de1e71c5f4b248bc4547040764e83a860cb3f882bb8b5f7821f92802808fa37c50f2f94d8f56daca841f42d3362762ba843aedbd03d3cdda887f75ba92423965ab4256eb842ad755aa7a2af331b488186f891065b07f5a299c807dc24fc176e085a8024bbbf12f386ef49ccc91bd4ada0936b6de78088cf5952ae6c04f6916799378bc0ede0da4\nA = -35439da9e361700152a35ebdea253378a1febec5f288e5b2bb0bdf25b84751b47e4da5aad7453b70cfd6640d5832237d2115575c738482ac6036c5fc21a981c0a7f979c8d621a92c02166b777475618aa6362a0e225dd6138ead3b2766ed9785ee01e4950a863d2fa0b7f5cb4c9a108bb626\n\nSquare = 4ed7263ae5beb0069f24318b38afe951a5a058a2e960e67f086c9680d0cc6d713f943812070bf94152f7926bdab9e5908941261244542b832f458f05ed5dc048c8b9eb84c2a85efe717e257796b4ca816948a6c8ea209c0675efb2fb5af4622b44e36066593db01b17f4dee21d7c1337ff41436cd0e5a8d01e4030dcd3d49839e59996fbbf1d39bd205343a424f2395b4d3eacdeb9ed3235d8df0dd00a2573260af63db3116a7c65d1dc69684a05caebff34e3d2cba9d4869a953a7b1fce10ebd008cba021008ac3187bba846abd7b39a1b97c9c07d8080549e313dd58b716022de3c1920329\nA = -8e1141dcebae61d5c4d81697f001d792ee2e847c589816f923f0ed42bb4de0d8f911b8ca47ffe77f80b9da6896a9b42f0030a3276218868bbe1a3fa64fb0a577704339af5dd82e66780da6f58900da3f1d75ebfcc302f78ed66ea3c7a737898a29b1f2500686b43bae1e6571addd2842cdce4d\n\nSquare = b09f5e9472cbb75070a67d025957fd5ac3be89c41e4acbcd5f75780ca459562461082c3f19c5a4a416a668b0a55f31f74cf2ec44555ddc43fde64da0ba781adfac4520dd0f78d04d9d2fd33d8b49c72663a6bc845015523e2e4e7ccc69e5b748b8b891e4089420bf0a3f6032602824c7230b5ff95f85a688dcdcfc890af3384710a9fe32ecf9ad7c6cc5761f13079b19d7b2906c7e63c14b64fc88c6f4bd7c41c0356c777d35c3626d49db8cb2d1e89ce682c7fccc3a459b08c20c4e5fc3a8eced9b37d01bed5af6ce9baff0d2b435e6e62871fcb20cf9ec10d1897a5c76e73a441e07fbcc2d9f4e4\nA = 3528e6581de547de385c93ccf1086a17614f23356a918b25bc6d73656a2302b318963bb679c9a93357f4a4f614e74f2e5e88e9c8aed8a6fdd8434630f664ed15ebb6095cbff1593f188a12f4dd6087a85b202f6c24df68ac3b137406c88c5098faf47d1eeec0743b35baaec7dae29b5a44eb09daa\n\nSquare = 5d5dc40783411475a4aac7c1a1eb760f76fcc6ec68dfebb754251cf499870654cd309422935ec841e6be4f5a15078356235c2b8cbe1ae755cd6d814e811072bdb76156b83c7d2064a202ff90af1e0f88f5889e5729a3cffa9faf33c463b74d0ad21fbb4473d4d3ebfa8a52e9c209ded5ce5131b12b69747c365146fa17ee5810e0dbab992f9da28b6c323062484d62472232721d608cdb9b5a341a677e2d7a6e5a983247d9a4001e16687b489b10b18bbf205f982b7ceee27cc3e9c6641827ab7952373f15d36e5f177b82d7eebb3f5054e12cec82c5f520a2675afdec6cbf6235d358c2fe73344002e400\nA = -9a9a19fcdf11bba84b0395088c5d187d84d69b68b77bc6418f63c88bbd8dbbccfe02917d814f9e2241fa0709817a0c85bd554fe887babae7439d96248514c12d71587c906247b3e965e954cdd57f1e51f1979f73c3237509863169efdf281c1359488daad3d9eb990a50ecf4d3fd25d4820077832a0\n\nSquare = a4d69ed4c4c9c08116ec5cc49ad458f0fb2ca00f356aeb148f18037bc49621e14820f325af39f3954bddc9cf01de7ba1e443088545883a94c04ff41a7ed5f65676109c5b711b4115775489667e00aa1b77f6dee5ac5c1789bc71c9fc797abf41c7c5ae3e2c1cf82d5b49b6c0da25190dfa9360b99b2f63444d21ec6114038b8284bf598eed24a2ab2b9802d6edd5b0fdb52f60621a87a14612844ffc71ca98180ff0915cf75f47432f73d28dfd7a932a125095655f07f50722b1673df2cc4f7566a1c6035792ff3f02356b9b9d25e905121df768dc6a1884cf5483eeb813c1c009fe4ed043febd61800ba978a40\nA = -335b12e40bfe0b847ed6ec143490df33d2e64ef4363869cb78dec008cb5cd66ea671dba964a53e48267da288ef4040e06371e1209691b81df02f2c86a79cac85fdcbb6732a1e5309fbbdbcd899fdfed18518d47258c9e63ff7f116ef4a8f5c4867aedd907ccc7d222cf8087afebc108f2a0f197c717198\n\nSquare = 74dcdacc1a4f02a99e3642f54f9d917b117d2ae8d9c392f8b6dee53fac66ebe1680c8e8cc29f5330e0eed3f63d10980060799bc37b34c93dd7b384d4ba30a5b5d42a145acc412ae838d7b9b7137637546d1118f7cf3eadf88b785f0aa01da8638f027c56faa16aba8591b64b45dae6138c9a40309b2ad29c5029a867465f9c6de8fbc5fc4b0442c8a8946272667c7622454ed6f2a236103bed7697dba20db84b5154ff3fbc6b4b9eb67ee43bcaae741d87ee2093ee67defb8eebc4a4a22d97a4e2aa7d4c31a1c88abf4a440ba4e2a5e40c4d903ba5ee4d80b4e8dffb8864bcb9806e015c1ce16490068df87282393111\nA = acf70350e554732c1972903cce269b215e985ecb8d6eeaa67fd5398d0a1b57c0db63368c0f8c2288c3a0466e2b3db081106b90920c46462faf00b5bd654f7140a689b78ef656a26b82af8dd1988f166ea04e9aa777a094d892bc7da4bc7bcf0618526f496cddea6d67df7bb0de9e99a35a0b1b210ff07497\n\nSquare = 9668b9e40a8bdde3c93943a918ca71fa0009cb05a1f592b2bb2c6c6172b2950719bfd80cddaf45d044cbb6aa99715046088f40ec6812945885679231c07f4200023548ead086b834abd8c8f8294db28b203329553242fd2f778ef5cc5ed0b48c7356d8c2d782a01809ccdb6b012896617f11d963300e7bd38ff512829514d94343476818ddf9d712bc70cffe7f767a9fc75a5630e6250ed45e6831b4660eb49d47dd1b8b6a0dddf3fb3ff0e12834337f145f741f70a2aa43769af50f099e004269ac47fab79e060800dc74da88141adbc46c15c7330931e3a2bed9b958f78b30214f81a64d121f96fbcebf7569fec0cdc6b11\nA = 310e7a40667d9d5dc29744b123cdf6a663a1b995f62fa9d4d853cbae0dd23669f4778bb2040317ebf6a06ac6299b21067aece5c5c1afbe6e789d656745ad66464991cada0eb237c6ffe991cac4670bfc90eed5f8c75073f4f846ea244bca0e9502ff56f8e9bc9b6caf275aaef38e26566fef35329ca45392069\n\nSquare = 49e677c8b052b7db97542948542449af47e14248021f8d3d3f92b9af41c803072f71050f16dd848aebb270affc47e85427a7c73f227f0d63f140d0d293157af0d972eb5b38de494fbc78ad3a4c3d1ab40197bc4427752b6102d1ced6d6cbc9d7caa0d1bcc57e708535822180055ecc9d9667e0590274b778480a3720823e931ff6daef358b1a1a9092f1f05fbb5b10ad5707a124e8be63bc696f083eb74e5b4f0e3110de8f297ecd30dfd2bcb010dcad4e387520d3d00365fc51c2a3dfe064b1ac77a9295f66beffbe5dd4333e5cd823b0f36b0b94d66507b1d9381060980f62f38a62e38e5a75203233bb8d64089bfd100f3205f1\nA = 898b5f3655de74cec3b0fde2ab03fd18cdbcfc3eeea48ba39317d26917130c2b78e05237cb0454ece268f091cab699fbcd51ce341b53d6ec0cda5d0d5388bac25c6517214a39d03450ef8502e1675bfe8e57bb6086f10ce4cf8ce65eadc865b5bd8a00dc26394f3adb2ace609149e3582cf44246184b2adc0ffd9\n\nSquare = ad00f10fed55175159b2409dc80899f9113ba7c8099d0402ec0f520ab4aeeb46d36369494a4e6fa23675adb38148fd2efa082df5094c0acfb77a9ab6ba7a299298d69b04b58011c35325f46b765e580b5c05eca721904f1fcc355dbe39faa92af5c9a6dbc4ab80e62b815b45983d9506ebd52b9efa7a6b9da352d1e4fd6ffa81d3b4596a0c14fb825297da361461ff2240e4378340d2ae529932d78f3d9f6b3c6d65d717e66122e5f590c50ce0a5d81ad8e0f24e104c0913cd8d0eb2de4c8cf62a7535bab5502df3fba08bb4dfe73d89c8b00edaa7d5f3274be9959e7ab6b6dde54f2491728a1dc11fa8e1c6a95e67eb7617e9b7471ee40\nA = -349cc2a5658fdbe9ba5c350d3b25baa38b1ede01926694bd550d36883e53d8758e8f1ebe83e2f4560605510413a7d880929e2d9cbc2730b1736dc2689cf7bbcdc68a342b6398e547a9bd67cabe298796d76b98ed4c1dd9c22e36145892e8fcf2258529aed24252a70b6ca8fd2aad8a84becf7e1bf98b1e9bb024b8a8\n\nSquare = daa3835d3189ec9ade592e6076e76d441838077a9431273bdec02379b3a6ac38aecbbd57c3755ea58d", - "def8105ac28f2ecc8598ec0c4bfc9c1c80222fffc776722eb0621cdd8a0d55f08767fc2922282a76e529d81e4d6e21a2542b8c9a403709ed1132e3b52786b81e684591438fdddb5df2f0b72e6b39cd2db6c0cc55c759c2dc1b6ccc20a5cfd10c6fd345fc766035c7478570d4ac534db3fdb718e2bdad3d096b137bfc09a562043800957e2afe4fdcfe292881f6189edfce52370c0438c2822ce3b14d73b3eff32f7e5ca97e989326b4e3a8fa35544193f8590bbb0ddb1f914894ab87998090771a0be1fd23917cd792be86ea0b98e6eb24\nA = -ec953f1b7ba7d561edaaa23076987daf86f50e9a66c36f0993290549a9006dd9d424885c0fa77295cfe34fc81c5edce9e2371b3039ea18d8f998d1956196284e6d81eb1c62ecaa8cf3fcaca28ca7e64342803c8dc3c139080bdd4a1ff30d7288b085a579d9e90903bd363b48f2072bb6fbfbd9ba2cab30a8a63784d246\n\nSquare = b33f4f3ae453058f4e865ec78f0844bab7af66a97dc2f265ca73ae2232777474bfdda39e10652d7386c16f145272192af728893c3d8a8e92c60d77722b924c30269ff5a399a2449ce15e50320c528c22655ad06227ac4efe5a993179ec61c2fc9115f89d75b53961fd16f7797657f6fbf55662b019608a1d30f64a2c0838e0018b7526921fdd34fd462bfcb2462b7065e2bc7abd57d71371e45dfd8fcfcc00a71f7e45430820747c9a060b72e4f6d2919cbffd00beb0c31a2bdc32afe2cc540b38dd04a2b73ae5ba481a6e535f37a757bbd6aaa972986213afadfa47cb7a15a6f1d443f93cb0ed824a10b4b7d82cae524a096b65ccb39be3c37c07f59\nA = 358da59ef65f62f633675764e292e5a68879df24a4727eca1fc4d232b3a6d936976c92eeb11456b5e8c11319838c145c6529d2f3acc828e55b8274bfe9afb5db241b102715f8e8164e454ef39f13ff1b37cf367a5a66c4f743c750896b7c3c29026e448bb36c6c06b0d9a3d048086ef0c3cd922a02e794223f388b5d646db\n\nSquare = cd4246489f6f221f920acbd8bdcdd17f47d2b77268f72254de4190685c123e8c5eab8517fded1852e8316c9e549d3fa355142d91b2921a3c94aafd8862cd2235429340da38a2af131b8d002f17662354f5805f6a7af7afb6dbd2f641036600614cea42bd8b24d86a5109eed29c0865a5f30c5291b1d1ef3223f9b9826dee773d98ce972da92daa19e843f84ca5f1cd77925a3c1117242ab0fb509b94a83f8de4fc8d21f856f37a4d025b3024bd0dbb6d8acfda4ab2993fd6eb7a7448d4f66ec725d37f0eb14eb242c0ff3f0c4572ba6b98a4ce905fe1b7ca3daca56c225171428c56af938fb66b37e99e54139157bbf41f536989ef813af738837afcd62290\nA = -e53ad05c88568f09f616797f0b7f2756fb543d691ec2a5b645c1e5892a247302826419a35b1348cfd2c1c569c23c31b4c46d6c57d4a488c29ab5beb77904d4adfcd0a01ea0a26bb0cc8790441cc2c8c900f030d7315b4319f1a3cf5685a140e03abe6b94730ad79e8de1f4a0cded86a3d6cfe2db267fa7dc9b2bb32872a90cc\n\nSquare = eea8028b26e0df090504d54da714a6f5f2695202e53cff479c78aedd47a8dc676243ec586740fde53b3eca9ca02b91031ce766242184109503fbe25b1b6d318e3cd5970fabd16dfa22984dd2e9f1e0f14c189170fc69c031d66663703e6235a942d51a4545bd7b0769d01d302ce2b00b83f01568a1e378f61fd0ca6201b0490330580cd9de85719e174a71915d7efbf65cd73d8f4e66f27e0dd3144d58ec09ed0f7ed7d1238ee596922807100fb7a11127944ddcdec6a9ca3bbf6df7301e354f3f049bfb7c275b43c3d8cda5907a932fba507c9145ea3166081c1b48fcc710ee32cd931f936c796b14f8a78a592e67753a7c9e428a01719c8ba82652f3a89fae110\nA = -3dcb44be1e54c5a5d7db48055ca9afa1ebe2ae648aa6e16ac497502a7deee09ffa124720fad0ab163ce8b3ea6a90f110ea52b67dbc424d0cf1e8c9726dfd9e45bebcefaa5cd5706edeed27896525f31c6bbea3d67ee97badefabf3e2532470b66e3ae3100f66ddf50cf02fc3a8e3f44c304251d3b6a7ca3a6e4bd5d16a41bd97a4\n\nSquare = 0\nA = 0\n\nSquare = 1\nA = 1\n\n\n# Product tests.\n#\n# These test vectors satisfy A * B = Product.\n\nProduct = 5befab3320f8f90542f3120235abd926aac3805a19e343f690\nA = b057af553afb120db6b7764f8\nB = 857734c4c27a1d17f7cf59dee\n\nProduct = -ab1ce167f4b2945c55ae3f87df50ad07d4be87cf9f8aa07b0c\nA = ae7a6a87ea8981a567d0b3ecc\nB = -fb0fed5f8c737bcacef4d6cb1\n\nProduct = -c2606cd48e6b075c8da79eb4668e7157f1f175c2860fd4c475\nA = -c28dc31984d4583e9d45424c3\nB = ffc4581a5c3f885cf42767e67\n\nProduct = aa6805b5408aff7f914472756da07830dcad902834dbdd6944\nA = -ffa07ff9f503511954e5dd3f9\nB = -aaa7af472ad8957763f5a7c64\n\nProduct = 58ca2569173389df29b5ce4b784086055dee821a7243db7210\nA = af417d936f4690008811a1ae8\nB = 81b26b80b43aa65aa55ded52a\n\nProduct = -a043d31dfce8bd01724d31c863d0a64f1bf013509d77737c42\nA = fb5fae5edefb6997d44a1ecd6\nB = -a336e50c6f7845a1686cc88a3\n\nProduct = -b5d6a45ffce851b201239d938ba551bab7dcb59fc11fc35fce\nA = -f918faa58bb57a2ffb8b01f05\nB = bae08c3006fade695029a1df6\n\nProduct = 6f2fde7d1a18625d727c6345ed85e597d546d9228bf7f0564a\nA = -8d108d7a16f0696d4ceb24445\nB = -c9c764cae465207097ef8d2c2\n\nProduct = 93808b1140841dc9735cd61c6f855ddbbb83066689b0d7e1a0\nA = b386d08daf3fa2154e9c768d6\nB = d2557dceb2d02d04d9c578670\n\nProduct = -ad04212ca8cadb1f7861c5130ba3a747046a2a7e4a0c72b69a\nA = e4e5f7d1311e0c5f2e404d55b\nB = -c18057a328d8c7375afdfd4ee\n\nProduct = -685e75c232f2b4a0e455fe5ee8aea52f292ad8b8178320e692\nA = -a683312f132b2320632e74ef6\nB = a0758f12791453b4af354730b\n\nProduct = 6f588c53185c503dc5b0dc3002d3817ca2e7eb2370b3e9a647\nA = -d70c9b93170261091f0c53f27\nB = -848c86c51a186ac4c9080d3e1\n\nProduct = 5e3bc5a04e054a9a244bf7c86cae215072fdb70e9199989427\nA = 898b64ef09d7cf63966e1a3b5\nB = af638b12f26aa5d12e97439eb\n\nProduct = -8d8372b235b16108285203c03a8aef6fdd3c0e1a9fd31d4f68\nA = f6003dc83818c14fbe36c9998\nB = -9343f6cbcc81fa4c9399dce5f\n\nProduct = -5ee6509abeeb7af7fc5caef40d1822ad3150c8d74f522dc7c8\nA = -875ff6f56ca72cbdf614bb9ca\nB = b375a68a21dfb1f159c22fa14\n\nProduct = ada25be404a17385af5a330da799e5909da81bfa0715baa6f4\nA = -c9b8df392e76abc3eb7d5ce04\nB = -dc5ab818c70594dd917b4243d\n\nProduct = bb24422ee4656ddfcd50ec38201b15baf679d3b75e5cb878ca\nA = f8e12cf4defe388b78510f687\nB = c07ee817b4ae95c2915b88966\n\nProduct = -93da296ba164c7220a17330647aef0980c94eddd2cfa2a3b2d\nA = bc5dc74ddf7a1363d1c2b1f25\nB = -c8f069bad7f93cbfe6df51169\n\nProduct = -6b2e1d132c4e0b0dc9b7e7de7d424fda5180480cb5ff47c755\nA = -a8048acb66a8bb88df39266e7\nB = a34e0b265d71435ae8c92a463\n\nProduct = 6ccb2cd93783576a8602ae43f41c786008b6623a4cca0a010a\nA = -b071f1f54790c951c1dd2a1cf\nB = -9dd89bb4d9b546207e282e2d6\n\nProduct = 5c742ba47d0d64bd97509927ce957deedb855766cc24c60016\nA = b44f3f252c368096fa62747f2\nB = 83439b97dbac579fa4f7b7d23\n\nProduct = -7347ba65691c913286c2fb55e45b177f031c1d86ae0e9f654f\nA = 937cf0643ffa53cdea24d642f\nB = -c81881f78243dd5737a7d28e1\n\nProduct = -9bc0649a703674e59f83ff9b8a560e5cbf51f65ca310f80f95\nA = -b536f8d9769be6f62da941ae5\nB = dc0746fb101881ae0cacde6f1\n\nProduct = bf4992fc3a124de350f9fb90ea825cf663b1fa051282ef22e2\nA = -ff7eacc7de1bb01d668c693aa\nB = -bfaa6627f9fc7ba68ae41bb2d\n\nProduct = 7c8992d34cc0b63f1c953f68d4e12a99d3f3a34d16bd76caa9\nA = 9e0d5a850d078890a983c0ec9\nB = c9b72c118b3e1f1023a696ce1\n\nProduct = -a75840c95082b9a0ae0d6e0a4eb5e09288e4e2a66e9697d9cd\nA = b2b042a21045a74ef1a5091d9\nB = -efbf8b120b384e869692a1b15\n\nProduct = -a510b333bdb4ed7479c142e8fbe2b12f7671a42acbe16c0998\nA = -e7fd5e0bb5496b9d876c27f65\nB = b6262653b2be44501af1d85b8\n\nProduct = a1c1e90afc4684754155526e307fc6ed798746f347bae2c880\nA = -b84674832b26ded0a690a8ff0\nB = -e0b7bdf2fd05a038ed3640b78\n\nProduct = 5588e0c33bffbefcc5695ca0615abd383343f21a8a0d22b222\nA = 80cad81ad9a66ab6a1c2e5669\nB = aa0453a77c8af1584f54750d2\n\nProduct = -6460c2fcd6cf3304ab163ea883ac48e2031cd10f2e9014c0ab\nA = c49ad3d7c8848d4fbf913b10b\nB = -82b3dedbe3cc7cd532ad632e1\n\nProduct = -a18717330b711669e85abde8c4dce426529aa621ba3da2a477\nA = -cab4a9c0a331a5a5e826dda1f\nB = cbfee5041c13075dfe3399aa9\n\nProduct = 8ab6282ee892b53c083d319a9dcab48af97a1ac8493c0bfcad\nA = -f7d13e47f9aaac8c25f9bf75b\nB = -8f4aa95231c1e2336aa092297\n\nProduct = 8f2d1c23c78777ed371f13155445ca3c88cbc0a9b299bdf9d3\nA = 9d8248d00defce1ad081337c3\nB = e8b479295ecd9cef7301f24b1\n\nProduct = -86d5e0c5b581fe59819730b4b71e33d1f85f9ab504c7dbe2d6\nA = b21b45e88acff48562a19729a\nB = -c1cdfebccc763beeac394b997\n\nProduct = -484ca05aefa113bdfcb1bc623f730c9f9555b462a8ab4c9606\nA = -8c12b406c02c4417163c0956b\nB = 8422b15c80c1c087b17eedd92\n\nProduct = 614c3c91f60050c785fd229a3ad74674577a90cacb654e0a5c\nA = -93d45bce155a23a397506d96a\nB = -a87e339c3fd5aebede5fb1b36\n\nProduct = 9683285f194a7e4feeab196a36bdfc4f828035fd184b9cc692\nA = f196d8fe760fdcae7eb60e2f7\nB = 9f7d88a2163ad818bf3a6377e\n\nProduct = -988a64599c19cc64f3cadc1a83fea6550185f6cc3ab82af822\nA = d0584b2a306671e4d2c9d0c7b\nB = -bb6e7559df199c68d6df3a3c6\n\nProduct = -68456814cb0edd951196d04c853172afdd5787a5bd69a57876\nA = -cefce1b0a1fb22862418bb597\nB = 80f614139947aea5e76cd55fa\n\nProduct = b4b1cbf5d6566e7a57aee0cc5c9c8ec4ad885e8766aa7662a4\nA = -d68ed1bea046c6cad057e21db\nB = -d7988b9be54f6e332d019032c\n\nProduct = 6b09212675ff5257a1384371e17b37dcc268bbb141577902e4\nA = a8208053adc20a609d5d01404\nB = a2fa927c5458c4fe662d7a3b9\n\nProdu", - "ct = -8361bc26f9bcf55f677e047d822d3004027da0d0455b244d10\nA = e82b6410b29020c2d6810a977\nB = -90ddfe0e7f0d6b9cdc0815f70\n\nProduct = -f1b6da00923fd513a83e32040a515649fbd362f69ebc016d9f\nA = -f9b697d9ec774a8d1ee5ea905\nB = f7ccb46a8869cb028492bed53\n\nProduct = d06206963f2e150bacdb32c823c3a47f013d5a267c3c0d0c88\nA = -ea8e63afa99c719897ad7f2ab\nB = -e36f11f55b6148d1b4f46e598\n\nProduct = af774a5eae6084df5ca499ef005642730adabf6a4f9533e2fd\nA = e4c7af7eea3ec9cc2443b7319\nB = c457bc264c8461789931baf85\n\nProduct = -76350f428bfbb95e6c253ec0f457aa84cebe8c7cb1af2a2120\nA = 8fd1ff97465775d44dee58ae0\nB = -d268a7d328f44baf80e35119f\n\nProduct = -787ae3f114f9a8dd4d249d5d3f3b0897b02564b9469416cefe\nA = -bc0b398bd0ec045b0cf147b7e\nB = a4050955c234e473257d0c641\n\nProduct = 9d6320b3d4aabac097a079b9bd2aca7f1898bcab0f23409fd0\nA = -9d7a4ebac630cc0662b816fb5\nB = -ffda517d3eb3214986b04e290\n\nProduct = 80bab8bd800ac8c9dc3bb57dca306f10af6fd88c5d8314833c\nA = 834bc50140d6c6ab938dc58b6\nB = fafee47793cbc533b3c66af3a\n\nProduct = -b08920f5922226b1dec87151ae087d8a7e5c1aea8c9be148b6\nA = bfd5b1ad323c79428cb2db36a\nB = -eb956a10edebdd658e6810fcf\n\nProduct = -6d428e08e8350bb4b0fae3b662c82df2aef7beadaa17430dbb\nA = -a57da276998c548101f514e9f\nB = a9040c1909712e1149d295765\n\nProduct = a57da276998c548101f514e9f\nA = -a57da276998c548101f514e9f\nB = -1\n\nProduct = 14afb44ed3318a90203ea29d3e\nA = a57da276998c548101f514e9f\nB = 2\n\nProduct = -295f689da6631520407d453a7c\nA = a57da276998c548101f514e9f\nB = -4\n\nProduct = -867614005cc204a8d19720fe13\nA = -a57da276998c548101f514e9f\nB = d\n\nProduct = 12bf3b676f64e5929d38c35e803\nA = -a57da276998c548101f514e9f\nB = -1d\n\nProduct = 24d8f92c68303ed0b96f91a8167\nA = a57da276998c548101f514e9f\nB = 39\n\nProduct = -49b1f258d0607da172df23502ce\nA = a57da276998c548101f514e9f\nB = -72\n\nProduct = -6fd5e6ca25c3d51b2e529f22173\nA = -a57da276998c548101f514e9f\nB = ad\n\nProduct = 1276d4705b81b82da4c7e82559d7\nA = -a57da276998c548101f514e9f\nB = -1c9\n\nProduct = 1ddb9abfc5d4017f068a67b5f4fd\nA = a57da276998c548101f514e9f\nB = 2e3\n\nProduct = -3a8b41c914b1b4a4e341433601f7\nA = a57da276998c548101f514e9f\nB = -5a9\n\nProduct = -97c0f4ba414d6e7d4c8b7ced84d4\nA = -a57da276998c548101f514e9f\nB = eac\n\nProduct = 1198739e0c23639c176d46d13f7c8\nA = -a57da276998c548101f514e9f\nB = -1b38\n\nProduct = 159150954ee0dedf541e4dbac0ec3\nA = a57da276998c548101f514e9f\nB = 215d\n\nProduct = -441d4bc44c86f02ff12c3d91a1562\nA = a57da276998c548101f514e9f\nB = -695e\n\nProduct = -64726b76005ebee27592237ba5dde\nA = -a57da276998c548101f514e9f\nB = 9b62\n\nProduct = bbe4ec7cf7c5bbd198e0ea86bb658\nA = -a57da276998c548101f514e9f\nB = -122a8\n\nProduct = 21f717d05681fd2eb1796776a69ef7\nA = a57da276998c548101f514e9f\nB = 348a9\n\nProduct = -396ac788a1748bc6955f99be4d2c64\nA = a57da276998c548101f514e9f\nB = -58d1c\n\nProduct = -54a213eb083aed1a04f3d1b2da62e7\nA = -a57da276998c548101f514e9f\nB = 82eb9\n\nProduct = 1366fb9c20fb14b8b9a9be4b3e3dde1\nA = -a57da276998c548101f514e9f\nB = -1e037f\n\nProduct = 238d65fd26da4733e5d93ab2485d40b\nA = a57da276998c548101f514e9f\nB = 36ff15\n\nProduct = -38272a99be154d531e922be405aee9a\nA = a57da276998c548101f514e9f\nB = -56dd26\n\nProduct = -64651b62b6a454c08951632c7f2c398\nA = -a57da276998c548101f514e9f\nB = 9b4d68\n\nProduct = fb272e3597b816144f8b945ae6130e0\nA = -a57da276998c548101f514e9f\nB = -1848320\n\nProduct = 280d9f5ed7243712ecb9a7c6358bcb8b\nA = a57da276998c548101f514e9f\nB = 3df5795\n\nProduct = -2fbb6bb8e1ba78cefc47fbbc20e188ee\nA = a57da276998c548101f514e9f\nB = -49d6652\n\nProduct = -57f29c13691ffa1642d2860dab9d288e\nA = -a57da276998c548101f514e9f\nB = 880c2b2\n\nProduct = 139c19d7668e6aabf2d7206cb0723ed34\nA = -a57da276998c548101f514e9f\nB = -1e55aa4c\n\nProduct = 2950ce04bf0cf836d4fe94b88fb757d0a\nA = a57da276998c548101f514e9f\nB = 3fe968b6\n\nProduct = -5175239488dad05a58414251496d2a06c\nA = a57da276998c548101f514e9f\nB = -7e020414\n\nProduct = -945ff0ed38bc6020cf679cbd3e0758c6d\nA = -a57da276998c548101f514e9f\nB = e585e573\n\nProduct = 11c69ae98f6b27e95477986f796bc67c8c\nA = -a57da276998c548101f514e9f\nB = -1b7f653f4\n\nProduct = 209afe75e8fb5ac76d13c06b545f5d4d73\nA = a57da276998c548101f514e9f\nB = 3270154ad\n\nProduct = -386d64b215e41506514f4988ed237e4da2\nA = a57da276998c548101f514e9f\nB = -5749c891e\n\nProduct = -6c13cccdb1d140d0babd52707ea72fa278\nA = -a57da276998c548101f514e9f\nB = a72fb6288\n\nProduct = 136228a8a45540372b9b3cd7f82021f6546\nA = -a57da276998c548101f514e9f\nB = -1dfc08a2fa\n\nProduct = 1f0ad3babf9d132eaa08cf5cdb8f19dbf01\nA = a57da276998c548101f514e9f\nB = 30050f2e5f\n\nProduct = -50d615ce183258e95af77319b766fac81e2\nA = a57da276998c548101f514e9f\nB = -7d0bf92cde\n\nProduct = -817d358293b86a56a4e881e50257c549471\nA = -a57da276998c548101f514e9f\nB = c84efb12ef\n\nProduct = f09b9e80be251de474d726b16e25a6865fc\nA = -a57da276998c548101f514e9f\nB = -1743322a484\n\nProduct = 22996cb0f9c60e35dce49f3825f8a479db26\nA = a57da276998c548101f514e9f\nB = 3585acec11a\n\nProduct = -2b307a37c91791a61c0691858f5f783e4678\nA = a57da276998c548101f514e9f\nB = -42cf6be3e88\n\nProduct = -8826698fcba6c30d755fc523de1cc25301ae\nA = -a57da276998c548101f514e9f\nB = d29cc8af592\n\nProduct = ae37fc99fd419809310782714530d7428d77\nA = -a57da276998c548101f514e9f\nB = -10d8059d4a29\n\nProduct = 1d544a20f9bc7d95ab67d1f65743979f23bba\nA = a57da276998c548101f514e9f\nB = 2d5eadef1c06\n\nProduct = -367897184e9929a0294d320f10278889fbeb7\nA = a57da276998c548101f514e9f\nB = -54431582d0e9\n\nProduct = -943a509076a00060a2e7fa1cddb7468d734a1\nA = -a57da276998c548101f514e9f\nB = e54bb102f4bf\n\nProduct = fcce6e42879af5ad13545c0bcaab85b690cea\nA = -a57da276998c548101f514e9f\nB = -18711db522cd6\n\nProduct = 258c49f86d0cbb14ae9edbd3456be8cede2022\nA = a57da276998c548101f514e9f\nB = 3a1562c7c269e\n\nProduct = -4a8bbce59ad7daa51136d557f7fa16e9a2faad\nA = a57da276998c548101f514e9f\nB = -7350e780b0f33\n\nProduct = -82f53ec9333275d5cc271876a7db936db49280\nA = -a57da276998c548101f514e9f\nB = ca94ad312dd80\n\nProduct = 11daee4fcc713db5b2806e47fa5dff3b5b770eb\nA = -a57da276998c548101f514e9f\nB = -1b9ed6758f9635\n\nProduct = 17038cac4f0c94dc24985ea108ae6682e175752\nA = a57da276998c548101f514e9f\nB = 2399b8a9b1116e\n\nProduct = -37e5f14394bf347a3ed061769fe8e6424af4348\nA = a57da276998c548101f514e9f\nB = -567840a7569fb8\n\nProduct = -9253d4a32a88d8f725984514d969012ead7cc9a\nA = -a57da276998c548101f514e9f\nB = e25b246f733f26\n\nProduct = ace3648371c16a931d29004e79f5b9678391da5\nA = -a57da276998c548101f514e9f\nB = -10b717b27b6a13b\n\nProduct = 1faa5b45d04c143c339b09d3aad94d39b94ef960\nA = a57da276998c548101f514e9f\nB = 30fbd672e106aa0\n\nProduct = -3fdfe246d27aae0d08d63b2bc501461d2bff3b8d\nA = a57da276998c548101f514e9f\nB = -62cef5f078a8253\n\nProduct = -5b792bfaeff04ee3d948cb343a249d49eb344f57\nA = -a57da276998c548101f514e9f\nB = 8d805ac65649c49\n\nProduct = c5f824406161eec321da5a58e3e00d393b55abe9\nA = -a57da276998c548101f514e9f\nB = -1323dd41d2e1e077\n\nProduct = 2226dec8a57be8e84e42559007e2d101ccbe67f8d\nA = a57da276998c548101f514e9f\nB = 34d47842b5d0be53\n\nProduct = -340f50f812c7420b502000940788a700f6769788a\nA = a57da276998c548101f514e9f\nB = -508836d8e1193d36\n\nProduct = -a00f1d96e19c590479625c5329a87774b5964cc78\nA = -a57da276998c548101f514e9f\nB = f798fc858657f888\n\nProduct = cb94f830cba8997331912a6a31c34f1bef826d121\nA = -a57da276998c548101f514e9f\nB = -13aec7a5c52a0883f\n\nProduct = 16b45140b048d6dc0b9fc811df7ce7dd88357fff04\nA = a57da276998c548101f514e9f\nB = 231f27f3e347bd67c\n\nProduct = -2aa94179351b4e87de5849ab619d94f47450640199\nA = a57da276998c548101f514e9f\nB = -41fe3ec2189599cc7\n\nProduct = -5489401d3da93158d4284e557d74016c0a7cfd935a\nA = -a57da276998c548101f514e9f\nB = 82c5281df41bfc066\n\nProduct = ae04d5b212ecfc9a6d7df07794d565df52991fb70e\nA = -a57da276998c548101f514e9f\nB = -10d3139229f5d02432\n\nProduct = 27821bc811f45d63089790b41d307be978d4b19564c\nA = a57da276998c548101f514e9f\nB = 3d1da85cc012b3e234\n\nProduct = -3de3c9e9d7fa3020a578706339314890dccf63096c2\nA = a57da276998c548101f514e9f\nB = -5fbcfb28bfc9044bfe\n\nProduct = -627dcb299a6720044abcf11469bdfd3f951edbb5bf7\nA = -a57da276998c548101f514e9f\nB = 985b930517b78e6ba9\n\nProduct = cc0622441497a37fddf1856d5e2c99df52b99ea4573\nA = -a57da276998c548101f514e9f\nB = -13b9b88948fb7e95cad\n\nProduct = 1a5168e1a492210591ad1ed660adde9110390e4caf32\nA = a57da276998c548101f514e9f\nB = 28b631c6e04b6ab0d8e\n\nProduct = -4d8ec27b7460ce616421b9f5cae708c2ac241daa59b4\nA = a57da276998c548101f514e9f\nB = ", - "-77f99bdf1eb09da6dcc\n\nProduct = -55afd796db7bce822a00073fc8926d3bd0c79772f036\nA = -a57da276998c548101f514e9f\nB = 848cdd6212b9bb3620a\n\nProduct = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34\nA = -a57da276998c548101f514e9f\nB = -154c39567bd8be5f6b4c\n\nProduct = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c\nA = a57da276998c548101f514e9f\nB = 37c6e7ee89cf87674814\n\nProduct = -39002ecfd6d96661b336157ccef6536756ad2e9219be3\nA = a57da276998c548101f514e9f\nB = -582cdab09915a652203d\n\nProduct = -695f49fc891d53f396f0593efae3973082b76d4f9e944\nA = -a57da276998c548101f514e9f\nB = a30074dbce2246af043c\n\nProduct = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7\nA = -a57da276998c548101f514e9f\nB = -1224195afc7b394ae8cc9\n\nProduct = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af\nA = a57da276998c548101f514e9f\nB = 26c6701c39334169e7bf1\n\nProduct = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100\nA = a57da276998c548101f514e9f\nB = -5436e84b4a29858a68f00\n\nProduct = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871\nA = -a57da276998c548101f514e9f\nB = c56e0f44fc63bca242eef\n\nProduct = da7fe3367ce640fa5941c033ac1874312f10ba5950da75\nA = -a57da276998c548101f514e9f\nB = -15200043166ff309f0426b\n\nProduct = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57\nA = a57da276998c548101f514e9f\nB = 25d057879db26fa29a5e49\n\nProduct = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857\nA = a57da276998c548101f514e9f\nB = -5e46be70de21949df67349\n\nProduct = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63\nA = -a57da276998c548101f514e9f\nB = 9238670897685a6c9cbdbd\n\nProduct = f623344788efb857db55c924e95a437effa4dc8bb2bcd24\nA = -a57da276998c548101f514e9f\nB = -17cc0ec84c228225a7cf45c\n\nProduct = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72\nA = a57da276998c548101f514e9f\nB = 20f9f925b3ed307edbb154e\n\nProduct = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f\nA = a57da276998c548101f514e9f\nB = -6c5cbfd29f3dae1dce99221\n\nProduct = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43\nA = -a57da276998c548101f514e9f\nB = 9136aa79080defd1bcf90dd\n\nProduct = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd\nA = -a57da276998c548101f514e9f\nB = -1d03b512470dc3052779f3e3\n\nProduct = 28388a244214abf046488a8d95308d95f021eae4b994a5a52\nA = a57da276998c548101f514e9f\nB = 3e37dce784274962ff862e6e\n\nProduct = -4da476e76119deef291c0f56934a912a0877278a19a561ee0\nA = a57da276998c548101f514e9f\nB = -781b2f2dc40094a7f8fed520\n\nProduct = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82\nA = -a57da276998c548101f514e9f\nB = 87772a4fb582acafd3e4ef3e\n\nProduct = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa\nA = -a57da276998c548101f514e9f\nB = -1563841bf7851ff158a395716\n\nProduct = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752\nA = a57da276998c548101f514e9f\nB = 3918c30b5568318a58e9be16e\n\nProduct = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a\nA = a57da276998c548101f514e9f\nB = -542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 0\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 0\nA = 542fb814f45924aa09a16f2a6\nB = 0\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 1\nB = 542fb814f45924aa09a16f2a6\n\nProduct = 542fb814f45924aa09a16f2a6\nA = 542fb814f45924aa09a16f2a6\nB = 1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899f571f257fa81c36a868d80e7fa2bcbda68a72ca3e31db8892b94d073e006433dd7128b7bf677d2b411532e5662cdff66d657673d58e03d4a338bae1a5513296f91d4d2b5b680527a2e12318e422ec2b7f05ea4fd3ef4780576488211dad5733685a8f0e5d2ecda549a15eebb235495e70d26b194c994cf16d98d356218d08a34d1593d90bc0d3572df0e84bdb1705c6c5e64ea4895599bb21bf219abdd4329813ecc198e708cee199c22f749bdeb0c206690e8420883f6c0661e47b29969986a7a72996ef63234c31aa39b7be37995d2898063ef5c3b672c43afbc1a065dec2671ae87e17639cfcd3148145a8323e1e9dc4f9c9daf981dd6aba4e8be01344c2eda185b87\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899aa73af54a4e1825aa6714016da99d9e3d0c02eb139716db437705cd9efabf0123b0831689735f4e488f226e577d4688d30914dd50ed368939452af0a7a094c065c6718bd54f53a808585fc1728c3bd1e7c968d76c6dca32f95a8323bacad31cdd4aae544d4208262c40bcf726c2f26cf1e60341c3e1e0c8ed4542555b9bf00488680b737a245cc9b7817231f1f6f1e614cdf43ea281fb850ebbb9305b1aa441a45dfdaa1e98b9d79d9ca511be070bfa94d8cd3cc750607c93e1b451a14e32356bd48d77860b37fd2e714827e770a5648ce8579a00ba5cae034502a8b03ba754994d9e002130cfdee6bfdf078dc8f6767b927c964197664c8e32bd3d31bd461ce\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46feff82a92989bca577998c68ee619d9ea9972c6f139e97f5bdde635152830bedf302873508d2ed73badb82f9e32e1f4d12ea8c8b1059aa6d15f8e17d649bf41467903ab40d220d50570b5a263f637c0fcebc0ca29f8a81e2a01bf39bcb60cb9229dfd40618f706b941836bc5c291dec45ee9193e74d3a4cc5f73054ca56fd774a359f17a687268587393b76204a37cd48dcb09d3daed57a7e6d7d93a0ca3d6de8557fc4ddbfe9cb163fd10b7fe5f270dc57aa2fb88cdca2a3795015a17fd352d85fb688a38fa54883d0cab67aab08dbabd58d307c601f0f810014d78b101ff0bddb6d550b24807", - "82406a905b9201e70ef6c1cb9765e91c10c8f5d240c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e3812764dd3ebb7489e6e66058ca6ccf9c007f8c049eda369b2889cc411bca78d4f5b0e3a9e80243e87e112072b01922b595afdef4dd562e58ce917f11e69c8fe050de54fdb2d607d05f09afd6dd140e9d195b91d85269610a1e5d5036e8c9fea2d4fa693d80ecdc819b201c0aed27dfe0b92b4b3b9ecabb3b9548f0d27dc917ffb14308c4f970863e163f375852fcd9fb115640dc40534f8f51a7b903599117dca6c80924fa9a1aeb43cf5a9a3f67ae818b484feed51d7ef60b3656720891b13a983c02c281c8a0954f13b7bfaca844d2cb66de5c11ff507e39cf774c7c93b38e296a44f04e5ecf2819b57943fb0509774ddbcfeb\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899c7bedb01951b0f4fdb2c0fb64ad74707fda20027f4cee25da9b59be288d404cbd348f27600b87015d28f03cdf411f0e8c22deb9de5b3e0094f7820d78d59c90017cbd426297f8a32fb4b55b09362cf7cfb5910085acb24dbf618752b8b74c7e87f9cac44cb3b7486c43aa9b19a64d40a74eaf1de8b5f168b43d5750236aef753278c11294efd1adaddb6addb846f45fa55d7391898e8ec1c82bcf0008d9850c4c096571e8872e975dc8af1ba01bfbe8c8c27dc30cdaddd198936e4496579741a3a20e1b8e17241fe4abe5e98794e469180b742b2e1904940381f703f512885bda0340fe74e997ab269be00a3ca29bb937db2e06d8054e26dc13a5014ba51b175\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d88997cc097fe3f7ace3ffb0fcee52b45551165bb02354b229788b59128489879b1a0373e9862a17692464a2dfc5d09185a0f1c67d2359ba70b52b03f21c7b24feb96e25e1a2dc7f4723952bf203979f7c9e38790f881e2b35006157825555d4c867fce9ea0a3cc6f1c94ee308a68e33f64f286247465ffe854033e9c64f5d79d6d66dcb38ad03535b20376bf4c3cf26e07ef445192ba2baf08bb5286695a61ff6b5dc7aa1832017198d61a324b8c244572157323c7bb3a2fee226133e1b0e0f2ff067cf71fc24bf38d0e172f459b0cdf0707c5bc586390faacf428bfdeb04e850ee0c35f6807eb6ca8d3a473dcc2239541115a8b0d33ea33295ff8c13b2a\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46fc245133c3335163cce37555d36c555182e6d9a754b9aa9305c070083d0fe806d2c5eda4a976f749d6ef40515c425e6531a7f4d11926e49907b7a8a938205e0d6fefaacb145200cbe3deec686476bcdc1f6bb3535147ecb00818f2cd666ac0dd497f0fbc087bf05c6425b7752a02e2a695655d4310f04943a6178946a74dbe4688bd1eb3f1a166aef37e39f3e1d36b6d6d422ec0db264cae8d44869f57a92952bd74a026dd7cfc672803905f029c723487d4123a7520688fc9c68b2384be32e881f64d0ed7ae555bf00e5799740dd8c6accc40f3fe573f194f4848bb05aea8a5509f2dd10fce023093f1ef20267244a990d7ffd462f4e85a4\nA = f33cad5d3876f0b6", - "0a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e353744d86d954c06f3b84ef271b184ac9957a5f88b08b606fa6aa97afc4983a62f1e74aa3f242e14a3f4cf5ea415d1437818663556a29d117ea7df1cf1ee32f70d6d5566e25d53f892c42d3f92e481b622455fce36e400de09e2d435099695354ceee249c793b76b3c544d70164381e0420ef8b85609502afff9130729ba7851e0775dc5d8c606ba614e7607625fbc38908c88fac43e29ff9b8728f5809e63f20289246b5128016478437550a833c60edb0df43dd9a47654f2e4ef308d4a18cea57ea4b0c6d08add07f2e7adc427cf591c29dbd1f975432922e3f2b71c75e4d2557efccf626be7a0d522b658d420ae321\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7be8e75d54e5ba9405f671d624eaf8d7a115d0479f6fb773b940525fd46b69bc43c815b6bb1798813ca95790bc68032f0b9e73fc964a9922507d8aac25f859745939b828ef5ed326b226b555e5088f13531be16272a89ad41ae82c940935b5d8fe75dc520a230cc279a887bce01bae0a79356f044af13c6f4a5e53c00b2d03cfcbb0f93b26202441a207ec91576410ac1750e257906d945bfe9204b73fc417600bd191edcf2e3eb79acbf4f84dda372405b5e98397abe85c1593543cd7a5b17cb90e299f422f0ce107d86b56474e435dbbcbb5314fb579cd68d54777aa2d0ff9b6b96de62b4676edea5b09589698ed829cad22a52aaec732b79edf6af\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7739032d1f8bb68307f4adc912f1d9b83797606874d4f2c669fe0b263565c4898a07701585237aa444234719adb869c17142126611a9cbd6e689fabb2847bb9dc5e2dc89694621a7179df1fe7371deb9bbdf5fea0b271d86bcde2796a65331c27365fb97fa3647435c47e5c854a95718fa49072cc239d046ca0ac2bf453beb31070370d59483adb42b9876776e43fccb663887f1a999f625eb8e9c4cdd0a89099c42cdff06be29ad9ea66a957002925c9425a83c3e74096ca31324134f5d4a2b7d3b8d7fd8d72192049f79c670874f65201c068c5aac2008a7df4e5eba02d88be8ec23683513a9cffe06671a7c2fa5da7a7aa571914caba1e\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a808857c1bdb914ae0fec75b02d527263093a9d9b8a42289ec74dc73e0e46568a9e8ee117659597434048308c9b66fa7a539694285b1238a13d1163fbac33db147e5431af1c7aca5b1a118db4f6650ec6340491ef7a2d203b53e43d536639f980eb6e92a37bffb2149c5eb45d6718a9496f0784370674c1d29732b944a3c3885b68f0fd2a121f556dc82d1b942e7aabba780f087b9df359d86e2055248c3aabc568e93bba67d3ccca2c4240c876506d63bb05aad6fc4c77dfafff1731a46c6711bc60c4d23976268928bc63e1d133add0633c737bb508c81fa1ff3b452b49b992ebac930432d555ab8c62ae17357b1186e80689672f5a9f472c\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be8", - "62f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6783ab6c7314a43e85a92955a5fbfbffcd31ef0913ba93563dab2b7f54d90fa21ca827ad15b5b1fb399a303f94837536b2813cb563f793fb780e91f8333a2de7bb9f10efdb652a504d6f242e7c15362d3a6eb6e3d1a5abb03023dfe964656979765a14fe8fc36af3d785030ce549b92a91dcb8e2aa13f5b89eb8449b31961a0f77117c8cac79af95ee69f6594e557af7bb017cd885027ff7c0cb1d2f99d1ed5eacb788f645c25150e737cf1184b546bb2d55f2014a18015ffe647580df6fe4d528ce983309baeac0347ae8739e2b1f6d1a83e12e4dbfea1cd81b11b8628837432ad1906c70323529b718c8c6e398e1dfa73\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f225bca564b7e6561b56e0edbb3a7f5934f382b916ab38423221d656357ce0e9bf1e9b04c0678b9c555e8365a0f977c95bd8dca1fb2ad2268193531ca36cbe7f40da8e1afe097e451dc2931b323ce731c03cc027a92ed8ae105c5e9c1bd385e238d989fadbf3aa54c097a8666df8a66b7e2d016e65a2a632603f2c84290ccd7346ada28dff79dd06c7f7989689aca4f494b977f984650f91327ab9936cb92675932440f135e54e4abeecf255d7061482b4c8d91769e02fc94b8acc43325d69541903c3ef7a7a8a5bd19bf886506d42bcf0efcb6197a8d178d6a60516a5aa771ae238a342dc61df8c18c6ba1ed952d4e0c3409c14639\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f2210cc134828c520a58df29ae28863a158a044937809d7d84d2940efbdddb448c64da5f1f31977e7865fd5529eac82fee3e804064a6315936295f8cb26f0de16a47373f5e8365939e280a57dacb508166a583a630c75730c2fe54971e70a35e224e7a1a21e3bd8f417a47c4796d34148cae15068e19eec637bed8f32846dc5aa7e8f50599e840903a8129206fc384e0b4085f9f1e7e3bf2fc67b62b02566ce73cb4b22d471cde35b4f0cccb74283cdded5748d62286f7ea5c184c1308d520ecc7c7f1535b1132708298bf94c0967bc8f8541bb2f2b3c81f11e50f1d8cba4ce3746ad5f85e6bacbefada657c9b386b991b2\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c36ad2daaf856508e861c7f68a2611a215a93e3a15f68f72bb80a4fe9f4cfb6c7f91639179342c633db0f70c9dd849b5b5767908b27e61b812659dcd1a0613433f2c0940be49010886bb384d4676bd523f9827c1a48c7649fbfa73e872a5160796813956979b0f3fd3af728dd48f8a7348090300e41b181c8acae08a3b3106b61f90b0421803e6eba0d68e9bc93d3b659fd6316ba2815cb4b3b6a74f1f3fd24b0c07f619d995ac2beada44188eb72d371a6894f90087eaabe148755409bbff60114bcfefbfe2182e6dc4218d0da75af80059bbb14e848c2e60790fb35bf1cb685cbb133b2baf3f2faefcc3f69e34102def4\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c0701452188", - "9172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954\n\nProduct = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef9518c8ddd2bbd782e5f8cb06be77fc8d0c29f12d4ce67bb2478369710d003f0cb6f40a1341a5a5f2509d2d189084ea4346a44368a54f44c2be4c7b90c4d22976a31985927d0379b2e5d715a7e67eb3228943a07325a29316c695867e8f4ff676e00ffca0a6dfe8fe24652aef9e7f12616e8a54e367b90942f543a01dc7c1b8000ff991228ae83fe0131cfc235ba12ab2bdb33bd4ab0ba1b356bdbc6da4a70eed9fbf2c704e14ed6230eb5478dac0b02f4def1d8c076d1c0c0e2c4cdadb248de4acf961cee51dc41e545bd5a605a0860fb343c28ebf3f8814a9d5a7e0f3e9c93e742db76bc5671258d1da7758b41efead5\nA = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9\nB = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad\n\n\n# Quotient tests.\n#\n# These test vectors satisfy Quotient = A / B, rounded towards zero, and\n# Remainder = A - B * Quotient.\n\nQuotient = 1\nRemainder = 0\nA = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\nB = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c\n\nQuotient = -2\nRemainder = 1\nA = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b\nB = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d\n\nQuotient = -4\nRemainder = -2\nA = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536\nB = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d\n\nQuotient = 8\nRemainder = -3\nA = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b\nB = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89\n\nQuotient = 10\nRemainder = 4\nA = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4\nB = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b\n\nQuotient = -20\nRemainder = 5\nA = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805\nB = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40\n\nQuotient = -40\nRemainder = -6\nA = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86\nB = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee\n\nQuotient = 80\nRemainder = -7\nA = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87\nB = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b\n\nQuotient = 100\nRemainder = 8\nA = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08\nB = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c\n\nQuotient = -200\nRemainder = 9\nA = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09\nB = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05\n\nQuotient = -400\nRemainder = -a\nA = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a\nB = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6\n\nQuotient = 800\nRemainder = -b\nA = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b\nB = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b\n\nQuotient = 1000\nRemainder = c\nA = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c\nB = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae\n\nQuotient = -2000\nRemainder = d\nA = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d\nB = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe\n\nQuotient = -4000\nRemainder = -e\nA = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e\nB = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8\n\nQuotient = 8000\nRemainder = -f\nA = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f\nB = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1\n\nQuotient = 10000\nRemainder = 10\nA = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010\nB = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2\n\nQuotient = -20000\nRemainder = 11\nA = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011\nB = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e\n\nQuotient = -40000\nRemainder = -12\nA = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012\nB = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166\n\nQuotient = 80000\nRemainder = -13\nA = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013\nB = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34\n\nQuotient = 100000\nRemainder = 14\nA = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014\nB = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194\n\nQuotient = -200000\nRemainder = 15\nA = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015\nB = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d\n\nQuotient = -400000\nRemainder = -16\nA = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608", - "663e12291e9b0695449c1153800016\nB = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e\n\nQuotient = 800000\nRemainder = -17\nA = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017\nB = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec\n\nQuotient = 1000000\nRemainder = 18\nA = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018\nB = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd\n\nQuotient = -2000000\nRemainder = 19\nA = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019\nB = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5\n\nQuotient = -4000000\nRemainder = -1a\nA = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a\nB = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722\n\nQuotient = 8000000\nRemainder = -1b\nA = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b\nB = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a\n\nQuotient = 10000000\nRemainder = 1c\nA = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c\nB = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336\n\nQuotient = -20000000\nRemainder = 1d\nA = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d\nB = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9\n\nQuotient = -40000000\nRemainder = -1e\nA = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e\nB = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5\n\nQuotient = 80000000\nRemainder = -1f\nA = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f\nB = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b\n\nQuotient = 100000000\nRemainder = 20\nA = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020\nB = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d\n\nQuotient = -200000000\nRemainder = 21\nA = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021\nB = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18\n\nQuotient = -400000000\nRemainder = -22\nA = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022\nB = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab\n\nQuotient = 800000000\nRemainder = -23\nA = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023\nB = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed\n\nQuotient = 1000000000\nRemainder = 24\nA = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024\nB = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719\n\nQuotient = -2000000000\nRemainder = 25\nA = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025\nB = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867\n\nQuotient = -4000000000\nRemainder = -26\nA = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026\nB = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226\n\nQuotient = 8000000000\nRemainder = -27\nA = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027\nB = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2\n\nQuotient = 10000000000\nRemainder = 28\nA = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028\nB = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34\n\nQuotient = -20000000000\nRemainder = 29\nA = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029\nB = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd\n\nQuotient = -40000000000\nRemainder = -2a\nA = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a\nB = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608\n\nQuotient = 80000000000\nRemainder = -2b\nA = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b\nB = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12\n\nQuotient = 100000000000\nRemainder = 2c\nA = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c\nB = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1\n\nQuotient = -200000000000\nRemainder = 2d\nA = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d\nB = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1\n\nQuotient = -400000000000\nRemainder = -2e\nA = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e\nB = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54\n\nQuotient = 800000000000\nRemainder = -2f\nA = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f\nB = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb\n\nQuotient = 1000000000000\nRemainder = 30\nA = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030\nB = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7\n\nQuotient = -2000000000000\nRemainder = 31\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13\n\nQuotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346\nRemainder = -16e346b6a4297\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 30c77f3380ccf\n\nQuotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2\nRemainder = -16ebc86eb88339\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -197b6f6ad5b75c\n\nQuotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a\nRemainder = 9bab19f12d81c3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = eb90162ecae18b\n\nQuotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240\nRemainder = 1e4f817a2f52b71\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf04674", - "5436391a673426000000000031\nB = -546c109fa8a9d7b\n\nQuotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b\nRemainder = -292e149300fdd1ad\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3246242094394c8c\n\nQuotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608\nRemainder = -dd3b3e32ddc79cb9\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e928618913898b2f\n\nQuotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241\nRemainder = 16e021603d30dde2\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 948887c1634f4b08f\n\nQuotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253\nRemainder = 407ccb4f0b814dc5c5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4ad17434071e1ce664\n\nQuotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293\nRemainder = -36f745b0f421d16db7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d71635bcc25183cdde\n\nQuotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82\nRemainder = -107334ab98e5099fec5f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -198a54e35fa0cfa328a9\n\nQuotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42\nRemainder = 170ebe9b83d4c43b79ab\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = f8e923a8bbc0242eafe3\n\nQuotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d\nRemainder = 4d404e93edb435dbd60af\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -52e36cee22274556059ea\n\nQuotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6\nRemainder = -3a2ea5f9d204dc31f21833\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3d3c79a115d9071b573d2d\n\nQuotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2\nRemainder = -17d02758f8fcadca911a95f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1cc65a75211f2826c9d0811\n\nQuotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac\nRemainder = 5c95323f3b8861261dc31ed\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c516e6e3fa6e3dc52cf5933\n\nQuotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5\nRemainder = 1fc63797594c56160536faa9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -462ee529b488d1db2b6c60e8\n\nQuotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714\nRemainder = -15e79293d5e055f906381a899\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 32765b0a34c88864d39bedaae\n\nQuotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b\nRemainder = -a158ccc7c055d64e7df3fbcf0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -10c061a37f6cbd11bf0c327643\n\nQuotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174\nRemainder = 21e766a0020ba429b330a325d5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9435cd2dc2a92c950bb9e69b83\n\nQuotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d\nRemainder = cafbe9caa1f83fd0dd3d5a6881\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7924e4dcf8f96da61f54bf83870\n\nQuotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497\nRemainder = -94ae72f78982ac1ff83f300cfe8\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3ad70d4b6b9b5f5b2eb65da67e1f\n\nQuotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155\nRemainder = -c83ac7582a02b47ee734e0f24dc5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14bbcff5423a260b21895327b18bc\n\nQuotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03\nRemainder = 8e07efb8ae4c9df39533042362081\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 93aebb72a81ba68e8881fd1a56a90\n\nQuotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90\nRemainder = 794801d9d5770a60e312b99d6b9f91\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7e408caf387a0ce9bbf4309c80755a\n\nQuotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68\nRemainder = -24227c242afedee2473c1a66a5cc29\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f622c665af7f8126eabfd90df8e9c5\n\nQuotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432\nRemainder = -dd290149e0e159f9ba6bb9f5a4b003d\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -14a7623d1d9dfc177e913d3119d0d30a\n\nQuotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb\nRemainder = fb60aff5fdd2a2b794b0d973ac4d92a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d439da27b5e70342aa5cb365ece15665\n\nQuotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515\nRemainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -50700f9c0da59482165a47a3eda2bf07a\n\nQuotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3\nRemainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 383c5a4f1767e83fc382ad4f1c7c2b7ddb\n\nQuotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437\nRemainder = -1035512a2717a89062d48f1bfd213333ed0\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1402b751a1e5f3fc46e22b43240d6ce9b27\n\nQuotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe873570ab\nRemainder = 72935d534bed5ba557b91ea023601f50b1d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 9b4df766c608ff3efe5ea1f65cc850fa73c\n\nQuotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2\nRemainder = 249f6433af4e8e224eb570fd438197af62f3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6b382f812816c77d65c94c0c660b31a69b8f\n\nQuotient = -5f3ced1e42fbd3c6b2c6f", - "1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8\nRemainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 31bc97372d17038fd842b72eaba2abb26df62\n\nQuotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335\nRemainder = -a1493bcbf57a8480461d62796aa8f8541ece4\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9\n\nQuotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c\nRemainder = 273e33521f4d74840a96b3fffe169f79d32855\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = ba7746f4400f812919a3dc86b00642e1487691\n\nQuotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f\nRemainder = 456ebf56c636d54e37709b9e799e83b7a08cb93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2\n\nQuotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633\nRemainder = -4f62c678137df301c4bef216e6aa910104e76ff\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06\n\nQuotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38\nRemainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1daecf01ec633610373b79e04c22cd7499012bc66\n\nQuotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe\nRemainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a1598a12a84e9cba42ea0e200e88d4599c9f615fe\n\nQuotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7\nRemainder = 4610b2b1305220bc0de584dd3f87d90109012a8077\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6\n\nQuotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516\nRemainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b\n\nQuotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2\nRemainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026\n\nQuotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35\nRemainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b1b959a7b3262d7f4dff488315903aeaffd982b726d7\n\nQuotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada\nRemainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f\n\nQuotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd\nRemainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894\n\nQuotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e\nRemainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7\n\nQuotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546\nRemainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d\n\nQuotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162\nRemainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a\n\nQuotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062\nRemainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831\n\nQuotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf\nRemainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017\n\nQuotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec\nRemainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0\n\nQuotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9\nRemainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae\n\nQuotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00\nRemainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6\n\nQuotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485\nRemainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd\n\nQuotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9\nRemainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b\n\nQuotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502\nRemainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7\n\nQuotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb\nRemainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04\n\nQuotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab\nRemainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80\n\nQuotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532\nRemainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067\nA = 1280d26263c574f655e", - "a63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d\n\nQuotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83\nRemainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8\n\nQuotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778\nRemainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b\n\nQuotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2\nRemainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9\n\nQuotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012\nRemainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2\n\nQuotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d\nRemainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644\n\nQuotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73\nRemainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97\n\nQuotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb\nRemainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82\n\nQuotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a\nRemainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff\n\nQuotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3\nRemainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046\n\nQuotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1\nRemainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f\n\nQuotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2\nRemainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b\n\nQuotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413\nRemainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40\n\nQuotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337\nRemainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575\n\nQuotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508\nRemainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714\n\nQuotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9\nRemainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d\n\nQuotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f\nRemainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694\n\nQuotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba\nRemainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6\n\nQuotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1\nRemainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb\n\nQuotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984\nRemainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235\n\nQuotient = 180054f8c36833d44cab9dd61e6d89d28605c564af\nRemainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018\n\nQuotient = -31412e97045c19ec38951b0e3884c66d1d7479437\nRemainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3\n\nQuotient = -8da1489ccf7203ecead94c67a5750884122b6e75\nRemainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467\n\nQuotient = e635f8bdbf80e99723aa5718d3fade4e573be2c\nRemainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed\n\nQuotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851\nRemainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f\n\nQuotient = -382586dfe93872abbe3a504fc62a8973913f96\nRemainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec", - "8edea425\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52\n\nQuotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38\nRemainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c\n\nQuotient = a9f7e5f235bae0e3e29393ac5c99d510b009\nRemainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba\n\nQuotient = 16de125df5936181981b4c2d0051a8b4d211\nRemainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040\n\nQuotient = -268a52cd10ab4814268f66d9f44f71a98eb\nRemainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85\n\nQuotient = -8f051067ccb82b6a3dffedd0ff2ee97c46\nRemainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7\n\nQuotient = 9b7ee4c499386f922432fcb1a453ee2ec\nRemainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d\n\nQuotient = 23efb26228d7bcf281cd45f54572e2b3a\nRemainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413\n\nQuotient = -2cfcae0e922f2d884bfa0a3346dc9812\nRemainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072\n\nQuotient = -4c0238ff3c18d4d58e543f020002802\nRemainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b\n\nQuotient = d41f9102a7785ce64f76b7d7b870b0\nRemainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d\n\nQuotient = 1616b432b3277e774aad92b0cf544c\nRemainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79\n\nQuotient = -320fd6a7375a42a3961362ae196d1\nRemainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb\n\nQuotient = -4bd06daed3f30345d269f51e4381\nRemainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5\n\nQuotient = d6fd01a0c5b55fbe36e58bbe77b\nRemainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642\nA = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d\n\nQuotient = 18bd9a8f5678d28cefd955cf99d\nRemainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa\n\nQuotient = -371239db55c79521206c9e60c0\nRemainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371\nA = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031\nB = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91\n\nQuotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee\nRemainder = 9f0e50ca76031b\nA = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9\nB = 1b1313037e30f4d9\n\nQuotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17\nRemainder = 93d7c547a9ba0a4a\nA = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1\nB = 9ff8df899ee3b3f1\n\nQuotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297\nRemainder = 6c97aace900389d0\nA = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48\nB = ec7123556af55a48\n\nQuotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315\nRemainder = 2903c7cc2651bfa8\nA = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e\nB = 4ea484a22ab0ad1e\n\nQuotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452\nRemainder = 4bdaf1f352e87aa5\nA = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb\nB = 5d42fe145e66ffeb\n\nQuotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29\nRemainder = 55422f1caf4a9a00\nA = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0\nB = 908ae83784ee35c0\n\nQuotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b873787206babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053\nRemainder = 124768541b600598\nA = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14\nB = 16d2c4a24099ca14\n\nQuotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae\nRemainder = 1ba15c46023500b9\nA = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243\nB = 40548136ce50", - "f243\n\nQuotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac\nRemainder = 4cdfd72349c6110\nA = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0\nB = 3a74bba39671fcd0\n\nQuotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88\nRemainder = 2950443357cd7477\nA = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f\nB = 654686ff1368e96f\n\nQuotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5\nRemainder = 3013136f5f728b68\nA = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6\nB = fde3ee3bb61767d6\n\nQuotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0\nRemainder = 1f130dd2ead0d35e\nA = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de\nB = 5b22f9d795df09de\n\nQuotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8\nRemainder = acb8702f0113e0c4\nA = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4\nB = b48a6b29025983a4\n\nQuotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d\nRemainder = 3d1890c5e1555d74\nA = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121\nB = 61c602477f849121\n\nQuotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5\nRemainder = a93a0c5bd51004e4\nA = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf\nB = ef1412873b2d8cbf\n\nQuotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75\nRemainder = 1ce3e5eb13ac7958\nA = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2\nB = b552d4f7eee617b2\n\nQuotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c792e5125e322c27daa73301024080d73ba3491484b659\nRemainder = 3286bdce6dc3a828\nA = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691\nB = 85735e9b78002691\n\nQuotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087\nRemainder = 135784870eb40c68\nA = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844\nB = 22d76a26aaf9b844\n\nQuotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a\nRemainder = 27b105741264f875\nA = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083\nB = 81a39fcadf738083\n\nQuotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed\nRemainder = 95f7434941f9d8\nA = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe\nB = 1ddd0ab110b89fe\n\nQuotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8\nRemainder = 327cf78eed336523\nA = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb\nB = 4ab08ad74f7be5cb\n\nQuotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95\nRemainder = 3b2f844440d7be00\nA = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680\nB = fa8e03d9ce6fc680\n\nQuotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516\nRemainder = b620b7a3b752b78\nA = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468\nB = 115100eddabfb468\n\nQuotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4\nRemainder = 53a0fcf5486c7a6f\nA = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b\nB = e340e9da9b305d3b\n\nQuotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d\nRemainder = e7751deb047d98\nA = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6\nB = 542fcd4a46dcff6\n\nQuotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0\nRemainder = 7c667ea307017c2\nA = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62\nB = 177907198f85cb62\n\nQuotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb\nRemainder = 429a380c9f8eeeba\nA = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67\nB = 432376698f8d2f67\n\nQuotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df\nRemainder = 37924fea665f5c92\nA = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9\nB = 9f8220509f5106b9\n\nQuotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88\nRemainder = de179463e3e91ad\nA = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5\nB = 2c0323980d8841d5\n\nQuotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3\nRemainder = 6bf69921db298b3e\nA = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9\nB = 83a458f0372a57c9\n\nQuotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539\nRemainder = 11c077beb8667d88\nA = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419\nB = 28d6ff55d5662419\n\nQuotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca\nRemainder = 1672a8aa119c3a1d\nA = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b\nB = 54df334dbfcfdd4b\n\nQuotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871\nRemainder = 44c3fdb374bc0c30\nA = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff2a3627d5b942300200c823d764b7a6c12d1c91b\nB = 764b7a6c12d1c91b\n\nQuotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613\nRemainder = 2718de2dd0796f08\nA = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c\nB = 51169b54c62b779c\n\nQuotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd\nRemainder = abf5f6c8ab6ed4f4\nA = e2bf43c91cdbb24", - "4790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1\nB = b682c7ee6ab5f5f1\n\nQuotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930\nRemainder = 6c3802d44dd4668f\nA = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f\nB = a71d9ad67ff2ff5f\n\nQuotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035\nRemainder = 660a35e1c1245910\nA = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac\nB = 90593662c86fb5ac\n\nQuotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7\nRemainder = 2e4aeafa2ad76832\nA = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d\nB = cafb4e30846cad1d\n\nQuotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a\nRemainder = 8395953f744cfb31\nA = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967\nB = c473dc8dfed98967\n\nQuotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26\nRemainder = b8ff45f31bdb58d8\nA = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08\nB = f9414ed2f4ba7e08\n\nQuotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6\nRemainder = 7856ec047cec8dc\nA = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14\nB = 2f4916d8b6201d14\n\nQuotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157\nRemainder = 83649246ade8bb4\nA = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72\nB = 84eabd4ea553a72\n\nQuotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811\nRemainder = 3daa032278ce53d0\nA = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba07b240886a6d5766cfb3ed0937a543\nB = 66cfb3ed0937a543\n\nQuotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd\nRemainder = c007da44faa80584\nA = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5\nB = c9e5b47ef8e63be5\n\nQuotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd\nRemainder = ef65a7789f54174\nA = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5\nB = 1a3d3a0050fa86f5\n\nQuotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5\nRemainder = 398e30aff5bd284\nA = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787\nB = afd12b2c999e787\n\nQuotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23\nRemainder = 378e44fdc7a5ec4c\nA = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a\nB = 7fae9be5dfd41a3a\n\nQuotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93\nRemainder = 39afe3275c01aae6\nA = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5\nB = a547d34edac1d3a5\n\nQuotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874\nRemainder = 63e5ed36ff73a42\nA = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca\nB = 459e52a6cfe4d9ca\n\nQuotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279\nRemainder = 19657d8ce516a138\nA = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557\nB = 1a41c1d517238557\n\nQuotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573\nRemainder = 1bab5b03c372daee\nA = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651\nB = add94e27f30ca651\n\nQuotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc\nRemainder = 18cd326996ccebc1\nA = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d\nB = 2663ec896e1d6c6d\n\nQuotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d\nRemainder = fe9b6b8ba7c30f8\nA = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6\nB = 6d80cf0c957788e6\n\nQuotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7\nRemainder = 169e15b4d5aa180a\nA = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89\nB = 2167f9ce5e233d89\n\nQuotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2\nRemainder = da381ae5c97a506\nA = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a\nB = 1274c5b4d821469a\n\nQuotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720\nRemainder = c41f9e7bf20b376c\nA = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec\nB = dae90967d9ab48ec\n\nQuotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0\nRemainder = 8e435da582e59809\nA = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739\nB = 904674f2ea3ff739\n\nQuotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771\nRemainder = 14135c686d2e9f70\nA = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f\nB = ea8f939c922b1e7f\n\nQuotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763\nRemainder = 230307c44cd55896\nA = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545\nB = 2633a0d905017545\n\nQuotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7bfabb2c\nRemainder = 40f5346f8775e20\nA = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0\nB = e3d7df32c15b75a0\n\nQuotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81\nRemainder = 2e495a881876da00\nA = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c\nB = 94331c1cfb1e941c\n\nQuotient = 5dce24b7a16d847b0c43cf365ea20bee96", - "79fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6\nRemainder = d8ead1ae3126aded\nA = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47\nB = f4dd6e462bbc8f47\n\nQuotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a\nRemainder = 57131776937c5df9\nA = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f\nB = 793dc0907d9aa30f\n\nQuotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9\nRemainder = 5065b726dc6b3758\nA = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb\nB = cec4f0466c1c47cb\n\nQuotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba\nRemainder = 67f48d3584cf4fe5\nA = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73\nB = 73a6a288012c7c73\n\nQuotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf\nRemainder = a5356d04b64ee12\nA = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1\nB = 22664967d67dd5f1\n\nQuotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329\nRemainder = a34980d5046e2ed0\nA = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e\nB = cffee795d695f82e\n\nQuotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53\nRemainder = 36052bba2867f5f4\nA = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96\nB = c1bd491446a50b96\n\nQuotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0\nRemainder = dc8c7d087bf24b0\nA = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0\nB = a26129615a2432b0\n\nQuotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f\nRemainder = 75c703f654ad630a\nA = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5\nB = a1cc13a7108327f5\n\nQuotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65\nRemainder = 453a3d59303ec3c\nA = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19\nB = 84afe4979b5bb19\n\nQuotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287\nRemainder = 5904e71034e3a02\nA = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95\nB = 70a6a40ab6c41d95\n\nQuotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a\nRemainder = 33431c3df719f946\nA = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea\nB = dec06757dbe61aea\n\nQuotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696\nRemainder = 31540f5e05e8b4df\nA = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d\nB = aba050665c090b5d\n\nQuotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5\nRemainder = 4ed4f2d12e4f4ba0\nA = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8\nB = e0adf6f71df7eef8\n\nQuotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af\nRemainder = 7e5661558c345eea\nA = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d\nB = de41a7dfc5c3576d\n\nQuotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897\nRemainder = 29e9c1627537e5a4\nA = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca\nB = 4671868b0526aeca\n\nQuotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87\nRemainder = 664d57c57d4952e\nA = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3\nB = 4bef9c961e2958e3\n\nQuotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4\nRemainder = 5ba8f49e0ca36ab4\nA = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44\nB = ff6d0277fe642f44\n\nQuotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25\nRemainder = 1ef621737e81780\nA = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920\nB = 4d8ea8637e50920\n\nQuotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f\nRemainder = 9ae7de3edb6c7edc\nA = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e\nB = c6b738c0bb282c3e\n\nQuotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477\nRemainder = 3ef5c6ee67e6f5da\nA = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09\nB = 77822f27d1e3cb09\n\nQuotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a\nRemainder = 7cf920ba2897f714\nA = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc\nB = ae0c1fe238c726cc\n\nQuotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343\nRemainder = 2689c40a54df34bc\nA = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662\nB = f05dc6676e51c662\n\nQuotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958\nRemainder = 53da0b15ac079ccd\nA = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85\nB = b54edbf4bbc9af85\n\nQuotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328\nRemainder = 3d051148ec43a72\nA = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2\nB = 3ed5a2e7edaeec2\n\nQuotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8\nRemainder = 1a1f4aeb882d7546\nA = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116\nB = 9196fe73d0e46116\n\nQuotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee\nRemainder = 4578107045b9cb81\nA = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28", - "ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b\nB = c3acc56b72ddbe9b\n\nQuotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce\nRemainder = 1b9861df51429a6\nA = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2\nB = 9672452618da9c2\n\nQuotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8\nRemainder = 2525d52ecdec8814\nA = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4\nB = 5fe5cdbd30726df4\n\nQuotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7\nRemainder = 14781a368471ecae\nA = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b\nB = 198221221724cc3b\n\nQuotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9\nRemainder = 6c754d5c167e1228\nA = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f\nB = 7137cf7eabda038f\n\nQuotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee\nRemainder = b14595005716bfe3\nA = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1\nB = c81ef51b30288cf1\n\nQuotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464\nRemainder = 10fae644af084f8a\nA = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092\nB = 1e1f583ae834b092\n\nQuotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532\nRemainder = baff11e6961c72e3\nA = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad\nB = d4929335a1623bad\n\nQuotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028\nRemainder = 29e33e0c2a515780\nA = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380\nB = 6199279c25d4e380\n\nQuotient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90\nRemainder = 11d8f2f6d4c1f55c\nA = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c\nB = 651f629975faf91c\n\nQuotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589\nRemainder = 1ee700ffb0ea02d8\nA = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35\nB = 3bd460ee19887d35\n\nQuotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172\nRemainder = 74785b6874d8fa37\nA = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9\nB = 9b9f4f097027ddd9\n\nQuotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88\nRemainder = 9a836be71a24e72e\nA = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e\nB = bbc9a0bf08879b1e\n\nQuotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c\nRemainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171\n\nQuotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446\nRemainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd\n\nQuotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06\nRemainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450\n\nQuotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80\nRemainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02\n\nQuotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08\nRemainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40\n\nQuotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a\nRemainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485\n\nQuotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643\nRemainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99", - "c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4\n\nQuotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777\nRemainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1\n\nQuotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4\nRemainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95\n\nQuotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229\nRemainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492\n\nQuotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845\nRemainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26\n\nQuotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122\nRemainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15\n\nQuotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62\nRemainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020\n\nQuotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1\nRemainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e\n\nQuotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d\nRemainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d\n\nQuotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596\nRemainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a\n\nQuotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc\nRemainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a\n\nQuotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395\nRemainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571\n\nQuotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912\nRemainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc", - "4936d273\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c\n\nQuotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286\nRemainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08\n\nQuotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8\nRemainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313\n\nQuotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b\nRemainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886bbcb851448dc1ed4cd66d6598\n\nQuotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd\nRemainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8\n\nQuotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2\nRemainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6\n\nQuotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4\nRemainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71\n\nQuotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d\nRemainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9\n\nQuotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02\nRemainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5\n\nQuotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6\nRemainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253\n\nQuotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602\nRemainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410ddd1e0da\n\nQuotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb\nRemainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9", - "b8b71372b\nB = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041\n\nQuotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780\nRemainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9\n\nQuotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef\nRemainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8\n\nQuotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6\nRemainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39\n\nQuotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c\nRemainder = -24f3431858d5aee412443feab243b465b849f5dc97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d\n\nQuotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f\nRemainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c\n\nQuotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9\nRemainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751\n\nQuotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b\nRemainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8\n\nQuotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287\nRemainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5\n\nQuotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e\nRemainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5\n\nQuotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581\nRemainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396f5db2d979d272798ed30efa15d52289d0c72f42582ea56f\n\nQuotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9\nRemainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e45", - "8774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1\n\nQuotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e\nRemainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c\n\nQuotient = 4213d04b9f0b30026bd355404bee887b22b2cf9\nRemainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08\n\nQuotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8\nRemainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad584636352913b7429b99ecfbe\n\nQuotient = -448c4922b7a7d5e1efec2c3f41d0264b76\nRemainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514\n\nQuotient = 152474a1a76700598c18d9301866ec00\nRemainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da\n\nQuotient = 5665f53d5a7405c83a5ff382ec376\nRemainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7\n\nQuotient = -eeda035247bb13860f228d8f2c\nRemainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4\n\nQuotient = -5b37eb0c3e3f8f8d9ac6f4e4\nRemainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065\n\nQuotient = 1c7ac058af2e7bfbda9484\nRemainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e\n\nQuotient = 472df5f4393f33cc382\nRemainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc\n\nQuotient = -12b4e74d76bd306d9\nRemainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec6196", - "2e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7\n\nQuotient = -548c97fd02eca7\nRemainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1\n\nQuotient = 14622572f311\nRemainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320\n\nQuotient = 5cdbb03ee\nRemainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a\n\nQuotient = -f16da1\nRemainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374\n\nQuotient = -71bc\nRemainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7\n\nQuotient = 10\nRemainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee", - "8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a1", - "9c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c95", - "96207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8ed469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -eced809145e696ceaa0ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661", - "a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b\n\nQuotient = 0\nRemainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb944181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0\n\nQuotient = 0\nRemainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nA = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb8", - "81617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b\nB = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449\n\nQuotient = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91\nRemainder = 0\nA = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91\nB = 1\n\nQuotient = 3b5c3007d9c49498ff8437b6f0014d146b63c20b6c5b91febee47211f42109f6081204b21a8af99e9ab2b5165d536344fec16bd691fb3883ee7335e12d69afc8bff57641ac7a4cee350209a08301553854873da153ccf056427a2415e3ce72972afb5883393806ec2388169b513674c0935f67ec79c89dfc4bdc6f9cf877a10f\nRemainder = 1\nA = 76b8600fb3892931ff086f6de0029a28d6c78416d8b723fd7dc8e423e84213ec102409643515f33d35656a2cbaa6c689fd82d7ad23f67107dce66bc25ad35f917feaec8358f499dc6a0413410602aa70a90e7b42a799e0ac84f4482bc79ce52e55f6b10672700dd847102d36a26ce98126becfd8f3913bf897b8df39f0ef421f\nB = 2\n\nQuotient = 4f54d7e1ac8816945de169e9a2c497ff240e313c2b7d58612c8175e277f032cd4ee5dd640605028c59395a1eb4aa00772a8187a0568b93919aa5b95b0462e5bd31c1e507170039306e1b2f4f75f63ab0a3add0eb01217df61a74765fc37e941dedf10fe142ae317573a4f0c8ce408c213749a12f56add5d100d0973b019350a1\nRemainder = 0\nA = edfe87a5059843bd19a43dbce84dc7fd6c2a93b482780923858461a767d09867ecb1982c120f07a50bac0e5c1dfe01657f8496e103a2bab4cff12c110d28b1379545af154500ab914a518dee61e2b011eb0972c1036479e24f5d631f4a7bbc59c9d32fa3c80a94605aeed25a6ac1a463a5dce38e040981730271c5b104b9f1e3\nB = 3\n\nQuotient = 2922aed641a12010a3099f3c03f708962e2791dd860e65440acf3b982a4041804dcbedf45deefdae5130df96902056f8b2942069fc17bfb29f46a096a36e842ecb30d0800da13b6572c5b3a095038baa3107ca28094063571b517f7cda3659b63099c57a40d7dd2893b92d60b1fe2fb4594fc3a19b7d7957921437556db0e353\nRemainder = 0\nA = a48abb59068480428c267cf00fdc2258b89e4776183995102b3cee60a9010601372fb7d177bbf6b944c37e5a40815be2ca5081a7f05efeca7d1a825a8dba10bb2cc342003684ed95cb16ce82540e2ea8c41f28a025018d5c6d45fdf368d966d8c26715e9035f74a24ee4b582c7f8bed1653f0e866df5e55e4850dd55b6c38d4c\nB = 4\n\nQuotient = 216236f9c82fe6f1c021853a21fde3e21e6de355cf193f16b403edf59a6a6ebeedb266d4c7a6683f5f6a434c7129f582d2a5a852269d66d2eda45a1e2f25286c665f6641ff8b55913603064cc7a157f755e515a426873e7bc6b9d699d1f316759c4505a67b7a025598f9d1af6ebff2ed0fe393db829f768178c1080ea004e4f4\nRemainder = 4\nA = a6eb12e0e8ef82b8c0a79a22a9f5736a982570ad0b7e3b718413a5cc041429baa47c0227e640093cdd13507e35d1cb8e1d3c499ac113021ea435c296ebb9ca1dffdcff49fdb8abd60e0f1f7fe626b7d4ad796c34c0a4386ae1a1310119bf704c0d591c4069620babfce1186d29bfbea14f71e3498d1d50875bc52849201878c8\nB = 5\n\nQuotient = b9fbd48d54b9b70374425aabe16d6a8a819944a43185c2fd07073e20358510ac3de13cff33fe6220ba952d88b2e0f3f7eddb8daf27462b476b5e127e72ea60fd56cc54bf14d2d92765d5d21652d8e16aad4423cd9789515d59aaa02d42d3e957dde50ed1c9a69e2295144a643a8104660ccaafba250854e7f28a686935738\nRemainder = b6d\nA = 8ec1cca67b888cfa26bcee98ee887c47507a253008032c2b37e50f2fb914a34c357f6351e368c2521f3781736d4dab43ce130640f1a55c3851e9b5320f34e772751fd70cab7bd7aebdaa9fc22297790661fecd7b4ed0e6f4275377f2bdcba89bf1d251e0074864618b6e1319eee807e054d193e2616ce52c09ab3d24c187332d\nB = c48\n\nQuotient = 5157f1bb35866dcaa3abb4abb73580d43d03536c3c7960aa95910db60f4d1ffada96c7d89dfcb290bd8c5bb154872e2dd6e50602fafb435193575a4cf253e4d22dbecf11f8f97408dcc83d6e591b1d5daa59825ed8cb08cf562fc50d62cd666b9720055dc11cd42278258e5bd8021aada0b39a340b6c5585bb6c9c84a9ff8\nRemainder = 3d2\nA = 469e999cc737f4d12c97d19a13ce331841f8232cb780602c18592e274ec8b503884566ffcf28a206288f1a9ab3a25bd74bd054781664a331922a96254d6155677836e7455a6690fcb1acd7550cdbca3e9124356ed7b644660092f8d2df06d22ae7f38ca8a4e7472aecce9ad73c47d3a93cc3ec9faeeacd3f59f70ae22c9614b2\nB = de4\n\nQuotient = 3566586b9f864dac5ed132d95d4ac6d1fd5ef6a2c67fee39ece89d615b4c681284b4dd5e27b90c6270b85b150fa2a63440e470b0f937b0eb83432be03eaeb37a0927a9c76b07fe40e3509c93a7b660b77ebbec9bca235d387a9a80a6432c77ddd8190c0ae8ea1d72331d5f4985467755b27573bf23109a01c02975e07daf3\nRemainder = 2a2f\nA = 9d68d0643f1d44b63aff6a83fca08c52bf800dc59260db9b7ff930eb1bc01a47966fa509abd7da21ad856f7cf536d32dc7c962afaca1c9e43bcde135e4c5b9cd9b3c8ad775e06fda06117f8cc03ffad8e5f4b456baba7eaa9c67af7a19c2f4d65120d51fa8d31d0cc1ec7502187cd784fd2d78514cbccff969123718de7cb30d\nB = 2f2a\n\nQuotient = e36f2fbcfe134fdf3137539006d6d9c03b8774883211f759b0258bb09585440d6ff440e799ffc434a2fc529773a455db9abf72d8c55903d9ae5abd5b2b5e9ccf23c015882cab8565c654532d9407a188a40d0cb026fb3bfda428d4bdfc14bec72b5cbd59540c42598f1371e9e61a86e6b4c957ea331baca764b771212495\nRemainder = 6eeb\nA = b669c646d1bbd7389fc642da6d2c440788fec53bd8409ee604222d08b1fc31b3d301e42a8168be0ac394e5f20eb51708b11e7b09d25043f19032310d6649d33eb6c9688506ebd56ebfd0d3f277511ad3caaba3642c53d27e8fb0eb991c75577f584c52b1ec44111b3a9bf5863c18d8a07b91d8ae0bdbbb3b05ec8d11380a9c3a\nB = cd53\n\nQuotient = a891f8a42093cd86d76cb11cf734a65dccd5b4d350328a7d2f2be76e2edb6b7dcf4c5e1915c65764c77ae73fd6e42eb8451253507e16f2e25ef80e5d1f27ea18dc976a9b12147ecb643b2ab060163307df818127b2e40dcea95a109d7841edc9288190587ac48ba9687ccd0d014d531bcf66ec401bbcbed777325fd1060c\nRemainder = 6e66\nA = 9077614b809f4b22707cf965a7e79217e13ca2011cf9e069babe2b4d908e318608f91da095864403b168d750d904fbfe11c9ed80ba9f60d57a8dac2754647002a0848fefb7a5aa8e04fd28dcb9c8e669de4ef794eab2abc93d68dcbf4400d86de603d199a3ee93050638fca7063ea99a9465dfb60d0568b99dfa1ed79da41522\nB = db65\n\nQuotient = 1b16f2e2ef7709fe285ede17beb7d9932caae2dd5fa0eebb541770ca1d53da4428820986cb7e79026eb8bc261eceb200b7696a4b90f675ea9af8389c60dde4d564c8adeba6b117edd05469d285670c0bc78afbc3ad047828cdc611fbcab403c0cb79665d6285b43fa04b77f0309bc7f74136778f8ec16899df040db34f4751\nRemainder = 68\nA = e91e7c26e2b562fe2568613656381d5581628e4705ede6660ca5b79b4a609748889707faf9295b57eecfbb1c0b1cb5cc2a5825b84878e8b9e3960f29b59580385a4af0aae375f8eb7fc66aa6a1fdc4a95e29048ce1e5760722c77cc1c95b1c4c16fdb3e59ed4961f8869711ff24c91ccbe2fb6e0617a5f242227e1e60b3ab673\nB = 89b\n\nQuotient = 37370826964cbd65a48598e73b519db77df6f520bcead8c0446f1288ac189403adb65603b2a68ab3cc232b667232f2e206b5bee0fd48fea8b3ff515f452b5ef0cac591b6ac8c8c509c59c6d3d4e3fa03e22578ff71f1c72ddad9d637ae0497ef0e2a4b261a72cb784f8283eb7e82b6a05aff0a2f61da4780e4e7cfcc4807\nRemainder = 3a29\nA = 16ad5614f9129c7952c5ee8057d8d12a70780144e616e3ed571b2e38a9ce482a52c436eb9ccb6e4f400321bf1f3ef4c8dc897cd91f868eb7018d084784c4840a1d078c8c6a75e950cb76cf2cd81b719ac04d2be5c9a830b1d1361f7ef6345af66a6d56c53234cd98f587b6762401674973df670addcc4a05ec0344d402453a25\nB = 6924\n\nQuotient = 9bb00032a27651eac898b8a567e19ed6448669c8514b5659c4b1103069d9289c6c00b38b44160e0efb2c635b7a64c8296c1c1b5c2cdb285b749e614eb9247c6defa06f8dac077b1e1c26059847de56a1a5ddf7fb1254662624f2ffe6edc48f3b318ffdc7ba2a81ef2d963b934120f58afba2b107a215b58f324e2d923f75\nRemainder = c03\nA = 74524695d4dc11023ff202ed2d165551ace0c126f7a51ebb3ff21ecd7c058cd4a6bda2254c55ce6ef76fd11807f92e80dad31bfd254f9a2e1ca89949f65a1fab8f6a4978c488f2dfa61df46c1faa418ff45250d82958e8f5fdd9426c44a3bcd7c4eeca276abae466787a5ff0ec482514e03434ee68fce24fc620e31265c3718c\nB = bf45\n\nQuotient = cecbbc189fb1d44c5511f742b63207bcba9c78d09342cdcd12a1b1bc3a95466e7fdd8c59329a9b18f7c793c43f08d52339a8202dfa3a9fa86a2426bf5a94e006849b45cbe9a5dd74ca43e2acdf1051be23359624e8f146b203864d03651d98165b783398a59b446314c9b01f79b1139c30df348b14ffd25b22d9d90866b\nRemainder = b265\nA = c3721776b9b5fea8608aa9d381d80ac603d27043089dac276832e7cde8d222ffe142f06c314e94c3b9f6148d029f260879b700e1d435b5f318c8c8caebe92236c9060c183783edec2845e6d4e816197196a0de3644", - "544093b04ac6fb4c69d7446954fbabadcc5dc3309e9a3fcf70368ba7448455cec9c3dc78512a19ebb04f6\nB = f1f3\n\nQuotient = 4090a2c78cf8711388347149926610d624543765c9667567ad86eef9f9777f53c0cc0f9a989d9195a5e0da875c03e5c74614f95b8752f9ab89fa61c264b8b5d3e02b043fd539d36dbc6782f45a555d1f36751603d5c3423c7f27b3b5dcb91ddc81bf1563dd3abb0970de6109d76da1f4f9d5208ade2b131fc407c5b169c\nRemainder = 2a87\nA = 129d32cde3c648298f8e8e8123f2e8ee9cad3f909a5647ed09e91cb99549d177575f54a7a3ebbd4ed2b89940722927a8b9565ffbc13d8df6d2616d5b1925b87bbb6aa6d39f2b11d26d071fa30e63083ed5a5357ecf0ab1028cf0a43178486679e86fe4dcb071c49832c83c9de4599d672e5ecfc7c9190f1d7275f5a0abed80f\nB = 49ce\n\nQuotient = 43340591e68e228fb03e44a5f2046afe41a3d7ca99ea9ff1a445d75f95f2ff7f55fb914791613b5db7369121d416a5f92f834b0b5e9280b49a9e66be4c682019881e6e8883d7a923d2a5d309b9d265b01d6b8a4ee07f7552934f2de002cf961fd93f33641aaaccc7c367fb6798436eecc9bb22357087a9c482131e1065eb\nRemainder = 6332\nA = 42e75e3b8c23287044593d9fa4bc5df437a0f8e876d3105334a677b5ecebf653e8bd7e55dbbf6876005196e44980bc23df491949c59aa199cc9e0a111b58f954eaff2bd270214726e5c98de502ba71b42089fba51e8763f0c11f278faf4c61589ceb674d7c7c61f62f8d18ccd619c20243a508c26b934f06ddeec0421b372326\nB = fedc\n\nQuotient = 688c7120765f8ef7363f7ae1bb65bc568b16e32c59762f59f34a57f08839d19019313dfcc9e96d7415766bc0aa032b19ecea72c249bffa0538bb1ac06401657df2fbea5c46b18d8a79cee4029e5972d8361fb7e6c2c537673aecd727dbc758a3bca1a001765a216e9985eb7eea67ae979f3803f14587507ba0f8fa29957\nRemainder = 9970\nA = 688c0894053f1897a74844a2408400f0cec058157649d5e3c3f064a63049495647a124cb8beca38aa802564a3e428116c1d085d7d6fdb0453eb5e2054941017c8d7df7605c5546d8ec446a33ba56d47ec34781c70ade74a203859c3b049f7cdc63fde35fd658ab14781751f8fee8c42ff0a064b941960af4507d59309b50019\nB = ffff\n\n\n# ModMul tests.\n#\n# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M.\n\nModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277\nA = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b\nB = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65\nA = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763\nB = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92\nA = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942\nB = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910\nA = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01\nB = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c\nA = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc\nB = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc\nA = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f\nB = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8\nA = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494\nB = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53\nA = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f\nB = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e", - "879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3\nA = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3\nB = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c\nA = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b\nB = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f5303a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398\nA = -442c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9\nB = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b\nA = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf\nB = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c\nA = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d\nB = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c\nA = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60\nB = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504\nA = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78\nB = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024\nA = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa\nB = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8\nA = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c\nB = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea\nA = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1\nB = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5a99c8a6afaa97d8e7d84f", - "4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c\nA = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7\nB = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8\nA = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3df11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048\nB = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce73126508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8\nA = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d\nB = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0\nA = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c\nB = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450\nA = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c\nB = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8\nA = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c\nB = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c\nA = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3\nB = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4\nA = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928\nB = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207\nA = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223\nB = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676\nA = -1bf5ae15f24c7c14eb59605136a3f", - "679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52\nB = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c1d04b831b712d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba\nA = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf\nB = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd64bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073ff1a506d7460c57d54e10dc2991c028606a\nA = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de\nB = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed\nA = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f\nB = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc\nA = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414\nB = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c\nA = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65\nB = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c\nA = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad\nB = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130\nA = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c\nB = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768\nA = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39\nB = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e59", - "5c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f\nA = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9\nB = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e\nA = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb150408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845\nB = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227\nA = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45\nB = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c\nA = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382\nB = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad\nA = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7\nB = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda\nA = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf\nB = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec\nA = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8\nB = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5\nA = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf\nB = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4\nA = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4\nB = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9", - "dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a\nA = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822\nB = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26dfdb\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0\nA = -63bc10b8fbcb391dea305fe61b404d3bebd035514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b\nB = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d\nA = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb\nB = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702\nA = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91\nB = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c\nA = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643\nB = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18\nA = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33\nB = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a\nA = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b\nB = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6\nA = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6\nB = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121d", - "ae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b6243ffbb7a979bf9664cc7ec41e75f267d58a7127\nA = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625\nB = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db69f781e169\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0\nA = -75f903ed9bb0b6db8e3be16e797258f6c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164\nB = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5\nA = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb\nB = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa\nA = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296\nB = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2\nA = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f\nB = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe\nA = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a\nB = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08\nA = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec\nB = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886\nA = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841", - "db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f\nB = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b\nA = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3\nB = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820\nA = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e\nB = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba\nA = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed\nB = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1\nA = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579\nB = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c\nA = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4\nB = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754\nA = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00\nB = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a\nA = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995\nB = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de\nM = c462c7cdd79b7604246a0cd97c017700feb25908", - "656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230\nA = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e\nB = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35\nA = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891\nB = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955\nA = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9\nB = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8\nA = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a\nB = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39\nA = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983\nB = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574\nA = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0\nB = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c\nA = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc\nB = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 76c", - "31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c\nA = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2\nB = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df502a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 5b704b3181e5d0494937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04\nA = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023\nB = 160120a35ae3edac3edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93\nA = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15\nB = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c\nA = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e\nB = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9\nA = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b\nB = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014\nA = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410\nB = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90\nA = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8\nB = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e03", - "59c99d4bdc901a4\n\nModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409\nA = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9\nB = 44c336d7739118340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8\nA = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924\nB = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea\nA = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19\nB = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea\nA = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996\nB = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d\nA = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9\nB = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2\nA = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3\nB = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c\nA = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e\nB = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8", - "cddb5914e7657573804e63dc7b216b1a9aa175c\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168\nA = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c\nB = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f19a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54\nA = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4\nB = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298\nA = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa\nB = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227\nA = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1\nB = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179\nA = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655\nB = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c\nA = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15\nB = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897\nA = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4", - "a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1\nB = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4\nA = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2\nB = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a20f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648\nA = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4\nB = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a\nA = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6\nB = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c\nA = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6\nB = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94\nM = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4\n\nModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c\nA = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905\nB = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d\nA = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5\nB = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf\nA = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66\nB = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a234", - "49e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21\nA = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393\nB = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a\nA = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152\nB = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d\nA = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e\nB = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d\nA = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c\nB = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4\nA = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232\nB = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761\nA = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a\nB = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327\nA = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82\nB = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010\nA = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61\nB = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89\nA = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1\nB = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14\nA = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f\nB = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97", - "f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe\nA = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9\nB = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5\nA = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df\nB = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f\nA = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760\nB = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a\nA = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207\nB = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd\nA = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6\nB = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde\nA = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454\nB = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8\nA = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615\nB = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a\nA = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013\nB = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9\nA = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d\nB = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f\nA = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226\nB = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721\nM = 8e2ba940fc5165c6c5f7f4", - "cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24\nA = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d3486949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a\nB = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0\nA = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e\nB = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23\nA = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928\nB = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9\nA = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3\nB = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f\nA = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0\nB = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65\nA = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807\nB = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308\nA = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983\nB = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa\nA = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7\nB = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f\nA = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72\nB = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6e", - "ff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173\nA = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df\nB = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848\nA = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40\nB = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146\nA = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa\nB = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02\nA = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c\nB = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c\nA = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7\nB = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343\nA = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd\nB = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35\nA = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d\nB = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a\nA = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50\nB = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff\nA = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a", - "64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a\nB = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7\nA = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967\nB = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453\nA = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8\nB = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c\nA = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745\nB = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149\nA = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261\nB = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656\nA = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228\nB = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e\nA = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d\nB = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e\nA = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5\nB = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb\nA = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99\nB = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd93", - "30a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a\nA = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8\nB = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc\nA = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984\nB = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc\nA = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275\nB = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472\nA = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6\nB = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d\nA = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1\nB = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd\nA = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1\nB = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f\nA = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e\nB = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad\nA = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334\nB = 1311", - "b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d\nA = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e\nB = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4da9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca\nA = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431\nB = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f\nA = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864\nB = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d\nA = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5\nB = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233\nA = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244\nB = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e\nA = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65\nB = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135\nA = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9\nB = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680", - "068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c\nA = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1\nB = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb\nA = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f\nB = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511\nA = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5\nB = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79\nA = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15\nB = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e\nA = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db\nB = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b\nA = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840\nB = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d\nA = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c\nB = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec\nA = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b070", - "2b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf\nB = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc\nA = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e413e23285066eab8e126c320bb6130a91d67ef26d4dabd\nB = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158\nA = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d\nB = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745\nA = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7\nB = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950\nA = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d\nB = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a\nA = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b\nB = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82\nA = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5\nB = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3\nA = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7\nB = 78ec7dbfa2b28e26861", - "9ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861\nA = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3\nB = -2023c544b6cdd8d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c\nA = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be\nB = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce\nA = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a\nB = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68\nA = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783\nB = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866\nA = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91\nB = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069\nA = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933\nB = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901\nA = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059", - "c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8\nB = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b\nA = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec\nB = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3\nA = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e\nB = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf\nA = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830\nB = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0\nA = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7\nB = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d\nA = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437\nB = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493\nA = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6\nB = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5", - "dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280\nA = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628\nB = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8\nA = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82\nB = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297\nA = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6\nB = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d\nA = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8\nB = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2\nA = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf\nB = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17\nA = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c\nB = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8\nA = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8\nB = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093", - "a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b\nA = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751ceab01cf9e49015d42371fac30d48ef5853b6894ca83\nB = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70\nM = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb\n\nModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02\nA = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb\nB = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888\nA = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78\nB = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1\nA = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f\nB = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e\nA = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a\nB = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a\nA = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493\nB = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0\nA = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c\nB = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096\nA = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e\nB = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77\nA = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31\nB = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3", - "c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f\nA = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83\nB = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0\nA = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357\nB = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb475ee818199a390b6\nA = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae\nB = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca\nA = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6\nB = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe\nA = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32\nB = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0\nA = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92\nB = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc\nA = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756\nB = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1\nA = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf\nB = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6\nA = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a\nB = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f\nA = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87\nB = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul ", - "= 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928\nA = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58\nB = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304\nA = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5\nB = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a1b1b2d33cb610f1b398e03f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a\nA = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6\nB = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3\nA = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7\nB = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d\nA = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35\nB = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882\nA = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce\nB = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2\nA = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a\nB = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a\nA = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13\nB = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1\nA = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db\nB = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696\nA = -19d3e", - "6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7\nB = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48\nA = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214\nB = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05ed24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2\nA = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da\nB = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e\nA = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda\nB = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813\nA = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107\nB = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60\nA = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416\nB = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77\nA = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95\nB = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150\nA = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8\nB = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da\nA = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae\nB = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a962", - "1b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de\nA = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda\nB = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210\nA = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20\nB = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80\nA = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf\nB = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab\nA = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d\nB = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80\nA = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4\nB = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba\nA = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b\nB = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94\nA = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b\nB = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a\nA = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b\nB = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8\nA = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa\nB = 1fc4dc77f4a18d4406a4ba536e500a", - "ff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819\nA = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197\nB = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095c6a509d0fa15dcf45de8d0e901\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200\nA = -464cb16fdd395e32fdc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc\nB = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08\nA = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670\nB = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208\nA = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019\nB = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6\nA = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d\nB = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067\nA = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453\nB = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5\nA = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93\nB = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c\nA = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7\nB = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828", - "be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca\nA = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589\nB = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b2b63f84fb0023c81d031773f3652cd6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8\nA = -78a99d206b4f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e\nB = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31\nA = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f\nB = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e\nA = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7\nB = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28\nA = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756\nB = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6\nA = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29\nB = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f\nA = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf\nB = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec\nA = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e", - "1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905\nB = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5\nA = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1\nB = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8\nA = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990\nB = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec\nA = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1\nB = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a\nA = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d\nB = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5\nA = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3\nB = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264\nA = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d\nB = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f\nA = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b\nB = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d\nM = b18a9cd6a0a89578ea77", - "3fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af\nA = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b\nB = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590\nA = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8\nB = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef\nA = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f\nB = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28\nA = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c\nB = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4\nA = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814\nB = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0\nA = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4\nB = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08\nA = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73\nB = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e", - "971d48\n\nModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58\nA = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50\nB = -26ea5079ba7ed137a14d00d413d6f818e911cc183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a\nA = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae\nB = 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8\nA = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9\nB = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1\nA = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131\nB = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e\nA = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145\nB = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380\nA = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214\nB = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac\nA = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205\nB = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c5419211", - "2fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4\nA = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2de4\nB = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4\nA = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda745658bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373\nB = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846\nA = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f\nB = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04\nA = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a\nB = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074\nA = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc\nB = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590\nA = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4\nB = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb\nA = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353\nB = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e65", - "26be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11\nA = 1112d291463b28ef45e879412e6607a3e20d50dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1\nB = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c4487d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618\nA = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380\nB = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e\nA = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa\nB = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4\nA = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d\nB = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1\nA = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375\nB = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229\nA = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f\nB = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282\nA = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a8122623090", - "94ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e\nB = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc\nA = 60463fae1e9354559160d55a453c12d75775a53d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714\nB = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bcfb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420\nA = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8\nB = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7\nA = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47\nB = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce\nA = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772\nB = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47\nM = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48\n\nModMul = 9ea62ef634\nA = 55cc58c9d8\nB = 6b49179821\nM = f753311ac9\n\nModMul = e9ab3a2aa60edd30108\nA = 5134a36c2bad180dd5bf\nB = 2ba6485656d041690666\nM = 9b9cc4409e86c8b0fbbf\n\nModMul = 621f9b797e866028b7bd1ff828bf29\nA = a202338dffe171c99434d84f3\nB = fb71eee7045b3e3ab5dd809dd\nM = b3e6e8d53b7249df670e3c59c55d33\n\nModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672\nA = c669426a92d3cb5b316e2b5b9\nB = ccaea3874008dcc92450d8b2f\nM = b04dd2bb325baed1940cd000e8cb2d786009ccd5\n\nModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0\nA = c3255cb24a813e27c3dc410f0\nB = b144f39e7c2d33605ba7bee16\nM = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077\n\nModMul = 6124d7d171\nA = 235b938139\nB = 3a56a22a28\nM = 83eb4af4e5\n\nModMul = 9c006f56095d442ba98c\nA = 207e14237c42e3764e5e\nB = 8a495a26872432fa8e33\nM = d0cf2b8ae5c67d6736b9\n\nModMul = 97387cfaef652932a230c82de59cac\nA = 82ae0fc5e943af5bb8c4adebb\nB = db1279be12d59ba3a9c036a61\nM = aa36dc1d13390169cd54d711eb511b\n\nModMul = 32ee73c98da657464c6fed4274df20b099689e00\nA = 9baf08248ee24bcb17714e420\nB = a7f0428147bfe098666180749\nM = ce0bc198331c9ed1d21f0d498326e8185d3d602d\n\nModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34\nA = b36249e259b303e453757721c\nB = f0c1db50670d92abd93bdc84b\nM = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9\n\nModMul = 2663b741ff\nA = 58c8e7f7f6\nB = c84681fc87\nM = e0a50dcb45\n\nModMul = 21af3c0b42328f41b81e\nA = 1f79f5b5bf78c9700d\nB = 5bd1734ba0f0e59c2a25\nM = 9ff3fdfb5c089244f327\n\nModMul = cbc280b5106c2c36cb31ad7e7c986c\nA = cadf6482b769e83ce7f7277dd\nB = f9862a06da1a9c89547b76c61\nM = cc36144c88139ce921d2fd1740bc4b\n\nModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b\nA = 9c51a5bacb5d9f055a9ac2962\nB = bfed5625b21b4e82d1f105a0b\nM = a47977acad7c5deeb683ccd265cb30cb193f22a9\n\nModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478\nA = 997c4a7b537d9500d73a205a4\nB = c679ce666af284a459ae5a26e\nM = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9\n\nModMul = 1a90c92fdb\nA = 94fa7bb475\nB = 564b0a3339\nM = a1501bdc75\n\nModMul = 5e7ae5470686bad7996a\nA = c725797912c6c5f30d94\nB = 3a7f4c99ee3f5fa9582c\nM = cc50c8b7408f09a74973\n\nModMul = 72a15b13bcd1b63747342a6be8f0f2\nA = c33357af48a2df569e3c11ce6\nB = a4b4c5c14d7796adab54b6cae\nM = e22a0fdca62a37f4c8a61c96a42", - "9b9\n\nModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6\nA = ce8d3adab8cbf15c332c0b289\nB = 9333f94eeb7d7a86b82becc51\nM = a532a76bd5cff409b580d54d12ef75ad8179b381\n\nModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14\nA = 9a2b56a54bd0727ab4be57ff2\nB = edf1781b4296567990773005a\nM = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1\n\nModMul = 917bcdb402\nA = 55c7dbd314\nB = 997b29ef79\nM = af5b4cbd0f\n\nModMul = 660c4bb2b771f523a4fd\nA = 43fe52461d5139620a11\nB = 1f8ec4b67de1db54ddda\nM = d0458e215b7e6903d96f\n\nModMul = 7aeff02c143e4426fcbcf32bd1277b\nA = a2671586369a990dde7829f36\nB = c7ff67937c900daccc0ab1d8c\nM = 8ad9c1d4d3cce681d1ae27c27982df\n\nModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07\nA = aea36cf51dd2ce06c66b7a407\nB = 80c9fe5bb0afd2bf8b3644f96\nM = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9\n\nModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0\nA = f67636b03821c8f13f21217a5\nB = 8473a29f4ae33f36a0d2c6dc0\nM = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5\n\nModMul = 17fe4644a2\nA = 912611576f\nB = 7a10d36b80\nM = c5fa605133\n\nModMul = 8159b23d4fd697b4fd35\nA = be2d646e76494439e60\nB = 60fa770d05ebc69772b2\nM = a6e7c940cd749925a85b\n\nModMul = 7c412dad5c9fff91357bf181caf2bf\nA = 80f476ed5acae75b34ed54c52\nB = fb818e2bdab3b5f4bd84db3d0\nM = d0339f7ee41337d8462d1a9c207d1d\n\nModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b\nA = ee9c92de52210e61adaa6eb4a\nB = 8ab55a85b1abab62d33e75fe3\nM = cd3faa6de4cb62fece4c3f94492d457834a6a041\n\nModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28\nA = bd162c90bed25e84dd5b6b77c\nB = d887ee03020c5df356f091db6\nM = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f\n\nModMul = 958951bd0f\nA = 12bd0d3375\nB = 668bb65b4e\nM = 9c617dfaad\n\nModMul = 8a109ebc9cbf86613e43\nA = a3e7019f1bbc35689a77\nB = 3189ecd3fd4ffd0229ef\nM = ddadc50600dff2abc1af\n\nModMul = 2b4d9f85a398c852b3a0cc82524619\nA = c244fd157267f707319ba6c6d\nB = 8a07018a748992429bbdbf326\nM = bf3813fb54f749ea5627f59ce30e07\n\nModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f\nA = c9909dcfd3a59a3cfa538b267\nB = 8bbf89cd5a4e24adc2d8c646b\nM = c8f02682b9d480ea98faaca53b747ced33ed0419\n\nModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a\nA = 8019266c548982a520ab48eff\nB = d33c3e3b13576dcdb3ffaa796\nM = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1\n\nModMul = 3eaa4c99fd\nA = 6fc42faa85\nB = dd0b4e318e\nM = fd7f22301b\n\nModMul = 56b6b811ced3433755cb\nA = 145573d17cb0c996c69\nB = 9d3297d5ccc184896822\nM = dcfb3b383506239e83e1\n\nModMul = 34315b6bc6d3690c28060485ae331f\nA = b963a26973894cfb42fcb2d22\nB = e8523304bbcdff1a0ed4141bb\nM = d7a379aeac7d8cf94f19e7924d35d1\n\nModMul = 2ec9466e8b3357496f07e37ba24d36a237883846\nA = a75f3904e564997695b6707eb\nB = f9f47bd779834dc1f5fba0654\nM = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed\n\nModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044\nA = a38eceb9c551f0e69a544072c\nB = d5f8e7c2d534b2b8985bfd213\nM = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7\n\nModMul = 172f2e2e22\nA = 1584ff1055\nB = 2e0aee014d\nM = b904cb0bc9\n\nModMul = 122c10d3200270b9eaa1\nA = 86fd189e62a6dc1e4ba0\nB = 5235635f7b0336f5f235\nM = c93da97d0e95fb63dc4d\n\nModMul = 3e461e10ac4eb749512097fbf76616\nA = cf4ce10cbca07164f3812f89c\nB = b7e4639c233fbb0f923fb5104\nM = 949647857e1406871593fad5c30101\n\nModMul = 88117b59d9fed79dd6aaf083ee938215a995a221\nA = 94c888795567d434123d441a7\nB = c60ca79e61a352e34e0f78bee\nM = d2553a7c5dccd639a3927697a2e1af03845f2f25\n\nModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c\nA = c170eaddca5295d6ec6272dc2\nB = f94a5685ced7661df2efbd34e\nM = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd\n\nModMul = 1110cdbe5b\nA = 5db02b38f3\nB = 3369537903\nM = a8863f7979\n\nModMul = 90fcc5f3a346d3d4ea4c\nA = b93373680ea0feeb31d8\nB = 37f9dfaf0e180be64bd5\nM = d595cc29237d1c19e2db\n\nModMul = 8623a9997e514cf3c1d06c33c14053\nA = b396f5ede6212f1fdfc7e7b77\nB = 81a1ddc18306f2d2e84030148\nM = a6be32a91b34857842255ef8b1aafd\n\nModMul = 63f8f0254df06356f5cab8941b77619ad58025ed\nA = 806b2627b08d987438f920bae\nB = 83297039f4aa8efc1a185fea3\nM = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5\n\nModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438\nA = 930b04224bc097ac1d8bae8be\nB = b79496a80e45212c4663e5b64\nM = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1\n\nModMul = cd93b5b8b1\nA = 47a51b2d5a\nB = 86d6ba5155\nM = efb0ad3643\n\nModMul = 2037821ea789118bde0a\nA = a92215dcae19be637ff\nB = 93b9a3664a406737958f\nM = 9df360b69ed26f610253\n\nModMul = 3bf11785d28ceb668dc55b870faf7b\nA = bc8758854dc48e057cb6210de\nB = f03ca689620a77ecd8a6f0de3\nM = f3ff0747d6e5f34a0ba4200f579259\n\nModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf\nA = 993cd09f3e46423a8ba2053df\nB = feabee384158032dd013dc08d\nM = cd0b21388cb2033b1e792ec4078334df70b6c8f9\n\nModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650\nA = 90e5d18b017118177ffb080da\nB = f8e7e09032574f6c66e623ec8\nM = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11\n\nModMul = 8fcd412054\nA = 2e7f9b1a\nB = 6283de2c9a\nM = 9bff560ae7\n\nModMul = 57d0d3b79f1e2f3632fc\nA = 2f8cc403de5af54cfa39\nB = 3b798c3ead52878dfb2f\nM = 805e6cbde400d4b4bc9b\n\nModMul = 23331614e88633af879201f568c359\nA = f21f19da4b20980979a645dac\nB = ea752050b79883dcd69222536\nM = aed3faf4c88f7c4afe257c5ed90599\n\nModMul = 56dcf9ae1c787e773774df3c8762babb4675a212\nA = 9accf901fa599da05fa6ab5ff\nB = f7f6b9b1d7bae06237532e39f\nM = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5\n\nModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0\nA = 8e57680f213d088ff1a1e7db3\nB = afebecc9943b0093f87022940\nM = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb\n\nModMul = 143ae78a29\nA = 334abb952a\nB = 74203e7a50\nM = c9535a9505\n\nModMul = 897a2b57e69f5a1469ea\nA = 1ec8ca0ea4fed52bdbbf\nB = 3a6273cab05e478a57b8\nM = dcb33163a8ea42c1ae6d\n\nModMul = 4a2c10e90e2d37111db79a44d3e31b\nA = a90e7bbd63fc4af6de83029ee\nB = cf09c3dd50b41afc7045e057b\nM = 8ab85d47e4270116a64f97dc4f0f15\n\nModMul = 70f94276c9d85fd3f71edfaad6051456f754da85\nA = fa3e9ff6e1aa1fb78e51711cb\nB = b115ed197c50b7ec4040ca255\nM = ad63f69ef1346e7549ba71c13b24b279f53bc9bd\n\nModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac\nA = fc41a9ce06e882942f751be7a\nB = 881c05a51d1ba8134d126a48e\nM = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f\n\nModMul = 4e0051898a\nA = 2a06523f70\nB = 651b5044f0\nM = 9da4eb09b5\n\nModMul = cc8274c88d6affc3742f\nA = 9ccf0133f9628532f4f6\nB = c1d80907057be7a67b01\nM = d6e76e362da831f32685\n\nModMul = 568f15bed5c4405be9dd04673a9c46\nA = dd6029c3196feb6da7f0f4a48\nB = a5f6745f2cb64913d1d3236d8\nM = f62f02c9b9ca8993e3be9a02b444bf\n\nModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f\nA = 963c51a9415b03e85ccb09f25\nB = b1cffe333afe44311cb968ffe\nM = ab2128698d498e8d75455033cfbbf4487535773f\n\nModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf\nA = c3b33f391e78bee97ceddf313\nB = a9136f3af450fdeb245eff425\nM = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35\n\nModMul = 8735bd486d\nA = 563e15c52a\nB = 31293264e1\nM = 92f4b193df\n\nModMul = a541f69ca163b288dd0e\nA = a608b48c1dcaa18424b2\nB = 891b0b296e911068b00c\nM = d4140921f4b2c84f1eb1\n\nModMul = adc1b7cf65967b013d046866b4ed9d\nA = e97941448f65060cf63ecd486\nB = ca68936f76cb87a8fbdd37311\nM = ebbca2482fb82eeca2866057cf1179\n\nModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632\nA = c11f83f01bb964ffac93a2e30\nB = e05ee40eea39f4538d735193d\nM = b5e8b511738979dc740a6a1f7291cf4561787be7\n\nModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a\nA = acff8da571e1c96810bf95707\nB = cdd23e5504cc26d0c34a62b06\nM = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7\n\nModMul = 193f453197\nA = 8cb3078675\nB = a8fb003a87\nM = b60ff22f4b\n\nModMul = 849c26c8cf5cae426a80\nA = 5d1e3d2b4d038a0a34be\nB = 34f70325565bf0523314\nM = cbc189f9a732cad8f425\n\nModMul = 9a4e64ff530c53a4c6c5b6b5021920\nA = f53b81723cf74f520a61e614e\nB = 9d8ac2e6b839143fdd079a2ff\nM = a115375435151798f3644bede9d863\n\nModMul = aac303a4623e80158af1cb3331965cc8e3184edd\nA = cce0a88606ff962fdc37e72c9\nB = 9840a500a2051625c517104db\nM = b99dafdbd91ec3c05791031df5e193c03d6a441d\n\nModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf\nA = e6f48c027284856aaf3b96425\nB = b4c326f72a6a22fd4b93ba5b3\nM = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab\n\nModMul = 8b0929adbf\nA = 61fdf77ac0\nB = 8892f05400\nM = f12b3766eb\n\nModMul = 91b57f353307b173679d\nA = 33f8e73752072b4b5cfa\nB = b4c730f79f4f2c07945d\nM = d41be1d8d2e5753e3ae9\n\nModMul =", - " af04c564adfeb120bc4770bc8c650c\nA = af151333b3d4cd1d29fd801db\nB = 9ccaac44ff91be11b30bdcdd0\nM = e0bd6e70d5f5ce08fbbfd48d43101f\n\nModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd\nA = a2fd08df2d4eab0cd6d29e213\nB = 92c9d26ae7c215b52199ee28b\nM = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3\n\nModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd\nA = 855f941d085305725da617f5d\nB = 8f09b7d2c36e0340523da5421\nM = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b\n\nModMul = 2d278e089\nA = 59d20a1716\nB = 8e2a58bc75\nM = b3d61ef699\n\nModMul = 2f937ce359d0f6cedd1\nA = 1019d11d26040ffd5b1d\nB = 7cdb6252087423d43e08\nM = e8f537323004447e669f\n\nModMul = 6567332e25af83089f7458786ab0ca\nA = bf9565e9f8a098894447b58fb\nB = fc867626f268c24cc0ab7bf8b\nM = 930f39183353363dcd822933a438ef\n\nModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9\nA = d0a42ce512629f0ffd233a9aa\nB = 97f6d3c4c655c7353a62d6ac4\nM = eac2ea84851f880214b8f40f881a2e56a6ba6f2d\n\nModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58\nA = c237eb242c40960861c938c08\nB = ab2f481f0d768eebd90d2574b\nM = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f\n\nModMul = c952f9aef\nA = 81973bbcb3\nB = 28ddee3bf7\nM = c4a40993c9\n\nModMul = 241dd53d93f7bdbbb2ee\nA = 2136eda4495c45c9f96c\nB = e74c4baa8ca3f6b7cd5b\nM = fff4594e7a5f0a1d3e15\n\nModMul = 5f861ed8b0aa835761613e6c869cfd\nA = bfc5c1572086079f5f5d18d1b\nB = 95902e14923c8010b7e905178\nM = a819c6c109d623f9b845aa23712c9b\n\nModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598\nA = fbe65d3852224a812c432672a\nB = d57a3f38da966d2471d70a048\nM = b9e6a626d3ad026d14248fc90c882bedd64a1f13\n\nModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed\nA = fd91701ed2151f8e994bf4ee1\nB = 88b66e735b76972bccd9db182\nM = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55\n\nModMul = cb743c97a1\nA = 9c69ca9b60\nB = 7488f48f5\nM = d67040ed0d\n\nModMul = 931b2bee1bc30725a31\nA = 650f567b544ce02303d4\nB = 5858da30dd1fae88a675\nM = 91ce30234bb29fb9e833\n\nModMul = 5b4f262cec958a20390b5e568ccdaf\nA = f7e240e8a077e8e87506db2f1\nB = f8653fe64e3bd414782f51634\nM = fdb8225eefc1620648737d31dfe1f7\n\nModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1\nA = eda8e9a9ea3cdae17bd50b1b4\nB = 992e8ef4a45593e4ceff67876\nM = 95e2f120cfcefbada1058af6c8853cbebedd5763\n\nModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466\nA = ca6c51ba2f410d09bf71d60fe\nB = 8bdfa8fe5ef3b2ad02bc63c4d\nM = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb\n\nModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d\nA = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee\nB = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca\nM = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb\n\nModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634\nA = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90\nB = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc\nM = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59\n\nModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76\nA = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651\nB = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035\nM = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb\n\nModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540\nA = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf\nB = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7\nM = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7\n\nModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db\nA = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c\nB = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d\nM = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401\n\nModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4\nA = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04\nB = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8\nM = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1\n\nModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658\nA = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0\nB = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590\nM = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227\n\nModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764\nA = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d\nB = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf\nM = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab\n\nModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2\nA = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23\nB = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321\nM = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93\n\nModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764\nA = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20\nB = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88\nM = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735\n\nModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233\nA = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f\nB = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538\nM = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793\n\nModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4\nA = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f\nB = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45\nM = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47\n\nModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9\nA = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2\nB = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94\nM = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3\n\nModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9\nA = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f\nB = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26\nM = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479\n\nModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d\nA = 6500f3cf686eec", - "4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2\nB = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a\nM = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1\n\nModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113\nA = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4\nB = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb868dcf4e458b36f506ed7fe0ce5\nM = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817\n\nModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855\nA = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c\nB = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323\nM = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7\n\nModMul = 4452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6\nA = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d\nB = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f\nM = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b\n\nModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2\nA = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d4b2\nB = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3\nM = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955\n\nModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df\nA = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876\nB = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300\nM = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9\n\nModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad\nA = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c\nB = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811\nM = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937\n\nModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6\nA = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110\nB = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b\nM = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025\n\nModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d\nA = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b\nB = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a\nM = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335\n\nModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66\nA = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9\nB = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173\nM = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1\n\nModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995\nA = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd\nB = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10\nM = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9\n\nModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c\nA = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nB = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b\nM = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09\n\nModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688\nA = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620\nB = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f\nM = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9\n\nModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15\nA = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee\nB = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec\nM = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9\n\nModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244\nA = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941\nB = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd\nM = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897\n\nModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6\nA = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6\nB = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80\nM = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923\n\nModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385\nA = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53\nB = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59\nM = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5\n\nModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f\nA = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee\nB = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7\nM = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed\n\n# Regression tests for CVE-2016-7055.\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nB = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4e", - "b4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\nModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9\nA = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81\nB = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nM = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf\n\n\n# ModSquare tests.\n#\n# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.\n\n# Regression test for CVE-2017-3732.\nModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff\n\n# Regression test for CVE-2017-3736.\nModSquare = fe06fe0b06160c09\nA = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc\n# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff\nM = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff\n\n\n# ModExp tests.\n#\n# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.\n\nModExp = 00\nA = -01\nE = 01\nM = 01\n\nModExp = 01\nA = -02\nE = 01\nM = 03\n\nModExp = 01\nA = -01\nE = 02\nM = 03\n\nModExp = 01\nA = -02\nE = 02\nM = 03\n\nModExp = 00\nA = -03\nE = 02\nM = 03\n\nModExp = 02\nA = -04\nE = 01\nM = 03\n\nModExp = 01\nA = -04\nE = 02\nM = 03\n\n# Regression test for carry propagation bug in sqr8x_reduction.\nModExp = 19324b647d967d644b3219\nA = 050505050505\nE = 02\nM = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# Cover the E = 0 case for small numbers.\nModExp = 01\nA = 86b49\nE = 00\nM = 30d26ecb\n\nModExp = 00\nA = 00\nE = 00\nM = 01\n\nModExp = 208f8aa0\nA = 86b49\nE = 2\nM = 30d26ecb\n\nModExp = 27308229\nA = 17591bb\nE = 6\nM = 30d26ecb\n\nModExp = 2bdf498f\nA = 21292626\nE = d\nM = 30d26ecb\n\nModExp = 11317167\nA = 4a655df24\nE = 10\nM = 30d26ecb\n\nModExp = 2e1b88e\nA = da6b761a86\nE = 35\nM = 30d26ecb\n\nModExp = 20a12ec3\nA = ea811\nE = 2\nM = 23bc042f\n\nModExp = c42ced\nA = 1011a6a\nE = 4\nM = 23bc042f\n\nModExp = 4637d79\nA = 28d9a601\nE = 8\nM = 23bc042f\n\nModExp = 20e5669b\nA = 72fe6bc20\nE = 11\nM = 23bc042f\n\nModExp = 142ab9e3\nA = 9a07b9363c\nE = 29\nM = 23bc042f\n\nModExp = 14c64646\nA = 822df\nE = 3\nM = 30915765\n\nModExp = 160e35a2\nA = 15ea542\nE = 5\nM = 30915765\n\nModExp = 2f23a488\nA = 34d2e02e\nE = e\nM = 30915765\n\nModExp = 28e67f93\nA = 636a32703\nE = 14\nM = 30915765\n\nModExp = 29bfeaa5\nA = c8646998e6\nE = 2c\nM = 30915765\n\nModExp = 30959e22\nA = 81dad\nE = 3\nM = 326dd68d\n\nModE", - "xp = 1a1da4fa\nA = 116adb9\nE = 5\nM = 326dd68d\n\nModExp = 272bf0d8\nA = 2d21ef08\nE = 8\nM = 326dd68d\n\nModExp = 29f5054b\nA = 76989850a\nE = 16\nM = 326dd68d\n\nModExp = e6c7b77\nA = b88ee70d2a\nE = 3e\nM = 326dd68d\n\nModExp = 369605e1\nA = cf26f\nE = 2\nM = 3ce082eb\n\nModExp = 168a3c5d\nA = 1f82caf\nE = 5\nM = 3ce082eb\n\nModExp = 125c4bb8\nA = 2e9c4c07\nE = 9\nM = 3ce082eb\n\nModExp = 1c5fe761\nA = 523ab37f1\nE = 14\nM = 3ce082eb\n\nModExp = 21703009\nA = dc832165e8\nE = 20\nM = 3ce082eb\n\nModExp = 1228d1e\nA = a5555\nE = 3\nM = 24665b27\n\nModExp = 5226af4\nA = 1077bd6\nE = 4\nM = 24665b27\n\nModExp = 1b14eac1\nA = 2db3a834\nE = f\nM = 24665b27\n\nModExp = 161727bc\nA = 6bd962cb6\nE = 19\nM = 24665b27\n\nModExp = 10d61d0d\nA = c10caed407\nE = 28\nM = 24665b27\n\nModExp = 233da406\nA = b125f\nE = 3\nM = 33509981\n\nModExp = 24032799\nA = 1656b7c\nE = 6\nM = 33509981\n\nModExp = 129ecebe\nA = 2e671504\nE = a\nM = 33509981\n\nModExp = 20c20bac\nA = 4d7a2de44\nE = 1f\nM = 33509981\n\nModExp = 2e3ce9d3\nA = c53b3def4d\nE = 31\nM = 33509981\n\nModExp = 12fadfd6\nA = b4cf8\nE = 2\nM = 36e9d4ae\n\nModExp = 457ac85\nA = 1b1c7e9\nE = 7\nM = 36e9d4ae\n\nModExp = 31debef4\nA = 3a973028\nE = d\nM = 36e9d4ae\n\nModExp = 2333ad93\nA = 552b97c45\nE = 11\nM = 36e9d4ae\n\nModExp = 99ba1fb\nA = 8bfb949cbb\nE = 28\nM = 36e9d4ae\n\nModExp = 27b691de\nA = 93492\nE = 3\nM = 298fdb16\n\nModExp = 3c2b70f\nA = 14e7b0d\nE = 4\nM = 298fdb16\n\nModExp = 1486cda7\nA = 29acff81\nE = c\nM = 298fdb16\n\nModExp = 11725275\nA = 507489205\nE = 13\nM = 298fdb16\n\nModExp = 24d14627\nA = e71c55606d\nE = 35\nM = 298fdb16\n\nModExp = 222b8d14\nA = 9b1a0\nE = 3\nM = 3db59d12\n\nModExp = 3b8bd47d\nA = 13f4e8d\nE = 7\nM = 3db59d12\n\nModExp = 17e72356\nA = 334774ce\nE = a\nM = 3db59d12\n\nModExp = 306447ca\nA = 47079ddd2\nE = 12\nM = 3db59d12\n\nModExp = 90bef3b\nA = a75d62616d\nE = 37\nM = 3db59d12\n\nModExp = 1\nA = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678\nE = 0\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 0\nA = 0\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9\nA = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd\nE = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e\nM = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb\n\nModExp = 1\nA = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1\nE = 0\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 0\nA = 0\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0\nA = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d\nE = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d\nM = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061\n\nModExp = 1\nA = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600\nE = 0\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 0\nA = 0\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff\nA = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839\nE = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b\nM = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b\n\nModExp = 1\nA = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425", - "b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc\nE = 0\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 0\nA = 0\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f\nA = b4fde2908745ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe\nE = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f\nM = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f\n\nModExp = 1\nA = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f\nE = 0\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 0\nA = 0\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9\nA = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6\nE = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4\nM = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d\n\nModExp = 1\nA = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef\nE = 0\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 0\nA = 0\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e\nA = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914\nE = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e\nM = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d\n\nModExp = 1\nA = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332\nE = 0\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 0\nA = 0\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8\nA = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1\nE = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929\nM =", - " 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247\n\nModExp = 1\nA = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79\nE = 0\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 0\nA = 0\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9\nA = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 1\nA = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8\nE = 0\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 0\nA = 0\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa\nA = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 1\nA = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d\nE = 0\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 0\nA = 0\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca\nA = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\n# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in\n# order to test the const time precomputation scattering/gathering.\n\nModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b\nA = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898\nE = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f\nM = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d\n\nModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679\nA = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e", - "59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc\nE = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3\nM = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf\n\nModExp = 465ff295786a88496828fdc763e9292d557957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d\nA = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d\nE = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560\nM = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101\n\nModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd\nA = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9\nE = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c\nM = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479\n\nModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c\nA = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785\nE = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082\nM = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d\n\nModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e\nA = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059\nE = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902\nM = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9\n\nModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556\nA = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0\nE = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965\nM = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed\n\nModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510\nA = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83\nE = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693\nM = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11\n\nModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232\nA = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef\nE = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6\nM = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d\n\nModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e2", - "06ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e\nA = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286\nE = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0\nM = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7\n\n\n# RSAZ 512-bit.\n#\n# These are regression tests for code which historically reached the RSAZ-512\n# code. That has since been removed, but the test vectors remain. Note that the\n# lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4\nA = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same as above except A is negative.\nModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd\nA = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25\nA = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n\n# RSAZ 1024-bit.\n# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7\nA = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# Same as above except A is negative.\nModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10\nA = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Same inputs as above except A is negative. Note that A mod ", - "M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Regression test for CVE-2017-3738.\nModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df\nE = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff\n\n# Test vectors for CVE-2019-1551. (We do not carry the assembly file with the\n# bug, but we use the test vectors anyway.)\n\n# Original test vectors by OSS-Fuzz.\nModExp = 9d675d188a07e9bd1b32638cc8cfd5002ef89bd1a9648f806567b87939140a67977dc8da17323b8e4c6bc53875cda8b656df8f54cc32e44fd9c21d122ea3c0d6\nA = dea9b3e0b44ae67b2ac9b7c2b18eeb4dab206b014981a46ac409f195eeb6896f132cf8497c87d1188008ee511054ebb426203355b7d515dce9501cb759ac1373\nE = b01ae745b101e9e45ec05dcff72e7f8fc04c79ffe324301fda0b4f7be81d85c4e875c73fc6c5cb40000000000000000000000000000000000\nM = ffffffff01ffffffffffffffffffffffffffe2000000000000000000000000000010fab8d960706cd4c21818115650cad61d4f10da325dffffffff00ffff00ff\n\nModExp = 651f811b62ee8770e3598c340864dd6b0be9bb6376b6f933ab216fd55538e6ad1000cb2b3c64f54d554e004b6eec8138e6ecff00452d443a42041b72e6cd9ead\nA = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e\nE = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e09003e3e3e3e3e3e3e3e3e3e3e3e3e3e010900230a01230a2100ffffff0000adf300a58700000000ffffff00\nM = ffffff0b00000000000000000000000000ffffffff0000ffffffff00000a0000000a00000000000000000000ffffffff000000000000ffffffffffff000000ff\n\n# Test vectors for rsaz_512_sqr bug, with rcx/rbx=1\n\n# between first and second iteration\nModExp = 1\nA = 624e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d973b6\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between second and third iteration\nModExp = 1\nA = 11024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000f\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between third and fourth iteration\nModExp = 1\nA = 4171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d9736080000000000000000000000000000039\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fourth and fifth iteration\nModExp = 1\nA = 6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000006\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fifth and sixth iteration\nModExp = 1\nA = 44e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000000000000000000003c\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between sixth and seventh iteration\nModExp = 1\nA = 1024e6a171024e6a14ce297f2873536f959d8c3390d973608000000000000000000000000000000000000000000000000000000000000000000000000000000e\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between seventh and eighth iteration\nModExp = 1\nA = 626eee5e3c8653be47ed15e84b97cc7f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000187\nE = c0000000000000000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000002f8\nM = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f9\n\n# Test vectors for rsaz_512_srq bug, with rcx/rbx=2\n\n# between first and second iteration\nModExp = 1\nA = 3c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf7c\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between second and third iteration\nModExp = 1\nA = 485c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000003f\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between third and forth iteration\nModExp = 1\nA = 59a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000004e\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between forth and fifth iteration\nModExp = 1\nA = 2939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000000000000000000000000000000000000024\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between fifth and sixth iteration\nModExp = 1\nA = 640939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000000000000000000000000000000000000057\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between sixth and seventh iteration\nModExp = 1\nA = 25c40939a85c4093995e8efdb195e8efd8caf477ed8caf4780000000000000000000000000000000000000000000000000000000000000000000000000000021\nE = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e\nM = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f\n\n# between seventh and eighth iteration\nModExp = 1\nA = 7b4919849931b28a14fcace213f2b3884fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84b6e67b66ce4d9c\nE = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004c\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004d\n\n\n# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n\n\n# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30", - "f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\nA = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188", - "e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA = 03\nM = 01\n\nModInv = 64\nA = 54\nM = e3\n\nModInv = 13\nA = 2b\nM = 30\n\nModInv = 2f\nA = 30\nM = 37\n\nModInv = 4\nA = 13\nM = 4b\n\nModInv = 1c47\nA = cd4\nM = 6a21\n\nModInv = 2b97\nA = 8e7\nM = 49c0\n\nModInv = 29b9\nA = fcb\nM = 3092\n\nModInv = a83\nA = 14bf\nM = 41ae\n\nModInv = 18f15fe1\nA = 11b5d53e\nM = 322e92a1\n\nModInv = 32f9453b\nA = 8af6df6\nM = 33d45eb7\n\nModInv = d696369\nA = c5f89dd5\nM = fc09c17c\n\nModInv = 622839d8\nA = 60c2526\nM = 74200493\n\nModInv = fb5a8aee7bbc4ef\nA = 24ebd835a70be4e2\nM = 9c7256574e0c5e93\n\nModInv = 846bc225402419c\nA = 23026003ab1fbdb\nM = 1683cbe32779c59b\n\nModInv = 5ff84f63a78982f9\nA = 4a2420dc733e1a0f\nM = a73c6bfabefa09e6\n\nModInv = 133e74d28ef42b43\nA = 2e9511ae29cdd41\nM = 15234df99f19fcda\n\nModInv = 46ae1fabe9521e4b99b198fc8439609023aa69be2247c0d1e27c2a0ea332f9c5\nA = 6331fec5f01014046788c919ed50dc86ac7a80c085f1b6f645dd179c0f0dc9cd\nM = 8ef409de82318259a8655a39293b1e762fa2cc7e0aeb4c59713a1e1fff6af640\n\nModInv = 444ccea3a7b21677dd294d34de53cc8a5b51e69b37782310a00fc6bcc975709b\nA = 679280bd880994c08322143a4ea8a0825d0466fda1bb6b3eb86fc8e90747512b\nM = e4fecab84b365c63a0dab4244ce3f921a9c87ec64d69a2031939f55782e99a2e\n\nModInv = 1ac7d7a03ceec5f690f567c9d61bf3469c078285bcc5cf00ac944596e887ca17\nA = 1593ef32d9c784f5091bdff952f5c5f592a3aed6ba8ea865efa6d7df87be1805\nM = 1e276882f90c95e0c1976eb079f97af075445b1361c02018d6bd7191162e67b2\n\nModInv = 639108b90dfe946f498be21303058413bbb0e59d0bd6a6115788705abd0666d6\nA = 9258d6238e4923d120b2d1033573ffcac691526ad0842a3b174dccdbb79887bd\nM = ce62909c39371d463aaba3d4b72ea6da49cb9b529e39e1972ef3ccd9a66fe08f\n\nModInv = aebde7654cb17833a106231c4b9e2f519140e85faee1bfb4192830f03f385e773c0f4767e93e874ffdc3b7a6b7e6a710e5619901c739ee8760a26128e8c91ef8cf761d0e505d8b28ae078d17e6071c372893bb7b72538e518ebc57efa70b7615e406756c49729b7c6e74f84aed7a316b6fa748ff4b9f143129d29dad1bff98bb\nA = a29dacaf5487d354280fdd2745b9ace4cd50f2bde41d0ee529bf26a1913244f708085452ff32feab19a7418897990da46a0633f7c8375d583367319091bbbe069b0052c5e48a7daac9fb650db5af768cd2508ec3e2cda7456d4b9ce1c39459627a8b77e038b826cd7e326d0685b0cd0cb50f026f18300dae9f5fd42aa150ee8b\nM = d686f9b86697313251685e995c09b9f1e337ddfaa050bd2df15bf4ca1dc46c5565021314765299c434ea1a6ec42bf92a29a7d1ffff599f4e50b79a82243fb24813060580c770d4c1140aeb2ab2685007e948b6f1f62e8001a0545619477d498132c907774479f6d95899e6251e7136f79ab6d3b7c82e4aca421e7d22fe7db19c\n\nModInv = 1ec872f4f20439e203597ca4de9d1296743f95781b2fe85d5def808558bbadef02a46b8955f47c83e1625f8bb40228eab09cad2a35c9ad62ab77a30e3932872959c5898674162da244a0ec1f68c0ed89f4b0f3572bfdc658ad15bf1b1c6e1176b0784c9935bd3ff1f49bb43753eacee1d8ca1c0b652d39ec727da83984fe3a0f\nA = 2e527b0a1dc32460b2dd94ec446c692989f7b3c7451a5cbeebf69fc0ea9c4871fbe78682d5dc5b66689f7ed889b52161cd9830b589a93d21ab26dbede6c33959f5a0f0d107169e2daaac78bac8cf2d41a1eb1369cb6dc9e865e73bb2e51b886f4e896082db199175e3dde0c4ed826468f238a77bd894245d0918efc9ca84f945\nM = b13133a9ebe0645f987d170c077eea2aa44e85c9ab10386d02867419a590cb182d9826a882306c212dbe75225adde23f80f5b37ca75ed09df20fc277cc7fbbfac8d9ef37a50f6b68ea158f5447283618e64e1426406d26ea85232afb22bf546c75018c1c55cb84c374d58d9d44c0a13ba88ac2e387765cb4c3269e3a983250fa\n\nModInv = 30ffa1876313a69de1e4e6ee132ea1d3a3da32f3b56f5cfb11402b0ad517dce605cf8e91d69fa375dd887fa8507bd8a28b2d5ce745799126e86f416047709f93f07fbd88918a047f13100ea71b1d48f6fc6d12e5c917646df3041b302187af641eaedf4908abc36f12c204e1526a7d80e96e302fb0779c28d7da607243732f26\nA = 31157208bde6b85ebecaa63735947b3b36fa351b5c47e9e1c40c947339b78bf96066e5dbe21bb42629e6fcdb81f5f88db590bfdd5f4c0a6a0c3fc6377e5c1fd8235e46e291c688b6d6ecfb36604891c2a7c9cbcc58c26e44b43beecb9c5044b58bb58e35de3cf1128f3c116534fe4e421a33f83603c3df1ae36ec88092f67f2a\nM = 53408b23d6cb733e6c9bc3d1e2ea2286a5c83cc4e3e7470f8af3a1d9f28727f5b1f8ae348c1678f5d1105dc3edf2de64e65b9c99545c47e64b770b17c8b4ef5cf194b43a0538053e87a6b95ade1439cebf3d34c6aa72a11c1497f58f76011e16c5be087936d88aba7a740113120e939e27bd3ddcb6580c2841aa406566e33c35\n\nModInv = 87355002f305c81ba0dc97ca2234a2bc02528cefde38b94ac5bd95efc7bf4c140899107fff47f0df9e3c6aa70017ebc90610a750f112cd4f475b9c76b204a953444b4e7196ccf17e93fdaed160b7345ca9b397eddf9446e8ea8ee3676102ce70eaafbe9038a34639789e6f2f1e3f352638f2e8a8f5fc56aaea7ec705ee068dd5\nA = 42a25d0bc96f71750f5ac8a51a1605a41b506cca51c9a7ecf80cad713e56f70f1b4b6fa51cbb101f55fd74f318adefb3af04e0c8a7e281055d5a40dd40913c0e1211767c5be915972c73886106dc49325df6c2df49e9eea4536f0343a8e7d332c6159e4f5bdb20d89f90e67597c4a2a632c31b2ef2534080a9ac61f52303990d\nM = d3d3f95d50570351528a76ab1e806bae1968bd420899bdb3d87c823fac439a4354c31f6c888c939784f18fe10a95e6d203b1901caa18937ba6f8be033af10c35fc869cf3d16bef479f280f53b3499e645d0387554623207ca4989e5de00bfeaa5e9ab56474fc60dd4967b100e0832eaaf2fcb2ef82a181567057b880b3afef62\n\n\n# GCD tests.\n#\n# These test vectors satisfy gcd(A, B) = GCD and lcm(A, B) = LCM.\n\nGCD = 0\nA = 0\nB = 0\n# Just to appease the syntax-checker.\nLCM = 0\n\nGCD = 1\nA = 92ff140ac8a659b31dd904161f9213706a08a817ae845e522c3af0c9096699e059b47c8c2f16434b1c5766ebb384b79190f2b2a62c2378f45e116890e7bb407a\nB = 2f532c9e5902b0d68cd2ed69b2083bc226e8b04c549212c425a5287bb171c6a47fcb926c70cc0d34b8d6201c617aee66af865d31fdc8a2eeb986c19da8bb0897\nLCM = 1b2c97003e520b0bdd59d8c35a180b4aa36bce14211590435b990ad8f4c034ce3c77899581cb4ee1a022874203459b6d53859ab1d99ff755efa253fc0e5d8487bb000c13c566e8937f0fe90b95b68bc278610d4f232770b08d1f31bee55a03da47f2d0ebb9e7861c4f16cc22168b68593e9efcde00f54104b4c3e1a0b294d7f6\n\nGCD = a\nA = faaffa431343074f5c5d6f5788500d7bc68b86eb37edf166f699b4d75b76dae2cb7c8f6eccae8f18f6d510ef72f0b9633d5740c0bebb934d3be796bd9a53808e\nB = 2f48ec5aa5511283c2935b15725d30f62244185573203b48c7eb135b2e6db5c115c9446ac78b020574665b06a75eb287e0dbeb5da7c193294699b4c2129d2ac4\nLCM = 4a15f305e9622aa19bd8f39e968bfc16d527a47f7a5219d7b02c242c77ef8b608a4a6141f643ca97cedf07c0f1f3e8879d2568b056718aa15c0756899a08ccbe0a658bae67face96fa110edb91757bfa4828e8ff7c5d71b204f36238b12dd26f17be8ba9771f7068d63e41d423671f898f054b1187605754bc5546f2b02c5ac\n\nGCD = 16\nA = cf0b21bde98b41b479ac8071086687a6707e9efaacd4e5299668ce1be8b13290f27fd32ae68df87c292e8583a09d73ec8e8a04a65a487380dcd7dacca3b6e692\nB = 3be3f563f81d5ad5c1211db7eff430aa345e830ce07b4bde7d4d32dba3ac618d2034351e5435fd6c7f077971fb4a1e83a7396a74fdff7fce1267112851db2582\nLCM = 233a2188de2c017235024b182286f17562b2ee5ab9fdfe4efa2f61c4ff99fa44e1ead5bf6cde05bd7502ce78373c83e3f9dbab0c9bb8620a87c2640bce5d12c685af656df789bb3d0ba1edbaa98cf4f0166d422ab17aa6706f8132264d45b72827d6671a00a9186e723379e3a3bb7902d08865f357c74100059f83800241976\n\nGCD = 1\nA = dd7b7597d7c1eb399b1cea9b3042c14bd6022d31b1d2642a8f82fc32de6eadaf012fbbf349eaec4922a8468740ca73c6090833d6a69a380ed947b39c2f9b0b76\nB = 8e0dc8654e70eec55496038a8d3fff3c2086bc6dbfc0e2dbdf5bd7de03c5aef01a3982556ac3fc34fd5f13368be6cdc252c82367b7462e210f940f847d382dd9\nLCM = 7ae667df4bd4dd35bbec28719a9f1b5e1f396a9ab386c086742a6ab3014a3386d39f35b50624d0c5b4e6b206c2635c7de5ea69e2faa85dd616a7e36622962a07632839857aa49332942feccff2aee1c962e2f4e8ccfd738a5da5bf528b4c5a2440409350f5a17a39d234403e8482ccf838e0d2758ccfb8018198a51dbb407506\n\nGCD = 1\nA = 0\nB = 1\nLCM = 0\n\nGCD = 1\nA = 1\nB = 0\nLCM = 0\n\nGCD = 1\nA = 1\nB = 1\nLCM = 1\n\nGCD = 2b2\nA = dfccaa3549c1b59ab3e114fe87dc5d187719abad58c51724e972741eb895ab79a49f385f61d531ec5c88dbb505ae375093fa848165f71a5ed65e7832a42ade191a\nB = fa58a81f43088da45e659fc1117d0f1cd015aa096c8e5377cf1832191baf7cc28b5c24998b93b64f8900a0973faedb9babaaf1854345f011739da8f1175d9684c\nLCM = 5132f7ab7a982b9dc55114bd96800b7637f9742cf8a7a00a0d69d5e4574fc85792c89a1c52bcfc74b9d7f3f6164819466c46b2d622e280ced7ad121160", - "4084a15dc1fd1951a05c8ce37122c0ec15891d818a70d3763670ea3195098de9b1ca50ea89893a9753fb9ea801541058f44801f7f50967124abfc864a2b01c41f94193c\n\nGCD = 8e\nA = 248d96a8a4cab0a1b194e08c1146868b094597cadbc35531f0ed2d77cba9f15cb5cc7c10e64ce054bf93396d25259d750b3de3aba65073db1fd2b852a6454ac1a\nB = 4c7bad8e1844901fd6a2ce2edc82e698d28ec95d6672ca148d85b49ecc78dd0a8b870e202244210bc98592b99ff6abbd20630f9eee7d46b15ccfae8d08b86799de\nLCM = 13b01f9d9c6c13e90c97e3d95bbce5a835c631b3de3bd4ff5df13ad850f5223dbdf71c53912275d0397df9335ef3a3ba8e4684c6b25962bb7b18bc74144cb5edf0196f79863a7ff032619a71646a92281f7baace7f223d254cb4d05ec19bf8d4c8ce4455a9d770daec89c0d3cf338cbdae39cf982b3c4568f5c9def4e1133d28a\n\nGCD = 3e55\nA = 2fa97382f46676b7a4cc2b8153f17b58792d24660e187d33ce55c81cc193ccb6e1e2b89feea1d5fd8faa36e13bf947fb48635e450a4d1488d0978324194a1f43c6\nB = ab08ad074139963bc18e5d87ba68db64ca6f4c279616c64039b02c55f2375b3bc04114e8e05e1ba92fb6470768f61d123845aea36774c18612736a220934561faf\nLCM = 82c7c377ecda2cb9228604cd287df5eff94edd4a539c3eb3b3fdd4b4a79d2f4eaf2b22f8286272d3dad2e370cfcd9ea4d93ebb3f049c52b8fa23b68a5bf79af989822e2cfb978f68c6a5058f47319dffcb455b089b06ae6db9e5c8a2b6e951d6e118bd2b4cd08b6e5733476a446a57387d940d1289ec00e24315821ed3a5daf2\n\nGCD = a7a\nA = 923706dfed67834a1e7e6c8e8e9f93bfbc0b43ca1f324886cf1f1380fb9b77109275d4b50af1b7689802fe9b3623ac46c7ba0e17e908c20278127b07a5c12d86ec\nB = 64473e878a29021fac1c1ce34a63eae1f4f83ee6851333b67213278b9a4a16f005cba0e8cdb410035bb580062f0e486c1a3a01f4a4edf782495f1dc3ebfa837d86\nLCM = 57785ca45b8873032f1709331436995525eed815c55140582ce57fd852116835deac7ca9d95ce9f280e246ea4d4f1b7140ab7e0dd6dc869de87f1b27372098b155ad0a1828fd387dff514acc92eae708609285edaab900583a786caf95153f71e6e6092c8c5ee727346567e6f58d60a5e01c2fa8ebcf86da9ea46876ecc58e914\n\nGCD = 42\nA = 0\nB = 42\nLCM = 0\n\nGCD = 42\nA = 42\nB = 0\nLCM = 0\n\nGCD = 42\nA = 42\nB = 42\nLCM = 42\n\nGCD = f60d\nA = ef7886c3391407529d5cf2e75ed53e5c3f74439ad2e2dc48a79bc1a5322789b4ced2914b97f8ff4b9910d212243b54001eb8b375365b9a87bd022dd3772c78a9fd63\nB = d1d3ec32fa3103911830d4ec9f629c5f75af7039e307e05bc2977d01446cd2cbeeb8a8435b2170cf4d9197d83948c7b8999d901fe47d3ce7e4d30dc1b2de8af0c6e4\nLCM = cc376ed2dc362c38a45a719b2ed48201dab3e5506e3f1314e57af229dc7f3a6a0dad3d21cfb148c23a0bbb0092d667051aa0b35cff5b5cc61a7c52dec4ed72f6783edf181b3bf0500b79f87bb95abc66e4055f259791e4e5eb897d82de0e128ecf8a091119475351d65b7f320272db190898a02d33f45f03e27c36cb1c45208037dc\n\nGCD = 9370\nA = 1ee02fb1c02100d1937f9749f628c65384ff822e638fdb0f42e27b10ee36e380564d6e861fcad0518f4da0f8636c1b9f5124c0bc2beb3ca891004a14cd7b118ddfe0\nB = 67432fd1482d19c4a1c2a4997eab5dbf9c5421977d1de60b739af94c41a5ad384cd339ebfaa43e5ad6441d5b9aaed5a9f7485025f4b4d5014e1e406d5bd838a44e50\nLCM = 159ff177bdb0ffbd09e2aa7d86de266c5de910c12a48cbe61f6fa446f63a2151194777555cd59903d24cb30965973571fb1f89c26f2b760526f73ded7ee8a34ebcecd1a3374a7559bcdb9ac6e78be17a62b830d6bb3982afdf10cf83d61fd0d588eab17d6abef8e6a7a5763fcb766d9a4d86adf5bb904f2dd6b528b9faec603987a0\n\nGCD = c5f\nA = 5a3a2088b5c759420ed0fb9c4c7685da3725b659c132a710ef01e79435e63d009d2931ea0a9ed9432f3d6b8851730c323efb9db686486614332c6e6ba54d597cf98\nB = 1b1eb33b006a98178bb35bbcf09c5bebd92d9ace79fa34c1567efa8d6cf6361547807cd3f8e7b8cd3ddb6209dccbae4b4c16c8c1ec19741a3a57f61571882b7aed7\nLCM = c5cbbbe9532d30d2a7dd7c1c8a6e69fd4fa4828a844d6afb44f3747fef584f7f1f3b835b006f8747d84f7699e88f6267b634e7aef78d6c7584829537d79514eec7d11219721f91015f5cefdc296261d85dba388729438991a8027de4827cd9eb575622e2912b28c9ce26d441e97880d18db025812cef5de01adeaec1322a9c9858\n\nGCD = e052\nA = 67429f79b2ec3847cfc7e662880ab1d94acdf04284260fcfffd67c2862d59704ed45bcc53700c88a5eea023bc09029e9fd114fc94c227fd47a1faa1a5ef117b09bd2\nB = 39faa7cbdeb78f9028c1d50ab34fbe6924c83a1262596f6b85865d4e19cc258b3c3af1ee2898e39e5bee5839e92eac6753bbbb0253bd576d1839a59748b778846a86\nLCM = 1ab071fb733ef142e94def10b26d69982128561669e58b20b80d39cf7c2759d26b4a65d73b7f940c6e8fc417180ef62d7e52ac24678137bd927cd8d004ad52b02affe176a1ecde903dbc26dcc705678f76dd8cd874c0c3fe737474309767507bbe70dd7fb671bbb3694cedf0dcdaa0c716250ddd6dfec525261572fa3e1387f7b906\n\nGCD = 3523\nA = 0\nB = 3523\nLCM = 0\n\nGCD = 3523\nA = 3523\nB = 0\nLCM = 0\n\nGCD = 3523\nA = 3523\nB = 3523\nLCM = 3523\n\nGCD = f035a941\nA = 16cd5745464dfc426726359312398f3c4486ed8aaeea6386a67598b10f744f336c89cdafcb18e643d55c3a62f4ab2c658a0d19ea3967ea1af3aee22e11f12c6df6e886f7\nB = 74df09f309541d26b4b39e0c01152b8ad05ad2dfe9dd2b6706240e9d9f0c530bfb9e4b1cad3d4a94342aab309e66dd42d9df01b47a45173b507e41826f24eb1e8bcc4459\nLCM = b181771d0e9d6b36fdfcbf01d349c7de6b7e305e1485ea2aa32938aa919a3eee9811e1c3c649068a7572f5d251b424308da31400d81ac4078463f9f71d7efd2e681f92b13a6ab3ca5c9063032dcbdf3d3a9940ce65e54786463bbc06544e1280f25bc7579d264f6f1590cf09d1badbf542ce435a14ab04d25d88ddbac7d22e8cae1c91f\n\nGCD = 33ad1b8f\nA = 1af010429a74e1b612c2fc4d7127436f2a5dafda99015ad15385783bd3af8d81798a57d85038bcf09a2a9e99df713b4d6fc1e3926910fbbf1f006133cb27dc5ebb9cca85\nB = 92a4f45a90965a4ef454f1cdd883d20f0f3be34d43588b5914677c39d577a052d1b25a522be1a656860a540970f99cbc8a3adf3e2139770f664b4b7b9379e13daf7d26c\nLCM = 4c715520ed920718c3b2f62821bc75e3ff9fd184f76c60faf2906ef68d28cd540d3d6c071fa8704edd519709c3b09dfaee12cb02ab01ad0f3af4f5923d5705ce6d18bcab705a97e21896bb5dd8acb36ee8ec98c254a4ddc744297827a33c241f09016a5f109248c83dd41e4cea73ce3eabb28d76678b7e15545b96d22da83c111b6b624\n\nGCD = dc0429aa\nA = ccb423cfb78d7150201a97114b6644e8e0bbbb33cadb0ef5da5d3c521a244ec96e6d1538c64c10c85b2089bdd702d74c505adce9235aa4195068c9077217c0d431de7f96\nB = 710786f3d9022fc3acbf47ac901f62debcfda684a39234644bac630ab2d211111df71c0844b02c969fc5b4c5a15b785c96efd1e403514235dc9356f7faf75a0888de5e5a\nLCM = 6929af911850c55450e2f2c4c9a72adf284fe271cf26e41c66e1a2ee19e30d928ae824f13d4e2a6d7bb12d10411573e04011725d3b6089c28d87738749107d990162b485805f5eedc8f788345bcbb5963641f73c303b2d92f80529902d3c2d7899623958499c8a9133aae49a616c96a2c5482a37947f23af18c3247203ac2d0e760340e6\n\nGCD = 743166058\nA = 16cd476e8031d4624716238a3f85badd97f274cdfd9d53e0bd74de2a6c46d1827cc83057f3889588b6b7ca0640e7d743ed4a6eaf6f9b8df130011ecc72f56ef0af79680\nB = 86eba1fc8d761f22e0f596a03fcb6fe53ad15a03f5b4e37999f60b20966f78ba3280f02d3853f9ace40438ccfaf8faed7ace2f2bf089b2cdd4713f3f293bf602666c39f8\nLCM = 1a7a1b38727324d6ba0290f259b8e2b89c339b2445cada38a5a00ded1468ab069f40678ce76f7f78c7c6f97783cc8a49ef7e2a0c73abbac3abc66d1ce99566ce7f874a8949ca3442051e71967695dc65361184748c1908e1b587dc02ed899a524b34eb30b6f8db302432cfa1a8fbf2c46591e0ab3db7fd32c01b1f86c39832ee9f0c80\n\nGCD = 6612ba2c\nA = 0\nB = 6612ba2c\nLCM = 0\n\nGCD = 6612ba2c\nA = 6612ba2c\nB = 0\nLCM = 0\n\nGCD = 6612ba2c\nA = 6612ba2c\nB = 6612ba2c\nLCM = 6612ba2c\n\nGCD = 2272525aa08ccb20\nA = 11b9e23001e7446f6483fc9977140d91c3d82568dabb1f043a5620544fc3dda233b51009274cdb004fdff3f5c4267d34181d543d913553b6bdb11ce2a9392365fec8f9a3797e1200\nB = 11295529342bfb795f0611d03afb873c70bd16322b2cf9483f357f723b5b19f796a6206cf3ae3982daaeafcd9a68f0ce3355a7eba3fe4e743683709a2dd4b2ff46158bd99ff4d5a0\nLCM = 8d4cbf00d02f6adbaa70484bcd42ea932000843dcb667c69b75142426255f79b6c3b6bf22572597100c06c3277e40bf60c14c1f4a6822d86167812038cf1eefec2b0b19981ad99ad3125ff4a455a4a8344cbc609e1b3a173533db432bd717c72be25e05ed488d3970e7ed17a46353c5e0d91c8428d2fec7a93210759589df042cab028f545e3a00\n\nGCD = 3480bf145713d56f9\nA = 8cf8ef1d4f216c6bcec673208fd93b7561b0eb8303af57113edc5c6ff4e1eeae9ddc3112b943d947653ba2179b7f63505465126d88ad0a0a15b682f5c89aa4a2a51c768cd9fdeaa9\nB = a6fd114023e7d79017c552a9051ca827f3ffa9f31e2ee9d78f8408967064fcdc9466e95cc8fac9a4fa88248987caf7cf57af58400d27abd60d9b79d2fe03fad76b879eceb504d7f\nLCM = 1c05eee73a4f0db210a9007f94a5af88c1cdd2cba456061fd41de1e746d836fa4e0e972812842e0f44f10a61505f5d55760c48ba0d06af78bb6bde7da8b0080b29f82b1161e9c0b5458e05ac090b00f4d78b1cc10cf065124ba610e3acab092a36fe408525e21c0ddc7c9696ed4e48bd2f70423deecfe62cecc865c6088f265da0e5961d3f3a84f\n\nGCD = 917e74ae941fcaae\nA = 652f8a92d96cbf0a309629011d0fbaceb1266bc2e8243d9e494eead4cf7100c661b537a8bea93dec88cfc68597d88a976c125c3b4de19aba38d4ea9578202e59848d42652518348a\nB = 32e07b71979d57e8344e97c39680a61e07d692d824ae26b682156890792d8a766ee29a4968f461aaced5bf049044fba2f4120b1c1f05985676f975d4582e9e82750d73c532cd07b2\nLCM = 23620c7b897dc26c7717e32f3517ac70bf09fbe08f7255ab010cf4cf946f4e96304c", - "425043452c5d5a0e841d3a3cfd9c2d84d9256f3b5974fe3ebfa9255fe20a710d3e6511606c0d85970381101c7f4986d65ad6a73a71507f146b11f903043cfa805cc0b14d4f3072da98bf22282f7762040406c02d5b3ef9e7587f63bab8b29c61d8e30911aa96\n\nGCD = 2b9adc82005b2697\nA = 19764a84f46045ef1bca571d3cbf49b4545998e64d2e564cc343a53bc7a0bcfbe0baa5383f2b346e224eb9ce1137d9a4f79e8e19f946a493ff08c9b423574d56cbe053155177c37\nB = 1bbd489ad2ab825885cdac571a95ab4924e7446ce06c0f77cf29666a1e20ed5d9bc65e4102e11131d824acad1592075e13024e11f12f8210d86ab52aa60deb250b3930aabd960e5a\nLCM = 1032a0c5fffc0425e6478185db0e5985c645dd929c7ebfeb5c1ee12ee3d7b842cfab8c9aa7ff3131ac41d4988fb928c0073103cea6bb2cc39808f1b0ad79a6d080eac5a0fc6e3853d43f903729549e03dba0a4405500e0096b9c8e00510c1852982baec441ed94efb80a78ed28ed526d055ad34751b831b8749b7c19728bf229357cc5e17eb8e1a\n\nGCD = 8d9d4f30773c4edf\nA = 0\nB = 8d9d4f30773c4edf\nLCM = 0\n\nGCD = 8d9d4f30773c4edf\nA = 8d9d4f30773c4edf\nB = 0\nLCM = 0\n\nGCD = 8d9d4f30773c4edf\nA = 8d9d4f30773c4edf\nB = 8d9d4f30773c4edf\nLCM = 8d9d4f30773c4edf\n\nGCD = 6ebd8eafb9a957a6c3d3d5016be604f9624b0debf04d19cdabccf3612bbd59e00\nA = 34dc66a0ffd5b8b5e0ffc858dfc4655753e59247c4f82a4d2543b1f7bb7be0e24d2bbf27bb0b2b7e56ee22b29bbde7baf0d7bfb96331e27ba029de9ffdff7bdb7dc4da836d0e58a0829367ec84ea256833fd4fe1456ad4dd920557a345e12000\nB = 1f3406a20e20ebf96ccb765f898889a19b7636608fd7dc7c212607b641399543f71111d60e42989de01eaa6ff19a86ea8fbde1a3d368c0d86dc899e8e250fc764090f337958ca493119cbb4ad70cbfae7097d06d4f90ec62fbdd3f0a4496e600\nLCM = ee502c50e3667946e9089d0a9a0382e7fd0b75a17db23b56a0eec997a112c4dbd56d188808f76fe90451e5605550c9559ef14a95014c6eb97e9c1c659b98515c41470142843de60f72fb4c235faa55b0a97d943221003d44e2c28928f0b84bf071256254897ed31a7fd8d174fc962bc1311f67900ac3abcad83a28e259812f1ee229511ab1d82d41f5add34693ba7519babd52eb4ec9de31581f5f2e40a000\n\nGCD = ef7399b217fc6a62b90461e58a44b22e5280d480b148ec4e3b4d106583f8e428\nA = 7025e2fe5f00aec73d90f5ad80d99ca873f71997d58e59937423a5e6ddeb5e1925ed2fd2c36a5a9fc560c9023d6332c5d8a4b333d3315ed419d60b2f98ccf28bbf5bf539284fd070d2690aeaac747a3d6384ee6450903a64c3017de33c969c98\nB = df0ac41dbabce1deeb0bceb1b65b1079850052ecf6534d0cff84a5a7fb5e63baee028d240f4419925154b96eaa69e8fbb1aae5102db7916234f290aa60c5d7e69406f02aeea9fe9384afbff7d878c9ac87cd31f7c35dff243b1441e09baff478\nLCM = 687669343f5208a6b2bb2e2efcac41ec467a438fde288cc5ef7157d130139ba65db9eb53e86a30c870bd769c0e0ab15a50f656cd9626621ae68d85eaff491b98da3ea5812062e4145af11ea5e1da457084911961ef2cd2ac45715f885ba94b4082aa76ffd1f32461f47c845b229d350bf36514c5ce3a7c782418746be342eca2721346ade73a59475f178c4f2448e1326110f5d26a0fef1a7a0c9288489e4dc8\n\nGCD = 84b917557acf24dff70cb282a07fc52548b6fbbe96ca8c46d0397c8e44d30573\nA = 81dbb771713342b33912b03f08649fb2506874b96125a1ac712bc94bfd09b679db7327a824f0a5837046f58af3a8365c89e06ff4d48784f60086a99816e0065a5f6f0f49066b0ff4c972a6b837b63373ca4bb04dcc21e5effb6dfe38271cb0fa\nB = 1da91553c0a2217442f1c502a437bb14d8c385aa595db47b23a97b53927b4493dd19f1bc8baf145bc10052394243089a7b88d19b6f106e64a5ab34acad94538ab504d1c8ebf22ac42048bbd1d4b0294a2e12c09fe2a3bd92756ba7578cb34b39\nLCM = 1d0530f8142754d1ee0249b0c3968d0ae7570e37dadbe4824ab966d655abf04cd6de5eb700eba89d8352dec3ae51f2a10267c32fbd39b788c7c5047fe69da3d7ad505435a6212f44899ba7e983bb780f62bcdee6f94b7dba8af7070a4cc008f351ae8be4579bc4a2e5c659ce000ad9c8cdc83723b32c96aeb0f5f4127f6347353d05525f559a8543cd389ad0af6f9d08a75b8c0b32419c097e6efe8746aee92e\n\nGCD = 66091477ea3b37f115038095814605896e845b20259a772f09405a8818f644aa\nA = cedac27069a68edfd49bd5a859173c8e318ba8be65673d9d2ba13c717568754ed9cbc10bb6c32da3b7238cff8c1352d6325668fd21b4e82620c2e75ee0c4b1aff6fb1e9b948bbdb1af83cecdf356299b50543b72f801b6a58444b176e4369e0\nB = 5f64ca1ba481f42c4c9cf1ffa0e515b52aa9d69ceb97c4a2897f2e9fa87f72bae56ee6c5227f354304994c6a5cc742d9f09b2c058521975f69ca5835bce898cf22b28457cd7e28870df14e663bb46c9be8f6662f4ff34d5c4ae17a888eba504e\nLCM = c163cb28642e19a40aa77887c63180c2c49fc10cda98f6f929c8131752ea30b5283a814a81681b69b9d1762e6c1a9db85f480bc17f998d235fd7e64c1caa70ef170c9e816d3e80f516b29f2c80cfb68bf208b4d5082ef078da4314b3f20c7d6c54b0aeb378096b029a7b61c0a4cd14aeddc01004c53915a4f692d2291752e5af46b23d7fa6dd61f2d56c6f4bf8e6119688abac8fd7aba80e846a7764bb3fca0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = 0\nB = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nLCM = 0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nB = 0\nLCM = 0\n\nGCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nA = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nB = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\nLCM = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182\n\nGCD = 120451d8307219aa0c96f328ad653ccd462e92423ca93ed8a3dde45bf5cb9b13cdaf9800e4d05dd71c4db6a129fb3280ee4ec96ec5297d881c1a8b5efccbd91fef21f5c5bf5fba42a4c8eaa358f620a074b7a17054527bdaa58d5acaa0dfdc48ecba1a10ebf4d57bb4215de406e6be13fed3fe493b1cd1e2d11a8d4ac03c47756\nA = 3f8179a8e1f0b342475a855c3e1bae402dd41424cf24a0b4d2e263c8efb08bde7d92eae8607fb5e88b1378f0f1bd0733f229a35be6b1383a48d32749d5d6b32427d26323b7ab05bb5781289e96bfbc21971439319b15f6c0fe93fdb35d0b67ec41443c59a081dd3cef047ac797fccb45bece84c0bb0bb7e1797259526d8ec9cc63ba4d32cfc692ccd3d243cb2b53ac216312f3a8e8c0daa09d21b6150d697639a5e52059414a417c607be8ec0eee2e708219cadbaf37a369c4485b01ed87bbc2\nB = 2c474e396a2dd9cd10b9d7313f69d3b4ca123e9fd853edd488339236d14c56453a1381958864a04d2624e81995dabcdd0ccf60db9917813f887de68da075d0ea4440001e18f470e43b38ee3440b49be651d709fbdef980e3e4149913f4ae2681124f54523f4881376ddb533b5219e804cc26f4c2e577be4e02613c4da80ba1215775b0a5178a965ad47bd2befb32493943ded1004ef66347b4983f8d1ba990d4a943505dfce6debcfb322842ed88106cd6dee9aa592ff0d2274bc727a6e1f14c\nLCM = 9c129cf649555bfd2d3d9c64dc6d6f022295e53bca5d2f218adaa66aa60eb4694429b7e83bf81b6df4459c5104023ab9a33f006ffcd8114507baa17e2ef6fe23ebdd4740f66879033da2041f2cb7ba517ad3526ffe75614ea9432c085f71b2d65a736bac7ba42b639e330b82733372083843dcb78b6a273ab20e0d4b7c8998a14048aa15bb20a0a0bd997917107274c89b4cec175fb98043d52e6c555bd9e0036566d052a6d4e7e276d1e8835e1f06e3ca46d47747ba586e95fb1a790d992834b7c3e136141eb8a434e6c12067246ac3c0a81c69e03b1ed28aa0b3173d6eff83d278c2f461a47a416f3f9a5dae3bb410fd18817bd4115e7f1e84b936cc02364\n\nGCD = 95aa569a2c76854300d7660847dd20fe0b8c445fdbcaa98465cee61aee76ad6a438e75a8c573198570ffb62bc07ec3a2be0ae0a1f631670fa88d6f75f3161e8b9a4d44b6801ffc884c7f469c5ed1f27b1edecce9f2977f9e92d1a3b230492fea7e6f2af739dc158a7fbd29856cbedb57b4119e64b27ab09eb1c2df01507d6e7fd\nA = 4c653b5bfec44e9be100c064dffe5d8cd59b0cf4cc56b03eabb4ef87cfda6506c9a756b811907fe9d8b783eb7a0b9e129773bf1da365ddb488d27b16fb983e89345d1ccdb4f06a67a11925c3f266373be5d7b0075189c6f3c2157e2da197058fe0a7bcc50adc34e99e254a29abbe2d5948d3157e1b0c3fca3d641760f7b9862843b63abef0b3d83fd486f4526b30382fda355575da30e9a106718a3921774c4d69f5311f8d737fe618f5236b4763fe1b2ee7f13184db67367d3903c535ff6d7b\nB = 2dcca83c99a28e9fd2f84e78973699baf2f04fd454094730948b22477834a0064817b86e0835e6d7b26e5b0b1dcf4ad91a07ac0780d6522df1fcac758cf5db6c2a5623d7c0f1afefd5718f7b6de639867d07a9ec525991304e9355d1635104bea837f74758d6aa2aab4e4afbb606af1d98de7417505e4710cd0589bdff9a0bf38a857cc59a5f1781043e694fc2337fd84bdeb28b13a222bb09328a81ec409ad586e74236393d27398cc24d412135e34247c589149e134b97f4bd538ac9a3424b\nLCM = 1760c0b0066aa0695767099e87e9388729ea89b8e8c36bddcd04d257591e741613c07b0e69447c0a468c33a745084171e06523d987d8db40a1433bf435325e8a724a0876503b34495170ff3671d42117a2e4f3a75b1d9dd809a34fa0fb26fe50d84f80a9b02e40190e5efb927a5a61a03f13edbce2e666af6c3a2a9bcb84e47e3090008753ff27c4b8cf06480f471379a93f5230923623a83b286b71a555cd5e5347282f664ed90b14b2c4de84a70375e488211a7b3931119ef3bbe029b712389fe784818a0bf29d80733ce9cc940c547aa1eb3f06d492eb676bf37802283c82ce76156dfaab5c2d5107e08062681b5fa169f6eb68e1ab8bd9b2005e90bd4fd\n\nGCD = 244b9b1290cf5b4ba2f810574c050651489f2d3a2b03e702b76ebfaf4e33de9bbe5da24c919e68d3a72eadd35982b3a89c6b18b38ff7082ac65263e52b6ec75a5717b971c98257b194c828bff0216a99536603b41a396ea2fb50f5ea7cf3edf10bb0d039123e78593ae9ffcbbba02e51e038533e83b6bc73c70551d6467f39809\nA = 41a0b1310669500681cdf888836f6c", - "556758750f562d743ac780dd4c0d161856380e44fdbb1f8a2786bf45be6b0e7f1cb2cd85f6b9e50acc72793d92383c7d7fb796fc74d32e8fac8225bdc19ae47546d9c9c75f5f06ca684f07daccaf89ccf2cddeb7ec255d530c7dd1e71daf44cafdc9d30fbcb1cbaefae3480585f79f4177e3834a5bc91845e2e8cd8aeb27f484e5e5b2c3c076dbb6c23e91303f0a0fdde83cd33a8ea6ed1549e727b4d766c1017c169710fd98e1585d60f66e121f9180b3\nB = 251f5aeaa60b3959285f49540cdaf8e21451110bbddb9933bbbcaea3112f4eb45e435a3ba37c52d2ab79ce997a8f6c829b3aa561f2852924b8effb52396d09d2bf257ebb4fb56c7aa25648f69b06d2cd01e876c9f9c0679de9e6fffa79eb7e603723e5af7de46ee405a5a079229577b5b6fffb8d43e391fe6f4eb89638e64d6eff8026249aaa355a91625eb0bfd14caa81e4c3586aaa2e94fde143a44f223a91e226661d12f55dfcdb4215e5a64e14e968005733be6a71c465de312ca109b34a\nLCM = 431f918b274f3e43f446e4e85567883d6536a0332db662cef088f5a36b0f4b68372048174ba10fee94b9f8f1c2e189c974be2e6e8ae8e2ae108445326d40f63e38d8d4e2e46174589a3cbc9583e0036dc8146e79eee9e96f4436313b3f143dd0f5aceab05243def7f915169c360f55ef123977cf623c5ba432c3259c62fb5e37d5adab0f24b825aa4ada99ec4e83e9ca4698399e1ed633091ce5f9844c540a642cd264201116ed4168aa2105a5159f5df064f845830c469140f766c7319052ce59bd1ad7c3f2d8c30e54f147f6aeb5586c70c984302ba18d854a60aec01b394c7d66fa33fe18fe4a8cfb3238df219294e6e42190a30d28b10049a1b75853a4e\n\nGCD = 206695d52bc391a4db61bf8cb6ea96188333a9c78f477ee76976c2346dad682cf56ca6f176d86ef67d41ff5921b6162b0eca52359975872430dd14c45643eacdf028d830770714c033fd150669705851b2f02de932322d271d565d26768530c3f6cb84f0b3356f970b9070b26c050ead0417152c324c8ffe266d4e8b5b7bef3a\nA = 1114eb9f1a9d5947eb1399e57f5c980833489685023ed2fe537fe1276c1e026b9a19e6fff55aa889d6c4e977b6e6f3111e2ad463138637b50f42cf32e57d83f282de9e72f813e5969195159a666d74dcd689bd527c60199ae327f7bd548ac36868fea5fdf6f35d19b921e7c10b6448ca480de6826478cd0642d72f05af3f8e65ce42409fbd49f56e81946e89c8e83962c4edc0ed54600600a305e52d081aed3c351e450e11f8fb0ce5754c92cf765b71393b2b7a89c95df79b9ea1b3cb600862\nB = 1d8f3179ca7b5cc7119360c10de939ffa57c9043da2f2b0ca3009c9bdad9f19ed16e3c2c197bef4b527fa1bf2bbab98b77e26c329911db68bd63d3d0fbfc727a977395b9ad067106de3094d68e097830858c5ccfa505fc25e972bdee6f347e7d1163efacd3d29a791ec2a94ffeed467884ae04896efc5e7e5f43d8d76c147e3c9951a1999173bc4e5767d51268b92cc68487ba1295372143b538711e0a62bf0ac111cc750ca4dd6c318c9cbe106d7fc492261404b86a1ba728e2d25b1976dc42\nLCM = f9570211f694141bfb096560551080cbe02a80271b4505591aaea9e3b99ea1d5ac1c1f2378fd72799e117ac2a73381b1ad26314e39972164d93971479ee3ba21a4d98cef0bd299d540ce5826995dcee0de420dff73d30b23cbf3188c625c7696df517535bc5675d71faa00807efbebdca547933f4a37849d1c014484a77da6df0670c4974bcc91eb5f5fe5faf9dd095ef195ec32ad9eeebf0e63288b4032ed9e70b888afc642f4ff96f0b4c0a68787301c12e4527fe79bdfe72dd3844ab5e094a9295df6616f24d1b9eeebc2116177dacf91969dda73667bc421ef3ccd8d5c23dddc283f5d36568d31f2654926be67f78e181075bdc148f2b39c630b141ae8a\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 0\nB = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nLCM = 0\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nB = 0\nLCM = 0\n\nGCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nA = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nB = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\nLCM = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423\n\nGCD = 2\nA = 14e95a85e59ade9ef39e2f400c65db18702fa5fc485b9bba479a5282b2206129160e54f73ef4917983c17b4c5ebff7be112a886de069706eee29ba902515cb038\nB = ddcfff1d39c90c599f55495bf71c1e7597c6b08b7430707f360c6a6e5137bbc7b403c6d9e2c34f3d2f29d5d32b869346853c2de239cc35381bdfb4a01569211a\nLCM = 90f38564ee72e55d362c04599e7d74f068c75f541b84e97abba2841f1a9f66b06b5c9009f6a4c2e319fced85270588de03ccebddbd9279aaecb13bdc1dbea7f42acaee751cb7da83779b8785cc86f41b94b13b54964208ca287d981634778d1096f20e76ca636c0717fd27e0800c43f599a5eded807421b502eaf9990a8c8ed8\n\nGCD = 4\nA = 3c719c1c363cdeb7b57c2aabb71f425da4c3e6d3e447204d555e7cf0f3d372bdda906f36078045044978dafc20171767c8b1464d52dfdf3e2ba8a4906da033a8\nB = 30fe0ef151ac51404e128c064d836b191921769dc02d9b09889ed40eb68d15bfdd2edea33580a1a4d7dcee918fefd5c776cbe80ca6131aa080d3989b5e77e1b24\nLCM = 2e4526157bbd765b0486d90bcd4728f890bc6dbd9a855c67ca5cb2d6b48f8e74e1d99485999e04b193afca58dbf282610185d6c0272007744ff26e00dbdc813929b47940b137dc56ba974da07d54a1c50ec4a5c2b26e83f47cf17f4ccce8c3687e8d1e91d7c491a599f3d057c73473723ce9eee52c20fe8ae1595447552a7ee8\n\nGCD = 10\nA = 44e04071d09119ea9783a53df35de4a989200133bb20280fdca6003d3ca63fdd9350ad1a1673d444d2f7c7be639824681643ec4f77535c626bd3ee8fa100e0bb0\nB = ca927a5a3124ce89accd6ac41a8441d352a5d42feb7f62687a5ebc0e181cc2679888ecc2d38516bdc3b3443550efccac81e53044ae9341ecace2598fe5ce67780\nLCM = 36805ba9b2412a0cb3fe4ed9bdabfa55515c9d615a3d0af268c45c5f6098d2de4a583f3791f1e3883c55d51ce23c5658fd0e8faa9a3709a1cfbd6a61dbab861690f27c86664f084c86cfd4a183b24aaadf59a6f8cbec04f1b0ded8a59b188cb46ae920052e3e099a570540dbc00f7d4a571eef08aa70d2d189a1804bf04e94a80\n\nGCD = 100\nA = 73725032b214a677687c811031555b0c51c1703f10d59b97a4d732b7feaec5726cb3882193419d3f057583b2bc02b297d76bb689977936febaae92638fdfc46a00\nB = 979f4c10f4dc60ad15068cedd62ff0ab293aeaa1d6935763aed41fe3e445de2e366e8661eadf345201529310f4b805c5800b99f351fddab95d7f313e3bb429d900\nLCM = 4460439b4be72f533e9c7232f7e99c48328b457969364c951868ceab56cb2cbbeda8be2e8e3cae45c0758048468b841fdb246b2086d19b59d17b389333166ab82ed785860620d53c44f7aaaff4625ee70fb8072df10fb4d1acb142eadc02978ff2bb07cea9f434e35424b3323a7bda3a1a57aa60c75e49ebb2f59fb653aa77da00\n\nGCD = 100000000\nA = f8b4f19e09f5862d79fb2931c4d616a1b8e0dd44781ca52902c8035166c8fca52d33a56ff484c365ec1257de7fa8ed2786163cfc051d5223b4aad859a049e8ba00000000\nB = 6e54cb41b454b080e68a2c3dd0fa79f516eb80239af2be8250ca9cd377ba501aabafc09146fad4402bdc7a49f2c3eec815e25f4c0a223f58e36709eefd92410500000000\nLCM = 6b3020a880ddeff9d17d3dc234da8771962de3322cd15ba7b1e4b1dd4a6a2a802a16c49653865c6fdf6c207cbe0940f8d81ef4cb0e159385fd709d515ee99d109ad9ad680031cbae4eab2ed62944babdade4e3036426b18920022f737897c7d751dce98d626cdda761fec48ad87a377fb70f97a0a15aa3d10d865785719cc5a200000000\n", + "00000000000000000000000000000000\nA = ffffffffe00000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffffc00000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffff800000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffff000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffe000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffffc000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffff8000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffff0000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffe0000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffffc0000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffff80000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffff00000000000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffe00000000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffffc00000000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffff800000000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffff000000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffe000000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffffc000000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffff8000000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffff0000000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffe0000000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fffc0000000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fff80000000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fff00000000000000000000000000000000000000000000000\nB = 100000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffe00000000000000000000000000000000000000000000000\nB = 200000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ffc00000000000000000000000000000000000000000000000\nB = 400000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ff800000000000000000000000000000000000000000000000\nB = 800000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = ff000000000000000000000000000000000000000000000000\nB = 1000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fe000000000000000000000000000000000000000000000000\nB = 2000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = fc000000000000000000000000000000000000000000000000\nB = 4000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = f8000000000000000000000000000000000000000000000000\nB = 8000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = f0000000000000000000000000000000000000000000000000\nB = 10000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = e0000000000000000000000000000000000000000000000000\nB = 20000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = c0000000000000000000000000000000000000000000000000\nB = 40000000000000000000000000000000000000000000000000\n\nSum = 100000000000000000000000000000000000000000000000000\nA = 80000000000000000000000000000000000000000000000000\nB = 80000000000000000000000000000000000000000000000000\n", }; -static const size_t kLen41 = 18795; +static const size_t kLen48 = 41961; -static const char *kData41[] = { - "# This file contains test vectors for whether B is a Miller-Rabin composite\n# witness for W. W must be odd and B must satisfy 1 <= B <= W-1.\n#\n# The following Python function may be used to check values.\n#\n# def is_miller_rabin_witness(w, b):\n# # Variable names taken from FIPS 186-4 C.3.1 but the algorithm skips a\n# # couple of optimizations in the FIPS formulation.\n# m = w - 1\n# a = 0\n# while m&1 == 0:\n# a += 1\n# m //= 2\n# # b is a composite witness for w iff the following are true:\n# # - b^m != 1 (mod w)\n# # - b^(m*2^j) != -1 (mod w), for 0 <= j < a\n# z = pow(b, m, w)\n# if z == 1:\n# # b^m = 1 (mod w)\n# return False\n# for j in range(a):\n# if z == w-1:\n# # b^(m*2^j) = -1 (mod w)\n# return False\n# z = (z * z) % w\n# # At this point, z is b^(w-1) (mod w). If z is not 1, w has failed the\n# # Fermat test and is composite. If z is 1, the value of z immediately\n# # before it became 1 is a non-trivial root of unity and w is composite.\n# return True\n\n# Exhaustively test a small prime.\n\nResult = PossiblyPrime\nW = 7\nB = 1\n\nResult = PossiblyPrime\nW = 7\nB = 2\n\nResult = PossiblyPrime\nW = 7\nB = 3\n\nResult = PossiblyPrime\nW = 7\nB = 4\n\nResult = PossiblyPrime\nW = 7\nB = 5\n\nResult = PossiblyPrime\nW = 7\nB = 6\n\n\n# Random large inputs which try to cover a few cases. The nontrivial square root\n# case appears to be difficult to hit randomly.\n\n# b^m = w-1\nResult = PossiblyPrime\nW = d6b4ffc7cf70b2a2fc5d6023015875504d40e3dcce7c2e6b762c3de7bb806a5074144e7054198dabf53d23108679ccc541d5a99efeb1d1abaf89e0dbcead2a8b\nB = fabbafdbec6494ddb5ea4bf458536e87082369b0e53a200ed413f3e64b2fddc7c57c565710fbe73fae5b188fce97d8dcca74c2b5d90906c96d3c2c358a735cd\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 52cc61c42b341ad56dc11495e7cb2fe31e506b9e99522efbf44cd7c28468d3833c5e360f3c77b0aa43c0495c4e14665ab0d7cee9294c722f0de47d4401828401\nB = 3bdc9639c0fc2e77ab48d46e0b4ac6529c11c900e8fe4d82d75767c0556feb23d3f42d4924d16876a743feb386b7b84c7fd16a6c252f662faf0024d19972e62f\n\n# b^m = w-1\nResult = PossiblyPrime\nW = cff9897aa7dce0f2afad262b2de57d301305de717f3539c537c4ce062f8cb70df13fbc1eb4a3b9f0958a8810d1ca9042b4f23334b285a15fee3fc66498761d4b\nB = 9ceb43132fddf9ee4104ea1cb3eb2253c1d7f803f05f0305de9e31a17dd75832f47b8bf189a9b7ca0905f2a7470d9c6349080f481ff1708696fa12d972e7d7ba\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 67d1825dad5344170e65247a87aef1634a1b32bdc22f2f04d9d2959767bb5a27610fba55cd607e0f9fdd9fbb0f7f98e40d5e1eb2f52318fb5be4dbfd30d38861\nB = 260fb14724ff80984736859d8755ee98b25bcb56db9fde1db001a1e1273374034c5b75fd60b3710c7a08ce7d390776f010f384d4e32943cf0c477497d53e9e05\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = ad0bc85b58aaa204177aa9431a40929beb1cbea2dd6f66a25cc54600013213b225ba881805661df43f4208965ada7aacc8095d07d3cbef1a7bbfaae8b745f731\nB = 3d9310f20e9c80269fa6830c7e1a6f02fc5c58646001a9ef6b8b3e496602ff22c3dcb2ddb6a221723fc1722ce237fb46f7a7bb2945e415c8839b15a972f076c9\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = b25c917f55f6c7b596921daba919f35039e5d805119c1587e99849dd7104460c86214f162a6f17aea847bc7f3859e59f2991d457059511972ef373d4bc75e309\nB = a1f10b261dee84619b0423201d46af19eef9ec0612cf947c4d5c36c0c4b28207f75967e69452eabad0a5dcd28f27f7a8a7ed9c8b3e5026c6e0ba5634d94c2d44\n\n# b^m = 1\nResult = PossiblyPrime\nW = d3eeb0eff05b6992e9fa61b02755e155f4aae28c6e45ddb874edd86acdd2d83d18a20e0e00d8b8bc94b92d14fc3f41ced6ababe8ac98c7730c075dbe0f699369\nB = 6b7717269c6225203681a1cacec87cacd83003ec6e9e3f04effcc4f86634770c0860e1f2770b8f303719a44949664a1094205a99d95a0856758fed66d690105e\n\n# b^m = 1\nResult = PossiblyPrime\nW = 64561b8d9aa50340c3a01ccb3e6e17f5023513661c012be288f3900a3ca76890e67290b9560fa1d480f9d2aacccca581b5690636665f243fa13aff5d0bff12d3\nB = 1f5ff70d3d60671ebc5fbfca731898a04438053dbc3c841e6335f487e457d92d9efb5d506d5bef6872d58d12b9a41c950bfc38d12ed977c90eacdd6535b811a0\n\n# b^m = 1\nResult = PossiblyPrime\nW = 69c63fbf44df21b0ed0ee929a740c12d1f3f064da0dcd9d509f31fa45fa27d1a759ab5a9f6f1040d7ee90a0b1e68f779273c41ea1c1198fd547ff6bd70c7e787\nB = 5f7996a9bbfd8fd88e472220b70077bfdacdd63d88885134431f024c2acb7126827b174eb093eb5313f07bb5461de9b0feb7d77ca2c39c2a323a150f33ea525f\n\n# End of iteration\nResult = Composite\nW = 28cc3e08c44571c6dcb98a9ab8b4f3e2b16e1f884997d94a3188bcbb7f1b7cdaecdae8329c013ec8f75dc00004da0039943e4262cd080b16a42910102e00dddb\nB = 512061ab1c69931c2fa0bb89d8d09f3c9209230bf927ddd6fb6a72075f967ed3c4dbb5f437bf4d31ca7344782b22011ad56609dc19aed65319bababfc13dd7\n\n# End of iteration\nResult = Composite\nW = 4eeb7b4d371c45fe8586fee3b1efd792176b70f6cc2698dfa1dd028366626febe0199c3c5f77a5c3cad0057a04767383051d41965255d03681b2a37edad34a9b\nB = 4afc2e85f84017b3fd6967a227eb74c8297b40ea02733d9513bff9b3f01081963f25872f4254afc4e9321eea35b2a1e42eadb186fcc84f2f30f4a994350b93b8\n\n# End of iteration\nResult = Composite\nW = 8e35a959555dd2eb66c65cee3c264071d20671f159e1f9896f1d0ceb041905fcf053eacc189de317c3ee6f93901223cbf30d5b7ddbbdab981790e2f6397e6803\nB = 44c0153759309ec4e5b1e59d57c1b126545ef7ea302b6e43561df4d16068b922389d6924f01c945d9080d1f93a0732599bdedae72d6d590839dc0884dd860441\n\n\n# 0x6c1 = 1729 = 7 * 13 * 19 is a Fermat pseudoprime.\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = b8\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 111\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 11d\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 19c\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 223\n\n# End of iteration\nResult = Composite\nW = 6c1\nB = 3aa\n\n# Found non-trivial square root\nResult = Composite\nW = 6c1\nB = 653\n\n\n# 1729 has a number of false witnesses.\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 78\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = eb\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 178\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 178\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 6c1\nB = 1aa\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 271\n\n# b^m = 1\nResult = PossiblyPrime\nW = 6c1\nB = 2b2\n\n\n# 1 and W-1 are always nonwitnesses.\nResult = PossiblyPrime\nW = 6c1\nB = 1\n\nResult = PossiblyPrime\nW = 6c1\nB = 6c0\n\n\n# https://kconrad.math.uconn.edu/blurbs/ugradnumthy/millerrabin.pdf, examples\n# 3.1 and 3.2 has a complete list of false witnesses for 65 = 0x41 and\n# 85 = 0x55.\n\n# b^m = 1\nResult = PossiblyPrime\nW = 41\nB = 1\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 8\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 12\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 2f\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 41\nB = 39\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 41\nB = 40\n\n# b^m = 1\nResult = PossiblyPrime\nW = 55\nB = 1\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = d\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 26\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 2f\n\n# Some b^(m*2^j) = w-1\nResult = PossiblyPrime\nW = 55\nB = 48\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 55\nB = 54\n\n# Other witnesses for 65 and 85 will report composite:\n\n# Found non-trivial square root\nResult = Composite\nW = 41\nB = 2c\n\n# End of iteration\nResult = Composite\nW = 41\nB = 16\n\n# End of iteration\nResult = Composite\nW = 41\nB = 14\n\n# End of iteration\nResult = Composite\nW = 41\nB = 2\n\n# End of iteration\nResult = Composite\nW = 41\nB = 3a\n\n# End of iteration\nResult = Composite\nW = 55\nB = 40\n\n# End of iteration\nResult = Composite\nW = 55\nB = 7\n\n# End of iteration\nResult = Composite\nW = 55\nB = 23\n\n# End of iteration\nResult = Composite\nW = 55\nB = 2e\n\n# End of iteration\nResult = Composite\nW = 55\nB = 2a\n\n# W below is composite, but it is one of the worst case scenarios for\n# Miller-Rabin, from Wycheproof tests. 1/4 of witnesses report the value is\n# prime. Test that we correctly classify false and true witnesses.\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 379c6027f818b5164bc13dff", - "5e996ec7210976f33570d5c60275918b8988d97a63bb6582af85682c45667a8b94b7acab4d919ede00f5bd2ba7abc8634d66f8875fd930f35ec8013d37b958e65f07de015c0574e64198d73aab5466f3a971b74830b7f1671cb9277fbc95c1ba8c29dc903d8cea1b74c22ab9164f9c438ab9ba7d9919f832e40c3e36faca7343e2314669b0104d9c4f2e1b011cdbd9c686baef0\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 3cc4b644965b2133caffc2bb6258b1ecd5b586b900a09b010382fcef709e4cd37ee3e3182bf8d393c1ab6f9a933d46338b3d960923d8c9607c2b2763d5680230a2bc0c91138e9d0ecb35e7154a06aaa902d34b9b14964b81f4d8232641492d83b22cd805a115e75ddd8e63b864c00e4c90ba36a41e7966e97e063a60a6a6cfd53e1f62a57852c7443e88dcf6245557a4b65494c3e88e466ad75316aaa9727def\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 40c03b6ba22bd62c0379b1c36dfccd34d61e3d15f7af1d5f6a60ab972a9d0e956e2bb9e275294e0f1c879eb7a4555443429c99a8d74f7bd359a1046ac30072c04b0e2cbd005be15ff4ce0c93276de2c513fbc5771b5059904a87f180530f6773498114b5aaf70da01967d8294742e451df6377dd5e64b2a8968f4ba61b51a154317d63958ff3788defbeeebee21af5027c2291e8c5df8c0b66770d91b683cffe\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 3c7c71b84f0c6c3817f57511946315cec7d0120a9c30ceabda801fbaec329a8f10c7b9f0ae90a3dada9885bf73a3cabed86784af9682f3dea50a7817f65cfc9190cf997f12784223c4965ed6e52a1be26d4dde31741cd3d1a2e2f3a74040d0f3868eef849727aa855f66c94791194ad5d360298364e2de9ca9288e6423f644b01d52e1bd66a9f7f00bd7995a9ca2ed16f40e902852c6250a3b52bbbf5bfd33e8\n\n# b^m = w-1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 36e6aa9acb399a50f52be0324dcef05f3cff3117f94538f6d0952b7d7be88ba4dc75d843ff7ff775e11f55c86ba6b2a6ddebd8850c33424b4d35c66321af426662e7074f0a2409a9ccf1c66ef7d823efc8240b8f3c7e9e8dd65a64e8a3ca5b26695ef17171ffe136c0593b179414c5b5ad0d66f2a25146c38b2f97e60b0472ed72de34bff1b6ac186f23645a1bbe909cdfc2b2d861eb44931568f1bb117d8a0c\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 278f2215d3ab836043fbfa472216bbdcedb775a6a0ed711754d05aa75089a9e5d8201e113d68656f37381e44483cd365f5d383bdca5ae8d1f2e6575d7873851cfff0e12b1cfe100a04cb300cbd924353fcbd3307d01242cf6a5e86e752c6f4586bcabf48b018bb97e65c3ed409fd6f67f98987517356d88344b3c8945ccd753148a37b648dd2db44d19522a69a9ad8eb23edc55340e85a198abf179ad731db41\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = afa1478bebbfe1157568f4ae53549b4c3a6a8771b816970bfac6ce5c8b962231db7a41da4d5f1d8bf504dcfe440325b54e1888bdae344eb969436a35e5c6ce5300d46313cb2fcb57fc83305f65f53d392de400e9231cbbc2ac8243defcaf7063c632b9601a81d83138274702ff336d727d3e82ccacce069843ac9c1c590c772c8c586b65c7085a1df5a47fc960d4098a22418b41f0062c77b5d55d17149d167\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 10f7030590b629e0313a61bdf46936a1f25db91b2b421f7ebb671f7844c22561b44b2f7699db61e5228ebb5817afad416325f9439eff7a82d8a630c504de12eaa44d97c79ee56e726ae74ee0b472f0d5fa8f20aee426e689cd33dd084f96bf4d928a21e815f7e8aaca4a5752f39c4a76bdfaa8227dc05d0dfa885d8b26d46fbcbf0d2e0d999d2c31ad84c306c9126539dbdf447f8dc707d29c7fa8021a767668\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 97dbb6a55c039ec926aaa5ff15a2917a2b4cafc3ca07c4c6b05f931d86c9bf60ee05cbbace194e5ca97682ec67c36394018d68c3536fbf13b50f8a7e31eaed87307759a0a48c6c58d21bc7c38b878c53db5d7a8e1fdd81abefc50470a3800852e74d76fdd1933e45f39ee97b8efb68837721890d867b32a894dd0ceb4c5844a05d384145865c10973ce748ccdd8fee73f1bf8611ce0535430b6b98fb36cad7a\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 225f58add44ed2b0a64a1d8452866d0f3c0cd45c8375e1bb33c188915c77fa11b81250b920245dda7f6126e5e0c79e6f98f89dc15db86394cf81b44f0d801e613fa4d5c6fef66fa31f26cfe6153f2e8159aad6b0351dcc0e93f9a68f649b2a77cff747b605b542d22419166befebec6cde3201e3c0cacaa2bc9d87073b8d1f1aa2b114d61de45ac8b0ad2141b43434a629ef284cd999fd82b310db7c57cf5c81\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 2780926c9cf7c1eb2aaa935d90b6d4dea44eeefdfcf9ccd4a33feb215e3a1cb2d358136a490fed18403947f3d98807819737c66e12d42c3cc8c0e246b96b3c3b0795ab875fbaf668b81b5b05bf23e258ea00a0a140a790f76e04ab619800b7597f614ffc1a1c94be2f3f1a71d64eb47d98e4653d76eabedacff3a97ecf590e6a1fd55096b7bc9314629f698d0fbe9b01a1f2bc0bf3a2c097f99f1fd222b52ed2\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 129cc5b0d9f8001b3895f1fcb4833779763636aeeeb3f980e63ea506202e6bde868444b6a58ff1dca08625f025a7e95a5eaaf1a8899eee640e3f05fbdb2867e2483bdc27c87b58684416e521c107f3667ed8dd23f0381edab767c5205a4378118bc011947cb6bdfe3fa4af50b8de876b555c9a0b2b0dae01261847f63e1e0cac2d032530bf19d5da60a04dfe22ce6343f60defbb94ccf0bdf010f89a4029720\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d", - "9a6cdcf912a2dd0a12ba7e87\nB = 4e2a47cf67c3331b1e9976f583f6339cf76a8d48682d01355c25b2aed90c5544e737ecfa849c17d27a64fad7e659ef48df9a3ac0410e5c7ca8d087fc3a3ba23e5a3f000be009fcc8227ead28158c5b5d66f2efb47111638ef61cea4984de42fbd476bc2236ad02154d3ce85805c45e49d16b496e313a4052a37d4b88a3b13e598d2074a3e36a37e90278601f2b2305e034f9bf3aea8e939c3ba274e8ff4d8a14\n\n# b^m = 1\nResult = PossiblyPrime\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 2455c4ab826e2ae72708a8ff51348ce4821cb86fa89e298c751c1754211c63b2e9a712d40f0235f310606fcf296726a86973f19f890d571f5b90f026e8d24d07bc0478a3c1333171587387f1f7fe4a770b593216f2743318aabacb3320c40a4e52b9f409e1176fe8db099e93a7991eb8568168e2e486fa5aa228bb1dce9df3290ef13fd21c331479bb0f8b7a7e7f03c5211ae8cc46fa4d0f46e86b2dadeddd5b\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 9951c2c02dd7deedce29bd0c78dd80066b1d69c0e6fe4a17f7d03c6a640d866d01fc8214bafb6737efd93d80a35b8993f5367ce287459b07954e9771ffbc72ccdd812d26a9bf4be0292a24eb5c3b56f09619b1c1b481f7566f7e50e65f69f5feb591bd107fec72a783429dbde6e2607f3db2c58d4b070a45b4d6b43537e19942ce890b04ae1e91069c04a96ed03ddb2f4fc456f136b98102c70a15700dbd911\n\n# End of iteration\nResult = Composite\nW = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nB = 4cb8217d229d5f95f6d94807a99363823655d6bba6bdafa4f0dbfe7a5c538aa79c918710aad4f55caaee5ab405ebdcef29dfb76cae99fca8d5a955b6315f71a3cb2d69a217ff45aed66ba87cdc5c0de5d512c6dd12e641e9fe6a2557dd2f03bf3a18650ff139efa179f0fbe69cbb4b54e50d13177bfe7bb90de36b548d5ccfef74b05d3c08a7e2a3bb4dc8d7eb338a7a1b068c433ea204d171eda5e7c6b6722c\n", +static const char *kData48[] = { + "# This file has been modified to remove the 65536-byte long inputs.\r\n\r\n# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = TDES KeySize = 3 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:47 2011\r\n\r\n\r\nCount = 0\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 3bb96170d5df4cce\r\nKey2 = 25d5daa22a982f08\r\nKey3 = 52f4a110dcdc9e45\r\nMsg = 00\r\nMac = 96\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 1\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 9413d38685688f58\r\nKey2 = dc38b6b3cef125f1\r\nKey3 = 5b61f4f7a1c46ed6\r\nMsg = 00\r\nMac = fc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 2\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 101a2f13fbb69473\r\nKey2 = 76fb98f24073f4d5\r\nKey3 = 2ca2706d76d00b67\r\nMsg = 00\r\nMac = 53\r\nResult = P\r\n\r\nCount = 3\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 2f8a238552c1e367\r\nKey2 = f8131f1c26ab3289\r\nKey3 = 83d5b6ba253bea31\r\nMsg = 00\r\nMac = 95\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 4\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c1bafb5dc7100758\r\nKey2 = e9ef047a58b5ba89\r\nKey3 = 76cb4fb55ebcc1c7\r\nMsg = 00\r\nMac = f4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 5\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c82c29f1cb5851b6\r\nKey2 = 8b5b45dcbf0d8079\r\nKey3 = e6407057ae34ec0b\r\nMsg = 00\r\nMac = 03\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 6\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 6b455116f4f883d5\r\nKey2 = a81a206d25152aab\r\nKey3 = 86dc07b607202abc\r\nMsg = 00\r\nMac = 75\r\nResult = P\r\n\r\nCount = 7\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = c873d5bc4598d0b0\r\nKey2 = 1c1523cb4f794c8a\r\nKey3 = cedf6797d523dcab\r\nMsg = 00\r\nMac = 2e\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 8\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 45ce943bd31fe9b5\r\nKey2 = 677cc47c13c24923\r\nKey3 = 6b2086f14934838a\r\nMsg = 00\r\nMac = 01\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 9\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 804f9ef7baf7dfc7\r\nKey2 = 9bb6494cb60b8c07\r\nKey3 = 2080fe52e0d3943d\r\nMsg = 00\r\nMac = c3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 10\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 73c10b833e1043ab\r\nKey2 = 16dcd343645d5207\r\nKey3 = 6426f7f88c3473c8\r\nMsg = 00\r\nMac = 8b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 11\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 310d54d96bc73452\r\nKey2 = bae34f158ceafb04\r\nKey3 = 4651c1b53de3da26\r\nMsg = 00\r\nMac = ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 12\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 0e3d49d0e692f20e\r\nKey2 = a9cd384a3b688c0e\r\nKey3 = 584ae5f794f8fe7f\r\nMsg = 00\r\nMac = 4b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 13\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = b0fda857ea402f0b\r\nKey2 = d567e9f48568f1e0\r\nKey3 = 0ec2ad452a547a91\r\nMsg = 00\r\nMac = 04\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 1ac1543b1591f270\r\nKey2 = dcda0e9870b9d949\r\nKey3 = 68ea9b1c4380ae9e\r\nMsg = 00\r\nMac = 43\r\nResult = P\r\n\r\nCount = 15\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = d0b008aea4454551\r\nKey2 = 9234a7731ab610b5\r\nKey3 = 2fb97a8ffbaedae6\r\nMsg = 00\r\nMac = 4c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 16\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 04793b0b0e976d0b\r\nKey2 = bf493e58fb73681f\r\nKey3 = 1f54a262d649b985\r\nMsg = 00\r\nMac = 77\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 17\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = 043b759b578ae570\r\nKey2 = 5e522f19cb9de092\r\nKey3 = 2af2e90eb6dcc1fd\r\nMsg = 00\r\nMac = 77\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 18\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = e58520088910513d\r\nKey2 = 7c10196e1a310dd5\r\nKey3 = 5b043b2a1ab97f85\r\nMsg = 00\r\nMac = 1c\r\nResult = P\r\n\r\nCount = 19\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 1\r\nKey1 = f27fd0f189452c15\r\nKey2 = 04681651014916ab\r\nKey3 = 204046aeeffecd15\r\nMsg = 00\r\nMac = 0b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 20\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 860864a710ab0475\r\nKey2 = b9205751bfd91f7f\r\nKey3 = 3bf72abf13d97640\r\nMsg = 00\r\nMac = e890abe6ea126215\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 21\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = a7a1d57aabf1137c\r\nKey2 = fd0df2e35b8cdf2a\r\nKey3 = b386755bc2ab3d9d\r\nMsg = 00\r\nMac = f475587c2101eff2\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 22\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = c2c28a4c7698804c\r\nKey2 = ab25b53783dc0419\r\nKey3 = ab16341f4cead054\r\nMsg = 00\r\nMac = d335575aa3a4d8af\r\nResult = P\r\n\r\nCount = 23\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 7594a7aed3e986ba\r\nKey2 = 52a280e662d9e9da\r\nKey3 = 7649d3ad6838f2c2\r\nMsg = 00\r\nMac = 0e109f43557f250f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 24\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 0798d9ef158cd698\r\nKey2 = fff4ade09b169762\r\nKey3 = 5b6e6849ec2c238a\r\nMsg = 00\r\nMac = 05af623529b168a9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 25\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 254991cb4af76dc8\r\nKey2 = 2cf2e915918a025b\r\nKey3 = 2c61bfaee69b2676\r\nMsg = 00\r\nMac = 725ab7a770762894\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 26\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 9f68cbbf3bb5b3da\r\nKey2 = 31adb5a46e2cc8e3\r\nKey3 = f86ed9eaabb625da\r\nMsg = 00\r\nMac = 0422d94f874dda7e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 27\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 1fd51f70a77ac8e9\r\nKey2 = 5dd9986e974c08ec\r\nKey3 = fd61ce34a75279f7\r\nMsg = 00\r\nMac = a163a5d269b3cc3e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 28\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 078c57d6df9ba1d5\r\nKey2 = 08d94ac1b3d3c183\r\nKey3 = e90bf4fe7973c2c7\r\nMsg = 00\r\nMac = 9af3f01e20dc7c1e\r\nResult = P\r\n\r\nCount = 29\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 08df322f040e7c01\r\nKey2 = e92343e69d83eac7\r\nKey3 = fe94c1ec0da22c1a\r\nMsg = 00\r\nMac = 3d88c20a4f828c5b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 30\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = b2ecf41c8692c2b0\r\nKey2 = 8ff18c1f1f296454\r\nKey3 = 383dcbc4a28c7629\r\nMsg = 00\r\nMac = 17241dc726fa4c56\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 07d99d58f2ec1fd5\r\nKey2 = ea46c73bf4b60ed0\r\nKey3 = f20ec149c831aecb\r\nMsg = 00\r\nMac = f6a8a0b536fd97d3\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 3dfdc19426fbd56d\r\nKey2 = b03b7985b32af857\r\nKey3 = a807c7b3621ffdda\r\nMsg = 00\r\nMac = 3ef9b263ae1df460\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 33\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = fbc79bab46b97923\r\nKey2 = ece6da4c40f1e6e9\r\nKey3 = eaa76770ef517a40\r\nMsg = 00\r\nMac = b2da3efa7fc64abe\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 34\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 5ba4a1d5a80db5ef\r\nKey2 = 7ce6aeb9261cb00b\r\nKey3 = 8a5df23ea445e0c8\r\nMsg = 00\r\nMac = 51b2e75334d90889\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 35\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = e9c494e001027c86\r\nKey2 = c4649e58ea251904\r\nKey3 = 8025343dec34409e\r\nMsg = 00\r\nMac = 166123f1c59132a3\r\nResult = P\r\n\r\nCount = 36\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 6bce61e646452a46\r\nKey2 = 54ba8a020d0876fb\r\nKey3 = 34ea2f6149bad664\r\nMsg = 00\r\nMac = b0d0f625f06f2a3a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 37\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 2f38f79bc8e0ea4a\r\nKey2 = d09876f22ca43e10\r\nKey3 = 3b8fab02299d328c\r\nMsg = 00\r\nMac = b26d377a504b8985\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 38\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 51febf790815f1d0\r\nKey2 = 9152d5e32f6713fb\r\nKey3 = 4a40c2c8fdb9f2b5\r\nMsg = 00\r\nMac = a27978e62026743b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 39\r\nKlen = 3 \r\nMlen = 0\r\nTlen = 8\r\nKey1 = 10ba8fd6256ee9a4\r\nKey2 = fa8332a46ead52ab\r\nKey3 = b0e06e1fef04abb5\r\nMsg = 00\r\nMac = e1b0a228c142555c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 40\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = f2fbab6734769e9b\r\nKey2 = ab45910e5775ab0d\r\nKey3 = 5bd5ea0db015a89e\r\nMsg = 7efeb7d4d14b3f2b3df4b8a276b18b49\r\nMac = 5c\r\nResult = P\r\n\r\nCount = 41\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 5bc776ba64adf4ea\r\nKey2 = 195e04987c62a4f2\r\nKey3 = c1642fdc1a31705d\r\nMsg = d1fb4f35914404af9df3bf5c368c0e69\r\nMac = 4d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 42\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = b67c57f770202c6e\r\nKey2 = e91f4fb361bcae37\r\nKey3 = ada8d3df4fbcf4b9\r\nMsg = 9800db878187c87ea05bf92054b0e3e3\r\nMac = 8b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 43\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ce0bc48002fe7602\r\nKey2 = e702abe31c7a2313\r\nKey3 = d61964867f2579da\r\nMsg = 704e4e75be1623b21332c14555bf5edc\r\nMac = b0\r\nResult = F (2 - Key or Key2 changed", + ")\r\n\r\nCount = 44\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ad75e32cc11980f2\r\nKey2 = d0570429680e9486\r\nKey3 = c2379207f862dcfd\r\nMsg = 197de855b3962b1fdad687f9c4f1efd6\r\nMac = 44\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 45\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 9db504803d29f126\r\nKey2 = 07fe58b3da765bad\r\nKey3 = 6dc489516e9bb5f8\r\nMsg = 8f296b265fa575d146799f9e39d52965\r\nMac = 14\r\nResult = P\r\n\r\nCount = 46\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 991f0ed04079293d\r\nKey2 = 57077ff1baecd907\r\nKey3 = dcc7a719c4372967\r\nMsg = d9cfcc67520c5b2ceeb622c694a8e3fe\r\nMac = a3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 47\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = eca815d6b0371cf1\r\nKey2 = 597980cdb6c892df\r\nKey3 = 3dba0ed3ba16ae1c\r\nMsg = a03636db2fdc84722aeb9d98a6ed70d0\r\nMac = 78\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 48\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = ea80a43d5886dfef\r\nKey2 = 08bf4f76a8893732\r\nKey3 = 4557a13752d6730d\r\nMsg = 0371a63ad722523ef297d8399b124593\r\nMac = be\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 49\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = e9fe73e640808c02\r\nKey2 = 9be6986446012091\r\nKey3 = 707023615462a40e\r\nMsg = 83bcb484dca73d49ac234ece3a5d2ad3\r\nMac = d6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 50\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 1fe9800ecb0dd9f1\r\nKey2 = dbbc6bc72c794c23\r\nKey3 = 899b08469b6bc8b5\r\nMsg = 95f4a41c4c64cd7310fba748aa267a14\r\nMac = 59\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 51\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 34546261a21c1c43\r\nKey2 = 0449eaeca4f29725\r\nKey3 = 4cc4e6525186802f\r\nMsg = d204de1e671d3e43670dd67fee114402\r\nMac = 6e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 52\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 048aa8701fb5fe26\r\nKey2 = d56bd53d83e60bd9\r\nKey3 = 6707d6523ebc32f4\r\nMsg = f4e9f92fd2c9313fb61a889eaa4ff283\r\nMac = d5\r\nResult = P\r\n\r\nCount = 53\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 6ec19b02976e5ba2\r\nKey2 = 13540732d997c2b6\r\nKey3 = 7f4068926183251c\r\nMsg = 963363ab7c82b634974954bd0fe2c307\r\nMac = d7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 54\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = f4ecea5d32e32c6e\r\nKey2 = 385710cd3eb0fe51\r\nKey3 = 5d4c8f7ccdf10154\r\nMsg = a298857dc60ad2f0a8fa878607b50c18\r\nMac = 4c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 55\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = b31ff49dd970f8e9\r\nKey2 = 164aefb00efb5461\r\nKey3 = 981629757f4532dc\r\nMsg = fc3957b2ed0558bce61d478be615b774\r\nMac = 90\r\nResult = P\r\n\r\nCount = 56\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 85384543d3aef157\r\nKey2 = 57ea916d9b2fd0c8\r\nKey3 = 1a85830473fbe6c4\r\nMsg = 87db0d9d69bc0cf69cabeb92570e482b\r\nMac = 53\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 57\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 9bf8fb0b464070f8\r\nKey2 = 10ea23c7e5a19bcb\r\nKey3 = 408c236e10863e2a\r\nMsg = f9c98cd8a7d27553da946427b8276349\r\nMac = 53\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 58\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = 91b083e9c8e9803b\r\nKey2 = 76d0341cd54c38e5\r\nKey3 = 07bca7f44a3e76bc\r\nMsg = 7e5b64dc6bcbae6bb4496fc033947343\r\nMac = de\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 1\r\nKey1 = e6795b1ffe8f3e38\r\nKey2 = 4fdcea8c73c76e75\r\nKey3 = df0726ae4c079461\r\nMsg = 5265fb6a796d99a6beec6f71ba267b5d\r\nMac = e0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 60\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 375710c76202bff1\r\nKey2 = 3bb96170d5df4cce\r\nKey3 = 23d5daa22a982f08\r\nMsg = 52f5a110dddc9f44f8a534eef9df0b22\r\nMac = b1b9e11939228900\r\nResult = P\r\n\r\nCount = 61\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b59b855dce76adf4\r\nKey2 = be9bae10fe34fb1c\r\nKey3 = 0d49159bf804a4ea\r\nMsg = 869f3b62ee78bfeb5287168eacf69ccb\r\nMac = 169a389352793c8b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 62\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 615d792a7038fd89\r\nKey2 = 98ce972f016e75a8\r\nKey3 = c470255783b32f01\r\nMsg = e5aed6715aa4291f9c32baf6b8449b53\r\nMac = 73ac2da999bfdf5d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 63\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 1fb09443a1074564\r\nKey2 = 3d1aa82c086eba13\r\nKey3 = c137d0f4ea54d604\r\nMsg = 16f02efd285381d7657ca5cd99d9e25b\r\nMac = 38126d16957893ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 64\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 2e5d163461fea761\r\nKey2 = 9173bf75372fb640\r\nKey3 = 9e3d1c3dcdbfbc31\r\nMsg = b10fcb03443302ae929ff95a17b025fa\r\nMac = b70f2d761ca643c9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b9e5861c1c4013d3\r\nKey2 = d554806efd3801a1\r\nKey3 = 64d9bc3d646e76dc\r\nMsg = 0e6c9fced82669cffe7b5a6f09dceec8\r\nMac = 78ce4635e486635a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 66\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = ad2376516b974c70\r\nKey2 = cd3b5870c2312929\r\nKey3 = 1a731a7feacbf783\r\nMsg = 88eb7a0379da9d113343dc1fe0f3e6f7\r\nMac = 0c949483e7fa7d0c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 67\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 9ada194c100eeacb\r\nKey2 = da23ad9825c194d0\r\nKey3 = 3ef1f4c438dce031\r\nMsg = 0f9703a3454c25c0b1053de62b0ffc5b\r\nMac = c78a4ca3662527e5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 68\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = e375f870f4d55b02\r\nKey2 = 1b015791e3e337b3\r\nKey3 = 370dc45b15671c5b\r\nMsg = 5ad9dd3b112ea4cee1654d2dfabab01e\r\nMac = 22becbbe7bfcade5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = d61f4aeff4b5f2f8\r\nKey2 = 0486b53de3ecc297\r\nKey3 = 807fe92fc2fed376\r\nMsg = d094cf77a709c0fa5d6b4b7e9e86a2c2\r\nMac = 947d024d9d5359a8\r\nResult = P\r\n\r\nCount = 70\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c2c28a4c7698804c\r\nKey2 = ab25b53783dc0419\r\nKey3 = ab16341f4cead054\r\nMsg = 7295a7aed3e987baef19ad68c33ba5a5\r\nMac = 58de82acc10d556f\r\nResult = P\r\n\r\nCount = 71\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = f1ce4992c851e3a8\r\nKey2 = 835ec1abef97f2c8\r\nKey3 = 5b92384f20dcc2ad\r\nMsg = 9094935fcd7c389dd17b5b121cddadf9\r\nMac = 319c70370c172de3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 72\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c16ebcc1165d6892\r\nKey2 = 75268c4602f8c8bf\r\nKey3 = dab97f79544cf1cd\r\nMsg = b7ba1c66282cb6092ba601407ff9578a\r\nMac = d73c26311bd44a32\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 73\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = fe4a796720a46dbc\r\nKey2 = 98f45289e9f8b080\r\nKey3 = e05def5b25520d43\r\nMsg = 31c9eed491bb0cda9b8c0eb5afa31019\r\nMac = 8c2ce22633c62751\r\nResult = F (1 - Message changed)\r\n\r\nCount = 74\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = eefb40c715c4546d\r\nKey2 = 5b2325c8d9daa48a\r\nKey3 = d5ec4a6bc82a7a62\r\nMsg = 5a97259dfa081f040d3893da2f231ca3\r\nMac = a64113544f509be8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 75\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 0d0851311ca45db0\r\nKey2 = 3d7c458957c8c408\r\nKey3 = 98d37c9d51ab2f25\r\nMsg = 8be16380af3e2dbc6cf678c2e3331335\r\nMac = 8817baeaa909e33a\r\nResult = P\r\n\r\nCount = 76\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = b7239438d61cd626\r\nKey2 = 082c6404cb3897b5\r\nKey3 = c4c732cdd5e043c2\r\nMsg = 7120f19169e7cbb913c7d1f0ceb006c0\r\nMac = 32841ad7621cc0fc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 77\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 73f449ef83df75e9\r\nKey2 = 5f3d2016bfd0703b\r\nKey3 = 31abc16b58b64af4\r\nMsg = 83ecbfcff3bc37f1305d83bc0290350c\r\nMac = 8f8ba8bfc74203fa\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 78\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = 9b6ea461c7b9abe6\r\nKey2 = 4a08dcdc5b9e01fe\r\nKey3 = 6b850e9b6ebae9d6\r\nMsg = c538416fba487fac5c94449d0757f3e9\r\nMac = c13f372e9a061db8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 79\r\nKlen = 3 \r\nMlen = 16\r\nTlen = 8\r\nKey1 = c7aeeacb156dfbfb\r\nKey2 = ba43ef516232a7d3\r\nKey3 = 2c572aea62808c68\r\nMsg = a1bc9950759d0df4cffaf29345dfb340\r\nMac = d7dad4519b56a1eb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 80\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = cda4d34370234946\r\nKey2 = c408ea6bec07c78c\r\nKey3 = 19eff7f798fd6808\r\nMsg = d1fb0b68176269cf9fda18bf13efc054f0c24fd042b9e2ecaf75e86cb60484f6\r\nMac = d8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 81\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 02100be5627686a8\r\nKey2 = 7f0b38ec073e75ef\r\nKey3 = 373b1a64ba5416d9\r\nMsg = c60be37fb0bda4f46894690b3344643c772fbd2237db348adaa407ca2eae1654\r\nMac = fb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 82\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 7597571a6e7c6bc8\r\nKey2 = c143a2a461626b1a\r\nKey3 = 6b1307d910434cc7\r\nMsg = 49cb128641f7952dfdf34f338da268b2ef1482557b593e", + "c57f930164264ff83e\r\nMac = 90\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 83\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = ae89ad615201546b\r\nKey2 = ae20765745458fce\r\nKey3 = efd0867fba43dcb0\r\nMsg = e47d8659c9ad94971adedd6bce744206e1cfb65d042b942d93c4363cc73ec3e3\r\nMac = 95\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 84\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = b65886f13d6e8c4a\r\nKey2 = 0708e0b0730473a8\r\nKey3 = d04f2a86dc0b9e7a\r\nMsg = b97c12251d91512fe7b3a349a982409c7412f39494d970e77acbe9d3fac3dca7\r\nMac = 05\r\nResult = P\r\n\r\nCount = 85\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 3197a4a26261588a\r\nKey2 = 0dc4a75ec8b99b58\r\nKey3 = efb93e7620205289\r\nMsg = 65f4b3a00c1c1ef39445a69b2150b034705410140ff9dad0ce21740271cef04a\r\nMac = 57\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 86\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 62c4a16e946b4313\r\nKey2 = d09ea80e7fb33449\r\nKey3 = 164fdc04c2d5f116\r\nMsg = 898e824fdc89f21779156a9e58564c4b99004b95226c2ebb8aebd0b5365a6c6a\r\nMac = 93\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 87\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 6eeff20d3d5d5223\r\nKey2 = 258076b313611c1c\r\nKey3 = b013b957f70d9e62\r\nMsg = 2d7fec1a1e9ee85cf960e5dc4e239619ed85f4b14d32cbd42dfa79f77a27f2cd\r\nMac = 0a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 88\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 193e23e6fd8aa185\r\nKey2 = 1910cbdc549da804\r\nKey3 = 6b769b4923523425\r\nMsg = bd65798a1d02ab164e2d31b1387e505874779539046820bd429043c617854c36\r\nMac = d3\r\nResult = P\r\n\r\nCount = 89\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 150789ab37ef2ce9\r\nKey2 = 10cdf45dad9ed9e5\r\nKey3 = f475fd3e153898fe\r\nMsg = 044dd73a7d1ef37a437c09e9268708c82ebad189dc1e989ab3bd8d7ff75abc23\r\nMac = e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 90\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 48d9d08a6bdcc4f8\r\nKey2 = 1383641c08735d0e\r\nKey3 = 374a89c8cb73a7f4\r\nMsg = d62fb84f2a2442b52acf817d7f067edca031970bea092c35f29f9a931aa06dd6\r\nMac = 26\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 91\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 68f4620da8b00201\r\nKey2 = df1c8362345180d3\r\nKey3 = 26abda897f89d90d\r\nMsg = 0ac3f7f22d24b64aa584845d3a990bb69e5d2d4650640056c16c17c0b636045f\r\nMac = f9\r\nResult = P\r\n\r\nCount = 92\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 1c259df7492361b6\r\nKey2 = cd4acdb65b3e5b1c\r\nKey3 = 3b01addc2579ef64\r\nMsg = 607f4730a5ea9dabfbcd8586f680c3021c7ebc858e73354beb975d58713b0eb1\r\nMac = fa\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 93\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = f18a9dba9db5dff1\r\nKey2 = d5987013a4b69e38\r\nKey3 = dc16e0ce1351e3f4\r\nMsg = bfe99e184a7d7bf0b4ade8f402f2c49aa4948e74b2d5c905756ba5d32934dbbd\r\nMac = e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 94\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 8361bac48afb1091\r\nKey2 = da85400d107fbf8f\r\nKey3 = 31ec732cc29d7045\r\nMsg = 3a1ee70d4607325c13bff68e402e0a72742f6a63ae972c6dda74b6b2a3922f0c\r\nMac = 0e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 95\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = d0df1adf1cf72032\r\nKey2 = 1504d564ec1aea61\r\nKey3 = c42fada45d80a43e\r\nMsg = 3a53d9c7ae59e7811699fb0973e43256ed92162267c7ca4b57f5887ad5a24e02\r\nMac = 8a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 96\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 973bfe5b3be573da\r\nKey2 = 94b3ec7f343e46ab\r\nKey3 = dcaeabc8df405db6\r\nMsg = c8437dba76591a9031b3aa3b59fec0562d4eac439ca8efca57c3f2022b0ff775\r\nMac = 53\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 97\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = bc89867c43a74640\r\nKey2 = df347fb319464c80\r\nKey3 = fd92108a266bcdcd\r\nMsg = 1c9898ede16139560519e808ee9ddaf710a5bab30f54ed98230d1a44c189ea4f\r\nMac = f6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 98\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = fde925e301897f67\r\nKey2 = 54b3ab80f815df15\r\nKey3 = dc58928aa286c8e5\r\nMsg = b34f898d98a3aa0fa022b1b1d76953a5b3ecc88d60f2c79b59e1b1f636bc0d60\r\nMac = 0f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 1\r\nKey1 = 8a704ffe43e951f8\r\nKey2 = 2346dc8501202a40\r\nKey3 = d67afed616230113\r\nMsg = b2b4cb5e90ebf4bd265093b7f5efd4d62dc60e29737aa496e14929724e40c74f\r\nMac = df\r\nResult = P\r\n\r\nCount = 100\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 8c1f29f440f7f8b5\r\nKey2 = 5b45fe8f1f688661\r\nKey3 = ba40f43d9e7cc86b\r\nMsg = 220817144a15a0a654fc1beaabce60270aa72df83591754ee7a5fbb40b7420d7\r\nMac = 80ac51c2ef7bd5d7\r\nResult = P\r\n\r\nCount = 101\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d66e76d97f94ea16\r\nKey2 = f15e3ed06dd94598\r\nKey3 = ae073d1a6e5bc819\r\nMsg = 233d547ab33790859ab0dbc7a93f3bbebb610bed9acbfbce1fff580e9a1e8ef9\r\nMac = 4cb8ce681e4bc7c8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 102\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 0437836df770e943\r\nKey2 = c96e2c43bffd5298\r\nKey3 = 8552fbc16215e0c4\r\nMsg = 4f87d730bdfc7a7c72525c6b26ee9cae9a219b30d9575fedbd913a07b615a616\r\nMac = ea79cbc28f4264db\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 103\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d849ba8570b6ef9d\r\nKey2 = f1405732aeb61f92\r\nKey3 = 73c8e51ff167f857\r\nMsg = fd03202d0bd109b6e4299c7390c1407cd21ffb110013e6381185dea8f8707de6\r\nMac = 71070b17d05dabef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 104\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 914cef7ab6d998dc\r\nKey2 = a767abc18cf485e9\r\nKey3 = a2624ff20b2a408a\r\nMsg = bc5ce4c0bf3ad1a93e5306c9d7dbb620dde8708efe84e78c2200f41a958cdef8\r\nMac = 3cf4aaf3d337c9c8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 105\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 757f52e626eabce0\r\nKey2 = 700d91f14554bcb0\r\nKey3 = 548640d0dfaec2ab\r\nMsg = 22a4cf581584346095783be0982744c6201ff040760f868ab63895058d1edb88\r\nMac = b008b1150535ef11\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d65d0e58d3133b34\r\nKey2 = 289e58704994a249\r\nKey3 = e3df20ae3d585e2f\r\nMsg = 94c8414cbbec52e2d73bb8f02ef687c91432495c0c744666317d02e6d46706d2\r\nMac = b1292e1c7074dcfc\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 107\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d77a4989f4a17f2a\r\nKey2 = 409d91d51fa4d045\r\nKey3 = 6bb652ea1526fd4f\r\nMsg = 7a08ce579ae7af8004421cff72715e0b137da81f47d8f84da34c3ed53c32c0f6\r\nMac = 8b3cb70477ca7ca8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 108\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = e670c17519d9c2f2\r\nKey2 = dcc8a132629b462f\r\nKey3 = 58c1d52543ad570d\r\nMsg = a6dbad96ad23ff61479df39b99f0673a09f2a7eaebbd34b95d05c4146fa989f2\r\nMac = c470ec40599a0a11\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 109\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 290d292a15b6268a\r\nKey2 = 2638d9ad83ad1f34\r\nKey3 = a7d9ba62735dc2d3\r\nMsg = ef995cbfc49b0ebccdbd37d9f40a431c385d33d4b8234d7f0d6211eaddfb709a\r\nMac = 67ae62fb8142bd8b\r\nResult = P\r\n\r\nCount = 110\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 4faba73bcd5b5dfe\r\nKey2 = 1c97ea85207a97a7\r\nKey3 = 19eff116100dc82f\r\nMsg = c48e53c6956432460584c7ee1577c1c38b7fae2ff288199be25bf64081154139\r\nMac = d68a4558e95a67e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 111\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = d37c3dbc2f68baba\r\nKey2 = 918cb5e39237e016\r\nKey3 = f286b0739d38c4fb\r\nMsg = 2533361761ac80578fa262a50462045e3ec6e4d5d25c6e99a5c4ccf75f5affc0\r\nMac = c20f36e67732f864\r\nResult = P\r\n\r\nCount = 112\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = a0baa71c38d6d064\r\nKey2 = 8f58ba45cb494ab9\r\nKey3 = 853decc431f7b3cd\r\nMsg = 20e394c7cc90bdfa6186fc1ba6fff158dfc690e24ba4c9fbf11b68519d573a8a\r\nMac = 4ba956b98a99d7bf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 113\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = b69752407c68b6bf\r\nKey2 = 8fceb05201ec4320\r\nKey3 = 2a755e372373ef26\r\nMsg = e884d65c87411584a56956d5b27ca9725b473c205b64cff09400671f5ee0473a\r\nMac = 9f3de5e8cddc374d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 114\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 8c04e0f27f83b0ec\r\nKey2 = 042cfb6883348fe6\r\nKey3 = 404f5dfe587ab591\r\nMsg = 8a34cd562b111fe04fa0bf5e004faedaef99d0bab9344d966c8b3847486e6f40\r\nMac = 6c530215fb25015b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 115\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 429401ea49cd97b0\r\nKey2 = a8f1b6b63101cee0\r\nKey3 = 20bcd08c5d16e049\r\nMsg = 591d88123fc9a786b247e8d5ce155f136d6fe4084117c41f2056b67f9e3e1077\r\nMac = 6c414640b424cf56\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 116\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = c470255783b32f01\r\nKey2 = e3aed6705ba4291f\r\nKey3 = 7319100e54f432d3\r\nMsg = 01acc3282fe41b62f95f5dbfb7e7bfef694c5fe34ca87d31abe7e7bbf887b48c\r", + "\nMac = cd99df4814667454\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 117\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 73c10b833e1043ab\r\nKey2 = 18dcd343645d5207\r\nKey3 = 6426f7f88c3473c8\r\nMsg = 068e4a0b1a62dd64198f1b9ece814c2feeeee50ba814b70d7d42659952991b80\r\nMac = 1fc90834b7dd090b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 118\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 37eae98ff42afb25\r\nKey2 = f2231c028c29da9d\r\nKey3 = ef3da8d0c77fbf45\r\nMsg = f266cec01c5fc08c0bdabc9537bd1aa2df9f2b8ffbe5cc94722a3bca8de529ea\r\nMac = b3809c8b0eb9dd8d\r\nResult = P\r\n\r\nCount = 119\r\nKlen = 3 \r\nMlen = 32\r\nTlen = 8\r\nKey1 = 1358fb67155e0145\r\nKey2 = d02c54a1206b5d7f\r\nKey3 = 1c04ba46c74a5d49\r\nMsg = e38b4c3e7a82643beb3192426555ad9c9b2620d677373fc40c9ddbc4cd531347\r\nMac = b000e2ea1ef48a8f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 120\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f6b9a81067255b58\r\nKey2 = 927cfbc4cdec9285\r\nKey3 = dcd62345bfe03b92\r\nMsg = 246b66b10696adc45840\r\nMac = b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 121\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = fea186dc73d3807f\r\nKey2 = b8fec7387a197962\r\nKey3 = 4c91abe60db64ff1\r\nMsg = 8ba298364af144a8d5f3\r\nMac = a6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 122\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f264da8607ea439e\r\nKey2 = fdb9daa41fd34958\r\nKey3 = f85d6b859b9892bf\r\nMsg = 402006f6b18dbd11dcd1\r\nMac = 28\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 191c461adc4f7f4f\r\nKey2 = 75b932e68cb98cfd\r\nKey3 = cb2943857a1c9438\r\nMsg = 391deef3a9a41394d14a\r\nMac = 3c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 124\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = a2c2f713430ece92\r\nKey2 = df081ae9627a1351\r\nKey3 = c1ec469ba8c73b67\r\nMsg = 37a49535684637f67573\r\nMac = 40\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 7b61dac238ba3e83\r\nKey2 = d05e9ed34fc410ce\r\nKey3 = 98da194c100eeacb\r\nMsg = da22ad9825c195d1e297\r\nMac = 43\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 126\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 13aec10d13fd37c7\r\nKey2 = 89198c3bcd38b951\r\nKey3 = ecf843cdef7397cb\r\nMsg = b7625aa78d2961c0fee6\r\nMac = f1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 127\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = d94a68ec329d914a\r\nKey2 = 394a8acea420e952\r\nKey3 = ec04c8cb8602aec8\r\nMsg = e043f30a405c41938914\r\nMac = 6f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 128\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = d5cb7579582fb6a8\r\nKey2 = e67f3ba11383d61f\r\nKey3 = da370852e9b9c2a1\r\nMsg = 7d32f440151a7069fd73\r\nMac = b7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 92402f6eb54526b3\r\nKey2 = 924515d92ad5a1d0\r\nKey3 = 9ead2adfb025f81a\r\nMsg = fd44d8d0fea5cfdf3321\r\nMac = 2f\r\nResult = P\r\n\r\nCount = 130\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = a9daad97ad23fe61\r\nKey2 = 32e5988a37987a38\r\nKey3 = 31626d16a780c825\r\nMsg = d6cf17192f8ad745ab5b\r\nMac = 8f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 131\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 52c457d9d5d5ab94\r\nKey2 = 9d3875ba6d75fdba\r\nKey3 = 4fb91a863d15ce52\r\nMsg = 4effbf732e67af7203b3\r\nMac = 04\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 132\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 7304b65492fd0402\r\nKey2 = 62a4cb7c23708057\r\nKey3 = f2f7bf13839e01e5\r\nMsg = a630c0f362eef35b6a58\r\nMac = aa\r\nResult = P\r\n\r\nCount = 133\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 51b33425a1349792\r\nKey2 = dc5b8ca440eae6ad\r\nKey3 = 70adf49dd0a8f119\r\nMsg = af246a8a810cca5e657b\r\nMac = 0b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 134\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f22029ce51619e0d\r\nKey2 = 9d51bcc2089785e0\r\nKey3 = 689d62621abab3b0\r\nMsg = a9c9fb632423d367b3eb\r\nMac = 0c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 135\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 1ca226d0dc8c328a\r\nKey2 = f18a9dc176621f51\r\nKey3 = 3d765d20e03b4cea\r\nMsg = f9d9fb44919e47cdeaf8\r\nMac = b0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 136\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = f3ce4992c851e3a8\r\nKey2 = 835ec1abef97f2c8\r\nKey3 = 5b92384f20dcc2ad\r\nMsg = 9094935fcd7c389dd17b\r\nMac = 3c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = bfd929cdd9c2089d\r\nKey2 = 8e49988abcfbf458\r\nKey3 = da73d986894fce4c\r\nMsg = 88018424fdb76c908bd6\r\nMac = 94\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = 57bf2ca4e3629797\r\nKey2 = ef7f675443402546\r\nKey3 = 6e4f924038f8bc92\r\nMsg = dd4f0a872f4b7089d697\r\nMac = 5b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 139\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 1\r\nKey1 = ba86924908df08b3\r\nKey2 = 26b954ba52df2c98\r\nKey3 = bf38cb0e89b9f4cd\r\nMsg = a682e6fd64df4b9f4fe8\r\nMac = ea\r\nResult = P\r\n\r\nCount = 140\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 52859849a4b6c1d5\r\nKey2 = 380e73c7aefb0168\r\nKey3 = c479fef80eb6260d\r\nMsg = ee6857533675b5ed8d43\r\nMac = 43fd25f696cb0693\r\nResult = F (1 - Message changed)\r\n\r\nCount = 141\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 97ae01315d13ec52\r\nKey2 = c7674cc1ab0bbab3\r\nKey3 = b68fb99797b33b79\r\nMsg = ce9127f649bfff849826\r\nMac = 2dfe01d9bc07646b\r\nResult = P\r\n\r\nCount = 142\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 2b257032b0d9b0b3\r\nKey2 = 49f7c10e8a9bcd37\r\nKey3 = 20f4fb4679106ddc\r\nMsg = b2c62d03902c44253368\r\nMac = 14c5ccf5f9433a0f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 143\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 0b988c3d380e5b80\r\nKey2 = b86be99162029b54\r\nKey3 = e0bc9775838a58ea\r\nMsg = 61ababff3763183c348d\r\nMac = 28a2de26aa6b4074\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 144\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 26e9abbf201fe5b9\r\nKey2 = 7062a82f800d5183\r\nKey3 = cd45e654bf5d205e\r\nMsg = 020683e1f0392f4cac54\r\nMac = 6f1522d3c8186217\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 145\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 3443f4016dadcd86\r\nKey2 = 235dec80323e5838\r\nKey3 = fd583285e6efbc51\r\nMsg = e64eeb89828b4297601a\r\nMac = 5575a40dba5bc4c6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 76c7616785916470\r\nKey2 = 5b3d1f10e5252fda\r\nKey3 = 75a2d632a46ea18c\r\nMsg = ac7d701597f0ba879055\r\nMac = 06b98e161e6a6754\r\nResult = P\r\n\r\nCount = 147\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = f12367b568a758b5\r\nKey2 = 7b2f9770924f2c0d\r\nKey3 = 1f8ad9e9b97a088a\r\nMsg = b99de8168e8c13ea4aef\r\nMac = db534a059f930ee0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 148\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = f1adb67986923d8c\r\nKey2 = 02671957dcf75808\r\nKey3 = 52732ae970467019\r\nMsg = f759c3033d4ed34948d7\r\nMac = 2d9caabf50999ac6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 149\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 792f9770924f2c0d\r\nKey2 = 1f8ad9e9b97a088a\r\nKey3 = b99de9168f8c13ea\r\nMsg = 8bae64015d62f68565d1\r\nMac = a42f89527f5cb219\r\nResult = F (1 - Message changed)\r\n\r\nCount = 150\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 31ec790d4a8a131c\r\nKey2 = 562c8cdc07e331d3\r\nKey3 = f4a7467043924c4f\r\nMsg = 1798286c37c1504fc0d7\r\nMac = f0d6e2f7edce6349\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 151\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = adb692e376a12585\r\nKey2 = 8c8c4362ea97f810\r\nKey3 = 528f204c19f21a31\r\nMsg = 6543e675d34639a7f7eb\r\nMac = fac96e6804526535\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 152\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 62984a64ec7c4a92\r\nKey2 = feda64dfd9a24f9b\r\nKey3 = cbb04f7a1f26df31\r\nMsg = adb555fd5f5c6bdd9c4e\r\nMac = e8dee8714b285a00\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 153\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = ef0d58b55ddae95d\r\nKey2 = 80e07ca4aebcfd34\r\nKey3 = bf947ff4ab2904e5\r\nMsg = 1fe87a2f431f3718665a\r\nMac = 44a869aee76d79db\r\nResult = P\r\n\r\nCount = 154\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = aef4ceb55e3d37fe\r\nKey2 = bc0bb9d05bad972c\r\nKey3 = e0a29b2c7940ce9b\r\nMsg = 78ad5f3718acf9e8cc7c\r\nMac = dcc1d44200caf6f7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 155\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = a4403438f8fb254f\r\nKey2 = bac752cd83a170b5\r\nKey3 = 6bf71654f1854589\r\nMsg = 349566b6716e5f831d69\r\nMac = 7c08cc43ff4d8e07\r\nResult = F (1 - Message changed)\r\n\r\nCount = 156\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 2fc7f4c1ce042f73\r\nKey2 = 8346bf7a80b38640\r\nKey3 = 2ff74abfc197a732\r\nMsg = 43a32b8ab9b7ce4bbd1b\r\nMac = 8000a2612215014a\r\nResult = P\r\n\r\nCount = 157\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = c40ddc9e29ce041a\r\nKey2 = 583d6bc4c1a2abf2\r\nKey3 = 9b018fd5a4084a64\r\nMsg = 228", + "6a1eddd80737a724c\r\nMac = 0ff14761c982f890\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 158\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = bc327a0bcb2575df\r\nKey2 = 6b9483e6e0755d2a\r\nKey3 = 622cdc5b2916ab89\r\nMsg = e1be89af98ffd7d9257a\r\nMac = d6f4c8d96b3e2180\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 159\r\nKlen = 3 \r\nMlen = 10\r\nTlen = 8\r\nKey1 = 9e517cd616a48ada\r\nKey2 = 6d266192d5387a97\r\nKey3 = 8a081fda97c86b94\r\nMsg = 9e9fb0b2b77be6eeaae8\r\nMac = ba0b73fbffc0ab0b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 160\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = e0b9a826a85efe94\r\nKey2 = 4f615bce7cc1ba68\r\nKey3 = 3bb56d3d9816103e\r\nMsg = cfe9ee956cb1f5a60aa6ec79a3e454224b456879\r\nMac = 64\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 161\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 1e08a794a175b69e\r\nKey2 = f7d3ab46aeb9073e\r\nKey3 = 3e7cf8cea19d0891\r\nMsg = eb4f5b04517ee93e2c900e01948ac81ca56b2b26\r\nMac = 79\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 162\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8f26700dc140570b\r\nKey2 = 8325e3a889c823ad\r\nKey3 = 6b048aa73decf83b\r\nMsg = cefb55151933a488e2b3d421dea9720727188106\r\nMac = 85\r\nResult = P\r\n\r\nCount = 163\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 3443f4016dadcd86\r\nKey2 = 255dec80323e5838\r\nKey3 = fd583285e6efbc51\r\nMsg = e64eeb89828b4297601a5b3fcde60075fc2424ae\r\nMac = c0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 164\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 91a401cbb6460b16\r\nKey2 = 85438675f15b6e73\r\nKey3 = b09140318a767038\r\nMsg = 8c65cde13149d9d54a5bccc17747f1d5f3e807e3\r\nMac = 56\r\nResult = F (1 - Message changed)\r\n\r\nCount = 165\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = b78a16fb9b075d3b\r\nKey2 = dcabbf7a07150261\r\nKey3 = f7644a01d5dcea46\r\nMsg = abe2fd996bb6804ed3286c057df9cea6836a2dad\r\nMac = 09\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 166\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = ce8a467534cd679e\r\nKey2 = cb9ee6fb70a42f4f\r\nKey3 = 16c1e5c1459e4ac8\r\nMsg = 3c56ccfbe92023109983e740d6a53488b813ee87\r\nMac = c8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 401f0de0efd6dfa8\r\nKey2 = 16ae7c3bbc6e5b86\r\nKey3 = 4ffebf790815f1d0\r\nMsg = 9052d5e22e6712fab88e8dfaa928b6e015ca589c\r\nMac = 61\r\nResult = P\r\n\r\nCount = 168\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = d357bf5bef2cfba7\r\nKey2 = b757d3abf49b4ac2\r\nKey3 = 16388051da8a04a7\r\nMsg = b04e8f6d20924be8e4e2c6767f87b74377bdf90c\r\nMac = 72\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 169\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = f8ea68aba1bcd9e6\r\nKey2 = 4abaa4260d864573\r\nKey3 = a49840ab737af7b0\r\nMsg = 1fc99e586f87932445930a300eb28191d9c6215b\r\nMac = 19\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 170\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 94ec086d8c0110cd\r\nKey2 = 4ea11f327f70c245\r\nKey3 = c8d07adf7c7c5eb9\r\nMsg = 812dbc453a1fda59f73aceea3bc84d2c7a437dfc\r\nMac = b2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 171\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 9d575d582a9723c1\r\nKey2 = 294af47a54b051fe\r\nKey3 = 5131bff85bf12608\r\nMsg = 266e5305b96f497a956ae82b20367ebac0b14215\r\nMac = a9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 172\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 913d800ecd0dc762\r\nKey2 = 7f6ec476b6b07c15\r\nKey3 = 973262ab7c83b634\r\nMsg = 4670a266bebcdf95c62d36cda33d50e6650fcdcd\r\nMac = 4f\r\nResult = P\r\n\r\nCount = 173\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = b97ffe79d068ece5\r\nKey2 = 4a75fe2f67dae392\r\nKey3 = 45a4d9f17a9d70f8\r\nMsg = b53017500c100dea0511845597214484fc5f7f34\r\nMac = 6d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 174\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 7e1af10bcd86c283\r\nKey2 = 51cd37540e19021a\r\nKey3 = 988fd3c7250e2a6d\r\nMsg = da1919d4a2a7fcc34c88fb2065e52bf9dbc50731\r\nMac = 22\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 175\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8c0dc16eb9c80775\r\nKey2 = 6eeff20d3d5d5223\r\nKey3 = 258076b313611c1c\r\nMsg = b212b857f70c9f63d0c9d2ccd253c28d1534631f\r\nMac = 2e\r\nResult = F (1 - Message changed)\r\n\r\nCount = 176\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 92c29eb0bf3e73a4\r\nKey2 = c6ecfbe6cd49bf4f\r\nKey3 = ef19d9d06d7a5e7f\r\nMsg = 969304e651ca62039088f8123085ac3263796b67\r\nMac = 57\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 177\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = a4432f52975e4316\r\nKey2 = 7f2086da04fddf4f\r\nKey3 = 8302139e79684329\r\nMsg = 5c9bcd197ea59e1b58b3da707b253491cc5a5ef8\r\nMac = ea\r\nResult = P\r\n\r\nCount = 178\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 5ae0b6d6c2855b7a\r\nKey2 = ec675d3e73bfd685\r\nKey3 = d3406b868fd3ae0e\r\nMsg = 89b9ecfef6f10e81f7956dbc7ca4a335047535a8\r\nMac = 70\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 179\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 1\r\nKey1 = 8f7f85649d5e08a4\r\nKey2 = ceda75687308e07a\r\nKey3 = 9215c4c19bdc0d46\r\nMsg = e53101e6eabcda32c13d7b1dd1d88e7c2ca3ddc2\r\nMac = 14\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 180\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 7061b5f46b98d394\r\nKey2 = 58c2ce3807623475\r\nKey3 = 0df8e3c432da8a37\r\nMsg = 1086953d352e94a51a6d4c59a2295e8fff5b311e\r\nMac = 554d4df88228eba3\r\nResult = P\r\n\r\nCount = 181\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 347a25a1ec433b52\r\nKey2 = ec75d97046152c10\r\nKey3 = 86b937b6ad1ccbf8\r\nMsg = 4fe6bd43c28143ea5d40919cb5330a7e674f5bd8\r\nMac = 3d0d841895fb7c65\r\nResult = F (1 - Message changed)\r\n\r\nCount = 182\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = b3701aa7da61512c\r\nKey2 = 46dacba40740e3c1\r\nKey3 = 8f79a4dcadbc315e\r\nMsg = 4612fb4586d7518d0d648894347ae7d49d043f29\r\nMac = e5dd4392afbeabe7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = b5b57acb2c7fd6cb\r\nKey2 = 70b02c9d8651c889\r\nKey3 = 07f485f7b00e45d9\r\nMsg = 9011231ec382ecaaae57f34de1ac6bbb50741014\r\nMac = d34581ad5a3e9e57\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 184\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 88985bdfd9852604\r\nKey2 = f7f829aec8a208b3\r\nKey3 = d5ba012ce6754554\r\nMsg = 6cad7f3b9f196839bbc5a7f755c09aa8e17c83d9\r\nMac = fc7c93552aa14ca2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 185\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = cd0815194319d552\r\nKey2 = 346bb634027668d9\r\nKey3 = c17f2a26257afbad\r\nMsg = e31b3d97ba6ee6f2e18f084215ca0a5ca0d816d7\r\nMac = af5772396bb63d20\r\nResult = F (1 - Message changed)\r\n\r\nCount = 186\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 236e5201dfc1081a\r\nKey2 = c81526bc85c7a2ce\r\nKey3 = ab91d0aee0d68931\r\nMsg = 1f36b9cbf3d4d4dfcc4ba7fafa7c229f0a9253f4\r\nMac = 27586cf856a41e82\r\nResult = P\r\n\r\nCount = 187\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 2e01198faeb6986e\r\nKey2 = 7cb564801f15bc5d\r\nKey3 = f2d3ef0d4fec61c1\r\nMsg = 27c8c90c9e46e14b8cbb0b7559bb166d65f58aeb\r\nMac = eaa7b4a171e449ef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 188\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = df575b851331b016\r\nKey2 = 33ec7326e9ef31e5\r\nKey3 = 1686c1ec8a3ea16d\r\nMsg = 1e4e01d38ff65d05646d544b52a6df49b897eacc\r\nMac = 45789bd32147c0ae\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 189\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 43b68c1f29ef5b94\r\nKey2 = a7dfa1cbe9ea3df1\r\nKey3 = 83d3c286e973ada1\r\nMsg = 0ca9b0f6465db0e101f8c14b2e73859d9c355b0a\r\nMac = da439a51157ff0d5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 190\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = bf91d679268c85ce\r\nKey2 = 46b9f7bf4aa1a2c2\r\nKey3 = f7fd15fda2cd6408\r\nMsg = 0c2933e39d7e601ee6f2519eaf01294853664262\r\nMac = 455cd46d3b452a55\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 191\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 0dad9d451f890b38\r\nKey2 = 3416e3c240a16ee6\r\nKey3 = 5b80d6aefd4ab5a4\r\nMsg = b6e1de9abef7525c5dabbdc85746958781d50139\r\nMac = 3445a869cca839fb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 192\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 96858f8f2ab56df2\r\nKey2 = 5edc3b04b94ca7cd\r\nKey3 = bf10614ce0491645\r\nMsg = ec9aa18b3e7da99dcbd7de7617a79130abe3348a\r\nMac = c744a1392fc656c2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 193\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 46ad6ebad9644a67\r\nKey2 = da684aa48f23d619\r\nKey3 = 43a2316b40a46e25\r\nMsg = cf97c2abe3d0fc89e05538b50147a3f405391219\r\nMac = 7ac08967edc5730b\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 68647694efb32023\r\nKey2 = 0d2938c8fe1a4057\r\nKey3 = f479f16e7552942f\r\nMsg = 33a9c750bb532d2d37ec86fa851aeb3cad1eaad8\r\nMac = 3873ae02210eb5fc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 195\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 58d62fd92af7437f\r\nKey2 = 89dfb51fc807cd6d\r\nKey3 = 024fd04f40d5d0e3\r", + "\nMsg = cc293c9e1780b401d2e7fceef6f69edcf0f70b86\r\nMac = 6574bfceaf04b4e1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 196\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 4b377f98df0b7598\r\nKey2 = bf73f4c2cb074001\r\nKey3 = dc9857f47fe6101f\r\nMsg = 9ba5dbe7a8ecfbedadd7889cd7f1ae073e01ee3b\r\nMac = aaaeb7223578bbad\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 197\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = 91c8851934cdecc2\r\nKey2 = 582562aef1205e32\r\nKey3 = a12a70eacbad310e\r\nMsg = aa390a0ae33751b0bd8de5723df91d999aa70358\r\nMac = 67f76912ed61eaab\r\nResult = P\r\n\r\nCount = 198\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = dcc2bacbea0dcd10\r\nKey2 = c18ca45ed57f8f97\r\nKey3 = 5d58157a677f1951\r\nMsg = a7573e5b7dd7f4ce9e4480f603c14145a27f7c7a\r\nMac = 2b6af968464ac63f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 199\r\nKlen = 3 \r\nMlen = 20\r\nTlen = 8\r\nKey1 = fe6d49702f044f40\r\nKey2 = 33321613da401004\r\nKey3 = 8c3438f74cc2680d\r\nMsg = b15a118b3132c20c31e6c9d09acdee0e15fcc59d\r\nMac = 9f28413a00da00ab\r\nResult = F (2 - Key or Key2 changed)\r\n", }; -static const size_t kLen42 = 155170; +static const size_t kLen49 = 53587; -static const char *kData42[] = { +static const char *kData49[] = { + "# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 128 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:37 2011\r\n\r\n\r\nCount = 0\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 27b5686c79b3d242f96d3892c6135b26\r\nMsg = 00\r\nMac = c98d11822b9b4d7a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 1\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b4542a22baa348ee2d11ef62d44cebab\r\nMsg = 00\r\nMac = f7a2a3f519fc462f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 2\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 7256e344f68b3e7f9dd6e04c5c65135c\r\nMsg = 00\r\nMac = d4d7fcc5f979230f\r\nResult = P\r\n\r\nCount = 3\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 7a2116595c5cf6482199d3312498006d\r\nMsg = 00\r\nMac = c3c4fa28709060b0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 4\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0341551d6c7e7c57f678068f0b41d1fe\r\nMsg = 00\r\nMac = 821030d4b7889fcf\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 5\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b67ba2aa4e9ea9871c3def87e2dd77f4\r\nMsg = 00\r\nMac = ea896182698ac145\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 6\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0091d39f3478d2c59bf874b96db9ce0f\r\nMsg = 00\r\nMac = fb12c5971b0f2f18\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 7\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 46a2e6bd3fd5336abf02eace3cd1e1f6\r\nMsg = 00\r\nMac = 9c6b46ef046ae1d1\r\nResult = P\r\n\r\nCount = 8\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 4b0fbd5e6f9298e5ced5ebdc60fc18a7\r\nMsg = 00\r\nMac = 221857badcbcd2be\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 9\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = fb20547da671acd4c6df37f6568a6428\r\nMsg = 00\r\nMac = ba0c9bfd3d9c0c95\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 10\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = b787def50aaf446bf15c562434844562\r\nMsg = 00\r\nMac = ba60bdae64068330\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 11\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 67d77f50727c7cd5b38e0b175a888c88\r\nMsg = 00\r\nMac = 555923e6b5fbc504\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 6f552ef7d309bb98597b91cecc21e158\r\nMsg = 00\r\nMac = c2aa402c0443dfbd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 13\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 411871267919a145532cc401e753ebff\r\nMsg = 00\r\nMac = 167a31913228f45f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = abfe32efdf0464cb2eaafca8eac30d9b\r\nMsg = 00\r\nMac = 8edbc729b1923e10\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 15\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 85504d59a12f3e17edfb0b6337d4a081\r\nMsg = 00\r\nMac = 9045fd77cb26dcb2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 16\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 55f7565826b0e2ccc1368f4de32022de\r\nMsg = 00\r\nMac = f82395416a8dc209\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 17\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = 43c8f984390debb0f26c6b9c2df8518c\r\nMsg = 00\r\nMac = b5d732086bf8feab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 18\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = da288d2014616f16a2abf5923dea49ad\r\nMsg = 00\r\nMac = e03b67b53fc7863f\r\nResult = P\r\n\r\nCount = 19\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 8\r\nKey = e2f962d076df051c2d291b47a902ea0c\r\nMsg = 00\r\nMac = df1456a7edeb4e42\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 20\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 191b53e0c7d90161e5e2014e9b8aea31\r\nMsg = 00\r\nMac = 1e210cff3c90bd2e2a27a78ef7662f61\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 21\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 54666bdf6db300ee10982d14dac828bc\r\nMsg = 00\r\nMac = 9fef67209b8da28049b80efe98f85f13\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 22\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9a143c21cc6c9528b9ddd7e4405682e1\r\nMsg = 00\r\nMac = 1c3c3b6d1d86ac5787234f8f6d707acc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 23\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 802047ee1309e548ae81e93a17bff9e7\r\nMsg = 00\r\nMac = 1472aecaa0a09e45893a14090ed9a17f\r\nResult = P\r\n\r\nCount = 24\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = ab79ce74c0959aea0fd0b28ea5d0afe2\r\nMsg = 00\r\nMac = fde8a95536cc334f7fc8881a187afc61\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 25\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 644ac6fdc1e713ecb7ff1e0bd5729a57\r\nMsg = 00\r\nMac = 95a93bb50703521e6c1a8be1aab6a646\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 26\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = b4571e56f66a857daffbdc99370ceddd\r\nMsg = 00\r\nMac = d2742ea62f1d6513c4eb0e533922f251\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 27\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = abff2b097d688293701ff2c49ba48eb3\r\nMsg = 00\r\nMac = 17e724f66d4a9ef5dfc0cf903f8ff04a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 28\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9d45f6d97d1573de3cb3488befaf5b7f\r\nMsg = 00\r\nMac = 96ec3cf234d6704483a93885bd67e6dc\r\nResult = P\r\n\r\nCount = 29\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 00d385629e5df815a5300e6635351934\r\nMsg = 00\r\nMac = cb23bb449ac26e2186b02f7428fa022b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 30\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 2f9109e7eea21b2615c81c03182ce603\r\nMsg = 00\r\nMac = 4532211f48124a9eacd795ea4313adaf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 9f3830f5cd40a2396b6093b358cef1e9\r\nMsg = 00\r\nMac = f5ea59ec909a8ec2d8b11f5f276201fd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 32\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 17378e17c41586b88523a6b6af738dc4\r\nMsg = 00\r\nMac = 40cc8b388be6789aca584659acc7aa06\r\nResult = P\r\n\r\nCount = 33\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 064e8c88a0a0766186d75867b5ca3acd\r\nMsg = 00\r\nMac = b2f94222a68fcf803868b00404ad170f\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 34\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 1e39f1cba97dac4e4d4f3bce7fda72e5\r\nMsg = 00\r\nMac = 60763815c1075c31078a9b44fe4b8427\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 35\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 06f0e4618e0ea8fa5443b50ea005b672\r\nMsg = 00\r\nMac = 295c6cd08b1d668d9fa85ef851b1e029\r\nResult = P\r\n\r\nCount = 36\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 648d77b57770b67ecda1ce7951eaaeea\r\nMsg = 00\r\nMac = 2f3fbc6edf5827fce440b9a7ff8535b4\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 37\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 6f3938932b5c1280311e892280d8a822\r\nMsg = 00\r\nMac = df02edfb316350c81dbee385d6e1d8e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 38\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = f909903451d1f9f45ffcb93a407ffb50\r\nMsg = 00\r\nMac = d176620722c5327270ef30956d7ac02f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 39\r\nKlen = 16 \r\nMlen = 0\r\nTlen = 16\r\nKey = 181d92c7df1ebb0924719e066e08b95e\r\nMsg = 00\r\nMac = 144f688fa0d29faf787c48cd0765eecd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 40\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0c5b763b1e97b4f4dfc7059e4896ba58\r\nMsg = a0b3c6944b35f7208dfb40b4c4ba134a14dac928b679950793b3b6751221f178\r\nMac = d922ea85b3992a67\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 41\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 461d7d629778c8b05a688bee4fc01e9f\r\nMsg = 07571a6c9bcb6f97d626796bc74e551d1c45cce38afed761706f6264b7e751d3\r\nMac = 794b224a85396a27\r\nResult = P\r\n\r\nCount = 42\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = b91c6b09bf5a0487a9b5ea2fe0c1f3d2\r\nMsg = d31fd388e97727ba0a35d34ae05d9980e5974f6b3d86e2d4dd569b70f394a159\r\nMac = 2665ff2785bcb606\r\nResult = F (1 - Message changed)\r\n\r\nCount = 43\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0737836cf771e842a70f3eeed7206799\r\nMsg = fce631a9eb130178018ca88cec966ae53ecc83a51d0a73173c8a9af10b4d04d6\r\nMac = 1eee822e37dd1e84\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 44\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 120132c315bfc9c4fb93023f5d3500d7\r\nMsg = c2576ed3189eff3205f5e01dd8fe7c64f12dc73c807c22918f607f9e43fcc5ba\r\nMac = ddca15c8b5a80cb2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 45\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 5363bd7d867a9f9f0592dd9940a791e8\r\nMsg = f34e86b8803d386573b81045df945df8319a93b613de4c41904c8e1879844cee\r\nMac = 109dd7c920ebbf41\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 46\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 3fa1c7cffaa167557b250634e8052fa0\r\nMsg = 4255f8af18df7237e0abe98421aec9634443561752d893aaffe76380e829ef32\r\nMac = 0eceab8d28dd4a2a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 47\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6583a4ff27b6e109046d11b977c8293d\r\nMsg = b63be320f92", + "e01260fba37312224494a2764dfc928287c75dc1cafee7b698d48\r\nMac = fa0cced22e896b40\r\nResult = F (1 - Message changed)\r\n\r\nCount = 48\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 5949378fd3135dd02ee1929014000411\r\nMsg = 65c16f4e66b10c7c153be7ba2dbe3a6d4eed3b04fec44188edc229747d52f8c8\r\nMac = 9ef023345848680b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 49\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0e80fa889b1d96a0d23d236d4d642a27\r\nMsg = f6f094e46cdb2e45fe49b18aff1427ebdac9710fa7f47f75fc9ec7140613ef3e\r\nMac = a09774009934c9d4\r\nResult = P\r\n\r\nCount = 50\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1f88dfd4f5c52c22b1db47f9f4fb6e2f\r\nMsg = de433ebd1cdabeac46b94cc00d984f172923535ca8fdfeeb860546357dd8e266\r\nMac = bb17b3983faee0db\r\nResult = P\r\n\r\nCount = 51\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = ab0ab9e79ee53a6946a31ea807258dbb\r\nMsg = 89ddbb042aa2aea5207b312c9831fb48138aca90626ef7c5ce474d5797ae1b2b\r\nMac = 72f316d5bfcfcf6f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 52\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1eb19542a0064564e096e5d7d60acaa6\r\nMsg = ca25504f3f5559aa0e88199ce1551c9240b5c76f55b83bdbf2777cded54ad3af\r\nMac = d936b1fca0a96aec\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 53\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 33f11aa36d8ab0fc53486839a576b31e\r\nMsg = a58524e37c2504468f77a9c21b0e6d1a6b5e06fa051d5b8025ef97fa69417cf2\r\nMac = fd64f7cb283adce1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 54\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = a7b81d8245129aa451dcb7229de415e5\r\nMsg = 2b2ec02aba10aee056443cf90585caa2510b3b835454a99f1324567b0dcbe682\r\nMac = f4cd48f32c9dc66b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 55\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 3c1baf0d915e5aec92bb62babad0ba2c\r\nMsg = f8f2424c2dc0d0f3821af7244038da0832c547be4ff0850b98c04d4d44a716b1\r\nMac = e17ea6862129d6b9\r\nResult = P\r\n\r\nCount = 56\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = 943a49073db6ae94a88844ed895f8fd9\r\nMsg = 8a15e5be479d3a39a459ca7b50457472cbf44f6a8324ee3d4096e2c3bf1d8190\r\nMac = adcce0ea2c8b11d9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 57\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = ebf8935f53dfb3bd40453c31f627c73e\r\nMsg = 7edddb03d861dc9796f8e069bde434681620f604db436f34b7a6a3beeec925b3\r\nMac = e8ea88729d49bea4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 58\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = f18e8feed77d1b80c31483fe69073d56\r\nMsg = 37c6206e23163c39a13f19de48cc25dc26e6f83cb376e8d2048ad7c141fa503d\r\nMac = 0d4f5cdb2a49b471\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 8\r\nKey = b4e41c7bfb8fcaa5236f656185c1496b\r\nMsg = 32758ae47884fcef766dd1fee1a7f55ca6f6691574e2ea097a68cd4072ef2e7d\r\nMac = bad08badb66c8e5f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 60\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 708484fba04972b815256c5dab12d5d4\r\nMsg = 97751b4893a83cfe6b760e10da795682e9668749c09036f9bfadce9dcbdd85e6\r\nMac = fa74b33267c5ffeca75e5e16978bd7b0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 61\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = d0df1bdf1df6203241722fb9c9c1cf74\r\nMsg = 0e41361ebfbe4e6580fb5751e58e98de8ee5d9849fe875026fdab15a85804c1d\r\nMac = de4992c9d33659620cc203848e42a279\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 62\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7c0b7db9811f10d00e476c7a0d92f6e0\r\nMsg = 1ee0ec466d46fd849b40c066b4fbbd22a20a4d80a008ac9af17e4fdfd106785e\r\nMac = baecdc91e9a1fc3572adf1e4232ae285\r\nResult = P\r\n\r\nCount = 63\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7b4c800f5071521119e4cc6deee8729f\r\nMsg = 775946f3014523b6ea37804585cadd35e74e9382ebc1022579fbebe407281b6e\r\nMac = 2f6697f5d067aecdb3ff5a09d9169b3b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 7618d222630138cc14246e8fddcf98cf\r\nMsg = 432e3575a966958434da38dda3606f1f69adeaca536a7bf66c8b1e451edc3716\r\nMac = d7d78aac615ffc1bb32dfea41f2b8771\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = c8804fef18ef263c010c8a205e14516e\r\nMsg = f2d23bc605181e3894f61fa63d61ed4a610123ab7d3531c0b7579a58b74161ba\r\nMac = bfe5e2c10a5cecccd3de2529f340cf6b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = f98ac86ecb742c188852980b5150d100\r\nMsg = 4e6fd4fa7669ce9552154bd796644961b51067dc02303430150aacf671280031\r\nMac = 73df5f4d3ab9240d4fb2be775188adc0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 67\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 638d7d95ff5f57571261e23ffa081189\r\nMsg = 5f5bc4e32764bb00085667b7f1b15433f09c1f6fa48689f8f50dcaf5021f2864\r\nMac = 96b270629b2bfbf721f1a70eccf9abe0\r\nResult = P\r\n\r\nCount = 68\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = a5a20d8139472a4cb38993c5711ac2ca\r\nMsg = 73e1e75538f9a63e49a068189e3b0a1a1e65ca5d1295589bdafa3136deaa287c\r\nMac = 320647d53ccdf2335a9c9a3452c1cee5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 57656be54860414e8a62223381ca4405\r\nMsg = 3447e82ecec6c8b6fe1e44ed91f933e4a70c431911eb86eefe222d5ad78193df\r\nMac = 47c6b5a28d723129648aef418b74daa8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 70\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = e7b665600a2aa413e117c53816cbed34\r\nMsg = 5e4d49ab796025157add6d42258b9c506d9ce82bdd85c604360db0ff5aa4262c\r\nMac = e741166cfa2a58003dcae357d7a199b8\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 71\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 693cbb46bc8366086ec7cd7776f2c563\r\nMsg = 5a908ae85ff721ffc5096aeeda5ee83bddcf639e7be68d109394e5253c22dc9b\r\nMac = 9d56b03ef83082f601a9cc8730b0de42\r\nResult = F (1 - Message changed)\r\n\r\nCount = 72\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = b4190e3462e07fca26496adcb877724f\r\nMsg = 02097035a312cb02ea7f09fc1accc230a205e4a208e64a8f204291f581a12756\r\nMac = eb9604ec71aac0cacb63e0b369ae7664\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 73\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 4ae06c3b2940819e58eb24122a2988c9\r\nMsg = a2e7be3314238d7e4f604e134790bb15a87c09356c091b1aacb9f605b67475b5\r\nMac = 14b4507ae4b50cfe4989b544bede756c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 74\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 8d560de2e310ea69389221ce2e850625\r\nMsg = 04d9db45e4df19db757b9b95c25be43e822b8372ed148d49ce824a36da2b2f2e\r\nMac = 647f2874a083e82fa804b6c58c7b5c90\r\nResult = P\r\n\r\nCount = 75\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 0e1a79c5d734118c19eaba700f5da238\r\nMsg = 026470d57dad9893dc037b80978bf70c2e552fe46c8fe8c3ebf8338bda984d94\r\nMac = b936ff3bb8afb9e42351a2a3ad49d70a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 76\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = c88b1bc0050e19780ab53efbea175634\r\nMsg = 7207aa8fa87283f1f57019bf1c89645ff8fc36ab1102704e6d577671a9f7e098\r\nMac = c1dbd79e31c3b0bb824f16f735ccdfe6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 77\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = d87df10a53eb3ea24c003d2a65e44921\r\nMsg = fedd5813146a8c2af398d6066956829833b75e44b6e010e4f025ac0fad6f869b\r\nMac = 9dd7cbb34445bfb351d01e8cdb21d695\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 4d436a4a5c02b22ad49548b97216f277\r\nMsg = 2d73204f0b2d35806a8227206922ac9c18eff6ebddc73809179d67a702cf3e21\r\nMac = d2654d9bd6396075296cbe918d90670f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 79\r\nKlen = 16 \r\nMlen = 32\r\nTlen = 16\r\nKey = 8af7b74e35eb38f4086343bc329ab465\r\nMsg = ada1fa439c653d0cc88c0d129ba252e86c7d20a3087be93e920bf13d8e6f0391\r\nMac = 0fc9b177c874ea909b6beb1db1b802b4\r\nResult = P\r\n\r\nCount = 80\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 91ce6c87860aa84053f42e1abc16f489\r\nMsg = 4c287bc16196698d762d5fb428e801975fdaa29026b7b78dba968bfee0f534f27cfec57c6009c55c6261e0dbb14bddf76944d0c0648b910254df6c240e8a1a50\r\nMac = c1ce12f51aa823d0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 81\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = b7b774e5c9e2f6926660c48b8df52354\r\nMsg = 937273c7355e7b88a630d15be875234cacaa44e815f31997bf10b52c008cc3bb6d3724aaa0d7da0b391b252923d0eb6119575d346857d89af6af099883af5514\r\nMac = ff845eb2d77aa5a7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 82\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = d7572ed0e37261efa02f8c83e695efdc\r\nMsg = 85a327b0c7a31a4116e7fae0c0971e1578ab6fbdf90124b9ecacd0e70c909f51882cdca5a8b6b7e6b46d4660122bc9e1ae3932269f68e594075dbc293a2d4eb1\r\nMac = b8b3b7526419e069\r\nResult = P\r\n\r\nCount = 83\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 259129eb760f8a770410c160e4e13a6b\r\nMsg = 77d9c30", + "6aa257379053cf1f2043c388a301dac2a9e2bb89eb8bab6eb3f150fe391b7a3f628be6b4b649c5c108a108f0e0c55a0800b9954251ab07e94450a23d0\r\nMac = f9376f11cbec0ec0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 84\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6ccd61ed20f16ca7a78192f5b6ab5528\r\nMsg = 9211231ec382ecaaae57f34de1ac6bbb50741014a978160ce59c60491e64f30da0b8aa1442e42bc0f7e31973a0dd8c3c24eebeb7c329072ea7dd0b04bc163254\r\nMac = 94c275e6a4675d8a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 85\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 1cdc44c40efc3c0ed6fb84b0c2f78aec\r\nMsg = 818c636772036761af037c23aa8cb63e424f0ba0375b645de2f8f5af23d3ca3b9a5ca3951a6d02075a2c828eee326a2676ed8247164226b0267798632a519bf1\r\nMac = 74355397c7a29bb1\r\nResult = P\r\n\r\nCount = 86\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 2e523e9d8a5532127ec63b220838f11b\r\nMsg = e6d067907610109b8789e1ad00542539991677b9efc97a98d8bfcb50f3e334d0844323207fcb5a47e353e76d49dd573dbd17278dcc287b41dea8126cc7f07ab9\r\nMac = 7bd6745c6f73d92e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 87\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0eee5bc8994b723a580f67d45ccb194a\r\nMsg = 1dc4fcbc73dab4e73ed9d7606acdcd42b74972460c640fe50f028abdf255d9368fa3bc65b849ac31c8000eb47e5fade40ca167726aa927f2f043133d24ad0613\r\nMac = 486721355fff9cbc\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 88\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 388468d10bf0b770cc125f8b7d359261\r\nMsg = b9aaadfb3f60e48f1b421a9450129d75af2ce811ab0b1661680e9d5b147c38167ac7252ed40d916ae1e4519c3857d2c9dc2c538a106951b26d16433131438839\r\nMac = e13cef9392f4a80b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 89\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = edfe2e15edf0b0c28875651d4becfca5\r\nMsg = 70b1e2e4cf260b108f5a52d0d8234838ffd6ffe7b4acd78d7d6b95aa6342b598eaf402cb47396358ce61f8b4aa3a65bed0346e0036c3c5323f051f007aa58d0e\r\nMac = 7b70730219907d18\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 90\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6876df1a77e11165331a5ce2e0e6bea6\r\nMsg = 34b73ba208bbe1df06da768b0321243815df4ece555974dee2bf5732295f5ea9631939425e13c47681ae2ecb0bb85aa69be38560f5752a9d034222d91ad71044\r\nMac = 80e00df873439fe7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 91\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = e65d5fd5f446b4eab63d56b0a5eb1d29\r\nMsg = 554395f9b113c0f2a1f155de171d6c0a805c838beb90c3756e8b864dc52517c03d8cb894d1dceae092f0e8784c7775ac664ad7320afd246086b3bc9ef237171c\r\nMac = c60f8ced2efd52fe\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 92\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5bdbd06f4df6e15d644f3a635d7bb14f\r\nMsg = 4fcc7c2763a8dd5bfe74e34f512be8042af9ba1c73a944edfb616ad47a8d34cbcf192f3e8be3101bb3709b29c2dec39aee1913e3ac524ccb76ad50c2cc3a3e75\r\nMac = af33d5a2746bfa5c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 93\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 13bf2f72211cc8e16ac1986a22e19f60\r\nMsg = 8ee212ed4bd110ca6a91b37bca59e19ba842e3a1b50619bc6b07ec02a09303ca5c66ba56e870d0b627d95fe829431244fe4f9218c862418f14a92bd76b5a3a82\r\nMac = 18e8cd5bd42c75ea\r\nResult = P\r\n\r\nCount = 94\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = e9b913c2f0630562eb1c16b3b1ed8409\r\nMsg = 031105ff01daa66ff95834e47b6f5c683994084d0fcb84c140d1dfa2039a95933efe6a4f91af993d966e2e45677eb1e36159047928a38eeaeb5c9a64ea59f97d\r\nMac = f00a17da0fb9e6b6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 95\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6fa5a5991315702cba3beb33867c7bca\r\nMsg = bb0fabffbcc6935ca35755fd4bfbd192b6812cf75c4dc95bc3a175a1501be2065d7f57058cb7a5785a185dfff7e740a5551cf7c17e65051b2c6ef9509360e878\r\nMac = dcfd143f86442183\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 96\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 3f8c6d21ec05bc439bf82774f1812bd2\r\nMsg = d726deb8537bcd671ddbaff8fcc6968f951b71aa82dfc802a53aadb2bcc2ef9a35fd90064320798b311d6d32f7dd3cd90bca39d57991eddc36260d23b108aac3\r\nMac = 449e20567875d56f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 97\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 8ed1a4873bb37fafd4f8c2ee417443cf\r\nMsg = 1652c9539bff4b6e9f303f3e6b5d4b9ff7e85aa2a401ee8c2dc7b722dbaf6424f92ab9188882e2483405070e8666204f5a600b46949cdb830fd57433d63a55a1\r\nMac = 601eb06acc5a4e0a\r\nResult = P\r\n\r\nCount = 98\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = 83a4669cb9961448cf418cb83a16098b\r\nMsg = 26d97c3e28460d46216da39e043e024ed08e387b1e5fcfd3f962472cf1bac4676b03039b3b93927075ff41c87fe1d4a56bd9fa4784d283942787cdbdd5457f1f\r\nMac = 01a42494a10691ce\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 8\r\nKey = c9e6d0b3dcd8ab50ba5ff31d9c1bd95d\r\nMsg = 0d32c1cd73569ab2b10c67c167875fe22625358ed3469b424c5e052d4e49af2c97dfe1f947c972a08c938b327e01adbc48a7f57a89b49f49fa0fca5b50a57a2e\r\nMac = 476add8ee51b5e3e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 100\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 17281acb525b13653000ab45d86e7010\r\nMsg = 225750ca982e5b34fc62e277eaaa0f248532abf374933e572b0278566cc7cf980df26abefb493ef57f8477cac0bd19408a22e71f4ded84906996d8e7a846b5c0\r\nMac = 0f2aa7f2dffcf7df34c84d101aa9bab5\r\nResult = P\r\n\r\nCount = 101\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = d3624653ad0ed144667df0e0e355c29e\r\nMsg = 39dd298acc45cb597f0733572677f7102536c0dd86fcfcc44895d29af92a5b6a87c20f1b53087d4c874f4083aad32e877142d20ad87b1d8b7295587bfd235d9f\r\nMac = 795da5a50f5b7df40317616b5a470c02\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 102\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 813b3d579664cebe50a8e7050a0b4e65\r\nMsg = 78ad6517a09b99c1113d175f3129aade4d4a2516ebe054f15bc833d08ffe5e2a2d60c976e1b4b14cf8edd2c72baadb2db8001fd2b8798d39ac5ce27d592f1def\r\nMac = 20f40553bedb6496233e0b53143b6d10\r\nResult = F (1 - Message changed)\r\n\r\nCount = 103\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 21095cdbe94afa27d84bcd68276993f3\r\nMsg = 10525eb2794d03409faeab22a6d4cc4ebc0421daacb0e865b0f94eb387722897c827e31676debec9d49c36837b6bc234a95bc10ddcc7b1e5a0d9a1dca550e93e\r\nMac = c0b806ce5eaceb51b53b028e6efea9c7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 104\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 6c769a4822523525bb36c02518475549\r\nMsg = 4af38908fa44b46873535b39f432d9b3e677f6d06d8719af3d15b936afe515fc13d62566481fd0108bd95f6e8dbe32b3c830b1f1127d868273610aa834ccfc70\r\nMac = c1934b9c74127cfd515521df330c0333\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 105\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 6b454930925ca09d39e1e39a2e78fbfc\r\nMsg = 2bc884394ab7050c14d66fb8901cac109c0126668d918a4419bfcc5d75fb6bc2ba07f6598d06cf8cffd62f3eb29f6a033eac7490d27aa4701f0fb9f9718d1b7f\r\nMac = db19b8ef218018e5a53abcc39b7c514a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 5df295be7c44d59c44fead3f1988356f\r\nMsg = 3d7370cc2d61af35bf7b2ba50a143b23bfa0d1eff66c5ace2d8de5a28d17883d708fff7721a2977ee2164b6e34022c22523a0649ff0e40bc8134040fee02a065\r\nMac = 81b3181acbc2d6d2960ec57441ff3c40\r\nResult = P\r\n\r\nCount = 107\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 387fc73be9f019913f2222d98053f95b\r\nMsg = 944daaa76249bd9d3bd517d01b074920b7d4434d1a2618af902e0228c3fca658244d990f8ca42208239c42d4827cf114140cabebc2a72bb3cf9277ef008c1c81\r\nMac = 5de79be9ff9c3c9d64f9cce35b188648\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 108\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 7424990dee834ad05f4218861ab21eae\r\nMsg = 49fd56dec210e903f6c703332637f9c267eab9333e2701a16c74ce5e0b5a16d9da68b9c5d67bb6770a3c9a90a7e93fdd5759b27bcf3a753fa39ee7545fb60026\r\nMac = 38b66049ee8ed81f3f8ce2b45a4001ad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 109\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 232407986ad4a8e438990fd04ffa35bf\r\nMsg = 9d88a7970d4c58cecc20ed1811298a5b37297419ca49c74fe216679dafc938a656cb92bafb78efb31f24e71c2d5b5f994f6dfd82862adfd2faeb8c408fd22aab\r\nMac = 313d46dda3ccb75f497f9069c9478b3a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 110\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = d9bd6ac153cb0bc4e19e59c45cfe0d6f\r\nMsg = c68094c26c7f017b79f126dc26b3bbcb95f97535ca412da5f7853e15fcb52f042e6492c857c22b26ffca5520eabca20ee2cec2f0b71ea60383ece49232065e0f\r\nMac = 3b17778955990ae58e03feda7fc43998\r\nResult = P\r\n\r\nCount = 111\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 857fa35c6f70f637a9a5e6f215c694fd\r\nMsg = a1fc1307757ed91665980e2d3cf9778d8bffc9a84cce6bd5c5a07e47af5c1b409869db8286c49d07dd5083f1826e3ec441ce8cd36c85fef8c55fff889e761286\r\nMac = e1ddd63db51d3035adfd309ddc186238\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 112\r\nKlen = 16 \r\nMlen", + " = 64\r\nTlen = 16\r\nKey = 501f5c58355d1800f155f272dd09afee\r\nMsg = fd3564848ceb5d8cddfd50732956d18b4af433efc2e2a914ff66aba1de7b9b816d81a936f534f47038dbf1def7c11144b7e99ecec5fee6a478899cbeb6677bfa\r\nMac = d995f9bae6150996cd9b798fcbc623c2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 113\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = c1d636989dfbcb0edc9f014cc82da6b5\r\nMsg = 20ef1bbf8a719497797f1f1bc4617179ea682a24a92f0831cd215a01473bb8207e13f26dea1a467bde1ed638a51359ccd11210c4d0a2fb70c0374e8984f81f17\r\nMac = e4972a59db04f78da1728cab051faa98\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = b4bc5a4d40716fb06a359ef9537726b7\r\nMsg = 36594fae7b487798d62c2c95ccbf51c984df5ca6343465b2dd147c8b36a34028e53fae61f51b36b28529143cbd3edd0c077158a07bc490a79a06270940f7ed27\r\nMac = cfb3fce039ee2bb94b6961ff86688237\r\nResult = F (1 - Message changed)\r\n\r\nCount = 115\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = dc796e5d9b712c798922eef315cb4728\r\nMsg = d5755c40f52364343d2613420441afe9da9a5329d3c1e5a123ee49f5eb8ad47253f104f5d9776e08e9a9f74fadd5472326cc7b7c7ce61a1492474bc9de614543\r\nMac = 315f0ce76352448bbd8a5012a9907a23\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 116\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = b82fd283922e730a07f7ddb87484f66f\r\nMsg = 94e47b82b728d639777d5d5843de2a5c364956cb4b21cabdced2529b10b3f4275f307fbc352866d7b094cfd7426ae801aac17ac72335c04adb8d791da69b3c4c\r\nMac = 86e6a8485b43f1b258eb59688af91fbb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 117\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = f6db7efdfe73dcb4a26b8448842b55e8\r\nMsg = a1fa1fcd5f095b2768e32cd733365a136a108e7493f212aaef27d86da253beb6154f103099344ee94db6304e41b4e856db0ca7fd7ab462f45a07d697b85cca1f\r\nMac = f998bba6c5d3efd78af9ef57e7a38f7b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 118\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 3c1ba92d096fba134dfb4ef412b2568d\r\nMsg = ba7725d74465f5d92454bff794e0be51c4d0af7d88f729834d57312c528d0a7d15694a7e0bdc334093173f1d2df1fd42e7891c6b192dc5ee527b2ffb92c66d22\r\nMac = cfe6022ad29a54627ae7c4f907ef4da1\r\nResult = P\r\n\r\nCount = 119\r\nKlen = 16 \r\nMlen = 64\r\nTlen = 16\r\nKey = 4a92337f017a85b136ba6766444bbe84\r\nMsg = b0a3a8aa5d4bdfbb4c5c52acdcc60405c379f752b077eed42f2d7777cc0329047b322b9837d5f655ea445b578d9dc7e990a3c6f97cccc6cad7951ee948194e62\r\nMac = 153eff3c035db2fdc752ebd22302adae\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 120\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 305ec69b23e4490e0f8a5241cb9c8c85\r\nMsg = c641cf589020b94026ae\r\nMac = 3bc054afa9771970\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 121\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 28929286bd1391468ac75f5c03689f74\r\nMsg = 3813592f268a7a863c3b\r\nMac = bf1b514d2f899620\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 122\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 1b3163e2d3a471b9823525abc7543c4c\r\nMsg = cada03e8c967f9732a81\r\nMac = 53702fa98e6f9a19\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = be1ed49e2cb0caf6b6a0940c58453b93\r\nMsg = 4a348c5ec996f7a97ef0\r\nMac = 3358d143dff4adfa\r\nResult = F (1 - Message changed)\r\n\r\nCount = 124\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = f18be18df045ba31b80f3283cee6a681\r\nMsg = 93006a06d7e6df775b19\r\nMac = f3252f061dce32f6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 125\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = b9dafe18a904ba761762ec3fe0e4120b\r\nMsg = 173887316279a47fc699\r\nMac = 884f5b21d478d60b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 126\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 31fee08df80cc1009e661230e25939fd\r\nMsg = aa54ff7466923b265fb5\r\nMac = 03dd2a9616f653a7\r\nResult = P\r\n\r\nCount = 127\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 65a28d970b2bc7afafb4069c26d264a4\r\nMsg = 1aa5a3a4e6c5e5394e50\r\nMac = e0423589b192caab\r\nResult = F (1 - Message changed)\r\n\r\nCount = 128\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 6dc38e37d1379732df4dd535db88d17a\r\nMsg = 0093c6d94aed50b398ad\r\nMac = 19b08e65d391c491\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = c5329fd99848e1cdcfa406ec09745ae2\r\nMsg = 6d83d0ad7cc7efd0d2ca\r\nMac = 8ec2709e1466f8d3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 130\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = e608914a930b9c300b677afcb8689d63\r\nMsg = 146629e70b37d8b83ee8\r\nMac = db78a639bb15c84c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 131\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 0a998d3d390f5a80ad398b2070489984\r\nMsg = a91c1a8d9d268ad153bb\r\nMac = 5643a8c99b99d944\r\nResult = P\r\n\r\nCount = 132\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 2b6f78ceace47509a43ceb6b761e7866\r\nMsg = 3c0a41a78240c9d2fc22\r\nMac = 811acef50d6c1913\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 133\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = ca481f557306f9ce386edd0cfde375a5\r\nMsg = 9f3488736ef6e2c3a51b\r\nMac = 57e8a0e5965399c0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 134\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = c0dd1cfb3add04cd67a8e59be7ac8dcf\r\nMsg = a7c559c82776f429ac31\r\nMac = 7e43a2b43d030ff4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 135\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = d3130d9e5ef516b6bf172953a37913a1\r\nMsg = cbe97e14c3100c9fc564\r\nMac = db9f674a2d0e9ed9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 136\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 9ec8661a880ebfd15fd8b04f2ae09dbd\r\nMsg = eff803e0fc809cc48587\r\nMac = febec8d41b6bdc1f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 137\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 6c2b091433833a0ed915354dcb70d982\r\nMsg = 90f1416768fca7dd48d0\r\nMac = f6ada24319e502ab\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 138\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = bc79d444dff9d9e722effab07b068cb7\r\nMsg = 07d5a925b724e2443936\r\nMac = f964302c270af24c\r\nResult = P\r\n\r\nCount = 139\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 8\r\nKey = 1a15b24ba5d9648358f2c39c9da8512b\r\nMsg = 15b94910853a8f23dfb8\r\nMac = 8cdfbc13239e6aa1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 140\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 618fb69c8fb670250c306b3225687d17\r\nMsg = 7f54845a57d916866eff\r\nMac = c0d4db73891bb1efa232593407856808\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 141\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 8000aa080c127cbabfdfa5d9d9728c7b\r\nMsg = e53101e6eabcda32c13d\r\nMac = 5671badc409d4b170d4c861a0b3e1fec\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 142\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = b05b5557ab145cec2f00706dbc6a3c23\r\nMsg = 5e2f601395ec406fcf96\r\nMac = d00243508d25804548c4b4b512cb1906\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 143\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = e8b13346b61daedc1f9e3b49df8d1cd6\r\nMsg = 0593365419e0f75b6323\r\nMac = 871eb97850a776e7ad498467064484f9\r\nResult = P\r\n\r\nCount = 144\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = bc498326755503ff25d02805eb351722\r\nMsg = 9ece4c82fe9d38ef64ac\r\nMac = b5e88af50d1cff3d2b6d304edf042c43\r\nResult = F (1 - Message changed)\r\n\r\nCount = 145\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 4d248e73886a0e36b3ce7c6113477f4d\r\nMsg = 8de6fe3b24fd6c202ef0\r\nMac = c1a4f6d0ff7330171cfe570e900ce2c8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = b1b9fd78e3f8eaf4e8c91da62b2da534\r\nMsg = 482ea6f652067e8b791c\r\nMac = 63c6994c98bda91723f832020fa7d223\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 147\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 85e4e63341658144a99fbd17d94e3177\r\nMsg = 21ff834bec4ec6384522\r\nMac = 580c1e549a2ceca4743256a9cc972e84\r\nResult = P\r\n\r\nCount = 148\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 88b5448372548e6aab1b262630a28a47\r\nMsg = 36dbbff560ef04ea731b\r\nMac = 5fd17fd704baaf1ae6b3330ef2989dae\r\nResult = F (1 - Message changed)\r\n\r\nCount = 149\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 8cc76730ca47620d0b437112a2c93fd0\r\nMsg = c73be9f019913f2222d9\r\nMac = 2c73e2b5b84d8f4f3db1fc92831a03bf\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 150\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 7b657c640f155f1ff461c83cd656614d\r\nMsg = be9c5e77bf1b9dcbd4f1\r\nMac = b660ec36c0c0b4d987439505f1bf57e8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 151\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = d5044e9f10bd274aad4f7e605bb828f2\r\nMsg = d0be84df789c98dd125b\r\nMac = a26e513b09f184caf8d76d76961d1466\r\nResult = F (1 - Message changed)\r\n\r\nCount = 152\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 24d6d4bdc9fc4cd05b2867e9123acf18\r\nMsg = 0f9703a3454c25c0b105\r\nMac = 41676ddadb7b960e0269c8a59a6d9b91\r\nResult = F (4 - Key or Key1 chan", + "ged)\r\n\r\nCount = 153\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 6aa049d06bf66d2e2b65541eaa3730d8\r\nMsg = c562ab24ae5cdb7654df\r\nMac = 0d4d1196158fec46bfa754a526ba4a25\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 154\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = cf3727509577f1932bd7a92589c11e67\r\nMsg = 831188efc5d1f6dc9bb8\r\nMac = b5d162c885d7d4f6f65f4188d6582240\r\nResult = P\r\n\r\nCount = 155\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 0bc2fdd890c19882640f8d4188b88b9d\r\nMsg = 296828cbee50f41d19b1\r\nMac = e583d77645a603d841eaafa8860bfa91\r\nResult = F (1 - Message changed)\r\n\r\nCount = 156\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 5bab8051e2520b75673068b9cda93cba\r\nMsg = f16cba03402f9924daa3\r\nMac = 97f7eab25dc3ab017a9affc0e400dcc3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 157\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 7ac46e3249ca28e1ef0531d80fd37c12\r\nMsg = 3e9ddb8121760bffb7c6\r\nMac = c6eb13d5087d05b4eba2e74b283b7fe3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 158\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = 40f78f7ad3eede36e13bce222c6a4bc7\r\nMsg = 4fa8ad212ef73d37d48e\r\nMac = 3831419e62b51b7ced0d9117e48fabf6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 159\r\nKlen = 16 \r\nMlen = 10\r\nTlen = 16\r\nKey = a1f82c9924411e98e6f93fa0d07559e2\r\nMsg = 7d4748147575bc0113ab\r\nMac = c23dbc58fe22b34f7b007590558a3080\r\nResult = P\r\n\r\nCount = 160\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 84760f98ec565d281496b1295b25150e\r\nMsg = 9ce942ec81f8226506d48788e3acf49fcab6da22\r\nMac = 606c2f459a9ce198\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 161\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 3b6dd5169350b230774b02b9b44f06bc\r\nMsg = adb1ad81dac0ebc650d48f7a9329755a83f293d0\r\nMac = d7ceaa858508c476\r\nResult = F (1 - Message changed)\r\n\r\nCount = 162\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = f98d00755bcb45e6822121fe7cb03c8e\r\nMsg = 7064a2491f716f4a2969815e4a281a54690ced9f\r\nMac = e14634c400b9f561\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 163\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 5d27cb435e7724a246f158576fdbac68\r\nMsg = ee8ed4c12b0cf7c03bf91fba31a6a7b2d64c36c4\r\nMac = c10b474c0077a39a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 098c12058a0bc5951fc092aba322e1a0\r\nMsg = a2b76835229017bd0e8167a40ea1e2e18cc5db0a\r\nMac = 1d44128c3db0f7b9\r\nResult = P\r\n\r\nCount = 165\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 74f7f6516a17d5386c289756240241ed\r\nMsg = 8eafce9ba466fd53eb87f499d7c76bd486db0e90\r\nMac = acd978e0065375b6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 166\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 013bba67d26c7e52ae48dda3b67c9c96\r\nMsg = 48c0d53b85e6fa4928d3e9953afb9b451bc91a48\r\nMac = ef41ce0d30baece9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 14cea4c46d837c9439b088fba0e9d85d\r\nMsg = 3477384c396a9e9efb3e169722cba779fef240c4\r\nMac = 902158426696c229\r\nResult = P\r\n\r\nCount = 168\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 24f7b08fc2e6af6402243e22ca0626f9\r\nMsg = 914cf55a3fc739b5f87ac7518cc4171b4499d951\r\nMac = b775a3c1dc11d074\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 169\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 35b5428d440503773f30748ff843be68\r\nMsg = a5e5804cfdded4d610d1b05b7313ece84f369ccc\r\nMac = 6dac0947366be803\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 170\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = c8afe4e5b1d019c2efdbeda65d874ba9\r\nMsg = f739e632436470b5a1db9fa9796ed384c0523f40\r\nMac = 04c8aceaa8f8c3a1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 171\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 05a7910edcd7252b37e6d3d080a9ee90\r\nMsg = 702db7761abb9b5de41a86c8659270570be9d52d\r\nMac = 889a990539cbc30a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 172\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 4c8b0850eab7b212ad96dc7a032f8855\r\nMsg = 2de32ff6ca41b4c97424b121b8ad4edb133c00ea\r\nMac = f5ce7f46d457ec37\r\nResult = P\r\n\r\nCount = 173\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 687bcb63755f2b5c7daf4a154e8525a8\r\nMsg = 02778ca34db1cb5df76cb1a7619448f67d63b26d\r\nMac = 49d48bb0a684c6f2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 174\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = f8c4e562fde4379b08e512b0132766a4\r\nMsg = 627868b46ba546252f4eaa1c25205ccff72902d7\r\nMac = 5459c0ac5bb6701a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 175\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = dd235b05c15479dfe0326ba206ac784e\r\nMsg = e044ec24ddc0605bca89925a4ebc0234811e2a0b\r\nMac = 5ed0a03da09555b3\r\nResult = P\r\n\r\nCount = 176\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 665c2d7d6e69c2ce8f0d06b41038b83c\r\nMsg = 4fcd7541000cfc223fe9da6a030c681d0fb926cf\r\nMac = 1f022feb38ae6131\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 177\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 2efb7cd914a59b6ad63b7d1812f254db\r\nMsg = 67c9fe3e163787705a20f2fc8c468c4f771991fe\r\nMac = a866d6a31c0b42e6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 178\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = 74f6fd37ccb4b7702bb3a03b7322c0d5\r\nMsg = 011ecbe98c5cb7734476dedbb852e2474a5ad594\r\nMac = 707ec713b9bce5d5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 179\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 8\r\nKey = e673b3a954a00082cb7516ca9a54d9a1\r\nMsg = a6fbd41a838bdf0fab3e7b56c27a8c18dc4bf970\r\nMac = ad4dfde057b54a27\r\nResult = F (1 - Message changed)\r\n\r\nCount = 180\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = ce5bf070678cb07e963263b1562ff793\r\nMsg = 2bd10c4397a19fc79a307116a0847e0aaaefe813\r\nMac = 299e5910f128a1f091dfb6b70f6a60ea\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 181\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = bf144c9bb974729aaa1188ceefdf85e1\r\nMsg = 5e1ef2ad86ceaf5439fe87d2ec9bc41b52e5ba01\r\nMac = 58b4a32ae55966e42712721363ac9eda\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 182\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = a0cd07b684bb9e0e6692e320cec4510c\r\nMsg = 6e1e490a30f0c9e3d3b79f1c36aab742bd67c585\r\nMac = 24dd518ffffc1070f13d50d0bca42711\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 183\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = e3ceb929b52a6eec02b99b13bf30721b\r\nMsg = d2e8a3e86ae0b9edc7cc3116d929a16f13ee3643\r\nMac = 10f3d29e89e4039b85e16438b2b2a470\r\nResult = P\r\n\r\nCount = 184\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 4073251950e3331d03d67a2399576d28\r\nMsg = d5dfd0321b26e578fe987456ff061dc1cdaa4161\r\nMac = ed2823fb8fcae918064cef6211646e50\r\nResult = F (1 - Message changed)\r\n\r\nCount = 185\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = b08f47101365111133d974e8f0206507\r\nMsg = cefe484955fae117649ec158416a7439f29a596b\r\nMac = 3317717c6c0b138275090ea961c8d58f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 186\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 166fb8d0e110124c09013e05688605ee\r\nMsg = 24c65f715742da7d06046c783a35b2648180b4f2\r\nMac = d27901a86dbf0ed8bde0d69203646b7a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 187\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 20f6f56117758ba47a08dadf93a59056\r\nMsg = 7514e0f402e73d9c0b0576782011b2e6b2080a6a\r\nMac = 11cda489b6dc0ab48d111ee6cb26a829\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 7fa6ef35ad594a09cb74daf27e50a6b3\r\nMsg = ac0d616ed7dd3c3e86b3507d9f2bdc3a807d490e\r\nMac = fbad2fc6c9d0e5d21b25445f499eee10\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 189\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 815871a8300471dc325f8289d0d37211\r\nMsg = a8ff31e90556236cb4df078943c1f2528b42a7ce\r\nMac = 5544c93de980bcf653354ce08aa9dc3b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 190\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 06aa3f6fc20f867b42ec234a1bcb8665\r\nMsg = 25df5cc617e6e68be181694721a2a112a1bfb7c6\r\nMac = 2eeb7ab470caea3317a6336f5eee24a6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 191\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 860f8fdb021b1974d40e3d4bc41fa967\r\nMsg = 6c982a616510db422cc2f1beb955c3e7a88b6097\r\nMac = d2280a55cd0bcd18846b4e30db6322bb\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 192\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 15105c6285a9015d0edd414d6a806bd7\r\nMsg = f1cc55636836e67909ed3a581de20630226dd5af\r\nMac = e9cc5799a630c6f26087c1bd3b6f1791\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 193\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = b47aa890b03a8ac0dbc8f96c30fdf7db\r\nMsg = 58b06c99e0d0256cb1c556ec3b48a3bce73450a0\r\nMac = 3376cacc247686832736cea7e67e13af\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = dd057368033252d9bb2081a0b1a0229e\r\nMsg = 81de8f50fbe35f7ed95430e74d28666c885b6100\r\nMac = faa08c5a3a4ffdce81ca31873197d0", + "35\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 195\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = baf5afafd7d0c8ad42a44e4e0a90fd2c\r\nMsg = cc5a4209a6a60dcf12621e17150b4576b918732e\r\nMac = 5a43002d9144a1d5e48c2dc8dc167a52\r\nResult = P\r\n\r\nCount = 196\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = fa6405355bfb5065dc81e764d20277bb\r\nMsg = 5dd1febed8e94d4715e772c3295b48eaf471daee\r\nMac = 29e96ce5ba930134670b3c68b5c512f3\r\nResult = F (1 - Message changed)\r\n\r\nCount = 197\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = ad2e3d3af6195e74b3e43296b1f618d3\r\nMsg = ca776f79b8581014ae58a4d533b60483fd1fbbd0\r\nMac = b32ce1f493b126fccb9829d4dbe76382\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 198\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 04ae7190f0cabd117d30a359f80b720c\r\nMsg = b885e5e147f967032ab2552829a6e09210c44a45\r\nMac = 9386d73a01960ab399bb7d290674b21f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 199\r\nKlen = 16 \r\nMlen = 20\r\nTlen = 16\r\nKey = 51fdc65f6bb0d20a3c08ac1493ddddb2\r\nMsg = 1f0a56fb615b594d938bb8a27f4b2f5463ee9a61\r\nMac = 8506fb1b74806381e2654c8764464d8d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 200\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = cfb7e930b838dc3644f6c06f2ad0c8d1\r\nMsg = 611db4c194dbb54d80a4f4fa731cd9a6a330eaca734d3351f2cfebaba4bd541d86b3e35b4c1fa158edb0d15d610cd359a9c24878117f77f6b284f0363a576e0ef0\r\nMac = e9589a711f5d4a5a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 201\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = d179dfeead9d765d000462785459b1e2\r\nMsg = 795ee78ffdf302f3f1f2b31629ae918409cb42979afe3752dd14968d603678520e6b55884b5ebcce416248aa74b3cfe39dfedc2bb5246001503ca4d62cd7826f0a\r\nMac = f16ea84f554dfb54\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 202\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 22b7eb25e688672ab0e17206623094b0\r\nMsg = d830b16fa236a1dbe60f6db8d7e81a3ddb5f658c9f446e94639cae3699ec2ea6afb4fb152939d58df287271cf4b73c34e66eaf5265a623de47b135522c7aaf9f55\r\nMac = 16229efcb7523025\r\nResult = F (1 - Message changed)\r\n\r\nCount = 203\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = a64fa98b4662d801159f61eefd1c8bc5\r\nMsg = d5982c462ad40458660cd7b120ce07fce9afe812caedcebdee536ac19b5d561d679dee8ea85d62552c86093a2ac1f8d179dbd4fc006ee4b16ebe6afd2be134498e\r\nMac = 2f9a2fbcb96461fd\r\nResult = P\r\n\r\nCount = 204\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = e4fb10325d18666c382e6cc2442381e1\r\nMsg = dc28484ebfd293d62ac759d5754bdf502423e4d419fa79020805134b2ce3dff738c7556c91d810adbad8dd210f041296b73c2185d4646c97fc0a5b69ed49ac8c7c\r\nMac = 8f771ffe0c8d3445\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 205\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = fdcd3459061c36c9a0daa0dcab2b967f\r\nMsg = 1cfa3342540d03ec3fcc8378c021443ba3321fbc26dad7c5b859faba004a082a21d6d7a43d2836cc3820d1adbe4c55518714d48fd9346a254f702107da8212f605\r\nMac = 6635f9e17949a14e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 206\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = fc593384e6eebc508d181fc49ee10e56\r\nMsg = a6c891c9dd1fcc982c35bc74cfe71651bae424602519672b466d80e160af51eefccc5fcf76467a25bce1a10853a0209d9beffbeb53228fea5f1e77ddc956ade207\r\nMac = 7a6fd94e3928d2a0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 207\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 4e4ff248f591ca27665960d9357a8de1\r\nMsg = 198d5c9c4aa35d12b62e8c4bf6f3f141e6ebefd8ab396c71f55e32bc82b094cde409547383bcc4c5e5cd2cfd2d616c8ae273e260f2c98e93f7267424b8c2421bf3\r\nMac = 9140f91a0cf70762\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 208\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = f20826990acdf225d9451a3d22f89747\r\nMsg = 03d340904ace1cd52d4b72a96d96afd77aee68ac3936415005ed0d56f46036915b1e5f2994ad49effe7bf3ee46170642e5a16f2eea804e68fa520fb79529d6c09a\r\nMac = f30b668f16bfe6c4\r\nResult = P\r\n\r\nCount = 209\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = c231ea8b75c65de68c49b76e7a3128de\r\nMsg = 5b50879191a6debdb96c0bfaf9086b7dc6e25594416b08d2c75fe16cc347d2e3c7410fe3dc030a6c161ea22f6b80973bc43d42d8558f83b32a1bfa3c03757a4d62\r\nMac = 65ba53ef4711e807\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 210\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 8ef18639bc8c831dc0b4aeeca25eff4f\r\nMsg = 094c4d9baead7c5acd7dc58f3b4b4f57f1406b4e6af81a034d90cfa94c01760f4cacb4d2c63671d16d9594e1116b0dc2c39319523afac10175b1a485a240f7cf3f\r\nMac = d84f89e16c3b1633\r\nResult = P\r\n\r\nCount = 211\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = bab9d79aae4a1b282d8c5aa35d5c0876\r\nMsg = 02815f53c2be5f7246d4794895b4b15b6c3944819dfd3051b371f6d7d52d9f8ced84fd84095c33ea013c78aa5aa7176d6aa9bacabdafe9bab89cce4d7c183b9c0d\r\nMac = a01f976031bc8140\r\nResult = F (1 - Message changed)\r\n\r\nCount = 212\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 42b97f583f64d88358885c66add5d03a\r\nMsg = 187fe16a764c0987a28088f5cfcf55a6b9591b6395d2d41043e09932cbc4b8ae073d08d39da9799b316eef2ed89851a8cfc4dc1c6d3cbed95663e0ecf25403e61d\r\nMac = 0820b1ca0cd34e5f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 213\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 4fd555bd3a5253a90b68b5d4d46bd050\r\nMsg = 1ef253c61ac8ac66734ea80eefc1dc077edd660dc3518b5ecf709f10302925a72a3938e7449f2ae707506a67022dab63113242e9dff0d027aa3d22c8462a558165\r\nMac = 3770a6cc988a28eb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 214\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = d3a8eb3f9e5fb264ff098d85c28dd763\r\nMsg = e97a0986bf75e0e821f5adda80778863d9d479bd8ac3e7fe64a053f8016c465d581487278ef6923610a1463bdedcded62aeb22fb210dde9a0949947f8c6a6e7753\r\nMac = 4947e6e28dbba216\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 215\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 3043857fc40be37fb0bda4f46894690b\r\nMsg = 14874a8b59b0178c5ec89cd7316d909371969c1a1a1bc8a29f78341d39ce085e7e2aad7c350a3e7b691d3929bc4b7b47fef56be9fe7e7520a00abad5308505f8f6\r\nMac = 1a8c82e9109a68a5\r\nResult = F (1 - Message changed)\r\n\r\nCount = 216\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = b325d425c810d22deb3209f29c5c1377\r\nMsg = e44c4202499440c12109296a35dfb1f669f97e7f415cd251a5e36943e134a548f0f2e841fa3541151b374c04665053382a24b99d731b99f3d411aa22644f66cd07\r\nMac = 84faaeb5a9756a27\r\nResult = P\r\n\r\nCount = 217\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 7cb6a84e99f5573c1eb27c0078f2127b\r\nMsg = d7fa7be9c10252d6e41bc1a08195a344ef77b81785cea6b4ba453d398bf6ffb31d80e0d6a45a4af283676422b5ca94c76bfb4334f61ae0abe884278976a5a3bd21\r\nMac = 64fa7f9284c24f14\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 218\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 00341fb81209c2abdfe3a9d607b98277\r\nMsg = 74f6fd37ccb4b7702bb3a03b7322c0d5fcc657cb2c3f1361488d853589d2d6207359b65d62d896ed66f217395000c2fa0d11f956332f2d4bdae55251adfe903b41\r\nMac = 4cf05b6e583c70f9\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 219\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 8\r\nKey = 647a5be8a66c83b4b238975388e15d00\r\nMsg = 0db33eda4188a9165147e24e40f79fee1985eb68d51627287e9c4ec995a77d89b27fb2fa6a6fd3fb7563f3e710b6d20ca145a25f9ac8116d9f628395eb769f75f0\r\nMac = e8ef4f3cd7442246\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 220\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c98fc3416457d9eed0fa7ab1dc1b8a6a\r\nMsg = 190ae57ab8bb70464e4a10c112a54c646438301b5662f3536c26d754a02451d1a9c76abd7dbf656115b2a2ac702ec2cadae30cf86e0f0f96da39897d6222889428\r\nMac = 1bea94a457b2886e9098bf3ded932a3a\r\nResult = P\r\n\r\nCount = 221\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 87428d5a53f750abdb335f70ee13b5d1\r\nMsg = 7bb0c2ecfd141e7e93a897b259732b6153af3542eb7289b1a18dc0aefeb4d129c9e0e27d7ef25d3afc9945277e75cb87cc7d1c9cb39e7e6ab2a49bbdf65e1c6d89\r\nMac = a854d2da46afb77a787f0606a69cf467\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 222\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c725d9ef0dc6cfca84865cf5cc91d403\r\nMsg = d3208eb695e84c7a9250378e18be2f231ca3ebe72ba68e3ea4ff7bcf25206b43439bbd497e400dde738507cb542c7d6f961fb8bee99f0c8a6d9daf022368cc78a2\r\nMac = 35d57445a5f10fd567595fc668293e95\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 223\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 13e3fe7856cd680593a85cda3d6ff873\r\nMsg = b208e5a1a852caef0795150cf8313ee0cff06e3d28d438c2351484005661cbdcea6d8a3466aef0c6a460da4d7dc902ec99c073d086704112085a76dab0994fcab0\r\nMac = efb2bef5aae555463ebbeebe69791459\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 224\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 9b8112c1fb29fba2c8b0d8f16481b993\r\nMsg = f54105a04a4a02a1a07e020a6a4f4176e9c92bf40018ccac434988c650550c87625b84bd232d0e5ec20e6f6c46ba061b22a7fe36098bc7bf031ec6d6c1214bdb2d\r\nMac = 673281bc0effe92adfac4fef49477ee2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 225\r\nKlen = 16 \r", + "\nMlen = 65\r\nTlen = 16\r\nKey = 82e71e3ad1bc9a12a46e460a05ad9c05\r\nMsg = 41fb3dd6df78fe267175297e208ac753d50aaabd9edbf5e45385dfb47988b3d966f31be7a6329fd89e2869bc6f7e4bac1e3a0300f193bdc21c03d9629c9fefaa64\r\nMac = 36f7df58abb54a053988cae066110ecb\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b46e219217ab73c34904e24c6d995b72\r\nMsg = 887d6576572a3d8f6a1649394248c4d09d15026ffa930c0659508bac4243e7360802af084f363c2bcc4c91a04c6e86f4f8b22615d7915564949ab60b8267cb91dd\r\nMac = 10c1d8054ac549ad24ae4af2d8de97e2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 227\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b66edcc59dc9d8e34bea3baf4bfc0d5e\r\nMsg = 57caadbb1a56cc5b8a5cf9584552e17e7af9542ba13e9c54695e0dc8f24eddb93d5a3678e10c8a80ff4f27b677d40bef5cb5f9b3a659cc4127970cd2c11ebf22d5\r\nMac = 0c5864eefc04a6cac4f053ab2f65f851\r\nResult = P\r\n\r\nCount = 228\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c607f631d792499ea43586b81fa3e2f2\r\nMsg = 21ed22abc7bbb62fb2d51d1fb8830ca95b16213f56291af976274934ab0d43805f71d9b906c44973f7d4b59b7a94d35c2220e7405dfcee98499c1c1dc92a89d7d9\r\nMac = 4e65b3d58492a0eebb66928a8214498f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 229\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = d9e9136339d361949242e4d8a0cd6917\r\nMsg = 419b9c9b093052577837862900e7de29273eb0678bf6238223b59176c78430b6f382f27bc8d9a95b53f26f1d12e545ccb434fa0a21b84fa7badb5872e208254fbd\r\nMac = 6c81094aded51ccd4da38d0412e7ca67\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 230\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 6f349dd8b69dd41c6f246a1685115772\r\nMsg = a5a3c8afe5b84e0c3ba4f708a87b596d1b7c8694dbe691d7240e4e4815ad5aa4ca7e5b82c50989d092b96e80aa35e97f99ed79e75cf3b8750d0d263dc208289cb2\r\nMac = cbf41299c35e65fa4e2626430f95051e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 231\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c15e4e552c9197184b3eb0a74f5fffe0\r\nMsg = 7c4699a7d9e2d9f31410f20029676f3c97f5793f6732f95f6d33fd7ecc205d27b8e89eda803316a3cb9951f12111b4a6aeac606b43835a469eede86eebf63e5e8b\r\nMac = 77e77de5c5600900e5b928d4be3d5f8c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 2eda9b2c6d7ad95b644a8739580ab4a4\r\nMsg = beadccddcf392ee56a8913f057da183ab06ec538e581b52c027ff7f63574b32d8bc4116efa1c56f4a4a851695a87f5fc5f7c47b46fe67b0400f2599fc80fe68d7f\r\nMac = 948e63657b8b6e2d130f6f25369d6160\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 233\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 233088b67b741f07859d122a6a406d89\r\nMsg = 5717ed57ca0b6921f04dcacad34e0f6210c36673dc9f4d92493ff733c6e5f1c2e56805ef622a5f496049ee0ef51a0d41e9d363febb87070be558e8af61e86dc76c\r\nMac = c778152b00760fcd85bced0f58861d13\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 234\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = b7471a8b2e50fb319f198a09cdaeb319\r\nMsg = 385f9fb139dbf88561b7a500b0c7b835fe57e2698c6d9f76de4fae6dcd45c47fd8a0811ebbfba35f43c17aa360f09c767c1cd9b70bb671fa638e852ace97cc73de\r\nMac = 1a8b81be875a4814e3f988c274784a63\r\nResult = P\r\n\r\nCount = 235\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = adf072ebb71e3400a2175c96fb0007a3\r\nMsg = a49840ab727bf6b03015eaca3f15a2bb64fd27b51b27fe7a2e0559c287ac8fdd4294ca990799ff66974624b8a4539dade66cf7f06b35d8dd2f8a36e6ec0bc83533\r\nMac = ceac74b3af8750467e3b3c51624d96d1\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 236\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = 1b1d471add4e7f4fe197e3a4a44d06ab\r\nMsg = da06bd1405028d93fefa3c037b5ad551879451a28314bae86a7591b359f56e4b4e26e6fb2fe7b1af0f930cc2ae785d113e8b16546d59dbae9f41e7827be1ac89aa\r\nMac = 16d0021b1f9c00b37fefb60af3358d87\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = af5d4991c189dada2cb552c3c52d599d\r\nMsg = 1bb1e0efa2d6811d2370a039a0c47c59683befbd46c04257f86a468ae25ba03304e865e62afae77a62b3cec7b3556aae0c60475a7bfb02c69f955c7f60cc8dacdd\r\nMac = d7056fe01f0ed1b20adbe05cbccc544b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 238\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = d149441e667b245d4640e04c53ca6f51\r\nMsg = cbb34794bc8bfdf93d3c8d9f87ec1482b516b48b1e8a89b5e3b5df70c423a243384215b4bc69c76c6b18c497cf82088af74839a8c98895869a16294dfc094360d7\r\nMac = 64f5e8dce5c3e0f9cc224e306de70b87\r\nResult = P\r\n\r\nCount = 239\r\nKlen = 16 \r\nMlen = 65\r\nTlen = 16\r\nKey = c2f5d4837f9f75fb440c3bccad7c2e69\r\nMsg = 6a84594c4b3865f047c96038060b5b413db0d4e081c62e405b815ecd9e3be651f8b9075dc8b032eb2f87c1416a5fe4195f51defe75f671f9a92d966ddf18724075\r\nMac = df8c8c61e8d604e24c7e3d0115dbe898\r\nResult = F (1 - Message changed)\r\n", +}; +static const size_t kLen50 = 69750; + +static const char *kData50[] = { + "# This file has been modified to remove the 65536-byte long inputs.\r\n\r\n# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 192 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:38 2011\r\n\r\n\r\nCount = 0\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 771887708683bcb3577fbd0e6c13cad39955eafdc226d17b\r\nMsg = 00\r\nMac = a0db9bb6e8891e92\r\nResult = P\r\n\r\nCount = 1\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 733fd349c56d1086794eb20ed59ddc89b065bb8533b968c6\r\nMsg = 00\r\nMac = c76f82937b457105\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 2\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 761d74be5fae170a1bdfa16081b44c1e49972e15ce0818df\r\nMsg = 00\r\nMac = c65feb3d5336dffa\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 3\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 40f4a2261f154280a311f5b172c7ae34243cf2c59b98d37e\r\nMsg = 00\r\nMac = 05d920e78520839e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 4\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = e27150ee958b998c8a7e8b9324ead937d15580d09d6ffc3a\r\nMsg = 00\r\nMac = cf60783b5defbe3f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 5\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = d9bf5efb694089b2de533b1a65c12ae96d8c5bd75bd67fa5\r\nMsg = 00\r\nMac = ccde2029fb26c8ff\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 6\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = bcc658b2e53d51ed00c567ded2a124f8d1f85fc72dce5f80\r\nMsg = 00\r\nMac = 35d0d9ccab5b0f41\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 7\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = e31fdf3891c9068f621430315fb1daf418c328baf5e6da97\r\nMsg = 00\r\nMac = 8802047c11abcf2a\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 8\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 16a10208e91807fc479607cbaa39fa9c7273d89ce403b796\r\nMsg = 00\r\nMac = fcedadeca37381c1\r\nResult = P\r\n\r\nCount = 9\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 50fec559910391abc23eb7f5eddbc26a1031c0abd0a29ad6\r\nMsg = 00\r\nMac = cdc41e9b491092ce\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 10\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 6e9e0ae953b1b486ecd6b766d7b961ab79bcdfe2ffe95e94\r\nMsg = 00\r\nMac = 5096b9fc700929c6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 11\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 48043c405ef221c281d1e88246b6e1dda77e072f9d10353d\r\nMsg = 00\r\nMac = cab96cfcaad5cc20\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 10c361934fd6ff77a5051879ff228b08d841660d48b4067e\r\nMsg = 00\r\nMac = 167e7227d59d65e1\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 13\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 867ab71470f2dc3f5f11f8bfa7272dfc9c888e8e03323103\r\nMsg = 00\r\nMac = 96d9e7b084448004\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 14\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 5b10c228b447968267293ede9131d9345daa18c11d71eff4\r\nMsg = 00\r\nMac = f7055fcd9e8a8fd0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 15\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 997b712cd9295dc43cc19b40679f218c27af3e8c638d2e5d\r\nMsg = 00\r\nMac = 79a13778151aaaba\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 16\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 465b9364b3f06f3c28da12707673fecb4b8071de06b6e0a3\r\nMsg = 00\r\nMac = 945198b568ed3db3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 17\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = d233ef50e0ce1924abd315510464ce22de377026529085ce\r\nMsg = 00\r\nMac = 240698cd0183f002\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 18\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = eb6e828e01930a4b0afc8bda63160942ce32df7b2c38a8c9\r\nMsg = 00\r\nMac = c68fc388f0633ecf\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 19\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 8\r\nKey = 471b8a2e5cb08c21d87e9eb7ecff1d6e6fc2335581769dc4\r\nMsg = 00\r\nMac = ab5e7c91c35a0e91\r\nResult = P\r\n\r\nCount = 20\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 8b404993b4c3f62a57e4aef272788206c8076acc32cf3a1d\r\nMsg = 00\r\nMac = 6a3beff4d1d0e84ea4d4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 21\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7cccb84fa5c1c795bc05a05ea5bc6497acd2de2d193fba72\r\nMsg = 00\r\nMac = 557b8efe4ca9c4e603f7\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 22\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f1d434dac8cefca05ba120a34840531bf1542c8fd03b1ff9\r\nMsg = 00\r\nMac = e2c299a2c5159eb777cb\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 23\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7fac8beb476b470e13a404ded315db1b15a85c2783eb3017\r\nMsg = 00\r\nMac = 50faaf26afd61c5f616c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 24\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f5b4c2a9f096e13ab426dd8654fc7b8ae6a4a8d3daa16b9c\r\nMsg = 00\r\nMac = 535cde3d2c32788bf167\r\nResult = P\r\n\r\nCount = 25\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = f72879cc3446de9a0a43ae1cf08935b8c83f9265b8cb2258\r\nMsg = 00\r\nMac = 4eeea4a1847f2a30010c\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 26\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7021eaab074be980543cc70c809186d93652d7674c10ddd9\r\nMsg = 00\r\nMac = d98c93f4e0228ff68cad\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 27\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 7fd546397a9a0129861fb6815d419a307f90d259d55f3503\r\nMsg = 00\r\nMac = 13597bb97e38f400e686\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 28\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 563cfb49f1af034cd38d2112685a52ebce8dca93e84ca10f\r\nMsg = 00\r\nMac = 866bc21135b11ea1bc24\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 29\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 17e9555b9b4f89cb63f2e90aca95c27ead6a099bc41c4c05\r\nMsg = 00\r\nMac = b04b3bd1719d35e80e2d\r\nResult = P\r\n\r\nCount = 30\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = a65d24bd1ab92d8d294d654423412860e113c976f12ed76b\r\nMsg = 00\r\nMac = 83c1c0f3e89f6584bdd1\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 31\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 35555c801a2e7c68cd0c347e0f006be00fcce70fdd8d60ae\r\nMsg = 00\r\nMac = 7e3670cab617e79b3f57\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 138b3db9baca13bc66e893efee2b767ce6a912b172c2cda7\r\nMsg = 00\r\nMac = 4686805681afa38cb7c4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 33\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 1bc05440ee3e34d0f25e90ca1ecbb555d0fb92b311621d17\r\nMsg = 00\r\nMac = 1e9f80432b39f7318433\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 34\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 5776d94b577ed26820fb13c00ab0e2d1a1c3589bfdc45cbd\r\nMsg = 00\r\nMac = 4d5f56d3543abed97233\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 35\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 22e493c1f2e27c9be7bb07fc00fdd51089582d139b0a9f68\r\nMsg = 00\r\nMac = efe1c6493542a8412118\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 36\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = d52f030107a2becde77331fff0c24cd72ef62c0f46ae3e6b\r\nMsg = 00\r\nMac = d1b9c7f13b189cd828c7\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 37\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = be31363e5144d9ff49ee67efebeef6d9a97e22f8a3ceb209\r\nMsg = 00\r\nMac = 03228a1a80d5f3d87b56\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 38\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 6a46492ab7ae5f3dbf16ee7b8876e0b4f0449f3b4f8cd89a\r\nMsg = 00\r\nMac = f016af853140edf22d31\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 39\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 10\r\nKey = 89ef2284d8245d87f88919d4d2f71a2df05ee21d85b7d689\r\nMsg = 00\r\nMac = acdbd54bfb1f20bb65cf\r\nResult = P\r\n\r\nCount = 40\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = f4e74acdeb91d0f0ab143823102d5baed1ffe168fdb5587a\r\nMsg = 00\r\nMac = 9c15bfd3c766f88190e54d395e5387\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 41\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = d9aa4efa5d75195a400018bd38f7d8cd53fdffe88df1837f\r\nMsg = 00\r\nMac = 4a11b22e871b051ea74db3f763f140\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 42\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 13439fb32b1514d48de6002f5d12e19e1ced4caf35042602\r\nMsg = 00\r\nMac = 1412aad5e6b7f0d924700b438e0aaa\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 43\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = ffead92a4a5dc1eec6d2e441de9a9e1b7a88c607c9a79079\r\nMsg = 00\r\nMac = 6fb18d51e9a30fe6b7a6f405b3d3b4\r\nResult = P\r\n\r\nCount = 44\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 176ad1686a81992e042d6497a305038ba0cabf74c6ecd8eb\r\nMsg = 00\r\nMac = f676bdc753ffdad36628b1724b967e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 45\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = acd58261bcb2eb6345af7290b1d216c3016af6697bf5ab88\r\nMsg = 00\r\nMac = a6ae95e5a23b5f5a2dd8c8a520b9a4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 46\r\nKlen = 24 \r\n", + "Mlen = 0\r\nTlen = 15\r\nKey = 0b5eb52135dc6d9c1f56a2571c1389852482e7aa3edc245a\r\nMsg = 00\r\nMac = a46221058177012b073c6ebc6aff1c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 47\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 7bd398d1b9b45f7a024e70e71c1ee7132795fbaa2d63306d\r\nMsg = 00\r\nMac = 119bc07d7f3da0be3a87844b425c0d\r\nResult = P\r\n\r\nCount = 48\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 47575b64fd4797cda8d67e9cf115ae850d7998c39d2f8709\r\nMsg = 00\r\nMac = 3f2010bdcb2fd70241475db9381570\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 49\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 68627d802cfc43bb1a987e1ef4401fa84e8a7b2b43759f50\r\nMsg = 00\r\nMac = 1e0e3333ca5790a7e7df0d6d4bf860\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 50\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 7f16b90a18deec135d32c836063cde963fc4e6daa1555476\r\nMsg = 00\r\nMac = 013e1d0bfc7a7a6c838ac98ce0da2e\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 51\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 3c89c59ab30eba6e5be8f69f597adc534cb52e94259780f6\r\nMsg = 00\r\nMac = 7f9f1bdba93d26cc3c1f022244bff6\r\nResult = P\r\n\r\nCount = 52\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = fdcf28931c91b4b79c8f8332b4eeb3f995eb1ed2fb1e8ab9\r\nMsg = 00\r\nMac = ad7f8852f1bfd65dfbce3bb39db59b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 53\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 8f570ddd0963a80abec82caf8883eaddfd63cee9f375fa7a\r\nMsg = 00\r\nMac = 82b16380d804b8eef855afb5eb839d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 54\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = cc1d70d3050f022442093e3210f5b45f1b610dc0f12fef74\r\nMsg = 00\r\nMac = d1dc61c2ef7e2cd1a4e43dc34c0ba5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 55\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = a8a1cf9547543045fa2f00edf79bd85436bc1ae1d746790b\r\nMsg = 00\r\nMac = 48fc14782a351553ea453a3ec2538f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 56\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = 123ff732cccb535ec7a1c47a6b0ead68df31094d896709a1\r\nMsg = 00\r\nMac = 8f29dcec0a5d026d6fe4dc64cd1d4a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 57\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = ed06bd049d772cb6cc5a705faa734e87321dc8f2a4ea366a\r\nMsg = 00\r\nMac = e3fcf2590fa9ffe093bbfe8d3d7b0b\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 58\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = fa18c0b348aad167b7050c0ef6e7caf0436750873c7e4929\r\nMsg = 00\r\nMac = 630915919b6108770f5c3deaece1af\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 59\r\nKlen = 24 \r\nMlen = 0\r\nTlen = 15\r\nKey = f66296bf67b6e91d8ad629c1b260cb5ca1985273925e73fb\r\nMsg = 00\r\nMac = 729f983d3b49b2ebf24eb04368a851\r\nResult = P\r\n\r\nCount = 60\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 2f4a6501d8fe7b65f607757ddff6ed87ae0681b98b53331d\r\nMsg = 2361d2ed837c14b6c231daf0acf2623779e0d952e98e14149308807f79145c30\r\nMac = 9a8ad7bb37d79321\r\nResult = P\r\n\r\nCount = 61\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = e2d592cb412e65f9044257d78e7491f9f80c8b08102c2d5d\r\nMsg = 4163b7ad671761a3f27394776970b413e35a2c43ca85560cdd3c9b407bfadb4f\r\nMac = ab85ac3a4f92ee2c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 62\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1534e69565cbc541bfde6901bd6e598e41a7a703091c2240\r\nMsg = 85b78269899a4712eaa9c3de041f5a74766ec27dd5265da8a117c6f277baaa24\r\nMac = 6b177203b17cc7c2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 63\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = f0302d9a197a285909657d611ce12458b8d24652e91ffe8c\r\nMsg = 3fd6b98961f31c7b7fff0baf1cbb5884a9290ea7b5ee49915efb4b510b6ccd8c\r\nMac = d2d84fac8ecb665d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 2081442435626f7ce377132c46385510d9febfdd90c3f104\r\nMsg = c4185eb75fc23adff60d6380006a1c20fa2ff466ffddf67e99a421bfd729188b\r\nMac = 7373df1900b7a3df\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 715fb6fb464513f3650a9d0c3687980ab9caa9876d69dfeb\r\nMsg = d60b3402ad9f5f09375862ae7a370f0c744ffaf5001c80e3fd150730ab848689\r\nMac = ba39c81c18821872\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = a4d9f94e644fbcd97e0d993cb0af507eed259fbcf8fd7083\r\nMsg = 677acb68500d6cbbf77a3f34f58840f0c16044827641dc43d6767ce98f85dd5c\r\nMac = b129c1785acf17ba\r\nResult = P\r\n\r\nCount = 67\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 94b911cdc3137a6f7f32651b788eb82975660aea52b2c03b\r\nMsg = 549aa84bb182312dd016e3107f3b1f9c5b6a89b543561a450ccf713c76e66ad5\r\nMac = 7b92156f8b36d5eb\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 68\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = d3fff7b6f08dc4256239fc112890429fa00393e84e9b294f\r\nMsg = 15d1522654bcdce344b5d9753a0a6f31c859d547edf520478a8b5ae41506d5f7\r\nMac = 2d778849023fc9e9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 69\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 77bbda69ec034d73e02b06f0af30e2dab60ac80cb7822eb1\r\nMsg = 1e6ee96598bd014c95e9540f5cadfe6885cd094e04048e81633d1d634f065f09\r\nMac = d35f3c169f67b597\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 70\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 544a757bc50658d7e73b25688e7fef86fb1f9f08ffb33a70\r\nMsg = e473fe5656713b3b0e4fd12c640e8c542950577f446b01d09cbc41b6393ef81c\r\nMac = e1dad03ab8d2f432\r\nResult = F (1 - Message changed)\r\n\r\nCount = 71\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 1bebfde2d5468ba0a3031bde629b11fd4094afcb205393fa\r\nMsg = cf27b30423bd7e40d6b3aeb4b1bc01b40aec081aa00f2e3bc63ff61ac4b684dc\r\nMac = 617fdf927d0e4e42\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 72\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = ab83567833d2f3461b5fbecc0e366694bb5ea00933b2b3e7\r\nMsg = 58d43b9f1581c590daab1a5c56d6fbcff749e489acc3ed51ee6aeeac0104e6ae\r\nMac = b29232e882dcb8ef\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 73\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 0e0fece7b6b659b642668e8ba3dca330523e70279155f485\r\nMsg = d8c35129ca5a84e2e6723332217f0fd2e19fd06eb27d84a93b75276270f97335\r\nMac = d7ea4755260630e2\r\nResult = P\r\n\r\nCount = 74\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = b15763294afa61bc27e0785500ab5739136f51bc78b65562\r\nMsg = 8e8271b2758964fa71520f26aab6f870fa76ea4aa220475b3b379ec4ef8e80a7\r\nMac = 6357fb64482d171c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 75\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6dd6efd6f6caa63b729aa8186e308bc1bda06307c05a2c0a\r\nMsg = d2c9c1300f5a7520614550f9d23dcba6b41be6733426616f32912f155045282c\r\nMac = a12adaf849719778\r\nResult = P\r\n\r\nCount = 76\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 35631c844313ac335aa0d590fec472d805521f0905d44ca4\r\nMsg = 766f9ac761a06f4e006f405f7b3398aecad253f5cb8653e091e17427ff0fc1f9\r\nMac = 49090265af87c220\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 77\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 35008ef5baf263ae233758ca237dec1a51d67fcd3573094c\r\nMsg = a8f1b7b73100cfe1a03003331d9d55b75fb0d2596ede723fae9240581967ba38\r\nMac = af6c2ebe004c6d71\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 6f383f798df8f4b9f0a99206cff82709c367340c7b3b0401\r\nMsg = 9668a011e5a3a613ddfd149b0e529e9e66665006f98e730400adb4a8226283af\r\nMac = f97fcc39e240b547\r\nResult = F (1 - Message changed)\r\n\r\nCount = 79\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 8\r\nKey = 9071be7a11dcf7a062d582dd5932f047396fd9eb71982bcd\r\nMsg = a8a6703044010f8301ea33bd9a808ca35838c9f58683ae3925ab67b9e1fe1ccf\r\nMac = 9065cbc5249ff8b3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 80\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 36ad69f192ae4dcab771aeeacf01bbd32609bcbbea8ff9df\r\nMsg = 6e60fac7c027aed4632444a95824e61e2c50aa3ecdaf09ed9cec92cec35adf63\r\nMac = b6bf70e67b315c256f41\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 81\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 0cbb1d567bce009d1dc5bdb8115607213ed9a516389f728f\r\nMsg = 634efdf89ce2a9fcbd38bdc0b4cece54dfd7532880e0b4ce6eb3a4010b7cb1e7\r\nMac = 4f0af4ff9a9c9e844fe6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 82\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = ec65afd2d72bf477c7fdd9fbe3f1694c328088cb5f39d9a2\r\nMsg = 10d0e88b0db8d515bdff3a791c830b28e4e3ff4fa63f45b31a3f73dfb457bf82\r\nMac = 7172095284694f5ccdf5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 83\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = a76b981540ce229e73064af4474a7ca4a042d03a6e6bdcbf\r\nMsg = 740d4b25ca7221d0826057701a6bfd66c50a82f010a57be8c5efa0af0f761764\r\nMac = 94b657fb57cb2fd6ed3c\r\nResult = P\r\n\r\nCount = 84\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 36bf85bf63b28093d2dae511990a0bbd75184044b033c66d\r\nMsg = c1fbbae61b81ae", + "bacf151f1bccfb1584f3a211fe797996938c03e806392e14c1\r\nMac = 71796cf452f61db7f540\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 85\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 67b79d9ef1a47867c7d21f19f99ed1085f17a9f092fac689\r\nMsg = d354c54151c9dcdf0d0fd8c51413c2645efafb2bf6b680b25ad76d3825a4c04f\r\nMac = e324e8d377447b40629f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 86\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = eafa8699695431ab3cfa1e87ffeae4b822a391653d2e9d78\r\nMsg = bd647990f7afec76c8f726d1de806ca0cae6f708b5024b514f11c4320913724e\r\nMac = b0da9d38a1e821ef1f39\r\nResult = P\r\n\r\nCount = 87\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 1fc4fcbc73dab4e73ed9d7606acdcd42b74972460c640fe5\r\nMsg = c86553a60da69bec1924788fc3ab985158a2d4788f33c01abead80974d26dd67\r\nMac = 992fd0b735b9fa9255c1\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 88\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 618041501dfcfdd2b60d71c04d635f6357ad8b0643af77aa\r\nMsg = e7e6b57e74ce7afbde3697e2a69d61ca615aa3dfd32fe31f5521e6ca79877613\r\nMac = c183b8f21cb2aac7201a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 89\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 53bcc9e9244e2fa1752c61e65aa5c592138447ef9287fdcb\r\nMsg = 92e962f0086591b6f61c2ce5af62480722ba6a640c3f53806c421de438358721\r\nMac = 105d286777da3f2a03a5\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 90\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 6d2429921f90a22893cb65c4530e56068e9944d0b0f61fa7\r\nMsg = ea2ad7b7d3f80793391af0328fbb594d79898e1047210628bbc7441e135bfbe3\r\nMac = 482a75ec0ecf1ea59f5c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 91\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 3100d3c70e823fee9a1bf486ec1c56771acae35246535de1\r\nMsg = 4e6ddae0d805afcd10a055bce584c848d050fb29fe8f1c64b18e1abfe46b6578\r\nMac = b0deaf1bb6d0425d1810\r\nResult = P\r\n\r\nCount = 92\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 79aa6c03dde4bc5949921563264b440ebef71b3298da67b9\r\nMsg = 879954f977e945cd4db33d20e6749a6832677adbdd9c7e262e4acf632f665f45\r\nMac = 9863fe041d191777067d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 93\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 85467aa82c22ab019f9243c203b4371c95604dccee5d81ef\r\nMsg = b86edcc59dc9d8e34bea3baf4bfc0d5e117482a48e522c1b02a370e9124b379e\r\nMac = 54b2f4664eca96639f7a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 94\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = d37e7aa9215cb5c2c2fe81834f200192ada3dd0f4ccb9d69\r\nMsg = 064f85a23e049529c74c4f8267abbbe685b6a838841a9e304fdf14b835eee396\r\nMac = 536701771f51d2ec354f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 95\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 72e8c7d74cec3e248fe938a1159d8d969928e6da26b8cf96\r\nMsg = 58019989445d5ee855e0ffcf84e76f3383ae09cfad74276a3edaf05cbf8d714f\r\nMac = 182d3bf14cc391aef27b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 96\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 5f847950d2a5d44137110594d3c0afa995b36422ab36d044\r\nMsg = 70523bc397417e09d791a4976960e02636ca7144a5681cf7b116daa33eface2d\r\nMac = 5f0b325fbfaede23de5c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 97\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = b01e84220a7d514060a79088b754ac0beacb60e5b3a47020\r\nMsg = 036137cfed567fc5e234f18d6c2b8c7e9ae0f3fa526d6596e9a9ee7bf1abdf0d\r\nMac = dbe49af18c1e1bc99b73\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 98\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = d90ba47d7c9107b103cf167041dbd7b41d96016d93961917\r\nMsg = 2d53836a0437ccf27cdfe2bf2ad53f3082100a9f045cebe6b3031d21c9a6c5b6\r\nMac = 7252ee3b5eb76abeec9a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 99\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 10\r\nKey = 02e5a1306f612bdec098458cff3e691d93f050ba11ba6273\r\nMsg = 4bef96da992ab9386a3463213773f3ca7164813a15e014ab819f153386fa04a3\r\nMac = 5fac9c1a1636b66e2f55\r\nResult = P\r\n\r\nCount = 100\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 4c99ce359b8b82b67ee990529a10f2ecceadad456925a57d\r\nMsg = 89ed296a3ac03fbfb71422b9211799150b9d766a8116bebd48bd0a5068132dbc\r\nMac = e0e9583d784f87e0b7dd8fd7494a81\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 101\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = f085fb257ab64013b43a59150864a31e76c9ae94913a56ef\r\nMsg = b90ef6b773f250d4dac6fb9e62babad69ab424c96a8c0625987c030a91d27d64\r\nMac = 96f1dc9a1c668bb203428181c016ec\r\nResult = P\r\n\r\nCount = 102\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 8109f3208d5cda0f12141e40c85959b72eff1a937dae7f4c\r\nMsg = 49ab30d5c01e91bf113764342cb8ad32e6af945341a9c6a0ee2319a910416fd6\r\nMac = d13777a33f9520793eb8cbcec047cd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 103\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 1eba29062320df7275a51aa090ab489571057e64f0ff6a52\r\nMsg = 754f03c2e298a699568d10c3e40390e0f8c398283ce1c35dbc4916fe479b87be\r\nMac = 87dcee48dfaa43e8223a2b338b220f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 104\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = a04b976fa01411bcc9a3863cec91f486944fdca6e8754615\r\nMsg = abf45f39904a8f5766763fe80fa189ed9c6c15bb1a7a8fa0ae3058c9e5b87c63\r\nMac = 577aa39884335a4f66dce2a612515b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 105\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = c6f0a3692c9280c48393b0dd763e5d0b90477f34ad69f192\r\nMsg = 737bab64c8a0fd6a07329bd729d2ec88685cb5404bd13a40e095a61846dbacbc\r\nMac = d61ad5f6d8aecb7b3fc1ddb1aff64d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 106\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 095eb52135dc6d9c1f56a2571c1389852482e7aa3edc245a\r\nMsg = 47c577d1a7e69828b5c3264738dd334be8d7678ec77bf1ccb5fec3843f85ffa1\r\nMac = 4fd309a62435edd9b1ac8861f904c1\r\nResult = P\r\n\r\nCount = 107\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 2f853c1ddb31694985ea5e47322bfc8567fd7a74a46b0597\r\nMsg = 5719e671686e87e931c2c0e5842e907bf584d226e040645eaebb896b53a28c7a\r\nMac = 75ed56da2db0ffa101578118e3f620\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 108\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 67f5adc0842d7e1a4f8591d678334c95ac83df95c4341c30\r\nMsg = 6c8aaf2f91ba87b61814ed689331264c7bf98c2223c426a4ebbf7b0db692a8d8\r\nMac = b7c591522e9a5a4f3af3aea24121b6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 109\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 8702cfd1ff87a749ceb0a7192f5a872740b7fc600845df4f\r\nMsg = d29b6a2d421abd00a59b756af34bd72a42f5557a2ed40f8a7ea59b2e05ff01d3\r\nMac = 33b597665d375c95464af2ad56465c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 110\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 64ec1fd6af554485856b7bb3c0ad16fcd9c4ec690914a09f\r\nMsg = 0418a0afc13d6215c7bd68b12a327587eb63c145120ea626fce59c16f7d66717\r\nMac = 80a85e77efe4f47d8938dd9c55d67e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 111\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = f2991112c2cbd3038ae37b772a5090690006009f0c1965dc\r\nMsg = 231d72c9325f8c17aef4efc94855803eb2fc1eea601c84a98e8f7053840f0591\r\nMac = 14269c545a0e3d56ac9cb195cb6197\r\nResult = F (1 - Message changed)\r\n\r\nCount = 112\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 2c6d7fb9e92d98a1dd92e96f6b4013954ce1aaa5de242e6f\r\nMsg = 87ec7423f1ebfc37ee83c85938d58259efd16e3c8e55fb871e9998baa9cac81a\r\nMac = 782b7ebbada87c3572a3918a03305f\r\nResult = P\r\n\r\nCount = 113\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = d95a1b24964bfea5dd5a65f5a1398c6f9d43b26d98b47816\r\nMsg = 92f9cf56188322d18cb41d723847e6d419cd163e2be71b78e7b8dbdd099a99b2\r\nMac = 2498787836840fe1411a17f153c546\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 62f2490ba0c658848859fcbea8cc6774e24c9de979dd29d0\r\nMsg = 0822e3e6ba982091d532cd5271fbde25305d1f6e71880f81c618f267a9f122e0\r\nMac = ffb6c2a6c73245138ce06e458cf914\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 115\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 1841161a3752de1491b2b2f519d8447636e149437478d2ff\r\nMsg = 238e36b73b474de88226d4298121393ac9162f1736040bcd717b6e8db85125ff\r\nMac = 4d1656a2c8632260aa55a097451fe7\r\nResult = P\r\n\r\nCount = 116\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = d7d9a5f750078f1a82dffe2c70e6b0016eb42d13e1a8aad1\r\nMsg = 28a107d22fcd0499e0ea5aceda6dbc288a5f1d9da003c626bfb9a6c27922e9bd\r\nMac = b67bc2e20c422f9c7c27a84ba0bcfe\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 117\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = dc3ca30782c9c0a7fe8923d4b8d31aaf21e63895f51fb2f1\r\nMsg = 8716298bc17ed51aa273711873e2c2863e7a5021e46a183e6c6c81f99c02918e\r\nMac = f41b1896a22db30dac50b6b3e5e2b8\r\nResult = F (1 - Message changed)\r\n\r\nCount = 118\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = 0b6b36339122610178c4bb72eb558abf15e5ed9ea0077a5c\r\nMsg = 52839f2f0853a30df14ec897a1914c685c1ac21470d00654c8c37", + "663bfb65fa7\r\nMac = 665f05a489f8ad0feea290401b4bf2\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 119\r\nKlen = 24 \r\nMlen = 32\r\nTlen = 15\r\nKey = e200414db0255ca3faa7f6b17a62523f2c75d99f6ae162e0\r\nMsg = e749041b314f8719e17a8cb26162e2c910b31116dd769083149238d67792f991\r\nMac = 713fb4d0c95743ee7da970cac7f771\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 120\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = ea77165284ada4599f0bc0a41db787310f53a1588282b866\r\nMsg = f3a1a6dc2092ae7099bda65f8af32aa19796254a13fd9e0e7319d50402598faad6ccae2a028604db0d44690ba3530bfc8bad062cd96635d9654647c57bb81537\r\nMac = 9c7c379b5f8ee87f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 121\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 18e2baabdcebcd25958eb53d1bd2a95ffb9b51a3c1d92a9f\r\nMsg = 1df7392e915726847822817cb542df6b14df16d7d3d3ea8d615fe9ee651c938a0234bef059d139c350d6b01192cecfe1d821aa0b668e5d4dd8d5ef9a1eb47db5\r\nMac = db521506073b8c9e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 122\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = d39f12a9c6b63c17f116bc003f4def172943350e29d60258\r\nMsg = 75225a26d63e91281fb37ace46354f81de99dedfde8b770ea47f08503aea87d8d7b190dda9e150ecd1a2a182b06676da61667a04864ff4374838ee6899d8961b\r\nMac = 65aa057a01b390ec\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b2212ca369c611b725eccc3daa58df412787a3475f418d82\r\nMsg = 3727bac9706f482f55bda86dc052aa6810e2c1137b97fc93a65838a2724a9531199726517b6fed53b24d062eec7c22227ad9379b24da7658c0cf7ecc0368cfc5\r\nMac = b869a9e06994fb39\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 124\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 25e5fd5c39e684696e71a6f81f843a196dcd030ce2c07afc\r\nMsg = 899b48338d5ec3bb4a681f76ef37b6e25357b50e9578d85204c3753d3b6ebccf908e3de8b02dab01839ddf1a560b1ff33857a17fa4244b96612bbdeaa7d4913c\r\nMac = cfb0650c7566dc49\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 49bc9d3bcf3c22daa8cf55c1b59d4bffddc2412d60518e98\r\nMsg = 980026395d0544975dffaaa2c56db1df5816cd80cde513dc76f6f81d21f15c383c97c7233c9af2423fb28922efed2f69aa47c30de17ae1c5be17acbd0ad6cb8e\r\nMac = a7ed2a35c89130ad\r\nResult = F (1 - Message changed)\r\n\r\nCount = 126\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = c53f21f1ce3a1792a2de14277eb97664d4c561b3fd4b0e32\r\nMsg = 66e15206c23751497bc2c8d734aa1136aec08bd4e80fe3408bb3929a84efa749f379c7eb441872929b71872d761e0b448e0126e9fed86eeba611694cd2df4cf5\r\nMac = 1b86a912a0ec9f94\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 127\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6286e3e53ffb9bb143fcae724b45f86a23bbd74c42518144\r\nMsg = 62766e9acd41285eeed9b4007340dbb611699624274ad1179e327076135d907638c60f0c773c4ea8d9b8352027ee78ea4f22198f083d2f5cb920e55b9738c582\r\nMac = 3c56ff841dca9662\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 128\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 9c5d43c1a1269cde199509a1eff67cc83a1759b71c9e7a6e\r\nMsg = d576565a938782fc7e9b095db6213002bf5bbfdcd761fd6d876adb2c7947702b8930a5f71ec332bfbb4ac9b9d13d90c2d808d5459d0dfe5ddeedbe3e14038fd1\r\nMac = cc7b2038ead10d8e\r\nResult = P\r\n\r\nCount = 129\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 512a23489b8d6b62b63e9188c0ee5016f20448c082eefe82\r\nMsg = 1fdbfff7941ba22dd8e1dd13a05a3bd8f2c8096894266536c40a983929d0a6340af5233bbec1477363294519d3f3d9c6d41b20f18f76adb54495d9d43bec5afd\r\nMac = b81c76829839cd43\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 130\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 20d22c3b6ab38c5995e22b341f359be25616b2b8c7269510\r\nMsg = a1c041d1d4e7cd6a953f2e4837e3e676ed48633a2f15828f5f3551d5ad2a19c838a49caf75529bd5d5f89b3da2c2e9922ad8dc5d20325a7b3fae9dcd305f3731\r\nMac = aac4d4f4172e1f05\r\nResult = P\r\n\r\nCount = 131\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22e29aa7547e5ed3a64611e04f1d55f7a397c1619669879c\r\nMsg = 773b577b95e29d36fb30779d2ea23e2ffed9e1b46aede42bbe03a904fe22ef8f874298b5f4a6afe63f6ca9522863eb5cdb1c8d4bcd445e43e7302875e6ba3592\r\nMac = 16bf98c7a5deff18\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 132\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b320edb777d317af6c933a6530d9f5cb78d2d3104ac02120\r\nMsg = b31d3f55909bb660628de9eb95b75df776455f2f535f461edcfdf8a0cffdb096d573fedea7400f8374e62e30879a8beb259b3bffb4c3813a235b4c59853400c1\r\nMac = a0d9a7da024326ea\r\nResult = F (1 - Message changed)\r\n\r\nCount = 133\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = b9bcd0ae7100f991f4365ba0683b6d461979ffe86d0ecc24\r\nMsg = 19d0077952eba12a01db1d137050bd7e9102a31242eb38a5cfb3cf51b86c86cab57f6deef8e6eb9eb29c5dcdd852ffd627641013660b31abebd40fab60514159\r\nMac = 972119a55b125e0f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 134\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 00af010f462ad40a38eefb788b648e1cc292cd4bb08ebeff\r\nMsg = 573db0961531873316e87090f79e84f040c8358f8ca78fd9ea1ebeda82c1cff67c2ebbda1da0a1b233c1539cb4c0145da2a4a05431e06dac2c2731d59581a434\r\nMac = 92a67a99c128e173\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 135\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = e12f98507d6514c3b551d240595346bc9e9b6a987033b3c5\r\nMsg = 3927bac9706f482f55bda86dc052aa6810e2c1137b97fc93a65838a2724a9531199726517b6fed53b24d062eec7c22227ad9379b24da7658c0cf7ecc0368cfc5\r\nMac = ef48edc762db1d47\r\nResult = F (1 - Message changed)\r\n\r\nCount = 136\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 66fe8076d4e8538e18b84f965255d143f1c7d377e099c1c2\r\nMsg = b3fe18cbe086955384226c11c62c1dd14e7eabda573450d005b46fd9f9eccaff24dbf5d6d8530b5e25fd9f2a629df5c20a977247cab35255d71d992d85b04c14\r\nMac = cb67f0c1819ae458\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 82233a224ed122d7306bd6717a80fa1986964f9db41bd40b\r\nMsg = 65c46382a278490b9825d4f1907f3b9f196e136906067020b6b94ee398cb2f39ed07055dd0b151d974bb8d56ae3bc8b3b31d9054221514bd45d88a5f948ccfb1\r\nMac = 27e94d22e8961f92\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = d3e3bd80f45140cfc2f857a913a89f0c7dec86790feda4f9\r\nMsg = ff26ab66c6a10ef910f5b94589b24a7b6fae8e4396faa552b014603fcb5eee921bcfb81ffae989922debf24a6947ed6b1556c02e524b247c3966a7bc636a4fe9\r\nMac = d2d326c999095b39\r\nResult = P\r\n\r\nCount = 139\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 8\r\nKey = 466fa94c2158c1cd84b83fb2f15ccfce804f611ad0fbc4fd\r\nMsg = 5ea068d4f363dc7f1badf97b77ec85412a06dc8d8e3f4364265c7956d4088f014c78fad6c94be720ffb4ce4150da4a3f427f288031e0bdd241dd7daf975acabe\r\nMac = d6023f6ffd3c788f\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 140\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6f5a146524457615d81a605b38a5ff03edbc5c426ec7d551\r\nMsg = 9be3a736e7e72560bea45e9c8ee8bf37c279bf5b2ef16483adcc093208c05ee51a4db04632946ba2b96cdd9d15b33c25cce2eba4ede4f97aac29ebaa4cf6bbd3\r\nMac = af8fd676ee05154b82c3\r\nResult = P\r\n\r\nCount = 141\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = c62e6eb86b8daa37936086dd2c346e3b14be5054cdc2f3a4\r\nMsg = 559407bb6930d5adbdf19a7e285ba1dee5caa03ef54e3a3fc1b8c86a02f55921de9bf7d553c22d7ad915c6384329d664e70dffaefe22ed9c4e2c233706aafa04\r\nMac = e297ad7830c79d387ac2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 142\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 225557b0faca3d6cbaedec5c39c98f0ba0723f4070f2278c\r\nMsg = eb1383e84d4bfc5a9dad25374055b81eec74316b18f6e001b0623d470c027b7023456000fc61538b663cb7c0e98d77a7fc3ee2277816bacb4d9487c6741e3134\r\nMac = f07332a3b01d0e8026ce\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 143\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = c36acf733d310e3b9842b3006aa637ab092faf4a580043b5\r\nMsg = 1d674eb5d85945a6c7842042adebe549d4fe515501c06c1ba72961ee5bc98d8588afd6fd64893e21220db7ea6a973a420613130dde1d7f6a26677836d65bd0d3\r\nMac = d629ef50a784db860de4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 144\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 332e30ab63b197e79b86e4da732bad9250c0a5c9976a6c67\r\nMsg = fb41304f9f5b0f696ddb0e2f0f57bb091f8a31b5324d3cdf15c3bdf256d3502d06db2df9bea24c7ae08fcd641f199610427f3ecf24b92a7e00aef55aeba71516\r\nMac = 983e453f602db30e1f85\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 145\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b311796b0519a45c176f3ff458d4d818668093e82fb871f4\r\nMsg = ec1a1e9ee85cf960e5dc4e239619ed85f4b14d32cbd42dfa79f77a27f2cd740d08730de2eaeb91d0eacb8c498336e99b9a0c57c4045ef18749251dbfa733b4f4\r\nMac = cb2be0fd09f10deac5cc\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 146\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6311e7f0a7bcc11176fb411fe719d4e0782c8935524776f3\r\nMsg = 85f647d940a6d1acb6b7851912f807063515631eaabaa019dcfb993", + "e86f408266cace4c24940eda0083d8569364dc1afb816c0e5b95f3bafe7745e5ddfccd6b1\r\nMac = 776b9642c47fabd7e9c8\r\nResult = P\r\n\r\nCount = 147\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 6d120cbf74df2efffe98397ee303ead4e91c5e7839b82885\r\nMsg = 27ea9ff8359463a7742cd9c9c269ee678f4ab22091fdaf29b9007a92658687cbd71c4166e68c5a1ef30160191f6d926abb28f1da01da9ae8019a520edd576346\r\nMac = 5a902959d73ac97ea071\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 148\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 8e09d421e09dac1d9d966f02a3a520972c6aed2003d907dc\r\nMsg = cb32cb87ed59ee959c011211ae7cd475c3b5feb21cbafdd0b17796d47dc4d4e61da345b399c2661182485be13dcee33a9eaa8cc4b9742361f4c36f1361381f1a\r\nMac = 1b2bc5956223b8801456\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 149\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 3eeb143d4a3c08ecd9f7df8eba42789b517dfe99e07958ed\r\nMsg = 3292b8548a35fe34136457bcff52b469eafdb1b86b6cc88bed35c4cfba43785c59d6b01c1acb6870ef1e3ccf7dad20b1733f51ab1bc48cdb2fdf7d86eda17a00\r\nMac = 3a85ae8fd368cf9846bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 150\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 606452c62290b43559a588bb03356f846cecb0ccaf0bdaf6\r\nMsg = 3cfbc77b8897b6a5613f62f6b1c89b0d68f272c6c19b9e0ec6331ef616702006e64322d3460a57d3a5074c719811cb5dd78900268890da0ac177b40d48773548\r\nMac = 325aa552529e66a13904\r\nResult = P\r\n\r\nCount = 151\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = eac3a1a6eb8efe983c6b37b6c2709f5a8851ab72cb23a66e\r\nMsg = 2801a813dfc3f1c753f4f342a113c09b8e9a7ac16483c31bfd0b746b1db692f805937eec44c16bfbd132154557afb17ed01c1f4c55fe67f0343a6329441fb955\r\nMac = 5b0b383c4870af31a9a1\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 152\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = e2d592cb412e65f9044257d78e7491f9f80c8b08102c2d5d\r\nMsg = 3f63b7ad671761a3f27394776970b413e35a2c43ca85560cdd3c9b407bfadb4f1edd0e6026572ca0d8274bdaa6870749b0a727aa8c5b7e9442100e0c9b057455\r\nMac = 0380cb126c63bb48bdb7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 153\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b7b86dff6746145aa7d5bba73ed6a46da5b1200bd3520357\r\nMsg = 8e7f7e7e3ac2286bef6822ef47f5f73f2ff512e599df17c3723f7a55d4144a367c774de67e7e52ca3760c37484da7a2531d1d590b5380de11c34c3fe447edc0d\r\nMac = e7aaf6f82894d8825d80\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 154\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 70a26d985e6b99bd3a37575f011f2b84ed84bebf99a52760\r\nMsg = a2cfbcfdcd90e0962f233d7fb70668c8c36cd5e195e2ef5c043268f47187cecffdd36000f96e1f509f00283effa040443b3db15cf73d55c30c65f0fd7cf9c219\r\nMac = 96d09f0a799cb52575d0\r\nResult = F (1 - Message changed)\r\n\r\nCount = 155\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 5d678acdb2e6cc03537411ae2e95da120161ecb6c92d5e23\r\nMsg = 91dee0cd1d17d9342f4d346cee19f5f42e0c3b0498447ec4043c15bb2ae8fb8a7a02d2da489f28932c05fa4ea9c0760e0cf3052a97ed898edffce3247386b98c\r\nMac = 4a40b4f63330413918a7\r\nResult = P\r\n\r\nCount = 156\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 795846f9dbf36415640276642cccf87e3dbdf6519c5b2db8\r\nMsg = 4fc989f327e1a1cc7b8af618ee6ae6d25f78e2b76b681455336945655f13fd5a639bec3a004a88ad0e2df8547a0d315b8ba15f5269038638df6169d960f5ab5b\r\nMac = cc5efa5ef19f6cc63f83\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 157\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 61eab54142fe7e16787fd2d54829cd3c4bbd793e72f9ef9e\r\nMsg = 13f079b004d1fdf02121564f0a96b057f120899ce920169561d5e3aaeb16bb8e4347c7cf8c86f9acdc25ac26fb5d845a68409c0d9df0e089940fb7a88a76e62e\r\nMac = 920de91f34eabfc31648\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 158\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = b64d00f3a4df754fa4ee6376922fb67ccce0c6209f677397\r\nMsg = 8003586af34bdd0acae4f5547394245027c2ffcdc9d1335311acc859e9a2a7b817755a601dad14495d32f1ad811a7e751ac07cf18716e1cb193c203e7551aa83\r\nMac = 79e8a0ca036d7b0bd2c0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 159\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 10\r\nKey = 98f4596970e6515b5357f6c6396aac182d126decaddf567d\r\nMsg = 65737b65927aebcf6cefc7ca107fda8447e8bebf1f08a280d53a4b07f8e35904cc48cc08eda3c63a3475924bde1de6acebaa65fec5ee68ca22d3fe722bf33267\r\nMac = 05c51c2507108a3f8293\r\nResult = F (1 - Message changed)\r\n\r\nCount = 160\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f0409b050346fbd319c8630e4bc9dd6d055355fbb961f018\r\nMsg = 731db98bd990b2ea19f848fda3519b32bc1d2fcb2f4d42e13f655da8e1dc2af428c185fc01a5d55e20b49d643a254e8675d560301d2ea0c5984ecce39c655de9\r\nMac = d37deaceea7ea3b50aeb02636e5095\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 161\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f266cec01c5fc08c0bdabc9537bd1aa2df9f2b8ffbe5cc94\r\nMsg = e19cbaa489a0f65681c983cfee3a4b699339ccb096df06bc871398be9eb926d84426fd32d5d7fa4aa563a88b41afa822f761560d9897a9747cd85b3dc74b4adb\r\nMac = 8690d4f8153e56e3ab80c7e918679a\r\nResult = P\r\n\r\nCount = 162\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 6e12c112720ef346bbbe7d1c19483721b1c52c438dad40e3\r\nMsg = ab8b36f46d1749cde7dd9936df95cdc8e0b359b8963bff4e7bd59599b32408623354a15e29f287a79801866d434a0ee9cdf37f931e53a39509057c7f2b3b413c\r\nMac = be9e70fdd15f96a8b7457cb727caf6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 163\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = e9ed05813262fbe769c1104d8ba5c836dbd229a22a681de3\r\nMsg = 606452c62290b43559a588bb03356f846cecb0ccaf0bdaf67a18abd811d4315a966e2f3f87f6c2428814446563fa71864d97c8336b0e34bf9466ec95598398cd\r\nMac = 4b3ac19f4dfa04108283b0e2e3a8e6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 0c84328951c66e0f5341b741d2c2796d3524ef732c69e779\r\nMsg = 9071c45a99cb987aa79596a2014f54e6fe400a6bbd5de96e156cae87cf69762f1329d481213d213d42191312fd76911d8df4c6ad9304754909058cf477adfbaf\r\nMac = 1e1003ce7546009a3ba7f59dec236d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 165\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 3aa8ec246323db7a3953737928061c79757de2e921c27643\r\nMsg = 84e9cc9bb7f4fb62ae7396859fcf33da5ca6c80c311eb392107afeddebebe0d662a887879e4014187d2fe8feefb01e6fa0d35819d7cfbf139e99451423b62ee3\r\nMac = 4259d5f983a287fbd987e3badafb33\r\nResult = P\r\n\r\nCount = 166\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 66c07634c94dedb5d4c6f19e7cdeb954692ccf51fa242abc\r\nMsg = 4bbc9d3bcf3c22daa8cf55c1b59d4bffddc2412d60518e986899d6a3e2a781668b0c6b9b4ee0ddbbcd06bd643eb201fe7829699e4dc86e2a1b4876bf9e40494f\r\nMac = c40f872ea2f1a1b45ab5737c2e4f33\r\nResult = F (1 - Message changed)\r\n\r\nCount = 167\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 3b9d6b0652836457ec4f701f0dc0e5aed73d16585d61cb1b\r\nMsg = df7b23a4e4456e0152b24853fe0d5de4179974b2b9d4a1cdbefcbc01d8d311b5dda059136176ea698ab82acf20dd490be47130b1235cb48f8a6710473cfc923e\r\nMac = 602941735206bbe57ce1c2e3b9509d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 168\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 7253ef10bbc302f01aecf315f9a4122ba805dc4048c30ac1\r\nMsg = e12f98507d6514c3b551d240595346bc9e9b6a987033b3c50940442dc385634e2a28292856b97d5a78704388b2b6d0ff2ce7a19c64574deac593b98a7ce98bd8\r\nMac = 9e62a5b8851d3a0fcddf06fe116ac2\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 169\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = d718af395ba3f5f4c6d15c24475ec7f0f74f3238c81d42d7\r\nMsg = 0c0d3d7ff5d1b707be9648f263b8f013fa439978e959efef57d471cae02dc8e08d9d58d40381169afa039936f1f773c72003c1c5af03018725ab2408236ee4ea\r\nMac = 75749ed44b76d7ac16c98d8b6bc18f\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 170\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = ec98ec44f5a86715014783172e667a748f162c5c26a8b34a\r\nMsg = c0947efb86d54644087247f9fd95133a94075faf6250a2cc9f20df5393edbe1a4bdee20e90e877781a370a7f00cf9eee7373fc38acc54aba23b0df3f020356c9\r\nMac = d994553290066d778369b54ae06668\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 171\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 9fab32caed6e1cb27d2115cc641779127d4aa57db0955bd6\r\nMsg = 6e3e25db29da2c787bb37755ee770e2402fb8208da23389d36030439a143f971ecc880dfda90a8231ddebd2881981ca968ed45f3763a32ec8d2fe854fc2e4b4b\r\nMac = 4d3cbf9b68da0c5b49ab3b0913a2b1\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 172\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = aae24266e5981b2ed14213a29f961cbbf7f02f63a33c987e\r\nMsg = 8244cb416b3d09521ac2fd28c29084ff3d64761d46617b59e8b221de36702c2d3dc62e61375357b702cf8d4dd0f2bf2a1f91777fec0baf2c23e3e6865bae7358\r\nMac = ab8e9df7128f4857e0a1c24fbce473\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 173\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = b9bec4e88775777ff1eb3df671fe8ac03a693a1c26ea254f\r\nMsg = 8eaed4810702df8caa", + "12fe7e26e7ebbca11aa2de9f3169a8262c0e3c205a708f0071401aa8de09d28a5a6e590ebeb476341880c37bfee1a501229081eb27772d\r\nMac = 273b0d874010eac97ceda34232f7ee\r\nResult = P\r\n\r\nCount = 174\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 15120ac9468fa30c92ad87e7aba41ef552814e4ecbcb9350\r\nMsg = e3de6c6119d7db471136285d10b47a450221b16978569190ef6a22b055295603c9c1ed5da3bf96bdb43a5722cf4e2ea087cdf9b23b3093d250d44047be634b3f\r\nMac = 9a166994de85e5d60b154d49a867f4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 175\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = f9b9633f12967f1841161a3752de1491b2b2f519d8447636\r\nMsg = fa14d3656f7f7610f3a629bce14648a593250c6f309c02c6c552bb42984ac58db920dbc7d98f59295f37f3e9b99da55ef074ed65801b390366669b4c7aa1c483\r\nMac = 2c9f3650866b97ecc5ed66929f41dd\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 176\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = e87275bc62ad067b121b83f220d4ee2b4245541283dfadcd\r\nMsg = 6475757f30dd0a96ad64bde5c2605a9d2ca82a7223a9ba4c39b6dd3f86a0f4bd02876d0a32ef8af1071664b603862f4b9de6bfc6e7154b136e7a72e661957bf4\r\nMac = d0bd2d3d35a22f37bf113090cebecd\r\nResult = F (1 - Message changed)\r\n\r\nCount = 177\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 8b63d3c794e5ba0e09e5d5a5c56670bc0e289b30171ccfa4\r\nMsg = 44da1657e4be60d887a097e29d03bdbf5920bb0504e654bd963f58c487951a72e395237a9d32281125ed3a533c543de208c99bd063853abf79ddab4692c3a497\r\nMac = 29d04b97ac302fefa80f71ea378e7e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 178\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = 17039577fa27ef5ac3bf97572d9de5f8eac0aa58ff29b990\r\nMsg = b0329a0978e5a2d1bc85bdca333e7d0d1e9950217ee9547a84e76d3f49999451bf787288e8d12d40456c8214926c14e9b076032fe315c1633d5d21d85acfb1b8\r\nMac = 51b4bc8b479dbd60e5de94ba8b9d0f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 179\r\nKlen = 24 \r\nMlen = 64\r\nTlen = 15\r\nKey = cf6b5edc515882f8a7954a5d8517b1a85e9559858527d0db\r\nMsg = fde631afc6c042d77b579dab9298862d943be673cea59eab4a0c1b5cfddc2aef42590e6d8786d18a4646d7e338c2b984c50a50adbeff0fd64e7096f02e8385ee\r\nMac = 5ee3547a06661661c46c3778b0823d\r\nResult = P\r\n\r\nCount = 180\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7b6f4f158422f33543ca90dd0a76cbb23c0dbef26ee140aa\r\nMsg = 6704dc39a259152d2dc3f08b8799ffecf4e1bc38\r\nMac = 5c12ff63244c64bd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 181\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7a381f75058b85680061eeaa0242d3a16a64a5ca50cb61fe\r\nMsg = 18b31ed5ba1c3ac562ff3ef274424b86c0815c26\r\nMac = eb8f3d508c9edb8b\r\nResult = P\r\n\r\nCount = 182\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 3662d7b7c93211535c862ef3dc2724c492cc1e53a58f23a3\r\nMsg = 8ac860504258c134c6835d4cfaabdb316c36d99e\r\nMac = bc1b870eab5bea9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 9eac76976750b7937b3bbc6986b4c726f0d0a63310db85d7\r\nMsg = 5de2265292780222349ac793eaa17c5a22902344\r\nMac = a69594e569230df0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 184\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = ed1531500f319e09227d6bd181786b3b446f081abff2e697\r\nMsg = 7a734243e53cee654be988f5c735b19bb11f3389\r\nMac = 9f2cc2a8c3d0a34f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 185\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 85d0d04cd3fd2fb34dc18fd55e645f7492d5280657577008\r\nMsg = df899dd6b99cc28d66604ca92431fa7f442a4927\r\nMac = 18fc40b25fb9c138\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 186\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 90b0c8b542c91c1b2dfdebb589a7eced6c9b7b43a7729840\r\nMsg = 38d1a87296529595acce251cb232db8ede65581b\r\nMac = 077570fd0efa770b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 187\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = eceacd807db82378e9bd7c79054878f09dcb5087c2e1c349\r\nMsg = 09bf4f77a9883733590a3cc7ee97f3c9b70f4db2\r\nMac = 58af901fe0fb5d29\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 16227835305b7586a3106d93da8bd70aa0025df69a0e85dc\r\nMsg = 1a223362dccc99472b2cd1d712ec6dadd60ef972\r\nMac = c26f3980d17f6c36\r\nResult = F (1 - Message changed)\r\n\r\nCount = 189\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = d18cf5dbf5b2094dd6ad85d975449e2dda35b184633235ca\r\nMsg = 7f557e74f53c344daf7495526d1270dfa8fd24ad\r\nMac = 5b7cf33ec05b1576\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 190\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = f1681287bc931a0d8f296e13b3584d6efcb6ca76aa90cc02\r\nMsg = 08c62ff9bd7bcf189f530d5065f8764532d2692f\r\nMac = d646e2ec15afb14d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 191\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 116f4855121d6aa53e8b8b43a2e23d468c8568c744f49de5\r\nMsg = ab91d1aa072947d22f0dc322355a022fe7f0747f\r\nMac = 489068c07931ee9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 192\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 0a23972e036d62199ec327b25a3cf4e14c29279c6449d3b8\r\nMsg = 2df3e80fb6ddc1fcc7615330b24fbaa4981441c8\r\nMac = 7842f16a0cc7bd6d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 193\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = becfa1c96686b04153fae144c187f034dac3ee6ed70d867c\r\nMsg = a3a114679ce30c8472149da9bf3a42b1ffb07e66\r\nMac = 74fe19b5183ed3a1\r\nResult = P\r\n\r\nCount = 194\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 866b43c8fe3769ec0aeefd4dd02210488a354d67e82a81d7\r\nMsg = d9bd6ac153cb0bc4e19e59c45cfe0d6f4c9d20a3\r\nMac = a3a2ef83eba2a6f3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 195\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 7e00aa080c127cbabfdfa5d9d9728c7b25358aecd26f5850\r\nMsg = ce1a38cd75b9e955483ab53fe59649d087ecd1d6\r\nMac = 8375c666d09bf259\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 196\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 4bbf4c9cb6758329b2d5a53c4fbfe2d3df4fb50e57b3699b\r\nMsg = 6429ea2cc8fdaf58100347d21da64375b3ab2058\r\nMac = 77e417a60bca9a9d\r\nResult = P\r\n\r\nCount = 197\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 274b394da9402d3eafdf733994ec58ab22d71829a9839957\r\nMsg = 2b3d7949805afd73234cd327a62951b32c51df2f\r\nMac = 8f9ce09fee15516d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 198\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = d4140d988448d557454c3434fd77f8597e6420566845e316\r\nMsg = b53017500c100dea0511845597214484fc5f7f34\r\nMac = b9e85ce9178b81c7\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 199\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 8\r\nKey = 43d0d326c511e3bcf4f52660fc3c706a6a95c0ab550615f6\r\nMsg = 7c880698ef372304a663f0f02944500393585d42\r\nMac = 843f71e93b22f1e4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 200\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 273cc5013785baeb5abc79c8bde73af71085d7018e7be92a\r\nMsg = 086e6e3a21787acf7293446516b5f54da95a2988\r\nMac = 658a112d7a9e7a08c024\r\nResult = F (1 - Message changed)\r\n\r\nCount = 201\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 492bf7946bce1d3c6f168f4475e5bb3a67d5df2fa01e64bc\r\nMsg = f7b577f1396b23c27eb637e53d3d92460270b001\r\nMac = f2dffabed6871cca2e41\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 202\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 8e7d8a44244daa7df2b340993e32dac50e05d7b2e103be98\r\nMsg = 2c3c3582e026a3f29ffd21a92a8e1ee70f3a4147\r\nMac = 1bb40d091dde1903ac0a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 203\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = d2069266b0f180cb319e30ded7535bbe52d24be151de4bb5\r\nMsg = 392d567f0b8045359dedd1591517ded0171fdcda\r\nMac = c1ca2813ad38fd7f0f58\r\nResult = P\r\n\r\nCount = 204\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = f35c46bca9236830ff4bb057cd5764f02720ccb03b253937\r\nMsg = d4586dbdd5655cf659891f5b6015da524548dbbe\r\nMac = 4b6dcc78f6e0e9b7e35a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 205\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 509f1e38591e03a30a7409bc7e18595848253308c15edf40\r\nMsg = fd2109cac9f42fbb093a8675e5cd962c4c31df2f\r\nMac = 35387ef3967eed5b579b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 206\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0e9cf0ec43ca3fb7fb9a2b1999ae635d5041bf42f1b0bea1\r\nMsg = 65960c7fd43891ebdc7bf862b28d4822a8488270\r\nMac = 93c33247ca546a8c3fba\r\nResult = P\r\n\r\nCount = 207\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 51597a4c68cd228371e86c179fe04492642ad9b888405067\r\nMsg = cd8799124d94064f47d7eec59aff543b81ac66f4\r\nMac = 0eed36a27b40560b89db\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 208\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = f9f049328f5db22c41a501088e5759ef4d04db0c4b4f6d3f\r\nMsg = 7bdc26b5b4df58af539d91eb2ea10263a3e58b07\r\nMac = 68c45551f1367c989a9d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 209\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5343dacb05a29b3119d6f19bdfbcd6674950e710fc70180a\r\nMsg = 057c2d386fb1693b845bef585e76e0fc", + "4971ffb3\r\nMac = 372a801d1cd33d1059ba\r\nResult = F (1 - Message changed)\r\n\r\nCount = 210\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5987fcfe8a1ee76afaef54cb22d8b2a20b116f72bfc7117f\r\nMsg = 8abbdf380c668c6ff34a4f128567bfaf256570db\r\nMac = 5a8089b3d9f6c72fc858\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 211\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 301e0712ce74a1ad02079aeb0ce35edacc33f9a5d907cf70\r\nMsg = b2d894833daef4070b764361685fc94a780a7292\r\nMac = 57a225eca09fb227f79e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 212\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 144840494d15b2b31ad63ee05bf579a5e9fb98f534a6309c\r\nMsg = 71bf573cf63b0022d8143780fc2d9c7dbd0505ac\r\nMac = d1b2baf05cdd5fecd1cb\r\nResult = P\r\n\r\nCount = 213\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = b4bc602dc860108aaff5b3befb948a561ac495a22af9085b\r\nMsg = 3fa85ca50cc4c4817e951b5a95ac006973324c2f\r\nMac = daa1246b82d2e14e3056\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 214\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = ff48804c82414ff67f9b917a4d5d062d439454aad8eb4b0f\r\nMsg = 6def37d9b73fed0390f260491f582d2215369811\r\nMac = d7712f7d5f0da5dec6b6\r\nResult = F (1 - Message changed)\r\n\r\nCount = 215\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0273e421ee670be6322675f26f9014c040a76f0c869698f0\r\nMsg = d9de46934cb56e58899a31fd14ca64509131dc27\r\nMac = b3e79909c16c561eb7ca\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 216\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 27eb9812d3f7816fb6a1cfe474496e80750b1ed3959ec7f5\r\nMsg = 776ba7990086731ef7504947be74b3c455bfde5f\r\nMac = fc0f2dcf4e6fa041830d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 217\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = c56f710e39deed799ffde6d10e8aebfa2bab5e5e073d78e2\r\nMsg = f6fe0f16403182d012f8b6e02539c386075b4585\r\nMac = 6bcc4c1b06099220e9c0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 218\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 0236ce1fd3ef645a64b4ee7048dd35942e6a09e8099884a8\r\nMsg = dbf06366f766e2811ecd5d4384d6d08336adc37e\r\nMac = 1de717c402baf964e817\r\nResult = P\r\n\r\nCount = 219\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 10\r\nKey = 5cf781067bc1ef948e929b7287279c71cae5143631ca57d6\r\nMsg = a7f3fb7ed1342862247fb4b1993788837cc87041\r\nMac = ee867d4c0f910e9d9288\r\nResult = F (1 - Message changed)\r\n\r\nCount = 220\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 3e19b6f3f3fa3c2551466c9e09f0391350682495426fbb08\r\nMsg = c7496322ede893ae368884a91f80c3bac3505c0d\r\nMac = 55b25da032db8f3b4293a4865df77e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 221\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 5717ed57ca0b6921f04dcacad34e0f6210c36673dc9f4d92\r\nMsg = 5e3ed45f07a6b3c225ba73d04d867f9c5b4aa703\r\nMac = 1b642dcc4fa08cbd36d109d55a8501\r\nResult = P\r\n\r\nCount = 222\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 8eca0fb8033e63e24a54a3e63bcf8e4ec331b04ddedfeeff\r\nMsg = e3807f6d8c6471ffe188df67d952a7d67021bf41\r\nMac = 9a37eda1e3331bf86d208b2c0338c9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 223\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 633f44dad6995a6af0302692142a47430491ae7b54f8b00c\r\nMsg = 3caa9b8b24097d29bd24b913692acf96cc78b998\r\nMac = a6665b3b158f37f587dfa0bde7f300\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 224\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 14ef8096666ddf28e0ac5f3458b52f3e0c601deae57fffc9\r\nMsg = 11d5cef384474f33c2d313e6e1050d8c7ae5b019\r\nMac = 2643bb3e1c01f406d90104c4437189\r\nResult = F (1 - Message changed)\r\n\r\nCount = 225\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 0c2e1951eeba1a9b6592202b1b8547f43fd755fbd844a874\r\nMsg = 9ad62bff38e28f75302b6527c1c107543f798817\r\nMac = f42ff7aa728c2d815ac7c701b59627\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 1ee2df7aa80e3a131e2aad9c17bcbf546d8b25e5a849db31\r\nMsg = c4e8594cd09be010b6934157e0557686310e8dbe\r\nMac = 34496d184bbdc0c9a57916ff64dc3c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 227\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 75650ce366757618af20205b69af7e5d4e82c398c00101e2\r\nMsg = 42a71eb81ad1c97ac53b88831b2d15f3c57e7cf8\r\nMac = 4c03394a98bb43e6197074abe63070\r\nResult = P\r\n\r\nCount = 228\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 386c659bc45d0a88acd54ef7eeaa3e140e1cafb1b01474a0\r\nMsg = f4fc5acff75d404849675b813cf7adcaeb8f3d56\r\nMac = 5cfb2fc8869304428fc012a14b616e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 229\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = ac192759625f4e42d1d1fa73dc0f62199142155615478f88\r\nMsg = d33f716df06e9047f8d718ab1faa06ec7b773bb7\r\nMac = bbf5b7207faa5b004216fa5caf3f93\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 230\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = efb497fb9b85d472e7c9d061aff501f7b1e3a311a86cfc69\r\nMsg = 1fd425560816aa21d6572150d1161cfb3bd61e6b\r\nMac = 2b7e14864d29437647cc1b27a8a0ad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 231\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 344fbbeaf82ede8a401df7cc121ed3da43be9bcadeeb5614\r\nMsg = 93febc9e16003cc8d6490ba5a6e64dd673a0f887\r\nMac = d34ef878392bc226f7ce1519f3bc23\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 4b6c6b6be3c04985bff49719c4e11be97d7757801dafadc3\r\nMsg = 754336f8cf27f4bcc7af5207ff02a662232d9a62\r\nMac = 5389c533cf43ca0332574802c2ace3\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 233\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = fe5ddb0645387cc6535e5b7991e6428c4157a76bb41084fe\r\nMsg = 216d9eb896edc693520f99ac91f34cb54e76d719\r\nMac = b43388ba7859f803655d914b60ce90\r\nResult = P\r\n\r\nCount = 234\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = ed14373671cd8041e00874b5d098ea225eaf9c68bb51cecb\r\nMsg = 0569c6be9ddcfbb82618fdcfcab3dd60c20c49f5\r\nMac = c2c11297111a92a484868179c5931d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 235\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = f2faab6735779e9ac49716e7fcd3faac939366a7249f4f0a\r\nMsg = e7292269b07683acf5bea0b300782749074e2313\r\nMac = e10f324c19d79ed83256f15e302699\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 236\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 2bddd90daa1251a42a0e2fd2858568887f85e6d96d57daff\r\nMsg = 0f8b828c0e59effbdecc30abb6cae0d9af9c7636\r\nMac = 1aab0530749ac4c6432157730ee3ee\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 586233e492b76ade095e8f5ffc6df4bf6caad2a675953b2b\r\nMsg = 92af89c950d6221473a358dd0f280277bde7ab0c\r\nMac = 2a79121e68ea6b841e175ab5066388\r\nResult = F (1 - Message changed)\r\n\r\nCount = 238\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 5aea45c0995e950f333e29f4db82ea4c4c080ff82fe32bd6\r\nMsg = d9ff1c84bdb03114ebd5f471247a579311f4672b\r\nMac = dc58e7582cb555ea784036a8ba4b8b\r\nResult = P\r\n\r\nCount = 239\r\nKlen = 24 \r\nMlen = 20\r\nTlen = 15\r\nKey = 900c8283c7d50d6da79cc07d3dc7b76c2ef76100fa3ae2df\r\nMsg = 3f8c6d21ec05bc439bf82774f1812bd2dfe0d3c4\r\nMac = ec1fa18916f991d7276428b9c93c70\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 240\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = abbb803150cd7fdb9f3d571bc749debe72c825e45568aa5e\r\nMsg = bb5fd7f4fb020d38c13df3003a9bb852a86948f406c51624eaf81989b006\r\nMac = 799d598f32ebd9cc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 241\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 2fa619eed51bccdd2ce63580ebf85467ac9136f79256bf1b\r\nMsg = f92d1a6731f3bdd811fde1ed936de907ebbc4179670857859aafe788b91c\r\nMac = 6477feb7dd4c818a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 242\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = d0115f369d0f74073a46e3b9625660847dd7ac7571e40814\r\nMsg = 97da5d1f669dc60b6c6fe4369e01f3fbb9af30b483b23d885497c684d6ef\r\nMac = 3d7f0acc627b785b\r\nResult = P\r\n\r\nCount = 243\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 045c4b86eed865cd989f035afe8c257c400c11b1f72548c6\r\nMsg = 5a6233e492b76ade095e8f5ffc6df4bf6caad2a675953b2bdfa8513df1dd\r\nMac = b5a44479b0be31ce\r\nResult = F (1 - Message changed)\r\n\r\nCount = 244\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 4a83bf338fc0125ee1966df46d46a0d0b41e51569b3fa957\r\nMsg = 794a86f5b20d344ad86fd5523d08f1864737be57731440c29aa6b4257457\r\nMac = b45939cc01918eab\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 245\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = d9ccd93317441e9d6ccc358f31e7e2ccef8c921b23d74299\r\nMsg = 48754401bb69bed2cce8689e47210435878c7ce184d911f60d26b4aa5174\r\nMac = e0d1b6a530944550\r\nResult = P\r\n\r\nCount = 246\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 1e50fae752ac3a6e2b1755475e84441947e9f4b1d29546f4\r\nMsg = 34245df514f6c273d252271a980929e50a7cb0e77b05c7d46092abc30493\r\nMac = a0fd99f1405b027e\r\nResult = F (1 - Message changed)\r\n\r\nCount ", + "= 247\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 4f98838899bb47fd3b0fd5efcf55403996567a0fbe1abdda\r\nMsg = 0c8cc752ae8d487c621be129326513a5ccb4141e324d21aab399148c1a83\r\nMac = 1aef1b7bc7856c6e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 248\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = c98a22a667aafab0c94047e03837d51b11490693d5c57ea2\r\nMsg = e4fb1612e50607457dee8087ec41e57fcd7fc550497eaf1c8b0d47c773d8\r\nMac = 2c467fe37fee5342\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 249\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = bc6d4c46476ac1ea902be391b8a3f04e102aecead167f0e4\r\nMsg = 93b3314baf20e28a39e89592012c35adfaa3ee6d3d8e494051ee9944aaf4\r\nMac = 7f10757d2d36a55d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 250\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 5783548205826853ae740d35d6d69ab524c38fdfc5c51eb1\r\nMsg = 11c90809f9c53d2f77b56af0a42287ac6920e3d2921cceb824d496caf1a7\r\nMac = 07630c2fc52a24b2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 251\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9cac76976750b7937b3bbc6986b4c726f0d0a63310db85d7\r\nMsg = 5de2265292780222349ac793eaa17c5a22902344063f497aabb9dc038ce2\r\nMac = fd092bab159861c0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 252\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 616de0b0f868eec923bf9edebbbaa51d3faaa3f86b2a5687\r\nMsg = 38013d62558647bc21d293830aa3ba80ff3fb84a8e0938754c5213077771\r\nMac = b4e782780989dc11\r\nResult = F (1 - Message changed)\r\n\r\nCount = 253\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 5df77b26f3d34eba49d287addf0a38d20514e2b7e6059935\r\nMsg = 1930a8b428334df9fa1ac16890f3a6a93fcf9d6855d00b06ff831d8f6a70\r\nMac = a8ad975046cd7571\r\nResult = P\r\n\r\nCount = 254\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = c56f710e39deed799ffde6d10e8aebfa2bab5e5e073d78e2\r\nMsg = f6fe0f16403182d012f8b6e02539c386075b4585be5b18d6ae1c5f9ebdff\r\nMac = d0df47dda012655d\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 255\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = fef8982f7342f1b953658453cd5ea413700eff00f1ee7d6f\r\nMsg = 269b6c1c95bc079398bb31e285a887c1832202d6ec257a2cf62468e29358\r\nMac = d2c90040bf66b2a6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 256\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = a34dfa24847c365291ce1b54bcf8d9a75d861e5133cc3a74\r\nMsg = 105d2b82676bf67ca9575ffd31d7d114e709826fccb6a5c3d3d7e26ff258\r\nMac = 5e60278f98b3135c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 257\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 520fe80cc4a3a5ad9c31f7010504923b7a7fd88292a64f98\r\nMsg = 2e1e0712ce74a1ad02079aeb0ce35edacc33f9a5d907cf70d0548d84ec3c\r\nMac = daf839ef84f1c81d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 258\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = da4775b8f7d654bc4cf2eb75ecf4831411bbc9a960ea2df0\r\nMsg = bfaccce3a9e66f45e454090ffedc348306dc2807951ce0bf100178612703\r\nMac = 3e2eb7f029e687be\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 259\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 8\r\nKey = 15e3b3c5794fececd703ac58ccb22a78e15bbd55c579416b\r\nMsg = c6c3457ffcb6e66c085ecb69492deaa704e25aeeabb7b7795fdcc807b325\r\nMac = afd75cdc02222e65\r\nResult = P\r\n\r\nCount = 260\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = e0f2cdfb64bda8f02ab90620fc5a1943c4b536a99f3f8820\r\nMsg = fd0365ff6061e5f55c0e382f5861aad99c135f9511f33ace4bdcfe48c6e4\r\nMac = a1046d4b29fc50ed94a4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 261\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = c7aafe7d3b419fa4ea06143897054846ac4b25e4744b62ba\r\nMsg = f1baf3be69f69611fcd47256e43830a1b3fd8bd3952eb26ed679eda7a4e0\r\nMac = dbc419e1ddd5cfdc63a7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 262\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 58c219f2bc8ef2ed7a82cf70e4af4747e36a30809a5a6222\r\nMsg = 622642aa69b3efe14abe0a1d2ba20f3f76efddf62e6cafe2845c4dfaa501\r\nMac = 4e496c3d2d84d11923c2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 263\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = abccee975feb10f635d548a8502f7c8b6adbd2be74117257\r\nMsg = 4f37a460d180a12789779fc335326c983ad6b18295b47f1715b82b2dc704\r\nMac = 41b234e0173770c469b9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 264\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 0218eb619dbbde2e846218339aee4383792856496eb3b85c\r\nMsg = 28d3510a37d5f8481e7f22941c1fb1d6c70686fbad9747a23c9d5f18dfe2\r\nMac = 3cede44c942387d91767\r\nResult = P\r\n\r\nCount = 265\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 88b2514f368d51db283039efcde1891652a77daf68feec43\r\nMsg = 067a3a0434e92cac02710221fbb6dfcb7ef0264e2994905491317c8c3697\r\nMac = 128e652ce0a8f1a6194d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 266\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = f2a78c449621278e9e927fcd50742d042d98d5142380fd3d\r\nMsg = df899dd6b99cc28d66604ca92431fa7f442a4927d03b392e707b548b8ebf\r\nMac = 2eca3c42b5e5d0f3b9e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 267\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 01fbfbde7dfdd6f0a0c5244cf6c36eece4d6dedd8baa463b\r\nMsg = 485ef613bdab5473763bb269a0d8c7a4bf4850bba072a96f8fc39a31cbd0\r\nMac = 333eb331d6a0d46fa279\r\nResult = P\r\n\r\nCount = 268\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 6ce99c231d2ef0fd48c2375dca93f8bb0df97d4a44e835cf\r\nMsg = 32d71e59634126ac6c6156a80a0dfa0175b29e9f40a3169680b1c15830fc\r\nMac = 3e90350e115c425ba466\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 269\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = f7a93aab5707ca3d2362c5669198e0218493acc3cb7b02d3\r\nMsg = aeec40ca8964fd6a67d3dc871ebf1bfb72f52907f1d6ad441bf2cadcc6d8\r\nMac = 7381d65aa138c86713b5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 270\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 84f39f5207afcfd677a7544579f2b888a1eabdee4e835924\r\nMsg = b8d21e9c70bf63f04be311d50f84aad7e1bd2b0e517434ab978d68d01c5d\r\nMac = 4ab61c537f8b15f824cd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 271\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = d488bdda400932de56a9f105f0e74ee79c2ed869faaadc31\r\nMsg = e64949ed85de6359595f286e29014c26daa7759aee56e4194ee958774606\r\nMac = 2752bc490802b9dd8686\r\nResult = F (1 - Message changed)\r\n\r\nCount = 272\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 76ddfb075fce4be8854185c6899a88d06e24854506b31237\r\nMsg = 9d86ae7d70e839078babf7fd60480a4351690867c6a8af837d9ad465220c\r\nMac = 2522efecaa1ba11c0260\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 273\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 618041501dfcfdd2b60d71c04d635f6357ad8b0643af77aa\r\nMsg = e5e6b57e74ce7afbde3697e2a69d61ca615aa3dfd32fe31f5521e6ca7987\r\nMac = d958753757a11eacc848\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 274\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = dff6b9493de80447ee18ea7311fc9b8d74f77ac1ab21ce84\r\nMsg = d70aef3532bdc5293a3ebb11589ac1f801c9f93ea0d656e1d04068facf9f\r\nMac = 9a761e0e54767e414cf2\r\nResult = P\r\n\r\nCount = 275\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = d7780ba2dc5cc584472b64bc9f6246bedb27c70aca22c0a3\r\nMsg = 14691c1b47ff1547c1d2151913c2d1862d8f54782291ea202caa3d8ef07a\r\nMac = 78a2bf3a5fc87a14e090\r\nResult = P\r\n\r\nCount = 276\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 3bc5dba883e2e3b81df06760cc32f11009cf5a5503cbe864\r\nMsg = 9d043e368b41acb5eebb99197e15adbc3d19175a0bfcc97275e3e5efcfa5\r\nMac = f457293acf683c873add\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 277\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 7b3fba25c5ef410ecec62276b105ecc01c325dc2530e8364\r\nMsg = fda4bede287c57eea4448af5e99d41c7d307d1f202af7f387f874342a29c\r\nMac = 0cfb78ede5f4c185c33b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 278\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 38efdbbc5645f65414b9cb81d2f9e4f190cf6e6e05eaedbe\r\nMsg = 50422c5e6a0fb8231b3bb6e2f89607019be6ad92a4dae8e0fe3f9e486476\r\nMac = 0c1acd8e8527e2663486\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 279\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 10\r\nKey = 94ea5b0aa6c8b07e379122006042c920077bd61610df6b4b\r\nMsg = 1d52f401f01058356d8c4c630f64c5322caa6063d6365ebf0040ec4ee12e\r\nMac = 2dec0d3bca617209b07a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 280\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 5584994f80640233ac8eb4d2f873e8c997499095250b48b3\r\nMsg = 91febca4f1ae7e27501400c44ce8681ec90f5a5637c962db142c9284b1d1\r\nMac = f0b3135c1748e823aed10c4694fc60\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 281\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 57e99653fdcab10135a2ee3bf45c1be69e9ed57bd74dfbad\r\nMsg = 51c88fd98a7d82043a1500fc3d8a66ba7ab7760467c7fd89cfeeb22dd257\r\nMac = c588ee1d4f330e51872065c02cae61\r\nResult = F (1 - Message changed)\r\n\r\nCount = 282\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f622d736124641bb7d53706bf2a69db2fc31461fb92818be\r\nMsg = f09569906", + "381138cc49e3fc2384c5d33c34abd3d617c487b52ec6ee7b510\r\nMac = 610e1c1f9ab35059580061b8662a81\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 283\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 9662baae49c26e5452f3304ceed3b78326d2020a99a63f69\r\nMsg = 1d93aca4e2e31f5ebb84fad580fe74f5b6d1d86ab30cd0c8031be4090be1\r\nMac = 3c5a4eb51ec58ef3468bb00e7cae8c\r\nResult = P\r\n\r\nCount = 284\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f2100615431349aba5c4f5a7f358fe7be579f4cb9e8f33d2\r\nMsg = aaf26bff7ad4116969c15d9206de6c737b7dda87619e3575d9b6b2efd8b0\r\nMac = 7396deeb4316fc6d84d3af119656f3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 285\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = a5993acbea8c55d7eb55d60596f83e1d9f2cf636d06240da\r\nMsg = 0bc1fede6a6ed9e1deda82612fbaa6e60f0b2461fd5d131e6a7206f41a07\r\nMac = 2f6b0a9f2a972d299bfa5892f8ea83\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 286\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 775846f9dbf36415640276642cccf87e3dbdf6519c5b2db8\r\nMsg = 4fc989f327e1a1cc7b8af618ee6ae6d25f78e2b76b681455336945655f13\r\nMac = 8b3cf3171912096763a2ebe5ea9e41\r\nResult = P\r\n\r\nCount = 287\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = b214b16bbac27ccc9773d3c8dd31275da4876c039740ca8d\r\nMsg = 7786a3e30acffd6dde375bd859dd6be2c9221b979d0c66d1d5ed6e00b73f\r\nMac = 1a73acbf4e9250610b74c727b9c42c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 288\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 032b4cfce8a1acd89de5f6f78794e2813bbcdb89959dafec\r\nMsg = 3f0bf0141dd3ace0fabeace61811eac5ec801deb7ffe3b0514d43db90bf0\r\nMac = c24066cbc00cb5c28e48141b627411\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 289\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = a053255875ed4b5193bd9c5fa4172a1f660ecfd2a394c2a5\r\nMsg = 14666eb960c6b4f8b6ccc49f79a039b12c02e0972c300f1e9d0a38c0a474\r\nMac = abce3abc224772a43c058016bf25bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 290\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 0ee87b40abaa99f598fba22c3e677a85ca3ec95c3a51aca8\r\nMsg = 1bff19aacb9c7d0a44a15ce686a2469e3934d086365d36f449484498353d\r\nMac = 4d565c2e12901845e77ed8b02746ca\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 291\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3384f8563cfd0fc8019bacc9b691c9ba4ae6dc8cf4c00629\r\nMsg = d31e959cf7842db351db407266ddae0b36e37f34270576724083e9989764\r\nMac = 96d0dbf51d96b532321da593383964\r\nResult = P\r\n\r\nCount = 292\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 375904fb9fcafb7f19877b145b0284cef61ac7a3d88f537c\r\nMsg = 441bd4db5e80c7db1b575a19b7bad021a719658a2c818566291d3cdd32fd\r\nMac = 3b8dac029f6658e44e5f5bb8f8ee40\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 293\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3c1ca347a7d3d8db8f704410c493d7a65718cb7bffec2dff\r\nMsg = 555fd02fad4f44484133f9472c050f9da27390fa2a3e48cb0be0d7020171\r\nMac = 32be39d874c15a0fffc7111f76bbc4\r\nResult = F (1 - Message changed)\r\n\r\nCount = 294\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 8bed296a3ac03fbfb71422b9211799150b9d766a8116bebd\r\nMsg = 6df3de543cdb6d1adb6ca7df6b5a4510fc8379a4f2c87497ad1c2b9a69da\r\nMac = f24ff3218e7905d81c3e99c84bfd26\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 295\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 9530bb291d38f6bed10318081dde8fd178f02eb0e8b7d022\r\nMsg = 5f48624302d1acf7750994d45f0999ecd89a3861cd0268d5a51e672124b1\r\nMac = 0afed54c577e550eba7ac94a2d82d8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 296\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = f5400b86ace6e3da5f090befb96fc05d0409bf41fc77b4e0\r\nMsg = 1c79b055fded54af5ad2f3253f93a090ec003863d9458d3ff718c4c13937\r\nMac = 59f94d4b13539a5f0a8672e4599bad\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 297\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = c033e4a512297caecdbead892b11a9f7007af9a74bcab89e\r\nMsg = 3ce965d58856663d54269af4791ec57ef98227ea387d525769c23ab74674\r\nMac = 0dc19e37a255dabb61957f7f89ab06\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 298\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 2459f951d1255d093b72144b83b05ea3185d5123d1ca864d\r\nMsg = 661c6ff41af91a6d828a4d5d507f8a9130abe91412070950c5fa4c75c8d7\r\nMac = ac8e75b4465a52b3a7da3746f9875a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 299\r\nKlen = 24 \r\nMlen = 30\r\nTlen = 15\r\nKey = 3b63415210361822e23cccf0faae88cd7642f44cec45fe37\r\nMsg = d7f78e950d2ab520a6f1e82ec6f206b2e8c71131c85234bd80500527f131\r\nMac = 15e59760acd3dd74155d6d3739c189\r\nResult = P\r\n", +}; +static const size_t kLen51 = 61387; + +static const char *kData51[] = { + "# CAVS 11.0\r\n# CMACVer information \r\n# Algorithms tested:Alg = AES KeySize = 256 Mode = Verify \r\n# Generated on Tue Mar 15 08:40:45 2011\r\n\r\n\r\nCount = 0\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 45b74171271e1fdc19f9beadda58010d843af69dc2f4ad003dd74b9b570d5a98\r\nMsg = 00\r\nMac = dc0ee796\r\nResult = P\r\n\r\nCount = 1\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 2cb4239fffd13762fb5391f5a4760d12d96ea12666a793b4d651e9f4891c22c1\r\nMsg = 00\r\nMac = 2e19d6cf\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 2\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d88586da8b605a6fd5a45d316b89fea15e27ff4d92238397718e68b8e00ad605\r\nMsg = 00\r\nMac = 8ad78885\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 3\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 136ffda3359fee8c81e6dac131256f4bffc0d3c3e74f8aaf2f979a0fa5b8ed32\r\nMsg = 00\r\nMac = e430d0da\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 4\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = e1a7867476bee9928b7237ab7a3d502fbe3d2d45b6e4c41aa9f12b79099f019d\r\nMsg = 00\r\nMac = b6f00f90\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 5\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 5b4d945d55dea22e37821ec396476a4bfb617d2f392ad93afe67bcfda9cd9b72\r\nMsg = 00\r\nMac = 5076ef43\r\nResult = P\r\n\r\nCount = 6\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 23df62a79fd5866425427d0ccabf05b16590e8452ee22e028b51910926ad314a\r\nMsg = 00\r\nMac = 7bd29398\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 7\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = ce9da814595f76a7e52a1222c7c9a6579b3cc2e393ba51580ff6cc9b6ea2ad8a\r\nMsg = 00\r\nMac = ce872fd7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 8\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 507c4f32246d637fe08e454c638b014438109e1fca31f724d40ac6ec1aa20268\r\nMsg = 00\r\nMac = 282a7ec2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 9\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 537dfe9fc000468dde29800549b1cfaae67ad89d22c8264d7eadcd914ac54ef4\r\nMsg = 00\r\nMac = 7936b7d5\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 10\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 1f57959cecbd377374477e33b34979814f260f77867392ed645998f73a3b06ae\r\nMsg = 00\r\nMac = b4b63264\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 11\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 3d272b4a1a1031369aff514e2df98d580f972b5abeacc05cb1288e6e473c0fed\r\nMsg = 00\r\nMac = 18b35edb\r\nResult = P\r\n\r\nCount = 12\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 8774d1acf96362215a3d1e51e1a52a980685dec4f3afd2d438c03c00c04a79f9\r\nMsg = 00\r\nMac = 80eb7a84\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 13\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = f37155beb5eed8899d9ed4b5fa21b60b40af289f090a355d5bb1aee52957cd99\r\nMsg = 00\r\nMac = 6827f73d\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 14\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = fcb52c44379ae8083bdc7b827383df93cb1a7ecc21574730f9fe003b7302de23\r\nMsg = 00\r\nMac = ccad16d9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 15\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 83e231ecf8913ebce00e62b8f00c1abbaad710142fdb912c54664169f7af0e51\r\nMsg = 00\r\nMac = 8e393f56\r\nResult = P\r\n\r\nCount = 16\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 7d35e77450e2adf8805d5ad67de5835b2c5dccafe8440865c7e7a1501ed53a98\r\nMsg = 00\r\nMac = c6899710\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 17\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = 87143071241bb65261fe7afcc102416e59b9e46ee0c9007308f0eec10e45f6d6\r\nMsg = 00\r\nMac = a1a4449e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 18\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d30d2d1670553c71ff0264ab861574dd03a103d954226d1b540f18fc47b3fc29\r\nMsg = 00\r\nMac = 217ac763\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 19\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 4\r\nKey = d6983226b2c3a431abcceb77c8ec6b9bae80199115b28c5d7c56561e1b12944c\r\nMsg = 00\r\nMac = 26c717ce\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 20\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 0cf53b4aae3e0a209e58385dd32d9cc6163265241332c332af4de4b99b4022fa\r\nMsg = 00\r\nMac = 1bfd19f6e1070186\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 21\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 5f988f38410d26d293ef32d74eaa81acca82545e767ab59dcc750a09849cebad\r\nMsg = 00\r\nMac = 7e52911c0d7987a2\r\nResult = P\r\n\r\nCount = 22\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = d8fd6e1dfcca8f656705aed7e356a576baf8907c8d10d54c833d62a8a6703624\r\nMsg = 00\r\nMac = 31b478b4b4adaae0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 23\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 49fd56dec210e903f6c703332637f9c267eab9333e2701a16c74ce5e0b5a16d9\r\nMsg = 00\r\nMac = c8be2b36c93684f3\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 24\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = fa282e1f3276a3e0c769f2ba25ce830591e860300cc03ab57abdb14c0374d060\r\nMsg = 00\r\nMac = 27b8111c3d9f14f1\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 25\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1c6942e914218135496e0d7910abe67b9f7f29bb09029bb37021865d7543c4f6\r\nMsg = 00\r\nMac = 466b7077bec98b7b\r\nResult = P\r\n\r\nCount = 26\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 08f199a8d7e3ea821dd3106e8947cd2e9d485342b25a64713db2b8a650a49ffd\r\nMsg = 00\r\nMac = 796deae0d06b1bf4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 27\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = febacddf3448c7464297ae53166793e2ed962de0d0947c5e5e17abe3cc103b07\r\nMsg = 00\r\nMac = 5e2d21aa3351a2a0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 28\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 59b9fb83b6a85f017bde6c0ff3ced955b9f343cc71b680c6b591302f52759412\r\nMsg = 00\r\nMac = 3e5428eca10808b6\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 29\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = f07e6655424125462a96390e02bfee9d89cb271bd9bbf22a9de45f6b7e949343\r\nMsg = 00\r\nMac = eed5aed01096226b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 30\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = a04f84bd79406c138d02698f003276d0449120bef4578d78fecabe8e070e1171\r\nMsg = 00\r\nMac = 18553226e5f9788a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 31\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1673a52494e9af02472c1777232aa3813c7c162593eca7112f34b3807009af5e\r\nMsg = 00\r\nMac = c5907fff58c68ee7\r\nResult = P\r\n\r\nCount = 32\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1e4ffbed2d5a7bcda5e24a66048660629d57567f83307087a846db8246ff332a\r\nMsg = 00\r\nMac = 29599bc212927246\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 33\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 8b80c24ab4a3c24ced82ca8c69924553a37a139bfa2541c59e15188ab0fa5a34\r\nMsg = 00\r\nMac = 299746d93b0b4881\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 34\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = a00ebf59768f6437b48a91923f5effcf31c745b980f79f2edde9ed18dcf2ffa0\r\nMsg = 00\r\nMac = 61950ed83db6bf74\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 35\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 319d3f58fd7257901ff364fa68b86b1ba27c11962b2c5be8e33eb95548444322\r\nMsg = 00\r\nMac = 26793e8f8d5eb7c2\r\nResult = F (1 - MAC changed - for 0-len msg)\r\n\r\nCount = 36\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 015a9d1f2df2c31f14cfbdc0bd68725fe8113a024f2a43312d963207fd6f0d88\r\nMsg = 00\r\nMac = b19fc2680b8b82b7\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 37\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 003cff344c4e1932ac628440d819eaaafcc3ebe7c525cb7abb7a6716d2b76e05\r\nMsg = 00\r\nMac = 48a98dbf16257142\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 38\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = 1a581f36e1816d346f7bcc6df78316aa353111e447fee6f0bd05d562f30626ab\r\nMsg = 00\r\nMac = 587155c18ebbf8b8\r\nResult = P\r\n\r\nCount = 39\r\nKlen = 32 \r\nMlen = 0\r\nTlen = 8\r\nKey = ebab54c4a22a16f7d9546bbf682b995a6ce944e949f1920eee058db95ab9c93f\r\nMsg = 00\r\nMac = 067927f063adfaac\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 40\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 58405ef8fb69e88221edc10a92c01cc44255aa7083096adb79bec3a8cec6d050\r\nMsg = b4aaf9ad1bde60a8d7e7cb16c1cf6b713df17d1507b028973068a95963a5ad5b\r\nMac = 42ffe65f\r\nResult = P\r\n\r\nCount = 41\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = ca0f404e3389e9527135f53eb58bca7726266b8086d33fb512e8143daad7633a\r\nMsg = 8f2a6b2185f73372ccaeaa7f93d30d1ca80a451ee0e46ccbbaf98c8f3f37aaf1\r\nMac = f2b311b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 42\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 67b896b88f07962e08471634ab7e522144d716a2969bde55a05c3c931f747a8d\r\nMsg = 0218eb619dbbde2e846218339aee4383792856496eb3b85cc43fa81446fedc5d\r\nMac = 69db1949\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 43\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 422994df8766f7a6a7ebfa2ca57ed6189d9e9e8455c8715c14f3f407b75dff4a\r\nMsg =", + " 12f0c45d06a138a964fb11b2d450620a2977bcd2952afe371cad6e3d48b009bc\r\nMac = fc5f1ccc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 44\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 3291be3aecd2e06cd2ee61a14d723450043d450567cbb0bf88ba32972d86dca3\r\nMsg = 343d5a4ad39acf81adcf24e9807618932abcb3bc076734f179174c77c8cb89e9\r\nMac = 3593d615\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 45\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a1885ce431cedbb60f7b3d96a06cbc60a964df156ea4b4191abc5a9f60a0c361\r\nMsg = eedd0d767a25b24ee25fe747718256af51d7b4bfe900adc069381a71a2dc7aad\r\nMac = c558f768\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 46\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 039188ec58fa55acde53c337fcfd0013f0c6efa55c60ce470112159bcaada11e\r\nMsg = 009f47f180e085776be6644aeac0070be64c289f84a7ba3dece7cdc54f0db354\r\nMac = 20d3639b\r\nResult = P\r\n\r\nCount = 47\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = f7d946f66e1cc4e5a79dfb5559cbea5a128545eac38e17ee7f3bac9a806faefa\r\nMsg = f250c49f9882f10db247adfdb2112c2589e1011f77c48e0f219dbf85e326f8a5\r\nMac = 90b4bfcb\r\nResult = F (1 - Message changed)\r\n\r\nCount = 48\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a61f586ddbbe0219187f8f446d4b172f5e9bf855d1d5d6592ad8e03eb4d555d6\r\nMsg = 71c8eb0079559a306e236c49b7ce1b6cfe26c7888733eb7ec07690831a72c0c5\r\nMac = 78ce0135\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 49\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 7774802fd82fe96c05431acd40b49b1160d403c0db09b10f23d0bd0435022edc\r\nMsg = e75b6ca1b87e775b33536979422a1cf743f58c71b1599adb00050972c843cdf2\r\nMac = d885703e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 50\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = c4261ebb87a76aaa82a00392ee2e2318f0b52d5f2724e374847ad9ea5c8929c1\r\nMsg = a41bb1f256228302cd0548ae2148ff42774d18c2d6d3e38b36bc4938da13bac3\r\nMac = 857d8909\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 51\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 6219c19233c1b91d7785fde3b65df3bd2e1d74331ba62e4d365947a77cd243c4\r\nMsg = 68f17b9f57734784144112c79bf360ee324d37f9a7718137d954b15e796fa9db\r\nMac = 0e85de57\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 52\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 7e8cae1374d3a21bf2dd3786754668f17aa63dd5e3654cff9dd18041806d1968\r\nMsg = 2d335be62ecfed45183f5a04014c1a52afb7b918b9cc1f2be93b15c6e5240537\r\nMac = b56ee72c\r\nResult = P\r\n\r\nCount = 53\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = c2425ed20cd28fda67a2bcc0ab342a49d79d6b4eb196266cb0d116fc18895545\r\nMsg = b5f24c00cd15e377f444ae55e02b335379e7ae14e7c9bd05f0575d8981941553\r\nMac = 2e44c573\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 54\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 1f7871680bfa59a8a178604dc513b51a3d4c682cc4c421de594512e9dd062ad0\r\nMsg = fcb43224bf8989e1809d90481ba043328febaf4b6c1c05d18800ed98f4b71c52\r\nMac = bee03b92\r\nResult = F (1 - Message changed)\r\n\r\nCount = 55\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = d8a27558d070214d3f765cf969b2b8f09c0b14ebc492cb2539072b04db9f29fc\r\nMsg = fc69a1f0d0ba8eca9e7c0570cec9c76b511c74b2d8b65928444189675eb42fbc\r\nMac = fab3b2f6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 56\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = 72354b455230b72a6dbfa5cf6c3726d7f8e65ca773f9d469e99d165743657b36\r\nMsg = aac60835c309d837aacc635931af95702a4784c214283ebbfb43c4e29973560b\r\nMac = 69519d9e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 57\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = ca92b095173076a40e24522297be27fd3a765c8d417f24c71a9f03b3fe3d8e20\r\nMsg = a96c4d5c89a364263c97a453308b9360bc0ed868602b9ff54fe13f162ad31ab2\r\nMac = c59a1a39\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 58\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = aa56f98e03f559eea02ad958e125f2312ff97bc3310079ce437b383f247a9b3f\r\nMsg = 01bf2aa8dc66ca44d16d4567f1adddd4461f78706ff15cf68ad937eb57aa62d5\r\nMac = 31171cfc\r\nResult = P\r\n\r\nCount = 59\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 4\r\nKey = a0e317b790870e6703e6077dfb8ea327c12e29a17107284cb89d5effddb2d9a1\r\nMsg = eb4ea6b72dfc6657e835bf82054796183330c02a8db3c5b179abe37fd0a05675\r\nMac = 05d54199\r\nResult = F (1 - Message changed)\r\n\r\nCount = 60\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = e3de27949ff64066131c81bfee172b308f9bb0b31710678ec394837b79434605\r\nMsg = e41557341e8dae33568524f3f64b23426044c9db3526463ad16786af14f611b2\r\nMac = 975ad1d2fcff6a85\r\nResult = F (1 - Message changed)\r\n\r\nCount = 61\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 492dacdcb4a35fc438a6eaa35e26d2f683a1e85e92df28f213dfe1da6511161a\r\nMsg = 0515ad7b8576258645d37b7ac771745620e2e9e009cd778f34ed77a7dc5c30a6\r\nMac = 9f43dba2aad2f539\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 62\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = d71c50d55850d432cd8c8ff4ea427b3f19cbe14c785a7704202fcbcead0de5a5\r\nMsg = 7ffbc4a09583029cbb0acb6b13f08a189033da22c2ecf921f01d79ac68a9397b\r\nMac = 5d00ffc5f8cf1ddd\r\nResult = P\r\n\r\nCount = 63\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 557eb2e709d58915a8bada6433f2e5660247e0cb1588ea84a9d24028090eb396\r\nMsg = 003132645e3026f6a2b9d0644c16e5e4d1bf8b53a51f0e1b999bd45a67d19341\r\nMac = 6f3d9f50d09476ef\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 64\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 351d779277148ab4474843cc798942cacbe863eb1c1c9338dc25e251c12fda68\r\nMsg = 34bcdd3d0469c01d0d95a85ca705d887385bfde20596a90b47d902db826dbc8d\r\nMac = 79ded259f93456bc\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 65\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = e1c17ce3d3c61468a7652a95128bc0f6c33d9ccc46e7490327f15f645a94040c\r\nMsg = 97829c60ca9a71c23eaf1c4b4fbd72043037ef0cd356b68e0db0d4f0f50cc54d\r\nMac = a93f0d16499f63ec\r\nResult = F (1 - Message changed)\r\n\r\nCount = 66\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = a9a86a4407b7ecebc89434baa65ef173e88bd2dad9899b717ca578867c2d916f\r\nMsg = 25a152850b4b80b19d8f0b504b2a8a241824b3a1fca8d85c8713b2c0c84b5e02\r\nMac = fe84ce3defe00f67\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 67\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = ed14373671cd8041e00874b5d098ea225eaf9c68bb51cecbe8083149bdda062a\r\nMsg = 38106cdc72b1ddd0fe11f23819096dd7479e95ee9730940c28f51e28eca653ed\r\nMac = 470404ed731640a7\r\nResult = P\r\n\r\nCount = 68\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 009f47f180e085776be6644aeac0070be64c289f84a7ba3dece7cdc54f0db354\r\nMsg = 2eced43c084a86f89f61e7237425137c167aac29e4cac4071afafd3f0c9dee1a\r\nMac = f67d432e5b6fc5e4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 69\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = f250c49f9882f10db247adfdb2112c2589e1011f77c48e0f219dbf85e326f8a5\r\nMsg = ce61d6d8de1b299c9b063d1e1cb1faf7a616faa7c6673d7f9c0a1ebe7ae285fa\r\nMac = e1d950593abc14e4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 70\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 001150b2dd572288b6fde466ec2c2a64c75a9d516b7096f7082bec9f52c20ad8\r\nMsg = 6dc38e37d1379732df4dd535db88d17aa59d7cf9e8d60ae695b4047b90d899f7\r\nMac = 2de6700fc1562ad3\r\nResult = P\r\n\r\nCount = 71\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 68e00d394855b6697da8213a120dc2213b3a8a1e88c9b93f5edef465a809974a\r\nMsg = d21aed2073e8ae9c0560f9dc1adb961d4f959fa12c0384a44c675192bea13477\r\nMac = 9594f10d5ce5e616\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 72\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = be0f6052baf658a3607d999b81401edf7e2afac2b143e1b908c8ea0ff38193d9\r\nMsg = e502f0b4710bfe517e783c4bbb85055c8471b04e12dd6776f276367fb5d36369\r\nMac = d409a879dccca77d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 73\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 7147b3c5ffb2660c45cd8d78a6fd44bdd5ba75349642b32ec88f6688a287297f\r\nMsg = cebe84df789c98dd125bf43cd993e2f089611b98d10be04904e2468d116dd2ab\r\nMac = 21cfc1e6c1c38df8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 74\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 205e751926038ef940c6599d84a9e1b4737bc826e9fcde544d43f2a10b5de931\r\nMsg = 86ffd5bd3bd1cae10706a61d247b2257b165f37cb53ff21761077a2295a9111b\r\nMac = 73d66ea826b84fc0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 75\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 8c8a502eafcfbb813dd1ea907b1660a41fcaa3f905aa93c22320f96ebfaf632a\r\nMsg = 626aed82974ef29a1ba0a6c6fefcbf34ca982e6214835183502f6a24ea2e500f\r\nMac = ca3d007ecd99be83\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 76\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 596db502a357e102566291b916b32b8a09e99d3739f5e6543a2cd8fb0c9a1cc2\r\nMsg = 22bade59214fa4b933cb5e3dc5f096e239af4c2f44f582b095c7fea6b8914bfd\r\nMac = ff4ec21d89d4762c\r\nResult = P\r\n\r\nCount = 77\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = f51f2fb4b3fd8045b70d34b600a2697cbf7503be0d8cfb5cdc60f9312e3e269", + "5\r\nMsg = 4d43702be4f0530319555d7f1a3356160f6cae48051f12e22a153d7e405c1149\r\nMac = 3d615ee77043d8b4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 78\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 80a4b14f951490618ce53d39abd3d786b425d4f76b26a25052d98ebdb7e9e666\r\nMsg = 0b2a77b0175ffafee40cf83bd19e785dc7ec4319786c49b3e7a741142aea901d\r\nMac = aedcaa2e26d2f5a7\r\nResult = F (1 - Message changed)\r\n\r\nCount = 79\r\nKlen = 32 \r\nMlen = 32\r\nTlen = 8\r\nKey = 39fb57fadff7cd9e1cfdba154422b71d693d08807d86da46ba63c929417ea549\r\nMsg = 567c7400f190d06e682b3dac5f751639a9007362b1a2a8b618800fbb9f6c08df\r\nMac = e29461fe8c6b3767\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 80\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 535ed61510eb268100be032b7a258e84bdb32448269d3000a76444ca74b4695c\r\nMsg = f7f28df82f910badc5f4b3860af28cbb6a1c7af3fafa6dae5398d8e0a14165def78be77ee6948f7a4d8a64167271ed0352203082368de1cd874bd3b2e351b281\r\nMac = 4a0fd541\r\nResult = F (1 - Message changed)\r\n\r\nCount = 81\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 713fd349c56d1086794eb20ed59ddc89b065bb8533b968c6dfa60bddd16646fd\r\nMsg = 4f3b91aeaaabfc7d4dd6821549d4eee2ea17f59aa196c67b422be2d46f3a2ec65494464c969b157985a6a30199a72dfb1c0b7be524e16ee9c43fd95e83e19192\r\nMac = bd4eab1e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 82\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 1f89d9ee93294aeaf3503d15a6dbef48708de48897a72b3545b9e3852eb7fe31\r\nMsg = ea0608b19f47676f0f342cc2742e003a6a74fa2850f41e0cf162235163887a3830dd8b13b45842b3c686ca239bdb9897e646ac9f440713a0d8c5b18532db3db2\r\nMac = 8bddd404\r\nResult = P\r\n\r\nCount = 83\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 2b50dbe8a5ed0c7cb69aa60a38d10cfa4553c73d58c0ce84b26504b0fd55038a\r\nMsg = 2586563b0102f662b5a8f9bfb0c1d107a4c27569d27bc066889213e3e830427ceafaae1ca543aecaca7f34c671fbadd518cc28d9e806bba43b2e220e5cf1aa45\r\nMac = 987514d4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 84\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 29a7ed3aa55c7eb7e5bf343ca0efbf8b2062ce67b086255551a8efa0ae16569f\r\nMsg = 2e6f2d21aa133a5061622f08ac64c6b3a3dc8154862033055c27c3a3d9e42dc885d2c9f91bd1d0212f301c3e140b2f5bfdd777be623bd162a6214ba8f60e2e49\r\nMac = 1bf45457\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 85\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697a7ee6410184c7982\r\nMsg = 65916ae3d88ab2add5c0c6910ea993d385cbd35c5077ea0d9db30e53f378abfcbb1e0649fe14204470d4dd53ae16650ec444cb4ef22fed86b0009b57ef71fb5e\r\nMac = 578f80b2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 86\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 47e49e5b57fbb834932fa32107697471119f1be3c3a6e71a8c474d4b1596e539\r\nMsg = b3cec7ad75e2bf6c87029a67365aa83cf797ae2f4d42e720ed4c48ba21ea08ee6aa3609f69a6909fff6222dbb45172d255146e4ce1c59b48a7895936a8646766\r\nMac = e6e64597\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 87\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f0b0aaacc25a791c236aed0e9b537fad00a15efa9c89b5068ac52c64639fb1de\r\nMsg = 9a5a9560baed3b8e0e90b92655d4e5f33889e5d7253d9f6c5aff71ea4069224cfbdd19ae3f0ecdfa65c27dc3bed721712784a09fdde243c193ab6a0ac2417e8d\r\nMac = 990bb31e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 88\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 14db1ffc1c87117fc72981706c0f90404acc98aabe950839baeb6f0b727bd6d4\r\nMsg = 3d736aeca5720f5c7bbb16df61f6d785facfa070aaa89c2d9e8af9450d62490ebd6a29c7c8e521e4a00fcca7515439f006c09056cfb7f976a1e6b98b9f799e40\r\nMac = a6786e52\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 89\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = c6f0a3692c9280c48393b0dd763e5d0b90477f34ad69f192ae4dcab771aeeacf\r\nMsg = 8439ff717e1e15161119494d368d7f3812601588265bbefbc6d48e22cc8a51688dd021500cee38fe6ec402f9aeb0762f92b2a73adece96e1c7b24be2aa9924ef\r\nMac = 70126cfa\r\nResult = P\r\n\r\nCount = 90\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 75225a26d63e91281fb37ace46354f81de99dedfde8b770ea47f08503aea87d8\r\nMsg = d729d8cd1631aacfe485b1f408a4fb60256e7a8ed6e5b53afc34be7e57f1643b549fa9ba2677779318688ece225cc149babd6259ec37fbb4adc03e8f6dd63f03\r\nMac = 5112f762\r\nResult = P\r\n\r\nCount = 91\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = ab72eef2aba30205c986e2052d6e2c67881d24ae5fceaa8fa77969539152527e\r\nMsg = 5251a0aadbc92b76705eb053d09b25b5ad38eebabfe1980d143ac90aa81f7723353059824c8d9befa5ded6f5b4973f407c7a1f4aa85d8337d82d34fd3933e9c7\r\nMac = 52f7a014\r\nResult = F (1 - Message changed)\r\n\r\nCount = 92\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 6906d6533fbc33f56e38e6a639798005daa228ebd2fc8f93803d26fef30b8e95\r\nMsg = 6341370e126097f9721a13c977eb4875cf1286e15c3adfa4e7597e0e13d93b6a8ff66c809067fd5e7f40c358ee170d4ed1657c2deb3015b886e79589678e0452\r\nMac = 1b6a021e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 93\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = cd9072aeffebbdfcce95b569c34158d0e130ef24dc99e3f98a4dd246949be269\r\nMsg = f882339f93ff114bfead78044aab1c7fe109dbf1bb2d968ad476403fdd2034cd3168ccfb0cf02f1ff7646ae3875ec349478749edf300b08be7005cc0d6bebc15\r\nMac = d16bcdc7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 94\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 3005c0100dff59e5e4b0e3b95abbbc79749dc49ba29a79b1fcf7613ecb6aa9c8\r\nMsg = 4c2c670f3ac1c4e33a8d43063c8983e20f1ce6a73299fef1e70a42a5882c061b1ebaaa8330ee1181d946541b1d84b8d57df8de1ac9013ade36d2c682b172f8f8\r\nMac = e5689100\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 95\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f32eefb301356fb1cad6dfa94864542b5f8cd8e98438bdbfbbb431f0c10f12b3\r\nMsg = dae6db62842a8a25123e50041b701ad17e2f63a0496443c3d905a9f943e6e4e2f3d369b693ddd0372ff11fe496af4b700378fc72fcc9915e7bc864b44c1d4f77\r\nMac = 280624c3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 96\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = b0212ca369c611b725eccc3daa58df412787a3475f418d820971af46773382c0\r\nMsg = 13ca022396285bf7b82a600b560208c54ee14f8496bce684895029027e6451a09f4eeb0af9b889dacfa4b7b934ae30c7d991523e23edd0528048a75bfc525335\r\nMac = 8e9759db\r\nResult = F (1 - Message changed)\r\n\r\nCount = 97\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 57a9d1ea216c69c6e360221f8c858a9d356598a8b253e2cf67f1116b5df5927f\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d381082f379b2cae385dd526b189cc10cdebbd33bf3d8db2b449ed49064d30d4b3a359110d\r\nMac = 41022947\r\nResult = P\r\n\r\nCount = 98\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 749f2fb720d321757473afc5d3a377a0eaacb425e5591026e3a1bae6a785b921\r\nMsg = 2e4f5149d67c955c409b63b04d95538808da6202e69a50ed4d3846da52fcbc76c7089a17758d9d94a63efd5ae7054dbc0bf5a28b7381f7e78debd0549bff1e11\r\nMac = 67b34b0a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 99\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = f8ebad761b9e73c77faae3fd9390093fef595e77e6d7f6b35e2dfccbde925c44\r\nMsg = 18430f34d5b5fddbd228a910cab9c48e1ba2b5f57819eacbde756cc0c993b736a778c8008d37776a2915077af8ecfc76b8cd2ca621e9195bd0b27e31843d2890\r\nMac = 7a446398\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 100\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5bb9fb83b6a85f017bde6c0ff3ced955b9f343cc71b680c6b591302f52759412\r\nMsg = ee7e6655424125462a96390e02bfee9d89cb271bd9bbf22a9de45f6b7e949343def818dfc93d777528f609cd38be0a013b1eef816eb1f9593a850bb7aec5b9a7\r\nMac = 5e1fa5b9c9dcd90e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 101\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 57a9d1ea216c69c6e360221f8c858a9d356598a8b253e2cf67f1116b5df5927f\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d381082f379b2cae385dd526b189cc10cdebbd33bf3d8db2b449ed49064d30d4b3a359110d\r\nMac = 430229471a1cf1b5\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 102\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 749f2fb720d321757473afc5d3a377a0eaacb425e5591026e3a1bae6a785b921\r\nMsg = 304f5149d67c955c409b63b04d95538808da6202e69a50ed4d3846da52fcbc76c7089a17758d9d94a63efd5ae7054dbc0bf5a28b7381f7e78debd0549bff1e11\r\nMac = 65b34b0ace2fc6bc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 103\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f8ebad761b9e73c77faae3fd9390093fef595e77e6d7f6b35e2dfccbde925c44\r\nMsg = 18430f34d5b5fddbd228a910cab9c48e1ba2b5f57819eacbde756cc0c993b736a778c8008d37776a2915077af8ecfc76b8cd2ca621e9195bd0b27e31843d2890\r\nMac = 7a446398a5c59ec6\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 104\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b228c753292acd5df351000a591bf960d8555c3f6284afe7c6846cbb6c6f5445\r\nMsg = c66d322247ebf272e6a353f9940b00847cf78e27f2bc0c81a696db411e47c0e9630137d3fa860a71158e23d80b699e8006e52345fb7273b2e084407f19394258\r\nMac = 129", + "e40ed97c02ff9\r\nResult = P\r\n\r\nCount = 105\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 8ea05a5033ab8b009664fa2800c24e217488ce6888cad14774ad75b2696e9470\r\nMsg = b3f09d990c2f41c8707368bba007803621ecd76540cdb8705435d74f4300eee04710a936f241c034709e625b0dd5dae1f6e86d034426819c365a05f5be420cdf\r\nMac = 08e5d5b3facd3b01\r\nResult = P\r\n\r\nCount = 106\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 016b5537198ed152670c5fcfb70ade276de97ce0cb771c5f6f66fcfe1dfd945e\r\nMsg = 7ad591e67c6a3ce3c9f871e328fc4ce3b6e7048e80691da551efdfa4c96b06a3af53bb7a88ecc32869c8f776098df4d71af91393da239c24e50436e04d35a2d9\r\nMac = 36df9931a14dca9b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 107\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22d5d4c3a3aa8d2fd5f25c08b83cea60e94058e8235ddd050646b02617f82854\r\nMsg = e86dd3216500273d0b6150227cf03adc20c8a5fed4a2799fdff759a327657a3ca554b6af16d9dc5cf3db4bf9a474bf1ef1996a06b9fe4794e634ab94a0141d44\r\nMac = f0246b4959d2fa89\r\nResult = F (1 - Message changed)\r\n\r\nCount = 108\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = c892b095173076a40e24522297be27fd3a765c8d417f24c71a9f03b3fe3d8e20\r\nMsg = a96c4d5c89a364263c97a453308b9360bc0ed868602b9ff54fe13f162ad31ab20f3fc51bd2346ae68a006afb50e846e8431dbf7bd0eb3c8f30326d26311a2eb8\r\nMac = 1d943a8b0c470221\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 109\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 2c87c0d64806fe303c5e97bccf48360f89374b6119319bfaf8defbe74adf58f1\r\nMsg = 37c6206e23163c39a13f19de48cc25dc26e6f83cb376e8d2048ad7c141fa503d594bd395f4d36c70aa1e8a5672910f735d4da49884574f833ef54760975b0790\r\nMac = 58cb614230d590f4\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 110\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 028600eebf6b3eb04d8fac18399965aa8fb5f3954d3a657e188ba17f2e3bfc70\r\nMsg = 5b80d1cf745b14cb71cbc8dfe0bc7c7358f721c00099b3e250c41c2e1c9455c5ce55ce69f3f31090f9b1a1b7361e27f92d46d1e00d25f37b7b61f0b191385dd4\r\nMac = 02587102e6450de1\r\nResult = P\r\n\r\nCount = 111\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = ea1a626b623e9440e3f6f5c0b8b63b9967374ee82c1957fca5cd195ccfb2840b\r\nMsg = d082b2aad7058c3142021457d47d51d8ebaab62ab452f6039e771a1b0f3bd03355fe0656dfc7b75fade505bb05d689706867e75ec41da5c5ebd43d0844a670b1\r\nMac = c874df0a8aa87c5f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 112\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = d1155265fe296f374366dbd11f14466df1ea210cc88b0d1876509347e64815c2\r\nMsg = 3e3d3a464b2e6030be877f8db4c1c42bd2b8247adcf792ee833675a57f21594ade5be4399cc30ce373f68874f41584b4d7c8992b9082fc892307f645382c9483\r\nMac = 6bfdc96378f0c8f2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 113\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 9bcf914f787fd3cf62c6315a12feee358eaacf1f63ac802932b933c86b098a29\r\nMsg = 02c8b892b13f04d99b875b8aaa32136d19dd6b9c2a10d8871c66993a57ee91e3ebd0568e38348634ee5f5af4391f7da0356a1e7ba8424441f0db61683a002ba6\r\nMac = 365da451a2787193\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 114\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 35d5df6d714e2ba5b307c4d1908e108bc6fece682a23aa35e2de0e80d4cb3c5b\r\nMsg = 963ef1899cff6e0a6dcd80a27b63c20fdb8e9fa1ee3e14ed40ddb7c6b0dff969d29ba8f89159b82a19ac4240f402cd3b7279cd4c4ff4698c906f81edae8ff070\r\nMac = 33995a3d9c470cf4\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 115\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 511ab5e28b6fda481fa5a0fb3709b249fbf29be56346378a4d3f67e1cd6f09a5\r\nMsg = e4cbbf14f27490843b0f9a17b4520d4bb2c89726f4c788cae4a3344a1a2198bc222e41907fd16a20ef5f6587f1ee3cb7850b97c633b0e0894e70a6647af53f60\r\nMac = 3b4aacb52525b58b\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 116\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5e79f14d5f687ce62b82f856695af9f7dd350543ec763de75b593f1859e44c2a\r\nMsg = c0dfcb62fbc3a67ceb792b3428d040ed5e50999296702472b709a44f4c0b9bb1876f6e80866cc4d2d6ee2f0236440e029d18b2f27ea5bff14a24d53337877053\r\nMac = af30acca71feba3c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 117\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = cf8a477434cc679e52dc3f3f3520eb108239dad5bb363034bf0768c790343e70\r\nMsg = b891b1ab5a6919e0b99013e40fa7c910e55a480bd043d3d85b0b7d1342d3f777e1d2a6a4eb3ff81f5f71f99bb845217765c0708778f5be17a2294c2d5f369e0f\r\nMac = dc10e268f5f73bbc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 118\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 67d77f50727c7cd5b38e0b175a888c88687c97f2ccaa3daecc519116a7c5683c\r\nMsg = 02c5c55e7677c84a199d6e534772123c4e5c933622cfa8ef536e74cb3d745b717f53138aae9bfec54a1cb71ff04feb61d2f26aea65f37dae598f7b7fcebb978c\r\nMac = 885050ec166faef6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 119\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0091d39f3478d2c59bf874b96db9ce0f7e8b85a9b805e07dc96b219819d51663\r\nMsg = 7207aa8fa87283f1f57019bf1c89645ff8fc36ab1102704e6d577671a9f7e098482573c64ab24fe8007c697020353c411566bccb98b38c7784607045e61405b3\r\nMac = 96f639a86a2d698e\r\nResult = P\r\n\r\nCount = 120\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 0e6d99ee5137c8f6b9bb45a961be8a29358a91189cf9974f5bcf20d3b64c3b04\r\nMsg = 543ef4638f1322131402172d193bd304b34e3745ecedb9db16f35c0f5fa6\r\nMac = 33f10660\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 121\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 82421ddaaa5767a496f2b78f816cd1e1e6699f6e9e6576c34c909ba5f8dc06ba\r\nMsg = 4e2f0f91990b855a00d27fbb2e8db7184cd82909de361b52e7a75b16547d\r\nMac = 3f5ed151\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 122\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 134f20cb62084a98601f0e69d257fd2064beb47248caa79720a71d461ed07ce0\r\nMsg = c248fa87a6e48cdfafd1e5ac00f95fb1dfda861465747265796654dcff54\r\nMac = e7b21645\r\nResult = P\r\n\r\nCount = 123\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 98505229c1927d13001b53850d0b7d56f49087afc6c2351190cc1b998e4d6883\r\nMsg = 9bee2e347f763c5c506876bb514b5ba1248abc6b3d17cd4c96537d4ea432\r\nMac = 2c212c7d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 124\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = cad710b48ea0bce4a897482a535aeeaeabebb42619578a9d1296927301b3bfa6\r\nMsg = c1db23e776272765a0fee49edcce28ff7702b9ff9b6e31a4c3ed0c497248\r\nMac = 7f27420d\r\nResult = F (1 - Message changed)\r\n\r\nCount = 125\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 0bbf4f77a9883733590a3cc7ee97f3c9b70f4db255620e88cd5080badc73684c\r\nMsg = 7ff9ca86f820e4d57995d450611009ffaa726e6fbe4ce1558ca1e775daed\r\nMac = b2e5a268\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 126\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 6efabed650ce05ff22b67768e3bcc88c7746952106ecea92a38707af2b8a64a4\r\nMsg = 9cbce402511b890c8c9fa215b59c813b3e51b5dce01e776327f145623002\r\nMac = 03728e46\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 127\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = ca2843847a1c9539917206d344161dc40b379fd45dfa6a73ba6fa14defc40920\r\nMsg = d9365304c4363fba73feaa69d4cbb343a76eb2d29de6782ebb34d873006b\r\nMac = a94841ee\r\nResult = F (1 - Message changed)\r\n\r\nCount = 128\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = e5a1108da9cf587bcbdf051e216231bc27f0e6c1e97729b324d23768a89e0e77\r\nMsg = 536d4b6182a698d456e1fd9d522aab38cf05656f41a5e02cbd5e6f8cb85d\r\nMac = f52a4ba3\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 129\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 008ee06bf9b19536190e87820af9cdddb40aac44b0c3b1e50074fc29fe5cdff2\r\nMsg = c1eb4c800c631d9f387d2e8e431677b7fc8f65235ad0cf9b118d2b0d67c8\r\nMac = ba255bd7\r\nResult = P\r\n\r\nCount = 130\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = ba0bfda3b03c736c121cf9a257db55060b621be5168619ec4182f13ef6a408c4\r\nMsg = 69be384eb107340d953753e6a860ea2710e662e8953de8eff8f465d086f3\r\nMac = 9f650d24\r\nResult = P\r\n\r\nCount = 131\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 7a88524accb59f1c6307a1719a011eff211df24645086c67710ef539f5d3f29a\r\nMsg = bebe346356681f27bc62f0b838a25268e3b04194b865bf83eef2c8928625\r\nMac = b2566e6a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 132\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 9c956d7bbe2028739d73a2f0a80af5f2f180de923d5571e65bee0b25b5dd890b\r\nMsg = e0d2ea49e3e4a5823efd1b229c705ec3bb5048a7658f10fba2671c5d2cf9\r\nMac = 480a14ab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 133\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 2090b970a71ce2cf399a0d9e1d3d72c4eb500004abcba1303b24bf9af16707cc\r\nMsg = 0e0ef2cd18533bee01f19870f2fb22176c7e04748db4dcb98f7a65cc9104\r\nMac = ddb6f30c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 134\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 66921951731e95bbd45c014af5cf623933350dd9a90d1a36465716f8239bf887\r\nMsg = 0de1e090eb47dd4fca966e5f8fa5616618701164370d8a43fae2eeaf3016\r\nMac = b91b3131\r\nResult = F (1 - Message cha", + "nged)\r\n\r\nCount = 135\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 43c1142877d9f450e12d7b6db47a85baca7eea7fde595393fb394c1f34369aa4\r\nMsg = 77772e91be674abb0f496b47dbd632e5616177a0d16a8c11b271c2d38108\r\nMac = b2de16cc\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 136\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = db4b6206d001af121051cec70195055fc1fd0dc06ccc74549bc440152aded5e7\r\nMsg = 94394feda0528fcc67124dd1d77f0ec0b911f08c3e01e0c0dbc40c1d57d2\r\nMac = 5f72de94\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 137\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 4d658be9cfcdb19f79abc78f4d7f986d02b43a03098b37c8ca56ebb331e62d51\r\nMsg = e28660f57b044a44a19ca40ff7b6469a41523e8d1cef22f4edaba58917ab\r\nMac = 11fa4d1e\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 138\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = 70b4cf3883fea8c6cd852a4293c7e5cb0586a6cd71294883b760cdbbfd07aeda\r\nMsg = 4cb9aa069475e54b25e5688a52dd4acd134169c858105f01a0a1b134c72d\r\nMac = b6b60815\r\nResult = F (1 - Message changed)\r\n\r\nCount = 139\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 4\r\nKey = f75bb63d52c35137448c58383afe47e026d536f67e3afdff87f29b10d3d6d9e0\r\nMsg = 4259e4fdf10acd8da40accd6354f4baef4859a2f5ebada0d2c5b1b26905f\r\nMac = 336ee1e8\r\nResult = P\r\n\r\nCount = 140\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = c938f6bcdeca02939fef931c969a25edcc3daf338d8286016e3c7ee78f9d52c7\r\nMsg = 47179ddaa9d7ef6b9a53c646325c80db69128c6fc4f92ccd345078383b9e\r\nMac = 5cbd65df0ca36898\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 141\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9540e4bdd8c7ab99f0b76dd9de24c340a60f7706f680448509d5dc35cb5930da\r\nMsg = 4715a9a66d10b2dc1869d90fcf9b7fa99e91b40abcb8fc356b5853c92024\r\nMac = dcbd4dae7cc60d46\r\nResult = P\r\n\r\nCount = 142\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = d5c396fc1ee960215e57cfeeea1e792fab9334f2c45dd93e74cc47023e6daa4c\r\nMsg = ce188965b4d347a6c36a6fa5a47296b32ff0fa27311266b16b1d56ebdda7\r\nMac = 1684fadaea17bc79\r\nResult = F (1 - Message changed)\r\n\r\nCount = 143\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 897193cbbccbead9957876b8b42a77b404aed32a3f63bb9ab5f08cfe4936f35a\r\nMsg = 87767f13bb4904d0df0d64eb22c9ddb65e81b5739baad86ad5e2c239ffde\r\nMac = 84ef6f59b770d42a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 144\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 86aa015253a7114e1770b6a48fdb3ef22e9d5abac25fdc145315c09f4e8b69bd\r\nMsg = 2595cb8d4d6aaa148596e8502ec80a030d82195f9e1d9a26ab0ec0101e67\r\nMac = 63e67c44ecc05dab\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 145\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = a082c12e97bddeb0c74c13aa4ba788f8a127c44fbac6682050271dbf7ad6cbc4\r\nMsg = 7fc97a698d7b0eed7d7602a5d13e956a538c71c4b45978a47439c05601ea\r\nMac = 3e1fe077fc7e903b\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 146\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 18716638a2f6b4fb8dd2849fa9aab80b8dc846ee7e6b3cb0926101a814d8dd8f\r\nMsg = 6593194b9970545c5a910b2b4fcd46f0ddc7aa0bf873f0a339d5958d310c\r\nMac = c4556a75b754f6c9\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 147\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 6237aa30f1e3df239c96e7e50b69496da9305951024fb83a6fd01e96f6b2578c\r\nMsg = 0c5b7d1ba68654cd24871964f1b31ef7900dabc025baa02d37b55b35b4c4\r\nMac = 22c74fc64489ca5e\r\nResult = P\r\n\r\nCount = 148\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 32f60011bec76a79d2e837c611fad1cad486ee6f2aeeb74f1ea32a7e3899bdaa\r\nMsg = cf772bac3e767534b13efd381119b66f8a99b91aa52c8d3ab5f0a60073c9\r\nMac = 08d02ce41d4964b9\r\nResult = F (1 - Message changed)\r\n\r\nCount = 149\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = cb6cee5ba7b799f16254a17b1870cdb85fe0ef3f42110c138742bd7734f0d504\r\nMsg = 40d3c65a00d9204b76e013975ffd729b351698105d47448da285a84de281\r\nMac = 4cc6718396dbe247\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 150\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 9b8cdf91e848eeded2598ccdf084bf591ec2eb668236f555ca61a9d6b49959fd\r\nMsg = 7b3cc6f18a27047f4cdc35404e44eb8e51b1855d4bcd54ccafd1fcfaeef7\r\nMac = faf72c383b56a4ef\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 151\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = e6fdbe9a1efe081bbcfeb25b844734fe60aa6b80a5b5f611982de1a331b88041\r\nMsg = 59a0f85349c3f378d56c509a0a45a1512b5072474b297f9c1a8c24890016\r\nMac = 020354f33df66723\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 152\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = da360852e8b8c3a1b65af9e8630ee5481aa91dce414166f8f3dacb75b142f12d\r\nMsg = 61d908e9663fb195afc259529fc229b14e87995f8d3591b125fcce816090\r\nMac = f8963157ef7c1ba3\r\nResult = P\r\n\r\nCount = 153\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = c9bf0e7e470d0ffc88593796c4cf9a61c6db81d343305ee06a0f0563bcc618c0\r\nMsg = 19378e17c41586b88523a6b6af738dc47e63ea64b4b83fa283f1e502add5\r\nMac = 550523c0347fbcf1\r\nResult = F (1 - Message changed)\r\n\r\nCount = 154\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 7129ca274190400720bba27651f1ee0d5aa79116af9929418e198f9928a715b7\r\nMsg = 891e73a81d7574ce6f73e09e08cbaa0b9db242963f4469cdd2234512c061\r\nMac = 9982a14d261a4060\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 155\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = dfaa73c82a978548c99c0f1c34e1edc2c4edd42b73613511e4e6648ba364f9df\r\nMsg = 18044ac51ea97341061ae7d5bce017fd5cfb1554a384a75aa3919a74ba59\r\nMac = fd3a17e8c51a004f\r\nResult = P\r\n\r\nCount = 156\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 6f0be1905d1b5b607574ad93a1e7b4a536020fc6798acae862253916a0562707\r\nMsg = 8e502d5af4701025787e5b251121676182a0b26cdf52847f4d56d2ca0983\r\nMac = 73d76950066c77d0\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 157\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = b9fe826b0138de8184a3002d8bb59d228862e4a14f8556f88282d8494d29068c\r\nMsg = c97ca1930b65064b70d12fc46af4d5e220e6009e729a28a13b0f9a11d3ca\r\nMac = b8bccd70bb90084f\r\nResult = F (1 - Message changed)\r\n\r\nCount = 158\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = 99c8f69fb91b17299461fd8d633bd516dcdb172760695ec476a5775377cdb7a4\r\nMsg = ef589e3b4ad9a7ba390574a2db5330baea64894f8f881cd67b842dd23393\r\nMac = 38e11613e67e0416\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 159\r\nKlen = 32 \r\nMlen = 30\r\nTlen = 8\r\nKey = a86e8b43a1e81dce7b26420c0409628d145445d1c512e1c3df3270839475c668\r\nMsg = c71a0d1e20a7dc8e7adea91a408ecf3d512bcb15a6d8fc1435c6a7f915bd\r\nMac = 101c06c22819404a\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 160\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = c5a850167a5bfdf56636ce9e56e2952855504e35cc4f5d24ee5e168853be82d8\r\nMsg = d4794f6f563d5f6445450b59c1ff95d24eadc9c02b68eaa5df64edf81475e5cba8d2bfab021a2fc8\r\nMac = bf99dc0b\r\nResult = P\r\n\r\nCount = 161\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 551e188cbb7c7d1ff33b4bd5bb6c60da184b18f44d68d5c30704df47d8be6fa2\r\nMsg = 2b421be47d07dcb12a0706f7490d05024fce8f433079e18ec78f4c8678f5f1551448c9a0fc70e8b9\r\nMac = 32aeb3d7\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 162\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 000da8307f0e6112f0b8a8b1f927f62e8a9e5aefc0d37995088dd32e867148ac\r\nMsg = b89266f3a33e5b6883206e44f8e8e0cb01275039c304960e8630f0aa011c5c19d769443061a060d9\r\nMac = 1b5e30f0\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 163\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = f4ae2113ce96435b27369fd4571ae2841a965c8ddbfe61023219eff9abd490e2\r\nMsg = 433ea4e1923267fe443e1e89d2472834b72ef97323ad6d82f3825ca9e1d06fbff8c232ed4c716ab4\r\nMac = 05b3c894\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 164\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = e7c78ef4c4b959ee00cb1a09d71221a43892ef8ad705edd27ed85d03a377907c\r\nMsg = 4da25d1e7064bc4b4903a77452952885a06ba0712544210d30c0182533182fcac90b71e9f71caf22\r\nMac = c15acf48\r\nResult = F (1 - Message changed)\r\n\r\nCount = 165\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 6f48b3bf240525adcb02985900fa29747e4b1265e5a8899abb0ee51cb0f90367\r\nMsg = 98bf67b6e342dd94c948e76aabb69e7d091d24fba54ae233e4181404768988963915a2495b42a4eb\r\nMac = 71bb5873\r\nResult = F (1 - Message changed)\r\n\r\nCount = 166\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = cb6cee5ba7b799f16254a17b1870cdb85fe0ef3f42110c138742bd7734f0d504\r\nMsg = 40d3c65a00d9204b76e013975ffd729b351698105d47448da285a84de281bc3307cfd80b39488213\r\nMac = 592e54d4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 167\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = bbab624862e268765e9e6a13df55cf7a2267520e4e66042ba0b4905dc554c3d0\r\nMsg = d43b841f174335f1347834590b0984a2cb35f7a00a0ee993157d2d4f8487489a12ceddd6ac5b69e0\r\nMac = 3480805a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 168\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 2fc9e8f409cc6c0156ccf9f00686ac7abba6cbe08982a737fa08c7035", + "6f54208\r\nMsg = c1cd63e24e41f69a146b448cee0a2107817c8105732745aed817541eede8ee6809e73ddbd0742d84\r\nMac = 91623558\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 169\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = c49dc812061fa4995aa7c160ed7cdf769dd1ef570d8fc9c7f8552101c5bdb711\r\nMsg = 74ec6f53d188be3bdb647f37619fa5848076c66d21bac164c381a4517b1dcd2a384a4fc44cab97e9\r\nMac = 07471b07\r\nResult = P\r\n\r\nCount = 170\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 84b6cd1c6618c42ba74e746075dc28700333578131ca6fde6971d2f0c6e31e6a\r\nMsg = dc79743d2360cc52cee202b9bde9abc7c09d9d0311d89c3722da36c7993feb42992e913744d2f74a\r\nMac = 3acba1e8\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 171\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = dd472b0bf50519020a182f122239d161d9659773b4df454eb378fedc250eb490\r\nMsg = bdf56403d5ff8df4ffca92eb40d54a79b5595abcd67b9e2ffcc5cbc621d7523be75a87a2dc360244\r\nMac = 3bb0894f\r\nResult = P\r\n\r\nCount = 172\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 00ebd245e8c0e0b60847da5c8f7a1f33604932b9cd47a845a1a44599645b62ba\r\nMsg = a238e542f1c22621aebbe331e71123ed7f2591e4192180ae378c2c24a31c42d10fcba3a3f82c65e6\r\nMac = 1d17d6ab\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 173\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 2ecddb226ae668315eecf107c344926330b94077e029ac3bb67e6a077ee05361\r\nMsg = 38ee97f0dc635c7416a024e3af5c95dd1d496db8a5a5c3bcc20b9093ca906dfbcf0b9ebec3b450e4\r\nMac = 08834104\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 174\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 0a2978b5f20d3b5e5ed7ed5a78a093a51d5aa6e728077346f429c27f1c79b635\r\nMsg = 28313dfdc449628f4e2d6c895381844559067823cebb56cd41493ac0d29d6408e7d78d4a21637b08\r\nMac = b2635d7b\r\nResult = F (1 - Message changed)\r\n\r\nCount = 175\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = 7f2286d42b4f9eefed1087f3eb3dc814145be4a110c0e74176f83e7d4068cb7e\r\nMsg = 6c1aa088d1a6086d0e72636744a6840c80ab8223409c61b733f7ef6a4199ed0ccbe96f6c3453866e\r\nMac = 10bf9789\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 176\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = bb0fabffbcc6935ca35755fd4bfbd192b6812cf75c4dc95bc3a175a1501be206\r\nMsg = 9801da81a6d9861f26900401aeaec89a74e3d5aec0a5d612a11b6bb4e03ac1db322e65afb1fb5afb\r\nMac = 9ad23631\r\nResult = P\r\n\r\nCount = 177\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = ed1d11cc4876f58feefc463b52d8d36e69c4c2c9227b32fe356d1e2a1bb88466\r\nMsg = b16e6c44f429efdc06a892cede56296e12bf185d4b3c6953f7d31b1c3d59bce136d93aa95a3af61f\r\nMac = 29b26a75\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 178\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = a6fd8382447181bd300ec1ef039d3f353446d01fde490509c3ef52a992bf6fe4\r\nMsg = d41f8fbb6f968dda0c1b2cadbec04a6c72124eb5dc40b8d2b180fd3b17af915b5a374597e036d38d\r\nMac = 2b343893\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 179\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 4\r\nKey = df0821c9ea6ab329c626d11b4bc1ba7351ca934ece6aae483e3d0bef48601f78\r\nMsg = 84b9c150a1df00ba29386197d79d29a2ceb42fe6390c9e763169f75fe15c55dbe817f5c7fe80f557\r\nMac = 3a5026ef\r\nResult = F (1 - Message changed)\r\n\r\nCount = 180\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 0f1b73e54f4571b2d42aa5ab673f3e99b44f6c37a07a5d4edc7d6b1fba349401\r\nMsg = 3918467effb5d5dc009aaefce84d8cb4fe8f80eb608f4c678f5d0de02ea11e59078d38b04f10de73\r\nMac = 1c207499e0877bb2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 181\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 25a152850b4b80b19d8f0b504b2a8a241824b3a1fca8d85c8713b2c0c84b5e02\r\nMsg = b06f6b3f197bae7d8cde9daf38530e25bc51b68f9aa23ec0e95199b14bca96c91f3db15bf8432f71\r\nMac = b860013252ae83a4\r\nResult = P\r\n\r\nCount = 182\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 849d861aa5a37c6389f7bc2fc3b4860fac9d2277fa5e1a1f9415a6aaa5106886\r\nMsg = 191b53e0c7d90161e5e2014e9b8aea315b4bddf5750aba4be69c944d71896361f210f961ee6b38f9\r\nMac = c9dc7e167c2e442b\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 183\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 29dd1ee0ffa12de3a1f2cb8e4e24d2e548794a5e7e372f946bfd733f3c564764\r\nMsg = 891c806e0700f6df72befe47ff088d917cc30763866810a2fcaa9f38b45953156c860b7303e8b15f\r\nMac = 2f7355b3994f45d9\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 184\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6cd7349d96feffbcf6e95a96eacbbe8ddab702ef70052b7804f78518589df3f7\r\nMsg = bbe054fbef86db3ce7ad796e6d0add15455b9cff57fb787610b4e1ba05d5bcaed98564d16157ee70\r\nMac = 8a421387c53702d3\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 185\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = a32e186c29f6f1852b483a37b50c02defeb2ce81488198bc082c17fd47a741f4\r\nMsg = e687143dc4d98dcc6a2dfe6ee0f85d565d1f46bb0fafe62a17d01720d6f4ccd86754b0626c9d0af5\r\nMac = d44d78445c5ed8de\r\nResult = F (1 - Message changed)\r\n\r\nCount = 186\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 338f8054d58c26c49360c3e87af56523acf6d89d03e56ff2f868002bc3e431ed\r\nMsg = d42b10d3a688c39edf543ae7330466eeb9e3b678ef073967ff83038d40ded1c200c4f03481fc5aff\r\nMac = b25bf6993f18d503\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 187\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 96e04382027fffcaf779c984be80da16f8437db0e39a7123d9048ff71954acb7\r\nMsg = 494c8f931029a4919e2dcbc16512a8bfe275382e7d29c9abb1d14a006caec59ab9b52a3e9ce54ef7\r\nMac = 5a94a03591ee9cc7\r\nResult = P\r\n\r\nCount = 188\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 682f8bc1eafd4d369df384841a88db7b7fb96c9dd9abd6dedc9290a8d8d17d22\r\nMsg = 87b937b1d36e8a9ab33a1d3eed617030923acaabc7e620dfcb3c388936030fc67f647729c19e040b\r\nMac = 89347722a73d8bf9\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 189\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 954222a9cabaa5a0a91100b158a3aeb655c4473d0b00afe6a7a78e0d278a01a9\r\nMsg = b9197eb50c8168d16b8a12bd261d553ffcc521d979b26fee820376252e452213d736c21471cf0179\r\nMac = e5d175fa24cf0fd6\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 190\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 18349be2894d49290339b97f4db28c92b3e112ffac77100abbf9c093935b1a46\r\nMsg = 4b02fd5a46ac681a42424ac9723911af4e389ac73829f36f60916563e51cb2ec3d7d9b55d674a59f\r\nMac = 18c98fd13595f857\r\nResult = P\r\n\r\nCount = 191\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = f1f9fdfa9ae3ba8bc6fcdb2e15ae2c47e6292c2acb091fe03e325f298ffff3bd\r\nMsg = 75965cfbf66b0ba13274fce6537fd7aa4efa5d75195a400018bd38f7d8cd53fdffe88df1837fa06f\r\nMac = 935e4d4367aef07e\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 192\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 4652bacedb47faee1be641ebf433157f416b4c7d9e8c7c6f7b17b47e70156993\r\nMsg = 17e6acda3c05c9549eadad55d8918f4870aec63a18802fa33175cf838fa2b9b17cb43270ff2a1444\r\nMac = 7ce4adc343a4498a\r\nResult = F (1 - Message changed)\r\n\r\nCount = 193\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 200e4929c275557d9caab0ba3b0a153dd8010ff8f11ebc1f336dd0249d01dce6\r\nMsg = bd05d26ebfcb5f6e102e79976fbd038e02da6a64a6be90bb84bd092be5cb8ae447409e94afd89b8b\r\nMac = 5484fd10e83798c2\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 194\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 8c6a6e77534976b4d74a0972742989dbc0f753281a5ff10a862e9048b813b4a9\r\nMsg = 869c482db2b0825cd09d295749359b99fde85240e5ddaebef642f4d249e096b77af2b59b4e37e452\r\nMac = 9e640a86d55be78d\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 195\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = be3db75687360fc31c27752a5f32125cf04f8bbab694339ebcb57ff63fc7ba32\r\nMsg = 33dfb223c009001a7b3b81916bb094390c42c24a47884fc8a0410f05b2f57b67d8d9046b2ef4a8ea\r\nMac = c7666f25d2329fb6\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 196\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 29e7acc4facc2618f242ec9260a8ec36c4c9dabb89bb8092f00855234b0c505a\r\nMsg = 09bf4f77a9883733590a3cc7ee97f3c9b70f4db255620e88cd5080badc73684c8b80393302ca8803\r\nMac = 424535e20d082087\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 197\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 23f0d00daef3177fbcda6e9953a5a37d5da395204d8af5fb05c74e03f71343da\r\nMsg = 2222135e545f2af53be42d7a463719447e0a6a305fbe8e43e6279a91eb8f3c5db1fdf081bcb77711\r\nMac = 52c42541e2e93f3e\r\nResult = P\r\n\r\nCount = 198\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6746d9a90e0e763679d5469a1bcffcc4f18f35f50c7714d14c7329b76ce7984e\r\nMsg = 68530f15423071410a349872c559669301096c827333adc4df9da477387c89870942d12513b7f475\r\nMac = 2bf36912e1139629\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 199\r\nKlen = 32 \r\nMlen = 40\r\nTlen = 8\r\nKey = 6b1d94bc0c6e45fc905c509ea667853e4b2c5a8848dd914efcef14d95b12247d\r\nMsg = 207b649c46c1963723624d8428d4b64c08cd4091cc055175223d3758f880614149a9cf7f3725c790\r\nMac = 34f46b361bddf55c\r\nResult = F (1 - Message changed)\r\n\r\nCount = 200\r\nKlen =", + " 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 5c77fe134af3fef72fcd16006097dc7dbc45ca10339ae3bc85e0993e4cdcefa1\r\nMsg = fab52c44379ae8083bdc7b827383df93cb1a7ecc21574730f9fe003b7302de237bed535d40832763e7a2cab5806de91d39aa3f38d167ae3250e48ed1f6ad45b5\r\nMac = 03f36c5a\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 201\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 997c6b4b513bbdeaf701867bbe81bdee63de0d0d18c870bcc1e9ff7f627f093e\r\nMsg = 4c23d92665e88a4f6f732de384034d493d5df37b767a8260557de05688e8d60dcd0eba9cb8cc4bceb174dcbd3c0ab5a37db3b6ecfb6a3d90a4f54a9f1117e11e\r\nMac = 9e798c73\r\nResult = F (1 - Message changed)\r\n\r\nCount = 202\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 64e390edd97c0af1ba5165900828e0630606f83d4df5240e1b05c307ee9153ff\r\nMsg = 1ae71094fc1b304adfa3378c4efa8fb290526bb314714c9613beca2a709c91f7e3f6aa74561bfc7b8fcd12f910941eea3b593e85ba2fffb31e7420c6c6199868\r\nMac = 1977347f\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 203\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 44e2f6d41e04b75f541e724c6f6325f27d7475b3676fa0247f28b36e58b6fdf5\r\nMsg = b9ac624288352617e4d375f33953b431cbf8f03f9ecbda9893330ff2d3c59db8705dc3ba4a6ef924309630ac48765b10b1c02ec0669126d76602c95012fa2f77\r\nMac = 2cba4713\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 204\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 8e0f75b7029d4afc2a86adb4a088b89ef9783965027c1176497ada0fdfd0cd99\r\nMsg = 21cd3ff946e2b3c1c61932205899502852b1333d1c79a3d4e5b6617996ffba17041e5b746ab967fb1632c7be62cbc2bbe60ecd5eec6ca4482424994f9a662cc6\r\nMac = b651d356\r\nResult = P\r\n\r\nCount = 205\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 35b1106d174acce103ecf5801b03d3c10d579c4ee491ebad25fb6f1f1787e0c8\r\nMsg = 960026395d0544975dffaaa2c56db1df5816cd80cde513dc76f6f81d21f15c383c97c7233c9af2423fb28922efed2f69aa47c30de17ae1c5be17acbd0ad6cb8e\r\nMac = 8a8f65a8\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 206\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 71efa75961dfd60ad533082a8cfe111214eb02573adc4591c5d0e961640a3ab2\r\nMsg = 6bafbd22b75e21e1fa5444af283e69d53ac2f0412f717a2153f74eb1c195fc5127d240dbc96d2833c9957920a55c505a016a05e4a7ee549bccdbbf1095502e93\r\nMac = 88fea081\r\nResult = F (1 - Message changed)\r\n\r\nCount = 207\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 11752eb8aeffa364c9947092c1612461cc19b6c3a3ddd1817b5e6f7f3745a942\r\nMsg = 2d9109e7eea21b2615c81c03182ce6033c93783b13d698624392bd2a8a202bd0ffc860f29b31afa2f71c2bb85752c66ce8dbba244671288a4135ffe2e1a0209b\r\nMac = b5a26c1c\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 208\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 279a6c226f6a48f3128626012baaa309d99065a59dc0a4c003a6e94d85e61638\r\nMsg = 9bff96ba07a52d9ea2415283321395cf57cb37c610fad7a482c74de9f5e3d7f520bf73d4a6fc8b5be023d774dd9680b6a7c68139c8a753a80d61c9978a493917\r\nMac = 5e281941\r\nResult = P\r\n\r\nCount = 209\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 0bcdcaa87ddf8bbe6db8411d14bb9064e4a121286cc8a6e97fce1844935f436b\r\nMsg = 3ec0aa8d30d5ed825b77dc7095f421b1e608158797a377ff8bed641bd387832f7c14818cabf9bd5ced6044cdc883ff7296272be693660ab234b2d870ba170131\r\nMac = 1da79d07\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 210\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 1b41d148e3c202d419ce16385139da196dede5be63987e6940a2bae86d62e567\r\nMsg = 13ecd70e2d76dd53a19b2e5fc0afe0c0793577ba8948b7d4ef3ab797a07a37927dbb33a18252b96f40e0f73a8d3298d67a6551f5854eb6a51019531a122ff8ae\r\nMac = 91bd49b2\r\nResult = F (1 - Message changed)\r\n\r\nCount = 211\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = a1ccc9c992c8a307ad39504854456696f8eafd7c8da0c0c53b3a4485570e985e\r\nMsg = f68b0c3b4556c7f8866b3fa873ed2014418d6421d3f224512e5dae8c2d8dd92175e09508acbcc66ae62d536260cf790671ef66a1bded0343ace4117c1b8d7764\r\nMac = b9317feb\r\nResult = P\r\n\r\nCount = 212\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 4d8d0264ae6d8f7a7440dd760e0ded25a3a94cb0491fe81e7b55221ac8ed24f7\r\nMsg = 5faaf6b8ee8ed5b56bfc1a7f886f9f91a6566ceb99c39462ab675a3ae3be98f68787626fdf77e6243c2e96d1396a8a43417b1f6a51f7e5b0ffaeb889bce02c4b\r\nMac = 3f610010\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 213\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = bcf95051ae2ae84ac32a763d5477ccc4659a9ed3e25de5932939826dc90e2464\r\nMsg = fce924dd27db3e07837694c34f576c16084e5b0a254ca3af0582bf6026c73b47973ac924b02992490032cae987a887932539d3fa53cdfff711b03bd11ff464bb\r\nMac = 7b7e89ef\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 214\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 45ce953ad31ee9b53a9c948883bc86f4bbe0f0744085a9943cbad1066cd7b4f3\r\nMsg = edb1aaa7e8ac37bca99ff8eff5516464aa33fc2bebef8a727d43abf971108bc604aef019c3837aa2f3d429f22fda1f305319a70d99ed77f902663298f855316f\r\nMac = cbf4addd\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 215\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = d60841cd71d7227ab56e767817760edba9ce2290f8da504b341ee2c1910b5018\r\nMsg = 365fea641559759d1e5b5581218486318b1c776de812b1aca6a9ba6b1c6e39c5cb6d5a44e3a474f709b8eac457e74f00a43ecd3d060cc7639696bd03730c70e7\r\nMac = 7406f935\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 216\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = d172f991eb697ffdefc57349dadbe51066d2744c39041cd55ca75024eead495d\r\nMsg = 6a91da64812b9bb41a026e727b4f77c384813da2948caed5a9846420c86a26b89f46b2fa6975b95d12452ca69bbfb65bc1c48a79d95c5e69ff4ab7316fe468e8\r\nMac = 6bd82bcc\r\nResult = F (1 - Message changed)\r\n\r\nCount = 217\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = 3725c7905bfaca415908c617b78f8deeeff286e0c2bba268d0de92c7664238a7\r\nMsg = fc4bbe329a86089ebe2a2f3320dad55a9bdac1133dd28ddc9ace9ed665885a2341ea9492d4cf4b7e1d0a95f308a9d613407b35b845cf515bbe7f2f35102d78a3\r\nMac = c8e11823\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 218\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = bb3087d1b5b0f6f14a532c3604c82874fb15e97a4b3883dfc50e71ffe5752d40\r\nMsg = 979a9f96112d1ea95eec2cdfdf48c55114472360aa7de24bb53761013af96b33f02b17ae470fece8aaf649d801b4040b7b5152f58a01e7852f565efc77b5dafe\r\nMac = 66466425\r\nResult = P\r\n\r\nCount = 219\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 4\r\nKey = eeb983439a03ee6a315ebf941e9368f90bb6845b03b31839d72a1946c17d2f19\r\nMsg = 6d5573c9279897d7d1602d8a95c04bb5ca3fad2dbe89a024b3651eb227e73bb559e7c0db08b215fd7efe64afcd24fb155989f2f8965d0e181389e6c4b8e244a9\r\nMac = 7f77d596\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 220\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 6f0353a0ad95df6d3190a251435f62c30ed6b9cc0dd024c3c316565cad83d2e1\r\nMsg = 83011a83db0524628b55589ba0165523ce7c916465eaf185805b97ec7f00fc01b82a3e356a6bbb44f2f8deb6425239ac8e26d4d94871c5cf4fe7017c649672f4\r\nMac = 9e56e4574dd01fe8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 221\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 777a22c5fa2f864a9233587e3e9634172ce25006daacbba97b68e7429c8266a8\r\nMsg = 1f7d58d65c36142620172fda3197d3c629bc7bc584e1aaa0f8b6dd320588becaccc39ad124b515adeb941de49ac31c851c5172c4e1c322e42e13cb5ab7f8db2f\r\nMac = 498dafe2807ba34e\r\nResult = P\r\n\r\nCount = 222\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = e17736560b1a13aa8e536500ea6cdb9a6757309aadf25a6a9189055a309c3f8b\r\nMsg = 1a6b80d506147c3c02c89f50892bd1f04d34f9f21e8307140df43835d17495c56a13be7a045be5441de01d84ea19d579f76e9ffa0f92376b5b13c0eacd3050c9\r\nMac = 52d3fbc6e5821f1d\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 223\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f31f2fb4b3fd8045b70d34b600a2697cbf7503be0d8cfb5cdc60f9312e3e2695\r\nMsg = 4f43702be4f0530319555d7f1a3356160f6cae48051f12e22a153d7e405c11494c31e6098e24225eb676094755c6d7e992ec0c8c1e2608e76a72d79d173a4e07\r\nMac = 71239a4c38fa04b3\r\nResult = F (1 - Message changed)\r\n\r\nCount = 224\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 10a678f591b4d87280f42d77a91635575e2e82ef610a7c9105c3a9418f932c24\r\nMsg = f7b577f1396b23c27eb637e53d3d92460270b001cc612fd3b4d68bcdd09c2d50571ea4350636324cc2428a087e7bd8785f8202791e3c2d2bafe084a1204e34dd\r\nMac = 5b11c1407904c15e\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 225\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b8728441226558fa9764824597fe254bf8c2623789541feaf6c007efeb0dd2b1\r\nMsg = 80a2be15809f12738f305be3a210ba0c933599c4b24b48257c60e8e3aae189dc6ec58ff1f9085a15405b26a3001a2ff5ff7e1932961490676c6d2cda8417979b\r\nMac = e73ed6c4f81b0ecd\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 226\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 22a877d974cdf4d65bbd77958b2b77fc5ddb33a221aca3ecb6d5ae76596f9db4\r\nMsg = ce2ce41f76ca7477972d38a3e8fad1122db34ee80c379fa01f884cf648d1670445a8bfab8490563438c21537ac2dbfbcd7bb24a132d6973cc62ba14089adf7e5\r\nMac = 0ff91813a56b98dd\r\nResult = F (1 - Message", + " changed)\r\n\r\nCount = 227\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 03fa02c4df99b8295f502e3145e2edd3ff16722b87092e708bc8d126cc1ec894\r\nMsg = ec9a9babb68e09c38617c9b16e8a2d92e711030bcda4b9e0ab35c4c2392b41692312dde30c91f32cd39cf5fe15ea0deaf3aa04a8157262acee78d7f94204d93a\r\nMac = e50d9a04f79cf9b4\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 228\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0e12df1bf17e9645c5507bc2069ca4611dc0488c9996231dbcee1c73393b26c4\r\nMsg = 86814ce4a867f80ce9b618c6aecce37c89851508bbb095c8f7c055f569c47a30f79abe5ec75f12b601298718d6f96ea1c1ebbe7c0cb0b7fb973ec5e6d5c6a713\r\nMac = 05338bce9ed8f495\r\nResult = P\r\n\r\nCount = 229\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 51c88fd98a7d82043a1500fc3d8a66ba7ab7760467c7fd89cfeeb22dd25762a2\r\nMsg = 0e403cff47adee3ec5bb6b178dabfc7d53b60a04eaad33a2fedd9db705358a4c73ab2d982ddbbdc941f1c701d4cac89e5c56fbbe0f4170029ad25e931713ba63\r\nMac = 38c34175627b07e8\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 230\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0feb23c7e4a19bcbd70bd300d76ec9045d696f8c9687f49ec4154400e231d2f0\r\nMsg = 0330ed97e44e8b15a49f29c72a7997d05d398a9d45dae41a6cc635258beb824362124691e86cb7fea46e4ab85bdf79e4eb30c492770bf6f0c42ea9bde37a0c01\r\nMac = 271a7c2e687d84c5\r\nResult = P\r\n\r\nCount = 231\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 5d649799771f9074d18a2477ccd4d9e136e01451c1eb2e8bb370cb79e0486770\r\nMsg = d715bc0520dbb86543e76fede49dc6be2cce59d3c0db133ff31efcb63a85514fe080da88fa1e788b9e73feb0503c4142bdc67386ac0bacf9311ecada23ca7be8\r\nMac = 42de9f52567b4506\r\nResult = F (1 - Message changed)\r\n\r\nCount = 232\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 4c96d520d8d5a54eb73f8f558e328d1b3e5ba360161fb8444739a40a97a58a1b\r\nMsg = ee409b050346fbd319c8630e4bc9dd6d055355fbb961f018d3fda0c1eea6f61248f43709737fb18d4efc4faf34a96c2f73ece54200367292692e36870a0c94c5\r\nMac = 28610f524d88e727\r\nResult = F (2 - Key or Key2 changed)\r\n\r\nCount = 233\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = b186b9273d8cd77d68c05ec5389b2f6e2f267fe6cd6e7cb35a3233c0dfe0b1f4\r\nMsg = 0df3fc6396f851785fca9aa5ffb0cd98bdecf8bbae4c82641efcb34d319e7643ca9c5e22acbde800e0f700a95685c64ccf399173f9123438dc1181b676490cbf\r\nMac = 8d2f69b44614485a\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 234\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 1b1374648d93aadb186326e4ca2b82fd37f7234712816fe4feb339a3a16880df\r\nMsg = 9a661677f1e07153e1c9c661c91901757f5b4d9938031f01a802773d6a9863b2a169c44be0d4546c4780e828ef37f3b389f84c1a41473131e9c88bcd530c7334\r\nMac = 72838b59593c011c\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 235\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f70b8a4eee3518bba071af55f25f7b698a5b7dc8865cdaca6d1c7993657acc95\r\nMsg = 795ee1af7504621aac329f5081912de545fa11174f3979b14f11aa30df813a235b467fd8f3a14734fe5ac9e39105dcb25184673885cd19bc70ee5a53dd4e8149\r\nMac = 93542734d6cd43de\r\nResult = P\r\n\r\nCount = 236\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0c456d199abae4758734f506c4e9ccdb767e4fd156d5a4085726f3938a516d74\r\nMsg = 78f3bf568f1c3f2866eff8a246a70cf0faee4c3078f3fb27c4bdd53312bf50812bac2280118c0396e610b4110a22406084c18283a30ce7c0e49c769817170df9\r\nMac = c4c5be3c94fb7b9c\r\nResult = F (4 - Key or Key1 changed)\r\n\r\nCount = 237\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = 0a8725bd8c8eab9ed52ca47835837b9f00a6c8d834ab17105b01eb4eb30402e7\r\nMsg = d7867ff428c37836161a534d1d697fba43e86b0096c49b63d50afaf06ec772bda86eba7222796f087c5367d1547642b974d041cb496c5cf7984e8e126c9f741e\r\nMac = b5d40f8633965c33\r\nResult = F (3 - MAC changed)\r\n\r\nCount = 238\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = ce9ea80e7fb235486b5f1d0321c68a0e44cd5f15e21f27c402754a2f7c138772\r\nMsg = c246453f5d0f4957e6418b4d17b748f5c30e7ee672b4af2e4e41e145400be94056f4e94768871849fb44c1ee65378fce32d007e0c7ee5635453d4de6b0c2aa4b\r\nMac = 33ae4c66895989ee\r\nResult = F (1 - Message changed)\r\n\r\nCount = 239\r\nKlen = 32 \r\nMlen = 64\r\nTlen = 8\r\nKey = f26fad377bf7d6b35d8ea2e0621b678dad85826fadd3ee684d9215086b77e555\r\nMsg = 63539f949990883ac4f3ef9158b382a30254023c301de9fcd3cd4faa638a0ecb241a2573a9555a5c96da2435aa02c73cfc12c10f84b565bfdea9c6274bb8d67c\r\nMac = 8cda222f03f92913\r\nResult = F (2 - Key or Key2 changed)\r\n", +}; +static const size_t kLen52 = 155170; + +static const char *kData52[] = { "# This file contains multiples of the base point for various curves. The point\n# at infinity is represented as X = 0, Y = 0.\n#\n# This file is generated by make_ec_scalar_base_mult_tests.go\n\nCurve = P-224\n# N = -64\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29fd\nX = d9174b3ca6b093dee706b10e1d90309aa58aebf6c9006a37f3716fde\nY = 5091be99fda790ff9e6ecd2ac66b734f157f46402bf194d3bd8c194d\n\nCurve = P-224\n# N = -63\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29fe\nX = 2e74dd665404a8900c8e3d4f822b7a9b6dcb64940ef5f5671caba7ef\nY = f58bc45165c62d4c2c2ad7a8fb7e8f03322ce8ea5dc9c29f77625b14\n\nCurve = P-224\n# N = -62\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29ff\nX = c671c49a40fdb37ee1afb59c55915461d0c4b2a67cbe4f1f0c747c97\nY = 467fdfe495f8d2f97b00b4f8b83abdf40dc6c1b666fc5edc29225ed6\n\nCurve = P-224\n# N = -61\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a00\nX = 2396b9ee84e06252585475f54b390553185c05702db27913a80911b8\nY = 5bb2feab11a9448a5a11ae2b51e4132f0da82d7866b1b971dd85edd2\n\nCurve = P-224\n# N = -60\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a01\nX = 8c64ebb538c109bbd60fd54cf7ff47216d30ecefbac0824c6e50b291\nY = bfd6736f43c5ebb33959c9ec4444f5ea6c86e645b03dbed955ae402b\n\nCurve = P-224\n# N = -59\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a02\nX = 79fb86be63eed9cf12d44df82123ac91042f888b91b1b916bd3c107e\nY = 4bac5537dc8a32199840b52e4c4002733b7941c69c711c8248e8e33e\n\nCurve = P-224\n# N = -58\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a03\nX = eb81ac109e13fe579100edba2dd5389945b3fdf247b4036b018acf60\nY = 778b905f5bd3254728b9105ad7e4c53794201298b40d5fd166a75467\n\nCurve = P-224\n# N = -57\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a04\nX = 868ef00d187fef3010c81e77e214a828b4f9227cf5761d7eed89d916\nY = dae0eef456786c9592faebd46cf44d711fe16fa66b63bf7e8f70d911\n\nCurve = P-224\n# N = -56\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a05\nX = 7cdfaa27e1972788b9891be32d4491c5a9f7187a05c7d40107b7f0fc\nY = 46bb23e1eed098c6ac43e6c7e6a48c9e1e9c8169ef82488581f3782a\n\nCurve = P-224\n# N = -55\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a06\nX = a3168f507cc5ca03ec9507ff1fbe5ca00f3a1410948250749639b32a\nY = 7d83b007949ca192bbd2a691c208fe5e0adacbee0d5bc807cfc44a9e\n\nCurve = P-224\n# N = -54\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a07\nX = e095d7363877c57e22ad1a708b7775ae804cceacecf2e2df16618035\nY = b58fa951b3d1ce053b38a7cb072e69f64d281efc8cc9f1f42bbfde5e\n\nCurve = P-224\n# N = -53\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a08\nX = df5d3ed85b75fb433d057198debdd036cd9f11f339a4d607eb424932\nY = a61a1c0ab289b7658439375678b7a2e99b0c292297dbedf22eb912e9\n\nCurve = P-224\n# N = -52\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a09\nX = 6e53e26a8b7b28a7c7a61dd4d53d509514edad71188245929589c788\nY = f85f23a7c85fd7efc006d3eb13480eb0f6f647fdea5b59d06366d558\n\nCurve = P-224\n# N = -51\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0a\nX = 5b4ce687825f6a00f83cd3bbc77c67dc14d91bd78d4e47f7e2ce7b0f\nY = 6a86b2451d4be8409dec03799f680c806bc355e798591857fb8eddd6\n\nCurve = P-224\n# N = -50\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0b\nX = bce605150a1d4d750c5a043fb4136726f99b4a41f35d3b3832ea583f\nY = 768e2427050ad575667f8784b7fe8c6b2ae7873a7ff11ded64a13b0c\n\nCurve = P-224\n# N = -49\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0c\nX = f18721e462d2340c4a88e00130d86691386ba2a83d1fb1dc8b927cca\nY = b31f4d99a118d1c2c19f0815a89a921305d8d52005b64dd249b6a8e9\n\nCurve = P-224\n# N = -48\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0d\nX = f087c8764bb082e669a8afbc5db571971898ccc2c5d4baf73cd35e9d\nY = 72edb9b8154237917e7a05581d1cb2048d4d31c4ab90d005c9b67e4a\n\nCurve = P-224\n# N = -47\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0e\nX = eca965fd046c7fd242e29ba1a178b71b1ec6e7af6a5b88232a285c92\nY = 3e526a6b5ecbd24f9308de03fdb757a51a564ebc5872dbef7886cc7c\n\nCurve = P-224\n# N = -46\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0f\nX = 71f8a2cdf405c7ee499dbd7216a07e5aa61b8faa4fd20b516d2761d4\nY = 7a3008d5e50050b0ab427b36d15de75c0c190f7eb0b6a130106354f7\n\nCurve = P-224\n# N = -45\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a10\nX = cc96733b052b2f04f1cebb4cb8afb448a21c09821d6288b86cb8a17a\nY = 159e86c0c38e8f7fc210036054941444c90054fd2047a4eb0dbdbc6e\n\nCurve = P-224\n# N = -44\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a11\nX = d20981b43d053ca0ca30994a5586e7f2342c479b07c6c367d0025900\nY = 572b87044e041001d988793e9ae35378f7b9121a0d7abc1941b7cf8d\n\nCurve = P-224\n# N = -43\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a12\nX = 2f9a6dce655ee5d9f00b398e756defe1499b98df1e2edac8a784ad75\nY = bd851fc17271dca923b803a4a4554a949bfc20f14f26feacc2649762\n\nCurve = P-224\n# N = -42\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a13\nX = 0a8b3acff07b4e49ed1d6cd0e8cebbb0ac9f5bc5ec7d65e0adf7b21c\nY = 6aea047a1d6c9ea9df67e58538a8c88be591728e6c0d1443063199a4\n\nCurve = P-224\n# N = -41\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a14\nX = c772baaa90a968d497e0adbf116453e4f8c21c0acbea0ee34502317c\nY = de20e75207355906ed957ac40260148fda74b9acf699fa06caf08a62\n\nCurve = P-224\n# N = -40\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a15\nX = 5e4cdfc6fc36ea0cd69a38a7485a317a0aeded6b5f6cd80072826385\nY = 14afef7672ca22afe13292524ab55dfeef828e7e1e6abd8aadb9f27f\n\nCurve = P-224\n# N = -39\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a16\nX = 9a89bcce6f9b400618997c1184c5099a154a07954cb15d5c9f4492ca\nY = f48eba6a110031e81a8e50a0c3e5c141e3a66d12ef040e2cd36c4fcd\n\nCurve = P-224\n# N = -38\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a17\nX = 68eee585a12332d41aef6f91a587bc3ca57329508fcc9f5bb3907516\nY = df09fa68ba98511870b892e5f59c02792aed884376ecc9b081641901\n\nCurve = P-224\n# N = -37\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a18\nX = 9810b8218ec461154d317a954df66f5f81e51dc07ed7421b17d0b8aa\nY = e166fda56ccb98bbfa8423bcacbcacc05ddac7e88ff0ce13c805a10a\n\nCurve = P-224\n# N = -36\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a19\nX = 6116976ec4511b1b9ee2b839378ff122c2bdb3f58823a82a68aef8e1\nY = 99b4990881ca11762f616528685fbf94eb1708fa1ae25f010d070beb\n\nCurve = P-224\n# N = -35\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1a\nX = da200dcda742573ca097e34bb87b356b84541f765cf38d2bf07471b0\nY = ef05917f8f13fc686a8a0b6b544b0a1ed3488f1dff476a9a9c7cc19e\n\nCurve = P-224\n# N = -34\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1b\nX = f8188c7623f76642286b8e9e4d4c5d58b8eaf7265b3b0e816076e7e4\nY = bc6fc80b788a058da4873e54acc733db09105a6775bfb3faa6c549af\n\nCurve = P-224\n# N = -33\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1c\nX = 224c4a62c8b1028606603cce1d451409b23d680bb063a8e6875d3b5c\nY = ca97069c235efeb00a05729df91171d17605320950a1cea2e49fd119\n\nCurve = P-224\n# N = -32\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1d\nX = b700a5c3bb6379de6caea37ff7a47ca909bec01a603c5ec5e1d1e794\nY = 39e4c2c2e0968ef8a7cd7cabbfd37d0d2335579e72145109b23ce46a\n\nCurve = P-224\n# N = -31\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1e\nX = 0ecf1b60836e92b7af968bccd69ff8300d55a42b0e855a4ff3546eab\nY = 4bd76a3b0d1e95b063d22f890c68ebfd2327e3af12611c8f66bc1d21\n\nCurve = P-224\n# N = -30\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1f\nX = 599b7e7e639bc335eb891295f0d8f4d8d8c76e588f0767741ab07558\nY = a5aa7d10418290c0f35d3e4fccd02e4b3bc48ac8a87ad052e4cdcc14\n\nCurve = P-224\n# N = -29\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a20\nX = f63f9d855262e9b691f9bb848c78859508a8c1e6fb3246212e146e5c\nY = f75d5db787bfb5cb199828b1040e7ccd9a20d198d9f82a81001cf9e4\n\nCurve = P-224\n# N = -28\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a21\nX = 1243a602d84f3ea7cf4a56f86ccb93395c1d609af98d6474d8e7afb1\nY = 42c598ef4d24cb1f640cafc463a244dc4a26c694bf7b4737c8c6ec7c\n\nCurve = P-224\n# N = -27\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a22\nX = 1989153b5f6636b610854bcc50afc929e914c03da51a4a8239f4865b\nY = 46c7e1923864a71fbbc324ff6e9b7c842baf5973e6e6d0ed9abd8695\n\nCurve = P-224\n# N = -26\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a23\nX = 263ed2217", "b1f0a813156e647e87e6cf618b9635c3f910f9d92153b04\nY = ba1722401bfc9e41088cac3974d5ec7ad91fa0cd95b0a3555a23194a\n\nCurve = P-224\n# N = -25\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a24\nX = f1a7ae364dba054b51dff5d5ce16fb28965fb3777dca1ce3c1ad6ad0\nY = b15ffa68153924545b397331387cee02f86c97f51fb4d28a172db95d\n\nCurve = P-224\n# N = -24\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a25\nX = affdfabc0525468041b2baf73874ec60762a670562c0248e474456a1\nY = 00828bfdac88b772536123340be2bf21ccec9cda4e9ba00d50db9e30\n\nCurve = P-224\n# N = -23\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a26\nX = 2da9b6b6ec26e646ceef802c560782026da04bf2f2d196f4bca2d074\nY = 58d6f33f99ff23e92c8a043b47b66ae89f7d30289b35b16aea963966\n\nCurve = P-224\n# N = -22\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a27\nX = c9bdd86f5fb7fe1e54c6ff9026f20add6c1984f1ef22b80a887af62c\nY = eec590de16f168bde8d375e5dcc22402db091965c0a5bf7f95cf88f5\n\nCurve = P-224\n# N = -21\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a28\nX = a3d482c3e7eec18c534d4ceb1c9b8cefecb369a68a85a4e826165174\nY = 9b11ffa67c105561b349cb872408dfdc8daf9071a39d9c38fee98408\n\nCurve = P-224\n# N = -20\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a29\nX = fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455\nY = f2a28eefd8b345832116f1e574f2c6b2c895aa8c24941f40d8b80ad1\n\nCurve = P-224\n# N = -19\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2a\nX = a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c\nY = 230e093c24f638f533dac6e2b6d01da3b5e7f45429315ca93fb8e634\n\nCurve = P-224\n# N = -18\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2b\nX = c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc\nY = 156729f1a003647030666054e208180f8f7b0df2249e44fba5931fff\n\nCurve = P-224\n# N = -17\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2c\nX = b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc\nY = 00eb610599f95942df1082e4f9426d086fb9c6231ae8b24933aab5db\n\nCurve = P-224\n# N = -16\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2d\nX = 0b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d\nY = cc662b9bcba6f94ee4ff1c9c10bd6ddd0d138df2d099a282152a4b7f\n\nCurve = P-224\n# N = -15\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2e\nX = baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9\nY = 6865a0b8a607f0b04b13d1cb0aa992a5a97f5ee8ca1849efb9ed8678\n\nCurve = P-224\n# N = -14\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2f\nX = a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa\nY = 2a7eb328dbe663b5a468b5bc97a040a3745396ba636b964370dc3352\n\nCurve = P-224\n# N = -13\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a30\nX = 34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca\nY = dad7e608e380480434ea641cc82c82cbc92801469c8db0204f13489a\n\nCurve = P-224\n# N = -12\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a31\nX = 6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a\nY = df82220fc7a4021549165325725f94c3410ddb56c54e161fc9ef62ee\n\nCurve = P-224\n# N = -11\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a32\nX = ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c\nY = df4aefffbf6d1699c930481cd102127c9a3d992048ab05929b6e5927\n\nCurve = P-224\n# N = -10\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a33\nX = aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd\nY = c644cf154cc81f5ade49345e541b4d4b5c1adb3eb5c01c14ee949aa2\n\nCurve = P-224\n# N = -9\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a34\nX = 2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d\nY = c8e8cd1b0be40b0877cfca1958603122f1e6914f84b7e8e968ae8b9e\n\nCurve = P-224\n# N = -8\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a35\nX = 858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550\nY = fb9232c15a3bc7673a3a03b0253824c53d0fd1411b1cabe2e187fb87\n\nCurve = P-224\n# N = -7\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a36\nX = db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28\nY = f0c5cff7ab680d09ee11dae84e9c1072ac48ea2e744b1b7f72fd469e\n\nCurve = P-224\n# N = -6\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a37\nX = 1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408\nY = 76050f3348af2664aac3a8b05281304ebc7a7914c6ad50a4b4eac383\n\nCurve = P-224\n# N = -5\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a38\nX = 31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa\nY = d817400e8ba9ca13a45f360e3d121eaaeb39af82d6001c8186f5f866\n\nCurve = P-224\n# N = -4\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a39\nX = ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301\nY = fb7da7f5f13a43b81774373c879cd32d6934c05fa758eeb14fcfab38\n\nCurve = P-224\n# N = -3\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a\nX = df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04\nY = 5c080fc3522f41bbb3f55a97cfecf21f882ce8cbb1e50ca6e67e56dc\n\nCurve = P-224\n# N = -2\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3b\nX = 706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6\nY = e3d4895843da188fd58fb0567976d7b50359d6b78530c8f62d1b1746\n\nCurve = P-224\n# N = -1\nN = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3c\nX = b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21\nY = 42c89c774a08dc04b3dd201932bc8a5ea5f8b89bbb2a7e667aff81cd\n\nCurve = P-224\n# N = 0\nN = 00000000000000000000000000000000000000000000000000000000\nX = 00000000000000000000000000000000000000000000000000000000\nY = 00000000000000000000000000000000000000000000000000000000\n\nCurve = P-224\n# N = 1\nN = 00000000000000000000000000000000000000000000000000000001\nX = b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21\nY = bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34\n\nCurve = P-224\n# N = 2\nN = 00000000000000000000000000000000000000000000000000000002\nX = 706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6\nY = 1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb\n\nCurve = P-224\n# N = 3\nN = 00000000000000000000000000000000000000000000000000000003\nX = df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04\nY = a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925\n\nCurve = P-224\n# N = 4\nN = 00000000000000000000000000000000000000000000000000000004\nX = ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301\nY = 0482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9\n\nCurve = P-224\n# N = 5\nN = 00000000000000000000000000000000000000000000000000000005\nX = 31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa\nY = 27e8bff1745635ec5ba0c9f1c2ede15414c6507d29ffe37e790a079b\n\nCurve = P-224\n# N = 6\nN = 00000000000000000000000000000000000000000000000000000006\nX = 1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408\nY = 89faf0ccb750d99b553c574fad7ecfb0438586eb3952af5b4b153c7e\n\nCurve = P-224\n# N = 7\nN = 00000000000000000000000000000000000000000000000000000007\nX = db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28\nY = 0f3a30085497f2f611ee2517b163ef8c53b715d18bb4e4808d02b963\n\nCurve = P-224\n# N = 8\nN = 00000000000000000000000000000000000000000000000000000008\nX = 858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550\nY = 046dcd3ea5c43898c5c5fc4fdac7db39c2f02ebee4e3541d1e78047a\n\nCurve = P-224\n# N = 9\nN = 00000000000000000000000000000000000000000000000000000009\nX = 2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d\nY = 371732e4f41bf4f7883035e6a79fcedc0e196eb07b48171697517463\n\nCurve = P-224\n# N = 10\nN = 0000000000000000000000000000000000000000000000000000000a\nX = aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd\nY = 39bb30eab337e0a521b6cba1abe4b2b3a3e524c14a3fe3eb116b655f\n\nCurve = P-224\n# N = 11\nN = 0000000000000000000000000000000000000000000000000000000b\nX = ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c\nY = 20b510004092e96636cfb7e32efded8265c266dfb754fa6d6491a6da\n\nCurve = P-224\n# N = 12\nN = 0000000000000000000000000000000000000000000000000000000c\nX = 6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a\nY = 207dddf0385bfdeab6e9acda8da06b3bbef224a93ab1e9e036109d13\n\nCurve = P-224\n# N = 13\nN = 0000000000000000000000000000000000000000000000000000000d\nX = 34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca\nY = 252819f71c7fb7fbcb159be337d37d3336d7feb963724fdfb0ecb767\n\nCur", "ve = P-224\n# N = 14\nN = 0000000000000000000000000000000000000000000000000000000e\nX = a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa\nY = d5814cd724199c4a5b974a43685fbf5b8bac69459c9469bc8f23ccaf\n\nCurve = P-224\n# N = 15\nN = 0000000000000000000000000000000000000000000000000000000f\nX = baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9\nY = 979a5f4759f80f4fb4ec2e34f5566d595680a11735e7b61046127989\n\nCurve = P-224\n# N = 16\nN = 00000000000000000000000000000000000000000000000000000010\nX = 0b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d\nY = 3399d464345906b11b00e363ef429221f2ec720d2f665d7dead5b482\n\nCurve = P-224\n# N = 17\nN = 00000000000000000000000000000000000000000000000000000011\nX = b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc\nY = ff149efa6606a6bd20ef7d1b06bd92f6904639dce5174db6cc554a26\n\nCurve = P-224\n# N = 18\nN = 00000000000000000000000000000000000000000000000000000012\nX = c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc\nY = ea98d60e5ffc9b8fcf999fab1df7e7ef7084f20ddb61bb045a6ce002\n\nCurve = P-224\n# N = 19\nN = 00000000000000000000000000000000000000000000000000000013\nX = a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c\nY = dcf1f6c3db09c70acc25391d492fe25b4a180babd6cea356c04719cd\n\nCurve = P-224\n# N = 20\nN = 00000000000000000000000000000000000000000000000000000014\nX = fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455\nY = 0d5d7110274cba7cdee90e1a8b0d394c376a5573db6be0bf2747f530\n\nCurve = P-224\n# N = 21\nN = 00000000000000000000000000000000000000000000000000000015\nX = a3d482c3e7eec18c534d4ceb1c9b8cefecb369a68a85a4e826165174\nY = 64ee005983efaa9e4cb63478dbf7202272506f8e5c6263c701167bf9\n\nCurve = P-224\n# N = 22\nN = 00000000000000000000000000000000000000000000000000000016\nX = c9bdd86f5fb7fe1e54c6ff9026f20add6c1984f1ef22b80a887af62c\nY = 113a6f21e90e9742172c8a1a233ddbfc24f6e69a3f5a40806a30770c\n\nCurve = P-224\n# N = 23\nN = 00000000000000000000000000000000000000000000000000000017\nX = 2da9b6b6ec26e646ceef802c560782026da04bf2f2d196f4bca2d074\nY = a7290cc06600dc16d375fbc4b84995166082cfd764ca4e951569c69b\n\nCurve = P-224\n# N = 24\nN = 00000000000000000000000000000000000000000000000000000018\nX = affdfabc0525468041b2baf73874ec60762a670562c0248e474456a1\nY = ff7d74025377488dac9edccbf41d40dd33136325b1645ff2af2461d1\n\nCurve = P-224\n# N = 25\nN = 00000000000000000000000000000000000000000000000000000019\nX = f1a7ae364dba054b51dff5d5ce16fb28965fb3777dca1ce3c1ad6ad0\nY = 4ea00597eac6dbaba4c68ccec78311fc0793680ae04b2d75e8d246a4\n\nCurve = P-224\n# N = 26\nN = 0000000000000000000000000000000000000000000000000000001a\nX = 263ed2217b1f0a813156e647e87e6cf618b9635c3f910f9d92153b04\nY = 45e8ddbfe40361bef77353c68b2a138426e05f326a4f5caaa5dce6b7\n\nCurve = P-224\n# N = 27\nN = 0000000000000000000000000000000000000000000000000000001b\nX = 1989153b5f6636b610854bcc50afc929e914c03da51a4a8239f4865b\nY = b9381e6dc79b58e0443cdb009164837ad450a68c19192f126542796c\n\nCurve = P-224\n# N = 28\nN = 0000000000000000000000000000000000000000000000000000001c\nX = 1243a602d84f3ea7cf4a56f86ccb93395c1d609af98d6474d8e7afb1\nY = bd3a6710b2db34e09bf3503b9c5dbb22b5d9396b4084b8c837391385\n\nCurve = P-224\n# N = 29\nN = 0000000000000000000000000000000000000000000000000000001d\nX = f63f9d855262e9b691f9bb848c78859508a8c1e6fb3246212e146e5c\nY = 08a2a24878404a34e667d74efbf1833165df2e672607d57effe3061d\n\nCurve = P-224\n# N = 30\nN = 0000000000000000000000000000000000000000000000000000001e\nX = 599b7e7e639bc335eb891295f0d8f4d8d8c76e588f0767741ab07558\nY = 5a5582efbe7d6f3f0ca2c1b0332fd1b3c43b753757852fad1b3233ed\n\nCurve = P-224\n# N = 31\nN = 0000000000000000000000000000000000000000000000000000001f\nX = 0ecf1b60836e92b7af968bccd69ff8300d55a42b0e855a4ff3546eab\nY = b42895c4f2e16a4f9c2dd076f3971401dcd81c50ed9ee3709943e2e0\n\nCurve = P-224\n# N = 32\nN = 00000000000000000000000000000000000000000000000000000020\nX = b700a5c3bb6379de6caea37ff7a47ca909bec01a603c5ec5e1d1e794\nY = c61b3d3d1f69710758328354402c82f1dccaa8618debaef64dc31b97\n\nCurve = P-224\n# N = 33\nN = 00000000000000000000000000000000000000000000000000000021\nX = 224c4a62c8b1028606603cce1d451409b23d680bb063a8e6875d3b5c\nY = 3568f963dca1014ff5fa8d6206ee8e2d89facdf6af5e315d1b602ee8\n\nCurve = P-224\n# N = 34\nN = 00000000000000000000000000000000000000000000000000000022\nX = f8188c7623f76642286b8e9e4d4c5d58b8eaf7265b3b0e816076e7e4\nY = 439037f48775fa725b78c1ab5338cc23f6efa5988a404c05593ab652\n\nCurve = P-224\n# N = 35\nN = 00000000000000000000000000000000000000000000000000000023\nX = da200dcda742573ca097e34bb87b356b84541f765cf38d2bf07471b0\nY = 10fa6e8070ec03979575f494abb4f5e02cb770e200b8956563833e63\n\nCurve = P-224\n# N = 36\nN = 00000000000000000000000000000000000000000000000000000024\nX = 6116976ec4511b1b9ee2b839378ff122c2bdb3f58823a82a68aef8e1\nY = 664b66f77e35ee89d09e9ad797a0406a14e8f705e51da0fef2f8f416\n\nCurve = P-224\n# N = 37\nN = 00000000000000000000000000000000000000000000000000000025\nX = 9810b8218ec461154d317a954df66f5f81e51dc07ed7421b17d0b8aa\nY = 1e99025a93346744057bdc435343533ea2253817700f31ec37fa5ef7\n\nCurve = P-224\n# N = 38\nN = 00000000000000000000000000000000000000000000000000000026\nX = 68eee585a12332d41aef6f91a587bc3ca57329508fcc9f5bb3907516\nY = 20f605974567aee78f476d1a0a63fd85d51277bc8913364f7e9be700\n\nCurve = P-224\n# N = 39\nN = 00000000000000000000000000000000000000000000000000000027\nX = 9a89bcce6f9b400618997c1184c5099a154a07954cb15d5c9f4492ca\nY = 0b714595eeffce17e571af5f3c1a3ebd1c5992ed10fbf1d32c93b034\n\nCurve = P-224\n# N = 40\nN = 00000000000000000000000000000000000000000000000000000028\nX = 5e4cdfc6fc36ea0cd69a38a7485a317a0aeded6b5f6cd80072826385\nY = eb5010898d35dd501ecd6dadb54aa200107d7181e195427552460d82\n\nCurve = P-224\n# N = 41\nN = 00000000000000000000000000000000000000000000000000000029\nX = c772baaa90a968d497e0adbf116453e4f8c21c0acbea0ee34502317c\nY = 21df18adf8caa6f9126a853bfd9feb6f258b4653096605f9350f759f\n\nCurve = P-224\n# N = 42\nN = 0000000000000000000000000000000000000000000000000000002a\nX = 0a8b3acff07b4e49ed1d6cd0e8cebbb0ac9f5bc5ec7d65e0adf7b21c\nY = 9515fb85e293615620981a7ac75737731a6e8d7193f2ebbcf9ce665d\n\nCurve = P-224\n# N = 43\nN = 0000000000000000000000000000000000000000000000000000002b\nX = 2f9a6dce655ee5d9f00b398e756defe1499b98df1e2edac8a784ad75\nY = 427ae03e8d8e2356dc47fc5b5baab56a6403df0eb0d901533d9b689f\n\nCurve = P-224\n# N = 44\nN = 0000000000000000000000000000000000000000000000000000002c\nX = d20981b43d053ca0ca30994a5586e7f2342c479b07c6c367d0025900\nY = a8d478fbb1fbeffe267786c1651cac860846ede5f28543e6be483074\n\nCurve = P-224\n# N = 45\nN = 0000000000000000000000000000000000000000000000000000002d\nX = cc96733b052b2f04f1cebb4cb8afb448a21c09821d6288b86cb8a17a\nY = ea61793f3c7170803deffc9fab6bebba36ffab02dfb85b14f2424393\n\nCurve = P-224\n# N = 46\nN = 0000000000000000000000000000000000000000000000000000002e\nX = 71f8a2cdf405c7ee499dbd7216a07e5aa61b8faa4fd20b516d2761d4\nY = 85cff72a1affaf4f54bd84c92ea218a2f3e6f0814f495ecfef9cab0a\n\nCurve = P-224\n# N = 47\nN = 0000000000000000000000000000000000000000000000000000002f\nX = eca965fd046c7fd242e29ba1a178b71b1ec6e7af6a5b88232a285c92\nY = c1ad9594a1342db06cf721fc0248a859e5a9b143a78d241087793385\n\nCurve = P-224\n# N = 48\nN = 00000000000000000000000000000000000000000000000000000030\nX = f087c8764bb082e669a8afbc5db571971898ccc2c5d4baf73cd35e9d\nY = 8d124647eabdc86e8185faa7e2e34dfa72b2ce3b546f2ffa364981b7\n\nCurve = P-224\n# N = 49\nN = 00000000000000000000000000000000000000000000000000000031\nX = f18721e462d2340c4a88e00130d86691386ba2a83d1fb1dc8b927cca\nY = 4ce0b2665ee72e3d3e60f7ea57656debfa272adffa49b22db6495718\n\nCurve = P-224\n# N = 50\nN = 00000000000000000000000000000000000000000000000000000032\nX = bce605150a1d4d750c5a043fb4136726f99b4a41f35d3b3832ea583f\nY = 8971dbd8faf52a8a9980787b48017393d51878c5800ee2129b5ec4f5\n\nCurve = P-224\n# N = 51\nN = 00000000000000000000000000000000000000000000000000000033\nX = 5b4ce687825f6a00f83cd3bbc77c67dc14d91bd78d4e47f7e2ce7b0f\nY = 95794dbae2b417bf6213fc866097f37e943caa1867a6e7a80471222b\n\nCurve = P-224\n# N = 52\nN = 00000000000000000000000000000000000000000000000000000034\nX = 6e53e26a8b7b28a7c7a61dd4d53d509514edad71188245929589c788\nY = 07a0dc5837a028103ff92c14ecb7f14e0909b80215a4a62f9c992aa9\n\nCurve = P-224\n# N = 53\nN = 00000000000000000000000000000000000000000000000000000035\nX = df5d3ed85b75fb433d057198debdd036cd", @@ -2565,9 +2670,9 @@ static const char *kData42[] = { "9642dd68d1a988bb828d895ed5d116d7f87032133e2949da6c395738534b93220fe2ad07f0b291adc92433ee2dee160709ed9985b0c\nY = 0177acd53b00c9f29f3ece28b4724f834f49606d3f34656a52ef5443c5d9216ae388b345b828c8b09a2b2e495cf2adcdd6b5886f4ded1741425ac31c832ba74eed38\n\nCurve = P-521\n# N = 29\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d\nX = 0174c644d6c94b68287db3c1fbfcb65a085ff9f45131e86265ec28bef38f7664a1305ca9bc06876d72914003ab8e847ffb9ef33d8595d51f6d962c3927618eda25dc\nY = 011af3a7c2f87f419e6805acc95b41b7b7820233ef8fcb6441fcb5cf5eb795ad34b7be0e21952ce0d90b50c2732d706d303f0679927c26ebbfbd187bbbc4821a0c30\n\nCurve = P-521\n# N = 30\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e\nX = 00d087d70d11074b36bb0b6913261570a6b33cf015e1f913a610ea52dbcbae2a3e4435573f35d14754c6352756cc169eac6bf7d9b10f1b0af5956117fab72ec4b081\nY = 00c4d07f8c3cafdc1636811d7b95a6ac2dcebcde1cd94afbdbd3e47015660d29f15354d5b99d1d7d4adaf279efee5d860be9069edd46ff01cfc7b64d6af6579dbed3\n\nCurve = P-521\n# N = 31\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f\nX = 00d8e9920cf30f0c6615006a58cdb7307b7db574589657c2a6617260a83ca5e7726cd65543a904c9d429fc14c1ac09cd6b220dcfb5e488e248122257d0e0c16a8803\nY = 0127b023b5454a663987df09c13a214a30ec8b5406328f10c8060aefb72cbed1aa30f76b8c3244d14790139a868cae4cc263aa1bd97c7b54318aca4677c739792d19\n\nCurve = P-521\n# N = 32\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\nX = 0166ba3596d20a3a469443707af94ba15b343e3e16654e068038dba7ecefb9e5ebd6ea04a35dc73596ec67d69bd6ba5d1f949cf7475cd6c5c78247915ab876e56a9e\nY = 00477b0ff4d1940ab8111635e75ff3e08268ff7bd8bf5ff01967c1df01c65c2dd77de204cdb818cdd6b9b74de1c7ea0f36dfcd98c965ab96163695ca9a9914a156aa\n\nCurve = P-521\n# N = 33\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021\nX = 00284195f0978fb969e68c76eb4e3c76f58e52086d482be92613f381421a74236df0abdbea7e2b77ef1ae9a519a57aa53ac2a5ec59186b2ed12d5ea2e1fc649f308d\nY = 007e43eb08c656dc636b7b7a3bc869056d3a24d513abe063c6639e016769614ac5f2e7656ecbf3d138bf00bd7216c16deb3a88effd5c228b58f36be95a3dd3e11c4d\n\nCurve = P-521\n# N = 34\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022\nX = 0122f66451d0843fb59448c58962f5b7c130eb8db26b14dbf8bf0e7d84e588581cdea866a98b697d432cc1f1f8993db2173b55ac0435b8317a8ddfeab253d54e4d87\nY = 01bed137b942249932f3c1f12141aee1538aa373f5aee0a89a48d357d7c04965b0515097293e4f87a6a413184d9be8ea91406baa5223db7571bcda9dba82fd9a06dc\n\nCurve = P-521\n# N = 35\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023\nX = 00ddc300757549630a78398b62069e0ba392a267a642b593e0bfc4a780b56f97392bb4806c84fda74023ee4a618608f6b2cea92ff614b5dcc8d8dc1039c9ccd7d718\nY = 00c1bd2d07f6ac7fc5cc1b83431f0c30dbbfa510936cb5d85bcf462796591a31db509ab1178bd2c701425c212522ee69e797deba4db422640a4d3eb1d3ef241e07f4\n\nCurve = P-521\n# N = 36\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024\nX = 01ad81c98659bd21e082514d5e71894c417b2a25afe471eb8ad9e81a91dac8198aa9f385da9cc679bb96e724672821b585e05323bdc821e585edae56cbf798bd6ef0\nY = 01217026e6cf8e6fc4e761aeda5705b3c0f8ca7f475441227b9761285bc6dc8f01af1af50b0bb140013a75db963d8698121dd2c4ba1759a98b43ac7712f8455c99ef\n\nCurve = P-521\n# N = 37\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025\nX = 00944f64a6c21832b67139e798352ded5867c35c5d56c1d59e4229ed0ae6af9d5749bd445763a28856040e58e26ee0980df28c64e76ae4780273f1ac4d59b557a36f\nY = 0150b7ee1b02028ab7410c4b9624f26cb192fe4e6ff21865f85926317da6b7991305dcbdbc2471c83f81b85c564995a057c331a4be4056988296312bf98394fb2a03\n\nCurve = P-521\n# N = 38\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026\nX = 0195aeb1530c7d932a18922563d71ef6e7449078207b610c2c77690815bcef8f312718413823ed8d4ba112ac2ecc9d4e688346f120cb19ae965d853028d72a5f4a8b\nY = 00e0c42d3cc093242000c0ec0975884bb0308611d8bd49b6090a06c5bdf7d0e1544851f9ba596291ef1ee3e3c9a002b7985ba29e51d193b701e0c87e1acd797bd130\n\nCurve = P-521\n# N = 39\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027\nX = 0124a0b8f411fbad60755264126356a499029e9661a49b5b907238d9fd62359c6ea7256b0cc58626a1e2ac0bf434e5fa31795b4fa1d48083af670b704119ee33b77c\nY = 001029616edc7335dce3602a9a406bbd399c68937baa8796154cdc0b1240c690db4818dc59feb96825aaa3caf2415944e762f212e74b698e40abd8dcdc61228b61a6\n\nCurve = P-521\n# N = 40\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028\nX = 002efdef97e46cd544553a0c67f41886ad969f67883679409022c4ad6090a169b596f85d832dc9767b2bb513eb4d0d01e18f067fffb5ac53dbcfaf456a57824c9d93\nY = 00d88e2e3fdd283592d6c4c2a4687e65a6a823ffc6106dff96f75bb3141d0df516fe46a5357b21dc22404f4ef79e44aa97b22c101fec75d81e09b591f36738ae8e5c\n\nCurve = P-521\n# N = 41\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029\nX = 0175a140ed79e85e24a763ebfd9d2883082552a523e4b28998a685b85f23864a60c816b931eaf495ccce4c08c3ddc8297bfaddfda1a522cc2af68e00ce952624381e\nY = 01b09696d71855e2d4ed36f21343ca399be7ab59e580e9ee563223de821b22c82111b39e0e11ecf327da052a6e551fa28ebdf75dd758e7f3a3ecebeb760ec1028ecf\n\nCurve = P-521\n# N = 42\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a\nX = 0161960dcd7bd7263ed37a0a1c0aa146f918874f472a2a5de6f2f5633364979e0bda2868fa8595d78243ea20d4e83c72305e420bebfa3767dcd4b7902612a9491855\nY = 016ac1cfdd433815668a5c6ae0d1031bc121a00e6a6b58d1eec42da602f01cc43b7ef728d67c4e39de86324cba6a2c4cce08414fdd6ad7d0722338a50e352ad521ef\n\nCurve = P-521\n# N = 43\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b\nX = 018c0148a165ec58e4fed55022d90544d8a070678aa2ec1419af8ef0f94438fea396fc66ad7aed7d37dda3a74e7a9b3d85ca51f0b62fdee07d20713e3083224f497e\nY = 010abbaa1f099e78869aebf7a83c7aa3bf242677e91db1d144cd7a3037819f1a0bec67fd6098879b1cf1932d602b547ce17a94edb92f76b688d2895829067683adbf\n\nCurve = P-521\n# N = 44\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c\nX = 013fdb51df11f0b29b485f0c48a04cca16cfe1cecbe9fd57f6507c3cfcbef88c88cf761e3e73e6509ec7e77fffe912d2b367b25aa02cb1d33a5378f253cdcde738d2\nY = 01d14c8c184a7228a7034e4f65b3d0338f667aac908b39acf39c9ebedc0452b7c2f2a4460186aa2271d357733ea23d7284a8a123424f99a20b5242343b5cbafa661a\n\nCurve = P-521\n# N = 45\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d\nX = 004969d186aca09e53b879596b8fff2bc0207a58f7f28c147cc07b2df5e3f197286779189b7df8a1f2d9dc8ea1ace5703f0fc2954607b66b70c4a32dec600fc95c1a\nY = 01e81ec9b50cd8d3847d4d6ac21f3149fc7b15862a423270884135584a1bbcdb40a9b8d5b2802eadae85e6ed9e879be328e13463f5d90b37564f9498a7cd000903a9\n\nCurve = P-521\n# N = 46\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e\nX = 00bbdb162d8284a910021998e2d14f33a8c51a9cfb9a69a8fc5709f753aaf1c4d248a6ddb5626540f81d07c09231d2ec1549f672b6d2bd57d22f64f2ae8093e738a5\nY = 013b86f0d5921216efe01fe9c7cabc10b00ab81c9fbd9674149d2ece424b786f6c372a1831112f54132d7d3af42dc8cd7e17b7ec80b09fa59f0e42c142895961259a\n\nCurve = P-521\n# N = 47\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000002f\nX = 00afe31f8907048afd5f9cf5083ecc35882ce4e4fe2714033ff897233106c71dd0b2381864a0b9e922ac9cee75a3a9c4dd660a56a130d1ecbb672fda63c9abd59d11\nY = 0012f95dc8657275fe9db4290cbbb54ff69a605f079349209f88ecea7f3276f064979276080b904982a6ebb760f478d825e711ca41599f10673bd3065d2f1d90e1d6\n\nCurve = P-521\n# N = 48\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030\nX = 01fb35de3b21557462ac8158e5caec62c8ccae7d6d6672102c334b3cc8a5803e72f42da0980f3f6fbfacdedc21b10ff08ee6641752bd214aea2c87027d612ad879ad\nY = 018d34a5ac1587992deda855b9ec4bb3f5c176f27fc94d09e2cc871294f66cc2e1bae6214d64a1d97e37b7c142e0fb0e3c28596f24804841cae7b1958193d256d46b\n\nCurve = P-521\n# N = 49\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031\nX = 00a5cb98fa3c0b8c1d57cba40a63bbaba0d39d45c347ae499839f581b8b111dea9eb6bc2a2df52f6284291d8c84e2e345fa87258dab1ac4c04ca0c8cb45049efc0ad\nY = 0015dc95654090d77b971409b01bf72e151b749ee467877e5b7eb072c39d9da8bf835dd9775543d575c20c10f2ceebb72bb44b963fbfb0b88b1d0b9bf46a2c8884b4\n\nCurve = P-521\n# N = 50\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032\nX = 017176204957627b7a120baf0dbb1aa3f9ca5312b292e34a0cfbd8384cf1be365bc684804ab26d84fe02250a859beaced3f356b6ddab593aebf35386773de84d4766\nY = 01ac713d5c2ffb0e111983e07ea5f688b03dd3032d3a9450b50c5def1db4859b504caf8c1321bb6c8d5fad93d2e5b9d0e75336298e21939f704f3f16ac6addc84f8f\n\nCurve = P-521\n# N = 51\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033\nX = 0168395ba51e278415a2025d93b68145f3ccfdf9f5bde34fe9ba3ba316cbf9beea26c2edfe6af07390df1321ae1b1054cbc0fba689ef1d7be2dda8d916fffbcc9504\nY = 0071cc10f3ca041a245639d9531942d3f57952dd878f21c480ce24e5b174adeb9b3c97bc2b68badb600c849c36096e3aeba50600aabed3a89e188eb9c45edd5c087b\n\nCurve = P-521\n# N = 52\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034\nX = 001f32e875ce65d1e6d4c39a55b518749158a4dae03e0c1b4b4a58aef6be769f0693b9259354dcee33a4f00784311b6e5993955114f2afcab7a186177e368b29f6f3\nY = 005a3c8e76fb7849180b895ea8b22ee1a6fc2cbf93bbae0f4ad4a0c126d318c397911e73a061b8098a91112577769cd77ef2bd6b45f989f292da9301992d481b07f8\n\nCurve = P-521\n# N = 53\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035\nX = 0143f6e249195ee693f77b3d0ffd310306dff8688be916895fb727e82f6f948100c44e210e637209a78ed3af581fba4fe12b08153da9c98808166285684cccb69906\nY = 01053e8fcc9618eb2a74c5611a02575109877dc73fdde42c216935437e8053d10cb14fdf64f503cf3bb30f6a7a9de3b4cf8c040a3dfbc4abee6afd6ddaddd40c7861\n\nCurve = P-521\n# N = 54\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036\nX = 01938e65f2a40e6899c6414997e998e0e3e1cb09728861ea138fc6d866fdc6c98505393cf55982451c97dac4214e4dbf052bf707cab63228fdfcf5ae2048a0ce100c\nY = 0163d556dd0941ce794e9c2868a692e89dbf943485186e2074e8222e0ed99fea4bd0c6069fa8017db8bec972b99ee0d7fcbc0f607d677492659bfa47b98bb8d1b411\n\nCurve = P-521\n# N = 55\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037\nX = 004b52fc4b6d310ce7c4b551e4155c6daca97cb03e9fd9d0a79d6472d4028e8da1a18cca93917cad27e6be17486b1e0b549a7fe9ab4bda96ac4e84ad7ccebd470f5e\nY = 003585e54fe81461ae21385ea7907a1a7b2e619f44311a16a0b600fb114a7dbae15510aa85895c5a084cd69609e345b53586fa03a23006a096ea7a196cd230a36ef2\n\nCurve = P-521\n# N = 56\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038\nX = 003cd775038527f32baf7e9056e95b0cbef7638c12398e4b8b019cc29b3435be97f601378e253fef51d25730e56267acca241df04ea2e96c1840b3f739d5ae2df998\nY = 00789bf7cf42095c5b1770e1a3561fc3e1232b0430e114f67a397c1e5b54987f4a28b52a737cbaa0ffa2c431863c1a8cbf15eba60fb5d8b4723dc10d9706f4083cba\n\nCurve = P-521\n# N = 57\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039\nX = 00dc53c3e7fcf3c902e04463da75efb25ffa5a8defe72e6dbf85ef3c6d77a521b9f84af300bbde9118b2f66fd5bc64b8a5208372c8fff95c84503475330a4e9a13e2\nY = 0074e88fccd4fdbd992b68073ee6c4d4f8f7b13d0dd2caf9d989b62e7eb390dff3ea3482530d0d3bd86a4a3f82056a929f73a9493190c62a553233ad7f7fd9c4248f\n\nCurve = P-521\n# N = 58\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a\nX = 008bc46df1c09851ab92d53b6ad821b5026be61385c801f5277c9871b54c6764d3fdb96a728ad56c650d342a03e174a3106a5479d3ccb04647ad0f583210d81ab70d\nY = 01d948ff92784e9946a27a4c58d40bfb0e0b765073f1f9a731aa52b53e4fe686134fee784bec8fca81a73b8ac3a45ca1b766cdec69190bf94d71fa08b29292c1205f\n\nCurve = P-521\n# N = 59\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b\nX = 0035aeb454ad31876773063c60342df29eadc7223c5d98901999aae5c2934c222920055693c9b1344c691a90342d64373a8acba8524ec347208863be8a26eb16686b\nY = 00187ecbec147e7e43b4db0b0ca0aff1ba7f15a48db3660903f4e22f2ef3cb6efd45b8cf8c44bc83d0b8c9fd5fddd64ffec3fd82c38cfaffe51acf4aa03c5381fa2e\n\nCurve = P-521\n# N = 60\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c\nX = 00038a508e954435eff6ccb82b562ed32ff236f33caef52de9fdf79836e37bbe118392681661adc786c57fb6bf92d04b42fc051c3f6061c252749fd17ffbfca45bdc\nY = 008dbd87d8b1e7bd4d2adb7a7399b931e7169b0ecf8e37baa0e9997df1a529560a5a5edb1e7a605abfd04b1ccdfa683285b4d748f73799f3e5d4f8464ad3910e9522\n\nCurve = P-521\n# N = 61\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d\nX = 0115544c4a011407425c92ca7c732a1c7d8f8b6cd17d5b660d1a4cd724b1be8b17177193c11a77dc0b39a5e7fce59a7b32d7952bad1671543c41cb53d8cfcfc376a1\nY = 01153df9c6c0ac6485b307996d2a399c872c79af485fef422cbfec097a3aed58c6a003f78d54b7f553a8a834ff603afa032b56f22ee9c3fe5e24b8eff8cd4a17604b\n\nCurve = P-521\n# N = 62\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e\nX = 01f605dada534c5c8ae020f6ed49f27734e2378b0b7bc177aeaf943ae59581dd5885a38bf246fec516fd213f3fe32bfd4e19f0a8c971ef2a16969627fe31114dc85e\nY = 014ff96d82698b78d305a2252c7a4be38a37f2b0afd6935f4aaa50e685ccd164a2206284a831f6b296eacb156b6e7671eb7adda2d7e072a578a319f1002224aa57b5\n\nCurve = P-521\n# N = 63\nN = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f\nX = 01c132753b64640c457fe82f799acb0a6e8e1ca21b5affa0ddc1e7f54fe4d51b08453ae99661308e125ec63996847586265e75af7d025770ac8d0f5beb6fce8888e5\nY = 015347e184197a0538176d81ac89b205d7961a9e093286414006595e8c353aa2238005d3dbdcec1896bc13f78f82f0071283af657b5bf664a2ace9d15ad2a03dba15\n\nCurve = P-521\n# N = 64\nN = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040\nX = 01ab9aa17dce1112ecd14f3d7c0392fec2a67ebdbba81860bbacb614b9ccf8872d271bebd3c5efda3773a7c02c1603e7001df5aab8029a04fd41b53dc38ce320f742\nY = 00748d70eb848e920573aa10217c57b9586d9bb1cc8b2fb1dc1d0c63ba369e87ab8bac165ba1508d4b10f4a7b9e3af958043c1c1a5dba0653dd45af17058a5f8df5b\n\n", }; -static const size_t kLen43 = 65077; +static const size_t kLen53 = 65077; -static const char *kData43[] = { +static const char *kData53[] = { "# Negation tests.\n#\n# The following tests satisfy A = -B (mod P).\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000000\nB = 0000000000000000000000000000000000000000000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000001\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000003\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffc\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000007\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff8\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000000f\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000001f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffe0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000003f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffc0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000007f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff80\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000000ff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000001ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffe00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000003ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffc00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000007ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff800\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000fff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000001fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffe000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000003fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffc000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000007fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff8000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000ffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000001ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffe0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000003ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffc0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000007ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff80000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000fffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000001fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffe00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000003fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffc00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000007fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff800000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000ffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000001ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffe000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000003ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffc000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000007ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff8000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000fffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000001fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffe0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000003fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffc0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000007fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff80000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000ffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000001ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffe00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000003ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffc00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000007ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff800000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000fffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000001fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffe000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000003fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffc000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000007fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff8000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000ffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000001ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffe0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000003ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffc0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000007ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff80000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000fffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000001fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffe00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000003fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffc00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000007fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff800000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000ffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000001ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffe000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000003ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffc000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000007ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff8000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000fffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff0000000000000\n\nTest = Negate\nA ", "= 000000000000000000000000000000000000000000000000001fffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffe0000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000003fffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffc0000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000007fffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffff80000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000ffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffff00000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000001ffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffe00000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000003ffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffc00000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000007ffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffff800000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000fffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffff000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000001fffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffe000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000003fffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffc000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000007fffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffff8000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000ffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffff0000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000001ffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffe0000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000003ffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffc0000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000007ffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffff80000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000fffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffff00000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000001fffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffe00000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000003fffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffc00000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000007fffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffff800000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000ffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffff000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000001ffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffe000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000003ffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffffc000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000007ffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffff8000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000fffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffff0000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000001fffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffe0000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000003fffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffffc0000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000007fffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffff80000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000ffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffff00000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000001ffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffe00000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000003ffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fffc00000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000007ffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fff800000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000fffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fff000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000001fffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffe000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000003fffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ffc000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000007fffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ff8000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000ffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000ff0000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000001ffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fe0000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000003ffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000fc0000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000007ffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000f80000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000fffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000f00000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000001fffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000e00000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000003fffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000c00000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000007fffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000800000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000ffffffffffffffffffffffff\nB = ffffffff00000001000000000000000000000000000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000001ffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffffff000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000003ffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffffffd000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000007ffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffffff9000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000fffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffffff1000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000001fffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffffe1000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000003fffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffffc1000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000007fffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffff81000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000ffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffff01000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000001ffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffffe01000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000003ffffffffffffffffffffffffff\nB = ffffffff0000", "0000fffffffffffffffffffffc01000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000007ffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffff801000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000fffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffff001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000001fffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffe001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000003fffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffffc001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000007fffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffff8001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000ffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffff0001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000001ffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffe0001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000003ffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffffc0001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000007ffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffff80001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000fffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffff00001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000001fffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffe00001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000003fffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffffc00001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000007fffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffff800001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000ffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffff000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000001ffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffe000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000003ffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffffc000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000007ffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffff8000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000fffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffff0000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000001fffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffe0000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000003fffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffffc0000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000007fffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffff80000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000000ffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffff00000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000001ffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffe00000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000003ffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffffc00000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000007ffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffff800000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000fffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffff000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000001fffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffe000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000003fffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffffc000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000007fffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffff8000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000000ffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffff0000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000001ffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffe0000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000003ffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffffc0000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000007ffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffff80000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000000fffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffff00000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000001fffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffe00000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000003fffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffffc00000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000007fffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffff800000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000ffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffff000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000001ffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffe000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000003ffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffffc000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000007ffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffff8000000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000000fffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffff0000000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000001fffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffe0000000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000003fffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffffc0000000000001000000000000000000000000\n\nTest = Negate\nA = 000000000000000000000000007fffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffff80000000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000000ffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffff00000000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000001ffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffe00000000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000003ffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffffc00000000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000000000000000007ffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffff800000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000fffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000fffffffff000000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000001fffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffe000000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000003fffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffffc000000000000001000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000007fffffffffffffffffffffffffffffffffffffff\nB = ffffffff00000000ffffffff8000000000000001000000000000000000000000\n\nTest = Negate\nA = 00000000000", @@ -2577,9 +2682,9 @@ static const char *kData43[] = { "0000000000000000000000000\nResult.Y = 0000000000000000000000000000000000000000000000000000000000000000\n\n# Test some random Jacobian sums.\nTest = PointAdd\nA.X = cb8dea3327057fe69b5159e0323e60486cda3400545f7e2c60559ac7c8d0d89d\nA.Y = 553de89b31719830c3c3300aa8ad50ea81f40762a4f33ccf81a2d3bcc93a2d53\nA.Z = 4589e40df2efc546b2572c1f45eda26fc191b8d56376f2063fd9470fb277d181\nB.X = 32ad56497c6c6e8399de6814efd21b3eb949bb80dab578073cf0b0aa92054341\nB.Y = 57b33b7acfeee75ef6a31eb7ca0244b375f2d0962a3ce65c06afaa02688399e0\nB.Z = 337d5e1ec2fc711b12fd6c7a51a2f474a922cb107f592b657617d2e0b4f1d35f\nResult.X = 120c6ddd6f8ebc798c5740005bad5a2586575202df9cc3dd07401fe84d8cfdd4\nResult.Y = 966bc89126349ce41738be691f32c1a068e54a654ab2cb0eac39ef15ee17f0df\n\nTest = PointAdd\nA.X = a858b5249026ccc4d25fbd85db17826afa3c5963c26815cbf8511d84dce62a25\nA.Y = bd753e125579388da968036d50067fe0e8eccb531c4d6f1a69c61bc8259c6d76\nA.Z = 82f9cdd9abf991ac27f0caa494b7b7b2851cc6591c6362ef02d1bd2c33fd116c\nB.X = 3e5790fd7ff28a376586c8ef5625b906f2d5d7e6656191f5a530154eecd4c988\nB.Y = 6e6c91011cc5996a7db4e5539eee635ce84780a85a17778da06353048fdf6bd3\nB.Z = a9ef3402e9f15e7a91aef4a53431b2b2068914e4a09ebdafc8aa654351f32331\nResult.X = de9d6bb4dfdee64193d3eaebb9208a86e764b80e1459fd10a2e01c202e33c5e2\nResult.Y = 370e67dbb7cfa6b79adaeec48b1535f0c329856401102d546c695d0dfe1d0db5\n\nTest = PointAdd\nA.X = a2d85e21bf520691b397ac9e0c1360218cef96a8a6f4c2b24d21791360ce4d9e\nA.Y = 0cc1c5493edf586cd24f7a9f40185c1ceefa727369ed159a9fc09b700ba64f78\nA.Z = ad3083a5bd23ee1fdbd3a25abdee815052209bb1a8b22d3f7d8600442b760a61\nB.X = 7d8850dafe2c48d86b6c3f3f44453670aa7169712238d024dbd08cb4e95b9cc1\nB.Y = 6a2698c143609306fe2c402acdf26e3b42874f5ae3ea2e95898c305e791984b8\nB.Z = c81bc8988c6edabf4a03fcc456ce0c445e225c33b76a79552af0b818350ad6b0\nResult.X = 67c5f8af069b5a5636647eee50da847dff8f5f6ef71780a5d1330453db5c8a04\nResult.Y = cec9200fa541b602d94c694f1289d1d073e64f47054baa40a9921c20ca090643\n\nTest = PointAdd\nA.X = 4f9a035ffeddcc36846906cacc812ffae7f3110fe46bf7da12d0b19ec54c3873\nA.Y = 73539ed620938543f94c358dba87319dca40ae4d13d0a888527f007d26d73d74\nA.Z = 922e97056fbf12d89984346368087375560990c3fb2f337d9f46429f2022d634\nB.X = de6fa333804b1da9f046896634e498d5f456288f8f03cc41fc7ba4b1e978429a\nB.Y = fd45f1d5e905c448b947fd65bc2897928d6014425c8c502a1b2838ba882f5813\nB.Z = 50bb4c98bce36b8aad5662b8db35428bb5c1f298e17347caa5d4f542f278a1d9\nResult.X = 5c3cb05b52ec59f3cbb666b0059163afae885676cf81d64cadc943a1c0bb3a86\nResult.Y = 2871d088271faa9258e60ff28115f72294b938ef3d7b927e59177f9b41d5747e\n\n# Test some random Jacobian doublings.\nTest = PointAdd\nA.X = 75da62f76d1887e18a06483bb6b53c3ec42879ed73b7851ed4748e307653714c\nA.Y = a6f0d0d3bb492bf488d99d549aff3f0c3a48f0c35a5931578fe697b8c5f486f7\nA.Z = 6d6a50229164869f24865148a19a24d57d94ebd09dc06b5e4fc3946a95f9124f\nB.X = 3b225af8c7b6155d66061c75a03d23d94e01a2167fa7f44c5bd1e9d9c48c7421\nB.Y = af58b0e38531d1e08187c61a36b33693ef534ecae23dca4542667d93f1844d75\nB.Z = 86ed2be859c4af1d5cf99041840f3bcb7c9b8e8986811393c96e8bf57fcad872\nResult.X = ab0f931fb86a621102e67336eadcf01afe3127aeaf5b4f89e8f34628c8e1afd9\nResult.Y = 52c50e2783d69dde29d6bc75fa359ffe72e7115c2fc89a9699a499cac25e3383\n\nTest = PointAdd\nA.X = f0d499f2e3775de88ed997feeb4589506f061f93766abb0c1251d25630c4c24d\nA.Y = e8de27c3369ba718adbab5597fbaad9581f5b59ae3b758e7d664bae81d895be4\nA.Z = c62dc820a597f75518734f12b2d3c076e5b872303e37b3663636912ade79c058\nB.X = c2845b3faaa995eb88e13a44b08d8a6fdb37103f7bbcc585302c9d090be3fc5b\nB.Y = 733e5ef1b0314754b70b5b98da63cbb7475918ddb85a715e21aade0c2f2e5611\nB.Z = b8505e4a057d108b49f5d0b20884674be18bba48bbc37f765c2c32c5cc4aba5d\nResult.X = 266f2961b9352b44e61902a235b33f766f82f8199c176920dae25ad2cbad5cc9\nResult.Y = 8560e62047908b13c4247b7e4d2657f2bdecab41e73c846ba18523e5f2918a9b\n\nTest = PointAdd\nA.X = f0ca07297738d8687bffcd3f1433966241f437fa1c3381cf2d13f0fc714bc83a\nA.Y = 1181b9d61c6982e743f1c32de5d14da745290ecaf27297c36ff3ef20a7526a55\nA.Z = 93159618ca5a9f9240df7016ddc983e046126d1290e14478dfcc6a4bae9090bd\nB.X = 3a2d75803ccad665f6b785c828eaa96821cb0e81979641b9e59b5fd488fcc755\nB.Y = 99e7f820abdbcdda23d90a88788e30d67303dac86987816dbbed447431e33f3f\nB.Z = a870186c8137cdbd247d16f3aa18782de1e4c5848f49da3437223eb13d7a9ae2\nResult.X = 36a104368d39214d5a3a1a348a1de1389d1aa23009aee37464b5b3256ed4b28c\nResult.Y = da5b14dbd75f6c333929bdff88e53af7253c27e166e15ead6d778631036b7d38\n\nTest = PointAdd\nA.X = a6256508926caca56a31414aba2d5f5b04dcabdb065352a572e215b043df6e01\nA.Y = e6567d330ffb11a86ec29b406b8e3d5cce8ca46f55f38515d842dd856d6852dd\nA.Z = ec172618c8cdbfc0f4fd6dffb77858bb292f229e6d10b5c70d0d9ba75fa3ab44\nB.X = 0251f6715dbba02e6072c12ab1f89a562d35ed0ff68e021b3b5276b9faf57c52\nB.Y = d2d74ff4740ad968fa7e816bc2178458efee797669bef2e634e2857de1658e62\nB.Z = abbecea633d31f569297a4a9ec28f708c7a097cb2423ebaca66ac0e42b1c8ee4\nResult.X = d2a071d4dd72ad7e63834b58b23c4a034ed7950f5c80fad51bf96959b535d55b\nResult.Y = 3cb8dcbe25f49099b9d8dd1a9cb6073368bf6556130f2aa02637dfcff430e869\n\n# Test some random affine sums.\nTest = PointAdd\nA.X = fabada657e477f088883b2987042e595559d669de3a047b27e3ad339fb3fa5f0\nA.Y = 0551992531a68d55a8409d8466034f02808637610ce6d6bcd9cfceb8da1c3e85\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = 3a831cf2b316ce371994a5622e31749407fdf59660dc88322d14c37ebb2d68d2\nB.Y = 849c511908abdfa2bcadc43f9beae88052fdb00573c783fbb1b34b99687b9a6b\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = d5dc9241b457d33b9bda849fb7aba8baaff8b6eea92974a8adf4b95fbfa849f0\nResult.Y = 089a66780811a8ce455c139c4bea6c5c16234c095a41b9e31c617689bdc6bd0f\n\nTest = PointAdd\nA.X = 9dfe6299e62453bb943356b6f7d90c8b6c646728ba3550bb7c1548f2ba5920cb\nA.Y = 60a4e342a89837c0e7d61c0e3e88a943633028f5260eff6af5ae8a6063f7a5da\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = 924d7305f867afecd3cc550f4c05c83a2b4c981ba0e7ff20fd2035fabe2ccc92\nB.Y = 73934620746c23be03a40edb0662c09ef1776506bd50d6397c2654d340629bf5\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = 7384f658ccbe08afcf6b423bfdd092a8a95b03d81254a519b31517b9b9670155\nResult.Y = e922a56146b94776f805a0fbdee9084dd87be1df54f76145bf83e07cd31a083a\n\nTest = PointAdd\nA.X = 9b6642b661f06c5b3ef2a0950b3c03d35f42d3d0dcbe105a895f40132c40bd9e\nA.Y = 90cbe0ed40e47923257f064886f1e309a310cb82fc21282f8e8fa4f6c975aed6\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = 587f6b4c4bb3ab3d59ba8d31457615b3df9f9f9466df3563f4419db731f494ea\nB.Y = 38135b314572346439c8d4535b892a26e5da650ae1dc9ac2d5aeb85ade24174f\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = 97e94b6d485f8de6779e4ad19cc7bede6d70ff4853a56eb6d5fd4e5caac60858\nResult.Y = 303bf4d62cf569370ae5393fac46b64efe98ee8222b9982bc3dc61b8e32411c5\n\nTest = PointAdd\nA.X = da49658b6c64fc7a7441b177987abbbdbfcfc3c2c569ed97696d706f7af91ca0\nA.Y = 9a66906a6e313603e9d78f99fbbda837e521e75bbbad9455ffd43f51f5e30ee5\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = fe32e5885d0005fa1962166142d2aea201af9c4ca41cdddc5446dc2472f71f42\nB.Y = a2f9b4d35ea19303a101034e96870a7caed371a980965bf86291b03b5c85af60\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = 5375c5ea3e33c1862ca5f09322ce2012c2b4fbee9a299b66e4882e016908cc2a\nResult.Y = 936e4f12ed144cf6fcd0ab085a4929e5e3e7c28641692b1fc2ad9a3b3d447b31\n\n# Test some random affine doublings.\nTest = PointAdd\nA.X = b148cad109d4b24342eb3a03ccaa10dfd6101edf9548b1d1442b61982a4e332c\nA.Y = 7daac293162a8ee2592529630f5bd1eae96659d27c045898d33833999cd076ba\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = b148cad109d4b24342eb3a03ccaa10dfd6101edf9548b1d1442b61982a4e332c\nB.Y = 7daac293162a8ee2592529630f5bd1eae96659d27c045898d33833999cd076ba\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = ad00fae6ab0898f7d5eeeffe8c94b302060fba2b191a2d342a8a302998ebe566\nResult.Y = 9ee46ba864901cad75169cdea023d7e64da39315e2fec1703fad6b613eb24006\n\nTest = PointAdd\nA.X = f21318618205f4967c4f47c9bc3cea41e144dc01830d087414da8dcb16d37cb3\nA.Y = 76cebf81ecc696024fe949191dc49b245ef8cc0d55ada88abf481ddad9eb6129\nA.Z = 00000000fffffffeffffffffffffffffffffffff00000000", "0000000000000001\nB.X = f21318618205f4967c4f47c9bc3cea41e144dc01830d087414da8dcb16d37cb3\nB.Y = 76cebf81ecc696024fe949191dc49b245ef8cc0d55ada88abf481ddad9eb6129\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = ad8e13b721bcbfc0fe629465cda5fee3494785d51dbe65f1e13429f52c83f03e\nResult.Y = 85722e168d89543dce293428e75d52765d0935bde2ef5c45a088222db0dbbeb5\n\nTest = PointAdd\nA.X = 8797ff95334b238dadf0cb3d4dc9350678f4c7fc520089ecb70ab419510f2331\nA.Y = 326c7583d54dde377fa9193c8588912c4db2219e1bb383ab13902187e5ef76ce\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = 8797ff95334b238dadf0cb3d4dc9350678f4c7fc520089ecb70ab419510f2331\nB.Y = 326c7583d54dde377fa9193c8588912c4db2219e1bb383ab13902187e5ef76ce\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = e91c8ec9611de8e44e0d882df59f4fae8d15e3867858fb155256a4a2f154bbc4\nResult.Y = c12be21033c6dcea7e7d7262c47876d099aead75d8b025e45ce7986193fc6f8a\n\nTest = PointAdd\nA.X = 2f4cba9543c9537e393f126e31bedb521dc0a74a940e731800e5e39cdece355d\nA.Y = 1a0957898b746b7dbc9245acd0c6df9e6adca4d8537454c9f318a8ce7c3875c4\nA.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nB.X = 2f4cba9543c9537e393f126e31bedb521dc0a74a940e731800e5e39cdece355d\nB.Y = 1a0957898b746b7dbc9245acd0c6df9e6adca4d8537454c9f318a8ce7c3875c4\nB.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001\nResult.X = 5cdc40808120b68e3131bd6ed70a5ce6618f960e4d540baa582afc71be97c65d\nResult.Y = 1926a2c9f5b2d3d1dff784623fe6efe2ac629395101d38db0eff5e540bfeacb0\n\n\n# Scalar montgomery multiplication tests.\n#\n# The following tests satisfy A * B * 2^-256 = Result (mod N).\n\nTest = OrdMulMont\nA = 0000000000000000000000000000000000000000000000000000000000000000\nB = b4e9b0aea84aa5ed86964a22881a4d0e58f88e9225f30990c18751e7d4b9ec95\nResult = 0000000000000000000000000000000000000000000000000000000000000000\n\nTest = OrdMulMont\nA = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf\nB = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323\nResult = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323\n\nTest = OrdMulMont\nA = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550\nB = abafdc695e4c2c850f8fc60f1efdbf7406a3cd2c6c59bb7e608985723896c187\nResult = 917b1214c7b31a7ee7e53be0b41a139e435ff576b51ec6af1e1a944412bea38b\n\nTest = OrdMulMont\nA = cf0f01b83670a1c79154ea16f3574ca2d4c688a3c3b6017795cbe54854418904\nB = c5ec4d3b00fb2e11fb3b1aa09e60f7d187f7c515977d1343dab9745961fcbb43\nResult = 7aaddcee32e3b340af5ad06f854284cbbce5a1ab919e9b7771c3b0e937093438\n\nTest = OrdMulMont\nA = 50023f9913879ac4020bc45a89a0ea89082db6265b96b851af29969dd8a9661c\nB = 7c165b1cba80808db114441563aa0fbfba41b9e8acff77312a2dd2138b74ef89\nResult = 3d2ca1705d8d38cbc76a5409c6535044733cafcb95d12654af1d14de177978b5\n\nTest = OrdMulMont\nA = 4d5341ea735e53d2e4f2934755642adee209bd0e5a1506206513227f3c48b270\nB = 6e48f2b60eb8fb86760134abaf3d61692557862924069c599ceb31309ea18704\nResult = 37cde3e35c814d4287bd345b910d687983929907b7a08afa2acd8596832ea86c\n\nTest = OrdMulMont\nA = 33d06c3f5a595a41a6f9c4356f8ab2b8c550d4c64b806eab5560af247c5fa9ed\nB = 0e52f34adf5754343bcf3529d652620da3c05b5dd9cdcddfb08b674a1ad21a09\nResult = 9dc64d7b4c1bc33b930e0daee2a24fc41f770378659ee71b846d2239b0fea8ea\n\nTest = OrdMulMont\nA = 8f211780cce4f93b7193b9378e6f83e1147fb3602b052eef782de8cc833e54ab\nB = e1e4f7f1feb15be64292cff86b47cd9730bcb15b133340022b824d591a660cdf\nResult = dfa2b683b1ae23027c7c109e0abb40a1366eda027ad2cad1a09061a57bee391f\n\nTest = OrdMulMont\nA = 803c279c7e4c11a5568290c0a5789ceab6860f51a942bf646501a45e1ec0a6bf\nB = c0a1145a12037129c571f5f939bf16ea0b8b480f08ec774c045d059841f7d5ed\nResult = ab48fa3b4aa692a7c077cc55ee3c3fff895118a23728c2fa5f361b30730d955a\n\nTest = OrdMulMont\nA = 0e5c95158297d75dbf0b02c3090730f65bf14704495b14837dd907af569407f1\nB = 5a03e3787c8772b2fb7ab07d7fe7fe653a58bdae7fde3174c6ed305e524f5728\nResult = 71296d305dcf9ce39010ea4f4bbf9f7c1064a413597bdc7574c13dea3fa514dc\n\nTest = OrdMulMont\nA = 366299be07886f7846fc74231db624b169360e3c8f60196a1afc9f2101e03922\nB = d6d7c830a6edb6861868b964519a6b68f6f24f7c09d66003f3f88eadd1e00158\nResult = 0b89596bf5054ebe95a39dab6e975b58190160610b09b2a4f93331ecc0e79fd3\n\nTest = OrdMulMont\nA = 8f36f0ef275a72192c3b7388e84df2b8acf66fc53aaf556e3be05c76b3f782c0\nB = 704e519363d44e8df8d91f5f347eb61e8d3e85c8fc1b82980c370a379b2bc81c\nResult = b70a392e3ce5e85b5efbbded9b8c16a3068ba9b93b4cbed9a9a71dffaad6b58a\n\nTest = OrdMulMont\nA = bf4466ef4dea9f06f0f3b4f14e01140a774262c7e0706584f4d7dac19be46d58\nB = 4af12d528b2cef0f6714961bca2ab682f8abaa97600ea8181f71563d56f8a9f5\nResult = 7b6827c0881b9846e32499e13277efb07917cf4b8c8c72bfb3daa8c1786a8e15\n\n\n# Test cases where A == B to test squaring.\n\nTest = OrdMulMont\nA = 0000000000000000000000000000000000000000000000000000000000000000\nB = 0000000000000000000000000000000000000000000000000000000000000000\nResult = 0000000000000000000000000000000000000000000000000000000000000000\n\nTest = OrdMulMont\nA = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf\nB = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf\nResult = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf\n\nTest = OrdMulMont\nA = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550\nB = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550\nResult = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79\n\nTest = OrdMulMont\nA = da43b8dd7fe8830a4fe8980ec585ccbe903a2965a695cdff398200b74b2ede41\nB = da43b8dd7fe8830a4fe8980ec585ccbe903a2965a695cdff398200b74b2ede41\nResult = 5ec68604412205b380e26ee4e4081eccc10ac7d1417b09cd534f8517b0de81ec\n\nTest = OrdMulMont\nA = a82a2b8bdbf8a37dc7cb5799691494a8c9fbf649686a4d250dc30697feb0fa47\nB = a82a2b8bdbf8a37dc7cb5799691494a8c9fbf649686a4d250dc30697feb0fa47\nResult = 552c094a8841621d6cc26b3b54ce5da5664283888445196a6433d3cfdcad3aee\n\nTest = OrdMulMont\nA = d785006e250410d9dcc6d7740795a7374c25b00b9c9a37b8285694a07307eacd\nB = d785006e250410d9dcc6d7740795a7374c25b00b9c9a37b8285694a07307eacd\nResult = 971aaa9e70ad082cf43725f2e65bc73f4bf762459cee13167545072ec7bdcaf8\n\nTest = OrdMulMont\nA = 69d6d9f5417e87d603a3fb6acafa0d1f974abf94ca57ce58d718a0ad5d02a496\nB = 69d6d9f5417e87d603a3fb6acafa0d1f974abf94ca57ce58d718a0ad5d02a496\nResult = eb3284e5799fbe93171f08e6de9f792cd17f036b3a17671b0310e49b48e589b3\n\nTest = OrdMulMont\nA = 1c28f742c3e26e74901d0425f2eb4d5272524668d2405875b32cf6433f212900\nB = 1c28f742c3e26e74901d0425f2eb4d5272524668d2405875b32cf6433f212900\nResult = 74f70a95399b7ad061a2200fa50528d68eee4654341c8158101e1e3f8f16e642\n\nTest = OrdMulMont\nA = 026b2f69f0259d221920b2f358b378a79826f0332ee36afa257765043e3d6732\nB = 026b2f69f0259d221920b2f358b378a79826f0332ee36afa257765043e3d6732\nResult = e1e9cfa4724995bb50971ca22f3c028cd31cb51fbef8a37c31f10fd1d468f13b\n\nTest = OrdMulMont\nA = 376ed4fadcc1c6c4160a0c9c2ab7c62260367968b08d304d47c65f25625d7d60\nB = 376ed4fadcc1c6c4160a0c9c2ab7c62260367968b08d304d47c65f25625d7d60\nResult = b9ccb67f377e1278f1d2eeda26e5eed76f32406c9deed9764fc0aa346d91e02b\n\nTest = OrdMulMont\nA = 50f66867d0a4ef389678d760d2a4db886583b4c068d0e240f7ddf3472c871304\nB = 50f66867d0a4ef389678d760d2a4db886583b4c068d0e240f7ddf3472c871304\nResult = 82c3467bc5f7ca8b45f4ee61546745e2f53755a02e87f65f572418d60e471c8b\n\nTest = OrdMulMont\nA = 5b8bd82b37206d2b727f19ad2d02f63773470074dde7d43d2a77c448ddf2f978\nB = 5b8bd82b37206d2b727f19ad2d02f63773470074dde7d43d2a77c448ddf2f978\nResult = dbf3c2fc67a0688c3b5ff12cab1739d50b6093c5d98943d388652b1207e4a0f2\n\nTest = OrdMulMont\nA = bed7b3a4dada0e16984eb59ee239005ab212e5b1772cdd5d240c8ee268f65c81\nB = bed7b3a4dada0e16984eb59ee239005ab212e5b1772cdd5d240c8ee268f65c81\nResult = 9232aa2759ca9c5efbaefb0cf45cc6bc9c89def8c25e5c169fe623f30787df36\n", }; -static const size_t kLen44 = 169648; +static const size_t kLen54 = 169648; -static const char *kData44[] = { +static const char *kData54[] = { "# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test\n# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip\n#\n# NIST's files provide message and digest pairs. Since this is a low-level test,\n# the digests have been extracted. P-521 test vectors were fixed to have the\n# right number of leading zeros.\n\nCurve = P-224\nPrivate = 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615\nX = 605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eab\nY = f5cc733b17decc806ef1df861a42505d0af9ef7c3df3959b8dfc6669\nDigest = 07eb2a50bf70eee87467600614a490e7600437d077ec651a27e65e67\nK = d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0\nR = 2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6\nS = 8d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb\n\nCurve = P-224\nPrivate = cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5\nX = fa21f85b99d3dc18c6d53351fbcb1e2d029c00fa7d1663a3dd94695e\nY = e9e79578f8988b168edff1a8b34a5ed9598cc20acd1f0aed36715d88\nDigest = bde0fbb390fb05d0b75df5bd0d0a4ea29516125f19830e3b0c93b641\nK = c780d047454824af98677cf310117e5f9e99627d02414f136aed8e83\nR = 45145f06b566ec9fd0fee1b6c6551a4535c7a3bbfc0fede45f4f5038\nS = 7302dff12545b069cf27df49b26e4781270585463656f2834917c3ca\n\nCurve = P-224\nPrivate = dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73\nX = fc21a99b060afb0d9dbf3250ea3c4da10be94ce627a65874d8e4a630\nY = e8373ab7190890326aac4aacca3eba89e15d1086a05434dd033fd3f3\nDigest = c2c03fe07e10538f6a38d5831b5dda9ce7478b3ed31323d60617dc95\nK = 6629366a156840477df4875cfba4f8faa809e394893e1f5525326d07\nR = 41f8e2b1ae5add7c24da8725a067585a3ad6d5a9ed9580beb226f23a\nS = a5d71bff02dce997305dd337128046f36714398f4ef6647599712fae\n\nCurve = P-224\nPrivate = aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e\nX = fad0a34991bbf89982ad9cf89337b4bd2565f84d5bdd004289fc1cc3\nY = 5d8b6764f28c8163a12855a5c266efeb9388df4994b85a8b4f1bd3bc\nDigest = 5d52747226f37a5afcd94d1b95867c0111bcb34402dad12bee76c1b7\nK = 1d35d027cd5a569e25c5768c48ed0c2b127c0f99cb4e52ea094fe689\nR = 2258184ef9f0fa698735379972ce9adf034af76017668bfcdab978de\nS = 866fb8e505dea6c909c2c9143ec869d1bac2282cf12366130ff2146c\n\nCurve = P-224\nPrivate = 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4\nX = 0e0fc15e775a75d45f872e5021b554cc0579da19125e1a49299c7630\nY = cb64fe462d025ae2a1394746bdbf8251f7ca5a1d6bb13e0edf6b7b09\nDigest = a1ab56bd011b7e6c7e066f25333d08cf81ac0d9c1abfa09f004ab52f\nK = 39547c10bb947d69f6c3af701f2528e011a1e80a6d04cc5a37466c02\nR = 86622c376d326cdf679bcabf8eb034bf49f0c188f3fc3afd0006325d\nS = 26613d3b33c70e635d7a998f254a5b15d2a3642bf321e8cff08f1e84\n\nCurve = P-224\nPrivate = 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131\nX = 2c070e68e8478341938f3d5026a1fe01e778cdffbebbdd7a4cd29209\nY = cde21c9c7c6590ba300715a7adac278385a5175b6b4ea749c4b6a681\nDigest = 8ef4d8a368fad480bac518d625e97206adcafa87c52aef3d179cbfa9\nK = 509712f9c0f3370f6a09154159975945f0107dd1cee7327c68eaa90b\nR = 57afda5139b180de96373c3d649700682e37efd56ae182335f081013\nS = eb6cd58650cfb26dfdf21de32fa17464a6efc46830eedc16977342e6\n\nCurve = P-224\nPrivate = d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974\nX = 3a0d4b8e5fad1ea1abb8d3fb742cd45cd0b76d136e5bbb33206ad120\nY = c90ac83276b2fa3757b0f226cd7360a313bc96fd8329c76a7306cc7d\nDigest = 28fabbac167f3d6a20c2f5a4bcee527c96be04bdd2c596f09d8fbab7\nK = 1f1739af68a3cee7c5f09e9e09d6485d9cd64cc4085bc2bc89795aaf\nR = 09bbdd003532d025d7c3204c00747cd52ecdfbc7ce3dde8ffbea23e1\nS = 1e745e80948779a5cc8dc5cb193beebb550ec9c2647f4948bf58ba7d\n\nCurve = P-224\nPrivate = 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8\nX = 4772c27cca3348b1801ae87b01cb564c8cf9b81c23cc74468a907927\nY = de9d253935b09617a1655c42d385bf48504e06fa386f5fa533a21dcb\nDigest = 50dd74b5af40978e809cee3eb41195402ebb5056e4437f753f9a9d0d\nK = 14dbdffa326ba2f3d64f79ff966d9ee6c1aba0d51e9a8e59f5686dc1\nR = ff6d52a09ca4c3b82da0440864d6717e1be0b50b6dcf5e1d74c0ff56\nS = 09490be77bc834c1efaa23410dcbf800e6fae40d62a737214c5a4418\n\nCurve = P-224\nPrivate = 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2\nX = 1f249911b125348e6e0a473479105cc4b8cfb4fa32d897810fc69ffe\nY = a17db03b9877d1b6328329061ea67aec5a38a884362e9e5b7d7642dc\nDigest = 9fee01807ab6c43a794abf6dcd6118915252ca7d3a31a1ff96b88a8d\nK = ab3a41fedc77d1f96f3103cc7dce215bf45054a755cf101735fef503\nR = 70ccc0824542e296d17a79320d422f1edcf9253840dafe4427033f40\nS = e3823699c355b61ab1894be3371765fae2b720405a7ce5e790ca8c00\n\nCurve = P-224\nPrivate = 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7\nX = 7df67b960ee7a2cb62b22932457360ab1e046c1ec84b91ae65642003\nY = c764ca9fc1b0cc2233fa57bdcfedaab0131fb7b5f557d6ca57f4afe0\nDigest = c349032f84384b913bd5d19b9211ddce221d66a45e8a051878254117\nK = 9ef6ebd178a76402968bc8ec8b257174a04fb5e2d65c1ab34ab039b9\nR = eef9e8428105704133e0f19636c89e570485e577786df2b09f99602a\nS = 8c01f0162891e4b9536243cb86a6e5c177323cca09777366caf2693c\n\nCurve = P-224\nPrivate = 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b\nX = b10150fd797eb870d377f1dbfa197f7d0f0ad29965af573ec13cc42a\nY = 17b63ccefbe27fb2a1139e5757b1082aeaa564f478c23a8f631eed5c\nDigest = 63fe0d82cf5edf972e97316666a0914432e420f80b4f78ceb92afd1d\nK = 385803b262ee2ee875838b3a645a745d2e199ae112ef73a25d68d15f\nR = 1d293b697f297af77872582eb7f543dc250ec79ad453300d264a3b70\nS = 517a91b89c4859fcc10834242e710c5f0fed90ac938aa5ccdb7c66de\n\nCurve = P-224\nPrivate = c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6\nX = 3c9b4ef1748a1925578658d3af51995b989ad760790157b25fe09826\nY = 55648f4ff4edfb899e9a13bd8d20f5c24b35dc6a6a4e42ed5983b4a0\nDigest = 9b44ee16e576c50c0b6b37ac1437bf8f013a745615012451e54a12f2\nK = b04d78d8ac40fefadb99f389a06d93f6b5b72198c1be02dbff6195f0\nR = 4bdd3c84647bad93dcaffd1b54eb87fc61a5704b19d7e6d756d11ad0\nS = fdd81e5dca54158514f44ba2330271eff4c618330328451e2d93b9fb\n\nCurve = P-224\nPrivate = 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc\nX = f0acdfbc75a748a4a0ac55281754b5c4a364b7d61c5390b334daae10\nY = 86587a6768f235bf523fbfc6e062c7401ac2b0242cfe4e5fb34f4057\nDigest = 3c89c15dee194b3223e7b53a8a5845d4873a12a2f1581d5413359828\nK = 854b20c61bcdf7a89959dbf0985880bb14b628f01c65ef4f6446f1c1\nR = a2601fbb9fe89f39814735febb349143baa934170ffb91c6448a7823\nS = bf90f9305616020a0e34ef30803fc15fa97dffc0948452bbf6cb5f66\n\nCurve = P-224\nPrivate = 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3\nX = 5fad3c047074b5de1960247d0cc216b4e3fb7f3b9cd960575c8479fc\nY = e4fc9c7f05ff0b040eb171fdd2a1dfe2572c564c2003a08c3179a422\nDigest = 2b7faf36fdf0e393ddeb9fc875dd99f670e3d538fd0462395ea06c8f\nK = 9267763383f8db55eed5b1ca8f4937dc2e0ca6175066dc3d4a4586af\nR = 422e2e9fe535eb62f11f5f8ce87cf2e9ec65e61c06737cf6a0019ae6\nS = 116cfcf0965b7bc63aecade71d189d7e98a0434b124f2afbe3ccf0a9\n\nCurve = P-224\nPrivate = 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912\nX = 6dd84f4d66f362844e41a7913c40b4aad5fa9ba56bb44c2d2ed9efac\nY = 15f65ebcdf2fd9f8035385a330bdabec0f1cd9cc7bc31d2fadbe7cda\nDigest = 5b24b6157c0d1edf3a40c22a0745d23bdb59379e5e5e776ed040288d\nK = 7bb48839d7717bab1fdde89bf4f7b4509d1c2c12510925e13655dead\nR = 127051d85326049115f307af2bc426f6c2d08f4774a0b496fb6982b1\nS = 6857e84418c1d1179333b4e5307e92abade0b74f7521ad78044bf597\n\nCurve = P-224\nPrivate = 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa\nX = 4c741e4d20103670b7161ae72271082155838418084335338ac38fa4\nY = db7919151ac28587b72bad7ab180ec8e95ab9e2c8d81d9b9d7e2e383\nDigest = 00c6fc53c1986d19a8a8b580ee553dc1240745d760647d1c0adf442c133c7f56\nK = 06f7a56007825433c4c61153df1a135eee2f38ec687b492ed40d9c90\nR = 0909c9b9cae8d2790e29db6afdb45c04f5b072c4c20410c7dc9b6772\nS = 298f4fcae1fe271da1e0345d11d07a1fca43f58af4c113b909eedea0\n\nCurve = P-224\nPrivate = 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972\nX = 897089f4ef05b943eeac06589f0e09ccc571a6add3eb1610a2fc830f\nY = 62ba3f6b3e6f0f062058b93e6f25b6041246c5be13584a41cae7e244\nDigest = fb5dd3b8d280fe7c4838f01b2a5c28493ed3084f46b40642600ba39e43fbff7b\nK = 5b6f7eca2bcc5899fce41b8169d48cd57cf0c4a1b66a30a150072676\nR = f12c9985d454ffbc899ebbbb6cf43e3debcac7f19029f8f2f35cce31\nS = 12fcb848adbd8b1b4c72b2b54a04d936e4a5f480ae2a3ea2e3c1baae\n\nCurve = P-224\nPrivate = f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170\nX = 40a4ab1e6a9f84b4dedb81795e6a7124d1cfdfd", "7ec64c5d4b9e32666\nY = 83aa32a3c2fc068e62626f2dafce5d7f050e826e5c145cd2d13d1b27\nDigest = f4083aebe08c9bdb8c08ff844ffc207f80fa4406fb73bdbc1c6020f71281bdae\nK = c31150420dfb38ba8347e29add189ec3e38c14b0c541497fb90bf395\nR = bf6c6daa89b21211ea2c9f45192d91603378d46b1a5057962dafaf12\nS = cb6b237950e0f0369323055cd1f643528c7a64616f75b11c4ddd63c7\n\nCurve = P-224\nPrivate = c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85\nX = 66f49457ed15f67ed4042195856f052fe774077f61cebcb9efddc365\nY = 3a6e3f3423eec7308a69eb1b0416d67cc3b84d24f251d7cbdb45c079\nDigest = cb017b280093879c4b114b52ea670f14e97b661074abccc8539a23280fe136b4\nK = 5e5405ae9ab6164bb476c1bb021ec78480e0488736e4f8222920fbd9\nR = 7b7beaf9f696ca1a8051527478c4c075ab45aa4768937886dbf38618\nS = 93d4cf110a37c5a6f15c4e6024822118539e860dee2f60b8c3f462f6\n\nCurve = P-224\nPrivate = 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6\nX = 8d642868e4d0f55ee62a2052e6b806b566d2ac79dbde7939fe725773\nY = 79505a57cd56904d2523b3e1281e9021167657d38aeb7d42fc8ec849\nDigest = 5f1d77f456d7ed30acad33795b50733d54226e57df4281a43d3821d0762f12fe\nK = ec60ea6f3d6b74d102e5574182566b7e79a69699a307fee70a2d0d22\nR = 2fd7fcbb7832c97ce325301dd338b279a9e28b8933284d49c6eabcf6\nS = 550b2f1efc312805a6ed8f252e692d8ee19eaa5bcd5d0cda63a1a3f0\n\nCurve = P-224\nPrivate = 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39\nX = 7924b1d7f5920cce98e25094e40f2eb3eb80d70b17e14b3d36c3671c\nY = 26c5af35f71e61858582b7cc2b41790597c53ee514ffdf7a289d108c\nDigest = cce0671ca07521fdaa81eced1dc37282bd9a6dbbaeb8cd00d13d4cf75cef044c\nK = 751869c1d0e79eb30aae8fbfb6d97bfa332123fd6b6c72c9cd3c1796\nR = 26bb1b92b0f01e94eba5fa429271371db527ce857abba13bd1103f64\nS = 836aba9c63e1252c2b2d72a21e6a41b82241ebe32647e7f814652bcb\n\nCurve = P-224\nPrivate = 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6\nX = 18cb5826ad60e6696bf07655032a3749f6577ca36da3ccd6e66a137c\nY = 194e14820fe02d784fd1363ff7a30399518309765bd3f4412d646da2\nDigest = 4ee903b828f54f35adab0bfec06eb064abde530d8ed0384730aa23e8e9664801\nK = e2a860416229dfd3f5a5cc92344ca015093a543943a0d8f73bf2b2fd\nR = 00e300c1ef4a8c4ca5da6413856f8981db49de29bdf03f32ffc3ceab\nS = f250f18a51ba5f63e1584097841099fa6ae4e98ee458c061d1d5aed7\n\nCurve = P-224\nPrivate = 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b\nX = 076518e393940d42dfd09819409d66966d8c9189c83d554a9cc8a082\nY = 44d0ceaf4c0f50e46bea4a52e30423ce3ada19edd363ac5694c65cb8\nDigest = 215e9817eccaa125e0c053fed373f4605de292d27a692bd4f744e63215fd8705\nK = 6be6dd9f6a083915ccba54626caf12d246d3aece0a7eda7d8d85599c\nR = ff1460946e06fb6f5d35e8d2625ca70ffb9b45308e3fabf6ad8351b1\nS = 6029aa3990918e8cb8a388d53b0772e5cdfff49c3405fe0d3a95933a\n\nCurve = P-224\nPrivate = 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b\nX = 279649e2a2918e683520cde3fc98b0ae58a7100e8de35e7c9cc797b6\nY = aa4de6be34be61f02880139787b9038f4554a8ef1c994b887c2974b5\nDigest = 6571a344765c0512d3911a7724509b649a6ce4106823be76726f117f109ec0fa\nK = 8e984864f86f7a2a73f3edda17dbccd13fac8fa4b872814abf223b1b\nR = 3b18736fa11d04e27e2614cda03a63ec11a180f357b0b3192920d09c\nS = 2f0f3dbd570727b14fbb29155538e62c930dd51c4035275c1365dc60\n\nCurve = P-224\nPrivate = 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8\nX = 3fa617c50b177da1a2bdb98b780ad21ad1195c4bd24465f6187de3c9\nY = e3fd8d8876dfd03a4a4e31a1acad3a08d983826d286c250c4e5620c1\nDigest = 95914b17ff0362e12305d71657bbc9d919ae4aa746bf4ebe95b2d2fe7ca3f022\nK = 0128b8e3f50731eb5fcc223517fc0cf6b96cd1d2807eb4524bc46f77\nR = 3a6b633f96f3d0b6d54f7fb29ac33709e4f0dd8fa0e51606ed9765ca\nS = 63e8c119dfa51784decd864f6911f2210a80f8f02d472d88df10d119\n\nCurve = P-224\nPrivate = e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784\nX = b7ae1e992b1c7fde1141f40bd913358538ca0f07f62b729f13cea327\nY = 811252d12120e04805fc171a439d382c43b68a21e1a0bdf5e4ec1da4\nDigest = 2dd97b10b2ac90709062989f57873e30696bf8376957e68f7de95aa333a67685\nK = 7abedab1d36f4f0959a03d968b27dd5708223b66e0fc48594d827361\nR = d35047d74e1e7305bb8c1a94e8ae47cb1591c3437a3e185e00afe710\nS = d9c425c9d5feb776ac8952e6c4eee0ecd68aef2f0e7bff2e49c9185e\n\nCurve = P-224\nPrivate = 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c\nX = cd95cf8fb1cd21690f40d647f2353672a1076cc6c46bddaad2d0fc56\nY = 934262f74d9ee0f8a2754f64cb7415923d64bf00c94a39b52803f577\nDigest = 7c74a2e71f7bb3101787517394a67d03f977c95519526b47854e417b95bf8d1b\nK = 557d0e3995dc6377b3911546dd7aeaeec62a6d8f2af6a274382fc37f\nR = 56df0ea6afdcc232ceb41729eec00cf906b69b6e28423a36d3c92cc5\nS = f4f70fd948c9a147f55317fdea7b8a84c33e721014552d5800d63edc\n\nCurve = P-224\nPrivate = 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583\nX = b88652020e083ccc1c43dc83d1881884dd4c7e3b4e3460b344b1ea64\nY = 22b69b517f86d7c26dc37c0f8feb4bb07fe876149fbcc3334fd2805b\nDigest = ccc04666744685c57d2256f21cee0f53857a0528a96d59bb13cdeb92fd786d4f\nK = e4f4a3280574c704c2fde47ca81ec883d27f2c5a961a294db7cda9d2\nR = b30b8a0079d9a134b5e1618c2ac63e3fbe0e95866b9dbc5f423f2707\nS = 3dc36746610271ef66e0aa52cc2ccadc5c9b08dc769e4dc4f6538c11\n\nCurve = P-224\nPrivate = 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2\nX = ce1a06f82df874dded37cca03b56c0648e4e8917ecd40ee73ee61588\nY = ceb6177b8f1ac7c5c6e6e1f7737cc3026952ee392badd2cd7af32f9d\nDigest = 9e7d5f30677692b669e21cf5461fa7f2e887dfcbbeb2db88d666bd591a944e00\nK = e401fa80f96480d437ed4f61a783888062ec33d530b188fd48016a6d\nR = 28674f447c4742e4087bbccfb522fbad4e18b56031d2ce8f532b078a\nS = a5a7a13d15b423dd17771f73cea98d89dbffa846cc209b45c0e29b76\n\nCurve = P-224\nPrivate = f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc\nX = 0dc2cdddb990341adb1de73f02d87fc3822485a659a15145f4251d5f\nY = cf78b2a83c7352eda1af2c74e1804ea04b35f76c04e89d90281dc2bb\nDigest = d8978f697bef71b062d4b3211e8ab5b993c09920af803614dbb9437f6e261b70\nK = 5d1476c682a64162fd2fdc82696fc8cab1469a86f707ea2757416e40\nR = 82982b38ed465138df4018d7cfb835edcb591cb57446ca49d163782b\nS = 8ef1d7b326cabee7f7ab95b7b98d3c27a069c0fd95a1599c0ccb422b\n\nCurve = P-224\nPrivate = 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd\nX = bd6ba605639b98fa8113a16a3bb004ddfaec901c98a931206165f4a5\nY = a3190b10ef39e88abd60b2293b4707512b45c6c5ed5794cc11454427\nDigest = 1a9fc0195bf0f53cebba8aa7ccc8567c680d75187392d6d8201854ec4a6e6abd349037d831809e9f3add2fc09d27e4a4\nK = 0f0bb1e428bcdebf4dc62a5278068efc0f8ce75f89e89b3630f102b2\nR = aac0ea27e129f544abcc77f110e70bbdd5aa3e425dc39d5e8887025d\nS = 10e5dd06aee6b8419a04aa33d9d5678b0039c3acc3c4b61fe106bfdc\n\nCurve = P-224\nPrivate = e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3\nX = f5d5346f17898ea6bbdfff19c216a8757a5dc37b95315f5481628381\nY = ae61fd172ac8b7a4f13870a932dece465834cbd4f50bbcfb802c824e\nDigest = 0f236d9a43edd55dacf5ff9f93ee805395e130ca2c8ad2eaea0fdd68e2ee2fadae9f41aa46f881485db208bd9cdc463b\nK = 35724ac043e3b44b73b5a7919cf675190306d26aa67c27c28c873534\nR = 535147c265af138eec50c7fb570bcc8d2e6f675597b0fcc034e536bc\nS = 743812c188a1dddf9fb34b90738f8b2e58760d6cd20ccceb1bb9c516\n\nCurve = P-224\nPrivate = b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17\nX = dc5d217862a1e5b00c95affa9d8b925a72b9beaeb7a86dc397e788d8\nY = 5f05f8e976ae1eb1036eca6d683a82850795bf9127dee5f8b2859445\nDigest = 525b6241eb2a6dd00b55b172708aafd0775e959b7c601903f44ffcfc17ee979f34f204680f8a71044a6d7e3679a50576\nK = 408e9c8b1f33136d6ddb93ff3a498bc09d4eee99bf69cdd5af0aa5a2\nR = 1b5a964c8b1fc634c6e2b82322499df1d7f0c12a4d2a77723c816ab8\nS = cf54599a36ca064fae0aa936de5266f87704409d22a15d28c01b7f2a\n\nCurve = P-224\nPrivate = efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085\nX = 61521a0cfb72be77ba33cb3b8e022743cd9130ff49e97093b71aa178\nY = ce0819aedaf6fce639d0e593f8ab0147eeb6058f5f2b448231584ea9\nDigest = 88c4b7ca396f17e82c92596c301e41d7f01810bfeb33173cc0d1fedf3fd5ace6892ba9a788de13417f0ef00ff87344fb\nK = d1eea821f286eae6ebc1f61b08f9ad4323a3787e94af4c32cd31351b\nR = b37caaa71103752ac559f9eb4943324409ebfa8b585f684dcaa5c411\nS = 7c28e7619e2944ab4b7be022878c8052ebdf2cae5dff4f976c49686a\n\nCurve = P-224\nPrivate = 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd\nX = a7e975c0a8f87c683bb8e31bc160843a7b69c945f4850bd60e1c08c0\nY = 8930a454dcc2aa13bed7ea89368b2c9d689d816b2acf4e52585ee9c4\nDigest = 3babfaba30f3300171e6adcf4f62a12287031ac40078c96b2c2c063849e9a42ef3be953dc11fb319c18bf22fe511bf37\nK = 44b1fdec2629f9075f89c134ac28ff19bfddaa", "9db02a5d7f853582b4\nR = b0f5635d8bc9c53a1d54a3ec63de59ed66e6b2358d4ab79755414326\nS = 67c68fe265c7e5aba4232deeafb88545a2aa266fb9f2c2bb3f3ae8d2\n\nCurve = P-224\nPrivate = 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d\nX = 3191f0237102dac159032ab2dde53cf56c9ec827b5caddfe9e83c02a\nY = b496b1bdcca4434ac0d0d91ea38ff3bc33f9f54095bfe17796d5a9e2\nDigest = 9f36da1a5653469a52f85e7e3b2a21ac3497cc00ff37e03235bbdf951695f182312ad5c8fb8a5fbd0295dc8c5acda068\nK = da529c52f5cc1f435d873109cd991d6cd7e1631d9ff1dd9521dd5db6\nR = 8e0ac63903f4921755430572c3f08bc272790639bdf1009fe2a9a714\nS = 6278c841a2d0a270791fe54b36c49d426d67907aa4e4f59c8638ad97\n\nCurve = P-224\nPrivate = 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0\nX = 9fdd99906ab77fd29e9021bde947d05a7a9eb153612269bfb0899bc9\nY = 681b65b9ac8e4c2899bb622dafb253b7bf5a6e38e5f6595f997c291a\nDigest = 12532cbcfd4e80373bc235ac0bfa2a70b1044786d29f9384d555030f5df3cb5ab9f973df638b6835cb756792d1fe1a4e\nK = 66ed8d8934633f4125f593cf1b1d3745c4db1f15dde60cf46ca1c7f2\nR = 80199485a3a96447b39f7679cd47412a78675ba17dcbd10465dc5b48\nS = a251fd9f136a3cb0dd0bc80659ae032e4a761ba7045da0034553fb8c\n\nCurve = P-224\nPrivate = e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d\nX = 46c9ed837232c47022df2f1a1578fbe65ac9f2e81c98a74cc22ea31a\nY = 6fc5e9568ae62b31412a0b0b367242e9fd7e518c83aa06a069e1d90d\nDigest = 89030408e06cc06d3dbfb51f6725c710a2bc9db9e07ff1ec8a32a827d93d2dc951834cdb01a7afa1fe4cf4e9186ee424\nK = a4c1eb402a2fb3af26e0e14a3d2fc8ed3bc1a8b2475270356a79fdd3\nR = d478b68733d8ad44be46766e7b66af782fbdc7ff7ed0b191176da98a\nS = 5eae9160ccf71fd1d359d89cecce72ef8afaeee2365f6ba828aa450a\n\nCurve = P-224\nPrivate = f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7\nX = 9ca2c6ea87ac8dd3a23a5b4010841a7c8af309038882ae44634bcf55\nY = b0a347dbd5ded3b8702ac5a457e8b32bd4de06fd315095fa1b7d5fe1\nDigest = eda24262a9e64be110a6c96763e8a4b5edb38af2a084695e294593583b462c56b0db50bc014eb19278e3f3d675eb5f22\nK = e3cc786c1288ea567836c51d6d69dd0cab5c015987d936ccc3a4beb3\nR = f1234da71761b7a0f49e661a419d2a739bdc4544bf87690e3d2f96db\nS = 096d16bf8020c3d3c233894ad8eb81206010e62c6e692a215e088fd4\n\nCurve = P-224\nPrivate = 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c\nX = 101271a9addd4bd1f19d00bf116c8524f52cefd598e85dc381597acb\nY = 2f17d14f4d8ccb28b216553718152ba7c104646d8eca986dd9ddea39\nDigest = 983a5d16b009cc65bdf3c3badc2f21280e04f44244b70a583c2e9732534497373f51b226c3ab7bd69c6940e46bc41fa1\nK = d169f04f05b60c625cda864d187938863964dab7bb3b9dfc04b05519\nR = e4a51be686a764b709da23ab48b1985e153c6ee238d945e743907afc\nS = 118a8f1ffe3cd556ce6345bd1a398dd9cc3729b7fd6d8af9bfd82f40\n\nCurve = P-224\nPrivate = 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18\nX = 9edd544107977134bf6360d43ccabb3c94d627c03963c0a04b439627\nY = ece4c61d319a0e41f3de7863e7c355bac94395aaa74cdb5f74a87a5b\nDigest = ae7b5fde427af9c450368b11f66f49bf8c3b6e1f5abed6bb25683001924dfb005738637e1c1b7855566330d202ecc763\nK = 36f7c0f76808b826a0a974a1fd6e155e00a73f1d34674a8f88be405a\nR = 3e319444438bc2cc92f323ea842cb402b3c3c2448c89869ef7998edb\nS = 3420cc38f058f41c31e71f4b1ad488f801111c73541de69fcee60695\n\nCurve = P-224\nPrivate = bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a\nX = 8848f964c847fe9dddc774618d4588c9cd56bbe588d7b1fb369c8bfa\nY = ebbb699fbd0dc08859fe9132285fe20dff3b9d561c0640b6e0717607\nDigest = 63ef787f467ff0cd6e5012b09414c00ef56dba959c4b62bf7e76a4205078d436c45591752c8d55abe728a2d28b5b0643\nK = 59f1450d857b40e5552a4b8cd4ab0df2f01716635d172c1106840f21\nR = a206d8398a16a991bc217f77f23c6f648384f254f255a8a876404444\nS = eb1169cb5b1423dc0bfaffe565ae57f986e00de06405e3e7b605862e\n\nCurve = P-224\nPrivate = dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738\nX = 063a5d632f4144376e14cfb03ad8ccf1489b613acd184d20dff66545\nY = e77727f057b043d8a0f7458196b72e92d11f85b0891c6aaa9d915f58\nDigest = 11f0d587e82e7490af4737c272877d9d37c1e7ae7f2fd3b00d8fa0d4f2bcb3a41d5185e65604b8c411a407eb6c558954\nK = ff0e5cae2671db7a1b90e22c63e7570bdd27352d45bac31e338debe0\nR = 5bc0b4998481ecbd3b6609184a84ca41d69b08c37138097f559259f8\nS = 0df8828eb1ca85e46405b94e1a2972c34c5e620a54e2f640f04aecc5\n\nCurve = P-224\nPrivate = 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01\nX = de616848d8044a44789ef1ba3a6dd66fe9257ddc57f7534e59a701be\nY = 26cbf74a6d25e5b34b96d30f327abd574cff7f7dbe6686573a7d6c5c\nDigest = 537d6d3d4be3e3beaf31014dae59ca7186c1c1a32c88068ff343180a138ceb6d7c38e0ae1e9b51003b71c1a2f3a3741b\nK = 3b18ca6ec8e8e255ac88f64302745ca0b73ff94b2b2d48be95b4aaee\nR = fa94fd8b827c06115c1eefd50afc02ce5926ee0e789667783c01c34b\nS = edf766a66973cfc33e4159966c07321a7f6549c3c60e8586ef41402b\n\nCurve = P-224\nPrivate = 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28\nX = 3858a576eef2ce24d01766997fb81b3f3f78b6104cd188610be221d7\nY = 95ffc677ac7bfe3e0bb4cffb17355a964c8356a807151b3cba5d1f4e\nDigest = 7e16034a71ebf52a7a6cd00fe469c6edc121b2882462176298c9443aca2a0ad6ebe2eb9e145097409873170f40d503dd\nK = c1a2ec1ef16cfd5107c892790daefbed061be78bd8576696b60f64d5\nR = 18c908541843fcdac99b9ff6bb397f3f8094d16b42670216e4eaa2d7\nS = c107a8a508ff57c5d4f78f86cc37e129c864d1c44ed5e73909613b74\n\nCurve = P-224\nPrivate = ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6\nX = ac635fe00e8b7a3c8ef5655bdfb7f83e8532e59c0cc0b6534d810ffa\nY = 1d067aebeba66e79b28ecfe59ac6fdf5e1970dc3a84499c9d90cd8e2\nDigest = 3edbb59a32b2464291d0a96023a798c1fc6cb5ff4fcecfadcfac2be00c26fa27181aef76c96d8269aeaf2275eeacbb777abbd9571de9279edc5695a3345cad9b\nK = 187ed1f45c466cbafcd4b9577fb222408c011225dcccfd20f08b8d89\nR = f83d54945997584c923c09662c34cf9ad1e987da8bfd9be600e7a098\nS = 4ff2dba9dba992c98a095b1144a539310e1a570e20c88b7d0aa1955c\n\nCurve = P-224\nPrivate = 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc\nX = ecaea8ceea55c3bd418fd34a4ff2499e25e66a104eed846bc00c31d2\nY = 3933a356ab1f2dabc303ff0a5d076131e77032e6f502336883bf78a7\nDigest = 825ab979af5c263d9f074a2d771d1d1cdfa435e7938245a3c9ee30cb77ee8c1475051d2f09d7d11d920a6c754bfd253903131c491994679cafdb8cfbf32b763d\nK = 34cb597deae9a3b1cada937abcd247161b19b2b336b20e2e42ae01f1\nR = 58177ba46fb291490b39368774accf72736412c1fb5ee0f27b9b1e02\nS = 58337d78b95a080bfcabb5809bee012501b4da84b8ef310a4628f11c\n\nCurve = P-224\nPrivate = 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b\nX = d656b73b131aa4c6336a57849ce0d3682b6ab2113d013711e8c29762\nY = 6328335ffc2029afbfe2a15cc5636978778c3f9dab84840b05f2e705\nDigest = d0db7c20c201cd8c63ca777293543750d7f6a9e375b056e74cfe9fb2c95b2cc9807d8a9607a5b0fad6eeda86e4f73ace139e77a5356181b8cbef3f88173253b6\nK = dc82840d147f893497a82f023d7d2cbf0a3a5b2ac6cc1b9b23e504be\nR = 583af080e0ec7c1ba5a491a84889b7b7b11ccfe18927c7c219b11757\nS = b23700035349df25d839f0973bef78a7515287de6c83707907074fa6\n\nCurve = P-224\nPrivate = afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc\nX = fe83e59fc8ea8b939355d3258fe53a64d45f63031a0716b7cc416173\nY = f151d23060f1c856eb7f1f58be72a7228c3af89e43b56e9695b558c7\nDigest = 37d9091eddc6fc34b45cf97140e956a42ab659f6bd442e81b57c4ecfbdab45f7380a7efdbac5400ceb1bf683194232cd086c1b4e09fc9313f1bc38af731f1a98\nK = 0fbbe7b40136c81a8fb894498d5502157a1cf5a89d0643de92cd38f6\nR = 24f3f457c7b72b7e759d5a8afbf330e31c5d8d2e36f92c0e79c5d87d\nS = 36fd1193def34f12a960740fd79fb38bf2b480726ccad540eb42cdf8\n\nCurve = P-224\nPrivate = 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c\nX = f43d13bbfcee3b724063b3910fea49fd591b81e86fdb813b1a492d0c\nY = 6b4c8d6fa5dc661889e3cf5ec64997a78222837885f85d2fe9b684fb\nDigest = 8ddf64c9c67289a76c2f5b44a30b8365f4adf487b4edadada5749cad9e5765c57a348a750817a53e5c2ff551e003747ca1e3438b2aa1952c6876fda8fd8f4de2\nK = 83e110d0d1e700d2f36543028737d2a2f1474aa3b4b28998a39e4793\nR = 2685265bc878e85d10ab13293dec190881a57c4a467f8fc2170432ea\nS = 80a347bb49036522369339bd6485a967cdda818915d8eb947302fcf9\n\nCurve = P-224\nPrivate = 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc\nX = e868690641e2cda13b289a6c5d2fb175940396044d9cf27b4f2240af\nY = 4c78c9abdf2b7fc67ed4497001d7bcf1daca1739dc14a661f91d7c40\nDigest = 7c22f34d5897ccdf7d807f68a7f16e3093a4413625e7853401a4e0384d26893f1997c84557515f2ea66afe7629f62415e6b98e18e97dcb4fb2dec97cf2dd68d9\nK = e2374350f47c08f3c1359d4edf87e61d1ba4e7dd1540d8d9062efa79\nR = e12dc088d2bc032bb214c77d0e0fb749fc8e61ebe1ed72996f1084b6\nS = 0ab58aa31e0bba5fbc76855e6549", @@ -2602,9 +2707,9 @@ static const char *kData44[] = { "a0cdf2910c42c9f1954a4572d8e659733d5e26cbd35e3260be40017b2f5d38ec42315f5c0b056c596d\nR = 00d732ba8b3e9c9e0a495249e152e5bee69d94e9ff012d001b140d4b5d082aa9df77e10b65f115a594a50114722db42fa5fbe457c5bd05e7ac7ee510aa68fe7b1e7f\nS = 0134ac5e1ee339727df80c35ff5b2891596dd14d6cfd137bafd50ab98e2c1ab4008a0bd03552618d217912a9ec502a902f2353e757c3b5776309f7f2cfebf913e9cd\n\nCurve = P-521\nPrivate = 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb\nX = 00c97a4ebcbbe701c9f7be127e87079edf479b76d3c14bfbee693e1638e5bff8d4705ac0c14597529dbe13356ca85eb03a418edfe144ce6cbf3533016d4efc29dbd4\nY = 011c75b7a8894ef64109ac2dea972e7fd5f79b75dab1bf9441a5b8b86f1dc1324426fa6cf4e7b973b44e3d0576c52e5c9edf8ce2fc18cb3c28742d44419f044667f8\nDigest = d209f43006e29ada2b9fe840afdf5fe6b0abeeef5662acf3fbca7e6d1bf4538f7e860332ef6122020e70104b541c30c3c0581e2b1daa0d767271769d0f073133\nK = 01e25b86db041f21c2503d547e2b1b655f0b99d5b6c0e1cf2bdbd8a8c6a053f5d79d78c55b4ef75bff764a74edc920b35536e3c470b6f6b8fd53898f3bbc467539ef\nR = 01dce45ea592b34d016497882c48dc0c7afb1c8e0f81a051800d7ab8da9d237efd892207bc9401f1d30650f66af8d5349fc5b19727756270722d5a8adb0a49b72d0a\nS = 00b79ffcdc33e028b1ab894cb751ec792a69e3011b201a76f3b878655bc31efd1c0bf3b98aea2b14f262c19d142e008b98e890ebbf464d3b025764dd2f73c4251b1a\n\nCurve = P-521\nPrivate = 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77\nX = 01f269692c47a55242bb08731ff920f4915bfcecf4d4431a8b487c90d08565272c52ca90c47397f7604bc643982e34d05178e979c2cff7ea1b9eaec18d69ca7382de\nY = 00750bdd866fba3e92c29599c002ac6f9e2bf39af8521b7b133f70510e9918a94d3c279edec97ab75ecda95e3dd7861af84c543371c055dc74eeeff7061726818327\nDigest = c992314e8d282d10554b2e6e8769e8b10f85686cccafb30e7db62beaad080e0da6b5cf7cd1fc5614df56705fb1a841987cb950101e2f66d55f3a285fc75829ff\nK = 01b7519becd00d750459d63a72f13318b6ac61b8c8e7077cf9415c9b4b924f35514c9c28a0fae43d06e31c670a873716156aa7bc744577d62476e038b116576a9e53\nR = 0183bddb46c249e868ef231a1ebd85d0773bf8105a092ab7d884d677a1e9b7d6014d6358c09538a99d9dca8f36f163ac1827df420c3f9360cc66900a9737a7f756f3\nS = 00d05ee3e64bac4e56d9d8bd511c8a43941e953cba4e5d83c0553acb87091ff54f3aad4d69d9f15e520a2551cc14f2c86bb45513fef0295e381a7635486bd3917b50\n\nCurve = P-521\nPrivate = 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c\nX = 012857c2244fa04db3b73db4847927db63cce2fa6cb22724466d3e20bc950a9250a15eafd99f236a801e5271e8f90d9e8a97f37c12f7da65bce8a2c93bcd25526205\nY = 00f394e37c17d5b8e35b488fa05a607dbc74264965043a1fb60e92edc212296ae72d7d6fe2e3457e67be853664e1da64f57e44bd259076b3bb2b06a2c604fea1be9d\nDigest = 6e14c91db5309a075fe69f6fe8ecd663a5ba7fab14770f96b05c22e1f631cde9e086c44335a25f63d5a43ddf57da899fcedbc4a3a4350ad2edd6f70c01bb051e\nK = 00e790238796fee7b5885dc0784c7041a4cc7ca4ba757d9f7906ad1fcbab5667e3734bc2309a48047442535ff89144b518f730ff55c0c67eeb4c880c2dfd2fb60d69\nR = 01d7ce382295a2a109064ea03f0ad8761dd60eefb9c207a20e3c5551e82ac6d2ee5922b3e9655a65ba6c359dcbf8fa843fbe87239a5c3e3eaecec0407d2fcdb687c2\nS = 0161963a6237b8955a8a756d8df5dbd303140bb90143b1da5f07b32f9cb64733dc6316080924733f1e2c81ade9d0be71b5b95b55666026a035a93ab3004d0bc0b19f\n\nCurve = P-521\nPrivate = 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63\nX = 01d7f1e9e610619daa9d2efa563610a371677fe8b58048fdc55a98a49970f6afa6649c516f9c72085ca3722aa595f45f2803402b01c832d28aac63d9941f1a25dfea\nY = 01571facce3fcfe733a8eef4e8305dfe99103a370f82b3f8d75085414f2592ad44969a2ef8196c8b9809f0eca2f7ddc71c47879e3f37a40b9fecf97992b97af29721\nDigest = 26b4f562053f7aed8b7268e95eff336ac80a448fae52329d2771b138c9c7f70de936ef54158446afa72b0a27c2a73ca45dfa38a2ba2bf323d31aba499651128f\nK = 00517f6e4002479dc89e8cbb55b7c426d128776ca82cf81be8c1da9557178783f40e3d047db7e77867f1af030a51de470ee3128c22e9c2d642d71e4904ab5a76edfa\nR = 01c3262a3a3fb74fa5124b71a6c7f7b7e6d56738eabaf7666b372b299b0c99ee8a16be3df88dd955de093fc8c049f76ee83a4138cee41e5fe94755d27a52ee44032f\nS = 0072fd88bb1684c4ca9531748dfce4c161037fcd6ae5c2803b7117fb60d3db5df7df380591aaf3073a3031306b76f062dcc547ded23f6690293c34a710e7e9a226c3\n\nCurve = P-521\nPrivate = 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da\nX = 009ec1a3761fe3958073b9647f34202c5e8ca2428d056facc4f3fedc7077fa87f1d1eb30cc74f6e3ff3d3f82df2641cea1eb3ff1529e8a3866ae2055aacec0bf68c4\nY = 00bed0261b91f664c3ff53e337d8321cb988c3edc03b46754680097e5a8585245d80d0b7045c75a9c5be7f599d3b5eea08d828acb6294ae515a3df57a37f903ef62e\nDigest = ea13b25b80ec89ffa649a00ce85a494892f9fb7389df56eed084d670efb020c05508ac3f04872843c92a67ee5ea02e0445dad8495cd823ca16f5510d5863002b\nK = 00ac3b6d61ebda99e23301fa198d686a13c0832af594b289c9a55669ce6d62011384769013748b68465527a597ed6858a06a99d50493562b3a7dbcee975ad34657d8\nR = 00cef3f4babe6f9875e5db28c27d6a197d607c3641a90f10c2cc2cb302ba658aa151dc76c507488b99f4b3c8bb404fb5c852f959273f412cbdd5e713c5e3f0e67f94\nS = 00097ed9e005416fc944e26bcc3661a09b35c128fcccdc2742739c8a301a338dd77d9d13571612a3b9524a6164b09fe73643bbc31447ee31ef44a490843e4e7db23f\n\n# The following tests exercise the bit-shifting case of ECDSA digest\n# truncation. The digests are larger than even SHA-512, but P-521 is the only\n# common prime-field curve. (This case typically comes up with curves over\n# GF(2^m).)\n\nCurve = P-521\nPrivate = 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da\nX = 009ec1a3761fe3958073b9647f34202c5e8ca2428d056facc4f3fedc7077fa87f1d1eb30cc74f6e3ff3d3f82df2641cea1eb3ff1529e8a3866ae2055aacec0bf68c4\nY = 00bed0261b91f664c3ff53e337d8321cb988c3edc03b46754680097e5a8585245d80d0b7045c75a9c5be7f599d3b5eea08d828acb6294ae515a3df57a37f903ef62e\nDigest = 007509d92dc07644ffd324d006742d24a4497cfdb9c4efab7768426b3877d810602a84561f82439421e49533f72f50170222ed6c24ae6c11e50b7aa886ac31801580\nK = 00ac3b6d61ebda99e23301fa198d686a13c0832af594b289c9a55669ce6d62011384769013748b68465527a597ed6858a06a99d50493562b3a7dbcee975ad34657d8\nR = 00cef3f4babe6f9875e5db28c27d6a197d607c3641a90f10c2cc2cb302ba658aa151dc76c507488b99f4b3c8bb404fb5c852f959273f412cbdd5e713c5e3f0e67f94\nS = 00097ed9e005416fc944e26bcc3661a09b35c128fcccdc2742739c8a301a338dd77d9d13571612a3b9524a6164b09fe73643bbc31447ee31ef44a490843e4e7db23f\n\nCurve = P-521\nPrivate = 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da\nX = 009ec1a3761fe3958073b9647f34202c5e8ca2428d056facc4f3fedc7077fa87f1d1eb30cc74f6e3ff3d3f82df2641cea1eb3ff1529e8a3866ae2055aacec0bf68c4\nY = 00bed0261b91f664c3ff53e337d8321cb988c3edc03b46754680097e5a8585245d80d0b7045c75a9c5be7f599d3b5eea08d828acb6294ae515a3df57a37f903ef62e\nDigest = 007509d92dc07644ffd324d006742d24a4497cfdb9c4efab7768426b3877d810602a84561f82439421e49533f72f50170222ed6c24ae6c11e50b7aa886ac318015ff\nK = 00ac3b6d61ebda99e23301fa198d686a13c0832af594b289c9a55669ce6d62011384769013748b68465527a597ed6858a06a99d50493562b3a7dbcee975ad34657d8\nR = 00cef3f4babe6f9875e5db28c27d6a197d607c3641a90f10c2cc2cb302ba658aa151dc76c507488b99f4b3c8bb404fb5c852f959273f412cbdd5e713c5e3f0e67f94\nS = 00097ed9e005416fc944e26bcc3661a09b35c128fcccdc2742739c8a301a338dd77d9d13571612a3b9524a6164b09fe73643bbc31447ee31ef44a490843e4e7db23f\n\nCurve = P-521\nPrivate = 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da\nX = 009ec1a3761fe3958073b9647f34202c5e8ca2428d056facc4f3fedc7077fa87f1d1eb30cc74f6e3ff3d3f82df2641cea1eb3ff1529e8a3866ae2055aacec0bf68c4\nY = 00bed0261b91f664c3ff53e337d8321cb988c3edc03b46754680097e5a8585245d80d0b7045c75a9c5be7f599d3b5eea08d828acb6294ae515a3df57a37f903ef62e\nDigest = 007509d92dc07644ffd324d006742d24a4497cfdb9c4efab7768426b3877d810602a84561f82439421e49533f72f50170222ed6c24ae6c11e50b7aa886ac318015ffffffffffff\nK = 00ac3b6d61ebda99e23301fa198d686a13c0832af594b289c9a55669ce6d62011384769013748b68465527a597ed6858a06a99d50493562b3a7dbcee975ad34657d8\nR = ", "00cef3f4babe6f9875e5db28c27d6a197d607c3641a90f10c2cc2cb302ba658aa151dc76c507488b99f4b3c8bb404fb5c852f959273f412cbdd5e713c5e3f0e67f94\nS = 00097ed9e005416fc944e26bcc3661a09b35c128fcccdc2742739c8a301a338dd77d9d13571612a3b9524a6164b09fe73643bbc31447ee31ef44a490843e4e7db23f\n\n\n# The following tests use digests equal to the order and 2^n - 1, where n is\n# the number of bits in the order. This is to test the truncated digest not\n# being fully reduced.\n\nCurve = P-224\nPrivate = a80489eee3b15dedbc2d8ca4134f18b7d1a541fc212718f21a04692c\nX = bd283d0c18d90b69d9ee3e0f1e8e62f53822f5593fc94343666495b5\nY = b3177709b8dc4b62928f9dc561c2b4be42c7df52d4e90e7e885b4021\nDigest = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d\nK = 90fbb04276d112cbb6ecd2053e2a870f02350ac7e2881c89851a4640\nR = 7d0642a2cb98b56ff91837bd23e20bd90b60613b60eabfbc078cfbfa\nS = 0209a75bbd6c2310fa55fe2c0c3ddf35be53fef6e1cccf0537f3e7be\n\nCurve = P-224\nPrivate = 72a2e505634a669d492d28b1b43974cca3aac7b5eaffa1719a551d3e\nX = 42bafdd82b5bd766a727211e4af8bf46015705b878772b296791cca3\nY = f5db26e760f4b2ec586222d3cecb525fed32a841fa0ae547f5c435db\nDigest = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nK = d6abc49b0e60f1e2e7a5736aa8e93a5de9777f4b9e6c96692fcb662b\nR = 42232b212356d9adbb5e43e96e23c376fa5d21c9ad6a50137d2e3bd2\nS = 020596ef40a9dbea4d6779ff02c9cb853b520093113a968a32309118\n\nCurve = P-256\nPrivate = fb801b1a1161c143578358dc6edf8357167c12636e5b588e171d8bffcca78d7a\nX = e57231383637c82c1ac801724cf7e03e67198f467a9beb60ac13cb582d13afa8\nY = 8f190e090155fcf63810b858bc88e259dc49afef8bdef6fd06d93dddb1991aed\nDigest = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551\nK = 3d1df8b364fc045d8c6517f7a4b99c91643a2bca351b3a74fe36268c97198c3e\nR = 05cc6037bb021f4910ea2e489fab2bae6bb6a2769a97f42ba5736994102b7f10\nS = 5db54832ceabf8bccdb8be99b1a49cecff8feee045cb697dec43118e2695b1da\n\nCurve = P-256\nPrivate = df1ae1f7a1043d03811c61695dba0350bbe58d36a670da66d58c69e5bc9ce1fd\nX = 6e0e2897b9a554ee287cdaf43bfbe25ca8404373971575a0e4b61c61aff5a2fe\nY = 23ea7823a411eb1b39f81bbde24c2cd6ac68be2c7eec3a0671c8676131b8905c\nDigest = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nK = 6b6e0cf93ce4482a4c23821125186f39656ccc993e4f080ac8750c32927a515f\nR = 16831feeceab2fab1c575e073e944d73ce7e6f3e9b06312088f06159c530ff50\nS = 870cb824692638538b1569c6093fcb693c054e8e3b9a919e3bb26798910f66e9\n\nCurve = P-384\nPrivate = 2218a70d35d5a9eb16442eee8e74a8b992d9475edadd6b814ae6c8779b32df164553546bf3405bd5242b85092e2f0098\nX = f4a961c19f9cc4ebe4f43081110955f3cede085a08c1415d726e80b2eb774028c5fc96f092ba3ea7d1288dd57fe1db08\nY = 981398eed0895e09b3b582a0616f3024e51cca7b1ecc347dbf0d24a5f6a222b0c31912f8f5e427d4dde5c6c45212bb10\nDigest = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973\nK = 118f1682e0dc4602fc6f142f98d48e36adf32566f34be311ca55ccbe00fec28e52d72857e02f139578316a5dbe1ed9b4\nR = 0b77eaff05bbd922dd80525d2ab301cc119318f5a920a12c71c4b5ff5bb77d25a538983df9bdd5984b0d159daf21f1a2\nS = 73af85ad03a34b6b3993082bf719018d25d1555717b2d2f2535d0601af06a71ad020eff8232d065ab9d7fc4cd0c0ee42\n\nCurve = P-384\nPrivate = fae6a843fcef48d15685766d189fe1f597cd85d4e07172c8e19589e1aa2e8e8c4b75731e9afccb7b585926934583829b\nX = 54dd8d7cbf2ccdf1a42f5bbc615a372803b094f6040e3c7b651a61bc6912432c836cf2410ab7d67f543236751d81066f\nY = 2219d6257b1c80bf327c96786f2b5d0b5a9b9bf7eee9c853bf66a3bf09520494cb1f7823e4c566d79a617b7e201ead96\nDigest = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nK = b7db03d70db5cdcce3c708e55ad88eba80e90f6bb0be3713686bf298709a8b326619c1d47318f9af60039ff051f33a1e\nR = 9d923e199d98272e44b8fba382bf3c19660ecb4a9aae3513ff6802a73fef510c15c202807c3f9334b0bce7d6c6a80839\nS = 520784e6290d04d9b61993ee5ebc6fa8ff527fb0777c43cdefc7586701e60edb399005a5648ff852de80208232849fbd\n\nCurve = P-521\nPrivate = 015a5274c44e51b3cce4b1d657186871a851747e086934cb132559d83e07b3b2544c5d62b26385272101e20f963d2df6e029d6a6818cc4839c3f28a4c384dff4befa\nX = 00056cc489982829b728978193d047596325a91ee2e2c9110f7da605fd2d1b78424e87d85500f391fe9f54209c42e582ca3284484afc6edfe2acdc69c3591f6c47cf\nY = 010e91be6632da7afd03caedebdb572fd41cb1a7221e9c2d984016bac4693b3d10c5b1d76ba32b89f5fadd157df122be9cd85151977b99176998cfccbd3f9a03ba3f\nDigest = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409\nK = 001441599703e14eca10a787dd421c334bdd4c91ad33d05fe2929100a5eb343df47fb28236423323e769ad1cbaffc6e9ad01a06b2e401d647511ad2e920c2145262d\nR = 00bd5e59a9bc97de61588d143990ad7fd5405ac53aa8e6332a085a301138b23beaba126b41549db1167df47362a9de77c73b1bfaa14b31114644b4db8d35179f706a\nS = 000cbb560f68b7240e309301ed4e6dc20d329f7e2098bcae26a07dd364e6177bb408eb5d0b47a3fcf36def98b951af9a55a47d24d95cd66cc11973269694e2f6f8d1\n\nCurve = P-521\nPrivate = 00cfac6f8a1906241d873da27b4166e0d0bd76c511177835d0978117056db44750eb0648e6899f215e6c0dd6902c114a802ed5935df8c54290fbfe184ff8ccae444e\nX = 002aca58eeac43152b292f42a6a677d327386337409ba7de17acae1978e097f21e49d47f707c6ed6045c66551c93df9ef9bcc442db804e62fcac9f0574876d6d7fea\nY = 01862ed4f9d235afcc4e6b45e491da363104d4db7b97f12d869c40ab09a3c8c72519a9712ca733ddf046ad039842e8caed2425ecaf42d5171b3e236c11fee8699684\nDigest = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nK = 00938d2f6550a46fb07b058e6287f428f0ff12aa6732a666d4a6cf2dd7cd8023ca76d0ce4e16b62830d0ff9e2fab9987261f3f3ffe0749ff70950d91b897d57007b2\nR = 00ec0b91fa4386a8acdc0e46dd9c1d1775abbe0da8ead424aa4ace58e284a5be00e2c1ef95b6f4d861615564e1e7305656567f95275ce63b534420eae77ec37492c2\nS = 01e1099fb389db498ab4cf23b4f06a74b9326878ae3c76ea13832e50702b30fe8303093a59cc9a0995f1dfc15e6f7dabca8a2acaf03ec005447d29fb429a252064ec\n", }; -static const size_t kLen45 = 170210; +static const size_t kLen55 = 170210; -static const char *kData45[] = { +static const char *kData55[] = { "# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Verification Test\n# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip\n#\n# NIST's files provide message and digest pairs. Since this is a low-level test,\n# the digests have been extracted. P-521 test vectors were fixed to have the\n# right number of leading zeros.\n\nCurve = P-224\nX = a100d410ce497e991070285c439cd361a1a9c6c973fd6f5e1ba9ec66\nY = 0a8c3a2f909f212c84441b8c0030529cbd731304d86f771d89d7cc29\nDigest = 6a02c84186eb132d8e91ab6fea2e066f6f8de1a5\nR = 1bfcaab01e47addd4733369320364ad208169ffb15e6aac33c2d7c06\nS = 07fb33465e7b7b373feda2ea35ab7cc9477156a1335ecad942f99627\n\nCurve = P-224\nX = a6cd3d14cd5eb188a9f59d9c32e93d890558de382f6fba5ff5c6e395\nY = 7a76734a0afead9e5e4aba65f1ae353d6445b1689b5ea402de5f9af9\nDigest = ab1205b7f9f591a013c70cb645435b38689644c1\nR = f0f670963c3d2a3281d639f850f3781c6402d99a1bf07cd9f35b2975\nS = 758e84920c1b744502cd787cdd64ec58364ccc6917258a2580097492\nInvalid =\n\nCurve = P-224\nX = f5fe7875a517207f1336ec2bb4fe5cc7eb80ee2b0f8ebeff4c56e620\nY = 0b7ac24ea9092d03b28904d89714b517be023235abc9cffa297cf4ad\nDigest = d62c7a42fcf3738276a6e0d27160328e9f27e5aa\nR = 88617e694e361d2cfef6b0658d444607fba030ad31fe8dead14db22e\nS = 5b0bf37c4a583dd75d99aec20943ea02617cecdbcd295d35ed01cc32\nInvalid =\n\nCurve = P-224\nX = 8a6a77179ffc0ff5d412cf859cc82aa19cd18e5224ab997e9c2e46b0\nY = 3d67c177ca7cc12c7b05a3bf55fb78549ef5400a566efe8ae3580c9f\nDigest = 0b5a025a4038b6f9f995001c0b8d7a660e6766c2\nR = 107b7442e6569ddde54b5da55a9dac9bd348079358047a19a3de0b91\nS = 92359be39353cb263946294fb728eecf1880f50a43637f391d3e7824\n\nCurve = P-224\nX = f9f23388d573562f29e7e7c9a98f27e7a1ff02d2d66e177c6506466f\nY = 4545937caf1878fbacc34ca38a0e5e1f6ad2b25ddd796d06c8d12351\nDigest = cf670c7589b91dac6a131fe2e863e86ee790ca75\nR = bc1db32e437c67439c27db1dc607e3c505210c984bf707a8e87abb70\nS = b760f4943a2397311e54e888a1ad379ad9c45d1fd09b5389ce1a00ee\nInvalid =\n\nCurve = P-224\nX = 8781e5a98950092570d685964e9ed27760fb7dcff8d3b6f3c8f77151\nY = 9207cef64b7c2ed181c57337001f45f1e800e0d1bc8adac296e454b5\nDigest = e5e5e8c8b3f7146c72ef86ca1b75f422181b5729\nR = 79826ae5b0297b9404829df0f02bbb7b8acb35459e13a4045c40f242\nS = 2a629dab19c9e5cd0a551a43851fe6d8409469f86cbcf6204b41e5b5\nInvalid =\n\nCurve = P-224\nX = 03c78c532b8767784fd45e75027abce3371181f8f54914811588cbb2\nY = 166c7b70e98fa11ac361d827557676ec07e553370a462b4fe502dedb\nDigest = 270606c9c9b136ffada9588f15f9786455369422\nR = ff18b493b166d832c9c25ee491525e4c188ff2b804e38b5964941c48\nS = bbf4291db484b4e4143c01a284c03543bbdaa2db1f1c571f1e5a5e2e\nInvalid =\n\nCurve = P-224\nX = 99fab11464484cee96d72dfcf0327d671787a2f6ee32f9b184c48fec\nY = fe8ec3d660cfa3f3e09e5cfc2c3298d4de2f464416deb5b4a27ac062\nDigest = 9c77c796ba619aedef68b2d30b4ba00c4972488b\nR = 714c48c143cb259408c04f77a38d6484e788cb268fc9789d5e871491\nS = 542793d5dbcabcebc83a809cca02b8e95189c93fa4e330d66d5a62ef\nInvalid =\n\nCurve = P-224\nX = 014e8e57388eba32ebdce80df60c481e5c7758374f90a92e0a82f1b9\nY = d1aa8418f992283c5b6bb0461f05dc9103050dc55e0265e1c99b935d\nDigest = 82b45d1fb3bb502c7c20ee1e2d63f2aaa9f492ab\nR = a159b83e80e656f54f614e8437821bd87f6f13264ac8eca1b3ddde29\nS = b77b7bc8cf374f012ee15f9f9224a46a560a5b689cfc92ca4fa03459\nInvalid =\n\nCurve = P-224\nX = e0b9e3cadca81311923d6d6adcfc326b62fac9c4b8d61c5f960c88fa\nY = be505338108f8d3f0ee80aefa304d51dd4a4035477934a98a6111403\nDigest = f4da99fee346e572906e6dc8083a3d0c2e09b773\nR = 8dba585dc3312056a7be61161c7af8ba8b538f0c125c80cf9af2682e\nS = 1b5b1adac4d66c7045f3f79c3aa154a0274c4a994ac7a093e2482eeb\nInvalid =\n\nCurve = P-224\nX = 29197e94a3617e62d9999c859640871a4537a073ca4f12a4c324dcad\nY = fe198969ac7cbe49df2c61c4cc6fa502c2207a7da10acdccec7b1cad\nDigest = 58fab970cb7c1f0dac21b7c7fd67d0ad169688a1\nR = 261670b09afaeee71c590c5658e3f57d859b18a887f70fdeb90e57ea\nS = d1d12c11cf7f4a9dd015ead4bd245793cb37ffee1f4cf109b7b68394\nInvalid =\n\nCurve = P-224\nX = 0fac352c1c444435e6aeb1d60f28ac773b0170ae902afb0944ef0a12\nY = ac3ca693a7c5347a074808b43edea94059e2b1d0571d935fde3f5841\nDigest = 4b69dbfac12f1b974566d8170d1672d0f5fc0506\nR = c33c7a4de313ff856d2f51cd9e3d173bd10668c296f0e6b208c036ef\nS = e562d30822b5cc69713a57ce8c70f83827add85a06c88109505ebf7a\nInvalid =\n\nCurve = P-224\nX = b0d4298e998b7d9d4509322a1ac974c6180956533debafd3d9e7f2fc\nY = 185a64ca840d4b6a2800e72433f26dd523f97daadc18d6d01533f0ad\nDigest = b84805c37e76e530729ddcb59a68ad69d40c82f9\nR = a5155ce53050cbfe84b67d62ce118c6004564087f2fe1cdf44e9c945\nS = b6894b050d77a3ff4d191ddc0c9fc7009a7472e31739949193d7cceb\nInvalid =\n\nCurve = P-224\nX = 59996a4a06658e553fc2993f0f55e3fc8ca2cb52d30f882a37729be4\nY = a5f68f26ea6608fd1f350d8da7c187c7e70f23363177a5aa41508fce\nDigest = ef0a69578d8a1dc930803a7ad2a92c3c19ab6513\nR = 704ef49e0a43c61ef5b325899acb9d12287883a849976c8b9c950634\nS = 73da6e3a26d5c512405fc09fcfdf650dd8da748e6c3dfc05032d7a9f\n\nCurve = P-224\nX = a0cfdfc5a096b0b23ba6748ebaad17e60228b204aebdc01057a7154b\nY = 9f6bd5369d21d88d7b5c3ce221af530fb9a8fb91e751cdb855ff32a6\nDigest = b05f0232e6d44151e249e7b75c7c9ab05c14d44b\nR = d68aa9048e84b8653b8ff3ab31bc73884c6ac7df1fd1bd3c38c16b0d\nS = 38ce58afe5fbc6af892e06a4ddd978c745d5ec700cab825c11dd8fd1\nInvalid =\n\nCurve = P-224\nX = f1eb36b3e1c96a18d87878d5fa8b79d77afce9d2ce40d26199f33482\nY = ae819af474f3efbd62401a407036505c5a2d60449274593865de3374\nDigest = 1dd27c95dd6fb3f080afebdf5a1ad906502e12ab8f64e5f38f67c386\nR = 003122e976bac378c06ec95fd73290b067e7ff022d23493c40663ec9\nS = b99eb4220146a282c7a34f98a9a4fa38ed3f48ca2c7983cde2d3235f\n\nCurve = P-224\nX = 3bdcc7c6112cde3c0522f1a4863f1d7b6727c5bff67598ba2f1bafc1\nY = 47acb6b254e0e8747e0039de471d0dda443cb09a592c678717d83200\nDigest = 19b39292f4e862ed3ee90c35e709587231191632dc8b35611dd24abe\nR = a5aab7768f549f8fe3c7e650154c865b71ea5089bd6303bfdfd19316\nS = ee4989c4b96bcc802464fe44b2adeb1b3506755a3f4fb3f9252bf21b\nInvalid =\n\nCurve = P-224\nX = 6d5bacf458cee3ded627d0ff14fd2aeb54fe1455d6daaf7bb43faeea\nY = caecc8d3967ca1c8889607e9ed975b8a335a17c0acbcfbfed721ee1c\nDigest = 328ab7d2a7c56d09cb72cedaacc23a6da46d5cf984dfdfd16af60964\nR = 80e7024bf30ecddf7a658785ae51cd6e5a23963c89ee96a82346d889\nS = 561252dc8d9280fc54da0046da494fa5e4b7aed213923e8b894a1ae3\nInvalid =\n\nCurve = P-224\nX = 7f9789c729355516588a5c75cb2cbcf85a14c35e14a5d03b4ef920d7\nY = 49e95c49e62dd20f02ed16594f35ebf3415ed50e6efdc0c548101a9d\nDigest = c5bb2d7ca9b37af1f4bb572ae6b6e69e8fcab9ac1cc5a6e1b6d1f8de\nR = 3c7b664413c2a0e4682a9d1c88243a96196fbd03f72cb873b9bee8b9\nS = 8f7f81ee9d3a2660ab1d666bac6cc434143ca9b04ff638ca7b4aa1ea\n\nCurve = P-224\nX = fd3efc7108edbe155adcd8686d8605e811fa79756c7e2dc8c1c04212\nY = 59edea73a4e5f91541fb4cabce539afffa85b6b0113289f049ce60a0\nDigest = 562d1a8fa642dd8bbb4f4801f2d9fc8cf3452be916c0ecd6c8ddc4fc\nR = 4907884b8b7d0eb9a7b24420f69c58e3a17314e101da0280c0ceb130\nS = f7629bed92e5c40f35d7731912fb45a3cee06eab3d409a62997f2282\nInvalid =\n\nCurve = P-224\nX = 8b3f3e31d9c8408a39997455ffe0240fe128a5f1be9b3a33a97b0910\nY = d74ac6ad8de2407887c335bd66f684454dee175a2af713bb334cb3fe\nDigest = b57ffce01c72221c6714e4a38c76746c45a8cc685f37c55a69f6773f\nR = d28ae763c22f50ae9ee9fbe5bab682fd8d820b99ab70677cc46624f7\nS = d9fa54d0300a6ac74936e7a47fbacadcbb4b25ae3a5b550aaf53991f\nInvalid =\n\nCurve = P-224\nX = f4fd02f3d224727e156a2cd7543483f3e35eb65219e32c7923f93ecf\nY = e7aa734828ef326259f98e0e8c3f30b62bd3295c6d1af2c429a087f6\nDigest = 8e70efc206d69d1bd1dce263a29a56030ad5602046bc61848899474d\nR = 9f57e28f69d2ebd96f6d98903156a4e795730e09fb67963771b0a851\nS = 8cfe716488479e04500c8eccdc86fdd54ff00258639f7177169e2030\nInvalid =\n\nCurve = P-224\nX = 0fdb8faf52d8f46229cca1e0f22e869a91bd56eb6dccc547151f9c68\nY = 96c8d1946528bdd2c14c3a0a9c17a088d3f0599752d095ba9de9ffa6\nDigest = db452771046d4b64ba673771b49df905881df9c4b6a1292a11f87515\nR = c53c0ce7d408278552a5fe5854c05641cbe93b1dc18eff1c68af53c1\nS = be7453a12693ce7812fe58746323882bc14eff972480b49431cb10b3\nInvalid =\n\nCurve = P-224\nX = 240431da69703b32ba2ae501d2458b355b66170725806b45996db195\nY = 13beb5198ee00abdcfb2cc5454416d4f7c795e97a14bd93cec3f0a56\nDigest = 3598d7d7b2cd9e482fd3bbebb9ae4549a4b452c81b89f3da6f6f2e85\nR = ad03bdf64e3450407a2a977e1985853d6ea41568c3a394d696de6739\nS = 7b55db9abf2045e2dc7ccfa2e8fb501883c494662d400590c74d100f\nInvalid =\n\nCurve = P-224\nX = 8c80c86f91b1e330f86f5177fdba839e625a27e8531f232efb10a484\nY = a24deab897", "8dfe7398f7a1da0633ff7cf5aa7b7365ce2d840ce81c80\nDigest = 44603667b2251cf051cd67b927714d67a25295679d884c4b79099a80\nR = 0c422b292308f31af78b1261d12765cced1cf96a83a6bc3bd90330fc\nS = db34f4462d0bb1927cc99273dc92d3fe654c85a3b53c6d74ed900621\nInvalid =\n\nCurve = P-224\nX = 3a5d1b7ee6749630c9619789b256f6bad5bc4b09950cd53b78d5ef30\nY = e85c7ee707df680eeb5fd78451f7302ae653f96721443826096f62a3\nDigest = 2ed9e7077df2ca2f8a96dfea2127b1b34147fcf963f9d73e8aff9df6\nR = 671ad280609364b0e26c92b13891f677db7c83499d0a3d7b6d80affa\nS = 7c4b9c5a3937d540ed8bd59e340c13f02313445e06b2bf7525f5726a\nInvalid =\n\nCurve = P-224\nX = 350f59509abc9f7f9b35a8b80065258727a8ffc27e6dac635ed68900\nY = 634fceae493b200cc7680297fd940dd86a5111da14bed68c797ef254\nDigest = 012a6edb0064f2b734b0297ab924efcb0e653be9e6ae97c371d59680\nR = 13a302b200555a0e80584e6ede32c0f9c5a199125b219c3e8d0fbf96\nS = 13f1d7b0c87acea6290cd9d36f1820f546f83dd8d7d9abe9da5812a9\nInvalid =\n\nCurve = P-224\nX = 1fdb820003a2fe61deef2b68b92ac711abc76200c534ec3abc99a187\nY = 32f87d0554b6b5e389311fd3c86825fcd42654a0b6f5d4d5ba73031b\nDigest = 2afe40d5042eb4020b14053e9ead6774d566e0b536912b7de4450090\nR = c03e551abcb12eadbc291b2d5fdd53bf725b785933e0766969f0355e\nS = 94826a8753cb949e0199be3220b4f90318f1c835cdd67efc50df7fbd\n\nCurve = P-224\nX = 208dcc6c87e7c38bd914bc9b350602ff62ac62fa4fd633c1af5b8cd7\nY = 0263587c7692c8be1f78de88ed6dc99ce1198ecc53a77ae6cf98a323\nDigest = 3f95e73294defecfc125a2dbbf322d31f323c030adf244c07a7c8746\nR = c12d3b396e1a894dfe4a28971ce4983547596879956504e1a3aed75c\nS = 067b729ca23be6cd520fbe9b972b9bb3d00c9ee96832a5c35e20e0e0\nInvalid =\n\nCurve = P-224\nX = a66a652fa36413dccd72c83febedda051182dc5758a1466366197f5f\nY = dc813a79e0fc647d8892dcf4f2132c90914a520cbbad65f458ee0fae\nDigest = 8a8942761ccd4ac7c88c4afcb6bc69d431cc3d10e6ad7a2b8610892f\nR = 809d1b4557eaf36b6eab3449dad56e61d572bd8b63d51b63af1b0bc6\nS = 8bf88226a463606ab57c27ed78f1b71ccd61732fa58b62ee845fd3dd\nInvalid =\n\nCurve = P-224\nX = 8856fb8b81a4eacd971a954560018f33cbb71cc1fc243d03f63cabcb\nY = 28afa26baf31b4d89de1dadd2289006f836f23a11383817ec7e4e799\nDigest = d8454640ad1f4632cc667823418ae56c62028825d727adfc84afdb0842b0c9a4\nR = efccef331805e71bbf876cbbc2342a6bc4508aea7c691029c8396aef\nS = bed544d09e28dbf01a30b2cfb61b98ad6201a9818f22b4f543f3e7f5\nInvalid =\n\nCurve = P-224\nX = 34c5ff3de565b85bfdd9f0a8b3fb0d46f924c57b276bcc830a1ed580\nY = 609d22200ef38b410da77f7a8ff2f58448188042978fd9ae1b2b4477\nDigest = 831979405db4eb9dadf01249fa15f68d4846e0ece70a320d3022f75f3dc281cc\nR = f0138024fe0516738f3bd0e0fec10defaca8c3b89c161a77489cf2b7\nS = 4ae0934266d9e3d64c2a12f546b132ba0f33ef50abc90e7ef5974805\n\nCurve = P-224\nX = 465afb14f4bf85022ac1f635f46c0b2f6548bace9352d32f74eab012\nY = 036371a3246dbf1069d2d268ca431553d1f2bf0181225145881b7be0\nDigest = 489cd3c10d94f7f284bc4ea472634a5d7f0d280d5abbf139c110ef80c8bf463f\nR = 9bcd57a2fec2518903e4b13dc0a7b84bafed5c4908546e94ffae87ed\nS = a337e06582f6b3973df38b93a0fb2a63f7774b62db50dba557e5cfcc\nInvalid =\n\nCurve = P-224\nX = b8b7f923c05ec95ebd484db7c58d219cfd26ee6b66149631f25ffe4c\nY = 6bda5f4f988784555a80b5494eca51ad2c7f88ce94d2090ee0c76fba\nDigest = b100feed0121d9d0471e5bd94a659510c2f84e313f476431deac17ca6d87bd79\nR = ce4d86bf5a7543d1cba8e4470a297e9a48d0096d7788c6284b1c0af3\nS = 229eb0636ee62508ce3719396d7577ed892cec70a66857fdee0d1fa0\nInvalid =\n\nCurve = P-224\nX = 13e84ec2eb993818d7d78330855ee2fbe8ddb548a5e4198e2087b3b2\nY = c95dff249e10c506fb547a92ade53c61ddbb667c760e4127a1a7f806\nDigest = 21a9f65d4cdcc287e0bf330e4f76f1168d16d0cea796dd6c0e13cd2837decaf1\nR = ed26f00ed696e114305c546ed04db5fc35efa43059c0d8bbcd418d0c\nS = 6e16efbe9501e3055d74966a49232cd76b5d1241468788b4cc7378b4\nInvalid =\n\nCurve = P-224\nX = 16c23c93699cf665a5da8b2d4baa72c36158d3433b1b945e47204b0d\nY = 12023703e1b59ec9054ff22d15567b9f74058b47cc13f2ca08ab77c1\nDigest = d62496d0ee0453e7f13f8d9c57adcd33442a5365f626381ed665f95f528aa198\nR = ada849b673a1bd2949a8b4d8fdfc239ec53524a356d37da3c9d17ae2\nS = 698de3a3d8697c2e8e5b2c85fceb8796750c5b44154f01ce86d99e24\nInvalid =\n\nCurve = P-224\nX = a580f9a0cd15abff8e1e712f16b0fd4142d0d773af3c657abc06c2a6\nY = 22c6286340dc072e64274209eda60503047700571caee64b4a2306c2\nDigest = 25ef291dd6a2047ea193f8aedd3f4692f2c135cb519922a17cba3e969423b030\nR = c6fae06274dc052e482102520b49d4ccc4cb7eb8a3ea41bd3680ddad\nS = 50d66b75a2bbd0468be1f9e61bfda85b6329505b0134d60846cbe4b7\n\nCurve = P-224\nX = 0b4fb6fe5f6cf6adc7d28683628d4b9c569d21d2397533f5bd121a23\nY = b44d60a3414b9b7b6e4ad735ce2f9cb05593b0874ada5e65acdead4c\nDigest = 7d53ebba0424c4b6731806407f97af4af863a5a87c759626830c9e8753ca50fe\nR = ab5ac2039b49690c6436793decb1a6a58ac34833a8091005312a93a7\nS = 98fe955cd836501cef78c7a05fa27edf2fb3afea80990028ff64e984\nInvalid =\n\nCurve = P-224\nX = bae2b3634c7854c932551ece8dced2139a51705059503881a9239c78\nY = 094d5e455bc9296202618d7022512b0f9ce53d796c7294e6eb076a29\nDigest = bb5c0917ec5376b2c685f3a530a9f8ef1ef1c1b398ab66f479d936cd662efc1b\nR = 2fbdc7e9e98aed5dbbcc5b034e17a95209e2fe1b01515426b8b372c3\nS = f2b19226528f10be6ef0d27ec3703db690261206b7e42f93a691192e\nInvalid =\n\nCurve = P-224\nX = 49d9ff4f4bbd4320b6806a7fbaaedd962283c766a6c130e4b62139dc\nY = 06dbe8e7fb8fccf9758101ae46939c6fd4d3afc526ba6c8156c6b013\nDigest = 9a113d3d73543e17faba847981e0b7fbc5647e547bfc989921ddc987133692d1\nR = 2d83aa59bcfc8a0237884826e08dbd78a56733598e379f2a9d51e9e2\nS = 485036c74618d0e665775fbe2d614a313c550f9826b955d3e5636fd1\nInvalid =\n\nCurve = P-224\nX = 78451cca49655978b65d8ddd45ff367c47f321f5d55ddac7969ab82b\nY = 25b77f820aa9ec93ec89d7fc84285f3f3deed496e0cd3fb9ee4a5c99\nDigest = 352afd36279bee1ef5727c55c7428bb79db949a9f1953eb98cfd38c4a4a458af\nR = 998789490e008ed11febdfe2981a55c733eb9739d7f37fd5c2a7ec96\nS = c3ec8afade81860ff23cc1e7d759d32d9a5775886ef17bfb719df4aa\nInvalid =\n\nCurve = P-224\nX = 18ced60b7fd9ebf76c3aa5976dcbdef40bd3e36033c013553043dd84\nY = 30398582dbd2004064f8055e7fe0fe8df11b2c9d9e2931ad12d09628\nDigest = a1e3668af6307f6a2b7414079e73308ee0836b588b92a48bd5baa9a62f45b0f8\nR = f880143960e812464810c175001b5d39592fe63aab544deb9ca301a0\nS = 1e0657df071a25dd791264b411c8964688f4fe17ce024e659836ebe1\nInvalid =\n\nCurve = P-224\nX = 5d67c1fca848ba7f3d9de5b1894d3993ac4ebe68cdb0b49553b3b0e9\nY = 07c219a8323273c81f5694306d0dd1d133a49efce5003bc90f05578f\nDigest = e8f714f901cd2390c66f9fa9cb81ecc5f17a82bd934cf19c5ce2bcbd3a985de9\nR = 767cb6b2efa7a40739830659b0cc24fe3de771d00104b3dcc0f640bc\nS = f2e7268bc011d79d33f3551d2edd3c95f324955479b8e29e8aba629b\n\nCurve = P-224\nX = eac72b399cb791b3ed25cb0a49eb157e69603197e0327eac5448680d\nY = bdab3a2270066e74e8210eed7b5d43fba1e26845b6c037a8a7e2a13b\nDigest = 74aa7c8f25644514582fa904cea1ea88a0b262ffca43cdf6536ad97d8550616e\nR = 55485947e9e3c194a29c8ecaddb18eefd16fb6919aeb0bbbd8c12369\nS = 6309a2cc7fdd9eccb32b86d5577aa54ada79899a9645f2e299630d31\nInvalid =\n\nCurve = P-224\nX = 17f741267bf3e8143046707d41eafc9555953fe5f57d6c035452b232\nY = c667554d9a55fc8ab1062203dcbcd2bf9769c696a295350cb28aa01a\nDigest = 3b997a1c220593cab4301e07886db745436911b8abfd9d1b03cc12e1c7fa4510\nR = 57408bfcc68e60ad000eddbfe6eccbe5f87b98c95de0e0a2e065da92\nS = 51249bddc149f0942be001b2f3d6f6d17a0cc36fefce147058944667\nInvalid =\n\nCurve = P-224\nX = 3297edac34cb802df263f8d366f62a8b746c316adfb1c84a1c79c58c\nY = 79fe82e87ef5879c12eda6adda198a662fd77afa6a1fb5696cb7da9d\nDigest = e71dc3ab7ce73995d053bc6361bbb3f20e39ec2f295d97fa2bd229ed31a56dde6bf2c9cf6b0a9cc7e65962c57f3662a3\nR = 9993defdcf83965723c03e04ce6c33b3972cef3c449cdf1bc69990db\nS = 553b22a4164549f16aa1a928eee74548fc141fd3c16f213318965974\n\nCurve = P-224\nX = 2bc010527ea7427cedd213aeccf0c62dc513785888c6373740139d8b\nY = 2e9eb7ddf027ff7678ca880511be147098b34d8e77acb4389fbc6e50\nDigest = 781195b6396344146fe8b73a2526b4b1c981d26b9adcce0123176be1239f798c847495fd714661d1ba8e41f2ccfd052b\nR = 70a7cb04295a53b4a3a695ccb5d87856fe9152fce11987d4c43207bd\nS = 49f4094368f2de9327ca2913ef940e17c5801e8f589413838831083f\nInvalid =\n\nCurve = P-224\nX = 55c6217adbefff6e21bfb5d1b75213ce7b20c900d514ee094f27ad0d\nY = a68ae9f86eb9c10de3e7d9b03868518f33f571f85c3529d2902575d3\nDigest = a318b24bbb5ba46e6656f8ad68201c024e7b3b3849d6a70f3abce8c20f5b98ae43a326f5f48994045f0ff27098837b5b\nR = c073fba87267b45853e693910c1de791908ca7a25c1716ec2d3cec71\nS = 6138c86daf1021ae4af0faaf0abd5958f93944d5b0d82c40214bacca\nInvalid =\n\nCurve = P-224\nX = 4d0cab0dae88fa0cf53a2a6562934e0cf", "0271cc7fe54a30109a232be\nY = 70835833cf9e1f989a18d419e7bee9eb5cef1fd145cf62c4411c372c\nDigest = 6abbf2557f2e9b4e020126f4a87fb0262a1ec59bd3b569581048c5692f8a1cd381ee9c3cf195fa1a362a87ab604d79b3\nR = 3b8548eab4dc123e236133d826f2badbde96f92249f456e33ccc9739\nS = c82b2e41b9e2b21594cc03b1c0de216f183403c6025e18bb29bff421\n\nCurve = P-224\nX = f55a53b818b3ec4b4402a2c63429c1d78f2cd0d8d202e33812878a03\nY = 5a2b1a00615c56b4313828bd70526b12f402df1d40fa4900c994af8b\nDigest = da8d2571bea9840494a41f03c6c357410de030a7b5c023a0487020bb5b7c45fb6c5ed0e3dc66e4c0ab8460d9bda68c94\nR = fa934f9fdb765fabb5693ccb1de4177f172a8de108805a48f4bb989c\nS = 12994f2a26252742667044a01b509b0f315e8141629f760267b850e1\nInvalid =\n\nCurve = P-224\nX = 40a5c52dda7de858a2c17d12856c552ab820023336b9b4fc196bcd67\nY = 301e5368f59c00f15e6f3a91510444fb75a4ead8efb0778b4419e7db\nDigest = 0f88ea2d9dd40c19cd31c7a7cff71379431c9dc0a3092041a5fcbd2c20a05a8cb6e5a8aa143f1dfa169d2eaf87d01e26\nR = 0fd8773fac425a2761b954c946020615336d3e350ae40743641917fe\nS = d59f2b806ccecc444f9387f511c7f9926fe7f045c0ea633a51b7db47\nInvalid =\n\nCurve = P-224\nX = 372a134eec0dae3322de8836b89dde11a69e0379a60b10343abd478c\nY = 65921970ca8cf5a75f044db0e29802afe1726d18b3e07b61c768c242\nDigest = 1547d49d33566f8c05f68b9a980e113f919bbdef8d6d53046456a2c2ebe27ad86eaa52d05677fadd5ccc3e84b04c0f94\nR = be6474845a42fd4e85b91238f1e3ba11cc88e216d295c1b07d855987\nS = 2724242ffb5775f614ee06eaa4c985358f64869ce4ae4bfb16b5271d\nInvalid =\n\nCurve = P-224\nX = 9ad2cee0d92b00b11157a18fcd752f43e772ede7a46475a50e7ad8d2\nY = a6edfae6c5589dc0db6353b8655fe3b0f7dab2aa8400cbbd72d1a572\nDigest = 60942be3ff8d2370481b04fa07743482e08a61d3724010d7edd49bcf12e1463ae059696c825ac0505f079625b95310a1\nR = c31a40b6c245572457a19efac0da0db22b2a0818de716b6fdc5bdb32\nS = ed8204de94f1d92ae3fa6e10c727eea38d0e12b58133fda1a15559bb\nInvalid =\n\nCurve = P-224\nX = ed071a20d76f81c776875f8d3307841d33b70523ea40abd691d55d21\nY = 34ca47d8ba0a984d0d728c4d8c6b9aacdded03c6070616680aac162c\nDigest = e0776a80c616b8e596bacb0391a19956b2f0e2c566c50dd2ba99f9e59ff3dfa6197622c2a64cb4d02780a39c68d249e0\nR = c7a5dce4733a81bd738e0a6e0667dc1fade86db119e7f3cde57d6dc6\nS = dfb7f43343941cce331be27047b131617910f68393630fa53d137df4\nInvalid =\n\nCurve = P-224\nX = f51097e1e4b4f3b32e92fded0b4c8b7240a62731292e615a4cae0dcf\nY = 0549003f18e67076bc68110a75252072fc29b6d4a336d152dac2c3d1\nDigest = 48803bce00fe101650dcc83b290c49a524b21422f1f6a3aaa6e2f201863ffc355346d167dcb0ac552007a46cf8d6e4ad\nR = 6875a118dbf586a51af2212d5f32908c9f31110e9e9a7e4cdf7494c5\nS = 1542ab4260459e82070bbad405193a1894ce717af158daf1d096bc01\nInvalid =\n\nCurve = P-224\nX = 5255e4fdc816044389e9c6f5e09b85aedbe1c85b1cf9b7190ef7c2cc\nY = 683c8cb6f31e4cc1e2a5361eb47e305d5d8bfeaf94e261a341aedde6\nDigest = 995229c018cd0ea061672c46ec30c99693fff1cad491b13b4093df0154872adf946644dee6192657b436931c30b7af9d\nR = f1b0f8a3fbf7d4de19cc1d3b4c525c31bd97c2e2a94eb8a27c7c197d\nS = 936d3f49a9aa58935cfe227b22db83314ffadcc4751c8e26853d8cd0\nInvalid =\n\nCurve = P-224\nX = 7cdaf519f6b1254cb8da4668a2dd2015857ceec17f838c15d7d34b27\nY = e29f80fa4f830af7737126d4454b6498905e2c633fa61ad6acb30823\nDigest = c7d8d1f060287ec402092be54ca6e06895e91f9d0c29010124c0d9bd54007d8039b7328ec7b3a29e1d5d4d8fb78807e4\nR = e640f3e676a11007e73efd00b23087adefc9b9407ae8b79b47c397f3\nS = 66b7860a0ca35c2f1c65d50f99def9f2bfc0a6cad2008dcc38d6b3d7\nInvalid =\n\nCurve = P-224\nX = ca1a04f08708ae714b7dfb3db509970d30b7e01be7fd6181613894a7\nY = 1d90a2fcda7dd6ce8b207eef48340e58cd439a3ce17658f6f82be778\nDigest = 1f710f925826bc33c0da91798cb7d7d0700883da685a1fb9503179f0a06b589bf92eb4b67496faf21cd74c8e3d560d77\nR = 9e810ec2a0bc205df6a75bd6410e0c8ea1c738e71af060e2eb271aa6\nS = 9d05eeb46258c468b0398cb6e421149bbea5ed936be3fde3380111cb\nInvalid =\n\nCurve = P-224\nX = 558c323d8259e055a025fbbe6ba8b525b02f32caddfd31e5b08219d4\nY = e1d6398b1c47132632cd3f3fae14fc3ee3092faa619074fd951a5870\nDigest = 4b662138833a976051b20ddfb02e67339715b77046bedeb1e30b9dccbcd84204e76da722bb3bd020fbbe33a182792e0f\nR = 05d8b0bcedf287a4740bfc548570b1c1fff71058e0a9d88476bbb6a1\nS = 769321d50e34939e622a727855501e25a7ad44ec979985e7389aa3f9\nInvalid =\n\nCurve = P-224\nX = 9237e61ad9ffafc61cc1c72b6d2f96d69b588c8feee4074359f694f7\nY = db25a18f1eee72734c640313f5c6c0441358611406cc62619113b4ba\nDigest = 4e7bbf78843a767536977b240e9d1516c73c0fa19bc91448280fd85361b06fdd11ee413f956ca4ea3d67c0e325a1d53a\nR = a58225b10080dab26644f10d8a817ffc4ed4535011729491b6ad5d00\nS = ddbc010e295882e0731ff240f15ed82fa3e81b7552c690cc5b40be03\n\nCurve = P-224\nX = ea7efb9a7e7bf693dc0249504ead70dd422ec86806cd649ed57a7ffe\nY = 33dfb17b1cb244279990019286ab477a2aff2b55c08959deed0b1a28\nDigest = 330f78db9f217f95d99cbcb5414a32523025b85c87ed5aaa3a5e6b006c53cecbbd446166bb9b98e944626332c3266e82356e72110bdbf7df2431b8e7faf59e45\nR = deab574de1f971419b7ba9e169866c3a6233fc627c13dc6a8cb88bdc\nS = 8d4c542bb0046da1b3912652a2c84542668cd89920808785d04e4352\nInvalid =\n\nCurve = P-224\nX = 6fce4d789b1240f2ab1c23051aa03e219da99943a18864e7876d4d11\nY = 3e84a6bddea4a28cf8151ae73aa7b1964c37e654241353a9fa723f67\nDigest = 0088e4cbf3eddb6eaf108fd3937c439684ff8fe5595f2032948423a2a15811b34b0def245bed3b4b4ca90d3f497f3aaa2577a7154d22d7254dfc4755eb9b7b17\nR = 2d1b4f1ccaebc0a929598b650ee364abfd6091a542ba426886d75f38\nS = 44f3d7afe84ae33ab5f9426dfc85248ebc7e0df434d35980ddec75e0\nInvalid =\n\nCurve = P-224\nX = 72013dd6f5b1eb709b3b7da234987f9a36c6f0b095620b8c31f02381\nY = 319d54c719b59d91900b3c20d963ddf1a10d80d6601ac155094b075a\nDigest = 3cba2980faf5579c7ddbeb31c3318a162a882129a1efe1fc9acc3219a617c460701f22fd7a5c46b017bd9ec9c40587127319ea14b148d2be4df9875d5bef6e4e\nR = eb38db9b757b3cf04020f09188c789bf0258cd0467cf7d67368e8703\nS = 7664e85f01e67881712b24083f89e838c8b818de4d665494e7016833\nInvalid =\n\nCurve = P-224\nX = c6a65011926eb64e02bf472d5ba37841d49cfb7f17a20fb9f59355de\nY = 386ccb33d944fd7be6b8531863d2b6200cd602d300d7e7681537e53f\nDigest = eaa81b1236121db12f2036611eb6d3e5386f5733125fb26844cb4188109aae402525fc63bcd73494c36c170d1934b108739d79b0c4f184bd85ffce93b1beecde\nR = 9e7c637a699dd52512faea847079f0ad41b20cd7a5461c36d01e857e\nS = dec6e9ef361de3f6ec7d87de3129eaac5fd0b43b5f7f58ce46c29173\n\nCurve = P-224\nX = 5bcdbaeb2f6c57e8a9dffe94804e74daaf9db8452d13c6a8bc2a4966\nY = a564072356c5d86200e979291a19d5e73d8bcb701cf84d9012824bf6\nDigest = 4a5de84f304f0c83365ae4213fee71c0944d8580f9d8e7455fc961e9f98bf3d51b7fc20aa44e36c0bdaa09e365767742e9bd8bc868d5c6cd8e1cd2ce2968e3dc\nR = c58436fb77aaa4468dee284e1220141ce9ff4426f75daadf5a898a6f\nS = 87aeee1229a50921d8e77e7e3478061f5c051097defb104a0455ed81\nInvalid =\n\nCurve = P-224\nX = 6c6a7deef8b3dee2eaa98d8ec877dddb460365968e63ffe5c249a421\nY = 1ad1715797b5e47c4be24d7ecb8141f1772344a2f643cc66fbcf3f9d\nDigest = f59946dd73887a1fb945ae3e5b44b574512e36dd7d35925b0bdc3a3f69a88e50dc6ebaaac86092679961a99d7ba5724363c5886e7c2cd566433c5a9d59e2515d\nR = f778faa2dc2cee7de2af0bbc4339239dc240907e59ac034464ce986b\nS = 2ac929588a8dc8785808c9d4366bd7b1a81e0fc5be0c63e62344c251\nInvalid =\n\nCurve = P-224\nX = 0ee33a134feae6ee1488bf10edf7cf7c318a2d709080a24818619b91\nY = d7d39536e42652baf55159847f475ded075385a3c1af5c3dcb17ee6a\nDigest = 00fc4992514c1053eee7facc5199161a2b0f69dad2770326371ba42c2c12ffdb4ff6bd86fc440dc8dc1354dad42ff0c2a055b61137532a62521b0f3508ebe611\nR = 34bd0407f80cb6fc759036e6d4522eb6da94874c92ce0f02d8f5f2ad\nS = 3a2dd970050ff990162e5702b06905d03e3c7bb2771050de6d84eece\nInvalid =\n\nCurve = P-224\nX = 31d3c62a4305c37a15e9102072e287a8e0ac027f9189cb9d87ecbea2\nY = 26449ca391af6a2a9f8daaa036f2c9044b336773ee48bcbd9cad59f0\nDigest = dfafbf96b70ead7e91dbf48b8efd062bf2bc0aac6d3e90a7fdf61aac13a74b304bcd0d0c23c88df269d45bdd31d50f0fccfc0324698af4dbcffef04ca05a119e\nR = dc33e8f7b52f584aa3f091aba10c2a9a23be6835e1551092652e1bbc\nS = ae84a6d19f6bad3f9886930c0a1406016fae813673db1516b31b638c\nInvalid =\n\nCurve = P-224\nX = a6e4470712df583d0c795237ff46c9df5718ba2aa24139a2d99721b4\nY = 9edb403a8c10807e8736af665dbcf6052bd4b43bcdc8b9eb8d4394fd\nDigest = 36cd6716cbb8b7f96df4617143be7b74f42bc94e468e79e6658d00b092e24d6de82f207693427fb439dd13bcf49665cac343ea35a79b5963cb21273094ce28fd\nR = 4e9ba5bc4f4fc4e507c1e5cbd0d688da4237385b16ff06601436d8ab\nS = 4e0450a57d802d0ea7b0fb57eb162267195bc4248a831a0ee8b0380d\nInvalid =\n\nCurve = P-224\nX = 350fa782e1cf7254b18cde30683e54edf2c1b4782525fd081bed5920\nY = a77de5b4139ff63e108b6fbd3a7e6c0", @@ -2627,15 +2732,15 @@ static const char *kData45[] = { "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\nS = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\nInvalid =\n\n# r = 3, x = n+3 is the smallest x with a reduction.\nCurve = P-256\nX = ce24c99032d52ac6ead23c0ae3ec68ef41e51a281fd457808c83136d7dcce90e\nY = 8f7a154b551e9f39c59279357aa491b2a62bdebc2bb78613883fc72936c057e0\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 0000000000000000000000000000000000000000000000000000000000000003\nS = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\n\n# r = 4, x = n+3 is incorrect.\nCurve = P-256\nX = ce24c99032d52ac6ead23c0ae3ec68ef41e51a281fd457808c83136d7dcce90e\nY = 8f7a154b551e9f39c59279357aa491b2a62bdebc2bb78613883fc72936c057e0\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 0000000000000000000000000000000000000000000000000000000000000004\nS = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\nInvalid =\n\n# r = p-3-n, x = p-3 is the largest valid x.\nCurve = P-256\nX = 768a0d300a595005a520130e50927d403395c8e1e40be997b48fc048410f7cdb\nY = 16f217d8e1c02bd887e5de388a17783b182e61b5d534152dc2c4be8d75fdd706\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 000000000000000000000000000000004319055358e8617b0c46353d039cdaab\nS = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\n\n# r = p-n+5, x = 5 is incorrect. r is too large to compare r+n with x.\nCurve = P-256\nX = 0ec505bc19b14a43e05678cccf07a443d3e871a2e19b68a4da91859a0650f324\nY = 77300e4f64e9982d94dff5d294428bb37cc9be66117cae9c389d2d495f68b987\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 000000000000000000000000000000004319055358e8617b0c46353d039cdab3\nS = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e\nInvalid =\n\n# r = 2, x = 2 is valid.\nCurve = P-384\nX = 016d2db67561bc126ad6c344d6eeb2713a9e2892c649af0f015c6b7617f160c8a3b3a88add669d7155025073c5ac5b4f\nY = 43bf2ed0088af08645c80aa0a24a567a94ba2d794e9689d3ad4b185bc5d2dd008333e2dd2ebb5069a9b32251a3cac71e\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\n\n# r = 2 + n, x = 2 is invalid. r must already be reduced.\nCurve = P-384\nX = 016d2db67561bc126ad6c344d6eeb2713a9e2892c649af0f015c6b7617f160c8a3b3a88add669d7155025073c5ac5b4f\nY = 43bf2ed0088af08645c80aa0a24a567a94ba2d794e9689d3ad4b185bc5d2dd008333e2dd2ebb5069a9b32251a3cac71e\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52975\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\nInvalid =\n\n# r = n-1, x = n-1 is the largest x without a reduction.\nCurve = P-384\nX = b5b375264c09acf145ca91d12ab10a096092a41ec43f4d718e129ea1c12b2dea62c7785efc52f46f009fb1dba133e811\nY = bc0b2af172b4b3068d032a798080e76f4d56f72069519e3c19a43682a41794e52cb3ca139348d6bbc923e6a4f7945cb1\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\n\n# r = n-2, x = n-1 is incorrect.\nCurve = P-384\nX = b5b375264c09acf145ca91d12ab10a096092a41ec43f4d718e129ea1c12b2dea62c7785efc52f46f009fb1dba133e811\nY = bc0b2af172b4b3068d032a798080e76f4d56f72069519e3c19a43682a41794e52cb3ca139348d6bbc923e6a4f7945cb1\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52971\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\nInvalid =\n\n# r = 2, x = n+2 is the smallest x with a reduction.\nCurve = P-384\nX = 01b54a697305092bac2939fb906d7471b411c4eba8654169166a5da3810e1fc96795df921f7abbf519be4a027435176c\nY = a19012a3518773d508106d4153adee43c3c384fa62ce36a4addea08f593ec9c76b09a6b9c69d29bd7d47eb48e167dd2f\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\n\n# r = 3, x = n+2 is incorrect.\nCurve = P-384\nX = 01b54a697305092bac2939fb906d7471b411c4eba8654169166a5da3810e1fc96795df921f7abbf519be4a027435176c\nY = a19012a3518773d508106d4153adee43c3c384fa62ce36a4addea08f593ec9c76b09a6b9c69d29bd7d47eb48e167dd2f\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\nInvalid =\n\n# r = p-1-n, x = p-1 is the largest valid x.\nCurve = P-384\nX = c4fd8e68006b83f7b7b20b731ae405813aa05f6e57374589b36ae1cecd1d49cae1418c22f398188bcf4ef02e89fe7394\nY = dd1164b3707f59e05129fa228b8448031db159985f035d93470dc42b3ab4129f0760c46cf201d42e73a7e33ba7402ea6\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = 000000000000000000000000000000000000000000000000389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68b\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\n\n# r = p-n+2, x = 2 is incorrect. r is too large to compare r+n with x.\nCurve = P-384\nX = 4e5e4f1a6e97059a6cf2f4e8129e5c7c64cb84f9994a41ff5bf30b29c1bf5ba6898627c91a23c73e05cd1a43c8f908c0\nY = 06a0aed7f1e63a728f87dbd5360a67571a076ab0b4cde81b10d499959814ddb3a8c7854b0bbfa87cc272f90bca2a2254\nDigest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e\nR = 000000000000000000000000000000000000000000000000389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68e\nS = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970\nInvalid =\n\n# r = 1, x = 1 is valid.\nCurve = P-521\nX = 00f07e0b593332d09ec4fd0bae93f648a3da04dd224faae3f64cc490ec8fce3a6fe53d1b2c9e326be076cafb921b7e3f8b2288db491819522d65472870668c3808c9\nY = 018e42509aca542a8de421589c38ba653e8cfd69322336217042a9dc0f67f6d7ae2cd4e385f480ffaf8981f715c7ca3765d9867dfd5a02947b0895f82eaf8b257e88\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\n\n# r = 1 + n, x = 1 is invalid. r must already be reduced.\nCurve = P-521\nX = 00f07e0b593332d09ec4fd0bae93f648a3da04dd224faae3f64cc490ec8fce3a6fe53d1b2c9e326be076cafb921b7e3f8b2288db491819522d65472870668c3808c9\nY = 018e42509aca542a8de421589c38ba653e8cfd69322336217042a9dc0f67f6d7ae2cd4e385f480ffaf8981f715c7ca3765d9867dfd5a02947b0895f82eaf8b257e88\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\nInvalid =\n\n# r = n-2, x = n-2 is the largest x without a reduction.\nCurve = P-521\nX = 002a61afb982e49f030dd4e6ba0e495703abe0442b1283ee693fffc1b558f49f0a4cb4f138ea0604e667958495b86c61f358dce7e7f170da47372be3e4168408a260\nY = 01baa19e8929fc8e7208e854e706a3d7f21479d1f6922a6", "5ae3490fd5f52ae6580513b1fdd5bee927d002a9608abbb925b6727bdc110a3145fc8622d1fa8154c82d8\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386407\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\n\n# r = n-3, x = n-2 is incorrect.\nCurve = P-521\nX = 002a61afb982e49f030dd4e6ba0e495703abe0442b1283ee693fffc1b558f49f0a4cb4f138ea0604e667958495b86c61f358dce7e7f170da47372be3e4168408a260\nY = 01baa19e8929fc8e7208e854e706a3d7f21479d1f6922a65ae3490fd5f52ae6580513b1fdd5bee927d002a9608abbb925b6727bdc110a3145fc8622d1fa8154c82d8\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\nInvalid =\n\n# r = 1, x = n+1 is the smallest x with a reduction.\nCurve = P-521\nX = 0049bbb2d3267a6eab2c59fac5b138b9e9c383db6637fcfe5d9f430e4c4c2ba0332340975448bd86c92a55c1a8288adf7f774096022419aa8c497499dafee7b93257\nY = 00bb52fd444ec497ce228135f2498d40fb84eb6f674df1245d3aaac3c75b55ff5fff8e90b6f0189a3132cb9fd8d6e74fda5866fe2b9fc7484c628fde97e0b00f2b67\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\n\n# r = 2, x = n+1 is incorrect.\nCurve = P-521\nX = 0049bbb2d3267a6eab2c59fac5b138b9e9c383db6637fcfe5d9f430e4c4c2ba0332340975448bd86c92a55c1a8288adf7f774096022419aa8c497499dafee7b93257\nY = 00bb52fd444ec497ce228135f2498d40fb84eb6f674df1245d3aaac3c75b55ff5fff8e90b6f0189a3132cb9fd8d6e74fda5866fe2b9fc7484c628fde97e0b00f2b67\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\nInvalid =\n\n# r = p-1-n, x = p-1 is the largest valid x.\nCurve = P-521\nX = 00f651d53d45bf6fd55a5f184e580d11259bc65200387dbc1bf7fb867d2d12a207d2962204ccf38e9d37d23ed95bd01ec576c457127766ecb8ad00342a476ea82078\nY = 0196caedf64fbaa9a12c16836e0564e36f733957375706edb5f32911991a994c2d6a1ea5db2ee764835a9d6aff379e195f722b48e8d2b60fc50de2a5160c77c3f06c\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 00000000000000000000000000000000000000000000000000000000000000000005ae79787c40d069948033feb708f65a2fc44a36477663b851449048e16ec79bf5\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\n\n# r = p-n+1, x = 1 is incorrect. r is too large to compare r+n with x.\nCurve = P-521\nX = 009eeb7f956230c3744ca5b683f413009363107aad18a027fa7af6ac07a699911e94143d3ef00c0062d4187c2ea74dc9322c05431a6b7fed51ee71b047ce3a0e967c\nY = 007d2c089a6720f7c7886ce8aa6aeb9b821adde0eb025ef63c62d37c32b2d6823c857ce7743b8181c35c8f34e6aeb4487dd693e01d69dfe883c07c25ebe89bdc4d56\nDigest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9\nR = 00000000000000000000000000000000000000000000000000000000000000000005ae79787c40d069948033feb708f65a2fc44a36477663b851449048e16ec79bf7\nS = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406\nInvalid =\n\n# Although we do not support secp160r1, all our built-in curves have p > n,\n# while n > p is reachable from custom curve logic. Moreover, p and n have\n# different word widths on 32-bit machines. We include some test vectors to\n# cover these cases.\n#\n# When n > p, the reduction mod n never occurs, but an optimized implementation,\n# working mod p, may incorrectly accept, e.g., r = p+4 instead of r = 4.\n\n# r = 4, x = 4 is valid.\nCurve = secp160r1\nX = 39891bd61138e775cd012518ff00f59ae01c4733\nY = 25026b77b1c44affb1592dcf711b4290e9404c9f\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 000000000000000000000000000000000000000004\nS = 0100000000000000000001f4c8f927aed3ca752254\n\n# r = 4 + n, x = 4 is invalid. r must already be reduced.\nCurve = secp160r1\nX = 39891bd61138e775cd012518ff00f59ae01c4733\nY = 25026b77b1c44affb1592dcf711b4290e9404c9f\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 0100000000000000000001f4c8f927aed3ca75225b\nS = 0100000000000000000001f4c8f927aed3ca752254\nInvalid =\n\n# r = p-3, x = p-3 are the largest valid values of x and r.\nCurve = secp160r1\nX = d88d902a0d8d942333c7b846a933d4794fcb5807\nY = d24c4f405689b86cd5c61fe104e6365d254d5222\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 00ffffffffffffffffffffffffffffffff7ffffffc\nS = 0100000000000000000001f4c8f927aed3ca752254\n\n# r = p-4, x = p-3 is incorrect.\nCurve = secp160r1\nX = d88d902a0d8d942333c7b846a933d4794fcb5807\nY = d24c4f405689b86cd5c61fe104e6365d254d5222\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 00ffffffffffffffffffffffffffffffff7ffffffb\nS = 0100000000000000000001f4c8f927aed3ca752254\nInvalid =\n\n# r = p+4, x = 4 is incorrect. They should be compared modulo the order, not p,\n# so r >= p is never valid.\nCurve = secp160r1\nX = d8add22064027856c162243ab09ea96642975297\nY = 8822a506712385ab3ebe5c61737c3bbb722b06b9\nDigest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b\nR = 00ffffffffffffffffffffffffffffffff80000003\nS = 0100000000000000000001f4c8f927aed3ca752254\nInvalid =\n", }; -static const size_t kLen46 = 9174; +static const size_t kLen56 = 9174; -static const char *kData46[] = { +static const char *kData56[] = { "Key = 00000000000000000000000000000000\nPlaintext = \nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = \nTag = 58e2fccefa7e3061367f1d57a4e7455a\n\nKey = 00000000000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = 0388dace60b6a392f328c2b971b2fe78\nTag = ab6e47d42cec13bdf53a67b21257bddf\n\nKey = feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nAdditionalData = \nNonce = cafebabefacedbaddecaf888\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985\nTag = 4d5c2af327cd64a62cf35abd2ba6fab4\n\nKey = feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbaddecaf888\nCiphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091\nTag = 5bc94fbc3221a5db94fae95ae7121a47\n\nKey = feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbad\nCiphertext = 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598\nTag = 3612d2e79e3b0785561be14aaca2fccb\n\nKey = feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nCiphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5\nTag = 619cc5aefffe0bfa462af43c1699d050\n\nKey = 000000000000000000000000000000000000000000000000\nPlaintext = \nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = \nTag = cd33b28ac773f74ba00ed1f312572435\n\nKey = 000000000000000000000000000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = 98e7247c07f0fe411c267e4384b0f600\nTag = 2ff58d80033927ab8ef4d4587514f0fb\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nAdditionalData = \nNonce = cafebabefacedbaddecaf888\nCiphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256\nTag = 9924a7c8587336bfb118024db8674a14\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbaddecaf888\nCiphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710\nTag = 2519498e80f1478f37ba55bd6d27618c\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbad\nCiphertext = 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7\nTag = 65dcc57fcf623a24094fcca40d3533f8\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbad\nCiphertext = 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7\nTag = 65dcc57fcf623a24094fcca40d3533f8\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nCiphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b\nTag = dcf566ff291c25bbb8568fc3d376a6d9\n\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext = \nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = \nTag = 530f8afbc74536b9a963b4f1c4cb738b\n\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nPlaintext = 00000000000000000000000000000000\nAdditionalData = \nNonce = 000000000000000000000000\nCiphertext = cea7403d4d606b6e074ec5d3baf39d18\nTag = d0d1c8a799996bf0265b98b5d48ab919\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255\nAdditionalData = \nNonce = cafebabefacedbaddecaf888\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nTag = b094dac5d93471bdec1a502270e3cc6c\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbaddecaf888\nCiphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662\nTag = 76fc6ece0f4e1768cddf8853bb2d551b\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = cafebabefacedbad\nCiphertext = c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f\nTag = 3a337dbf46a792c45e454913fe2ea8f2\n\nKey = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308\nPlaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39\nAdditionalData = feedfacedeadbeeffeedfacedeadbeefabaddad2\nNonce = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b\nCiphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f\nTag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a\n\nKey = 00000000000000000000000000000000\nPlaintext = \nAdditionalData = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad\nNonce = 000000000000000000000000\nCiphertext = \nTag = 5fea793a2d6f974d37e68e0cb8ff9492\n\nKey = 00000000000000000000000000000000\nPlaintext = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nAdditionalData = \n# This nonce results in 0xfff in counter LSB.\nNonce = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nCiphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c\nTag = 8b307f6b33286d0ab026a9ed3fe1e85f\n", }; -static const size_t kLen47 = 157331; +static const size_t kLen57 = 157331; -static const char *kData47[] = { +static const char *kData57[] = { "# These test vectors were taken from NIST's CAVP tests for CTR-DRBG.\n# Specifically those for AES-256 with no derivation function.\n\nEntropyInput = e4bc23c5089a19d86f4119cb3fa08c0a4991e0a1def17e101e4c14d9c323460a7c2fb58e0b086c6c57b55f56cae25bad\nPersonalizationString =\nEntropyInputReseed = fd85a836bba85019881e8c6bad23c9061adc75477659acaea8e4a01dfe07a1832dad1c136f59d70f8653a5dc118663d6\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = b2cb8905c05e5950ca31895096be29ea3d5a3b82b269495554eb80fe07de43e193b9e7c3ece73b80e062b1c1f68202fbb1c52a040ea2478864295282234aaada\n\nEntropyInput = edfdb55e77d418a63e4414dfd42225ed257cf74e99325fba26e8f3a4524a71bc80a731af23256908cb4675a9c253ea6f\nPersonalizationString =\nEntropyInputReseed = a9372fea93d607fbbc75a97b7f65f2d4ae8c06bd184981572e888a35c5794d2bb380a4ae04bba27f2efcc9e7914b96dc\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 11b1a0f0bb935ec0c54e089e0cd20832d1f00e7069f30e9ea2e35b7f15ecf0577d0e90035bf0f91ffd9e8a1fa8a507503739afbec19393e02c9b7c230cdea36f\n\nEntropyInput = f253fd442b105434c0f47ba9b6798bc20c8832a142a2a6d965678485a3ac52393528a5e092341d60ad74429f4005f8bb\nPersonalizationString =\nEntropyInputReseed = 600c822b198dbdcd9d13ee25bd4b846e5d8665725eac5347b4cfe7512c1f3fbdc4c51c85d977ca58e9e6485a17c533bb\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 076419bdd354d6a1f1415a0a71bed94db29cad22f0205d983c841874497875a4857404e573545366850fe6eb5286e0deb87ddd63bb3317b4556a82920412aeef\n\nEntropyInput = 8dbf2c37dbbf3862f05af4b32e98edd3d8cd7bd34d8a23daa2d15200daed6e9d238387ba85ddfd35a2986bdf5790e1a7\nPersonalizationString =\nEntropyInputReseed = f67aed05dea08baa16cbb669ae310a0b8e019da0a7fe2762abf684121292186a50bc13d568576ce5d7aeb080e4604a1e\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 69666e65c5623140da35927ec39189fcfda0891674efdcd2a7d6f2628921a37bd49a164590413c04f6090a50336f040b015dd8c45452991bcdd96994c5ecc6bd\n\nEntropyInput = 2fac25dcea5274a7dbd6af112d757b59a4447f5dcbda972666af071c5d8f71583ec6914a1e685f610b8a43ffada0b411\nPersonalizationString =\nEntropyInputReseed = 52f5b1f927c0873ae375d6a6e140fe594fd474a63bcdcd6a98109e32ad980ce534714ec626dad7acd43101415e5817d2\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 3096cf20137eb6f94d9d26a4871eddf10285c6984776847105ca9294aafc68925ad8bd7f36bb68fe371476114649ead11b926f9f0fc1d21c744342ff5c44c8e3\n\nEntropyInput = 4133a0e6ce837125f46f2a44e05c4f64d76879156ea16a1d16db1d3ec460cc53609fa9e4b3081f9dde0b79f00c93ac5a\nPersonalizationString =\nEntropyInputReseed = 4613b2327dc9054f34faf933d62bf7b12ec8b34626c07ef7512cecd8aedcbd4023f26b859a941c5af77ec1e2e02a1d9c\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = be02e94fd18c488741fd90b6980118dffba1cda5bd25aa23d44414392201c5a78c3ea68252f92afaaf540b298d3f80a94818f1d1ca84c2be5f66a46191a7548b\n\nEntropyInput = e312fd67b5009ab1c896ba8f85d53fb29517ed2a26d20a4b9d09505ec004bef5739cc94e7f368989c675eee1f40501a2\nPersonalizationString =\nEntropyInputReseed = 176ec11c0d4462ea26b1bdee41208e3ff3b430de11f12567ebe982c16d709f681fcd9f5bd5309f3f2a9d80b3a426929a\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 07cb9f51e34be38fe1d1c18858ee44db227c1e6a6c2f7d09e9143e87e9e09df0af9a5cb7a183e5d26359509fe619e52e59e3333d3620373d3ae5a008b51ef786\n\nEntropyInput = 3eaf30117135d9167c829e35bd8da227a6302471b649381858085e67c65496058ded0ab176a38b3888f4e3c2e65269dd\nPersonalizationString =\nEntropyInputReseed = df60a1b9fb2f8501756edd09e489fc98a60ed08646f5a2e018f55b71c76b9b7718ac4ae61b41241593829108ddeb0ef0\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 29c4d540354e97f50f3fb1de84eef471192cd76a670de34176c6465523ff249ed5eafe2c09f091f5ed101cf8a971d782f150a2642ed291e850906e29328d6b8a\n\nEntropyInput = 99d5543c192c6a1069bf548d80d678bc42c1f020f0b29a0ceeba424c03f8a8aa38df1c0fe100ee4c1b0bc870b4afa3d2\nPersonalizationString =\nEntropyInputReseed = a0fddd29c792f6f411b5d532fff2564d492ca15ac8b7fe1b4575e9b59806823665ad7ac4e2adcd2803ccaabe87ab75ed\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 3d58e98a1f4beda50f84f773c405d106b28f4be6da2a2942098403843bffa3323c53661a7f072a020c68f55ea2b3a9cf9157b7c4cdff5e642ee9be1f436f9c18\n\nEntropyInput = 2151ba6cf2ed6a7366991e516443162b6ed4e7f8ef2d6c81ec5e5feb0061e20ced65da27847956194dc6177b5e0befa9\nPersonalizationString =\nEntropyInputReseed = 73418efab1c6039145dc6ce09b84abde4ef4f8eaccbac250213bdd75e2a5e8b42ffb1367bd8d1281e3b0051651f78a05\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 5b219cb285c820f3bce52b9eff15afa042de3036f1a52896eab34e4476c28c60127cf8daddce0809efafab03c9269cd220a49f79220e14db9d208311d2a22a1b\n\nEntropyInput = 7c7321b69fdefdece32c45e47cce07a0d599e83ea8ee5781e2f2ff341f292c0bdb848e5ab379771639e811fed45f63d7\nPersonalizationString =\nEntropyInputReseed = 4b04652d3d0515b305f4da346754c0d398c8cfefe8e5c1edacb79cb8396018bda12ad7d42bf86e801159bb62c34fff68\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 379c12dc2c8a884c6f40df5353047d74efbd9c626795b86256abec4a6f42ba26529f19e4b043f53776180c7ab16a3817b4a50c09bb3355234786e714edb9e2b4\n\nEntropyInput = 3a56329b07dffb8bc7761c0c2b4ec4ec3b7ed2513f0cc3d9be3eb9a153e8e1605d9392dbb951e4b0989ef473301f6f57\nPersonalizationString =\nEntropyInputReseed = ff6efb9b946748af0992bdc38eeb15d4991bb610692e1fe53ff828405924a544ee0e4da70aa1d0ae55e7925a58cf5597\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 9f32e40391217833176ca768beedd2839892c6fc17dec5c250f0820c576e4ed615729653515ae13292a2e4aedaa2df74c6535d8c625dd1cab479d3c5ae7bf955\n\nEntropyInput = d550f48af436ae42ea48a8cb0cd615be8db51691b365ef20ed826b28561fbacc9deb28cd3d83655033068948c55683da\nPersonalizationString =\nEntropyInputReseed = 76ea2e732f77b337ddd402e367c158dacc3433feb40d7b4376fb8dc449891336b00841580ea189583ada95cef783d540\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 8433b2ac45da6fdcbeaf3e6f76e66beb5b90a89a9cb197cfbe405ed53b1dd51a42cfc9aec5fe7cf778f88031fb7b15b0874d4d1ea87ef3895848721b34fb1a35\n\nEntropyInput = ce6137f720affd106396d9b66540580ae216d5d7dab48ed2729cdb3e587c7d8da13ce39ea8d9d8c22220a96b74e7ee9d\nPersonalizationString =\nEntropyInputReseed = af9f12fddeef001b08a5993f62da5e7c3aff23f882ae874b9f66f28eca1106e6386dd82f07ae1fb6868f186e2ec4f449\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 219fc160dbc136cdc9a7c3407eafde4639602cc58101c512dfbd85cc26b61fc9a94cdf76f15a1de7a46e36ab64aca3eeae36acd6e3d0b3fe59b75958b3eddd24\n\nEntropyInput = 1accff5a19861164c5d2cf542cf41a789f143c7956518ae158d4449ff0c257a00966faa862ccbb363bcf4aeb31089134\nPersonalizationString =\nEntropyInputReseed = f2fa58209759d84bf38a1656bae655669767a902ade22a830df56b32ef9e1c992335eb4cb27eeb142bfd21b5d31451de\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = f214b4055d182cb258d9e9b61251bebc9bf090db662c4e36023cc156964fbbe1cedf691cd0c3d7db4262fb65a5d34b942f909b0f31fc18009766413523dcaf40\n\nEntropyInput = 99903165903fea49c2db26ed675e44cc14cb2c1f28b836b203240b02771e831146ffc4335373bb344688c5c950670291\nPersonalizationString =\nEntropyInputReseed = b4ee99fa9e0eddaf4a3612013cd636c4af69177b43eebb3c58a305b9979b68b5cc820504f6c029aad78a5d29c66e84a0\nAdditionalInputReseed = 2d8c5c28b05696e74774eb69a10f01c5fabc62691ddf7848a8004bb5eeb4d2c5febe1aa01f4d557b23d7e9a0e4e90655\nAdditionalInput1 = 0dc9cde42ac6e856f01a55f219c614de90c659260948db5053d414bab0ec2e13e995120c3eb5aafc25dc4bdcef8ace24\nAdditionalInput2 = 711be6c035013189f362211889248ca8a3268e63a7eb26836d915810a680ac4a33cd1180811a31a0f44f08db3dd64f91\nReturnedBits = 11c7a0326ea737baa7a993d510fafee5374e7bbe17ef0e3e29f50fa68aac2124b017d449768491cac06d136d691a4e80785739f9aaedf311bba752a3268cc531\n\nEntropyInput = f963096540d0023d6703e18248755ad16aea91852a2db0dd0f6a414d2a5822f3224ac8b1d47b01aaecc93ae299081d7d\nPersonalizationString =\nEntropyInputReseed = 399ed54bd846de00d42fb1f92d1ade93e81e32cd6ce73825f0bf86179dd46fd79bc8cbbd3b8834e58cc86619e19b08b4\nAdditionalInputReseed = ee073f9f6145d0a7c09a5e4a12d65baeba360bc9b5d7cadf93e7d2454dfde507af37e49782cf8550dd3a548e8cf98563\nAdditionalInput1 =", " 6a42ffe56dac0b4dc5d84b49698859b3645c920151565bf29f56b6322244bcaa7cd1ebb8ee9936d8ee1d280f547ae245\nAdditionalInput2 = d057c418a758d99a8ee855093da9bc1734a5168a6df9d9c9924e8bb472b5945563d86350dcf3e11aebcbd06a22b9ef78\nReturnedBits = a0cd72e63f49ce4c1d64e21e92546afced2af268549ef48d3ca88afe4d4097f91a52ecd0e7ad12ec0a1f67dd8c5325b78ee507c0a63cf90d64e9c47862acedf3\n\nEntropyInput = 333a0269eb0fb1d9d1e92f55de9e13cd7e24de64f5f276382d3eb2ff356a66679a9a75d2da31d39a940a09cc85d9d531\nPersonalizationString =\nEntropyInputReseed = cbf504cc473c9a6e66493b71b9684e8df458e65d2cc676e4e6ad43eb59172932c0956d0623134a6a3bba23906ec9da0a\nAdditionalInputReseed = abc86c71ae0585827ffe0d19a9fe97f23cdc4afd67978e553e0669d4635ca1df30250843fefd4d1288f6fbc3bfe04a72\nAdditionalInput1 = 15d15fbe7c060e6811bf47c21e93639c00cdcc562f4e02c88f7e347ec14a2c8410fdb2ddc3dfa62ba9ed1758f12017df\nAdditionalInput2 = fff311ea4c5cbd8ce53c45fe8d8106c28eb06d01ec9d8245c29f95b50b13085a0ec28803d733bd0d8a75193e63e21d5d\nReturnedBits = fcdb52bb6e2ba8d896973b9284b32af6364a34a2b80b3e3c7684c200c9e0a02f7bc6c3cd32b159df9b98da07a17baab9b0b07eab214544d5c562e454ec643de1\n\nEntropyInput = 86e4c30c5a7dfcca86eda7723930ab3272635f0ad9e2fd70a2d7a69b6a07dc0cddeabffa9c411198e3cb7589cb29d3f2\nPersonalizationString =\nEntropyInputReseed = e1af1c42cd29dd002e10e5839e8b679d3c5192da5e1b655123132ff1ade22b35651ac6df66fa14f36e1832be7a176895\nAdditionalInputReseed = 5f619073fa2e98b9f06bb4676bb972379ceb727e1e8768ef09e532cf3d8fed5ce92a7528eb55ae552959d74f75dd0324\nAdditionalInput1 = 330e316bec4955d907d7d7bf2b7149f0aaf4285ed1a2b7e387376ea1a4e0858c114ec3ddddf7a1edd7c8a29b1f12b998\nAdditionalInput2 = 405911cf7c6779e02e4740fa9737f189370292494c80621cfaa9f7d16d68219e72d474f8d5a54aa8ea8020dff9c36650\nReturnedBits = e359c3e23315c9c1d69ab2ec96ec3c6c5aad868e58709e101b0fa08c4041248e4d538d038993250d395d9651513514fca5760dcb9970dce53d2d1c2712bc56d0\n\nEntropyInput = d8cc5d13badedbdc2fd41852247a9f2879b0103b4a8186f0a08da7d55453b7484f642a9e5a5182340584d2ca7cd5ed10\nPersonalizationString =\nEntropyInputReseed = 35788b8369fdc3dfd206efb873b5c5215f5b8ecb0541fc0a0e027e868a91053b5d58cc8ca0751e0c0893c868e2322471\nAdditionalInputReseed = 6afcdc760fe62b080f141886b516623971f8014ede86e50d62d307a90cf3512da5fefd37b3932d3d9d86ad0c03447be4\nAdditionalInput1 = 72105702fbf1da4c10ff087b02db764804963fd986de933b757b8fe5a6016e0f2700573925aced85c09e2ad9f9f7b2c2\nAdditionalInput2 = 65f9a3fe4e1953b7d538f6d6ca3c0a73bda2276fe8f80860c07b7ed139d748c3c45db5d96598f77ff863a43977ba390c\nReturnedBits = 7c2b600c3f550671215b03ad7aebf71086ec59aa4f45cf6b3bac9bba2e108f801f6478b098fcc4e063454cd3f64a951ed70f619866c1a4e70b5c47458c09e083\n\nEntropyInput = 07d14a0d9fbc76a155047a93bc0bb2b578fa7dd75cfe9a44bb8709fe3cc2302fdcc06a9c6751f4602a3a4955c0f38c7e\nPersonalizationString =\nEntropyInputReseed = 8babab6b9f8429f554156da3905122cb48c0b901fb6eaad8df771e8d583ba885dfbad02e47524b1981768593bde88260\nAdditionalInputReseed = c185c45cb07e8c8ba8eb31d3bd48a7c864137c689214c2fb3b1d6d6abcda84f2922a862a0955e67695391d60d6f2d1bf\nAdditionalInput1 = 326a5c9c4a1a2b6fdc369fe2a171bf625dc26e23d1a34faacf59bd33be98ff7ac7f16e485b6da3145ea4db37ee4ffefa\nAdditionalInput2 = de096ad13dcc1ee1449c3a0661edee028603590f087474161a7ab8fcfac896a924e14b0a57aeac17fed676f4b9c7168c\nReturnedBits = 60911e6e6455bf4d85a4f76378390f6cd537d7cce88228cf34e4a4889adf62a9cc1070dfc39c254e81a8557bb2c350fe3f462199e377d3796ed139117b6b0f45\n\nEntropyInput = b3458c6b38ca70c44fc6c601e088863fafc953c6b5d3ee57fb1a07f3f65dd5e6dc19aed17aa5530913aca598b26a40c0\nPersonalizationString =\nEntropyInputReseed = faa8d3feabf972e482e5a0b3821c23ba067c45267e3715a4c10f65716a348030d7fa5637e9f000b3e47d786c013fc035\nAdditionalInputReseed = 901ef89ea38203b83249a34a1a8cbd0da4773ccd503d60a395be3a3db113613e6c571a49960a4e99d302b6f237f64d54\nAdditionalInput1 = f2f87693d1f28f95b0a6459c538e82be99a8cefe8a2c7ca037822072e63670dd141873f3dc9e309c6ead40783f46794e\nAdditionalInput2 = 93cfefbb7624a137cbd7b177918823893e77251fc5660a76ab0cfaa3b340ae822a8a75365056f06b0a7e76afc39f6819\nReturnedBits = 5bbcdeb5d7d1ae19e4ef7878abd1ca4f2641d42c765b94a7689172a4e90baae46ebcfa5427a882c1614cab36f186a98dd3a15febc4b23add955f69dbfd5e5d2e\n\nEntropyInput = 6dbcf6f2f3997ed55471f779039982bc84a1c052fbf5883d6f62c0a61db108386e74759d7237bb0efca030aac76bc7e6\nPersonalizationString =\nEntropyInputReseed = 1a16753c195fed27a1abbe067b2b22aff4c49ae7832d18d01cef5ea5c7d5833008036f71e9c77c1629b6f61370b57f7b\nAdditionalInputReseed = ec54395931ac0aea2a8739d4c51e33c8425906005c341db373247e73b968c2c79257cf7ac74353c00fd81a80f4c95b8c\nAdditionalInput1 = dbd6bb5579a10e395b534431f3ab7c8025527bf99e4f7c162d681f8d35a56f6a03729f07ab43897ad0e80146044b1614\nAdditionalInput2 = 5d35742c25620bb795eae41178d7fc86d9cbe050ea702573ae6adb61e16c411b7445548dc535d57371bb11e2cdd59597\nReturnedBits = ba3905bfddcabf6dae311d1fc19fff1f6fc1ce779e38f864b7ccd2aeb1b3d6ec1845305c29d39b8736b3977277ecaf5735d0e4acefccf7778ac3542af815fd41\n\nEntropyInput = 3a9e8099007c67f6e5f98525cc4295a68c5d5135d01f5f66305c7048ca02525caa3f790b2d12a8520e9963a9cdd597a8\nPersonalizationString =\nEntropyInputReseed = 15993dba9775db8a5bf79778a316f2910d4dc0be59c3b21c650e3aa89c8c89b33fc69e9e5d642e7fee16d61b691de2bf\nAdditionalInputReseed = 946121bae27e5804daeba0d7dc7ae0c1c397bfab106e13b8b7c5462b540d147119af5b7c4f9c198161e5aa9be34e2d28\nAdditionalInput1 = e9799421e75bae7086731a21242dc101c93b768fc747734a357454fc0f7c082cfdb79b8bbcea2d1122d89316a7bfbd3d\nAdditionalInput2 = caa04f94b4b9d694e2c4bfa1e8e708b9c00d9c3d645243acfcb879d2e2ba723d9e48908738114eab7d15f8cf36b043ae\nReturnedBits = 9bd50f3c5384eb28d931f03a64eb97ef140e1e81f4c1d9c910cd7d79a40494e1fcc53d82cd32df35d53b05a450e54b7ec71e28359c1273848e5ab117d5ded88f\n\nEntropyInput = 7f2a0213de6738ec62bedab769a5f01732dad2d35dd4cad7a765dbbb6f9101f57b65ec8fc4e23fb3479ce6211ca3d84e\nPersonalizationString =\nEntropyInputReseed = aeb097e9ddc4dfe87874ddb1a856ec3d00fff1b38c8f954681c11e61bac8b6b2e2d8d010e6820f9c4d807b295acb8ab0\nAdditionalInputReseed = b33ad3dec7d529b71e39d59147f79b4884039d1112804fe8c70e174fdd9828c06a4d44d20aa5fc1918c3ee8082a2bf93\nAdditionalInput1 = 8632d221757132bb7b883b7dc26755f62ec2ffab0876168d11ea7b92774c15c553b11320393d64a2262133608ca92a18\nAdditionalInput2 = ccaf3bc3ae9cdbfa885aa8414c1f823c6a3ecc020b619201a52ce0b7516ba1f49755c450c532bfe11c06b9d0e049ccae\nReturnedBits = 4b1c065a288e5eec56b67fb341e25fc7521b794b52b94f9570bdb16583bb6f7a780aea5297496355ffb4bf5a444c277c96394619cc33cbb5a3b2a9f49b00f9df\n\nEntropyInput = 80773d0272ff48ba84b98c817365b097f21258624d0de8529381977950a5e49ff2b79d0f2522269970ea6d484198922c\nPersonalizationString =\nEntropyInputReseed = 9b101ac018be88da3611a236dfb1300c0049947e9f6ebef7a3ad6e1499efeca0b142826fa06f427e271865232a18dd29\nAdditionalInputReseed = a67ee22453dcaa5e4726e3084872145ab60489bcb6e83346c108f3efcce5b3d988b84d58786658d87c2dc3b9035e9d88\nAdditionalInput1 = 546515bf86e48dfb2b4dd21c2b46f10c1e797ab799b51822e8e7cd99ccebcca00b8899ef6af5cb395168aada9056a6c9\nAdditionalInput2 = 57bedda63fc5f792a608be111141a12e522496c086194515909bddcd868be997e718e7c5899e28dd6b123cbcc3f2a8f2\nReturnedBits = 4075461e459f15cd32030551be47528223693c2f44e32443cbe9271eefe74fa0a6e1ec04f4b8f41d7ed6c5f455281a3cba56d952b08b7753f6a3d7da3517317a\n\nEntropyInput = dc132c15af0e214d1b56eb88849e96b81dc17f238eb3d1bb9a659219dbd77eba38ca2796a8011e29cfad76f8cbbf099d\nPersonalizationString =\nEntropyInputReseed = cba23d4fdbb6c11e38012b71ca264bff9d1264bb20a39bb27d86dcdf7d72ce7a4f5c124cdf2aca6aaee20832495181e6\nAdditionalInputReseed = 07e043add7cc14612a82926c09934dea092f4618cce25674972b1f50b2907c7e3d40a25722ea49b0c7ceb6b57ff2d870\nAdditionalInput1 = 0017ff834967cff8827598ff6c00a9c97f0347c34f2523a85dd7d18ff5575756c1f5383de50338d0ab0505841d70a193\nAdditionalInput2 = c404dbc3cb0851b08530f96500f5a2c10d8985c82dec2ba31d4199fd07687ccf124382fbee3fa119938f0c72ac586102\nReturnedBits = 1935cce86bde7087fcab30b5dce0e072ad741c2f281902e1801e56c08ae8b256d27514de92dd48a838ca426820002c1206f86cad37cfd99d3a935e05f56a7507\n\nEntropyInput = e48495930a7fc86ecbfad807d40ca84ba35e346c812090def8f44d9e48b0a40704ac67ec80ae15b12e858ae85a7ed9cf\nPersonalizationString =\nEntropyInputReseed = f4735954d17e99077061c9604e8f1734d61dd662e54e37256c0f8bf276e025d59d21cacc0869ededb44a2aac9fcf2ccc\nAdditionalInputReseed = e796322fc0ef503251f6d4bd72dc5ea8100", "c5a59f1a4fe4837fa8eb2623bc650a0cd48c306f139e0ecd169a51deb2cd0\nAdditionalInput1 = 1c844d24b7cd9512e5035bc457612ebf6d3df6867aa909038bcbc1f474f7d0783ed474e34525a817bea1fbc883961e31\nAdditionalInput2 = 5c5671ba79bd0b83f74d0ed98e9c8b369a2de34188d8b7cada20b3363738d1252ece1e6a26d007acdfc5b6108412766a\nReturnedBits = 40f17e2bf6084a6447f2c40d601e16a43098dadd9f9614d518874623e8e684438c02e127e582b000dfd46df03dd5435edc4f0f47098320fd311afdbb8542c4db\n\nEntropyInput = df4a888ec7363fadd99ce2223ed39577a41bc220d20b253f98dbfc617aff8fe4ac66e5da1b5097228422cf8242baaf53\nPersonalizationString =\nEntropyInputReseed = e16dca80b2061706e8180dce8f59e888f150836a0bbceac179a4b8d882eead78709ed9951102728abbbbf9226a2d913e\nAdditionalInputReseed = febc9f6b9f2b90b4320d5d41e5c5506fa32b164d86d5e7f91d4a360fe179c127bd2bdeb78fe760174e856a5e04ed898b\nAdditionalInput1 = 0aba74cd299e75886c9e7e5293e5915d720da2c8c1cca7f0e1d6f2b672b4014eb4582e97a877121c87956185736ba0e9\nAdditionalInput2 = e451eac802660ac843fc72b66d59f1e1ca831f22d6a361929043f7626f1d82133f512fb1f2d8ca51004f80ed600609e4\nReturnedBits = 968b708ed6b54d2e5a66d46f22998748dfb5cf47e817732a40938bf3593fb251ccf8f2076837715d14b316bfb52560135602ff98338593696bf80a462b214c4b\n\nEntropyInput = 43bc561c4dd1b904a5333a092a670d0d1b61128a13be2e538a329094574819284e414b938dc8b1860b385c293c03010d\nPersonalizationString =\nEntropyInputReseed = eb362136f4ccc9e302505d525befbfa99d8c3336187d5902b03ed75641913ce973743757f97dae9366874ba62bd87013\nAdditionalInputReseed = a901f4daaa638804177a0b263e8cbc81688df3beb218b02316da83b729230a9e5112fb3896b727298755bb9ac6b6250a\nAdditionalInput1 = e33d181f3159fb0874eff5ef8ddd2b51a60b13ccf046f7e637ed27bed81bb604277f7345e6b8f0e09f925793ce417fff\nAdditionalInput2 = 3ecf6233820e6cceddac7b024c490c5ee14c73d5b598c92cda30940471b6ed450019120689aaf157fd87b71b13afea25\nReturnedBits = 9d793dd96b870dfa0267623bd1c2d8bd3e2c63e9f211340f630fea01358011394154145a10659c4d98274a525c48a90da0126a99b85ed5b4b903195f0dddc762\n\nEntropyInput = ffad10100025a879672ff50374b286712f457dd01441d76ac1a1cd15c7390dd93179a2f5920d198bf34a1b76fbc21289\nPersonalizationString = 1d2be6f25e88fa30c4ef42e4d54efd957dec231fa00143ca47580be666a8c143a916c90b3819a0a7ea914e3c9a2e7a3f\nEntropyInputReseed = 6c1a089cae313363bc76a780139eb4f2f2048b1f6b07896c5c412bff0385440fc43b73facbb79e3a252fa01fe17ab391\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = e053c7d4bd9099ef6a99f190a5fd80219437d642006672338da6e0fe73ca4d24ffa51151bfbdac78d8a2f6255046edf57a04626e9977139c6933274299f3bdff\n\nEntropyInput = f1e0d7b1ac7e4e155bb588500f57d0c59969267ea5427e2d7fde1f9c54e67b7f6562bfc1019b8b5799d2a833fdccac79\nPersonalizationString = 86da37245d9bd1fb59a4bc7abd289ea2999258042c5fa696f2da7344bb6ebc5b770ca284bfe642570b52ef47b780d5c9\nEntropyInputReseed = 9c2c9c07cab12cf50f8846148034a416c83366c1e20776073751553cae69da8d1f6bce6bde27087659d69a62e2ba7c3c\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = e0ac06d7eae89469b6c14a31e7f0464ee21f7b30d2264c2de3e435cb40d0e5043ee13dfbc0342156750880b2d5dddb3bebb43b162a8478235c8b87f96d0284fd\n\nEntropyInput = 1dbee767e9916ab322ba461fbf9f7515cfbcb45944a7b471577da087690d94d967018b631e0c1f64da3c805d049f449a\nPersonalizationString = 966b5cd94019d4d90b48ea7f540a698cfe30d7eb25f5f7e5fe42d9f53ebed6e94e733b0794fc6bf30627911e20cc18e8\nEntropyInputReseed = 96e828128f183c76c90ec8341a43561368b77114048ccb05db66128d54c9539d1adc1d72f7fb0950e41b1343a9e4df76\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = c4d3f5c55d3979b174020650ad7a46b423ec446dff2a9e9fe0a782bf65a72d5fcb1896bc1092a8c73f41295e2e7044434f88aa0aca78f7eac40e322cb7c25563\n\nEntropyInput = df588bff3a1fc97a908067da6a7fef08c889ac29ad7d639bd047157bacab4dbdee3dffe575f37d071af94cbd7628d398\nPersonalizationString = 548715cfb28c1bc56453b8c39e24cfd64077c0f6e9d959d51b9f0667b97d3c4e1a179d1a554df845b24c26daec85845a\nEntropyInputReseed = f8c165b5ebd8347a2ffef2218f993877027e977598b4fdac2f65d8d994c7432900f8407ab5aed1885dee5aa2458f5998\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = deed18220bd8f72a34559924f3cad925ee717690f76bc223d5ffeebbb554b61b9d9eb6ac5697b06331e236672677e2e01d6e3fd581a4fa1ebad289797b68955f\n\nEntropyInput = 98555093e443fe8e2bc8d2eb4d3a7abb8eba00b25683a6b31191fff7c043665ec2cad3e99e55bbc241b8edc699dbc9ed\nPersonalizationString = 5627a0a55457db05e3903d4b69ce15f55f933168d6eb374c044e8f1040f61ed7eb24f87f91c68cde050f504b8965dd81\nEntropyInputReseed = 18d17e1b68378801f83e7aa9a6d4b84d3960022c740e6c845869a5db553d2e02479cd92f3c0d8abd3e92fc9c9fbc6a3f\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 7a7f0ab07a540b4e9a3eda3f8bd1262015d8ea6d512dbea05942421f5a73242ac236009ef083bf2e51b19c40d1a019367a6b96fb52d254e4d881550aef0549ed\n\nEntropyInput = 07793bac6461f23e5eb0d1bc60b5f735515458d1530540df1c8e6fc5c3ebfb06b9db60a8947eb629ff7a375fe680d696\nPersonalizationString = c1e2132b77b6c15742e06e856c1549c4ccebd1b2eda93e2c43391b52cad51490fe34157f57be9eb4eff463b059986680\nEntropyInputReseed = 23e47e0c41462f7c619bbcd5b73f9ab1c68c7cdf1ec92c4c37126402958e110e329107742e70db611b93974c393936a6\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = e6dab4a887f48ec33cb293ffdab5fc69595f94c72c5a9bb43f468f75490190b7e0f14f5c04550cb62a6d0ee0c3d834be3434c8229c124087bb985a06b9a37267\n\nEntropyInput = 25cefa0512921fd4a3a4e5e7c48c6201185a6968419ae5bcc6667bb74c35de4f91988a33f25ea88a8443c65643cc73dd\nPersonalizationString = 07ddf125960c346680b4b361c0a9c6dc1008a85ce1861b45ff18907e6e7db41b046e5f016617e6c5b0ceb5575ac278a8\nEntropyInputReseed = 8cf41e5413b0c8ffacbc4dfc119f10b47569359b911448f45c7ad63dd58e872410c25176b986fee8b83966d0098d996a\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = ab58ec5c35600566dd2ee187a5b67dfa65bebe13333670d2a198fa5af0c20294c6cb69d37564d2b2587ea5587e12341e77f47f173d6cc9f9b9e5dedf0ee1a8d0\n\nEntropyInput = 929f1dec0a6d14de483a2fe114a430796d0b449fca56a4ddbbe661bdc26a8df85cafad7b677ccbf1fe4cb0d5e8cb57a9\nPersonalizationString = 0bf8c590a66653c0494750d10274b583d86e540b517bfc23bb3b0c9fde373e456558468603c2115c97d3662e6825f4f2\nEntropyInputReseed = 84030628534b7525dbd4023aed1ab08c4f2b86a7c2fa3bc9559b425cce07c34fac14e963256aea03f74f1122a7a30483\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 199f2dce5bbe32c693151a216fb36ccea7996c313f6b78fa30ad812a0e603965023fc29706a71b753d79244cb9e8fdaff467e0f963426b10ad89a98e987af316\n\nEntropyInput = 7bc5d970186b9e1b0052b7564dbabf61c89cb3d64ff42f9a62d625112aca0486cdf0336c3612254b40cbfba83ab65b42\nPersonalizationString = a25326fef30f9c94423d99759a1ee575536a9715df9526de9a0b8dbcc3a2234cd835615f5dfe7823927355f569ec6f02\nEntropyInputReseed = ef8a0137013be212402e42b28c03ed6420881aa38b3a3e6e90a861116516df1ef732a19e8935ffcd9be7a2fc236783b7\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 29f81ecf3f41d278c01bba9af9bc0fe6009539682f46723ce5b0ff75fed217ad71580b5dac46289e324d824094c332c3955c528257701a14ec2bfecce4f62a6c\n\nEntropyInput = 0c841a245a19295281163b07541590376d31d86a9be99e66cc22352dabb29f95e113ee233d74d3f2b7f2f608830525f0\nPersonalizationString = 28d3581054d87f153aee12edca47bad80bfc9b066ad1e8b9d96c851dc7b8ed768cad007b891d1c9447d43065b483d085\nEntropyInputReseed = 587a1dae75c2a1f2dea7fb42ef7bf38646b76a964ecd7043d8b62fdd9e6a5c007882f02f78fd040561d15a337e59f257\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = ba7bce080963fe2b4e8f0e1aa700e92b3908e18dc78728666904b0220e4077fef2cd18bbea29a2755a3499798cca445bb75269a5adca2f291dd3875457c69a89\n\nEntropyInput = f4afddabe515ca3e776730e7d44461b27e8f72407ca398d3fb578365e09ea8c24d6c4b09724907a610d755407d38667f\nPersonalizationString = 846bcbc7014ca8c6fb042a80d4a8c3aa50b6c5eff15e4b12f966ab17e6514cbb22fb2eed628ee5c2a8acde821a956078\nEntropyInputReseed = b2aeab1165b150908c9bb52c2b7167c149ea4fb4710edc8acfbc63f7652bb552d636a7e6fc3d1e74d3f65461baaac087\nAdditionalInputReseed =\nAdditionalInput1 =\nAdditionalInput2 =\nReturnedBits = 2a0335c3caeeec7c797f99fbc145654d3985c3c71025c8e4bd4b098801f15d21c272420417d805b0ad1ce68f904502a46130246315957bc07a5db4f3447a84e7\n\nEntropyInput = 6942413e05ac487cf539bc61aa6866ef8cbd9d0f15e1385f37bba5a951a29fc956d46f8740603af7c71800048c8312ad", @@ -2657,83 +2762,406 @@ static const char *kData47[] = { "887d92419e3c839b8b1dc43c6507026f1f851e\nAdditionalInputReseed = 857848c62203307b39728acf11ac8462302d3a41d186778b3f112a86270252f058fbe5767496e47662186b8d0817de02\nAdditionalInput1 = 9a08df0de742fd2e2d55121a58b700dfbff250a4881b02fc3b8952b48ecd4d034d6e7c757cdf91bf7c31dfaf70b1da22\nAdditionalInput2 = 3bf0e4f1291a8bc272cc985878335882c75831510f27963c7c01a879c60c5b67a9a14a656a746a80a091adf6ffb1adf6\nReturnedBits = 69361d61f4cf5ed489888934f320a9acc5383e719f09a1e30b6029bf71d4b4cb54859798ace2d8ee5e681d4acb223b9c119dab2dd07e6db3f7f844c2b46b9c47\n\nEntropyInput = 6f45b55ac62d5ffd452d36b1e4b18cc6abd6ad93e87558b79fbe99b4f4a962b74bad00821019bd126d6f9dd73912acf7\nPersonalizationString = 913a783046baefe428346085fd640caa1874d4aa6974832cacc5b51e78514bcfedd174606bef1721df7a1194a0ccd1e3\nEntropyInputReseed = d9e19ce3197004ab3a4bf995a481149b6d8e59a3970161cb0d3917374c0c86bb5e9bc509bd01b6796fa1e77e5fdddb16\nAdditionalInputReseed = fd31068c90614e04463acdf856b034293a079a816f1c5f3de63b870a9876f7397d2f93bd3f6776b56a78f7178e1fbb87\nAdditionalInput1 = 068e3791b91adb820b27c45a5d8544eed3133486a7d2d0bc503d8abad8b7093f3df214f1e0ac4ff2d347c760b2a605d5\nAdditionalInput2 = 6c55927a349d321d1a2141aeccc3543e9726ffcf3d8fdfe1aed63c61972a213c12ea65d648e476268611e9b08486a648\nReturnedBits = 552b4c4035d964b5eb26e3036445793df67b7321d36e8d2362fe284503b587c961a33b816b40b93d4b006769177c6593c553b6e669076f25a3e2a7214156c249\n\nEntropyInput = 8d492df46257a62e717302992682e28494f84d0f3237c16439efbbd16a94b3356eb7f7c2a0206892045a0d7d36d69f03\nPersonalizationString = b915f3311feadf6676df2389baacccdafc74cf200ed7b99167b33dafa875ce4aac1a61ce54972ec54f9b0901a3b050ee\nEntropyInputReseed = 2e345fe3a471c5066b20f4aaeaaf73921426ac1bc0509e93671535a8fbc016f5967403d6d13b4760491bf973c47a8ed5\nAdditionalInputReseed = 2e8f1f01a7664890feef93152f7b7f05032b4c70c58b5f261ef0a9c2aef23f2a14ee57c3d3465af24289b1c850e52ef8\nAdditionalInput1 = f8c218c996284f757c491cba025fd84cc701f9f83a16f03c314712c2354fee39214ed5994ab24641826bc15ed1bb5f61\nAdditionalInput2 = 146c53dc4af90f26d8c85822810d9bde2949495c23ca2c7c13ceee8221cbe8105491d560e0044c8d50d7e365da41890b\nReturnedBits = b19dd18494235abdcb3b4e99c9355d19d543c7fb7e1048d63d9e25abcc12dcb31549cec2818667713ad1dc35142072ca8daa511927aca71303493e500503be8b\n\nEntropyInput = 2a595f08947d0056ed19ecc8a547867834c125cf1740230a1325b93bf29951cbedcaa6a8f5cbe69801fb9a197ad576c6\nPersonalizationString = c0fb9dbea13863dfbfdb2c0dd864887413794a07a4dd228836f0f6afab901496486a2d508a3f4b784d83382629cddbc1\nEntropyInputReseed = a3ddfc3aefc94dcaf656f4d8eef0065a6d233a76e0a4c26e2d8bbb86459c9e4a173ff8cbec85ebc14712640741427668\nAdditionalInputReseed = d4eb9b12fc2a6fc75a69701c8b5ece02e47f813effb705dbdef0294e38907f5aadf40bdbcc067d0ebc0bf3661a2e0990\nAdditionalInput1 = d3c4bf4f8a3f61413fe1953523ba83bc02ae6d7eea1c8ba288f8e06f0d0276e61667a410f90548d283c4f1ae79483961\nAdditionalInput2 = e6fc29680eef141e1372e17729c9f4407b3f7a57057be1081ce46c78693334bf56867791072d9d18a7b4835bf251712d\nReturnedBits = 08475bfb8e621e12e212f4960e737023f7a3de3b204b6ffeeb929f424ca78c6ae2e0d726237915e5e244616713e88a39df302208e3a324f5444213b70b2e9c09\n\nEntropyInput = 3d5332b91dcaad893df504c7c675b69890b28055dfd3ec7d0ba56990dcda175096ff8f8f9f9ecd6dddeb96b829b98c3e\nPersonalizationString = 34753432b3c6bedc4d2296dffce8a66591b400867f7edf10cee447046f5f767036da9f3f4a02f7b8cba7bdd4365c1fef\nEntropyInputReseed = 1a69af0ff696f9a2fe0fddd26ccf6fae215faf91804461928c884eec13b1dd1501862a738373454e1b449c6026cebceb\nAdditionalInputReseed = dc47e104175f3c9812feed9e143da5cd7e553e3423db5bc8be3b652f577100267ff795804aaf42c3991589e7688a977b\nAdditionalInput1 = e64c0cad3dfc0bf0eba3317cf37b7779b91bf3de3e0ba36d3e16feb0014286596edd364c197847e8732925f971294dfa\nAdditionalInput2 = 1ff3a6bdb7e319a86b35d062cf017ed270c6b5511bc3d63083272e76bf4db9d90e836f18d98f1f79c2e91eeb0bc635e2\nReturnedBits = fdef7e67c3d19f5f74784bdc64d2c23d0a3f027846da2b2afba940fdc2f066d89b63d27e55d3d0a88bddb97e29676894ec8a18268e4bc27d181a867c5a80fe2c\n\nEntropyInput = 156c8c0f44f4a8f17044957b572ed16d54b73a9510d2b260a036ad6ef223f45e124c4ae9dae0fdf5684792da0ff5ea0a\nPersonalizationString = 1472f56d5498564a5b53d2eae27103f41f565d7873b37c37c30472075f1d84d69a8d68c92636ae06aa61678358cc47d4\nEntropyInputReseed = 6bc2bfd44f72982b23b6d22c85f7d601d5941ebe6e9ee9d06a8efe652539ec00b1136adbc4e43aaab76c3ad6a57a267e\nAdditionalInputReseed = a83b1547fadb97e491ef0bdb8b0d006ab16638fdb211613051f0f57586c146882f1062b7f71a8c15bb27200fa83ffcaf\nAdditionalInput1 = ac188da8a895e0807bab61b1ebd73acbe43f99f375c7d29174f675e1667237cedf1d41fc50da277a0db21ee2891a5abf\nAdditionalInput2 = adf9a30b6cd9dac23f193f66df9d606a5765b96cc42c099530c53c26a6d6bcf0779ae060d188e1cc5bdab6c312892267\nReturnedBits = fcc79828bf2c9d3d799d7a0e83583c70aeb156e25df0b2fde030c2775c9986c8054e848128ba38ff5e5b0b1e5b72f9e41726b960008408f5152b1a47072fbdf7\n\nEntropyInput = 5e0dd8e37aa23d0fe79efcb8e5538ee90ffb5733decc83f7677488c4f64c2e0d2a918968a5c7351de9360f23fe606a4a\nPersonalizationString = 5161b794e4a13371b320ae4b2b6b698e4df507402a7582555598089dd9484358d37f891294948512e4198a79de8ca3d9\nEntropyInputReseed = 850ffb89bc23562f3ea03947c1afa7309a0ccdc0b714bc94ff45d66884b74fba0bffce97887f2efc178388f36f0ea95e\nAdditionalInputReseed = 50f605cb940f573c4ef3ddff8caa9a3f544f40fdf583b82cd79338523d896f72f86be1f9bb37d9aca02a2856f713c812\nAdditionalInput1 = da7bcf6810a6b3820548065edbec0fa2fd4bc03e5d50666f98a8bea6b744e04aafa0714582f11b6608852c45ee51df6b\nAdditionalInput2 = 4e9c0c770699656217a0b2dbb466a0fcb0cdb5d4a4a05da40fa2eb546f2f0f28aea575a0bdf6e89352d519db44f47dc5\nReturnedBits = 40ec0e8e3e54cd4fd78f5e006bf3134c378ba619ccf9e7530c79217da631458b5f9135bc8b0d6f2e742c53b58d0ebc18263f9d2ef37a2fa0fb086d2193857863\n\nEntropyInput = 219a364ad362fd8a1d69c1284fd64cc9ec05e6bfbdd133ac9170594b5d95946d3dda2ebcc58deeace86f9dca5ad99c18\nPersonalizationString = b0b27b03fc65effe4610e61916f2e9bd252d47efcc08b84aa505b1befd3a7e9295ca764ac88f099bbecc28301f0f298e\nEntropyInputReseed = 1bccdb4b2ce863fbee104d7a56f2cd88a44a088392883a6db30e6fc7bf5611759c71d53a61fe62b6314d7426e510a722\nAdditionalInputReseed = a06eab3b05eb3649a01be82a356030effdbf45fd71f49b1862ecf33fdb28a7191a34f104b9eda1da4ba48daf9da381b6\nAdditionalInput1 = 88b17e13e02a7e9a3f8263946fae0b6a9052692c3c5cbe858369c4d0b198b9c6a8f4c87ff5e6b2835a7944b911266aa9\nAdditionalInput2 = 828222c8a275427a5f8a963d0d65e92f6170d5089c9a162429c093a28dd69f71135342f16b3baea9a4764e2cc3762267\nReturnedBits = a739f9fee9a40049e42b00b381a1f663877abb776ec655e3a7870bd94bea1a25d3c6d380eced435e498044daf78b349bc1868e4bff6257cf2711ed08e2357201\n\nEntropyInput = f8513c2f6e46f75fce3671ccb3c69158583a873b0dda83d8b1cd548f4e5efd75642f2c23cf8792d51023f31d795f6f5b\nPersonalizationString = e94f7212257885511b15a873d0158fa5ea648846afbcf9d62a7abc4e6909dd43c671fa18bc289f47e2301e9aa69c3e88\nEntropyInputReseed = 487b9c1866ffdaaf6760cdee3df5a930196d30b0ac8db780656577ddfc1ff3508c451ef2b0b478a2cf0c73027597b2ae\nAdditionalInputReseed = 7387b59f8c78e79d36edacbb428fd515ef9e58086059bf7fd642053b0f5706cfe86eb3c35ca0b6f02e5d1304e476e3cf\nAdditionalInput1 = bafc59ef40e59d8c28851212e1c357cce0d06f02c69d14585170ca8eb18396a331d635cf0651319842cee2f7c87285c2\nAdditionalInput2 = 82d905ba69b6c45ca28107beb6698a152631ab48614235f6a9f12e019f66bf326151d9ee84e0cd42b6566dbffb46ec35\nReturnedBits = 163f48d09f3e9ebf9f8647766a0b2e189a2f3a21a5a4e31c8a4f3bd138cc50030ac8bea1c4d9e9aa0b67f34926239fbcedfd1992da165b941cf03b56737737b2\n\nEntropyInput = 0a8f092764d473d48215e947ea8a32b5da8ea86d8ed0d83bce31b1b5a21e7c5f1af2186a39caf9afa61644caef02ef9b\nPersonalizationString = 84637faba756917b0f44ba2e0e26546f5239782e4d9f952ee251367081629e71c20a7459995a7563810daeab74220664\nEntropyInputReseed = eacaded3d89a63b94a5c14c3087306e670fc4ee7d56cafef4c5aa7d553ca89ed34418056a44f5447e2b07dd541ac4645\nAdditionalInputReseed = 104a1541313fc4be9d34bced288c1c1b6fa793e9096f8be5673a2c6825dabef91fd88e45a061b2d897f9b5e8a8ae0ad3\nAdditionalInput1 = e30c9d8aba0bd5dc63d911897e4dcadbeacc3ed9392d8e361b356e02a81d65bdab91f7e9f8dd2b2bf9af0da5100e77d4\nAdditionalInput2 = 2bed42b8c05461ba2756a5f38393d5538d20eb9cf1c06775e7fef7284341f61ccd34b0148d1e870c1992dfd065560ed6\nReturnedBits = 855a6af3e6dddf194ceaafcef6f7ee91f489a61a73b759d41be4d5298510b9902f5b78b1162cba417684519634b578afda9802bd782f04b3a25106f3586ad8a4\n\nEntropyInput =", " ed63e3b88a2f0d6a40b7b36a06cd8d40ec10158ab6c4f8dabdb879e45d22db573320d2641bfd7db31eb6bbf4c6330b9f\nPersonalizationString = f82a5ee81f349a69dfa6a6e53b406bb560cb0339f61b3886237023ae4582b9725b8774a8044ec5134ebd4d7606f18188\nEntropyInputReseed = 7104522c2a69bec7e010d9670d7ab92dd817ac7ff05d63ab0e12d431d4c9aef4d715421c1fb5d05d3aecba36859a6038\nAdditionalInputReseed = 3b83034ea440604d0b7d04857623e9adc0eb9aad4a45b2079863eed3d72e65abf67d255673e769a2e2584eea59f1ebaa\nAdditionalInput1 = 8678e4f831887e96a27c3a8ce0963f4b34bbca25791b06526cb6c55624c33d98a0356be624238cecacba3535e872c4c7\nAdditionalInput2 = ec3452ea2722984bbe6a5b7c22ad58df37a854abc8630b9e21bcd0469eb207e5f44e044f5f666920dd55e81a393500de\nReturnedBits = c340765fe7a3479bef2d7d59e321066f8ad0db53aed4c517bf8339566bf877d53921e6de2650d0080529004a5fd32124ce8e58a040e2d55656b37d9ea827cb91\n\nEntropyInput = 882ed05487dce4b4f9e58ec4f2da1fa5d8ebb4ef9fcbf7b0a0e15c4dccb8e19788f86dcf2885e71a20cbd9ac10a6648e\nPersonalizationString = 05f5bc41687ea1e4c34a69944fbae283cfee4c42b1bbd78fddb0973d0fca948539b6843658b67c30b73191b9a0bf2921\nEntropyInputReseed = ca1603d4c8711404c7bdc12c7c75b2943a4b042ea1d2eb54506a6876952157caf3b152dc75f27f2213645a141577e8ba\nAdditionalInputReseed = 83cda53380888d53515e58154f89d5528ab69f31fbcfca34988cf03c4cae5f60aa6291f32d99ab2a726b6e08d2502cf5\nAdditionalInput1 = 5bf5ca9f964edd91e8ef491fd3cd32faf9cb9d1993d8221914d1751fb0d4252a5ca950e213f088050900b2bd74f5e336\nAdditionalInput2 = dba28dc1d8d615651547867d4ef42519045ee16378143685101da47a27b55498078e8a8f4854052f7cc6f5b02e571ae8\nReturnedBits = 01f11971835819c1148aa079eea09fd5b1aa3ac6ba557ae3317b1a33f4505174cf9d7e940821c9b0e5527a1d3e186a7a83f187c62d3223cf5964ff9526d8484c\n", }; -static const size_t kLen48 = 6637; +static const size_t kLen58 = 6637; -static const char *kData48[] = { +static const char *kData58[] = { "HMAC = MD5\n# Note: The empty key results in passing NULL to HMAC_Init_ex, so this tests\n# that HMAC_CTX and HMAC treat NULL as the empty key initially.\nKey =\nInput = \"More text test vectors to stuff up EBCDIC machines :-)\"\nOutput = e9139d1e6ee064ef8cf514fc7dc83e86\n\n# HMAC tests from RFC 2104\nHMAC = MD5\nKey = 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\nInput = \"Hi There\"\nOutput = 9294727a3638bb1c13f48ef8158bfc9d\n\nHMAC = MD5\nKey = \"Jefe\"\nInput = \"what do ya want for nothing?\"\nOutput = 750c783e6ab0b503eaa86e310a5db738\n\nHMAC = MD5\nKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nInput = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\nOutput = 56be34521d144c88dbb8c733f0e8b3f6\n\n# HMAC tests from NIST test data\n\nHMAC = SHA1\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F\nOutput = 5FD596EE78D5553C8FF4E72D266DFD192366DA29\n\nHMAC = SHA1\nInput = \"Sample message for keylenblocklen, but the NIST test vectors have a misleading input.\nHMAC = SHA1\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60616263\nOutput = 2D51B2F7750E410584662E38F133435F4C4FD42A\n\nHMAC = SHA224\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F\nOutput = C7405E3AE058E8CD30B08B4140248581ED174CB34E1224BCC1EFC81B\n\nHMAC = SHA224\nInput = \"Sample message for keylenblocklen, but the NIST test vectors have a misleading input.\nHMAC = SHA224\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60616263\nOutput = 91C52509E5AF8531601AE6230099D90BEF88AAEFB961F4080ABC014D\n\nHMAC = SHA256\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F\nOutput = 8BB9A1DB9806F20DF7F77B82138C7914D174D59E13DC4D0169C9057B133E1D62\n\nHMAC = SHA256\nInput = \"Sample message for keylenblocklen, but the NIST test vectors have a misleading input.\nHMAC = SHA256\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60616263\nOutput = BDCCB6C72DDEADB500AE768386CB38CC41C63DBB0878DDB9C7A38A431B78378D\n\nHMAC = SHA384\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F\nOutput = 63C5DAA5E651847CA897C95814AB830BEDEDC7D25E83EEF9195CD45857A37F448947858F5AF50CC2B1B730DDF29671A9\n\nHMAC = SHA384\nInput = \"Sample message for keylenblocklen, but the NIST test vectors have a misleading input.\nHMAC = SHA384\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7\nOutput = 5B664436DF69B0CA22551231A3F0A3D5B4F97991713CFA84BFF4D0792EFF96C27DCCBBB6F79B65D548B40E8564CEF594\n\nHMAC = SHA512\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F\nOutput = FC25E240658CA785B7A811A8D3F7B4CA48CFA26A8A366BF2CD1F836B05FCB024BD36853081811D6CEA4216EBAD79DA1CFCB95EA4586B8A0CE356596A55FB1347\n\nHMAC = SHA512\nInput = \"Sample message for keylenblocklen, but the NIST test vectors have a misleading input.\nHMAC = SHA512\nInput = \"Sample message for keylen=blocklen\"\nKey = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7\nOutput = D93EC8D2DE1AD2A9957CB9B83F14E76AD6B5E0CCE285079A127D3B14BCCB7AA7286D4AC0D4CE64215F2BC9E6870B33D97438BE4AAA20CDA5C5A912B48B8E27F3\n\n# Additional HMAC tests from OpenSSL.\nHMAC = SHA1\nInput = \"My test data\"\nKey =\nOutput = 61afdecb95429ef494d61fdee15990cabf0826fc\n\nHMAC = SHA256\nInput = \"My test data\"\nKey =\nOutput = 2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776\n\nHMAC = SHA256\nInput = \"My test data\"\nKey = \"123456\"\nOutput = bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd\n\nHMAC = SHA1\nInput = \"My test data\"\nKey = \"12345\"\nOutput = 7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb\n", }; -static const size_t kLen49 = 158570; +static const size_t kLen59 = 317573; -static const char *kData49[] = { +static const char *kData59[] = { "mode = 0\nkdf_id = 1\naead_id = 1\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8\nskEm = 52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736\npkRm = 3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d\npkEm = 37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431\n# encryptions[0]\naad = 436f756e742d30\nct = f938558b5d72f1a23810b4be2ab4f84331acc02fc97babc53a52ae8218a355a96d8770ac83d07bea87e13c512a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = af2d7e9ac9ae7e270f46ba1f975be53c09f8d875bdc8535458c2494e8a6eab251c03d0c22a56b8ca42c2063b84\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = 498dfcabd92e8acedc281e85af1cb4e3e31c7dc394a1ca20e173cb72516491588d96a19ad4a683518973dcc180\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = 6b0f4cd351730cd25993d8ad0f11bff1ef2c3a957cb4d8694bb06c60a2937385da1b47a11595dd7a9a28f76c26\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 583bd32bc67a5994bb8ceaca813d369bca7b2a42408cddef5e22f880b631215a09fc0012bc69fccaa251c0246d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 23aff4f784452e70b6c2adc5c84237dae34a91246460f497b753822086fc8ae5fdd770f3c1637086e860535864\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = b101f7842383ab460f22dcf919e4bcc3f1004246db7b64a40e7add713838bda69c601c4287d351fc075de3f965\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = b46b92359b09f5b77efad33bd96c0068212a7652bb3db182c0e40cac71fdbae0ff213047384c969df46100c3ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = 49d450f5d0bdb3d8850cc9fe1ca5ffece5075280d3aea7b1a309d0ef2dbc71f7a3a4e32205e5c53a14ffbd7524\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = 2f8a3cbe444213a1fad01ad1b328e464f03edee81243bfdd5f1e67ca41ce14fbb0c00ae9a3f5c4dfe20e1a7bf9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = f5575c1560c23ba23ea1d919776cbe6e42829097d918dbff28583ecd2bcbbb7fb2a035ea1038eb435812e8bece\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 7809bff8c8f0122f1ac5f179443983ad0486ec3a3420353a6d91eae9ae3dd67f871c99a46054e04b96dd220fe2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = a5dadd95ac76b59aa9d2cfcace5c19eefa20ea4f9ae98f86bd1373fe19c930c2a9c31ee7fa7f96ff92885dfecf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = eecfbd7cc0ff49800c25b9dc9f0881893b275b7654c8560048a2a982663ced5860aeecde40e7e99c5512947ec5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = 9325ba3d4ae25b7494432993a1feec051f20d60afe19953c7f41463774b154be00e52fb29e25566a32358fd9d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = cb93b418d2070cb290a01565c413fff6f206d70c7e85512c35d109486f8e28950b1951f8d420ff1c58464afbce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 1d565b4c9b6fae2b7513a5a8ebb5285a8865734ce3f02cd7691449c60b1157c9a5b0d1c4b3ab8bf252a764a4f3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = a376dd08d1fcfc7d2fcc1bcb519cf9e10b6249fa9c02662e3d5f6cdda5e192034f19477a07f37adf6612c863f9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = a6d0fef032c38a97a76c95698270f779368cdefe837ebd39120bb867e34e3ff0e07112d48cf82624fb4996e5a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = 75494cf44a66b3930ae98865028c415329c326da8d0370d404c5f36da228a08754e67584bd07aa3a4a625a751d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = 0f24fad490d9a581a635516006ad7ff4ffa196ceebd6509ba6e172aa1b59da60bd2b3fcc374f956672377c4b40\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = b4f5b4147bbf66407d19fe5947c91d0b7eeb80dd3d97f8d10bd248126e92468dceeb8d75c0c4f90a5c9d04e538\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = b95636af74f15ef84a35b7a15b5d674bf2732c95e24f5cba6621dae03087778cdbaa3ce526000c18471044ef2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 80893e132d80f878575a5823b5a0f53cefb909350faba8b2be46a700f254f8dc8b627f39287b5e7dff4685b5e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = 3027f6ded51e5d1dc08055162c5ea4391ae78144a1bfcea76e78665e23b665351e5d294d785718b58bbf0cef20\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = 115013b0e9571fe5adbd2e6c8f2fb342413b45fa8774112def20afd37c837657bee0561ce5958cc62bc996c0bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 8a261c7bf47ad9955f14ed7d23e3af4a3c49207fd3bb861714c9562e01df89f67f5b4c204a3f9981ab81c215fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 1c4813e184dc263c495b6944bab183585c24d3f68c719580a51e6e2bd78c219f9e01f7db082a3a41a33c19b4d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = fa873313a5d313bae4724d007072e1294a066994efc2a68c28318f750806cb98c0b58c8eee565ce3d2bfcabccc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = a586d2e92499b32199a31a252fd5323c0b7483b0fe5568bbfd88d845d36396027f238b9a9a7a51a6921bd8786d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = f4edb9b76d8c3152bb52f8d58940bab09919f7d5b53d776c57d7b7decb0aeaf94f34ef0b7a5f1ee9ef0ee94b00\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = ac143d5f263851dbfb7f6332664f7bdb8d944bb519e2f9bd1d01340400563847e24b78edb0f833b50102857f28\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 01b0bf550b7b39f6ba0a3f5bd39b8e35fe1721fa08b32ec7adcf7da3d8a605027b456a88da073077c567aa9c23\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 7712235314485e61455a897b7b7965c656a4cf0ed9bbb7f156983a24d4520bcdd5b65afaeededb3296ec3cc9d8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = b7b5beccc1a1672179065992d1d4de75bf435509e0fd1a3ee6a4ea865de64f7387e54850ec463b878cd7808087\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = 1a6d8d50001d875e31f0c6a491359605369b18aad9e94bba37fc12de53a96e84bfd3bad47b98519b5de9936c10\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = f58d2816634c7cd43a4dc5c904817a0fcef4ae72e75f38d5b7376e7397998be48e10691e105bf259c33a01d8c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = 86edfe5fac0a7d0c91abd96b29be8617881c8dd60964628f93537e0d11f09bc4fa13abc4e57c1bc0df4f7b0600\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 922aa471310d038de267d919867fae99d54715563ae9f755ebd2ab48e9d45b8375fcf77e6ac8074f92d8b25546\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3", "9]\naad = 436f756e742d3339\nct = 79897532bbdf8cbbf3a1fc4aafe1fe12011810d25981ac2c1930a575cf3fe32324385c2898f7720a8764de677c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = b8ba5849c031f8089eb724c65d5eecba4a02fb03f26c9e185a2cd76cd8a6de803338b22b8fe8799ad6ad8ed62c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 0b64fb8a7eaf3be9e2d9e5e1ca87ffc34e812108303f6c983109acdb1a2b71ffcffd35e66ca16ebffcdde07db4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = cc83e8120748d0c2bf7a37a24265047817c54892231dfc105bc87c7e05704a1102e1b6cba77e59438eb8da18f0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = f2975c7f7ad4289936993a728334957160a716ec854d41df436a0f7ffd30134a3978d5161c86b3b72bfc667544\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = 2901f92e3749d8d4827a69bbb002769ac17995f9dab380de0e8f9e082137dc30e289893d18a8f21834a7a5d54b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = d1816064467cc47210eb25cab7ddc47cfb1a9aa5a3421f461e6266fa85c6de96afd430ee8e0fb29febbe947338\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 007fedbbfb53b8bed063e3dd5d0d0faf3cdaa8638c68259cc68e601ceebc3fa0d7aabf8eef6f6e2d356e8adcf8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 0451a985fd7ae7a22d7fb2e93f7fb4ad5bd8a49dc723b438feafc4650c02f3764668e728a95c89276dcdfc1ad5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = 999cb87e121a9adb7b6179b9a1f70434a9110ca25b72eea89c56481f83757e1b013ea0c3a17eb771e9ca641179\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = f6f8c9ea5029d30937571b85a750e5ca372f437f02ded4e4ccebb8f9a69c1cbde753e4000f272268254b0ee05b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 1497f44ec6d1396377a5f905fd779a4fc47779a5cc91f7471c52fa8d7e2355b779780919c762118b6d0ff4e197\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 302a216277bf30fd9907044192a2ed68c9f5bad7cc80f4a43b08d46199c21251eabf7f0a72349445d5553953b5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = 85fca2a350545edbdbc9dbae4ea0d53cf0c5c59e0c5ba3e0c78bc4191b83b775b7767a63175db8fa5d2b092ba9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = 54219f225567f98df7fa6c0843e08c382a352300c5f933b0eea585c97c83b8130f4fa006ea6f7d6c752f56f24d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 1c63c110d2bd3382f2d01869e7cb0c9c3cefce54a80d4652cf8b4013538d9a517586587edb01bd4436f844c8e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = 57150b1d36af3605fc66764ce07d5dafda5420d09c875a176945a43a1f718f1d868bea8b10ee8970bad900585a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = ae7431872eb110de13baf39a3cdc7aaa19f0dcd8e4a7a36590562f155600d421beed065b99bd5dafb60501aa84\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 9158e15fe9608e89913c13117fb78d61aef4ae6e4e1cf2e00214ac84ceb0da7ee0175e9a903a23d2d3be06e8da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = b1a6c9dffcc0ad109862cb1733e680bde703e726179f1df4dafbf832ac9b37a2cee9c997b522791ac1e166d175\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 8e12c961da22502ee54caf4ff7ef49a7197761a77ddba9f980077a0e7e5f025091e9762a79f4f6e06d793e6e8c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = a9662af8b1c5c322f54bf9016e1418595f267918cd6efef045bce86feb3a5b9fcae884dd21bbd44fe45543188f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = dedd1bae324ceb12428043686c4cde519e6f6e3b50977b6257a927f5cefea7c07fc2978f6aa3cc420e24a33ca6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = c20e3b06f604743449534e3f590b4398e8101098571b4971e07dba987869d5f75e30106efba025e31d543a333e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = aae857fa33d40cea2d5a7d7fc213013037709e86ed22d29bb7617dcb52c136a461d017d48d02006ff264cf8594\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = 3404b8a603fafa37ce6377a2b65cdd6c53e566750ffe0e95d4f7243cba3d044507c6792400a91a551e03076299\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = 4c2ed41a49485b292346afd28a798f2639f9078f9c5b0c318582e1cdf4cd84e723fd1b790f69828d4fb953ac1d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 26fd94cefb27a210d6669802c7cd439ea940a83fbf290eb0b9b7d166d8a0d31bdd623e4d2c3aaec44db15e4bcf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = 0707c98968bfee0343e9fabc86fc6b3a6910a4d2272feb3654b6f6f1c19c3251bbe1349519e8b720eec2b027f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 27efcf37b480d38abb0e721e9c9e27c48c5c55f8d9298e2d532fd3bbdb94d9ae0bc93c9f30e23292d50ce9bcae\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 8c7a06799181970e5e37afc7ba7b9c363e46670ea907047ba1b2020600a9f19fd3b497551602d287a7ddd04da8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = 01ef6860434c054d0d1bf7325c9cbd4e929b0da00b1fb486321da6aa59428b3dbeaecc653ff1f0a8c4e81d1fad\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = 5cb605f39231386b8d8566c1ccb7630475dbc2b9c98d63682e99102c63f8aa53e597a7ba0021d04d20c45ebf08\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 2f4be39a792de469e90417c537b00adb7dde3c5824126cb4d7173fce5f42ecf1d60e9ef94e7d46d2962aded25e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 1ac5d5a0282b8feda589a0b23b47563beb031b985e7beb21a20e2fcf05e952ed2e6bf6a5728e78d1a0ac44b3ef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = a612cbfcde1f6cc45960ca6487a99603cef7c6048b244702ecee87bd9fb4918ee1d9907c3cb2cb94f98aecb38c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = a67d7a21299f8ae24fa49eac42136378b37430577e251b1a4e10c5d0536627eb552499dad55a02f31c423d4959\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 55e2a69619637bb660194b78e8abab23940be918de9c328d11fe8718fbf716d4b20aa5f5af03c04625ee1097e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = 1e444851dbd27918d0b613584b57dba343db268fe3839e659400499c57e84dd07bdeb17241c0a63efaa5bff7eb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 5076032b4803292150299121c39ca9dbf6f7e63a397140c3c735c9c1a7b7c903bb4f1181b913f4602e5298b06c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = a3dafa222c1984f1a739c5438f64b5bcfeb237b18143e3fea787c01de8a06d07d148d9c89856643b65c850423c\npt = 4265617574792069732074727", "574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 86f3e8f09a8b6ffd31199a3a6589003158f7a264f74fdd90d9bbc1b5d1aa4d9832248f09499ed34332f37998ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 1ccda8e30aee17fe4420d55a6895316308b083beaa0bb4846044e842f70057f87813867a50ebf3c46a2a621e2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 9a8d9bef87933a6e6719f2d4b455898804d1f6b4f9b164d6782165ba190cf350c4513941d90bc1ef3fcff5f42f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = 72b9fb04b16ba1e4bf415508a10de5602dd220c70e2213698dde2093d976c14dd29d71f85165bc625764275a7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = c1e4550971e20406c6a4df36d82916b7ff21a623980efcb08f1bf3555b8a46ec6709088403dfec93bccb28082d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = d1734abd432ad375c7d07575723e1f62db2222cc6587a763d75273a65be3f2114537c2a15286b232b4b755609f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = fdb23db80f5b3f4cf7ca8372300d64dc22df49047f7ac08f2c87d61e565014064b9389af0b1b8ab192062cc0fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 9f7c1ae175825557a6bd4831c69b5c1b230310c5c148300b5063cf8a694dd68875ab99d9655881cf048ebc0f8f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = fac0b84ca769e8127647616fe2c1bc9b82e6ea7e30dca140bb8d9f51c15c46a19a07a9a6b4c3ed2c8f861c1ab9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = f8132abfbe8ceb59eb95e81d3fa2edf29a4edbdd1484fac75d234a4e337bb44c7c746df46dd7fc291368c91b0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 4b6b3757d40d0aabfdb386ca7dc035aff0db22792c4ed143c6c8974418dfb3b06716a757e7d57559e9e5bce53b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 7441092041f5daa0ccc3039c69b5b632bb940249b7f78570b603d07004d72de0f6fb99fa9c571981d795d84d9b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = aa32e2b8842f29b25f12ade4c13127c6fd35a54836ef41dbe60ef5c3a707940e5a965d1c3983aa2cafbb6b1953\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = 19b5e18fed35df03ec9666383f175a0feeb992b793262a3931a39cea5952a9240957280e763756e8e42bbb3282\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = 9e0e04a1169d08d1476b875ff38f08a0eecc92ae0594395cd7f23bc6639c5fb3954e2b9129775d21951f099b12\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 0ad315c17cd383eb41f9c0939327a6eb7cdfcd827a2941f2d3d8d1768eb031b7796a40570d2230616bb331e09a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 111d003e82c2b867f7989fa420dead7e2d41ec416cdae69d65d7864733f2d7b7dacd7a17512780c1119505bacf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = cc8e6220ebca8ab1053b893fb2460ec66ff28337b158c9efc5631af4fffe49cbc3b72a6524485bca11994dd0ed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = 94d7bf876d568146f05b2bf9bbb05a9debc2f64c1d285a4555a0de65b154d383c302b072eca2f65d12ce826148\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 8050d2ae9762a4c19bd422d6b94064bf8fabcdc87d98c8b048ab5ca03454201ec055488da7795cf06893c9a89a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = f85a67e67e44d24b009872fdcb3084225c2805df1ae029793d3320d5e4ce97c756b08b9f0f829b5b37cc07d6f0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = 39c90a0c218625591ff0c8dbf7f6e8e0ebf92279b1199b58b55e0a278d7f24051b6c733ce74a0b806d16c59eed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = db08e7fe6e307ae61042b2da2c46ead96171914f3b5668afa0aa55ecd00fa760b74bcad66ef8dce4e3f29ca2c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = 309d3e5fb0c51342033b438002d6e846555952921017177434444683a95d225e7ec4a3c14ad6e6ad6411facaec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = f27179ad35d2d96181dde3b6569a1ebcbf1fc151c5dbf14ce747fc109fb95e5732e99b08f91df32cc38be09a58\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = 246386a4bd5d7fe9a386a0b76269baba96b16378a07825c72f676bc76a4fb5d525786ed10da6baeffb897848a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = d977676edf9981c83672c3e062a3251e2e07b6fbdfdc139f678afe90832009102f28fe4b63be25374c4dc20db1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = ea17beb33f417dace9dadc51702e2baf43dcdce364abc1f70e9c73e134a102413e10916bd2d128b7f64ff24698\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = 931cd288f6a18fcb9b836176bc49918d8c6b8d24fce3b26782ba6323e0d01f0ed542c666d69a5e1adf8e28f88d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = d5dd7cc956759e1b2eb99cf049e8eea9d754de9617f308f9f215a3c1d7cc76b88c7b45eb66a1ea414f10f8bfa8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = bb407a18faa9f580fc417725f6d8f3a3f5d7972711f7adcdb7a79d5e2db9668ca444d6045891590a384c3cc57d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = 8e7949a490d9e1893766586fa30ab84ad1de6379a1fcc5c73700b748576a3726da32036e08b166227257409393\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = d81c4ce027db2322d6f450736279d5954502a7b4a4a60e58a4454443ed9243de2b805cd6a44de1e815377fd917\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = d50c4ec8148090f231ed8c5beb042c01f12923fb8ac6043325434fcbf5075b1e629e23d7ffb50c38c61974527f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 059f89e9d8c1a2a81fcb9fc08328396b83339ec2583d6582161af67944819283a2c8216ac717fe3c52564b6c4a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 48f4723289cded2b3186dc81adec430dc462f3dff6a1fe76c113a105f15efdfcb61618456b4ea514b0f94ac049\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = 36914027bc50597d58312645d452b4956d51730831d4087494bf55d243b682e706baf4af30fc140d4c7e8760b0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 5bf15badff51ad5902e80fb019bf22c7de3828ac70717b0e093ce03d0d5e31f807923cf2adbed8d148a95e20c2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 0afd4ae86b1006d622cfebc369ab16db3fdb6f5a35613016a015d1e99ba3e3c978df4d0d35d0a2f9f06fafaee5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = 961fe5dbee9b80900d894136c48d9b2f72f333d33c9e3dd6f7b6e220831805859fe70fef5c8d2e0779c035ff02\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = ea658fd7a", "0ed32f79b9bd882573c0868906c822dab424309ebe0ce6a88904bdfc21f1b7d623b43bb1801f15acb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 8853f1ef5e1d958ba00066d6ced600ec672755e904073acf7b74df8b97fae9f6222c85a45c18e0366c29ea110b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 503c748de0c1174fe461ea8df059c6adbda02c71e4ca7975265df346ee0e5447d7e1c99af8fbf987d020dc771c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = 1101d759affd853b3f4736a5d391fabddd995904d0ac652e54748d87ae86575aff30bbf9b7aef4f5467bfa255d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 5e46ab28a07f3de79e03c243c7d0741aa614117c333ee6284d34ae3bec5d5344ba7104b22926c89d3b59304713\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = 18bbc207f373454ad2bcc58e9b28aa1dc922143f75a87e3c11f2458016004b7c5cba4880487d8480b61d6000d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = 235dbbcecc9392c8fba97a87f863cdb9784f1d48ac77fbc057246d73f9e6323ef85d943b18135e3e012e1e4750\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 60827c015db2567c68c661cf420e7c7bd5be7f661f4f1d216f9daa27c5a81d75863ea192a6718ebec30c2cd629\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = 63a7e13e09042c69d0916be813447cc6fd6b7fee47490b3c5db971be9eaede73365c9366dd26c89287c3d8dba8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = f15b689482db2265e05c44ab8a90bf11a53b92a5f0d6e4fa51fee4a2827c601c7b9c122ddf61a6f581b2d85a1e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = bb0529cba02d94fc92ebe189bc617e9f571babd9c538dd7b523fac4e4a3787f6f7431cd647006be35ebc3f0e73\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = bdf79bd98a347628236e8e157750be734568ce7a7bcd809f02d8fa368f1b2abf919299bb95ba6758072467df8d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 8ae59a9f501b706ccaec2ae1d9cc1e3b7e7536ce597209467f0abb1d267f2e95bcd4110e3d273023e08fb96785\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = 1e50d69ca00c1baa367e275142c2cbb1559e9e10a85d884860a072f25a5ee7fd998d03b087b4ca08a6d2fe675b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = cd80cc084cbf005ab0c6b9c66c35d4095d4ad766c08679a3659f227c63d8f2c5cdc52120293d15832bbf60506c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = f2376bd77b970f0cd5eaa7e0ad3acd6a3cd26ab4983abf90c9e6539c6e86a9ecf811f81e8d3e783b93c79be8de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = d22ad9245afca25fab8ae95839627c441e7725a26af2c304f53f502046f4362d271b05eb18f47b7e05cde96820\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 6d0366868f9b70d94473a970da7cc4c578d5bf524a26e5e6199081f5eb415927d3e26e09d35d63662e5df62fe9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = 25f9c6fce909bbf3410cc30043a9bd260cc904596bdcf06d72222e28f064cd76af537a4fe9eb9af71177105988\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 719e4a1b6614c03f9037c0a10003a049694e28058b68e3132736379f90d58d0be068a753e53a20c3d3b192e75c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = c2c152e46f9251690f55bdc7c5af4dae14c4f06582e4b5cb7a4b96eb5f701d1814cb45ae1ac47eae995f0f5d99\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 84410bd0ec355bc8cc211ae24abf5617162482ce4ad5166e6f13b226f72cdb2cb7c0860c951236dd3d0160d0b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 3e6a88dc89ffabff1ad6588fec8689cc52929971453196eebbe4b45c8f9a79500d9a3409f8bc27ca78c721b72c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 7fcaa5fe7dd8486979b02b54afcbb6f501dc34499be44ebc22cb4f784c418984ce24631c523e6337c5ddd2fa80\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 88179dcd9ca8c32836f1af6fea05348fb324f4174e7d7a89e5a54cfd39d279ff2b7cf15c84e282bd1c0f178d1c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = 7634f5a7030b11c1705091ecf529c63ccec7f41be49aae971ada75a8fab0604d1492646379b7af472df35a86fc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 4a7c938a42b31ac4e8f2cdb1041e81a091102bf594e23c757e383f402575680165359e7e2c9a3ed456aca43279\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 1f46e0f23c790848ca075e891e56e054d81be03cf8fda8a7dcfd9c66d00415890392feb0fe6ff9302491847198\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = b6da4466f0e2d1825294a5def483a7815d05b6885aee96748f765f81976429ce1b9c1dd172ca7cc7d2c2e54543\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 4789c93ecf8fc2e795141c476279e114c38f356717624212490d99c880ea3a758efb0a0704a852fcde39861111\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = e1b6edab620f9e8976b4546d76cb0a2202a7650a09da7f087c0b576aed17c3b55abe05cdfe4fb04646acabd894\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = d19badb722ea912916fbf04a5d0934a064c02ecfbf090fb22a38736543f3657088534da16fac2890c7ec22019b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = 27b3fd302f3ca57ae14797a83369d81c3126d6b3bc727769e969997e7845b396d13d666cf435e9cbe120b67b9b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 7c93908f4105929b8aaf70b9192646770a6f1a71320b831ada5f37781791704207e54a5d661b4931d421699778\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = b7301cb3436295e21e47fec0c2a359889f37f08c73c6d79a33830b5c569cf6e1046b0b9a749fa74543cf85004c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = f28de8114f5b7f5c087f69afe59ced3b604804eecff48117a0ad6d5f8ce04180a836f5dec8d7b9ac65e5e9c3dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = 1b58a1930c3d7c4189236bf01b0ee9027ebe20b7b77fce05c071b876580bff086bdc7f11ce9c004496484f4911\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = ba598857d0babfd1cba4f71d20d4eea53dfa33be01b6f2737513e77a074158444571ec20aca80c8d551e63fad9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = dcbdd4b149f6ae366db71cd423939a40aa45270caed006e75af1aa631f078b9ea1ef7a122a2c259288556eff94\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 7be6976ccf214d7fb17da9eb81f4e25384e81c130cb9befe6402d2b22abc8eb34b2eb9f6ac5c1689862c6d155e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 512e0c36c83568e6bd92ed17a3498450a86ad7160", "6b62506972e513a6390e671c85f0228dcb4c50fcf75ced46c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = 38b355ae0f37ded45f072cc83cc87e5db9d9146ac0bd2385a68019ccef3cfdfa860299840781ff23bab90f721c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = 475e9083f2dc04290d8c22d4c292b05e0ab5d368897a672603abceb6278ece0d5c1a98d866a3a95ad738fde731\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = dbcb8b3a6dbd506d997cb38b24a2fbfa4fd67e1a2caaa04baa7c46f56b5bc73c89f7c1f9c16489afb4f5c67649\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = 905f223bd677ff36128f9116c5914a1940ac6b5c6b43fea7576f01c0061e51fd44229d3dcf90d520c5d9bc64ca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 199768bb108c0a1a8f06e7e7b5606277f9e169d25d3e1df3cbc6731e703f04dd0c2bdabeaf10322380f759740b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 391ea01a5d7514bf1209856e8d3e9b54550ee3816cb8811f1e99eec6e029966a660e7b5a43e0cc15d15fa77887\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = ed6cfd07e862b831c989e2a2e354c7783ad198d7bc43eb0fed5429ad6a4ae4a105d2a95e84f95ef303e6bafe23\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 6afa3f15edaa4f5d5f3f9ba43a81b85d472cadd7ddf57268131122def053aecb40df6f2efba6c6f182ca8f6e5a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = a13e64ba419d4cbeedcc7feed6ce98baaea38eebd2444afa3bf3783c3cb365ab2dbcaae354d91695551c30f361\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 042dd17136514522d9e851a5dcd3f1b7a6d32f5f9401858680e29d07f5801552a976c80449cbdfe8ba42d76cb3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = 2197c7373ab0406d2b2a10b980412297b3b02a8703608b649fcb707dfcbae50fc2aa0cd6219e9008f226bfa63d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = f11ecc24c15ade47ccc5ec7456d4d7ce0ff90d69875ecb901b1cb235cd11bbe94f5751784fddd5aa81071220f8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = f70ab7e2c3a2aa02c025b04abaaf7f87157b1ba10f8701d6dbebd799061d3ffee2cd443db521a741b363b3dd01\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 03bea1e16afeee73ab161f075dd5b1c9b84f13d33e3e6ec56e50ee6dc69714348741994e91913a2cd624f99dbc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = 8e5f558d4df3e7aeb17ca1be524b6b5a33a2d2b644a96cbcd62c3d03b83c09b106808fddd1724591676dff69a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 9d933bf7e3cbd7902e37e0f30646edeb898ca0ba4da7f7ef75967d525cc074901933d70de411cf7d8a0c85eeb6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = 2cbce6bfca6f4951bb3a784054524e67c0d07239536fed8506bd873bfbf9067748e42e62541233f7508eab4e4a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = 716a28254162bc0219c4664d8f6a9e46b18cc036a714c414b46f7a204b1cf457832b1b8eadf722a533b70fdba6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 6275dc094e6c92a7bc1d81479860fc2ac3ae072a8a55fbcdd98f0ea326eb6ff8363748cf8630fbecd89bf06800\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = 84de0169819a6edf0e3dfefcc508fd852ec4d672fe95ca4bf435769b1a984e014a328c19278a03fa376cb1b03b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = 2ba22d3644fd8a8db6b78737e5ef13bfaab8b2e28d1996f3605a4003c32085fef13213399bf53b96dcb1caf58e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = ccee2c9d252ba25e26a1481c207457deb29943e428c468dfa6fd8b2966abbf799314cc54c650241e721478960e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = be78ccc2fda5e94b6388b8d0d5d0ef843a5938d1d7ca60177b035565de27cec31d93555dd2a002d0b93e52da3b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = b31fd66aad180524619cefe6ade2d251fb17642da158e1aa631f709d4d105e61fe6b01195240a16193063e8ab3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = af59d3e7a79594b3bbe8db4ce984f0ba255ca4faea025fff25293a4b9e971056f7ca2ba63d8ced8d011526bcda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = 12ba779fc44fb80985eba7f2386a350182bd744482c297689d4e0defde46bd3d5bd9bfb2565b24345895bf8bf2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 115d0082028ba6c0320478122223c1ed244cf0072360a5016ad6bb094d5b2da9cf06187ebc1a8a079ec48b024c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = 3277b0ffbac6e471af3b7677c47d2b20e66357929fb25677b724c4fe7bafa318fad5655bfb655c0f407256ee1e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 673ecb10c28ab0ccfd3deb1380c60c36b1e8e0d5c4f4717236410a42dd3dd9cd90f312ec8730cea961386530a2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 94478d99db8d0a98f3e3051b88d97819e0bc33be2e78c812cb6244593bba7a53859b45e1e6d7b68c2915734fb8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = 2d6e3998937c32be83549ee659d16650f90d2d0c09c2c5eb5b0df28c2b94b6aa25ddf17528344497dfc49409e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = 4048d5bc45e25b47b0017d77e8b3e2f44264d25cb8fe0957e8c80e0d124fa4d0e021b062e2009a7aecfe8f21fc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = aadbc15cb8b2e2e41521a8bd340de45e9223c9df1c6b7a12a55dbf1b25ce4a5a617cc740030bde488f62de396e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = fcfbac7cd22d7fe25e0a880098b2d75fce7b16315da1fdcdf2d3cd283dbeab28a4b3219afc9bd4b0ed6942358b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = d218751ce5ece2e9ab6f3e587ea3d7cc0c50daed6be792aace4cb10e87a533dd1626d10bfe484f76acdc93ac9a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = 0882ae25221dbeea0b136617e3784a785e781155b71636bc49da7519a715328cee6b8c879c7388d8148bc2f835\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = f148e482589471084200325c984b56ecf299bacbac95ab75490ec465d675a7b6cf22d52c8566db75b6c4716d16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = c1bd637a6a2b207d6cc5651086de001564c651ef65cad565ff5aa9280101388f22377241485784df3bd6634efc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = acbc6056a256021ff7656fdec4d2dd666ab8b56cd6bf7e71e4c8b7869ff3b0e7a86cb9afec806f396bebd7eaf1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = b04c4eba94ca076512dd4bd4c3c4de3a849e9a45d4d085ae0276fbdad1f0b38de7d72405a", "ffd06962d5157f20a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = 9f8e175be965e0b0fd6746cd1a834dd8ba515563a2b55b4e373e19a45d5ad781acc68d7d9bb92853ca3f9e4451\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 3ee67fba41dc7f010e069659bfd1e103cff3c481a6942b50657c53e64a0a39da426f3adda075bcf605d283d5ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = 8774c1df4da8b2b2a31a9c422c9437189626721e265f26f5fa871d3f60c53e677bb911a870601608724f34d504\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 267afd21052c656a3dbd834d884e9fdb4c40b4b90f06a769d6b19735a991f4c33d147e1f3b088c3e869d47620e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = e24a9fa31932da3acbc15a1295fad6e19289b58748c514cd26eec61b30ce899c5aca795c7a9d7ac69d9f497fdc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = 750b5c5aff3632b31a4db3c16d2f619244da9014c4df85005e9a4e4e64417bafe3f1fe536afaa6347c231edaf5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = 364a6f2e20856d6fc6514f0bb908f69c96406a86186b64009e3ee51345dac0898502413e46975673af776c3a13\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = 9f7618df484f16517f8dc338455b24877f4a13edff575ae9a15a0c7182dd7b42a676334ad2d49f60280bf7b590\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 5fcad7847f7c3a09a360c910cb9902ac5de72abd9d665b837be1ebbba52c4b5aaf097b8f250cce2f2391755dc5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = 86a9b61e7f1ce39aec4561e4794462f6e26d901192320377a599372d20f186bfe4689a1bd28a477c32fd72d6c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 8eeed56b89ee9d09984582a43c774d09a9243d930afa527e5d8a0fe2981530e4f3a1b645875099195952b5f941\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = a1d4df87741154f6e27ca6b581b4f0920c7ccba250ad97aec67ea68885cd4a5e5df209505911724cda01490c0a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = a26c3dd33c49bd19c789f50d8b63b2aea70fc99ee5cb8018bb3909280a8a7e49cd0297eef454f432fe41411e86\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = dd8dfa615c3915f066ce14069be8a46b87eca498831ce2814657545e00c25308fb57d4d90350cfe187dc02d23e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = 53c56d8d123062812b589b2546e0bc26a1f21c43210f3959465e072957742020eaa8cb889aea759747f1d3f0bc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 29f3356dfab7668dcdb1453a603788d87b94cd6973c1a5621f81b21b74aed2f291c78982870b123ca3f6e914a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 61cea4a7385001e55c5f9070da9301fb2f0d342ed3cbcc2d73790207dda81f72f5e7426abbc9c88099da54128f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = 4fe3039e14b0f29339fbb51341e7c34e975fb5c88771555f97c7e54484bafd4576fd5f30de25e533b9012581f3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 9ed04bcf46533f6ddcbbf2d08a2ed12a15fc811bf42a642b7debeb4ff749eafa5b16cb4ec7b4000cf4c53fdf1c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = ae11d77d8893ccd77f25c85cd1916aff2b9d08ef726f27b8ed5a6a6a01480f235019204197d19d4e18269fb7c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = 05983cbb9bf73d6b78979db91e265ab05ccd892ad878334885ee1b59fdcca00cfbcf7ae78a7ce56b40391e287a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = 49257b519caca28e64b4bce0905aba5c6beb6381cc1bf541a9b75cc0fad19bcb3c033b9d5ca3c094bf0f56cca7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = 6d0564b09411152a344199bafe764ebd0a1a78c3ed2ec09b74fedb159ef8d73bcd08d0360898c85616d36436dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = d6a4a22e7deaba659ddfc4fff641e540ebf4e5a45b4f69fedd2e06fae3d2f67cbb5c4ecd8320377ef358a82de2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 6f0493e3530818e079ea36a379749c060cea93711b175595bc2a90d8040bd8ad1084bdbf5ca11f0d5f75683434\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = e66f93ca92944c7dd2001db9ab020c4207e63ad2599e37396c1fc637cffbca229df6340766483daaee69e95fcd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = c1eca5247afe4c933db5e0bd8963376eb9dba1691149b256c18dc120ea3ce6176fa0317538aede743fa9642fbc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = dfa1b227f043ad79bdc8c881168c7a00365e577238856fec72d445a210080c24064fd9498702c7cd8b03870e02\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 590af9651e02ec8c62a0d60c47c56d60f19e57fc3867ce1b064ae78beea37a4c6d4263d7e7e93ad42f2e668eb1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = fd5f871f8806423284621ac03b819953baf5876b1f4dac817b2f263adddad4c20f76bcbedbd42ee0132d65830f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = fa64f0a324bae6de6fc8722c515dda3395f54a5bd6ab4efdcebd019d0fe85a64ee3f3d741f7f78687fce73523b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 547f4b565b0379029f44e39af706387b33ab6648a97ff0ab783b4d440eb7db3140b1064d400bfb53d7d86ec7d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = f3a39bbf0c8d8b56743929792849d3ef87bc4888a89c5ea531684f085181542bb8f0688b5e8ddc2773d74eeacd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = 0e968243ec434cf4404eb385f5d7a6ff5cfc1cc6af2727b099633e09756d9d8f26cb1489ef2fb3d032acbca7e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 995ef7b92fcb80c178fe542af57d55cfc18a6b29dfeb2704b2c2b03e88acc57219c600d8dbfd8916fdb5d433db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = e2c782d717f5b85e73a8621768ca07e9a9b96bcc0c6ba07bbb26890c156d2cbd39fea55453fddbe42a846acd5e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = c779ddc174b893b8a5ead7dc19af506d2f5ad25cd403bebeefebbef9cbddf0fd6a10886db0e2fbfb1b86444c38\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 8a6dd08102216ad3331cbd6431de11071961b9dd54e90421dba81635584c3943cbb2132a9f9dc5b090452cb49a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = a948cc86fabc81c0987133a29ebc8ba1845c879f186ef535839fabf7dbeecbb121b3437f13a9da2ad8c5a48a2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 60d6dfa5156994bac2180ef5066b0bcb48ba87c1f536d26d722ff8a20c43724365e3e8ea0068171d038781cffc\npt = 426561757", - "4792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 2a1a9c7b573fab29b027275cc862c9f1b1a97dcc623f836ab2e20af97b69b576f5ffef41ff8f85d25a3476d25b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 7a529533655d8f51640bf95469e06f9e33b7552ed1317804d7810f6376865290a15775f8bd7234f55ce2a7cf1f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 4ac01212f7e04167219c9bbcf0b814072f9f65fa4f3a31c5212af2d402c74c8c01de3c03334c6913e5da9670a2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 215c945d815eadbb50b4730f829faa5668678dda90fe88bfd2fc09198c000a60e3b88e7dfaaf9ef04420d0ae48\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = b27f5b4f1c063594de303b7c7f44f8e5c2f89c1890c2bbcbe31b5f52cabc1fc770c9a9f6e87128018b09153625\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 49f88fdaef767f6916a2a03a65589e7817807b4f43b2094797fdede6557bdeca3bb3428b8928cb3df940e18186\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = 5d3a0833027462cc7832edbf0743f8aad86d4ba7ba5ed1c2400a28f86e1b78fa970cc56cfded2604255341ec0b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 6125484ccc89fdda010b6b33f61f0afe10b1b054696a350ee7e11fad8e825f357583570d5ba9eb9e0b28768e9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = fed0d0d35ad396c05bab1ed230fbfcd8f73f3c099f73eed5818e210541de593cb8b693076c2a3f087e8bea2513\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 00f9721ca2fa4a05788164cb72eac9422393424b4e77f2901f673916cbfca31f38b7f4b1fd7dfb3bf5ed34c223\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = cd8124fce8c715d4491195b8e5bbb251539993077e9ca54729e3e42f3e4c8960532df32e8d7d1ede799cabbd2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = ebfbfeb6c55bb671f7a557e231f8f6cf745b0fa7f38d47f9118fb6cb62a638f4eb8e09719d2614b18dce1ae766\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = dc0339625b508a9836c1b54ccf43d76d969e933d0625c31e75a45c07b399dc3321a69718829a9571f52b714486\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = 7650cc7b7a1b07eeda0b6de063a4fd423a5cce9dcde1720d210d3fd3a03968e4ca8889a2f18b6abab7f5dc1ef2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 7175db9717964058640a3a11fb9007941a5d1757fda1a6935c805c21af32505bf106deefec4a49ac38d71c9e0a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 957f9800542b0b8891badb026d79cc54597cb2d225b54c00c5238c25d05c30e3fbeda97d2e0e1aba483a2df9f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 3853fe2b4035195a573ffc53856e77058e15d9ea064de3e59f4961d0095250ee\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 2e8f0b54673c7029649d4eb9d5e33bf1872cf76d623ff164ac185da9e88c21a5\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = e9e43065102c3836401bed8c3c3c75ae46be1639869391d62c61f1ec7af54931\n\nmode = 0\nkdf_id = 1\naead_id = 2\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 497b4502664cfea5d5af0b39934dac72242a74f8480451e1aee7d6a53320333d\nskEm = 179d4b53b6365c45b600c4163b61d95cbc2f4d9e36f1695558dce265ab8bab11\npkRm = 430f4b9859665145a6b1ba274024487bd66f03a2dd577d7753c68d7d7d00c00c\npkEm = 6c93e09869df3402d7bf231bf540fadd35cd56be14f97178f0954db94b7fc256\n# encryptions[0]\naad = 436f756e742d30\nct = e5d84cd531cfb583096e7cfa9641bd3079cf3a91cda813c52deb5f512be9931980a41de125a925cdad859d5b7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 2c43aff25343fdbff864506f0818b9d87df84ea01b1a2144d23b4d40c26bf655fdf197fe40297a8aebeed5cc2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = e0a8f2cf92ff61215edbb8c55dc31fe9e2eb42a5685867bb6854211542099f9e940c4b41c192bc390835b1a5f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = a8ea1deafbe4935d0d484a026301a339d4668c43c37f5e289bf758c7aeb3e2812d0321c12b71978855883420c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 448a8892f261cbb6bf5b7b64a4fae8a2c86492494b069c10525895d871c27c2f12cd17e0588fedaba9f7b0cd4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 97c746402aa3728594f8c4f217d1e4059dae56c5fb401025ff601a61da903f2706355685954b2fdd518b81ef79\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 91fe133508fe3fa6905ce19e6c8aba53994c168664088a2cd4300238236dcc90b5d2510d4315dfa8dc34bca821\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = 641346e222a57bd4cf1f0e6a6039c77c1684e6d01c8983b568552d338f080f1bf22d022a5ae863e12191aebc7f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = fc8446f5867c639c4c3f64079b2bee8987180b88e789a64297b91107886d739ec8f492e252bcdfb008cd6e061a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = c21ce89d9947297e1de30d9a59c0815ff1508a8930f63a91d29ed89bf2a20029830728045cd54d8a00b06f3520\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = 8c26159d7fb4c50cf29b0fd2d005d9a04dd42402f8e4e1dc9e2dd7cd0cf807f5b5a230554127c85510f95d945f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 75af5386f4a2d4a27dd20a490d1feb261dae8206a3201c02ab48ede53d2a92523a6105ab80bda1dbc1fe8e8deb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 1c8873e7af703e1e8f8085ee385e694173c9fe2d66cbdec2bdce1b3ace52c13d0ff321b41d8ce95bdce73c38ba\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = 10ce2c23ffa22de0f547b33afa2f34552200ae764c65d2acf6a5366e4d2c6dbd6614d964574b97687963b93400\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = fb0e6d7705e829ab6509668862e65136cd0fd2cbe83a158c832ba630a2eceac6042019ec726aaee793961c663e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = 4bd36bb99b6035a3ccd5f41998b6d49d5562c72225ddbdc82e38d5be180e6b0e69abe68d12be85239a664ac672\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 1a1916713004d3a90c8651e9781a759e63eb70bf1d74db5d3871e01f4664ea5241035f9a09c50c7c64b877a2ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = 510ffbb00d709b3ce27bea8b8202f2fad82632d6429992b4c0f71728bb3291f20f696c4d2abd942dc9a8960b39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = 25695fc573d452c33f7bb8f61a30d1719c75637cef9bd9c11e4b48583d926fed3a31ecacf54bcdaf42d7927f98\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = 913948ede40a023565bfd70f5f47c37ba2506e09b22d4784374659c90da556d3ecdef17e89b8f749e266f11b46\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = 3fd6c17dba8dbb2a4a0a5cd99aa0f1288f0f5bb02b720243d6b7c1cc92621c1efd0dae437ca54a67e2b", - "3127f76\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = a42358de18cb5495cff2729069fe0eb7996dbaf2138ec00f570107eca2a7c6950b9670b4ec66795de04685c2a7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = 18b1f565922a8e9d58959adcf3cb25a3a907d2adb69d71e19c09268f173157f569b1d4279c93f840d08b746b4a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 34355c72a3581d4eacb5269e76f920a77242cf7525c8d734afe8921c87deaa0780ecf5998af6e5f84ecd689048\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = ca6ded0b04e98db9bf3e62a3cd5604678e805c3ea8a8c5c390b29977662a344791b443d0aba785bd8b9fec65dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = d9065c203b0782caeb631af2ad08d685fe121033ba52b94608557bcfc8007adf68e2c77a4b6a475ce1171b70d5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 27d600688c31400608c332d1af2bfadc89d22739e3cc06d6f0f1b356a61e214f5b0ddbf7caf47b71d2be8cefb1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 9ed3e280b8605d721509cedbce556ee4429aeb48c0fcd400e30d21074ed902ce77589ac1f5d282ff1bddfa8cfc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 3eb0855fa879f7dc8335b5d426a440f19acdc0fc721532304de51323464707643b40d54812599670936eed2208\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = fffd265116539bf8b564f012fe3ec3a9dfccd9a5b9dc4ad9e2964e794c764ed63a759dcdef61ad043f7588a11b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = 9e7fd0052e15aa19e46050a2661febaf6c5f326caa52dc439eef425662661388fb9a9be58ed989760a7494d3b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 3693b73981435ddc8b081186f7a7f06fb4a20eb7c39c147f6db5cddb47e2f29f60f909c4504b2b789ddfb8e40b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 78fb4fbcb3de5bf9230fd0e41aab0b2899f331a4d806423d2a7cf91110b06ed76146a9b815fc0f5b1941d24de6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 8030cb70867979059a6e5848feb3c25f7504458da998c831594371141c868715578f3a62ed71dff8aff1afa2c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 89488d044633eebb4a41f649bf3a5f1d17affd9d5d9baf5132c71f8ad057aea36fd31ff72fc78d6880444696f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = 4ef51de05e1e02e6a15e30d313a8905ec12e35adb3fdc6ce79ae56dc348e1a636531fabf5e2c78962d492bc0f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = 2242a8228e57ca15267e01abfe430f1d6e4aabada7e38f17f20df015657d81aa898d2291c631773628f8833e9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = 8d71a286ec6f330462aebcfe15a2e3b3382eee9fd2e57123565bb1aeb319112e9e53418a2bd48d16f68a59ca5c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 87e2b695e365860db3f4653bc16bbe0389dcf225838cfb1c480442899d38a204c474565039e3e120848257c1a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = 86adae7eee8d06e9a8855672e7cb80276deba65f0b5d17e5e8ef0cf80189e69c62187605ec2329330264127063\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = ce603ee533d23f2f902aa82adf76c98a30d0c5865079840acc8ff62e7c774db66b3cb758137efd3134d790ec13\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 904d3c71ad0a4f8d6a0f087fcd93059cc19da7c9983b59da32f83a614ffdd9cf65f0eb8bc2fe3ee64a4f5c4981\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 71dfd30756f262628af5e5293a624eb219d2ef6d323d37096a2a94db6308e752f9659cba28d9072b71946d7868\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = 4f0d84759f83d02f49152f5852121e863ff3732bff98915799be5c8d5cfebfa2048ed83c0380888028f7dc081b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = dbb775112c824b1ff0689cb13ee056d84615d7c0604de71a825bf6998c41623d66124e7b871c7fc2ad4887ecda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = db01d24f44d167d78a9bff68828aa4340f99ff89e045476c4e918438801a02bfae77ad4161c298d958702535e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 59ae01cfcc784d69f25c005e9dec4b7f74bc05f284166ed5a056918eae0d9e1a83fd028a52f9e6dc6ded369941\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 8a5e074f9f14ffcaead4aaf599a97a8dd791c44833bd6676a09b7b87e29f1237ee926550d80a44378f025f650f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = c86b3b47535fd4c11610a1830a2847c6f7c7338d96656f8d04453edd1f5842af3397c6f762bbb39d4730f043fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = 053e3ec87d82425c627ed4c2d84ada5cc0b5253d6ae1cfbacff5c78f377f3c09ac89257d551772f6d2e053b344\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 73a145c830aee75e0fea9e3c7bfa24c9a5b1c0602683a5502fc83dc4a087e0a9c9b142dccdbd3205fa22cad268\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 98d8fb2a4bf5f772880010e4cdfdd992360189f45fe418f3736255423e60657a2a01c3e60b54d3efa932d090c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = b8abe4d887990e1e527a8b7c2ffd661dd4b65c618d7afe742281bddcb39c8be07c143b061bc607b4a8f41a3fd5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = 1090be42c502b75570c25a9b74777a4f3c981992156a9dae81c1f3a637c388ad55a42782f3785eda7fc00ed9bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 2ed5cd3dd937bcc54bc8193cd81420350e5a94f233bf52428dade8033de59a4bd0d461c7680fee19d3eaa49790\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = da16bc9c2b04ac234af1d2bbd11bb4bbfe6b32864e7381ac73604b2a870e7b8aaf10b128d8ca39b4e3f0ece26b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = f0d9acf36f857f86e02b06348e94d0fed7fb010d4e6365177ceba970c1a17e7f472240dbc585ee0cb137cd3b70\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 32199e20199904c07595fc6e9307022a0548f8f56ccf664497b840ca50176a05c72469c3231e4220544114054a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 257884a96d90d927de623709a39cb34a5981007676ba96b2e1e4e3ff7dfc499acb265dbb4e1812428d5ae31514\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 6e37fd96cc41de256d9363d9eb27868304ed5d979da469fcac98b4509719b10a8ed0c205abb05c7d2c9afb34bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = 7bfb5b966d1a92d893c0bc4ac5526a8a104ad929053d09481538b731c3e164ec46b4a6e6849ff1b6f732f3109f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = 8a70b13706ba38fb0b279449984a4df520", - "3c05d242bd7e6af70c9e96cb556abd9088f8e9b28121d050ed74908d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = 44dd0d86d69344f086f4bbc3b75f04b1a5eade98e4d22ff130a28b4f0c60f7db23fe2c30c3e2f8269719b57dc1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 946181d28098f47928bef7199f777dd0d2653f08c326bfd10090b47bcd294735dca636428bad26d0c186ff56dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = e080406e00c83bed2e94537263727d65ce99534cad2279dbf119eeb614cc5ba0b9103b7497fddd7b149579bad1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = a86551ee5f2b9cced52e1fe1cca9a8f7e63065515787ea7f4f9f4ff51bbd7698a79bfb853913c96fd714694b8e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = f450c832f51334c08e08461d087ea1d3b475ea1964e3075e41b227a57b6f8cf2b9ea8838d54784d0c533d5b5c8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = c25e6034c2c2283f5b8e6b7f659ee33eeaf3401ef43a81dc3d8ffbb9e7a32370311ceeba97c6a6287d3786321e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 5c30e2053f7f1501eb430edccca9cbc90f01b03200ece329b232fe0a4a9baf418adf846d402c2443fbd72aa360\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 9df08200e50ce71aaa016d6f18768803a8bfd20ad405345f4cbe60cb28164eb897e5ad2675c90595d0df83b662\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = 56fb1c4a86f4642fe820f60b440e59be913ab632de2027defee6161e627ebd78fd30a606f119070460cba0aacd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = a8163438d8ea48dfdaa8ee0286efb83747796263c11e97cf910f8b56adef3f6bcc12c2aa885323d641985116ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 10a66fd85dee2f3179efe704174f2fa4fdf0dc3839c6ba06a39f947dcd9422a32fb5b7df5d6a467bb0c5035d32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 50384f9efe0ae3adb9c834114862e989995ce080f353f0727c4ab2d41911755d154b4eb0a693b0e72124c465b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = f74ad7b18fee3ca88f91c653102e6b877e1f8ceb73a3a5bd44323ba5194ac722e87e0656121001c39653bf2822\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = 3d0b638910c26c035444b494342b5059eaa485d51d49a7526bf5a76cf18ce92be1e88922f1ba27db8f29a3bc17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 4d17c2da2c4688c5ae15be76b2fedab1d677065ea79a452f3cd01c12926ef4991cbe8be7e7e5e69cf2666121d6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = 7aa7ebe84cf4c35dccf15682fdca996164f1ec056455ace8b9544b9c1b1571b8bcfc104fc5e91f5d68d7738707\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = c8300629a6cac3b1a7b408bb50e503191cbb79f102256d0bf3f25e33af30ae12e430af1bc9e44753a0e25a824e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 37c428339a389e8ce35daa03a99f5c07fbeebdcfc3e695434f2eaff8f90cae8902fef683e2ad238f2ba037b5a5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 39e65faf2c41d0bfeeceb28699042b62e976fbc3836e6a8a41ce5a5a85f9c428887792f725baf7ac68db824c9b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 0a478a818d4fc9da07c90487cef008949818fcaeeb5c1cc83f45d487321fd491ad58aa1863c4a5bb75e9db1b66\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 32cf849851e83b92db5eccef5ad9464af0133d588fb0ecdc4a43ef0c03b1dad9889d673900e95c7e0051035426\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = ba1e5814a83a84dada756914f38e7069718ce13e97442003ee37bcdfcb54032f8cc3e50bec78c2b8c2e6402d65\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = 3b91fac4f67af1a93f5ee312fe5c39bfa915a2317c2268b594e363d368d9df09022468a5719a3cc91d07f3c36f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = 5888dab7e84869c9ad8d5a80db2e89da750780da4e3fd59f317c4440ab2ade53aa855254f534e8abf7b030e1ba\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = 9f8d979e4c9965a2e135e0e85849e8e51cb9edf27c5a48713c0342f78c6eb42f89c246884f42b925d508ac1118\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 1a3fe6ad4387133e6dde596102384e034984b26ea9c2518690e43bfcbba241b8991b1fc22f5301f50a6c067b18\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = 35ec707cfbebcd8d29a94b2a53279f06d6dad1d67a85d26515b33805cbe9c8054de90590d90ecfa2e75b319426\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = 98b90ba87c954ef7a61833679d2d9634cf6c9e0e2bd346b9240cfee3cae141f3bb886ebc195019bf61ea174fd2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 29d4773ca7566d5e9e32701d6c46c70111d615f150663e76c62c8afbf3cde30395b424530e71fdcd91abad8235\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = a3ddd151493934a6d056bfb33c3cdfb872204b2e40494b2c12c298aa2443563eba9baa7a984b4627a1aef12b35\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = 97fee29b1aecb67490fa440db94e8edb9d44da3db59466700235cd0613bd7f385621ef78bbd1a61207f61d58d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = bcf3f399b75f170a59b61b5a8e381f1254d4599bfaf906ec035aaa89b862616163b32c0078ee65f57e372921c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = b4fb4b40243ff48b3af21b81f86742faf71e9a2006c0dada26824262d3fddc428575c2b3fdebf84f777e6ea7b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 3e4774d43410c80bdd17e94276dc4c9e593dfe1be6e7e512fb0ec7e8321f0825ae52cec95ec88e0a73cee34632\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 149628f5c0a0c7a83a255124b93bae9acb5566caf56e2a44d425a045f5de8d8b99fdb859853195048e9a2c6838\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = 23353f67794a1ab146b07737c42dcbaf16fe80f5fe275808900ba8b64f7c277710f99887617c315749db003750\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = 7f682e36cd661cd0604d0d161b6747c9116fb2155698a880390b170c95a1a4ac56281296c3f92b643a43bd7bbb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 5060bd31673101670052d60db668ba50e577282f2d04ac7f55a968df8f1e656f3e54c042bc376dff57881449f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = a1a9e8eba75c2d5492de5ac21b96067d86db723ca40446043d6b518ed99e546adc70e872b389c8b252f968ecca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = 265c2fd6d576240fedc1e9d2e54ea85d4c6f948ccae75dbdf5131ab9e34e6b7c546fcd2799fd70bbbd80f4a403\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = ", - "436f756e742d313032\nct = e5cd249047639b55351adec7054b4bad49ba504dfd012c24e6664b174aa7a96a8f43e3e74c24c72a2084a30f54\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = 718f45fba90a6d7fe762a963a3afddd422bcfb69b4d67f68a07f0963542d11a9f93fa7becbe1467a6d4ba2bd59\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 83317a03f6e6f5c8a70c2ab5a13e594f71de479e37041bb665f2f7a1222cf3f989dba32842bcbc2e9d104eeb6b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = abb06a322a83405b85f2921f0faa10d142e7957cf39c0f61efe8d4ef7aa408dee8af86032f3c16a2e103753a75\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = 1846787cb992d807a28985c645ab2752cec1059250224f49da67cec65ff51d9ea1edaf496c1e35d74a39746296\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = 5c272f93edda401fb918c03179478563bf812a7012faf8662002e4e8d0c45b4faf1f8f1345b3cf93efbf0c3590\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = b93b55d7382c44f03f7d5c376fb325f009ffa705b785922525f83d81226259cbf27d5cd1d5657eb18ab49c8f57\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = 78f36217e54bba52f594bb8f0ea26e189abb484421b838e983d5432151f5ee702310a7da43b3f3477b6446e42a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 98b9e8dd6a2e8dc8e2011ce879b160554365afb06bc62db992131c2ca3ccc83d83aac8157816921da8cd54933e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = 4cf48574b0986e1b19c19af1254c62403ba242ca7e379407095bffa6e65baae539bb9fcbcab8a915d3c633013c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = 94da1edb651a79419cb2c0ea1a89c14fa3a725335e3b3b10b71e97eca026526c9d61669ddef6fd5f71f15fb930\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = aba2968f77b8170707f3b7affa945289ea56986a10070956efcbb48b6512e22f960f7a07e05c77d5debd69daef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 258e1acdaa6c7ba5e31bc1098ca42d844531b0039c399e05fac4c0c22a75fd4e308b288a24127334fdb1900b0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 6a6d65cf15054487bc8f4840b86d3de127c1a90080051cb0242f4b730d4a526659a7c059fafb0a83d937d62e48\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = b8bf351fbdabc9a5c4843b6ababef5ca9faf95868cec99c04d1d555e615005dffc6ad3e4eb84cf7379242575ec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 5a042d64ab6da7841bfe83766b66d10c272ee4dd3b9cf9bad9d8980f8b1d191e495ecedd6b28444bb6431c0457\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 7198f5b0e7d9a041570522a57cfa5db3d488504339762fdba72e1593e164a7df5316c674a592c064cddc9a6c05\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = fed6055b80361e2493dbcc48b658a35afaf6247ac4532063fa5812f10b7e4f259d557bac0f049b1b88577dd67e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = f6b7aaadedcdc89ef9147b3817494a3f43107e756990c415d4a2270312b0e257b756c0f1ba929ec722850fd762\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = d4ea7ff429ccd38d86a3a35f1a86de748cd1c3fee83e7c85dc5e52bc5134dba53d4c85368733037a3845b1f8de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 86771ccb6999dc2085ed073c6f0216cfd8a84347456e7e411753a70b20389ca84f25968d4bcf3687b8250d2048\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = 76196c59dd912a7fdf3da785b02edb0669830f23a40b23364d9a8417c25a44747eebf5f02173bf254bb6535451\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 6e5b768c7965f3292010ca206f966c30f1dd1c1faff520df04114442072c3890ae5bf14295eaf7cf8aa57330d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = 7547da149fc7eb27d904143355133e920beb405a8c245e5ca8e418297f09cb96aae615d24661f834e7dffcb018\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = ebe8030330f423a2324eb863310d1c13c62ff7894c1495a0d31709ec1fe567e62954fdccac05064c412ac00409\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 99f8286c7921b46fc90023361caa5b4b2e0c3d3b71b65de596876eb70a2211d89b4a90acc225b24954224919b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = b9b31bc2dafa1c31154322fe4d23b5f130cdc8f6c92da9ccc937503f4173d5cbc6df18d7847b77aeaa11be32da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = cfa6ab15f19877c4c030522077c18d442d1cf220c1b021e4a5fa45d14e66044ef18d894360237281b55745d10b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 46dda78d75d4beb46b6e79c68abf242895d072602ff0984d22ba95281652a55a26d5a3209177bd0b78f80b6565\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = ac8ddded913db97734636b351b65a3a7ec32de7c95f9c2f7ea2ce186a9cf39fdc6734d9d33631ff7b679047da7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 5a63fd958d7da5229b2ff04155cf5eaad8af24292de1b6f23dbc1a6c8b717c373171ff46e9aa6ccc87cc38739b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = c3de57f22a0ef3147b395ad8dd1b920e6e331fe19ffc4a4436cb0587ee1f9fdff890ff1a02fb9ab220594b7f9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = ec42e72f0a8f228508141998a0007f59bf281a9a3648812ac0f53af320375a0abe4ccaa73712ab9de8b2cf8327\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = a8ef6cd778dcbb82e48217e77e132aaaf3434370527978fc6d68df1aadb1f6b1f534b9aa58e993044871cb7d71\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = 59b52a68e18b64aaeec537a113586ca56f94190b4c8fc0074febe8238606534228854d2fd45f734ae726fe0b3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 595214d9c7033b1790e9ae70b739332711baa4e199f5457bc72c033661b559c0f1c3802bc96c63953b9e2eb5e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = f7970241897e25ef6c4fcb0224e5bcfb2cda3715c9baee3b3267c7b199c82459a2a95ac9c767d90d91962bde9f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 7569b68ca4ff6436c0a9e68b289ecb0d9eda9a1a60a3934ce13a92f57004a4b41e69a75c3d2a29cd2c929f5ff9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 1ed5e8fb578f67d31a061ce5853710851c98b8b61765f76299711d2e763af33ddb9eddfd537bb4b967e47d9260\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 92ce89e443024b7a80b61d1f58d638cec095d7d4664e8549e51aba582d219fc1dc5083cc1021b441560f58bc03\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 17103f6d", - "8cb385452457040307ce7bc8f18705c9333ab51867f6cf62e51f76cf703b69b32e209c64e8777b05de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 6441c689667add0ed50eeedc0dd5c487aed506f2f360e768b7937f3d06b0b43c2c3f9d9c883d105e7c97d050e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 1848f52015c0b917d755528d3d0ff70574ebbec2271d4c5c672a93caf37dc87695848b79b9f3caaf8937585296\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = 71795a914c78062acef28a7e6326c106dae40f564c73fb63d9f52a0522954caf5f3d8b59406c1e4c4efb4e78c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 18b51007114b30a1ddf14efd7297ecc0a8ad9626408ed9c6bdd22676d9aa0c11aa3f0cdc525180d47b1fc2803e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 1cf6954862fe38be7871d362a3836ced64dcbf2ff114ccddcb6f248a24446505f73cef228f1217647d3e70d7d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = 41cbb2064d9db9f43e9fb550a057b07bf90925ff28df85dcc01e11e2160749e3a4003df7693baf73315d3052e0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 099e43c3d5305e2294566ac688e4a4c716f3b81373e941b6d28320c4f48acf9c8bf4f3bc32e59ee4931fadae79\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = 4f27075c65c4768779f33847f720f635de15d5074d3593391936e4f0db79abf016e548781313176bb83afd544e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = b49d1947610dc84a71bec3407420f4351d74a6f97dc59cdbaa4063de82998480ac8d8576100f8fc1dec8fd0415\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = 0452a34aad9eb57de1748b18570ee94d88d2b123cbde141525e53fad8da5e95fadc36d533d9ff158eaadddaedf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 4034b6231f8e1809c54bf4d394cc05104fd223357e95a60597c7df32d2d1b69e0b78adebc088b4364970c9088b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = f2cb80c67d9226f131dbd64963e27ca64e428e8f64c2c193c3798e2af548a4bf5d0b64d0e9a5105bea4340e40f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = e4be8d8aeb13fad3db0e7d266e89ee5ab7e3c861bdff61776d6356e786787e14e6d1328bcea2001cc48a013425\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = c1084bd11719f15b3194ae5f84d278efe6a962c0b5f16123cbde523ff7ed2eb88d91293c22e3ad9683f5dfaf69\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 91e9c1582a12184b4fbf796a81ae583f865a2170bb09f2ca46121824f19dfc7944044d533c046ad093f7eb820e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = 8e4fecf7a15fc3b258900b55adad4aeb1386c6486193e4d3fda60fcb255635266791eca1cd76fc20b411955210\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 671e011d0e3c57f73508f885c64dab5124a4283a9430168033f11ec0f1aaeafb7da3224a62264d2013baf4cf72\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 8d27e076edbcba9f6a9e58b62914463dfa5bfba6f419807d6664659230a947e069756098429285b590acc89927\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = 7ed3247399afa43f2e3db2697f9e37e94f71d4d210e2ba4f3896eb62bed1308df32e5a63a16c7915538ce7463a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = 535bc957326207f14417a5c79dfa28103f488169039d81986319c0d54ec72ee23b8154b26bfa9e1e6941bab038\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = b7a029e3486549bdb19fb063eae5ac28c646929b1f195f6f1bbdf9f99a65214e923d9bb03cf19f17765c62befe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = 11c717389193120fa6b61d9fdbfc74ec17309d744c1fd6e0d49393a5c32665c0b70a0a64916ae4a02d020762d2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 45a5fc34bb9062b93a34063f009778d4bcc3af74a69152087db014bd88eed080c06cadcf1efd41b31a9bd9a65f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 2ed43cae3a8299d0ee9caf4297b330ff643066d71af8465cc19a834bbb953343a7e165f646eee638ab0485b903\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = b42058802b285612ffc4c9660931a282125eaf820c116659672ea4cf4e901f9aa9c496ed515d6fed6cd72930bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = a5cda906160fc86a45c80cb2b51c07a0a1308626426bda2cb6b2e15aa5d650b6f59a97b503ef046c88f643e0cf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 3c0656ff6ad0c678d1ab7f1c49118191a475882c66b9a771a9570e1b19a7bafe0e2e2b55f0d17a4d054d175516\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 75c7b335e15e94bda0851db69e35f108fc233a545da4b928ad14461e269694d8820956fafb4e44720ce8381507\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = d3d4208c7bca3519228b580237ddf552c0f479fd621b5751d797cd1d973f62702e1ddc2d743ddea6a14810981a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = bd8072b89e773e49b1ea161dc308c1f47e0ba2900eeb8969feae8c69ede105660b348d2a6ab5251e192812a704\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = 802ba6104adc7ec67dc96bad11d1540c37c7d09a1d8e588e9d037a559aeb8bcccf00199e002dd1b51e38346d01\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 170693138046e54de3f940047bc9c083905bd0d5f66ce4a21b447e8671662ebc13ee7cad4d0710fc453fd18c44\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = fe66bc839bcc84b49b7b2f74bc79f6b6d66d081b431a9f875738ec99278da15f562636f26a3305c06ff0ac1dd7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 68387b231332367d7c8b6d57bd2053c79158bd8b364001f0ad10c2687266df9c2339179d7278db2c9b6a0a378c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = 5c15441304b8c28780c052b3354b85f05985dc83ffb718e4b680bd0fb1c052aa5741370ae14ced0dfb94d80fe8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = a5b93d9b53f0134eb135abac39506ebde71368021255ad77964ba92095b370ca6bc1887266746f2f24a1ac68cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = bc646bd2d4af6cb3eeefec80d906ef332716d228ebc473fd543c51fd4c626ebd9a9ca3c5379fc935748b302fe3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = baa95961ad3798f5ea49f68c7bd46a47f1e1b1f4c4410aaa23ffd29b539257dc6a519bfbdc12f48c2dd44f41b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = 63350bfe96ec394c5df26cfec536c1e13c36f11366dada5c7fbc87c7a77824d3aef9f68420edcc90dba8840e8f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = 2aa46f85e84cd57b484eaafb542af4fc5be63a3c", - "f0517924311c5014754cd28ed4aa3a7c6ace995369a121d919\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = 7125de9a7ab93363e12742330ab38a0afc493cacd21fac7dfd8d6650b58088e5441b4612957290bd81bd9b51a5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 99e607edbe8020e3d501f2d861864c65c0f3c7017f73a5ffe4a13f55bf5576848f3c74982cc59b599b10f5d16a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 327928bae37c3ec8e3013157520df8a40fc82e554b8ab673f0785aa30ad582b3d5c16214668a9c02b8a3305996\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = 970a798ffbc3d26f2d8d937ddfe93944b9b0a8ef5b5090cc2050c9e1cfa24ae8c9e383b5443b6b06498bfb4576\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = f9888faf2641b1cf17a32a2f1be9ebed7461bf164bef4d66f925d97aaa29890011dc5d32b1662a46e56422ad4b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = c4b3edf0d1f37509c2571d4b5862f59b2ebe75c53553fec09fd4331db9e968beb517f1c48a2e1025a13d0849de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 128a7f7e9f4840e993df22c6a27fe71ce85ea48e30e09cba1d61ed2a4ace07cbc6d498e10909b581a548facb53\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 640183b2b366539114dd437cc52c7e11ace537522dc32513d28a72306a0859bfbb57e88f0ed282c328b2811575\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = 737920941a5416463d091bb39cc88fb9a8777946b3d491d74f873149c121a680f61bac1644fbbbf4e4e084615d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = ee533361a9075cbd1ae3448b865d16d540869e232beb3e7b7fcf0982baea5d4a7634b9ea2bf3a768da75d7bf62\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = 94be547dd7acb0e06fcf9699e4e0417b08da4248b09d2344ec5a3f3740cb6df8a2e73cb7d1f586e2bf81fbe01a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = 595ad5462e873d7289b871482889242cc322d57e840a826164fea4b240c18a951464d27444a5672cf0339cdecd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 88fddd9846559b1e0165e961bf90d9320b8846406353174667f03d667e90da202b5dce27a32cfd2c4288e80cdf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = d0b40335e694ecf36a1c628c215f8d1e59fdea2ec54d1997a7784c519440c58bf1cb2cef6f1787b84f75182726\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 3e7e536627f6b2bff437b7c3147e19b40a779ef2f9d46d0be7aa086dc462301398e912b268cfe8ac174535ddeb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 61919626cf4fdcb05b3994b2b4f1cff36cde151621afbccbacf5cd30371328023548debe410f5fd510de7b3f8d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 5cda7630909f65f1639d17ee1bf9af32a154e07a09d5ec0cd6d980b2246420ac3a713f64b747325ff98ffbccff\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = 93a81809a5c145a51792f16fff011cda42b7955c15f8005eaac4b5a2c69edd7c6a30e4007a9d7a28eb4c916f91\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = a3be48ca8ad70c6dd6b2763088cdd9ec7fce54535369fa711895e938ef40b634d765976e74997bd6ce3334d691\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 3f060c4ebcf65552febaa5301832a124ac261aab14cb4987abe467712948466ef42a819442e857a7ed2d406a04\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = ec45590afff57643dc270647f6932475fdedd8c94c13c7834c44d0f80b48f409fc311063140819518fee6274a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 157c4157c5f1afaa789e304c096b751c3ac0174264696238dc614c0872ce6259261613938c14757173966fa5f4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = df36b86290c7ba0b99f6b9ac4489d570af4941296ffb352cf0a2caec11e9edadcb61391e381763a3f89055f1b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = 4ab902188cd8040ba6c4d325cbde2161e672e996f2431af34a94bc89be127ea99278e896082847c11029c94cd1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = ecdbd21be32fae547cfa7fb4d665f3038b5ef47383b349700f53fa37808f9f971c4e6f2c686dbead494695037e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = e4721d14e172cd2db536535a8452a247a60642a7645f56b30b2c920433f082a111e798d644e764eae231b9e36d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = beb673981c54566d15239a625e70beb02dbe9ad49782a9589c6dda7db3409ec9b0fd5485b2b9ca89f51ad2ba92\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = e2b02be0b2a8b327c7a83d4c276e7fd9f8ebdee2e951113bf0622f2d1b52566d0b5fcd582b8f11f2891206e439\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 33ae0f52a3cef337a7286ae47e4f2939c18435135f3f93794507db9fb4d779a4af607683a3f837d6f175570ea4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = 7bbfc9c9e8a4b2781f1dfcc48c3a6d9e66ec91e39348a458736681d7cee6fef84102da9bab48aa3fbd295b129f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 951bc3e3f3a302eff4cfb7989a6508ffd2bd69223d9b962a4c68cf04d209e37b056f92c4ff96e41b60e411fdda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 031ffc754d54a488cb7bf4577e840b9257d81ea3605e2b1fed1c4d83ddc76ad7ec76d3cc2587636287bdd15423\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = 7a88f024350986aed407259173cc4f1672ac1b0e4d29584c3bf4c717ca48e9d835ba99cafcc0ba9428368df5cc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = ca06ec3e337014731f122f8db788f765083be95cb6abe2e9827d521f63a71932a304fc8f452611c02bdc8ae83f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 44571995fbbcc50754e9858f45f81f9fda89f862de946f55f6def93c0703486a59675a28df6616057aa2962bb2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = 2eb20f3269a93720f615d25f908c9678dd1249646211eab665b4e15ab84661fd737f32d4c319d2bca171bc33c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 9db897191dba0aeace4709846d28d905933e576d8d19f64cb26cff759608eaa308752db430c41e6c1c13b51878\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = 132911b40ea785d6becddf35b68c8edb4ce3bf81eb982bbe6e93bbd500c7804a62d66ed3e17ba1677e5f19693c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = c0c3cb5727eae2624429233d3864007cffed7e839777a25d15dc3d46ac06dbd89004059e01a346feb05c1c81c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = f5d86b3e4a39ab7317273283244422d0a764f897b6b91ae8faebe925fd1ba2a15bd980e0", - "66dbebef574c894a92\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = 681295d554e5f657c02531e84309c96abdce3ff58fabc8f969234e5f5e4c6726c51be58218063cf086abcf5983\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = c61b1a3724c8d67195ce45c0bd59886fd9b12c43f76379fb9c99d528bb8165ad41017f1dac1e26937e84c8adb9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 5aab74d6eea92c635d2c751530d2f0361a8684a515a475277bfaaf5fbef1a2171a33c34a90302807c701d56790\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = 7b998eed5008fa6295b94dac34ce9ec60faa1c4608d013cfa014aa3a96ea6687a106dde3657825e63440dac506\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = 956ad989000458007af0b41eb2fb5a716db1b095594821fc305ee35ea27b41b2476880db3b4c86bc60c4394d05\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = 21de030f4aa7fcb8650847deea5ab6a2934f2e0c1c5d592320a3933bd6054d6ab8498aaa4afd84592577f5982c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 09ebbc42714876507032d57cd75862b36e37c258a60381c2eacd54df57b63866bb6638ba70b819c5154a8449aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = e00f7b42761478774b545ad968ba8065df957f3ebc9f08bd7c87883635ca3150d68a0762e366346610627d89af\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = d943ccb5bec78bb5c5456ce7e0c2bbc2710451f67f9398f81b1365dda8ceeada480e270c6bd39cd40fead78ec0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 97e618976ba5b39d98d79dbb6e94f853cf2f231d32e6240929e4674d91789d7a3dd7199051d49acb92ff1e3064\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 3a089d31db7927069a7956793308cf8f59e3570fbf8f561888699aaf5ba4681a427d68748705754d6a7344ca24\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = a4e7bfa5b0a0b537c1832206561f764c88d722429340101906b380aff934fbb98f5bdfca0e77024805338e4e61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 2396cc5b30ab05634f7fc6f6067eadd043e6263f1e68c6ba556fa99dd075a7f1b42b5cf195a469ef2443896fa8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 8e419af52a43da88133fd3bccec458a44c82cc24dffc7475f62fcd69d9118c85505c0080811504b6b28d94c7d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = fa41df9a9badbb1eaad232e4bf7c431b17418b429cf8345e45b1b9aed9e8669ea2e19893f22dcf4dcdfd370f39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 03ddaf89dd237786f561dc04711aeb5976a61f5a32f789f92867b39024ba0f5f09bca97ce2456b4d4c8ea1e692\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = 185eab1d7ae0d33b774abf1d730abe7cdbc7e238ed7c986de2f41e650f0915f33e816fa9b0e08143cc76c76e6c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 559b45bb28a558ebbaf55adf12130d45e18adf68249514e564437bf61d4c49fe9f252c006914429d96ee719173\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 6457329e5fb4296beb868c175f84f16ae889a3edeb37edc19b38bad597064287aca727b420b5ed8b1a0b677786\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 38f7ba2c57febe4b4d832c29299060d93f8fed98b6cbc95d0d6e95dd385d1fee063783ea774a770111ff9aa31f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = c45408567b0ad94fed4067cd1d250db315561c9322db62e2d4604bd36aeaf1fcea7db541ab88197266e5d9d7f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 15211da2711b3ffd8f4fd59500a7fa1e5e4bc96e1ecb874671e455ae30cd8d993ae61f7f2c741337dae98d3514\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = ce742653b0a38f7c93e901f97379f074f875eec71299361ebf5cada487b9992d1e7cbb975ba8d5d44aab2d5854\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 83165d93c0178f0b4f73a46952457183421a3284b17d9d5a056c897b7021ce1cfe5295a44a6daec6da9a02e1e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = 816bcd488508d071fecb91b9a0c792b93461a1b6eea76728fc29cc1791f47b9043adde84e0af3e99acf72f7c95\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = de13015f54f2d415dab8f63a47d8bd5799b169f1982b67b79890fccc187be7a1ebe08670e4ba6e61e98e4a353a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = 6f533ed89dbc3d56641e7c6baaea85455a24d7c81bba4c2c415e146d78c15b05acc144c64a392fdabd6088d731\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 43220fbb436a9269a2b8dba1734e8a9f77f443f32fd89dc78b6205a10817c38e8d26859b2c3aa62d4012dfd8c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 1a9acc8588317d8be40f50afdd9ff12464dced0401e6f8043e387a1b4d82c75e63cb0752a06d3d6aab8eb41cc6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 1b6652abf366cb5106ee5e6676510d44de609794badb2672f9d5537fe32134955d8159da22d98c58780980de3e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = f4048c4d1b9210430abe699016e1d696b9f67102a68d216d84bb99eb03f6d57d7968075942d4f6e56d462d25a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = f3e1101622e9c97c64fc58e58d71bd92acedbea1a5dbd90d09fca60470aa2c708ece6e8e845444860b37a9b420\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = f6ad1823eb0b932d04b6e23010eea64f1fe5edd0583dae5ba27ca6363f4ea104bd217331460ef4208040423641\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 53624f4f9f173453b14e633b45390ff54cacaa4428d44baee1bff8133fab1ab3afe60f88e4634b525c54e92eda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = ded6cffafaea6b812cbf3e241e88332adbc077aca81512914213810ee291770a\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 04d3cb6cc116b28ffd22ad5bc276c60d31fec71ceb87ae24db811c64b7507339\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 7c5ded445732c14fe09727d29b4251c0fd38455fe8440571e687f0886aac94d2\n\nmode = 0\nkdf_id = 1\naead_id = 3\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 8057991eef8f1f1af18f4a9491d16a1ce333f695d4db8e38da75975c4478e0fb\nskEm = f4ec9b33b792c372c1d2c2063507b684ef925b8c75a42dbcbf57d63ccd381600\npkRm = 4310ee97d88cc1f088a5576c77ab0cf5c3ac797f3d95139c6c84b5429c59662a\npkEm = 1afa08d3dec047a643885163f1180476fa7ddb54c6a8029ea33f95796bf2ac4a\n# encryptions[0]\naad = 436f756e742d30\nct = 1c5250d8034ec2b784ba2cfd69dbdb8af406cfe3ff938e131f0def8c8b60b4db21993c62ce81883d2dd1b51a28\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 6b53c051e4199c518de79594e1c4ab18b96f081549d45ce015be002090bb119e85285337cc95ba5f59992dc98c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\na", - "ad = 436f756e742d32\nct = 71146bd6795ccc9c49ce25dda112a48f202ad220559502cef1f34271e0cb4b02b4f10ecac6f48c32f878fae86b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = 5b23a1bb4a46eb6534d7929b88055d6a73fe36fa2209b7c851391a8b73aba3f8034e2cc588317ad35804fa4f0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 63357a2aa291f5a4e5f27db6baa2af8cf77427c7c1a909e0b37214dd47db122bb153495ff0b02e9e54a50dbe16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 13e916caf926e56e911b1f114f4d3b91da26a5761bc475bb874e91fc625e2f15d6789a8bcb69907d03d618406b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 1ae4fc091fddf17c3c18c8b7bb60063668e6eb7fdcd0abef5aaa8922eb73b4317cbe38301689a9bd876487e86d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = 3034f34153aa2227884561ea011af79eaf74fc9f4540c7ef71bb49e80c0a38834ecd2a2582c0c6c7412b76fbdb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = d9f753851465e7153c1c0ec83c5d9804f52b2a984e6d8bbeafd92865a736ce1dffec4cb28f3adbde0d16acac77\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = f3af37da4888aa0b0f1ded625e06a277429df8e8d89782b6d10e58e94bf50136abdb2b5daee5101213b0f49f5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = cb8bc2f5c08dd4ad61b85ea2e0ad5d0ae244a663172d1b7b2cf0477f7c1f16d35b3c5145fd6c310db97fa56f6e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 7b21af3ffba9165013c692cab1287d60a93c82ffaf3f9329ee5fa9d8eb6f11d2432314f45d02b2dd5a3f73438c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 039fd4450d4c35b2ec404479975c3a83a526bea12c1d41653e758a8f84f41b7ad2c1ec84f6fe0e21dd664f36b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = 2f65411d6ba8e3113b67c7710502f7772bfc9718d37f21f2cc4d0f61f2717d0fdc2c2a380f8b84d006e8af33e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = 494dbc5558dd047c8e6f3c547cf5ae3010496f99d2ccbcbf8e3660d435d40ed41c441abe4a71f7cdc298a47512\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = 155dc29cdc2e5718756c572197731172cb5463692619d10c0f49142c858e7fe4c84a801ad74ee11277a899b17b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 554c22933d7d58c6689ce050d8e1eda0af1a1e6b0c9621ee5c3cecb24170be59b59794f78851bee7c75c9bc9b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = f14f868aeec918d8917b5e1c5a3acba3eac72500e2e1c5859e940b836bb5fc690c9fa666040e0f24235ef89461\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = 09aa8c97325c57173175ff935f1545dfef19a3c23df9d650e6e504b0f38476f9c328e9f8545dc03eeecd397efa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = aab8d8659b899dda7ed988788c1f753f65182fa46aaec3790c752c5e6d4edc66d1a29cb7775a06d611cc3ba9da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = b53cb489b5afe8d32b8b7f06a85ea21eba5d95637f1b60f5bd065ca400176588edbacff42a2fd0b9b2319c6b54\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = 2de0dc0045de431a43e2d46b8309c01755777174ed464e3076d1af20b0ea679e40c426df862d3d9e24885e815c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = 4e92189ed1d24e7816771cca561591384a644a7ace00cde6a3680d83032c3d74194dd478019cd89544fe802db9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 3992ca5ddc6cb82d81f1b317c3a1105ae1d0b5b7bc38649c7c350a4dc257753097bba175deee96426f96aee308\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = e6f475061e9cf348298d4de1b3ed8e84d05b1a22210222d317092554b4b1b591b89c91f890da65e815294eb71b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = 7081949d6353a8a4849adca6ab69c21873368cd5381f317cdfaf64d5e47b21499996a890b24df18e96a50ec4c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 154c97813292de73d50275d18fba298c207e7c8f27f74f2d7566db9334348166b0be420c0cef431e085fd44324\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 9e453e6146c12681cf1ad8c033c5a18cc28824c847a391413fc2bf51c0657499fcf3cb659cde1c0d00dd092d24\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 53e99d1fe817118adf77c5eaab64ddea7f8880e5296c5261194e666931924c92d031cedb844f23f2284270e4b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = f4337b127f13c333d1c979803fb31fe57673d4e68dcc907dccbe67cfa2de78ac154c63cc43510a821f7dba17c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = f6ee59922b6f249f7d55f64d52692b06f6deeafae40f91d56ccf8d574d61f93a37cebe5744f40bf5b1451ef983\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 39975125abc4f4647b5e8dd5141a375f9ba66bbff0c4f89fa26eac66abbb71f90044be9197283ed9b60516d866\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 545ed2b3050db6cbbae44b8f59fd3e80635390d22b2a93114bd928fffffb126481b32ee539120ff99dc3138dc1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 2dccce6855d90951971ad92eb2fed5961823e402af0d4f21f910465c3072622ef18e37f91e6e456a854256159a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 1c614a68a70a26f0824a92d25121791d985e8f99a54f0b72475ae04656f8517f5124fe0c8d55d243e47f296f5a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = 9425385e046c183e19515b5776407f7cb6b8b71a0352598e57f8bd8808652e1267506432084d98b8397ae18df9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = e5de6144eab00d48ecf33a175be12bd845fbd640ed9cef6c6a31340ab536c9a0f07291762f77f1638e248946f4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = e402b0a9c028a1b292820d8e438506d157ce717b5c8bbd4eaaac9e6520363df7e108900f0f94eecbfa314c3c43\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 47a319e1ad50f8d95f55e2075f1d54f9af446636571d81b39ae95cd50a55543c74d65f811aea42de7ed79ce756\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = c35d9f43b38e549c6c12a3aa433af0d6f3fb383259ba8292604c82f6bb2761a474a165c37f6f27ab816388af3f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = 918222466085e53705e47e6162d3e715cc1ca21bfcfba857dcb1a4dd1fe45c0fe95f4eb2dcb7f27b100dd165c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = bb2136e56748f6d78f7c4aa8093cbe651d0081d7046e66873ab849e7b155e83402fcabb30af22b607a3758e5e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 7671268965a6bff9b8ffda26e5292eb37e1257d3952dcf37a65a6077d93651744d5e5c44643b1b0b53c20d2039\npt = 4265617574792069732074727574682c20747275746820626561", - "757479\n# encryptions[43]\naad = 436f756e742d3433\nct = 17784b52a709bde67d6fcc6b6de937cbf80f9cea7405708f42bf1cded9da2f6c240a6d2063692bf2c896c6df86\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = ddeeeb8ee50963740d7283ee5404581b0eb97619acba905588f66b5e79052ab61da7af7e3c9b54c201899565ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = b4a4871ef73db1b66c310341e67187c30cc526ec5fa203e57848449f029d20906f8968a6599ba5b9b5a519d1b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 5de1796b6b89f1cf0b93c88c41e7778cfb482a81f3bab287f636b10d0c10612cb884aec9b2514b0c1b7af59fbc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 041b12ea31a73f9fb5b80ffd373c13a938a1f7888923355e17bb47c62221383d614d485bd25d090c68f45dfa93\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = 96506b77c1a44ced490059dbda1578226c3514977d4ebb39fc334c92b71af1220463f46af1d9effdaf099d23e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = fc3dc86ddf279c9bf386c0161dea4a060f5e109484a4c0371bf551a5aeab963e0c38fd3d1562531572fcf041db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 762086d44613f1c0a15ce6c5dbf89d314e3af3728c0063a8eee91cda202de81b678230eabed359421493113578\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 33f3cbd6ec16c70b1e639d455090c939732cecc87c7eed10bf57cd395b31c3b48f9a5a1655b48d3c471f57e969\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = 515dd43217bd14c705e96f8032e58fb486ffd167c89215111ddcd88087ae0df6741180eea245e2f834aa3216d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = b93c95015ef99d815be1381fb27a6c5b2ba1667c859db56b2eccc2df9ec697aeed944f0cbd93fd8f952432015d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 543a160b7a3025f401958732ca4892608bb3bdd362f6f48c3052e0b5599ddfda1b9ac57dc82d436bb2fd890728\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = ebe8436ae2822e2f6c3ba59b8a79752d10201da5551caffde4e8421e35ff23918e82ef57c154882edf949412b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = 2e3babd04dbec3db0c25943f765409f83efe07287272d53fda796edce01604a24a409791b1dc6c9491ef951ead\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 23d8e8aea875a89cd44d1a0f2f652f389a2ee8899c06f1b186f2d35b98ce2ca55586bc8304f2ad8f11ec6d4a45\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 7fbd9f0b4ab1ebadd868ae523bedc740f19f619e3147cfd44626ac9e0148facf092c1b7a1439f12b66fab1ee91\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 79901c340c134f34a87943df878ab284769a7fb6ab6b63c03107150a7c0bf02532c203b847f6b2e82b9dde4daf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = afea3edb11f087496f4e969455d323c65936376a11db5818717b3fc4729567140aa786e25a6420be379d9d7356\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = f7ea8ba2c5aa0317e7364d13429d7db23aa3184afd9698fd368287043ab04b9b0da3477973aae8df7c95055467\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = bb875e89ad36fc0be4ff873d25548e73c572f22af59cfb75db6a5842528720d0e9251a8d0d69d85fe4a44c23ca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 93d5bb5d990e893325555ef94928cff7e722dc1ea4be036e7803dc959c33cdc052a3da5af36ec904247128ef71\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = 1c77e504b276395a277babdcb14e96c02d44966bc1722e813e2ddabadfbe0893be0d5dfeff38abac3b4fe8c6c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = e54391814005400e0a3712f651ac1cc3a4d8987a75c03b111d71f80cb9b1491efeee7a2894e794e83ab3e65333\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 84e80b892d7f4b4fe505047d67f61d8a62de98429d4f34d5fae2508e7a38037ad8c67e85b9def05b628a0b85db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = 3feff021bc5491d7329b2f0521397af99ee65a301488697b3c96ae6e8216d92b43478e7f45a8950c16888e94bf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 328bfd026fe81f27992e84d4daac65d37661c5f16c41b4901163eb0e4ec4a9da77d46b7f35fa5eb41ed19bd054\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 3f975f0ecf397b0e57e007c588bb93a4bd123506089a7c907f733cdf21c5359f861e6ecf36d137f3b8e3b951da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = afbeb6001680eada34d532ed5fcb64f888eda521bf62ec048405c40433d6cac6cd1317f8309529354d581767ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = bf217e3b30a4210e59173df68e359f806e9a1636e2c683d12cd1ec9443fbc1c7c2b14f54ffadbf4d0d8f32c300\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 4dbdfc3cbd4dc0efdb3c8f9e660d07bc8f1d022679c0d0ce7108fd679992dbdbf4ea0e05caa1439fddc705b5e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 2894e03bca52f3d6ccfa334a5e6832fa73ca18c75d21ed01321d7cfffd87cf56ac3b141ebb5dea1d611adbdc61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = ea1c4c156fbf85ca5e6dd5cadd8bcb6c9e19b3b833012560d5da193abe33752794f92e67525446502c0b684aed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = f7f162240ba707111097a7fa5030fa6e96033f3fc67551398fe06bb26779e33bc2e8130081ae237607e7a8146f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = c3343330c59be643478135ed7604e9f5a8e65cd6c38b13d51b0e3ee59bde00c2108116f9d585f0c5941c32860c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = 252d5d39d319eb01e8723da3adec3197c6c012a058e7ededc5fea6ace3cdc643c45e17cca3ec4e8f22ee4cc373\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 77cd702a74023299629f0f3ee73d1f1f9515939d4b82c0e4bc1cb608b3281dceaefed6dd604b51c28fffb772ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 2d5636db4e74f6259a4a63927cccbc2393ccd024bb9880a475776432ba27e1c1045c73fbb74948a8d3d2c0f811\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 8ecfa6ca7db677ad757d74ff454d1c8f076166bcde9cf71bc22a6724cb6e5ce6e963aac83650f45f36c069df85\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 3951a980d02ee0d047402352895ec3092c96687f3a4a81af987f808ce7a7df88cc8a2b04ad4dd7e1b93a3cde00\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 5fd41e209137f2bd71793de55445a4f4df44f732488d657404b335d0a5e21d737d3ced858be28d5f396dce8810\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = 1516e99633edc73806a84334bf6a4b5ae77461de405fe6827da12c820a5eaa78f6aea9d41b22cb0c6c11ac3bde\npt = 426", - "5617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = b2ff502eff6663def30ffac7e432f1e580ea814b8513b1004af12d268de932e7cde5a55d99b6cf8517f34c4567\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = 34aa152d2822ccb3c2efde62f6a7923d9bfa510376c8622c0148fda24c62a9da754f979c44c65e93020baccc3b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = cf271c985cd39fddacd870f2be45eeefa6b1f7dd7d85d4865708847f3916656b4d05ddf593a0bbcbef0ed984c2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 5199c1fddf6fa7c089b20665662284fed97ac3c925973bee516767b4fe1e0005fe476fce94bd3deea4d0c9fcfe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = ef3a374f39725309cc9752d6e661c79cd8db58bdedbbd7d6b08fe1554644e5a601433bb035240dcf7a3d9a38f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = c3e155aa10237e1043e28a7a8f681b91792e13bf78c897db601fec3d8c284b247638467a5a57dda646b90543c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 0e72f2d5e27c37094638f2d0e3c1b1d8d7c745ca85546348acb4ab8fe1a3d379191509189cbdfc4245090487c4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 27ac400f3b4beb50ada443e43d74c46730e1b71eb72e97c636d0ff977d79cf91bbe87c6913d4f9601bc90ccb4e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = e8b2e055c163061a6234245f3e6ab72c9c7e897c2c2d00e298d3774f65c0f538e6172cb12ccb36a98278f2e3cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = f61f2943d8a4648282206473fa3702cc74fb1d6931ef2a52ccc88fc4e4b6ce23667103f6d452f691e591e6afd2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = 0cc73e09604e6bed58aecf1b365285c56f5a94ab35c3f4177fda4b52757a1f003c46b9ff528863ba9a2644dbd7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 2e5ad52049529415c2b24dc5949a128cb9045304e1645d428e9602dbdccc9f4d8ee5b7337caf69049d7091267b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 6146ffeeb44cf294c63962c4bb48cb233a5157eef4c1688a99b259cae5b0125b2cee8a4969a7c8736c3b959d3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = b0c71e3417967f477658a019ad720307e21287096fdf9cba517c81bdaad0dddd39a8ea1ba5e9b03d0adea8b4f8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = ddc7ea7991cf45bbabed2c1fc38ca55b475a226bacdd1778ec8f90f38fb10ddd9e14ebcf57a8a472f89005fcdc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 43b4c369a15522e7fd8ffc94ea8fc0ac4bfe6423f2140d741948b99d7f37a7d19b8c711cd1cab239eeb8b6a1c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = ebd8870f51fe43cfc1ff67bae967befad397f316d183382f72dbc8feac3aad0c06808a0f914d871be6ab3cf2c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = a5abd9ac1c787a9548b37346a4a6337e694fd42fd180623fbb860e9df75b0948e9558791d5729f064c11cf11d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = 11b1858f8cd4668aba2d2c6b5f7a9b34fa4c2e5afa16ff42a3c05d58fbb2a994a387ad4deca4ad6f569d9a9f39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = fcb7d46fa9102974cedfb8e83aafd1dc2392042b8dc52dccbc0a6717440597fd710bd9c1ea3af0e3d7a362f122\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 780f8f46e0c247ec2793933ad66e2926d6461426923e2f4821d021facdcf0271fa252fde7f640d3c2780932bb7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = 0e0cf8a78acd8b57ccb6271c134fee2ee7c2ccaae1fd7869e91b07c9252a81f27abfcc14e7d5f79a28ee444676\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = d6290633b09e5511d1c4e019a1dc35902c3ef1b3c6f25050a88328f615e737e0a5a118a2ad6ebab15ddf982c0e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = e1d7d3ed74c0ae1a55c25990813f19257aff7d518c9cea74e958c7e9da405fb0faf1b0890e5ebde57958eab161\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = 337be5b4890c40a215ec994a22c052271d190bb16c21a617396623ceab9c92c24659f365a825fb3d2f83a2a51b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = faf4e4ca80ab7165a7c438dd3408d639d81be2fd41acf359c7bf2aa36a3ae2b85048415582089ca077572c8127\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 117a8924f12695b93ad2a524fffcdfea837ec279e587e23bb91baecf5db4ea35c54658dd57c3c4bcd4e7c8b19f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = fbf09a8165127a844b9d879a39addf98f08474e244a8db6dbe50d51944233086aef4ddb0cddb61fa9e9cec113d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = f2b6bc73bb81a7db754d4210c3e29addb2bb31668321a79d1673c258acc6aa35c62282f9ae89c4fe3caf816ea0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = 1dbe114873ed874af58808fe65631fd1ef2e29a4142e7f15c3e9c12abaa11f26e4a945f662a99fabc0def49caf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 424df6475b58070d56590f81e287798ec199aeac5a96f8d39f29a78fbe4b0b0a9c2991413e815edb0266f48bdb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 672f979899572fee01ee11addd53923252cfea452f9933149d53cac450ef7215a98407c997096f16a87bf316a9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = c4158a774b811d3ba2bf11e00ea2b4887abfa329219370612935a8b22f4399718689be9bc54871f6a362c55f11\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 9a153e98698656d114ce7b45b6c24341d50d66fe45a170bc570c185eec7f0424eaf20db7118d5ddaecd911f692\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 641c90874675f1ad9131a995b632648e557edef53779e6572cd9ea80e684ed62b7c3cf25380634a0f34d3a2d13\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = cdbb52dcd782784096133a696ba4d20d755f0f150f4e1c7245cb17e30a5a599e53850c53ee980492a0ae0a86ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = d2d7bd0462eaf3320587507249643315a77da7cdb61d9e00b59b7d882142daa8d64ff910b637ee892b97c9542f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 31d62424dad797797679163e601da04bfb30b1b214ee56fc514f728d3ec1928175ef03b04cc0ec8ec449145a9f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 72890066793d4ce5851795f2bb11a702503d0b02091d8520e1236ca9429f6915e8b07ee41c560e9301a341b1bf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = cd427af93e5a6e662da9d023a4731972348a186fda02f2524f197708edfc7770e2395f0ba24c0e3a73827628db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad =", - " 436f756e742d313234\nct = 0f54466a39ee0e3cff12f715fff595576d925f76afeb50193173d744bde8679fae3dcb65be7e307b23ade40504\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = a30fb4f1fa85c078468ddb6ded139106b6b4f19f4e0c9f51f32801a3f67af90fafd3cbf46c9692ab54bacfec17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = f5205006e1605b0f5b9943d5bea5c452c00261fe468902d948cb4e77a88c9cfbd9c4f765de197d67a0a2e7097c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 5a1ae229d393354ef6188759e73ceaef47c5c5038a4764774f996035000d34e9f8235f7a7ce94c1a6a29d982e3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = edec2520d385d5a75d4281d927865302c61dc3d99311ce987fe9ee87c2035fb93a5ebc2e5ec9396a9ecee6b973\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = c410d16f9eec0b1f2e6ab1a65fab63885f1555e3499d1883012cc94ee87490fab8e82d40b749a317b15b26494b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 14f1d6f624b582aec247062f9f9d6c32d89c80d7876d41441440b324f9c769e4e071320fe8ecd30a8041da7acb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = 7f89975b443e215589978e9f61e6207cede48a6e5b19ad4df15688babc33eda041ae74f5476b6fc37f10798dcc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 91dd02deb3f61e67ff45cd8a2c61aa6c39df18b4d5676f7b6c57c0c274b4a65c9d22a8b412ec9eb2e2fe5de3e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = b3c6fe76011eb105e4b1d5a511be0e863b5b3f3832ffe8afc84966b36ed4829c734b1191e7fc83ea94db64b024\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = baffbdac2c8c9a24909bbd467ee896625d9dd72eaaa11b7ee1520cdf64412c20a07fc60620ff17e9c19f5cb519\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = 8a7bbc189f3b80d0777d94cf7e47270b0d120de46e76de9a896311d4b8e4bb1e946475641d987c15e1abbd39b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = e24362464d437c2d00bb59f020282c6a72c43bdff5c660c6d7184272157248edd7362e20550545cd9b7e2c54f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 9808dcdd8dd239d2405dfa278479dad5366feca0c6e15cbf0750c68e092c08fe02ebdb029f0719022265299453\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = 6096422f4c0a38d68b4faf4364e22fc98534d594b7791cba71ca1e1a381b318158e34eaf30e4b030206792a859\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 21f71e717075903e15db104f6865b6f7047fbc3dbf65f9f648d15fde45c1755072c8a211c1c0bcf5d5b42e4137\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 636e85e1b727f382bd1d83910e0908bb3f47a204b0e04a77722c76f168919489727df626e346600f28d0aedd32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 4f6c63ce156ed1168d83778579215ce35312166bbc98d02abc4ee03c60d02326ad07c51d08777544f0705cb7ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 8f8359af17b3a5c18343ccae2b5d553b9994dc6f7ea613fca8479529f842decbb118ee9e74ede49e7003b49f3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 221270c0f2ac46fee06b8b779eab41baa74d0ddcffef47b9ca30a33f76cdde4b22d5a57bd91953736d98b1cb60\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 23a8555e5165ef29e3d30d087f471c2b28eec5e94eb818d8d4fa422757019a3e1784271627ff2b526333b740e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = d375e5d6ba2387ab0f19fbf63a55af82b4ea6ceed080be285c6efcec7f1d9eaa7717d8bea52783beea0a8b06d8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = d4747347e4f5b93863cb1079951819e9148ef5f5b830c45799efa13ac446987052d47b20b678621f8a223debe8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 9d759d117fbdef4ebb9b70fabba081c3d2c6e083faad82999f9b2fc9ecbf738351594eee9d949df083d9c954e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = dc539696ac9a42698551ae070eba7dc1b540ab553dbbd43e1113e0f1079d3e6b092e90e9fe9b5a27d2b86dfa50\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 6f508b76afab6ec152f4a9f19013f37363c5f348ac098e172efe775f25c8726190eb17256fd91f21d6aadb18d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = 0ea02391896c4b37451a3863344f606dfbd654afd7d58aeb29b09d19768dbafeae09e858f6726e6e708130db19\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = 52b181eeab88887689810a72ab9ca29eac16910f635e5eb2716a47790017b3782c9f8dba0a1bce3bda527fced2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = cd8c5f53ef7a6a19493d3fb4d88a491c3663c0a6d8380f53dfed5f727e583ca6de725645c128a6e739c4f928f5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 5876a1c9b5971b0433f9dd08780fb47b4bccf298bcb9363c83a376ddae778d9ccdc9bf13f6f81a818828e48dbd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = f68cd40a6d61712410ab2c2d3fdf3d5fdfdfebdc2e533c6e9150615469189e5854cf4424022aca568bbdebf527\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = 3b982a6feb4b033b7b742c895c16d0c273cfe4a3e43453677626fc8eaf5867b26622ab8d49cafb444894ac1e17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = 3f283b4367614462aeea93abb6f5e565a9138e4b3fa3453b719bce40170210869025725ed494f9db4416b06411\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 549ed49d0ed44536dc6f9a73fcb6cb6420f0441b87a269c390974602259aa376f20e16c42da372d5c1b397da28\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = 9f3229384c4dabb5e647618f501b66989311fb5258b19b4ad20c72874f273fb8a434dfdafc8803346be8d5e801\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 239c4c8a6dee032f79cffea36724709c2ecdde052ce0c9ae6c15f7757eadc11ddb0fbb949ec4720040d039a3c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 027b6cca81e30aa3f37c68f619badbbf4aa9d26c5eb279ecb57b6f5fddd4020e6143e49920301c8ce1dd0d60c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = b14f60943b33a79a398b225a517a0f9bf03709afa714375d4398371551e91834ffa11baa6e27c878593113596f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = c8b145b8217f0b86a8c69ef1d835bfe6c2185f22d87b938cc2a4d838c830a75dadcc7b5b7b63823d3aba11c14b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = 53026edabb6dddcd3b63512641c2134801130bbbab6b1b21cda7d5e4a48af68fd56287552834f1120be8980424\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = cd52eff", - "6227d1e8a9201acb50faeeeb476515857f0e127a0db69176d41e70ccc9c01a9d426120389f1d08eb5dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 4e9c7956a5fdda91bd84fd006df5b298edbc6055fbf8553c733eb55658fbb8a4d3b80d969838bf3eb2153c47e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 46bba4391f8c75515b7a2b2825071d09b44a73450185375540902cf86c47917fe9f19156db6555d6a8d9e4ec00\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = 69aceffa957a4fb972a42bbbd1daa8a98d1dedadf925e827bd41b8e8e4adb33de639f2c8f92e69ce7669a63cb8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 4b44cfa8a50a1eeb357b08f1659ed01fa0527d3c4ab59d72f0bf06301620cd2d25be3dbb3444c3884c5366dbca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 5442eafe977df2fef456f9658e6e4a74b7c90180bf8a33d2d5adce2958bd343741fe1579ef2f78a52f5a0842e1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 30b747860a4f39eeb11e3758a15cd554142490fe12c9aabe5d3c71fdce34e69a6c1d4c799d485f4d4b51a5c721\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = 608dacb5aa99f31f8c957b3c4630aed121774138ace30d373dd98f29c17a6892e1a842d727671721145d93e5d5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = 6fd543b032740e762f04f6d90d83e75183a997214883246bc24d4236d6e26656124289b4b4b6accee4176f1dec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = 6e3cdf915393c8a4265055c1d2671b97776e074115156e10e7f81e69adf97871bb0ae58f15fbd7b1e31a395292\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 4bd80d3f79c99c40b5fa3913fc83f5a7d9486fca22f5589f2b4aa50c2b9d86e3c0f1a49aed3ccc1c9e6164e7bd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = 31ba0bc96f3a6db0ac4bd73b17d5a0f21ddef1668db1bfc5a3f3498f88a23033cce86933abc8831f62529df2dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = c3cc98fa65baa464cb950b3c539c5988ea36f73bd3ab13f85be6dd0df1f9d79a9fdbc369d9c286253f78126e93\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = f337704ea92c55ef28b1cf904f066c7b62187a313051ce165584b40a2aba61ffc04dfd01be8493e15967234c73\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = 3050885e6e284811a759bd67884ab62f1d0bce7d790729d6cb224811c83b73cd3d708d85b826e204c5978f47b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 461dd9b8e3c50875b0f07519cdb9aef7d13f34df61dd97a093637b6ae09cd1e24741e40a2c309d0cd6b11394e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = 9f795bed00dc2ba48760fd5c9cdc2006ac435ae471a69c8926019f7d71919829dfb6359bd54b4d87c04b3398b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = b557d7f6cdfc4707e99c047bc831a0558f19bd9b15ed607f143aaa85bcf73ecf2468752881c6e02b3e83d4543a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = ac251b361aea0a771c028cc9ff768994d008389f126970d9c89d1b8713575833e3757fa3f9efa076b5e77ec318\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = b69c7bf9d7ef08541f4bb4d96030a83fe3fdd77005cb16c865c7923ba30b3236955db8b28e7beb3c0535b08f5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 615b848aa99f4fb56bf436f6673145784906fca3172125375eeeafc57d895d3f6cfb2a6305d8e09f4e077278d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 1d4006772989c69d4d8b41b189ba68d1216d003812524a1db206da42f111ab38da9de9c39b06d0b5a0f4f7931f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = b9cd2de5a742eff0f508eeb3a43644060a88a73f5476e804e7be8d426b39b3f23324c89bc653e320b651cb843a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 33d5a57af1cfa7fbc086b39770180dda5bd9ac8b7fcfd5ec8f3608a8e239ab39c6486b6733b4978c0cc011adc5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = 3f9665a5e33e089fcb79413f53e79c40ee93ad5b2a6de97a35843ded62fa277d4c258ea260a5c7e06f95a8d449\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 242b8fee457d1c21311ce60c7774b6262852fb64e1d4f61de6d11f002535ee6bd9d65cd7f87573e1d8cce8383f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 0b6e167302c1351ed4b8543c0d2879a7a8fd58e42f906e57279e4b52d8b9773e9f6a10334a5dbc07eec5577708\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = f34086725af61863c42947ed52aadd66b4e48b475f13266384e48e2b536c3dfd2ec6fb984f3bdfbdafa84b213c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = a53074ed3b88343c5b44799aa2cb6b323ef5b0615f948de2784c00af2709f7afa25f987ae24eb061b69c6ca2a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = d293b46b823f01385c458a9bb3125ac70cd021de4cdf5624810a9899d3a3ab4394a3b8407f6a49ade6ed95cbb0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = b1c77b724b044ba27240fce5f840c4de73d13b00ce73ba7582930d725a9766347cd6e210362c6ad01eae100141\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 12afbe5e92bf061c3ac2cf48919616fc21f268cee9dcea2c9f61e02d9c37d0e2a27f55383b11ff4a8da4026a2b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = 7397c4a17f59b44a4530f2b1c2b766412244d31f340ceb6abeee44fda4a7e08bd390cc458b19ae003cd833143d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 6181055e55e9f226013faba7694ad4f2655fb7c4ac9776b98fa9cfac6d4373a60199c6501a14461eff0ebd9eab\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 51a0413101207b176f54ff80be07e219d3c526633cc83a4d4dcb504e2f394ca8be6c927c1698cca387eff89f8e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 4dda2afa170011d4a85928780d19d0874e6fd993c1994d23e3ab6abe2ea48e8b6cf72e3935ecb9f5db85978500\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = b37a22b46572fc97e5ae45043834d8a19bfdcae1b98111cd82135ae2f059d85e686d464e8ecd5ea42c73f20362\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = f8261dcdc908d46e6aa03bc25565cca2f2e6b86436ed94bd0ca94fdf28001b8b541a2dbae111b28f1a56a2e86a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 64628718d4472b3f592cd09d3e1180ddcd7d2618129c0665085d3b377b3065c03b13c3e3f5cc57cfec3038c6b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = 3f2ac05adeaaa8d70088302c09bcf3c2e29b11ddfdbaee8a2aee04608241ce8e663fffc4421a92abc69a1c9f80\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 44f72dfe1d6de08f95407f63ec7fbcd97cee0e7", - "78b74268d7a50c994653cd3443efd4fb50adb13a6d6c79ca9ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = 8860128148e7fa751e2176bdd0989f81699f4a6f8db8b9bb9a740878bb98c1da926b34e7f10326527ba27dfbb3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = d79816873a6e24b3738576e66ee2a3cd2faca1a8e6300e0bdd7932f7bbc2908f02af2bce13ebdd6cc108f4c9aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = 6925df0f28576eff6d3a575e8917bd1b94d3f656299e6d7f10b6cef87d0a228051c21e8c4adb6202396cc4502c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = 45465e087d0b390d3a13351a12ddc2c20b3055d2868be79465bec9a5eeb114a034dc04964928d973313b3a9f61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 92d94f52220fb8908a226599d67f101d8803a6b38a59ca1cd439cd42fb3e9dc3cbcb4449e36449e5f9823476fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = e95cf8938a01158d09ff66c37a5436d6118db2aedc449951126ebf4184da493803a7cb6a71dc0e09cc46d42a22\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 95ea0e88e2cb4b88c1669d9567de88a8f403849af9a74254e906ef595586b2e168eb0cfa2d6d258dc7b75e1ee2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = e5c938d2605a5eb68fd5dc37a3ee20a83633ed5e5dfad218bcb2d8962eec2346ed040b4eab2a95b44fd98220fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 9f75c8ad1becb7a32fcb307c5b29a91c53c7e6a745ae7664071d4aa3bd23c8e99859f1c4731473948a01655e57\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 5b1e23823276f8ad3a202ae5403efd60eec67238703767f85e2f7d2191670491db06e109a0a23c47cea7ea7f0a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = a954766abb4da6228599061eff24e6e488dd28e645044cd2ff194114dcf8676da441f5d3d6f6a95156edc01d58\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 08388a64ac543cf748ec47e7e6080a38ca18d40eb3ddf1efdbebcd57d3f357aaf7ce57f7433601175bbc2a97e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 41d792afa8a74fd0d9bf4d9cefb406d9208b3364dd9a4059234ec9c3d5ecc08d5dda0e8df119467663f8b770c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = a765697054b7d1bcf82d5a3869f01ad632fa412e23f8b517ac4745e2f34954c422f108256d36b7c12ac942a9d1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 164e696bd9a10e227fe9a3582e40574fe59d225661c5cf09a7c75423f8ddc370337292bada80e48b9f7d88628a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = fb6d6c347a61f7279767a92897ebfff446e929562315ab50adf47cea14d7f03b0d86939c0b0dacb245fe4314f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = 61625bab2d94464510430ff6f74793cfb64bd87a5ca4193c5b80401058d082e351a36cac8881aa083018f9443d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = 6c04a3f61cc9bfc10a6e67e2adcb7818a61a0709bd49285c5bd069808799a4b888292a4a802c15dd38d75925bc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = f4f8b3ba316bc1109069dceadb7809b2864c7857f8d9ed3f8523fee84e4033ea681bd941868e1190d40ae96b18\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = 1ecd688ce744a684f660547887d910f0445b5b7167ea29ad646f2668bb064d83160205b5e977e7487bb4d06523\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 38e766640dce7ce1edf30aa96c4324763036633bb4d881fcf26225e3c021e333ca8aed8288c565fa74e9238333\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = 8bb09de244855723d0b697b02a967bc98d064bd529819046640c1bb009f27c9bc85f68aebc1da97791701e4e53\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = 5364e964cca737d51bd327276a0bb9340c4efaf3630b6086b4b0e20205a418d4fdc8855962da8b682eccfd53c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = fb7a049058fade2c1653b3dccbae8c4ce3c5d50cafdefc618695c8a8955a8b8d48cd792c97b9c7599ecaa08456\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 72ee72219b3239f96a902837a653fbea4a652f76e765ea4009e97f647fd0441f23abc6e6fd4af79c91bd206307\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = 54215a6653acd4e6976d5230607127f898aaae52addddebe170515d8cd6551eafc0e653d3f91e714dcc2cd0504\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = 1375489e8fa717c36d15cd26c9519c7c798af560b41e354fa86fc242760cbc448fe81de05044f1e8671e3a29d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 025b901c822275bbe1d6f72358f9919d76ae4062f9cb29f0e8c4c034e2c8791f198ed837c5a78c01ace2a74e89\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 7a7d9406e7bf753493cdc3167253e53b21ab34b5fb906c13255fc63001566aee76f1f2ba9dbe2de613e4178195\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = b192c5443cd1b4434c3d5f031f56fba802c965eab7803371c9702dd15927d1f842981c633b28e93f3bb9254df1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 1ba5f39d42dc02590901b8b2b755e528ca59085feda6c37318baeebdf6604cafd79a26369a5d55e58c45d90645\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 699225fa0b0a7cd2350d4e6100ceaf21945bde25084b031bf2c83bdcaac73ae9563b5e3f60366d4f152ebb156b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = 03a5d97ce6e8ddf07a3c2c33dd4d401eedbd09fc85ce68a5e52b1a2d63de672f9ed62e5e4e3a843560b4363937\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 177a9525be60073909a731825a3622cc60dbdd7540e7fa6b706a45beff03f8d3c65220d439832a42660caf3beb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = dc3ca9a852da948fcb4659fdd6e3b8fa307ba56e8face0f3d723582fc06c090a7d817a82df0cecf86335b82e31\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 6ca9b591de5234579a0aa90bea2f016d60cf50e77bc2a06d729579cb8b7b4c68e5dc6d483d337c5151d2989180\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 02e644e2e21b35f8868e786ab534c31a485b6e69097d10df2a25f24993c4d4d407f067796af1ca127de2f325fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = cc9ea8088634939f2e757726833e70ca2b00d7e617b1e525bc147fbfa9c6b3d29621d38a73e954944ff4e9ce5a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 180bec2fc3e686d2f37f2b18a3b0a195a2277c28ffb49d85bcdecbba92f7cfd3d1832a310baaf01ca9396c3d8a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = b067fc48293520ce29f528b1bad11c0d38dbbe942f0c27c0ca953469dcc88bb1fe4a6b1", - "56134ec7803a8f6d367\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = 42bb52ae652c21e3a16821c1a7dddb127e42b56c1985cf3800090a9accd8eb8080861e00f69f22bd09af42e19f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 6bb1ca4dceb6137e525632def5bb056f7ce6f5dd452edb7a69449e43e947706e970978d47554fc50707c30567f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = a37b7d0abd040300937b12ec5b6c3c43e594295f2b1d0f3292fdb0c38205d6ba925d0a11d3d1274b10a45c1d29\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 729c0bae1bb680320852f4ab084062a0b143d535eff67da55999088f9f751fa7fcee704f524a9f6b8a94aa280c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = dcbe1ab062cafc3bd1c189007316e09bba8df92eb0dd9ece681a62e1d5bb9ab9ce4e5055257c96d70b43b62092\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = b08f5a570d41d21d0aa528c9da0b68bc2006e2579a956616f40f46caa5c24f5bf2e6bd8bd5ebf4bce2b79fa282\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 985991414c213e093e8ca144c4ac5c6d90e2f136810c934831e8623a64349dfe77ca188acd973551b5241754b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 67c3d85876339d04e89d76bde220151c85f88b83718d50973ed5712373545ede91492b1f22b3c2da20d6e6d7f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = 7552addfff71040acd9740a8deda98cf23dbe410a9af5fefffb7d0a21d60cff55d0ef91eb295fc2e0ef51516e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = 8f531f2137e6b9d7b8f07af2f3fbd425c5ed60cdcd642c035f4354432d6f5d41870cf1d6bc18bb192489982866\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 18ab939d63ddec9f6ac2b60d61d36a7375d2070c9b683861110757062c52b8880a5f6b3936da9cd6c23ef2a95c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 7a4a13e9ef23978e2c520fd4d2e757514ae160cd0cd05e556ef692370ca53076214c0c40d4c728d6ed9e727a5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 4bbd6243b8bb54cec311fac9df81841b6fd61f56538a775e7c80a9f40160606e\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 8c1df14732580e5501b00f82b10a1647b40713191b7c1240ac80e2b68808ba69\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 5acb09211139c43b3090489a9da433e8a30ee7188ba8b0a9a1ccf0c229283e53\n", + "4792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 2a1a9c7b573fab29b027275cc862c9f1b1a97dcc623f836ab2e20af97b69b576f5ffef41ff8f85d25a3476d25b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 7a529533655d8f51640bf95469e06f9e33b7552ed1317804d7810f6376865290a15775f8bd7234f55ce2a7cf1f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 4ac01212f7e04167219c9bbcf0b814072f9f65fa4f3a31c5212af2d402c74c8c01de3c03334c6913e5da9670a2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 215c945d815eadbb50b4730f829faa5668678dda90fe88bfd2fc09198c000a60e3b88e7dfaaf9ef04420d0ae48\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = b27f5b4f1c063594de303b7c7f44f8e5c2f89c1890c2bbcbe31b5f52cabc1fc770c9a9f6e87128018b09153625\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 49f88fdaef767f6916a2a03a65589e7817807b4f43b2094797fdede6557bdeca3bb3428b8928cb3df940e18186\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = 5d3a0833027462cc7832edbf0743f8aad86d4ba7ba5ed1c2400a28f86e1b78fa970cc56cfded2604255341ec0b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 6125484ccc89fdda010b6b33f61f0afe10b1b054696a350ee7e11fad8e825f357583570d5ba9eb9e0b28768e9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = fed0d0d35ad396c05bab1ed230fbfcd8f73f3c099f73eed5818e210541de593cb8b693076c2a3f087e8bea2513\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 00f9721ca2fa4a05788164cb72eac9422393424b4e77f2901f673916cbfca31f38b7f4b1fd7dfb3bf5ed34c223\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = cd8124fce8c715d4491195b8e5bbb251539993077e9ca54729e3e42f3e4c8960532df32e8d7d1ede799cabbd2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = ebfbfeb6c55bb671f7a557e231f8f6cf745b0fa7f38d47f9118fb6cb62a638f4eb8e09719d2614b18dce1ae766\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = dc0339625b508a9836c1b54ccf43d76d969e933d0625c31e75a45c07b399dc3321a69718829a9571f52b714486\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = 7650cc7b7a1b07eeda0b6de063a4fd423a5cce9dcde1720d210d3fd3a03968e4ca8889a2f18b6abab7f5dc1ef2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 7175db9717964058640a3a11fb9007941a5d1757fda1a6935c805c21af32505bf106deefec4a49ac38d71c9e0a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 957f9800542b0b8891badb026d79cc54597cb2d225b54c00c5238c25d05c30e3fbeda97d2e0e1aba483a2df9f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 3853fe2b4035195a573ffc53856e77058e15d9ea064de3e59f4961d0095250ee\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 2e8f0b54673c7029649d4eb9d5e33bf1872cf76d623ff164ac185da9e88c21a5\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = e9e43065102c3836401bed8c3c3c75ae46be1639869391d62c61f1ec7af54931\n\nmode = 2\nkdf_id = 1\naead_id = 1\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = fdea67cf831f1ca98d8e27b1f6abeb5b7745e9d35348b80fa407ff6958f9137e\nskEm = ff4442ef24fbc3c1ff86375b0be1e77e88a0de1e79b30896d73411c5ff4c3518\npkRm = 1632d5c2f71c2b38d0a8fcc359355200caa8b1ffdf28618080466c909cb69b2e\npkEm = 23fb952571a14a25e3d678140cd0e5eb47a0961bb18afcf85896e5453c312e76\npkSm = 8b0c70873dc5aecb7f9ee4e62406a397b350e57012be45cf53b7105ae731790b\nskSm = dc4a146313cce60a278a5323d321f051c5707e9c45ba21a3479fecdf76fc69dd\n# encryptions[0]\naad = 436f756e742d30\nct = 5fd92cc9d46dbf8943e72a07e42f363ed5f721212cd90bcfd072bfd9f44e06b80fd17824947496e21b680c141b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = d3736bb256c19bfa93d79e8f80b7971262cb7c887e35c26370cfed62254369a1b52e3d505b79dd699f002bc8ed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = 122175cfd5678e04894e4ff8789e85dd381df48dcaf970d52057df2c9acc3b121313a2bfeaa986050f82d93645\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = 81448cec70230638b6c6b8fab63b430f3ee3d506a96229bd825fe8139f3231c6e1db349beb18bdcd8bcf796ff9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = dae12318660cf963c7bcbef0f39d64de3bf178cf9e585e756654043cc5059873bc8af190b72afc43d1e0135ada\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = f998abcc1c84c6e421d6b7049fddf1839e7c5464645b7c5376edbfcd4d74352648645b08f6803a56ea624158e3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = e0b80588421e345c607b6dcf7485dfa28ecba51c083a5e4c748deabf49cd8ce8ad64ab16a818d97c94f5cbcba4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = ad7d5a8737c52c89521932e36470236e171c6e0e020983b4e8f7bd443a743f616220c23ad15b6eba04a0490f7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = 12990eadd503e2684efd367ef6eb7c10bd901a8db1d7cbd76f1eab25b1770fda29756f2432334b7cb59ddc5ad7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = 6df5a172c5ed16fc3d4c7e55e3bc931a359282ba7142f3fa7da6d7feea0ae0c8071a081876df3d38cfaea8089b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = ac214db460440110a9874b512e41384d7960711016d470a9e8059e6f4d46338742a4e0c8190e51b0c8a7d3322b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 8ecc6adb36ae93e951da72468b99141e38103e5d5e872577d1d5e4a7fb9d12729a678c4905471fd2b767b2cdac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = d5ae8d2f471d28ae1ec85a0ea544ccf9d828bdf76946556d705d0900f4f52edabe8b1b86f760d5b27ede114bb4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = d2d736316eb91cb3a019402f1ea2f95601e16a5f7cf2aa0493b9a0a9822e8a0c5ff701e2dc4dd98c7a4361eae1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = c98347b851ad8570f2a6e25a7d8ffbaa0514fad0a67a567cafb7f2f16bd185a2d366fbaeb993aade524c288c11\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = a6ec1b6537df7d82ddd411da2fd2d6c80a6e1a81a94c14a04f928cc43f6595dbfb9820e201034b69d4361fa294\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 64136b023c77e329b6c0585cbef0ef139b7da50fb37ef0d465687be24da10465e1a4dcb9f9d10ff8d4b8b2adf6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = 4781db96aaca00e95d6a33a87b5aa4d4febc7a11cf984365651e793b96bb2fca0a5c5addeb0a4eda8558eb4639\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = efbcd0926dddc95b33bca922dbadf82df2d928f211cd1a95059bca159cbb2ad1ae4b44983c15079c3f3e5548a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = b00418a10ed979ddc5f733c8d6e1feac93398f99a03ba258ec3ce46b801028ca218de871dbf35a9f90230a2d28\npt = 4265617574792069732074727574682c207472757468", + "20626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = 9a69b169ef765433fe6ec1414ee5c7aa84974d2dd47c7ca95eca39cc3016730656fbc2632dd8b0fac86bdb36e8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = 781645d997518600d2d331939f4306c2f4ab72b4b8b6aac3d0bae922518821f5f3eef7356ede837d706c9e0ad8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = c7ab847bda8e799ce31cb751d8d8b40a44a69a797c61de5b4b26b5083ffd6ead2dc6c9c85e044ae953d59e9226\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = e598a17f69b9f2516abea3602756f864cceb7e75c292e152c0fcafbe006321d6d7229d8eb7d7a5bc233daeb93e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = 6c93a379fe85e3cb345d3f3c78983003900283ac7cb685796b739b77eb15da62834c87169fca6da3f33f12782e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = 62be42591a5e2cdcf43ee38d4a01e36a46dd349ae5e25f0cf0f9d1d303a49788b2d782abce7a9015983eaac1de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 88ffba9f0cb873174ce8467e4f0101e1b4408ac8dc6cdd9f924551ba9eee57c96901ca19c592cc0e7aee3652d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = ab98458f4280faa8a00d5bf65846ea270ce47b05e887fdb48b2ecc17e62d1399ba45eb23a370dbde5067b7ac27\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 4181af4e773e309ce7a4ac04ad08828378b4644e8a33b8be02776659d1c13c25d1cf3d95de95d15e4f251098eb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = 566c4c023069ac3a2e9ad94e29819d0846fcb023614f04fcc107b825a6004dd48082173da952b9466b898e9514\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = 14e76dca587889d13c87b6f9198e40bf708b59eeb7524a3330acde681414f0b563bb73681077ab2c3e49a34b2c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 02be122d5b3fa62dd45baacc13c060c726da0ed95e6cb64b75d91abd08c237a0e0f48b7442737c403a470ef86e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 608ceaf60a18be198b8b3ef4772a550f5803412108a8fbb97dfe7ddbb34900774f4c22056c48f9abec995be7ef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = c229036df4aff67458d0779e2d9a4a50ff775ff64dc73acde6abb01098c2b25b7e7075707d3ffaaa696fa2db2a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = b5d56ebb67daa05ca9b6c8d65742a8ef164b2ad5a108d61a77af584897ee41d349903af4e1c9a2a0f16d16ac52\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = a9406787523a3fc63adf9a04a1df6fffe90a8f8251a623bc144aa3ee0efa0d5aee37d95f0cb769d49293e154c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = 9ed258258a8f8bf329162d322a3edb75ed1799e0543f39fe168bb1aae05ccc1a5532a3c4df7aae26fcd39513dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = 958ff65e212d9dcfe399ee93a921bd0235fca5a8e4836bf854ecc5e2fdbb664fa7d9ebd5d3bd52018290b793c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 329831514fd6313f44895b2acc15657966fd6b800e63f7a53fe5198d34e30df848de3068b1921661ddf05681c2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = dc37ec0e2c08be44d9ec709138e811b116a2bdff4f89c8a0639783165ca3da21967e4d2c08927e5beb446662c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = 7b8c1fd6061641cef0913dcb80dec12274352bd94eaf46b631b1968daf5b3db6aa21336c9878a194957b466058\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 09227ba8d90dafd0948dcb79cc661011b022ae576102c7ba67cfbc4b04fecd6cc7edd86718a23a11bf97100631\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 86ca60e820b54fb1d39b4c23d3f390e9cdbbd4220e24267cea51bfd90021b2f16762a7bf44a66e79040c63933b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = e9108564d752c2c56faecfdf36ac2c849c8d1e923ad6bf331a60bc5bbb45aff7ea7c334193bbd7f4143b61c185\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = 87ffaa9446a4a80fad33fdab7e397b9376f8ca33e20e48a500446b60204f2937bae2836798735a3dac0ff5a880\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = 0da994a818399e05a41f120b7b84c1470bb33828908876b9bee7754a52b6487b092da01ca67cb021eeed43c223\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 0217ccaf0e54da8efbbad4948d54e90ca3c3b60ad39e54ac9f716ef0dd33cacdb897f6973ec66024862829b0e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = b700163bb5c7b11c8e8808199cd8a6cc82db500abaf3a2facfaf678431ec5bf7783d9395e450bb7d107463618e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = 8fccbfb3882371b7a04af739edb48c87f1f1d34621563ce766815ff4a049da9045943860e5cf2cd1cc02bfb8b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = 13813c57857656d5dea3730a4e6430b300a1dc2942a5b1400cb45776533a407143224af56785e9149bf072721a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 975c0845a0955774ba4ae6386218491084b22a721d4bfb977ab50611fb5fe579fbd041beb05c04566feb1a7a69\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = a5b8ac851160bdea05e5d85f5c4ff730c967edb4665134633dd2ca26a802760a8ff0f64096814698ed5eb0e546\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = 1da6e12454409f9ae5560fdc8274069345307c9b719d54d42c8053b18fad3b369aeaa6a27126aa846776b06c15\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = 50de3f90d54c98ca5e52d854d107b7f52c22576f1a9e77973baa6e9e9e4a69430e504094a1818294645f475cbe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = e8460cf57d8bb3ab36a6b577f1c24d4a7d55c71e0b47422b950ff046ae25ed41a66d89d70bb4b40edae7666cd7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = df0a371a1a83bcbc24105317a97e134f4ca95c2aa875ac86b99b36347159c25d84d84882e48bbc7942fc25047f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = 5eeceae1e61e5ee09bab6d6c793226a642bf5dfc281ab2f8a6da7bbdaf44578b3fcbd3386685ed8e28b7af9aa7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = fa6dcdca295a350c7614f14b491ac3b25ee40241ae6ee36a2b416e1a46a6b3806ada8b7a525921e6b98b085498\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 439423232f496bb252d246e44c7bfcb1f8a62c8fd3a97ca98107dad5632d17fd423e6b36265a67764f08db8fe6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = fc9eb541b325893b4a4818619b00b5988356bf07af8fe4c34c6dd0eca427a829fef7a3dbcf0172e868b0353d16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = 23e5725b20a8b5db67fb9b64861718c1f148c1927533e2b499891f33c66b46700fb0c6e99f37b98aa278c1044a\n", + "pt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = db051cd509ded5ba54169f883df5ec36dcf155242c24cb999aace1c2d05805814af27b5ac85bf5201282c5437f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = 63436a676cb38ed9f79cef1a7a255e6ea5aeddcb23187a43628990dc4810049c3ceb87b0b603d9f0671ca17023\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 3cc01a55b16ba7baeff8b99bad41156c284f12876e288ef0706f0bafccb6e1a02c9dba61e766a7992073f2267a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = ece18db78b48e32e9880fd5bcdc69ba51b7d4d1f9fd3aab4542c87260d15f86bacafee4f59aa743a38c0b15355\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = a0523c4744573ac4900f9945c36bb8d85c36e890b302a53f310805f59295e66dc5276a9b4a3a2c320b957a1384\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 4fdf4ade68a050e46002772274f44d948aa705798279fa4404e42b2e4edcac0b09f0099514e3a93bd7a0f8b68d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = 63acdebd758d7776c0de540d44de08fac33a9eeff15b6c06e9ee74d52416e7c791e407486c82c88f46b4d50b62\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = f86f589944e090e7bcad7eca46ff36e976a464145d3991d4ddf3381fd8683177d5ee87b1c8178c86dc183bae81\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 05f5471471b5b660deb10c97bddd25dd194f7f43f256725f055110b25bbccf4033cc99da41dab17b650b6a88d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = 5fff11dd9778ac87d60b20639d261508326ddbb935a6f9fa71c58d20678bb71356ad42f0110f62a798b0941e02\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = 80b2e9bba9e59d89c86251450b7bd08a53aa618a0b555e74224642d43924f5b46d4e40efc5291178bd162cc38a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = c31baa7d0246c32738420a7c848f998be00e155022636b90a4e2f5957fe7d41ca78005d5562e1a2ed06e3f80ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = a0bd8668746dd5718d0890b32df5a7edff64a31917f2174e124c64f2a9e454f9cbba573cd6a338f85c6570c437\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = bf893670d1f7b8fc9980b0dcdfc7245bc8b27fb894f9607f0e2fb4cf09b50951ddab19165579b00421696ac21f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = aedf69ddaf28dae07110560ebb7d1ff2f20949ca874009b7c99c6c316f1592e72e48c877a859dbc506cf99e76b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 41e85cbcc31f046537ca10d1e0a66e3b6056a1f46a27cc96645d885aa6eeff6bb0a4ea4edab73fb544dfe58581\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = f9e5f909b0a75b5d92b586597d4de6e740b5a83fa2d78ed1f32bc11e147c85496a16fcc85b66fce6ba94e6c67c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 9baf794b4d654aeea56be02d01bcb21d2b186809e138724cb6114d49a7a6fc3803cd4d864de78665d12c5a6425\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 2f224c7f088822260ad71775444c01c71bc871a7f56803b95c13c9f159a523ae53c000d5c21f12fc76763d2074\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = b8047bf627a69f930658561d2d005a7e2f12e90292dc16a9c629645409a4de2e86679db9faf011901a69269e1f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 64e7d452410b8d53713677ad165fe962cc08952f10f9d278f16f73806b64b14f8780834a1338a19924c4fec4a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = a47b2785274a366fcfb0444ab8efd960194d6ca56d43c982c6b0b50fde16a9ee95a22cf54c985e2429b2c21a61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = 200afde88045125efb6515a23c8caf595f05a35509095a967378bd84e5383a306f72f6d5cef6af15c4563b554f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = 4b4843954a9e2ba61595c5d2b71b4feff5c84232e53d6593a702dca7cd0a5ccb5d0d3725d7f9795ba1e7689b49\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = dfb69ecc70667ad3d2adf8d263d012cb44235778a61ccd579863c6bb8b2d2582cf1a391de20f155b2fbb84ef2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = da056aeeac653289bbbab6a1aca568ae68103d1cb1295f7fd5491b2e285d26e0ce4502786495cdd6dea5119050\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 51a2ddf0c656fb01e203dd54bd80f2626727c33a37aad2414e3fe5e07a9d9c53f7f035924c89ae068bf8005aec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = 95a1a85f709d79b0a58e7116b6323ddad572c165ffaadac7ffa9598a262e30522603d4fe1761e42408c595d0f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = c4c2c129dbbfe2b327352ef4a137159de3a85802c4930b744134a62e35868f3722053fbaa9a5f1cb16d49592ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = e5992c2caf9e0596fcd502a4b554300fb454a26ba2a99e5fca0e8c0f2a1d640726e322e41986b600b94f82e8ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 27887d96745fa8c476b816c1e8de4fc7389079baed2c0c291af27f9b802d49d768ab7ee7d8b8ad6a4b4efdf081\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = 49f4ab17cc03b6e18d393b56a3860e9d88f7177fad47678c94e15da52f3aabbba208803c1d3ebe630385a612da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = 0aa5ff588989b5f855c507fbe0b002108bfa9aba5d3459041c6282216baa58b82a54e81ea4cd7ab8a6fc5d239c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = 98b19c082e948172ea6a0c2e7bd1b99adbf828936f6d2b1b356fc4bb7545839bc56d81f7754f32110a768a908d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = af857d081486a28209db9124f78e6bebb651854092483d7b74e0c26b076e8d848918ecb6c7ebb0a3b86f31b54f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 7fb0ebececaafa792613ffc21ddd744cce2c117a7fb4f7dd98630d5aa588557502835d75375fce13af191f2c1b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = f5c519e52b8ff3f45f42eb20df56c11da4c44f65b14518b7d8fd663517cc33121f2606d7d0ebd28965ca7c79f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = e215ae3bc8168ae5c1e24cd9ed4ddefee8a663813c98aaa94c97fc7299e27b749e30b63e8a63ba7d66a397c8f5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = d3fc389d3a47d3b4f57ec7bebe6df29561d5fd0d08fe087db6bcf11c3859cce5e31a43d123d3a765ae425db2e3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = d559c490d3bf31b205c1c24df652bee186bebcc9bf2798f3e3839a171765d4fd6064cfcab00d0a4fa924bd77db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = d94b85acd8b65f6c30d0928c4ab64cfd20b6", + "8cd32b6e9c66085255d3adfddff964f21f6a6a0de506b3d0e60afa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = 844d58bd48a973956b27134c63c95abc6ed159671601f69b49e07d372a9df1c754c68ea906c4826d40979bf6cb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = 98032e309da113a76dcd4ed0a1a4c1f912701b39a744070bebe648395d67cb4d7e45862a8b1e0bccc068da3658\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 80586eb97612a4216cc17ae8a28e0f53ecc59c09cb51d48b59c546e067db7ca9080656297d797d1861b3f31aa6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = d881138799714f3c37801f45169a681cab1ca82c05f7ec3bbcf9dc46268129dd6d06696fcd0441bccd0fecd084\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = e22d4de220344386a58c2c9227c390d64c629c896db4983c719117a3b296db4b8167d022416dae6e2577a1c831\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = 1dc52775bf6b3039aff1c911e795d0ff4ff8d33e11a22af4ded075c5d9c3d32082fb29e30b219776ace8e9108d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = 319f7752f2922e1998b657deef0d60fdf8be55774ef2e092d0b14cda85b53fba177892cda90eeb8484f209ff67\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = 6bffdd2a91a76ef016820755729dd1cc762e3b96dd4e21a1a07522384dd59d027f4fbbade6bea645ceedb7cf3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 11e601289456e29cadb4573105efe2d186915d7f1c45b77dbd2fc21d1ad78b9ba57d5a48f0713c46275eb61e9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = 4fc545841eb688bec47b35667bfca116d95f075e710fb3480441c4e0182f7d70b87fdcc4325c79b36ce6a46c8d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = f7097d2cdb98ee9eda11bf59d64b43aa10fb8b81b027df316488664f6720cf582b2ed8748aa1b76bf476056d68\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = 3af5a80b57cf7fdc0fe58c1d86ba214d79c5ef1412948d8eaa4047613b5b4e6bb65808fe2fcc559aa0fd6c0ce6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 073638839b556b5f816e00d901a84eaed65a1d0f7fe71bfd1c25d09a44a03cb89cea8c194bb497eb04293ccba2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 9cbeb946854deb363f3019e125cb4eafcbf05e29355736fd3c46358db24a63a97c727a49f49d89ae0b8e5c19a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = 02aa1edf942b970989451f81f00521cbde12a481a59ca407a5b0ab61ad25f861535af165f4c09dcdf8cbe6f4f3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 6f37b8476decd18a872a1662eae5906c0ef03bf6d1c6c33965723de049c54ddb7075c67b1330ebe3ac9ed69cfe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = e4b262588afcabc486d0dbcd4b84ce500bd171e88487766bb4d63e6572c2c614ea75cbd81818c42f30b26232a1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = 662e4486489c51c83574350ae1f76eeea80ef585d7232a4db6f2ea5fb818d59e5219a754b6b5a4d86012e9389e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = 5562be7291f09cf9b3c9e7622af65846baefa84b38a69353084656c9681bc3c33b7c3ec6d1c3c0111de711b8b0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 710caf513593d917cebb4a3d12a49f47b4316540f8c8446db7abc82da4710d43323d1f9fac121c36e39544c34c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = d8c8ef69c4ee6a0f820d6a8e45403fab4549192aaaf48ecb56cb3f2becb39657c89ddd45d1dec4972551c5cb19\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = d77337383dae131898513e758d30af2f0800a418668a6d159670d26d2550e92703565d84babc97014e517d32ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 8904b0c8f8dd8186e9434f24b62e28f9109caa6f74ba9a1881e5eaf76fd52904b969bb6dbeae9fadd82a4ee832\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = 983be08bed47991c01a1475d5dae7c24b20cf54ba0d7efccfcd5fd03567bccf7d2efb4668fda9b3e0f4641ed60\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = 0e639053bc508f725b7049bdbea8e4e14439d0b91208ec0a5ec3a2af4b9bcfdcd82a1cab379280af9401f4c87c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 59836a335a151ef278be252723abee0953fe521b7187f523b03690526060e27097e0387fcf4d54347a5a037595\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = 9d69bdc61e64e2bbb59ab52d51a5d6b126e9e7b2106198fe700381c8dc35064c9f3de37bb360da618be14c20de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = c55c37cad984284d634ee73db6eb5a76a4d683a86deb2f53be6cadf460f84a1a60b5035f3a0ca45b321bec43a4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 755a83c6d6a702070665eceb72f71d1e9a5ba1223445a251f8be5e3e218103b61f1926be9e0a86efc1212fba07\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = 6b7907669ff3987ee9c3ea832b7b19abe12623b141c6c1c4c6d6a49000026b3d90232da644fbaee197ab67df64\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 1b32957f79a49363d4d667c051f76d8ba143207e4a91e870dd0106cb506336d261329002c92ef9f121094bbadb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = fb489163a7e7ac0b9c2d731919b0e484eb2d31fc9a5cec166b2dba01d6f18589e8da0c892d3b45dcb2a8ee91fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = 2e5e5092c57963424f18ac82cd2813f727f8a26a155f71e32f4e09d6887bb8d21695da3215acbcdc13c3514cce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = 86a7d68707aeb690f327bace44b39f091635626446353652dde9bac18e9a2c4c477557052ba3bcf801b976b608\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = c1bb44d1ce3a6796ebc9cf92d252de0e711336b645fb1f63459df7a3bed93d2fd8a76bf80ea3004041ad075a16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = b49e9cb962459433d55d940628e5f4ca0147cdfdbd63a8dbd6fadcde9f567be0d84f766bc0c309e1af83171155\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = 3c7581c6b7cd65668f29f99ea81ec939bf926e80ce6a585fcde3d6515d2a94ef5ce6e625acad1d6d0a10d10f5e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 1008b16c05c29ba352d69570147f63d7588115d43c2f4272d6d208985d3302538b44786f27e6179d1c8ba87d46\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 6d10b989a058a5a9f08146519fc37dd98a54821a90a3340b93e3013a2ca87fae8a30c0d6dd633116516df9c1ef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 7ae87645153c2b643430bfb2f34ddb268381ec60e1b895a533cf4e5bf91166258f07", + "8f67f5b14922090a3f27fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 6e52e215f4abd43ab4b1bea110953e5da9e9a6af452373f1eefe86ae1657f0f63560c394519f2c16294cd55825\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 7346f609ab37a2819baa8dd5151bc0b60405dbe83b84730794f1efe0cf2cb40777a110095f23aee9adbb8e0e36\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 90b135d13e01f5b2bd1a2fe275e771e960b1ddbbb7f8f297495a79cf0bbc221ffb6949561aa8e52934e654e653\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = 9949b6ec08af333d9edbec6f24d1492b4c86ddfad845ffedbdb976095a653f050aae63d2a9118c27d9cdf3e47e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 40edc2b843da05fa20c84b7e1051f623afd235270fcca29552cdff69c2f727277a287dc3d7d4906b5f0bcef44a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 0365c963b4ea7da34bba7484e803fd7b825f858ec3352610361b41d0c589de508e7b71296c08573018a78e2f59\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = ed3d116c4af961f795d735338bac2b14170dcb5c3e6e2696804e55e3bb65eaebc23ae875268b520e48be029b94\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 89752e534d425a179b43616db8fe503c4ee3fc6dfac8e85ef984565044982abcc7d46212c607ed81041ca9b85c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = a988260aec1a06011b2c740bfc4cae0482eabfd191810cd2fb95e342104a14d0d95176081d9be161bb597b6f00\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = 7363c1bc299398934f4fad4185c93573bc80b367c93f7605ee2ab97a3b18179dc4761177c0e2b0c3d87dbd7bf1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = 83cd7966ea988b9fdb064c1282d30d41dc9c4f37de5ec390ca0a1d55c508bd0d3af1b481f64541830cfb9b0e5d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = c5a20c2cf5336d791e45a4e97a1df88779a79cc259ebd9ad3b7406c2f42f655ba5a235e4f3e6687b21d21c129e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = b84401ad73b092c5be750404eb74ad48c5f2193835495fcb2a6ac8f0bf9433d92d8d3c17f0722e3cfaff428c39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = 233c14c55330a706f1269f1a81c7381779c14ef2cafd12054eaf740bc9ce13f7849a0143ae9ad5924c9c31121b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = 4888309bc44a04ba1708d59d30495247c0eb1e55e68d3d814d8eb8d2d9df704babd92e5d2a3b61cf0fa0599570\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = b8be632847c77c4c9bd4d6e448942a698a23a630d7bca02e4eed4e79b146032d60400aa41d5bc1d82799044b3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = 53497421c5eda1f339ddafb9d21842d5ba7e1e93909308512ca76044b5f18c5eeabeae194c434a3ca9b6573c22\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 2bc98ea9344da4e9beb2b19100397809f75d5c4fe960c7616380111b5831096de6155c9fe8a16ccba73feae3b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 61205ce18b656b2861cb38fa0ea5d91de1e27df60fd23c476a641ffbfa7eb0c50ea000962e2d1f1796bf99aa8c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = a6c01951f5e2a019ee77b4028ba33c2e204d21563795b2c1ea78271280255f98f1b903ab05d3afd089439ae6a2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = 5c1dca44abdbcb6c895800e2d0a0e4112bc1b2a81e1953d80268c99ad235da2888ced02fa53ab60f2ce737fb9c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = bdc83d3cf8044b9b91ba3c4c4c5470c7bfffb1cf44762b977de0c79635253d71b8a9ba32d82ad5625e23ba3046\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = ea6acf6fe36fc0e728874232c30390a5e2fba7e8ee95e9f2ca719f980bc6203deaa5d704ab3f8ef47ba3cdd789\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 3b7823bb868dfccb41d9460742d3e845187ad100fcb1b4c0fce18c58bfb5e48d39f02a630cf2454dbf50d1ba85\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 6fb22b75d0a26ae07bf894e54fb066976b45a386c4f616b13c48923613ad5b87a13dece0cfa6e35c4837ba73c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = 0bf18ee332538b314d98a0f850469e2c54827923565102712558bb07af9a6fb0297510dd46d0975ba2869a4170\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 6d823e5a8fd645b8f53dedafd7a592975d8e8f0f124c0229d7c8b6db80b043cb2365f39bd8d63d468c70cba26b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 14e7e71ed3a662f1fc9d4f9eb9432ac788a125ef1d0d15941d98d0db8026eb3de49758d4001945046bc8d0fa7b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 1c4ede11879727fd70080e8d33106f1319a5aace4e35831d143c046f2acd1640321b9df29d606ceb29b479f95e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = 778ef01e05e75d9ddbaa5e2732797973d0a0d40e53310f829b2c7fd31f96a50fdcd13229db146795cbfd6254f3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = 25807db1f5a3a6481a240dab4a8173601600e577cad5703db9973ae5a3cecdbaa454a57064ecd7fde4f0ca5aee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = 64cc1acc033bb52a4ece52d51500052e41c4f716a6b93f92351557184ebd3ac2f1c8dca0bde406a36f8e6cb03c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 1414cb7aa19771b187ab8847f9bfb3d8fbea142ac7e458779751eb357ea12fe5789aabfcd027576fcbf60a0baf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = aab3afdf79e28db0ad509fa8d64d35cda533a1da3e6a76a14b2ac1952ac2b573adb22e5c7ccd4824783f35e5db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 381cfc887f4a33bad777c29c9d706ca8349a887f72bece0826e49d87e964a5307e86d24f09c104cdc30f18fa4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = 0f98fc2a6d41379342df0dfeafd13a679dc166193bb40316383aee3397ae7606798be7414f941fcaf8c7136679\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = f50864b8e23d0d56476113d7195a9878abcc16b1f1538970dfceea4ce3fb738ffb9af5ace7204fff3d62e2ad46\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 123ad7cb5df5d0f172f1767513dc77543851ad63c15b90192a00f80c417079a02ac7838bf13640ad79171e58ab\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = 00ff6ee0d24c38b8ba9073824b547375381fe08cd921c4ae3ce9dd6dc51d595a64b2ab61b268e4883f12322e09\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = c06f35ff7ed289407ccce5100e43833c86248e35be2eb60c365c87e2e189326b345c831ff639219bee69aa9148\npt = 4265", + "617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = 4adc642f976ec1de0e1177f0ea29f0da33f20e99f5f957b1bd219da9a2a90d6f38e8194ea7812b7b7dd6a2ed7f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = f08f65f247619c09c77f0c36b873d423800cbbb68b6012e39182be10f03fd05cb0df4a9063b8fea215ec613014\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 795a1860ccd2777ec87e7691c8c7b87fa60905c973d5b4cb63fb4c1ac2d64bc2ebf5f3baf43b5388ecce3e3c81\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 4eb24b8ef9de11652206ffd21185b00cb5738d4d3836422f64ba3da86e0b512141434cd91b189b3ad178975817\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = bdc4f22e46b5e4bec8c7013d3e2419fd36b47d8b3d4323c508374c97c2673083a550a5a8e425b3b3f2952449f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 0d2faa408d419e3fd7c39175b5052df2c9243843494f27e29721533446ff551ebfead78f2a19b8243a33915c3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = 08a2211770ded14e210dc9a5a711b011aec7283624be62d67754b7c0e37bf88e947180b7ba035ccccc754e7139\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 706b1f001fa04d7639aa1838e6b94c710231a25f10d30426f098965961f13be8ecc9b9031b120e4af5652b1e27\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 3550a384167bb99f123c4ab49ecd62e2a7c21b151ecd6dd0252465b45d532402aaf767f139708abfa31857037f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = d07ab8c75beec6f9b3bfa5b580aeba179c93f607828f43bb1acddcd698b12509db5a08f110d1d46fe124953e01\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = fe1c8f5e53563225b7192250e3f07bc47ae46fa77c441a2479fe28241d2b83ac3f8ab24a8b16ea628f8f7dc138\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = ca0001a376ec98bc5195d861f61d699fc08ab8e8933becb9a1d4dbb46092439e5bde711f817258a91ce864a972\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = f5ec0401b4bb76ad6664bc88e104c84ab9e23aa3df077d4019d6e81efb838f95bc6e4cc0950db56dc7e4415969\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 3287b895c5ab198fd61e498118d4c91ba8559c5a5feb2e1e1bdaa14691c8fa3b868a3c6962aa6905f8421bc141\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = 887a2c0746336d67fa4edfa866313be32b3950013c0aa3eb2bd666a6d277060f0f5913d8c0cfcc95b2e70c29ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 9e246a263d6662f70f8d5a05487cfcc99965489ae233c209262bd0ec65b4994e1d7dfcfddef63a956f3cc91193\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 5fe3f5242df92c284ea2806c0492e5c47837921cbfd8c49d5769ec8a54206ca34156358756681664090a8ec2b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 726f0392cbd3f225064c5408c90c7486dc6028deb9fb3e60ebb84ddc0b339ad872dbac9aeae61985a3cd03a5ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = 82e3074ee6f828726fd8da9cb54ff24181e01a379e01bbc1d00b4ec69937ac24dc7e055aa5e9924531f907fbcc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = 8383e31c4dfc253cb64eedb29bb50e3f03fb7d88216146cfd8bc46a6e24b259831df8aeefa9484a2b1c50b713c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = d1064f889c0a1c74c9e812980ddeb4db85ccae0b770d0d9797f79edc8924c3af354c92519566b1856e7d4da7e1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = 5cc0e2246dc23cbcdedc6be5ff8563ea527ab0b7976016eb23d029f359816c998d980f4c30668c662260b17869\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 4989fcb35d8c5d52e61f4a1dbd7de520fe36dce0bacde2832689f76b26ddd4ca326576562a939474b6813c0711\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = cb2cf08cf6eaae26dc2824aed8b93627c570956427732c9e18e8f77b9c255d0c01cf546d9f80d7edd594c5978f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = 7559eddc8eac912b20fd672610acd68d92f8e0d608182e3689542d69d8015facdf09ccd6e62ae902d4a7a31005\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = ebe4067990f4439d84f7684139de6fa2f0abdcb9002738821e4e6c2392124f17ab77ddfec293ad790044b06a94\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = b2442c7c263cf07bc84857281860c2b5e3e12865bfce9ed32b0f86af630d718f5b14da335658e256de2243445e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 2ef92ede552eb2a291d9dd81034f2b47ce79f6b9e88f87cc84b0c460fb66535197f5d3936c1b99b5ba66c0de33\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = 183220a6989012152186d775d6f15bbf56cae846e3a6c534a863b4287ab778851315d24621defe982a4c735759\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = ec0704f1a68006acc6142b6294936199228144706a5cf730be95078585686c1501f57a97d2e7a1ce561dadaa5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = 4f182c1f81ab60e667c48fc78fedf17d3f4be43479956c06871b9935a28db8ef1fb91ca7a05cf06c6c16bdd3b0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 26da513d75efa918a650d24c738473713383f129ce85ad996513db0284dedfba7b04def48d985e3f77b24f31a7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 57966eb046bcd25b0f530cc8f844ba2999a0faf954e7106f40ce041d97f99e69d71e0bb20034a5ee46790753ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = 554122776faeec90d03157835252732eb116d796603cc16c075a89a01b943f80f334bc2b584590de10a082ac2a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 4a93387559a484b91fbd298b3bb2609270c48feb7a31c1168c2c229bf345aeee4bec0e4b71271413bf9c211c94\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 725a88ae41bcab900b27b92450c3cc081de9fcccffa58afd0f23533189443d04659d8c6eda37f10fdf0a1573f3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = e37ed1b71ab95aa52fc9ac19f0a0b0449797cbaf5cc73f0da89025d52e11481801dc3de65b34845e193391775d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 3539ee61e9a5d7b83e44c16e7a814da6fb440a55f6548b4df7b9797309bce67f63959a8a237c59723cdac3ee77\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = a192300578ca40a4d88bc195814c80725b01d479c1c4e7140c61963c5aeb0939e2fc9100dc0893da4a4ec0fa62\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = aa9cc7b2224b57e280a0e56bd4a8dcacd4981d7516a4a7e526e925bd97260b6b3c75427da747e006bc2ddf3ae6\npt = 4265617574792069732074727574682c2074", + "7275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = eebe5ba2f3a25eb3602188a6fa7d7600f83b31e447e0bd950ab5064e6ce714df761b4599ba7818c2cc80365b20\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = ae81d85a6a29eb394bd83ac3843eb61cd5e8f322d639c3a5b8ce3222c85ef0b058d1c34695fb783eca8aaf3658\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = a3265e946f45a0dfc2d20dafaf4d65cd4595c9c9c9dbd3bf7745bdef26f35d1588906e122de8143b3e316dd43c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = b68e78ed1ea01475d0775a6e20be845084de3c7d68c58611fb8c9dda3b83ad980fbc4bf99e3ee9980ebef862ff\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = 1a065a204fff91b71d0a8d92858b77cd4d9ab9f7293dbfad8ae4173d6752be925bf7f996d40ceca5099f424484\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = ae8ac359da42f98628985f27bc96aa25acc9a9e1354491a8325cbc4a5e17d30f8f77a0275761ec1d7e1c0b1dc0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = fd831d62c9cce5a711697891110acede3b5885dba0d1c1333c009a6715402e6dd5ce8d629f1056eb2eb990c798\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 2ab45b2a78a28a874bca7625da63ced2e83c11d9640c428a5a16e311053152a04b9d8db7e1bb58ab60da47df0f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = d9221ea8c84f6dffb37fca1211eef538d24e2a180a5e24dc535291faf32c7ccbe03747a1d790d8e00bb1f1f61c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = d2cf65a555de09dc505b894dbcef2f72b4ed6fe15e685b41a15182ef1105542c462689bc16ed29c3e3badd0b50\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 6dcc61746a8aa5c549fccec383e9a387039cc4ab617ac1c6b0014de3e02a104217e1c7f404724b8beb3f684803\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 8fedb6438e1d014c4eed849b7497c681bb91fe6491752ee3abb61b6329544aab8896ea1a2b80b6f1291d99cc43\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = 1746236a4775e8841dbd4e1a3e95a1b15fee50a9e3b137bc094545989eada59ef1d4a35cbcd90eafa149126de6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 075f3e87792e9ec9f1c7b7f5af2e80d3e6b3db51a319cedf79d06161abffa9ea35d8b56caf2eaf5a6e06e225cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 7c71f10dc7f02913ae8692e93a886119f6b5940a9c4bdc24850502dc163939c5e74364780d414774a0b0b6e757\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = a7660bd0d3420f847c09a034d34e086049c70baf1d183fe58af2e4d8f581eab7fb043ffe2b75b54f24b51ff8c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 173ea65a00440de994e2a6751b3d553641c57b4bf2cd9f41b10e4bb16c6b2d6c5ab715dd970114b6486d1f6a6a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = daf7fa1a6a83741e82f13262e7730447ee1c1f29cc60810b4f0f10001ae0c37858db6a3aace4a03f3e70d4ec5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 6a581b9771b748adbaa26d20085da812933d5ecf2ab2d11dee1ad560a2333f9182d31f017f02ed6b47b2fdc50d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = abd6668670bdeaba122f577eb635e56bab0f9f861b3223e8e17facf19ad716a9457029a09174791322810ff81b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 7a2f1b4b5cab79ef46c15d764461ccaa4124cb98f019782013904877ee830de5632c551ddb8119cdd2e38de5d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = e97b38dc3a965a1b2c7eac9071a4ac388145a9fc3d975c857859d3cc73574c65bf111ec3c8155ebec8a5d5452d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 6301deb287ffc74bf231704ad1a59aa60cb470953fa6bb7d0c03cf69fbc8c4fb89acd0162dff353756a73d6415\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = 1921a34039e2579c8e86fbdc731449bcec690214d157f3f9c528102f19d228ca36e8eee061f733e0eb64bbdf50\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 4943f4dc007e9d1366cb4efbb5e71cb19e70ab4bd917f07770db6bb956c7bc00fef39fb5e7f1f5f0d116552147\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = d45b763713b7aa7d36da691a52a1a6edf128ba72397fd20d2ca59afaf6df53751f04c5879e9a4118298944110a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = abb4bfa463b825b00ce013d965cb8c232593819411ed494ee6087932d4c088f3c64b0e75585726dde1b28cf37d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = 17ca4cf2e6fe5ac0ffa1409a272e29766acbb73c3454be25eea8e3ceb5d3c00a37d9ff3b7400daa2039cee9d43\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 8d73d3eac79d6462dfd82bc0f7a0a2532e2903a88259b3891a5622be390ccb882384557704ae7866fc623dfbcc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 24262541ad0b43fb8f007debefe2d0493863fe5ed9c51080c6a08e5cf747a0ff2c203b2c8b22e4647a3de753d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 624fc58b855bda904dedecce0391e91b8cb2ff6e45f04f56311512b19de81337a6efa8685a33c36b5642fb7d65\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = 769ac35e2820405b0bf9b41d1390a57665230606cfd3e61aa4b3780fda6244b2c3671fac7e67cc2a727d671f3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = 31aa9fc2c5276ddf3e045df4a3c471146e834a7e827988654843999f0d0c1507c77c57069dabcef90a286df87a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 55d53d85fe4d9e1e97903101eab0b4865ef20cef28765a47f840ff99625b7d69dee927df1defa66a036fc58ff2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 42fa248a0e67ccca688f2b1d13ba4ba84755acf764bd797c8f7ba3b9b1dc3330326f8d172fef6003c79ec72319\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 28c70088017d70c896a8420f04702c5a321d9cbf0279fba899b59e51bac72c85\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 25dfc004b0892be1888c3914977aa9c9bbaf2c7471708a49e1195af48a6f29ce\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 5a0131813abc9a522cad678eb6bafaabc43389934adb8097d23c5ff68059eb64\n\nmode = 0\nkdf_id = 1\naead_id = 2\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 497b4502664cfea5d5af0b39934dac72242a74f8480451e1aee7d6a53320333d\nskEm = 179d4b53b6365c45b600c4163b61d95cbc2f4d9e36f1695558dce265ab8bab11\npkRm = 430f4b9859665145a6b1ba274024487bd66f03a2dd577d7753c68d7d7d00c00c\npkEm = 6c93e09869df3402d7bf231bf540fadd35cd56be14f97178f0954db94b7fc256\n# encryptions[0]\naad = 436f756e742d30\nct = e5d84cd531cfb583096e7cfa9641bd3079cf3a91cda813c52deb5f512be9931980a41de125a925cdad859d5b7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 2c43aff25343fdbff864506f0818b", + "9d87df84ea01b1a2144d23b4d40c26bf655fdf197fe40297a8aebeed5cc2d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = e0a8f2cf92ff61215edbb8c55dc31fe9e2eb42a5685867bb6854211542099f9e940c4b41c192bc390835b1a5f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = a8ea1deafbe4935d0d484a026301a339d4668c43c37f5e289bf758c7aeb3e2812d0321c12b71978855883420c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 448a8892f261cbb6bf5b7b64a4fae8a2c86492494b069c10525895d871c27c2f12cd17e0588fedaba9f7b0cd4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 97c746402aa3728594f8c4f217d1e4059dae56c5fb401025ff601a61da903f2706355685954b2fdd518b81ef79\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 91fe133508fe3fa6905ce19e6c8aba53994c168664088a2cd4300238236dcc90b5d2510d4315dfa8dc34bca821\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = 641346e222a57bd4cf1f0e6a6039c77c1684e6d01c8983b568552d338f080f1bf22d022a5ae863e12191aebc7f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = fc8446f5867c639c4c3f64079b2bee8987180b88e789a64297b91107886d739ec8f492e252bcdfb008cd6e061a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = c21ce89d9947297e1de30d9a59c0815ff1508a8930f63a91d29ed89bf2a20029830728045cd54d8a00b06f3520\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = 8c26159d7fb4c50cf29b0fd2d005d9a04dd42402f8e4e1dc9e2dd7cd0cf807f5b5a230554127c85510f95d945f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 75af5386f4a2d4a27dd20a490d1feb261dae8206a3201c02ab48ede53d2a92523a6105ab80bda1dbc1fe8e8deb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 1c8873e7af703e1e8f8085ee385e694173c9fe2d66cbdec2bdce1b3ace52c13d0ff321b41d8ce95bdce73c38ba\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = 10ce2c23ffa22de0f547b33afa2f34552200ae764c65d2acf6a5366e4d2c6dbd6614d964574b97687963b93400\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = fb0e6d7705e829ab6509668862e65136cd0fd2cbe83a158c832ba630a2eceac6042019ec726aaee793961c663e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = 4bd36bb99b6035a3ccd5f41998b6d49d5562c72225ddbdc82e38d5be180e6b0e69abe68d12be85239a664ac672\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 1a1916713004d3a90c8651e9781a759e63eb70bf1d74db5d3871e01f4664ea5241035f9a09c50c7c64b877a2ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = 510ffbb00d709b3ce27bea8b8202f2fad82632d6429992b4c0f71728bb3291f20f696c4d2abd942dc9a8960b39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = 25695fc573d452c33f7bb8f61a30d1719c75637cef9bd9c11e4b48583d926fed3a31ecacf54bcdaf42d7927f98\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = 913948ede40a023565bfd70f5f47c37ba2506e09b22d4784374659c90da556d3ecdef17e89b8f749e266f11b46\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = 3fd6c17dba8dbb2a4a0a5cd99aa0f1288f0f5bb02b720243d6b7c1cc92621c1efd0dae437ca54a67e2b3127f76\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = a42358de18cb5495cff2729069fe0eb7996dbaf2138ec00f570107eca2a7c6950b9670b4ec66795de04685c2a7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = 18b1f565922a8e9d58959adcf3cb25a3a907d2adb69d71e19c09268f173157f569b1d4279c93f840d08b746b4a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 34355c72a3581d4eacb5269e76f920a77242cf7525c8d734afe8921c87deaa0780ecf5998af6e5f84ecd689048\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = ca6ded0b04e98db9bf3e62a3cd5604678e805c3ea8a8c5c390b29977662a344791b443d0aba785bd8b9fec65dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = d9065c203b0782caeb631af2ad08d685fe121033ba52b94608557bcfc8007adf68e2c77a4b6a475ce1171b70d5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 27d600688c31400608c332d1af2bfadc89d22739e3cc06d6f0f1b356a61e214f5b0ddbf7caf47b71d2be8cefb1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 9ed3e280b8605d721509cedbce556ee4429aeb48c0fcd400e30d21074ed902ce77589ac1f5d282ff1bddfa8cfc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 3eb0855fa879f7dc8335b5d426a440f19acdc0fc721532304de51323464707643b40d54812599670936eed2208\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = fffd265116539bf8b564f012fe3ec3a9dfccd9a5b9dc4ad9e2964e794c764ed63a759dcdef61ad043f7588a11b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = 9e7fd0052e15aa19e46050a2661febaf6c5f326caa52dc439eef425662661388fb9a9be58ed989760a7494d3b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 3693b73981435ddc8b081186f7a7f06fb4a20eb7c39c147f6db5cddb47e2f29f60f909c4504b2b789ddfb8e40b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 78fb4fbcb3de5bf9230fd0e41aab0b2899f331a4d806423d2a7cf91110b06ed76146a9b815fc0f5b1941d24de6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 8030cb70867979059a6e5848feb3c25f7504458da998c831594371141c868715578f3a62ed71dff8aff1afa2c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 89488d044633eebb4a41f649bf3a5f1d17affd9d5d9baf5132c71f8ad057aea36fd31ff72fc78d6880444696f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = 4ef51de05e1e02e6a15e30d313a8905ec12e35adb3fdc6ce79ae56dc348e1a636531fabf5e2c78962d492bc0f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = 2242a8228e57ca15267e01abfe430f1d6e4aabada7e38f17f20df015657d81aa898d2291c631773628f8833e9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = 8d71a286ec6f330462aebcfe15a2e3b3382eee9fd2e57123565bb1aeb319112e9e53418a2bd48d16f68a59ca5c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 87e2b695e365860db3f4653bc16bbe0389dcf225838cfb1c480442899d38a204c474565039e3e120848257c1a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = 86adae7eee8d06e9a8855672e7cb80276deba65f0b5d17e5e8ef0cf80189e69c62187605ec2329330264127063\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = ce603ee533d23f2f902aa82adf76c98a30d0c5865079840acc8ff62e7c774db66b3cb758137efd3134d790ec13\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 904d3c71ad0a4f8d6a0f087fcd93059cc19da7c9983b59da32f83a614ffdd9cf65f0eb8bc2fe3ee64a4f5c4981\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 71df", + "d30756f262628af5e5293a624eb219d2ef6d323d37096a2a94db6308e752f9659cba28d9072b71946d7868\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = 4f0d84759f83d02f49152f5852121e863ff3732bff98915799be5c8d5cfebfa2048ed83c0380888028f7dc081b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = dbb775112c824b1ff0689cb13ee056d84615d7c0604de71a825bf6998c41623d66124e7b871c7fc2ad4887ecda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = db01d24f44d167d78a9bff68828aa4340f99ff89e045476c4e918438801a02bfae77ad4161c298d958702535e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 59ae01cfcc784d69f25c005e9dec4b7f74bc05f284166ed5a056918eae0d9e1a83fd028a52f9e6dc6ded369941\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 8a5e074f9f14ffcaead4aaf599a97a8dd791c44833bd6676a09b7b87e29f1237ee926550d80a44378f025f650f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = c86b3b47535fd4c11610a1830a2847c6f7c7338d96656f8d04453edd1f5842af3397c6f762bbb39d4730f043fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = 053e3ec87d82425c627ed4c2d84ada5cc0b5253d6ae1cfbacff5c78f377f3c09ac89257d551772f6d2e053b344\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 73a145c830aee75e0fea9e3c7bfa24c9a5b1c0602683a5502fc83dc4a087e0a9c9b142dccdbd3205fa22cad268\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 98d8fb2a4bf5f772880010e4cdfdd992360189f45fe418f3736255423e60657a2a01c3e60b54d3efa932d090c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = b8abe4d887990e1e527a8b7c2ffd661dd4b65c618d7afe742281bddcb39c8be07c143b061bc607b4a8f41a3fd5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = 1090be42c502b75570c25a9b74777a4f3c981992156a9dae81c1f3a637c388ad55a42782f3785eda7fc00ed9bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 2ed5cd3dd937bcc54bc8193cd81420350e5a94f233bf52428dade8033de59a4bd0d461c7680fee19d3eaa49790\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = da16bc9c2b04ac234af1d2bbd11bb4bbfe6b32864e7381ac73604b2a870e7b8aaf10b128d8ca39b4e3f0ece26b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = f0d9acf36f857f86e02b06348e94d0fed7fb010d4e6365177ceba970c1a17e7f472240dbc585ee0cb137cd3b70\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 32199e20199904c07595fc6e9307022a0548f8f56ccf664497b840ca50176a05c72469c3231e4220544114054a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 257884a96d90d927de623709a39cb34a5981007676ba96b2e1e4e3ff7dfc499acb265dbb4e1812428d5ae31514\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 6e37fd96cc41de256d9363d9eb27868304ed5d979da469fcac98b4509719b10a8ed0c205abb05c7d2c9afb34bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = 7bfb5b966d1a92d893c0bc4ac5526a8a104ad929053d09481538b731c3e164ec46b4a6e6849ff1b6f732f3109f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = 8a70b13706ba38fb0b279449984a4df5203c05d242bd7e6af70c9e96cb556abd9088f8e9b28121d050ed74908d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = 44dd0d86d69344f086f4bbc3b75f04b1a5eade98e4d22ff130a28b4f0c60f7db23fe2c30c3e2f8269719b57dc1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 946181d28098f47928bef7199f777dd0d2653f08c326bfd10090b47bcd294735dca636428bad26d0c186ff56dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = e080406e00c83bed2e94537263727d65ce99534cad2279dbf119eeb614cc5ba0b9103b7497fddd7b149579bad1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = a86551ee5f2b9cced52e1fe1cca9a8f7e63065515787ea7f4f9f4ff51bbd7698a79bfb853913c96fd714694b8e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = f450c832f51334c08e08461d087ea1d3b475ea1964e3075e41b227a57b6f8cf2b9ea8838d54784d0c533d5b5c8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = c25e6034c2c2283f5b8e6b7f659ee33eeaf3401ef43a81dc3d8ffbb9e7a32370311ceeba97c6a6287d3786321e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 5c30e2053f7f1501eb430edccca9cbc90f01b03200ece329b232fe0a4a9baf418adf846d402c2443fbd72aa360\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 9df08200e50ce71aaa016d6f18768803a8bfd20ad405345f4cbe60cb28164eb897e5ad2675c90595d0df83b662\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = 56fb1c4a86f4642fe820f60b440e59be913ab632de2027defee6161e627ebd78fd30a606f119070460cba0aacd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = a8163438d8ea48dfdaa8ee0286efb83747796263c11e97cf910f8b56adef3f6bcc12c2aa885323d641985116ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 10a66fd85dee2f3179efe704174f2fa4fdf0dc3839c6ba06a39f947dcd9422a32fb5b7df5d6a467bb0c5035d32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 50384f9efe0ae3adb9c834114862e989995ce080f353f0727c4ab2d41911755d154b4eb0a693b0e72124c465b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = f74ad7b18fee3ca88f91c653102e6b877e1f8ceb73a3a5bd44323ba5194ac722e87e0656121001c39653bf2822\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = 3d0b638910c26c035444b494342b5059eaa485d51d49a7526bf5a76cf18ce92be1e88922f1ba27db8f29a3bc17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 4d17c2da2c4688c5ae15be76b2fedab1d677065ea79a452f3cd01c12926ef4991cbe8be7e7e5e69cf2666121d6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = 7aa7ebe84cf4c35dccf15682fdca996164f1ec056455ace8b9544b9c1b1571b8bcfc104fc5e91f5d68d7738707\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = c8300629a6cac3b1a7b408bb50e503191cbb79f102256d0bf3f25e33af30ae12e430af1bc9e44753a0e25a824e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 37c428339a389e8ce35daa03a99f5c07fbeebdcfc3e695434f2eaff8f90cae8902fef683e2ad238f2ba037b5a5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 39e65faf2c41d0bfeeceb28699042b62e976fbc3836e6a8a41ce5a5a85f9c428887792f725baf7ac68db824c9b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 0a478a818d4fc9da07c90487cef008949818fcaeeb5c1cc83f45d487321fd491ad58aa1863c4a5bb75e9db1b66\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 32cf849851e83b92db5eccef5ad9464af0133d588fb0ecdc4a43ef0c03b1dad9889d673900e95c7e0051035426\npt = 4265617574792069732074727574682c20747275746820626561757479\n#", + " encryptions[83]\naad = 436f756e742d3833\nct = ba1e5814a83a84dada756914f38e7069718ce13e97442003ee37bcdfcb54032f8cc3e50bec78c2b8c2e6402d65\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = 3b91fac4f67af1a93f5ee312fe5c39bfa915a2317c2268b594e363d368d9df09022468a5719a3cc91d07f3c36f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = 5888dab7e84869c9ad8d5a80db2e89da750780da4e3fd59f317c4440ab2ade53aa855254f534e8abf7b030e1ba\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = 9f8d979e4c9965a2e135e0e85849e8e51cb9edf27c5a48713c0342f78c6eb42f89c246884f42b925d508ac1118\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 1a3fe6ad4387133e6dde596102384e034984b26ea9c2518690e43bfcbba241b8991b1fc22f5301f50a6c067b18\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = 35ec707cfbebcd8d29a94b2a53279f06d6dad1d67a85d26515b33805cbe9c8054de90590d90ecfa2e75b319426\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = 98b90ba87c954ef7a61833679d2d9634cf6c9e0e2bd346b9240cfee3cae141f3bb886ebc195019bf61ea174fd2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 29d4773ca7566d5e9e32701d6c46c70111d615f150663e76c62c8afbf3cde30395b424530e71fdcd91abad8235\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = a3ddd151493934a6d056bfb33c3cdfb872204b2e40494b2c12c298aa2443563eba9baa7a984b4627a1aef12b35\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = 97fee29b1aecb67490fa440db94e8edb9d44da3db59466700235cd0613bd7f385621ef78bbd1a61207f61d58d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = bcf3f399b75f170a59b61b5a8e381f1254d4599bfaf906ec035aaa89b862616163b32c0078ee65f57e372921c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = b4fb4b40243ff48b3af21b81f86742faf71e9a2006c0dada26824262d3fddc428575c2b3fdebf84f777e6ea7b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 3e4774d43410c80bdd17e94276dc4c9e593dfe1be6e7e512fb0ec7e8321f0825ae52cec95ec88e0a73cee34632\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 149628f5c0a0c7a83a255124b93bae9acb5566caf56e2a44d425a045f5de8d8b99fdb859853195048e9a2c6838\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = 23353f67794a1ab146b07737c42dcbaf16fe80f5fe275808900ba8b64f7c277710f99887617c315749db003750\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = 7f682e36cd661cd0604d0d161b6747c9116fb2155698a880390b170c95a1a4ac56281296c3f92b643a43bd7bbb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 5060bd31673101670052d60db668ba50e577282f2d04ac7f55a968df8f1e656f3e54c042bc376dff57881449f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = a1a9e8eba75c2d5492de5ac21b96067d86db723ca40446043d6b518ed99e546adc70e872b389c8b252f968ecca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = 265c2fd6d576240fedc1e9d2e54ea85d4c6f948ccae75dbdf5131ab9e34e6b7c546fcd2799fd70bbbd80f4a403\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = e5cd249047639b55351adec7054b4bad49ba504dfd012c24e6664b174aa7a96a8f43e3e74c24c72a2084a30f54\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = 718f45fba90a6d7fe762a963a3afddd422bcfb69b4d67f68a07f0963542d11a9f93fa7becbe1467a6d4ba2bd59\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 83317a03f6e6f5c8a70c2ab5a13e594f71de479e37041bb665f2f7a1222cf3f989dba32842bcbc2e9d104eeb6b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = abb06a322a83405b85f2921f0faa10d142e7957cf39c0f61efe8d4ef7aa408dee8af86032f3c16a2e103753a75\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = 1846787cb992d807a28985c645ab2752cec1059250224f49da67cec65ff51d9ea1edaf496c1e35d74a39746296\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = 5c272f93edda401fb918c03179478563bf812a7012faf8662002e4e8d0c45b4faf1f8f1345b3cf93efbf0c3590\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = b93b55d7382c44f03f7d5c376fb325f009ffa705b785922525f83d81226259cbf27d5cd1d5657eb18ab49c8f57\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = 78f36217e54bba52f594bb8f0ea26e189abb484421b838e983d5432151f5ee702310a7da43b3f3477b6446e42a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 98b9e8dd6a2e8dc8e2011ce879b160554365afb06bc62db992131c2ca3ccc83d83aac8157816921da8cd54933e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = 4cf48574b0986e1b19c19af1254c62403ba242ca7e379407095bffa6e65baae539bb9fcbcab8a915d3c633013c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = 94da1edb651a79419cb2c0ea1a89c14fa3a725335e3b3b10b71e97eca026526c9d61669ddef6fd5f71f15fb930\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = aba2968f77b8170707f3b7affa945289ea56986a10070956efcbb48b6512e22f960f7a07e05c77d5debd69daef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 258e1acdaa6c7ba5e31bc1098ca42d844531b0039c399e05fac4c0c22a75fd4e308b288a24127334fdb1900b0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 6a6d65cf15054487bc8f4840b86d3de127c1a90080051cb0242f4b730d4a526659a7c059fafb0a83d937d62e48\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = b8bf351fbdabc9a5c4843b6ababef5ca9faf95868cec99c04d1d555e615005dffc6ad3e4eb84cf7379242575ec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 5a042d64ab6da7841bfe83766b66d10c272ee4dd3b9cf9bad9d8980f8b1d191e495ecedd6b28444bb6431c0457\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 7198f5b0e7d9a041570522a57cfa5db3d488504339762fdba72e1593e164a7df5316c674a592c064cddc9a6c05\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = fed6055b80361e2493dbcc48b658a35afaf6247ac4532063fa5812f10b7e4f259d557bac0f049b1b88577dd67e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = f6b7aaadedcdc89ef9147b3817494a3f43107e756990c415d4a2270312b0e257b756c0f1ba929ec722850fd762\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = d4ea7ff429ccd38d86a3a35f1a86de748cd1c3fee83e7c85dc5e52bc5134dba53d4c85368733037a3845b1f8de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 86771ccb6999dc2085ed073c6f0216cfd8a84347456e7e411753a70b20389ca84f25968d4bcf3687b8250d2048\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = 76196c59dd912a7fdf3da785b02edb06698", + "30f23a40b23364d9a8417c25a44747eebf5f02173bf254bb6535451\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 6e5b768c7965f3292010ca206f966c30f1dd1c1faff520df04114442072c3890ae5bf14295eaf7cf8aa57330d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = 7547da149fc7eb27d904143355133e920beb405a8c245e5ca8e418297f09cb96aae615d24661f834e7dffcb018\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = ebe8030330f423a2324eb863310d1c13c62ff7894c1495a0d31709ec1fe567e62954fdccac05064c412ac00409\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 99f8286c7921b46fc90023361caa5b4b2e0c3d3b71b65de596876eb70a2211d89b4a90acc225b24954224919b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = b9b31bc2dafa1c31154322fe4d23b5f130cdc8f6c92da9ccc937503f4173d5cbc6df18d7847b77aeaa11be32da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = cfa6ab15f19877c4c030522077c18d442d1cf220c1b021e4a5fa45d14e66044ef18d894360237281b55745d10b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 46dda78d75d4beb46b6e79c68abf242895d072602ff0984d22ba95281652a55a26d5a3209177bd0b78f80b6565\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = ac8ddded913db97734636b351b65a3a7ec32de7c95f9c2f7ea2ce186a9cf39fdc6734d9d33631ff7b679047da7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 5a63fd958d7da5229b2ff04155cf5eaad8af24292de1b6f23dbc1a6c8b717c373171ff46e9aa6ccc87cc38739b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = c3de57f22a0ef3147b395ad8dd1b920e6e331fe19ffc4a4436cb0587ee1f9fdff890ff1a02fb9ab220594b7f9d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = ec42e72f0a8f228508141998a0007f59bf281a9a3648812ac0f53af320375a0abe4ccaa73712ab9de8b2cf8327\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = a8ef6cd778dcbb82e48217e77e132aaaf3434370527978fc6d68df1aadb1f6b1f534b9aa58e993044871cb7d71\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = 59b52a68e18b64aaeec537a113586ca56f94190b4c8fc0074febe8238606534228854d2fd45f734ae726fe0b3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 595214d9c7033b1790e9ae70b739332711baa4e199f5457bc72c033661b559c0f1c3802bc96c63953b9e2eb5e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = f7970241897e25ef6c4fcb0224e5bcfb2cda3715c9baee3b3267c7b199c82459a2a95ac9c767d90d91962bde9f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 7569b68ca4ff6436c0a9e68b289ecb0d9eda9a1a60a3934ce13a92f57004a4b41e69a75c3d2a29cd2c929f5ff9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 1ed5e8fb578f67d31a061ce5853710851c98b8b61765f76299711d2e763af33ddb9eddfd537bb4b967e47d9260\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 92ce89e443024b7a80b61d1f58d638cec095d7d4664e8549e51aba582d219fc1dc5083cc1021b441560f58bc03\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 17103f6d8cb385452457040307ce7bc8f18705c9333ab51867f6cf62e51f76cf703b69b32e209c64e8777b05de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 6441c689667add0ed50eeedc0dd5c487aed506f2f360e768b7937f3d06b0b43c2c3f9d9c883d105e7c97d050e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 1848f52015c0b917d755528d3d0ff70574ebbec2271d4c5c672a93caf37dc87695848b79b9f3caaf8937585296\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = 71795a914c78062acef28a7e6326c106dae40f564c73fb63d9f52a0522954caf5f3d8b59406c1e4c4efb4e78c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 18b51007114b30a1ddf14efd7297ecc0a8ad9626408ed9c6bdd22676d9aa0c11aa3f0cdc525180d47b1fc2803e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 1cf6954862fe38be7871d362a3836ced64dcbf2ff114ccddcb6f248a24446505f73cef228f1217647d3e70d7d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = 41cbb2064d9db9f43e9fb550a057b07bf90925ff28df85dcc01e11e2160749e3a4003df7693baf73315d3052e0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 099e43c3d5305e2294566ac688e4a4c716f3b81373e941b6d28320c4f48acf9c8bf4f3bc32e59ee4931fadae79\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = 4f27075c65c4768779f33847f720f635de15d5074d3593391936e4f0db79abf016e548781313176bb83afd544e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = b49d1947610dc84a71bec3407420f4351d74a6f97dc59cdbaa4063de82998480ac8d8576100f8fc1dec8fd0415\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = 0452a34aad9eb57de1748b18570ee94d88d2b123cbde141525e53fad8da5e95fadc36d533d9ff158eaadddaedf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 4034b6231f8e1809c54bf4d394cc05104fd223357e95a60597c7df32d2d1b69e0b78adebc088b4364970c9088b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = f2cb80c67d9226f131dbd64963e27ca64e428e8f64c2c193c3798e2af548a4bf5d0b64d0e9a5105bea4340e40f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = e4be8d8aeb13fad3db0e7d266e89ee5ab7e3c861bdff61776d6356e786787e14e6d1328bcea2001cc48a013425\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = c1084bd11719f15b3194ae5f84d278efe6a962c0b5f16123cbde523ff7ed2eb88d91293c22e3ad9683f5dfaf69\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 91e9c1582a12184b4fbf796a81ae583f865a2170bb09f2ca46121824f19dfc7944044d533c046ad093f7eb820e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = 8e4fecf7a15fc3b258900b55adad4aeb1386c6486193e4d3fda60fcb255635266791eca1cd76fc20b411955210\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 671e011d0e3c57f73508f885c64dab5124a4283a9430168033f11ec0f1aaeafb7da3224a62264d2013baf4cf72\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 8d27e076edbcba9f6a9e58b62914463dfa5bfba6f419807d6664659230a947e069756098429285b590acc89927\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = 7ed3247399afa43f2e3db2697f9e37e94f71d4d210e2ba4f3896eb62bed1308df32e5a63a16c7915538ce7463a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = 535bc957326207f14417a5c79dfa28103f488169039d81986319c0d54ec72ee23b8154b26bfa9e1e6941bab038\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = b7a029e3486549bdb19fb063eae5ac28c646929b1f195f6f1bbdf9f99a65214e923", + "d9bb03cf19f17765c62befe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = 11c717389193120fa6b61d9fdbfc74ec17309d744c1fd6e0d49393a5c32665c0b70a0a64916ae4a02d020762d2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 45a5fc34bb9062b93a34063f009778d4bcc3af74a69152087db014bd88eed080c06cadcf1efd41b31a9bd9a65f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 2ed43cae3a8299d0ee9caf4297b330ff643066d71af8465cc19a834bbb953343a7e165f646eee638ab0485b903\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = b42058802b285612ffc4c9660931a282125eaf820c116659672ea4cf4e901f9aa9c496ed515d6fed6cd72930bb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = a5cda906160fc86a45c80cb2b51c07a0a1308626426bda2cb6b2e15aa5d650b6f59a97b503ef046c88f643e0cf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 3c0656ff6ad0c678d1ab7f1c49118191a475882c66b9a771a9570e1b19a7bafe0e2e2b55f0d17a4d054d175516\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 75c7b335e15e94bda0851db69e35f108fc233a545da4b928ad14461e269694d8820956fafb4e44720ce8381507\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = d3d4208c7bca3519228b580237ddf552c0f479fd621b5751d797cd1d973f62702e1ddc2d743ddea6a14810981a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = bd8072b89e773e49b1ea161dc308c1f47e0ba2900eeb8969feae8c69ede105660b348d2a6ab5251e192812a704\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = 802ba6104adc7ec67dc96bad11d1540c37c7d09a1d8e588e9d037a559aeb8bcccf00199e002dd1b51e38346d01\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 170693138046e54de3f940047bc9c083905bd0d5f66ce4a21b447e8671662ebc13ee7cad4d0710fc453fd18c44\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = fe66bc839bcc84b49b7b2f74bc79f6b6d66d081b431a9f875738ec99278da15f562636f26a3305c06ff0ac1dd7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 68387b231332367d7c8b6d57bd2053c79158bd8b364001f0ad10c2687266df9c2339179d7278db2c9b6a0a378c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = 5c15441304b8c28780c052b3354b85f05985dc83ffb718e4b680bd0fb1c052aa5741370ae14ced0dfb94d80fe8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = a5b93d9b53f0134eb135abac39506ebde71368021255ad77964ba92095b370ca6bc1887266746f2f24a1ac68cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = bc646bd2d4af6cb3eeefec80d906ef332716d228ebc473fd543c51fd4c626ebd9a9ca3c5379fc935748b302fe3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = baa95961ad3798f5ea49f68c7bd46a47f1e1b1f4c4410aaa23ffd29b539257dc6a519bfbdc12f48c2dd44f41b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = 63350bfe96ec394c5df26cfec536c1e13c36f11366dada5c7fbc87c7a77824d3aef9f68420edcc90dba8840e8f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = 2aa46f85e84cd57b484eaafb542af4fc5be63a3cf0517924311c5014754cd28ed4aa3a7c6ace995369a121d919\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = 7125de9a7ab93363e12742330ab38a0afc493cacd21fac7dfd8d6650b58088e5441b4612957290bd81bd9b51a5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 99e607edbe8020e3d501f2d861864c65c0f3c7017f73a5ffe4a13f55bf5576848f3c74982cc59b599b10f5d16a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 327928bae37c3ec8e3013157520df8a40fc82e554b8ab673f0785aa30ad582b3d5c16214668a9c02b8a3305996\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = 970a798ffbc3d26f2d8d937ddfe93944b9b0a8ef5b5090cc2050c9e1cfa24ae8c9e383b5443b6b06498bfb4576\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = f9888faf2641b1cf17a32a2f1be9ebed7461bf164bef4d66f925d97aaa29890011dc5d32b1662a46e56422ad4b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = c4b3edf0d1f37509c2571d4b5862f59b2ebe75c53553fec09fd4331db9e968beb517f1c48a2e1025a13d0849de\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 128a7f7e9f4840e993df22c6a27fe71ce85ea48e30e09cba1d61ed2a4ace07cbc6d498e10909b581a548facb53\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 640183b2b366539114dd437cc52c7e11ace537522dc32513d28a72306a0859bfbb57e88f0ed282c328b2811575\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = 737920941a5416463d091bb39cc88fb9a8777946b3d491d74f873149c121a680f61bac1644fbbbf4e4e084615d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = ee533361a9075cbd1ae3448b865d16d540869e232beb3e7b7fcf0982baea5d4a7634b9ea2bf3a768da75d7bf62\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = 94be547dd7acb0e06fcf9699e4e0417b08da4248b09d2344ec5a3f3740cb6df8a2e73cb7d1f586e2bf81fbe01a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = 595ad5462e873d7289b871482889242cc322d57e840a826164fea4b240c18a951464d27444a5672cf0339cdecd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 88fddd9846559b1e0165e961bf90d9320b8846406353174667f03d667e90da202b5dce27a32cfd2c4288e80cdf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = d0b40335e694ecf36a1c628c215f8d1e59fdea2ec54d1997a7784c519440c58bf1cb2cef6f1787b84f75182726\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 3e7e536627f6b2bff437b7c3147e19b40a779ef2f9d46d0be7aa086dc462301398e912b268cfe8ac174535ddeb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 61919626cf4fdcb05b3994b2b4f1cff36cde151621afbccbacf5cd30371328023548debe410f5fd510de7b3f8d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 5cda7630909f65f1639d17ee1bf9af32a154e07a09d5ec0cd6d980b2246420ac3a713f64b747325ff98ffbccff\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = 93a81809a5c145a51792f16fff011cda42b7955c15f8005eaac4b5a2c69edd7c6a30e4007a9d7a28eb4c916f91\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = a3be48ca8ad70c6dd6b2763088cdd9ec7fce54535369fa711895e938ef40b634d765976e74997bd6ce3334d691\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 3f060c4ebcf65552febaa5301832a124ac261aab14cb4987abe467712948466ef42a819442e857a7ed2d406a04\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = ec45590afff57643dc270647f6932475fdedd8c94c13c7834c44d0f80b48f409fc311063140819518fee6274a3\npt = 426", + "5617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 157c4157c5f1afaa789e304c096b751c3ac0174264696238dc614c0872ce6259261613938c14757173966fa5f4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = df36b86290c7ba0b99f6b9ac4489d570af4941296ffb352cf0a2caec11e9edadcb61391e381763a3f89055f1b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = 4ab902188cd8040ba6c4d325cbde2161e672e996f2431af34a94bc89be127ea99278e896082847c11029c94cd1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = ecdbd21be32fae547cfa7fb4d665f3038b5ef47383b349700f53fa37808f9f971c4e6f2c686dbead494695037e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = e4721d14e172cd2db536535a8452a247a60642a7645f56b30b2c920433f082a111e798d644e764eae231b9e36d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = beb673981c54566d15239a625e70beb02dbe9ad49782a9589c6dda7db3409ec9b0fd5485b2b9ca89f51ad2ba92\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = e2b02be0b2a8b327c7a83d4c276e7fd9f8ebdee2e951113bf0622f2d1b52566d0b5fcd582b8f11f2891206e439\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 33ae0f52a3cef337a7286ae47e4f2939c18435135f3f93794507db9fb4d779a4af607683a3f837d6f175570ea4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = 7bbfc9c9e8a4b2781f1dfcc48c3a6d9e66ec91e39348a458736681d7cee6fef84102da9bab48aa3fbd295b129f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 951bc3e3f3a302eff4cfb7989a6508ffd2bd69223d9b962a4c68cf04d209e37b056f92c4ff96e41b60e411fdda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 031ffc754d54a488cb7bf4577e840b9257d81ea3605e2b1fed1c4d83ddc76ad7ec76d3cc2587636287bdd15423\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = 7a88f024350986aed407259173cc4f1672ac1b0e4d29584c3bf4c717ca48e9d835ba99cafcc0ba9428368df5cc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = ca06ec3e337014731f122f8db788f765083be95cb6abe2e9827d521f63a71932a304fc8f452611c02bdc8ae83f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 44571995fbbcc50754e9858f45f81f9fda89f862de946f55f6def93c0703486a59675a28df6616057aa2962bb2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = 2eb20f3269a93720f615d25f908c9678dd1249646211eab665b4e15ab84661fd737f32d4c319d2bca171bc33c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 9db897191dba0aeace4709846d28d905933e576d8d19f64cb26cff759608eaa308752db430c41e6c1c13b51878\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = 132911b40ea785d6becddf35b68c8edb4ce3bf81eb982bbe6e93bbd500c7804a62d66ed3e17ba1677e5f19693c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = c0c3cb5727eae2624429233d3864007cffed7e839777a25d15dc3d46ac06dbd89004059e01a346feb05c1c81c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = f5d86b3e4a39ab7317273283244422d0a764f897b6b91ae8faebe925fd1ba2a15bd980e066dbebef574c894a92\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = 681295d554e5f657c02531e84309c96abdce3ff58fabc8f969234e5f5e4c6726c51be58218063cf086abcf5983\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = c61b1a3724c8d67195ce45c0bd59886fd9b12c43f76379fb9c99d528bb8165ad41017f1dac1e26937e84c8adb9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 5aab74d6eea92c635d2c751530d2f0361a8684a515a475277bfaaf5fbef1a2171a33c34a90302807c701d56790\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = 7b998eed5008fa6295b94dac34ce9ec60faa1c4608d013cfa014aa3a96ea6687a106dde3657825e63440dac506\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = 956ad989000458007af0b41eb2fb5a716db1b095594821fc305ee35ea27b41b2476880db3b4c86bc60c4394d05\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = 21de030f4aa7fcb8650847deea5ab6a2934f2e0c1c5d592320a3933bd6054d6ab8498aaa4afd84592577f5982c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 09ebbc42714876507032d57cd75862b36e37c258a60381c2eacd54df57b63866bb6638ba70b819c5154a8449aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = e00f7b42761478774b545ad968ba8065df957f3ebc9f08bd7c87883635ca3150d68a0762e366346610627d89af\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = d943ccb5bec78bb5c5456ce7e0c2bbc2710451f67f9398f81b1365dda8ceeada480e270c6bd39cd40fead78ec0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 97e618976ba5b39d98d79dbb6e94f853cf2f231d32e6240929e4674d91789d7a3dd7199051d49acb92ff1e3064\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 3a089d31db7927069a7956793308cf8f59e3570fbf8f561888699aaf5ba4681a427d68748705754d6a7344ca24\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = a4e7bfa5b0a0b537c1832206561f764c88d722429340101906b380aff934fbb98f5bdfca0e77024805338e4e61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 2396cc5b30ab05634f7fc6f6067eadd043e6263f1e68c6ba556fa99dd075a7f1b42b5cf195a469ef2443896fa8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 8e419af52a43da88133fd3bccec458a44c82cc24dffc7475f62fcd69d9118c85505c0080811504b6b28d94c7d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = fa41df9a9badbb1eaad232e4bf7c431b17418b429cf8345e45b1b9aed9e8669ea2e19893f22dcf4dcdfd370f39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 03ddaf89dd237786f561dc04711aeb5976a61f5a32f789f92867b39024ba0f5f09bca97ce2456b4d4c8ea1e692\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = 185eab1d7ae0d33b774abf1d730abe7cdbc7e238ed7c986de2f41e650f0915f33e816fa9b0e08143cc76c76e6c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 559b45bb28a558ebbaf55adf12130d45e18adf68249514e564437bf61d4c49fe9f252c006914429d96ee719173\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 6457329e5fb4296beb868c175f84f16ae889a3edeb37edc19b38bad597064287aca727b420b5ed8b1a0b677786\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 38f7ba2c57febe4b4d832c29299060d93f8fed98b6cbc95d0d6e95dd385d1fee063783ea774a770111ff9aa31f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = c45408567b0ad94fed4067cd1d250db315561c9322db62e2d4604bd36aeaf1fcea7db541ab88197266e5d9d7f2\npt = 4265617574792069732074727574682c207", + "47275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 15211da2711b3ffd8f4fd59500a7fa1e5e4bc96e1ecb874671e455ae30cd8d993ae61f7f2c741337dae98d3514\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = ce742653b0a38f7c93e901f97379f074f875eec71299361ebf5cada487b9992d1e7cbb975ba8d5d44aab2d5854\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 83165d93c0178f0b4f73a46952457183421a3284b17d9d5a056c897b7021ce1cfe5295a44a6daec6da9a02e1e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = 816bcd488508d071fecb91b9a0c792b93461a1b6eea76728fc29cc1791f47b9043adde84e0af3e99acf72f7c95\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = de13015f54f2d415dab8f63a47d8bd5799b169f1982b67b79890fccc187be7a1ebe08670e4ba6e61e98e4a353a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = 6f533ed89dbc3d56641e7c6baaea85455a24d7c81bba4c2c415e146d78c15b05acc144c64a392fdabd6088d731\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 43220fbb436a9269a2b8dba1734e8a9f77f443f32fd89dc78b6205a10817c38e8d26859b2c3aa62d4012dfd8c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 1a9acc8588317d8be40f50afdd9ff12464dced0401e6f8043e387a1b4d82c75e63cb0752a06d3d6aab8eb41cc6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 1b6652abf366cb5106ee5e6676510d44de609794badb2672f9d5537fe32134955d8159da22d98c58780980de3e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = f4048c4d1b9210430abe699016e1d696b9f67102a68d216d84bb99eb03f6d57d7968075942d4f6e56d462d25a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = f3e1101622e9c97c64fc58e58d71bd92acedbea1a5dbd90d09fca60470aa2c708ece6e8e845444860b37a9b420\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = f6ad1823eb0b932d04b6e23010eea64f1fe5edd0583dae5ba27ca6363f4ea104bd217331460ef4208040423641\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 53624f4f9f173453b14e633b45390ff54cacaa4428d44baee1bff8133fab1ab3afe60f88e4634b525c54e92eda\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = ded6cffafaea6b812cbf3e241e88332adbc077aca81512914213810ee291770a\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 04d3cb6cc116b28ffd22ad5bc276c60d31fec71ceb87ae24db811c64b7507339\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 7c5ded445732c14fe09727d29b4251c0fd38455fe8440571e687f0886aac94d2\n\nmode = 2\nkdf_id = 1\naead_id = 2\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 47f1eee3670dfaaf27c30a83d06ee9f257af174727c17b35328ef730dfc1cd81\nskEm = 805b278cabd22c9dbd461bf25771703eda4950ed3ef35b369163097899555356\npkRm = 3668d659cec6f338f4f8dc6da6733118d2a633f186a3c1415c895111a8eb7c7d\npkEm = 9e59f4b1fa5c876f684765290c34e51145894cc4f244342b9fb1a4bdfd8bb426\npkSm = 4a91c3d0893433f5e31a79fc520f885527a1bc60bf2b0c72693dd7f0b2e41a5a\nskSm = 98fdf9b9773578a79d4ba82fbe483c74cc2e3b8d9525d148a18969fd79a74876\n# encryptions[0]\naad = 436f756e742d30\nct = 10b964283ac2cc0bdc4c85ab617291b446bf3832e9359b2c3a0facc50ea75a3c1afd08aeaacd6041d02eb560ec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 83b24287a5ac672289ccebf5ec303d3c0a85bc60bb7a748014d85179b51c7552ca93a70817ee3140442f92e23b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = f42d890891825c1a57dea5a66baf2c940126704682826bc7c5caee60ca71578d767db256b0c2a4051bef1236f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = fab3f66ea4273bcc0e40858c346f4e12067b685dc8ad6d57f3d398bb3035c4144b578991c99df545c214a53373\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 470a09a528036f80a2f1e23bced44551e5da71dff490bd7de6e01e2eb412cfe69be650b201f10e55a9c289e712\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 96838a987715414de7048ce44f8bd0cf7634638d4d4ea25748baf44c65bed08692a8442f060bd87def25098d2a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 2c088d57556144930fe7f52d49d8a451cea3aa6e307d794a034fd5fc91e69f56c8c31464dcfa26ff1b5782c80f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = ef8b777272642c61eedb8bf809e92e2ea35f92a53f09b131e7f7a6004cbf0b7e6c528d27567638cb54f86fd89b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = 953a2067e752c7355f30364979ae55efc9f36346e6fc2c51c5fca956a6367080b045381612cd85aea2b41f8291\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = be96bd02bc6cfada4561a2655b4214d541bd812b0ecb45b4446d93785287a68dda16dcda9790603327996004e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = 4b553762b63d15769e5b0594f87971776044b2e0ed4b58aa6379769a56334f87361dd5ac710b0a4afdb61e42b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 1b92f016ae4ba14d4662d6f65f2cf3d1df4b99bf98b1c8b7a7f9c7d722085e5a2cd7f242c4680dd896c08fb9fe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 93cef4666cbb4c191fe7791b0dd46cfd09c7a9bccd3dd120e31e1592379c5112268661c738c27fd583d1a69aed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = ec195f886d5ee74f79eae5cbd1b46e143a92a598b1c0b585c709d704d97ff256cfba127afb2a9f1a23f26ad6ed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = b7a4f0af656ad0afeb7c3718971940a31f4822125943171520981b17473a5ee7b7f1192478534db62ebb79e546\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = fc8b1d895f7d85c4a07e756ceecf6add2141056a80e86eabbe62feff6cf69db47d6c3e9735d8c5befa973196b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 328ed2e5b69f06a3ee88aac0851952c7723f9bb28370db85a300b01b5a2d41c7355bc2286784cd0fcebc433ff6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = 19cd1196f10eb2df0b1fdad07c36ae1ef483d66c0a474cf82447d2a8906093880b1d8360c507ce0ea06fa16532\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = e281b6d64b0f97ceee63df5923192a42eed46a87551d476b5e6a01e0a6ddae36415394c3bcb2c2c51b9ccbe80e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = d764613d9a6359243a9f37dc8d1b2fb384c9d036beba29aaa99e966f5624300da396952413ef482a5034c66300\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = f0d056ca8484082c5e08980dcce8e5bac8503d914bb6662c196dee3778f0ba795d108361e3b82c01883d6b4880\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = 47d384a5108791541732373492c339e4001760802862ee2307ed01d8692f81efa8750d940a0f8ecc1d509053f5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = c0bbebe48e5980326bafb7840ca6d408a4ab796acf26634991b21c34170c40817199cc71345c2e467acf5cab30\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naa", + "d = 436f756e742d3233\nct = 0ea456e2deb27ade97571f5c51835dda401585260eec29f29896bb7a6947667cddec9d52fbdd0155d33c0cb318\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = b525498a5ffde5bdd0c0c50b0c1d8c8e64ed47124d3ba52b0c5fcdb11b773f568906e5643b390f73abf178860e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = 019b344de40001e1d18fae03002be1be4d2e020c32a514ff4d84b15d066cbcdf045490ebfe9e4fe536cc001b6b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 6542b6f3e9abae49d31af2a8871f5260648cb9d3c5ade0d7d3c43ece10186f6b1ab465d71c5503a703aee2d889\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 8079a278f77b5dc928f17125af7f62f0ce040ca8d90afef0de758da1694b056be1efde71258636c8a39a300428\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 2f4cbdbfc8e9e1498dfe1f20addcd16e00fba26f06fe8bf510ce726f4e6e38141a027eb9b930512300ba50d772\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = ef6390e3d57f95aeb00e6a8cdb3b545bbffee6755c8215d3b431a7327da4981bc3dc35b5b913b18de0abdbe721\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = 0aa56230de06dee53bd6e405bac54899367a1f6d4dc4791f99a86f6eeced0b50acfc68eb49393482325dceb15d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = bc0812f89e395491f19b70d43b4ce1be7d0d274352817134ef9baf7d9c5d7b93a272a79350b8bc541997097023\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 86980d73a1f515952156be21c6b42ecfdb40ba67ddc9c8af12dc4afab2e659622f341e84adf06ec71f2c4fb19a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 97205bd532ca8dca11de6245d21fdfac06d6b48fdcbd399cdfc3cd18415a78bbc62bb9aae0ec326fdba7c1c846\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 625be4d9e0e0caa56cf6e7c24ceb7cb336ce4265b0177b93783d6225bf347b84b3c872de9992666d8d7255b3b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = e1957331f9fcab02fa9697924b1a22b7ca36ac728a4bd2c4db20b839987aebc6db741669ed96f63bc52d949f64\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = 5d83fd726dd22802afb242f25923de6d55e1a481c1d5041c2dd05986b5be5f72d611efbaf8071fe2bc0d416438\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = ec453efb75c777cb1fe3322f3504da40c2fbb613bb4735a02b33280c1383748377bd33c35eae2f48930a6aeaa7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 3a050cf76b072e1897fb498d090dc4591dd06200f8c74e8f7a6b43e455680b32fc831fd7891450c626a847aa4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = cd6a04939353bf21e3c68fb190cc2e450bee3403938db4fe9eb1d826cc15ee1f0b7b32af11a32310c2e4b49e30\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = 2242c9f6d2b04a400892c3d7d7f4086f7851489e4bc86ac090ea5723585dbf61bace21248c2643e062329c32c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 6bcdf8d421bd9623a6872b1aea124a4b978312e29d24a3b0f019c1434e55d2de4775b256aa91096533fe51d292\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 4e02b9b212688ca51278baed8e57f3c948d70d096afb6842920b8fe504992b7920ebbd4e3e655ae6cc598244e0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = c2acfa09b1f580da4d924247b5c98c3122c09a37b72b5aac9826e579bdf194d7a3d179e15a7085c9fa8c53de19\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = c7f6c9d6360f14a124bbee3624e2f03e34b73248576f2c83127eeba3fd9da799a456f27bfffd9211c5a40a414a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = fb885e9fb8012b9d801ac0c1cab978b753ec391ececcae9582b360f0c28e6b58f7e432d3f0e020dfe0831231c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = b10033bc7cf55378cf7d919a0773bcc79b6878117071674df4028cf59ff3554963dc3f6a5edda250170fc55d85\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 3e62ec8300d4c6d0195a7403ba2d8c70c347a920a9f1051a9825fb5620bfad8aa139940b5f3a91e5409a00849e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = a7d0016602e0501f39ebb6f4173005a5732fad028dee2a3dc3e087ac7b43afbe0f486c6267a883f223081dd89f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = 93c01585a1d1775f3fd3b1925c26bb6e810842a24bb69a9c2521db72f6d66a2e005bb875a480cccf2eca122d8f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = ed18775671121dc68a6413f544a45a3a197faf39c43cc244b32c606ebb61cd1333f830414624530e43c5328216\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 4cdc7b5fbb3c8f392e84b238ab3cdc7b490cfe1476259d0db4eefe53f718f1f6a7a32bbbeef1574ddc41358b83\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = b47aee63fdb669daf990181bb75bc094bb9919b2df809615b3aed0ddfdef0235f79cbb95082bcb44f76513876e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = 55b76bcd5f44cab153ffb90b809f5cb504bd02f705b6649dcff9917bbc9df878e2265d96591d6d0bd856afd1d1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 67eab42d7d1bd9a03221c283669ec7ade98f5b3a970f7903b9dc160501f643eb614625f35fa89c834d582282fe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = 95d31adf6ca4f047c5097816a6e6cd02e2c952f3d63710cc05df53da29bb37abb8caa037bfa2c50b59948ab656\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = a48d3ef0c3f065e7cc4b6ddebedcda1b27a8dc0664f4049521a3c446834a9cfdb76dd83a506c1f6f25178287cf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 57d1902ba96fa509d930d5ed2c7cbd57fa43232b14c7c6fa3f33168fd543f4d96777902707cb02a1282f83856e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = bee02243ee8196cdd8470528e5f2a0a366a0c48fe71827c07783192a762506d283c6903419e84404738f27a31b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = da1e009146d60483a43a1518c2bd545f21392f98f5d2761b6b54d455d6903ed8f8a7e5794946b1d2c8b46ebdeb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = 99bd8213cf3e48db8b0cae6cca6088b3c3f25d8d8a4e1d38b1cecfaa777ca0975b579f2858ad29f5d292b59295\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = c49043927a47694c3e0c6095fc3fd7ef19b947b1c15d455504a72286238be0aca23bbb8c78e9c5c066d7d2d965\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = d056c8521b101402202aebbd5ebdff1085a1e0f32e177f44787c2f25b47c3ad598ed05a2441002637cb15b7257\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 3790260dba51810aa30b24f7e841c0c485b40f234ae1e0cc66bf895c6fc00e5515b3b4b383844eab29c706c336\npt = 426561757479206973207472757468", + "2c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = 6fa82757e4a3cd33d8480a35c303250ca6bfbc7584296ce67af456be72b58a9ff310c7ec6a50f86b20a92994f0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = 44dfa1d42f6f7e2acab917cff4536463a3e73c4f5dc0c2ddb189e28dd7c3e6b84540b98dc0c51e1f5d00f9805c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 26a22d894060884040677def8afd4502c79873f13c1b4c5e0b093ce0e21e6c07c07106bdab1b1e57e365433a34\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = db85091e34637ca4b5d709285d61e13cbd5db120cadef028caf4d7975dd8f2eabf8cc33d0ad6bdd9f4b3d270b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 294b49e84bfaa136422bde1ec4d15a75cb8a8c0c7b9063d08d798e641c6aa7fde89ebcfbdcf7bce1823a9ff3cf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 93ded3b6c98642921cdd0663bc2f3bd844b6aab133cadce857a06a9b125a34ab62fd21699f834c6c961c567ad3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = 41c05ee1b1d21d9779f39d8331945636f0e6214e0293da5c13457cc6e2ac700fe39086ab35fb700225671cf680\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = a26d2e109a3dcf33fb46f2283d3427b92275afaa1e8f0f8cc0129e6900e9c3278f614525851e1939a97b1acb02\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 4160b4d94a4c4f08cebf3360d64188de51b2a062463d6af30d8e60844f915528acbf675f86b6517c7b605979d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = e2396d75603d928144c116457245275f48e681f627fda6a888fb02b00bc61648e010d4b82a993c9d882fc9c209\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = cf469851b3a16878978082d773079252e7646e3d1c15ce10e11533ea5b89389baf5677679b792337b107d4cf8d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = e5913c4c0403b0cf15e20443cd18a91365022f141e8e480e271d335c4fab1fc5c9e4af70107daa43f2869e1978\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 7a6a29c5e897b0df0f986bad7d073e3680f6447b820d36cdcc24c7a6d5881bfb8d42a812ee74dc3a945c3aa23b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = e88641d6c70b5eaa39e00ab2a7d55188066e9520cf517aab36724dcf00de2e9614b10f389aa79044c21574236d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 0f97f67f90f69d087390b081c7d026f4f37df0086c3dce2e9a02a930a39e68c894ddf92bbd7111e0451fe6cf7f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 06b7381cb3efda92c617ba646a92e2e7afb22671c71f913eebfd6d3f9595beaeb90011d7e18ca545d3fc2a29d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 4d6f4638c2f8b3b8282c87b7d5881ee4572d0a8878842119d21b89d519fb4c7d063e0d553b4eb0da11df6d33b0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 294110587b38ce5ae4b34f037a8ddef605754c6951b5f6c0f1288e17f6d0045acbd4a0f41e98b2178d9acf4b6a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 5918e4d0b1dd3ebb1812b715a46a9674bee2207a1bbe77f810a3a481b0ed0b84f60e5adc2228915b4fc4da58cc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = ea7c2a8fe7d6cc0237fef4002226d2b0b1dd9e9c37e0a7d083c57ea7f3118368f8337b972f7642d52152e16a37\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = e6ab7aecfd81e4808eaf4d160f726275c006761f4ead2e9c9637b81cdd8759a35469342b9066f65ecb8f6336a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = 72d49670b3dff4551c1c6ea2a5cb7d74e9655a2bdb94048ac9173b5a5918d551a818bae8c78070aa580fadb7ab\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = d8615ddb96a5ee3a29e17f00fc1bfd64199bb4587f54a41b60b516a9ac590dc4ff2ce7ccef1baf56ba08d25a32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = bdb6cb3fd276d11f8b3839f1daa23c25407b85e50d990becbc7548406664060b3e5ea7b8744cd6d01f7d6246dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = f11c35cd0da9d7986d34525226edbe665c332af3f265ec9ac3252349d13e2079d90e733e67d3a05153876f8b1e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = 21207c730b60ed9139203c845156fa9ed93166eaeaf33d91501f2a183e98d6f9941eb270df1d0fa455f028a9c2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = febca60a4ef7ee6a73993ba1ed1d39427d96597d04e1ae338ff3418fc4323227143a6f5ab874cefd098bdb3b8c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 08ec4f99873f2548a2bc8ae0de56543e927944c305a31543fd56d5f1bee086acf96387d918e7af898598fe427c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = 99b47953bab7e516974cf195a7f14d09ed9ea6f74fe612e6cdf58a9ef0710b2ea7582fdfd98c90a343c6110d85\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = b70561bf36b2acad3eb13d7c551af56e0e2fd6d81ba181489c857f66c88817fdb8b76b8d7d594585427b032c7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = 2180d3d0a7d925c0af160101f6b334f0f94bbb32142fc1e6efca3e82e9099e382caffdd909b0fa7f4e5407a0d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 03d6a815ea1f2f88f0028ee0670e07bf4a0db028a5dfcacb9c281daffcd9226565fa56f92da3ce5eb36e095d8f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = d5e0da3bde65864905f8f8c8f9b6082f22a18f035fb9c04a2973f71bda24eade1772c27faa8c3e2552f817996c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = f13df7ecf2282a7aff702530d169134c0bad279a94e4de7a0604c4b57a2e394189bbf6c0237e6872e0614599ed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = f9c348a57f3249fdce7612d3329293519f6a675d2a030ef812ebe8c7fe1c69408608152e5f489eb41671c36891\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 18335b721b8f80ea3c5b0eb16d6fd9eed45f96f7b11140d3692f2dba9ade5cc48a16b4b316ddc704b70e299138\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = 3801b54b9a1d15b10a84eb78a8a84e2f70b4e57e0f6b7638a3d75a40720c101fdd92cfbca87ad22ff7dd20d317\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = 7d1b5a06d94e07e677cb647b44f378114ddcb55798dcb8c98fc263f61f4b34d4bcd375cab0c1ef2224c9540961\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = 08891c005d9ebc0f9f8d07ab3dd15a88c3d9c60402b9516e3c6727bd0b26ad70f78e8d1a1bf269077a35fc745a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = ddabdfb862b8e4d6f03e2858e2a05976286fedcec6447355c2ea0f0540f0d3abe3d9dc17f7aec0f4684ac8a11d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 533056df19cd99b22c522903837e9b04b38f072e869fcf98e63ab4e138116f", + "b1a327090612b2cd01ce60a92c04\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = 84a75eae557806a60d8dec4e0a030b31e2150299ebaafba2118e1d9f8a4332dd383c3cd1bf01bff70f235e7ca3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = 5288205e740e6eb70b52dcf29f44ade64979a07023888f5a098d6b386b926e5b2b3dbf1aac04a6f80920d27f2e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = 24f72645798f856137576f8044502e55f03c53cb3fbdbe9b13a3caeac07631ecdf5b30c11757f6d66697244aaf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = 178de8bef65b6abca9a55a1819a9573a248e0612832f255f4d307df38a8f29554fd664639a6a6277b5e33201b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = 34613e05962717b7a5c60c9c3a2cc0c2039e584948c9a028da05bf31317efbfdb0fd86252e6061712e3b03a53d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = bce0ba4438567b1570821759d9f6d84a6c600701b8632e9fc82a5e68f3568f05a00080bbc4c69d1043fe09a2e2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = c848e35cec53b724b632a27d3b90abcf1044b93ab5db0a5e63c93f15b8e3e599f737826db5258ff8078d4cc379\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = 2026cfc3ee0f725ebf11c9474bdda1560dd4046eda764d9656cb46c949cf0cdec3fa8a21cd0ed4eff3a7b64ee8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = aaa53f387b1651d71fbe2b11f541f6f8b6d70a92ed1668a797d89be0862e2867a35b43f746482271bc8337eb79\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 426bd3f51bb64eaadcc1444282dc0d25edb2b4e777c2437910d355cf3e6cd09ca989a76a34ea8c415e9b9af767\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 1e8c313e38d847030c366926fc26029045fa4cf5523d86e883e386d348b9d2cb3ea727a0ebc586191f45017320\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = e44024793dd020b4a059346e2e4d325a301c643fccae7994b620972ad3c5d249cc08bc4c30d3434a62a93825a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = b608878acfd7c879b587555c43f5713f5b8c0f6abe2f1c781e72cbadb32dbec4697f23d8af80eabf32ab969417\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 0563bb0cfbb03d236e68090252082c866c2d05dc48c530fa5920b32eccf2d4913a190c12aa8d55f6a834458684\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = c0191c7b91f01ab891336ce5d77d97261632ffff8fcaaf25a0da0f563604a5cdcfda6d7d0d6a492d4bc8f8eb64\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = 2e71a5a07fa44ac159d7eb2e483d46d59d4552895973fd7fe32f4919310b814c45699dcace887744d4bac9eb36\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 6c769767ccc92a2e3c6ef2f94df67d72b9c02b6d1993281d2ffdea0b40b5af09f25b3898f05ccdcebe4bd6f31c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 5dcc6147c104f9f5586d88a7cd715830d70d88820a6b2157a574b96b7e9c37f834aa6adb957cd8e0aace79bf47\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = 5839720b5f44874828ba95443c2685d53d079f83d3246895906decd87ee41a3cd7969e66c7fd5e88330b6f354f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = b01ece5e6481555fa1db96bdead1d578508b9d601a6aab00a1d433e2f94ad75b843809b4d85aaa4f0ba88f0d11\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = bfef11050cca99cbcefd59be7f27a793de11dd74793ed2bbfeb600fb1ffb0e2d1e559a68e14ca6369dd48036ae\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = bedb06bef935d7035b316b485408a8c4bb745af2ca5214bfd87560f33fb2841618b431988373018adb03e58cc0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 72d0e6266e19f5bbec3f4a5ced9dcfcce96c3d98ec677cb1e91953f0d3774a9c17d766ea497a25397bab478964\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = cab945a20e896773bc7408ac7e90e39e7530b2f6408c09693c241835a76d7a9f0894f9f7275a8c9ab78df0bea8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = a8c02c46ac55f9b655b547d29bd5b00be116094f1208edbc83b8b27aa1edfa4e3b7d7eed3199cd64ee4f451c1c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 878713ff6c3375f2ac8a2b38c7c0d8b49a7ec57811118b9990b0952c08f097d7f1f41bd86974e0b419246379a5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = 36bc1b88559208bc331263d2ed1a16ffd8ddf3770290531f8a6198701d9b668d2819744befffa6d2d0ac01b1af\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 94e5ac2d046cf385ab849a7327278e6d3c51cad5b5d38adc071a113ff3273b1ad5fb5289a01e4da180c77e8ab2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = 7db0c79103f304fb6cbe56ffd5876aae98322e285fb705fe724f31e283bef9ed1ae4946c7e7dd8de2ea6073cfd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = 516d927bc91d3e6c822fd7612af2b129a5ded8bf590faedeb8495b7493d12e8ccf52f34d630280800a126ba478\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = eed3aeedab617f72af68573c059ef7e786c233a2420b58426f01689e65a5c89d48ad08713102536c7beaa37d16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = 8fe4c52fadc9175a6468a45fc8b96be427e570531dd5ee573d70e5dd0b9b1a67cb3873ce2a7148a066b26c8c3a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = d506cd6d849069d44977b1fcd4233ea51f812ae84bfc912b7ad80fbc4b7eb330755ee73c037e04ea4d54cc06ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = cbe30ec8e0fa8aa643cd53fd08c036f27ff2b56d46f2fb071bc9730c3bba256dd0317f14cd658b7d347e0eeccc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = f3029bda331c4e1c90960d60c2536bd0dc758e23d59ad17da680318fa9253f952e4fb019642920307f9dd59e94\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 8d1b5e14384b86b38dfa1b837573247c3bb58ca07bd6d8a0261306e6a04fec85ce2e0999eb994efe91cef0d8a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = de39ba2be428a69e47b70eee0315663e5d169da6ef2218bfe7f0ac59957022e5eda5c0b3e804f65138bfb09b8b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = d26d5406228c57ea78ed35a5d5725411b86b82a7f155d845b2e024aa86e2eeac11d33be3c986fa065fdc92ad68\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 8a8dff67b3d101c00e48d1c6f77d2e6e123417064f5798e0efc7e994cd31a5e34c913e2262c609991e56000b4e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 90443aa2655619390b627e09daf3949f79e77b903cf2343b84ce5c109eb02238e442bbb9bd2a158c445c7e57fd\npt ", + "= 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = a3df261a314fb20a519cb4b116832fcfca255372e9582c51bca30df529df7f8bea576390abdc25a8c09c030dfc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 764b6ef88a4ef4e00495eae59c83eb4d4da8512ad24982c04c332cdc0c39944bd322d74c89b78977c649e344f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = c1149b45a6f6dacca8342741b452c3c0fe8ffe65f12ba4dcc731f38a0e29cfd551984ebf4d2850c05b05e4638e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = f5c2222655ded319eb73adcb75cfdab103855d43bc8e2098cadabcb6f02c75d5017fa95854d4dc16514cb85bc6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 67de8b5afc35709924eb1598c90d1f8db559e5d1f224e7549205cba6ba70dc4bb67b1f7f3f9a15d56692d3e88f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = e6add3f1f1dbad46769e62b770e0e79f795d43c64b76e46d578447bfc7c01e48a7bef0607791fa51b9f8f73db6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = d974c073ea225646215fef776186673b1c3b10c8fd130dd6c46216c90cdb05e5d899c55be32dafb2f52777be56\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = dbb16370248672972c240fbe7558669713aa40221a8138789a4b1fd95edfbe5dabc361b95e1adbcb804fe38188\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 0021cb3186fd692c8ab715950564165ee8f89a17ea7e308ce48c6337103a1a505ab2aac137e5a110b7c92260b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = fffc59f2ff1d3a761d8e5005c25e12044f10875aad3ebd5e9346534aae5e4896eaecdf05f7fdc8c60952a0056c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = 84d2ab92172e21b7251bf2825f3c083f474d891ca0b8cb7f5661ce37956446cbce80046c82bcec29eba26b4289\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = e80ba09d1d2d7de13067e460755f3609840f017e8a6e4561b7b4078817696936ad19ff6b5c5cdac2b25ce809c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 445d8be1d404aa0e508f7021b22e48dd6a349141c182e601520420ae4610791a8db67f4584ecbeafd3b4169e50\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = aee6debdac56b80f9b55435fdf649d174fcb801a93866fdd8f6bde22ff85a3baba12409fe7f41b1c9b248711f2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = fe39078d272abc9c7999630c5eebfd1e1628a4a694430c105f119d20e524e99face043b5da613d3b11ecc897d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = ae4193c43e06948b19d2c912613f772c6be49b16a4f7dca4991c06417530681b54821b94ad8ad6c0d388884ff5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = 114fccd21850ebd4069127be28198c5c2e9f270b598baa7be337975510299aa20c054f8498f51898eac61567ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = f11d3b4bc526d850043c454f9936f85bca7df5fc1957c55677d3dbc18a55de8a02efcfbd407cd8a4d0a30d366d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = e59152496079561fe9f114ac73ed3356720542d395921f7a4c5c50da7f6afa3f492848361cd3a1a13f4b7a2fbb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = c62cfe00dfced3a0d9f35f6f9bbbab100bf6d609f3d78230e1bdbc7a2b3f1c4713975b62133bec7cdb8cdd91fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = f7e0185224ec145225b3cf0451dfb014dd44137775617ee72d9da4f7b41ec248904c107d6c6db25f3f8e2aecf9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 93c68f805eca253c23dc452302ef9ae791b4ffab97853c01f5967b6891cf2c5bde002ccd85a365fe348a57d6ca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = eaeda86b4f90c1f66e5929454220ef8ae0cefec40a6c03911212810abe11d5d961f625fd973855c7d6d8bd6426\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 72ab591663e0fd2edbce4d5ee04997d259b834bfb7bc10d36fc14e04e2808ae38cf601af89ef33d28224301424\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 5da0811d6bb5b9d00402c1f803062e6e6db4da219d695ff502ed4e74f011cefc3c74bfe86f142a6d5ebcef873e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = fe429d92e1cdbc0c738fa1b057762a61b6d0b3bf3d6c4a480504f3d8c07363d3d9adb50c5c44fc9ad2f80afbb4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = 73d7980299de66489e24e2b042d8cb62bf02a50ea4f6edfb3a265fdb54028a2284c5090fbd5bf7401d8f7d8c55\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = 9b81f97ffded87a9697145b6d0b0210cc20afdd117311238a5354d1ac0a5d0b834becda5de16280c7ea3728e26\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = eb9a1e55a34f825c13d2b7b014cbb7db6249c4c511111af9ae9bf441a9b9b1a701f778f2bfdac6383a9fa79ad2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = a0603640d761fba6ace56a20de14ccbc45baf0997755175d7f3e3742edb274368ce0a776eda420c0eff6a4785a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = 0abb86f71c0d2e456c4322bf4a26cc5dd898952a98b6fc815b5ddcdfba4308e6ec2c6260d7540bd0bc2a399141\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 2d076ed5858dd9f5441b6cdc386bc30eed7471a8f819de6eb6173f0704365f8043fb6e8fc4a7d7f9549457a3fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = c51e01a9dc463c20728a6d15fd59525709a8c51d9f46f15cf093773aa7a968d40232c9ef26d20257762ee49f56\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = 6be4673041b4f9281b6f5f5b3a4a611062254f82d7d298e93ac3395b0f93ee4277f3d60d1116c5f559ee498c1b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 56fb203d31045da80ade5e18a2a2e16b361fe1ed4edf4ed654d75edbe82d0326ce9dc51f75454fb7651d5d25b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = 046305f4ac30a91936afe73f55363480558b476ffee4ba19a4a99a6edab9bdb712f8dd2abf16e37839382f1c07\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = cb90b1ea72f58b73984e41ef7297338ca0db1b4bf51d1bde41372e4e4bb9ca00f6da1a54e55fd20f1c21ee996e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = 33fc92d18d7aff541c2d8d3d0d590fbf94c7fac0f5403ef4abab82ee855e42a0753ecef6154dde04926799b2f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = 1fcdce642c0628dbd694cf14df7182c5f5bc300ded6c2c9354866a52f4ebbcdb3a07f16cd66a1f6e25f1aa5c36\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = fb4ee64e15307f7209e60aaaf58ffa1e3348c3e6aff46cf95c3a15e96b65762cf72749898649aa4f2554ec973c\npt = 426561757479206973207472757468", + "2c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = a64ad7dc7d7f2c272293f2c0fd957c4748f3911e6bc7242a3bad175a20b4508b0cb065a7ec848677ed9d349e5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = 95eec59259b5fb711157229920349524e7e85756419492df26298ec7b16668a892a5fa41ef7728bc8929a1f942\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 8cc240907d8cab9b1a0168abfd01aed8cdeeda252e298de2f3f89190e1e03719e40845b9b5d93df184702bfd7c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = 5cece69c96911efcf1406c5faff0de7e7965ce0b6b661df3290ee4b86b4ced5db98d2782cf8ca5c7ec81191ee3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 9a37d67894742202ac23904b65d72e40b7afe31f7aef8083e3f41185e402481f1f6466bd441a27dcf5a135f6c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = db536753e52ccee922ca4578dbfc8b24069dc526202b9e95d865ef7f76b9406ba6afbb665f4a2d048f0c8afb9e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = 015649389a63f9410008083f30a4ae626ac78d8cf4b35f701845a56ca07c58aea12908020c43890db3f91745b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = bf7df6bf223d74a821afeff194aa402a5f71eda3a2a78ae319b4f996aa7b0da67c221c87ff2a778b7a20030a2f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = 9003c98d71b1aa4f531c51537cf538302b5b6036e7af1cb4aadae99921baa5fc30aa86abc8ac525495d92f8b69\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = 6b7980f6b429998a899dcd87ba98a96cbf03b9a0878d3afe10acc0742114a7ee003047deb911ca38ef760fc903\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 4681f2b8075420e813ad70b9dd169187ee65779371d3f1abc6e62a99c8ee1cfe9be5088cdb20ebc11373d8af38\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = 66361f11cf2515e44be30d93a4a8d9497945f5cc8e7f06df6e4f3f58cb47951841d00ab8b4a52011303bc58be1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 09cbadadec104db37f240fcfcbcabecc92a03ec3157b789cc12c25e01c376a2f59189ff77fd8488b43bb81e8fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = d490d9602e9e59f96b8aeda570e2e58428ce7c06a4e4dd3b8a3b61307d6fd4c6cb89d07776c30417484ad2f249\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = fc5ae84ab4afbc898cb4b5712e1fbe7f75465bb6e834a50f039a0d2b7095cb732db60b053ded3c0e3df0626864\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = 8f1af0ac6b21371f2a347a007b9de28f54cdc3ee1db93552bd340732e61d1bbaf3194e24cb3707b018d97f5010\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = 45eb8bc519b8ffb448af0dddcf31b378029d916aef6c91dff98dc01a10d1a2a4c0e43445da2d2cc6da4037193b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 65cd2f48815dc6ecadc4d751cb8f9aab5e678d87abad28d4499670eb5b61c4d1c3c808d62cc946771a5673afdc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = fb0111868c29bc462791ef235b845450873cbce9d64a7d8851b993de034e13f40e9998046e9d29caebd1625be1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 6f6b24fe3698cb0c0a8b8b4f6c999aac265a81a25e85db60dd0847b8be655480e462cf8d3bf6f9beb21de26feb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = c93a9ae61a56dc361674f9e6c2570b464840afb49842807989c6d9f700552245151e85e06e37d7a30c09780cf4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = 145048e595c7c405afbea4c8013fe3dff529a2cee5117c61d70150a3c0b97200809c03cb7d317ae9aa3c06628a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = 29f01ab2a7ffa29fbd4c63a590ad7ecf87ae93a2c0eb1b5936b3a6d649e7803fc950a94810dedf18b930536170\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = 633d7ef1a17ff121485a82bf4bcbc9051d9768343e547ee9531f3b3c1cdcbc11dc45705553b1e16a1182488b1a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 37bc7fc586ccb2579fdb41d13865c8d9659bd8d383910e2474fad0dce89dd418404a458f02eb8172a1f56d8453\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = 92c1f5393dfe1325ffa85d86c1acdb492476ec7a5564820771a761a2df780ac6be823900edc2fb0b61a1ed5aa3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 7da1a3fb27f68587bfb66e54aa2b98b1217c1b274802dda873c2143aa69b0dc999537f07d473fe2f0b9dc6a8d5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = aad51528d9d7518519e3e610e9048077062eb164e64388c9bb8f63e0eab617be0ace7878cb261fa426fb051d12\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = a646e6617fbe4e18d4908a1f0cf46500fe3b82cc306e249b76586865cbfcc39d7b5c73b3f372a18a135aee8523\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = ba2a96778c42d5be2c036ff75cab34898896b62b1b2d0adee7dfa194e3da00a2c36967a74107c25030d1b23bd4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = b7c0b4fc91764f3935da56c764311e6ac6d3c8af44fd5b5f53901842e9bbbc6ce886dd615d6f6c4b6c285dc9c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 3420f14b4463e393dfaaaf07d48b383d6f082e5d58708b2f2ae51e432c435fc9e2fc17f5db6b1575343e91482e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 0f37542535f680177a32128a9f79ebe52d34821fd818298d6dbba4a51c484d1426d904b5afe80f60e180dbff91\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = 67325db96b9572e0b1082446950019b05da85c062e9a5978c3065aa5bb938b03cddcb50575b8b3b5b689bb59e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = c5211f82cc9a8261a0a5d93b005a241eb23404497b77689975437b19a2e42b6b7bb38a16ac51d813a413997e4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = 4d9571193ceffe27a4944d1c78fa0ffe3aa6cfbca6c970b0f93e32aa7a96333fd16abfe81de9114ddc45fec762\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = aa0133057136602263f523658181fa9bb1e66262a9c79b97b1579bb0b5b1bf4bc0a0fd64b607b01cccf52d8e9a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = 825b7894b5a6c4ade04f5f70cd98d975c5ae7707c5f8c1ea197e1faeb280562c77a3e5130d0037d64eb1c86cce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = 46f11fa25fe412843fedade29098bdf448fcc6473ff0ee7503d1345667d75e74746905166924db804399ec2b8c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = f7fd8d51d9b9d2d5e24b9d4de9f61c9d604cab2bb65712f80de2d94e8daa307de22283c4bb8614504f71b4a819\npt = 4265617574792069732074727574682c20747275746820626561757479\n# e", + "ncryptions[225]\naad = 436f756e742d323235\nct = 6f54ae130c8cd9b75627495187d6aacf564778a7bc9f6fbe7001b5a284592dd0c3e7ba3f14d955fe42eec72e31\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = b0ead5ca3c514d405e22f57459bf3e4b3b10480bc5c5ed6cdc907eec7d7c55791c3ea020640cdef28995163a6e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = a0fcdb684a93d7a27ddbdf6c2dcfb191d9a9bfa0a7ec64ce88b408cf8a8deb19b966cb641d944895b85f0b954d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = 616bc44dfe78f7f3ef9d56dd2312e8ac0d08de8f4852dae7794a7e7a415094f59665645ed09387507d00303def\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 8929024200819b1fd946627756e9bee6efe49fc6a80c6e720fe00c2ec5689f330eaff95e77398a09ac8d3b9aed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = 54e672bb9e4ecdecfa3526f5bcf1a6745f2007658f794712c8f68e2544c6dcc9946f4a81288c3e76475c1c929c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = 9846eab40523dd43878ff150ee10a54c5fe54248fbbed57cfc64ca52aa5817caf0465eb934b4dd99b96e5464f4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = aa6e8697ae32fc0908b8f6fc79639f65f59282329f74f65d82bd23d5cffb83ad289b7400f25a87825658c551a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 8412449390ae9f7a8811282c45109e2074213a282edee6014f0f9b51ad5a573de7c98d02c19fe9f29336d4e4e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = ec413d776c28591efa625f57ac7b1efc0137654044c3763a103b86e94082b92c2ba158eabf8ddc80e232f184a0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 179626ccb1dda5d800312a158da372a184fd6f1803bdb472da045467f2d8e4676114881aa10cd1c3979be9cfaa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 6de796ba74b37a78fac00a329ec3e7c936425aceb4e36a623671cb39b04a571408fa1992bc592a44ac56f2a96d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = 48b947a68b838f5393acc967cbb6f52dbd161328817438df5dfb9533cb1ec2f7f77aac3c8d1a487691ff3f917e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = bce1baf335f9a2a0677cac2bc6b5d3d2618e772f3af688bc82fa63d839c5e7fcd51535fcd9ccbea75936d90b51\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = 952e38288246111e5cc6a6f0fc5901577dfafd4e28bc544ef5e468e71bbac87ab338773f859ca87f3474fa629f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 660c6a8f448d5b0680cc1dc929628405e2a6c02da409cd3c6fe3cf7141811abb751b223ad789fd14b9e1602afb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = e5747a16c008e797c3be09d597b2884945db07314faed0f8f778d4b6b9cfc59620d53be6ed8b4aab2e4d9f59be\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 07ae27bbcee503b65523d33d061e97316f061f7c355e633d3c4ab131fbf33f4c6792e947072774bdf8adfae78e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 3d9f2b4d7c14170cdfd535f6190d35e7a1abb2021b30b40ee8f3bbe3d54c02cf69f2b9da331a916e739d74f959\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = e2c42282ea2f99db6d93c31bd90e7bbff5e3376d32303a99e358bd5083918986469f01263bcf60c38b7c822230\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = db37f6664496ccd0cc0422c0151cbd0a5ae14cc5355504e76b52d7cdc0625eae945ff1c39f37a78de712d9d30f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 98c02dac817d309004e910ff1aad1ee768d641f717e68a951762dee0384f8a5fd09b47a5ce35aac62a1093db4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = ffb8ec458cb1d80e79871777e3d6340e41acfee88b8a777d08f83a95e9e8c0806f23a5ae627b85c1bf67031d3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 9666674453d6e55e481ac351253fd806f1dff6833c755f16737acb4e01a52a15eb51549892f08c039710ff17f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = 87faac25c2e84bbf72abc74bb8f86ae409bc36c1d7f4ee3583c6246a2cc4f72bd4503c92209f0bdcf2bf9b97c8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 9b779902d73179cc203b8551e595b2525005f1b963768fa742471bb8e399ed016806052cffe16ec1113bb92761\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 9cdc91cd4dcf786f3d64b9e60f60aa39185aa9124d67474e8d5ccf252a486b8f99475f2391acb83cfc97572329\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 5a8ac0f7e52b423a242ddf4a109c81d67d340f6c73115e327fa34768cd57e2b2f03b97b59040757a0ce78c8d41\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = 77796249ac3cb85b11d8a912f4e3ab18e941875e4fbfff3ed13b0e1e8b6f70199fb1aaf82c90e0106abd697fdf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = c62723610b47a9702d7226f58e4b309a3165e81425a0e0fac70dd6c3c2dad7230da418743a3f196a51c7cd06db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = f2783a56b5f0cac017424bbe7d29dc9cc45ea7a6050ef83c3284f5ad7bc889aab2cb46e6916a683b17b903b63e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 16bc024eb0af9037260c822d45fa786e3c259aab1b7a4a196a72c3e794e78446440ba42b531da44d3d36d0a042\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 8890c5615e5d6b0e1b212e26d80a7e8c0d03e796377f09e9377aa0497ccf89c9\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 51f60f1d4505688a1aca99c9b789e44f38a5bfa177a6b4660ff57114bf50c6be\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 25f7c731201fe73978b5c66405f17de3e59b7f1c4bbe21e9ff57541d152841ac\n\nmode = 0\nkdf_id = 1\naead_id = 3\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 8057991eef8f1f1af18f4a9491d16a1ce333f695d4db8e38da75975c4478e0fb\nskEm = f4ec9b33b792c372c1d2c2063507b684ef925b8c75a42dbcbf57d63ccd381600\npkRm = 4310ee97d88cc1f088a5576c77ab0cf5c3ac797f3d95139c6c84b5429c59662a\npkEm = 1afa08d3dec047a643885163f1180476fa7ddb54c6a8029ea33f95796bf2ac4a\n# encryptions[0]\naad = 436f756e742d30\nct = 1c5250d8034ec2b784ba2cfd69dbdb8af406cfe3ff938e131f0def8c8b60b4db21993c62ce81883d2dd1b51a28\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 6b53c051e4199c518de79594e1c4ab18b96f081549d45ce015be002090bb119e85285337cc95ba5f59992dc98c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = 71146bd6795ccc9c49ce25dda112a48f202ad220559502cef1f34271e0cb4b02b4f10ecac6f48c32f878fae86b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = 5b23a1bb4a46eb6534d7929b88055d6a73fe36fa2209b7c851391a8b73aba3f8034e2cc588317ad35804fa4f0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 63357a2aa291f5a4e5f27db6baa2af8cf77427c7c1a909e0b37214dd47db122bb153495ff", + "0b02e9e54a50dbe16\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 13e916caf926e56e911b1f114f4d3b91da26a5761bc475bb874e91fc625e2f15d6789a8bcb69907d03d618406b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 1ae4fc091fddf17c3c18c8b7bb60063668e6eb7fdcd0abef5aaa8922eb73b4317cbe38301689a9bd876487e86d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = 3034f34153aa2227884561ea011af79eaf74fc9f4540c7ef71bb49e80c0a38834ecd2a2582c0c6c7412b76fbdb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = d9f753851465e7153c1c0ec83c5d9804f52b2a984e6d8bbeafd92865a736ce1dffec4cb28f3adbde0d16acac77\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = f3af37da4888aa0b0f1ded625e06a277429df8e8d89782b6d10e58e94bf50136abdb2b5daee5101213b0f49f5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = cb8bc2f5c08dd4ad61b85ea2e0ad5d0ae244a663172d1b7b2cf0477f7c1f16d35b3c5145fd6c310db97fa56f6e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 7b21af3ffba9165013c692cab1287d60a93c82ffaf3f9329ee5fa9d8eb6f11d2432314f45d02b2dd5a3f73438c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 039fd4450d4c35b2ec404479975c3a83a526bea12c1d41653e758a8f84f41b7ad2c1ec84f6fe0e21dd664f36b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = 2f65411d6ba8e3113b67c7710502f7772bfc9718d37f21f2cc4d0f61f2717d0fdc2c2a380f8b84d006e8af33e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = 494dbc5558dd047c8e6f3c547cf5ae3010496f99d2ccbcbf8e3660d435d40ed41c441abe4a71f7cdc298a47512\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = 155dc29cdc2e5718756c572197731172cb5463692619d10c0f49142c858e7fe4c84a801ad74ee11277a899b17b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 554c22933d7d58c6689ce050d8e1eda0af1a1e6b0c9621ee5c3cecb24170be59b59794f78851bee7c75c9bc9b2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = f14f868aeec918d8917b5e1c5a3acba3eac72500e2e1c5859e940b836bb5fc690c9fa666040e0f24235ef89461\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = 09aa8c97325c57173175ff935f1545dfef19a3c23df9d650e6e504b0f38476f9c328e9f8545dc03eeecd397efa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = aab8d8659b899dda7ed988788c1f753f65182fa46aaec3790c752c5e6d4edc66d1a29cb7775a06d611cc3ba9da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = b53cb489b5afe8d32b8b7f06a85ea21eba5d95637f1b60f5bd065ca400176588edbacff42a2fd0b9b2319c6b54\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = 2de0dc0045de431a43e2d46b8309c01755777174ed464e3076d1af20b0ea679e40c426df862d3d9e24885e815c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = 4e92189ed1d24e7816771cca561591384a644a7ace00cde6a3680d83032c3d74194dd478019cd89544fe802db9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 3992ca5ddc6cb82d81f1b317c3a1105ae1d0b5b7bc38649c7c350a4dc257753097bba175deee96426f96aee308\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = e6f475061e9cf348298d4de1b3ed8e84d05b1a22210222d317092554b4b1b591b89c91f890da65e815294eb71b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = 7081949d6353a8a4849adca6ab69c21873368cd5381f317cdfaf64d5e47b21499996a890b24df18e96a50ec4c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = 154c97813292de73d50275d18fba298c207e7c8f27f74f2d7566db9334348166b0be420c0cef431e085fd44324\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 9e453e6146c12681cf1ad8c033c5a18cc28824c847a391413fc2bf51c0657499fcf3cb659cde1c0d00dd092d24\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 53e99d1fe817118adf77c5eaab64ddea7f8880e5296c5261194e666931924c92d031cedb844f23f2284270e4b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = f4337b127f13c333d1c979803fb31fe57673d4e68dcc907dccbe67cfa2de78ac154c63cc43510a821f7dba17c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = f6ee59922b6f249f7d55f64d52692b06f6deeafae40f91d56ccf8d574d61f93a37cebe5744f40bf5b1451ef983\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 39975125abc4f4647b5e8dd5141a375f9ba66bbff0c4f89fa26eac66abbb71f90044be9197283ed9b60516d866\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 545ed2b3050db6cbbae44b8f59fd3e80635390d22b2a93114bd928fffffb126481b32ee539120ff99dc3138dc1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = 2dccce6855d90951971ad92eb2fed5961823e402af0d4f21f910465c3072622ef18e37f91e6e456a854256159a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 1c614a68a70a26f0824a92d25121791d985e8f99a54f0b72475ae04656f8517f5124fe0c8d55d243e47f296f5a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = 9425385e046c183e19515b5776407f7cb6b8b71a0352598e57f8bd8808652e1267506432084d98b8397ae18df9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = e5de6144eab00d48ecf33a175be12bd845fbd640ed9cef6c6a31340ab536c9a0f07291762f77f1638e248946f4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = e402b0a9c028a1b292820d8e438506d157ce717b5c8bbd4eaaac9e6520363df7e108900f0f94eecbfa314c3c43\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 47a319e1ad50f8d95f55e2075f1d54f9af446636571d81b39ae95cd50a55543c74d65f811aea42de7ed79ce756\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = c35d9f43b38e549c6c12a3aa433af0d6f3fb383259ba8292604c82f6bb2761a474a165c37f6f27ab816388af3f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = 918222466085e53705e47e6162d3e715cc1ca21bfcfba857dcb1a4dd1fe45c0fe95f4eb2dcb7f27b100dd165c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = bb2136e56748f6d78f7c4aa8093cbe651d0081d7046e66873ab849e7b155e83402fcabb30af22b607a3758e5e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 7671268965a6bff9b8ffda26e5292eb37e1257d3952dcf37a65a6077d93651744d5e5c44643b1b0b53c20d2039\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = 17784b52a709bde67d6fcc6b6de937cbf80f9cea7405708f42bf1cded9da2f6c240a6d2063692bf2c896c6df86\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = ddeeeb8ee50963740d7283ee5404581b0eb97619acba905588f66b5e79052ab61da7af7e3c9b54c201899565ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = b4a4871ef73db1b66c310341e67187c30cc526e", + "c5fa203e57848449f029d20906f8968a6599ba5b9b5a519d1b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 5de1796b6b89f1cf0b93c88c41e7778cfb482a81f3bab287f636b10d0c10612cb884aec9b2514b0c1b7af59fbc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = 041b12ea31a73f9fb5b80ffd373c13a938a1f7888923355e17bb47c62221383d614d485bd25d090c68f45dfa93\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = 96506b77c1a44ced490059dbda1578226c3514977d4ebb39fc334c92b71af1220463f46af1d9effdaf099d23e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = fc3dc86ddf279c9bf386c0161dea4a060f5e109484a4c0371bf551a5aeab963e0c38fd3d1562531572fcf041db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 762086d44613f1c0a15ce6c5dbf89d314e3af3728c0063a8eee91cda202de81b678230eabed359421493113578\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 33f3cbd6ec16c70b1e639d455090c939732cecc87c7eed10bf57cd395b31c3b48f9a5a1655b48d3c471f57e969\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = 515dd43217bd14c705e96f8032e58fb486ffd167c89215111ddcd88087ae0df6741180eea245e2f834aa3216d0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = b93c95015ef99d815be1381fb27a6c5b2ba1667c859db56b2eccc2df9ec697aeed944f0cbd93fd8f952432015d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = 543a160b7a3025f401958732ca4892608bb3bdd362f6f48c3052e0b5599ddfda1b9ac57dc82d436bb2fd890728\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = ebe8436ae2822e2f6c3ba59b8a79752d10201da5551caffde4e8421e35ff23918e82ef57c154882edf949412b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = 2e3babd04dbec3db0c25943f765409f83efe07287272d53fda796edce01604a24a409791b1dc6c9491ef951ead\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = 23d8e8aea875a89cd44d1a0f2f652f389a2ee8899c06f1b186f2d35b98ce2ca55586bc8304f2ad8f11ec6d4a45\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 7fbd9f0b4ab1ebadd868ae523bedc740f19f619e3147cfd44626ac9e0148facf092c1b7a1439f12b66fab1ee91\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 79901c340c134f34a87943df878ab284769a7fb6ab6b63c03107150a7c0bf02532c203b847f6b2e82b9dde4daf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = afea3edb11f087496f4e969455d323c65936376a11db5818717b3fc4729567140aa786e25a6420be379d9d7356\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = f7ea8ba2c5aa0317e7364d13429d7db23aa3184afd9698fd368287043ab04b9b0da3477973aae8df7c95055467\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = bb875e89ad36fc0be4ff873d25548e73c572f22af59cfb75db6a5842528720d0e9251a8d0d69d85fe4a44c23ca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 93d5bb5d990e893325555ef94928cff7e722dc1ea4be036e7803dc959c33cdc052a3da5af36ec904247128ef71\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = 1c77e504b276395a277babdcb14e96c02d44966bc1722e813e2ddabadfbe0893be0d5dfeff38abac3b4fe8c6c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = e54391814005400e0a3712f651ac1cc3a4d8987a75c03b111d71f80cb9b1491efeee7a2894e794e83ab3e65333\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 84e80b892d7f4b4fe505047d67f61d8a62de98429d4f34d5fae2508e7a38037ad8c67e85b9def05b628a0b85db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[67]\naad = 436f756e742d3637\nct = 3feff021bc5491d7329b2f0521397af99ee65a301488697b3c96ae6e8216d92b43478e7f45a8950c16888e94bf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 328bfd026fe81f27992e84d4daac65d37661c5f16c41b4901163eb0e4ec4a9da77d46b7f35fa5eb41ed19bd054\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = 3f975f0ecf397b0e57e007c588bb93a4bd123506089a7c907f733cdf21c5359f861e6ecf36d137f3b8e3b951da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = afbeb6001680eada34d532ed5fcb64f888eda521bf62ec048405c40433d6cac6cd1317f8309529354d581767ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = bf217e3b30a4210e59173df68e359f806e9a1636e2c683d12cd1ec9443fbc1c7c2b14f54ffadbf4d0d8f32c300\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 4dbdfc3cbd4dc0efdb3c8f9e660d07bc8f1d022679c0d0ce7108fd679992dbdbf4ea0e05caa1439fddc705b5e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 2894e03bca52f3d6ccfa334a5e6832fa73ca18c75d21ed01321d7cfffd87cf56ac3b141ebb5dea1d611adbdc61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = ea1c4c156fbf85ca5e6dd5cadd8bcb6c9e19b3b833012560d5da193abe33752794f92e67525446502c0b684aed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = f7f162240ba707111097a7fa5030fa6e96033f3fc67551398fe06bb26779e33bc2e8130081ae237607e7a8146f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = c3343330c59be643478135ed7604e9f5a8e65cd6c38b13d51b0e3ee59bde00c2108116f9d585f0c5941c32860c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = 252d5d39d319eb01e8723da3adec3197c6c012a058e7ededc5fea6ace3cdc643c45e17cca3ec4e8f22ee4cc373\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 77cd702a74023299629f0f3ee73d1f1f9515939d4b82c0e4bc1cb608b3281dceaefed6dd604b51c28fffb772ac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 2d5636db4e74f6259a4a63927cccbc2393ccd024bb9880a475776432ba27e1c1045c73fbb74948a8d3d2c0f811\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 8ecfa6ca7db677ad757d74ff454d1c8f076166bcde9cf71bc22a6724cb6e5ce6e963aac83650f45f36c069df85\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 3951a980d02ee0d047402352895ec3092c96687f3a4a81af987f808ce7a7df88cc8a2b04ad4dd7e1b93a3cde00\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = 5fd41e209137f2bd71793de55445a4f4df44f732488d657404b335d0a5e21d737d3ced858be28d5f396dce8810\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = 1516e99633edc73806a84334bf6a4b5ae77461de405fe6827da12c820a5eaa78f6aea9d41b22cb0c6c11ac3bde\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = b2ff502eff6663def30ffac7e432f1e580ea814b8513b1004af12d268de932e7cde5a55d99b6cf8517f34c4567\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = 34aa152d2822ccb3c2efde62f6a7923d9bfa510376c8622c0148fda24c62a9da754f979c44c65e93020baccc3b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d", + "3836\nct = cf271c985cd39fddacd870f2be45eeefa6b1f7dd7d85d4865708847f3916656b4d05ddf593a0bbcbef0ed984c2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 5199c1fddf6fa7c089b20665662284fed97ac3c925973bee516767b4fe1e0005fe476fce94bd3deea4d0c9fcfe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = ef3a374f39725309cc9752d6e661c79cd8db58bdedbbd7d6b08fe1554644e5a601433bb035240dcf7a3d9a38f6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = c3e155aa10237e1043e28a7a8f681b91792e13bf78c897db601fec3d8c284b247638467a5a57dda646b90543c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 0e72f2d5e27c37094638f2d0e3c1b1d8d7c745ca85546348acb4ab8fe1a3d379191509189cbdfc4245090487c4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 27ac400f3b4beb50ada443e43d74c46730e1b71eb72e97c636d0ff977d79cf91bbe87c6913d4f9601bc90ccb4e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = e8b2e055c163061a6234245f3e6ab72c9c7e897c2c2d00e298d3774f65c0f538e6172cb12ccb36a98278f2e3cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = f61f2943d8a4648282206473fa3702cc74fb1d6931ef2a52ccc88fc4e4b6ce23667103f6d452f691e591e6afd2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = 0cc73e09604e6bed58aecf1b365285c56f5a94ab35c3f4177fda4b52757a1f003c46b9ff528863ba9a2644dbd7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 2e5ad52049529415c2b24dc5949a128cb9045304e1645d428e9602dbdccc9f4d8ee5b7337caf69049d7091267b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 6146ffeeb44cf294c63962c4bb48cb233a5157eef4c1688a99b259cae5b0125b2cee8a4969a7c8736c3b959d3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = b0c71e3417967f477658a019ad720307e21287096fdf9cba517c81bdaad0dddd39a8ea1ba5e9b03d0adea8b4f8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = ddc7ea7991cf45bbabed2c1fc38ca55b475a226bacdd1778ec8f90f38fb10ddd9e14ebcf57a8a472f89005fcdc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 43b4c369a15522e7fd8ffc94ea8fc0ac4bfe6423f2140d741948b99d7f37a7d19b8c711cd1cab239eeb8b6a1c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = ebd8870f51fe43cfc1ff67bae967befad397f316d183382f72dbc8feac3aad0c06808a0f914d871be6ab3cf2c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = a5abd9ac1c787a9548b37346a4a6337e694fd42fd180623fbb860e9df75b0948e9558791d5729f064c11cf11d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = 11b1858f8cd4668aba2d2c6b5f7a9b34fa4c2e5afa16ff42a3c05d58fbb2a994a387ad4deca4ad6f569d9a9f39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = fcb7d46fa9102974cedfb8e83aafd1dc2392042b8dc52dccbc0a6717440597fd710bd9c1ea3af0e3d7a362f122\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 780f8f46e0c247ec2793933ad66e2926d6461426923e2f4821d021facdcf0271fa252fde7f640d3c2780932bb7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = 0e0cf8a78acd8b57ccb6271c134fee2ee7c2ccaae1fd7869e91b07c9252a81f27abfcc14e7d5f79a28ee444676\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = d6290633b09e5511d1c4e019a1dc35902c3ef1b3c6f25050a88328f615e737e0a5a118a2ad6ebab15ddf982c0e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = e1d7d3ed74c0ae1a55c25990813f19257aff7d518c9cea74e958c7e9da405fb0faf1b0890e5ebde57958eab161\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = 337be5b4890c40a215ec994a22c052271d190bb16c21a617396623ceab9c92c24659f365a825fb3d2f83a2a51b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = faf4e4ca80ab7165a7c438dd3408d639d81be2fd41acf359c7bf2aa36a3ae2b85048415582089ca077572c8127\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 117a8924f12695b93ad2a524fffcdfea837ec279e587e23bb91baecf5db4ea35c54658dd57c3c4bcd4e7c8b19f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = fbf09a8165127a844b9d879a39addf98f08474e244a8db6dbe50d51944233086aef4ddb0cddb61fa9e9cec113d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = f2b6bc73bb81a7db754d4210c3e29addb2bb31668321a79d1673c258acc6aa35c62282f9ae89c4fe3caf816ea0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = 1dbe114873ed874af58808fe65631fd1ef2e29a4142e7f15c3e9c12abaa11f26e4a945f662a99fabc0def49caf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 424df6475b58070d56590f81e287798ec199aeac5a96f8d39f29a78fbe4b0b0a9c2991413e815edb0266f48bdb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = 672f979899572fee01ee11addd53923252cfea452f9933149d53cac450ef7215a98407c997096f16a87bf316a9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = c4158a774b811d3ba2bf11e00ea2b4887abfa329219370612935a8b22f4399718689be9bc54871f6a362c55f11\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 9a153e98698656d114ce7b45b6c24341d50d66fe45a170bc570c185eec7f0424eaf20db7118d5ddaecd911f692\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 641c90874675f1ad9131a995b632648e557edef53779e6572cd9ea80e684ed62b7c3cf25380634a0f34d3a2d13\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = cdbb52dcd782784096133a696ba4d20d755f0f150f4e1c7245cb17e30a5a599e53850c53ee980492a0ae0a86ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = d2d7bd0462eaf3320587507249643315a77da7cdb61d9e00b59b7d882142daa8d64ff910b637ee892b97c9542f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 31d62424dad797797679163e601da04bfb30b1b214ee56fc514f728d3ec1928175ef03b04cc0ec8ec449145a9f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 72890066793d4ce5851795f2bb11a702503d0b02091d8520e1236ca9429f6915e8b07ee41c560e9301a341b1bf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = cd427af93e5a6e662da9d023a4731972348a186fda02f2524f197708edfc7770e2395f0ba24c0e3a73827628db\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 0f54466a39ee0e3cff12f715fff595576d925f76afeb50193173d744bde8679fae3dcb65be7e307b23ade40504\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = a30fb4f1fa85c078468ddb6ded139106b6b4f19f4e0c9f51f32801a3f67af90fafd3cbf46c9692ab54bacfec17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = f5205006e1605b0f5b9943d5bea5c452c00261fe468902d948cb4e77a88c9", + "cfbd9c4f765de197d67a0a2e7097c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 5a1ae229d393354ef6188759e73ceaef47c5c5038a4764774f996035000d34e9f8235f7a7ce94c1a6a29d982e3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = edec2520d385d5a75d4281d927865302c61dc3d99311ce987fe9ee87c2035fb93a5ebc2e5ec9396a9ecee6b973\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = c410d16f9eec0b1f2e6ab1a65fab63885f1555e3499d1883012cc94ee87490fab8e82d40b749a317b15b26494b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 14f1d6f624b582aec247062f9f9d6c32d89c80d7876d41441440b324f9c769e4e071320fe8ecd30a8041da7acb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = 7f89975b443e215589978e9f61e6207cede48a6e5b19ad4df15688babc33eda041ae74f5476b6fc37f10798dcc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = 91dd02deb3f61e67ff45cd8a2c61aa6c39df18b4d5676f7b6c57c0c274b4a65c9d22a8b412ec9eb2e2fe5de3e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = b3c6fe76011eb105e4b1d5a511be0e863b5b3f3832ffe8afc84966b36ed4829c734b1191e7fc83ea94db64b024\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = baffbdac2c8c9a24909bbd467ee896625d9dd72eaaa11b7ee1520cdf64412c20a07fc60620ff17e9c19f5cb519\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = 8a7bbc189f3b80d0777d94cf7e47270b0d120de46e76de9a896311d4b8e4bb1e946475641d987c15e1abbd39b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = e24362464d437c2d00bb59f020282c6a72c43bdff5c660c6d7184272157248edd7362e20550545cd9b7e2c54f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 9808dcdd8dd239d2405dfa278479dad5366feca0c6e15cbf0750c68e092c08fe02ebdb029f0719022265299453\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = 6096422f4c0a38d68b4faf4364e22fc98534d594b7791cba71ca1e1a381b318158e34eaf30e4b030206792a859\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 21f71e717075903e15db104f6865b6f7047fbc3dbf65f9f648d15fde45c1755072c8a211c1c0bcf5d5b42e4137\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 636e85e1b727f382bd1d83910e0908bb3f47a204b0e04a77722c76f168919489727df626e346600f28d0aedd32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = 4f6c63ce156ed1168d83778579215ce35312166bbc98d02abc4ee03c60d02326ad07c51d08777544f0705cb7ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = 8f8359af17b3a5c18343ccae2b5d553b9994dc6f7ea613fca8479529f842decbb118ee9e74ede49e7003b49f3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 221270c0f2ac46fee06b8b779eab41baa74d0ddcffef47b9ca30a33f76cdde4b22d5a57bd91953736d98b1cb60\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 23a8555e5165ef29e3d30d087f471c2b28eec5e94eb818d8d4fa422757019a3e1784271627ff2b526333b740e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = d375e5d6ba2387ab0f19fbf63a55af82b4ea6ceed080be285c6efcec7f1d9eaa7717d8bea52783beea0a8b06d8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = d4747347e4f5b93863cb1079951819e9148ef5f5b830c45799efa13ac446987052d47b20b678621f8a223debe8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = 9d759d117fbdef4ebb9b70fabba081c3d2c6e083faad82999f9b2fc9ecbf738351594eee9d949df083d9c954e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = dc539696ac9a42698551ae070eba7dc1b540ab553dbbd43e1113e0f1079d3e6b092e90e9fe9b5a27d2b86dfa50\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 6f508b76afab6ec152f4a9f19013f37363c5f348ac098e172efe775f25c8726190eb17256fd91f21d6aadb18d7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = 0ea02391896c4b37451a3863344f606dfbd654afd7d58aeb29b09d19768dbafeae09e858f6726e6e708130db19\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = 52b181eeab88887689810a72ab9ca29eac16910f635e5eb2716a47790017b3782c9f8dba0a1bce3bda527fced2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = cd8c5f53ef7a6a19493d3fb4d88a491c3663c0a6d8380f53dfed5f727e583ca6de725645c128a6e739c4f928f5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 5876a1c9b5971b0433f9dd08780fb47b4bccf298bcb9363c83a376ddae778d9ccdc9bf13f6f81a818828e48dbd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = f68cd40a6d61712410ab2c2d3fdf3d5fdfdfebdc2e533c6e9150615469189e5854cf4424022aca568bbdebf527\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = 3b982a6feb4b033b7b742c895c16d0c273cfe4a3e43453677626fc8eaf5867b26622ab8d49cafb444894ac1e17\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = 3f283b4367614462aeea93abb6f5e565a9138e4b3fa3453b719bce40170210869025725ed494f9db4416b06411\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 549ed49d0ed44536dc6f9a73fcb6cb6420f0441b87a269c390974602259aa376f20e16c42da372d5c1b397da28\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = 9f3229384c4dabb5e647618f501b66989311fb5258b19b4ad20c72874f273fb8a434dfdafc8803346be8d5e801\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 239c4c8a6dee032f79cffea36724709c2ecdde052ce0c9ae6c15f7757eadc11ddb0fbb949ec4720040d039a3c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = 027b6cca81e30aa3f37c68f619badbbf4aa9d26c5eb279ecb57b6f5fddd4020e6143e49920301c8ce1dd0d60c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = b14f60943b33a79a398b225a517a0f9bf03709afa714375d4398371551e91834ffa11baa6e27c878593113596f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = c8b145b8217f0b86a8c69ef1d835bfe6c2185f22d87b938cc2a4d838c830a75dadcc7b5b7b63823d3aba11c14b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = 53026edabb6dddcd3b63512641c2134801130bbbab6b1b21cda7d5e4a48af68fd56287552834f1120be8980424\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = cd52eff6227d1e8a9201acb50faeeeb476515857f0e127a0db69176d41e70ccc9c01a9d426120389f1d08eb5dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 4e9c7956a5fdda91bd84fd006df5b298edbc6055fbf8553c733eb55658fbb8a4d3b80d969838bf3eb2153c47e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 46bba4391f8c75515b7a2b2825071d09b44a73450185375540902cf86c47917fe9f19156db6555d6a8d9e4ec00\npt", + " = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = 69aceffa957a4fb972a42bbbd1daa8a98d1dedadf925e827bd41b8e8e4adb33de639f2c8f92e69ce7669a63cb8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 4b44cfa8a50a1eeb357b08f1659ed01fa0527d3c4ab59d72f0bf06301620cd2d25be3dbb3444c3884c5366dbca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 5442eafe977df2fef456f9658e6e4a74b7c90180bf8a33d2d5adce2958bd343741fe1579ef2f78a52f5a0842e1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 30b747860a4f39eeb11e3758a15cd554142490fe12c9aabe5d3c71fdce34e69a6c1d4c799d485f4d4b51a5c721\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = 608dacb5aa99f31f8c957b3c4630aed121774138ace30d373dd98f29c17a6892e1a842d727671721145d93e5d5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = 6fd543b032740e762f04f6d90d83e75183a997214883246bc24d4236d6e26656124289b4b4b6accee4176f1dec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = 6e3cdf915393c8a4265055c1d2671b97776e074115156e10e7f81e69adf97871bb0ae58f15fbd7b1e31a395292\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 4bd80d3f79c99c40b5fa3913fc83f5a7d9486fca22f5589f2b4aa50c2b9d86e3c0f1a49aed3ccc1c9e6164e7bd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = 31ba0bc96f3a6db0ac4bd73b17d5a0f21ddef1668db1bfc5a3f3498f88a23033cce86933abc8831f62529df2dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = c3cc98fa65baa464cb950b3c539c5988ea36f73bd3ab13f85be6dd0df1f9d79a9fdbc369d9c286253f78126e93\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = f337704ea92c55ef28b1cf904f066c7b62187a313051ce165584b40a2aba61ffc04dfd01be8493e15967234c73\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = 3050885e6e284811a759bd67884ab62f1d0bce7d790729d6cb224811c83b73cd3d708d85b826e204c5978f47b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 461dd9b8e3c50875b0f07519cdb9aef7d13f34df61dd97a093637b6ae09cd1e24741e40a2c309d0cd6b11394e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = 9f795bed00dc2ba48760fd5c9cdc2006ac435ae471a69c8926019f7d71919829dfb6359bd54b4d87c04b3398b8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = b557d7f6cdfc4707e99c047bc831a0558f19bd9b15ed607f143aaa85bcf73ecf2468752881c6e02b3e83d4543a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = ac251b361aea0a771c028cc9ff768994d008389f126970d9c89d1b8713575833e3757fa3f9efa076b5e77ec318\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = b69c7bf9d7ef08541f4bb4d96030a83fe3fdd77005cb16c865c7923ba30b3236955db8b28e7beb3c0535b08f5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 615b848aa99f4fb56bf436f6673145784906fca3172125375eeeafc57d895d3f6cfb2a6305d8e09f4e077278d9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 1d4006772989c69d4d8b41b189ba68d1216d003812524a1db206da42f111ab38da9de9c39b06d0b5a0f4f7931f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = b9cd2de5a742eff0f508eeb3a43644060a88a73f5476e804e7be8d426b39b3f23324c89bc653e320b651cb843a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 33d5a57af1cfa7fbc086b39770180dda5bd9ac8b7fcfd5ec8f3608a8e239ab39c6486b6733b4978c0cc011adc5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[188]\naad = 436f756e742d313838\nct = 3f9665a5e33e089fcb79413f53e79c40ee93ad5b2a6de97a35843ded62fa277d4c258ea260a5c7e06f95a8d449\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 242b8fee457d1c21311ce60c7774b6262852fb64e1d4f61de6d11f002535ee6bd9d65cd7f87573e1d8cce8383f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = 0b6e167302c1351ed4b8543c0d2879a7a8fd58e42f906e57279e4b52d8b9773e9f6a10334a5dbc07eec5577708\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = f34086725af61863c42947ed52aadd66b4e48b475f13266384e48e2b536c3dfd2ec6fb984f3bdfbdafa84b213c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = a53074ed3b88343c5b44799aa2cb6b323ef5b0615f948de2784c00af2709f7afa25f987ae24eb061b69c6ca2a3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = d293b46b823f01385c458a9bb3125ac70cd021de4cdf5624810a9899d3a3ab4394a3b8407f6a49ade6ed95cbb0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = b1c77b724b044ba27240fce5f840c4de73d13b00ce73ba7582930d725a9766347cd6e210362c6ad01eae100141\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 12afbe5e92bf061c3ac2cf48919616fc21f268cee9dcea2c9f61e02d9c37d0e2a27f55383b11ff4a8da4026a2b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = 7397c4a17f59b44a4530f2b1c2b766412244d31f340ceb6abeee44fda4a7e08bd390cc458b19ae003cd833143d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 6181055e55e9f226013faba7694ad4f2655fb7c4ac9776b98fa9cfac6d4373a60199c6501a14461eff0ebd9eab\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 51a0413101207b176f54ff80be07e219d3c526633cc83a4d4dcb504e2f394ca8be6c927c1698cca387eff89f8e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 4dda2afa170011d4a85928780d19d0874e6fd993c1994d23e3ab6abe2ea48e8b6cf72e3935ecb9f5db85978500\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = b37a22b46572fc97e5ae45043834d8a19bfdcae1b98111cd82135ae2f059d85e686d464e8ecd5ea42c73f20362\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = f8261dcdc908d46e6aa03bc25565cca2f2e6b86436ed94bd0ca94fdf28001b8b541a2dbae111b28f1a56a2e86a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = 64628718d4472b3f592cd09d3e1180ddcd7d2618129c0665085d3b377b3065c03b13c3e3f5cc57cfec3038c6b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = 3f2ac05adeaaa8d70088302c09bcf3c2e29b11ddfdbaee8a2aee04608241ce8e663fffc4421a92abc69a1c9f80\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 44f72dfe1d6de08f95407f63ec7fbcd97cee0e778b74268d7a50c994653cd3443efd4fb50adb13a6d6c79ca9ce\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = 8860128148e7fa751e2176bdd0989f81699f4a6f8db8b9bb9a740878bb98c1da926b34e7f10326527ba27dfbb3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = d79816873a6e24b3738576e66ee2a3cd2faca1a8e6300e0bdd7932f7bbc2908f02af2bce13ebdd6cc108f4c9aa\npt = 42656175747920697320747275746", + "82c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = 6925df0f28576eff6d3a575e8917bd1b94d3f656299e6d7f10b6cef87d0a228051c21e8c4adb6202396cc4502c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = 45465e087d0b390d3a13351a12ddc2c20b3055d2868be79465bec9a5eeb114a034dc04964928d973313b3a9f61\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 92d94f52220fb8908a226599d67f101d8803a6b38a59ca1cd439cd42fb3e9dc3cbcb4449e36449e5f9823476fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = e95cf8938a01158d09ff66c37a5436d6118db2aedc449951126ebf4184da493803a7cb6a71dc0e09cc46d42a22\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = 95ea0e88e2cb4b88c1669d9567de88a8f403849af9a74254e906ef595586b2e168eb0cfa2d6d258dc7b75e1ee2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = e5c938d2605a5eb68fd5dc37a3ee20a83633ed5e5dfad218bcb2d8962eec2346ed040b4eab2a95b44fd98220fd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 9f75c8ad1becb7a32fcb307c5b29a91c53c7e6a745ae7664071d4aa3bd23c8e99859f1c4731473948a01655e57\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 5b1e23823276f8ad3a202ae5403efd60eec67238703767f85e2f7d2191670491db06e109a0a23c47cea7ea7f0a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = a954766abb4da6228599061eff24e6e488dd28e645044cd2ff194114dcf8676da441f5d3d6f6a95156edc01d58\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 08388a64ac543cf748ec47e7e6080a38ca18d40eb3ddf1efdbebcd57d3f357aaf7ce57f7433601175bbc2a97e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 41d792afa8a74fd0d9bf4d9cefb406d9208b3364dd9a4059234ec9c3d5ecc08d5dda0e8df119467663f8b770c5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = a765697054b7d1bcf82d5a3869f01ad632fa412e23f8b517ac4745e2f34954c422f108256d36b7c12ac942a9d1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 164e696bd9a10e227fe9a3582e40574fe59d225661c5cf09a7c75423f8ddc370337292bada80e48b9f7d88628a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = fb6d6c347a61f7279767a92897ebfff446e929562315ab50adf47cea14d7f03b0d86939c0b0dacb245fe4314f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = 61625bab2d94464510430ff6f74793cfb64bd87a5ca4193c5b80401058d082e351a36cac8881aa083018f9443d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = 6c04a3f61cc9bfc10a6e67e2adcb7818a61a0709bd49285c5bd069808799a4b888292a4a802c15dd38d75925bc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = f4f8b3ba316bc1109069dceadb7809b2864c7857f8d9ed3f8523fee84e4033ea681bd941868e1190d40ae96b18\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = 1ecd688ce744a684f660547887d910f0445b5b7167ea29ad646f2668bb064d83160205b5e977e7487bb4d06523\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 38e766640dce7ce1edf30aa96c4324763036633bb4d881fcf26225e3c021e333ca8aed8288c565fa74e9238333\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = 8bb09de244855723d0b697b02a967bc98d064bd529819046640c1bb009f27c9bc85f68aebc1da97791701e4e53\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = 5364e964cca737d51bd327276a0bb9340c4efaf3630b6086b4b0e20205a418d4fdc8855962da8b682eccfd53c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f756e742d323238\nct = fb7a049058fade2c1653b3dccbae8c4ce3c5d50cafdefc618695c8a8955a8b8d48cd792c97b9c7599ecaa08456\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 72ee72219b3239f96a902837a653fbea4a652f76e765ea4009e97f647fd0441f23abc6e6fd4af79c91bd206307\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = 54215a6653acd4e6976d5230607127f898aaae52addddebe170515d8cd6551eafc0e653d3f91e714dcc2cd0504\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = 1375489e8fa717c36d15cd26c9519c7c798af560b41e354fa86fc242760cbc448fe81de05044f1e8671e3a29d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 025b901c822275bbe1d6f72358f9919d76ae4062f9cb29f0e8c4c034e2c8791f198ed837c5a78c01ace2a74e89\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 7a7d9406e7bf753493cdc3167253e53b21ab34b5fb906c13255fc63001566aee76f1f2ba9dbe2de613e4178195\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = b192c5443cd1b4434c3d5f031f56fba802c965eab7803371c9702dd15927d1f842981c633b28e93f3bb9254df1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 1ba5f39d42dc02590901b8b2b755e528ca59085feda6c37318baeebdf6604cafd79a26369a5d55e58c45d90645\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = 699225fa0b0a7cd2350d4e6100ceaf21945bde25084b031bf2c83bdcaac73ae9563b5e3f60366d4f152ebb156b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = 03a5d97ce6e8ddf07a3c2c33dd4d401eedbd09fc85ce68a5e52b1a2d63de672f9ed62e5e4e3a843560b4363937\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = 177a9525be60073909a731825a3622cc60dbdd7540e7fa6b706a45beff03f8d3c65220d439832a42660caf3beb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = dc3ca9a852da948fcb4659fdd6e3b8fa307ba56e8face0f3d723582fc06c090a7d817a82df0cecf86335b82e31\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = 6ca9b591de5234579a0aa90bea2f016d60cf50e77bc2a06d729579cb8b7b4c68e5dc6d483d337c5151d2989180\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 02e644e2e21b35f8868e786ab534c31a485b6e69097d10df2a25f24993c4d4d407f067796af1ca127de2f325fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = cc9ea8088634939f2e757726833e70ca2b00d7e617b1e525bc147fbfa9c6b3d29621d38a73e954944ff4e9ce5a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 180bec2fc3e686d2f37f2b18a3b0a195a2277c28ffb49d85bcdecbba92f7cfd3d1832a310baaf01ca9396c3d8a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = b067fc48293520ce29f528b1bad11c0d38dbbe942f0c27c0ca953469dcc88bb1fe4a6b156134ec7803a8f6d367\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = 42bb52ae652c21e3a16821c1a7dddb127e42b56c1985cf3800090a9accd8eb8080861e00f69f22bd09af42e19f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = 6bb1ca4dceb6137e525632def5bb056f7ce6f5dd452edb7a69449e43e947706e970978d47554fc50707c30567f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# ", + "encryptions[247]\naad = 436f756e742d323437\nct = a37b7d0abd040300937b12ec5b6c3c43e594295f2b1d0f3292fdb0c38205d6ba925d0a11d3d1274b10a45c1d29\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 729c0bae1bb680320852f4ab084062a0b143d535eff67da55999088f9f751fa7fcee704f524a9f6b8a94aa280c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = dcbe1ab062cafc3bd1c189007316e09bba8df92eb0dd9ece681a62e1d5bb9ab9ce4e5055257c96d70b43b62092\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = b08f5a570d41d21d0aa528c9da0b68bc2006e2579a956616f40f46caa5c24f5bf2e6bd8bd5ebf4bce2b79fa282\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 985991414c213e093e8ca144c4ac5c6d90e2f136810c934831e8623a64349dfe77ca188acd973551b5241754b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 67c3d85876339d04e89d76bde220151c85f88b83718d50973ed5712373545ede91492b1f22b3c2da20d6e6d7f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = 7552addfff71040acd9740a8deda98cf23dbe410a9af5fefffb7d0a21d60cff55d0ef91eb295fc2e0ef51516e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = 8f531f2137e6b9d7b8f07af2f3fbd425c5ed60cdcd642c035f4354432d6f5d41870cf1d6bc18bb192489982866\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 18ab939d63ddec9f6ac2b60d61d36a7375d2070c9b683861110757062c52b8880a5f6b3936da9cd6c23ef2a95c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 7a4a13e9ef23978e2c520fd4d2e757514ae160cd0cd05e556ef692370ca53076214c0c40d4c728d6ed9e727a5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 4bbd6243b8bb54cec311fac9df81841b6fd61f56538a775e7c80a9f40160606e\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 8c1df14732580e5501b00f82b10a1647b40713191b7c1240ac80e2b68808ba69\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 5acb09211139c43b3090489a9da433e8a30ee7188ba8b0a9a1ccf0c229283e53\n\nmode = 2\nkdf_id = 1\naead_id = 3\ninfo = 4f6465206f6e2061204772656369616e2055726e\nskRm = 3ca22a6d1cda1bb9480949ec5329d3bf0b080ca4c45879c95eddb55c70b80b82\nskEm = c94619e1af28971c8fa7957192b7e62a71ca2dcdde0a7cc4a8a9e741d600ab13\npkRm = 1a478716d63cb2e16786ee93004486dc151e988b34b475043d3e0175bdb01c44\npkEm = f7674cc8cd7baa5872d1f33dbaffe3314239f6197ddf5ded1746760bfc847e0e\npkSm = f0f4f9e96c54aeed3f323de8534fffd7e0577e4ce269896716bcb95643c8712b\nskSm = 2def0cb58ffcf83d1062dd085c8aceca7f4c0c3fd05912d847b61f3e54121f05\n# encryptions[0]\naad = 436f756e742d30\nct = ab1a13c9d4f01a87ec3440dbd756e2677bd2ecf9df0ce7ed73869b98e00c09be111cb9fdf077347aeb88e61bdf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[1]\naad = 436f756e742d31\nct = 3265c7807ffff7fdace21659a2c6ccffee52a26d270c76468ed74202a65478bfaedfff9c2b7634e24f10b71016\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[2]\naad = 436f756e742d32\nct = 3aadee86ad2a05081ea860033a9d09dbccb4acac2ded0891da40f51d4df19925f7a767b076a5cbc9355c8fd35e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[3]\naad = 436f756e742d33\nct = b7de2d672ecddcc77718bb6736d3982fcaa5362198e63690f0452b0137f55480f5d5d3ad7c3265f7aa3f72f140\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[4]\naad = 436f756e742d34\nct = 502ecccd5c2be3506a081809cc58b43b94f77cbe37b8b31712d9e21c9e61aa6946a8e922f54eae630f88eb8033\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[5]\naad = 436f756e742d35\nct = 0ca5f85ce4569e0ff208fc23c691c2fc85da677a270cae116fd5357f9c4548f5e08a3ded8e137649b86cb5cc97\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[6]\naad = 436f756e742d36\nct = 9a953b1823973147329f2fb802f2944e5b01a889b21700374b3dbc2cf41ddacd04266796a47364cefae16db6b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[7]\naad = 436f756e742d37\nct = 472bbda3a67603e6a242ef8fb037d033560cb9e8f95132e9a52f16d0d4fdce88bee88c00f682fea1798976b3da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[8]\naad = 436f756e742d38\nct = 2f1a2b7fa25d10af90c993c87a533da919c3d274e25bd74b4e5a299afb283138a8f1e6d85a08d6af19a384ed22\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[9]\naad = 436f756e742d39\nct = 8afc7a43e9e8d575f8e09c71dbaf2259fab97b5f48d90a284a1b9e0d52c2974e22518e9c22076e7aab14c7dc7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[10]\naad = 436f756e742d3130\nct = 10d3c4181248ac1e01aa263439ad123ad9458e46da3d513c8eea06b4218a442ced2b27c68f2bb27b29b0f9fba5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[11]\naad = 436f756e742d3131\nct = 14d77d5349d17d3f3cd787356180d424ef93835485e82593ce8b0403eca1e1924a7aedab78a2f3be37994bfec3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[12]\naad = 436f756e742d3132\nct = 1665cc5b2829613ac24feedf9847207bee8ec2ad536aa0a3b1de5cf614e5eb419b00aaabcc7d9b85d03626a053\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[13]\naad = 436f756e742d3133\nct = 4beb712b2dc79cb2923affcc5ee55df481a807922b74894741f1a8ea1ca4145b3872ae617dc23c1b940320dc5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[14]\naad = 436f756e742d3134\nct = d24b966c9ee0dad75457b0bfbbc0f204540cbb01e0875fbbf6e434111b0934b4a4d1cff94ad918135233021ced\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[15]\naad = 436f756e742d3135\nct = 64fcf95695b71766b8447d96ce5af5c8629268d6738e46032a5a14d7f69d280ce004876eee8dc3009987e5a774\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[16]\naad = 436f756e742d3136\nct = 0ab4da8253b8eb87f8c934527484e9b1371ea99bd48c47ec9060cc43803a8640ffb0c904f41d5821c3312a5d7a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[17]\naad = 436f756e742d3137\nct = e813a7fab6db458b5b819788c35671485d53b2647c8989e865cd0adbf9fdf21e98c69b9e49976b6d29611768ba\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[18]\naad = 436f756e742d3138\nct = ef43d472e241bada94631ea7f713b553fb01df4abb004f56a4f0b0b35c2879259d94c48b087b9eb84393d5029d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[19]\naad = 436f756e742d3139\nct = 87573897dcb5e2ded008addde56b4652b44b286662689a651bed7949dad1034c8751462d9e7d7c7dabb976d4ff\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[20]\naad = 436f756e742d3230\nct = 99e8c16b09b11d63912d23b29b9514c5a8a13c7f6d26352088b648c6cf1ba6fd71cb15c16a911d2538023fe4b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[21]\naad = 436f756e742d3231\nct = e82e1588353a993dc57e713d9f1dffd711152edb7667370044424291877f93143751643a3d2b646de364d40060\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[22]\naad = 436f756e742d3232\nct = c07ab9089b2406c2f8f8871e555042ad683c6e9182b3e5198032062b81c59850342b653085bef4525def9078da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[23]\naad = 436f756e742d3233\nct = 882f8fde7e025247d9684126e08f44dbe6e8158804b9c42b652a471ba904ce19f8f3d3a9162230d717ae083815\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[24]\naad = 436f756e742d3234\nct = e14ef552b77de117f9fa7384c93bce3dfc471e78853b6c35d2c5b18b57ba7940650805e61c3b915e1640aed9e6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[25]\naad = 436f756e742d3235\nct = d258655d099fb86e3e2740c0c1e11621ef7dc61c9e770ceb07fa9249a3dc42790b0e0eaa63f22bfeee9181ba03\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[26]\naad = 436f756e742d3236\nct = dd836e8c6", + "28a4d794cd731a26cfd591985445be24cb5ce9eadafb86dc93e03b1b53dae2808d5a8a56ad4ce76b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[27]\naad = 436f756e742d3237\nct = 95dd4f0d739fa6d3a5c823af5be5cbff4f67681ff4e91da4dd60862e0aac191a01a2a786e3bc4ab17968c921fb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[28]\naad = 436f756e742d3238\nct = 4826674734200324d6111c86c76cd574b2e6838b61fcdec1ff9166140791919ee848122aceb4fa39a4b00d487c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[29]\naad = 436f756e742d3239\nct = c23f7e91ffccfab228848435d09a8d5b540b3263ee03381dccbf268244e109b3ef00f46c7328e5bc5904a8e4f8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[30]\naad = 436f756e742d3330\nct = a1951f639b495355fde23c6097dbd93a2291c84e2e5d047e07f0db291b2a23a162106328bb257ea78c87ce1499\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[31]\naad = 436f756e742d3331\nct = 2efee285dce215c4d318a7e7cb3c79a5f4ed206810badfd13db42f4af0aad43675e2c3c7f2818018ababfc0bee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[32]\naad = 436f756e742d3332\nct = 19fa32f8a868463888d6468a9177c2c09ef5eb09502646a6f2f24055d670e3714f5bee6c15a6fd3cfb8caf6a7c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[33]\naad = 436f756e742d3333\nct = ec8cf86893c64175c3247ab71f71669de7152cdf2735ee855b272535445d707a58c9188c386c9d62cefde9ad4e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[34]\naad = 436f756e742d3334\nct = 2bcb2e07356124e3bf185777306701d48c3f007df73ad77ed95e87e18d503fedf881f9b428edefff6dcbf35457\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[35]\naad = 436f756e742d3335\nct = d112973726df1719a6756479b75ccb218d5cd493f0a641344ceced3c1e7e48a62dfaf2eb27f943b321ffd11eb0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[36]\naad = 436f756e742d3336\nct = f7e38aa4187cb6f9f2b46990dc690a340b1244b0e96ff3b4599ede765b1982cdefdd3738be0b2e98f929e04cf9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[37]\naad = 436f756e742d3337\nct = 43011ed36c336f6c499a33fa35ef185e08434ca63f9fa5478a533133af82c3bf38a31729af87a7ad1a0db6e886\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[38]\naad = 436f756e742d3338\nct = 3241fa612f4feb1f2dba73beef8a35da4b3650af9edcf0fb6d364b2028b335933e3dd04bcf013ddc5df174a8c1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[39]\naad = 436f756e742d3339\nct = 195052ebbd8afd125f4462e935ded4c6cc999f41d11aaacf6d645fab1f6e64ab0ea600a480ec7c21921c6a49a2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[40]\naad = 436f756e742d3430\nct = d659b5beb44258ab7f5045a91e4ae127d1bec460fe58af259cd3ba8eba696efb4d8344e0438ff64a952955f16a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[41]\naad = 436f756e742d3431\nct = 1e5d05cf7eace9542eada2db4f7579452febe6ed7f4b3b53b5971238ec182e0c2a898204f47338dc469b1a2298\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[42]\naad = 436f756e742d3432\nct = 1cbe40802bc5a0c96414ae9330eff0adf7bc160944863bb354f6602d49989076010cb8381892ea8f30384226ae\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[43]\naad = 436f756e742d3433\nct = 02d88f0941c79663d90b8f8603c1a78101242cce044fe72ec585b48bd71bb79636f04b04084b4007cb24bf1ddc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[44]\naad = 436f756e742d3434\nct = 5910202f4266d349ca3b1e40f051fe16be784545bc8031f533d30e82b900b9edf5096f448d5e2de8fdaea4b72e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[45]\naad = 436f756e742d3435\nct = 1f8e71b30e4a199f7ffd05a7feea60a09bfe3d052047def72c8f8bbc94ebfcdb9b6bbea97eb15a30ad80f67ea8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[46]\naad = 436f756e742d3436\nct = 4feea6befa30b7318fbd769cdd44e4b30374993edcdc3bba868056b30f1f1fbb32b7ba9f17807feec73e646cbc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[47]\naad = 436f756e742d3437\nct = e62536d436e2bbbfcb8f01aa84671ca601ccf537b3288491b20ad62046602d8f3d1b2fef5e0af542b29eb7cb07\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[48]\naad = 436f756e742d3438\nct = 57e90938ec88919ad5c7de2e2ed9b410e8e8ab46e1983f71ba3a1a85bd8726e7a84777a97532165b0a1d00636d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[49]\naad = 436f756e742d3439\nct = 056625bc0f5da4d70678d51a0b9e79278042a18d81e4c12362dcffbe91d53b8c5f357a9e0afde2b841fdd65cbe\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[50]\naad = 436f756e742d3530\nct = 2e4ae62382e4ae36dea0d243bb69e02195188eeb91009c6a02dc4295543452233e97caf6fdb1909b7c4c9782ca\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[51]\naad = 436f756e742d3531\nct = 6a5101ea9f65bc392d82cb52aa6e5d5e09262639ac5a7fa4684c3724c2c9883d20873b4a03816d0d62ce550820\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[52]\naad = 436f756e742d3532\nct = 8c3ee8a0bff374943428dcfd6d6fd0ff06103c776a26a04ea4c25c606e1442e4be786fd71c412ae9916f45f8ae\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[53]\naad = 436f756e742d3533\nct = b382567d688e25f95da3b8d7dd290115b5012acf4783bb70336e192ec4c52a9769b29c20325d9a4caaa72e9ece\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[54]\naad = 436f756e742d3534\nct = e048715bb0bfbd3c5cf4df882d03d5464ce682400dc4c349a2f1d1827473100e7d4dd88735e21cc3d9017c097f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[55]\naad = 436f756e742d3535\nct = 17863a9136085e486347c5bb9e13b13d311c7453881a6632eb9711e6bb0aa8e4eed65a3f77025eec5b18b4b180\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[56]\naad = 436f756e742d3536\nct = 5eae326e0d64c3d2eb3ca030b86574aec87ef9aaa3e8f73e10a55f15d54cbcdffb1599a30fe765cbb4b01b1620\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[57]\naad = 436f756e742d3537\nct = d8f57a7357b566b35bb59f12d7cececc675ff42a849cc0204b59fa8dd8f32e28367e194d5f0e6686b5a304d5fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[58]\naad = 436f756e742d3538\nct = 5291cd0c0007d0f903ea34a44c8416604cd581e135cd53388fccb2760e64c497148f510a74bc0bf8c5d9300dc2\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[59]\naad = 436f756e742d3539\nct = 8e686ad247050455bc96e7fd09bbd75b811479f19c74a4b9efb42358138c0665154508b40d066cf01786e5b14f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[60]\naad = 436f756e742d3630\nct = 16b50d9f5803b951a5cf311bc2f974db9dab83290a29c892173400864af47909d89bdce645f43b18a40ad224c7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[61]\naad = 436f756e742d3631\nct = 069c4eeb76b1fab4025818cd505109062398b57d996e16487ad944f97fba4225299801806753ed2008a930d792\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[62]\naad = 436f756e742d3632\nct = 0daf3b2ddf8acdf78228d418742f97a43bc4175c4490d627ae4b689a1b58187cd95eb8919031ef450b43b5a3af\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[63]\naad = 436f756e742d3633\nct = 0e87df1bb6c8e6c39bfc581703caa8c8c89283578766bf180bc1c47d297d42ce90e87172f7f7d75de175379e93\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[64]\naad = 436f756e742d3634\nct = ca21ba4e95aea092d5514267e6fda85ecc1aae1b52bb03c598655e64e839aa54aadcedbb65c1d1d5d7c19971c0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[65]\naad = 436f756e742d3635\nct = b38a51ef7d68dcda26f36ba9430c841310fbcef1dc2b0656747faf4987c6da76e81cc098b6da02883c47e9cb80\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[66]\naad = 436f756e742d3636\nct = 1a8c0cbc4967c3da7ccc5e14748fca5b1ae0ce7b07b99c60ae133f493ad94fba50c2e0f44edb68a1a6d6ded1d1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encr", + "yptions[67]\naad = 436f756e742d3637\nct = 4b232c97fa9cef6fea482bd90002a6637629e59e6839aa4b51a9698b0db79ec010bb06aba00c1b05f282115181\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[68]\naad = 436f756e742d3638\nct = 277542b55e05f4f5b6f1149a45e981973c860e140b0be9be700605be226b5482bdc94873971d7a03b03b180b1a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[69]\naad = 436f756e742d3639\nct = d1bd44f2aaac3cec6dad09ec5939c8bcfeaa45a020b104af54db92805c150ceec660c14be21114e691c17100b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[70]\naad = 436f756e742d3730\nct = fe86fe64f4424a3cc43ae90ca90c4c829555be0d346195fc6f98c027326c5907f652e9ed292e88c262c8d1333d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[71]\naad = 436f756e742d3731\nct = 4b1a3c565eb99b18edf4240a06cb30acf037dc1a932937f649c24c3bc313368f9c13aa814886886cb8250e33f8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[72]\naad = 436f756e742d3732\nct = 82b190bd232d86589e0e1e7f37c0185ad0ddcf2b082c76429e1995b0d1f62acd588bba85b94f226da892db271f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[73]\naad = 436f756e742d3733\nct = 51f98f99fa19184916e1b08c76345b5998ca5fa7fb5242aaa521f7b07b47cd53ac3dc9637e13b436ca617a0b92\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[74]\naad = 436f756e742d3734\nct = 323a32f6c87217db499ac6bda975371333f1189a618fbad68e0d8887d1c71b0520fc301f259598de1e48b1044a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[75]\naad = 436f756e742d3735\nct = 43227f6091853dd20734cbb1f0aa1ca58d8fcada7a6b8366a1ad0f777b34ebd040abcaed06be5dc6f4c05df706\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[76]\naad = 436f756e742d3736\nct = 209ac341492e0d028320704c2af7c2a3ea84b86e6542b9b3f2a9a3b7da467d3faa471fe2dae932dccff31f30aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[77]\naad = 436f756e742d3737\nct = a68f24e02ad3f221d11e3ccd7f6a749f7e3c1b2f37bf20108ab4996db6c599d62ce4425bdb4f596b84eef05e12\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[78]\naad = 436f756e742d3738\nct = 04309d4b824c4c2d7aa0586b90b18f3b96b8139e27ddc64b9a2e16850025b4e837b9c4e2965d46d69d5580a2b7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[79]\naad = 436f756e742d3739\nct = 015dfc58fa0be8ad7b4fa8fdd2705a07c9d70a615abe09ea744535667f0a444616b888f16a744ba50bee990ca6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[80]\naad = 436f756e742d3830\nct = 583194570397fd8c5f366627b695df81b281f70c97acb4f9e957739e7741e64aded30ed2bb892a082cff249d5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[81]\naad = 436f756e742d3831\nct = 2e8468cb395a1b361f4ae24d1fa7b080451edf50ebcc5a605cc0c64926a0a36adcbeebba318189e3a3f10ec1bd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[82]\naad = 436f756e742d3832\nct = db3a33983fec5d55e1152118386a3942313dd11a52b43ea2453e555619bdd8f2272c4ae6b6b2e45afa0708e62e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[83]\naad = 436f756e742d3833\nct = a55d4f5c9e4b54d5c430984040d9e3250a4ef60b51c6913ad9f0ffd24485c5220dce9368047b2bb275aded5d1f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[84]\naad = 436f756e742d3834\nct = 7546ced9a69893f81e8a1fe01ee428f1fa989d81a91b67b37335d4e3d74f4c568e37673c8357aea9585f1bf8e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[85]\naad = 436f756e742d3835\nct = da9ad2308781a5e98f26623db55632458b1213d6255d9f93eec34dc122d92882a573f4489dfe8819a33712a56f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[86]\naad = 436f756e742d3836\nct = 8807ebf2c3017769a8fcdf49724b6e87ce6b78946f157fa7b596909ded7f3fc5a74c96e6a30bc94c693a10484a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[87]\naad = 436f756e742d3837\nct = 617fbe2f615fe2d78e7ebd09d7119ab6aff2f6948f5b11b0fdbb38f0097fe9728d87478699ba2c4418833e3111\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[88]\naad = 436f756e742d3838\nct = 50a2a02f5394690595cb345db18c4da427fc31bd1e7aa225780a9f707296429f3ba7ea55dbfb4e9071ad46c33c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[89]\naad = 436f756e742d3839\nct = 7ad5ce81fc409119042466e46b8b5f69a9ba6ef9ab8f774d6931971854ae54dd26534ac8ff8006c6c5b6bfc080\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[90]\naad = 436f756e742d3930\nct = 9ae0d06ce9213dbea68533a6f45db7819a38ba452251aca8c648fd4ce55fa98ea1016e9b607bc2a1c86b9dbd5b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[91]\naad = 436f756e742d3931\nct = 7411c84f11d4b995887faebd4068eb91f4cc6a4210e78db48a5b95349c55797280ee86efbf50aa4979c4291658\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[92]\naad = 436f756e742d3932\nct = 00c70bb93351ff8c53993390f9739ba7c6ea01b7340d98eca81a48c833af3694586d80d9eb84a28609ae505e66\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[93]\naad = 436f756e742d3933\nct = c1292deef48fbd48a60e5ceea9d2de9aa74d6a6c2f4ad7af550502d48e85340031608f7c6be408909723e96619\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[94]\naad = 436f756e742d3934\nct = dcf02c0f52dad173ab81af5ba6a71c6aeab76a2f6bedb95a9686a11073ceaa555aad04cca16d61c3000d8f2707\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[95]\naad = 436f756e742d3935\nct = 99c731a1024760cfabed4c9e6e06ba16362bf9cf8af0984e3e524a35c57e1b70132b401e879ac25b5a19e52608\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[96]\naad = 436f756e742d3936\nct = 380da1568940ae8141c20d77a0c3ca063a0f742aad509a244cc4218a0894f2d4f70d442f2bc3f45e898e8709dc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[97]\naad = 436f756e742d3937\nct = 577edaf7ba9b06c19d8b3afad647f1fbe2cfe0a1e56532a9942d4d3288dbcf2d65720c5cc5bee93b4524924e0d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[98]\naad = 436f756e742d3938\nct = b8819cad3a864fabdbf303f761b2622ef5f12599684c59a81618b3e8055aae2b62030fa487e672339abb772624\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[99]\naad = 436f756e742d3939\nct = 8d0ccbebe563ba37f5973677e0b3cfc333032d0c6fed82158702b1c39a3378b02e8a474079ee03e7be10c3f8b9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[100]\naad = 436f756e742d313030\nct = f7b0d944940dcb42172ff7f050ced108a040c92cd111f62f64c7c52bfaf0768eb2c22fc50371c6c73a22abd7d1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[101]\naad = 436f756e742d313031\nct = 8a2759704dd2c7712e7fc09674b5c786a0c08fe6abffecb93eae0667adfc68f5b69a8dd1527fe7ef9260b665a1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[102]\naad = 436f756e742d313032\nct = be595d327a37a484b706780f14a48626426b35a61ca0c897304a8d3cdfa4e0f769bf7c489f207240a548494d1a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[103]\naad = 436f756e742d313033\nct = 58081bd5e9bb449b50338e606a5c9ddb06323e0b30606ec2e7ba914e9783be9455c5864e5cd591cecda45d3818\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[104]\naad = 436f756e742d313034\nct = 5b841f947cb3000c81e0dceb2a647d87fce6fdb8ffc1b168b483ce2a7575f03a02a4a7ec748b21a18d75d94f69\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[105]\naad = 436f756e742d313035\nct = 7db27590c2b9d81f0c51505db4aff4aba0114977c04ab386078368f4a6efa239d94efb93c2291a031dae851324\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[106]\naad = 436f756e742d313036\nct = 3d3d4b63bf33ffe734df92cdb7ff38133c3661f985770e814d5961c8bf8934b7151f722fc0d801afa031cd9a5c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[107]\naad = 436f756e742d313037\nct = a123bb67617a8d49db372b9158d3b741b55c6052bc23ac936dc1c86371594fce34e40f7a85041642f2941442", + "b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[108]\naad = 436f756e742d313038\nct = e593774a7353ef7730ee7fedf79199fd47df3f4a0f35aad4a584112283d137bb7d1fdbcf9d8980ed4244b6eaec\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[109]\naad = 436f756e742d313039\nct = a083192b5973ed1a6adb237cec62aad1a304ca0044e272fc023f3a906f696bd60f545f1dbc0ec7ff551619e0a4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[110]\naad = 436f756e742d313130\nct = 7bfcbaebb82a899a39ea6c34bd76be9358f53e7397d40f76b46c7262510f264d547c56fed89a688c4d9a2b2e4b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[111]\naad = 436f756e742d313131\nct = fbfc7bc29317c97a62de2ec25cdef1729d169986b334f9272a50110e1b37a71b6cb1e12b762022d4f49685979d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[112]\naad = 436f756e742d313132\nct = 21fa26c371405a806346f540f8c82bd562d517a1a9bc531f089819b7bcd66cd6adf4e93afaf2aa1b7ba2f06baf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[113]\naad = 436f756e742d313133\nct = 6c254fb53652021322d5ef73a16b6562e57432f51ac20b364aeedaae603cd4f391b06f305d9a2fb266a2d3e55b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[114]\naad = 436f756e742d313134\nct = 9d0e3c870e95145533491b24626dedfa8c2b54508ea88310c285e60d4064f3e033aa9ed7b0d06e759e9bb8cc1d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[115]\naad = 436f756e742d313135\nct = e18e654b8bfb3ebaa9a42de68fc117f1df0b50d1f690101d7ea5905441733f776a1bb789f6490dcd902b232924\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[116]\naad = 436f756e742d313136\nct = 44c2bc8b27fbcc94f7861e6d115203940d437c0bc10f6abfe3f7f54a1dbbf7e16d83a624de58d6d984db4629aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[117]\naad = 436f756e742d313137\nct = 40c149be04bf41e6edc15e40f44276ab6b76f9e2da3a6060680075467b696310320d3bb21ba23de62070cd2d56\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[118]\naad = 436f756e742d313138\nct = 582a5f80a54af024cdde0bf597d332f94b58094ad4930e470e9122a00da2823761733ed6efd7ebb208e5dc11c6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[119]\naad = 436f756e742d313139\nct = 6fedb508a62f8119866fa2f77680511461d6acffd5fe5c9cbdf755d0d696416245e94efe70c440d02968f4682e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[120]\naad = 436f756e742d313230\nct = 7b0baf62119a4aa6f261f840ff529913c0d430042581939fd5c4c706eca535d4bb8b27f4b85b063d6c4b672194\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[121]\naad = 436f756e742d313231\nct = 788717ddb583b85e508ed3adde0a02dd665d887ef538261718f5e08a1d25ccd6d3f669bed5ce34cb12fe94512a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[122]\naad = 436f756e742d313232\nct = 2d306491874eb01fcbfeeb9ca73bb6ae048077b87f524e597cc87e560ae8faf08a38fcac3b1608431715b232a0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[123]\naad = 436f756e742d313233\nct = e5b3e678e0e0df8de042871dbc3d2bc3acbfbda12646825ae162340636177e73aebc28265cb0430553940e5cd5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[124]\naad = 436f756e742d313234\nct = 6efccc349b12e2f49b660d577783681b571aa00faba56cc51e71c041eea5e2c855090a0183b395bdc5c1e649c3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[125]\naad = 436f756e742d313235\nct = 5a43b00495f38c68f39eed4151935cbb44104f3aae74307c474e824f8f5e2cc4bc967c4b9fe8ed41a6e00c1704\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[126]\naad = 436f756e742d313236\nct = 884e27f01a7fc3b3c01204a8d4d21128c597a06aca13081e82305ab6b3369d0ea39c401088129d9484d511dbac\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[127]\naad = 436f756e742d313237\nct = 6708a8ab40099f4fcc5ce3a1f4c1eaad0959f40d52d7efde9805a1e309cda3da9a229e3388f7fdc5798ddcf8ef\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[128]\naad = 436f756e742d313238\nct = 2b59c9116a3cf4a2b1ff7b862f05d0a9f4fa5b21beb071a417f9ddd229fbdd3160fcf1f5588f85fe1583d910d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[129]\naad = 436f756e742d313239\nct = 05e5f0ef2c208da0fce32169d86aadcd206ca2b1a64f06b602cefbf791960f99c6763708362b0d321e8b917bd9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[130]\naad = 436f756e742d313330\nct = 55fbb90f11eb01007b31682815a474280ab8718957856ad32b4dc0d86f71fd49ee1000957b76ba3f56ba5749bf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[131]\naad = 436f756e742d313331\nct = cfffd60cbd241199eeaf529be3cbef77a67d9c5b62fd65861c84056037c73149988be4d6031d036b9d5ead6494\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[132]\naad = 436f756e742d313332\nct = e065c3fa01c9b0d1d2c20132b5fb21d85c50715ca55d85fbf29e29c95b4119dc054a02a7061e9373ee6ed49736\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[133]\naad = 436f756e742d313333\nct = 2ceeb7fe75ad7845efa4867ad23de6816467b5305f5bec964c5d4726e6cedc42e18654c2000cddbdd18e013382\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[134]\naad = 436f756e742d313334\nct = b0a31296ead350554678e5460b31ce11c7f5928433ee2f948f441702112d838718170e81f4b3038139316a154c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[135]\naad = 436f756e742d313335\nct = d8e3e2a3c1452588477be454dea80c7ec1d84f63430fdc46143bbabd77348c37ac4eb24fa23ae7b4fc0e5bf04e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[136]\naad = 436f756e742d313336\nct = db487ed57bb04f39a39e6ae8e82e86ff0efb765c47bc49333671b6394b2b50f0e56907adb2a40bedb7fe70c460\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[137]\naad = 436f756e742d313337\nct = 7f7277bd1a14fb3843c88306b5f7480c2621b98d76a42e5cb6f3ca139443a2f3a07fdea341dff01e29d68a5afd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[138]\naad = 436f756e742d313338\nct = 3fc4dc2569ecf94fc28f7a61109351c4ddb7648d7c42285cf33d732075e3852d528cb7e0858313b5be0f00c6dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[139]\naad = 436f756e742d313339\nct = 825c39e7cfe13ce352225b76abcc4f434d3fbf8e1209f852326ae195c669ce411b150149e14d4634b6eedf0b05\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[140]\naad = 436f756e742d313430\nct = 9de9581a72f883c91a4e160c2a9ebb75e41538a9612a930b86d5c86cef16c4c88c86c6cb9c4b4aeb91b9ca988e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[141]\naad = 436f756e742d313431\nct = e04a92935f4ac59e99aab8d602b4816bf7c1dec5d5d47e5d76f75bdddf80ac7f6ed46e6a0986c5d50a980a61d3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[142]\naad = 436f756e742d313432\nct = da4285f3b19a5a63611948f89a9141b060987ac46739c68e65d85e1265043efdb0aa5d390b9e216660c29c9185\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[143]\naad = 436f756e742d313433\nct = 72c1383d0adf2021832cf8e7be8565f68f2693fbb79d1b181331fb84c189d8543cba13e6b7a6dea80208bb6f39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[144]\naad = 436f756e742d313434\nct = 7ffaef3ded32191024d313221da9a3652cfd1ec17cf65aff57b1b67224e5ff7a931e32c72ebf8b226911bddeee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[145]\naad = 436f756e742d313435\nct = 8eaf068482dec200d6e13a15f23fcb59f30cb2948ac226aecd002cea99c89686daf77848f956933cc25fd26f48\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[146]\naad = 436f756e742d313436\nct = 264cc5d6a0b7a0b10f6b1b3248b5a3324e3d6f478145618d09c47fa28978493bf1aff64ed4fabd094d5ddabcc6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[147]\naad = 436f756e742d313437\nct = c148c4bcadd21fdcdd7e068507fa3ca526b14443164eaff48a81db46148cd2ae333bfb325a335296bd19efbbc0\npt = 426561757479206973207472", + "7574682c20747275746820626561757479\n# encryptions[148]\naad = 436f756e742d313438\nct = 098d1dc0cb7cd977948f0b44542af26e09aa4d6ea63b17b5e72a78723ca9efe1eb002c98a08bdaa8b3fda0b7b3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[149]\naad = 436f756e742d313439\nct = 13fc200eb7d9ac3ec5672a9dab0e813903576fd05bf8fb7ee5635fcc8741419b869a7b8d9f863b12e88e2c5930\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[150]\naad = 436f756e742d313530\nct = 81a5873565aca0a8bf27d7e0a40b5190406a8be971a79e71a249fbba371cd6e95297140bf30a9a247db65b5573\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[151]\naad = 436f756e742d313531\nct = dbc759f3edd826642105b502435edfb28a66c7c9053f77f701d019e8054a854c50ddd9951c8d329afdfc5afaa7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[152]\naad = 436f756e742d313532\nct = ddf2376a8e02ff6aae395fc4455a4c776c0c9783453a2e42b28b3ea3cd1dece1d6a87924307611ccab815bbc4c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[153]\naad = 436f756e742d313533\nct = 87757e2c0821f95564bcc568723acb7171f293e955173726017985e9cb3383b33ed8066fa6f48ceaa6cac6df0c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[154]\naad = 436f756e742d313534\nct = 036d4fd7e9e72929cfd2e1fcecdc572aea5bd5ef16a92e5b711cdd9646eb3a1008a2e7d39ce74e67df6b73f468\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[155]\naad = 436f756e742d313535\nct = 5cad074af3887ff07a8d3ce2e8a20e67feba06ba4893e26f14123894d7819392f827f646bb28cd29bfbf7be7f7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[156]\naad = 436f756e742d313536\nct = e52d575fdb08e3d2084927dc3da9c7084bcdccdc88d997de6e06109d203b2c030ba2cb79a50ae8e0e738fc0736\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[157]\naad = 436f756e742d313537\nct = 4c98fe2ce4b77757ee09bfef308f9973c2aa28939ab24ef5fe619124b1c94e3aaf67d7739b22af2f3e158a04c8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[158]\naad = 436f756e742d313538\nct = f74e7f2532e417fbcd01f4683bd5ea14e94dd4a42f0834819d283c39f27fed8c3dc8dd3e74dcd5fb525d099044\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[159]\naad = 436f756e742d313539\nct = 48aa523a358b5777f7dbe60c24eaa1240bd2fc186d91b7d9fd340a62cdee8a79a84785873efb9ff65bfec68f6f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[160]\naad = 436f756e742d313630\nct = ce4db0c062b8195e46f62aa014b1cd99c00697e6c04cb0adeea45f076ae31200cc03f32e224c585208e580fc87\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[161]\naad = 436f756e742d313631\nct = a53b8dc05218c1f4dfcc2af880df86233ec8fdcf3697c4ffee694c0c042fd545e01a652fb30ce0c46c00f1c7cd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[162]\naad = 436f756e742d313632\nct = 18459e8a46abe63533022ab99edc9417f41f0e43704e3146bf7b3638d9ee9715e89d2593f47296d6e287fc25b1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[163]\naad = 436f756e742d313633\nct = d3d522979eeb9e6be40d83ad69cff87fc3b1c7b664629454f97087a61de9743586c129ba27849449edc3e218dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[164]\naad = 436f756e742d313634\nct = 8ecc61ed64cea2091b3e5b13ebc92f91f3daff14b029c0741b7b7541b5e4c4db44e6cb3ead3f379ab6f7ba2134\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[165]\naad = 436f756e742d313635\nct = 2344551199f0e4ffd040d05ebd33ed4e72b8798bb9e0a48c3cad3c3b6953dc51eeb28ed9bdf7dda5c96faf453b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[166]\naad = 436f756e742d313636\nct = 45247cc2629c2dceda0e9260ae8cd347d82ffe9986407b1d4279216ef9599dbdb6427d5a8b1ca999b6a86626fa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[167]\naad = 436f756e742d313637\nct = 451db2902d2b4391c47be9a54d5d53b476b5d5d71ba02832fa5b28f35c5a0604d161f4b2baebb09013ea8d5d1b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[168]\naad = 436f756e742d313638\nct = 97fd72b9c01b4974522d4bd494563f05404725034db95a4b4bd6dd147d6258cfe473e5425c39273302f654f09c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[169]\naad = 436f756e742d313639\nct = 77ef019177e690acfe0eceeaa26094135271e14125c3c9d84d539bf86150cf2f4d5e1871fcea5ab3a881e98f10\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[170]\naad = 436f756e742d313730\nct = 89819d7bbe96c3cd71d90279ae98765d701b3b21c07dc287b6b5af0fab9e4569dbf57701e4e20a9a68840c04e7\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[171]\naad = 436f756e742d313731\nct = bf4206d7896f079093d3e6fd309ce43999554b8d961f51e2070bd23850cba7071065369af22a56122318a34d9a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[172]\naad = 436f756e742d313732\nct = f10322e7dc93246fc9528b238fda0e8bdc779b908ac5dddf1411b2aaff19dddef9a5ea8eb464ac38939c5147f5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[173]\naad = 436f756e742d313733\nct = e2a426d1a686b4d994cc9a919c50a207f5c86c5d4f019592fd0c3255dea61a5230be629c77d69bcaebad454196\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[174]\naad = 436f756e742d313734\nct = 8b0ac7f5154a3adffe0463b0a7c86e7397bcd7ad1eb9db45721c6a472f55a30546de99cffd4042fdd7ac071b27\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[175]\naad = 436f756e742d313735\nct = 712953e4994fe54d6a5e02d1ab33df9b5f028726af60795aa8571ab53a1cf3c44024cd40d2bfccd79afaabd13d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[176]\naad = 436f756e742d313736\nct = 929f4f028c846ed34b643f5bf111e7c2b2cc38676c37918be2cf1cf1432528194f8210eebb330415ffec3ee601\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[177]\naad = 436f756e742d313737\nct = b5622dd7e3eec8cbb474ce5ec72505100f85c98725c2ab0ec69747b6a8ba6740417c1b90ba2d285f2e7e8aed23\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[178]\naad = 436f756e742d313738\nct = b94bfdec74e4da59e23a0abdf35e78230df609e6e939e1590483ccd7168cc0d730afa2aae1bf5c04c10b5d146f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[179]\naad = 436f756e742d313739\nct = 825fd8362d28d8c9ee2cfeefb8baa0ad579acd6380cadd617eb4241a45571fe75407f1c3c288476a1951f13799\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[180]\naad = 436f756e742d313830\nct = e91fd4c291642964a2e3206668e41e7a833b3eaf3c73d8ae18224479d5e603ad0d266dba04d07e187dcc7e8817\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[181]\naad = 436f756e742d313831\nct = e9cb31df1943fa60763a5883b2dd803f1a1e114b945ea746fe1169ee04206339a109b33d6dd4963a46c95b9d60\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[182]\naad = 436f756e742d313832\nct = e907d69102325aaa155644e2fbf83402752bd7c769abc9d587eaaddf75fa196de4c100c9dde8ab273328f8895d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[183]\naad = 436f756e742d313833\nct = 7ec7579899f8c4000fce0f7b6c5ebfaf4b65cf973181dbb4f8cae39256ab61843605f58dd2f40e5a375136011b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[184]\naad = 436f756e742d313834\nct = 6470ca4f7442d31ac907fcf167ad10b185ea0673a48f0fb52e08df541707ddfce14df56e1f1ec136eceda5dde8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[185]\naad = 436f756e742d313835\nct = 712c2484fee14b3eaeaf6e68f22016121302a6c4071e3bb4dcb41315bc056c7de29504bd30461dc61e2a62290a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[186]\naad = 436f756e742d313836\nct = 1089d0ad01eb981b0e75d04ac8ff62a2a8b611b932bb524cde1a33f1103765022b056f0d082aa41d162e9643be\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[187]\naad = 436f756e742d313837\nct = 7055173920dab9eccfbbeefe136fc57ef767e1e8e6db8eae6783235755ae9b0cccdbca572fad83b28bcc7b4248\npt = 4265617574792069732074727574682c207472757468206265617574", + "79\n# encryptions[188]\naad = 436f756e742d313838\nct = 62a7f47491f3d31a422fc9e908823a8f2d7254f36131d363c32df985ed6dda80871e3829375f25a96d90b45235\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[189]\naad = 436f756e742d313839\nct = 192f865b9b0f87c8f3b35b2ce1900e3687554a48736e6188aba905ef472c7377db213d32d56b903f7be0acee06\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[190]\naad = 436f756e742d313930\nct = d0f7f686a5225d8183394c33b1f10c707e7f085660f858d3491198b3a9b4e42f6a9eb365c409993c59093228aa\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[191]\naad = 436f756e742d313931\nct = cf3f64e8b054cf660298d2e7ec7d644a2337429476a7108f14f491345c42e1164a6d96a83b0c56ebee45cce38c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[192]\naad = 436f756e742d313932\nct = 9893da31204738a3f8f4c107c533f64cf8c01b81060308576cb94bfef56c7c204421503eda93d05f5f9ff3f7c9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[193]\naad = 436f756e742d313933\nct = e407a8a84fc18a3df9833de5ce4e227f338cbe0549bb70d1b30abd5c8ad89f0a0de24bc8dcdb8455c80f507cb3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[194]\naad = 436f756e742d313934\nct = c400c9a6494c2c62cfc420c7348f03b5598648842115975d204d7b039b3e6bec4f5a24b879d688b590ea0ad3fc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[195]\naad = 436f756e742d313935\nct = 49ab830a7a7be18d1fce87538b02c4514ce2e33fe7dd0041bf206923270ce1eae49fa7afdcc23c2e7095ccd371\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[196]\naad = 436f756e742d313936\nct = d5beef3acedf662be1ac545ff22e0968ded5e7f835082563cbf32f2f97e2ec57ac0a24ef9b69b311c08b2d0705\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[197]\naad = 436f756e742d313937\nct = 3200011bd93203e202108feb721f33cff9adf984d7b765c152c42c71a08f6a4b914f59aaea2373dede1d84f49c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[198]\naad = 436f756e742d313938\nct = 0d546040e599350adfce92d598fc83b2f17b8210648ff39c91d7382f1ddf9316fd55762a863bd39ac183d71cfc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[199]\naad = 436f756e742d313939\nct = 56d782dcc5ae009b8b10f486678fc31d04d3e2c2fd14557bc160540eb5b40eb2f4d76a2a54f6ca7debbc8f6091\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[200]\naad = 436f756e742d323030\nct = 57584651099749aa985fa971b34618aa8d30aa9c1fcbc8cd15d887ee5ab0fa3d515d8dbba66eb3b1bd53d5849e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[201]\naad = 436f756e742d323031\nct = d18e9ec60dfb849deb7f665a032f5819b9d047516a4be94a48e8bd2066662d183f7853b3baadfe8971e34a88dd\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[202]\naad = 436f756e742d323032\nct = b05faf558aeadfc164859a477e9cbcab1d27edf19bbcb35a813aa49282b42f8a20bf5fcf943ebaa6d94f93eb32\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[203]\naad = 436f756e742d323033\nct = c069204693e8b828a9ac4d6001f8b0c49a9e7f606a45a8829dcfbc7ef0c23618f7c5ac44a76b00d6b06bd32e5f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[204]\naad = 436f756e742d323034\nct = 957d7c12afc411e4c87d7cc1bfac25e4f3391aa9d71bfd0b8606ccd7565a78c39b02c7c9d763a2d3529600f7f1\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[205]\naad = 436f756e742d323035\nct = 648a024a31fd41c542eb6bc1ae2bc234ad3cb899fa65b1d22e947f061c5804f86df390f8ae79642630c26ab5e9\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[206]\naad = 436f756e742d323036\nct = a54a551ae735941e911b84b09c3a33b97c8324f745220f78a0514ad814502654b0377fb45e8628575a7fb14018\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[207]\naad = 436f756e742d323037\nct = 35dd21130084fcf97491b42348efcb8271dc611c94cc57d9f1d7700efdcb207d9b725aab10b33868cacb53b5b4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[208]\naad = 436f756e742d323038\nct = 2d7946eaf65d501637c5a51139ffe27bd5c0189c986731e9519ae256f17cc2b363adc654e28622236e9517007b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[209]\naad = 436f756e742d323039\nct = 2182643ecb216095a07ec8e341bbc3bbd9700b98cf6108caf2c6e6a99c567ae9650e18e7137784ea60c0037bed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[210]\naad = 436f756e742d323130\nct = 5cb48c09ae88281008141e22f274be6aeab55d061bd0592388330518bd4e9877f14edcebcdaed09b17839526eb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[211]\naad = 436f756e742d323131\nct = ddb662da553a5f64f9e70dec7a00b5fe2492c5a8e7fac8b11a24225fec99b72b46a259f58d30ea1e565c3621d4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[212]\naad = 436f756e742d323132\nct = a812ef927ca2d5a7e6f6c25dba203a28b3749e94ceda1d2ae2f1e4a9607304521eb2b87a74ea8d22cbddee107e\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[213]\naad = 436f756e742d323133\nct = 94f9430c6563ac09a8fa019177cb0bf6be3e222e3299211cb771a2e3c39dc490ed2962621d18988f6a8494dcf3\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[214]\naad = 436f756e742d323134\nct = 88277b8afc800e1bb7f26f46223b8ec3175d1397c6f132f1930429397b40bead4dfbd194f030b5f9eefeb88c39\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[215]\naad = 436f756e742d323135\nct = 409e3d1897304b141d13abe0f59a4b10d0af57618577b340ed6d5480e4e83457b7186a3ea05a18f80a9a6cd637\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[216]\naad = 436f756e742d323136\nct = 7ec49da8a4de583b3edebc5b67357cc3ffc51362866c02523ababe69f6a5ee3049d737e25610eb0c3a61899f0f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[217]\naad = 436f756e742d323137\nct = 4246008ed7b0791df31f88250292a3a1e26dd47b14035e9ee4279aaa5d51bf2dfb594d68761ef239da62d38d67\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[218]\naad = 436f756e742d323138\nct = c5d310202308ed77fb3bef60298eac77608ae541bc5ab2d9fb3e43c1b3e2f20cb266927ca85af01353dbaa0166\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[219]\naad = 436f756e742d323139\nct = 812334975ad365ad977fe1df9fb18bfba5af83ee39455f877a9f496c1e883f64571917ce52499479270c7db7cc\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[220]\naad = 436f756e742d323230\nct = 7455ec4dafadc6a32c4a1482e78e7c80d34ade86bcf44860230055fedae26b642f2577dd5ec3742e06fc72b285\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[221]\naad = 436f756e742d323231\nct = d99776edf6dfa1683b926c03a35a08f5fa6e5ed4307a6bffec785ebe2ad4663e824aea40958ef2fdfcca851a3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[222]\naad = 436f756e742d323232\nct = e1773f8fd60b35fe8459a194b3ed05ba72f4d0f16f64169577e2ee4f0d1e9dd1fc5bc5d10da552ae5fbebb0605\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[223]\naad = 436f756e742d323233\nct = b0977a21fb86e2f53605146703243dd713979041ad41b7f4e2eb07a81823a741dfd6296f7a021d0863cdf407a6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[224]\naad = 436f756e742d323234\nct = dcc76d9c0b453f3bfa0e93e4b21665157670d6363a0444bcc2cbbe3a82017712420fa62e5976f1eb459627350d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[225]\naad = 436f756e742d323235\nct = 4630e92285a0940af56c00a34b93ef07e755000d4b1faafd93eb01a076798dc5304c9119ca4b458ba39742a4ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[226]\naad = 436f756e742d323236\nct = f980e55d2dd9dfbd6f0d7f26e681cb6a99b01536ed287570db15819ebadea6c383970e5935faa97f3f7567d419\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[227]\naad = 436f756e742d323237\nct = 8b1b4be8257e2d2383b2b5236ac58a4bbc0619129a6af82201034f27bf762f14c9e113d36b94066a52b81edb63\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[228]\naad = 436f", + "756e742d323238\nct = 79368883a496b5f8962d2dd3c54116730aed4a6652fd2c222490470b66a91fbf2d8abf8d1336cf596a0c89b488\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[229]\naad = 436f756e742d323239\nct = 6e0315642bc29b8a0f6eae9f0f3772c4af2d9451b6756847cefce570299cc8a09bcb14bd3c8e4e348dc60a80cf\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[230]\naad = 436f756e742d323330\nct = d74717cc168f8cc3340346e442a7b789776ba2f5f3f50b18cb61608f1a638d57d5f6f819713bf617936f7193da\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[231]\naad = 436f756e742d323331\nct = 8885a9956a8864f070e8b83175dc2a76208c32c669fd64c84c7efbc9eae048e3a3bda1a6c5e9e014177985f345\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[232]\naad = 436f756e742d323332\nct = 8248c633eb511e4148c97a9d997288ffe3e9b130f7e1768900e07a3dbd0322bf5feaa3ef1069a69d2f63b8b5e4\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[233]\naad = 436f756e742d323333\nct = 661b8260a395a229aadb89a0b0afddd08f65597d5e2965763b4c8779bec4f5a91c6a73f395ee45aacdc03f244c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[234]\naad = 436f756e742d323334\nct = 9e270862f567f91b5fc378247693a6a598dca076802c15f311ad977c862cae39feaf9da66ea276e3f6826ecf3d\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[235]\naad = 436f756e742d323335\nct = 9e07269e710dea587007ea36f823e5a6c361a7d852e411d0f608468b61a1a4cda1e79cfa8ae3e0398a471970b6\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[236]\naad = 436f756e742d323336\nct = a2cd8eb604f9dab48b73b5e09a99be8b4fffb8eed1ae639866fa1626acba6469a4389f867c068601e1622a61a0\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[237]\naad = 436f756e742d323337\nct = fe968506c8c9a82cac93961e2470e048eee80c4a2898677f624d8a1051412475ea905a499cf6eabe8c2ec58348\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[238]\naad = 436f756e742d323338\nct = bb45acdb4652e760404402bf5d2a424e8fccc7c5dde8b26338ad64fe2b2cd5e53f32e9e3f69a896bfc3489408f\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[239]\naad = 436f756e742d323339\nct = 828fc85f305e3e63442ea0b178d182b53055c4ad909be23ed57603d9572f8c146e17648a3a4787c120daa8feed\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[240]\naad = 436f756e742d323430\nct = b0bbbc30e91367092697057b87e49a0278d6783e7100e58052aae3d6e43d86acf15aa52826bc29b0e1a3b22790\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[241]\naad = 436f756e742d323431\nct = 2dd238f23bf4c01ec65d5a5852358a6179783673414daa0007ac448744072057ca090203229d79ad6fa7676219\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[242]\naad = 436f756e742d323432\nct = 1f086bb895f86ebca24d03d530e085e64e99194e4c4b741d80a8ecfda0a93c791b84b9c5df8fb054573bb3cd55\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[243]\naad = 436f756e742d323433\nct = 530bca4e6045806f7cbc7f47ccbfbaab6fb78470f1d722f039f37f9ce03dd0f7c466f0288cdd70bd76e57298ee\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[244]\naad = 436f756e742d323434\nct = 32d031fe93733f5494d4bf4cdf2f331e477e993daa98fea19601255e768848fac11410026b796e10b106ae8e80\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[245]\naad = 436f756e742d323435\nct = 0dfb7b313aea0e91dcd2ba7595ee587ec910e6c669f2518355538dd4be47e137873db3c9b34b2ac95ac3f7278b\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[246]\naad = 436f756e742d323436\nct = e602015ac66b00e8b34b1091368b4e1f3eb1d94277d6dcf11829a8cf3a71a554e6e2df953c916f278aafcc072c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[247]\naad = 436f756e742d323437\nct = 9dc47953aae535a27441e77b6eee0db9a884f69c6c3ba1e6ef046d04cad1b4028c34ae259900853f104e6d5edb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[248]\naad = 436f756e742d323438\nct = 1b174d49afa1ed54c34a0d23921d4426b72133b094e5876c9f5089a20bd01ee740b9bf9623d35079b2a7f764ea\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[249]\naad = 436f756e742d323439\nct = e9a9a9a54a5909f74cbaa86707b6a3db088f2a4458d3075be9d50795284abf0912ac094a17e8228011fe8584e5\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[250]\naad = 436f756e742d323530\nct = 5c21e68187f15c7d68c30c1d515567a6bb812f79646c97122de81e2f4603487f2398622ad573ec22d6c8d07b9c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[251]\naad = 436f756e742d323531\nct = 5ebbb4ce70e2e65fd6efc03cf6fda8892321740fec30ea21fd742dbc1b53f531f58697dced5c6b1623bf659feb\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[252]\naad = 436f756e742d323532\nct = 0d4a1a33581ef910547ec8bde264a46441bcde2e06050b780d887bebc13f7853ab8b264fe4633cee8c4caed106\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[253]\naad = 436f756e742d323533\nct = 4e89d3f7b4f86e71601eb768ac42df8afeb983c18397fd4f277e3d1caa631d66960f923798e4b0fcd78c1ccb3c\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[254]\naad = 436f756e742d323534\nct = b640e286eef2d6078f8d5a3e801a2466042121f5f001f8ac8f3461cc261c9f772904b9c15cead99bf305063f29\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[255]\naad = 436f756e742d323535\nct = 652e597ba20f3d9241cda61f33937298b1169e6adf72974bbe454297502eb4be132e1c5064702fc165c2ddbde8\npt = 4265617574792069732074727574682c20747275746820626561757479\n# encryptions[256]\naad = 436f756e742d323536\nct = 3be14e8b3bbd1028cf2b7d0a691dbbeff71321e7dec92d3c2cfb30a0994ab246af76168480285a60037b4ba13a\npt = 4265617574792069732074727574682c20747275746820626561757479\n# exports[0]\nexporter_context = \nL = 32\nexported_value = 070cffafd89b67b7f0eeb800235303a223e6ff9d1e774dce8eac585c8688c872\n# exports[1]\nexporter_context = 00\nL = 32\nexported_value = 2852e728568d40ddb0edde284d36a4359c56558bb2fb8837cd3d92e46a3a14a8\n# exports[2]\nexporter_context = 54657374436f6e74657874\nL = 32\nexported_value = 1df39dc5dd60edcbf5f9ae804e15ada66e885b28ed7929116f768369a3f950ee\n", }; -static const size_t kLen50 = 982; +static const size_t kLen60 = 1436670; -static const char *kData50[] = { +static const char *kData60[] = { + "Input:\nSHA3-256: a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a\nSHA3-512: a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26\nSHAKE-128: 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32def58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c922a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b1de33fd75081f592305f2e4526edc09631b10958f464d889f31ba010250fda7f1368ec2967fc84ef2ae9aff268e0b1700affc6820b523a3d917135f2dff2ee06bfe72b3124721d4a26c04e53a75e30e73a7a9c4a95d91c55d495e9f51dd0b5e9d83c6d5e8ce803aa62b8d654db53d09b8dcff273cdfeb573fad8bcd45578bec2e770d01efde86e721a3f7c6cce275dabe6e2143f1af18da7efddc4c7b70b5e345db93cc936bea323491ccb38a388f546a9ff00dd4e1300b9b2153d2041d205b443e41b45a653f2a5c4492c1add544512dda2529833462b71a41a45be97290b6f\nSHAKE-256: 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a\n\nInput: 33\nSHA3-256: 1bf0b26eb2090599dd68cbb42c86a674cb07ab7adc103ad3ccdf521bb79056b9\nSHA3-512: 73fb266a903f956a9034d52c2d2793c37fddc32077898f5d871173da1d646fb80bbc21a0522390b75d3bcc88bd78960bdb73be323ad5fc5b3a16089992957d3a\nSHAKE-128: 0a7fddc22e37eaf05b744459f6129fd1c97cb501aaf497ecb6d5d9b1cfadcbf5c16f4e2ca3f6f0d5e02a0a73d266d2ae0541395f5094b7bd6ee75e9610a5609a88991ebf24555644d9e62ad7284dffa9ca9d6f9e913c4024131bb401c795c7a241da8db9eb403185e29d0639c0c09b46a27cf06f886485cfc2019a930840cbdb48cf9bd8f53e5aa349487a79b904cd18b2721dc1b31a31ab5443e2aa7c02a1dfc8fb439c0838e68753218d2d1eaf4cc1af4ec3e42339612a7dffe12be85affd9f167cddafe96b921a9d50382f6cc91ebb843508ba58910e2cd4352fea695b874ed9bb2d207f2ee33e938566492ade9edca7993a09633f248465b6f9a80984284f6f898406deaa74c83dfeeb99e268f372748bc3ff1953974c81a4a804e06baf8b705b6d93b01721713af41c852daf16a935cc4f0767b77c9c28ce1296c2da0ef5e285b0fb38819183428bc702b26b0ae0030df070e49acc40438baa50888a14f54a8a13f7f6bcd3ff14544afe61ddcbeaf118681a7b43c965f969c04deb4d8e860f083d8659a62e1155e21d114dd7741aaeeb8b781bc7f95256c7f1915e29670082ae9a59825d21fd26e06ac8f3e4f60b1dbd8cd59ff196291412cde99f4efe383f32f235010be4109c8aaa2dce3086ad4562a8bbbeb26de4f6056a801991e10580860f193d3c07eb3920599cce1aa162a3000a18c13379ef90590d6e0260799\nSHAKE-256: 08946cd494a2c00b0e9321af0c225309e9d1b9d14ce8eeb4ed5182031c3f29b0708cd8a24edee1ceaf383c20bf625dcdbce94504416cead3bcdb65572207b36678097a1f5c88491efa2392f470046290da06ee5370964dbfc80f1aeb4881d5611dd6c87d28e151749402027148d428407db197af35fe83b42190689455acb39c9fa8fc9e361ea33a264ecd92b82e7c991eb2de0bb583ad92b3670733e5005200b64afa3fe8f49f44262b349a9be799f949736846f90cb7fafccba6ab1e2b29f6bdf885e7772aea1ca6a2c971c9c8b464fc17a06f44c916c56597d92e3882f82661fbef6f046b737d51a3801aa074ad1f2b67c16ae2f629cd542b9da8b27699a1fddd0f4d239ec93e74e7491802e5a7f4f271c85ff95722f665131f84de26e9f63a3d7abdbf284e9e644559fbb76017c6b136f907eb3155b18bd42f8cf49899660098738b85ae2d259da369030a22256eec14a9f68f74a20927753679dcd296bc28227e380271b56a9b8d799ad6d344c76e40ce174e457e44d74b878159b43b3654fc6c464f25ec6590e4da4f5a6f191c066ddf4d9e93c215c10fc83082e71e6c1f4e5bdf466aba05328d68943cd1f1a6643302457cffdbe168ed1af88cbb0b762d048f8bfb31bd788d8db02ba68e544ba6d2cf587bcff7f28e44c0812123d4ad62747f9c024559f5c120741fc5032f101241a55662b225d9098f5d92e9853f0b\n\nInput: ffe6\nSHA3-256: ad581974ff7b0df546160c70c4386752ce54299e543b3ac95b0f3062a2aefa75\nSHA3-512: 0920fe4bcad9346fed8ed00e5e03f7e6366f725ea35b60459b5f59e09765571950e2903ea88613f481c7170a3a172ee2541433842ed25a1b9d19c662990dd251\nSHAKE-128: 918511e7f7475a759bfee28d0d39ba918ad101233993b382ff4c0b85ce90161712776a52f57e1fc8374fe677cdca50c56a80f30d47389ab4f1c95bfef80ccbf916bb12b9e02a2ac68dc10f834018822522468a5f88accbc6e5a99dc775853643acab45347c91ea650c13a72755dcbe08b916eef30499e1744cc0257a15ac6691c7b02fdf29c94b8f5a9a49d2381bd95b168a840a3c262b9ab0d455ce576b111e326473c3f2b51aadd589eb2c44195f99bca88e49d9f4c8c133072c1a3f615d13d6d0a4dd4d56511630540af1bd86c0ccb65eeb88e81b15904650b9a1e4c4c9849d7b78dbf006241ab334be7fc5172de1341001cd4138933551f87db3264c2c41e1977cc03be143541440fff9d778bf673d70eb9b383be3fb8b01559ef9343291180fe0585533db847217ab28be3559da19b5ddfd85e9898601458851ebc950532521bf03c97298e192caa657d2f60ef8676607f6a9baf5b30126d755f2058742daed9100d303060dca8a9ca4fb44066b6cbd14fd3280f4060bd2282b510ccf59f51202e8e5f635fb4609ab1ebf3b46a6c3791650a74386e62228f755eced0301bce93aea26d5dadfab9648a3989a9f058b4798570fce8709b3340f958fa348e2366cc011edcbc0e37188853c7caa34ce2d51129541cc9ae3eb9e8bb3cfcffc052078c3dcae11f68aa69b9eb52794faad71d2ccf97d1b45aa8156ef2005d98187\nSHAKE-256: a08da3fb5cfb640b24137e3d2835379a5ceae0635591c74228e524cdb7da37e56b70f040cde146699805b8bbafc4f20cf3f54d21ba5a19cf76613c343449747a22952efcd12aab67defbb2182a5cfd6cf4a1ce4a1e8ab0225191b72515142d70b2a2d5f351a2cdc23e68655ad6ae981a5c9f01634d6e438477eec4b9b0a69f7da98afea221fcfdd8f7bac47c0ebe6a510802332bffebead87a4ea4d842fe86be1216c14658645a097876dfee6eb9c1aa3b02809cd3de3abffb2611e8ad7f0df783c458ac02a52b493df113edd9f4a6a42a15135eaa6574e4a85d295edc2409fbdc4f97550290660cb49c23840327c22b0109fbb1b317845b19b6362d90348c05d3cc94da54cb0833a29ec71696f20a6aa6f9b0d7dba50508485b81c4c68e1bc2d6f30e6afb243ccff3664e4aad130aec4b4792d94f9899a581acd0fd1f52d949b0ec555e19c2bbed480178684c8ee196a87d475c41acd0d68e05d0d3cadbc9fd7e48ea14f506a0f6819944d75875eaf8b1f2cdb4f0d995ae33fdc159ca298be2e147ce3f5370a2d9636b5700c7296ce5bff266b1ce897cbeba4fb7980200bfcee8dd7eae98328fee41656e4a3cf6d675d4f3193707bedcbe74bd2f50805f715b04453b1ab38baba5b371c46c2c4b6eee5fd07504b8c6b1c156a62aa66903abd65261a810f34dfcbeb316178c947b2801445cccfcd4d91e3b710d56894396518d\n\nInput: 11a654\nSHA3-256: cadf843ed7a78e23f2efe6ebfc781f9b5580bd73689746c3f0f0156a1a6e1755\nSHA3-512: f3790f001ff50078300d72db9eb86412a85f86ee474854c83b7a4ebd10bc51fa461ad8e1797e9c2047657d35b94925f408fcd30662e82450ebcb2952c5309174\nSHAKE-128: 5e8c78ab6668b98083e2ddf60ca1fa9201060ea0c5ab8ea7d7e983c0f4e8f0eb39cedb030a177978758c4f0c505f5a47ddcb4e1760b9e438814e367c4ee0ba8334009dc211d92cac3d9dc96f4e1165dfd72c46c1d8072e02b02ad0be8fc35f74cd0a8d11b4341fcad8bbc30a6e7a4ca970f834f9d4270bd322906e71a4710b0c1b830f238e735db61ae7685811027b640639c168200da500b0d0ed083fc1335136b438c8774cb2799e368e5f3a45dfb25c6e9f48cc29529211a127838252ffd9d11b2431dc4571daf2f5447439fab6f11a061f5bf8c1406c11373b9cfcb6ba0b9cea8744d50dade323500951cd27acc03210ab1c394bc5872501c57a7c11e2f9421c8f4a2b5b11484276c08f85bb09445598e2749425450be45fd27f30a39922f7ad8af5edda3535b829ea0a194c1c29922d72cc1851aa7494324205cd165d23cc073dcc31b0f4cb55c034d9d792048ea3a063a84a6cedcd277aeb5c364b8356582b5f1497f32b06f3b19e13debf321fc04be12c0983c49824f919ebfc0d73d2ae723ba57023f0eaa737630d2f2bb917d1c4eb880a87609e2449998231a75dfd5ffee2fc9e60991d476d0bb47552d8706a8c0a09483b32805a455e18b1fe32fc29f084add155eac67b0a0fe9667f80da3aafddc0edbb84c6519c7bc1ed6d10b6cb3e6dfed6a4a818a31955449395ae4fc83bab0d53607c138508391c52b67b12\nSHAKE-256: 1f85405fa99fae5332e040268ea", + "598580218bdaf799cec847159b9cac0b0a7dec3c71d5a2da14c10794b8c9948fc20af66fefcbe038b4f7ec71451948ff393854f80d28642ceb1535220e091d862e821c9b4e4bda6c6c8355672a4bc01b5e87b81a17f14d460207bdeebd6af4fd9ce66caa0245fbb414e3454d83dc22ecbc8efb3d5547f21835cb42c507442fc852a50a10ed7b791a8297036d4204d226957beca62cc461b297c620baabee036c715f0f0756c85c22a372a08c1479c801532c86d85836362b9ccd03754dd9f060b471a01102cf69488bb893beca104063db22fd60a9bef63fa847b10a14e1e9c9ad83224e3eb33a5573fa1f68dba8fb0a10707263439b2fd84c9bd69798aaf208eac2bf2d7f82ff2df47f9aed97ba94f7efc18b5eff9c1e891a78c6b42d9f7dbd5c9ef409cc25af7dc2d354343136741857321d5fb92cc6f52edd0ce6a7257adca5b88167e2021cf837d1d4461e5d6156658b8884ae87fad04ff7905f89720947ece55912b1633203ce874694a29a21bd29678d1d13c70240e5476ae103bead724f65e734f9bd9e23175ae4432968424d52ec95b75593703964a665106ad1dfd25eb5f47441303cb1f882e229024a73c93642a9acac84026d2c28ee861659584cc4342c31224b6b2ab006a3e021e25b1cda9bdac6445f8ba77bf1bfe0363ce6fe5fc8eee4558c221aa290a8dc3735d80500f2e\n\nInput: 9fc87b9c\nSHA3-256: d6bc044f3c040762bfd6714b272aa6b0f592f6f5a8438418807f66def7f8667c\nSHA3-512: f7e9e5f13338d81148e5b38856e23c3de659e149cf2563dbfb862835994a553741845e03c39b2b2042a95edb7e8e03c773496cc86c489918fe43bc37605e791d\nSHAKE-128: 0cadb697b8cc098f18bb95bda4bda04d8c73c26ad25c1373d348d663cf7d162eaaff6515990c7251a7fd21d2ad82d5c45ab5c8d0fa876910216c8da909328aa2b30ad73c49a5c3a88c5a24a5b521b27b112e9d5dfa2f476e88804e27756078a98f1cb22568b3a3dc76f42602814d2ff363c932d000fd5625f160d5eb38570df81674f19b2cb0e04a88f92ed559d0bb439f2e1eaaa6650e70eb234f00426e580e0e8de5bc5aaa6e54729354e95775b39445f54462cbf4dc35b2a2d0421ad1f17a9b02bb6c11bd4745a8c2511aff4027b12eef7da3924e266b3566efc2de97d47d88f6381d3b8c0d93535d2ee5972e2d508227ea9e443bf74f088c4d8d7ea13cef854e28e50ec712287bef78721e18eca806379dd09a743ae9656df5e844af9eb58fde125c33d3fcc07e54a761fd784c62e9557a8b60111773616d2342f35bc1c9c2327630c438431daf46e233fcb0a4e88e553b1d36c8363b3c833b055a3573778a0731fa9ee54ba3a19acb76efbbba062f9aee539a3db1753ade94368fa9197b52bbd61abd01fab0841a43129034bcc56d1152191cb28afdbc44ee62a17bbbd55216348d33ac6de7880c63be0430ec181d4972cb23685b734f409fefc6b9496501cf5b783412ffdb10d481f9b7865f49b56616fe22c69976315fb1368184e375b8debb8ddbe55d9df717d62c564e167ba6d06b9f010a0c07d172b3b2147621c2\nSHAKE-256: 8248a3121c02a23f36df9e1c64b2844e57b5b5fba28b2c35d2f33045be874badce70360c1752a27a6d895e48e8003f60f12c2aa68d2ce53e2ba900e190c13f158c17fe3a292efce04cc82627f4bd8d48f61fea209c42cdc88e1b6caf114a3272b471a9dbd1a58546da3d85f33fe9ac53312ff5c7bfd02c79e2914ca0f781efaa2459955b0535eed461cfc62347afc2f0e223f59a21c1861da0eb3ac39af381c8b6f18d40c366b23f0172066c3c5737078d0cb87fb4982deb3054e4671556b5c172c892cd8845fe9d1e15f2b88668a532aeff5c777d89cccfe2a1f3aced536cfed22cf840fc77f918e9b431ae7430e371cc5e73ddf0faf86c3dcdfebc80a42eb7d044a4c6b12d02a4baf46d67f7b5aa6670525e673231c245e7e3804679c5f9be3db4dfca93942d54c124436be80f0165938adc339657b23f0f6e0dba9de2d07bda3ca8195282c183b8bd250963f59b62b53676a85098b39e8bae576567f14835ee125ee1efd0d136707ec5c3c28db9539e6a1244c581784e39dcd7638e548c55dbadb980b41cc18ab053c32bca5e00de8b5eb5a8e4c17a896a894ab195958e2fde195153b7db73bae4d42a0780b9924786769f1be6e2b1d8ebb3b3429257251e373a351f651e7a06f6601557216c2f0d8c9d5af81aedcc7cd4157de5a572ba7a66aab87dc1f58d4340f5fc8c285e58ad6053f334313e9e7a85bd631dfea7473c\n\nInput: 7c518d2209\nSHA3-256: 71398643fc90d0a8deaaa35af60e66db8ce8a26dfe29127c28b2a863cf0a6055\nSHA3-512: bda63ca97373b6552963805f07480e31879773ff7f242c14ee893f908970ab66724c21574d856e30e66eb6c58e5466a95c2c5985fd5a9689641f987f48361ef7\nSHAKE-128: 41b0c62b7b258ed91fd9859b087145baae04fab0d3d8fc646f6d678cf7ab1de223908737bae96b44c8d293c87ed14c48e4e053cf135e55d4d46db250594ba9ca69fe7ab013cd51be3cf94099e7f68409eea430193f4068047ad8d4e7864959f62a402d56deff2471e5a271ece7c426785f6e8b69e8818d571c1c7a5a642db1e88daae203943f956caa6579fc0efdd8e53d53ef78c455b153809d510152a79b5e29e402a2795fd662694ef1eebd3b3ad4b153275a5556b5cbcc7811277b9ab940eaa1357b721e6eda70bec722ba3951388a9b153f07221c72297352c514d02879a598358b79facfcbc8f62c4bb95aec328eb504dd98f1081dd2179528290909548bd277da6f595195324b63022ddab667ae1e371097d973998a008a6a170a9ea733e4822194ca02ee964827691533215ca1892357cef581edd330e666fadce00c543f0e1fb1022664132d5b7ea5f10ee7c3784999d32a1aac9853324a1bb52aad18ddd49856462978037744d6468bfec992d66bd27055ed8b5043bee51bb3a1271bb7478d31cf3c0d61ef56fa50153f75aae6807d4b73b1d3d23e639e6d538a6b9b22daa4bc1f297eed37c7de4a597cdb3f2ee437e42e9aca0298e3f78f2e79d7324b8d1a5d642d98bd223bfffa8244c930bd2b5e945e4e3ff5e1620586f201f343c1c1f3329ff5addc2d3e10bc4fbd83e0bddbc98bf8feab260e94c56273d9bb\nSHAKE-256: 7d891923450f519128d72794d8fb529f50868ceaf17b160e311b173ce72d1b05617c374c2373d40499d27b724707931553eb945f3e5c60689c0e18a1623477ca48652b59b7fb8a13b3c8fafc4cbb95243370380c475c5b4ab88a780ccb137ed02111917b50915bcf68dc702d86403659fbbae0448a18651a34b85b49ca02e3752e0cdb0c256d8507d072548119742540e983ad4551be9ec158ecf1787a20c54af359df4e04e12e9cdfc33d43286203f361725fff83af5727e4a8d4a566664a4efc77a39ff6d3ee9bd3b99d8066dae0be2789682d9d161fe89c78b48b83ca174c1daa291d54f715d8ee7a34917cf4438b707495eb358b76fffe91dd3cbaa2c16121cb0a9031ac55476ac75b30220adfa913d5aaf3a827744f7faa99643bbf854eb69b21257e17d42c692fdb87fe1657789886db2383d6a3474c882b619dc94ac203f851436ba1d46b765fffba01e5cd8946ccf2cbaa8241f7ef6a550e71b79a94dabb6b5d3d92accefc4d6553f81bed9a226bffca001ce246ba5bdbd1c41fa663f6ee72252700b0d9758211be5bf1846b875692b304d507879de451a21ecd2b3cb20185a6b278f2b5bbfd6444712cf3dc295c70638a04f3ab6190e815551d1e58d83a6e35bf3fed2520ec98ba4a7fbdfaf0eaa2c3da6d9df83234f8999458d4f153e236cc586b249debc27302a8e9a16861ce2304562483036d0d4a8c58285a28\n\nInput: 8227c838da3e\nSHA3-256: d88ae623fcac9fe12649827898db33731ab7bf20b9934888ef9bea3bb5d9c27f\nSHA3-512: 305d3788da885cc771a52af3ed3929f03645ee11ffd275eed8d375004ab8073eec30feae99dde05454de1dc3748935359de710463e38f2565bfa5854779fb7b0\nSHAKE-128: 3c3a2163bca02a9b2b928c8c178013a16c019f7ac840e075029656c9e2bea08737735113f7171cf416a4f9768e1fee7b1b6d0906157709cb6eb17d93559e39ba33f09bfc8439cb7851ac89cdbdc69d984389783342e1d5b474480786dff485607d0c941c52f52e8988d95f3402dc6ac4e72755221ae06b5301e373d3c8bf58209fa710a53fc2627d7cd62e12eff1acf71aaf6ceba466aede52997bfe8f232635088975391d1a58cfb8944cb8606ddcc8be054cdc3a42b9303e4ad69d8098b78bf3216ea57062590a826326b87eb5962d0923acd72fd4585d0eca49fa8b9fbcee97dac0ae988fe28de40ff670cbfc888cede4b666d89ee0b791a2fb75a01971867c139c85ed68e0f7ffbd3e990439bb335c01eb9ef28d6e8d11f0f7f04246bfd40590026e7f9dfe0c7f2ac3ec288f9afbd0aeb7b36b3544e27e591daaf643f04e6d4983286444c948b6ebffd7646cc0f17537339a8e71e7ebe7c181ca9ea36055dcc82e9e54e614d04b980887b4323a28afb2952e0c51e2b2b6c9d08cdf41c39b57b1c3a62177efeb524e9487279b5760efcf2046588b549faddcde9162892421f02a15b59375750197b839b897a6559d29d786db5ee5ed4c698a1b70b8e25304ae5c0162b7a4adb5c23771df1e719230b7bef8292753dfa0b2712447fb070075a77e889a6e49bdaa59f2495ead0d5792b8240f8c968223f49e0041c66305b9bc\nSHAKE-256: 4221abaa92641871e69e5da3f2df48f8780e29577f03465caa2c4f3438ba170326bd57e1a3ac429710eb6eed5ad425cfd14c10b87ecdfd80b3dc059dfa00547ac4a377d2d3c1b8488c0ca438c88f00b9899002229c809c29aa61d3d7a42c777c53b31fbffc1184481e555645b6fc92a1755c30af25a206b13529606931eda8d96cf34de3e1341aa68fda7238455e5e999db5f5d9ccb2a02058ccdcd2426a3808d57c7f2da74c579738dc9f4b30dc70be4018cf8eed1680fb9b02f11b1d943afd7fd9d2b14093c5c661bee9735bcd33588f6656d6a2db3673ada616ff6c75906c23606947cd984d6fdba218a59bfe0976cc6e142beafef8af7b8e4c377182b4e930a279cf02060bb5af95eefb3296a259952a7fcfa9a6a27a4a97b1509d7598f464e63a13c3658e33d193af77dc98f96cda99a7e22c82f555e58d479ccff946471aeb7af02a18106ea665cc1b7922498087133d6c28ae1f4b8425a70a645bf755b6dd0392e0d66048ae43f5ba3f7c487732250f1ea4fb7ff7b52e780ae400699d4f9a0b0d90f58e2371e497639cec5138fae155aef6d16002e52699b7ac188905ddf094bb3519cc658466782c6a54cdb53e7faf003de015dffa7d822068bbd19119a294c1653f1a30d03046d9d9975c607c00e842c9683882d93b0799cdc45985bf4e05e23e86b3f7b1d23095dbb44108ff23aebde09995f142a22d703ef5d899\n\nInput: 4f662296b11190\nSHA3-256: 71d13f441503986a93836b2382cca09dc5fd79243163b8cc546fae1f0e7a2b49\nSHA3-512: 8db9bdab35e5c755ed9d269b6c8785ecd15bb6d6175453111d34bc27326ed07d4fcf28b28f18d5b0f50197f5a9c243014527dd40bd5bf9a19629e65899e9ad1e\nSHAKE-128: 1334c0fde66ad64a381e7b7f4654be7", + "57680d78814d751f1e444c2a3c9141ef6ff5b29e61c07f2a206d904bd67cd2637a7f6f475dd83434709939b8c6e5c94814a29eaa1eca4af7abaad9249f7afc06954b098cfbb3f8e87acf500e89a27e1db6221c51af783b2ade8a979ad093bfb6c75615f15c0db4a5de178a82eed2e4a289a3b5042246ed9deb55a84ea54a8ead119a8ee6ab3e5b350e7a2321bd4d5ad7a3858fbad294b1aabaa384e238f273399981ec6794d2db723111653800ba3f2b5e1bf3715b76e740066f0fd5c6bbb4f64c20ecc7e74716e296c81668cc47b6b5f3020f4475a4f9a669c9e279170b2bac0ffaf987d9929c3d7b2ed39c79c95479b12d77c27479951e299350f7ba9c0262a14bbe42ee4da408ef0abdeb129f4d59404cd290e32084f8827d05116165c685af9057c1eef166163f40b6f6b1edd4d8042b87d1e8b374a67d187a1b624caf1e883875e58d6acbe03c5b7a9afb7f01908eee831f7cf9dbebfea4846db2a7af020399cb2f199122e55c151ebfe1fbdfefc657a9ec5ac155ac52cb13df096c46e60ec12557dfd8fd74615073b9e436626f22a3b5b8247f0b7a8672bdd86cdf7e0fc4fa7e018a734f3dfa71b09c3e7702b4e942f5bdfe051f9fd90a7940df05ed388a53bdf68a5467eb03e373b76754903f0d33df84c51e71ee6d0eb46809d4a6afc2a84e7f3513593f23dd908073611fc6e\nSHAKE-256: 30be161d2a53a1726311cc87056eaa95051d545bbae46d537b8f7e31feb04ef9baca4a94c46ae583d5ddf2b6c0ca4894df1ca1d529280e4347e426681dbf2a323a0d46357c3cdb5c384dd72a794966cd29a9d7cb71c4141d9042fdf40ba7c594e9700004e7066a9eeec6642b79f6259e8e60f259b10ce2c7425ae8a862b2832278602cda8c9523ad2ab92d837ea2c8355e1758c6a1bd4979170befc8496d122683e7d2f818e119a561f1320dba7c5edfdaf3fc18205c568f0037a454b8b0fa9ffce0b3c597c8349d9b596a9846c43f4dae226dea0190d2ed8816a12a07f07c24a6f893cdf90cf23926b2ad9d6d2e8f5c71d248bc07ffd5c8437fb2524667f42166c7bcb5a18dace4aef5c6a0e7b6586d1609c102c3932662c884549c5af31c06e27d98674df45ce58e242bb580f522a594a9b1027e0d7b7f2696b8e666fa3ee1ca94cc449da57ea3a373edf7db4e508e66407a47ae0e778f9a90747673b6cd0bc8c187c26c2a777e6fb98a24717e7bfe12729245b1d16fd555f5228fb8710b04f3d70f8ef95885efc2ec997351533a5915634e7b975be56a689d8ef1385781407c5d8c250c676a0129d5073098e9f6b8f1676dc51b6c6799eecf9df58c69c44e062696ce992e78c00fd541f114101be231262d154130e3bf98b9509c59b50ac9c40f8b608eaeba7c8d7334613f58cf59957622478bd4d2c0c5fb796d5fd83d02\n\nInput: fae2503b2539e4ef\nSHA3-256: accfa4d9e87975dc9484f59c4f74c2d6ddb85c6eef7be26c00deb5f6c0387b75\nSHA3-512: 126643570019138a7c9a74ca9696dab0ba7aad00a988df4b0c281ae5ab318c19ceb0a7260c764d3268c81ffb655d84771051f086e3e785d1f53452011af0e357\nSHAKE-128: 130212b6ef03ddf21acc384a8bc12ccf9e75acac27610eaff19ff0195cf6ce1bb9695fc2475e88d7639abe222b85fbcfc7e744934a34057956934b1e5751431313df7b255e816504df399a345bf87a49be2059dd6223a51d38745d7c9875d4fd1c3528121f8a0544fdd00f04f81ddb7d243db21c6093f471a77390882bad02021b497e7214aaf38e962ad58b20d3c24165951e44c3080148419f96eaea7e890ffe1760b4655af6c05aef3b619ea3c9e8ded69e65f95e3b5776335064bee0120c8190e98973a084326cab4bca1ace3789729ab97421c894934d0821277ef6a868e1ba590e0b0c15f838b0494b7cb5c9b1002bb93664e37321a1ce6d549895160084f7a3bbc8a46374abd4f2a7ba75c055130f0d4a403c91449e6bb3e022ea35ef6b97df54963938b2394b50954237d8b93a5153a919b7de8e731f197c9f8532c26ce238660bcdebbd9021473e31761afe37f7f3e4de3a039300ff197ebe31c8d52390f56dab1a3b54783397920f883b2cd6e0a9955dd7d75ec0e59b92e914e283af0306490cb5c137ee7c3bb35b0cad5324a7674a6ab025cf2ab4bee85564454a0ac3777c135eb9ca537cc84194db103395fb20730c981706183d40fc3235f59953ffdcac579bd42ccf590fa1c9ced5a425ca1cfe9eade0575d37f2c4a1a7aca781847f9e76692bbc7e0b9c4f1939689c50c64a3fb176306cd11647a5a7fd5020\nSHAKE-256: fc41fc848ad550fc33f77b678dea5ca0965f0e59f8cbb77d3d8dfa1ba113b50495034dda20436eb00c26f403a2d087ab170142316dfc89484c7a43d8b68779da248fcf1402a69005154d0ca3deac843ee2c3d6eccd14739a61b6eb031805c4d7e37f0282711f0ffa5d59a924493e57bb1573821e88b32f0078e4dcc2117f887425cf5684326a2b331927c3a1925cbe615238cff89c299a83d9c17fff0dd11d12dd50711562ef5e08b03d131e1d920acbea6658446f1aafdc774dc4caf8e5d9176ece53d5c09b93b9e3ea344d5b6ac593e734619c30126ce237c904285ace9f17244053cbe2017e3a79f4778f46168fb7d05f46d103c0d6358220337e1e3077e15b474a07a17f6a75855edd410623f6af4dadfc6b5c336c1e45c0acebe61b95ca42227e09d8768bb78f0f1ff7ab2803a7e25c8876dbbc6c45300a861e27c0093bd0a83e2d494615ccf5958f3c68d8f97d35438c9adbf873048c61c6d183ec0cccce2301d7cc1a17c245373cd6bc177e1557534e3b55e85c3e925c7608cebf4d06f4525ee5aaa20fa628b0e3338188efca66969131efd7577d88fe9715ffb019edaae83ce7702dc81c68a7bab54c2c147838feece6c2991bbcd7f718d96aa1b180a16984cb1d71cf48c0c635ce4b386679922d0c0846a846d1fb66b99b36b1a6a0a60b7ae87b73f4a7f4e2ab28f1f691c6a255ef336bede975946ff510a73ed943\n\nInput: 36ec9190843bde0cfd\nSHA3-256: 5510a8c5cc5fe00fa20382d78cf48bb194493bf1bb82e2e836b4e4546ce1edac\nSHA3-512: 10eb990bdc39846694a126c3383a4564b197adbbb84feff1ec53af2feefde24292ef84882647929915b9f50c52cae0c9a1b076f2901a494a099855603efc3bfe\nSHAKE-128: 8d84aba1072f69c1752ad15123726fc207cace0bcb454d227651b5d6165f784fabbd96b13ce202e0fb923959f378d8af2c1c27f4d7c7742550c4cf9a23df86fe04198ad88520597fe86fab4e60487eaa2aff8effd2c801bd5cb13d9796ba81dab607f129676c196c9fe9f9a1c5a933403d175b21cd5c72ccb9d50f5f26d6c590bd12254e4764da7d8031cde0f93d5fb63e311a7c846ff0a414ae38e92422caa96887cad74261eb0bcd2bc678d5fb78d8ac017b7932ba2d7cc57cf44e688ab4a34b17cfc3bea1f0820b8664c98061ad49e75319c5107ff8c68288495744994a84593ae974fffeaa532f1811d75a374480b7337cb099c232846a24525b4ecbd7e0dff2912371e0ef413af74b9586dd0f091087c7ebb17e9e5e910f79f619881f171763456b006032b86ecf8795289814d3380457daaff22c2507298ccb05c8312459a78130aab1fd476bf6e39470178b5055578f0042b2b0f70590abfefd191ddce4fc99976606080bf0326601b5ecb0555d59d670ddaa248893e5a628070e791102e3c6abca0a60b4f0735a51ee7b9df1fc6e0033074cdaaf2399e8939a8265440a340b0868de27131e3128e8344c19cbd580fdba781f30b916750809dd43d4418c5bfb179908d10d7530eb77a1c844d4b7de0adba12bbafc93593ef64940a923b9a440f26ebf43a1cdcb91b5f75445463f62f8db4b6a0691e93ec719c80aadb6\nSHAKE-256: 8a7d7a8367ed699ee74fd1ac4d1950cefec733e02c3d3bc90a11fcc0fed37db4c1ff92b28cdbaeaa4db1155320b88ab64a3e4b741014dbf3a820fe5488f2639d49c209952e9d6952174c5ac2a2df0204e8686912be4b5c50c5ca1cdb3b6a1116738882c749a5eec78a758ed113d32a9124e29ca0b6450069fc1a9c5ace62350bb3902926060b3e3742b837b9fb944a0961816543a5abb880c9b0a3203f02c1c09a5f5db5ded3989df4b4834c6e188de5361b8d2d16a4816518a654a6a85665bcc7ed1ab3c5fddba195ce7c39ac58168b1f3e9bc9886ae269e1edd6a2391cf2babcd755947544092432957c6956381d7d854da1a1be589415fb1a5d7970a620a6849831c6ccf1c86e8dc5082a0d6f8573c2bfb54ea5418af5048c573dae47eeb9103075198d17a36f418c3d605ff078ef85539c1898f46e1982e2a880f2d0c7760becbb54c231436a1a50983bfb3b7bc2223a0df901469576bd7bbeb2f318ef5575e230863928fffebe1c37b83cc861c5aef03bf1ac2f1ce03ee0a0e29c4bf20bc51a623247b0633e950b62d52119c9e52c0911d5974fc462a8f8b35eef65e623bc87354e16e1b67cd32e8e7743db45a8ce00cfb227e2eba8718847627e4d1d614a51b7ef205a3f40a5b5bee5e0f0427482abdc8a10c121617d2d3a94e2f2701347058724b5efe28dd320b1cf098d5f20b8716acebc186016c2731f21da4487aa\n\nInput: 11c1adb3bbf568e78273\nSHA3-256: a08841f8bcff9b3b1fd889a949ea20bbe48b13e4c770ce18e544ce3dc6ba21dd\nSHA3-512: 345a95b8628db509e6fa8657db263c5d6313dd034ac42fcb2b7a7401df8843e0b7028c10aa39360fc92ef47ed2c8402c14a8135b8c70ae5b585418807fd9e895\nSHAKE-128: b8359b57c2229241fd25c3ffc8255250a117279b08f213fac689445d1f798e7fe3bac3c783c56679090b085031d97dd7417c0260d289d04fe74614d9e3eb5dec6b14e8ab314145de44a445ff0b8d60c25d03e9a426284c66151c7d03846e29ff07e0180c0696f121bb3d6f0d677abfdec59dff379b485151e6ed915e4edd0add374e741a0dd449a405c07782953e9928fe1121135c6edc3e23d42f98b5afffb9f3eb6b3265dfe7bc36be7162b9db1219391575d654ebc196e292b25872c44a87251d40a9e1a48ec9c520cbeb745cbe6d908545a112a3155dfbd12e556f2a636b8ff61e92f26145ed20904445891a8d9bebdd1425e58f0d2bad30137c3efd4454c54587093aaf5f5700deba8e7d7d1f90fa5b0204fa2e62dad742106a118021bfd4508f1476ec98c42b6747aa1a052f47cb1fb3890b70376cf9059069f0b5eb9227664bab422cd98904c4ee30d21c2432c198d9c5901ea605215e7ec3202d1587f0f09deb8adfc6b4fb7a65177aac0850e00ddeb258254da34759afab0fcb365dec73bc39c81e5ef32f5c9e8e017967df4958f9aa9dc592583b7614cc6431587f69c1ae749cae12111e2fd11cd92846e61fa0c1bba2402305ab6c56b088cb67569b6347f01e6b67e6f16c8bfd1fee595dd08eca56cfcf48182e22a0d51b1e7a6522c0497ca10b0e0a922dd0d312622657652de54d369f47e9088320b5ceb651ce\nSHAKE-256: ac206334849f388c40f75d118928a802dd2917c8bc6f477c075e600be4d102d1682c8ca2f66e2de01f64499432a1539e94be68a7e055ae4c31fd9dd9f7ce6c2455b10fa40c9f4b785540fae35507641335c01babd9f4ea3dd59eb1113325a8d8607aa53da35dcc0199a6f4d085c778d37991c8571a38733265e2af33", + "5f249d583aab3d6a9f84d60d6deaf1a0c35fec92d5d521cc791dca72c31d907dc3f7a41dbfd1abf96757d7ff791340dcbc45724d35271171f35d10dd4457546980cd101b274413c81c20075a7f9b7a70b821733c33b20ae2a3ad8755b8b0f3f4c0df9f804f58750d8309ecf751d4dc9eee69c610abcb3761dd28f5ef609c84ffa20f47bd5540dc7409b163c582f593d9b21c85ea30dd304bb500380c9346588ea91bbec0003b313908480db0fde4bc181df09373a7b4b7ad8053a9dbc908bd84dc5f44d518b1f47d6ceddd703dfb4356e6dcbf07a1a480604eea40ebd909796340759ccf4757237e98cb8fa33fe7ffdd31b7ad23ea773984fd297455267aa82a6ac5d34e00933ace84f02d1e5d97293f0f5ec2ab9e5d3b3efbc7cb4a984db7333ed3dbb200bdebc3a4fc09a3540913f1ddbbda354ee151cce1ec77c8a71d97a0ba960c844f6d161793d2ae2f58304d49f2c17f1daab6a76e163c921d7323beca1223053c853762b8c0f93ff6681f35442690b88687a235a0c2e46f4597f7796b97693fc7\n\nInput: 043f0c672734757d22899b\nSHA3-256: 309a1cbee401a477764f1c96f91540e22043ff9d74f6a89c760b2c68a19e86c1\nSHA3-512: 08100dc4126f7c1498b1b9b8e1ab03c4b93152c00cb451310a6be8dd4bd95d7b5249a56634fe37904ec014d2420379d609a1deca380a9d03685597dd24374eff\nSHAKE-128: f8278126ea82044f9d2057e2b5667d2dc110898bf65146159c11d29d636ff0d9c6bb47fcdba5076f7e9e501c007c27333714ab470a5de3445836995fb2040c9264bfe7efb041a2632f5943e064512364ff63e16f0fef097331fdebfaa84146a29488ff0cbe48ed6d77316b8efb9d3cbdde38f08772c925cbb064862b228927c8a2d86ee37db1450e85f841b55e6ab398ec25f4acf5969d6f487348e1a501cb51a1c31110193e5c555ca99245ea79ea882c7d2337b2014eb690e1fadba57d8be61920f7b6dc19498ec0a0519781cb50328100ba340488af7b810081bccce6a835b322a8d94c5e19f826d7955ab1faf4b21ebad46e91392f1954db6a25e3bbd2cd93f03a186d1e2f658886f508ec7a29fde9dfc83b562b16d97131b544e3551b2978d9b83cfa4debc1970c593b69ebb66efbd3d24f5e4355b3e2a64fc717b9ff033414c8da2675e751774fc39f1b38158326d91c53099c66d5b15d69b22ff68bf44858d00ed43d0d2142790ffc50ba5297c5f1216c44c7d5aed53cec685730771c6403dfdc1126be77676d91565877fcc40c1926217ed45383bc6ec956d108ee74f922f8809d248de7ea4ff35a022f94d9d59d3de13288137e1949f3cbf609af06a4e64e88bcd51c0c7f27cfaf8773bf7079bb803e0df0978a90743fa7c65fc1d9130b463e8f1cb32dafb4e1330b669ba34ebd7fe6eb40f1af2e379d8b18a91ce4\nSHAKE-256: b288b308fb32711a26c8e803ba7493ebbf1b74a9925232bfab56f40488658c1fcf5e331942ed380f5a7fee75993274fbbb09f806988af7ecec9740da23e6bca66d3765cb401889c82c2e0e2d16bdcbc334208a9bc0ee5a7bda1b4c7990b324e022caf05b598f116b52cb09e59a429c1b76f6b0a2b529b87e9abe98099e736dbd6e318bfacc030dd68fa993754877969f7da3e55f3774fabd2b3cd1a515ac6f01baf8ad57804f72eb2b55d5c1356000cd77df039024b6e9cc4bab52d4c01440a6ba89ce95dbadc5af743bf032e08b6aa30423e65da56d93fa145981863203b06a7a4abcaa62517d920e72b8573afd6815e2765339a9ff01d64abfad24d5ee18ad326565400026bb4f14af8be3b312ac6ae42889428b82de8a531a8b183e7add6366c1526d6a473b1aeb44a893854cb9dc5ac3345a125eb3203b6affcd22dcfff04d8c702cf9f44dd97144272eff2354deca3c0f8292618b3b0da43e30d7d337a28ffcd7f191ef0953b1fefd29de0c64e0f19d07b5079d86469bda5ce5be776ec11f87315826e7622c5a0b3f0e8a2409855bf0b5ebac7afdbf4375d476a4f68d790122df80f16f07f01737f95828ef9b562d3ecdf6cf5ce812eb8becc4ac78f7e1bb50f77c80e17965eef5d13dd2b2cd51319c29ffb7ef8bb17319a0f62b3bb52fa89e7fda397f2d831ca9d2881319b8421181ea5d251d42703ca1346845c9eee5\n\nInput: db9e5816e1f35ce7b33e6cac\nSHA3-256: 53b707ed1ac627cc458384fdb40fc138abaf4d817e87622c355550ab26bac330\nSHA3-512: 303d3aec5c1f7231c0e55801064b36a5704b415cc5fc652168b3ad2bdf8f21798479f6fa7927b5a897706c88d67522fe9254c95db10a69cfd82947f39873d1b0\nSHAKE-128: 045c70d2735a302ec9ee594f8d4757267914249ebd3e0d6d349aee0f7a0e8b2a6d13729e0e6a629ad3e3c00171dd6d3d9d59418005791161338fa995c7ac9cc2639ec27d985bdb074d64c703af04207fe72bc57972da2ee9b81eaa71c278467e9bfad32ae9eea648069264ee04fe14ab98c08ad79acdea8baed2543a0ddce05a0d0117c00000d09fa2ce37f0c10a496cad6bdc858a019ceb10d8e4df7f1059daadcef7acce15ac3c54223aad1fd4ed401aaa93041059c6ecaf88abf16f7a0dbdfd0f0d39e0191d3c48fdd6208c481d177e9c429f87fece2436e55c034b2777716fa69e08eaf305d3150e114e1b18c3fbd281ca444f024ed09351882e917585b8d5bc7a70d914d954704f58d1d8d68e459671e22d5f53c7c09357dad1cfe5f76fb6fab8f9a7cee950e0c46ecf879f5a7064f5f58ce324c8d54979a3ba7ae0b389bf228fad7453c680427072e4cc499ec59516d51a52a2d1aa6bc1975bf6a01d9f331eb5589a2cf8ac51a8d252988791bb80a384885ba99e73687428b75244447648d9a0f2b879bb729ec1cf5e477bf51a763eceaa7f5a83c2d831e216d268edea3381c224cd2f59d2cddda4f17f3b1ec2c9385347ff412ac9c8a83f08c5a3852bb02aca4cec85a4d05b48d12736dc83d9baaf5ff18c386c1b47423df60f807c02bc544496d1579f365a085e5b6df6590a5c40e350987412c33846031d10ebddfe\nSHAKE-256: 4b90ecd04c70c519861ac01ee4f2ec22443273d6d8ccc49b8b63ff5a7c3824dad9d3b046f783f8b9fa87c1bff3371f80f306e95652f89de91d3ca7e0f5c11d397b3acba2327a7677bf81ec8b5dfb1d7950be9494a0d829707152ecf123eb4338cb4b8fb2c172393d13f25aee9a50fe106055aa996bcb61d249ccbfffced3dc5d1ab84274e8a51849c79b0552432712832e3e0b9b3d791b1460f75a390658935695837e27fa87a6842b37333f490733f256a4d2631ce94ab3224832495dcb36a5f3cafe0152865cbd464a1b3efd05862484437845decadd55cb5a431e846c5f6041f21b734902e675c46fa9a0ec6d39e8d90692ac02b1d6fde8471add624f4b26ba5b46a15fe453bbb0d4bc4c9a8ad9c990cdb4ba8803967985518125e41e178879ac3d5a2dca80dcab74a209b4bb6cbd7d4d71a7d2432fbb739027b2223ec31602070db1c7501f6a9cf0f4a9eeccfa4da9324457911334442eb7da8557a4ac6a97cbe7debc339fe99807724a6ce78abf5f9e7a9c3b38a9817b43bbf3952e353b9a0ce82e8fed9b0ed5db8a8734352fd72d6e017f6bd838db7c78a09c40c1c902ff15e5d6db094e106e8d7691b16319e06550c608a78592dd1228993a84902baa9d96f6e0e52a0d86681e346098fd2f8cae94efd77b55cfe328984547c2cae42b8ec843732d70bf0fad10dc9d30fcba98fde7454bc3c78db0b7de1b9558c44817\n\nInput: bb47364ecd0647d77e397730fe\nSHA3-256: 6f71194df501afccddac9bcb408c774d7041ec29861cd2d1e4ded3f079dab513\nSHA3-512: 484b51509d8d63974c80cb3592cf6db3be77ef9a8ef97f9fe39b5e2db0def4ddf5ecae22f0784f6f768c4fcee3fd858e36ac93f56a9d4a92bc2f07cea6d50cb1\nSHAKE-128: 297910584ea4e6e3b6eedca785d817f88e95aa71eb7902a86e55fabfecc445fdab4cdd067ff36b68a7fba7572aa2b1e23f724efb63fbe0f0e433ec60755da0faa1860f127b40f77bf7fedb5295a38c75e7397c1f8b67fdb98bf2c82ea147092a31a968403c9a8669d5e1273fef400f326b66c9d0257cf2c42168b031cb716d4a94b15c1fe1694ecbceab12e8b0c5b9fb4e2dc96d808a30b9e6c7ea8c164076331d7dc668f0fd5e5184d6a5cafa5e181618debb0a99de1ad988e5d59ebd8769474a1b702a44bb422541df91bc0cd6fcc186ab6b19bbe5a408fbde50a0330c6d10f00940ea80694a1a52b80c25cba15fcdbe64b1f26c277d6ded1b1122839979fe84c2f8d37d65adf7bdc0f95a49e837e19241769a28fa378ee291e26d92b50d6332a451e0790db8d44abc632712792a0777a99e219c5508a1ea43bb7442badb63d0299a956f87c5eabddbed30c57dc20bd3643bd8cf2bd2c09d1d5e5cb47c6d5b972a968c069705fc23812193b8d7a9eead3e6add5297ef262c7e2a1899dbc8af325d78374428277eff5a7639d53ea7dd78bcfcd6e6ba0ee678152da8c177a98b3f36283f2c41dc10b118a218b78c4cc975868e29b37347132cb324be9f84f7b24acdc53078da0eb7edf3a415d87d6c0b11cceca8b1df87d44c231c7c4e265d3811426f1c1b40ce97770c35d9a277c027fdbb1bf774487cf022b717fc4a4c7ef0\nSHAKE-256: d313f55a9518697d46c97a725d26c23e3a740eeca5f168b871885da9a6beb576209ff5fc61442e0b3c90173f88fb1e6ab9305aac1a54849f16fd289b5661dcfd3b91ff966a2951608fb63a220cefb7f4bc5eef965f8c30135c5a0e4eb17f40f3abd18c9067394bc06ab6cc9898eb2b9cd68085af9432cc29dac718ad885f129510f415201841d6774d01aa1a15f870c494816ab4e13f386ad94a279408af09f5b73dfc687902bbad653d375ae2da8ff9c375ac7a8ea6ab9bcaa10d85bcda53c73834d4401fe5186b562d003595007decd722cd6894b18e3efa426c260d6452670ff9428299aa702f3d31e9a336e147414cdf1c85522651c3dd0fdcb126e56dca18f2445af4e123322c0beb9b8e186e67ebb3c00cc657aa31e23b6e1e73ffd3596396cc0a682ab5c8d33239a3a7d82ee90fdcfcf56c4fddb53089e5dde57bfe16991e5211e50eed627092ed4984f266c2b6d04aa4668ce7843ec63482dbb4e66ea2c0369d765dda72a97efacc51f6bf7dfd5b3347e421f373ab4d02eefda9081a1e9978c31bc940c92cc29244d17d4f050362fabbc3f98959efdeec3f3f9c18396f4a3cda066be65646923ca6374a77f6ef0cf85e3dcc06473f40506d5ed99e09672aa2bd7d3e71d05f5b116ceb0b2e2221b05ba9665cb7fc77432e1af426bb9cb75847a2a57b0085858336aa13e2b41d340820ba6fde5571504d60781894c46b\n\nInput: 7eb6e8745e9cff4a1c7332094427\nSHA3-256: 97adfeadbc7bb16decb0fc209162e47515b79adf087cd2b6d01d71ff60cd97eb\nSHA3-512: d54f9b028d2be866cdefd057d8984c0bd93b7a0ac566648f74535073a1a1e92d60ccfa2c4813f3411ff90cce61eb0986f193bf0fa909e0276ad8c5b53bf3e318\nSHAKE-128: 53e08f0d4a9345e4fa1ea520eca1874b6d7b9f8001bc0af52b7f1459d5198abee61af86987aaa44a8ec9708c45b04f2e7286197aa06442f42e9746f2647542cb9efa645647ee60a5117385128c576e6402da9c9b4366db80a9175829d4d20e15ac20", + "b718144599e921dcb29bd22cbef35782ca5c38bb2c75331cf58e5b6c7cd84a6e3dc4ae5eaee913c3a54c2ec167ea90b80086fc2911918dfa82eeb1d419151f1cd74264671f07c7afde17e528fd5be717ea68b491b30611121fa31402d02fbc9443ae854a7a2e54891f0783095451816c7d5593dec07d5009bea6a9796a1b085df7bbdb594e7ac390aad4abe837a2fea3220f5a72d6371d32117709ec35e8c65e2aba23f772eaa4dd8a338ff9765b8ec6054d9bfc7b8647dda23e7d3b4f82addf176bf5dcdba454d21c7a8f154db73c55461e1269ef3e515566bdbe339f0f14ba6a50f06737a620df4d8c7302cd18d102d5805fdeafbd44a99b6f8f4d529b6ff224bf268103c844054e52d08222b8e47902ce0d4dbe0f5b9997521fc22bcb203ea57bef5c2958ff0975af3756b6ae160efe5ffbe6c69da8996b95764db5fe38e514e41459ba9755f8dd5a28282c7487ee745967a0dc60c6f6361d2159063acd7fd4b0542494df23c176f338b7935271d04db4d89434c66a5e0d88087f89d07348f48c95c674392d8f0b90d5c6e32b646411d50875ba1a8f3c8262da797736\nSHAKE-256: 42fb58bdca40152b48b7190adbf376ecf36cdb0a9c10e37ec9985efffcd7bb59e5b0878a18155aa83b77c57db5faf9b59e8092b28358609f4a75a4ca8bb3e74034e5811d2d9fefd15efa5377b5b6150a437e5f84bbba6a38e5ab847003e38abb20b50713f424ad39fbaa513b0afa868a4b5a9ba0466cb1e60cc8904ffe6db3f2c5013f65f9a5df6bfcf9cf27665ab2ddb5221e6dd5e6febb37a773923e299fffd1f7bf3c8b6b60ed1451960faab2cce19b04363a4a530dae067ce29de407922acd9783f8f4719112ab03213245939e061da90ff2a418f964fa21eecba047186f0b4ce847e954607c5ced0fd4de775d0fe342b462b90938cea33869ec6a3058d9d62530118fefe297cab2a02165214b78f605ca2c266ccf128e753cef351d94a514f34dcfe79604f7d53443f7e16c1a54d5d719ec32595f3b152f3004ffd31131a337d85a41bd46b8beb045c9f63693771f0296a16034dc55aa9ec8f3c27ffa4dda533f8588254191814109a3eeb2cd329dbf49500f4973b51d54ec289cacfa9255f909112552531076a0ce1b5c54990379d79d902361287edd05f41698080bceba2e98fbfc1c885240287ce2222b23eb2518b966dcd91e1be7a617a8539bcb05185e12b7106e86e0d996126063168750a6042c576f397b80561b734018c2b680a391e58af440fcf970d61f7824048e46dcff005825196db2f5493ecdf7b7a976\n\nInput: 9bac4256ebde5d24b0a6466684a420\nSHA3-256: 58ab4a7101e87c05d5c55186655f3f596e4144f13ed36e3d971db59015f87bb6\nSHA3-512: 975e3348410e4f29f93d117129f7ec24a3f8fe94fcf526cdfd1dd6bff4f28d3bced4d79b8b0736358c7b0fe62e30395ebcba53cd0161b213d101bfde1273999b\nSHAKE-128: 1be7e622342d6adc2ddf7fd5c06250738fda066ae9175df5e4859e659ae249ffea84bd73d54fafb877719b1bdf2f87629547c456c1e5e03372de0f1e72e65a253480ea5c137e2461f792e2960c2c84124bef91cad6585b51e0f4b07d2f4d60710b64f430f14380152d73f46e238965af06aaf3938668befa8346364c295823c591d11c9257892a096630d59c0da031a1a2eab39950791a7c364634dda3840c2088701e618bb88e43d5c3238aaa5f96a3c3637059ba47a0e13bb67ba0e706c8893f2b9fe71d279f3e7537bebc121bfae5a8bab31050fc423b48410487d2599e52dcab7196e839cc941900d11d5f11777950c5bb72b10a6ad87cea33b85130f79bae2c86f742bd61e8d77bbe8fb0054c0d194f72d88d9483785988a0a67f5d442376852f0575de83184817941df23101807a5f712bcbc470c65639652475518529b65aaf91bea1e6896af759a66a29fcc59aea7b90dccbda2813c5580a8a08c11af23cb8cb9d41b60636706328e019de64a4ff23a463969734b45245889c160929a01f66863bb944ca335c28afcbde60d736a95ae0661b76a1c55906c780bbb3379248e1bb62c7d2dde67faf1be6efd458a6409abeac88910efc5886a2a964bc5b05203d9548056ae877b2c6ca60b00489de851e66e6a4fdb71a938486fd324a4723b2161970463ab84394547c134b6e45b0d4b8715d601d7d14f02b6dc38baa3c\nSHAKE-256: ecd9b35410ddc2744bfc21688fcbad9e3fe779e31c6192440bfe64b5ae3b4ddb8d4cf2f6e960908a1f7427bd9d0c000e20d5528e827b472c8b3fb8b62779f43f86f985752677f7f85945e83c8db5affce156538d2547cb423fd041aa2259289ac4e40e5f50c273941b941269eb00397dec8257c6bc462d2d9c2613f6f1461f4550a443081b6e12c5165c70c3fef045357fdf67404b0ae5672bea5e01b8f40627f8967a6df058fbf88227c5ab6c7ace3fd23b0259e6f3ad8379874d17d7493332e8cfa3db8943d24925a06518ab1fe262a4827f02d6544d133d23164b729f595522997afdc1335060a69c47104483b01e2e0a37c00dba1aaef67b93c0f1a732600e7f4544b802456913ff23811a6e976e909d3ebeb3085a0530ac5110394381c37c9bfdd96dc77d143760a48cb45e64da6d05df12b605a16aebd95ca6ccf3e4b9badf292333144f5d2663889993e395e5ca12d10e7ae8cd9af1dcce6bf438b374251371293c36bb2b1e47e8b11bda7287fadc1f5c464e020874ca8b6992b4cc6b08b2e91f01820aba11220f857edb1a2734f2f85141bf34f4e25b437f6448219970c8c0c0f8a6e508335b4990228cc0e47cd7cf6e3d2a4544b389f1ae2f02e25c16cd1d347de5434f1339e95b62a075d8fedbfcbf0c038925ef2ea3f1d6beff8b1f9c7019d611adedeeabc749739c531f4cdba4d97427876b3a0b03f4460cb911\n\nInput: a91c3e7119b43d7c675548a37357e246\nSHA3-256: f6bc15a3d2343b19ce5fdd7214ca50bc1f0a31d5e66585accb90712941b4530b\nSHA3-512: c5f432de1d18b6c7ba4480acce9a2c62a6ff1ede15704404be3bd8dae9bc0578721030eace6e25ea24910bf9f5a7a3600e9c03ec3f3c795646dccc8333108234\nSHAKE-128: 34c109a8b5915ebac04d5281a103a7bc02d587955f0bc602b12903f74fa44c0d34d51f6a2fd9d02d30c1a648293da70443f9b7f5658bdf9d694986f9a546aa7f1fc6b4e79aebf9f8c3ced78c4386c5d0241b0a55ab497b74ce824e2eb168b5c5a6ca74d6efcfcb2cc34f008c34b1ee3c8b2735d9ef3dfb6148b1be5eedaaebe90b631300ee74878187271f3f7284cd88c1c3921abb87e3b749e3c136fadbb98730a7679b80b9e622223df2aa5a7c0adb9191a44e196ca67cb6a134c70b267e6334e081544e0de4b57d807ea02c10bb30896e7e77dc02660e380253fac4924a9720c6b3fc3f13aa15818c61d18d947f9ff94d424729de7e81e280752eef1456dc77499f18756d940548319d0d1c0601b99f4f759477fa9cb5695f23d82532bb04a2a30a05039fd5d8765048a8f9b6a69d10957d8f4484995f9212a89214fb10323a0ae880dc2a2c20eafb3bb1eeeca16167415f774c8d0b95ec0df79c61603d077b6276aa22e22fc64c0909d334e77c16912a4259affb5186be9ee7a1d91756313a695b6c319a753510de6580bb453ed983e35455b954044c77db682c36bbb45e9907502c72d04172f88b9baaae0d21fc8339619268e9fd630eab66372284f3a25944c9784874a974028847276532b4fb60996b6c5da75daef90cfcd9ba14144878d21c66f9faa55b8e3850968e692fbddbaeb830f9b3d12e0d7cf8e9f71ba083\nSHAKE-256: 7940cb003352278e463f3d5e71c16676cb6058841c896106507df5f5050ed17b00c3470184f4611c9209130c4a52e2d976c6d6629a5e3ee4384dd6aebe513996741f9cda5ec2057b87092c57f475f5f830d741e7a28b7f2d00fe603bcd91ca0f8d40c8f23979e7d583f618c139424d3cf35466ab1e50e74aa9969eb8a48d5bda63e47fecaf3febd07dfb57c5da23f7951fe6907292fd1562f5ae187797303cc854e7906e9a7083901b81606548ca2a873156728a851fc608e0221524c2840acb6dd38424e0ddfbec08975fd0a268069d6193012337af24bc2e7bd736f172ed1a69f23a447132efbf3d8d1370d5d4d4f24994c47f2a57e0fa3ce755a2465f7e2b25e355114aa9f31ca22feef39bf9e760e53dd720c62aee59e6917059646f25279f71816f3146ba7e1582add728e0a20fbd13a2278e591e0c819a7410fc624b1848250b18e7c33df06a579b9ecc7a945731a44f4cf4eda1cdb5e873049768467932ac7cffb14c4ee1ebd2b5f504ea73a6912e840460ad278632fea968b02f66ecfd11a9dd6246972d310815c499c361248810b5dd92973a79fd3ef964d2c17f6670451c7033b80b7934c47c18a2be566485e887ad39e730c9e7327687f95bb63b858dd1e9876b23ec94e0d3f5f447074975ae9ddd9d27a6b9715bec670961c3d24a23f84abd002cfe51a59df1d7516c656fe9dbb108f6fff2c07d8b1079e23981\n\nInput: bc3f62cf3df0b82025ac38e112eda280db\nSHA3-256: d489ca1938887440617093bda8560f8b27b4d7147c0018d8ba7aecd93901f338\nSHA3-512: 1f7870a61f6191b12cad832c1aebb60b86e52d1cd124eb181d1782822b68d4fab7d9ef83eeb24b2e4b84475fec7c4cb1c4dffbd920ad8441444cab5f78e47902\nSHAKE-128: cb524f5155f7925864a4a4e6fff28a262dafafea56307a840e9af96899a62916d2b4906b106930d2abd1de46bfca3ede61167888f1e1b09bd3b3f1558b9b47d05e3ae5fb77be3d373d24e5db14aa1b93dcbfb1cdeab883ce59f22cd81b09f55dc253ff26210d2113ede3d3c42fc70ebc87fab5c9ac9a4ba4db8361cc836f51ebfa91f01b4239ecf62021cdc999c711d4be623ce2bb53a544b9ebbe4ec02ee031b9ef714a5bb5552eccedd984f55afdcb0d882632a24d73300d0d375af9212b4d21a7dbd9b059350bb94df0fd50d8ef9f12a6058027fa92aec0c919a03eec3c872379f6c52679920ee3d367f2f97522e4e618e8ba37ecaa69619577b1d18836b61af66577adfa30aca67fa2d60e8a16ecc6c07399d0725c8b278206cca343ea6210e04ec5e7cf60345ca7cfc4e763ee83f4442e542ebdcafa6d66b742acc0f75b3f63d4a6cf5c8e69677aaad2e50a36da6cb208880f49228de3d1e6df53a33b30715cf41d0e7b882b64516b13561dc3b9debbe6d60d61dd96e8134f7b6975860369eed0e52cb48a89ddba19673933506fec060e4c13ed176234da417450a04bc76209056f68cc8991d07c26a1f5c0c5c37bed42d4f20ff8b37c8fe5a4cf22c0f7305d61ee37d4aa3546c87208ee48f087bb519025b9117c91d75e1ae61aa0676143696414d6747a5fe9b9da0c410f62171b4e31c37239e58c0a33f56706903549\nSHAKE-256: 8fcff21ddc3e69121ae466654467c50e11b0ec3c7b72db7c43d6a494cc6ca571cbfdeb6056bfe2ac8d98772928ab49e67a3c3c122c72084ecc01c8df2e9183ffb61bc57bc3e860ac3fc3f020abe302f3a331cb663b3fb4e4960f7b9c1c9bdda91b72b9ab5212c4dc71676ccb6584c636b7ad1a30e3e1fd12c4b22c07ac464bf81ebfc55f8104da87944009442e5e6acbad5a8747ce98b10b5891531c2c6c858cdc49dd42cf6d5aa2aaf0ed2a7d3e9ce8e414d1cf5bf7462b0cf", + "10fed0dc42ecb8de2367aaf65bddda1583d137cb7a431e1ef10cce07257d6b1aa3ab00bc47e78a17c4580624a6438a1c707fc56944c5d75421898891f857dbfa1c3c26ae65724df288da4ece1046766f90adeabb2ae4a1d31863b852bd1e61bea62c247dec1225f73ad4ccfedc79a9a909b3add048969e07b0df037b5cb631e1f1c7bd316dfb4bd9bf46b25f0adb6aa91dd75f8170e269211f959a7fe1fed4a18ec0ddbcc059539c1c0822d2dfc1add48b5a9991eccbd8586d6d4dd2306bb700e7ec6d37cc17f51d5ab383dd8e8133daf834da687d69aefcd2089083756f40233d26f13517a54a1366d36b3975ff2e9cd916e07614393810dc74399abf75032fc70cc79d22ac194283f78262a79fba5c37aba72c1258467c1aca7ab3bafe340c9d514b15eb06fe8439c9e4a936a398c6bbe92803735c4025a3ceb80d7bc224d82c42008c9d4b1\n\nInput: 5d47df1fd0f97013d9a187ba4de0a0fb5a7a\nSHA3-256: 44eeb88166a6e0d752d9137fb1f0a784a372ed1f0915681e28917d5470100d26\nSHA3-512: 140fd0a4cff59059c118b9c980427e10af7d447f6613ad09d48379626713e6f07738a4226975b13b850c58c67c3d0bb70634bca18b7a94f63fddd7c4de3e8e42\nSHAKE-128: 14e2b17b6de7d9385e8243b3831ae1cb5279473c3012aae5b93d60ebee2c9cc564ea74d25524ad013942f4f72930f151363d4f50cd7f1af697f610d583523dfaef8efdf24ad86e7bc6d7530e6ee0b91948c7ed46285dd4ddec0fc4e5a288913c563cccbd1cbe8e65a28f7b4bb84831103e055eeab58f56cae49f3039f2199b6e5e668455bf93356c3574279176312744556fc9709c0e40b8cba8074bcdafc4a017d0dc63642b04c50a6660ba15e1d65759d21f1cd6721551d011fac95470e39d1892586b13e211df6a0b2e93d342c4362546ebb826867dcefd84c8f7e1cc8833160a91604b6b676fc838848dee885b1dddf167d2c2ce08d340f60946050de2a2a10e48eac1331de749d3d706c88089a7dc4d6243b2752cd13064d20be6d742b0effccd606d1247809ff8adf9767ab017b609350dfe11be6f4914e56bc55971cf6696225c606d0d8f803bef2b5526b5664b4d1973eb3d88ca65de08cfe90adbaa5f60ef9216a82718c86c6f098c7b96634b479fa90ed20a7baeee929d064c7c5489f4eec8189ebb88239dcf9c44928d75b38f51d4fbbd1dde9eddb26a599ec25719e2648bf86b67645fd345dccb162d3727a3465f9d31d54010c4e8820a4c11a4133561e9217e49c6eb21b227b1b7bb89ec654e1a185326aef75e3630ddcd0b173e95ad6ede8c5076bd2cb8ac2582fcccbd0a4209f8c70b1c1124bc980e3aae93\nSHAKE-256: 9ec46fe1a17dd8b7fc7be6ee1b6666b9e6967140fa342ad4b27c2564b0841f0115b6416f95702f0c18303f2fc5c94ee51a3a2a74a63e7d91616a9a48dc86cc92afd55b7afb66b1237704a0238745a5ce2a49f18b424e4cccc9f90e879d0230acc7d6ebffd6b34e77f041d34625382265b4246e27cc48fd82e3b0644583a9e3498ec1f64fa007ba8b2eaed66a3402eaad5517487e538e76a7da3ae22b1f0d339c220f071d4d345453f03b4514760ae99b3c079146a100f8252aff84b2330066dde7dc4fdcc66cbdfd27352511879696b075deccc0e3be814074546d109ac293b7fcb1cc67ea30fe50d8061aacb6d0e149c589da145bbdaf0f0f68c3844b78a1bc7481aaebd49bff0c3e97ad9c7a8fc7adfe12dcfcdeddd3f47b96b562c4d549fc5e8764db5a28f56afea623fbe4445731caa4f13a6faaff8057791baab9fcf9768e55b7c46bc9669c2fe86da5463c690ea33bd2205de9ad6c045033c4cbe26d7e31e0298c2530a2bc38c3861835346abc0140a708e2dce9a5a5c5ed9bd1c78b37863018cdd2a52a6b765bdfbf17398dc1d92459e361195d13383f2522921c694049f4db70639350709fd0b56e8cfb27d146675dccc891c794b7b29156acb9f3174fbb8efa9ee4ea13331058a46a977d235581ee3e7a8c6037f28211a7f6b9a3deb1d82595887360841856cb90982c63a700adfad8bbc5169f796e8b355e98aa56\n\nInput: 189dc113c516af57290ebe6b2b74789d400701\nSHA3-256: fc01db7a65f9b323227da499d956c28cbbc69fa5533d9d1242644f24ea692030\nSHA3-512: ddf459e459e60f8846f20d3b4139f4e599a4d9838c6e8ea10eafb9fa04adf3aa6a82f3a6519a14ed2ad151599f853d385d48c1e586ca4c0a4bbcfe4c2a1fb23b\nSHAKE-128: 16d28cdc53b6071b2d63c7a13e52139166e1f49ff582e07ad3707a06e77ecd400258dc833a3c49534df462ef51f705f7c9454fbd4c34beae0a7fcbb504c97a09b030052808800be67569d8a1917ace4bc00735bb0d19f83ad4a19eddeef99e39a7de6c013aa7cd2ade2a900821f2eb0cc06bd0de41a75970c718fca3c5ef0c654c7bc834946595bca3c769390875e7ab1afaf0f0bf83b8fec127e4b142e471d40d72964edf301512effaf0ee068523eaf847edbd77cc32cb786fcfb103b2fd019ea834c7fb55513ea38b962ca8286645f5feac74dfcc39f4adbabbe7df8391fcabb6ed7f31a91bc7191b2c7c9a53c7379385bef027a5afd817b952103efbadf374f8f6a965da5c987d6a279f5e507e468e6edd9fdb1ab4e9b69ecfba47fcc5e9f4550473e7edc8a8afbf89eda6df5bfde259b8348d4ca4ab0e84d38935bf4330b7b2c6ebc63dfd74cfd4ecd58f03f4ed26d413d422807dfdf7aebbd6f61d317e06f35a2141f7bf33abd96d52114a70b0d1f44b25a1efd84590546f5bc7760a63bbe2bf30310d5ae9ea6f5b490469af5da2105c507c4dfafd182c11ed1b0a6c572c27ce0bab7fe1a8d7619a8efe7d8cf0e95732d658a89ad63005a58bfa945a2d32a813e741f73d4d58ccc90c5a54ae39ba6e3cb5baa2dcdf231c5a2e3205b3cdec7aec1c2d661c54c3f335d08e7a8a5fad985fabb88c7793867ca83287368532\nSHAKE-256: 281b0436f2ab52c8073906ac430e0cd1f5f53cf55f0be90a5f20575ab3950e42947c8cec7b4ab802629205c3e1bc3e165135524edca7214efb80e9fcf931d27c0394d405260007513e486c026d124d592c55e2cb7e89cb975819fbab86b1b2f13e96256d3f71eda88631c172b0e5af215a9dc8348b698d136b48c46ce17c6ec693713f38b9716399bce28a60bc5119dc9671386436dd7940d418c60be132377bcd5aa1ca96e12e3b6c49a992a6b8f0a0aede893cd4a41f9ea8ca3c33023946653c3f25e986c91070c6afd56c2ba22b16242a562426eb98cee9ce6659ada5662977ed149db1586d49f7c61c2d723f4ca71aacadfbb7ab190ea322cf5793a2c539248cb2849df97e366b8d919af16be6a9f0ac4d8ac1268dc7886f53d5a09a370d93159259bd33ad8df60aef7043be934660b4123bdfb4314a880b878bdfafffe3b87dd519f99817538d47cc76cfce5864839d8cb4e02f0ff3e6c3bfc84c6cddbf2d97f61da42192487879aeb4d526e2283833313145db0f78654bc3744ceab4dde23b3ddeb556f6e07d0b3bffd8f6af7fceecbac6e8ff928c8cb77cf5980dce3c79d8f7697de1ca2c75e2c3cd2aae37b6358818f26820f8a60c211a2c4824321eaa6e62b4ed350df94086beb76b6e7d8b2fff4a6e0ff5911091153d7759b292ea537d3126599bf411fdc4d42e503f285ea3802cd14ef7dfb12bc7fb52fcbf7286\n\nInput: 2b478a1b167d15db075fc7fc02b62f83ed4a8aea\nSHA3-256: 88ef8b9cf6f91458c2ae0d9e55e69a97ee29b8308495590b0cfeec709f103b00\nSHA3-512: 771d6d0967b1043982df3d73e33bb7ba8b518f960ef1356c13db41e6a068495740ac94ebb9f025685d30a6ed49a3b2a4a9447a1c7a024efa753cebb726933d13\nSHAKE-128: 8069654eb46da19674a38d14569ea4d513ae27e8787e87317a1293a3f81eb39443388595c7fae7b3a0b7320e37c72154a46e5fa861a312c74fe25a7d9f4efd248096849b97551af785c71fa1bf6c15e72c3042523a956b3700068dcb4e85f6a4d955e0ab3ebc3d2719773a8ea101e36b37a255d754d0547068eb60523a0efb22bb279b3e5dd603a078c8e14534e2fbfe87d1269226d3d3a2e41ac56e08254043ced4708a1a6743389246a00b083862f555903dbb6cbacee01d6758b336089645a4ba10fa99f16157c1e40e36b78f6cb4cf37c6362fc256937e57aa8f29b6b6cc4bc941856cb4993307d76cb81e83393dee7fc7856368fca66697ae7a983bc644a0468b1a5903b95e20d6dc776ec6f105e44b5737b0a39cc6b398e4845af103bb9230e73e6c5df24f3e6e951bd753353d1f2d21388ffc1d47f4a295f78d8458e90f86099185fbff1112c523cd53232f9a7cbd263669bfb0f2d675447b3b3160cda41167f6d8e5be37746c2ca2896304dab7a40a6953a593876efcd4e1f496781d803db8f6e169522d4be125070507fe8a055218290b2cb1412e93834989e5dae53bb112de3882e0619e9c2fb935f1c38b17bb9067888e2c94368c4b490caf9b68334752db8d22114c325b231914f0f1f3a4194480d54801bb491d55709ae6a1d203eb0e86a9856162929aa838bedf1e36b45fb287489a5e06058af92e38a271d8\nSHAKE-256: f911e154504fad5e4c3380645cbae088dd31dd7dee06a362af362c669f69364acc161f63a0cacbbeef35e14b8b3e08ba327e91e46ea29ac8c2e587e18398981eae787d4aed81c58ed55066bd2cae2d73f23bac22525c2506ffd69d12c446f4d4bdc54aa5b77517e746b14a406796cddad60cf1fb38fc7bc1236c3cdeb514a44764d473e597c18ce817379634997dfb66b929b32c93aef84d3221b3f757279d2d07b7400aa6f718adc4c80e15ccacbfc41baf29c0a3fd9012d26ac2c7c402e8108e32dc158598c6ff3572e35071a64b7fc942adcb37c21d48f5cb2911331cf1bfad23c0c552d7a7a4c5e1da44a5d44b0407179fb43144b04752203d9f495a62412756176c8b1a0264894919c3c375a6050912f1f5db124ce85d5e2a1848b64e5b7caa6d5ef6859dc36ce8f566f99d7300177ed0c1857b7c11aaf6422e4e81d96e549616ca116be39eaef20aec3ddddcf7e674f6cdadc92caae566c6e623ca5258b0d7b96c933130f15d4e4bfb4b73bc6ac2845caee190d0958d2960aff26aa692b4fd766d710e453ea5df09802141f3eb8541a230d81b5cd995a34f6d7801f0455e337bcda591a5566fcd10f71a13802ad416e2bcf65eb2b5f4f89131460a77cd95d9b43e3b793bfb249c020c936a182ddcc7b15f1080d54b260551ddd70da63021a6b14aeaad6a5a50d28d464cd89cc316d8360f9632930e72a65d50a6f7e518\n\nInput: ea3b01340dcc414761cf572fa65cfc3bbd4f7998b8\nSHA3-256: 912ed6e91a3eed4c16e029a17d6246dcb11937ee435d022717b7a72a28ac25dd\nSHA3-512: 769b8cb47b210b263cba11c48e1c0262f258a498d38e4170d9472b4d95dbf9386b243e0b1be4201162782e80be6a9b73d6cd177681a46f987b6a4309b0819520\nSHAKE-128: 1d52e4ff7b1bf5df0f4155dc34cba89e47e48e9d21d03462b21ac34cffba48c5ca1fa42ba58927d19d766adef6508154a00ff5d4064aecc2c54f511f17a4582a46eb9778413181937175f1432dd0fa5c1ddfa58e10161d8dd21b9402ef5f09859d11bbb8d79f710fc873a6ca2f8c92b3bb3ff7fa0d114f23c0f665f37fc1f96b2fc04b5", + "a1b84827b618953186c07f4997db3ebc86024bb0677bf6f720800381550b098ff857affc1e9a68681963ef148786b6874d2122a1dfb82d49f597be27a081a3336f9dff2a27c6372a42bed7be69d576eb97f87f4138aaa863fef2c26a69c06ca3fe9993910b8f72cdf877631febeb78d4f98bf78e3fdc344234b3e58180e20c9cb23c5d99975a1e73842f322e13565f1e88035860540424b7d27dd944330fbc7ee622fa2be53f68613984f4f22d5dbd7c2a23de05ec4842c5a668721bb87332dd9e585ac25eedaeee89c299ea7fcb1eb12bccbb2fd79aa4067fac613a52be2230990a75f97b078944e6552fd5f5a30b4103d81af458a37f59fe256dcb3f08b8772910169f7dc0e6edf5e0408447db862b4c0ee3ddd068a245d8cf45625cbb123edd13eac979d1258476726aaec4e543860ffa70866857a3a8d2aa0c6bed35dd636e146b0f1ca255ee284be3768fdeee4f1e7636aef0765ef23084bf1a940c4acd17b6082e480ed4c6c6f07eafee7b2756ed53793f888aa87a991678e5b\nSHAKE-256: ed0ba9c308166bda24f7855508dfe81a2187e2fbb51d4ee003061f90e42e06f4c732476031637d7a7585d33459f65e79284cf8523c31f245b7d7a24dd612e1615ca74e9ecb6a74856e622dc89c98a92207ebd3585341425f355b2b325e5b2889fa2f0ba90ded9c1094064ae01b6390c17381ba915db408a328459a5bac63402d84642b964301affd2b82170fd2e3c27b2a49bb5693dca2af0b82a9c7a37bbd847dec88f6bfce0138c2d2bb07a0addd2bb8f73f7001d84769da86ecc0e3374881f27e1cf5d2315172fc60450defec0d12eec9493073fa089b3bd7e584c463f2cd97ddd8a5490394e8e68063811b45050b2a1aae1b40678e508d9e5af47cab880526a4e587f08a630729a26bf944e7201043da5cf7ba6e7f1a9f677f3e141f8933e81a6a13a163ee45c0158afcaeb39b060b7faba9c01df3c3a19484693a348c706f81c35d263b253531c469ca94d8e1570e06f0c4ff97e33fd116d4c596a0b7110586ee3dd23995c8668622d78d2ff63fce8e1c08179ac43668e622604b555773b6df4bd148b435dcb206f4ccb242c976b6cba242198738cd4d7c36f0a8fa41c723c1866c5293ee86a77e64bc7e4f266344c047fb8d4042c11b359b8df4d9663d34ce4cfa944a8a347c8432b047d3c4ca9a4b7f2e1eeb11f686a8a2220e0833660ab449b38f72f8f2fd647be6e0fa4c87ded6a49c8206a9a2718084fcf246890f\n\nInput: 03eff8768d8e35efa08606a346916a334ff3cab22724\nSHA3-256: 67a80739c6eb039dc27c633aac8f35400f226137176622dcbd89f355040b9e9a\nSHA3-512: e27642f7fc370e8b9d9cac21ef89b9483209ef885228edd00bd51b277432e9e7896fddea4870d7c9faaadfe85d42c7bc08185962f8c4e9edc40c8b7d336d042a\nSHAKE-128: 092d5e3d7506ddc42886fade9e8b4f7c27f71259e60329d1950bc0f85f259061d1672303a15465f0df65f8497c8852704214de2a2c31d687e7a0292305e4649b6c1a013a7f29b22fe98d38c2adc513198c44eede75d43db3d69fa181a4e689f38be52263367159a11ae863619d553466010d5ad65466e58fd100fca0cf6f6ad2a07371452a50e262c011302be9d68b21ad5cef188da94491397849f238eeb58850c4ebf9eb0cb6040698e74b544a4bbe527e36f8e00b81e1b3b83834bea349bfd88ab43b93b84d1e98bcc944cfddd6010b753b563c2c298afc54cb863291e969581fd00257321aec56dfd59beba88e1075dbc4f9bc463a437b7acafffb3be06f78dc1991f5857da132fbc9b0c96fd95035b4c7f372c99e68dc7e92cafe3eb6a5ca17bc8c208ba87aafdbb019721ffe3dc2002f52b3b2a2eb1a18dcb57c789dc35f291cea513f792579918a95dcd009d9e454ff5af9ae1304334bd052259e024001deef0fb798fd65132d61a011237a270aba9417cc96d6643ad32ee727ebfef56d5bc664eba3bdf058f9d74d642ff9bc5061f7701eb8372811ca0f1ad836e678bf0af2c62ce3194a3f8e004f28c3c848787b0f0e0a42ae8781a4db5de6f21857d3e3129205b4a7bd609f570a7a0a50afd7f5696f883e1bf5a9e25ffe1858ae81e58ad79be7d90909841cc0f12341d9b24a65056ef39c6415176fe950c7db2662\nSHAKE-256: ea349979a8da595a625568c35024c29b4a3e76b063dcd9af23cd7d3539eb586e0944f51d6a15a196ce9e3279895b316e37e1052cd8b734fc47826eedabd7b5f9402ecef7ee513e9512a229fc2c54321406cd5d178465c35fc59e6d85b01c85262de6e8d38945d8643e3cec9fe7f2c699480939edadfe731132bfde06c88d90cd68c0a69bcbf52fb2a172ca7f0b0e9ab073d547ed6913c21221e12b6a8e81b7d74f6afaee368eeef9aa4ca6401e613c6df82faaccc4661233490a8710cc084c663c7e51821987c8e7c8a482a912f67e66eff1bfbde23e04c55c1658ce15ca873ada17391ae4ada75f82d81ac78f136a63445261f9a79165bcc16393c7799adf4a0c75d66a046d7ce1d042da701ae5be7cd272f77ed01050eab3d349645b9c201082dfd3f5f653a485128a293b78ffa5804f992fb53b8ed899f10a7b5e01d0f83e065ba3ecd6f9784df4658c7929b71385790038e07d2a64b873cda68af11eeaa846e9234408bf21c0f144f8c0f34db703187b9b9222041a6f2303517c6ea24d10670142f3441ea93f62d7f655a4f4219aa8a3fb49df9947238f3fff71a111e53282d9c834e6d9393f9c8656b9b4bc93621639cf544f957b441f6cba327c36e099c2b15383485c29eeec1d7a1c1677da0a5a31a0e4ecd640f34974dfd4f661f137df6d47bb37673bc0e4acebff55bc799625dc78f0da91b1865761c753c2dea002\n\nInput: 2046da183873fb9bb52cfd5138d64ee479a6561141997f\nSHA3-256: e916ff6591c5e9af44bdf1cdf4fb075d75792061aa4f79cab7a1560ade447403\nSHA3-512: 28863ea7228f9ee25a6db7d89db6183edbd3d6c2bb3a5e54182a73bf32fdaf377c3f844deb2beff3ee7e737f266ebf8d854b26bc0c758d01be7e0e9936931fe8\nSHAKE-128: 792228ec594e3685110bc17dc494b68e17a5b23827465048dfe83f30ad8373f0bd3f8a00fb0cd3b43ebe5008d987d78d1d1c21b43eef6b766619ec219d5e134923e2cd1acf462e5396a94ef9a86a073ac17faa2a72a223be96c387213b4038c6cb460ca8bb421d76e6874068924b09a2243d41e73f6e703560151f43b8451d6d804befedec46b72a41204ff92f1fab2c1dd8780bc24e9e6953b3384d9dbc591974bd4b226d3b4f2af50d6a5e1810c36d32c1126a972352da088007e026c8b7927c59483a61f3ab3ac3ed38068d195b078113b59000eb5204740378c864fa8aea7d6fe65cb944c34f980caae8e619cf707a7c28aefb4c2804e3bb841cfba599754072d1d8b2fdc5d89b1b97a0f753d71b10aec1fdf18701d6f470ed843dd1c0ba8f2152a4305194924bfb610393acc8d65493fb1a6e1db19c52d4dda5ee465968c4e028e0320f09baa683f17ebaa95130aaebdad2a18432435417a7d113888a6ca62474b4117d8e6d52764a3165ff70c6151076c79a65a51ec93211cac08ac32c7f1da4df3f5e41c3f556acc9b8c50158b15b1fe8035cda97b80473fc8cafee21a708fdba4eb67d826cac0d3187379ef8703172f6b511220c07e22f97711e157c12e2cd3feae397512460a4de0c95b275d3fd46ecbcd7ec6fbe1020422ed9d71ba12bea7e2c357cf7c2166d963635259bb8838c20fb4806f2141accb35a6ea36d\nSHAKE-256: 986060e94c0c34299bab9217083820267cb1d26e20e6d0276d746d2608817dd179a11831b4e5857e4a99c971dd31c8cc69038645679cc05f96ae34dca1650367aabada4eb3eb046b87ec261dd317f7a2ac9851a7b7e0dfbcbe663c88718ea6248a0be3b6ae7b92c7561dda7d29303a7a10c1e49fb1321e1e812669aecbc390d3f05b2edae96c8a98cbfdaa045c790a8b4223abea50361982549e3e5acf05c8a141183a941ed55d742fe7c45a9d69aec0e7998c2047648ac8ae919e9fcaec18616fd2b1f82cfa9cf885f6e2be405d5f1edbfb688b55a123ab45540a006a3fbf138ffda74bc26c67e98b0b6db2f286a1170fe50bf3f870fa4df1b0f12a18132e503c351a471a4ee8871a685f4ae121a037e6b7a073f0e0bba39cb13cfca9e8823e7245ad0440601139563502c7c787887e09caf2883f40cb9fb316fec50999fc6772f370228a68d91163ef436ca6fa7673653b91c743766cef8ecbea2ebd2d8988f21b6748756bb00c094a08db8eadc30f687a91bb424f11c64d7ca58bb56eb2ba636ce493bd2bab8ab285cb459cd040a77ca0b72546c5da4d466b24abfa62ff3c6b65e0bb2d8174f2038d0145302b190a6cbe7386364dcdf6aa971871c23d4216af369bb26d83a32b6460857d3438d6a169047dabe3edfad7677be1f2b7fd82fecef9d7969c32956dce673281ece315757f0c4e9a5ac81ae9c4bcfcb67c884403\n\nInput: 4e7afc0d05e09895c03643e17342c55096c4b0b093cbf41b\nSHA3-256: abcbb82310cc801e5882001f11ad9516c726ef67242bd761c3f029605333ca9a\nSHA3-512: 2604063998c7e2669bf33bf47ddda0fe697ead4ff9cbe7bcad411569cedaceb2ab1cd09cd63a6deab26c157e6294a9492e96c1d716b79197887121ea6aa1d00a\nSHAKE-128: 9e1aa6debe9e3e12f8f89a7ad69be4b679f57eff4dc6691ca18d48cecc535045ba5ea2622633b158eb2dad673274e444f4461125b99435968821052521fe57f3f7af2ec62f252747283b914e3af2e1362342c40c7174205a8805be0203bfe852a74631b51265c9ce1b09c9a40f07422a4e6d3f82e8bb17dc98c793adf54493fc6e40b60d68f90abeda3f388968e3b7eb5e4d8745f806ca9283045581e9b78e5b4d7a1bb25bf38438921c446c2f598e48a5646591eb0b09dba5a51daf779277e25f0ca960c42999e20a5e5993d875580c374440bb1c7f019ef236a602ef68105d5ceefbdda214c062a06d6f646292fca0ea5cf806f0640b8d081f90b236da9689dc3699f8dd9ad065fc87a147aef57ea34b7fa239da51d4df281a85c88a74116512a6b02350f264afc0d978be13e971c028cce3781001a80a8cf6260e2e66d66a5b67c7e6924fe9c3ef43f74376175c8109d28c6ab1ef89d004ac811f88aab67b648dae5cb814aff1c6ca96fc002fb7cb33e483812400cc72fb9d75df1fa60b6856c2ec4457c09244c1ea8d4d5145e32d3a20631961431210d35fe9e57b31e2690cfc440d46cc9018cb8de27da74c7c89043e8ceeb5f05e1ff54138c664e507954fec5413852310435cb64433824a342cbe3d5f5bc7c5ff8a0a19be89d4193c8ae6908184887ed999cbd854c50b2410694999fe10a07bc283019149522cfc83f9\nSHAKE-256: 07e32c3debaf29b22abae2765409770c8f0120cb07314aaacbd6a913d5639bee56ba5731bcfc91ff0d2e9980678b5652d85c04efe93c8ff9437b1a780d7d21e4d26f1ccda2c9d32a40e63bca23d6c51241c515f6b1be1ea0627b64a1b8951109ed409b707e79d7cb7238d324c90ec26f6ac9166a1a839cbcb23212ceb127fe4dbd96aa49814976c22d1cfdf1dffe60d6a621887d6514c3e9fbb17e1c458da20322917caaa3f1af7fcbadea78b9a3f5cc25dc32aa07fd13536f7b7d7c476bc279346ec198bd90", + "23a799472524789b3a98d8b2a12f621d932b158ace68c73e54a877ed15dd7271aac2a825ccfdd90be73290bb2e2e266cf2feaee1968555d2085587e52e2b14b5b012e0dfa5bb580549c350aacc4ce7dac6cf71e32440e168f5ac35c9718117d18218f860865d1c8fc62606887121a0212abb23727dc0a041a6e79bcb2c1f58240b277f58576a84fe7271a16cc4f6655327b5b11fc8f6feba9d8b0cf08a6eada0d5556dea55dea6a89bdab8bc5b9909f70b9631ad7816ea3f3e076d049421b6f120dfd3ca12f0c6ff55396f56e901f59fd259957008cfa73c4a4b2023795776e99a4194ecaa0db47903ad9374b46530d82085b96a5ae683c814238c59a8af958963547190e536e8197e1d71a9e1a2322a5d1cb3ef4ff7db51dc12f91cf05e6ef33864bcdeb3285dc56c017981f85bee0d2fbf7667ab031e6a900c\n\nInput: 0dc319d9ac96a391c6862369bc918fdfb08f67e2cd8324f099\nSHA3-256: de0c3cef50531a1d20bdae04dd82bc6377073d1e770b5cec9dcc7be62ebfbb9a\nSHA3-512: 21b90e766e86341c43c9f2b4541b71e66d9cce2306b4f3e7b0b5780ade02d1a711be77eb6554f0bd358d6767ea0929d619b777011bfc591b0c9e91201180c406\nSHAKE-128: 229b77134727ef1ab4abfcdc0db57928e1780bd493dc1343c738baacd5484f294a98582494f46d770b43018b80ef8e70dc278eb9a4f138e1947d3ffb3040109cd12288f12bb211825c55fba549859f9f17081c132f2cca8ffeeb65c91f8ef75bf283203bf753c113a069f431288c4307ba98aafa86c8ec3962a4a3c14d44a21c7ab7b3327fc684077e498724a8ff033fd3a09bf0d2feb38251c206df21e07eaff050c482827f500cc69e4154feaf93d4bdb5ffe1b77e4d2b4286cac1f382fdcc84f924903f9d973e3f59ac87f56c39ef9e59af6ac3b7c54e827c3637d537ee891ed0887579874f15e0bac1e5e1da6c47b2f5fb36957a0fe91c6bc749f9859a8568a80f5d15f7c4b0229c3362cd86595d26d9bdcaf1ede6a2637398835f33e557f45a396ef2ab7aa80aadae2e241cc769429cb195c389c34f85bd43d7aa055b1d05579e2fcbe848df1d7f084b8ee895953f3f0f703bdbc58110483d12b092a59ab4faffc123baa460b1e985a494cf2c75e72d37afc56a0d28b6e9df09459c2c9036d4ece4b4f0d449f42d5ee3ef3cfff132274c5e860bcf9e25b628cfd34d0074c67cffe2f231bdec8e2a090a0a68c2f44dc29c85d1e47cb20a8e7ce5257d9398780a7733e0e62813d77186a32876a43db85d93e310c714f1e56bb6020a6d208f0602b69f8791aee42e6d7bd986095588e56989c2619f524b62fe669e6f736966\nSHAKE-256: 02b5c47eea0b809686c5b5f1fffc9543736ca0b169cd64e0c5f17eda795f0704dbbcb12ecb66f50f3fcd50fd94a3f79ffbc776dbe4288180e2296ab2b041a201109923e1b441fa60d7ec4c2cf56575ef6b2ba1b16a7d996f02d2abcf3ab416fbe2122b5fc698888d47dc3d33be304997201bf7b7bb497b87e12bf9d3efb04612a0a12de221525c93d6701d602b8ca0209f2f3d77d3926696cec2fb0118fab3216e6746d28ecaafc1b8c8d69124a4db9d2bce0a03dba443e708f443e9a9918c134fb617a0237db59a2b7b1ba86ce573f58c901f2aa549476746fd681f123ff3ebbc564a9caf5728612c52f52dbbc1c9589a93e9161226249973d42befc9849e8c774e72b5466ebbd4cb5f88f89a1c944a73612c959974bfabae7d34ca7d891c5c1386cc617d14e45d05ae8a9aff2856aff537e27272b165ead9c5f2f932266638bdfcb2e44788e64d11e56421fb4528e401c21bafa90562ff7e57ca660f918d3fa61613973c9c58f0b02a0b86a910710a1b10adca16f8e9815840370f84d408f7251de1923630710f92c7752ca4dc60153fc24564bf22c3b4aa51068895e7480a101ab4e6e944bf2e6191fdc28d1d5b8c90a4abdbf6b0165cc4185c1378688367dbf240d18a63204174a276c6921e2eece6d51496c3444560fbe812d8d1df7590bda36942ccac2ff0b8f13c91c7a7decae255981214463188ad9df0aac82272fd\n\nInput: 8e5a21913069202ddd1db028143c455d22d0a7146ae1f0319bd9\nSHA3-256: 9ab79dd9d96007b8ab1e8193cf55974b04e8fa665d9bdd304b33a70bb7b59127\nSHA3-512: 1a6f6e794f8bc989df9326bceaf9b34770c1c00ccd9879023f60a72662c21fea849c3023db22ebfa4ee4c731d8e5c8ff8e74c976ef94ef5767dbd424107c88b9\nSHAKE-128: 5fedcad6e307439586222b40f49a08ed83115057f0afa1adf3621ace8f5325e06695a4506a49ec97ace3b77a89ff69a3fe116c5dac95d43c150ac594f6ef7503dde32e747beb48149326f5592a708d729740cd74b54e20f730c622319d0910b0d679e274774b1880b117417f0feb11d6584f38f2cabd992170e24cebc955c8eec10f55e79a37706a9957e004a667b272e0f4f80a187cb1c63b279129d7b63ac1aba4db6b3b262e05e42f179f35400a34d11cf6aa5c9ee029e392c00931388d3f6ed7d716baadaafce5e8ff27dc500683407fdf603501e0a4a697cf8d465bcf1a95a639de3461555c4473f33800712e9142221f2f68d77bd871b012161f235ae6d216967d7d0ed30fd0a65fd1276cf953630687fa52d161e43d833a3af71df0bd073c63d3fe480f1934a2116f039fe952404ae3e6d7b6795d24c848e331eef3bc4859b9b899980fd78e8e8e5e239c6221a82cbb8eadb18f3d3a45efb439ede14fdab36c4b67489ad151d2766b1b9d288ebc956735787c1b1db65ad7c697d09db802f5218d2801363bf1a7dd97a7b636359928c0ba7f0aef3df536f81a6669965b0478ee1e3ead37f18c7c740419a6a761c89ea716f647b6d962c7f070ffaad6ae99e5a41d3f7e2157e3049be674b8f7b5b84154ce895735f92fdb5e2603e1e95ea38249745d8f7e0bbaa438804ef46579826c8f49e21511602d0b334bba5aa64b\nSHAKE-256: 2e94d95b8a8b0fac681ffd50746b91de654ef8763b7b60111f7822527ae4f9d19fb4c54a3f3982ff62c398a138625dd11b27802e161bcf0c8137cec630ddf5a47f9f4cc4b07a117398fb28f8ff40ce58dc0e1afb8e5d4c97bc452fb432406a0e0f352be770e4b1e6de1422898c9ce39363e22c49c215b7368b39286c5e75d11604d20af5e4e12afb1c24f4faf4f76492793d7e4e72ba916795d686115e8238bc41380c484ad073f753fe21f8575204fa9971e70976cb7bab7f4af9339b1b149873a4630a5aad4706c0315072729f0e25305df21561395b94a5bd4020927864e2931199d2db4f4d161f72910b69d4b598bbee34e26646ca1ad0b23f0e769021fd4f9006e7594f92aa8a7a5649bffbe3763421c3fb923e4e7aa2f845f7b7a97f1589405cb33f062dd198579ffbb52d0977ac152affbd74a35ec8d99c41fd069aeb0c5b9407677381e65d0d4c843edfa1c039e18036007d34ccff5f18e8ef3dbf0705357efdd0b6c8f5d1e245edfbcd2a6adca161d01955fe4845b2bd340f743afcb98af90925ff0968f82b3161904fc54df691227815b7f4a522852d1ac1f0458d0d81e470d8d5d0a0a93754ec6dc4be72890b10cf12e14f5e2fd5a8bbb4259d1fb30b7e32c1f40f5dec1c1cf3082e850d8e965695d6099d23f0086ebcb33be20755ef66422558abd25a3982e444610dd8439cd41bc361a4ed534405935f02ecb2\n\nInput: 5fdba563608c12748eeba272d8de349426e52c3be893e4965b3004\nSHA3-256: 54699ad1647da340b66fc3a04c3be7f34e538ea819b57f4987d469f2b90bee84\nSHA3-512: b8fca907b4fb8e724d4dcadd166813522866c6ecad2745ec580bae4cabc6ba272291fec2da3e4df3ce2edfef4463e566c207c644eaea5aada42b3c9eb4e81fc7\nSHAKE-128: bf96272205b208e3967d99a5aece30def712575548df530c14e46aa82f49a7c660947a97dfd13dde44301d72b273546d05c17dc970a2b68b7297def20b93eb3c0aeedf912c0f4cb7bec330ba0c39186ece341eac8846cd870bd872ef04ead4a1a53585569cea3563b3d09bec288516dfd028404f996cb59ae04529c5a69b9de783440ef91e9539391d7fa09d79c0e33815f31ec3f27609a46c783935fa407293906e282452e5b0720a73186f1ed71421558fe8396ac325b80ec28ff5138b9eafbb590e9b5cb0573df2c39d4332e9d151519017d320b96fbca32e7561a8d28e7385d28320d29e85265c8ab1229ea6118a3e47aa8fea9468a4c87761f7157492c373ce3b3e405c536519e3321fa7bcad21e57cb3bef52f7092078a8c84008dbd92274dc17bc5f79d8a12fbbffa968b3ba4489944a94591f005792776ee57d6f28f7248ccd16c92e3fed7810ea3a40aa241579bb59f10ac2d96bdc5abc2af554261b887c6c853d596f3667b4c861d33b0d55e2a462f4c791814d6d3a97a23477f67a274c00e06835980869a29ebe0644fc00dffc4fe43e8f977161fc2a461d071fca2283d071222858685174c3814ce30b8dbbd18e36f15b22895208515ed5f25b443d74d4f1b191787a3277e8cb71096933cdae475a78bfa711a1343db22f1c0ed9ece088daf35f349aa0d65b9f6cbff203a55ad8b5d7f12032bc013f8e73967ed\nSHAKE-256: 22da597be4a76adb8a1818a5e916cb10a65f103aeb194569eccfc3297bb82822fab958202559d157f38a2942be666a51eb0f74303b0d8d6bae8949d4cb1bb0d247dc6cd0a2584fe3ee85589678a5bf14414e4980a069f6551062738eb75ac568cd083777262fa563deeab4f75234aa6804ccc888b4373dcc1336b67db3b32a51b283e7b037e5b749e25cf49bb3dfee1f75af76317b0dd60c8ea785e05a2f477739f2a0e082e9374688b6dfaba29c44252e00f93f47f4297c858f220721a00b783f5fa8d4d8de39122825a9a01888c285f54a0dc54e02b50a77b4ee4f54a8472dc1497326d2b43c00c8a4de4574915c2937cbc9bb7957e32a9a0e7c1fe8f03d81a2374580fcd70a3a83c8f28409dfb2a4b749ad221c16cdda00eead1230ac0ab7cdd5311b5f3ba717232b9b62c03dfd1a928263b7f424ad4e8c9d4b8e4921e85814d4cec98a9786f422695067b47860d941312129a97b4dcbfc3dd43d83fc484b4fca6e53b7ec49e7ca5355470bc429e91b035526b97b27bfaf7889d38e09a9618389131e5ed3b41c29e0c67323ca9f912e9f6ceb25cd1b2d42fbdd71d1bcfc7dcf92aa50860960d80602fdf9e458d7112271fe0ae049529a1323f496cc62f6e5168461f33319fb50a4fe3029ba0ee2a619bb5a344050d49e71531d79d5ac10f53f2086881afc7fd496bdfb75a8e5a7a7cfae034ebe8f4a41e3facff03110e5de\n\nInput: 21005bac451d9afc964972ff66bd4128bff16e906b35457c5238e1b4\nSHA3-256: 39eda830533b9970760737c1ff84dd82bb0a553a45550c1def9381c7b9412e83\nSHA3-512: 444cae26b016422e89345938aeada69effceddc9429d53e8699c6d27e307f0e6718ee54cd8cc01b7d40aba1381883ac22c6a7f85c3fa120f066c1dbfe9fa86f1\nSHAKE-128: 26d6fd4817751f625d03d2a9341d5bb6e965b300f8f4ed665597655f8fc5d592e5821c1bdd4e8e42fa43852cde3592fdb511237a3662d76f78c4ef1878842c17caed8fe72948431a5fcfb535be25a28f21ee97caed6e9a7fe487deca37a40e5c6a1b01cfeb4da864dac364863f3d7b71c287d6b9", + "c7d8ca2e9594c0c8ff755a709b729530db88836cc846adf800358c953438ee4d7e013553e16878813c7b36fdc80c1ec559cd5e5d4bc240f66c4a51dccd1a35fd58ffdde5500b4f02fc41dfc9af65d27bdf43f1aa0a0ed11ee1e14623d4d8d9ba0ed86df33fc8319f897b3e2c313fbce96905979942f2570f1fa48af8d669535af6ec303a328d2e28ec940298b2b40559221f7771627e188abc991b0976f894891da1b5eb1662a75cc27cdecf085bca4482c052d4fe4f189bdd619c12ef0aa2194dd043fe3389e43792a68f5ca87e18edc805a5cb460d1209551c06c9aa5c8a609b5e969a50d66319077aceca29939e839864bb1e07af34bab26ad21e36cf44d51bcf459638fa92a2165a8b8b2a1d9547c0ec459fffee65a50ac221bd94eb32f94923848110c1febaeaf5c9f83e21c6b6db842dab1ff800b28a87af6438c2321119490c18cf1d57d723cf47d429d510ea21cc8488c906570257dade9eda09cde5741f2da86f4ca4f58a112c0f418453d68b5fe1491783f181d8b2d1f997cf28d5261da689bc6a21d4e846b2e0\nSHAKE-256: 74dbedf9c64aed6f22990f8472e1c99e3336a20836b5cb3596ade1943bba158d1427ff107ac8a578fafadde93541e88ff79c50a1bb468a2f31e48b08b1dab3ca9a6d517b7988a5e9d553cd653aabe7da9d0bdddfc925c980705799ca9698d027162547299d256a42f11b63ff41902bf8ae747cd530404ffae8efcef6f92e8f600fb2e56c29966d6063cf9993bcbc877211991c9f0844582901ff8bbc7502e4e2c1718efb31148955b84f86af1bd82efd9a2c1b8bbce6e346552faabdaf727cdbe48362dd04de7f6751a1149d3b14e7c4bfb2825a42703a128a1b330cdfbeba8f249e4c61630cf081049220e8e0e6f6c8ade1057e6469d6ab6a29be0fa8130a026d6bb1be7492fb5c0f55226985fd073b1d0c4975b87ad6fe5b829e285a61dc4a55c9cf9c22a1e452046f6a4e1768a518b1ead08cf2960570bdf5c3d87ec0b3da65a5233cf09d844a3a5b36512a97a65fd8d7f0a9367c5eaad1a34a7b6d82551a44dec51ae04ba9d74071819062e829a983477e0ae2a47ebd2d0113f7e30a63c411df89e06cdf135b050dbf6cd765bd22038121cad24a7c06f5433b749389f91b2c4b98fa80877715f60fc9682b681475eaea2726d9be7880e6af5b38c53af6c4876a4d1beec684663202e2a12ba9d8d1594b745a591cb8c242385de19710d48fd8b1191219b9ab04911f28470b6ac3333b558cb6a10b56ce679b38a952a3116e\n\nInput: 4864ee08579b78e11ce9c39a5d834e6f1286d541f5aae515c1bec39a7b\nSHA3-256: 92983df41874e898ce89437bb4a0a3358e2c6989babf1d1a12d1a9ff8358afc3\nSHA3-512: dd21b44a9e5cd0e25325e1b20739ac953f12da16751d5d9482947a25e9c71a0f772130797f69f531978450d1f766b72732fcd12b22f90e71d07656cd9748a766\nSHAKE-128: 93d2273ddd77c2886466ff91b62e491bd80d2b22d1aabb0b4554c8fc63cdefa3102b84a44ae99e60a3c556632bf6f2c454bf6c69fc696f0076a65ccc252ca0fe14751b9779c44bb46f83dc49fedb7ab51a69f7f58661a942d16235a1fb0576ac6e776df6c57f224b8f91a95e343d84f8deff43c4d7263dd2c44724142604998c65c25cfe666343d75ece79af73c1fdb88d7114abc9a62a4a636b07b69ab8d83894397683801e6fb1b0c06adab13b883c5a6d225a034371bf28622e945bfc64036375dab8597cf5d7566a64a367e9e7362acf5324864ad1ca930492d1df862bf9434a14c977815ad8e658f3cb7d06c0f0faecd2ab01727edfd6fdaab6ef3bec620a768e33f74663e96f1aa420c8bbb47e0bad3626dee4264bc18cf83e31ca683ed4ba112414f5e4c4b4d2dec8b48a47e4eb1094313b53b0cc03406003fd04a6104160dd07334a98f60f1872775447627c12fa194783c25c9353bc49c9b5d6a872368d829d461e75aaef59e408f4817116d042aba1bfb035e75018e29264134d2e09b3e0f0be00f12228bb01642fbe607762af0126810e764beb97fe4b7915899251602feebf76f5e9df24ba9b0a5465a8b94dc788629655a5b38c7275548f61b2a0add819cf3c11ea1112d5b2b5668e375b04efc7d733c1022c42f16c863b4c9a6f6bec119f7bcf30963d5b3a1ea8a936cf5230bf1bffb75fb93753dac8d4387b\nSHAKE-256: e9e35283c8e01f2b4719247ee1559de3d79a7c9aa806239f8ef9f306e225704901152a23c5d5636d4492e4a0597f716efa2347ec678a08346597c910381741f7e1ee1d31814948636175126379f2efe0d3afb3dd897df0d0de32a0d9bd13f31b86220c8c57a3ee5dd7e1d741899a57c5485bd7a3785e9fb44eedaadf5bd61adada805fa348bffc487cc188194fd08d00517db609c5c20fd43007b65ae8a2bbb91342e6c53f7db2457b01859173884ac30aee4e4145ffc7ad48f3bca8e448ed8947c66d863df1e46f554fabdbf22b59167579dc20ca7daedaff8409c7c1b157a7523c9de8be4b0367475f26ba4018bb8554c28afd9e7aae901d23188993d0f76706e9470eaddfc039169f0e52941fe1c9764709c80a887374f9db19f00844e7deb8035a47ce0cd3d6b6fe0b3fc27d9e15d9ae64299114a3f18eb5605e88fff7450f17400f29968a640d8da4c9c63e3e6aed7453a28f574553d86a28a12d65ab3292adc48812a8b4312b996b0af7ee055ab002618b8ce33142828181fa69205e12f35f7c3276d0cbd4398729700b6a141f6575c51453b09ec13abec4b141bf7b1df9261bafcb9cd319e9bba899445a5d82f09e3f1f5fd41497537d534c3bcd7684c5488af7e29fb1d5db3db12a7298bbe0396e6c255309d0feda66728fb5d241c344fe2d73b61ac68b0a74fa983c9a31a1504e5627bce52dcd2cf4cd7d13c89a58\n\nInput: 01aa4958d39bb9d00ab7800a81f99baa348181548e338b3e9a9b4d20cf07\nSHA3-256: 4df05bc94300199c4327e5e70c8eac44125bbf43175255c5434bce6553b42d89\nSHA3-512: fd459d25d4a5fb1bbb803413c88b3f4973f4ddb63e6806a73f9c5d52b3a64a2cee3c1b528a79b4ce1627d82cc81cd0a7876413779f74209612e1430bf7aa3483\nSHAKE-128: 582b756f5e1c3b499fc795897ccc392f110645fec4a2f1c5b462d5c91358321c97002f50091c08c0000901bf39768137eebdce84ffae5e4c4af56c93603e86fbfd2320f050520d0ed1b06a5c6fc6896eb22e10875804b428353291f4236c3924effbc5b77fb2cc96e55cb58546655ed658adbbf72527b726beab53ba6556c70c76d32d213ee58471c11414893115cbe9b21d9ce8b8f7d435df760b2b0c156bbfa9dde991fbab57cd842366661d17a77d2136058de9ab4ac8a6a6a769501c4cfb923f59eee7c97202009267b59407e7fb004b1bfcce1eb44bb5366d1fc44015ed5e889ffe4623383046025901ee8628b32dcd59efe4147e06c2d7b4209287f6acf09ec7bc18cb8e8793f28ac40baad522c27d14e4b2fe7fed22dc8ee6646beab751e1403490cd43fedd2e630e9b302b6db46311e29cb0e5acf4ff92bd7436ef79e0c84e5ec1b7932851c1096f307fe005c7766c6dc0928c0b106bff6526c76a05425925d4046b7bb747b107acde81dfd8a9b1963d8010cea4dcca888cbd68de54d557c3d64a46725e69613f85e3c8a0f140cf4f56e1da6253b3c08c89de8202a5aca73306823b067407b2a9d42108aece95352786a5ba5d26394a79e19f2647e060b10306db24f0d29c518a58d2ae102766ed36b798a6b8e2ec20bb839c0bbbad9e9f5f6c86148dcd25a8f15b1b486967de06aa1725401b22b9d3902b32c8e643\nSHAKE-256: 33f6559bc75f2891dc44530bcd793ae36852602c507a6d9df7db36be56d1b45fe15e6af912a4aa9cfa3a661fb5e52a75d571bbba2f7038fc499a55a84bc53aae96997431a7ee62256b811347dc8b5540fbed64e8c3ae93f761d80a73ffffdaa03e7ac1dce88b1cac4f3754bee0cf23b4f1b7477da3aea813a6c22ba9413cc0a4686209e451c28e71ff29ec5f796802c13b4fe78c64d0fc85b9784c92e331503d582671dcf3efd2704df2fc9e08f4c36b68bb3b1137d6cba9d67296547c9d7722d6e92beb83f651011731d785ac41f4845883360bb7e96542b138a21b109d66f59bcb959d7f3d41e59dc468149a2f9208fcb8d34066675e7f13e3363f9e60770ba1df6eaf2e3bbc812a4300f3bdce8c7c5cbd6720642974e39a3ca1a6c4d1390d6c37e6a31d90ed6ffd6e6b77de2a8bdc7df9373fe54e7ad79e82fcf5296d3eb3d1ea640c9246b3d177150f1c79e44f8c842b98713329fcd512cac1180765b3a75b30199c7edfb079f90ad180b303e996ccc138d4307a023cb04d8e69b653298cc310e09503c60929aa319334775d7e34f0f96c34dcf05bbafc123d71c389ed0c5984524822836a6cdad4145e2a52a795a6926a13fdadd2047e803bdeab92c0b017bfc10b290b4c22dfc638f9e120be274678032ebde6f010145dc6b37dfd8ce33755c90ed0c4224422e3ad8f06878d10a29a6a8a8e975cf2f81f5e3d31241ccd\n\nInput: 30066460fe3e141746cc61e728fa0f72b103d10b690044ce4bd3ad4f9d5572\nSHA3-256: f29cb96f81ff684d9a964f4396754c8a137e36eea5850c9b9faa346746d7d8d7\nSHA3-512: 552d35d6bbab94d0f1149e920b2c4e664a7265843386a8ecfb16a1ef1859967cdd4869435f6a42a992c1a32f5a5533ec9e4881263cd3f997f28eb639c27c281e\nSHAKE-128: d66ca38196b2d09b784008adf9423e63b64146564a62832e06cddfc13a28b2dea2f6db634c4d0d1fe6fb3924dd588e7ee3af85d71177af7a20a90cf5a80c075307cfc10cbd17c6e1cae5658d351540e2f722a14214896874c85a341297bea8e2e86dd5c94d197efe751b01a6a33316c294cd0b7e947c269f706ec6438610a1333b927f76dc9b01a8e88e7027235287446ba4bd7e952c0803993a2588e8002b678b6b547b50cc92d8d7e50a9d13e9c9537bfd85755216fa33c2b769dab7795fe10222f64afa6ab4696957871cf14fc397194dd199332dd17acd1987db6c1f22778fcf3e569e7e02e4c6a72bc1a7804287947092201cc0df05812e0d89608055082c77edcfeaacef63ce2a09021639e2b1abbedb7d0e2982731b45053dba70d736f597327402cacac3bcb18575901d322a78f49b75c3941655858c26ed526ffca575e4006a98b426f54f96d5d49ce77c092dc93f35be2f0be1d22fa7cc5e0dad08ae4c8bc1f52a74bffc7037269a42f3ca0ed67b6a631ba90caa8583520bffd675a3b7dbfb6d90423ec9a2281ca9f46019882a34b1ae0fb3fe926ac4af17d014d7e54d19150d1fc4fca5eeadd57d36f82aad50943151380d309b7f0bb0c7b73d2ff5ae09174c037fdbb2478aeed678724f6d105d9e95ba8b6e625300a415ac124d834583c427b2e847417053bb60fd0ea99c5ed7cd12cd2aab55268d1e4c30e070\nSHAKE-256: bae5f0d6fd4e3f9f243bfb799745e80f58b75205d049cbe40d13664979b8a2b343ae8dc78ebb10e77c9c133d6ba1989dcf08973621789f110750585dec6cbbd8c3051b949a323786c05b3be8e6fb8f6cd836335460cc88962d04e4e6a271b67e3dec0da0dd54865426ae32ae4104d05a37d35ab08fc047a032403c790c146668aa4f46a00974e06ae9205df10e26f73e9d903c96ebc657c1baa62f52587e201b124", + "7f152b1ac34ccdfd5977ab0e69760ec34bc6590eb8381d721b7a78ad059edbe1ebada3735a70c6e4acbaec11892f998083ba17b273d457d8bc1210f25a0add04df61780336990ad3ab3ace0dadb0a87a7cb3b16cdb1b7868b0a2cab833cc23c315fd42174e722e9d38ccc3db54c71cc65ef3faeaeab082cd33a7d9e9a9e8faef3ee6140bb672051af9209851629c3f3b2f351cd688c95538fd1e5cca8f86c23f0c3dab34c95fc2a510fde43744bd075c38b75237c9fb51bf3260d2182583773f4d2a51e27d58ecc7dddce01ecfd9c891c729c4220926c8acca749a73daa7a5bdb7fe137a9e91b2c55de1d9527aa3cf8587335c61c2a6871a62c22008a6831d4eba4e6ed3f6d5529530b8633d8c7888d28bb4f64f11fc1decaf9cc02a9b1795917d89aa9d7a7406efb12be2988614174d66e6a840c96e881808703b6d2194e685bc3358992ef7a14962c6ce9080c2843a99cd47bf15efdfa2aa6c3d13a253c\n\nInput: 3baaef4694b244d3e6bdfd5c37fc8b3905369c60fb0f930bc11c9ea374b1b5a4\nSHA3-256: 8155e0ca922f5d5a64dc70cd951b8e665327ee9c12b7ec433ca830ac8bba58ef\nSHA3-512: 407ccf40e6da04d40e4afa36913bc5e2727367a31bec25ea9cc0bac3bd2423ed139abb882d69f070f8b78f3cbfb1f4335b480ad802a1197b62332f701067b30a\nSHAKE-128: b66be8559de5345f79350f813b737da008a76c9028aa030bc285e4cbbe2691a098f0261113038fa567a5ad38a6c234fdf00dee6903a292b3e8ad95cade62768985a3655423b44020c51a31505b76afd509aa51a2b7c55c729e9baf1cd2a9f1a0763def0ad46b3e4a733f36040d1b80158cdc77ea2441659373ebeb900466dcc2bbc8404cca499c899f1cdfe81b6969e4c0ee4555f5009293f3a65cc37f98faa69171445e625947e60363115e4f3857f0c1a5bf39a4ebf61278cff04acf03242688dfa889a35a66afb4383dc36b5a52172d57104e7d5f51ad5d46be84501be7abad3302ccb0796fae9421967097d40b71a3a24a7b1b03569460fceea4904f25ed7801c0b1eac292806902b887beea84546c86998743b3c8c124bb6cc249b1a6dc516cb802e358cdd51a106abeffe3b34fddb8962caafd759792a7c9abe8658994e9e8ac8ca1287fe1b9b12d8f49f7ea03ed4d1fb2c2dca62016e4ba5caac452a93a51b9874e0f9c9a94ba80d10d34045051a98e3b0b56dd383b10e91a95f1d0673cb3a78807ae7beeed3fcb45fb4d3ce96d0ab0ec84a0b9c7a9b1247d4ecd9eef08a009f6f54ac7148a31dd93a1852c5b1e54286e4fffc6010681d95ce58afda9c7391887f002f5ce5f1eb64f093a28841f6ecc5463f35a9cd2dd7e5f61391864484b6fa2d62c6eed8b9641370e944e646720c1789937fda2f87b4c03c729152c\nSHAKE-256: c38ee443ab657a90f927827f8eb0a53cdf2be2e20b490af6babbec8335e1b24f5b973804fb3bb777666f56a4588acda942e1c7846b006334c46dba7b6ca2fbe234e0efd1a74d80030e1c1cb84a6c351951273925a4122671ff0afb0be51f9f615ddf5d090b8e6a99c9b37b8223e40864412983b91f96253a6d651be3beda5edb1f0053c8044b2bd71514d9be24322f84436db047437a72124b2afaca7ba284f2c9401c485bbf1408e6b98e5a1f4fd42e967d825b529d445381fcf657e82d1b05ff765280b04856c91c53776f6c83fb88134f6fbc61bec41d6d56158b804b59ff9ca2151dd184182facbe0e43d24d17a6977ac632f5557b5653a0e7e2ae7a5025b1d9f70d1b01bcae9092cfda1614d0d8ddb088d1d572bf5edec8b10522e499ec3a49699738078d640656147f1331caf7a263cf4086931ac8248cc715c6d602027acbc9977332d038f26c733c5cc6c07c6af9cd200105e3561cf69d4c4d4247f3638462780e999da919d9cbe4c3f45abfd57809e9336a884f079e7f8ec38b3707f78b5eb1f4122482637fd976933d6a0f92e82ee2a35d02b17498cfa5b090877f0badc39de4e858bb3cf1eb32a5815aac1459fdea1dddf43fc70bd0ce1cdb0697416f2ee3c506420979c1180d13305d1f1ac98c919f8bef5165149a7a4eb9ea2a149d923e8500cc52f4a50a74dbd671438e0e864ea812132d3e7040d057ff5937\n\nInput: 2f9e99ce29d4597fa0fdbdf7c383e790f60088c2f660c97ae5fdd8475f98b79e5a\nSHA3-256: d48b8d6763781da35eca0740540f7bc7abd1acc169e5849de8869d330df91b13\nSHA3-512: 6c39b8b25e9f82f36e3123244ebca307be7c0f8ded8cdefee1e91408aa19b55b2d31fdee033dfc685865cf25f4330ceb836f9f7ffc48d68d3899b63a71b35b2f\nSHAKE-128: 861b9d463405dc3a76d2295d94858d5a59cc36f9b636a7b6572a4302f002d13ea6b6d4ae91dfc04fee9bb27d14f1ec3e444ae5b6a41eba1a12f61e6c4f97f7e773c314cc882f74d72548b4091cc622ea1ef677937c87801b6ad7dc07fd422b35f2cf0efc12e75dd0c291e74049a6d0bee35091dc8fbbd1858cd5aa71eb171d1f7a7b6b8e660aa467452d1da4e250c4b0b1f23b4ea12eefb2bc4960d9826e61be7194a49314c5eb426e83023d212555226503d6fe371d0a3c718d713ec6ef599ba749423285dc69a7c01b9883b435723ce9bb1d22c0059bb507fe3a1630513c33000c99fe917e653247a1e4329ddf05266e8be858ca128721425aab6555dc840f6b29b9e5886247a66645af06739fa737d404ba7fd41807f360de125cd496efbeb087d40acf52d65ee745fd231afc2f79f0557293e960a1d97b1a0b138343c7dc9abc6bf6c2873775585ace3192c025f96caa9bb1531672d1562e30be3276d0491321d82ac1c5590e5bf114d5c6dc92722690c3490093a210d0e7dfeadf8a41617632a3e728064c7b22785fc0483ba4bb20c633ec964d5b9267bec51ca70fcea65b7b25bbf58579a833413e993b7ba466d9bd04ee3a411cde85b1801d96f37a0c9aa900a35630a266d8a1c604949f98ebe57ebce69d65288323ed684bb1885255dc04c5ce2b77dad448a3e1183fc6595d85b1714570a2ffe9f98ca320e7308eb5\nSHAKE-256: 23158da1cc6b70244350f7ec3c3a3605eefad2cf85b7b8d7f47b8ae4317ccc0acbb82c7a66a9be86ec1d720b5183b031d015788d64cba5602f18f309e1462ee5548e4f7936913f7e5aae21df9b7a11bd96d3b54526b17790f417790363d896f3ea6eecd264189ec6d5bd562ce90e51948c0ab4fcc9663fd22326707fa1c5799a96b8cacba9c6d65441428936bf523b29c2bea01eb93fc65f236eb310d3ce6073934beedd6a7bd065b193a21eeb5f206ff77d42da520f2470bd9699d5195de1f6f2e863f3274fe9bb5b21dc4be8af79d55d9854f45f51b91199bef28921f4555e81e672dc9023f2662852b8f9e0042890b7e6160354ea756f02269a286ba7c3935c18ad79c7711063a9bc91a046e496cb0383c26fda249853c3e995dee89947838aca4d1f65238b7675ff4db7b318db107eb09da4add22931600ad3a036ffde18077cfdeb3498e5e2ca614729267276b879a1b593dab8016b725dc0f708b83b4c96de0fd43da8384f53defa3b27fa551bad7e8feb5815ab00f8ddae7979b0a9d83b0d48324fc2769fd073f551325fdf4aa82faf72db484b7e1f38c7880e73572a6272b0a35b18b14be0ea756ccfb5e03a014ac54513596d0fe5377ebf033ae8a9e1f92afd228f6f7969922917390b72b6ab58559790b5293f9eaab58445bbf2a1099467ff2e7815eb8fc615ec7d2eed0634f6a418e9f413f3aff8856f5a915bf4\n\nInput: 44d71697eeaf1e246b7f6913ba918dc13a1d47badc8a34c2cd3b979cb5d02e20b6bb\nSHA3-256: d6b804de67c52bee73936e37eefbb986e89da3a2b4ce740cbf2621e137feb5b9\nSHA3-512: 8e6acec231e23eb621fdd6df9300c625f4e4bc781761b03073c88c38a874db3c825976bd095b5d7d533afe2f4666f47a3254f933bfc7947d81d9c512300e86a2\nSHAKE-128: 7dd23d0115e6e0ba813f6b573a37158b9fefa6c7c27a80ee6e1d1af376aa0745c1a5856f6ff7f363b9223976c72e14868197e15d1e1618e0f700c47448686ce61a06546d761e25b484ab2f8c848eccc40ed7fe6b04dd2ec3194806235ec46195f46af35279a3c965f32f23a450dc2e6c5f903cbd7fa72b92030fb30a78cef123b4d0a3f0b0c7f1fe4de29ed6e3b49772ac8626bf4f29404ba0b62d3127c6b610a20beb34eaceb1254a3cca64cfbf27183b95113461cf9134e75d2569c714625e4781e4cba0556036a2b7497cf9a465cb0b730a05e98bc32bb49598973e24a6c74a5152d7ea7038f37ffad3c3e852c79929f9db478306a85c1c85547595502f272e494f0a789539c0301b55fc1f6a0e97c42ef1f3fc384e884a98f9e658bb512f31c20186436c1759b184bb16d1557b65e80dfa61c21a625ee27b78890a228ed4515a6473b58e22fe5c519c873c6c2715f3cc907b0a720d6cc5359ae210b001781cbe82b0ee7479162b1801950551b07f249efc260860a2040685899477408d4855e338e4f73f5add727aa87949e093ee1709fadc4afd689bb4f88e20947f3afa3792ef7dce1711e20ff8c55ddea9e058bed8a409e6c314e730691488a4f91427ecfa33b1e6392cc9e73339eaa39a6aa62ff406c58198de5a384241890a1f6fa8c90506677cb4fba1b00d6c8a582bafa231d235ff197817cc45421517e42be30f\nSHAKE-256: 319eda251365f2e12d14640d2d2c9256d0e7d58bf602a1653094b4f3136aec84f1fdfb41bd2630e1541dc19fd9b37a6a4b5bd18d9601e9368d931f5226f3e300cf18dc1e188ce455c02db8e225897e22a64b488bc18f046f1de59cda01552917700bd8d93b006a143095f4ab989339841fe8ff4459f7e23271ad5786e8a55db61aae6859c5e688888f7ee43eb3e535a130abc01551656dd86b67fa7fc77223e885c42aaad774de7f6cd112ea51f0ab77261fe56f3adf9a9df3b83529a63170dc0b555190f4a2c82bdc09347e65d3d65fba9069ca2e4485d675b3c3292f36bb9ce51848926f06059499de9835665a1d88dd873cdd3cf849d11d6e1c22ea87f49dfeef7decdbc109115ac5558249275cd9f78177eed24a457d4ada0a557abe9668bfe2f47cd23ce6888233dd4f29a0d3411a7a0ced427e25087486d5f9a1bf4b0530f31dc0487b8c44dbfb553e816908ff53064dd4fda8c59d8ce9e0f8e151b0b19fb854d49be7162356cfa9e81f757caa25c3d321b56b1ba0b586c2b29c33b5195fe3a09a86b9ae194316098ef13f8522931a7632726714c7ae1f2e9f9be57e98c4c4d01333a2d56cc151074f99edc3a41c0d77ffdbf64b78e8ad35b3464a66c4afcdf27557466d62e3a423a215ceedd114600b37618f0505d70a6c506a10d5f301eaa2bf3ce57c2c040a3530e9e35921d7c46014b6411409c57aa240944ccdc3\n\nInput: c694bce845d9dd6ce314023a26c498e6dfa62810cdd2f5dd41c1dba73a4731a4bb2cbb\nSHA3-256: 6c3a66520463ea3b50be0aca73c044e6d67cb4920357b5e923e421f07e0618c1\nSHA3-512: dc32c5b3f7203a7245233df3de4ddfc965fae48ea97ceb33e0f9c8c76eff0295d02c557420f87c1b6cb4f2c9a15d4583149ac50ffc20fee06a27bddc3bf0a0b2\nSHAKE-128: 2a415cc91562c63cd6df030a8dbeab504ce8d1806d0b2267c48a7856c02142d19b3251896221b5c75eb586560b9adce338a5eb5", + "7035b00b68df03456ab12a97e5a151deb6c34e66ca37a327275c7f45f9fbe4d16790a316c28580dc4c867c06bb54cfb1bb49c0d8906dc3509c9a223588392e0f7416e162feae74207259deb1c09149bd64b35b09f27246af11bce03eb5be9b64f4d847690d78eedb89d511f6f854c2700bf41d9a95426b9789de7d09e9e50e3720b5934cea9fddf59eaeaaaee245504b721b5401dd59b349c54166c7e5e27875b3acf38fd4f752133aba03570bec9645af628f831f30c113f4000570d47bc43f99457ae6eb550fdb36f2fdcafa223c0202c7ce0f81e696b08770a70ea298c087637255ba9cf60c740c51b92ea8bb8e1faa7624977c65baf9975b8927f60d7f756a2efbc274d5f3e8200e54275da395a8500b874247975f0e7c0c8704395488b4eaa996e3d6563c0925600190b9a64d9b2f9a35fc7a8fb38c494435a792ed932c14d2a9ef4c4ba7681aa154c4568550796629d4974baa3b435cd2dff407adc1f384a557f093eba4d0eb854d52388f84dbc97658b43c1368ea0ff6bb1c2a228519429e7b0a6c2bbb7c56b61a110a0569a7e453263c6e88589996959504d032f512e711221437b7dd935bcd03550d88fda2b2ea4e138141a21027a95a09da7b8e1b1e62159cd260f38a783eb3d59\nSHAKE-256: de82b0282a47cbe163c7adec398eec7325f8df8a749591d09914a45030c636a5524ead02de020ad9af8f9bb596212fcdd6b0b6e8755bcb611bf388e7ebd4fbf7cf020fbb8d169d369b904f325e09707d6aefbf9a2434b75c7db54522307dca61b9c18ed1ea801d8d6b1f4b64f633c36c0cc2fa503c9413b662eca9a0707df65de85f32ff33c12823facd80f46f4f6b7001323ba8ca7867d09b014867b9057d600e45b01922df86a1956e284d3e40d7d863dbdeffbbfa03bc961c2b8fbd870a6d60b23463753457e1fb9977527b4628b4c6956fde108f9380646bd2b23bb5ae35c64e2190582fbd9d4435595ad785e5480f23507e54b8a33adce9b0537ca7097d30651f1be1b15ca38dd8ee010fde51849526ce9c6a7a74e02c1620ce6f86242c923848e678152f45cb1b8e43f04ed691106a4dbcb653e99914c8ddcbcc78520b807d2ca316937a29db01ca34dbf2314e342f065e7b850bdd5cdb73a2215133077a1181f9fda5a7ddc388b3b76b3a7d7619cf043b19c47a59d8c75750d057cec65cfe9e5c3a3a7dd03167dc7f3f2cf37d438346e5fe7143e4487993fe374abdce9975aac23fdd42d1b96df7ba694cc936dd56db58f507923d80524bcbc89c064ad96e42ba74523366f753e34c807e8ac5af1722e5fdeccbba2841582482aaa19160cf52b867b88c7c61f2e0a126bee207ed29fc923ed29285e78141cea198398d\n\nInput: 0d772d9bfbaead0d163a6cc4ed5b2783db5bcb4aa63d3b95094ed40b780bccc05e2e7d0c\nSHA3-256: 438ae74a49f4ef828a99c98629541652aa8c03819cbe1a27a6b9f7eeb462c3f0\nSHA3-512: c99403eb127b0eb40abfb241121f8e6ca17e0841ccf9af66ae3155f22a29a881646e7ca98c3c726ac34485eaee5a31d55faa7cf3348a75c1de20108115fb3517\nSHAKE-128: c44cb03a62e32b2bc704876fba5dae7dc61dd4ec95794599933f5d1a36d482554abb3fd5abc1dc460e48d184befbbb1bc2ba027c73da2ea65fdb4d82a4aa4957527d0d97c149ab9eb50a8a5fec7b8c18b11cded0b0839b67d92f1b13377337803250181977fbf851cb7bf899b8086c26522788b72912ae5f8820b23e801a57a84d4ce5dfaeb3db4159e68b1c7517093491e440caf020ff13c07123893d8399606d41f59c939068dbd2ea94c83359a9761dadc5a1889dabd04ff711eb013e6ce4bf0936531e7bbd620c4f3dc341b461dc5fb7faf00155d5ff3685043f40865ca7b8fb7a11a5dd21b40f41a27b33396b006efa2c1d667211777b9b83e078f705f48e4201c86c29bcc8e1d7b563f08339c179928478827598b3d8708832a388ff01c0daa4d777ddb8e9815ebb3e72892f32d099490f9083cb9c5b257bd520a9a2a76e038aa6110e0c90361047de26d4eeaba2cf67b62916561a06de9ccf5756e86e3fcd43cbf2986c87c42b3fc7989e28db739785783494d9937888cbaaa8da22c0d473c0475b02afe996aa23e65f7e664e60969761a7e76cc09da7a516ae3d6f01429b3f063d254d62f8980aebe22a5788f307876226557c58c4bcc264afcf71fb3d775718361d7caedcfa6eb1438f9bbb5422a14074a140e66127a30657a34ebc3b4857530a4f24b53168c7e4aaf9ea0c4e3cdf7134b0c77a6242d9617c71703d\nSHAKE-256: 36f48807470d7526051c6ddc3d7da7a827e68070e8e7853e7d77fee8a13aba817160de027102f8134de1d4d233923531a2aa7ffcb7701ed401e6ad514f4eaa0a956a6e2ab14f1c61bccc3fe2f2450823b08a25052eea26b589fbd2f052be6d7b5578ae9a773cf11f9d00847d982556a221692d89a5d6e8cd2cc98b64f5b65bda634a418d4c29c0a2dc8dec2d61280f3638562aa46dbc8f5d1bb140693042a575430e49ebab59d6816c085b3567a6e4d03014cfb30e6e2abe855a2a73a28140eb4656078eedf99471d19f96afcde898adb54141685acd81f067ea1bd50bf1ecdda3ad0ad3674f3305ea7a57e55b915c0d3db83a352563b7c381bb88aaf176ea1385d3ffc3686f0465c803c90da2e5477fa9996e042c1eb5ccf4846f380f039813f1aea19bf058f47a3a734d241e6e89adf2b8152dfbd958cbdd0c205199a0165a709d7a58daba7ab09b7e4b10203232d23ce18eb47b074374d22496eacd7222a7cdee85ae3fc8f3f9b216608e1e251f1dd4465926058764d65ced460599eff184d66a2bf7abffd49a720eb4ac6e6be62052e34b2388e458d26359189c35a4aafef2b0b48a17e108e696b4881d802e75aad91b5c0bc58797a2a9f14210d08eba3b5177e43dabfac5cadeecbd48a29b3945a94d923045dba482c9135dd2bc3275c25784988cb05fd119ddf823b34eff3d905f9a5e32e01e72e697a43460c011e494\n\nInput: 03299b44e194c177ac85764d575c6816edaa8075d3341218cd9c1cd0dbafe447427201ba2e\nSHA3-256: fd95d2e2b8d9696855bc4eb17c7f0c59a5db26670c9d729b2c31dacdf083862c\nSHA3-512: 3bf5f5f85d09c632be494b0e7efb408127668e25d30f2ec1a3d82c4efcd50e5f5cc4791514dac73d97607d334a26a995cd06f4cf13f50c1c981a1a1f6f85b280\nSHAKE-128: 84ed5bd3059dfba0a2fa56f8db08695c241bfbbc76482f3f52200a4c44358e050486e3717b2e74a856ca8b83e9aca12d1d456aebf519a50e858639a1dbd74cdfad7cad2a60cd0db3c3cb2ef5e94942f336436d76a15e26ee44e47ebc28fe059f58e89ce6ea2741be2e362a5869d8f3cf93918b88906f58d4a65a4381d92706f35654c5d4aa5b1dd7a1a977c089d1488c236232fb6e77ad5fb131cfa4b9240304816311460fe88175f71c2d575396ea052b84059855dcf4b14c9c1bcd6ec12f9360e8775d8a1c49efdb097f9ea369711bd82752dbe9b35c7fcfd8133255180f4f99ee30421b174ec5aeb9f1393d44b848ebb101dd5186218bf6528d00ad43e1ed892cfc3b6c66beccaff0b8d09c06b17eb4bd3f3826a04acf355b325fedff15696ead77c3da4084e99a9fd27626afe8f68ff9abded28139cc67715422fc5760e9092a417a96f3374939540cd80d5f19316b7db7dde09915051ab056678f78c9bb5df4ef232efd5824f7b15f52095a4b6919a5537ed3a992e522af5a8f2ff7ec875ad0b33dba05e934c08fba74d06ee3a90150a4b361e6540ce7d76d0fbd038e16edd949ab68b43ce0316991ff659bfe87709ef1ff059b68d2fad9c8cd24639ee6bd77f178ef4adf74210ccfc883e4054fe7350041cd7db5c4395b3a7f31a57b02b128f68ec15df29a923ed90ab6b012c46f286db69f6e2e1674599873d8f235a7\nSHAKE-256: dccb6f5534478981acd1fe0275445abfb9f7fb9d738e05ef51a9d9dd6b84d4711d2b3ecda1824f63272abf1a4c75a806f60f0a31a0980a35835c42cd3037b0028899788179c234a98609f70ee008959dbb817806a190cc51cd31b6a73b45778526917a9373c3d69756de76dd8c78fd0c7be16ec2690aaeb1bea1708273ba2add62c3df45b7fde538edb582729fc3fcef58904d838cccb3bf542b27cfc3bbd201a040ee0dd548caabe2fd0d10877635b44f33c49f1ec58e876e0e752f68efb9912161a0188704286291d74c29235f06c8b24a1fc7dacc6797ce802a851a0b51143e77dd60679efacfe2f6493a1d5228fddf58b94c228d9b417cdd40e8dca8881f5fcd88f8653d259325c77260ff8848a216c8a6e1fb56d37271458ebc22ca8645c6a8ed38e14f1a7b02b167db8db2a803964fd9b93475dc1e86487b0e0a29b3f586c53baa5fee027a96ae02a50a6bbdb7e808b6973a32165e5f408901b84d2c3fa6da7aafe5fb7c853e7c39ed6c407c49ac3b8ad6ce5d6656f973575f44374db477225de8698ee514c312a749b5335332751828b275738f954cee6810f12e1fae4b8debd41760931edee29c306f0471a43beb178a08133a674bffd68fbbd1957e65ba65c585776a4bca044f61a1a3f5536bcb0f60887a6345395535ac133c6b101280629abfc87b3bfb821ccf48b89a4b02b8075c3ed6cba2a857dbfa14bde03e\n\nInput: 84f640ba62910ca3ec1ac2aa24ed47249f28e2ed64f0d856ac01a59da16e85ff965ed1b988d9\nSHA3-256: cf2b0d953542899b3fd685facc8fff04ab576b3365129e3f58978c90be41b311\nSHA3-512: 5a40eb8b2775da0239801950517d37140e1aea0df0eb77ade8ca14a293ba3ec50dd98cd0660502fed6d4aa196e13f1b7f647873cdf87c04656bcbea326902eee\nSHAKE-128: 6bb90dcd71caddb89e8806f1568279d306b32f98c4d8b64eb0685833afb74c6031b6aef1445e6d9b24dbb0c320977a55484ba1d8ed77f17c5d2e637aff0b62cc2aab75c0f03bff91fccd9a05b59d0d21c51da992fa7fc5de0f94e322b3f9423c6ca780ab75ac0223336bf9d33fe9318cf646699e3820d087a59b8d2389989e6c53b73d6524233907169ec2e58723624d452bd8f474d15b51c5875d2252c641144f3bf2f61f2ed3cc12f7b4df59856321159864607c78c7797276a41bde4216304940d6cd08ffcbd213beb950491956e11726cab868f406495534fd10514369a568c9b4c7fb4d1f5a3600d6943a7cf599a6d63b320b6e4cab266a709ee4f67d4c120d47676b473dfd92fc9e8fa9a9cdb5ca4a7ba8063f190db5a648595ea4d94ca505a38909dec2a3179d2b5e6d29c3e5a4461037e712d12013ff6ad21a0b70d0130a98949a3ff26c973080e3d1e3e9f351426ef4f24c06d28a5b9785482f863c066d3649d56348b8b5fbc1efcaedecce7e35fc2700fd27f2b8137c0e38d74d2a0626abab9a8a22aee3a3fb32421646ed406f47e01619718793a7e28c0f5f4bfce1931d007fe9f363f8a58b3fcca3677982e5c190b2efcbc3ab18670dd2be383391aeb2b4d341c37c6ddc5e56648376a876648e8b259d3f9a2df5b9012f4ab0a5f026995ce48586578d16e042b7a489d19b96a20ab424bc1cad5e90114cec8829\nSHAKE-256: 141c74c023d8764799c190f1d609ab2f533d843b0f5ce416f403bb6b36a70a727cf5bf6271e646b2672a43d70cca655051edf9f8b1a65b29ab904d070cc7f5556afd0214cec6396f882109fd", + "68f86905ca0f7d4103827de810b93e951e4940cf28d2b47e4ce384ff6d0ecd2d9ad21451ec9f20bbb05062e2ec75ee41711e4014cfa55c90a6ac2eebd92feb4817cc915e9bebea6034e0df196c6963a381f8a464b28a2f0946c69cdd3ad049984a26d25c80f933a572c708a31e0654d791b6f935f5ea4c66e098ed72d85dbe2bc7ad6dead1edc7af5c5be258fb491056afcbf0f22bfd3d8f001f35c691f65c54ad1cd63f48ff94ac76b8afd6c4607635b5394ea9683ec1a14e129fec22cb9e99dca27a0b040b1c3fd5f93f14cf972e52bb9bc8a4329ef9a8c8844149af5bd471e18cbf5e9a0e71281239920c934ac8eb3ba10393d4819ecadb053f36d25a1d08d62fcafbb878377aa3baaf92a8ea2f318bf93897fe7bb13f110e7c81f04aed2abd96299a4f35d299e1bca6bd96343f9f0a97d7430734e3e02d9c291ba2ad8247c147299df882e1deb5ab25dc41c5e1ec8cecd4141282cbff27f6d2faaad45bc811fa3e934af60eb89c9c01f030ac5c306f1e44f824186adb90d26547a258734a9b5b4ff81f1d97aaace0343ecb050f3134068d5324a0666ba8ecc1d744b9b7eaf66a92a078c5691bf8b82be425b2fbd0ba4b14b4\n\nInput: bd8bed4f51232fb1fe83174deb66fa3f5094b5f303753bec1b39043e0823de8437043bd576b895\nSHA3-256: 599abade9819bcc0c09e3e73dcb51ae7098953ae064e1124fc18e1c8f07c646f\nSHA3-512: 3b11228897abb8df8471aba9466d863d57bc5bb8b0d31b59f1574ac77279dff51e5f996bc8eca7484d128a966fc4d6e38a376d137b54c0590df851f0de7a056b\nSHAKE-128: 811a0d3862be612c2ee8e75a5812172a0e620092cdcf589806e9f006a306e31a66bd96015e9a9e0309f081ad6750b3e0a4a36e15b235cb1418d4224506f057f5f6aff88b42ea3271ec40c8dc58e7cd7ac2cc6483b06dff396a85b1e7d0cbe533c3626ab12512b99ea0cc7ae5e114119e78a2719245445aae106f67d12580d6348356be53f004fa4b66d7c965640613e0df2bc087b141b09a40b871ac6fd8447d1000f9be0f028f1d58e6c6562f60ec94d02976df49fe3ac9a70a78bd8be9f75c37ec1bd31ff4de821a291deaa5f7c768bf080e527d1affd123b1f529bd35b0be52d8a1608d5a95ae5ae85eaa5b3deadf32b9c0732bfe77b799e6904e4cd61be7bc05543cab87a1d0367357f56b6a49870fc83d95be3c9c9ba4d06f4d0988c7b95ea6e1bf0cbccc58d2e086d2bd063b05ce62c44a1c8b9fb3cd042f9057d1cdddbf870e759016f263d95ad485e4d66ca4aff14160b4ad3d65e7481c9c02eac098e2e29b34541786e0919ca6c1937b13eae992a2ba395391d16269bb905890c6362d062ef12392aedcd46ec9337444ec2d3703033ed56d0e0db8d18cfbee2e96e7ba47ea0b6e2ef2e866f0f3bf3d28d0bf3a7acb7dbaff967d9eaf260bd6d4d131c17e275ae95eec31d42855f658a49fbfebff37a543f92bbbc50a04fe8b2b5a4afefdc2728367343e2f5c5046a338ed52f01448b38224b4797fca06e5c20342a8\nSHAKE-256: 400604b1d9809435833c8eeed07604d95722fe522a028272743265124270d85c5bc563c89e5e6ad7e2b9f72dc636d58a8df2bf6156535cb0f083a87d30fdc8b6b8044dda81f763fca24a8693a62b89bfac5e1b0094846625a554e196b51cfd8fac5bd714a4d0eefed570b0c280ca7ca8025fc870bdfdabb780f0b0274faeeed57a8656e51a48044c16110401971d7f0486bcee3786636ab0159ce09d286af01ba448b431f4e4805045539aca8e6b2302cfa988620d51cbe72beefcb205ef6b0d95d8b3377947ba7980c21b682c734adf7cdc3306157b0304bd53777212eef94419a0293f9bce0f2a0f8370924ecdc2c2cb8113fd46ebfca618def3ea8a103a3f295df6bfc9b87ac9d22a451d42922f2f9254817fbae13c58a57d3ed8dc1b7d1571fa6911a97ee3faec3b9cd776894919096639312964bce538f02a60797433b46858ec5504e5c61d69ee2b49ca21f3c1d4be150d89ae9e24d91249a094e1cda38ebe8d0fd6c99d6e2d82c3a6497feaacfc602db6b22f4e419e05eb4cf068bba3643c1e473da8a0fcf08662c84e1502f3f81d7ef6611470a629e4f9bbebccb908ddfa45419ae1060e104f970afed6c7756b2ad43d13f623f3c84baba265863d2ed26a20eca274561295672101a57e9422b9ec7af0c941932b21d2bbc3f5c2d9c3f0a996e9a425d1fefa28a2985fd3d53ed5ce5f194998c279d32f8b37ed129c0c\n\nInput: 1b9c65e6a2f87fffd9a57f890b61c449b0e3118901dcbbbf19ce044345d85b192c1dc61bdad64bbe\nSHA3-256: 4a60ad2de4dbb39db69d3edc21c1f672a3f82f0b9a2932c8a48042298154d13d\nSHA3-512: 17e45b083ff9d2d227599bbc07076148398f321d232b5e39f340d7fa610f6a360a57e2a50c6e170f940661212adfef7ff6d90cee1792e8fc72ede9d550f27bcb\nSHAKE-128: 8e1baabb938de72d8bfab0e5192378f7aac81f15d5f529750da96ba706537c6f2978ba7983602b103ca6a47431c7e04af61a94afe84269618cbc673feec65f9f53dae8f779c3eea8faff9998a04a89a3be63fd80c5412c52b632805346dd43f56b2808f652f6b36fb33205f789222ad09fcc3d25ee19fd15c4d6c10c0208240534f8a963784d3da1d61d570bc751c0c2dde94365fd4d57b33bdf7e2e17165242d89bff50c16121c33844a5a5a6eb4c12be6c835718b93cf1e972efe076f5dffdabac87d7dc7ac58c40db797ac249443c7e3f1fd79d17cf78992b9df5978ede51453ec664d855632442a5687eb82d58d8f180a4b00236e4c2ed6e5e52eeeba6813ded0c5ce51fc80d248650a420c000745514c4f6b0d363a816feab00502a32064f1ea13ef6d73f00b10aad47fc50e016f34fd6f6064ce13022e9a82cbfadc7d0412e0bad0ae49aafb9f1f2fbaf9b8e5f632de4a46a3285a40a8f0146b8772b61046ab4ecc39c57d662e6eee2f8037d4a7b612346ab29a3310096b9f00ef23c564948bdb0b3f7fc7d3aed7f4b893aa60a3078d3c59cb720bd7b57f96e723f47b26a1f11003dcb4e15eb1461374c9e4bdd065a02d8675b8b9eeb05b74676385c2adfc46fefae6b21d9587e9aa66de48d70f0de2ae248cec374508fbe2ac25787a8f2cc79a43cb39d772c0005061bbd06c68c284c3c4622f84c36357f08144c1c8e\nSHAKE-256: 87abc9e86b46445a60844fcf6c7fc59e09d60eb6594661defce6f8dbf2dd25689b27f990459bb31b63ddcc8a97122a0fbdc7f3b792eba01af0ad1e2248d319a284fd8cac6a91fb07fe3292b49786094bd76f560b48f595bc53c4fac06b6c1b10333d0a16823a001e2bd2b396b58a173cd896d487408d9a98837e58b80da674e4a1585c39d576a249e1976236ba8f8844112961fb92409eb79db494570d7949ae8141f0c3bd3946629136dcd9bc8b65262dd6cce989f280a333eb9774e129930ad0e745da9b5c7d6070b1e721acfeeb05fabf158169dcf7ba0955e965bfdbfecda7e2a657e076f511f1a76f8a805e5d3baae7da440ee70d74575923942add0327f775f722f282605751c44cc731f6f0b96c9257a59b81fc365f82800de1f432c5e34d2c61725d359a8724a2875a3ac6ed1d3c5aea608bcddef30a9481a264e29e216e290845a0da638c7cc92e9c65cb40c113601d20fd4f01aee38ef6767b2b2b4454f811debb4ad362a8dd0f95c18e1b9c2567cae2fa9c1106d557b2a257865ecd2be612b2092381381262db19703cb5a88f88b387e34676425bad2f52d009f217500969a99db6e7607b20eba512bec3fcf0f37d08dd8ec89adc059ab194a3c8fc1341520dace26107011e4f5fa7d2c24968f301c13f65e8cf61b560e556280b0b0200aa90bbc9d4af9069a0646ea197bc41a0fd34c5f0e94470364ac11bb33f\n\nInput: 101aa19c7ffbb9646ba711798c5c802861a56f0d712295f4f8bc12e5ef93132637cab5c69abce78167\nSHA3-256: c64464eb5cfb4311c9aa9f8c82e24d9448ddd04b59bf85ebf0fa4a3bf9a25fc7\nSHA3-512: 0f6f906a01c18b71a4f1824c26c138c19a46166a54badd3fa489de03f8ac84d0cfb5f571c1fc011b2f3716e2d844537f02ffa4931cf75be6ef02f73e082e0a80\nSHAKE-128: dc186094f4ce80166046d1916092e40e792dfe3bbc7273ad9d3a1e672948bdc97af6e9e1c945823051f10674b84da6805b2a787f854eda0ee680a2c3fd1f79a490e465be98c99b0b64ee229958736d07d16de466e1e56615a083ba9019a928a036723f0361fcc116010340eb1786123114eb0a8a2543347ed027ea096623172ab0ec33bd7466a977aa250351d1ff84e903d29cb901a9f08f76c9a9979fe722011c595ae169b401617f4673fa300d3f3490eba6dbce5dee727f63e3097707cfbdd89728435d8a05bfc1fe8d0fd99f3cdcc3713638fa51706e68e417c5314867c59a57b65754b89c07cd45207de8e377f62517a8ce259c2078b6142a21f76b88a606ab502ac0740042586e65fb7a9da123256183b8fb1790a3f298cfbe06ea3a9d87ce9a7f0890bbfa930514a5fa4208ce08ba673288a98d4ececf9e31d346eebe714914364bf7d7e0e160d5fd2841b7e577fb614fb13db7d0ac9d71fae11ab26a75b28f2097a9e4761f6ea3b9ecdce87944f7f15965a80342b611dad45caccc72ab1df962748819bbe4c70c8b080a1af8a9af31aa2ecaa3560ab08bc2a022537a3da85e6d1bc636d5d5ce0a7069b0d5ab046f4106e7699bed682ba00ed67ba8922a8310c208166f9cac957e91d7102421b30260635ec179a509630a1a95ea3d27ee8e737b49f0a8ca9482b24c2744851b6299e8b9a91e6b2ba35d4869efd5ed23\nSHAKE-256: b98361f3cdc74b392edb971879595a0a1b45362866599f7371a2ceb90850c95992e0f796670d4643b2032036e21f46f1d8c1d40cd158067897537f75c11ddf0542175227dd391b9f4dfbfae00a5ea59e79b8a02cf3f03056ebbcb5032b9fa0ddf3c986ebab6821c137176686f30a989fe450dd62eb26c87415f9976f55e3c3520adf35f34d8092b727ea8dc9d259a90c2fbc63f84c5b2c1000eedb2a74e5dc96f966ec3c4b5f9ee04485d826abcebf57ac50410612cbaa06009226a30f12248fbb55f415bcec6a2b27b29b1f976869e531c65cf433b0156edd412b2d136827c4d70c1b51e504703cf986835e4cb2994f1330f63ccac93dd88d96b3f3f194520b2df2e6d830b0c83359137f1b9571809c14f2da071f667fe8fd6b4651f3fc9b2ab49e700e9324a494637ad4595519944aa061a061f8856149d49b23882f064bfe07a883f6daefec8ebeaf39cecfb83afa8a1d6a35cfb41958e94489a5b83585863cd358ddb64a09097cb60725233b868416a5ee195a625b2560966fa440ebaea6c0fa82c15f42a92dd597d5721040f437e7e259d2f35b04fb0be9b6a0fc55b40a8fc5af06ddeb3261fcc33103eda07a02921518d574498cf7c0e96ddeb4ff393826c69402c4464d51a9c476f33ab44c90e51783e66fdb4d743f651d69f9a7113c643ec4a744326e1612056ef1229f800850f1573f5fef1ddaafa120df0bf337ab\n\nInput: e15cb62bbd40ab5f15fde6dbb0d8ce437019d12f94d70d862e7a0898a3191c6fc6fbf684e79048912a58\nSHA3-256: 924744167698219299e17a618ac449a520fbfc3030d7e02ae7171a96224060d6\nSHA3-512: cd8ee20526b1468c", + "47c6f49897a361101ec88770d18c2da7142cc73e97973e300927f130cad114cdedf7912fc30394c42dfcc94a29c68dfe6e3e291fb490191d\nSHAKE-128: f23e2976c279afa8e6ef9fb5962486b4f62664500721215beac6cdc1b3af773d7bdda23c5174f9817c47efc55ff981cee81d5d80357cda6d9a55183249bc9808cf7d40bd73db7e02b5fef215c2d5e373606b3c139ed53801ccbf8366c6f9c60c9019f164772c5576beb684b7e8109e16b739574912f68505b11cd1252af63c0982e7dfc858bb3e13de4b4722f42c7c418a5d1925b944d4ca56cd189dce312c0fd87ff663fae241b0ce538e96ec79cf128f44029f5c859ffe09a50be7ee441614ec5345e256d74654ff9f2f1c7198e1eeb13d2fa56b80e9256b7c88717038278644a4820ab3efed9f3b194efe9f61841368ea28e8f8a4a2db1f9713851131eef3b05732c92ab42f7e493822949d8134c8578c27b865b03c07f7a598485bbc336a6008c582df49aea876d34ca6f5d82e4a1718e0cb53eb773a3cb3cd9b42355dd14c9ecf30aca5e4f44df642883d17f773154fe0e4ad2cbeb7d3e6d40851b4d7da776bb1bc8c1e7c1baafe744f72c8925210504f1488ab3af14d375e0cad875dafc6a13c425f6f0025d61e0b2e3008639acd6db32470c1bdd57606717a287fb800ead123281d4d5fb27dd6c11626b4cf9409e39d349462776b839598a99cc703fb35c82cd57cc593cbccda0dc5bc6fded808597da694fcc2962cdeae7d31e818901226016f672208b3de4c3a20813d7c11fe66e43045b2bf2ae20dee5bd76cf8d6\nSHAKE-256: 180ca4d79a7b7ba820d46a067fe7c947999530a1151c515362886af44fdb289a5cdb70cdddea1c9252ce9baba2bc3a7342e0ef83e7b98587e0e9e8e1d80e6a06a52305b28528620b9152b70977e4b8cd9da628f878560923b05bf399ea4802cd2e5af6989f4fb033749454222be5fdb877940f6a349db9469f30ab8f75eb2a4a152e04046f22b86849517cd87435c790f39de89a6c288ec922a70a6f3c6deb4e97ae5abf25572ddb3236750d86b175067dcc7eb981dc4dd241bc9243ac857a21d047d97f2a3c44456e6cb6c7a8dfdc9d7efd14598b6a87b40204bab1147939dbb9a2136c107bc98a52f7a3548519c81e2f9509a937b047070fcc2e47c4a919e99e962bebc38117a6a2f055028f45f9951f41d2cfc6180ac1cb216b2e0c9a5a79a9559c3f300d74ff114a8f916de54fc77bfda3e1a426b84e402d14f1a25f7fa9d428e37b6d3350278b51544e6c2ecb8050f3b7b9b927cb2dd368e722a19f4cc933611dec6074ec704201a110fdf549dd5ad316e161a1df844a15b5faebc5a66b7d4516c198b27fbca3b6c6e9d4af8f97f4f7be9c83206f643629cf2d81e91f980858c92a8f2557d4bad8010016590f5da8d97f3ce72ca3b9b769e37bff26418935b2a0f2e55acd7fdf32512c149a924a3de44f5b778cd9cfbbf7a9b1d241fc94f8e0bac90b126c6a093bf1a351275a230a6050b55a769ae0786291c82ebd1f4a\n\nInput: 5a4fedb8ea111e4f47e81ff8f2bbadfdf1c194bfc798446b7d46ffdd4b385f228f4c9b4f39f9c16f4a91d2\nSHA3-256: a7a605a3cf851c2080a835c1eb8383a5a719887443108acbbcacdbbc3e639281\nSHA3-512: 68acaba0f375d73ef9b7baf86b462f01b19a30885966f9ac9a6995125a6f6f83bd983959d1b432292766031f9ff4e7cac1e14b6ecd2c82fd3984807cd552ab73\nSHAKE-128: 5c143f2d4244319ffe8126568e1bab4ab71c515b1a91db4892b0961b59dd31f6a8d864d8eb4efd77e942e03c7c05a54129e301fe43e3fb3b773ec3ffe64291133c66ead5d3b068b02ee1a59d7347c8493d28798b0e9bce310f5681df35f026aef9081f0011c5f6dedc0ba4ab1d9efd0bfca44e770dfabdd8a332f9b3d52c83b73aae4bd75317a0836efbfa9cb369a841163d3496b13c036aabe0930d24f1f1a0d5943dc69ccfbf98cfdc109692902b72ff8a9b6edb494d51b1d7e58bb106799bbe0e37c95452cd47709de53653ddcc41c06bf72cee7d2e8823be52e9206ca379cc8e8f5a64b7f8fa9d224a9aa08c4e93649e45385a44a4af04991cb5469176c12e7eee34ea37219804cff241dca4a4d4e3b306659bdd32f4d203f542e3f407e1852e899086494714390c99b4cc07e7258f5647d677d99bd19f6136b075332daecfa31d3f802462e1e35a494188df5cf5ad68d6328fb62e299475d5f95a80a0dc2eb3965874cbae9f11f58b3808b20ae1120f74e40fff91308f3958b0016209c2782d54b0fefacea7752ca4388566cb5c5e3fce0f8a5cb830f9287dcba7c15b66ea9f1a0126ea24e5316cf09faebca41e231105ccba2c2c287a2364884e3b4f467bbef324f5bc6359862b772641874ad8bef3ca2fc43d1798da890e2b303cc957f5197e587034c3726d001eaefdaf571fe5f634a7b8d8a0daf5b1200c33cf9d66\nSHAKE-256: e30a8bdda6169e84bcca9805021cb2522f154766200b6e796b4d9c261aa3d977e68a6d850946e579c04788d1b47133bb56a76028a4da881a414cd46d18601f46aadd7616850b895bd3ba6a70b9dd58e01e70a5bf9e7e96b273e177f93599030f749a994a0510c08ef4fd205d2ee7a49c5be53e1df20817299997b10311b897272f2cf5d90b1bb9b1395462332a561ce32adc09ae8f6bd9c3d496779f6a5e9edb69c51d05077a8e7f489065c1630e351031dd6b56c86fe85d57dac0f63c0e7b846a31339136530566b55386c6cf000c3ad7c024a5129ffcc25bf272c54c23ade62b159fe9166eb480dd241682d875274f3d0425a7621d4976ef6db852fefd8cdf9e7fda64ff5b6e6aee344a66d961e2e62e266080b73b0314fab5fa18e6d4361c508c5592c436c8d0c0bac284bd54d5baa3b49a239fbe5efdcf28dd7caf203294f6f579f5fbee9ce08d1b1eab96a0c3497ea5dc9143db813c760abe537cf8fba09a90e5f014df8b2c131f4a1a47c44c3026956a8ded0b87d8cf1b0c2e66b2b64afc5ab88a19c8e19a88de3a83e949b012ee450c079b519260760382be3b1eb2f48ad68eba33fc66b1fc9a9cba9e621c750ffb4ddf3c7f1a436e732f1b7ecc88a84f51361f8545dbb0edf43b1be0b2ddcb960d4e36034b9395bf7354e84d48a1d5fb0f77e67cac8df546f40dec8624ec63caccb2d7d82bca1686d919e182e7d86a\n\nInput: 35d464596131a3fe25997c1e3bf8a5f02c532b934304a5e42d4759714f8efbbe83f7cce78118320bb7462eed\nSHA3-256: ac930961cede24899ebafc4552319f6e413569f876ee3177a46437d596dee1a8\nSHA3-512: 8a8fbb6465c5eb8a7960a03e06a6d990b33981481a8867829195a3b8deddc8924319186fdfad0080ad13c64d62e8e8b8db92a18693f2da143e80a82c27c9ee15\nSHAKE-128: bbc78c2166cbb08c5bb4f1f01ed532b0cffd73790a8ee0aa4e0a0427f6ffb28b994829ceebac951038ca2a0a97e0987a9e9c13c6b500a4365a5c5749fb77cbda6f06f1d84daf9a0bd150123dd6814baad12bda15420c88f3205f83c8de707db3b642e526ff2b35846c6ea2de1e1c919a0ed383a147f1da48940a67d7a5fda7cbff6c56d35312c85f6c1c1171b4179ca6873948abb57cab2d1197f3cc8b2b11db947c6fdd43f96de8f6a2d0faba6f30e218848d1f3cced4125dbe22bdcfc534c3a1c28baaf12d92ec215c4c339ea9c3fea17122db8f4653b72de3cc51d379e24ab46c52e940a2dec13cda9002d463f65a09937d8eb8224d335c8ae94f296e75cccb0e1fb5c2d4b4d6264fba84e5abc0efe29c1899f3052809122eb356e902474e6eb83bd89217b15b096aa4c1eddd0c25aed4eb2c83921ad2888603f0518ca867a6704dfbf95baaef53c0d9f7eb2a6c0a109ea93b08a65c783dbcccfb4bad8633e4aa3502e1c136312ce0929820db0ec40a7c0907c999d651c0f64bdcecf4db65cf259074bc6775a62fcd11d4aeb17c913eb7ee683f5a5ca0736dea140fb5487eda84af91efd15897497d4822116bd66211b00c8d49ed3498ec44419df921c8af9b73aff5ad00a0ae0f9629e398afbb16d42d5733235766f7e36abf8550bec2a1d0838d60e2f4eb77c80401a0846832e12a8eb4d7dd84bf20a382a5e5e2f5984c\nSHAKE-256: 904b686130e05f0ea1d070d3999f3374d3f1dbf717ac9a837d8df362b09a3b8c1629d228e246d1fb943ff6b6ec64ec36b726cc5c2973bc0cc92009c525057a10dd4f939e2438089f66b03dbacba695f5c5f2c8fba4b53a993c63ae3fdd265b4e6a3f6e70857852808ac5620cd99db39a296d36d5713a65527e5b31bbb37d55e3c5f630489f43444bf393fc89a7b42a33370cdad27dc6a2722b29c173b4e2d5dcef079f0585334162d3ec99b00f01bac49c04f1811b7c50921423ed2a2df07dbb430790cfa815fff4616c8e335b97c61de567cb9d3764bffca861eb2f7b5b28889658addf477a541f60d614929fb010e06b78dcc1be39bd49bff747cdeb453eba4c64ba0161628f2cc9c0bad25570d1e36cb462d0195a9a624f7878b78f654904407bd4240984489e62d676a2a5efbde42982c79cdfa00367d4cdee04bb4e55b479055d43eb76193caf840392743a6ca25aa29598bfb65e8d1c6227e50b75fcdd7dcdea82a610fa5367d17b4e6cbbfe3040ed8232e585a5ef2002902bc82921b20f94c9f5d527d737989ca4c226502ea0a852dc0f1a6c721146ce99922886d03b98324fdef187f2f101b7914c7fc7da08e63f3196b54afb2d77067729154298a3ee30834b6289c508b302cd9da89b48bf9640bc4ff97cf022016e8e43d8a99421491274d6a8b8c01064bcddd004e1e3e46a175af59cd6fb01fcad351f00da0a8c\n\nInput: 4d70d3bf7e9238943734230177696a09f3e84b1422ad81e0cb096a55ee61bcc3f13e0116dd8da4c389cc2116f1\nSHA3-256: 96d30ce0d1d88e96cc19cefed4787d015078cc6425617a5d56e2cd0b56a658dc\nSHA3-512: f9a450c4c7b0494b2aafa34fbcc0940ee1fd20cc15c37f216671e9027c14a716c5e9753b376992e3903db2ad034ca4c88eab591e03616b4fa203b782984af951\nSHAKE-128: 4596c587904f1c424d126fe55c70450193a9dfdd3178a285f3ba46fcc0bdbcf7b28a18022eeb0189d90560cf021956c6025194ab1d37bba95c0d9a08cd6cd3ac34eebf89f1f4d9d2016ea98cbbee3efb5f76639204be225c635ebdfa6080c543719fa210252b8be729329bdf39a15e6403b710918d8eff4db37a376bc3163bc8f8bcde49dc377c318d81b77a03d148079a5be6f3bf6664e7b4fdb827073fb9de892723f3be19ccf9cbff923015dee4afc1fdf2e592a4c9a6782b4ffd19d579498d48752249901772c48d2b2257e4c3308f95cd0c48222bfee7209061e9087232c40787fae9441a0f4e7711dbed3905420d3ceced5f633792883b8ce541ca9afd54166042b90419ffad7ebebf89fb40102d6946f7038e88506db4a666880384c6f5e1952b2982cb7f14e88e1def7bd6863d0ec867f4992e55891f018e517830cef1ed649039f8f3fd2783c426117ebf5a1526a3cb60702fb92e52ea6a2c41ae5225fb71e701e1105f7764cfe6c49e45ce27cd2c27efffa40973f30599e0da7d7d440f42a9554dc1db558001ce61e9a22cc3ef55c3b90f1dc20801cc6d092112bd1fe9dc320a767b130704a88a17f78bc3e94f938a29fa4079dab60af977edb29998820ba5e7b1ba79e8548c6", + "18a846289bab0baa3ccefd830deede0baf7c64bf5da46ea5656e0797cfbfd71ee0a56d92aad1d01d50e4a0f3183bbf67da6089e3a\nSHAKE-256: 3e81728121f9f284532f5c48ac9b4dff1a51ed61e4abb5c914518a8edd45b20ee6a84b024c8325492207a3de24ca31505e3d70a3ce1edac1bf5b36d0033aa9826c7a138a7201c829cf5ba2df57ddb5ce3be001c51e758716d513d4ffbaf26d38b5740fe8889b601e27a3438ae58a49601da7658aa419c8a963569ae7a25677a44560039ffd0b3869543ba4252f3e8eb33a41dc24348e7707e5fe207195130d867aa6eaad0ef93e619070a6b31f775cbe113d92ee5594d591d0034802fc681a8d25479e79bf8bbc7d266cebe70e161f68489c1a17114f34932d4293c105c2f2ffe8cd274c160de6aa11416c43537712b565f71637a62af1de859dbd1dab350df38c0ffe8c23542e32be909a821ce770587637b1b1d12fe86cf1ec0c9f8a9cb8ddbda996100008b05eae66e6379e14044fdc6daaf1ce33f616f68215a22699eba633767376a9b77c89dc72610d282721722d35d4c4b34ebb6259a9ad554ebeb5c0a96768403426e53ed0cbce8a070a81dbbff523bb76ac194914092892d0af56ae7668d637648a2156c3179d1e30603a9c38b49fb0414aa67de4c68dcd1e30c9d97d9c42940f645f77e1be3987ce3c2824d41422bee9603ef9607bfe6f59ced39286dece14d656cf6c6e09ab16b95c33a646ecda8ab9ba4de6ddfed7ea7ab868c6836caf8d111fa2af56233f11845d1e728afc80a467a939fa6886cc038a49df4b\n\nInput: 2f6abf66f6839ae507d33d1ffca3c8655509693eb09073d5ac0f4c1b906fc9d2aeaa0bbb3d0f88ca10d3e4e3bbd7\nSHA3-256: 30cb41af84471525d246779b8fab405e1d5fbd9fd29e7e29913ba72fffbd12e7\nSHA3-512: 1c4c599739feef90c4bef91048d235e05bc69c2b74b93d1b5d47f7531c32a7545d6973376e90e50e37be82c7a60d3da313d572aa16ded535b365bc5cca75eb4f\nSHAKE-128: 46c4b180fb326cdbbb5cca502765396bfdc624765daa826be979de9dea92c5df86f86ecb9bed6f29f6728a1819d64a9132fe601b81c28971fc97a453c273f47f470d81e2679a2351bf5672ea00ab56122b9e732d3c64ca3e92626cd5bad06fd5f20905182a9c8f40817218202b4d11a6d10e1bbdcbdf96998e5561897f13761255096d8feca1cc7cf5da36d36de737c7902a89f0e984a642de0ae0efacdf8eb325486777169319619e3622270cf271f619cb6bcf99b234fc438042081c65a8c9419e2fd0e2fd85c70dc1a6f9b11d53396c7e6ecb6806ca02e7caaedccdc0e89a6a89acfa63adf6fd48677e60c1a3cf71d7b59ad300934b63b9a377ee59f5f212db1e6ce0f1fd5b94d7d96c92f15dcf8c0cf4523107886211aac3cca3590a6cf101323a26c89604d63a97a349b80af1eb27c7a637d31e3bb9f50734a884107209a6a1e2206926595d662dafcfbc033a7f31bd6f48567161d3c1e3b740f11ce4b2c2c76f70a3ab131acaecafe584820bcca84fd2d943191f0e954096533a61381bcf503c45fc6c2868927c1c390f753f6e7f722ebb45309310e9b59ca2328d72bacc04ac1ed1c7a0728c7fdf71110fef2df34a11cc3942f004e64b0fc0d939d1d0cf41bac5b8764adad93d6307adef39334de5c85dbd52138f9b2208d21b2e2ef534de8d098176073178e6d592345fe53d158131cc25ff55383810d2fbda44ffde\nSHAKE-256: be2eafaa1c0ec39d825dd62b7d7e53ebcf945a8f6cbb3fa52947d8a64579853ad1e23bd3a9443a1e5b36c90eb5ff0b71704c743d22e9d44e299fd7ad83ed3f447bd6d8f06e84318a6ffeb46afd01d32d72e2be62b85ca43b54df92cee98ba4ecbca30afc9133a2a6513a0b309905d00e381986a912305450d66516e10a6f7d8965111673823347775c48f80063e3bf81dd267116957998dc5c348b230dd359527a087637d0a6c724a01736b7be491521cf46ab18ba9a1045208a1d4567480de1b503c4139e02aaf3f37144b4def04aa1dd36ad26dc604871eefef521e82aa8478083e1d07dd67d995d66529f37bcc1cdcf6739a23ee08be7339b9df32cf50a6f6de6030557063e0df18f7c4343d1f873bfce918ae7613c1888bc095481e34f872abd2b73bacc96ffda63bc8659eb97e894da5a50a76ace391d35eaf5492d16278bcfe42ea58307744ab42155c93f44f2721bfc013fc7caf6b25231de572fde03404ccd3b882839404835a91c9b02392fd1d91876d72ad98ac75ed2d91310f530505a5aa1fdbaab54ebed14b689e8f763d6a8ac1d5c2a085fb67193432f03b38e83fee0aadee422ce531d0dc860b5714d698fcdb1837610f66f699476747375c5c5d297c00253ae03e97d42bbc165e633601408aedc695bd14ba4a767d79780abc2a38903135737ebb91f43c7834dae7d92d2de1ab0d11af9a2f0040f107d482f\n\nInput: d380c1db053d9c111d49d396393858158f7782a1c7f3b610386a64d6fbdc13a6f0bc0834abcb9c0c5771502022480d\nSHA3-256: 0fe6b5c2b370211a270c2a769da3b57370656da2860f226899229fd5ab345f9f\nSHA3-512: 21bcc4bdc76fc9f8b42549af3bc27c8e1941524a0f0474555eae6a2c0d6db5bde5b66ee41e9cfc6f2a7c6b05c08692a48a436a853441aa139423fd786defbd6f\nSHAKE-128: 406ef25d8c529b360e7fa01922896bf7c997bc17ebd12e283df2347843442c1547bc113806dd66679b3c77665bebb71fabc3c0808ceb13a3322162eb556356f0ac64f4886e538e0dd41eca81ed55ac4179e5344e34f8a056b434fed04af1dee2778dc2a59d5a1811f92e95cecbd1733e4ff67db9a6e65a81cad569914a21a74809aebf17087f9c94d4ec55a0463d573521fc614835750068ae825a2e3543d3f8e0948cf3d87cc899a2df359579bb0f2c1872579b08f84fb25b1a86eb6df7d24e63bdc6cd83a465a3f3752fc08fcc93f3c93a121887732886c11a4c81cf3da554c90614226f0bd3bbf18bb0f4c77438db998a854f5d8f993d6f054525ee0a6cda5e204f95eb050bce4603b86ce821b9efbeb8dea50763015cad0f703498779500da88a1094b95f2d2519629eaf3b4a8b83b0900e06e2b3678db8bc0299970ef53e000a8dae0da4c9f8b102bd41ebf62144dfb86804351a49a748a460b4b5a9b2d3f964265f353fa8b00b14135756d3443fa758f23f3da7a913f328ce6c85449306bd5c5bc9ae69457185cde331bbc6cab11c6a41260cb60b3161ee5ae5aed4982f045ad570597ef7fdeee96e848b036fc8f47920781d7b9f499f102f6517bbbb62110d5bd04a19cb184edfaa5e953b02a523511a65fc459f362aa4c10a9ddab248f086efe8bbd0dffa8a78905d524cdb059d354c737faa879dbc91550cbddc212\nSHAKE-256: 266523e1a6211719ce79de23035f3c6f137be6f254011696abe43b9e13b856feb9436d7cd4b0ebcd793a2a154e0f7ba86ddfc208e3d004d28f51ad919941ca0f8e36f476652b0d9529f6947afe67f250929a74b9d48d83cb646e505aec45d889a2b7c71e36e19f4a9a2785b59c62050907465ba2ccb219e31c8cc5ef3d9b112d64c988bf5eb3b239d48ed73b4371058b03bd30c185fdda640009e453ef7058beeaa4cea44b55bb30a945296c6fd59bb8232305374aa71c93cbc116900897bf9172646c124b1edfd136bce795852c2e0991c9a851bde757a65b1439696576a147c7b1508c0a0e14b737a072432fdd988841c2ac372fd990d7deebdb5a6c9e7a13b8d2d61b4d12f115c1fd9e7fa8fed7eaaeddfd92969e41ed8eaa02e7d26bde8ba46233764fd3a6bfd4cb53b893adac6a72350f8b91827c4fefa1dd7bd9c6dc419505823dbb0d6359fbf23f0a453b27cb70dd705165ba0fc7644921fa9d06f2407df2c4682dcc6bc00dc7a74fd1780283506879a220c0952b63a97cb6892c5d6af0c81a487acb50996faaf39924b5ad090e1b3a3320a80e88ffc4390dd2645c2e40ff43a3afde53262781798227b7415ff77397946eef420264c4e935f1a97e31dc0a6b4ac9e4ae4b0803b929d1e3eb24a3a977b2ee2bad3ff7943b9d4bed6dc968757a704d57026347fb6996bbc3a7f73fabd6f28c25a1e6c187f9798d71608a\n\nInput: f39fd7828e22b3c7b91fd885b468ce3b6a790d70dfa0aae900d85b5a55cb09adb6b9616b29f766c79a0fa5f7e6d895c5\nSHA3-256: 9237c1a9cf6a5814942d425d556216234e5aa0aec6916e914b2a3819d597aa75\nSHA3-512: 8c1e009893ab70e8e0f93ee450478a36a4c19beee25c040598a8b77d94192d8bf012d9eca45d7c6948f67e2c4e13f21e7311db255ceb32ee6f5c873a49d50c2c\nSHAKE-128: 7841d70f81c0d5129991f801c5a9f0a8ddb85692b48c5f90dd3852db9289d0a328975b9ff360e6a57564cb0367358036633132feabf6c4a4c27dee7189472e49528666563c5d70f8e5c10b04e1ccf061d8d5f5cd42221d9937e2cab5197285a3d1fa282fd78fca9ac9be3a5f4654cacca9ac2948688d44cc9981174420f036756b7150868d5cea6e34d5d05eb8249ce7787d042c8d40bcc418e9b1d207370c996ff2beed191152ab868e97996d7371f0990091d220a16d94f839bfe9a7437a3e9bf68a5851e83db0fbb6ea796de8bb3751d5ed1f145e1f9398acfafdf6be9a6de6a200be7a28c52325e03ffb04b99c815787090d5167ee688d56e8d3f7b8a1e5f926814df6c1f71a92fbf4c3884363a961cbf4841f4f6ea50165b5fa81b2f44b508feeb5b11eca3bb3a092423c4ad2c9d2a4518ae64a3b6702d5448241805a95c67c8d9d7145c95a45dd375c2240b4077d4a0e30710673ec525d90d37d881ff899c8ea1215ac9f124c7416e153642a1ab04da80c64216ca3dd117ea55b0a074fabd2988a6c24da7d1764fde36090f4188c21d0cf536eb5ea9de5ed2bf8b7751cae2f021f741475a1eef1bcf811cbebfce53598309ded5ab003c256f59eadab25398e3175df1c980a392c33f056a0810555772fb495577a73c5effcc401677a71832fb8441da9819ca1c01268e103edca142be0dc9498ce470befec1ccfbc79bc\nSHAKE-256: b3b80256e144e30bfc7eafe307ea0c181a0be32f46b557998fe0775e1f63a1257789fbfff41f49a1cd7136e4e297a0625e52cf063341f6bdfaf7dd2dc9812033db7f42c93d0d072cd08f3a48007491e25291fbc21b38f3cbae9a13a1126721602bc7fc729164e3bf3a3e7fb4cebd683935fb614b7e1f1b225563dfedfb2f043c1c675a603cb1744d87be179527c3e2bc7c178f48be7bd2a701ae34d397da14ed9dbf7cc748230c9f695fde0f9592a9f950831d81e5c7a3d267c77b2559101ef11583386ddd164b7ce9e9ca361d18f2370db91f06ea370ffe174222ea887e01de54e8a7f88c3b3706a04b0d0cad8cb03659c5c140b558cc739444f7950c4aa0864f48ba89732e498876a4e0f6086ddfd9c2c4f0a9fb31647a87ebdd3d5a9124b6bc3a5714539c0daf0e0f371b6608a210181f8f65547e3482295a6073746d1da4efe24b4e592ae01a1eafba81660630115aba2b77e7da7ce3f6826aad9bf1ab1add6bc981095a17b4cd26ba689fdafbd2291bca5ebfac762fed40d74071b22c94a104bdbde406bb20b12c0ef8c6861ff6cc8d9af483e2fc8e1b61d717c43bc2b808578626d0d8cc735fa769721753a624acc53fcd078baf3436795e4ada1fc9007db2a053e1b3", + "fdfd23e6f59661ff9e0fbeb749a2a36f9e4d83d6a2533092bb98d066dcb9d99e09190bd45bf6de93fd63fc171b66952947028b6a009699540df1\n\nInput: 4d101db2686fd80ed41580f0f5e183c571c80d513ebffc97b32dd1d5fd49e4b83461419fd195d4449a6e4e218199b75edd\nSHA3-256: cd8d0dee49c55315d715388c4ca5a8769886d2f69d78b2ef090ebf27fb19782c\nSHA3-512: 24e1dcbdd7f795e5303552c0d7a464193092e24588cb63d06f2e4876832957a4dec1016773c34d960466d7f3b0f296e47472ff4bf053815c0f1f7dab7b607477\nSHAKE-128: 765992f4176067a17088eccd552499445e642b15ea63f842ee401c393aa4e0bb68f6dfd8baa3d68aba67c8c72d046dd7b7b1df72b425632eb176601f2ba6b4e3ba7cb719f5a3599b4adb2d327cc9e00016ec8be82f0317b3fc80bf624e8ddbf429243c1fe2acb9cf72c0716f379ae41d60b21ce9ede4f306b08d4716429a2a4e54e81c87db4c99d36168b0278c76f8a140548f667473d927163d0d4cb32e6d0b792fea5f0a4d2ca82fd79bc0e1830b2b14298aca8aa866e32c0c1d3919eb45b174323cdb40be0780a9b5f0c11c075d9e4fac4007492b196734d659b424f9874af24ca1b4a4664a5dfa57e7285e4d4f409a844065502e58475c35558f4f6c04f2bd2640078debf3f314f370dc4cdb41bea716ef3413b7df68833ab1ddfc49a006dcad7ae53212cc28d10b5d06dc5e5385d3f1cfb846cd100cd877154fc8033a0692c002475e09aba2ab3448d625d38d6f9b08d29b11f3876fe468bd89605807c29d386ae7502934a7aae1761be854f32dc36c9ddc3b7315a8034166dc2395770cee76a1fcbd92759271bde87064ea222c5dede7b8f9ba134df5056d0b8e5c060fd1a16a82220092aed686a2e029b4a3432848fc2b8506cfc2a4426b6386bda478c0cd3b5c94b39ecc55498fe7643a8cec944975cd5a8ed9241a0a108b2213ce8093f60825d3079a1dd502b6177fb87b6e2905b7eeb10081fdf395372dfb9669dd\nSHAKE-256: af9606e5fa452fafd7ed0dfe46af2e91637d1339f3e5c982bdf5525416a2ec30c59d815240ea3612e3de7f546103821d4d17d5ad889d7679036ef5d90c6cdc4719853ffbb528442dbdb56da08a44a8e4b5830cf2ab155f361ac3a914450fff53d33de12b496b3e7c02d557cab17a6662ef3bcba3d30c81c2388ff36a81a4c0617be5d4c558c967d21ebe056ccea48d75ab90710d9c01243059dc7446a727d0da5f8d8ba67bc1f8c773afcaa3b2dcb5b4c7c4d807f78ca569ef9402b3fac77c96f1552a9e805030e7227a3685c0b468b3491e661fcf63f700c79ee6d831c7549c7ef04f872460379de6e43da379bc802a4b2a135eb6d5103471b295dc1aed59a48a815debf9a446f2484f567f5a46fc6213b680864b457806d4eff062fc74f6dc402ea56a47aca62152d1d3d796f2a65c9131d9c4574906f8729ccd5e30520f7d7ebaf6b58c4d2bcfed15acba0e40c756e5c8a9103009a4878840ba9dba4e85a7752184c50d177671144aec6dbcf956a57045dae0dacc3242c3610565c40557760be0a23e5fa0e3bdeb76edf3e4fcd19a1993c022085b82322da73e1f124b3b046ae9e3e079fbda35cacf04c9629fd22c924e4dbf115dfca028f47db12132e1d4e5b96cc21278719e6c1f04cb519569b4cbf515f06fbaea46adc8c18a7fa9807d2cc6384f43197a7f6d4997cbcfe0fb8366aedaa902044dfeafafd4032b319a85\n\nInput: 7d7be4b02ecedbaa424ac42b6bffe9a3ec7f75ad44a4df2ce0cb88a59ba84694b0ed7f6f2b4d55f5b3ed7d28d71055c6d26e\nSHA3-256: dc06ae7e4df0107c80818b102c935dcaf66ac8d10359b423ab9cadb4f98bcf8f\nSHA3-512: 402c2e34c174e4ed4a4d680dc4301bc88caea40c12a065f9668f08b5caaf99c376eccec32ecbe62425b28472ed08dfa67469c053fdd53b2b202fc8e584580926\nSHAKE-128: 4248b42bda953e672cd03b18f8798b688546a7a79a3e16f498c0e9b83557695e3d02416c60cc691796f8c9f36e73cb32ae3c3437b81fd793b96a25d8975b92d14694c8bed6b4e24087f7e8b9517b66fd114b17880c83141f439a750204a94145ff71cf95b1da46720e9fc1df3435ab67d4d637e965e599e2958e31e3edab92d7c41780bd13bca29dedeee88796006f0bef002b520c9e9a141cba32034dc2bf727090200d854db7216d4a40e779dba15794ea5ec2d2585459d78893eb33d6b0edbd98ac766266e83b6c476eca165085fec8559d4fb9b0bdb84c1489f020a0a2cae1352b6d6d496a982b1c1e2d4fe1daf4eb87fe649c2ff320cbc1828ef169e20447eafc3f644d62e030a230d0409071adbf445b67dff1a05d8c250cf7e5fefefabe902123c386ea72d12d4ea4e4edc5512d8b63b9299d30b5243cc339046cd859e72b109bb97e53f139f6d203a96537a50cc4cf7500d6504f03cff3b1b9dcc2999fb7001f0e657579d33a9aebf43d770cc4f4b92c63a88326c027cc9a8ae0a05b7b4a7219162d2a73f85d556f9946bb07964d8b6c9944a1defa6235c4095e919722f671e258d8748600480059926be033dae70bd42d7d09a24aa78fccaa0f05db5c57f6cde7afefb2ed2ac97224ae12fd393d2c772ad67267ac10d26f4a1c114cb2b4875eb078440a63b7ef13dcd94c70159c2fbd73ee8b382027304b3faba36c\nSHAKE-256: 8f16bbcb9fb0889a7a78d992bea4fa8e2cda8482c906d3b5344d657ea903b5532aa8d24d8cff12c1254e732a58d60a0ce594a2106a003d034a95c35810f53900d3ad0a01004bc7071feddbb06bded15d849e1416cdbb1b01a4315a8bf7e147d2eb7c60a666dfc66e4c73b5c9fbb5e9b64c1ed11f8585b31a6acc0844906165a09b29610cd6fe6ea47dfdd289e160a7df96596e27a02c235098ad937a8b7006b3f54983415585eae106e435bb6f20ac257491c446d98e0bca9be85235b9b4b780ffbb5cbb3cc71b63976f1a77f1000602cb8185c9f4f9fea78521267e54fb4913c742ff43d297ac64310a33fb563fd278a6dd61b8c91e95e4a626aef5350da11d32bca67fe7134e45af13f64446f45ad15a375c295affce07b44e06db2e0b2f90c2e6045a524594ee91af7eb4ced4b745e78dd09d076ef3540c94c302cb1225ca08c515dce25bfafc4c3b3d5688d68f63ddb6bee6aa64fb79ae89aab5d0ad255272e9460747364b290823c619a944a100f69f07409f30184d06707b044ccb1db0a4da35bcdd70b274ace7cf30133f3d013a948738edcb2d88fd11425907c22088a5c43afb5ddf6c7391748ffd6a29b2c2ea5678181e7a753710b8d73d6e1083011f32ae68a0459637a0062e9c5c9e5d9d29eb6f898a2acd4845e05725b80046f8e8509f5b86dad4b7c697b4137fe7ab7b6287fb9c936971bb33774217159627f0\n\nInput: dd80fa702c10fea35ff234749dec19d443b3811a0deaacb873aa677a284ffe5cfc5bae4c042080154a7cab325e9d19baec49f4\nSHA3-256: 4d72b922f8460a14e9266d58a486bbcfa4f5464adf79ce376ebc4491f5f46eec\nSHA3-512: 9afb669305462243435bb6a24b279eee1be13a1485e4b48dcbabc90dfe0e542d5a09dd2c16f6fa096322aeefda0b57c22eb4616b5d913b6481bd49aa46a2e661\nSHAKE-128: a3e8b13326ba6085a64d8bc54f9d83e6cfdf922a6eb7751c9103305b40a5a63594ceda863d8833ccf0e115a1685489a337df1273878c9bb2d48dc95ae7440446de01b9096bc67394f86106eecb774f103f3485b09c7da333ee8b573d3076c96aa8cfea3179fa9c25747e085502262c7620bd5016cf4e0789152432017c961fbbefe37994efe41e02d93af54216c03bd17e6809b962542fac8766ec75a21601c5142cd69d9140045b134a1cfe592cfbf349bc6a02a2592c6fbbb4ce1dfb8647158c05f73544d477f8eae57bb99d343c5739c6bf8f7f8885cec4bd0cba6d357b4e054f65d24751c45effaa34244b7b0008302f94fe15724c2a2a4ce580504b99515d94fd270d182432224c2b397fd99235a0d8390961967aa56974b0e32ca449e41c575a085d6fdc0b81f48378b7e7f69e2b0ff0ba4568a6826af88cd2be852eaca151ffd34783fda8498eb4c97791c60cde6f9faf77d58a2bd28ca2dd2387bc04df8fed6ec8a27b4a1a2f46060424d6107b3eee03f15a8be527718425ca29dc339713fe82e1cbc21d6f086a72b62d4f920e462e2037c84bb4c7e9ca8eb809c76ebadbc66979b044c2dc69df0b95ea2118ef006b84f7ea4b331c4c604fc0c5f2fef621b5c9276cd10edcd3a090de045b1c16e31997725ff6d2bd4468ed539192c8f790860b1c4cc48bb4a4d60590cc94b18d2919262a759848c357317d3eabec46\nSHAKE-256: e789cbb6cd66edd83ecb9aa040160361df29c2df5d4cab9c06de6c52ae0b4180dc3c924bfb93902a31ac658a27ab7c0c1d09bf80d1d2f5f30cde2eb29433d330f0d535ac5530aedc82b9c1a6b669f38e8fb0df5bce1d8cb8b1ef62add4ca774249e44c070558fd8dc8bd8e7b3ac9f58d540d2cd07089092095b6a2ef2c1c4e0e6d3e31a3befebcdfbb463ab51c5e5381ba0aeb44fbc64949aeb47dcd164478260bb66f06e2f1e72764098c198bf01abea3a0e5afcd59bf5fddd70a9b4f20270f40e1b3049daa43c6ffc7eaa603442384f1ecfb770b3d20fb1d687f2a2ec571c2f9a3b24baa677a65b0d406bcbb4397a6d8f1ab728d571882180731231a51dcb12824de6d046eb5e0ff0787b21bd621e5b0a2c1c32b389d158c1c6df9af1ab5c1fb77ecc3d13c21cd3bd1c0c6b6b86debf0bf31f5e5acc220ae0b99d2a8d4640a484af7ff9c2342d5d30309299b13bdc7f94208e36209a59b5b91d063f5731101505904e6715bf56845148cc410bcef45b5812ea734e4eab7de7dda3a6e6360568141d09648f50b8930f7757214c0e0c41922fa78d861e201d787ca86dc40ab76af12c50c25ac8335c310aa92b502c51e2719dee53b31cbcbbe06fdfc04dc346404aac43c055a9f75f6bd38a73340878c16608c843a41c3aad41efc78caab02e063c1e9300c0ddc9a3f0a080cdeac740fb0c75864b63ac6c91a4030bc0e475c77\n\nInput: ddfbf02e5d6d9d497f4f7a437872eee3fc734d623f9a9959b718a5d4477946dcccf63235cbbd809407ba33b51259bd361367e7c0\nSHA3-256: fc06bee42a610b25c0fad23f70014028808609127491858f8a78066e070c88e8\nSHA3-512: 9aadd08290e18576a42c9fc0b0a13100b7ec2052839f125c8db964cc4227357d888a22f3e0e7b907b33969d8cf0bc270065d185df054f40315c9bc901593ca8f\nSHAKE-128: 6e99d49aa56489101a57619964597925d206798b2c78d077a05121bc2c98f5dfa01eba8bd66ea6cd2344df00706c82af5bc593f05c1b5384576f45e0cfbfeb664ef2b04bf76126ea6a8e30cf4162c084b4201bca5a234db5305f94641f31cc1fcce1aa17e528a9761dccfeea28ba75564c87f31534a8b8845e0589f4a7f125bd2c1bb9214d58999bb81198df7901b1258e29d37d70c9842ff712c0ebd0bb0cab682632c76bfab732e47910c2a02a2e236e8805c057a68863b274a2aeef856b69dc5521d5e3e15f86eae76949adb4e2f09c1782fc32582248b2b250e6d8484f3e3612e8b36745ab81e2a5204e3f6cb26a661b913ea63d5cfe3920855847082cdee3c5265627754440d2f60dff91191020f5571ba6", + "1d8149d79c3e010d63c0ec4cd974d393a7ee81a198d7bae30f8288d80718878c2e13dcbf0f40683a526bef8a9417bb72e1222493788e37a5ef3fcb7c7814cc859870c616e53468de44867d594dc692edfc53b0af0a65f2cc8eead43cc31abfabfd69209b809c806ed9964ecf8612202d9bccc87287f1bf5fc74edee5aef79d9f68e00a4273c94a4f2de03b4308eae213acd3ee599ea81a1cd82e5cb3c726666cce9897b82139ab7c42de618b5ad918f702b1f35c8295fe6076a98e8b55b126abf7aacd5f9cd1a97dcd30d9efa7edf49d9b44af123f17070734a3c25698fcd69a5974efb3a1fa2faa550e79f2\nSHAKE-256: 3b52a060fc5f4f2ef98fde3f839e24f3c08fddadf386a4f3b04a75a181e723b5aede63c72471392a109693c119a071c2017adc6474f69a8490001ca189fd1fa17a31739fcc91d187bc0f1d1a9a5f3580fc2eb32e58fb6250a82785d9ea5f98a02f6f7e208e8acaee2c9cb1dcbbc2f6c5dfac4188cacecaf9b0bd64b0f350f8a8172139cf00b637b6b36cb363c947ef71564fd0f2c010fac7165ed213f86a9610d2d21427e8f6a8da5127af1a650e072191f0880083a1ec77ddd3b4ea79e44a49715a0df3a6431236b58a58c11c171bcf37dfe24e3e89e2318605b5c16811dff435cd21164be851070110ab9a387822677fc167e04d946ef8d1fe9d95edab0114d93465570c3d11d9661d30cc7e9fb5a56d520a4ac7437f2995ed0039071b43c2b6ec1f953caa9fdb3ded271b53b35856daba9e8497022c09e95d941a37b1df45ad508c3a92cfb34806dccba60ac1dd228475d7665cdc048270fea13424badf64a3ed2d2ed18bf609e73507c04166e71eb04525195faa63fb8c9b63878eb51051c53c879c9a363375dca71d8cb61bd63b33f5b877ca2359ff077712ce8919803fb022295daa89f9e6fb37e00bd7bc8f137f18a899a3b268567a1cda83f71e6a02cef3adfec5b7f1766d6fbd9696cad24e9e57e60c4137b515391985f835a0d545c98a9600bf717d61b7fa46757ab61cd99e35f1e18bd8073cb90c5b3c96ea75dc\n\nInput: 37a8c4fe65fe5b6d9ac559d50f4de8f252f7361bfbd4a4097b6b8fcffcd137d743060a620064aa8d8238b46e40c173fa18373cae13\nSHA3-256: 1cc16d8a32c8da579134146bd66c44b859a3c69b2a16887b25f5b7354e357769\nSHA3-512: 7c7280d5e03689d8452b13e359880836b33696d8f68cdd23cd5a4c1c47867149e45e20717f930cc0030007d671321891892ff400ad6a2613dfbb08bf1d97d11d\nSHAKE-128: 9f503979035b9449e65898ab26cb0313e98473f27d22f92f620b802f99f0440d1d38a75dfbc30a24d2e193347e804b4c19c675f6ad046ef1ea62b5a899b20d2721ad10119e0d877e138ed3cb90bdd131fdddaadd4248dc940ebfbb214709d21d1753997e862f5242d30a0c003a1dc70a2db96146114107b5d5f6e423eb0425401c2e78141cb1c52fc19e3cd7ba6ab5350adf101e67c6c12f4e453729e897eb1d8c15cd6b8b25e72f710ccf1e15c4a75386ce380fe608135335f1ccb843af902a4289eccb94f2dc169a52da16bc8f94b9f33c26cbf4f3ff1b42e6f02d78523131ac3e8f538d922790a1b505aaaaa215cb3c795a9bf72fb7182c1a94758a915277c2dfd6cc60ab95641626057c1c6a28aefb66d4453d625c58c14084a936fd537517ed96b0fd1be35c0766e03e8511642e78f6a4fe7a148e599d53411f87a95d2ed62e1f71fed9fe3d5893b07b6bdc8ff885106222ba15fae6cd7225e39874c2300778d7fe69b84c175008eb1b326fc092b3e870458de60b857d434140b7eb93f7f77f59bf8e5beb43adacf1ab7634ad3c95e87620bdbe24dd40e0966be68c0a88acd7cd4f2b0709578e77331b0d4bb0524be9611f660b0996c28195686030719ed507ecc96a888929116adefaafe9637254841c8cb237b7e83f02240d498c697dd75c0ec1f5380c1e1cf90d8f1120054e44097ec5337c39adfaf1ee6d413cbf6c\nSHAKE-256: d65965965a6046f83cb81692650e20c023ae66d2b6799ddcd2331dc3b012567ef394840725b5d77eacc99303113f290971fccf0e5d82c07a9154633ff751acdd36789b832cf852795a8d8862093e5bd506af37bcd446dc80ea01d1c4d5cac69cead6c33677bf3e73b3239d936c002401abdcfd67dadbc05a9c6e28498401c71e871d84d73db0fe3c440467f7a287ffc014e26c9ca5d21120aed8c9c91bc3607eb92e2ef3dba9080e399d6bb010fa94b362f06281a5f1d5cfe49c459fa206634d1ab78137902224c706b9474ddc23dd447fc484bb2676cffb8e0a98bbc099f6c1eeb5e7671d3f759d49e3294271b4d0e04148bdb9b632b1680334d7394ece590e6f477b6edfd5f5d5796326590886b30851a72df4c65cbdd3f93ef0fd7406acd7ebd1041400614bd333e4a35b17159382cda4d0686f870877af24bbbdd6902e62ccb29aa6151caa61513ac73f91367e54fc0bbcacb728a971a413e88052726c1d603ef5c1042ed23f4278168e5168767c477ab5dd64475d5fbcbecdee68975f14681f9223b1ff4e7c1ec672fd248040cd91f58e771501cebc0c8cb6304ff44de6eac8d4ef90766badebfcd1003ad648908abd72b90c8fa353c4c9a25a26cc07aa2641120300fefe627cbe7635d25480e69c29a2c1f21cad00d5136edf2f583fece31bc57a76c9ba7d557c7b0034394268eec21be8645a951e7abb473c6ca918d0\n\nInput: 8496ec3de3bcd449cbb35f6ab61f12b56bbeee2739612a3a28a435727c42b868a9a3f3a189531708b35e5a3d2b9f95e19a9740f2182a\nSHA3-256: b12813656c16efd43912400a4d32c800b26f169e114a5b489399001a5f067ce1\nSHA3-512: 2784b5adfba9d516b6402419e37cf2fa00c5d8e9fef384ceb24de176e5de0d9074f66d64b09b8b48361eb5d562a15a48a8ef867224bde8e1b5999471e4b0607b\nSHAKE-128: 143337563999b2ce15481f2b29a8c29632c02b8969d5538e21aad8c58374a26659d4928fd4df530e030843afef90309b32a6ae267091ebcbf3e327aeefb9152b8c487443fa043d2621e4e4f1158367841b103bc6c67f3f5bcf2f03aec2df76b280ad8ec75ee3b3516ed24f432782b9e9000cf18466d5f3e4ec37bef78df34304d3357cf8c8209197bce46838a5db98b2300f1be2b923ea860f6d153db2068d1ea72109a55f5194ea52a9cdcadeda1eb5f58e0a94a54c78d967652bf3923708198251f7c59a4ba8e199a0ec3f9052086c6da0392a73dbf47f89b7d10b771664207ca13e6e52ee0e9a61de4e8c591388ba8edea5df5b75593bbdc7a79cb81e7b556468b8636b10527fe8eddc9a9fbee6e44a429a9767364992dd4a490e5a53dabb9285cec85fa8fd182da6423693d46882f605a1c2928384c4a2e8558eeb4cc31e028892631359c4faffe2807d1d1cc13060abb125cc49922832df65af2cb10c04c6f3d555479a9fc70f283b9e2a86948e94be7cd1a39420dcaa4c786b4a84a556932b0782a0254bd78a91340c573759401605c29244738d256979ec275aaa17a14e12d83d6da94914e1b1ef69c0185b336dfbdea28d3d1e4c6922db8ba538cbd77e70dd200e90475623910dbefc0651398c8a75141d6a179abe2039361177bc24cc42040f423343f0cfb1092554ccf6fe7e37daa9c672d51d7f4514a4485c4861\nSHAKE-256: 482717d0513f165df6e953017b5cfffea3d9c5bacfe65ea789686c24535c29f636c44986557c468b4dd3050d790bd553244c8c2a88622c4534c50f42db1dc42414adedeaa10e1f49d2716aaf3d24f9c71f6a480599550524baec78cf1ba1361a4bb13053d547641c89001cc01ede407c31d7bbdc6cd3204fb790239be50af60f19544617b0e87cd5cb0fb5b4a6d945353111513ffab6081e8b56ee87bbfdbdaa14e1355d0b431065d082f78efd1872fe796e3c4119eb975b49a3a08000e1a431474a7e3774150a02672f6c27373ad26cacf140b7141d4ebe208761a52779f262a12cdfadb2e2d7915fe551f8b65f4edb4a9ad590784e18f2846494ed6048a51046642fd8bf86578650e77ede74f23e670f1bdc2471fa94f43c514d6e74c9fdd963047688f707164e34d0096097a259e97e23133edd9f95f2c1c094b2df81db17a0b19da7096ab41d25728b54d09b29a833e9ccc3917e9bb208f455cb9e9ce4a5d715a1931b01a51d73058dc4aa61dc425379150e20e953aefd96514ceda97de45cd52fccf8e240f1767e24f2fa5f20ef4a930a1330d631b24b3e2de9041fffeee35011646036fda133eb863f7521018221334307df13e3b708697a8753b48fefac13ab9a56db074f5143a6b8b8491f4c7c62ceec24aabcc188aca253e2c2b59fbe85d645e135cd8b64a1fbf58e08a69e2a20489dedd92a48b75e939cee7625c9\n\nInput: c4c7cc0682eeff5b6624743392f783bc7958541acbba5ce8c5ed561122d59db99d8c15175d13d586de46aa0c817eff67a3f0998e7f9fc8\nSHA3-256: 554013212e6c414a08eec3c569a4493cfbb60b7f88c09c85863448023ece4434\nSHA3-512: 7decf4e85b911f1dc3f2df78c60022c97f08f7f3084d0945ad193a4960bf1286eaa12d5d318e57135eda4962d4d0bcce26eb52a6b8fb7a3854403a427c01ec20\nSHAKE-128: b034812e5c5065643db679bbec20df24b7b2efb0ff687a117371e1a1daad9ffeac38e777260f21f3985d227b987ca5b32840083cdfb29bf7ec7207d990f7f535f992aa435aa9b63a4d3851f20e96d828fc25bcba2cd3aadfcc8521f525d08f156da7f602774e3cc3b58be8662315eeeb797ee257f4e45dc094c730e31fabda20699eb31a3c3f829a743f1fdf46b5a94856a032aa76038c65250c4c2cf10953586bc814f4a6c54b9e874719178e5b39e281ecbc57ac0248ddeaf4080c3b7b55b4acd8dc7213482dce63abac44e5b1eed89204ece529a1da443bc446619fa0667ec0053401ea3c2dcc6e4257aed7beefca197cbd5497f1141c90d339c6b362a8c974bc4ca64971bdc80e60f47a47323b061f8a2bbd1ab235eba9c7fff71c5c17b5a9d115e2c4cc8c082cd99ae8c3190c01f76f3e0fe9b18447b659da597e407cf07de2d490ffb74bbbe8364e79540204eab06f121b43c1e6dc843e21e2304f8bbd32039f3188cdc67d8683700cb76e815034eae76eccc8e6917c03ad51cd78ca4a42d27434740df67f5a22fcd4b954178a97b9fd25a20c5d4527f2a2818459cfd439bb7f72290542e10b642dc5986bd8720817a0c5c7d5f09396d0dcb3474ae15517696d94861a515a835ea98f317ae16e0c4151ef33d6062ff466b3c606968a59b6a91010d607192fe4f3e7b6a3975e75c6b03531eb2f03a733dfb1e38fcc32a8\nSHAKE-256: 448155483ba01e6ba182b787449d34261332f0869f36c278732a99b871af3842d43b4be659ed76b8e742bbdb2712f855c9c94e938225fcdd4bdcaece06c8bd158aca12d615b81ea5748437f793822df77a58d923701cb2fc2b468abf2ee2db5c1b173914a2c1c9936cc32e25758482b28f346ae5b3b58bb481e2d3f62ca307c56cc2d6e639d581b08b3c9cd868a18b80f38a8ab53a3cd198ec3537299af782ee9843ade5f3c5c7f2f0edea59f10ed7f82f0f3dbaf35bdcc15c44ea869078cee550b3ac130f72f3dd76b19ea2669e2bb89124fd39a858a45f4f4a3f672e93f82f7b9d2bc21a4c95a5fbe52eb8fd1dbe08e624b980634ba5a61ae", + "a77978afb0cea1e227f4bc67747cb77267d19ed564627d1aa2ad3c52b1f0b10b898c5664378c9a6a0d7b37a178b6f6d770db282a37edc5dd5d15756ef153adbbeee8490b954fcae62d364db0a2e7bf6cfb0ee20937b291b0b9393426e7722f40546970cbbc943c7bdb40765146344cc336f1b65e942b0a2439973bd2ac669405e677164a658f30cdaace2a7063e07788a4c5c5eee1735a529a6bb33d51469f626aa42db9741a11d39e32032f95f4ef89991c5cd9f962e6a8e9299dd483e5f1fc1e938a533df48e30b76d728bdc1eb2a100f412340e1d37a920da112ca13755e4501c893e7d79ac0eb982e737cbf387c52ed369986e16e7a758694a856465ca808ae0bcfcdff90\n\nInput: 57ad6f51c14c180d9e916dff86171fd0609dd429a01dc5a765cf9e1038cbb3da2d9e70493f9d18cb78b93e6b5be14e8fec41f28f7a6000eb\nSHA3-256: c848025f88c9ce19492d2de2bb606adeb1433d10f461fde47e08f3552b088191\nSHA3-512: dd1610d08075bc007c6e19844d37637d039286c8d531c65a947256923683a5704ad9838536abf77eecc0f4c8e320067e1413622800849f6e85635f4099815e91\nSHAKE-128: 12f962f39bb6b0017c17aac6f35e6e196ee89b431090c6f17624f9cc06f8dae72bf44dcc602e4f3e3522b93430048a702cd4349d6ccb366c894d48efae290b56e8e61f89cc2763ad4380e8f21415284317501bc4d3374e2e29b6d28228c459ca44e1f48b1559563737cc2ff387d33b5422445d06fc247820ad74e8433ee63f4a8ef588c7b53afd49f90b2c919ab7a7f2a0a4f4906b1128bc5175cc95dbaf4554660c923b88974cdba054461cda616b4a97700814fbd11988aadabddbb9b2548f540dc9093418be5347e40237fdc8f911f65cd1e50580187d3de6cb075320e426c35fd3ef5ecb026c0ae2e06f517ae626306999a58bb37933036d5d5619084c4a7d133f2d113a3a430558774d14d30a8fb27ef5ca2672251a8bfc79ce110a8a244b42780ecf55a027f1c84b357d3f3bc2b7a49a88002a57a779c9dc2e82e8701b12b93f2428df830e0bbb9c62bba1fe7e9a891ae501f32ddb862924408f24d98444afc677b695915f6aa2da1833d0540440eaafdfc9f1ae5618818dd3b3e41a6872ca041b5b35f0588092e5e3c7702db0f483a4ba39e2717e31659c2e4e81651a0b5dd405bcb369af07f4f9acc5c5e17ddc71f06b5ed0a917015d994488ffd3083a793d23e2179e4744051a2495d37338f002af1c0ab685c7b277c4c4f73bd4c7925e845bc8668f32c4f342b7f7e2c681a2a7c63e41b8bd4d2df17310b077997c\nSHAKE-256: 4604f292fa45e5cec93a22148709f74d05837afdb1cd91aebb26286076c8dc3a571115af05841e89909df784784403fdc37e1fc9b368fae327b629799c00b8455ac1f44a4e487b6e16e4a0829ff3d0095f99e5dc0056e56e6bbca6167580acbdf028318b229ac397bd05c57252ca2784e0007154b48999a4abb762be6df51a8cd33df9841d9eb88b1444d1bf11511682aca2d437f1b4491f7fb2cb43b7155f8701d5949fa82d56b56409622c57c816f7b8044bfe4ae6d540733884ac754c907dd2d91a6807a47085f66c54a5e91eed5afd77f62ec75fb00ed0b58ece86bba3a3bd242bd439f4799f00dfaddb8a771fea8afa453bb2aa18f2bd0aef1b3536fd694d35475ca023835408264aea1c60ca22c85a4a7b6682b6d175c306e293c38e9e0634216a26c2dcef8ef3051b7a1daa2388d3ea89d6faf047146b4f0f8916f7b911e6e994dac407ffa2ead672d1d16413afbcb26475480cfc0096fc7faeed8c726e8c5e0fa10486d8081de252aa4ea63fd1edf6dda1c6934d5a08a35ca38a51484962063e1e07087172a4ea02bfea4db6b6b713f1b9e8c20b7c741dcecaa50a5dbb056e21e95b4d8f28de8ee5543ea64fea01d2bbb4ee3423727b781a822a974db30f4b7bfb1b085356879d561c108c2a6b5366888e1df26352f329f5ba8f249736374e622ca399614855055545f363f5066827d320549e5a8034dfb0b61d58e7\n\nInput: 7029b593a62275941ee22b46814b594b0e962bd4aef0b79dada2cf0c28983efb8a8528e018ae640b06a2c770c72ab6135923f79588d4bf1705\nSHA3-256: b02569d72f0e08e855ceaaac5eb10aa6d1ef8182f9b538059cf8e867b567a34a\nSHA3-512: 3bdbadafbeefb5c4e4e06bef4aec9167cdebdabe00ea1b0a8070832c6d930702a2b7f4a092fe147c75abc0af45d67ce45704d9072716607b1515ca637788601c\nSHAKE-128: 35ac8e427cabcb13e233c043ae77ceeb1e3b4d33adf0b16289d3a17c0b296e372d49392ec5334f76c874b432994c05967d01aacf411197274a11eb3727f2845890da5da9c1900ce4ac1ba38933342a8166d057c6dbae3c5271e6c86e7c00edce8781e72c54b16bc1153b76b8a713fd338dc60462a10145fe56affb0323394e3cb56c89cfd4fef48d9e520b5c4acda030d869ca96ef0b09c3e56ebae914162eb946bf9e9b6e6b0e944ddeb44438f961a3d8bba96a4ab31f65622b7e618f6ee2c85277a2f4836fda531996391e6927370332d3d5a2767aed6741079af67037a43fe57afa304beab47ada56d1deba86ba3ac3c079725702f7815cdc3bc1d84675a66380e692efb0885e3fcb094bfe2760b3c9691335b6a6257cbc2f9cf9e101a2a8db5490c576ab783eb69ac026d13cdf0820955b24fe16fe2ee72450cfb53b90909c7d4e80c1f36426725b7771f046d96a8ed24a296d80311da54ee3cd03d4753e16115029fed2b0914f00900186a8a8a81a17b994768b3a1ede8102927be9be616524bed52543047e652e40804477c87019c2bbf8efe5a745a9ba6975fee0d0eb0a2c26d73b2486666b08ec53668ee55ba5d76d78049d2abdee82bea7801a66f68288436a06fdcabfa4de7ad081755fd70cbc2cc95df390644b28705fadf1d150d319b7dfdcf52b0dfa1ee3bc7a3cae71374fbd420f40d63cebc348383d5f151f\nSHAKE-256: 7ca002966f635a4f09b4bdc0eb28427bc83a447d6fe2eaf1ff1438eea5cb70111ce178518676236c571ee86a592b9fddc58a3edab27f3624461a7a027fdde0b113619e72b7b27d0d051fce7e9733554ae4111ded41c2d70fb63179944e11e68bb3a4f4323ff211221e4ba2e3ffd9142ab06fd9ddfbc62e026db42fc4ca91d8c6cfb67dfa732232f28509e436b772b4ca17085fca2f5c35e2a8511a1de7bb866601f4c6f33969d02a9b5c80d9c4c76babcd8f21a1bc0ebe4fb31a0212e9961837d95a28d347352a9921a95eafc70da85b7c11ee3a2fd84aa8bee8fe9449c53763ecf5a3df102a21d5ecaf2d1bba8e24435dcb865980df02ee64c61fc5140ff5cd5fd8917020b4da9e0e7bb0aa33051256170b3977f14f7bf6465a697c24edfba6e575360fccb3ec6d299202ef91775be9e61cbf6bad169588c8217f12dd9e376b2a22b593b49fc1a2c0a1ecbe1e659caa1b88a112390ff91e93bf65eb162b2ebed42380d4918c74890763bcf641489fd93fc187adeeb57796c5d44c26b7fdf0036abb3101548b25a70b9846e07ea329d4aa92270daf64e8f8f4741e755ff6a6a6dab85f706d31a5f9190bc94e642e817783b11e0909aef448fd657ea4c986861411d4b6d8bccd9bb260863df2c5ce957ae986bd8e8ab408ece604f6fe6f62c99e0da41e1320f3681305fd27817f28e1bd6519c958c66d7616ea00b61a8386e64c\n\nInput: e2d5ce5fd35438de1c68bc51ce953e8445b49a53267455d3c99c203bef392c33025cd4be8b8f1b9da41d7722de7357605fa4da21606fe7bbaafb\nSHA3-256: 7844b094e2a71bd14b2109abf3aab9a0879a3c80c9ec4f76dae2e17f372a7526\nSHA3-512: 645e43e6172987725df7321c84b2824a2aaad8b334e2625ae2f4ecf1b66932f87bb860ffe20fb529559c8cacc465077458148a26ee262c8d6591942030f1f6f5\nSHAKE-128: 8473eddf56115b8f82f20c3ea7e4b100bd8cf905d290409bec85eb10535fdb806d23ec048cb86c64b2155ea08e5662cf201629123efb37b0535767e0c180cec8fe2bcf7f2a1dac950d4e2059f087033b46a0a936ceed627d2c6be815baff915909b427080ddbf88412c4ef9aaeb3b04498aad8a9afa5e54708bb831272536f4868080ebc6510089c3930673c23e90c0db88b3403d93263c18a50367969aef0fec3a6324883fdb9cfb27d688f8b268872033e19362a03658e71cea58fc69e800789c1143be37527db9ced9e845bf41834b6accfe91fcee96533558533e4e24d273a53df559f3c0d4bec65af4dd6f77568bafba48009ecc01b5b1da2e18cd55ee49b3cd3263c0afab658aad6962f325f0066437a85e59fe9fa4e860dcd2a0db5d278dda9b8e3b4f0fcffb2f010b7e09905382fd27722f85feea19ea080fcfe2cd48f6fb9923d90fb742eae8befeacbd87e9664b1d73c41f4eb59f2519843e64a6524a778bbf36caf54e266f4b5a5330b06f20878933d94a51b9c0d5e04f44a26c536efc6cb392c57d42569c8d31e20ebdf110f5f6d874a2b6347bba9ae2b700a17cfaca1900a23566946f177b20a4138aac6f19f36bc1c04ef92793a0505ada030f28de0c89c0e824d34ae19f9db53401da4db5d75aa3f1ca5d8e3a63ecd577209c5504ed6a43bf46075c714f9102bbcb9592a1d695bbbcd47652265fc39b47f45\nSHAKE-256: 831386c569efdb703fda3ddde2e549320e832a1eacf0bb44f48bbfea660785ae25cf2825e4b4a43d15279ca9e3eb6e57355cae2ba6671dd80020e8008373657b6340f47de756433d28ce6ade50ec03ef4acbf10bf1554efbb09ac450aa3c423e51a5646fc0dfc86696646b1f346acadc84e7dabd7c6dea1bfde54729b550fe1dcc318c11b25095f1e67131a4a2933f94d7c84262fc865eac097959a1aa089ce02c4f76a3dc00430f6e19a3d7937908ce27f1e17ab693f4c3556a6ea743a3db0dcf6c72fd5315ba7826c878a3fdb187e916a9110dfc8294e55cbc3f4735ec55f41de01b7828c47bcd162031b8933253d765e88f52544153406f3ec8ae51faa3880586e136fedbae170af6ff32226392dabf256a109de067a28e65bdf420fd99306f730aeb5bdb4fa5eeb8de8cc9c912802ab82cef2154958bc9d3392ecfc3a9b120bdfc37bed1997f29ff87b957baed1c3223cde1f379312aaf158a99813befca826c5ab96663382a07a0a2a06d8ec1aa99172a52e3ea556e0403328d700399211f04b53a5c3ffaa060cc864512f194f3aeb03a5b2a7fffaa080112532148a2524a9ccbd470fdc1c5c3409152e2dfaba60a7a36a38beaa8031001c1ce3030baa865328165cef7846b562d90c4e49328e54d987dbf89ffc7d756f459592fe843c76e9d508dd88dc1362a2b8b392ded9a0e51d06cd2854e78f5b76dac95ae2bf615\n\nInput: 3cf94966b97498f5d67314756913bedaf4ef574dffeadd2823b78cafb2c1b4239d88c7a7cf188f3754bb44f800074930670e03c643a96e0610aeee\nSHA3-256: 7b5dd6a11f0975fea2b57a64690fbfe2f3740f7832cc0bed6e7d3071959c79f1\nSHA3-512: f9024e88ac10327c320c03eeadb4c1c48ddfc37187add808389f46198da2760898b5f542d639235a2ff7da1c6dcf069f28ec7750b829f70a1420c3ffb745ff09\nSHAKE-128: 739c61330e3159e22ee0eed4808d5cfc8bf6004f88929712ac56b7ff33c678ceac5c6467535b746f31cf79a", + "6c2db34a21b78c370f3eef7b610e909ea32b6a5759b43c43c8ce6de6b1a7f09e888fe2146f15dac008962b464c82abc1ff43436ad6ef5fffda19c31022983b5855fdf135d25d100deee8bf01ff2a0f537ef7c623d7a5001865f21162c964f868b43a354fec820d67dd31385621601b8db127bab248773fdf88e6ff2ceb62495f9a5f83109e4b57b7ad5e899c05d4a2614d4a6ae99d07271c86e28bd13b894e1ba97609d757923573fc34743d271c29dc274c56e91d5ffa69f9914bc6c575dba9deeb2285c9487982b13964ab28ceb39c9791b842d584ed9a3ac2807fae0e9624a77dc6872f20f2cbc933eae630d5fd0c33cca662bc086667a53bd04db2a26e9e1d90b7e4b92a31f8ff25546e824436e802b44913cb9b0bf6521acebfb0218fd20c25db5571f18eb9747f01b0f0db48ffd10155a170ae94652c94baa1df16d9b8b8b33da02a7f953b057380db5d8e2c67c897ae28275f888f0fdfec2bf48f6f092749b4d89233fe98fd351214d545c5a463fd504dd3e2f921e809fa2c8d623a8109279ee43f66e064b120be924b6c1939a6aee17fe42b921a78f251ccd72c51520771087c548f8b976720625b0a03f6ccc82ab173f5c1ea511fd4d4f657ab33929a0e6ae5afbb9a4d4058ba21334c53c538c45595f\nSHAKE-256: f8b0b1da88d27ccf28f6f55b896f952a8c2dbcc5729a6810834e9f8c026252d61ceb32e425d512e4ee02beec1a294a9da429fd4611606bf0d5c1586079ce01b3851de6bd9d60fe057d158e7d9086bbd78a0fa38e99ce4def07811b3230642540cf0fb3b682b0542f5e1527d1395ad95a6568f2d358642b4a450ced51ab5ab17ea5b0eb3f4b163d5219543fb5ca2626f6d3a37e37e6352d957675ae63ac8a3aee9df37d8186ffce03441d917f17c8afe177fc59313a6202d13b1893a38fc02941252e137bdfc3834179cbcad4decfe4d6860cf1da2397c802fcfb214222794cc0fece3940ff6546e57f25ef2868679388c6d41012ae52740f52cc396fdba69c14214956f8b9cbf81281a89526591c682aeeae9a0c20b167c8ed4d0e4522ba90984e3acd7b9740e6b59de6cdf6dbc6383db7d7b6d86c016a12fb7554f495c34286611bb37a38d184f768e28d6541cef8e1d461b9348e3439faf05e44026a77d4147b38d104eb4b43c1a72818ab5f7e7a10c7486c23d146011bb1bcd4e41d22176b749561a9442fa8879c8e7014311476e5d61dec0f47c8f6c522a797cdfc02741e95c1fc1e889c14e0243b7f8c18de1dc3f0e88eedaa37b622846b09a0102d2eaeba6549260edaea597c9a4c1a758907ea57f814d3307966a877c425f45ea4f1ecee5ef0586e3120c263201bd7d6cf250cebc952cb38d3ac0bc5e916f595adf618\n\nInput: 75ba921ae852d20adf19761b09b697209a422385fabaab50abd126e27af0529dcbbfc30fe3ad38a6cd01d099530668be4871c8679dcdf7d81cebb558\nSHA3-256: ed06fd039a86da95658d42ccd0a3abe2df6bd4e8887d67fb397c9f098e9724c1\nSHA3-512: b0898f35429a876260a1d5191cc020ea055931f02380c8cf02bff17e3d6d8be8a030239a25903b8e29b158de5c9a6aaf2f50e821aeb6895193a55e95fd4063c1\nSHAKE-128: b426454e70af7d8ef52625e72b7f04112e92024d4e15334bdb81ffd4609179a1b8e4e2b3c9e1f22bb0140c39a1fd15dd8e9947d7c19dfc9b305855c492a9495c872b8b5acd45c0603e71177f83fd59432c8440a38a67d0b608519a5ca0ce0bce0c3bdeafad2a330230177ec648688ae1f675d8ac6453b2a48c34cf6566d7e9ff63a48444921f72c08c76eabecebcb14330907d6aa9055c2dd3295a881ca1081c93653d575eeae31ec0c2b673089c99838300f326f047f9c05b505993b3027b66fb70928cb9bee122f4e26f181162539d1612baa72f8574397d00bc313eb023222ea5b570e5d91b947dbd6da54be56283a465737102c318c1ca7d5cafe7a9577467aeeac64feeab29e2b37a2063f724cf4be58f40107513a51cfbd9a642d3f6372bdf1d36b071468efcaa7487d5cbb55790c59bc6b119bbd2f805cbd89b19c6544406269c25a432f6fb50d976e3f993daccf2a3914bbefa7245413db118bda05cee309dc3dfa65d3594777d4a29d942b36fcb9af4b514bb324680c4af1d8cc75cdfce4093500fbcf5ff6df47fa53344063ae400c7dc17dcd43f9c86e47fdd298c41a7ffc4182c71b0cfcdb93f9858c947744d05bb21ad043d2d962a17c07bf1dbc5825e29135213775fce7e167680e1736e190bd977b22f33353447dd07e990a68de9a4a3d30acfcc00fd8eb7840ea101790e1e37e6e6debcc4b03103f827c433\nSHAKE-256: f08395712f6d359d4f0cf258d9460d67975a7bef7d89849a5b1a0994183c5925b326b66ade872b048c65f032b1c7bf925febba208d72a7ff64841e9ce2f251d2b2496b98a3e0b0156bc5c1b58e5938e6e88556dfd66d2fc52d1d91bf504cebe2ef35d1e2db31914c7fba35930b31627acd5aaa6858fecc1c08e7ef64acd9c03f211e79a22cccf878a65228d7173d71455856c74a306c1272bceb2049dc9866ea53674dee5496a4f1c616f518f16759252847cc0bc6489d282c8e9aede4ec2fc2fe7811bb0fabbb1c3a07e768e1688821f90dade72ca265ff5f33cb70932b1a6c039b1ade189ac5c03f186f05df68fc17ff1756542e1fba35981d33b34bedcca911c506ce63b65ace07ee08a9b8b824345e2679a6259e6ca38b24377e2b1c6db0c256bb477bfd4ef962bece5577b35874eeef673dffb76da01322ab7fff29c1ca185b0bee14ddd4bdd1bc820a7c41e9b99703839063f58e58cc99b3c9d5faec4d17b4ce254e1e564ef0bb8d3d069156b67d1c939f5dbd387a21c4a35d6a6916ef5d4379c5f759c6c64f13b48f0e6b96510b19655901747e0e195393c4614b48092c57bd632a9ff4a27cc73cf6ce6448aed648d0a3937d6708177885211b51dc5a5f7afe87ae158b590bff8b39fd7fd39bbb5d4a21c77f71aa96be89bde8943e16c6e267a57732f23f18e9f43862614846e689b5e0ae7147041e64e167001799c4\n\nInput: 754e30eb272a52fea2a4ff6164f94ca5b9dfb140d6be78594d14b5987e2ba45f2e237f259640e704d8badb21ebd48ffa2bd8edf2ed379fa2ddc976ba4b\nSHA3-256: 8df64280bcdae9dc7f8e4bf429fb2b8add250b5bef3b86d02c20956ee986c9b2\nSHA3-512: 375d42a4623670aa92060f9b43f943beaeb3a469862a36fffe6be4b7ceda860d1b9803f8801fc1f82c25d0cdfbb6f0a5d730cbf296100f97a6da1d5807e738d6\nSHAKE-128: 895c62236f41c932bc5045448459237e1479ffacef72b877028b8f2fed9199cfe066fe198073b96a59a8452d037f34d2ac49193b40aade352e5e5c0478b62e96d5b95492d8af8c73707dfe9e937a1d2f27d056820aa17e40bab1c84d3da3d9ae71a1f1a6ec6129d8af0d052b040694afec52fbdde7c06d6fcbf844a2cffec4b47072c99ad5f8e785c2b34f9fd675798e4615f1a5ef28deb1c19a15e382082791cff76d8d3a79c4f2bee9d374a887cca79881e1073be62426f94ca077c94b6a177425454ee5ba6605bef5d84bd4ed3ba5b90b35f21e65e9dc9ae16402636104a9d412b53ce7c9ccf4a35ebc55e9da5948c070810050f6530c2ed56735241c8c411df32ba7597e09116a8a10a5aa54f9f07b05dc3943b73465edba9888c19327ea3a1cc228f2c2b0aeb091b03223b7e344360648260c69b9791eb9e239e97a862e51298a21ef1f4fd46bb6cebc9911c85f6efa0bf70d960435e68c880cd0836b15ef28280375562d5b63f190d795af486c42483a3ef2d74d36fea63c493de5cfaa6461a0fa262fa8441bf0fce992dae71af98f3e1a1bbc3152ce8e6cc57ea75ab29dc9fa1b9d2dbf58bfc1df4fb480e015ac608c939807581b3891310d610e03b86897a222c10f740f6f688030432e612fbe402da806256d5f479a99da8ea8e5e342526583b6ac4721ff5ab7c95717abd4c86cce5cc6585224fb66ba51607b36af\nSHAKE-256: aed22bf278da38a8f6bf5499fc6ac9f40f2b4325cffcf2ca07549daaef5a6da0812f19f9435e774563115e3c847c6bfd9777f30e7ef2ab0751b251243a441ba13c2770d5fad6f00985232eafb5533b9d62a9f0f44ee507b88b76d8df3021785444d2a83720c4f41566731e12e1955dfc9e939644c7ea99b54297920f26e9d1f411c82ac60c970f72eac9b6f2f0171f0be322b4f35ee7ebb4e638a42f4bf7eba4866e47198c04fc5f6ff4689f81d848328996f7c01b1dcd3fbba95df6e84e68ae6d80265a19808d81616bacb9194fc821b001755175a7af88e841ad9302b20b0a897cdbed7ce3847099e0120069ad4959444325d3ca53594b25e97c813337f2cfd45194429891d5a7508fdd778512cbf0f7b9ad0d2e556c0dbd3c37eab622b263fa379a0d513e45890d705288c62add66050a1a655dcd2f80ecdbaff2e6a60f0f6cfeb0bcd9d6a2363dc64e2f3c27a39bd707ebdfa53960f4c6218aebbbb12293aa0bc9dc30ba3f11062fadbcd74650b15ff1ff7ef3cf7ceb708e41aa10a3176c44ed4e0480ced77cf6063c3e3bff4e547d207299accd29f3df586e4639155ef22cad7a191e43540834ff5b0f623d0f6653ba0b0b0738e8bd32d57ff33ffe45abc185e75062608a2a93e993b460e08fd690ce0b24e1030288f195558fceb0bef1460a22d620e43992ff9fedacf72a747e68d15af5b99a493a9169ae725ac79430\n\nInput: 12f65da49d593018d4bd5d90b83e46b7190daa5d68a944a6390beee24046313c3e3f6a24064d6d45ffaa2b6b5872a04284495c1e893c59cb5a97d4ac766a\nSHA3-256: 1b3c8db0dc76f9f3e0cafe87b55a722155874cf273b9dc15f738d9428c59e8ee\nSHA3-512: 6f0fc4b3a2830eaa649638abf7dbecf279d263e630cfb9dcf0e7b7ba5bb5549a97ad96bd46771bd2912337981fe15402807adb275741a5104717dd792e884f10\nSHAKE-128: 73ee2d1711960feae29df60d8b5de3bad8cec6ecf6be8d8a287b1ff492113bcfb2804e74abe369cd1a19ffedf0aff6dfef876ad4a05842362cbd0687203f98223934d3d696983e92ef30175de7ff2ca3074961d44c600f6f70ccc5dfe3317b0f6a46da58b96ec7f5b62d93d3d4033019aec924f24ab6bd3cb805c8bd50b2303b51b5863820928257aa2de67ed9699eec25f07300761354f7b6f82452a95e96c131e2cd4287617ae643bc9c9bf4bd48039ca679a3df27b33ac29fd9b086663fec62ac56df288d568ab73bcb3ef88791a2ce5db96809e632e3b990123bb8333148cd9ca7519281f23bf678989c77aa9ac55ef86d0845abdb3561380b31e8a5886441d51cc785ecafb77819db8d7cf96a9a55dd5fa851ee49f6b923fb9114734fcc6521d9f650c0a45f77899695767c2bdb036d420fa6822d4041fec998d8efc7585ab5123751817d68634a8a7b8917ddcec767f54ea649fd25722464755dcd85730eba4e03a81e034c42748e17d7ce867079ff5b583853aa8f47637f4e1f3b85d712636daeb1186284ac7f6e814d95c106af81e70f06cd0716121c888717db91887dabe80030f07b3e6bdb76fc210178f36761749333263a97789fa243f2d8a70df833b06ed946b982e68cfbe6e5b20f94445f1b158f44dac070c47ece9741dcd67fab98d5c9801add03436e328bb192c7724b6e613a9fdcb50a80ef961f7b5e5c\nSHA", + "KE-256: ca0ebde1e3a4e829e4d09e54338c7dc59d4e89029fa8d3a916f1596a0da21d75da21d94110658b11ada83a230228357d640d604bb1f7f3bc551b48c7c9aee580dadb96c0ebcbf663469fda0a6a261932a9866938b96de58b9fd9204a9cf69b67a34865319f3b98307c5cccead1f63c202a53982986be719b550be22de9d0e323017422313678c09c32e954d8307c4ecb6be7d93f80aebc9ba9fbd635c78338d3b5b5274a5f2d70cc5496ba22a07033f357493ced80883f0d5aedbc52aa38e9389b92fc49f9edbcbe11512a714dae356b8ada8f0641eddf8313e66b4acf1d6a891f5013f00b3013feacfe933bd97ceb7ec87a2f76e09c3e357d2774298876790169b58565942e4b8c900dd50f4cde0d1f910fd2c1fbfb014538b9eb5ab3e7862ffa1c80cc5d16226ea3f96fc3a672646e9a2c06e7328125970062345b356679bc157a7c0fe15b3ba04ed70fec6167addae4adfd88ad148d18fc7d87e890acb512d4dffa245f3e3b2ee723f6bc7fe2787b4cec72f4e39e917dd39ba330d09eccbeb2c5e703ae0577950aa7dce4a4bcfdfee6d1a2fbb11a402dfae58e8a60d8fe2ef65f5ee64bcb422a69d739627c2c5cf92600af2452986c752de9045816943ecd27acf033e7e576c8f2c766f9154d8b04de42a0d0bc0f807b45ce3bad3fcdd7295961d70a460621dbc90bce7685ea426939e400936e355ea9af925b3d2e78a165\n\nInput: 3c53a0b11e41857cbd821b844f606f25854f6aed8717039ecc91939374783679a108f6258348927a2cd66901123c7feb55e165179565dc4ff38d0b560e0cc4\nSHA3-256: 11eafea069d8aa20a4a0e087fd4f62540ff02ed803f090e49e8611d0a322bf95\nSHA3-512: decf3d3e66beae6ab2de0647c73de1ee0c1ca8d9f7bba2fe140d22a32fad2a9fd5dad3ac02cabb2a39b33ade661e449449f9407d7eddcde772a81a15efcf9dbb\nSHAKE-128: fd35d1783e53a508f235f076b827a519af479152d725581a904c7b740f4fb5f1c84b2e3eb3097b0382dcdc5c835777f3b0e9f2bd9061dab2bfad12bb8c8369c775af5940502b6bc2600bf987d8314f3e7edb73514073309c4559c3376ac913e2f30ff70f875bf26ad9777f032d9b66f26cf1361e29d815d97f7c38ca038bb807a9df5069563c6f1c2152fe135c96f424255599507692bc7e74748c0afc9c198d836870c50657db969baed3a0f8b2617c30696bac1cb10551fcb036e3e9562e622e675cbfe5edbe1fa2e537282f2ebebef7e93d2d15ee2d4093ca1b93e5f521347ce647f52eba77e578fdb0ed32dda58f300ea425d168a1b3b220a44f6ed30d9d0b959531c8dd4d7a507f67756ec9a2ef3667bf04bb4a8f298445c09d5a9009e1ea7e525d90a73109715209e4fa95fb1604ce1baa5f7030ffd5fe8ac9ad6751900d73cb718f471866b1fb9a49509c6de83e2aa797f42c52e27ccab8c9390de3de4a7d2b0bc07926e67a4daf364441f809536da9d8b04895ec60deba438a32b33f71c13464c187858753a0e97edd3c6c708d00f25adb5864e08b9c955b8aab1ad335a05895ec8f6c7bd913f2289a4ef318ed9cbde255609d7fe8879b4beeb86d2fc445b5ad37c29f48720ac65cdc69dfd33b9a6ba632bea363f305219b6e28fbc40d3b0c7c31bb9a740851a01a3030c247e5f02698ba7bf9de3ea07e312beaac96\nSHAKE-256: 236bf57cd87c8bd82f7808a880055c5ec5c8174afdc157eead42cdc5807d57c40df54d7363b077c57b37999a344f85eae50292e712e2dd3f2da06a0859257150c20be81549d64ccfc265704d37a008ab651fd4ed01f8ecf436c66e0fe711a753284bc5fbcdf02ce5b51188fb3b59b016c8fc116241f1200d6f5f588efee440a7812edf60ee33c06e98a0717938b9a65740db3c172b90dbc9c973fec0d6c36a27d1485613c4d430ce0bc29da145aea9c3ec4713e7555be6e8e0d5019ac6da5916e97e881a72ef0712803f3202e627eb64719af50d9b9f58de29a3010f436a0e0f869588a7fd05fc23bdd16023bbf82e92925deff6b6044ec987c7d9f7b50ffa2e0a9ef1392dc4d0c5bb0c3244cf3f3cf1a8fea1e87d61465989e81621c50c95cbd21cb16e68af075a8b400c379349ca7e2ebf5056b55aa3869c843bff1b04c517f6015cfe93f93da7a71a5bea89973e3e84686851da1e1fe797c5df34c7c7c95b82a2f33a7a4182f8c906174c3767e1cecdbdfc66e3f9b407a55d4158f77626cd0c0cf7e10ab13499199eec6ec356cd4a6286420bd51c4f139dc86b62e2b822fe39b86bf5b7fdaf6750706a48ea8f297ebe5cb7934ee8ec9153f40a0e148fdfa97a612a90f4dec889a7e331ea5d9c940232dfe365b53c8d9782ac0ee21ced50be3ab0b98140dfc06d41577f6fb69d84662bf207179f3ad27f2eb20fc16dbdd800\n\nInput: 0bfc630357a46239c4a9ed1aa5e421fd9a3e3ef1f2389eecbebc869e029dd6ffddf2c7f173ff5f0bfffbfa2fa876b329ff7ffa9ba2f6844176eb85dcbf2d4d5d\nSHA3-256: e3ff4bdcceb21003693e2967a091c3891d81d119234180f86133aed009475fd1\nSHA3-512: 0a59c2905d85b2c36fe3eeab08f1cacef0e0a3a19f6f0cf47773f5734dd5ad47d6a7e4eb3edfb70c97567653c3e4ec8154af29e203f126c568e014b2566c5c99\nSHAKE-128: 728274a7c07893eaaddcde6ab9cf4c95279501075bad804209053a1e644f632eb86cbeb737b4bb579236e2233692da728c22c40bd3440f050a02f5f894937dc5ed6be861ec3dd0e34eaacbd145f7e4599a5619740296fe8fe8bfa793c281ba8bcc39d290b9b56fa976e728049cf63d380a2ffbba099481e1460db038070de1c743eeea25d228735e42d432ebbe092eb2d5167ca3a7c8e02528e88e44aa3107bb1733d966ca4a0905b8f4434bca171ed83b183e85064b36d8f41aa57a9758c3667f75d9829fd1eb8cc40b8db89973883b7154a8294e74536b4419ad84ddb54a4bcc8e0654fe259638c55d8f0a537ae8a7bd3d46603ce4ab2e6f1f2c0858a542346e63a81b414bbc537f4cd401d264c6b2b7ef05a9303399068aee5592340f42ddb48391528c0aa79164c364b9c326e0b9abc7371e97954eb7f7e61d66e11b69ede459d4aa676da969daf4a62ad9549483f37faaacd8fdeb80f4472a51f3be2e52b51ad7b0e8f7a2c1bd72fe505dfb10e3d531ca78d1fad7beddd7d0160b72b4617069ef25637633c9ec3b97430090a4be2e2c56e1469f0f84e5baf4a9c6d347da831d6b1cc4cd89704b37bded9947279d6f4fb43b5bab68b72a0a4fee53425ac77adc8a5e9a0743271b0dca2134ec407ad79bd79d46c43bf13097bda90def112532b57a2d55ba659c201295a43b1c6fd688ee7854c7ef10abd69c8406e24cf581\nSHAKE-256: 47bd1b499562670a34fff9df86771d1aaf0f63a325fddd85a9d4b91a85d401c9f2bbd60c9a1ca5f09e4a3e0880e6b850493a2bf11cc42f5eb3e766874876d7ce92568c0c510183e979573d661f869e5c77e8c988ac1f7e3e77979e6dc50e8af19f6b6e87a19e1750057c6f533584fb558ee5ec5ca6e0a533bb0b433b9b22b2fa13240a21130eed49085e2b32566395578e42a32c7feb2aab582a41d90c223b7d88f78cc4ebd4130b5358f582aa5330e68b24139a24a29cb83e685c459c458cac58ecf0ddfc9a5f278d43f3df21a15aec9018c95ff4f7f6fbc26ce46a047592338c369bf155bd18faf0d75fb7d85a25c0cbac6151a8c507e1496545916c9d4d4482f6c86ad04310317288aed0ef414e2985395f7515abce13101304a213dd8ac8e5dd4e00e738bafee810b4c8d38d3741926fdd8be93a8f17b141bd98f637bb97e817d27f9b0deb8f360892de1d5d496d573dc85fd3864a13a80c0beb217a26da80736adaa71311913edcf15b15a197b0568ba9d08232824dc2a9d169048bdf1be983159256190628c86d13ddd51ee25cf02f59752334b341ea24e5993df3f0c8472173a78cd97bb9e18f604414fdff5a1086babe421c5d95b0d9fe9b8fcba84f5ac51ab9731ad29891ed5ef94f6f090157160e340ff078ba2c7548b451fc4056b6d5bda83cc001d305a178286e2eeca4b66dabbc08c5823ee0450474eac6fe35\n\nInput: c493a93f3eeb7f8fa2ad1375ff7189945595265bfbe3d0aa987d55eee05574b9a69c5393e30ae256da33a11058d2ea43e4689ae63ef1864753570870cfca7068c0\nSHA3-256: 933e13aaa54e1e3e5330c8995d18e0f0ef9a74c9dc7894925a4f99726b683fc4\nSHA3-512: 7b9128362284a109dc4737166bb2b4f2861d76c720d77bba9d42c51f2959f74108e9a9975e124173cea9686664b570921497706214272b3732bb9a5154752f7a\nSHAKE-128: e3b651aeea2c4bc184e1cef7bc87bd88065fe2c8dfae4f585e4082c057c787cc3f8bff9d5edc5364e750823729777b2b5cc9b92dd6b65117ae1d4a8ae576631de77a291e65b11605e982066a13cc3102e8205db8f32bd58c44546426b47a5874aac7399b82e4f0dfa9dbfb12eb015fba479f774670e565e6ddeafb0d1a3e131c0f7055592902fd254f1e5ed955c83700397e4da7a42e4dbcb01916741a854584aea774ac0a6771ca7df1ac3601908d0e9ff7501a508f66b07376d562620742d8dc879e48c66b720f7dbc2bfa2b9e00febf84f1aab1fe810365630d54f126d4bf227fd35fa69361e94847d1a48084f9281f38eb6758a938099a587d753281e35d6973f410db8ad9828dfd949e89dc8aa92e5350e82b7c128ee4e6eb15fb47b61af326289568a2afb216863e4b428fa316435120e423fdcbbf05a7e04cfd57fa6b1708a181521699beb644130fdc0fa9e66f8b05df2f283f80971641d5bfe6b8aaf224a60fa813f6b8fb029542272675d170787ef9dcbf862ec30126ee17af7d5d57e6ed0d3e876cf9126e7ebd49aa86f72ebe2d7afb6e023559f0818827187ac196f577c6585fb7227aa40f395bd2203c62e4777e6e2d097d29895e967ebca6756005b99c519b4029de633755302aa6e30df6fb86e06330bb774c0492ed6cf2bb3af1257628e96a9697edef4b9a787ee3d6b324c1491bc220f3d36bb7a2b15212\nSHAKE-256: 8b7f9583a76e483b7f6253bfd689e8a633243a18cc377814bc304cdfebb0e1ca08ce2e593caee6442477548066a74d4cc07ede61400fbe276d1a1e1389ef7ca0cfe4263e448e5c6a6018f288f49c139d702b707782afe199d83486fc101fa2473925119062343eff03b6959a581c2e76e39e9a92cc5ca1f40be70e19b113b19f6dc634cd7c37c13ea91887b5cc3890c6a03ad0d5685fea9edcbd64a838a5d633493c900d6677dd3f209148a010fb71a3205161ec8f914dedd0bd5e6aed048cdc216f8e968c6bd02c7ac2392b1c5016fbadadd366eed11f5eeced898f074708c24bfa453a4658895861e32415e9d8bc9567553b0e96cf6f318aaf2673933243eeb66ecb8f00a9a23ace1b0f9022e717d8fad6ff2bee6dd0926df4beec5baab17e1bc83918136c0427869efb0caf9353070d34bc3912bc2a27155ffcc4a2b0a5aba2a00a989ad57abea7caa83b280038b2d71d6fa82288c69822e17b07f08bf15e8fdb8c62ff1b2b717c29122e6abed21e2161d854df98e76b43cf90c29b95ffcfa9e69afa37679c273b74e00623f4c3591a0f260fb56c853e4281e54bad61076fd4dd27d0ec31c199671ea2d242d06b4630116f31bf8885c02579a750f43867a2d5ff3970da12ed3cb56", + "54baead5ccdbd30bf608897c5b45fd289d279ec44aabd4ba946e45482aa65485309f1b436b0f97c762594815dee5212ebe78f7cca65d9\n\nInput: 446a5542aa0335d67f1b22176e7c9817c6d172ac26a741fd85da46b01fea43b0db0968da07fc7817e95fbaecbd441e0141b70e13aa59873fa91e6e93e50b6423bb5c\nSHA3-256: 30c29bd416ab6a14f640ca9115dd8aab86218307ce00383d8ec87220043210fe\nSHA3-512: 92694fbb0587de18866d9281c312831ef5e7bb6ea36259faf9638cbf106f0daa3b45bbb770cddfe919bfea61741e2a58036c3264f320320d124cf7877b11bd3f\nSHAKE-128: 71274bc8e44a45afda79ebb794240700420089c6ea397a557d650ed2b5952a99171359a5f2afe216095e5991e5bfbfc7a8c25d329fc6bba5ab0ab905ff8e1981d9b18a7858787dd9892ccd850715a06581bad3ccc8c4f3be2a4fb62b10e427af9500b9be425d8b578b4a344db0aaec29a19cc1cde8cd0c80f4f4b0986b6c0c491215d7c9615d4ca8153076ea5a1dea0cfcc9d93d3e261d8c06a87772be4bc1b51848d38aa1390574f2980bd35e08ea19ff1cf7dc48adff572f7e44ef9c8123e8fb820ae80cea939ebe0c489f8157fac2e4b24007a7bf21629023694475e467c6c8ea5cf93f79aebdce9bcc68d57a5d45637687c0a3c0521501145f711f4202577e63fa4f0d1dd02857f082ac8e718c5baadd1403af588a6c5ac6f9063be825061b2f1ab36371b833a44143a5ad8b31afff66f5e8c2ac37d469678ff9068e13d9e211fbdd71a7b4abd17fa6d2dd06c6eb8122f41516bc4849a15e20159c8a953bc985ab5745b8197d3a04e2128d6c5a787700582f29e91d2033632e7bae715d00190370bc8630e2a36548382a12bc0dc84b259576df2fb04af0554d6e5b57d56ee078604f7a2b02c0778b96ce28f8160980b25a78afda67a5f62aad286e1b0d752c2eba4cccaa109f0fa1beed137c66caf39a82103482611095fd6056f05d22d709e21d4487f84035d831ae5bdcf77bf4520c6a07691b029d5c991b37734bb54f\nSHAKE-256: a483f18f71fcbb78a30af0e0f3831fb3afc7eb4f2cee7c46c7b768e2bf166265a3441f36234e3e12d168ac8b241f08e97217f6044b24f8ff48a2d04fc1e27920f0be8469e082f878389ea6319793a9e1a09d8c7e5e3690feb5590e3dc9e776404e4a84fb46acb1e19288c94bbd262749878a5950ddb6cdc190d90064ca1b91e11dc950cb386e876a6538d9f8b2013a8c491a3c15017b68a6c74158c67d73b92f1478a65acbe36b053cf910e59b92e2649e9a535bd7e5b7e5c1acfae5c8ef3dfb9b3a99e26f7e1377bf7a019d18e58e2a9373a79205e3f7185ac78126cde2413660cffddced977e2a32bf532817ba09f70bc83fc609d8639e92d536a582afc5cb5873ef482341204f6818d6db3ce902b85123dd4f52372dcfa302dc93255d128565224956a61ad3af0d4892952551a268c3d4c0ebfb2b5c76d1015c2362216f79009359c6e5eb3bef4a618c1e865a4eb5e85d89ac3a64feb76b1d84ebbcdcf69edaf7a35f81a24e54d47ba3f1fcb93762eb73c9c2cc3b644306fe590c27ecee9197c1802d7ccff4583e7be23a42037236f926717b33477a61b7a54ae8f4934281275509356ab9079158a7793f298dd0a02a577ecbea6461b1701e4e6777a2d48ddf156118b68836d029f7ebf743fe827d245c951274c93f8cef8032097f391586b659b761a5f551b02b413a091fac65cf3592a992f02cdfd8a32606f24050ae2a\n\nInput: e232eb3948cc2167e2658a6652b7da5c5ec6d43c85264d73451817dd385a4e65c368d8a83e4ef36fef5659bd8903d82eefa8f8c6cb39e4fd1d473e110b0b1993d4c4dc\nSHA3-256: 2239e965239941955e33f82786da1093fa7ed00175b07a17ef8aae148805fd49\nSHA3-512: 93e30b220e778566049585cc57200be471e3cb08faa82bd0d368a4ecbf3d173fa60cba84fe7f1933a56a419ab5a3b477d0797185df39922e8b5e14dad75c8672\nSHAKE-128: c14b46e44b19014199b9addbfc061aec923a8952958a2939ef313f12936a8b72f935cbafc3ab912b89c166e6e13f0e31513be67de9423aec889c32db485d11c7c8a48fcc61a013ba5ac66efe0d5502689589b1bd2bc0eff94b65d35370d461916719652259a71075d901f9e5b7af16e0801941009c4316eb23033462df3978a5d3d9305d32951353e3f83c93815fac66acfc7dc26051461418cb7b5e9970c595b8be9c207d453dda3f37016a7e52999400a2ff24d8d5468e6187284e0a962074bb9a5492a13cab2bc1638c78ce96e9a9e8d38e60b9d350243682124c9b85929cd6ad2e1b9a59ba333dacd6b3d97f75bba45cb815d617daf64b0f7893c8ed202330aca4144bfe6fae8a23c30239e0e6b9b5af51c6e010c43ade06472c950f4e0aa2c1d78d1bce81cf19aa7c0d1eaa247dbe750b04738026c6425c9bec85726b4c1a6f26d0d817a60ce9308cd8e60102e566a11a93e9baa588993a40482fa783a9a833815d8d5d82de8140d2e1036e34e08578cc4866eb5cb0ae1d2eb22eb36a9373ad74a1c0a43679d7a8c1d272d2b5d5d998b9446beb6af77f68c11230914fef2a9a86c658a894557a94158376a55767dc7270fd6f3a35aee4536a812c97d44af3e8bca1620645c25671e3aed9989cac78af7ac2896eff3d857b2b718bdc856afc0a904f8afe8b3fc59a7695926c3568001476d2b5179976361d532fb9fab298\nSHAKE-256: 76110579fdeab911a296dc9c29900661ae8ad404c5012726329a74e8cd27d145b41ce7fd165edf068abbac7ab7f313fa1caa6bd647d73bbcb7e63132737a04daec2145e7f76914649fcd50ed6127b021e8e8eca0d0e5b084c0e24bc8ff6a43ae81082d5eb7b21eeda6f40a6ce442bf7f6e9132e9dc8dbadc43ae79ad5c8be8bc6c4988fb3a3a2a35576d03ef7b4ca169a1a36289c2bdfad398a4c86c53de594f32b2fa5c8b43e43d13c4596d8e14d79275cddbc863f233afc5854354c1589a2f523a50a0434150070bc2caf34c55fcc397d3877dfd586888d45fe86cd9d187a6e4d97f979054003f732afee583e9701d93de679af806b8e8e498bd1cb8617b9590eb63d786c0e5ad88bebefeefa280aec789a96f3abe7a8b78c09268831f216506e50b55abe1f2c8664ce7c6767a3069796c01213b3bcf39688d1b69ea4c1b18e07f72b7eb79c1da6c5b0403188f6caa00298180f066ebb7b2d816b46d8504ed06bea93fdc467762f97a17605229dabb38b3b25cb92d1f6e13217878c6b83a14ae2f640f7e34aa203ccf64c233c51be6d2925d971a5865a235f265aaaf108750b33e0c47b23f733bd1649ed51aca270ca0e48dd5168d652088a2aeb5f94e09a12475b398fa5af03583d1fff507036fc6f7d638ca8d944186724f61c8a50daff1f0c76ef727b78f4c5eebfd54cecf2abaf143765f4d5ca962b9962f042222caa8\n\nInput: f685aac046b016ee5d6efb32ae7b3d021d63a3bf5778a80a3b76b1a6ca1af12fecde9b5f60f6380733f5a5934948980b68b8cec7a27a317a39041e6f0afa542f939f4815\nSHA3-256: 2ad04e6a20bf4f00a86ea729b9fe9fabba8cba8642e7e8964b0c4dff93ad0244\nSHA3-512: f4cadb9a533a93e597df80a32e515bbb875035803130c583b81d166beb1298bd1f7b28241ff3505ccd63825ae8fafd726e3b99c3adddc17b1d6f79b5dbb713f5\nSHAKE-128: 84ca5b836ea1518c8812c24ef0c866ef99cfe35633738f27ccb92ff8ac4a3ead7e4cef90d42c19f2253ebf3472e2bb38306d9bc9e543b71e2696ebcb12c6056f2ad157c27573b6af3e93085a7e3db7c766dc4849925b7389eb379284ab8debc72d41e8974bddc0e798ba888131d5440b84d7786f869de3cdec60fbf5dd7af4a5e9a588d361799e023c508c854903bcffbba8bdf45697f4c96b20c898f8ae299ecd3685ea9b603554d88b3ea205d60234a336afca3748a06c0948329d6b122fc8bbbe6af72f6b4e7ba1cd3b958c9f666288502aa96e85a1794ea190720cc9f3cc68a3e203e361eef00552f847cda4b6a7540db29c215d4ee9e7a30b0756f4717bb91d63bc6bac70e5a7a4f03b28d39f9aa5b859aa3a864b1f5cf98800f15096de1fdcfd7dfebeed7a84260f14e0b769d7ba7383578911d46de1164b5f70c071f83582626efcacd206679b286e50c579c6bf72d3056462445c1d4f1acbbcf5353645891709e4ec465ddbd1c22a19a9b4a3b857a8a37919b1406fcc785a46547b264b2f33766ec8b1b07fe595cbb754cd96e4dba8ea90ad93d26dfe6c581e2670f27695f483de1293b9c0e950301be9ce5e753028e62c636cf55df5dbb43dfc8c04d3d655007b84601e0887682e47a9d8ad573aca39231da82d957dc2f1963ecfed54fe0c566cb6fc9ddc2787b61939f60b73e9611a0d4458dd6e2ab39a03f93577\nSHAKE-256: 33326e9dfc09ebf385f246548b4f667441fe2bf9f0c307d0bb90f9301d0a6d80e439ead419d1db7488e8f06f70868cf9291b81a178fdff85924d0123a69af1fd7576d26cfa07cd5b5d39e5364a3885387ef18337c50851c11dfb1cccf827ee094c51d78910c94400b55c249fdd63dcc09acda120a1cac629e813536e0f9951cbabb7462ad3f085a1ccdba227a4cc0075b86c02350115fae9ad86efc643ebeb01c486f4c00def25ad251bf8d08be3e669f5e4f40f14dae6f6c46114a2b23ef4e82c3de0ee95610c7043cdc602115fea6374e9abc901041ff03e09192f950f4ac6a259cff1327d5585f3ebed3a4267776b8e40d3f8df57bee3d2b60a855c0514c1a6594b066bc638d1128a1526c5e34fb3d63e53f345ed1ef7f61e904b290b3cecd4e177f8b92321a979f010eaf2bd92d724443af899e3dc9f4334f6d5596d62c97b790068b84dbfbfae7928cb75870b5d648c5b1d54c5317e47d32b1b976a42f96d44db23c8b2c7f575e64bc7253331579cab153d53def42cd710484ce83bb13e4104494ba1577c97e87ff2c0605e0c1216510a5443a4fb5a9a0da68e904f41b2075d0b8c2c270430a3f9a343f07c8fe8b55066ef63cf2761a0444b05a5c788bab3d22f2caed58eda455cb834fa35ea7501ce06167f223c3541c09e63cd03fcd470652c9f7e2d7c3d1f18b3299d42138bedb51d0b60286bdc9e1978f9fbf15e89\n\nInput: 83d71959ccd94bdb722444897af34a1f241136631a86dd8883c29cc41ed72b719ed228a210ea76c4ef69e30897434fee86b062f840b33934d8e9d85b5b2dc0facd6ecfc5fc\nSHA3-256: 15d713090d5d4fe8175ac0a848906c96895f60379a435c8835d5d2715dab949a\nSHA3-512: a9f6021bb02367ab501caf3153e2f2c6dda96b55dcedd060802ffc43909e8e6874cf84eef86728a4c7802817b923d5f85d458c564e19195ef1c6fac9319aa221\nSHAKE-128: 57e18d71027861eefed813d71f32eae2ca2573dc157bc5d1a8902f35d8ee08b8556daa8fafb7ee474f3748f21475c52d3d688e822aa2f5bb8d4cd991980d3ff9cccd521d4d6fcf846eb1c8ed9e5cf47a013ab57c95a8e5c2c4cf5989922e6275085a8e07251f99e17c4d804b62e88812a5bb3ca97f52039717ef0e99035f7cb60ad699a8612bc82a70c38c6a26a62f549505e9135e2a7757c38cd99364f4c7a1124ef3ea134f540bcd0a44a722b1fb34203b5b75063fa3eee9bc9cf4ebfb668a299ff6beb7fcbbeaf6733794d55fba61c64c14f", + "71eeb6f41346282dba33ef7a1dfd6e9b9225beb3dff5e20650059150e64a3b6f5a3c21ee29d9da8c79ee75c851cb651204fd67e73f30736eaca8424210095171ba9eba39e680ea9c394d21ffe5a7543ba0d711de23de6cf93bb91549211c2fabd3cf909ad985262c55c3f13f22e477a86729b2ab2b9a11b4e0949431ee2dabe021f5b37bac854bbfbcd6bf73d9a9be2039b34c407181e7532bdbdaefd6cca960334b9433e2c4b46a7029ef9eda8e18e0127d082761a1a8eee90188bfa8d396f218604d6380da6b3fb0d1d7ca383606843f3b538574a62bcbfef6933cb9d01f6ca3a63e61b33eace604780f6a2d3d5b05c460fec1b07c4eab0fb1f110a257a9443c855739ba6d441767872910fc2f9cc3ed3192ef5768fe42444d692db5d6709e35fdd3a3a324df68e57fcffd5\nSHAKE-256: 54dc72d28ba8ef42c88c558eb19f7d87ccc160d5ae857351348d288bea1907c0722f7415bcf62a2cbc327adc6cc9025d7816fd7b5ac6aa87c3f4271bdb1f4ebd6ce04d124282be98496e7daee4f35788df0f85d895bdd16f5058280e891b6a973afab3cdaea18ba77cc992b1ef9ae1d008d3ac448b225390860329690b1a6b7279dc58f8980002796c527fd46161ca272902c7b026aeaa38fcd24fe97eec536dd00484219b9a71198bda2da1ac46c141a22e913dee5172b4a9042c20cecfddfa79f7a3f8f22792450e7df2e311741edba0c74257a1ce7a9adc8811b49744d7cdb9e65ead7d369c3dbd6d4b5e6518f7c75a8746ae7e2cd1667ceb9cfb3c0bd91b0adebe5e2c4efa9cc30d04bba33f5ede1c0dff87c457a122757ab070b0c53067567c2efc31486ceb11bc470defb50a204c938f6ec9b549037bd06f9db408a4808cd4773b9c2bbd473e51d3f53f8a84291f5c7795ea7d863eaaab9e700dcff99d3279b33814b43e50e90116ac1e3f65cc6b6d08dd568296c686e7181b616ab2c8115b9a782f206176d8a4697f7e8ae41d973a244109354a2cd4247d876d13c1d2e1643be41aa2718f8cd8d54b0e1d4436259a2a889e3f533b539e8225ac65d10a74f59a9af1d6e77442a321a11f5b42cedcbd840a8e0add1393f01f41f0519f606dce8cd260bd696ac7198d3bd761798409db0a04294908c504ccf2592f4125a6\n\nInput: f524741527cbd01fdaa1f313debe5e0c711916f053dbe20480af1c8e52eeb1e28f80403fe3d5042c0a4adbb8283c2255d7c6f99eb190d911af7d6f01cdf9f81de3ecc65e12e1\nSHA3-256: 0095d0c3e5fb1ce5b1e507daf7ad9c49f285654333406d3c60e0f738fe49e6fa\nSHA3-512: 3ff1abd6e788e8e653b46a326f24c2dd17b96b027d4809ca8ae61eb7786bc16460560c5842087c9a3c046fad44a562f415f60258a00de1cd661b7cd18d5d7ef5\nSHAKE-128: e96d01bcde4721b7153da2086686538ad8a5e45f3957c12de12f9e32e1f33d57aa22ef14fbb8ea9c93a233f738bdf04018dc285f6782e85edb0c1d8f0f4a1757ba684e6b627e3574e465979f8382de10e78f92b7c6783eb361a108d72a18cdbd5e05e928f6eab746d544414a4c36a01e193582562adf06c0b88994b3284ce805234dde9df671d7816d58e235d0fc24a96ed02027e10dc3b6da317d4e5aa4da93451c520c17832202db4860a5efd30e4e9dd6a5cd5e4ee78f941018963c6059493c47bc661cfd6ae8993d32821b4847bc7d58f817295f938d497c3da0d99bb55bca3a1c8ae90e6f99392ea3adfe35d3c34a694793b625cde73e76b2c8b562138c0ebb899dc50a452965e2869bcb902f5507c222546a5ed893de70e3833337a9525f2c1d1fafe8d5e21888076a9b72410a7f76908432fd2f64e3a712bef9fdb62176ae537574eecd780a1288dfa9039921703e19f11fe49a28d4f31029bed38435a892dfcbda317c882ee6dfab2b5d2001b7bd530f4142424a9288de3513b9ae0fcf6232c515dfe0802b5f1bbf464665435122fb78680201c5028a75472a89b51142799e1125bea400e32a2f2c23e4b904ca475c5e446984df593719b6d38a3c14732cfd5739a065ef9236431bf67290165282adfe7411274b5598aa493b4c5f3bd57ef4162d678d765027fc04e1b9a6c1ec40576e83f0fa27786a365ba2db7339\nSHAKE-256: 00d50a80ff6cd547b74394eb4da8bf3a0338007acd5de6a2a1c53632777f4a85ad2e3b8c13c6c98283d6158dfcd7369d0d6b159345568436a2b97b58ca9c55394ed9f8afee36a10a8f1a66e4e8f34102581e30d55342faf30653efcbbdee80944a2292688c304b1fee10439b65db3bc68c05c5ce8a82092e4a5cbc81c1832402dac13c16a6af8d987264d48dc9b9f98b364103b114dfabe1f706642626d9ccda5db02d9424740de1f3095d0a61f72389ee892a01b08cfcc575ec86b4d20d98f502800d8d44173bf149ca7bc48ab80374d694e4e4ed68c29b82bf6c23d8b157a1048899cffdb2ba74a66f701fa65fc7f9d97f066c6f1756c9d098c768d01548f63f8ebd7a83b34cf0302b0dfcc8dea59ecd26943a43e64d2a59de6344cd8f2ea0914631fafeb871e2c2414130bbf2d1947ed63e0fabaaa4486a43fef28d6aab4515cfc23995dd59871b7887573dbcea098474165960258b481e36cbc4e6dd3185de1473aace4ecf77d63eb09e4ffaa7fa3376c7f704ca49601cf3dfb0abb5f5d5186e5765177591a6d3a1d6a705f738252b38bb1ba3de28267969c844c5c23950d3191982062008b87946499cc9a329cbc79088cd923813fb1f739529f24f1fdc12cae7c5c287ffdd1f0d5e6a201f8f464c0f4394b6a5decfa7afd87a9b8ee625e664a9a6cc737934a31baa3b1ff7943197aa5e68918c0ee52fcca028cb95db83\n\nInput: cbff1209f9c383d4cddcf902e07dc780afbab61ae4f963ed2ea87e06e9f0c77be39b9f9eba43a045e0899a87a610a8f0c32d11e506e8094b6b269ea91e79b6c1abd00c90f3af7a\nSHA3-256: da5a90b0747aa27bac0cda0294a5b4524a46069775e00d43900a5170f88c273a\nSHA3-512: 61a8fe7df85215fc57234db4aac7c41f8be1876f7128160324a5f4c0a5c7105a64be79cdb7e67561be21bffaf6e55da64b3b3321834b4c18215c779bbfbad530\nSHAKE-128: f94b142d3299c018fb1b67a98fa54ce27c336cffffd9999a1b73a3ea9f6d90c95bc56a377fa382b31d9fe456b31a0872cdbfb5bfff696b0421459cf8465943a9354b4a9cbb00f906df2adc8257032307ce6efa3d70e27a99cbd5c684aeb6843da781ffc20d7ef2f28bbd3460065865877f31f8694e1cc08525290efba5c20e630572169ead9fe2e052049c529309e753d0486ec5f5c6131fe3c4eeb2dcf7fcc95f3d0ade91dbccfc02f450a0bb66103da5d95661602bb86755b0e62e1e68aec5507b7d5fd751cf0a353185b5bfde2b89e11564553a5e15c175c438394a013cb362c0122bd088c2c2d5db1fae5e2831cca6326ad885b76455d544348aa1b696eda12431b24e03ca02e21b681f9d051f0421bea719cdc5b2952517e2371a227b90d015ca1ac7aecc4963b777b246a9e04defbd743533f4c0353e92db10f4bf0e3bd35c3ee1d2510e3870f8e33274bc68c1e350c1249d3c085551f58ddb50af7399521337f3bd7c3ea4042bca7021a90b5f361d94d91f0cb9dfd6dca02986b0eb4970d6a707a3cdc8ed37dedfaece5bf6cd44e12696a8e70f5acb0dd896e84739cbe1e81d96d4062f745e98c2459e4b88cb5b371d9f6391c474ec43c42b920201ea31821c9ee675a068e4dc02fbba9cc7c0fb2c30aa80ce9a7a1d41ecd83da2b9029f0c0f20ed9baeee1a75b434c1db35996d8634ad7e7bd80ccf100159657bc527\nSHAKE-256: 8eb8f740662490fcba21b9d3ffc9e8fdd5927ceaf5288b7eb92b6c716cdfcfe60498ce5f70deb8598e3e43d17ad34f80dabbdb5cf266b950230f0ec5c0ffd28858d3a1b9e42fb6e021517b3d47d36d8c1cd751ce86433c3d219bd379678b518e52eb2fc9b5debdf13dce59edba450d0c20456b60dc5f513a12a533c872f9fb2e8d4c63ec5c28be79efc429b4920f60017c1e8c42c22bc592be91d66ac8eb092e85442649997539d06ba3e3173b486b60551dcf2026f266a3f67fc3a51add7973d7527e95fab9633ada3849b0e0e98f4703bd797ce1ab4c549685b3f6681ab5ecbff1aa7a91e088190186aea0f78c5e93149982a142ad7a518e7ab9db6d3d339aea6a0a971d09474cf97f23cf396ba54bb2311b0c464ebe238182b5e4ff7350806826e89def107b9204cb83df3974a31e63b2f8a8c820c36baa9c957f4ffe196674c9c5dd0917a650f803b5f023a8e828fc5fbe8f7c2fdaef1066e3f9d11b6a3b3b651c7b0207c27cae1899c1649f2592a8943fe7cc2cc1b4f70bbe7a276bd53e5d780176b7545bd5275ba02b275a4a7cfdf829f6920514bc02deb9eb993981476e8ee3b7846de0c26643e56aac8557c31f0cb5b8a7e767073e651c57ddfccf51cfe769e1c0761f6066d86534e3c2b33f2f1801ae40168294b014ada5a6b8956a0f8e81e8ebfc3961edcee8d5596f6f738fa89a0b151e959b546c695f52741773\n\nInput: 91e6c2992563533da91c6c2a1546b18fd3aa48f1e601b7ccf3888c18a8c00efeb20999dc811beb2c09ddc11d37e0958682508c90f11de5e167747053129deb69d0d8594b1da009d7\nSHA3-256: 948b9fb49309ec0ea5e15dde14b50a98af48231af3788188423f82f16029b39b\nSHA3-512: f9b1d8cf7de9d77623ee9c58028aaca313f2d5ef1e7e18766f384f446469edeedb6eefd93589f938544ca319f57f160c451dcd42bd22ef30e60a392767d7bfbf\nSHAKE-128: 3fcf6e900f8e10e478c6076ecb2002aa6166461ddc36f0e4315e470958911007f46708ebd79746c4f32e5135625acd24ae721e9eb900973366ce15619a2ecc379ccb9ec2eb14e4f4ac96e427031a0bf47489cac3ace1498f4ee1772605287bc7728cd0148ad132d20f81e85457e6c86a3e4fe5ded3f322e69016430067b3e8b868c38078ddc9a5cb8f605bfa5d5c6cd0ac91921e43448ed621c6f6cb97b1ad0d411db3e34904285d19ffe827bdf56df8da879829ff394426631cb6ab415f2e8be8f45dc072afff34d4683bfd7f23f19a9223bb6a212b35a0431e00242f7ebe7ec0dfe1ad0850129d89c6b66c506f53a4b0c357e6a3b8a164eef9cfe256255253718a6f56fb518b0dde5166d23c5593c39ad4871f1e16f45f38b976b6b9ba8f922005c0bdc7ee09fe8d16bcd5be7f8fc84316e6aadb611afecebe9e20ad782fdf42292ae64cc8be119f4dc42d7f1b1e984c40dd7c8fd88b42cdc2a7d38fe68853b412b5c644efc10ef3c52a037779f31747b3d1febcbf2f8b19f6666aec4d6c8681951c1dd22f79507973230d1bd7ff9b3fd1bc3a00aa443ef5a7817fec7a52a1f584a44d72a39169acaaac0cc6274c1229679c052f47b02002dfecbdc0e5c980832067f024d4dbe1a44aa593f2007c1bdf2e4d11ff79062c86d8d3fe08b827a04d8f827264e889ecde37f5c392b594beae422ea3041c1918c35adef9a9f8f45d\nSHAKE-256: 85677afeeb6b08a5fc06bc2a0e5fcc4bba23f7a365df3a4910caf878ddfbe6e6585baa75b5b7990ab252a9789a0fc3d10d136a0bf7467f640fd4eff193afd865cb807b79e292351649d713f6cc685fee05859ba9c64c3fd49ee4a88b2625fc42d03f670ed1bdd1aacd266f2a56264ef4f9a224468e2a6637f2c1d5d64c9e948cc5c47b791d59", + "5087f991f81e2b8b0c38e6e0b59c1ae60a586d65bd85c1b8e0338031878e1ca0f9d139f8436e483c8cdd73965202fe0ebac0209c94440d09754cbc099cd0260ef4ff0702f15b1166089a617e989992b18b923662e2609bcc06c227b3f87d1e327fdad07f0a5a054a3436d7d77bf787c658a9800552f98f52708e2d3b649d77ef2b1ebcf7cfd672da132ae6ea5b2d82f6bc7bbbdee2730116142527b861a2a0b6b9760c65400af4c1f8615fc935e71882428ebc2bcb922c27b38af3c635624f330cebdbacce7e4864f5d66fce20b0f9c93721f9ad1507ff664fbef83ea3f64fca38aa6571f4978f1022dd1341e624740dfcd3fa0cf304911d62ed16854a84ae7c2c966e2c329aef8188ab8ba80623f680ff859ce00dad35ff005b12c09068c31f2d95c68dc77416c932a6ce062dc28beff895794b1faa8b7bd5bcdb0af2e16c180119a90d7484ba9fb6e45b161df982d08a0511ec32846b58560ebdb071d753fa3ebbcc89d7a8b84148b833a81280739e2cec81a6cd812e05fb5f\n\nInput: a51c1a148b54d086361da6fb68964475428273153ac145532a23bf5889efd3e9a419b5384205ac381f9983fe6ecbf414cf302281f97e82e3e0a51171eb0df1d1b243bdc8b335368437\nSHA3-256: 9fa4cf24baac213facb18094c57732f9dd9ceff2b18b5056c2700d695b148a22\nSHA3-512: 88cd3efd6026f8045315cb9c56306b148d7f398608da04e5c830e34bcc86996cd21c76c7f3bd5d4d02ef14a866c0155002f53b7811d85b527373c9820b8ab117\nSHAKE-128: 6c9941a24023dca0a0cb3c19b5e7dc0d129b1d0cdfc1d90a0e11784de12d91ea9a61efbf52a744a4ed087b8c25282367df62ca275d8f17d3e19a2bf84773fbef44ed01009c34976d4ab01d410eef9e806c5d61da0339d9cd8e2f35ae70b3a661570e7ded79542d27a307e98388191557d367d9b8065c6a258d2bce924f5fcfc1702ba06fac26ba0e1a0165682d5257e8626660994048fad8f27ebdddb63a4be79b5bfc66f2bd30ac1bd99017eafcbed18a440600077284664a786ca23b59f5f5d4a6beabca3116159aa20cbd96e456665f11ed70a04572f3de560c29372156f84c68ba2b23be71b05446953990267d341fb0e2eb72e4992b9f1bdc6a841ecc8bb6c7bef8ed76379957b9c78d63d18dbbcad1d6a5ab1648a372b4507fcec95f799015996833092f42c836ab21714d138611f9cea5fb70f41f893df9f56e73cc19dce1f159f78d6d760705af3187facd745c2c4e39413ad8cb6487f7499bcf8090b0acaf7d30d29105221cfb6ae10ce12449b69227aa589ba07a44c06820170000d29d5013e89fba2468c3ea610e3f67acd9dcedd09f843db48da6480314cc22eedbbf832fb21d8018a6285be823f80f1f7979da31b75b6619284b477f45e3db8c54a6ded5effd439967dac15bcf03d0e0389332bc5758a231e0f5298f27e77827d02c43728d4dfd442624d6a17d70758fd786b9fe0b0f0fa8d525a1e772fb2ecc\nSHAKE-256: 28ae05e3e7681924268357d3af54f589e08ed584335fbe3b97cc05386fa3b5ccce5a7e1746718859527a09b1559147cd03eeb8930ab3f0f0b45b8c4b0fae8d8afd6c99ab3d3b544287cf1621410bd9a476969d234e8f98d26d7f6d72f42806b4224c814cdbfed4f7a3d8ec14e7b8ad3f59128611cfac1313765955d4e34804ed8c4387e6f0f906a6b7ff08ca957256400211b0a726d756e1162d40dfded3e0c7f2469f6984761acc659bd86d70753d3f6a1408162627ef7893e2343ff3385171eb5d7fe7214933c6d5b8bdbb389e70fc967f0b073cc7fd06b8dcbc71233af8956f43bf151977fd54d429c88f4f8ffabf029ecbe3b38dea6ba71ebc67a878f87319ba7eb150d97d0ad8398e2fab16bf02d98d388acfa7c799f82853098cd15d28a4621a52223a43507731afb61c0c7a4e4503cbca52f318b47abcfbf37f03d5c36278763f27b0ff801f2f54fe8fd3398854d8b433103e46f0df48963a6c60986877519fc88ca69565ef5ec165ea0576552e195df93808279dca9516c380e796bbe22424a14495cb7a8a67debc34a30da5ab938efff5788652107716cbd8bdf6298c1de9215f952a8b332bc3e6dee98e9cf059910f2247f90842e398610385f69646da32d9c7a93da2fc68c5bdfa548a5cd00705766c0574bd6ecd5562b78f1b25c854df2bea2e268cdd354f5ab9da3cc349536c75325e4a68d243fe819f5fc60f\n\nInput: 40e3a3b001f88ff676059da5e248fea60b3d44e6153fbf1a84755a60f31ef477a8254844143000c3a9d4df9da73827e970f47c96a3c0827432b41a60e0f3def0bc1f4f0d94c186d76067\nSHA3-256: dfb9995afb4341366d90d388c3c2deb4bc9f4278fd1764a5360d081dcd7ad0ef\nSHA3-512: 839e0cdc3e1c625d5358d75bbcf39d25791f720f98e4c87b0036daa719b607d9389e02ab028f88cffe2462b67103cee4cf71566193a5b465366642dce2445fd5\nSHAKE-128: 4b4b8eae8635c4751423b10ba08ce2a8de4fd6b35db0876fd5bc4f9d352c4f6a4abc3c2cb1dced3414279597eaf18043cc39e1198aa6ee5c7ead4a97b26d74c3cd54efacaf7491ca74200e68357849daad4b691fb4808c570f7c04caaca774ca70860fbedb2317f97d6f4fb6162d12834172d0152ec41a07b5517ed2034ac96014a45e184a52c065d6b9599d7b5d4e6fc011b53932c4288afc4ca65206066a362d1d52ac3edb0fab549d5a49f895943a9838dbd5eb36aefe4018a4ebc3b0c80d6b2687f4750508acf8b7fae95d8ea941d2deab112573e23c40f3f6e95f160eae039893feba65a05ba19c1983267ea31836394f5326184d251fe6154558a40c107759c7d06c04abda3b2ffb1b41f79f28041060280f51674abf4978552a05cef5ff6c07412b76dcaf1ef249d86d50cecb98f6064cf3911a26b5a645d1798eda7176d638d4802a4c6809149017bbc46eea3cd0d0d2a789d2bf926b494a757ddb39dc253e218df087243cc8714825ae6351f1fc3e1ccbcc7489204fbd315cfc3269d0ccbda071189c976800946ad7155ea35c1eaa858cfd72eef4a60ca47969f6b4b9ce0834bbd901c4fdb4b648f5ca3fdbe27ddab6c558a1d8405ea86dad5863ed8ef119330ebb1f87134b26cb44602ad1a1e552307905a5f21306bcf4cd28d0fd66385c4402df2ce0218b235de0f5ee1052217c586db22fdcf07037de90ad9713\nSHAKE-256: a1d0c6491012388b17e84f28dbd66be5408e495b82aebaaad263e011e962b8b9b9fe51099cae73bddb4e8f18a8ceb6c1442ff1426119ade79927ad794ea84d353695cc054d9ecbfc52a3fccf1944d8dc0893ebb4453a393a5625c8ef4cfbb407d46826b45eec94a6ffa5f8b77b3ba4d91e1422eec0dae50ae5e0f3d9205f69bc193bbf84d03f7f816a5c170e24273c242210db18933b47ccacf9189b016a81ef51ffc027744b8705b4f8257954cb1bb0241662e0176fe718611b3c5ac17f928f32c3956f0b8184b082c58ee94f3c5ab8578a979850f55a7450c5649b1e3f34c589d0b2805fe6d33a35e241590576574f5ce19135e4291a50b7329acc9f21692f33e2573b2ba60624abf8d7eb38fe5a19740c9569cca7a413290139f386669a59d77a4817a9f5a304ca6b395f2b11ceea0f814ad80d70d4c18ab87a43cee0ed2585779a62c13ec9df27efd4233d7c4bdd10fed212311053d8d27d7170bc1d1d6dd4e82931035248ec35a37e6aebc65f8f388a7143292144976ad4080bd5652b0170b33a9ad836d751f1c09d98eb488202af325baeb56631aa21159ea7af06695eafada435da14abc49d76ea48d41fce7708632724034c56b95658ac30603d1629950a65c8936f7dce93430664b6df3a5e93091d59d539fbb94effa79419ae89b200c3eb8898969bfbbfd2e1fb7f458fe08d0640bc0ef62ff882128e1cf89781bb\n\nInput: b7a5e0f41e801da38c9ae31a4868fc016983eb518da2264aade0884152637fef2991fe59447995929e068fc3c3d210f80ea7a83c370ed67facc2093f5c52ebabfc474f0bf9afe13873cb34\nSHA3-256: 0769c5b23c0c6719c2f11b1a4bb60f047cb418c6a0516f3a0398f1e853d9c596\nSHA3-512: d81d3eee1fc52cb4146658f48c03761cd7442bc8dee3500ad86531b9f482f900cc1d549a1319451b5dd4b2149c8696891951979e9ba8e4876ac27e9023067d0d\nSHAKE-128: b055c86d79c6a5021f07442708a12277e1bcbfbd0630f04d65083bd0efdd90369a707e1588976ccda1779ceaaa72895161603630b4022947d0cf2edceecfb3c4bf293326836952a15cab46d745b1ea929687255b64172997cde05684d59c16c2d259658bdfa08ea149949b49b17dcc2a5a33592715336de67544f90e43b1522fda5f72f1c196616de6c07fd11cfe74842b23acd48f0e1aaf895a0caa26f52fefc0f8eb03c7da6895b1f78e7b6e312352ded22c38577244b865382bc38a39ad3f0e351f9f9c051b3d90b08936e0cbd6137150729928039855d17040ec25eeb0d14a93aebd7b4819cd67de76315a24b3fd3869e353747ef5c6f3d447a11028f7a28130e1285616ac46ae2c028dcf17914eb38a973566dff6ac57f64857eadbe19207fccb6f70334ae10f1329cc40f9560299ae79dd84e872735cda3ca99f1c68d86348ca1f5338d3d8c06ad1f642474ac4222c92d2e610d4960ceb69094c2700b87ce769a346bff372785522a3a6176cc435914c64b8888aac2654c196f72a449fa10d209488ce221f3f44c5f8a7bafe34d4d8fb346aed65973d4e29331e6bedf58f10e304fe8cebd371f24a28ef047a3e37e43e35db501c6821107d4e7e1b135681bcf7a615ecd565703346039888ad06dfe73b2756dd7c5b7926f47acc298ac48c40153078364e2ce45149d7eca68d8c452d3e077bf53825eb89acee5dca5da9\nSHAKE-256: 1b9907b03f4b2f536c7077928226d7d8965e2757c5853f7fa7204ba30359b6def28fb02645f79125bec9b96022b58ca837fce4f899ed40588e39b51722d1e429288d2f852f99f3ff137ef34300f2a2c84d986cf26d4c24aded54b8e0fdcffc25f41a1e8de54299c82992993a1643c884471a95a5349fdfd61fd8cf5c5c82378a2a373956696467275aba9b827c0d83dcd7a4dfdc3f0e83c8389a2f4fbe9df0e1e349f8e49a0c424155f13acb10a562163faf30fff1583ca60d84d890cd00fd8c3e7fffbde667233aef9308bd86a782f645448f796faba481aeb5331985a03dcae82110c4ebf1a626119f3253a8b11793a32a063db700255773724de596d473e67195c8f590b37978a8f8d0af4ca0d02a5da9da5a09f96c88d4d57413ac495916619d0fadbf43840f45a5c2d3d08b23dda32166dea5ea3e1865268b2bd82efd5fda7c576cff26f222074f8e5c44cb82896155e5d0ed5a82b81086a20c0d867c635b3078e7541832000daf2012b0d6125732bce889cd53727aee17b7a1c2182c87131a8b908148af135ae51ce88c080442bcfdc22706e819f54c6a678aba2ff3e1593dc74e6e2163c67e7c873ad9b7a0be9797024a2decff9befcd81378ae8cdbab21f9af7d6f874e4496496996d7211842f2b09f3321be094d0a29efecaf1f04d3450ff1c95d11ef9228fabe6859fe5cab246206725b7241330eb74e209764689\n\nInput: bb9185d5f94c1dd0b2fe1c98d24d76a35d09212d01ebd46eda42abf0ce64c0cebf51df6cae7af6665b13e90dc3cefe9c64", + "d55f5cc37e843fddcf45437e073ab68f296fea018a8b0b289c0b99\nSHA3-256: 55d1a9882bdb8e98a7b12817ab9030d78223853cad39ced49afa2f296634b4e5\nSHA3-512: ef7d22900473c916b7aa062a264cf1b6928cf2a7eed5b4c88ab41abcee554b547fbe726e2e3f8b22fdbfe51329873746c5f4625e9492305d93ea1e9cacf7e004\nSHAKE-128: 0d092affaaa0dd89308eecc3f6f511a9d742ba16b68f80afcd7eb33e5308ae1647c476ad0fd54cc731308482f4bd76e85f55a9ce3fd0d6437b6833c1010c786db2d653c16af814b5538ea64a8212d83ee80b088dc620c4e2601342ab17710d268e722ef0dce5b2e8ca73584e4008c7de27ab56d76a44193746838136bc6a62e6980decdb2c945c5811993e5875b92a3f8d38b1d76cc3f9cc0b832f31072d56a11aaf44c575121256d9a3696858068c855c19fbd0ade893e1b5298200e47681bb99f1cbedd4a1c73f954b4ef7d4d28786a5697590de0bfb615dae3892c0024349cd809778aaf001e2ce90f390f84a0b810dececad6a9b90492d55eead14f14a99a761c44b8919a79729d0a2ff0bfbd45fbf9091c784f07718a9e99c05bfb0eac934a3c7aa7f2c0c6fd4299189f37a03a99e3d0b2328d5f4cb89273374090d79fb8e98db0130a1528d1a0df937b5cd3ac8e35fd14d42290a275e6002a7b1a50b9c4e84eaaf31f94fe53ca91a9970e6f1abe081a298e3fa89bd664a690cf04393203f9c0a9cf194abff3a9399cf961c7e6ddd2f65cf83a6bad28ce8ed47dbdb80ba7ab8193ae323c9525d8658ea96a7756d9fe22575a01ae9b7221e01ad4612e748a7e2d716b57cc35d1d32ef55aeed18220333b6473bbc80ac5ea111e451a8143a83394d10fc6dae120455a314cb6961abb0e4a58d7e78eca8e37873adb97df02b\nSHAKE-256: 60882c8d1b5e250193fc3f071fffd088bd73a908a797796327153ce07050382a6e29482ef6e3d1b478db796684a8ebe0d58f1573714ee2b8609be34838af568f175b2c9ae594e3b91513152eefad8badae58751f213cffcb6123287b70f7425193bad479a4a10166088a72af00624ddfd05b61a055e0791230550c8bc2181f5ebd6f68f757bab2b83c9be4708e3801e3a5d95aff0a90ee26c320796899a5e355fd73be10ec23c0539f16cdfeddd06c39ea53071509216de31a275f19879a7901ca82409eb607612d3b0a93ac348fec12c5e2faada0c1d59367a3d6e71785d0fb95f7ec514a890192fc56faf02765e676b8161b5bab583077d227452e52fa040503654a73f6bc956893e4258223e94b75ff3a64be5107b4da9ca27f5988af4f710d6acad9c2074e6f6ac5a2903aa8edb61ed89a995ecef81cdc825ed96ba5d3946e8e7502394f527671bd1f383fb5f87d2c386e2d059c9507c373e2e6942b13190ad094ae03af7e778769a84f7c387dbe76a81fdd5ee2625f68925af171602680cc6c022da167d9dbebfab079bfd215dbe6b3e753d00fe4fcb2e33ee42cc767cf60167019bdd3d0df5cddf2654875c6ed4864dfbfc0dd95c71b3f4e81f948a38be42c0327990fc74f6bb346f60a8f739b924522230df2bf700670f5001ec7d7bcf91023609e6fe3330aa81327c212f3748160581c937fa2d8d12947a28ae933a1\n\nInput: 660fe039891d87e954d0102b01dc8c6bcb460e4bc177542f82cbd244b8b5e5d5ff25e1c6abf906884bba5b6807a9c8eda79d25e73994b61e9b7e85af43277376bfc3439ae53846a9c463c6393f\nSHA3-256: ebbb154b6b6aebfb4dae2de18c85d320a97fd0b2cd72514e10704b9b614fc5e0\nSHA3-512: 2f4f8876da1437ffc80eb6718894b63f37746a50ba7faa4a24a56b8db1da6ae411901db1d2290703d0e88d1939306907ab22808aeda2ce313eaa4f9cb5de4665\nSHAKE-128: a1ac04a6dc71f1d2548288083437dbcda8b29168dd44f3af8f26af96f4ed5e7cf991909230ddd86641696fe72a92b8977d3fdbe9c447322e710bf6586a340d53d9bef84c27011a7576bf3a3b5d9f3faf3ff3b9d544775fe9dc0aef9b4d7f869e158ad8344c906ac4f6c5edec319e49c62eb5c1943d8ac05aa2c0c7ab707f3381142ed0b9bf1098be6b9d161c0ff760524aee825bd78a7cf7660974759850266c2d722b1add2ce63fdef210636c5c64cf55a90885c25a7e001274e47f98c3cedff0fbfe4f83561ec2bbb59f4c901673fd1c346def1b211737c12000fdeba0264007b37f0f205d72dbe52402d313bb127ff1d4c7963e9af5a47d65f184ea5f3cb7112eb3860cc75b00ff66f05282bcaea0e3c3596be090187c3ff40cb46e163132abf572a946bca781473743648ec5a0ad140d45f6313f1584bb52d8ea74c55c2611d0cfb9b89a8539b5d6d6114a6e14515ec6bd4dcae81847bcf99478dcb25ac9bcf5efc19d0e60827b1d311d7688bc35f3ae610b4aab6c604fecf7a93758e3b0c5bd8a97ee1a642c0964fa0d080cda8bda7a8981729508c51b44123714b4a2dff6fba94f5d6f9780757d93e68768a2ba579fba7e4e6f2b5604065891110e1705b0d96570c59cf2103ffad0623ef66307bde012d34f1b6452bf125566d73189202120bef73363e8cee0e826c2c8958372da550992cb6e382154dc1dcf54250766\nSHAKE-256: 6e05b2b1179ee333f38837ed76f7e16262eb5090a7f430fb119fa1170f740aa7eb7a112b9b4abd6ef1694a8887523e3504ff6ef056de45221f1d0aa88ebdd79e5e95bb7731297d778f8f6d470d2fb57a9400cdce1298db26dfb730f6c711d49378a0cb5b578dc3568b3ae89c40c0f357e1fb4a1c77098015ac876468e09af22c40262b38eb1fb380978bed6428a680c2581ee0a647c12b886fa66d38a1b951edab374ef74aa9a1ef4d9c02e52510b1f1fe83d5218b819983d7d8a02617db0d479569d9f3206f26efe5d78ec1f5f001f558e4794d725add528d2bc7d51bb4e0af2d159d050636864bb95478662092a55695cb4cbc47c1a2e64de9c4fadf02f38d75318f94f26d09fc87f92a0bf7aeba1c3854369e5da67435e6e3dfcd7dd9297e6fed038f32bcc108cf909bcbcdfdd5423511e903176640f2934d11428147c5b5cdf3b0fc432e238bdbb48c63612182cfffa84026137c51fc7b29b85dcd82a01c989221760066baed91b7ce70f7ab0cb96d2a8f170c2262e02e4cd5d7ec21bc3fd3c1517e8515895bf3442157ad3d123cbd01ccd0d65584600d97451601e33e8be3272f97e6cab7c21c19be48adc7d8ce840980a62014f6e1dd494958edd463bdb8e1f2a785d241e843d715998611c6bbbe8843f7d29ad21dceafc7993aae7ef9a279efe673bae8224f07a9b70c28e261dbefadca21408b83ade66f579b995f06\n\nInput: 9e7e411cd73dcd42fce39dbdd34aba115fa067de5431318bfbd4005305c9fb8d8930f30f741af6d7fead326a8184e73aab8dd173c800006bfce3916fc1c04e186c7a0302842b1d5ff949b6a336b7\nSHA3-256: a27026fa9c3347a8be47e225664d17d4b20f811f0dc23c74685210f544a7d832\nSHA3-512: 328db541058bb39941ce7d13287733005d0181572cef3e8767e230421578c71e23a125fc5a17880b52a23f861436d9f3d735b9fd6bef3f244d3e86bffe0f6fd5\nSHAKE-128: 8a7cf91d22a70f75f24cc3fbf084d4ecae4d835a5ce4e5bbcd46a5e326a21c1fd680eb182018193ca05b846adb0323701701f6915cfd9e697f2cec74533a43a2ea65a3b03faee89cf243b224845bd71c0d5f4cf76aa143c2433832fa23c3b883bf7fb7615311af787b039d5fee4af2effa398e1d47531adff800ca9472ba1b13e10e370f4f058131016f35e86b932110bc8abad9ef63e8eed0c9c7ea0fb68540de4967d8146bb15e8052ef223efcdf29747aeed41e91186d255bbffbcb5f99ddbdd09a4f0bb95e93174a0200806af2eb6bebdb57a0d08ae8960cba6c5fbd5dc9eb2c70d2e9a75ec3a9a00c35e0047ee0f41108f4ddd9f244c142146371d7572cf0ec81504f4874ec83c579d4a92cd67580695149c1b8057ef402d2be1beb30f56f9e1dc037bb37b91b4c1da49644a0853fd8bf1d2667109a02e2215bdfe54f359d30f893331db75536d568d142295da94495c95ddf9f1e30f9ec3612c8cb3ecf8e2a767d18465579c483ce156a4cc590746b81265ac9ba9dff95873928d2e9c361b6ec2ed6d8822f07848f61630164acccaa619270587237f0f8c7c7bbcc35a880e6efc3ce02efb5c0da8c2db65a18d68fea45d596e80168c7c7d7b6ef118c44e1b529aa770b479b24dc6785f7ef4de6045b6c71e2de672eed757de9995fcfbf0b61d25f06ad175cdbdd5be7330c97944f3d53dac94a4e3e720217cecf5b5d70\nSHAKE-256: 9304947e788a2d843ac096642186816f99695d82c74a956999ea8df1671c556081b0b3898d06b05086d2319f24d6e69f08169c32cc11b6f6a67e7948e5e1eb153f853da58f9a2aa38a68f411b23c1926b283aad55557d56e7de8e532b717f26b916f9cc8c2f22a337ce35b934fa3e3e753e8d12432725cb21f178aae33ab3bf862502f255323f2116c840ebb361d2b2b15e92b04674486c4097759b43d1de3e63a07cfeec0e3aff2c7345e69fa3fc100f6d0265b4f300f423eb71a4005b262fa2ef8533baf1730fb5c399de4d5f7ad117a357ea5ea8277b12be00dcbe7bbf7be51e1c1c2b4f54f01b9b30e34df1b27c56d626fd8101d2c2a799a02a80ecf5fc6ea4cb1d8660a73a7dfa362297d15d6434786603ca31cccd98b009916294fd3b87474d8d86d391162f09da6551c9af26e0e2e9c72790c8c7bf63ad3f6df253a981ca5bb113a266701a962bfcb02fa1986b275cd98baf933e42ba3cc6907aeb54b889a4396eb401a8a0e68dab068cf42f78f2c6ee6a55609fb8abed4bb41e3fa55a6bf50254f007a7bc87f5be2117c803e2636cf827827c7d219c4b1d48376dcb8bb5ada0c282a862b238ca2f9417b3786dac6700c31356c9712f2164b16602754f36b868d051b2ae9bed67e673223f5a1374a00018eb1f10de8f4e0134e5ff976129ecf378640fc57ae859c81a655e768036dd1eee0d73d2cd24f52d01c798c97\n\nInput: c767258594d2fe24eb62b948ab2672f89923964f17f6ce7afef074b52dd3de9ddb050be2a7db2ce893326670ee4ba2f060d83614c60efa7dd805809e550f9e8c1c709ef4e6209e6b43794940393a8b\nSHA3-256: 1d9ace700005aa14098dad7d25509399b743b97a28f61455ab0dba8e7bc50fe7\nSHA3-512: eb6f0a9b9692b53314a35d231a91b007fdf7e8dd826f07b814a372bae59bb57112c6c44280b0a44080a401dc2fda30c65f071a69a182ab33568fd9984460d784\nSHAKE-128: 148affbd9ef3b83410a5213b4d00808e85c471df7380822965807e33aa9defcb825fb70e5d8d0267a787c2b1234332a6eca6e3436fdf325d620f51c909063a3be0cfe92612e5369b1c6f2a19b721c0104a34bfbb7a995aebb224b2ab20b98d18a85ec58116735c398077e1e38942f3e2af9604a2c47f95ad029ee15a9ef7aff9a86974a2cc468302c204c4da1f89a3c041176d4f8a70899962c0a8f9d416ee0d54cde901b147d0a8fd8aa3443683b4b4f624abb8907d31af361d00050a34200cb624fc91f64ef8899704f6ae4124516dd7c325c6398389f5875398d51532410bdcb2df046dafae1e8effc15eccd5ac3519bb930b56ff03c544bf60a79c086207e6959446f9ad4349bebe3794e0ccd77d88a8e1f24acf9e0", + "f730c154ee42e7a582aaaea296427c5c1e5d932bb9f79a182959f780e92024c9d575e22b1efd225343188e713243698f4f118d76614e9a7a7b17276ada9b311949d78609444b3a331a16c110c984ff31e829896fb5b66f0a0e852af918e111a331f49e3db790f51318b05e05549bd697747b3d988c92f76abbae74ef3b3bdbed986b2bd7b772195281a5f48436d3032498d42dd4389afa4fb1e0252501289e53a6bcc63e05336b35911c9b7abcb8e0dedee6188891aa3b91a028c7ce2f98fc41aa50e26b4d85b82621861565c1c6000bc6836eeaa3542aef9dccf10a72039c355f3d89f8bb96895ca\nSHAKE-256: 5fca527861751709c18f1b2b9966d71ee3ab417231e15e2d1a78ccc52935dd2d71d0927c957f69f7e08fbffff64a34a10defb149dfbe0c7a4a15d334cf19e2f7815e57b64964ac591ee04254de19e8ab59bea5ad0c950c18ab5a8f81efede783546a16d11debbecbbff09ec67019114155d783c925624e9725c4da44998b5d0dc8f9d1983cb72eb5c411f072043eebeafe8221fbbe14d74e1ac09c3905eec055767853fa663b091895bbd57ba2caead2a63eb0c4ebbcc5c343091ffa9b5a5f97dae7fc9ea34bed83a79d6096b7d9a883cc8b189eed475fb4a35757ffef085ee3cc334d987f4cc43a196e9f83a29c1fe6d88341ae2b98f6a730cfe0b7772bf23d0f6f8077756649964fc20d4f6be402c73296147489a4598dbf25cec4bb6d3cc46bd28669cf5b9fbf2530ece0fa9e9efe320ed107e89b99263e03857725f2ca461e3a9ea64bf50b716dfca9834022e85d74f1906edcdfe8497abe0b07b3bfd46b5b4050972b0dbd1e551969741e12966881e9177de152d652d7ade352879a726f478866ac2cf0a865e0b6938fb6e8177641213590c94403d3c5f1b590cd1dce65fd901a3bc4951ec0c98b5be97c552862d5202992a3e0c7ebf2b05036fecb88fcd3a5c542f728662eff7d96eaa9844c68f8a4f371bb2340585b63e3cbf52db5c4016e1bc1ec310b9b162ec8b004e9ebc613d4ce6435eefcf0b51e63cf8cea931d\n\nInput: 841c10102731b914ab98389beec42974e833af78537499334b1519bab5173e5e057de09ded0281229235d1d6f81794085444b3840be748bba793f4165ed0d918d2fe138b495a44bfd2ac071565cf8be7\nSHA3-256: a2a1cd48e5df62dd2a4a771cdef9d6081a4577ade325ceba377503eedde874e4\nSHA3-512: b7dae82620f7fbef24bae22d8a9231bc0213597930576d72bcaa65e9f060e3f8f90bfa736d3848acf579d1005de206d826abea5d7e1df3f7110ea5d9c111d48c\nSHAKE-128: e7857cba05c7149d29f7f1e4e541f40cda7e0698d05bde45b2407e6c3398c753f507be861bbbbb89b64d4742b057bf5128132ce91da2d4b3477f1cfe8fc1421537340a2408bf348eda5ca3171ff145e1949a97006341ce8df8b2dcf4370077f712c867f0767aa2f778a28dbf47b24305887d07e81fd97582c59c6779526068d955b36ad6726b594e3c2d51602de57606c8725f04b43df09eb8baf2e98e508b4ea49b4d6e03f75882e1769d70026c28d06ed9bd5687c9627856b9e76fc29ed19c4cb5c78701e419379cb08294b343a3b8dd8a4a0a1957ff246471bc5715c79b497f6ee466b775c8f49cf9a46b41445434c633b877583539d3d24b044284fabfc00a3a6c234b6f262616c7578a5ea050a4ebc88d122525b1fd3124b975505bef417dd6fa2f55f72d47995e767b3f5d8aa4ebfb686d1a464968583a648a0ea2d6d60a446bd2e1046146ecb4e499d12939dbdc427c5dadc205673daaa6940f00b7fc481b3c883048b39565d8418fdab70118d112bb678f27bd265cc3941d544dbcd699ed4ec16342ef998b9b15fc54e6a66f405ddd54bd4b110448de6e2ba9b2246508c33e5847b5d2c0b90f3041fd073a448b40719840a0d5c9aeeb89d12929a4e6144f79715cbe741d1499f7f1bfa3987c92894be2e3a734187d13b1ebc35ec3cbd5b3f7a1b9da70d086a7de7c76abc73057b5468f378ae5ba83929c4b976bb9be\nSHAKE-256: 96cda06cbefdc46f0ed5872d0a81322bcbd5ff2873468b9946b761bdcd31cbc4d20fab18d0e3052564075a24bb667acade85ea247766c4e8fc53f4b605aba9dcad2484a2d1c46837f82223d6e9253f9fc61dad368a3bbbb646c32bdd3f645d10868627a96147bb2fb7689ce2f1592e273d8ce8ef4cab9dd00647e7e811c4aaae9c524d980e9125218aa308c95e33de1924dba5e0a36c9fc7e2709be4dfbce341128cb9b4e6e3ef09329431e036e83287f050e07f92f0ff412aa69a5c1a073371a09ccce60e197e6df4e7157bac2ea07480a8fa82d9ed5d4b63d3465d9d0cb2e23c5b819152b5b366bebe2cf60948c2a76a17291691210cddec170777975e7b1606f024477e3c2be32b8a2d6cc5f6643fa447b436b7127d2689d8b63d8b7e21d17b3a4d105f25855fb6259f59848ded2c919971de25cb73761e3f865ed98e8215fdd887b2e756257f5fb0f4f964ef9774cb33b87a936b65c577a0bf453d95556a1029ae377d89a15573cc48aa3542998748bb5c1a8f9f32e57f6e3b13c6d88c602639a7818950e5bd208fbb1779bebd244438bd6f4965e29cdd2bad68f478606d4efb97325f949c704072fbd30cbfb46e022e5bd0e01dc5a4ca007c7c547cf529c9d3c6195de9e2d460f196adaeaa36615a2ecaf45bdda8c059ca77c9c4672f86934bfb87a8fb0dfce00e1bb2a02e892c359d2c6c0c17af7eaae309d5cb3be015\n\nInput: d9becf1e7b37309ad81695eeb36db252a5d5e211cb7f0da414f83ca0b5b0ea36c73b3242f3314b6f93bc39da33d2a9a0db6499d7fad81f9106180b19b83cc734d7196c99ec54ccf254c9c6959197e2c5ff\nSHA3-256: 9f13d522a37cdb1ab4ec69248632becb63f0c62658655d689d572524693d0f84\nSHA3-512: f2549804e34e2fb3c4874a8c92ea9acaf6d4088243978edb450e667359f297e47fd71538a0e6c1bac69316219382eb2da06917d506d86cf06b564409201760e3\nSHAKE-128: b9c79585fe65477159bc4b55dcac2bc95b173b29d90b218c55d01c9c381c410fc221fcd872779b7d64395f68c0884a5da2af57dc48f3f5c02c9173c4fe3ca45c04bb26a3ed2cdf0570a66a4d9e98cc0a3281fb585558e4d8975fc17eb6147a4b4a54fcd8ad6fc067070aa77419fcbbab047e585262da1eff76e503fb98d153015d01c8b299429f08e21072892682c252f0034384d71fca0b4c30116cc72fbac0d825f5db112a97830cff6c8373458548ee38c269320728b759ebb1894a50d580f56f8a23bb45d6d8e5944c30d3aec5ae713ad01ec3b57cc6609da6525ae1900e6fa776fca52aa234da6712fabb87fdab903845738a5362133e464c2e6d78e1ce2c9b419ec301885173e11e08f922e0e937f6d2b8c86b5e5d09ea4c96aec8bc572a6a86cfc77d37e204b954e14716c26f6c492d1f09d208aa7e259c850e4548aa7147496a90a39baca85bea414167c05af60246927567e31d02f156c97b0b86bfa8b3832ac10acdeb0d2d119985a63ec53b436ba5943fed268b4ee4834ff0829275afbcabdc371d6da0e6e16f2a40213ff7d4851badb7bb38554ce2018c3943570059f6af19c699d353a6e7f3a5e32cf3934649eafa0690a964a5630b9d4cac38fcdc00f37b29802f1b8b2d1b3864d7cdd0cf85e635113b71bc558172fd66a7f5a01bbce42b12d33c5a38f6292e3e74a3bfc6bef2f777632600329fba507842f3\nSHAKE-256: 48db6978546e8b173007446a686e48977751ae724d4be05745ad608fb0e1e93e05a24370201e92369f03206c398633953f5ad865b9f7917f59cbad9ed40dad7ba3de3397fc1a55d3931fc4b45657727167dd9ea7d24a317427f0063d95caf29fed04f1ca2b2cce09fc348cf20bfdabe066d049de6320f8e6e7c545e87f9058cb197d71c45eafd0f249121d4049fd37d419c7469a2d591ee6890c429c2d51768b0663687b408df38c5b7c8bf653620fff8601a8025a65bb32516c7b3655e92faf3297633b25ee55168554585083537505db84ba8f815205cc804292dc3eb5c054fbb24dd7701c34c9a757e117304a2c8c3b54c7c37e0135996fd8e0582ea10ed61e0fd33573d86e24141a4b2bb7a7a1cb6ff4720b8a3eb1c1c5c4c2dec62bee460094165b86b5a46593401f9f2a97d9327215f113c7163d5e0f707cccf283b7b46ae83caf25baa2975054001275a858b0c43123cee11adc04eeda963e88cfd0c2a1bb9dab1d6b4041029358c49d3cc5357ff4ec582f47923ffb9fb13e41cacd63393b156ed1f8d413c60d4a357281dec33a1f0f9bfcce6c3051178e3e074888d466b0d0f5522b170143cd6e5d1daebba3f3c531856f58a18d14b5735acf52efeeb4a1b666987c72a25b0fb739e7b5ce3fa7b5cd0c7c853097bc811c81d23b356cf462953ebcc411dbef3aa44dfdd74006ef9d56bd6f3b87652e591e470f2fdd5c\n\nInput: 8266fcc5eb3f5f41f7cb430df3a65d62ef90319c7ae2332c5d6169cdaa3a68b1bda548af443309faa22bc23a25b382484d8d90586e5f44f47542ecf6279f678a16315d349c1ca6b8ef6564249f6f9dc0ff97\nSHA3-256: f5b571e20ac6c48d570d656fb8400a8cd56f24d882bb269afeec0bd5aff0c0f3\nSHA3-512: 5d99d2dfd4123381c029424cf49dd9b3327d9d5ec59d88bc3781b63992508e1daf58787adfe1a36595727b6094cb8771853521c8c8c824ac17a9d70dd72ef936\nSHAKE-128: 66a8840e0613700fac4324bf8d81b1a740cad667915ff93aece787ec6d6d1848daa5ee3eb4b34107dc49f65a273d921d202823844d79ccf62d43c5f0fa2bb3219cb67784826049c5e14d9ad9d0af09d34fe7d8c2519a587d6b92c3d108d8983ce7a3960a0a7b538eddde3bb335c9f2b3b885a4f87fefd635b9b24ecd9fba4a5961e943233ca21e3d8e2505016eb60db2c4f3598eea7829d33235449f63c6409f66a7f188838191b385ba3dff11566732aac53c60c66389438dca7c9f0b1f2f25ac1158afb18a8e351be6349ef14c78499e2ebf58c319a97a696a8c9129d79e94db6c28e1513f58a375888ef8aae3e49983c1c5552f578c8331cbfc7dec8b69721fc51b37466ab5365627341495014d08f5b8e14d43c22c90238daf77d516ad11bfd1479f0308dd7187637bc0487ad64b6df9dd10a6618654da3e0d34b90101933a23235bdd112105d52e6d125b44d4d4849569c075716ce6241d00977539d7998cd8f892443657ab9a86056cb161ed941c934d8c17f46fac5301240f61c3510d544f43a011f5765fec94ec09860e529b27f0c5c1e8e5ae7dfd504f8ebbb08b5cf741f60deac0feb16507e178131ba877665ee9d6928fb337b299b87c3bebd213854001ac0592f390a140b05af44a50f136c7a8f222ce76f3faf673476cbae1652ac67c3ddb8ef81418a99a9f72e05790191c9c7d1f550e0a1d3d00fde4159299\nSHAKE-256: 058ec7248d8a973e190c505b558abf8744ceee120fe2c59263cd5da85d1b27a99649e379dd2f4b8d860b260bdd90b4bc3b58c63bc438cf6493138e97aa6a97a720a1d218ed666616588641932e8c0aa0eb6e5b1f581718e1a401693c00972258e9a9c49ce8106292f55044ed0793b3afe05dfa99ecf64af94cc38f8c4262d866bd285d8db805d3fd38b46b80fc66bd9c36233f87cfbcf7080ef9296ace7174b0f6564d13ca55d1f868eb6c50", + "87a648cb2111001ac2c280f2b87de3d33a2643018856bc4ce7123cd7e569ffcccf1805a724d672ed71b13ee164d182d75832ccdddd65aaca57fff3adac4c218637cc6f7815e9810d6cac266deb28db3e151cd4844d749061481479bfd3034d23f6ac90ccdcc3ea88b6ddebd18b8213f43c08ddc95f410e8dcbaa6eddd9fc7420b30e157fbb136aa92f041311ef327ced8ae0c8568d0bc2817c19fb3ee6462cd95e4455839eb2f88205231d23cd098b4cd4db4580baf53e5c5bb4eb91548ea6557c8e48c2596c4746b220690d2e3fde6ce6868c869f30541df21b3d6ffd73c10db9650ecb1ebe2ce217fda22ec763e9a095aa7c93494e6fc239224c55752191c010061b55a80a4c6a4a61dfbf6f977bbac67bca554b7e010ee4326bbb5cdd103c6ae2d0c7c6a8d8fa9d933d22cefc372cac74fdcebc57c8371c7a604fa9978ba14c668b8dd74f6299404ccb227ae3a52b6f47277f\n\nInput: 298323ab396aa86e3a4c10d06a1f47eceb77bffc8d03e51082f1343d3c0c21aa870703b909cdb2f446edfba44b8967816585fdf3a512d62e56f258cabb4fc50b326c116ee0ec1746d6ec4be229ecbdb7fe9678\nSHA3-256: 1ce273944d7da9455aee7fed04bd0652c20c9b9cfe92f93e661dbfb3f44623f4\nSHA3-512: 98f11eef7d02242442ece3908fef59b9625668f21fd582e31faf18a10455bab6e8f69fcf36473bf5c7da777fd537e8c80d10e4986672153320d44743600994e4\nSHAKE-128: 4f603c1a60160d3bd1f495e2912b29ccef1a0d6cb0b8ac5e744e4eed433f309bff039c70bbba98c5c45db47315e3e696adb4958f975e85d18b4ed8cee52b0ef24a6e2c692dddd075f9c8f42ab145e6525750b231143d32f10196993520914eeb0df635f3ad460877570a2e81e3f90b9d2f35cbb93512b54151171e4d3f6854706c76d9fcd0c4c074d8aebe66c045f3b303f4cd50a135bcd4eb96ec56b0f8a3a55f36e8a3fab2a0879aa198993ff2cb2dbc5b894a96cc624b7514646d078fa1376f4dabd78804f4b1e2c7c700b1359fd62d7ff1dee7f46b153abe58f4ff900f007a37f2c01ac570d08cc545053afa4ea7b632b0602c00d269998a019e8f9b4f7a65ad40e45f6bc4c3920fee8d87e4c750cb0d19152da0aa490a4cf41c4890aaa7ec1c3017fd3ee83f34cbd6d69257681a4615defdca57ce6d73e00c442ca88caeeb4e6170fb5b6aa2ea893f4d0803649840889a4414f1843de1c10e568239863bd1563257abba5d1b540821492321dbfe70d650ba4c4e606a4aa5957f731d2eef6fa5799897e54e9e9bb58501a50a5471ffaa377c9dcf4c35dba59f823cceac9016f8d2755b6cf7a43ae3958e50fb8d1674699c448df6efa775e6a1da49da1754f522b1d902c19c9b2e949a385006e38c71f5518bcb02675b32301d48117e72eb97ce8e59cd1584dc0cef3722a034814bd39a82770ddb14dc1123fffb21e5b7f2\nSHAKE-256: a1e7c4205de1636422129e772632198bc56d96a9bc66658ac4563c4445edd17c7e0acf50f6997baf1bdb84eb7b0ca2770883ebe4fcea2085a5bf2f15d7b226d72c3e7a4a8bb128ee4401ff2aa909e450ecc350f7133cebbbb7cb5d44e6388dd749424f02d49e707c5b2326abff0cbf3e72b3a196dda6f513a8eb89d13c1066308eb5918ea22d2da5e87e480ed9a9fcf91f6c9e1774a1df9c5a8d107ffdd3bc6098926b4c868fff13d3baea829734f15440d465473f62e64057e707491d0230872503c383e744919853868d2a3153e27c8ba3ef09f871ba048b7bc45ceb3eb7212bc72a33f2abc5deb8a3961c1552fa6f589158475dbf45eb9b871d6250d1d826e8b074cf41fa6cfeb963ef6c08d1322a06e79ec7fcf3d59323c234a9bb6c2761cef5f2505e830fd249f0a6698eeb897076306f4a6af8655c912984603198d5e6387cf20200d29f5e0b0d763a7b4605490a1a4797e09cada29c533213171688d1dc87dfc5ce873337b71d6179e7568589a306a4123f472b285c92c8243e374075ef5f038152f96072fac7b5f90e034589b56b63955ab16c2ed45248e2590922493b48bcd1a984aa64d0d3600c1b7076e48a7a8acebc689dba2e2575fab54b3f5329d3e682d14f8761e58fc9f254c00c5570690ed4ff1b7047b51fcbf29fed053e968020bc579817abe01233056e56c0abcff27979044ee6096abc27247e43fbd3\n\nInput: 5984e119a2af00c1c1bbb47bec7d6d60fa95ee0db721afcaee0ff190719de9058c854733bee1e392afbc1c7fda4d22d6a2a3984551e90fb35f9a05fd9cd377bcd73b1eb0745a37926459c3407332ad1ab36e41bc\nSHA3-256: 08da9a98371d8480406619ef9870e20637c69ac234fa02548a00818c12225bb7\nSHA3-512: 345bb1115e9804292a0891e53c0d111aa2ba988792f6d010c49660e328fddd87bec535183cdbf41109309b8eded23806c818b9830a2b5eb6197af39d663ca707\nSHAKE-128: 9f9c80a7d10fdbc9ef7af847e0b876accff1880b2321db5e52a51bfb219c03f98db2999b8015746fd7a46c812240acb3a8eec7fcd5411f5849fffb89667def36904d9e23581f0851320841747945d17e55ff856e94fad2dc38baa777399d198d9aae9f1bddcc641af323a477f1ca7f0979a658951735672a99f9d1a0d501c652bf0a65c5286245558ebb84dd4cec4f6b329a7693e575a1ca43b2f19a1a9e6feb0678cc62f5080a65d89baa2cb08c93cdc89c2b8d16d069281c0912713268428f7df0f62c227aff943e301bf5056510e8caa7c556a6e1729dedf042faabd931507dbc5ed38dadd29a7a9f844e5dd3773caae1074e10eaeaede69ff4a1572f4945dc3ed2992707cf5e211cc3b02066fcb6f4dd241f29bf513d5d50a9b7470fb88d3cf917540d9037ce9fa7853a5129f33970780a1b4bfd4ddc547e99c5c1cb8209536d386a1099ed2f3378875bb8b788c66f3e3781ae452086d2b122f4fae5a760d16c1962b476bd7a2cc2dad0a47f83dbf2c4ca1f5b2cea60546bc6a336ea28838f0ca7bf3ef6a47d1dd516851a210eb1f5233044c75c38b5b36514226c219ca2061c1958d3f17659a3d591fac4f2cb6c1dd5b14e58340c19c43786fa750a8d0acdf322172030b3cd1862562881159489240e43fc40adcb57f8b1f775b63f392ce8308b2e5c25bf3f06824d6442d454f1454cea36df8e885f857971ab952effcd\nSHAKE-256: c137fb1b3de72f8198fd405c5dc8b5d0771517cbc43f019c872045f85acfca90f4b3f67757218a287f625864267604b9a678edea9ff8e66b71f9595ae92567c6c830c8c238b3ab759346f82ed9bf4241d67c39a465f2582ef8e0dc5fc531bdab6d83abcb2d70360343b1e3979fdab489c504f69ba6584fc18f26f9ae4967953e511b0990b907d0c2be60376fbd368732c0d056c6ca4e14946b6d6b08f2cc5e326f68a521b14b6c07b04124a2bce101b9ab21dc9c73a142197c1817991077e659dceb7781bb0a7d7c794fb95f8179e54537fde724f782dccd862a09eeba5d291e8138fbc6c74233968981e0afe8f88f563757a279a536c3f39aa06be75f7047494f6b4e49965b45f08c9217f868c9aced53d5d2989de55b42d625a3348fa1e2600058d88bbf6bf2fed20b52a9e4c5ce61c8774465f715ab70685292640a61be64294e142aca153ab0525e77afde384a107e4515252369bf6c9c893256c9cad2ba33a96eac126e6ca0ed58fc08ae80f88dee095bfc3914426938d203c739a7c7e99c40e85042332542c9825e520f41ae89b96d83c5be36094e915628fafc57fd2c2b5c63bc871f8e02957f5fb859a485727f15ca47826d0d71ae4a5965ed3c9fdf4c0f987091327a35c868966a1d9a37c1c0b278d067b9a77ad4fff7e465b16bb280d56fdae4a98cc0236811a7a2f35a3b09d50b665f86f76261b11832759fae7f\n\nInput: 51c4a33da38dcd9a81d67e5c5ad7d471067a8782ca6d25b79945f1690ba17372f72c716241411fdf61b134270536312e0ccf1d827f60b8a77a5d1035084180994ea576339444f054e90abb7166c5848fd6c27347d1\nSHA3-256: f287cfdf0d4010a0e2eed87dc8e7830d49bb8c3b86a1f1c09abbdabddebbe42d\nSHA3-512: a381a1f9a5a3c2cf3480e5a33cbf32148f8aa4f04ba41bcafa75a321721b6890850bb8cdd94e7d8691541a65d3058796efee022b7cc15c600254039b7691fc76\nSHAKE-128: 557525dc11ae6b2bdadef053e23493d81e48d204e911257c32792ee10508297e975f6f23e1397336b255e154e01dabd680165348c6e23a6a098552a10ed03a80283c5bd6158ee5a8222383c36267f2da576518b8f3b7af0fdacb2be74aa258fedbce179aa2d3b83b74e8fcceaff633ebee7e426059bbc0443071059f360db994fdf933c1c65a901007a9668e0679fe68d41bf82fc8492aa167fdd08761268a94fd8872ae62755bf1e1c1846bb5146d6c7f41d5db6259c5cb9f42e4fea6838dfe9fef6c5f7c47ce97a6622eeb886eef263c7b48347c8636f8ede26ff849f30ecc827a05085d45d51057875c8f072a00fa10eb5ed5554a5310d93803d4c7b7ff020660ae1305ff97639439ee284471a0c3296df5fa2c292b5c4966531ea272e19ecf87ff714a409ead7f7e47306afd948faa667b0eeae844150cfc9193cc0f63e49ac9ee13b41b58275c7262d9e1c283731f07996f7f71bd045a9c63e2b4439e035ac2ae93e0fa2cbbf479daaf0456b8c664fe62ab60216b158cadf223d69eda5f2f35043b727d79ac5c341ddee0df202191fc36b865d924b5c21d4aa091c146cb7203e551884936a5febe0dee42bd79310459fdec93cd09196f0b9faf86d0b3265a5f0aeb24f5be19d1a99e980a5a8a292f158e2ac54d168b49d6225c8b67b0c8732f834258720c337c828c20640b6976a2504dd87b528cc0faf11dc79d957916\nSHAKE-256: ba28bb2b3b6128c1eaa40f7fad34e07cd9a58a7c219faf7c623987c202ae2a37a09ff24c673deef4ae0228b2cf368f5627657951c1939732fe4262ef28c1c096ea29853292dd64e3ba01f33ab257ac7692570dc76efa14cd5e8a61ecd752d5efcc5c8eb66f23f9eeb9e188575c205a396d54a60b0a95bc725210dd4046a6638e30a9949ee3eea7a7e2ce98490a23109fb8b6b08312696839aaca3ec790ffb1553a0edfef0c9d47a6ec90de812b70c631fdc68bdf65d4a6e1ad3a136d852dc881eeafdcaf05a6067255d512b0f86441ad2d375ba2f78282ad2e45577795906e5fe213dfe1c7014db2dec266ca893b42b90204072c55ef8db315dd7c15f7a286126de1b598bbae239c1c1e6e07a53551768ddc3398e9ba464753044a660cd08a8df670deb8bb4b7e85cdf903d1bf09f49123fa07aff19d804a24e2663e85508f9a575cb07303351f18814a1c7d98f7b68cae47573e4a65d12c671137a601aaf70f0238bc3e850e569b42320b48c132a7da05b7b4bf7822ff3c8ca41699b7cefa66ed3ca5634a19f976a5da041bd5d538813886ddc3d984ce8857a1141be5a74faa7574eb355eade42323dc30cbe8b7cd5492efd8f1ad7a36fe4ef1a34debe44f594fa2f6ad18e5e8e2bc43f109b98e9b98f1068218be13d9fea875766064f22331d85387a5fb593b726ef902d50328a434e75d3c03b093be3e490ed0bbcf6d7c26\n\nInput: af5aefb61b5938cd55aa7ef696ddca26e89f9438ec35afa4e0c49b26dbf169dd6df7ca5a3f02a35a7c76ee9506d322b1c8f9399ef0e84f1019", + "1fe6c37ee25d57d1a016d0c258297c35f88b3f96531e0f29d5a3f8fe00\nSHA3-256: 901914cd3c43b94f752fdbda8e8be676c492bb5ff1b259d129ecddbd013af284\nSHA3-512: e7dd2e33e60be0d42b12c8373a36fb964b7efd01c89bc854dc5c50431d8f7edade2605141b50814c39e5bca6c8a6ecc25871d7e76868c8d77d2d91bb224be259\nSHAKE-128: 0c96a1f92e5207bd5b0f737c4fadfb150f295149c7d433a6dd8a2ced262ddbdad5647bf4db930e4462e1a1d1c192f48bf73fda06f6d73e3487b73e869774052e7cf22c9a3619ae2a8b5547e5231ac1528bafdc56b27cca3fc66291f135258a7a2f9a30b2684fbbb368d513a6046c50c5846bd2d260cf0d37e75c2d3b244c39667b3df12803a4658fc89f927e6fb8f709d14905758de13a902d0b39039c8ea6cebb65813d211fd739558724e0b57be1aa272a4e3dfef0d90396404c52d54cfea2dfa8a01a36aa9c152891d1e99e465551c78e7af69b5363819ffe14d4e33e31d99182f250ce19a9070b12ca106a5ba140d2ccdaa111db057596e399f2b18e98faa6397e0cfbd538f14d6271bd9834a3f7b17b9e97fb44acef5efffcc68d860378bc4c0446a0ff90d8a4ec0fe044b7e248f5255f185858f30ec20d12b7985154fb4ac207b11b9c465705148087daae1645cc40a2de2986ea766649523673c8cc340a4d1ef3edecd3bcf13c20c868b3978aca1835284c07e517e3446ca33b82f1984012fdeca395e356e205febd0a962c1351794b735355fafe1db65b40c222191df06c55b7676b6f883136d2f273b048864c75f42efc96232fada93bd3e86b41cf318968b838b7fed32e378558067470c9f376d4abcbabcb4edacdd1dacaf17addddb287f86b6284a106b333c6685e84de826bb0aed18436a9465ba564c6d1bdb0\nSHAKE-256: 7d52250724a0ecc27102de01f447dcc5f8f880b5c63c092d30d0b4428afaf236c3efb4db8d8e259b98d841985311a4c1b0b4569d43d92293d10df96475aa16fc2f77eee4488b1137ac155c8b86e2e9cf7f856b3b9be1e39fbc66ddf41ffedc0727d680651ae15c37df874213af12e8c2639af4304a8175aceedb90ed25a857092a90cf06e7f2de31f55586a322bf3cbe1838eea3289abdeea9863e63b8008f7178a9f4098a87380c2465577cc21a46144c84571c59dca710d31410e6c16e46b997f12a72b4558f4cc44450a05938e67f1b2223eaf49a067d173c7afb963ae23d8d7f339c2e104c4c8b54e1f687f8be775931be8c27a6afee239a2eb1668bef7124c6d533f0db0324c12105307c75835a6f5a8395222bda00134b0ad5ee8b6cb646c1128c5cb1f5ab56f7111a89bb647519be4a2ec26e58a0429ab6b9562f0b900cbdd0dcbf89137e85e10894f7b0d350d9f365ad93224c16c973228d95e40b1a7f5646c629bcae798a72a89fd98fbe4d002d15135ba1d6b31f48a1e80a581fced231cf8c735774423061dc393f011325dece9bf8159be64e7e0def54b696519858582efed05370682ad19b1c393cece3dfb84db80395b9d36efc73f3c0026eb2929c508f5a3477c96fbffff94b796f67844b7ce7eecdd0b601e74021f7bc5642123f90da2738d9a8760e5d22070d5e069ee51132e726cffd2dc1502a1f9486c8\n\nInput: 587422531899b69a4210335f71ce016d83172bc0accc2a66e117dbc02351d7f98d0723e04968862d77398d195fae5a52a5553af85a6bdadb292fc66d040cf74c33fcb8cbf7a985d40a8b1a97b364e06d5a311f4f3f074d\nSHA3-256: 745c6840143e4fb44533ed5a288599c3bfda2518ba76e2df4f816f2f71c5fd18\nSHA3-512: 2c19e49a0555e4c2739fefba00fbf1d31a9406473fc22f632467934fe242bfa8c644d6fe9e419fbd4f3e51ec89684718a351cfb73b9cf0e3cb85e4a9dd2ea2df\nSHAKE-128: 496380cebfd7b2ed2afeee85c5f34f66e30d553ce47b1dd241620142807ecae2c96c032ea36fd74dc2a1683d68ebb526bbc2adc86c1a3a9c5bb0d59ce547c3f57aa5f750028ef4f65dc6bd2c9df4e3aca166c6c8ff30b9399841e14c380c9aca0d52ea494fdcea22539121fe4665f5309e2e8a18b8870f9cb16d36f56dfc93b97860ee991e0e1f2f898a70448edda7e3d17e8f5d6eb46e04646ca8fc35e813b3216c8cf854507f7082b025ca33d95c1282b7ae3a40349b5ee09a3f6900dfcd59f761b7727e9827a368dbd77a38d8757dce7a3f79261c8463925991b45a05e008dcbbf427a886f0995712ab30285e24d216a39b0da65df5273f78af071ed287ac01e2f2784202724f5c3c84545b2dcfa9258a83fb960b50c87ea3a1d895af20abf53c7bf8fe94e699629f0b9a874cd3203c7bc477afe4571b4f6c582429ba3f551708c0d63813e7ab80b2851bfc7472f5647f9f5c48fe776205107772af2e8c80a7dd7bce1747a3c010c8494c1ff10e41ef5a8b6b7f3d8ea19be74c92b433f0be43f469183678eebbf2cb0a5ebcc932d10cb86999cf8315c887a7613c899a0a2fa953a2dd965a21bb89ec202426b241337aa0df69a0a3845796849a9f988651d9929effaaa5193bf4d8acc08c6dacf8172ba295babf565bfebe9b11714d8db876ab4cb679e801f1d056df3577950ea71552070dd93be1c9e3d755022c22f8e827\nSHAKE-256: d748e4469dab41a98e31077395480aeef613551061c8923e4f8f4bd3ad6792d2c3c9431899da77c57b9d207812f1c9df9a13307a884f0d96f8d31092b4abe74bfd2d1db255a82f65f3f0dce9dd4d4fe39e5d7c6d77b1737616ae463d2b9e67f7bc0ef729e3f834d1068091a47cc90f112c537e82a7b1266c3b93e671087f912a63a05b6b0c6d80cdca232e14218f1d8d71079d307861273ae462420a7049fa3350bd40cbffcf43012e60573845a1df2431095d76d8de8840b4fd87e33d49d10713c5ade6b482ae9e0c86a25b668a8add1fbc3eb15f2225914a9a5091127d835a6a9efe874b08da73ed34d46208875d4d592f9cc2bb58e9b15803e4c7fa0e3ca6cc34e950b22938ac54cf788aad8ffeb8211742d3b668792c65b086f928ab91ca38c28fc8425623dad5b6207aed0a6318a31b1937c83f6e1620726817b8319523691931e05b0d0d5c53dc01bb3ec268c57c2cbb2d9d5c9a5a1ac91ab7210aa40c7e2f91abff073ea40b738ce3f6d7708467b21fbc047afae7d7729925e6ca58f29479863a004e3b11c36fe22efaf67a021320c04778b79e5a3eacd9206c4401f7bd61ec4d1caffab5b9a801b7417d095c45b2d096dce4e1b797fdea1c95b3100ef47210b49db4180cc26d6c29a2d41c9bca93fa3825fded61c3569edfbba127f76ce00f84fe86f6361d688206caa841a90c1d698120dacdeaae646c6f1546580c\n\nInput: e1ce4dd63d0da4e12cea38011bb478d02c9f338ee93b44374540ed3a4eb0dd27aa66b5a7b1ba4ce921a8b0783ccb2736b1af28375ccf9e549cd33ef34ed36762253064b8b2487bdb65f8a11f27848334638eea482b2bccc9\nSHA3-256: 5d8f48bb2981b33f91a1c401a6420940d3b9ce550f10f9739a14fb08dfc55214\nSHA3-512: 2accd26d6364cb4170df06e4964edb21d88fc03f306630c44811f05960d8173e0b167b26dd5ba6e205ee59429750fad81fa5eb0da0884888f46b41800de8e730\nSHAKE-128: 247230813012a82ff8b3bbdd6a5992116bd770dce995387f0ce97c6093ae60531e43dd187eb071aa44bbc324e8b49d8a998008202669e43b4596a4139e57715508bcfac38a324ff664a289246c3a6174d58fc97dcd3525b173454524cf836daff7fc578e066bceb28240b56e2d92f9bde7da3dba90e62832dc0550a298a5e158a501585475afd0579b5414009d977827c77b00bb612d02858b176df93980ac2fc4977b41110a84da27d06b2d13eb39347e106e3d31a5a174bfc801778e9f5bd7b109e354c76e1d468de7919108d095040819ae6cdc77d6bc2f0a1f3d3a8dff1f40cc3143907a271e82c78f9143f5c90fdb3dd90390d60af99cc9fec5ceea413c667a225a2420d42d671e60cd2ae160509cf2a6e4fa6d9bc92955a3a635f1d198319ee874dea47940274e84b3723581f3c4fe4649e378a43a012a74122073313f8bd405484e26d46d19ea7713866c9696f23784235850308054c0ab40dd0c5af88125069b36ebf06717ff1eaa2bc60fd3780db465f59ead5a35382b7dd567395fe37299f8ea13148b87624530a849c2131f77ef3f4696e9db1845c4eb50ae85b44a428d1f01f257f8efaff0524807065d4859507f6d5927d117fca14baa6a70350cbeeb82b60d4499c0ac205a2ebceff921672e51bea674f342734ec04580ef53665aa24003fae748332625562c444d5f3de9a6f390c0e9635211cc998c670d5f\nSHAKE-256: 14858342ecdaacacbf11e359e835cbcf58ea9db1f1b0db9581f9c7664c45b9680f3efb9c73ff7c6baec27f8be31434995bcbc48f720867bc41dcbcfc5a55328b57f6776f3433187d2ac668cd02b471d5700ba0a5ae75487379422bce671ea8599e5ab109a7bbf3a783ea8bb09d52878260f58dfa71b54e42e23a9f1618c45e70bdb7f6507a03a59c177142cc77b59ea7e627a329a0edd2b5357f194dee695a5b5e660ba886ce6105f6296fb3cde595a3b204c543d20795aaee7799c8fff8b526f8c0c3df86aa6786eb0929d21da3f9a6947fd50f2bc78bd8be825861f9d4d9326c34952633a316d56367173e9fb6855e1e0ca674958dc6deb39f226d0964b91ee63ea060302fe30cbe7133a3f8e7ef86db6a2507bceb5403a4726e0a0eae04afbe61b675f063cd7b9e55b7f084598d0db11ed433c546a8259b85bc7f382e010a7bdb253b387acf7b12a49e9a012adeb1ec9ca9883808af6f50e0dc6aaa0ffa4a994160317d8ca8b905f26c2cbe86c94c745ac53115358edeebd796563aecae76b7e7dfe89e18db56cde0214d49922730a56f882e69d025c0e3658cb4b2832eb8a3fca57aa1c4236e70371938e270a752ceaa8a45ea045b8fe47a4059270acf5414df3252402fd57fd51acc7b14f2315540372bb184bfd1cb496284d0e8d573a903054a449f3bd3ab66b45bad026485417b7d83bb96f7268cd367e0355e9fab75\n\nInput: 7d3b2faabf7f0e115074f9ea9abd75c57408ef1110422f7ab6aad7d7ba16114323a50d852c62c89e2596e51553f64464e57d80e3d3db023b5128bf9db397d3ec6e1dca6cdc4cfe52b701be280cf50b74e19359718687bfeb92\nSHA3-256: 0800cbf70683163396596d298a4fd71499256b085eec12fb0f3dd48f55179b92\nSHA3-512: f5597d5d3c00620f8efc700ea68c74179bab920f26e1645f1ff4a4c932a962a7d14da5e4face8ec339d7e624856cc36b742d6bcee1fc7607a0de58f1d57fb277\nSHAKE-128: 97d219b4922f32f8e353d2ca1d6f84a7fa2045de30bff7d27429926c43ad8a189575817096a145ccfcfeb7bbda0949697233af85d206eaef7794d2c23e5ece28342631628227594b2ac7b70ed434576802cd986299e495359e3c75c33ff1f37ce4ef00b8f17fec6901e4504bf84bb12d53eb66295c945c1695ac6452f446663a920f57e083198d00ad964ff2832fee8da2cf6b033d43396dc8906cd44df14b4a8ae0748b08dcf75208f434429c83bb891e9af2d2515b670249e75936f1300032ceab050e07d2c31447dbbfa2f642814488c6c7dba32d963429f13389addc3f3c55eaa529c13c8c5354904abcb3823715a141c204031b44a", + "861bc610affe923a7c375e6b0ad926eff423ade762594328c8faedb3e8c80ca4aa68cede5eaa14a6eda6bc2d786211ac8306e45acb013ffbdfce37b9234d73c7c6c8519c15a28fa6a8c17c18573aae91faf358d52cbc3f0da810b5220df7707642d6ce7d209a7cf13e30860c1204ea16e34bc1c0d67239aca9c4d13b58fa588e07f4ec88928bfd6bc1a292f9d9b669ad5648503eb1e58050643f8861c87339c8250d2fb4341ad5bf5edf41f200e43278f6a654a575cc4d6f9ec794c84f9d060bee6ce9e47027ebc058f53f262bc322c4b9350e0ffb209cb18a382a39c5a80af6e8b2612de8de7effbaa877a9a76ae923badba214b8b579503535114ad6cffeffe80bbae0513beca10\nSHAKE-256: 38084b2cfd610b21711da5a97f92e3f328ac66184d4d36e629d54e311fcec9d15a4d2d4ee69b17fe69bc7a5ca3a335473121551e0b39afcec96e77a4494184f48d1e8117560b17f3ffcc644a73b6ccb629b4fe8ef8bea791fb90fbb9ce54c74c4ba2a6256b5af3a62b9feeb9439b75b0235bb599494eb346aa7ca657b7005b65f0fe4ecf379aef6a84d5d8e0360ffce7a6fd49fc30233f6c8d4d8d939927dd8d0d40686ad50d6af985e5df41a84cd3ecbff083bf5dda1579d116441c69787a1d5b0e15a14806fda0005dfaffc67ff482f7dbfcd91f5167d8f735bb37e4cff006d8b4ea3632869d3e607410936741d471b98e72b87be1c4a0f5f109e1e3dc823d377fb05d72ddce8f35b923f89fe5be22368be895d35e314649d5976c809b8bf5e54741fa0976e129e812a30965678c7fb2711c452ecbb72a572c1c8eb61597ce8d5e175a0f7c50be56df02711734cf1319729652ff96340abd14885af1168af7302305c778c4c784c91689f6869ff143925252e48aa8a776fd599ad333a88cc74881543f9299829ff7cae89fbda115a5f138e0836e690382171046ac4ed6ab7dc3a394d25a4a8883c14120204c35064af70871d0c70d30c2b5abf8c5a2e561443e417d7658d76c78e028ef9a937bca7c6bedba3ba9c82e3fd5e99de1e0f717964d3d5b739a1f17a82409d5a4b20426ba4829389978efac6faca990b1ce265088\n\nInput: 026f6f6f05302933c456870c990134163902de8c998b7bb8cc0b78daa9d03f8a0d8c038bb7092e07dd5ba00a743cf7cb4ab8e3c7b6b624f2533ce2c4233f4e352c43af2b1fed779916d79a8fea06bf8561c2881fe0cdbadb2395\nSHA3-256: 84b7e0090567d3ac3ace568927aa57aeb4b4d88d7466d1462267795b253aec18\nSHA3-512: b5541ed65d59251d1137cad24de4979a3ffa0ecda1384e92ddbacfe6d193ee8bd1d582aa2d73eacd1f0949585becb47701bd3ab764ecbf8ed3c6ce32240d1e1e\nSHAKE-128: d27510661de6066bd2027ff51f41d66e5bfdabd3fa19f3c47d1c8607a96c25225f5df6d7f15f8e3d92a53e47e9723ad33ef3200fa9497a0470b6eecfd98df477b3eee5d8805f73efb589518c34bb54a9794efd89d45490526bf2017cdd57ff93f6fb27b98299b2b151635853abcd9bb270976d74347d9cabac6b6cd8ccb5fc520150790934445fb3c01d748f1be8f86133f36a533678e55de791becf9448e1bb07bd7a5f8a94253915a2c717cb900d692be20c5099ae3f8f16b7f477f5475282a632471a1f1e3773b64af8979837b0737725ec1840e41b8fdc7cdaf60a9e3b451392366bd555e7c9087952f5cc88986334e081d4309450665163f97fb4d661797752ad1d3ace059b94cd823246ed49f1ac29912bd96bcfc284fef2c3bb3473ad085a6b7e337378056562134a20d82914d5058c2e12d5a7b8b8bdc78bde3d0371fa5d83072321cb6d4dfd3cfe023a5fe4cfa9647912fbc7984afff4d918f1c436bb0105eb12194704107532edf28db65d538d38a739e3e2e542e449d49b96bcaf36816cace4382d2581a6f92d0b193287e88ad595d635958dfa317f6d5f660ba3f43df86164bc2e7fa092a0c06b0e47cef34d4ad135d9c54eee9cc0f53f621e0953511053ad42f88113638887077a9fba0604faeca893140e741daf4207ade4cde04ad7c865590967deb43e82eb93c214e8b96f50927d04782e934e3a71338f87\nSHAKE-256: 250897fd36c8abffe12be394df2b6e3b824726ccf3e593c2216a3054077de7e34931293dc10930abb7f8d82749ed34923ee7c35ffc2b7030ad053d38a050ae70cd07f3963a21fb7ba2bdf93a31696a1cbb9528855c78c861bee27f42c09dd2ed5785a9cf0fb3e23c7b48d09b45fddf594dce4fedbd87f3d8acdc1a6d90b787726ff031326cea22e8a0e002ba77f157391703c04c7b0d463cb9b41a4e1a46ab40f6595a31b10c0fe6ad3165048610b04b5e42484d80a178ed989a585c4f29dad8a1033dfcf507e192ca70c1cfb7bf93327f30cc3179e1d9fe608a6bccc6e6b247c5203c2856e0063975cac8f9fa78d9f28e1d60ecbc3386b4acb841b3c9c43c04599fb4f062793613770a5504f7b18f01aa20a1efb9ceba70fdde1f6914cfc300c6f4d6eb4877191d8b41866b6f08beabeb523528c28334aefc8ed68311d7d04dbc215fd0c9193e1952991236ded46b743e50bdddce37917715971bb958213ca0716dae67d8f217d94d6ab50c757c8680ee430fe4c448aba260f3f677c251c208b7e4cfc743711b6da6b3fd7070966230093c245517514cf1121d17278fa976b2c426840b52d90cbf5456f6227aa8c778f6381251d8c90883686e4dc854d0b63f76687620e3120a7d308288c85296f8da6134eb7105fabe487ee0ff497751921db85ccb66dd0eade3736b332d104802a51aa4a916e72c075d7fe222994e3913d1\n\nInput: 9d23e38ac6706488f7dd2b6f87e3761506dd7e93a7b3699d87d08967aa52fa64565cfb8aa8e883cebab09fe24ecec25a6e908a940933182eefbdab8e63243aa086eee375a5759e0631e0dbc8fd4f2bb5e7205502ddc7ec2e3cf02e\nSHA3-256: cb4ad71cea10814f40f3bf9b9d4d645fe3c19e85516800110d40f8ef73907b29\nSHA3-512: d90d6ffea56b9c241c931cc3decf892dbc188d30ade4c3f6f3f937f7f621fb2e3747b394ccd6e98f94d6367703acb576de7fc1503dfa58d9680520969b83bce0\nSHAKE-128: 55257719bbcae66813dab30ea0d61bd99999b36ec3f5c70d4e43a767eb14ec9d801e5cac7ddff3953d28a68d5add288a227530a64c3ab12702ac7e94c9b620b5680e25e4ce407a44448328679351554364f211f56acdf44e159a9468ee25718aeba2ddb033d8c6062f96af674699bd9444abf79e90e171234bb5b7018a22e96068a185e981f718d14644231079d1e9d4afd547f43fd441369e286182b740e14c5fc0ddde0d5beadc84f80073304beab8d45bf015560bdc80e59a9bb2c686b587fd6f4e19dc9921fab0fec24ba1f3361a3ca7c57d70a6ddacc15af87cd7eac343165e5e8fa700193a94f3a4e1b326ea4e3ad630ba713043a4ba78a439f274e6facecaf4176c5641661f030160bcd806fb904c0b715d3e7bc603f2864533434d6c500a504e374ced40fe08d0e1a4d3a0bc689c40962188cb8d8a82b7fe5a91154c98470e4f59c06d7d4d023e3701619e6303a06fae769dc12d7aa4eed45bf7b5143e472e905a837f9f2e97e56cdc9f0b0661f13b776e7e61c354c690d56dfd539690a8230a10bfeaf08aa046f3c5bd8e93588acff43f23b6c5aa48826560a61a0a89c475cf38888cde67e8a316484038590013727033d8fff87f99920bc13140e2806818b14ea027433fea7a4392ee321e7badbfae9ab4ccf5bd45f15953fb9320d3b05736164cc77a36c5bad10c8226217ad3cb2eb89df387b67154981901e68e\nSHAKE-256: 21754cc0bf73502e459215539932e58d15eec9080272083e1d37866f5dc1fd55bad7ff611920359401088c02bda64fc5f1241b9099ebcb293bb90bc27831bac0021400b7170aaefd019d3e2164eaa5df1b422834f9853304e2505d52f5b05a9a43eb69d7896355527c4ab233c7677e9d5c1ba778a57d80a2d9e8373ca8e84d252a227101bf73b8df6f8296187476f2ae50777526d4ce3e3b9ce53f7e5fad13b1cd5c1ddb808f1ef7f3b1185a772a0dfd81d25a9d677b69454319486b48dde7a5138ee634cbe4a1f21770bebfdd069fb119d00eb45997639938f0e1ea09a145b87276ac242595533869ff49cf341fce485ba63d3023c8f9f015e8e0d42932087a7d5b9df36b960a31a8ba963903767dea2b166d17ce346722c4528ea083848a1df988c54dd61406c1e2c2702bba80bcac21c26fcc29721a8aeebc22cfa194e8ff7be9d92a43c56ec239b8571dc26e5b4a70c5537973322e08a3b121095e873fbf125da1c76a1ce4c14d6311e93b0341f7339842d5e87249b15dda9f07c0212bef7a14fe0afdebd7002610b487888768268e74ec938522ee1597662e797d0822b858c2ea888c78647bcde64c1411b7335fa4c23c6151e6bba93fdf49c231e4c64e6424690959d95ef6ad792bd5077276696c7cc31bf76c5c0365c7431b4b32c37b526762dc2f849b60efb10636a6f8f87337f6512c0a2bc29137ee7d4b908793b3\n\nInput: c6361cb5c9b8d03b126324ba43509f9fa8a0628fd59a45315f7392b4f552be15b3cb1fa668e70f038fc272de922118230d12848915a77a80d03b5edb0fbf7b98965d0fd9e2bfd2ba999c1943c32439ff017b7c6a5b392d6daceb661e\nSHA3-256: 54255d6afda6da8ae4dae17943d3fd52eca903e6b678ebc13b869f3aec4edb41\nSHA3-512: 180d74a3318fe1ddc6f98a788ad52ed30cff77e31714a6960f291b476501e3a36b8444576fc70809db9b08f7cbe7c73a8b4c87720d9079a05b1d6b2bed8a9f99\nSHAKE-128: 0c8192d81efd7bf6b9f357cbbc9464471e607b6b3dc59507848026a94822fc8341a1d14a9b31e34596933c2ef458ae33bda0fe2e97618c5c1ffe6ddc0834ad9337ec1ebe76c6d48de1c274e75888f9f666aedaf5bf3bb85ba8fbf7b08bc2a3fd325f3c22c44f0fffb59da41ade87ba2f537dc9bc9fc1353c66d36f0d079e042689a22a1439c54045e3f2b0cc535d34ef86b0cae88630e6b112ec2e88c99aec71a22e974f2e6a25d8a748c27d51739ff2ce97ace19fe9ef4d1501684e31568b2fdcede38715b112c7e6e8f5b42b010aa3c0a80e2e28cd3d32cf9332f8fbf3ad6ea87136575fa4bc6809d00174850988bb2367737f819da25d36c708d00e2139769a4b0ecde6da112f4b9bcb3f7def59e407d1d505496b782b8c7e87c5ac9ce619257739f31bcc6dd7c14cf100d199d12939d7e2a8d492b4bcce4b946369d999de580ebaab9c5b39ed89f124b1c6e9a3e9ac396d35d08d0e3cb4da9f42c14999724d3ae54bcfead719ea4a29b1be840b5db9b2261b6ce81d857be36d9b6dc6ad169a36c98be353ec2f944c69146fd1c07c03bd80bbda7502af326bda85e6d574b6bee682f0e12dc2e8edc686ba6630c88f6e9c8fcf4a09137cb53f1c556b13408e3285ccc07587c92550fd79826208586a4b14d122d78f2f976060fefe4edeef0c1f61b48026a2cb8a2ce5f9692e99759b9e34952a2fb3d8aaa64ae6a9ab6ee136\nSHAKE-256: 8c6f9ea5a91b61911d2ff807a2fae9d8036bd3e111e7add0d7fb2e336977ea814747d8585543028606d6c80299fb254ed1ad5945e08be0f05000ee3523234fcdec189470dacc349da7fb83d97ad39cfb049d01ef2399f65320e7856a872e1cff75bc096126701082ba6aaf2dba67", + "c9cee12d1118fad215aaaa6c5cf9a2d398ed61330eaac68cf988b2573cfd616b720cdddf5781b575d965eb175e56092c2b409ce9247d06f7d572f41a3eb33e4028ce28468803fcd9387c2394c4d876bca1ab807da19c62c81b3de6ee4f476c9dece51f01e37a7c5bc9e71e5ae258a91d609f538f1c18273a704cf2e220db241474a5240cb4a9ecbf978201c99543a60a9fea8f5db2f108b1a3a335f3b9a40425a62c9c7e4d8666f2f6f25e23477f5cebec7fe8143e0153071acd71b0d773e340c2cf484738c613c1de3c680412d69ae3fc367c3e772985b2ced66c0364d7dccb2a4843f6481f26ff0af9b30dcc2f4fcf9a6f07a5ca8d0612866a5913cda9ddeb2a6c763e37b6c8316b6ae4bcabaef53cee189cb5316a49d423820ba967bfb4375148cd33407cf77a23215884ca27bda0139f970a0db0c93fd20dac887145644326db4751c865da2f41c43b7489dc6f156953371dd1f2e5139aba252100a61c8eab517c5f4326133b42d1721737c8e43a49720c01c55d279d511c9058711f33a43bcaca341ff065758dc968afc1d1373920c5\n\nInput: 7bf763dccf44a6333d887207bef0937e665b829b04add35a2c6c6b96137993b6b0e5fca1600dc3b70935ef519fe86c1831dcdab6c4589f9104dabdadad69765bdad6e00fd651cda696bf9705f7db40a720a1aed47ef6363b345365c4ab\nSHA3-256: 0200275effd7abc405054a471f295744c11ac480bd68fdb28d94b6e0ee3cc396\nSHA3-512: 7f4509d8cf8db08cdf280ebfe5082f987dfdc77a35686661661dad7947773f626fd8ab01d8cfb730f05e1d466815b8465c74e7b836b29b8d8b1a206c0e7414f1\nSHAKE-128: 21de48aed9c76315176999df80996d7469c099020f65c45d4be7ad89f376c89060b20932cd066e520190293fb3a8f972ee70af41d125c00388ce945e3d6415444d65db641254a79e8b8b78330822d3d7959c674346997b83db3ad2c0e3c603435661528a93429d821de449fb4b58e1441074080fd2711b5c16be28698bbd9def1c1eb7c6a7a69a72708ae169b0acae6cc11ddf87968583d865fe068732f3330b0299dffbff6f492c7e51634e2df9652e690bc0c27b8498b374628cf7796ceb23073533487fec76430f6b45d9f63fb1c7c898fb65c77d0bc73e6149cbaf6ae785ff71480300bbe8932f353fac59e047f3c7a9afce44b94c1c379207acc431a2f41527b405d21e4816c6a2450710e940fe64b46854f0179af91fe24c2b5cbaddf1b57a72b06d80d913f3a055cd950a3082cc6eca922a42143cc5eb6d45c73019e5e669b6d3d9aaa340a6ef2441ee9006ab1060d06a304a9e4eecd5a0e96b8e2a58236c1f2a4faf51bee1a78f28766a8da29ef28262c39483a75edc23fbebabdec83dc19f94e0a2cf7742f0d9782671756f1e0e01ea8866adca3ae1b8c896c34e6956b220ef8affed3297b2747a0a64ba4aff09b1de13f8d64bbdd8198a9b03ddf3b8dcdddaeb74d98cc071126609c9a9b12bdaa9281be176c76b1d39806dd52c9ca8eedaa10d41f13a1192e5bfc204d484d4b42eed1905b69e8f22bcd3c9360945\nSHAKE-256: 597dc9c838d9d63c934853118ef09d7671cb29f248de1c4b0824fa340d96c56896e61cb512ed14642aae2e4b6925251918ad8d38b6b9b81a4c2518925e73a5aedcfc6074c72f8655d5e61bde0d282b7f01fad3b2877836566643d3a743022fcd7274f696d35e1ec7fd742fc8b522dcfb9fb6b0b8f39dfce2956d667cdc509ec8e39978db96ab0bc67e3f3bbe3b8985778ca8dc619920ca05d1f8319a2b353925900310f22af11284686016294beb379923ef8e83439a63302ae0cc4c4c53a6c2d24137aed274854a0ea359d656de607969bd0f9195a909ee06fa14e26a0308a2bbaa08c51963fb7165669a685ee0241045e59362336c8634967ace60786f92c53820b4383bf0c142bf23acfd3d896e885bbc1967be5fccb848eaba4a0c7bf9f8813ad95d9c791bc1ee0ce11a7a43dfa6dc3663eae0960279881fcf61d361da95208a5f0a1700e046ea0036321091ada9e686d5642e9d761692045e29b9e8e9f5a764a3c1e92c093a259091fb6eacbb9744efe5875dcc39c9a401b746d6d3f79100714774551318a2c0c3c11510540cbcfbd86bef903d2324e993b01de429a05d4b48faa4f36ac2345b6546d8ce95739610937312975005b3e5574a2a319fcfe337f57dad62c9849343f778b66a6179a58c66503a4769b397d404ffee03790b4f2d59770f74553db6a0cec5176bbc466a476b99c93ad36b50c0c59060d390472c\n\nInput: 5415d15820000e1a488c2bc7076b50cd22befa33c2915146d092615168f6dafefd806de15a3144df50c6afa546e5057186bba9722afcf4736a6b70a3a10e56fd74243f89e812eb3917a6f9082e794cd3f95425bc8d53b93663b07e738100\nSHA3-256: e74b94a28b1cd757b863f5d1f4467dce3b23840170fb8c96a913d236e9426173\nSHA3-512: f06a46168dd515fd8bed004a066fd64dee3ff932d19f461039af26596b9e99ce13b80d1edb15c9866c2d4a6304142eed9478fb8bd41ede252c96c43cf51975bb\nSHAKE-128: 2b976f8eadebe15cc99ffeb62eb705966a45cd6835f4a97500c190f3ffd875336a5b4a5cd54c3a9aab605f19109a19e8465504395ee6db7e6f0f3858ec68a6a7a565fe4566021c55a7cc575b4e9b168da7715518c7bf8b8153d5947d19c69314d94f66fb41a4fdd4181bf5a4381dd042e36f57ff34bea5557acf4f2b1b68e6589be1feac46dd466104f6c3f849d77b1035114996696abc7862b8ce2df12d297d467ef9fb54ec4ba4a150b399ad6cefdb8ae40794a99f4ef03ee88c21021f6b787b2c19286627b964db57b08220ae39687be21a6582a2cd83d128b8149e9820d88ea7aa3ba970678c7a04ca2cefdbe9048b64a9309ca27acc0e11ec66b47a55c1f0b4b89ae57099d5774f063bfc4f2dc8c446a18ca9dee5d79538473d569e190c53c856df8a03f8fe1ae2e76dbb5a21973f960ca6a64eb82b573533e2bb840acc09eff8a3c61d882b29cc417208c87faa718770567a6b8fba8d3fa782aa9a69bb9429d40cd1361d5251b573d3c0b89656e74292c661dc9340d65a9a737cc37f1b2f2515985941126fe395501ff762114f5ff61e44f88bfbf8cb5f53d4f145cffd72c105dd76247f0fe814cd781f20b9716db865fb7d553cc545fd691053dffc0088fbef6042f77f2f0458bcff6f76d9138789cbf91936ff0f00f827815a10cb7761da5272806885d2c622172527f8952f37063be01e5a279fde34a0ec5b2b8bf2\nSHAKE-256: a7554b32621046f3e5d68e1ead1437fa53749908912275d445972a796dbe168632cd0705b3573fa01b7a14f5e101b5c4f31fa18d059d0883075cdfbf8bbc67211c9232e9cc05bba2590fb29b0cede00fceaf37bbf9f671197743695cd3882519965a58dd171d20f8194376ef4cb229d9bf4978dbdd859d57f101f83cf74f3a3ba306d0431f8fd07423513960d10295d9016b7b4e74eb6441f6b4c88f567329ef7bbedc89b47bff0afdaea325fdff7f3d5f0ea87f89f08fcba941c28d7a96604e1d5c2a4d41f1b0274bee3b43a404c9a956f3db677e3e9a16c5d6e6436412a9a04e04f3869263e420be3dda6a1c98e494f999d78bfa92578e89ce584e13eb6169cb13cf295978f37b058faa691a8f1fc1d8c5e6efd6403bccc1a078351b90a9c6bb54b849ddf2fcbb6b8339e04ba8e305135cb4eea8d2c743c3b822ae9c35e3b284755c9088143c1dbfba7af07261387063c85a81bba504b6883b894f6ccf03b676d41de20b57c4cc6cb150673cb6fa3ab9bc054ef0b2f30f77c6639669b015051e01c33744c32c48151156f0a054806e3b3c59ad220003238b7c99a276b0d8b8006f04c38af016db865759d8d45201056494eb18a568f0f107b4cc40964ac073539ec18953b692dd0b78050fd3f6f52306a9d4d6b76ed1ddc37bad9369b9fa8a7347b8f34ca8874d666d07a64519dbe9af724a9ed582d9fc2e5e3049cd3d40f6\n\nInput: 9fd6dc35f5a262f697280f2f02c5afb3bbb8472368510c56649732a02366e2e30986239cf17b06b12fbdd2a2b9fde72a4d03ffa2cea599299106415735ee3e565fbe194e2daf7effa03ff1eb655768895c41feb811a0da9621100c03599518\nSHA3-256: a1e53a1689157ba4e3eebdd453483b93decf2e902410e8b96375aaea3877602f\nSHA3-512: f926cbb911690568b3482c542818afd24c9e3f0523f5aa2b619131449df498e91e1c51a03d15e26ad6a105d0cb49e06b25076e453159ce9d58b13fc3604267d1\nSHAKE-128: 8715cda875410d832aa1fd358c47f3c7480547b2ff4b171d062cb8a5a8d8787f3e316056f52d1d9951b2714495a42ab9b48ba509b91f1aaacada87c28d7d5dce5469c131373d2de9fdebf0592267a1e7667f9bdf11f8347626b69e98ada84ff2cefa5776580fa0fe2bbd99c0afce5fb27922588203ed5c3e18b68ba1530fa68e4277ae5951b64b39207088edb900bf1be512019320c0a1ec59d2983b845577eeccf7cf6901b129aa62bd2dadbe1134a721a6d05775855c0a79a12988a792f1e630a53828f23fe3644f54f6be9ce3fbe69c432f5d96899c5ad8a2b5eb72c2e90f9fe625c8e2c9a22bf153f53ab993939fdc642d9afc3d1c0402626a58fde974399cbf872a38b6fb518cb19ccc94f41a306d0883404926e09a6d5a6faf069a5e95ad56e535511b37c63d668cefc770b73384c391b629c7a2d0b8b10a13a8dc4e91fadf0a233e1c3bd9f804ffe715a57ffb7ee761217c4b7532bdfd63f8c6692f9478fdf89cf5e79b7ad0cb6d50ce7310ca269b5b441617773e7ede9b34449f6d21effcee39bf6c09b85351b7ca4f314b291b7ab1e665e1b2131853af28faa5478a054d9e21fd72a79cf4a8c2e252965a291075dfb2effa7cf58307fb0f1f9d7909961103223c53eddf8f058afdcb72e3cd08953baffb6ac6432786a65f2907ab2d01e73d48e13bbecb98e5a498e3264d5f9c4d49cd99b6391ff6cdb7c62f299bd6\nSHAKE-256: 94d6441be046af6d276dd611826b017165fb240cf6300f37791fa5f08d54edb1c92e279fa1ee2b4d7053bff2c0922a6c1d981908bc14a340dd5ae636ce3f649b2dfc8fada905941a023f99eefe1b2f2cbad7a1d5b4ae59e7d547891527eba4b26edf3afdbe86f8f64ddc4b8e544235998b424d73f1025980c08db26dc5e4a5ece1b95b0ab6939df0d3f127db81af87c37612416dd5f8a209c81a5c97ee7cfff616d500c69a1b066b6155a6a58e27c0ff5125621449ba614803fe32d667f93f32b26ae23783917109bb8dd92f1afca98add622a5e253972d9b54aaae0891af9092681c1c81a7d34021ffa945ad0c25c7c76cfa083c72f6a39c6a884561a22d9334f1411ea02bf14ce793e9c1144204ec20f60bb72e6d34390df5d1f5d1cd6967c4e3d1dff760d2f46ff403bebc4bebfeb7118595553a3084a9f82e431a4e0c3113f3fd9a7b2bab8710bed6a605de0e20ad4ddb8e98a321d77ac46488bde96799456488c30795fe2d35b35900a35533197cb4325655aef35f068c2eb084488e97903af2ecd89cfb753da331938b994d075277b04cf45999a17c71d4fd5cc09d2c9c8e64907f7b1580bacc2dc47a56be480ffc008fd8a2bfe627133e0e48e0180dfb1d51857a6649b7483fb81773a0aae1bcb0dbfa60518b438b60b4a726a5ba20eb5f", + "fb3cf9e0ef11ace7bce448847338dae24b25fed4f6a163e8be81cc9d9a43b\n\nInput: fef8f97e9c7b78604bdf862e367b530c0e78fe440b2a9b9d1070ec5ac3c54d3af1664ab10ee585c74a1ff66adf4071ea381968cc4dedb45d54dc070b0b6971c966feff79a3ab4597ac2ea4cc2acb62cb977c99daf1fac18b31cf7ce582e6598e\nSHA3-256: 71fc2ee2b0f65d92a641c96de854caa02a091f4418d24ffa330a02ab8ab1d114\nSHA3-512: 1996c82450ba523bdf777e428f1e92d226613bbb40f5cede9ef7452d9f128be2ac7f013efb991ae1d0b6b24d6080051f7d5cc68883ae69584db094d8861b00bc\nSHAKE-128: cf60cec3e74ff7f2872c7803f1650122e1a4b60ba63fe0709c43ad2e79e6cb1f3f6e5c56d5360def71c5ce548b90aaa967fc33e94f3f9cce40e705c2e6e9648cddcec54d8bee72d63b8cd15a3ef0ab530d391590091d70c40835c5fb6929c5f6212e1b26b59945570eb6671843cfb7b277883d2bd7aee517477dd78c9e1e564507fa7c8273f0c34a25313e68624d50ac600decf4e61bbf1bbd89848044b3617342ed7f5b1810ab2a2cbf76fbf2aceaae1d46dda5b43cd6820cc08be7cb7c3a4f0ef5b1ccf0a21a3a43ed68dada2ad7527007ed0dbef96bbb7431dbd2c74c1b6573fba73bf9df1a4213ba567e1f19dd4c4ae047a8e5a2da7fedc9050b460775e9ac9ee356a8e579382e50bea24c6866becd19f723ea3725f49381fa45194f65db690db4450f98207a6f4a7dc47cdd89ae4633d936479f6640b1900e77f6d075a63dc76ee63608c66e434aef6b2ad9f3224dbeadbdb515812e7156842a454f55efd407f4e6cfb4a08dd5b1613be47aaa2ea76c1eb75e2647e28d068554338e314eba2bf82576da349b63fd72549da7eb3f391f975dbe3f1c774e6e39708c7973cfb045f1b2e4fa3b34414ec9f85aaf45008070f1d57f0c3874b5688d515b636c77ced23e0557736494dc17d8cac3b3b161f3bd66513281ee26fb48a4fcb81d1882659e8b90e4db542e705e85898c7ae8e80590682848c0ecf371202eecfc25b1e9\nSHAKE-256: 8531faee306337264a5ce4dab36cfe75b6eff44682fb38d3aa571dc4f6832546a5ccfa6f8885bb88d5f2ae04771434c020152212b09ea62b8eb5caf805c66ae10fe05f2df2baa5a96fa4b4df06e80422df03310b5255df69a138ca9f28406d9e698e5f0de7afd6b2fe3cf652cd0818b0e096f40d88919f41286350a6026b1ed629844ed79ef3436a77a25c06476b5047bac8da8187507c7b0772e12ca201fb6f0c2a09ac30b0be1e9c3b9fb7d8bbd57d36284d307a187b8fbf99ce1d52a7b384c312b39d1634b1ae66a1b1173e0991098357c887378b2b6f96b66d3fac9d4e3bb8f772288a627cc4d829d59d573ac734da755d61166d4cc350dc1a29f4e472cf12170e18219de1a5c396fb874235eed26d9dd04ddd384fd85aecff2d55cd10402e3f2024d96981d213532b09cfb1199256fc4406241dfa0affa4a607a806083fa7f406d74bb05a5ec014bde3b302060153bd683d542c1871d80af259c505347975fdaaaf1c1bfd83538f3cd0beb068bf6f75e308982ddf578245dd9058e85c13a559c2ae06e3dc1771224873867e92c15a45567309981ecd7f452f009ada7424c169774d83ce63e0a2c92102ed36fd0ce89aa00981f148ea782e4d4d69b4e1bb55bc0cf24b2b58976c90f6fc10bae429e09cb90ca4b751ddff5e4acac52cd99816f06c59d82a174f03126a5123ffad873156abdb736b9716c1015f92ebb4710a\n\nInput: f3d3226eac14d6204a72aa3814fe609a960cb49b23ac29bce72d06cb378f7d29a1483f99cd0ef4902cdc5f819ea11eb871bf6108157fb05937e9a580395eab43b9feec72b69561e066bd6a4ab52ad60066307919195320c166eceb622a1aaa8779\nSHA3-256: 7da625f7af3b57ea3bf2826722d03d2e0a093f7fc1ab3be16ef4853288943cc8\nSHA3-512: 33a98ed1590484d60b149507a6ed6ee13200dc356608be4519b2faf84b6087efcba295b380f43f9ae372a83319b39422e96ba7dcc44ffb419f3c465c9fa1541e\nSHAKE-128: fb12cb4de9e6620d1dc75962896a66c3ceea98b40665529be95c11c10aa733503228536401ffc38494af704ae73462ba4ec0ca45c6b814bef7f16414603f9d645f5737c3f8fdf14eae147cdf4723208de000d1bbcdb0fd6787c2eb3eb60645f170eb08ba6738e8060ff248a3e548c3229d92fe27800ea7729630bc7e321c192a1fbb2f49fd052dc2bd6746dd9a878a53c2ec61fe31daabb73e9d8634d4e9fad56a66ab4f19901b66b6dacc766bb8250e880ef513416f4dd3fa42b0c8b172c8ae199fc8d4e1d0452b15d9865692e1ea522ddd197b202b96d8321054996c509e068c21aca3b9da33c1dd7caf2971c4e35034a0541bd54d4dc06bc9fb98837c3df04fb501944e1581710ec7a77cbac83d28a742f519d3d42e1440ee765b064bbe93612ee64c136fff202cce33f177f9309d3e1d3a953607a1e6a836da6ff5b539fe78aef1bba10310328baf6fbfaca69a5e72117ced8f3ccef57e668d1b9c6f32a2cf81fdbcab441e8af34ecea7fac38f05366a516e33aeb5b119d4e0f94317d641f6f546c659dbc922d24c6e1102098b344d651a7f79c2f09527789c09f0fe3159ef6913e910c70dbbf7c087ddf26eb42abfca439befb7794785cb88205465678afa9d76189baf1b85bc8b059261d908fd9f096cc966a696184880cee81759e581bd4816e8980d016702e27dc730a9b0c87aee3f23215bb62fb459153c5bd107e6\nSHAKE-256: ee80e5705f423446c944c123efbe15972ff72dac1310fb1c010cc66d1bb21c66084b242bc39bd881e755ae4f61bdd5a57ce87284d4e81c7eff570165a66e7894425a6bb4f5475c0c792604962637286750ddec91519601736febeeb35fe11d02bce2bcadbb37079be4bdf71cb777d582444ea15884513c486a343ca4d9f41f9e4df8bd3f8403aaa8e676af52dce812de685fbea566df862a7e3e28044e07dd0e55ee2b2a26985df864b03af809a45314415b2c2ab6c3625915be50cb213a5cb362e177b40d6e2b9415029249abd224358ef52490dcde39cecca69b313797166dd7ad5ba1c5c02294e8f81bcf4b395288a4885e4baaee6174aa5b600651f39cee7897c321ea1311817ca97c5532d0fcb4eec9961c26548edbd09bd75111a2cf9ba400e055887d5f81b84415fc8980901bd48dd5dd3b83b65e184d515835265c36940598e5292fcc4c2c79f506b199941142aea01ca60d4f1a8231d2d8fed8fd2125c6546b089643c5bb6056bd3de226708765161b55af0babdd051a37ae5ee91b7f7392ce9cd2687916b784b23aec3e10affb6c8365cca79325d910eff982506fa8179251ba5e3284aefb6f9cd86d5813f1dad4b7f1466665dbf670b9208a26f87bed1f3a1cf7de556625149891496d3add375c2397231e89d91c5ba1d80ae58832cf6fd483cef4507cce4e8518867175e2f1deed27118b098d57c9ad64ec6ca3\n\nInput: 35c1d99c7a4b1ebc4afa5ee2d59300c9c7a0416dc27d9270370c913c1e7ee90ea7a8eac4846721003bcf667ec3c6a1d904af4075ad17a5448bc9af0a0a1b170f814ee4feddfdbfe4112748e93958f00a250608a5e23e5770b75bd74cbd361a3b6ba7\nSHA3-256: d16792fd65145017cbc7b459cece6175ea71bebe645905bec5b6f7e3f08b1b68\nSHA3-512: 94d42440814739587447600f78a1209e32ec3898068962133ad8cb131e55e0d71933ad06cbc88b57b62dfceb8c007f95341afaa4a4e66acfdf934753cbc3335c\nSHAKE-128: 0f084c6ba1d72c6428b0f8bd4f874c77aa4cd16480374493f80df21bf986d204c6892875cc61bbad2e469a03b082bc26388eb41c863db775dc082b79c770ca8ed6bcd63cc96f2f2cca7bae5851f4111e856a8c618ebe112e31926336879f5b0ade23026076c5ff5b68ac6103387c2db593de91b08a5efdb86f4da0ff62e9118963cb7c235cda314fb0503f4a0cb99b0376c6e03b83a089c6504f05d07a2d14e286f46b52490c9b41661e0f372c52b5977ff5cd149bcb195cde578adb10cc0c2eb1820bfb20fa9883fc5836e0350c4c105af6eb576848103691d74a65064c4a6cb43cfb5124437399c2d8117a590b149bca4e07f87971c892d2f6b4c73ccfbafc5f75a55bd2cac81a38feb1eb0c8cd0c22d5dc4b4e650e2cc17919a0fe612b748c6dc1e96ce44c4cf90177f77d9d40dcddf1297f23551fc0f1a365f2fe35e06093c4a80b5be2a3667257dd6649957dfa2ec007ee8824a4cc2186ebc2c1511fd2020cea8dfdf676ee064ff2b378ae27a7c11c16989a5d1ebc7cb0b222d6166746787c02d22e6c27750c51a2a376f905c08fcecd5bcd90e2fa071a8890817d17dfcc9f3f5df43d94e55d3a3b27f428be895e229d1aabad52f84c1814878fc14a93e55438b16ace6c3e57d2198bb5f19770d9ee75034979d908f8166fda8d121a671430e6d761f44f26247cab72fd2bf6f5fae52f74cb75375709f1abd5dbec80e38\nSHAKE-256: c8d924239ce5ce0f47335316f9d65f157b063d130e2352a48385ede6366473d1206f429199d0493ecf656ad7ae952889d90722f85420b38dc18d74ffc3442914c9d78843b08072b02bcaf4cbe575ebf8a117b57c5169bef30b0bd1ae64841be7a6d81f012bbd3da7bc4b75c06d58195e759f00b6024847c656b9bc55e5a4ae93733bcf9c8e198a4a39c47710e1e9d334be8d4fdd7af9f1d338d4db701fa1597c2e48489691a57293b8dedcdb549f4e95b3534092d07ee56989c011590ff555bcf08b7f3132c3e56d331a6785d7c5d35210d7e18ef67cf03f4b0e1430eaa11225d1e6c3709a1d5ad7f043d0381589d3ec2e2e251ad6bedee737e5a841ed40e49a84b818621e3adea56aaa86d4f7e808be98f47cab79b88cc03f66a95f855e6321c6ccfc31ac2862778e87e25f024cfbe1ba1249831baed64594b6c672d05d70284b5252629d9ca508e471871d1cd0902ff66bcfdffbec253e638dd9e25c2e0bfbb62d43cd5f80b820e5af462cefe4b584aeffe251c64a477d74b14f7c34b838924570df3a44e6bc30c43f15df683224297016dd214729cd3a717ad10ba65ecce3ca84f7f95a8d06e39251a06353e390a9e259d095a35414d0cec4fded093b949f33ea8c35f485a0ac4210cac6e4e88ff9aa4b7cf9bda78c1da0b320958bdadc6f12af84b9b6affcabd241871f047c9b98536825799bf35deefc8a37789003c670\n\nInput: 3c6ba9073b3e434e295dcf913cba6675d372b2588e1be48cf5c4483bcfecfae6e5b25f4547233d50a27104c4a772734616579308a87095f2c629af46669516ef514111e44bb0cc0b58b3cda35a7bb2ea6862d056ca68ab5d06dd4e457bf6aa01ea225f\nSHA3-256: e48658f69e93496284a59a0d4a9df639dc751c903faa4de0a2b23e12e040eb1a\nSHA3-512: 6cf1a0274c86a702c43d1d8f550a30cb33cfe2d9cb33237298732ac6ff4d285a842449480513734e0c4fcfd03a982dcbf380b24c327f3dfde512a8ef42cbd7a3\nSHAKE-128: a0c763b55920412584267b81f48fae5f7d6f18311bc8b32b57c205c6d0f0c8b661f171c94cf66a555423876fb4dd5359a3491791a2257f779562978478a03dbb7e176d3487d6f1d7543b247a8e1d42e9483fa996a3487d5552ba50a61ab28377586b32c400bf6663ffb7d3e7d3af6fa2bc81d4c", + "368f93cbbdd31c73e7d151701aff7627448bad9ace94d2512d45477577bc83e81abdbbeb3e8c319871847f31f04edbafdb69653b4620af05e5ee7105c1766909bf55ffd46df09a22947dac99384bca2172836cea8376457c24bb43fc567039e8b471f3b09812dd013b25dda072211612fadc166e2bb2d303960af063b1ee50c6cd8f173ee3373aee2a3172ebf9f2638d550c7f28664d5473909f605996aa5ff73c22298164a41ca888064af08ac07392e200442246bac7b3764139703bab9ae64320d0676afbf295e3a50fae5e2df68ac05776a298453a933447b681dec3ff2088ff3a7eb126a86c5a13b50d9ccea12c48bdeb6af0f503566a8321cfb15e12c99b62fb8ad043571ae37c5acb4a63923f6ab63e360f4b52a9ad65b2d0b9484fbd354544c461f7feda6c8a5937fb0f3ac2319cff7c252275e926787738911955917dc018771a21a8342873436da1972eb53ee239fb3cc887a2b502ed363e686caddf102b6da5c8f0506268c0e5e7021d1e85e2b37eb9cb93111fdde4a33804d667f3dc6e1df6324133cd2533f68\nSHAKE-256: 9b43a7e61d41c03861f1e07dfdd8ef50780acc4b59b7c61431af948c7d779d53a406ebd5018d35753595371ae4adf08f3b41ecaf0f7beb28d0adb60cc2a86ba22369862ec617122ef1716fe309740f0754844c06142aa3a7f720f75b1da0008812b7d0f6c81a7bfcace3468385f5673705bb7cbe15c5578d35fa2a5694a9969caf67b3764df9c963eeb358fa3222ebbfbedc758b17d38695d6e18ba82f523d12e4537eb7604f2d1108351161f6caf5fd4723c0ca11641c9f92d065461a8c17ff68b04ff26cad14f6aaa6ae4f9fa20491e1aea1b925f0bf385c3baec611a70f8553c7b46567e5ffae040251cb4f97095a222f1b599a6c55c61e3b9001c6dd654e47ac52f05d51b3cfc56b9d6ed2a072e0bade5acf574ce918de83d200165ec67daf1a639cee4d0632ed23bdf718addff425ae83f527e62e67b2533b3728d1005d1a70ac6a6f5f9ea14b4f72da3c21588e237fbc9825e32005874b82dccf61fc77638c6125bd097aae9165191b1c71b8a134d4b92cd37ae9273a415a5c9287d5b95f9a4043e8ff5fc6997ebc80865cb4d094a2ba718631b909c14741ebae62fcd36a2258e99ec691696af2c8eebdb71e82e488eb857ee58f28ffc5e38f528d8c1a0a0992a10aa90fff14362c34db571dcdcbfd0ae97eccff02b92ef6af866415a323531adf657810bfcd0e3dd3cdfe344a22e9014c636de77dfc1467e2db72d932\n\nInput: aceabca849e574dc7f1e4ff0f4e029376131394f3f06047ed392c9f9673fa3bb1ffb657e069b5a85c5e25ecdc768a789b1cb9825edc9666fe7a9311e460bfc22885ad264e45868b12cfd8b666f20cbfb575cc84056545089e6a8ffd880d0abad34e3b6aa\nSHA3-256: b8ba283002afb7eac3f41487648ad04c2f8b34ab7c4dfc6e3c2cd761d8e3a41c\nSHA3-512: dade49fbed3939363a9895a4ff4da6975aaac658ee460d0d3cd59da156f7540a3167d853eaebd4736fc7df6ab2c3b03a27ffafded29423a977295b8fc747f5f3\nSHAKE-128: eac76b25aafeec4aa1b0f86e15483a3f66b00b343d639340f5ae69241c326d3d2920f7b797f4d866326ff9a897a1007b9f3e7a2ad5f8dc04ab38228bcdfeee24817d390842d66900ca47171e457c1a7dd5e2aa1c8d763276d40c0f4cfee04d30be5faad1c1ff6330dad9e1de1acff98c0a8d51eef9863392d34609f4735f6a47492116afbb94e9f4b63254a2f51143568952a7ce114d3e8f50ae09c4af8a8e02431ad0137706995d56f536765534eb4272075b66ff81ac98423344e117c6381eca7a86a3bf4cc35ba818ca4357dc44189e0c5b13eb57f036aae718d4db3bc30682b79f156171ca633aa995fdcbeea114d77273830a15aa08005acc4096b4718b349be94efa75b72e3f83157cda7da57f1ed3deab9dd8fb04d986ead497cf2452ca7226d96e852bafee99450f6b3395c567a23056a95d035c4a80c51efb48b3c661bd22413a01f9861b893050d16546abf0cf8fa3df35a83fff4406c70eb775b3e05bd9ff49f814edb97037776f173e04d1a44c403fe1a7d0e1e861465e9ba279ca15a2b87821a1ddd789e3c79a368971dbdb93b56ad3bf0b6df141ef21c16f66acb67c57980500aaa9c5222c5e1bf528ca81ea65b160b0abfb68af5d95baf955e296b97ac6ec1068764f6a2bbd715bd796d1819b40f357d943b2312beb41733d4ff2fd435e87d4315b75c9333d789b7e4de0f23d08f0ba6cfb39e8ecf53db952\nSHAKE-256: 7076e05eb3fed9216bdaa24cf872c16fe18091f334f24316224d10d23c079e2b9a4e0e2b06df19c24cebb7515b5dce134905309bdbc0d5344a3129205bffeb634061766976e5fb3a8f6c4299065eb9d5827894182f80f5c4e1d3310b186bc67dcbde13649f3874b2f0d2546eb273e3b90c26cb607e45a60a332d0896f519361611fd5ca03ddb696e774e7e93b9b93c2392045fd8dad6a05f5baba7717454ada1e2b91ed7efa2f8d41bcd6888ef23f4e0e8ea58ae1773345ea7fc659276bce91f3b57f5edf19316f02da5c9ca9f65650ff7467f83f08e0ed5c0954983279891172e0584a2d91459050b462a00face843afd5000e3333f252d1215b6f2da7d8837e43ce8dd755f91f2479bebfbf094f1f0c5e9c44887a1ee598282baa95a259df13c920487e334cd6124b5192e1bbc3d491c1f263158fa0f2bc031e804380af8b7b9d5556733719966bfd97e10d357455847ae83515a706866f0a941f96c8d889fa1d2788b9a81e8c1a49ee94fd54367b2914075a4ae848fa6f5882c5cbfcb1b1152f93b58e7a8ce6973e201c3cccbec40959835239938f4cc1a8d3231bbb2f697cab1096a4ade3061de1f5f4178a82ab5feb14965bb0cf1f5869460bd2960cf7fa48b137227c59c3f458e1307a9402888bed1b1176281bd7675e545b1e5d9eca4ee4e2065c3bc8a77abb094a423da90c6cb095431b8d0c596678650ffc7c86eb0\n\nInput: 2d3ade8ede8e46d0a93037c1317396b3d5e20d9e80f50ada4d21c5b8e16ce0382dbf57ba46d590621bc75f7e12b0e0045e45570daff572e904646d1b5e2f92eaeda264ee82301b01c43df23e73cec786f23c54ea66ea856455ba8c7ec4c1c31c30b4550d78\nSHA3-256: d30f9baeacd3c84595dd8882fcdabdbb348a682252372df9664fa26e8a5530c4\nSHA3-512: 039fcd70581bc7e28c8be280d617dcd553ab2bfc74f509393019f9cb07184a61e1f8f667299f8f0e83559629de6b73beb3e063e586140fcca2458498a8b2ff17\nSHAKE-128: 6d01aaa95321656f333010d53c3da6c194a6fae2e9f8d76f40522e87df2b6735dd7287b3a184b243bb617c8287cca01106dca5ee7d07d2ce60e19ef0bb6adf52ee9ecf953465714171726fc5d48d781b858d5215cd2dfa6eaf88b4806e511a565a2d4d29837a79c5f497a46ee89c5887f7f6bab3a0368fa13e3e2e4228f846159944c25150a97ff8801a3f3adf8377bc0a3ab9e9875c81a5e4959270921eb8bf6069ced5374f794bca1a84a5064659c9272731d8dbf3d016af2282c68d6bbe4fc33f3d9f220991a60bedb2033ab17334ebe5a9d817529c267d3f0fa846577d7334f2476f6744e4d737a0738e86f9eb1b8c9b2f9359365f2c39e19ffb6d700e77d1e3e11e62d4dc9739164854851b51d2550b68818667ba27df8642c597b13db50aeaa0f7fd8b331db099fc7a11f7007f32d0ebe62e0785a8db2a9c3fb041a543e3fe3a256eda487a07c9bf31e656c396f11b94952e9ca2a977971156905e3cf0f5a1245076649ec831f539eb601cdbabe79cc32e0660bfe988daba6a57cbe2c28f4ff3416762aa2f75c5d574c78d3948fbf05611cc89b022a391bb6257ec48841684f12362440da77269715472361706883b3243c5f85c140910bd72c4ea992472929994ef8bab2996f8c6255bbf0e154ae57d10fd678a8f1530e601c3d8cef1ff40ec8b8b0107c459d6ba9b21b65c1d129295897324733d4d1c7197717d0078\nSHAKE-256: 9fd1ae601c7184f305ab6f79ebdd570dc05202081b57ecd9be172b26f38cb7a22d68c13616f0cbb2db29b3205f69683bd2479b0b7b6c26303298463fcd545171b5b527df3a065852b6174d438f860f7daf9e7bd60ebc26b64c07d2c8f9b228abda53866a501311b6a1e477db5254f7af7d81d8d2a5e7f1eef61a49dd02af2e8537ecdb1bdc9e97a470ab99ddaf6c4c29c5c448eb4c60e611b7ce88fe944421767032f1c2c3b659db9641caab566a981c636b9324ad5a7c43828ed509ce33b9703f91cf96dfd9f71b9e95af981cc11e695450656c7be37534f47a1873b1112f10ba33e69794a4f51fef4ed4b8700fecaad48512b40f730f2f937728d23d96aa1ebb2f3b9c338e8373cc7822c382163d82402d95621d2d0ee35f479b3386d67717bafaf9efd95dbe53e1964626efbc0be48d771c3d53380ce36caa89bce4625d82e34bda0d2e929d08977996bb81a3ff204d3f16bbc81dde28b9528592b1b16ee0253347f2a9f539911821a3b2efad6dcdd8cede707d57cb1fb8a9f78bed7f3c602fd812d1f5bb8f555be8b0f4cabdef3f8f1704c20ce485f6e8acb6f2ca0f6ef5a95b08bf8ca68ace7b35739c7e215584902d8db632d1f731663a4ee9294d401c6b09e36860b3fe53e8a5b0f0c8abf76f19e8b334ee98d1677b94769553583d8487184a08d94bfbdf2d26eddda1bd89f02aca22571a049de363f23425f5d8b2bc\n\nInput: 2b500debb9773def6e8630658cf5bce6e083624ebd2c57e92e792e6cddda58e3b72662981d43d3e89585cb29f6daeb9d5ba45d486ed302be4dea9a2ccc82b641feb238164d3cd8a8d9bab40a9d2230d97fa13b88f67582ba5db2e077f54ec6634b9acf765bc5\nSHA3-256: ce68de7e53335162618dece848c9ca12b39a8402411398d0ba9f14f6d3d67638\nSHA3-512: 2e3cee24e11dfd59565454611cd66f74f97acc7c244246ee01189ff7e1b920ff57ac96cc865f8376643cad83a15763022a7e44d6ac3968f2342e15759bb52d4e\nSHAKE-128: 6f05b022adfd1ed3e3ec94c984eb8fb9a5aeb64c589031fd31171ed151f9272da60a819c136f63a16c619989850718729d1d194aee19e9ee01f2a35bdffc2203fce0a7130c14780614663815405292aab1f2a7144db63c4830b358d4a8004a3abff2cddba734bd920e742967072796cd6597d6e41b410ed613c95c5e10c751339b3100562b6a25e56a90c2e701de5a52d7a11329e4e8cdba0987ac13dc4008eb5dd31d90560bec2d608e14116576cac7096097b9aced88a804b2a68d133ec2b63ab71dc85791bc68168a852424504ae0d62dec581aaaad5e3cab0b90c05f9a7942b0084e4bac2731898e3ed07fe94ab5026c45cd7f3b6abc785056c8b02a3134dc49619b1cc0ff8f101c93e4b1e5608e2bf75f1158fd43c0e93f1e150fbdc3d854cf1081ac80040a2aa5395fbba7d09e61b7d5429d8b9f06a5d70fc47dfcfa55ecb417c7f91bce26af94b7bd81c56b10a68a015c62a66f5f9a847ee41a32556b99d5089fa0413176491363ad1236af6aa1bf8375e5986371c81318be58ab2dc120c6fe35311a705dd662ed27c5b1645c1ae53f48b99ba8b333d5fb28da97464ab028933d949c908c24840add50b3219fe0f8d872dc749d36f7bb98f302c32eba150ef88c0f963059db5f0018b87bbc097f1d", + "046d1a7c709f913fc177e8bba378e1617980c8fd53bfc69f0f4b37d18ea929c04a89430513634d3d3679b56e985f\nSHAKE-256: 39fbbbf06a348f021b53794e45ba06e342ea8a4a0c72ecb6077dbc095060e00f897aee0e1afa703018b4b5f4088c13498166f27aed3a4d7ea1bcb27d6eb3a04a1daa97bf264b85910aefeca9cb5308fe55fd3f47750f5b542c486ecff062ffa4cc724aa13073663270adccb589f6c42843a4e56e1877a6413e7cc916e34fc3af89df0f712d1da220fc28c07a36dca87f27c8ecf3a43bd136f8c87579a50d2c7719c1ced8a6e4219c081773dce4380a246b7ba74ab725d16343de9c221927d3a980795a40dcc12ecdef19d6311c23192409714512385987fb5619eff76de1c98dc0dff0259807211a913303ac8a6644a5884683e210b7cdbc94df9125459a1664fce38b3bc394e4f5ce0bc2e282ed9c3606ab4f723b2554a2c7dd62cdcf5ee90347929665eb56b1ac55d81d813cd5f4e618d1b4b0739d72d85b9eeca8824ee3a6e9f1c399076b2f1088b9a76e82823fc900fc78fc13e4b78db431528d83e06fc3f7e603461faee335d430b884b87afbe87df8debe24a86fb5e1a8a39be98c448e545042758a52d4d02f65a7bc48a3059caf4c943583fe65166b36bee735673b6872081a319e214c27995b30e63c460f973f3d41a9446158559802855f4c95783034f878ef135685b4f1c9032f88481e88f80e4b0a291e78c43b084560392286230f356e17f0ab85625836e72f2b037ae545ca6fcbbd9e8c607c5cca88c8ba9083\n\nInput: 3796254e39b006b8f145485c6eab86dc8f7d1fce265de0e12d9a96e9b0559727dbbd7af9385826bb5f1476e94222dc748c41657991def02c03e37a5eef35059bf7aa3f430ca31730951eed529e9c78c7f5b2274993bb03ca5b2ac23ef64c121dd6c7e3110a6dcb\nSHA3-256: ccef493e344639a7bbb18a9b96c54cd1582d19f6053e03967433321350499023\nSHA3-512: 672a2619db96f5d981c203ff2018dfd520980cf4aa25827e0181d8e7c85cdbff5b38a9645157a5f55e77e9647499aec9d1fb3be42476df1a43a18e4d69b9a98d\nSHAKE-128: a8ff0db1daf2286ca2d4a71b282706778e4eafb78fafe6602e646535a5e1716f387e0d343887e1bbd37faf64d51c8586109aad3b193c463d72cad15dd8e791737397848a9909b6c5dc8f0dec4b41e2d72388c631d9065881716aee90168bd362fa239e231663691ad8a46b40f71c964bd544d14d21121c562e7a47854f5e1e445ce8f340ec485b756fe7239f4f83a8c744c4e9ff9a2931d1cac5da592b9f78f0c475735a7e6cbb3150640f7589be14fa0070b759528af35572097d0bb9a533ac1409345e183ac38ce3c67bb6fe42a76fa97469c51d2be07dc5918ab6b5ad266dc41533b42c8f5672d4d1c6773b735875ae0b9c959e6c5f2bf1d21aa97e0f6289774b9ec850ce6697546dc377800222e12302c48f44b41af1f873ea9fe448db49c9e7febcc346c4b503b03f6485f1ec805a2a7d529ffcedc7bcfeac51b019f2c7e319fee026df03b56d0a80d9fd88959dfd6b4929bce8222483040ad6ead3e05a7e00d45c8b58963ad8b62ecf768468601745fc036826c6a8d234bba05a8a5959ee8b0f9fc814f285e2c0f3bd6c76018cae094093de2a935f906b39fa92849e73711eb7b3d13ab9dd50e12a00f45fe3e3833900a2d66971b0fe9d5905dce8a729948f5192352a4afbacb234c397bff37a42545c92a8c4d2ea3cb8ffa5cc8b1480dfb3c77912189ce7d3d670d9a08f564cb27b04e7c46ef6429466c7f25ae7239e\nSHAKE-256: d8c48bbcff9cd9b879a760faac34a4f0d8bf98273230d3d4a6f3adfd0554fe0c4e1f5781eb8b6a52af20050faeac182254765dbdb1cb0f493a4e688c0680c0c5dc66ef69c3ad9e72f21d853b070eb3be71fd499c89970d108b9ac7f7e47463125e63b6300b743dd8426d37008a641f94fb898991a3d06c97570c73615dd25ff3a5680d4f3605361ef50f9a8ab504e6268e055026d776020ccf50f735bdee32db1887599eb547a8829a670bcc891deed3605d6713be02273c2a1a34bebbb9137c1e6284aa254ba66219d8450d5307428c1b76da16533c1fba2d5b71af072c54ead8f4f48401bba1c6409a400c49606cd155273fa07deccfe9dc73c5d129730457ddfb2f1de4106b86991329e3c830471193b826ce73d726b8559b366fca520702831141c313f8b07a9c1a140a4e86e32f472c8ba558840bcd4ef8a4d9ad2760e3af0f046273fbfd435f86aa1984a51c6f40852bf567ecb06724ffdd1ff8e0535d290ec7d77696ca709c2a4c58d471e51706c7f452fb2f03ede2d24201da6f227521ed00c3efb8375b3e7118b90daf3a7c2ce3d99d64aaef411ff2f5e3c9e6511688f28f077ec66f42ae16032f95bc0b1cc2ec6186e8686c9459570cac293c9f5b92f9b4e0a5d90e07ecd1938425aa32d4d720f83c23fcc6364be8a8f1eb44cf3f30e6edace8a69983db2142003fd403c49950aa1fc07eeee52b38f70d9a0c63af\n\nInput: 9854203fdf1e91287fa6b1465b82af9a6daeeb5516f82a803e23d36d79719a5a8614f33e81b4cf1f9a9d3e5713f0d968ffe265e2fb9b752f7a05225de65e024c02dab90016264e4a469ab7c1f756ea4913f6111967a96893868f8e735873262230b50f31b1da2fca\nSHA3-256: 8a45686fb32b04a1f6fd09c31e58ffdc5abcd41c2476455d5be69f5fd8ee28c2\nSHA3-512: 161bed160157af792723b9f90b967267817a441652a6b76835f10e368d24c7c0430698d005ad36640a9ae20f6f2732e2fd64ff79f62475b846b9281234d90216\nSHAKE-128: 0e2a5b8360b72d91874fbc24d859862e6284e9aa14ff4900bea7395374d9f44bf0cc911b70e790f6b56fa655cda322ab597d6eb3b979f5d6ee0261b5258e1614743a7b03fa191606a46deb808e409af4d28cd83942bc205731eaf142745147e0f635ba96f2e474b8d9953f5d3436ef990cd1c232cb61442e70f69c52b9f276c626ed4266580b6fba58c1367a261479b824dbdb5f6b4fca2bd72d26eec88aa95d911d4592220957c5dd66089ef38f0d7eee8f05a303ccf0c5ef338f28e6c636f295e8c1fd24464a7e13a07625c80a273e775081ba83f915f1fb29b8dd059ef0b64a68a3572bb8900620aebba597860de1dcac422b7c1b0de78e8c7329bd8fe492ed1a4fed87d2728a9302a8a9647457c958742aebd260732fc276db35c93da4ef9024136b5fd71b026b82dcfafd595ee177e365ab87842143f0c60a7b43e18a1010fd109a59c44a82738739fc07559bc04702a06871f059a67bbb875bbd815ac66077ef09554d26ea1a7c9ab01fe38a869741af50a3913020d847dc7e9c5406b94c72237eb7a39982181faaf943221ef3a849c5f17e405db99dc3c0d16a416b9c5f30724aa729e8b218154cddbfba6d71ca289f0d7f528f80c8956f4fb755fd0c7c7de3f0dbab93f734c24a2d03049384b0dd86a03b621f8b2888d1d09c64954a57402feae878f2834a9d9a7b1d3314c093a9c3608a87bb06e5c01024d1bee245\nSHAKE-256: 13fd2bd3831dc5e56150c22abf9d3fe878d0eae8e3e4c5918e22942a10a5c4f1e4a79ec16759b705f93e39f9020c967d9c42cc5b4a719d95296e434af9965017bbd37f4ac00b46f58e1dd82223304ad6096a1be820b10d564ecfebe0a039c311be195d101f1e5f50b2f884d96bd0b0e074114d687c1f6eba9d2c23d4000a7a36dc9055d034ac9b9b952db014c2304d34c4e5eed0441a14ec47aeec036a0f9d9be2c3f7047913b02ca96f544bee0c06b88b5fe88e4a07e4e4d6085791814f27c8c6f3012ce979a550fecfc385ab851a7b174c57252ddafacf9581ef65d94e6e9e61306f8c94a30ced1b4743b65f2c34426a2eb6476bc2931d0c103c42497b3fb126ce1c68b9d2847c458c1ca3b81960656b6af23b737bdff65d8c3ba676ea5768a70285e2d6f9252bbcc1a1c66bc3905d3e3bd0362b66f4038fbbdf4a46425892680ef7d0516ad3740e4c466888776a6e4b55dedcfe149cc6c4eb752523e48ebe31bef009950e4359fcef09eb09943e93d50d979132d01dc75e14bd5cacff151bf5807433dda091eaba9c17aa3d59f3a73bae7c0c5a9a593fc3de7f0ea91e183f3777b1cc7f2abd1e7a1420c7455798001949b400a7b0b8716e09af409d141d9d0c072fab691e51b85d9aec9fc3b7afda0fd967142a53f6bad08808eda66d18305e6acb95fcf765a2077908e5ea96907f765c6ed2a01abf4747f699a58ee90e2e\n\nInput: 1efa493b8e796bdd65499d7370055a43d7db9ce58ba8daa2f52996d1c3c3e3a05dbcc92a22951efa55f8fdcb6e1d18741655afcdf01479aa916afeaf7bdc524b71c1432fa9ca52c5ee9015df22b66361d7040f6b13e6a661a1412f78ce19d3d5790959719ebcbc8282\nSHA3-256: 4a34eb30231583f43df135804e8b608bbec0d176107d2ac70956def41bf23c3f\nSHA3-512: 119bfa6f5daf2bf4692fb589bd500ed45caddf61ac6a509531f91182d2e6fddf60719cc42697f8b458921f8bf9679164b38d17a7262e9368e34afec1d6ea0b7a\nSHAKE-128: 098319c0b9cf7e28b4ff3e9a8813b7bfb894342a0a009e84a3c4831f8cc355fb6fde6098d87c568d98e9b2dd41ee337355e256486ab8c3787d779c869ff2efb33206e92acb4ab495d32c6de7d2b1405424d545a47d75f51a7f3d87bf9ea02dde951e0c12f744e2ff8eff0ec76409be1fb06430a5ddc1c11e7a7cab53be97340e4fa4314d353f2de2c89d92902b96a1790e15ef3c3ecd982ed05b9206273c3fd57f60d764365fcb7c0bf106f8ced9093fe22ba68481ec1c4e8baef6f2d9e512f118dd53cac79206b6befa44ff641c1b3d5c899adba20174683df618a657390e8b8673b87518e906d48341d09b61c36d6b6ec2f8b904d04b6d093e33a2d015fe6de2476409ed24f6a25816f350002a2e5521fbf28db49bc8f916fd815516878bfd1ea86e093eb0663b5aebb2662824ba518c4bdcefd06404a2c4eee4d7c898e2c1b8201ec451fb1adaf9514d01766e354448efab62fc45bcf8635a1d26ab30309850834afc1f35cf2aabc9da6168c9a6475c0456a3b961810e0af5de0844a6b47d3ce3e43f29253b381c66727fd4f197ca81641bce4ab117e70447fba451712122dee5596b7eaf4c78e681ba2d6bb430f8daeaabcad8828c5b2aa33a609e7d7a2aa9fc877a3f73ee5eaac5c782e4dd843564104829926e9d85d9436d404280309a573b2ddb544f8c0bcf1c8db74a0bd97b63875edfa466eee1d51e3610884add09\nSHAKE-256: f7ac227aff5175fe81a618865470e23df0cf2647a6470063bec560a35ef7dbfb148b334ce66bfb937323f8a1bd9184861995bad2e8e765e9f74b8b3340001ed642a1de5073bbfd804b3dcf3f4757ec1dcfb7696c85a4056424c2d0807a64afa0156a5c2616170209b9e834d30064687e84e48213d4f1bc139f750f7090023a72c72b7c7b3e422e597f939ab88538ba327ed5b3a876ba4dced9e167d4d0032ac70717d080d0be9beba150f11299ace18a2f2508418e3db60f61cd52fe810b15b6b6d9fe7e1ef514ed6a8eba6edd21a7616c52696f44b42c6c3fb09ade21bfae012d152038db1b8c345e4d592fb5fed8f406ee83af132c432e2839bad3152cbad99d981e39b9a6f74f801e990831a24a17b4cd61e775a40a03e021049cfee457aade3", + "e415431d3d50a5b828844edc75b827dc8aba7cf4d8b9054b26694fce640bc4a3a1741944decd9ff54bdaf0c49394498b7ef61ee5a8d5d6afc28d203f9e5989bd6d12b7907f21cbe08611e96622e9e2aea5d88c8d64792f95535c35fc4d4b26050908534a6f4d9e77368265ba49585f63598be0d65694f446aea374cac499f8bff1a88ab7e967a5748c68b4947178e1192912cd05cfd754512d295ba304e3aa31e18df690331c3ba6dc80fedb7de3cd7705a25a8f7c4d2830846441d49a2e29369f0969947d056b7062dc5722744a4077d423f96df850eae2adb06fa96ab42\n\nInput: 0423487a1c6ebc37b35693aa1973c0d1d468b67159b0cd1e63e8198fb6d2e49d46d176f1339b89de7d248cac92d492cc35d60ad688694c35103814173f87607b5a3b2c7a852b278930ad212e3041f390945f1c234dc5ffe7d6bf10cc909306a12fa4f687494d84498061\nSHA3-256: a11fdb3fb398aa719b28a4772636499e7f68566c61cc99fa3f277c86900cb671\nSHA3-512: 9e45ba286c4f7fcb2ddbdc4ea62a417b7f6138351e3495066904f7974ed5b838494dd18e360beefb8958d52c9d7e2683905c059d22e6e491a35c74afb2241039\nSHAKE-128: 7231145e7a185e939116b05c0ac37d227d52b93ad91e08cebd311ea124fe3f4ca54c0fd88411259782886dc3cb5d7f99fa5477c60a8eb91f5402d45bc27bbe394749fc3d44d76e329b0bfcd8b8317a8a2e718efdb6319c39d15a8c24837b897d47675c770c5330d1e2a99a3895c30755a786bae9d6ad7646cdd440d3caf3861335751fada2a2eef029405d498f0d3bc338b85c8b1f90369e307c425ba95eee382ca536f95dac0c6cb3bdca535246815a9a47fe471435b51c885d46b92a91beda6502e30e3a6168519d7c1c14638f182b5d3daf46946cb6fce6425e9db15da3bd2826a3c892a8b7934a5c4d3d17267f6480387f076d5ee34ed541e47bdac288b1775c41c44e20d10b1eaec27b0d17d1706b40197df58053a6ca3109954a32b6daefb3c4180e2b0d95bb2d662099381b76c7a83b212bbd9b09e45dc51a7665dfa90512f1f3a01b728c7e8815c8b1dc85938271671034cd530961dd64b2380c99f52c40609f76135d1eb974e59b5379bd8753a0f16adc6b95ba6a953d7dc32ccf7c66b40680f6634c7e89161de3142b40353f9b81668d8a497e89af52bc580e7bfd72639d032db83ec834e3b5830cfa927a74b0dc252e616d7674f3fd6060ab12d6145f045751a570e65d49b2a8dcc26f4de91bee9aa74adc502b4e164992a4108a615ec8675e1d955a67466c798b88f723a833334b3ad52dcdc11d115d2b386f93\nSHAKE-256: b90f6a48d415f59e6e345c6f2e48eafc0a57b99a718e88f7c8886c2f4c3b897152b62407ca1ba800e35dc09f78112af6c743416f21eabb87fb2f125560fccc51ca0ffaeae6eb07e1ef8fe2dbecb92c1a9044c4da93156ca899f906c9fe49de57467aa6c150f81f32dd12f2a9f133381129d71e6215dd934842743f1a4401d8b8d4010071fa1dcfe0330607ed0f9952f039c6f85fb8df19cec65a6b322b4bde1508eaa36c313edcc651ee0c0891a30dc5a3490bf47a2b9e327b09f4172eb2c506d9dba0a06131da2f3697c5be3c0e35479b4e758c654bcfc95944978df3804b79270b7f2df463604aea17dd63917303e1e25f9bff1a6ad91098d70e32066280ea6d8cd356dc2d4e4ebaf37e1645b3703db566e96b21b2e6a4de4751775da7fce721f81d167f2ecaa801c3f6fffc4b9dcc8eaef5cf4698a7da81e0c8deb2f90824be5407d21f4e6574f682f6e6fe3f75c9ce970e900ebb9c6bc166179a8c805b4ee6bfb6c9d18998df3014ae54c0f4abab6bb7191e44c9048fa65d012235c377630423ea23d3398966fa2ef6cb0157cf9e72b248dd570b08baebf64776125ba200d3d664d4e0f3e7bd917c8a95d5d7d8776e215364f88fb05d3d434d4794a9f0fb2e3beb158789a992b333201dc519fb030eeeb4d9724a43e9bb2ea6f38c3d89633112e03e85081a69dca1d12f72fb364098fbf65d8ad5ee52a3b4033b61654749\n\nInput: b82e4b246a92bc8a006460be8c81bcdcbacf89438c22eb0f487ba5b713a9fd245bd5427bb518faa7aa9dc8f62d8b54d1c6a075f374da48e80d7ec6bed3a4c721276c0ab5fcfb42b4a0589d774860e3b38aab3ede08eb1a3fd177641f94e3649db2849bee1146f7978d73de\nSHA3-256: 6e7a51d6aabfb589ae14085034b3cab302610a022497f3a197acaec8ae8e40e9\nSHA3-512: 08ffe79f8e857f8b5697f7b2e888649d40af50d6f997261131f1290c402316bd4db237f2a34ac6942526500d67fc172815213bbd09011246e8d57d8cbbb7fa82\nSHAKE-128: f45a5af7bcfcdc4f9f68092b2490bd7343af97802ad29e38c8400c89a1136087befc59831bc934e20258e0fedbbd002ead105bcdf5c2636c30c021ae9b7d16fbc9c7061b537f71ece7276eedd0188e94c8afdad4a3d21e7d7226cf43ab3fd71b638096806dbe8485a550c9b5e706812a664fb99902b14a2b5c63b4b6f06cd87a714c322fe4b98cc9cdac5ee618e71333c0c1ad0612c97898280d3bd553552673e8c46b2920523e744c3c424b18ef0a52f7f24f21ded1809fdcd4a00ebe82d5482a76e8d39e335102ffba14df3124da4d03dadfc96c2d3a1328e366d81bac271e1b744a40b7d5f56bb5ab370496f86c172190135230c8429b853d671a47ce45909f7c3073ee2878fdf24682fa3cbfd06d35b408197dc35fb80057b4cf19f013df8a6f2bfeb5c3add696c64fe46148948ae15296f403aa7378f59308dd40884c44c3bf59a7f3462f66f81d871bdc34f74000bb431a5d080f834c8d9d6a7551a4744be571aaab8b3d90709c7314b56d99b592cf768ef0fafd1a01d5900b1b84c19fa22dd1afdc7a3c93f62fe673d06b36d91ab2eeeadb65f7baaaa1b8c88686ab97da197d07cca731801702386624e1ddb56c1824f362c5f31416722d62d78e3ab7e07b763cde2ec79b882af79cf1f5759e9498655a53a930368d33314d041a1c1052560c049eafffa0bd92f9679bc582bc30b6038addaef5856e6dfbb1534457c7\nSHAKE-256: 57f734a9515111f93a6899c592147ca3b4c0296683f2d7491a7b7e6469dfef514ac2b850221f39e6dbbd1b659f63f6b88d8f861759c078a76c3fbe07545f6eb52ba104940e6c8390f2afe61a0c2081330520d8433ca01213ab214309316418e2955a25c0f261fea74950492fbe0e0a33b4c3a29e978004d5d36adbe0ada5eb5ecbaa2ba7d4c8101e95a1fe38152e8ae3d4d5dd3ae671a6fcae3c0d8d963ac873134c2c963d29eed8a905cf1839e81392225a9ef129c29130f0eca8c3307b39baa8a7440b094bfa564db3ffc641fbfc69cfade4fc0f9b24396cfe25d73163706027cbcfb7644147f699d066d2b2355c79a38eb462e335812f25fafd573165d41c4e90a65e6e7b09ecf6aa747b5f951fd7c26d2a929ab03d7a130c1f94a5284935c700c47f805a15ce73340f14d67cb482ba7b1a9807648bc8593b656029fe92ebb909dae644130419a4871efe4dff16202710b46f84a398be958e519d6c0d14235df767c1e8bbce7d279d1160cfe3f03f9b8b262bd28e67a1f62d9b851330a53f45822cff6ce31489f5331a6f61885e3212b29450fc7b47270b352a6582501f0b54a27fa1e99aba84c4cc5a3f16b22482c9d94f53f96086ee6768441d633104b4390e80412144358941da7ac76a5cdc1380d4b6c39b2c65aafc1005f70e7dbc950e5909d003e07184199798882127d02a6b30ca09f407e5ab4319b4f5095452fd\n\nInput: d4849bd34af6a40f6fe6a2c87e061a83dbe0ce7161f3cbae54b36c6b9784ad4fc5fa563269004afb8fd2ed90dea412fc4408db95a69618a743f5946f1249c2136f3ad2c28e6264230b977db7596cc0ea370dcf68956630fccc000b8fb6c90d56966b5d6a9a158fa8fe8053a3\nSHA3-256: d21bc9790be2ffc87e21a0fec1208e1ff3c8fbd67ee73928065b6f95d1796880\nSHA3-512: 99b6a1ba0dcdfa414a72bee0d28a4af672b80db2a88580082b37ce834b5ce59d2babfd3a534cd09ad8ff130643d926f1cb1c188dab8b356c50c643e5359fed5b\nSHAKE-128: 100e253944a90ff4774a36793d56449ed3579907703057cbede51c7d5f9c2c2ed992ba48062e01311e438a16d9726bd2e15839a73ad256c0e946710414e56b15652f6c37ac713bcced6bacf8ea6696a970af87c7a3edcca7cfddf280b5b5c5eb1c67ab09d74f1a3c88db5d757d72d514eb22dbfe889fcba1acc3963d178d8a60f513d59d009e09c5a6bae0797ec88a3d2f8db5ebcb94c364bc42986785d16a884f2db799f165c9813b133ee268bac2c2c1ae57badee159f531a4f0da3de0a7e2c4abc5a28add8abbae954ccf81ab2c00cc355d82f9f1db23ef81b7fcae12263a2c919bb1060df6af0380a6c9bc52ab82eae9e5d9dfdccc0ba43dd65ea0e2755e9ded68069111c9993bcca5c335d51cd749e72d4ba253abc934c6b6e92fcee3be011257d8d13efb2acd8ee91408ab1ebc67e92205d42271d39cddc90efc174c53e3665982b397fb5ed2c9ef162f96570138f9bc842c8bdd2bef7684c951e17da796b4d7054faefd434a8c36d755ab7bda6a76382692497b6830e1a09d7ac58595bed3d2ebdc309a4804136737d2e28b45ca873e6312b743cb53cb582a010a83fa0ea5746cfa2de108f0551e452a314f1f990e72963ad7af7a89c968499922f0a3565019960f70c801e2cebce759a7adff9874c00c244a890cf25288f0408d19f13c8567570ccc46e4563091af49c17fe499efd8e47987f0d3d015d2d6bbe74341\nSHAKE-256: d67d044ab331603c8dd6368e6bb6a24d48137c4b4badcdb52071c6701ea076b3ee326f10379abc0785d7703b618c45ebba0cffe0c259a403c058799ac908ab45c3c7bdbf9de83db39173c894f23800ae22777be6fe1ddea721f5271f7bbf3653a2828fee3e63e34779dd9a1ae96bd24fbef798e1452099d2d520faf56b16db50dc06cfaa2e6678b2492d6c238408f7b7bfa55485fb595778b481ca5bb5e75ecc0a51b44916eb67e02272d023d4aa463eff068d39ee2b14181aced2aa71fa73d90a0c398054b6231c196baa6b16f5effb0cc9e628d3c963d42235cbd0abc38c10f97d4e4fc6c6f5a014ac98a07f5806b5749c7981bf85b67b1e04b6f197a8e40a245977d1e6842483a97e5af4a959b29157187834a6e0884ab37e40a074731f535e642702edef14a060a2eca68f84d2ef4133c8fb2d58008c2d201f353fdba1cedae6bcdae64b4c84555b9a8160e8c7c69bc81590317b8a90114ae1161ff91b4313172983fb9c9cc4e38df0d5f86e2858482e17cfdd612fbe684194fae79e600e0c6a5e5f86c993d86d9fa51b660dee83f522496e55e00228158c4491e8eecca856bb49f52e27e1147de571ea1b3d036166145b695081a4e16d0d48b6952e9ed04553e8977706355c307388adac0b247428c4ce66c56733e8cd5013e0ad02cbe4d76fec481ee8cca0d72d84f4f6ed1c499004036f5cc0ad594feedb4e4d22017a\n\nInput: 2f481cc5401fcf621a235530b48e2537817f318c3a6e0cd51ecef080ed853c4f16b6c9e1ad7d21ad27d2c82f70cd638b734f6aab33607d2b23045787a4a0e0ff256c5482641bd2469d1a6ca45f05eeff1571fb86d8abe0e356104169219d5caa38043fda057643c01f9", + "0f73986\nSHA3-256: 45cc7520aa2e4602b71674011df3623d24c85f0ac5a28aad444abb7c7401dce5\nSHA3-512: 3fcdddfa31609acc73907b03fb0a779ae4f0b6e7ee50555d6969c9ebf0a0d4db90d5178f4ad26c342fa6c75a7a8f59326aa847f556238ec3183b9d5adf847baf\nSHAKE-128: 52a98f5599003819cf76a1c08168db76134dd914d688df2c1f2f1e006aeb1730cd022dd7ed1d7aadc7a850d557f9a1e6b334f6bf79141339c993ffcf0f0ec9d3f4886cca6b372cedcf76f2c3b2a13f4bb19abb85b8589d104712670564ded4b866e3290b13ea5e7d68035b9cc7836c0bf28111c84db799ecaf9c5c5ac7f5270f72ae59737e72bb04d894f2ac37a3f017b148fd9ac1d43ccbcb6de0aa75c356247b11b07ddae10977190a66a49cb0b5dee5cd9c2726e86b86b00fde6eaaece0b5e9be1628747b7857c3da602f67fd0bdfb9c796efd68df839423e19739c46b66c05e9fb15338e664226c6d11036a02d43fce9e98e42fa544933a7d28a47343221dfe3c2e099e6180f18f1ea23c28554e02e2d88343de89216f14065e5118276fe13ea79cf5ce0f35ab8b891aa27665324e8a5a47aa64c9fa4ef82669f4ae4b3b987543267532f7bf54ac3df767c380101272b9c8dbbe1d74dcd4a0889d9b154cc67fb7fab41016a4c3610b1f366f68efc69a97ce8824b42b9b57053fec6a939f83fa82fd9b5fabb9ed59eaef64b8ad4711d5eff7841d40efd563f56cb4938476e82dd78b7231660c77d140bfab6b574cd7bb8500cf534b227bdb487afa97d9a15183679d23a897a609004560be5f91dfe7a538d8ead173eb8727916fe4a19b1a4368217047b4e58b0a77259363910295f2072168669bcb4ff392fb01ec7e41557\nSHAKE-256: da1e92fa8f5a02a0f584bb49e3ec81d2ede70425f4235d97d242f99669b7d151a378a294752764aea96adddb50a782a00713bfe0111e1536e0ce9d8398dff672d58106b567207f68fd9cdb7a1767d48e26e9ecc1b017a0023eb933ce2506651f092863948eb07f48dc370f993937ccc9aabc07ad0e1d9d76e7333d0da7e676a49171ac4721fd2b7e7499bbbd0cf3bec0ee7e49a3e3348641f517b46877361b0d01a7300fb62914863f2262f0e32b92c3bfd09970fe4fbf82c90ac84e250844835805582475c99c1cf48ba667e647df79f36b5ad7bd5f11fd74e3441512b641a8811bacba142fc6b0c0bf98fb68719d9e3e4af0cf1e4328a30db6bd1d60ab4b821b320dbfb20eaac7816d49a88dfa7a831abd685e145982666d6b0b6d6ada4f4e39fc010f3a26118ca1e74caf7048086b15586a0b2c1ce5f8078d16e92e3230f469a6bfad539fc768031d44fd39c2563e9a8f8f864a57ce3b489e141e9da44386e6e467bae2a20e58079b93a7694ae40e1c62aa5ad8cc451a0a483956d13ca63dcabde110e7444a46a3963db9ad6bfb138262311641a27d8d8df3fcd0afe87406f4dc954cbb471fad46f4bcd8bbb933fc222fb1b6de90c8b9c8ce6c444922e9dbdd58a839f029e53bb815d31bb5bf4ea0abfbaee5d1daba0b3c71b1beb429e41a1ed9505d9a2730d0e42bc89b20651f7d3fd53af5a6c18b23e3d82ec09e07be7e\n\nInput: 64645da0fc47a27ea0a695ba67645df97a07742693abb78844578d4afecd64c12afbb69d6b213b48c4c3eff956067ecfba0a7943e32d2158ddbfdbd1d40c36c84d9ff3e171c1f64173be3e8e7d96619f18d0846cd76bfb6ff4719f19c4281b006eea5b437f091c9d0409f9317987\nSHA3-256: d3f0761f7bce557c2107e4ae9565059038466fc5c3e918f46875f948e824a561\nSHA3-512: 706ad421a96edc398388500010406c41383e70fdf72f434eb2b96b8ed5f30d5c210484e2a4dd8899d0e4a59d8176e47e21c2a8b04c21f54be16e06f963fd7300\nSHAKE-128: f01d3b339b9b8a15feb2fb1c127fe3bad0d602fffd73d0a64f3a23a7e19b3c3d20557ccff0721bb371b02d4084d2d40020b225e7ebd47bc24786c0efe725be81ef66b7f8c80b14eb3cc053567963d32899cb7dc029801cdbafad4451762a97173c6198891e1774da25e107d26dfeabc2780ad2ffcec3c26eecbbf6c9f362fa278e838f047baeea8033f2301df07c7ea2cfc732095f40c443c6d78cc98141eb62004cb006e607ccaeb14d4a77d25ebff37930d77193483e192e82e016a05b101039c4dc2cc49f18da1a6fbd0e8363369fc2cadeae1a565dd4ca56ec97611419a53b1018652080e335e279f5217c7dde527e16f6b22146f66bbb15037ac8d443d84f510af587e1c77dd48ec39395c730620bb60c44d9ca05e7c261ec1d58c2114edc5998eed54d3aad7527c8667f0bbe1f6bb7b27549591ec1b62f5394f06c5f582f4b55fde5ef705aefb200015c927da27403b6eb9e70d86555433e858539331fd72df83653fd84e8029ac263fbb2acaf5f0f833f9720d899d04cf5cdf25724013f48efcebeb7c7ec2dfb8db280dcfb1c125f429bcf4296e2572334d74b85db72417e5297edf0122cfc1c6c239e2398bb87195cbf1410ad09e0fa9593b08e7b10aa4e09c7e6f3825ccd1833a7ca550949e8eff9e01fac657e7e5e5e84c3f0ba569a010c4b5eb44d2f6b31a94197e2162b6698b4ada8f02072d925080c5c8934fd\nSHAKE-256: 90fa125f0e327ae38b97463bf631909d5ca60a0de33fa65a8033822678d674091e38201c0ca732ee29c319b6ab2fd5173ab8ae36f57a98eef5a70497cb013a373854c5bd66299c21e0823fff4b274b868333b0b19eede58995afb9af478819d8dfcf48b06bfc2e1a315d91d2839d00eca22c0415438f89211c68ef710009eb2ef6b15c02c8e40e410183cb5177673746bd6408181ae12c2a5192b6c8163895bbc87b3ea0d4a7292df28e6e40a14c6ffd97dfa38c01511e1dd11e5ba816c2806f870477b73fb13e965a768865501ab6c7ce29c2a0b971ff1ade63277bbae3c489080d209022ff5a528d393905b45688b42e693a91788b109e13e19e85d16e801f356103e012fa5e2a13e40963215510599191573f38426427fc455d6bb123f79f7569e2933be29ed870ae0ecd39a35629baaede711bc81bb6f520455f22ea0bd16e016326c67e01fcd92897d0e685a6798f9da022c4e678011ad755a4b3b4cc0f6839a27f03df00cdedfb77532a77ac7f6690c6bc8091f4bc1e46079290bf2f94691e234a65dc9802dd6ffc9158c3326973410faae1d972d3337a0e4ff292642ae78c0ff1d9394914db65789545e582039cd232adbba74e829c95baf0300b2225c134492382efd4537b6c98382c0f123be28e249f81426513bf2c4b2aeb3541b620f6b8e8f8817e961442aef8fc820d89355cad04cc50d36aebcaacf646ae6cb4\n\nInput: ca602596e85c8d1cb7fc37de34daa9cd0f6692afecfc25fde42a9230dc8e7e09da2f5da0db9eb2642f8ab42a2a69750f3890b4726d5a6a482e9aad1ad0301276eff7938524bf15d94e9d2d115e259edff2df1f208e3aee6f8e7548651dfcf52d3f71601e1ad7e8be6f758bef48bbee\nSHA3-256: 533c392b55f81ffdee01b29a608866c60d9e083f817c9e14e85db645c1c82891\nSHA3-512: a084593f7c82b3bb74c18075eeb0304244476b5ea714083f1cf906734f200680bff3fae2de3d6b4e41c4eb18846291f806a7226071d276b8fb528d3b887fb8d7\nSHAKE-128: 8446eddfa873a874cb06a0b50a2afbe14a3212b1418b7266e096b7112de36511f898b71f8b21ba908c1923cb7279c7c9be1e3655aa51d73d2a0a0350e7ed50cff4cd002049c95e2205b65d4875d22d73eda85b15be2dc995d581ba8f1d3eb8a57cac8ed8ba30d9a358d380ae19424c0201a4462f9c38142cee3ea89f0850686cda85548c16a882bf965a64ac02ed6240b89225bfdf2a34954763d9146ce739f71f142b2fc1fab44bc3f859d3ce5e732f171a73993392b96ff4ba7f2900407b36a3ff0070a9d96c5d038b0f8b569ac913ba4e43f409c97ad7bc54b134eb6310656233df77dbac87215afca1b8fd1019e3efe04d3e2d77ac7c9669a1e75a406911d1549acbef941c505021340050fbedc21a5ac646bb378ae6eeae4293a6a742b33ce00cbb522acee956f6c7a9037a468a3830808b29ebe6118b39b690f6a643a80a296e45690cdb7aa5f91d7e7a061d2f0ba74b935c9b6fbe2dd958569b799d7ca1234bbb6f3a58d87bfdedc6b81f18698545072baacda7d58b88ae5d10cc478e53b56e6688aa449390a2f01fa56d25e0885127fd36a15d0d4a69073dcea53de893cdd4719378cd11b7ab410c7371fcc030e23f633829ee8abc3bf274264f79419696a4f85ee3fb58b2d6d3fa59bae3831d0bada3d1e9ec05010cd83c5e8a31f15da227f5cefecb795513c27a4693bba493bbd6ea3f44d3e736adb1486d4637f1\nSHAKE-256: b341658bd64d77ded0c1dc505522c1724827bc143879641d86db3459448d425a7297cfa5769f6036b55e6a30f70cdf98d9748ec7280316f3c51820541838b142faf7f5e7b90a32fa0e7b264340bdeee65dff90032f5342c9392c20984be2c2c1da6f30e760dbebd83b462624cb76105f56ef3eaa74d75b0fb2257c65c982529212d8a106c9c73b5a553066cfe7fd79723587a9762c6f79f0852268f7a84926d0d880477ca8a877ce137636971a92284ac78acfcf8215c2466bd178fb2c0fa1d5c0d68687022b2542696c8a5eb7fb11c8febdae45259f773fca8ba0829a7fed77ac2a6dda4c6364edc61d5ac740dbf6708f34da81e057570945e170b482c94fde4d7b2b77d3d17a2a5eef40075ef918fd31131f49e4b2cc2306ec2ba046d2f9f35b1145c6e87a0228dd19586b5b67d157797392d2e2da13330018ceb48a9e934908d0fd8dde84a272ba26349540dd449c08e610c8e30213a53d6094e3512f157ea24dd3233bd43a8bfaaf331f17d825f633432976fe77b050371c371e96211951807c6b01fc190e81c7c1cdcaf528cafdb6abd92a0c45f186f587adfb14acdfab8ffc4af2f16943f92317e44e0f6f018661c1e55e2032c36b93811b5fc7fe78dcb49078d23c217e0643e5e26626105fa9efce6cbe76fd8e143520560e43a131d215f58f144a55b80c3930f8cb5ffe9f1eeff909c170fe1cbf7d4571562aa238c1\n\nInput: f07790b21001198ab70f89558b4d47a06ae3428ea414468610df5ee6fb2f7879031c6f6b7f1fcf7e81b17d1cd2c59c7480c2a9acf901557ad725f836ec714977a4392f9e64b151bbe76248df5a276c0c74350b099f29297abcaab97e033b2fc65ab86ee65ae0eff819d629f774cc7595\nSHA3-256: 4a50eb3417f00dbb5cbe1299862eabe8a655bfca87bb87e9ff5b6934099f534d\nSHA3-512: 718d43996b9eee05f74d1b55a60a945ccf976411dd621dab7ad92ee78e46bd7f98e1e2d9cedd4d636c54c7bf13604d7612b6000fc1edefb6ca6d2037e3d46e95\nSHAKE-128: 8e57b6223a1640e667277d54cecdb342a1aeb6cd95ea1240457c43f16bba3fb9d2d83c3f2671bf3e7ba1f176cc910570326980e05668a9c80553a0011aabf5faec9337202f434bda9af24d02bb0d9e1c727ffe1b1b1cfe9a3ce711a090dc68da6c115e815823ed4be862305eda148f707c69d406ac95e1d81ff03beafbc294f56a19ebef5a09ba302141e185e4e197aa3e5743cbcbf856575cfe560bcb44a149c2e8e488c6ba5fae2b38a14a4ebef2fe64b4a9b1c23113293f02614e5d2d14018794b3fbd6ad606ec29c8279", + "143b37234bea697d5a03c9fcb5a7bd92c4f0cf7a730c61e00ce01b6c57281a3e672012bebc471eedcb3994d6dae9d3b55ce70f6d5e61c85459b07c3ec94b5a146a27f8c804871697bf2b5fcd13d61827ca88191cec6a3f61cbe23c31393e5a4a10ba341e64237f19a0ced77f774fbff2bcd4ef8f262c07103a0e4ddc3312b2a3deeb9bacf947cc53cda4e7630da3a88f97c17873344d5343b30c2035a723311c0d7b60abc147cc1b4051176427baa3ec97dbd6534cf50d3ea3673417d50e64c9a3b57f2361396f60eb15b3f4bbab1efd935c73898acb6fa17365137001e0c0eee3a3631fc8c5ffe5782a8438f52d4d1248817dfb6baed20061a7dfda4aec5b83e8e386c27d359b342b70091785bd36782688410b5e260f9d155cdde4c06089eb427d37c2384d316767c38bcb046c2d21e9b7bfd0\nSHAKE-256: 3c852324bfb91777cbbed7229267951d47744eddf03b3c8aa5c86378e96f03f17e2f9f361ca9f2fcf63f65b31ac91db5b4f18e6202b854f9674c72cb9d1ccd3b96d8015d2d4d3f60f5b991c294eb9e8ab4089ffba3b8201d3fce484ed5ad76df3a5cafaa7cbfa1f29b17ef2e3e03ca1b03415207cf5c9a2b35c834398f715a0b979bfcbec19344fbffc703efbd440a9e22118f685839288ef6696a90ce7cb50cfce83cad42931dda697a5587287ab822f62953672f3d9ba7183e3f79b9a249886eb6f11e45c6abeb76bb50990671f9ac5f4bdc44359239587703f56b9de9a5f70bada9e84f560c96490cc2059a9fa463d6316154357533183d98f87d06e6c1812649b8e1187ba1a82d561cc514e4d26d4bd644094705407b30f5bc7cc9614c2d68b51b9360c0a1bd8bbb215087b8da38cecad4994de06a828ef11167e0f4869b66fad60a3bf813ad5350a6690d1cfc788a352c1bc3442a6b2ca5e42bbefbad8198d99c0c6f3f3743e73e4705109f40d72bdc8dc20f66d87fa7e3ff1267e96a8b956ed0eb695abb0cc18aeefe3c3df562433c9ddd890c5b97169090ad935bfcb5d8bb46cc4aa46456c392d4f26fd85b7e78f8a5a28854f828071e6fe94f1e18dd66f8ae81d7eaeb7da1cc814bdd43b70aa047d513748cc77f34a717108ddbaa20777ebe0280d68d6c5abd23c0844ae3f76061c4683e0e4bf7886de76b37df5b85\n\nInput: 89f27e3affb00c9f33713b6c5abe419580593f63ef40eeb1f130d30138bd9d5fefba58983df50f6d4c29148ccbf2ecbb4495eaf8cd4cb050b732f185695d40f0ddaed73f43aafc27a56e5293df48dcb9d234074baf06f49bf8fd75f5e1e8843a60aa3124c621c831183e103753d8b0ecd2\nSHA3-256: 756ef5591413061a1b2d44ea87425bf96074a631d1646ac967def3befc4ef9af\nSHA3-512: c56d1d68c249f1485de1391275815ee619f17a2186f8ab650de4ec1d4ba37071f6d9f1fa7eac500bc077dd2d4a8ce85423ac7c3ebc58e2bfb0909bac8969ff97\nSHAKE-128: 2a71995ac3b504751619b853edff136ba026eda8752699644822bf6250be4e7d422d672116394d1823fdf349fd1b81e4dc29af166683feb2b07754b052e31b948940e954cff493aff5de93080955ee57b24fd2c5c15c3359a065b9f8ab8344ba090ddc8a02b63d633c80354d61000a583b412b79a6b915e0276c9617a87177b9f2fe99346ed726187fd0685e9f2cd836a49fea3d443341affecf93ca960f441991886ac338d2786afd90df1d485eadc0570a9aa7c10d345d932ff09df6c85e1dc0ac69e2c6780577303c387746c89402f0595a1dc6098f2cda5ece4c071ff43d6fa58aaf5080afa7c8b2ddfef61ece3365cad3cd2d0dbe03b603054726d77e83135c9775171167a4450fdfb8179ff2bf749aaf8c805572dc111d494ab04a4bf11fcdd681d16a70c8b96b87d23a46fa457b2c2a003e8813492a99a2f4b8373a26779a5980000fcfece7ba74fb3bd8ca841dbd3f87f5f02cfa13b88f94b3a523676f854f26b05eb854ceb505429151303b3b83d4b88e068b3cc35d096350990113c08253fc2a545e0d373f2042bad258aa5a029d5965bcf4f585b38c03f7f310ff62951c68f158afeda252ee369cfe7d2e57571fe1c19e20971438e48a2429e08f8e0fd8401468e20183d6d9fe7802c289b2118f5036e0bac92ac69b5da47800d7194318445bc39defe2a5c7f7e8cd46ef4191dc6915a424adfa8c45ba9101cb8e\nSHAKE-256: f15a62d91f9a3708f1d1763d84b920b46786935ff6234f8ae1957694087ba3205daf3250bb26973d64fd998abfe82ead5d394e95c0c4838bb5989a6c343d5fcefd7b7cd5904c78de0cb841c93fddb1311edb9b1c17779739855b53436f28e5d09205e556e68391d83e4a6993aaecf09219c08ab579690903dc6d33a63aca7f74d03f48e92f25ae5e8cfee869104169e91af08b23db6d8c26c69c56c6452a37b6f7c36f232c9f91b7f9a6ba1666b5ffe2dc5f48ef96866ba6b9a08dca85a37ac02adf961cd5b6fa947e37233121afb987a09aad66ae7d4ba7fd1c5a754cd295269f40b19139bc91d199b1237d6c805ee1fff71552e10fcddf349217feb7e39ab9467eb91d96345abc6c17ccbf75fdf06cfdc74ae29a7f3355b2e72f213067aa3b2b335f7a673b85b392859b0b49a1d5dd539c843ace412f3e21558bfa415d347ef5c3ecb44d8ae91870f6da3da2b16b9786bc8dfe4dd92a93ca5b9c3826649d35616c31b629b8483b1ed1d2f3901a77ef5759d6db479d611ab9d6ef2783c9762c32a937399062b7693c3254fafbed260b154cf3c7fde7f5a864321136760a7e9f58a8cade0e046a2f4d922c78702dc6ad1da1fddbc387cc35df7db5a2d883a8dc90224f1e0eff1cf8cfd74a4c289ac9a1515a01919f587d0b3233ce592eef0394a81b9727d76a3ab47a58d74d08dc2b09db40107a621ce5e33eb29cff527e49e4\n\nInput: 73ae72dd4538f9b6e578c03bea4997f9a52de49ccfa6f9f66d04b3bc3332ff218180169592060ce41fd8de23db05dea9ed9948ae67ece5cfa87d5beff20368ccbb27b4757e466f3a038ce7eb8d67a1381c757792f052f11610382d48aeb2927d120545cdf60a875065868afdff548acbab15\nSHA3-256: 0588b1db2bca3c8f29d4ff13b932e5de8645c3958aa846032fd02f2279ca8f15\nSHA3-512: 34cd81ddb175a27ae15614896f32f7f0cf5673476abdab74910d1e4b9b996f41b2634a1cae08eb5ac912347f34e9a0ad885f8c272ff01f66e23521ec6f5f9e7d\nSHAKE-128: 3b25b65b8dd67930da89729c9d04809450b35a653856eda7365366ed420eb7ca1d4ac63844b0d01b0be7417aba6233fd50975d49e6e2de82a61e1ed6d5b8aeb44cf4ac985c0015f49fc96eb20ea92cfd1130f697308da87c79f1ee89926f29661f38696a633b392785fbd229e25a10164c87b9a489157870db698f3230c01edb18932c85fc5be79b0dbf1d72c9181e6a00052615c50bd590358fe8b44214a411a682f469781419a6f2b4527ce6519c2965979892c5ef4f0275ae021f07f5e30df0bd171b45289671585bfee6d577b7b9211bfddfcc479e5eeed5726b8663e42700fafa93d2d2559806c980b3c86d2fc7639b8e467da8d060085469ed8f2f5d28d5700d8136463611d583f87bc7de93afdba4b1d0814a2384dddfa2e167538aa21765b75560d77ddc5b24a0d1e065fc5b1059bb862671343c4eb6bddfa74a37becc934f70ad8a9efa535623ebe4cc1fa3c4a027c86c40af58a4192f24392d6a95f15efc13adbd073081a131dd20c6fd1da62105eb5b6829be92dc3e00c1d161db17c72f0e03ce5c0da930e9758f5fd71f184d3fc5829c3f863fdcf847d61283e990fccf64489742c2b7e8920c1a0bb7c84b7851f19f4fb6a8d7cd9dc3160b8ece8f49eae69085a12b0f016232fa40c35bebf39b02a5c3f443cbd8e7ee53faf9868eebe01a1b64c19e16647eaacf6f1a85f07e59eac429e0a2b1a45cafffd31d11\nSHAKE-256: 6023874f432b60ee32d8d1090046d520f83c095458a7a27ea632d1fdb8c1428701c62e13a59a2aaea4691e1d06dde6bd2ec60491f7dca4aa1577c3240b540bc72cb851dd54052588cb59c1dbae29f5e8e1c341905df6d09a36fbf5bcba287c29dba0398434ff8a69fe0332b129af03a6f40d9a51eb55512052deddad3e1b8cd1b41aec792b070fb7d9a953bea684113589c9caf38696217572b4a9612329f9a4ed5b93f5c7aa31ec6b5e07fb2e2e0e2fcdf843ed7f860def0a1c8758dadc5c80c7c959414d7cc9df6eb6f0a22564086a75f59604333976c6da1f2f7878a69fa5cf211395ff4b890e7864a1aa44bcaae3509c2fa8ceed4181018f808f945f36b21a8cc2aabf7699ff722ada3121eae9d0b47dfa55dcccbc7190c02093cc8fac37d81f54f71890a2c5960fa0f9e19f86a29e7aa715625b74e449e041a8df3e31b1004bd897c157fa326eaa4db7fca6ca7efd821ad811c0f401057d02bed122bbf394b8f13ec0a7c6541d7464a9681136d807291f5d4ffa975b27cbd2a270ed1f1b5e408db0923c845aba3c445279dddf6750eadaf9cd454895032cf44c09b42e96fec0fb0d89ddaf55359b68732719a059106b023bf81bacdc88f03b97954a34f348da8620d7aa2c2d5747d38c10b4208c331e1a1405dc3f93a81cf1051096340863a3bb123ac32c05f7995f0403137916b67c1c7f381e5653d16d63e05dd78014\n\nInput: c2266b0009cc5bf8188f06a7eac129d916e340b0b6213f603f81ecb490cfaee610626f9155a431b69f0fe6e40f7bb6343406b716c541a4cf2dc36823635e61f972ead865d781fe3144ef0ea9c5a22b490574544da6019f1f8ef09dbfdbc1e5a6b7346b1be9de72109265eec7b9cea5493e7dd3\nSHA3-256: 150903290db4cf71fcee3aa3d10fe38927aa450ed0446c49edfa861793c98deb\nSHA3-512: 183ef809e5184a1d8283fe044c5016e5f9342c2da3db10e703f2127e7c5c72e72d0a41a518615e95e378b144a3d0e09225717c44157830844c5bc23a0307b21f\nSHAKE-128: e8ce313951b79619c22a02618da53d7e091e4827468e7cfe74aab373cbc2d1c3a522a35890eef7af22ea6719907d4f529d2c0fc73e01606882f9de38f5a89895692141bf07e65d876aaec9ea5c11464684a5387e44c03e1e1eebeca5ddbf911dd81d58e0c90b4ac55ae6c49040d72deb303ea51ae0fd5f6cee209986e9094bf8c577e4f26736c12e952116057f7ec158b933a417126457b4ff15f5e698356472b0ca6ee325acb45ae808ccbe9cbaff49a412c13e322efd1a165b8b5e40a68cf0bb8a415f9824b3ba3b1bdf3041024f2898e75fafdd259c8ab35197282007d1d43bcff9b47190c524107908fcd693ce0f4d90c3c0aab9088562b84c25fb8600c56206f73f9226cf24a25b86d41f7533464cbc466c845af0bb112718bcd14f3f12fd7e9263fc2eb67769093b0f6c6fb8b46fb04bd63a4f0207ff12ac8240fc0f4095ba5acd64ee48513b939e384e83bc7ee97355c03eceb66c6d3eacc640de48362ac15f43d54e741449b18cde04f9dbc032b0126460e8d5ff4fb3e912d5875ce8caba98e4cacbf31820d4450cf318a230a3f29e18d6ce04ef165d61488bf94093270aaafe7f8b8d14f4bbd8a95bcb23170c784c34969dda2f36da089103d601e2fba262e0a560642b77435a32642d105b388f06d298651c5df29ab93a9e09c113e22ec2e1d71f660a96d56162d6169db3fee567633652845bddc8742fcb61cbad\nSHAKE-", + "256: 1beb9bca6135e309311dcc248295e0a0d8fb4c94602ddceeaf3f2c59e7b989ae40721d407db96ad71bae049f0a325c9c5133b585ab788e360ee22d5e3ce71d56f0a5f7674ac3ab9f16f47a47446b00e35c9ffca54e4637005a5fcd395754abc7dd7b5fdcbb41e561a76e5c97821fc43aec647e96f7cf3d5fed5adff3e360af41404c6336e1b61bfe2be502f99233dfb1f08018eda247f2a96d17302837d6278854188cc1a8e3344014cf05b9549164a55e6b0d31e6fbc358799d59ed4bc1244f3069ec98caa805733f3b7d89622c9394b5cf4a6a0fabe5f01d66da7f6a78fd92fac492c3caf81f54cc03c8aa295892bbfae8d9a1b262f8afdc29a78aba155feee6726f99d119609b7a803ef96e980f53c0825ae85b6fc1cba3b67546447cd8a3090daac43f736a985349d46ac66e11f8390284227bd975cede4a85c847916140f91dc1d505eac37b9a29238091a31e9ff0baa4e7ee1c6619d93c23c532458bc9587c1ee41cb8e057122509e623aac6db0f25984012ce85b77fa3ad83254ef9d4965bcb708f7d1c7840276a53bbd17c32eba2fb4bf337e432ddfb6b175d26cf25a2d1d8cf59f4d10df6c8b8aad41d78e7013c041ea4ae4c6ce7e1cd6ab9771b9f1b5110b27ca392fad00a95868d9f945b036b2c83af88986cf95fbdf844f84b5bd1beb8dbdb64f29d1d2287263f810b0b546af929f28f2fc751746996aa5d8339\n\nInput: 32cb40435e87277bcf62c24b0b695d97d56879f9015ea48c82e1dd43c1a2161314dde71d16fd6d2d9a5fc3fd21f8bc8ebc704ce75afaa53e6195b2e87c9b5b2dd839b84792307c84d6c4d8ffd87769c3eea0e35b48336dc4d05713d6db16345aa314f27b2885621fc1b2aa8e107c3e45bcc61626\nSHA3-256: 4713623868d3438760d1edc51a2b06aeeff6bc51c9cad4fb6c87c432564c3786\nSHA3-512: 75966495292dc84d1ebcb88e9322393435e18443face019254bdb576639e5063a8d2f979ce83ddfd036d86a7895b19b21c984fe70e7eed6e2691366765e927fc\nSHAKE-128: 2d035aebf8bf8971131a2c84c3a7c9b118ff9d2a6bef0a76fbd617e26b63ff32f07198c76e096edcd0fecbd5f5123c0c3f5e7df76502ec9ab520cc6967f13e927a43487889afe5af9325f7d1605c111132f4dd49ce3b53ba722942fab0f377a25a267ddc4c82c6c5656962a0db2e7e6826339e6c2e37b98eb19a1b5eacd159f5cdcd139b13895f168d1a7b416a96404f3d76e5215bbedd0a12c7ad3e2d09072857f645d303fa7300a43f81be90e70da684a056b5b497a89cb16673d92b5c557708980f79d671bd42bf46bc22b6b50ef3f1ba7a4596e6d78476be6bbe2d0f9a3d22f4eb9358af8b5fcce37045281c2b1c020424a57c262c69ce74d5e0af96babc3470c5d0872fcc8873c4f7ffd772d67d3f80a3954b6be05d15d4dfb93044a996a97713487e614149cdc7462cfef0fa4c0c27b72f985d3fbf91291d35169222ece7c3534e4bd7fde7cc39e5eaf2f556b14c9947db2fb996fbec1bb9f54471ca3d15609b5a9183f7529ad666a281968fde70519a55209275226e0569d0b1d2267fbe009ca1a0704c2543036cb494dcc8e50f891445401be9b0701da81ccc7734d021b98de7f72bcb011527ddaedcfae4f5772ab3b8fc04fb9fb4cd3f4b88bf9c9ed05fd7aab5e4f3bd468d1492887762dbf253425e304b1f63356a51c0cffa669140f3e5c92157ccf26c520eb2399018ab86c50ae4a8710757a49b723a75cc8f23\nSHAKE-256: 893e2df39e247e1e0e52f20e9ce594e45b084cbdc8421f72fb18a1fba20c9c11390e332d31e487fff5cf2c3c63aa4875a16673c462329a24154a14d4015421ae04b4bd2577db785549a4b0eb6361365612ea56e54b9b0e305b4c20b25816eaaf34992a13a4773f3bb2b602ef0f9d2e5e185a8f3ef8ea75b07b29ba19e4af55f2c5cbe0ca769a4d229ad51c46707d9ad2fd436b76a72c2115993c8135b69f2bd86075aafb5bff85467496d0e69468730875f3785f8b3a07c5e7338741fb1752f4dad517bdb01e1708af74d893f503cbcdc930261696d1e6b65258f0a1eeb355768f48c02e8293fc8b190ddb12f4df057f1e70df2dbfe99c13147d6c1bfee0250e2fe38afbadefca63945d3589ac5def3f2c8fa4bb152f78d2c06ecaf548b190f4670703e8dedab086651f97e6f561a6b61f0aad0a966813942773c1b5e2466a26d97690b30ea2f7b06c81b3817bfabdd08b794bdbc500cb35963803efcde65b00c6abf682c276e1efc2cf95247a42893fe21998367ca69e8a632c8884485e34471caef2792a312dcc4f9192685a34eee9e4059692c5405cd7ab4aa61c32879a4a358b5f610eb09e66cef34519593dbf8460d640d6f604ea903f7558f8c22f6a8963445b5d77ad14b7d6f4f0c0e5cfdf01893cfc39ff85d4e804041e1b62d46eb41410bc52c21f8eedaefd5ff4e55fe2936b9bef5dcf20e7e242513f28da91cd02\n\nInput: eb97a9f7256f7f1d01f8985b36cbcfadcafe70f75723d87dfdccd7a4dc812e13f081d533e5a96d666b955894958f61698c59aec84573c16aaa90178b34e2b8cb2ad16d5e205df48fbd9f62276740a425a1ba09ba1ccb67e0c0abc4cbd9b521cdf38f45111b841da78fa24f26f72209ed7f207e08f2\nSHA3-256: b23993d84586e9e505140b3dbad20550c69c39d0ce23d2adf58778c86535940d\nSHA3-512: 5a7c24a6492a33485415623a8b28010f5af942eea03fdadb251674e08a02e86283ac1fab281340b6fedc173e26c1bdc3a740d61c2174fc30cb455648c4ddd823\nSHAKE-128: 38fd19d8a5bf457c28150381774249ca68d2de02109745ec95f832da44cb2c7d8f290eeb3477347be2090e1fc0c9cc22bbecc5aca21d01aeebeb0b64598985edcd59147d0a13ea1c9ff0728ac0f772b1b1cac9038b916535b7d4a650b3f87f925e48e2a0d9e9be0761d37e54bbae6bd16f855e1942b326a5d6e86de47da0879ff3a0c583bab074dac3fe90648f4d83b88a7fdcc7b3017627e60f79ac70103a01e430123888b85dbc31ec75bccbb4e69baf6396efbb94b809e3516f9adad1d25d8f85c250a729f43e156a16aaa8431be3cba49e66609680c1092e7f8bd0197cad2fc2264e451aa37af63cb1e1a86413ec86c5079b98f4b91abcb10ce5d4c2455d717e14dd93d0e0888520543fcd6e3000d4618c4bb93885e90866cad9fce3421d96b0f512aad3c7b4fd84f5eed05ac903cc11f3aa7473e85144b19fc66d28d842a7fdfd7eb796782937c12bcc04d791e5a1a394d7de47c1937dee99454a27d6308ad4c20d7f523a9e2a83818de0546c827116d439067323875fef53672035755d20a5472e637f5fac387d039a2dec1f7e6348179b3b6d914aa410155e1fc69044952610619a974cfa406be4f3f8d7ad710a687ec0ff4d7b05effd61055eace3a82ebed5cbc4f6a26d326d538baa5eeb9cacfe666689774fa14609d5919d6ae067fea3a907b570a28d7a5f6026c2dc03d09640c40be448c8adc96506d22a025bf2\nSHAKE-256: 7a9ba6bd8fc0ff9b9ce71d5a9280496a32c4879b9dcf8bacbf0b1d9802988373134e43fd7328d27e0c2f7c9e39de67ab048ef2e68eece88e9d3aa7539338757c0d018a8ba97b8afa28eca0caed9428b79871af1cf7e21404ceacc440c6efa42f1f40dc9764edd7cd590e5b339cc9e6d37cd5543968389da4599096aa7958a5f90bb272e9b8bd447445075b730a5015bb83741e291d46fd7ba3e49ac280108ce424e98fddfd59f645d50095f45a887909c5788f65df59fda726057d747858d563ff51b385598789cd342f5dfeb4d7e2786cfa24096cc55b76cb311b2581a963b8ed663ae47a13eca74eb6a6fdf0b1e75ea51882e8f42af5ba5802758f933d49326913757d4bbf90f95bf7285607d2f188c01e8dd2a6bab4a9f880fde1bf04f7a2870d6ee70c4525ab41435e0dca0dca38e993a25545ce1c3a02f52f998c3526029e2fe9a69cf20b8e6051c3324752c33c6bfea44f18e3506780a39ddfdfefd6da88f57d4f0e6735138046b4578b700a09a0437e55ce45601d5e3ee820f59d6476e7ee74bc09f5a5a9c5d170b2238690fb24a9dd19ed8b4c32696aede4401276c04084d71cf47e2c288158716449b4f54895f5dac13bdeb724d636caabb9420ff42b2cc3f01785e0d18df44f716a016168b640f29238654ac351613d8936f7228c2229a2e9eed086f19348e89b1a850dd4bd34d4fac5c87de9f16d29a47989e0a7\n\nInput: 41c7e9f0edbf31719ca7de349262e2dab8a810e053b19388b0ac26f053f927ec86fe24f45106c9762ed2b354dfa34c5deefa6f6fcd4d612b1022ded6b30a9baaeb793f44b65ddace690e6ff507609979ad1e90ae49339a3b8eb1b8b126eb74e61804b3625b73b47708dcb810c731e0bafd17c7f668a0\nSHA3-256: 712daef73d35c49320e01db642ca593579251a88bca8d8d147a18e3cb96eaa05\nSHA3-512: 6b2a7533d54227e40e0f706dd727aed0ab7ffb94ec30318f2452543a30f0c33508715cfd5e201b3f0f06566c9310ca3cf268bce53a45b36514eeaa23c03f03d5\nSHAKE-128: 51564072d6d6ef14e37a534fc76d1a28d5a86806b6b15a28e0356e7db311f118db2c2902383b3a965725bfd10bb2e6f3d976170b2d6eb473413db481c361209fcd1b73b9aa3ceae64d4dbc011367030192fbe23a1f8a12fbeeaafe09803e6de236b37b87792161e01036a31baa2fab5abc45675a5627c5e864e0e95538553adcec15a42a7ad4c520991cf7d7ec58c430fe6cb8aefddaf0874aaec1d91fff145c8b5ad494c2d390b92712b19019f4092c6a6b186c66d3c06ffde6136904a2aebad6bb211a66c97bf71fe28c86406ae7ca135dafef79b0d2e0cda51e4cb2b20d66b5ea24972c646f2bf52bef2fb06add84191842807b678ba7c67c34734df131af8db12a4f5cbc63eecbf212393eceb7bce20c2d33538fa26371ffb86cc8a33f526e7976a5b4c6f450271f7ab03f5e951dece9896b3ab27581d94200dc4be1d5c784ee118d63fef89566c4c49d3b7e6f4606678344b3c650a63e68b718f924bed53550b13e1abbc474fa62e8866309e52166b4ec40b98c0f98d66b261e8020e7bca033a19ef1abfe38be70d8178baface7591e6c9f6d377969dfd8c0246812c7a28e87be780a4ab4a4a567303e30d15d6268e8c4a6c0de18825c8ac457a572837a9d165fd5980096e0f830b11be7c94a6f3ba8f0d2d33291a259635fbc9b3f1ec444f1b6c7a1278d572821260005eba3b529e500e242b32ddc37b26a990d22a982\nSHAKE-256: 984724f2c422fad05d484415250b633501a59f9dfe4de2fb51975e1b8a1a3f65557865a7a25b8d9fd0a7b8780c2c97428abcb0d0f2b43db9b301e3ece6b533d9d368820e65040b0d1575f8a10142802fdd5c14e3ab92b675260867b2e28e8fbbcce98945e03e8bde3828c0b83637621b14f4d1d5ee07e6730fd963acd0000ee29f33649894d792c505950ae4c0c9181ef94518e192ed0e3cb75202ced3d9e19e2ecd39ba5f7a798b81fd8c17328674307739ba483c4c9dcb2c4561227df9e50406cf79ac386714cd8ff89fb9d68f619bd1409e2202a8489b9d145f87f3463d82a21bbd5638ffee146089fd85fdb759890fb714b7efcee6bc097d2cbc1a3fb67a4b70e8c8c6a13485384ce862bdf7edec2460efb7c77f0d6887087164d996565e2a097e815ae81afe5e70bad4", + "18ee1f36c1e8426cbaf76cc92b828974683fc573d0eb6605ff64dbb0fc5c2c6ea8ba614adfa2c6114734162b07fbc050483f4e1525a6ad629f9cb28172e9ab24dcd3090f4899d64430bcbf194f8f0edc90a1721cf6c557be71ca28997295d2bf85cbdc41626281a55e897b322ebf77bd3ae8b9bbce9cfe21789524fb7a4ae17bb1db1d02db2f12d2c863e858a6aa6c038c23e6bd7111fbcfe97ad71212820c8cab56bd667092065063a7bbfe3c47ab353413cba03accbb1edf2d93b905f8ccca622edeefc16840814978b11618aa815e5b24909c\n\nInput: 049a6c914cb7ca30f499deff144df93af7984bc3c0388bee7dda2574e380ea8e3f38ecc5a60413e7a4ca05f46596f5140f8732f362c79379d2692c7b4c4a7108a7aaad4e855a2953b0cb68c9efe258c63f69c2b6f6dccd79dbc373765666fd41fca6edbc820ba1d4fed7f16207b6bf3a862425c62194d1\nSHA3-256: 986905859363ad095848b5cb0407b64fa652173d8b164e6c280df8f21dea613d\nSHA3-512: ff7fcf4086f68de574d792046974de3e318ff1afd7ad87202b28ff95d98946b12aaaced29a6ff8618100b0d139e29951159dfbc23b0920b572136a0c8021b950\nSHAKE-128: d1a14bf38a12924266ce77db2beb6a90e75b6d162c4a2328332048100e1493ca20ff10004bca77df9f095690d603102645025894a75a41987f5031798b5e449c2f48e2bd041b365a7b296bbf7a2a2ec3c4941ee377be1881536c7475604672a203278ae35b4c645700b1237652a90e936079aef2eda1b0ef271825ba9bbe8923af33dce1fef4a4190db56245e4ae77e9306b76dcce6e48ab9140f59922f11a3e9e7b76a4780b95ebd095a842ddd93b7184aa5cc668648c1ada90916756ba4f37a430f5ce601bb8cded574194cc711c0da6080254bf985ecf75c17e34bb3c06297c0a08efe763c69f9c20bdf2a81f1230ad4864b88dd35f4fe3ebff8acb178ac9d922f407b347c76e8d10c7da7c16653a009070c1d58fa6842f4fdd28290b9575fac7a396e317cd5987a0fe0b092a53e3f151c486dd200d83efddf14dda67fa4370dfb65ac53f5b61c30cc4b1158fa83e45157b661695559b2c01bd3fb60a00a5a4338202d57a6913ebf2b5773db03e7f4095570e13a97eb33affb25a7001626cb1c52de252fd8a697f241d22ef7bbee7964cadbb4e91ee3d3adf2d1e79effa061474b35f6bbe9d2c9e0b31b8e7b1eb46b09fd8922680fb56e3744b5ea2a2258cc2c067ed06bdd7e03a46381fde1d461496061947b3b9cd4d8c21bc5bb00bd6153ebc98a7b726b356693ec652301275d14f5a386147e5acdc20948e71191f99a9\nSHAKE-256: fd2844697dcc66c47e7bd76abedb348f745c2a61cda353f260cafc52f98eb49c30e4a85097eff79de7580e857212788ae47700f71c3d6d7c27cfa01916c96dd864ed728fddee20ba9f7fe0b0d6a93191120d803a89a1c27129f120c061aff1375b1b495383cfaebeab141265d1ab730b60720c23455442268a7cbd1a315923c0062ca297a550b8bfc1eb2e3d6eb8fafcf4ca17bb2455152ca8d724ad25c523f928fa8c60d900a39fe92ae1cbc4af4fe04a12e71b1ed1f3aa4e4dd7787261f0469763bcd5e9b134a03916f1af0f028811c748dc5d03bfec40a83b469da8b5395c9969a6ca2a7b0f64cd5b4ef14fad89972ff766f234f5bacdb79886a14a84f8e38b5fa2ed396364136cd289a7d1e9fca494123d660d429e69779653f2e011b416d5c93c07ba93fba0f35e36d88a3f36a460be12e27978f7a3f3d9e59f78ca7e01647d41b68c116c5119f83cd235d99ee2277d3607f5b869f75185cc00a72d151be161ad6ee9a303b3c1cec8b1221995a4734aef396a581676f90599995e91b74e8bb076f8d2b823d7f607e4c0780cf9464fe28f05a5673eeb1aca9bec81ad53407f75feaf7e1ef8f86c3a6ee453ba3cd411e23e307b482b6f9cf69e4c63a9bde328a8e1b7ec7826f5c228cc9d8b22b1fe44c638e7be8ed1219adfdfc5439d1d4ef85bdd33d02d00709ec5dd9e529fb8dd445210cf70dee720aca690d2f34a873d\n\nInput: ae63dfc2f09be9982adb090e01e52c32c644af813d2bba345703a6fc28ed4424b87ced5ca6082fab581ea087503dfc55e2186201652fe6eb3ea2ae373a7818cf5db95e2ffa3d3866bb626f5eff7fc489e8c511cbeaab3416fec00cbf5621452a429f7263df9f1f837abbc81bbfc98b86464a1001bf98cabd\nSHA3-256: 4f3dbceadb4ac0ad62f08c19cf060b3a117ed368c8b4ddc83f7beb91c8f7e496\nSHA3-512: dedbfb6569e2f2bf633fe7bd64e6d378a66e7e70062d5a9ee2de301ae64297c12586c3362ce6d9eee22ff6605ab3da4755845cfabf6f251182dd5b787ec7cc1a\nSHAKE-128: 5409253a0a57c0e0b7917007fb91aeb2b9b97c8cb06ebb1063d9170a52b13d8a1e2abdb8722c0e6b083e7deb5abc8115867804b6d6a78e6ecb2589938b4a749ca75103272b73e733863443a87aeafc95d842e59316ec665dc80b77ab61a9fcb6c5bf2fcd17850c3281b80cc1faa94b88403fa4808b7bbe2c9f7d7e9f7665cc593047540e39b710a37d56ae9ce2f036822a280990935767ae2e1dfa8c12b3606d41040303ab635d2cb44ac050f2724bef9bb2ca0d665f448d0d01984e1e83159fd956f9dba37b00af3dc83cf66fee4674aedd018031cfb140d6eb17f2b6f1887811291fa50608170d10cf19bf137b9d16e15131d5e906c6e7a850b9297a876f2f0573d2802900de26759c7531ef8c9ae3ef7597cd7bfef10297f22aa79643a49ed6df8fa66e72c5f420eb44ee4d4fbd648e8c21397b532399b4a997039e3b1fff758aa874073bada425a29e356db0a1df20bb0ebcf8ab945b4f0addc834402a2cbfb6f912d68623e33ba70270cf61954a550df1bb116288667f8a05b5e8a066f6be76976393cb4c2b6462c17b6d3f8b61444056a3310528f98d26cec739bd7315b653d4a481e24adcba16ce11954d2022a78667f1ac36d25f00894ff3a356aaee2dbb20681a058b6af32e0b39c5d90c7efc3e45b3771e2d365d4e82a4a7d4737b61dfd6b39a4d0100413111d835c6d533c9be207fde8c73287b8cde79ec034377\nSHAKE-256: efc6b890389fde367055837a3ee74b3fefee089ffa75fc42ddcacf98c81f8ac0ecb05df104b5a109240b1c6bf6ac2827debd4c926df2a34bea7dca98d9842f5c5f04c4aa4cc1cbac86f4eaa3bf904528b7ae9dde02932c229663fbc5e6f1b4dfa40dd48f2c3e6b28fa63e08f2442cd811346a3fa7fe5cbc3d4054fd2a99d63cb09e72521ed67048f9fb6fd579ca85d19d65b409f0212ed3cb69eb05b5c010335297f2156cd786d86759043649775939df265bd2d9765950c31a5512b01cf992874ace7b64035730eed60255d30b713ad2d45bce4b30334d812b297ca681b4de8a6545555393880b96d13054cf05fc74fcb8f29be9b9950fbcaa9b3dfe93582c184b9599dab2aab8660ca93972c8d9595e20319292b967277156c351416e2634785bbe370f112e222f78f9b50059ec27519377089dca2fd2f1a597feb78f972a626a110f6f45d99d4f9d72eab9f01ec3f16e9aa44c284daee45e52a720d271e87593111c57f0d710e31b8b299a901d4728a22476cb22b86c1894f1856f9d609525a906b6241047b42903ff110c7b007c55514e35aabb15284db7903731e128f2f77fc1da63687f96f0edb47a371739dd94de965d4a3372872ca20a32647cb42193c68449940ac603b51d71f5706ba0d6efc49763366d74164f038f97bdffd97be0190a1227fe696b8231af9059b50a0693909866355600a9116057dc0aba921ae\n\nInput: 28001497cb75486c18ef2f28207ef12403d0095d7d743fc0c43363bdfa155c7f3bae0c18ba1fc393b48b360205225d7e09f57ff9a0f4967a7bbd632e63b49a5a47861b396cda2324528f0d8aa4ee23d04f9d19a7b06880f957bb5ff804d7a31e267c6041b3a64417ca18bb89bfd90deeaab98f1058ecbdaa68\nSHA3-256: 737a58a3f767c1eacadbdb0694c842c65e65d3664b219ebddb01f0ae80769b68\nSHA3-512: 61fd02f4402dcbe34e1f610398df54eb64d19f6ce76bfe42ab4bf4e0a6f33f79e26fd32324fb35dca59e16e166d49c36164066b1ae2ae1cbed573289a1235942\nSHAKE-128: d937e6720115fded4915f00d19aee91c9c7dbae74ab5310153a658db55b59193875792bf8b6c1a8bd53d41c3468583dc12225dd586fe66ab48a831a255bc3f178619ffef7e3ab6787416db187c17cf82ade24ec585540203d654a70b28b8b2dfd88300e3feae3bda45d383a033cf8dc2e82725d187a40c49577d601f2a013eb6f38bbe4af4d496c4d1eb3d18c89759b2fc37719722ad3b49dad8da54f48a27e48ccc56cd711be02ec4016ff823d2084eb0ff783c71cd553282e02c1470118281d8685add175a1f57392548429570641252b46bcf72207943eda715d53073b15ee15100e7f9de765b59cb8d7090a5cea53e52398216f1edb7e819713ba19475fb6209e2ba712def04025f5d6f114c8508236026baf0d45e0dd828401602bec46a1796ffda1df852fa992e17a1ebca822c91fd2fa6576bfc8ccd3ba7b18ab4a321ecbcb66044791dc25f5e8d5bde77b39ccda620f088a282d4058b0a8081b26d03410c11d80961f30fcd83107dd6696cf2e0542c2c18b0409e7b765cce710fce81e8c41ffec307f1623547c1754d540c5acc43d2956b56bbb4fe027d7c07e99e75bcaf4ffc15a67ef5175f194f36407ab6f4bd77a57493c4d5f61bcb0b241dddd1565ab2bd8893afa00e9b427518a9a2807ec88ebbbaf1acb6734836e18539700c935dad6ab1fa79c1814d08e69ca29a53142d72d9726aa0c9cbf14cefa269ff1a\nSHAKE-256: e4e68f478e81c2ae1aa8396e68e9a5b69d4fb5ce79879652ad230c3928b3645edfe0329b53c5d728c95b5a89cb74bdd8924d40ee437b8837c5890e539e49dff20e1d55b8ecf7956f3224eda53fed98ae7223471e9cabb94ce2f7428e76695c4f4ad818f954997db7dcf58ab960aa8e460c342d4dee393e826aa4d991678e027916a2edce6e2b2dc8eb52e5eed290ff653f411970b9cd05482ee31c5294a3aac3507884a600143ceb8cf13206db86a0f33b3050b9ddf49ed6f6f8a0d89d89b24448fc3e9886812841a43ac0505768b6d30b2f7cae6f927d924896427a6304c1ccad0f97e7f32c379c9b99a7cdaa5e02ad7c4ed8894543216cc9454339aef2eb2ae144ba0a478b16fb652bd48cf237d3784642fee8922d0c5a3b2f741019480115b731627202148bc26edae5da5530a754b2c40f5dad45d824bfb4f40c0f71d119a6ddd1a43f8f599762a1682142bc3d5bb46b8395f778c853cc18521a8d5ccbc78fdc0a05b34361440fb67150d6fd9ea5328dfc8543b3f74a29fba90ecc0873b8a593806cef07e21ecbd60ab06eae15f4ff4579d46a4b7030ca6cc97a34885bc762381b44523b5f7099331b0212d0af43402763ba319feece6201fff803734d53f476032fe674be2acf8a7a3d3c30f4571ea29b3fb2105be11bfcd38e2f644bd7ed356a71b3f3dcbab4da944fa0e0fd822369e9131cf51576040c113cd66c3a6b\n\nInput: a6cac62be9e7f2ecd19cef222384c6dc668c28026d78b3be985d29204a842ddeada52a6d6a620e0f57b6c4e74ffaf5398a32963904e77db01b2077aa173a23fd3962fc86ed1318a629629e882c", + "9eae89db1246ceb739d101c27f48363a658fd869c2ed72c277d680d28bf4cdf0d396baa3ae79d4ee7ca52ff89d\nSHA3-256: 22e9643af462293ae170ee5180840516c7247d0bebaf524206a10178201fe554\nSHA3-512: 1a03ba5b21ecceb5928de4f2361b8506caecf131922c56b9115545b781cf8b232d680071561e433793ebfd2773918a11d449eab2f4f116858263afc8d6e14cc3\nSHAKE-128: d6a7cd994b84489b1d670c126141667f4de746bdbac6a3e5adb5cb6f174ddc21f586ad0ecd6322434909bea75b1a25530a37220a857bc25f2e3b220e9aa72c9463a36451e06a951612dde0bafab385effb32fa49edb5aba3998d26c986fb40f7dcca114ef9d9b0d70fccfa05210642c82456dcc56421f1b43ed02dd1fdff266d2e87a1dbe991269d16046d7ea437263402a3034d4b53011aac19829001d6344cd51b1623871f1b900253108a7d632145b57f6edc345945d592222b173bc7338e64686047aa1ce76bad45621d91ee3f0050658cec075e412549b0e96a9a465eae7643b0fd2b0f89790d677cf9678d0ca641c5284bc4eafadc6ec200be69e120e917ffa07bed42d0c87081aa7713e7c3f9579dca816c82750133ffbc1bdfb1957e75b8909b6ad88a35533be317f7a6d5395caa22daf43d6f98ff231ae224a4d77bd0340d338913c45eaa0f9dfdda49ddb30274a346e53957e1e0b021adf3b113427c3c5f6d0103adde978f0a297c381a516da895391b5e61a34c6005271fe45192288ae4722d0a03d1ff2adb356a50cbcf6520bc11f4824439faed20c16be1498ae1e3a854389995832d32b5e21f247852c223786e59e702d2cb74750f7416564137bf8fbd1fe210eadbca5bc41ce1fd8752b676e160890c5a17cef9e7c850db6a6cacb3319bc5b2133171eeaa74cd27c7c634693fc052a6937289aa20d49cb961\nSHAKE-256: 4a3230a7711bbfa063ce369a00a4efa90f999a92a1e2b8e367b6c1cc4efd99276652bf316045e0d158b5b3c1948ec1ea0a669dcbcbb2c11950cc5b32bd90c39de49cfebd0139c07a4a72cc91272faa4cd38c6f999bb50655b5d9f801589c212e5f9b5dad7d70c05a053f39a46d2a8d178fd242306f16a0e4a4f7dfc2e99420fa128d974a835ecff7fa73cab13a2b452f01560de30d6ce7970a0998cfe041b59f562ff576a86299d29e8b60906b754628fa8db8daa01f0e229c681246ca1c92220165a914514cb51d488b8c39ce092762b1824ef0edf2fd92b222f82f3ca5b57945fe92cd172d948579b43e5d71c9986a24557c8408465a8112fbbfa045dbf311f3b7fcf69bde058bf256c78e9c5f6aaad9350b5092aa74dd2165c5fd04ece86fe5a60b07cadf07d8503e2211a0ec593d8870686e8804c90007e1e7e4fc874e15572c2ff71daef350b75e4523f90fbe9158516f11bcf8dd75b1fcc6ac444aff1f082b6b7280cea01ea588b3218bae47f1f85e44b10471850cb1e6850df3f777cea3285e79405c55426826d515209e78757a1b649e0ec27e374a243721265feb178310b58d53d1f287133e9149599539b6fa3ed2425e4fb19ca2342d0779c3cdb9941e51b1c2aa7b3911958dd7d163904dabfdff9a8e51876a470eda1665fda77a9f1bbd933be4fc4377392a9257267a372c64c1a061397497adc44d2499890db5\n\nInput: a380063e2dc27a6ada0a6c018d7cc5d7e28cc20cd81ed67a02631b866be02083051fbf2742507655f82c75e5644b6b0d87db4f3eeb19730bb910853311860af20afc1a3571b61f0341bf75fe6b89649d21f9431f68774c1b604a75639d90fd9fd5b8362794dd09cb45ad42496064d180453a17b611e1fcac7542e2\nSHA3-256: 6d7ea8152f1745205cda99dc24d730a482319e1d177caf04ba32713d90d4c37e\nSHA3-512: f2f32088526ad75d08a1ed73170829afa4f4936b6f3fc57f757cd2d12dbf9bec7e80f464d998cd8285986395e2219983b7bfb87066e2c9cc60fb8df3a028fc84\nSHAKE-128: cf87384910dbf1e75c3f4ef4d12d78161cd2993ba196971275273928dfd7664df9d45a384e06394705fc15b9a4b14205b48a36ff994b70211a1a53efba8cae369084175f5602b27a74bb4589819d897694213b316ce8abc6089879c44eb8e33df7e3b6b69eb694d632fbcda33393623cd499a97964c9ea352e3aae6f53b2410c17c12eb243503552313365340fdbc3bc0e6f027a2179230ec80c70cc22b7720ccd34bbe388c63181182b6c8580367b6839dea9e3e889c242c4bc0cedfefe3707eb9c3e04f4b0ba7359878b4a9292d172a74efa8070d06a43b4f24377bf830122f56577c8c2773055e0b6974da818b8433110c5fc01d35daa9eec76b0cc24eaad0fa60be0868fadc3cab544e3797211318da3add07dfabbda12932a5e00c0942e54c61ce8b70b1f44af78065b192099da4ee179a73e2966fb3cea98b384fbeadebf7f54900858103cc843858f7276b58279fbec18b367a77531bf957477838c37a6857d46836fb342fe28d012e04945f9deb4c18a780e14ca0cae0a3874ca295540db68d8ff18c5edcd72cb6db452b1593e9842e5efbb24e96c43752b7932a5ce9bf81b2ad3965c2adb44ba131281a855f7c0b2bdac6bb94d9183849449d409b9ac2bcc953ed94d8538817431382fbee05bcde3ec1ea427142e33dd992902fc1906932219f0c4be7b42171bcad3c459a0855193a5ce5f3c6dae7ccfe82ee547db\nSHAKE-256: 179895cc083b075df85b99d04a915f0a06b719ca79ca1f09c43d758c0c0978d6ac30b7488d0d1fdf6941f955341b11cf58a8ea7a3745d01bca9ebbe870a3cc3ef274642162503a85a6a41b7629e550440e6b11ed4af7845faff397797528b2739fcf68264b9b09c4a9ad9bc414492009e84b0f4d68280fccf2ba97c858fbb4747d73c02df45520f9de9e657b46b01f426facaf13a5cd5205320b7c8dc648c0b7f77f8754662362602b06f39afd05d60747af85190a723ce417af86328d279bc980a17c3b2ff44678d7863802706fa075d48fd3263dba1b15e2857b8b4716e9784e193c551c75c2a4111a0a739a06dd517437a3e51b6bffc45d027285a6b25c6dc706f670eb52b26074f57c911fbd8ff5433318e0065d108d6d36de697e826535ec3d866f8f0d264b88ad0fd856f12feb8e1538c2a38ec3d13d7794161de3e118479d1c1e2b00f1d3db3088ef77dc59c9f5370c01508ff77ce1e26de81f5aa88fb4cab529bf0b417bf0ad837a2fe88f57060422acab56ab6bd04b4255e4b2bc46197003683449c67de84db758a39536433f6db32411e44557eb6b1fcb46320093a43d43b9eb988e6a2f2b61bfdda4a7c25684c76d6e669eee233a44dcd1b654ab50631455ae6a6a3d6dafc2165ad5273af0d5cff61b6c4a8ad39bbabc9c4a1ae01a3facc977fbabc5bcd127b0eff3c5b74eaf8e85eb520ca6106f04227cd953a9\n\nInput: ee6f4a1d83fa81348e0f4f20ba5369cfc7156397a1a3085606ec8d0d6f2ddb4553b0c1a46c6a343a1cc08d1127e1e84252c2279ff1ac4697503c6d69fe6a7b53d67720052a275e4ebf5dbecd2428beb1be0236c8fde377a425ece6fb51b1c8b5ad25c81bd807a438cc65f52663b327cc553a73ff85d9ecc136c040bd\nSHA3-256: b9c603b04b16f4c97e775249584f2d3a1243aae1e15785fe46bc9b3711e2ef77\nSHA3-512: be5ce65df06c490e4f9ae5976193d82d216e357b183a8e59680c18351bfd9047e6299a54b1ce26093b2f05789ab29dd5f28a7cebe98983b21d8bada77e8c035c\nSHAKE-128: dbe58db0264066be2a7d2cecb07045300e9e9539ba7b3d849286bc6031bc7d8563f4005ffa2be7452f6403d1fd4716edc5933d1b542255b8b13348e77875e554629629f9d403766846bfcbc7ef5e5220ad5337cb428c1f91b89591e8c6b868629b7f941c5ef70f29597de36e902cdd6f2eb11b8809794ec12462c860978a44b3dfc1831dbf45171c27072e3b8038a8abecaef436113731243ae4e91faa4ad17ea308a79863b7c15bdace208bbd53ffc0461a8e58312b8ace3c78ad559ef26bbcf87eb1d5c8f710a89dc76d58d0a74da99c8d1ee5e25e99c6ca0bef2ce1676ceafa2a7123dc2784d1305df1fc3c92c0335980c327c767e76c274aa959452f01d0151d7cd91f88e702188f5c457e9285bb620b6c117d62b4d80c1e6f8786d0dd6fedc668d0834dc6e70c0e94088dd4a1d584b0f4c49ab24b080d83e2c78e6bbed1bf17743ecd379ba166022d745c7ffb44b13483f63935769aab711806e6b0a999adc3805397d9c378f5044b8bdb38fa50952009486f88b358121be9d007e14e347b6608c2ff062f8a4415a178d0c409e5a0b2d7c0e01e2aeacf05a49ba556a5ca5b60c6e28a33310880d4c96a3a5d8d44aa374a77b4bc55869a99ee06a725d5d8df8445d2cbb4d21e6597d9ee58fe6a4105ba9532f4b47acb77c0ed3341a5b3b4a578b088c81b29fd80f28449c9f5c7e188d423b57f8c7188ccc6dd94162f3caa\nSHAKE-256: cfb3dbd092250c22445e77f3cf3e348757d97faf3964ad104ff6dbea6870ae37f94f5e5bd2164ccc93cbeb3782261e0b20305f7cf3c936949c2918a9a9264f1f60e2a1107f2b7b1b88af6bf70e3ca2ed656244025a87ca72dd8c8eb7e4054436b6e1ee8f18ffeb32e2febcf6f0b6315ba90a485ac16ceed790c3864b262a6ef7bb9c52db2b5433074dea30d3b52e4cc500e5411b3c62294f5cf08710cd538b16224f6a78ebeadbbc4d6f72f8219306b4fcb32fe5572a75e2b085562c95d0d1a30e2453c366f61d59646a7dab3c387e636846d8ca1d1890a8971a011711f8dd0252cd0cec0298cfe48ac8cf053a9bd24559db313a5ffce2f368c4c42b62c43596f69316156fbf76c4dc0522a3a170fda2078eba14a6ca5fbe829c6981d9f85a42361c41f8dcfa480d55d021e0648863a330517afab53ebd5f5330d3ffe6e8d6509239ebc1b28f9278830ea221ab0e3a0b72f44260ac0dc64da5ceac3507be2639a314f2ba665993c6138ed57a9e4506feb2557f3ae719310623a2926c4af553b38b68471e1526509ec45a237c234bcf96e4700eaf2dd5c0a8edcfbd40dbea29b6ebcc0f09e65b6ef4e0ccd7f12a5b7844921d499247fd4294f0836041d12eceab0ba03ea33786f4dc267b225f4d247fc4a5f44003c14f77e93635e7fa0e2001109bde540e74daada52c269632e6989810a6cc256972ac9607bbd903ed571e0c16\n\nInput: 34e6324031346009d2609987de9f92728996a23ae893e8e791fb044301dd42b245acdafb1ed02957749e8a90c2ec2ac97074e5c56e674f72e39a8fce710e48560b03da9daf41d4f515a2416facbdd6b2c9346ce9690810f93829a893eaf8a1ed5fd92651c9395f5d5823412a55570aebc5d87b319fe3e0e472a7342931\nSHA3-256: f9ec2c4638735cea016fec3ae1841d8539e7f53e2c00f26130f5ffe6a528e018\nSHA3-512: accf81b2841e70b427e7eb449f5bfcabed47dd5b860dc8205517a28ce48cd999723c322e48aa3710c49b91cf66f4934de71f847135fe3d572bcbad00fc1171a5\nSHAKE-128: 3479c045076ce92192482dd6444ec86e28caf8f6511f4f40229ac61dc36a1697a4cd3165093b6f110e9391ebc739b8723712d3d213ec814837b67080b9650a7e7457d1fbdd64160a714829083c485c04dd14506add4452173cb3cba37881b467b6bfc7c463915be86cbc26dffe52a6d8cff31c2eb041b8c79f3fe4e", + "c993bab07d5dc8db74de022e6febc5e980885fc4579620503c92bdce83acedcaaf3c7b0b1cf3831dc75b80c88ba9a3b8345b251828fe1bd337485980ad90225e1594a1fa334e2c5e96c1944ce0f325920e3a4e7d0ff09d358d482f90ebedc787cdc4c7c2418ab665942171a1a15aaf413bcfc0d0f2f5cc042ca12ca13b3c17b1d53661f6eceb1bd8aa346979d75f95a992009f2717b1a3b446a15d7edb117fa776286ce097a80a18723a6a267d544fb52bc226227aafc012998feb4d79e324e67237080f61204dfa14169f7e4b60dff077f8f1e45c051423a01caa09b96270c63087f5b069ab691ec814f211784c6a5393f9e03a8af680e0627aadc89c92f194469de78152b9533c375b809111df7597317dae40a9918902570a7de8e9b48448b21548cb320e138b6b491ce6b83af90d9ce382afa10fb899a50c9ac8cdff8dcc1596540e48045872df3ae2d50fced17336003369f8516a1ca1216eb82ecd157bbf4238ef7d82ed9c2f981aa6bbc305e5d27d943f82de78535c37d1352c7c8d39c65056008\nSHAKE-256: 72abdb1a7cb78b16160592898e26cdb327ee4b364b8a059632878efec973ca7673ddf296bf31009dd2e57dccd6dbf6e90d5981d8688139900576fd64d18c72fd135232133fca1992aa998cf119fa6d824ff85f5759854cdca26a3db4d2ec1695c4e5909ca9e1ff702b16537fce8098d25ed4c9f9c4e9af2207b0aba3c173b24423a28f2ec9114a98a40371007f3b6913c7e848b30d5c1d95e89c41ee94556f86179c638e026de0b4bc86b17f84d453ec7726d0a1c6981eefce687a436e00c8290947b5f6db04d25da4f43d7a4b3189f307e3a225356075b16664e6300bc2a807b627b3fd009d69488e2dfc71d0b80333ac39eaff02616721eb711016db1f428435db32f7182aaa119fbb643ac8ad56f3b28ebefabad3415b789f27f279edde1050788c029b8ccc6a271d126080b7c2f682e7b7450c80cfe900c40f12678af974897c50282d2999d65f754019c8462bd2700e241505fb1cee22727d2e48af7df16a0798afb27c1677f086c225f2bf2a39763bbf9c5d6efbbcf0cd884eebb9e200d03ad2dfe14027ccb4e0dfe681897f4b57facef27fcdea251c04a1b6723d3698333e3287c15da5d0fbeda0b69b31c0f552072be54e498c9ea8e14c92a5850d0231e3dd9cdd811cec3ae9df1e407623d54c986df03763b5c822f1c3b0597f6fc90345d74946709ef886c51cdea9ce4d5c37fedd91603e8d2f8663b3f983eed541\n\nInput: ec5039af0779ec867f2c69892809ddb0a1ecbe61da78ab75af94c589241f0c36dd44fc89c43e1a71236da6c6e78c202df425293eb6314fc31c44ee78b748cb2086107720a6f1e11611a5236fc0d5e76ceec4c6bf1dc17877789f6ac8268dd547b0486f637421418cef73fc5a2e823e217db7ad950f489ab229e7230c291c\nSHA3-256: a473a599d897a3da1c8fdcbd2a4512ed8416bd089c5037109bdfc84f80e1797f\nSHA3-512: ec7047dc72674fbda3ee35b400bc1f884ec360419fe2eec376829c3194882e1388ed09ee0ae56f586f25d960acd497a988a6495414a9c233d9f766cd5aba3b92\nSHAKE-128: 572637b19cfbfb8e47c618a28368da2c666f114aff39be92e9a5eabe31ccda14fa43133ad03b7e6a2db54a8251671d041e36d49024c2bda3706b53307def1c2d4e30bc1ccc425729eefe19404ab6a87279a2da4dcbd751acec101d6399655c0b4e4f25457f1fd8f46e68020c788948e763d3079086eb60acc2defca9f61e2c40ef8290dc6ac01c435d9959b0a23fd19a550280cc9c2d73e8206c118dd4f105764c95168ea767e9d1e9b27b38700d6bbb09f3e777bfe8f51903b5034c8a8d697907be92379fc43b6f73bd742a5a04a5f3639d84090dd4751a0c15fa583150a12c186cfe6a19a188c2be7bd10d562f7af8f35bf3d67e8f5cd53edc3b2aa7ae017790dfc4740b9b19d968b3cd2aaff5b4f9c00cf7f8134447689009f4c2bffcec22b16e53fc8ec1dbd2ab32223f2d98e745bde2438b4daf5c0d1d2145ac5862ebf59c28a7bef63a6e8925d70fb2c7476ddfc6c82f4b8d6fcc3f62526788f44567ba72051de51a4b9f59910e9d94cfeee78ef48fb5f30488cdc0909d93fe2d2182b3266320d1a601f917c8d7829c80eabb8993e248c7302e0d9e454d43e219f530b467eb6981a3ad877643a24ca50b80a5e86be6b55acf36df16ef085b8a43cf839e1ceedf7753183dd42e84cc0f813a857ff9597577890faeb945402506d27de41e8b2f77c4c3e328822a2fef792ca49fe51a986709b176b08ceaed41dd3fbe7b58\nSHAKE-256: 2e8754af8dbc1fa132e4d408e0b0489beebb03ad3d1b1d550dfa9adeef7094add624e492b2f4c7103cb24c62937901987bcbdb6e4e1666ae8507178f715539b7908b8069d6d3de87cd04eced6d500633db4924b1d6219dab64267373cfcc28bf6884dcd1e3841d5f4365f068e4a4c494f39318556eb1b4172375969a062735286c0bc3b29a4bbadafe9fda3139716aed0088f6ae09a1f862fae61399a2b2ac5abdee18a2fef8cd4dbe82acebda7cbc097819a66dde85d14fd6087947460a32a77bbe252acd3302c2c9344f19e4253235456713e8854a4d23a6ef5d8854a3d0a6762618509ea7dabb3239b4953e0c01ca31fe0d6977bf23cf36f35a3dec33555e1b14cbb253622489529607eea10b7683172fe280c184264e35a8b6e5167d79d51b400890aa0eb66eb0e066b285be46d6a5e47a03ca540852e4840fbb3382f0553f7e08ef65b98ae48b5e3e82cca46b4aaf85cdc3618a41f0cde5c7979990ff67eb8c895b605a165d276571b64bc8b4b9ac9448a0031216f6f1047cf20e5b068c07df2bef82e7b5b6df09a3a06543ef1ccb4b0677174c0a08612e6500da75207a8e6d799de734747d8ca9834146e414bf2a754b1b5ba4b0f74107289ea82d4ca4a64d8a4de9ab275cfda1ca200e7bbe7956b47942a81b584e9e6e894710722272b1e2d2c373706597109441438e22eaed83c0f17c0aad9ec93979ac4f87492b67\n\nInput: 68ce168e461c0ef58050cfa5a8d0e972de71b6bad0a8030ca6f897e85fe7dfa787583bf18a7e609c6e05111e35e1eced69477a4e26a4b011156aef475866c6ad41bae79da1be3330640db24e21f290ccdf03e1b706f67627cfb1177f694a75e3733b2c0ee9b25ceac1c86f5adee2f2dedcd0e366a9b5519c96a6387efa3a24\nSHA3-256: bee74e4eb770d8f4e061e9c708f1916f00153832ab5e24ebbf5e9b8b30b542f1\nSHA3-512: 13612bb71fb0f676a862f119be44ef04f98074e3399bc3f0dbc55af18fad890cef29e7a381400b8963f10edd02374a3e372c20c66a560608bcf8f06e9759ce35\nSHAKE-128: 39effcaf324adcb0fd28758f714a94236b3a4118e09415e44046d8845dde51d916761f5728b40554810e4542c67736a118afea34cb7cc7d87b645a9d2d1cd6350680d01c0a3cc827cac0155cc41baf45c2ff82b245b674ac298d3369b0a02ba279fa3c6f6fe114018313149705107f3750c16f36df52941ee3c2f28b87413eabfa4d8fd0a574aa87c25e520c78f3fec5ccf03f6d35a75e3b9366d37058bf2cdb8dce5cf0dd64f8524666bfe17370e6c7f5105d6425c6564b47d74f79c81501776276cfa784d4a0ea87fc91af461936f9687fb88adda48a5f814afb6c57c64a57bee662805a01dcf8add10aa1d0b3c2dfd454f9cfdc147836a820c878b89fe78e2546943041e5176ae91e26c65be21d1922385a9f67e157adf9a64267d9d51b41266e368a5d6eb61c222bae40ccfb88fc72c70835a70291ebdf83c9ba05347bf2e2dc1bd92c66d8cb9bd6570435efaff4f88385a32f5abc46ef7b58b971153f70b2ef657408951ff5cc0ee072631199542e69f630d9378e01af68760affd04fed1b0ec9b78db747b797c216a00cf0e0e7901c17679af65769657284dea615dccd0ef48bd34deaddea1651a2b67d149ae65c7393b304c9fb90017851421913d289079ae61a807c5cd9d6bc6803cd09b369d14b480611b30d4cdaddd9c4b2c794bd3837620aac9952c3c24a68b9aebe05a3369c07843b4357e62e3e1eac20642afa\nSHAKE-256: 56b4dab1858bc936fd304a649f05d86d93c19e0b839516a8b781d6ec7b6b796fe86ea4a30b5a5bcf1f23359820ce907c1f71318c2ffc3d57b7812eb53192b9d35eec73a755b64453c06621b8235ad483db7071c2d83b508750c89517cfe9cf439620459c4c3151f2f360c5d55f68c40ce1f0f1ef5102892e9b931f95cc462bfb54c2c57581201dbc7a61e25000577b799f163f454e01bef1f5cc8a721a60e88fb9c1a07afafc989cb818a23ba9daa46dcfa981213f12e3a85716ea51ca02e23bb894e54195abb9a51c0b60dd4d066124e1830ac8b8c48fac68f8b0b30095a08c051663de40daa3bbce76bdf016186559342b122e7bd61d7af31b5574d28f9f4dbd940ed6b0e41976946af256977eced173030d86e44739d2a882447806d37626f0d824584dd8c3f71ba93a3d9fb0c81a71666a99e230bbd1605e21a1fd015348f6cf9473aa84b70c732fdaa8873d6b2d739f1394b49c1eb7fa74613a051d425a22c0f424d870c78f47917293cfb8b56957eab89e8995a73cb3da237191ab79fbd6106d043db7be0d1905ec88820741c16b55a77c7507f7cdd667bda56ce2cc53418f5e51cf635f3da4028aa39304fbc2ffd048b0d262ebb2376fbb69234b4d594ee07c87a10ed333c5fb141acd14eef124a7cae00c773fb4524c28b14966cab9f5f89b72be484488ff1fd5b5d15ffde25cfbea0b2652e398fcb4c15ba7b12c5a\n\nInput: 37c613d7467c9c7bed6e3b146d94b981c5dbac9322a2407a4fec381111c4bda2f56aa4ce4ded9694950bf1ff5794505e12fcd2aef9985f28645bc5c486d063970ed2328e139876a7ebe066e088161058b7a05970a83d81b1929772b34dc1edc05094c5243a97b9e16a1a8ce89555d8836e9224d2414dcf59f6740640379e24e8\nSHA3-256: 78834b13ecd041cc6fee48422830219dbf00d04c4f8b1122a0681f4d7c7f8fa3\nSHA3-512: ff7763b88c470469b610899f7c10a265041e39e1f10e4f03cc97e5eee4a264e79864da497f16d0e9dfd10185cab9282c1a0f00838b916c8ec54f0414c4d9b13b\nSHAKE-128: bb0367c0bf50c7cc407c9d99dc9a71679dbcfe3a3e6e745f42f147c9cf15564732a8aa8a039142bdc1e2dcc37fcd8b6fc6aabceb5ea1332a7f944c216f99703f19509b68667393aab5980c244b67a1baa6e5f0520b23ceb0bcd1ed17e2608a9caca086186ffa564b1014c202a5e8499a55ea6bb60a03727c2fd1f2c586bda213ab896fcf4392f0fd18b26540362bf156ed4582e5688cf8a3a64e661abfc32207b18f9e1ded38a0cec52b8b8d8271c27f73c6be7d11af68a4da18cab65e4e6499c1d2ecc59b5bc758b22b75e3aeb9670f059659eb35ae2381c2b1708b8c615f02afccfeaab1a9a814c47fd10d098e7f10f0c4a83edc2d588061b45d7ea6d3e860d2c03a5dd75172ea1392943610b281166172847fcc2fc87ce30f5263fbb7b4f4b6e39ae8b7eb3935923e9a8f572d2f95a70462cc54e0f1b0bc5839cc74e5c719a20837bf6626171a1326b5a3feb3ff424a9d2926e29aa2444718813549b0d13183af149d8842981e6296c4a4bdec9d1f04a7c7c0f0879f054b4b1107aa542e6397bc1c8e598cce3fb32654b3", + "ad6ce9b45135195697b0da42da3646e0dfcda3c148fee2613d5ca8acfa04c505e63d6828f066234e1259c4c113ac9367ab7ded34d52d657087f5ccd6818303c7b427b4babf8b7b08e7db074d66f0190fdf7091df7efa51169ec96772c80bfc523d275165eaac6af18d5ba428f5c3e09eb59e6af8\nSHAKE-256: 11bf70eaaa3c944971ddad23e1caddc862a2affde5ef454a2414d0f1a42a7e7d28d7858dba32e2b555c529825fcb1217001de6cf8cf012bd42fe32ba5df6af7a056c85f7d57aec4dbd0fb7e1277d0cf2cba44a2d43a3689e3239446b6520c3e85a698e290f3267567fc1c7739f19096d4885dd941d9981eaf4c8b817f9df23b15047bd5cace0394c9b2a3293391e87c08f1e6167fb2ee2c412b693c36734fcf331378fd6080358380d24e44e934f110e8d4fd2c3eca427a8973548de7f818c7f9c226ef2d5a280c087305f0c053970ca78f6db4e2ee9a2bdff0194c6f2fd463aee7a64326d086db73d0bb4162502b6c37765789dbcd509db887ba27f469a8ea85dbcbcae2a33ea5ddb1563d4276e612e79ef1fa25cbf54141e0a8182b46d4f197633add70d0030961f26cb26cd889ee90f306ddcfb605243dc5f7f584234a4e3665e66b73b8dc5b97df2e7b99d4e10c0fe7b0abac8cb2181dfa652aff7304de4b97ca739bee8270fdb88a18fb948bed5d999de4e567e836042114703359dc59e054d6e27a689c2acc60be7de6ceb9a9029ff4d3ba1381ebcfd04ea42bd1702c8f0a87f7d9de155910d29b22dbacdd36010c664e361b18d96e93df0d1c6a082fbb323b740e9fc8663d4da6ad910e65801d7548cefcd7de346de528e6a99854fc8e79ebeb77fa9c4a5217e7fee4f168c3476c32d238115661189373f81c4a12ddc\n\nInput: a822ed3dc2f1fe3998e2d733821ba4ea54e9595658967356dfd525e2e758555e2d70acaa6c993df921de4beda0bd459849f58bdac8eb4b06fc08e34ca5a0a9f89a2fbb8c84e63c97744a834cb5c63b8821b06dc6bf80b699cd3dc2aa565aff75979fd911e9ad3e706299c46dd47d42962a9b9db3d3146736a0397845ed00eb904e\nSHA3-256: d1bc17fee89897d851bd9d5f5362b999cd1d02639bdd6181e55256a536d26215\nSHA3-512: 252164f74eb730edc743df60b5e755ebb7cd6d451d680f770c739f6ce2b7422312e36a67b5400efcca006343ca7ba2e9e716b635674e26ef297ab361a7fb65c5\nSHAKE-128: 7f7bc9bfd0dcb80134667ac0fe22ecd805148e76c4e6fc411746a771ba23d1fdadd1b76b928805a0da2ae5fe7e0870561c21af3ca5bd6880e5a325de0a485c74283b0e39da280a599348c6983518545526d1ccead1708863f1d2f72b505d5e95fd0479bbe4d0a4efa3f3784b02e22a6caa53379514df0bbd7e0c10c18b2a5f13af878bc7c131f216f259967369d51c25042da6bc0d663145e69397dd5f53eec7c094e1e57216ff1810eaf047bc00ef31d6a1086053fe401dd90ce5a337cc24bbb4f90578023b01526df2b96a448e15fef8dce2e64b03db3e5bb450c0521516ede835711cc7566c51073fc30fd395223998db6f7bc98a01a040507be97ccc7ad64bb29b3db066b8214072798f02556429969a15ea7612c860610b7e7d8f618cee9a0f29d16c2d2e4153695fa64d3e31ffd7171382b51e125991a6de4246c1e5a54fbf29d7516f66107cb71c206dbb24bd24cde5f8e24dbccaa12501bfbacda8eb7d93cb9a3030083a9e0a6240fb5354e8a9505b1192b421ed66888f8bd4eb715337620edfa9c3e90033276dd0b88086eccb553495b6a2a7ffab378cfccc438f39bf8db1bf1c6e9bb96ac74ba0888c5f0639d7940180aee191b41b1bd4c157027ea3755c11b457312836c3f30dc552745004ade8ffc404f71975fbeb68ee4d9338dfc2f856243f24eb49ca44c4b6468ff4ac9aec62831a0ebc53e55c4def039a8e\nSHAKE-256: cf1d4cc392dca0081cb89a1f177ab711a3b5440240a1cb6e832d238d393c4513a8a9d002a73f3f8395fc1819f082a52758f141d72c5185f1a2b679d4c5010ebc6e8dd445d9e4a2e310e726ea00be29b36b870a37d75649d1becdbdc7afa561364b4236e580a7c30898bda66bf5b00d4dfbc19fc11969336836807d81c8f21179b9e05f65ebfd9a919156cf1b10cb0a3b53f7bc7ac460c179edc0e2094b7052fd3719ff6adf679a7209bcbf5a1c8e6b1eada056759207a93a27504fb6d8f42893dcced18087f3599783648c8d11306a7e1fae5a0f7b192635907617ad3bb23b18e3f02c2b8243c3a1ba936cf98b9f4b30087b53e51e0f686da136377cb96877d75779521006f2c07eb0ca3f6b1a1985b22ea99e481b94fbdd516eb4ec5f4d2ab2b8a657837fbfe98bbfc534fc8e341d39b557d8326cdcfe8ff66f59f94aff9d8027149523a4fd658d135c36fc12fcd621bbf3fb566d45e868b6544a8cb061af44b82b441243b9f998c5246214c6c74da6f90ccc8711db787f5e7ac44fc8da63e970625a788f71585b75eab40c0aba1d84512a3b04ded9037975299ac7534c44c810380f768c93dd621ee022338b81bf12f5009d58cdc50f250f42f336a74b1f3f50a798fdefd4c4b282fb193e2b5af73837f954b5b626f7016b150c218384400b2bcf4d53cba69d768a463342aa1a546347fa106f73c91d3cce2496a43f480cd8\n\nInput: 93d3549d81b752655ebee995eba6a3efacd208627ee7d6b487f60e77178c7bbfa26120fba577f61ac86319ba22fcab9703dc96152f6a091fbe6ac3f35fa92c9e3d2a63549c8f5179e390e2fd373c27d492e580f0f854fa44be656e0feff416304307dfaf52b1bb50190bf4689b000468aacdd8bbc64095193d6ca5c0da7d9006b1a3\nSHA3-256: ecce62ffa6585e79d3c3f72abfddae91b589da964399bb6360f3f072ab38dedc\nSHA3-512: 433b5b162fd791323aaeb44a931434a1f2a8649997a1bd1fef9de9ffe8376ba67cd0a343f998a21a38fe87657591bdbc095af389df5d2176387da3258dd2c0d4\nSHAKE-128: d13276f14cc08ea815f0e74fec9223d21ed02f80d9b45c0b15cca7d11d40725919d7541fc41f91f9d04b5d8704952763575fa1e4229ec0ae1ff47821af2871b73ed43b334dae0b8d3e7e256f10731b969b46ef6e5329e86afd96ef9531967a642586158f0702473784155a7c6f4cdc9b5ba0fcd6e2da23dc32e5d63a80344365ece7dcea679f92394ea0a304f90ab8ba6fb5cbdb29b8328aaf21fdce6e0ef087953ac02b95c38a7ae114966c98977cee0379f65fb2b49013a6ca20cfb93f0e83215975c64de4f6b817d0deededc18b8ec7e99244096d86e12f30a99312d0fa203a29fbd1c28d0fa5a59516a3bc64080c9a069eea2f35b0a92ac97bd9d4af4c819f84363358e593e8c2e39dcf00863471929935270c84e64ef955b2affbc1a13afe5c34f7e8ed494881070a350ff3a5f8a93845fa8c559e006e92d0267f5df13293d1d07146ebb8088b7d5eecba083b43f0b5965381c196f59bb39fb9a9245589b8ca2e7240ab470d0bbd2c51718cd065f5907b9d09b61d8fb60221bd35ce9caf8908c38482ae73a460e94494263330e6b541b7459fdfc5a2a5ce28bff9a580b8d35d0f3516b0c772ffb1ff8c044fe21136f5b9a46f48dea628fbea81cfb54765671750b145eb7a1b5afd98cc25866e93351b2510e9499ea3e1e930284b299fc0dadd89a7159b7576c9ac20e04a480092daf09d0889897720b36e53d0f1fb64df\nSHAKE-256: 8b4b56492b2815289538e7bfc086aaf4b30dcec3ffa054198b07e45862a09a9cb62066646c69ce1269a60d3fd80e7761eab1f93d8af130a3b5605f93c333b03bbf8571831f554b1cdd0e38a11dcc169d4e8ef797dcf2b06028555fbf6082c3b597edaf8d6d7cb18ae84ef8d89006a02f304d4d27a952091892d1e1f4d92c2ae329dd75aa401163d03eda0b69118d11dc0ea82574fc086e4be968e204961655adc1c3e4d9c038b9cec0107ae34e8a50ebb21b556f4d99f62767aee163b07128486542f33454d3a0ac42f7f5ee2754c10bef087ecd5f42de3a9bc160e145c50de14cdad9d83f1dfeefbcf42dc13dfccebf503750748c3fd01574980c00db1112f621025858cf0bb669ceece3a07f65b12f3d5664296e05cf7a7a18084122e48348256b29412bbe534334b032b6d1281f45f35ffbaead248308c99ff96a9198ee82a00cc3c219634077598b356bc033d2e618aa888f922a000d224b965ce82bcfe39d12260a48f9ad6aa2a899089cdc770cb313aa807a90d625927bd3b4c1f5cf85270d743e6fb256367a959ab505f43ee758d99b871ede33f217c30a2ef1c9533a8cb16b50da087f95fb92d5c4d1d269eac69b62ce5fa8fe918a29d2dea24d4645ab4b26794e6d79217baa2d8b0d1c12acbc110a344989a2ad0a5d7bc0f54b19fdf95ea98b0cebb34880b988181b25042e1cc8421f3d1f6ba382829036032aa461\n\nInput: ce13d351614d4b3a8433156a1d8ca9da3865c08cd824022c836e2d204f8d05ec61f7edf59fe8a3fd90bc50314951b58dfb7f8c56ceee1fe400fa25d150e3270fd789ee2823b01504457d8429663e0ba78ee2c39e8016bcf2c9e1be459dba5a1d50ea3eee5b91e09e29a755e33870d8fbc3ffe87ed6425b4ae815833e3f7c3c32c2ad05\nSHA3-256: 283da78f172708fc0058f128a74214067ce44b708286c483d63b9ad51fa4ede1\nSHA3-512: 54e9b4afab2922f39b6186fb5842bcd8c7233ef5bb66785917a4976f63889d2933e9e4223d212add25830dd490227d97e760e4d4fa657c50ff7914298956cd5e\nSHAKE-128: 517512791fd67c6be32634a5ef21341c1fbf4168a7b6bf456625e66efda6350b7db4ce1f9b2e73bb54f334231b6455359912887ac4052274707d8ec4e41907642553f95d58f94f54f7f2290a42e50a13cee9af3bf5c89bb9e6ed83f23c5e8c692cfde82c251121574cd25ecc86ea3c2ec31267dcde8de572799f3508cc0b9998aeaff74b6ad70f0207bb06fc34e727734ddc07a603c6851d3356fe31fe55662c8bc36fb97214e7179c0664653239061b4583837e30a67d07e206f96187b0e42e68b68ae8bed7a40731ece4eab6b2b89a2c5d0078e2cb6c793e4dc1b556492ce83726f34727fd253bdb1eac507ecd33d473133e4ac55f208dd8d2e4098d1cdcb17ec96cebda830db449312828b57c1ceba46d7a6845a7f0df63ca646173695051fe13c5b2eec568b8650a2eb8ca5972170d9237cb5000f24d9b985c85ab6f832ba7def440530a3491d4870f8f5e5bd7bd4bb87d4e9879966fc02cbf06360355b7cb6cc924a2e539a3f5b8562b980269d02d5a67db8862c2146a156adb6808cdc08f7940ef0b33bf5bd8c60282da7b828870d48e2e2e634e2a4c1ec7e76bd5da938a8b5101abc10364560588b6066129aa312d0b6dd24446dbe88867be381e61cca27cd572d2f6ad76411a25911a10a8c70636c10b003a2cbfba25ce2a537f533a286cd0b317744cd563bf68a95c8480b1117b8b4b7c84c8bd30ebc0cb1c729906\nSHAKE-256: 7ab3bfaef07fe0bd3c45a7bb89942d5c66d7c74a3cb41926e03b6a69d19d5b68595cf275269c792e01901bcd62cfcf05e817379ea66ec09b861de0bf48b8e436f47b43739c6273e5b81698499ce3724f1eeadb99913c0b93bff867952ae8c3d427d751da298309852bfeb65825a6f653c360917fc7fdaf60363fbd7c5944febda76975fdc0b22fea0a69634fb3d", + "d10001cf631ba94f2ece8cb7a85c8cd349d925fda6cce5c173e19e229832020fbd8fb87ad900ae5cc730ab38fb156d176b76abe7d79374fad508a7812ade43daad487668d10daad078cb37f339d0bda87c14d4e0c5f7cc1ea2a1eb2b648b9a218878859ea837eb74f159837d25fea9c6f621cf1dd9e1e010e5f397904040cafa7dc35d87ff7aa1ddb3e20f1e827b1ab5c5ce0d247d7d791178365a3af3987e07fba819737f9326ed1fb8e8d95f15308507294067021cc3e964b09b2b3da9b7e100d15fa726c4c89206582afc2a6688d9a8a8638fcb27d67ed1d1dc5b31aaec0ae3714c1f965b6b60da22fcd5314abc5a85b4fd82c3494c151a3fd9d46d1f22bd3326a11c9125a0014e8b9a935c8fb504b20fa061503675dde2645b527b4cb0d7b955a07938e3ed29ee3ec37475b9bc1c2b3d338ab0f3cb234315cb93370d76124828c59fecdd8e5f5454eba68e5be8c9f450f0a73a48d7febbdc3a924e6f8502143f805271b4db2ddccaadc4cb07064c406c6\n\nInput: a36332dc9d1474e02587a0575bb2226a7b74d1c391dd1de1adc552f2e64a167f1886ec7c9217f128b07555fedae6bcf2aa8ecd4ee8a582d84d6ad252794cb3316d060690211997e285f629c5f264c39da1771d7fc10a678ae6f92b079e81aae9abc290fd5ef4b30f4097fbe111052786043f649f4f1a7ddaa56111f72db2950b37a5e58b\nSHA3-256: c33d885f5a0cbb797341396ce23a467696fa9d95ad5573629fc607b83d57d010\nSHA3-512: e15170e4cbe718f42f570151c531acf88e0b448ee56a836553473fdca1d73ebb19b9b0569f6cf15214445c9e993e2d219ccd2fbb6c6c00a578db1250a779046e\nSHAKE-128: d8b54fc3d921d1a2262655a51cf14af350508f2acd21940432b86525b27253206e9b14a46641f010f8739918691f051b17b531945d5f43d27fc9ac65f00372075ce7e79f3ebe908488ca5fb3198ad9edc51d394e3a6f9ff098a15a44cdc5c7bbb4cf8b074a0959e39ab85e1f8783924859ea338c4b99980010827cd174b8340ab5e053e0a7e501467468ccd19cac702ffa77529c1fd379b71fb66fdc54db3ededaa625e3711fa1b6dea9d31fee8a26c977c1391848ba08c8ec4d7900a71033d048466ab417bbd721efd7126f109b05a6942f7bc0a844bce6880547ace57ef2e989159ffc69ce02343ee4bad123c588c75f56294b9c5fc25324890618086619d86fabc9983e7d4cb8e8dc6cfb3eaf3c8334ffe1e265ae84ebe38958ec9a2a4b8efa75c50d1144a6bf87b5b6f5b8c08bff47153fe4c48f94068e204281355e4ab5ac96e4228abbf6108df5016458bb7e6f257bfd63da7ec12db754def0d227618aeb8278241f72bed11e89a7c8bfa58db7e80c9ce508fd9ea062852c3d90e6676489fdf7ea2c4332740edd386594e86f5ab6bd7d0d5301dcd882479920fb91980898abcee5b471c4f8ab8d4804a4e98c77f92cfe4a658acd630ba80b3ccee5eab25343c31315b4a811ae78c180a1c217c2dff12668a727419229b07408a9164a566956c871c9d75c36ee895c454dd5342c018f8571935ef70af7c6b32b531e52f3\nSHAKE-256: c64022e9e52618e44ccfee0b920c615753a12f7f8e85f3f1ae144d3d481baf19ebeb5253807887ffa74d16ee67d1b23c5fff4ff8eb6e8e38f18fcff48591a86331d9a1307a132df2f3d1f2a16e16cf0a8ba187a6ed27d0e275b48409b3e09a0841664a0e716a244fbc7eb485275e6672589697ca313f64651e11e74a64c2b7c847d673e18f0d79f8dcd8e81a4d4d3bc2fc7dff81e604d8b5a77f39afdea80ed1cf1014d4cae519b8732f4cb2d390c7b16b0dbef4f53de34319ffafcf293e248a054a191f45ce6a11aa564621fb5dfb4c910ba2562e627c01eae49451a5a2f9f6df90877c7770be01c94946c286237334a906fd82e653b2c7d6bd32433f6aeef0a6d42e93930794e3acdead02be6ccc15834deb057f7e85552d2a38c9032f548f7c5e274dfa69494c7066ce185fc637a82856a6b2ce1c7eb895592a9dba5b9567d96b594e394cee241c42289542c89ce07632c98ffe383ec0fefaea2a81ec92566bcc811751c31a7017c79e4b2b2f0f0906d31d915d7b0838e9f2bf055bf132b9454e2f470f09e15da0152fa0fb0d060b3368e42a49b0c3b791a4f98863c7b612469e65cc03b2a3a74e0ece49ab14897ada9eb777fa63dfd81d5de10221137dd32c9e4c0481cd30fe1cd8f432d1597ff2dc644216fdd944e6dbec05141d1ad8ec7e0b09fdaaed3b4113fe94362f59c44e47ff4c5ad7de99a049635074adf11339\n\nInput: b7639c3e054c8b1b1c5fa748f1e9459585e22cbd5548f933a8000414ea4b1ad18753e45843b352581c50a44f2650e5828999af0381c4de516f906fb8fdb3b1a34716c5f14eddf2d3e64dfd01c2b48fdc7775e90971393729855b6d7dcdf382b7bdce212483d712f00c7d6b993a3f70ddd47fc490951fec5236c2d873e391f56862d655a383\nSHA3-256: aabf0cedeee7fe03ced7be95a52f5c0ad3a4f4793f378e50e2094b5b01e0bcff\nSHA3-512: 8278d511be1bdc5bb57b287d1b3d97a16da0400d35e396c95a618fd34fcb7ee11135a034c9d34fbbd0e35931ba49f04bbd0497a163a5f04205f990cbc57968f0\nSHAKE-128: 7bdddb878f5005e678eb9e3fcd868dd9c3069ebf611d1a46c2e6a4e745758a60e3872cc995f98b141b1070659eb14b30a4e734e03e2c5aa471740bea6cfa376c85b8dd794ab825b19b9f2d3afe6b8a13f75db282fe3fd22d654b504a25160a4130c9bfa2e0d3dd60430ec6d1c2f6e42c346e5a40bc594ccf983e28c1c076443575eae8d49d252d97edcacad10b1807e753e65e8df5cde408a20914cf9bf8e64ff5cb9ea12c69b611c7406b9d8cb5168e6737b2d30d50339c0a9c73ab3246b3ab7fd2ad8e5bca331aee4b5df21a377e953106b9b1f390e403532fda41b3f9397a2b23cb81aeca179a6a394c11ad5a57ba054e4c62bf38fa719ebaccc37b54ae81b46c3f8357cf2fc2846805d26631d2c447ee07a079f489e2315212aba1e27a6f1a99b10f3d7208b614170f368c08ed13b9053a5d4c3265db22957c120fe63a767ec9def5c3bca25509ab0a70677340baebc4609d885faaf3e5a651576c247ba809036b3adce1bd573154478f6d78c78600d1777d5025aca4499db44007a1b311f95a053efaa4ff3015a7a2247f53d1c388224d228b27797f86a9728f8d1f831ad3000ecd88857065dfe230bf4fe384cb61ed13d5a275dd483951cdaf36b0b3c86d3251e2c42a92e7ae54697c400a945f7203f3537ee120d9d9d8bf32230045b1d70e1d8e346bd7f61ebc07dedeff36e9e9d2662d7a70543600e20cfa183d7ad0\nSHAKE-256: 242cc0773ada5c7a9795d56a4cbc9b690bf87ea2b884bec0741c139c5526209edd8760f3e0ac1ceff51048f45d9ce0dd92a9a5e1016b582155475662d00aa9893ed6c94d9b54265d0d5167aa5ab37812f43cc2a07e914371d76949059c3c82776d8d702f0efb9d877a5f0b4acc6e87d59701c6d0f383129384d9722903db32dfbd161d69fc845ff2f738630c031677c2cfd43fd2aa7813e6bcbd60c636e5f6e40ff340c5b937171179b01e4a0d74642fa745bc9f2c2cf1a4be45e3d5894f98550e5ac2928934fe7c72102b7515fa365bc5a4b9db43cc98687583df135e107b38b980615b723d1c1906c5a9c58b0d983c52c48ba94878db8cf317ebe6dbc00fd3e5b8e1398962d96be9813f744bd8e297b76894663cca732c4a91a180ebde43c5e2993b11837b9d3e24ddb64b180d3c9254a9e62aa3f6a7824e8640e45cdffb666536414a09831dedb6a8202d4d01abe6531d62acfeb4f46ea0dfb6bed4b410c0a4f6c197fd18e2bf27c70581b382190266607eb8f6e4fffd18e06cd45d4999952bf2061ff4f52af51efab5433bce3a2510407d374d2d53701163bfeda0c0e2acbe64bac15e3be31a17bb676d781f9742e9d34272834e5cd1d6e14a01727f17978056aec039f70014f3c6c6a826cf4797c7a89814eeb1e966e2430f6a28846d4a99a874b7caf369bd950e00d7cb73d8911f3c26c6e11774dabbcb4c1b1d691f30\n\nInput: 574c00bdfc9ab2f7c09ce02d209e975ed609d9ddd16712ab1ac4f592189643e2b10e2ea13a6137359c0ad3956647d9c0c0169d41f5a43dbbce350a2c83e45716d17c7f0ce4919559737de007a610eb9d1d96f19a48364dc70edbb09514573c1ee6ebb1131d26ce836b14e141b963c073bd586ff50125158a5242fd232ce7e7f5d86ad2eb9543\nSHA3-256: 2bbee2795dfdd0d733e7a84f6f0773d003ce1dba900d701777b0c17d4b62a950\nSHA3-512: 8893f3bac1dcb1124cf6d763fe0147d185c4fda24116d5db9a089ce4a39934d54e1daa11f2fc02797f5fb2b38864d8cfbfcd44069e7eeccb4b1f616912477576\nSHAKE-128: 7157859a930736c636f201eff4fa23f753712a2b8bf0251a65b2b0bce24d957b0a2b50b03b2ec142c6e0eb7c30431c4468e9d8b5371bc43346210949d31c8640d253344ec86d64264d6c3f03a41555e94e071c4658efbcfcc8c8bde2c1646a74607f0198b3a96c20b3e93cac4e7024b19152d7ea3efcb848f3cf92ba635f09cc999c1af86c422454254a037ccde5ae45ed4ca7388c61fb7dfbb3cd4757aac4dc6cc689514500b0fe4514a3a274105d132b7c30a960046ef19be35d711850071c9f8875aa651d4144913ff683f31c713d025be987d5897ac63ee573733aec2f818d00099fcde33f9f40c77d59f07cdabf6324ebc610ef8d399915a8171685d4abd66a8b458269ac065b2a38eb548397b7e8976ef0349d588512e8111196e0fa3e65c2a19c9bdf044bb9714800575d6b09a52a203a0d2d8d0e3b4238221ec90f86cc0d4a9b4b3a1d3828411098166a71d1659fc96517d0684c4bd587412c0d74195c86d673a9661b5c824eed70e263664e90f1d6f771e60846f5c7bbbc32ff08a4e3c87f56d5b7a06c31d8412aba6518af73186cf30f10c8c8a0d298ebb59f7bc51fd8a43f2107e822b393880239783a8ba0cc7bf4f475f3b8a3206fb66d357786f2404a30a38abe483edd8bdf9cfa491762f16dfe5ea3f904ca89e1024eae7a30b8dee2037f3deb10c0a071c275cee5e8df4cb13ecbd08236d48662fdcff4d15b\nSHAKE-256: 92f8461bcbda3a94d56701eeb6f982cb8508353f78145bd549087865fddb92f0276c0ef9bf196452bb4f9e15d88872d8231185e276200710682116236418b2eae77021514f5a98ed685daf983e9bd13dd29c6753337d28a2cbb0608fb8a61eb637943a951eeb9b88dd810226055b56df6fcd6112056cb86c4c16db33078432fe093554a275eae8f65c2f1da7c57f51a470b3191df54f13f0c3977af1d7df910477cbc8cf91abf8c850f020eaf6c353a4e321994c332cdcb4783745d24d328bde50ce195ea075e5e49b62ba83c1eb0fc652b5d81a36e54ab022ea2371150ad9eda2b128ac15c24f8775a6e591b919d4c9b34da20c8033c5440ab81040b3c07e2f144dab18f190e4d61aa1cfc67f00ada67c903b27e78a854c986f39ca67a4d1145370e54a1ce2c2d278f54f096359606376e3e8bf40b7be1d1d69961a78c26b62295f5b0e6c9a31dc23dfb4461ad25d98713aacaaef08f6ce9a82d5f6fb91b79d35591f783265d986417f741d048578fd913234a2a2595bbff12857c3c7e65768b4f9cd54256b2c10cfbe3fe9", + "48522ab6cad2954db47b0237a0f9408c0074a1fa68b0fa1ef61923b9be021bb4a0cc0c1015311fab51aa9eacf7137c5b536d1bc889c248f68005d5606773cd75c5981351077036f3e7852d923cccc38b89b01058dfa885c00a949e53182e2931d2fcb173a3a51b6f58a03459a9b33eba2f859ed4\n\nInput: bd9216aa0bb848df6d137e5e0b5f9d294d8e06183c0be2bcd1f36dcedfcad7ff7551a9409d1f91f74759be71e83938c24c020f4995b0e1086b7bf8bb432ee5dca8fb2a6e534a1d39376b04d39040a818d7626587a4b25c86633f6f8c72a673d9880a0d11cd37658acc7a1c990f0aa2006236622c2876a315a025b3dca94cd267f29e940fd98fa9\nSHA3-256: 53c3ffd99923ef24c44d422a779c4ce81a1131c400e500d0bf220def62cef9bf\nSHA3-512: ed4b9d297bb0e65977f5891bffde362799fac57c8e71d9695080239c4e4848be84db2755bcbb2104696081b3b95c1b190a4f9d73c7f960bbac5f8d435b6c65d6\nSHAKE-128: 6b95cdbea85bfa40ece1de7cbd1ada561e372f613325cf3d842bc6ad54efa3ebf8ffc7b2a30d7d1bd163d2e8b75dde7e25234115cf0873080522a1338aec767cb2aefd9288e2e2b1722fb87cb9f82517320b0362a27bc59c6e2450bf80c3cdcf69803f61f6ef0a2b122b6be9cd6d02b16f1547ef189dc388de3fdaa60757fecb22d9d492a299a14f73d898ccf38f84846c4ac51bf8f7970c9a9e95cd7af5dd9ab19aeff18e776b909a0c6616157ddcb2ae86fbe3f67c3b7a8369d54365a772b2aba9b68e679690423a53b034d92a6878c64b0916e256b1c0750db1ed03c91082c3c795ad7723b0b56a8a15ed7c66b51643af31f8ce4bc43f4f584c0c4e8dba038b6a2ad3604a9a2cb600ef50f9b17dc8708b6742b357976e0e949120da83cf67d0c4cc00aafe836cecc53584cc48483434edd0e8d4a78046672e5b818cf1bec03fb2c7c29e945784e6829493f49c3c308f11520472851dce9e4310f093cb2f73b3d0605ce764081f114105781f50029293a92a788e46dabda8a53ca689dc43e9a8878311b0c9e0252d6361489395ed5da897349a0393f57261cdcda7d83bf0a18cdc621f82213988fb3515aaa8a997c7eb541b18d8cc13115720ae8700d61cb570559e7b2c70f27009ed744dfcad16a7f2411c5d515d584e1c70011254e66f7d34fe72f3d649e4b83506f4ff416f77de480515462a51aaec3c2abaef8d9e749a\nSHAKE-256: fc38b53bc8bdf48b4a9ccc1ea3b76d6f6dfb65658971f5fa83e7124335265ce881f11eebf925d1ad0dd3444419aa8cc5aaf7ab92d086c641af0311dcfc3f46cf8d1f81861f0b1e25f6aedccecef792d52a2fdf9f5a7b076af8574c321e6c13ae1f7eba7d0f068d9b669162035fad087c57fe28c648c168d6e69a815394eb079fb250a231dea8f6c2cac96f72b06eab13d366475bbd397a49c65498cba4ea092a93ddd257b1938b9926d5ca06eca0dd2f427f3162c34f90541dc29fbee807664643a31d624b2a241ea7dd7dc1f5193fbc98d0253eb76e9fbfb927eecea9616035c9158443e5b86ab2305ec8198599d6a1956e65e7faad9ad6109fe5c407ff0f46e372a00ce14b20fe7e5135a48652e32e313f6f4eefe5f865ff05200acf1ba68b8fbf4907005450d2c414b9361580ea4300c86bf003c44f3c758d6a89acc429c805cc148f224e66700fd2463dbf858ed751cc59abaa154f0b64df93106951f0e2ab5fb4743388fe694b5b6ef02511bd20c7cf9d13ddf63ff7b31924f2cdce2416c71fd11d1e1eae1345191b180541e6708a00e8d3d6570df36d31a73d36e1643d06b332490b3e4071e97c47b7a1a49f1a61afa7db26142a41c1797d4c65df0934851b6ba3d4e683551cb82254a3af647c9464c80a032db328f35e8e16d525c86bd881da650bed38b273bc661782695fa45b687af8566636e5473c389ec7dcb614\n\nInput: 89917b5c2e40a353ffe580be25efc5d56424d1c56ae6188146e3ce2f209b30c5c575b65108e6888ca5eb7db5d7cf41b39518acea853e741b2fbe3083a27988e1b83bbdcea87e804e6820407a59756e9ccdd5cdc225625228a056f16fe663913e550c458f32d10a6250ed461c15ce7635410faa5b071f8ff3a65c1ad7976ff83f0e181b291e4caa61\nSHA3-256: 7b7b53b54ff340a351310e81b816dae770bc9614f7eaad68c809256904c35af9\nSHA3-512: 3431236679660fc13fd09d7a22d16b566b2c96064d44b774996d0907e0a96102f683e99d1d8cda92d8be351b3d7ecf802997fecad864948f2277a08c7a011488\nSHAKE-128: 4be60d4a7b7b0d0876560cbdaac7410788d490a3d2fdf4ef8e4ba092052d135f6750586359f4251307ecc75823e1abd162bf2a0a3e2c22f7dedc80b2991b3d273725458deaaf95c45e0b448c3a89fbb84dd4e6619aeb911250f0e9e56e62b128935ab11b426ccfa043206c6fb913ea0479f44e7ffffe9730653c84c729fa63fa74da032bc210e0ddb45ccf0e8f670d0028c8817a1afec945234c621f2da33c950d530b806eeb1880086ff4f0a11a66569af904786750b0d34d39ddbc77da8d6607d7159c3e22bc13216b2fe69e0dc580a79d9692022dd274072625901424462c7a7042ccd822eb76b421a98c23954ec8f451e1e6ab981fbe5d811bd6569a5ed765c2e27d5b4a89cc6130952fdf78822edab36745a9aa548da600efe07e9b548dd8be0e48a8ec4c4e7a3107d0a8684bcd07cdf0b164bac2d70ba8873d28ca9cefe7b210e887ef7c245ac0640d9c36e7dc517d80e8052ef4d2de522aa8348138122c8e1bbc520e2246f6fb7ab9dbd68ad35d8a90fbaf8123c849625b32e745c72fb77e415698774ecc01e75004d3561cdadb55a4d663501ca10ef8761b87257fe743c257b001ea7b2a1ffb18bbeb496c0bab40928394064d5778a2224ec13d33df1997d9623ab2fad08c16667e3c2b78b375a49f62ff33955f835fa843fbac28724f8a82070b898cf5a30f204f001d094ab7ab3e6a568dceea8ff97dceea9497fd\nSHAKE-256: 962e382db26ec28ed8935a7d1987e2e882e465178ab9d848ed29d575e7717e0d24daa5811309cd0ff5d53629b1bd46ee15082d82b83f57fa1f2dabde0b6ab5126c929d03fe1b02ce66f3075cda95708d1e53794b79305705d0dca27305a2bd5b38ab10c8c197731bd0efd70b48bd5d30f57805116f2f2d6c409d74d2424c6f7ff76a039841f2e7cc4f3b264d94347b8ae846ac135b3613721201b8ffcb341bf1ef44ba5544a295e7a7dfa3099c6e41f666f769632cf4d6caf4505e19a6030adb42fd16a4d32ea86b587b0f37134322da09a92ce17ad037cfffa46df105aeef74bcc449847b83dd43e8e18a4ddce028e9d17638b87296dfc6987f5b42b810719a830e7103574c4bc9703d8f7201f9c2ae661a2bc3934c065516ff8e3e934a2817230bd8498351c992ec57e837f17ce50d882446cb888d4ec7dd16503d71bca187cc7bc86670d10dedbdf0923b8e3ee8bd54412678d4c79dff669c8a704f4ebad14a19af384295cf596b3cf9cc0d4c34d4993447a09adc117972e6c91c30b0c381c85096d05c8c8e2447b4d1ba5e653862de2b4a9b92a500564ee47dca8265a1ede9ca6e3d9fa34a7f219b08f5b1bef2407ad2511af72198fef2555ffd9614102f3723c42802b72a0d80de4d25190c0f7e8e03ef644d5a7c7a7b83e69e4f150ef455a58811d93f161a742ceb897baaeca88a7cd2299107ce0ebda1e02fec865b1a\n\nInput: 700bad39588403361ff086244ee3e72a60541cf640277e12b47f0adbee3d8a55cd9d2f5b91c9da969a5514e664406ce4d217c2be532db2c1def5f8316cb8054d13950484c5178b008c9c19c9fb516689e67bf897b60f3d69206dad8515eadadba1f0343e76dc4292bb507e14840786933aad4f1121ab22b70647b54998296139f375c6cf67cbd4829a\nSHA3-256: 5f2606b9c4a89acaaf506c85f26b7f35b26d595d43bf5be5c99a490e3daae9e4\nSHA3-512: 8148cc206fdbfb98992d6997afec75ebbdf8c5c07a61eafd6fca292a86fe1a3e6fc70099f9f4ea068628c82416ce890913178264f14d8681f1057f3bf70e67f8\nSHAKE-128: eb03f27078f1fd2e32cd7be93e36c166d426745e95d203b491905dc3d4f3a48727e309b6993a02744cd7108d4934eddf65adc872127105ece70b49af41226393f39cdc89b749ef3f917349fed7d56173f85c769f81ebbb9cee66c03bd1a9479ead4af7524b76deaa88966179b86a19353e03864dc4d1dbcf9b940b3adb05886b3d6d69011d5d59d06067e9f379ce39e3df3fdaadb657b8a6ee3892258ea892e259f488ea221447f6ec1da550a17a11d01a6ed06f82adad792ad229514e503d7cf9b4d4bb92ca3d388a74bd67a2d913c7ffb1ea0fb15456eaebc9f5ee970b40241c7eb874383dd64e1daa9a0300a978b3b2f3fcd035ef20b5e8ccee159513e5bf978c9c9da31870c4bd6155de05963eb1da66efa8e03a11e75aaa5b735cf30ef2f883e2f029b8a619666708323afecf1499554796920c8bcf263c6caf92964a7cf27de1a43340d2f41797a9528eec96fc9c476d1955282579cc809f6d5e6507018a2b68d99564ab424ffb1e968ea60034648d8959c71a6f14f4b4b37735291c96d336b958eb54674e6f7057d585598bb7518489af010fb94c2d1394e51674e21309e0cce95afe4d6661fb91b4821a4ebe2c9ca1a4910a027ecb900239d5a2f2bbcf3d4595e9b7310d47bb3dc47e2faad48b9b27cab4198ab1f0dd78f95e3e3292bcbb52bda87168e654db2572ab3e7272d30189a1040aad9cc6efaa866651fd14\nSHAKE-256: e4801de7475e60ae13b070a3dd860f43fad63b5bef1f498a130562c3bcba9851e791b8649d72f62abd44271915aaee445d96313a0c0b5d388a513830996c5bef5be7b86e5af238f8e6ee89f9b7697f25e11b61a03247a5f120c6431bef3e21eff6c22a4a199a98774da15957fcd21e2370efcdaaf1a7a3f98d43c3842c845787d42107f63cf5f3244d2c8fc17af9d371643d7f6db1524da3908ae4383d6f0c887d67f69e24ec2b57dd301872cf9cbee6a9ea36147f80a59165037f8e9effa7f07848f1623689c8fd1ff90eb48c7afcea434bf3e83f7a9ac56a024e329971ee3d72487d195d10cc13f9cad3ac14c1ac4cbd99af3dfd6a4fb83bf1eb42fc994f6f6178d219734cfb9c4dc060d9609d7dbbfebbc5f2fcce7c8836555d05a7c532102f981b4d82fe67cc02bb2104e4d9f354812e24d14d130131da38c2c58b8075f70425ef4f66c27382db5104cbd629b80f69a78102cd66d995ad3d74a1dd71f36ca75f69e8062d7204b33ee301173ef0c3b014265cd7f30f19b50a7130b7b1604d716a4358b364a589fc3caa98909ea6d3fedf67fb17825c05bed4f194d67df484dc6c00c3460050e53c28304e9d407e74e43d4184614874b90fd952fffc54e0da042b539b96b833a1aa2ee71f6a6d5bc18a2d3b878a77be74e3fb6edd0fe3bb046aa93d2c91e20a18c296f8cb11d8fd61362890742d638b5bd6f4c41747880fb2\n\nInput: 1751740e80bd25ee5b5c6a1bcfecf420c8e7fad8a7d0c4fd65e83569e43641662b5637c6f8715460f5ca025e27022cef61c9b86a99d4f4ddfb315890eed541b5459e33838677d0f1839d46b22a688ec0645b9ca9b0597e9d039e7b77b541e3515445a785ce630ad84e9b61220e6660db0f3c78d9f3c437abd2b7358b21", + "3290d759e05668ebe78c23a5ae\nSHA3-256: 79e11b42bf5bca15565aed94ef9345f4e5de59a3fd90f2e52eb44785ab02d3de\nSHA3-512: 92f0c2d042d7d5b3a6faa5a4cbc0cbb014ba1acc69586cec2b607a5b34480381d77f7da46e5637ad808a96a517adfca1c230b370fbdd71bcfffa47ce8c7e4321\nSHAKE-128: 67a29f36fe9b43ff172079d457b4417d64836017136761fdc97782c7544ea6fc5db21c058b5909afc245ec26eb382274413bcbe44664e1fe1ab34dabc680774d709fd433a8dfe8aa1e1d74b6b816b1f93687b3a9855803507ba665e7ab604ecd118fbbb161ff5c7ca6248d4605ceed55e850479fc691e993f0f91dde84436a9e885e596f169d5e6caf42666e2fd4e6f8d88175ac37d66d677baea4cc257232f65a2fac3d9f46583051e5f3801b742a9cb9e7d875e30c62fca9cce1c659ea03d452997fbcf06f9f130d428c5ada01ab87af3e5a021afa446e51f3d694cc0fd4b9af8d6493cde4ec915e9da21b6f67b926492e721bacfdd82353f43a5ef9b2bf9ca29b91a4b3a12e6f8efb772440f55122f452731e27a748bf57ccd7cdada17b7aebc6d9ffce62537d09f8679d4631f676d8f06760f58e67fefe61d1d1fc4dbfbd3ba373944064bded08bcf14f912f6f31593d2f507ad3870f3b022905077046688d7e35d29a5c26e82a826f073c802d0422b2f1eb27301f368cf43c1c1655327fbd9bad31b4d68dedaa15465d63e9ccf309fa18625aa8a60ea737e24261d89a84932090501aa202377e5903e31b33c2489c5ab076feb7b0ea73be2b23bb20b254e5dc40f5e6fc501172bc53002d72907820b52ede638218a3170c84c37e88e0f7bf042b0b226f55bd2cfb2712e339e7390619672afe79c6fc4298d15b2e69c6cf\nSHAKE-256: b33c67ef49de5fdf94ffeac05fd3f95c8b0523c589467b62fa397cbe59215887e2999328ba323395e7a642b3cc35788652c985774722296e160d88ca4508883b7a3c8b4b35723345cfc6b617ade36fa9cceb064e743a51994cb95e222d4684757c37dd46232dbcc76a7ca43cd2c4cb27b86e93597a61282842839e4e97e17262823dc3956105c18d15fc16917d3e0627a0bc9e4a74c78c1e2d6f7fbccb536e4f4cc762b91cdbe5b36db6463e4353d0a1515d4cb1382c4384e670675f0dfbbbddceb6e31fc40d6e52327a6bc1a69201185c892fcc2f2b2ab5efaf169dfb4638de205a30385134d110fa2b7c04fd63dda663645c4bc83573b0a82ff73665cc805917d751327d3c703627f1c38c3dc6f6e9c6d725e84b5b8f63b200e3927215d02b668ff50dc8f6f8188ba95ec1482f5fd008f98118cfb59e3049995366054c11321773053b4d4f146b4d65e81b4a902fe94a4cdf2c7cf3b928545d9160b3667d90f6362a3a59971ae407d24c57973876afe4006b5f5c27b1085aca17d0db8e481ac38b8f571f734bdc355c0a1867c1d1f5aa4619dbecf8a7640dc222213ab08208f8b829af9f78e5ec6f2e2a29051242f6daedeab953ac8092887ad26fd3e891fb2b57d43f6e68100a1b55a4d9076de51120d4561ef10e87549f660780832faf58ef0c48238c02b54eed22a8aea664648a5d64ab870a1ad720507a6ee00068f393\n\nInput: 2011ad3f23ebd4f5a3729211f158753714739047f7e8c5ce2daedc7f5eb26bd9b9722cb0b3f811cb328410e8fcc2c30c166b12d4a8306f289f7c643221e14118b6af3d0ff800879e305eeb5655a213957ccc1498293cd9871fd32c2c0b2b5a85f7952b32554658b5ac963d3c0c3567b3c199feac1f66bf286f8ff5c0ab940b2f6bf1e0091a437fcde575dd\nSHA3-256: 1482baf89a1ade8eabf131f25c73b28713c848929e20b3dae4485ca2149d507a\nSHA3-512: d0187b0863a0a4d2fb407dc0f520bafc0639445ac8343d8468a13383396021e121a3c878ebfdd9d834a5b2f23d18b91c8b096b4a21ce44b6af8d0ff7a655034f\nSHAKE-128: ca4cb7ecab9917233bb3bcabc2430330a6c5f72c4f3ee3203ef461a03af968e20d6978863dad68977ff9ea062824e52157ebae9f8f7f4d25c2e360701d4e5273b5c66d9e75a7e5ff1f6646de35c18c3b889fa00d754809ff9fa309b5c90ecafcdd768f674df085c22119fb63514994a38eb755afd35a945833d7db0cb53896a531e08aa67475993287ce3361f098a05d46315e97345fba00ee7a658644ab13b50911e4e91fa2f4d90efe1ec9cba048a4fae547bd36bdcb89b04bc009f86b6fff1f25f6c1bb20a4ad78f18f800f8ae58785b868aa6d25e9afda57c0e7816141b00f4b8bef5fb243c91412d26ce0ef3fe4c4942941158955e60c330eb5f9195f6c618ca955fe9447acbc9480c35e9b463bd2dd423023f6ce24b5113e598d7b176fdd80c364e797f44f1f460be6c22b2d0e0a7cd8194e2bdd999d23abf1d25d642f622ea62808b710d3da2fed9bc5af83a5718f79817ebd975934e00fa10cb7315a9b9b785916d58fe5a2364b8746797183971bf9a13093fd7e599d34bc920c86a01aafe4a67d85183653a18e4282de5ea47841b6705fa910baaac802d8cefd45bba746fd0b6f5d17f97662ab13bff621ae48c26ca3dee75cc18f5bd53a98e31c03f630f31ded4ea463552c64b6b12abf29e3bf824992f56ead1742c6e684881123e4231fc18e1c7c1f613c6ca7a6a2fc07f3e72ddf252f6651505fa332e8a3b45f\nSHAKE-256: 2f14be6bc0f5b754d05b3f37e4110a9786785d6f982f67d896250a0887bea3276ed5dbeca632415b2f6b5898ed6bda6a32f2e3397ffe5d699c0adc2147e26980812d327c09745f166d5ab0a1aa874eaa0017ab0691d19c3811882b9c19b6fecfd01425238ed47cf9e43dc2fe2919d9c3ba53fb50e7d3b346463b8b9cc177f00695e3ef070ffc1743808a54f2415cc07134e12a08eb6017ed73424e738e75eb5eabaf83a75a64e830537a160f4057e0b646ef19be7eaf770638765ee409936639ccbda76e271d8f3f9fdc9d5d17382cff658492ad3f4be9c493099e893cc9a3aef7727de37961cc59af90b379561b3582087fa9c5b4902220604296f104c2ca7833c28ba264eebbc2acbf6c4225d72fe73b03123c3502b9582d2b0a7fff72dcd803bd3c588b437eb6dd2286525aa3d05cbb38dce120f5c2b3bdf771cf7b91986f8e2fcd2d04489a6fb3db312bb2152da6058642b95b54f74e67a71fdccfbce9d83ff56b2f1d24f207e0c31a8e3a4f6a99440ca67baf35515e9f344e50d8855868591c8c57b8fa4be43ac01b95d0406c231d351978262e15a20e86b8bc03a6b4271a4fb2f582ec303346ebeb58b4c0387d55eae80c9d1e3933ec75f50f15d2aaa6e0b8f040829b48d253ad0f61e709446af5dfb6bdd4d3eb721bf38baa3abec99b29b8538be3080e0a3c613370e9edd540b408d7b648979c00b2eec7add68a91d2\n\nInput: 87cdfa57b6ff82c5c8d87f57a71528ea355186d1c130933d51fa8f8dbc003a907fb3f8abf102ea7b22c12c4edc8762b6ee540c14b17ecb11cb688fa1ff6724c4c5fce79c7768b5ae37f7d70dce53b9941b733bdd9598389f0d422279bc67bf34861a0a0f34ea6ca725fa101c8fc14f37fa9485e1a6f9d469aeae234a3f853680bdc0c19219abedd7a41d2ad3\nSHA3-256: ca6dcfca889a56e7abe44560b4b40cf9235be2571b31d3dc084fb398ca5d823d\nSHA3-512: 40b44640bc438713469ed23b9cafe57f6b41d8f92ae143a9fd2253915bdf92f0585bd39b7d0a2d7970bf5056adb24f284286755a24760f18681dae0b7b9f0e9e\nSHAKE-128: 92ae75dc85b1e650e26ad62ec12f99d2f7022d009a92e777aadfa0b699c0856c436ba942ba260eedb0f6309c005d970431844d511dd5d9276de0ea22a4db24e442bbdfa34af68d2ab8dbb7c3213f46c4760485f53466429a29cd7090f6d2855e04d1da82d6faf148cbb1979f1fdc65e521b647ca887f71172a63d65b655d329e7f51f35e8815031e552a712f3384ace870e0208d016db0b11740c9b6d96793b182dbd1263aaa3dfb7590b3aa8748e0a937584c616f08e3f70e8eec4d60cee631f79a60368e8af7c45096879878618514f920e032122e3e2e2008adff08517f00661941643d31dfa621efb499555d61d699db59701018c09d6d03350420c73c3341b69d4a4fdec477776f00e263f93e13b4f38923fb6fe60ffee5b923741033f076a5e4c4bc0a3f456beeba26bf82b848873d76e04335fc9a26fb4c85a3a0bd746d1c5392dffd1efeef80817b3e75584b4a1b243a65503b99d72660a9613037c89fcca111d1a4df557faf7c38632b8e4e52a62f97052262f25b6d60007b87a65a3818baa67ee8753c502b1ec22c32a84d969624730f34c3546230581ecaf61f412ce3b42f0b914d02e4383b48d41322098b78f1ff861a9ab62833f12ca4d6abbdb7364bb4eb84532071e994389f15ea75d1f8c6fd757b4cdae707f03d40f55582206da322882d28d6de3cc50b94f8b8a5d3a519d2f4cabf98ecd16dae074413aa\nSHAKE-256: 8ec70bb9e6f48d76afdbc6bb651e542eb47fe2928153875a1fb545c0280d4216209bd03b859decc682b63252370dd281dca24ab5519e6062369a771b0b20f64f829984ac9b3f2931585e27b9932fae886bacd3b84a4c881b36b503edc73b9d17c3eed65fd869f2a78907381c904e24d7ffa4178d17cb694f6513b1af8465607a4fa7fd5bd515c4ff2015a657f8308058657adc7d011180aa75416d360f8d59ecccbcaa1712b6923d15ba0f75779f5388cff62aea482e229b79818ce27c51f50393e1e241249f4818170d2ee6f155bdb4173fccdefe55c1f7d3f59ffa12ff39244a377349459571dc5cf15c61fc132e5ad15103d9dfc5e54771cadd2f94243c339ba3366475c4e5fa9f3a34028137b2174ccbd44edadab19e3e4283996e1ef78d17bf4e4ee36a8e0cf7b82070a35511b84e662286fbd7cb34bdfe052dd6e53052bf05cb26077cfd1902c449dad47597bbef5f21d0803bbbfdc3580301971a6ac6c7bbf670f381e33a45a069e9c88f48738fe51895469b5d9b9e52f925890783996a83ab24f5feca6b6aba004eedd8a1411cccf9e5818b49738d7c8f4760d28814dedafeaa8e49ce30eda364842de59200ff1984e2da1590e6915c6f70b0c7502dafc8b6808379eeb1fe8d55b3338b267a5d4c7b5b594ca51311a36844f7c55373cb2946988358202e1d0488cc4800408f539d65c2d3be1c2049d604679695e8b9\n\nInput: 754bb305e4c0083af28fb4630de1fcd54e929f7492aad462bd1bc6cb88d1b32085eaaaf98a34ab4a449c9d6255ad1be1d4c8ed9bc950f9a880ca4afb2eca23194095c969d3c729e6cab72e73aa21c7ce3e708c3d5d9654fb0080f41064b35dfa51d89b4841783171ddbc432eac5f19de93f529a9d15230074eb09607a9a935b76e791adf835abf5f2b09fb73a9\nSHA3-256: fc9ac6ca53a4252b178a12663e10c408af3079f20da1c5c988aaebb3791e2e42\nSHA3-512: da56a010ac693468f18ea04fa5b8da64402aa8e7cafbd9fb2010f0a1b95992aceea0a6f24cdf31b8908eb2e53f8915e2df36410816c426f79d8622155070f591\nSHAKE-128: ea16fa5bd9bcca32c0e9f25265c5a9472052c1213b2255162a10b24f739869beac1c355864f60cd8bb358f45bf3bba2d1d7cbc4d6ee4f1fc3c51808621cd17d9bf71c1b48c7b2a2825a4585cea0c2a39799b9da05e5c79bf6ea0351190884064dd10ca978057bb464c906f4", + "65272e53b0b24ef3f28d4b4bc0e8adedf0c24c899ba2560c022b4cdb6301d7df35271b8f4204e7c8a74f8863cc3e5c238f561d711ca99452d4666e95a44128dfebf2e68be9d5b46b847d55d2d3376f56c58f22b8d0368b8d84bc4f8430df78c6423bed93d2d9b6c4e82f77a9eeb80da72dafbfa06072d28829406b003560ede2524522dc9dca69cbb1a2ab3296a31635a43180114013ecfac65df2b85eedfa0c97784e59d569358445485a5bae39078a7388b61aade3f6c522f729839daaa2f68d793a9094bace118465061d46e3ab7ff291c6f9eac3d92b0b454ae10a3a56dfb0ed3e0cb8bb9ba7f22979c56080c8ace18e1a109d66d8f89b00776f1650223aecce264d5230d245cff9d61fbbf8f028ce0a73c5c6a828181f70aa4dc2ee0533aa297b74c012ee21584503d917d7fd7f40c981f12d071bd3c4d3298b945abd10d3fe79acda62368dedb5d015faf0e2dc4f16e8f43e4bda08c04216a76101de9323028a346e98c8547dfec0a40203a7799fa85eef13ea90a9dbf922ca0d5ba0bec3e9799e868e4d7ae556e95dec6b7023c035aff8f\nSHAKE-256: fb6fdb1f26ff572ec71a2a8a75d488fd0cc56a38367d95337958abd255f67c3cad20ceeb86bb4d5f4a375cfa7acad29cea0cf2256d98f9e9e3ec583a109afaef0980c1af57ea7810fa06db689bdf91b6546ebf52c41fa9c6c329da6cc7b369c0469bb15a764e163d86673ceb9b1ed0d1a7ae2bb721e44f3b5c387d436c058c4947dc9a8e1a9b5403b0f028e18110d22eafd7c5aa0ec6b0135a06183a9774aaf05421fa85e6b435bc5cd7c09b4af89b2a3904236bef556496c0970bb2f76b5b34a4139d8a26e3577d7a13fb5e205df73e69c0dce8aa0d06f4ee2ac4694eeae8ed25f30538ad5330c208efd5e1381cabb72b10782d9b9a7695f73e204fd0d5c2f45ee81bb3fdf77ecd0c3ff4ecceb9de0fc7cb10135faed8474a66aa13e9a80af6f7ea1b3d43ec9efc4f51cbf773d8edc3efe28bd2254555c585333c7a604fde018e26b0479acabd4e2cb796de5ecd5a9ec618ce4d15e5976f0930c0c349b89d7701a3bd4d5a8c958b82771faf5d28e86509989a766f092825133641a6e3c408e9791d52d315da274d4d5cdd6220eb4b041fded55ada3cdd160f56e420a01b0151a4444014c5dcb2352534eba5e3763ed66ee96d8a6a9edbdc9c718b294051f4fb4dd2b10571a2e1e6ff5c880cff90a0c9207545c4d0dc9ec4d3e2d4fc2fab5c725af654c7e0f62b118268e103065e2edabc3ee9d00d8f41ba2ba0e14a22f9c1bb\n\nInput: e49bd01f8d90e8a5aeb9521a12dace12e4cb34016b32339546f500c8949d75a8dd6111f045ec4a931345481633cf2e3a7db98d425bfb15f415e5d6c1a7326327879fc47821726de011938cbb0d2eb2d3609f605c6ceef11ef4e6c98b2a735cc13c0eb3846cc6a1e058c472b5849abcaea45196cd6589ad8e9366d6eb51b83e423e0339252acd0b68dd6b94a1c8fc\nSHA3-256: 557dbde517d3c35e876be9cb5706ad05bbe5d67e4e302183819c9d499deca61c\nSHA3-512: e46020bff1403deca609c8d18bc5396e51a4f04aa2126e35fc4597271f0e0cee1e9452b541db7c85d1f9507272df7021418976a5a062f90f1a3481e5a79cd30f\nSHAKE-128: 86d7caa339b2d9233ddaea7761ef45ab97f8db74e317886ed38b11537a49fd311af04b50f7bdda49796dd7194f9a6273ecaed5bb8c3f58836cafe2b5e8fde2da3471a0a06e34d532d8b69d4a99bfbd0fcd426115888e802460061ac80e040d687015e39cbaa70d885c3910e3832444f43c63bfdde4f13202d25ef7a39b2360183048c4caf3486c1353efb7db1cceea5857db77cd6fd5a3aba60e105aa7cbf5b843f69b68a863472b318d0086a8d1a28a298d962f67dc73a1e18808a2876a64d028b6a0a1b63f1d7ec91aa7cfeb6ff431f1c0da8a2da0c48e04f6fd4ae7ed2d60cda983168c4f2e7cb822593f03840159ed5f6f4bbbe393a063efca65cdfc61aeb2b8f08556d405dec87165932a93c11cb5df6f9b7e696b2e3b25f5bd6d119f09f4e652039b98454ac81d14306a7a05f7739d139c93cd4c1f0750625f5e106875fd6756efb8ba0a8d8886d84bc8375d3986b20ff76c7e9d0e4aef402d799e23c59cf84e7f679743da5b0e0a1b0b256a8811ae903cc5b420998cef594d04d389f7e09136374d386376860e26bca990b3621706877d71d2c93780305ab113e1dff4d75b3f1f96dd992b8613868c0190ee2b4f86ff57ba7b741cb1a5a9f1f71746e94111029db9159c13267f35b819ba0d82abdde9c3a7271b619d19e0491e43e3db2eff5e2a2f49ba61fbaf8a055dd311a6b905a886de1d436f312d6cfb592e0fa7\nSHAKE-256: b3a4dad43666556c7cb808c7f688980eb80e69615eb8d433b38bf4306b0e032554065160b072694c488c4b2fe6601d0a9d2c08b8c6055e8c67326aae61a9c883ba0e6c482e687b5070a287951b1c9cfd37c6f78bbb2ddb74456a06c64a1314410d7f5f6f9c9f7010c293e43c225a52b4ed6ff977d9f8d217c3e63e0d9f2a1778c99eca77e66d372e41fcc9c54ab2cd6a5f9aa90501a56f980311386ee32e499577c21557950cd1e30407f74ca6e0ef8cf28be46b848224d4eb794bf3003e9f084da03bec00bf45a32b4b05d09ef023fc3acb55f70f74d98ba7e6ced8a9a71dd1fb73281510ff337c1b2723897e06d13f52c956af7036997ca12cd6110292470f6aa59343cb42095d17db96e829fe6d4222a178d0e6296235c8aa6998306402594da052c6f543fca291088842b232f6e27580a7187b18870dda45c845687d2c1e1edd89a0ca3f33713cef7a5199a4d6d2e1c9481ba070f846c57d3dddf8ba4166138e3ef3241af7465a87c32f2e2c7b77ffb6a2ea4bb2d8c26195b409b4fd65a93aee773b8a1c09483ef8e3db4e706c37786d53f6726a0c2a012462edb6c3032e8b30529be7dac69a7b7ae3089c4bcc0155b643310bbd210989d67a6245a882215c490a25356e89ad49771f0de382e0261c2048cdd183db9cf7c0f48c6cc567115b9bc2ecfc78271d9a2f3e147f2ce26f5c7aaeda0c5d85bcaefcb7d80e2b0687\n\nInput: 3bebcd15df24f642aad40235464943398ff055a6d452133906e41e6bb3daff888e59dbaa3f17b3aee06d2e9fbe5c79c59bb6c0e4869573e7ae911cda0e48f538a01098941a014474469c9fe49702eae2faec703b065c76ce9db3af23b5f888119623d88e575820f63de9f15a85ce64a9faf966c723276b1627b43bd19c8ce0bf807edb1f649b45e70bba8934db1404\nSHA3-256: dd3dc79b9c86179a2ff43e25162473e451f315ce3a738218208797863b9559f3\nSHA3-512: 19ab1d72caff241fcd19a144f9080405eddd79d271936f0dabe226ec2632667c6a7677e50f3fcb6421e6e184d442d41dcf51028d7eb44f7976a0edd7303fc950\nSHAKE-128: 64fb41be037d3a07bff254815879a610f6f0cf08bac74e565f5fdcaf802fa4bac02f149ad415ebd3e55332bc4513086f981d06aec103741bf1fd1a4fbb75bc65e13604052f2b609b3d35bc5ba9e49d658fa9a6f187f3447ec4012a035ffae106e0cae6aa3b62d16ccb355d60e20d6a1b8e592e27a26f34689adc07bb9c60085578bdd7fd78f2b009c614793b89955b23a59a08b0fa75c1e4c349eb678f2f17cb1f1d842139bdc00b0731aca52d2079ca95c08c06b8bc1f31a97745c8ec76aa4a1d601a630109c4621ad0af6d7e7127a6391f3ed2fda51aa179bd9ef20fea5537bf7d0b6d1d1eeeec303b11164e64965e8725d66879584eb20739a0266f1c6b5f4e15c274bcaabfd5c4724d31527d7ea296ff22a9ac5253cc2b6432a16d971d30962d15c411c86e19aedc3b8c3cb0191e966e2e842c30afd278bdecb03728b0a3c6edf92297a282bfa2fb327d4474522e18fa2e4cb1074ad32acf420219aca25fe0a6c1b77ee795fe2d8eab6b9bbd8734db10d0d4b7683faf547e7847e581088e9f080da1b29a0a3bebfa0ca82dd83839cfbf9e934831233010552dd3fec78d17760cfddb9aaf291616b3bb70ccf88953404227db99e80f2fb1d41200b5c29ccc64edba5e6a89e1ed37809df8227b882623e7879ff9d3d5b3304d0096f1e51fc00ff41721311e53acbb0ce395cf14f56244958883f8c75fb2d0da623210e47f57\nSHAKE-256: ae15c81213c4be30d1ed0469281ae6a936e9375c9ee02810fa6ace01670aea3189a2db8d4bd36b5691589b2e1eda3ccd252b682c5b77bc3d0c259a01e5562765491e3a36c3f09edad4b3158c6e936d622c1161bb0194b9f383bad4df489bba081e7b8aa402ae8991513627ca7101f8feb1568081482892d3db678b419e9d6a0db024b306953096cb429e84f75a11f71b865b991d6ae0dff00756897a314916003de63335bd7dfd9d5b80e2f0d135a3ea5bd12b5ed24a37949cb7496d201734caab74b66e17ad8ec7be561e48bae5110711ccefaae8ff18c1a03e5f231eb84f4e6ded68a0303a72cf979e2055f706d4c25de36dae79bf20c213e0ed8c7071e9830b9f4820a1b701977866831e3413252e7f81de1d900336bc2d8af7decb118128a0542e9d40fa91214e350645964cd49ade226a2d9c66b1732b3f18e02a0a7139386da5181e0008c09e0e24dcca3c4345bb11e82f67db50d6b9863c25f93203e6cda204d6c91993f2d1af3b5ea3714553713f75922a412ac46de21e08d21473f74497575fab23fe851112ad73bb6f9b965941084b7134b7f4ee0c5e30797a5be3c29314968e0c63357046c9fdefee12baac4e682a64085f9f66fa3b0a97e708643cece0df24e7e3f10fc4cb6e1ae3421b1ec673e14e3eea2f3d6f3d3b179b8d8ae2a5ba510b2bf8db36adbec59e1a6dfe9780950f230e21764f721ee0bcad7ffe\n\nInput: 436278a48d2717ac56515f09c4623ed1c33c579b72419af9b3d8e6fd380cd4f46a3fa518d5b1d3da56b66a553a6d5debc52dc7a3d239eee86f2803849f5db90d75c2066f3bf5bf7f73277f318f11d3c7c210de83a0611cf22fb061f5901c1ab13f92e49396a2aeebf5ea29319b81dc6e2c53c21bf4502389d4a87232d7c2ac861172fe0d6fc2060a95eee7c827b95f61\nSHA3-256: 7b409270acbe161680ca010d72c01312b33da9076e97835bda0e17779501bdbc\nSHA3-512: cbfe1ac87b1d33cfc72ecd580c3da7fc1c95a009542e193d2313d21a959be6b921d58e36f2d95326a02529d197c621da49e1873627c16cb31ea36e8047d996d0\nSHAKE-128: 46a400681e308fefa626563b7f7bb5ac43413c358b1e9fe35a78d491ccff8950ed5bbeff790fafbe1c916d81c595bfa4c23da23632a2cd17ccfebbe68f009488a26663f66ecf86f3bf047cafddfcab0ced8685dbd2660cdb16b73dc46904448b51b07b35ca44323f419cff42232aefb484c631e80af5acab434e67908ebef79ba03cd65b1b4f68d2b6212bf855e0f6198ed12ef209ea127d2a07cedfe9c72590523b1b2255ec8dac9d87dd7df30b70405c3365360a5e6adab1a8c2a6dfa5a4bd4877b54d5e3d1c332bb9bda148d5997d531d3af4fe9a57dc4df78aed48e8b35121428a15d014096300c4523c61dda3938b32712582f5c504b31cad13ef03146ae9777da3c6c6da80cfadc1e8e91a8511a5e93ee9366bd7736b6feea881da84ec031280da7ccbae961e54ddaaace474196119356e35d486fc12f181a1c327e5ff7b62919c3b8e6be2650ff28b", + "fc4cca9c53600832a34d9e7ad5e705d603458026be452647176a71bdd5889e684297c6d404b10d7f39d4415010538a9d0e2bbf710ab27988c53310144ff39353cc3ec642f48c0d3f12d9821647450a10611ee8bef64e99ce874f30f1c8f847a71f32085e8df095222d4bc4675e4f28a4cf73103563b665b3701ca8dfc8d10dd5f7e8b4f6f2f85cd6230f4bf4eed65488be11ad4c3fb1709ae0d004e91c441575b49bf67317f6f317ed779d72ba452ae6ed008b19\nSHAKE-256: 15b5b7ff73a99d95070c6117c80ce615b26b30fe5a0f5dcb5e0faedf6cad60d8af3b7c6d53964503362a1b380f9f4214f431fc1ade26a9994bf0b569af2ea1ca2840f5291ad5eaa883b9a67660920519b5a4e63c751be9a7a93f0f9e64b26f0f083d074ec011c5c17883189ae1da7015b31c306c6db82c264cb02cdb935cef36f4e585e532d8501c7005894422607bdddae21d9a137b84763cc31cc7f94ed8b0fe27621677dfc4da010dd86f33e23e0ff8d5fc25d4e620c56a695f4b8c217fe3c3ea8be07184249eb9c00b7d7debe9754678fbbebba0da4366f8ba8065cd1b71d37b7e65c990ac09b9051a9f35605b9b68d9585fa786464a02de0eca25d168278506b6f932f96263031e1d196e50f413a9265bcffbde5624a502ee7175e01378878006961c918bd0fc2449ead1bcf2b6b89b75c5452bfbeeed8ef6f8137ab64be6f26744311da048746e9888248bd9937bdf182c3ac7c91298cc6cd5d67b3a1b4abc57cfaf3ea3983558882425f780bb17b247ee261c6e3b2d0eac470c3c3597fa7e66571dc8474e2c02fa8278518d3fee2b2650a5630a48bbb2719cc60e2237ac83534f5f1e6ce63874405c6379a5735b887f402a101c465a05294a6cb205a864d52a52069efc5c5dd552a02e97b512849d43ecdc012f8a2f382199052da3e0eb966ff2f2ff3831dd884cf984731bd8f75fe03d74250d8968e658ae18e41aa7\n\nInput: 862661c7b5a80248c37ae669cbae89ae8c2d47da1fe00df5c27de11522f15208c4a00e203f871884dbc42e04be13949ee1cd1ce6287bb176f1da4585b6f0e88e361e2dd722d1abf2aaf784a73bdce7fe4e10f3fb05e79c8f6f7df7884f07326936bc26ff680e673666fe173756ef50dd1f5a9fd745aabe6005534addd0cdb51a79ed52fa1e13776461d74df3f9ac91ff40\nSHA3-256: 830a289a025059f716ef1a16a5f1c43c11bde0b0e9bfce3d0bcaccba1bb89c44\nSHA3-512: c15fde5ba7c52645394022804079508fb289206325032ecaf59630afd792c203c271cf23fe16130cfcfde647fda910f018f4db075b864f80a6a22c1f7d7ed668\nSHAKE-128: bffd9b727eed80ad000788b50f2a6064bd0e2b76564edabf0c1e9cc1bd56441b395b71dab926dad74fc2ab4e8ef42a20273d3efada68da22cd5f3586e870e96c779e67785cf57afca75089c69d919fe1e5576a687708a35626360f0019b3055b2ddf4a1435d13b755009e785d2a62f8a94d0a7cbcfeaecad36210dc109849993ddf6e28e9d1b47d300cef027db6972b19865533c1b5d2fab1ff9bd910661f7c5c0992f447a6bed46ac6e6d0c44419f5f572a3308168491aea3237bbed226c645ebb2e6f7e3bfdcdfb22b96c94c86980f7fa71b40fceb9d74b0109d5deaa0ba6d5bac774ae57dfca6b593b7cc89ad68098c96cead070c2bb896ec14ff66bf77b5ee5688895de5cd13acfc6b964ede34039ead09975595d9c57c3f9fc782f52d2d7fe5b5eb3fb1885df0f0b1c36e83311d5b4cd9754f83c530b98b02be398ab31f6daf0895c48badeb6dcba95fc4b7c8e47e916d7f60edfedcb7d361c1205f491b36655d53baa84c6d3fd43ce8044757e4f247467176aaa4e45d4ef9d63169c9fc72ec77f9d458f7c0d79d48ffd5782e306a9b835baf75d3325c5231a73a3982ac5dedb7c0d18d1c38cf96007376522646b3d0fe7ce28f20a269892aa446084653f81b29eac9a1cfee7b444115bcf9e5dc33a9f0e32e2edc777b470146cc821ab67575997b40b4cf1b39b66f7f34a1839dd8a6f062305542a9ce2aff836efb23a3\nSHAKE-256: cd6d528ce17f45c66f805e0912742c2617c79f544e0fe01c42eafdb84466d54c5c1f5a67d99651e1cc1a4ef725f94f45b64a34a4d9960e735be2f4ad339eaf712846fcdef1ae50eb896fb562f7891e96c9169cd36a25c0e6cbf04db6c9e0ab77ba2e8af76fd9b3cc3b0daf966e0edb5a46b5b800238eccd0aac8daa3dcf622834463d4cd3ca375e3d28f1b9a6f084213f6d92667a55448a60826f878dcae71cb485157f701c16e44911aa0d17d780de607b87660702b295151b2f7b01c655142298d74f8ce76a8694907a2e2a928f8b59d61057bc18bebb6a93fab80815ec9f067a94b57133c1845c7006dca811ef4b7a356b1fc5f0d6e56f80491cc3bff9a1175c90b6de39bc11a3e1517273eb1f46b971d9fc58183c72c7dff3f51349f8d7dd9e8b4c255ce9f717637e3d4d7eb3222d9d638c3ae1aa1315c8ff89ae17f39949f31e10ae8011017f021dd9aa6e6118b40a15b52d54f2caa8c6290219e0860db1155830126d295cc23e87710a15e653c440da05527ff148d4fed5a07b478de38b52e4005d486b915b7d55f3439bcdf64411486500bbcc54a1f4c0b41f079972a69d842ce9365221694764a80e243007d2ca54e1c75ea4493e81e0aa91274bb202e1beedc6bc17611e4b1d8244090635ec2e6362a0fa4d019cd4afc08939c5d7ef8f624c1eb391e1f200c3a2bbc60bb0fbbfd34b04374c4f45ea0c047e6a9ee31\n\nInput: b7b074ae22a8165ca192939041c6292dd677a30fd134b9f0cc6ff0e932250bb05b797f9ad84893991ce199fa0df598dc92576d560836c722d8fd00fac679669ec2ff4d0338dec1a57d162aeb1c6de23abe54219f2200da49b8329098ebf2f90eeaecc15bea6d1135267d21bbe399995e395a028cc8a22cf59981d9cd3dc0560701ddc2f0fe94e0e9e898c1c80553f80db164\nSHA3-256: 966f1d61d277b5d3447abf39fb7ae5218ae86849c66ce3d88fd60f964aa6b562\nSHA3-512: 05c16b8daadad5a78c645873625e99fd5c1e746a616272c442d63a2cfdc1da5645b3f0e01c283abedf749ad12603a0475205879525cf069089a2cd6814a4424f\nSHAKE-128: 512b2037cf1d0edc5c2dc08650210e3811f1536021fabb2ae6ae0f61924ecdc2de92cef47811d6bf52190ff00e0af0e5e4d279a1585d77d7f304d19b6692bf8bebcf4f50f17a236c1df31598bfbd81d2e32d19a9a8ec24e785a35018bffd8028060037ee22ae0f210f5458b8736ecff7d4fd66870f362f59ba6b623b2c9865bd9b6fda62b7909d5e3e4e5d9d0f7b95bf2d0c6fee2a95869787ce851eab1289d8dd2cdda42d104366f1cdac430284296fe313bc4c5eb517b53484491e3841628a41409ff9088eee50a5da5b6cff95f9d6ef96e9e14cbef71b6fa2c9ca70b10e02962d212d2a9e09195aa0090fa5094cf09b7e2dd2b021746bd09a8a5252ad25eebfadd2356c5189a4d0444b085690a369c1aeab72594e6fb321174abb78d7192370f08e437c558ed38bfb687363274a7435133bff9b4ebf074932981f7d2d4b7a44ee0d1baca1cda3fecd068e0f8deb98bd7db1c78468fa86649e7c941736de175b6869481040c8fc444f09499bd0d10ffbd44b7aab9aa1bea52168f5c0071b6c7094d05fbb7ee170e676b40c611aeef58ba4e7afd9a7ff859374d5d06afa1d5447be97e0b164106173d7cc984d9944693d2118466ce53088ad1891d367301f5e8acf022418443c5958202a1caaeb6e66adc1131bc92c4f4149a511e9ffdd3b3cab032b56654af2e98973440153a3015ff74dc355a5190ec1507667725c8da8f2\nSHAKE-256: 582be104657ef9626697e3c4b0bd7121ef9bf6fbbcf8d530078a8cc215095b6340d91a4201c938536c6864648380a0d35d1ccaf6824ba630d69816b6495baed2f53ebc5c5ab060d29d0bcc1fb357c0e4e05cc14ee8ef79702f731ff3c4f7ce99483136cb3364c75e5773210607c406a50ed179cda0251db5a61c414977e8f0641d683891712c15f39c4c019b87b6c9d1ba4e639d0fce2c7fe01561cfd9733484d95d4ad81ad55ef1ede87ae4aa787c9ecef4faa94d95f57a66285aef7a3a73b147d7c7dee2eda9cde286c276b514b4321fab0f13bc0ee0305864a39228071ac7ad64e34f21183dc23ed02db09e21740a975ab1d5a322e1037f8df1ebcc288c2653254ff30d0fd19bbea66c35623f8b257e7893e4242b3c484d3b1549e5cbfaa76c79e513d268bea9bae4fc8b47722b5ba6aea21b49bfe89c7ffd76bcb8502e4403263424e1a5a0ab256d24d3d76b01c6daca5f3ee63ab2e09087a849b216282c05a20068981f917f507856dcad0f866aa730dc868f01fa7882dde5106e6df5c551db39dd5298b78061837755d2dd57bc9dbab55225e50c85922726664cd7ff09707445066f0bc1395ee8d7117f3ddfdb5a601875fa5979d05f61f7b4d2eda04ddbc1bd2c8713f8a4535cf58cccf1cfcd520360774ceea818d91dc2d306d32cdf40b9e48a1df19482241d8fbe749d340bd3baeb9689a8cb4bc8e342bf0ce71fc7\n\nInput: a787860b2baf999c69ad656b5029960e26db921db866d0571adf893af4fc5f1b0c58472b6ad40ff846c5a3329165d358d5cdd6d7fd959495014849985fe04f1bdaa779c355d3eef94085bd6a5030cc53f642ff30c5486506cc98d31fc68d4fec981d210c9ce82c5ff4c6aa734dbb10c371b5f539ac0c761d8c69c15c706cbd4b46f0c665ddca0eef70ddf165d653194d45c97e\nSHA3-256: 90c0e278302e94fa6037f32077e14d69f79989403d7aeba87cb26e72a56e1c0b\nSHA3-512: a996ea958c6877000766c53fd9d32e5e3da2d4c586b67736a74c60b6740906c32d3720591ef01c6a9b569535c9bf80358138b4d4f60e7f430393a6332dc19334\nSHAKE-128: 9e41c99b513c9849aafac7492f91aa30c497d2fb78b983a7bb12aecaeedd4421479333523ea57a8f43f2b6a54fc9b3ef657fbc70514959aff9ca7cfe20c1b7fbcbbf1c9756f4ba29a249e80f7a0449c596ee6a32756c9e1993ae2faadfc8777d6548b62477fdca9a6a77db6921e1f96309afc0ba854eb7d0c98d94f94e0674d950b75ca831d6bec4d715221e76dda56fad5c560f5d9c184e4480fd536c93818ff26104b86b6c310ca40e7024222c667aa8746d284054562348bb162bed26a94bc1c492893b36a62bcdd48d7c233a6dc23c732e73a33048a7623ae06cd13b1374157b4ed844bbc99557122a6bec13b4a49e1240d97392f0bff67daf1663411c4dd459b0e77c211bbe2152482b963a11f76993af10c8948bb8d1c66e2073b270a7dea9479c640412e09133c5cbd5247063ca0a477427b92e92ac05407d812c8aa5d1f41e6d6ff5bc679c6095b73e4123d9926a16386b07b1da2001498b19306a0f26108b3ac901a0d272ead091da310b076127072296eb8fb80a814d01df92cce4464ea2e66c71a51382af584cfb3730d1b9148940763d6a3f5dbd0f1ac133bcacf8f2471f1bca4f433459a73c491ea98f79fd90a26e3aee2c58cef867ebf1720f8d18e05ff2bb34db6779eb43e6af9e375730fbf5466a6592d68a3d3df8b5f415d6d9806958407239fd69bfe5f5f41eaf65f2b7c220c54a12caea91beba1938bb\nSHAKE-256: be5fb571eb55597da3427f9b72ed6929ca1fcc640ec6dcc6088376e5eed", + "7a37e30c0daad625149ed922ddaf9ce1072ec9f04eb494bb324ea843834038ef3dad457773b04a5303445ff83ebe059a83e77a8acefbf1ab636c6d7ce78e0833414f9e3ce52c76d41dfa776d9c3e356f208012a7957247e399acac92e84efdfdab26f63fd3cc90156d45ea476a70111f45b4fd3011c637185d313d5889419a9c34734ae939c5deb3f644a960b52498c4a72b774d2f2d83d7ba1a05c16a2147a39bf23511fb6f1799855f0513d8bc4adcea5bb15448e6a36bc4bed64a6377f57a1590949fd8f0a7aaa7c355fd9df78736b7f800544a53af8a09f82e1cccd0b468f761fa8da081faa1fb4cd7901dc424ba80fda7585deaf6592e831aa7ec7bc91730bcd08f668023594f5bd4a2b7fc6a5014839f1eea5861118039bbe773d546c1342e5fee7d962c84cef8ca52ab434374370f4c10239a9c19423b993d4bc7a72d983c753677e79c0eec47be32c22d024e2ae0910b123cabc1af6afd75dde1d09b9d768d8d954d102bd5964177e4c285a0358dbbbf556bbdd084e4c603ce7a3748932ca46ba4c1f69afe3ad15f24587cc546eab9ab5a3b7dce241b4201b7446b0ccdb586671f9b0041853d55bb15fb03cdb512f35a128999cd20e89b0436d8b2787ba546483ccc37aca57ea977bc7549057265eae412049716d6868e6704c1d8975d99f\n\nInput: f5b906b363138f76039f9985be0bbc469ecb722dba87a62c4c354de2859a994dd838f67fbaedf0525c147b91e8761e593552f1bb5386c19096a11056f04c52aff42bd1a01d9d1ce3de36e33938f78b97b55fc2a08f0600e9768f67ea518e126312b780dea9b2285b8a7fc34d2c407847f8fa49301ce7877bebebf637841186cb57e576c1bd545eb41cfc4cc9b86cca71e6dcff38\nSHA3-256: 9b940581359d1c3dfff159f988db2babecccacbe743e1a0d262343ed8074cbbd\nSHA3-512: 84cc0b6fa46dc0d6500a3be0e00c0cd8f75285fafb4518c0138df8f0cfcba8a96731b5f04563d461dccad95cc1bbe1c0343692e7e14b8e11812db2029c9f897c\nSHAKE-128: a4ef49bc1019c2f8429d58c1bce29d396dcee8b51983ff507499696fb83015af7382768ce81922f73bee8013d028adc29b1a4517673318f3cc3eb25b4d3298e9875f9267ff4bcb1266a7fefa505059d0b1896e0faba538fd3293d1563b8eb291bcd2a2d19a30c4f9403f7df61e9b4f55a2edfc80eaf50e38243b95c02bf1d64c0b52c6d5f2a7cdf25bae5006e4ea1051b958eb4ee08fce6eb1c0a6dfac28a23da7e3d569dc8b84fd4f86964e7e5953eb245a2518c45fd5a1121457abd3a5b35ea727cfc652962ad38c6d5f1320fc05aea0a0cb7e1c9a52fddbe6c4349b698ae805649cac370cabe7b0b0e1224e42a32c8bfa15b7ce76280cbcdd6116928295ff6e7093917833d9d72562c3b142daaf361d258f2b88459a530bdb6c44b274a803af725a9c316088fabf4d3ccca681b48205fb78054c89927febd19e0581f230101f13c321ea14eadd08ded31ff0c2038085d29c7f0f79c24695c9c13b9dbea65a7b09baa97c694c0bf27c905b556282973e95364507f4a236ba354f435d8d20fff4d52fda21d37462119c70f85354a2f61606b142660d3d95ed71d03a530a1f3c9bfb19a228d7e5db517aa79385ea458bc41ddfeb80654ccf4aa2d580ff2100622740dfc81530e8c896c3b4c6e48b6463db386ee9b166304ff217482c73851142251b304d63419da3d7cdf7a063a576b411a272503592a24cafd185d3183e3f84\nSHAKE-256: 716899a6b4b0155eef7ed13045e16a9c08a024d0ef35415026af87c73053a5ca4238b68ca752f2b76b3c9228a2120d0cae8a5e0b7f2ec25aef0b6a1c46870206360aae3df1c8803da7df17a0fe968a617e141670bafaf41147c089c8a0625d028c5a5ff8eca6c3c96ef088a910a06147ea642388a108baa0e7e1cae341a105e5bad7b36d82e4a5dfcace410eb677edd947ee3161794d3e55688a66598cc7da1cea67aa653749e2030a8056e7c6eee08e35fb6bdf6a2e8056529d44ff7a27b5ca9d886a61c3c51f90be0133be773c47c6f8098197455f891e574825468002bce02636d3006ef759a44dcefa93b2c5050d96e8280f41c570a7e671bc812d2b967945244363c86c45f60421dcad2079c16e7bcc173f9fb1db85395a0e73bb38f2fc6d4b71c15782ac8a93b3f963bee1d0dcf4e7de26e0c2f1ae3d7c094381d9da942496e7272bc710285f7bb88003f07440d9b693b5edaa6791791241cfa8651c95a31838ba32fe97fad00a7096561151c621d31b05f5ff7d6f77e5bc3e2fe10dcd31f60412b832d7ebd37024e6cc50a55bb6a73c0c4016b3dd917cb04bd0cdf2e426d511311ba47dc6e1e624b43e28828dcfd52ccff40b9712f3f7289ef0d16be669053970b0112401d3fbf6e1744fd0a030e96849d5cf59c316dd7faabce40700869191c624a0b6214db054fc847d96899d542973c20ded7e804f0b082dd4a2de\n\nInput: 48f33080e7a0c33c3c0c8ec1690e7ae61e0a617e327f56a66fb90117913e2ca3cb23fc2eeb65ea4307df72c7dc0c53ad619a1fe6d47a6d1b26004080c46fc99ae167e4068474fe1ea7e0d5f342d7fc305fa1674f0f1c4e4822293bbf31c590004db13ac252fe59333f40fbe2c846bb729a42a452a271ebb0f7b728daef0ffe3d400077e117f1ef59596f23906d2ee0275ad971143a\nSHA3-256: 49e997e97a28f2799a78c486f62dde3766d9fee27979c40372a6f31ba0d3a62f\nSHA3-512: b3e97e1aec2743e3e9b614aab190bac86046d0fdbdd5821a6e113a847cf1e92baa618d87edf6fff3e8b50b3241f04e67bab7a71e626a05cb4d4b071fa67cee4a\nSHAKE-128: 7fa3835b2309d1f9f7cbc689b786d4534c2c98daf606931f55b14fc9c6ce49e2ce8531617724a48b6e8f3ec622bb4c8574273a2197992a7d8268433e0108f00f4e185ae2dacb92fc6f77aef2446d67c1e00d94ea4899329e29f0d855af34f8801193db04c663e8a841cd441732931164476c2e24c4acaf288bc38cc1300d4b3f9277f88a83799f61bbdbacff500242c8cbf250e7264d242450d7d4fa1a3f590a6cc0b49a9e8c6eb7e4c0dca2014b04b5e45bd3a58655b25d746a222cecc8bde9a476e49d3c104cc6244f0695dbf0e9ee3e3d0537fbfe77052bfbfa6d67e396179b6b84be1e86edf8ea006ca2f2232ab75295aabf73c26cad47c42cdf3a191ba42c766bc158a7f937a8a72a11a1ca161076379236b640458fd745bda16177d546eb786d2b02fc983eabe3ecf485f30e2cdac07d804b9677aa5d9716e6482b5d53bced26ffb77e67c45ccb93288e05804c5bc27f4e5396a17536538f3df6bfb7993a0513129072b3ca2a49310fb5e0b2d3da3b391ba0458f46c9b0a8fb20bc06d8222e912cc8adc61260801422c07fd892de65ea70987704d66b01570f8e06dd9b5921622450c9fa45259c887a94d4baf31f5f33805541989a8bad38ec3551cf58fbcbdbd8c0bb2bbc645264f124feda1913dd35d319434c21c7a32bcab8b2de67ccfe825bbbe90979a991f41b5c1d305e944c2bb8860bdfcea731636c4772c683\nSHAKE-256: d3f7831590ff5c71cd88a0f60d414fa7f9e288acbf6eb9e6b8d8c09ff5d8c65bf211b49c22944007302b2af8513819dea9e88947ba9c5730821ecc0a1ae5d7e98e86f4b1848f766d203418a941a1f4d93db7601a5d840bbde04072d9799762a921b3bf6ebf21e5cdec7aab3210062375795c252ea0530dc5fb21b44ed0a7915930592dad84ffdb3419a6eb9c82cf7482c1abbc415bb932d66667384ff37e2836e766fd0ad8bb12860c8cfbbbcc144c746257058de6b86e2f44e92b79c434ee037d55a5600d432632102596c5bc34d3aa23510cdd7f6f4eafac50ff00e5fa6d890512159c9f3c5bfd654ce3c2ba2805b5078ecb3514e594d8ec04ea4010eb2a7f9fac8033246f4ef0eef8ae9cb68b151f8a4452b168a08378244131fe65948989504b175ef37e5b7a18bf56ee731da001970686f71ca2fa40e4cee78073bc192a2de02d789f4e97bf45fb4966f7f2de6e6de3adc61a708c6dfb0bc2aec974047088933af77fda400d709135b550e74b1913d3ed232ee1409208033dba7a383d8d90bae1278f9e965f8175a179c4fbae606ed3c869989989bbc6fec554bbbb9b45c4e68d2cbd13a01ff14d6d4aafeaa9bd78a1363886a53be408f6efdc6cc54d820354eb2d193bedd9778f9ccbce112824ed0c35c9003081651925a5541f8d6868fba65518aafa3f1ca2f0202f28c444fae0ab1e497b0287601a3cf40170211d61\n\nInput: 247fe03400387c9c3909237cf28ce2ecbd0f83443c45fd09a3702884a823e69a4be63406a974d7c20609e7d89a92a41e1edc9240d643d5188446bf42ff24f2776c8eb4c1110049d12a50ddab7deec9bc155c2ef1b5127f2a786eb7be727bb73f24e4cc538fb463f0850f9650606fadc202b8ade8f2f06aade4e1c0eb2ff8b9f37f50074c7f1f3d76ebb03c37e75e73bb952f1982643e\nSHA3-256: fc7d39a32c55e27680f05dd430f456a618152afc83f71ba1718efb8dfa3cb6ba\nSHA3-512: 50d37fd99da73abc79b09c8307994a645a36ff220e5c65437546d368ad4fb645ffb0321c46eb7b6f231a743ffa9fd1473ace4c979219bc0aaa1509fec5698d1a\nSHAKE-128: 91507e989e6becca4af0ad1828084424b8aaaedaf2a2fe5626b21cdc56422df1d3903f857afeb9dd04b87eb24c057eda91c70cfc48e63b42b5c4535b5e81b23e69326a0ad3495f501a4c5581ec7eed6b64ff3b6782255f6baa1508c8993b273f0d67229e67b9d2ff6960613ba2d14ad1abff090c0237bfad2e19453ff4f1fefe419abe56e68093eb7c5a89f468e8dbf398301791e8282a89cf7bdab7c908e5dacb00785eb47a6d1780c246645c64b3e91a424815240473e2632b6c8f76408670093d506df210406cc30d9d32902cacd0ed5f2b98cbbad43df9e0a64052586cad0745f450b0b450396215ac34ce12eec2e49f8da26f5de850a91e913cc1bd3f9e3fc3af5fe884edd13d5c3689e37393f1a49ace6238a9993ff229c16d809f6526f9085f9950219dbab322fc86ad7cadaf7e799c29cbfb0c1d05f734553cb0082c3fa13d03a176e0e29365d98aa3a8f52dc1e5e51cb93588baf6436c99a68e3be995c0c3db573131d369f9133c45e1208d5c9930b2e1226c27f06e9fe949f660c0688cdc40c8cc5ae31f0cc73a789f3b445a8bc4dd51dbdca532f14002d82d42f51a2aa10006322dbbc1a20e380a47b5a378119d06ac39cde78006ca178363bf6bacd9b14ee07fd73c9b2b0ee8c67c8fb48a8c0f036efa69bba0d042bd6f7a54f1694a50a5c6dfcace66b9ea33f99955cf1c0bb8202d682a83a636591aaea4b7f4\nSHAKE-256: 9ec781e87ca22957775f553c8d506f7dce73ff58b8ffb983ed2d77da511303c77d3c30b333388dd224146ee6d7d0b0e4131cd163c5be4c261867dab7d9cb5947c8ebaf8c988a83558027ddcbbbde3f25b25bd7556de8d3ffadbd486806b4a38869bda6cee1dc6792addbdf3d1440650b2dd67dae8aa103ac0def296e6639bd32786921aa484701ad7278dce57a585894b768a63870911d90851f281bf8dbcd161aa17b496df28fc92bd930376403a2a87657bc81de35eb454daf5c788290464af783e8fb771cfd401026b9a4819667570b3069fc72ff3e261eac2b7371fedf0711985c194f8d3ce41869de96", + "78b3a8ea32f34ddd3f3c5a1a3710a4b8624b2e773076c5a31dfc671df1fac10d5b79ed382af460cd0ec6df03a7aa3596e94e10a68881a8e7fdda720c5638af4d921f302d129ac3b607a8e4f9e1647deb8433f6404aa7ede0462bcfeb1974f01c7966541e602a91987dd8e0f88b6fe5e05b4fc2206b665f51e9d6618d51cdd2061fe98e8d9061b5882708fce29e323148fa2c8cb24512f5a7ae504a9ded4df5d53419f96b8bceb070f8c8dec0be547f716b3061b4f798001e95fbd8b4dfa93dfedd911ebe5a709e226bf1c361cda9076fb87f75b5eac39a4ff1d2da41a400d7450a01b2ab3a8b74e59338ca23ed0232a732c2d505340da6c98a17dac1238388e871590911e14b24a3cc733bffa167d0dfbd7f2ec5\n\nInput: a42ce79f9061418d9d982fbae68275f7417303a9620bdc51b880f4eb317857816d0140b2368b44ee6a3c3c6e91c5f2dd74dfb0a2726e13db6ddfaf302a146d75dc0f80721fff2b18a2968e2c29c0284437867971464173c7e52d5d8276d45de965475a18a6d52fb21ee19684bc8e853bd3d31d8de7a7b1dfc59912685c039c9be94a0686be363f683827a673367996ed3026d0dc44c0d8\nSHA3-256: 832c07f71e0f306f230d52ea3cbf23785ac3eb5a3c386333c2e80dd262b7f6b5\nSHA3-512: 95026f63a483169bf87f78dfcf86c16d0478c07f647c78f7174a747a4648c9832627d372412f6cc132274e5fc84b43eed0e4dc20e904e43cbc0bfb1b40f66d7e\nSHAKE-128: 09d8d39dd0f6a7793849bec520d9cf26e1c646b6d731582edfbf5536165d1465c7e0188284a1d61e39351c97bf1d1a10944f972d8365bcd553cbf77a2b6021b1942d4c778ccb1e607404093508211b050f0314c2af9316e762f42d1b01c0d39ea96f9115d5d9099004b43aea243b73fadc264ebb782c8bb1f1bfd81382b11ace026284ff9a9e411e2b2328fbdead95a5b8e06c57148c658261250eb4c0a2a2c0a725512b7eb81788cea6ad55bf9d183804603570d684f33c4a5f8ca47bd251c2d7c6bece14f254e75a41e500d948544ca8e162f62783c8252351c6dfcecb2a10fd5638afa64f050a450cb16baea345942bf48dd8d3d767b27adfd7a368199594c8e704217dd9b785e4c6d86e94bce4480b76f43a5a5c33849b453810b902f887227be7c2c369b2734a388c9f4964203fa28a896b998cd591623bcd2cf56fd947eafc7559877de0549890ad80bdac11b40ce99b0455c761339223f99b7688d997d5e8b9615c0b1b939a9984e87880438f0933d8b069d898f678da0e57f405a1cab27c6e4b3376d1a76b4f38b8d7e51a48692b48deaf7261669b4be4e04fd2e1b817569ec9115aa77eb5078c138f47eb1607a5891a19a45fd495c0df3772e2f8e28a3fd64ce76df2535670cb402c0a809d2d3b1160a10192a1fad610b82ed3d0593372e044c779f6a724208013c6aa8f274099ac2dbbb3d7276e8b4c7536dcbd9c\nSHAKE-256: 0c3b5d478174301a17f80e6199af3302fb7fbdcf9bb98119b732a1f15dad35de3996a280148c62675573df8033291b372d3f4eebcdac776d650b993ec947527be91a8705952e85acbd14ea5632c28371a73f4e357873f0690c57229e51af4ba8cb7a1812fadbcda00c6cfce01701d50f939a6a6179635a49be0256d97cc3d3d628acb8538df67138f478ba7b5af8571fd467dc221a371c6eb4e70c68410d6d66344a43ab7e95cd301926a5a9eb9e7a66a6efd9b7b415815fc7db4493f5048646c4b84c88fc0da21e6f95a25cbdb652cec045cc85063989f658404100624b04109aa94282e01e0b11f777d95757514c1bfd79d98d08cdb80b87326850bcdef3cade9880dffd08513943c4ef09b9388e29f82c4e2a95d64ee143921e8c985423d2368e188c0a5b7a413fe9877cf9d3936605a911aaa5571c5d9b603d54070d7eeeeca7e2b67e182cae96f41482cf63ade802080a6280855eba2d93b5b72316d5976b5461905680dc1a9e53eb8e8c2b14c9239376bf3c5dd48ae9ca4a5ffb5142466261145acb175c14353151c034b3b185f267ccbb8534a3f839309d561a7bd49ebb213f7ecb5ad28e6592bc161e72f9d0be9b6d40f13046d3f28741d12480c6e95cf1fd1e561caa13180de30232506c0a8fb787b61361f409b24a39ce4e17360ae407a96c3bdfd1fa00d1001c19dad187c9cd47bf5ef08dc5cd7ee5575f247857\n\nInput: e62b5cfaeaea9c668eccb72b1bbf32a0bbd4c4c4606e1b9dd9917ebf57487716e0dda9cbbf88f961a32c4fa8df3634748ae00853a9645ccdb9a614d9cef20042d55afd848726867a361ad285703733f7bd491d140d1b1d865aa285656f8a71ce5d6a7b1830126dc7fb806396b5e23854ab78587e34238f550537b15c077d0923a3028f47900b662fee92813ea4b5819c7c927ee6d58c3189\nSHA3-256: 6d2ac2302e83cddadfe560c936ef24434ba76828b68c16deda3ba5a26ff4a002\nSHA3-512: d19f4dc21bebfe50d0558345795165a73a543babca5c20b9edd1c5fcffc22ee08866679e42e8efe7af902a02289e012c3e0b043e42fdde0a96feddc80c5befb4\nSHAKE-128: ec6730ea185da580acb15f5505f5b26c66c350f98570107d6c05162145f46f82918c2c58b5c71018d21f7bf561e2845d52ee2710f56d7f3d795088fb3b49eb8d7ef71dbe3a01b1bdec3470e544a35a385840c9d99ccc1942051432500d0a256d48b1f30a314cc5b460b5e6b27c34fc9cdb9740f723c15f7db38a2a88e49d2cb8146e80ae8451d56754260bdce5e46c22bd3f12cf584b6cd1a3298b29f88725a262daab75c0e955db3281a28d2da54bc70796a302828afe737193c155866020475681186f688529203a7aea245f5c7861b724c936e1c98760a913fd1abf07ce66e63964213b4594fee49516eb69d36ffdf01f6f7a7c2012624e254d525fbd06d329d9a3c1cd5dd03a3cb371c5bdc9c60bb9294069c1bd344966204fd38da660aa2eb33176d7743463a3c184b0bb219bbc8fefb1b2656d6fb4e699c425624aa2911cf210a021439f192ee988e863e334bd6a1403b5de35a4bb8615d08467db00a22e048be4d2c26d736a2a11a065d53b27ecf1c6ad4267063442fdfc5af6c14bd112ecc677ce47fc44aab4fb27ef19de45877a18eae13189b81088536bf4220c24215b19dcf706a95706b96e036aa0cbcecc91378233fd483daf9ec66f23f9e6363fcf87249df7cb789859254ada1569d15015c3994966de8d59ec0d7d372c7b963699a4eb7c749cef4c8fb5512a710f30ac9bb9d577331bdd22eb3bbb33920802\nSHAKE-256: e8f4799b265bbcc50d08a465eb2092d7577437ddfdca62531d65c78b464cda8c77d9a87e3425a94edd5145964ffedb150d82cc5ce559c517bb999cef0afc704d15d43f322f92e79ab9acae741aee93d59f2869b0c2336312288473e91ab419a2ba4f3165f6120e0b293399e0c7eeda25c4fb27c5a871a7e08cb6f91e9d2ff4d2795427237db3a43b881bed35ec50d2db66c6927fc7939f75fd64c7edd56fa09c378c5929ef6e3555e280ce19e93f0477af7c16e4bb616ff2f58d2baddb532555c732cf2be1585b95d3633c7b979bfba7f2cef7892eb06d97e483236d283cc37486dde7a52eef103bf9a4206681f0472fae73081d355cb021f4dc40a6a368a6a75a2209dd810665dc08c333fcf04992b8caba046e249957f57dc75289d1e52c772c05ddc1553033e11121572caec891ad564110392c77382ff10ae7a33192973eab86c4b47d0de9eea9d1a74ad281683841a68bde477aad68b7018c290f10d98fa8958d0750ee557b76ce9d45cbd410af17bdb62aafbffcf0070a05078c34cb704c894b04133c3b50e9265c2a395ffc233e383af4a164973d35cd090ac6679c0cae6092b4569e0d052b15c327ca6f2b567bc81cb0b2023a61043b23319c0beaf58d1e0da2c4e28fedceb340b98a724287e74cfdfb053d8bcfbb748dfb5c0b7349fc06e84ebf90ab635f4b168de59ae23ef3aa140bee37da3f5f12561078d5e2fb\n\nInput: 7a3894b2109c12af5f60769f9d2b2e44f271ecd14647316b845e750c6585d78834a8153f6d7ce6596a4b310119e780d472f704d270c383cbe6f44152df8d8191131ff2ea0a040d8e73f4668064eb979d1a5135ea3d308bff354afc6b8efcadb5c0d306c044379a7582289232928fd7797775d00db9eb85b4d863bd4450274c8b05af96ca709b1728e0f585e7ff3cd1c163913f98aec7cb2198\nSHA3-256: facd784c40a25a3fb5b1b51f6e0e5ef1906c63f8f4455abddadd79a42c77cacf\nSHA3-512: 9c32b907e2fd6554a2278a750d5a3dec55ce7448c791ca161c1ab412f6bbc1fd297b5145d182de77bbb622223be0051ba3b1f8f071454514a7fe5855d85626e4\nSHAKE-128: a089e91575fa125985439592cbeffcd6ee5681359f830fbd998bfa0a3deeeefd0b35e4a35f664fc60231bf1760b04794fdd967369f83a1f04575ace493e65a1a4254b728856f2ebbb53cd134c79b0d0b193ccd963bfd770e26e607feb14c1d06737651222b5d09dec0f059d062f0f60b47d1f1474c70d1f0a41f04b2a2fb698977ffa1125f692e581f60d0ddf09fb269c3bad87bb84f20f2e19bd40c93d6655fdf3c46bee2ed29d77c7773d137950af90b7da9ac7b50cd7a2d9e0408a7cd9f936d8ad07f9774607bc9dc4898c0dff645ceb6b2a58646f6ba1dd038f8df03e852544e924d721767f2d105d21d8f2c6af7ad7b498a786a858b2439e23755626c8f8b32499b3c442e77776871f983d7d1f26bcb6b05e1890e63ac0f1b0e399d7e24a23431b05630a409e31a42a83ea7b0e285bb35344dc5aeb42ea4128172e8d20d882f5fc8c478f263dabd424dbfe3fcd32d9221c95cb26f3361d97ec7a55b61b28a84dbe47b2190c0561014fda0b11a09e0ccbb3074d266432788eb619111582546b44dcd1dd5c35e60d8cdb09cbfa752442850f9a1e67b622503b737eefdaabcb4819c18c82e8d0bb5e0db5921b8daf7277024b531eac3a70bbfd66ec952f463b34a9711d78d126573e0cedd622bd5151389474d7a4d0c1ea6b892ed317781b6e3a279453d17acd60e0fd79f7b3c1fbe84e3055d856309d33f15bce964334b2d\nSHAKE-256: 3d0ce4523bff664820f88f906b165624869e89fc8a2c2d859cfdc1a4017aa8d90444d20fb87f27aeb2914c6e9ac8e52ac8c69bf62a6afd8159b6661387d108c6ed4a5b256e16b87cf19485741548eaa5cb14640c6b4841311e51f7e8297961168b0e628421e5f7c34955727c9404c18c37363f89ea8591251d3c979f7bd0bbc56f91bb469040faa4bcb53bd908a3aa80049c7d0ff7fd9ac9a696e2617c62d3d0178fbe28b4911590e889459fee6543f2f4f0768a116791e1bda3a4de6a843f0ae0acee745c118093d5023c8913fef5705c0f2a97294c48bbd6b430d879110881d751a446cdbf2eafff1a4b139e4af3fc592471d175ffda6275f96719feb371cef4c83fe24053b0e71a4b6ce075ade17d5206a1cc47a01a9b410da06bcf7a6f2a9fa16d9e19930da51efe6a303b12f3a645101484d1519f2c1b8b27b3ac81b8a5469aa72715e0bca0d298d037a72f8e0fcadf4c8e69ba692adeecfac90c0b2a04def3dad7e6c3a15857349849d2a0042969f6940b0088500928c3fb2840d8315eb57950f6ac56b2b855d83a8ea8cfb7f3e83603627c2e524b0bfb27d349586dae91cbd6b1d35a10471f3d55f5fcaa787de0d", + "7795194744d6fbb95956fe6d137be982941b09e6226094066689f6cc59ba3912f0f90b2ec0f0f0deb77304d6e64e7f0689c46c19172343b9dbcc14c32647bfb8611a345029f080efa9c0274352225\n\nInput: 2563dcaec9dc8d3904ffea5b2fbdabeba986d682649d187403ca9dd615debc638d65674367ce67186c5cbaf59ad6c60f2d86a66c4dab971c2726bc33c13678f50064a9b53eb6510f600f222f5fd9a25d3018f803df52ea8ba2a46e6ea2c17c8ecc4d01b6fc0ed4807c701386415c23025464715e0f60e4ae22a464e8487d9eee8b72e73fcc0b9d402244d5a3600501d56a9ac6c9ce4ab1c8c97f\nSHA3-256: be795dcad8126ecd55561156ffc61946f204dd6e4ff393fbeb4146ada363f2ac\nSHA3-512: 7ee78e3bd508831e983b9a5f77867083a1bfc2cbe7c393ce791cda27b705d69913332bca7faff5a10599f11e8c6a6bcd08e8456b37b6affe4382d73611d47b35\nSHAKE-128: 13773a6b9d48d6e4e5430555250d2c922b945d8d8ed2d7c79c63037b5aac43a4e8994a937e5abb3046d374d91f728a61c0bed7d7b3fa3b3d4a37e694b1f7c8a7887a88ec3c32dd25d61bdcf2b041644d39421e40ebbd67b98470417961fd18c096385fe2f3c743ab5279d61cc7e9336e32b6709835815cc5b7357abb465000e2c4fccb7db341bebce3e3aa78590385d05b017f1c280cf388789bc147c2ebb40492fae19e327baf1495ec9f61de4a18166671cde605b7c0dcd505bccc679e0531970adb446ca0f8d2dd9b954101b0c7b2aeb584c8073e8de7f33c54adb2ba1b5906500543baa9e6e433813b74eddf0a579035da0f1cbddfb820b5a44eb98a65a727949f84d27db29f39c5254584d88ce767214424b89dcc654de869dbab1f7b00a1a4540594475078c857f7c640bc9a6933ee0fecf232604e6e0a4e73cc0e2ea84b891a11b715aed48f685fc62e794e211e6b357684e070ec25645582fd510709d8a450f3f34a60bd83a18349ded0bb3a040041c6ec6bcdf4b79738da38e85d6f5502136272aa4c68b2dab8b814fe6598a2f2ed7169ad5ce91588a60cfe392fbe347878f2d7cb0b614f6af31ff59d42a3002021fb91df8c8b12f94bbd529fe9870b8a6db42332122f94a14c777c50dd247070476f81e6482d3ac17fcda0226b81fd6858dc2d1d88f72977134533f8b3125add87631e2321ae49d73e4115aa273f\nSHAKE-256: 197721df9ae3c5c7d634171e876b89f252af6762cdeebedcb86a632a9fb8c684fd5927a48510f52c779ad3befc42c5d2c1337c7314e3102bc677a9f1f696845774d4790060f1fbb1feff3c0999056274ee1de70cde86a252265367e5e7aec28b58354610d31d6417254620413067d60a60f927ab176463210a8475760bd0e24e0a8360ca12edcb3be4ee2786c51026f2b97ca8aba13ad8299b1ad3a91658b619426ec3b9c64dcfc1c4c429885d274e32f4cdfb544e2c5ae80a1381c59b57fd2a38734db3a10bf2f1c26d857fa0440ddd6c98d71155662c51bf48cc0db943f60878b206bd0db334129dfe4c39b808bf9087fc74869ad22946cbaeb6be9a471a67464ae5f893d3023c0e8854ce0683a3920b5196fc72ad8a8b801f7c984d42ea6a44ffc29e8090d978e051fda030e0d584d4e4dd9b020ecbc67cfebf0568c3aa450fa160b3741709ccc687e3662bee8c7c4298843bfa6ec20b8b7f95707c3815ae23cfc661db287f204e15faf93c3b0c4fa083ba9f52cfd9a38e2a7fd6fa7cf14d17aaa5962b9d47119ee3426cf05e3a675000cdae24d44efb599c048db238381a4973b9f0f5312cac73df673e3f271fd470d8f68f599e61cc4bde7b272415772043e6548855c1c27c40972a6a339259d3f000dad2081b1be702cbbc441c14f2a9a7177cdff288e2faabbd13ebecc3c94881835b1dd751fbecd2acac910fbc662c\n\nInput: b6f0a0e84b48212cdb93c601ed0a9c095d72760cd3fd219a8670434869f50851ecf1893ce6f26c88de2393175f32bf1adf97cca55370bfad357e40226c5aa694928fd812a6a4afe5732171f037586e75b380d9c1126d9c89ae644179e802db2c8d7b02c9e4c0eda1b9304ce615f410bb57835d458e18e987e2c25076ba708d8f7d9fc881a5082eb30dcb24335f592d094b23eecbf1f539f0d0c28c\nSHA3-256: 5911b99b1d2043a881b097cf71dd1bef9bf3dc83ccdb7fa9a1cc9a43581edb5c\nSHA3-512: 82b33e1e8ae66a51fee64c7f7ba7cb5a374b389f5144c59887d60e0df3c848c3686b1a880d5540b61cec51570bc5992856e99a42beb5e46d38787158acca6c1d\nSHAKE-128: 677ffbc2228fae92542d15fa5291dcb4d101fb66d6b21398cf92ae902bdbb17a351f45802974c85710c37d8407e25cf0f1a4a99d67eeb097cc98426d016bf4702d7b5dfb8a9a36bc3b05d54a3df7aba54909f88fd6b00ea2ce9859e4f2b570b82f067f6c7e1fa16e9345c41b615647b6184f62207f0949110279b003cee9444a820f2ab13ac47876440943058b8ed84c090d7d24d83e9a39b5ba89443b76d7584671628a1bfa72de0654eb0ae621bd7d4efe27b561dd26f77e298f840576bb7590ffb7cda87fc5ae1d73e5803dca18bd11cde7e63c5690bc867e33a983c71fb1d2cdab3e6fdc56c5db8806b4afa396aac11e2844aba5e3e2bbedd4dfd1ccdc55424192db776f54df48595626ab7e1fb1892a4b764d0fafb204ac01070d025968145f663a9b9cc7efc9ed1a381b8b19b9b6c39e94d73c6e3672dd63c1490c7c805cff8a9bcd7edea23e4699b2514b9407f31366044a213c34680e375f9071325ef77602498e4543abadefe82afcab8682e71ddd8b0f404ffb081764a8f44a9d05309b3fadbf63ba73d54ec6c8cbe70d7795be5bbbaa841b191d97d6d7e2f5d740af1345da4844c497218e2ea5470b5eecdeeb470ed66eb95f1477eaedbd4eeddd81fbebaa388f91a2454bdd5b121cf9a1b55a9f8585f490dc22e8d70280cdbf99f7a4b9152c5922cba6af93af5906bb1a417375f25caa9c710f635a8685eceabf\nSHAKE-256: 7a36bfc26cb42040fc90910530fbd70327da2b8de96d379bcdbcfd2dcab1555441c25109302bdaf0952c5092b574323e5d905036119099841125ea3987a5962c6958b941fc5645e2ccce9870a7312a40a081335fcab33dc20e4dfc8ba0287069364857c22b8d87157c5357383e751f24207d289c0f993a4f062ce69008371ee1d3f32ef57a0ddffc47b1488afb6a35779be4e07d3ebf0e70daf5af367139a53fda153ee060299784b91c268d1afebb2203b9c990d48097c147740261d3f88a6f4e15ffab071fbd79b9ea0a914d8c55ef6af95858c621e1c0bea40574b1ad22ba1a323de794d15d1478d74ab833a427ed8f0e50fc35ecddace1291d197273692cd1e76dcaef9b0b80a16242dbf2af961e2ba2fab9eaa20dbb1e10b8cb12f168a3b325aebd3ff6fb5fd42b4afa32daabbb8ce4e29774898a1e91a525b753b58af8b39600ce2d734ca56b5c114e8aec72e978d6ed82a7930ac0230a2b22d23f1652ab9785b9b6f3a1988fad39d8e48720f6fedab49699d85e1fe0c1b2104b77fd685756fce1150baea7126526df284112e681f81904db283f22851f975c342d3b881902dc042752f8c3a42072e9ebbd82065dc83e7cb076ba667f628336fe67256fe1b3a492ef54bdac253bafc8fd79cf3de38e3fcf01c900056b79ee9273fd02e93b0905bd4032f150cc0ad96605a835102dedd557b703a131fce768845e2652dc\n\nInput: cc61a58994e771b0cdbe9a57cf0c6efe2a9ef9cda62d09a9759435b1aad540f544f2375601dda12644c89a7da988b62ab2f3f40b1f6bf5439b0213efcd81cbe8d26de3dca53956fad3816d419ff90e3f1fed477fbb5125589b84c94892750276b6dd19112936caf6fba99e3ded4488a2759b14ef1075ba8a113783254d934f2f945cf1fa0b57b8d354c9a83cb884449718914944711d2fa3f7a0df4e\nSHA3-256: 95b9474239e8a2ad55ff1c63fc01d1bcb00e5caaab973cebc6b3ab754afbfa12\nSHA3-512: 6032a1622cebccdade3e3a1dc6af6e1fe12640484e14a19de6ea03a21e6d386023f9d7ac9265f276eae062bccdb135641849ab311e0ab0b8344b51e8eaf22d38\nSHAKE-128: 73c8dd4b073e5444b43bee40bc73dd712407b4f893630283178644d6887916d9369d8ab7d58ce0a106c6c7d9ce5e4ed042ad78450cb6fe19cf78cb1741546cee5095f40bd520d9d7b209a6a3ce1824db116f0fb87546a5ffbdba9695e948317b6b0c2ebec36ca01cb2665cb16da80373919761b7c84fd40476ba888f3f2a0ebe64275c761d2ff42e726d0ba1b884a936a11b24935f34dcd3c3183c22726409a6a671e4e735ed95ef6b1c22e53deddc5281410c4fd44a528e79b89e034e593590ca75713c490f2df26d5f1c26d1a9490d2f93fb087869eff5fae4aa755857bf5ecca6a40b964b6fdaf6b1b1c4c6f61be830bcd9a540bcafec08cf59bc099b7e8fe658e5239d62a34f3bb9a9c6a140a99f09fda5e7625ebe3017ebfc6746edaf024e27581c503f7f5428b1e48145db58c52c44566d7d61adbee783056bec7eb24a9fb6d48f2727f83ab424f690ad953625b2d3bb4431796c96706e1e799cb5e422c3a94a4796a92471b6637a2591b62dba79fa672a3678cf36894196a0d7679ce411bad614e634321c44bc613eca7311b551b3a7e20710daf9228fa7ca753fbeed873f8731c3f849ff4e9e873301ed9d1c7d61caf8f3bd61e592e244519b144259b1b51eee4082aa64417c3cfa78ed0d2673661574cbe40f611cb1c8c41d7b38204a5564c7d527c09c9c932b31970048610ec0a25a9778b1d0efeee6050f2d2a8e\nSHAKE-256: 08385409ba4686e09b70739881a247fd3327bc9839fba89fc735f08ff201ea5a4c3e315945d6302a1ac2e444bcdb2447ce2c3c77716a76ec1f3dcf7abf1274ec9d6d7764c067a466f1d07604767f1f8004dd7bf403b82933e18596ebd96bd494a5072c4273088d46dff31a88d70650bdf013876771e7ab9c2725edad57d6ade43189217c1902fe41ef42baf1ca880d36da7d25e3da7b16c1c9af72b2452fbe74b2649209ffd3ee734f1ffcec027079cae8fc9eb5cce3683a5a5071a2ecc76abbfc5b1e1261542dce007f6f98bd11838fce9e60317949f6a277d6b49867da1159d5e0067fca3aa9c209e48466852ec83a8ba042d81558dbe8913cfb0badf3becaf7694aef9eeb7baec2127d533ca04ae51a8a7d4b3fce5081897ee1ce2a4db0ae11f4915026db2708b8c8d93c8fbcc7c66ef1a89bad7e14534f01a66a0f5e3bf32e508ab57b4c2d817b1549dfba49eb311a1ea89af6f5efd85747461a72f0d57f723e0bf8561ad07a69cfff674dd28a0a781146dd2fde450308dcc0688dfad3f905f757edcc879d4354f4666e8a89d3afd857c4b7724f023e82c056beaf2b91eea0ac11eb10fa82a6708148bc4f1dd5c528e92fc087e9cbfd13260956048b053908ad16a31835f81e456054a88109ca3c01e0d6fe863b2958d0ba5c4fb1078135eabe0dbd7fd36dc8d5dc594eced50c757f1cfc8c5e7051c586a886af755ba107\n\nInput: e9ab089ec94a9031078225e0cb5b0bcd6210212c164cd1a8828fba919c57454b8b5194bfbc919d92f986d9cacf335e81b2c94f53919ba2e07bc1e409ce472acb6255b17c4595d2543fc88cff7e6dce778ec821a9d7c03c493d8df88a2b1f857018422cb42f437fd8e4b", + "56dd8ce5dd051fae21a50169f560edcfbdb353ab6e5a76ef4336488a4e455884b63ac717a8d5a923d119d8f7cb72c5b02a947c7\nSHA3-256: ba7ecbf0baf1ae6d66446512b122fda0f7390f8464515a8fa94a162737c8f512\nSHA3-512: 1d76714b2c5d53a10023adf248733f3ccda9c9ace16ec633f21e834275c6bc8146304d874b2d1a4fe2cc3bd816d5cd7e838ac32c3a6bb220e717b5cd7c8135ed\nSHAKE-128: 4a10ef9999d8a4f149d63db1a4fdca6f7825214cae1567e4c9b9db2d9891499ccb4affbd76553746c9c7acd507b2a61f22c3c4e8558205ea8f090cc6bd96136e5f306e7c8730389c1c3c2576fb508625c0132a0ecbb3a8fb17286e8b4f993790b25c96769481b3758aa581921540462c45689305fc3937c5955d88283f8cc856610837f8190061daf69407d34c9370b840584c669961d4b1b1000ec0e1a19c72cd7d956703f43181fd79f52a01cbbe9ac9c00ab4d96dee77865aff2eed26b17443cd26f3e5d4bdc73d1d21dde905663da923e5b378b48b0e78552d96dc76e726b5510fa067d80ee45f4bf666a7026a032a96bded1745032847a63eb5f6a6010f3033185afb514b282bcfdeb328af735820ec6554aaf3220d6713c5a1012e0b0be5e5f28e88d4a8aac6402a9c1ce9019639137dff42c43f37f7478e014c7edf8aee9f57d08e4add5c990826b866bd38a93d615b85cf982f7ab9043cf7af5a115ead4ce3aded10373dedc8b3f5bd5abf0ef3c029ecea9092abd521ed17ef47ec43c7df389e381ff80d06a3521679be60bdfd65da288b629a32498cf65327655e1386700c61db566fc9ca31660bad598240b04c0086a897949372f36e4d4a962fda0325c2bdcb85389a5e09ed83e56f7016d35f825812c233f680be2a025214b76a51a58e0117bb9e1d2eec599587dc8a393a3738bf62f130c276ffd8968394b904\nSHAKE-256: 300cb8a792161c14dbc080c38137a257c355be9b87206b19cd77c3f3d0135e2e30049b23920bb7525869cec8d9789d909bf3c7707325a885bb00931c5d97b47a28ddcb0614ac6d616db79b4a41c38bb1b5d3562baf9154c42d21961f5fcc174a1a0d3b0b148fb5634772b45df564c8608fdd4c4b6cfae4a2f65b543f2e3332663986ac147b5ee7bb8526bf795605f02a2a3eadcfbf19bd2e7711ec7947a1213b567279d821abfe0a730d1b8ee50bc2262c7b84a6c9ccfba901ea80f002c7542096c6efcc3bdbfb94f7bf35b10e77599c05582e4ca1aeb25f2097eca5989dd235bcb7374412aa3d7d72a7ba47eab1daea8d6fa6de5f201572f8575e8cdac34868a8d39f8ea4d8cefa4cf42d46112feac6ad59624db355433018a9776df91a1bef841d74b3c4672d524d6cd5751b780a3a43ec02e5ca8f610fa41500c7f02dbb597a542a5109de728854c06a9d0c969d47ed75f9c3f370d4fd507e0632d32da16158279557e36ef03e71df430205db6d9f90b2b1d30455b10d390da559b087e0e230d53086143fdba0d894fb42119eb567363578ad8a3191ec97c2b343cbde2a371abd50a2d1d7ed26f5166d0e0fb649711fadad192ed3df06be0919dd12f54c1c370b3cd6e85fa8338fc16dd37160137ca75a5d94f1afe6618f69149f127864a783f3d19c5753176b8c39465b054f48ca4cdff8ce7fedd63d2a68c7d970759182\n\nInput: 7e4bb35b8328ebfe88865646060dd1317744f433481c713f0ecfb545f59ed289686c08fd72bbeb05657be92eed9daa5e3722a84cc70d1f76d6eb8d72312de8d226e82ec1b3c70f274a42d48431cd8c250256f27e8a996a4ef55b9c0bff8b743e007ff7113d01e467912c105fd797d871d34ced922ac744ceac5c0368157346c34e2348366815e6e07b7c363010ceae303e4cf731359ef9414bff1274fa23\nSHA3-256: 182d71a067aafd086f57a60067f6a44461ba53237a629cc3f933c261f3c7d6c6\nSHA3-512: 91aeefc4a9c2021a324680c763caac179f71c5beb7bd4d64a885e4858e30ed1647a727563423084ab16cb00cd820eebe1f91fd17c58db901dcf62ed1379ef2ca\nSHAKE-128: 73767c89b554764516ae5c69551a8eb988e1d09ccc078eb20c24f964bdf6aa508a7b99e63b83a3fdd6eb688175659395b61c2a3097a30d0b1dcdfb028d80c22a06a6e0796878d83616c1272399811c335e38bb1df0033cdba3971c8bd72d49d1edcdcbede24ca79dea9dd76ca26e755e8c43e4bf4c55467c2ab3c47ac590130b988bc866d2591297a052d759037b4c144addf27582bf69fc66c03e5b42385b3f8b789b6797b268e4e1ca0ee57c7d2c4f89ab8209d27dd04c0b536a699c17c9778cadeea33cc5c16293ed80b655b480b868dc049c9337412730725826124c619ca6f073e64071b9234e5a5685a87b202ace64e946c61e570cb2a72d6f7432fc5d849a316d537b9426a11488f80c87735ddfb71fda0e4966070b9e05a2a75399efdc572aff98ddef686642c7511544d79057b43773230aa22982aafa90a95d3bc06932f1dc39469480c4d9e8339b78fde08800e448d2573d6767b833b58cb43155659978a724bd511f61931ffd33d5f938259fc84467ac15758f07c76a3ba046f3e5f67f539bd322943572d69547ca77f77272bc6e6c21debed2810cd404603e1148b2c7583bcd1d2096648cc278e5142feb72c8514a915a4ee5c90c9e386049ec0b13b2b076f99d3f98a8498ecd4ac0187d3f2d3b5d7f0bb95a65ec7dfab84e3785edce8eb17fed84224cf17f5985a48992c543fdec4b5801ce6cda6dd3db47af\nSHAKE-256: 6bf110f1a992782fe40bb45c884c97592cace7ce0bbb4eca05cc8ab9151f22f8bbc2e40046b39ce4cd85c17a8dd7b4dca39938ae5071e2708d4ac4a3c2f3f8443fe07a17801f7e763ee059b587b994fb7e6086f2fac4254c576d732d14fa191135370af6d46a8d024ebab2e596e8e2500f0c455b4975a08364e6f1108c35c9208f948cd169d713027c3dafeafa3f8d9c85ef4a2e1b656f6decce48ddb1b84bdb90f3c7cc7747ca15b2da26eaec6ba66a12fbcf129f405fa3e1b8ebae0e44c36bcffe7d316452fdace06f2bf7f56578d06a7fe09c163ef94692ecb61b0f2d74a7d7c6522df5768c423595c97ff91545e84b9b87c81ca8b0127135cf7afe3482c078bc0ec5dcae15e2184aba00e06abddc41c15bab15e2a0d7a12c53a6b472d53f9d8325a9e8f489bc9883cacb3195c5587ca4b3f1139108d0686c6b1552bd328ce352f2d39d244b2c8a84508692419be682895c6bc4962d956dd7b512aceb5212c4f4509a2bfac6ccef094ecb8dee50bff1ea609f21a25fc2163768af3e5e061435d376ff120e408a9471265548259fa102a4bfa0cf544b74a399b972a069732ef69053e8e8d5818b077d136e5be9c5b615b23319a9b033d5d810b225b8c7788a2a6dceb7410daf71dfdd76b0f870363315e11898d994a797b472993cc9660658aa48a0dc3e8aaa2b11f51a1495c4b26d11bf85a1bcf1757fca2bf0fe71293662\n\nInput: d1fe4c78f1f7dc376abf4845629fc9905e6f5428b92d689392c81a292dec6c98c3d1bf86b5466c7df2131dc98bef5e80dc3ebd1819da22a7f1f3bf3abea76472907162383866879f0d2cd918bbe3755439118e093750a8d8d3ccef925445c443f96065600a3142a8ed7c568bbd48f0b2805882aa0e19c5a261c7daead4c5eb907ddde1a4f2286f7d0f76c5969e4246372e13cf65f0a29d5b3c136bc30d2132\nSHA3-256: ab562ffd46c2727f91a75f91d7a8a4c0b3e5754a721f9e6002c1eae51079da08\nSHA3-512: 2f42ebb2ac54ad9290e3e4b559add7336119e30bf30c31e6a588abb31f92f80caef6e2c49b2df1bb9b47668fec09a55aca69564986699b30fa201bfd8b7162a2\nSHAKE-128: 85ee6e19087561f67df9bc810835e6dcfb116551fcbbf2e9792208830b8200813019a68be93a16e9066fd8c36f012ab406fa82ed956d419d68b5252c8bd26cd5e87217accdd573671d47025f6bb1c580f94a5c68d39ed11d05cc85a224124c840d23d42fc941a950b3e6db9d543efb9aecce47660735b40d4dfca037752445af7e979d0d8ea89779ca68a7535e817dab03d90fdbaf058adcddc62971898c60d723b5121ddf3da39d3d1bcf73018dd8d677a7c4a98ed60f73fa14e21e5078ecb2f36e7bd1b1c140c096e194997a5d03473f9afb6cd9e87eee5feab1088a71fe809eb303feb7004e437ac67ae0b0b4b31e2eec7230caf474906972537fa05193028eb957639d04a745684a404c172a0bc7868628a07169ff12417473b7a07bc71c7618ee12494287955ce4382833ead9e1d50ee15fb30b0b91d816299f6e65d74acd6c5f01efe7934dcab624926c2d53981e5a82dd22b69bc2bb72f8aa41ed9890072178642d2fa1d84c3a7a58d15accc9de8b5732bcfa65bac170bde985fd076698976bd3ce1ecfef8a03c4f81ad2611dbe3d70f75ae928ce61c670c76f9d22c809eeb0a98f3973a98c4e39edebfa0a756c8c01a82d0c9744f5f7ff1e723cec17e63721f45d83c6b06f7afb22e38c421ec2d4d3b5dda280f5d06ebf8e548e817ced6d3d35c6402ae13caf276f63bae87614be1799533f6c30b1d1e17fcb88a7c9\nSHAKE-256: 2d4d2ea5593cb0bcc7726a7928036036920b031b14359fd15390d27fb4ce5d8ed59d28d0710044cb2a8c25e2b491170dad1d31a362a6abe79b253859ddb9fecd000e3242ce29e11df34e730bc487be6fededfb9701f643d933d7057f46e0f9abcb9ad1409bac576cb417e2dd6ff5a8204d3daae317ee82f42c79cab4083a1b27e6d03b5007134dc9b9e961e0aee97f45d29ecb94ecb7a1a5540005d7a744284713301084c2ec13909b3a4a0718811797bb47bdb42c90ac0c8d21a5653d7dd882894be34e81c66f372814cf4b94f1d8a7742107f74450f82bcdb531d4e8bcee06715e1055cec7356d0c07cc6abc1747a9d60fc1553c9ae7d7698eb53a1d4cd3b2995f4990f8c514db87d6b6571dca7d9d7a3b0483fbd4b9578e353ab333e9cf11ae9008b48979187d4d5ab642d0073efe84bbd8fa29df402bf1ffc00d662cbae14de7d2891ed4d77725cae74367a763fccaf8099a7ee97b6a559583c35d1fa2ed6f0f1989a83fe356dc3c33d1b5f64bc75369ab5f2a24653ce928b0f783bdbc19d31305b702af2282da3d2e8a4adac2affa5932e23b927ab85d81190e4efe7dce69e1796f161f1bf9566cd19750349fab0261627d1a5cd98cee62425640d4d8141c05eee7f913b3adf280581053b4e6afbad678c44bb21532afe4b9609032542c2c0ce4187502ec1121c2564ee7f286ff96620f5c8f7a358933827002583a54ed\n\nInput: e87af3414bbcd9f741692901c14dff358a3a27a14ead780291816a287ef93f597153c2d26bbf19ed0de9a81627e33b2b2b2337565a38da60eaf580c54bb0e05961cccba98042bf1c6b6477e7aa799b8bc49efaf6cbbc98bb5f02eccff7a1736aca4079076fd49f1291cdf3e5a8536bf8489cac8f1d44a663cf72a923d276ee5579ff86e2f9d59ca59fc6c42c792a54e11584d1f176f605394f93953c82167ef0\nSHA3-256: 24008ffdd3b5d2a93e226b145b865f6a5ecd9b6e528ab23f7e75da13984691dd\nSHA3-512: a0d70ca46c115396fba0e10ce55e58472ab813d65561216d7a51d2144d8f318c2cc4102bd36b71f1570f455bf821c332b898846809a5ed0f98c25f490bb9f806\nSHAKE-128: c93ffecadc392eeaae213006", + "7523719ef75bcce8a57c4d45c3b54c8ad1bf8cb0ee8c5a7374ea7d9b25101fb508c3a4b1ec061df7aa357168b94fa1b888f74eee46e06c157c50b4cbcbc0531f15b22b893d733b0d4d755cf4a08d9bcebc8a1246c7b1d5ba6833de9d641bcfaf009a5660849021bf02aa1560aa46e5ae35ea7dff61aae6124d8e7acb5f7b79c67990a9e4f6cb7ea047d9fb0d58442f8e8b84009d853cc3a7f1ffd9173d56ca74f844fec1e3fe90b105389445b3e9e734dcae38306d6fa82c1302bed06a9d9e9c94adb4d759164d74de1e3baa5732ea7c090b273b1fd2347797f092e7801b35758882e9235fea5cbaade88200ef9d3ae839e8ec989d5ee2acdf68d996543000446c15816cea5ccd2330c7ee617009e2cd6807e2257d4f15d09dee07e6dc1ac2cc0ea941d22c0e9ea4d3450e76bacc08031dcce4454894afa20400d69f7713d23b416abbbc90c2f07e923055f62f5712fb69fe255b13f2b53b2494eeb5313618e53c1be10afb6401587e764c402f1962ac3886c3c44b023dd88f1671840f5598b1a13356b5848bc59efc00d59090cf83f769a5cde297a91e548c1111c9696ae2632f7da9a086505eb760d85d242128ef56ff49736b4a7caea885504d0c974931e1154500458000e1ba03112cb356957d311461018442dc5f90f9043c8474f03087ecb4636922db777bda1e56d772f6fe281f0eea21\nSHAKE-256: 7cf6634545790e7e64f15e3a156b62629433903968cf3754e99117fd5afae7413d2bb56bc1563f0f0c78643536d39135a9eefd23aa8206cdb9008c6d9ad169e0aed69fb060c449175ba706e17b1b4452c337ee8ffb2b078518804b01964af84aa1a5c812d7e885dcf935088d4ae2ebca1587f365e467fd5be8959f300aade8c4b1996aba14c90f773cb31253dc6691af6f0c1dde9427679b48eb22a8a26e8cbd3152a8bb8cf5b61d870bdb122ed8099fd18b3d5c710398ad83e52291a6b11c10a516a13fb11bd129aae4e6c89a1189a977556da02e563c012713a573480d6fea0caf7ebe8b6521a417ba4eda0b8578d0327320d1449f9defd6cba5fd299b47f2f3cf014a00fb592e955d556de45803d5a079e2ca719a9d0464bcf19322b5a8d598b2decab8b4f85b516ffae0eefe0b0011a4c0e6417b9c8d25fb5942106f8c7c8b9fd141fc89c8ac98c416448adb108c62339b408ac5ade418e3a58a5bc454567ec15ce9c2fe38e6cc6f1c3e81dc4dba38793312933a43a620e63a192a05275db146d06fdabadca5512c57da9c082437b1b57816956a938ff709e110753c7be6fcf937e06e60e9cf61eba19dfe9c80f96782fb73b1359c591c2e6647902c18c0eac2fe0cb43745c93ca7fef34c1316e1320bcac080557862fd438bda3e7034d04a2dfe67e7309fc53bcaf46d7330a25710c61bd17394ba8ce5aebcd4190e03fd\n\nInput: f2789fb6d04fcbbefb1db6ff38c0d198f440eec808740b4a73c1b733e0637804beb35128261e7cfe8543242ba4918ca7b6cb545c21adca84cd3115bb85ffdd0240e99f47cc1052a26698488a0868ab6952f91e9822a69d1db0b2221dbd1ab4b635c3fa08437efdf813440db82f0c47fe087ca87dc747586dc8067d89749929490856a760072c5fb0f386733a794e80caa391278851c8e2bdea574b8d47a143799a\nSHA3-256: b095951d8d3e0a77243f696035f79db2cd0047cf9d7779b825f0bbfd223083e1\nSHA3-512: aa3de4e05b22c4d7306c072e664422cad7c866e0291abcf3537d62ee4d5f9825fb788a823da4429603507870527f66eb87005d57ca0feab0f66ca1025b2b5895\nSHAKE-128: 79c849d27a5c454d539960000335861cf49de47d45539523b84499b6eb121d727fa5b5d8bbbf69ba1d0256ad2b99650f64e0532fbf511c763f70ba7a064c5ca0a03cca6f5adbae24200ac3c2e5f224bc7319c5fa2d49e5c91c735202374bc0e113a41c81bfee4f098e192c496e81c19a7569a757a2b1d48b6bfbb7b13ac178ada062c04eb1e010370f8b45c0d9a3ec55a61e1823f56dae26e416483eb138f06265f0d44f7cad5e48da584be3eb76d9a17bd7218609b76eeb6efdc0ba1f3e88419c921bb84421d966cb0884750237b3a2cf4a8ff2b6aa5da6c57a39eadd6aa606c7e312e14a7ca4c6afd035d51c1edaee39f9b6d6bf1cf2a5cc0a5d944ba3ee92b4ab18dac7bcf11db689126e57efe254a9cd179b463b4b0b1e584ecda8ad000ad5eed56f57f9014282dfcd8074f7fe617383a1e87558c42456404315aa23266b0696a8714df811faaf8e7b623288a49bfcfccdeadb7cb0691ae1b7bf2cd7111786d1f52084cfbf4bc82fffa49f732b806866f8e3acb97c15fbeda83d6dc1dc76ef64900d336599e357cc8def03c419a8aeac087958dc2e0686f664133e758d6031b90a962ede5c6e1e70b3843bc6c7ac4c7eb781381fc01b2a5a720ab0653a0df3dfe995117a3b40b8dff547183a11bcc9c3787519093fc95ff0603cb75c8a808dbc016f516012bb651fb7dda970fff4c72bf7587f30402509c209dca0f89570\nSHAKE-256: c9c0ef0a1f642b0a05e969d1bc9310359b958e3cfd5f6bc6bec4dd662bfc4a6c4a2ca497811edf0d6c2bc138c7c2ae40e7d31ec5fe2c50987a284d3e537274ad77e0a02137bb3ba85c71f9e78bd6e5667fb4dfdf34cf4c3d4d32a5e40fb52b5fa896cfe7948f32381c70520f8580489a7698979148ef969ac0af5ef0cdd92ca4ca214de6df914fa4e9188d514d313fb0d9ceb225ee8b009e9ecc3712903004277b9b62e4e9fc2dd6d4b0803acdc70b27c4f03e8828d079620c1766d4d1093618eb77b3024de0f71f1991375ca91d035027cd2569b076633ad87efb3d102beb39ac18963da9dcce8c2b965edf35476cde6a452ecb07500481679c493814c0c3d93d6f35b70f51d87e7e0797a2adffd4cd81996d5606e48186a384a4f3956aa34991f41d1dfb6b8dc60bec8971e443ef2618ddb68f2132b9b3855ef012a91a60553d9d9d5f5cbc4d8b9810eb0b2d00985b8c292ac0819d5332084fb3f5bdd689aacfaf39f15f82e7caa3176973fce4ac4a8c716eed8cdaf016f259c47d7139ec9edf9aa8c6e7dce1d2fd958a72d6a2618b7a38bacf98155972490b57f994d391cfa03ba2270e43716deec550526a8513f442cde101762241add510cee2b5b5fcea5c745787e84fdfaefa2a4023ffc6894f049c555f1e01b5fac5ff0619b4430272eaaf453dd997794fdb98b1139e8f152334c816db3d051e50693bc6dbfc8f9fcd\n\nInput: 848d5fc2c126072764e27f29ebdf1fa244626ebf8022dd147f6c6721e34efc075ef71df27347e268aa84c270914f97d1d47b4f9d21dabda8ef6568fec89872ace42719c6e9e6dd84249944f4ee4141181f4f8e67eff691de0a983f151f3ad25e12ba9fa1a18ba1ce7271c30a87de57f251a02ffc1b38b68d6dd501f6b077589faaf5087d00b6072e19fe1ef47257eed2bf1c35acfa4e61cc09e0d9abbb169aacf15a\nSHA3-256: 73c860e8fb1a9872dfbf999c14d26e432a921b99e4d3702ac9670397087679fb\nSHA3-512: 0d723fea7923b4170183443c36afbf3a13668d01761ec72fd2560cefa38e314e68bef8d3d2607362aa3cd1066a05a541d09bdb53fe3157a1759542e3e0343783\nSHAKE-128: 016779419eb48c2d1403e167293d9905e99633d4a69066d6f89cde2888591e30cf8384f51ebdd3eb8d4d3bc059bbab6b8d2aa93bd9edc504855b8e7406afd22292e0ddb88507081f985d00b838ce6d9614505879b131c1d87862499306792a3ec46310da6360a51f2b48093f89847f74e9fd9d953c3cd4770f8295d40b4e66c5d92162ce733afddefdda4858a1717de83ba0b407d3172cdf1e2106dde5379459e67cc3803ec28e6923710e9bd23f6e17d64243ee3abf0cfbe4432f9895b019dee6043c57e89baecf588ce14b98b0745c2d675cdb9ab269e3d33a9e56f9dd932dcbd7d908f5a64e0ec6b808a57cc3c56e371f2cdbd3aaae7c229c89a9926d7b4cbada16832d6c7a6d4c9428deb93d569932683904e029cb578bb12415d0ca9d334a8edfa1245aa68709dc6a23110777bd660f32e92f0591ed7d94982fc3ecc4bb92a5392513571388d06b6641286faa5ae9b2684bbb713a133982c4ed792169707ca20e5869ea2a2ddea1a1b7f1ec761339e44cefaa0ac5adbe9e07ae669137d17a074ca810756f04a8cd8888359b313fb81f74fe9eab0b1d3594d5878baaed653d6630bb4c08e9900cd560f4b30b4a5dc14146b140a4e3b15861cfca47c661d1a1cda7e13c467c7873f782fa5bd5bac6a0172657af2d6cdde6cbde20bfa25d2071d10f2cedb808330cdd360d732791ea40eee037e51bc6bd9943112bb2c50a0c\nSHAKE-256: 11a40cee10e05f702c723eace5c5daac6f67d579b2f7157dda16dd48074288e00f23b5ee7cbe1c0cd27e06aefe80c2515b5c0cef84505c32520358a2499c69aac428fb94d6df9d6395837b4f1bcadd5812fde5cc87436183568d75c078b1f350698e1bfd681f6273191353c52c32b00aab4e78fb7a82801776c064d53199f2e7b448ed203b8fd2612747de9c007acda3da1cea87da270caac3b3474932543e159e25235a4e509c7cdd666bfb0b7a04e9c9c17f0517a6b25d2f74eefbce53a9f606d80de7c4537b5ff5feba24f572f5e35de71e9cd5ee929c8f74b5022d3fffb4a2e422d37663e010dd2957c681dad0a7656739017583c556d40224a1a8daedc7299cbb8cac833c789ea3cb126aa82cf2cd8f033190edde93421050d74245883c2191b0b24dc6224e12a604a9093c493ca6918da37d3af94d6f0cb4e040d28739414b40f20ee7c3ef0c0436f6340ab3caa752c761cc6382bd6a13a8f891e7ddf39126215752650918cdf9f3bdf405739e5ada97b96113ee33d2dc2c6136e385adb2889050c4177651b3fc8b9bc3664bb64ea332a3c9d826977bb0c7421dffe2869c9417a217765b32e7b59ccd2207e2d199eeb77f56aec5a5f44f872b113c5f1e229746ab4be91f0cd7ac2ef9dcdd5a6bb5568197af6bc795e60c50dd13dea0f79b3db23038e01e2f72b3fb65f8fee68c8e60d7506b9d4cff4aed6f16a2f46cf7\n\nInput: 83501fc9032d8acf59d621b715ce019d203f06c4f55201e594c22d038653146aca9bf0e4eb9a69a2c093c3ac7aba01a2bcd6ec9389da2ba4cb8b9ea0581e74e25c41b2391182ee5b0c567ce7f4820ad3dbbb99743038a3ab2568358007a97c3f68592806cdbd89d4b7073cb40f410fc14a8b3c20d3c00b8c694e068b80e20a963257c300010524cf4e66a8fcbf6aaf6ceb8039582db1c81843359afc5054f298a975a1\nSHA3-256: ec2619261c286a2e0d784c509bf1b11aebc1b50ce5fc1451382a747fb09e268e\nSHA3-512: dc9bdd4cf49dac650945f0b1f3c5e087cf253ccc529580b60ef0cb201e48f8d589b04ff10b8095b4f700f0fb18920a0bdd7406babb42016d0582a31abb75bc9b\nSHAKE-128: 7c18516ccf2ffe4136bdb96a2b436be2e4e8d3bafb7e39ed24b361ae7db71fc4a3b13a9427f6192a8238829d4065a4293923908917df53ab92b4034cfc147b82c3acce25218cd584bd1362c92acbc36e6af8b1cd9eebc4252172129f3cb9e49547889f9b3f4566b9618a448eb894b3d9fbf032fd6f9b99743586c49e59aae8d0d877d92d47b9bb26ed6c526226823e1b2f6d79dddea178cabde0219a20db2bfd60845726254ba2e519815bfe4ce7c11a9dbe363", + "d140f000a95cf12ce843cc7fbdd23e6bc62596afe0301056e9567951f3a371f887f3a4cd38a208657e31a8db28ea309f914ee7398ccace75564a1b35b75befa9a5e74b1b758bfd290ac232b0b8ceac38b261bf1f7e8b42ff72268c83ed71d380b3af85e81afb3f28013997500c9183274d7926c28e543feeed77da4120e8fdac0adb439f9dd363ea3f103e606c35aa725d9df9ba3948b58eb0b3bd00719a360f5332e165926bd1c88505ef61819590a57834ae4c8f77d343bcb4506aa63db51629f890af8c792614f4d5aca3d92cb8d9afb8b7475f3e6170197ba5995d9e163cfd93a50a3c42d47fe10ee7c0e65e68b646885ec98fb92b578ee5801e06452cfc50ea77ea87d41bc50e7f6b44685caef9865912019df05d256c0704f206cc383807fe2c769d02a990bc79b624c0dd98057204b10b887715d04a1d17a36e8c741dad282c95102213da7488c2739\nSHAKE-256: 119754489bb54651c5c1c305570b30b09d9d220ebbb60047ecf0bada89613bade48d4cbe1f6973f9508725b7df1a59fe3766d74d9ebd4fcf355737624095520f5b4b1a39c7f382f69b21b621029a64f892d94c7bf305136d60e9b2af4c5d845a3d608c745411767c50f6716ef6927271f39b2985a26196761e6d342b38428edab738e4a32f9208d6388e19a187e7a2edc056308b64ee17a53d4e736af01bae3cbd81ef3d5cda4ad5de8b4e239e312079109c6b5d49a5871439e020eb449ba945455117ca6457d1959f142ecca866f8f9c383a523a33b8bc90210473cefb2d06a51fda1e564321f10faab67ca70fdfa461a7d631daf621b3a4a1244cc7767b4901ed814eb3ac9fa6f99183e404101e747e52a0d5634bb0dcdaf9edb04016f1c5afb6988fe7aa7d299c058a41cd2ed884fb4064707ca4d4089a725cff2a61abf7037bb65f392aa4d0c2ffff3945f2962959d8b0c6566915ccd19abfbaf78482ed8157c4a8c0ebe62030b7ee07161568a4fe52a4ef2bcbeb738df0133c410f01d24f0c1564926346d558ee47955470cee58dc78d1a8a4be207a0118aa91e911588ef2085e4ca90aab257c4990dffa7c743c13346cdad1703bf29305dae008c8be89878f91d93a849b34863ae19eb31bee1a8b26eaab31c26453a68ce2b243340589c29680e86436f19bf3ee47e85fdb367d4669b7a199eb0bd54d697555f949cacf\n\nInput: b9b9e7892cb52e97e0f283fd7220a0e42bf94d95935e90e9f7e0ba0ab1a709d8da33a4b5f0a72cb50178d14f617c1f106d9af0008032b8a4ad30344253382328427c47a5cb3f88db09a6dd7ab5d1f11c1ab3441db386ee4daf6dc09ba86d13d9f9f67711b2d8d77daf786bcf1e5f69945f1343b11d66564ed8cb1845adee2f2013b3c4f0c0d66667d5d60cb594aaf3cbc71f6fa6819f5bfe4dd43d77db108b12259ff10c\nSHA3-256: b27c5a57455ce51df39940d85f76b5a662743c57441d8384848f3967952b2141\nSHA3-512: 2b68cae4a177e817d050679503179bf2674f8a70dacf0759d6316fcd421abfc019c367c6bdc69fab96593b2c6f4c6ae3be28a5695ddfbfa3bdf45c36b3208040\nSHAKE-128: 740cad4c5aad97ecc4c1638f93d11ba9826a18a21f1224632c04b3ca9bf4e70c6db5b2df228797e0f68e245592afcbdccf908525db502c3384569949da2220177825c6ee2d9df792fbf603d9a4695ed034d02d94d41579deed46c1f97b59cbbdfb84c8bb1b54f8f423da5fda83c20e5f9913f7cb2c027c3520f1fbc2c8a1bba9bfdff3126656cbab4c2cc852349e454266c392d29166a7a602c5f0a3bf34de0ef6e310172bfa36fcda31d2feb28a197090e2e38967110be72456f6f9030e8e1eedecebf8d9b157bf7809342b5cffa68277e3a236993340305fcbfb9cd06cddbfc078835daa30e7c3d9e3fe77ffa1266fd1ceee51e320aa5531cd4e7112700ca84651cb7f8e60080c2875077577838540783810d0fbf30d6b844c62db4cfa2d89ee776b1f91b9d363701c1d71b59afe7874ecc0a21bbeb4061af730daecb6a361c4eb759f7310fa5e8bcdec9ce569ed4d20a7626ca4de768727c938d00632982cdca044a2f835f7283fc8dd1f0880e30aa17d83a240e72b3e99edf5bae01fbcb44adfe189b5ad15d8dc543c40f1e3d10093d250d62387c289de93c2ae987aa3deeea142165134eaba8a7aae19feee51d9bf47757e23b31be47a41c1a33eb6da831557416d955cd76e64e9cd69ab8df45c34f0632da14ae921436a48a4307eb49d1f7e8ac20691a5f7a776745a7fdf397b3690d26a04f96e4b44b9371190d6e5ef\nSHAKE-256: 40edeeb03068cc292c20588a1e046b0f8853ad28280b984832a8bae24c1103c980f994098964ec36ea15a3f4d87a819785b80c9f3d792cd6e2dee4db370837c7ca5928da817ffa546e1665f5ac1672594249c2243cd25110ed1dbfe7c16b6b81b746bb9f67297f08c6394c040badef763f5238486804efef080213f7b5bb739104f3a3efa75be7f378fc53954a4f31b125f3faf061bbed5e0d019dc01c4b82b5c77861ee021d81f2508533df4af9e5accfd29daba0231c2a7b76facd1b8aaea25f0dca2566f96b023a3bc810d6067c3b9b5a1fc60001af1c102f4c90f6850455df2029038e0f841b94f1cf78d8c4a589ac0d1d250f8ad8682dcbdf401e4e282f11e96d7f826704947e52f0aaba17ae73ec7fadd15764fa18cc888923ee5233fbe9dd8ec5e548839a093a5693d3375aa7977c2e71cadc6a31d3b967b1d57b0ed073181d7f72b23db161decd93e360193e372f95a2ecda55a4a76ad573d6ca7df7c912a1218ffb14523e44d131837c31aef09c45d0eff172f0c2d26ceb74e6a7607a0e1bcfb5e6cb8fec42d1496c7690f4872f98e7ab4f183cb278b1b4e76d2f9c05d046a452eb9116df276f383a6903f41ec8723bc54ed051391defd2a693dfd82db2e0c9786e9654e3a06f9dd5a0054b6b6a5f9e9828ae8704224d7e62e8e88244c1dce41d5cd62f092b6accb858a57f3f362c57675531d8e9a6129378577b97\n\nInput: b4aaaf6f9c39082760a3520a09d5095f3ac27212875907adaef193cc2165d5e9bd85d4e622577984fe563b63f225db6162cac5486eb228693530be75e454f52c6034b7b02a49a80eea1674ae5d7647bade2a32042dce560c8361daf26455de5106b332bf4c0e7c3b0b9749d5ae36920bffa1bd9bbc69f656f18b3337f2eb1c3b7a599dcd3aff6cbfe8d857b8a31f549d59930de178da85c3a62502ca8190638af946b9c33d\nSHA3-256: 823738f36e3efa6f1d2a590d6dcb8903dc3a2dbc1716df61945404dde53d1d62\nSHA3-512: 1387e43d7c3a6913334f8a0c9ec8dc8395df3bc78e2031f1cc6421f05ce3321eea99f6b6b252c3581b1f539d7b63d01f4a6e34cdb77f735c099c5d4d3738a70f\nSHAKE-128: 3f852b8a272a3a9cf80aa70ca6c979ac623ddff272f7a0d5f5dcdfc50993681d2f1a09c7e9af9e7736278fb49d6e8959a702b955397373f104ee423d4337d4e12a3ff8923be9fd5bd227d2e496a8ccfa9f737e787b795e3627088f5c918cda6dd8aafd31b731b8b5aef911e4c91f9538b426f62110913ae14284d8a83c4c3b8fd6e10976f5f63e2d585fdf2410e5f1c1b6ed3565002261652c3bc2a67082830bec3df9fd778898ecac252686eca2e4cd4d62204436b186397bd3a6fa874de73114f3c8576ec6aabf1617ecaf3d518283cf7706caccdcd90e0d1a2cc19e1cd36a2910af3f6f29a13a9b79e4122a584517690df370067f36138b47bf7816ef5140dee01c19ec085013867a502e6e0c538cb4dffb107f4ebe215cc5b69cb72fb57d3c21d3a5c2b32f9e80fcc41a0438874aca2364851bbb2078f16a4171dc74dcbd80855fda41544ccc5921c5d7f29b5cea11cc5c153485d3952fc39174f0ddb432970a1cd26b805054ed387a9421998c3662e16b30a75cc7fd4b942aa6379e7cf8edd5b193feedb6a213d7120643fe40bb118515de6c6949f901426f1c87b6aab524cd65bfab7ea95c06fe6b7ae7730226feefaa4eac8fcdc511b9ef2970eba8297d2e9bf1b5adfb2066580e3f2d171a76bfdadab2e1b43b8b2eb0db2743263adaefd3bc41661f3ab8df5db258a9b2f3a69373250e57e6e1377120af3438741425\nSHAKE-256: 457647b9eef14442838f4fa1ed79947cc5c2f4197a631f81b70bf51341d33f528fed1cb8524d29005b326e09b9e2caee29f2c459bfa283a316da7db6950796e154d6e1a6454c9eb3d0c8562a91dd29da5b0aa6fc0d71f844a85a55f4bee6194e33e796f6cdf1c43d05c9159c3fbad2f453fb4ad86e3c5f0ac39c48da7468d93a34ae7a36a2c9fc1178c987f34902fce8931a1142ee1a9b0b71eb28aa77f54f159073e207fd467d312c1bcc94881168f65a89e05590833842d44724bbb2cc2683c5775e976980b5ca887896590de7812554f4e3ec4dd392092ce214f411d1427516c94f835cfd68a6e8f8904dca04805b10eeab8c20746a9671c46f76b8c49bcc8df5b776b2531f7472b60cdabf6e70135d4a43c7ea8ad8649663b684c1f72b768562dd156cc2c4fed3084d4180588a65de8c5909b580220a11401ce3404798856cbb7aff796aa7ee62b5dab8aa367cbdbd0cb0edb8e08400d16e4f3ac8b683a317e58790af3417b89e8559fefe7d8d30f054c1119e9a0320562f8b8b4e619328b47a05753f613c35d2dd0772fba3bb98dc00a2065ad59c6c617c7e787571273920f457685abe5e2dd14a7ff712353b39b8f2dff1a9a67fedcd64ebcf12d72e12e2b3836e5256b4bba424cd7f754121a7cd5603dec1592eeffa9c4e60da3758b9a9863c2b2cc287b866fe94f936d1742a395b7323bf9058c197cf85e3a1d5b1f5\n\nInput: 830386eb7a344f9fe631785f1d4d4608d3e93549633e95676a3b81a62f86fd1f4dafd97065094ca3cc721101c9ccf95656b9ba49ab3ae44f68649aa310e94c137197a7f7318c73e42b831855362fa32b47ef9bb97425ee31516292e8b81ade54937e359ec20ab4c5fd2962c1daf97c78c093050c1fc828b6e7c1791fad61d90d19f7d8a67c3942fec74de8323ff9f40088544109297d63edde884526450199cab2d440fe0dd4\nSHA3-256: 8a1fdee075f3d5e5b7847613b9ee7d527538308ed50cd8468c653e751902fe19\nSHA3-512: 03250f2a2ee20159ebc6be53e0d861f6eb3369efa5e416fed9cf04bef009e0f0b05c8d1833ec52e7439aa46de761529895fd055e46acafd19203d18a6f78d040\nSHAKE-128: fadd40e24b35e8be2af90aa7b41b68972912137aef1eda45d912aa3417f7fbe8d2b990656c8640e3c5b8dc435e86b6c3074218f32c8fd3dca13c4c738791f0989ecaaf7d37e3657bd7e7662c45037a7f088bc9cf5831cc2ac7b3594641a1cd4f3d7fd2dc1ae49aa0b321ffd76ec342352683c7dab46d752f7c9b308e519c19b2307a03f565701df47a4cf3eb8e32fe59dfdbe046b3b4e989996e1b47a2f6131ff4db301e31cd51d706dd6457ca8950cb69ff4038e6a369c82edf972466fe1346aa80a1f5f03fdbbde4e6c068da782c6ccd97f4ed5b3a089a2491746aa1b493e389b56442c2e0c0496b25c0536d346d69954d1dbf796069d06141f77b4be2bc78425a8c5fba4f814e8c36c0a439cd9e7fff0c55f9ae0ccb44e8f49665406f9101cd72d8afdf1fc7fed89ee0b983ebe6b6bb35040d072fff50b08e13cbaa501675480d847b69cb791e93c5222b3090615ceb66", + "ff3dd169c2b1ce802e2be78adcb5e1aa8896ea3a6112c6b744d8596bed5b076e1065810e51037a4592c788c1fdf131cec6f3a6759686cce4d5d2a0b7f293fc042d4ab79cb498e1193a3dc90db2bc9e80be0bb9f314c06bebb3434da76bf57f98a0258e951d180b13bd69d78c59fc4c13a0f6ac820563cb65c15687941300c790e0a3f7515c368662f8fdc14aad64b20f0d92f15f9d2f6bf39832b3fa485196cda5fb8cda8d16723688af667f686b\nSHAKE-256: 018c8ab358a7ba3f03c01042bdddd3a006c79a955044b605831a401bd5cc15cf43360b19b9160fc2dc539a61236c29a8af6d28ed6b1fd067b8fb1ca400ecc0e646d5bfef6ce67f7545400b9ed1ad3ab477f848d725404a77124a1a1df747810ab637508e7c7d02099e225fe9391a2da056700a920e819da75199f256ab27a21f8d10747657c302aa90f2bfba7db39840b79c9a95ed2927aa4e4fec2b671dd789ff432eb16e1b8020e6d19208ef559aa468ef47865b2233f9edb70fb29f2f2c84a436c92de3f9b216976b9ab797829531c39a55662b21bd31b95f4c9efbe383aef4bac096e36c38136f5d707d5288c37ca5760fdd3bde2088d9def233bef062794b4c383f0b93f995b61cbe9b0013f69bbbb0d06b5471f20585d98aac770a03cd47e83077b18fc92767d64100d8988aa9ce4186cb3e44e4bab4305a58c88be97667e7a67e671b9afe60edfd63712235a20c60c21d0455ca724c5c117771fbdaff071173b387a02726975d865dade539983a4ac9b791eac16c8de51ec53a3af5c319eccb2c6ebc2087578cee7605da9ef41a3d816a9acf859d7a822b0d3a2e6284e50aab45bea3158faf444d57eea33c9873dde12a5cc80d172d2414aa902c507ab22777b025af79ed410c54ea61a87b56e019116da8682accce6247d098e2e372ae73300c0edd14819df3201682bb898fba4e4dfc0cf4b6efca5370fa1dbc5531\n\nInput: 8183466420f4a3d6dc3bc05dbf2bc0f54bc9c96a83e4d054d3549ca49d3c9f7f559d992b1f151d31d2ccf61cb279cbc1122b71df0880c4b07400bcbde5eb0448ca62079db6182709f2e44d5a7b927afa4909105c0eae0582fe14ea915218d8f2726f93cd1c288451483e4b074389806fd8f2d39c74ea00d77f8d73c91df00e1e27a40038d5e7423172ead9226f492cfde73cdf020a233df2268ea15c8960d19b95ff2bd7a9db25\nSHA3-256: e6588b31ea9e43f1c26c07924577018917c1709a9373c9ffab06c6db3e9ca6cf\nSHA3-512: 4e0bc9f85b50426febf28034b22a42dac17e002c897f583ee5efcbd1a304fd825c7a202f26a5fca79f0303b0d11ee171ccac5e2e1a929e3da80c578291e60f5d\nSHAKE-128: f93181a0b2741264db275e23c5ff9fce536e748dd483662399159d6bf56737014a3cca4e34fd44f328dbc3e0d7f8885e0cec26e70c3bf62c79b1f10da480ea03e4551f70f9a835c0ac46f32763d3cdc561963b5530662c3c6db007070f40284322738fcb4d1d15d9bb10079747a5e8fd6e4b90fbfec332faf25bd180cd91d5a0c339e80fd959931b7468a903dc9b4630e799c322b6c3edc9a755b7da28d3667efff0f971f243da5af81dc560d62c8480ff2a4e01c43f3c52e1379e8d7f68276ea5ea58a07266419b0d13fd43dd7185434eba711420d1e84253425a09b4ce31902a4e36d6044a1e539613ea3231754e491b516e6e7dc4603f2ec9255261f1014efc2414a7ad6007c05a5b245fed6a3bd1fc842230667a91a40a8e9a16b6b3d2d6096c6382f4d92080abedae2601c6bd1ee0541b4946b73d52ded19d74270abed03aa9dc7be910048cd9d5ab007e28877d6d506328ee9b2f389e29a31f21f2a1d44184ee3e3ccdfb4b0643845952218c41e3eb9c6e7534d82d014668fa14a4a9af3047da861327ca06e20328418719b67de3d8005b574a49977aa6284b8b36df5f74508c21b37d57616da181c0f434abf9310d92f94ab1f2096fecbb05fa86caffc766757838419d2fdffcdbd02c11e4ea70da9268a03048ad280d2a8904a8c61a6740ca6e4f779ec0a543a0ef042d88a9b9acc055e7fbcb1047034d818a4b521a\nSHAKE-256: 41f7cb8f32b08edeff63cf18d16b67ca9af194067971fa7cb547c60bf1524c29d29e27cd5f90b6daf1bce08d46e0579bb10c5be737d199a3e08f3ff0b95fc337bf7d7de5b5aff097c90aebb7ec52b0e4acc48faab31a2f1f3221ed312ecefd557e09555dd6a4fa2ffe41925a087872977d3ca069d3be5af8d1779e89c340d07453844b9e3634e1cf8d9562c11fdca3217a56b31522bf5ec5125983373296220dca5efe9a112a690ddb5eaaf35724f8b44793ab1caa2731176000db1dbce57f1c3120707c137881ad6987267ddc18d6dde15b00bc6ee1771b67f8da82d789fced735df382bcba4e315e8b25d438ead60af99130e2f8cc70d189217723b2d99956f347a0339f43eba17addeaa48d603973ead2cf6a84ee01047d852eb54c3404330aa5f1e66c51685fa5654c480c7ff81361a7f1757736184b2211352451c01dd3c82afa8b9fa5b0903fee8d7bdc2c3c242823e93ec7dc6c5a46ded7f20cea10f50f309718622148cc4afe07be108d2375ce4d0b93cb7a6c802d11693d55c711a9ebeb18c77454de7fb321ede260f9fa9667ed8835e9d570b8961e724619247201a0072564eecd17d6947147a4207952874af051e649c3a9e81cdb21fafa93067c599cea9ae22cb4ddbaf7ec2566c771f081f1c46e1848e02d42649bced38b679d26ffeadefd270e374f56a011d2ee37424bc84c84f40d695be35713e24905d311\n\nInput: aedd7d4df058d05a0867fda243970257c72f928cce917389cf957a993c28782b9df48f28a1dd8b8785d070112235499894dd5dc6b839bc0da9861a693d2086e829b4d6dafc10f6b5137aaef9ab98fe1cd6e4c6961533828462ec9fb5e33b0cfdc2b3f6f8c0ac0e4331a412222e0ece93cf6de718a42369240e9d4a54316eeb710014daa8dd2c20bdbf7c77a9a6b1f1256fa6267d165074284b3858f534fcc97d01a1e6e0e9fd9acc\nSHA3-256: 487233319467b1b0e245d8b6eef7e3d9c5ea8c2df6acdd672753065dafbf348f\nSHA3-512: bb40831416904fd1129acd036743bf930ac23b7e7901cbe1a484348d5b5c1fdf8b6ff9d4b8790e7ed1b9744958efbed650987180b54371447f33a48eaa8aa675\nSHAKE-128: 2fbaf54f36c514d2531c1e2dd265dec281698cb02db571cfe9bc090bdf7fef737332a9fde52a75a81071d584abe02c78e911291791167395298fabdfb16c1961a54aaa8546fe6dcc2968f44add402243e0253defd0cd051b2d2c2ffe4eb49f17ba274a7e5870536f30f9d929906edb0de8fe6cd746fc32415ce46db6379dbf2fa190becee381fe278201515ccd0468482d0b5d919fa1fec0f74a9ca0e8b06662fef2605e652afe0cef70bf58900adb2a2459cfaf1a9732023ee4612a4f088b77d290f7307aabe3423bbbfae30ac4297cd72cb1a3ab580bf72f73b9aab1de234956d2d1bf2b86b497b361e410ef491166ee0f303a713ee79916bf2f048c9c101d7c109010b3506309b79dcca9ca7e91f4588c2455614a099da776dba61edb3bba76b74bfb5acd1a0adbf4763961aa8f4bd06b366dc39edb1db48f2206895aeafce9df2ce50f96b84047b5976922b692ac00604418634b1d7ec4ed55d2409539d1757ab391d1bc7dbb2253a35569f3fbb51daaf6c87d6c018543dc5911ba1370a6fd1bc6039b9e849d693006c34055320d9f44e5e63b9143c0dc088cdaf15357dd6f98d5588c154ec3734484dd601b7d643329cc7bce2c498c74e02e53474d246037bad29040a33e313e02c40b4fa8e5f9ea6e3f5ebf6a4f463f27379bba2625c577c6ddc22873643d3ac5c693d96fe0777de4fd1054d8ecf845098f4097a54c52\nSHAKE-256: 49f6bbd89b7412a5681996ae7658bae49f658c561ead09b1119abee5fa1d63e445b9a47cc3b28d419d313f6c24b3a765e3376059d5020cc1669ec6e1f4b5a1a3881e4adf2fe28b79d0cd93aecdf7749f2850d7aa3a584e638e58d185a17324671f7d0b3f175ddb3f9b5ad96f01099c1c05939b8fa91609fec435a533b548e96bb10a9fc4864cdafb67c8019d292f8499c3fd456b80f7ec3f2658cc704c21232f2718a6ca0cdf39caf6771b104e40fbe2f5798ac9c3e19db0747069ea5d867b9374eb7106ac88f29b5f3a2db824a2c2637a85dbbcb7c97f649a3629d27e832a64fc601a68082882575ddf396c49901d58d098108380a8bf6810e5f1ec5e02036f6338416016fce4fb9d65e518c5cf44062b3fcce9d72d7463be36203097b8ab9d12ddd467e98890c51afc3086936869b4c1b7281e13986cf8a4899070dfe4ca7ce5725a3aabd753608d46f5cc3c106a0b1c2338f62b9ebbeececadc262d7e20681b7d1be367c067fd38930f7e7c87d680641c8361f4973096e9841f07e7c7ff2609ac0dcdb47eef34fe4e8f0c182ad70d8ac3d9a1cb9445c7892c422ce2dd444decb0cf95ba3cd44bca9e02d7168550e5c5a991b492d9c83d49d1fd8e33ebe9d341dc42fa0e76edc5529acde710a99ac0484b8803dd0d9bf80d1bfba7be3fb23ff4be8fb8fe7d8ab602bb46406fdd436209b3f2ed4faa594e8f4e18c1bd7041ed\n\nInput: 4c4b43f7e229b8d72a178ae73a741c66e891f78316adb994ffec7421724efc2b66e50261233374c6e48e895c7c2f4ee6bbcb62eb489d9e3fda40aeab8d12f50338c24ca5179fbd367db6411add8f7136c7e7d5c194100dfd1f5763b4df3db5d4482f82e5e80b7f23fb9d3c2c686ad60254b0a55f1a533fd5a6c6b810e28c8f807abc079b1ee45c759ac8345fe42c89afe8b0114bf4e77b8fe35d25e7b40c5d91d123e5d85a6ba247bb\nSHA3-256: 0e78a059156dce37cc7a95babdd1e151df37452bb5e57cab0fe4d47d9a5309f6\nSHA3-512: 5447bc790e138847f01f89d8ca25a0b21927b9ed409798f7bf7b9b4ad33790b41d4bc55c588f780159ecd6791d2677ad4669ad9de00decebcedd89a108a19ea9\nSHAKE-128: acb70a1c594f0faa4366b8c31d4d3228b0249bfa5282cc9fac98dc59b7c030df4de5b7b236f85cbef6beb2059975aa678e3ae2c24a2f2c4f0825a8c0997eae244278a3ad118a8b677e4ffca33fb1530ef5ce7fd4d2e1f7a49e45afc18e393c5769a6a45d9b6eb2a8d773ede48ca9b893c8e30e65cd3febe6a8229fb696d94aeaa81a0574a4ac1a1f54de7e12753694f5355a129d150b4a5967b7c33c5ccc39063fdbadd19aa08faa851f6401529e09d0d94ee811dd14b3635bf3bc84e21f498c6881f6beea96135b474094f4606ee977bff1a6522b2411f7713a33bcf5ff9fa119b8d0ed12efc764c453fcc0d03cc76450f8c1454be07e169f75895bba90bea5b075231d665df6d23f51930e0b123fc403ee0db707ff6b35ecbfb3d7bbccadd6159810e4f134491014d7bad4e33d476e364caa899c950b08a774e3cbcb7414c0b1b9112152357e435f58d068014fb0c7a79ca2d1817dbfcfa2874244af3865e96d561de3da655c23e9603c425eeee2ae2f2b859711ad1da17f33cb24a08454c6b9614c1d522130838ea18c9038190855fabd1f772691ef3d8a86b9cf00c30fb70ff95261b729247dbb17fae214068dbf4ed27038361c025dba667d82d973dd356dc23d27f8fdbe176a6d2462b24b7c6be47fec15fb970691499e704fb50eddce149e8eb8fe5a0f4", + "40989c376893186c8fe1dc265ae1f0a23eb45eff8366f7535\nSHAKE-256: de216774cb6335fe4ff892842f8922adaf89e84fd018fcf6cd86575005775a88230093d33df85465f68821b253165ec47610efee13d6f42377412de0c53ab1a648488b1e78bc6db4cc3fa0d722c01e7f96870a5197ac43a3ad7f8a76c41b86b36c1c644f1e55be8584cce096cdce8cc0e13113fa9a58cae588ef85d6de320c00d1bb87f204ade26fed7e9243ba457dedbcc7b8d80b9c9ce089565bd7f6126ff108281b3cfa2e35f3bf19adcbf1184c3c684f54f5eeb23eb4ee64277e0c8515ac1dc28e5840510e6b1bb980bd61bc2b225e8a3c969a332f6a8504709b3c7ec0da7e132f32fe2bb46e3d40a16c77ca94e1d342db530dd0b6c4d9db47ea52d3317d85abc155183ed9f757a7073674d71904807f2392d7c87e0bb7c99ac089b447a8f8e89d9e4641441fe5d4338b90b2968cbecff082f92f777c4ad3d9ba600614730a8c8f8b676864c5359ed09b874b1c5fbfe8854d86995da1c494314209bf9333726d39374a7c3007a41fbe463d1906dbb0025690b7a752b99c8ad2e878cd508158bb082f22f85ab29a2e1542343a1db7a478906e11728e268d53401482464ce10f0b1470c5c577aed70803612abd93e0b3f09b0b44d8e40ffc4b9495cfcadc05ddcc5e456483b59ffc4c19232b500f1ba2722bc6511797fc508d5b79ad862701c6e3112349574da0c85ddc2192e9ec63dfeab75b5e153cae1eacaea2a4e5e46d\n\nInput: e8f183c01f3623c1923c8c5e8a74948ab2e867e3aaff927e27311377f0fae7483a6a944d5feafd1e2dae3f510c1294bae6f09f21f80d5210cad26e0847e11aa6767e1f1f05cdb3af3376f7f2e1cb43a70000dc4cc5096cbbafdae46d2aa9a3acb973a8cc26811a93b07d83796a3e8629e376e5ddf21e007a1f70567b5970188ebf4e8a0253361998cfb5815ab675c4f82e50997d17035c85f55ea10501e6831fc6854c444527d02fc26a\nSHA3-256: d88106076b2895c1af4bc69da719172151439a03d104dc9d333994919f072fe0\nSHA3-512: 54d3e50231730eaaecc10ee186eda740b582c4c35315a5f2cf4a41e7e95c96850ae162b84b7c7dbd2dc00bd723884e0d9a287b3a81762ddd5dbd9f13385a7ef8\nSHAKE-128: 38be45bf3060ea5c38e5d7ed1733606b3af9398c360fd8b81bd78e98a13cfb4cec7c4fcf103c852a1285edc61c3177ed24558951d2d9e0c2c6f6f8736e4635cc2d989c62fdc7b4d0e94ab92c9958f9c93384f82d90adb5c0177e8d9e3bac8ab0371ff311204f04a78c87e25a9c81288174880683e7dbb30a90193a55253fe98c100ce3cbdc1e4aac38fca40320d0c3a22552c7cc79c40d92e8ff0b9f3596961bcc8794a4b8e2e85c325debb4813effba6748f68fa572298a5eb16498d358898b184f9f83a55cbe48b20cc9316e0afff58e3e9a5f73ab20e550b99393be931f5efc61ff099e335784bac9ea3170f43f9f336cd21fb419e5546f37a7cccd3bfab8bdf03d2c22062c9bb0dd528bfa6d34708e558f6e46c7e6c29e2ae366841a9b85a64ffccd7276b564203c3fc490ee9fcbc67dbc275e4bc764b90fd833fd80e8fc6d46c3bdcfbf1b00fff9ddeb61c3b85c614590800d995359491656e0f8b9dde5418f44ee9131ff0fe622608efdd5d56f3055b87c03a18ccb40a89022cff383a057d8537f126de0335fe326d29c510ac72e1b16fe8627fa3b9e2c83c7c1d96e10ad5a4183e5c3e6c56cc2959b59ded9fbaa1c0a840edfdc2ebc93ede5eb40e7abec36044c0707b13af59307309368a9ba936865b69110f3b52752ac7836db9e72ccef9da71473e127169bf8647d3f33b3c33c55465e2948aa2d3fced0878817b3\nSHAKE-256: 5a1c61aa8f02ead397be6f4add999c5f28804888427e7a71ff326ca6341d76ddb69e4753088feaa3781e109eecab2cd683e9449d71d32ea4a387ab1f761be7c8660d780252ea5d87d1c8a2d531a9a41d8b4f27451b2632d9a4d2ae28972fa436c51a3a430a825dd1c5f56179f31fb7f2d4e31aaf93252feaaa8948f6554408eb625d0dc85662c6a5d3bb1fe663263b3420bd787f5680c262d24fe21df845ec395601be00b4736ea5e40a4505f1683f70210718db8fab038a0a1f0764aadb5c16d842bc609c3ef4e9129389055a6064dc7ffa877dfc004b47b737cb60194ae9f362e76d78b22b2dc257d5603f905fe626f113520581bdfec3ac96c3fa9e739ddb6e0b8bc087b8c3e5d546779351e14d0145d65989512f23b59e7e62977639f946c9a97ae2d8008135860ddbd6fa1b94f73958666106aa73960ccdf5ee2998cd53de05870ac5eddce34d91e257eaae2b764404737f9a63fbd4796c32405986b8d234893d805646eeafe7dd20b99b3379d2e3dffbf22777a418013caea431d022f470ab7e5097b336fe98b7ad3c08e960403f21359fc37ddb4df95210b197125802b7075fa86138170ccfacb8de97603fe6575696c4842c9bad9252a449f7d5173ca60d297477da9b601d68ee864bc122675362043621198d6b818753c05ac8da433936f7ce3cd0cdeaa2450297ed464697bfa5d8734ee78a03ca813aa995f8dda1\n\nInput: b5cab4ba5c48b493cff3d50cedd742411712669bf07b133954baffc52d5c24c88ed86814c381a0aae8bea807bca098da5168887ac9d08b278f6f9be9a27c66ba7d485412a61249c99c76cbffb876965df46993ccb4afb0a34e16e9131bf9003067524bedfa1a42ff1b86edb35d6e0c9a669c2e0c5d08da98750a798c5829c05b5dca67be375789e29d4da842044beecbe8eb5015f3c5b1d1a289a43079b4886c260032ddf012cce0d437c2\nSHA3-256: 5905df34c6e01596d1eba439061ba1732f6190cfd3c9c78b53cfa8f974c358e0\nSHA3-512: ae3d1fd93c3dfc5bbdc52a33ea6962ba9c22b2e4e65ed87055d53defe0069ca00d2ee420de827d9731230f0497bddf69b4dd419b5367e713827e179ef25fb88c\nSHAKE-128: 0fd86ea32ccef48e530aa3e9af51f6c86671375ff1852e4f71af38c7eba874ef05834478a1426fb4cf87a3fb17dc16bd71cc84adb3a17adfb696433c328de22447c93f00cdea4aee2a80a0e441c3da531ad8277b40e8a07ee183fdd3237ccfa7b885bba6d93b85df5a25f1812bce8235ff5a6af0ea98dd5ee574a7da7813a32551a0438cd69b31cebfd3b5a357a8e817ec6c03f8048bbb450b607f6f423aff89424c62ddf0b615863b15f71e1c6d7dba058c4afe8f67ac6bcadfb0d4804c32e9a9d99b1d6900fc73ee87298dff88d5a59013888fded3d46a6e7e7dbf2207738642af13f6742d384d534b7ab31a04ae5983c80cd68d740745ae5a65fb7545bf57d30e62200b253d2d93282de12fc5540be5f51af99d40f36c77a0d85fb96d6c211e54799702af65a1b391f9c3dc3a9e17597b677ccc3d00ea19b481c1e990d923f440288813d21b5b99f9f646152345ba2b5514482d8ababf1b5b8ec05b4cc7fc0bbb14cbde9b702d84604f92ab195a41bb1e8010aa82a44f657cfdbd2f3d0025116635ea11c7738c4859aeea55edad84dd840cbe8f53e533503ec97a8eaa334cb738c26e62edeb2f9e4085a13a0c0378de984877c0c0e7957c0f301aa8ca1ef2ef5ac474fdfe523a64194dffd39cd99a68cb6a85d0a5374b8a84eca1e5c8009754cdebf81cd197019f9fbd78380931ddf1654820b585d18d827f506d66b7d466\nSHAKE-256: 66c1b1d6376717563dd22084d8b9f914e6775e4c34e34760c1c756f412e5dd664055d14390b8fee10c30ba1daa884563890d60b5625ba65e58f492096bf57e6b23180eb3f4f7f05e9cf517c39c1c8415671d8345892560ae7150cd11e4d987e69a2377c6394aecbcf351f0c3c3e58f049e80871e41f12cdbba1e54079aa30ce107c6049c7fafbeb19188f2fcd0fb8f3cbeaf13315372a2942383175bdb0c2c9b8d88154dca88596693e145d045201b1717dc713b290962da25d5f5cf803c6aaa7447a6bd8a4e2e55f3ca6fe9016fb05ec50ba5f80c7c7e9da67493f426d90771fbff118ad2a361c266ebb1435a6e5058c2bcae9dca8c3ef82d7055629b074b1b04cff78126bcaf2cc433e2a7ffca51832b18c14835e9f9b68109808f79fa9ac89af0b4bde25324f478c2e2b3544608504d860cefa373d2b63b0ea5eb337a2ee8af5a770c993e379aa5172a40f80f0a25777ab62222d1e08d1643fb7c3e768d95df19b32b4416c73e937103e9d78c5ffdc2b13490ab2b5bc944601436c9e35a95e34a5abccce7a2a93d434a458c8931809370aa7476e112c0d21c348d3f00a46a29aa47050baf080022e6a62963ee1e27e3b6c5e47194c360efd99ed1702b962d3bfa8f2b570f53fc30d2630b20b2b61f951033ea0940958401ee2051d3c98c78afe006de30bf303618bc457e95e8f11c459a3d8cccd9c903c6a7931a4a162e57\n\nInput: 58e174ac05d115b8e660032175b78922ea3561748ac654914baa1a7e60fd34cd943b5da31e7aa8230a6d1fc91bc1f4af820705eef1e2b55a708c103ba70d000b3ced3b35e3ed5abf46aae2b1cafe4f860be5324f3231d2d2e8b2ee0b6d4aacecfbac9abae9c6eef8028e3ea339229e927a779460424e046b8f5d5d1343ea1b26e00b591766654587248ad1602492a0b09c882f14fccdf588a4787beb1a5b1df973b1ffedafbb58dea875fc60\nSHA3-256: b2d84cc786d713989c086844baf173df63ddaf9aa5c8c77953d907e945a260fa\nSHA3-512: 87cae8a216e2be1b499dd25678777e57dd7271c924fb26df3167d0355f78bf58fde4da97d5a0d75e997fe84cd127dd4df3ea5aeb9093f90e0600ec47b5805c45\nSHAKE-128: 2a49aad1ea47e7b2cfff1f481ae652050d7b28a07f1339fcc01d27c31dd7087425bbdadeb5714d284b10a67e94b3af2bd3d27e4e50cae9f40ac1c40878e8287fd236acfcc1fe23d6c6517a2cb4a51a7a83c4501f3eb64346c0fe05930c17488e78a4453d4f32e41bf86e1bc5cdc44f08e64ad65d9efa8b23913aa97cb89f440cc9ddcb4f0be5c5baab3832ee45f2787bb1fe02f82cb7126bd77191033f2a51a033c2d5dbc5cef0271e4d4aee344826eada9af3f8dac18ed163efc3395cdbd5d32957df1822ea26e791044ccc9b03b8a5bca2c2ac1b439485cd9063b3bc51f590ee74b3842d80b9aebec0e6f29d5ed3f10addda8b2c2b3bae6281f77505c1941fbe8a964a080ab8f5f33b5d5d5c43b8becb0435a165480ae03b44c55d7876e1455955dab7643b3673356d404c33f2ca143c6cc95b97f6618f31ba3d32a71695507305fcc62d325e5048e8fa6bbeec1fd8ca8bf0a0c123d3fdcf326ebc48ef2855d1a93888a22bc0ce2cfcc93606e0b1b3c76962e22f598ab2879a3949fdf10cb458a915be42ede4b49d98d968512d54516b339d96dea2b26baca5d6fa23dd536bd0c7b90e62a1d85ceccd3fea8dd69a947b5c3264da6ebc8446d7b50f2c8a2a242bd42f1cc29be3ff679a71698b6623c09a90e43bb10ebb89b7530e45d95e6f54da6a9d4438d129d9d3d0416ad4c8f440d8a451a567c9bd6deafdc1b60068e7be\nSHAKE-256: 85a7e209bbff0a77e310316b1a8ce7f46b821ae0c05980816cfc033e7a91f5b88d70b5f287f261f617ddf9b00c3500d7b643082e24cb0979b6c15ecb51f180123c22c28c41729b534f386b5ec7abb81754921eab9275182acd8dc758449d1b1ee2aa0760cae42e2dd2e8ebb2f059", + "01292168a10f7ab9f343e968171213262b80f4119276e345336879c7921aebaec6e4b2242169157364395f834ed128b455aed203abb91582f179b00e5abea1bcbe0b69f0074fd36f15e2df15a433c3c10271cf32f12c8a85bac7f35a4016d280c1e224559e46a39fd7f42b13920ed24596e2b58f5fb7ea69779bab8a16a51a2ed54359c29ae6301407c5d05e8033f91cef989e1e964a7c86a5694e2cde01ef03182a5e8bace013210517dbd6e2ee734ef2fdd1eb1068e42f0ddc8e18212d6aad7ec41058b98dbbcca25c4852c846cbc7d8e17a140bd30f330f626d664d392b7754dcb328f7c5db4025387beaac9c24d3e912c5b3a9e664d6b54679b81ce296fce8b2f0f8f1ee84e0da350f5b634fb4f87d36bbd4eae62c096a623dddb8ba34cfb6d1754b6af40a2a6dbd957f7abb73325a0838fac0be9c3530626378f3a167cce054b4eebf84b443fa6997be567f45c1bdd86fe0184c5528225c970289ad12c7acc9d94891fcb8e155dfabddc9b2fe5172e364f175b5e838db337f63af139f6ededf128730fcec0a7ee2271ef98088e453da\n\nInput: c674c4c0a01ce902897948b940dd050fbcc1f6cc3e5ae9fed88caa89411c9ef89e6ed4afc2c63efaac6ff1b34b5df500ba9f369d87e4a15302467288ce11448ba202626e9fbf6d304f8b83a822d940173e73a806a5026c36f6e6c3d96484f10bd3786d88e28a41b9b1819093968a4e09110d55d6adf622ebefd1078bc92bcc39223a4d3f2935a226bf5db2d68bb318eb8bc0e91916695c0247eae09587424ffd99676cff05d0ccba8ee3748f00\nSHA3-256: eff718cb0f608d383ba22d44a591e57f66b486fa538167ac3df84bdc1327017e\nSHA3-512: 5fda98fc2a87dba3b244cc6aae9d508f48642390578eede05fdbb4f6b051db033092bfacb92facb1efe56af660971f4653327e08cd7105adf16f2dd4a04b32a2\nSHAKE-128: 85cf5ba604b240cbf7ddc4a7ed25475b3bd9b0e635b0ad57120f9be14c7586d0d18b3b299fe7b153f2f9c52cac26f2674b990641a8583abc03ae6910c2bbf97de086f7fd6ef522700adc4d447cf7287dd4d74d312d769e9b48ce38b3948fce49957e28c7f6dc5c8cc5a2c7564c2550a25ebe70b76bbb377457d3c6e62531391f86216448153fa814210628e1cf1d59442cfc0ccab5ee5c56078e035c56fb1f6e33b71c412064680851e7b1b07bc4f50f1dfe50cb3665923a0cca226dd7bd286acdc4b2672260456651ac0e4eec5dd4c0b60d3975eae33ba13afecdbdc6561e1bdcbf5a3eb529971fa4cefc0692e4b36c94e31f256f097e544f41519b06581735f8cea09961b0210dd78c8a8611bdff3110ff97c30adff6d2d65058ce1b1d01e82158fa657ad5fff7d2596364ee60bd2f851df294eff5ac46e8c63d8166955c611d74b6ec2da727d389caaa31f1431d1b6db0dd793ba92389f123ede93d0e2aba26afe2cdabc172738e3912e73d40249e77876a281ac9ad0b46963a2feae931a03669e1ac4dadce917adb49290661d402bb53174d8d446a7dd9a62b8d1b632e88c8d7179f3b74decba2af7e17b7a7969c24147c6f763f93aa84a3804b108842d4736f27895d95a54b405cd6e008b3216cc97f7b87ee9b8e4dbf38ef5627294a3d3414d03070b3dbf9d2412bd40918fff3dad5771685160cb6140efe6d32b6edd2\nSHAKE-256: f2fb71fe9a5132674ea710cf40f7e3192cda6bbc3548a9c5136ca4789fd8e640f389e0f9105217f36a971526c2c00b71b8a8b019a6535427aec6831589da13ca264d71b48e4beb11b991409dea107bea517fe426720cbcc974fc8bb0eecbab87820d57a88d245b25690f2659b0b884e8285a3958c88c802a144af75ec06fcee31c54c415f8406d55b54f7d1bde5743814936a59a3cc51f318c876dc1d4b18b363779c58be71b2ee9b7138b42e05488369a286f6363c340d45d72c84af4849722acb992a262aeeb6afa965b31b481a6c4dae1bc49a4237132afd3568a1a130284ff5773e0b5424dc15bb12fafb9454102e0d48ee4310d09e204af705f3ee361dd93f5de5253d6d6438a5df45d2ae93be8eea8236ff22ea43e50eb1d06310e8e72fb5a8726ca2b3ef069edf4c4612037fd4edc4315ea1253fdaf830153fba34d55d1c89f0b7482ef7ebf72dc3da1bae5523c3f3151d2553292adbf9b22eb421992d152832f439476658dde2df2fad0af3eda103c4d6c2ac1ab3fd2b2498c6285a6a71a171aa46d84a92d0f51e94b12c620abdae702bd31bd05da8c4a6918c4d88b04cc4003770c415d0c29232fc8a0d03479f88940d911230ede1adbc6a4f44677bccfb4a0d7a2c6abebb97abd53619b02d9475ef7a7decc9730b16209eb73d50a5fb10d7a4d0515a72f3ec93de415e722ce4e30c3b47f6e152c5122374ee4406f\n\nInput: 82b9f0fbe4711d1846e60c5b3c1ec2f63c7b01177b48e520e16ef37072ae1164470f133b2814dd28eb52c0830aed25ce3f1b1531998ba8d8fcefe0b44adcc6495e0a95560869b6e39b4e733e5c80d794f22406f0e25f57f55cc14bd692949826f3fcac476a9e88ba047ff463e7d510baa3931df940a3cf0837c1f9e78ef37730c02a0ebe354b4a0a37d0936d0887b618282e826c6fff0977db37cafba12bea152dc86945fff2448fabe3b44c113f\nSHA3-256: 0b661bbae63e82189d1529c9475ccb12d76fef0e827b8b9be6c5f83c73a99c14\nSHA3-512: 84315f3a5b75a11133828fc979eca14210adefa648c61efcfcf2ee7f139031987fb7091e50c9d0d480a016d26de95b825a3ae98a86b42e3f6e1316833e11541a\nSHAKE-128: 52f8bd2add8fb7f5ef797da7b82232998b69adba3f9a8766959c3863d87084ddbc29681d1a544bcf90d686bef33203752146d3800b3cccd40e653317d0cacaf08f3a5778c95eb69d748ea5838577c14f13705f8a28957d57183e8f242da54fdbbb16c578f62a683dc51c342f2d654733781ad7acb56f57ead896b2be4599e706a0f3aca492ee90d143bb2dcb76fdd55989d1b536e54c8311fc2500747e824c9cb762af7f67e02a4ab83eb1757a77981d82146f0f4dc70ee45732a5f3debd776c4db983014df468a1efa8271c4a14309d6786fcdb6f7357d2bdd8c46c1c3dd89d645526761635435948b14fa783bb3479d5bdae5283e5318c4a970f0fa91782d49f7c028d0cdf5e21248c433b7e862c11452973f580b6357eda684e705392bf2a983a8072266c65340133e2585ed44241edd27e7abc0b8ab04cbbdff3ebaa403bbae95bf8ec303e46cdc6f03cbaaf45b7cd8816efc6976f8a5fc4a966fbdc26f5dea675ac16af50ed8d62b367744be87a3b4f9378db2e9f651d622cfcbc82f7733face16eb6f3b3ed53f76391d7c349813eadf05b6f484eb1357954980403b704f386adbcff5ed5f261d48f1395518cc0c7fb2a8b6ed19a8ef32834f83261ef8cb7b2113bf7cef1ebeb7909a364c1d4124fcf832344f52759fe32a6e802ab17177bc520362c25fe7a4ab85c4e7f4a8bc306ee8155ab49a888ecfce73efed1d890\nSHAKE-256: 9d32ae154bb184722863cd13d26da91faebc024d68563fbe1f5eb1d4af44cb12dd186fdeb1215e02fe1f432f3e152d0bae159b11703ade7595e350aeacbc033304433d7aeea3ffc71ee28991f54e9480dd48686c0417f5ee781ab17c79bb87f1d61d11561307cf504fdca996f3e40d08f98edfd961a447429df97d5d6bcf5bf704fc184c4362d5c482638db7bacc133accec8059d5e7243994d68a1db0d460b959b9a930119ed927742dc222dde6401dcdbf261e094c2057cc5fdb701810d526dde60f5782f988d17719d5f36a29aa20a646a85822da515764d84e877d87f1171ab3398a331c08223b44192a30093cf41d415d54f5a7d31dc02929d3df19258f3e6198358642f5425852f1551d1e95f95abcc1c6989345684defacbab74cc883aa247deaf5650e0529fc3ce53478ca31ab0367bdc7d1b74ae2c23cb6140a0c6b0b62130266d9686e32cb09766fd4321c028a3c619fb04354639b33396267a3f32ba3ba9073ae180788f4eaf06419779b05aaba1f49840315604e71809788e33dfc6cdf0987e62c3442c335d1c53c993686cdd496c90c88484271b19dcf3f2044ec9edf79eefb0648aa96b83c590621b85da48dbf181d4e3e2332f494346a909526c576faa39c462dbe7dfd2ee9368bce3ed9bdfecb8169f1216c26349bb8f130e51301fdc584a88c0815a4347ad400872abc58174fac1aaf8c44e76829fd7422\n\nInput: 229d67d2e720320832bd8a8eba769b2757f4a23ea415c7e69320bf37f9465a67c8986e7060d95415b700483c649d5f2a5f4f869ff7d4ebc316348b8c9fe89ff448f8bfe373f7e5af707217cc4402ebf169393eaa9fb47f11ac1f81c01d420d01987700e6aa3478e9c7cf314eb28096a2b02e096e1d75370ea9d322e27b89510480e1497e7e09c9393b6e1b29b9e0a5adc85e8efea304de235d2774062785193ae092975f393d1d50fe228cae559fe9\nSHA3-256: 933e9545a9bd73860e50ddda563948df811f83b8912c2945b147d3a156ec6585\nSHA3-512: 7db8d3073439ca04b90ddd662a85f22350b53c5303844ba777c409b409eb5fe9bdb0593ef0d724cbc2440f2a36d94775cdd4c2709630b4519d8047f5c6bd17bc\nSHAKE-128: a1125656eeb8988e7ce91810136be6d53fa8bba277ab6a6a5000999dbfce8a5592d8d56a86c0e04cc56c186a5b780ae60398d0aae2a39df417c227844ae496d0c2007116af56631b8835d9017228d3745e9eb82cab60dec5eb39ee755961babebf8ba70dbea00c66c582544b1a5f3cb695ef1eb2115a2225ef02df930be7a55e6491684ddf4948a89c12aef4fe0bc7776758a6efebf133c8266e768d02b56c2dc2b0653c71c57ce4b4a61ceeaf147f4367d39987d3ac6a966da5c48adf9971d257698e8fc4d7d84fe7a303e0c738e1ae8231f604219783a232a6bbf24008cea4a7e0660f27eb74afddb309e409efb1a9945605c3f2f589c0241717b9412b2d079ab89cd61f9f3b00b85624e50eba49edf49f4760c8685e113087b4d61d51628659b3996edc61f393fbe8463040594998c8fe6a865955e961fc4e83b80e46a2c9e42e9e1846ace9e68b96f373c3a1a7d0b319bde7d3481cc5c140a84fae676a61caa988530ec61502d4d58c27a42a50acb2abf6508cc667ff48aeaed6c42e1bd7133a174ea66684907a3752a1fa343f3ffd2ce175703af007eebbfd404cab92534cf1f8982bdbd18221f6ccfef116a1f57268640b525975e22368fe5adac7937e6f9dfe954fbf009b4d6074146105c85b90b85d01ccc048778ebfee215ebb285a26db85cea94fd329d3a4698ae75f7b09aef3da6cf2537b369be11f5b718fa881\nSHAKE-256: 33650e8e339406fca9e400132973ad43066d5e299750af7ca3036a310b47dbd19bb78f8ceef327b0eed1055b2413a5028a0fbd1d1d885dca3bbac06d25901e32119e1fb0d73d443fe8aa991fa764851d79f8c8e96ed6a24765f6aa0e7342729014b5d81ce1197d586c36efd04c783676d350669bd9d270828927e23edcdf85390fe86f4c020f4e4740a17042f275bd92b697e421558679b3289e26b381e0c0bdb9c4ecad034f77e43edcce59b02fb6b46ec025f44e60369386568c6696f5ba999c79be17ecf98965f585f17bc2ea76d1ef90718977a67a5e224a696efa59e94994b49b9ad1d6f94508b9aedf1ed27dadc4c", + "d4e06e5fd40bf5cf3a20dc932535a863a59d6d960df058fea44bfdd8a58fab24064faf3052e4d83b26bf4cf5ba7fbdb93a836487cde2a0b848600e0517424fa6ffe5c6bd90a98d59f3c061387ba591b5758ba2218dc9ab604dd942c130f20096b646501879a2ad827dbddfa8feb3f6a91db15f6452227da96879efd9a74ed7d21c4f1bdcdf4d324d2f327a0fcdbebf2fc5bc1b9dbd00b9ce4e95c0390ea8763f3eca88f22199ae15ed67a5f6012fad9ebd905773e11db3f89d3a07c504d2f9fff17f5e4f57cfafcd30d809a23d6a596b918c549b6ab7a419bf06ae51d7b3b6a3c1ea8064cbf89b106f56f601b9a80ee2c1fba804e446a20e89c1b7e634469b9d59a90a321a5d9c4622c704b59ad14\n\nInput: 8e8569fe543eca14ee94cd8e94a404b5c38c29c2cb832608070777fe656ef1fd452480483f08fcf1c1eec3b2601595f47b9355289a2bf413e99cd4dba6cb956e2c1dd786cacaeca1a20d9caa087765b66ee2194c005f1c77b501b2add7bc903344398a079a63861dc45a0fd631d48d52264c2990a015a316e7ff0ed1b191e46bed17e0aba5c735d908470c9adc07517dbcf3094cf988d2abd36ee866af28c0bb0e9d4eaeb290ac01bfde337848170021\nSHA3-256: 3886ce31c37138062860ac38b59844c6617bb82134b4943d4eaa0ddc37f8967e\nSHA3-512: 3535b31251e1cefc2b718c7d745fc611a2ad198807638177a97dbfe0860a1cd0f9acca2b115d719da8ee493d8f5a16c31464dcb17ff26cbc752fdaeda76bd5fa\nSHAKE-128: 2aa87718c4a09ffcac7388442f7b55b3cdeccd0a001f2ab5b8177b2d4184abe962e59a0f29060b27b824986ef33eef9a34a1df4a2eb2be942d125f7049811e00ff92b50789caccf5e8b87065bb0332e3845c21bbb92c0fcb590cbfb7d18d028e5f73694ea8789f848ed22a05b76711330865ffe43e58df1b45519a33a6af86d2624882beecb78860d19ae673f6091bcbb2e57a5e5821056a240cbd68a32bf055990c3cab9067e1d35f48e77b1eea6cab5750940d969d4eaab5b46ce2417ebbdddd2403e53f2ce59870341bd9ea8f63b1fbf365459cc3d60f88efa89d056c1aa7a5129064f51251ce625c70ed270bd87699692f0d910a6050ffbbf9274a0d7794ed7cb181852137a026d8d7a46c6a8f35364b52d081f4b45c1c15613669a86f762bf251834a8121b7db714e0d5b662346a76204ba5b84551c7273bc0cdaee394130a86487b3ca8ab86bf2472ea0bdf811f882c5143b363d355708d8b210ca593adb64427fa0ef069cd830f034db22f5f7cdad5fc9a53e5b5e38be677749d5ea17c38b23e0e7783963e4f8dede1cf40eceab4e9476f349e8f5135c1fb8bbdea628e6337f46d48f54d3c13fc2e90fa8916b9f2c50490d6fa0e8dddc671d609d629549291d157d0afee1564b69677184ae4d6770199e162f02e3c270d3a374c3c07a6a32efc6770b78d19ce136b15dfa015f12a4c18996302009d3e063a43da7204f\nSHAKE-256: 0af00798718f40e2c67f35b3aac0fb3a645d824747088500d366d709a12d6d2e9adee072a1770a7f647e4ed71192fb42eedca087d973ab0df1ed192a34f3d973ab16668a2032fd105e02e2cb6d98f278ab4469fbab5db5be34dfe2daf4de664ad7a29b6dea74957393e0b81d21f5ae6af86e2f06e229df28bc72f559f4dd9be95b956cb22d3f21debdcd7c33adea4d8f08d60276a230f13df4bd09e09f5c3056e6a8639d572ce4c62d462cafa340a2d853a329b30e4a22708f5de73af2e0d861041be97eb5e17bcb78528d4478ad5eec694b12a8e343c9c1c92aa65c7c27ec502281d4f9e2f66ea19817cc3e47caeb1651b03ef9c4fb4aa4c607eb0d1d840cf70054dd6171ca9812e722087b2e6a9af30a94e2d3e383a6ffed950c05ef97de38b9f54ab3e356ab663bbce12d80b50148442b2bf5e2a20b91df1506985829a3005005b53281b0756bc794cb698ea3bfd8f97353f84f65312a90bbbd6d628da6d03526b8f6d6e048b0fd6f5b03e10c68475723fc2c27839c229abbabd2bdf8f5988b25124fd3181d586957336b7823b47b3e896fa45d3d36d76fd1379b8b3e611b5b52945e7d09b5529d3d1f856746f54c7d2582aff5606632d2f6efa8c83ad16d9d7577828cc846bee0967ab5738129d1f40f02bb858d1f36e54b6e4213c98e07b34079733ada34cafdf9eba88497da60a023e36d1f0d06eee2b86c5a4b3a258e\n\nInput: 3f976ed3b2e33c3496029398f70306c73298f0ee4ffca82a4ea762b6aaf7d5b4137b2b6b56220be349872022f8de4d2644cfed242f206dde96312a06afb5c82873fd21e2c308a60cbf9a50ed125def2995b84a5b34c4fa85bd7c67df00a9cf37cdf45177d1ccb0f6d4b044c817f965ccf39b6218be6224515823d420eec5691681ec8297d63166f3bc8c71ade757e550a5c2e7796bd3c20d8203006e12ac5dd055aeca6ba7e42d76df8aa0a598fd1a85e9\nSHA3-256: d088920b352d864d9608f485e20777a2eefa2222d0ad60847295ef1e1834d49f\nSHA3-512: eb58ced3c5bdb0bb88130a9c41d9a8445283534916cab4984d6991055efb82d1d88e13c9dde3d6da05eea81e0e38e2b780e1a9f5aad74c5933dc481276b84d94\nSHAKE-128: ab3b544c0132d1d8ef68e9d250662ec91d691e2a7f07d9a6992e0d4ff617c65ad661fdfc9cd4afc7587499ededa82cac5121daa60b00b1a2252d350c5a32fa11be97c26e2a7330bd850de06d38675742e9bf5169be58497ba79c60f3fed2b82a0e9de0b2100180d8c77733fc38770f0043027e49f7167ab3098cfcc3193ccf38d29572f90e6d120c2f7cce54b74f8765d8de95f004b73739968dab94730e70149ecf653f157ea6a660f9e524a89f2c9a5f7829ee26fbd2fc15d8e38146431f629effc5cc331ec9118efbda80d416462d819daef64596b262ff7f60a901cb4111c733a1974bc55c306dbe8670b7f34141ea55aed9f7616adb64ec84094a5d20e1d4826eb107e786035ff774bad3feb41ec4bd81e1cde427e3008d0c5e0705ef6c476937c6d861c938f055452165050a5979897e347e68fd2c02c75340feea1f26a1b0b4d8cb57981f97f44a96ed6b80cd95c7f7107514eceb5cde552f5f8d525814650b5804188dcb032a2b02088cbb42e00bdbc9e589062899be5054074100b03b765e04d6b328c0c027fdbf03a850a654cdffad2b7490c1fe5b2fe432238cbdda3bd0964120660d0908184f2044fbf5685fb0b8ce58a39a2afb156254e3b13d3725aaa6670175957a459045ce7605e015250314cc24efea383500358dc7fcea33542e367cbb335b486c897774c2a72aa6ac6fefeb5c35499c000416f5a229a5\nSHAKE-256: 79272b225a7dea2658a0346db65301fbd76e0bb45eb564c12839913fec0073d1f9c534c685925e5ffe89d30dc74e74c7850119f05d6ab0f7322d9eab8a053088b866170b5858b5058c26c90eb01956b7a11e5e19e0af77d4436e95ab147bf6afa84b9d3b08e0555d8f8007efad525033f6bdb0162683d20daace190d0587254cc0265c25fbe8f31ad160ac49486117438852a50a6e4fd229589229deee1a8775e8533adfe35355c46ab28a6e4b7b513265e2b25dfa90c7b3b0c916c986dc0673dd13eab7f81fd396c8ba521e9281d24dd51626c83806841e001c51c54b6bc042b59f1745da58fc1d87712fdcd70400eb971b4f9d153b627b19a0a45177ecd1942772aa04a97c6943b91ade2761e20712bff4ea9ae4daadd53d05e555cdf5aaac059006670e8c6d2b74c44ad38c9edad19128cb74496085f15bc5b672b5e1ced999eec93e73b570a2110f70ce8bf724ea45c37c9bbbe7fc6474b50aad4b2005fa8852361ebac5f54950af5ec588ea0be69cbce04686d57ce14b42cd5d7b1d04925962cb12849a3cdc4d827d78b7e78efc4bc57251a06736a083c4e0a187f3a7407dd735b8ce27feca4e8d83e49572c3c27b2f5f6a531bbc6de39371d872c6bf2ec1fda21539d01acfde4c829dda8d98f2d207a04ae12ec5d54b798339b1531e1c85263ad2fddfc850fe6f6dddf9ed0763635745f3229167ca0a3c7119663effd4\n\nInput: 8cb29bf522b10e53d1f587842591b370f6163cc7539d7786e6f39eba7f4e0620d0b57536409a0433d42f0e00e7d9d10eaad2fe6613bbe101fe03744115dc9d84b2b5e99e3a46082144a3563a0d6064c5ab61e19ff4946b90792e19a50cb867af96ea242bb68d663f380c66eebe008a62f77a1b6dd8cfc6fbd766131d57780d3562977ea6f257131761b2ac21385f365a11f436bc1e19a3b15483e19659c078dd4e44e4b34cd1a5df3c965a9c831ef4acb183\nSHA3-256: 87a20cb399be95d62e9b06512ed474ccb044d7587a8c975c20b7c5479d320476\nSHA3-512: e7032658df09f179ffbb5e3ce7c8aab30b7a10d048690bc02c81dd932ecf9dca8a15a2af9e7e4963c8e3f758d806357012fe124ab0fa031a5022410e9ac63605\nSHAKE-128: 0c5def25a2ec1ee0c49fc531d70d145c5d97405c5fe84bc8be6bf6118980d54ff938b9b0b7ce5a8ebf09a9cd96b1237bb276c1a098b1969de379938b685e603399db27749bbd5763b0dadba5899e7e145b84643e1e01aeb8f2b8fab6c8270f4de12959410dc246f45a45f1c04e78077199d346d35f0460db388f3aacbdc295032a9a292cf7ae737b615f82627f997a857d34f6cd006b9a7fe3ec3b414209c7843f1b44fac569ad4ccd20a1daa22a655a3c0111fd915841b82bfe5274e8b696d3c432fc0dd6bc883ed218e72a79ccfcea51665af0762d25dfa2f0ed118a7acfd8365eb8d1cd619e47876323cf18a2bdc327a917bae4ad083fc86a6c6d5eb1d514702aec1c42ae2c6bdc2d973cfd8385f1147543447ba5d01decfb4a7039149f3b4cc728918d43e91e414f70e073d90496b468f14c002b11192cd06353e403af089ef8c08f18d8881b594049b104b6fa080c16792cbcfe5eb078d0be5269cc147aa60b688c8634cfc6d502adac378abec595bfa30c9af908d264a86ab5654c4e1cbe2b0dea6d9e60a9e96e608afe422f458fdeb2eea9b58ea7b059b070d30a4d16be78bf54e5c1beaee4719d48b1b3349c78afa2ef3ad912c5c2bd0e6708c9645754fb8d288a940b90deeec8828aecc013a50970383029724ad795b30c666d3c9bc3292071ee1dcb3e1ae754b546303d047edc0c174eabc3dd8cd0f0badd1bde8d\nSHAKE-256: 1cfc42f75e63eb90860bbba7ce5e05e28465374acedfe76768f61f5e4a615c0fe3cfa5c84fa7440905631ecd70b3e8fb324837e4cfb5142490c08fe3a365447ea059fe8c59b7f77e712be25163b1cc03d1f90ac9d2dffad743bb0e874e25879f1584107ff84c1c458a3771b60f4cd2d7636b4451e0aa7bfc306121a1669231b3b5b94fcf92f805e044ac7270e46878e10268d05037714934e2bb10d8393e5605c41d8a3c36651b9b15d201eb5613338926f55426fb02bc749eca60141f2030eda12fd961f6cf6f16031cc597ab92aa212416a3db41f4fb96f97cefad45a2cc67839238a965119f9319b0830d483a4ba4ec1af8741ae43973238cc14316f4f9ee78947296890d1b8ea8b7067e458692f89112ba75d0054076e2faf6bd8f2e69698a522faadba489eead7f5cce6f4fe49545b0a4e3a9652397a79234b47e18ba072e1721521b5366d4e6749882d4ee9143411bfd526717e2980610e020f7c6da0020d76552084a144ddcc2f8f0", + "7c30edeca92683ff6b0ddc143f3b66fc4aa10ba97e964022c51616caec3cf2d4318146d18794b9fce0412698ec2e424b00708f7ee5fa573fcdd325f1678cf147483c6ceedf4c76a81da472dcef61777fae750f2fd04e2cc01aec52d2c0333fa485533e293b2412e3c04773073681723e4ed3e14513eb28a7120f9f28fb70cc807664d3502cc7e0991a12667cfd5b9496fc5fe393\n\nInput: 4f05e3d1fda79905776f720083eacfebf90982344329caf2861193f1e448336e698be1b1089cf0b8762e844a967962db476d342a5fe91c04d7ec11bdb8a1467fa83123129371bef9bcfd4265e9a3d0c9964e8960baaf2020de60b4c78f6e6bef9b20a6fe3c6b5767e12a29bd34cbbb8c7048e0a69c3625dda19bee68245f9547b139891ad8862c90576b6c7a1511fa8ffba69706db51fc763c6e1528311c26e88482c800e82d3c58ed3d43173bff35fe2e3f66\nSHA3-256: 3f486ee1fd646ce1d6dde03f9766d73b49a6336d148f69582ec11e00e3b68c0b\nSHA3-512: cb282f421d786a80783c28593b25fb4b9be6b0e6fb8220af62d8b3139ee49be8e06ecc9796f20ac5f2c5857d05c700701367dbc17d69a76f615b61c2281a114f\nSHAKE-128: 5bd94a54eeab2680f30473e4aa94588174b2121462d6470c6003b6a2a063a5c4aca9065d90cbfc79077ee39cdd17e9736c6e47a4c735bd56f7c32c77fa6124090a5ae798941c4090c10447c04912678b0d0b2db1f4dc8d4a617c1479eb2250b6f288fca4e5dabc51d6136ec415c6230e11a43d16a03200d936a02e19cc280ecc11c6738c0c1ac34846f72cc85c61a16e87edfd66cc0f8d4630a9a811da15d97cc41dbd0866cbb86dd8bf8fb1b9c49c04c29914fb0ddb08fa5b29c4b48400a3908527faccf12055a9a2a459e9b1994e9f89adec5c4b91832c9e5fb7f995aeca46c4e4de78a57958f661f7ca9bb6287727f0f929b5bde833706532ec9cd33d6226f31769d48c397174cab2232f1f84415ef6978b48778d24bc78833c2590c1b367bb525ca55a16b0afc1294d77c30d2c22801c4150f56114ba1621b3bed9b0c1c0f129c0329da9ff6d3d05ae5261a20f81e92e1b3c1a4a9420900aee9c59a77ff07dfaaf94a409f2671f7325b57c398e8d59ffe765b876516682f6fd3d79a6d7c9e3928ffaaafb227cab60adb8f0f9abb45d0b33b92c60595153513a18bef8fa1b8d8e496a127b84f20f7d6622e5aafea52ac688ed3a74c05396babcc524509289307d8e040024578ffdf02512dc30cc71309510cec06537e52c312c42d618e7ae493cdb8623893377abbb1196e26e38247bcb61f8dd40e6bcbdbb6d23e67cf286\nSHAKE-256: 6fecbf25e09f5ab63dc7b6fca2df42b32344ee9abefa1ad6a27de86e479fea0c9f99e488819fb1c4f17c3b3cd93c46c5fb650c264d5d3f9c63e9b48e97fc8a83aa08bc063456ffa927ff236db4ef4bca28505cb32ce224398b5b7f4c979e446147b15c05705a8e664ea92a701f1e77ccdfc86254ca0ac2b093f6a22379e470235d63430b87f91224a1750c010617b72bd5353507cd7b44b7a021e49141424eec58c35883664a9e1e529ed9436b8d3676d97351ea69328b8bafee7af18013335c5ec0048c868715c770f7abd1748ad9db284d849ee5bd9b5f295c66a837c200e68d4f545c8f138fb4ddbe7e0ec8fd7db1b7f8a31e20577ef177a3cb81666af2cd43c354a09b6f8a619a2211edf571fe138e0799d0f9517304e6427cdbbdb7e203d4a346557562a9e4530722e74e1502269431ef92060db0bf2da17cfa21531879f0722febce5224f60686649da3631f82cdc6fc4a3af11dd34ace425000938663f0119ab44a9167038a1643ead8af53754fad0d1fdf91b9a1587d4116050a143272fb7562482f66537271d3ce6d5deca4590a3f7b706b97a9dc0f48c294b898bc34a0b5fadb266ac8c1646689f53cb01ebb2bbf53fb7e1edbbafac8dd199c43b8c01951207522d2399a1858b03bd260f899a1f1b81950d4d2bd7bcd46e793053d1b0aa5b54c86dd309ccff16eb943dc18763bed8d6f8da828fa913eb030ed05f3\n\nInput: d5ad3a11d0db8c2e1641e32baa34ad2bd897f8bf1d3d2a333fc3f23b7fc4dc0f3eac71067216552ccd7c9a0a36cf4588796b77197305117101b31dba5a89700aafe4712774abed029941f7fb16f01d2e7f5177b196749ac6ee52b36ce5c17031617f966d5d187d85e2009c8a8e49eb95fa82fbad549b96ce701d2e820cbab85a61fe0e41cba39cb87e0277e5e3a595db9eab3b3152739fd97a1e3eef1a8de2196611781dc2d9633814bb6308aee0e376eae6cfdf\nSHA3-256: 14d424191429ca7f805dccd891875bd1de21a46d9417cff39cae89f1be23c673\nSHA3-512: e286dd38273d8656f2b26ec2bca0bc9f1dd429e03b1ae4456702e6be7cd9c6afd2ca4a6b61ff0cad39df21aa63dbbf8b43f8780abcfe0a56f95aa3fec8ac96b1\nSHAKE-128: 81dbca4e597486d06663cf38f884212c4c5893ede6dc97dad40b6b30ab2217530ae8a0986796ffa740a61dd4896e77f4f6b7ee12ca5325f9d8bf2983583305318ee5e75fc7cb79c638c736386f309f7df56b9a538a3968b4418e05cdc83bb49c651c6f4c2da393285861e664ceb9cb4eb3b4ae9147ee9c480f1a6be0e74155a473d76bbdf2fcdb3f586a17c36a6f895429e4f4bdcf6a7cd38219c298b1c7467636835eeaa82723740828c49372158b6cb99f9e55153c8c7e468173ad80ab355b6d35f82d68f43607e7239373e85eb45121e777ac0183d8a3740e43e499eb1618a2aeb8e2b052d3e229d02c72b02900c0fefd524c6e88a21b1396346dd9e330aeba23f2992ade32892c2581ff087428291e51de25dbebefac8c273ca4f34dafcbf399774689f0e7c98ea5570aab2c5a60921ac656439aa12a4b694dd9655b754ee4d87df7e97dfcf767f08e67ec3a37b8e59be8c57cf65d9b167225af1761de3f5eb89372ba7b67b3475e638c9ea74d48e87fe5139678b297b28785007707919827958cf55dde194ff1996ea51e48dc143ac15fa7853e1ac7c15530623b382d1bcb7778fffcdd9ebf6c43c3e066107fd5f87e543fd146e9d5e34eb4cb59254f394973bd038fa33a05e4fcfba93482172acc47364cc164a5c781346fc3affa8f52d4896e509861b29e5be633490e67eda716055bd9f3a8297f6072d4a22da6c499\nSHAKE-256: a8eee335b744e1cdd6cd72108d31d8ca2bdcb748f754e94d25470812599ea696bd72a7bd1c7d0b203051981fe3d2cbe7ab6366600742842cd4819d91fa5e28e890d6272b344575307f8d092fe5ef98412d074fb55af565e2bcc627684bae2f65623e52f0701dd57ff927bebf77ba098aa1943578d5abadffc9964ea12e3cd298ef39e6a433bc6a23b70087222c64b0d9ac2a10e7bd040ee9af8de79f912a7ef690dc56d23f8e5075afe248bae70313f6fa1322ac557ddb14cbe913522c2e25be9c4edcba912d96dfa16fbd209934e477c907fc7b9506472f5ec28f41bfedeedbcb30cec621135192120cec7d5a8cf3e64b25ebe751b62ebf757b42de5fa19c65db00e477deb873143f6a30e2363338ef8577dc24c03f23d034e60ce8f3f0edb8f7de4ebf9257ce7684c831a0e860ac309fc7007944fd5aa4746dbdea020ee04f4dfb938de3c52cd4b0ecae955b96c232a7e3b021e0e0e330a079286991a1ed03a7fc2cc0c5648704ca7099c07d89efb2c5535433eda4f509171b3b23e8ec6f451253676aab9548950b67604f114bf866471e82b147ff2836cb853baf6993f61c7d005ad03a4f2b6cc3ba1a8489c7baef9b733496584288866583d421ba252586e3ed207903ef4e6ae0adc6eb1f5f3c342ceef1b167ad783a8ea4f0a4d17ee64d86bf96096d757ddc8b8c4d1d3f5de2534ef10dbe85921b5dc313b35cf6c546d0\n\nInput: b311beab9189e433b5f36012c574bb089698428c1e65cc12c9a770587133aaffb5c75f4c41d3abb1430c39778804f29d8ae0c941d5514ecd25f7f932c331cf9437e32e95d990cc623f00224fd0cfa60ab597932fa077423082e44bbe460435ce1dc414af62d1f09c2d66e79a53634e5c7962e85b9c2e63b2f0f7e6f3a9efe93edd9e38a80824bf7f8446d984a6e9162ef7d0930dce9aed280f42446eb94d90693d567185309618059f5899b6a07d91dfa80f407c2e\nSHA3-256: 7b75f592961399841e599bc15181a2e338a750360371dd278c36a16b8798434b\nSHA3-512: 84a92cba77aecd59633c70445ada4ccf72321fc52440dd9d0205896e674f557d146a632446ecf106db474b647cc552fb555dc5384f90b94d6840b0d271056099\nSHAKE-128: 4c19b4e38e9bd2d6ffb0d932d4c7203ff4805c4c3d07177b40def0f35d86f8f6dc2a2213d8e63c9de300da1b75b2d3ef62b6b32c4890f5d5b8154a0213dad5c5991dfe07f480cb6e4b522906b29bcd97f1fdddc00c8157f64928abc8a45d399264bee8a2086bcf80579c4c7e3a9b5b123cda61c06169020ccad3f8977f1536d4d6388f85487b967f831c25d0a5125a8b5ebbd1b62decd7ef8c1479feaeed21238e47cdabc2fe5c72d70cfba8ae3869591ab808edb943069157fe59c7640871cf6f1a26b9846168af1a96918c7f515b6509ce8e96eea13d8a021dbd74573e1c6913e2a0f4aa413e46c4b7ccd29accb86319899f3104861f1270a64c0228046667419c31dccb0f815a14e51596dc7504aa1f5112d9096dcb2d5a4127824788d5d844636941c6d29e17dc2768e057dbf0505d2889a63cc146f150bec8af0ce81f69d60d8411e05a89167c3615ed1ea596a7bd20156503c23ab5273a857465b180821091173cfa7c62693b07ab35ee5bf246639a29b202b8205429620e00a4383a247aba394d1415aae2753618ae5b33be1e9a59ed88f63d8625a4895ead2987a31b507dedb44212ebc46fcc6f9e27527f784f49a53d3e1bcb1483ffd385589ef79a475b51acef440887bdb46d6f535a60094ed94bfd837efed006f56bb978eb2ef7122878d69ac754356cee6f34f9eb6df6e7917fe8c2fa9f4fb18468c59b6763e1\nSHAKE-256: 5397a1594abc5a6686c993058da61dd1704ad2624a1bfe90d12ac01e85afc128c3bde57b2e0f733302ab3ba9265c764e547f759767ff8f532a41394d32a8eaa8086526fd67a6c7c990ee4d295f01b5f85a709069d5405536a5e10021359c63603b9a86661150942b35cffcdbe4c799fff97aeef213dc3e6a156b101e6d39dd88f7635f0939c5b7190bba11efdf9d7e04206eeac182e246c29e7404259e60fcaedfaf2085b1e7995650dbe06a8cbdab7ce2a2518aed962ce72ca94760e34563a0ccd8b0584017894c46aa667582c2a3121fec9213b4fd376d040571b58856dc862da9f070c51848a6be1a0fb049995f8351816b78190a43f4378e475b84bc83aedb651605c1bb31133a2ff4dab6593689a457d66e00d35e4711307a160d1cd71d3d40f6dc154332635180881d78b2dc23731abf42c72f30d5baf13c95434c6eab161440e4bac4c83c2a61b98641bdbe2ad0b7027c6c3716eea667380fe191ff54e583709e05ff475b45a255ab58bd29fd2bc57999abd2169edcc332d5a15a64443a2f51a0828b136da0dfe49faa508647b919ea8143c46370476e86914a66e60437ad6af6347ac67c3693e25daffd69dc7337117b4606255ef1942845ae590079d90d2b4b407f3dff0d779eebc5124b65d4e0dfcb1c04869e94ba0b87478", + "6b83b957b367c68d3fb84382bd610143f5c7e81a46e8672cb9a3d3f9c001b6627e007\n\nInput: 64f53e8b0c26f733dbb4e1d99c1aa22427c265c403a50d01fc3b05f01a55f28b31ecf737332c28a7904c806148dd1500dcac41fde02fd7fcc48ad018727b4e05ca92157ca101a371a346005a3e009c5a0e415233898a67a136d67121a4413ddbac9c63e27083ec255ef84a355c350164883f5c1d0f6869100ff89023c4acb15b46d76e55cb0b0f454d0d970e4632650dd2a1fe45b223611f23e3a22be288bf4572b6b3b737671e026bdd29979718f29a706fbad97b35\nSHA3-256: 3c555f81234412706c6a642486711571f45ac023d67568a8c2505eabb3a61ea4\nSHA3-512: 7b2b1fd3c323f37175b42fc72519a0017a595db6dd2fd52b8c1fa595ac0392f9d2dcdf0b0af88b988085a855f60b95a74d1164a88994ec121595ee3c3ece990a\nSHAKE-128: eeba189a4cfc05a319e337bbfe5ec76a27ddb9710bfbdc64cded7adc86a5c439002ec66913caeb0ec2aa3e57114da49b29f7e799176d1928eef03025e3a89abbe24d4d0ee538a771b17eee6fb20ee12f4b101691e756709c57d3f10c95aa26e6d9f665da0d20d8fd28486e623f0a7ddd79b4881a25f6160f9c59787f48a8ea895032ffd8debde3a6527f62902cffb2cba60540080e6c34d0503883ee2d522e8164d4c784eb0b40a5c07a86dfe38a5913df6fb136579c12c81177c80113ef9dc5223fd879dfe63fa40714ecf4bb7a64a43a7f448f838af04316845602b8cc763c7c6479f758c6630922318c288d9bc9ce735a3636853c19b1cef1b12235a48db6e489466c53ba2ecdbf7eb1d13a09d8e0a728d961f6c41fe31422da3f4da7e941e0e2ab8ce3367a72aa0a281e53e0519611cc1948fb67e285b4fea57ea92b0fb724cf0cdc0a15f99c8e4119e72f51eb4ff080b5ee482ae8b6adb6682ce34ce60a2394dab11e85a60405075723d424ce7e95efe3ff3f476c98f18f1dc1344746f9701c2a0d35e193eaa0b68f81527e76b206922d6fe3b84d8953d7a89563eff2a64d0216dcd17d790c5fcfc20b2ec6a6145b37c2c44743965a68a999354c37ff753c079cce193542a4813433c62e8e0659ef8c0655a43c9e5cbed8632477b7e6969a493f792381e49cf6e3bec40303c4e8f6bb640c3e678dcb5b58df5c095f94ba\nSHAKE-256: af0e49f8121ba44cde5fcb938a1d930ad867ae2cfecebfe0ab0d55ea64ab17072b59e542824290f1b46341f6b9f9988113bc8d7edd15cda6fcd07737bd61adb542bab0b7452ddfeff252e229a84289921f839014d3d8e2d8b986624fd8a1fbcc93699837e9b8db2df639fc8e37b5aefe0bc722d294f5f728964c693846834ce1973c33247d178c8acb27e61abbb877311f0c5026e29eddcac2cf8567c209ea56c8f65ca26b20b1ae7199bff57de8734e2fddf63be338e48bb6fd815158b006a939f64a33413051420691e52512100aaf0da1498817dc708d3b69a3f4091c2620da22a9cab6d4de21b5b75f67c37e83301d15171771ffcd4847cf8e66e0e996cc90b9e7fa9bc0b32dc795678cc7af93ed289eb0685f0b71637544c3e4701c7b427cc843e7b96fd67397af22a5f1c54428a010e5a89827fc52c8448d43f1477d7dce13ce2e417f9108b8b36448ae56610b6bdbba1c17ffea622ce6d87fc62a97340546c705a36b1be299599844a07585e89c8b1f319d0a960aad8767a6d0fd23896736527120b495e312c2f47710535f30e9b6e9f5213a25b2bfc4d7fc324a0bec9814c3bbc98433fc8bfbe04ca4a964b31fe171c4f883647e25295c26f2e201794e24e844b89631aa2969dca0bc648fa27e88877a9c42d0b197a08a9eb896c6eb621440f0230d15cac102ff805d865b99d82b9d01f6e95160d2223c4443b59124\n\nInput: 5d7510e7be21619db024dae6c38fddc7917f9f8652482acb209bfb08244252c8d90291184444210f6ee6c4b2f99e338562b54b0ebc410c4aef6fc2766f6866321a1747cb3f82e0c1224ae799b36a54b48b0c27a57c74b609be5a9b9b8d8eeee15466f15cdd30ca79666d47b97d9514c0c4bc06ede23b5a5cdf0eb3cb9722cc95f44143ebc576d768d072afa213bac03ad4a8344f454de99ad946940962ae19401f1726775ea717a8a7494ed2ca16b3314bfd183c3e06df\nSHA3-256: bb71743dd5b9daf494a937e3e3bae49454da4a616e2254786ffb59a5631199ec\nSHA3-512: 5f4d2e65fe7c5a347d4d457262fbb938942e3eb48e25459ca6727613c1b1c0a30362e7ba8961c4edae127b8e74775e9748c5235d01661026c0ab69fb7db060c1\nSHAKE-128: f1cdadb6e3c24c467ec0ab4784f78806d7ccfe9ab6570fc9bd0ac2d31361de2a851544c743e3d1c2a16c94898e4c1bb107e7b5bed2a8820ca80f81a26556ff41c637fd87dd053be51b8e06badfc42a003c307f9fa11903014e7855b56470d073b2b086b0c901ea9e0faf38864c211d0316661631c5592b65c78bb53bdadcd3e9bc26286389d4cecc9528a238549c99fb47f2981769ba46ccd0a08fdfa3690a069beb882fc10e5d0ab7f326a1f08ae0dc34eb0b43d549773f90279cfc95dccdb1785ac4df52c0fe1c91e8b3a83e9307ef064ae0898f189e3202668cdd1455660449c7f897d101047c90309c0a9c0095276b9e17ad177e76516868ba14ef88cf76969aabdafc266b9e66171b80a5b16b47dabbc46c0b6cdbffa0f61fff9fdefbff9b444b136eca9375b810b545ebbb52aebab5275da1c4c375f68baaf7757c82e80be61da7dda8680a8fffc2632d9ce96343205ab914af428075c84cd2bac03f5f250f01cc65a62c14388b8370d4d3f5aba516f86f2c5b014562849c39c32278a438602a4ebe2e300d1ec7ed6f093b5fae5d889f6c7e69a779ebf9318ec9dc1c66730b2f0c02ec5246f51fa1798f0db667b566be4b6a1af75f62fe97f22516863c2f24a3968a1b0290923158ae893fb56e87b8377c5e491173e2ff1662ad5e88ea27965d93ce19e508ec773626da451bb811d292a6b2e5091d61ebfb874cd9050a\nSHAKE-256: 7e624b901f762185deb5a89ec175328291e87ccd2c2be59cdf77100cfd2fe4dc59a05df16cb243c240002c3cf009d1ff78d3b0c7e83d75935359bb8e93a4c78b532eed90ffa731f2a199b8adfaf55140ed849c0d121d74a26402d309eef1a43721d59a87083f0e628ddf86b909e46bc43e8d44bfa876d17dc84e11eb88ccbe94f17183f7466e5361544fcec1a875fd34e844d361dd399ad9f822920d4ea59033a8e1ef10befd133a6939ca0d58dff578fd78e96f9ea82241491c67323030d1c5b04165314bf840da1f3e6685260f8927bf2a3526e1845d41e0bed2ad1efbaf655bbebac6ed06d1a956f04febd0a057a73759510b986f9fb5e380b2acc01359742a693def50972c0ee5b3b4aaa7137658986b90efc489e56eec2692694a21df5e0b1aac3d34cb4a146d492c9484153fcf13dc9dfa9a5ae315e62b4351ef810f3c5c2e153593e5673657e66f6d2e4abf47d6101af045f2211e49294dce570378fa004c5cd3073af8ca9fe1b33cbcd59bda96b2dbc8bba24e2e92ca7f8b208be46cd0a4136375033185046102aca9cbcdb88ed2329db4ddeb63186cd0f0b9dd17176f144e0bbdbedffa422c5bd04ed1fcad081b18d963f78105d5d1e1215316825640d4835205fe1c8b2a66e966635b3591a3c57b149129d93214a5cc8c5e62f714091198ba6a61d762fe80e95d6e399e14bc9103fcdfca4eb342b7a0d6a4cb092e\n\nInput: 0480d8e4e6202d22e84bf28798183c07f692bd7c8ce76e5f66093fae2c4d179d54fe7d3dd251b1c93de0ab50919a01712727cfcab8cabb2c9a3083ddbff95087af6eab9ca6ccc27e7dacfb1b57ac3c568ce36db4e08729577887f74d32deff6c29c800555bc53cc48c877d5b38235633267de3e588f12c02cb4219463c9fc82ee3c1e1a0f9eb3631f9ee5995cf7daebe79e05389221fbc17f1d0a6b1776b9ce1565a306c962f485b0af40e98b7e8240a205f39d4705ef0e5\nSHA3-256: 10436fb5992891c6f9626abd77d551ea3dec782af6b2262264d8ca5b2046f398\nSHA3-512: 81e96dc335a200272752595c2de1088e1516b49c3417e9b72df9c07ba272eb954e488e8cb85a0430f541c590b2dccf4730108c1bb2835337d411d22144d1d384\nSHAKE-128: 48c68319fc0c649d0fb5d76d688c49022699dcbd3ab3487d15774a79b4f4a7a221a347d1c6b79d67aae611570a29795b0a94f9d667df9dbc736a0a5626ff830e6904573e24ec4e51494edd347b061f65aad4b12c2ff02e4e196bdf32e1d26fa342fe5c792ca45b6e5ee9b6e0a77f4e4b79922ed559e3b739ab9aa1a994edb4c232520af0429cbe00f9efc58de23b15e747a066b711a736b36c767c05137d23568e46f90d100d6da899dc25551a4a487359364bbc304984a1ec19c2f6f06a508a0e22076de5c0823fd05d5d67e79672729c07e70696e47fdef7e73982bb4ce5128fc0bbac8714dad3b66b46c5995fc84a328f8acd69066b9d129fb6dd2c805e8d19a5e798914d6374070bd097ee52d62aebd78076a0a7a6650dcebb089a8bcc66f21324d2a66e525dc0e77be3152be626641e0e61ee07df14a7566fec71cfbcef764328095c874477029c9f6def16c27c89fc2ea17b364246fed07e72db07dfc4f3e20e360652df75f36b471ed6c89f8764664edf30030f5fc2daf5a67b78b198df0452bd92f005302f9735df90b8e3b57e9c51af6026fd143ed7042d98c5094d7e36b1f216c12d56aefd5f197a6c6e7c9ab7fe060aaa81699d69ff240084962b1218fe004a2fdce7f614c42362131395f6cabab626066d7fd2e8b214c30568ce8c0e132664409cdcddbd3377dfbba7516a07343d31321745629329fa8ba1676d\nSHAKE-256: 117fd223d35f349d1c17c017067f17d4b28fc156693349543a841c31d8df2251bdd057081379aee01f5bf5c49c8e076732ccf51a2e6cfb4ddec8d88e6833dfbacc11c4c5cc01c0d9e8facb07017f71f9f306834e95415a9f16894d5cc8363adc271a8b981b3193d8d9d2de747ed3c52a3aeb5b2e7cb21a999692f21c2fbd6c8cf10a040fbda51d1650eb0d644c72a5f7b9ad19483f7504780e6b2a391ff59131d88402cbc59066740794221dd4ae0d62fb156dee172ecb965f81f9e49c14069502d60d32a6394c7cbd9681e7285df4b98d5311633e5cbefa49fc66d1912ba8b516993f773124923373d8d1250c31892732965fa8e06cb52b6d56538b38cf141c69db0d16e5625650c33c19c93930f3c1fc08c94147d94488a80aeffe29d4ea0513cc0d95d03381caa872ec764b29dd651f1d2165ec1efb4ca1765dc530bbf1949f25cd22b04cd1dbc7df7c4c86bd919241093464a5ed3fbcc8939b6e4ee50e543ad1a33cca6722d9fc221220e1fd313c48e3cce6a0d1dca7542a48df5c7d5bf8d4d279a2d9ddeffcdd773fd038511fea8b04f1ff025e48e9e716fc30a92409545d488164cbe649004b4cee5d09359551b6d92f8565823b7243650e7685ed55e9fb4eb4c35ec6d3c95a35abd8a5f6515279a0722c635629c77ca0d1cd81f32e23db9a3be0a9fe7964c39e4cddcf9da8e0eb1861ad54535ed9ce1c02ad6f2ffc74\n\nInput: 340cc17657ad9cfd9fc068f434104e8f30b1be119d754ce3c35f7064f58a684d7450654aaabd8fb8b67e659922ac17c64de89253ac9d1c5aa07357b64d6bb5ca84c", + "440d3ae603eb4adb5ee48c4a4137da87b509e5c9ff8b2ca2b9eb4fa6327e3fa2f9aa0d68c668bc5d09f4894803a5d34da6e38f1ea59017344e93b8462a117095bbadfed798e63a39228c050f2bf8677d9da8b29708cbb6ebb9258277f061e0c90965fa424bcdc9c0a76d414498b3737d7b3907c60b3b11e\nSHA3-256: 59ba4fe549e9cc8ca818c6770ebc28687121db19b31fba4eb58dbac05b233a2d\nSHA3-512: a6dc43ab6a1f6b7ef078a8c5a61138e8fc45baceed1ffa888db039c04d506f614f00d0a8c06491804760d7693a0b6882b292b0308ebabd8deeb516a78c4d2d13\nSHAKE-128: 250e6c56999abae263738f6e0fca59eddc7246cc88672e8b44c125d9ddb1f019da35aaa457ed5d634f2cf2edba12e5dbdc4e0a466af863990e22b6577ddfc47362e08c97ff42a40b8045c556ba88a2b9ee9e03de419bea4c6f1e0f2c7fe600264803a79cade405638423d232e6b42aded9b32a0e8121c56ab530f0bfeaba0addf4ae84377ec0eafb7bdfb04b0b4450886236dfff991df9793b87d3e015e3fc3394b04800df741ff0e28afeebabe66b86b5f4dc0371e528dac627a7f705401d3bf7b85834caaf61db3a7befe983d7064e081d40685b09816df13a5d03fb6edefd13880388a28a1b57940184c3f8bfe2bb81b33df3d4b5386ddc3b93cdb8a32b94c74d715074675671ee852a1577aad1c06eb83c827efe97cc503e4648a0034497dc6fb8944eabf72cca3078cd4c830d8ebf7d0fd5cf04d290275479910945d08511a3c34f18eecf76aa023a136ca5664c05d2693408ca595fbd1eae82268924fc01dfcd9e314d15bb3366135efac60d09e6ae92f0926a1112385d3f93383ba50d81ce9c6cb3ea5203d0cd6cf392832f747ad5e5c438edb7e6c15d0edee3407be4959f93f96aca896cded3d1c6e4f7f9a924e387827e80fcc4efa7c8929c0a96d1f80674fc80f0abe54f89360e681378139031dabd3e0c9ee899e6650100ce074fbd4685737206c5cff537bc0a88ad7c7138e118ec86a18dae00d68c719c0e0ecf\nSHAKE-256: 9c2451bf232ac42a93a225cdddb3d30cdc99362573fbfcbe85417841906ad972789d40cd4d6a85180b3944f7796e46218647cbdc848231bb7314b4be60a3b3ce945a7d2c021f2baaec3ad6d0800df797244c9d26410b42aae41bb995b4401a35d128fc3bd6105a296a13d5137d94c80688f80bc2e6c30c7d3d17f3b773885bce40424e29c1e67bed88d34b6fc88b4d902ca2d574c134084cfd4e70c44f4f29b09f47f84131181e0f72988c9ac00ea78f7e1ed842bdce795d83e8e4846966211aaef35ec19950ff6ede86f9670e4b953cf9eb351ca746a6c9f3837ed16635d07b5e67b8273df63393712c115d76fa632156c4ecabb7ad3eea63405a45661585778111e9dfa7b53e1d65121f7953eeaa4bf8b6f08ef8ea503b6437b512cbea6b34afccf693a84f031e7e5945fde5fcc74d296adc54e97ccd32b47567090ed1e8a525691006ce044eafed4e11338b7804d265ae87cd21d42304bda2d75f302e58f7c92c653d27d731e10110162a988a550237f95e19951b00d23516c85a05ac82e11760e323609c1e09121ccd9ceb5ac14ff409c6645bc032ff2151337ae89354dce7fbeb59a763cabf2a0789362f9dc6938d006dda2011bb15426d73b0b9fa9c014cc152dce090489bb6845bc0f65b475b36c1c0b62b7856fd988091fb24134797bfcc0b5317c7e9b1aa98ff2560a7398bec93a54652abc37daa276eba01bef7fb\n\nInput: 3315ab6d10e6ff08959fa1ca33fb4b5e81b6c1d7941f285d01ab092ce0a3c4815342ba7f50a4e4db438e06ea2890a944ac5a124d8174c7aba3c5aa68fbdda9e705651611c88417ce53ca3a08c4c8b8fd7277957693614689b2aaf399133e660a730323a4ed2bab3da7af92e2a806b5bd114c238e00bda13e9dedb76965ab70e2a96a958ba4ee4c9b944a14582f401d08b1bc509dd9a218421e074248aa458fb2bb7c0dad165b84aec421b779ef22b5895d0f7a7f3f835c9636c2\nSHA3-256: 987e2578028279245d4e8c6e16d3714359e62626936b50f5e0a4fee9b971da24\nSHA3-512: e56e83351322e87a8022569ef1a8baf85cd2e408db5b9553571e0ea11823d5760b0f0665c570094f358a178df9e263713c24548c6560f8e5fae4078c5f0966ba\nSHAKE-128: 639cfbdecf1538bcd0215ba263e2ea8f3008e9e5e5eca6130967d0e1023c8856fd7165d9a28d46c4693afcd3c4e12ecbb70d7618ae0465ee8e8816466e3ceb12d569774e23f3f71d83fe556968d84af09a45361b0696f3840e5eb5067c7e604c457be57f9d44ae425773194d6b738c0d316401a89ab87d4226a4fe4b30cccc7952880c72fa82bf0ab95b9d456683c42ba3f999703377aeb6e07554b7e7bbfad5909125f6625c158cddbac04379db9455a881f9c4d18537b9f0401a264ed175eabec10c4e0047e39a63537df47df473c0f19d842e39e339aba0207833f1c08425cf2fa9c6bc45e89c6e31def4271da9c753daa337f961a14ce9142596307cf0857365fc6928ff0e34c5b682f5dce2f3996a47e577319875eb1371e9e58f72d718b4a3f7ebdd692382a45f0bfec3adef716c2928aac120956ba2879961efea21d2d498307c9141b98ec14a1c7d8e4e577fc2e523b8f05d83b3dd6df01e3b146f85f11932a74109bc649e71da6933f4edd006c90b1e1a3c0416d0ef05cf319f3a6f241317381f3dcc0902697f0917583f39b0ac0a2ad008fc05d400fa69898082c2adeeafb680d07371c590e8110c9c74d8187919aa005c40ea2bee78161acc40c15f16a5f137c39d9a567bac0326a2568255b052526212eafee82d69900aad5dc64c289bbb2bc79d40bc682ba2a6283f481c72c66b0a9d5d5b4a25bb9ee57b57d0\nSHAKE-256: 54e665758035a69dd73a86b529933384c8f64867fd765b8960da0477932f7ac849a74839b43c29c526eaa94e4b2c261a1627e4c49173432aab830923da2065502f839c70d36fad2aef4b59e929f3efed557e6a47ab19685485aaeaab88f31941f5a3a38c1a291158b84a60c838c40f57a3fa9692e456dd945fde95514c962c0fcb37f06507ce06101c3e0530f6ae73f60b87c17bb9808611306ec96f8d0b44a301d43f35ba018d108af0e91a4d804899a35220864c3532126cd18a9b42dea59739e16a2d34419bf437989be85c7418b4fed943be8ceef18ae9338db4ccc91974740c91e191e83d27ae7091ffc54bbccb96c78f94544e3724376588c9a12e41aab5f29cf94ab961f711043f15d351e8daf2a0ddfafd1f4b4518c94b62c40bc1599c15f99a15552e23c02c3363bb42b59460601f5fb9c9865f0fb5e2409435c66dbca608c7fbb58d15932ce9a2f02095e1494de7035c59c0494d8e3139040b8d8800ccddfa7bef5feb493a96db3302bacf7b01bfd548fc6911c60e4f3c44ade04cbb86e392ee7e56fbd6cf0238cac3e5837ce1d756a3493e2808cc7260a3916c38bbeb0afad7f479b39270289487a30706201300649e966b4bef2683a73d1c6a21ae910dfed87585ce8db5b12873fd2aa8d3fe189857179cd5acbea005cb64eea533c3c36063cffe566e980b990c7141993c21e785d7cd5ec569b278fe8c5358ac\n\nInput: 5d1cdc61eb7d731d1af0d9bae8d72a3997989230e60a9fdfed7a5692b3bcfbd6040e1df5124c04a35fedde8b326563fbab8f8a8b0d4e96e0bc29016b8d14698148829a27c605272ac02dba1f1b2876bbe76be347a05f22e2266fd9766dbff7681b018cdda77651b9be1e56a2dcaf8cf797116f53d14cf32b84ad69ee0f41106db3b21dc7384814bbc0d9f02fba76e0e0a951c8017358eca97fda2d639c0ea185a1a3d14525a6604e380a4d83e284e6b43ee8ffd7cbc752d8530a60\nSHA3-256: 79afd4b3cc3ceb346a08ac539bd1b29dbf00ffafbeeaca42607fada575bbaa16\nSHA3-512: 311d7fd554a93654947c74bda7a63defeeb24bb41e52d6f100eff06d2e09419199d834e0efb5f6d4615b6cb9f2301e66df2103aadfa2dd421cdade628137edc0\nSHAKE-128: 95894766e8ae5db0e2d8a070adc47025f275939ab5d4831ed2245ccb14eeba771cf628788081c2f718808ab602b1b7ea8b8bc68b4c89a961cc285ed9b0111f345cb25cc4be2c8a632864a4ce1cf8a8fc2e951d71f3b06435618f496fe7c2cd26e89eba0f3aafa5d44ac8f837d0edc9a383e3640123207341bfe1efd3fee75a90c7e6f9651c359315473e2f7b1fb259a935b13bac91dd720eda28bdf90f992525bf0f445e4a3acb05bee4366c267c077c1d18e4099c54891ee6df589193f62d7169c139a4e9f643c2bd6d0e0ab9a1ae8d0572fa9b86ee40322756c47c4c0e71be958180197834d3ba235ff485689083cf578853816e6ff4c4a4bf51fc8c75fa2dc771dbaeaed95b010d3cb38fb6737397a70682728a33e50ef57d348eb16adcf8c10f3b0d0221db46dc1c8c4440cd10dbadd87056ceadf4b5e9c59f5122bf525b1a984fc11212ca12a027aedcc2a8957708993205bcf307c0ca27b559edadafcdc77215425331ab149d6182beb9bc8c4211633c5e019aa859b2bf474f59e0635a3d30d494bccd58468365f1d77815c62e5bcef5d9d96e43b07290c29d1f56965378126282dd2b8f98ca09c6548b1add53bf7fe9fcc93965583a5b08f7f26d745ab92e5c8eaada3d73682305f9568322f842eba482a5cf7fd10edc4c9785b205bc0a31e30297f7ffd46d4df666ef67110e942a6d2e04edee805e9c7c00b32ef691\nSHAKE-256: 23e636c76235e2c58f3c3da086b60dfd0c38ae901e93f1443dbc2f93f8df9b910b8d09b11e834093d9c61c4d667e7410958e47c31dfa8855ce758416151b8db235d8793a9820c04a2c56280d35b6dc1a5b627750f3869d15833c643b7f7b8738cb5591fedf97ec938abd1447ccf57656d2494c6ae179d3b1dad96ba44ec88aa5ccaf6173ceeae8260da816fe57368a08bd532de350d8e2d6aab313c6d27fae3feffee068533e15d87c1cb1ebaba3cba32d292bfe4e164ddcab62f820d386ebaaa780365578b4932952268ae0d5d74ea5974bb8daef045e7fa13665681970603154f15eb8d90b340ffab7b012f2aaa77820a6992cf886bdd4684b12686448028475cc0371042a144285c638b4a7624d0956b6826797994d2b6a488888b8ccc757a2ccc5a79c0f012e7698495e0ed8aa20dbc687db6ba1804e969087c829e260fea8c5ee29d7610c121b379e493bed9de9bc021849447ed19086e0ecb3598cd96221b72ad09487a0e72b27313b1f0f7a90b3a095ce0d6f8bcd7ffa22e9331273f3bd6c1887f1bb1b49fa7b068b93f66cd30e3b34bc70a9c226449eba4458a89f249d0b033f084597da885bcf46e5c2e548b28e051989ae16b15e0fd3c26b0aa4b1e041a94173009e825c5d570e8eb8d6dcc1735f621cc1346818cbe0974253db4979f98380a7d72f04f4cad91777b710641940ed36af6d63d905e1ae1a2191dad3\n\nInput: c84eccf5fc441aa65c63f41307d182ce1e43127bf9433fd2bc167de2b5896553e1fee73440d9f04dadd9ca3eac5827572100fdead72e7d26efb4d66daab0850385a5d5982dbb82200cfbda0f31b872b2d941482746c21d8b9e94df2804f6a66872d8f57c76855de32423feb5dfe1ea264261ab09b7d0c1ddc5be80f5a2008eb01cde3e122522523b71165d960554a27206b7c760140efb1f243878fcbb06ed3c30", + "c1af2f2bef99ca8ee939d08a6c7e456c7e88aaae00ca42a1e818ee\nSHA3-256: 4dc6da3998004a3cc7f94ccc45d5e301df170d986ee86c8fe6547ee8b6887e65\nSHA3-512: 155927f7187b9cdb9e031f2c2dbad1d89e0f42a9187c68d30c4a77fc49cd7c6484424b1583c33983ae24edb4cf2f5279685ffe2c964fc2c26676d915381e95df\nSHAKE-128: ce593821733d37980c561e4b1e806842b496b0435c272fac7bf6e728b6a8c61b871887eeca33419e7ceb9470567a52fca419c4772562776ca48d03640eed5b1c351f5b7642df5425bfa6d875eaea582ccb129504045eb7320dfa6db51b2075c1675f06feedb4ccbaccad9c56a0ba81135ab3bf6a3244557e53e0967f991a44c6715c4dcf437cd3480a390795b89cfe25b3186dfff0ffe64103f2b6e5fb113a857b1fca1a7825b49bd0c2bb66a84b5f25d4f5f9cc86b5544ef785c0ffff341f9082c6cb3c0f3e562e412c7dcd8d43a1a9da1d8c8472b22c5584f51a89705d7a5fbd3613048ce5aebfc0826c400645a49a4743ff1e924cbf7dce0b7d52c52308b95c49976b74e194883ab407c51f5d20c22ae3635638b60e86e15cdb981ea8c9a301a57dceb8e89ea47b281f52a796c5be5d23194758f2d73bf9326f47f23dafbcce4cffbadebd923b032461b2e0a636fc5342bfc161c3540d044067d348758d18baf71211a6ec4f7fb721a5d6831d41821a77a6d29527a102f91cac997092d85a866e5a1513ab5dd886725728a3a9bcf8fd1a9947dc25bc3eee8598c4bd0b5214b5f5f4547b712ea02e85ba3f8a00e71f24636ab81e6db0c2a4d82efa6b2cd34e257e161213d855861e53b01abe6ec4e09f00dc0c951f5d26832eb6474450beae292b1da11c32bd3d7bdb04522d0ee3abedacd7ac8de31b4e536aebcdb411b7f1\nSHAKE-256: 4d0d50729f2e72fd138bc54bc277a0a447584062d5cb44aef576c36129d54b200d5c3c43e15afd2b67ed5304f5409f1bea4f659f40de7c52bfb34d9451d0622301eddd1759b8ad0649193f30f8ce0307a564cceb881d5d01567ed2b25b1de660aefff643756ff14dc07bd6a727db7c0c1b01137aae560cc8d083a767e58dd7a50f7060eb45f8ff08cc23f423727d877a2d85ff8b5bd7186ec15c078bd2ba6b4fdc43a441474523f05cd2a517b8f781ef9a269d9fecf514582e5c5500dacca703f7d8ab981212009525c5df93e2682f477f2cf43a52e01243768cc398aa7fe30e263db8fe4533d0dd5d5a460291038c47530573082ecf4d7ec827962e34ef1e0d8e03fca1f8138540b0a60b0036da671e8a12c91b5259bcc995756f4a99d6578a1c319d64dc55b0f08136e3e2c4280f2b92cda736526d832b70f29c973351aa79328dc886edf5acaa38282b48ec47ff0f3075da26490c938eebc95c8b78906f6550e309144053f41812d25ebb89ee7defb7742b02dc8f31ab9697fb3e4606d6b823cb242df76fb0522076eb881d18e6169ba3f6d45350559ab1803d8a7a42b00dc055d9eaea01782f02e460876a72ec6de5fd5c274b3dd6b8ece1ccc4ef6c7f26e6142d9945e0d6c3eec0419a4597527602b7f9b33e217808fd082086269b04f8e0e975334200451be5de9af5111f6e976775b738f8e7d5bafc2aeee9dfc8b9b1\n\nInput: 9bd4ad22d52d95f819478eca86905c813851d4dfe2991ef9b887d25dacfb38ce036a1db2c908a6fc74331e7b8121181f4e370d8cad59319f4aea346b297f7ffede19d2a8a4b1c4b3ea810fc490b3ba888d31025e4201919101b42b77386b71bd547006ec1d25b5a99a60a5bcbff7ac2b3c347a7c20028f67e9d04b98a297c9bb42e2ee1c4cbc206cc965b559f62bf3f41fb4a7d7d76ae4c3f7324a4a0a11b153605cf319616aba1192c9b66045af9508cdd0a1fa526f60356ecabbb885\nSHA3-256: 83514eb64d7aca8ff061434e68f680f07566d4423f1309b35f84133e9bc5077f\nSHA3-512: 18827f4e197bc959507390dd493a885f3984f708816179ff56c15817a406504df1c4ff9a2928394c67d781712e5f56faa7847be7d962a5cbe08e19308fc81e2b\nSHAKE-128: 16928826fb11e8f339563747eb27ad42dc5f225b11896af5e6513c8b94f405f2c0e7a71338c50be4fecc2d0186428d229d1d2e469a89389466ab212fcc536d19262e59ac05bf52510d4ea71be29fea88660f1d5273c9afbfd7df446c96ff787f164a6c9315c7d6f0bfd5255b60ec4eb0563f20b3bd1a8071acaea3d0c53babc4d2ff5d8c51f4a321c7676782dddfed0169533786f757fe32d3caa93520b51cf6407c1b080468e60513c515bb570d826a8950468a81d2977166da5f35d3e5d9419288fa0c868b22ad57ac4ccc1ba20db135e58d63939a4ddf31bb9c8b85db874b5f83690c236ff4e27aa73fa35f24059618f59e5ae5c7f22dce445dc69b35de52e431d00b333eab11b2041b2e0e1496fa359f1c1d9c56498fbd244dbc30605cd0ee4abe9f200e6c8fca40c155012d844160e129787ac5bb9c82b77ff74d9f329f118acafe5c16efbf0dd81eb2a3c40fa229a2f58d253fbdd7904f783c9940f00660c3de71083146e338797be79039e9459fd42110fccfa7f60e54002c9151b725f460d2e662c22e219f862b6fa7fd736486a6974eb4b128ed829bfa695ebd862ee17bfffaccbba23bed046ba64af780b2e63d2d000c82fed6e3e357eb61c9cb04b520abebc538815fd29fa21b4be702ff977a0f9075143610b949d9f5f9a08a6e3041293da8792a2687d6b9c2fefa0061d3929a3300a18ef254d90bc9809bf744\nSHAKE-256: e91c973c45fb542b66a06a8f7e090d3826845279c250c871761b428ecc3cb042e159c508f8c28b1fd7add9c62deb795d9f6cd0988d4da1b6811c416c9d372b99983d71a3074a1d4444365ec02b56621046735dc293a7b3901926bc3cfb70f4abfd972618d9a68b1a1ffddbaacf7750a1ad050eb2985439fe62713abf3509f11dc7019421bf6999737f42d1f4f9a20137e2d183b7d50a991f8f644beb2448c617b59a3af8788c4642befda934181a901a27d2e734dc22cbb6b49401a9f7b3e6d6aaadc6caec527f6989901a9cfc2b247a55a72435ccc9afaef1a74cea19224f019619539ca7d7dddbcff016feb100d32d96ae277dab24ef6150bfe2d0e7e75e695821cb02283b7749f5ee0e24bcd4ca467b8ceff070705c75ad3be927418896af9b7e0367173c447f6ec2f22bffe14fe1892e68b10c5dee7a3f953dcf93f3d31aa718f68f2a3bc790a966aaf8e9fd1717ca9786d09ac64a11aeca68cef2d251ce2d027cd5730811c85f7f2a14e15c8fab90f3f9b89df5493c8a34ad31db67c41eba229fc4523cfe4d610ed02c2882fcc9fd420fe2a6d6425abf9dc0074246c4b8d647eeddc3fbe4fda6ecb8f35bba7e31b884ef5f5f7c0febf59112d6fa0e1ad8de95244eec9d0b97ecf4eddede6396d40c28bc3c1fe2fd9dcd8ff0fc3fd6be90b48c7013ae629782b73159663a45c3a5c656753f9a2acbaa8810ae63e7d53355\n\nInput: 674a7b538c33c83a093dba209a806ee911ff31fae5728ab14e47d72d585aebaf1271af7d14ca5e657609cf1012c07e87599bb1ae3efafba75b2b919850fdd75f6b6bada522680a1ededf5fbf06e27029e11ad4dc7436752f3229d11c23a8036515bfffc37f8e52bac3659cb32e3a405416ce39abbcbc3f7baaddbfe0242039e8b27ed162986a00cd62087c4add0dc7092ed5a8b1b4e079705648713b7decd02b50b1d21ec1f49ec416f96b1c39ad0524c3d590c404b05045988a4721f21d\nSHA3-256: c1a327802b8842312d372bd4fdfe36a23d93c67a21bab53367e3328cd6276e27\nSHA3-512: f5bd53aeb146644923f2577529a31e2379e867baf4f4031408f8e592ce8e21563a2fe90aa69aa9bfc9d5326012de7e3cc208b6519ee6716b21757988f74a85f7\nSHAKE-128: 4ae5b2a348f34b30cd626c634b776ec4e24004551d7c1d885fea59bfb8deb4e644e145077777b35e48e73a1e002b31284bbf1d9efff50b676e162929b453c55000a810fb66180787666df6d2822204504ca1345129b4869fc31e7cec3237f81be4e7be03b7301b6501cc17d0eeba3f9cf06b2a4047ce8855c750b32a447e38e4cbfe2a12b643ae6f20965e5c745e4fa396e28b9635b62f20f03c3504ce02405931e5f8056d2e79f8e4fbc554aec14a861b51e448cea1a6edda2c1f8c97e95a9319fc5992148721d924bee3eb52b4446e7a408d777f063f9e2462cee9df124261ba9377ab06accd7799aa8bc9e6aa338f8cacfc10cae29d042570fd40ac697f097d22b6d5d43e3cc19d1da9e08d3721c8382cb4fffb36e373ee25f6048b38376bfdad6e95fbfd4f09f2632f54d7e23fad375876362bb3394961a76d2a6877f728362f7216c28c028705cf5dc747a445226e6948d1de56bb5397afc3347c253e5e10d84a63501bdfeea429c9e9cbff10a9b719de6a924e8d3d9b1b56734e60ab60207f97fdc132ca65a95d9b161507f024e64687e1fcd1ba03ab11637f7f45301b85a802d88ee66d2f28ffde63710b2b35f0f3fb71851864b6eaa5b2318ee6859a5fb65ee3521cc9754a91123072f4506680055db83e06f2a5887fe673cf29b9d9af72718cdab01382243ff6fed32d611354d68026713aed015a94d8b53975775c\nSHAKE-256: 2292020122b147b72755c99df4775654ab12911b28dfaa5864d8eeb4bf712dd20f8b6be52aa4fd3e36a16aa76db2b911b7643338235bc97856667dc0616066cbdebc670b5ab90d9404b1c13feb7db477964c6ae5cdcfe153b838038b606227b89899a623518348bb46d04d70fb65ab73d344f40d3688ccbea76f21486a699ab72aa13ce3272dc654f735a3e999a22814059dc9827c92e1eedea60de1a3fa4d9b261cd7b5ac435d00b5de802b776063c677f75b34f4c63dfc8a575183834932b1983b3b39538fe35fec6fafe73ff74cd58c91218e8470c5248fac7ae24e3ebdebf247e88e175f2bbaa6da71efe798a7ad90bb2f9a83db39af7c50dd2319b0028590a8702f19ca63144271ed40e88265bd1144b56c3aabf44aedfb90de7cf6910a8364ec7179b3e002d88ebba922d177782ff969c6d3402727cfaf352021ca95fdefad4b654b2fadaa6f5d3e399afc7208727c859af5519a6ac0d67a761aa24e808c18b64a0e0fef0465185f1d95a52da41816b560060721e58f6557d422ddedc0806a257ea81963f5473f3334700b90107351cd04a400678b6425b63b83e2c070d91050c710ffa807f294e7a5c9ae966929abc5b71e4a2a38a5cee33cbc5f8cd829672e409fb4139dc531e184897fbc41223da081cd41b0ac329c6f3dd1a543671e30ccdb6a534d7166267fcb5be918d94b62d929b7a86ff87e59328019816a52\n\nInput: d172b60b6c13417e1605198979133d24a636cb686a1bfa126f966ff02df82d02c96b29144ecfeff01f5fc3e3996e98e114816f834d1b20ee74df1d5f3680ab0d99639f535744d28ac1a27eb6c4e6a399940ac097493548cf9462e0cb158e97af356c2f8bd134c9f51f9512aee84a3db7462511d137628ecabeec9a5e67d07eeb0da65643fe91fe7d08b60fa7380a52cd22f511cea0ff4f1459cb269fae822f59004d6a82613af530c94763a9c889d52dbd0f796d5e79068c01fad17c743aff\nSHA3-256: afe3a346fdc9ae99d087d7a2d2ba0c31aedb5ea4709741baadeb456943e78c5c\nSHA3-512: ec3e05642437d6264012d404a78", + "7108ca9db0ec8afb635e26836f4ab0d5190f081477af44bbb0a5c9bfebf3b6ec3a90a79c01f53f569124370d7091ef9658f0d\nSHAKE-128: 7ec216bfafaa313a07b2a5d6cb82b06d95cc3c667f0fc5566209e651814dd29b3e20021a5c43f9499622fee2665e95fbe6cdc9d3ad3f53d934a471a892baef1d1df700e5cdaacadc4b094906e141c4741923c2f037611261e0ecbeaabd08075d1b16c9f58741902b59032a7fe22db57e4fac696b30d664b60a054e3abf101183493b574c393040a01ad99f0847acf1fe68d34cd30e240220fb607bd1ec385cead614a8afaab724f67893ef642a76fbca3f629e476fa568be21d16125b1e791caf5449182855a012b648c4d30abf1bf1a78063a0b7f7b4f128f22e0f8973701573d3ae5069fe37430bf17cd494afc0d3e0153d75455fe50b2369d59ab908035cfabc09aad04105e22d3c940bb70bb41d695f6591310b0ecf1504b0a7a304186ae222af252995c1c9b969399ba95fade42c65d7f6653e41c3bbec4594dd44136a351e2d61385d3e1b469c9d431c9039b4446465512cb44738fa77386f001567d2d0ef96ed9ee4ff68084a9d54eb7359413aaefdbceef4f149b5bb4a53e1e84c52dc5192e2ff35b443b18672137d71fe4e2baa70db7eece73c6de8488c83acc042607ef93f8690f119bb1d20c1b044641b59789480726226784e01a66f097f18e07f0a26cb1f75d010d2c1417e0b06e3107f12a0c70b54faa138a08324f97f7a016d5b3361fe98a6d3a34b86c4dda027f5048337f54a35ef26117c67b3d16f6f0fc\nSHAKE-256: 781df09c7e135b95df6efd9e61982e670c4b0ef6ea4163ee6c7acb86efcbf4d852e05100bd11e20b82d0b6cc71ce5c953d22ad23ac3659d4513f5acbed7d75e30e78baf13c154d8458a1e50f41341332915d930f4a254d5a6d5cb80856561359b1ecb63962ab8e4d91c3730a19761234f0069d9690cf92353d4fec5f7f82f91850eda38d6cb16495113204abd689040a45710dc21fbbecfa78fb47cc960487f7f4e036877c91116c479fa27ab9685d3b3da1d059bfe102f242179815ea4a6633e5dce845db1fec42ecb7253c5846eba73eb7927d91052eb05b73648674cccef307cf8340321bbbb1cfba40f4e60e759e99b91c72734fef050e1558c7262a344c53ff2aeccff4357985da726c650eac46a161ba87cdb7cd74be67096b14f7a653634d9361d466b749c168f88d41219bd5f2d49b66892fd3d0905050059544c3e93875401844fecbfce82c06d2f5b2c1d9643c9bd2388c9ecf0892cece5bbbfadfd4f5d00bc70310456a3578b89979642f1487331359e2897303b49abe4380006c504d85cf0f5cde019f1b2edf6859a9b70c174a2fd7a2b65b66e744b70f18d7e5e43987f70286d42e9bdc0d8212dad21093245f08c2876b78d765683a38f4f72042c5098f9d8ef3f7a04025915b9e5318cf0b8ac7beddcd910d03d8633ee994386684c4321e84802684c4359fcf467d3587c26eecc5a0034842e25c2b0788da4d\n\nInput: 63fcca6282e49cffc903e625ac18a37855c8297a5af2a9bd868e3d20eb154e9834c3224d04762721ea817d6b5a47a0b2004c44109d0cf6f854192b5531ffbcf2e3b07b2d4113f3a2e3caa75ec289e871f298cb1b58a055b1f22a862b828e846c023ad0aa0575cb217d3acea86ceaa3a71bdcf8db0d43e64a9fd562268f22a47f2e9ae77e05df26dd16b32bd0516bb316b31f68923737ecf622cf2b7168413c8a2f6b5e62e935e3dad7a2962d93c65700950bc6d624e12143f2e92ab31e9a69fb\nSHA3-256: d1d52860fea19f75fb1c218e84e80afe19443c72b9941f58a7e2b2481ced1ecb\nSHA3-512: f48fe8493d9753cd69c5096a73a4957d4290dbb62dd938dd7d999517de4042ee29a3c64753737fb21aaa858929855cb383e471a15581d92d6ac6e75338e93d85\nSHAKE-128: a2ac830e8184fcdc8996c88f71464eac054c6298f90bfcd7368b7d2a3afe255d40a70626b0e3ef65c7c0a8975272dd28e434e473a9b379a00b1cbefb36901e0cec8d186a05cd26af343f564f36e55fb3f563e0a58f14519d19f6939c6c3717040965714ac569551211fff0176ca54d69db1f9cb34b7b3a6a452b3442092891357fc5657c337735f3c50a4512e4c2f66f33463a4d8e30d22b5d461ba3fdb8a4cc1633aa2bc9ee1da84f561a0331ac6e25e5d0daba51697e011869d74ca67de5a6d49c743fca08b5408844cee70e1fada3bf4d3f242eb563eda3fd68f43d75cb2df7459f997a5584c4e7c05c24d35c465fc82ef59972c79a41ebf2583bf069cdb06c1410e903f5118770783f84a9d4ee28493b9be3341f306e2d5aa754e7b8d944c8fc947fafba07cce9469cf1abd6393b92f0cd70ec405efc438f853d8cd4b2bdb0aa1417c2b6e7713dcd7486ff622d11dd284c182dab58b2bdc8ac6b05560d15b557cab60f49415981533c98a1c61c209d9df4e28d94cc119939cc60c649078fcd3ae7756e9864b01f5747ee72af89b686bbadd8ef880d330df2e8ed2bcfa4dc940550877dc4116132ca1304db8e05d75c2fe067fa58d4802dc750c6dcb7f359e3d9ee1eaf061fc23a7e92c8949eb7ecb135b70f4d52624d0569320e4a68157b66e14bdbc00360fa2790b27d1481c51e24fd19a14658598bc5c212fea4455412\nSHAKE-256: 00a1e9cba6c159baf3055b37dd53a7d4f72808e55545ae5d7ff2f77f1695445520056008ad8d4e69392b196d6c656b768ba074ce07b80790c873b47cf90a515f096cfd488ab4fdf01177f3c2960018e672b33ad11431e792d4c6b38f3d894bd041fbd4fdd6187f21e16df7f552840816a1f20b867b4b22d51dba353ad1e5a313eea1dc199c548c74ea37829360b5336944994088a8a50ba8e801f56189bab8e7e7a3a485cd2bbd988c902962e51cd7740508314aff19385db79c2c98daddbe82c980fdeb664ba24c78f26c71b8b1b257b0089bc1edf9c30bd3e1610395e731ddd5f2fa7fab62fd1d5684ec4d42c45929bf7dd87fdbbbc3fadd71158cd8429f5a007dae2291c35dba14ffafd2f920bf9ef5923024ee98687f8fe5d977e75247256145898c31b3b5b4f62074f8701b4d4e3ddf66ba3a103ba54e0de58dcb821da0a1a6b5c08805f3aa1f8370d5769e51acaecd59b1df02bf4001b2fe1afe8e1ba3ddc073ae34632cf587df5ba694ac548596c34d3b02d4d9563713409c506d66895d58bddcd93433b26f3e32e9ca9dcb62d280bc8650dea0e7bb468ac6d181b6d86f2dca92219891f39a9d27577a43b5c86d47ebb2f4ae31aa47dba0584757e53350cff2d146864c608e7247e76e7fd12a3f0b7b3cf28c22fd712247e9630ce26d6bf6bb80057725c12cf1289b318402ffd52a48c2badd1f13fde48fd09d08130d\n\nInput: 6b5f5951ace32dfa396b6184930db09c48761707b7efdf7a1f0218355da12985f589b91020017c79c3d1c55e29f6312fcb832934e36ba150d268cb4538b235908aed661f656aa0cbbe1583624c54909abf1dd07ec4b65629e34ee0697f0bc679e11b83daedb8ae05f8ac02c2311c2add15a8c679d5d84ccd0c98bde65c37915532035822885f1837104d666179ae95a3e957bc37919bf128054ad27c1470b8e62bb266c643fe9d49eb99acbc13232fa075d2ab390ed340158aa1e3c763822964e7\nSHA3-256: 0cadb85c05c1ec988b5f2f3e3bdd9d5efe9cdfde128652e87f5d98d96d27685b\nSHA3-512: 0a38a72febad51c48c6b693cd2604791ecf08daa515f175a5e568a1a85b0efd080593ce90305fdda185b594c68d348ce97655aa0762a59554dce423ff35cffa4\nSHAKE-128: e430074882fc908b090366b479342a759c71a692a528412d3ee74a59c27396766d6a93d9915ba35e539d0d202f4ae9dd98178db40a0fa6a884829487aa2edcafa150c456f55b2fd802b5d858ad79da14a0b048a0b731ebf0f728a66bbc82c24d2ece77d3b64fbc6e9aaee4a8f57c943c7e1e4b607f88f8ea2037db704dbe3b385552886218460e89255fb34db1888e8b044e153af7403dfbdad6d0cd8a71d8ac93fc3d79982093e66c21143ef4e5275c199d79243ad9e77d7f3075c36370acb468eb2ccffe38d9d4462cf9acf612c8d80279cd8ab28882afb233dade14d376f5600e1ac1bc2daaecdf681d96f739888f685171122d660f70a60fde6e55e6758143d2cda792949d0c2e284f96ec33190579b533acf17c089ab6c267794a36b1923654d568c8cfe6ba2287809045a0bf9a6731322b99aa418f2dcc9cea5d675b10e686264f20afa1e604edcf63ba9641f29ada0a6085f03e7414126225bda49310926cba864d2e26c08166994677b48ada633229de4806b677cfe5c5c022767389a1b622aba845db90484976497c5a6cbca75242fb53828e765fdd8fa3bfb0c4b38b195e4692e8cc50fce6ac0ffa8231a5b58b3eb2d87cbbb2fa52b9a12b51b96e1a7e5fe339dd2991415f94d1a9e1b18db2e30b8cd839dfaaace55547a3f37a8bccb716376543ec24c6916992e22ab86c88a4f468f357767c49734bc96bc3a65f\nSHAKE-256: 65d7ba4ec10a109da4f0c3c497d93ab828af47114be3909ced793287c78fd509923775c11abfe1efd55d0f97cb574dfbac7213624162798d17a5608b2cbd6c5ed678f63556cda0f6aaf1d0bd17308d1b64bfe46d23bf597800b8db890a320b0b04748d9e411c504656fd9a59230c618554594919277c9540c007bd7c739abbc9649f4dac08924da16cdda44f1e7438e5db45be387d4582dbf8bd0c3d69d733f4e449fb3927d4c92bcd83a7dbc3d5ab947a7cc4af764c87a8eab5c6a4e4269d609f754c33ece1e6605091a5a256fcf857e26a32aa5a966aec319215d0e657feb4eebb371d94614cfba129fb1a5ce4e6628cf5d23cf8e4b82a391d7791631f19cf14892a46269ca0403fb443ad69c8ebddb3d632287a13fd3061cd949b101251a0606ba2765eec3efc69ff773d647c1d46fd9b58427c5ccd869f3ad69cf01f33219bfcbaf0f4045616103eb85a2b1e22151a976581413d74906a02ed8e55af49f02baaefa899296c029cbe6d0f9eedd889098956dd3ca35418306fc84a9849a443680e68737ff42a773b5df926af978e47efe347b9dd4298dc754543b01da825080f5dc8dba3e11a35b0fda36295d83aad35c029bbd8207832653d283f9672121f0505cfec8490262c1440cfcc76a083560ff990704e5ff290ed7e13ae76a1a2b86ba99fd2ca04355f056bf2df863f6cd972c690601c67d7d0a004500a088b6c35\n\nInput: 813f41dfd4c9156162d12ba613b5fd841b5dc1d8e10a1c788053caf1296b9ee8921bf5f88faa60b181433339e8e7d9678c1966169eafbc6bd0bc9c1effa9a626b31989b00b271aefdcfe39072811982fdb8c0056f36382034c77e0b08c684e52cbeb9ccb809e1391ebdc437d8dd35f3d2c58278f6fe74bd9a27c874f8e6da38283bc2ec684c1bb704d319fd18b93d74532f1e0267a2006c85e8708063c989591da493c6f02e3c9e0f0c651b80863ff9acb69fc62d035af13968328a2743a79c9c9ea\nSHA3-256: 5148058f32fb9c1fcb6089d066b51b6c00f7b83f77962cd8724517b2fdee452b\nSHA3-512: 8cb913db601532a5c94adcd4014b8e322b8633a0194bd3a3ddbdcdd2e98e65c46f84e6a46ab37f208c5b77eb698ce928d95da69127991d80b5eda9e4d740034b\nSHAKE-128: df8cbb80b70498dce78715761d85418c253c", + "b7690e35635aefc3d90694b1237078e76ed0e31941f2a9d487cc3c7603f688f025cfed8f5f4ccad01534c0ee32f7abf15df3a3ef5f7cce027f69e2e2514868a20de044548e4dff4f8e58d01db1d69698b7d194c85d22641544084d40f01876db496a17578ff8587ae0df691651bd54c53451e5d238aeeea3ee5f26a18415e91585548600e5db45749e8149949721ea1cef62269e145c974c29169004a09ccf477431c86ab0c2d5d65a72f3e6f66099f65c27a2eab3eaf7dd71ae111e3689ad8bc6534ea9b50d772f11a84912e01bc2307e2453758af9facd3edf567b27e34041fd1c5c4d60f42a33d2194ffe2f290ce0d40ed950e2f23b8b10955123a22980bd62ddc2dd60104529e98d4377871eff0a4d41a156a36d7a60502c42bcf2159bb8e3f9514e7d621793dcffcd52133539e87b361095b3d35d3a8efcbebb3469cecedfefd04f74269e1c0bbb45974a8f20f739e071a57f68dd7c4ec97f2d73e7761b8b98c323ecf317df1ccf2aaacfbbd48df14ebcf6f3731168d0835d8a1978ab0a2fcee4f05dd4598925b3ad3b4d4f833b411ac94f77cd0ce8c7d20f5bacc5e58ef3acc4771e8adad34f9f8d0fb4e9eb21147f6036451686971a685657f66a6050c8521f9bd63bf95a3411f391f194455f995e63a6cc64cb6e6079773fb8c5b76e69e67f839e90b0cb43ed2b161d64\nSHAKE-256: 3aa310d6eef897603bb83da327ba5a17d1c1f25cab676b44716b0616e2b952bf7e75bc6fb6e0d35cdd5c069f4958f49765471351c22b8c8364d2d4904d401017a1979e62a6f3fceea2fa5010bb6a58f09119e22221d7a17836b2959f352ef0caf31e40fceed17c0b44ed073e6e3a9f93d3bd62d506952c6e74a4b0625ff87827d90735786a9bc1c49c91a3f40b0128e067d9d629c8d0d57a54de59477be1e3d1ce65fb7bb347588092c76bda804f9859cff36d3e38fbcf14e600754911aedc632633e72d08be81066805fc21095c1f23b8f1b971353d833de5d26ab303be71d8c24aab64b4a9e277b50c9a638e6b2d76ba062d7843704770ed8c9d65e721776a4769cfb5a5f913aebd9e51baddf47558c358737b2432c01dc139887e03c95432670ec8e08fea374a2dc09a75ccadeedf1b05e3e36243ce439f13bfb55a967f6475387cfa4e2d700081e39d851a22ed3d3ac64243348abb6dba8702d5e65afcfc19c01c74a7390c7d7c468def7702ef3b6cc53fff88da90d3fe103fc2cc6eef36a6dc42fdd3dbbf8c5856a29a011e169bf0671f149999783f946fe59bb2041784c5cd76cd1e5b4dbd56cd28bc74f24d0017ffe4b4d9a665f934072a9590dc853db6ddfd9051d6e529fc2353f1f2191ad8359dd659ff602f4d5765d8d94e1e96c338b11b12e5fdf887dc8a54fab4b42b6b3dfcfd220e65edc21e729d0f801e8445\n\nInput: 1e083d8503d7c48db022d51740a43180f75c4dbb323ed3716572238015d37933194493a66df59ee752fe895be09df7034b1f292604f536cddd6ea6a2069324964d8b3e90281fc746023dd309bde17ce32f71ffd765bede2731bd595313039df06787ddb0511d6f19f811be6210abe5fbd3171fd03eaea4bf80c5c2f6550db01b9ad43e9da1fee5e68d7ff8e6af51ef5c25a078b4c9dc5cd42202fe7d86124b332091325149addb5db19a0604fb3a53da2d61c21c05a4c01dfd27e4be4868e4c4e26a4c\nSHA3-256: 5274a8c26b5b6a43db390ce6b66e77d397276e8fb847293d96413afba9ab7576\nSHA3-512: ee422e7c3db2373246c91977eca12506fa2087e7e326cb77aeb399e301309ea3d0050278092f940c5a8f735e72811649bae58b0375a373b3451740bcc082ea43\nSHAKE-128: 5b061da038e8ad8a306e6b0f1714373502cb44ea52e902b435900b754a9ac5d189b4fd9c0c93dea178cd9606a5f41f17f44459027cb0a1bc3300262c10b661588ed627b3a61320adc06b1eba37abd1eca8df5f42c57928dd4cb3c1e12723eac718be310184155709d2c2eca08d6769717ae2412013e5b93fff39329f28e2fa8244a573024c2fe46cede32a708ed32460ff87f921340f9ed1ad1ec5ed21bd83c7c23786840b86da8823f1882e9e3aadc4580170afd824270510869c6f977b5841f2bf7fdd12574327f5153f579ad0b7c6f2138110cc7b1ca3b0677d630a1c2eef63840b8eeeae20a892561e7a01c1f9a8a7cd148c0c37f1857e7b7abe308fbc09202acefe351ca5cda325fb211ef4f92f1ffa23ea6394bcac2468865cb79b19a857405bfad4f9584d3eeb74d1c1aad61eb59586fe2c1bee6a450baecd455614a30daf0039c3e3ef478a0531702ad3de38d1fc24a5757275a3c47911728d283191507f3d10c1cb858d7ab4546401b1d90570001a70b25ddd651ce0b27486eabc9d79d9024584f7f1ba4f04e134623a5826aa0e5e3872e7528341e8191ae501cfb66a7b5c6ed9ce69502f91b9e7b56fb7f71059cc1ac1502665bb2df8af37f06b1c13c89a2270e46be8b932c6e6bb628786b235dc5d00d89d163b04dfb46fc6f820203b5a0876707860c5ee968931742108023697df25a0f175842c807404e08c82\nSHAKE-256: ef2c4f70fd8ad613a8600cc3cc4bcb69869931718174eaee73c9e3143569281da433c3ae41e9c07ea1fed115ac69532b5420766ec8c6143f9069721e86be50972018c53a5dca28e454a968a144aca08c48a29bfd400cce5996d68fbb40ae50b93aa746d8523dec0ea27bc3d75b3becbdbd567a0c0ad56c9b20e02f92b3136276ffd6390e6582de5c747692111ef82428f7d928ca1f03eba7c8f2acfd66ab6cc1f72fd0195c1fb13e179d78e9b0755a7bce3b3012d95bf27f6eb9e6139b43774a063809c85ff46f2557b82777c7ee5a4b0c56ec9e07bfc65446b0c90d1e47125858bc3e6ec7f5f20d81e54ae840b0b3f914b2402f42ea382a6f7e02323ebb9cc6cb69f71741375bd8dc875e1052dea88122a04d7d1fc834898a715d12da44e9a96f374be029a51b458d6fbfa2dfb5e3f9ebb54bc91fd587f207435ab47b7aadb04f8db88b4638833459be0bde209c739c516eec99d3a88560274156052fde5d7ba0ae8e22fa32f0105506ec2cc63cb09c5620aa29dc38afc5fa67fc1f41e70019411e224decec579b7eac231d944a5798801a29331e3d7bfcd7dee35a08207c971bbdd8ff53ab7634247ab7a1220e43b241f046b4e33a39de6caec6c6c5d53a3204cc4ee0e4409236d4b218d7d3b13fb6d4565f503fd0596a6466b070a3fdbdd9202a8335c476dbef48c0b0be4461350bb6c31090dce45692437d7395d592fad0\n\nInput: e0482cd9637b3ecb98689bafbe4902bcf68349266024ed6977c7c384261cefbf7ab8b3dbff48bd113da9a0b8233b4bab053b3cbde0011581475e08af5851270e3059129352bf9847be41a2ebbbeb39de41b03dbf6def201f2bb85617c898aaf9826311b60978d3b85473db52c5fb98a5d5c21bf205049613578588d9a918fdabb9ba86eb1ea5b864ceeab4e74fcd57de08c622201a6d1fbe8196d81f10a0bc24a3f1d0a46a6b372f5aab739de0480b6ca4229f8228398a47342423937af2506b25d8c933\nSHA3-256: 46d65b033ed9052ddfcb83d7156fc6ae508eb34866f913d700d15e63c820843f\nSHA3-512: 574c34b762deb6fe975c85dd0b3bedf6f2fef4564c9d6de70b8b068a7b261e279276a25c0e8a477c7ef5af725b5b561fb32b5d1527666943dfc3f6a5e250e122\nSHAKE-128: 9fc51aa88f7cb3ec83772870dd237a645042d6df2aabd204be6dc35cc97d01518a5e6bff843e25d7336d666c3d1f6dd1ac24ffc588f3fd730f500d2b744cfbd28adf97c7b0bcd467f89998bf71b18e3b57018d094b3ad7495176e5b1d9a14e35c20bfec25cae782692437662e00b912fd68faff13ed01f235a2fe27e54ee24532efd10f4181985964238422336f9fdd87f5391b45d8071dfe045e172795c2e191a529c701373af035988c0322a4dac427d9c742f4140dc53f43be72d3598d4bedceb409763de8173ead4318dd0290064a5bc024044812d08a9d005ec2db5f85ff2aa7c88037d47a3ec7998806675a99d0a55b0160ced62eb1eadc9081e60e37458e282a6ac71c19641000a8b105c14bac5658a0bbb468d5e3705f4641b602f7d6da8b85ff42a148ac5624becfee049db00294c742b86d231f86d45cf12ce3858604a656d583f7e1f941a0be8abffb6fe0fd512c849e302c4356aea943cbd0c0a68be3222a6f01ff3e99973bd0dbad75bd686a593c0b3babf32e1866721e06f394cc2073d69871ba3f7b6476f080bb084eee55232a43f710dd38b216099100f178b4fbe4e391e52087002f0681b70432cc1fe2cb59aa892ddbe8c6c84c9f91074efd314ceb4eb6224d8f5296d05259ac6a9069b5fe70799406ba45ac66c44907e6980e295496ebecde98b933650674a97e2c6b055f33e22b362b757895c08785f\nSHAKE-256: 35857596d7f139e1823a4051220a58ab8e64de02be60795f79d3c63b24eae8f4b3eb9e0f2b11639478e37492b2151a753e546888436bbfa88654984da03a8b884d23a367712ee3b48fa3ca3a9a1c12e24021cd8dcad7e80a212d1417eedc95e0b57269e88793faf1fa7828c7c4b51519eb7d1a8fa376c2f25999bef8c3e094c53b08cf8e7565a041754f6738451facbbaf271d8864f76deb374888163ebf38173d9559e52bdd9b8537f008a50782ca660a8045cbdd1cf77c50c8ce0bbc839f2ddfba0fdbe650313a38fd95d2530aaa00b981c883bd1906a816039e6aaad2c457fb6e2a53db73de99b2e02f318ccd06ce3a503ee8b1f616b82f5a01653c9db9fb9ab69c53e1381e5f814abfea7a14dc93893579b1d8c372b049fbb49cbb81353f7f74f34eb741edda6db638748ee0f89628c169274dd33222a457dbd24a9fcf6b37a0a414057881a2de713b49450637b3c99be6509e65ec15073c4e0531bdc57a0879172d49d8b427efc8c8d53b43cb151d90955ac28c9050777cbad83208e4795434c3f7445a35752314a245fad4ef1bbe768b4ca527ad7b8f5249c8e6675214e904831fbc954801b5fa3f884659a66107105215d76652a0c6b6384700df259ac81fecd0ec463da7a96f02077bdf2c3e41fe6e09ccabb68474c06c9632d49a5ec46996860df1d171b06dc4084be93587d6c6061de2994bf91df3fb1d2fe6521f\n\nInput: da354b5b145fe8d279ef57c1ffc190e54ae3386c41f79f685927451de567ce3da8a89a5ff9a29e85cceddfa48b095d9908accd00169afe739ab8131e6c7bef7fb6f2c9380aa2e35533e8d2cfc12b3f3972d47407af698148015c4b9e86de7dcc0a345d2017ad132415f9635c269c03a15e1f2c82960b153777cf332991ec4f00b1c73a482ca248798b3afbb3e9d267527b5ad8d78eeda259c629c8690a074bba24ad70be6aae3fd7ffd216ef38d929bc266e5d8f3f49f4bd195262fc7f315be312cdbaf6d1\nSHA3-256: 97a98967e5c1bf185f61bedcf054a33383213388b711b1fe0217e8bb8aeaa662\nSHA3-512: 64e27f30872dcc56c84a60a711905bf04f27dd83e460e16e8c4fe738155b1d227fae358b35a60bb91cb82841b337407ff82cae312bae306707357de765110068\nSHAKE-128: b4c955488c9c70f4ccde66fa6d1e1f4c32e6cecbbe40c8a655c5fd7be3d9361de91a629a9e3ec56106e4448ee19986f4d3a272f00db7455a238cd5b7812b3c642677b9dceb2ec47407b47a6921867da026dc162", + "cd22586b435d5bd2d92a53040cd59adba14a283d594de2949d88dcd7656154141cd2148f7d79b039a8033341150f738eb9850df5e0459128565f2bc7a34939c0863348b5559c747c1fbb30d3c825486d3a6499eb82d2d9035b0c861edafe0c9985a6c6e6ebcb0cc8e878af93f2d900e3def53c5adc1e8cd45d7c9851b6dbdf290838190219f7fbda2445fc739eb343d09b2095bc65022b760448d957a09eed88c8a8e3ca1c432df353958ffa65b400d0a6714c84f29fd915d9e68ea8117984ec4671bb3389ecc3878187d7a5cd7ff8b6983639264c0db436113c2bc5b5b999d0479fb8d77cd2c9d75e05503cfe2a16b3312c61196cdf5909bdad3828932ce271f6ebbd3856a9241109e5d70fb326fcb495b809991bf8777fb52a2298923fdd981d276c1091a87b1a2f7ef87305177c64545663e568c06729a818e636c9f68a9ef6c1b4adaceb00a6d0927f775dabda4d553ba8ce92b49f080f20b486d3db1e03fbbc97dfc892be248d6dc2ec0190d9fe575554c1f617d40a3cc7671b8bb7e1adb1ab981b702dd50ae396496918d91a69e4d978b471aee8a4c8f2e346f144d50c0807532efb8faac48e62c178e\nSHAKE-256: b0d33f40659610fdd9da3481e49bd6d85676983df84ca10015c683fa41c5c4987064c14efeea5365f0d3c1db4a4b1d190ad9ccfbab976954f199c297ec9e111ad423adae6c60ffab04ca6aa2623f87c1f3c5f5771a50b24f730fb95e27c4537af0b277718fd5087d24a005d32af1c177c1c387f516277a5104b9170efdd940495a4f505af4aa9d20d83a7ed20a113e422869515d643c905771bbf1fbc66057b119f1c0015898b77c2d68c0c6e0d4ae400c7377eb9e105929f6a697b59fb047121a08727ad4071d66143de9f7525f66e6f218dbe4943d382de82e025e49120c3eb672036332ef3946cafb534f0b3a61371cc60f3a247aa559b388947c364de10083f9292d38a2c77107550003e32c10ed783db383487873e95bb33c30c93756a2f2675fbc865c1b1f21c83247f1b87deae3f54171a23e515f1a4ddd25d1ea6a239325956c256529ac8b23b8e163a42c780150e10cab3f372de24b8cea3679076d02a6c4f63050846d7e486192fec2ff476ccc077ad3df342f5b4f6dcc470884ffb6ab30d2c6bd9a140e20f2c2073cd8bdea4d32286af4171ead433a5d8b9232975bfdb17967619cda8a6a7e04415a53c6311d7ebecf907328c550a3e476a4bc19167607871b6a7fad12fcf6844950608a0d2da8e02a69372566e307c11e771c7919633d3cd3f11af57e11b9220ea52d2c498bf44faeb0f4a95b0a8e1c5e216176\n\nInput: 9eee7ec7995143ab91f18a10856de919ab0c8e4351ff526602cddf5d1290f1170ed5dfe380f2fae2530fa3d7a364863b8a28f098e5effa1f5b4c037385bed19fd2f7eaa89c7ec5dd1a17072e54fd1ca08383b82832767595f0cd17f9c4c82144f8aa15819a7b6b717c68f4769184a11759e43676d7962ca908f890cd97212e528e803b4ad3b32d75770648183ff09a66bd61d2042476d8daa8146bc9e2056ca0bcd88e5500f3b2a4f203f4793a67a1adfed7017b377bcbb7ea83b75b5b55aef32c344c3b439c\nSHA3-256: 24d80d86bc71d691260d314fabe74d79abb479895038516fb8444f0f26d035ed\nSHA3-512: 108c1fff5e4868b72c93b566fd6a7c820b13429f4fdde4b8e471db26fa77678bce206f86e563e3349e6b71f5e0dc4c5845a910157557fb37aace562e6594b177\nSHAKE-128: 88513577e4d5149257bf04b88a44e7e54e8b411838f0f5cd464815e21eefa4ea3969e9c603f84750e015e34f000cfa9cb5e9f684aafb31f472fde44a6fca8a37097826fe3db0479c9e210a9a945ae8d25f7b57b3ba1a622da1346faf118e76d0939cf1bafe5bbd01742e710ea31200d67a10a9d174eb7e9823de02f94878daaed0ed4f1ac7c83c663eaaffd0dc3ccec83e9cd88e8f5c54d3042022fa380e1f8a06a37f31cb1b44044d29cb6a25269eb87bb4454aad79929e574b170ba0198ec48584f9937c77d33debea9e7b1770bba7cd3b2eab070030c808998b165c80c4d0f2360d38b95bd79fbd351cd2fa8c7c51d9d8231ca4ff9a4212a1106843bcbccf5c6a92d21cc5d12ed5f99b04187f1fa127ab7580056deb155ca8bb01c4582eb7cc31a38dcc2e458f4920ccb824036344b4f7346b10aad5cfbe2357947ad4bc201b7162f7f1a6ef9cb35c498bbb662b4554bd598fc49da51bd5c3bc6b7fd5136c28a2a0fc6dc4deffd29d06145992e8004a68b43954d299ba126ee8fad2bfa42fac521dfe776471f6d536fd7b4727abfd2fc3856c8184cde6b50e6b73283d952a2a29ecc32987935aff1571864dd304bc67ed6d00b8311ddc3a452c686f551ce7c74800ccf4d8813c0d4dafdc5f5af91e5080b709cbfb89083e5a413ceb0e70c7498032a91072cac643be57b4d8c5ff4bf864dd24d1c2caa581f95740c61fc9c1\nSHAKE-256: fb5b8ecddf4c95c106426713d89b464a66595021ed53fd17fe012a9c37eb8e7d54f997858b557d094ce8e1d18663e7c2ff124e594dfa050403345e99be4e0e8cb3c713da892b3b8754802504619489000311bf067702c1a21a44261a701b21b6ef182d7920e81f2c76cbec15ca9740708596eaf7b1b878d58d6c1be1db248bbcdfbd996c2d86e5ca779b1b72d0e0265d76ebd9f5779779e7e986e177a803272ea9039e2153ea8d6087eb984f83a63a1a1a180257250c3a5566e0a2ed4aaecb04e0c1dfdd9e8684e7366ac1cac6825d96e2ff5a5c8f5a365d09bf081dfb8848f96e33ec3183e308313635ece78cc1dbc1c869f0cc0bcabd09b8ba6fde3ac36b5ef20583f45c9439a98012728a97db2d65e182bf4c26de201b557ab92d041d2747d805f2416d5c911885d84cb3b12b27b38837f923945c36530f7ad3591872dd01231c23923bb5c2f31aa0d1c8c9252aa7276bd53784d93a9ab2804964a5170b238892ba4343c82623ab20f7eae286f8a379c4039a254f15c9b1955af20e6f5a2364d170b9524a51e91458a073677ad318f35e5653e94dfebb18c9be6a5c07588740578c93bad4a499a1f6a593b4e486e961e1107879bac965d23975c58d4cddd0c8fe31ca6fd88c95edc7bf3ea719b973583d546139639ac44336851d2a527013ad8f4f1e623c77841d803f6d0a40ec6007cce49ccfe4f72863a5694fb9db5f6f\n\nInput: 1dfe1b84fa65da0aa11f623559ab798a9f4db7e5eb30bc5f60be34992c82db2c3187387140a75ea2808c04bfb844ba804b595eee1fdefff58a896fcbc2d09304bbf8649bfc7546ea5573dbd20757bbd15834f3c54d7535d9d190d9db705996575f31c59486950a7971cdb657f3f41b307de24275244278a183b6472e3300795569572874bb9d4f7671c04eab276ee65bc83505fcb0a207db459b0e6cc47741b0ff2bf60e8cdfad5c557662a6b2e34a395d817185e007087e3875d73a9375d8528e06ac677cc7d8\nSHA3-256: 555e373ca90834513542b22d2e8b3db8877e485d749c7f73fa40cbcaf10b7ae0\nSHA3-512: 035bf9b5af6c98f72961f939963278fbe547ec06689c6ee9adf9bc7a8a2d66c501dca0cd5cc990653e96acd7fe580d06815f880b3fe467b6cbe892647ebcc62c\nSHAKE-128: 1251095f90fb3b5069aacf203606b628867505de921077a0184ed4cb954cd6ba7a801178b1f0a524d878456007737a1506f582b4f369b45b656556b4f4c7e72d07db9485c0c9ffbd30064a5e4701f72dc078cc43afda6fcf74bca6e1fc611b542b48c67905f551ca2371da1bdaf84be20f23c89d5b10a3987d5eb110e9389b9953420a4c48d846b19f21e38cb0f089e92e859c3d2fa6e7c2e09f52b9d0e24f8f4773469321116de360ed43b6f4e24f7ffef7e6a38d9e7c9cdb54d6b523b1c1eab75270e313e5bd954a363c47b6b7df69cc9f0b36ff1a944f032f1499b00e138ff21785ea68db3afbb00280d9f11accd7178a9739b5030371652feaa0bdf51cdb5db7321735626f55bc2f6daf6b7bb1d2bf586aede1da4adbf7affaa946774869bb6ba66fffa7d30a11317299ba26aabee664614e000ad0ff2c6abdcc3354fdae8cc3708efad5db14270475642cb45ac91c99478c98ae094197becaa7765c6377df1b5a51f633feb4b630fbc09dee1122e18b72c5abb4d0c3666816f9712c0506f52cae9cbd8435536c0f0c5c803c656de90ccad6efa872050182a5c838d45c98245ca10887df2f05eccd820b3e0987af792acb1a90b1be3c52dfe1a6c720966f54a42eb4acb8aa7fd81873062fcb38538895416819817ab0f4eafa2f6da4ddb4e78dfee3fb9d5cfedb0336892ebf89b7525d578ab6e66b94a4d0e9e56c369eeb\nSHAKE-256: 81fc1f79ecf5f5d228abe7bc20670e477bc9a1e4cb65d168e114debb0a0831b2750cb4603410ac58a77312ee24a77174a2b8592a2763cea9ae3c6c714d1c989446bcc612b8ac296aecdc9080e62509ac614dcff0d806e0b9e855214e1df18166a2f1146e4c4a1ba475ebdbe6affa66561bac4a69ab35fb645332d58ce3473c822892bae426af896234ff66d18e512682cbb953c63cde1fee6760ece353aef70f4961c3240d4739f830133153f6945333ec87dace6eaa2589e1c541eaaf787ea42fdf34dbdc90273cef52df7debc482587a23f2e300305246ecdbe2543bf7c3cdcddb1c0b85f324470e7d6976db3c17a36e7197fa5e7106e189f1f4c34784686e51fa2bb42dd7ea78a6cba5ee7cc8136151ce24a3a376a91509ac6244648fe5e1926151a5a2bd0a90c1978a529a31f5b5dc3dfa21b02c34f1a4ace5ff4048613b5ad40ab7cade27e1cb2d9240e3a49b1f26acbb652977f19e1acd7e8db9b4deb174e941d55dcb23e277b9423bfa92408702159edb40a173d134a501267fd4412320a0a71cd5c633d4d9a9366372ca0b966b3b0cb260f3049a7bf969eb8d1501b4d9c2aa210c227ae4e6ac30c41407a9823c18ff5b9fd3308fc14b6c3209dbd9cf45ee35bde165031fa3c72d652b3c218631a82a78cd1e835caf917f7ca1f4b03136b2388de081ca80ade58d6d6102c5d8ee75c15a6739798fcc02411f3cc5fe82\n\nInput: c11927c2ade33bfac955afb6dd1338a45396a761979a1d3e932ecd62073b121d7007956a12a4ee09701864c6c781a834278e0923fc0449cc14316fa7c89876261e37898bcd39852b8a78ad233947cb0e62e414cdf786ad89d028bcfd6e1a53ca0e197ba139e15d811769b0206696897b489ab154aa9fd0306577104f8fb631f398970c945b7dfcad247d6aa18564144f27ef7c13955a63dc24794fe8600fd2880a21b29aa55d42a0db2347bb9ce54578a4b023d98c7933cd921c3b7161f6daa802ff721641d0fe12\nSHA3-256: 70064735defa8642da9cd774773c55463b81733d850125e67c2aeb08244ddb85\nSHA3-512: e4fc0b3041f7298f695893d173d94c595e2c028fb7b23492991a20c3623b2d37f244d92e27e639a7385d714c3a158f86a191672e01c35ca1bf5dbb731edf4bd9\nSHAKE-128: af57c891100aa0089ba5d96dca42c084eb3b02ffcdfff0bcef8642b5000f2f4cd2021d76790baa1203da690a02f7de4cae0fe95944273834d11ac6bdcd002d3e3fd4121ae98bea396298e6ef991ac9516b4511b57f92137e528b991fb81db14d58ccf257c3d37e21bfea541f490edcb0bf6e928b3385306e70de9dee67ddf099d1f2a2a15f5c96a3b968ed88", + "f50380eb874ef1ceff02d2e358f40a2175ada198f8ce1f0d08f53b7f06f2bee6c789da385696ddd986d14211fe3c44e877978f6fbfd4fbabf0bb80b222cee8c3085709961827756a2d6f1c0201cb3cbb834999f3e862d9f5ad035b943f77cc23603b72627f9bb29c6fa637792cf50721d6d0cf434dfd973de2ab35fa530fa7066db37562b97a7ac6dd107b9678072db2a0ceb728e95e8b480bce123e43d5f2af554de1a4aafe3a6d31c26734338d75dc8fe8123b5f8a81105f53e06431034cdd5a2ea7e7d8cc641730a865a0b4dc507e3fd80517f0516c764ecb5b614735b3bfa0fa5d04a047589719852d34241d62278725e5138741c2c9de6a125be04d5221d747a259c4ba0a5f235f35fef1db358d5558d37c6f9999d894dcb123991ae5721809ee14fba97d30845b256a9901d7931e907888b9c175340eae9a787144220433178e48e7e808f8d34392674fb4ee6a2cb31912f7e1c020ef1ae906e8d2de77db4d4a477b50ccb245faef6769c940c7ad7d13eb\nSHAKE-256: fa1c24dd4017c58cf695e7a3af75856547d7607d2c965239e5e8d206458a9754eb637dbdb6b48d9443972d2f51834e6435c892a64f883741b5f865e9d60137f2386c75076c02992bbab60d1031f35c9e7ef6e3708d5633fb2f14efe2b4488e0996c0a45a736bf89b217ad835e9f0819fe9bbc70eb067930a3c6123e53504a8e2ddea81757784a8d80f9c3f184740ae825c11ebbc9b80ae3b6b4bbf993949ef8ce6acb1f32a6a76ab2de4e89d0c4a789d9c54bf8fa6a8725bf5ea5094951cf5a82820e830cff670bf54b92053b4949d5e10d5449d2fd61cdca8750399caa0dd4a169e1b00206c813400ce4f9ab0bba5814c601d70907bbc6b50b843997a71f2a22ff28e005d5825d50f92fdf29125e27b6e135c5991326a3aec15866db6375dabdd89167838ba577e38cedd0dc3c8928d25161bc263843fba41803dfc4c3932804654b47ef01c54deec99d2e5f2f24b7d2bd1aeb7bc31cc57745341fc7035d802a5e5a09b0ee292c108d37cc63550ea1e418d57e4f0a90f275325b2b61476580fe8f3ba8c00a7fc77f8a10d702e7a399fd47cbb0e29471cb1ea549a4f7c99493883cd01feae1b30d640969a3eed8e960ef9ac59a1c3f61d99a019e5a9eb3bbf0e85ab700d536846b1c683bfbf59359b02e911dd667c461802a303b995e39ab16b03b209898b65c58897d96467d7a2898a23032b9850027f6ba1cce19e1e540580\n\nInput: 3ddbef8224fac0a3af319645757f8bb76d06d8d4375dadc9266f15049ff28b2bc14aeebbabf0ccd4b2900a1ffaf7d3091a17bcd7c0f9e862547d9d664ca5a06073c21145d865f8b7a23de1104739b2d0c621fd6702e247f53184983bf91ef5e11bc3093e697409b59c90981e3ec8414277ad7cc145e4d425e5ff04ea76f6501f5dcfac2075c46b77209eb16e02f323bb9036d0ba48ffce32f7e3c8563da166690fc67ba1719949809be9e8db9a4cab38ebfc9bb2877626d50630e901def90ee9de4babb76e6ef58834\nSHA3-256: cfb5a1a201ce6c46ae2f6d6d952ad0a9324a731bd22a7661d3f90dfb70bce7f0\nSHA3-512: ebb6bcb1e163a448513b4b071ba0c1b5e803b3f127fb3a826aef9ad3896fad5e328aeba88cccc04f004f7e9612f964cbd69601033a0b4db574b888c87c83005c\nSHAKE-128: da74c87906763c794c091913c641a50c9d6e2fcf130122dc871792043084ab9f294f98df4d830c863e975f46fd59f699e847eb4bc03f2ed497e884a35b97930c1bf6afdc4f7e48cbb6ef5f0bb79dd3d573894ef4412f2a77595c00ea7ee450a1add6a9bd2dafbd49870b4fd27b03183ef2aea104649a6c7b8b9dbddbcf72c9ebefb50befbcdb806c2aeedd720960e51e72149f58107c75ad1a1cde245cd6f26c5d6ceb1ee2ff215b714009ad4b9ea54c25f912e5c4c59e03dddcad67b5ec0ce1c1069bdad4fda097bc354d88c99b888aa2097dde3d07ed5177385614ab3c696d3e72ac8be12fce9411b4d56e99fa4e44609135c5e38b6ee2f19e328fba3c6168e849c51c948a005906ea4d0392a3b7408fa7278e7f81699337d787e252b64b701fe4bb95c86749b6d7ab60cb5cbf90ae04e8ca24cd4771bcab5c95a5fa4088fd57bdb2b195c01fcb52cfe2649800ccfc6183ea8cea887142189f77f6273ecc164c452d885cc3e937fa72f9d56891d1db0291be75d7545a76c79f74b943d527f7a7d94d33e0462483cc0175e1cc785aa1f3cff67e0822d7ea0d38ba863e7101410b6cab3a7459834622d7391576307722d7ccc92cd4a63f04aaf5793bf6c59465315d66abe2cea88e197196e6587df6841c489ec1eef137c0fd2225d235ceadea3fcf848acab3a0296c7c4b85048ddd3594ac95cb7983e6136af8dbca72a0c73e\nSHAKE-256: 3e6ff49cf6311f87846ee961a2ee2ed2b8807690da2371493c39af4de9bd3ad79f44860c2d8441fcef8dda45215de8211ea00c1d55b63ea359d141366991142b9719ac417617dddb93af36f8ab53442513f3ac7da455c516c3174acd05170f4ebcf919d579fb526750ebf93db79436ccd87111d07a367c66fcd5a5dcfe197cb257af736938169e102406bca21f595cce3e8ac626048619b0591fbc8251a7a8f4381a9e2c7a9e5104c6ac675f7893b096708f969f66e6e308067f746d4b3e6a2085390731c70bb6f48fbcd8b5cbaa239c8149ac4de8fbeed8c4b4108cdfd615161815b0e2443b958f1e8d22c2294eb6cfe72545f1a6c85fb25057ed6f7c178f89b37f962b5f43a343fad9f2103977fd00f2ed5586bd6e5495c7d79e0b65356d9e2334992d6b665a3f6d179dd8ddf238189d0248bd2c179192e07ee1eab5d146840ce4963767b3eb9bd5a3cd97016c7a367058781a81d6e46438b8789327b36295cdc7f3eaad4595c77d1a6c471c525fa074ce97b6503046ea81a0e0c9d42bdb7a44e3622d3a78ee8f6eb5456eadeb267c7cfb031ac2002494b4b431b96ee36058dfad76473b864f02d2b4574710d931c852f9cc83aef2c3d02959d614ae40738bbe4a41c60eb267a2fb3a8d50aea90f7342efc658897019edc441e611fe573f920fea4cf93f291d2ca90a36fa4c9301c6ef45e68ed11c7b861553712cd2cd4be7\n\nInput: 1552163018398990dbaaeb57388d99b163d50f37ee846e5bc1f6eb8e7c22b0c2e2f7e8fa93194a8c5620cf711a7395a5f27deaf8fead08984ac2c06f4b7dca2e131ffa137b8cff98c116a333c0832c8745c8704780eb11b7bd0a418dab3729ab15641fe6a379b967e9ed04e127b1e3bf8f9a20d14d4942530638f9a98c40b4d65d85b9a48b3260adf1b87508e46501590322c86b5fe8502d33fd43bc53563942bce57696ca83b5478525056d18130ba9fd3a08d5f8159e3ed608a2d2ebbbb397fd1f35fe11a8f2d98dd8\nSHA3-256: c07bea7da35c1c005911c5c44271fb322a0ce939b2a76204ac5a2e6430a216f4\nSHA3-512: b1e985157bfa9a886bc7420b478567f08770eaeedfec0a7db27fec6c7ccf2fc6fd83fb652e8b4ff3abae6adc8f4e6788dd1b772c6ae40219979f1447386fa682\nSHAKE-128: 831b543331de5abee4ca3fe2b6af5f96ce136c6b2c82d7138f51bd00339d1fff001a9fa6c0731831116ba5b6970d4b80b3223f99f311baa35ac8417569a35e9e48c844d598e11a6de2fd1cf693291a44be35c5ed86dceddd0d5c69e6f40d24509ccee1080cef50697277a3e32fd720b454915b8f77f1e9ecb274887140df62a715bf35b32895f3524eabd70742fc2c6ed863520117c3d5efa7af1dc2c92035c647f29487d0ff6712c91b5a55fe1206a2f3eed6445bf77838fb0360201d4707312681f166dc7cd35d3e3bef4232d6cff9ead031ec349fd7baf7bcf6605b4560fff7689dd72bc85b4dc8cd62c594cea068a4d1660386ee50ce13f5237e196912eb4e17e883a26f8b9d4ea5264ec5d4e13e9a6305460bb9f398fda9465ad2067d1dce5f91a0abfeb6fddd2483fe613c339ada084f177d0978421b5300b616c5506a57d4802c19e6d09b598ce9e48b8e1a4a7273c1e70f9c16ad833b32c3bea2452bc2714e9f9c8fa61fb9ec1f78544bba00f5e31e0aad09938b14b8a88227c7204055fc4a93f7bd3b718520576a90ceb3702ccdece515e08d4865a80f3a27d01830858f860f195dc0ef551ac474840539208157becb8da58110b668a32d8f074eee8d713f67619ceab693414b2867a338f20a4efc3351af77704819292726d8612a2923ebc2477c749fd31e78f78255e805d23eb75364b5925015aa3e152e4e3ff5\nSHAKE-256: 6124bed8a30fbb5b4078a27326a068dc9bb6761af1c08d88041e3203223a2c84b005cb470bd0ac9a8ed2e93220e0ec1164a078b1832a546713c1afb525b263664d78d3bc501d3a9c629eb9fa1d28d42e88801b8fa59cbe5ce76368729900f770d9eba4aeaf4e259691c01f5d1deea9ad47a3f1b7d54709c14a1521ffaf77a721dddd2dd737ac6455c9f006368c40deb09f560ca5eb5f0a3f08ff0f71896c75c6d7502792f807c3947aeae86fe9c99e9402e520777be3a8a561b33ffad60ca318ea4f8a537a60e86832514af902f34c01a11f63490ce1f1eb0b1a8253666179347fb063d6ef222bbbdc57a219aa305fd11f329a1cd4d182fac70b238a35f250a7159dd5a6cfa1271a1784beea67f8537a883da8f53d72a1556676167e906e24978e1f19cb5d3e3bc3a961943d0b5bcf211184ae2ef157b0e4519d3320a36000412c3215f04c7df5ecf6ffa29899c8169be7451e69f48d4ecf042337a6c084fa96f732d87c7369590f5211e98f2de5c63353482dd315374ac0ff73886e8837f1f79229ba02e9631ff7fcfe85bc768382100a10c5602f8b498f5e1159692087058d922507abf6255ace5b3296d66f1e1cf9f08661c7f8373224b1eba70222b8f467ee479d25683f6ec766e475a35e49d633af2776417de0b3205bc8810ec5f49c9f628fa0a9f3dfde39bb576d5c50c95392a4fcdf801ddbf70ba84a263ac3cffe47\n\nInput: c11136c92b8d9aa938de9cc269696f4b56b0d5969756532cf84b34bb3e33b4a06a732bbe5a9533df3fe2531aedf773d864676ca0ff78bd62f49525a843064a59754d94dc22f7437ed9aae4c82f44f8501c0ac57646d031791b13f445d1dd42e38af3d0997d8795fc23de60184e86bb6dac77a05648523592d34d71f03a1e506e3eb1ecd3ad9162e65ec2f999c4c5360558923cade2540e1271b8c6396c21ff7c1114819e83d2ca25542cedd5ee9213172cf0fc9a4219632c007601b40b29043cac6d45763f57ef22c8ce1a\nSHA3-256: a9500bbd85da11e66772d62d977238050139447a7620b540666230293edbc633\nSHA3-512: 1bf23364b4726e869242885352977179efeb38ca4bd01ec966edab3b2fc8fc7addb21a6f3ef1c85531b43f11d1f5ef22850b660878a5c5f9ecdb2ad72e09377b\nSHAKE-128: 3ad5230641499a0bd303cfd43c8f5486a25ceb986f695c2487cf2822dd4016d863da65718be13ac3c3b5c255d041a8e7b38ba5e5fe0febba7134fd5f80be3e2d36fda40edb2f97c3762506b6ace923265e63e18d8e060eb4a481e870151ce20b6833880d3d0d1662c6804b1ae67ad64ba02388106a55eb93595ca69ab280b74694ae9a64cd3b5a981b85385d1c9f276b5f49021c0058a5b80be785889db3b77f387cfdd62856be020ae5c9538be2c20cb78eed3bc121602d4e61d4d", + "da3ee12b912fc3ddc5f4b731292eff10bf62d2ab5afbfe92505b0f64cbdca8e7e2b58db85ffaa44797c4a87c32320465d5ade18d188d88e47cd970340dbc2130a38c3017287f705033c9d05949225277c4c12e057de6419c97ce053c767fe4526921c6a906e57ecbbc8a3e09ef489c824a411a6dc5d508cac57bb56e34e1f1f9bbf6865c60cb913d78cb1e5b20f9960bb86bcac7d62e39f7041f0776b23912f9a5de52eb3ab9ba7bc8b116549ccdbf9187ff5a49dcb805dc2e30a90f9c12d801aa34e31f50b3ee20f3962956a057abe903c69a4a417da7e9c7d72e03f41f2bfc68304b22d2c1f2224ddac0d35df43c816a23c229c1861a10c7e3d7b963ebdb03ec615208e11edd9f9e7fb72acce10394a40e0a9a4245ba256eeb29559a3af31583cfd4534d08b15f0dad0f9c86c809b2ae6b5f87e71ef9fe334bf935b8f0b983064c2f05e\nSHAKE-256: 31698056280c2e57e4a420a83ba172fedf4105b31eff4f8c58a5d6fe9e1aaea459a86db294e8465276167bcf5518d315e976e9416da8eb713dfaf7a6f358acd2e57da6fe2ddf5703fd609e728e133d2baea917b41dcde4160db3f66d1f7f4fb2cd4afd8c9906966f62e0ec2e811c2cdbfb02dd57a1020ad5759079efc76df6802c2a39533edbdcc637c50609fb634f652f50d9d3cb550891d224b89247112d8618a1c43472029780236dc8c0ccc329a75959e97e3db96b256b3a70bae39a296624e45ec68a6f07d1f35a2b475e5820b927ddc3d366be7bdb15cf3fccc3a2b5f870d9505fc0a0fb1f7b4c4609470feb6eca4d4b572942112b098f79f023e512288d0acb55e3cd8206f81fe81e2eaa8996148bb3001353f539619b3954c0bf9392ad2066eebaa15ec451d92cf301b4c436132751bd43be225a62afe08666ab8c77ce9cd8b225f4df16346e2b3a6cae699a99c0ac98757de3c542d22d15021da522a65eda0414f4d58d02e62a29f22af040e0b3fad88a9c31dc168e3769b928d960fc4f560601a41b8a500f7897b496372f5c613ffa180d9f1f1c46a5253001d6d9d6478ce799311bc79f8d5ace15127bb06745ab2d56fc3b9c86e97ac268fbaa9fb73f22555837fccc7bf7189e648b60d3e6a6b1620ab5d5addfa756608f74c9e2c57b38c1e30311c0f92d12dc3b3368178b66318624d7668e6ffc613a6eef1569\n\nInput: dcdb25ca178fc0bca1048cd3535960af79e886bb5bd18f9d2bb06303b891b02c57f442325e1756c303d66afd8ff8898cc724d2ebf82702377afdd42ea4463ea14cafa13f74de1a74da0b80dd8b0b13b77dafbc92da60146049f2474a9ff2f2b19c0e7b3a87ac095ba2ba3d8b57006510c7009fcb758e975410fc08f60a74c92bddd67d70574958d229c2b4d1697f85168e4bf2c1cb9fc7968b5a07cc944f933815bf4459353739d2b57e3feea5cea858c339f8f8a8ea7d9d8cecdb579fbed48a6f6f6cef538ec3ea4c9cf5f3\nSHA3-256: 089ff30b624db854f7b1b68813a85d4ab4de42a9700a086a99ee98d3e1ef302f\nSHA3-512: 17ca2d9091a0de2115deb30de29fc4b1099167d6bb514a975a91b85ff2dc89b5736db54f0363497625924e61de83fe84e9ae27428fc181818489fdbec0ec4910\nSHAKE-128: fe8848fda456484b74f009c900032f96ecf8456ec7c56cf7c866c23a2c8cd23440d337215072cd579be4ce4d7d0bd6835106a125144a25ef90062b48ac934743a78d20bacec0ec3f718696dcbf6f3a89bc27bdef366786d5c5af6901d8d7c06d53db921b394289e6e01e8d66519a8a54a9410269de54534165f563a51725c66735a200327a19bdec691ebde7708631399e7e145d9399fa36437090518ed5825572ab4be61daeff9abd8e1a50d844c5bbe852776cea4e009179ab846b8d6e83a92ec2c3fdafedd6279c7d941c9629de52473244fd90d11314deccdf6d62c805d67a8750c07f9dd03bb0a407949b79356d89af5e262be5b47d749891063bc12fd36593f2a757ecfa430a875b7731b829e73874d6b83897731bca0f540bda0e813e7fbdbf8b21b001fde843e35578309ee93d61591a693f615d29e91a70acc8086b73c55e28dfeec361b0ff89d99a95c3284fd26e3605fe96d7805f5f67899fdbaa1921783ff4aaa2d2c073b885b8b96cd92a1e14b910f735dd82decc039b09aaf6de6f3db559d383788b63442bcea94ddac3b5861732422e961a177626b4c8786e8565825752a5697fb629f50026524a7452344eebfbdd31ee14543e6c84138a9407580da7f335467bd3c33a60db2e06e260d6c23b4c62fdb2f85a466cf29eef8ec8b32153b8543c6e809962ff4a6b970a209f0c51606c7ae69d02751f39072366\nSHAKE-256: 2fc48c6f95072d0e0d9e1b2aa9249befe1450f160d0cf975cc0204349c94a40913877efe8571482553435671f6905f530a72ad9b0a44c7d144d86b91c99a8c612c41a744d3ffbd08cfc828bcbd039e1ffc737d70627c02fdfee4ea93dff9cf70e64c096ab43efb39757e60999373e3b15b6dd7a35b638e7848a0ff168ddaa419034a058c9d16fe3593838c7b6d79c21c8aefb97d6bf94379cc09c27ed8f8c8274847bed48f5fd8bdfc702905041eb6855922d85c47e5904fa19356835c246278687bbc919e334dc81ce5a2fae0a58baa7445d005f338dc1ea4707d0d04721807c4f9e84e1ea9c64d95ceb0e8078836d1f7a732bbd1d0ddabcec2ccb76ec6c5ab4fc02b1b69ee86d30a970abe6f53e0cc69833259c9d5def0dbac653885a8fd2a7b55be9c9510465f9deb9204d08051bce870d0bc00d3a24d67826fdae6f29ad2984a119dfcccb41b008ae190f89de4da96b596b896f2a9b0764af0b3cd2b1c44db4b91ef1f13874528e1638b40cddd6c9b09a72cf901bf48f92917e977e1441f5488a0b13775f45fee7ad406e757dc3ba0463a2203463c7159d82eb96f03eec2eddfdf9ca6da3c3fb54cebc8fe1dac05f5a495e0b21c97c69dd83c9d5cd6ce881d51019dc93f7682c63dfa9d3bf3e0a770782edf4b9d0d0a323dab9725c28094c228b60c31c5dd207f05706f08b8fc4871d9e6c58a575467d4b46fb7ff84a803\n\nInput: acd70a34f0426bf20d0264be87d453efa82054898d070f5e400b52bd53aacfd9509becdd9e415d3d25439257ed8748675e86ecf9376b4036b41f89a3e2bb93c939a95db0c24c27728a395e99ffa3ba5127e0697e9465ce4bd1aee082e5930cea524e4f954b581d6cf8dbcc2968b66fccebe2f6b106f43683b97bde945f9a860a705806c44abeb87994925ff4888ccb17a83bbac11ea47a4ec9a40bc94104b65c2d9808b92f698e567559019f8a570377fb92abc085d09c0bb437163dcbf6aead14f89f59d5726f239b73ab96fb\nSHA3-256: 0f93d7248c3b4776724f006bfb74f9fff34ab623e25cee949d53d8b3474d6dff\nSHA3-512: c393d5a07a89aae37f4486c09fa28fc0eed76b002b8915a1eec3dab0e5d2b3cdc03bea45f8fe8e4c178d49ddb160944ead326b9b927d0b44dac858cde941acec\nSHAKE-128: 6550cd8a150961cff12964b0ed5bf155503f5102e9327523750cded86cdf1a6b44c1a7649d39565e382eb595de1b79db564cacce9501bbfe33c17a4716916170158096c86725baad6aa3ac05763c389064f7be14bbe317d09fe00a667bb7e7aa3a6c81524f759c1f83918212670b678b8ff6d4c5d4b36a1a237f7794afcbcc7b071ffb39fa86434a67aa2ee294b78bd4502953574261198ca1bfe6027adc8f4473ea3e36b58c7e2d1e575be5aeb407226dd513976dae33ba6c5c0949f5e6036981eef16fdeca37184cac62282537a7fd7f07d5fa355fe335b07579c3f1efb71353d2d863f497f68b5a86b69cc2000250fd4df82597a33f8220c61aaff387b5b11087b872cca579d2c0c5796a450e7203c2587a1e4758b5536c39141366de4bf77411c1f4b1208722389fb79df1d40dc8358f9a6826a46310cfd43eee217f48bec498abf8ac00f0775e397fecfc96eebd01359a23c619234a22e5efd05dfe1effd7dc7c3606250d8da7d7dd1d5d52f9412f05a42d14c7151ed143db5fdcfcb64c7dcaaeb6b2d9935eb2880721e00997c1251260287fb7d2856db1da9a4a65291b8906d4645039266b156377a67328c1a854ec8d038af8617a1006d97925389e3fcd9b3ac312fde75868b4ebabc1f1580d04e86402e98195adea28c8ea57c30666b219fe93bbbbbac9b4d2baa6c0f44659810b8b8cdabee92661ea36513bb96013\nSHAKE-256: 36406e60d22f0e0be92207cd18bf12878b7d7e8ba803386b3a6b4849ef5cd679d3832b74509c2b14169018aed9c37349f0457526b4d7e2aa8d2d160827ae749e4bd435c66a928f2a69d576048c3869bb9d862a6a824f6ec79abb6882f9a41df000840cfbc00bba2a5355691a49db965f962926a8cb3c86f58cefa346467da937b0b7f7d2cd9a5eda831b6b4c6fcb9d0502cf1ad4d2e805631ce51a324d959521ee91500082ce818cc93e1016575dcdcad08872308a208de121a77843ce75c208c484cb8e9421e87161458f3f3fbf15adb4640602065d95355d7531764cb22458f12cd60899fd9b14c698609b32d165d74ce85473766bece15cf80d0acafedf7fde0235ffbdb2129ef16391a8eb81843a99543436f1f03e0bfad68cbdf141455bf0d3f505a4ba0c563b3a8bdd5d8273bd0d19c3ba959639549d381f9f0c065cb6d0e0265c2851acfa82485e5b73ec858d559805daa56b3e70a83ae79fc2ceb6ecbbec06a8004dffc835d41b2a7d8b6624567baf02c0ec27a635362b54882fa718168cfe6c5c4b1f77b0b4e25a4a547e076be2c7fbc341a1a1a9b22d2589fc9e52930c6fd27f7a1d10df4e740d0ae7e15f0b8d261d35fec3b02b35fd2d2c85a6819c8f53c6b1102fae799a116715b8a925e5e240be1829bcbce46b4916221dbb9d0db764b33e99f0c5048f75d9ea1b8f01af8b83559e2ccdcad2e0f7bcc79c7b36\n\nInput: 4e90ce8969b68ffeefcfadc432a86bcdc39098dd92bfb2cd5e9b1acbebb385e70f4092aa4cd02dce0d8369f2b57a3614e66ca2dbecdbbf6df226ed245853db753d21d8577b66fe9ca963e88d4ff30b6d936c58908ae792500175d8bd45febf480001201481672158acfad3f14c008f3db542c16d4b71d5586e2606f9170a50dcfc33ea50081647736fec46c4a1547ea7cea95f51330e83be02fdb895f7ce8ff7e62e41fd5bd70c6f2b48750293ce00666f1ceb0deaff16b5b43e40b039faef53466332b46429224244cd9482ac18\nSHA3-256: 7667dd06622391280d854179a1bdbec9249227eeaf8f82b971a16133058da242\nSHA3-512: de169250b9488399bf464a6b73263ecb5007d1a5ab1e786ef1fba3118d6ab91027e20a3c9f57e10f69ac4e4c83620ba6b917e910d826a6840b11882e55b7794a\nSHAKE-128: c4f61f778edae5db2b8b51ceded98dfb645490247b4419ed439f438da83f9bf521c12574b12770e9c38437c9c0d948223f4b09f665a619fdd250c111a9b99f000224ece192e85ba46085c1197b03442d5a9cdd04b6796fa0280348fc7c3bad357688640dd60348086a34a11cfec642491c98ab19bf582f80969e4a72e76415e587962edd6f9d42d25954eb47bab82d1fed71056745f63f704d71779dc75969b0e9c7f855d2d7fa2af544d2d99ecf73c60df1cb85d8573a28e5bca8be490a9907174577ce0c8357cb149462aefab83c64f9a67236c62c2b8a8dbfddc56c445c472798", + "a77a539c216762c6be7e2221d4e969a86ded0d84f2460a954118c3b0dc73cf312a351f9d0d10c158c5df11f300bcf3564942a72fe80c24ff85203ca7149f1c678dbb75721fcde5e0e72ff964c114af2f38185b7936b6d8beb20b6df294852aa7e8cd8caaecbf8a203d0bfe5b5f864556fb87c18f15194128e740a99a4cd651a915e0443a03b9991d7186cc5770187fe34161054abe22975233af49ebb768ec9bee5fdcee98dee114c11cbad23686e2f9ab6667861dcbaa88c6cfe66c27d1eeae16270bb15fa4bcc803844f7b966f7e739a9ba1398f4819f1181f2d125b35e31897d0117f91afddd3c3dde7b22fda5038a3b00a0ce545a0dcddcc032f991923b7ae5584eb1463933e40cc114e147e01039b3df0473094585b00e7412fcfb3\nSHAKE-256: 984160c1135c12fb386376f00c871459da09ffbcd6b47a5f73402446fd4aca2ae233affbe811adc5fb1d1453a2d3a5b4afdfb2b2565a71333b94a4b8321b4c93d1a7d83fb5b8b533980b440c69ab0b4e90bd842d2f13d1e2ad8998465a451bb0d9b7ad1134c8e55d55bac3b4d5f9050bd5a8f59425a7490935e83de62169b649900bbca4d3660a34f31b5c98200db06109937cddfba5fcb92d50f7cc33d1aefcb0136578d4ed8af65efc8169c15584fb026361b324c90e3d1fe2a75d27209c74331212aa3a774402bcd9696d326d15e87f0d84b893b3064bcd81f88a0bb902a3ae6b444adc2c7199ac6bedba376b0f3cdb0399b6835057828c7884fab41da2b23bbd046ef0ccacb36e51d29e501f31b65fafb88071e3e5847c1026b54ca2fa36bbf4cb2315a22e742b5cf8bdf2f323e0e323b4446adc72851b31d9078af86ea5f5f91cc7351b5bfe77607fdb3bd9e42d8e1b861904d58e5940c446ad262bbf82e8dedcc04103d28b5f68b12a62f3ae8c94607526200e91ef216033ccfc411b0ec426024f22de5252e3cc9708508c1087e7eb77535c358dcbd517afa9d275365c653fb9850abc0ce4643012dfe11a77d2fbcaa0326654f2406e1f20a45c5920fff90b1fbe8b76825a69ea4e111f22e7a3352015a3e297140a319debc126b343eda2a89667a1b38324c17166341d00eb415a2591c583e6e37960e3427059a73de8\n\nInput: bbdc660f4d4f05909906dc3e2af5711b7bac1605829b0d99ce886941abeba0141b42b350cb259d93e727b8850732c5fc520feaab8672369d4736fb363f9122f9d186d30725ea4e41e55e99a6173cd2dcdcd2c1e6cf94e4ee066de7bb4deb2de3635eba7dbc35f019a7b4cd7434faf3bb009c34e6352317c810112d69c36f6295de0e09af838d120efc52178323cf143377bf4c5241f2cc4866e5875f97112f031affd5fbedeac99bc2a8b63788cc71e7ca1e14750341f147f538947d2924e29f5aa8beec1a0cff67615d143ec689c8\nSHA3-256: 2d4e60f35bbdf7b2f461681e4a675a7c810babd9df333b592e90848f40861577\nSHA3-512: 7d86a661dd0b356c9c379223da7619e5032845e37e1817a6c03ccb8c34e2984bc5c70429f9cae97d417951a074e84dfb643d2944f29f488a61cac0ae1a24bd74\nSHAKE-128: c3c3941a0d0d96a7ed96f15f6fec7b9036047b66b8e8a1ca6761a636584e3865703da9af9093904166f4ae81bb1f23492ab523e1a2b3387b83a9b1c04c99469895952184f57db3ecd71ed89794953fc9c6415293f51fd83b22e3917e8d59f4dc28414bd121d18a35f025250f1feded15d92849602f5650f5f83aee160fe69a40bec54e9f4a38508ad4665ea8dba41232e652166ba4885ea336223e407d3ab5ba5356fa94d7cb3cf12bb21caa7116abd1cdba9699e08bbcad22ad7769d9a28e75faf3fd3ef7a4ee92cb1b513e0f371ee3642f47ed56a79d101693d4a06fc45fa9b9a4f2914a7a7df3ced212593379b629e5df989e97af9f2d5aa10b4dac4e5eb1e298ed39789cfde0927b576efc338e251df95483128a3f77f63b85e5670e831e1e2fc13d872ad6536dc5e35501235d27e275e710b703699937b9ef286e7455a5f42a6629105ec845e8d2ec8f4bb4a8a29498973d8e07443c93fc9ee9950e6548c25940056b1daa514bf9c6704c4d39584654bd17d0e0e8c5c67c50ff858609e23d3fbdba32ba8fca1984f4806642718fb1fb191e6582f703a7f51b10fa1a3b40f4ec62bd1537ec81770194b067d203a5260261b179c0fd21125dd9a4e699efd1907c4cfda88affb0e5604e573e25fad3ee5b2ff124204db084b2c5ccf7e8909405a5067e0a7796a3acdabe57b3a476d0f5d6ce6d8a475051ea1e3228178fe9f1\nSHAKE-256: 427aeb11a5e42d436b2775b900229b0d23394ed8320b0e30be2481fae8606684d0c7bb942aad80925f734506c2bae78ff0c359cf6c460d705f17caa07ee99addd5476a8308f2427337302dd1aa9059d15d5081565b71b7ef56ce5311de63c73f8931103c469f5c1420ce2741db80fabdf41d6b425fbdff26e7d5a81a279de41bf4b1db2aa69f7175867e46cf7c3ce8903c09f1a999ee25d049260e933e66f8afb47840a4ecd112a3e591fc9d92908c905c0a37a7660ce79ee0eeba623ce40408a10bfe7cb1cf6e0cfca5bc59f828bc7a5f0dbf49ed736bcb6e1ddaec3114d51a33c24ea46e22a552fda1148271e25a00ecc39612b4fb4c54ba559bd544d8c201757b572353a55b1d670e1d985b808fd70fca1c0a9251c5160f7eac3f5964caa72a2dc305967676d037ebfb35166515c5fa0e48ee4137957c664e886a39ae9f7cc2271a5e18717129e33476c2228a954b26d7b61bcb772cee560a6c5f7a4712b45dd5c31037869eb50ee42d3cf09a9c2f9f32b1789517ac0482ded78b36139ec9f679f178a4423db4aa27294c31a388c0d20cd94bded6518739396d689be98143d3c1c1bec3310afc18e9fe0da94cc84635ae4e71b4f645b94d8b5aefaf14ad22b091899e838468432510c11f53de255ea59f5d33656a62ea5b266756626011b5dabcfaf0b68440542a2c06860ffecfa70ef918370474f08dba34f54ad39b8b65\n\nInput: 2b420bd1578ec9a8f78571e63c7dfbc33e2176cb3a2d3d34569b287b948f188814719b59292a05c1bee2b575299194aa5a6d693c9c5a55cd9d29c94abeb348f6d1272b98d086a9ebe6fc10896c55db72e25636c3fdf82e00b8fb4be0dd0123bb82fa0fd8e6b5e8b47517b7ee3a099400c3422c1d8d74d872f58abce230d4199ed0bd5d4b291f27662e5bfb1797abfe67c46fe4ca1f35770ec99b447e26a0e1a99a244880c034593a755501c94c4e1d1cbc26c5d0b18e2b557e3fda2a630b3af17f3462a8ba8165c43f94e60459008bd8\nSHA3-256: 5fb4b601cfb32de59b058a012775c904ffef06823bc10b81e8ee395204dea3c2\nSHA3-512: 608a5e8495564eda5490f740608aba2470f4e985ea1e996d76c33a41ebe0d612ff0e5f5e16d3149e6ac921d9a623910dbf23f7b9bf56c649c91736e6903b3475\nSHAKE-128: e66c647b296a772bdb0e6a5580d164b41949671b4bb7366bab9c159fa0aa2bac0e43147776e44d0ea679af0722b6736cb5b0e3be8f51b2ad56096ede4561fa762539cb654d43169832858c69beada116954b74012b796811d0171b1165ad702570cfa1e2487b10b228fe1836f7791eec22b219792f1a207af0ce1b346b02350f8e8153295c6b000b2a2404ee170f2a150832a8bbfe8f8584723e5848f056281c12cab129d4eacf053a32e7a81476744703de736528382190b1c0cb745389e7a031e4b3949cc1f5f8e576f654d7907d001fd5a64e43353bf277e96936aedc1f5448a8078cf4ff0b2806b5b6a3cbac76b09e2acc8246b3a87a708451c03711776d0cf19c16ecfcbe1543e90e77af3d9d0d9272bb93162cc2dd18d3250d56cabf4137d44edfa0872d96934be2bbb3d089fae510fc3055b3aab40ccc19ddba125df48810ac67c5fc0d14788cb38e5b4d6911c5ca49ecc7ffda8b52dfe0e99e7b18acef7895326755d430efb09b247f1713206a281a71fc7fb2e516417c29b65f6fc813b4ca3c4af93ca424e50d19a076eb19cef3517af288ad04ec82f7d9f757062ce0560c5b05c9f367d45988f9915aa142c11541687d997cd0edf75c4c38535c1956c3c9f8d1af653628abe20fac029149302f74c783c155ec7324c7b4f0921cb8a33391a3e0b8095f6cf55ca0ef75ef322963e6d5283eedad991c532332549fdd\nSHAKE-256: bd71c50339cfbb3b06f3637f1603e328bac90c65c38297fc8fd4668072620209bff08e719ffc2c261009cdb441285dc5a7764ea90a0c39c275b069ea86f83029c42bc95095ad9cffb88a1604b44bef0066ee82271b0c928eb0932222c83b0707e1c44d2ddfdd3edebe2e8103a6961644a8c3e53327c52582bb73bc1ca73901bce43bb6a9f619cbc4dc83817d98530d473140dde9b3c85659c425cf00e2cec3aa31862b2532321d9be19671dddcd0513c70d046c9cf0c7f014cebd8431777c559f73577094a0fce970e4cde1854e43812b8e38c1a5051736391f5504d6a1802e3f21a1f3aace9222fe64e50b93cea4f6db87be0b4754f626c49380cefa771334670c03a729477b8fcdd4bab8cbe065d0e183ee2cd379d243040e49ecaa22e36319ce6f9166e95d9ab51a75af78281cd6abf3b103e0f650572ae99147fd8b13e845afd77d927306cb3d814dee5bf7968498886b93568e624dfc494e607437d5f9d0dd27eea25c0517659eaa42ef0c3720a96119abaeaeae3e89a867789d1767967cad91e721205c86e320de55c72f3ff6580382bf80ff22fc696f5b77a87ca0f4ba7d5bb4e4175af10ef2b584d13123c3f9435964d79175070e8582de4734a802303c48dd28728a1ace5b1607fa27a86b7ccfe4abe08056ac5c23cfe0ff771630bc0d186159b58e7e28259655f2c89c5cae65800f4af81ed96394bf479ea48fdb6\n\nInput: 09db368902f22864867fea5747c106a94a1c7d925c0f6e7bb28145631a44721eff1fdb083cbff4a5c0743eb770307c7d71ce9a07c354a392b86ef7cc9bb2bea3c2540eea28bd81c95d9688e775ad0beb75ce94af73cb7864cecc440250e70708e76594f6d288883b509447d0e07233ad7f92c3f3f7ef82b5b2f33d8a5ad2bdc4c88dd236f445c0042b3580db00d18e8bea780a3459180081a2b1bf4649bb5d324dc4bdcfd06152e110d18db1b032b1c9c32fd39d87ac0313bb44f726e15caa2284817c97d79a7f3df4e00c5c1d2fda1cee\nSHA3-256: b2a43faa19667dd60ba88c20c2b48427c2ac0be5e5f301fb626545ba2afc2ec3\nSHA3-512: 5fb4b8c0153c49a15909ffc47588bcdb4ce085beb1e12c543725cc07976b36f4479608a80ee9dac9800d1f603200b44cc3ad2883792450170b223cfdb030539c\nSHAKE-128: d4e830197699a840469fab0c7900b63e95977ff9d421f9da1a18b12bfe60556108ddb034e9bb6bb1fef35f4d2aa1ba71588fab8b427c661b632506c3a04879bdf33e826056d2513a40138d3993a92764d8b4c3650a9d1c2c3c4496a0c0496871d237ac46c2eb5f08c580026c6d4753232fd89278acc924027573140e61e65493de13427c06805652cfb05ac77594d860ff44ba258952d0b3e08470abf2402869378c19012e32261580e2241be21b5fdc0d5cd050daec32810bf7d85964f8678955f884506d17958071201679113dac879a31313e1a3a544785b1038f0f6f4f32b9201d71f5a6064ea42cd3897c1a1079ccea8caec84070f37fd022a1a765382", + "4d1f0bc34fe3e6408572eec91ef48d3e661bfc231e185164be55310b651e196424a241c3943e610bea691752b2f661c1c538b9f4d763adbb3e3945578f2aee085677c2aa45a59b1383a8a72248fe2f0b25a5aa0a93636447de562af1f5f0285906a3fc801a1fb4abca14a8cf43a108bb22917b7c384c64b385f69df5502ba91107ec6fe61084c5818a97136096dd8d221cac4539fa1501d88c5abb8607bf480e5b785e7ee21f7da3d85c71211e69580abcdf8f7402830a20c408f8f90fedb9771a56dfacc4704eb35ef8a37786b3470832b9635dc778c0e3ddab16422d7e362dc555b9d2460d3b62a5a460d40fdbebd571ddf67f8e0a4b184c016f0e78f71c0fb\nSHAKE-256: ece3a63bfbcb413d1f1f6ee7b4360260cc12b66d0be70fe58865c6477d49ba9dd8d4b8cfabd9a970af41362aea07e22ac39d9822d493d2b72fac966f5eb7092e82daa9ac68b738ac8cb6b3517a1ee6969f93dd235a0b31fd63154f4c5d394b6a8d89f5a0c5d1baa81a458d340abe829b4b18ff84344ceca0ee22e02fec2ab19cb1f5b6875997c362473f32cfccaf8a5876e99ea30f557128dab24978ec8ea605a0c99f261bc0b6e870cf7c98ad135fd67c0debebfe0f7958062334aae3beef348df51bad6c1b41db9e895ed41c26035993f46bcce82e1ae64e7f79807adf53d4441cba657e0fc0f39ce33094d0e35b81001ab40c431d7674f8abb3d22b2c747ca0587b55970a0bb1786d71bdeaf39c220c430b4c86db31a9c740fa7da712269a700a8560b030f884bc60891a911048fc6b73a4f7fcb2e43d592fa7dbd5b7a2e4ae76aea7d430bbed8fd787bc82f5ceee452dd86dcfa97b05105dd16ee306875ff5e522396c14360aa76453beb66aa63241e697dc115e7655c4b0f7c790e5875bc8130c12e0051f0d7f55b477e127bef95b41070137d76107aac05d9e0bfb0fe2d3c5c6eb9a80d19d143a260f21266bc608a23bacbf1d198eea6de89b10488c178111f80b6b276ccb4d6922570e7b320f97b7d48c4d7273aafa07716e0792c5ed1da6574aa047fedf43ff03fe4e52ad535c33c6dc15910c7c9d55b1a2a43f7f8e\n\nInput: 93d6a4c02ac1b643e634aaefbc6987e7e9f79ae924acbf8cf095904b5178ca060b27a23b12b3c6d3a49faf8abe4fbfa6d56cba95d9e67475edf7afa89dc4f0ac00201739b281ccee5d4d5981949eda4d107d71b44b141e9edf3f8f83049debcaf2053f37a01a10e90f30ba3d87b8ab8e16a507d44e36825fc8f3495bd541f76f6156fc649a365e9a5effe8eedfc8deba18f2883611e2d0570dcb230de857582fdf128c77d0efcf821fba537cf257ef340e529cb4a8bed0a77137ca77b4f2526ebc12f0cb6776963a18a435891c9d9f060c0f\nSHA3-256: 492bc6e0939e66e0e5d0d2f80adef3fd304928bd85b7eca3119fafaae6377c46\nSHA3-512: 9d4683b3ccdbae21d017feb6c91aa456b6c11b538bb910dbf5f9a79d5f2fbd5dd0c078b39e33c93116bccd7ac2dd78be028a5cf71115d896be3d5deeccfb5f69\nSHAKE-128: a635dc8c8e048e477d9cc0cf7aca2ec5304915a81623f665b68735985be6f30d358e2eccbe9f905014b4db0bf350bdb19bf2ea20c3d530dfe9c6d77b0f383fdb208a02d23857c89fa6d20e2fb7a71bf21a5fc476f6a201edf48fa16aff8f6279563eb3bed87fd0404252bdaf8a2318aada49a9ecd7ce96233e6962706a9ad2a44f3678ce73d76648c9739e2fc26d1fc06b98a79239072bea5470e4c9b8837323c4c02c7b940407ef384ec155d13c726c5289221cb6a2bdaaac574125906a0729d0c62efa92f5265777e5b030131d9a681134af97e645de33ec89b1c6fc07b6827bb6b5b02f7c525eb15d9be220a17bc4da9d82c1ad8982b0ba08d80cdfdf3a710622584d74e30ad5599ee79eba4758700046dd55ee8ab9a3f8e35122bbcc0238d213ce527f13b12c948c1d13065ad88df31a27f8cc8bf593c4525a3f77f216f27b511cf999b0f343907c74c774514a0b36a3b95e4ab651ed53acb8fafb89b74494520ceaddef9eb62e4de7424e0d6ca949e91b70ea7983448ce335887307f78f6bcd19b966f460b5b281840e4809fba896c757248ab58f639d6bcbfcf530a40596e1ca424896beadf4ebba639d14737e3d5ad166d86b4f8fd501ed0a313ea71562691b0abb66e2f573e8cf699ecf44b9418c4d9a5d07ec09ab65092116e9a4e0c638351c708704661799429b0861c6c86e47e5e2bc97435230186b91727f9f5e\nSHAKE-256: 029310a46583a192e2690cbb46944b555b52a2a392ed7d407ed44fc3412deebcb912db3caad2c84066ae6764f55634035383bde90c010d1ce2b8340ac66931fbb9c68910b1532f30aebd1a08b7d3edab0940f35b1eec6e24fbffc50cfc6f874814952f0c95c9f8ceaa5e36e9740f88dbfdacf6d0aebdce6714957a65520eca9861a94cf87516cad310e060d1ba05aa56d95892d072cd636bf11f022552b185201c076e0cbc7443da18ebc9db8a74efb45e510638cb1febc214dd3a2e83012af8de900b7f2035c3f16b980589389e624f811e227c2aebca9222008270ad36302da27d19de0856cfda823b645c1b568becf1c222e5585015f6fbd74b593aabc523f9b3a63256f9241f16e4f1e7c88360ed4d898e18a4feefa0d4c88204856722cc36b3f24025435d9223ee1256101c64ac2c03b30529e1144be8c495a6c41ae5ea43ce9da9c152562607d00260408a20bfbb9c1c625119fbca843a02b58d7c4622973d2c4e352410d628eaa9547fe33a0552deb928612485f14e7d77af9085086e91cfa4c3eb4f4364f29fbd2ec53fa5c78a152b0148e17620f4b9500ea50c0c22f79cdc624a1e03c4ce19616519b83d90ef57b43498d0225bdde5077c6bf021019c62db3f7085603ffc2b9aac61a2243c8c71a7a5358c97f2dfa1997cf3000542bf3df140919d77662dbb3f410879c6b85fd9759fa1a6ffc0214ff841b7a9534c\n\nInput: cbe425b719fcaa750b36e13732b9bda0897ea1bd0203c5618571cf4bc63246099d70153bc5a733e49dc25b99c895066533c5899a2a2298e734e781a20ee672fab24deee3f4e569dfe19739debce3ee4c6b2c4f67a4c93a1b7c7d679c341c3c454cb77584e46769e616ad723e3b1a4b84fc4b429901b564c80b1562d523740787a06d91909bbe57d91720f9b3c62d56e045bd5f7b4ebcd871c5c7c9c1efd0e97764ec4224fcb1d99a553fd433862e579891e2436138d308af4759dc4848e6a13cf8f7df271dd3b41676ce186f7bf69c05ba5885\nSHA3-256: cd7878c09d4728b60595f65fe496395a14073a9ac7e0f9235652be99be010efc\nSHA3-512: f356f3811f5c05fc964243267b616103b2caa8d51096b76a21a8c7e5f30144102d84b21220df058e7794877c5e5de41e3816fe6d4b46b068bb45549918fe362b\nSHAKE-128: da0c9497bb24e6468389e6b9a7d9f99b930f0f3527f4b2a406b17cc842cdde0e66e8c54d3d3afcdea7e8da8b31e844dc088f60ea368ba228bfc78e82aa4a704275a1790f264e205e7cd0cb8fa0523db312d4a8e78e43420e7a231c976c71ebc4924d4789db991e8f48f8ee25b7a9fd55baedae8c71bc86174cd130bde53552dbd75549f060a2cebff89dcba11a4d82826c70fd014d5e06a3f1bce0fd83f3717641d9fe2f356d38b543ca53bdb3ace94cac764bcfaa81d61a69c4ef52e89ed4cb3510f642261bb847f6a1c49316ed6b97f9dd85421af39eec5b12e4244fcbbb7e705383e3976ff969b6235d24a8c8f7aeb82fbc2dc9713ec06d2cf3b8ce238460d890273c3e3e2d9f45e78a30aa5e388bc6bb79989aedcb48699d7f9bdc542b3f4c3b93320eecb5f14691ea1a5463d298d5b428e9cc37bca32f0d02292823a48528a8fea188ba859c60116710dc8f0d646c1c12207d6ffe302ba012b8f9667c336edcdb7f38bc8979ae7b8fcf5da023ea408f5cb162c9b5b2db9db81372a2d09d6204624833f5333e5b9f5d72d6d861f0daafb9c71fb5991fd1eeece9c52a2af1ae924ac0416e09d79b0226bf7f21a391f7256680b1317e279273f97cf9da8676e2db95ac6b03596a1b1be0187f6d37b00e4735302840df45d7a6df5795c9bce5851b6b39018f7623938eb147b7ab802b8fa78684508b9ef99fc38cbc38905d60\nSHAKE-256: e20f5898dc17b81629a66bce66e5ab9411c3818a7dd8320bc621bbda40be68579e2dd56d7fb69c7a8de445f31d93a17e83842c3ac4a7ed96950e8273ffdf19d4307be2daf1a9f5e50b91219ab74a4e98a69ba151b83f4c79218bad035a23fec3070e8c1f61b464bbc85028e35d893983ab24789aed54a37b20ac1b966316f6890b497bae7f1b752da7f1da68fcdd82cbf84ea8ef6cf95a36cb627d1d5c3e18380117df8fb880879ebac2326d1c2af593ed6fbc1fbd453eab0e4627c20c2f050df3a67610a4c16b4f2e98666357154a58a28e6d4b648c160a0daf293a7af693dbf941a51b2d8f907c5fbb3078abd17ba81dbf671b7e7ef48a28d43718e54c382e895bd51b8fb8325e43d97342b7bde1ec691db4b2b7d9fc78c8f6d3b29470d3ec1ef66552b252f4d4eebf9ff6774cadcbfc2d59321d3eaaec31e4be764856e2fae0983ee262c7bc00791d69fa278c038b32fe52b34b1550bc300ddc3992b0ee92b53c467a4e6cf6fe2e07feba9037881c208e7adf83e4987623fbd645208ab78606a714b71024b305a9af08be91f639eb7da807f98861eeb497f26ecc7e0f151efb6e6a6aca2da7bb86bb833aafeb902f9e33b04c92cd4811fc0a6589a1502771809932f1bb7130f1198b6c322290c1338a54e70941c7c902e457e81d74c19b4c67b1e211f72178d8636f8021c1abd6e7f8ecfbfd79c7cdbbbcc1fee153128e17\n\nInput: 22a566913439a1cc544ac6214a73aa37a764838aed132b00dbcb9070c4392f6e0d2a2772cf26068a7de54c0a2f01ec72a931fe6483d0c887166f8c6d7f6a2d41dec5f6c89fe6aa1e5f46b88e5ce6fd922d1b3fd6e383a1ad1d0bbecad10f923610488e197f59c6517f15003f0d689e9676b32643234ff87af5e676ca87c2075f60d071c336414b9ac429a5781bf75187c56e7405e4417a6b9e0a9dbfd01074cf48972037d41a217c3c3cf78108f08f7d102f82d10e8c9d051a48736e734ff4ee9034f4e69c9d852ec38723c17a9672416247dea7\nSHA3-256: 50e91f74ed444610d26f624eeedef897825b335900baa5e0a1fcf604fdb5e954\nSHA3-512: c0e1a3224dd81e1f4c62244da4916316fab96d8c90ac8e23aa4cc6660e399eb86e167e7a6dca99157453a285f6bfab5ba6d0d252ff4e1886390179838a63d33d\nSHAKE-128: 5b711a629dd16bff3d3a19d5daa7621b175e773a6f7fec44fd0684855077064eb99de18cd73d83e486d49e6bea23666a708fe9e769fba7f03cefa84b9a0999ee8dd1b7c28f3494ea01366d904e7536797e8cb43e63a8bb9c3cd417fb3a74106b8a71632b4a3cd0096aaa22dadad462fdca816c89b23be70bce3057269c718b4b8ca88b3d794cb27bdda62aa41093c2d6ae217998144213bf3be91e1aae8e2ce39823a52313230221a415c2e9373961cecf36b62cbb262b5dd0bf009f80894213c1223fdce3cd4bff87527193cbb7f8fb4f90203dba54b29668f54272d1df2e335d58bee3db916ff7100601f3267689e9cfa65055483cd185e8ab41c01d7a4009d46d6aa43583755f8069f9f41e1399761652051d", + "5aa7a1013730cf78c5a380135f431037727c47bc29e85528b7ac969949d7f437524cfe5cef13b2a33cea10118580895cac032376b7214b02fd34634c2ab8f81e9cc80c04d01f64c4100392f6bdaf9d14609a40a7f7da444bf24c25089c46f227d6fe800223db819d2dc0f156e88f7f98fc7ded88d824975739018800a45f1a0083f5a48e60402b1f1d8e8878e9671abfcba1f286e4c680c4451ba650e2962fec3a9c0178053925eca3d10e7369236f69ae1b8cf7ae5fc2ed37723cedc0a44168617aa14e7064805df76e5231c923448aeffc80d1031d118c5eff8b9cf8d2a0a7f46db2fee07a3387aa55f5b6\nSHAKE-256: d97ab52c8790b430f6e0636b3c4a20c89cb865f972f015456ed8c6b1a1626f0486d5bf39a8681e661662afb242caa05d798529e99f5414bb1914f1966d9c8d5a53a2e623f752b57651233e02404c80ff477ccd29a1e79797336438508025e41e73cf684994f062d72710f5e60728717e93361940cebcec21e2fa87b54691c1d0849cf4e80763edc2d41a7e43870e20906f7578e7b72e13d5dfd853c75e832d1d78f818ee1626b167cce0edd057766c4429b56b510760b29bc707318ffc41b5ffa830f6349a1dcce35a99da4aa78ca50d22d27bc837f8f729cd2445bec48811b83da5d39959849dfd04ee3f26e87304ce52683792b7830b4cef1be6e87cfc05f9ebfd452ad31a235c287f6c45afc4e697186e743c5c9a8bc29581e8eea24728e72edc7fecbcc31b48baaa0f9d2262d45a68f0657d3afb40c1fee3f5f433c46e8068faf1e4be26539231415e272b94c7d8f5eac9cf7e6520dca93c79e3eec03b42193d8f7d185482e640c076232a9089e392db2993bf0a6bfa8c206662824f36a0481ba9c4f50d49b27b3c407c53a44d7f9df989b301edf70ec7b35017d65abf1a0c1c82cab5f6ae4c84b39754b0e703abbb84f0958caecb71a77164998c85f9be100b5be13e0c46d71b855bc64b0fe2a4f6558183a3da984d027ede651b066bf577e361f60974fd3aeb5ce9441fb2f76881614b932712eec9bab2ab43eb485337\n\nInput: a81d8d736d05998869b433919635086d12b932d426881ce5322ae82f1666778f0e02c0c66e97b82cd97a280ecc4d0a8a6558db94f95032273bdac795b0a11e96533e86539d9fa27e1651a2ffbd5aae385f51d5729e04f36ff42e34e8ce955c8252df2b1b118f04d7db6183e099db0f036d124c35ede217821c4c81c0ae88b5ecbf8cbbf9cb615b6dd0e3aad6851c91fda893249d84be9dcde847ba9f70262235304b0b45828376cc070d8ff20615388cf87c254e4e663efa6fb26a2cfe691a08f4cb253caf8f39ce2054e6de6cf81729be8f3a5b96\nSHA3-256: 533538ead5ef0ed276c3b81d1a87da46b5db06406e21f18047a241baf785f4c0\nSHA3-512: f64ab8734afa332b8fc58db60c55cfd27ed07b658207424338211a1bd35d593dbe22e468b72c7c032efd1e20e96515a27645cdf358c608f1e687cf2cb8c6ba32\nSHAKE-128: 8acea12ca3575333a36780322c30350192841766986b76be4403a47a49859c2ef35dc9f634573a27f58407f3e9e8f2a356b9f61d7409415d412593283f71e10507d0c0841a2ce0a451b5b1b5efdad6365a38f214c97f6a307b068f7754bfb81796492d89b39aa8240a88a510fada2147f890c795a536831e308885a94483cd39b3283487661492d4d0600685eeb02b2a294a8f9fa528a4e7b46accb59ed0bbf43d2942ad7902ea77528f1f32d0ab9fb55cab71e6d1ff6d4d09b192b6e22a95c192a52e27800df3e7c19a37bb86e66dc44ff73b1cb92f4d7ceea2da6c0f06d9a53cb1335217a2c7a5677869d1237151af7bb62465620d3e2fbbeb0562620fa1f319f1e2a148edb62e68fe24fcd4dcd5615ef3a03bd2f0ef288af0a04d73b00965af172c252e2853901368bdc964130ebb57b35324026a0b7eaf9775d55217c8928888cec8d4023d4bd9af8ce7a220ccbc7e19389acc4a788884ddb506f5a1f6ae9a217873d32e0db61f05e97481f44ceaf085d6a6b8464de87af7c9505cb836e4934387aacc0fbbb89c10b793d805a61c8d70e2f9cb42682557b9871c5dd83eec669e5093d3ca02b626739d514d9c4806ca760fb11fcc7860c860386578620df563b5831a62952164326c2cf0293b46c90d005297e67ac0d3bd2e08ff1f91b0fceb3ca278522548492cd0c4f241fcd7c53ed74f7f4a32f97522f517ef292002f0\nSHAKE-256: 14a7f241068c58a3ed8596696529160a745faec6da26524ea647182c4fb6502c95e3a8bf01f9bbd9dbedc93e7a0c451b1d3d538c70e782da43772f0f9ddbeae416bdc5947bb243168af5ebf5d58b7e1fb45013740b90ddb2f26a190ae53f8666e979098ff85a98b9dc5526de63324713e4959b863d028becaad9e8dc8071bf1d80480d303248772d517095c749850ad32e3c96321628c064781fc94bf213795a678bc479ffe1970160d11c2af509b556c1692b185168744fe44db8af6d880ca5ae6c4554904258b039e1d0887870b3bcb37e998c8221860d1d63f7b6a47004b789add08814f5e491dff693958e66598fff1f557d55c8c3c89263acc0aeeb42c2ecfbe7654e083a7964472e4bc66cb17aeeb7c4872d1e6acdcaa7841f2f701fe31ce6f255747633e9b78632a83752fba7da9c90ca095e628cd81d903b78c1cc2a279868de62fb95c4834c8181c2367fb0659d8819f3c4ff105890db0486dd319e8f86cda288d8510782de1ab736a0f5ffdd4c79c85a7294153557c8027682ac5a61c6a42a503ee2ffe66b5f5b213ae846735b0e97ca3a3623bb03f4b1c2e99419aee280cf1c29df2003231bac5a76edb03dc4086b6c1e75403abee7900908be371d23a38121079a3abac1d7084b4ca955507980cd64e748253fbe6a7f00db600b5ec5076031ca9634afdfb85dc10f18e4f3f4e071509ae94c92a02bcc00772ae7\n\nInput: 0235e74095c1f7afdbda35e82495ef58468d8a96ebf121fca9c131d307b937bee22b7d8d78fca6f6e6a099b7ecee7ae95a7bec727671583b4a564b95764eb132656fcc7f552f2b97581c15308b46ef706691ad6af5ae3e04a38dd7934c2032c4e18228207e15659c7bcc9d72ab5500e369da631d4ff70b50d5869ad82dfdc6820d9928b65fd2a980ffd9d07cdc3ecf27231a3f17260a21cadd8b5d2f436a6c7ed4ff4b298ee33071f0f11317a2ee5198e78ee0644d2e7515074c278a6ea62d203bea97fd3415c5f28650775fa04b35b1bb5d893c4589\nSHA3-256: 3195f01c24e02c4fdc230de122a0814a805c1e18a0b6d03408c8288f1fb25055\nSHA3-512: 49ea7e1fe6523de95362126020148597179842a22726b60c17c19b95b1860728699ea8d8995cc47dfbed9b616b23f852eb6a4e5370416c30e3cac5bf22f751e0\nSHAKE-128: 6d0825fa739da0a8e0c106a5def62f5562e5a85b21afe097122447c2afe48127be19fb55bd08119cd82e2b23a1e90c3e12588da357883e92b46ad9c5c87639c9b8ab03bcd61a097841599cd05416071f5d44267d3b5f279827556948bdab80c7942bf500ba4f221931a78fbed0ff0a422d35201c0b55f2625e7efb535803a9c0b93ef1d9e08ce75787f4ad3952b1f10a53802e0583924c244114e8f34531dc47777a723eda12f9b757b8c4f937bd249e48f42448d49bd95370d4b4ec9a2fcba1f2a010c686de43061d12027782fa217c9dfc4ec1017ea387ad818f6e836a855ac6d7407790a3907c80367e5eaddf9b6ae2de7ff55b7f81a394f1b027852acbac9bca617de8ae7100816b674b79e4894b1ead0323a017d50623beb6105ff2b7cfaa802c3ac0b060cacc1a6c0616d1cab67b2c9a62100301f6d5a41f45bed437ebb9b6705884848bd85d058472f5b2bba61efd3e224194bbdd67bf372d06af12837de5713782ced8e81301ad8fcd5adb466f3fe5c8c6049dd0a963c8d62c08e7b367f495cb0e4a0bbb0391a7650b765e5bc5ffc28be436a8b17f1f26293860230ec3d727f7ada2f626eeded96c2c596436c69d53a8d79c4fbd406c3d68c0bb7cd9c7bc603464fe6389e9e334c99a4b4617d206a2c86855f536f18db4abb28b190e8035a660ade9060e521721966df35560227509bc0fc11359f1f417bc1a68fb29\nSHAKE-256: 994daba1eeebf4a1e4ec15c3a24d7cade2adccf9c9c0ad68387499086124ba52fe9693ad367916cb7fb26c6708c820886c3a2a7cecfb6dadec3cd91910f32fea86728e79138542a33745bf409599a67fa70ac08e522f2332da986f4dffa7b3ff18137c81c32cf8f99647df868ead4e155fd2e8cef91841f22a95a57c646029e5608a35a74998c17c6eb83d2940bc72562682e0316327dd78fae9e637d95349025305eab4622dcaa410368cef15cb0de9d4778d9eab32f41c4be276a37f20ebbffabb88eda81cd5f037a2cfc68d7e4bcbaea8c8776491cbcc43c1e4779dd775ae5f006badf99a3ac546d86450b7d6c86ad7861f8b041c1ebb3360d1a083c690a36c83bbff012426aa5caa5c9096e20ff934c20c8dfcf89266aaf15332dff625b4f80ee76617d36ebd52df22f1d5e764f603dab45a980dbe6ce05ee08a73fb75aacc24a9173d67a0c63fe4c4870211073cda5b88313c998a286804a286884f5d9135e6111756256a5a71c450f9718643487a286650c1311256c2ecdf313ba0f8938f71a7a003c806e9ad56c6a82285571ba7170745dfe328e5bb9244fa797c8bf1dacff678648311b1c6145976616890d121e7e624a3312865e554b4524b09b5afb6bcf1c9b2ef84b21a6ffbacd89d148bcf2ccc10a7af51edc9d56f4b8d3543365f5cac39883e18d76401422427612d3162e72e6b4f19b5c71fa68e0c3347975c\n\nInput: 609548bf5732c9ee6c9c4176dd5b5fe771626a67a2458ab99cad4e922e6206b87dec5273428a96f1742bd10b3394175a553fa505e8671e0b5f0a2a892b63f85ffd58c63e757fd70076ad7fd19195645d7aab288277f9550e91531dbb0847dd33f6c449568e799cee21c4c828d33d4ae9f5c32bb5e6c47474c4a10c49909ddf54ef5a5be86235006bbd6b696078e09aabff60fdd64a8a7d945f7359551f4c061669bccd789761658d957ae657d3ac87f45f6457c24fac2e314a48072d80e3990c8d756f5a89604178843c904f53cf8724fc5bd80448653d\nSHA3-256: 966182c2624dd280816d4b003e440c6a23ed205346df56732ad58f6cc68c6220\nSHA3-512: f6782fee83e1edbd129ef5a949e0f5e550268d63512c3e3f3117324bf9c53aef76c7e2f63a12c3f93223c2ea62cdb428e3e12bb65e5315840f3c761665d78cd5\nSHAKE-128: aa55dbcd0251ebe3061a183c450e0e4158863a77264ca64b0975994cfa3c8836d6102a3262fa1411f0bed71c84bec486bfc017d7497c0cc0d19f439a278f7e947936acde2c73c33ca630eeaac2e789f8b6a0ab83b676370430ed9b5fde9e165b37ab997214b42ce01523a2ce4fe03a4e7f17bdc01d29d5e48dc1d6191d40a25ec1cb0bb2d61b127a939aa855e92951251087f0da9e2dea8c719465186e97118f51ad393ac98427c6f2b39478dc89772e44c11c9f1e14baea90923ce267a606eb354987c90d46b5706c6881245dad1ed81f26be755cbf582fb88bb4818cb026f07bf54a3b9c472fe4605b3be1af110e9b8160e73006415f5d39dc7ddd211174e8c7c9a42ba260379d727b3a8b0c2cb5556ae23440002c07bfbc473b6e2e643e8", + "9d7b780144cbd4afadac509169658f4d5b5b48e6278d9b85a5bb3a0f5fd239a0542a384966046646f2b18f1c8d3d4459e6821eaaa456df0215394c8c476ffec183aea0a0a9c8f82e488855b01d9474ff2c3ec118a681da31c35954fed11c91080bfbcd159905d808bb65ff118c97fa1c3052c1641c5b526bfd5615e3c96aa6d169031a34f63401e443c0f7eb392fe1bb7203b7710b33dfca3646a195d74438c4a0ec2118f45cdd82081282d7a7b78d0c0d1d71aa682fcafb90b3a8bf1963fd255ceeb2b291a0e2b5d025a5323db27df963a973da3d30ffffb594d68f88090ba16\nSHAKE-256: 7b2181bae5266455d7d76b1d83dcf5e570787713cdb77121e6b5bedab1c45a30910c598aea76d1043b46518cc8f1916bf8f73e83e1fb4fee3979a5cb9f36bf1b6000e241e0aea1fe42ee6ad41afdbeb8faecb60fe748f61a33fb2581bca7aba15e9baf3316b309684b8bb314ea1e0055cb39ef5adb88baf4405bd4835bc99cd7f22785c2d279edfd10b92961b27b035c21dd9f0099225a126ffaa051d8c6e9cc4a6d813e8329053eecb9a7290fefc1e9b0905fb6e134fa0d3f4a5cd23a08eccce3dbca55f17b044091fe10e17a4bcad76d27415846e5212aaeede1a150c3f7ef31ba2f07c17585280fee8671903e97a2fc8eef29200bafac3916ed4074c48f15afef6830f8286438371ae7723985733e02bbc285c724cdf349bd104700102af17004ea15ddd5310d1519471690f654168480176d6db31e6d3f41838ffcbf5be1ec916fe9cb4e01dc8332883d50acbb0e01d4cc3bed03fe34405da6d085faa069ce82019f7eea68371272c33d6fa9386aaf86386b9a2daf23feba59d5aa3b1cec5c8f0176590108c58ce34a3ba8bfdd92d03c05bf3cd0c7130a37f16f033e8cf945d9d4c59ee27d7652d5a404cbaf19701d59245120772c7d314b9ad7a21b5200dd627cec95951cd5100579eb1ede03ab2e81b54cbe77847086ab645d1a825a2b3d0f06e84abf82c559dddfd646c433e880c6066a0c884a148f15fe6cf70a7d77\n\nInput: 41d99f01e7d7e6f3694d07b0cabb3ca98b5cdb4e59d515e7dc9e1e1488dfa1786211b5fc3f6e63687a7de307caa0c34363ba9a57bc013f191f22536ae08cf2b3a10fb20fc338f4642c71dd1f8d146ef9565fcc2ad04e77c8c0ab1db65b5fb5a0f4cdd619cbea99d0f8a7daad6ea76cfb586db7fbc93b266d5409df496097b0a539d044a280beda20abcfada4eebe6905ddad66ba023e8e88cd5aa8e1c77700bdb2a28b06bccb28f10a2f87b0a65f8b1ae9cfc47068f08917d893d7e10af77f9e3f671cb44122d69ddd0709deaeff359be83d1c20b4779eb8\nSHA3-256: 9c38de43851c9792a9cb56665e078848e6f5cacc246f8a021474331cc8ae2a3e\nSHA3-512: 0e68ddd8f8530c79444daaeb859efaf72eef56f0a34f399f6a0a43cf63a9f205d8e3157699c5ea1c95044478f9463fedecbe78e4242b6ade685991dc6b3c73b2\nSHAKE-128: 6f9f09f01222ee6960536416ea6f10b7148c2648d81d0e70d59c8645a619d817462bd6adfc277d4963a1d81bbea2a198ba7d19c109171724d302f7e02e93455fb4ae9be4e792a83038307884e83ababff795988eaf787ed00832eab0079b86efd04b47c597d17a56622945870431205f414ce4314eeca3671cc8906ff1186abcbb8c667ef60ffe5c4a9e652fa4ca68a066f3b6ddea7146a1769aa161cb5cd1fb70ef2592d6644eccb317eecfa4dcda0143b6d80d75a975314916cd2535c3ba60941ad6a657cfff6ef8f8b056cdf02cbe01129ab2c374a9ba4345d6df444d484cc68408afb329e4b0924bc5847e2ba1d62d46cb624276023deb151dd38c67f95b907199c8263ff1911d5402ef4d71e548b59501fac54e86666035ea010cc7afc950433e4950d657384e7dced343f586c8f0b072dfaa6189215faabc29f6bfdc7e2fa64022e5ed2f3228bc585e9e0fbe11340d7723a048c49de57df6f2dd7be350850a1ccabe23ba7cae77ae3e6db782efaab1b6795cac09e88114cb36c6efb1e57d9e30fd350e4cbe7ac8ceb3ac109aa833caf1213e5085dc7d946f0cbbeeeab441821e97b611ae70cec4b09fc2584ae558fe55648606115e01ec1a313026b0237748bec0bfbb85ed4aeb38be3a2e2b56d57246df7203ac406ed653ebf61ae121fd7fdbaf959ba77bcb2a9caf8985b5d9ae1bd02919e2a2a77a00d2154e8e96d8\nSHAKE-256: 62306405fb3ffd2ab01bf74d35175cdca8a61ba0566562c1c8e28883bbfd21385909d7a4d04081ce82d053bac643e638d155ab54866e34ac4c36623e9d9ef84829dcf36debcb99c9006b43a2d2915705393e8192d8fde4b8aa7666417f437ab5c8b9412f973ae0c1631df624f096fd5ed704ce97ce65378e43e6d1a6282df18972fa4d9369b1f1570e7dac02680179b708249e01784a75d9b5d2963ca40acae0372024f30dc52ba76c6064d295962315a1932c718a4bd07594c1a7478eef9398d152ad1969ed20cecd8a8ed92aeb8b751217430d13572ac89ea95cbb0e955bded246eadd33365941f0b3b726eff18d551cc79d905f02f2ce103ed874681f585e7a4a1cb267df38c613c76e9abbefa8d6db010680d53212ec3130950b5e66ff0008f7dba6ae211ccbc88c1ce135a34cc918afb838ce8d080c93407b3b94507c65a5c2f6dad1d78cd307dff49701f4e73969f0fb13ce07f2ff2138cd5b79c10a43c2303f52751d22b1215e8e721cf41e0765a37a6e4a910d293c269d832c2fe298cb3d7fd7dc24fa41677665192dc4e48d62236b1ed77ce75a31fbc19ce893ac450ceb097d74ed6fea7b565d6d045418ef613fc73980416afb3ae92eeeda07dbd97caa0a3ea6d4f123d434cad43b79b03b18facf5dcbf5e6ab6c833d1e09db6399beb71e76277d3b06b35f3fa10184cd114b4693bb9c9d17512eca1fea3933b00e\n\nInput: aac9d8468d782c1029c1646feddbe8f187cbb7e59b1405ac309180ea0cae539da6dc56041a4e13bcbdd1fd1b9aa116bd037cbe3160cc0bd45787299fe53045288c9009d9a8b6f3d9c4678f3ec6c5361437139e096106d28be25f8a9864f6008386dc19485719301c601479cb95d3e2f5ff85142554dedce436850cfeeaf835e75971c6a1218bdaf57dafedd431a14fc2ad80b360729fc40e9f8ab2a9b5e8c45956d9034d2e12ead756e0940a52fecf93e64717c2e4a1ce7e8246864fe78301b79acd02b5a7f73b458b80ecdbec8f03d6136d95773162c6b804\nSHA3-256: 7861c031072137ae2fc055f1c5572fcfffd909b447c9dd3caaae7123c42c1fcf\nSHA3-512: a40b37484717f4d51416185d420f7b2e91d40bb4b90b1afedc12b94bed535b51f5d6daf8335e31af1d7fedc3fa8d41a38b3e18c200df7d0baa81d604686b2687\nSHAKE-128: 03d55219b56cd5f7f7de66ea8d7d01dcedd48b55e92008996e0200c5e7995961a7e1b105b3c1b8233cbaefb715068e530de79f911910a0c013c4d26d56c9ff268681833fff4a9bec9758380441abeef49500c69e975e9b670b968dbfe26687bd5c4cf54437471484b9eff9ad5ed097a53d561be1df496b7b7a158f5d684643a3c88efac5574b48b8d232b7afc063e3dfc79047011d0dbb63250e2bf7d375bdf280a861bf45cf9e168e3becd856592581d4a44c1a7e9558e4f94dd9020b1028095cd6526fcfec07eaa718564d3fd3cf7e28d7aeee5649e79a613d50269fd3de041110955c6126fa9de595ad296cf3dfe376a04806797c6fa613dd9197099dc3380bb7d2e00277a3ff90f664ff18ced9fa58e5d7a179217a593a5e11be423a2c9a20a8a248282085eb8d0478815019eafd5f6d8480378db4b118b42aab24872214533ddd5fd70c0aa3c405c1a1814c9b648353f526c731f9cc3717271ac70027a080180316b10fa1dd63cd74d210c382b363cfb95c6e665d3372f46f1b11cd044e1918e3eff8c1b00f48ba8d5b623be6501b2642c4560e361a25ddcc215629bd9d9c47353ed9e326166a89b41bb107c2e5616d1a0bb42dba1f3dc4ec20db3394d257add7e28eab9c5366e4d1d4c8c29d2d8420fb9f15edf44ecb0e3f4f6c8f5418ed3dbc4a1cc9ecf319a0cc53db51186af313bc1e3fdc04cfc066677311680a2e\nSHAKE-256: 828e32cbc9ec44b90a1f69b962ab915067d0e7555bc93e3df136079905ef0a8aabfef471359b68e21bb31cba9e6de95f49da647162b45d6b3df3ae920d283a28ae922d3b1142578fcdcfbd7779fe76d89c13482793f1deb8dbc4f972ba4ddf70e34603645f4426df2c237db899b785d823394d40cc44fd581bf8a0526d21fd70c4b8624256c877598a0faa70c1ac6ae705e69987c4f76142ab17f87e3605d5b747d76474dc4cbaefad7ab9257c13f16446a69172252788588cb433e628a35d77d76e0ee3fd37895501666cbb5084ef76283f214922fb36e1994a3d64e8b2846a04366a90c476226dfbbeae51c3b548b53dbb69db42b1b98f08e49e899a21b4f74448f235cf60e71635f2a1ed2a65e328860b50e216c6b0c0c23961a83302b67ac539827d1bdac10bf3cb04e0363934f17c9b8a169282ddc37e4790639a3acca0a80d6041a78843cf172a261149c50781bf68c7506bb885bb5aa232426e6e318027d0e8e46046e2c4a00a7fb4d7c724faa42bb55f253b58e97d800c66091fffb7fd383a066337833093c0301985afcf238de7ed721b05fbefc3393ad2862cb30bc0de7b85424e6d8347d1be3134dd58f270b3da126f8075d8eaeaff767bf9932c4c27d3bc1acffa6b4e0a3a53fb5a78b8a419fd78a5a8a495aa34ea09a0bf0016de798c7afee7c1e1716155359813e94cb4ec41710bf7befe481f13466db293bd\n\nInput: c1deb23ed9ad14c11d26a61491bd2e36a887fb7125c84b4cb0a9f178b911d88ed8d1b375c96eb710d16038d3b950a4d22f465a00a001d9174b1cafd708abe6dee4e5a6d2cadd9e20db051f026aeca367e213471f9c6541a929aeed89737e8895faf17f5c922b5c13f8906422c17ea3be3859c70af54f5b97be733411891195c504030012dc62133b8e01d42871d4c12c5570635e4331a7be29fc52f46858e52b884fe48f1b1c642f5dfd2489d8a41c2501222c97890985b8adc392fea0a5841ca492ecd59c06f653570c48de37eb7530425cafb28fbc32f89e61\nSHA3-256: a679b7ab4e57b9c237ac40a2583340c2316ee359d6233438159f921c6737843e\nSHA3-512: 933c36017785179b2f83477c2407bd7026ce7f9342b823a7ca23efdb9d56c5bfe758b37b7a2f9940786b84e542fcb5c8ab07c3c29114797df63073a84e443e63\nSHAKE-128: c9fa3d355427be6cb07d8be10c99499c3c98f4333ad0023ddefdd1e7233f8fe72c9982cf54c8acaac966e24cb26a15943906e3dfa8939e367944fac0e4a4771c0b453054b1425b3fa5a33ef5a8ef10f2f358d6a55a6e3ef95c14c2618a79f7802f3b2c75605a1503ae71545934bb34a5640694b959db2ca8ab09233e2ad0e0adf740c34250df4b49ef0316cda03bb02ce2a55f09ba32459350ccebd08298a9700b1f6b8be5f653d6e1d9bdec26c07a9131b1f716e9f0441fd7ba4cbc65149fde64acce8dfc9a9680db50200d8173783f1a8782c7e9936a35ee0e9c1d0b78123225c3b18eb63ad1041bb6acf7d9efb9af396052981c686cb02f68dfef54badceaa8c23a4a26ce1c7b4f0fdf8a6551284f5d1e5e81640ebbaa1242619c5a7048bd9436", + "a1a92cb94cee5e907db506b078cf902f00bd7cae72e3f68803c1689ac96a0edafc8549649b3b2a3caa554953ac724eb7f67163d8b9315aba9b43ed78814b05f122ee1997fcc5a39cde4e2f4e5016e5c380313796f6cffde2dc362cbb26d9db40b04f09cabacc214f9c25351c5f05d0519a2a3f39eeedc621641d232918e5aab90825a362558f59af2b08c07df8432d7abb597588a43424c867b4025214136df26c03e9daa05970e5233acaecb8ae32bf300b356ebd834694b2c897a80144f2cc4ba9b3f1440ffab0c2ead1df8eb968f338b0c4cc007b44a589f6a794d082\nSHAKE-256: 4ed9ed12efbe6226c03961a3b9387d15ef35988a2d45eff78f10b4614a3cf7846b7cc992e3b262f0753ee61367bde2edf82429b1a05bf3effab11186715dfe6e48f3f630235fdd78e322425c9a022574315aef589bb780cc73193018201dbd8125447900f0b59c2de5b34c42a0ac133e390f21f3ebdd22857f9eb0224c83b7cf7a501322ba0a1bf0592497dac4fed59f1eea428c9ea66fa7d27b65724f90699912bdb59c9c9399bd3eeee1fdc490b9ead67bda5fa6980ea002efbe181f47c82a5c4e052132809d58cef049f7506de8a0a7c81878ba6f4becbda51f43693257595596df690a8a98971591f37864a8e8b3681efae642dde95fc136c5b265785df37b2bc06018ba445f54b698afb410aab251353f90df8d3c037fec0c0c7605eb0ee99b7b8a5df828f9f89977f1c0e96b0ec726de3e7e877ed4e3d56f4f67fa0b56acb499dd92df70cc5639f6c2de0f5dcd036b22ff758382eb9ffa3c3e8c26a0f5d47ab0608da5f59ee14382ad5d1bdb4243aef088129dfbe9c7ad274e063ca6d556d51bb3aa86fcb64cab8a2b198fcf259723105a9b6373f298248a2578f390e59870b871f794f6e6c9b14ea3b5369ac498c562cc00a71e8248751a1170b6e13d1a9a65f161e6e99d9b964815bd7466698eab2dec2db4a8415dcd9e9599ba7cb686b0068ffd4ae95fbe1ee89c7ffc08310c4ee04da7ce52723c781ea5e2405df1\n\nInput: 628bf044592032786b2c93abb2bd628f789f06095f8d863b9a140288e98b7a734f1ad312458eb6061d6a68c3bb7d02161c94161888c7d5650645cb365b63b7e46f658528dde878c769975406048748d09d767aa1cb65be4364f2653ed87b68908db11f3391392602089a2939f024c392cf7db8b2bb0e68472ba341ab4a26c64d6269e724211f167e59122d147f37d0015d598b00fcb5aa77634555eda050cff084b9d26c5acc41e1dd140ddfdc68376a162a861d29ba35001dc328f5a061d59a0413d62a0fea13a952738610f616ac3393d080d95a5aa95accba3b\nSHA3-256: e1fc64b830104377e8263ae597251311b255ee3b9ff42ed4ab9d0a7fb8b2d213\nSHA3-512: 94e673412bd29879e0d4b773bc59a7d9299400aee79d7550fe37a3b87bd23a6d6fb93b895cae469110532d5a8c57d97216d3482d4636d136bb5ab342b3402517\nSHAKE-128: 4bcc5d9461d393e726e684afbe1d7b38b67694ced3db48b442982dd8c84a903d1c5ae06b4f21a5cd0957feb8a3a6f519e22971b608e1319dfb42603352178fbae31e3e73bd2ec19672c2aef2633b6d7f300fa6cc30c3d6d727794fbeac14bbaf7d0c3ba8df5808f2a1a6b16c86d50d5739c6693bce44c21a5381b6c594c177e180c9945d5bedfe6350108aadb752f835a38d48d025c51648adde215fa4e5ac9e3f18fe97269534a2803fc2e7cf35b2201ba3d2d1318b6fe941bf98dc150d11d435574ba79337bf679f1c063c9f57d05c2832f9b5b3eee0246cb6dc6bf6ec257b1c29bb636d149d0aab208ec842c1ca287dfdaecc0338e4de524f70a1558e94476325ffcf0a31f610149cfd50da56b7b39b3097e961a1308f3be28f8a0e8167735d6623677e7847b6c696a4ee1e698a06a0a35a64d986d9669613b6a848fa7f3e38cd7b4bf13362412b5c2f47ff78fda644af41ae90c23017a328b4a4e70d16b439b811f7cf27e54d33b84674c95d10e91ffc474b7fc44fc7cb77e690f4cabfd0de1f84e47a3f9adf07d1c5c2237122be88fc0ceb7ff1d50c27a4aaf978822c6e9e1e35148af68bf5c59608d00a13e95f847e816d79b14c9b6a4079b91c55bb83f8a4850b334e561bef46a11caa690c354295206406595d1914edcc8d083d29052f65ed564aede4933ad3a9037211fc9b0e4c57ccc1285d2c7640ab326d9bbebc\nSHAKE-256: c0c8c55bd784873bc31502ac7e2f273479be35a07be01c8aa5ee724f18aa73f30c535ed0846f6bfa37412da13817b99461b614c0667e7ebeaee1231afda97ca02a01e563f57cfe8529cb765c4368218ca634bd2a16658366a845f851e4801d8d98bdcad550d550b8149bb6421fff709e15bc1fe9c66b056469d8d20453570c52ecefacc426183ce780ad5035917cdd188dd5952bf02e109b9f2405922043deb1fcea2c65cac1b9c6fff9f40a22960215ae96536dd64b9d7432a05452dc9242b2df5d51d355cc64d42549d82f465272a4868790c8bbaeeff120eeb6755efad86d4d9d18af1270e568471410370429be7810cdb094accc8ab7f7827f30cb9893948d30ca77f9262c4f808c662f4594e9d3f08ffaf04de673e2469b985421da59198abfea7a42f474f46bfeb0535eebc732cd0adbc69439969d5aea72179c425bd6f8ef1f87ced51f26d8141fd8a9ffdb2866a9430982fdf47501377aff7b4b4dc57017da84b27a90dec14a3ca07f943407addf8d2a7b1752b6c723f6cca355dec12cc7d3b894a2a64b3d5e7df75675abe78d5fdb4b6f49bafefe50272a4d82e780cd0742338837293b37d4491b3042a403a4595c4a452b101ef7cc4c99a1194e04a0207faffde2a701b169bd7190d8b5ffb599b76065997671f9fab50afe1bbe89bb432fdff403627869896684a2e99684b22213e362be0e3b8c56f9826b66f95f\n\nInput: 6fa131373bddcb6e92a473b561e7eb356222c32e95dbdcae284584693dd6a65fa73a9a7f15396cf1c80af39fe90d559f2cfe584c6d20fd706665dbbfd1f1afdc3ecc019b8e916929a7d3294910371c130a236696ddf7308bc159c7fc77ddd95c29f424c3d34c52e6cb179c8463db9c37eea4d52980abecfcfb88cdd36984dda323a6f161d842b400d43d7f310855307e18c800801ab25eed9e5020bc0a26145b1b46eebfd3042f39fa60d6a1ff7f252756bc1a32aa5008f7ec108c6ea13d7c02b09c6e56ba436140cad7cacbbf1e72498daec6063a9e808e2e5c5b72\nSHA3-256: fd2c3f9cdac7f91078a10d355476826d6bbf6d02a405d2352bd26606e44774cb\nSHA3-512: 7ed204ec21bdab22f614feb76d5dfe346db0f9d9e80c60c1c3ae389068a8a46458a89bb40cf6612bcdd5b4288f88ffb7f272e6340ba22fd77b2b20501b515047\nSHAKE-128: b95d0619405d42fe90685f69b72142597bcaf22ec65570e9aadffd04703948e080cc49d0174bfe41fa6f13f11a5119b7749f44bf888c22fc59c6b37346026707e291e425aa1679e99ae7961a4be4704bec2594693e4a7f61904ef63b71f64cb15b9e5bb60673d09bfbf1cece80c1719ea40fa4c53b392e5330477cdeef1018866525573d369d6a80482cd8715748aeadabd098bee76c078593e41bbd005d105de305da19988eb25dfccaf184d7a4bf64c746fabbc364f7b7311dd487e58b487bf65b6f71cb910d19e7fb39e65277fed62fc9b643e4acc407860f03d30984bbfba3fc6582c9764acc71ec085dd60afef98a26f3b197ca350a51f060d0fb41791d26b75d2abbb56e4f2a66cd52a17927567d96add00ad670188e37483f0a979186737c1d0ef2cee2d069263f4cda24e1ee854f72a04b6e4f143d38aca1ce59c15db9b685051018f8da6af676e575aba73b72fb8f003afed3914e94a909f777d14275917d93e379b935aa85e244bfd393603e97684de938a238cf313a10d2bf1a685f8e160e5b07965a3134b9d8edb45be0144e15935c298178c9ac99a454c7e15675166598fc92f748fd1b5628b78c272464a918d4b8457802613ca5bc5c625840b9c0d31402703ee690a54a108744227469485ab9077e67ad601273b927e49d3a3765a11b05151433d55b90952f60fe85ebc3316019cad8a26ade71c3e1343be0\nSHAKE-256: 1e9cc160c14608841adf8d1e4ac624d21d78d32a328afd902ab47f4de60d4e2e59ef9a02164a0c154cfc8a28c7f04dd2a9d64231b5e3d4cd9771188a713506baa5b19624a695d9961cb0933e3b47ebac81bfdcbeec31a11f1210b7013cf283e72630459dbd5fbd2aa8a6385fdffa5dad56b7465c6ce60d55f1c84580af7bde5572fea4427a845fe0901588455ef0aa25844deadcf97d7de3a3425cf13044fdc1a07336d0894780564afaa51e611736540a120cadc9da3773b6b42da3f7f41a320a34f87f8d3b64965744fbfeadd54e7e14721e6854a20162e73ad12dd822373451719986a9b00a91c937e3a4b43ce004e3d96e4fbcc33da504359969de5d77d248a8507190f4ff549fe8d226f05109e7f9b3bcdb566c7dcbda6d5d2a232fc10831cdd75c16360b08a4de3c2ea6d91423af8857807d6d157d6400a867705c5be7f81a0768be2cc23ee571d2d3471ff098e4947d52bcd3f5517373f90281119a64ef8a1237e171d1be6efce5ad4c3900ec3bd8692fadc2532fa19a3cb99e9abbad977972b4fcdc7936b123f46f3a85fa5b09c6317c22e75c1b9fe5543a6c07b3783d26bf405990548a79b5c69259e2e6ce04c8adccd55a03a0a31e0d8f8308ea8341c4aa85ea55ffe842ac70c8729c9d01aa9dcc821385369931ae2e60059e333a93c29a95028529f1c6bf029880448a75647075dd5c3376685ceb30e8f490cc04\n\nInput: b9e1022cb42a3684e1aec794f8a8f756a64c587f1316251cf1916f771cf8a362dad0375d2fa6e261c03fec8e9585957665833369f17366494aa73aa82d6f44edfe57b100279588c78d479e997b4a204f5a111cb1c2cd2c9279aa77c1032efe91331b1cd624e5f1e77d8e852ca17d75343abfe974025222b84ef6771b5bcd25570784aa92e4b3bf9016742d0bea2b0369fcfa8512deb4706a456bee23396de4b0df197c76e2f41a14ee60144571e6c2f934555337d7da5c766758d5c999b1ac28912d0832d85a5e8b440b76cb5c27400dc8b5a31e8b92625863f923c68b\nSHA3-256: efb0890babf7a400b83eb935027ffd1bd2df4eeb5baec091e9eb44ab51a9b8fc\nSHA3-512: edb5550e2b8b3b40d5aefce96584b96785ef1c28229083b71f54c976e476322500e226d785b9ab077e5093bc0b9d082415469ca1e38a820c2a5de174bd1186bd\nSHAKE-128: a22f4268a32b5b4b44c86ec91681783ebc1eb4804383dd4810f337a593679e4ecf08dcaada1241873933a317eebca8555452668d08354d574e4c08fe4649a114bb93b95dc1a6f2059eb2bdb128eb4edbb28e0abe9864123ecfb58a021b277245288b347c5c893e887f82ca586619014324dd48c9632344db7c1210bd1d727883c3f0ba6330ff35743bb57eb63e221c4679c8b420a7e02ef1d135fe6df87800450ecb4934157b8be0fcffda26b41b5305f7b6fea7649fd2b8b9bd23e7593f76f607c9d43d601904536191a86ff6a04897b07b2795b65dc5bf32e961bf63ad90956e10ae1a7637fbd65d6ae3ec96f76262111441dc03ae5f462390982a8a25366be832f17410af15b1fa0bd6a3c5a0979a197d0cc0d517ee4e2d41563", + "26476ce36925290595ce768ebec59a4fa663aaef28972485595dab6af269c101dc5a29c88334aa6df15ab98c1ebc29b4cbb8ae8b2129f9e104345224b8645956812e12cf311dd9aa20a7b3819c65a357f8c449954b38aef6530c5fa1412bbd7d96e9c48408b1e656a6019287cf915d306b9a08da3f809fcb2f418b4542590bf8c0faeec9a9b23f07ed46d6ada2193b25b2d962c2680f2e7ae4f0bfc22f6662a968e6e3246ac7a190e4a0c2d18ce86cf8d89ca492c319cc6b930c66001b46ef9592c95f28bc39db35c7ab3c1df4b0f35310c4b5402cea6a367644979001d98d271f3728923\nSHAKE-256: 5b0b619f4326d8ab07f2d3409eb2a60a9f64e4c9d0528ff62bcfe11d6ef1a10f10dec37310652fcb850d3810f14a4c935377f2a6f337dce0435a98fe2cfee2aac478857c122f4c00642775a4181e571b42bb5adb26c6e9ef3a47d8c022637aaee69dd1df7f38edcad32992a32f8c60f4b8857a834a6eb915f95c71e0a4f2059e7124e128108c4298abf7ca7e0c5e3e1dbe50f46909155e3459b6870c54963ab7cd05cc32cd7811058fe36d0d530e3a35613bc9e142d84c79aa3c9837fd71fbbb139a275596dd9ca11708e6af3bd585d1b7c4724c512cfb9fc27d1b7aae8536d2375ddf0878ccc567ec1dbec1cb45f714d11795e2f3ef7ba4849d3afbcc8db5080bdb0290a08ed432abe6f6f855f156b3fde73cbe5dab64ad6ba23675e3e1e1cd09ada4a9ff3791cba9f8c0e7d55ea04360ea2a6c16119f8aa3d174623e82cd3a3a252ef41439a1bf5007ed46d56fcc86ab79be4ffeff432e02075fead36a4ae122e82d99aae98740f63f2a1947123100340176fc7e95e27a18cd4a267cd36990d48c40e6286022d9ed15c4312788326b4d8178e2a3fd29c1653fdf3d682cd1c632e83628522f93e62fb0d9271a0fcf5ff3cf5f2ba2e77a7a0fec43cadf9759c507fe320b63f4d0e275b67729c9a44e2df3e8c772bd613f3f67673686b05c4507f4ed658bae79c3ffe0f6fcbe6ecee2e3dd18818bd9a2b478d900c55cc4d587a1\n\nInput: d2e7b64a739968d0ff4bc510384c1595cb05c116d395d6a33c5cfdb63e32309a3c1215903253e98c7750ab96dff0ff67ecdaa646d819f529741a5840cf3f9705b99c23c2675e4a9b8ab6ff203bbd0d728669b74a0a972604efc3a4749573a4e3817e0f1fab98b3f284a786f74bd3820108507e52869c91b13ec0ea35a78c1607c108333b5e361f83d62d6739952a42c69e8b13cecbf79058e2d2a0893c0c9b5b95c89befc4f3bda93fb384619641518d0a9a0959bbface9c812919f7d164f00c3c83f63a378e344739f85cb051e7585838a6efe702995488c9563fbd5db7\nSHA3-256: e6c1394d221492fd974a0d23ef338106fd00da3fbc5387fdc65aa65fcfac5ab3\nSHA3-512: de58b8b6b934fa8b0a0265152fd27ca21238881ec63df087cba563ac8004381e6914e10fbd9923809c4bd4774d81bf7210ea4f6a31b12882e2ec9209deb95494\nSHAKE-128: 5f0f4622976141b865d9e3ad87e183d9fe9b05e1273eaaed54ee0c0a67e0372eddb57f15222dbaaa6fef3874fd1d12add2996d6330a456bc7f5c2fa2b7f6978abf95e039e71511f9fe1796ec4b62c88b61126f14419109e3952af405ec201407b4419c0c22115ac446c408a4478f2aaccbedc57498079dd09ecd04d112ec281f325b9963432d81daf36a6d86b47c411fa6a36bda6c30775996d7cd088fbe2457762a97b0220d3e5c9ea17aeb98da74030d4e20aeb3fa0de06c817a76ee5b43bc1b0c148ef307bdc8de41bb7817c9441d995f7051810ff0a35fde819ba1216bd7438830a7e55df1c9740c5445a5feee2c189b279362d361ca77077602765936474487e21670fd4bff6998480d65f4b25166cad1d1af18ac0a25bcbdb1ea8d1234b314ba89794484515199c2ba0da2c7b146123528769e8d20ff44bedd3eca08ad8c44b549457ee1f3d5a2a82b182c4f086f1dfaaea9c85b20292fc751ab5aa722b15aba228f7e8e8a9db65648e26ce8fcfad64996789e92dd630f54c7e52aa23b0ceb87d0b23a195f5d5f8c7c5995f2dc7f9a66e4f2632039a30e2eebadeacc49d9cf8f55382c0b68c4e15247a0db9bf74c2546b059397cbd0eab35d0059880d7b1bcb401f3c6df52f2c85dfd75c59832df53875176455a982de055e778a3d3808118ec3fb7c9844904a8c2cec582d46e402155ce5043e911655fc1bfd489de3e\nSHAKE-256: 4d3c69d1ada62993b92c4fdb50ae2d7ca5f713a14140aa07bec80366bf55bc77128bb4303afa639d048882fa791fbe2b7b7d45ea00b56ccc0e7669862deef45de9506660cb4b947090b7999bff417c9dfb819a64e4d0f2c70aef7c247c99563d5eb10da60ead138c1e6a22f8495b46d351ad7679f485434e6cde0631ac0530af7fcc621c1f3fbb9a83426982e5b0d3090b1c7828ae6440330a7ef824ab181f83ef49e397820139cffbed2a10b95a73d7903e20d4edc3617d155f5796de67f046406a9f991a0befc595460ba44118e05c1ae99dc5ed27ac7a368c5bdba7d0dca03b1b8f32ef42ce5622febff0d3f1681c5938a9afaf112479724efa1fe5a2603a048ccf7e4111df7f97e2b841dd57388ff7d7ea014c31c9554eae3d124f2083d88d3a4df9463f4b14977f3772aa377cf23f6fbf4175d2112c4d82550b11bab7d151d1563adee205ce369d83dbb6277d97d33e2bd679a8b7323451c48fb2348f702ab45f5cfedc8e7010d4543f769ea65785548b7c9743dbc3d7138a623ec8e0debb341f279b45642034c6718d3c4c89ef52246a85a396a1a7099a48182c2b05b2af7bf95cd9c92e611655b64292363876d1196db97bbeddc0273cdd86d6440eb253208f497334f9c1d24ac2e0513269e8b9ff518b27ff2158d24aeb177af62d070c50728e923dc714ddd144753e20db67843c9d74c2456a2cab9a332b9e3adc74\n\nInput: 2094674dd7119005d478da6e45f2671d525a49ac99ae92a3c7f9ab8219a04491862aa67295d5913ac10b6f0d98a1f03064374e64c5988713726960f60d8f2bcfcbf429a963b7c93fe94b7b7226cdbf661004f5a450fbea217b4ac5c26be0cdebbe42956a95a8b8906d9ae441129daaaf78536789810c42d02929c4a36a74bb5b1ae5e215e4a50ac80d6dae62c43fee51a10b6931ca30bc1ef311ed0a275a876f089597dd8aacf4550274ac74f3452fa0e50e2c36f479142fdcf92245b3b7debfb06b264ca1402a22326f74fd3e41daeea7c79a2b6cd0a0d4cc8b1c8acc47b2\nSHA3-256: 7eceeea660220975f1578f3956d9c11098496c586b300273c7afb3e2282947fe\nSHA3-512: 59a6b782809cff21fae5e6aa532b5e77e23fbe54d608d4af5846dde24a153b2aedb9171ab3fc1cd0a29dfd49bdcfb207fb9d0957767a8992949206b17d183820\nSHAKE-128: 8c3549380e57a3d8f22df7e3f4805865ecdeb8123d0f8a245e27fc4d24c4ba357b25fd6b30b86f98a136bfc6915f0a03f7d0b4e10ed8c087005d18367448e0fe33ae3398502d0763ab2580fbd3dce177a0b060523585606ca5e39604b8189c7ccc8678c90a94319bc0481151cabfb2cc5a75f58adb50cc5d74a46394c285fd534339cffa0705da3e98e707dbb49ce825ae1fe06e0d67b0f16657fd1eea9c098f8f58a2582c6b5e373318256e14eb8cae459cf65d6a3f8406f20115e30fbf93b4218afab25ce4e6b9ec3e0ca1da5f8c7508693c3bf5251bb144d3d99151505b736abfc3fbb9334f153476aa061d505011c1400a61d2efe1f614624051ca3110916df5c528005a5dc620a17450c1fb38d2c259c072976869c26971b227dbac11ccd6f252a7e46a0712f0d4c21f932541c13475e8bfc38309dd9b7965c6ee4afa215f615111f91bc7c20dd36e7cda9002790ae74d6596c50b0362802da7bac3c1e2216aa6ffa6204cb63398a31ca85efe33738c56f24509ba2a5103fb0b2f3871594a9388bbf525f621e37014bc18d22799c7d0605cc22eca7e868cab468ddd148f8be75b176161c4415bd2eea507bb0a07376c1b6a98b49c3117ee13dbbeadf165cf7578b0f6483d046b71887424799bee3aadef378c0eafb8a17869469ec7fe636cb4bc9fb906ee52efe895a9bb877f672bc0274807a78ecb93b2ce1979e3f6eb\nSHAKE-256: 355b08122a2be5abf4df4645dd14aea16fa1918cc3ed40d4c90a3a357ee8e9f21cd5fb8fe964b3809657bba88e071ab7bf283e63fcfbe3e74d3a4037426e9dea2d2f485c5cb2d947f8bdfadeb2b10427f2c85e5523f8c3349e87ab844c70f6d5628140447db1799805987044613990036c42adb6e5ba05fec30f684e4627cba7f1a479e1c0db38fabb9942021aecb532592b0c2315d3a2b240afa80eba76da0ed51310c9ddaab22f35cb5496ce433b88b691e4c1e535629832a943c5012b6ef41f6b2e4a0a2e9240758671ce5fb0b98e60c6abd58c0c2f6137c4eaec12937208a6e8072ba5574b01707facb770fd46d610d496d44f6c354402264ca2b7cdcc8585959852d5d4bab036cf45b21de6fa975640bcf7852181e102f80e5865332bb1299e9be8df2fcd7f28167891fef04aac71eadd5febe3d463ca3393ab559cdc2a09859aba73a4fdb01bb7aa5197a0791d973596a3e1e78293e95dbc6ecd6e40f69c2677e7930c2608d01375039ccced676c8e4c273ef6bf51e705048fbeb7414a266e92d80fcf3de0fb4c3c4d3d1015bc88d75926d1265f2f818ff93d2fb4d2442b2688b7bc92bbe47125ff93fc32114a82069399146973aa3b28f829f6e63029303ac6a3eca672b759f5c571ed58df2c280ce4d47213769d14f2a831f88d3dab6b42a0f2d553ff0f1dcae10f8f31f650ebb275b78c03f6a9928972252482a4e4\n\nInput: e73e07075122a733ce1ee9c612ebcd05343bf8a3b21dae3654fe35517710bfe48237cc74ec93ce6f6009e8c02592520dd301029d6698cddcb60b9dc89810ddbc5d6f3a1ad58611aad8f03e7dcef01581b8158cfae6f8de0ef67c07144c35ce0264ba68e382f06ed0b547a057d0f2c17436e94dfcfd1562998fcdeeae1184a57912b50c38d5f4c1c81ae3aaeefc7726eb8acd7fc96cc103f6e16907cb9d8866ad487e986ce13983d9671b7eb249ff2ea341bc2cfd723ea6b386ea2003d8ee1f7b6da85369a1072a789bba58f331709ab77ef98f36419a2f363975c362b5f779ce\nSHA3-256: be4a321e0ca25e0bd52dcb9958fa95458daf8035a3c1ae3918f4b266e892130c\nSHA3-512: fa62af07d9164309ffe3d5af24689ec1dfe173bfd840b13ad9cad29447be6fcc87f54b11d2e057c878ef05eeb35fc564447696835194aaf78e9b82ddfa6f3169\nSHAKE-128: 2dd8651cd1299041d6714883669dac82cc18686d18415c551b45b85f0fc87a4137cbfb973962be0c36ed388ca1907eba070198a3d9b45a4133bf112ebb44add9deeb41a66d15fcf2ea7b78467e7d9c3e3c068924bb507d64484019087197a2b72c52dbbef11bef6fec3005f11a4093b72d4aed1eb379f931a85f6413b431d452fa4bb251041451e6ae39195be4588e96cc3d05fdf08d5abd46b49fc6e1d6f011c9b55b71ed135e599d1135c28f237a8baac0f22eab26e65a39fd8e2bdcb133917386f13fba6e6d62705d52add49769572f1a7cd1d311a4df1f730ac3495c938157c0fb607d30a1a7c062a2327fd57eaf3bce8e54b8f00d010dbac6bab6f9158f7ba7d42a7451886dc84b35d0", + "8bdbe35e07d000653face42e2f0e86d95e9055929a968ffa292adf5e08f24318e76be64329a1b1771866686cddf24c16e413ef86797e9bd850e75c8224ab2099aa581a8f2010eb730b24e1894e063f793d4c314876d5f1544476e371ca49bb1d1b8948844932590cb91c1b3172691a7a0c1b2ba1c97607c1979b0f0458861ffc81a6d145f0f55c01b6f62252ddacb917f7502da29fc3bc829c759ac5b3ca506d61beeb1d60de4fb59ee2adc7420a956dc93916c0cd582e7370b46484b9dff822b25914cbbc8d6fcab14bf31c78f33a2f0b654d10f554a23f0b4763e0ef3a1bd151c242a32e5b56ca62737fc1dccf4bc48f5cc5d1\nSHAKE-256: 807fc779a3f5d69eb1d86039ce80eb8e2fa49a1afc85968322acbde10de1d3a73ed5d445e0ad12e53d302275d4af9646e2a5dd034aeba787a8ae4bc7311f9d723c00a231d98fc2c4ee9d615e92643e0e731cc92ed0d81e8f27fc66be870441b7bdf62125c56bf5fc1bd3c667417a7d290588ce8908f9450dc1604d5ddaa448d3aeb0a99a5b53157d2660b000646c098e5f3ed92e0623551274d5c24896f77e513ffadfd04b1621ebaef5d68e51f0d08232c4ee837d0d4a5941e5d92e043a0868b5ae7da8ef1252c7fa6c6fbb5cb82979dcf7ded7e2744d6c0c03e6d2f3ac66d3bcb33937239026fb65861a1a7584e0fbc9eebb578e67795bff259432018b69c47041fb7e1449c4753078d4a6c305fbd6298fa3562c0c132492e45b84851bbf65f445887ef7242ed03fea674d6eae4866588904fc97f4eb42d83cfe589ee88d1f69d2a17529733771b3da7997adfcb994e37ac88ab63c37bbf2e34824ad9c84c9accbefc5f0b6837964dce191adba8ebbc28af0fa69aa2863c03622f7d88f98ef1d08cda19d986d5050c28041cea7a90bdda726ac80ca314879d1bc1115f95c747abb923bf6cff4b0e395742754cd9c454eac925c7c71a3f97ce529b2c47f987cd00186efa82c8fe9e0c5a63669ae1c63c51062a067da99d8591a8e7f4c4fcab2e63c08d543183f33abc29fc833b64aa5d468d295c120f30e1e5179af8b2ebd4f\n\nInput: cd1fed9185894cc0b898af43a82e4ba2438e25ebde851b74e8ad73046fe2fc64c8c6e1e0b0cb4ca030aecbb2daf9374734cd610545dea0dabd9de9a7f9b00523e73dc571be43de0bd4b0672a3eeab52ed078055764fbcf62e428f0ab0ed025ea1a8d385c550c2028c0a790c96a97350c29084d5d5103a17484b686fb87506aa0a66fc772bf16265d55c42994039c04df6bc8f34597fdfccad61736fceb61797ee6d967d371fc9f440d18cd203bcecdb68c1572a80478e52e1bb497c683e4c30f4429a6186cb547ea5e20a51534053cb9841cedb43c00e4a0940319e1987e357f36\nSHA3-256: f06aa9a208ebc715bddb0d95ce54c5db83f6fd047acbb8fc79f655e8fa052edb\nSHA3-512: 3b7aa9b35135296bb540ff7598163a5cbfa2c89b32244586758249ad2d42fe4072b2337e2bd03d168f01b3bd7ed38e4257240fd9600bc1f7126a7079d6536862\nSHAKE-128: 11877b7bb55a6a18cc0831d63f728e0d8d905d671cb76dba34957d80e996754cd43bc79970487f3ab854e7f4fdf4fc7494b1db4fff800ac58fff7b7b3dc4979a813eba74a33cda86b2e435dca8cf7837f45ec03c0415193e3d8be306daae69ea8496f02d1b7372d43b1b72b511a942d2b446889e6af442d6dafd811256447715f40bf5251fe049beacdb234bbd04e2285c49148a1be827b2f78baf4794ab234c059b3415a8885e2b7a1f3b7640fcd0ab5086e8e27ecc681e6212af4b6c415734076c9601bbe45376458641df6ce334c0ce6da0c2c52719275886fd9fcff2abfa8f8cca6f8890d7db14833699417ec14f7a0f965b72ce1cfa8df14391a3fb4c6cccb85a0bcf842e81ed8d72b8579b97fe03e7ad05ba5be5ccd931ff1767db75ab0f2276b0dcbac3ec726fd7e5921c672a71a643c845ff07731ecfc4df29e18a88ed9cb2d15616f312e27355cfb02a4fd7ed8fe3ab47e02296552965237bf3a438459282e9b22248fe59ec738f5421821c94badecb1a2189f7f0564882253a0a413b9827ab7c2c667fb79ab4fad9e90f379d7e908072f67bbec26e617ec0dd30bf711f6a06bb374d43c2e8d73348f146b7b8110508b2ef9db3fc952be48080158d8bb9c283deb5dc99569c557e9d34ad63648eb98145b14071e879211b7613c0ddabe81158b656254630f7c41e1f52eb2366d52a21e574baa590810143a68bab97\nSHAKE-256: 40eff28bbf2903924dc849be6b9771532cfa3b161dacfcd9498c41a9079cc2060cd3bf08ff59935d8f5db4f90697d10baa8b198cadfc220ad9fe98cf283a6fbd4e2ea969f3c57921657f7b06246155cf5ee8c342a3e8ae84b790093028e5fafbbdcbe9c67ee429ba46e60d46e987b6f0244850629844cdb5ab50622d9950a2d8a4e13f0fd5bd49374c8c437676bda33d74d9064b5f53309bb9a33e97c62cb4cc142707b7cfa41aea84a5d2030835b1a6f5abd7537ef1b4258f7630b7c7b9c136aac3b52bace1de79b8f35c5ef58d0134145ea531f3d68350d47ecc4f3f1728462c5732c8be5e52bbf3e2f980853af28da947e2f2db359975c1b562f4fe92494e00405627cd86728dd2bdbe054181cbcafc2a35a31c915691c1f3ecd5d1013c2ec39356cc3d021c328b93db7180321bf7205548609767f176db2f75e94cb4f453928154f2581ff3ddbd490d6a20a354c05950e48584ffb13c3290a62bfe1d01c9327eb3573fa454ae7826ddf241a3b066b748c0bad8700a997a87024f7846562da8bf417871704c2dd5bce52ee9de74038e7cb6a325648cd3365a43cc56df27b00fa86ec73b7e941a19c601825bc6341fae4e4d1facd20851850f75de764b360618a186edc16088b42389ed720443c21589df73baffff947d22abe451f6587e94818a8da7909bd540fcb76dcb649ec42ffe04ef4b11b5bca526192f3b5ea394da\n\nInput: 1fc72a8bb1cec04d3a339fbb52abdbd836feb9767a08e64b4e9d58d009672ff8894da74bebdb712f7aad1bed506422d7e8462a0282415d2c54d73de320866801b066ab53090c5c01478465c9126e55443a8bc15103091fb5e9ae3c415fb458ab992bc6efabeffff1c0cc75ee707fcdd895ca1506d08dd4816e69c9afeb06da6c373ced598db76292514f4b2a9f2df6371d3b4a835dcbf8a1782c679bc2f36ee57ca6a11b9dba1f697698b5cb7a3256fc7ba3a914c72387a673d33e0ae8da86b8f6d335c44bd5d428ce627d008404a7aa167a3f58bb5c49bc8a5953898eb2eb2a2786\nSHA3-256: d2386e10efb3242941654e4689d834ec59aab61b206ef63604e26ec12e0af924\nSHA3-512: a3726541bb21a573fecd0a8a97cd98f9479fe825515f637b3eb643045eae9462818b0588bad1ddb68ee0aeaee128c4bd374a907ae34b4b5b32621228939a331b\nSHAKE-128: d5f964e616bb9c72dd5b7e7d556c072bf209f26aee132c4ea6e60c4d694649a3407d0373a77b97661ea19d9ad295e1ba5cc9fc7bea95d1e9c2a7b75834206386d176fd80a6e59512423da1264335f7058fc7cdbf2511d0cf5943d3455ef208e39ae6b8fbfe3fab43ef37c109fad914494d769c0c7ba2d134082aaad131d04a60aa3b09f08b95d0ad14ec00068f2684aabacbdccf1fca5b04a9faf6e176b2a853c2a4fb123ae0ebf6cee4143a5556e2926b101c25482889df3e378d19fe785354a890998c98434754414ab22d9a5171fd19b691fede3651eff98619c176fe77c6796a2a14da4001319948f501028dc8fc33d344963c760a05aea218a7c599221cde73a4afed589a8cb3fa7d96b30c3e75dc76f9d9eaf35becafb09b221a38af21e3c3fc9b065ca8e9e8d29251382650064c6fb1301b513a0a33057f5415851110bdb5086faf2e359f98455309309eb4f0bffc550e14edb9c2980ee9409493edf531fd05fb65a8d14cae4cb3ca64a02a217003d5d1e4284f28d494a9dc6718165c95fe71926e53cae299f3a23787d022dbd00d0836e3d002de66bbcc03c34f039b10495273a0eaea61840040fb7ddfccc44c6ac886e27e58c8103177b8260a88c2b48b9d6aa089beef1f638d08e48cf1292e469f8b3f5f70c0b66c486eff552b586feeed84c347ab68f8537db7d640435c394a5d607114dfa7401348942b0eaa51\nSHAKE-256: b7c3409ad333b73e68465aa9570430a479904b715d5a0080ffb7860e9a45afdab76c8085bcde027ed84ae86688f739c1f43a998902259f1e6f66d692c9886a5fef9f992b2ddb44c9cd900366d42f7326d73e4984a2734fb2fd1b6ad9a8878a93b1bed8ed48d3d59a19d54c28d7d91c3b8e49137212e37533ea67d50e64f239e54b6ba1107e61198211260c98d4c57900c8f859280efa10a71a26f1831a64425658d33d1991f3845c21cf7faf05aebea84f48a3b25501eec17f79a1bc59a4ada9efec85908c7810847d4eb9f2bc361cba3560539d2c7c9c05b866178d84dba73ccda44fd28350cbe49f5db53449cb34779df5fe8fc2ddabe3cb9b22d6678db2c072aaca0e9642035b28655eaf9553cbc52c333723b6fe86fa378ddc8f587c5071a07f198fb75d6495180952cee3cd4e4f4e8af616ac3df77dd1801db4ae94166c325c5c81c5b7430bb26910be607a2d312aac29c84615a038b024d3ee8b55ec5baa16a42ae6586b84ebb2c0a9d9faf52922f056c0301796338887306be47772884c44785fc908c9b3a6208eac5012df811567be0ae322fec748367219e235670c092729a9f1eba45fbdecb6cedd7f286b0d810199e20090b9b386718944394d66000d57b539e6ceb45f9a62379d4e2cdf603af5af7608e5c6e6ca8758b42a4e0203cbd2f7b95fb10fb7c4d05cb0fc1b8ae02c16e9a159d9f4e07607e41a7c2b6d\n\nInput: 70d04e8dc1e06770b25942b7186becbcc0ffb4e8a13f2766b6c2ccd3b6401ffa5ba5b665b8148b1f19018d5a26d5c71836b440e9aee504a93929b18c2fa208a3bce013b0a47d60ff083e73f24088d331a18155ef8fe0ea2870df271600f25e9b4d2ee33c8c84286c7b5ab9e1a2330c337d9012979e77d0ea1ab73474b84e535d7de9dfd9d93573665129abc71daef1f2c927f06f1bbe949cdb3df0233ae3cf347d7cec3cac84659832c43de9bae20b3238984faadba07759186ff5f42635180e85f20cd500bd6f0db358972cb6fe33d0ae1a755200e851deea582561f73dbcb99a6f1c\nSHA3-256: 703f307f54c11ed6d0c78a1a0bc01029018a30eedc44c73fcaad5caedad1254e\nSHA3-512: 9ade73c7c87619441fcbae921ce91fa216f23e069e472efed144e482d98450104e3a32d97e523b2041601b643baf40d8f72959c67616716a40a2a5d56c020f94\nSHAKE-128: bfaa2b064b5fb2e34f0fa5c756a3aad82d31e66e48953795d8e45cca69c91d93062a6559eff09cecb3a2c43a4486a034d66132f78a6c391351a9870eebd1e735d51f94f0f48cd76ca9d4378249bd05978cab5066453596f63b641ba4747ba05f09ecd88e457e908360c8a42266a34a38f4654a572e48463197dbec3c441e5466c7e369ab7995f4406626139083ef8c4c4a93da9acf5dfd45aae9cad7326cac634fb1736d1042ddd47e09e21610aee7543a03f22d449911f2c31597f76294c320edb30efb61a398b33fcef5ec7e96fff7fa808471d11576507c59b98c22d76a0d0bd51981dddf33999a288982f27168da573763c", + "01ceca70a0cc839ef1054e042af22a4a7f74192fa918056be04e3c9f23a6da2c7b2247bfb2117576126b7d5e12eb9a3255bed0e6f577fe16bbe7951f5535468f38cbf9c4c756d1a367c05a156d41877dbe4a18307eaeeca046d8839536c9fc3fc65931c9d8b5c7532ed01653a318fe34c2ce76ce8d3bf74fbb50335236686917b0afab7db8fb2e969379ae9f74afcdba9544762021c12227b9200aaa531ec0bd31b4df2dcfb3fe799e314f73abaa6ea09e6b24fb4efc15a658386e04d708ba422ee92bea57404a1812ce543973e594974441a85d0644639c339cad04fc3d49d0d1dec72135d51df26bc536a0dbdf5dc298fc7a51d110b9b3c080855f4b1d63b27a2f846c46eabfc10e2456110\nSHAKE-256: 49bb833777715a6494e67abe3418635d56a7fad04fa5f5a3dd783be8afc5a370b546d4214f200e2eac6eeb87a582f9221dca350d8f982892c610e58039824d29432fa0979fea554035f28e837d780dd353462adc7ded030985a8ea71a204668e4c625645d1a0444ab66bdbee5d3ec8eb4f736cdf2e2227e94080fb0c9b9195ca7cd1157d097f045a458eb020163683af8aad2e5c4da4cb86a0cb7a286a577d2d14527bc9b16319d71e89cc109b0515246032fd2770db3e3583b718cc97c58aea39bbf3b57be9e0c15aa029350e4e6d2baf41a229b76f88096296eac0998d5b15c031d3cad4ffaede1d8cd61bcaa32cd8354b2cb672bfad25919f279ab34577c607fde97ef3b46b00f7521380931508dd5da6ab7d3487c37932b38e57b4efad36f6b420e0928e658cdfffcb72fc85719511ec4092fafd7269ad0d53d37d29ba9b5e08ab2b0f8f4e47db27f5640b28d246e07e4f9306b43bb10e78324192aad60422846d340a4a5b1d696658d866f7b426fbfa430d337a609777d994575e44f67d37501d68fd182167eba82902e98ae174d38bf9d8e209b65e6317136c2b08e80b91947c6ddac565e5a371bed59be36cb266324e6a12e9db7479c980ddda8fed2e34713ecad65c54587b72a18089d73a2460c53bbcb93ca303761ef1c63071727679554fac3fe0629df21de72e11fefa25cd6b018b29913ed7f4f7ea2cf3dc4de7\n\nInput: ad2714ee315407195082a3536522a2e842bec353e84fe6e582fc554fd18d202245827626530256457df1fe2de6f3598e9b9adc9b28d4b4df3356fdf5823050acd63a25a54a99f4cc5757ed6caef879edfdd8710191581121384ed1beb5b164333ec52d9b464fca768c4c2c3b63a8f41cbbf025d3ef84fafe788fbdece9f5397bd66493de3a37b8c0ae921cd401a903f70e995cc42db68e30981cae1853632df17b87845029726aea09666ad52c96170c1eb445e107f156d679b009cb22aaaa9578abe32fb6646a94e560097ae9a47116132fd4138765bf212588d8a3d46b929ad16a4adc\nSHA3-256: 1bd9c2f03353de7628ea44b5bef95aeba9a21dd4c90bb5baa6e4a3a18409916c\nSHA3-512: 17ad20dd30200047a91e41b7dfe5aa064d08bad5aeae8d9f016fbe9b45476199d60a778b51f1678a84f55184ffd5a6230f3f18a0ee2a04f8ba60629d2a5dcd67\nSHAKE-128: 42bc67410a1a9166b9ea6973f2648c12d7a79261e07f54e5f1426924ce222d042583c672f0d145b32900c01c804108bca8c49643f11cc0f9ff2f9499aaa411302f067b61edeaa49226d7c60f1a55d1a48e0b356f1f183f84746a290a418ba99555ba2dbdca7f64cf61c23577202f843928607f0b513446967a17bcd48cb58ee8bcb7893f07d28d0530f24c4e80e8c0918b8b9983c5a886dbc0ee5fda2b36156cadc431b3a16d1e331d7057d75051ef5d27f6e503fc7c3153f3f633ff33222d166d423761d504af6c719552e402537103472f5863a6a6e51798411ea6b8c45be99e814992900689d1e896a5f56ae1be23c7403672a457bd3618be91d1b205ffed5f977de87721e74da04d479cc48afe57a12f3b31de749863d13cdba19f31f17601b84216d78df3eaf969430c7d5b1c6650807b50eec170ad507155fd468ff52b704a9ce7b67fc7d590efe25221dcd731896453678a2161baff4ef1b3ee14bfb7a38a52a7fdb5ca40ecde4aff429daab193de993139335bfb6affa4d915e151e0f7740cf608b322120b349747e2754522fae30d60eec4204e9dec55707fee9e1306e65908808fc185cfb8dfa8f730dae96cfe5b41fad61f9371d5725d8f48cd48ad3aedbeb8a4313c7d05c70a8c0f5fe8aaa65bb1d1458bdbcff795a34f15e0f2dfacd6de4063f22c19319702da0e31c935b0bc2814196d50ba76129bf77a25e1\nSHAKE-256: 3950c98e24fb4c5cdd6c408edbd9e25db4570e886800a4a1dd2cfc91f309e8118d5069f3e157a46509640406f92a3e4fb0138044f2be2f0433b1aab73df399bde2b74c04bc4a81fd123f122961ad6659080169fb70e95bca29cb90894035b4035a0439f17a99bb3bed637fccd6c2573085d73c6b7c312afaa20a044ec681b4c6ac3a2ce511eeb7274ddbebd97a7b49b3a4e356ecffcb3a7d3a4db7205a22318a9e0bd6c4c9712da89b9c47cc9e6d6ba23366b98d06074346b842698b9728dcce804b291ebe17b389707d6c2fec9f7f096e98ccdaf6a59f3e4cca0ed293a373ebc794d7d981be6987c565234f187296ed2edd3b0495713eebceb324c3a6405e9c4dbe7a71db01e31d1ff6ff042bfd3604c3c03a8e065867a3179d4989ae4887a70c89e05a746159c589cf4fb63eca84e13887d77822cbfe946a4cfaa0712f051ff2442b71e2057313c0952ca45a676d62e88fde29be01fa9d455db7fc3bd59a55e03d4cd04de3591355542b8ebf9ed1d2d3b9aa980deb0541e7bf8a00f2aac59956ce81dec930a848efb3cf45644b122937f489c4c92d90efdfc2c61a03e9d5f2cf4797e3480c6b5d4feb5965d62c40e055519826d78e94260b21eb73cb3b1e010def722c2487ed1a64492e8e7aeae6eff6743bfe4e75fd7193f9f739c543560611cb89a2ad9837b1db1c25098169bfc024610da32fb4e0ff3bfbac8929da107e\n\nInput: a2c824a11f6ccd3426a1f3fe6179749b3466cadf1e724d0da3007567c41ab47279bed7882bfec231e2952e2ee7f192bea8ac1a2440dc1caae0b02c40979130e356737e842d1fd21e3a87385228ff7f5609d7fedce7244940c612ea528ec8d441444f10707b5ad3a8a199bc3f795e1a250a59eb9bfffb7c4807d4270405f73eaa5b32725ce82cf86fca0d253b0e73031d3063973fe46ef1bc7b729237e0efa7cd2878aa6ff6b95dc4f52d0c2437fd35456b8dd2f6ed4470f709e8cd46700a0518d9761f3b8fbb039445f0153f0e782a63c1b623cb958926fcc1c6cf01e6b80aa204809435e9\nSHA3-256: df7ca5feb6d2ae7f7df2fea79402ee137b9e0cfc530acdf91051c47f6910b0cd\nSHA3-512: fd58e6f16154ff640736467bc3edf239ed3d1953d47aa580c5ada30b66713737be1e4576668a4b5a11afd2c06f30a5cfd24a513ea0ebcd2a58b9da1de24f478a\nSHAKE-128: 8cff2a722350ea98908e931ea11ee7ab3fabea4c775518bb8c4a558bcec9551a6304a3b454280a51c88a7449d0de0dd5d712e2272f0a39a66403a0b96acf8fa361ae3ee963b17965642bea6b06b77d9f9140e05d9c125660146eaf769e82ffa268234d362eb398962d99e83664ef3b850ca5fc9d696eafead038edf5e59c2ed95d2c5b2db4525664254b38895e110ee7fee96ac2fb0572b1207400cbb652de80d2c8f4b2204df7474fd65ceafec5d3af9b3e935f90b9e7053686d1283025eb2b4daa7381fbb403141f868a634b3943f25ec77fcc8b713211cd5b3a9d09b53fb249e43d230f992f2f9563caa657c63a1642f1de2f9da9eecc2307ad5270875821dc451bbca6a9159ed90d56047bf93b202f0428472ae763c9d2515cb3f54d70e57a98db95fc0dbb6261f1b1841f761a98c3bcc3d4e25cac62c5521102d8895e2018e6a49d46ad8759d442fa3cb5f9c2ab2cd5e1a5424ffe0107cf043593acba6500b0adf2d77fbc2eadabb14ef22c14ab1bcdcc35b8ef702b5f8d79da6b99204fa3771dec691da24d332e7ca3c7cd7bb7efc6872625d0ca42f8c737e1966dc376b589b6a937caeaa12e43094fc64a66dadf2b823f422cabce34b44f965097c15303712dd348d95b6a12da5c2b20a2fca05ab0a61910a8b423c4f952901ce09e6e1708ff42f664bf489290df22af6b46f212b54769d04e0383578a513a5ba6f522\nSHAKE-256: eafcfe6b85db69f2574ea0aef9ad40d2ffacdc7dff546f1fc1cc9c085887a2bfd4bc5a155035339c6c484ac98c9585d25fc4fb6a00164dfe48c27c33474538e5faba8d797533e4fa9960fa821de4636bbef413777ebe5ddb98a64acef648f136f94e3440576ab2aa331d46ed378bd2142ba2606b09f5281d887e351aea8f6a40f54e494a586e6ad47791a9e41e455b884ca610437fa9ccefa0c91060ae885c9ce83bc14e5bc7dd6b77fd9e09d650ccfe18cbd84d44e0d0d296fd698b117122ec8e343990bcafdf4558ccec74ed6e67aa0fcf83bf6b104ba23ca8c997737afdeb0d2a90aa033e6035d5cf9e4ca1f7cc8f604a0a508eee1399d922a8ddb5c89b4a68d5d4dcc5092cc19885c706bf8aca8b1d4747bd42cfdb14cecb075575994e6ff674670641c16f1487a423d39429b95b27a3009e1a1f5e068830856a4c14e24e7e292f195accd8abf7754699fd699f61f801a2fecee713f148504b0a31a75849cfd02eb13f3bc2cefab03757bce4f5afa07e3bfc701946b088e52e3290409bfd091940d00309ebea1b3481672168179cbc8983d38ec76e392cdc2dc19c742be1cdd89eb3d13ea620527ac0f09d7681edfadd8b83dbb308e5ef13438520d7459b1f836f00fcb68199a88f0e016d20b16e80ecc14ea8db369134e580118df9e5058d5f1a155e80f9a06deb871ae8d0c2495625e2388f5b6077bbecfc5b03c95326\n\nInput: 1e516cb62bd6ad8ec887ef837fdffa0d91ddc85331bb24998b85601be2458231caa87da5b6571199b8149e166e7ef6acb5dc2d4cc00ca8f98758ae4fa342eeb8c9d097412c64898266c7cb7baeada32c01ea6d9970e6774d50622b94d8b559285e6889d3e10dbbd68b3fe6580fababfceab42ccf9c6815929b14e589d54de96ce09fb7e0f4baa5d9e7632cc642597465f6078d61914dacf3194f51dd796264e9c9f8115afb05ccf39b3bd800790468ff2ab9bcc05855eff48532e3f9b2f2ab1aa72323291cc3a86583353e509d26f1f4919a25f830da4d0aed8440d4dcbb5323bd3538ad9167\nSHA3-256: 4a68ee4e6a66e6bfa419bc3ceebac6682622419a4644cc7968f4aef766d43317\nSHA3-512: b7c38a6acfc5f290c3903889ecfd36a27277f19644d3d996fd17fc87f6fa2cd157d8f1be5cc2de80331867fbbe5bc6223fb7faed10971e46921903f1027770ba\nSHAKE-128: 81fe3cef85559441ab5f821dce0b3ad7d64b2e731b2020e80e53e6989308344ad92aee14474092f00b64170a8eeace79c34d56d68eed7b73b3cde7884c878b17bc264b63c26556c0fbe0bf11fb8ecd4b4f8242b287cd75380db567df401f7d6308e4b611332a9f807c8ae99cea6106f30c22613d057a0b236efb7ef32de40e9a909ef7ed4560ef09d5a469cd77ec153baad98e9430a4a3fc0069d38b4eb841b81a64cc51d3a64227e5b4625dbd3b993dcc46ea0df6fa270965c5976ae8c24a3a9dc2436b7ff1091cc7332d17fe714a7e96dc", + "a4a8fb8a449ea8f27a46dd26a6d43d9a5c8d3d1f8af81a7ecb7813f5d488df3421993097d32dd7e80b1d3f1ed6ac073bc912c7df8237de1cf68a70e1732b71dad9596818117843545c88415336634988cb130670f7a92094e6aca6629cc74c7265d86d65f13cc0df895adfae2f7dd437b63e183738164098dc1970f186964183f9ad479c0c43d7a080360e51f16084a0280311e75ee62c2206ff42cc6d7e49c44ab3ccdf895ec2b4af2f05a8f2579e938f98c4cbe244523a7b74cababb8ba20af459e603eac6ef04e95064fce2baaf8e655b011f1e9c80c99cce4b9e386717b949faf9f7ad437dfa06f57ae96b6cb21f29f18f32cce94eb7ad45af041da3d6907397e787384676ff93e01cc295344ce8f523f44085c43aa305f97d392fca80e04e455a08152fa56057c4bc5a9b99\nSHAKE-256: 227bf6d099e53606dfe403f5abd87355b2c029daaecc55727543eba3575817ce10e5c3f0667b6eb3b008e9f60fd9f145097aca1381be7f06a3f13085fa2d62016136ce410ecf0f207b0a4523e88e5f3b4c8b814ff136f1248f206382c279d4ffa97d678e7cd9db52f5a2eff30daa414cab2cc4938586467ef85c78940ae78d6c40792055c8765c68a5b5f3b4d32806b1d1cedcd09c8df374dc97f9e57cd53633eedb4a9a2c05c7a71a2d5c7b2f2db3ac8a9451ed63d6b77384c1bac6223e26e9589974c6216d9edf79df139942363680295a18ff3cb2a694d18fc5a9bcb2b7993ff0acd39f1df026c19f7a3fe747c93de6faf7c62c3ffabeb6bec1be4bfbbbc83aa6da92f5a0d7f2b9c53e183c9a965824fd3070224ab01f48acd9cf6a1fec3ff48d1def254196ae5bcafa112ff96e83982798bede8d5f1a70ae901c1ac93103a1828d57da018a024e3de86e51d60f6cd322fb030a22007285b9145ed54c0c51ce711975207a4b5be0d1fb29650fc52ee8b8c82b2886cb4b594916de568a9e06064d479eb4a0b1aaeaafbc014c363b5a4593567480b24fa931fafd91279af2a71c636eb0de227134df65d364ab9ddbc38038d15c378d1cdefad04647332bff2adfeaf8854439f0da106daa77aac4df5ca5db19ed31bdc74ceee48eca06dc9b45db8eff7bbf8ec94e1ffa09579fb56ea974eeee091c9841cda629f3386efdc80b\n\nInput: 96ed40755a680da2e163c74eae0856f1435ad63e76a740a217bba48ba77f8387b4aeaca18037afe3f7a6b2fc27d04879c9e3e17a43612afc4a7f375a19c284d3999d81b5a55af26606582c0219479d37ad1458c3b62e458e572808859c2310db02441b5a90155d30faf0e9400c7093cdd4c43dbabcf6d54ded5adec2b11c9c83a12c314a154938479addc567d17599718a4df761bb7445b843a51cec9b8db24e11902e9216d9726efb72fbcc3bf5ce4eafda8952ee7bf47c1842b7c45107e9f6b3c08abd345b01ed4959532a4193266898ebfec430f58cd7e5b402e6c5307aed21e835be7fd587\nSHA3-256: 38a0f7c991a68615e43aad7f7113b6b226804c69fc95f80c185abb7f415b6037\nSHA3-512: 9273679e29bd1f463031883fb3511f16a99e143030491a404b98acf53d2bc5419e653f5fab9e05399c7e6e281a4441c34ae39c6b5e33047cac9348c77372c1ee\nSHAKE-128: d38b3f24182a17e05bf408bb3e7f5d3cc92ff319ed295fdf2baeec860e95bc10426acc995b69c34a97bfa9dcb477b401a38b11f1955f8f7f403c1f0f8002a04d95c65ef267cfb3efa279103a0193729a8958ccdd6323691116cf9420f8b711d2abf51aeaddd18f588274191c21469b1a48aec40db903033cbf988dad24d8435ae7524f932c936e1e276dad5d80431838c228bdfa9d165160df9d41e98b130acc9c079ac4d3fc51386446e7c5c5372fc1ebc2d2ae430cb3418882f3ca73b5ea34396e0c1d8c00158a2b1f440ce2d9ed5449de7aeb9272ccc3fc8ee3a4058db676c2c7e8477fd7ff3e2e1cf618cc35650ad6862a66d60773d3c238757b573bacd1f48294068ab61c5f5f90c8166690b9b467f195b1abd8e53601a922bdb9dc0fab32c77d03e334c241febddd494bfdada46b772e62b12693960959c80b6d83c00aefe9d556531756699080fd813b4273c650094cb0eb3c6509bde4058abe10f25890c634f342d20d2d02d0292e5c23789ab5218956c0274d888386667329801eee01e4119984aee457209a9decebe578c12b76ca852ee06c1280974b42613c7f685735bdfe56ff5eeb44e0dc8e93f4a6b477a279dd78f5993c2c3b3b7f4e0c6a2deddcd599a8b9ee0b88918be8bfd2c68e1f58443f2046433dc37198126c9d5d08f54649646e77202292c4d90a70dc756990d7125b475cd8ceba8c0613347f6ecb\nSHAKE-256: 16547da68d8251d8af605ce2963f41dff3db32f4b127ede06a714301adbd217c37b47877edf5a4ebb374477f6f23ae98771b9b0adfdfb0a41b8698c0bd79eee4c1eab7da1ee4270f7d90a44a67fcbbb1b3746ef6281b52c8c27f304734a34d3e93906a46c6ca94048f5263e7e624184b13526e004efbede02c803f7dac90ef1f64511eaa8a7a37406928471289e970a86086e3ef3ad96f0c307c65c4ca96b886d96a8b4da146ca22c1a8149616c1201e27ca53838a54122dbcfb79a5612b38730d95249a84dab2705486af77ea1b36dadca36aef39028387e806736fc6f7aaa3129b19cd0cb5ebe775a6fe5532d82d05fcf53363d26a22786dd957373d6028110b8abf6c7ef2ff2c59248f54ffcef09c9756678cf0e9da20f3c10b1d30c592640c7336ffe170d279aa5639cc64deb693ca72060abcd447405944ee3b9ca8b6099cb76219146be5efdf68a84d64ab5daccff2295780b32f6466b9e45ca19fbe6d6fdda973eff1f66de7412ca4ef3ebe9ea390558457dc33460d9d5a3ad48e23b889ce648b9a5c01016439ff2971972113d57af57ddeb44f47b92cf02daa3c1d309bcf3e5fa3b3e4f0daf9d4247ddd314694581276eaced7e6dd084d5c3a666ace58f75c9ffe74e16368929975b291dfae535cb17a65aa7d80a46018116a08d468a8d97cdc7f54a45a3e58364cd64cb5d8202ca4a8a36fcec5aff5e90b251fa281\n\nInput: db15cd3afb2e55685fdaff2935d9f9e2f5706baf34afd5fec6e9c26ed0b1cb824354e4f967ba1be63ca22deae8eddad24cbd1d0f14f882499546d4b1f8e83db655a934a9de1d9cdd1791c3e2251ca475d91b5cf558232c865af118bccc4a8d8f2cf10e55124c6547da721c3594ccc2423ca586f1e1347ee9eadb7cb62e2982fac8592a1290fb15ca13658f609edd8b874f2beda2ec903a5990e49700b81d66d82797bfc29ebef9ab159590f06ac66f1d398a8f1e697bb25de0a79cc73f793c5438c2bdec00a6e4ff7121ec22a527e18d840e9c7e7277fc9476efc35c75c13bb92750aae504fbef3f\nSHA3-256: b89eefc201611ae8700d37fa699f2b8f9a7e9e9986a5488d143b0176aa3ef8db\nSHA3-512: 4d7920a5471d827f6c6fb9047b6897ae3f4b2464d5663b085820d142e86109f61f59cc1b6b7a0b1f5ea99be0fc5dcc4f7ec6eb9b24e2795b2b724a2a5388295d\nSHAKE-128: 079367fd274e01e889d411ada1c1790246a281e4bed95bc4fc09518efec0265788c6bff213d39653412b7d1302afa4ff892a3e1d758dc77c7969502be3f94b90aee1b0838fd67cfe0cb11753d70ff08b989c197cfbf6d695e23bba737a2273447b4702971ea54ce4eff8e1e6cac8e2c8899ddb97a192e469ebf073b1e4fbea18552b2b429d0943b936dd29e82dc9b0d5326e012cc933a7b5575d9d431561272f7c31a1de8a344c9dab43805fff7b39031dc75cc4cdd0a6c4c9f9c22314e5e3ddbd827e952f6f954ea7f4f0b4eeab5440f469c1c4b4ee289d04db002b52bfda59732879c5acf0869710d61e3899119c748e51e618ae72a78257bbe658d1ad866382eacb3a8d98e9f810dd606cfd5642708d9297236ee6c9744445c90f4e8fda6910a374df53f7cfb7e07902008b68cd62c83f2a7a2b7eae7c377b3e3f5ed843e519518e3ae4fca1df1cbae79111eb83439a88df8dcc535cfac89ca2bbe59d9bdab9193ab7c66b0c2edb98045d368b4cc41bb5c8fcec6f92909cdbf13b2e400d74a08e29808ec4fed36b71d0d31fd2fefa0778d284ec87b42961f8d330a31ec01591000ddb5c6dd7b515102db87f1b2d806233b5887fd25fa097e7fb67695d5012a2cfc8a0871bd2c23b9429a64bbbd3515add00cb54ee4d34c32743f835e9657297edb4535f17000092f0f2a45ece17da2d7dde2bde11f5121f7d8e5c4cf59561\nSHAKE-256: 0b1be090a5183fdd96ce9da4ed8c3ec255ddc07841d304cb70dd04b040bfd36083284d992f8670e8933ab00c78c93d53f6cdeee87c9eeaa8de3c8cd8f922be8bfa31c8e12abf75d1f76f1da74c1c443f60f5e5bff9092137ad0a57cfac083dba6e4d4045bb5a778eb94e126bcb00a81959e9d44de4585ece3e190fc2602c47175ab643d2c0c978e887f78ef6fc78d5a51b99d7bd200be56a578df9e8cd4b99be0e1b6629abf957e7ab4586224b6fef45305ad8d87875fac4f127aa141f6d0406e97cf1aac2399f94e48551d11c9d2de4c03dba28584bf58071ea158673801c0f0afcd0264c6fea1d4f388074d587690ef9a74c6fca81fb944d3ec0aab290f742f6d4923c1225ad2acc483eaae7e96dcd047911b203c78275e7111f04c0cf4e6ec152b18ffb3149481999e67090d7d37767e0df6931b85f1684399e3d033ffd5d9746360b8814517c7e74ee9e24dd549505f6e6c25febc09ffe92f1d91fedd244a343c46841ecf855b0056288e863e1bc1a95bc5d756c8c6a6ed9433df51f324d4c0a7b53beecaf0ba4db30d5f4196ed08490211d2b8045abc733689c7a298c4d88a79dbabe5df13dce5dac9240963fcbaa8437413cb7e38ebbf9b394b24f6acca822f3230184d21a1831a887c5656620e9c54f4e6d3dd95eaa8309dc27bae6bbc038dcaf3cc15b8bb2d0a49c09152ed22a17f33582c65b207fd1bdc3a20cbe45\n\nInput: d6f0f213a270fbe037dffebbc2edfcd261bb4b64538931b3340253b7538cb2079532f2676257fecea12fd2730fb4d033345493884fbe5c90c642e67972f7210e625341fe5cb210eb91e718c63110ae3c81ce769ada43e7f9a3282d49e7c28f3615bc76ca601e2dc4d3c450cc92ef53c0a2a37c70048ebadaa372b948fdf45652171f16bdb9e9fd45aa70482f86d4cba0aa30f2a0e1b9508a002376e54438ef91eaa4a0005d7558996f8bba0f7111e8ce0f3334d29abe98d1c74d7daa589d17b250a3154d83050b564de1acac041d15584f657bd85f1c1ff73508afbe856ff007e8be0a1ecfa8e42f12\nSHA3-256: 1549bfcc9a635830ed84d6e7e31cef1487f32b0576b21091b4aaec3ea8eac986\nSHA3-512: 62988baf7b9cdf62db7e8f54d256e2faad8528c85441ef849e471bbee965cdd97a0e656b013f01057a1b468d5bd6f7c994819f7147de20d7dd98ad4655742c37\nSHAKE-128: bd08a0add6c1c09788d5e8429999d33384a6c4aa1fa6d6341c7006ef1ddca379ba3107d5e653d2d1d2e86e933cb6f4b0fb6133dcd86edb64df2f6b043daa414fbe6157fca7d06b02ab687c2c3020cd0236e516814aae52d3d86cf209d799497cd8f2eb19ad52c1266f3d1393176d53f2975e8eb330188c1e7266d66ca10df1c683a8f56d3a2f76345d1ccc5cf1059189c11bda6d8ef73f7d60b9f0ecad3ca8d65c1298a61f5de9a", + "f8a1553bdfc5f1e92dd00cf5be35e8a2de2bc620937b23e487d0ed815ff0374cfae003f979581d811186c25f84b9209d15ba46d4f77ac2fc5e3690980338a0935261c812864e6801fe600191ed9e2a093edb1dc2ce5632176677b9b780a725b47cb2122e7f4b681b1c99dc6e524ac15d4bf9d11e3685fbdfb32fb04269b9b8002cad4ab80f9d3b2828677fc5f9c850ee31b2fab898f8a9615da85e6b84eeb32b05d72a3c0cff3f319f113a29e837295a006de2f554511451e58c912373372dd81aa62b1d3c23d29e6bb52ed82a740c8fe48afe55f3a2ade8f3d605f47154dd36b4977a7c6e3bca7e729bbaef09ef517434245702e5c351f0df4c3527192e4766b23c3b53675bada568d56dfc4f6d0274886705a2177419965ca8edbb2574ae5c1a326629b0cae7a500d41037053305d507ef336e4d5f0ca4013a71213652c166a0a43ef275a9fb3f381c6b6d15eaf20a709c4ba2bf0ce03ad\nSHAKE-256: a484c816ac9a9e54ef2b627c79bfd27b5f3b9e55908059650eceafadb78942ab8e16ed4a462abc8f868ad4b655a7fee7a58b404946de490616b9da8688bab38e66edaafcf068ce08afb6ddbd04805c28a8ed9ce50c2374a6971dee70528a83a22159ee623262b450559c9a46b2b23bf38180fce9d9eae76ac12232da5baca18b521f4e92fbc2b3e79f7d9588d4f2a674285c50a0285719a45c31d922f09783940b6a4aaa96a60e77046980267ec0b57d48bd6ef89b2410d73276e1d498d05f10bac90cd876674cb2b3e9481d1d1f5ad609aa8781b0f29fc36ae699bc02a95c67825ed3f04c1accf2fba00b0758be16e713334dd6298451c24fe8a8a00bee8b0735cea40615dde37d4d354f811cc8c9f615d5ada1be10640d6476f173875b42d4459dc43d6b7af31c7e239192ea1878fa3c03a0bb7147faf2765621e5fd71573dd5759a29377761d01d6ba34e40c599a9c6ae5a44d19e71aae040c2bb488fe3d11e18e43e1262e867635b31a42687990e9a8846020ae5d065a98bf17764ffef8d81ac2ab73d22fda9aabb09f0c18be346be08b23eefaa083f0716ab6eb6c14c8cf1cdda941b1e1b8a54729cb0e3f1c180502bd328676470cf8907a61378e94b64c2c8fc4a7ef866d8f807688f4f57908b16566a24d519969a5e79b5a2ea45c51b319ee8c8aa4dd5e7e56bf9e778a44c3acd6d47419d0478d601f95808a86879a9\n\nInput: 9b808f69ef76934d895beebd9f538309920c0a93adadb72158e60ef4ea1a432371005761eb2ed02d324c47d633506428b5e25a5d20184b20ebcea0879e3012ae6d394970608c84cf73bedfe2f238f17632b635f275293dbc2570821fe6eb07088f4cab9673fde0396001bd85e4477ed57da0e6c5123f96ace2b0bb6d3c89c11dafeb65c3d797d40150b2900f7a60924a523c0e8a827c90e7fdd6623a30dd62ecc7eed3de8079e5f019ec87a89670784b34758f2d68979952710fdbbcb498022c73aff78fc5addcc3ff8a3a00e10a62e84e1546d48e6ca2fa5e739ce20f2058bfff57fe9f49cdb6ba081f\nSHA3-256: f067fe731683c0e032b4ce8d159d5b9dd12dfe3fac6b84025c4bcf960bfc3187\nSHA3-512: c1a77b916593865b2293acc821b7e5a9ab8b877c378d30f462f4804d84d7736e5d373bac9ad40a7abb3a0fa42ba7d4e4109b9a0b8606a691211e5c38f61e6300\nSHAKE-128: 29ecd8a675d969063a997d70d63e86c7052607d69f6f8c57f9a6025a29f827e6d0f620651be9999b44a9c817148b2223a652e8a1b68a7a43bbf4f843592de2ddf0ed2287cddd44006e53d65790a68550d7eb2189fa0568648546192814899418f80dbe7e08ea4dca298a7416d8d7b6bd7b47fc3cde9fe701c164903b194e8fd72ad1608f25d356d2531fcbc8191979ec92656bf350fe19a0db704c318849a46d68dfc38eab207d81152111ac5b6f8b6698b6795369129001cf883bef8c7f5c34f9bff4d352cdcde64299ef333ddba9627ea6ab2dbc435bc9af33447c25a604e9148d8a4cea1c8479c1abc29413937a168116919163fb4db8f0498e13bfbb3710ed60b3e2874800bd60d1c52460fb5b294705de0062fc5b4d6ec7c4717b96882f8e434c910ad568cac7ad2e35310dbb6dbacb8565222da6c8d74df81cdf87c39000427bf7bc74b419bce98fc4b5b4f919968b9d2f78bca2ab47eff2b26a60d95463398e0b03d7a40696ac7ae7ce653aeac4e33524384594ba8b35d0d9f47493c22621296b8d00616dc738cbee67627d906b9de10ba59e5abb1962d201f9babd2f062aca79117db765e2e10f9922259750818f5fde2f8d97fd6e5b6d82beb4978755bbea7e5bbada8b61732cd50d33aa836c0b6a67349569899335f4f35551e22f561f22b75fa1e793a1140b62b2658c6e9ced86100382fea65a7ab5c563920f8d\nSHAKE-256: 8c206096975cb1b79abf539ea773802fc7d4236dad945eabdb9d0ecb392b98753486a8fc6298fc096f9284bb795b2fda9afa6e33b0d86e356e48216cb68d6dd6cba6fdfdf0d093a534360628f61604f2186de471026cdc01f4fbf75fe0a7885d0a1589ff6dc64e5898b1738758fc3c864fd42461c11c5b59a3ffcddbc1d0bfd77d25661794e0692e114d65c4d102ba41b4401b9599304d5514ae68d8342f33d71ea34a4ffd78cec311177920fd1fcd2e95f57cff718deb65c76db03a3455627851df43b1e452546dfb0a99d2d49a3bd8fec9e335c0d869f72c69bbeec8965edbfad5a62ec59027b8d953851ea75d228f41dda11c80707ba7a8bf62505c1824d50faef1bf3423b56e1697cf6b644f263e50d12264b8bbc51ff8291c913a19e8cc4fd41649cb8c0d94b74fce4138874b0c8d49078249bfd74547c2d1d4afdcdd7dd4aa6129f9d20bf24e6cdafebf9fb842a3b89870eaf990b90b3a51bf11e57dfaea6f0b58899826dd433a8709507b65bce671819b42544fcfb6a830b87b74a28f6ae923b2e183e0a0e47fbc9fec1f2c0002766fcb255eb1b03658d69760ad1ffd48bc1bcd4c54fec976ee18bfcd49a513dd04140bb83bf0acbc255537051fa8ebbef24d4fb130a1e2572b151a1c2e17b5a335e4151a7bc07e67f26ef8200bae33c110e1de7fda307b8fa16c4e6dde43aa03f3976f8ac93066757918f983f8826a\n\nInput: 104397edbe2f576576c028925fcd36fc8266bc5af5467bc3348d3bf652bbf7b8460c437f16909faa311e78e90fb853855f734b99be6e18b0b85c834a79180b4f69528c1db786166ad76e724b982072c55cad2833c0544739a95242ebf62f1dbc45c47b86a4c113037e517c9da405b47ec43334758390c2b78594269a783813d409f75b9d7d0a51b36e9163a3b7c3a09fc57ea9a632be44abab445f5aec387032e97641d372353348c600fd57c54405ba8e5f3614ff7618ace965d2fe17de87fa66a19707b9139b3a22847deecc4f6c2171aabbc3263d24b4d78a8c4d66049d47126e2555d693cabd0939db\nSHA3-256: 6df06abb6e7676e3b6931457938dd74ad4e776b3a7c70a33a926e2c6c81e3547\nSHA3-512: 179a089371fb87869bb015ee07e39fab9bc9dad3ecb393cd17c0d0ced4eb08ae17b5aa01446e0567501bbc0aa22c8cebaf0c73020408fbdd216537596888eab3\nSHAKE-128: e2b17619f731ed8d52c09cbba6f0ef14cebe0c25ee74ac28a4efc08fe7052b5e7e0e6a95f84dcaa247763215cf155060d57f84cec434213f08e0937661defb4f74876b4ce2345a0474173b9edd878ca3842508623a8d3049b8bde19fc3ca1b099a790039f1a718e93596cdd96293bdaeb7e2ac7d03d228e778e88d1ae8d774a14a0b4db44773531c2e4b65fb99697f833dc033e0698acbc3cd5859c3237e7f87c734fd3c5a93b438debff9a858aacc22e10525f12a9b25ed8b0d435016ac33a3bd6b83c556fb689796026db662093402e46a75427441afdec588bcbf01bb0ca4511b7a152c43fb35958a3f118cf77e04b4d58ede58461fc76559dd2c1acfd3cea1eb58af1eda1cc4802e88ed5c66c344aacb4c0b61d851c2d17fb3fdf59983b2b8a84c6f40a95ce7315d038874bed6e86d1f96736fc7ddb2ee8f5024a0516370bd10dd3bb8ba9f0ad77f84070f869376976ada1c1717551ffde4b8bef925403fea1826712a7e041ef611956a0face1f8ee6a6f1f6a0aaad7e302ee6046cfa53258de33f04d4d1f2afa7e57b3840df9b20c9b69c8abf1fd0328094a2f5866a36902177a876351b249347978c65e6bc9fd0e52145bdd4413809a5e06f37c2ed8ff29dab976fd16ec911bd07346d10bf5de623511ad67e989498e85ac7811289fd70e50e761c575199c3857776c2c7a9aa3267f7439bcf558cb54fc97c7e84ec3b9\nSHAKE-256: f19fb2fd71e08497fdf497a33d077564f357b7e630c2a6452514fb194abf0caae43e2e86da3fb080c218a4a5d12ffc1d727100a86f5cd8e582b1d548679af7aecad42310abd22e62aefa2671ee7ac70bc6d5a3c5c5ec038c1e5e0c8800d8447365f3ecd538a13dcc8477fe6a1e5ddd0a5455d09186945dc123b8b498f2eb97a2736921f708319fabc51fa53b3413222667ce583a9a44804f5b450dd60588df3978b127a38569e887fb1bd190d672f3e608966626f30733047d90f9e334c71edd5cfda174fa27d9c2ffb91947714fc31d976be9557369d7c369b5d1f9c65758dfc6c9d21b36d094cd668c906384b72c181458089e9aefa91932d54c7da2f5c91ddcc6e3d85c6161e9a3f322db5efa9f4388908b083fb20e5329a2376f07d3b7e78072d7d53d6b022ab335d315565189ec47de473f882bbc0eb602ea9bb712c604c23df84cbe82872dd1f5512ebaedb01bc3656162d7756b656f022c51dd1c839e3e38b394d0b1f63faf389cc31776f9b0d83a1d9447a35657b592a8be30220d4ed9bbf4212dfcfaffd6eee1f441951c09f2e05dab7ea39172e1f3e0d27c852d762ae384ce5a0d413f5530b1d03a3fc3eb382cafa4f0edd07714c1d559720903294f7ab2ab95269dc36831f365af8efced43bf0a0464bdcf8d058c0e5a935aa1fe94af6d069aaeed99bd46912d86f9201d19d1941106f2530a59aa4d5756bc11b6\n\nInput: 4387f289c912c2f3ccba165cd5c8e0cfbe12b19e1b422ea74d6df97a374c04b58f030a40afa3264c673b5ecdc3f2aed201d5721b91d8e4739db26697caabb9b30ae04cb67be82492e34a663375962bb663f3aa8a6f1551e42b59b8763599da4cd4af0d398973d0f4cc9063fc3aff12a1edd69714bc5e8e0ffd7e0e963567bdce817a9ed833593a47d79f6ae59c3ef7d23abf0af3ac6963223a08d1badd23fd4e3ef629123c61e0850e548ff74ce6cb732f9f19837ae5ed239aed78307fb58d9a4861773fa0d28612dff5ec6ff72530e22cd3899358ccbd5349fa37bba12acb84c257e757568ad99635a0eed9\nSHA3-256: 3d72262de24abb59cf024bdeade1e8fa5d46022e7662b3ad6da69fba023fda6d\nSHA3-512: b766933cfd728793a01c71d3faa9ecd8ac9b8428e7f297f4e44ea5c15e9649e85b8b30a856c97945ad690c50b29eeffa6c5449ea59d54b092698238aa559c5f6\nSHAKE-128: 6e58f6120d3d352fd4b2b464ce1e2bd1c5daadc1ce069ed947e5f47d25262b34a1ebeb2688283693dd40536c545bbf18468b509675d8fa79a50aa927be67c14dd8c20f16b119580fda29758abca5b3b8db715776f80f6edd722ae16755fd4df51ebab193dbb7289f7546a0e08b735d4f9a46a0c2", + "0256531680fbd5bc1467949b698b314b2cd9d8fe246939ab8b4464e37cde9aa9bab0d3628bc224c7783d3916dd84d99e8443156640f906d57b82df31537fb3eefc4046b1cb7da3643ad8654ce12e7dcddb26a61d017e218b12e45944bd589e1671ede96b5a4a215ace8af0bb9ff3664cdcadac965128c0ffc706e7fad3f7798b20eb49ef20d0c3f57df04c26525e1ecbfedea0ff3811440a15ecd610943149f7bc896be6360505e3b3733299b14114f2b574e13880e60c02799206278d6bfb30c1194d4de187652cc6bb5936b2861590de33704178e9de3ce56c8b77ab991fe5888fdaf5720f6bb9c7e6ded2589ec057445541f71e39649cb82fa8b419ebc57225c2f415a468102e5c4a221a40289f066e27701a62be8da8c5b6609ab20dca4d75d536a965fb243d2a90211614ed92834ebd94eb877432acd0e1fccbdc2337f8fe4b4208831be25f4e320c6514d3ea1c5fefe4e1a06f634eb6af0d99e25c8388e17dc6c645ec4d9b34a432f3aad922c0850ece5986f5bf1e81c8c4733f9805cd7e2e804da1af52a5c8c97fc0\nSHAKE-256: 7ba865766bb4eae18222e21845ef08d74763500e946c6ea1999ce04ece7be33489fc1e6b88784fe06c0b1c4fcecfda9e06544e0fc45f38a65262264d8118f6113d0956b0ae68859465c61c63d74e725077bed988eeeafabaf40d92d725934a8dca2942e427ecc34ec1df6756cd3045e5e99a2b232f0cdfa3e92be8b2784e5db3fd93fd6c72c581c67de7032ab30bcc23a02b8c1ea1fe6293ff596f604fcad9c0f602a1faf170e178a2cf6cf983d02090cf363c25ad5cd00357d5d259cc7aecf3e94e87a8af915bf9ed5fca7201266db5ef4f007e301b920f8ecf563378b626944c4e7052cd95d348b86b8a2e2a11ef765ad008d18e3bb0ffb68c32def3ba773868b0bb9cb3eaf6ea2bc69e86b38b3e7667c1da2694fb15887738ebf5c68fb002be3a0ec74adc87b2ce30b628fb0c31e5735a0cc24e8ca63d9532256bca9b29798ef33a97878f646ea9acf39d430b6e2ee7a58d1c707ba1ebb940ce7340f03af9271c8244101ec0bbe500fb86d6ef3f2953f7f1515b9034ffa9f041f31c45be281257ca59d3ccacba947c1d403eb70676bf2c6bb9c4e6afc3905e959e72c4b129be147d99ed227253143ebb88ff004bb1f97f0f0ff3ed7bd575ce675dcd1c2bf7e723c81157fcae1455e0881724f3ea3f0ea711661e3fee85d1b7b90ad192213183bed450d9db5ece4cad2d303a5342c4738f5da0dba171f41453f93f86053150\n\nInput: db23781ee6638dfa2726105dc8b855e5a1007e882bd4f19f996e3121b03414968028d2df5eaebe660c39831184111b960d6b94b2f73a4ad53e489a60201c365e2d7c86f29dd4f76f6c8738b0e275cbefc77463182b541e436f8f33b61cd28eaf69dbf80ea6c133ca28e140ef31946fb2258360ccf700e455e3b1f0d9ed905cababddb3c460d5111367d925cd21eed9df4f1ad7b2ebf1a4985c8e5ae25561d4f1c419de6d0671e385b2e356009703a97cb2aecb989ad677933cab43d4e2bb1232738f1d8de109f418fdcf1878b0754929cb78d283d8ec4d54251dd1af46a639f98e9ac89b61ca40cae11b8d0c3d\nSHA3-256: 5847c5f55d5a69ef026351c95fa4922b254fd21de714b371df2e570983a5ec2b\nSHA3-512: 4016fba6114b05b831b9e3c578473f6e33196d7800f80abe992af21ff36ef4e9803674b26fd6ac1eb33d9c275a622ff64d7077bcbb9f4bd28caf3be8a4caff4c\nSHAKE-128: a249c1fd840e47fa937351342f21b6bb7e7bd3855bf13d86843538a2c822503e0fa3fd3d71e1cb895b8dcac6b5145c9c02e3b0b9ac25fd94ca5b6492dd8c895164da68c62c56887aaf6a88e80272f43574df46946a79626ad566b5d1c95c46178ab042aeb8648844cf5209b361bc93053beb61489471018c95edd5163125f62e28aeea4af296fa3645efcd10d29e4209034ecc98af0ee038d209b483e3a9a791062bb26633448b94545bc3283ee607178b595c3e9057ced171dc1f0c7959d782bfc9d78807c2403bbd70fe26315260904fd2fc194d45557ff12bce96da005fd1464cadc9c9eb8e3c69928cc7787beb98de3e73f61dccb6784583fff61e34ca364cc55df3a1af610b5a0961458ad555356b064ea1fa69ca5848937bedcf5149cc292237cc8f7e038dc774c4264fefd410f315b3ae852db82729de69cffa9bef31da86631297cbd934f232fd7b0a75bf1da03acba0ebd39831815b294319ecea8d736a081f2939fd495dfca181586442c7ffc0d9eb20c900c8cb6b3db89036917ee7af09229be2c201c02c57f6eaaa63e45aeae95c42048ed455b9e1f905ff671423ddc2cc03ea21707850d9a046a0f0a89f75e8236d3f5959133fcb7b374b6596be4a6ec0d8f60bafa3e14997729a72747996e7f8221def9933e6793d53dd34ce52a764d28214ea25827027dce609743eaac578683ecb94483b40a25fc0155a2f\nSHAKE-256: f92dc1fd8947a773fd36ad1bd62a90f490e9d9a777b1ff1f60a673ccacca16fa6e096a7ad6dd979099b8b8c6416d16f997a003470224d42b75190c38f8f4b5880633999b7cc0b6278bb954aa6e70e66955204723bb4d7b69fcba898c05b704a3b0606ad1be18cbced6d84f2e1167a37b60ea01688f81720668a45dc46871f54e5c1f9f45be6b1e34e2515def14137a349e4c50f21d6e21018a1a9825a31e450b3e319fa1b9b05964cd3e7ef7202dcd64687c7e9fd95b767cb39991eb17ec7c56b26f0afa8b4df22c6398b2230ecd34393c1507fd50bde15086e118f10f9e5cc81eaa3c63afda27bb998f960c8d3bb85ee7de1a1c9e8c0aeff5eba4a3b20ba620be939616097b42362bb2cf81f0c436580078e2ff975602d793e7b15d3a6409ce5aee341993100d34a5c77f1d68dc84333cbf2428b9ab509e853225100441017b171fccacc321778a1bae6f0ad08ed223815b5ab2aeee5f117eebbfca21ba26c3b420fcf97c4de9132e193ac16391b52fecd9651629ece5f20465e95b93ce264b0134f5ec4724da024876ba1f2f4402c45e6a9ba8da82db370a4677ea57c9e0f24fc22985f7a466b059ee8898a4c059442b298cb2d3e382363735db9b51ee34bc06b202b596b2e2bd53adaa9b096fb555f579835ed23af4acebcc6274b05cbed172f7774c584323d50e8f093fc7497ebcbdc433394f084a005718d4c585f6782c\n\nInput: 3a9c58c10c1131bafd9ee70b9a3b440ebd90ac1b24e319f6c046b6572ec30df62f88c24d1583fd3df4ea9b4eece02cfb681e24add0526f66d5c1cac417956115a4b90fbddf88fa8ccffb12ad393cb2bd64ee633ade7525ebdd2b48be5b6502492eeb451cf021f3b9e109ed8004a2a789c999c8c000997301da8010358ede8fa0b6a6d4675e371ffd409ff42c25e5e9c163c440f6870cb9d422b37799f66f14ca136dfaf24049b1cefe0f65db9326146cb1c51137c37b0cd0b71f29946ab17b863c04f7fd92e8fa6f5596910838b6376cde2763af573206e8b563d621a0218dae3558d777ea465d14ea3774c01328\nSHA3-256: 279ac0a223dd22b939866cb544e5f3f96f7cd101093c8ad2b6c3528ad91028ba\nSHA3-512: 909fb3f4b8f99768622d26670d4a66787f5f2b67ee7b92efda1ed906a34b476a99638e5a2951e619d74367695f7cace34d36c1c47989d50719aa2e52a60e06cf\nSHAKE-128: 4fce6fc03da3b5cf1569b9f073297cd9f1983096e376d78dc3cd042aeee1293f0aaf8667bed005be25264e524eba485fc2c692685d5ca4e4290ffec33d90e11dc134a070796e247722625dac694949f525948c61325d2e8148cd16683c01b683fc639557ab77791c07d284f9f16835f13009eeaf07f4557978a6730f03caad982ce89affdf1bb37af56d274b7071e369db3bda3435ee0942d24655b71671bbd6a656cf76ce2c668ebb377b7f9f355bc4f8ca6cc4cfe4ad06539d02b73b7d05db91069ba7e98a18522921c213dc16a6a13a1b611d1ec505e8a461ce99d1786a1394d2bf0a614cf5d61cd0db03bb023f21008fcc71480d3f886bd58a63352c2afad5dcf9b8791bbea40d2f76ba3daae4c103f45c61d6469339ac1757362509906236cbb10b302eeb25b560a86a617af89a0837758dfa88002df2061c1165962bb5afd8c3d1e566be384add9a048e0274383318e62c5fa17c7b85d0f7093111613de15f596fe69fd37dd836c6f435aaa5b91f736a9f3f5efcd48369eae8f25e13d146093e04e9a9bae58a56499a4717de51c667482073b8e1d95bc45e294d7b444f2b8fe141b8eb36cd1e61ac86ae49b2d0e1b7ee2b3cec061ca519303344e3a3d656136bc8ac6d2e097f9862540023f05d5e59f5b49c4d153810c581f3c3fe6cca3cd547d1ef5838db1f1b55c7688232222e5043d3c95c6a211778b51e39840dda\nSHAKE-256: af298797ca68f772dabeca721d602df61d312bcd9d472db83aba1ea84980d6e7315a195255d7edab15e542dbe8ae5b330bd61a5c855d4a9bf45f0351323477b4be3c24fe29ba7e897cfe4872f16e9fe641860499716b954beee0687d0b26340c3aa31039aa71f1f250b4b81e9f1cb3b45b100bf0301d755d8614f28bd9ab5373fb86fa51ca4a51fb91371d4d4284122e6d6a25ecdd28e88b579b5f6cebd76f5acb6e022bb65d40ce9f7d32e02cc66e488caa6ae6b34c4bf222023653ddb71aef339f78b1e33697343b998ee9d75ccbbdcbe9862f258f7b18df2e7be379401fa574218cf8c5d58ca52d01985cbd2daa761cde4b6b9db6f635c6aa1f8ccada6d000019bc2130266a7c500ae42652eb96e778fc41d73e30e25770849266827a04634e959f838df3a9dd7c75515e47424cc70f5f37c7f1cd5f486fdcaac4de1b0e5c285696da79529a112f034f43273ae201053ead1b45c26c2afa3e06bb2baefe0dbadcf826aafc6c01e3fa32e5b0d145fd01d914bbcbc9b7af506ca567af21df730ae5b2f9cbab8b939d961e4703128f4c9979cf810fb0b0d465173f924740a764d6230c5c72704ba9b1ed8b6b73cb8b12c4da960bd7904cdc39ce7bd35d24b55a6942f234eb53fe58775d7b29c8c73dcc6ee11c8e680da1c43710fa466cb3d151b90e991ff10a46977b48c12629c29d750f8fdf3d5bc851357492dc610d0a5f43\n\nInput: 49066d0a4ef8dd84451ec290349774ca7b9dddcfeb12badb2119a05e2006ec80794cb680022cd6e31e41b418cc69c6a4a427b0dc1fc6e084f006349ccca756752ed8b7a8ed511f77d3b96ce33e3293355ac1c2f6e18e95a13beef946dd7727a1a5159a50ba054049adbb4b767a651bc1544b7f812fe3efb63f48359f2ecd58a4dfdf45bec9c035cc50ebb3676dcbd06222db837e2b837605c022c03e2ba318eb03451f6e94540964523f04c17d41710c30b51677c71e05124621b196f0c325edd3c601f2913022a83ec272d210af2be1e139b581b6032b48473b0521c1be691486437817c723a3a3b4a65fea0afb3d\nSHA3-256: 5944144da3149c34e15ee77ae83446d36e3c1c89cce66fbdea798751f3f7b42d\nSHA3-512: 6a31150580d30dabed6661249e779b03f22bfd5df06774737b1787c5af3ff2d18ee1acc9c3fe84251c7e86020daa083557583956df3a53ddc71ec9759eeedfc8\nSHAKE-128: 9ecd5341bd1092c94a0e95630218829b014028d83628e093bf3ff5bc970b2913bb44bc90c54b6d3930372b53a804c946b56b5a468ec7cd1", + "52a2fa01eeb52b4a3ffc8ca76f715ec5ed2f036924b1e9c24b3044a7d2740146eff4a6533ea32464373d8b5960d8cc359d99c086576c42f68edae77ab3406f861009346bd387b3e89514210193c7fc0f516e2850b78ef5307ec2cf97a0a4c0b984e0f4f6a8626d10d0d24647d22b7f73ea45a7aa356a6503af4aace66fca136cdc94fe02460c03d8d8712c4e14e5287a9af9b549310d4543791e21468f25d044c401c9112bcc63c659c2823b826cebfbb730b14bf6c98876e54907bf2859266679de48b81374ed590c3f6ee5ce84e7bf901ab547e89e8c9e4417b69f2c72e41a255a0c46474bf994e7d4e2b327eed8e3bae63586a6d985a82c0b02da2856cb78494f647fc6a96672261fbaa5c8ed7ce8c185241a2d716b5826b8ffcaf91d7d3149c18c453524b3087236e8ca7140a558de8237b6ce7bff0ecfc8bcb54bb618f11d730bf5e4d46c028b9ac28beb09c17ea0f0122064bd66f6ac29c74ffb68c41c7b2b5820bdb56e43922e4527aba17d71d44aabdb1ce5a0824f775727c8647d6227fd735a8a57df0c32ef655a8dd8adebbc0b9a2aa2f4ecb7cfd16224b9983d3712c6dedcf0fe9d5ce470d5ec32d626172d83f70097b95f397082aa47b7e21887ed137ff8db2b63882\nSHAKE-256: f23ba659df103e91dbd958e3de3654ce680b666c5d9654cf8ce6391357e4559a2355151c1f5b7a1b586646e59052b2aae37a51180500af9ac72a2ffa93778cbb991fc1c4b0789dc4d373dc1c0fe59fb36ce4ce2a1bd1230abeb8be5ec0653905dce67bd5e198c080c0459cd060c566d41f736b54f6fc33ef6fb6f169264634c3420f2b34fa778a85809a47bb6bd620b881f977eeb634e4586a3b965b03c57b9606de8bef492c8312e4f1ac6bf22fed5296968528b0c632e07a90dd1e63cee356bb86a00b3bc492dab48829cf7726787be741a6014779205540f286e1bb45afbd0cd0ad7147341cf6fa5a16014b376b2d00a3d040c8d8264781f00a145b31e371f12d6631804dd6fea14321cf7ba5e4a8295ece64831a120b775ef3f01eaba8493a5189768912ec487a2834f421dbb5e988c8a11a8bf9762a851ac2d2c4728ac6caf3b23014a951d65d0c4e1118f859ad0a4dd091761cb44cfed6f857a945086829f2f0a01ce54eb9a6bfc2cafa5a2427db50bcae7c03873dd9a3936b9686fa44e8bf14031d5cfbbbbe6b83c5e3300414f7ebba9d1283e4e2811dc1908e7b6ae4d52513c22d6503efaf165247f5949506afe9eec55a266b8b4537b21981aa4533e532673e822453f3dfa195634f65b8794a85d421b701236e50fa59567d2b6899534fb5d1a42b712ed3e18b742a61deb5eeb4d129b452b104a6ff0de09ccc0797\n\nInput: d0d3a2f121c9f6c2f52266f520dc693228c47a5ce36a2b136024c6cd38da94f9c1b69d50381d56ddab1a71f64a0c526ca70000a8dbc34e1022bb5e83e8eec8955ebb66542ba2d6d471d8897d55825ae3d2cbe6612baa6c3f7ed0483a7e7048970797a70e76622cf7f38399f39e533a30bf7b5d1e65012c63c99d413b2b1a52c7e8ddcbf417df9b5bd6ee9ea07d2a66bd81905df3615098e8bd252ced871ee2a619822f1efe412fb2b6c511b62b06953630c089f33d26af1a3bfa8289a3638f5ddfd3d7d9e94ab83eeb85b6d08bff61a04f0dbecd7ca0f629459a2405c9bcef33fa980953585f68ec14ddb89ccd7c0793\nSHA3-256: d43b6e294a5eecd1f48b65e321e232c2368b5f43ec79469eb134498d9fd6c6a1\nSHA3-512: 2b71298b796db056378bcfdb178cc21c15be4fb689e8af1f29296b11f377f361dc292fc8f87efa10bbc7f4b513591f468a33688c82ed458d0d5079a15045eb0a\nSHAKE-128: 2cbd12780dd57efd0dfdfe40300913c5d060035c1cd3a05fcf8a078cdba32fdf5b45aa757d340d068cd1ea22596a9ad764b65d95836b0cd93fac228a28b6dd51d15b9c7ae3d308cb63d6c060832506ddb11c28cc4456850d78520a444a9df772206e79a92220251240421b323fd7eabddad1331ee02aa64c191a9560ccf70bc885481a8d3d6128090930ff3c35c6e8accef653d987428cc6016fb1540573f12a14f62228b3fb10a7f32260c4453d34e7fa2f1bf038614b22561d19abdec8637094a65cedc9fae494a6e30d812c5465b557f20197448d56aefcae31cab49ef76f4e36c13a1c550729189a138489def8e8644296224b2a3fbe9c79ea6e76c68807f1e9537f81b3691f73bf608de157ed264679781ba21bf8d00709e1e8c9810f7390cdb09eeb115e12312c9d7aa1f1a29d85476de6402279249bf8c44dc16b7b4f408b70a2e14411b95848d5f6b6fbfd7fcf3394f4d7b95c8cd8e26e6c7487eef6d18b39345b3862d58d8dc6f837ef8b2a9fc76dca76fd3d74d217f7d7025bfb5116c9918075b1418d15511a81bb996052c43ece5edbf2898f95e5adeed0c97cc0b6879a86ad5aee463d3f234a6547534a5d4491b6475a8507775c8aa8a59c5e9dc2f70db11d47da6553701a4244c387e9afa83a77085d51cbd102f4a299167dbb071e917ae38e494fbbb1cd2acac6e9ed6a1f1b9364e859dd7ba4e59a6eefbf99\nSHAKE-256: 1c2d70ffa422b262552d32390d01d0c4ed5d1e1060bae165d4904e8f4782ed84830cd63771255ac2314d4d791d686ac952b41cb7d246dcbbcb834bc8105512b1840e32ad4f34b5ea0e6a8bfb63a7f2b28a1fe35d3f5fd975dd3cb3e2e61fdbad2fd7d42ef393c249d87b708329189b2ebb056a3679dfebe4502152cfeb53433ee769a0909ff947c45f839439cfedcd2e193a24bd07d249c30f2247ac0d27ca558a2e9e5426395a393287c7e6e5749796cc74d779ee004d1ce1dd8b25a156b3be5859a6754c23e41a9e785bd597c90860a5828db0ab225f7403077481da3b196ca4610989cb0becda4551e0d2747a7eaf26c3b3c82fc0a980f6a93d3a807c65a4b1e098019e55b528dd74a4985dd09e3dc74bade7a5ec35333963f7a159b5aa4b5b4c230d80b534b53f2f62744dec9062bf94ae0474d0a9666305a17698d467aacb8c2b7967b60355615614b90a54512d564619c533cc3fcdc4eb9afcd012b591019c699807b465ff68b413fcbdd60792996685f3ffea5bda8cedf86e3620a74af659d90235f919c924ce126f16667d8067c3e8c377c2b1689258da35544ff3645d360b12a8273bf25c39b2258ff0e1491a18c03c846815f0d5dc880843c10045b03c73400efecdef0c5324b7288668911ef812fd51d74bd23a40f7b52be19c35ca036d53ad5843ac50d126e5f4ee7492bb9f7670a7d0a5439802561aafa29b78\n\nInput: b5ab7ddc91c7088f13afa6c026aa6aed5bd44ba3a1cf5e2393bba0827925b3f4dbb724208d6fd5c1d9137611551644b813daade29bd252e1d2a6a01aaf9c7040eb26ddaea710869a86e2a7e996ed56205cac0bfd6bd27b9831a390cb07d016f61ef8af0f58d90df565f2dbee82e8b7822e9962c1acf8c33cf291094cd25b276d7f8c0b442ff64028772daed26f3564eb0a4b5815323622cd6d5625a4702b324cd7f377a407350ded517a12fe827c036c9d023d36ade34a5c00db7b9aa711f5a202fd224c1b42a31bd9a922d7f106434f49445e1c1b98205e79ccf36d6342d3ce8a6257e9338f2bdee61b9c748d08312f28\nSHA3-256: a287e2a273a2259e003671e81ff0c9b8f9de868e61ea69ac5fa3526adb61d2b4\nSHA3-512: 11bb74976190429701f29d5ea1cbc7a0fb4c5292bb49c2e3b730a1a2691e4f4536ec2689508bcbe83f4a4439dec497d33b4f164f720f822f74656fb024486aff\nSHAKE-128: 5cc7d226995a96da1d8fcb5954b191da6c0abeaf09fc61386c7e43a92b7ae846d9a1c2d5b41874c052df9dd51920d0ed93ba758e27caac91f6614693fe376adb9e8a42dc49350fa8da57ce6e7f715fdd9927849a137e70754376197ce14a5747a85ff2282b5ddf897b444026fd5a4d661a82df4759a253a45223b281d1cb0b052a78303bd42ed042f502f409a3af66b08676ffd479189e494583853326a1ac810d0dfeaeb6bfd8dcfc4f2ffb6e4bd925e9bb61fa20ee8a35becc0687a1142e179527ae8535537c9e1b0b20321378957f8e3f84d3fe889bb37fccc49807f65b3a0785e103efdbf4a4da7de4fed08177b0ec1dab6d5b387b592d4bdadc196f1d4276aa92c842ad02be03f06e0630f7082ba9e3be7b5e56fec7b9d9ab31c7842c82b933c7ce3ee4cabb5d751fb5d8e4180fbc50ae07ed5382005dbbece1246ea6e30fbb7d7089f8c885435633e0fb0c8b56a4e79d3fd7d8a7d0a59a82e646bdd9c02f8d53588a265a1e895a6b3d62574f72b48ec7474347168a393df46042ed40cd4094115755ddf4d460911d4f32b917d5b21552071bd22592375658ce9a4aa44db70cf8f8d7cc3f1a3fb7f8c138be8d857b30e0f2011b43e6730bde5af5ced016e69bf94dc74a10f2b55b9d944f2b3601888ab6900d87a77f638cb3e1cf2b443941f0c29932c5685a61911bb6dd66fce8368ba6ad7b7271867d763e6974fc4e62\nSHAKE-256: 9959147bcaf01d7706ba5413f2a4b61f11b7bc3b1bbeebfedd473d6d4ce8fc63fff53819eaca4ab276689ded2a95b4b086d7c02de5c6a83303fdf3e318117d98460b679b864a661b394c1915f4c4b98fd5ffa458a37340f948481c01310c680d5d46793b74dec11e738f0e3f84b0fbc79c9b925461b7a0938571abe0fbdf4fbcdcb6e97cfae07c20732345b21d3a24bd373d14f636a0421a62e12b1df1e04968bb8573023fe34f310f487deecd6b149752aa5e9f42513f9f0df59622823f5c957ffda8f0e9a521c1ede963e4cd63acad8a21bd49da05db44d806a8644b0cd330fb4401d9d5d5a98b27a988495ba2b75a45e178610903b373982df532eb39370f640d35e8a8476d036c53195ac247e30c3d4b3a0eebc12a658031ac1c3eb969bc47c0324fdb71cec67780eb460d1476bccd476cc07a3dc5fadb6133059019d7873b4906ce5a9117cc12dceb16fa164af024afd301beede87309f82f6d7c361534074cdff3c73250ba565a170455937b41949ac446ace264430cdb554686ced220b47a5ee953cedf051a910d2bf7e6105cffd6bc0cf1cd79f1bc647cead649bf672a89c2b74dc2a58b8473943669f3e40abc864d4494d7c34ac40f7b7035741b70cb704c30aeacd8846c07b8d2de527d9853fd8d206551927245ec1b9652765696bb282df1329522550fbcbb46226ca307348075a249757671c1a697213b73069f\n\nInput: 45346d9d8260afaf991963dd54ca4e6c26490f339cb82fefcf97f12abc520e1f41e1273490fa737ae407c4763667cf0d9085bf14ae0b8c0f1e1e6693e7004deb9eac4435c8a5b9bae44d3c30d45f1287228f7fc5bb8f66031b01c17be0a05b759a4eef5633c6407f691796de08d5598519b3501c64f70f0cc27227045e72560ec2c64f65a1ce3ebb55892c273a14aff82aef8579cc96553d27d27b56978fed66679893cf94421d5965c90ceb38c3e21da3eb0bf610fd0e736d8fb17d71bda2fbbfb9e124f4e98169a70a74acaba91d96a0b38bcbab4e4bf456dd04cc9062760b32d05183aa60911ef61844b44989acc465e8\nSHA3-256: 0dc42a6c64871139c14db5f429b5828164a678afa84108da99c5ef294712aacf\nSHA3-512: c6d0dde725c42081097f77960625b79bbf96a5972bb045847ba1c64553265e8e9a9a6231993370cb54084cd35f6e036e377c1eb7cc340800", + "764a0798b013d7cc\nSHAKE-128: c8f243bf07357e67eee9167cae9b936995ab62ff28db3595119b190d9d400c178de5e26ba5aa67f3556c434e9f3649e8b96030d8f5949fd5a7ee9a9c726e39e96f789ed537801d1983ffb132d9b73bf384b3e706877d112c3186d78da182cf94400e28c7cd2c42191c6b510f833173d63a862e1faadf1db38478beb57528f6d3ea06de37bdb08615e2d8719b49014441ce26b53d502aa727a75daba39afcfb677ee1939760179c198ade6df425c07726dc386346d589c7d2d8160429f0740f4fba4ca9b127b0284287c4b76fb26710da87ee73f9aaf23fd58a1887f37312e2d18d4e92c967e8d4cd4a40fb18028b4f531fb837999c7a2d46ab4b8244ce807dcccd6673afe00184e4b5be27681719abfb5e5dba814e31c81e1289ddd0decfa208fd801442ae9fc39725d26d9c224ad83e28f6cca2155a3df57ad6e770c6ccaec2c51a4ad45c7c97b62bf52066a0034a56f6da8adba228a35b381a143d012363a3eb1b11480791715c83190e74dc5d0113582ea265f3a5d21f87870c825d4cb7064091eb1a6c23427c80aeefd00204a939f0814bcead0d4c1748f92c952b67d727d3a63c16f840e1e7133c8237df0db215b58d68c20b38a162967c67d646ef2ae3f7cb2379d6747d9769c6b7fb1b4794449998afce373d8c5cac060f4a347cb58978a365486ee2242ffb61eca5916ace2ac44eb72d4c48f30142814b4644847917\nSHAKE-256: b8c44d49842a93238c6491a9f3921e523a6dbcb7482f02f912b2a59a8d1892013aae90c27e723507729d397c593177bb10a453b35c4b5a66977f57ecc75f4783a863917896a7da96e81910b44d5586d504b4b8c1c292354b93046e7f4da928450a3978e530184d3113d3736106e2611504dbf1c3b0013ade7d804c0a0cf07a94af710887f31d822e007a297122ad6bc119f4396f6b94a8de8967d5308890afe25aa9d35dc47bfc36731df789ad0ec22229087f37e4d16aa801a0f2cee8a574da627a0c7c0fef65077aa39010218bf85e3f5ad58588b0bc15ca7c13394c2ed7530d7b4f7815150b243e3bdcff9523411590a5a44ab87ec18081ae003b439e5d95f5ff19c2608e4d4f79b61884dab52159b20ea29de4a2c7c76c34e993e8b93807583c7981af71a5c94d488b914c02b19ab4eb73842ca2319fa6cd846ca5e079c85e23226a84427ca6994c36ab5f5f2ba159b37e1e6a563db5a950abc6e0aa1351ed3b948f848acdce2ecb99e3e23d17cf38c06ee8e85e57bcb524c9cefaa6e823660ffebd25b0448165d33b5a16533900949ff2fde756db95f8be4d787fff7395dec325983a3cac486a4cba452a29738364f8c635ec72254e52c8451153fa63a5c7247e5753071848046e5bab1f02af381f9e43736e4fe6e3271b1706c969a73965ad3ac779926fca1e9f82a49066d95c35ffe4f620eda766d40bb4c6f7dea11c\n\nInput: 5ca2d0318a1decf3514e71290636ee4bcf7be5cc6053a1a3aec37665ff3e1ddaed8e0e8640f328d9e9b09bc50367b09871b578728e43e0107ca4928854535680b4906c16c93536411234d2f8fd18a93da84fb41da5428fd94171e3e0c0b5aa8b079d7559cfdcacd3e60253b794aecdb796c6b83815f1597e7f38259eea795ea360fc44ccefa47cc1adf030a1ab5af42b2372030b96e579f7eac976425085060e347a6881c75316a6cacc20538203353149188138673b2539d91ae2f13005b5b1e0fc9a3be94777d4763be0fdc871beeb1fad082dbb2074da4cf56e0af1135b93ed3c8f7d9cb13f76d41fb3d4674ff4595f03cb\nSHA3-256: 93e74cc55d3f3141db30ce96b011b25c2779951930ea7482078cb65a68679fd3\nSHA3-512: 2dd6935955c05eae9336bf57342a3c339e9fd4fee60ec886c0752f46631284cf4ccff919917926802bfd7318de1f7f064aa08b1f264238ead74b9af5c7dcde61\nSHAKE-128: cd9915836c0122da2bdb4b98496665e1c01627f96c558583decbfb41982a6ca0d756cd41be3276db4cf10b0bec1e0ed2e665ba926125748016e90a008b2da8415196e1b53fbe794c67d0bd555d09e16c73d222723e8eea594c6af31d1691869b68bd69e3d27724851cc474aa818616e44205c1499790eb944b8e3493174e0c7cc9d9573ea8aae6123f86bc0abf8a8ac1cf202c4d244b839263eb3ab18a0ff679cff4d4e1a92947d853e05d8990ec00e3972e01c0f6fdcb630004fc85d51300fc2bc74206c617088803eeb302d1ab437338b9b98859da91e9999562489c333188d4ef123b1bfbab33d9b99631ceafd95b447159df4a6850f9d16ed95af249895343cf67cb6affa321bed8a4c12a907213f042be11b8d9415add079dd83a764bb6786764ea813559cac299aab158b087c413c199b037b9b7681864f102d55dc762841a7a93269dde3a23b1ab2d971a145e8acba071a70b4aa5817561d54def6402b1c7c995307ec4f7870d15cb18b3d4979e28431a511a6c2b1d08e38e0bdd5d063f1af09f73e24d80d22f2f1c2e8bea5025e9a3367d4d3244d678ce100b2a56a653e8110daf44118d2495a336cb24afcb2aa4f507f8722f2f8f3f0a3dfe8c006a03efa193323d5dbc1c6950335ffbdb0f1de27e8a4620b243dc5c1109fc5091abee42750f0cfd3a767bc7996f651121e5183c0d605fed9da74f4c7a1ec1fb53bb\nSHAKE-256: 6ef5278bf8d6d30e0316a67246913d9c921a8a12c4c71586b85ec0e201b487dbd7e104001c1c263cffb4c137af7b7b0bdcaf82167d2435344b960e5bac3b66f72a6d0edfbe868f6d77d3cf234df6d86a7a33a2da7b38a88ca2329864937614cb008ad53ee37c654fe27c9c515bf50adbf95f16a9bae7a93a2a2029fa1af9a0365184a6f7c1db31b31c1cc4ab732d0a7590c13273cf962f24902b2719b22ad32a26233b570669bc7d7fded6b7d16ed94b3e24e1f6fdf4b7012081468976e34ff09368d3bb8aa7e1fc2aaa16c017e58ffed34445dede4ee3a5c92bf92380cfe3db4c11843b1eba9b923e216fd895c5b78f4804450ef7478aec89ed3eeba580e70f577df791ca65953de0717e31ff9088ff51db34370b909ad3e8227153de574a5ed3d9e754b6d4d86334fd24f7b19e939b9cd02eae5e1f890b0faa93f2c586c6db0c0c09155c443d8f74f156bae728c38eb357cf3f18f4d1f165b74093eb0d69afe3704931a048d3a90c0683dcac9084eab4da0e7554cf2116161d31a79af7f01bf0a680269405d2222ddd511490038a9c2e21921735ed2d12f5be19684dbe48dd002f163041b63501b7995063ab41da29c1d1924a559e0f9f68e6109bb1486543e9c5ad964661603a4308e937b88b88193af2c8cf479552b3673261fe2d5b5da2af9ea9b5930ad3f21f0ae76f5313005297ea202de032a614cdf4b6765efd7f99\n\nInput: fc902b11d00a27cc0a1dd7ef8ba6dde671c896fb2a4ef5811d6f1f38c2ec7472c4885addc3d688f45d3b8c30109df4ab40d1080f0483b6d56f1ff1c71b3fdd04beddd4d2359fa1a9986d9b3d28e150a14a83e4470985203181bcf6a2ab389bb100fdf4fd80e17da69f9853c781edcf56c9d7f8b5db107ee42432e777fd6949a2a252ae586ec5b5643a878571246fe3d6334f8b43238fa34c85b0d370c334024f471c21a06f7b5c8cc61fdfd1835a00a324a5e370b1954a35a9afea993475d7d79ec29c21d13314bd90e1c3932b06ec6eeb83548c616b61ed35ed98dcf94bae97a9d535fa8dee9542a85c9ea464109732c36910f1\nSHA3-256: 4cbefd4fd2add01f4ffeabe0c7c2aae0d3942f38ebacd202ad80768c5bfe337b\nSHA3-512: 32e2aa3facbb9798deaa2ae54de23e8b7f8d8e21a03a7f1bf6c41bf1b633ec4820ad6635cc58ba7a6b8a281506c433780b4e8eedaa11cdb63bf0ed7de9019016\nSHAKE-128: 7d9a1f990c42f654061fc4b24474f7d32f4e0a5d05b560e11666a7594db494600c1e9645025be3827d9c5a49702dd826b32ee41d610eca594ff820055a664648d4bc0ba86b11d3b76a661d2e82033a1fd9176bb2c832cf405138e8e793c6b3a8848a82842f83e8379eed1fb130f8d537d680c511fc1d2abc62fe16a320f91851d19bcc0f500ef94824b45271c13726c2004cce2691944a4072062fe94e36b23f2cba8393a19fffd343e211a2d2fafa31c29726421d0c007619f0ef9a8feff763172c3024f2bbb3ea13d6da8295c079ce23b93f62bbb5bddf00670806bbcd058171e25d2e076300f1ac1f5fca2c6291b93b29356eb442f50247d89d23cfe2f4e64b498293bf3d7598044f25e5d353a87f4127d06f3a74c792a7faaecc13aa4b76794a020d863a6fa12f911408b3a0e34d71abb9dab9527064aaa2995378cdea84f6bf89bf6c3ca30725552c42ef36488c4024289ef5581324afe03f1fca7f5f05cc000ad3aaee6c583791cfa2549fd8eaebaa3d5d61163f2e1c229ccff4b3286b88666888e598946f8795ed4acf9279ac0b4fcc35ee7b1de130d714bcd6b7db41b29ed72efabcccef04ad1669c76030f79918c3b08f9d7a37254bc2c7df7eba4264a89f7dbca4e80db787b5dc6eb3c62c85379cf06b15782401c276a710d2f9b1e356bf1ebf5be572a077613611958975cd81c857bda283a80c5bb26855cde1b7\nSHAKE-256: af2eae5e9d4e5a3b03044285d2370983b179a56c1fb69a64bab96ca5a365a87a973f14887b7f5fa64b0478cec273e0c834e41a409053d704db6adbaa8c9ca957e0943be08b285c0bb383123bcb954f1ac87a9b17dd017dbe84cc2fb425ecb7e19b13dc53eda4363051927e9cda6af4c2f6c7e234a542d41f942978ddb61febfbb7c3a874eb58cab96f7e83d7080aedece9f427288bc7547e5992370c4c859ee632a5b04f5707c1cbce35dee36260a5f961f7a74f71ac9cb4534739b0ea1835ff4ff92b24dd1a01a45cfe2684760007ceb6d69c3f33511632803fce9115190eb4603dacc23030a85b41357605e15d457704488a71aba01aef0fd1fec8c889acb2cf6c49c31f3f0c41c6bd98e5585dfec9885ef2bb9f4f5659f6f78d910497498c14489b82b5af2f8ff1e874ff43f3e5e55f94f58d40f9b58ec3e640268bd20fddeaa8b37f0bd94cb8bad407434d63107591cd73ecbb6cc06a448d4bc6c79d26bf7ca8be8a433b508e73b1c5a50a93f1b6aebd823c012f7568167f3c49314a1997ad61eb48ab7914321e734b3c8c993c6303e358222dac99781706d863aecca70cb7f83513ba833a26ab7f79ef65858c4927e17b9f2e8eb1d05923ff2496aff0b0a7f9dd82a6d4e7b6882c7bfd70dad5dd8689e012454e2f3895ca9d638d4be9f05574b4405c7397bda3b0d49b281dc66d568b56d8045d0afdbe2b9568e0870fc9\n\nInput: 7b436a5f837151816c3764b2ed1706a9f0c9bb99f0643d9910e6338ce4ac2e22fab42e99493737d4f54b471c4d93cd7c86577a1237e16debcb5980579a8c198bdfa1cdc3d6f6dfc32d61b3182ccfd58ac94e900edf3adda2ee7fa37b56b279f46352c638cb901ac0d4af218d8e84aeb5c4a1289550154e3a8554ec552b3c34952e9cffc0378654940b4b6d53ccd8b94960501cd293c076ab0c7342666c293b9bb24c9432b9f5cebfbe42f7a0b30c2a6b7abb0aad7e42f24c81110a9cb109f6d2543dd05bf4640513586926470ec51d145a58ffefd82df091fe79329f5a456adbb0646220af1d30c6b2718dd3b4a0acd6505102f53e\nSHA3-256: 2e1aec5a18335a7425916a7183e853", + "e1135d26fa62b6fa04678ad78656b5ff03\nSHA3-512: 3d8b5603b6dda2b0f509741eda0047c79970199b4a024729925abdfe5b3f9fc8866c31a3b3e47cf9167661842f6b39cac711e9c899d402310ad66b1ed8b14303\nSHAKE-128: aa46207ddc3ef07ad7bd317508525b50b47fb4fcc1dfe9c03d10cb271c07a9d3a366a09766a5651292eb45863371f1bf888f82c335ab2dde8e24b995decc1ec5385dfc5ec6871ae9607425cfc8770d800d53520820405a5cc93344d658d3eb7b5832c58022d2519600e8aa6016060da4ae0d91f6535c101e57b72fc49a4176655ba3129c4229a00a55c4ed2a815ebd5c345de58e2506d03c123fabebf369449ffad797c90e36112114a6ffe20c0c00d0175f84e6540dd30de12e0f4ccad0f78f7bf2d57a157706a82cd6659a0aabdeefd5b2aaef3d29631b72963df0f193819acbb65b31656f79c93e260aafe9973a28092b45bc43824e0f3c8ea5a9226dd4fce175ae3e79e19fba520e895556555ad0ade34a39eba04352c2d0ac62c835f6c406a22e9067da6d6663761d1f6ea9fb37642d327a244efc16e4e52b9cdf1e1b1210f6d8c10e58aa3d6720013867564aac6d3efe389980a96fdb3c952d58472b8d89371ae283e87e4c70658149ab05647d862e23686487ce9685cd0aaf0c037775f918419df6e469b2ae122c9464f1a50deba8b222383bf29a264cd1cca83a258839d5bdf02dcfcbe37273c9ee1aab3e55f781d24c6b639f1f5554d443db76c813e2f80e15fea3c1b1946cf02aeadd08ffccc936252e472a72500511d1e1772502a04da08b7ade5630c7ff8913c2febd7082e42391db9df71ba6bafbbd9b0c7fb5\nSHAKE-256: 77b2cc5c13aec5aa5dd7867a7b3cbfa630682c5e67ddeceeb6d38bfcd23c3b7459686ee68f940235d34dc2a29d09503cbbf4253b2070621d9c8996e3df592c8b32322baea145c782ec01f30e861071e7ce926a494753079c4b9ba88214f414b44bdf08198ff24866ada5b768889e306ab4f8634f4a3b92c5b297992860b7b5f44f31fb56bdd083171f6aa57ac0b5d683ae69f71e2667abd72f1b17c593457771e07697ee10556527cb1d3faa01d408d799778d1b4c6c102800db386a9383c74b61877dd99dcae9e5910d2ff5d9dcfa7ea2f09ae3329b7bb32518e130fe234599f277cf446e816eafbbc89d323a9d5eb1ad442a83f4efff7d647311f2cf49f2698828798e0e33c1433324529ced6c876c2bd5293fd5c6e46cd72c0a4e1676ddad8c76734ecf4818b616ac29c683cb9bb0926d864c72c79b04053ebab0386132c5783064f7bd48dfdb84e2985a1dd7437a91491a807c89a2bac41160a70ea40f12ac25a64ef3d57d1703b39710c0e1b46531157e33511f2b3d7867a1a36033fab525ec11a5df97f3f25d76a1b482d09fe5dcf0c36220d7cff29998dd07cb2eedb119187d620705eeb9014ec1fb269b1315c7b0de82cdbe8ffd6c1ef9be561802386daf7acdf5e6610a79c9c4a6acc8b25396beb14eae775a9f20c87349c43868bee9b86292aa9dda0f53a5c3d085d4d4199ec0edcc4773667687497f77db6bd03b\n\nInput: fa16ccbbcdd640bd6d184700b0b940af437acf958f75f8269a8120963ccd5c45eea0da9142b6699c85edfcca4ffc3f70b902152512fb2313229601bacbdb4c07716bb0ec2bd85efd4a28fa1ce314c42cfbde207a8af84c386d635118c66696b83543037a7bffed4f4d6a01ef5ef996f0f289094dd7a753307ba203975d3f19b1eb2ac131317af9c1e9de45694bebcb5d2e6ab09013f6af579d0bee8de772b5f351c3f462db3833645aeee0263717d58553854a76662dd878bd0b70c504f5afadf9857ed263139ddbcb3f5f7b13249429c9670736605e9beb9fb7cc674878abc594905fff3fdf05158dfddba27cf72e051de0bbc57a88\nSHA3-256: 572545f609a8e5288c343e2a6aa19f86aa5457088d0231814c7def9e7f36b6b6\nSHA3-512: e16ca96f553bb20f0cbb758cdcc3086825a922096736a1105101b8ef9e103c88a1f5b0867c7882bcebe21cbb8aa9d04ef3b1dd3f137a060d92a1842aca898de9\nSHAKE-128: 81afa606496fdefb580763e228951c71d42c80a09ce3db05add69f9b28e5df3a78eaf07d67e30603c9d577538e5cdcf1bd20fc853aca5713d1fa76b0f1b2436348651b65079162338078e20f932eb7d645e1dd0e77c0cc529bbe2dc9962c57f6a4e79ef2dfca7eec816eedeedf90c77e50f55bd578cc6c5fc34c085a82350bf8c17e1f076cb8f661a9711cb5ecb92bda1a2b5629730dc510b530cabcd589fb2c84ff87176f1223402f4e6acd27077b4e8e4e9bda127069efa76c1ac16f09b6b2a0c1bbef4294b79dd41f795f31b1895219c55b92efacd3cafbd4d949c271b99b04bf428bec63c9197f9524e8e0163ac47b3518b95c816d005196da4d9bcb3ec1ab2b98f19d8406f529265119d99e7319499726b6bf96e3dd2928f87dae20eb5d3cc1a07dace145355ab0821c91685dba7674aee048d8a24434910f5f5febd1bf68fe5c3c18668f14b567cddf0364b6064fe374fe00f56160549b39a9d9b290f231f91f68700ede93c297ad7a188a1dac604576d2d173e200d1060923253f543432081675638f82714705bba9e2732b25707f1029a8c6626f4abe2892b603e17d4ce8492aeddd796e12d3a7be3607d8a8d3987e6efac9475bd5ec2a02d2518aa5843ac8e48148357af79936621882daa2c419e3259145afffa2db1fd71adc24eb0bf948da619e38f91e7d0e7d5fc03000232f51deaa119577d8dfe59c73e5f3de\nSHAKE-256: 5ca44972424792c3af77789c3bd0218b3dd3caff0f7c4d03ed94ecc6a2e9d71ba33adf9fb95b0325ed9fc66fe9ab6a2a65960df377ccaa8200a977fcc2c8dbe33b4ece1ba560467a1999b8eba51741a64714002944d696da6e48c55ef37022a1ca70aba8c7f1410e6db44bbd2d70707f7437d339804f942ef0f816f084e7230b92f3e04b9a5e4e15db519a71a037a80201206d6321e7195898ee40da56fbdf9e738adfdb85a185377dc54417e885aa6910790f5bf0b9d66d91609d6eed9f315d4a7426e196cbc2820fb96c2e407a9d5c49a561402be8f6a81aa70307e52c7664cd62554d0a75fa9800fc6ed1fb0c80f32d11c390e01b198a28b432522a98e6da062c4b704f4773690578f88621b6b52e446ca1373eb161fb55d17b8e90e71140eb355510874982720f58b3192178376373597a521f38afa90db1215139540d3bc1c1df15ebf640271b1abd90e2a4ea14af77663763e24fb52968945d9ee19b5d650989e2d292bf2c7b0a96fd36926b519ad47faba140a22c22484dca08551d5cd4519144a969f0ab49a0570b01ccc623fbce38b0fc26de2cee47ba3600757e8a5510c92686a1806cbbc65a703e24925ac1bf76c3ee04b6fecb4761674089a5326022d0a72a80be9523db8b3507a81359ca65ce0fe5967ea2bdaa98f8baadc682f2f1a1a966bafc833a147f8a88e55661e57acdb640f7cebb1e290cbebaa0c0b2\n\nInput: 7e5a413e596e9abe4ded3274cb0be8ba6d0db2689f5e1b974b69329d02b1fe1f9c9a1c15c79634d45b296bbcea48d43d05e2ca805ded57e0f2709af2eef2e45a9efaed722b7fef97d1be96fb167cdda764f795554063cf46b1c907d9ebbd6b6c728df9bb872ac6f32ea10a8af0c1aca22ce0c7a6b0ddf5eeebdc43cb978434292fa5e64bfdc13c4531349583f0e73b4d8b23a9b97a7067560cff1c28f4a0999536ad36fcd93d859b6a04eb81df54924303eb9bf79b472a06dc87bb7e35451b0b4c17cf05508cf9ea5d6fd2bc03f2141f86b91a7207050ae956b04d970e8005ffa11b265e8a95107e651538be175703fbf1650b099c56c0\nSHA3-256: 1d0af0539c811337644f75fe8bcf724bfa567befcaa33765bcc2c3cc76480444\nSHA3-512: 3856b6e0b2f5b5122545948416b6a54de802511a3e3c46cdb718068e29217dcfc046d2ea00da6deb9028035530b118e4939a703ed5cb36cc605ec1470dafa639\nSHAKE-128: 5f3a24215f7ec7ba7faf3a85899dab79c5bb3b7ed7b10ae95fa39f5279ad81353a14b93c0792d7b7725cd69a0af90fc5c8c008fbb5c340a406c1fb82bdf95f02be7ce906f6da3e0f50b57d6975e5eed21d8edd1b010b322a45df3e738d3660d781a7b85376648514166f7401600c239063bb56d2f24869a0f0159b65c0468beaa4b25199d374a33aaa74764931c698b5ddd9d865639acf287beb059a6ea6eebfc6ec610a578598c3c86e026b72110e0287e6b2e07a0666829560ac9d764c16459c1b78da661c7cde053edf9e597289340f92cdc11aa10f83df4d1db4b2aff202bf07cce6edf62f0a7d60ccff7f2b1f2b5abbe8cb42746c067f107714f94dd7f4b90da2f1a57851cda0c950fbe32e0b5726c9e658a93782e8700da09c84189a3d0fd27d6c8ea08f05625c6e87413e9bf32ecff6f4b70b4434403ce53cb5c8c3c40932e571b17d65e0a2ff95efd8bcc02e7a272a40ec8fb18482e93222ec3a3a449f2fdb8847f3eaa03c5bfbd843ba82963f250783db893a45f6cf89b83b24c33a60a2180b9bfaeac9295fcfc2ec3c1c24c61a09363c0ba6134c3ad1fcaed5ecb623543f039bfa3ac69b1d029bef8bb92a730c1c9d19989e1f6c0b69d64f90e278a5f44877b0689b21e3b77b348c4fdadf86514c35d4154c0f5f590c738d655f7f3ab6bba5bbe092699b40677f1a73fc4edddc482015f020ed5c609cddf30afd1f\nSHAKE-256: 02da9db12829427a7b9af05f87aa60e04ee0a6b7a334a2a1c6ba0da35d7a42024e6fa8cc78a88cc17acec14f84be09d01f7901d676b760d0243e11e78b13e981f25c591242ad4d00ffe4b22106fa587fd56752ab8f7e224aaa182f89b71885a1a080d3e51272f6f5d139e27aed6d2497fa5db15c6df8e4c237888d8c2b46131e972ccaaf3dec1e5e215b75a6f78885610fcc7bedd6fab84f5ab03bbf1e7d3966b63fbe94f346bc8b087b433532ae36731635c7ab8162396de6d333dd913cf9f63f92b52f5eaa39ffffbb9da34e79cede493a5019d6687bd944ef6a8a637786de9d49da917976598245c66441157841dbb198f303366fda8293053ebdaa17d94e1a58e819e11630f617e78f3abe3139fdd908437053ae3243f9b66c63b55824889f49e43aa079512a2e8a9db76139c6727682f80be0513015894facfccd5ae4c984b588c0d98ed22989fa9b98073a051834bfa6cbcc3002f908dc99e977fa082da2c28fd78361f15406f670ff1fc0c13ebf89c18e69a3eb66bcb22704a0eb9a59db1674be5f35a29fb7951fab67e58016648abf0accaa7e7e20093d766e2d9a4916008bab2ee70903efcc422cbcaec9002655ce6900567ee028135aaedd98f607aa1220cce44d31a4ff3ae5c7ce2c9dafbee3aaedb5e285037559ced5dfd87ee25f37b621a5c5b4b6a64b66213d8b3fb54dbf76134aaea5a1836109098dcd668c\n\nInput: 3d3a40750a0a257f7e8ca3e13d73a4511f8fa77393735393ed3cc70ac1e363c590a4e1d3bcc087f1f56f1f8f3262dc9d6d5812b9901a4d222ccf34b4b58939a3cf798bb86009a1257989f790e3d8256ce38003a1943debf28d3c68a47960bb1189db6bb77550b8bbbdb8fc3e596fef06d271d8f301f01eef8dee16a7aea18d34f46a884fa953e062a9301f11fd380b11bce89cec1b29416acd03a239a6846415a68b6385204052471af4529cd392ca23a42badbd37", + "1ce6fcba7dae3bfe7e7830b706f3ae0308fa5a804eb1c8f54da827dda83a7f76bad549b96613927274cebd4c6c91d8e078e977e69c30b4c3f3e62c433099708597ffe7\nSHA3-256: c83c94de4617dcb74566f95c705db05f6a707c3664430b834a9081cd346b6007\nSHA3-512: e9e0cde8a75d95f89c9cfbfa0868e07ac565f43468cc51359cee795babeee301e68524df756483a2ce2d4878a611b549f3d23a26d65a2a4659c82b823d78ed79\nSHAKE-128: 371b356a3938b8aad9c13a669ea3f0fbc344247ce40f76ef4dc9cce1210ea37d081b836d4cd9fb061ed005158bc13a42ac9aedd8164b23236085c2ce6c41317cb5fa9c7a09ebf857ecde30a296de72b8f20aaecd415b73751510655dd3c2b5420bfb0225761ceef95124ab5fe630bb5b0686c40ed9b2436868f26d9d8a67a884a109dfb34619abfb63be473e78d09de5a7b433fb33636a7bd6dd1faa93e3fb20e853c52a2ba502b13ea05f564cf1dfcae5ea5be88290003e6eeba424918777cce480d3792cc492ae110c9713f37e06aa740ae49eb635e36bb6b080c1a145b3eb38da9e2b2f6158596e2c8db8fc2c5a1d2e8c19b06a81bb041e72d35c1e91e2b96bd4f06e3a7dfd2c86d057b4952e93351b08c48520414928c9abab7bbfb6b5cdbabfce0cbb0e8589645576bb2ebd4c2b287e15be87836f3f392475514be8b4030b6da2d267e2c06e49ea8b5a017380e3ffffcd0785ea170146e4be5724bcdd51a22a7d568e22ff87a717f5dcc4afec22744d3a41be4c3f577ee7208f47f20c024d2e801549b0b1067d9041c572410635a39d14f5b0894bd11ea73ff19417b08615535b664e6cab2ae3142838ea3c61af0e2dd9c5fa5aa4e8c3d074c2d02dac1b527e6b8274a08c039492392df95da9180120dd5d6d277b326337d8703c6118b729bf0c8d1417b18663b41d52e5cd8085900798d63ade2292d4bf98a50e6103b0\nSHAKE-256: b9b977a5212a43a5e4312d12c551d3b34d16a43c646cc7769a87d69b6cfbaf074470e0f430b200acc9fd06a5b129b4e888734ced070c05e514dbdfba557c5038ab0dc115f8e7c60990b6a741ecb032d50f90e3f7fc1722da652325c3c8a06c16caf2045dbf43ea07e8a3ca481d4711557d7e7929b8988dee3ca74776f596b566928b37c10a1573dea9c652dc2a754ffaacde9970ee9aba0edbda5221935259388fa6bd2766c89044017799a1376ecea92749ddd30ee6e2c81bb8c35f26274f267e85273e1e695303865ca29b4dd96a689b939da1c0ee2bb6095f867b089235c3972b738a3dd6bf8214df431051192e5f2086188341bd76152b90c741dfe9fe0056ec463a27bd8603e4ac30b71538f946137c9a30939bc42024af0f574e6a433da16dfb88822b90053e19d18cdd39e39028165efdbb2e75a7d8f69f01b900caecce0ca182047861dc918ddde65dac2d187aa48ff1cd1baba076ade5bd811b1d2a3c0466b6f8918f9d82a384a8cd73a1c39cdc16a520b0950141fdb4cb0f1e5a5015fa12c4d19dc08e9403488d233aa40de546991612fb6fa7178ef5436df14bf9b6f6d0f2d7751d5526e6d910f183782b9fdabba6f16651055e6bac189e2d93dba80413aee6d6d5b22bdfe88e864481abc56705693bbd11e274cda1c49d24fc37919b009b0d8e634c120ede55741c93c2f3ec62b93634638896b0505d937679b2\n\nInput: cd9593c7a88e370ede4ff38540dd9c1cbec6631090a289d4297740769e5b9ab97eec2098bf7e6437dca5d88f84d731340471e816268d78c0f5bd1d9557b10aea9010c1a4b21b436c5c7be89d6c6f5d2db901d962801945979cdaea30d0828020daaaa88d48e3ad69916172a5d5b76c34a7833dbf3e7fe33aaa2ec8cf9f584dc03a97a1f9e00b32bc631de9900b7b8cd7b7dd0e0afaaf2b8683cfc6905b3dd4e793b4fea9de70dc1ce4d062eafdf814fc1aa7e6575d54224e988c6cd04fed9ec0d211a7c4c18d7ccc9cf59a644386dfed5d30571f514d428e3c1659c8d0a667d8082039e6a01c434dd423a64b4fe1ae5212df63d326a0886f84\nSHA3-256: cf0e45dda9abbd1769c38fe0ba2d2c64e49e9dbaae6368d6677ebe7ca10cdaaa\nSHA3-512: cdd7edace2d1253900f634afcc1f449525360e9334de7193ebde8174126f462875aee6e5fa291076e3f296c3e66581eb0db81abee45f9398be9eb730d08f6d96\nSHAKE-128: 94268739f55403c877585ee64db08557fab4965cdbf25a9c3e2a41f044322f36d6c8da14bda3ee1461c5712f7fb283ce9bd6daa028b5209c730b9d7accdc930d978695f6a158a62c7f8ff708e33c5dee6bc388d5ac1419f809e8f0877e69097a593fd5569b42d1914a3ee1ef33f7535be1f7305d3b9b74c039ce1760d671f81186c1d516e9e780a0b316994f57e4b3a64c6d0706add4e6e3918d75ffe5051a0db1e031ad2018dc4baa769cf1aae47a758d8c663341861acf6fb027867ef63c653fff860b4efa1c567cef24fa9dcccc4bc9d77e576c511ae0d8ca7442d3ee5990ead1c4d0b6cd9d5a7e10b2305b537a01a3bdcf2242015b6145e8f2f4156b944dfe31bcfabdb8c29b35770d63c87791e82294089d0ce57a033b112005860795c32d732f04ba609991d7eea086dbe1b4c3b6e7599f9cdad2252bdb19fd91da4036d002277a7ea0ae5b90402fa98831b898a58fad96d01205955fc799c00097196e8b4a69c7ad86ffbd7a8531cec11e51d7c0d0e6dba59e3c2fa28143971e53265b3898a9f555d16c9db921904c71e7400b508ee6617804bfdda35dc64eee7dc8d80f4acf0c1d26f37ad442616551109ab5c6761cc1913862fbc557610ca6c2e9551ba367a08e051b983486c3bbee3da7abe0020eb4abdb82d89e04b207b4bafb4e9053981d5cdeed2e5399c8c342d90878ba8e74e9619a900d5837306ae427d3af\nSHAKE-256: bb87c5e0601f3ae9ebf4be3be8485443477388d9476a417180514e372b03e09f44c3ed7ea6d050e839068a8911f91fc1f3348d2562770745da35b05a44a1a253badcc64a0a4e562c8746fb06aac65b447aa88ff5bf42654bf2ea6ce48ad3f353d11c5db3e7aa0c034fa0fa65151f7d8246efe1c61f48acfbc07e5d9fe8818d02bdce1abeab5f71e82c80ddcde85206d475e54cbb93c5aac0a2198f562393906d0ae9ac2d8059aadfd6844cc8dd28b10cbf4273dec30c58485ff020a910298e2de13ecf4a002c7619f27712120509f2de5a0883033ddb2fe3b5c087d272b20c51141706ca599db10d565434889555f0634fb061625455371ec8cfa652441e46460469621d686f06f54d3e9c4796a0064d9a9c9efca9f532c03dcad578ed3875788a9ff0e53b91b55ef66e4d4c96a9cb34bf0f998cc42a7ae5cc31516d90823a91b433fccd6dfecae10375e8eb41b21ddea417ace683fe9fef086b40c03b3dab50518c7a106d64ac0bf229a3ee70c2eba56084b855f9caf2a87ec5799cdc3b2b3d1e2ac8f09ed48e21d1831a7728b991ac9fc03184c3a78eb4da978064ba16d8d6ac799fcb3880ead2d495ac4638dc4f8fbbde5d4564c99504be1c7a3a0c418ef03fa7938287482fdc985c325e9a152e3c5ddcc52342d6134b450615cecdbdcef1bc11583022381407019d1ca777d613882745fdcf0e010a89c2620794c8644d71\n\nInput: 770147d755e99b638c1614141cfaf6fe6860899d7d3749cb4b0ced7b0886d59fbe4c508854e457a0d382f9b4173694ee62240fe0a146897deaeb5bf2d7cd533a5ed1030b84db4e4edcceb777830714e8d9cc3b77a62778207d5f190b31ad4434c5de2f24da24f59f50f36100bbd2730deffd2b0fd00dad16e184c7ad0f4ee2fd78eaef211a7eb9c2ec6436a135650a3bbeb2ec0a5c52ad29478104873576e13b9a097f8f207d4f38a007ada015ffea07df4501180487caba5f238079059386488e0f726f2f8c045d9321624a786cd0cd11e964d5a3532413820c56cbb415bab1130db499b8469953904dde523ae030892908e46e3f4a2340591a\nSHA3-256: 75f58015984714da7cb6f034729b4a5047cdcc42301405bff9eca9ae747b8557\nSHA3-512: 211b84361d13d66cfb9fc4fc06d8ff12ac21c805d820b17ec02dbd98a79020141ad481fd1ae524db6a2c04a0c66e6ca95c33618ef773712edad9f1ad90d5c5ca\nSHAKE-128: 93d46e1ee210edbb595b865dc8ab89deb2aa4270ebf348eb24352d633a22df07dfb75819847f5d8de9d2e9b4ec54cb79b5d6e42d8e1e547d1728c041d8637406eb01064914bf4fee3796cda94bfd15bc0788aa3eb57ca81d67902e435e2307084332a268d301578f51c3989f4ee6d46203545157954e6b7991fca84eecbcfec4476667c0d64315ea62643c214f147eaaff4923b8fb1a3fa6dce7fd3defb6b2b69635e3729b4cba49335d8ccb9318a87b2cea70fa584072d159fb675c2dc37df2cfe6d11203b312e7fce2cd29cfa7abe5c6896d64947903fdf93b0e89d95bd01e4d42cff457ad3961ac4d64703062b346653692371a9e03ce710cfc05335022128fe07cd7a9e894fd6fadfc78ebac8d4f62a3231cb18e0184e0df2bfd0d9221ffdafb7fb204b87c509361a65446b900c882306b681625f6a69893a7100e67754048a226144b08190a4fce7f7ca4d2e58809a9dd13ee120d72db84f58c121a021c6d34c435cacf876e741ae1a85df50cb05a6658919f61f8d4bef8fdcab5fa5632a2023fb8818cbbb7de0001b65affb80cae76c1221eab8fb2b54e7511c8f4b8ba68f75b20d952790afd71f6719e84eaa6eb0b0922cb4921cf2e8b78d5ba34ac6ec3790a2984426af0036ea19ba45a5c4fd00dc2b40c52444db7f3ac05f103b6a949858187b103597340296ea70c56d7f05de6bec86a4a206247fa771cf6fec10b\nSHAKE-256: 097954ad208cbd10fd2b46800c0d2e13be2ea589e0d2b928b09ad8f0df5dd922a3f06f9f123342409d60fa8c3c75a25f5e885d456b763c243a3e3428178ed1f86bae5200213a5a51ff60865e16071a3f60bbad4572dae5af92b8b2c66f065a89344eed7570018da8e1727e8f96bff2f0b4869221e7af96e5f0a65151eabdaaab8ddfb11328d6d1437de79a1789a38ee66469694974b1d5475c776c0bd70fbce6552ba7dd9ce5ae281b647bfe801effeeb68380abeaab6a718c2df308634cd3cdd09cec319b4e4ede6d01f18b6e43af83b24acceeeb22cf01dcc2ad96237d39e2c4355115a4b4c1d30bf58f7fad4f175292eb8154535d3776c20fb6dbf513b1fdb635613d5060029195b23ada730a705624605ac63887b158bd16bb062426de571cceab89fc5e3f9791edb468be8cc114886ae136489973f5cf15a14448027d090dd73a6565f39341c2657c20201b329dfc3227a8c650ea1c176efd74dac4dbb6aefebb16cf0698d58874d5f50c74d7dcfb894da9fa529aa5f414a500f05ea928017eb09eb703400cbcd49a915862f4002963145aac657716e51eeec01a865f372e9fffb0ba9ea13fbfaf4ff26e2c646b00f2ddfd5842de82634a724213a73d77a6c510a5ef3c2c82449806ae84953f043cc9ab7bad0fec9be8c54ada98596a6ab188cafa14951d1b64cbbbea1f03588d5ef77c7529a24f5b42f1df0c072682fa\n\nInput: 74ec44258aede674de36afe98af9776327fdd1d387badd03e79cef9e7894fb291b59cf81a1a255a6be6b291bac8aea7a800f0a70d08f8de4675a18891d3390e7ce3ce0841f403ab0d15c3b877018649c30e1d2efb9b3949", + "7e1c708a0288e5cd8c1abda692b015c97674fba882673e0aff596eca3c3e05e2630fd187928e8f92c24207eb7c74368405311461650f9e40e6704f797f856fec29f0d3af5896c7750cfebdd5e5d522209cf3fcde9f1a4923e0bbaca43b416c8543348fd54d3e19ed0a534dd3d37e24faf80aad3b52aebeaf7c9796cc9af663d53a771b74e627352e2dc5f842580f075f027e9f1b0b4884b738ccc49fbf8d0556786c5b0\nSHA3-256: ba3bbe144ca628741fdce3c48bb83342524f7de5b9f95839fb822955240d6cec\nSHA3-512: f57dfc7f0d05ad4df05edd0139e23b11732160775944752cc982e4a0009c4dd17ae82065ff5b85b885aa7f913d3283d9ec009686b3b60108a979b50781a61317\nSHAKE-128: ccfb862462889fbd2320277f6a5470909a27adf3a05e93087ce481c8e35a47d909837079fd97e2909d1c89b247a82e8b77943160bd0291be559254fd31e21a77e95577222d450949cc4a1373b3b022cd0a357e4e14e95b61f9c7f4c4ef85f6e7a0a28d02541e1cdf3d520d817af8269d197386b1036dcdb42846a4886316d4fad98819b27ea40bc5924523f11dcf0340aab54c2119648e87c7fd2059356eba822520f54f075b463d8e85a758b407f39a7a73efbd3534fcd24debf8a3d836df7be992a2f6ef6c323dc348c8d3283ad02d3ea9f72c697b37c367e3830d415751db218bf92801a52487f9e2128c3cb21931bc07042339aad4534bf1f7b60d75a81b79bc5628835da5cfaf85f2c96b4ba95f8987e7b2ed6b7d5aeedc371aede18c50bfefc3ac0fbe9a942bf9a90871a55e14b80b9745e84ac052c2a5ad85a7e101ac65bef43af1c15fe733e4eb1a294b459abd377fce1409ac7de99031df7e35f7118a533a804c37613fd07984910ccdc0529d5eae51c377020b369fb42889884e9a8e745e600799c6907acbae19cfcbf8a41a2f41741a50824331654d1cbfc5a318bc6e69644549d0055855999fd203bcd478fbe2137a007c096bdf82e22c9edf101d3f4b9f3a4fe6ff5aa6e4d7d228ffaa58c376617c920ed162004d59d01aea4dbd2c242f2f2f454bdf4318ea9ef705bf7abc4b43cb234bb20152ad21dcbade52\nSHAKE-256: 312685bde5aeefe566b0d29d301fb58245881e685909e234e3a665bd85996c49cfbae1cb9c154cf82b92b3a66506be5ccefdcb4b041caf2024c1e2bc855b81fd7c41de25d59d22eff79d1287ca7ce0b2d89de1ee248ec0e5a38cbb90ce5afc893853e5e8ad5b5428720d06182574876cc12516c4d708c7989cb48d02e57daa34fadd4d34cde1c033442366164695297267ac0c5e11e660038156930ef0096b750b83d161f3bd2ca3022b382ba64973aadc62c0ac24facdb75e2c0d71cf1298e3eb5a728dbfa5309116ec851499ff2eb60458960e17c702c8b356f9d13020ad6f3ff5c5acd5a2ef229d7554f6a8c400d6d04b5a542161bcf28126b4b0ea40c6a87e81a469ac8be1913d627f677a758a1b1420facf770840f9dcbbe8dbc9db686b61895f7051c5b47d6f0f389a8fd8021215fe2aab363fa2ed0bf91d7b69f65c0bf066a5ba43a4c592ad78e28ba59a2fc97be8ee1b9b175915b0b5fe747741462d7ae26950253f6145d8b77ac58b8777af00620499c59993fbfe51de0e09019d6005e568b1dff976a8eb026084c33647bfd4f5b56588ebbb40cfbd4b0c1fc2c7b12d8cf6f74e64ed0747209791226fc2487907be4d452a50c9151bedc9ce2055b864f66fb95674540fdc049a78cb287f93114e0333e8adb7a2e435c7bd5d11e33cc255e03556af393f03251b526525fce5fae2c5caedd268f5c0cad025b5227884\n\nInput: f26edf116fd5f08edda64c345d74f45d72e658c26459f71eb20194cf4d26ef40cf6dfd2b4a3b6b5bace715f6670cd9a3216735347a5c0b521d2923ed3f2759ff015e0610780406c3543e9c6c41afde980ce5b1932685ec4f358e6cc6036fce1de5b8333c928ffc34501e2884a433b01ed43f7037a60e325d85a4bb98e016b6b3ddbe76925daf591eb52aba7205093d8ba2c202170d6d7831b97406d34d1445a17648798b95f4c9d6ce99e91515828c14e2103d955795a3f8e14b88c3242d9540dc054c9616d127dcd0a950562e8308a628d0cb890651ae55eac994d770181496cb5dbbe6b8c412390476c68aa28b0226976134e19297701600a5a9b1\nSHA3-256: c2e9da9b01d7897ad357de03be0afcb8b2b42a2ca322ab8950ac011d596feca7\nSHA3-512: 326fe696e978af9f289fe8f7d704f08793d446dd990a167822e97cf3d2a9161a2191b4ee49b44c45eae2442f7bae3c638713919dbc53c75b8f9d8ee82ad177a0\nSHAKE-128: e5c6ee339e658f364509fb90d481569d2d5ef98f21b8322a5a4a76be9998f03c4a7600b1597d977f0bee3e7adce79518fc4b620d7eeb2939cf5016b55a047e8826a2fdb7f7e07a1141d050e69dac08ff2e6110fc351e183d104a137284946e423aa085517a8121861cd5f16d996aba1ab1d4b2d7691c61a4a9374df4bf88bd64a77108949386ada16e948cab361feb81b9b6b6ec55447f71605223533425e7d19f95c0487632fbcaebc53cca2f6f60962a61fe3d7e4fd534888f65c143f775b7f8b0d21b9d6f27941b85c2cfff751622b4d5bf8986cd8bea2953a95c74c58e8a58543817095b2dd889af6612a09a75deab17934aa19d2261bf84ea3a15cd0f78e983d0a710b4b50ccb15c1c1c87b9f5abd35167c3233340d706322c57d4058f9ec1b9daa8855a18b711219d365e8f356ebe79287c652e1675b84732d218e434a36d6ecd58671251a1be5407c88e6ffd0d35f90e44dfcc501fc39859b0b5a82bad6806224fdcc8cc332da4f422d0588023dc0c28491e4f8f16e98bed1fdad371c43809d18216388eb0c7c016bd206379b8b3305d32525bb7054178e31ab34f6198a4733caf8f0a1e15f63fdccce563ce94bbe1c1004a87d8d2e18c95a473a0b95d980b3bf6045f88c94544529208cea83692d532ae12dc6bbbe727ab73ddca7e94dbf72170d6429bc108cdce9122e2c64ec19853e08c8ce6207a66745dc1ffdf5\nSHAKE-256: 9046e8aa3d0e7f9eeeda0fdc6ee6ee899f0be53cdc2fed363dbc1d7f71de2db1d07f15e7f0c7d56fd58094b817017d2e2653b949612134f8d79a863f5c8f5d0b3f14a9601fb2969aa1e10e0b6508127fcd9ac001baccb435f74330589a3b6ef31c1a60edc51884e8236c6ec6c6c13f66dc8c282342c17e1880e9d38590061b5aab0307c7b188eb768b719b1b5cef955c56f503af264f7e116b78febbc9aaa37abc344448b766153b566a44d784e2668d6bc6c78f6fcfb2f9985c8932633242b73ed5c2a8d52e837b7ab31e931c81b487f9bdf533dc29f207a19d433de191aea95277813049c7e8d0cc7a33c4cb1a7015da38f051f3bc6df10e15bcf5be130ff96e97930bd1e384eb25463203119ac4ca628f76f8d66abcd884be33b02907d2e498c36e35f2cb870fe54eeedc4b8919bf413192e4d42b972c824a11a6ab2ca15e8cd83f0fb9212b6a54e514a32c1919c50db35c25bee771d990d4f54e3c01f198d2baa70bd178ba96b93ed7e920488cd79f57ef019fb0151abcec631d9f6e843aa93463b8789e8428fc37141cc891f8870ab6dc8ccc497a9ea47445aac1b542fdc899e9db0c6e1060ec73508ab1591bf6b6eb64e85ed6b2557a14c849cfa4079eef975ebb054c21257336a4fa920bcb39da17ff22226515dab38750ef7344e37b23cf0e6a20171c2a8bccd50ee43c1e0f3c745352a9e28a7532cb2bb27d4ad691\n\nInput: 5701e38a6369652b54987fbb64e9da48449eb6dda5ffdf18e9f758e621997e3fd366f24e5ae264f9a99a89983a7393369d910996656418deb583a17d5b831fd161cbc6cdfa04633908582e919e8e4187708303edc01e5b7a52d7c626453a569fddb393b6533f96f0a2c7efb1c12579145ab20093f6155f92e314223ac06493d306976b635cdbd8800e49c9b02ab4fecccdccd9f710c0a2d23fc41b1128cba023071ff7d6ce7ec91b27f1ef3a6eec51beba4cd9e09378f828e4bb16841bfeac6c44dd49078d12a5594a18dba78abdfe3e097d12698c74051adb9f4b7d8a9893e9b62a216a04835e7243b7528edec3a2a8a54f9f14db607b0a2e611a78e4\nSHA3-256: 7f6162b07425a5ec070dee4142698ed731d57c2aae9f8a41f8946f2d803f58cf\nSHA3-512: 4390bdc2cee3ed8e64e5783e6465607e0f62bd99fd1a87b1c83071ce1b8f81028141506164d64697b9142a4fe061f7096f37f4e85b5bf37b247f976950f8c730\nSHAKE-128: 7f4e4f6f10ed93e866e1213cc7a5e7049cdb8b89e92997689948e48f579574a28cfc37154c95a294c6c76223dcc2528f7d91a6f220fead24ecd4efac5daa98b47e14758afb2050bada8c31c99569821ccf572a03da20c8ff2447ca33ed80598821811e61007cd97232d13f23ea5790e2e91d9d951d2892fc76397b7f14fb5666868b050e119a95b1c49ace699ef0b34d31018a83cb368833f73844d776bd41246a77785c7e91ba4f86f8b38874e4eef0428b05d5007f699a1fb1786c486fcad99a844ab39ad3318c53c8fc865f2506a4407075dd55c0b523393d054765ca72381b4bc8a9d3144bef5f1288401bded3edcd53e6526414780d4936a793ddc58e10bc495537632f532d6b04d1ec30ff88e65a80aea1741fb6345c4feb055712ba7966fe88dbc4c40a59c89146457e13f3634ec1d3b58a47c37663fd285137a298073e99fddc948a68c4816af2eb09462be53d7687eb00fa77f8e971dc6d2ba4a58cbfb1564a9e49d9d7a047c0c1adaaf077682915343dfe399fd5ff868838ac239c3ef2ac46eb47477ca508be40b27a53cd8c7f2a3b4f9cab1fd131aca498c54dbc85e61c6b203030cddcbfe74db7764415e1172c2a206a26db9dd7d323d62320700267f9aa20bf44d95aa444a021d08d2658f477d357846e4e3eaaef817cb00523831d6ef7e30c255d96728f5a752d506a00024fd9543cd26ae4c46b93613f5946\nSHAKE-256: 373c1f4f8d4ea40a39226e46e8cb27ca28eed2c9509520211c7c3ffe0e6ae77bfdc3c10f3fa3e020b27fd171ddc2e6ea98e2939a980407c565265c92b120b6a807c100f35d560e1b3a564683819ef4deecf638afaf19ea4f748472e28b231b4a02fe9b68dfeec8b931d58c461153f741dfe50513c0b7bac95daf02b3bb85a94bf79f0ae35d6aff1b85a80b96596783b8e591956d161ba0fb38efd515b5e40017da800d5502460fb2f0755a203ac70053fe5477096587c5582da64afdac60a5b25e5fda154b0f50439d09592541cb7d75aad8c34a80d0c99d3868835db18ef2ae09940cb95de5e8fb5db9858968792258f44190ec88a276967fd04b46623662f0974aedc4e7d9173556ef5d5c50cbb13ce8a2b7d06400bef2899348fa136bb40159a3f40a0de1b41b44a87943df74f550416d17e08c1ae831bde3527e8d9b6d78f926aba2dcad0931529a532872121398436914546aca57c977c2ac8f0d429b0510327b4991a091499c66cd8d387a7a68f1a0fbe5d720ff8ab18691db9bf2deb7f12a187768373e933b9d8625426413d09d25db96165be394255bf3b3dcec457b48a94a8a53bdc70c31be514d302e1784d47d3784bf2098daca58b78bb30a175ea465b83a1dfeed6b2622ea66fae70e73de1c075e01cd6b3142c44d0d55346755ca3823aead2fa73bced19bf4cc08520e7473099564a", + "337fd2768aa3eda16aabf\n\nInput: ea10ae25b93ca6aff7926230c0b7ada7a6642bc5bd39d133c721560afab1109553880e7c6cd1051a1b9877059dc71df622fd8c4e0e36ce63b0adf618126086cd87ee283aec6be53905b279e36bf4b7093ff87667b65949a3fce3a118d07f96d5e2aff5d00f7c2e061a0a3cd642c4756476b782fb6e75abdf9f970429c22f82c470e754ae89967310fee93fef21f46b579dcc558b495ff9a9f0f13e592c2c2afca05ad1b59089a82072030af001dd9ed78cf69cc25f2e11f0b52ac95e15a0faa2afdf0e59c01ce7b7f6391a9bcf9ea1aae15f1f4728a89caeedad0dc84804911bb09e3101cbac38232dcfc77a09261693c1ea9668eb57b05b7011e9fe6659\nSHA3-256: f49ff4f90481e06f062f4a22154a3e8a7f07567d7cb6f9b60d7efb8bf2e907e1\nSHA3-512: 64e23641d232ebfd883e75ef28a654583ebedb6000031ff9275c616cd888d01f8ae90f91313e6f74405db8633dc2f8be21122479f7c79986cab3ef24953e08ec\nSHAKE-128: f62c711b81f53b8734f364945c1fab1644f3a8d099f61940d90d348072cb98431696e146265aabec37183f84546ba8fb3245b3d163e14ff68917388070ca7701e7c7e23a3c109a7b78b8159feafc0a7c57536175599c872a1c9344f0d49dd6bc9808f2086c103078223204931a97e0380c9b18f29fbf37ebec5cdf489c95ae7a1c3db010bceb8756edc090e5a1caedd8ce3770de0d7ca3b358f465986ef35247495f49d31a9b7ff70c2b04fcdd73642070befb7df4ee49687a90d619c65f2afc6cd531d45615bf81ed0cec421d7fa7ed25eb4fdf0036715fd56baa51e90c5a2ec4eef4d270cac8c5c42872629480511e298de5c4d3600f6ff556d038e8c453669ebaaccb0d2a8c7d28d61c8cbe8323020d21a789b5e64e06c3637a2a591af10c7f8ce1f4be7593018f03c275103336d6cd99f5124c12b6e72fc560f6f43d1254ec7787a41628fb731fff82099290d9a8b86468d263fc215ddbce6008bd159069fc3126701b9db7492ec6262b47f733712a88ba5edd440343cba5718c851036f5e96696f8ae2e11471b4c5c568dc1f80cd8aff995cafcaed76ed49595f135dd57d2fe23bb10440a4f26ad6f61097cade4176354c3b4a1e5dd29cbe7d8b2169cab6704f42110badd380220a1822cd921e2b88b148f083924b9a0f579f8f5ee11a2632390d0104cac6d379c905618f5def16ee5fac507756fedb618972d5d112d64\nSHAKE-256: c992070f51b6219403ef463e43d5ebcbd597f9b45d696558a743db1c985632fe1fd9c8eb8d1a19352769e3d256545936f0546a0e61f2540fbdfa90b02c9bb68e6869be0c09b16120dfd8f608fa8f003b4b519b3cc56763148df0d51c897b9a376fc31511104a90b4773470f7d64018f8e83ddc64967fe14c20a99ed886b9e63989e6384090287a8b0939a0c16ad030c6688b4c40f5ba4c8d53ab1d8e9b54773ef43d99e21bcace73a94a0f27de6ffed43f9cfb6012de532214cf56adfd315c6abc379b7f60bc67f2ed181743b042db7bc2207e68db8875a77ae5e8b739c848696d68512a03654313def86641456d0b3b7281852ea909eb1bf4eacef383e128a7963b3fa6ef56a75a0c9212cb994f821f1606b4c5010aaf26c9e15cea40082e4d1bd46e53f1a5a0d0fea1fe322d8a7a9e89afe646d5be3623c7774e6d2962bbb03642df081ef1f6776e947d399fa8446fdd48c4d2a87e2c0d441e046c8f7a27d5391b6a5d0e75d365f984c4b576ac28d7218e9b699b3a9fb77fc3d282ba6458de58306142f8013486bb9dc795b2728f502c1bb56066e3d838ec4a790e7468d0a8daf13438c9286610953d61895e23efa338054a7f90439833050012f04f637857db6332827518abec34db8fbc614d7198185009e19869abaeef4014cd3174121b8e3a77613bcb3090ff9eac5eeeebda2087bdd3db19550355e8f2b2223fd124fc\n\nInput: 4360c70baecdcbcfb6a94057584e0fa4f1f2185785d344065e5f0b507db3434774a04907b66f32ef5f40a06ecf9b3e976e17fb0c4e3588027d3d60e3f48f42fd25fc13ad1a4ddb8220136cd67c89a5c04dfc531d253fddc0dba1f69ce13225f13570ffe34bd6ca40f15e73bd8bbdfe61873441d967f6933a2659fb88eb4dd74c461686d026f0337d160a485e18349198d47b512a867aac6bdab019eee08f4c7dee03f64881c56af8ac3b6167e93c94cdf65fdc94e43ee4b4c689c3c0d022cf62d0705af1d8e82e76762f6b0c2cb5d87b27df52d0558b7f87b92a12c232ead1b282a5db3221b6d1003a61e2d26a60b2ec0c9cd9c07122afde1c47f31fd6793c\nSHA3-256: 3c7ddf0a7615c2fdcb7528a266ea2be84d433798f8eb84e70dd018db916f091e\nSHA3-512: 0f649286e8d8897b7069c72e6d47abf3f5d093e4d3c2b3653de43f825a1df62927ccd0eb283903d23e8f8a44435553e88d131c108ea663939f04bf7be4a6edc9\nSHAKE-128: d214ac64f919f0397013beefd269bc2ab3b2d0480a02e2f2f7b988d024aba052a81d5b564a858a4ca9ba4689efa57697de94a51094b9b9ef1681e9c3f4f728a4257f7f2aadbbc07fd6b8d67c633e28ebbef2fc72847a27317ea760fbdd1d82cc2c5ed88cd4613cb024f8f157ec9267d2801794b972ce93efc90608dfd73406f35a7812fce1351a17fef6f0fd884415f1f2c6d3492c4041be18e5b2459e6521892709625004a22824634e6ebcd8dbd042b78dc2b57b86f5107f07fde558a5c0f53dc83c42a7a8214561931dbdbbb315efa239de9751fbacf8c7adcaae002dbc209ef14141545b9ca1ee93044e1664e636700385e6f3dcd109c88a4b91ab090721015ed6b6d0430ff4469ccfe423e57d6b1fb02f7a1555c3fbc192c96f1bed089f480a62b0d45702bb37cc71188fe1592591f8ea2736954e353dd511d59ea06251b3c19d1db0e9516897b9116be3b30b993575a3915004aa2760af56fe69cb4f1ee3c0b9bcd872a3f7f2eabb305aeb2339e7f8436fbc82bbc215953410f3701d79893e5f0efb6ae77c7f48240e30234dfa96e373bee4f8d0c005b78122a4f17d316a695d0e98879f107fdb0041925d5ed812c598ce71d5ceef3f004856948a3723adccce4ed29c8bd12ebdf28cb86fd5498fc8d316c086f276b9163f7077c0cfaa7c3ea75944143b6e501f59fbfeee5922ff629ca601918ef6c2206d27e11945fa\nSHAKE-256: 5444c7034a69919b8f03e043b4b91141c8d61106cb37b88991a5c721d9248fcf67d048e05f70b812f7e984fbdb82f4780a1623fb971fa450b977b23c0249648fb4fc9102f08d9b89b4277067cede46391d4aadb5ff81bb019edc96579fb2eb1b778914109294b5c69d8206f6255fe4966b742ac22ed3cfb9f51b201594c5a02707660226b98ff36e0322b8d6a152018b55fee2aed13647ce8fb38fad547f2776aeb1418dab99aab59ec62ce5126031054709bda2d44f9f5887f28e64692050ca7140a127cfce16ae93e3fdb1aef76d8c63c4e06bb2b262d980dde6289cb7735bf118b27f6559fafea65cfd15087ee0ca7e7718f9be93a45f1508d5b6a37aa2d1e10c340cbff858a7710300b1a116f61e94bb3dd06cd3c47a4a0f970ea2db13fe6cedd326ff9824268eb07c932b71ffab2f3362e78c6db75f2a189545f40ea779aff61f2f9ab88eddef2ef369a65a6d29adf986c5fc3b7b810c654a130583c424629245630941ec8e269e29924d63595ee01c6e55d78fa8a8de3d263aee09c351b894caaf525d3ee5eb323d1ca18344aa0187efc9579ba555f9002cad6a3dd790844f9def49dcd3777b2d27f05a52c7f51e65800e0a063e5e792160af492f787160cd1db9e26b8740459816db1de14803b3f79be6c8782b2ba131c76c96a877f175e36e412c7b19007f11fd0f0084e2d0743b19ce0b8bf2e926732a00cebff936\n\nInput: e88a8bd3c73597ba608159428ad3dc5e595379e968c65450879775b013d6ea4be59163e55af894e2c3580b9187a666822c794a5947ba06e4deffab1b11fe50665b3ce6d993b5a6951d64e3d0019cb2096bb735bf1c70f75195d17509f76b81c9bce24788d7767822d6d0fd8eb19b4158e703108b77e331b81c30225e8a6fc276cc4b3574297616a0d810a3faf4d4cac185b4021cfba57b5ff20c24cd3f6cd05786fecff5eb26b2b6f75ec05183413852f07238db7a55c6c4f5ef4d4cff40dd0317e62b59470cb30845b9a509c132796625ca7a4f6b0b836f333375458b70de86525f5d633997c6a79c9d006d1ebf521eeeb73afe25107a54251b9fa7daeba654\nSHA3-256: 2900f7bd32b47390b6dcd7a1487b7ab097051ef7a8ca57b1e2c0acf5aa916c30\nSHA3-512: f570e175c9bae8cc1279e005c4023542cf1f2e8e79090405c94ebce9e3bb86365f59fa1d3d68707bdc9018988e3df4f5867e9679382f04fb4f95c3f79c138039\nSHAKE-128: 017dc84e802a7921ab5e4f25fe620f1c166afa0a0c28ed2e92ef0d98bf8118a2e3024a9c67cced51ddbf243da84dfd4c912b2bc78a2f0179c5aa16777f5049097dd93862d0491409f0bcf13b544af28778a3458fc4d748cd5a969c60d9932b0731ad808556a56162d07fa9afbc7279d8b27990ee8dfd19437da66e2de145cc1a8f78bc49e49f2460b2b80e173ace079203e84d991f39c9f2d1067f2d26072d3d538de5c5f022f18a007cce18b48d944dc8701b63ffd4ca5eced6e1dc3b7ebc33003035faa05a72bba1b20afa27d2d607619d692156e0e394edf6de120f3df7ccb38dc58e565de8220f7caf49b9983a62172a78ab31d317a2a22a53e6fcecd32e900d88af44d43ffbb7e8084e73d8afe6c7d527d706f4f8677870f92a91ace791c16405f98ac6a974b0589a377933ea8efef9b1c897191f8fff39a5c877e25b155cae39fcdc9732c32e67932e46bb11bd71942c7fb326f7e756943327645da8ad22dde91e9d397a5e3f42e0ee710c2b5b3d7d01aafffbe689e4c2e4925eb66543742a11e8e79d7fd128313bd02daba45074acc5088aa60bb5482ca57ed9af5a9b5bb40f8889edaf2a52341b965ce6793f4d87da1016c304da98dc769aace3fc7b1ccdfbb2e76c2800d42f1d9cbda1f944a183d25b8340132361620e50c848b268c015b1d43a85100f1b448308d34e647c91893a0049779bc4f3d5d05fcae3630a\nSHAKE-256: d69a619cb21f01fd900efc0890fdcac0e2509ae1843a68ffc33d724e143f648989d139d5cc69cd4f753e8a5bf7c92b4a73762f1e054c4ddd3a5ce0cbb1263f63e9f835f59b33931cc7570873e332037f755a24d8d398206b3cfa007854a555d6a83006891b46b96720ee4aa1e6a8e805a2e7662a4d3f49609f05ca40e21ad8163ee2bf6ff6e317d8afff19463e999a20397b5e9ce728dc5061d79c336ce5bc4428d656c417470c388374d17aabc34c686c954c80c9c04b4d69b66b8c19e292a1cb5124cdaebb8d5e4faa05b08e4c4c0a86bd1ebb9977b57be22b1b9c50afbee96a284ac02fed354832ef77dd2f664b1669aa8d0ffe7835249331a3a1139049b609997c4258cab0dc82d88a3744213ff6d667ecb26769acedaab1098537d040ed32b37457f7540bee59fec5befdd192c7250de2fc4465dda267de48719eb9c27779d0b56972a157b95c1be15c22ef46eee607baa97035646d8ff7ad3bbe4245eee457ec74518a343d1cb45e471a0925607d12a2e6158bc8a7632d6ac6aa0c2067b1488d414f75", + "ebaaffd6c63ba667ccd8a710bfb6172bbbd0021166c0e831cb703d574bd60f507956b1bf62cde153fb6710155ac2a304f7df20fb17983a558fd960db1fbd1485c3ff802468ba6db3d06e5244a219b72934082885f566c59b273e039dc925ec103fc04052bc0c643d94f4569322a09c6259bfb51b8eb9c7d2e1c6\n\nInput: 2cac1abf6c76a7e3450fadd914e6f52a97a2de95d01bb708f9cf6b821dc642e031e38b019cadaccc92955563f9e9720f57785b3ed7d8ae80bb629abf1a83b4c69ad1f77acbed9b248bc1166bed38d5e33fd834aa32a0f9889c31e07a4d8cbbfd1c537317497b3c86006841e179685d49a5d692e9ebf0bc9fceac563b735f8cfc0a73fde96810cca92845def17ed59da35b11fdf2e0366b09e228d64b98d1b726a14c5c5806676f5d4039ea5e47004a26d862e1fdbc9bd8bec58b682b274f9819c443f72dd213acb4cd2d1e9b8305481f86e173090ef922ba2e7ff42f8c52faa97f67ef1b13f7006e92ad0b233b82ae39d9af3c01e117119edafe6a3253f4474281\nSHA3-256: 14764f8bde01e3f03004e2bae672d44ebb1d88fd722ed8b9da8952ee790bd860\nSHA3-512: 7ea1680988ff41ff8d7c0523883525bca467f139c213c9da4098f30dc4fbd558bd9a90ee4eef42c669a9bbb109d3b6d0b09abb3353e4cd9c7794f88d4e232386\nSHAKE-128: 87ce49eae21ee9843e34779b739effa4a685a599b9e1144c6b02a725e497ec2173fcf043dac731b7d15b971c471bbf69965959e164c83016594067983567042afcdc7eeef3440a6ca8412dc9e8eba1a59587879a4e47fe7ffe5d232290d990db639cd4247699137ce9dae8e531c4cb859463b92942e69c2b60efe7922ed288614e024473baf81473959d5b8b1b04b7b77b3d2c5342f43768332da54e586acc765714e6c68034d559fde7ca60eca31a39a397bc47eca2004a08059b8a8194297f40544feee115d282366bbe6ee3de859be6d98041d3d50471a0b74fd8da152af5fdf7ce100a42fb38e23a93c802009d3951cb0c97857b5ec5adac967f4f5175b84b4314e04f4e03a0a09ff0508bf19accfe2ce03abe0f4cc8a89c519a84886f574f770115010f4a6dadc63fd8bf590e4fa4e75a0aaa60d836681e1c2ac2b5e3f411a3dcca70e4c21dcb606e9d62acb0603334b2a0a619f177f20cc48f0fd4d215786e35724a84fd9af85dfa6e21f2ba41b5decf58e42d476e7eceaa5ad3c1a7455f01df614d38c1ce68dad0172b88d696aeca8748eac16b27ff4681d9d867758579a83e2df2a0ed3b17405c61e30f80cdbdc445c6e84f5738820bb99e5683e1aec5f84043854568829a6a0d65d28a0d53c398ad1ff45cdf6e7f6d5c6782c124be1eb1216189799681f154606a6d182323e94384702fa95a5fa9f84bf1e9dd8556\nSHAKE-256: 50861d074d5c375937bda7b0cfcdb63d2cfe3feb0a48fe463ac45699ae9c0dd0c843394cac4e63cae1f8fe86fcb3f8e42c69d49af6e854f91e57f7004fa1a39e05b5429b0bc219765b0d0f5105b95babf3bbb4382b1fe2e9969841150b791e02877827c9ebd833ee8050ab5098a9b7ac62f9f1b5921285dc1aa6d237c3dbea7259b972f5eba5ed6f0d399066b6eca67cbe66493cfebdb6deaed459e546554dc783d3f1c68dc5303bf2d96020b2f2db9217756ecbc53670e7b704c5717525e3890e7cd3baeb508ff3ee5a36ba2574ea7831927395cfb4680632026f7c1bf41c29b9ca3b03b983f48ada3f4a251c64304742f2a868ed0c081dcde6d227e62a6456ddfc3b13def5d4d2b9dae596c5b08ca11db82dc51c69054d78a2bc6ccff5070442127b6bed1c4799e0324f2f0272e9f50e698e73de70a7f65bd3845c6f77718853d6c095254d2f1529894f7c10582156fa7cfedf5320d4cd06423aef0a397fea5a2bec0db12cfbc3ee431614ad40a4382bd9fe98d49ea0e6bd5c2de9fc3e40e9201615b59cebedf3aa8f325f1b43d2af859ca9f3d90d09f0824eca37b8519033ed55f34407b6d5b12639818c98f1d488e917ba5c6958496db22eae39b7d32004f5afbf7bf2a32bd117c64d324b8437fc724f2c51086386972fe3769089eeaf6025fc10186425f1b56db0961d6275e09880f4b6270e8dcd210fe3040850549d03\n\nInput: 372e38b1bfe43597a45b5ecfaa290b7d699112f0a7c7b6a6da75f4c6cf36e28b500a835e9ef3f1d1a37e45f1bcf2ea9458de4cf1e8241a39d5dde527fcb3bd6100f8effa6970ea6369cc07afa21a18dd21cbbfe096b1260187d062d4c7bef630fc3a0d23a485df7c244d3d20aaa9d60713e25ca30edaea1650b715de51cd6378b4d1197085c0d3563ce880c0acffcfb26ca79a3d3ee8eab4d759e3cbf2b791c096b8a222eee30e109904e1ac0e503bf81cfe1cfb6dea2bd5de9ec73746b45e39623659a02842b0e434fce12aa9f031aeaa478dab30946c4550cabd3232b0529173eb9cbcbecb261233b420fd24c0bd7c24923e14263c0cbcc392c7cbe326b6587c95\nSHA3-256: 7f372aac3ae216bcd2a4fad5ae7bc83f23c031bb5308dd5babcbede1e885a9db\nSHA3-512: ae1da5eb3a351c42e8e00237374afa065a1aa5e3507b283c88c366969253b1839d28bb19ea6ef76474250f594a5ada641ac8ca4f3dc619cf304b454187aa5487\nSHAKE-128: 1435eb767d0ffde116e111741fb9af48e6e847fe8c5b95639f7f5881937c6bdf1a9483f7f32f95cee3e1cb73a8c3f0e38c81e3cc6a0e34279fda784f7bac2bbe0c1f652c5b6e9da138c4a318dbb3e02ca09fce6b394eeb4232694af4b169fe983802d75e5b2b59e6bc606cd15643a85cceaae5184af607dadc7b82374090941a9df5f4adfcaf321b7a6191871841d6a974da68f18bf8f3af265ac35579c606c619c1df502ad978f229e53dd092cc3a6e5dff9df191f3735ba493966e3c7b5a1b81af45f51e97deed96336b39f9881801ee89c0802ab5a9808598695f64d94cebc4db9e022005636dcbefc274105bda301b14056a12deceb75ed0e1c8acf9945950d205cb0c82f234829e53e96ad7cbc4dfd199fcef21ed333ab26774ac9fa83143b741569b5c664c4af4322f8fadab866d21dc4f0fb4741b45d7c4752a56832377a53c245a6857495cd396901218cc22781e72245feefe2084e77111532c1d0a2ee02a7399e77fcf3d20b68c796a650d1f3b3bde693d4e10e1f4be19dda99048fe06f41adafde18878220d74ab7cc4c4c9c1f79454340f4417d81e064f378037b9075427f53e40395cb1ca879e829b7e24bad9ab3be66a505494423f956611d7ac42969fa1196204fae1598d46dc52472a6c7efdafd948d60fbbc44ca793f0138b0351b4a14d3b410bdc9e9a32cc7f44fb3b5ac62b760e65307f8c6b303d19f9\nSHAKE-256: 6ff5891efd350de99e5fedb237a718d1d4e5d5bb2ff0b75de1bef60a91145ad9d3069b9eb2b0e0df058d5b18bd80a1f55763bd30b1fa06e4fc4147b7862427680ccdde7b45d66323dde0bd3372532d4ee08d0add32d73394dedf8e5b7be358e85fd1549c7bd68be27bd365369bacfe69c85bc7ec50f6abbcf1cc52610b715e9cfefe14e6bae138750acd176dc61da6599518e9caf530f52c4da2859b1ef2b4f08c67ebf44ccdc884fcb0bad23ce790344f1935ff9bc49441803bf2b3404c1029fd7497ac0c3ffe11307cf5c565ae218ce383128ff0318edbc96a4dd4fdd03164bd4caf43e29afb254b2e1c16850dd7511bc4b845fc2149ded1935f2e262ef3b4f4f451f3e94ab94a4c2ccd12ce50651e4f20ca854164d28cba30a9291c29d28ebb728115775e103c1403518c78167ca54c9cf9c492dea414decd1d610a605adff7fc80f34376c1dd5e71250b6150c5f961f8008c0d764f87d9b2278fc081a3390ad07766bee11c867606b5eca91aaef192c525987abfffa45c7b14d48cd5c36a6573a181c7b33412deb9327d994d604726e9cf8ae5a0708591c86e9481d95358f232a166419fb28dcfe2e94dba3efe926ac122ac423a05229aa5d0bd06b67143533457fdaffd643473ec5184d09b273eaf2480dcdf3b594ee0ba11832d69d1e003101b25ac58e58c0c592ac023228541607f213af18517ed4ab62f0de796f9ca\n\nInput: b64032bccc18e4778b836f9925d83f96c6e9ff00f7ea1d48a356010ebaeb1080ae628e2fccab9b0ae65fb3c096896cd8e48c9cfb1693a2410fad9e08b8757411f0a186178baead3bb25dc26cbced479d2dbc57e963258ac60106e00062ccb596a3ac38c574aace0331f5bd342194ed3422f01b7ae14ccee79a74ce8c836dd38d44602ba8bdc7172e705400ff68cb0c16daaf8613eaf45fca09f7c43a830898e24523bc72fe4bc3518083fc5239388433e9a880f1ff813491634dc024a72cfaf03921b03db8e8e24c11c4b2cd0fc8756cb61b337826619a9c55adf8ab925ea51f014ddbf968cbbc4a6bea8b278cdaad6dce2aeebdae5c3e364cea8ade2c8eb201b1ef1d\nSHA3-256: 537cdd7fb96636ece72a599024deb36607b0964a47053ba68d34e7e4f4d41da7\nSHA3-512: 0f0f54f8b5e82d8cbd93bb6ed419300657cfa2bf41a5c1bf4757739df0e2371e1f69563474cb66603558fe55d5d923aa98b05f9ed48d8ac6bc1550bddba21608\nSHAKE-128: 4793ea2b020f54fd4e6d132ac229fc81934e5f615c522ee6c6815a093b6cb756fa3b945a79b8f2ed76f318e029f1e2159257c504749c84696504c0386c0f3a2a97675fc9083338d1e1ca377e1db74718f3a609f472896f83e321d7407aa675a762e7043456bf2a6c0728e2ca9e81946338b1b53ac9f6dd44c24894b6462842be2f8d892b24758ad4fcef8eef4eda27424f76e9a7ba46b4f269c703088bfd6892353dc9b6eb26ab62dd8a226c86bd2a96a5d9bd660ccea0de506c8e84ffccf797db27b22d2086926667c69eeac3051cd4b19edd1454bca98eda48208f390119d69bbd8fcc93195fcc97a1619bca3a01b18e7e56198e9fcf77ec211d45d5f97a3642c1860ff6620954f2c1edfd48ff9676364834c33d843b404e6b4c38e9d82b0c19130a54d19d701e298fbb498c2df341a5b4acfb6fece92fd77c7f19633add19f3e2abef828a91fbf19d663ca76719daa466d44bf6077fa888b7623c739d715f8ee260eff698edf2bd51058b315e68c5e7710c5ca6931e11cb7bf29fb29b8325fc60d265ab05e68597f62679e4f48757f8407f18b57f6451a1f00f49228a335301da4f939a3c26005db2a80c00068dc7db20cce1e9ce31239163c6c8125d4bd2f7a49a3cc88fd628be4f720ec80837f380a188c911f19be69a25b5dd188d0df1e21d73d0bd38c2e649d76d6806ffb633fe165691f2f64861ba5ae63fc9a73777\nSHAKE-256: 11336a7e6657409ef191555b7feafc4c09ef34ecc4155500a19809362ff0a265ce7f7fa92147bfebfbacd4aef86c80ea64c32f165759b9271dbf85b6e0dedd3d4dfcdf9ac7f060f5bbffaa06a7306608e8703b21338a386b23a556daf150112d75143804a9ac129c55f1780a228cac0d5fd522d074d362d53e4b80bcadcd045b934a8f950ffc0e9b0495a540c9ea853c69877aac60d740242be1412473d271b59e5e295816034ab133a4cb36b5a2b78cd227ef3914ceed0acbc86f8a806eb94050ea177eb280796f84c8f03a3e09cea625edd2267c8238f03937d71267e1279c7eea9aa43fe0e9b59732a26ae1ab1db2d7697fa8c30baa13774407de8a3b708c6f15d995623969ce684e2ef109e", + "6864b53d6c0790dfffc1f7678cebe749c4afeeaf35d9419816e892479b32fca9a3c70fc0c5b5881ea35df79669683b19d64fd0cb6cdd7bc8ef2c9d1d71675bc8b5aaba6f4cd2892cc393583b26f16380abcd1e6ee3863d44b00994e459bab128b08e9940787242840c2bcbc0590da09c6bf001ec4943470b8f5bf808cf6504fddd0bd3b18b0f53c66035940dedf81ac5fe7bb472bf1448a1a6d81f89c90bab567f01c07c6d9143b20692412053f51d6c59c9f9ce1c5eafd031e061bc91d579cba76523d6eda947b31fb86dc12116b9ec0a6eb5e8e85f632e5895a3e9cb0c61be67c24ae113d23b706091dae1d1becdb4fad95\n\nInput: f97714080ea30c7afbca0dc407110c2748cc16f55e8046dc98c3e0b683049141f541d223f3ba53f1bd566bc583f338625f449769f582eb705e754016f1a09397458982951ca67d55312647d0dbda6e30de43c66aba4d7d67ffcba1b9cabaae8eb853c43046c740ba6c2bec18b41fcab944c10e434e913714e3dab11a993733d85a6ea60a4c1821decd84ffe953224ef5a3f9f7e1ca46254e6b1bde25adebb6b11d564b8c3a06b22a317340380e2e7bb14682608dcb7f2a65033af4fa6e0687600bd608dc270cf6b6d5bbb70bf57f298aa833947476b68f7873363e342620ec2ac419da6d5272c0cc7ade9aeeded2837bd851d7c89c63bbfeb35a43ff9db6b86912e5f510\nSHA3-256: d32656bd369c791d043f53633885bff8ea2d12f2b6061f7fd9b5f263541527fa\nSHA3-512: b63a1c499396a86b55b030de972fb6f0cd8e1aa354dd31a7d4848cd9b092576244fe5d317e2ecbbd2a5ee59a51a7623a5ae7d1d8e89be3acfe68e298e4edbc65\nSHAKE-128: cdb8e6b07a17804a36b18bffe1ebaf30359033d8fdf0ef71a16ad2b68f89a7291b6116b7e8bcad5513f1228e2543f5992ae4aa51f4fbe9534f0bccd8dad0520e9a05c7ef6cfadf8b9af7ef3f046e026a0fdc27da387c1f93d3f6e46083879ad08e550085f9b3faa74fa95aaa55499732c85952a972f102a62aff0e534de1cebbf828d357b8af0d5de0fbb6f84eeff42d7ec579a92714b7c5cf7a34486e98f24e54b2e5554718eba33ae517728f0d6cf48908a7d7bd0c4af9190f102bc6d56e3a4fd0d52e5d88f091963338f5412c07fb1df31b25646e8e0f84870744108b300cee3360ecccf657f7a8ee1d1472167aa191208c377b779947cc94847432f8c8fc1f64f5aa845ed65c132e5aca6ca5b705b15f97ea430091358a76a38249d9622c59cf3396e0b7fcbdf5687e5d8e66a4a76365bf1ce61a26cc9f6ba450876c0a608004bf5698371179d374f42eec3dc81542389070e8b78f91fe46c4192b355e6f858ae2d62a639b5c44c123d4703ebc4d2c3b0c36ba0ec7847954ef120cbc6429d561280e95b242cfb30e3bbf082c2c2ea5ca3d859a43d51194a566255a6f89301a79c285f592ffb04d163a09943c202d8bd1abbe81e6b77e90edf2c1fd3a195380d00fca26d04649e341737cdf31a0abe444258d03a632624b881de45d2fb88b3cc63b1317d61bf7bca7cfc5ccbe3b05d46e8b09876d38ce293494cbb96408c7\nSHAKE-256: dc836a3e48b065ef9f86a4ed6b6a09d975d399dbd9a195000bfb4b97c1d4f0e70251ecc69259b22303dba9d967a903085dba660efb6ec5ec925e57fb6156fbb34e89bbc6f61cf20ce3a091f8aa2541b36038e672b785b0d5db2091b42a3d9c6e211a5b9b9645245f16b3898b80da3bb441f04c3a9247c58c9af6f390dc042eb2e58830b0ffffe12b399b7c9b1d5c77ee0404c43d43be71f8dc6f586fba7aa90c0d2773b99eb4ca61baad1771c3f9984a1224e4f2974013751396f5cd9367d3fe14c2aed6bcf54ec2de36281b043c4c75819f4cd0de3991050e3c7fd546f359ea139fe1e615bd516450a6f9ba694fd2a906bb9679f872bc413a725e68552859ae56fb091734b5f5dbf9a1f30e470fd1e16c5b37767cc39c00df0dd6fb1d118ff94a84f4b66a7cd22b658149e26c4cb8c71b382296776771d30118ed1d3943ac3fd6c2b6026a0eb06869d666cabf0b225117d38d470d5bac7d1fa8ac00610ae2e8983945c0c7b1db4dd9715d26a0b040a7924840b14b569f5a8093ddd4008a077f7def482f7044d4fdc505622c8c236a5accfd300756ba25a865ccd2d5c6c746b1894f4fe71190698168b39b31ba52d36598722580479f4271d37b06c1148f7c7744de0710098d2627b411e4491dd7e5c63bc06851187711cb1a298710d1a993e42e21c6d791c4cdd298635aa3b78576e5fe80fa9f11303f7560a1b3ee104755fb\n\nInput: 860b94ae766975e4e2021bf79d312862f657a91b718a2a73e3131d289a0264f5c0c781c0d49268f91d65301e558f5d90af55e2b4f1f9dc6cc9aeb2dafd7c1b576a5352816540350a2ddce7c7486c2cfbd55a37846711d91a3e341638f535593fc50aa4543df7d12dbcdd5fb2ce31a829ff66c11096ad9e43bc32700f7d3bebbb100c41ea38bc9d729d0717fa09f23b1a37867cd1a50ebca36947d552f3e1c0a9e4cf56989b46866336727ce1bbe7ad206e49157bfeaa8a45cf0df032bbe2fb3a6dc43381dd8f70a0b700fae4472252642610f5765ca864474d6211081446946e57244d25ea4287622d0fe698fb3a2d26093d333a59dc2e05ca827c7342e565232dc2b0f677\nSHA3-256: 679d204c34d48a235f50173336b3c04529128927cf736579c9e66495a103d666\nSHA3-512: b51b8977882e708b58a655afbaefdca9426d9d2d080490b79b7863e2c9c48cb362d63f3624d38371e381658d04b6351d08a67139431961a277044cf3c19508d4\nSHAKE-128: c27b9a9c98f3cb2117aea392026cdd78cd77ce56912b474a6eb963703112f2f8d3fdaba277952c9bea4aa834d2b3489b8bec81149035c3b87e4ee11b3b99fb9d251acb079ecd306005140a5f3bb393f364be252e717e6b7c3191d0e550d6c255b037f42bd2bc8036786a5977ef53058dacc14ce83938d07259dbc6c585f80a69de5b4f0ced20f17d1f0d8fe5715c2192afaf5be37809dd456f8c47bc8cc7de9d62779404a047bac8dc60beb7f5c09a53de5e623c5bc124a77e64eec1d6309a444f72e4d662bfd2f82c47f88514ae8a8d7ce9d78eba16b48256bcb9b07700458e48c0d35fc4b864c5f2871ff2f7242c63db0f8c4a58ff2314b49b5a0c68e3a868b4d3011aa2c0f46858a8f78b3e5e9c6cb24582f74949884f92c72afc4895e5c05982d067150268ebf01a9905bf7ae373cad050eaf89f462c790ef13bc80fc622a3245493f5fb09dddd3fab9ccf8bbbfe4d61dacb23b67b8c92715d0971dcaf885604de100ff3af5ba4d204576e784c57c423e434d2e5e26f30e14e9d456cd74d26083c37382249ca363e4a496152db430de29c873b8ef8cb267e80eb5ad09645732dededde8f261f68fb6ddbe6a5d212051bcfeb75c116e15accbec86528977ffcc629d4f388d69ccb1e5b24021d2530b983c0290f18223afe8426a039906165933121d39bcda9cd1aef578b5ee0d9611f7be2ce2f6afe260f7986c1a7a9814d\nSHAKE-256: 8b0cef8360d30689d77bc874e903ad2be47a6dae4f51bf0efecb41eaf44c48fcb2977c3ba7867358685d57bd3858ef2acf760e73a5e04b306ff1b8a80030985d4ec5725e9ab55b8d75d5877c6b882b2f8552a5a2eecdad5d1ffe5486777870a902c57b3b3d6de658c439d5368aaaec49d774ffd9e139caacdda9c99cfbf6ba12739a0cedf02650de2baa9268e818767e47c8b9d6aaddcc4e207d7cfb5dd1365c0aede37f9239790175126261a6bac7b149ceb64e02c3f96011e2330d37ffd2c6a767d548b7f6e5aa6c10e2c5d8422ce3afff13fede3986e61f764dd986ec884b1cfa68d34ecd727c8d9ce04c809b559f94c3db19ce3df274903ad8e5d4c8e23c25d2fd42f6a6a5882bf6b915805566e61e2ec786242add8876ef081cd58ea732e3cd9d94815527c099708826114a8976e65ac5f6a009780b926bd937d950968a5052f351a0913a21e6bfebc65e6e62f7b97059b787a5150a19569c30ae6125ccfd2f21178e6cbef9f8244fed1aa8697edd104a8e0fd9340915ca0c67b2d001533858b384da324fcc711c558dead233b02ceadf4a9e8b8d6d1fc9da00904123db64c667faf8864edfed0dbdf1452fd471dc17ef5866097c7630ad1aa1be680a9aa722e2ab42d7be2b8cecb4a89009486d2ac6164068797b2369e593653284216911dbf270e1adaca7e9104f6bba02e9d79f932f1cb666c395866c8bd2666deb78\n\nInput: ecc4fca85d6ae5f6bdbe2e411f0964fb143209726445ef2df21ab4b0644abe4a6d6bfbcaa765b547f70fd5c370706711df64243232e63a680c9176034d1375988e0c139df06c1a4d1174e36c6c9f6e837bbd4903683d41e298645c88d6c406619514736d73d8fba7f171780aaafb5c1f6d6340fdb341a8fa15afb95da511c88c63622628b373c882f45fb7ec8c5d0640bfdd609ef6f0fe2769656c07b289e22cca6326879742fe68ef6b781f1aef435a805f2a4912810d57803c4bb78d239e82ef52def50a86605185a85c668c533095254d7c156dd32a6c7d40b440df46afb30a395aa60ac634a18264f742c194006defa4bba52321d28b28527817d2baccc3dee13db0806e\nSHA3-256: 6e624080602612de7a5802939448416871eb39399beedf01998d696c38af16a9\nSHA3-512: 404190b936d6ab530f63a61c5dcce09990134c0f5cb89dbea7e2b5775da0170f686e7928b4c77843f6a1a015d5b228015c95ea41c539d61b7b8069ed745a88a6\nSHAKE-128: 99a1fbb0b208f1db63ccf3b312a74f472592424f35dad8af2384e47ef2763639bcb2fd692f5857598b36f6d5df8325a066a3998e444a45123d0c740823dbc987c1573c62a5aad1a8724d248a1cea893e6b70929b23c7d1c1089ec9a6af13264f9bc921c274ec2183a9c5f564ee0fe36b6fdfa6760d06659e54d1f07c58c50b746ecfdfd26de12d590f5c34326362c79909d09a21765df6d1bb1b5fd8924031f9035bbaec88a29c446fc148b2bf0949c425b69d565333577343aef2854399e48d7dd97897bbd8173dc30d4e630a2c6e7b5d12df5cef1909301b9744692898431ae7d4b8c1f65d7cb771614e9e12e392e50dd9e41f730f271bcdf5918e487ed6a2630e0fce0cb68943f63621f254e7d8e901fc75ded54d92616161cc4dc24520f38bb9fac314d99ff6577c8b979388d197ed5c9b2989cb9108cd4159c12007c10a11787008e0e25d51fcd1f5712f875079c7a03af3593b97e7b919cb7f63102a9fb47bd3959a182041a97b4ff6a08d4632060ae6a3497c537af27527bf82797d42e8f4bfc995de5035c2583b1c8aa9ee1ad6d17fae1a8e9962b2cd12a05d0f8613ac710abe6f369ae15f7aa1db66acb4f6f22dda5076fcaac7f90a9b9b9f33b75a412974df359af73a7534004f2e9e3b1f9702cd96931b144f93b93efdacea9f8d13b09a1b982d74e2f4e720e18fafe3681b7934dd26a2000d0ac1eb5f7250f437\nSHAKE-256: d43c9b6aacff1221a97e3a6a12ef2de2c03cd827385ddb0eaff3278c659f5d45f57d68a7f37cf9d3d6d0037a3814ff1b58479141636a15fa58be794047ad0ce1266d2f3028f979384ad14dc2c2d54ff37fed0c6381cd31d4330f3f1aea362e8ddebb376d1adf1d3d73ba772a594d21b4e960d103e6dc2b36b468855c683db0a2762b1daf73f0a82920eeeaff", + "3af4acdec41f6b131b7376ce432b2227b351e4673d2563ddde8d778897dc25f9bd1eed68c407f913168e0853c22a3e3aef3a64a58b34119b0d847d76e88df6efc530884e143b97ed4cc0d2f725760b9226223008c53aebfc7f865a88da69be3b7f52d1ddc914908e54cb19e41064fbe6a41f46900eb2545de6e88b44ecc62fc87fe6e8aa1a9fb927c5053d73b7489da48672ae0cdbc0c8d741881c3b477937d9f7260028a23cc2db5f5363dae3410f2d337a60044e17a40689fde2ea30d0e67faaed2b50b402f05fb09c4287b799d0b002e2108ff7909900fc7ff141a0c67b20110f77822ffe5d433d60fdeff5a12350b346696dd482757090b106d2d2d8394ea74031b95275a333773d1c7081a99f2c6e58c986412921a44742ebba8983425155e46c5e0ff13485743b12d1b54772b177a21f5a63b0478d8a3fedf314e939ec97e322aa34f62f85d5ed6006d4fcc0adc94e5ab918f593d5e585636db3e65e65f579355fa87758f672b4c381e1d8149cd314bc45\n\nInput: ea3abd219495e92ccf6cd69d87b07c67413510c19ec7f2f73f758db43481889160d66abf22b4640fb3d2b992bba945e7da20cc40e8f3f91de66327403a7d6af2c2e3db5f79c4918e9b7c48d772733ab0df94720b03233b367911df37ac43d63289891db8493a2f60ae69de9ecb226a58e3c9c2b2d433b7712ad4c17f0907f1fd1cb22cd8f961c6b7e82df2ae015226f1ef618958b789904f6e99e1c4e783ef3dd836cf6bece8f1a36fcdd0033716ff4049a6b457157eab9dfdae074724978f2a8af40ecafe399c4ddc7a2a9f3301cf554d5cff2e84af074c8c4e4a0508139a6fc71ce5124f375127abb21de9bbe9ca795a8fe5e1df19170d5b049359a4be663c53c31f17809104\nSHA3-256: dddbe45be0dea9e93e5c1a17730146786ac63fe32fc89dbf90cf18ad3e88ce06\nSHA3-512: cd985dadf6842700b8e504e021e4f366d2ae71afdd60b0f1660d6602b47450dfcc517d666c8f438f1e4292fe8449dec3ec46e28a99a315782535d0ce38c3d47e\nSHAKE-128: 022b80a570ba8be5d3693c8487a318083b5fd44c775e74172dcaa3d9db38dc86c7f7d2bac24adceb87fb831ef61b1ba93cdd1699807d3a923d937108acfa42265d935804bf10707c7c543bca94d98854f8ad05edaa8a5bbfa5562ddba3cd41ba6f57ab438d4c5967bbd8bd0ec0152c36d8bd0d40d3c9488bc9a77f9b928d3fa560f7abc8be7b7d48a53df8da0157ed51ce13727eb2f0de1c2093819eedba9f85b2289833ce7f737dff0093aab8cdf5c79d77a526693419a5bb431d60bcbadb833379ec1c9c9b10f1e4027bf479f128069e5f1c2e048e773e458039f9091051eb9347cf89b2adb7d965fcd9d433dc7e19c8d559f3c61502d98d9b211fcbb045d536892918b9a535765420dc554ee6e009d3fc0783a24d22fd65cba8805f9bf42572efc871f7051a2f3e576dd46bda87a126bc50b1a2030ccb1238290f259a9e52227c931ceb3c30402e330a12972da384f0505955d30d10714d35d59e2eb6590911ac9e9b4d42519ccc253cb15b445547f6112d734f2c3d7bbc4d95472fda503d84bd3951b2b22943ca7a5b0ccddc67d79dbfcda61a3c2e7636c333d50a40ca0ddc3358f896700b352a4c0003c2a4c17a13ebe9d6c517cc38e40b6743f8a98b0a4e4af51117d3a38b727505d688098e95a45cfb6eab878569d2b5e0a64670f1b580b6bed3cee9d59ececd65ac51838b79d7bcc1f9edd61d70939eb68609ce5b97\nSHAKE-256: 6d5ace1d431e06c8b9881fe5da99ecf08233bbaf7b5e6574b481eaa0c95906b4c346869e2f824854fa1ac7904dbe9d29833188acc4d1f6417f2431ee66b8523f7ab6f4f6f635af061aa95425a04abb43b930d28afe5231675fdc8d30c904e30ee7e747987e033d0d47babd6ffd628ec3f2475003428e31db37ea528fa530ebeb261fdb97bd5bc3f04d4e26a96b675849045a48189314edbfecc3f7fff325c0cb8fa11a9a530b85eabffcc4c1673e5e0ed31e27c1ba3a58a2c6666cd8321d9e59014d6551d381da4ffd6f04d26fd950cb9500bebd5cc89408cbe6a2386e79906875b7f9006acc7e655d5b5b8057e7df427ad467deb56264d40e1962aa1389cb2362efa2027930767fa02686aaac08b69a3d98a88673da188929ab2dfcc0601ecf77e04043e7bfc5f453a3ed2b304740e36fbad84b8969242bcbf8a155a68afba2a72d1266f8f4c42f248d3cf91b3235c6831adc473529c6d7a06d097bfa05ed38237bf896bafe060a089a4583429f7147c12e6b5952cfff3256c332310ac520bf78603efadd5bdadcd2497d30ac2b2891d10843840881a7a0d4aded692710ac242e20b8ab4e031113654d0cde8dd3fdd97902fba1017d9ed0adb5a34439830968e9af7c199af54358aabe0ce99ee58de9194a1f2d2bb2c1a8c6ecdcae0ea14874702e79b13dd26feb9ecd4a94624876b7c2bf0edc30ba1fda8c4889637d870138\n\nInput: 3e0453d46201d0530ecd4132f04d72e17976bbd7cb28c4f95fb59d5160fbe71d9ca146631f230d0193e5ad11214d5a1e806ea19afa74fa42b9991b3dab38c64e30cc91bb2ff14fcfc8d84038534f3b33496dac0001e673ca73b6d99de69734ccbde5ce13ac201084948db5b4aea01bd835067c4a6cf08ed6611a6c97180eda5244f738d2ca18ed3e10c2ca2895127301666e53928b68a521f336dc0709433cca9f471f3b82a1a72f6ebde86f057d1dedcb8d67ff334bed59b320858dc3fa9e95f7abb18a50eec6d8b1a20dd1369b9d3ba969163bf4879f3933ad185e687c1fb004c5532ebf8b8375ccba949dadc6796ae5fb0c7b97672d32bb64954d46840604cd76294138421868\nSHA3-256: 8af8afd04bbde31fca8c2f0a885a463363d50f578a4f589cc91997b4b2755d74\nSHA3-512: 863f1dcefe4aebaf65bce38a8f2b67ce41ae6ed391a0860c952b458311b64346d944810d7bf694c577ad888e21ef5c1e5ea122030a465b129fc5597fb8054bda\nSHAKE-128: 2b44dbbeda1344b28fb2929c2dff8972283ea15c3f4428fbc3b8c4b6acd30d6e1a3f50701ed132cd111f51e5e7816919708505366b2065cc5e509bffe42c4b6b7de4878c5a897f08b3092ee754a537eb2874ea16b881e7202192b42b95a09299bdd49c0a63d711341cbecab39b76a68e35e1f4d15499be370ef46fa9957be5c5dae88ac05f5652140c77ba6303767834c02eed401868fafc5dee7544bd60bd2615e415668100c84d0f65d69adeafc9f360793eb5d959091b750f76ff678ba35e1fe3198ad06bdb055744fbf60070c9da32022c939a43b104b19af6e80909500f34bbeef18ade683b0eb84ffa683728cc9886fc91eb8ec9049aea84944f4044eba4957eddad1ce201e5df78259a987aa74df0dd56166bf0115d15619d5fbbaf1a220372d031fed4d03de366d5b27d5d123ef90c7af9fb7d1e93a52fed8bb841da570ddd6578786e8248b02139f5a7675b82ccd6e7769991264e1d3daa82e7e294746bdb7dcb9518119a6312efedf51ca1eab17053eb4bdb90de326768449ec4891a87c3cbf4fd82a5b8bb940c108fbf66e874627e1ab9d275aa76c77f294a23f1eb3dabf9e9ab0a4c9f5024eb745845a5a824bfc534db97da4633f6f5445157a720d10c505d23c54c35c268c3e4453e12dad27d6428dfeedbe8825805359004a83fc972cf5e6a38e3c29002e747f65c77640f1480ea1c04af6dd05ae0c863d2b2\nSHAKE-256: 299cb0887b20324eb9ce6589899d81e4f4086f73c563d9a4eae5bc4f05202678b970b3916c65dc2f04f8e47dd5fe33c0c4395b1c15a92b1ebd3dc06a7c8117cbaf05a3d609a368c82e9128ea571c2db826b1e36038179923e7358cebdde430d58f3a43b54b881ae3da85480ef55f224ac35a848fda0b6224d51cb776cfa69235cf8a7f712897e51199e910d46fe32acb339b5d3f6fe1e9649ea235be8531d612129f2b9323d8bb775484aa7e312d6cbce781e0f183686e0df3477846ed5bf3e0d5a16626080f7152896a33ba935bc6142090c225cd325078c0e3a7d13ecbbe28434068a1b24336a7c80e12ed0080b9377d36a08d9f117ad1f38ca56e0aedf14b7f22f4154e6fb7e6d0f4898dc54e6deb6392f889b716effb663c8abe4b2abcd4139509060201901a2ff35f42de38942f5ea7f70dd39eea8a641afd3fc678d3204c594f17c411ea80847f2d3493fc7afc382b3c89f466e6e7b75b6fee482d62be054811babc56a8e524f144c48a50f3ffd6437644d621e7850946a2ec2ac5b7d71b91c6e96b498186c80e2e0535adc4793d493f7ae857747174777552604adb4246a1d0f7a52cf2174a0ab8bebc37ae12eee67384c72ec6b6bdeaf6c85f850029e4165111c572792abcd5f1711f8b219c9dcbf4679af2d25cebb1ac3418c15a3521eee3c221f6b58e15af00079347d00ba1bea06674f5b2a0d99848d60fdb6c3d\n\nInput: 2280b52c769b3b0f66f7c8f8f8a042a2939ab120bfe2cb64b7e92c39683acbaa3089e3969e508696690400f2bfe874755e6a93c7d0896316949503c6b91524b4234f77ff24091aa72951bf087684678894417acc0f04be79f891ae73aa2b709dd95ca11897d420a0d3ca403522798f27a5ba246c5747293ece752fd360a86a0df0cefc0c51e9b4af95fdd939eb6d1fe0d1792a40f8d6fe5312d6e46bb388521966b44e3d93adb43abac0b4c8b572413bce1bad3e6c75aa61828d479ebd8bc75a1de0fc9107eb83f0904274a2ec9cc08310335efa6f27b65c9252997a5fba04b309bee9e186282869594cdd927cb93ad64b9bf896287465e0cf08ed909383423823d11aa9fb496c7399\nSHA3-256: 50b238c33b1ed91bdc92d23e564a1fa387f04f17debe51ddb9f28d94f09906ec\nSHA3-512: 11042e74d21db4fa61e08ca79db16192bce7c8007f9ceba467ccc423d76939e2913f34ae4d074823014e6e8e078424a5f677f32e6e238f0440c68fd5f8b2b757\nSHAKE-128: 1880e87365c4f6029cb8aaa52013e6b64f86fcdfc351e1ec36fa11ff596633a36332768424f40a43c431945664fb8ec2aa70b611196edbb8af2051d3421b65a24d9cc4e2a113cc5edc4bc117e6bcdc6ef52ed2e9fc59faaad035a229c2084ff8f1f8ee794f7e951b12bbd2068194e37837da43ee7779d46fd8cf1aaf1ca9fce433e053a469dd1a67f29bc0e595b8d2064717d2a4342a1b4528fa20d28ff742c78379432f0fcea52e8d8761f4098ea9aa14642538d2afa42645da5186a49267516437ce3e63710c54771832986b2575792478c9b715d6e98baab0bddbd9ff6c029a16f695d4bed7b9c46ea3169df7cc4e664020d69bead36ecce65b8f0669caee20f1182c1278f74d99728c8b9a632702bc3abbfa3709b3222a8ac041425c70f8b2473389cdfd3c25b02438cadf78a25205b890b3b85f76bd12f2b7e690f07bd57b0759f98e78e597242b18df95077556dbc0d86a88dc95fc079ddc30e9d5648af62edb88498764edc0fa882ad49fb1b6da2a3fa27275626a50a88378d835d1399e63f1f9818a3e03d3e4b6462ec4f8e39b242267fb26f05ebbaae97f32a732348d8fc2c685730b1ec9cc91d59be4aab6536bd07a15959c6dac2d56284974506b6be8d5608dc5f89bec743137a0dcde1a70b89120b0efcf94a75e3e9d7bbfd2c2cdcee2127b0ebfff7d4c9663e78215cb4d25b3bdec6a7b808f8a2d2ac20fe085\nSHAKE-256: 658", + "1507caaf26debb329f9f912f82058d9fd2f94e86c380c466e135205477cc20eedbe601fafe327ed55485f806b8f68ea34e21fb10bfe90a91ecc3186e77838fc7b2a084e200c99f455b022b5c0f281d8216d72f0b52837f848745747db8dd5b6b75357d2a63bbdae03831897c624ca3fe4fecf774bf6e125067cbbdea226c6f96b3c08d9a5a45ee74e2c0a746a61e236deac32c0a3b1ac4c343cbbcf89b3721f28c153afd36209d43f3f4770c7d7fd619abdaaa0674f695a7ac209bae34851fc1caa5248c13b89b1266ed08ad39859613e1c072b5d2fcbec8e95e3e9f2cd0df7cce8fef2bb75b38fe6d498c0963188ca56c2ecd8c60ac49e0fa935fa07c19710a532bf8f869fe97115dd5c04dfdcb8594d20f2ab3e050e673e354a6f4b97a835590e3367c9c07b63c88a3ea86135982269f660bb7dc9a612be6defbdd5e115b711af1e17ddd70aadbe346f31585233a5473d46bbdd0cb5a77af5e499989ee4b479ac30801836b1e00f43f8929245d42cfe2ab8feb54fdb9b643187fc20b2f4b7fb1c077737ef914bd251956d767eab53424c0b0337582ba36b5d3801b7953db65251a6624aaf1cd8e8bf46c3bb4dac37acaf9acbb4da1a047011e732073ec56ce360de3e62ce605d868e8469c79f8e97e05e0edd699a9c16255c0628129774a8678c724fa8781bdb91a8d628d571772001f5a60d3d95b2f8afd2c4a97b1291\n\nInput: db13b7a10e784182cf192c757990c3dc2e53eb4bf9e4c62dae0eaf851ce12b2c119a6df26295941fade477eaecc72d3a927704db69d44eacc6d057c6998d35d7ce53b03e4bffe6d7d025c018b8116fc510da09fdae3a3e25fa51f8e7e9fb370e4d2a01fec526b225004888596fa12244b02c945a529b21633993de3ec646fa8091c156f866f2a5e3c2449c0cfb3b8d6821ad7edb283d1a71910cd53ffeee57a3d9421b0ca8e45959ee63a38efd823d41d92c937945b275027038630484845e85f674dd05714832459824d2ba821bb6ab1851cacab5531c18ae324e9d5f57185048ee18422713eacdb63f5174f3882fedef967212b514c15b23514e1369340142465bde575a843dc234f6\nSHA3-256: c76dcaeeff89e3ccd39e92b58e50de06fd760147e130ce01a8bb8da74066a06b\nSHA3-512: 55b31d8af2131a459465339d2f03b07ce47afd131df616c8391189b4f2545d8143339d07671e8f53895fada7d17dcb55ac74d2c97912676298609f0515689042\nSHAKE-128: f92622f229e5025c85589e5cea3d1a78d228c75b6169e6c667e3960dd6a15c5b392e4c73ea31d036d4df99401f30697310373392cc6777f846bab94f80f241190be0f24536ae9f0a02d2ce57b9b4528975a156c03c795556a9febf69ea295fb3ebe06cb1ec9276bc601b367dc79de47c12c1720530adb85e2cba055920fcee3c48fdf28ca3bdec7b3649df218437a6ee32ed76bcbbdaba19d0c6b84c0b860d78bc12313ef1382c5afec61baee174cbc0870b0707f1344a5d314fd109da6d287ec1f82e91a02e6e1a33169ae923ed902d9b08e2a77fff309cf0d32b1f79169d8983f9bb8193071d526f7c35ad0f73b5a3e5d5a5b271e1139363865b95a40544aff37878662eded46ff036492a4961add068565ec8bc218255074f199e629897498a8fbe941df1e7d6ba8331192dfd37b3f85716640f8bb253987854050a558f75eaf9f5643216d2a76dc328a4ccbfbffb9a92f62bb48b273288b7036853aa7f81f28832efaadb1932d64d62fa3a9db48f387c80afb634f6e8710232039edb469fd877dcb8d9eff8ff59e7f9bd15baebdfc09cd6a1ab0dbd2d2ef6b660b3d814bead3eb1b5e35c8d33484b8bc2d38994fe44503020ab738c6de2f971d8ccff05bd6e77de9c71531fd616ed526118a56f54f9c7b70ab01ef884c8ecf347b6e3ad23b8852bc778e3cdfc081777f86eaae791a8ca6d4276c586659bed8f83d32a8097\nSHAKE-256: b6b95881fc769f27799517de1c29137654c1b5ba60466789fffb3299a9a8f2f66de8908dd5d0891c70a3355093e729f30acbeec68a6fcd3cb00c63e3cc5168dbd56ddc88c88fb9315670cbf44a3d4233f2230d83971537288759a9b270059250ade14b776214d01bb0bc2552bd08913e1f9b038276660110a66dcffc77f8af37943f96c5423654ec48a069bca0519827e54be4750fafa618d6a61dcaabe320eb3daa19651f4785b6b572c4eabed1bc4898953aa1ad9e7a61dd19da6c89f7e5231be40b011a9f160aaa64404eaaef358f1ae0745f3f5d67b7424ca9017b6cf278b2872dc2326f5d321a541654260b72713ea393d2155f57217d4781923da3436f05afb18fdb90e182011c36bdbb0af600e613057e6412083cd357b5036b76169084c61dc6112a28c781b3f60d8e283cc92e4603d86d96f3f146ccd2b93b5a03ed851cb3a2b13f9c8fed06068046c131fe4acc558397860a55f06e20c735ad1cff57a8ab59a2e4bee7f69e1b7312345b5a0431b5ac8aff3b54b34ced32798c9e2fcce3ac3f245b1242983d83c4b7e8a7b80b662538c4aff286c691244ffda9726b6e524eaa32705d75cb7b863040fa47316dfdf84609f062512d3104f3eb42af2d6cc2d78162deb1dab8954716d42fe98a488af0bc94645403ac0c88b34eb8612396d1e3b5a9ac0fd328a8ccb7c43378d79615ddd3333db6ff129b31e49ab09942\n\nInput: 1f8c348b67021f6fcde33f05cfc9987dcee56a056783cdc2a3025952930ac0c6a649240059928dfda0f4fb1db368c41f65e3c191207ecd1d550506b808d996f8729deffe56904c7b6b14fad2bb48d575e7ff847ba7522d160d009c15021f891275351e4326171ac6ca83794438515de6788f99ef3120ffdd0fe4d0d11a492efa59a1cabf6a3250702ee2af51a22707d995743eca05f70090f2ca4e0fcc4b875a9af8b594ad1d19a1a7982732ae6d01233941d87c9725c122e02e6b83a5c12422ba688c285eacf8fad6225d63bd2ef2b12be2b3f353b62adc090f311f241ec2cb5f62e8ba473ad15369833cec5bfa8f52e0951e36a7bbb3e9d7fd6edaac76d1e7fe84811449c5427e5d39aa\nSHA3-256: fe373d6d0ac1567978d60afd6f91e756e6ef18b86c742ca9f174e058db5485be\nSHA3-512: 748ede4afd133aabc2b2c3e171b4a9adca376c94aa153c4551a047690f6392bf6b82eaf7384e46286556fa1453e683377013b4bb5a001478df8ad94f566a2044\nSHAKE-128: 0b9e23ae52fe34da3012a88592243463adbbb76026cd202f7a2ca2c54cccc81b97a844c2c9accdb9d6e748c12ec3ad1333c1952062ad9c1dceb590ce2afd0a943a1f08555103c38a45df28c94162319bd40605e5aa8a71c47d00731ae12f3b493c635cdacfe96073f09355d0967c727a309efcb1a1baac208ff48b49fcb65aa3815fd9b02383d3f52eea0f211b2a34f1f45368a7ce63a597d84f82113fec18648f6715c49f20cc3ad8e831d850c3e004e50c08760d6ba05f0f0cd2dcf5aef3a0e58b2b340484ff7fab486017adb000f3624338f5bd0f7be7718d24fe66de45a19c51b39e571cf7de8cc2b4f7bd739d1f94a1f01d71c588c093cec21cc8eae0bb5aa1ed76d662e3776b5e19f6ba1aa2fc7b3a9fd5a781c4ef722394164a92c14dae810f4d6304c7e4712b9d2222795b1237f3e00fab25139d9b1a53f89f7b216d1c008e350f23b5033fc1b8517cf5d0e79e94329b42ca1013041fd380d6f9d38025c419cb9b843f8b78f3637d3a42cc8be8f9fed94dc2af0df35da7a7f36d7ac0120743273812c0f2c41b5f25808309cffe6cf8a92d63ae89a93d8c184c96833023efc041dc0f98dc250469af37cb5ef39074a171445f2fe9ff7c91f4bc22e12a86cfdae248d146c0d9ca09cebd77f7b8d02e2a0bed8a1c7b44fcd1590cc3da849202be31fbe28e4719ea9ccefc5b7350fe3b2a2c0b9b3b0a40f9660a28be5e1f\nSHAKE-256: 70d864b0dc5e18a1cbe34ac9f2c15f369a05b8bc49d58453fd85c01f294a662872893e0512650aeacf61d22389f6b02d789369a47f7c097bfbdfcdf66710fde6530bd2771f8e742bca8db9acd9448413a0192317c49013bf7cc80ae457c482085a7cf73fa6d0d5621897b7940de8b7f847c189284db259a8dc7c1b07bbdaf2af3f8040266e369dc7b9c10edceefddff0c9d99e97c227b95297b80e3860f76bfb71956dcf93daf939a7102107883674fafb30cadfb0e42af83e834ff688421e867bb835ea79952235beb9ee75259b1e0db81751cfc728229a101e0a1aa51a1957f5682065c49754ed91865182f680864f063f7949fe64f2ddb3ae30a7c86e0e5ff7166860469de45b67e11e623c6206e650a10314da5ce52fa9185f1953dd3f05f73cc1b211910ba35556938b3e18287e940358197e3803f1c20045c5d55509fa2f4a886e70c298cb6b0b38589906b51c86d82d5e91943ac14b99e36c621097333fe584956f6a3d532b8f252087ac676918b57851a3f81ebe5f008443a8faab5912c8e1005dbce9196bc14ea90707cc50dba0af06323b39633edcc48fd5c4668afe2c65609a98fbaf7ad4a4e952952227280eb7842646e8c71ff5a6867d9aa2ca56958a793dcc9742923b2fed6fc9bccaa23a58509b6b0d408d0695fc7266cb3b613ebd6d2e3fa84ee0452f59cb8ee8c76caa0ad8fd282060bebd81d6c2ff008a\n\nInput: 729d8fc64fe6db8e048f6a37bfb54f5f069996a36a420e5f99cd9fdec2413391c44d780d65456bc74b3d40e20ccf8e8c6bd3b59074585ecdad26a824d2bc787b09ad0a44f06e54397f98e623da375cb8de601b9b5c6e9c035f2e8852ff1932daa35b4c78f9eb1c2ec1d6f289ea53c62878ee46ea5d89d71b97110b8efced657ac3a673bd4d1d1dee6de938d18591774d34bb6a689ba15a920869ba591301fce0b3764f78262c54df9b8304a7044fdda881fc63c652e484995635f214ac3067e1d42c4e1c81d899423405dc3e194b3c4cf2c0581984a72886d897bbe0a7cd1336b0acd355faa84f1aebbf19adbfe0e50141a779f1a610e773188caee1fef93f5fef77b62ae49b6a0c2e391399\nSHA3-256: b88e3a3413adf80069c982e91a8d1dc79aa60e0360bc7800797ba4cd9ad5d161\nSHA3-512: 41dd08a05fa731ca2b9c931ce8dc1e3733975bf8ecf907a80f0881d18063f19daa846c9d304ccae6f83f89f255f1dc0f757a62f2e81172ed91673757f85f0db9\nSHAKE-128: 1271c691206fa9b251e30079c7ee149158b8afdede5630bf2bb223a306d7b32f98e118139859bd223622806c1a450ed368bc7d2ba95716324f1e09c27526c7591b42e94eb79d8d8555b94bb5b6260d0c3faadaff1ba771ad707b66603180e3133e92d576c8d8d09f163502ced3835b761f798bfecbacd0cc9f890dbe59107fda82c4addb5230d24ec6c1bc8a8cc5cdb9b21e8f7551b4e026ef5e24469399796abba0e08990ed466ea3efc2ead7b57a2221dbac3b431b7c8ef8332c4c240497b48fd845188b63d0558a6054890fca64195e8808628345ea0dd6244094780230af73941256ceb18b29b006ae00e3e40be33d50c6e506773e823146bf7c30d3568747ec2cd3744249b49e701c6d44fb4a8302842c92bdb233770b063edeb383af3c6386b49233d7934d55aba009e57a88bf18aa1070c4f13c076429b9e186ab0ec76bd60dbf7503f8684b50c7bf20ad0c4a62dffacc57fce7a6f80ca06e97cf85a8ca3e5704fa18d7375a3c717d50a014d1d7db39c6", + "820c2d33a59688c4458db99a8b518e4f3b464d28901fedb51a98d92cac850573f2a4db4366a8d28ed68eed5d19aad1f8c74c411f7877804941db9e9cf21945732e131855625ec63d00f810900a36315a21e83c6aeb507530ef093945d903e012c16a60f81c5ef6eb2e2660b85553dc540e56e35c75f29cae6cecd034126f78f32d1f81394ddcc88417aba3a7\nSHAKE-256: 4921d30144351ba6c0756c47ea7212aa0acb53d8dec565b208cbe24c22c702bb810b9eef414f2f9e8b89b415c039008130ca97e4df3908a0bc94ca76bbd25804e19462f77783d6386ff5f22388c7ba6df626c87b9318681860cf01c35390d86134f8e99cdf9d5773dac5577f9d5295df194af564721e6309b27fb1cc1ba2bd84b2782fbb7f021e13c97ec84b616f41d205260c571bb7317022d9ff37d4e164acd291ce97e8b791f4c834b8aa641378fc3a698698d98a258ef4d81d90d6b80ffc70e1d4b5d1cd9bff8c8d57a77c5f85fb244fd05a30b1d4c39898bc258cb5c113691ff20bac89826c77d6daccdd9163863fb69775b427c9f860f5934c9a4f3ce291e3881ccefdee5f8cde1c840bff04100ebcdb45149dc7a6d6474c5cda3b2987c7a9c4b2df04b5921fb9fc661a12c3eafb2bb850c02dc767288f34a12e7f7d600f8e1af4cf6aeaf430f20ffc8dd27e95a1c0499a40389b5f8314ae580d740d4ff5295bf6a354ba1625af2adc0488e381fd864ba3496be98cb1c0a9e199dceb499cf47c143f7316a130d2237011eb490186464513c20402cf8c38dfeb9b75abee7062628f8259d439cd4a2b012a1f5cb1cd7e48fbbd1dd7a27b95a1cfbeff782090fe5a68f4a7c49fa8aeae1b5bf605a9fd618a92048d6a486bcd631787a45348587bae0237433b095bbcf82cc0891b57a75504d13943fc7a80460607ae04df1d\n\nInput: ac5d1dd5b325cc1704539bfb4b17f085985f358909600113f5e169922e7045f9c59f6ff70fd9d4832037c39728cf2933ebb087f40516c9d1c99a83f61f2416cffcd92f6cec5f681fa61d7eb4d12ec6005b3327c9574f1f5ab79229987ae1a3acecd0e207f371a22512696ed680f4e598847be3ed32b5183277735f1c54b8a996f74cb2e943ec67ae4b57225d310c6d4cd412b54d81e3bcd4d6999668dd94aac0683519c4e53b853651953774915d519e0e3ff9c70710e888b0f358de65a1571cf7366c64c8fd782bf3d3708a64e4eae8552a7456cec1b0301533aafcc34ee0702e8535ca6d0d0c89960611bc92fb536d63836eb3ea86332597e08f51d47a311f5401bd4ac1fd37a6a65a54df9b\nSHA3-256: 7693a6c5cda6c7e3c1bc7b13368664411cc13bdfe6f654d2f1816d83fe3c06c5\nSHA3-512: 8200f00e1b76f2a568b6252d64bd00dc7aa48bf434e63982074e72938588ad805078ff31509e2d210362e7603c6be1141bce80cf8c32cbd52b6f48e6f2dc37c9\nSHAKE-128: 8759aae658c0f4515e9651e4ced886d43ee9310aac44dc8a20264098be04e0431aae39818e09f4d4c631af823bd608f638e30417e8d032b2be885707c1750bf70314dc80f1bed99ace14ac691d8152885c2e63b52c3adeda7f44fc30ec03f5cb906518c205c6d1d1c2b1e3f02a765691156ccf9b9d1591491878278c51379f41434312d14a4c3503a21053e26e6e68ce3cdadd9c58fd0581bd9b3fd5d60d882e8569824be4f0b71ba7195f7e195ed0218d3e0e2efec064831312c4f7f14704af49ed969481cfbf5fdb29d03663964e5a93b8bac338f2bb061510b59bd85250247ddec693b7f910eda27f675bea89a8e6c4975eab527fac47fdd794847b98f15ec6ff71e38802171ee6bb51d684e752a018fc3b11114a99909f38755fb4b8824b7934b31aa9ff482c0862de142b1a735bde8c6fd009e2d6a6db98d2ee09835134df83d8744b0a5164ddac3e6bcddf2f0399dd08b16e91c6e24bb2bd07968cc6e3f91c8c0d668e0464dd7a57cc9b7b74cff82a87b7df53c792db353fbd6d00760b53e577584da643c7b9bc1bc4ad5f99d1e0b889b959198b47f3730e4a38b6aff25166c741d80e3e73bb876510bfcbda4b029af129338de2b31e870101b5a537fecf8021886945f88653d3563bc07461384c0b81df2ced4d67e58e62b4ce80c1071fc66a261264714c3d89a87e8f5566578c87791ed998f2d1533be06231d94e77\nSHAKE-256: 0ede8fa394fe81524fa2e05cf7a1b20a6a48c3e328c1409f2191e20dd4a1d6d9119c8548a7fc52192141c69df2f4336671e46cae068163d72d37315c00434234d2022cd27e69d2ae1ce1664e79a5d0f84477c8a03975f0de22bb013038da57113bde84e7ce292ec5ae0b7e83d0759b412d50cd0ae4f700bd0b2706b59611e67de5c05ce7611024f5fa2b822d43e380f30a22387955a4f33c675a004db855b336945ed9c7f8550529918850c481297d0207bd3cee6878a8a66f7e7ef857235785ee776bb145f564c466c133a294bb00b0fdce3e58bf877a7d940291448421547873898b85942da2fd36cdbb77f057d4c7f32eb0cd9a7198ac147e918c77de6625e64fb5acf342c76a49505db257094b5f614d5d3a2f49dadf556f267eb947125a75f488e463f6bbd2a8cf11cb9ce3b772f57db15b9ebd7e4b4f09113e8977bc0f5f7a1bf0fdf59a92f1e1380b88abdc0f81dae22c54f38a3939bcc54dff1001fefd4cbc505c816fba2d66c96fb85a60bd8fcd5779437ba68dbbed2a31ac90198bc25a78f8c6e0198623a1e68baf4a4b2a1d433590bf4218e7d065c873f8ba5f1526e22b7686f6d324d3096f8c89829151b1f9e7cf9ae377dce8df64f7fb33a53e9a17918560fa42258e3253ac4240260699a8c92682870a524a959164bde4ea8124f4cf78d4954a5b5a7d84c8c02cbbdbedb58e1cdc9455f5b5766e294b83eb42\n\nInput: 51bfabadcce5073b71abb3ab9fced89b7d455ad5edc895291a018ef2a5e18b2d644f92c4b53aef2b35d2861e62ba215096e0e3ac800b9bb749db92015cb1b80877ff69b7927d4327cb3b3540595e34053d588948e362f366aec7923a7b3e8bb6869150f2c2ffb4adf97ffc0ea9f17e1d37ada168c92d1ee82e11af361b4439ff24fa2db7caa2aaac67a5ba27bf0e0677e3d55dcdd6a5bb61e804b69466a04cc335bede90b56c0b7dd4d1b126c3d32e5faf0990df1ba046fa1cdb1082f5041e9e4fc0e7c833f0fdc01322d20a2373a0036cb0b12abde86d0d3d18a1fcbd687ef19ab395eb99f22621842eb0d99a1da6e6d73ac58d128061fc1e870c048b3d94ed0f558b82e709c62a374e98b767f8\nSHA3-256: a6a4f49aa81c7a7b1a24fa2f0610056444def10ba30e015ada592698eedf5438\nSHA3-512: 30cdbacda93a4f02c2be2272fa371148b4294aae6046a11179d9a9712fd8d85c52e57711682155bbdb80f2cb66af0491d351ad7253412a4eb1ee01cfaee21ed2\nSHAKE-128: 8a8da0ee68e4f36c7a54a7512aeeb94559b236138662e987a03ab61d39a80c6d14cb7ea2baefb027ad1d9170dd791b6adc03a84503a0d4abf1f7c42f29d18638e1f41b687a32c38f26fe74f5d55f296fa044fcc6fac5df42c877d53f6600c2f16b59b1f60e532995ebfae4bedcda5e77325ad6a475843c1d6d65a4c237d9ce9891a9b2e23b3819b3d8aa2349fe3a8a05822638d4f7c44a2556c68f185414b8ca03f0a81189e3dcd4c712ab90fcfb5fc2cb40defed7f4cf0f2ddf3168a8de7aeb62b55635596c750a89116f34f911250b0e322dedaf856cbcf5feb14e037b985499bfbe59ee3cee0d2d628700756b2034ab112b61c9c0fbab3a1e112147d3d73ba95973d5af662c35713a04a9061c083fac6e3359ff78f181fbea8bf2faf31c6699547f009f55491725eca85a08290330776bbda3c968f23e234c16b1927d243467ddfddb14844b0dee257c3367411f78a39bada30223779845c5ce048d5ee206d7317325dac57ff3edd77c69add101a6296de4dcde65548925a8c9dde7ce93db6e59651598a0ed8bf58d7c288ff255a29d2964297f67b7f28464b6b25533e44aa1a41c26fb3699f460d034857d778b0c20d0634735307f584e7a1e955731dcd39215862a0cd6502517beccfb6900582c9a1f416536ce311f3455aeffa9b825c03443d9ca1b1340ecf3ce15a0387c92688ea6d2cd34101e5f48ab3d1da18de3b0\nSHAKE-256: 1c78972f04a35672df49244baea1c234c6c080c2cc06b14ff315f9b91d6bf9d836411a5f5f6c67e204b392550ac75fe6dfd60b8d0a99f06a34228d0cad4cadf3a4aa01b86ce2482149794e96dcd7dec875908fafc81636eb5d4319ab8ae36621abed573b8d9dea93b92fb6a8cdf6fcfb6a0dc8a46c43436d03e9a534468e6d5df627c2d617b48d985e93d3ef39c9e5b2dddd2cb81d99054a95fd4e2cfa9d50e8f0b81adffd7c8d7251eedee1256e3c1e94bdee107be9520ab5789dc4afe0e90197a145fb7fc981abe0c5281e7be51b934a467d0f556657e14826bb72886e245d7c0763350a23a86acb7ce46979575895a198c642e89d5c4a4e9acad9cf8b209d5310fd3e8e46a3d3a723c02c95e4e6d5cbaaee1a74a47c37cfd78643d3bfcbbc1901dd37ba79989c2d3b7deb48130ab1b7cd6707304a30da572437f38dc5af762b342baeb93c55c60dc914372a31225863ac63c0c38287e5c41c1a05cd54577d8ada22d16bf17bb60a551ff07851b67ed2ac78b0878826f0b144e46c723d296c5085503be0a5ee8793a17b9a0dfc381e0f9e012ff1ed712e772d78e969068c6308c357e136c9030d1e7dd07d50b343e9c1009d15448fdb85d90f3aa28b752f0fdaf31098a7148270af2c9f27056837dbab666aa91e2a08b9600c2f72cba22025f595d4fea56ec53fc1d85ed71a1404b10d6146440071f55015780ac7859a4a7e\n\nInput: 27e80655514f4d34afa7deaaace16c8f88eb2997e9a9a7872d22f3035c83537f9054e6cd6a1623102001bd8b41328a1209391e590f757b38a8198671b8a5e6bae498b6b4f8c12604a960353d38941c0ccd4448a6e8251cd78f01660da55f655e64764888a2bcd8fe9cb65f14a150d816b3d4ff49c8a23ab00e926fabbae463e035c8308b95b54d88c13b5d8abc357a5cb712dccb7c2604758e52974acf8e17933a186e170ccf803590711d7989b4d28c5d34b3a2097c1263cd30c19a168e804b6d3836f98ce97f2c53534038842f0dc3256c3298b187f43540fc851669d5de77c75f05462cf47255bf42219c05cd5f6bc1f148f8f4750550808d3eb97b148f1f2aab693b5c29b73e641888b856f0b5\nSHA3-256: 1632a3c8bd62e72448d84e6c5b7860769d0284b3ff349cf1c46eba85131df913\nSHA3-512: a4dc46b171853a7e74304e8637e4c12bdbd956d4942a336fe2efd47b96988e194dea70c2f1f49d279bc45f5323ce7e729313956e503cfa9a4929a7d47942c64c\nSHAKE-128: 8ccfc4b2e3e6c0a4843347e3dcfc69195c089a60226f9807390aa0847dd33e1b24c1a6087a47051a37689c1354d8451563fb2ceff75659a9ad1ad4a3b707688672addd53e37011ec2007429a594aa7d19c960700481ac1e75575db628054ddc670ea865b63f9fcf6bddeeeab17c1669b0718042fa5734338fb726b339d213dea2cea9517fe008b36b6cd46042b8682c76e6177e12ae2574bd94d47eb627f12f4aeef6a9e6a3d7338b279c9da51c0a7d0463f313e798509ce743d377a7bc9330bed0bd127cb64aeed7c2e7c03995f8752e68670eba6a4b6f", + "6b18de4d564d87880817fc084ad8ac5745b6423e8ae1886f99110b72580698f4a7c1677e35a5955e7bd3c632a65d502154e538ded346a423e475e83926522a8ee56155fd69ce41944be412deaf6da50d20d683b3e094875e9e0ed901133e48be40881861e3cad178e0c351876592d5384bd5edd64f1663f854ae2a7ff1c52d9f51db6e42b93bd1ff13007b2bdc8ca4fb6196cdf7e06da9ede4242220736b92c45211ce3b896f9d37402393d6ac1b63f299b00d96c96813855991d76dab1d9406cb6065b82fdfe33f1d4a5afc070ef39a267f479016207e722e58c08c5af97a449ebe3079a00643e891243fe9a6a1ab4d53c1c3ebdf5e498a7fee657dc77919dc5751e38915a5230c3fa424ad8029e15ce47e6679e255612e2d5e286129c225e923ba33107971cf4a0\nSHAKE-256: 7f062ac778722f8f390c0dc94976c491952a9fbdd1f6f194eaada7c546d66ebfce9cdfb5b165caa25e50791292a3870014ff66f885a1f5636200006a588e93211ce4530b75434c553d32d685925885827eefa7ebe92000fcc35cf9dd4c8c471bfc0027aff5f2ed6ef539786e832f8806700605cd18baceae1cd244e91d8937a2b265af66ee23ccc5afe28000e4f6e4906aff767b7094e29ddf411f9085dcd25aeb42286cef644b14d0330927afbafa9fa665883bade60e9856fb640621f36cf4e49f981fa4aabe106e7a0d42eaa8791f4202b962ef0031f4b968d56be2f8df32d3865022eccc36c5937117529c7da51ed4a594d9d5ec6ad29cad82a6826e98e3a6558a1ba2561c8706ea045fc109dbb2a72992e26d62ceb4cbcb6a845b17cd2e61b49053baed9a45978da226a2027c8d4fb9a44208a35a6f9d105e5115f0dd8cf9362d199c05c4c33b2b15099772b34cd4da011867409ce0df29c02de7b1af15f63f8144a3f3da53973c98919965e81cfe12d62e111b1f5590c5034cf940497ef337adf658e0b8b58183fbc2e24ee1816c1ef78c23dcd6361f8e7164389e93faa48332e9d2862ca5dd6f53b38498a5e651de3c86cf346a15484cc6dd49afd2d615b4925606d061f8ae72b54a2214d6256cc4d61016b9ad6483edb8c266490b5425aaa5ecec28ed008fbc3d15ff6d3f1802ad7cdddfebfb3a9007a8fba7a2ffb1\n\nInput: 8365730dab7edb5392d48dc72d9f80ae437f98feaeece8c783761bd93ca9da3d2fdda4e0b36b9fda88322dee0c15f9d095d96864b889ad720655a49dca5f90ee9f1c2f726484d6881108aed840ad6aa70571aca09b14b7f86524d008efe5620a5f143cc14422bbcf389aaa802859b2d383ca19dd2f2918f281862107586fcd3c5715b7c150c5977a40f925e0e81ab7ecb82a48c6308ccfc64e4b31958edb46e4dd82b5eb0d57ac965d1c4d565c8c8f8052c27c6aa7a4021a3bf9cd1b5a5d3fdf03038caa922c7ce36ee1b6211517d694fb096a6bb5cb01963da45571f543c5e525f7dca5d7d9bf40ae0155391b9f6cd6c3f13ff767995f9cca17d7e9bc28c139334070382c908f58c7e4490d3f3e68f5\nSHA3-256: d7c468e0f3e3ce5ecb5e385ca0bcd9c3741bcaf28d717ca1a4661fac7f6f902c\nSHA3-512: 5c4429344973338b31dcd6abad2886fe0d3f185171b13d24f6be2fc576bc69ffad69655bfcc666f20975c889f2b9ff64cc574080a9a05dcee2726e1e8a407500\nSHAKE-128: 2036e57ce4f1a440307b35dbd8899db94f21a196e3cb9ffec5abf02ffdef2dbdaa57ea850b2178760b7a966983fbee99c7a411322d8a57ccdfd7628c8d9d6d7449fff9b759618213f6f7ddeef1812329dfd7c95a8f0bd1c3497ca4e91959fabd9b21b723559cb30b931c5d48208bbbe6b9e66c2049d5825df3e04312cf0938ee29af767e9a9d902987c44375cdb682e9a58734f3aebfb429dca31d2380d15614e2f9e7a4527181069fbcf9f4457f3ea1da2acbd5158741acbf9ea784cd1ccb75636c60742eac4e313889a29870da993d9b1fe957821838cfcfa7d3dc4dfcae6b4337fc5d8d20c5873625d18236ffba499285fbc09da88345d22b83b089a9e3bf8a6d12e58d62a4b24d4375d4cb020cf3987c982edf78111f4b23a91ea10e5609667b42e41a22e3750fece2485b284737fbf7f063fd8d9facc2b268a7615a006c0ac316f52689ea36ab922b33709f42476dc96ab9913a92a6aa93822b42ac5a6e5c6b32bd03ad80720d4764f414d19ea2fcb247865d4badad0ad4fe826ee9939f2eab178b214ad3243e862964ae0f5b0c42e288560cd3692a9209024f9a861b3e7ae110bbd103da7cc27c3a6311263b081cfa5082fd6fb07b66ff7c35132e89661079ed2e44524cba97de759fe2c029ef117fd88217e0a10268499ce12b38f67229b5b897213558ccb040d14962bb6a5cd1842d48de9548821c8f6076d77dffbd\nSHAKE-256: 9d8839facf48aff8c787828163f6f4527a6905fc8999285c6747d24423a30aa213d74d71849e74d7f0724aad32df07666846d82dcd2bd1f5724dc13c9cba6bb8cd7e2d39a6e834ebf187e962b40855d3af41adb0dd51433687f4bc7e96f793e0d893596328ff9ddef2882b84ce89ec0c766b5fdc48253df15d3ad0e051698ce23b91e0293d3a3832077c17a0c990f602bb087f3359b5754c9fb11b44546fc0a8a951ac885300dcf7ffe2e1af3ffffc7bcb46c3d9ea7a1777bc4e5cbe241281dbc171be331e260831d6aadafadf40ab077417c3b21937b6fef599086c3a5537b4835de6368d09ac3ba0a3a0e5cd4a22c84ec7328a8fe06fddf6ea9d4dff9eeb70340dd6f24131e07b8ba73d57bd6927fce114f6e245c87f451ed67dd74e4f4cf2bc7638f330606e3b4a1bda722f31e70a0d7469b224cc40877bbdcdb6c51c5b8871c519767df0dfc2be481bb476b86c4895162f2fe6f64e5423e1de59b1e4fdfbe9a9e4e536232a3a359c0090c1149a77114caf52d8fbc80f85c27d917a46e9ba14b49ff5628cb003e13ede80e782f56009bc794de06ec4ef007f9fe5dace44e5294ab2f14ee9c763e2422137ed574a116e08417fb90d1490d38e7595abbd7e98d00397838836993b324216ab4e53b49a5090e5a62c3ff38f74c68221df05b59d295394a3ca45ca75abf45ca953aa8ac2ffde1e7ebcdbd5120213fc6a1ccbad24\n\nInput: efdf3904ed2d8e8ed5383a45fad8cf8d6276457a3ba36e4ea8cd925dbdb0f4d346b24ff2ca50402b250dc0814d07a9e604f58298b650ca31e3a5ffa050438a5c28dc35f3dc7478760a3000c1f2b6676b77a46f3fe67453a938bf05396f227aac55527f5d41acd14bbaeb7980389a779ca14d37ddbbba43cf9d0750ae5e9a2cdea286a20cb4777c7d15a8cc407da234be4a010875a5db3eace974e8d9fb44e3a6ee771f2b2592b490f5447fda431a807853dff8fef5cdcc01c43775ea387a3cfb6952e58350a21db037734121395b637f00b31e001bd1e8bfabfcdaff243556a076942b056317f9057b58b0b2089bed9018706c379acda9b5f30e359e6e7af427f33d9af59435bf9d76d135a1f4e5cdd091\nSHA3-256: c505f38539d0a6dbbc2c755ab14f9c3d609abe5343dd0e692698e6c37b155fad\nSHA3-512: b00f201360dd2933c4b4644b65d46a895ece6d84cdc6224efb323d930372b42454d5b614bcaba111d14bde4ee2cc8f2ad6bbf5c170977468333943635636bb8c\nSHAKE-128: 28af2cc9df157765e199f6380119d577ee962fe88530c06a8c58f63e3d0e6282eb9be1ef4b89ab2a087c988fed833be0a689ab4e58fc8693405949c5ff3811ed4c1fdf7ef698fdc5aff0ec7148d4c71ce5622b760956522242847b4e4a71f414309b36b78dfdf8493b758612263d31346db5ad29f47d56dbd3795faf8426c781a8836d578245f4692d464540aeeec1f3cd1c5e1809f06612e3c8ae0a01264378f05afb825a5490d1390c07f0fb07e61b02075a20b387e948b9892d4f848de289dba430affc2871b3e6e2f7a324ce23408012a7efedc320dbb3a9d567c65033a8fe04d308f150c57910ab36c3dc09efd8e190738369540ddbe8478f6dd64d7ae9d502901595bbf392af40c9dc1f0002f3981c86e0699d06fc99f045ebe6621cd47b6664ed1f8d2cd8be89310b01541ed236a7caa06c966c9873b44103773e5136206da8ec97a1b093d6b6297e6c1e3f546990adebec1131c1c848f3c381c9d6505dca07fc58e8c9cd141e65f18879107461e5238e2669fbe182f5b33720c0513cdc731062d36566ed3727269a83991f45d616e9e74603ce9bb6f4fe52f7011348ee9883bf3162e6be76ab5020dca295da20ebdd89b34aaa6ca986860dabd7130895a5780c3545202aeec547ac9866bc8f950ad48f70836943faa59c34fc256a131b6dadf8497c847b6561236ad5af44991ef8d2b260dd6f425d28908ea3422fb9\nSHAKE-256: 20100a3a892cf2c23c400516918d548b7b879aa379471020cce08cc008163dc9f7cbf888193ce0e41aa49753169caa07dc56fb2c7dc1eede64b05df544ea0672dfb54ad604aecabd57deefea29794f439090ca37856575eb66f7afaad66be78d4fa5966c0ba9899820954bb59e3645c3fb8475c7e4e11a06b6902abcd262e463c3c216568787d86fa99503aa2bcd3af2c689c1d46ef15756fa41539479faab2e46a3ef7f61fadda259201bdc00657c406b086822997dfa546b64b9ab2d6a28c7735e67076b455a2cbbe3b7f5ed903dd77a7609f182cc5998c301d3b14d704d858e3baaa146cf6a490d1c7e5fbc718237ea57944096c24103e383cd2c8ddb6fc6a23cb5431050df778c54e3af004b9386d4df09a491ac9fdb65dd74005d4d32a38c42f0af8132d1b84468663d1c2c44604179d4675620eff93619467f29f5a1e0dbb8c53c8ebde6a647da5c75fb851aaf953b94788aa688bc17fa02627bbec1c2f68fcd412846034089a1edc87613f12b48ac0e9d33d105ebd36bf950d6dc89b99e33cd9d06c3c56bb4d09c8853690796bafae2b92936ff469ccf0e056ed3391c51be2946fe390309eaa0a82192fb6a53245f52eae636b86fd4d22a4654be808024b86a8621564d1765aacee342cc444a830e17f87a821a20f5f722c6506d9e2af06588deb873c8567768e3b3a2b672016f5a4e84d94b2b7e1fe174be1d49cce6\n\nInput: e002c0e6546046f772574f11e60d385bd7a0090a65b5bd526ef68cb5e2a8b853c6e58bf9532fb86c6fdc719033b8b954fce7504997d53e213dccc208b2198f69843c30b33c7250867e6485c6a13df1553b50482012d637727bf1d351a22e385bd7d2baff5cdfca6d42ed798b9179c96ab90a8a2362ebc30e45b5c986a9443594732804924e387f04a813fc9d4537e4fd372eb64fefdc5ed2b141b1c179acf39188307817652f1b5144c93e551b7f7bf2819c67b770b70da64f0191e4908bae62bf909727c87e8ba41d16e517f5a1f5134018fa8d816e643ec141b436e7b8dd0a682141eaa4730ea30c8f1b8877de923354cfb8578872732bca19e7d215fad4bb7fec9af756b75b85b79e4ba6d142becf9e83\nSHA3-256: f046ae10437a8a95473a42fe343ef4524ac43eba64a0929c03e5837da9423b44\nSHA3-512: d6da2264164eb59f4a509eef9339f59615239c66337c86b5ee9694f335ca719d35fce4a810a452e96fb3be179991cb0d566a425d813f3bfbe14f4e2025d5edeb\nSHAKE-128: e46c31d487e6159638e6fd8431dc1c9fcb7dc9f03fb8816088e2a931eb1c366a0537836931a1760a83aa2db59bc0d885f354", + "cef0bc1eab7ba13bbf5321fc939af996ffe6a17a8ce2653d835f4ae4282292a463816cfaa38fbb8e6c02e3ae7b912d942300b5393448b1a8a5b25dce9f6f4e0ce003851db73d4c731f6ec4f327e2dedc12992ba0443c0dbfb4a6ed4de162b527175348f0c197760870f4bffb8d23eb0dfad744c4b298462f5518d396cec44d99ec161e1a9828be84cb140b4350ee3a59463b597eb529efa078ab54501ebff4ae8a8f7e9049d808624aa932015a9bcd6b79766ea3ef9327a72581d4e73282d822c7b6e77be3641f468c0107af5a3b47095cf2c51908b5dc72e1ed6b53f960c3042d70707f427b961b722ceb6f6f57ba45b66e178e2fe83924a40ca42cee25eb37a48ee4cab26958fe6812ac1b9ce257d69a9f9cb4d6af615a607e15c079d301709edf097192dae3ef6db996f14af57a5316d00578790e41064fd87e522ee9af0cbbd10765cdf9dfaee3373f747bb83ad77c416e4df81463b1fcb3a3fa8ad087b721cdb7bd86851a458ac08df9ec2b42133d0bcc316987413f6107ea48af2492e60f8c3b6c0386ea0e92fec3c5945055795d8fb2e1ade1348a7a2b62cb46ea2c453707687b43c1ec4c4e5b00dea642c604b48995adbe31888cbf6b0fc86d188712d45947001c707392356627b1c5f4\nSHAKE-256: 21a88906d79bd3154ab5f420587074ccbf18a0ec54aa7a6341cf30d1caea5fa342359d1eebbbc6e343d2c799f5fba27fbc2db4f2df13d73a6ae75fe6f9f04b6571c3c08aa5afb4d1b586abb02018d9049285a6fad0a35dda2004a3e8c34d66e6093841dbb1c71770b637cb0c51d501e7a64edc6ea20db914429ffc1ebdedafcae2aa164aeef6cc41ab2a2119c8deb790d686df2f6bf9ad4dd32a22fa753fd6d278b3844e5ea670c2444aa877cfa08fdeab1adc90991c74292735e66a138a559199b49fc5f1889605b21f89e180a9e932919755efd9397106caff728b6ebecd979fa490a552b419c2ac6b64e476e2a81016e4e1bc650a75e42714b391b3793fb57cc2ed005b239eac5f8506e2b96c22583c8760dceea6128440736af864c1fb7f5930368b7ed82b5dd5ad383e724e90e61e9fcc90cacde0093c0fdbff30006ca57c2fff6025ed537e9c1d1e7d4dfd1e36025002770420ff10ed2c6d35ca36f2ea876ac71c1f973bc296369800babf8c1b1bd76f08b0e850259711d4ea0945ca86630afced62093c686c4f7f9b8c55c9f94c7d348691ebf03d2b46677330e8adaeebdb11490cc0845ce731bdda1d815fecb7314251ccc6ce27ca9c919bc685014d8488d8db061741ba31e95f76e1551b6a1a9dcfe51bdf3ee7d2390f45eeacc0b5f212d1df81c5475c4be2efa6d531a1bc3a6c5a9d5f608520cdcdaa3bf7bb5c2b\n\nInput: 54692a55b780a31f2bcd6c2032f6c4464caede26d332e1f2d000abc15f03042bc70f391d26c762dc0a8f688096bc156718069c826b20f1f737b81378794bbaa290a8ee99d7c533ca34cad2257047f14b471a95ec00d1a8235547db2d384c49bf7b0ac5a85bd7bf56d02e6ac8ba2d79bcb9911ceef7d9feae1a8a0f5a09740d8a4fddc789d70c0c7cb42d33d301319705c8b00f9136776366ae8f101d6359a6d4e7eb09049365b982db0e166f5509bb88dfb21c11de3396e8a445429d809e654d8d655f9e80b5baa17285c4e6ccc7e89972b939e185a4fcda700005fc1bcc975da39dbabadb3373f4c58416f9909cfb77bc683ca38f29cd93a906a93a395d5ba7911ecf3bd1fa0d954998ec7de43f506594a6c0\nSHA3-256: 7d4025081a99f0ae878d4fb71e9e1407bce9b75e8febcfc361308c71e939f2f4\nSHA3-512: bb51b8311d20f2f3ea60445f7dcbb1b76363ddede4804195e8c614c72dbed42daa2e9330b04f9957e26303d5f756c0115efd63a3ddc241e564cd841df6201892\nSHAKE-128: 3807ea489c34221e708ee43219b1307f4e618021f23b75db41ea11739c9302d455e01335ae2edf4292a8c411c2973c8357409ca19c5d8dc6297039baa0ad50b034ada0f7a041c9310f350befbb286f46b93a1f1e9df5da4db23f6898871b1536965b25a934c309857dda1a40acb9af60ca233b577be6347ce999158bd91a4d151c39fa13fcf074b3f499e2f61f73463eac049b908e9c457c3107808d9beb4bb8f0a9f76f6748f17650b11b51fdd02e1ced83627a9d39344dca8191541391d81a08e99b3681094f480e482fc6af12a506bc9d5c0f9aa3954d0252ff8d7188dfda785dc39992b2bcb9dee5574028fb940ad7b44be65ff981254e4ee941fa820a02fe85121f855644fefc1ada6fe1052c3eb41d607ad7620b64f715dcb2fba8f7a40b04cea7e0aa847b0e21ae14dbfee7d77faca84a5bb9339847c8d7500877e4eab8f333da4a59c99d0d77e5b73aa6bbe3deb3e1de3e11a88839e4ef5f67dd5c183d2c7fb80a72f7c13ca4a1560cbf89b8b27c1130f10f1c224a1ac82c8691ec5451d13d859cd9850ae17231956f061ee9fc383722eea5e49c7f6e792500de8477763a8a96aad37f0b08ae74dd31837184f5636f3a35c302c33ca980ba11fabb6c85c322b47fabb348faa083aee27e8b2ed171f374f89f86c398cc71b1df60cb1219f1acdf4c6c7cf55a14f6acbf8c7eef845f7010b121ee895b0c0acc3320e699\nSHAKE-256: 8ab322740e5b1a6958a66b33194596ebd1971150a8a2db6e33325c80c82741ab5e9e63723135d433364fee464a13386349031e30dc993551afda1fff6c95451ac8ba3e172698f73194b6a88f2f8d7b449654431ebea20caf531be620a791179568265870a63063b0506bdd836e0bb1b0ea18c8d6496e5c603c0969c2c3c52811f5e27148b830f4199601e8a741aba23cc3760e13152f7939b2b2246d3fd4299a314f3796448d4caf1beb721d044e9d5b1d5e4bfe610b085503fe80750a94eca1fd83a8ba2bc3170e42e074bae8917558500976b5d92adf3437ba63260fe688f8feea501d4ed3960dafc359b21341be3ae01173c9547b7d8439b0a498118f6772bf1903ec50a4cae2a7242c7b4f58f0f494da97c18fc0dc198f28c6740f8a06f7239e9bd2ebf48c07e29cc6d4a28f53a33947f2549e4c7e49094b993c4e508b29dda9c9b41a4d4d2a3a48869f53e2aa3e5a47a7aea543a129caf341810b30650ea57328676331c24a434c2696ea9338202780a21192b261c5a8561740023f217f88cd4adbf15cab4f488f8c76bb8b395f07423f2e57e26bc3d1c1df1de72d0be66ec8a25ba6dcd8a418aac224674dc395cd44f249d72219f6aba16e5d881f5f1fca2c20bb1b3ac33f5c4d69a370547ddabdf64f12b94f71a71e93153afbe3ae71529df3f42665444720bb147c8aece34eb7e286f002d09fdefdacc05ba8829a5a\n\nInput: 1535ef658c408bc2fe4a0655f00e966902066a2f2bb303cc589edc73f61d30023ae50e9f510cb6fe4ea7ded57049831cb9b02a5c6c647d7bcfeab0dfe18b65d80f9dd1c835c3abc478aa0a89b4bb39bcd97a2caa6d0181b27799a9e3254fd81e9b12b1e498b60027cddd292f852af47926e57835f771f1c2c0cfefb22dfce57a1352aead03270c6d778fe33454f2e4f9af5b40ad0f1d12d2a4fb822b082b115cd8c11b0974c1fa8f01c7788766e8e2ce63f60b6d79474d0fccfc5fa80aa613c85b6649acc3a80896a0733f0f6ef8d32b4bc5ea186ce5f004450880b1c1d127a364df1939c185dc063c1d7c65198abbd6d59bc5395059ae517e30dd7dc2a20f77baebd0d84c47e0ea8a44d9ddc22efd4d4c4f9f35\nSHA3-256: d2caffa0459f318d664c5da6ef39bc475a0bd3cc8375e9249301f4577a898087\nSHA3-512: 13cf6cb40e4bed9b0ff94ef19683608c106975f0d84e1e107280c2661d6b74bad24d70fbf844e01488bcd272ffefbdd36c7edc367895a3a51975a38ff868b59f\nSHAKE-128: a5552994843726e3bb834938a7e7884d6e07f2358158aa52f98491c1e408f6f1a8f8d227b2bf8cf857f540fcbe3425110476faf6985238803baa272f34d181324961e52d987e9858a8422e73581d83ee58963dab02c3b614877cab4b6e7e98a623f82ac5fb688584e1199e1521921ba67e6ad5835d0e7b5846be96e1383f802ff2fdcb473e1e0394574aaafbeb8c256decff577770c83e7a9a0fbb6a9cfbfb777ae4edbbd0e7f1feef0f6301eb36adc3d6139d412ad221b3cf5242bbf45fcc61f7de7f791464aec259b911aefcc1f0a6ce1cc6e706c5f8066ce2db240c7337db1156be3ed55bac93cda4ac28ed34d7956f619dcadd030243d1f1bbf2471c1f362098560326f26ca56b0933c2dfc812167cc6aad5ba68a407770c84fab02dd5ae37ac47ec86d03f22318563926f036baf7bcfb7f6f786b1d8e7cf5dfeaa4d4b81307f81aee797d2b107081703fc19fa82d0db7403cfb62829bd8d57bd0de9523551ebe1a2dc4f7562c1fe95e2e00dece3f2aeca58063a72b2a3db4640de783a404e8ecd187681e0f8b6d8db04dd5b7d438d61b323a836663eb511cb8e2264166c272dafc69e0c12172aa3d3b25e08142d7c888f4d24dc64f305843ad90d5ad6524196cb6f805104e6b813d2353cd94f95b6c5f81685dbee579a6545efb088ed28cc52d8deddc6a82a8b087440f23f5256faf54bd17665d2d7553e7feebd63bae4\nSHAKE-256: 681426d30e8d72a1a53471d0c05ed752dd27a098b5cba22757eb99b8af2005770b010c3e8a04aecffe2899804214873bae21904c04926d727721a3b3c3596a995044be04f73e77c24d357453865bedcbec30697dcc3d9a7c1596c0f5c98f4abebd6ba27437d6d82283d03ac92ee7d3dc05564c15c201cf88b4b21468349e1c8f33e3895ea01d443617639664e9f021d55ca018617e12089ffe7bdfe208169c2b79b9fb35f4b269ba8969c134f81dfd90d5769a5cfd8ec1af4c48855e8e483405b55f0d3e811a7b902efdd0b706301ff2286c23a769d65555bfcac138aa6e3e175d27a8d4b21f01b6b760998b80c2190f1d21130f23568928ca7b10614091dae4742256bed806433815cd1893a9b1ada7bbd953b87f7bcacdb24392f83db348ced8850b321ec6bbb9b0605c26d36cf968d69834032ff83bd4f1e21f9261a770d950f4d1c1cc26f8fc231d93e984cb2ec181c6e3f517071663dee12cc0a8b7dc4053dc4465a86b12bf851067121185a5a62fe22ef9d9f8e7aaa1cbc538fac04bddb5bb601d428e30b043661b7edfc96b44d75b57349ab4ca22bef60ce90bfc34fa7baeb3355d09029889a62e8fbb2c416adc3e4a1a9afe2b44f3e872543b840d0a9d512e5580659b2d6e6738860720e2be7f7358c4853cf5528fc4623cabb04dc28c00feee35697a4f9373b454b87f59992d74a519582aa49b528c4d3686c06884\n\nInput: 90b9879dbc421177d7be19cdee515dd09f62f6d712b5211e48d3e56a51c9230513d59032ebfdf060b53b8fac74c8a297a950afbd7f51beed8c072cf6f3ddfece1f8e8e8175a158ae6f3a9d275179a3f8194d5fa47ab977d244f1e51ed01b497196d66cb2efe5b47998a824906d5bbdb8ddcf6ae175b116ece27cca213ba32e89a272b9e724362cdac508b1540f46c1d593b25d69f387949ab208b7dc1836aec2e3a86af4f5ca5b1ef751693e70d23caea348d025d9c86f456f1c353b5fc67878901db08732ba5fd3352b648533dd13c67f30cb7b90969e05c78fff80103227fb56fc30a8e41589427fc66c475e3a5ac3e2468dac136ce46adfc5c85a96127e32dc7734c5c2a0a6e6629", + "453f2531ac48342aede8f95\nSHA3-256: cdc39b97a1f24eb7ad02cd34a7ae02ab6ba2caa174b85cfcedf4002857c467f8\nSHA3-512: c08684aa7c3b43707e688ab7a7e88a607baba3f2ef6f27700d9d6bbec028cb35b651ff4ecc873af264b1ad445c4382f003645aebcdce0e9acaa38ebe5b6e3d8a\nSHAKE-128: 464545e0eee1b6a5441917053e967bc7c11025b1d36ebf3ff37031be6554c5dcf743d8bf66be6923f0e4c92f728facf74bba01dc8fa70cf36f33eab6d7334b2e4699569f2b3ca5ea129b0517f2db562fb090e6c4c3fe6e06c9ad1922f0808412f49d4d7e292cf591f3bf5f6694fd8f770c456b0fc5a5cd14869f73aac278c447d3793b5e92355b886a2b0e41e9d4e7ac4007207c5c15deeab218e4e4200445068ca6e981702261e7a318f39040a75227be8a4f760a91b85e379df3c4ece2cf21c2813cbceda206d246f4355f038fd631b66758f23a56afe01a52e9e5830aca65200400e59ea501807d0b3f0302a2816cebdc9dcefeaf5fe07e0c0b6d969f25a7e8974acf6771829cd2e3ecfe158eea2268d731922677bf2ecd74d46c66ba159603ea93c1b1a7acf468a8bd5c126375cca2394698edfe5d797e86923b67fda053f40b76f56ca45c516ed62516ea3a379930db7cccc60f60a7718fda472a299b5fd7a844332af0781825ec424a246034827445dd9e0b83306e9fdc1ede7b31bad5e3c3b3e4cce93810506767b526659473b97c4b7cfcf42b31d90a0c40a9c374ba02f191f58c5754aa2ebbc80a77b76622275c3b12d04fe729a2bdafe4d7c696e642cbf1434b81ac7babfb7efc18728c62d4d9f625d5d62cf5422f6a7a3880e8111ef6ebd9c5b798149930f93b765a7f95569340fddcc1974644c733b88789cb25\nSHAKE-256: 7073c700ea2653cbb3b30a49e0c862420e2b8653d0bafbb8afd537b06e044eaa241668753fb87573321205fc0553c85eea20e17c53338186d707edac2131e81517cfcf5c9f6b7f86a7e49e131b78b479192f16945655bbf8afc2ab126436169c699701badcb1c6d744095b20894789b13743e5cf4b7dd221e0929332ef4b583cb1c4d825a2036189670c9564f90eb2dd5cec9abf425868bf0ef5fa0e1b2bd7b4cf0df3b07df0b0f011e85d3c9605fbd78feb0869147fc825b443145a0cc1045eaf1d7ab3398fdd3e4ef2a95edd659d434757f68932f8acdff7eb0fdb20f91a13d3834ee696d418182fc93414bf4f04f4949bc4457010246332a157bf10a53a7c8a244d973b04e9bda80f28ffc88a6631000921533f7bc1e34e5710554e294adbbe09803a073a639d30b974c91b56771f128c8d1ff11028b469b9847e729c4186401a85c63d7ec12ffecf1af1a7f496cc058072490556731f62cadae959a024a49314260dcc78f13ce030bfb9e3b04d5d2069e95b4cafca7e2b6d4defee75e086824971ac8774c569cd6163cc0bfd83b6df0eeac1bdb139c1e205e91cf8859b21db639af4cae76f1c265449f8ec556e62d2fc7b6f9b4abc3f109bc9f2f96e51e2058e5f7808f3b00aea72813a789f8b38f79313cf5e594556422c62ce54e410ce136120eb05d3536a710b3e995270b20c496048b6ce7987ced61f8d56112d8f5d\n\nInput: 81d5e31ef3c329fb6b03231af5a2bcc4d22a551d23defe54db9dd7b2c2c6d47cbfbdae2f766201694b7723ebc6b0ac18e595be42f74dbe65460e8ecb3abedb904ede81a0d847c09910314344d9e368ad9da3cb5e62c3e606c55139ce65281d0b822fc6b23335da2eba23392a43b2eb4145d48b34128b5ee1a3158ea78c39c38d04f2383bdb41a1f1005f5b7d5b86bda127b964eef40160c669aba8bbcad2ffaa2c3c0288003b82051df80fd86fbec2d4b6adadb19329fe968ed1d40af932fc9c8c90b6b7558f5370f6e69c44b898d9a7c189804a330b2ced2ee313a0b2f44d9851e38d43efdc98e0ab307eb176be17c70262f780d2bd994e5373acab89ee9e101539e038c717eb9d7a6215207bab2a1bca0fefe23cc6\nSHA3-256: 8b609669303e3c4c23139fd4e4c706516cf38d890961e1bf706a60d63c384d01\nSHA3-512: 91ad72d6100448d8ea2549765b6efed6fa73e063046ea586830f58cf2c2474f1b8edf6233d135ba1dab9462aefbcf5c5fc64062939b00fbf5306905ab9953a67\nSHAKE-128: 193ac16aecf1a57f263ce027a583e23724ec095f7690b9b475898e78e0558bd7e7982381298c02d7800205039d1b18751ff7e17dc3e3c170b884ac2a4f552a9ae77c5e6d60ec048eb445ebf8726d55f17ce0c18ce9b79c8c426ccb0c37c3edce5bb6884335a191b9bae0ef9be7ad130db8bdf66bec1cf15c76817d7409c56fa54c806cbc97b5cba71ab178e7742b4bcd659a829005775b4aa454d8c84ebec84f407713f0028501e10842d1a8809ad510adb4e6d0c4fb02f9fbe59481e8e1527028432766602c4263b57cfa552225c99615a9a50c90fae91dc30d22529614a43b72ad57e735b4b329cd9066873712466aafba1af439bfbbfe794f15aa4233705216b6c0575bd08c98e14d0d36246196a990926bc328504b0938bb27c0a307b739e09261f78678c8d070babc32c9d44a0f765c03ab1647b39260ac9196cd8b31e30dfdf9ca36d6d9b4807e89c2ba0001461eb35d7afff07dfc97675e068da86b5bd92198a99e18b0feb672f88f663762f65e0ffc5fd6f9b97ffad3dfd12c5f6ca0c5062a14a3473a178e9647772600f8b51aab8da43453a7c1ebc03563ca4982202c35467a0612c823b8a3882ac79dfdaa0d8ff8e6e4b462847d7f4ff989b7a5aac03cb76452f26fba02493bf57d5822d4ce43d41afecf1755406dd053113dd77e3109f1ed2c12bb9335ea5280485fac2935fa130ccc2407df565a7d7d142174bd\nSHAKE-256: 2966fda3b1471db641149a3be0e0771454acd15a5da691ab3ee3315a0ee8b763b036210789dfa0db39b79efad9185b4e2b62f16efeed96ee40bf27bd0877ebb4edc9924f9313694d9f86353c819f88f0edc50853db5d1c9d4de91b7dcbc9d647d5897918c5ebcf9849348c7f850e5c64af64cb326d4aec23554660417b85066c7bfe2a9bbb9cb0c2ae731d7767a6b701344e7470e181202dff18a5b61e1ae069610fc24a7b04ff4fe1cc78f8bac1ef4703ea2c968aacbb696fa29e778ebfc2127ea27a201623ea38804e9b66ac9434b162335d806d48eff66772f901470f99843b50ada91ee3fe8a881a5217b4c177ba7683ddeec1344e8059c91d649cba678815d6eb78f7c70c843ed6149400a0e78b249da170dad15782600d7968c35bc45193f37d56d260ede5cc073a0c650b9dd65f28e55bd16fa4d6bc6055d4eac00ca57a4b1f9755bec079be39b2af5296bc42b961853a38d2c9de452f0d87ecfef48708f3c554bf3ddcc731c6880087da91af067eaac7662db150cde24f5ca23d708298a6f54c23a8bbf2760ae9e83a5fcccaf6f43c9263a81d9aa3493c1e40dd2809a1ddd8c60f1ef2180db89bcb5fb47e8f97ca1ad5695d6dd80c923a4224b22893064ab93b3d7e75af646cfd47ba181343ecbdefa13a8c4d7c42daa7e6477828d2d75b47c7f6fbf6b40a58cb5998e355a709f9ba20ac10e6461bb9162828ee60d1\n\nInput: dc4a9ee194de6c75bbdd2666ff40460c797ef348c9e1ab50dc458876e489ac1818da76c06e67e47ef6b338d3c23afca82a6807857a05177f0ed02b87fb342668324eaddde742772274e3b138f11bbc7bba97faf60c35f6b46ed3ece039503fb758b117b54ae6d143643198cdedbbd3756654ae444084518c82382e9be84bab8f9b3bceb0734186f29774e590942b48669e366330d84a1d9b7cd2f50479f4db632d5e76a2dd24d84a44f935c6dca0741c7ef29934aa6c1ec27352203d8dd6a49f3f7695bd2ce2ff85a4ac29520fb0ee8dc4f58c5b266409e7378a6424bfa72937dc5c71d6acfba507ee962dd98c3fd905e20ae503ac83b7b0e23592136046afe32905a657253e5b9368c3a484953daf3c1c3e2d79930e80\nSHA3-256: f569ad0fb31ea98fd72c24f17d0ad66cd1dff65342e2a6fad2260af5816170cc\nSHA3-512: 0576a47027d545b43cb7dc6e7dea9027a3645beb00c161c9967fb01dd374290cb822c2f78f6f2deb16af9eef18f1f98dde644d71b73bfe02759f46b4d6b9c215\nSHAKE-128: e2a1e76e3b3c11c5734d94a968625ec28a413cd4fa98e5a86f2db3e1f8cd45b943a399129fb65c0706f0b059ab874449785fac5fc5a548c04bb1d493dbd7c12a964e2603bbcb6d08b0b9378b3ca85c6627893edd55f8ac33d40fc5d521446626c46c53db8e78ec67b1b5c2452bb7d2ec303516a7fc1baad537b46aa8e347d449f99fb125ec0856bf4b71df8489847b0dc389ae995d78f4a2b94b8ecbb68b190de0d697915d2aaa44405a4b3c70561cc62569b6c731bac93dce35759cb23a62e8c82a7ea1d50622cba0e14ca43974b0e3cae09bfc9ed5f689ed1d1c57046ec84f4685612909315f97784394a44bc177a47263be69fe1eb5f6bd8fba5522dfc946fc382793a4bf83505d648aa0afa19a393d8470c87b22faac8f86653ed46846b7531257c354fa996a3ca3d945f82b807056cd09554aafb10309bb124b00e04db325603fe9cc58a2d23ea7feb764b10b7f5fab4f4f212ed90201ba9868598e27a2ffd39e3c089afc74461816b8ecabc535277b3845a7937fc5f356fa573d8ec600f46b108b035432bd582d838dcd2163b37b5224c6d93b77f3ce12a196c773d2d28807b4f4eee5f993ace341a3128dc37d49b99256834c5d23b56b8fd2d0e6c08b9cd728949fc8be6b697016b5eb95fcf7a492325788059fd2e3040a03912885bcb2f3c5eb8a13cb615c2478f7c75404c32c9263ca814421212e2a66e4e1ccb19c\nSHAKE-256: 485165582c06bbd80607e83f429c3fcb145dc350c37833a52b455e2e7b6731834e422cc98c9885ff2029b3470d23bb670b543179e8af239c5856661f63ab7b4cac6e8f961702323d8e485e934a26e44ba336e27a0efdb48831db9780f69470594bb9a9c79f2b2a7e16d8fbdce3fd6b0eaa08ead854dbdfff13e4bae5403a91065242be572f0f6e771ab4ef2dbc7301dcbd506c79c48b1be983b3e8fa4c963b31f22d7059bf556dea05332feef6823b8b70bcb2c65e42bcb3a05e80c01646efe6e9f79a362bde977438c7d94cbb468874cd885bf14fa2987388acdbbd1d79dcd7e5ee9e356d8373b42878bde9e39b3fc273781e02e0ea8674e4ff3e734429df701cea95dbcd266c33aaf01382ce370e77ade2508bd157006de1ff6b0a412c79d43fec2a01fd578931c38149aea3bba5da580f61b146ba887ec2e8204204bcf9cc60cc33f524c79969d4875cc91c0b9593929066210e54b3d1f2b79ea612b9d64ef16c69a30a018fb9efaa940f804f7b4b4590f92624282c1b21618d16bfc6a8b77371f5967dd0bd117fc420455a672df7ac482d0119c196b44801612a5121b7ad7329d8d1e6a853017d57fb826eee6ee3b97ec47a485b85f725274606d1003ab6ca411fb1a5f77bf2cff86cfa2157b0d1f791f874e7de92ea62a1d32288f2f92cfb309759c011de3a70ccb9671c683dbb060bb47d0919ee12e012d7ef8f785f2b\n\nInput: efc3af5126fac87f8b4245b2ba4638761f115e969d32f3599151356ea2de3fde638d36ec4e869d4cf6ed5dd3dca76ec37fad19c19e26517aad60e0085c1c30b8732ec150247494ebae5663bee8c63e987d2d7b123a", + "75e95c4eac8b37f77596a22ba86a9b90ee00fc96c09c9257c2daf7f504ea7dec6ecb6aa369801de3763d29c1521b04cf12cf5dbe5e2c8f5215081186f2a7b8076070b21b9d2083f2c89f66851ffa9470aef3b400d3172d3d7404bed12400ba80da86b07475b6ceda17d48a402a679476a74ca3575fbbeb0ca5f2e81e2b5b75c780a75ff972802a9c655e9898586edff5bd2ab61abd795882abd91a0ea3d47733074cc762ecdbeb139e9e5d8af39ecd38027fa9585143684989677b192565bb02d9d398\nSHA3-256: 4624d4a1f65a104d93279ce2659363f63101171e0161bb0fa3f1f70e33b430bc\nSHA3-512: 667193d3ddb9b25ef76f269ffdb2f3c7c4eb0445f7d07c6343d65a91c4941b1d6e656e41441c93c8cc1fd12870c1ce4aa9b5eac80347cb09aa16cb5c1e33a1c9\nSHAKE-128: fd661201b20a53745d320c2384d4b9084051bb602522788126e39ea94b3f9abc2987805eb45d34fc7c9de1205701e812edd0eeca111c26bfaeaf0572bd9d7090ceca8ccb7b719af1ae84366ab68a34fc36bb1d1df90e6887c66a8d31fc03c5e07cfa5f6a77dd4b1a7080663b018cfaf4b0adadfc9e60366dbdbfa38ebb529492ee472eb2797b79e3784c2d55a9e9ee72a87ce97e5f779211804112c81a24b9ff157186f91ab057eb49d1e788908b40c7a77e6edb1d36667987f322ab32ea27a4363224eb361d06e4f927fd5ee820572fad366574298c1a8c116a25a051a8834bd243bb7a4752d625dacf3eb6ff5f287d36a2f0323246e7a7e07fa9fa84d16c5de8667c3e9b032ec2fa1adc9ce327d981ea5bab8ba6d3dcb2767d8f2c00f14ec24f7352b1d5f8fdf7682554dc15ae9a99990b837f692f159526aaee63d089b7f51b1c0518634413998f3950ee44252cd7484d61442aa1b74efc040a9c4c011da6bbf4d4b59ff4f798118c95905e10af4719db31c22e051ad491795e168f967fe3a817ec0e43180e318bd9a65394632ff9745f812237f2db623a6b97a4c66242c6d395da1637c89dc242ff6cc9f575cb98962469a5a2bfded2f09f910cfc7538aed13ee3ef1424d69b1d4444253e9b8e9d5710320265a901258beb66a434f7ae013ca8996c83f84690aa7bacf5610879cb00a187c0dd9427dd1b04de958c09da8d\nSHAKE-256: 33d8950a0fc29cf0d7a4bd55b1d6c1fe240beafbed647d2fe50b4d6b90066ecc0a9b87de9461d65e4e749f7f1adc11b99dc573846c2d3d6a69cebd479b83b2706081a7cc90befd49a0f0ada6bd527dd0ca7d3fb6a3dcb0a57cad89025f1b26b75661a6740a20364c22236a327f050203360632f0a7046b618892d9f2cd9f98078e652a19e766fb764c1623e2b207da66eb618560c90320b2668d5033a5cae5cc3a84c62d1dbc84b1e27ae2a69b4cbb0cdf3a2058845014749d1fda1f7f617c05bfbd66d8d458a9aba85a9bdf664b39623beafdf5e13f4126915251f1b70b05e30020c1ca240b1db33b78febbffd7ff1eb53ea04edc666b56a717b972171bd23f42ad78a9545cb2b48bd072988477cc09bf72a351e6e443f042f63bb249a27cd2e0099055de4fb3f2a7b6205410f4ced3bde016b58e43946b4bc35d16b8efcc6abb422ede02a15e3bae41b0f0711bd0ee684ac3b04c76580e87350a8676f060dcbf3d24b7e41c9bd1ee27c5302b21ea8ee678e939e3fe806e8457829902330f9728cdc857a7a6433ced084621d5f1686a8b1bd9834e62e505b77f59f6ec4e41bb0d8596f5667b0f38e858bd28d326d3e6044ee60aeac5f1e5d449202c05180cf5768066e057ceeeb9d00d730ad31a4b3e642c19507bbb55db0198f6d58edbb8c30c6d24ef25a4ea8e8d3d66d9c1ad3a231707a734cf5313dedb3117fac53dd1ad\n\nInput: 982d52f8db5b4508e8189d045b135ce76e82265ac654c124126b97385eecf167170a8e2af284747b8353933b00ad8822dd5ba238d4b7cd11ae11078b575a2159ceee555d65462d57c86506da009ed5f28616d6c079856f5715619bc750692a26c3640756180a497b19ba43922b2910ba8c2fef0c3d8580442539d7a410b4a653121845d90efd990c348d40ba2254f9ebabe44908ce316f5eff8433fa63e28007cad4fd404a7f2252be45906a62e8962e7eaad9bb0344940096eb1bbd13bfe22d45599d7d1b4687bc30786c0cc3cb179d59359983f2734a36bbcca50034a44946ccaa2e978d35e42679bead2711db6e2cc1f1f792fc1fc57323405fa2454c55a51af38a51b9c296619222efadce9998f9bec8611de668e12b5d\nSHA3-256: ad5f76deece42299d761cd7e7381cc5372fca0de6ef2cdfdeab1a820acf22232\nSHA3-512: fe9dff2529251a4e420f6441c6e2b1c57138053e991477549ee70abc6e9c4e7cd7462bc3ceb290b7778ad9d7b674221cf51330b5fe87f45d39d9b38f4f91330e\nSHAKE-128: cccbf15a2d7024e27be1696fb0acb73eb939abbcc65b6b2e0e9a72e1c1a84cb8e74da7fc78891ac5bc6b3a1055c7198eedf8101bd6b980d19c89099e37987258a5cf832886a18a68b3768ee286613ee9c754f047b218ba44e2fb85f327e695c633c3c74b08c7a8eb9cb4d78c01fb0ed1d9d23e177bc942c9e2db2ab64bc2589b9c5e49795e5536ff179ee83bbe3f996f27f459607dd8e0050b43063da9a75d600d92bc003da2dbfffa316470ae9776221ba227eb5bddb7b5bc6dfd9f07f9cca7ac4e78fcf8c414bae8b8c408fafe701665fc8cc30a3b91230ac66554487bc5feec9e64b26e203e6e48ede876af8ed22f1ad0b9a5e160e1638f26b52ea8e860082ae285d4f67b8786bf2fd4ed80e4fd437f94b2df623299ebbef97ccc4fd7249257099cd4a93486307ab5527ee5661149a123284fe8b3bd96a1b0c475187142eb29f7cf56d5701d47f72d30f0942146c138fdd073a2a619787448b10303e965107bbf4615605802fa95e91024a1e4701e7b17969f3112a16cf562d488bd4de95f0e1c7a20a18766834c3cd58ec7c1fe49414077e4ec24caa6434d219569ccb54efab5367da75ffd7ce3571a1437a0dbee1e8d4d2f2cd1d87d917ecfb09d33a03238a3d6f19e50bcb2fd173bb7f45f0846cb6cebee818e62740b20edd3aa47cc0dad3c908c581b59e49f26c57e4204c87fa4ea2ff1ebc861b979fe5985938ac149\nSHAKE-256: 101cfe9bacd2831a4b3a6158f72fab1f17db9ed21b8990b11b36ad0d8e34678dda69fe9bb3cc8cd51d0c492d9763b1bb6318da9d5b3a4ef4b915e421cf41f0fec3da01da8dd6fd2a7329fc3fe95f951ca191000c2173507ad7f98c119a4add043d5e41ed1439506da87e51e3c4991e0a86cb1f6ef93770b30522c131b4aba3ddf5f46fa507f869c9226e89d94d3315c60ac89cecfd1e493dd4c0d3fbac64483396c3c5dad300226924b8c6f9949845b7a24133ffb42e165ab76215205c0c8f3e36fc4e1997205b09f3008029f60820a28f21d8f08fc9e5b26f20b67fbca1e0de1c0c97bc48e7eda9e43c6dcc7eec7b6edec93081b7ebfcab874f6b4678c36c7299e279cdde7388556ed4a6bbc601034bad84637eed67417bab5632a6d8e6a0647dead8d68096fe5963d4fc30f8090a900ebaee2f50c5ab2badfe28247073676620c606bdfcff216d5d37f8df956a546e63104791156bdba748ce7ddc4da82bd7eed66112b86dc8f49b4ed64e723edd6fd3f5ae97a614310c9043c1d3345c3ce6fbd35d91782408db5dce39c43115be349683e8a461045d1a0479ad4d729fa01b8d782f04f585a6537e3a9704fdf92dd7d9f1a9b848524c32c8ddb12c800872413c9e88c78926512a0b2d3c5507adb77525dc2e974eb62b05402262def7d86f6b45c93ad8ad87eac2c82f9bc507be4fdb58f49b3ac0bf99ad93b55d06d6d15ed8\n\nInput: cdc7d095efca120d007355a2895b66875c9cc22441804351f2fb09d7d90b9edfd967c35cebcb29d6c1bbbaa8dc69af061693717562151afe071522cedf04fde0f1c9eb3f28eac894b73dcee5f779bf9596920419b5b78209e318149469da41959cdc8f2150f76c846b41702295410a63816592cbc7c08845d44711417494e102b9efeab8a43d8e32eabd73db46470002a4ba6eff8a76e23986ac333739529e4bcb33b065c6886610030ef777efb1593df7394f8e0813a03c107b23f455a34fd1db3c82386be2f885931d8b71c39f206fc657709040fd7e799339e934bf671099efaf6db4633fd6c7422d66995f27b48642a528a7b7829286b683613c74f240cf7cd01607ce58cbb7be61a548bc0df1dbfab32f95e9037fd16a14\nSHA3-256: 0b48ddf496d546e2e26ca3872a026073de4acab887a09cec2ddc2d2d5ae83f73\nSHA3-512: f0efc092d8483f54518ac283350d0e3c7a99847345fa541a1c6cd0e49224c7326c77abed931c6240228c5c6ebb75789a746f0d20afa368256c0c9474173bdebe\nSHAKE-128: 67174861230db049a88681bc7be757f2216fe519a04574d5bc822f18c2e82e677356509bf3f541e1e5a1a29767cdd19d815dca663303f39c9daa8598e85f7100b98c041102d2ce2fb0ef17233ee5b0aee6260899a32900ef7e328853a136d27af732f2bb051947fcc529391016eb12def1fa8ab82dc3c4757b703840f7765b49b7fe66df5fd4f200e619158ae78201dd5c5d9eeb1b0283618bf8a54a39432ca6445ff593006ca5222c0e8f16454dd10b8e80f943e279cbc4bcbca73930340f7b523b71c33800b46332097cb05c751e2f7ffd125c3f5acc0972318b849df72ca2da1f4d3265ae1cd7e40bbcac57cbecb9a91bbc8ac67f87fa52dcd789e69a44efe0158f67f6599b5675949aa1d1e9e821e31211fde863ea6e5b71b36f5cd927e081a36dceb5a178cc67a89cccdef82543d2de8bc64d70c479667a12273f0ac5814090fcca026679258d83d9218202f86ce94b4593aaccf34afb1d3d805be2f1ed37b0163aa87bbdba93881ecea6e124036f8aa9eb4c07962bedda4e87c0a2b9951a6516906a1721ff7c316bce5858c072753e8854ba5e653919143188a0004f296da05d5975e7270c77d689d4f18f9f2801d6c5c344000d9a7b5c91d3f357c7369488d1c7d1f1029e9523e20e4ef36adee0346cc8efff55826fec0c693b5018b0ab190577e2d44e8ae09d02b17f057d16ce3651b9493ed1898f7669ad23d462cf\nSHAKE-256: ed7a69ccb1d8d51e984d8212ceda3572fbbbddc118d26d862f74675eba3876bbf3fe7d3f858dfdcfe90a343372eb6f378d7b725c15e183b82f1ce7d1257a36e135130fc765dd8d17ca9c1dafaedadb7a76452721e13338a1595e8cfe37963f4636f3bfe72bb4ce37afb1ddbf9d783bceb5c1d97fdfb9c24da3ec7df488fcd05f3d805c3b7e7f5662aaa5f41e686545020431b2aa5695f097ba83b9e8c62ddd622bdd64888d4887521450e4967dde86646a3e9b1a5ce0e83f7acd27c078a1e33cd771301727e497910afb8e4542c4f842830830fb707646a2a039ad5c084e63fc36cffc2923c13f89c987b92d0e4903c31b629daecfeb7b2ba7f752392d2ed9ba2300787daf30b6ea57a9e1fe828dff5ac320e050dd28ab51342f624126ff2a735f2ce35fcb02f0183acfa28457873d2b42986528d3aa03d1652d4d3ede3bb733f6b0f51e9ec3727d492cc370af58cf7d8aba4d2b5e7d5ca15f18824321bb7213e441ff1180fae23c9005f9590a7bb874183b6b8680fb77f30cf98f5448da12aec7ddf921659c7bbabfc4853e8c50a8240f6e8265099e9c199a6f29c6", + "b1bcf7053c36e43e980ae4f66a252636e1a87e4ff4f7677e5d25a2d89fab0911e4e21e12249aeb8a3f291179dcf8d3a5e52eee1119b6a67235370ad0baf9bd48d5fadde24b95b7d84909a21cce4300d7ec045daba4bc49b7b7deedddfcef9a0d76079008\n\nInput: da4b2b8d854d4b7d4ca5d5a6e1b37b6536e365560466405ae17d37cc9b66eb6b93ddd0de81847bb438db1db4467296e3769ce81f409d8bc451e1c131baa4a284a5ac15a96f2750089315e0bbcbe1c8b222fd6c1f918d0b0b2bc4a0240f9283cfa7feb83d7c1412ee348816167bea1ba0529f89632cf176509cc7a418819f128dbb6eefaa61726d1027d71704f9f8e63e7255e7fa444e5acc18ec0569947eb6bd6feae20514d702ad6f3d5b7b0830ecf11fcbfcfb0c2a4dcbe8cd996cb4df23a4b15bce66dad00f1d8296b272415bdb9a49000e903d35d9def2b9b70ed3bdf7ede3bc62724360c792b689de1d897812227cd63f70b157f690c1a887e32177b6df15e06c6d1848951dcb8c86102a7b246a84799186f15c39ed2e26e7\nSHA3-256: 97e0a7596c47a989c1238b775085b0662ac68853b34b8867202dfc48baf63d6c\nSHA3-512: 4d2ff7f2dc60b947c8d6df387c14888ed3e44f883dddae2ad42bbdb2146c3cfa0dd8b7508937aaff71038980abab46ccde72f0d6f3c81183798a5ee3464a97fb\nSHAKE-128: b683ec0f6237484a26ebcccf7641b49fa5812c67d53d508bf97e58d044cab18a044db3b827e986e479ea1d2ca67660ad9ffae59d106de4554e47e26190a3ed626783b4d07e28d52140be785218c2e7b854bda8800a1111da9ec96b809027dda6763d4f0d08288a648afd8377dd6d91f553fc9595c056870887dfd2f1ca31d46415d0ff3b4518578961a79038b93bdf0d687499a1db051a26c9900767d204a5f9bfd70ba343b0b86b872fbf17124a9c1b997ffe4c2aa2a8f5eda4239933d435a45ab529c6ace427658ba083c81cc023138a0cae2c107f8b0308eba0706cef0b62eaa336db00b3e8f3bfa5b148c642246990611701e4a3f39ff09dccfcfe43b23178ebe863a5a96e7d21a9fcf9b55bf59dea794bcf70e3267470e2736746ff39de186c26af9194a672ad79218c40db5a37bfef7eee3b7927bb7126ddee867bc727a64b92a7b59cc972d10881377d97f9779977ffb3f6c2aaa6aeebdb990933c654dfbaba599479c1ced6529f01de2cc630634af8a262cf9cac590f904027862d358692c8496be501086fcd5dbce19989066e3f61210046edb60040492979306b545747d3684818dd8f4a833f149bc37a37d894d212df80a645db9a15a74dc12da632c14ab090698d88592c8cabb4fb5283944fb7f08537b3a06028b8249e8ef67f1d37525feb42d61c40332e3852d134df8c5c921bb1e16bbed5147025c998107b\nSHAKE-256: d2c92915a0488edfc3b4582030ad111b03906d374b0e22b9cc3de998e093bdc35539afbcaaf9893d211d2a73e817bce981cae26028f4db5a20b294f63f149ed0816bb3d28434b01d3eb7a5852097d4b06f830d7700b50d63e8450f40ea07a83bd24fa597bc23307167182bd3c87635ed386a7aeaeaeeaeddd7c032d3ec0fc00bb2bb7e190ac791a310e3758e6d92f14a6178bb5737c3dce0d77ec51da09b8642c51d5b5ff69922a0414a83baf4f7429d4342b9e9f284a356d2644c43ebb9fad6b27a6fee942c0e618fb645e109548b2376eb058e3a42ebcb530755ace8ed32cfa966b903f75b439feeeacf44bba3c28c9b4e2ef016ebcb884cb056a34023b3e50fec85a3dbe7a756aa15eda6d57a9e427b95e78420a00266ba5a50e1a8433bc1eb2a9d9445cd5d156377b766fef3b106e04ace461c9754c1dbfdfb969cf6536dcbead8bfba49d1c53dd61f7a060c9ed49a9efa8c3e1e6be41b2cd6a54ff4b43165cb07e254fa3168d4c485c67418a1eb63cf5989a96ec232d3d7a71da26dc3d1b0ab4aa5acebe22fe6696e9eafa030c860ae63330ebf58c5acb03500f7c0ac9e3a3da7fdb97b9f417478edb40d267532f233cb31f40823391c6ca20dd7d58873b8c00e4393ea471c791d9c168016bd4c7ea9de4402cbc6a9909115dc6921e19f8990880e28f01076d6cd1f25efdac70d44682bab317a9b723c4320c0a983fee9\n\nInput: 40857ab5b4749e0637ebdae9e087d5e8f126904f8cb613d10c5b1023b9d6d6e4508af1033566a0fd75b3107e0806ee13b31659fb287633ac093d19cd58480e7273a84a5a59ea1966088e0b8f6bfadb2384730028804121896a9ca5749438bf71c44cb1b585033c43f9c6797620cf890ac7834d10318e41c531a26b786c3fb1ddc3cace2ac8e73680d1336e1041450d48972d7db2294f79f03917ccc60ef6be063d92863b283a0707f1b78d8edb7c27812e5a0e42a252e2be578123cb870be64a49305a323891434f79c4aa1d342a167c88722fb3037f72dedf5db95b0e6fe337c6f84a0d829511ee574a190e97b5ea01bb1ee9b9d9375255939aef09c6a1ab9e7574f35a801f4c557f00641bd01ecd4c30488e43ddb7bc07af39610e\nSHA3-256: 426af9ed8ec779b7f7d1ec165b29c6405e79e5bf8072116f45518cc1477fa055\nSHA3-512: afcb19b3acadf18ac91be9eeadc2e819f359e4e485e42ae3d52e90487b66a13c0e7d694573e32a815874d258c6e26d593576c149fa36f45a608f716604210511\nSHAKE-128: dbfd0ae4fc3a6684023c5bd87a05d5c14f94a589a443d83ea08a6dee44310464bfda51b5e4e3beae037e6e877f568b3267d91bd6c6f0743a1eee48dbd8f2fbd6b495ee82ce8d621477fa5ebfd21de7807ac68ce700acbd34922a575490aa4cfac6c97ede9d900336f06bf34e81275819933f151cb8f6b5a6a1b0548fdb3775e4e5c032a8747c588efc940ded5b052eee71723f843f2fcac53f15a897bac1528a10e63eab401b794de3cf4c4fbe8da585e41bbaf89e8fc019eff0aeabf69f3db26f0cfe180ce4aaf86ec3e1671a7d54a1db658edbb6a4932c20c34f523a0e59adb9d8df3beaabfdbd4b02369e3e7ed51cbd1aa8024c0d91f421ca6080ac2c78667e5924a3bfa81a75b1e5769beaed658572438220f54cfa2c857c434082209a5b570f05341eebad97afaeeb93e3851a5fdf52652df4a4381c37019f79c59c7bb52e497175b3f1423f27b37a4d0c046094fc5088a328f3889029540515253508f20aaebef0c5c652f19d5a45f0e9822b56a746a2941b58026fc06917a76bb7c515edbdc9a4882cd78822ce84f5545205f97ff3c0c74438dd6381c3e7b8c6dae0cbf63212fa978cdb981cde0402ddbbf694a94d6d1fca014608680142a2404cb4f869e9183ee83c2956720fdb27058106fc8b06fb24eb726ae310f26295c3e5192404eade63f20115c8c01cc06b2f5400b1cb7c5f953aa0ad10fce525a4a3a3e5f1\nSHAKE-256: 8b7d0782814c8d5d918d7b21fd6a8df0c47e7c607c7b55507bfa7f59282585d138d6bd4d0e39b38c5549038d0ec22cba09251a9d32cbd28aa9aa5bd559ca62a7b57a5ca5d4bd46eb1cbf990e4583c048876b00bdb21d979fc91cbcf5fa8a48d1b1f051bef726ed5ac6ea369eb6f7433eb09f6d58959091496f5966dae57e8ad3e8a6aa890e903978cfe163b40fb1b378a472866fb41bfcdf8f6f64c01a3c350f868db8d5d1c0e42a886cb526d081c0f91c932c36428ada7aa9254d530909c7af414b818e06a553cd5102f8c910dbc3578edb07dab74630956a546a6ff7203b374692dae40aeb0b402a7990b3406cb81b8b85bb98fdd491767c2876fee5ea2dd3b4795d159abc049e9d2763c07623026c2425a86dcced67fe86947db44986f59de69cf38a6344fe75bd002a4a8a5ade2743aabea92306f5ad1e81d590bc53190789655fa60e6530ede5c69b100b10a393f7763b46c24c60a19eb503fe79634a4301023389ac1f875e0736a4638b56edc73629d1c45fb67947e3cf2450bad1c7034a3caa4c8970cb1b4741856b5ef3c021ab5570c90aee5edf72ad86bb3b2ffd8f706341df08e4e38812a821eb3fce9e0693217406ce5ed992997d0ff0d529385cd15c6f689c3b0b24f850e19876d04604af386f72a644678eac55b1f8fff7802d07dbc56af17c292fdf6afbf71042486d1691172aa1bb463c089f231c6298bece\n\nInput: fc9087e76eb6d3d084e801aa83231e60687b9c3fa6d04eff6945480a7458fe660fc0612ce552c72f0090ce99083043b43390a63b351a081c0e2f089a8fd290b9e4586cd199cf9c90f1b86acb9be31eaa78ae32661e2e1921b7cc3c7977840bf36e1ee9bba0f797dfe456a7bf82267ec396212651931949b05b81895e76135219f9bb1aed88c71495427eda3fafc1dc4ddccaf7be43043e82ad524402f88fe2b925524a84da14a99ff1624dd351f8eba7b188e6f354048972f72ee5f3600da9db3c1f573c27fa1d95a7e5c2c9b233e61202be878e3789abb1c0a5d62182497c417d1ebc153edfc0d3ba3ca28be8e0e8597d3a56adc1c96ab8af4af3eeca441e8799a3b85691af7f29144cc8adbf391f800e71ba926a575151d24c898f6d\nSHA3-256: 429a35c46b9446e852b2ab200a426ad3c83001608badf0cea48e67c066e44001\nSHA3-512: f70f4d8286e548bc52b4c0b1dbda597bc35cc4af0b9a89afa82956daa1f617c9db9c913891f9bfda8360a2bf9fdb458c274463526e42ddc36c36aa916987e9a5\nSHAKE-128: 5b015f3568c2cf39f7da83058b6b89b96379e94101674d6c6370e2db5dcc86c6ae862b8ac8cd675274604c796770c25ee632b3790e15793bf66f0f92c2af18ac92ca2a3d648303eb74b9fe7b42454756dd213a0ebc14c4d9f157441c15e8cb1cc253a7e2810428097c310f9a7e052a9cad45e0f2dccfcb388c3a534fea7e3a9be6c9729eef9f2e1d7ea6e1b3345eebe4f8821d246ce252035ff4352c8640adc948d7f83771aba70fbf4baadb0d3ae6d88e1da3496d4ce1d53d89e52e3eea46af04d01d809c3ca5d0aab7f671063a75d02df91a77113c3011d108a2601bbe88856e9da62cccf7e7f3db66aed7cdb4c462b4afd4e65288b5a8a182eb7af82491d1e8042e617c93f847aa3d86e55a3bbed77c8fa4813f82a6c705d42b82017e466964b2ab5da536d92a7248971f497fda6531d36d0a7c2065a600ad7803b2643367d90e976ea54f4be0cea31655c5fd88b0bb842b9c7d287b3230e1b3e1c70ca32dc56130ab095ec3d1bc7a13d2a9d1a5feb0f699670dc741bcdf8c5481731c5867eb13a2878c3d90b7405266da0a02cff2180ad3cbb9d716fdbf9e5dd03ff10c02bd6f2a3734bed3d9b41ae1b90761594e906debabcbc5eb559e6bf14c00d842c3614c6cb5bbf50e73b3b1fc169cff836eadf82632cc98b3bdf0c5fc064f66e833a224d6d68b343d746fb285aa8a99ab42000be32745c7696bfb583db4db36ed06\nSHAKE-256: a0c8d9acb9bb4a7be8bf16b3c009635d4acf76f69c5b1395b8ab5fc72ce0a275c5f019eb82f87cf48e99f75f5a74d77a1c78f9089df1737995f5541bfa410e489e54c81da3157cafa62388315bb001fadd90f851c83d92cdd40b9da3e509fd2c7b04f4fa51f3037d593fea5a87a46e2c58e4704434e45fa54091f7340aa5728047a451febf82075d03697b26e57eb9818bbb84d621eaff263b28330340a71f0cf1dc69f122f590bd61e8d35b89dfa0064519654d13029244c7588d9426320792628538b238672ab10d1ca55bcd27823a3a11ece42c7", + "bd63e74664e4b9a6848357789228e98eb5b5aea74391c999202fae5196bc3e04b17cddbfedecdcbaf3a647d1948d12f98f717182300787f4774e1e78e8a705d9f2bb20d43fedb7ce7c7227046e36f51c8b191e8bab7b8fba1d38dd4a7c292c49f072b64692cabd90a3dc78697813e8087a974f4c516d39f15f02d9a0a97fd02b7cf3ab708ef99985f9858eaeb0a7b8036a76717a135334deb07da45be251d2105ccf4f654d4e9295b2e1ee0d25baa23d43a4eba396d5f9f89d243b6bf13aa01ef629c87336bd7fe3fc4d0ee5360b4cb4b531d4bc15c3876bdd502a234a811278c76e0fbb8e739190f51410b41aa3c48b4cf8dab173ab00e1fb8b313afcf33f09d7f2dd5b86d04bfb8f7b82017b236d2146bf54390cad78727f10229a8e2fb942ff672c98e39304c17fdf3\n\nInput: 7fe6cdecb3fbf75172db7a52a8cc6ed24b110147b62cb74433d44398fbdc24e392f1f6f33fdbce5a09c7eaf37c1f5d2dcaac0b7e291a3fc334a3536dce351a7f137e7251363da73c0e8361f3381ab7da0b9e0d21802ba80c24630f20207c9d89b775d54b8956e4da37dbf6b2523aa0af71fcc59cc9e85a6c15d1e1e746688dbb2636caaddb1b01ecfbea34dbd3162eff996f84c364866fe1a0624fb5274d6ab7769c6dd97e7c5cfa054c9711812a605cdea5d4a821f90f3f7e1b672d725035c0c1e3c21a3d75a13d90edc7db5f8e7f1893d31251059788d3191c8b1f9c430dea210d298d8721c61eb9d3f5cb77f9fdf0870d154d51a03d6b3e997e0ddb7c6bc6738265a659ae9cc24e5d59b5d60e9af04ceefb31c6751efe3703fdd3bddc\nSHA3-256: 6d48c9735c7361c018094d02a70c28ae7497d2c7865163555a61011c90f1365e\nSHA3-512: 901e829d81ad9506b7d0d4f41ecf450d2f36033c733ace8c57b8b88760c14ba489190894ded1721292bff6e830c906cc5c228436effc2d08995bca9bb0a13da4\nSHAKE-128: d55b433a0722b64ecd9c1475985eff90dad60bbce50cdf7be42c565b9cd3152a32ec459bfeddcee895004bf3de4152f578217686c1ef0644f76ed32f3a501bac1389b884637c4920e5bf045e8dc2b0ef60cd335d6f0622e66ab1f51cee1cb393a91f4628ca8eb7a71e6754c593bdfc5ac00c78111dabd1963c39e55c1907bdc47ebdb0ba3ab4c48af868a4f8aced18237cc04f46e6d37545d1cd8d86742dc317fd80b79bf34359c5038fbd61ef88c2e648584c1e9400634c5a59f61241eb0ccfd7c61d85da6dafec56839984ac9e802f0df559c405b72fced4d50678e7ac7d08ef9137c393ccea0b93e1ea55f5d6ae7f030d75344ece4c00e047e237309088f7c50a84d7d57aec96cf071b7837275411865eabb41969ce51e16fe5a0640584842ec2c9243d20b7f91d6cc0367a1f481cb77a9ebce97555ad1e879bf2c98d2f20767dff1e673774f8602912bf465bca7440457f664de5c8f7e89271d15e909bd07f3fa3e9dc3c25e05f95342f578217f434b61b051a4f8e3ca97713d1895a03d5ba520a1eda249a5be025b03ef9f18ed2c12d4b2dddac1b04be8aefd3d49f3582d959fdce4ee98338cc434c656d8e0cc7f28f6f7b0e8dbd1f3ea0e7aba39336ae24e4a5998d760e01b54db06d3debb49de377b0ab94177cf16f1b633e58e415acc5c56d8eb6615af5b4331f702cf52bf2ea77664cea34210f2ce5da08eb1eed5b\nSHAKE-256: a07c5aeda940a08a4e96330be1874c1f67f641ac17366357d3b8a3d1a0652f314033e1dd80eacc56fb1a0ea366700fc4c3ab30d243d731f83295f19d79dd7a317bbcfdb37c0a8f770200b39c22e1da549b54e4264e00f837b85cc222b4814bcff6cef68779b95f0fb71d3ddbdda9d875f24f8cee66c9bdbfb53a05c2efcc110f019749a860a06fa654b68028a950d9535ea0e53888753a32737625e74ed15d9c099b55794517caae103664abc8efed099f551d2e46e7da9ac89660ae3ab4edb27eeddec4a8bcd13ee871d16fc9b1368a000164375c725f8d2a2b71e03486e2407d2752f469b25f6bde0c65901f5027e2ff2350cd726a0e454572864c926476e3a84db2dad891d786a86784f7fe3353849b90eb39b96a098fe573016a13cf91ed90a79dd0054a854b0ff372b959bef00656fe039b4baa8b07f2ef8c7211072760cac73cb1c26b98c7b84109a36bf1c86d9fc228b8c6a432b1e4d855796a652966648334426462cbaca3fe52ba8d427c2ad1ae522036856cb1085d70435d1ecf8ff7ef7cc4dc813caf3246db578b432c41fe5a942ff16212c7bc276b23e90dfcce1a72ae539dba88003f5eca8012dda32b987a7f536098244c16098b2d1985fc5324a106e5b28a0890b47dd63a089b991e8a2e981ceb726707249d75263892944928db895aeeab269f31ab4e8e1dc1799425ba16426a583b90f115dedf5d89a2c1\n\nInput: 541735f7a612b7b762d13e10506604068c646d932a6bfbc79d74b7c632df52ff02e3d43a1d964bbacd132233d7151399baee44ef347371450a5ad45f50c74dddb758a64eaf6b58fbb5475160712c74443de884aaf394353aa5fdfae73b29c9a7017287d9ef9f04ac06c0f21b1f512806743017213bcc8596beb7030548defab3e4865ffc54cbe6af0c65cda66c9002a827ada24d58ac28dfddad903376da8811b5ffe672b2d0308a8a002f189ef80f6988731318e4dbdbce7d532cdcf7fe5241bc13f984d85c0d730da52751005503baf3529dc5812d193c4bbe6b6fd5542c5888184293e2b01976f03b4bc359eb6fa4ac07283b4e913059b7517152d35672c9a233ef06824318a1e8aea302988c5ee9ad40d09dea6a844824c2b705e75b6c\nSHA3-256: f54283a1af3836885fcde8d2d1edeefa408d44aec0a3b0219c33c3631cfa56d9\nSHA3-512: a00c4337d8281751f7ac9e836025e283b5ae918cd9fbbb6cae2c08f89e66aca9c36d82047936e9803260ddba07137c6481c8f324793f3424a36f6f2105f35902\nSHAKE-128: b8462bf2ec877be1dcc9825bf265dd18ecde6a861986df0287a1c4380bb611e0f9b222852b4a56f33d04cbb2de9d93efc27d5888b1fa896a53d50c0db34b0fde830f1f35d8349884010f110519dda082e9cd7442e037bc28e34661dc3186c451e356125b70cc4a2ca1ecb2d348c6281d50391c108366d4d5b7326c765dd4d8517321a333491bae1898bfae6963fcde71b5e2f951bd00bc03e94c27d8e93f954c577cf247076e75a6138a6b586bb1379dbe45b842444d5c681b15028e0f20d507b927473604829816fb54beace47d9a0fce6c6a5b66515a682141b333347cd491d0782b7efcd476f9c57d6c1152af294d63a810419c51fe9a07af44a0d3dcb1235334ae954a7d6e4b3d61ef972a2a7dd9fd787e3dd4c794036c887530f4bffcd9549a02622725dccc5d04f91d08bc117d5c76ee6fbd9c1e93f6161d9dddaeae4cb622144592dd8746caf2e34866309288be9d4976b70770d06fdfd94fa3406e064e71f582176f5f92bf5e1af95c45d96a7f9ec3e952b190a8e5f87a2273a62d7b3841d07da0498f5ec5bdc3e3114d2a538ab5d5d61dc739af54cd3465c9b0c5333fa72087857b902928208fc9a110a65ea21b0d63c8d48343fe41ae45dd558ea98238ad6a954825143ad2295ac5073e360f1e5f8be1f9463fca9ba66aab5e375f929911938d949a0df8a8c2b64a7bbedb8acbcf02d5c09bb57177e9e685a99091\nSHAKE-256: 132a4aab2cb18814c7fffa1764aef7505ee0f55262020968f4e71ed1392f0ab38ff5dea14aedfb871a8dd886a778d05af4664af0e8a1bb86b3157b49080d5140c0adb05bb957db8b440e1b3a51b060a942cdc488120096e5a75126b738eb129e05eb17abb4db8106bfff35947769a7a7d0a01277a68ce0ddbd06890aab4424b56c1648b09148871491027c17f766b4ce0c8cc264cafa3f94c120f4b23d94013ed67a73c10d1f185b8dba3af99d8ac7ea46f0cadf033c42bf05ee1a37d88ce8c85c248307759e7fb67e3799c7435f8fe4cf899011d816b3a9a3047df72c55ef3e700f0540625a6e347cf215e99f09e517a59e9e74bcfdd5faf7533e4b449d000ade92f49c6e506be1712677712f867b21b0d0c84bb385d61c7632da9f39efbcb2d6938bba4e9960d759683e42f7ca623abcb8dd1088c91af109b46caf3a0b2299eab60f260c4acb4079ac72c409e00b1f3bdea96b31b72a0507de49772623422ef3095bcd9f6866fb2d4b9abfa4cebc4e2c3e43a410c3357662fb450d3a538de3cfd60f7c77419b055e345fe55f532f73f25285b63ef971b01ccc723a6ff3a360dcadcaf5c9f91bc3e7cca5f5c61429fb27dd53640beb9701d986b5407d2b81ec741fd3f7faa1dcb461b3a9a27235205f9d3403b03b08c2236897c6962cdd29dcd92f418208bf1427cd93316e8c04edda363f7b7fcd4dbaf2ebdaf1cb093fb558\n\nInput: 910526b51d4c23f3f31adf694bbbd88dbdfcc6c4dca7cf4c24a49912ad21554271414dd4cde50c4707fb8e04e8a80ec9f0de4f38a3691eb9c1f57a26b441f029c966b9444cd0403456e3f22aaec0d0624ea64881dd9a28de405a312ed7c26620034177ab74043ab4c556c46e3b7f1330f3660c9a9ac1aee46bea25471b64e8cd064c09f62262f297d823cdd7c9f7ae863902c040ad6e494ded161cce4a488cf40252338f4bf0ad6c6d0bbb9824462dbcd29509232d3f71299c69444bd60c3268ae2befc2483efa5e6cd2dc6185e7522b5506f60886fc139175f71c6e3234a0d62ca2a8770497f44800e35057ef4d128893f3bdd58f42edd31fc6dbe5f252614932c266520575363ea7ad55e6464ff32eb55908b4cdf23ed2abf8e889d9b2592c\nSHA3-256: c4f13f0158115f4a9dfa7662e2c65d2789f0f5fa986df308dfdbac62199e17c9\nSHA3-512: 03831e79a6e484e0d1ed5a8bf62dbd092cabdad379dcae48d58c04dd73ea7541e6a1d0bd9ec6a71bb8774314f35f515a6f38ea8f11bbd9d4cb894be05df2f0b9\nSHAKE-128: e15041bfcc45eead31440e66ebf30ee2178f73da36cec16063aece4cd93d3e55de07b45bcf2a1067e721e33d2bf62317a6177427b323c241b6300dcaaccae7f3fb901fc7046a1c18e3446c7bdcc23d0e0983d875c05c265637c2a552e39ac4c7c8f165e1bb4ce6a33ea30aeb9155a229ce40623731b464c7c4dc8ba0bddcd0e357952214508640a3e5316c0c70d948e8cebf604ccb4362ac59d78c623df06a74f08cd157295cb8b86d60ac9fd2a4ad7e5f22fde5b1e779c773e7f41d99af984e04916153d6512afd24da3c33247b254872fcfc82ecbce777056622d176113d761e9faaa4d3c14ee7affeb0b71c25473f2bad4b8978d8402ab9b049ac96db48a51167dd5ae452d97b2a98b9b01434ffa79ef39b46aa67c724dae1786dd7e4a78ee2539464e7fe5edd3e45fa4790159fd4ab0a87a800e244f21d9e40ae666199190e0c3c5d6b4b205245dc7f7a098f07d346067a2e2fb000864df0b0b58db6c8361db940145ed8e648fb619b9b0251886c9c73c34c2f9e1b1c2aebf32429635893b24d2c84a8d82173555120d7d6f10c5bec680a38d375790418d5af6e25ebb89ad8bd6551d294e5e7112d5283d8d63539bf2873612317e4b82bdfbbec15aed5d3f0388302a13adc764c5ca0d6d3447a5038dc8584ccf231ce97996501d8a0a660732025906c6d5af85eeffab39affea62fcefdd538719f0ff9061e0b1942a20dc\nSHAKE-256: 291ce7950a62", + "b19123512740d9501c5ed03872de11d1dc46a6d45e4c41286335589869c05ee8e48e6502bb3b86e2d7ebab17167a6acf714fecd94ae25a38e0c8ffd2bee4a3a97db197c514aca41ba15d278469b8e3252d4bed5681f5550e151698b821cfc2c2fd88d17d30baa930df00ea26245bfc02c64cb59b98adfcb57a56471355cc9d3da822d4a34b166865315af37422fef77b882e4048ecd915281a6b48ce057f303a9b5ab447c82381c5f64976cc32eab0c7c3a2d8d83f5ad3025a40c96cd7b90fe5692fa9a0e15a1711fc0a3f021a8544e731a08fa33648a9331ff6d09f7d624c299f68105eab112079cee143c45e8bf5f2f8b1748d82f951c0603ddc2107bb1582b8daae88096cb1955e006743f95f7b6c3cdf338c5426f693ae7d372981b8a99688f2baead3bbc52dfe3b63d552e8d51fda2d77390adcf5c38d8794232faed18cc6102caa68a64e5bdb7e6257b7b48dc09ef7820e8b59760b3ba41f5d099d04f154cd77ee846a2ac14b9ab7d27493f35fb2387626693b6e8017ab8730da1077071ccb754a87f548498aefdea820ad80640d5294bb6afcbbd4701f279e3c7a1c49d58e598a2f61b90bd81d3007730add991968ffcb4e9b9587bcad5955c1d5dab585ed24e29ef6b7c8170907ad1638c711db9d68d1f99366c58025816604eea42d2272fee53224b65c11fbeaa1068bca9a9c7e3f9d6f584e03a9f1\n\nInput: 7d05094a1f3da2ea13d015df2e188f69fb77b86143e36e2b8c690c29306e04e3c27734efdd2da418a0e63bf4a03a3d3be49ca2658c4b8486bc01420a31112226ff4a8f17957e1a6d3eedf6778cdd88f786a6c07b0ad2a316f38b82c5858dbceca7d80d4c8992c10a858b7ba1db88fa0b9c276e7e5cf647f2336125c0114e77082952484c73a15ba0ae74dab3abc7717b51f14c72ec97811e5b6d3a7cbc832d2e186ef869f8ed9edccfb2052352b77e9a59fcbcb7972bfef66d3d3548d961dbb5a066be89956ebfa1a4c60a78fec5d42b21e98cb9b75db1f7b491393818a593004166647aeca294f34c1aa3d6e1585fa75bd0d549a81bd202938192b3ae58a6cd872159c62dbd93ef94e7c54462fcd99dc52b716768f508477023c69ecfe455f585\nSHA3-256: d4626138d0ffba7b61806c35351a35c206158ec43e0a6793d8e5e17953c9e573\nSHA3-512: 5f5c6773353c716be2c12aaefad8ebfc5cbfc1df3a7544fb7eede6e18e5a4aec4be35eaedcc8b2377eb88a7acf12966d60feaa41a29268ac2cac749e0afff414\nSHAKE-128: 1030cc4c9e3b8871b32584aeb457b0cb97c259e9c8028e5916e7dff492593deb7f4ae35c10df4290bec9b23d9f88589caa36f3b280996faae28702cbf150fd7def3d556280b5a232b91e1f1bfb4b81e9dd76d7940468f4b5964876091c2ecdcb1c6b0025851f6539e3ed81b57ecf9a0c434d917393b273c2134bab757fbbe4aa669f82570de80273ec5cfebbac0fcd465bb6ff99710aaa6ee4b1836d4575ae56a56086e834e8f268a0bffcbe67f2da11a3a2dfd20c1e5ef6212a19ebecaac5a173ae60d71d4e5b8446c6358a408b46c19ad01d7d9b7ab3907230f72971c0b3a97d8dfbbe565b2ad6c61d54401c27e7b52a20233f01179ed7e1d71e7ec438e3c8e81a2fa1ed9e4a9bad05b1419f5fb52801afb66ac14b28e3cf35c309a2f699f51e13bf19a25fede71b9b0f20b5ea638b865706bead8a317c90cef42c493e5146cd617d7c36b56c563f374485550dce7298b12ad84e6fb96269c61abcf0a40ecf89341fc30b77963275f4d3f5e97c289db9318aed42e78b54bdafdd47ac88e7af9c11ad675e7371e91e4edcb16bfc763d7a0c953ff05d99e230ade52d2a795cb80988df705c3b31e0628cc885b120bb318436aba8fb4b58141742315d6702588f4cb9251fbc596d199c3a26ac0789505c65f49b0c104f0373ed18ef576b346da92b7f368cbe15114ec92cc5458f516295560ebeff56b6a1515928d67de3bd0f8a\nSHAKE-256: 2b79d4d4dc9303aa37dc85a51ec0b76f7dba9a05dd7e25f56704b012427b73c8861a7083e57c09ea89eda306f914e827210b7301a4f91b7f90e438aff0769521ce4ee9cd684de307e93130683701d14733dbde1419280b3b6d15501b282be0acc2fb42895bdfebb4cf64dcb13bdfe26d05e7f6c38191b131e34fad47747ebc790042157e33178fcdf85f29c56d0a09b6d5b971e9145fcc8952a0f477e7bac152a7492092df7ecee94b49c187e36471eaf4278a5af77b1cea7bc863a82a89fbd3d8c3b561b39a70fbcb4afc35f2b1620617c544e788b16b81f809b2746d982308b9e1ab5250ca7640160aef30c6d293f847f058cdc7f46ee422f95b8094e1af02702fae9b47b6f7846217b076b981fc52ff4648a36be0b69c15f3b9f52980c06b89cef0ccf80d9bbec46e97e32d591623c66207517cc609cfbef954d9d88c88f625816dfe32fdc5a5eac769471e64224d98f73fd533e6a4ddb525de1bd9c5a5c785cabb2151b796cd114e8cec334ff22bd9915bdcdf711daf1eb9b967d9c830b40651bf402fdcba20164407c08292e50ab3e53b4dfdbaf2d0b7794dfca04d360ada347ccc2a7ca10b60043558305a44ab94e94e77e4f4eae89f758b29fbbec98afe91cfb6b4cd082773f02f03481ac35f5a2a6d67047ec6f1a4cf9da509db9d03e9ba3b1b5b9cfc95a3b62e9298a4b59c572f48899a9e7bd94968d49171ec5569\n\nInput: 8d37257bc1ce2a74f53802fc071c83faf2a1cda4916cf647473872e5167adce5afad92706f092ec11bfd40f44394e3d3c5607f3d1aa6258603937ccc85126a5b284bb11ae06211756c53c752ab31377a224d27d46033758dc533d731e4f49ca6c19f8d4f07cf7627b99699255bd1bb44aaf6075b36ac48eb884cf09eb5ad25a6b1b5afe5a065fc31d2cc54bdbd209b2df28a92e0427e30e2471df570777d47bcb4e5443b031ba7f4f564e85dddeb7112af4111c34cbacc97e7b4963b564c28bc9a966f31c63263f12b6108519325696b2a8520fd51ecf9555509a19d448ab202feab4398b44f78172d11e0bebe09a3cf2253ac7fe1f216765b0119dcbf95dd68825df51384f36bdef2bbbc3dd45e01e8de39b1d28365c0506026908dee93ba13d9e4\nSHA3-256: 461b8958af44435623aa915394b898b2ec876baa9683807d646c0ab3e3363940\nSHA3-512: 38c6b98977513c984dee185bf0565867e4295e2714917135edccc65a02102115831b60a30c1ab1fea81b3d28b5dbe009373db9fe4bf9c15b6f3231e82e4df58f\nSHAKE-128: 838dfb304b91679daa626a2e5ea75d64ba50318c3adfb4b05ba4b9f232ae3a2bcd3f5082cec9db146350d1672f136a415730b2adbae96241ed65d858dc52bcf0a1049e1715f24c5275c514423330db10650486c0940a7851ca6d38244fcde265c15845635c355255d0ec80e38ae3a27a9616f9ee2e3e8f62235fe457dc3ebd3f88db51ce3bacb32d5b4dd4ca06f9162c93139e10e99189d5407225c898fcdfd14f1e8b7b154769a3bed3fe1a2e4cc5baac9bcdfcfd02beb217b66a0c7ae1d6558ed2138dcb9c392250d312c307e8702cb60e3e3514157e0720715d6a0cd0a71d246b78a8e5536eb81017b0642a643d97fb0c84ac6b7a6761c1dc7153eb235d7e2c9c30149e820dc8556f50e7baea5448fa9a317e1921a37fdfe62567e4df3e471fd31463f4df66a651b4aa5a1bc652d8e17f0ea069fa93933a306289c5b9d42652e9c99503e05563d947ebbc19e7f60f7d9e7ca131f9400dd16eb8aab40ecf30b9e14693df9c91d5f5073fab6e2b5dab702f537d7fe8583294d04e306f13a57f070a8fa353bff58c6a8b48f57787f98d244e22e600165b09904d773b2b742237d26f4291538b398945a7bea2bd400bad0530bb5d5836970ee318cc3f5566b63b0899c4ecb9fc78f807781f68f8655682bc16aa3721354caa80a043fede006fb2ece3f8fce692d2d8a91fa784b490033ecf7cdf5eb4aa05d520007401a8869a48\nSHAKE-256: 967db108d8c66c43d77d997bdd5c6a550392b5f79a7ce4b8cadd7c20fb5416be483f50bfd8ba39e69994d2b7c5b96f24f66fdcf98377e21b7d177a1884a6fac76f4a1f689ea7e566a23176c88f70757a69c9eac9975e4bd790a7b5e640879b61eb0f39a7089f6b6a1a74d14eeed179b82b533edefe0ac449f6b35cb36a9ce22135d2563b9b6c459b6cab9850df05fcf1be408aaa4a04bab8e5070e24b34f174ef20248a910fb06bafbcba5d23fdb84cdc0b3ff3368e968e1accdb2405400c0aa7b40cf972339aabc29b6b45af1ee9ab6c5fa896155f7f92fa90da168eb6be1d4c68aab2eb164c1e3aa18bc2759a3986e4251f528d365b677a9d11b73537bf63568ec616f6facdf6847c1ae90563d7d2828ac5499f63cb4254626a66251eb5bceb5cf883bc92f47b4f434405a088aa1ba367f8ff7fb0764216344c0f04472330b7e88b498ca0dfcae0d20a83158eec3f7ed7aac0cd8f6f20103f4b3800bed34c533b97cabfbeef485a4638745ead5953d1be0e01102dfc1fe37d9fe19a41ee82ca2e9e195de5ef29b2c035d44164bfd1162f104b2e35cc77b79918acf2ed5224e00e55a83d1aee05dbdcb50750af44c83b3595fcc8e5d523bec1ff505e3a744860760d798d1ee51a8b29bfcc79a21c4ff58b65c7a7c47852167a94b2feb094358bd337d5fb1d546f62f265ac50f816a3c4b15b34c0297346732c93ba978d4f0e6\n\nInput: 7133a3246b8d09db79f615a42a178641080ed43077904d495567bfb196d35a116f847bddcea64a5366d4b9589d0e22f3ccc925553024e2badcf495642efad5ad50fb792a998b59730f75e4468144a8de793dd177fc7b89912a604059837968a62bb034691af0504cf480e698398b2691024a3a4e6cac8b3c23f88eb2c9fe3f53bb27c21c6c5fa60c1c423e8e426318b98e51e5cc14219bd7ea3864adf19624079811fd5b7c6e466290ae2993e046081af5bf3c5c7870772539ebb9fa4e6f19b364e68e2344072a15599ca9262702c7b8b76d96c0f67ac5cbc081a76e9ec12783ac31ecaac05fdc9bf671cdeda45ae85ce339f5ce1ead05535caf77d18ff25e179c2d4d344688f178e7cd802db25a44dc3b3113cfd5837a6c690bf010a3ae4328baed76\nSHA3-256: 509c07e9a9ce88e71aa7688fdf2a39c353576c59079259797edfbc3f46d961b9\nSHA3-512: a209eef30f43b43a97e1a5e33d3cd0444ba7fcf371eb9715b2d3f072f901e2246293e52fa31436bfd3a25d46b8e906fb24d95543bfc9a7c6b1055c355d8333aa\nSHAKE-128: 3767771efc54ff5da5ebee484d4a0e43450ba9e219e5ae4075c3338407589c86e875dd828bedcf960628b04bf0614c9b3d56ed824b5b47b144b49eb464b9fec1e8c61d2b411325672d5ef937440b9b5aaf85c99c720490a763bfb43b46780c90d6dbe0a6219aa0f6a7b35ce2d1e209088da03aec22bd580bbed5a15d78c7bc25084ea438773e1ff291d164a77d84e34c7411a5645d8866dc24a3df7778c2ed9aafbcab1cb70188b86c76d4614fda66074febd711dc0a775259289922705382944fb75c2977445ceef2d052d9fd8e96e04e6598bb4013d9203f5b2cdea5e1a7b8ba226eb42061a4ad9b584881a7d5e0f16fc52f1da018416c4a734a2375bffd90f6c7e0d36835c8336480fb35577de2a07673b733e2b224805d279f12c9830c373c6fd75a376bfc886a56d84f0b06674edea6fc4", + "8c19cf482bdfc3f54b1a731606b0ef35a347639edf356be510db50a4ecd655f562b65ee56a67596d0d2193de5caf473716fe6bb9df02a65505081bb15bad3ba5073119065f6ccf73973eed639c028c41730425a419c59d480c62d913ec07c98a63821729ad363867bc5083f2aac901297e8496c428a2598f57a9c84aad12ef95421264e83c68505b6daf9d785c743c124947dc7193b1667153dcef5b6cf32d5a932884b5d1b23806ae00a9d2e0dfdd2f79612a9f0e368885924bd3f9bc9e729cc3f579f72460003d935c868ed\nSHAKE-256: 8a3cb1139c7149d4dfe924f55ec0c8e6dbe30afc48dba519cb71e5231a0d7cb75f90ec1650c6bcd6ab3116f2b3f83054bf8b0918090538234f550162e809cbe31b7037f0fe1485dab815764753b7831f0dced16822a7a73f692e2361977906d0be716756c9b7e3d1627351113c7822b5f3deebc98585c07267793eec06dfa49be61cccb5ed27bb9def097e0c13c94afb31c8442697773a4d4866db8dfdb029766fbd954d579522d65375b3b1411f10a8eecc22c51a53d9c5ca4c2c38ae366fa33b784194dac64613830e2b2d97845502c3767bb10352204094af6c3f5f03819d6c7fd51a6ff037e15e7e3579caf4c1066f04c5079b2f808b44fc9984af94cd845dd80788116c9b107e4fdd93d624bfba6eaa2334f833a2c5956a3dde48ca31754188a40bc82efa2a2b5441316d705811b0c646b4c0bbd04c6fa9da836284c5de6bd0b1d7de409b46cb2e92e297a7966a0fc766fc5d81ac530e02f22092407318185ebef5fa86d4d6b3b7885c05b6d43b95afd9e6cf11c5ab03465b8924e84ba6ce6e657db0c560054b116004ce3bb616b545f1f8501880f4f2d852c2cf568a115250392b37d4d6bf65ca98fb2a9b287bf027519a3ca2f386da5b89954c2911017e444b1b61135103effaebd857c0ec8d138c88aecc67278e58dff9e92b32128c103750785fcebbaed0c3552d85afd62396acfc479acccf1566d970658ced9dc1\n\nInput: 6cc39693d1f5a982ac02825641aaefa2a3a1d62aa83017283392dc4a606be266027c4186c4b46c92f3b41d8bf693f549008c5724cda01659641be6f595ca3ba66f4b381708dc59663c8ec0bdd5cdabbb072797311f663f653ab1ad95399f0abaf6b8004719e5bef2bf703325a49bd129451117db95cc80a4514b2bf81763e3dac6c4667277eb3af6880b99875b608a525a69092fe3fa35724a1e0c5e3259df0f0a7866be3b629e13c4ab18ef80feda0c99de436ef818b04894f479725eaec614d6326d5bf10528a244848debfffe377113f0c1bb7b4b306dba6e17a3c02a490376769b4d498b4ac355b5c97f587e043ce001736cf4039f6c460ce90198d724478d78c8186e0cf5a33d1ecc6d7203b0e77f096cc8f8b5146704c4784392d22a3fe9712592\nSHA3-256: aac5bb80f7a750c76ca439b6fab24b369631b1b2dc7a21ce8a22af7a4c8847b3\nSHA3-512: 3068be89026edd05e7260f384d68301c2ed854d5c3fe5c370aa887175c68b2365bfd1db3b4bbf43c777b6eaba45a7f125b3ce6b0ae62e01311cb71729a994e2b\nSHAKE-128: 43453dc6a35904378c3fa336d7f422458f6c689ff7c07a2c218c5a5d51a14923f8c1d169b9547c1d82b0f54391dec847e64e1ab77bedf047f685ea938f63313ddc8066b35d630b93e8029f0ac97a0ca8a8179558e64da635b614a75e24a7fb941f19332b4b441c1635cb96e615ea157bd6c7d94cadbd3d0e8279947c332c8ab93b314d2053fa5af27585934137e1ef662e571f0d445249780b916b05a9c17b39e5d0d9dda4d98934c02ed66d02247a76c5af2b152bcb92472370a439892711b312eb347c7a67395d76bd214b841394b8a66cc818e5cca1e1a92eafc74f10133954a6650c2cc5f55add16812ede14c6b26c19aac442c45f7ff4ffae42f30a8007fcbae47a35644f158a06bfd0c7d5eb0d6f4071f7232f4310b5991a59498610de0ac05ba6e152bc280a7219c744871e05c962a33e304c027c7687b0ec63783a9c994dfd99b89dbe7e2dfdca51f32fd7d4908ae1533f4c757468db189838af840b8c493ef30d6a6c0507882c81b04b8ed1dc3e98f14a47e67d080ea4baac90a5abfc5f7eb868640867319867e6b8d5f99bcd919e560e3d3c43a190df288b95528244e6cf9da15bd7a4e57fa1010a74575b3b2d2ee19c70485843bf1b4db7ee88ba9d7b0aac28e1f88af06bd5414c91d86c43ff88e26105875d2d1d0bd9526db31b67c2507b903c511dd2675f3615f727874894efb5355fa211b593a2c625e62c2a\nSHAKE-256: 0bd333376747586ba078b85f6932b4af6629a82489395ea56131fb75f6bd98b18bd95af63eda085e7c9d481871101e139b4bf6d2a899bca2db32e3dfffd458136ddcb2fcdf00590cfb19a3379134f9c145f3c31d4f26eabe5b5401e3b9408bfb1b5049d3ae480e88688f8f1d765e126e26a39bf6c61ed2226a26b53ce531fefa9fad54ea0f54dc64192d7591150edf002af3759cefa4d1b9f1ed71a20da717e5db71c740f8dc232b6ab1bc767de11ad319f8d58ae3f955a1969da7693cc12a2f92dafd2d6f9d8513c1ca1e6d8e3f7509530088a05f52e53713556505bde02cd951d448d01b382b8b2401c7addd2f93aa6292523a6993135e4e736efe4cd75b1ed847507875b5c5e54d0b3e0b4e30fcf57bf1c5f6bbab18d70bf6e92e32eb633287dea548078427edcad3b4f4194027963ed61469189838fe2a94ab26d8fb0ab0dba83dec29ef66a006651becbd5a5dfa49e02ee10cb438101a7079e0933148cb5baa47fa20daeab642d0b4f38572f21b7dffb0fd475140b94cd959d5a2177c6939c63120781e6537cb0304451136749968cfd58b6187d8673c10e74b5fb213b5860557c80bf7d3e62c8bbc55e87d47a226ccceaafe13f65a09854ea7c8ee719856c163cc2b717e5beb74708d5645cec8c98a8dfc6981686b5e274fbd7cf6ed6959343ab99e34324f25641def45e840946ed6f02f4d194270f6e862c7407db238\n\nInput: 2e091266dc58ed4ed872ab83511dd33590228e19ed751fd83a576c4f21008bf585bbe4e5fa412d6ff63ec28eec09df4a3b341701e3782fae10ca2f4c68e0f4dcbe6a21139eb0f3d4e6a1d343a20494c5ab5facb52c3c0fa2c3cc0a5052576373833f029a6369433f4f01c21922eb474f8b28e3777a30e9e5fa1d9470c67dd6ee1f78289d18d55c1868054669a5191792a958d12b5147f689a0783be95a468338f18f44bee2a3d24df384bcaf2b0a5217c3060f94e196655fbf891e596d35129c519f0a042083c3ec8898e8bace89d1ce5914bd5f7297aee1c681f75d2e88fefcd36de8fae97e07112e3a591f6de023cd04d8b0f6f4cc9059c41ee4a6d34f2b8b5ce552edbc608c2ae6e826ab3428e01e6cf7609290ff49bb09ed813baa8d161f1f2413ca1f\nSHA3-256: 5c7fb6397b81c1dc62f37308b4812dde363dec91733d9095db89c8cf57de393b\nSHA3-512: a7d9f2bba59e4abbd0d40459897a16d3d3240ff6d545390f0650e83190e81fed0f27104ae4f846a7df822952ed096c21d7929ab2e4cd6284355d598c86a330d7\nSHAKE-128: 1e0d2d42d96b0829611d3e276e6b697ef015e30ca8d6de9b9a838136249e7aae2489d4e768585181468e11674df4e4fe45ff29c5b99d2986b42208eea2a92b8ab9b2c9dfbabfd6738d751d254297056111d8030855f1a965cbd41b1703cc3d31f23572224d7a12fef503ad33c21f59d1a931cd77a2f9f15c35c7f4c5a23dc9213cd3eb7f195d7791ada722ee757f4ba023ac9b0d20ad1e757465c80e02c60d44e5df7a52038b642ca57a6763ac44915ded5c0ff252b3b10ebf865c91ba1054573ae72aa7975687e71e611ad91085deb038cf34bd71e33d4610d4ce67f3798fad0ad07cd60f99aeb76b92cc8c80540f5884c2396f273a4a1d7f1eece38b068a5b9c11ab0a3c8f5add2d78d977d4886649a3e3fc1df27842eb7a61d819acbf5b130d9c7e1e79a65f19986f00316dc960563fef757b7a54d6091696f6cd264032f57c8fa83f2e5d9d35d60adbfb8369958dc74e114ad65d8a11fa6206527cefd72d46b789aadd19e3e55bea8f529b695630b9fb49511a85d7ca761da072fdc0a832169f4d8a4fcdab47405c86817b0226faa882ccbd3bb99e9c9abe6c721f6f07595c8d64447dd19c578df8dd84b8e6bd41a8f2d0d9d13bf3c6ca4ac259af09cf99c156d2f904a218ae2f388023d094ae427c9bee1a0c7688aee56c7182fba40e007bcf7028382bcd0aef557f440ff64a5808119cf8d0aa64cb310c1947c8d55ec0\nSHAKE-256: 13bf2a73747f0cd365150e08c10bdcc8e65fab0a179281f6a1db4551310e602af1e01769c983a8292a4747d95730cbd374390775f2d8897e49a88a6a1f4ed3cc67d75a843e0d7fc310697696bf9ff693071e51d737734b2949e96d6d65593b4715ede9dda2e877b4a4a5eb808bf3728dba02ae1f1e29c87fe808b008ce8e135193763e2666b2f67ae19232c53e06f11fd7b79711cc0ec963c5fe0f42f3e3d6dcbcb08686785aafabac481f5de7944204f8e32f01f0907328cba07ec3c292d1f0693a93376b264bbaaff2f2c5240c6aae861a7b943662293ddb5fbe2bc0db61a8b3743ce4b4fbf9af85672fb9cfe33610bcc015a4c7ef91bc1afd51eecef9511cf970f68f4dc3348ca768ccfa73b48eebd1e50f3a8df78686b6a77e4da73849b964f7ab21e225781704380196baf87c3bc7cb702973d0cbab4012df1cd9370dc747976b01fb3c6e7c70bfe074f57185b925972be69c9a557896e63adb4ee68cd51cf2f60c6c5350b9a98befb9503363b6424443e04b5ab620acd055a5521533b5298a23b9400e3e31b41e4399d0927b4b5d321810508cd91af3cf1e978fdd63fba1a781444219bf9dc2cbb2e4733d54534bdcb67542580b104b784508b3b9c22a2cad8d6593a2a999aff702e7ced2349a4d142951a0ee582672d4359acf4522dd24e29ed43edd40f3cd44eccf1e49370a0d7611c873364aae01e0abb768147ce2\n\nInput: 43614220cfae0a3685e87c195f61c5b12a2d070bb7558d9897cc20d3a602b741deb33f5c535841c17b995df026d3db768dc88563aa0cf39aef33fd8c3e60e55d3d4e2b81ed7e93fd7f297a66d2eb9e1a31e5feae0b4ab682dd8d2cac27fbfa964c33eea0107d2fe07c45f28e1a3fdf9fe380f104f37f91853a15733ae6730d477bbc2961edf7d6df740fa45e14bd83f64b6f8af30cb68ba0a4a2737f23df17fdf9c98bc8ad1dc00656cbb425813c0bcf8d02f2cfafdccbe6a6d1455a539eae03bb5bb166d42a42819051bb8e4793c11d148098311de5f039ac340329d05021aa474ac390e5f84cca678b510f361e117275c41370ef50f8f6540ae81d94fce654491c29f2e6aae67b385354871ec1cf0a18231c81b11f3075f78ab54ed39a69a3585e40540c9b\nSHA3-256: acacbfc98bd8dec52209b78df4b250f93f8ed6128a4315f0f3119d9bb1268a7a\nSHA3-512: 8cfc482fc57ff764e6eee05700262335c09a25031d8d59d7885b8a3bc5ddd866859cafb569c7ce4406d40278bd3f5bd2f072fc3c5118869591fdb8ba70c46ff2\nSHAKE-128: 411fc4a93b655c3e89c450141216430739cdbc6792f64e0d92305c6acd431c66e997861eeda284472bf644798cad315ce8ced4b594f0a9766811ea8426e7fd7017ed807f283514f73ccd3aeb2eedd4e5d301", + "ed7bf1916acd09f823cda85bcbef286164116007d3fb35229202be189742294f3087f429d082a295eb4704c51fea8934522755cccdb66678b5c17845eb72f4da5434c49178ad395c6789ab14b374e64a0ad3b6836ad982c1da1fcf9753d248a32b0cd542bcb2dbd6354dfa1c1bcd3f7fe75dee13e2a2e73222a1ed8f946b85cf8c533eebb399812682f976732d4c3ad73d02e8a93e0d4bb7c73642bcf810065f69c4908b5c6ffafa6d2e4bc1c482f7eb17b323e1c0ef0f2856732ea634c02e47b01767b8645b958eb95e7772d38f271bfc7ca4f767569012a1747ec7971c75edaeabdb1cf6859a3ff260dd106a562bc90bd95bc9faea7293d766c58c7aa21031fbab9a27a907e4c8253fffc5955ec5b166fa09cb418ee50711d65554844e7b92ea770cc7c8b875c7c7728fc16cd1918e865be45e489c0a0606f7a4e86f4d45e24d6ce3594e80dc12182a4b8d4b1e93156c94f1e1837ae67609ec27aed58673ecbd98c3fcbfe098776922be5d7e74ade47286d94868cadbfd0017a929529f607078629d3bfdae736d3ada155999468d928af05fd584b501c5c348f9352f3a720b8c353798177d6da9a7be1621d56f\nSHAKE-256: 86eca51958c53d0233fa71e953b2b7928ba4bef3a9498631aa58ab0bbb604bc602c24957d6e5d388e347c7d8794f09bd166a16613208a412bb2130db9b5cf34cf303d28b26cfc10f57fb803ac4ab428492fc91d41c0f024ff2429912fb0eda894af8f2957333733e6c515b766b275efb0d5f88f90926409d6655eca9cbd33f315e2bcffda86120e8c19de45e45ca54155d10696ef7ecfa3e7059eb36bd3eb80b5eb576b6a2a970fe9d989e2276ed8011bc31641496bf418cc38bae347f0f5afcb16371d5efa5842fb73ae4f69496155c3129035afc5f8d79c61abd4ec1617d58be6cd0afe7f8e32f3b997abbdbf3372a36011bade2f6318ce2e1e6c85c8d467ad9467261e1b4ea1485f89d20ed1558bdd7699a1820438dba1178b7009020b245b9e47e38442fbc1cc436f9e4ef101af3b4642571b1931c4bf116122149545c572a0904a4d8566a099ba5c6c8930ebafb217dce0eb6c67c9020caae65109b8b2cd28a1ee35b03afa369bee1345a38736f8037e7c3be9c831743125c865958b842b9e728c911398b706ec2f764421189f021e1c035b756d7ab8e6daadb5480fc15558716645b2b9cb7177aff1e6b98a8da4f4d85d2d66f8792aa2af6ddaae4e5f15ef9fc50d23e29eb5797ae7579a58448f84ca303884472d7ba1822436cbf01d908c39f1173ef88b94bafed42686e702ebf52cdccce87fcfe621ed1f1aec3ade9\n\nInput: 1e9fa05f3a81e19f6b4b3c02c72bf86b674eaf60da30a14690b3d6b23decf5e4a8b809b8f7a1c51d1796b8a4dcb4ac55b35eba33591b60081bb98b615a66f88d1e170f6ba3ebb9cd5cb448fe021755257459270e8a7e4095694a066b29b60e4b54efeda117d662ce11fe10103c512fb2e07ddc0266ff728dc289c4950c7ce92b2d8d3a779e295f37724008952eff71f4d2078fa96063abf899e3605262100c1b7ba63a7821e031897ec01e331a37515f870d24394c5372bdd6ddb91c8b78a595707055d5ed4fbb1ca7f3d6ec7f4d17c73dfa334bc1eec08e17868d8ee1ff3ff11221847d0428a568dcea25667270d8e348c5be84bf635471b0b6aa53f26648488f2d844151f1726f969d46584d3882de80d182ac3f930d2c27b3482193c4af56a27180f26b2e6a\nSHA3-256: 7fa2ca6171e3b25f6ee47469fe5d43bc7781cc88f1132cd6bbf92687dfa3f714\nSHA3-512: 82761db19b644b8afecb00c3a856b7a37a42faf347da64820cf6289ed636e4efc7d5a8218d3fac27121a5128142d3c71be068dd91218abe979444898eeda97af\nSHAKE-128: c1885b7e95d4f7a362df1613e5e4b733fc5800faf05647fe0d11d24955c2e1bd29c871ba9190f3b7f28fd959dfb7d75e06d82ac38b145a341bdf87492315db9e53749f00c60d6644add1875f7dd90e52747f4b2ad1155c0b2a261b116d17c59e93b840dc77c0f2e7e06ab9de699f0bab43d2332b40a33f7ed1c440803687860b4df6bfba631cc3f732a4286dbf6f2a9c817bf411defa632ed688b2372661e23594d55df293f5f32f00d71f476ccc5aae145bf945f2f2126bbd8b2d7272a6f16d37ce6bf474ceab967ca376b9a447f3f70e2853a5cdaeb1139cf95fcb1cf7fec0077572d15a616599883d4ade6db261675d9e2139bb41867926fa7a1ec8b4da1a32e64565438bd6695f6f3286e8c310bacd82a0a0c7e504b69f1a2410891503c949bff9a4db57398c12f8dd731dfe8915b7d8c27e52b1c9400b9839d0b99821311503f25cc4bbce93d0730c9a83d8853ff8252cee82fb7f272f1ef0dcb99d14bc15ee6ee8f94e8fa21fd74a1ef89b672671b18e9faec66fe56f75259539477e6b7b348f7bac2d0bd1e9b3726789bf33d59db7101c40b2300aad6ec8f7a6d4ecd057e3517f10c203cc3556d9e3ebaeef4808c60df0536d9dca9639931650b2b7989a3dbb8b94b6d2c850a89d72d96cbb4227373edcc65595f084b0e71cdadfa9fbf867232ad98eac88d96aeef7854f2de9b285c44810e15ac03242bc191a4b3e06\nSHAKE-256: 9f0c0cfe644345268197b53c0dd84c0df1058e9b33fa0873735361e8ce6550db807f40b06dbcfd60cf95c67520e0ca83c996313a71b3254838958390273ba4c9b2e46c337b4b0bff507a36231d0038e44d2df89b2a734c3212900afdad94c6978ce1be521d27d6116337a2405261389414259e644294a55db78ba5ecd4e12840601380932146d3695d0b3576adb8ec1a89f331033d52faa90917efebad9c48fef16d30394c04324e8dd9dcd9348b30c10190ec4fb97c6a35ba975f1562c4d73d958ff153a3641f502fb60ad5b26e2802b74a9936607470d820fd5cf6618685bd7d88c675ed185bfe6cf916e7919826918735f84e95517038ff9ac6d49cb5a798b3bf6b174d51ceff5639342cb6288bfcfd142d118caedbb64ec389564e191c5563895682a76f902b7345c0dea07e1523f882bacb8e857d486804da057123ae0a1dc02ddd857cf5d79b637ad27de2252c53b0c3878477e0dee16416ea4245d652a5dc231b8225441764f40c82fd66d34aadbf8b442a04f1ff1c52041043c4ccaf266969dde9a905907970263b1026440a4d3538f6ccf6b5f4a84098266a9dba4f01b23cf3c5ad00e88bbd2ff90c9d679090e854e3bd8e28e98f3ca7bdc972b7aa477c242aa3753b16896e8a16bf55048336adc31c3f849799b8b15aef01d6595992a147e22596794c044a781f7651c01faabd3bb2644d5710ec2c1caba620e324\n\nInput: 2f1e14aa04ca1258a1196ec625faa4459260315e38c3882a574b188bf9f5309ddfb90e5a5825d539c22c8507de8b0baeb93d47b7ab45740e4299fd775e3035dfac8cfb91cbdf19e35f460011e9d317641140ead2c33c94e052eeb449781d16a4f088eb358ac98f7afb8e7f82815557b26f34a2db6de558e2b83d3c9afef99f67ddbe195a77b9176d571ad9bc3e39ec318cc5e81c302ba3924278aab8f0fc88a0ddd27b062980606ea7ec7211089e0cf0607904f78e0f5f196a2a86f21c03c58106716cb3d0e52ceb4caacfbeb5b9cfc28a1aec2165680dfb9b5d65bbc539f7f71f34fdcb915e37d9e8c350bf9f210a78d137084e088604411e37ea03185241a40681a62a9ad6efc5810768dbac7ef784502805c20a2b95854ca10675a94a059796dddcf9f4ca5307\nSHA3-256: c908f1db42869889f717fd076c41b7ef56407e1440ef1330b0f777b60ff1e82c\nSHA3-512: 17e8aafff553b9249946e4d36d11d076d334c88336ce082ba648f099639e0bc67459116ec56aac9e723351f37e5b34fbc2b1b5d71050a777ed19bbd664c290d2\nSHAKE-128: 93eeffac6b784f9158868ec84843afbea9c173ccd788ca01b40ec634998a9971f136e6230eb55cbc54905cee83b5b38fa70909107556596ef0556d814b79a2799399d0ab32251b38a5def76d8cd5c1729532c59f51dc9d34bbd71e105ede6e5343398138c47fac478b32e23711e644ccd8dc61df74e11e788985b0ee5056e62b16d5d67f588752fb7e70bc613d31440977674865895b1658370255b259cffcf0ace81a5ebba2f180c6c67b04275bc0bb1fa8f1ec9dedecbb0e511c1bb628e2dd637916f75dcdea4c13f6afd58d3b82390ea0422250ee186c031b8ccd31cfe0e4a147745b0685cef777eb91a096c3d85b7f7fbc32e4217e932ab3969e753d60a3c39500df53ecb7a69fa41a9e67da32d26b13b467a89a9bc4c2a42834993f9956cc6201fbb226855115caee449ae6de01bd43e1ac6f06b921232af1cd6659101a1d57b3981dddc101f877a80fbdd5dd1b22996d5cde9a730401f37c878b294020f1a48d398dd92506f31caff4bca5f9a4ddf7691e6ad08ed5295129c75381ac99f8bdc9e93cc5cb1f92f6dfc95e03b7e9ed358ab12b50c3dca219f2e9c8aac80da03c67a7a857caacf5843a60dde480674efb88f1c3a1a73e086dd068594636fe4e1441e940610d4eea868aff8228e207014b18750377703a2cbe1603508233133f533cdf65456b07a328ca49e0e91f23a66191939ac037ea7264980a14436f2a\nSHAKE-256: 2cae19c70236bd522c48a9dcc88bbe4ac08e05857fd0f91600e5c559dea5e7de19ad6a13c5fe2c73de2b0957e9e8e1b1e390080513d1df15a1bb7190fdd474e0df00fc642bcc4d7c3c15f14a3b49ec5575674d252608755c318b02a86e3cbffc54d9d959b98c6f99eea492030ed84d26a485511b860d55ae8901dc80d46a836d1b2babfce8647cfa39680367320c8723a013252c0b1f394e37658e7b7069b4af225aa6c4fa6657b8144a6a38c95c8c730a76fe678b915dc5bbd15d4c60636adac39c203b49a003fe79afdc6575c37746b8f6a85904911209b154d5e5c9cd62d637b6dfa3800543c97cbfc97a3743345c40ef132073ac0462155fbc327bb78c26adda7a71ea833d111097101a5b5a215dcd6ca4d920781dfdefdbc36d458ef356cf358cb5e73532608c34dc1c620ed8d79fe304b64ff012008c838d25ab5d64aaea9387b36dc43380ae04638fa200a8a790be0d6e77ddbb9d0e973689b973aaf075a01e6694fa361a100be3885ce223d1a32f552751d8fbd0a34653f6efe16dfb033e11805fbaf7a4189abaff53741c446df67df89f03a364c73b6c843395c92d6321f18d3013b2c541bd7dbf01d8e0c0636822c916909a1f66318a723fe7283f8c6ae3076d5aaf20ed8fd24ed74a27d13e1c09144d1d3ef108638a18589c71950cdea949df2c8d2a4a2160f43017a663712c02fc4dce826f9c206050ad0f839d\n\nInput: aba2b00372a2377221221e7777fbc229c674e22eb29063fd32412718aeb535eb31b9f28c6ed3f50517fedeb107db7f6a8380e7bd825cfd518334a3d15077fa1ddb7f999c56f2d19347100533c7ede669faf2fd95a54170a4f48b5166a2ce6b0940ae96e02fddd2532c036b5ad18992a989869b41fcc298f2a9545c5a2f89673cb66ac673f8655a59bd800bd322c3da9b07a49153578d2255f0651ceb5d3ba69427e7d0eb8fe981b7708f5c15638d2c3d70d938abe6044ca85c4cc90d530912fb6d325732a30b1c875d7c4f8d8b74af7da72d351b900a26e7ebba29f36b8c039c2c6625519386a0a49a3669fc2e98f37d51069e4958c94b7b233a23af619a35fa7a3", + "227c2e17bb80b2bd36927c1a12a68d7d3665b6f6ade370a4c9a40061506d39a2039d75bf136b9d7\nSHA3-256: 80c741a26edcb20597c59bc1664d9a6c2401b152aa6e3c06d24bd94f3862c98f\nSHA3-512: ce2d2f13dfcd8e9f36c8d7ff2be33537d123f7099ce8e305f194de73e3c020bdf6d75b31aa1b607b7c9c17f18532c515eb3a53d5b58c05367dc0f706f956e967\nSHAKE-128: c8145279fd37619ea59853a4859a498465a36b5f38dab2b455ea83a7add23ed9662093d55c058d9a0a1dab4e090481f39352ba7b8c9eb422264626fe645a4b293d59694f0ef0cac28b0d0fe4f943b7265b39faf58d7dd6b00b2f2ff40cf485b5c95433fcc512e87346d0a28aa4f5be6880c6cc3996168854647fe808e510bf1b738d0b79f9580175e797be6f19a5121c079388b87505d70d7a0c9bd5dc882e18b39adcf08362c2af6f22effd560fd141bd1f1220bed3ac565beb4f3e3a4b77f354dccbe4871596c05cf2155620b4d6b034a5dd8d089b5ac59ebf8c0f2bb51ae2adb9ed5346aacad7af606e5a73efe092b910a270f9485dd6b4caeac0bad1dc405b54c94b5dd94f0cc5f3bf1258cf0c46e5c92ddf672871da94638b18a4641f45a249c49da32fe8c2514e14c7732e0f5c685878e9ee0a5d5fc9be848fe09ea85fffd54d97562846fe79502920da5d6f85bb94e647cd81f70c00d26c6b2184367a9d58a475c4771739a645b816bc6770008b4c4776abafd05ca1de95a6e1a2ddd2a11a7ede8fbf2ef900db2329de8c741c2372201a538fb7f84fbd9b21436247eb736895a75fc7adceb955f471fb8b697703cecf5b78dc28e2d0a364e6d4f680d7fb8726349e207ca8a5b3e8376156a92406611f941cf4b55b89630c666a36ec0c463dc5e1225eff8b1ab847044e148130caf98034839dc24f5b8b838f52b3a261\nSHAKE-256: 0c04096ead8e3f6584b575e7c31791fa539667a0501860d4db2e5b55f1dc068b2e1142e3f411491878e69672ba30f5c84f2a105245ef37e4744887d9e4cb20a7501da7758816bd126746e4547983cb6a61680cbb8fefc65349b55ffbf15ee50b213ab8863564505bd7edf0acffd425351973214b749b4ea87379d96560fee85b332aaef3a10fbb638495a29ff47b64f439137e3c1f66b75a5ae36d6d0f119d0b762e257977407b28472d9a9e98d4f243f2d2e4765b7b3ea32953e282716c115b81293d26589cea0408be53b73574c6140fc5be1be24490a7250af07d0713cc34ad531e619a42fc27f863d5fb34878ea892e3299b3ab66b8005a814afbfd288198cc5539397288abe18f7683c8f4a46b4fd5f8f5f51c77a18c13c1e66b55b97d52a1c708dce66d3001e720d9004d7b675ebd1d02de3f787f331847ccce0b4d3c13adc14d091e63174d95578b4d3436c94cb325014cf87b7e38cc7b1ce9180a621a865b1960e2e9333a747df0899985cec144ff692ccdb7ae91996451906d5f6d44bb6dd05ea2d348a8c8aaf8dd43069b5a4d6933dc4b1edfaa1aff849c3278060d6795a299cb9cebc413bb4f161700596f856b0f60b9f9abe31be4898680729fb8e848c60e81c9f66fa9006a42e02a8b282998f6344c0d9ad01405c7eac9956cfe2618c0b16db9a44261d391fa69b76377c48a1f324f289939064ce29294445ae\n\nInput: 21bfe9a3283cd9488467a326919a01b8e49317883c418493757bc2eda84dab6ad706f277b34cec155822952ede0f72eac7ff96f51113d24b1992356809bb5d1fec918e3497348476d2eb48334a3e0ee82de3d8b3804fc48a107c2fe02c2ac42a689717a03004f2702c1a1db7e864dec1e1e1bb653a5358606d3f03f5411a3757a0cd5f70c98d16b95ccf0f239cc664206002270a0863db71ae33959b9bf139e280cab2752369d13094cdd7912d00060ee95b7595fcc1360da8d3a2fb9552eaafdf9b15419c9bf59a7dd52dc7a4aa573eb7848123eb6ffe63cfe482896882e284882ddac1d3552319a7f22164bf760b2995dce5baede14014e6217124572fa7c6c370c086df34c5c828d4915b8cb9c19da85b6486ba90b510137ec818621699399ae177f7f37f6b310753\nSHA3-256: 8d5243be42532d5c5d97cbee1159e4a1f68e1d1761841ccdb7685038f123c8d1\nSHA3-512: 95104c36f15ba132fa0210f2ab405385fc9bb2965e98cd572cdceba168a8eb11b5927c5e8bdda2bf295b63eeaddd4185137aad6cc74f28552313e211b05c77ff\nSHAKE-128: 6b97ce384af6302990cff8844b93204a49b4919276161bef3824ff1483d2b195b1bc5187580e2ddf261c5f018ee7c47ba9ea547143e07cb40dc1cc05a24a3bf58b44a7d84a66eb4c6f250a65760d11ad302aaccb1f17ec7240ccf3ba14a8af133bf4b81654701ba44fd8b3103153cce4807ef31fc72b8d3a0b0cb31ce1ad9e6cf997120b1ff1425cc1430c633d135bf1dffbb0189c01417745014ee5d3a38840015bf9421edc70a22086ce4388e62d439994b101585bcd4371ccbd25caecde59ca884bb7fd3a1b860b712b0ea69dcd52ef5be119062afd34e54567ae3251a5df66eece67d641babd3adf4f3b60b65ae364e79e21f0f1f99674729cc15870fba39c91f555f587b99cd6a80ab44983693db813b16724ba77a13e2f12e112e5a817da90b81299918bc0c6ad2b93f0f57e1aba7552780591a475011be85b07952e4ba397b2bc576e3ee6869fc157d63fdc789e21760a93777524e8862adab611fb8ce1587a77f223e206e6d1e576789b33171c6ad174ac3bfcfec29acdd24cd99396b6e59585c984720dd935585ce4e688aaf165873b31fc0a53c8a9633245f6c2b4e57a98106e1a28266ddb89533071562d16a30befaccb98628a63b4ca836a9f8826dd792eaad40a4173ae95b0edee779a1989577fa2fea219c2efe6d4fdd53ff707fd436350a50d7dcf2bc7eb64e045255a9cea9cf2fb9c1170ff4bf21a41dfaa\nSHAKE-256: d2b0764085e191b9d61201d8f4bf6626df7da70d3b8de99094eecf693b7f12a931f14ced221a5fa33d193c9692e460cbf7013e46279f84ca28b0ccba8c96fdc823567776743129cb8ae7abb62228adcce85149b16a9ed672734496fbce6c3c8c373d29832e063e72eeebcfe1fb6d06fff079212770ff00661d928965f0d1fd50b681e418dc59747365a8fb6143d90202d4732205189d5520079bb5ac3d87629043382df4bdee6ad21b40d4306a986d78860cbf5490f90ee8522cb83352d9335bb6151dbe8dae17bf42545795146e9844dc9309d08d069e84b6cf516a4c5680980289f07ed5fe17bf3514ac729845e754e3faad21d84d876505594b5fa36e551db52b0f6e92f4843dbdb2ee25f6e939454db595bc2a227dc7a16101b962cbeb3c3e05ae576d1bb63f19da02beec972657f6a04d5f0bf44161481a4b72ae7b1f5da588172364cae626403fe31588a0d8406c06b963529e81738b34438cc069e35a2ec79e34262bcdc2355c421cee11cd7c444170fe67bc31a3d45b08e54521c2d74a48edcfb863884eea6aa1454e30949d5b1bcfe95b9b118cab25dc89c893211507f214e3e460c53e35be5a0824289ad9133be685300f23ac1f6ef14c549b6f03f4ca37d27c7e9e502c11be9bf16c0d16f9d3393def71aa3914e6ec83caf7b8adfba3b0ce06ae1b1ec35e187464ed44e7a85136fe16c5ff24dba33685c3a5ebb3\n\nInput: c48c06708042f2931962dd35deccacd30652474dd382839e3d464b5f220a38c3e742f6867876f32f73b97ebc812876f55cf0fc85d778705647ffefba3aa0fe02c1788b5de8db887ddab1e071c24fabfd5a9fbd5883ab856b1f9922497e7c8cf6cd5780d2a68b1c6bccb9335cf5467f6a1480f5beda6cbd022f0f41030f7dd55aa45a461be66090270429d94471e9a9db418bd6b8fdc05b2125c7ca3119ebd6394692df1a1ea66bb4b699d7e75cc85186b11689c685d078b5d00af83531840d3b42b59e8a38e044e9cc02c89fcd6fc5f292c761a83bd6d9765911b89f5429422aea40c25b108e12d599ad0e7243f5145c6488c5c51ef1bb899aa9e6efa8bd0ff06b88800fb1d74d0bb09437659e0681f95f9ba3393be81464ae3296d68efc31c638ac2ce00621544158a041\nSHA3-256: c635158da5d13129282e21f73e61d24ab97ad8216b4565a9c8983b757ae4a143\nSHA3-512: 15c317f655521e98a2ef97b1a8c3ad298dcc754f1e8d0a4f00e034672df32733acdbf32dc43607f685738feadbc6263e6ec1b404d50f9f0281a00d1aac090467\nSHAKE-128: e2f2f86c0009a79595f6e7727f9692153b4335c9afc23ac915ca1b4ca57072a6cbf955112adc1a38d73013b969663d1067eefdc5f6b58e96e77593f05d0ebd31849afb330366682014df3e7085569b93eac45a12112d8839073c59a0eabafd161ca1f0d2cdeb61255e2d991026a7c241d57b5ac63c6b335f67cbb6de15e8112ff763e5aa76d65cc5866d693e918d134c53f94a7713f5f0cf997726595db4fac6a74c20d8ec69e6ac45a929af7fc924e607bb86a9d39e69337b7b763fecb6bb897b888f6aad033f4cca246bd559e83820efbad12354ceedc6c2967aa82cf0adb888eb8258801395640c0463069a261b8db9a68b0cbe9c92e8df9eea0541cfb390c1573a953f07d49e15e2c99185a70500a670ad809443ffa76a079d5d8914e2bd7229aa90f08af87231d446874bccde508c656b2c2c10f52d616c876f5a9419d3840546bc2189cedba321fcd402da64d897c14e1c6c1518e0b0d720175fd31546632629d042d2b05ba8a2d2abe71592ad8ec8f82f9f9c35518a4b84ac8a68e2e54c4605d01b4fb476cca7cb852f5e84f9d3b9b2c7fb164ebc01013c815ec40633097d41dedf30da5a147e622800cad61fa708d02f546d0415e981ccd4b921d64f7bc679fa8cdb9fe5f9acb5d36ca26c232df5a6a2cab2ce9e8edf32520bd798df8e7db350b732815c7eee1019ae29b5da4d2e28b2eb10b7b9a685548f46728095\nSHAKE-256: 41e93039a891da92b19e8578425ca7e94b95077c13a788b6bcaa6e8b39f8c48ac7b96a430bfa67fec7d8b605575dc85ea6b56e942fa86f03fcb0f097123a2fed6edce65f8f57b40ef2a4f77c194c8dd55c407962b21367c86a1aa402d8011df5b568ae0a5f7e9440a6bc721cd04b6cb18a1088c659d10119973915b7fbf1ee1796ed2130207d36330f0df7d5f4da0d6a1440b6468e09acf1a139d10a6bbc40984461f42e6f8c4549133e33930308cd5d4c05cfafa8ff1739d56034c48d36d1b4b37fb7a767e95d97161b762e2a72802016e268ea9fad70133505465d6e573732e4e767696b57b32c8bc0fae5527032aa6110502f5b648006dab9440367426514e307d694b3d93ce7ccd739a5bb9f99effcbc8878956873f3dc841e4e381dcfd433c2e7b93fd7fb534782eff9d58f14a1ab8dd3f5a95f265cd457241f0b99e4c5203917ad7b9b3d9ab914e91daf4a7b6150e1633c4d7a4abe84e8892d5c4013604314429e4388ef19607bc326f25e81547d8844b928e4afba64c1ed9f744e9230db1ade44b111fe1b4ce05a05586aa667f7b4d94462e1dc9373dfcd3f55729bbd5b8cda9c01c0f4d3fb8efb7ea5dd6269e2ffd89ffc46ab001c0cd157481ffe0fbc64de8c724c0bbc4ae6dfe84b53034a00000a03988bdc982a08b6054daa9f3b72d8b283545fb12ec98e0ac71dd64126d2e668ce3ca1c896a490aeab5b70b943\n\nInput: 0c99f027e947bd1408fe151f72951f2136", + "fddeefae90351b5874c4e5aafde8f5f458b4d042466f2133548fd647e631e623473f851d72b0afdb0b99aba93bc9fcdcecb907dda4cb5fae6b7c06fda702a83b54bde81062f650a626af9b5284846a977e838c472968c5e61fc0f0f49bffcede0743edb2f9cd026a04235d956530061029e97a7fa6108f0b58df5a803eb0f80c314767399a0fd66dbe531e220b2dce94088a973fe7c3c3cc522f640f5210954db192ab61f0af2a7918f66264bbaf74eb853ade1778b33b2ba975997c54463286332baf2cc162aace8d505c42dbab48e24b5a36d41835c3f20328bf0a1dc9beb08d710d0bacbc686ed979f12ce8a1b77edbd84311f07c8064488ec1b1e515bffc14427b62a2d97d1b99a8fd9f3f60ccecf85057000cc0bcd42c29ba\nSHA3-256: f0e795d921e549dcfe208b8996a0acdfc73a9c6e4cf9f1a0702f2735b1f45faf\nSHA3-512: 4bd4c0c3981741e016b6464a3d13b42a536124a6c6d74aac0f3e541cc7855f922c53e4f79f24a0b0cef31b7cfd39aae5cdcbbc87bb0e85ed4e7ccf77aaff5e02\nSHAKE-128: 255ab1fd554fc789595cdf9f95e4cd9369adc16791ab706ed626542206d6c7adb11eeba24a9cf32976d21bf99cc0c73f03fb7aea369de8e22095df32af9933ad8f3874375ba2d6a0eb11d7facdda7baca3886bfedb77589e4b9a20741da2d7979b29c494a3b8f790f8b47d4629b6643ad5cee0ba50856878327ab9514e7d367a649716081984e444de6bb10165f8b64d83101a1eca55ea012c6e29fb98c63cf6415e1bca81e32d185388b44e56ef2f302489f41d962889ddbf9f21f1a2b4c0e3f3d4c4205804563da057e4e03ada500de57f9775927f296622e94eb00756eab89676f9b960ebac35f14d92552eff3ecef853a620824515e436a6c366da3c7e6d7b6fbff9d7e5932c0433dc129506422f944fb9a52398671e8f432a892243927fffc6067fa9eee3c087e47a2360b1d19744974cda866880fbc4091ae6f3172e4b34f143f717e96d8232fab89ec65b5f6d4cdaffd814bbe19b669174790a1c33f2f1141255424bfaf1867546f9e929b65d4ae533bd44acd62be8147cc937eb2ea0321058a91fd83706f658b17746628058346204a94d10f9d63da2188defd65bbdbd3448d53587313cc0058f7130f2088f77da8f25a740cb3bf6d83a9f4fe6b6693fc9672b626eb3f9f8ec6a65d32cfd6a8a9d0298a2e6b8e76c566d8d4dbf83f43fed469c9b746f759ff99167c9acf439a908c27f73d0ee38b91dc579e81100c6\nSHAKE-256: 8f1f8b3e9fbca86320b40f2d5dc5f91cf5b3c0f08cae8817a0e5eee3c2399cf86ba7da59ab286ed5be296beb8dc23a215656b812dbb35277ae758f7297541b4225684d61c27a623eed9098f530c4a4b3f932de4c7d6805f1f96dbb91bc8b51ca8f7795b26afaae10b38e15f45ac32b13d0c4115996f3e63ac4a5bc8406323c407858f2b38bfb69a005a34664be565c0065deda78b2b860c6b5e4755b5d7cbde7c5752c861b66e8d7c11f82bbac2812e81708f08e6f8ace16ce23723ff0f3ad27802973dad283141c52e54a174d2c87874d9ab15a43ba8a9e67c1a5417426fc0f94dacdc272650a746228d69e0fb49b29f33e69b775bdacfe6d762d9609a373bac4adc95c538d1048d7ab753e876ebfaf94979cc50221c4fdd33e045b98ee4dd7eabde4c03a7a59ff5f848e60e1fa3ed5f01b9d6adda34e01cab2db45444d8f8200d40955ab883e0cfd1e7c36895a285f00b29fc3818de076198f707a45d7f820a0ddddc986d461f24c8720c926542c4b34d32dfe224693d5b99ff5bdb5365c79a84dc2035fc00ceb34fe8888fbc4cd659c23bf1a6803d4c4c0406d1a0039b9a57bf209a5504986eb0a705fa4ac90e827079711246b598e87c846afd9634d2958dc6384ab1e7b58c356569197a8cb29bc992f0925c7932ebaafe2e0badd8d361de607068929bf029abc650f0c114fa402183bdaa5a756b96552fbd978491e5a07\n\nInput: d81404135b4e3d22f64935ae6670f51508f8f747290ce379436cd3e2921ae0be598dc8630d418eb2cf0210e5f763a31975d9c91664bae9843b6994f4b12a59b2dc0ef279ad23b5358e8429a3e53b9b4775913758c5068e27c67724528f44b818e37dadd3d4db39aa5c6494156bee3f5936a631a4c275f7e51c831ddc6f22367d530a6fa6db7d930634627326f825cef0a587675b31a31b5f3cbd72a0bad7c274d01d216ada8aa7441afa1fc5f43e6e9c5fcac25fbaaa33002188ae22a571b8a716f5f4443b9d620168a3f32cbd0190b9113a98d87df5fe85544b9b96dba4ea7a3184eed9c188178ed4434b92c64bec103539632fc0d02654c82a605d74da9892a5e1c74ea37b39ef4ecbc0abb5109f5a072e3deb515cbc2a22d85ca29327ce694f2d2eb640b746de04b1159684\nSHA3-256: 68399793d9d001f947cb2ed112e86f21e6783db0b20f5270334d7a958c309f89\nSHA3-512: 5ef7258f80f3cc8c204f28d17e943b724213332ba5178c9fa3eb25fa837ee07488d8d4be55f108420ceb4987337a608f9f0a31095d2f6680b35349c0916c9895\nSHAKE-128: 4e9f4b8cacdb5111718b75d4cbab35c21e98080d6d13e82cbacfb27860463e2f82ec59e8b603963e1b47ae2ecace8e568c6f5d296c431addef9f544aaf6eec4842ba1a2a1df55775a842026d15aedca1cc0de299a42de8182ece32846782fcc48b88ea341b4620dfa1677749dedb543c950c1ef64ef014feec9dad24d142bb5aee88884833bd28b70490ae005427f107f077a6a1225888bd402daaaa0d292f3ab44b11df93991b0754188fc0982602b3c31b459baf1c7d7fe04c9a692953668da98529c2a2a0b3b42c1859d8191aec4a9ec35933ccfea44212676d732b43ea032233fb0349bc1efe16d84aab8e9f448c6cb4398fe0d6678b129c6d5a042698dcb1de9711e262f0042927fae0ca04192a28a887376162ca65d45a9d7bdbb5be0665892ef0285836fefbcee3b0eefd90ee505b70382a3334189a6c56c0caa0585273c777cc11a5233652c5d3c60a6d01672080c07b97d560e72a09db8840f9164bd5f834315bd08f173e4e757cbbb05cb7c5d27149c3b3e2fe7fb7ae4c9081d704c6cd7daaf176baacca5aea448cc8d3ddb4077bd4a7588918f9c4b7e56c7d6d3a1dde34583d23250bdb8c953ed4100a95c7933784d8d6bdc65322e5a1aa99bbb87b02a75c275467d1b5053831ec252ee2c43261df8fdaecfe6441ffdb2d251936f7e83f8166d6fb635a9afbd2ecb9cf04bc8960a1077f972d0973f157331f445d\nSHAKE-256: cceda327ba6ccb72d91d870ac94b0cfdf7ec88bf92acaea18d4a7376994b1617799eed29a6f52828d3e22fe0f40b097f9a56c06750f173e98491f83dab1ee4814d13286541ddbdfbdf2820fb0b56e859db0d2a99673c7e9528c96f5a03b671b4e23e6579b23c5ea5137f69fdaf74ece3d5b22174bf27f2f74679d473327da25fc25acea68ded49d1550527fa85448dbb32b4254bcaf5e8fd0363092ab1219ff42bcbcc3a1904fa2014252a2966dd029eaa16154597b69d56aec09afba11b092ed12b5cc5200e849cb056d23fc4753dab2aed05dd61eb681631a89337329f0a7a4cd7beb7f54f254e67c1f8fe91099d20020e86e49aa6c11574b175679fd978b23d776b85b3ec58b403862ed11c5350db58df924306a07b6477c6b395c02889752a185f8f215b6e8823e012af422caa0d31d92cf55545743c2321c5f0311877d1cacbc840941ee8af5d149fcb0e0433dbda6408726c3b58d1adf38990f1daf104899bd6c286ea3227dfac1a5bdcf308ea8a7149664273dc21cfb3d03c9ba595e14dfda33443a09e7f10fe57ddaf26cc3eceb2264aad815b294484def86b5de126a0beda10811e29284a93810a2bd617216e7f1db9546cfcee280c555d208520ff93fd37052dbe586f89bd2367ecf4795af027a3a3f79605fa62822de1eb71257b209e7e274623542e84b5962fb7bdf2b24a9df91fdfb928ac3cffa4ff82cefda6\n\nInput: 56e1170b5215235cc8d04a0f9dc7a7ccb8ebeeacbf57fde85d3e48e4b27d8f8875d78378bfc4090e8ef412cd7ba5726c2036232b68808b890f2a5426c405d95530fdb7e48323a0bd38a81f2b311929158014ce84defcece71adf7f7a1b88f90cd69db82d32c7ce8a2c3fddd3647077c39b9c772f771b6992ed430196c840a4f0a3bb15382bb7e7bf852fc0ce79a0d3faeb1c6b6b4a872036104eef06baa13dfc19e75c575292d56a924f55b664ef2845d1422bc3b966b106bf60d6d3cc2e08ef548d838392451e9a34944e22af61d0a1056c37afd5357ebf6137a40142ac76e00dd8b4a31812ba559524c68770808dccb477dad7d0a7e84080d85b4d991b310e67313b6c948670e36b17a3176be2b7c93d0eac6f0407f10d0ff1906bd7caae57df621b7e9bc95a8e3fade6213e8a\nSHA3-256: a48b35ccc7427b7a0da7c2c7b4e255095ca57f0fa5828b42f8e272e6d3c746ce\nSHA3-512: 62bb63f7905f2555799a06a5bff681e31e69b2eab72466ded7a15fb453a64d324e8936e348c81e4c5ebf60ca8862241b60cbc5a251196dfe1e26c7e21eef2928\nSHAKE-128: 1b7a20ea2a6f95cc95de593fbd99a8ca79aadb5908b50e0014b1d2faaefcd9a6a4ecbcfc1109542719a28c4ab2abd4eb88b7bc700d592dfb736afb75a115d023351321c89bcd834ac24acf6d8b2c02f5204b168851d919308ea080574493e432a914df9269d2e2bd58ab515fb6cadee5482d7b5910bc3026541c35d216a8e8956d73dcdefc5199d141812d21f206b323f9ed602346557d4a092375c7d614668d67c61c3a15451bb814e48bc555dceeb107fdeb488cfcb4394878fb0b88ff5e0f408529125382f3de1879a3465f7f0e3252c1ce58a1b4ebb85f35b95dc0f3470c855403471c789027bc6c23f371d7a53d38f1fed2af644af7399add6d3ca6ab66a13d18028fd52fb90afbe3bfdf08f4aca16620740b60516020c5ab8a17a7ba1b6f267b41610f43ab5941a3ec94f74ebab67ab3b0f5158b7517ae7fffd30395b0fe3a41083f0711be3688859a8340bbe596144688aee4ac4f636050df93bc9b68934c6cd0b8a9b011605d53135d22e27dd9699d9b02df1578845c0e217a5322182acc3014fca4002399c854c5ddf50daa7548dc3fc65bcb96b9e09e402b97e1253792894bd8edab1345bbfc348682f6566059a9fff5464e88b28c0ceed1d5eaadcf55fb4359523ffc136b71148fde7a0b159f3bd4ca3d0fc4833ae3fae55c9e061f07639ee5eb13da7ee2e66c05eb1ed508c8faf4703a7b51747102a3efb6bb91\nSHAKE-256: a0e67a267d4b46f495525b7d1aeb4393259e7b7534d065083aea9aa5feba6874947b25a5fb19db5d398eb571c90e9d0efe900df181c3fc7ab9967cb73cac88f8d46126f9862c713fbab358cff4a84a7833a9bced274675bd89faaeb3660951a7812b80c24a65d4e2536a5e8bb24b99d45f458c04e3fb0203d148ffe03ee5a340dc358dedd0bbff09c4d14fafff489698b1cc0178ba74e1b8028a80a9cd10c1086bebeaad3bbd98dc885e440629640d3eca48db39c6af2064ca8ecb7a6d52f5e3c28e9ac9237658181a5d62954bbdc0325abc9337a502591d66b46368ca206aaa5a21bf1bdedf5dac276a1ae7f21d02f79a892e0ec3d0e249ed43b77a68ddb04fa14b67ed87e144bfcd6e182a7adbaceb77d7a12e352bc65370f1f320", + "ae537d8f14db27901667d9cb28e58a96e7d73b2a939c01c1f888e3cb9ed4602dcd2ca9039301452f4543817dd7666a0ac8a0c7c4c082ef8fbdd5589bf923e8ef54007908242478b173b40277fcc6f3f8c9af2408426c6fe561b6d78568077fe3e39a7163b39295766081aaa8dc1fca8438a20fe2349c8d5a26449d3f7cff99665802a54bb0c8a34d6cf66fb335f5f92c392e8178626c9953c5f04fd1d241b35569423bba91e97c11f245649f71eb478a0fcc551bbfd6f3317912a8aaa26a6cf09a11c72ffa287745faf645ff268055bcb6569214759408f280aea774256b52d9a93b4406\n\nInput: df11694153ce690b03478f30f41c6fef1346785b807762203650674d50163edf2b14d7663fa58b0e309f63a34acda80d640a6dd553364c6695c1874709819c3d468739e14e287dbd54a8c0c7b0190a044bda36bf215ad11e22e4fffa8e469cfd8e5378b5924f61dddfdd70167ec2bb8ed88437965f0c40a65d3cc4e21ec387226b085c123d54f29dc8146ae1a121d4d66812de29910e3c72f31d28109385ba2c9fa0715f686e856cccbecb6e7bf7fe7a133e517f59ce613113e79748f8fc87d9bc793dd16e5c7198e3ab70dffa143b3413b9a8dc79abd44c5d96a59b1b7199a97f0b8d45d6f32101e0a8c2fdb6bc2731ad1a482e48e5f61275770083776b3d70f449fbb12c8a0bba43a243972c9b0dae93e4f7d9b1dfd0edc9a687dad656edf579a84e5674ab4b3813f7bdc8f5e791\nSHA3-256: e0badee6b1666f94de06ed4b5b480f14bf1a9d68136655c86a657a9cf7e7fa51\nSHA3-512: 50087056808d631eaac97401eee467dcfba5faa819b988b41a40e3f6b440f1d5c67a3e9159deeef676dc5c110a035e96dd531b4951b69964ee71cd35c82fb6a1\nSHAKE-128: 003e1cf09cdadd457887a56eb2138cfb8475b3307e1c7b494da2298daf94722e33e3ffba04a3d621ff4817d9cc6adc5229eaf9a7a9a57bb39cf554171348f779ef53d4e8662dd8a9e3ba77593ae19d5147120d5c5f559fa1ffc1a2ea4cf4bc91f5fc579d8b3cbd181221f4d03549021c9a68f8c9a912ee09ba2cea394bd050d971ceee8bf77586d45ddab5eb3db35dd09d3f8fe8032826d53fb264c946f2eed8aebd670e6abe76abd8bcfb17c4b8554179f16bae1208bb387fbdd6d3783f5c76019ae43fb3693071625b328a2c055cfd6d72e2be532a73272c57263154e5cdde2657acfc48cfd2f0376a69402ed4555fc7a2a51fa2e8e1a7977caf05590ced902fe4946bf2156d21f00ddbda1c356ff57f9fcda5f06db28d8868abdf30a98709a85c9d0ff4792ec2cd88e4d19d99a78966d46222756247227fdb7b1cf9b8e3a855522956133dc5bc5321d1669b82dc53634e8c61056848a641941a861bf2f6bdfcf574e2bdd888be4cff5a8f42038bf763528e0db130b71820da35be1447975ee0e1bbf4f62ffc395254b48fbc97ce30f6205650b630014fe68f68bc9a5c2732db51055bba608e9c54fa6e7b3c5b0e6ca54a53c78c856bcacdb43ffd60edd40114195765c9a98dc61b13ab2dbf27322dcd5489b7b2138bea34de2f7635991c113f015413fdc9082198e944a7467c66d0fd191c2187f661edded4e836ddb7baf8\nSHAKE-256: 0861b8e77f6e1877e336374694d35f81ebf2382ce959ba6c59d0f2ce6a19379bac5e4f0db97496c2d6176a7644b6b2bc12d651f842f7d9f46d8fe89d5d18c21750aa70d86907f1df85907a2161839c16f7bfb2ad87cba4b46ea7e393fa405a663fe0157ebb43e6fe06602190f1f1d0750539c9e661dd6fc413f254b0de8fc64176206a532da402578d8c1ff1a4b0a31e58def3d2920ef8e4069e28597e175416a965545f402954247b7858fbfaacc3ec994c670e21d1e2b8d9c3eaa4d08e420d7ad975da66ce698aee4437073f93818d95b92b8fec0dabcd8489a63fecc556cbabda2601369703dc4a8e3095aa0ddee0bf13325e38dd0c9df2932ed86262a7a1ecdd374937dc3b2a606a8a97b83b12967ac7737f24fd9ea4b10917be4eef337b4235fbe4c92ab069931c0a0993bb7ad0d9da23c657bf9eb6a4621646e028085545d5a93561cd7f33b65752f1e50f7ec5dacf896061657ffaf525fc441340e60c7ecc6bd593e95342fb8d5eba6db314780bf44f724df877e0bafbda6207d9986758ae96e8a63375a5812aae28c10fc75a4956600f3bcd8a1a3c3cb89cb80da9ac2a878e531741d217d4a1eb7466c200a6f9a5ef98142a0a6a6d81d76376f7a48bf36e8693bb12648be58e9c31081c86a929be6597d001f4ece5c5b8ceb0e6dadc58e46a06d0edae4175f3ab07a62030fa3b1c2ffff51213d424c2e4db59c4a07b\n\nInput: f37516016bb9b67587f6518b2e19d04ca307170111b9744ef895b208c62aa576b86a40e7933f3f1c0a8abd79074802d9bb0589db4dad5997220d3cd712d16c6ecade2d72fdfc77bfdf6bf402ffb9642db1ef17a5d70dbaa4b874c170a256fa23f298257bf63a2b39b4a523bbdb5adca54bc8ceb3a1d45bc61ac9fc71b0790d6db5c4eb952fb25fe8fb464011df75698cd22fb644058807a9cb1d43eaa57153b23507c94b1c380955eae106e56d365efdb9a67e5af132a7662a4c947cad2a41e0e32fd701d660b7246d972fe48e96db0f4ca686c3366134f5445c31c3206e2a4a2a9db2a939d775c08bef8238f93cf17d787a483273b05e2eb7dbc7d1a32aff8c8b1582ae91cab2a5fbff6ab61626b067471919fa94ef678329cc734c76450b2bb1cd25782da077e2e49d7334aede1204\nSHA3-256: ed116a22632a8b54a6f6667811d5467f5f902007861c7961b00517afe2aef3e2\nSHA3-512: be77b550f7c1bef8a8a0833d0c5516d726cf7ba24aec15c9000e8fbdae807487070e1c46659ada850e70230b09ecb9304848ad091e12b996da839d66706912fa\nSHAKE-128: 40fa9a1ce9f50c3f97300c73c30ccef4349cc73800b9bb307d78a85da4cc9cf072d9d3bcfea0f36bd5a67d3ba408344b49a23d33c05e06fae1aadaa16401a3a2c04eea1551f84a8ecf9af84356629ae12ac0644468f3d516921eadc30ed9435371609945c313bce96997f07c34b9adfa77e4cd9daa7b8e5204878468371c2aa32dc193431d2916f81379361dce1164ece6ff222aceb48c20738ca732ca46670191ff614531928ec815a88e4b1b2ff3609778868d19605a0a7f02fa94c6ea5b97e17ebea252e1a83d317419cc9eb3b979415d0a627622b9c1383c997752f228d7f91e6d53f44b31ef00350d1dc3703b2e0a4964ee55963ef635df9983f3a0f9944cf564bbff83ca8454d917a1e7e09442665f662572b4e6070f3f36cceda076a3bb8cc1ac6b6a2ac2e99eda1c04f351272d77e3b02ace7efc6ebc95e8d732cb9cf655eda636647499f0e3e7a19364da118b7294ae9aaa0e0f1c265c42f9fcdd3e6d31420dd3c3c63818c07940286f2fd007a290588ed12e68a0a5d5d280bc89feee1696727c06c3e81a87c16e42279a5df55c975b0865fb33740a2c47000d3adbfec7c98077594d5d1ce5f5ecf5f57d27e568dbd7d5ff96632b4b8a7e708fe2506fbbd390801e39fdfd843e3f27f6acd7041ed05b3762b3d975b83cf960288bc678adca9750b4a027c10d4f6370278bcc4eeff4cfdc0d6a46abf160ff48e5ca7e\nSHAKE-256: 65afe99cf9ccc48b1cc743681aa8e693800cebe8a84e59e1427e0efe3fc383b4be164d139140e793a02f871aefa7d0e147623116cfa9e8ca7f6d13418857a31afe779ce7ec0836544789d5786a6c1781021e2a1b313c05ccbb0b75568b9c8480e69d3594e029543726351d35981725801ae82816a6bc20609cb12f6473a8d119d5f3d0149a3ff57e90ac3aa414898eb1de44ed55489d54aa93216517218305c4673cf7f66fce48108f24d83eb4b4934911cf6abfc4186a564790aec4a24788a26646cd344e3bd9ea84227162030ba5c27fba205c35fa8393e590423136536cf6d07ca31652b1b3d25be100246f1e41d1ea2ad28c6ed7b2b040df31033a819aec2f507e242ddf9e695ea3f6d1f64fc7c4bd6841fced22d512f6123c5224b4017c4ffd250f483371eaea7b4f6d39e30948007539697284a5b6e8d0e384115a985c9c75f178e34f72dc328b93df95471dfb7ff7704a52aff53e07b9fe106a25d1b807c21af9aa0f29a2fb6ecfbb87c4bea000b34d972aa8be60c7af6a9dfaf73e9fead417df0fdeadfee97fb297842710485f6ec05d663fd5063e3eb47f041a0db0166e6993b4082edf94dcc86c470ab7e4628629bda799c13c4b691b7673a6a6aab49c4a583d59917cf6a01a605a6390af53fbeb8ff2a1ca1348ab2c788b099273ca36717385cb8f834f3db669ee20677cba90b118d818af6e9a8b39732566b40e\n\nInput: 81becbda93498502a81d61d6a92d028b8cdb474d679565581a3bfe8e8f2693739a1312d03edaacfc565a97376c807cc94d1fd010859a197a942cfc58168e1327120579ded3cc24fe84778fbc7680e3956a5f1745533e2129cf5fafe4a5c6355c752ba0948b329150e94ea99eb88069a34065cb02e299f307684cd072945347104fe4a856296dba9cfaf18d64dc1baf907d792d1efc1a58ae08251e418f1d9d74f3f5c9db0455fa888eb5675ee7596a611065bb779c8eabe6dd27947f4bb8275289632295ec54cac1f906581b9fbdc98e8d283a4ad96e7f514cc0e2e2c9aed4d737759e02c633acc2e18240e3d958eb37dafa959b0f79a4f1f8881f72e7655ca226c46c962eb905d33edd5d79120525a6e1fb0b0870c8d90a73a6c1831c010b277ef5ba56e8f72a87d5685ae150eab893c9\nSHA3-256: 5659d1214b4a59ec8a18495848d78d0b80da4e05da29436f08a87ab7fad67c72\nSHA3-512: 18ff6ef11161cf1ec6c7d787828fb8935476955b1b484534884bdfc3fa80093b57736f1814c2f7b9a0e287367e1ecc3692a55f2dbf9d85461e6393ca53790231\nSHAKE-128: 798ab31d47271a183bf8cbcf098959d5a2112bdef2ae2aa335f85d8b771cdb81851d9ea66fb7a0895efa095155ac416b2708944291e0bda2a3c520285072ad10984c17f471f5d2fb740f7d35c51f9746140e6920b4abc43653cdc48150dc56f1ae5ce3871bd241bde4d51a74e8e26439b9590901009f908bafdc21d743fbed9bb804a95d17d8991e1c67e5aa5b1f766e9dfad1469777327145c63f5b83d79a784ca399d7924db0f602b98d4fde28d68e57b0d566c2252083c99f39d86a0497f7ab2537bb6c4f040c551a127590fe4f76ca46041273e90179eaa589c49792ee3b7d83ba2c812ffad719faeda527288f159c813c7bd398821c04c959830c8141b0ec50090f3a743ec273d47edbcda9dfab0fbc0716c6a02bd809128fc6ec3156d7b90fc312f814778a524a91c65360a998cc62bbe7cbba984cbc027dbf145938cda6124f090d51e1e907d7ef0251b069c0e4e93d47c7f1022274e3aa46f10bdc35ff4221f4e8ca111f11e5b2376ef2463e6ac28c19ec3b8c0a7c2b7b61a60cf2475c9222e02fa1b33ec7ba674b3a4820eb1d6be05e09da2a7ef80337492f45f01048153dea63c36e236488bf0177f9f776b240c5a98770e1e7c8439c16644daf530f0609a16d9d0e4ded59d6a74086ce45346bd9f6a8f340fe3961472d09019bdd8d8e800f2a4e18a93c8b9485ac35e7de3af82a25b608c3c7280b336e1ae0f739\nSHAKE-256: 2a58e4ed7c82856574cdce494e183b943a2a73bdfb6d54d3fda", + "dd7bd9791cdb24c5e49395545c3f0712c1320894753ca739a1edf2a810bb8f0efff45218537b064afbb2fe269cd6138ecf2b467547cf0f7a7d654007bc7019f43f11633e979f1391e1e0240b6baac485e49135ffe8c97da60c0f349d2021b3f69f0f9e8d12fbf5d0b733d89ddf09102c93635da5660ed705f6e24ec49591c5fa5c9c91d0c2f22c594f1e292d263fe76676a4778c803a15c7902b5984cab8ece4f6f088cce45056c283c60751c34416a58d9bdb33c5350290d6fb325b0a276aaa7400a6c7f60e6bd6d81a4bb9824ec1417798961508d2201daa8139640d641b8103401e403f4e04f3277ba64c5215c72895e93692ca9400b43c6a01da9c4940b9d30807060ea5a80fbd043675de7e977f2ec3a117a0c6e4130cd5481cfcc7d38e309dd996d0d0ea510f8bbd0ac8f10c70fcb8ba321293dc6010eba9d3b867f6578b6ca2bccef080c8d9236dd3b3d985a50f8b0b9ebf7c9c910dc407afb1f6725748e9372cea88b6358a44a483381ca71137d60fa69a05d91d701cf5e4b65cfe2cf28fbc126863cf34913c983775454601f5236162b0945b0f9725d360f68ba48f5ce1a8d9181f92c2833ea4f57171e3515b8e50f2ab558cb3b47b4f14e10dc00cc1ba3584f2c7dd2e97cb67f25530449a042b2287bbae48f74074d11104fa2b8436804a0d0ad27\n\nInput: ca4315c46acd97c37b76970d61050102e7ddb1e4f95db0c81fc9d55612a1afe71a2b036c64ad864c4550fb6b9377a7bf95165df87afed684c58ca205a2b39292b28a0838ddcb9f2385aa6c09f1e3b6bfe1f2a01178db8bcf9173faf88c47f725f0abe9e2e821c5c855bc309331bb77e4dd1065950cf25b8b80d59ae78ba07ac2edcfe8b47fce1bae3c3855c4c886fac4f4408e65053e6384ecc55ff3d596977d4d7210d08694023b6dd813f3662aaddaadb507485093801ef03af9c81325f57dbcd06e6967dd1d81502453f91021dd8e07d19eb85e25cca18ab58a3e90d4cdda237eb34fc2522c6fc6409ceb06d4fc80e9f1f73f9a5879f120ec265a4df75e9620df5d3086aab7f7917098d746bacb9c6bbf500ff5ebe8625e97253fa74ddf65a29365f760c60db718fa6df6e61125297e45\nSHA3-256: 04a8f7204bcefb506b572dd5c8538b287046e43e5066815151bb3c6e6dbcb253\nSHA3-512: ccc71224fb9dd702111fdb9dd7a593077024992650021cdfed0a4ff7e2f3ab655e94e85646a507cb3de4dfefbb013d220100cf325f33e628c33d66705d1b5537\nSHAKE-128: 989c604d033bd74c50b8261446a699799f856cfb1f6d3a936262692a822cc1d5d64bd8e510332b65f7fd4ef492fd3a21f3641a83527e8a44ad7122256a8733c01baff7e9bf34fff86458dffcc27bb3ec41fe266ef1459e98bfe7dd900838e93705c2e75d762ee58d24a21882a5b0ae4631480fc23ab203db612073fc4f30d60b949394cf9a02eee44a57fefe9733b5ff103b280862300e824e532edbe53088612152412d982e0625a33d4f5bcf34ed45d6f92ba489e73f06a684c4bc2016a6e2cf591a18f9c0464140ada6efb5d70ddf91fd0572c468cbe583bd455cb7f8f644fc68df1688fa57e066101185b59e0c3b970b4bc17bfdcce7741e8b4dad8e144fdc34471d8cbc7a446c5bd73e074fec09292631473ff17b9b140be876a403e1e13cbcb6dd0d8dc9c70354bd097d0cd511d48eb7dc1ad1de42bf20fb03e4f853f86fea6e8c8ff5d20bfbb7d6dc89260f86794253dfc719a876b5ae64f1fde3c374f6611f6f9e1bf439016f79025b7b76a6faab937538764f35d6f746f5f6e89adda68249d4e35fc8744fa165cb3c18c5b78c8db48ba710d156e9ffee11bbaa063e86e7d073d0e03a5be5f3d2b82465f3407d4009f10d331d0730b95fb17e13726d628991c277d023c1bc9b7f78e7d0f279da39aa89df6a83baaea4a2cc2169252385bd6d33e23e2b837dd3d88deddddd238ce620087af8548556020e2d0c937638\nSHAKE-256: 87886ccaa45a414cd7226cccba707a264804e0dbd539afed16e020a4a68527f19eb0ecd269f69755ed7723f5e2403b63bc7c58061605b55892b714b2c3ecadc0aa2103311be3e0c25b4307b314e0e518d083c4ab42e3fcfab9a1791beb188d3e7040a254ce8b69b08dc94375790b143caaff270e1278c63ec914186d8169dc0b680bdc906b75595dcc59cd8acc2b2adfbe736bd0147f3578e5438ab3458c19f8731cc23ea1a0fc1b69f0d3aafb6f2269fd6bdde52bd14409d245df5f6cb13b88f601db75a884200eba9c4094ed81785ed35fd95e43d4eb4ff786b28d9bd02e576c01b62f8e751004e8810ecf5878364b24e960467f643142b24f1b7fbbd89a93e8ec653cb67d7111ba52635d6967db0bb16fcfc96fe06715cfbf7bba1bed5072a7be2aaedf3ef7a97b6fd97e5d07043764af8d6726e7e583190bf357751ebb2aac644d30c53fca9a8a3da5cb6a812c45bb2e6b060dbab51c04c3272572a03122f47fbfb3def82c301cfa386282b997e18392aa4a07f051ad348f37a16c506828e32e75574425604c52b185c6e8895f02c6ab56b292856be9ca033bfed6cd183d51166e4c93eed9569b621fff08231fbbb95d6238f3e20be4d99ddc2d4f9c7215e619d9208895d1aa321c2f28b20c32dd750cb76a2dc1a004985d30b3a15ad57a16e69e70494a7b5dadc0cc4f10e272c4d1a822c2fe6bab6a05a4c4826078a353\n\nInput: aeb5fcc949ee6cd5ecc0aa6bc5d9f1aa6e87894fb4c44ea73a17256b9066a32b6dc94a7c3013e4e27d925b7b702ef867b071345dd3238796118b980be568aadde3ee973096e5c8881bd4f466818d523a7202b6b4c8da3f9bb8d751a101595f68874533d59ec7eaedff2820853d1bb8a62b92ab924d80e6468bfbce3b7629953e3e1dc147bc98038694ce4f5af655541fb493f855f62e0031a7e52541c9f085bee4c6d12b5f8299245251102ec255d9090641e29d4cafb947bd81d1c73e689a7594c0e00fac67cf0c4e9aa8a5ab059478e77d4c9207a5eab82ac15046d139419aa12bf0bbde8eec6ac57658dd9261f78e9eaa06aa945f606ec342422922ab04e511aa13861f84249e9734b38154ee647cb277560aa2ce7dace4484b1001155d790d8084edac135a8255274638af773139e5c509\nSHA3-256: a96105072cf5b42026579dd80baec04ebfd7a536d9a8f37265eb69c585ae0934\nSHA3-512: c57adbe65452a3b420c9b851c0293de9a891bbad2de7877580a772a6364620bd69f3fcd2fb7e7347c52db8a5b5c003662a32c7f3f4a5b31e80b05603d47ecd9e\nSHAKE-128: 7dba93f35ddd5b5bdfd0afe5740e2160590db05925fa1342696a2f2e14a9b8722f6a10ef9a77f90f363814f0a61dd4f40d66a9112480fb7fa44d9b58f08ab2d0972e406347c89ba77892c13bbf0803d3d0577b3a5058144f42478b06dbb25395ba5fbd788a24eb963e8cba502b93cac69e0f5f0a187570361eb1319ed5e3d56f6cbcab89d12405deeee2a4a14353465e1c767be01e5f21bd40bd71d77cc1ab1d1a8b0df40769812e98b63f0ea9bb69c939acdec5c8ccbe3e19dc0318daf63331ab86be40c622f743619eafa9fe284f92f8ed283313e372f30c69a75d1420fc2b3cc8b1759f3ab57b48d2eaeaef88f4a2f44eb4aad86a95e3d8dbacac9797ae9eeb37cf1a6407af72e89bd6ccc32ec972f2172499652b5bc525e7e634e1a4a07b7addd8e59024fc6dcd8d9841274e80ea898da517ea03728ed48ad53d8c84e3d4db4b73d2f680cd57a667d0a00d07198c1b7d29b8d7c683c4e34dd380afe03d2b5ae4a807500fb67d37f33591b2210d07d1cf52f2bdc62dc3eeac6a9a71f6c7180cc02aa92da26e9becf2a6e6fdbe25a91159d62ffbcbf4ad64b1eab0cbdf3aa64e809250d3d57c317f4ba48c4ce56f02a8d214b7fad6404c75e8ed0f387ab9b72997619f624823ab3c40dae2b2735565829f5f30ff5a4b496f53860dd764c01e18fa53d97970bfcb0c40c292e639a1dc638bc232913db2a90e9e6af7dea852c7\nSHAKE-256: e3319fbf8e3a1d2e32b7a8bf40b969db5f3f6e2de978a06eba27007a9c03f0a6d32643b9db01296a4ccf984d4791a8793660ddb5a366d2970bffbf31622e3a9245082f5b8bcdd64a11ae49d92f4ed52ffc5cff64d2e093aaa495e9426d5825021776db47424b8970461fd8518185083d2e36eac7375b84655da44f49efccd35502fedd3495af29d2d4448bb4a74eb05857a7c3d9d9cda121c93f705be58f82855ec9917a52e131d6578094cebc46c02c76c6074f6f736546e47047ecf3fb6b68aff99204baf80fbbffee85a58cde71c4db782591f45607f7213d2b00b4d29c2c15d9893c6be0e63681cc720bcbe8b14cd32c0821bbc950882145646d0c8637c44d74d9a6e933660f7b44239d53b88d7707942c7dd78791808c43faa51e720989e5303f966b4234363afe34fda0ad1bc7d2742acdf0c12b50de2d794696103852c3900526c35d842098f7b5b31339304769637c9aa7fadb716a476ad2777ace5a8e1a96bca143c770cf524474a2c3f43614b09b9daf227e9cdbc0413bef32d4c6eee4b63289f89bd7fd31b3798d7b5026592e75d55bdb8ceef3459f747b27e0292dd8f27bd43fac59cc01a9e8db04d0dd636b71832f875769bf7d926ae198cea4333ef768cf8b895c6ff7083126e1d8908ec8096b24679def39db34cf0dc7040f102ba09dc09bd576c5e830cf7e45ad25bcf1aa6e5c1a19448b3c756aa703bcbb\n\nInput: d4b2636cecb58dc9b609f23176e1610734ccc3aeefd2d33c1a8a40850c0dd908b587cd6d03099bbf9e5983b4f83757c7c1c276af01ac1f30a5391dd7ebf8cdc6b248974c77ee5ef11e4e73e447814331b644ef53a13c47ecb01bdb62298e6294c85cf28ff027009fcfcf68579d7a7b20aaba88bef69db0861e285269b7eeb43b9b8f379b1ae94ac0a7e82150012060aa74d4145e50bbf202da20a7ecd3cb5cee3a80d797af95875f0fe11d92fe1e9293ce81cd637d47792a0462a123b6ab5ae50ac3cbe737f3f17c65d5748abde58d2d18642a09531f11820393c74fe327c885d8061b0e1d29e4392c2ae227d6d0b0e19e432c78f329569d2f9aa4a68f7f19e259e5c26806955202c21a4d833a91f2dfc9dae0134aa441c656696b1c1c77443f2271891e2016c9f68747992c932a500ae6124e8d\nSHA3-256: bf62b289e163f452a2fa2192aac373ec0af03104f2415b5c424e0452261dc28a\nSHA3-512: 94bcd370a29f9dfc5234f8f715562004822facad148c1fc2bdcd8b42888d33551052c16d80f6f96836aab079b9ee45208c2f5f04bbf923bb23714b8597bbeea4\nSHAKE-128: 92f4a04bc9021340e60c55efc5f816abae9580fdba462be1a5e68c465360b52fc386594161c8ea486609bc48cc53713f607e994b9b5d05e14308b20c3801b72ace6dbee33612a05dda6ab8bc4e407e53b3e125225e52b1fd6a817e05efcc41270879a9dc7bca0428ccf083b986d65b2f6b8b22ca09d6fb664d18aaabd1e31a6b8465d7ad76cd4aebe42eeded7588318eb9790fc4cf7ac041b7d3c28c707987ea2df80cb927d0cd52718643af358133ad4fb2341554a64d6f35ffe714aac14524ee7f9a4fa5c233d62d6b4560014718c9d2b4bfc6f48cb38543e283e99b95d285593d06cb39f1b9801c4f80efb68bf5d4d89c103501259a2ad9a4939b7296273d7da5b4813929e1a5d13e2e2382dcb586d5e25219", + "1a30ebae9c42b3a286324ca2a88d22fe8bf44f5d6fe072ceb5e18df8213e93c9fe4128e2a5fdc8a845b883b1d89d85a944aaecdb6f13480e0882e1ad09fc5a08e10d53a18c5e46bf9143cdf3d35aac197298793851a72250284392edf2436e49d79b81688ddb3da42e580a474db679e7837f11cde308586e2b27f65be0ae5ca80c7167b46f8ad5636b3d8dd9b5f2bbf67b196964f0e9d36d62c7497b276243a694a355c2930d81b04ef395b7a252d1ec48d8b9f9f2292c3424eab4cfe66feec42004b6787477c33cec6dcbcf6ccb40f3645c9ae2b85a2b2a35df6f9b21ac956a1b9d25ae77d79cc178d122b1\nSHAKE-256: e688a2b9bd422c5bb54703a949f8d54214c3bf32c73f2765daf19486443ff8254f609fe973c742bcf23bbbbc3bad967a209ea6a52d28034d20c9890587b3ba8631cd8ced9cb363b31349308c01459efa1f2025b097fef3ddeb565f8f1d50653ada6334c069c59974b7b87f5fe4d3d2ce11630923a26ac1aea5a67d469577ffdc3f6b7353e08d8599a5d1f5539189163cfb9ebfa2b651bd9edf3121a36e2f791d6d589ef4fb0a8d389e8f9bbec689fadd9dc7a224b27c9f2465353efe5606e3b02ab4947bc59af41228713ffa8ce130b059100cc5423242099a4d2cceda23a399e6619e245166da0918cf37f2a80d50b173150536edd7aaaf75aa3f76f26004eb510dd08135e9b3faef8aaec0086fc4dc27a6505de254115be72a81592359c3c9ce6b664bc80a7ec7197393014d4ab312b5d0d9e2d0feaa2e5e750c16ddb5722000dbfc98dcf90a414a26454f2bc47811f615a0024c214ed3937fc784471c20c5b6f30e9f807be33c917059f2099696a279d2b24cb36752262af828ece6f43c7d112441b00a88ddedee244ab76b49d95143b499a82b8a102e02d14e1d27695602b5111d91e170272fa7a5acc3d89bda2c0224ac667421e4d694b5c9bb2d766f0046689938fd829ee6c9fe09f4343691e06e3b2855560232771eb2f9ab9091016ba7b9169005b7540e0065c717e9f6aa63d2a0cbb5e6dbaf632d193b54e7a69f3e\n\nInput: 8714c209c0aa593f0705a04d8e1bc75a0e40dd7108897ad56d6ded5d43865c43cf03e9bf9f0b289603cb4c68eda72756e1e21665a309e8ae196cc25d448f189c2ce0da87a2ec91f3838698c97c38b613a8501c7549ab6c12a6fc6694db8cda928974c0bdf57acffdcad0b3ec1e25223d8f802d0edeeb63565799dc4599ce7c246b955d9a10c32aa8b8ae662a6fe5e7b28c7b8d038e542722813e86937f986a593ecc0ad73839e68caedf8b6e5b874143cbaa2d56130cd1636441c7a4d9379086af32456e7f6e7b37237487b4aca56ca9a8b1d778102db398d5bbd799c59fb23c6ee521fa14de662e80cd42d0ae1037147fd25a4a50e648d5c2d09c44b00e748136a55ed0890a186331d2cf5f46b5b53128bdd90125591494d1ca12e55eeefc435096a36dcd12e8e9eba69e7f77cd2593f963e34f3c\nSHA3-256: 81c54e87445e06e4570baa37a8265f09d2cdeeb0c56f1f7d7080a93dea98aacb\nSHA3-512: 11ae6931acd2050cba25c5cbb4e1b1b069167ecd2a15e957643b7c591a73150c3d9fdbb62d837740be8fa9a2898a649c41b3ea18b417ee2a73c56695d8cedbc2\nSHAKE-128: dfb24270828d067dc43e48a4d591bf864e4334370353754b7abf959a86de9b7ace18489c5ccde0b27c1f4d8ab280512f625e64de3a9a26e1502b60ce37e8fc32f92780d59a8e5d2a54241f7d90a7fdd596cb0954fe6d1c4e26decce70113f086f8916dd2e311a87f24d07a0cfb4b305ae0fd655075f5b575c4d2ab2d3c29979c68cf9ccb224fcd6554b062877777d2e649576ca205b7fc846ac8173942d55fa2e5261836dd153907c99ec5a02fb0c0dcbab6fbb0363e7369509f30868eeb948c384279dd6adeea1945c1b4234d4108f503a54768d90b4f966382304c7bb64b8f16ed6d2c0e32a59c2dd69273c6c74a240b1fdb779e72ab708d8da1e9107a2c3fdb98f0ec1aa298c2daed3f76025b71bfa647d94abb60e30296669d9c229da64a6229b8dca15b690c98ddc1a8f33d6819fbfb48e44209fb238bd0ff8255e314760eed6d6ee9796128cf94b37c0c19723250143aaa177bda71a03c9ada47575faacaed10f8f4fbca035db31efde36c30fdbe5375298f0b89fc3d3c6a75f9781e3e382946c56a520d2e15966ed0b0f94da33e642dbfa98f155c724c5879967705b3b126152245e264916bad5ece113e3942b17e7eda61c6fc6544c58bf0d217aa8060dbe4290542ccd8ac2197cf5e4dd1ba4ccfbc32d97752e3b5824504b530d3383cffb730a560ed985c8a0f7472bd7dd69286f7102b51aecba24d2b2dce913ac5\nSHAKE-256: a10c45b31c5e7325938672f39f054f2710d321dba546a45f9d28b4a7c76ec4a1e4773c44da280d1cfa6145335af265eb40267f59047b35981628326a520258aa98592d8ab77c5f9053b9900a1b95ed30438a10f72ea5397258b15d718381fad4bf26552a79edc931a5a20266da3fbf7c796cc58e6c824162d80ee4e5fdd03a3c49a149fb4dcf5d08090f9a01c8043428f523f10c78522223cbf63be2495632e9bd704ca81429310abfe25990067ec213c1a01223133b86e3ae3393339a33ac5ced8a1617640c4ea7216b43d2eb24de9a4b5187ad90c3742f0d81bda5e93a967f5c7e1cac8203ef00748bfee124a91481bc5975195933867968cd0c71bcf880a901037b74281ef4e6500867f246e67c3a3635c407c01a739ab61328b2e69a7a22cf0104cd81524eeaecab8e16961bd7c91ac061f4833e7dfb808c549961768c4ff2cbcc56160549c895175a77e72dbdc0245845594876c8a051cee9f1aa329b2df3393810fd34ccd23ab626c0e067f74b05fe63144c270ce96efdf645b8e8dd789d9daecaa7207b506bbdf49c60ed29d5417aaa8d1168542744f61ae8d26cbd41c426abab0acfcdd7967adf3ab002f740d0349111e82e601ffe5fc3ac8330b66ee4a52a5910c34df7f0dda3074d9852a91ea47ae36ce7f597cf733ae9890b37c318b42e20e65b710dd317135f004e7292784edb394456e92c2f6e3c47f9994d8c\n\nInput: e54321a971715c43d925a82e5b645dbd387b5f0e349b2d52269766e3040c95b1808bb6233f9a51ab5217a09fef77be9a67e15c13552f614c0855e8b0caefbd6e077449bc6a047d452b15d6ab8f308867355b6f47c9b1ef3f900a5ed1511cf2139db7cc34cbd72a2c2d0c209d7f2b2cf2cd81bd25937fb68d5662a61dba638381f61db2886fc47481f421307a237f27f164f243065b6621c38b57b4a018a8d1ea8bc75f6a3fe71dfea4369d42354bc172d55ffde7292f28b175bb935d2fd7cbc98d4b94957717951b5b593ec04ecc4f7eeb5de374c8b91473dcbc70cab2b3fa0c8fd0702e1c26a1fe3e8dbc11c8c93af23650f68fdf4a05106f706155e58cdb6618452f16e6a94db0acd71cf8af9ee87bc5ba0c79838e1a4f9470f5270bfbe04be5b34d1a20c81402e151f3b7ff34d7d0974609aa2eff\nSHA3-256: fdf566636c4f16c36e30e1be3ac463f14cd82db3741e425655c823a77690aaff\nSHA3-512: 6b68d0e5f9a6f9a27572a24e1741cb401e2289f2d2d136b355ffbf1ed182c4f1116557245e6265c8b17d109b2dc598d345008950819a1944fce2d57791d4e4d3\nSHAKE-128: 091a11385245197de133305bdfc7a131524a5305b98fc301ec405fc6a70e497a9e4a4325d9c8e620bd0939105346ef8978fa147bf6e739a69416ff44936dc379ae1567e3e3b16ec180985501be9f7b1ff858d257d213d832f19628f1e2f67ef088723b5c3506fbd883c996e354fe9d598da95796ad8986da1f4b9d2cca268b7e3c9310456a1b768730a4b3bdc750fb963f5d4e4d9b5d5379e11129cf8cc4c980de97979df6b0fb343b096288238a39f55cc78d16a732fc92ed95cee8f3eddcde6b4335d68537d565623945c2797bec030938813b7ff3472f33e41884d0dd9ec216fa725b0bd9f9d2d4a75eae78878765e8f72273c3d13621958c95c3b0bd90bcd7651fd9b454e608f06a2b7b549275b78993be6ebd4d1fc3b8fef839cc0d0fd6bfe99b388dd0ef3546cf411b9be870eb29387c86edce90ee0b83a39866f337ac59c72803cf0148005818fc7273bb1aa39d18196db789eb9de9e71e6a753e8136b57bda12f953d1d0a22f86c401aae71fde12d908f90ddf6be3d76913912906c0cf59b5b0ddeec54f5ae1d1308632bab9875bd27a710fdab47f43aebcd94061cfbdbbcb8325e991bcc74d635c18f478efa1bde3af0dcce40c11bdcb06cc8135b61a60faab0e4571d861bfa2cb8487a1d9982cc3024fb5cd78e08665b66f701d06da4fe589671faf133259d50e26efa689d6b72715d29c543de3261c6d457261b1\nSHAKE-256: 44b660a5a4df9bb7c7777ef04804d6ff315ee50ea68f7ff62ff8218d063991f75f4d63bbbaf131a32d36245a397c33563a4f721d8c17ff2d28570442cece41cc63928581e23ec493ed7c8e2fa7e90f19a3d6531c19cebdd1ec3ee2d8c751488b99b00155dc4b6052496332ea9730d9b327b5da9c6954cfc971e239824e6588e0f2a2f7169994e231e0b84d81a17425cac347956737e5b1a793e3907ae4559ba1a0ccb9df030637d0a7dd43b2a7661e992931bbc7acb67552a8661ae27dfb379d8383190a6c6ee65f49001494ed95b86b92e6c71126745702e28d462a3df6e218a36f2699546f269e9817c03e41efc86786c88fa6d2f7c9a8bc216328b42c13d6434199c686c652a65a61e4675616d1b9bb3e373b1e67f1e2f682e3294b2d8fcfbfe6af56fc082610dc0f5f7438946f27136c2575d6cd71891471f8c091c8da4831a4ac683b7b3f5ff89088e41ae29172a74e841ef32ab507d3431bd052de6457b3ba531c8dfdfba5c76ee961045e497f35e4e165ea952f95030d5a8f9473721720e3dd28d1822695a0bec894adeda611e384b86d2d8ec893a723cb5ce176019250da8cd64e9edcba8f927e211d5564f77642e41e09d6fd22e11b48d48fb9b19ea7d5e06868ed450720f55e8bfcded2505d91be002ffbc748fe70542cdfacbe7eec921b4deaf9ff66386f94eace732d49b0a61e376ce4d5be23a278c538447ec8\n\nInput: d9a389d68743a155209f4699c94d3b1aef9320bc29386bd6ba49a86b575ae386220c03d04470f8ef149b5c46b75fcff237ea98ac264802dc1ba1c8830091793e5a1e104fea96bf467cbdbf8fbed2ec7eae1a34edd16d96a65ccedb8ed178686beeb5a582ee57bdf7661e29a644aa464a60068ac4ac137ba91e668eb91fc29023106101be77a2cd77173c7cfdb2e010e6a2a494eabc1fa9c1672c5fd5418792e44f359a8bf59da29bfd167e94e5d93bd98268ea145a530821175ecaf05f4d1ec79c13c461cea3eeca48c05b570f47a1879adcfb75645ddf80feb56302400614edb9c810b11c010df854c9b42670172244e6d7df5e892fa0adcad17c7ea57c9398263475a9a8e02576841c46b892044bccea5ad61ba753ebc437ca800dab72cb5b2c31b38653b2bddd817561acaf27504e8912cb2323dd49\nSHA3-256: 09d138cc642814ff6ffa408c0a146997255b3b1b28fbf2dc56cc4343dad3324c\nSHA3-512: db06ec9ddc3f5aabed07918360e3e8e7e246bc2e6a307d32bd1ab3165a787a1b41b623e5536ddaeaf7d4ab272587c19348b6ae4ea1718bafc59ca018df6676a8\nSHAKE-128:", + " 88ce7827185232203589eabbc4adac928941bd99de5f75bb8f6813405cdd52919fba4c5be7aa45f832504ed4d4e3a7a8b3a16fd6e05e037940a8acdaadda831985eb87cc9811a7706129001a107670f7dd2568f79a90c0f61db2a4a0b4920f179f782d21f8aff1e966ee18cbbfc0743d25ed703cc793d032302f3bc867927343473b8981339ea112eeabd3d6c6674b8a28839bf866ce7581304686d2b49ddc8442ddf7ea5abd90d1f07424da33765f8d61e0364703f0065201f1cf7a70c6f02b05dec67f3264e510249a6d4e4b230ae0c0999e9e7b1948a516fa5e9fbc36fca0b74e4124488d0d5c43e2732f9e993ddad4bdd8eb8d4a27285dac8d8c915a6da10a64deb12bf001c12d9d249ca4a98b10a5f925b3442c2dc4763902c839a01da6d98633f8fdc9a15476d4dd1a5942cbbebd461dfbe756d67cc3808206ead0171227a6f31d25d6a6970ab734e679793b3f03bab1006bd433fc6531808e5956f081485e2c436caa0a51226a0d13ec31b97aeb4acf00ff5f50141eaa8cfd8c02bb9255b709588940d691539b99dc139295ec37e5b14b23cdf17c8785a3029942304260727068ee29f83143ee4e323ea48ae5c0691f1e61a961bbca2e280404b879bbf0e9af985a3fdaa9ad77cabd3873733c2d0c60c1187cfbb9cf96be9cd3105d28c917da0484fcfe334221d279e7b25d2c10a3dbc5114742ee94729864cc40a606\nSHAKE-256: d188d7c137813ecd13ebf55158ec570498c73d47db79a9277223dcb1b9cd6a194105bc42043fab0298a305e5894fcee9064bdf0cc240ff8ea30dd1ca928c3ecb8353d859f8d7a777be1eec1240fc58334bbda98dd0a386fc23634658780b63d774b1fdb93a34be669c02b4b1df9ee56caa43affa77f5ed0876dcc7f8a7f88d6acae92cd06373f36e33afae7965364b5c4b77096b4d95bf02f9659832811485198056ec0c6770ecdf5be6738111489414e3508385548392890b24ab902093e2df5442e50b36186bf2fa7339a61818cd77fecd098d8b95407a5d0ef20da61374928b79fca15be0764cb3ad2d9634340b79a61773944aa811c0da50195c5dc7e4d5f5bdf7d0b4af9deb9a8dea16eb7238f93414139698225914e44334e5407ee1c5d7906999e6b9db11fa1ee3afa5455432a0e374ed4b97b1ca7422898bff78906f0562a925b6a800fbb962337d107e326b35aa78ef4eeb2619035628c11d4309f7d031c9ec46214b0def7b414cbdd1cc36783ae59c8490861d6d7717e814b2a05e947d2aefb045ae666b316428a028b0d4416b1db852ab8c6db04fcee5545d90fe0b794ddec1cfd1b1956df674fccc70166582a62d9d158ba0e2b8e3f9db6a857214fdb02ee7913fcd3d40864ade5798a4726c6a0b9f8c61f8256e8d99160e6c9ac034280c33418236add15d20dd880cd276579aea0b89e1c1f4f983b71d75fe03\n\nInput: 6bad96dca5417396cb5c4ddfe0e00c030e426614156f168ffd76c1bd5f6dc538ac9a7e506e60a73adf4e714cd354ffd4a0a2cc1ad0ccc41f70769f585873897500c93278f17a0b3213ed6bd349bcd086adef33b862d06ed915fb9fa133c55cb163b6778b2eeab8aaea424e817a378b72b9cdd653467061bd73210ec193c16d1a5797fee0bed814039f0345775692e2c5648a519d5ed3a495735b9c734f2f897b54bb3bb76dff2f1a1631690367b5204224c0547704a521d1dc8ea60159ae932529d338a8f426c7f0aaba6e95fd714a9edf14b553db7eeecea3b8b5f6f922e87b6de89600fb93a5057fefcc8a0f5c5889b0d77ed8ca2580c346853b1709986c213f7b07f38f761696255eb078824e9acad96a512c256a5c4d51da603335e2b6f5d56b23d0f9248da480bff90ae12cd7464dc0dae24a922def\nSHA3-256: 38c9e3f7b75b45c66ae876dd5b5a7671711c7fa9d701b46d2c652affa08dd290\nSHA3-512: 9c2b4c6599c2629b28e02d0b9a18367f87519bc52dd9ecb5d8f6b1b5febd2cf76076fe11199cb566979f8f57e0a27d0b6042b246f7280c98d23e30f27426d49b\nSHAKE-128: 1498428a1c414799c34789378a04c56df8d3c84a388c2cc269de9e786344f00465161c9f1cbbb74b4fd4637b7ffad021ddde4d13ecdf61253b0c73add21c7422ab20ac566e60e57888d354acb5ad14b2e1128f22e117dc536d08c0befb739bec986af8d981dfe75675fbec6bad8fb74741fb9fe3dd6f3b618754e97cf7e976198c82ed473d878e676e8a674c148df163b8817ed1236114eee37c0bdfc8ab2e835b9cdb27afccb5716d08d6c189f5e43b96fbc8daf7bca181562ed2f7b0fd7d767d9d4542652a5858bc87ffa1e7e18b0df4283de82e9f5b3f4ea71ea2a293b2de824cdc22e3a71cb8f41e360dd7c49297ae9213521481a972c71a5e95c9ecd3e589f62ba3d2263065d739d3c983faffdb3769bf8f491fdb11a0251c1b03c155ebee5b7198081f801328baff3751d8663391784ce5ba53fffb8fb3de4109ec3d574e8c11d9cf7cfc50aecdebf4ad96ab486e52acc34ca900efe056db93cc75db4208e1a28098ad649a7db418f9a28e4956815f47c9aadcb98193fbe46e44f10153076b56e575134968d956a04ac2753f70bc0a805078be3c6fd1dc48a9c60f043ad9f86d12efa4677d1056e5394b69691b2eeb1f79148192fc48a059b7e38ac55dd5e88f16bb3c8f472ab597730bc6cc945d8d63046bbdc840bd2e718bf3b37f76ca41d0723767010bf64653aad718b473ffc625c2273161ae0a3dc7e808c180bc\nSHAKE-256: 769f91c5c69eafe94fe1215cbe20013bb3cab93318bc99866f3b98ccf44fc23f41f9c8d5a924d002bfa169253ac39d4fe061d1b161a6661201a6c019285dd2b82a0dfcceede72b52c8344b6689d6752a4a605b926b6701c59b448b163c501066cfe32562dcdca5999ed7fea7ad967cf43c58c975aeb447ccade5c4330eed18779b76c192ea5aa43e3ce2e0dd6f1df23cb3b9c23cafcd7d21611c2ae34d64d5cd5813f33f862ca2a90189a1e472e3bbd6b0d6766df3e17163367b2246a63efe166605a9cf326b83b533ef875fc3b0efa8069e214e64f72d5253db7ad40f6135d29620bc8e5f348f4477bb5b8f4739844145a63b2faa801a5ff0c13e1816f180bfcd52e2015d30aaaa1623eef7c482fdaa0f2496a367b50e868b06c3dc0cd970faddf375b289f4f668f6727db2240c096f2128a1f3ad7d99158d4750f05e587674808869b90e43bccbab7ac5663f9bc9ae335298359f7bccb811d8f8cf8cecc45369420d94b4bf28b20bf190c9d77f6ce0e3c6359fcb064d8d96549c3d53ed4b535a4e9ff2e9b969af0462a9104e09652dd595d4a74f524648cb609d4f989af9f7dd252f39a76d0263b92a19b4f71d5c369b185ebce68af8dbe6edac4ec055845926503d738f551b6cfce644d029786cd3e1c1cb936d85c31ef2b7b9a95e1edadfbafc87e94ad8e63c5c878aec95fb9d7db6cda3d74f5a1d8a889fcc19ca2571eb\n\nInput: b99808da3159c373e4dad25aae5d599d088154c987b8d392d468d6ca73e307bf68e7345a29e53e4b698dfe77fd65534cae0385fa05018ba7550e1f9a6bdff905c5d2aa8810b663dd285ed46585e3f479c54512fe7eba0e48dd5a155e55f93a776846c451904a7b4945c78208e7ce8cbf5c7559fe8005cfaf71907ba7406b9ebb64946a31ab54d33e392a026891ab8fbac692d68cb7f9159504f38dde2082e7eee031c583f450815a44df1b1d503ef4f07cc3c050b7ba83f3f9fd45bc36ab517b7465dc1c9114b1a808d269c981e951cced579a92d9ae97d3f2dc5dbe86303495a33facbf9c41fc24796e4d4a647cf80424cbfc6f4f6ac721670ee0acdb24e89728042b2f73a07774d02ea45dc262330ef0d530f8cf6b1e485b0c6d2169b47df8467b162cd9f43bb54e073001d7d1e867fce7e8311da713b26c\nSHA3-256: d2238ca83e972cc8d2469786c91d34264ab4f0d6c72b84a0f4ea3ab73782b6e7\nSHA3-512: cc0970ce14fe16d1f0a157d87b46a90d9230b07b76073ad55379827255916304a2e4e1152ea74a9c17dc86b4f4986bc7b4b4c9bf72b827a8fa49511bf6f733e8\nSHAKE-128: 648203c584c7f1e42e3c2a7fe05e2d64876166841db2dbd9d3c3b6f219ba7a8dd796d56b6694a5f292568f473be42b5cbcbcdd38f62dd27821689cf1b02673ff1750f5101afbe8b6593b00f4bd38e703dcb7a5ff3d1294b25405caa33442f087912e63fea44ede5e86dc09003ac81eeaad1f8d29f64d18ed2942b550c189538946dbb0b01224b03ce23c2e03c12c9317858c7871eeb3a32ea3cdb08f1c8f4e365eb0843ee1204a7f99db3538daa7701e2806c1e606bada0ee51c847f7ec9995fed45fad4628f23c50f040378c50434f31abea134e391154af09e55d3c7bcfb9c97404e7a5cc7f647245951e405add7f52578ecf449e8d183535cde35f9ecbc8710f2168721d5570e583345fc9a71559775d9848172a1560a8f7695f2e98ac2814866936cecad49a6a7a5062d645b58b6e2c98d280f0f402241746ebb9e8098f853ae09a14d687c18282aa2000a6c9930b6e1aec29ceee5f6d0d4b067ca4162c6713f428904dbcaa869509aa561d98b9ef764deaa6de897c148abb71cd5d2175c9581188dfc558e0e09e6ade67fd2e64a30fb843016e9c0942bacafc0d096fc2a4ba9f26ebae6e4954af3cb2b0eb119fc762ce14b0204b7ef68af0ad30eed8ac8a3cebb208a62b4433fa3ac0ccedea417f996f084cdd200641e17ace4fc607c0b47212af5f65d621d9ea0c4d3dcfe02e999b41110e5eb7477d47d7254c57dc515\nSHAKE-256: 35d24f9a1aefdd3db9561472319a324e96c39c046fd5ec6c0c0f9ce5697e31d00a880d479f225d348af1926c9517bd913690e715e151566fa84fe2d4029a27f344a9723503e18030b81680c7031dd974bf5f6b8394dee6e7340a231a775e08e123bb5d127638502bdb19d5e095e340af3c553bbf327f5fcb87cc5791a3a2aba1f10b6568e9dc1e7b9b15486d6023d081710c59cefe16af1795c1dce0784a3e361fad18bae98f106b235538bf472f47ee3fab87aad20f85f92966035f6f2181247bb06601ba078fb5fe60f14e8754005e92b5c7c3eebfe695d6f5bb09f43893be07cb7f2be74b2be8790887ced636a913fa6efb0b0e3cd27eea2acfc43cf04a252568c738944031af4688831bf22a0c7511261ea9a64db6c42f39ee772f8dd3f706b3ab66b815a44f184a8b01916762ee67337aec72757f55731089d9c85e266aa2aa4c9272cc8eb6de93beb18bc7c6904393da52251afa012d40ef0abea0307645267b22b4c888777ed7b8073044db1e16d63774d9ff0dcfba968ccc6ed03c775f0463ff7747fda63bb7ecaa05f581bbeedfa1db2fa5b4317726eada34a1c3cacf5266e12f7d27885128bba02d8871fe4926e79ef9139ace761075cc48497264ee5a7c510fc77e722062a5dc76758d60c4d84a8dccc72f333d18f4d0e78285ef25ef4ff5560b70b7f0cf623a518ec46f6e276b29eadec55eba269dec2c71a64e\n\nInput: 8fe8cf22930d048ee93c3c585d7654b67e0eb0458a2d0674d2a2408761afef3f07660ce28154b90df842d1244fe556735a4a9064976d7f40d4b57a04d55771693f358cb34baae75e54069829eb7befde872baa217e927693babb741002c9e7684bf878bd00672caad92e7dd9a45bfb49f53b661903a4ca3050798c3373cfb4facd94b1602099d1e4cb9f9c653d", + "25f5c8b569f75b85584ba30b63b73e9b1a6f886c68ba696a181a5092eb64c1af3f3e6aa0c31d23588c6c403e424dbca91bfab2e76ed1dc794a175ede57a5be96fb71772a3a74400c49abc6e12066f9a6830b31f145ce19b19102db50c61614384856069e31cd8ce6812967d0ecaad4a99d5b6bf6a6fe3e3b8def473a1f19faf8e028774f449123aad86244c5305426365d15743fb85a83f628716ec022c30e335aefd3f2ad37d516bead903628\nSHA3-256: b13ceba57c11e33f271df456d85cfcd5f0f226c056072e81dc1fca5d4bac6dde\nSHA3-512: 0b8504ae37902477e7fdc3d86fef18b985377e3bc90f67f785a1689376dbb963cd4c374b5f57cb4591f7cf49de340c3c3de406be4b36c02513bacd0ac46ac476\nSHAKE-128: c403e558fe846e2ea705f57763e935930e3e7eab279bb47e5f94ea07220c3f3d7606fa6a385fe01056092e1d1fa277141c12e4034be01cd59fe651d9e4bba201217452b723879e33e6b9f63a15326de8c1fb895c5dcaff0500a34319cf151d30d4f085f71e0f7c38bbb86a0e528c4438403461a3da44762268ec1502bc7227825148c4ed5d50158de1dbbdca72c74fef8788ed88ba2bbbc40385ebd29638aef0bb22b61b84caa98068c640d8d1c43842717fb15b9343c051c52a89a37b53f640e058cb3fb6007caf634e987e1ebfcdcd1a483e9629e60d9e8f5882e6328fd2cd5f55b645b3c8f5b4a9c429dd1338ce036faafcef4e1ae32d7c5cacb139fcba5db298e4674b141bd31b76d58864f224c4d2b311dafe3709fd961fbbbf0454da10f1aaa3fd5063c9bfda15d372f1697f8609f9aee77c84de485c363b8099cd2e73f328c8737b2cfff5fddb30cf80d359dbbfcb798b88196edaf5cfd1c6d704b15ee9a53cb1381d96b881f8c722b0b1d5839fc3317f3a3f894ff2f1c95f774af8b82bc4c67114de2591535ebb079c7cbb1cd6223de355439d4e93e3f500a2496161b44f7e44ef021faebcd07ff1f22d7688deb1bdac9f01174f1c9c01a2711d67f6eb73c6327ac9468ab7575b2daa25ac1b448c79164080aa672e53fc2ac3367ce645ffdd9e98c881d7855ea89c1bd87dd7d6b5b731b0723af247720c376f2befd7\nSHAKE-256: 87e86f6cf7d58db4602ad24aba1bd9b1f94f4ea55a0df8d610c01174b1b50d1d6996123abda5334f76a7fd491330f42b9c46a693ef87bfe187bb299c1e3026d7cb26e2ba74a46cb17448b415113eb5dccfb46c1c77c5bd4f102be5a5a8f41c696a35ae6fcfcdec6d98a5af77e7aef93218dd9638159f4d4dc6a5f24d42206d6da6db02c1bf6d38eb7a3ffc5169982bbd586a7591c1891e615166fa6c4c42c32da04ab584891afa389e0b720416362304532d15efc7a13770a329be9faef33e6f67ec03b73dc1fa09e501145497e7978d44bdf2f16f625458afa3c51fd1b46e6c0fb997e57e29777b9ad1f55a5ffdb3d5c95c2f7420f888f7189cf85ae3c6246372777d8dd74075d2beec37354421e535aa7178ff5137c16f12aa1bb6393fdbf2abfe5a2976c0dcaf8a98a5ac3577170f022eeba9db26da608076998517eeb5265db21518b9096d457f94046b383e1cf6ca63104ea6cebd26c8fbdbd8ed864d8940cd21fcd78fbbbc1bae5bc183a65836a86d914cea3d6dda09765fc7d8c222207415223959774e391bd29423c0e869a20f954f22cdcb321d4a1a0253ee89f572b65c347a7215645fae6c8ccfd011fc46e1b7d8ce5e1a4b280974ef968da2224f3934fe6ae335e547b78d8ad7a841c7e7986abc577f0d71354ec67ad4ad6383efa13e4b74b38f4a92f5b94e561166260c8b407a727395884d66fe2af1006451f1\n\nInput: 9df00118a5c3c9455f6546453c37ddf03ed59d02e5f4cf124f4d80b1f8a9d4dbe1c4fbc277f6d7e4a3e69980773daeac66fbd37fc7795583758e8088018abd191010b6e0ba027318f556585bc13310cfc35bd63517c892f107f1dc669f636cf392ed8cb84f78a46a9888417b71b25c2786afb5be30b959cdb5f7956bf11d6f43b6374f83a29015b0dbcee939e77d5ecf046fce2acd74c89ec52d8853ae6154fd108e3add8668fa61388979a610ef23dd8802c08cb6e259aa9da6a581abe6f4e4f3d4084e81b34db9eff85ebd089c44de87521c3c5f642d5196873b8e7f2bd835dc8b38c8cf9245898723864fe6ebf8bb1b06446bb45bec6053403ceaf198c76e425e3b5cee74d80073eda8dd809af637f4d5810eb50a82eeb4fdd8b7f98ceca10bc991331e47d15d2bb594c60b696da2aca2399b7718284fb2a91a\nSHA3-256: 4b9e404695956c371e0c13addaa068de61adc35d265789575d9cbf64a99dd3d3\nSHA3-512: 7cfb3a25018d3028239c0e0908d34b117703fac0160725f924d2a7d749b9a7bfd2671b712c91fd5e2a5ad022b9aa0521c8bc9968c58da335de921e5b7e76e21f\nSHAKE-128: eb8815d17ca5c61af9d168774e4ca07ecdb384ab11754a4dca861a0049bb786e77bef74796a5ff13b7e9792561e1966b8c9922553c8cb98f761ec14fe672e2bd1e3baf00d9a92b8fd24deab10b59ab48882d64beb6f0529f2628a8fb06a7aa62a7b0e992d1723bf022ec74b32eb5a89bf34faa5cf2be217e522b7da4df4962346fc22558267c59f0e618f5af05e807cc5b5c29aaa7e6a7898b4eb86b57c38bb4bf05e4238e4b2675eadc2eceab6cb04af3086d715d361f69f09c38b538f787b30b1def66295e552cf4a289fa2c762f68e5445baf8b794f11a9074d8da62a32d0f385bcf3f4f18cd405f5e202fccaa1ea33f406b2662629c3808dfec990a35a5562d249046e8ba6904852c4eb893f1ca7512d227c703e8eb44df872955db3f0a0e3662703b3544a1c91ea276d5c90f283eb1b9c32b9afd75b19671a152828dc8c196bd95753dd61fe69ea21be445abae03d3fcb1ed01853985994240540e4ea092b67472f0c16ef0242610bcce937a43a7311c1eb66750da616b6ebe7ab0785407f7b566d144f539c175f4beb51ce819301586fb0b01edc4fca83a7c96dd1b94eb2fa122fc987c613606c1ea22bcd62758e41a22346021b1648838110d6101cc4d16b85314c667ec7debaa03f8e12e33a3710b1d9772f83efbffc5ec7b3047c43f9bc8e912bf282e07e879c83c355f3a2c6f1301add4211ecdfd4c5517084da87\nSHAKE-256: a84296c85f7aea4c1db0130a2699f4b68c15179becfecd669bf86bec711897b00e3e65911f5d1586b3f976023eb30c9f57fdb1284b3a1a52923ec9dc162e2c9cbb2ab7d111d6512d0b0629d30989ae9c4d94a0c5aab33e73f6d83badbd1de26891961e76069e00d8b7dc8a4908d9e310dac62a4e01f81f858eab667f91426f0e906acaa515a4ba9fc24af2fec6a686e75df935cc21a479ba051c7d25924a2f2e40100ce3b0029f586dcc659364d095ac06cb7cd7ca18c350c57258cd2ad640cb5576bb070ce47e65005c59790d308b4b9281f6d6a1e1d13dca5da6ad45751e1436aeca834162f66e06f0741704853ce7fe39b6cbdbcb1bf67719ec84e1b0f91ab6b6db2a040a95161d407b8e30508abed7fa534def132bb0851a70cce493d53cc8b0aaf650f995c28021e17d2a5afe4549a8039e1a74092251d946e76d51eae5071eb5213bf418031af6abebe988de6a40b878a205f3ae7a33f950c13fe5fc5cdca1437d4b11872ef54aca2f1f06e53a7cb139aeaa831e73b4d13b4dc993af013aa096e7086b73d41998eb7db0634339da06c445b7e7244e752f485d2df7cf702eb4a8de7482e90824126312ba2ffd27ffa31035aa65e9be6f08b0fd0fccadcdc88f0142b6b2e57dd5662b94966e100796a0a0001ebe8899c264c718f9644633189ff9b146f0acaec225bffb9a283c92a5b8f9cae684e20facfd1774ce70f90b\n\nInput: 9b44c937570b27e211f2c80c079ce567edad47178e17bca5f086288f6e7d152fad509b733e758fc4e00227ddaf94a35034f48210cec809ba5d1762ef3d38a6a7098402b41d6dccbea3d8e564d9864ff20fdbe86fb653adb21c25256f5b073fb1515355bb28244ce2e9c9e2965032cd02d3303108de4a3af987624c0aad8150e71a32c437b34e639f117dd64000aea7fd2f726bbf36dd6b67399c85b476a0245b89f51c0983e4a16b739e4470b012c9fc675b8c18701a6fa0895860171d34e17cda32fe3018d76f0305de5e867440a666b51a5a3381ba4720579dc336784c22206b1997fb9d66c4f4bd5fcd25f265c0ba2130c2e080c54761c10053ffcf9e3d708a838f904282ffd5acb2eb18c9285c1d449d705154974c61eb35c88b43819aa6a31e85161b848a204f3ebdc0072a492e43c31e1f37c22152df95411a\nSHA3-256: c01856797c37129f6c58f5ef88157deb317443f76d25bdc414ca22ee4e60a873\nSHA3-512: ac34622e1629fdf2bc56a1dfdf7d5080d7c658b16570d3b18c401c5e3a6e9c12716bf29341f514a38d330f23f54d8e5aa1ce9a81500a7d6834ee8aa4159d0a38\nSHAKE-128: fb92345a618193607c846f6e63e1333f90ce9312cf4f8024b6433b309d59ac0e5497a1f146c4b2c962ac1b70d92e383608be07b0385e4da1393b1d927ad40590388920b02669a6c7435b3955a2ebb9d37ce60f2bcca0a1c4089d88310bfad7cae96cc712295ca03ed2238882961a9a0a567cb06847b480c830dad807bd61e2051c79e834dc24acc189e343975ac64ca34f40029e3f407e2187d28365e6e974e314a3c988270d2cb8073e44d724f46beabac9012e957630050bdea1c532009601cc0d8b0c6e3ac47e2a9423dfac95df5079d025b56c823a4b3579566f2e7d1911ffde7288109f20a2589019ade05251939d5c909b6334441b793c081725f303a7687734e61d9aab3d8db5148ce260d9a9baad1525c477b41ae89c4d33b54af9f6c6e0a06813b930fdeb8051cd99a0b05e9910dea0633e9f80577f47edfc0bb577d439176d9d60b69df0ac05d7b09b68c3fb54008f199c34d3fb666bbc2d06c56bd7aaa168faeba4c29213cda25fc1a2b4e38a621e22d913ae997b8157148b42f6058f2cf29f3852081fe1088099d32d7ca31a09702f6779b55aede41512761786f200cf0b1f1ad23d74a0f09f60d2bfdedc3ef853cdf01c06b877fef6780f72804591830a8dfa52d692386096ad6f3775f254f2eac22ee4fce509a48252402a6bf438e6afe244c9c92b03b84e6e089639be0606419953a72de096afdfd29b61a3\nSHAKE-256: bb362533402466933a4075dc8f574f357c2e25d02c1b742b575c0b9c593ae3b735d2c2796c905aae60839bcdc2cd1d5a3c22e6bbbdcb4419d62220d05870fd34de5ec3a9d45d4891a3820f313a3f19122bf088555cf13b8de8d0a8c4c689ca98b7d521265101fc119d4ff9f305026c1ef3d90f3b1028cfe3d6c92a628bfb25e7e93dd79a91d8e200c6ebcd7188904316a683e09d7aa1945fcf3d523c7ec0d09265e3dde034f2c7504cccc59159bc59528a3d9feff631043c211d165f1f9dc874df2ecdca72a3c3b087be283a9d942fb3611cf7e3f6d5fe049a1710c177f8e5234515047d01c851c11283efb04a11fb3de3b4ecb2318c4c8d8c91d991fd8c96d0240331572d9fe4d375b01c07f60f6305a2d45a3d9851843fe887c3233f6a3ca200ca9e24d1e39da736591dbf04a363c383e73400fd12cc1a8150656eb1031cc3e8d4d5f0506427ed7df188c1caa2a7c13343cdc9e3713c1ce537e049169a0c1b821b512ad1b6df2484c73f4f8963", + "10c7f70210e4c3ee816fee0daddd53182a5c64fe745f9a485cf9403b39aab5fd754f5e66301793dff664b1cf2cc725e3b58bcf783650c2f44f7c4566bed60cc62e1305a836c7214dd18bf07ef7448fd4d09e9ccaa93d89ffade4a7ea68828f0dd2c53162b04b9d1ce74c183a41fab1599087d5fdcb5f9f6a92de75e6de5787025fac1730474780a756b6ca4105f5888ba730\n\nInput: 45e27c743224de404140198a911595b73014ace8ebd92ecd8d3f6194593f969d6f97e5014f3a1eb378390382ec7ada25e26267ba8c3025e45e2f5d8ef663024a8f4aff3d467a013d3fa04f4cbf7f3e68fe0acf590215c15e12d0332e825a0bdadc934e743f8ea86e10c0892de1f4a3970c73086ac1de92dd122ccdf80d3577ba08cd685c3737bf68a2ee7b72e536762de46e6e424d099c8a4012994a66766e539d7eb715ac5400571c6c097be4ad138313d003487c96d6504ba34e0739669d6a1b7ffddbc34d20acadea939ba0adf634ba78b4ef128271f0f6034ecf341341bce8a8dfc43a1e42b0a02cac126f3bcc900526c901865a5016cc7f79bf901a9ebdd5a08ea91efb982430ea9566204cba48673d6f1280ca9a0107204737e50f864b48fa32d50bd6a346e325131bcf92e8f8f6c9704cdae3a87895a696ea1c\nSHA3-256: b50801337648e2da983d3a3457a659d64f2522accf5291e0f58f4e59794f5a4a\nSHA3-512: 61d93d672e12215fd3ca1bae1793867402de110d04e5ad39067cc65386f974dad09dc022976cd2a78fd7fad65b32cb10c6334406279a87cfc355b9101cf66158\nSHAKE-128: b851f014c1d9012151b4dab6e0a8ed83ccde0d88242132b1ea7a88f0f4f5a5d120ade9cc420a9e604a6d69e8155fd534e4bc1514aa2663daa026605a67cff8fcc6c4a41c91e834c4545a0c5bbccba5219c8174fb088945f2c1537f7830764c25a64169a4495503018a64bbae725b077e3fb74e8f6c07e946d86f90b6293ea790e72f3cca991929f68456a5e9211d2e8408d3565d4663201223bdbe5e6191e907aac86272dfa9eb92a0ca78799312fbafc0d85e136111de478ca66d1d17c6c52eee0acd83b5a311aee9996ddf4d44c7b54b455a9d181e8799889970ac9c09204856399f53bdbf1865ae301fc8b0e4956b5e18ac6b5ca66379cb8c5298c1e32715eac89354786be3d90269b1ac38e7b3fed7cd230edb20c4ed7b44a8dd0221ce9afe1e510ec82541d333d82e66192dae242af4f8a0c026d7a606532c6d0dc650a4ea51059ffbc2920cdbe69e8133457b0e3d743d3dd877167f12dc7159b40f64fa1ac706003aafb1e827aeaa0ede298c6e834dc28df11fc3f4f3bcffc7ba9c2c273e54952ebfffd51fb3c0b138695f1342f49ee03d4b01e4d244f38fe6fa0201af319994269e96d8dd3626a575185ea0e5cf6bb59caf82cb7b19a5c21aaddceca056842f348b59fe541a1e2526690c80ec00d4e6d7a15db50900d3b394aafc37a13550e7efd1a3039ce4a01b2f7d2604f6cce262672f0e7fbc25f2cee7d1d4b115\nSHAKE-256: c34e5e3e61907050bc12e4b57a944a8bcd33fa09f498a056df5e01bf8f4c155e4d78f0bbbce005ad783843ceb570791594ab3d41472f0a265b4a2c31bc7e06111cf40a8c89aa539de6f08b48a98fa237c1ca09f673f27ce8c5d479afd12bf504a6963c13b9fb11129bbe01e88c6d395acad53e604aba28d54a219f777fdaa2fa901b50c29e0ce1edf907b61c81cd6fabd13831ed1894b9a0da1ccad21d3926144cb4e4b174c13b2f32a9b36ce725af711b6339aca3b0e2bd4cd306de85c96b1c72dc134c9afb59b7163405b4e0a09926eb509d2f0cc45cf5154cd8fabaf810807b1c844d543e663e94a62156285fd0a441eb5ca0e2008cf65ed7aeb872e3eb0ef49d7778a631020e0d63db2a8512f5da4da5e22566dada1068bdde628b7229669a5df039eccfe4d9cd871d4fbf29dc64291fc9dcc558f5ccba9e3ca9808f3b0c00e96863963d46cfecd4dbbc1ffe222842662939e311b07a787b77b7742046a1156d88df45c78fe65f9701a384cf54c37c434029b2c948aa45858bb9c7b40158de7ecc3918957c5d51007ed338ed24ca5c00b75d4f8e893a917c70fb0e5077d92bbb9a7a6901a7bbf4d6190d25a66f100fe23423f9bfeb4d0df2da83853687209055f11e125df5f78a3d6d3824ad68dcbf697a3912fe4cbea82ce766bbb4eab99aaf7c975ae976b4175f90e9f9ff855426ea8fc75d1a773b5160c4d4a7c47a88\n\nInput: a46f56604a8f25aa1c4e76d261307831e5dcdc8adcf2a1e782012c5e9edc375d086e09e7c1f3a9fc204e59da6ab9808f647421987397993a5d6e27eace5b7c88136c528086b7d182eed370fd3a654434726d33a799f93f064e8ae930ad649a892027182782e11b3da4ac3d07e3f4967251039690e520cb0086aca6b3fe500a42bf4b38a199307b9d0ae6f1a95462072e1c8387036d676faab028296857b864e2c614df8551627ef24740760f84c8d47f345a8320675638f646fd21853dd9b2ca3693cd3b4138ff225b4571616cddb7a84df38d6e6438611523a9d4a4f4f68a0a71295b37ce117652395b4d390b0ef820994f1435aa776f840032b0fdb9b97f2b5cc8f4e4178da166937e97116888915ab9d433d3009d3b8259fa6657861244b32090f3de3d0b9d93c8607733e8487524b867b5e581895d971b879441f371\nSHA3-256: 55701b60ad86cba2ed462aa098b49ad5d3ecf76f993c549c7d282ccf2592e988\nSHA3-512: 14e5469f2f6a883d903b8f242f0e1e945d66f687f8f464cb4828a2a8354e3ce568ae2a5f508d9301b2b408d9c87c923d284b25b7e85eef57214debaef7b84302\nSHAKE-128: 5df425eb8d79d46049c78cad4273502a2c5068eb7e23e86d43fe4ed061f8e2a99533d7c61c20c053f127dd9d477281eba860ba978ee336045d66a5a30e00308ae0b2076057ef8c716d3623e1ac44d41fb65686511e13f2622e13ab911f84f5c0201518ad131f0bcffcacb86fd5a9601119e88f30fa87ad7faf705932aa46944e358922133b27b3634caec10d0b90a64b676d733aa99424c9cb78cc2322efe0fd7c3ac0ed5937f6d54b864fd36291000c9801ea76d63518f1d6ccb32e550df74c88972b4e2c1e1b23c6937fbbd7b3b997800dcaebc039709127960e39dddc6a438f6cc561277b940296a8caad85ee23c379459940b1e1ae952939df6c4b7fee4db3567c4f5f76a1e43883965a63e5b01aa13e7fc192b139fa7c5d20ae0e0304670de5c5fee472124e3ddc17987bfb20a5975253080b1d9ebd54cce2be7b446c6beb934185bf425fbe6c9ccb0cea49b05181353e2231fb18e632311de280d49d93f9c3400b47edbb5de69c546962c3da64d19e70bd0b41f5259324af8597d3ef5fcaf8a3f9c287d375d954261e24ecdcf0364dc40d3b8508468875b8024a329b2fcf0041f7ad382b6ae30718ddb866d28f21990411bf40d89fc362862e90e5d3b9cba1f84eb45b1a172b826b32e901e1778fcf6f094aa89fd982950a6bc5be11f50392dd9d497f49904b20dcecc44d9d709f8f49ffbc90be1647356ce10e3f07f7\nSHAKE-256: c686aa69a931481c9b937887e6f47e2813726598eea8ce77c60b9bc6d5fcabb44331bd9a1711ffd7ff2f1b268d81ee2e0f680deccaf350d538ba493adae683bbfe2642aaf98bf90235f22f18d1a34761a42b00f998e2e7927507d74169e8ae09427c4c26fab84287e36bfc0ec4ea86450e7f5bf57ab34765a5bbe69215ca7e19c738e9d61756ff6201be7674ac9750d750ef84569d7d7fde5afc45deece687e87a5d24095d3659f247552735e6f42ca56d27425800f175e8bff14ec2ad28cdaaeb317a5fe0bd55161aaaabd333a2c84d98b56cfe865b0a1a8815c7c2e8abdd749215a52cb51b9e9ef6af8bcdeda440383cbee1f622031cc2ddd5a32657017b5347a1a2aa53331686c8080608dce2d0fbf60b94bd4dcb4e919a02d1b05c48eea4aa161d632417f32e50105dbe45d3ac686fcec29bbc75c527ca4cbf3aae250a82c160b3ff74cce836a4015ab6b175ed7c6fae887725b2dbb73902bcb7407218caa942a7baf1a01f6f414650c804d896a5b7bab178b1e454d261e4663525aefcd8be574a19da1b1d7dd2ef832363d78ee06b69bace7716d6c042061fe91cfb0170e07471eb51cd421f410981fd3ea3b795c6b6068787dd7b97885656f997268ab34356c8e5c67e0c47482d3020227892b1a0f8b6d59f545a64980b9dd3e318dcdfd2030bf154947ea90c1ce1f3f3fa61cc4aec8bc3c94dfb16d2c65040d370a2b3\n\nInput: e6429ca3e0b6e7408032053d69ad8cf3f084e22a54d09b80bb24861f299d54af930f5dfc0d5e3d63ee4c97213f04ddb26d9f08da682ae7670c01052eaec1a172dc2a25672398e45f108c17af12f6dbd86259b5c28ef885563cb3d4351863e0e039da8ffe88d45c376e37c0624806409a2b7da8328466ee15dab370b37f1eac7dc738a529eb44ffa2d9cd87289aaf4d46e8fd70d6ebbaeb288f1b89dede246285d96895dbb7e1885f1c98303f0a59feae0355229537a14b756401913d7480b258e6f72693bdd1f987de5cdfaa5257f1bc85881c211064f0ef4db176d4b2a9c57e65a4fdb15b5958000b2c46fbaca61b863b20cba2e1c51ec729c026157b74f2d75c782d5bee2ebc01994c29178e3c0377c1988b2a371cb8c8cbc49ab8fbf2f0fdc08554bd26383330a84ba717b6db41d67f7ae9266b279d981ce3b434a1262d\nSHA3-256: f3dbc7fd4f3292f03c0ef3eb2a2c3b089b10f4511664cc1703927ea83a8d6e9a\nSHA3-512: 065a113523c73fa3be0fb7f167eb1c1ec4565f9175615acf75802c1d276b15611f09bfa4db26b4d542905a67bb339ed6dd8f7a8337d771faa55e8bf277c8e29c\nSHAKE-128: 0bc2513c5ba5c3318542bffe844e4d3acf7520ba768f84e7fd7083e582d8bfd6be59f5e27d2813823fbb0cf1ba494e259ac0ea051992f1f8c1ec9d536edbb2583c9954f8d8d50e35ba5bc2fbaf146e1a529190d862b491af62d450ff1443a750fefe978b635dcc6ef6d42db2cb000b0d27301019cbe9d19cf85ee5e59e4331e6260447019ddc7d4529c14ddca33830a413b9466fc8655a55f0f8d0ec12d23242b4cb2dac872f4f211ad0468c49a719217a5071f5f44ad43047d17dca115acd35feb95b392c167f21060cd0b652f2641b772d4f9aaadd95a4501826124d69c1105ec05bbfed861b7a8caba9fc4552a9571ee8a4e636688715a14ff482cb02eb188ed9bb2bcd57c9f51d58538533359ee6b1ba93b8bd6ff7dffe6b3d9973217c4d0a15448c9e06bb1df5005d0fc710e4963f13003187f187225a3dfc75ed28735ebccff5a920fdf3a0b460b59ac3031c0488bfbc5289eb932ee173342d359a1821c410289352ba8b557c71cd3ec25c721f048a74c2ca07c5e7e9222435951a5f423b86053736a2674acde90cc2fd889ffb01a9ed4de731a87a9120d85d508df4e77d51973dafac5154f95b446598ef976f3695af9d147a0a54de5f44f9cf9c7befcbb9052f72c828a16c068f0454a4a51f3ec2c3bc44a32f858f1df49da48df0980a0e8a13a0ec60c6f626865c19cb4028601582b810df0e228710f8844e961c66\nSHAKE-256: 4df8d47b8b214f229791290bca0d195029394cf6257233a4839493d48d961da20cab8a3db88d626dfb857a22133cbd0b413459401d2009e84912cd333690d495cb0", + "565b83c95d691c3505682cd53879a2de7b95e24713516ce0bb8c57af11bd2a857d9f5dd069269aa2b6f0f4f40d339977ac9dfcece2a9d9f919fd4253346671bd8972854e54051347a4d448b1b842fb0b55df5913e3c4030718481dbc616727621a8ccaa91330de43aa43962f2bcc5e82bc5b41df7576fb82bcf350ccb21d15866a653ef2b14f5024721e22d75aa8546d72478cc3dfc0865e0af1330347b6e2bc345bbcd12f4e888cc0d5ec65290d1202d8baf41a32f4b1ce03e160714c26f65756f27775a855d65ce2fac045d897ce43a9ab303a70ce2044db79b7501fe82348c5f011d5ae621c979a13f39bec59644f6d0bea7b731304ea5f36ec60094414168bbfbdd3aeb181e378bb70e1000458003eee64ccbc8b6c4c3ebb4e930c23e0da6c9d12ca27058cfb5f0942616f1ae9d3104c4269cdfe7833622109e75a3e14ddf5d027c01f7ea591285ece202503815b39b36041a8fba78c7162e3a10be251e399fb3b9be564a7068852c68a6498b6f2c1af0ffbde6f2f3cf158b71522c470f999f4453b4249e41627dfd5e21235ac9b0a5c393cd420699b5911b9fde689941250fcf32eb31e7bcc9dc174f137752a65ecc68b154d95978d440b4cb1ac04b\n\nInput: af4a227cfd0c3cc80b62f1c597708f0c32e33230e4cd60dd0474167627b7af7411a5c0e7ceff72208841f8b40016ba3fe927d49b481895a1ec7337adf256424e4156901fad0915b07b17d7168c79688b5178ad4554dc8c880b75c8142108b5d0822751f539ed18477087d1a2e39b723b89c8a457e527c71f148a17c8a8ac98b7e73388b0149a6f354f5ab7f11aa8371d0d64b1f275aecde5d593e5cfcbad41441f2b613123155c06c19414288b4c84fbed747675dd0c2da40c5f2d8db159802fa40a3d51bfcfdc0a18e59e7b6fdf5faf6c02b55df9310a150b7c6ca75258c47f3dcb636b0fae3470b2b21cb4fab96b990b23b2e4e92d967bddeff3235930b0420ddef93aa52e444496ba7ed267a92fd70bf33f2435cfcf39786f495078266be2cc310c37b0abc1ffed3fece6b0b3134a2c8e166b74d0d65c16b09a15721d7502\nSHA3-256: 95989a5d9831d69cd1f9acadf9f0d15de6e3f7d51ac230a82e5c90dece7a0e91\nSHA3-512: feefc975f20a6798be6e184223babde6eacf98c770a1e6ad7e8fda13f757676a4e5a57f56197887d596f539e48000f1af180239bed9a921973b65fdbb1fbd2c1\nSHAKE-128: 2b64d5f5663be93dc8dabdc3f4c989cd09c4d56d10435befb2a1f0f2c566b78624e58d493536f49c8ac638d88cee70de16ad1e5b1e0f0250d7c6855ec017aefc238b15220efde08c37a9cc3d7b8e2ec09f1d701c10766ed19abd31049533a5156cf0d185d71ccf75008de5b90db1152f97cfc4951989cdced5bd2fc0c3eeeca194605d26183d42909475530931235ce770992e67ad0111898df271e3ecf4c4c332b8de3a28aafb3afe55c8e2b9ae8860f1b93ce53e713a55ca6fb6c1a80329626a5a915f1894d03195018fba3e157b23a2195edffdc8065d83753b9c52d1d60508ec42b46337a0e6a8f2627bd154b469fd12c785d8deeef7d2777043245bde18ab32da568be9022c5565e8e004d28a38e224380e6375000d0cb7cebe710516dc866469a0c1262954dd46542390e2fa8d53eaf95d0be60d23f484822bb16e8dcdada4fa242d2282218f311e3b74ce8d461b9477271b704c69e8868078923df97c7f17ac3d9b42ab17e254b3c8eb82f9f9ce87e1edcec58af9ee16f0ef2c704b8fdda09266014f5df11beed3dfe02891f89818b443ec1f7894863bb9ea8da94de0f9c09ce79871a3e0fd55334e9833d8a6308a6a79921c2dc7df21d2b0408e1d36d303fb289cab52b686dc2622e72746be6557368690d670ceea842ffb37d34e62cfb8ad1ead7c47e362137a95dcce178fc270c66fcbe5abbcd2d61dc02fe4ca95\nSHAKE-256: 6f315854e87c5d2c10511da5c4404c6b8881b0c84fcaf2e81ce901ed39ac2ead17b1c60d662f9c9ed309338bbd72aa9ad6b558bcd63d252e0d190fc46a5e342f8beb36d16dfc95a40ec18352060653001af4030f60f33c1bf9071b61238a27a5f031e8e4ae51250289535ee3f52e14043a3c0826f4af377762c3d10eec4ce608be1288f8bc633f1911f3cce3cc1655b68a56eb58cd6f2d171c928404e67ff1b76c3b312002360469606ebd2acfe9602b22f2e3364e901f7575052da8ca75d69ec0bd492265c1c750051f3b9264df6254bfb4fa2545e48736c7a765060837a68cadb1f6dc2932b3814d4537587cec0f99740a88abb90456d405a425b735c9b02a4e7acb8f847c07a6fd649ca392b6f88eaa69a766feacb72bb0eb33a24009dc204c15f0241c22710d2e57b601e7273ebb943eb9268819f4d24b910121c2b8c8b77d5cf60bfe322552a874f3fde02b217fbace61d0959d7b426438c2bb5241b13c8abb18961156c40f90d7cf4c0f9b54d4d3e64722ed70f4bf47c2a6b8f0e2badd0cb4d59a0c75e969d9d33eec7044a6d1ae59319842e11e4cb190042ac09a9b7b2b022a66c651d7ee7f06a66974894a9d726fa6532880bfda63d270acf744187a2e58a634b2bfdb1fa9d5fe5b057bfa27dc7c1cfb7570235e5871fcfa01ff1389b5e1ad9aeba2be0d6a047e4b2e8019553dc0449ca166eaf9891d18b4f17616f9\n\nInput: a018d8ec56744e59e336fecabd7627f3ce395dec1fca04c22584987fdbf96201a12e2842491946bcb35254d9b5fe378e84cf921d869433b5da45c0fb5c9d0b1bfa42bf287ecfde5c605232efd3d2bc57205f4d02030ea815fd27d1a8b4c38f144b1eb94933240b937b9b603342a25a51de3c438c90e46625ea91867934117bac436820dfa7ae1ad39715a9069418590d2281984eb4a9be6d4bc5f178dee734b784156d500c42e960966b75e302fec66c135f4b672fed463236f3e4df40c4da84cc8ee888a301e5156f297ff3da05173b203ffe3c32e8340fa26f4c4dcebe02e17f9ce4fa07431333d85d5b991efb1284add5b4bfcd523f8342525c669bd872a77ecf2c80e9c472f49639183d6698e6612da9cb52d8b14fe16369a79fe91a06d735247c356b7fe46bc4fe3b6c135ca5059f4476b1d016850ef1254f37f5f761ac40\nSHA3-256: 0e183959177dfcb9903a42f8d20ed0d777df75cebb7feac72b8c57783b9a794f\nSHA3-512: 11dbc2c3ae9a959d1fadf9ef3f71834b8575332ab9647a899ed734413de795e575cf0d608b2f38b4b67b8b417865ada1b86e9bcf241c2394c0cb8bba974125ad\nSHAKE-128: 37916bdcc9072faacfc245e5279fa702341f26336d15c1521545aff459e5ba06556c3b03bb0e3a11e7d777a71b95bb68d95b05e74a40e072d0b40be79688e9eedbcca3bc8a304dc16aaaa4d20bac5c39194b7ca6c0502dca7185b47aa6d7533269fff14b49c4e7d4190a1e0d6de3e7d7ffee5c6afdf7c7437536e5d0654064ca3ec22ad1ffceb02a366dfdbf3931cf7da6ee98992d228f3bcde786e217a13221ddfc9922e89eb47f00693c227557320d7026cdc65a83f5a1667b9950ef17466083a50a7a038e213434c9ae23ca5d1e1bfc4ae3774d15c9bfdb9914638969cd27a08650732f8acc80c0dd437437690407fb9a724603f41f260d88ad355fa8165941799e2cc7f07399bc9a5b6dda42f7245a4895004c7b1380d5ddda1356bab9d22626e5d08081472e0ea24f94a3d4f82d92bd11a12f8000ab629ba31d548b9cebbd0891f5291dffdba42e10a592f5cd85e766088d7b85cba6429f461163a9f6477ee9ec9779218bcf7dad043ab294d6bdbf0a0b5fc2e0344d0c0d8d67b4e6d95bb0547df6773e2e7246ee0eb60a6059b17b040939081fa70d6d927c0111629816834824b07d8f4db8568e81a4d5e28c903a407cacb6f0aff2f0e6846dc53d2b1dceb8e66881b1e558407001153a4be7980839d30729de66908b14619db1dcec0d8367337f9ec5739da12ee7e5f487944b21895641a9e16542352ddef361948461\nSHAKE-256: 57d7a2abf4fb4a97e529c1cf1ff58e49fadf11bb69e0c578ea425fc2cfdef11de9619558a27d9d8bcc0915a9425cfc378e1ef1391884b124cb8950d6179c29b355594cd0e295283f76b4b37f15af42a0e347501afdc31be810fbf49103db05184c3fce4baeacca1f53419e35fa8146c41339e34e757b1c8e21715375b670717bd79da568673b44f86de3187f56fa0423f2d14c8d2170706931f4c9ec98a1dae49ecde4f68114dd4d2af9037964b9096f8d73474f914552b1ca976e72d71fa9394d71f1b143399d34e5783ef841d606bc42855f9fc65d2a4b5e6d29c01ed83ddc9edf7525b0d23e9c178f5938b02462bb5598600a9f6d7e8905562408cadec2b562440ba5dfd872c4b9f90ddace9c16f4e59618c3580be7c79830d24732daa5f1f7f760cbc655ea479994dff4aea5dd6ecca3b13eb627f5aa99baa367c1816a167763a286840ee97e30065b1b935f4dc41ab6f55cdcd48ed6beb51c0a134914b323a4a58bfaebc7b96e63bd99b6e2c52744b93774b52d4eadad08610f161c1c0eb90bf1b5d4be223905748b2a4b8f9926c95f196147433fd609dbc8006c2dbda01f24cf76c81f5c83f2f5018963143a6c815884af1088846a439d3c9998558b3b6c230f725ffdf38a76778c90ef28ca0740aacb0b3beeb86ca933786bc70f53cce46976604311f66e5999ea024cfac381b2f024562e4c0e9816bfa8d1ab5522b8\n\nInput: 2057111c545a7272101fd5df1b90951a0cb10710ad1a63ed4d6b642616f5c4e9030786b5b4f267f6786684b6d9b86287f2153012dad420fa69c8a4138547e94c0b45d7a3b424dbc4ab01e2e5f735211208a1190a01998f35b894b64f479ddeebf2d440e39ba6b74bf8ccc2fa469046067a8e50bffe07bee0216713ef10d1d5d4d8d67added24ebcfb1b758fea52037e5afd6f4703da888a6e709061f5c0190df59d58d89e7d46dd44e4199b46c7b9614d59f194148b96aebed08ef495a6ed42e1212cfc87f0d93c953f437f34840f5ac178c448154261acf05117d1a76f5375cfd81f6814d9386b22eaa48fa04fcfd2ba524585c418b42c41d60f0ee7842d4c5ab255cfcb64e70a12c2db98dd7afc701d216d25cf63c18ac52c496e320265e0e9dae306bba88f5883b3403aceaf5b0d9807da9871b224736afc0ca09f7174f1090d3\nSHA3-256: f82c53ea32e9f46ddfe3ac965e9337455d312d3d6bb0fd0aec5d56b6e91e6c8a\nSHA3-512: 9d8cbbf1efd85a37d8f013d82692f6f371273139daccc60f17db41ed180a445e9de9602b908934ca633ccf6b178c9996134919dc4d20f7b117f8463568829225\nSHAKE-128: 623ca9f49358bae591f10acd5d172ade9681d63a2354038effb3172620b1a3b1add45a52961d64b371e8060da82804ac77150449fffab06a3ad2e53aa939c4014851f7b9e4a143d89c6551d1fe32aed6db46e2b3a32ee6ff60c17fab1bdb4cf64ba3347d8daf941eca04b958eb801c48c4a087919ca5888f75ee20b9855f59a7cefaaf829470dae7250e42996c18b24dee38690b7b5881f847ca2c7ac86f057dc461e557783758ec30a3fe4153859fd2b8df225ccc9d2af94cac57c72c598ea3ece349e06b5479c2feb05ed9a95894e9e4aafe907e1eeec9f014249f949380a62662b17c02946dcfa1eeefbd0528328421a3a63f365ec20319547a46f1c1a8fd3cd877f8f88610d70c6cd40f9cc5bcbd2f6c", + "b436281ba361ebb87b7e76344623612035d411906cb9d4a99dfd65c6c19ca4bf03fe56643c3f0d2cbecf77ac1d382b793e8a284525f677f6c8a0fb1d26af603c4b016c1ae416b9b8b6c2d372eb7dbeb08db8b1915e9c101e875b80400b2c53a5142e0d03bf8fae6bc9eb98f58526b8996b1f1fcdf1b919899ab455de3211ffa4437b701aa08808cbc7ce58f7822978511f38a12115348168321838343fcbc6925e1b2958353a82b0c7235a45ae7327d6a718ed260fe577b721e4844027a027b961c0e23d4602aa2387bb5433b1a2b8fb82b5e2560baa9845e78ac892514eb93809e9f9a2d4be016b4995522f60db\nSHAKE-256: 7ff8ff6248323b630fa3bdf30291ad972dd0626c19bac5a86ffbe034dad1f73e8762436ec095ea2ef919ec427c07d0559b8e64c45f6579ea61291ac9bde55f4082bb5994d22981632800444bf2aa5168ffe1a2ce470a7f35ec63ed1298642e940e818d2540a58511d1662e4a4d14397a5ea8757c7ed7f54b4f8406d54bc2e293fc4f16bf7099826f589bfe0f546389870de935febde9371d0445b3e6c0acddba0594cee53d2b6fe3da2da26e7c57a68963690ada2aa0582669480f676d9ab75dad30b979476943c6740986b1e09a1c8a81495a8863c06807464d7c2bcf0839b5be5b2286471ca1b30a35034d6e9dcea540080e2d20858d76081aa99c80a2f8973ac740bcd98f0bfce9a2540d7e41ffa1c02f4b3c134ef279db927e777837efb6640925db9905cad3bf49e92dac18017d43e0e9d16e3fb8d0fb1343d4b427befd30a701e9353c3f27099a0fffc18d8716ef4fa10581253c9397f2e7278f4976cf2f25dd75e4fcef1e297266b68516840de5f75358395bf5474ec6562e2e15f3b4bea73578fad3eba139a48e4fb8b6fe3c947465e6acde70cdf029690c75ac10720200727bc6d142c00bd642f057256842e83364712195f3ad203bfd490f2e4a0920700cf2d673e7a02e6c2160afe05edb9a9e9460f906a46b31118202bec3fedc5df6659ca1a7ff526d79f4c727ec27ecfc2fc088bfb6506b286417b5d044ad1a\n\nInput: f57450d357c9081cdf91f2ba01ebb06a5230550feee2f909725bf6a2f9e10ccd73daf7a9e8e52897e1f94817f5d6c38ad9ec81ad695b0919d24b3c321f3c627436a07ff5fa75e5138839495b5030b5efff2869eb9289f35ec7eba4b0b4b183e263b4fd4cfa5e6cc44947b3b7000b173b48938a3cbf9510421bbe9bc0afc18f1f20a8ebb48df70b8db1b6c9e0ced33d93c58b101d865c33d4ff74c5e411e312f4747c68b7bccc583d2a0d9d861bff8cd3238b2d28e54bdccd3d74e11b1750aca705f1ff3e2f7602d5350253846216a2d34a286faba9be11f3fcbd9f2ba67d52af2454743bc10f36325e2c67cc584f1c6668a5c286a4c98a98c29075296a92fdc9f637eba477dd38440b8c185b825d30f190f4243516d751286097335b808fdce18392f7c8ded84d8f3f19fac8e7cd6551f17933694312f3cb6fd241d72de8c9ca3d0195\nSHA3-256: 369259a1170e535ded5fabb2309dc934d31f93479c24eafad85266ce0fa44f8a\nSHA3-512: 93828c471b3072ef0d251f6ee604598b1993aa056878ee43c4eb93112ffab60ead95c766a9cd070b6287da5375446a52e3d2360657de617a533246ffa698d11b\nSHAKE-128: e03fcab6097fb52ac1782a485030815c5ee19ac80a5eda8b743be46fc0a7847bf69c2be0a526d14352e639b1eb22f5ed8b18a710ce776c15bf39b015f7295381f98ee18f301da56c7cc35bcb387efd5b5c90122b2413cc64754e3d21f5bd48f69039c2ffd557f8db7c269a02cba9b48c6932c22bd834e3b7a9499bd5cbea8beca7684baf14ce21aaa2bc5ae534831e2d5bf2c35adf7e4273f8cc280df1312d7981ef37d3af0a47c79e33b629e01aba1640d69e5d0071a05d78d0d7eb7b27237af7672fbd703ae52d3b44b4f346b342a01fef9aec20f998b9498da06aaabf9b0a900e7bbc9cf04a250754955e9a477aff1b1aea342871f40c0b246e2f5e0b2e6b90adebc2eb3439545e9a015902e18d2bab8a42a5f459a1e76e46a457de9fc2141aed7cf57990ebc69fee8e267074003e19ccbdb902a571ad6be46449a2e3721580648c8c7ffe8655f37e804b2f2779560996695b838c19d61b36a66e580c8d8cd7be03cc35d34927477e1b84f50c7ec9a2301414575cb7cff30ce32621d7e347784ab3d56d7e9f7fbea7ca3c8fe9c47af39c59cda9828a21e12b2d55fc9719d8766f96f78e45a01d9110272be1eca0df9f30cbeb4e18b6ff2c689fb8c7fa0a49c720344eb703815b93e48b9cd5b513e8214713815f52480fca592ec506175d54ab06564941fa0a77f6f490b62e622c18181af1cde3d265e07d3361727000ee17\nSHAKE-256: 67475e645aac0dd794abacf223928b4e53ce795a2b2751fbd11ea3fd688bf7960d5531c5ab16ec58b784caf73dae768f9a184d68533a9c5608029fabde14ac85db94306713d88f4a0f332bda92029893cb9f59ca7155b283294fcc7214ce38c57e54e09a44683990949a57222df7d25a487c1f802f6a64b4f226abde3018e057f449812c3741307d7868a8f448a128309a6551e6b3c5062ae8e63b3b123325bc953d55ea0b68d7e3454d67d83e0bfa5287e8cb1562977b406045ab391e1ea89d26d66aab3294f42e003ca7ba1fbf21e42c2ba955257dc49c8fd2076d707a4b2c4533537c8f7de290361ca15517ade864a4e8fe12791ec6f803b17ebfc17c58a2cd4c47d98083751f1d5d2b851f5827d1697c3429aab3aaff67da0d098cd6df66deea37652a4de78d6a350436d9977993bc42facc6a4e9d4b4ac835c5a4af6d642d64bda567c321364a6805bd3dd2a54229f83d32ccbbee94eee4cf164b41468f20ebd7bb77493c02f963fc4eb44900ce9ca9f0e92932f77cd0eb1fb1a8ded7d4fbfb78b5ebf326c0c75388435047779eae04aa09b3b0d294fa19c62c199206f81d5e46810c308cc138a01b821a4af7f7a7a4f4f65b4fe87f0b4b59f138443029ab9960a92304e269fa99c66d5657249347a67b6287d5f7b11149c440e2d0f5ca047155764e8c9a5f071da2b2616ec8ddd4740cba2aae2f253bb86c8619ed0b88\n\nInput: 66a566fa4c8f5565bce3aa5bb0dab1093da688ca9b682113c67e1601aeaf3cc6c8cc83327c41203870604a4c7660aea2a37ad754f8d0510c275e55f62f8013cc72edce3d8ee3276a07ec71206afce1f5b86f64ff855b6e6a3387a6d64cd6f20b3d64147925fbea5042ebcc8f2fd4be9c3022adc32bad52a240cdef00446244fd7c866e287b40c4228fa12209145873942e825a96fc95166540948a22179cdd694e5bd61ab45594e71ada5cbab4c6a3e13c9f52666e0078b53a16eb882bbb19639db55ca23c93209e9db368cb244a79e741133c3fdf43deb7e3856b57403f4dfcf0d2c2f0a4602c75db48a09397cde2d4014d74a3b0be004aa7b91c4038c6570629fe6793801b9a15a9fc72a16c76cf9443205d5fdfb5eda33345b1c3e9c6ab4fc68b95c754678c6239e2aabd61af26dcc84789ab5305eeec24fc12673e62212ebb8408b7\nSHA3-256: 647aeab6095d50d15b90b53187903909c65d0e926fe2f42b173598c2b86f42b1\nSHA3-512: 2d6ce550321ca2b7a21ad059bf7eb32681ac7b74d584ca579f5a3c95cc5211a19fc5ce198f92bdab92c6406b34611a64a50c39fcc93b24648bd9f8762da18d5d\nSHAKE-128: 72c936b2a615e8cf43cd7f3d6d3f31a8a35832b8dde7b3656b4670c0e28a382dd432ac77d47f6afe00e4e157e047a2b79b9de437bf166e9ff7561742d04ff3dca18ad11f2e1d7594435bbec2021db63ffd74193c618ca6f464bdd4e50ddd1256636d6b32879ef965f7893619489ad99bdf0735d8d130553b247437af1f50cf1e73c2e1581df6b5c9b66621b4812a27c3894828476607895d6eced756211df606531854d5ecd2d569c7a411388c8a34dc034d5bf53b54705199e4357bdf27b6fc1b31285875c90cee1f91e937472e1f038b4ea26f293bbc4dfb458d3a951d5cde73236f9c6c3bb3cd0b4524a31e82a60b1641848d2a9906561c926b35dbd29312f47264611d7cfef2b544a49416c4200fee03f82d5520500363a95e3eb509d43eb7a22fccd59daa9c91b2c5bd667c02e7cda424b25798717b8e91d4bc192364267b0fd795bc30c3a8302fc59d237ee40e219d3afc1d680efd0a5cbbd4206b2190713930ac9994c0e570747c4db10f49e917b5c01291e7787809bec13fcea6fed818e489e1070d0ea6caf8f72157ea76286d0fb999f3deabbd0f29d4b5f519fd43c4dc4178d4c73b8dbb820ec038026cb36c4d015987f3c45c2e3103964367c0c2b2c3b63412ebc42758c8133242661eda82fea4f89f0a0eff08dbec889f18dadcb50bb67b0fc97ac6a6a755b7046ab68c2659967525250b5ad9a168bd0585a964\nSHAKE-256: 6c3d87c88af787e6e8e6ae8cbb75ccd707f776ebf97d63b4b5c6e458ddb508825aba04d3a7d1e48c8ad054afb00ba0746c387eaadbbc628f0c83cbe9d7ec74b2f6b5c7b1123f0cb5b0b904c7530b387bef7f3e267d33cd4ccd53af007aaba8e31321a8a96a2d3dac954440463a2de4e8cf43499298d80c646699e31c9c806745640b57f6d0ff9fa842eda35459e76802da75ef568b0a13d9778f94cd59303e6329949ab14988be629eae251584d646088f7c0663e31b2d4313c7a710b8626d3d6c79f7c4887a0ae42209c4556d30998a67d7f7931e010f257ec44630c9a74e520a77b528f1e32ef9312aaa22685dcbcf7b3e519031711051bb52b3f5c6cc6524f2fb58f9d9e00627be494b71c0c1d021b5272595b9726aad043ba4642d0ad9f425ea6429fae990f80e9de6bf23dbf645042fa694b2664e77760e86880900cf085c573327f4b21bb5f4bcfa730ba959bf29c1472ad6b42882729c39c796bada7f93f8b403e9c57c13172190a491d57d97722b53ebeb717c1029308ed09e5d7b76e6537ec8707c61c4f4094468b26e7ee32d6fa6a1b6cbbfc358a3b769550d3ad670c77b27a08bc01d937099cc826e8a6693d07279b56de45b0833bee803583706c6e3e77108c643944417a1f2cdee89369d5d209523278335e470f362e584fbc9af47e23b7735173793a41fa5e6cecc5a6a2a3b8cdf150a93fc5a3b51ebc3ea39\n\nInput: cdc6d3436ff6eb8e6c5a96d2412e564b93649fe237ccd6ed16f291cdbae408f3987dc5f6c2e3e73b9dbd659571ceab9169fa948aee45b86efe9eadfb2ccabd7e1c307d4e4a9d93f89ac14d5f5aec0c66e0f146cfa2da23fc3cfc884fe72bd91932b111641b784d9fa3303c32c021286b3d2285fe1805473b2a836dd8f131c0505544fe859b85a1ca53cc5d702c30c32964638971ebb90e7613904e403ea38b6790c75fde92760a8292a8559755c707c432cd30b7938d54bc191d3156b41d5ee2b43c130e74101b0e6dfab5827ce17c710e28b76a122b1199a4118d8fd4c9020cf2e25f7fe79c1d43ab64ef16b78acd258fdc465b9c91f851ad0d980b9f84b732b7c73070b1d959a896bd2e494744854d84d7d7e41e50c768d6acb9bdb9d6eaa2049804932a6d1990673c3eb97d66d07074a9cf05bd79845c4424be6a716184b88c14a3ff07\nSHA3-256: f4c31390dec66465595ca8b20028c8d988cf69687088ec892ae21781f3a58fc3\nSHA3-512: 61f0307106075b44e9128789692880872156ca6ab50fb7c2654", + "7c2f8b33c5bbe1da545c570df79297e3a1df4c79a447d27b1fbd0dc732c3cc0014fe0cd683208\nSHAKE-128: fb0fd31dd6f4d26cb36ff2ed22df3b56089e83a68e9369b3cf061522f34ca524099b9fb5f28d36bd71964d63789ee6f56b3983a17523c6ca6fbb59cffdb06a529fd9a8304952a8daadbf7913f5896217e863394f88b2c0b56b3ff190a59b3b46e4b8695055ed438bf110f8506b08521a1b5ae30091cc554604c68a6fbe7e5d69b62cc1c63ef2ba81fcc44d8973309db2295bff72f3d4df8d30a7586204f98ae3cbd450cef65243b01e399416f6e3bf7773474ab8684da592951827d907eadbcdac5691adfa96331704baf2779c0382cdcce1c3a33e3cb374c80629aac700f263f0ce92926447289ed41ec964b9fc41bef6db375e7b9aa1171758a757668e285d59edf6312d1cf67b180f3239ef5766e908ca62a864451b6e1a46eb152ea1b424d02197687f76a935da25452f1ee5494f04402db6a7573558412e92f707e521faca362abeae3873574a8224952d22dc8644f89fbc68f80dd2d87060d84bdafb656a79f125ddcbb1a7b109d239e77c0296ea6c2771d37c1301be4477d9ae106795f954c9fdddeda4b6a8257ef658b9007035029e08c7e2027cf79fc0fb2aad001f495d0adb442aee372fd40631768852ac03ef7e9f92ec13dbcb5411ea554784b9b8d132dd2ab916a07339cf7344e4bcdc9fbb7d4119b64cb46c08bd5a70e19c2e86d3621fa72cd2c87b9cadc8c7d0a930c9c6c13b8b82519cfe17abe774365619\nSHAKE-256: c4cd4f87185905edef10016b570a26bdad24dcee8f6c3c72d42f293eb7f9592e4aec73b08f74611ec6124665969ba641ea8fc79e7f5465b7ee88d2a3a8e75d5362830c3867b1f3ff600a6128eee98faa67b35249f9af1b7a9480c05d4c777f6b4e1085b8146ef37bcec59c72ae9d710ecc32ed4198e44fdddf85e848742e919575e891884ea7bab296045f10b773a8cefb2cafbefe539ac1968c8770d70cfb632051df88d0c7dac5fc10bff79fc79850f16352b45b80ed064d9dbfcc32cf02f384792fd7f6ce5b65374de3256f44f58f1983678f724f45d2b0d14e958edcd2b1809a60ad293a6a22741afdc94379ce5b79360527ffbc4403a9dd096488b4ca52e15db4594308e7e04ebf170bd08a3cf5264f84c57231626cf971d6a0698ad53211bc103f5866f9ded1cbdc6dd1aaab98bb27169548125bba7a48819f49a703455a799b38f1e13e395425ef4c72161dcc0ec544c0d9a515b969117fecef313ca5dfd2ac90b323cb5a634f5c3eb4a6c9f2b97245b16f75cdf3f4626ebf7f1ab6ffa57bdc0578a7df46ff5f2c7519b9b456f016447c4d3e32f7dacd760e0451b295288b0d31ee4f664b98d455e9eb15e2e0a9efa32b0d47007273c36e329b56e31af0998554ddd035c306aa563760cebf6ff757de573155985f7be4306a2ca30b3eee56b5757da7d818035a511aed45d1dea004885e39a2c7b6554cacc317b8804f\n\nInput: bd7144dd6b8872d12d4de7c059bdd66e35aa72f722867ca1eab8e3c745bce32809892d7e2f0e9e60eed5f2fb6cea7ec6a37d1b9aadc6b920786941bc8305799371458c7382877352d72fa11b71f100d92f6370cf748afb2c0ee479608cbfee8d449a3d5ebfc164544a57c35fc764b9c4d5bd94be96b270d9fd64058f7137fe73682f63fb98ad8e79298140b2b526afffc22a471c896b8437c0c91193a07caef3a905a0ba86f7809951505def5c0f19f540c84237a7a550fb5f93b87438f5492176324e3e8fa02936bd0c1bb1beb2c020447940ff6dca9bf81024dc4a28ae34e4763757a993836819e12c2fca5c684f8c2c46707d9a8135569394ae60e714bc91ec48d568156ec485072d15963395dc440fda3f87685274b15701ad6b1f99482f70b9551b745c3acbc9a48eb70f37c4d65ba57091e3d02a38dae050a15ccf6ef3eb88b7da720a\nSHA3-256: 909fdac5664d90125ef601247c5d312432cbcaa1300fa96078d536f043db7cf6\nSHA3-512: b74f867914709c952c1824223c26e23cf2796f7f07bdf38468a8235629ea35555fc3a74799f5d425e5878dd0e7b430bb7c15e3d81ed67f871f7f323ecd185927\nSHAKE-128: 62596bd8813457538fe54d5bc53cfec3a501a87558bb0b83d9a5b73b6da5d7cf1a2c245fefc8356b408df3f6262afee9ffa161911e41c89f0fecd4a0bcfcb6201e7abf412a7a4898f3217fe296b507ef89785285b820c5b62db87621ef1272a36a09ca8f38293cc385b3293a7fff14290a12f8f7a13343c5998b15fd185fa1ba705ff653c52efe5d24d7b01163f920ef9300c20c645fd0ed71074b18587c582c6a871fd72b9c35cba4eb4876ee7dafed6981a08a4e80758dab149bc943883d88ab845bf26d869bf887f8403a5208af1d9150a6ef7d772c857482a4a7785d876a3759db1a62e353dba106ad3dc3949841f459ed093d65e8f0f5f598b9e49807c033347ea825253f42e15941f7aacf91aef9761cfd8f896217b5e9cee969907b1057865ee28023f8b9a1a989b17229f0657a9780e67f22c9b37b8fa5556603bc767268b4744d5eb3e151394056f360039eb341deab1a9e84a4c09e1ac8deb5a33b15a16479aa41240dbb4d5cce24b1ddea0ab879e09795a070f0f25e880707fa3e408280f664f5bd363d46fc33bc31507d973454476ea22419c65d59c980c0cb6cf272e481affd93a74c1c78e0fab128e5e52dc89f68026bf5689aa90f9a35166973cd96d92ec3ed850ae92942aa888e4b0d6407ca89d9b45827eb1ea7d1a9aefe6d36a52fcf898b09c530139d95c395b4c693f296eb936c6174f4edf4f3577826\nSHAKE-256: 4e5360c5316f1e8cee69513b72e2868733045e4f4a0a48f894b6f0c08b963e507ab5e872d55635d8f18afc1dd5de27ef3a79852a5fc3c24098a040a79f2884d443161a7c0d95759b77ae086ceafce427a9273b1b87db74456c184b07dd9df50187f0d2676118e9862c8c8c63fb1f7c1074fe76dbf4430c2493363d11b96a2c308c1f0ee9a885be05d2903395ade15fd71edc60e6ebff2a3a8a84ca5457a0e260a66c829770240002dae1ea490fdbf50003519271932475402ac7f30202d109edc5acb4cd12f4debe4910907d1dd64d21fe5d147c98d4e2568fcd82179b4227b588060c3d9df6dcf6781ce4357e324c2d5aa6087a7541cff561e8ae4334721910bc2736c74a3a8a28e6f7cc8982ebfc9530734975d19f96f8329e7e6a6fc4b5d125d39f206a02676bd6c75f57aaa3f41b50887da7c40d69f385ec67c8948e55cdc71ef8be77f4f1415117a628fd8a98e5606396ab6722d690d2777d5dc25334e73aad0a66ff286b93bc8eac44218d28ccd3fe07b646d1f6805627e33c7999079ba611f6c067649af2db730709160086cf703c6ca9dd9698276e67dcd98cbb87186dd06b47fd40a43b6fdcda5aaba3fed0e74dda14cdb39e9e627c3673e5861ade9dc5880b8874506d1f6ca40a9a16d68f5b63c3c41c6770b94eefa15286ceafe83a2f545f29bb7e4d51c9c23090c66ecf04ca94d1a58ae26cb27a44a40e76d864\n\nInput: ab2cda3a61d4ec27dea999c7f0dc114d878162dda0032751c240ee4c26c6d1e0b7160d5685bc2ed8e94ba5c10a135c02d68d017d97e0317e967169516d076cc3dacca636eea86d743cf59ab24715e7beda94fb78190fc0c0f9fa85e9ac5b50799df52a3729c5d56e1048dd0b390a80afb11e6844d3f3d623e8653db52d0d583ba48621c19afd04eb33da9be01b49affd2e2cc429e29db4f6982e52965e962ecc2787afebb862acad36151c8e2332e80e9bd5c49db3f19de5d13ee7aaa9e794e8a9fd723cc7435c22cbbb4b4cbe3377260e03ad8c4a5d3996e0aa9f08c66231e58032ec3c6335e7c48422b855aed98064e59fe378d6483e98014bda431ba7d82ae4bb93995d1994377a37097be92d4b0d448f863ac691a5d81efafd7db31e41dae27f1ce629972d696e27c6a8b9299bb3b6ea4b5e7d8cc5585c92fb0552fdf14a3c2e56a5417ab9\nSHA3-256: 369ae7933c3923f0fc40fcbe0a8f5a61daf5cbc245e4e87eab1ae892319c9cbc\nSHA3-512: 3dd9661a91a8b678fc8f7d89a8ff28f8f0fe29ad0ec1b9e4ea78be46e5704bc56febd6b62348888cb21cc3e5f92bfb7a02d53fbad714d62ec6e688038f832214\nSHAKE-128: fa130dfe3b262931dfb09bbd4f2d6bba50398d9f84a50a234932deca342fdfbb2f877288239ab8b8ce775ac22b48c3099e642fa50b0a0f850be332699c58c2382f9cff7ac04162e29b300a855629bf3f29593454e6fafb23b17a174cedbebc699d803f492707efa2acd26a728a5e43eef4215c2e19501f69be3408ce053b6d9bc09419e34b89816b674915ca763b743a68a7d9c24311349df6370ff4a3563676c4dd7118dbf1cc7808dc0db19db025adb62dfebb81c938ae57d6cbbba9a296469ac07de2d00eb44ed14808014565563cea6be1561c42c5ad1aca52403b8cfcd18064194878020691390dcc65a929bd691036cd3594da4935d0dd46871e97eb149ac3bd9970918f3aeaf5bb1a1da294bb3fff082a63a34860e467bed8a6936d15710acfaeccd00228cdc5eaae13ddfab763f712d05c65e7e222065770c6722edd91df3216c62000ea0553e06a7c9003756eeeb7e8c2931078b93d00c06c5304e50d3015e6ba831d8c03020584ee0758aabbb91883ab28f835acb9ea7c7425b45aa89f1f5b52fb413b566994d0fc8a464848415f7bee5edabbc4c6de58ff567cc38e898abce0d0ecb0f11d6b8366a4566bcfcfc85a0ad61cda2c329d86732400546c40b579f701b140de27fdc43b4e581fd7b98d31e557f814e1ee2ca1ae7ee89b7acfc8ef4e0e7fd8aefe3d74f8d7b6be7da2735589638a664a2719e7a5e08925\nSHAKE-256: b18336b251cdb716cecca025b0f72312945f45ce5cd48ad94580a20d52890f88c8f19fa363c39878a45ec9bc6a56203ec837b8f601e720d41cdaf962e10cf6c2fe4675a3a5bdad2b87a4e0f8de92aa9f624e8d0716aba96ddddabe09e0fd6b8cef5e8804e98ac8c39bd7e868d5ebd75de7b9206ef9ffb83a3393c38d3038b86011e377ccb83d397c1bad1ad85204eb2466a5a3054b8e9f06e33f3bd84f1b8390e039026a92916fb2f38023423246a8afbbfc6c5309f2052635eef84e01aa4cff80ef15259fb6210e7e55c9fe1aa73950f2982c9a5de76e08f192f4c463a442d4fe080c832ff0957443bf6cb67c63ae417b4fc5ade69f9581a1eb4e98cc6229f65be8899b52e69da6b6e888ed6a17190598aed49887117cdc44697387b2a9b0a0492fe10f802916dddb030ffaa30aa57fb74faac41660501f015ca20584046879dc1def80443ecc3dd3e67b092996e4979ddf001897c2cffae0e8f667ff4e099fd194e71e8e9d0f64191f23d97e9837e794193d97f4369d3a11b383999987df07306ab9b421bb04a05c8c7d74e93a9fd191c9242b33f30e6d81aef5006f0559afd96df43a4ea0abba52193b7967a702c72c653458fe9fb3ab5072f6b53c6b5c45aceb770ef11b446e00db690636820f79fe935ab6f6490d06180ee6464d038df41ca80a6c3cd0e9d46793d86e79ca4ce2b1ce9a0de7001c7767afbaa122037fb0\n\nInput: bb17a22648ea1f9c6fc8e88b2441a5186e5af524ff9df72bd67619d36bab891426e4af724ef43e8aa3e04071a618aeb415b382648595251a055f031e16500998de321f6dac", + "cd3c35eff60520d0aa0d372efd4a465d8000fb98c8fb51c432f4935cff0cd26e64c02b994ee0b314ed34b8e3bbcc0569b9f9e2cd5aead1ed938636fa64ec93dcd22b935fb3f054c5d92e16c2152dcd135579c66f7d3ef4a6c7aded48a97f220c44c7576b14993db62b5e80fecee665ded906a52d88f071a7821d42f0fd0a97c0c502854e1d96e33839c3d8f0008546754216b007e76f3cb61e8f279c0d5ac219854cd2d529e59b08f4007605b09b0001c7d9338443826b39243954db13fc68e2f6770a9374dbdd6be63c020e3982c13a06a926aca153181c6833da7327d5c7e52b5c088bee8efa6cd312359f47f0df0389bb44b87e1633e306a88727c41ed79fcb6db5\nSHA3-256: 022702776c5473bdf62dd6ba76af1b02efabf782cdc2c32751f5efd82207f4b6\nSHA3-512: 2dd892ab5fb7fae8f4622f775c06f0be69628bb36cde9c91a4c664fc2680ce00b3416ce4fb4c2d6c76a92d4d0e4c0b67165151d886e651bf0b8ab8a8e3d9fc7c\nSHAKE-128: dc9ba7180b3ed55c177fd1a80b6fa972e5aa05845cc3a0dfe5479bcb4bd92ca591b07e61f010bf61724f65eb786139d244f8d9e9b89ada2542b400c9ad22a0b4b1780adc05dbfe247e62e2691333a33117e0b411aef2f8e0b5320d992bf5b682a56b25bb6cf905b3733e61b1dd04c1da85069daafdcf590aeb0c61f5d384e6ad67092fb99e85b09b03f7da607f5eb93e03b409f69ef14474486966319bdfe98f2fb71c75dec6c908652c03a73e06358db0d2cfdf11f9a192fc71cee548bc4f86a2f883c105f1f5bb180a5b20cee3434f4de9051c9d309170b7a86903b04a2b7eb2452fef6208adbb0a22e24ec150c4075b4d19fd375bfd820bc1ad6197af53ab50d20ceecdae600fc7e19c87fa67fbcf0b96fc2de66ddd9a2e6c0b383d8d7f216e54b4cfedfaf9a1bd8af8d45d03b802cf5f1a4718536bfa774f6a10f39bf8eedcabae1c05fb59066b838b2d717a884b2464c469a0e040662471723422ea1be7ccb16a24975542a41e77a61b58afd89c725d2ff4cfb8c4ec946fbe24e85c3334461bde680a2c41de8d6f98cd79fe296c50343e1630baba7c9e3d859b900b7a136704ca0a73704abbe97e3636c538fe3936ad225844c281e3105a0ea61c8feae6db351d408b51d0db782b784280bdace171efc0362940f6ff400800a9e2071b9d605cbc30afc256a5f34fe77a1313fbdd7c06166ac905d1c70314122a7c70bf80\nSHAKE-256: a2b5558a4a6530697639ca8869d62d9fcbacb00679b3f51c73c8934f951c389a9e36e1d088a02aa29a01768aa1241e45e50df6ffb49c4df396d494861df3b24eaee148bbd5d5d1cd737dc371189b4d5b867b6ea0abc389f4d56ff30e23b72493a5de8027ce52d5f9d5921b12f6dd9df5ce70d81d895ce0823c7ac42e853a2a94559fa0e01dafcd12a8bc045525662d884b034739bf0a96f6c4688195167013126449811ed21c36cbe66a1460d97f73c21b4a775481be6e6efc7aa3d6f2c0411dd548e66bc5a44ca7291bd9bba97ef952b558d9d17aeeab92d733061586ae3c9c4d597249d3997bcbef327d9cca51ec1aa6ecdfaf1bbf7b35c2bc339d59f71a68dae42ade74279d06bfba6e1751fd85030964ac336bb3336cb57e6ba1699050f62de9ee09ef0a3e84f63beb3d6a3ff73d9544ac6d947032ea7d07d60a0ebed0d107cb61ed96d80a9e901b86291c14ef681ac9884270cbf998ca00557ee3f76c02d3008cca44c4989277cea4c7b9cc36453b912120b87ad3751541bdb87650e04c2d4ad9ba080e4d167efb00ee2b92b5b5c90c9b5daf68b1130187403c8e5b67a781955290a4a8529d2ad6946f8d99399c1d032ae632a0be0f2f7bac96c710e8a744288811f69cc1d17c74b3b426e6062b69fbc9145992c1d7416ef1e0cb33218c13d23b841b5d6d03b3c21b322c547f562ccdf0b84a2b447b130b9a14643606e7\n\nInput: 1429133e292264a7a6575b185cdafe44abd33cb2c1f1760d54233d37815fbab30e9241bc874844eb5d92b7500ba59fdc1e4174656a6779d2110e02b4bb0d55de77b73e2637a0ea91ff7d574850628e629739255cbbf1121442d4484b17c0efd0b1bc523ca13d9698943973f13d19cdd3e14415f7b33439d14fe3a0e2bf0ca36855d06ac2dbe304c7ae6a888f998f0fb05cf39a8a8204f37ded23069c23ae26d4d1eb3eb9baad24e384e155f1b4e91e03db08e61755ad7ef90f47a038f4777a568aaba59e0c5824ee759d7f4fb0dcd6299a8e5bd24c5211ff8340385020b4e802085922b064233a7dda883731650d3f4e551ce52ae04744c9599244ba75c253865e5256ff5c9c472627a790ca1eb93adff4c3b62a8d94bf2e5088df1be176cc5abad45ecd38c55cee58a57cbab3218d671f695d67a70b1309802766f9fe7dd8a3898f1e976c32e8bfba\nSHA3-256: 7381db34d2f4af61898478629579627f4e1b387c394befc924a680706eb71551\nSHA3-512: e3874e6fb88df8461277cd502d81ab678bfc16752400d0825d7d37020dd1f568e0d0e480c247426b05ce938879b459fb56a47235bfb4c968132b773014fda224\nSHAKE-128: e9ffa7d78d45d2cc0b758a623b2cd0feffd0d3cae7d46f659c33cf0cb75b94a329d1f63cd037e341df9e0a8d2d84b065b985094d06f5f9d40fcd03fea68a969310029cc8cb7ec086808057fec0179a6a66bd6a1050124c594c8f919abdecce6da48be9c0e943c4034a788be6963ea0ee668ffecc6729494ba17bc528851c18ecfc977ddaeeb611a234406cca83cc3f61a7bae5a33dfaab32363c8decef81619e56390be9689e98e2bc60a4b60d5568e62fcbacddfab5e7673b6ade49a63fdf7d2d73db401802df0a7937d89acddb00c0d403aa75cb17bbeca61c31a369e71d47e24e08e64a9898cb0868f175d30e989fd640e565fb15caf06a420bd0a725658063c77d2aaaf64b2dbbd12e6e26be4f5afc745f60efedbdd8b0983156443684e3cb358c2952850535e3f4a512a355bdaa1b25058f798690d4ee052c4b6ea9c243a9df886c973f47311df4852b62442ead15173610fd0970330f893e1ef410ae5df740cf2e18c9ef4b7f907078aaef82e6eda84c964896dded21bee68ade27e70aab5fed626ed1ba299b7f0eab4d3e75d8c3c1c143e406507069ed7fa81dacfccf663e1c2423f7cffc215f7eeba4d720f2fa7de3064255fa4d3749b79f991e6850c4d92adb9d6f5deb3846efc1980a49f69873d8eb489e6d99e6546af3354e769bd01d110de7b33e9477334b7f413e3c118767c7d0693fbe7ba3695090f0c27c21\nSHAKE-256: d47e404a0be71c17348b23d79b913aea6d459755b6d2ed687ab65c8afce7cf5b327f2abd3394cda2dba9cff176e9e8e590ffc60495714f65198c35a865e2dc289fed1f7ccbc7dbff846272d5f5e17b10018209b9fdee7293ecd86ba33bed88a8dfa0aa45435250a32cbc2a2662d2e974718053ec02714b0b57dfd6a668c4c9637f97a4c2e907ec197e4480fd03ec84d1fe23e4f0d24f73fbbe1b5919ab42db7318f074c9b7a42e71b39beb077c32be1bd44d6648e22ae300f7bf6e327367fea2d13b7a8c6799ece5634a58b84189050700982131f48a84221919860cf299f5339cc5f10c95bef0174f5bd1b448a100677daa8bf8d0fa829fd2174ae43030c4d62f2287ab5a2c0254c0562b851d94ec275b33c4251470c5f1f5b529b00d3303b5d52d400b3ac1e7688802c38bd9ace7b676221287adb1513ccde68fa50f69d34516583f9cd957ea093e587b70e55eba01e946532c0ab044e7c5db59941431f2b31e55e96102bf7d64f0d1ad873dfed97e7e9fca95997d326fe44c73a6ecfed093f6779a165957bddedfd5df62b3157003d8a359ac3bc116bee166a0631e583804dbbac0b3088763b7bf13d095a4190245f1899ff32a141e855f34a31409201b361689cfcde0f2ab081743b9fe63c7b7d9a1e643783fdc67842fb005670490759aa354b5b7d4dacf5189abd87fc237184656ae8155e58ff3e0ba8f7abc894b9a95\n\nInput: e927507afb8c2a233fbc171ce6faa51669cf6017b7336416660edcf5f9c9c88ae19bff34383c525189d27fee3a4888bf123b587004e20868521d8f45569450d22b6a9e18c1d97621e0286e83cae407833bdfbe9674864672ac52eb7f12a81adcf0049bbc20fb4b3cb423629690ca8434f8f3e9495f7ca70c6eea6deb02049310a7e94411e739fc1f5a9d39486de6b35b19b59eeb98fb43f4b9701d593952547fc3788c0b85b5c0bf2038ef236907b9f435a4158eb619668bcce8d5c417b5ffc959ef96f674c6ea2a01b7e0f9f35a4f67ce92d59c514c633d7d0d66388ab7660524cde4541ea8e966c356931d70c4b0ba32412c694c9de13f7584beaf1a40ef542fec56acf435ef6e6fffb817933c8d85cbf6a5367ad4dc7188439a717f5e9bd18d62570faec9fa41ed8efbc126512bbcbe33b447b7d214560287c1add94b7524985d92c4b8d7a376f65f\nSHA3-256: 044a7a86cc56aab6cddda2968fb158965db849035cf90f4ef66ae30c9296e4ae\nSHA3-512: e67d1dc102917d0b894bcb761c7eb753963e0d376ef21592327dedf6c73454cf0e6a732681d950535b35ae4ad9952b23c684f42d818ff5ae8fe7d9cd04973bf4\nSHAKE-128: 041ce95b9fb726d7274617b76f063f227c9aaad53d1d07d011b09d76c1deb971f82890c358ed4ad729b098920629e32db1a9098b151f5410c49dbb8876f6e921e24368b04f99461c0ad28a7397aa70c9cf4db1297c61320e69067d6b05ae2b207892b0374bfa9e7c1a0572015069079d4b84ef81eecbf96eef3d51879af02d0797e1c33f2bd92fdc2b811126416bea1ff9d4eecd9ec59b0ae4f53d15498c6ae58179eeb59211630e7198e85e3e421f51fb21ecb889421202ee270783c83d1d7501a2e1eee81a778fb0daa770859deea9a523467baf0555237d25e6f791e3ba01ab01fea1f1b0b599785d383ad439c8c330fc71806eea12e1e6f43e9375dd7e884d6ffb6ecb6a38c3c537bae7fd2a96a09c3c785fd015e93a1e7d56d844c5bca2ba28acf36364975e6fdf12ea24fe0b6614a7100318f69fdb13d428137f596980f0820716077e79036a1645f599a7d9510e9557f6c4f18c94f7fca6c2f9bf8ddd2ccc7d825c806140a8b14fdf6b2752a87cc4cc94001960da1b8949ab18a03ac0bb916b60ada763bcc92a4e0c542751070e2a9931f7512624b521e98f627da159cc16cc10747b58f86bc67fd7d763ac766888402c04a73a5437972714d75e5050b9b708380f4c32719bcd01ba2e6fa0fea5b0a2d5ca6368e506c9827c4c7ed49870b6705ad12570bc83c1eed8138162bde9708ac4a089ea3170776ffe1772fd54\nSHAKE-256: 909dbe8405a6158ad0cb05c3a17f4ce9cbec209fb93c61d53f06d4a682c3c20d47b43a3986a820441684452a42311e81dde785872e6570faf0b4576ebe025dacd5a31235cac9a94e3c400b1be0ceab53225bcadcd703fc38719f645ffa52c43d1a194c2ee067f5d7bd568d03b75daedcef50a15022e2430a5d7f5bb641c100ecf04f7cdf6b809d310d4bb663603fbaf1e2fea606a66fbc3900058051dd83b672d0d822600c82b3949be4d42bf28b5d66e8958114bc9ac8b9bf27ea1c93af295416df45683b0cb8a035d97827ba1648ee0473ac107a8a97ba705e1397fc092b82cf6d2f54c814e6c1cb22db8e3963ad48fc8178b02248ce311d8ee351", + "0d0769e2eb3f8795d905df5b668990225f12562091c6742eab8a3a3c9872981d1a11d8bc158375869905b9100bea9140424dba109aaf8fa508cfd10795ec3c45940b796f73d27e121b0473f97aacdfe81b508f675e7d567a5ba6c0a0d703e0f8a99b81db89601d44caf4551fc13d646aa426ace2b2a8f3d94df76696729a0a49703f3d5ab1ecd3d09692765aab203ca13735ba96f577b72d64a5538338a7d440bcb2f697981949f8a0b82c149ad3dd171d92ff0d340616cb4ddcf02dd401a1083c1a97de15f83b1b7a166058bb96da0f82057beb915a2fd5ca776329bfeead55086765c041d4569b1ea20b16dc29ac0e4ade06cf2d93af463b5f5674dd686341e4fb5652\n\nInput: eaf5406334eea177923921cb60824c02ed687f9fd449b18ccdf2f9a4578159a3b4881e4a22ff0156f561c59d61b3469bd3150e88784a58c38838a95fd9c672bc35c3079f81b8802e25a142bbc087cf5bd21a78f12a8e0965d6c9a7a5c3f11bfed6c1dcfaf82e06a455f6fed7ec3e2defee27c65156f53b52731c309876590aee58d7e3f2cca78254c2f05b3e5be33d0336f9f1e031e50dabc3baa21dcbc55ceee876f7f60bbc28443d18118379d0febcd78b0f2fb6d19cfcc6e9d00240aabb505919d07423cfe87ad5daf5c5012a046e7734b29ece5f8d336439b5df22cf764ac75372a6512c856e7e86f35e3841986e75cf635fb0dcf983d8f5917197f591c04eda703f1ebcb3cdf6fd9a309e17a1a9bb366b53fe13f1c9620917ae11c8a39e7ae03d985122c7e09f833c79742fb1c4c01f8dca920d9e514bb732093daade421f971de4fa912d16340fd3\nSHA3-256: 73b4846f84ca7b3438ec7e8bf8cf03e8e84b6e33fd84d7921e1659dd4f6a3369\nSHA3-512: b1b3e1ffee4856dc021a654a9454934f3aee82f540dacd9dfb0dda52647fc66c14f05a43209a9a4ee18d487ffae6dcd12ef60d0ca750a28dce8df6593a3331fa\nSHAKE-128: 87bbe0e9b60d0480a3f2b5a9f6f8156ad6c09defcae79f69c5c20e055a0602f0134c92af4bcf269fff5dc1c95bac87fe0b64d37ba71f4bb51dc4fff15c2d6e0881cb63461895438d0f077dbb964417f7bf8f9e76afd952f3d12ee38184858feaa18a88e70695689930df502b2a863e115b32247673dfda4e8711c76e96c15b896794d09d0137f1590d53220538a624fbbf646c521b51f78e10fbf236f4e7d9d3586c52c12f948747efd2c128bc47c1c4b9f4845387291938df49cc2c15edd96e7d61e5e6bc01fb986ba0be821acf2be1d8b27a16ec9b5a1978ecf44adae3a80080baff5530d7e7682f7bbffc1dd004c3099beb86c2d2abf458a56f56b0abdb02c8deaaf0d0e30957342a1b9c7c0b3557321906d6e220127c4dde1c221c75e8e61c6447af19f61509d742cafa3f26226e6006253d963949a3334e9746ae028339e9b9886c306d11acd52569dadbfd65c67c363318d412b042e908479c3ad85b64267ca700908169894e98ebcf43ce0fbc0c75516bbe893108717a12e0c6f402dd8454ed3a043b55dd3918dc38140e73434a80f4e3ae913110c4cd7ed32b156f96e4c158776ef9a37c4491c60aaefb4b9800e36c0da115e8faa4b718d2855cdf64f80e7ae1d028349843142bcc0a3dbde4af3e006fe536bc52f84e3e9fb3658d2ba7f81d3a10b6f93b99b427be35dcc91c762878f73f356a4d2f18230b4121c91c\nSHAKE-256: 663e6f5d60e357677b27b3f6f340db9de8bb750cf2d3733f2ceb9fb76f6fbc5818de159cb1b58062d994b6bc4ff5ad84d2f506320464c28e8613356705252cbadb2428058d1e181c4c61c99aac478767a30cd27705710afc03af7fd1fa3f0c30b9f282eee67d569f487e345de2fcc20c70be9ac6d827d0073dcb4acf1aa7397e433911478a68df7fb79e93d343e387c475b013ada4153ca75ce365d3f233fd53ad30d672b4eef590f5a0519c60a06f8fb8036b301630c713ddfbe1f8839519a22afd8f3a0b29099abe55167dd0aa47b765172d64d968843cea0725b820c86fb63c594e46144aae53d2ae7d08ac4922ee1c8086189ab40289278efe3677018fde0c1a27b4613089fc6ffde5d221c74cacbd1784b4a0173df4fa7af73a53db449b1bfac9b0aefea0373e3937a0e9d208277e8e695d0a93deec9484a655af994a476ec9e6381d28ef6d37fa98917ea993b61adc22bf2280259b6e0f7cb3724b5a6376c1419aae0b9fea6e628d2746334a9beb6d68de061d438c0db0af4d49326261cc50eef580b98220fb1fd2ac8363bc88b6cea24584371def90389202e0f9072fbcfc029e420672d754366bb1c840e4b4c94a512aa30c5742b9b4092a7008e591d73ff0e1af74b6d61724e774cdcb65a0d64578b2120858cb968f0ffa0f3d4b8e443d124b84a5d3f2ceabcff867e7cae062dc9b03dbda62fa0a0292385066bd1a\n\nInput: c908eb43c3e7f6195880987da3ccfe7fcd3f5204b6da156d0d67f1d26ca0fb8cf20d2fa729b7812935761943c28d148690c039f49a9ccf5d2a2311fdf7c63d69115ecbdbc1de01d7646a6d34afe4b4f4a64f2730a5b28cdf105d9919e2a336212a3de5b199d58cf67f058a5cb038f0612858435f2e709a81deeb0663cad1bf562aea8b83c334190fd7cb4598eac8a089cc1dba78c0117aef25870c6f662ea2dfa55a709b7db4372629df9e12ce81bb2c41c02737400dcef1be604cc1c41fc67c9190e5d8017da4605f1a39a37d848548ba98c17fd767fa0ab147d0a011a8ff12d0268fe01ebe014397d1cf9379f8d4ff7f74b5029017a9d05b59aead9fc7965827a233c004d10c1bb355d847f88e525af942cb091bc0defb2676c5db34b1ce619fde8af3c1fd7cfb3c2b96fc1bbd688699c230795a535bc5a6c5d76c4bdb7ddac7da2814e4de4d001c4f2210\nSHA3-256: 89a35b7ad236d5f54a93541dd9c07d5c063da7f5a83d9d97bfbf25cf969eb372\nSHA3-512: b6418e570f5397b7c698af8d0bba10502d280a5e4394db97666999a2ecc2374d40195983d66c95b580bdaa89b25d2c1175fea57662dd5b582f673cc283e6d2f5\nSHAKE-128: c98c1bb3f77198bc003ed30ff222a35c30c77e4f28ca59b1cd1ef8728b77e0d69e1e5c39fb16acfc3c1f9dee63acda843dd7fb2c2c6d75ca2e9f4d7aff8995a27a7e68d4fd29fce5556694930630b503f52d9159b78047cbdb168f959889ac961ac7cb9bae581910cc3d78c6c3840251c7e0caf186fd6cbfea58b00b57edc3d622e934a489aed19e9c2e4f5adee86dac332f8b01f4f6e8ca5ba250a15301d3a0b093df33c7a738b573bc39aaf794dc1bc3be3a33106197f0fe17c36b1a11eee6acd016dc27aa1f4f9cf44d9fe61c99095becef58e6c6e1dcc2d5b8a80229bc89a49c780912bbdc98082936fe234c4e93e5ff6e019827b69a9309acf78552ea2a0a7743103d9dcdc609949e82929992b0b55bc4c1d9b3fc86ca7be91b88ae5d163d7990ea14d99b070fa9da4df2a5a19ed943e625676ea83adce42fb3c5320e6a36d6a7c980f37e6f36f97002e729a3193bcb68f32109c424c6896a93923ddfd23b69b119c2e1323ec8275013cf47b99a641c0e21e58a0314bc2ab8e5afa5f15c075e3e97b8b208c3051d69cd4be5a4be08ffb851163ae017b99129b0690b27331cf3c756b60d5f085fc8122e91c50ec143376cd56015729c7a6fdf6fbbfbd8add78f7c58309a42f62f958fc93694381c2e0d85cf3b63612b7d1892abdf0756dd4350bbaf103c08cfb4029e55cf72f046b08ba1202080ffdcfd8125b93b2239e4\nSHAKE-256: c5e41d4e3b73dc0f379048f57a41602b98885a859d62394c446888817e694d68f6b59f3213a902648e0701b9f2c88e5804c6ec54849783ae41250439c6740a710f4f25e6f03a6a6e654ab1cab8d14dd61e69adf8d1c060b349b69c581c9d888d9208fd5c0f8b48e48878458330de27de687fee780bd17a40205819c576f87e9f580a3f802cb3f793a85c6d22011f4a6a57a3ce92761af6a8dfb0bd6505aa38f1610aef0980932aa4a4f5eb8c7e0f7d6dc09d0326cbf53527e4bae49cb5d4464775bd37edf89852769031a989bf22d6c6c0c65242a10fca2275fbed4f53496114473c98d9ed1bb6e1bfa9634ed9b2e26614f3b2798f184b7189ee911e52af8508a1d20a40a4a3846cf25bf2a9a3a521b53dbc6b17b021c36ecef22048d0f62f08dfb0e2f34b498ff094d4baa8716f6d2e117cf02eb36355508ceb98fe66e7e56121ed7c26af4dd6dbec9ae983c3e14b6b4b78091b1a782997143093436967d631baaf1fbf8abd074fbf9bfda48769a5967fb3911071a1d1aa649d8da7d0a2ed914c5862a88b305392f0beac7e11529882f89d2cefab476373b4a6e52e798931d9044716743e495a05d7742af43e35d2f7b8b0a058b1a838c6258e505ee748d8f6e43695cf0bc681adf2737c0268cbc23015224d4da38a97948f10f986f811eeab62542d060daf0d66595290c3f89618d6f195b446cb3090c0aa73e8e620c1b3c6\n\nInput: a730475ee0a5d4d5dc2fd3f47c5432cb01ff205fd500d26c584eb689e5c87ce8c1e2529d0dc425077acb634b11efd86632c6dbc2614551d80783989451597612dca10a72f025a0aca512c90e4100936707daa7e424789391a566330749b61550d009763a1c0225fdf8eb4663094e3df79dad4883a2bc814bb2b3d1704528bfb00ffd0cded220e5fb3da7cd383522a7791b7e18f6377d44a2b77d52dcf2d222724b7eb2a4208819600ae05615933b2f5091a7dc3cf4bd2bd9636d93129fedee883eef65681d281fdad16aee6d0d0531f642a38f901c852b708a76bb6111c7e747162bb309484dc8f12296a81bcbf9ec91a48c9d4b5b96b6144806aeb3d9c91b2e25a3d6dffb73770a971281abdb105d6748436111d592e0398f705b6ab49b598c9611db1b6953231c6b70d7b2adfbc506baf780a60cc34d097863e52fc722b67859130876ada3e856e0b409040f\nSHA3-256: f005141ea2fb7fbf533a5d4498559f87166e367cf78a381a108b88934d058b80\nSHA3-512: 1b06721251bc6a6257a8b63fcb04c1c2c6f64de644f6cceff44146007771f3a959f4ada77d91ccf4e20b5555ed059ae429f064fae1acf74c8c13f0e80e360fcb\nSHAKE-128: 8dac834f5daecf2ef5d75c7827f4de4e5e3e1a7fdf6b1274a5ccb295f03cfbd49016d1ab4c9d16f28950f28803e4f9993f5f3bdd2a03173d727c4052111ee65a0f35effd3c492e09ff0730954ef6c46721380fcb39d2bb127b197a30b61da9413b0c4ae60dd2e34595e6cab6c68f5673d648e0631120ad4c34c1517d9c74bbd4ece0efa47a1be36dc3481481112d69f554552ded14766a4d0bad8dddec9debaa57cabfa88049dd432d59d230046925411c050b6901b9869ce2c4882e74702efddfdac1fe2a48d93dd62ebd3756fe92aaafa7a0bb880ef32e4691904628dc3bd0e6d9e028b10df3c31a9583888c1276b196cc5cbd74d6cfca7fb9ff4461de549b2cea752bbc43faba439ec8720525e87c2470e48e1d224ac168ec221794684720b3dfeee648d79a0b4fa3450b1b681b1a0f4d4b4eb69f68bee8e743a140736b90871dc612888a45d0bb0053917783a3dec5008eb97d748393dcc728b4e1ccc99ccb319a35dd795e1362de1d76c3bbc8d9fe23b15724e197f064cb2231df3fc493eb61f38f3fde7d12d3b73f25d0d0f873441d831af51d2f1a55db090eeb721b94d6b1bcb5e7001f247c66d49", + "97f767b9e0af59baa3465e0994942d35ecbe22f1794bee6ab1dc3ff0dbcb90a41515824c3c96eade061aa79931b2a854815150632bd64af00646505048e3691da15923816d7a6bb73ab881536435a40c020c43c58\nSHAKE-256: 48b0055293cd80c3b268af7384392ccd65193efffbc3e242209868e487ca83d5d550dee8c6b8da28f35b2b889eb1cfc1f881b15037958804cb1005a60ccab44c7d2207598fb7026056812649056cf2f9e3bd8d7cb437d5d5a97138d55ef16a6554ceeb95719777dd0dcc36e6250ac9f4b38882c175d738ef7bd25a77939374ba9290f2669ec80b5f33576ef5f3d525dba4814951f2137edd118535b8f2531822776d117ca0fb15e3f4a69d17a23c59435a6363b871d08986b3e5f6b918244f58d826aff7e84432ce776264f04b005471eb28bdcad53216835bacd603eac0fe26e5aceab0ce399706189d659b6935fea38de2ab7831350ec4aa087eab4d44bf2c7d52cc7c00191bca347e91ae3f195703ceece8170aea872bedf1a6cc0565d105ce243699b18580ae0bcad58efc748b6eed3c0b7d0a7fe6c4e9263fcb3949baa912622eeb68cc6d168dd734e49df7171ac50df238da732cb9f025273197e582cfd4a057cef85684e4d7c82efc78b45ef5d6c052d97d7b82d18221a6c4471300c54a50b72f52fcce3ffb7c1c6b42f4d7b25439f7c3f8e23f12cc629f02758f603d1601f6a3dad29f9ff956bc5be5c7e3f1c822cc800ba2f16fe43666b763c0b8838968801484b7049977c15a368e4c9d47ae08b8750cb61d69e3e8b533f1792506262376cd3b452dd8bc65dac42e75697976ddb1f083d554b7dd68cef6774cbc4d\n\nInput: be7e8e93ae33e329a9028a9faaad626c586ab01e6bd5bc6ea7050786f45a66fd21a904420aaf5107015eabc321dce3917da8c9d74814cde5cadddc7d94014d5a9e7f30d109956ed0be68e9bf88db79210ccf9dc2c5180483fa3ab3fe64866bfe1f14086baa6872dfee2b05589c92ef036ca6216aec13268b4fa4972ec2965cf1dee400f7933494260c6ec19d0b2e8a2e3b271813f0314b386105d8637e0ec8e789e653611fdd4d62cf8a262fd0328d43c1613932963586ad86986828320f2c0b6a9e02bf9bfd42059708019163c8fe1688b950c9ab6812a7f1c1deb414ae8be4aaf5c52d86f1da93610d2091b046cd609a81f51e5b4571d3d0f3172388827c7cf201624b59e77f223e15adf974b75892b9fa6af730dbe0720a3b955d9bfacbbb9e39891bb65d6ba845ded585ad6899e651521817fd320ca280c92b97c70ae64ea1c382feb320c89fc6543dc414c3\nSHA3-256: 611febc0e4d8b92ed1e9562fb493fcffba7a9887703c7cd57df9657b725c4b6f\nSHA3-512: 8e352cca86bc3fa6256d9cb3668af6bac0e791b66d82018ef7c18b5e01496cd6d638281f7490529db2ebccf3179cf2815c9f0685ab2ec9a66b81b44d596a1d1b\nSHAKE-128: ff7b104861e2fa4a7135cf8d4f65706dd00dd8062ba78dcc3a417757c47f2d67017e67181ac4a319bedb98704549218d78bbbd7c71a719c4e5941059d0ee70923e052a3f02272fde73ea2f1b7d2789175ae6aa63ee98b75678be432a7e1d89456e56265d4fbe4f0a931117da35f815a25ef7bb44c5e263ab70184dd1e36afeb5e150d7ac5176aa43b37db47a8aeeb3d4402e848ffdba1495d83dde57b673cd5a530cd7b735d46cb67a6d2e8df95b5bc2e6a1580317dd03019f5ea9b6943bc7cacc8bc54db8ab7f1339631cf10b3669c7fe35b6de3c3c67d0dc99366cbe908b51cbcfd7b875346a9cd6f5e7ebd8a2efe8910f9a979fe58df47e45c9ebb3c78f98c5b96a8bfef7a8142e98e78f57031cab96937003103a0364fd7550a61facf79b8a0f218413bc6b594f5cb006cb433c002451cc2917a827e6e8283dd3dcf7375ae8303b8173904194fbb6294c0e4899fc7686f16a1e0027c95a649905d31f3c4508f71b91b72ee0a32cdb1f5773c2042f39b209e4f79469a65e04505ee15852b899f40645377d90c9aab6a7637ec153e685db63b69b914524759aca3d2d3e6f4b725f293e22f79c04de6d53780d96fd4368bae0dd74152e7ad7e3dd3e9d58a5d4c782dc2fb371745d1a458d26cd9d9271d1111604d8f5d616ed4e7e3b58b2f900af7699127cca640beea28a19d11f60e1ddbbf1f65ed2423644e1826187a5b3a7\nSHAKE-256: 58b93d4752a53f308c45571c4655cb2c013e1642208f0a7ff6eadefb992ef4153631d02c123484bd86dfceeafc8718a36a8b72f2da23c6fbcd94707c72eafe32667716b72e480689a91f48ab1e20aa2811b4e5149f457d4d9fff79c452ccc52223599384bf1c28539149ed6af8865bc3cf8e137d68bed2d0089a0d0a85eb968e85f012c358bcc0575c1f28bca1449bd67f68e27367518eeed469d70cbb9facfec6a5e1197b1900aaceda1ac121acf9beeb6e38e4597165c26834a9919682edc543ddd414e21b358e07aa55b565fb76bb2adfe44c91e8a50da5ced0f61a7200e12e1ca5f3954c7fa508d9cdda4918bb5d6adf3c4db06764426ddecec431f2a04a685c5203b050830bdf9312650d94b2c730b2d4c02ab37f85dac727177187b1db9d6acf3a559dce2cf81ea6013174704bd53a9447ae9951ab919b7bd73f0ba22071b982e0ce5082007baa1f818f0c4869ee6a2a3319bf3a5403cabe0241c360cfe605e80f10023edcf13e206f7bdcb97722c5b0077b6a7786c01164fa17226377613d1f3edbbd46abc4b0023f0a5df66555331ac098ae0f89df9b33ffd9a3a60521f5028abac8002f0110c7f26f8f3fa594147d5b37c5268164c30e752befab2900c380d703314f28649142c43e173fe0f01c8fb33ff79653f63b17258dc363a2e76f54d359798575c6fa3478df4c1203547c92f21b1af903f61783e935c5c316\n\nInput: 90d292ed54b063d1b606f02e330b185e3b59b97e0a3e49f0d78a66d927e5793e86921332d3cca0a4950d12d37ff6d472be4cbe50f01eb9395c333992c9c666a913cc752f0d8a59644f04f561826cc46a60a6b642c5550eab049029a62ca701beb96984b8687713ee0423e7aeb1d60e4571c7d78b58a94f474027f43943c00ca20b4d30291ead1bbdc720131af90add629aea2d75738bd7f16a9b14bb361bca3a415585071293df4bc8519b2324f5ce9253664e9db842d2af24b3a03494479107e77eecc00bd5941f00efc77f2035a47496837dda84f2f137e9e9e5126433c65cbf55a607216f8bdb0869b3e47f52df96a090f9255611297d7670210e94291f22300f0c3f6988c6d0819fd422931127cf166414c900150040e4685ac95606aa5698d66c3064ba1c501e32f6426649722cfa3e292508d73c269e2bc7ec67069600abdd5e5e922c2bb7d060f3a2701f7c\nSHA3-256: 882816d458de6b518b20b38357c978482313345c9a4b15a5ac857aec73de2d94\nSHA3-512: 13d1f2a2c33416897a12a09754d21be97078a96e442cfcb1a0ecb4d54856f8a3f400b510d5a23d50bab154353fd20fdf16d4cd70d0e241d4f5418b7ac2c07cfc\nSHAKE-128: 1a91f5ba5464187228ace9ab85604b601dc21604f4c7fbd6feaf8e40aa1e22241c875801c0dd24d1e942a994277df86c06e8b72013a1a35d30c850c3f28e8e1151a36f6bf9afbf8ee4997a50b28b6e0a17d705bf3106d2e25549b35a25523ebea2dc0eec4c8a2471e71b41e7ef224a836daeb2f95034dd97199e5ca03c62a7be05228ce67a800f3fd64a6fc38aeecd81b9784061e3f1742a455ae0554aa301f7d5c2c37ca56c8f36184c3847aeee0e6f7b0593bbc94a16f01d1bead64825e9bde2bed095ac48a4b48b91f509d9baeb851e07240781cb40e6cb160afff2800ed0912f64bdf90a9c3d8db9a3f457c64617fc0ca22d3beda6f56397bdda3a0bafbdb632e66596a33601022a3fad38ebafc1d7098df6250cebbeeac5c83e489edb38bde4dbd6a7c99f87c01e7d2067e36d6c76c3cfdbf334d5873ecf7b486f1e14d9b167627264105e6d5c115b7f5a95818915a6d92cab455a2555cc99d9f9a66b98979b282eb5a18622e5eb81e36c91cc8162a0ae90d4ae91178599c5216ec2a8731880b070c24899897e2f5459d7607c38e9df7f2ab5f1abb458d071057333d4259a2a03c2f75b14801f264caa7eadd86ccaccdfc275b66b7b7e7583866b1ac9f6c4f2018eb320f1ea1df77b0b79d66971cd87c8eb78b62bb6232d850ff4077422dc8aaf84c9c21acd7ec87a3dce87c97187f801d8adabf2946b2849f89c90ec59\nSHAKE-256: cdbc00ac59bb7f5a3debaf3a28842d0bed85287a4d835a179e84c32c9a04fb24f0cc018764850eb26838d00353cb7c94798d83b8cc97878dae9bbfe6690968bae614cf4094597ed25c622f926cda65557bca43fc2b11d5bdb1bc853a332d9837cb86d4334583010ad9610f87adb03634bed2077fc27ecdb2aababbfec0c71047455c50bad87aef23bd87616dbefed3af6c55fd73167baccf1cfaf8996d80b43068ec9902a085a34251d318f2302a8d0180115da333d1c82fbe7dfe33216443e8e8b5449f24bf6b788945a295ea03d4adbf2a313a72500f779666e5955a77004cc4b10179e70fb15bb9b51973568340dabcfef59f07917909e6b32b8be9be6ef8aef04f5bb1a36c25a41f9c44498eaa400a55e2f1d61791167c5ae21f762d905127cffe8a27cc3354564d7c48575e3d860113da9ed643fa7c85cab7a9f484919a82b5f61c520f2364652223902f8b2658673186548eb705639ed9bb21e8b3f5283839d958f570cc6f5c31507c3cac22177244f241235aaaf9383fda56bbf438c12ab31975ebfef8055f18c9d01866289fe5769beffcc5a6bf7ef943c3e7524bb8a6bc98964a8aa6d53c071f587759a93128c3c40dfeefdfccbd4e6f283bb98eacdcfa6f63ae214ac116ec5943b6105b878373703c62cba5777bbba3686459392be84dfc5f7dd8778d239879ea3d00181f83a5b6668d8d5492fd4f9d7c7fb00d80\n\nInput: 95a6fbfe81a870d114546048f04f143c205511d36c7e85dfe8297e0777069e5c94b6b591456db0b07198546fc10e7ba44714bba7a2f43bf606491b6e2c61edd71d8cdcd035be76e8f11263100d6cee4109472226b08cec9d68e384f3d86b205466bbf1a95373a32e8665016c376bcd94dbcf1ab75195abbc08fd1d2971a0fdc4b70be9bd2a1b0f6eb283c277bcb6bf29a9d7252730b76dbbfab62854b24e1e2fae393da84050ff98184637c4772fe7dda52d7babc215297aa43ee155459b1500f1a56029e3769f93b72e20fe861e59411947ca0a44eaa91b413575f58312f4223380939cd742bbf346da7939338e0a3293e982e8b988c7995e1c3353efb2de93ba02d313e0d6f16e7624c98287631dcc130072944d79836a2f3cf4c95bedd81303b530cbda8914f168ed93f74a16a7ff3ab6df6cd354427203892dcf33098b8bb17a807fe14ac0e3946fefa9caaf9d09\nSHA3-256: 7ea96818cbcaff6e7f9a3307b1a051a16e1b4be242c0d7660f24c4a9dea4b5db\nSHA3-512: f45b206fd2111bb8f9aa316d659d54f6a4d9b882527132a03938b6457888dc3ad7af4f838c9461c1a5b3004899f8b17ee58123cb9fffb8eed8e282b421ee1c00\nSHAKE-128: 35fb2070e824ffe85b5c52b49711e6324c4078ae11ae5c6af95c1ebe21f7726e72bb378c66fb1e6feb08254884f598a6a4fc2f5aa471efc26c3fd320e1b1ff6ab7da88384467003fb56799c7", + "83f512ff2069a9817b1f9067056481a053d0d199497e29e4d6e99592b1d9ff3970e16a47902565636f1d049b47bfe6c247f4d9636b41336feaa6983a737dd901617961f1cd4f3fe9af5d0b38716f9d9f5d2539755ea06cb5cb8737560ecb3526dbfce41a6fca9533fd26895d855a1df5351ed5d0b45df176f7eeaf5949362ec987cc13627bda9a89916571984acebb0329cd06bd92c4b1d453b3607c24c9136f50b404838b1815f9c6b700600d9078a9576b4494d9462016409754bc3bcd682068c169b1419a3ca86a15a000439ee7ecc7f5975f88935d139689654218e44b5957952c3f3a9d983ad06143dc3fad7c38d00a003556104623d89d9816b54a14ff2942f46b97203bb8be485bc967d774dee58c9fd295fec98867ebc45240daff66425e2b4cd671d2f0f6932bfdc9fba5f590fe56144f76f669903fcd79cd2e6b6dd5ffe3031716415a1226dd873429ec5a44f2af7af5a425ce8e729359c48a07a096b6d552747cb06fa1acb66afd69035f89a44a0bc846af2f208ab1a35d79af22f1894770e3516db7dc51587c8e1e216ec3e194e7828fae258330ca182250782d0d1d3061927bf78acfb4276c8b8bc8548f123d8d\nSHAKE-256: 153deecfb74084cc75d54714ab2438a33d067e943f9df46cb868697d9dce1fab762427806d2a73aef78dee77e410bebe21d5669223e8c6d6ac209b8d17f81f4578fc1af7e94b7c29848b0d21d53589f9fba93b317a522a278856b6512c742579e59079c705c833d7f61561f1b5bed4bbc6cf0f0c28e1a59d5e93513f860adce944a9d060ea3eb1de4aacdf1e519a507cc9abb116f56af00d57fffd2bb480106e9347ca42c4bacfb5799b6c8219b4f158630834728e003337944831a5d04f6e11101a3461a32af2cc15dde808b100fec839759b569f412e77a095dcbc9825ff45861576e8ab1cd5f9dfb906296ad713259e67150a62b46182f3372e5ed16a4ad0551a344398f8fcae9268a95c6683e0b317aa6ac6648861f74366885ba05d8a546ecc219397148791925c603985d3aa911e221966dcdf2f53ac3379ed2f0d5a614d1143a2dd0ee6f1ff96fbc4cc89dcfacaa070186c21a1e3b570572ba4dd8bbfd38f2756266b95d22dd2fca8f9cf8ec4ab84fd3ebb4c97435934afc2a9237e7d86ee37741ea07adf3a2259a027c6d037d0d1a16d0c4405e9453b366b8b55b69be857329bcf3c4f694654398d4794c26e047f2f2ad1d5088b4067e1f42bacc5a28bc8de2fbc584ca17eea4a5f2464b3821fb69f1d70cbe4280f59bae8ea827cb2224330022a1e1ff153e36fcabdd43ac2acfef3f1b82bfad11f80d13d05e5bbba\n\nInput: c7a0713f693eb301685dbc245b22fb5eca34681d54909847f950b7fa45d42301f9d61b97d6a40cfea74b3b3f255f208068e87e8a18295f854aeacd264cfa7b3b495204075798b48ec1cb5c29211a77dfd75537efe03fc65267ee819eb0d766e72667d50c38764ab07ec67bdd21a9736a6bbe0cb9d5a8f87d73b0dee330ed8614e4f4955a408d490bf182d5eb6fbb5b041635769c40246a86272b85f5d64429b7067252643c7cb438e0a6bf4c0b5a1369879e2a27aa79ac660b524aed776f404b451faf1d3a32b2507fa34f875021e7ba96ed1c3a1130b91c553a3cd4080c725690e732fe8bb86db55b194197dc6d3276a6f1fec02b177b2414a769d87fbf4ea1fb2c3c597848d2d1e33aa5b4f55f8e33b37b0a28d963cbecffa41d2138db191411e7b6af9408ae59a77386e2581fc1e9b196a1505d82766b5bed1b1793f54af13fce56bb7d091076efd884270b18f9c144\nSHA3-256: d9fbdfd7c7c8eb34c094a5385e92fdaa230e017f7e9dcaf97ae4d08efba3dff1\nSHA3-512: d94d058cc3702832704ee2e258c2e9b19dd60654b53ab174249425aefae37233b358148da09bfb0a7fbd219b1df2f1aea55f66e9fb2f6d4c66c105823fc2029d\nSHAKE-128: 74cf31f7b34ef2bebc394b8c0b8ceaa0498787dc455b7f8679a1cbed8fe3b45ef84e349e0becba371a0d18d32b6120a0492b37b4669add7b04e50f8e10b69e765cc6562662248c523ffc330e77d92754e92e204e3e5cfcc6c95c359dd5cad459be0b4b2d3dc6de446df55be27077276d1727b89f2cf3d6fd9fb1edd2328f15ef7d7e17c654f51d8b0f01731120fd66a669ae8216b32e861f5995e0ccf54d174b1ab71ca0dab30f217413e15c500541d409e9ec3c375c15c91b3ead06a16a64d8ce70ae7e0a8de82e51118243e5b02a9b5953bfd4f85f57eb4edf00eff6ed2a90a5265a0f5980e924711f77c61b80378c89ee1a944296a1efcf8029e8d35fb82c56ecb6646cd6709c57fc88288a3c1843167cfe61ec1a26b4c565240a3fdfa36ed8cc1c64c77c4e4640b938865c06973cff99b981baffafc112b4a3adebce1cf4d17a8bca9669756ff3f4e3a353cc383428894fe707c38c39823886e0db165f696ac78a3aef49fe655b08b51928c1bfec35da79ee7f8cbac35cd819335ed41b0000ea9388641900d8f973858292688af25402db491f32d0e97c20b4392523e6ee6ebf3ec65f80bf447c3a4dcf3735507fa5fdb2b741dd864ec4d25ac1a954e38b19141fd49445e5f9c1604a671a83c98aff842c69711eb4c7429dce2210005a844d2d364995a84e7ba4e6339e545cf073ec4713f5d9d1b59ee52c3bace58071f0\nSHAKE-256: 5452d3653a1e86c95efe73edbd75518aaa3887a68dbe2e3cbf13fbf44ea51ec58a9a273d3d53d4aec5096b599a56c0fb00faae80a3a08e16aaa98e72251f638360bc0793404d54be7375db7ea46494b8b073a204a2187d9cdef127992e936c6c60ef12152141c48eedcc421ff0daf26a85248c0c99e7f39d01c36df837ee40e086a9facdd3a04bfdddd45e681948e028efe31886cb86c7a155127cafbccc44b51f9522f6b5663c77d9e9489877aa840a2f649e535d07d103c0767b10618ac5efec3a2502640c5482915748c3aadc71c72974f41681de30722ba12cc20f11ca4217928b5f887f36cf073fe4076d65adda37abbbbbbc90b401a4e8c37163579b88831e77c8e43a301f95918ab70d1b2a7b80737c1eb9651321aaa9344e9184f125bc2792773fe397cc48dbf795b89c82e9ebd60a80b4367d63c16709622bb90484c84f9155b707e38906aed6522d4991e834ad89c446cdd0094a736419f3917ac91b0bd606042e8462fac53277f19a5eb425274466cb4e7e6cc3c540333267e16145d93d59046de08ded93b3662bb49446ab35c8d4cf236251ce4335be9bf7f57a3ed4bdb736289b5e30f4cc4e33dafb7ac113534fe8b68df69c5a5b092572481cf1ae758972494f1f2702f475c375cd91c7ee589e1cf4a32199e7653cd2191b3ba4a69ef5d82d265faf03ed8d0b26b794365cc4d6c5c14c99aa5b4630806a89a0\n\nInput: 7794f72543ac73011f9e65ba1a4330643ceaa90bcb5cdbbd9d3770d05250fa82c982ad38c33bae338c7e34d813934fad5dc5fc626eebc149ac95ca5ae7e2320cbd41227e2ce010096d1c00764955e029ccc2665997b1b5b3a39ef90400766c2b4b3b42c9952fcff6471445328f1404dc05c021896f5dc59b71eefdc593e62f9066f3b2247e88cafec228d49c111fffbc8162f9f3528a7ac4101a7eaa117f247f8a564b91c85126619795c781ce0496a17ffd04b8db0cb579c7e60cc590619ddfe6c113a129df815697498c9c6f753549a795858cee7f46b1064eff5a53a15dcdbc3cdfc457968070988382b56c4570f6f761f56d2576c270eb2eeab5f9727fd60ebf48850a1206da02c0624c519e472b6cb139431167fe6d6fddfb517ce84de1e5991bc697a2bd2da3beb037884d3f48ce130eeef37f8b857fb32003683ee25d51a8cc88a14b2a270eee8611e0ebe687aea1\nSHA3-256: 54b41aab4506ebf41442c4413ecae5719f2b9e6c1eeb6d31104ce96935c84cd4\nSHA3-512: 565008baa6f93bfa782a23c0b29572429a569e4fa4c9c909d400253b6e6de47d35f0065330a25722127933a2183b42389081c576e823088d9dcaec91e0ca0781\nSHAKE-128: 1243c718671c6908324b8d30894b8f2730f9f060f17472ffdea4ad2da52f8fdcff08670cf45180caa8719b474d2c5d4b201df9768537684a5a6b5d1eab5eb710ea7c169d8c82ab7f54219e5ad1c5350abc98d2a21c6af0514ac28bea776f97c4015d2fc8440be3a7d4f9a8cdbeb74926ae7b3464e0d72292f88e15c6006ffb42bbc3b858a7e7e8f20cce405d75ae42a94a2cf12bd3af4dbbc87d0be235e87cf5c6a6f0216b82bd75e66ec46b1a6c8bf07431485523d8f95e590845f4f8a7ecc977c4f25733189d0e03a7ef77c1255e2bf82753773742501ee2256c14992aba8fba7b417db7f12faf719ac23271f0c3c719fdceae827de3867b87d61a36d5cc1617bb4fb77714fc4a74e7a271256d33bcb0c32a8514a163ad093a996497f5333daf23980db72eacfda73a763ddfb5b1efb621c0553382e54220c61a3e6d8eed9cfa850d8791e3883101ccfeccf24ad26fbfc98b608b79685a8d2ddb81d6fbe823458d79798e69f2336ce9b8e2f03ef7f5b98e31a26c1d03aa35e264d199de5c2701040fe01ffb3b766956afec1e8114432c463656f8c35ba6da9c5c4fce14be134ecf5522482045016341cc57e4ee85a03fc48a9ce78c29c28435455b2a7eb55d9810fea1dd783898c786a1bd38b2cd7602e712ce221558a749bc707c28a912eb8f16d672c07a125dc46999a046d1db6a83202919cb9bc4176437498514c2170a\nSHAKE-256: fcbe62a68cf8b5dd36068152fbc6625d14f825fb3f2a4aa863ebb216d1cb384f6e560907edbd30586d90de49f97a6aab13424b0d78c34c307932aac6c8b0e2870c1bb2055e583d7e1cf8c5fa8704bf81aef81ccf0b236322cf6e9fd81afc55747199446aa2ede7cb9572a516a92b81e149868dec06c2803e93dd9b68d8c4f64d969fa77ac2985b6ee0411c2caf19753e10ff44293dbdb7ab03a6681927759c553c477fc0e0dacbff82dd1a2c8efff1d90e5297d95717d590595070ddb61855e9531a4797d600a735fbb4401e7400cf5b16c179a57190e295d59ad541d22ac993624f6c477cb4de764c7a921b71e35c0350227d5425613d9bda3ee35045cc3b7ad7d0131ee96e277668566a60b55709f063dace907db8bdb75560c61e7186ec9e5e6f0fb672a904510bc178f84251cf372ea26f25d5d4b979c22eccba9e6d45feb38f7762706abfd15b6fb45f05cb72e0f2556dd10598d65e75be6089c1fa1ab2f17c379e49de8429c34186284e3abeb0482b5681e441423416e84db3f7e2fc881fa491733906bdcf891aad460db85eefe3b3782a803c6269675951661060673ca2dea5d1ea9eab42d10822410f6e7ad0246ca195c167bba159bea2f1703484acd05b88e41534a572dec23e112be55ee5f6fa657bc391b4947415bd3cc2fdeec39d9db2722699b531494ee3d6f61af6b3a8ac5bfbe4281eca6e97d3948f35eb3a\n\nInput: fb7b0094f50c281b81a2651e6c66c915dc467e179ad5670981cbf1db39dbb1beb62450106db2c0f472369fc8ddbc0322625ab4771d7f702b0c8b641c7538692c631f1037aabe1f74c25ecdde0702c9723130c624fc2d11ec5bd04680f950a9747c2709e685814a9b8fa28c256f1a2df6120c0fb08c08716bd53454390b9e3e90c28bfa0fd4fa69bf5e61a9249ea265d365905b797c104bc3e829d5fcd3197d62a389ba0cbadab42", + "2f5d2c32e9b61ba9147143925f668dad1477e1bcb7ac7d48f1cee162e53965b5623ffaa97b180deb0a274be11cdf59e7bc25377ece1811322d2943626ae4cb9a7ef303e59fa98593a30d1759e84c2f7ba0cc374dd46208b42e9f1264923ad2199a85a2766a9a0c14a5929d337b5f59e1bd4a87f477922db0eade993889f1b8ca64f570b29438db7f4cd385de432c038bb8622111e6da91ae2a24cb84044c54c68d19ce2cb083df06561274a\nSHA3-256: cde2fff0d26c119b17be046fb7b34a89effd445d6c6dcd072e040609805e3a0a\nSHA3-512: 534be649085cf9fa56c0a6407aa8cbc75163695ec693c871560bdf365c2ca37f82ea543d5f504f7b696a8f4330b739d14bba2321b18bc3b4835305301bc2c559\nSHAKE-128: 61c0fdcb6c331b110e8ab65fb664a7f3080a031251b1bfbc2648603c1368f6ca36a999a3b328a260b4295cbdf995747fe7a696474d8a241fd76b535e538ea1d1f98e92d7175a8b6983a6aaa3ea9304eecc60b111871c8a4dc1ad0df6f4c7ec8b2501b7b206265bb367466a161b2524dc39d5097df8ac84d74566e3059dc64c945baef1f358fb4e391674cc6008e966536d4add5a5e34a967101720471a1b87b18386aed4c633e46e6d3e6c123e9a8e3d860d6063cf0856073fedd29d502f983c502bc3fce558d0c62b15960ddf43aaad8cb7a6c8abc28cefa32e56f2550513fb6139176fb7446281a01c4f14eb3a80be9002410af6447f8e88c1c3f58f9e9682baa441977bcd3b78e070046fd5fd161f52eb3294d379fddce657ec4cf61d4aa6d55b956a84624a027d1e18b3d5259a1a8710f0ae65255f909640605e0bf91ab2f747f1db1a38bca9979a525f54ddbc0f8dbcf6660c654401476a5a5bbf63f3e800eabfea871b56f57df6324431c96bf970da44ce24c29cbfecea256c430937e6d8786e3cbdb2bc7e4660640a71577c0bfea1de1528ab0fd757c4dedc2dad94dbd056f1b3f09a40fd9d041b9e7a94776908c12527c9cde1a4db520bb49cfa8f17cb8535582303083e2ed85064ffb9f90d878c64824c6c145bbafac8886147d50b9125adb7592dbf646d8e74e38c38e5ac6807dbeb93690af629777d22007eaae7\nSHAKE-256: 94e9f65be1266f0a6c4b98dfbf9f9a960a792bf570e500a7184c6bc78385b1cbae8eec915eb9bfc319109b8f378f01e06ad1ed7999580f813957a157fec005e95099c5bd8a0ee0bda386188cfb0fa4f12473b45a5721ef285f608a47d667e08888d245638cf2f8f88d668f50b9d41da8f085802d1d31881b725205f73ce31029593d96d875bd00e5d981bf559e44fda90b16d49c7f5ce18baf605666667e813bbf0fdd0d26ea1a6d6f490ae213392c443290122c36471045399650266ecc90b57e8704259834e92ebedef651393bb9087b3439445eda22649bf9f74307649935822c3bc246090b539a50f1f4f46bdb5c480bec961dd6781f2d7ef8ec71299d89d87fa61798f491ff6699014ef3166f592932c3eaaf979774da00170c2a90d7bd2ac132678a46ebbe6d96f7329d51109bee6aa76121d5f3a1348d1cc81aa972c19ae914c7c0de62f3673a22ef6080afca08691f5e5e3c84e6e6bf1aed01dea503e857bf8cfa006e672d7f866c7af7b7d2d9ed51f1db40b90b62a25ecbc27b1174fe5eff37fd8544b8ec3d63bcbb862ec1bd7a77116ef5ee433a1448e6649b8b580b06d5a1675608fb5b89e4495e7175881a5aed0e3c4869db2e04076258b3a7aed5a529dba5420054213b355afc7cf0a3f39b0aa3bd2329d81961fe6921ca02dd68494d57ca5a51ab849230486368594f64a253c1bd2f0e0911031c15d4fcc3ee\n\nInput: af4291ff05cd1dbe1b80cf378325d5c62a53872ade8480a991c641b3076d291fd46f34349045f606d40769cd10e113d4c7583a8c12000110ba91945ee6805df957ef782565f313a299eff9c7a780666c9c42551af910f68c24beee6e74a8bfed6706584a73a482b54ebab1dba45c742e1af40dc296b7eba66278f853f081452284e29183dd1bc4efaf07d1dd9676344c72cbfa4be91dd22fa88f6befb96756b750718f22f74e9ba996b3dba0f7889be697e34d098183cdc7aec1fcc3d6f6600089bf290d6ddfbb59d3b4443a85a6970df51a6e2a4374f90a54d7f99e6df4663cc7de789149d5aae272203e0819a28b43099035638a080ae2938c7fa8700680bcc72c8360b7288b131fa04e87f5feb07ebb254a17f0fce26cc3d191cf1457e7e50d09b4143f652b1e69aab0f1257e5d9155b2959bda4692f2ff8ee8c9ce0eaa6d4044afac2ee01137fcd4903adb21597d2fd17012\nSHA3-256: 577065e0783e4bb3328af3ff6241da6d88ad94b43906081d518c67ff4fa5b70b\nSHA3-512: 7bf542c6d00529907e5d789ad098d166a0d15fb5c46d7913314e30c2ffa968f9edb2c7d140caaa4ccf22f5e5915e6021831740b4aa45b39ed6abe8e38518e73e\nSHAKE-128: dd9964cc58d88c6cf3889833af45d068f4f940a7e75ea7c3b976e642a21010ec73b6d8b0cb9950988265ba0556e13090bc578add588b79e4651183dbaa92695b3d3023c6590ad019afb07a72d33b0358f88b3eb460b9927e935a2a211b6a0ab2cb700c3a66be415d03b7babbb3642cf9ad4e0421092fd7d8e435f30f781dba9af30e76735d116de9fc96d7db1c03e8bc8dbb1de50986a396c62b4914287adf0000b652a0bb9e7aa82add02e9b9bd57c202791b44b1348d05bcf99c89a04b1c31a6ca1a24e59721596551362076407ae8cfb37fc860ad7374792d892e41fe590fdfef40e693b2cb9235973ebe2c71d57672e177eef20a7e60852f77cf00e37c7af070e2a00aa9188e833205cfae4507980066aecef01c53a0e80c070f5d1e84802db4565c03f8afd3b1d2d91803ae995019b16aac2d7fb108a9ecba8626be6bfa4e9fe77586e12558a22c8398075035a6f758d449b44d44f6a7f85c9a881fe93078726f5cd3098268e506838f0112cca4ae455ba209704510a8f02cec7f970470c220425720f19d225b5182665e40330a2351647ef9728f0af679bbce0cf81825676b4dabbf8ae95756af1909feb0e813478f56f5f40c8314629ad29f86fe9dad63cc9b0dfc8bfde915b2f91768fe3dae7a46bd6495433ed4394a85507d70b0bdd0cccc569e130134ea598c1c32247b2eea2fc799e24b228729a1c1354e0ff2d7\nSHAKE-256: be08144a3fabd93c6262924da03b1866a5751560af0eb21501fff4423bf9a5e94de42b9eb95eccab1169c88430ea9f60f05fa2b81c277cffcec815462990baf5266e64cc93b02b167941ee5ede5e507de05f3ba58508e47bb7c6260ffa089bc7b5ede76dc389f731585dad489a6f805597365acdfcb03a1b119559ebc1543233172ede172e3ae91d76bb65a72beb8cb75768f4e2f40eae585b677c3c24812f7176e508be999d038615e3d01706b9e6341618e574b4c453f9f2ff64a59425ebbb617aa5361aa4b2b50704051b69934de8f016cc6de064f4567c38dc20ee24b9948aa1a20eb57ce0b01876bba3037c325ce9e8d472a977026660087ee44019f2e9f93c9c139f855f2e72f58f8b4b03a441e6f8c731af826185a837c4690cba2871cc284a1098d296715dc1fc3144cb30d3f4fba2f54e12b38345695d822465da406ece9a0d0e35db02493c55831e7938cacc1864f78102f0794548156d70cca48bf7eb831cfdc4cdd4f43ac1c5f13d8516c5de5c2f3677686e5b598f448721cb7e301096c0014e5e57bc2db3d4676f9ce366e2c57ceb3beac22b59606610caf134f84a8e5f4c83d3e591bbde4e7ff03c045b883b035a7b003eb8b586cb06ca070dc67b0d3266235a4eacb76211f383551564d143fc142010ba8364f354fbfac8b24edc7355a6410059cfb2eb16c3022406a8a9c2b95d7e6e1df42abe50900e3ba4\n\nInput: b927f3edddc9724152a3419828b43eea97fe0f7a523db33e217c5cc898c1b48979ac36a97d9d0f3feaeaf776252377a0f9e1e3460581442a23b737dc36acf704ae098d02a32e021e0379abe4056cf3630d97c95e457f00b334f4e1f90dbb3cf6aaca8cbf865cdafc4a8de021017477fac4f09813e553a8d853b4c86dfdbacc2c955051148248e06ce9b48c8259c4d747b094cccc28142d7668c69e88844a0f45ac6cda78d5a3ed8432ccff2e2c944067318e7d21af0ab4115a62a5cc89183f1088ea4d15024ea93629e3bcad347be8e1691aaa76c52f9c0582eb71ef8d6eee2bf03987c5725e58b4ec0ec91823019815c61309de1b30c64f8cdc0092224c395fc827657be3f48647acb2c4423e58b9f9c985f62decce7f19f7bb67e737ac88ad513dba8f876df1b6a6f9ab6b34fb8b5438bee59cc9342473ae35063978d008a8a90d3b04d35ebf5db7da5e990b88156db3d5b10e37\nSHA3-256: 87f9b8463964bfc3a30ad91ec1c8858dd356a1cb9d8c14e2b71da6f9eb599d40\nSHA3-512: c37aa982b40c25a6f0082ebcbb88bb7a3ed098c3697d4efb7623260417e4a84025f9905189b36b69081646fa89c6b9168e89e1f2a25d123f77b4ac163f5dcc0c\nSHAKE-128: 391deae3b6da5ffd593319a700e2e517fe6b6a690c5f1739f18b9f39244118cddf02bdb8cf27c6125015facfe5118fd32bdefdbfd7b572e0e59a842a05a75da0b84265fce402a7f34c0e8e951793e9fa7d9616252f45897c4c264ba8acd7ffa54fb0802926f331899c18e9dbde6122fb441636fb63ad25d275f8aa2a4b84e62e2ccc60f3c3a11db2e1aa2d63a249907701795e49d82b3983dac7ddc5cddc567e421091a6715b1a8d763b964a7f2c1566392fdf44d00f59a5902d13b62605e75a1c9ba8559c1bed7500870ef4dd0b35678fcb932e2063052dc6c6c4b512e9c0815ff7e184add20103776d8cb67e1a208022e357e7caa5a88fc1f041294c160a9d4bb418872f6f9dec402071d4b19051a30459ce1f8ef768cf5190682d12b83af766a69812872ffd326afd7152a0f794b55b173d12111bb609c0a40b30447050dec34cc6adb6c1513268f7c466bf8610c5c4737a2b54c92404a6cc36475fa3b0da139e67b840b5ce46eac7c21dcac6f6926af5cbae75a6c3babdfb7e0b4109d893a01a99cbd518bfaf14eb90122cdfa51d573e33c39720e9c5e5fa6c7853750bcec32f2ab87c6303f417a320b41d1bb1db1b663778de06cf7c72e00e42b2229df4ec14b79167e69c78027f0f861904aef240f5e47ea4742249b4784818075ad464df562d12df5003b8a53a2aabcca2936db08e17c5351590aca4af1f961abb1317\nSHAKE-256: 220ff2fd6589543431cc7f5120e94e9d1f59368b6eba1893b6f737d63fcf264739628a403cea4fad44466f75bbc3b60b218d3a65f2cc821281ba090adeb2699275bb699521ba298f53a16193be9d55e7f12105d17e403bdada98086c37ba2be92c33032745403104c3b52c7da70b6700b5274f42ac392404a6d1c3729f64c88a608f129480dcf7f784d1b83f0b832b975b34109fa1edda8b70f4acf38b6cd307e2bb6de8d16351400a98038c4b36f6487454a5b0c6c2d7796f432021c345f41c77407d515e103cc777f6be9769fa33b9901e0b4e951e64008317ec7207aef10c240f36fb6b466a953f8d208f470fed19206dd02af12c4fe996b25f47b69689f3397b25e8fb5adf220cabcb4f0de96446995fb7834cc6ea390f3ee8996d7cd156171adce25bcc8de56dcaea7bc551ac40b1277ae94a27717b1f0c42048c2", + "6f902f604f2d9e1b6efae38c135474cd89789f1e46e595ff3af2c2c075b52a6e09f19b0db9afce4431f99046f69137ad1e21642fb425596ca5e17c5a4dc0d43db7878873868ee9ad0ee9eff229302965c215c539cb2045f9fe2e16a5912e20ecd9a9e51e97cf9caf238104b037398009726331467f1290c746f7b5361ed6a439fb8572dc3ad893dfed025e977c482f2888e59b312754cdc74213b0aae29608f06bfd6ea397c254cefb4dff4b21942ca5d7bacf867e4bf0cbf3eebd3bc0842e4904cf9\n\nInput: a0d634a847faa5539ba5d8a6fbaa9bb08764a7ed9867f25593032b1318757a5a69e53e412c3d3b600728df9de025a0d07317c40fde0df05c7ae67a98e3623540aa49c07a7afe070be3d3e5ecf59a4ff04a06696ea79c231eb7d9f89a66b2d180c5cb7afec32a7c4911d8e9992ab89f443548acc2b6fbcd96fce368be49cdac2eb66d2ceaf5e44895d494e30a452d83efbdb33dc983c109972a612b861f03678a1b3a4b33e2dbd6eae1c60641daac3b68589330efa1f0476bb886c04f7766c2ed2f49a9d6951f0feb6b2c6c09f91f8950dc622d821b235d6460cda6ad1b8ae87da7e2ec32f1d750ccb5013a424514271eb92d0bc91ec86533abb422a0701ca829fc04cf6a35dd961f40bc3f1ff24de6912acaf9cf8fcc533f6c8a1919be011f50f5610f7410a794628b2cd96001e124aa0ccb405996ac5c7224e7b11c9da82807d534f7cac2743e467490ba697b3a975d25f1b869e099\nSHA3-256: 410227df0e70469fa7cd6c1c154e49eed3237fe0fbee7337c02ad9f1d92d3932\nSHA3-512: 8a450f2b8647e89f59717b45748c5858ddd1f33575940d561ae812feeb3e7577b973e2f330731f22b631d410602070fcff7ea5cd94c10df2d3986b878ac2fdbf\nSHAKE-128: 04e575cc692a2177232b99ddc65824cbd21b5edab084cc054292800a02bc94ed420c0231aa9e9ef911e3df2a37ce201e120bec879785da304975bcdcd6f44675cee82f58b97eb2198d5b299df7f7e6e1cfc95034a844080a6980c0bb0f3bebf355af30b7366c7e52b3ba93b335cf6162493e7e071866a95fbc7fd4229d2b03f22d47c75c23d94b18cd939f2f96a542bca08deeaed2b7fe25d7f3bdf62914ba2f920701ceadc111f9b310a551256f927048393ce57e60fcd880850f8ef2f93e4c6e348f335967de41c31ba4183acb4dcc18f606ad22d6889375fe614e8f8a7c35896f2997812440f6075ab0c8ea28c6420f5bb55770ba56f29fb4841129ffe5e589bde701d5e93c5c7a79c8a2762d1436191c7c59518ec67bcb52190dd4ea5fb5d42d0260e67cfa9e35066447f5a91c8c9106d5a1e78323c34714263fc051ae2488a316b4bd2e2871c30f7e5ec7261d6ee244473f296bd12e62008e6aaf0b97fac882a3ecd44a31c126d10310b4d7218132b823fd6c439f1a84958f2f5a51f7f233b45dced977de853a00f31418db6996cbf29acd2c16744975092dd3302ba26b4660ae46ae1cf65b59f765ab3bd5322ca678493df56a5d8552838e164af681004d1fb4615ca57d0c7326d48e0c025b830c0a8c536657f517fb28cacea09c020f3e34d7b5634f8710e59bb917fccf75d6e2de1f892f1a2c7f92936193dda48474\nSHAKE-256: 0415c21f8079a4a81bd64a78d1306dc682bed6af53fa431fc44db1097024a503dc2f2f842595ee6fda2ab47d26aedad809bb7a8787cb5c7e999ccbc6ff1b0087707eb01a567b357384971e62a350cf6facf6fee335e3b999c36ecb4f9130d9534000b6dc6da3addb8f4e93fa4f09429b52689ed83aed9d46df0c2202c39a6520784132c02e6e5333541e1a16e0462a8ec257e0428fcc9fb4347a24ac7c10b6db1ad1e08c32e5519a170cbb78c25dcd0e21b3423c1268ce39055a79ddd7ed9fb63066fa160034461554b349276ae667851a8cd9e322be5da4eddbc1a312679076c46c19ad2c9399026479ac11a589da2b33ecf073121c1e2aec87baa6824e443183da038e3039beb3beccc33f3cdef375990f7896693b8e7508ce68c2ba8d0de867151fdf9af940f5a35e10dbaf41a8b7f66157206d474938b66bb80939872497aa52686f48bb189754039f68881f965834050f971b24d7e11b6a050eaea4bd7dadb8aca75d0e88ed6545cb645674e7f0dbb542a65086cf09cc76e44b36fe3736b07cf796159965e2825a99bd7fd709cc232696c4a9c8b4a74650537429ef13d7712d6bb3209f822d7a7849508e339f3f4fa57855f970fa01b0c58a3f50ceeb7473dd829d5badee3e9b0c6f8ff3c7a2605bd663d43cf80a236caf245eaa43676342de7561e22fb9b40cc9de41ed6aafbc3b6fdc807ea481ab7a14b9440cfb991a\n\nInput: f121fe4fe376ce93491f66c13ef89f95a247363033e055bc49c371a3e5ebc3108177457b06c095cc6b09768133e9659bf11e21bae40a1716620fbbb612e912efc24d2cfcdacdb4bd5d199ca040967ead8d5e816b5f71d9428b613a2fa870e6356a6fb201cfae0b3e1116e88317a35da80739c6f9f1f07b9ebacbe5c6cfa8f1f94fcb696bd8c8cd45989b66b4e61cab86a5f2fb106deae2b526ba0f2fbad01b456ff543f48c4639875eaaa287b5f0d6f963a1e312f66f3188f8f43bb983af0467422421c96d6806f1b188af1336813d44b595d91dadc013f891dca69b390374ed76be354fa46179786e95aedb549feb89aff468f0603e8d3ca50972e1f5d5065d1ef79d511d82df0c740adb9ce419713e561b6c4a7b3fa94b72234fd194c2db42a7a10e68cbd2de23fa9c1bf94aa5e477f1a2489b67cb2dcb4cbfab465e8a3e0a1d0b3ea742377308e347a840a036bca7861b7cd5b37732\nSHA3-256: 6818a2f2f72fc5737806eadee03f9ee133dfa6d0ce8bc8d4c9def4d73422eaae\nSHA3-512: ec7b479dabc10c94e0c0722b5004163f0efd15359aa1f2d56bff4b7e5e8a2f1808f974e4de24029439a3c8b99e99ea1dd92dc2d1d8c32a7f6fc416edf2fe5cd7\nSHAKE-128: 8ef9e9b8dad444121b088b27cbaf83999bb232f406049a39c4a4fd3481d7458c370e211cdafeb74a688fc613f62291c598626cb7f477040d2f375fac6eced66c2e7bae633f0ffc3a18ceb32416790873a8a34bbe4761bc40d44e69125361de9e5b396d35f6809b52bb643f8a010d8b8591fd3a0405d052f8a0484165ef5c81837ca44941e4f3f0d820b1b44ed8a628630ddf7c15ca49347ec8309d49cd9f9dd4ec63bf97aed04111fa50286ed897587338613d5ab88c6a8f4f474a5453eb092ae279685fbf4f52fb68abd005bf0586e1a2edec09ea7e70cd4006b02c6256a00d47b7f644dc8a591d8731d77fa116b0045cccc247496b687309334b35db7a905f2ecc67001081d76708ab8ebfcdecbf1a8c77a64e4bf9ffcf6d19f4ea9200ff19193f8aecdb73c2a11fe6da875a3e14d2e3b44566cbeaad3d1f2eef16eb0b168103b30306f0fbaeb942eb67182723a333bfd05dfc2a2994ed42c9a39eaffa210f7d2bb46425881687b08733310b4dad5a3244f4cf29a13497ee6a8913f901756bddd1f4f0193df644a99052c7d14f32a94558f10d4979493cdea21021ec930118119ea3e122b34e7ecdab755c34a690f7f77b3bc6f2f03552a8fb66bd794d617ce00e0f0675394718d60e80e9fca97d2b22b66fce6a7ee94dc25478477a2bd914d5d3789d8c99d98ef6480d82939465f2ab0b5d69d13e9e58361d3a078d4d23ee\nSHAKE-256: 0f290efd94d212b9e9368840055cf65f235554ae86c848d926f6e133a84d672f180d4ccb2652d34484a018ab9b6861d13e663c45ca139daca7869599765b0ca5c6960bab022f81ab316dc98b00a1636c240ea4a40bc9924a187e7bdd99624b72fbc1b2c194fa8a54f83116b41732c1c75ec51947cbddc5bd0d6c787d0bb29879794cbd0f1d59b19075adf47e2c877c3c3786d86b66d2509f71f1585597b37c8949434642694313f3bc7c0f90732662e62bd73663848c274403f55862acb3eef31a5e13d8b73aee88686a2d4c8bf4c40b5e8c08cf7d04ff157b133e63a7097ae6c38fd470d698eb326b8290d6cad0e6d7e26d28d75a59e4336892c5a3661f08fb3549949854a0e48b0582695d16fec512a74257b5f49b1e8f57c414685d495528b50674605d65cb22515d545964c810318cf2aaf591f6edbd5937927f1acc7e7b1522eee7178963ce0b49fab472b039f5668d7c3e5327bf5395991c777a77485176ce414aa307aab79817f26bec5f71bb874e54842597f347d0801bd90463bd27b45bb3763678b06a6016e6b0b1b37990f68e71d6a3173ff5f7927b4d2822d82a372e1544c019683cdbf13a78a71cf87e9c388ee22a5ddbca42187951ae886786b76a2139c8ccc39ecbf7a7c185926828dd5edfa72739dd0d796e2f04bf1c0e98a4908501ea612393ee9bb88fcdbbddc2661bdbce17c84ac5a398b79fa100e350\n\nInput: cc1b0b75acf83c3c8f8085f81bcb986ad336d5295b599490180e0bb8deacd47c990a65e698830348aa42727e5dbf7f7162bb4d31b4fa3331b111ed278d3c59d3f669d646ca7e419393e856b1bd13bf8cd7695d45ef410b69bd53d3f1179510d1b3fa207f31b2f35e1354ccf2072669e030cc8d57a2937c3dffc29fa4452fd99cb149573d7a821a67d748b8428cdad11c9599f493860abbb50bf86594c1b51b5d8ad9864a154220fbfdf063eaae765a98851d38c22e645dedd58d9c2753e47812110a375a07786f4a3c1d81f36bb2e9d176aaef75cb6c2179474ce64f06090047dc41ff58feab7af81b06ad73afcec22dea22d3ec706ac3cf4a47d089db6130f0b05893e5347759f082d8e026652f2cd5813446bbf502b8a6ec0f4db255006ab9cd7a659dfa33f370805667bc2cfa690a0b868e3751731c9c45963f510b6f53121d2df953e21d8d9dc65d5a7b090815117f902cf0e593e152\nSHA3-256: e12f07905f5b8504c566dabe6ba77b117a437a2753fc77bca439adf622d923e1\nSHA3-512: 94588ce33c8a3c769c1895a2edd627e1b07d4dcda1c7a6ff677a994c265c690f5acc6fff57ec75cb5f688fa0ea99bc6057c3ff9a2b91185558fbba9b731cb9ed\nSHAKE-128: 95481d3c6846424774cd3788cbd2ff4cf0168d32e496044a1ece2438c3440c4c190794a9428403f672ad66184c806a6e6d9489844121c13785f72aa7c4e1b6a9d0bfe281d9f4fba252fd9fd106988b89ddd913934bf44fd38576b97daedfe6427f3a8e1d568b488a85a60c248e10e4b135175db98f1bb297d11fed7aa7c532c443f6abd1cc42455a51466b6cd2a3a70b0a66e0050254f3639eb2c18562052fc8d2b3b1c0ad06c5428b8743343768e31451790e8facefcd6cef67e38aa9cb58c787e1709f6a48b7bc9e8f891b2ce20448442dff774b61d41541c7e99176a0b585f7d4b0e719e148eddf3fab19640f0fb4f86e04649364304ee1e232301864679c0121a6f1e9909c42a568b6a142b2b53c4b43b6e72189ddbdfdbc475b005e992287118058b949aa76a55d6e28b6cff834bfb65c913b98cec5667480edae4c087f0e21ff6ced1e3f5fee96c9e1418010471f3d66f28e5001f6ac33855e75466501cebcd602955b8b35a583e4a671f81d19ec9691f6fdfd1ffb9c86d7d153b0a1b7700df4fa5edcf2b3fa56a8e472606b62dca396c6d9e50fe3fcbce2543488cbd52ee61d8047b7072df428e6f0e27e472ba4bcd9f857fc21ab694ec1cd4ea1dd61f9bb3cf4b118a8c5aec6eb19", + "aa0e3157803cd9a04d0b59eeae97dfa09997432baad9b5fd91d7c4f128fc0825e7c8a289e01b190ca63350cc12ddc2e89c61db15\nSHAKE-256: 33830802b3bc62b49ecd126d89a6098b4aa7dbd87acb98ccece093d279f5a148b23ebcfe1f7842bfc1708a0572f014872a1c1d63601dd9043057f3145c7f62b9cfa3c7a2c12d23f93dab722d1d9a3881e6cd588b6e5303e375bf5561d2048111f4d27eaf38ae572bbac4aa707ce66335c5085b553346beac077f79c97310c6e70f8e019e8a35ae9b55c2060f2e1b0b3a51691833f9e396526f8d3861e21ec4aec7340350eadd0d754b577c790e03452ff1e86908cba523273c5ec7b0f9337c8d0a5f1075aa24249fd6a253681fdc472fdd14d78e5dc33b95881507cdf3ff2b2d2bb0ef8828457d22d3b3656390b7db27814068820f5b51100ed11acf643a943242a19eea8d57cca19cb67f1fe5463660c1178852e676d2283528906798b5cedf23c063cc135d67362f46d05c7ea46787eb5a280ddfed3a23f2c51a3787a504ee9bd70e11e9bd0d7db3bc9eb0938b8d4798b335d8b1ae1d21c8a6b1a4c676c0a0f017332e7b40ec5118edff781c5f6bd67d2cc2f3f1fd71b51f2aa52bf8881fb96662b82f938cc5f8083697c67fd959c21fdaa2e1b918fe281ad6de128f97db2c3376972453ac96d1d79bbed9262c1bded2c16dbd35bc150603fe3d668cc416730375f71945e95f20b29aa569648e41dc156ee555a5a5e33fffe340733d1eab6758cef9ebcbaa0e55dd8452708d4505127ef04940a77a54f55620c1000c86d00e\n\nInput: 125cd8bee8999a8cebbd56d484cfef419c45f0be7a2a8cec88be1eecc4fe3e8e8c03f44568f77b685711a5524bf51e36c960ca3410e0dbc480c0e337c5641d7de1a980b4cb7a0bf5583481d1956aa9b1400576f63db36fb680c40b48c5ae20b46e9d53e02d6d04ae6927cab02d288d2adf0eeacbb20d2a04b9755f2a7832915175a4d9d173c7b559c0456e3f8325a73371798b5fcd38e549b3a314a88a72679913da5fdc33584f1c98200c378d2c36b12bdfc7a41a10e18c80288f9b2984b187221a6464416dbcaad066bb42ce2238fece8207e73600497c4d5f09d576e3c1a0143b6f09798063b0ef62be972a7cc830d64fd8296f86b4078bcd192a418c7b26a6ecfd4c10cd52f28f160b38180c9ea664ffc97510cbbda56606b909206a351ebb91622213c6fd8accdb594ff08abb8477bc3d309e1ea938d964a9669ff2a3d3cbeeed786a89784670524dbbc52feb8c5a097bdf57dc558985\nSHA3-256: b9b22675b1335cb5c2ac6d544d4bdf3f7badc3030f1d851625c3e2a61323ee5d\nSHA3-512: d672cfd599b708760aa020015ec70bd5fb9d1887b1644d9b6a41234025362388613b3cf712f8df244ab574cb4912e7aeb7086cd8dd9ed29280f1f84cf2fb7739\nSHAKE-128: 9be70a6fda7c801fd98a965b96db2d41d8db3bed27c2fe62585219921bf92b371a0d3d658c609f4f307ccb72fa647213b847fed8a098cceee08dc4781cfa3a8933af123645e2a90eecd7b7fb6c49e8ca712d98c1ea1286edd40ad72a709255ef5dbebad715aa2c34536ea7e5db974ab20d8a57e6e4a3a5d73ce5e950c094506e5c85a9cb3d514ff0df4d6e595fc597a846b00012723cf37a17f6ed3ead84e4df2763a8f3c7c9f2b39c68820fd2ede9c6c525acf9ee0264184a13128dcdc8abcdefc1d4ee488200c5838d1f6d1756e064f456ec6601970fbe524e031db70a79bb218455f3803146be1e6adba12499d57604022aeb1fe40baad7737c33c9e52639d5335d23faa1a441c28f3cd41e53282169707f360c74de40dee0723d9fe589f9c6923d89ac3037a4c4dee49df9e40afcbe5c14df3d4ee23b1bd90b05f3152f98a1a6b86379eb64838ea330fec186c8cbfd8c1567b34aba708dc0634bc51f7b0e747b0b81ef08759bd58e291a0378e2dc86e99a9b083900ff7fea473e2aa324f0b12b86804a062f49d79794493b2821e09ecd9ebc69565422d503a7ad84036929c998f0ff6c8dc5046a44ed2eee8bb486177c08be59551728d9ec9edc67076abbd50ac6a108d97b368f850a718b2012e239aec93a36f1b95c27952cb1909c689b927eb285ed2ad427d79a5f7068e2df00ebaa9a8548d247530ddb99bdb5c4bbe9\nSHAKE-256: 2f6e5988df1acface9078c0c38821d3fd3371455147ad63fa974e0fdc841f6f0a1c7aca5590e81486c8137213801b1ab012954db996926e034db89b15837adb8f8a58cce2fb6ecf94006b66ce7c338776cad9c45a2761511b11659d3176b7086a16c892d86fc0df96f19a17c4ee538486c3b0ef0542963f699026a727d4bd928b6eb9c457e7290a9a7eb03791f15eb788793608949898fec95d3d69023243cc206c33b41108ede8256ed99065faee258dacc1627e8acba7d7c3bf4380fe3df358739e5520ecfa69d0cf05c31be52b150b90c0fa9e483e68da2f802e2626264780e2b964eb84db89816652255382720101b78317e6be050cb835c70dbe08a424e0877f3c0110e9c7aac09a26d6c586f11cde9f7b274074305b4cbcc0e455d11acb5adadbd40bd10d59a3025ef20f6bede88009d32afde65b35c6246b2f8102f7c25555e061a88aa0353a5aa252c81fe0f51cf59a53b332eed34ec1e5f6bead8a898e1c8ae117adf374efc975033c4b5a86a2a84277c8a1712149097419891155933042cf273266e00362c6a1f0050b0cc17d20a75225c2a5023982e1db75c23219b203131414694890cc7bd476433044293381b46a1e2f8dd63f4700f539df9214380685769b44db28579673140bb8f6a54e74dbbb723f05b5fdf02aa85d0cb9ddce76d03817630b7ad7061aed590b984d50ac31efc8eba46f217941010547e67\n\nInput: 9e5340932eab438def4b1be4431a35401676c4144028fc0949ba1b18cb40354b6caf36ef31e4301efb00be59c06ce307c5d8575bc6eb6e632c788277b0eab86a4e1d97054c6b21735349d69e3084e2d90ae641c84007f5d9e02510ff43a72cfdcd3e9b57a0771490ae08debd6bcf38995d6ebd0fd1bd40273ce6d37bc3e396c06e44e52bb4f2f4e378122a1b2ed8c41ffbdd8db259d7b7cd582b3dc1fd3437aca8ed1d5fcac096fc22d75c71e7e2bfc0eaaa01ed915f90eaf8cfe873cf552615bae30e00e698690bd765b02ad2f92404a4e03c8aa55fcf6e78e513a7e4c7d03cf3dc3ef15b363af41456587d5eadafbd9c42e821985f391b11216438e31e236429f936a53a74638b39f62c83c59e4291491d3acff11922b06721ce17941797ba40d73cf8cfa2b9b3c2473d41c59f432668bc13ef5ef699da1297994efff8ffcabd696cefc1731a90d8dbe3f92326bdcda25e4db687acc5417935\nSHA3-256: 17eb0e9237549b8af61407ca9a4b7380d8ccb53aa322a93a2bb5f6a53c685580\nSHA3-512: 9b08ba4dbd66f71976094c54e91b4e9b25ba9f8b1ae2c53edfd35bac1d43b24681dcc4e35881a5a8f880edbfb147ef0da27d122b4acb31a5d87ec5e411ccd33f\nSHAKE-128: ae2b528b64485616e75adcc02675cbd00af6318b6a40e5a780f1c70c614bd9fbfec01d6237dac8a76c74d826e67373b247bbfa74f3b5c981f9dfaa4bd2d8345d42e6c67f046900fbe767e52ed0264b14c87d11e67aadcd08b102ceb2bafbe614afd5bade7d217262951aa4d7d104524444f6ab5e90f07848ca0d28867f978628a5e302769982ec21fd7d0982ef9300316f41cc734de23273ffc912b5de1a436798839efa69020f7a698889edc60ddc8db27fca1e0e031d1513fafbc9ede7812aff3164fb68e2dab6cdfd9764d10e0841c1c624f2d42997fa44a59b61855caf077e448e87bf181c5d7f98d1b61448fb3c1159217fc3500c748f8fbb13eb5b17a4238d8b1f1f26fcd9f5a5e0d1245be804347345d1ad8757ca14d1aa691da6048848f3a30cfa67790feccb59fdebaa1e861997f77cc12e532ffda9560fc4c7288439d1ffce99c8fa3148adca61da9e4da3d0e3cdecea405561d74ba043a7fae0f2b32ae4ad2273e9706241ca6745575bd8f809043c77e3a2f1912e967ee29c25d2fef76565555891441f3f6290583c97166fbbab8b972d30bc4c51295a6d3aeef8545e0bdd236761587d9a458d5a0438cf5a2bb7a314f671fc40cce494484da8ebd24777f8a4cb816878770b86643cd2f56b24a2ede571b281d157d37f3fa83d1023fa0715d6cf353d3efcf3faff0d8b06c4a3410ea44e68a8ea31ab49cf9931ce\nSHAKE-256: 33ab9c33f4562ee349d7513c48df0866c9278af2dbad73c8a66c4c99bfd09ec32ad4db52f0854d83adef7e8e39eb834d702a4bf76beae7dfbc685860ab38f6d315891370d6934731ec6e384bbb83b868a84022526c12b24666b4051ba256b5eb47ce0cc594751a81cbbee82806cc33b9f5510719c1c6a01ff6933b87b8550c91e6d7bdd2bc73f2baab48aa054981e7f85449cdb28bf679748bb106eea35fdf3fef3f08d4729742f34afda8166a1d99843219a3b44d3e7a38b0acfb0e130012505cf32d3d83d7f761ce8d4f019abf507069a1a4c21dde5cd5791a73a025e81b1fb57323c9c72b2f62f4b5a651e43e7658d558a0191680a2f31a13c9a5b64a79e24485b594908ac9574759ab2a5e30532167b8f5c55fe7510a718966af96c3ef3e4809e8af4631323d903c018210836de61f0557aa01072c16c876f72a767d2a0d67ab4e7b7b999582cb4e012966a177ec52b8316501ad3139962143246863c0249d3bc5db8fd9a57546687fd15598ca35539237ca4ca4c8ea806489d74fc5d40f65f7e96b9f8dd5947ee7b1eea13f5041b738d7e7fdc6a8b498f5098296e5405a96e8570fd1f06dfe99764573d3ee07761cd44f643e326a5acfc8643a128994af133598c82f2e0c4b5efb43a978d2e0d0cc67a19f463b206dc17837d432d56f6a0113ed5a34de08519a73c50b55b093d5d1bc20a9113701cee277f4b915d92dd1\n\nInput: a0fea55c8c9358f0504ac76bb29fedc52604222ab181f79b710e21471e907de6e9439243b6ebb8aab87b25a3443a884b457b6c4126223f2cbc6f91ed47e25c7f5d35944a8c128b385aad820f8ca5a997a086463fcd8f4504c42409dbdc23ac5dd17c8b3f48004e64e093727b6506f8fae804d983267e7322c20b88bac687db7fb22bcc6221f01ec565666d5ed01be89f45f809f5dca87443bc2ad1bb2f60ad58a88b55ba5033221a6e1974f8ea017b728c6f2957a30c594a8c25bc94d046fb27bff766da92730b5e7e3b7196c51c17ad4d9ee8e64ce14afba226d5bfd3c638d3cb8ad0079b3f3fcf6007b2776af0edbfe43b82352c892a1b202744d4e7224ec6938ccb0af6558cf46e19075d09806ed7a3ef949b00bc00e10539dc78e3dbdb9ec38a87b7bbb10e4d28bb15ee7073c50c93a3cb8052471f2e7eab3159849c794691a55714c408f851795124a5c3dde4e3d524b81c254b7f8b39c9bf\nSHA3-256: 833b10d5871ba809385ab2ea77eb9fa944f22c22c5c6c50cba6d841b7a9ce2c0\nSHA3-512: bab2dcff692037fb334dad4d1325e5e504ad1a2ba94e07fb7ba8946856e97926118cfcaaf8c207e1bf843eec656692762aecbfcbfda51556268cf3fe17b7f261\nSHAKE-128: 8f562ac719aeb4a7375b2ff3446684235487669cfab0b4554daa738bba7934d2a84eede036e839fee7c7acdf7cbe0e1bc1828d22049e7c99f8d3e2e39ce9d66e0d875780475faf79e0f85ca", + "5e80473387b98baeb6664aa675359fa77d70f84919a5725990d5d7e84a4b238284dfbf4305897a9921f1edfb9a7971d136ba8d45f44c6ccfdd7625ec3ef472fd8c660fb44f27a0d17b2f9116efd5d3ed7a0b6b8839127e524fa0caff6029accb09818a22b0ab793ee5b87667c36bd68f9b2e82a1b63d4042fbf8336d4c9770e7666285ff85000f7841bb27eb5240e8250efda646f2baf649c1a1bd526ccf8f1758ef0b30517c0a918295924bbf6764eb519f54477cd7a2613b52d4b1bc794802bcd25b77dbf24cb58e0cbee2064f29d37c6f99b151468e38102aa55d0579fcea9f7601fb8e8d1a2beeca49761f48cb201613b9969a795ca3feeb81b7dcd082a2b36f79acc409be6f6e49305e9f63094255441780d2884302e140227a39796891082352d61c12a27a1823e2301b8ef93aa26b87842c1d2e86373947bda0e7bc67befaa157fc3f6e173c076f0bab5c06417a39c0a12b496b20fad4eb0ad254569758b56d9ffa05b286321074389f4becc628e9a60dcdec3164062b1747659bee21e855d34d5fc671010a25808e44033da4ba7876fd087c0b9ad09052afba21d8ce73b8806abd0571ca8bfe9dcd8a8a3d4a49dd16408\nSHAKE-256: d64f944c7c4bc92f1c13134d3bc8a994a605d7e72fe02e4d4fcb70d7c4a6d33f4b18c3142e28fc615248611a46716ca123dc09c7e8ddcddf6cbeb42fe93322ef46ddfd2550be8bc2271345589b0827aa7d554ccc42e813fdf23a72c95132495054b541d44de4499419a15b61ae4be502c45a9f979856a01de316fe9e69e58e259ca67c988647e745a75a0c9063b9432c68b37707ffc178cc5ceb59c830c2df6bf052390618f7b9ccb79b2194bd5cee6bafab75d695742a6a22289719132d3ff98cdec60b295dad8d2cca19c540c191f37b871a74a170fb9d5483384d6fa88d8d5d9de4e73c4d0b3b507fcddeb116fe149082dffbf9555e72b85aca9d9a9f6cdee157569d59778ad3227f1558a0984002373f7222526db5a633ea165367ebb8a70bf92bdc12aeab9534d9b09d37d0512af7861c4981272dc93dbaf519ea5f83b91fb3e166caa4e131ea93cdd41594f8d705ce5dad261a77af1c25d94787846dd2c207ade42a98fef07e168982fa4e52b8ab8679d0cc8056870e89cbe1033e741a8bdbb7abb43f38e86d0601ebf627d08346091baeca085bd9fdcd0ce1a626391d68cb1ef35e286921f5694e0c50e3b6c4ae2966595e9054247339a000459fbcab447d9f461398bc0150d40f6f17eaccc524ea9789fead23783de6c8b9e8d2ddff51b84adfe2b116bf206cf672bfd21a7807f4ba98313f329d29cd5f2f507312c7\n\nInput: 33bdc66ba51f023f843db1a400176d2a36171869e248428df9fca11a4c8d282380472de2e7c45342ba75a8b6556e3f1e62272ba962dbcf9eb4b83acc7e00e382636d037dc3ac24121de155dc638f952b1c3ca8c9665d256f5aa3c865c00dd29ff136bb8700843f66a847f2ae0d625285a01d85664d8551363b1511156c852e0de2033894fd33a7efcd5661ff55551a18ebd82f7ddfc4474e456298076781f725065682efd7e3547286ee1f62d5c924ee8c6bbd9f0cebfdce64b50315d1766e438814b9d3ff99136e9873ffc6990da89c9c2912e0b158e9623e6a0448aba1db0b0d569ffecec93da04c477417624ea24fc896137029830fded5fdc319b554206f008a4e477c07b71fc89ad03a086d7e3ee56ac3bd9c7677599c354834ca2d9b3c7c8e9ab1829e5ebcd315bcd0b52535f04aa6d166bcfdadb802bd3ee4c865995ff5882fdf76ec41e3a117d8218f90af86fb1ea9c2fe94c0c6a684c6a5\nSHA3-256: a3121fe7e8a0b90d4f68586755956a3ce1ffe49a2a03f57783e16549a831e0df\nSHA3-512: 55a55365afe00794d34888535d340270ed9a6f7231f5ed4193432c49ae1c338966603b3dc74228ff9ce8fde3c42404c57f8313c5aa32547212a6e858bdab0f25\nSHAKE-128: 472d9d57e2040ae9fdc9ca5f62a545e1eb746e43fcd04df66d60cc2eae07f158eed84735024c5233b7291272bce8393e10a39899684d96b8f85e7336ec174790122d7f83f046f4bae3b02cefb520ceea668084f4fa7d50fd86a6efad4a7aab4db3f7a0d4e0c3cc28d4626f4a65be44f1ad9d1b0dab9ffeffecf7243b5a03d04bb9473df57a05d86a276765dc775a09e85c09bba99584c3d8a09ba07db273bde63d4d243fecf068c494cb73b78794af7fb3527fbf2bff5b68a807598e067b01f6ae78867b7f9ab1bb66504caf0fd1ce3c2a305a7b3480e35dd3d4cf0c39350d711f6f35e441a3269cc10edd89602329a57d89612d9c931c7d6a5da18dd83f26cd4aeec3bf75a8df62974aafb76c21c2b61c6cc90fb16219c9bb1894e48c80073abf392056830f2e6d77a9809f598582e94498257b78f48f9c64edfa707b66021279485f181fa3eea3335bf5c96730f56fff52f4674c18c6cffce4b5bc82873c615fa5ac972d1d6dfcfb631fd6a9fcd1584d5ea79d29876ba9ecb593adcc003d0b4c102b81b939f46f5043c4772d4562af3ef37f15f11a019e3846d6ab545cba6693dcb8fcb4486b7553fd5a60123ee6033b863d557ebfaa496bddaba54c09a02b8097dc86a463facda6d6e37d945e3249507b6d2a866b1de9de85cefd7161ce4b6985b26ce544ef1ffadb46bae7d5d99f15b26bd4a375274fa38ef66910ea60f2\nSHAKE-256: e4512c4c293c86f677286b26feb6b553441facd3b943aa8938f10f77eadc5da395b6e224532154c938b14759cf3bf79881255ed58d96c880b9fa9294e2eed57f3e13a87ba31b95189c8a696aba82954f0b00a8f159f4628caaeac10f943c81fb5b02d2bafdae52058b72d86cdc0722910d254a19ef0d107deb6446e47c7a6330d8ae774c2a16047eb9f325c284cbfc4e8ea82186ddc60435d2db23675fa2105845a53086a59d49b57e80cd9159d58cc0e0b2a1ca1263291eed50e631383d68df9aafb19a675790ce2bf00f2295e2bae649910419ed037c17141d45613af6675a24e1f2c3bfcdbb5b153a62c404039e7e879b9decb1aed8e078cd9355ee669e90720174618e3cdc7cd3df51198d9a2b9c13fab76a33296693ff7d82fbce6b1f3608f16ae8461e3c343e59e143b8be635e6e96e1592cb21676fb7028c7f44f86d3585fedd9d8ecc892616ee7f79370da979b5645ca2c4644c3b21ac04a3733d53a08d1623bd9465fff1de423e183b27ce99b33074423d1d8b533bc74a26afc5e6e271b1289e008342626722ac81bd7834dfd5317c481f622ed028c38def8f3933bdd4648e19b8621aebe0473e932d6f84e7017f506d9d6c8d14293d6826d09c55e7d536f9f728c54a71703ef83f2e7c7df49ac56a38bdc534a98c926cc47cefd191d654ded63ec3753222a2205d01e659cc5b0bc3150e7f184a8bcfd732c04b069\n\nInput: da359e0a3ec24ee762d7513c5805568593f6b0e0906435c7204e426928c885d71a762d686ebf660034d83aa1b73519517976e8539d5e1ea19caf9689234d0e25c30a4dd1de556604d69da9fefb47c05525f83074f863438d15792f2e2386a762b609ea001473c3c4f8af55991bf9b31d55b88d1b28e97bad74c713ad40adaabd825257b487b0f9f0fef2f0f79ad80212beaca5cafae6d3fcf13c0165dde79006797a507a70526d1a235464bad101d18a1e1092ddb65da8e39b760b992ecedb0643487ea7b253bab2548160bd673db399055da70753be94b438705adf9fbe681a45ed72223125611733c0dfd249f494ca2923ced53949a51775caf4e05d9232292066d6d4c883667a34cf2e81416ae2ac6e672d258d08c5162b3d16b8f5eea92c99bec546a0c35a346d1c0add0e7b10a064d3c6691d7000a422659e25b6a4775b7fdee5cbb74945183ddfd9ddef216dc3d165d8243fbf6c9db7a954c600\nSHA3-256: 1a49c1fba7ad52c2c2c646a2c0ba5205f744fa407f7d50971213d99ea94a1d56\nSHA3-512: 98ea655a0f357d4d053804955a745d1871a7849e3fe504a32bd367eabdbfb000590c99e7a012d929086dc50eba6ca98d2bbd3cd17647e6cf247d3bb846608158\nSHAKE-128: 955c845d27c001b82de66136413f01dd36036d97d14b63371fb374ed4f738e6bdaa38560dafad203c9714c2341605315811698417dc2ee647885e1942a23a0ba1b2c6bdc1e0f36d20e3dd2ec1c2fc22ec0c8281439ccac015cd37079e799762fc83b9278436046194a80bad1824ac5ff9ce5158f8d5e073aa536227e60658d9ba5fdf4bcc7f6ed5e1512db9840b834eebef03cd0cafdf62865545789ee64360bea8f04d1200e2042361faf3ef569ab45f4128a6abe932d39b54fa9a557cfcbbfd18ee0d35903b4b9c245ad3f894e091051a982d4fae4998e7d4eed69de9327db1e604c48b49f4eca04e72d3ecc9304904feec9d813f9172c04843a31b2897b9f2fccfc75e8580bd2ef7f0454bbbd8374c22cc1aa0fdd73054f299d639d104f0a4dffd0fcf5788812bec374b9a4146b802cb14641e804f37d61c1efc2cb585a78c220bb6b06184a0a4e69a254020536d010dd7aa563d835fa6202b1b2a1aabe9ccfb2d48affbc7a36c58df8198c17fb7e4551733668af8bcffd04f5841769167908a37f6ede10e9fddbe6ed86c341d340306f18c1fde7314ca3ebaaa786d54be6ef264575b44e7e208fff9a8bd6c6e08d81b6f93595e447be96f27064ab364f4df3c415ccc45d6b5294fc830bab56ce85f48862eca3b4a1cd58a334d5aa8a6aecdf43b11db5f690c8ea985dff5df7fd0fc298af2288fb19568b51500edd26ebe7\nSHAKE-256: a469a827dca3fdffc1c1170872161d8453e643603b2f750af934b5469da9aca47628a15ad1fbbd52c7a9091d2dae407144e439fd4d48719d40b330d979628eee99b29f688fc2c007ca15174547f81dc41c2b2f0802d6a74723debdd0eba2c6c92504167173e7a5651a822004e7da7b6cab52065ab6109def151a19fce5de8bbeacbaf72441bccfd141c51821a365df31c4bfd36042a2ef3c6d144a110d718eb55df74d8a2f999998d2225964697114ec878ff3d26e7dd54071d3b4ccbe911b4ba7cfa52e2f16d80f9d98bdfe416fc6b0551b94cb5243f8da446bc69467ea8cf3fdef442e003e0941c340e2aa6904426ff1f72cb8e6b939ec06914d9afbb24a9b35d3f4538bd913589bda6248d1e66bb703a807ba3e33382400559e83cda61e32c4de5d40a6dd179350a47a4c7de4e7046dd4309f1b649d92d8e374c49b9bac9184e1265b4a32d3b6120b1aea391b4f0d5618471458834120cc398fecb996e977a7cf71023d5e5157ad6cd75845a3fda1bbf27938df6818ef3a9424c7f740150c9975daca01be972c6591472236cd69de621ac501c31ead5701c9477ce9823290d73e5970976803099559287a4bc53e56dec0f4d6e2e2fbf6a94b64a3104632b0ee541898823aa3f035afbec4ce444be3044febb57dbe89bd6ff3384957ba589249904b1d660b734caecc37bdad86d2aec9dc41ef4dcdfb36bbee9b5ebe34344a\n\nInput: 2ed8edf286c81aee2b8d34f163c0fba7cc99ec284b9ff789ef214a86aa3f2530593324be5b42046e39568d4bc7ec04430fe07d98ff75e0e4da7d2f0b8157073bb643216d1c1f771c687c9a05ee9ad0c7ed3bb878daeefc979e9e22c41e2ce31b17a8436b328344309a1a1f047f39cf45829d2eef6fb84cfedefe3b7c2c848f3341c7896ecc5c5d30df84ed72ccbde5ea61", + "607b68758ac8c63dd63a72a421642d5305fe97dd68a08aa8ceda5869a376fc37995598231c496061243d87451204c917ae3d731ab58c06f92518c5e0ef7f43bf3ed689c652e7dd1ca4a85aa0ed01a315c561c435dfdd9263a4e438d1b381394ed2c98525a6962263b68ac0296932b58ffcf807e496bd3489596887eb471eca94ea961b1863254e28f2833b9f5af5869787d01ae7e626274f17a00ffaf70bb376e9244dc9ccad3efe51d5e8d33a6c7a3dc6f6187e0ae8c65bd7c634e0828e7a5efb53cb4e235f487f8687e2c5fd\nSHA3-256: 614efad7e4b514984a66ca18fc336f9abe95e12ce959c61a85cdd5a79df53fb4\nSHA3-512: 2e88584f07f95dbb50ff26d31d6824db259a4170afb8ccb3919bf795a5c460e2bc97208d20e94659629f9d2b565141e2b485a63505f92cf1f8ef719e976ad876\nSHAKE-128: 2b4b84b7036d23d51961b48554cbcee7695ae56cfb7712877d7e284f53627d81d813d4afbb5f3548a543d96c03615e453358b7c2c68616a7720d082cca5f250124c78ede98ede0041ea655386d0c2c4bff30860c8c8ec8127d3f01df90d5ec53c5e9ce099477a253cc8b1da84dd2b575703422a0cfaa1a97d5e9dad67b7a54afbe8c2ae8b8895bc65a8a2574a336e27140a5caa6185edf42a7fc66dd40f1768e650b6429ed19a78a9361f06f75565ab4ae475d1a539a1c7388b127fa948b0c32eb0ccada4f0c782ebce2f647e692445150cba6b07c33264f7b5a99b7a951f5db0feb01edb0ac2b3f9da8a1f4e3ffdcc87e5c96e259e7fa0c2dbe0c64f970db40a8fbd35402434333826d7d65a23f1ee185a256c1d4ecb221bc1d91ccf997fbef4b18a5af1b4d6a1519d93e225815b37a6ae3100eae5aef8a1af40ab026c772012dafd503c361d495bc0ade18ce03082f7297a162a6983a79cce2cdd04b082833d96ba607b51049c7c709b5da309c1d9fe833dd7be5acb5954453cc584230fce145d209396fbee1227657cd51e9799046001040b5a4a9cc4404fe232f2c87896e0222108e55ca1525c00a54e9777f271cf60044c4a2ba046007fc5b3f87f736ef13670cf6d1ba4de92661c1269b3109769def4e4b74ac44144462ac756cb613b786bbbbbdfcfdcc467070db8da5a66b8a463a24de9da2b38414efabe8d2f5353d\nSHAKE-256: 8104bbe785add3a91033acf96261e4759560471eca4e2cf4cda0fa1cdb456062870962b5da1a7ebf0c271d8f1722363ab7c7b93040b8b814de97cad6ae38241a431b0d5d882ba552c9dfb55f0d35734411d5bd31e6f93e5779c3595b7200a9786f7f341ec0910c9f0bae2e0cad2e68869459e728dbd7553a5c100b37faefc9edfb75a3ed3118c259f51fdf66c486cbf8e52a4b7f54081893c63de1bfc94186f38a128c2f53fbbd40a904c7f0646aa59900bb7a7b11c6e010b3fda5a6bde05bc2b16fa4e716642d6cb582d0dd0c7b0afc33a285996e633e5e9e3da8498927a6fdc422ee3ce5a2481dcef74e779da0d9b54b3d5a39bb280c6c8f494d9169f185be6614758d950cdc0d78ba1d8b6a89d65e0a28cd56c0dc8529296c6de753036d2bf1e2041968f0089ef8b58cfb6e8ab69c8226b0fedd87d44be98244f3a10e4cc4796ff34d740b4accea27bd5afb9c914e7912bc02ef4d57b67cb511d4688d7c69bff546bfdc73f4c1c977c61d700f6a1d5553a091c911013d764d2215bae06ba1e7f822f77ba130a1fdcd4465a9db47b5b7b5e4fb75d49a230c1a4df9d3a3502a38a1b8e78604b5de719323cab05ab0e21086a7d20066a8014a00e9a2f75e91b201aa1fd177e9a087e0ad8acb056af60482b400975ff0d4ef6480830b18e874fef81b7fbd3e17ea5234910ccb1a10a5eddc6d725cb82d16f24050c7404fd6cc29\n\nInput: 6ec3f40af6cbfba4ac92898cc7c5949d5ddc13e6398b40c38c9168e5dcae0ffdeff3f08a1f59336b06baf238d5b6c9add52c7d94f5ba79b9a1e66e7165ac683568783c402f114019c222e0c39eaf54951e32f1ba8bcc71b6ddd3c1fc24fb2972b16dd74e7aa551caad666b708d0bea5412649d82a1ad578f08e5e4b42644cef8115a4a4e9e4da1f42be26d91390a52492f01e5d7763e29f50602e1ce8c1cfa6d52ed89641c853053921bafc5904cc31ef022425c10bbbc16e6387070c7e4d6abcb3392510f4b5c92148273ed3f6df409a26751c61745147a617715a454144d66a424d0ecb98ef1731ba821fc205b53f6e7db27b3840df0b8cf87aa1279d4880adcc4cf427ace3cb9fb8f1bdc48b30674a77692c6934ab4f06df45c3c9bf6bf00fd777055fa225ac3b676851cecefd00528e37f3a59245ebee18acc3a971842a3be1e88f379be9a942c81eab139c91d3ba43a59eab5a6c21d4481567aa096a8\nSHA3-256: 7fb6948d5fb8cb19ab6b7677ebe107406adae052417c5fb257fd388c7fd85e07\nSHA3-512: c5af4fd05b88e2b06ba270de6faef8cb95227bd98e14ad6485438adb94166a237a185916f478ab3e244985110bfdf42106592980557655cb53b8bb673350d2ca\nSHAKE-128: 9a9d3e15b3a82f9b01fa4979a3b396061349d140eabdb2a2365da249e5d317a18ee3394755e4d5e3d13c237635c4877740eb15b73ec7216dbb9c2dcc434b65a8e939450af48f43b79f02129ead63b9a9a396921c871fb13966c85f28065e8e411bfc075d3eb86f9a455d253306186b24b155c83b63aad3119f328e21086fd36f07f2c95bc19c6f5e08c10483dbde1c6835833512cb59478dfded32f429e71c433b280bd3e30d8c25c5af7ca4519d88b68c059302f5690d0e9e5bff64f8b0181c18eade66bbb43739e6231281bd7a463f2c97487454e509e19dd3a7ad5116dcea8fd148919e9a75f82a81f39be0cbd441d23ea349a30c6f2d687accb27848168fa5b3ddc9649977cc1fe6a79dbe51c8c5f37d86a0162fab3224b65e685cb6560b5f7035e3e460fedb4874c2922279ebbdc67964d9fee88932911adbb33f88d604cdc994c495cf9ecf4bfdcf5247f4b5f67709c577f49203ff6cf36126f3feadc4fe2a9d046ddfe6d2a4ee2b8b198c7d1623f085a33b8a3e6b552f641b2639409ec4471c30e1515d9ceb43382ca7edf2c8eafc7e455e699e86c2e92bf9b70ef176c294ebef125de0ccf348aa4ebf2c6e5f06bd2afc91ace8f54a8ebec34e7a4ab6d8c611682b5b9b53a2fb0a354bfe51b7030af6ccf710ddd51e11069f689c01fe3c7bebedccd4096c2a0d567d40cb3a223ceb69746f5f7ed10c8c8b926d850b2c\nSHAKE-256: 5b043c9ecd94df6e419aa3e20a6c3d30132ba3c9aeb96966c117abed336eea02f9374b0d6f8bbd23a8615f9067491520fcffbfd17913010112cbcf58ceee837536617acc96e1f4fd338f32bef92662dc36208349c1de66f6679c8db6545507fbecb4afebc963c455dde414e7b2d0ee25e03fb0d6aefd80238ee2b94d38c8720d1959783e71015cafa7a41d38f0ef49dcfa0e07e7fb159e07f4ce8a4ba542379e5e970275677d080d7d7e4d7a241aaefa702958d5d5f3791e5adb5349ff2db5085cd32e4a75d2fe431ec372ac5699690098b44af947e27b20b480173e9551a6dbd6b8044f05a3325a1e5cacbb79c514a8a8805df21bdd0ae98af551c57103ceb236608c37e008861acdddb9eb630d5af02352dc70e9503b30354f30a9c853752e7b660a5405910864f38ad90645ccdd31d0fa713d541be2a9a36c3ca57f0541dc7746a1bf38408fca0a6546f21bce523f6fb7cf4e4087ac63cb58eeac0d96cec813386c012023046355323cc21a4a6c4204cd5287253e30e6aeeb2ee2af100c176970bc41020328dc81285b26b59619e6bf30be59d5c9a3774b86dd9cdf5077b1a0eba6dba28d860104ce1a227f7eaad68f5e5c64309428b0ba837e78bdeb0ba0c5de87f61f0865896d39d1d27f6341a6bd8de49b4c52c42dccaee911149923146804f9a259d4c0975f0b6385aeeb3b24b63dfce6c1c3d2c3bbcd891e00d3684d\n\nInput: 5ed5d5440af752724d74c5c57512757eb0f8e42b662100504d7bde40b688311292d297d2ee1a2e7627444c103e41f992e3df428263e9727bb728789bdf8904ffea0301317026524758905d262c23a07964fb7b4e20d9355ae0218b8e5b26020589e1db3b77d5c7953459e0672ee133511ff487cc36e5baff1d40a92e70d944b80d09434a5334d5a4c9806a11fd54c1924ee9f2d6ec57486b41b38f2f5919fa0426f4556df91db5064eb929ce539186b65251338ee7b32596f3805b286854d958460777b5131ff03a817c221cbc1dd1d6fe12b33b3f0fd08a853453a763c7ed00a33425851a25d32896ff2afa7af279c4e8bd1d3b6d78be1bc9f85359debcce83813438c0a763ca9617c54285f8365fc511fe9b006d310f83f0bed2bdbc378137d9782fc870fd64bfa6cdbda4fdaf9888759e0ba63394c666fa383be16ae65c16676bcc55e16656d1a423bd9ed0a3316f3c095c5ae3db9a357ab6319f9b2cb920\nSHA3-256: 36af2f74ad55a72062ff75c6a1b498916fc5bb04b52b1ae6952549d21101f8a4\nSHA3-512: 3b3a26019213edf69901f5e8052340ccbb4418f7ffe0cdea27925d176d59304a020d38f5b157ee0410d76a94d7bd50a85da53fd7fe970986496d4f2392544146\nSHAKE-128: f761c91c1a89dc1aa58f42ce0e69d42186855d4523d9ccc59e67d2cd7581574b1975436eb430cec0db2e8ed5b936a2adf884ed462b3deec8d959ec03efac0d997418cf194176f387b8c849973e0186877107d9ff9b2b0783cef0a8a8a52fcecca2e193c8181352edcb2b296e0c61cc6ce220576ba536b14d4f7c6dc9fd08813ed6f3495256f4b7e40251fc3ba98b0fcabad06b564209c7b96ffa6e445cf6e314ea7fa1b62c42b3b34b9d3260ae3d5548689897ccd6500941f6ee06ef216933fabeb2dc6414a7288a3d6eec78776b38a9b99b0a2b81bb05c58dfafd1d6107b6f149a513485972fcc22205765f649bd019fbafe8402f140caeeb46132b5fbf7ad5f0911033229590103abea38ffab1dffc9ebdf3ebea5301edbc574c135cf36162d2d975fbf598a488d97839b8ce40976fb962ec397fe0768da8046f1e270722ed7616f7c59cdc0c427ea26deda94d394456c7a2a1fa25664323ceef80de2e037d8c0aa160cb03b536e71a749a3246277f9b6305a94b2c0708b45f6b75da9afbe269826b0e6401550b86742ec082a188b147df07828bfa31aa8e2be6a0d4accbf4fc0de68a1378a8b2ea5550b581a82d6367f413ea07119a309af667bd466b5bd049b2647e74416f415ec9cd60600552df7396baa1b4f3735c0efe0198e0823fa9fff3a71b223bff34c92e15e7f0670a728b258d8e2062fc9672995fa54e077025\nSHAKE-256: 23751e41c4b31d226a7df123ee6316910b13c60bf7f9037814e6ca27535b65cd2f99c4a938c32c78f7a5008fa4f816baacd437f039170a7e593af9ec1740899f5847afc542e7c2f8394db0caee1222d3b1b3d8625d806c7e3093dfa89c6534e375432d6417bfc42408827b24dba2f7dfaf785811d55cfe8c3713bdb46690da76503f71da9ade3fb2a8981745931e2a4fc5ff9fd54ff031627850b14f058fe86e6272cecb1d82f78479fbc2b07fabb3a1be1a42f14bfbba184029cc6be5e719153dc4058a30930ff9182d6869121a8dfc3b9241dfa050c990904ae35f15c435407def57bfdd022aefccdd0159a33ec1b8e974b617c77aaa2730a959e80ba4df1f45186065aad5", + "521b00f7936b7246b17fd38cb735b500d9ea2f98655829b6c0d8f9efce3ff04fb6eb69eb27d97385693a6e238f4058b345242f3d6707b7b5daec8e9e4f462609c332304c507495190cd267f58454c55f05f3eafea74cb4ee9e60c2976d62322c65ab03d6a18048e9400fcf51f11fec5c3f6581d78b84d538dd34619eabbdc184cdb91501183939391c0063e1fed6b06099fb4883551ba4d949ff87a9e52f877e94bd2213a1ed3e30ccaa0a12053bcbca0329f2919d64a66333243088afdc8ce65f58609ef748b9cff44f3b4af5bb2742b69189bfe823daf7cb28529fc5eac6615e5beb3df1cf395acc0aed81070843cd5112444a05edff0377be\n\nInput: 93c220e7af9a04d2b69c2a8321aaca20196c841d124240ca09c2a6342dc52ca088945afda0d33ed6ce3b5de2de8701f98b3927bfeb7d9aad128ca5d0723e2e013c3f96810ba9480c0b9a004011ca4ff4e5b81a444d63361118d49e956f1dec08a97c398a503397b5167efbcbf78714d5d4bc9d273f3fab3c46a6d2a43634d88cf43fa2841a18e158d2bef053400f3f5782b13323a96f7b80464d38bee3e737f95ee510a0b8a39bc3c561d5c48e99b5fda6299ede49d1d8d53a952640bf86d9c5df5dfd24e46b93822ef976602496924951516afeb560ed8e8731b72efa1b387619e5902e33cc3f0c40b4ce4b4be9312f391e9fa9f9c330a6cfc625ee40452eeef53198235f67ba2a2e25b83f5f29dfac216c6ac7cb8117acf8499dacd9e84048c7ac901be429c797a1cc04da1dc6cabe950d8638616fba422c8701a999729e0433c5dafc2883912ff272b78a531ed35c06f1060892d0e1b8563a040b99057584b6\nSHA3-256: 39a6f825155d913beff3039213712e0e6a8bd1b3f4baa9dabe1681e28437fb04\nSHA3-512: a0a0437ee9ebfd657500052e09c1abadeb1ee68d9d249837d94f7e8532cf73ed42d7ce3667f655cbeb9ab89a95424473338d0162ff657e53c3b9ae834f7ff438\nSHAKE-128: 3e1d1555943005f60e03b53dd7950926dc9c841f6514206091109eef603ef923145ea788c2471db33a66655c24b2f6404cd2f9a3a223e3fcf7aba5171219e5c3f120eb7a8345b9b50610fc66107d9420daa8c9d8c522036109e96b0b0cf89ab1638c4360eb4859d50a3722bc26132012f4395c919bd215b847528a0bf39152aef3e896e414a8cff7becce02e52dbcaaa90c2b8f227eb1eaef551ee73c3b64feef7515882ae6fb189fd06d42c5b440bdc067711c59775408d476bb104589b2fe293a2e101268cd6063c5b7d4375e0698be17c4ea7693a9afaeae48267d703b24bbdeeec0f48dccb3068e38e01bac05af092defe69f62c969acb7315f0bd77c326cfe6b1a5ccfc2dabd308345186e85615654a88456d5055fb11fe1458a66437a2d188c8c51a833f8a60ca4f8744d3ddcbf47781173a3e22a23a1b6fc4b3f771633d1fbd12a999b53c26995c9290873a2d822be77f2ef27bbda4c83763088d46ba11f05644b828bdbc6e879d5a483eb986bf560b9e9c6c81b689c4f9ca1e54febb3681237a0f0b674f49b27e7d12d937e369e82e1992d8fcb2a8db916f91d789f343e079c1275edba2b4221d0f40b9f6ee5a6c58e0618a58eea28d781239f342fbc0c30bef0d2fc1e97d45800bdf66f2b6a364710014dbe6b89520196a58c9771824f3d28980213e9fe9b0b2c18d8f564a13cded86289c8d495d0f37efc00d74c5\nSHAKE-256: 637750aebfb4952c7396bcf29030a91363656b175c34e215c59fc17beba45a8811616950211b510ae6a15d8a2930661d11b250c1f58103c1ca5f9fd693cdd36e44bc629d5dc455202f9d99e676321ccaf51cea7599d729d4b9f01edff6c66593ce24fa98044000f5aa02f4fbd3c881887dcc96b6a3472a058791197c43d8eb63cdd5195a7fa19b9452cf99a917f85241d48d1bb32b8b68c5ee84322987654a95080f3f685542d561f440971be3ad08686a786b52a39c5b9f782899fbb1fba82011eeed10f1866fc448f80932aa6c1d738020c953e119ef7f253a0f348960cd7c46a2f37477d05e3ac15f9e78fab88a8e5f6de8ebdfd60a545ff612781680f725f2926ec06ece14f63e4cc41d0ed1c90831f4a247f91d15eba6a2a40f2c773b44a583e125cb1064a5af1b46c65b65e368d5771525d59a152f7bb364cdbcd57777314b1bf4f0348cde83c61ce0cdd88b4ce90eb7b8ea5e8925e963e383d955972392e81aeb675bf3e50d89416c4991b31bc1abc1e2260bfd17f451adc26dbde1a5dc1ef92113ef48acb1e2fd9a822edba525306b6fae6e6845a382b87d2c5bc4150e46e9a17bcf8f048f849e36e9aac877310048ce73dcab0a95b433a2b289c638a2b5ad33e428c32e7576d1e0a8ab732b08d3a71b753cf1854ba48b1469d8dc84bf2f78ef59d1140a154731426bee4a1310d9037f314348d86199cbe50c302e9a\n\nInput: 0d60c256b55376b40c60fb0e2cf3f84255259c94f3a4eb95837b4f191a135f0f070397ec6c20d535f9cdff9f9895d9e076fc4fa594461a15976f648ee62b7de5388709ca06c701b9b3e53a2ff27c1c6763225e6688f2ebb26cfad57f4de8a946c44fae70e272fea31750c9a24b8384231becb45f64de07b0abee34fb89ded50cd9501f23536fcf30083532d3bbb925c8f7dab79e6dbdf10f4ea018f4cdf3644f933637f7960b3790f8c0871bf01baff1308c19db30f53586d886c8a7bcd45206d050b9c0d510b740b2fb92244f4ec0e7d98c51c1643fa4e94b48e1c976be1abdc418b3aa3d7b883c713be366a5704a710389b0b876fa50acdfed20053e2a8e5828695b06c093f1d5889ecfdbf4d9f560f9991ed91fd6b21066b1342712acf99bb9615ee48346fdce7e2ddf069d4cfb3facef6634b7bfa422a18c85121baadf15f621f801d6531a74a5883b112c55802c8c67d973e9ee9bc8f48d695ce1c2c3d14b24\nSHA3-256: 1a096dc2cb1c41dff0e48c9016c3fe99fbd616a9f0bb2354fdd20645f8c69a6b\nSHA3-512: 8cee6944c0bcef0003d725b2bc312c21a9d67efd6a9abc19573d9c80394792cfab726b16a55c898555de8e95d7a9da1b2842778531fad8c12a95134afc162bf6\nSHAKE-128: 71d09897b0abc35aa7603501ac64c289be15ae573f671d9f10baa0d6465652d6801e55ca88d8e39b4c6481ea7fd6d6c53d261c3762e1516570a575036608c66e11fecc0f8d283d38d568549ebbe1fd77c96df45ff39a263798329cce832bddb683fb2a6f8f5d5d585ea6695893961475c6c91f600d3fadda2b00130f74e5c71daf815425aae6f07f57f99ded8cc669cc6ddea5f9d22adb6eef67d6f4fe2fabb9dff4ca537cabfc188386e65ef69a5ba38ea932290e1e28dd5b99c6fae3cb7447db6e519884f7e56191a93efa6096c60a14c5d74bb9ee6eae2b7d74cc0a20561bf4f98615fa6fa95b2c47c5920e96a5a7eae8efa73bf4ad35b514f239ec8a7fc36612230a912a954a8104461c9c5e059852e7002536b3264eed1a693888898b476fba9a67408b150b3405d58a7d03365a499ef31f00356e237b0704af62ad81dd8ac0295401577de712cb8d22f0b20e98bd4c02777e9d98495f067118f5a9ec51c4a0a7740e4c0116a37c5527d559503f604759af91b10d38521992532a226a1d565664e52f0e17f5106c4b31a4c3cf2c9907e06858483beb8616e646a59109947c478445dc2faeb89b717be8805e3643f2bf61e3a142495e441531012be2f47b958d2afe8cb23fb94ca127b3fe36a2035d006ebe88b8aa838962e7d96bb407f74d329e6a8f3bc85243777a4f4e11bd78cc406272f36641203f5205aae07ab934\nSHAKE-256: f861ec157f5055854b59fd718de43da6605aee5b1fd7584ad0a0522afeb15a87aac83079e1f7cce049198642657abeee98b980f78f02d632f1ffae56b7e6dcbbe9030de8e1a0229194090904942782f6891c5ae450b547aa8ed3c95bb4d8ca340db79fb9f57ceb50a3ece65078aeab7846f38151ab24c22b0f9146847144e53a5813704a3669d743bc8f67422c8c894cf3a1878681c1e5cdf7bfba756b28466cbee7b61246cff6abf5c38114746c20078c7f727fdbb97e2d23e27e154e7b817c3d3b4f7f2b44a94e062faa449b5ccd818f01a65feb0614a4240e63183fb08dc6966eecec0f70a33d7b8355059f7efb7b5d13a6b9a59d443bb49d877cf827cddfc32b6ef6725908496b79e7fecd41b075b4c5f752c1fa234931ef45703ab659e1c83a2df8f6e24ef7cc86ef0c3dea431bcdd52760a66126a987f08278aaf53b9e0b60f75376097870813cf5c873e8679204c15f7dcf4719f28d8b938394bc782aef4f4539d77e682a41d756d69ef52c4540d55e0edab6c3b27cba379456c9d738eeb2be1614fcb7558158c2d32126578b6f81c500a02a8f8bb0880fd3678307688287b19bd166f9a90761f9d0f45c1e16fdaaf1e2f9d588f1b6925eb89806442d69d8059a45765c5bc3d66a7529606e11b940a22888349d59cc368ce8a241481e0622c0187a30a50cd3e1c71c62f340dd82e8e74b373725d7900337f69ea0cbc9\n\nInput: 710ed4d47ac42ca31de8b41d698d765f1855ae15cb28ee45645c394dc3ea00bf4b7687ce75e3b7209ae49d79d4790f40fb3dbb85823a96c8ad9ca51d54d076bd58141fc75a48d1967b23d68d46435859d3fddb8486faa014a52c26a10be47b6070e160e81757b0e45db408937dab52bdfdb95d805638a0ce9d95728ae7989054f9e39c7decb29ca904874f246b090555b39a55b59dcea6cb9611d79ffb4343e407b10ed7c3ffa7efee7d134019936011a2141d1cf81eca4d7add18c06e62dff1e6741ff596782940334ed74cefb349736933dcb00d1cd7084f60906c045dceeb354a5121ff867827f04a85947135038f6b8fbed7614ef04366193ddfbfd071461b1dff32e638e1cb5d3e0eec19e4bcbd2c37b666c68fdc32fd7567e552c169f208fcd8e6f406ff5f1c5d4b92d3bb1393d510649e286b698a65f4c4b433a0b07e0edb2c87edccb7476d3662ff05a96b3198dabce88f9533984cc1d35ec5fcefa9fc766b\nSHA3-256: 5d700f858524da4969719d5adf2c3de464ea4e8dc9629aa861c609ad5c972575\nSHA3-512: 1d6a1265dba173c7a37e6c7c456b694e5b3c246ed5160d93ff11acd6a73b4cd0ce5c6dedfb317dc391b886ad84c5489b5f55ed98bf19eef9f8569b19d821faaa\nSHAKE-128: 0c3ddffca4cd31e8cb41f7665c86ef00abbfddbe1d43944350511bcd02a18a5202966e75322a99ad90185a4a0969a1907ec185787718625d4806b7f790ca80719b23d2144b2724b202429269d0c44723a2bcc056515399be9dee894fdaa73633c9ee557954e59b90fcf0b958cc933768399a23ef30d424d7e1740b3e649ecbac510dcca8fe7ecb19f4a279c9e7ae98cdac41ed0e45769632c80297a7f5c8839aeb415da421a19e3bf5d55d83929419cc3c14788fe68368a51dcca927a924a1b7e728eefc21ea17c091575d6f7a1db391486dce78ad6e9a1e6a7c8a566e92a6ed59cf806d3428ba57137219b07e7e1db22ac5ff6cd64c7dcd2842d8c36ea35b045793040042f0f08c92fdfccb2bb104fe52fda607093f6e318df3bce6e413ef55321bdb467e80c8a65654fa399dedb9794662394fcddd19bb0953dfac1f4c9a6b92b12ef04dab1d6f973691c4781d56669cc8c57fe2b43997de80740fdc02013b0708b5ad079f7444b1690d4fe76ca697ea0aa47", + "0cd982d59fc555932a55607f6bccac0c336a75f7058abb7bf82a8694b32f4533edaaec6d2786c5c4a65faa393d6b7df66796a052d2b773f6f5fd430c0cf53bf5835a33becb51fba9f0197be5ba5bd09073c07931bd85353534b44358860b95aea96a22f0370951d48029b42f05c81adc97084fe9f41ce52ccff1db3990eb726616154a58c0a809de5f2465ddb\nSHAKE-256: 5d873df505a5041ea0d6eb21eab4ee8c36a8be5e127b055b2e27f774a38fc7c6df53a8d55c5b4cef24f3a40e2736a9b283cc29b065fa15e083b693cf37c62f2311915fbcd6204045af8b9fb70030a1fa6a0f12fbdc70d730e7a67ae5bf2407d21a294917e83077e0c80f62375c783ff6599690a42d9831a5d34c0b86597355dd98d8c12fb2da5c62cf0684fc22f68d9ae0a80539bcd4f24e5ddd202378efc2d68e821115ac3a7ea42d5d4fbd6d627599ad592c1f655d6d55252e9233e6a0c11d3a187aee930a304ac0f812beb1351c16fb4774f13aba4db4b83b875e4d7516c5ae93265993fa96947c96d5c6749c0ae34602ca79c6f8ee15240c2c41cdf72116e894935ace36ba87b2ce255537dc1fe4c0d05c923f77015af8ded25cf064af7f76bb70cf089b9c43cf35bdf46a828bb1ca83f533ba3539a5cc29a4c74d161beaab72d4141ed8f5aece792e3b496b402f76523e6c3920ab5056614c4442ff25f7777706a9ef82485541ad2b1150613ca01bb95da5fbbb7db497d08f68dc58bb92472fb12b54e7bcdf3f29bdd00762ed02a7ad753975131a1557b15110d039da5aeb35203902dd80e96f2923ea6ad43046019d19e4433d374b21150c5a453f588e47f242bc5738a58151919e3a7c60dc9d28a1cd3d70760b3028c65aeb5941ef457b9b23c849789abfb483c8e543f2869f56b0dcaf9988359bf4855dfa082618c2\n\nInput: 3413a6119b3cf2932f471cd4f4d7936140968842d7c1945a7b48dc3e0571b93a728f1ef4251a03140274c7a2af32227f7e2713d588b803b4fdb865d4396a0a760bcd888d964fda507b173cb79185d50ea844a51e182a59c677e3e0b08fb4dddaf3fb23bad8896181b84e162d32dbf083027f08618a58598aaaa3f498ef4f1f8ee5af145be8ec2b35c3a633845601bfc66c1787f088e17daa5992b31d6493337c856da11c26cc3d29ffce2c11a0034923483df5f8a9f7d5955f40d1ea9ac51c1d8344869133cd875d8c076d914b03317dbcbd6f4eed72145819f2757f4d955ae2cd38adb19b85dc0500aa712e6945460a8cd4d3f09edc83398553f601d9e7a19e0b8a08c4648a0f3fabc94422ace8501bfc602859e4191d70dee72ca3bffa9c2febd08df3b2e43f17c4dd5b8324d2052d11c126a37fa46494864a6a2cd618c22610ac3dc27d1839443be8699683c8c358b0c3c5b25b213bf28de404be0b383e3a1749887c\nSHA3-256: c1cf289ce40c80b9d33ce479fd6ac984409d45bdc95a72c4900f88e05e80fa68\nSHA3-512: b0153258f3f4c196d85d7c0f89a5896f61edb621fbd83db8275042a7d36aa46248732c70fec94505a222cd2934a0562257e05e3874963cfb9d38a1f07fe5d239\nSHAKE-128: b7ba7f37e38e200b8e917df97b3eece431d9417f2c51e0d211b09fd5722fd66bd21e2331b72fa80d08694c2da3c32754aa08f928a41b9a34f02e41b71e1dfd0a13b69790cbbf6d90809e09f52d5d616e86064fbb3d76b110bb0b382e0d3c17407e1bb9017104220b13c03cd58c1d6be9628c1522e22507ee6986a1c59485735787e91c3f6a840d36514bc5a5fad34500b69bd37e74ab1ac61b23f74b11a4d36451d28d1c523c8eca3cccb2cfbbfcd2942251db3fee7dd32f54c9bc81669885e24484ad7191fdc794f9a93b661be32bc32e5e427442fbd2277dc35a3dd0f7c2e94bf0f34e064af36b9939d7ba186e44bf765366f8a81125d32f3d09a340d673647268de56be3f313271220dc3bda75199ba3bea60a41e9a8ad100f840755553e894ddb2ccccac2b90d69c855e15385744008875af5b7387698c0d08f9d03545d22a494cf0782e501b904d9e84596c1fbd638bb28156afe7d15d79aaf4baab9b01ce9e27bbacebe61765a88f658bce51fec2d0d46da99a51ee7f26c2670211f821e0e797b0b97155e2b859aa02fc3dc1a95e1fe186c1110b98725fea83f7589223e3cf6391d184f7f0151fd8b0ed3f3c8a8fdca9c35a71463f0fe1329cea13b69d313b97afd5653f7f297ec7dce072b05897980fca0978d672b265c5a55ffa051fe772e521496b6d5661cfc70729a8ce48b473bb3885e90e381373fcc9aaa77d73\nSHAKE-256: 7b07eecaca4d33d2d6f0ac5adb4bea8f5ee4c9e7638f769c3da5b34735aeeedecbeff302f6bed4ad7fb61951778251dbe5301e569733a25c645e50e2d0e724b07af3030ddd8db30b32ed595cd4f3464202614689b2110a726cf29660ca72ac619c7772e560be61e972d4acee2eca344cfb3dccb766f26478728a8136c43182344608cb7324113fca15b27967bd5f779d0654ce7e07fc318ad8e1dbc2d1219f912b73662a5ded0553415af1f280d8102968f1480f8934debcd2d0a27e1f58d029a41c16269d3bad5ef8b7c42b2942f2d9aa991b8975c3dd26d7b7a527dd8fc0250fe3ff1e4c3564194d95f4d755b2ff667912d158611e988420fed197c918bccd23c074a010772583f9a902d592fd84bba2fb81b3b3e6b43e1b4aa7b0a75f516535af277c8ea3fd7d9bdf03d332ef101fb67ac8603ba5aa9114ba1c82580b1c54fb5814de43024e5db9d330b98ed82a9db0d63bdf36ab722f895614d6dedcd398d046c7165b212adbc20cc66f04e0a0e7dca87e82fc10d2ebce13a94dc24a7b013885f49524ebde6ef7b4aec0849541f99970660b4595f75ba61e8afe14bc7e4ebf52f9ef60f89bad7541692f102ba9087007ef360f7e0207666827539256b90da0a69b1b83e5450723b9c589c8b2895e1fe759aac5f34c957ee4457c5f9cbc97b29d9268f30d8eaa8e4b6b5c6d386fee22a0f3930bf307524a1e727ba5d2dd52\n\nInput: 1e83e1b93f89eb5f1d1c2d578b1da7ef19779ee3d0452889ad4c162618c5c3f6f6fb2586b10cc14ff2b8b884ad28636191788ae02befa11cfc5a6f19fce541fa15cd5323a9a06bf28680c2126be3227fc9e8edfc59d2e30439989f5007e6571708522d9cec452e623994ca40413aa0d5d64d534743b666556f2ba57d0735f63b90d35bd50b4277876709742b17b80263e3447c95760981d82939c2cf0cb0de9b32aa977ae600ab2e604365fa96aeb5e94a49645ec1d76d4a75c9f05ce2e7b67a1c4aa00db1d9c35f751a152cb1bd555c3b00b01bb9fac137b3488eea241374721b3d3d9a5b62879a74299bcff2557c8c2f92f36972fa545f1a04a9a60f5ab54fe72a28a3f5b36225320ca07fc86963243789cef12db8fe7c78e4d751e9dbe08f5d1a2de4a49affb60f23c7837c19c13d931cf630dddfc6f8d334967e0b88fe92bf9f17340a33b08605fced634e0f6e54027a4a7664d5d29475e6ce738b3e6a8c2bf43d6a2c\nSHA3-256: a18b0c0f20c5ab16ae8ea8f7ba5d207113a37cb9128f1c20eee97029141c5a6b\nSHA3-512: e46cd8cd24b625b760cb748e30ce10636c7d6a673c3578a6b1e5c94c7cf63d5a771ba2065d347a249b44498f045d8c55288bfcc7dbfcef516809a135d59fb40e\nSHAKE-128: 6268ade4d2edba105002b96290e93d0aba4d6286c67c2d113c679146c746296a9318e6036561291e99a771eb956a7b6fa0dc35fefe40e6382dd0b8ca4e64430bc3d50e7361ed3f04f3986692958ed6424b41bf17272203c3a7b90fa9f919ff28a5c71143fd290a546b08bf71ec29ca70aed60e4bc751c88aa132e68739781295a29b5ba091210211c4d4933a438ba0964bfd0732177f14424f22e817ed568a88d6aba4cf775af168edcd4b9ab06ea4fdb2c4ef876cbc0324b8da3abcf94e42e98993472793eb9e98d3c153992391bf58fcadc46993a423b8b42812e6ba9b6306116c1452d78465b055acdc96549b6d82b06b5721be08711fcef226335980eaaa83cc152b513bef3b8efbd0a7a851dda835ef80f6cd73c5084a15f965dd4782cdbafc112baf732cce5e1669dd4f3fd51d0db2fb3369a7fe2671cf80bc677274a54653da2773adb72dcdc933592fdd290e8d5d701fde5e34cd9b4599f66ec658af0f92edc8d4c31375434008d1333de530eb7395267b45ecffcc300ec01982ac3a8faf1623df28e4b14b0d975c2fcba23eb1fca6fbd9ae1ded5ad4fb6fb9722a9a54ce014daddb7a90d23ef966900c58604243f6b0dbeaa144dcc192eff378ec33c8776596c05a005023845b53b260076ea140a969f1f6974680797ab054a86e37d06ecf7152a16f41488079261fd916ea5579c35ada6809e96b4d8cf6f0e755ee\nSHAKE-256: 7b98def75be857c276f6069b4ed0a02fc93df15136073dd1ef1d4b4abc6e1e02dbcd88e837bc97410c84ce40d82a392545eb00685ce520aa8f5e34ff4a50d66b330368794eb06166ec4441e518a288aa1710e337b6d3619a99345e1c2489522c5c9da8e28be9e1fda40c4dacc9dc70545eb02050fdb8bc29338fe6ab87c48a215b773b12bd76cda4050f3cc91c0176860b12b6c18fd0e7591e9d18d29aaca522af45c59f45b3cb65b8884682a567df0b7e106dea403c04f722f6c8e70e6d247a6b759c060d1122a3c226e7975a9bd897cea98c038a889402f6c677548c49958dd8de7ac2756d62ee39b78a029dd8012cd53e55f570cd788cc4d602bc38a7a043460e25b14b96fc80556c993c71d2a5f1c26942c780240918add13d413f435edba8162f06559e0809aa2dda45c005f0acd384b647a575c2fa920a5376f39aa4d8ebf2ce8a843a4aca30edcb7226569905833e0db266c01fe61ad43d9ef92111c2324bd6f9ac85cde8d8b6199ab35a451299680f834d9c5747d7b9eb4c1dae2fdf1c82466f7a796a15afa5b43e12f40cdd042326f5ce5d34a9e17303a0e0bdfc1da87b697dc132cc0d8e821b928a41d97dd6482057ae47be210039294725446c3051d6fd174fdbb99e53f20b675d0d558d0e06f9c10213f125f72371a549711198db0d817a26f5fd7d98ad3b90caf1af18f8b2fd1f5c83eb0b9d29800c1fa1d8b1\n\nInput: b49994a979589e7364a90c3168a499d3cca99d33a2f02c33815b412aaee7c7e8d78675d6a93c5f41505f02577763967c2c536f93e140d475ce1515350b52de1266e84f0d9b54681c0971965cf0baec5da4a01cb72f7981de8eaf98da7f13ca7aabcc1b61dc00292833bd8e27da1d5f1a85e97b48c02241b6f9bbaa0cfd343485b318da4bbe96adbf7f42ca4a5b907e57edc7f168c3d42dd6e6e58450c08e2c25d7a17535ff6601345d0752406bdd0929e02bf461e69aeea4ef55804995bd1d117eb98e6fcdabddb5d58360c5d10051e057c533b59a2d04a79b0747f0249c03258fc4a1b39a91f54e67a093e47e5f1920b5ba00d9c5472977bdeaf9e7e3e61cd2546a7d9368eeccfeb21edefe9601c6464af4fa073a59833b39cbd3686ce1e55e6b6962a0bc039de97b37f1d1e3117dd2a8352f25374c98b900e332011aa2dd17aad7963d1b3388861bde7ab57d5eb8f52931133c37833cfc56cac80e8b1d1e4ebc8fb70e5443\nSHA3-256: 6ff2d8b2e81283f01758814d7a37fc6de58a0428e89f7f4cd56e72b4dc7adefa\nSHA3-512: f4076fd679aae1c3ac4af58400872fda0d6349244b830bf2", + "033a5187993099f29055d87f0216f8cbfaa24836271d823066ad030210362368a86c3322273a9994\nSHAKE-128: 32f719f88333daf261eade9b59e570d93424a002dc813ead1cc9a20699e6c805c36c6a68321bd9bc808586e560c49b2aaacb82e6bd54990d1e059c9801ee492d9df9fd07afd91ac035b1364cb03f7719f200567dcca86a6adc40a28c5b9b13879ae355ed16c3c4cbdfd3bebcdacc9239c33ed0ee5db7b7b02e40ef4e7437007d42f247e8ac20c117ba8f4fb25c9bb491ce2c9ce8045d09d3ac2ed153af5f0739e5b2cdf10d2a6e2bf479d9a2e6474757bce303e4eb2a541126a12528baca0920d1d14872163a0abdbff13b8a12678c9244f96025ea7c97f2ec33057a6e9081394a7dc62d72b0ebdc0fc32e1c81037ca0c08c815f8a6598a2fba5d4379da1189f987887c9a01270e449d4cb85a5d1874709cb7e8fe3ed7cc23112aa51cd27df17fd92b9fe2fd8887310e2268f8b54ff72de81c0299ff984baea5ce8590be3067648fde25f4b144a1770a9197ec798cba4d092f847af804cf6a87a581ac48ed42610fa0f8e4cb4f6e02b4cf7c3de7ab500ceaec645f9cd8c58e6cc2e30b657c11a9d518023b86ef39411cfaf2482bcdc445af154371b4be5c33a3e9f28c57bb8241956b6a0cd058f75c763edf3badbdda75d5d917d18570448ffa51401e7e8a44acf217d901e60ba371e0a82402b661b77762af2cd60e833e6d49b55b45cc050cc0249718736370d3616c7825a2a2828444f6d596635e7e34aeee15dcb828aa077\nSHAKE-256: db9861bf49e41992811a0a671f68dae0f3da94ee063b2c2f3a26d729302312a8a7871c7215f400ddb8008c083644e7ba96d19c381a4d354f1965313a28d0cf93ba3dfff44aab2123ce3a79b1705b98c0d3511fe4de1d3f0e76ac9d155a25ca607af61ab1c63cf5538947616ef5bf4a6aa3ba6465bba54df46b2ac14ff64725ee3636c3bea7056c06eee23d67d15d88e437c94671b01e1ecea55e9c3ac35bdb79eb5cdc147d9be87ff5e9fb52f7b7d3a5bc86048390fbaf8837f575fb5ce8b55bee040c1c1f90fd1f389a802da596133d83bd33fed6818408fc5e722da4179cc34cbd822f09c80e6a3fd263c098ec7d71dc99bbfc7cb9b542e3b6d558e1f7ba16dc14d8f6675f94409675d6bf669818856f64f30ee4425fa3fa39f43792456bfc47d2e82ff6e4327df384246abfa397033dbb6fda454562075f1f3646d8d5f1680146cffaab0af88d93a130668148509b807940f6eadf50476e829f168b1ab968414bf1b6ed8b824fe09b43a5b51ef5ef05bdf35da1c86be978789f1108bc151f3231f3f82ca7f13c03ae216c360b605582fbf1d8a87954b074ea2c6d906ab506a3c49fc3846535532059520dcf99600c82d8472430507a5c81c0c2b631c3952363793b9c55767b8057df4b1b7847ba69c11b3b7ea9400ca2a1792da759796d61b0299397ace012d0c37eede54d14c45b894d3c7839c30a59e15fcdb2ace1f553\n\nInput: 6b84528e3c91b21a0d393d7040cebcaada8d1f73be40b2bf8309b41e25210b5a3013f4d09531571317aeaa1eafd266b603b5a356ae42ef4d59f5d91436dabe4ff01a68abbd9e729eb1c1d712c9ff1df783961b3d098aa3c5b83dc5a2c952dc9b9a8d97fad618240e7b7118025c6694abad6cfb42855245a3c15a5408697a38bed4827abb63a9e32edfa7be42455dbb720903af6c4a27d371d85421f2032f0bca5084004dc4e4c1489f28aa97da9577be4522a0b357b2f3794ee755e209562e9ff33677fc56fb19e7896a71f8cb99274ecc1fa909d480d67e4b1112d48aff704b42f06eaf9d248b61c71dee5fedfd57d382ece853404167642dd70718d75bacaa5ad87c9f0ffd11e5980af896c242d6eeb840ef07a4e5ca854ef270b2e4e7222a00c05d455d43188029b7b5c02b3593b3d44e58a2107aa36ddf63c8700ce9b9155b8ca99b981c2211ba770d7216879030c333bb268b29340cb23121df7609914da0b24199acf7d4\nSHA3-256: 41fbb99b0a5dd5c5d6fa9fa8cabd19188f69c58965ed05f1f319025df3c52d49\nSHA3-512: 9594002b41e7de3c70e12a97b3d33396a9c056b869137cd5048522205276b3f4adfcadb677984803e039a79feef8ab6b4c26768caf903a3aa8b21c907072ad8a\nSHAKE-128: eeb112de75aa7847cd1a8b5c28dce7364c36820209a75d05dae6b2b8144710df7a858ee2514f3b9f7c9fe179c2a3fc9b7e21c1cbc0e20b2b5e9fa35dbd610dc79645e90ac071ab6d32f2c711bc1dabf03f25f095ddd7761004c014ee12b76a6d963004d5ddee6d49dc75ef2e33f7b42a5bd4a0ca62ef10ecc8c4a4ec578b4a9c54a4f22f781e8ec32107be43e3b7187cdd1e9f49f21f1f78ada8e979d162fb33c05cca3306c5967a7b3e4d19a5aaf0affa88042f70ff4b75c8d3ca93a1930a6124b26e7fa17c07ff44b02d1053297e139a19b41556379b4166acbc2b41d4fc572753fde2a47ca7b46f152a927dc1ab167ae00bab215c8684a9ae46c06d237399ddb6749d3e198f692c9def055a4e5671c067bbbe359ec9e49ade22b8191760e709cc35ee8546fc1b1fef3fcd7f704261e5b57ab3f6d0d6753ea43e82abff2a3f6e2ddd09d23608413b0b508f290902018c3782d870b98379bc70a5e9647cfe15d67b2d25ecb986b7dba880ad9ba748eeb7840f3d30fe0e0770dc7f77b6232041846e5bad154b1002adffcf893b3ae68398f1f1546bae803e35432915317b82616f0ac7c4c864a173295704353b8b39b94ae2fdf11f9fa1b182ba0790e7bf842b23bc901afa2e4277153b3af80fb6c411e6013d4d47e1cc03598d5a2b8ad79788f27d7ca33dd9fb34319dab8aff50b329d63040570b6737cd1f7b5635bd583c89\nSHAKE-256: 2c69dabf55635955c472e1a560c5826d802da7ee59e31dab55a550734e3ac69ea78ee59a60bb8da7d003a541b0d8de0ad34c13bb244654d4563462b1b97f77f5969cbf30ca21b75896854269eec6a792f5d1bd4058a571916db8ff196f4b525d304fe9356d6f4885d19be09f0422d2a140e340fe2c3a7674ed97d5bca83bdd52397c0cc0f42a992da1078cf68a9837e9ac2094c29403ad52e10bf82824a830be6e1eb54ce690cc0bb069b37052aa23cc0960f42c29107e2a64b7faef3412d6e40d5e5fd7ace4577e104c89743be94f9fcc68cdf1d87abe27334815aa0498c33a96a503fea0344a9c01c93dbd4c72e6d59a899359bac8aaf794ecf9d88ad9ebb1f3ee0f2355fbfaa6883eae0c5fb5de6adef78fa7e86499a4b8ea2352a256cda01fc02be095e854cf68964d8daa002e2093ec29e85f13b08df39548f51bcd78e158bf7f0973a0f7db3e572a93fd116e48070e193d499d93ddca7abd1c467eb4d6b517b9eb39fef87b60e3b08df1d5de8c283fb860f51db60dbb57e9ca95ce7925ec1464e203c7a3be44d86ebe3ecbea49a5d535e8c756f2d3a6e5f77e61b02aeb1aaed06859073f2f3538ba7db6002ec89cefba0529dbfb421e70d0958dc67b18bf742295e722abeae7a23f1521339c7ac137dcaaa5899d65b641c331b09d02da7a22582de1659d2ddb0a81fa26f7999ec3ad8c3c92e0cf1d95decb67247ed846\n\nInput: 2055e246530f6e1780cd77b476baa6020c585da2daab1ccd9e41179f5b5d9a1911c3630a0dc074874c2e96459a8e62a7ee86054d9c8a466867c0a00d76c1f2bf57fd3e5c18d9490c7616295b94ae18e7561b61419bd4a1fd6bd67269f08773e455e85664567e541d1e97577e7ec9373764fdca2373a073a9aa12bc54bece937c853c2aaa3ccb2fbb46f9033335d8cbbfd04800692dadf44972e212c142bdddd5ea949b213303037e335e2a9e57c4a1827953439021ac2d3b7462aaad99b378f9de0a8a6770d511e17128a885b7cc90a2e41bef5e9173da7a5cb964e35e914cf4169412bb68c6db8c12a8df1db1908a10c0445ab0e60f3ffafb9db4eee91330c45fe713372ffa648f3345cb9229787e0c355f6923646a5f4edb88d0c39a104bdfba1430e1c06f7cef1ef0086f84622e38f774f05c6b672bca06c9335efe0a17dd3441a58044597ccf5402fb580ee0e2a36ec41802444dcd8fa555a463996ffd8f44df76bbf0dc85ec\nSHA3-256: 7341ff19f7b0c2afa7c66a0ef9cbe0d734cb20fef053908c06a2e8a28227be94\nSHA3-512: da146795e82b046d736dbe86b3e5cb18ccb1f06fc10e2a07feb667339b7067136e8612797bf90f7d76020865c41c12a826498d672cd2c635742ed980282d23cb\nSHAKE-128: ec0891253a89d47dd76848bbd00705021fa87baf9800419d31a643247479afb49a7833367caed5a65fdb53e8ca87699ad590c353c5cd895f5fb93ce615136d62e815cda143fc04ea9a8694eb6d3e710b7bb0dccf152193bee1d6268e6eb437cc9eb80301a02fe7aa313d2c2346646d3081ba7cc2bcfa94dd0025f9367fdcc9bf9a8efdad7c197e6dd96086c13ca763f4ce1835f10601ee158975f7c0a397ff26cd79f4c754b9cfa3680c79ccf111aedde065c700cb71694e7f101ed6d33c2b6bec8df0b0e0b6bc1a8d6cfec5904173d5432615e7ac57331b764caa4b564774db2da78dd4f762835232ef50c5aadd66a13edc3d523113671a13ceec767d8185c39e957e5a9dda2d9b65fa68d63c46d7b907fb5b0275d2720bc95e4d01577b7ea72b7148a0d030ce1e3d31024bff631876c0625788fd2718e1b5122c5b91fdfe28fd3bc753c02c298a3df522df12a49cded49ee283685cac5377faf99a2cae0521c823af47914c08fc68344cce1b1979ffa07a65cf456f1a365dbf46c4d4e9d4b3b69dda19c7145f0903f64c5b11ef9634b1d4750569ba5e2ee0eb24bf0a546d9c04e21061b9c04ae894616c89ba7b3d8ad616fbbb441ff04eeb71cea0b6cac70b089eefe95e2caba70f2ab7cdbca20e49b426f074e6fb0f876a209fec8602b34dab5cc7c82a3ca91b66881a28f015eb85711ec0d91ffe8dabfa10f6c4c4a1994c\nSHAKE-256: 4f75025e677295e39e8fb9a9e4b53d231ce1ffdcf723f49ea6989deaf8feab166244193bd4291e469feed9443065aa478401f3e8c2705ca7ffee6fd96920050fdcd40e80b002ad9902db7a9bec1e8aee0b8087bfad05036d5f2f5763cab58b1df1b00f11afe28fb0fe2eb3231bc375d19b246cdf0d6afc864cec1513556ffb71ad74c9de657a9013f9303a571d70abb516e264d587d8a95bd87c690a57a60a4118f49d31ee5a4f4d11dfed677a29c7281eaac90ba98fc6d1b50c0168fa74ec2ceb297158650169c264bf4429735131ca3b48cc40ebf2e3fd947c6928b27df5607604ca8bb0fcbca15638f090d3fdada71303ce2ae5e84a1f4af14c552c541ab9354647d85bbc196384bb26271a138d138619e8136dd0d22e4a0287274b2258e5bd5e2a9958de70a26d97e7b69876f125527e07579c7720ffdcd08c068fbc69027e33a5e1b210f787477d46bdb7a3734d9c404afe9c034f5b734d24ad608da2669c42cf58ea2700ffd60ee80a9b0f35e8fe8eb64e1358f7ff4751cfee4bd49c9ae51021dcd8d721e1768db00d4526fba42ce2d2929bdf346b3749c833df2ff48c85405cec843ee3785daac3e519b63b9473919d50811e827044eacdc174e35891e6c917b0f06ac4db65f5f6331a2f457c52ef0085ec4ed1b2dc085267f87c93be7a518f7758d983d5a9b1a6458288425497076d8c46c4835378c12bb7c408bebe\n\nInput: 0d4", + "37fe03c456e85b1c31127b9ee903c63e740138fff16625030d3da087ac11f10bfa1b5110a201c5409d1ebda8b2f44a8a156c27fe6d6d7871e7eb89934d80b43ac2d0c8d525f034aaa7fcc1f0b989eb27b2144dfd7623db1180bffbfd3b51dd4c66f33f0003210a5c19a52e0b6184dc1e49a8d6187d32150cc5cf42d0dbbe2a16369c5e2324f711e889489e40757e1855f36a1d2a3689cc9a1df9198c9e7095f12c56e2c7149845d9eec980e2ee3c2909f9755aafadfd54b188342d19f4d61615238ff8d3f978695b44251726cf6f12c6da231ba64b12fc5f23bb9354db9717dcc9a9c26e19798e74dffbe9030cac53979bdad59ad48f39961e4793fe8617f8cca31e18d33d10a69586e2f4ab59b2f7677b88355dfd53419cf9c333b57788b2b9e2f44edc16bd11072f99bab25e89bd10243dd4090eb0000be3fef96ecb98339e75ab3228a7580ec5e2bb1c72d8fc0fb7e0f16e42fed547d37bc0357058d07c8945bea1a30d70fbd\nSHA3-256: 6c0be55984a5c555d7fb89e5b2ba06077423adc324d3685b88eb58a9ca10358b\nSHA3-512: e16fd08c234fd6d6cf07aeed8b75e5425080bf8b40259446d21c12a2d8f2549aa4fac70888af9fcb09e3bed2345295d03439aaf7df5e8a95cb87bfa719666026\nSHAKE-128: a8ea6c5a4131950f85a08f4d02006b141a4f4f43454b405de523810f001b32fe5ccb76294aeb5cda44ff89aa10cba14bb22507e11b8e252881123e83c937a5703900bf2d764a4f221e90c170d326b66f42628b929cbe9d263a4a36fb9e659354a413ce782b5785eb1fb3b5a60ae67c02e7da620bc3438f2a3dc44fd56181f797c0aaf9eae1ce637f11ff2e276cd004f5bd51f9077deabf7c01906440456447baf45c7860ac71433d24adae1056b0b375e099a6f6e7e19f99c14a5416ef875a46685c1148146298c40f5c4bbbbb38b188b371728f2c96d0e0a1ede3e0bc71972e5162657947783bed3de8c682453553fea584f2626004d0e6510c9aefb9d76a0b1757217bac4b2e86fad318d5f69ba3dd8c495869ae986615955f95b367cec7b7ccb81b1b434d08e77f9b64bbd5c0acad1337bc40fbddcec249b9eed8ac76875fc584f6aef4042bf06c58bff3bef785681bc174481e24a36e9d8f7a5599063af7fb09364eb8d3f25b6b9833424360ec7fee723f752130ed7634093ab5c20a9ff67b42c876bdde372bea60c08052a91dd77a206a2801a729b650dfd54edce5107dbb227ef789c653cee3ace3513f1d1e2146ad02e28f9dd642d5bfee96d3c8df12e643f6151568e553b50adce04c4ae412b1ef04a3411602c8f6bf9598a5f45e72b73c9769b57b9f228c07fd4798148c98cc0b1238da9abe3d62fb097e681fa971\nSHAKE-256: e43c6da216e6581b9f0ee8af42fbc7fa5cdf47fa339073bc4082a9b4b15c358d9c3d14420c8c0baafcb27babaf717d64b41ae739b1f13b024d09f48008a47d2c07fe3b6b78b93c11283d329f70d06702de0fdb88957e60ab253fdda6d2c5b1b731d82826e4597a1b396453bf25b5be65216c4057e8bc8d8b241091f2606a4723eb957c20e0bc451787899052046835a4a6482a21587130a70c9fc6eecda90a13efe798fe114c64d38c6d63a60ecaf7c1e945ce827335343a50e33914c7e5537e4e9382960a6a040b62c2b88f45d832328e7fe91df0a8c760371a148d2c1c755c65a812d03ef588acd909cf7b301a24f353bcc38a234c5837d8b38bfd4e7b6ed091e8e21f540e89f829842ddc21e79112fef481a19319e7063e5344ff7640b43465246d4afe665186eb1de796b07b3325a7567dedb43580efad9856b7e7eaa31040f1ee5299acd7d258b18def9602bfba9c1bb5499c33544b7e71056070d36cb15a778d75cf947e89813256be883b1d6deaa9fc11cae4ed4071ac5347c813462be871e81b6df4b11122fb21e63d691c3c854206d7f2365b904b170456125f9494b1e183d6206181124280550943dd042ae1f501e7f21a44114952186deab362a907126392c2b6b136f7231f697ad8b500ec1954a5106f4f75ea4e1ab282048139526f31f7a64932d2956db7854f1cf33b4782927275e819aee4e02a0689b1108d\n\nInput: 710cd512217036b40fccb877745314cc01b77cebccae192f35e14ec76e58deba05acc816701d64308a210f782c7b4c648acaf56c7024e73fa1a504c1faebec3fac199e3af7f391602bc0bf57a3dbf2dd97757e34cde6629cb6ecd9213e02964e481bb8a7637f6f3a07832e8974b4969a32b06590661def82619c453fd1f53aaf75701e011f4366184f599f009a3642c8c43fd9b8dfce4c6f7ca309a86b663418010adbd6f8ffe53b6ed7294c76f611f321b631d05f533dc5a8abbbc1db382f1aea39c02afc432452484b55cc1a17ba2adca738ee4eb3b3d30f2739923ba010daa78aba4a88da976e01782fd1bca66cba4dc33eeae4100daf2d4465711f5854301159b322d73b86d5aad66f6ba90ce0aaed8c86fa09eae004c7362814cbe55188cf8c4f7c44bcaca56b9a3f5139ab5455d3d26dd237898d6f5b83aa930a6fc9819ece36884700862a59ff06cc4dc03f66a1be2bcd2fa6ab0a2a919f1e3f41f9768e4c8d3d4a2fae1a8f9b\nSHA3-256: 357d8f0b537e0e1392ef6f5f3aba661a1ac06ba11dae7cabdb72d6f866e1b893\nSHA3-512: 52b6f1015d222103016acc3d27262e069bcb6d06aa84814fc8787d081e2dd69e92b662e21032d28ad87ae966e41a0da916084bd3096fe4a6118b48c38ecb1c4f\nSHAKE-128: f750d174e4b7eb8c650ad3fcfdf1c3d61a049f36a77e02984ca2bfd2a78d9692e3d2f965d84f70dfe88f42e7c043cdd8f9c4918febe1eea1ea6030a92802f7227f8cb07f962d23b0a56bff3eaa1d072b437a074470e1845a8d8b37d4c1a6841a00881a75455067ce3e679d4442d7f51787caeb4b5fab9677a9213d014ec0c69ea3ebb8b4d55b3ee78860e34b199f45e5a548c81bfc689507efb997a8fdbb814fcbbeeae7bf4d099d72e0d7a996ff1e875004e364a2bf7bb66a1ff1af2e63327c320fcb9d185f9ed9c8e45b67f7f127826462f042cb8fb8b8533583b75f0a54c7761711fedcc593633cc1de75a1144353de183d280a89842b31be1fb70752bbcdd53f557c7cd003bb492ae54b0a3a865c7e4f3c159be652dd76a805af1b70db479c0a5a71eabfdf3ed7902506715c1cc981bc67fbd26eaa92270d274e043cec5d00909c8d283effd2c755adb4afc03da248a92bd6fa22177007104b1860a2cda30aef3b551da3fd65f76dc0e3628105980200612a2a41616a82a1710940e7539494909471ed5dbc2e54213328abe4e1559c54ec452d95c88584162919cb8df3d965db11a9d9b2d44dfb3ac07278292708b00a4a01ae22f7b422283de8349337e5f90a296d3e1e444f2e45c33267c8cab487b982f944b1d589380629870616773f77ee2a9f2c0fea2f2a6b0dfee5bffc4d1611bea08a30eda090b2424bdec88671\nSHAKE-256: ae3db5e77b79c338dd2174fd7024b70ff326c33b5e03867969685a6c52a89ea3d416a63617b8776c37852cf900e36f4a30b82f866dd5286252f35a323b21b3edea52e5590726d73bb38c5a3ff3263eed114e6d801307948e4a1a99c08e0438ad15f435c4cc2c7c35a017fe7b74a3837331e5fb2a2ea67d6d8e55f0155e36f694c028623b0c3b469eac9f6f44e8bbc4749e912057a1b9c222a8b65b35244998dfc9f14ac0593d3a90376aa74000c1dd115cfa8f3ac2aeeaa1cbff060467cdc8118d69e195dc232e3c34084698ece4738aa52d330648282fa7533b7f8f1602d1218a93ed5dc45b571f2d59ad77ed4ffcbce0ba518526e7b5037d410bf93a46905ac39776e28d32bd62a0bd959ec17cb0088da53ebb8c64f5517d83155c2c69a78a9362720becc8ec69ce6fced9078db433db12745be27f351ad5972e97bad4e4a5dfd83beed239a3a74a30b2ce47bd24b478e37423bd9468294714484db1c69d89ae18346b1670931874486d1c93ac9f24dfc41e1bd6b5b576cc5692b6e9ee90593ef03755ad163106cd071589f44d1f4b893cec2e2e3995adcb8d58bf763fb0ca91a775f8c6ab274ee9f8f17e2309c561a75745a0247bd3fa4aef52d1bfe42379db6c2e1d2de4b15a2c0a9996bcb7ecc46e99da0b99f9ac082dec4889c5754fefebf0a74cf1dc072ef314b5537f142ea22bce2a603ee76844759c4a500a3258e5\n\nInput: b4932cbf47ae4e31784c9d2e0d343d53b62ba90377da1d758d938413b14298939673cb43866d99b901cca9a2f11b40e427e01eb037e58a3849e880e62bc6f868439689cefda8ac14d3396d967e43a77ffde594abcc96fb5f15a1fc752583c273d111db508076c3a07dba67d5bdc07e2790070f2233c221294d8b61a20c68fde27182ece43b9bf55d7dc018e158388443497dd01f486e47923b7130c79f6d49392f9273831a465d07d35e2bed7237ccd8f28a648e8a2f52e2855bb14be998934e8afee14f48f8b6489cf8bfaae8216e9aaa0348171e6435cc1ce517c233f1edd3ba472e817e35fd23a93dd63a5fa02075022070c7819bb3cf66d008f6fe67e2cda14d836419b5749a4d4bed6938a045d7062ef4a75d19f5f3336b799cd3b2f3f2b04050a6e83d7f683f5b5c57ab63288f8f3316a37a70a6324f6726289dfcb933fca1953b02d13205e1b37766702d472ed3bf7592f846372c0ac9719d09ad181445b7bbd04a74f31c9e36c9\nSHA3-256: 59be679aa585afb04d991db4ee1bae6ee47f2db092a82c3187b75d56ca2309fa\nSHA3-512: b31d536705b711d66befa70dcfda750a121da6ad752c7974b8bce4b06508843e959548a16adb3ebbb940c8d2bb6af9f77d93fd4e4cb8b917bd0ec1079a4aea3a\nSHAKE-128: ed5035f02232f4342b101654142f57fa8f062b16272204667287965f1e2ce47a587e9aafec851d71f7ba2efda0a9f862b3375475347410a246f1eacffac53228334eb429d659ca817158bdd430b44e2fc74d42c0763bf32f0c66e78a9b695c8c4c4900968757f2c2b9ca08263ffa37aba31de0579ef6a2a5445877dd1090996db7819a2b5e165d20fdf825a9c6665e73b1f9f60eb96a9b66e0234f93a9d0e7171d0992e955bab8a9ea08499b199d52afa1f30970f969a97701d470147309139d3aa0ba49afc927d06f72d3e6d79e201c1885ce934c930b53c86a552ce1147cea3208ade1f36a9b27f63be4c2be46f9f1b5112fff79dab5b3697df09ec4c56614cfd28e0c435a0c07fc50c450ca9a65fd06be9ae90c0eb87c4fb8ce45dc687b784579093cb59d8e30535fa605fb6de84a2981622a19ff5898aed7ce82d56644e86426e5458c6ba64a40726a705eb51e16a150e2dd4dcc7c16c3c432ceeaff86ea6c4ffb61678d3e558b96d84b2c69d3f98eeddb55418fc654bf43fe04c84822a9d5fc1e150a407f692a43aeccf29f58460bfc9aab92c78229f5bc95fb201dddcffd87591f1d9d2b146310382e6a7af24794ff1d16a88ecb28fb837157031fb7fffdedecd1e0602a0dd1e701e29e8ae3a083e85030c6200a57ff1829d64bde316e6231b2d9e3a27d36116d286c78cf1beb2e2039534c33268d97a2441ee8b08380\nSHAKE-256: 592d0b0dda85fdabdce70eae293c587755c716722ad29039d2710e9a62edc9a35f36f77d3b5e298e0e795d22af1fea2820934a4bca5758998851970f01dc089a74c1dc1ec551e0fe8a2bf2883d6e1770d2531469ad6", + "fcc938b59ece406516031cd8343cb21aeb68600bbb55ea3e7ba428a89669c20b03d607e70daaf24f59f343704488f8cc1bad59dac442a955fcd0e21a49fa697230e2fe546f57e1140c7e34486ddf971617d2f89f3e265ae19bc354babe871a0465ab1583195eebf5ce5f6428720f10270647c7823cbc0db102995031c99ca5226c206786c277e6e3ec5d36fbd605dfa81d9050cc725d045c9a0ec796c30bfa4e6e5abf588ccff47f2bf570fb87e194c84b58e501502bab04844cacd545261c010fc25f397205382b3d345496fe13e6a8084be0b1f3a6b850b0c703d6ee40c63c7e9733897f69e8af1c33db3cb524faab13162ff48a981a17fc32d8e900b6b0f1015c009d1c3f5862291712734be9c2dc5754d62284b372ab6e0417122254191e6d83d981714401914eea4ff5a920ef2ff41b8a61d10b2bfac36079a336cd2ba85614462bbf1d188a8bbe4484100b83375d7708a2e2088c0f4fd43746ece2f8753ee4e1e5c795367fef072876a70dd15027bb0b2b8763ea4d3a6579c55ea58e030a73c1997133758e23d259e50b94a0e975074a6cb29ba1e97fa4aab6242d9788c50f8f552fb444cfc9728\n\nInput: ff41e7ceefe8067419d94ee62d81548b71d4d4b79e096a1cae13efd163fc4767fa0f54a9c63ece8608e9852036bd5538a27fc475cc0a15f04d95cf553123df2668dd67dab79cc77f32266966ff1eacbd180d79830d78864d7fae65427fe57b2330f64c7a6bafad7db0a90ac8774fbd3118555b18552f0006dffc490afd2c3d96012724e3bc5b059c4a9115fb70740626045dd2759443db5a871d6aa9204aa4b3cf4f823d00f428efdac01000d60c9bc5e2185ed6f1e95b37466674d9334371fd0a454d1ca98ff6e9a602998d6abbd2c8945af77ad696d6d0f9276b69dcad3995136849f323d7ecaecd1733cf949e35076221144998bc07e42cdd91d587882d23f4b424377e52f960ec74aae61fdec839e13fd598c5883837539506e65890b434975714b939b9b113656f8af65ef142f22ec74255748c0ca1d68e7335935af3bb90bb6fc4ba1a56b145114f869020ed9a6cc9463908b8ae6424b3e82db1975c83123672fa273f846deebcbf48\nSHA3-256: ddb885156da787ca133561b8c5b7cdd6cf60de2b63d10cdaea679ab05dae1a41\nSHA3-512: ece1d6a1f4a8bd44ca1fc1bdb1707c9cb0ddcf230a6dd85040a2c277b6102c44e3a5da362d3bbb7693c3f2d1c51881fbb5f92cb833c0463a5838af4253d326ee\nSHAKE-128: 83bdb49701ad3d050d0be5e45e97d7980c345fd7118ff2c7260d2be63247bba70a23dd8a460af5cff0092a9e0515025e1e249094fee81d17ea69d927d87dff6f2a5f88e51008a016883529a3f9b8503c49b65af545bb699e34d790044e754885201422339d4f9b86049b2d9d0281d7b0a07d2ed110536fd34a2d474682977a68e9cf6a031d7c9ba9a41e985e47b6842374d0df17be3f2ab8ff1c362922d1aca0b84744d1aa195a97d2ef9e61ba9b7cf7e316dcd1297b510537230692fe0bd836ec261f1057343a7efdd734e4f5f7a5d8a9d0d3b7d7da0cb40734e3f88bc5db0c736ef5ed5ba3f722f8c22782ffcdaa4a3a88d1a1196610bbcafbe2969cf9b5e84ab281fba2d9e62f03a12c2354bbd589becab5441c41a6d058bbd6e22de69748de0faa7ac21da1549295505f282cffd53f88578220fad3fc3b4e04f49ecc2ec919596a26b9f44ed8559c9d5a58c4a436112f009a43e3c7137b6a3929126e501a2293c13a861db9da45f758a772aace2e993a6ee5f308aa948a96b2a2f2bbe8c5c57f881348f6d6d357f49ce6b5972007c78fedc77d50bfbeb01c9dfb95d436dbd3b5db712aa56aa81fc99487f11bfabbbc080e40a2720e37938952ba4ac90f3e6e049fede15990fe1d56555bfc0144dc54b30607e3d02f017c0f3756b497a61d87924776c1d88f132e72deb4b10edb7cdcbbacf946f891b24af2e1496533e4c9\nSHAKE-256: a94d06cc13940fbc4b3eaa011c4a2f5723f784194dac0b23aa62300c21e00b9403656713c5cfa08d03e971aaef3cd9320dc319602472eb3ade45c75173a3d4a1861e82529e8ef03a8941752739ad52c4af01b3b07877d5ad6866053e45ddff6e0c8c3aa5ac5c71a4052622338742f817d59a1e788d467def5c55fc9d2d00e3337ba40561d39701b96f9d6c77ec6090a12577298c09731c65274c875ebac30663edadb30ad8a301f87f2ea99a131789272f9a630a47a9060ab5079b9f7bc1351f4bf1a078f61d9007500ce4da0f2fede68a3afdc95241087ac68ac84a1eb5796196cdd32366c48bef950f95f5c0cc4dc61df7112e0144ca76c9789ce46f9915765ba409fa5c27da958c55763a0eba2f32e7a606f912b7cd95d6bc7a8e248fbb140ba3bb3e6641dd2026888ce9ec5222d2afa9112a1975882a147cbc3a19bb887f15cd9257e3972974e6f3f56972e50ff02470ca39bd8401ba8c316d436ab4723b371548d966a7e880b5e486135c22047d21d6ed60905f029457655b925483617a9d98469c8137e55cfe94e97d1e9aa8a588cee3a022a60472332829527ac7d547e4cf9453eb50dacd1dc0810acf30a14e367ae5e0d04932de3f44282f5d760c8dbdb4b51aac9b502c3ec21c7b24bca50426bc7a95b43a01fbe06438505e6c81b256288595bdf81fb9dc4758c0cde7a8a7702f6dd7c12fc6004d5b4dc641747edd\n\nInput: 8472676e0e14f5171388c1698e46e2a32ab37708f201e7b5246f28d2da088e7574bd6913384fd861981154c584f639ab4d209d7299d9e161afc733b32da761c58cbc7c8a3ec18ce24ec49593a5c9a1c54e074ed9ead07bea7ebe2d551ce41f96ec32b3f70875d4c3375985be67365ace8961b03a2a641bcd139e9bb5aeb6f6d67d3a122a1aa2c1a2e4437d01d38d1ffe35364f89424103a496eae3ea6140253256b9ece36ba074e8d95793c03e188fe5a0163d48e9d05abfcc0b5dbf237bf263f47fce34644160bb3b3d6d5fba371e651d270970a71c4c29f3dad250ca021384148d07fcad0922671872268f085fa185a8918c12ec35a34525a31975c9c0504849678347be37ec37141e39424a45b10dc311ca2b1df3cc762f60949ab1e4f75c3b313ac15db02982ea4ed04de69ef97729173e55d9759cc7397a0a999fa7a5c9603693ebc6545edfc0f3239e7f8474e6f72794431de14b83f37b04dcdd2b40fbb9b51d9190f7a6ac8f817a539b\nSHA3-256: 468b2515d935d0869521b3104c926199a780d34f30f56505291bd92f890e79d0\nSHA3-512: e41e1634754e107dd270669ad30f717ed119930f26528ed8c5acce82c261b8905ef24510a8f112486a730565bf2aa5fcf26fc9c735731fe05e31af49ff808ee2\nSHAKE-128: ec40140cf78c90a2ec2ba14d9b357ecebffa4244e59c6ed5132c803245ac0f8a722e42ab92222e5ac1302cd7ce4c3d2f7d40810a7713a22157668c95125f87d0b942ef27c814799046b1220e9e9847a9ba0fcdfec75ab7409cbd21aefee7c2753747784fab0e183719d177cd3de93c425f229264f5ea60544be0fcfe7ae450b5da9adcbb9bbe8f0f670aa7ba6529cfc51b6393718fac8f4cae53194c2ebaffbf9269467bae6684b8892b8799abd1674162b3ea264b2beb83a4db4bf3dd45a73ed51100701bff8ea2fdc658805b55eaf35333b4d82867bff6b9fe186fe5132128eb5a92497d0389d70533a5f215d34a22c62d1054b9668d68f671f49beb7d47905d1f5ff1c6c43007779188ff95280a7c3af927099d463baadb7690d9979abbf522890960c2c3f4ea70307ac19af6e6cab88f0b1d3124d7e44dfdf5df8787e651e396dc49fb6a49edf75a14dc46e57b9570280e01814fdcbb352a4d4cbae4ca70d63f446c5829caff791b26c38e8d945536c81600ad35baf4542f3fbabd20770e888857483d97f364cc9585898cb05ce186fcdeb27024694d830a179eb723bb14bb263b9e422b86f976bc6f33ce532a7ce719cd40f74c77f0f73b6bd89cc639da53e4c1f8bb5be8fdbdf78f2cae130d2f27ac3ebbdd22ffe7e99d8d96a66ca96bb66c1c636429a2313f6797bf1c5d71ddd5f83de434e5a86c6fde1b73a7b87316\nSHAKE-256: 01e5119b2f6058a2ec0a4ad9c431708242851d44fee1238fdf5f7e5a20774e649c56bf4dd5948d856c863de621f46a84616cbdb20b191749c2f0413ef4108c5045dc9d1fb01f0bb480505f2fc2b5751a4bf6f167a268507d605c2ce8a8167cea7984907087755d095de2892258fcd3e6dd25ace4359958d1320fca906fada17f7a592e63d44617f4776091b10955b1d5402ccbf8e11c623f8d72089fd5872b32e63962d1b4254993612c7c07739c689cfac0f838346bafc453e49f95ff6854e5a281ca71719f7a7b1ba92e993e23d955887bfa617fba7a1b0c4f139e25ab4622ea13a98435800f457619835e5a7d7a769fb3ff8c7195af28a9407bb53a29bd469bd54bb39d48225d47ce09e8cdbd2a0a5ee705ab77b50a6f7686c19f27c4a40eac29c8a610b2991ea81e0d25c1798a97ef15ecf5c2ea84b5a4dfe7d75f1abc14a1a4e96303021a7b15353dd16e32b5f246b73235260758909e4ddf8f9f7ae0d90b9390832f9e5172e5c98d8c2049f2e86702a2d0c0d45bb52b1a82e35b48399b332f93934f1e7bd57de9611dd24add5dcb4344ccf942e361e41b3e4e002e6238e02130e005fa30cff8d822deea166f0e36dd9c4aa0dae10fb7b59f291562e0f7a9dc81830b34319217e6771699a58226dba67efe76166218501ece0b67ef55676c04d88f292d39b45bfca9c7916cd7e1187485801f5e7164dba27168ef6ea187\n\nInput: 3d5543f7d2bd5a24d45d961345899c0b75295e3c4b9c66d0be3cf28e4a020d39eb00b228ab324014d7067802d8ebbd9f8f9df193e87ea48ad6cc115971aa00c78f1a5de4118ffb45b0796c51a3fdc155674f8c88cadf2ac33ecfff1256e1d4cb92dc58180fa77c52a3ac6ea594dac94ef95d29efb5f998e5e687294d7752cc6c59d5c003854618915f0e398577fae58c7aa1538d586f263e90ad0daf2b5ccfb9e1a0eec6fd59b4b9994749b3e4d33be8e78d9b12975872b447a14a2cbcb7f59a57cb5942bc96b8163d6c738f2c86b436b221b9b6b6368f4af519909fdd0ae3dd1c1862911926725bb61efd57815b09fe980759edb2b9f02d73cc4f6ca8510cd3e5c01c09bc15b6141f76dfecabdcb60db8c99f017dbcce8c406da45b75909a75f9b6716f20fe474afc56cce5c6e20ccf1e09e5516b17a3168b1a4e664c09c92fb7837b21c964995b38c303d788e03ee7391a38e6bbd27fd3cf1d41c0e5afbb9e47cc928f0673dc8fbd27888874d1\nSHA3-256: ae38b8caf9a9b6e8b6e9ebc1fce9e5126ae0642d372a57bc05b7ff2edd1e91e1\nSHA3-512: 188cd44ee8aa6052d0350d7511e16ddcf1c8e062f43e8796f3c896570fdcdb8a0f021bb98707fddd77578998f3ab45509a241ac809a922509fe99685729874fe\nSHAKE-128: 34831ff6905375401e4f122ddca2c05536a8a4a79c382b179ccd4b5b97db244ca69d513543d2eed6a6be5fefc79a5ac3098c4c375b9f9c27e8c5cb6fa5b9ecd0d9103e92b0c1d8d4c9cc733992261be1116f5fd89b8d3f60bb5c58a0a34146e0285da2717a730f5bf7ec17d5826fb7376f6a58eff6a8c6a6aa6348a6e735a671aae388a1111cf888a017d619bbdf067a6eaa056690691b85435c5a42016aac9502ca", + "314316724f7cd9db25dff452b2d9010558ff563a4aff7faee31a7bb681d59f285e29da0a3c864eb72dad54ec6c3aec23bad69d5534d3c9ba52f617867728f705dba937ab1707c1a886e8e983b0469a4db18f65cb47df07c2bcd0c2fed91c50a11e8aaf7a61c5feb9a6debe89d31d11c70e3138962529ab4351d1bc70042ae3fcaddc5b5fe711c1ad6d4d1b28ba808f3e7db91764e19ef231a9defe3573b2792a75e13ec0bebf35c1ed94b9901c9c62b5a8561150c870287167843ee0b69ee4226c8acff503454a24c957eaafd4e94d5cb201c4dede7027f55f718667baadfe3007ef87d134b5e499268cbd05bfce752c0d7c2d6c535e9d17171421eef1b00f7dfedd864f1a496dc0a40ca0c074f58ca944769a2c0b0d6363d88621f1b5a2e24990cfbea603f840a30c96c4c83b9823f4069d3dc4d45db3bf384574f281b4cfa8a58c1718ee348643fdddbc1fae6028cfb0cf91a8c5c25eeee07a8617a119\nSHAKE-256: b869f7ae351b87711367a931334a1065067a601482cc016d2399c5d64e33c1fc406f367dab48425e0e882f15a1f26ad82fae56aee337066705529cc9955e7147d269be2309d17c4975c0fce1d9a91b13e667616411205bb8188136e4ed627203c893bb519b8aade93007a30bbd1e7b2c1237f70ce35929801318b71a73f16848c5c7c0e456670931a6306b96951c8b3bbfb5e657643e91858903fbccd9a6b80911cda820960ab77a245172fed854f7571595c09a498e57840e65114e88348a5b510f02ab371c4e36c20f9bef1964c5a720a599f8f05df1221bede09603243ab961098a6ef728f101b8fb84ac8e72725c1bac9ce7edb4ddde99f1d1e427c5d7af473459762ea919a288289c3b4e16ad5bc57c2d65813cf9b5efaed09a42d8820333c7178a1ebdd03213a5e597f2027ff020497a21bf8b58657ed08090a61dae2ac862a562fdb35b572062d9b7726edf0ee465645d5f18db7e2c026beb9b12144911985a5445508a2c1fe6afda935c6b3c953dec3f13b31b9dbb6d37e3b530cf4d729a1fff281e6bf6c67d7644b0b047ec299e62dd328503ab12dc1e5c217d8580ab4b9d2b54b5327ad574af736d2be6506c5ae45bf417d3f25621389eaa4b4b5f5118aefb318de74a548ea8016e8df4f8eb009459b7faae98932b78d57607abb33248b64e43fe30f11882ac4c06be7efddda89e4d1da5f7e180a1838d68ac06fd\n\nInput: 7f093c2929fa050470e227343eb4a8274a92d42155940d85fbd4fcd1fdf8f1d01e50e43cfa21f7d46e14de288a73fc3553d6b1f201715b817754874af0878ef56a519a37d9abae25508b8db113914664be0492a2f0b68956cdf416b3007015804bdea660d45e505bda44a72126d00680cd3628f6085158edba7ac195c7e4f5bb8d680386c45c5730ce400b1973f523c8f49dcc4c5fadad50b639e92ae64f0d332300bd57aee67d623ef0deb964d80a64f64ea6ea6fe79bfd419a724c5314da0a43dc44423cb308957e9913ace45dfd14fcc25dd37c8af696609b52be9506361e325506ada208a6c61d8729b41ef8eca78c9040262d3f002ab6fc260bb66cf44c25e752f5e7f5d84537b6c96bd6a8579c435027652199c639551703802366739ec5033626e15057d3867608198fd1c190678afbc72e2f7b0bcd2541e9bd9ffa0664544a1f61653e9b06bee3b623309d5fa85cf398fb13246f30d6dfbe22ac94639541192df91b18c1296feddbb8b131\nSHA3-256: d9549743cdb94a921e60f3329856f19492c41f59b7da8e5f48db5c82e2871b94\nSHA3-512: bc09c36b30a5eef73dc56302bbc8729e708ee78e3e7aae2acd5f01e33c6a1cf32220db2b9c56de23f60ef73f47e51f0fdfdcc990bca23a5ce9152299128993a3\nSHAKE-128: 1e703a44d498b273ae99e8dc83267cd30c0fa04d759c8e6df0c3ab9291c2a32b1259892ec59cffdcede0cb2a817c9d5be473618d012e76cbbed9bbb60e750b3d292800c015ef8bae84088044be61dec55c53af6edd24f2b2ff77509e374c23757477348d9989f2becf275dc1e78bb93d6342cc2bba49a3e61ade2a65bd4242e3595db783f0c905542ffc2674336f7249f05eac7df5fe34396feb9f081e4dc33b92788101eaea79052cb7f580d3c77c4344b9fc1d5ca53f1233311a164ae9669eb02d71a64ee27b9574f727e6115f94255257473385efc02c40f513424052630fd50b30e76ef81d93d36ac5f579f38b65a932ceef0efa1316fda43660471024d03b4d95228a1014b1a7023308204c26800abf014f6f6127b0847155706eaefcf2f3c3332216cde3c1d921f34675c9c095bf5d0ff6bd89dbbe96f4067f1854422a1e3d7ce410f5b79c7e6129941da8df125efbf3da5f6ad5bfc408d8b16ad6efbfaf21ac0f0b0b48714e9d45b00d7691da76f42ad5cc94e04e4609dd416f5024296a5fee0c626b58e4ac3ea6f935f03071572bd30411ccaae53b940337594366a0bc1cb55204236ad08ae39825c5b482a3271fd1a1efa430fc3d2af87c212adaaa20c3b20dd9fe4cce80485a6e83dc79d1dc9eb4739e8a7989136e4679de327f46b7b5d29d8b0dad9ea06f59c80935b204ec7b10d78e9ec1ae5ab25c0e5619dbfc\nSHAKE-256: 8e169144ac47b224d1d78e54ed095417ecda2307d0cc15770a5d3366ad86b6087d624abae8c62a9cad80fa19bff132f8dc8f586e3009af4a28ec4fe4ddf72f00ca1acb66b00b9f6504ef2be037725fb269449c91ad1d0b8ae5b905dc073f2454c11d41c8cc990bf001c874318378fa967397ba2449c5d01012354237d3145f64e9a8a01354036f5e113eafcdc85881e038b0d16a0f21bc35c18382c7d5544a9880219a354aaaf348d21844d8dd771d6e5b48cf3d514d1a55e6e456cab28a1fddf4d8c42366d9dad236d75f5373e54fc70edccb595d5fad5aec724e607262bdcf2d0ba51585450cb0b3c0602cf612f224a21d4b9a503e1506b52633a5baec5324818dfb2bd46582b11e742784f268948c7d33bc0940060fb7255c39d533d853406815968d7432c5c529a8540e998ccdfab1f5eb58ce3e808fb722d6f3758582f5d2ad4638eaec3b7b9587f633d7c05c79eae629f00e5c31a6b67f0462331c128f5a8c6f6ea5676e4e7a0b2d5949802b4a07e08bcf93f2a8b426238d230e08889ca04e491c28820ac6825a33deb6146cd04466954a713ff8af4d4a1d1c8a9d873fd78bb8bacdcc2cddf776c7983eaad111e1e370662251fa0df1d5c72ba8a39168810bdddaf0a4037dd4fe0709bfcdc6b1d8a1cf24544502417c7a7a96cd8c2c0eee3a49397feaf1655c42ec5cd40ff9cf2a325f78f6a28b98d37bfdecdb652317\n\nInput: 79f55736f6eb47a4f6f08c34f6bea1ebaf3054ba3a80692ae16a33af62b72a963c2a47339f57df99cf4b3f2b41d78ea21ed13d110fc097f3aa53aaa665b2e5be83fd22f5c62b63f9ee7f34f399322b5508571c18e37fedb6865dfe8c23be63ff12f117f5d18bf1b370afa431fbfe12edd271d22c30775141f7ecc47502a9f8871d5001ca73c15e2bdc628746c61696aaf3df4dbd6efca1a25014582683ef1d6941c6d8996f710c2711d86304abc7ba96528f57706b31dcfff89b2e127e56582159de8ef5a63def90b9825f5bc5797f7cb5919d5d451110a7cb6d17fe58e676e3b6a2f3089e686af728fc1ab62cce004e228a04f7912558838f90b1ea358394ca872d12f1dbe43be383308478c51628299a99906ba6d879ae8231f2966bfa035f17f4a566a9245e5f48a971458c2b439854d1a0183c3d9e9a5a9c03beda15f4dd66d3e832004221c2f516c2fd857a3e263b442419a9ea7ad3171bdf55865169cfb18dedc221ae11b4f04fa5f074105311\nSHA3-256: 350fc2df4d21bccfe57d4b3fa5ebb4895b34de715e360d299e39f76149a80870\nSHA3-512: 3b2cadc5fcc078f3d246ed4919799b35da619cf8db35ac731e9e6a2ae36ef8061c080bc44e62e7e657618df83607f651c5227c6992f727486788c22ebcc4736f\nSHAKE-128: e1d159ed87c02a784fa248b430fcf6a26b7f984046c83c16579b6b3fb2f14b1273a80fdb7d07187e2a935b8b121c389b92f647ce49f2481f944b6d61d763bc961369553e4230d6570693ab95e41deef5d2f67a80b3413425e71767c1853ee25c2ac02cc14844024ea2fef7d55a6c345b646b9a29d81aa9d3dac9e5ddd0efdfddc732b3cf2cb4f603cc99fa8a7fdddcea891aa9fd5e78afa5972502e9e351f200a67ae30e76982482dc05f2aaebb2d42f188ddb38ad27ed177d38af420f48be91cd3b99e228089e83354ea30654b17b13b7cc141bc3d732597f4e74b0e7f74afd9b8a0410a1f82257f548da8b5f41e87fbf820cb8fb585ae62e63b280959c2952bde1c8ae816264f7673ffdc39d2a215aecd3edc47cc15e8cd3290cb26c39e7f75ae57beb8823c1336dae6879c528e7e5cb72b97bd8fb5553b0722544e1aafc74afdbd511ee698366a42e9aee9a51a93c3893e5b16f05da5aa2c758ba0218a54a1f837cac8bc358ea077cdee3aa50056de3854fc9aded4d9ae647e9cf3cc152c7c41c556b08d9d094c109d64a831c7f956926c2fe456aa58952df717721a2ed3b17f0fdff5bdec760ba091b9aec694ce2c1eff2207df7f3831bf22f8385ab2fa70afc78eaa7b2054b37f324bc1284cfd89d56dc693d8c81a2f620b94e894b1f281cbd90602ccb87b36a257a63755829eac9053c36b6a710fae4486a76688feaad\nSHAKE-256: bdee6aa7b2eee31398991b9aaf2a0f660917dd34bab28d653fdb005e983ebefb571ae6f056399a43a6af2577fb0a69d5809448067c94dd5e7bb44f80764ea84f02c454057702b5d47ab209224a05facf2fa9b3285f23f413c4f21a877644baf4be368d391d5b63763192561e924f426850ec2e5257e6547d3f0955b607b98e58e8a3ed0ef7d096429a5f5dedcda71d1966e8d23c2e3e6002754c99e612fb719fe0e08b4ab2cd48539be6fdbc4bcc2f3c5ded25e09b5726c2646a553a7693ef8747242118080bcc8b82d839977369ae3e09f26c212cef8b453b995ae4a27b4b2cd555860ed05cac5681efd7458ea70bfe04a75446c72b2f1e489de672a22f285afe519838a6640c241ac49780a4113ea314b25c644f6a603a3d6068e94a896d6d876c05691556f8f6e042386c12f43ba701c5e4329331954613a44bc743a4a456a389dabdb9f4db2291c1491d8b1d822f5a5768f2d2da7af7b3681b29610f60a5ff32ccd68a82e47e6948b4f2a2eabfce99ae6a6981deb09101e13c676dff4deb9790f240fa2661688a3e2d7996636e47c0f7a96533df69a2f07f76f5c9bb0f4293679a45b8239a9a5145554d960a7c3370c3ad2d102d85d90f96fb8139eb060a36de622aecf8776d390d80ac0d93a1ff81ca43800aae57886f187bc680b53aa24c1244ba4d92c64752144b21f4cb4499c6992e3ac11e0dee92fe5d8fb41a35ab\n\nInput: 3e7a0fda6a530ac6a79b6645f5b04e28e8f27f17274b0eab84c27f0f7a9521ac3644007e3c7ede7f4140966fe107763b1f1d92f623115ffc066213a937b7a527adf708a5e5134115b0d5ee592197dfc9b401e22a4ff79f9316d8689bdbd240fc7ecebd015188a0e2b084dc20607dcd88c5b739da22f0ea862c362fac742068f5506711cf225809538553b5c3c7cc03554dce500aa08f720d58d56b81245ec830de792c3c418f3b091720b2996a668ba187e1119253e8c64478ab988cae8b216caa9", + "0256d27a55971e2daf78b49db7f62862005e5588772617b1120d40c48f358f3b2d02ce6201274e3c0308d4e7b64e6ae76b4e9a3d899c87e9d04691ff52461d4ad660c9d582e95cc56ce5a24c50f19d88138005f5ca1d5e1b086065b885933f05848b09c2ea12e65c10b69e821097f0b0b2c0a5eb627e7b14b0976cb67ae52ceafc25b97309c64f7b65f82e3f1c61dd781eb6c26915b907a8aee14669b7350a8e7628e82b633e419fc7a614803e1f256\nSHA3-256: 1c0b5de0794087103a9320d6aa49834db340addbd6adabdb257dc5e9edb29bd2\nSHA3-512: b4d63529d9bf830a5b001ab4ae8fbf7af5228dc07b07c2b7b98e8a21b89700418d5ae22c9182b118078a27c80ee81ddee3fb5b907d56b60031dc9ed12615c3bc\nSHAKE-128: dc57451c5cf77e85ad4d2bf4ae79a810708bc252ba6ffca1b1b586320759d11ac55c7ea5d555f4acdcb74bb4c6ca91722c61a4a873046c8f018a15c4a4ae0920b289734e5a3b44976495f2ba4ee97bf65b8e9e42f3412809b8ff12f0f4b9b989de40ee79ad429fbefe6b81f2606d2ef250c0d50ffd2ac8a3be3761f702468acf9af0c2a12890592d66536cc908b5a34a768ea29c57d3e63a395f4efcd4c76b4c188f1ee621a67184d38e7b5ee6d390adac0ef0075afc5b3230bb9c6a17d3797f713014c02b6b9060889bc21b3021e946a5d1978b7ff1fc418679b4f3451608f1cb1aba35d94f078094aee5c89d3c61a782899a6f8fca313de96f7df42b106a87ece413bf7a54df5ab916540e21346afa83a4e78779b2bd86f07d7487af3eb8e6445398ea05375d4d7be10cffb64675d5e1993997beb9e53e8bf555e92d06324ea7c3d10b79b32de2a43a39740cc3aa68b667d8eead4fae011dd54329f8033348f9455d16d9482d266032b4c5d818f2b2460748e7316e943497c927a18a686a21d202790f0efcdb8741cdf4cc0fa6498ebbe5a4943087b94038c398b0c0070bbb010ccfe7b67c6582e54d342536394eac1bcb1d0a11e9e7ec7cbfdfd9ae0305c4b6a36c386f1bed3120b5f7a36f153bafdb6280a88554c329bb25dcb2dcb91c8a63fba7fa9627bec86cbc513ad6a65b42e58a4dddb6655b9a71d51ca6cdf37ced\nSHAKE-256: faf1b5d5e774524da28933c3239f1c1f17ab48ce5e5ae28038cc492768589c7651ad97029bed08eab761eb06f6efbe8fbec3a789bc9adf91a9a8055cf480b448cf3284f588c84b36bf93aaa0e0cbf7967ae1b55d30b7d49a9b126fcf38d25873c4264d83fbbb908b8c59c9041eb70a2d90364c018858b8c178baef18da38f4e2136260ee9bf16c6fde1d18164dddbd74bb70c75e6ba24b9a532e3b4bf58497b20b0392ea27fb150d86dd9c66e5d9605621122e6ecf45bf7e5685a1be5d870249b22c19be13699c50b07d8a43d90cf535985c8bb4393cd2ef64907a443ab71751931bba92e7aa0e88323a67fccfdc6292061a39b9ba8c08d1840e078859619363d28ed3f36d3232281e3c3c100db8cb739397470c9a3e7302aa54fdf3f378c58a5a7deb52048c364e16ab08079bbd20d3834ef473f259330df12b69e0e8538661d440e84e5680aa679b65217694174fc81b7a502b4b33245a7b22f7e3d562f7e17ebd170efdf5634fa970d3a94d3590ba7d54ed3b5ed07e8d3bc6b527e89fd0cc6d9b1dc29e3203a18363cb170f6848b1ddb91ca66083f1763b61388655c4607c583f4e34d6f7bc753297fc921a7bcc602635818c8954ba92a8d491a405dae236c33c9d44e487d5827613160f7fe0a5cbd8c8f55e98ee645d4d63c32efcf387ec2fb272f3b09a2a510e61fc8f0d53c4731e9beacfaa2e86e6cde3b0fdef146383\n\nInput: 53051b8b4fc5a89ab0c20e27f9f718c47ace170b6123797b82f83d65506aff8aeb2f8217b074310eb2d37d2b8846166ae91713aaab668606253c79f6192a48f0c241175ea161f5078f7c595c481c6c2aa9ab64186cc1e23fb3e5a5ed4291bfc90951b4d501a874656302d3b79a9bd5c913d8a9e58161a09a2c6987b629d1d5caa18e023a8cd2525e4d23f960d74a732f64650837a8a496cf3c5f9b7362fb15c14f86ee30d7f9f4bc91554255bfb83f4c8e866949e42a154f9958d9d549b2f347b332ca54d61a88c22ebc3c8f3db75896bfae01ae250e2c03e9c4ceb9c9fef26947175394b3bb0ba80a27e6ef6aeaf4ed20d5c7657f6928d2e5157d3a6d35038aeb70956859d11a2c5cbe7e98342284e0ece2cfd33f110753a3e7fa914e74d85395235258276d105000903d6b86c2c4a45c42d63343cda1ea676ef0b800932f23f180dca17d1b2a291ea5dc2978cbd060fb1c55f5fe099ab871f318faf296681d65470b4de026e00e7fbafc5a6575bd7ddd02\nSHA3-256: 07fab39d0e356808aecd2c9de72528d3f867ef599e7fb8cbb94051c6385a726e\nSHA3-512: 7f863b5ebf33ada96fc5919bc92bf9a65ebd37cb6fa51cb1abf832116a9a5d577d608a45683e0d829cbe36c23c8d30e9c4a1482359de9b932ccd74cc34b74fdd\nSHAKE-128: ab93269839b28a7a7fda05d4ff918745f06538bee7caa2ececc062e0eba70c635d4d3dee9ddf76894dad964af32619c2047afd4bff765628814aa711b5c14a4d4d8626a83c70ecd9c13dfc0bacdae25c74183456b19a743fb4b6da6aa4f85266ce807109b73f2bca62f0a5014be736e1a408cadebd8b73c5e2532485a7477e63aa45cd124029172fa2f3925aa5178e18c32674d487524fd9a765f986015ee18c9e1d202f8bc1637862ce57698b89429af882ee687c140b8af60cd1bbd6e5678b58218d4dd4129e7f664fda82a93f2f68624c2eeea319feb934407b5a7d428007154875a63abd0f8645d2fcb12fa776ed9200c4e8c1ac3ffbb165e7138fe6ca9eb181266cb0e98d1773c1c31055c0c356bda45185205f2016f0dbfd4d5f47c9c9cb733568f6ef3752b0fb622ac902b19b635790a3ab32e401fba8c91a1426f8b11a26de92b6ee475678f63a27e59b58f91dc03f80457bcb987a4698fe04c1705ba17dae89096db3f55433de4d88c943ff9df0ade0d568a658ad392105cccfd69d62513f91a4ccae08cbfa07074718717b9777a7105ab8f58a7ee26a63035af912fb6268a1a2bff91e3e4928a75de118fea3a35194b44ff7979722bdbdf12741c1aa213dd6dcc4d714364fac0a07dc9278b2470c69de469698717f541eabcbb2957899fce17fb34b98112e1edc8048155ff5f66ca72b974412cce156b69f8ac8c1\nSHAKE-256: 8dd6e97ce78d1f9157aa7a45bb308a3cf873f6194459454c04d7b58608d472d71444597de1a9319055bbdf499776fb70e9cd1302832f78c3a1e565b91fa3d18d867e6cb76251aece710a1532057de929f1c795a04a098f66ccf047d8e31b75f983b4c8f73cae36d33688556c70a19e7bbcfe4d76cc9a14fdc5ff166f7e0ed34c7f0f8c99c8d08b960ecf4e3a7339191a87df0b97c87488b2019f03375bbf1a39c6f867008e364e417b4a8fa394276e34bc6ebf3a0f784b14fade577016620fa655ddc9aeaf2ecba970c9cbd1f88dbdf1e3ff1c703a2774ce2a5083881ce7e5a4262f38cb263f665d9478efbb5147ea902b2bfecff75fb24947822aaa27fcf1d14eaabefcd9e0da31a2f330bc3eba770c6699133667807f5e99ed800aa3a7aa5d271646c083debd9f6f3f903b81f3ba15773cfe01c3194fe2c6813cda2cbee02e71bfe3f4b1a7689eded73ecfbd4cca9a8bb75ec25566804ed74f97914f96c418ac8e3315994dc17452964783c904a8043e3cd09ec7cce5e4b86ced213c51bb69b37901a61208821ba37721d6a0cf559ca0ab2e25f22f12f4577ddc9265bf91cb5d3dd5a3453b5d5d626bc0c76af20c8ea16c31d5543f5eed64f3cad4d96ce103d1f093e5fcd51bc38bcf0bd12f092e4f2f904a575153c98306269a583c4d3e772574279e717a8aa41a0ee1ad74b1fc04558fefb2d68243c72d4b8ea49139c5f7\n\nInput: 1db4d3cfafb94e067507938858fa4573864709efccda1af4ed62250a1a7c9d70c6c30b1e3524e961fc4dcc131b37de34fe623678a39879dec86515ead0683ad4a6a423dcec529465be9024459a097522ba904f1437f01da34bed989a2b7b82b9e9983ff17d241ddb707ac653900f2f9263975ad6e94b30d4678c6b00ac809ac9e5a40b6b0c96ab1e27c5bd0bb8cbe05cb979a340e5f46e501e2a55d096ff4a878d9720ad136d93f6aeeb8b98918843a859bda5a65c73cf38bf9733a56c523bd22eb7005f0679a3c5bd0ad776563bb2e0a4fab8af45c60664dbbad70c3f4f3f6a3a443f85a67c96a475d131f95c3adfff2babed90a5677ea2c8fe6c66bcc06d83bbb8b4006704d5a7ea1173baef6042a826d150e7fb0b8986223afcb3148ee208e670d0485439d8e3355298f545cac093660fae653b72bf3a4aaa6c17d80eeeb289b3c1a93e3ff8e596d589cfbcb5f2869b7cad1dbd3a9e434f51e72aff6ae2e2f10253d333085d99e89e3d3d264627128a064a\nSHA3-256: d4e05ef94ddb47885e96aeabf65bc9c53ebbe65d9c85ea76cdb6b7eeb9656b41\nSHA3-512: 4fc7ca976cf3ea1836c15f4e81b7c85031833f4781b4a32eec1287daa92636462bd1547f767257619e4248bbc0a683af687018a3e0e3aa883a339ae93e0bd636\nSHAKE-128: af93ea7701c49591fd65b0dcc4a2f728072728b8e7dce8c06173f481f451a62a8a5054b56e4daebef18a40308b8849e556d646f4cca015ad87cf09ac9dcf7659b1c281ffe7c058f80339a4879146ee9063cd1b3bd65835540b1cba47667e358bce6551761c15374f651dd4eb4a6c04d3c3e544fa6f92911a8f77382d96a0b25ce9f4b91ce245084d699b6032fdace30a1ba21f1123a625a09c5ddcc3e9dd00784f9bc2d8a85798e4c6d51012df6d013b6132e51d030bf85623119889b1dfad4935e1bce70f34db6590dce4b06d264b4c411ae5b17794f1997aca3a982bfbcd8608106c0447d37cac40408212b351aee54a9c502658771b8782cd0c3ecf53b8501f9eb5af4b2cc1b7cbb4f7d949e26cad2ddc9bfe7319ea4ffd4642df066dd7678058222ae76708fbdd12159e8d4a797d7477bee9e88cfbc938c17d148a836827c99edaf3b2450350038d42b68dd8b691082941edc6d5767c720491d647872094063964365f9174b4d03e0407a91398461db6263b49c49745f868a615eeb53712624b342d2d55170293a925bac930463c58ea51622a7023bbfae5d3cd0cf5051ca5fa0d46b73e8c7bddbecebeead3f4d0bcb4468bdbc5e5afad2ab384aab6357e071417b955afeea3af494d6a16acc7cc13a93cf496a0f4491751d340f98f3a2e7eb54332b6e18cc4ee5fb3198cd1830f32702275643df6ab26ce5049c695c746\nSHAKE-256: ed886bba79a7b38bc05c22197b3490fe46c12bdd2488084ad0942a0752375fc4da8df0ce393cbda431f15ea02abd514a1ca2eaf21ebba072ced38a17f2c39a8881f013ceced1b6fa05db38e7be395d0a569b68edff474890ec8f125afb9dfdec83e910179d93362ec483ad30a498ca198f3e84125f1e4adc81b8bad82b951e948b4e8f84aa1d0cf7a32c0d44d40933ce587d923c943fbdbe7c22386a7a65630566dbe8d3a129ee2d8778f87c9ac5e11f083e3f4ae3c92df2ea1b29e1a5356bd0a9c0270a86b8022d480282c17e0e23c9ffb8cbe74cba309f6bc151c607bdf3e55a4d4be7ed2f23f84d3cff1d3a422cb514fb14e15deb3be31adc3a3c0e7", + "c2a70799c4e7339b181b86cff1ae6b04b9952fdfdc1a29aded29a2cc44941bda0c38b98b26f1a0f42d47e4e1bd2891a1dbbd343c332ced96031d9ea91048c504cc3b6f89fce428e3c7865e96718eece7d60d037ff1c7317eb0fcb12a27a05739c50aeb84caf7b609ff2ed638494cb1b65294a817e0fb33ef5daca7260ed770121a8f20ddc54a426c0ff9d996a23400a038b90a1f7b31658e6b15ada3417741e9f21c4767a0fd6e3f212e2af1ec14be99ac6a56f3c1d0d0cf57a8fc9519bd059324d85badf85caeb4d4363cba6f3fb11558ac1757c867c450f40fdbb6dd9d5c7a74ae1294d2f95cdf2d31fd169149220b243b15181f9481fe58412e3266f3c77613d14\n\nInput: 063db239fd48d35b4cf24be7205b004e04595611e82560e49dbb5dfc3d84edf8fc34eef2663cc6c1fecb4888e020c587cf0584b5fed5aa657e879dbd26aa04ee8ece8969b3ab2037e5d6525ddabf44dd65de734edc59bcbb729f40cb1e093125ddd035a9f65c6bab5311ea5012de54fb851b52face08e9ac16869bc7c03297c1013facc2c5e41e44e8514ef0cfc5853e64d1ee4868900f8b4dedd19e0b5670dc040c985dd131a2605f4168909479bbb3cd3af92a77ce7b2603a221d898b46a1c9b4ad696cbed1da544d3ea45c2375db6c4855d8be80ed5ad0a4b392de08477de3015a9a591ffc1f9cbf29606771ead53779de65531d74f7993355fddc00cf49a1f4365a0c8a31c318538fc75a254dbb9fcc51664a27174f9382952f0791c753bfd404940cf200283807afb7168c3340407103c756d400cf171efa84ffa3d2e59ef4cae152effcccdf874144815a8bcc9f9e2129306c759da903e512ecb61fcc43c23facee1c8129403d98897f5854d1cd28d9f39\nSHA3-256: 553d970562ffe3b686c6f9af1453aa2c0b2b91ffe9f668e07fdb4211e0938984\nSHA3-512: 117af462be8ab8e8b5d88504208761c7aac4a8e0e66e3bee6516c87b40dc279ed08b14b6ab241fbb7d2fb025150b30da31600b8f485657a9acede8272653def3\nSHAKE-128: e6c75ac15183be41f6f582d60353ada52365ffb43f6cbc9669ac59409e720025adf5d410feefdded9b34ff65f85739ff362cd55d7da2218e1b46d6d484b549f8541c5933eaf470a67f6b4bba6fdcf1e3bf929410fbf8316f13ca8072f03af9d364cddc763826a3c8876555413a008517b91302fa3380bf15a34b3f904fbb153660788954f8cc31cf9a67c10aebb710713f3580fa9d2f2a7e3476d468855c8eb5c60b5604d8abb210330842d40c77294c275fd05af821778b71446ccbd2e00dfcbf2ebf21d31d84fc5eac3725304cfc9841c1a276a9b637f0481d2770b89d69c574cb9e558e6b163182e13a9a1f2125ec84343799a45dd3a3d49ca27ed7a0095eeaac6189a41016e8e2a07bca96320ddbb90138c68af46c9ab23d4a4e27a09a6b6795c4f36121ca7041dab7cb2d573c5bd2780fa74b9af1e7509afcfb9b8202615481f1b7cd28a29d486cd16c04c6bbb499a3788c66fad80bf83b7a2f6dcd636ab343dcce189509de8997ca43150ffcb216b2db81e0303c6710a69fd9732921372daa21e96f0c29c4e406cccc119d6a8776ae02c49b0851af603832d77a9f341b22d5de05c80f3e7e91717b6eef311ac39b1ea4a2722e018e07ec5180b6cd8a63690b84011204993bc3202775935cc263342fc2ba56cbc60eaab55e054d5354bd7daa00199f37e3d218ea39a067bfdfbd922aa264e60d6cced3a85cbc1b9cd950\nSHAKE-256: d4a76ba47fc4495f0e925d79415c7c693a9a0a0148a9d83a7ae9e1da36284780272dceb6d1c4c08878bd1aed15ae6876d3267c4f7aae224485308a687e4b710db5f8d6beba864259c1382626992b4767d016f363425048d3e06b054655dc9b9dd625c5664421279151815176279060bc391635d7f838b998f6f7d69e14f1dd930822751c98d4d217a1840f87532a414f0733bede11d727cae37db0d71d6e734bd1e68363209a518e29cfff65978d11990d0f264fd46c23b4109721ec87d387db320c3582ad254bbd618db27fed5c13c1c46fdc6e8667f5f4ddba233f098c7640b48b05fef4a33bb2a3abc8515e21bcae94ba856857d325dd24bca610e33a87883e2b9c34fc628e95d0e936b0082cfbde06bdadbbd70f11d05792aceeed87e91138bc05e0fda08c49e7f5320d6b8058d40e48a54364f2499f19a2ce4892909c0917f04cad80ccdd95bb702d60666102718f56b606b5759622f0ee9ccedf9978c8ea91137c0f4dc6bcdfb82dd9e8b711a094029cac9b44eb1db64f203b3c0d61392b3b65562e64baf3c1033122bc980ff6f0e7006e67d24d4f383bf5f66d0306c510ba8c6c80e91eb8ae291df7237e9eef366bc23926b8bcc7a02622c8c2f56606a6a6817fcbd618d69549a4aae4a06f29e55fb590f96ff930f83724c1dcc3780f37bde595ed3c476775012e7a6c4e42f050def7c3f31e5c6d3dd49d034f515c24\n\nInput: 273af4b52cb785e584f5626ef0c2693b5f6ca3f1ed3e533259ec2a41908af89026647c1a548248a96637c4f4bb965164780bf94c7e19658d6708ac350186a5b9a622369c49926ab3bd52eeccdea6ee373947b71beda633a7d073ca00925a968016de2fa0cdf93c845dedcd860db0b2d0713ff4867706d2131589da3dd075d12f9f4cc0718c3e0e6df3043b7f58350063fe741fa5db4d1cfe618cf6e2f2c1deb46d67b9acf1081eebe8b941f90500180fa90f8fad24143338c46a06b16195a634c92d5b5d80a19fafaa2dd74fde5decfe76722013252496bdf51ca2e098c1a41a9e9f1aff12827e548d37776f38aac556e60ef18dda9a8c3f3bd41b87f8300430c455b6ca321920fb6848e1156cad7eef650be77c28d67752ef80753fbfcdf5ea694f37704544383ff55208f22914adee265e5628f785e66831759787169eedb08bb0f8da8dbcb0860eefaa53eab0cdc4a07312f33ef830e3d0ea54887397f62a4451ee9c164d0cfa544be3cf05c18ea4ef8673da5f\nSHA3-256: 415b8161c4bb6c4819ec92468ffd5f51456742a1dfe9bb521480f2f66d83eb47\nSHA3-512: ac3a70eba484017b27826d1b4a244e51e183e25adef57ce868f0d40607a9fbe1aeecbb6d14c4f43b8b4e61ae23daaef16445ca26a014f9ba9ca745e892fef13e\nSHAKE-128: 5e14083b9161d5ff585c5a726772814d9178e63d4a3fb18df5c2fb8ddf7a4792b5d5aa6b5f3db662a1a9870e5afa78c8a885b1e9ae260c8a3c97ffe3324f03ba8b8bf9774b8061fa4d425e25c0b265de94d93c9c3f5b645516531c69a29390f930903c988f4f53f6dc40e4c58b6c665e0a8559640faa99509df7c97b9d8e6cb2e33ee5fec3f6bbc00d92f38830684643ee652580d75dc434f43c60c63bb63fd1f7817901b718f149038199322d646796e2fe3ca358e3c57fd521a96f375180762dda5160bd7224c35ddd1fb074a910ba637484f991245fbb1aa4a39504bdac30bb08472216a3c56b146209ffd13c2cf2e14dda96d09bb05c20a815e0da8a5cca12a6f4966668b06eff7571449c54f8143d05c5d711377f9dd7828df1f6f73769f1ec9f0d04b5dbd93f0bfe9353e0be5c93f80be106c708fd949f94af1559fc6131f8b34ccb8e0df5fb21203ed94f9fc05a5d8436f2ff6c7597759b4452f76485e9b5c1b79a38302ddefa58bdc05156010fb6cc1530aae6cb64f7e7d65f5ac4cd05bb0b9a9c73888e643bb8ece017d1e9cdabc9d2d35d8a40007a51ff039803ee6d32eb1e0636be5425269d7bdbbf4cb0ff09efd74cddb3ada1fe2ffce90b91650ac1fa46a8436163d69fb23a591d31eb89e8e0b2f0097dd535444c71568496b5aaedd1000dad3f69f4ecc6eb5d88e939f1048af55bece64871ed1cacd2a28921\nSHAKE-256: 9b30baaa96a20fa770686ff337a11538d18c84d34e0f44d3c12c19f5bcf3bda5cf767909d46b3329cfde7f8018e146691f64d4a7854a6566f233d8a3fd85eb0b31f2cf3c652b741a857803823519afa6b94289dd85a2efa92133320ccf4bbfff1f2b0061b25c47e8e924ac3c99aca1f64f3346087d8545b921234f96edd09b7dc7f6acb3742b70fef7f64a4f1d8dd75e47b5bd802957f1369d99a3884b197e1fa16e82035b49132083876e6c78cfdca3a20f5ea008a529434d37be7c198dfcc60ba7edfac3b4dfc02c0f2c065175455188d633232aa3e060752a8b7fd0e0df58a5dcef5e85aa0b90ffd68b1856d41b74af252c3a840e78451b395bbc50948d7a2299779b97ba312d9dedd893c0aad0b9f59f6f0618c007bb3a9de18df4b9ad0a5a6b759f5f4b99034ca6928e5f3c6666d1dfeaf038751eace2a8ada6602533b20cd4e11b77d1bbe74fdeeecbfe51fd7435b3644110e6a3e2b35eaa21a06cd16731d5515db9354b4efe2a2c7828b0235a623d2c334c8c70f6d196a798cfbe2df2af5203ba8ea0ad4d9bc72327031113885a4edd0bf15a244c6ff774464e01561caf1689092d0adfa719d150478339ed8e927aa9515858bba9e696877e492bc832a601b4d16d51da4a2aa2e0850f8291cda4678671ec600f3c68e83d5bf39eec7bb03b5648b0fbfb58c1b24522b10748151da559cd5b7352e6ef23810a4df5d914\n\nInput: f233dfeddc26b55516a7279418ca04fee102752e7fcb74d1a7def07d60cee3d52edc13921a5126895a6777ef439d31902edadc9f5352decb95912b44828694402b2ef67816e36c0a4c4c3bbe909ebb467c4408b2c2ff9ee6d620290e484255d2e0ec68d5c46cbe9897a468319dc02309a32d6c9f827a79265d43568bf439b655b9993d50fe74cd4b931424e0741a99ff72b3fe2d8cebe266060612b26693fc6f2dcd58a7d34d42469f742add897179934eadfa7af8b198a57bc36748a74c374a3ba8d224dfad4a2d5dadadfafdc4e1e2f99e9d4d5b2d60823a861ad4b5abf85fe6a4bb16e2d505e4329ecf422627a717fad1f97128f35534cd318a162c56613a4197406e109d2bc5565d79a1914b406466f3562e0e519f1ec4959ee69602534cbf3889250ff91d3ffd1dba1af06995903fb7cdcd443d0b4428786cced5912099eabb156bf8b53850c92ecd44a3258c2d598eb004421de65a7287ab80aceaec46ff859bdae0164fa91110fdee6ae2f6f6caf633d62a21\nSHA3-256: e9fa38cf69a8afa25a7473bdb07ea88833912173e112167d2353e8a85c3399de\nSHA3-512: 350532d93a5326e845b9615ad5c7df5e37732e2c4243dd54f697566778d157a89c5b578cacbe7162c58ccadab4c7e645f1fd345efe3ca648054cc564f6d669b1\nSHAKE-128: 029893aed5ba190c9bfa2d5257c27c05278bd53f1fa9aed898cba91fb62b50baca41146b3dfe0bad9bea6442f7302157e3f0e1ae553d3f20fe7ae0af5eae1d04ab5c649df00ee7c7e81593ef7c590a3be261f8b8f757c7e3e0aeba511351a42ac63aa848b0d1c17e6505153eb3a580b56d0d0db9a7e6f2747d9ebec9cd1e6183dde2433f40223ce79997fc435c3d8cc7f73ae0ddef427f23c7e665378861e904e56ad4bda8c4f614ed1aef37c506e091f1d24f4cf5ac4dbd289180dfaf95deb1c1949c62dc42788e50c135c5334be1a50bb81bfa228caeb45061ff1d96b1850dfe438187daef7f4ca5db676fb4cdca4717d7af3b8ae235dfcba287f950153daffa1ad2782e7f2bf7539f451d398758b1ddeddc20a156029ba4e1f225b3ed0d5e2cf86b36a4c52ce8233fed771053315e40f0", + "d6ae8433c0208042b6200752d91d214b8ae6fe5bcf7eaefbe00edf2b5757fab27bf7cf79bcbc6dcbf52144c9084db89a8dbf8d729a2b72eeda6b95b7fd2ab95cada881c42edaf03f971080332d0a9196182d3781f61564efd482057e8bade64b83f29a503a32abae813764933f889436da8e8f1ac19e8c91521d095fbbb1ac20c9e9cfadf4172a6bc26c211442b26055c557d04120261a5248688297fd2dc034133bfb8cb28b559cb023439224c92ab693cac388c12d0a59ab0f8408529ba7775e10829c44359666f0d259fc854c\nSHAKE-256: 2ef6f572076dc81fc29646f53f39fa9f1e581a79e08ef72293f1c53a66b0e52fe3edd90fdc732b294901286f5dfa3e5001c9d3e9aea7bf186203693eb9c0517735b6c51ad6ecd02c1b6252c187f658feec33eaf65f325e6080343aa66a9425ceb0098a5a882bab968b259c7f1be04ac65f72c098995b1ba55f38049461ca17253009acbd75b6ce028cb29db87747417c8bed508f170ee71956ea5aad3bcc1b9a5713a6bfa7c06cb98ed769e976cc9214e185c748d7177db989d718aa1ca476fc2a41660bd9c92802a3352a55154217a2a44fa4082474421f40bc52a6ee8e468ae0ee05d9264a9327c628391d90e77512b81d5427c2fc380e38876713084a3ea46f0e622e7943bada9835c2f6082e6831e7c316f37628fd1230cdcb0394aad6d2d4be0f7075824f375a4b446359035514c9f5ec9dadc58050e396b80154b026477573256be53d86e7cefe387062410ab766c67213f7d3d37ccddedab30cf6c022826680b66e4bf304859a74e3b2e2bb361577a6060912f0fe1cc394b1e8cacb8c35132d998a7ec336908a07c052b061040b1d8c4c99a5cefc71e338096acccf1a309289fa2b65b201778ab252983e2e713a3719950549c64a9bf794940f0b8ddb032de080fef7de10752de2cdde8fba483fcc52b592a97c89e289814d1d674bce5b95e5999e179ddbd8b03fa04cc9cc2342b849855b486cf2003c1140bf238701\n\nInput: 6466b51f6591e479624e49209e2fbd595678cff62cfd4a5af9e2f26077396d602f4d0356bf8ad612f9b700111a5128e6a86b10bebb56238992a98867d2f93f8bc4bd8dcd928201f51ff85f200400e19d77d643a9948793e2d1044f608e25315930f8cbb09c79e08e06eeac0d6ff30f44cc781cf1c84a4049609d6e1d447797ea110c561525a74249f999b6fc58e863aa3a514dbbb6350455395a1e766a936e00259c773256bcc1f6fe6ff0b3b3919812932234839926032397473ccf185fc45c112dfa5c0f467fee251260c42a8cb60e50332c273b07f3893c7974f524116b6c44054d704706a829394678f38d06fc7613bd6418de1e83e8d3260647bea6f4d21e111ccb33f9b6bdcecf04ff47d006e31eeec3574cc9b9a8441515296bbb5d5ea08e74f4603ec4f38d98b9b98c57774bf8b3838239f21a21f235bfbeeacffed08bdb517cad9ef8bbc3f285f5956b8e21f1d2844698618c3e4033e1a2d2c4166c3413bdded6b8a30e2278719f9a159527e0aaf34f459cba\nSHA3-256: 63518e03bfd81240756a96a681514b0f6bd6742986fe0e92b47b570c15f7a821\nSHA3-512: a7e1f722fbb84ffedd05ceec49c812f8e80909e02e0416be0cdaae37d3470d41bfed8c1118410b397b0e27b01e453bd9ca1cb391fe4e2e0424f242e9852cbdc7\nSHAKE-128: 7134614fc9f7fa355f3983ef4a72fd3682afe10084e71503f0856b37a8ebe18471351d15c271fcae8107b4bfd45d15c30f030ad3c50e119bf20868ba24df8f8538d05fca103401617bd083ab015521c8594a76b368753b0a379d7db7923271127530d11554a389cc0a7d45e708f0dc774d94cea84ab6129b9a28fc9c44b526cfe0082da8fb0b60e83c538158a43c32741326362aeb0dbdbbde5303848ba320f6fce8166cf2a25dccf9a81d69a879eea8e8f0d564e09e3c56c72f0a6f03c9a286ec9981c58b33677df399cc866c79c435dfbd77338d0de0034e14553f85b8c9f0dac710a4c0f137a23fb5f371b7f260923752e8855a9b8ccb9a6523d87574180a57db35f22b69bcda7cfceed087345d4927fd065fae4d303ad8f642fdee9419b492733e84c1bc2202e5cf746989f5cd2f3ba6860835950d0906cc5e8b2e6f2076e15b474361aabdf8bde41c6ff1a48c79ce18d7902c8058f3e1dd277071eaf6d0b3d42023450191b8895fcceda16d7d32b043f8c5d25e8e99ec6d63dca9c38f9f914f096febd752512c93c6d6eedc94ce6b72ad1e84c6f58e069d44b58accdaef9b72a64770683e365e70759b635722d71091a012782f8fa60e7ded07e2e43966f0463ff50f1586a659731999bc8253ad74209f65acbfa004961cebdc0e64257891eaa00172b27db638e5c8e7900c3d2b175f2cbd8a3068a3b59240f28ab65370\nSHAKE-256: 226c7c529756b8ad6a9e4a751bdc8b140b6de02d76a0a859974e919fde99d1f78f379b9f49ab65c636ce7bfc096d5df12cfdd211f8a7b51ba472dd79f8eae9df7313945ad153dd193f7690fa27c2bc9c7d23e944ca4a2a92c6c062b891c4f409fe8b9bc54f91b65b82686b3441a12eb8041beb9780647be7e630772636e5e19a0d84735bc1264129d6da469cc120104ba2c44a471c77dbe37f7fefc01757dc0a2140bab536bf4e43c9f8e60b7135a48de9e2c943f38b2a972cfcca12933eeaa06e370c4159535aa55e8f43c01c92c16dda07e8c10e28035b66334e60c3830e6bb4e225f4f925b9be300bbbfc79e09cf24a59167aef3c2e2bca8303727becf04da307076700cc65765339a24c4d9a2b269cb169c27d1fae981d8963b87a810cc6af1882c2ca19a79e72430be434c6fc7441139237db1cd19edfb64c123b1d78a71f2ef47181752def7187a4347af8953c64d38991fdd6d6aaf80cf02489870e4bc76a6c5bae96a6d4732d42e0a767d99e08c268ea3f2daf34bf1c9da7901bab831a6d51818892adcf8c7409a3691396e1a4993d1039292387cba62311079b3445bafad5b82a8be877078dfd46587464b197a2fbd441e49f0000163232bebd5cea9e3de74287cb8e87b85f6f919e9e2229863ce2f48ebfb4134b967f8ff0c5aff536d10237ceca8c02436706c09dc2063deb3aec39c02abdfe477e42a8aae02e90\n\nInput: a3f013605c12ef3625c8eb8b5c22dc37e11ac67d9aeb9005361f3d75df76e850df0175abba89663b215ceaed3c52aa9c0055555ac07ed266b985f39ace2d4e978494678daf3b0b3f00dbdc90288e03668b976d9accf74656f0ef1c6003fce1ac40e7647049788ea01b9dc82dd9b2c0106d1d38d3bef72d2d36577c310a7d7ae3b878c8838d023162c53de11e2c2401e07580066e16ac496adbd10705f848980ea7c8b2d3786b643afbf7b28b2cf432043cc8efc2d4351feb0d44dc26eb3884c399cb5eb6bea6f02ad3334e50ddc30fde9e98418f3e52edb53bddc8f15a447994dd1bbf8f1f36aabfb11ced082888757688b9cb2971f06f297afb68a414cd86a2768fc52cbb6a003808aa989a83e577e0398bcc218cd5844841d5e0348baaf7a1a36dbbd7f84634c27d6ae3a47b3ed4a692adc3b937d11739912c2d2e6d8f4b5c296cc1d2821d65f3456ec12be74d348226ac04fdfeda810f3484c3d3c4fae840ed77fc5cebda2231bea73f21dc0d0a426d1d9550d4de40a4\nSHA3-256: 48bae6a8effd7de8a539b361c3ddc763d04fb4094b7f267040cad37dfa83d854\nSHA3-512: f0e4538b0e0973f072348352e9b9143ee109a8ddb51761ca597ce9f5fa8778d37694e6effd97a65eb782920120a28208b15a2bde181eb5d7627834606363a31a\nSHAKE-128: 0f09fb53fcd7742616acbeaa6bc4f633e9899c3ee11a4e0b69529b9366be341851480e7729932994c4a5f0df728e130d3c1e439d2fa3b6b2d25e264bc05ac37b4e4bc85eca32f78ed0f8a4b89290ee587402497172a4f4b27e0567b7a5e4cc6876c042b37381fdacb52688c232e4062a2d6b7bcb63212511f055149cd8bba6d88d547005a963126a362bcb143be51faf068ad6cec569fb705406124693b391caf90871c0c0f828adbb12c1434193421b30bfbc3af46d4e9e645db6675365cc8b222726616101395a4aa0fd22b4c5036714f7de18226aaa7c2bee9fb0630ad63c80442bda67645400568e80809215f739ca4141eb696da726853af41089691da6b5bf57411443da571859ee2401f25985b49a8532546261758ae72d37ffc2c9bbd3b29273672ca72d06ee84968da5f66e22afc03e460e68021b3e193e9fb18baa04fded22f2366ce444a2658d137bf6c71148dace3e3daba821bb79aee050aee6087903461cccb14ca6f7038791d3ead6b37e1bcb8f93f241d1ffe9a8c1e7cd53502d92445a174b468de13cff04b82cc8f2a372397ef3d4e02902366361f9ef2e80c942f25c8f83cc70ba2cb5f2ccea050a88ec5a36aa69cf291e5e0ac263ae9e57c6e7462567a7d24aa295dd3cf43f5e4a6cbe0c9a1fb418465c75ecabb15da54bcfbcd0cc5a264b45d08d08b33ede8dfe22ee836b51f8fa59517c50b93ff131\nSHAKE-256: dee56ccf964425b5bc52bb6143a06fd786ea401f5342bf453bede8f8baa42b3cdff4e63d636726d05854099cdad117112a93f18a2601968eba0bf60794e824f8a90f67c16750fcf931f1d40df040aea62e030fe567542cc813efa9be7b299399a499fbe25c28b2a2bbd884abf1cd7f9d1fdd7c6656f5a6ccdab04e12597364dbf536239042628ea618a63bf5bc7470d27d67e77611c0ccef7d28580c213f901e254630b09ebfc3d17084ad7236a546b5e821ce804ce59209fdfd61a8a04de07ff2df29c4648625303df7a34d26c0ab857cbd2ad8047981cb8a03fa688c4e107433e552d04df07ca3ade2505a19aab14ee7c77d617402c30a06ee33bbacbec35e5b01f7163fa8f801d63a741068d2a324ffcc54064ab00963eeeb55931de38b7837181cb5f784cd1fda72cd7add58b4e06ba8dff08ff42782e851b7119b0c69a68abd186be8ed8ef40cf2913eaed9a9fb7b3e6189e8d309c39d37890d465d466a77f66ccf155efc84bcc23799170e7da83d4a467a663e51a8ffbc78e3ea27e7b24968da59eda37b03b700197847ca38ab0837c134265048cce0eb0cd3335e587455ee3a5ca7144d49b42081781df32372eddd70166c4087d1f92bb1d98f25938ea62de81c99d25106162ac7f0e33195308cb733c7d9beaed748f7428edca5554ec13e4be9d0c043fe0683b7db1638be2f06c470a922303f08c3c918eb6cabc187\n\nInput: d7e1f14b8bc81a0719044f3d66cced791958c6dcc78f2994dd572e6d506eedd89b03a1fff42f558a0d9e41d17fba11de88be029ed34cad29036c9da599fb4c4868ea777a23a0f6017fe342831299380b5dcc2e1b3b9ca4dae523058f0f624edc7720d02fbffaef7d1e155295671978e7ac8799daa328151c439c37eb4a21a9bd17e697e4314d804ba51a39e5d487eee5eb1020b51fcf56997d7dc3bdc2d65c6f441dd0baa0e729f8d353d4f5850bb03d5f5bd6e0c7c26d0c7612960b41e15acad0b19b1636ac9d8e9dd6336b41c0cb782cb281bc09f927f523b3a67feeb19886b6e8979c568f0983b22666193657ee5c26a71d4c18da0288e5995673755afa2555c41d7de38ebac02628ddcc84c4d5face88aa1e7f6c04c8c0fac4f9b86ead615af1689c3eb7be46657e7eef3ebf59e5ede53da1b197d6e884400ad78e88453145d", + "5de8050dede4d524155aa5eb12a9a9238977e084b9b30e4f662e2298946718a742f79a205d614eae8785e70f49e9b2029ad47661acb8495\nSHA3-256: e48e245ef0cdde3e372bf40bc5f77dde9870b7b67d6d8812928851bc952c6456\nSHA3-512: 9a6584142ab2c3a76d1ddd49fe5d38319a234e22788528f22fc1535a21c95c23127f68b238cda504a5f3395ce0251968b1a3a50b3918f3facfa5e15e7f49f81f\nSHAKE-128: 9a00d6a91c3c5c566482db22ffbe6fe498a8275a1158cd50fff33e6b4fac3248f34df65955a01df0dc1548f8e97e3b75cd4e3a24dff94574e70b90664f002f5d99f29e5ef78b7cdebe7e50b6197d980e422d1048fa7539b1defe20b69290f28ed27b92cb2d7c272c52b020e1fa9c0d393c465b0d9c98f0e98682063c5a3dc03996353646170be1268f580c59099c0fc65ccb1faae5eb09438ff8d01d6370d09ebd02bd25f48eb7dcee717bb007313cf176f38fc0aa528612883a617792f4ac25f50ed094cc3ddebd22ac4ccc008ece7ad943f008aa7394881e36d65b60d96b069182339044f60e2794b04fd047809d3a33631cc4fa15e46d6c2296998277087351bda0aa30e9801c35fbeaaa78b2ce410231f10a76602062d416b44d62a075bdb1ff723e707a42c3e322c20708630dc1f79408ccba8bb05b72a4eaee44baba9383343b391aefd79ed5c08afef24cfe9e8e0cc3ab627e87ec4eddbc59c808aaab5633c40c9e184681e1f8e81917d9baebdb9103fc673da7d3ff037a1ac566c87a457868dd3d64755cb19e9a5d13dd7297f0e5aa3ae157688d571d68aae34ad14f309a6b762edc74b06eb8efe84735ea65d24bb45b935339c45bf1fc402d9cc484964cd22f06bd31173c1c0907d3a6320beee230e1b02ef40d7cbfeac938f3ea46feab31b9b8a74ba93ff927b8fd2ec70dd8d01892c5fca43bc553f34b5f42bfaa\nSHAKE-256: cb98ddc5707de770fd616a7b78e3e6fd33fdfce0f8b164032cdc42bd957e0f90a65792052df20b47f1a2073b1636265c122cc8e19f4a592fcf4cdf25d81b244ed21dc06968dbbbc9b0e4791b9e9dd07390989511e1edd305bb75feb975c8a6a1d76da649bc0ec8f75d316100fc584aabd550ace25a64520f17d7a7b2c510baf99eefe32c177433cff1779aa7fbf6ea8a852a743ff8a3078799e82cf26dbe8cc3343104046c2ec7aa144f0d6856243e9507b4acd70aeb77e540eb8aa475a8de379c1e804de9b631dbae1107a0195803d8c8ed4d904e4e5327a5c250debf65e56efa1ae3fcfdcceec17e25bb2b9b4f050d5de7741665f7d362681d86fc31a692acdda00eafe1eb927ccc6472497f5f49cac64980a9ad959764fdb08777340796781cdc9d4b0aa4c482598d4b51de2a91280c2d1a474a6ebfffe770e932a3785abb7f9f94203399b26eafb4ab61f4e5edf74bec771eb1e0c19b0bd03f4f9c7bfbff35295b7c575a79729d1935f71aca546dca1cdbca00f1109d454a3d5c74178c5f457786730031beedb703ed6cc2b976f0b328e06a4f4e19f76c53fd4f8105b5de3a37c73a1b5b5777c2ac71bc88dc93979fb54d04afdb11782c081824beb5c11225f8b6fdee81df9f85459d11a2fe1bcff4c33877a19cac842787ba5c568595561ecde9c58f5c0e748e143adc63d717d5dedb81eebfd2c979d889fc970baf02b2\n\nInput: 6a7d45a2d32335609831a01256e6db34c163fd108d382e1004350aeffe77c5bb9c03e949d9e5f68c99de869149eaa8a3a6f76c746cb308264a6b737826a04d7901598c159981343d32c7aede076b1b39c06ce4c7e5398d40b2da05ff51946d73de923b69894a4c416b1d80b8c6a08da79597af31918cff619baefc935ade9a02d590f93f277ca95ffeff465f54bb11073bb8ae2fc915b3532c29f8545182bc8555c00772d86f55347c501870c771fee37e360ba6da3d310ca8f62fcc46d8ef0e21e42ff093f54ef500019f4d4e570acc168fbf083030c0fa955d6820c542ddae8a3b330663f89986cbe668a6cb09bba6a53033f0fd43b0ae780e222d4bb586f083e1c8e89f13c37428b63d8531244aca664b1673698c6a85875bf239ba9d2024cacf893b70785a27fc061f7d9d840692b5e1707f42951f12f35f60726798c9b3a8c05a5cc0ca7a48cdc959cf5e8ce5d9d70996e4e3a2c91e111340266c5745d8c5084cfc411ccea0e8d234b84b454df98353356b56482fad429a\nSHA3-256: 2e6c67afec7ee6e031268fbe1d2cc893f408d2057b1707de5d8f526ce5741a07\nSHA3-512: 86ad882feb50b573bd9abe7b63751b30c422cd622f503318c84be34f75d6352b72ffdcdf10aef6cd72b99da24ee72767683c3b004d2a238f0d1e6646bf0b640b\nSHAKE-128: 649053433d2da70c980b5112e31c0395beef3781ce9fcdc009143e9064df49f2f2853dd08d621057bef14f7edfe36038dd5481b64842bb759206662f224f5e4d79f8bd8b2999320715766c83a75f362805e4b6f63017b3b918f823d7b422d0854b0728d3dee04d8537c34835deb800baf6bfa7ebf02400e4241dff4e7ce1e1a8a85ff898944897fde6923ee50695206f07badac48564311a533d9b467f9f5defe88480767389d10fcef02832bdfbb7391d25c83f2d62849f0c4f6e65bc18e27de05dcbb8ef7decfb48610d5a62028da1b2abade742a2ff59b61161a238751f48d3adf73b246f7e4f56cc82df2754d2ff1d280e3d62b6c450bff71102522376c49f517913478108d45c9e57f005c7523a9a85ba3e0b138146d038c4c78065da6573ec4bf975e5db9e9405836853c45e2f2c39fd3739d1e9a37932ed7c6765ed31fcc7da3808ef3faeb526085432ae85e616cfb5194e6c458c1a8143ca2421450d935b43110843ff6876d6dc09f98dc6afa42c716656446e3e5379a9ca7c94ce8a6dc64a7f25fb62b7a18ba3ec8f3d7d7e49d5145dd8ba026b441973251c7a71382b09e2123918d6cb2a1eb4efbd6108bfd495d621f02621b3c447ccf177f4915200aa287f0deb871b750c2c6dccc4b037f141c9eb1437c2f6878374f557c13283568669de258d24de9713eab06daa923d56bc58f2b60657ff56a7f1ceb07f6fe9\nSHAKE-256: 9f877e6ff3ba10a62587c356289815fbed3f956d2b6b50a32297db8748776dd1381102fc6e09a19faf73a70fa74533b2532ffe3bf1766eccba7b8feb038bf0a1b993f0049fda18820c11e564806194e585ddc8ff0b826007b09f1dc47d8fb0b652fbb2df2c6bdf31a9130a072d2a2f4cfd31851fd7275e0b7caff67c3ed879d3b443baa2dfc99efd9f93e6739e6afe09e0fd9c6be78d4939f86b3b73f1990b189f60a8730d8885b43a6fe79f7b59a2e8ac3d9f637b268a621a33b90917595e98b56cc2e91bd48571aa50577123baafc76b95ab9e8203199cc34a8b90a8605fd9d563a572d80a574f81bf2b40df34c7632b0cfc2aab34c29e641f54e64176cd18d1502a9201d453d1c6c287fb784729080dc9705de7b90e85386839b08f07a42f606f4b828f757d68d1e4eb33b421a09523bdef1b41f5b4fafef5371f216a15cffce8d36186c1eb3eb7343d480d9dca3a282098c1690c2eddf9ea6416ee6700576137bbd1dd396baa3533c46d0b0cdc5afe1ef46621d4f68ddf1aab5e62c5e8b8cd4b5c9f11cbc41c54b05d735d6c51c36d6b0be28369e248dc32fd901aa8b813c29bcda8b96d3a05116b749938c37b9b5d949ce2794319bcfa696b11e42ecbae993554530a6a404139970270b515ba66779a1848a68e94480689d4bd008d3a386dc9f22af347dc8640f6d0b51d0762a7d43b0ef186811a30a8ab218b618b6739\n\nInput: e31ad7bbb43ce2961c0e604e05e8d2f40419a2c9fea01f3b8eb559507ea58e8a13065c0406b4d75cf16863bb94e1811d6e99e8ef8f6f406405ac3342dbee725a5a2dadfe482a94f2a17a20923c6bc5538f587a6c5c6d60907c3704d6aa6c8751df99d6319216a133abfb421d782132a71cde6bb6e4dae7473adf060f3420c6d2e18bc433ac88dc9e3b2338c72f870134638b26eed220a9da5fdc1ef059970709076eb1375e670945900a679720d23ee5c35f033f915e27339240c722dfe88b7c1e17ee676ec1d3095ee9556f39fbd1e6f5634a974a7bfd4de9bd333ea24a9ffb89ef8c5b5b57c229b747fa3a69c53eec0572ac560b86528c964e9c6dc6969f76815584e25250b6c33bd4947449d66de617bed688ed37e982c6f0710d6df76b6fd9a7745ef21a5bd010291f288766323b881a231de8671919c33c5f70705c158ed85376d24198ea9f69f915efc334637e851048779e302fc4044448a3a614fad0849d43efe44d2f07b82455267d59ca3ef6ce7bff2cbfd13bdb3a65\nSHA3-256: 3d66d13a8b691114c9e3ff869d47c8ead189d70000d460a0529ae71d875a1720\nSHA3-512: eba2b4a9678d1ef7c75cb634f8a913e077493e626ba07a83cb0952d914eea5ad6a8547fe650b23f92581d0f273891da6d040eae3db46914320b50e7311d2cc7f\nSHAKE-128: 2af04af8d4a578c4db3ad42443c98246790d4ea41cdd53260758ca04b0238dc63d59eef7b661cecf5323d3d215d9d5719be5e758f16496ee5e6a06902a968ab7c19c273440d430630378f95767f9afae7df7fe3245ed7d297233b5f184b771edb2c54d8b347f77bcc96b448ee4dccc16522e9651a279fbf6deaa33dd9de9970ae624dc913bad3a9a572ace599779558e6ab5ea816bb2612c618a900046f5cd4d69ae78588fd4f07fbc1d8fa808cf2aa343e660a69f83a5ee788e84c8fc9daec2f80e4ce4a09665225d8e5741f90b0b33279adf189b09519ca057c1398a33718d7e4409a178971cb2e541e651682126cf0b7989798297140ce86ad669f71c076253f01e9e02baa22e0161171da06146bc5a22c90dbda967a93f4415fa00906625cbb34ce22f2242f75c37fd063f76f619654b91641428af5981c932d10d994d55c21c2a1d7ecd73fe15e2f85f02f49f9f69097035046d42ea604e0ab336ad6c64e6243feb6459a54356badb02c9975d2ee8ec588af761b44bdccfc3f595ff7f2abb35781f1a6fc22131d452f46980a77625a3acb2f1b2d279b26c929dd85b88e0c29bade32137d7c65096f15b6c1b18f2ab7b68053032f3334190a4b94b6a497ac0ad0eae1c953072a0cacf5ee99f0b8c34148da5fb6ad5e92dfa309cf699df58617e0ff07a3cc6ebaf02f8c77e150b57424110c0a24d9ff2d9857f31481819b2\nSHAKE-256: 85721e53c19cc2f3f3543580d56593945cfb88b55534249f81c11c96015b7beb8919ac98beac721fc35195c95e3f54c9a3523a087419a02fe8991c8de03cdf99f9a8197c1e789eaa6fca7e7a2cd89660f3809127f0c9f0522c1a4691cc720868e07adf8a21d7e1434bb7062fdf9ce7fb4fbc4474c83eba1282367fe9fe5a63a4a383988d55f9a8f1106302a70410e2c69688d01b514c5f7647cb002ff4b07a6a1de3c5552faba22a6b0c87ca3fc1ca06f58a5bf24bb0606aabfc7023a4cefe295aa7a5a4ee661d97695776f79d82a505b645ee1f5074102b64dee4fe38858a1cedada98b86940c8fb1779f5890e46c30339d2d663e680bcd588a714f18aeb5fd61190dba98170b60cdcf9a2e9f710c47c47438b848e14a0437dec2c70ea9d49187d2ffe027164e986db0aff2a0f24fe5e8b45c11b490e2eae8b9f196adacb8f5c0260f1483211e8ea9d564a90171ae564760d00dd77861bb44623c564fba2934dfc02094d9f", + "bd215d9106e59386525d45bffbcb02d4324a5d1f4b45d553eb3efb17308a1014b93c7ab2d9d5dbc2b442c3bc597073f7ae247c2d69a75184da4a3eaa4592ad199c9601b883f74beb39560002ffadf33f3e21010fb1658c284ed9ddc27b2ab22c08f79d9cf7dcdbf2856085975e088ad0f5f1d4f0c3a1763c4e9dde06eab2b8b2eb4dfd9425b51f8471960fee2f101b93e527b79c63be7e4cf4bff\n\nInput: 7f40559970c22945901fab05555988c6c320091a9480ba748c9f03110952ef71fc4ae9225136bcc96a7ef04eeae9e7644733d15ff7d2347669646bc184669eaf50ff6283883e28c9032030c89029a9bed2fd1c3663b83fc15825b8b50cc1eab74fa6c9d4e089fbec75d744d0aa21a99733b71b4be494771dfb9f60ab7f684e582d7eda0761b2daa7d5a696af8b92d0af4dc08fd7adda0d00297eb54cd727185b9255ac0b9bfae7fb3570197a06c8f53f7f5e7d6e138de72b291d37bf8c1d3f1effa1ac383236175eb69c601b6d297ec9bc7f434c120b24a3c616109b19222598304522d9ff812c6738214fa977d4edcc17980a66a5c40baf7bdfbeefe4797f51e938adc9667840f32cec404a621a34143627e8b8c30121a47bb21157664e5e5b8edffda5fd91cd8adcbe789b07bdd74701544d158873c5baadd54490ee45cda3d442ec519e0744927e0defa092b5bcb5025ac69476a73129476edd14f82598fcb386605ff826b3295c9ed8120cb6761489fbe6e111bb493c5f0d521f\nSHA3-256: ccbf6d6a9b4327b709cc6a1686d82da72ef585a424eaed5bda2dfe56ac8174a8\nSHA3-512: 6913b7c1798b71b2587a6100cdc0dfbda6ea5341fbd99f0ae0bf34bd33a137d48f145472ba435569bbf235f5232ea37f0b0dd89e126285d60ae0f9527214aeff\nSHAKE-128: d14a615e8b1addf13b0a2801565d11a9f7afb89ec1148f7df09552755ba234558adbe31506ebf56c51325b59a18e2d4b88109a1861063745ee36f8cff7d54975342d4460fbb4fcec2fb8c60e53c9a96ee4c645531a055d4f94cc187a4f16281a0d48d91fd180a5350f30ac50ecd08ab510e247181f9f2af3d51a0b0019235a82b93fb6fba56a6f948cd911b1c449bb54080ebf88f59a3e52723eef6db8ec859770cbe7cae788fab23eb156e1b65d08e71a41d38aee6a14ba278153fbf50a1e7e810d1d7c8fec1145c6280a96b18b93d033e8894f8d576a035d34376bdd591fba70ea48de838ce9db91b7359e0b087b802235e91980b5c5b7ff7c02317adf3c0ab6ffa09f2e31f93dacbc0679bf8671009a8c1c63ffc8b3b9b5a2ac61dc46cf31cd43116b650ba1116aa7477b5bff7d2fb388b097853e95e35f2896aab8876276d89b69394a0dc7b93fa5843da4069341ef20ab5257bec3609e3d8f7b014fbb014ab62cee207fcf699a4dfa66c874e7144a87c289ec3cee5538652a5bd8a7accbca91b0dd5f93643aad49075965736906f2718cef80f5d8fc63605cb9d68996139f58d5bd51411c9bdb6136b984f647068250064930ebc818dbd6d2941c0774d2491e71d08b0d34e42ec4b723e36d9c158038c0a15a99478e2da6714b600666c2e6298d95960ec58f987c2c55a80c9ca255a198df0c73b00971d903ad9602b87f\nSHAKE-256: f25d1615ae6931adaa58cac66b0ccc1d2c984b53cdb776ff1dd3227d03e1bb6ff1ac47f99d01d293581c85bd6175cdf02eee17c1e57b4c270709237ea67f97dd871bef897cf3be3f1dad5dd48facd6f1c778a92bf0355af3f24ed93586e5b82798398f1f29f5a34c1b7ac3eabddd1aa5fe607126c8c693e409840ffe968fdee5e3a360737137ddea1e3e29491adb548b1b255d8f85f4943b3a2029ae46d4cce1e14f3bf49c4f3ba7c7de3c062266a0fc0a7c88864392f3d542e1548d7f7c4c67ac19c06f37481313db09adce6b98a826c066c24c6ae015f892bc4b85a90bd2fc74c4ac80b30ad32f4b9b4dcc771198886a1485c621b55be680e2b2385a1a89dd48d7bae87ddf3ddbd12534c74188392902918857cccf5f19ad08b519c061a86241789f3423880c6d61129b6d768811d8ddd88384bc32605511e10b835158d546e1657de9e3a9271194814392217689ea6f2645a1a68b12671854140beb80a1403b8b3ffd27e5d367f10e7dfd5a03fe2a94e2f9c4980b40607bd68195f6583702c04615226cb5aba8e1e0fa251550e45acd6077b1e6226a8f5e50c6a242ac144838af611b6e07b23913110f8456fb4f185126620dcdd1eca962d99ed20fd70ca37574a88396325353ba25f171d08fcc2712d70ad0cf73c82f31f0b51ff74c4611bf86d4a3bbfa429c79372ef5ae01c4df093405fb56200c503ffbd817029b5530\n\nInput: 8c389da24d19a880bb42a7085a65cdce736f7dd4f3f5d1bd21a96ad5b73939b3eee5ff3f39b8bfac77c1ce03455650bb41908ff01a7ac5d31be98f7aef9983c36db7ed882ca99be7adbad9924bb1b86599072cae8c3b14a4308c3797c26306f3f2a6ae42668aa9f57b8933d666ac0f0ce7cb1d2762ba1a2db12314a562134a98b56fa9b0d1ae1911cedf45e5b2484ed992346e4de646f7599dea8ebb0edd13ef839aa261ca69fdbcb68004f8784c5900ce31b157010786e96fbd74702c510f1bb11000b46598cff063eeb10b7821b86d84ada623664412858abbd3b10b2399837fb78e014af556eea94a4721286145dbe79f4093ddf499dbe5dfe6ca8383997474f73a3faa7e57e8e9d16329c9719901d65b98cd696913ca5b63ab7726a66fdb966a5a4fa850c245d10687c596af4c272d65fbd460a9dfb7ee14b8430f51a29323e35f4d5d3dcc4e2593b01ca73330701aedae4d4450ef2c09d9021af9fe76fc1e13ba9302c319d6c7064c7a06deba906df9399dd18e14ed8ef9c09c44\nSHA3-256: e470674845cfa5ecfb3bd85eb91825a897f9f6b3d4600a7732854e69e80ca423\nSHA3-512: 5168aa57304d56728dac134c325fd27b8df58c8f4d3dfcab4214eff6e4e203883aa26d8c20dfce3677a99d4f25376a34225fe091765a21ae2f31e6e8cc282606\nSHAKE-128: cf5393b8b011a3a69993f1bcec86f627e4ccbaafdede01d9b387d14240463a57e876004c6b68892b3c7939a193f113cf7f52dc9ddb4f8e538ca2ce7872a373f952ed380d2b51b6d04bba0d0c84d29c7a0116b7d11590a25b81abc9a77407829d3d6697994a650bc0b56221e70826709911a2f0dd9fef45cb2585b2b8571d88a14c8b5a241519d21207399babfaa6b187a9960fb71fc65ddc31d3fd15a11f5022c33a5400aab3cb91a8fb9ead3df4d46d321a4465599200c4f6feaf12f0adef7e34f3d27b198aeb05ae9ea20a53aa4aebcea2aa0fc0673faa1df65228e8e284332cafcd79cc027e67659f11cbc591193d98f05d3c4e512f3bcb790a7a4501d7b08aedd750443789bd79a10458a880ed5bd7c45075a620bb15655fe938a6e7e9fe5feed3066ec05abe53db3ce04d53a6cd7e46f064c6861484c6e26a8f722339d184438d45150657f051323564fc75af91b25b12828a397d3f33ae33615188d4971a459050d4c43e0ededf2ad7142f570e133b7b473228eb4ed0b17ca9496ab7f17c61fd42050d95d95e1130dc70f35497c1cee24ef50e82d16e2f603ce6490f1ff7e5671f4c4b956565f96044658bddee1aae4822e2d74bddc014a71cfd2072f782863f1eecf40ae6a849fcc695225551e81c654ee888e7468645c3ba735d314974b40dfdea55d7ac31efe5fbe38c0a1b577f63fd64f4b086c9d383e8d2085452\nSHAKE-256: bbd43da18bd641c6dcce368753e484a4036d124c1e78d5e9b8d6c63217e6f20f163256427158434f3785884116ed2eebed3d7011121bdc8873876570665269e950472da4e603041b23867ef87b39346382c49b4247779c412ebe5cab7b1ef12e3b4dc4cdb13ea6eafd21990a9beb179e1cdbcc3b97218e30ceb8cc9252f4de7aac1cb0d35f51ca8c517fe1b32a9ab400c9c96f3c76b458ae66395f61115b8f6ea76ddcf1ad69dd5f5331dc304c113c5ad95dad8a48396323f83bcc445407c5aca3c0274389c12957815456a94114d75dab65eb41a283e66284055a9f591cb29578aa5729e0e9b8593db079ad57f5aad8d2c95ebdbc4dbf57f8617ca246320af0617a0f1200faf7e73541178a45a7dee65a14941cd0664e03632e73fbd2e234aff217a1bcb30750ce67e5f7dcea38cc2f75d34d31a2b01ac810265b375ed9d490812c4d64fd655554fa1f29f2778728f4b53b9793d313e90e0f0a2341939db88f410694326bbedc282e2fa137a200b9ae3b1beb6225c3486583533623e777297c69a5737ff24cce06aaeae19a37892f472d772e105c5fee6aec6664988702cb7da6e65ca982e4857bfd01505b1ad86bcd8c2205b9dd051fc7fbd85702c0c1060a58dbd3587003127e55e6db5f3754498ee587e1591c5ced6cc1bccc7153661d0c18e953d4cc2572651efd25627a547f67ecb991200626cf0e33b2b11e5860b4e1\n\nInput: 16cba47718e34add507dd192af933afe28338dcfce13e944f3743da80c2bc1754a389eee1949b4fb17f326dc85495ff30994539859b537d163b3d24c75d80469e9ba9b1cb6ffd8631b04a0479c64a6d9bf8b2f65ad5753728c61a48c509cc6d969bdfb5f35223081a874218fb4ef3ff43635cb6e487c945ad990ba2439e4ca5f8e1a6e802163aa3da6426ded594bfa48dc42c364437552982ae5cdfea9a3f6d1c9a90439fd5d514d2941e362cc6d7e767d001dcdf0b05accb9441d9e5140a041e629a16893b7c4b22c2684ff37dee8b5c61a24b0c9385b0f31b7a4567ce1d0303d3e3e13c8a35e047ae7848821624b9f32bed0f818c16b573b9f83bdc412f8a4b682c1879811585b0342db1caa70e6a7f527c83a693a5efc8fd027f21b03d5d4716926be5922714a0c11e1479800f6838a0e0ccb797ac837838cfe8d68f426f95bff50e2fce90b41463a739407ce336ffb6359964317164af107052e998024bb4c8b17eb59d972c1a5248e9f86fe1715ebc020bdf506592a0b0e6dbcbb1c\nSHA3-256: 6a513ba574bf90b759f32924f95c19db0a19fe6b2aa51d27e5c935bfc2edba06\nSHA3-512: 417f38d3d5e1185b53ed0f7ac24bdd24d1311b6e5b865fa69b8fd1ad4fbf81ab1fb2001bea3ac8b324cfbf51406ff3e61bc187bf1df8e973a9d23f1586c725c0\nSHAKE-128: 6aec166190764fc462e38c0d9b4f81511ad59e8763ef7b1101afbc718a7f145a06fd9495a9bfc2d5109605a2430cad89e2c2676610fed22fa3ede665451223334b387763580463741d045ef327c91ad9f085ea33ad0bd6e3915b91af3554c11fff65ca38416201206d09e3fe595267a63ec52487feaa9a21382ec818f43e6309c12b424eeec47321ef261f8a4ad85e54ce8ec7a5c0eb3fa60eb4fcf2d5a0347879cb7953da6d53ede146d1525a81e41b5f21e34408f1321360cdba4f4799eb8350698e6d3f26dc8b9de8e5b382b074f56e210bb583ff1e06263743bd8b208ddd6d42ef074dbc55d28297640a25679665f2f09132f737c83139de12fdc0d5e84ab7e0d8943af1c38ba81ac5ecb66ac86fe78d7e69c0f70a48298926981c53a5a4359823fed8aa7c159f5f778c077bd7c44e02ddfe3532657b85210baba709a61bf456e410057e561702ef67da0a93460a5c181b5b948295f7db0264176d289bd555d7e9a509bd491efb0a27329da668e180ba22b84ea3638b7c8141f57e15080b0521", + "7a0f94b17791f0613d449b839b55e0c1dbca66df3f6b6a853a4d61fc0679e9ca2aad0a1d82e5702c3450445968f2c8abb9f5da26f0ec1ccd948e0f318b0788e947258ff6ca96486808c049777c8fcd72692612fb9412ac3c46e9229e17db38abdaef3f9d18e991334287068ec59c557a04a0fcf7fe3693e9a87533ce3e7c\nSHAKE-256: 1e80473ed498ab1b6689fcdfe5fb11ece7e87af92cedfe1b0f6fe76facfbedc30f563645584d39398c9d809bc5eed39781ebb438991c32482f74a3afa0ac88d86223de301e6d3fb0c664173250d5a50231c09bf6a6a1567b9b372120132519aab643f5349df970d00d5b0eb965f421a91e3e850f0081c6435a6ce5a44f8d2828bc291f2204b9c05b9e58be222c3c99dd61413828a854332593188f5bfccd669a17226d703bacd1bc1d896a4a13c35d02f17b34cc38b1881db6fad9b2e07a9003b8b7e5002eae75471ad867129e3215624bc2f85fdb2377033d9b74bfdc71538fe4659d81c3c4e22100fa7b403a275c02455f32ca08074e44838eff84aaa1ba4ae1217bd4b06e19d7cc69bb7edad16f279121137385959fede1f872ce30bacb6349ca3b5b057e6c8a021d21f20e1c532a417aad6e17faff0dd603f0ef55c5855f976e102cbe17a551efc3d6444f7555f9b35a5f5b83649cfd6993f105d577dcc25d4d1f093a2a15ffe80a37372523992492972aba05459674946e16ca28f690c1d61db4a29f778a55daef66a776161f533361585f34a96f6a502547e0e7dce008b538873a3b6c91c9a61e46e28f450df7e05ff77afdd36968f7cbcb859801ff415240ea6b5b57ccc04e53277e3688e9136ae0a9a3f175b9cc3d9207a419fe93393a18ca02c4c46d25c4abb47659ec413fd8555b7fdf5cd8072823fe80079f3eb7\n\nInput: 13626e24e7f6cb73475e1703a0492abde215f508da99c10118a8ffe4a1522a4878a0cff4b1b84c978da82f76412f4cb66d070d8bf510909a7622edab9e6a567d98631e8a51c3b9018c6bb142f5c10b8a18e5b1b97a5092e4042f938e3b45851c6d16bee021444460536f7126ed90b0a3bc0f0b66a5b52ff6688595fbd60fb0ff7201d55287f124baafc39ef6a4fa97cd933f8bdfd4d8ae20e34c72940f04c061ca52f0d883c174ac2537312b2b833c54e7a0acbaba23fb26da34a29541742463d0ac7d0a55685549e494cf5c4eca7fdbc502fc3323c758a744215d9a3bac9aa8a85582b3865e2ed7dac142e248e7f10d0e5a0bc4c1cf630a031c4be58435c0995638ecdbc4de34ffc7679b451298407396b5700f3eb26c665fdff6e4e72fd36c6b5c52473841c3ed23cf5145ffa231e790f8c965c142fa2f09e321e352eeda1447fdff1376d1653d20b4e71b51b892c939badb9fbd186e8dcbaf5c63bc1e46f59c2b0b90fc9d94c14e410b2e27b0c5de5c5180750b0ba5d52154fa756a94bc\nSHA3-256: 31afe991728b1d1f659bb611fe00ef10217c00dc1badb90a1f7505c43ebdb1f2\nSHA3-512: d0c77f45a5993348d744dea2e222ec582902d2e73bfdca7c6e9b56abcd0385fe0ce7f96dee837094e1f4392e01d96e1ef10131d45a50dc97b56147fc37ba69e5\nSHAKE-128: a48aa632d6bd9aa57d037a5b3392beb909e8b73e4ed2ff18c6297939b7bb44c633c79cc9d37c3d85fdd1a0f58b8c77174e71d198569431656bbd03fc500f3bb970048ba6cea7fc9a757cf0dc3fd2ed7428c7fa694c30ea77f3956e0f50cbe5aa4656ffc73be2321b20a6502294964246e13e01fe774cd1f9b2b163950a288bfd719dac09b0133c7d30041654728109b66b76ddf7134745e0cbcf741cd834111d18d39fe9c0f3d147afa853aeb415c91fa5b46ac83d767b97a3da147348ad334231c9d64174642554408e28a1cf45527adca992c44788208776c75e066c3a9c3858e56955c7112bb092cb62fafa4489f6834c650d78c4bf19715687646007597a24c35f985c79bb78d6d1bc7b93b8d039a017e597510c2dd60be032fe9f9d18663727ebb75cf9fbc49fa2e5c1d76c00f23f75ddde8d7ece33fa979bb24cb6e581fc5dd76807784e846987adaae31339a99e4a6f88a952d2b5ae5a352660a43e4b9f6257ef077e35387b0e5dea3d2f4c94d4ee70801f523166e215a91c1296763a96ee813c81f245637f8df158fb6f31ca063e70b13edc8d45b3226f832bf2fe626c2540643ac119150727975c064b09ae935d54c28d500aa1a1fde56374d91ca270c2134e5f058e75752f73d9ad22adff44b0046b219408f36007e1b23c2f5d46566f3d0bc04c8bc50ac4c2dd2e6ca3532ba5d7a61e0cdd018b6e0ea441c26822\nSHAKE-256: a9b7f03341bf9354a485e20201c4bce4c1d8c76f5440c74f8f136af53f3fcc03954b152a735e42690058a60af90875e6f075db1e485b5d06821c1c31e2e85d63fb24cfd734b75e63e0615d0b9db3dd1429d210399a36d3b84091fe89195fc68f2e15f66d354562c72a93a543a128f52409e1c3c2a01bc28bac078f2cfc34a659db28a6f7a890a9eb165a31535a2e20ef647c081676be72a136760471ba29c07b20912f1e917a67e4ff2b52edd641bb5c0ce1d857e4b584f8ca5e38ba9aeb9d2c767f11f43b949557972d8b8f0f7b1c49091052d43ec824af44039b63da0ca00857b14090c7a522a7974b0c4e8b58bbc624e2141c3170242764f9b8da4a92713f9472600bfb1a074cdc7e4f834097f023f78e370aa15075370076728fed196d78ea4279c098cb34562c84c047901b8d84922564523f3f2b94dee2425559abc601a9293a0a4a094852736cfd9addb7c4fce42161c2bd31e42b096d4e1fafa89d052a244b9e4f435d8c6a8f8c0b5a184d78d48d5118d64f8c26253e42a81f178d9877b27a47258aaa3641b6bddd8b470771a82fe9f814088d3c3a1d754eb5b3ce1215e94392b23686c9976ae4619b3ccfcb6d68d6edc96c1e22bf1c82569c64e6f2d3243546b2b5cc7662cceb0d177d10cbf5c381347e0775c2fcce6488063fa36a9ee376ba062fed0120143c702a55d86a6eb0e62a1e49bf2866098dea103f01a4\n\nInput: d4faec5b5388b6fcf211d9e2f9029edc54a8abf16caf4cc20fff48b7cf314de06433d76ca88f500ce93a0921838a2918322e82244c21fef69196d897edaf25e0f47d430c7f3a9d4b7f24e3037e1580fc390833eb0b872aa202cec873618ba1b329aeef3e7c97361eecdd35aa0719607c761b465725505087699237f5b508993ff6e4e4c252358c26ff9ad12b17709548a685e71857b580e286a86ed8f35834926cbca6dad1915fdb46ba315da0b20fe34be0feda2332fbf47c751f9a026e5b7c895e07fa834cf69bdb83c5677fc2b40c68a2d1f5e5bda92c68fbb0d33597da93a638048d79de0a428c0a4845e007db2659b3d7758e9a59ea45919aa58f9040e9ea1bca94e1a3e6094d5f335470bd9b18b2d7d2ec4755fbea06a01ad043c90e13f07afeb1b571045c050b5c66d08eeedd3c68a38aa5f97d0246186ba93b623a806f0cfad913acefa8117e349aaf894e92fc4c61f0fbc846a504bd0d522cf1d6944006d091e83e9637143c608047cbc0e1f8c20fcd63c426320c5fea65e62460e3\nSHA3-256: f84fa47b820bf7b6d334a37fde581607a86cb80971a8217841e9a704fcc916ac\nSHA3-512: df221d43584736e871d43c72fd1aaad6fc00b2af108c07826eb6fdd88e1f9a136444c7c211ba50e70c009a58d925324d2a1f1b7534310ef49f03ad3c265cbe12\nSHAKE-128: 7004ba7b2a6e45deb95e33516a9734a96220c6fefe9d43abbada5265a867e47d46d12eb821d3a389066d3a30d4b794e16297d16147556bdc6767f8aaefb74fd88f5086b097b6d39c5a1da8716e545effda1ba4d369c85422609ac854bde1b2b7cfe9e3f119651825628c9efa9b63f6368d485a4c5a2385eb83c9b6363def370b1c7969946dae468034f09a5688176534592a0c9c7f1f05cd999e015f76cdb23b085d90c77dee43896251574af8e900d3c2612dd7f281ad58978e390e4de1dce4cb9420417d5d4d319b4e78dac86ce302399a05c69179f6e06188e68d45eb6fb864499f395b172915e464064764e71c0faafbf765c5fb1ee253f82b378f4e37410b7a5523f0b622400abaae73955d389ca47ca2f7fccf1b87ebd77e46286d993938808a0244780072bcd2cf849e27a5bc8d8e5e78bbc25d6f963f1d8f23be407b7abc085b14847d4f47357dee77a9c428d609cf8f9f6ddbe61ece39dd8f252a534c401562ee77cdc947fcada36b9658f99f91d1fc48b946af467113c568368d8bd8f3d14990ddc7c370844f7d9740fbc63c6c00e3fb1e5b29831a743f6840ea3adaba0b0fccc0c5622f9d947e9066d4284fe2c185b3900b70ac056b7238d2101d76d05db48be56e9262bdd1b27c651c8931bb7b026bf6bd8d36353d2fc53ef287bfdcb296e3c8d011d79ffab1de2b85879157a7f2d2a9b93029095ae1fc24b82f\nSHAKE-256: e9b1f94a4b6e08fc50a7f4cf71ba630a6fef2790b81234658e4e2aedd9848c28f2c2857994bfb8eb7acac04616819216b7eed04d7d6272e5aa8cd0581d005560e418b1fce61d32d6744230a19a59c30163f2999cb49f6b078cdc271a1549a590b713d97a773bcfa654846835f64e2e940a5edcfa11b4b40cdcf730524bdfc40fc5af459cdf497ff888553de6367283ec0ee9ff670b590591cc41d4d8d6bf27072c6c314213c6179facc677bf2d0d3cb4a23e76a98507ea15f463fdcf860648e05c3b1566dd539b7bdd9e7f13f898161c7639c7e6652c1618a3e781c38691306c82686b85602a4f79522de823c1385926d9dc2fd8b5a909f6e0a2443ff412bc78a2a1d96ea97ccf7d730f8e732fa7033659d2fcdb2615aa6aaf604585a604ba7d276ae16c4d541fe42d5a19a17e24326695befcdc4e38ac7c229e870dc7053dbde7cf44d408e046011204bdf6aaa3db198cff29401082ead099dd38551cd83ea72fc8559040449e73c40eee930fb11f2aae85ae60f10bf24a8beebdf71862c8aeb9d8880ca54e97e4fa3bcee97d9cf7659bed111be1000cbbfb1ba4325e50b26b1e46eaa84c0a5943499408dc4722593e76992aadca6ac2443a8d2c138b2ea428e72e214619601a38ba52ba4af291e1b513703f2cfa02acda2b6700f8cb4e3ea54b8c3166591ef3331671ee7d9b07160fba395fc302a306e25aed15ac9081b84b\n\nInput: 5a1b17620c248080924d42e5a5d0017363f033b148addab4d056fd5528cd6050100fdb0bee151c750782dacfbe25a2cc030a765f9239d60893c569c7e11f0322c7c3f04ad66c15cb1522f0f99de091467ca4c0a62588d2fd328572933950dde840a55218b6240482959cb1c5268a8f103f0821c7cd2d4dd6d40641400566519cd53a56ff44a4fbc6f59475bc06d06a4977767e839eac40227bc420bdb768d370e2d586575453386b7b320d16719376e8eeab38c6c9f2e5063c791e5879cb91e5c3687cff7e8820bd6c4e8ea7a3f18056f02a756a39ca77f101be573d81f626b58c09eff76b307e16441203b40b921c2f82eadcabbd1559b34ba51c10104df9093513292ef1426da6067453cf29e3d24898175735e6f64b93237243e448ccfb5863b8da81877bb0247d0f2fcf13bea01e8ce047c9761b46ffa9144a0edba748551b062d85abb0810e54c2102aee69d1e1d3a79d5ed3b1b61e97822216f338dbc3ce815bb07eb71d2db43894a936350b22a6d56c171aa385ed5187ffe953177fb846\n", + "SHA3-256: 3a89712ca3e44f5453524009158731822e39f6d7b08896faa8ec3ff222a5f5f1\nSHA3-512: f3ce3370b8dc903e093156319b3f248e9230be20a31c8f38b983e42dff057ccbe08a1c88776b1c9e8ec0225e47f0dec7e6943e8efbda7dba552579483e57333b\nSHAKE-128: dd5b047fbbf9916b4c2ad5f76eb4efd94a78585776ec72e7aad5a47f78ba19f99b7454bae2ed240a2708ab20dd84a6c1697f6e3a4b87bfa7a49d193de7d8179c5e476913c1d375e52d4329cd3b526fc5102da95de2b38b94c7c10facb2ef9bd4f50492cb1bb81b214820702b8545ab039e416cd684dceccd6778ec66569f4fea6de6061cf8c320c0629ac23b7a3b727cf7e0fc89734fc1f35eaa4c63e215a49b4e50d62e6404235f4416cdbd128c8167401b9644aa6fedf9be19e946678e5d5999e37062c64e834ba0a32688502d9529a33e181b8f489cf38327cd9c834a08204875f0785024ded83f0198def6f892539f93084d078cbf48ead7ec598f42d619d6dbf5d0381c0e4ba8f3a05c75dbd0a1ad9b0a0151c2cab8b594a0fedac4e97268635905b040cb8431677212ce4587c2e42d16656834ad97886eb46db7f18ff4460aee767961e0f5efe625a9c8185bf5655f1f4ab031544dd727f26415eb895c11a0f8d210426a363bac633c5beec765a070455d436e1f21ee94549d06244e0e81a59344bf5732629fed54577a7dd0d9b935df06ce229e711ff48c70fe460544daa110eb5657f9c187dc30c385f35d9553480b5e815d79ca56a786e684b69afceae4fabc4f04652e4f64ad81f178061e490c09ceddac7030190f42538b1b94174ac29be6e04949df0eef20116a4140f911c1f3d3d2122048286d24cfefa82305\nSHAKE-256: cfc83be8cd4d81d74eefbded58e0641ac2827c9310d37863fc14549019f4d2165b4460849260558a5be85ee371c60e46704691b08333b5f748e1f170c85872333ad04bd9f6683852fb1ecc5d0f8fc8e8fdc3ddf3bedd3260df0b235cc0ae74781b4c14c6583067ddceaf6b8ca84b06cae0c9cbff52a5270cfa6a96522c43fcbf24fe71f1a29300218c017c47aea87d076274c2f8f6718e5cbf980d04ef39899114e65d705d38e606e665ceee590996b577be3df02da2927a31b2411f075b01fb7d1dfd139cd21c31d172101118b03d843259c033fe044105aa5a2ee7f9f2f56c85a1eeea7a89dea243cc371bad692aebafb1b858adcaaa2c75bc63e33914149afd2fcf24f5546c854a00fb4ca2029d818056d1dce1f4a3d3403057c49d4961e5e89623e1603447a7d9a95504a6c428adca322f50b044ccd052fa08d36e1d8f6a8a8d16280275c8e2b1bf2a1a12bd165cf820d12d6e177a17cc0951b31819fd0e0d05280a7e4903d44cc22f59a66c57e9896f93e429ff9111195f40c22acaf4b7c090ca94ac0d0ea6e80848eef9dc3089a00c086e7d7292f24ca3a8c89669aff9a627c85d8e5a22e139037f7ba5c562180a2bba5f8966760f0e647274c67340e84bf2c0a4a7dfd41c6d58b274d52141d33de2e7338ae60bcd8bc76c1fcc7d9cb3f4ee208bb369a8917f95b36d6c2a7d6f7d2a9dba19f57accdcd24f54325a49db\n\nInput: 2db39a02f3662414fa04be05f1c1b1539df2b65525cf2688c51a9ce9089e36ff11fdc01a141e096635e27449213df1c0db794321ff3fcb0399394b5859fdca055eca580e74d130b7cbb0de1aa48b43f3ea40fbbdfde79e3460eba3cefe7c2ece380f6fc967c4ebc7476a84e165ff4bc346ebdf66cbb436aa4ea90b55a4491a73861081fa8a4b3816b615b2fe5029c736d213f84628e55052baab0e2d0c423eae220815634ca7154f61dc1cac59c56b1ecd4555dd1429b34aad48dce477e1bf2441991851772dc695e2feacd66d2c182080dfe4cd0992be60605bca8b4a178b1460fb298cd4fd2404291d0ddcae8627736e0530c3a4cb24e700d90a88a2a75d55cf7917a578ff359077f3933cb00908c14502de54efb2a16c6980feec94435b4ba147ed08910153c2851a114c38757f273add752779568152242b031a968ff25d0e3bf823177eaf68d7524d18dba88cff446f48a0ca9a6c8775f754d328ff3d60eebcb98bce415fab1bf6f26c4b404fb80980f34701d9956f4b9fbfa8e125b43d95e1\nSHA3-256: 19e6a3959284aa4d0d99eeab4b5028a19d504af3ae6bb0fadd4c879bc23470e7\nSHA3-512: 6f3d322b73e366c9e2e116fbfe2df5c97eabe702dab4ff2e58ba8e98ab2be776a0df3cb8bdece3deddb4ee8860bf6a8f9f91d9b3e3009502381a52527b0fceca\nSHAKE-128: 8d4e06233d8edec173ab3da4861d240c4e051e76f52acf0e636f7837622ee7bd54c5a0ee72a266ec9d437f07dcfe4f8b3f062b3bcf242c6ba506f777116f92b80ce336cbe43b35e8533fc8fa112b4c788b50fa10b33f3afccc182484dd6beee11d39fa5614e55ecdd17d7e17a69ebdb071e7ce846efc36e752880a6788094fea6403dec3af98b49ddd7b9170edf8119b1e1807cdeee5630c7651db4da2b33e5432bdba0512b02a0b60008b29347de95315e6784dd07e7d7042b47b5709aff29d2f9ae5e9b37f9d4a42dbf276bc078bfc738ef4f33cf8d15655cbb45e8813f5e3f3b2de438a6bb2da2a52630b228f500bbafbf649686dd6a13efea325080440e4f2f059df7528a5c16bf4f1ccd45a2d53ebebec9cc33e060c385052bfb3db1e620503dd8f608629e03e338436bc742f9d8e3a570e1b4753201d7de14def010af5c8d091f27a3d332c3301f96b30df94f90dada1607829c372492768e69cfb9a92cdda1bf56f5d220aeba8e27a121342d4ed7c6ac98a7920cef07f088aab6b3348f9d34b6f330b063fece96ac04b4574c8208479e57bad1e69fb4977a177830587b0b140736bd7ed930e1b2331da9bddeba2edf2bbe111fe07d44b43ae76a684709ef41bee692d55e2c2afb10497dd8b071274dc5387b8a077e85bd7463d8dee6c8bf4d08026ed099ae1d7f92b8db28e6f6aa33a5492cfcd752c64c236086aed20\nSHAKE-256: c6c7d668d23b4b6fe38a2ddbcd7b5f896c9808857bbc1961f80d36ae69e01301727fd719488c980ea81eae6190ff47ad611e2ef7af8a88401909eae014be578b47b7b541bb19af9668baca24716eabec884f1076639a41321378d64162ba31fe0df463b01af01ba8ef7f43faf1a1ca16283ee232190fd8e5504aa7d4c59c4cf191e2401ff17ab605b8da096e5b2ae6f9682963eaedc5c32cb39bae0df1e84d15707f19a737cb80da87e1abff0348984f6218f487b69f0daf78f2f9b132592d256048e9b92bfd8dcdf89d7f5e39b5b4bf8dbc0168ffb39ad793a4ea6924fbdd5525c38a8c5d5ab54d2e5d9c909f634c205be79f01bf1ef25107b7e25861965e183757243b2dd80baab3d247e2fca959d6d12980330f02ee88818e3b37f02be7ec15803472f24a635de68244eadb8259c824c7e390b85ecbaa5e78aed43236b80f45bfaef5a148fb4bd2ac7005e4a4fbefe4662491f3de237e08fd03ef024e46d81dc3d333682e7af14163569446969d5f7f579af23297389d05842024ddc826204cbefab077d1a43aff458095843a8011c20f2f9b4973d7aea9960574f4fe1acec98cd70481fc2bd3bf4c2f79160fbe3b5edd606b63364fa0198e3c0d5d9a3afc78e2ae274343f035ca81c8251e0485285d07205e8d27cbcdb8596283612bc1ea22ccd7aa889dcf28fbfaceb98edb4aba6521583c8aed4edd62f794afe53b3072\n\nInput: 06dea577b3a09d8fcae0f83eb084e448c9037b97230c56a0d7c2bfa9c0f02aef3ad17e9440a74e6eeb79a7dc09b44c06ed6e9e84c3077dc6c20faebad1c67567bc198e78f192fa5015585111284c6dc31627f6a344995218415d6e5aab5016f22c96755076c9ea7897c7b801811cab662494dc58ad0fb2ce461665541af52f845055e22c9ee92aa657dbca5250e8c4aab6aa839f0f9740a042218393f4e424e79f06b8bf33fa45e65d753bb596bd088d0c9ebc1fba36b985670db21df1d05bd7efb1ec140ecbd5ecda88e1de275a75ba96146dc6175891cdf0ccb8ac88df6d666e19b901fee624321c7af73cbadf0673a9e4bb518ac2303fb5baef2ea37602c2b27073d14665c9138c951d68157d297ba491f42afabfbd488edb80484e8c920c75b4d9264475cf7a999379ea3823ad9e4c66d871ca9bba1efe8d7457102b18ffd6057a74509490bc189af17348140c88d2049c8ebf75215bbe2a6ae99d2d1e0efc913b1cb8b2b9ca670a2d268369ea57a95890e841e559184b4348fcdb673b10214c4a\nSHA3-256: 3ee10b6c9bde66fd26760edc830d24b23a12c9ee90fb845e2e66b61039531fa3\nSHA3-512: f123d185a90bd97b04563709be0b59becdad03eafd4e121f4b49df3ed25e03774e3c61666bc4133fef5779c0b52796041b41db1ab66d18ce7053f4399d6a6e89\nSHAKE-128: c41bf9fe4d41a7608f9affb7c7b08327f7007110a0d254885db22bc973bd50b9a5b4f4033bf8bc9abda0a202571a35033850ce01c6a283a260617a93739ba98d5f88327d0e8128ecd5996d5d47a8f866ecab19e1eb53d10e3cf8c531206d229964bfbcde6c4fdc38cc1086e6f70d1f2c0df0345e4e3eb7608eb398bfc4c68b99723e94109e605b43b2928c2bf0cbd222e1907e1f92bb09d84288d4c9a4a603ba3d14543bab5229cc5ab6bf4a6a75359d5973663b9bb868431de709f4fcdd4db1eff7aa4b1a575c0ada85aacc24e5064a3da89e82eb807643c6b66f3e6570f2e40a7d97e4c73f41fadf0c26794fba6d673adc936bd1c75b9a0be0f426a604f31a55c6ad2a65bd7f149ac8c971f5d6fd74f13f741f5d29fd36d318a021c8d34e4fbadae9256deafc3080d3b73c64eb1c32f73bd9a720ae4d3a6a64a9905e01936e44e8c0f882390d40fc9d3ef644c793ce5e642a8f0ff7eab75f214bea46062d0afdbcabb950d108c4b10f098196ad5621785805a44af9816e619acecc0c6498080988c9a6f830cad1a7877f6f7324af0fbdc6d479c5cd3f33418d8cd85d769cc85b3a9d0110ffca11ad532ec8d23d656e55eab03a5a9b57741943c63b3e7ee4c4728508c8bdff4966d420d0a58c3a3f73b92f0a3b009ae1fb8a8f9538d2a96aba99bf421d73e2d51f27819b22e0548257540af4fa4d31e5dac0dfa80ddf0adf43\nSHAKE-256: 78a94d55c5220197bbe4a86240d2d71d30ea3f89e47ad03a6a106a0e08d1be4006cdc1face4629a7c262c9b7497f0b78cf7abd8243d6e2b743f910b303350a3f446883b632873a1bd3357e533aef68cfa3b26b6839c922053f3b3c8330529fb5374017bfc8c4e28a2addd8a10ba87547df0031481fa808366bb85cd3446d50113fc0e7c5ccf349f08e525fe683a03b0379cfca6a366c5697479cbaa1602cac302570eb7580a7336011d2e9654b2e62d1a8324eb720ffbfc5c6bd3a139e95d574daa0aa2ec52892e651eb2b64e7f8e10b698a929c1458d78d44a92b45d45ebb7a81c160b88c9f656cca11564e7457abbc46e7d5087145e9e37d2df9278778c2c4699982ad709cef3a6b749d2ad750bac745a0ad455fdcc33fb89dce513cfba2df4c7664f068da8130a380ad0fd3c9295d4d54b3e46dd02de87ff87dd35f946b05dc105c15288dff0f113cd555c5ccfd3fadd3210aa728f265f15cc52af6220876901cc65eb0284e58b4e225c133e3a729d8af9876cb02bd71e526507bfe487f9812c1510c18d2446e66214e7a6e3", + "867e7e6f7f7ef49cf6e9a1fbb3413a04d2a20fcb3ed8185b74b9421543aa44985ceb5cc6c15b7b10f142f3697a806bb784a4fbc228a4059bd53b3bb3af32f557d19e4cf9ad197c692c13b394c85f2690cc98da0cb82851a00c31a477f76f7275dd707be101710af87946107c34815091654c1\n\nInput: 29b61423f55b91d6ae44c7bc4e30fcd28b2e7cafef586a2f18680a00f16c9a8aadcd6c068bc955e82646f7acf00a3e13e15b609553137391f31443b65974d9644afe0173d75f57d3d797b7b9e41832b652e5f4225eecdec3ed6142f900b8b840dba5a807462df1e06a46f347ef54d6b0f0ab7c162d04b1f120fedc4926b77f799fdd821683cde4bbcee95479df0985333d7408baddac4c98052e01e7b90dd33cc963b66501b8cb2772698ae4fdca4e0f28a73894210c1cdcb388130de2ab8088e41920fb1b966cc8b9ed5f3f880bb69a40ae9d47f0d871d790ec7828536964781830eb37981b4af8f7a78a9aebacc95ab96e75e93e817e1878759fde4fec88f4d8c1bf4f113c43bb73f9fee95f1ce0e5fe79511e7f7d29621607b11b91df1f4a27617b323891d3368281dabc8056c20bd0d822eae2d03c799cba783545aa9d9d505ea0ea3a2795ee617519b0b9d0f3f0c92b57fbb8b021fc07b68db1b2a3365442caf9ebf8fa85ff4f2719b936c83dce87a47604baaf5ef80c7865d3ae08ab6f60e32ba7\nSHA3-256: c45293b38ab6c1081ec876a7763ca2aca46394f9f64014884ee77fc206cebe80\nSHA3-512: 6def2f0f59595193d82c0cba8d6f3572656de5657ef333d26e476e86c89b218954fd9b4e4c5afcf306383e4c28a48fab71b7a9e6ea3d2f14056b048bfaa8b9a2\nSHAKE-128: a76a5901740448662e918d04e4123c07bc2e5b089e5a87de357cfaf0fd0040f0933ac8796a0f79281e83fb8368aa88747b4468debe75f4b3401e3b21df60f9279b04941afdef4f62d0106875b77da75e1449cdeb3dd88c2f204503c9a9009607cca17929a164eb6e164e131aaff091f628e92ecbe439a1c7cf3ad6536dbd71e79294cbbfcfc3410a420ebf05ada8e5c59cc0bb52a6d543418821c8fdcc89416ca5d18a0da5e2799928bca94cfe100111553a0dddfd4bd632b1ebe77ffbf63a9d4ae9c82fc4df4b47920307380ee8e057c4433eb7e71ae60334fb02c4e930bcd03d442074d5c18b8a92b2808043711605a4b874811e6af646b40eef437fb39fb8f0ccb0fdd2d2525b29d2083f58724a69acc20386ed1d0b6741c0c81b98dc6a4f73c7d69b666f3bffa2e8061bfc9de2190d6ab6036d2000f7000951c491cf7c5e6a52d7b2c6c435dd26a82fed355edfe99ee0938d784a7a6e80e2e725d106e950765a323b6d343c65c1fa666963f8fe12120ecf95f9cee360339120107cdb8228c47581669925b0ce8b7367c39fee035a811b7387f93067cb4350f1cff09be4c7b63e7003b950fa9aeef604d5ffd6e0acf5d1ee368d0b206876c34303064d7e7539f27779e3e62a4022200b8eb9dc45813d6e9dd012decf24446961608a5baf636d9c520dacf13158ed3f30da40b97810b0fb1fba1d59004c3654b2aab4e64338\nSHAKE-256: 3b1b004d076ac315a34b3c73fa9fc634a4786ef0f2a0f667957c88592214df3fe3f6a1cc1e0c5afa2e6f400845e2c06f5aaf1fa6739f3c104e96af1358874bbd787066ded75eb1c300acae90820828347f29e9e9da85f35f6b618e43c6787e5889c33c5d112d68d579b3d5f72bcb5fa14713fc9a968b2372bc8fa330b8da5cb300c32bf7d1576aadb0e2743ccf73e097f8771ddb8598d1906101062f78e2274a4c14b028b2849f014f9f8c7d625cb29f09fca2c8dd04fc7b5d2845be47986106b901b9543358c6d21148a360b5900f984508de24f18a206699c1eaf0dd31d59a04a09322e3321c9892df5c07a9e60e5aba66990ee5baeee317919e2b735b358ba7a6380482f0c25bd2d215733d1e4151c21964fbd5710ac456fc508f264ace4c02bdd06308ba9fbcc38d937e586e28dcd70146ca53f26c1af8e1d094a6d37c2f98cf62f0cbf130d69e984a339e0642422f4e7628c8dff4532a2ea7d66f92a9d32084239bd5bf5f9c9e08077b440a1fc6d68547e25f3c27ee015d1ea1b07888aaa1800f7e1853a83de0b882de3a554813acdb9f5d0176b8384da80828632f83a5e7a33b1765fa8c1ea015a11b68d0a9d68ff9ce953fe28c91d99a2b33e7cead83be3acb38cc7cc299c5b4243cd0a495ba276d0f1786ab710ff6d8b168f841d623c5eb83c44f9730cd2d6a7415aa4a865f46953070054d6ae9f87977d03cad4d1c\n\nInput: ae3948274283d3acd981ec5a74b76847c269e21bde741b6a0f1799a2039a78f030af8af0a24ca2dfc7e89ce5ea0131a39ba729c813cbeb4b8e45f39caca2169813d95e0d3d94dd0a4ce273828ffeff0e46c1dc27bd6d8135fc1016076c1fd38b4f59086da29c8e244905ec7fe216404f8416306fa613f156ca1d7a5576733f12a35fa83dbb4ba3c56b59bddf2066581d62f3bba622a3f20b6775de3cb23a8b1b8ab0976d020cbe2a4d24d0bdc9146f31f5272036a5055e07613d042c1017333847ad38c372fe562aeef9bbbd0e882d482b6744375f741d68bea2ac83b9d125caeadaa730e36d2d261ca87ef9c238c468e2ce2ab41e0a265bac6b7bcb65fb2123b562c1eeef50f9d172fde0d3de38b5fd996612985b83deed0264819eac16173bf588e545585f87e86256ac536a0ab68c6df54b9a985ceab91eb798bf8c413e3864e85ee2ed19dbd8bd3551e0ea7079cd0751d7c82077a711be3a3f778ab8d06b6fc8d90a2e543ab230df8ea663fbae161e667af9708e8a6158af2d625cbd5fbfdd0f82665e\nSHA3-256: edd26b4304aa09e02164092a1824e45e059d610898f269d4cb555743f98a86aa\nSHA3-512: f5883158090d2281f70c5d71b4c285769f7c480c9dc530bab91f2a3913713d8124f6717de07810f7bcee2e47c4faa9ca77a9ef7b828a88c0e507a58c9eda1703\nSHAKE-128: 706f1444cedf1593b7d726776d7f8ecb8818b8a51617a3bfb12357e9829ed1dfc658ce22e8f51bf9139d81cf1296029c1a424167a63c8fccb84b1388564a26667d7701bdbd64916e794ac3950eb798cb190bde9da15194cbadc767c1cb5a705037332c4ddec5b98d52c177e9b3e921614ac399fd37a9ff9f7aafb2bd7eb8b578caadfb1494e37868a8f4958362f873d0b6dc674ec1e4206bf6c4eb7e80478710b3aa5c0459094b42dd7db7a531ca4471f9f3bb213ffa44443271db1da878ccc2891d467fb67c560e3b8dea46742a5d9c9c1dde648fab63e63073fd1ed6e751b6046e96d99f9fb8978ee1330c3a85d3e041ff6451df51d81ec4a7415c6bda6dc541ea3ef1aa3c44890d77dbfc67f76d1704dc1941894ab19d4b88fd0c7b5ba8a16bad50499f48fa4e28b441e6ecbae79e0155774785ed9815ae7d11703ac6ff267ab30e1ac42a8ae140d5cfcb365089114113a05d258068b09fedd35ee5d0174c24b5cf40dc95736500811df0f62cd46fa505b304d3a93b24753ef0008e09d2bbc0c5be9f6385c4f0d939f89e3196e7d889c2421b1befdb571d903bf7d0e32063dedcc2ce88f24028880f7108bca816fba966df6b2b3ce3d02be2ccd45d53e19b63e5fbba02e1f426bd3cb775a391ef1bbcfa98eeee705e41927f7fee08650be63cbc3d65d03e9f92965e9bca43eee85af9b5667742254f3d4b0ffbeb4787ca3e\nSHAKE-256: ea93a4746a7361ee436d5a5b1550173f628ace591a984a937225a6f349861a5cf14d2e15b141fadb4b99f8a5d18c3b06caf103a6e273d70b31ce7770b4906a12367189054a21b1f0f2123f25d5a100c7fcb25135bee2924bf74d3302f982053f32ccf775563241569f9719e426ad9cb795b208dd4997966e3c50470ef031fea50c2640fb686db00b877f67b5890f75fbd11eafc7139aa6975092b08da934297c3ed22301ff408e12054b79606e8d579a8e30509d7d5bbda9b43ddeb85cc20d5a2dda7b31d0f34d853b984952992b90d87c11780d4cfd8565a033e54a44ca655771f4a6aac16c80302dde578688520f50e5fbc044cb36529a23bd71c74baf6f758237bc45c84cc65e38972fd523e1c05ac365a43968bbf3fc2c340bdcb52d2ef74070c7e6dbad586d5023c9edb34b3a22452292813cb1a328c8942128bd3ba41abbe8034bf80a3c50142f964d047559762171f9d0d99e2069d56d11708ba65dbfcd4bfb914c489017589ff137ad9e53a9b12530df89e5b7284da2ebf381f3d1f15784c9a53d92e9e394fb11638498c8643deaad4a197a377857243ddb5718a6860a75858c3d4adda906bf0cf935d54c3f2ed894e90bb3b17e1377c99c5edbf00a2b970767a729507a55c7a6291e13570859d3089d66537f4561890663124e2b23b020572746b4bd7b328c28ba5850fd18c96af7908a98e34a341f65a2ec036596\n\nInput: 68edaa7ebbcf5989c64e4f9a346cfce5eba91736de01a15186a44245570a166c13149cf6d8883434a0f0f0a2d8d82964913d1ec4ad13db7f9ba7fa59c0224d2297ee9015defae2a925506fdd7090b0cb94315b2f4044977348aca9e0fa56a0a0b204ca670cd8108de0e6031eddb2120b6dd8069332e4698ec29d4da1aa8c4d573aa2476fc8d544585d2fd5aa8634d1b0683bc4c9dcf5aad05c88d20f25af6910cb2475dde1d27e3cd81b3532a5e06853580f57404983e290415f0c7515294ad83623b5122d83470022485c297ee1614b2997173947ac14d19927893fc698ca9024c66aa839bcd193e1f812beb62fee038107c5940d1af3a6c40a2907b64b77fa18083911ae828513ede25d0a1bf783dfc678f0bdbf2b75792c931e3a6345809e2dac76c417bd195912e3c40b8020fc2721f3c961f40de14b0195cdac0243d2c858eba9b34b737ef98f9a7a73d7193234a969a919e41949c3aed2672a6a20d3d4f5cac333cf1668cef051b162a4f5862555cd4b42b66f0e83c35b52ce6bcb3b726928321acca8\nSHA3-256: 16229285931b32299f0554a9b27ea21607724bfe2c36c79abc421aacd5a4c285\nSHA3-512: a7a5a052c72cd4ee39667d51deefb383fca8742cb573cca6a9053756d7b391f88053effe1c1e9a5bd0ff19d2f8e0256e2f87e2373076a69e217d4c34c32e8d11\nSHAKE-128: df0f102c9e046b38022aa3823792162106ab28a86b31175b7060a81733ba14be5d5341c3ff42a387f2434cc73097988cb54378cf3ace6277145662b37e2662a421b5d6edc08fc5c8cf68a322e6440f65551289e669aabddc84ed8bf18a28830ffee571a1585124dd0f392c159a385ab784c273f0d0dd1b7b7b718116ab461fc191232f1205c9723063a46343f4e50c5ce128cf19f5907a67b8a1ecde245a9c5027a9198c393193577ff566978fee0434236b7de46ad7ef5b975119e99562036601c9178a07d5fe63b40385cb638e3d594dcdd171ee28f1267ad0e1ef5d3414e672a6a24df4f9e8e07af17fbf57abc5735d61c2f5467e8ca34abc6f73669707a6c33f76230c8f285d7319403369908e85f138b4e768b7836a0cc1b3a5ff4b71f65c47a7e77b0ecdcc1ff05dba5a0c52e4f8af4a3e9832df5ab2937275e06e47d2522be1fe2613ef55db04154016cad7d3ff87d781cbe46a077d5dc25ecdfd194dd156f57ea2f33a398a3f08970b802e5647a89f66d139b864646e6e14cfadd8876cdccd9ecdefe32b0ff944fc457c7e2044f5", + "12f72c533706811c758bc8203483fd5f36eed3834458ddb69cebcdf78bb6302c1b2f02306906931d68203ea123ce3b63a8b4e429fa36fcbf64cb26a50ae5fc87b3de63cb7e830aa1de9caa0ce3c46bb3eed7f7db4e1b1bd0e5575174d195cad6b005f7ceea9af0754b09f556a677\nSHAKE-256: be29d1621d863d606dfaf2b4dfd027ae1dc0b0d737c97fc3b80bfcad5a2d374a46da96e7d50c2a2f0045ab05756b2438276ee15fac7c403e349578732eaa99d354f5cb426120387f60da60a3f0695d620b8e07458d1f6f21ef05022ed0f8af81ea3722ec7724113972d4a256437ffbca9842c582be98957aaf8acfee2e3e67a4fa2f02c4e1c5f92fe50dda5976ece38830976510bf8c395be03f5ff4f7cd9295af202e8cc263820548f9233615d348a4d2a14d079dfba3c51fad5006805bb287437c10787f7ea8d6969b0a75410b8dd5c055e4eef7d029e757d5a372dbb432836b4667724864354b2c2ed29eb8615f35a617b5e589835049de622952304ee72b2daf4c3d6527c9f73835905590758d9c7a78f0721f0a5a3643887bae5f8d94a22bd0d42befb2b1d49db1eb03b3bcaf1cc63f96cab0549142a9c3fa79ea6ed736a1ce1b956bf2331389d22738fcc1be763acc520138f6b788241c0bf3a83f0c006139e2d09d155996cca21db5a6587935bc59b62f88cb18d494da0ea0122d5fb77b6ababec457b2bf3c7909bf0cf5136505b6d02dd3bbce7de8db94918ba89426ac266158728af6838ab82b1ba1addade600476074775fb544a0692ab397aba7af2263679d8d5c870f92c2790b0b1223309d49d2e58019601e22b8a03c0f27cb2987139698ac61b7c5ab86ae2377689ca8a019d8902477a7a9f6ac0d6634107f4\n\nInput: 7a147b6569e0de1e98b7d27f86e794a0315bc9dcfacf0489917f3853b4e31963e0c585737af058f76112d96f10dd73c26cd124c383e161e45f31a3bd0921feb4e9d91c61d3c7fcde1f799b6a4b7d1382eae55fa7ca797f2a2ca666c9fa07f4507f81777c8b095014c77e782eb6dfb6b7040d378a7c83454e73a27dabf87e476fb767db3a04973eeaf3fcab6e4af85c1f37208147410624b488fb5e64c1ab1bcd39638e3234922b9d9d6d26b515db2ff12761cfff3913edd72fb9e50704582bac13cfe67e62d7fda45bafc5059950b221837c19d661aba5dc58250f800457581cb7601bf256f02815583dc8d2f6a797725697ee66c0ca2515c2ff6e42bfeb1dbc5dd750c9f2b1284ca2d65d7618f9b13ca150ca0631c34b64cde5702981316e427945207b1a0eb3d688fc4b541a2a168fb9bf3669e76b7ce1e767373ca31b97197ab6bb27aa94913ac0598eb1effef781151e4ec49786ca78545b6c8421930bb6ae1dd7160dad5144c5083b347042c1761c25e788933e8cd04b46b2119bf4ed549e0741c1df18de\nSHA3-256: 0945695bee2d7c9fd9287b526174e27a0575d01db79e7c9a30feb5ab2884e18f\nSHA3-512: 4d4d793e946c2f70b0418ffe97a5325d94eb4a70e619d833339fd9ce10d8fab09cc8a3b537168478ec4fac7b15e122735567f7ffddcd8bbabfb2f60f8106cb3e\nSHAKE-128: b1935ad6de79d96fabec45770dfab1f1e000cdf05e8280c6138df24997eec2b8778a41addbe3503f4fe4221217716287c6d1bda4c5e7b042f9d951bf498ea19f7eb96828d59eb0e1920874d0e92b01baab48e9c901ba32a1cc1d2dbe391d86e0955d981fbc6329092716a94c5ddc1b411591245209fb9a9c043c590b204cc662675788adc8145f0517718554af37312e84751ef5613f16c00f8f91dc085bd1df939763bbf8e03d7e771b7bedc1fc428c9eed059b28684588425f4a4a84bc56dd585c0fd184a8b32bfb756b5d1af9ce55013ac5c266f941c74f3ee0e4a34d2ae024f3ac9ddc9d127c89ada33c7db0a5af4c5fe72824cb0966eed3562c16d83247e2004566d114dd436d4c703557d2c7976211ac31f1cde308d622160b22ec3918d48d2d699f94e5008906be3e6cf1104143756805889dabb2398fe2c7ffce2cd4bf00bdeb163603db6896313274afb37508ff9b051bc2ca2a514f0d92f31c6ae1cc37395081325f9d1b8e49f123ef4cdac8cb9aa1e6c728ebedae716c8e7081b350ba7927e2ff0f67ae5239abcf29a3b7dd87df2cf261590bd9e1c771f855e84354387035b8ac11d7a22365f64b9ed54fff51f3e5958a140eef8ceb11775f8a0ee7716af0fa01eac64b40b89772b995d3a29037170928550cf585e2df8c38066b30b419c05520bccd8e19e979947fd2ac17d096377ca831eb03bdd47ca2fbeef4\nSHAKE-256: 8c56e33df32f944f0f6d1f2a7bfc5348f9c76b03aab9f2b8c3a932aa40c6a0cc6870d06f37a49f24da6bb9be56261c6150679507f9bb6bea6025dff9b2abb6e36f513c192d289c1249bced411e31b4694328f0da2fd9dd0801ebd6f8f8c280ec1dd04b6702088fb0372f8cde7e5b7e18aebb5f99e4b7848cfa2132098a39a7ea3734c6bb4967544fcb7a37195db546ed3f1fda095e05d1bf972763e040aa2b27a3a1ee6f32cb4f21860f1f2b0cc6face83dd949554ddbbc60a3be7db0beff2b24c62a7bdee44198c8290c6e7fb44f0519127618fd573ec481537e959518cbe592e6dff4548def7c0333404eedbd61ab6716d69201618f53ef342606dce96494b1ee53eb6128605499afd84de233a6ceb6c1beef543227afceb451e5969c7458cda48f9ab7b23691b1e0f8bd3a9189f587198d03d68af187553d6c3b653c6d3c70b3268aacee367897d82bd5aa10fc9b09744a473869b145e39a68ccc2ce5d586fc4bdb87a117aa6089b7ee4b6627bb5da27e1f4e14fb751ed86c313b4954e740454927e530cceff0e15a6fe4ff5e59578b0db0081e6b928ee06f5b26b6d41c2165fdacaf7965cf54ab0d7354508fdd0a71c446b5a3d5aa732cf19d6446a5200aba4151e8f863770fd677cc96511c0c5e3be434f5b05556777498529e2424d43cfb02e752276880d8b55d69c1479a6e5ad9557d822b856dce37f326a944e19f1a\n\nInput: 8b62ed2276bb3c7f6f6aa4345bfdb2b1ef66bc89faa8c1bb5175516269a751af57626dfc9f9087aa6348058b0fa302933a0a6971e2ec09b18c8ad573b402a296d4b7fda0a4a8da0d02bd411179ceb1259656da22babc9bac18ce42409cc6e4390c0e249b67b886602338cb4191e5e51f331196f07e4c425fa0cda51da56f13bad1d1fcefcf4bff8a3d1a3d84035a82f629d73b8a9a5a8e4d684d53423923753f336ed7c67b88c44e78d124b8846caa4a0b10e99df571c5668c74136ee6c9741fac0c2a47dd8f56fac58e2c77ad78f18dddeb5258d575110210411c6887b41c94b1e446c55adf40ff11570f5740226386e4fad63ade9f510640b662bfef09481b6f4e8eb19efbd12ac2143f1a5f58ac7fc44255b101da94cb5676d75ca1fc04c7aadbe83ead268887369a5be872b063c1d76d5a09b7aeb8eb4f301e3882c88f638396b7cda0e2890cb7c439e4ad59e476c73cddbbba5a12fc26e0e7cb51e7aebba96a0c563387238b13be75deb5d135af0ffdb45e4c58f0704e792906641586d2ca235febe82fa363\nSHA3-256: ccc1dcedb1d8aee5bd47e37e181b96f3f9d3dfc9649178ea5cbe7ba4065ca160\nSHA3-512: 532f1a7f2bc4fa2b0e8797676c0b2851abaf2416cdb7ae063097b209db308ad3501f15e79fb2d5744e8c1601ec06f0b408f0f29dda11473330d2d30dbd616d6a\nSHAKE-128: fa7434808fd360a1a46f22527c2393c9d922b63d956a1f5b0b3825a603dd08d2b1ea063d768fd0a5088ffa2e841190eb4c264859f90b64a0725ce70c609155b0abfe22699e3f8e2e79955f180dfc93818d535343d50f2f7967634dc6b8db5add13abb4ee2115e8bdbf1a77ec812afb12f79d3c639b29768706f5281814465541498387284f867ece49185f7f7bf0279d0f5de3e359760cdfdcda6ed19cf572535d225093a8519896da5ad56ea73c43a4d52a87e16864c7cfac130bf4cea147e030ec3d05e34aceea3c8371f66de73dccbc99c1b5dff9c70f43c65b24030559b052001cbae3515ff4128dee6e9b7979de0167fb24c12a785eb3b6b425f8a93cd9ab83a3a0eb8758fa6d4056740ca222f5c3ca4377dc25d1d531e662b293ad46992121af84c5823542990a05aec0a9ff7c3689284d40ab5365b96fe73109067e9067262dd6606777155db16528cd31b5f460420c92550e6bb22068e552adc6f14088aa84b15c6ef8cdf27ac542ba2d0e430f88a70317c6dc82bce2628b12629f07f32c9ec86b2613db7a5a4e5406cde885d5fa229981b1b193562fad324a9eaace9ab9e9cb9d273bfd9f96ee8681f72f7dde28fbac236921ff1d388540a19932a5418756b360eea52beb68afa6fcfba73f5ea9b5873b7a90ad67ef9818a06b8d841dd9da654236c77bc7090fccf2a4672e8cc968816e9ae9b767fae24f74b55eb2\nSHAKE-256: 8d5917d846f8ee3b1f2ca19a963890bb04d25d6cafec48a0b1f1a739c725c838b1bbb94d8a4c51195f7894e82d0ccef822c98c5160818e2ef6614a2a75ec05e326d5eb1adf7b7fae6e838864dba71a78da10b9d72aafeb3634d41cf7aaac5e196e20eda168b528cc19a5cceb47c0566b2e002e7ba5f2922b88943c8947c2cfa3b0ee18025d492cfa971454d15ffce6aeffc3c301bda9c0a1e6d5b397feb0f39cc524bdbfccfe7894d4dc7bb8a50d63222e2c8589813123247cf6e0cc9c1b24fb15c51e89d4f321f268ccdf59d1240ecd99527afc2f404f902c8296dae07e4cb89caf21afecafb8e6b0f545822b8fabf386a1505712834b760ddda16aa8dce7a262a717760404944cf3f03fb50eca8ba58f265ede70eba9a0c9c69372c071af54ecbb9456d8d23cefa2c9fd9800c492d1424f3559488c8e3963049e07dc6f9092588cdc6864a592f638ce3354a4ac5a04e1fe8e0e20e1054ed0901d04193f9c688d0c8c08eabf521eb9490050383f72bb3af75159d8623f2438a3717b53af826fce325baf312de817b403c7b5db5290706cc4ff4228bd59011989096e6d08654d1db51ca3b1357e6d949f20df94cd1b8481af6be42702d92a96d8bbb72994105a0ac10cb90475a0b80d829a5b851a7f405340cdda82842fe438b9d449680496c50b6748e1db1409c119d9b92e628563c8c3479b2edaebbfc6a462d2c5a0962a9d\n\nInput: 3df71463db0f76c708f21cc1a9c05420a0480c1150d4e0e7621b2c1adea238bad6e57dbd51ada652612e18195ac88012e21644104588c83ff3a99a1104870af1d6e9cf81626841eaab3a738fe420384dfb77f416f1cba702bdaf4dd9afcc492c71e9b0fdab4bf228b4d79ebeaad54b5b7b77eb52331930bea8258ac89033e1074f8f29e4b4a4cfaf5c7ecd46a81d93b79df5a9861ad7f19cdc985417bca0ee99a972d2e486df93e8c90229ac0c2fe37ff4125405e8b7ae3082ec18dfbfabb490f96c2bba32bf9fa7c59d9549686a9479f5ccc63c580fcc01e323ef84c809255edc625613f07b178449610587b655b38abb072eb5d12ef3b985ced2a9228cc1346c0b0558ab21306cc20f2f7958e4f12d9c75be15ce7c5fb0bf967b841f1059cd89d3e16b521c6ad84dc1eef512aa7e888ebdeae092bae3d56d11c3bdfcd8491e3b37dc76cd5d92f0bb126e7e39c0d1092f870d2c54ca02a94536e5c27e0f3d4561e929d4c202ec79120953e67788f973f1f43359ef257113e84067b266767c207db", + "ed5b3e9e1f079ac\nSHA3-256: 8132cbef7fd40a14293be6518899994f5bab57284dafbc15b635c49b1b2a26b0\nSHA3-512: 81d5f661663a713609e8c549ef8a1cb304d38a34b61267777887fdef1da5dd9c2773890c58a7c0a10c248413b7438774fd2f0773f23d690c45797bd8168447ff\nSHAKE-128: 6e0f49cbc22af8874eb98b2aa49595033e53aa3eca638509450e682ed6410d5977c5ff1ead2adb2fa4eb6db02822f4d48346c24f272d41da3238b2312bd2b9d5c09426be39bd1b42ebb19f3c2fba6f8b912070b92d2e1b128c53b592c9e460d80ae5e6193124f4cf2f1be0ea33e36abb59f93a99dea952f653f3019afd6bd9161367d0bd9db79039abd5751af07a47379b07d3741f9a2178cb0640e0a13a43fd5fac407fb57a105685bd771e9f0d55ac86cdc4402a4c2eae1515bc05f05e9bf3ee13014ff1c4e465ea06ada61f1a73dc34842f1272018ec70f47cf39026e1e158f419b3989fb98a54e3070fe65c16846dda18ba77932647151382719f6b2db07f841cba2ff2374c271d6258e067f88cf1e9c86a8f3a63249bbcc9065a2dede4758e48c9ed13a0a64a78697af9a574adb5438aa9408d5a70e9223296f24acd6852cb5b20020963ee7af954f66bf9734c0490e269b3d116553bb3238a7b16a76e2860470f7092bdcfc28244fe6a043ea41590cd202bc3c717b9458e75b1a1cffb81b78d2d008347c14ee60871771678f2164b136992408fff07322fb9943191f1c92a05487720a1c5cf343a2c88ce3ae6cdde0911109c62f7f54e55957ff273dfd731c93a3218fb4cad35ccb5a9a7bf6a7307e76cf1c8390f93610ff545f87986c9abbc4414fc6d186b3218cadbdc3867159a9b97ede724fd8b965c2f9463d1c7e\nSHAKE-256: c540a118c334ab0f74a1713ad4492d34a685f745af92e8da0edf65853ae53fb0820ea6d0d224772b23a141798f3bb6e61dc4ec944979aa4df6b5cf91b68891767787405ec9a088342feccb479dc9ab88faa5417bb189d08cb1fee811a9ddd8f46d7302cc845261f9765bf0ba444c566bc9c0120097b5e759c1940e0fb857ea5e03ba27cd7d738ba1ff3af7004a12bfaa967e5808573bcf60f71db7f84455c799a89ed23f3951c47d9b874a9da8bd085a18392036fe6ded6c75f81b819e8a015006af2b53a5b5e9e57900e542816f15633af74b17dcfc3d49edbb5a8ad7314fcf1070b76048a100208688a70438d48e71a3cf5af54d43608c891a91c43ead9c2a2e9107207c4c032206041194702b688cf2413ec14094599b7b87cf0a9056453ccbe7f5d44b9c790b6c8c303b5e95d69def684c4a0209b6e4e420b4e289f8dfac69e5d6ed07aba81c53408021b5da75c5d5d9d14a90bd3f4cd5080464ecac030f973ca026d7b0bc4d082ccc070794b27a542dcc7a3f804f6388e505543945bd19a402cab12f8542a3c0f4b6aa5e0716faae18c286b51d43b6b94594e23e15101bab6456da5304719b08628a6b65229b1daeecc9cc3fa1d6e4390731a0d7c69f00263581707f124a21a88da8cabb5fca4f81605de1c231fd95a2bafdf1e88bfb7178334eff60f919ecb60865689db475c609f1b28cda0e268b8119cc4426dbdcd1\n\nInput: f5a1887af9b02fabd048594d5c5649cc3c077e34a4eff9677146fbb84e8d14609f5315d440c1ce246f8f8a0a33f58db6e0fe2a31d66a1d2e2b82279d8d38b0e0b2381af396f1642d9140a31702ddc36d6a5a3b36ce510dec9d85fac0a707ff022f8126c18d56bc5fed4e61b1acb10d7cd642db58f7a2c1b1aa0266b47725942c97ff08204129fda483e63e8dea31660afd31327b340eafc56a88e47ae34ea759c0dfbb506d13929f0693f7a73513bb16e1e48b77e4132dd62aca4b3a408f77476aa34189de868ae6bb3872634317a0286c798d0d32f450db7017c431683480259151c86594032d0e2a181e4ec45e0c717efbb48b8e486c85c76ea90dd3024c45742c8672efabe56a3eb6521b4207f55f71d6a7945185a559f16e748e46a09644bdd1f70a7329170341e670d2554852243032745d73195a38cf57808bfd2ef669f0923446df7f2a7fb22a56344c2f89844ba2e5fa9353b571bfc2cf1728d1fa25e9ff49c49749d40a86227b066c616b6040a3660a8b51a48817462c7e21b2b873e6e4c32ecfa54c502753\nSHA3-256: cfe20a5670ad6f19fd605aa16fd9c191e5fb1241f83d9839400dad1a823da402\nSHA3-512: 7441d090bb6ab910a7e69630cb736b3d7154f3814545754acf3a3a7304169c0c23224c98055cd1294704d3b979cc1aae8ec5fbf2b3344dfee0caff0e54951abc\nSHAKE-128: 81a346f66504e143f7ae9ff8a9774ec95d9dc74cd183272f4e129a9da361508d261449586c0c61af7badf9bfb0099128e04b879d6fc585db274cf4158f7cb73176dacfa17b267676cd9b4c658c6c5175f5611b29b9920b136688abcbd4bc5f846e82bfb46d882465fcfa6b56b21597b49d4596d987a856dfd9317a39cf13a355e7cb2e221bda0f2220f10e5e8d5c16291f85fbac2f67a4ad383a9b00f340cd58a254df35e395559558d096bb52e54ab9edbf97ad682083101c6a78245883426d92bc21b25e1354b18cdbac3119f76757cc78542aa7658e61f4b846c4711018234e9ce093037fe09ae7b094f084e072bae634bc6e8bd7b720f12d1935005d9b14b513cb9559ae84b521bb7705084965e29ef1771f9c243f3aa821864651a8f777d7fcde6d068adaca7132d00d9f769e1e5353fd2418774375b7c5a95da7bd3723b417e41956e3e42c3d19facfb4a5affbbc9db692d010cec5c97776756803fb02a6ad4729a7f701316fa459ce5064278a40154e2b7fd10f0868426b4dbcda2efed9c4cd621ca0a87b226692cc7170e1bf482907165cd35503935cfb6362c41e30e30b32076a7c1a17fb6a84cdfe0a4429f776b76414e89c477c5cff16004821d4b5326bea81fa182733b2db6cb9831437646e9dc1995044f5a5e503b8b5c947e88983c5bb3fc093d7efa428c8637460694605833d5788c5a4f4d5972757556016\nSHAKE-256: 87848c358ef2fd8372c76ff942aa2c1ede06eda00cd442715c5aef0e86b6ca35949e7cc3a763440d771c24847dcbb1bd97007f048756008d81b462762e5f222c45b3b657b50ce6c5b703dfad5b5eef13edd31f486927c93bf4d0b360c81aeb9d8826831c2ee2155797198d375a78057e71d6bc333fc81808cf26bad65e6aad9f97e12fac281199d0a5886f85089b07e71a42909172a56cd29834c465fdd11d224756688e85fb6dbb4af5561e7824b69e066ad8475b632ce17f48dbea3f3c65808dfd16036e2e525b5fbe5a506e36f6f40bb7c7922b38d462fa6463199d6742ad9ab83e45b672354f93aa975ca7859ae93e391d231dbbdacca6a9cda16e59c2110cb02c21264252f47ed1ea62a543694db156fc97433c1cd688eb644aa63e05fc56a2b2ed158cecf349a37c6ad1c122bd2a63edfe63d83323475cb754a4010a01d7d43177c80060fb01b87ffd05c8f804b1f9f059f7dbe667c5d7147500dd003da0d9db71541a8cf210f610048098b6b686fac3cb6dc8e120d63ed2e1e8c249efe1f1035c240c74bf34ac4e96b47fc3cd75ae73872045beab116441e0e468db5a9f519adf93e68a7677bb22da09c571deae23bd80c681b54aba86c7ef917e3226773267afdc69892ce358a8bdaf31826de17cc648e62e9a7b0e2b81263c867b1227c68529d3acb7bd41de2a072ab740aaac9fb538be7a0a2f2f59061ea69fe706\n\nInput: 3a4af0a5292741a7c97d2ea3715107ac96445154b9d3e863fc6f90ee70d717dbc42e9892c361ce0f913385bb4e4ef33a632ad07acad91a289f0d49de7e27625e95a72d28d53fbfb94d3a2e24f21575d0361e160e92b2ce9aea4aeae7a343e7597022e198fb9e58f8e2688df21fc655e7224abf06c20462776d3f0a5ed1aee49b5231d267856a623ed9c1fecbe4e136a9ee7fa6b23a2f8b7e8cd8beefcc9c04001cfc89dba50ed610e43363223d3bfb3cb67ac04c3516e63e13b6e68bacdd482aa02336b7062795abb043951ba0a608ca94d5521da3fc90b4804d3d9094882e3f4d15278ecc7e0945045e3d7f51193528791c9302f16e105914dc94b0e5d927f4f2df0254df91a93b1319dfa04311296e9afe19f233209c444574f310d6de16d7d8c0c289b8461fd599ceb0647b7dae6858db52ace9c6c4c80735b417fba412b32b6ac02a684eb09242cb423cde29faa45249ea0e2e5c92d195ea5f7ba9292e46b0a20acfd4f880eb72f9f9edae95abcf03114e1a53ddc10974428291688b8261727e6f58212e9893ea3b52\nSHA3-256: 1376e9249aed022502d6536cb99091ab4038a82b5efe05deab15146ae395fe94\nSHA3-512: e0df690af3d6a3dcf9d18f78f04b17179cc9ee8ccca98f37e827d74dbc52292e429290bb9060e6d942c910f2db3fd09562dcd14cc896d9e7cf5276432525d364\nSHAKE-128: 957b5de6f3a27a14fa51b20ab9059c7fcec15bad0c364aea964417c25f88a7e2f7813a0e35f0c7e6b23be94f2802ca25299e48c1369cba05e92ff6a30b427e76de21abf575baced63c2cc19c3b4b6aec41aaf47fb65b923fc3251481bd4a025a0c70fe70ac0865f1b705a449c7b646e807d29f88a5a9aaccd3b350d016c4408f6ba2a89c5685db8dc98a595de1d02fc4d4a03e10e8d7b4d11a5ca0c3c811d895b986fdbf5ba1acaaede703c66f3b77c8979431252009cea2210541f4073bdd9f9c0a4bbcbbf1d9a2145fded61d50121c8fa78841aa8a946c94cf6815d10cf9935e250f3ca3cf05986bedb32060adab9d9b88a43d0d1f2acbe3a7094768a34c485c281195237492b6bfa52500fd83da8dfadd3c53fb4e1c4437cd302ced0c44ee83a1f026d0b064ec62f745362fe3dae0bcd1ef23e48037fc2d499310a45c860242dc1f5e483b3d618c8cbf141b81986a82c9109852a579863d3d46f402300e655641b5eb40be3257834dde08929ecf662217dc58da062d9d29bae5b88e74ed7bcc846583a53e87b99071406c359b973052634ace5457445f227c5b602cef699a71771fc02545aa638238a2e81dc6c30043f4a5929a636caa197369959e44215e6ab298a524d11607652ab6a9712e1ae7236df7487e5e4b30447e8c75299658e5563bf8538a78db187cccbe975baf8dffa636340947325ed5ac9900ee4a87db04\nSHAKE-256: bf6bbd0eedce120a22173f54aa61fdf3bc75683d125ac416baae9ae722f772a361dacf5b599ef047888f1c3d6c4d47bcad970bec1ab80eb18cd15cbda54b2ce65178dc9fe4358730971fdc908429344ef219dde2ad69e599a3726f7e0a308c584eba43ed7f4d683e1dee30fcd189de586fbb450f2f5e2299919ffb6a59f3ac0ee20414a6a2dc5e919ce5e754415bfd9c6f719cbf4ad1ccd5e5c861c6d8c5e37e1fd80edb66657cec0237a6cb45724b7e9db2afd8532c6e022846c74861c01d9fb5674814f70fdf97baadbe05d56fa3425e2f896f5a2e5c73238d6fb11934f88ed382a4bdc835f827af74c32d0bf1f0fc4861be3e02671253977a3e30fcb76caa1d99a76a3e3b25691ecbf8ddc3c1edb8c844d47ecca35cf231eb08fd6b641fd053f434dc1e52bd07552eb92c78130d4af356b2e792896c6e93e0aee758ea012437296ff3bafa607e2ffc69c4c3afc67c18240d58f0c27699acdafbbfaf6f81c0b60acaddc0d2dc0be7a144f4fa8194c6f33995d3c15", + "fe3b63bcc3186dc80ef74f5b405c36a50a15ac37cb7d5766e77590c91153caf53e4e7f2fecc53f5fe1aa990a8bcbeac9c03afc13b41a293359089d9c1402e29033c8e409fbb2f56f5df77c2892b095ee9b4ecf1ecf9973c93e8f3c9df67dfc513da9b6b06bc34ffc5e7c4c19b396397d31dbe0ec494eb1a70a0a1c6e5ee472f92203e1bad6d23681e49dc\n\nInput: e1c921c68d41c7933a21823335f625b4e86c3ec6ed83ea9c74acbd0b9fe5ae40ae187e5024cb785bf9ab1be9ae16fb35c5626dd103c05012c4d8103a5fdc3bfc16d1d04679620c630fea30ed2a3133ba21a21472cb49cf8881bee184e5acf63470575169829479004f0782c414d5d492c259cdb7d7931db3e48eeba0ddf5ddee9bfca0e516672a7f738d3dd983c7123a5118cf4108628343234d6a46e72c1f692057b9998ce1bb85d0e409f2f2ecc4db9bc2a83bda86ba89f9f17014e27e6b5cd123c2c61878df96494da43690c813c6271c3ce22e8339a5d4af5a8016878c8c44423c26e6c69b03ba065cdd498ec8555501c71af6670805aa40e4a91eb458d2f91266b2a8cb42d64f293e4085b340ca0ca3ce9df77b41366ff9e66c1752e9caad9f9a2e327abac28fc822cc61fd656baea3bee892ce70eb9bd975c090c22d6d73294f4a1bb9caf63c197acbeaa1b9420b05966356caf9f8920bbd1ed4d4c584876caa8af7e5e803788e28bb6a7303db743071245c3a79f22f88e6d415e39009b5e88ff71aed406eb51417a6\nSHA3-256: 58945aec00f1bc845a8a8f2cc1917b811ae46a692170480e04c289f508c5a7ae\nSHA3-512: 9499a0fedef7d0016467a1a68efc9aa27e6a5b8a917391dd29f6aa2c94f792186d60488b712308a116a19f945aa0ee626e3009aed2b5aaaffda25fbf38736fad\nSHAKE-128: b596dd197274982a211fbbba8cc31ec3f58e7a34699bc9e0013098b500845c074ac7cc993e618ac158797afe81978c28a5002a9cff10f5115d2d414cb4e2eef593264f127e62cbd03f7b1c83f6f57ffa0f744ba2742385844458367579c48786f6fb08d5f0f9e6625bb0c5653ab429d49503d5ce18b67242654b18ef3988d14abaf889d8f9b39a6c04cd48ed71878eb91a8f1ecff0d732d316e4c7e76c0fcd3b73ac1fc4b0888ad296fae87d0c8ffd27a59f482da043c0ec84632c249b26e3b9edfd18eb7aba8c2d72602cf569ab924a9fa3fcd0d9be8e8e30c06d9e455f278960099305069ddbe28e187e27a28e468441274555754ea714d6aa67f6f9c53756b71a3c8da0b4b34a68783825cf7cf1b5c9e703bd4c92d4927ba3fc12e3baefa812af098fa65cce43fa1174e06e6fab579c9d872e5f75c14e547417a67a0ba26e735d96d536668a3903c6e326403929c558a9c89d994d7d6c722a77194d2c4c6e1a8f5c03bf59896486e6be433b408501c37f8cc32a46b043a745691670d95d99cdbd122863fed07d94abbc3dfb3e71838089b5af5442e466c1873d0e40555928eab4c0bad383974251c920460a69d568750b7dd3fe5a5a955832efc4900af6ffdbe2a7cd5061753b89014c1443f6169af0a9bb50283fec33dc1c85b53c612c00ccea6ffd4d2c0301baa8c645c6957963665539d51a4496d92592e038932f7d30\nSHAKE-256: d14ce4ea407aaa340432dcd6644392dfdf1be881950fcc12463c63434e5526016250793933da08dd0d23f17b49419072ecb216947ca11a01c02c8c7848ccc047d29ccdb50c9d9bc6e4ae86aaf95089363833e6718fdb83c99cdd38fa4c5ba25ae1ccf6f3b26a02c4c0a968cd54a92a6fd9c50d439138a3d189038a0d9e64079517bcdaa104f157f9e16c137a5ae0e09cb6547ba0a09202ac2416df1ee662b13319055c1c2db2d9103096b7f6293a46f98f3a79f587bb50ea575aa3637f57ee99c5e613895b249f198c0c5a40898c16adf44542df020f4e8df430198ad05f31aadb8a3d30bf0564cf57c29f56f4cf6074aceb9198639ff1e273d28329cc18eacc481e8126a6a6214f88715667fedbad0f1d9eef2980e49136dfb0d0ff2c3101a6d24e6d2cc38cba98d8564d189d526ee627e78fb8e1de90383bb4909785fc5942b3cfc763b237982769a63bffa130b05e8bf40fe63f1a2bfa12cfd4736d8c836b7dd11f00f43691b5b6b20ced161b2797dbe2dac4afe793999bca208c2725148b302ff6737bb3fa5d877d4f43a88ec59ec266cf16a8e25e202434381d477f1261e4df88c8be6d061b0a8253339cc6d0bccc515cba38ec99416522ac01e41933bf6b67fbd2855faee4bba9cdde0a758f67aebff44620a2bcd6d8e62ca7289890b938e77831c3252441a9238f52ad263f4b57a85b17f34b0394ad1221c1d7617bcd\n\nInput: 2d7e340c5992de30a18da9d500d4c7791cb7917265846db7a1a368d86a3dab6d6d9018c64403961e0d59289d8403f498d5978bf2e11ab8084d79f9d243d7dd7521c065515bcd41a4e897411347f18780406d554fb1abb57bacb586ba3ef8aced462a59fb74e2503f8aab7182bcae6714e7d3c6e1e28890b418ff63870223c915cf8c375c2107dff152a3616300463f40cb74ce101c8a0839bb88fb000f1ddeb76d80121dd79e8cd8e0decbc8d0444e2e649b56aea12e569269dfd431ef2a6a16332994feaab30956948776325f58d1e74eaaa408974d248278c02c5fcb94e17451841fd69aecd8f06a4262d4c6b03ed96746adfda38b476c9e7750a1536964601fa6625c68f70d384c28d4aab6d63436637c69440dab709602fa082bc1cdaa59b8a73eff70261c6e361648ddf8a5f6288449a1065c2bfe4760c921a677643224a08afea4ee8e971e2fc4ac1295839ef51ea37b0e8add666a7ce51a9205035289bf7382953704368c36ee9ce77e3dde31b7c06f4b5fe1b746608beabe0015dcbce640afcaed5ad017bf6941cfaa\nSHA3-256: 74f8761d31c8139b13469557e5da3af8b577762d39fc47d4192f1eed0ee3b92c\nSHA3-512: 7d68a5cb8d26c2c6f45319c15264d51d69f6d42f578ba4a8946dee1dd9e77860c7bc30b7e5618907b2d62b1597cffbc427f53564bf32a2daa1071fcb9f3158f1\nSHAKE-128: f73f5f368d86f9a1a4de508dfdaffcc872f144c67566d53e36895311c056f79e729bc6098dfb910df952a84fe915107f326e958714d1823d027433b17e7cb5a8130c41458e2b243a8be147b84932ff47a6a1d7d300d377d6bbbb2d9376291133b588fa9ea960f22177e4db7994abb87f444016decd8404369a55a154a9d73bebc339b3a6e098551ec02940d6dcb63e0c9c34cbf16737558f2a138f60d5aab4baaf3528f0208848f609d7ed8f857ec8a34cdc08c88d93f145e7d42553f6496c021e258fc329bde7870d278ac7761d99d17e967e9547dfcdd679fdcacf6c163ddf50aeb5c8fa7f2b8961b1ba3465cd1ef49998f576227bda7455b2129ba037efd22046e9b6daf92d484cb19c60935a101270c1fda39d0aeba436ccd6c7ed9cc687a878858224f9bffd9fd074039967b2029cad5930a90c52e30bd3b14c379cfb385c3ea7ba5e43374fd8aad3a5bc1c641c3364ab8ccb33b44acd6c3ae631f688b9da82001194c9d60bb260f117a1eb9e17af78ce5aa72508710cc5626aeed2c7a43c35cdce4ddbb397c46c36fd973263211c8664b87ca0be17c652f2c0bba662bf99628d1c28f07f11de1a28d49d594bcb64182f72f918612105a790ad0bb056455c6889a9a07b465266be1a87b6b4405f2e0687e46e7f0f62020d15a2f93caacc692f558bb46baa3ca58bced76ce2d0dc71be1dfa9c3ace9a47c618e9fb33f248\nSHAKE-256: fb187b473b897d866196e18f88150f2b96581caa25aea585f1927107ba353bc1fe8fb1f1e6a09828fd88824d47d2b5f2bf5cd756f51211c770a7d0e1d89391cad07b8b56884d38650a2f695ca36ee8374cfdcc961664edcff246756c6360ad5ee3851a4030f5881a7632218c6f607ffe4b88cd3b9dc4ffbf5ad71c85718dfa9ede0404e3ce9308142c77d9f0994b1764ae3445e37f3ec34d9380c0c9b7d7c18dd8969ab3174970d48148ce1bb2e6a53b37c3852d4e32088198e507c6702c0612fbaedcde2ebd134186b91da935c243ef3579089b362659540f9d7846ff2d597ba209753a5975a1ee2b6cf229bf22309c4dbd10d2c75d4836b943797a7dcd9887c14590fb37e185e7eb32c19a476f1b7488828becdef7fc323d53acb7a125367625032f6db439f1626156e9513372a0557b79384e303cb7c4ea527adc08005a2fb8637ad079255300d3f788a77a29000c9547e6927bc109dfdd9803eac4e67be32194415c0c2c1f5042a51fcfa3de15182b0720bcaf47f743fe81a97b2fca5c5b525e693e5a1bd295a006fbb9b58fa238678c4d8e83063a15ef2f02a7b080d24842771d191bdf52533e89f1663d3735aaae542a82295e0134d4cccd95315b669975d248cdc5e8e64525f0a02ab51a303f8bcc8d9f47526237dbda29cb4e16f13b5119d244452695caca1c5a2fa02f09c4fde43668f8f2c1999b28cf86a5c08a73\n\nInput: 4644288aed84ffc12c24383a71339aac98e775dbfd43482524a8df3dd99e5df181f23aea9cbae39f780b05c823b2f0474483eaf5fbeee87704eff7081817b14d93b617d9bd7726a34261eea5a8a6fa64e9d9f0a7501ab543e2c1fd60a74ee5bfc55f2a432cde8c6865822d1a2f59681a0c7de93f96cc39517ee0c3a13f1f873ed53c902eb0dd554752c9da20e21179afacd203f325f994436557783ef98707ebadb30af2dc7a0aaa120031ae52ecbccd3838027f38a223a18f285bad78e4bd5a050b17c90a1ea3f2442987678762ca8a57f9b5d406f0e0f0e626939612208efcbbd3df3463094c88dcd712947310b2ca8cdaadf7b5192725ccd4d593240c7fa320eda5685ff83732abe1bcfa16f644568d50ea886e951f291b9c57fca8cd5a2d86ae6470fb2a2f141d8f40d3a54fbcc09d76a57677f963ee58109284b238f0f3f421120a26dfacc9cbd0a4cfb2bb2516f053d692539465a2725af6e7d5e5ce1cd15d8079ac78105c18ef3f55229f5629eebd375d5367f108ccc64b788e4c13c9e7be2505e915297defd8a1b39e90\nSHA3-256: 393f4d54c7bc96b2790fa959333d584215507463265d0b513de5fd6b456f727f\nSHA3-512: e7db0a035bdd41f85366951dd5add7e67605df7a0ca23ac3be177e71b5c9ac936bd6c01a0491a97b7c3e02e234aa672f70853df9c768ace9c5aaee2eaeafa002\nSHAKE-128: b1fc316bd98d531694e45eacf146451cbdeb42f42aebad24c64979c079950490919196d95adcd7710d90a5ed16200b72434d4c2fd169e97b3fb5092bbbda3d41f7d19fc8e84ffd922760f62fdccd18978b3ba9d25404c8408e2cfebab86238081315c678597323955baf89fe3e496da16cf064818a8c0b4a515f66c3b6f174282910901f10f042b57e02ef06ae38b2a3fb2cb44cdee923c545d31ca60e739e6a3138fefa862fcc9ba021e96d6f8e2174d6c6da898439612e0483f2d12ce5f1addc5416923d6a572be2c85878705cf1bb3b782ae93c8b28c43ec132c13b5e606372e797ed27f7fef54fc5b691a4d9b698b797439718307af9ddca256441f25215e86c2f8e5758998d43427a8cfd034a26511c07ae534f1de841cea6e69c0963539b416dcee0c573c6debb4dc6fbcd2ae634d4cfbd59ddddd6fe5d6b6cc2396a030f0aa901eb5cee3c2af6d7f6af0907dd461deeb729913b5663d3fce09021e18c6e3d", + "82a503f5d51cd5f26aee454c9310b1a7d1de6707058073b567d59e8b83d27384690c6954aaefc7b44e4ce0d7cd110f4e9ecd3b77a835b0a4ab097428f3b4a1f60c7f241078c9fd8c54db2fddff59b25d254c860c9fa5ee8197481f2b672678f0e287e2f435d6d31d3610b284fbaa8f7d5375ff51712d63cdc7653f14c54027568709054417837e7fcf218bbb6497cd80520233cbb99d618dd545752e79ad\nSHAKE-256: cbea31fbea071dd2df595a77674baea79f636bb090de0bed63f7d58a2d5ef29c9e95f9711aa15169e6152db8f64cbb7afc341a587f955410e99f83f4a3b25608778f6c4e3d6c01dbd5558c6810348b838dbdb338a996bd0f8ab824c9b47e5d039be845d1df1f28f8c0f69f2561774cfd12a2ce8654f7d393748ed5230969534bc6a2b2dab21a658b87f031521a7543a0da9912662fbbad5b9049ebad3b1aeb8cdacb4658c39d739f57c7424372f52d772264d102200703d2b507b5c0b4cf57c6cf182d200539dea6b4eb30a17c82b73446f5f3e47536542f2ee5f5b40e95c848993e286c688ec4ce243cbe3f2c1b3dd3fee022bd0584c856bc33abce447d423765ff69fb0511e25a94abbece5af5a12de12e6614b32c79c4dc6fc2f599ef5947ec682d890c74c9f1019fa8acf12c0851f06212864b70205027c23df3c23ec96c52db218bd5cbde63b132417d061df9d1acebcc97e323e0cf3354f53bd336559f8783fc7d0785f24f87bbff15226a584f4d0d640d2b22fc75c464dd3fa3fd9e9e18d12d0a7a0bf1a584827db98ade4ef93532da6b664a5ede2bb865b8a501b4a703e88ff138a26081ee37a736c9b68bb014e033da050c87534269535f5d2c67da854a144ec9032e31da45bb9a76ebc480c3b267db63fd1a0586fd58ce345ef39f0717103d46dc703b09449bbd386c82a48a39528134579bf6efccbf552df12cd6\n\nInput: d7e9eaab91857a014ec93e8a44a61c454ec8051f541e4fd3e99c7a1f70ad423b87dc79987e4336f2868da8bdf939ded0858c0fd94dae0fa495b2d36a82e029a258657d4049f4250d76842f4d3782e3e53d54ca0d533b6a0d7b4f5cf09fedf4713d7e7fb8f1387e2bafa66e384b10fee52716f3e1e6f2580392ad3e5c11c2ed0a686633279a32de81e41aa7a304621c8f1290ec35ad0d6ec64b3d4b8fc3a43dfe67d5272b048c1702002271f670646bc64256d9335ff7a437733e3cc810df1528ad130ffa815db46f6a7d08e3e2e61196286c99c73917d1756ee87d4c3ea66ca35917c1189f160d789aa19cf64ac7c2a7b5a738245683177f6bdb434aa0b0f674b78e2396e216ac6d14081ada8d7f62403cc4791bb75c511495c024e93b1ed81d7914845a635af1db74b4f58d9c12e0ca48fbbc4c85cf1941f76f9511ab5657b26e4a8e2cf21c1aad74bcc4b9200f85931ff842ae8aba372604d9283617f41723588779e798dbc056cf2620b3dbc3b40a1e7d24b214d6fda2ff273f58056cab4c2e9a858f8ca300a176ec7fa84b28f4\nSHA3-256: 507743309af4f6a4ed517f43157d5e3adae25e03612037927a5746167fb15076\nSHA3-512: 21eed916f6bd9fb6ae9fa1ca8d425ce6ffdf310cfc44c63c23c2e330b8ef48b4b1a33fb10f69a235fc97e8d46d5111e4feaceb2b9205a7087850d5137b8521de\nSHAKE-128: 193568837006f0675e8ad7211594c6f6d80c609ad801e958d3cde45dd2b4c9e5837cbfaa4bf3165ca93f012a27e20fc5294dab4faae771e0fa38bc9c511c20f75abe4befe0229230fe94b691d1871baa7c790b6d620d727b33c9b407907c10734b25af0cd2eba4cfb28ac736e7fd89403b505756bd710b4211cfe3a61d231eb379b5a805e7a02648054dae0c3ddc3d163358128244e159424c9402c555a5a66fc98ad3f2c946410df452f72f69351513301239a65effc505e3c3a77cec236db034c4116b9fb3c3288db78fd97f672cfd6d3aba98960ff735683bdd67bfc2d8ff61c31aecf10c395a3a31968f79da366d510bac55eb7fd750c127b58d16ee4f3d1b1598add0bc26dd60021370948e09c500a0ef3d0935ddddd1a5077be84bf1eaf559f720d5e2adbfec9fc6d58cf40922328a3b2649d254f2a25c498a0e40b3a84abeeb7b15c1deb73a561ffca0692ab759955fc77ab163d2ffcf7252d2113e18a870327d1d8288854abcabf167d05fda1334c163d4171b9ade74a32a07a12e70b494a180277933eb13773b646fcffc10501370c6373d34b2b33c32bdbaca61d0d0e829373c010da71faf1c17196b1024bb4c5a28428f53f229f04297b56e53f6ebd70564020be8e3f25739de5990dea115199782025e37ae6e9e799be46b763a1cb629c19e13dc95e96f67ba0757adf4cbf0ff081a7abd0d738b1899244e94a2\nSHAKE-256: 7745eca85db88e37dc2b5231b1673c4cc7c71c35e3d0b9efc3b238e3ad7fb9826a9b6987f1a7d28d4b613c7b11788bb3cb128ecbff69b50109769c6881d1ed64560d051ef5026de1e57fc46979f8826e874cb6a809e4301eab2e2fa4935e6bc76b9e80419c99f3402a8fc6f21985428db6aeb6dd9ca66161dcf4cdb111f1bf9ce62d2ee5c31aa30ebe13603d01ed887dc60b1f5156e972056c7527688362348f1e677235dcd87c1ff122d99c0202762c8b5c1548287aaf53fe5d07d42882af0988cda148c59b71429597f3b179ca53caa94f4a0c064a8b5cdb72249b9e60a796f433081bde0d95a2b7d7e50010f99760194a2ff5e1f14c2b1b6db7ec71fc22a49f389c41552472b8e198624cbb6ee6d0717c5144c7b215937c8db5ab048db97921d8b0dab9753539cff30277808a79dc0d9fe067795b07ed3b4a1dbcfbc5b39c37850971e5b1e478446783901f52cb048abf937867e849188a721b08918be4509a24503808206f11aea662286e26f2c0b4345edd1edb84291e4ef68b822e367da6927cf58abc32d822af609bd9be3378411d8b85ff191783e9ee1c1210497a56e0c6bb69e74f2bca54a62cb0676496ed1d25d0319a54804acc8b191e8d7aa4f4eae575ec41f4600ac3e04499703865b27713e31865771bf11e87eef8cb546e95ffb2898dbfa0e3ac1afa8bed65fbbf74e7a11b632e6e7de004bcf131537f8e50\n\nInput: 90da290aeb99300dd78467fdc2c04d1ed87e7665af71c4ebf052c54d37a68bd59d21bf9c59efa78b0a1bad7c6a5e4025727868fdb4e0283ce7881620e42737ae9c9781d60fc651e6988c6715de14a681bcc3d0407a9f9fe30d3c9721b2093bc6c129df5933f90973bc408edd963c3f542db7e6b4f9ca91c0b4b7f79a3dbe913ce52f6c24d071d5f52a0a373f6487c85154fa04327034cca8bf88fefd908d9440c94f742ad6ef40885bf99e75513a61a4d489410ebe91a724f7c397498df52770f2091c88b7c2e9e8f9b30fb31cb3ad5240ea9c8e4b0ac5aef022755bee74946843fc57e899d336e974fa90ba5bc9fdf171ec5d5638f3a6199d9cd31ccaecf2c4ac7878cd0e889b196aee9c3c12a5554868ee09314773509a287fb81383eee61fa986ace0976cbe945d0534e57c3f0839673611b19917f1b5d15f9290d25ea0d0a9d70cdc12dab14ee1bdcb0c9d60424d88c225b1d205f8911458c5896a41e5c2e30ee8d4841c032c301a614acb9343d15427bf5cd7e83c5264ddf3be4f119ee78833831f6ede94c6a3c86016acc7db9b\nSHA3-256: 5935affc9b15ad7fe488e3f724a5783e52d33b863feb22ce0971aee053d461ae\nSHA3-512: 8de4c52bf9bb9da481a55983973a44ca62a270185eb076f54307c5191a153c459310d6df0858248599a8dd3f320f5aa7f38fd8dff9b41250f38a4ef3a2a2b031\nSHAKE-128: f806eb93ab809535ce73a70fb759d03f8c1c510c75215a79c239ede31e7f36b90aff05a6e524110c53cee00789bb9d72381007a0d9966c59d722b5e79d060b32cc289fdc7f4fcb1ff2ddadf81084013a1a1ad2583e955772aa28f416f4863a03c45e592a6a923b828320f73fc4d567b1812d1233408b10e22ac8b12d3981d717dba4d5c70bd6083a3b96cf772659a4b75d367c6800f7ce7e8359a3c1178403592d3a5d1aeee5a3d3851d41ac8f9e112c57ccfc8c8bc36a7d1f3dd719f762ae8d5dc016d3a447abbfadd9e0681466d3ac9013b75b6c3c847840c792a6baa5e92b7088ff25ae7d8869a6b3e4b705e184e885b00dd077d2a317ba2c492fa41fd039f06d62082a57586d5fb82cd140cc362b98435ff0844074cc1541a702e9fa78e85eea0cb144bc0e8f5d2292195c19b2b66bd1583960319f66bbcc6e9a7bf1433344862e8ddb6a15cafc71a399f7480e5c1a4663372488e6b1a963db63a29e80e5d79a18a4bb5b3536aa7c6a7e1b679de3214b93aa40c0bb3cf6c4371864322eee5e63f84a1aba45c04fc78d913b5a5a9ca5e406106ae6ac3940b6b54162debb6b1089d9ee5971720b32c70b7ca3ebf37e195be28f3bc0c7ae35859aa514c398e7ab429fc6676847b6cbb4698dfe77d58b14bb5c065356d7de985f5c49fedcd6147ca0d612b2daa6391c89aafb158368339c72fda9a90b736f32c209a118895882\nSHAKE-256: b55bc28a85c43b96addd5c61410f04ee0ff0e6b50b5d9517cf3b30f609052bb2e3c826c70dedbcd67f852af0fa2794552a790e0475e7765456016ad56a1195d5d1b3bb8760ddcf5ba17fb3e4a88c4740bbcfbfe2ae16c53a5350b526e5f9b28828ddb4e7ab0b8afbb722124d7b62204ea4a5a8ad57c1bdb13014021a19392eb697505b65b148affba2888223af60e12003a1cce6245e5224cb174a0e761808c265258c07d32186966968fd38d042377b7bb758df5348c24ddaaad0d855d59daf5c58a6ea196aea5a827232993c02858c79c15fec83a9cb26fe8627a419b05872a17c981879a5bb0500191cf943522c5bd11327493f8c59c82f093d7eda78584d0508d94f93fb5e7dec2273144c2fb8e74518fe76c69c543d0fc165a6e68e2cd6186462b5153f5927e65f59eafc2cdcf6d50b50dc91b39406b9f44b907df780367addda8c038708a2776ad69512c8219f7dd764ceae804678a922dd2a1f034885d7298d775104593be12d56ff303e658464cbe1991059f62ed0162f9ef3fe28ac8cb3512f51fe9857c88f90824692fa382f24a36f1c629824d2c34fb3a4925211cb2466501b91fa79f6c76098f3df25f1b114667af6b308c8f6c1dc5eab56b12a4fa672cf20fb15f1f2520b47301a35a40613c2ff797c8d3350526c02646730c840a5e36f46ffd174c3a203d4e34ce7b70e1bf7203199453b393154882a89b519\n\nInput: 7b3390819c7586e7a59a64bdc529e5c3bec452b1f1d9130482463c45686dc2368b0481bae88c5d80c34adad229497a8d3c6b3982102697116c444e4de964d8eb1375fb785e33232d40fcb020aed7f2528025cd803b89d0acd5f6115a9eedf34cdc0e213fc067043492dd63c413d17e07fec07e7b16df8761545af478352fabb07b7fc8950a9d4cdcff52beb0646b319d9ffb614f14fa675b06aedffe7c6b3acdf9b8a969552d81fba94ea99f19b969496ed75d86ac196b7ba1829c421e8f6c0256783a8813c25362039c3ca4c18d255fb004305043a2b0ec7aead4aa1245c43c7722589586601193762735c50e603a5d7edab6c717ad1b3fd253385bb76b118275fe83a70db915f49dc35ec0ac3d87c8bb02aed4f1653c101e0b7362b6134a9c6b2b7f2265c8af2f0cd677df886ac9e1420b945f00776e1080791c5ca993852c6e2", + "60092eadeebc879b00efdc01cc051e54a48171ea09539657028f743bfecea77a4c8b981d86ba447d9cefb69860a7087515365921ad8a80afe314196e298fec17d92ee4ec7cb0b0a5f0f3894aa9164c4\nSHA3-256: 3450d6c22cbdd680a07f45518cf25a3fef46601667c45f1257885b53d5c52db1\nSHA3-512: cb8612ddadab8ee26d9fb128c89c23567adfacf11d551770a29db1cf37646acf078efbcf665e99d1adeeaf5156a07a968669236f994129dfeef634f644a741d0\nSHAKE-128: a4784e1abad8b37bed79c22a3939b997d0dbe41ec73e60da140d168db305e9d1b95bdffce3f1357cbf22e6eccc1ebef9e7e589171643adbf5fb09eafff3b272d784172f557431f2ea21b0ba60bda2a9495548db20a98394fe0cee66b9ef80938dfe342bc5724eab3b3f9cf23fbec89def20daaf601e247be67332a64dcd9ab97b73f8340f3337929e12f2c505c34f16cde182992f81295e7ea0b6ab05f0c4b776b50882113646981a950f50b793a24cf9164fa483c3cee5277aee76c54abcbc90fdd3246e831b516f94f4712bef1067939f04c2c7ed189aeeb269edf104a0aa5a54d6cb30b984be31b00ff41e43b24378a129275117cec82e458b5be09b0dd2f504e188057766d7cdea894349ba1c8c1a590d3f7e3e9992c13f29b8e6f31c53a45b852045c931c8342780f8d780887dd5a07f1f621d5a41f3c9e1a6386c0f8c0c40376e4cde308c2b691ae13abac2b9d1a6f909058487682be1c91a63430a65e878628dfe312731d78b027dd4551e67baeeb2d9a68c2fdc16adbd3d981c37be546b1a23ad327cbd4c75dc732ef4586174c1854dd90d260ceb9d750708b5b488ee12f352ca5829695d721e5849cd615f6dee85cc6d6038037e216dd5b0ac21170d6e9718971d7bd1f1d89ae657b47a735974ce69213220aeb7e8ce4446e8c12cf8cfa3744ac1ea4efaaae18b98ee704b314b7a541f01afce7ff5e5d50b4528990\nSHAKE-256: a3f7b68bc0e6d6c8e6097b3549979fc3d1617c7fd3788b86a86caceaf6b887c02c06bc15da0a16c3b1de93a9a57b6562d98cab0049fd440b844f856ef90f1c20f7279c35de73a28b8e896c857dc13931909ed1c4f04361e0f2809794535c81159899a20d5369a14dab4ad9925881aca6a65cf13de7ef3ef16710815b3e1ef55be129c0990d2edd501e9020247ce0652f5b5c59db0e16fe5aabec161db8129812d0bbf5df0a3c343451393c8e76b96277814f9d483205dff9dcc35a3401e2b540804b4201d4cb94b6c514eece1b43e1af7ccec6eac26b40d96896bb4a70463b3cedd630a228eff16790910caa18a8973e6108177d8b176763506c566afe8c1a59d3aa7beb82c76313fff62df4638b2a1c529b79bd1610827fe5ccddc906611a3e482c0b9be99a074c87d1c013f72efc36e697327326ee3e171e5a3e63c676896e52ac29c9f39e1befb7d12afec3c8326ae430ff33f07020c6977b29b5728fa1c19214fc2838405157e4198bf6652500d6f734120aecab83c16af242fd67a50b971802be8f26fe7311d380c33a061872092224e7cf18344569a3bcdd7c8c2e7faeab97de6d4638ba74ccb25e0ed353e190dadd1a3cb5873b7374c631cd198292851084c68c5b2250759e12973210acb3545c05199e4f7557d025b5f2a5d357a5f28ae4a0cdbbd3954db1b884301f989513b0e454ae9ec4f0c1bb5713bf8c59ecb0\n\nInput: bb3f53459778f0c0f5a9192868e735f5e2126bdad7840a7053a8be2c62f178a731a800088ffec0142b0294b8b04fb8c4f170635e458ae5a985d940e2a4e6b7a10e4eb69a638f4ac842ad78d1ccf14a4de413ceb53dd201d3eec40fc110dc3f4cbbecfd1eb8679cbe6dbe62a804f8c82e0f9a76dffc9b125c3be7f7e2674fc6790b2808001de6584145c7ee97ff7493d818a7d9642c8015643035c0b5609917f0e8089150382cc37cd23485ae8e856fec49ddcfecda688c984e4df605dbd56a85d7788e266ff8c76b0fc296f25cc1b64358022e62a203eb959b5c2af094df102b26ff6e83a9f76755bb00756f9cea94de0b4e402c56b5285405f7180c267f942d2db4a0737cc27872babe5aba80625d262e04c424d224490a4f944f2897e97201afc130953b427aa5e985a5dfc98d64d4678cab62b808db9d65685aa8ac82ccb35a0b232c42e218c794c6ebbb101e6100d7e87fa060f461831e8b332e5d5dc3bdae93ce823b55324b5afef37860220cfdafa8f36fc062f088219174db851e0a34989b437361a2caf408753b9eb05d42ba2253\nSHA3-256: 0f969141037ce87637c5ce8b1932e5465a0f6bf9c1b6ff91a37f92b2fef957a0\nSHA3-512: cda666dd5fe282dbf592d99a797a5ef8d189446e7ce1cb9bf7f114115b810602b327ca4c6c347a8fd49fb49dd82017d1c6fc32ff26a5e40664a6580930a6aaac\nSHAKE-128: f6dd532d02a69224c95e8d3bfe65219b919fa5adae83410dfef4204b0609f2d1ffd402eb24551cca9300d23b62689efee929cbb799647da89230ed210b71e787dbb6d003b4e9adc8eab57103a9cb82bbfa6175441f7cd5e71f37a3e8d4d5da7d32b4371ec8da53264330fa458b3e07ae56081e8580c4d1e56082ef1806aeb46421639391d4795d28f0ebf635d99ffd7acbfdc457d88b41b268743f20972bcbf1eaccff81cf9dcef9ba9ae7f087972885f0ff391fca6ce1dad088f81bcb7ddb0e6b49c54d91b0bff7980aa56d11f61b2d84af26acac246c00756f64cedf090428298cf89880beb96da45d6a4c03788004a02915873fecf5b8c60494573ddc87770526d279057741568e51654fdf702a08a8ae6815f6824555799592c6d601b18ed0a816f7d3bee88776d265e0444b1cb01eb40a445eefbac3c4a0622adba07dc1a735c96e3ff330ea7a3501f1d5f0709f4f815497ee1587a9d154e2d8d59a52be7f8e789e51801ff06e919566b6381e502f29b96baa32666e14798d141f396554175253d5170461ce655d958262d0788b14706b42fd6b847c5c2be18c10f954a670b4abcfa68263ecd2310004cf875576363ab54773f8fb989f55d6f3e54d554825503327400dc981fcfa4727cbdf6e0ab4650ff76abf4d8714c16ae2e494b2e7c74a30cf8aa98b93c4367b1953d55176d7eae938720d9f80151742f480ab09f8\nSHAKE-256: a0a8cf47ef7c53541b0579893f86fedca88b43de5f4b78ced9cdf2e6b282a6e171fe93c98b6e2a53447f1712700fce05eb32309634a368e1d1b2d91381eb88b5c25cb47aeaa31d5da36e1e225a8bb2f54ae2328bcbca872727766894574fe93ad32829ed91c9d6a4c0871eaedf03a8e731a3c6f47e7d19470337bfa4d02b2724448123273e443b44cc8c5bb8b0766cb2dc31d477a14a4b870bf6ab41e5beab3ff7fa57e90be6cbd6e250e67bb4bb09f438c615e976ba6a5a67cc222edc71f5874abf82f30bf29d53b16719132c19ef29a1b7d1ccb56df4c2a8a0483de32936d7e23635dfa4ca6ef4c2ff6ba5d3c2a7e40d58c533641d7ea5252c84973efb1fd18d1ee9722908312da864d02dd9459515390f92e2b1052f64c80bd344c77218339b56d371bf0cbe4cfdd7c4e94018e631138d201c6c488192481d6c636e14a62cab74f0b6798fc447c6635fa444e91dd6aa5d0a88cad66c9a1593037f0c9022b4d170d95a5de385403c5a38a422ccde6ad755c33257a323bfe75aa331e249ccad5c7d4c7a96d14b625e5c9162b6de58e7bf60944caae0398f49643379cb7c5c75cf1ffc3e14fdae6d6598034b685717e1514abde8148e0799158ea418492c1f069be98e1cee64c7fd6ebd1cd8b2fb79bf7a1c175e555d0b316610d36f33f37072f6511e402fc38e13b829369ccf34c097066ecc6a92e1e0918a36ca79255c07b3\n\nInput: 727401beb5fd6523dc357b50461ca505802b9644963d18bccc0e608a1bf03c6bdde33d231f35dd658f20400bfc82e0478275b82cd49f1a1d4965c09a5accd42987a978ed8764861fa26deee8f8777891483b42df7c517b98d3454f4d2d47fb699f01f10b8785d8ffde092c64ef24348392a5c4b3ca4cc88f697e5e365abd8ab353c6af866d19b067b77927e8e67066f1462e0d0df7ea073319a848597fa79c8f320d46f07b88975f7f78783a6cb1820a6bfa8a49703a43c7fc2d2da5685229ea2f319f252c66e683d4a05de9a3f6a5b980a592302d3dcb137090b91dca04b08dd273d34976ac5f0157e27da7b4037f4afc2885033efde528ab36dafd664daa83ef388bbfa60ad82280d3e060530741420b80d8f4470abdaf5a3f9371cb033cc66aa02573fe7a5e6d19c33278d5d5e196700bcb4c7a662ba09f7f6f56dd4971ed7c267844ec126b3a55682e9b532f1e7c12980416f9049efb9948babfde102c024e7a5245b4c9fb342854c5cfc7c54ad0fc9bbc2c4c56abdd9ed8e6349af809c5ce75ecf886410a6675ea2366958535400e9283\nSHA3-256: df931008b451441679dc01ab884772b527f4b3f73a98c816e0c95112f531d0b4\nSHA3-512: ae7669dba36065ca0ed7bc6d4e5e4190246f97b75b3e71e3ddadff44289aed85100fe7401bf176980674e22affbd73b2ff48721fee62f45b91fad2b33128aaa5\nSHAKE-128: dcded048919499dc0eecb6c1e3eaa087944e70ad8e2b5c9cd0f9f7bc45444d3051290bf7927d26f271c006c72a71d3ecda9b9963ca48767bd6539c14cfae69ab1e611a8309f0d4b7851143a547df716c53512540171f9e3743a24a0ec2c971dfade93c2f2dc8277f2dc96aa56810825fb31c452c0fcb14e6a1e07f9dd5854b0c4da97c2cbac2c8abaa6b807559ff13f3c8bb4b124dd53ce185c6e66059675a84e46464207fc007d89ec99787b70b09342f5c55fb081f7f01bd7d0b822a9af68511996603fbfd15c15e85697c2ebf3cafb8189ee99a0621bd9f23f7426890f6e1368f927ac8e646c86550ae665fb7eacd096caa7179da374d2a01cf319d9700c09af0c9f0cab01ab1b98318ea997a072dac975363a390c2ede4401817c94fd330ca1fc9aa58dc88d0707463779d4f49d3b32dfe7d78ca0ae63c9c54258721ea44dad31bb225031b104e4a18915512fe0db3e4effd4e5c7e7343a3b046088d615a32509fb9fce1eab12e14e3168a9d3552257935716b0c75ee0f3b72b5ed8e4cff158f6d8abe3ab5a5ba1898919501877d040efc223b679240001fa8d1506b34c1fc7b3dfc32b14a5468ffb04783f4c2f1e981227628e48c3d370c186765bfd2b53760d944ce0454810c39b344f82ad9b2128d859a2697844315f3ed780e7e7ca38d1a0b48e3424ebaa64ee384f2a7f39c7e887219f8f2e9ac90ed0912c3a1f75b\nSHAKE-256: 30ade12f1fc32c8626893b8bc6e7c14c78078a28bc0e9ccd3456cd877c68adfe79abf3ffc4ecf3e297d042d6ef957e65af407d1778362881ccbea52c3ff04937a4e3f8f383d94561f35ac8287004039d9baefcd082afc55e8850d674b56812b5050fae36f1796114938b74f98aecccba0da42a02929cf8be958ea39042dbe2996f1b81b3464c6d168b43d6ad2accf4388c3043ccc156fe2c0cfaa5ea534ff8cdaf30c39b389628a969b4bdd1c15eb2425d50145e22bef574c86537f06fa4409823f954776765569aab2071be1351354442695c93b08a9466a7ba7d888b1210efae148e5e71e82f5c7f74061617bd1e833e3d44e984694fe3bf71dac1e20e68cbe40852fdaef0cddc710af1ef8b30a98bbca82912db70fdd3f204b1c6312", + "5c7bfd8a46efbd508437e8f50e1d7a0f7b076913ac8d104815e6424f822bb77dd7194f44dba1f1745190fe5ff33c7e5dc3c0dbe357eebcd6c3ff67265604a6999c22dd106d829ab123cda3a161ac03b00c66109d84c5d49380d1866148889da29b0fff9652f3a5c9db0b3a8b93813ae332d46264e04ba1d5305c1b0af95b33675ce097b4346ac1a20aa72dc8b1d3d67f14e4752f1228a2eca95e8990861abacb6d9303286a77c2b7bdd84bccf433118de4cbf5bd46c0a1cdbb6f8e2ec8d279a8e177d049c47ac1735b6a9802fdc8730a50822cef834a6174f443f850c5a8be7cd9105\n\nInput: 963c9e70e33b9333313674a0efba110168fc0ef24ac99aac92cc139859188d1f76dcdd354ddea15cee383e461128c6df5feec317f5558b48839256783c47bc25483964e80ec7a4b521e179c3dedd4927c32e6b3dc19a5a1bd8826daf73f88d66c32d9c1845088830d0b2aa2c4a4c66bb5c55cc668332056c70678ff77e036a66ec497a07675fb15afc747596938c168d1a2f75aabd2cc2c1c271aca7e4cb79cf22285ea5125728d0eab0cf08c02a96d16cb653dfd8144ab48b89603148d24fb85fa4c430cc3190fc5783e9908667aa1b172f617d625559c7216dea1f109c8eddf2b86021ab98199a76b3864e02c56ccab7d49113de2e396c5a93391c16e349434d72cc84e1d91670758affb458d6f7e09eb30c4f79e6609986ead0b28c8ec07bbe8e700d96dff2afba2f6c0cf6e87d77d62e8426455bc5336ef393dc106731306a73be705c263e3cd1d2af38673da4fdbca3539cd5df79982639d8f2dc793bdc11a40e02d19e655b7daf044e9305ae127434868c31abe8fa2d540e2f2641d1b54580fba89f8ee4c518b1d229e509283689d8d6ae\nSHA3-256: 8692828f27f1bd0340acc1669b4529e59e3ad5fa77730c334c7e3be3df59df41\nSHA3-512: 54a4604aab4e58928f415ba83712b0d706c196a9737862740cd9dc82c5ce14b78d1ca90ced845ee879785639680c582de84c1f5da78009f7d9fbfe95fe99aee4\nSHAKE-128: ee46ef0e314b7010c45e20fec89941671ff212c518df641958950a0bb980a8150d2147e3eadae106d5a48d5135283e871d133b44212b03459cba3180de65b9372ad19df4c5f1e8d534a7a7f369e241231cb5778e7637f51efe4be8c1950ea91e09f49b0a7cd340d54f825c4a5e89e5c3a1431db42e89f8856808a7ac76cc1c75e76c327c2b1618509e2cf9e3ca905d86630038f36ec9d0a814f8087ece586c2d10b273588579143c34f6943b61c07bc746d66740813387e739bb4685dc1290f2b210883b9869ca1090d644d9f054f7cbc5d36f39369ebd800745b560af2fc76d513ff0ba297da5a1f8643eb0a3c28356f8353ddc57836e5bc35c4b4ffcd799c6b37726c8211132bc5b9936d98eec999d69ec1dc3f345e3b94711caca41a5827f0148a0f3546247bb2012c6b48898287cf9542cf506d9cb6c77b1418cedc689526016ac6b9123fdb1b1739bba7bdede043e4753b67997030fb2f041996d0de13b0f82910035ca05e9e5ca8169578b8542f1c22d11ffafb811b4bc72327f0a6bb1bc320183b0203f09956cc75b0f3fa615d56aa994333643b52866979c9ff3d22fc92abff6199bed4aba9b3c4d57661ec1763cae9f9dbeeed902c68db0bd80a752a9bf99a2fa00444f39d8b014871a54af8240f90af917ba32fa0446440a054bb3476a1629362e97565654f790832a43186ca6af7a4379da368e965105a2cd22ec\nSHAKE-256: b0e9a8742568151ba97dfe777331b20448b2858322ee3e41f860b2fe8ace4de66363d82118bd08b1a758d145a80df1947a95ca86b54f9cac41231882ba3db484a0cc1f294500460a009dbdb79be0bc839d13ed4af69e98afdceef2fb1c7215e3c51fa94ee41bf9a358ee9a9f9e1c51ec5218328c7d6a684814d88de729076ecb2d1a7f2db39fcab62893c7910d032494bfaf43ffd0564032a16c228b9242b59ea716bc1d809536493ec0bf125384cbdeccf40efa0ae264821d8bc3d4e65f4c8e6daa114f69b8ee186cfb6e080ad1d8d7e4b91540ca49687b664d967596a7b41a75025dce1c4d49c0db801ca62e670392967ce6d9a1cbb80139f3ac81e9d4db80525091aeb85bde25e7246566d87f55dca1a8b837cd81d1a5e6fdab04a031337a4ce824d9d321d957968b8d4bc5037379befb4905ba77afc7447fbb866cc39d311a3d0e797995dc5825976183d66f7c15c6776b88da1d06ddc1b052cbe16da1afc3278e906b1fe759feea7775c5556de4aae8c4a2670403499b4eee9b957545802dc0afea7eae3588cccc2fc502ace0213c57350470f43f9fa01a9225716ff4b338ee1b0271d6cf76c95e7cf27eea8c35a2f98206d79861cbcc72f25949e623947ad03da3515bb5ac5dcd748444ae82e878474818c4895c93a31f8e3719ffe1d406eec826d00b059dc3fed1dd9948c5c39b2e9eadc38de7d6c9a8e6cac4774cbc\n\nInput: 2b11c2ceb444c272b33656e7669b6ce9f8545f78a943ceb71a28d647cd53780e355aefbd2516314808795baa461f3c2efbe55ff892ef70620604841cb22c3a346d284a1c1e547c38b58a203ee02d178d50bf2048f45eb36c55a63c1fb464c2d9752b1a7ced1fa407456708bfb09bb958627aa266265f07662d3b222a51c7ec1adb5aff21d98cf4fc03475f16af1a7b88a9bfd667abbf6b863aec616b785046389a682219bfe32304a3cf8c1c33dcec579937963ee0939e276d5d5189cf0ad30e7332b17f4bba3b97132c44ff2612d6758a3c582c38a6bc6f4e590e4fbddc8cbcae08b53fedceda95c1ed78ce13e35c073e800b7a18d2820675da236577c1723904a79c4ee78b0e4ddaa20ade85303b0238e698294db892115feed7e29c8d1e34957ba2bbea7b966b54988f9f29e6cb9d29b078b18fa2d56a01a2d02af23c712a998a56f8c9d6feaa58989a5e2893d17dad4301de0a79496004abceab08a1e96690d401dcfcede9d3ff4ded49cbbf16419fb71a8373674c553c8f5834aa000976768f446f24534e9cfc48db6294617dfdd6601ab367\nSHA3-256: 366f11d73ed7009975be072246592395897a248e6e9475fcc629fd613f89872d\nSHA3-512: 2286ada9d9e37e601aebfe2c19f3da6bec427ef276cdb01fb13025d3eda6078617a22a657a0daa3958df9f12cae18087bd947d6f1af1ada470d8df13f3c01382\nSHAKE-128: 7f8c7b74963cf9c17fd173765ee6570ab1bc1eccb5de390282d3068875a065c3556cba432f2d7b4677669f7f48a3187bc944f41c8acd61ccdc7fbfdb5d61dbf8fd34a060b82099ba81823ad64f1cbb5800463403e506fd7c426e71d9cca0c00670940cae04ad9e4e7ed492112185fe95c04d2028c9ef8d6917615786c20e92f5666a80e930a49516dd126e39fd3b9cc75da4999ebd0fe19d6c62cb21fc648e8b3adea6f84e65f5ab6b90f450b13256bc075c29c7353c2584cedf08a82d290527199550371e061d42687ac8fc1b48560fc02d531c1f0950ae8b388c505362a3661b212518241f329618fdc19170b778977c96baf833dc694678d3fb51f448ce9632a0e710448018ed885dcfe883a1ea1d6dc287c32ebb5fa5096cf43973d36657c895988de482a4521c974d0f04ae8634d5975fe0e24dba39bc54ce50a96214e37c9b749cbf2b0bfdfde942544038073bd6498498e21faec1c102a7a80e16cb4b50a2fc2d76b678f38a0980f883d814d9e13ab1f82ae7a8855a45b03c1d46224f96cc111430692cd58bec1c99fdcce05828034b76ab04d535c18aada18e94ffea96b970d71e60b7bccb59fe60f0aceee22f4826b32b7cbfe780b1eeb666438f4a0dbf90f49b34a7cecb7cc0c162936e15d4351467e40ca823f04b0ce65f1490d614ea8abc7dc91ef3ac70059bf58683b065fb2f0d5e64ccfe3ac90ab34bc52e0a\nSHAKE-256: 6c75b70f0b05133dbb5b87b91864652024416dec1b005ca29b68ed87aa5e8f032ad60950ae23645566a35f48bb6b721f17598c3ca97dabd2f9b4ca969fb4bbdb6496d5540987d4ea45edf850c83d484037df8a93f83b5d2aa17d272aa2897f77d498d5cc9389e878bdf37970fbfd99f28695c1b8a751d567294f04bdba83ecabd3437658e769882783d7db6da8c6c82c960191258b4db4b689d4b714f72c5cbbe078f20d409c52e6e46807d2a335f549f297fa73a7fa2744d5357f051a8a1dd8020b951707792ada69fe9aa521bb2faed61845e65c7a65807dccb063c1fcf77a01770fd8357beaf7838b854e3805717b0fb8c45be08466d21330f341dd055a5cdfa9e148efab483ff6426252d5ad9d365a0867dfdfa2a504f667c89a825a87a0c75a6c1d97dc35406d28ebf8b01f246c18783d3e049702b621f4812af3b8c588fc546c2e05b316a944095e2e5beda94ceabffa9e48168bc7488c13084b33a02e6b355174f638dea84d5b54a46da18ed85de654ca6bb0bbb0631b8b51235e73c65ac7fa43420055f74c7ec5f7f8ae0c2019e052ffd85d46aba5b0aa3d8ab1dec94897897564afb02913adbe08e26820640958c51ffeb3e9f038d31ccd562955b990a2b3d6290b78ccc6d1650a690a6963d23bb8142b884d91e60c704f242a7ed2cf84e13c28d6808be384ac8d9202dfe41160af5d165a8218064f852e4f32261f\n\nInput: bb466809914a71891f2b8ff50d924a38937391bce04dbaab19e05e087b46bc1fe9e29289129fb1442ffe54cffa4146474b63880483ddcb8492294ce7607706472721ca75f1bedf6579db6871350270e9ab01f29ecd3dc3b2faf504ec9f5bc38a74ee9811d7bb76f1e4d256c17f686cf59480ea1698e3684737e2efe8f57f1c51445bef8018c8e7567d89530dde74781c7ba109811c001f48be2ee5a52e687842d42d50103d48d6ab00c5dd9ffd50108a85672ca8f26cf52831f0290995996308e32909408913b44a8fc5b60f8d36b7b3e87f983f0506ea0582ae87ca6b64e7facdbe1a9f3d862d86dcea1749e6afa7a70bcce167a68badd51f2d91576bcb7e573371debecda1587e369389be8b7de232e22e394ccfb24c9cf2e8f70f718f69ee6c6dda7302200302ba941279533cfed1278dd6b515f12fc128ffb2d6645cc069d773d156cd1aeb0e0722c3d5c375588b777020ea59ecbbcb0c1ea0ad6f8183a0c128667ed5d4ae699a29280f7eada6984cf5ab177993ae07d47d984b3155dc3c03f22898b9172aaa93ba249c20cd31ce76b1d7e3332f\nSHA3-256: 6bc6167a14be9b2e70d1f3de36f67ae1138f7626005df0578bd401da6ce74d44\nSHA3-512: aa9cb684035e0f5b3318b8f59cd5da821127f7f53da319f5c861ff7d428d5add9fe09672447ca35d12d022da8dae019c823b36a19f35b89dccd70edf738906b2\nSHAKE-128: ce282d1b666a89c2bc07176e776bd113c6969c7ac0da76168bce22a81169633d71301dd47bbd5bdd77320a0e8e48c7a56d30c6185fbfbc53afe43794b3b69649083c716c3fdbfdbdf801514bf99889fa163c101a6b30b92b50f1e0951f23a3877c52f543568ee9a1f723d9b5471fc29dd24fdde1455b9f0100be456969372628b0d74d3caa9277a984aa6639b82f98f33c14ebd17b60480953f9dd1c0e6c6c337da940b04508187b8a7f0c09c2e1f9e3a7f044d5a36433144f3784633936d93208045ad74b3fa7f2edd5065eb5e4dcd781f4a7a7da490d534294e6e36102bb05f326917e813cb8e55d1b6d554a9706feb6b3", + "bbe6d279844a47ce51e39114d51adf555be6a8da4f33599723e078120e3a013590cc38b8fc377ec794d23c72e585e4dc974e1eb71111fd330b83a4ca9c398baaa6170d2906c408e34e03582c1a80e1d28f54776d89dbe5c1661a272a2cc04a03f1142d8f2b9049d88bf8e547981053d0d2082d8ddb01de2a312843cfd82900584551aa36c03193e51e00d4020c313cda3ba5d0ad5234681ca2a2b8e63a1203a2bd80e9eb36f28dc1b573b128d1dd190df1da13137cea1c054f977c8a6fde73d14c8fa43832eddfd6ec4c5beca4759b3d463dff1922f7d1092275b05ccbab1340537671f5057aceacbc74e848d8cfc0eadbfee5b360a02f4e8de481b3aaf11f180ba205bff44d6aa97b2d8f00c40c\nSHAKE-256: c5e08b5a5d70317f03605d0b0da4ea872e06ac695d79ce59cb09e1b95938eff075e03676523428e14d59d937012f453b5b3b20185cfeb7d317326bddded47e9862c1b62a6ddb72967fe17e07df75116b0d810928a7181160742774550ed55ce80b7758201410ff573639ac9695c16ca169e1504a93eb584bf69803bbf69ad81affe96408e1e1e60624837396d47ccc2b83446b0ba0088ba8e7303dc1ae17da9136589fba5b8b6f3373516d1c14a901b53d9a2cf3f9af118c974525aab8cc2fa70f8686de38c63685f6aa985e10255867ab2f62f6aa87773e36b24a2a3c89ef1b52935d6027a7433c30dcfd392194bd4adca2cd0973d72bf3d77f781729efd75fcfa499cdd8b978d572efd6ac4eafb5559a0121646f89f88db6782deecc22f7f58e0e0de0a00f06caab4be8dc4479f8da643db347e1dd2a0a3acaa7c1eb7c1417cec47725fd82c41d69ee25c05fd2c31319abfad032669c11260f16664c94df8293ac3729e63116f1494e35d251bb711e88107b81dc221b95eb1d9e8cc9fa3a9b9f9d878d99db4f9463c881aa4e7fb6b411f373c16fcf7a0a71e9908576fe79fd4e6037f8b4237f52a94f09413f387b3f363e398f0e54e7f214f9e2fdc01ca76b8f884068ace3c40892fe1d7e26d766242bbd3da7b3964860c25958842852bfdfa93038de82c90531020efa67d03f1c4c7e46c9207ec1bed93d9e1d972ab30eba\n\nInput: 96458ec8017a325f62a35b19fa2c1427af5d3fcf6dc3879f3df98ae0318a301ff0d29dcc79a1b78a30b7595f7e88c0f7e249c88d6a1d68070cab0ca74225ace9104ad50367908b84989073b1662af944e9f6dea4471e66227f209d2fddcb6b18b9f66584036b1a1c4bc67fadc89bd359cd7869c171cb43ea4aa1882158525db6b468d40ed53eb1c4d52b5a737daf5845a9405323cd4ead0d9af59d4754af163b9d186850c9fa105cfdc3e8f9f6e1dbec8ed40c83cecf8e2cc936d869004ebd54874ffada48eb351dfdf1de6e9bbd0dc6712514da109fa48cc6b7c11d9f6a0f87e4353209abb7059dcb13128b89589af01ec8708dec2ee23f35034856c24662d41ee2bfa36d3ed3a71c0e154bd8b18144eef7d864a95bee86645f4fee4adf889b422296b2f96f65187a753314a89d631dcb21630c47f74eed3e2113dcff457085fb82902ccccd418590e848e4cb86fc43cd5bf55c870855834f9fae48a783bb3e2071064d82b700f7c1af098a3a8399a07742aca0d7220318ae7b10be4a0078f72457a0eca0fa4d35128728a5b53e1060357fe2e29be969\nSHA3-256: debb9387c9ba69a1344f17ba1ee850830b1a432c37e9bcd7e9bad62a6b1cf4b6\nSHA3-512: 0d850be39cf0f3562d6d014932a059bc28c33e7f45e0cb3bd192bcded763cde34063bb35a858496f8a5b5f5edfc076248660004594a419a52dee728c3db99cbd\nSHAKE-128: 87dbff9eb43e65151be75a03c75e6777f0344515678cb4090cf45f747cc9d5d471dce7abb7777c344bc5e858975c49cd50097f3757037326434c025d1f71991474bc1f545fd18f02ba6cee1e2b93844a50449f1445b234a65097b1b578af4f1cab23d7219036d32650bdc59575539e786db7856149882676ce859e84826a49a04644b4d50810c147eb165a23d3247e50a64404870f943a7a09e04f2d3578709674edd0cb664817faab06773617e25c40d5b235206d4c0df034284388daf60b4de0971bc2dac65d7eb2e109212efcf524663839ce0b93d377273876433e0b6083781445bd0dc7c6ed3b7d2f4ed48993027a0ffa0232f21006d76b078ebe9db1824428fb52055806c0ab99dc46b4be6b9b7b1ca8430977bdc84a84567fc47d14a153e8319224fbcbaaeb5940572b910beb067d41f6649afb5eed9f32f70e11f3ac181ed1b814cbcac5e4dee7220546ad923df5f2eb4fe9929673231ae86465d0148b86963480ba34cde2e1c31e248f31417e1f7886f136ee422fed1ceaa588a8b2906956954e1ff8ad8a83de816d9578fa6838c5c9cbd4b33274c5a87f917f1dfc20879a7d8b883a1ce767934990ad40ca428f90738769e62616c8bc3ce0a28d38ed0fcd87964af8d2b004c738623eabc6204e13edcbb2a93740ad24f093f7026c80dc126e78b54e0c7e4fed955edfaadeb5e8744394dc99f8f64b3719e643750d\nSHAKE-256: 2a8ad41db153b2e8699685d82cce057f2d6c557a464ce76b8124c8137fdf886057bd39d8e4f9bef43a60060aae7d66de892b5a1d85a1a426349a66a12f6a1a13b71aee1881c2f0be302644a4624712c3ef7919ed93dd53b20d69e5eaebc6a46a4e34b27dc2f234470003b2542c4ae85173511005ddc444c4db971232e21876127df1fdeb2c102a1308f268800f4b3214ec582986a79d047bd1dff647a1d707593d803e92c231c38aed6baffcbede78df215413cbab9d294d3db6a80f174645efcfffc4f6c7c211c1d698a6f043f18010436ace0a9d13a580c40996f02bf3bd9a420e5187596fe676d9fb78d1c371ffe92686882247666297e1d52f2f1fc9cfb098aa3e29be3003dafb03a16d505a40f2cab5725107738986bd00b2709aa4d7164b9203dd65c2b7da0a6fa50941900a89e046099043a4f7a6b36fc865a4f51c6368925c90bcf4b0dc14dedd4a549794cd889a3ed96f2840fb6f8a7ffa34a8e097c8dc1de11a34efb7984d826332a1403d4f751b5122513f2a45313f336cf105aeed881b921e960dda136c6387afa3650285623e52ac29da124f1df0275b6da83b1c7f69cbc2c88d9a7ea5591ae9ae767c24ca0994dcf932e0a09e2064e713d7eeb9341c206a2c7a0ff0756629e637074adcda2d473a5572806a12a1f99a00b85ffac52d3c702e4779b2e54ea8dcf8441f421847f8bc10a8bd413afcbd018be000\n\nInput: 32332960ac977c40fd4cb279e27e87aef962907b44c227d2f7e794f699961acf44c0684c980eab060c9319d2b2e53629e0ee08acf195a6a6fab0b57367178afb7ec3bb4dd6d3f74f747f7455333723272123f46bf8d7267f5e84dd4938f23d8058e27fd8bda33ecce74272f6c40185b19b7e4e3d3792f6a1429ba55c686a8a919b6384ec0d92a27b75b9fcdec38c17541a1f55caa0d6259fdac8c1270a5f3d427c0ccb488163d4b0b275dd604e8559440337b027268c06c6fd5d764e7176bccfbefe08d5e3245022f389babb456e1f7882b60e26be4c777fc25e83cb99b452667b9beda8331524cd3910944be9b1d163f8f825abff6fba9179591254fb3eb32b53ff4da0c5c810669e67bc094d860595c853ad13a3fa9a072b8b9e347cff8fb6aa6adc45a293c4628a0533db02d5bbaecd2d917a09fd07127e83792495d59c3854e9b455377711966841f55f402331c3fe1c974989791f27bc28b3d64dcec9f7bec62b0d7540f195746fbd5facb9de28ba7612958f654ade3222334aeb9a3c48c7d7aec831dc8aaaa4387353475a8131969a8628444852d8\nSHA3-256: d7e8d71c6238cdc86022b0557cff83b5ead376078eab2ad8a49fea2662298ed8\nSHA3-512: 425cd15a11290fa0c991a1b68f65118b01596b3dcc72b23a92c9c5057f77a3d8bddfa50db0809a7a775217eb2ef84a25fca539dc3fa45c6fbdd515667aa9ef7a\nSHAKE-128: 54dd37fef98056417213cff89f4b09ccea479dc62ed564fb820adf4f27eaa54c7b3476295524321d97a1d2df61f88c6495ef5def5d51986b13ae79c2c87ffa37e365c955fb2077a7f0bf2e4cac4675e5decf6a4816b74c5ba7057e1aa3d19da2aa6f66dcd0d9a4ec4b30617f4c5bf24bd67cb0f47c535fa9623d829941bd3af4e1829a6aa54d04802776c73a8a563cf8c6046c144d12ae79b980e778dd4ba29c6ecd83f6451f2e321e9f28fe836342904733d542fc134821a34380756a980149aba1795490de7f546044c422f9ecb89722690ba7e35067b8ef2b0f7be86d3921e8b2d77af3d2d98eed5bb69f73b65cb68ed37d179dcd853f2238a3c35cc1edb94506cd128f5e5c3921e4856da4d2dd5e1645e3bb1143c46d342acc0524f404a112fa1a60a03489a52980eb846520411b7421f4706273cde9ef5a81bcd009ad736ab6b8f64a162c4cc6b4c8aeeb346a82bfd33991fb1e504a311f63cb514abffd8d9b6b6c4ae324830980ba09251357cb1f590e3341ef09a365e54fbc24e7014bdd22c6d7a72b7205a72c9c3e39ab4ee746c0bed97b2d35d24a093163d3dd23d94c3d5ce9db1ab039bc9e1ddc6e8d0292cfd0c1405b5f015ea6af8c514d175665627df4ab42e4ee09bdf5dab0e0f75f84accee99faa5c463e7d0a698c2c8253d4e0442c7e51011d0221cd905f42c122a513644564d8b24e74f0b0dac5d68a8cf4\nSHAKE-256: 44d047d50ed1ca7a78ae36e65d298d976cac0109355409a02bda73f2676c14769dbbb144ffb8a9ca71b27d36f92c2201b3bc46b5b346301072d314aa260ab4712564c4b18f07d190f2009cb685e07d5bc1019edd98c7324fb37b7001d85682dba601563cbedb44dec6aa56c266e8d9a3d94481e6f842dab82c3e0bf62fde577b462cc2bbe00b84f3a06ac38ac8593c293f49ed4dcbd08c195962a9c2b8437cc6bca326d0d74cf5871161f5bf9a2baa2ff40a8272d8851421c5d95ff00ed5b163ca56dbf484dbabbd005234db894621ba2f2698b86b6abe9271ed1745c877d0b9c4ab1d8b74536c6d4ed2a20011dba517c74021596594e45c689233403fc55260056649215635a65e3090a49912e14e191434afbab82b51081660b37378e5f2e9130098a2be19854eea7d8de6c2eeca9977dbf614fc80e6e99235697e2b4f1505480027b81f32dc530efd9af6856115c5b0be1d4190ad1e89b1bcd40cf6f7ea4dd3a32126a9fb6b740f7cbb96b2ab0f1cec3ec12e0f85effdc3987d3f378ee25ce084c7690e6826c4e27d83513aff4a0f0c5693ca83f702edc4cb12a93599505bee6624ecc4506a6b07ba481dd4557677fa57f155bd255a7b9c2f3552e17d4e081a27ddd3a7ab5f28a93daadde0f58d652bb986e7e02700fdbedb4478e5414458518c306011b8762c75ed7e1efa79dcafacca76b61a27236804fc9535e2e5ad80\n\nInput: 68c42229bbcf98149581222e8dbb0746c175c4642334938e85a46296585ddff2c42a1fcf7089498c1d909308fce58aeecccdc82cce95cd03001331bbecf2cfb6736ec39ecaad60e8075e525374e028cf2cb60e99c9fc3dca8ef09e9da84e060066815ad42c2d77e04bd090755acdc2b74d5e437be962af782920f5ea4db2ae2a56fd33fd77150d2550a24d45b69c0cc239f3e33ee32d2e580f31b6cf86929868e1f29d29c810a991f6f9d16eddc38c601a3f8355de7ddf39bfb94985e87f37534db", + "c9e6b135738b8693e27aa81571b1e8c120c62967efb1e92285e37914fbccb0e342ab7174666561a492fe51f8ecbf32108f8ef8963704cc9017b99456ff9b9039bb098f24e599c0957b3c704474dffd786b590d3c05d36a8eeff31bf8ce0a29420f6a23609b748477ade61acbd39f6986cf7e9315407551238cc6e22d100a30caf27a8be863f9a605ee43abefa1d85e002c4b6c8afc31615e188215d64e0dd3e262ea306ed818c8c5999cd8815cb460547f7d3f5bc7ca62715fe83a5b11cce7de5ef33401f94884b4da649fe150e6e3187f850fdbe47f01f\nSHA3-256: 0ea78c17b67afbe1ab8a2b9535464587838b1bf9915d4247a59fcb4716e89ec5\nSHA3-512: aee5e60abb9a7e2f333a9c671cb68c7fddb6a98760ab7b115cf63ba52365a5d73be0cbaba238050ae2492ef8c7cfd590928b10d719ffe33a0adf0ff89fb59e2a\nSHAKE-128: 6d97249295c33bec0997c97171e3231fa7719ce6ba1c45d692e0a3a8080f2df4d543392ead22f5d635e676b8ef67fc929500bc537573d557194ed230cab42399c8f88d445db223c7cc396e98ab948c8b854b201b61219376e8b1530b28a0bf4bce4f175fbe710c36f149ea1838f3e221b86c2be685c29ea88dbfa41320ddc2020daa2dd41201eca0efc63898df74a21f0dff80130e51188196950c770ad6a389042a88e6ef224baab14808764da421877a9337c3f5d674e89aadf6edc23743f7a1d9bbabd7e9bf2850aa54c842196b8766af14ea71cae7dde8a75131b0c70550c6eac8db33552afe8b918383621afa8c77fac3938889d762066e86049933240e44e61dfdf55e2c65468d54ff8ab73564d81512fe2ff3d17bdb8a2559e2bb21da45dcdeae988fa8f73431fd2cc77ef8ecca1152a3b69f9b49b3fd660fe7e15de89c443c983f19167fd01bdcce280faa992bfce496c1517aac5286b34f5e9b6374cbcfbdfbb9d2280ac03331d4938186d927d8255e59e55df50c2301fa42c8ad9c858b52f477d3c4ee3295c5ac136d873b2f5d3498c486e08268a9fd70cb9366647294831e3a7c74811be502ead64b968a967c15069a1531d90a1abcd5799b6d9fb0c7453920cebf6f93e9b998bf0e4ccacdd74ebda205fec03f50f35877b6c121b5d5440b17ed697f611d55978151bf61eda1210950e5ac96b8aa02cf2abc1c53\nSHAKE-256: 33e97ed04cbf7dd7ad46bfca996ee8fbda1fedf3d52af18b8c29cb717843e265f91410211a0436365b2fe094ea4e2876ecbe08079c5029383e85b6bf2d3ab014c504689df79afd827a6be92669635f3b18a8bcc32f31fd014840148c2f389e0cf571e6bc0da85e0cce8d5224ab433a54de9b78c5c682c5446e5077d6afd744804df78d42123fd8e4ee11b602b91fc8eaaeb2330d8b166ca43799526f8a2f9faee7eb37fa170ee3e567107d7635367a76a3227288b7f62186791d91a0f88a898de6123a98e73e0e0751a463eb042eecb5ac7fc4ed36fe3b4ddeaa81864197bf0251408bf6f5b7152c802687964d36f388474b6c4eeb302e38a64aaf45ae9d425d166f16e99d8e5a6f52926c499c78adb9bd206a33da301c9e71e76f0e617c1f37a473a4c5fa8875f2269b070957d160f886ada548b7fd9d7e13c72237f6065d39d9f92808cf39e320c9f493ce02f6cbe58c79c9c04c3d9ff89d06156f797ffe3d6312c901ebdbdb596c0afb7795caaab8c5a8af2008e48fa80799fca8a8374ec813e05ddb85dfb0342309b43d3cee673f64214b1005062fca8112e34d6650b1d84d8be2de72a2f6aae52f100bfa235bcb19754d5726909b0eea17e4dec05454f78181a6556c952979b7fbd06857c368b901f73d4e7cc629dc5d2e05dda4617d52bbdab3ea11af07f6c40c2d85d1d6d804477e3bdb2f2f28cacc75a10a7dc53381\n\nInput: c53297613290998ef167af4ce2c703397b13fa5222efa686da768268f2143f51b4bf0f7c58637749242641627a266458ad0a53ad7185ee2ac17e9c8a5dee4cf3c35376fcd9d41c41801384e631be727128a9b7b944424aa209f4356ccaee36537893135631b389d7b06af047bf13855b8c3fb94c15fd9d0ac759e578fde22e7d3486c51f2290252d5f624a1910a37c8ceae62fd6e833a9694af66abcb9a5c1caf153347fef720140e20905293a6faba3317d345bc73f17c790007ae373ef8098dd348564fb63d7bb4116d529f91a9f73befb0623c533721b9c56772a80bab10d197b45dd3ba9db1e207db7854fd95b711f6f150768ed9482ec070f706c5eb2a0a1b4c19a4a24a001dd741cfbd94e6c690cd66544f0ca81b67aebf677682f69534e47d4b4cd8fa1cfc7a33ac319a42dd853f76e2b3e2aafcf36eb41c54ba26532a8dbf20089503c81cf4a2125c6b16ad24aae0d8de4a5567bd4d233290b7ecd83d874105a35e2dcdab6d95c04dbf587c62cff9a6fcda531fe5ff021e55e9b6ea0f315120f0cb8e604dcdfe22a3e0939ea835c2d3a7f0378e14da5\nSHA3-256: 3988c97fc7ee15a8eeed62ba29f80a5cf9bc3ac1eaa0a2df6623f857bc405960\nSHA3-512: 30a2d6491ddd7ceceb51616c3a47bbbaa44bb86e249e65b864d0f84860e71377f5562a25488e96b3b1aa0615c6810f91ae1a439689555488f34b554a774542e3\nSHAKE-128: c16b9eeca6f28fc0ca38092774621f4765c6bf1062b4cc23dc37384f6e9cf62369f54bc729eada9844cb54701cb2e03d639c5e26774e541a434fd05578f8dff690129363b7011c8cc5349249e059c22c6e781b33420e03ca455a6530b5dff682a7e91ff0455cbde928750fa88fa2584a45a0006233367285423c0e1861df4381e67752aba12336712c823f3264d3ca928ea7b9e2e5fc7edb2f3d46b5b68affbcf4f4a14e292ef4179918d33481fdb3a972943b5541172bd50ea0895cf3470c6c4954a6fffc1370dce365e6c3427af3a01923be7a89c11a348a0512e287455598fe899b34cb7b2aa82558930c656ee2ce2e1265d0f7b7fbd6f79b1353f82d7b058335402f7c5b6f932aea6752cccf689991910379055741d237074f7882ffa991c9b5ac06550da118c839d79301a1c3037b2d9de8c5492a12bb5a6092e60b3e204c73ffb82c9499dd7b5e8397ca4f6e685811ef46de3647906bca388237d3c310c558ff4c3fed41e91c9642e307981dab26ce24b271e4352c6ba7968be1f6e65e19371bf67ad75b357b028cdc1589411733327ddf15cc33e9b2441fd37c341dc3c256545ffe62ab793151af45caf6c482c2f4aeed0efca3a27c4f8171f20b8bd8925db37c33245a471e285e4b741ac6d95a143becff081a249856a20dc51be008bb96388bedab5ed002b98c23195a343264b0b247da04a7025315d81dfed50b1e\nSHAKE-256: a8ce4ec902d789c79532f5ef1978803ac0117c3e4eca7586ff2b0ea83b53250487fd30c13301c631dae3c0583e2c8e8214180f27aaf1611d5eff0d3474ca2a119357b8cd7a983c6efe4d5568174a3ed9a39f297b68c991e25efa5016e105f9b33e073ba5a5414d5ac8d4d9c14a6faa84d43e5379de9cdfd86dab5a25ac1025c6898aeb8135611a19c78d3cffa3e0d55b689fcd3f66fb8e7066e8da8ca78d6de8b56139564524af229527960dee4264ff2228db594d40dd670d23476fe075904079b79205be6346d82a80b24708368de59ecae12381f7857bcf5019bf5eae34dc53a6067dd71219d7d15b089d84a69fdc50ab7ddba714b5d998af456d5f29af10b41f11261ca266f668fe5744a11f9603d48493fdf57430e440315f12b6c0c6c8eb9c4f38c19bd555053df2a44f38afc26fbace2e5870ef26da593be72f10129b3deb35025d2c7a91e88f81f59930c221199a9a33cebb68911f52fb1a3e665d54bc49fd91f09d57f6e4fe514656019823e35b6fdb3ec3fe20974e5587922775250f313dd71d7e53e3b59fedb2bb249de1d6c57b97c7271586f97755fe154c6236cb86cfa42b831bd60b10daa91faa13f7a1ce464d5efb2d48e2c5d6c494bce340d69abc82a44d52d80ac099dc72b71a7774161ac74671827a5d4b30abf411553d502bbc9c4b098c851a49cf8c00b0e429eb88bd6413720b766139743e3dc2a189\n\nInput: 6711ee7af398dc352a63f5b3c6294145fe61812a20e316ff516f5f20ba7e41c0abe38d941246fdb423160c34a6dd03491782b626d65236969a75a84337149c2c561eea967718f70d282c4d0a15c7730d4b5e9c5b15ed9b0c6f050489f1c163c4c87e6fe21f42a529e93250a7772ffac722e87aeeb0c541860703fd36abd376d838898689517c1cfed85feb3e37735a7ef27944801b77caed05c06b586d9e846c56b8c86758e1196acb0e86fa4f92eef797ab504b031eef29f7c40ba1a4f1d247a122964b9d86fa9706225c3c88aa81fe337b4d3c5493226b4d02ef15e399307ddf391332aac0d0da5e1b4109d03f06833ac09c6957c39f9a1516d9c1376ced36feab8b3561913ea4671006fedc676b186a926503bc183c7817c6a76616e85900516b5f2d518e56c03e22008b0df3ddf9092f0e6baa69aefd5c15747f29a42de0aed892f86e4d19293794c424b9b8ea73e8e1af6186e9a928fbfc61e7c8c3ba3a7ed37577ba1e834fbefaa605dc2783f73b0d2ecf9ba413688f5f60a660ef69b00a986c6421f8a4015cffc12d4ca50b810fb80c0c210cd719c19a6b\nSHA3-256: 1724f0eb5b4550ddab7009f91a3f95f686f2e849b64d0ca64485a91e00647dd4\nSHA3-512: 229476d2266f428b243810b3e54229e207f224d7b584d5999d166a2f5c65a09a8018b7d2a39ddab27ec44d19c0e05fb7077f72932d0984f905138ca615dc60f6\nSHAKE-128: 571a5546a84d0f34c8ae0f3a6babc56068ef0e0b3103f04d3a4b0dffe28925b71fb09b602d8b310ee9563cac5bcd7863392a5b8db7c1620937450e8d71bcbb59f8c86446ff26a48b505a6c7ea4749fc9e35ceafea833fca45ae94f661995669758a831c668979aeec71d4ca9200af675716058beb1b2fbcb6d157edd53bd2f9d90311ee9b5aa70390808f9b5fde991c07b21757464cf8736a2a547ccc1b54436f4729ebf4668f48b3edaad4a2cca8decca60fa22550e23a078bd385ae597e5f9639169ededf01cf695d67244181d39057f0d65071bdb64a7545b9b0f81eab779fff3ee33840aac6a07555175c8441e8f3f85672dc68e2fb8f6ffb634116737a83f7b895b2693f3bc3fc53755aab6baf8f0742e5240fde38b13be9852ac3311454523863d583f7fee11ee486caaae000330c85a8b944df2692bd935f12ef024605c9a187395a9bee971126f58a52cf833932158e9ba230d71f108de9aa93b84e4788d9933804868f38c69a5a307cc4bf0ce9191cf4c9b36115ff69a5125cfcb2824f0c26759ed63bef9b5772d00ac7b6c322e71e8cb1e9daae248c32b47630730238ec56343d09a2eeb41f4b89d27ac617218d9bd52d6d6c9cb4eb3e8de74a0c491fd6ed15399b917adbd5448707d66751cc2721c3b665c41d94bf5a9dbd454582fe9c2dac7e867c25a16580ead40077d4841023dc3e1437192da49b4b00042dc\nSHAKE-256: 93ef903e54fbca753813c9694f430c43cc2d8b9740bf1a634a0c8a7161debe4e1726a27ef5580beeeaf925a3244fb7b2fe819af741822f218ed568d6ce673f0acd11c9258c593f7a00d920e2457c8fe5d70e2eef5e8c7834877ac3d240a160b0e44b338961491d8991e40ca9e10c522b5d64f02c4365dd1719ed801498610e99b2b4dd9e6de", + "c092204bd8bb32cc17617858f4881125e5da68cccd3f6e41ed45a7cf4300d3db773458b1e3c5d9438d9b36c29a7f658995468dbf898a38fa1f6d6dff973571617d5ddd6c29e5734712c0c15656db1215f59f083a7bbda54e13fe497d9dac8f3cec86494a8449180edc7d86795a3ee78d91962b493c516e79e67cfb80a6ee9e925b918e0dc4b7a7b1df10989ca9e6dea67a058b6452ffdc90ffae85df1b42a94898016a6463cdae58691252cf4a88184f2a10e809c72da5118ee7c154a70ae1db2d035decd5e86cbd31ca7ae810fa788f7646167e1def5e07a6d3def1f84a8320106dcebf530905ea10b760e4073b08f41a316b5eb1446e0b11a26124ccd3b3dee0bb3c242280a1a4a7565bd1411fb6113b7cc53adde6752bcf54b4cc599e4b1a5b2eff6b0978cd32b1dc080ecca63a33ca62972c164afc8ed8f99f0083809059d2533914c6cb5fe19267e43a61d57caf0b30d2b35e88f75d0b9a7023ac10272e5b47fff37ec26ba4590a77640c4cc73335bb3825395abe9503a12\n\nInput: f31eeb779c2e04d9066406bb29b5758a1b83b37dbbb3ef41b4f258156c10712dcc62ded7209d9a67146ffe54f0683c40a734298b826b9cba047b10233a5ace48943303e06cd844b2eae22003a7dce8219d94ad43a647c4b4718a1b6853c295da10447eb72969c356b90a2acfa8de5f2481bf30b1836facd2d42a90cbb1e0d6daafb2f57b7381d8ce162cf671bb7814f074657e6743257e5d1e79958a2c5b595cb6eadb824465388da3438f0853a0821cf09604fc9d1b06d5f74883743a1340e62fe211eb6df59ffdf79769ab296e815012004cd2e48c6f6cdcbafef07afd178efda2e92041346b94cd12d7c8c399c2ced624a24ada583966e023448d1cbf455a236893f6ec20003c617b461315184c7f3d9146d62143178fa96c7f43ab94ff31a1f7f23123be65358296893cbdadd55520cc3568a7166b100985ad81c78e76e0cfe66593dd43cedc4fcf023b1072b0e187ad465f58afd179bd9eb846f0f63c0e90f4eec574aa9b37f952f6b8b7d8cb883c9addffdfe45dc608bee71125be8ff2869a5d66c2f060c3e1c6134d407b21409d8def871b4b42db9537e13d\nSHA3-256: f0b3b09fc6d8ea4560098af7e4f3c707aedafc19285f92e1e4a2597355161337\nSHA3-512: c04a2969decf073a1509347dbbd457958cda16a2fff67a9b0d97169f95a4ee8a4471a5f45a8921a95093ab31155668058b450ba9b219c88c711abbd039f9f11f\nSHAKE-128: 279ac45ac06a34d2ab754760e71d96b1da5db5b575a778f13e4c1b84c7582062bef51b3e0e6ee3512ee3636f8c6f19ad0d425f28fe8a7c3eca61c13edbeddd115065ea85cbc9fb430fa261f8ac5b258e3c033389ec649a5e3eaee776fba0f0f08812cf6142eec8935f43484eea8e7c39b833bc927e43ca1552168121dbe187ee8de6fcec95dc6b28fc7ed341787b819d09b94d9821825f72dd5285bc69e32f2c82fb84cb9464c459f0841d443de66a0b7373adb037c550aad875fdf1d2be18797c53dac18127c95b21e423526b0868d4520139ffbc88a7cd1a4d337fe44395f1f015a13fbf7c5f6950e46ff9c7ae98883a7b17a7ee7cca934157e6135a632238ca61d5c09e973d5987028af876bd0773e6dd3e7131fd26b3d4537d6d2ef7d79ce165d308fa6a8866a0e24a113bd0fa27a633f07dd10217427f55491feeb8e0faaa208be4d4bd4543c905507b6d2dd9e00452a82f491b476ed7d6057f5d93f4fb0395e598cae8920cbcb23e4adf40dccccfa971ff54dc794f70efd6f307e6e409136d08b8ad063bdd22c7186a011806fe1b2821f8ec83803b9f6b823ffa49ae4c0634bb500ebd8dbfe9dfacd265b9baa531c68fa1cf2e6cb7f6c096cfd97e675f5f51615338c44c5019520104729e56efb56e64c61b8aadb671d7efa72da288a8406cd5904c1c831144d5c8035d48ddbdfae84da9489487de3ed7283ea86a563a\nSHAKE-256: 6fa458b61a50ac9a3151b8f3910dd719372ab02b8821f2706b0fe94a78af744d0942cf2ba7fe1b581249407ac755bc474b331ab241d1e9aca565fe6da3dfceb8e0866a70c0410f5e0c4193375aaaa53a05c9316cd573c6682a2138f4c9fec4912a2479549cab015b2a80ccdffe8207715af239759c37fc6a60809f77076252ed03b0719a7ca1b8b77fffc2bbfe5b0787f2fed45481e3b43b6ac29460d8699bbe1cd5d339f995b9b24c0203c10c55ebd94e8a15bf5e264a6759096f089a1ae7fbc3a6fdb76a2093b2c0cfba50b729414d49e6f82de4b3091b8bbd63ae10e5dfe419bc187455e0e16094bf3e3d0342db3a42deb0e23d37a7ac165edc9a70ca1cbd26ef002dce86495e91249dce436eb3f4bdeb098324a081ff2d6d4d7839a72ce8100a1d070bacb07f244955db010cd7859ded35220b9a409d689709b1aeb47bec01aa2e2bd48ee531560ed257d43c504d76564cec1eaff3b4db3692518dc9be8091d8d09f63cb08e1ee1d45f9f3962467fd1ef2692b7c907e706309b7722bd15fe5452c61ee9eb5037a29f8f39e058d2cb5e1bb198305838db79f43d1fe61ebbba3e132a32edc00262fb7bac58b23ec985c4266cd1ba24ada0b0bc70b9d10413e2ad46343faf71675d2c0a3414282292ba8c6fa0be4ea8f47b3ac2cf2e5580ab8473ab46feb2dfff994bf256374a169599585565f1bcc93a6db3d70bcbf81dfb1\n\nInput: 6bad07e5691286a34c97c05406f328a0973c3fd40ad1304542ffcb1d08913974982bf0c0b885dc29c59c2b05d8aad112cccdcd9743db2cbf4266794dc609167f5b53b5abb39093467f8e2496ee1cc4b80b861a98276646aae80f7112ec4e4aeaa5d5ffae7a250091f703f0eaf3db9e26ab9f870009471680ea341daa5b0aa34f4746003a56504f7e3e7d61efcad17cc37e74ee09406ec55639530738f9870ef8cf2f8203ab416658ed5a3a46f10aab3a376e529d755fb70c60c1fd90f0e8918499624715520f3f136b4eda78e976c1a62f5dda7374d1d74f7008086f51413539ca41f25be42ea6f79cd230e72f5e60f2680be0a877fe35312d84c70063885c4e7490b173c595b41ea6d1ec17db0a444d78d3640d591796d7f171250a7a030a6c3bf67b4e9b08c3e2413938a66f2befa04068b752cb5ef050b1e98735d1a51257e7a0c58199502c3e445f96075944457eb7754710b9ec6a5ff2d82836e65e5a73a245da58cba09714959107cdb278b48ae467da762c09de12cfd70d40439e1601be318f4e67644cff8695edb64eca73be3e3420e170f3df5e2a8216f209\nSHA3-256: bedbb5b67337d5991c73efafb9c8f8993fc3c62766e9beeaaa00864d699826c4\nSHA3-512: c8e644c52aabe55bf86c396aefd32c79abb0bc0634969bbc148d0b32cb834d873cfb1a07d98229f9b582642f1ad28bcc9d345967273f6d6c213d96ac2c7f0515\nSHAKE-128: d614d1497c4ec81a5f759b62447ba59de7f69fc92de4d897a1f20fb3051975442e711ee6733c2e20e8507be76d113ed5af57a8f336be9d7fb85acb474c25b40688004c4954277e7440db45400b6a73843fa6335c522be4968547c821a3191fcfa93201d26dd349bfb54c26fe6e46b6adc16d30100cf37dbbd76b4dec04e63f8f00e35da8d80fd59442b17e740e76de5964eec244cc871d6a275aedeeaa34368c437ee1d9f2e5de7220bbf13c1c28e65772e9801d7586e0d891b6ca62179ea16f8d454efade89dfa6e4ae42c84f592380034eb6287e57817384bae7133925a99f37d8e0db693998a34861cb96483bec4b6a78f2e7dc3191ece7dea24c2b6ee78a75665c2acc76433a231d0458c49415b1e065fb8a6eb0a989a2fe23c2ea9f571681d322840592d2e10a0cf1a832eb0914108c7aabed8e0b6dfea22bc9398f5087fee6eb49e4b78b24a9beabb4d9c8cb23bbfb617f1ed3b3df6e698095138c735b127922d4a5d6d01c7180bf03fd72e7590df65ec2018a16d6a95dfbc5084dc26d39ab979a75ec7260064d025b9d38e216147210fce4cc3205bb5bf5aa3a61aef9e8a3e49093dd09e16639b4c1e72a5d4962a8e3f6a8fbed675bf866a60beeee1c2bdecf831bae515568549d4c3592316bcb87d704071dd25f8904f4a84805ea82514c88691176dcae96157f492386aeabdcaaf865cebcd5c155aad0fdc364e2ad\nSHAKE-256: d565b339c8d24f416eb905a77a2721bdbb7934c73f94f727208cb5dff34d24c1f0797fa15523c18040e586e9315ec04f531a1ccf9690b5231406742f0792273013f1f161f98b1462fea06c3d8c7b478bcef749673848904fcd9854d04e830096675543d83dafa0502ea1db1c77e2a26f6e83b2d272f9413a1e5b95b0050c42b4d95f871d673fa761e4bee369244a97e0c4b4721f1bd2e2def0f8c01cdd4765599ce14bffd45e99c03dd5c5ff506d25246b252b5a780f7845f12c2e74cb86bd008a01cf5ead6c8ee8d58e7c2265eaa7656016b4429f773c3117b06f934fe3cf65f8f65d92ae7e5adc5182124d93fe910e2478c499ae10a5fd11b3c15e14e487fe9ca333cf6624b766e95f5e0ec55b8330177bcd73ca3e497ff6dd4fecadf20ebd9bbe234bdf8c8ec353af2c2b00802d712515ea466fda06d6863e251b22f49b0c47fb17b04f49936da1ed00b6bf5b55d294058080d9b9c2dd918f960290d883163aad71e2f597272bf05cfe127ec695f4b5652c68296a97f9d903c69364c38f27dcabd5bdec15a42e368a87304f1c952d75edee9973afe9ec1c227d9fd76c50242947be5f42261734fb449f9f1c5598698a8142e4a36333304dae7c8da6afe9e85255c6811523557854b4106d67a69e888cecf3a5231ff41d30d429084d7019eac4f94a90e6a55aa67b3f97fb4e3d0d4aa7928745c00d9d5f801c99e2f717a631\n\nInput: 039a364b092ce5c609fe0fccfb0e299c777146fae04ace31b88c8751bfa80467fe77e44258f1a688f193b172bd9a68e28076e1ce57c62646149ff98f1bcf96d5355621037bd8524e4411ab8f4465b0324af81e04a8801f1cade7c9ad30cfbcbfd386e1ee01937445807725e55fc152683d1c93860050883495c6b22dd651a2b8ec16fb91d64aec69a5db8f2e94ac25e01492c3a1f66d156534a9d021f2d8c5428e9f54974414c0043a0cc3639d75101dca40ed4313634f3add07cc159bac217454e2370b228abb5a71013533324410341e617f48e48d3a27b611e7a4e50a2eb96206af273e3b75c64228b9b78c6062bd5022ff766e101d95d27facb81a39fd8e5b06290331bcd008407633c7b8153b7f6b313715826d0866452c777d9d629de29c0017e8b286d81ff092a09b0ef29fb01348e092f27330c5990c329e1d9f410a0c60088c3819eb24e2b66f98d79c0a46b36d86532f9ef18e358841fafd6048ff8ec96ea75dfdb10b790296061bac6d44c4e9234e6178321a704ffa0823d5ceaad3be08b50fa355d9f241c6060079705d2ac8c9c93f07e74ac2d3d810c3a9\nSHA3-256: a62dd10a971d1622d7d0201ff0b4814ca996f169b1b24a5f6f28a3763d2d4aa2\nSHA3-512: d1714bb1ce7efdeedfe215e3f44481ed2a58655d89d1c227b74c652ed48effdc338f6a2693ce60b4d8ebf6470d27b60cb633502dee784b3faa2d37f168d911ea\nSHAKE-128: 9d58334addf61a8921a3ba567edbaed6668f2db1d48121aff85165d63456ce66593779dc529923d7e8aca6e6273cd252e67e32f7eedf879111544ee6f3ac247f2df7", + "c6fc25383ce0b91817432b0036b06bd66e77bf7c33d9b331745ac5a413c4ef675b97d261d9db69f106ec087239a54ab310b28a69d74af57b86314c3659fac12ff02ab4a976964368f5c4c5fa8370fe7666cacfdff280869536057f7d806279ea5ce142820f1ad1a0c5dccc3f0503f0262f29c5124feb8c6d183965c2ccb8657ac66bd7469293d8984c452e2026b389665b607f1d18de7467fe5be7932ccae7160c894e48cc5fa4285dc1f6c298f7afc7dd28564e7823d0117d84641159671694c9a290084e56399976c8373d4970ee9da6f1eeddb35f5394bd9a7584ea9c9abf78630b41166af358b67ecafe02af14126ad866a16fbd1194929e6847a074c8435ec976b91f483f11a273fd81e437ea5c1eed3eddc3a24720c91689296af78b14cc5424a234c0db9f20bc2dcb82b70e699ac8e057761702eca61bbe9ff67b137cf6bef7ff7dbacc5f61fd5e21a0d0d19b9e333a9b7ba39dd9306842c5c9c91dfabde8c32ae9a520578c7fe144b77a45cbcd9d49adb855bebb7fb01f250a0e9f904ff948838fa3cdc1dda5258ac994b3f7cc546b1f33c416dbf0d9c310924a5cd44668183c373a47897fdb49b899167bf04ada7033ad36faa675ea64267cdb\nSHAKE-256: 64048987391f68e1402b5c9cc1ff7199f00fbca1b364fb552d1ea132ff8939033994e39eb053a09f9bbbf1fe7f5b5e27df55854b5a4dff204bbdc0d540c8380c2b229bf051991e025839de3f747d49f78153ca95dee6e94468c1199ba902cdf5b2dd2524508663a9a4b74fd0e10b9464f19b1d7491231c0dc63629b23a7ca6ad131ee098c7048e2b9d2b51427696d7c6727c54dd57e2d999fba587a7eac79e0e5b4577d5d9d36af98da0312f46be08145d704ddee75ce923e21f179956c7a577b75a61556e11eac6c02d3cb97fb37b1e3b51f465474d24d1b9a66c5e6cbaf0cdf597bb2ea6966533f5091d8280f3d84849cfa58b8fc40a6b9e7c047f89bfe8f0c65b37f12e3605b09401f4367700e66d6cfc83006dbc6cd7da4493d1a46cb821fb88d397050714b79a0f6f785b2ff91da9fbf2b7a76ddfc290a5eb4f9066b9dd0b7ef3362fc7c243ea0b34901b0fdb86dd947ed421ce2231521f17436a9f278850cc3f8c001238dec6613674c078236cdaaf204ca79dd965d59fb60c7032a415957563cc91dbe20db150ce936755d7d0b1d1dbb9c63ffbaf60e2223ab3b6d33917e551aac6184ce9fa720ba0e08f7e481248453fd218593aad0c9d3e9dcd30ed8fae3509b2c65fd617300ed3b78565d860989abde9858ee3413139f5dfd22f9d8e1f914c1fd8bb1981f3554343650f101f6bf4ddb8d0a08b9b4189fbe37c065f\n\nInput: 0d1f2dd3b88b91f69af010ac33b8e7749a7cc92c1e5c2191867a90ced8f1721eb968ce3c46018fdc070b822b366ce4baf6ff559359fdea062e12913afdb5778ad945e307e12da0e4d9e01aa585970452732e7db315b185da83707d51108e35faa10ba7a16e2fd0d27e52bce42d134cbc1385f3976ddf2e66f5849c9a8e7640468f46b48dec7ceb53d19abab2682d01795c64517b369a0e6c32ad800bc96cf47c8246bd09ed88feca2e19990d671abb640d02c233e5a7e17a03bf5733c19deccb34fd96a48042d124af1260edfe4da2e6f335cd220022b9d815ddcd63f51de77218eb794a2c1fe620331cc89ef2e57a98ba7f01b4affdbab762f6ce29b617b518e8ce187bd30324993e2a8cd5d50af572f58052e3eccd8a70d84e6b44f73f7b32a69d164d6755acda600cf0e5a7ea2caf8eb364c6ead615a0bb65320ba26ed1f6cc7df9e296fd703fe8c85b6d273fffdd583aebafa5aead47573af5d3d8a50a4ca24dedb8f38317af4aedd63b4c7a4fb2cd71bbf479408ff46cb54f7843e1e820da9418f29c62861d6965440233c8d014f8ac690a2e49784c6037e284e2ae12\nSHA3-256: 5d8c1023b3bb0536be62e334d9e0787bd4acef8bd629d0c1cde2db71df0ff3b9\nSHA3-512: ba3a06c4b754b7065e68b369cc558d5c94929e5076269bd9cee3d7fb41603bd093d8f38571c7a753c8dbead75670b56e3a728dbe3c050ed58225c5e5917f20cd\nSHAKE-128: 02639386680ca2dd24a295130e02911f5f4d4010f0f7e85e02d40fabb402156c6f69c7840c76f5bf7be6e6fc9ee2834f8fb8565e375b52c101571ddf765aae99bc3c73cde175bcd2905a9b1010032fe847cdc2b7b405bbb5724a600d92b35f2f78ee1c22a7b5a795f4c10335767ea79f0a2617684af3a7ecba4a0690798e4a41568ff6031c06fe75aea6e4ca792fe1e06d8fa158ae7d3f7da5281f8c09b3257aba529961f569273b1d3f00d694bb8adccb3f3d7fa8cecc8d07f743f89770e00fb730a93eb7b428ead5f4116f4dc88a69d21bc06a2a08cd4a08974bffcd5714005bfe1373eb02454687be7bf88030cab462650163f112f6b4b33ea14dfd8cd3975a19d7312d497c48076a6304ba167d44b70e3cb62a7a0bafc66e25338f56b5d574941fbf488916d7441a3947b94362f0906899a8f8fa896088df91519991f5ff7940d02dcce2c223e8929e2fd767d56384d58de03cb7d3d3d4c540b63071189618b98f330b2c7293c0a0f9c6ea1a06c8bf9d9a6fde75f7946e9e17d72c5779519e18e2df3aba20cb7fd403bd6aa5a21d07430ed6df3c82d8501da548846dbfaaa5a2d4f309da62ec22490a1678f283b50f37ec309d4fc69e8d9f3ddf7cdc0f4fa895118c775effdc6fb958648475eb6c9024250f7cdace5516733c1e2d34f70a9b26c1e6ddec01708a29f27743f015722108a1f3719639a6de6feb3646147ee1\nSHAKE-256: 4ce1d4304be042443ca67feb700e4bd8b7413f4a1e3183c56f4553714ba9b095e403f741596bdeb0bb0e1de0fb5014cad9c0fbd7816cac6e1e7435465d5e5f49f7a25bd1e7e7fa8869622aec233e85d6a93fef721976f1c4138a1c023464d6db9cbe714658a3bfa0c62c6a858775bd9c444af4269a71612f53f73b551ed1cc0705938a8d925b2fd3d1c1343ec16c0a60a0fdb31d5e56592be5aadd03f2a01df036e443c2e04fb8c54534f1237dcebbc90f76f9af11b24db7b957abbe9b5e8c82f3a59c38845ed1a88b2e58e74485ba3e2cf6ddc104501798d5e6f2bdcd5dc582a18adb81b737f502645d85e90b2b4811616dbc49b175a3cc84b03966e8fcbcc3e2e68a3d16c6d8f1ed725a977ec1ed60f05bcdef007301b3673687a686e28da4a4baaeda3fbcf4f822e7d9001ebc1f92efd8cc65bb8d93f3fdbd596394eb6513093a81216da249b8c86c4f91bf118176f13bed383b5f775b7bcdbadd61d0cbff284848a85901ff1f81e9b9f49d0c14cfc63337778a1dc1a2d72dd1572acd441ac8816abc6de6138adea4e37b70584b1418a25a90b3e98ca354ba525857f7a63081cd3a2e84044ede0b3e7c9978e0493afe372959f694d94aaf95eaa33a33dbca5e3aed81001ac04fe6a6d2347523ab8944cd85495782a96d670e76aea121cf941ddb5dcd58341ef9551241c274a2432773e301000096c0d285f341cffbd32a2f\n\nInput: aca91804ffb5e632751397c297bf629503da0113cbc2c2c21d1b206e4ba2b8c58531253c89e33993387f81d43476ec850322b49ed85d4fdaa683dcea0d19aa0d00f56ed126689828738fa125ef8634e37272d657c82c3dc0da8b7c2e423e9024561b0757a7cd310fb0c9bedc2ac79375950033ab9afc8a003194a1875f3369a83305c6ce13626faf7f6d0caec2327a5475b46ddadeab98bfbb33105d38e63dd487c191bfa94b228f6ed8fd074b958a11455c75439e370b51ffdee328a3efdf103d999d604a974317a2b10b69c2485877931d04e0869488b128ce33d52f091926bfc7c89edb56349eb17b029952505bacb331c800f773fb001244379643f073d91d28ed861a5fab461835bc1ac0f655be509a49a305969ca477137ac1274d519c6e15ac9d53ad4545c27c11876082d6550abd417f71cb68d92e0b0857fc451b5fb619ba0b44c0222d4e2b829de6a6fdabc0c2fc44bc624b2ffad83ec3c889a037bf9d78a35f02d0d764f0de212ab1554a343cc725444736e839fe2864479044ae0c9c69f3f488dd2ab7c8b4733d3967856410b49e1e9a3e851e29b4e3fe857f56\nSHA3-256: 1c2f5a4ae08d3330af63c8b2c59284f555bda28df434d9f704b01d4cc53aa18e\nSHA3-512: 7ccf3c62fa32ddf18092835aa6b19835755a655244208bf6378a644b114fe957d658661c4f7faf2bb805e9c7e8907581e625a7347548c821f4a16262d3e7189e\nSHAKE-128: 81393ea475aafcacc9ab2143d9af3315bb0aa878ae651af268f6dfe9120cbf666bef635a32fa4d766861e4ae603fb0b431ea4a3def9313615cde9bc9b81e525eb009ae4f6bfdd2cb4abac7d4ac274eafce1309caffce625172c3624d1085121ea28813be51fb74107b0c17172c332316823d298d3a733c8a3f9a1a4cb7c5f8fe1272a0a0fdf6b4677708488d94cde7d8900336877c79ef427160acde082c30bb76fc6ba4dbfbf5dff9e705b0f17563f7ff20cb7ae220f1f2596c4ec14eb2470891d4efd6ab94a301d7b701726740562df43fc3890bda88169bc4e0a9a1df93c6e6b06a455e6e6142078a2fc116d005340977c124eea6425838d3c03b2dd750a9be2b9eadce477362ec84be98d058c8ee140b6d4e927c9eadc08ca920e363e3678145b08a6d379c7bc6c5751f9a0e1d7ab5adba7807597d0baa20d18c87fad29fcfa3d238e7b41cc45df68a5fadc0c14a6953c4390a61c00ab0d59084e00f1a766ad42033c24ac11edbf891a488cbd5edbdd03a3eaf1abb2662018dea84a621587ec1f5738a159199f6625999dcca685340d306b92be682ee3f40ff4a893955a84c6774f6bf62072886664d4afa9883f4e0d76a6e7acf1c752749cd918383e9bea87a90afe3211f34f1b7b00c3114d83d0717898d333caa02c5b07528a97937a1801c34825da9a78c62f88e89617a00b95cd5c7260ff981a3cff762e2b74a4a5e\nSHAKE-256: 8e4fdca33b1c7eaeaa3e503addae4bb150ee8518a9aca3b95887d984a7f9cbf746f96c55cbf9530c962f9e795bb19c9ed574d6a6645fa1ed082c55a833f95d9215bf97102736175ce68eaba6d73528c2969be977e73d7f0440b1e7e357d04797e7ceec0b681b1fb6d36e72f851809857f142dbc09f3638025ea3d8ebd27fa4e4a0e19858fafec28333a73cef0bd75ccc8cef39c064925717a13672f4e252f5d3e23153544354d9dbea3447c8f8cf33890b44d1bb791e0e3f9349bc886a2bdf64ef49b5b5d7f62074cd81499331600f280e6d78ff8a293cfacd3a582e777aedc7f58fe0d4eb40dd126c7ac578fd4364796f33288ff3a725ea969c18db0fef752f6f09d61bd5bc94843e9df898d25b3e30cb2cf12668752106882c4b2e14bbb4ce1b57c5e048079983d07b918f0d7ea15811cbafa31bd003899ddddbb89c30b54f118053901fbe9c248aacbb9b4260f3e6df9d065cb7aa15c41bf69097429f8644b01dc890ed935d7fd44eaac9feb879e8755c657c84acfd2680798c78c60e24fb62e9a87fc264d52876edb748dbcfb034e9e78dc8429e234d2b141ca3e31abde1838ea2a36a608e67caf5847f043f753b3625b8b0004f47d792d07a7f03a555b740cf3bb5302d3021c5ca3845ab74d0c3ec6a7412e81e7ab0fa4150b5c04300480f92654b2a0bdff673b46752b108c73ecc6868299b879bacbc39d39e50bc1b68\n\nInput: ac7", + "79185cacddc70d7471ea7f4170171cdbaeb3e1d29d1b7c8fdbd7e78394a3d4dfdc02183a8b309cf32e307ec1505ff7ee8d5657eb86348ce118638d3a9acd91fc26c6f790bd283e652a131f97df6419274c7076ab7a35e467bbe5914ca6fda67d217c2aae68308015d9dfe91547a4fd87c1f20a90e2f13246160dc658fd37e69fc3a17c84d0d1733f8541f05b017ea12a4919a5102773c47eebf9ae60a9022b0c0edb92cdfe1f4147a703c53434c399d4d34b0e05ccd0641d6c9c4bd04c3010524c829f5333e0da3470f78fa831021749572e3597a31034a018c18842c662a81d3a5dfa10b632171f2a672df2964da7985c2173cfb70375a3b4213157f2ea5bb26f2f9c4af9376fbd8dd18049e2c06422c774078260188b39db7057e3e695887a3e2b6a173395fc1470ff9a3830a1b48868921853544c6e412b29810e375d4078f77955fc1144e1edca7bfd66dbaf1ad12a6de25b87331bbafecf8274b5d577adedce96472ddd02441ab3d24e139517db3b43d14785d5e5c033f964c0551e3e915f3529379b4f739e640a667a3c65337d483434c5f959b2c282595e8ac3e2d6d\nSHA3-256: f2fdc56a3580e7c38625ef220d7a52883796764d75b1a114df9ffa16ccef7ab4\nSHA3-512: 6a83da096c828b943f0545676e5c8fcee3abccec5fcd2c1db96a7a4ba65ea049a288f4d2610e34e018bae9294e62175701c17919aaa8f0108cbbe587a61c75bd\nSHAKE-128: c7e42cbcdb8b8520fe4eaa878f2dea695c3fa5148304a93f8bd1decc7d3458aa4c0d346fbb87277362566a1761a64cf7942d94f0d5c8a7577ce44eb7db364cbb0a52add20ff7de71051bfeb0c21097db4454d5678adbe9378c78413a70307217f7517eb43482ae758a5d76c9016993a72d1c4aa5887d1bfc6c3ed05e50db5919512022fad0acb74c2aec16a56b47e6d79995afb8ee77b1236649f023fa3ac19bd55382aa36d131dba9054bbfb5ea9bc86d03c4c37193b9aded95ec06f9ccdab9431f1d1768228edce655c5b79bc71bdde39ef1cc8d63dba44c7eb132ee5cd2cd26e8df751e400e42165983f8ece7e45a44640947c13fd55631292a39f7dc88caf822ea71918ff7886d3286572aa38be92844ba70d5dd9d6a005a0a1c19ccfe885b636f12ae2bd62b914d3c46bb092d8f8495dba085248a83e461fdc2a5cc92939e221ce54724ce19fdf4856010c97341a18440cfa6db25dc6661ecc624c20fe6c368c0f49e5763f095ff7b1bba2ef032e3c92943d39fc32fe1ab786273ab8c90f2d22eb6757e5a472ce43e96cfbebd880aec4d33a52308beb0396c8435a6466cf35796f7419e47460f84937f344dd22f49041a4ae9e026052b1a7b9e32356aefd746847ae47c600667cb59b74c1ddd38385340a5cd44aa53ca1930ec70d0263b0dd90632c3dce4a994a3b56fb4f89b0b8fbd61f27ba49d0ebbd67ecbfa28fbbb\nSHAKE-256: 7e75746cca99fff240baf2703c63212f2596bdeea6df3a05ecf5d5cd6a012dc6fdb52f76e2149b83bc9637383740e692d664ac6389d97f5098b94b70409625d3d8e84e9672070ce6f170fe25af2c6366eee75b49c27ed2f92bce3e7e6881da793cdfe31db232d94cb9936a455fb5714854b570f7bac86bd670490c3ba5f304efa71e276a876a8ab96ab926bf792ede9139e53d7e4e0742941fe3fb919f9730c38ea88947b18d761a8f7eab48a7f205c2143206f52109552cd47606df20c12a14a1dbd8fcf31207066055feb25080e8c66c17dcb952d8e7440c7c2afe63c7aa19ebac1075ee5b2ea87b5ad2cda204998390db7d78aef74ec02a6fbddf5bf240bd01923f8602e5792ac57b691363aac95a886147086a7a231395f8eb4ca575638dc4304e3653f8e237e4ce57a72513c877fbf361488b09452058ff92c17c007fc41dfb50b6b6d6ebd2e24db6fd94bcc318d3fdb051a49ab9703184d2977eb77448450918a4bf5260046dd28ea6694255954d7efc84ec05ae1cbaeecd71e158ef6856b631c1b7ed779b7d36db8b50094ef5a3041ed23c13b9f56537135dea7a1a0a8e6ea30139b0badbcd4116fecddcca54de5744c8fc24042f79a3b88c576a1d4562fcd8e1642f181d74483ec2cd0efdd0165a1ddb46436d5a1a9658457ae47207647aa24de5a23a50e7423473ee0e1aa9c4325af9e8590fa9200ce3258a8ca3e3\n\nInput: 0b91d48b6c7c659c54aaa1ad689ac3638019d5d02eca22f3c26a077f7e9dd5aee23dadf0a8ce0db1cc488b4ed2e5e8d40adb3620f8a1c367bf489536bd906c68084828a44a87b8c893e8b08d6e1d1cf6de9809084be87401c1d3407595c60cf9c0e6083bf2af180c9ddaba7220866cfa49f604a3eabb53072382f3fefb234f0fb554cdb8320f7b0425449705e16d2f0cd231db2494458b21e86e0b1dc409067744d328017c821cabe47f4550201f76bc8a7d1b52c3cde48a81dd045c0f78821b1468e46149b2c212b7ed0f356188a9494ab0a230daafb86b01916b667653553493a54d41a132281223838dbd3ba4df99a9ebbb013fd41309c8ea05797153d6eeb5cccf6ecd0dc54a1f2c5b7114ef6b9813326bc141a6dd8a119723f3298dac104db5184665e1b59eca01d1e32898566fd7e1dc2042b0b827d7f3737dd7b141d88b8d54cb53755f87f09e0a7fb3f8977c10bfc961b5f6285e5375ad1e46d3b7c93265c10795a3cf6fc0a503c042b2e084a85be1031f1161f0e975dddb2fd56f5ece1ebdb84b83edf6120dc3ad93d0d4979fc275fa40dfcb3e1900e4b770d1d8b82f07\nSHA3-256: deb888acae19d49c07813c91349b64ab0d5e497993734149bb9407e075ed38bc\nSHA3-512: 715ff279185a66adcd81f2ae5f80373926806528f030dd289d6c012601dab62dc15deb6e34ebf2f0677badff8d24c820b0b798236b1a9cdc8c2246c74f9f6fb1\nSHAKE-128: f10c539e4328b7653ff8d143b41d067e802e7316eaac2980cc4b1075c58b0b919655edbaafe7d6eb71a8e8373b4d3e87b43a965830f8830f238ea3ac9e8facfb8c367c588f96519e9023a74301a16f36d9c740695949f816c0d925722dfc86f1aaae0727e1cab835e68c0a79fe83f2413e854e3f3f039e348fdf4ebc73a1a4b06dec1ea3f9a3295f7a2b2bed410ee657df076708182db3d03e856e180c1cc49afee2d1ac9c709d5eb0e770bf88db3f9c7e087b9fd2d7b0850c46e3bd57cd93197f2bd924063179d4f410c270eac979ad7f0f22601ff78e38223bb73f83111fb92708e28296252c90c6a2853e3c5300eefe8dee84feca04890f208e1bee306f9f7067f1d8a5de753b0d734d165c1ef41ec1e08df20f360a4de3d2069d656aaa4b9e76cbdb2eda0b757b4795d94ef2a686a34cfdb691400e3e5b6572069a4554ad28b810f6e7ce5b3d8ee3c43297027e5306ece40ed51707595ba743b3fdcfd0a0b8eabfcd7708c7fc863d6ba9b8d4e77d8044d32311bca388c2b3203e8c7f822740e257056c01501c982d0ecc6cfb70bcaf2751c1f5c73c6a676de7dbfcbf2b53ad66c4ec3fb349d63c70703ec346e6aca12ac8f82ddbcb83d787e074897240a11c0b6cd3c865ce89dc4a4e107f67925a142ee5dc81d49fa437b9f47d7fa6300ac5c7024a4719cfab4b7c9db2e849359b2c23c2b6be9f2547e621b68a968436ef\nSHAKE-256: d6773bc5f6381930f215c14323e7b3140de74927cc5ea5af9f64270be8cd5dc86237300fd4ef802b537b766a628975de67c47476670613f8599cfabbfb4e0f273c4120a8d7b1f28584447b66b6b77289bb0448973fade5a7de7fbcaf69fd0e09a0faaf0b2e410b3c3e08f469f3574d360d7278de0f9f4d089c01577ecb93f851c0b9659613747f350201198a37e361abdc08bdc6fc5d85bbb9c25abea178b6003f14d2d120d913b1f91f9962f3e1625223227ddecff671655743c44a165800a0a68141160260f628cf20a9a39af9db1f89da96cb0eb038eff318208b8dec164255df289c769f1f221feabf4fe0a69a1a9841ea684f2f1ab8fd532927127cce67948e8d60aebd7c6a50378c420d5c7b2660c1465f45f7d26e9a0eafd6b5390f4b75e9c12e1965bd0c5d0be2729017e2299410aecda7f5597beb1b6e18bda7c7b629a150133f14673ff8ffd30d49600d6d864ca598433a656bf4d0d37b5a11759e837ec39d11288c91123fda7b017dc9a811fc0f235f5344acf3620daec68ab21d9d7c6ff986b6a7ac1f69c29c858309e59fc3bec48af5f434c99e05ddf394e63cf86e276deb19d861b83e6f1e093498fcb3be0dda172c432af7584750fd50f19418670e854b7a4190af60e0f896b386f21e394591536e254866f9ff086ce677a96e2360b5e19572929928e8b2bdfc023391e50bac81fbfa1bed99d1fe30079325\n\nInput: 49c723bce35f180aa15b854e5de2843b55cf685c7187439dc33010befe018f8231437c614cb64e9237d6e4d0e659f833b00d28268cb7375bf62faa33899214c105c580a7201a27abc6fd77c8110ce0d1973eeee8a55daca1c82025194769130d53cfda1e18e7bfab03a977e8c1ff6e59b87cbe1afbea9777cef76a4f58563756f5081eac70152846527422b0b9bea7c8b5352a5b7c33cf369c763a73e711d6f3e26e0ff653d6a9c7d1841747179df158a14d2bed01147d1f435a2657a82c3365f6974f0a02fbdb111e6b376757c77b8dac35d7da4eed6d749f161c120314f7cfec1f60fe14f1d2d0a1f0d0a92b16767497baa817681ecfcd1ccc49823d8a071d59d074cfafed535c646c0bfe2b0659b09651931fdabcc3cb1b830860e0036b6ce3db43f0d45096181fae2e52b5f3a49dd6a78c1d52bfafa8d0df7cdd9838e0edbb33588895bc20c226a2cfea7356ccfbebcfa9ed0227fc5c2b2b12235aae05a10fdaca3d42ef6f509e707470b58c9ede50b20eb1f0c08f0c7c50ac1aaf884019850475842fe852bed676ebdd14f936871d7f376bb5ce38962fdd3b4adce6375c669084\nSHA3-256: 7a744fe808527b4d3ae4fce7726a3cded3c7697b391d867a145afb7514a80f56\nSHA3-512: fbb46380983033c4bf6b1b028ef47530bb13af9e58baa5005d95c9ee067e5330fbd971ebd0c5b2feac23168ebfb97e2ff0bebf6bde89fa9d8d7c8104c328098e\nSHAKE-128: 45d53a551d17cbd6924a35e47ea7c2d07ce236bbb0915cf8cd06a71aeb589b888297298b9dcb4e91828f44f0583b90cbd61316c1be7792e047b88d308493d2438b30d41b752b07789852a83a2577420f9d909cedf4d272f44a99bd9e49d157d493286e2e55e80a7e214f304809f608e438a9373e4a9f1b39bcd33b615d700665032c7dcda0241cab2adae5157daa9b111a8a090c256c4d1ab8b3e85469004baa8687a326025085f68355424ab20c8eb5c8d91305f7ab7ddbfa8a2891d4b2f663bf7a454befdebe15d31c6db833006d3535e063c34d45e1c37c0e64b69958a46b7768f543c2fe767719c15b33e89ce25b034ec1c0370d2a52c9240cc5d92b448f2686c5570722cd6fab5a8cc3b007f5dde0f13571bd056978c9a3a1bae8dde4a09f98e79464553f39fe071cfbca5be869a353ebddc37efc8f0868516f5ea07049838d87e1893e6ad3a54534ad20e153a84faed659ac59171ebc01eb9ceaecdfb4f94ac627619f9943f63e8e2428a59c11fcef5c2e7fa4de691e072b83fe45eb0b0ef557808496209bb66d0c2a8523a5f303ecc4cf846f1b30fabb48400578e74d98d3dbc42f6ff3012e5de6da38c2d69d45e49d0", + "a634efbacfa849d63ba7b8ada19520a671b166e906d3f7d73d05ca62e5bcb7e4dc672f0e3ba4600c131ed5e40ee41f049934616bdbfc560c28338919d05ade9ee2805797e855f36ba5d67b7cc\nSHAKE-256: 6c16cb83647687de388033a8cfdcbe46e15738ac0a97c8cb63b4d946ff16f95857d050375f29e739e4967cdbece077cbf650dc4f163880842b2d6cdb7b92aca7a304f1478971ac563a80e25c2564f524fbec79a33262cbbf2b3129a815950e4a929ad698abd0a74820d26eeae419cf5507a95cadde12b587b66178126095873bd7719d0f4986214105822cb822be451f866f8608be9ebf6c66963093985f0e60b6b65f38485f0fbdab08322d04db380b3b88eecb0496bf7457551df80830346517c307b67d0252e22542c2930dec1da4e536d7c803d1fdaf400fec2a3fae2c4e38fabf5f0d8f278a7e7c5f9df81447f0ccd9553ce32b7d56a4484bd782bf1bcbff2411c8277b3a043eccf4714c3dd2a3cf96ea55f9ed59fd994e99298d5e22368287fcd55068a65e583cc5033f891dde03637163cf31203658ce1437604d61950a2ed486a64a99ccb2e38640f178386ae33191e4ebbf753d2622914e8f7c8183feb68da87c546c329bf10c4adad1f22a069859635e6842128add6c3a0631ef8fed2d13b51387c9ced1320e6b0cb4607178e494b25c93fa34110b4b339d9d1ff5df5f8fa4fe7b98b9889c1cef2f08b3494a16badc164811678cd268bda3f380ac04735a3bee8b4d671558857eea0a69aaec01f4151a68e5faa3b9e162d47a4392da4d30a44b4bba92dc003df012a452d157053c3ccc8a669e44e65cfbce0c6d7a\n\nInput: 0cfa36fae999c6b1a2ad65b67a149621401f1bdd69412d269252be5feb17a42a60683e103e2b66de2dfa72ebc5ef72f9b1b74af1f8e0e6863a7b27d92300e45a5317826f670e4366999f6cd911af9f6a09a20e23db34d30231a96e0fe962967217823f6498598d6909acae11d4ab201a26616426d2818dcc86a49154fff5e1bb7fa733ccb300e8b9841195841a877adc77722b196eebd86f77c6dc9aabe4176a8f987bad20d9dd05a72630fc5411aa90a9796fcb587a112ea782606efe1f896611863bb6b413f0edbf5e352146c7c57f9f3714fb8172437bf720847d9106f72260e49cc50c25c9b3b88bc2597c1f33120d532396fad5ad5adabde8cc0f129f6a0a9b4defb56c4b922f53e4b76bd82d00eeac869d7af62794c659d510a4bf0e9a5ab01f7d9bfb30ed9ecd9577d56b2f27c3eb21b9c453399d54cd64962c8e10b7faa86d161b316795e1751a24c195b1a97dc327ce117cea1f1c07bc29d3072f66e021a1fbafb238e8b838586b386f3519e45ee3ce5e4c4b176b53703f964dce2cac85ba9fb580947b47af85ea89e91336a7eed173b990cba9bf753229fa6c8326dda46203\nSHA3-256: 4afbbba791ffc182e5d09a8cdf3f3712146b888b74243997c88896ae20244824\nSHA3-512: dcfe6234dfafd5c8df0f3fbe1e61c3c68e02733103aa3372a0503c3ec7eaa44ca452539a2dc84a5ea3855d25238551af70fb44a1b6d20575ba54c88fe765fb0f\nSHAKE-128: c5d20bea850e301474da64b94d2f05eec0f9c5e322495731c588d8414a92e4565e8fdc7e1ee63737d871daf10e111f362d2429e171c8e23f8f5bf4f7280142d1894b46418acf25b1380af1010cad2328511896f4f2a68e7d0643dc70b04d3feb13eed857bb003ddb7d1ad24c36f1f13c975055092fcdf3cc00fd043789643688d2cae534d157af1c3810d57e392d617ac530ec18d025253b817b78f4eb9baf859ed427184ce0f0379955a0bc07e4ff9d1c44b7a130c4ec37a43c0484a30c5c5e977ed315667cf8da119432398497756da5618e257f5f816413fc48c07b755d378999d7b7177bff80500cc70025e4d7ea0bc24a7caa31c8d7ff864c219cbc79a3cf652a86bd91f54a8a021af057ee1ae859cd67ecb08f8df0b1b12077aff14ee716272b0ecc8931d3c4e8bb7e55f79c741779c38751c846ff7cdd4b2b761d830d4dc8e0d4e37936647ebe44cfcc1ae90b53421a0b68e8545003e045cbd07732e9790a90d2deebd4c2b77633cda8bf3a568dd9d79bec46dfcf857b01045072bf82a1cc2a40593bee9251191583abc79e644daa3809dafbf90c36b2706dc34b512c59435809852c3ec44669457b4d5640c10adcd4068770cfc71d63ee68a1b8273f99c72a4cfdb2f5db4fcd47d25da46c80a0c40f34682e0324cb5772315c38d20b621adb23090d2b33582c4ada8cf4434e0635648b079613753d4868153fc314bb\nSHAKE-256: 3458e94784777d96d124270d80289091eda36f05d550d0629405f88e6cd2285604a2f4584802d7bb9f5394ac6c0756a91f1126dcc02581a3bb6d38f1871f5e7ce835a123ba715ba9c74e76df0a6553970dbffa2129aca71e660ae5d0252b1b313b444dcb142bcc93077f9c66fbc0db9c6fe3b2adb155fffefb328abaf5bb487ed81ba6bc8942b70d40335a0d218f84ad204d239712ea9117cbaa9d69ae82d5849b7392843cce19c0bb76af4de276072ad476c6201c40634f9c9958668a939c11f3da19ab025f5cbeb32a7481b31742d78840b9c446521c8e0d5056ee38700843c647b287c509f3b439be1863858520b54bc19a7e63a840f892c2a11097bbc0c670fe47c9670249b35d71f6f5ec912bd4ec97efa0184d74e3c8b03a520c1353889b62c16377d0f0a1b845000f310bd501cd2bcad6db9e5474bb283a916a1ce771c32c1b7fe5c2cae272f98ff172a61009a7bd9ea1f30f5d4e2ef17341bf3ab4b2e161f73a3350de45cbd11a7f4c1307ddf7b3eb5c17c73570bb308ffb46a7784a854a33e9794a06521bb13897e83c168472356674bfef974755e0fced417012afee215ec3be12229e8732446f3e12439ad4648adba74519ae01cbe057ce9fbae0476cb3bb8ef913fff6e261fd5c09c744641096085241d52b330ac94ca757fe72713944f47338a25a288ec4bf00c9cf15801b0e8bcbec0da68ddcc655efd4668e\n\nInput: c43f520822ab87a54f2517e5db9e68dcb3a5e5007ca78fb6504fe98ef0e920a0a304571278c7624a81255f1210a7e3290884ec9c7dade4c502654bf721a5e10bdcf9be9ada5ea077128129e37d4d870bcd19808340c9bfb88a7b29247e7684585b62f50ff76e3a5b15de5fd57696120cc5b81c25020b2e5972bae29c8ba9a26cdce3d2835d8cb16d09ff73c1f0f20ce82ee7c222f2d6ba9891c3cc062ae110ecf796e2771902c692f4f1afd93d3423d72dc503bd28b1d6b9cd143537a0a4de86be389038502395179d9a706e35b15579465576a7f5b30dc4bc2f8d0ac75e5b82146eea01003dae4850eafd7284078c36fe1365bc7b5f3d71e97e10dcf493745e8b78547535122a9b9ecc7918c822e62476aa84eab6fef203e6dbbe61b1fdc07112d62a01b8b24842e414a080ca7abf7bdeb50b04a42ccb39562d57ff19629832b2bf3e72d74c45122de7a640e6d08b6ef7703fc05466320b547569b0109ad950bacf69fde2b600bd7c71a693b00ce16091e7aaa6287b9e51b12c1a8057da5b76fe01f40226d23219031e18bcd3bf8fcb4b39ad75026fdb7cb186dd1910dc7d28bfc9bd1d2a\nSHA3-256: 6e16dbf8b15d67da697114dca2b6f97c116edbb2c0e985be9ad2b9e3d6f00494\nSHA3-512: 89e3bfdd95b46cd5d67461d7e1108df41ce7fe96eef08d800d2f64df48296ce200694b91f640d4236572ef5e63298667948e4ef7d46912a2c5f2cac5cb4d965b\nSHAKE-128: 0c3ac08518a14a12dcbc3969dfe14bf2425f8f16235b3d38d5edc2f72e9a6c32f70467d6da172cf5fd0269d5a0393c6fb625ea2896cc60becb21b7e38b8ad2ca14b1149d7defc7e4e60625be6adbced3ef33e9f7e84fc7c3ef9f8fc9608a1379d21405b3f3305f13221f175f26f6df977c078d5ad215d4714d6b35a1c73308578973d291c8e619af12663511c0fd708d374ac6534b82cdfe188bba303ffa231b9f9793371b15b833f167b8f93d8977240456b2afe159576a19fe5a43c83ed798ebefae338f1faa7c3c9bb80dcd5eb1291c85a900d44b59befdca580347f9ab1e6097fb6316e084a22a77d71fae60202a6b8bae6ef5dbad640cf9c9bbc87365f68a3e529a6dc13cff56674cff0c37105123a6f3f23d5a9d307a9c5ae871895659d2bf877dd86099fa2bdf6a6d25f12d2a575c97f268decac6622b81a48bf0fb9ce0248061cb61dca3a784807720ae10c1e6c316771b2cfec7db6372814a0c37d9837773d8524156c259f8c1644593214c6989eece5de1403b63b9039717c872fe0a8db17ba6b2581e0bac110c72cbaee53011bfc5fa7dd6b3ced0565736bd9bf0a734790cfe7f7d47766c4842ed129e57134cfffb188a1702ecad627cfd804ed9a8f195e4be7411361d747054de2c4f61a37dea7bf0ffb60f552ff4ba3d7f983161716c1cd617e922cebdf4a96a6994311b7f8b9edddf579194b5d325def71128\nSHAKE-256: ba163ca09a10ec8387298f8528803e43495b2cb3ce8c4ff9237792d97b1e2ab05a111936022be2cfa0b489bde68bfdf1d9b1df03f963602be77df4974e6420f914a0536510cc1d796c9bdd3cb16649c9f4846e1197f77275fe71bd138cce3abd76c76d183d3eaa9e75bf354a828e82bf0502a2b80a0cdd1691911eb3ba28c62bbe4d236243cde1cb6fc3b51950b68a35f7d9b8704acc6323151ffb9d8caf2e71dfdef3e66580d29b9fe07f4cfe289eecae45dbf3bec49ee17eb3dcc67be63fa19b0f0638feaa5ad2eaafd89657270fb08de9adc136eacefa2143af9855bd22296d230862d28cd6e3a2c4669bfe71e5470e39cdd493ea530e9b839cd505d97b3e0d8b1c9d04c9c216189366595fc949881eedc7952983d16d619c6839ed08075f904642598e9efb55bd915562d45c415c2174528a5f3b304becda752d09eb598ff3504749296f71b57ab89e291c84ca06e7d3e699714bc6182d3cd30d009c8e6488c937e6994abb51fcc338d74cd96020481540315531142e3ce306362f12f787139ac3be2efefb25a81de16b500b298ded2fdc3a44cf1255537433296e7a684360abcb81db4afab90a2fe779215cc600235fd430245ad07e6cad71b5ffb70657a925ae0b76b56d35094ef631b8feabad41b1e4d280719d4cecae6f62a4b2c4a16d9492110727ab637e8134cd3907ca9b3ee430b3616064a7e9d13709dfca5833\n\nInput: 44f4551dc63fdc076a1d6bde17ba40ac91146fbce81952d451837019183fdf5e01abae7677ec03e2357d5d1523d2941651f2911b8b91dd580e0f599c7c6a9c00681cddf714157b04338a90a0a8de87bcc30b4643d6c39e42e2356ec18d181d7d6516a11108cc682799552e7b3f230117cc5e0867f2ebf43b64acc48e31157f53ddfc58c1bf35340f0d5e7cf23ea61f53ed0cff4dc626a42bb9aa9ffb53635c21a04b588312b309d20a5d5d22909cc7a7bdbca030fb70781d80d03466791db1c1571ddf44a61b63ad0b091267e8f721cb232efc3d581442ca41d952504dd149d6ba507600747b90a0387c722d793cabc16be6dd3fba8036b7e54bf303f0d68fd1b1396acbc2c06e237c0ff6d3041c7b4fd6df1b8f930a70f837a0f7e389d025577f515db0a8a2a8ba8d5636539324ac823d9ad5af68012a0980376c298412ee4017318af9d4dfc5d212d718ddc6b88ade6ffc85e9e9b2d5983f9934d419e9b057e1bc3260099392f006", + "39f802f5a285a7267bb1c7ec356814121cacdb21343f538a2454cf0617e2b38709def8d7f7f7d098b7f50fdaeb842bc1372bdd8551db65c3256179dc05\nSHA3-256: 7de3302e7ede529e874ff916b62f49f5180fc3254ebeb4fc0721bfd24b79951e\nSHA3-512: 66d12b130527f05859ee256a582d373d0bde28af93069b763e6fd1cb1b512d4fe3834b3f4d0f92f06a9afd757d421615acf546e938c6068a972a878e40b880c9\nSHAKE-128: eaa733a8820d87f297293a88a9e0fd7564146ffd750948ff5cbd89b7a98bd48b3d53074fc47739a7bad78c2365a6cbcc62357173bd2b3b54b0ce3659d20f123c8009d928c84eb9cd3e7672979dde3ed956670de3a31793ba8af0a143decfc924f4a9d8f293081be593abffe53701982ac5dcfdd3e4f639d6193532da879f88088e86a65bbcd492deb8954b05eb140bb1b1bd02f70bdb29e3d0f8af55165609e8b431a75f266731a6ca990e48616dc1eeb48ae2811426397cac99ec9bf2ea76c5cce2dcac0f6283f77810b0f690b9785fec55419dde20f06e25cd0913c7bbd734d21b57f1df1c660bb555c8d713810ea5e1a12c61d82922b9fcd5b43fa67ff43acf5f0f6d33c119da097b5fcd7324a3c7de6c46a170c484cb29dcfeb53c9c48da8448c19f5ec577923edc0e55874f5d67ad70a3408cbb48c09c6fc865966520acd6499feefeff4fa94c86459a227bdd39694d14392ab7a54fc2b42e345d723724cdf0e289f8223e69ef9eaff8645af4788312605d6a7a94d0f863d97bd06815289e4c1cc36ba5f2b6996c93a3593acb8d60f757891f850fe674a3d4caf1280bdb2c764e8b37868c9e75a12f474adb8a0d8cb601a04a2c2b588ab678c05b82d39dd62a9db4f1ec5a9e9fbaa613a100da47d6deb984bbe451d83b906d647fea81267948ad972cdb85dcac26f9f7a79f1f43838f47c8fbab0e03e70e3bfc919150be\nSHAKE-256: 35fa173d7b2d4547c3b1f768f42f336b4b24be3e616d774dccbaa09ba49aaeeebae23f44d3e8c5532991ad8855846ec7b32adbc5a503d06c8a6e0a311528bbe6e4d8fca7f99e2773d8fabd5154c5ebff1f829287a253adc2c8bd766548ed38ce396e3052222f192e61dfa06210145d67fefd8b259f79484d6ad4098d6a74fc16010b2cd6ac3ba88efcd82cdbe21b86527dde79dc836deaba94a9ea30d74db94d359bac8082a59d900d2a7d5785fc01c26fcdc37505973f181bfff933ef5e78a5e7c9785ec832cf5f198bdc1dbfde5cb02cdb68c0f31d0b7a05cc93411fe075ccc84313ee1c03acc001f533f590cc190b72e737e8c01e2acd7a2b0156f0df5f246e0eaa4f16c7fd1bc2042c2c204b7831d5eac8a043301de21c6e9cfc40d876c299c1bd1f5a5a8f8834c0712ea9a395ace6b75b7f4b2483cc744c7dc159c0d1a691d70072a2e5a0733dd6d7fde7477d182147588d5a574313ef075bc29c1a320307652ece6b7967a1a41abc42887d87a40dacc68dbc8a9b20ccecd1785c9bc175d5d7cde6bcccba0c51931a32041c49333120d1f4352f5a1a301226fdfbd0987346ac32241e82106ad272c1fa6a02afd4fb30f9a54f311bcc9b87f5516741adc8d1d80267c4a89e05761cbab8d5697cd0e22a78c3be1ad869cebac27dd821fd72f786aefd7efd5b1bf5c1af22f5f05f4b10a4f7ed653809529c060f41a5cdba68\n\nInput: 354b48f32d73667f253909bbff35cd20eb3c6a2f6a3709212ab9c0a2ec49fb423b9175283b4cffd1d836ef20a63faea00103dc7f18b116efd4c49f5834dacd81882341684074728267535a675a6415a536a05376cc278677aa438286ed0ace57c4d5d646741537bfb2f376a0b327080cda767dca1a30464c4d81fff416fb7e4ecb625ffc95ea1c2f592725253a872f3c84e5880705e78ce0ce40635566363c03f99e9b01b31bad4791a1c6573bd0dbf12e23271d2b70ad6c1951415bebb24de93814751b3c5a0069aab1a442dd201f1b983a99917b5ceb9d0c97896c0400a1c548e2dbc8ac63c2f401a2b6688a76b1cb6a563f32270c93334d6bdd50312443afa70846042784a401651c549d1398478c0704c6e6b72f8662a5ed38e65d03253c339113dc429c182f8c15bc83c54318c273b7019a25cf0b1eb9251d31092cede1f8dee316a8710ced8be21f37f1bf7b2b5616bc96a1a07cdf5d931f06b47c017217c5596eaa2374d3eb3f3bbe77b5b4e1259ca025575d612d90dc81f6cd128a1502790284ff21e6ef5acebce822961369b7a7a55b6a61cd75336e3d99f80c3b8220e385465cfbe8\nSHA3-256: 9e957b526f12da94e773f67533798a52b25938dbbdd38b8c2bc85c2aaee28991\nSHA3-512: c9cb6899f2ee9193dd89ed856d8488e95082ce9ecc20ec40b16c019ea0c69de83cad7a4b079459d5f3b3463470094aad76afd6b73a1e4d1b50d48828726c7d9f\nSHAKE-128: 24014841c302eb1aa4f4b8f7386a0d66b62506df18edb7fc6170348b6491ac88ee60a9dd957c05e538fa947f7d1ecb09983843729be68086af94f4c8be1c12d08433cbc5a767e822fc236b06c70110306e38919046a5356a0a2092c045913082bb692896da625659f265c5da91ea4595d244a95fee0bb8ab24887db39fb845893d7a39c2a23d9631ebf44eb02b861fa263fe2f9f452770f177195e90633f78799fa2edb3a4ca6546e7ad14f8211e7c524cc2f6d3b7a3f0e4f55708f5f3a9ac943d80f26825da5d2dfacbed1bbe61ea662b55242ef36be18a823a5581e54b24049a55b1a2f17cdf91c74141f84923e6ea7b884b02c348569c461389f9eba1bd78d9d487ac429968ef8a7ee7a86f17beb6ddd2c6feee03bff5b0f2a21bdeff33c875ef38471b44fdd9a34b73f93d2983d10dad5f3b57581534ddc1b7e7850b3e9be653f099eb8a216e530cbde318a5a3f36d8524d02a8aa8d33a2e31d5da795481cf3c668c5b76886209bd9fbd021378a7d0b66ed6d97c1679fba6b9def8bcbd194e4fc798cb1c665e87cc7bd2fc1d48df6b7820766ea730976c063b4bf43eefd26831dfbcb117f7bdd1afa7222c72e748014f8d05a75197c41582edec03b467c252492cb071c278c019050b43b48a329ab63e0e06fdaa5bb4fcaec63bb06bcfd3d48b22b9538cdc15ca543722a204ad13e226e80305a435ef9db8423082b4258d\nSHAKE-256: ef1776a55335888a90c93226a41ed99743ce812c2615ae439c1a299b1d8143bcc984b45990c7ecccccc45b5b6ac1ee978833d6fedad9f1ab7d5ed7abcf72eb078c571646d803bf467dbbaa775d080328e79804e0adcf5ad621de4e8c35b1b20852dd39f56e0de5bd7fb7732696bae4fe2a660ca4477684bdd21634573fb6ee59e37b1703df5b23fddaf9b535d0f8c8ec1688c514e47dc83fafc9ab81882833edd9ca13aadb2dac2ea2d2c4fb8745e4928eddade1e1372db3639bd183d47865153277c70b102c1453f69e8aa5c9a906f52a27e220abb152700578d31b583c5f9d98abc867c9cd8938dbbfc3984f390d4ffdefb01cd920f3e6d5357d9cdc4d462918ba0c2ee94cc07929a56ce71595aee3008ae1edd6f4c98b27ed54930febfab292d58a4db7b6653d7ee5e541dc7e4d9732a05c895f895a5e2316855e36b6f0854817f2bdce7b6d83aa114054516ac49e52d9c3f1ffc53d63184675134c01d498f193479c3b334c2dd8d52c2f1a02659b778a531646ef01d78373477a6cab883559bab262046497dc9706465b8edd992e496cdca9f788184337b16da85dd25a9e1b16063463915289d7322c2728f99c276353548da0eb062bad21cc692a1451fa16d99ce03564f5eb2c69050e6c3f59246fce019c57e54e1572962215ea3e51a04bb8f4965c1f4da15b3930bb51e12d0bb83763982b9178cf861cb1e6fcc499e0\n\nInput: 5c8a2f14262524075398ea143b7fbe4d1970cf5ffca912e4cd10b4b1859a66f93701fdc2982238a451f121a1bdb8fd83cabdf242e9030d2730b19428b194b6505ff255029063764ef746af5e658554a906586b9500da95313ea39edf1a77d594c88cb76f81f871421efa018ad43c2192b348dadba73be803bce1b993c6e49f13f428c1a30000225ba0442a57e67ef57c7ec6302b55d7863667ebc71269c890c0fdd305c68156b3e7d47e669118262e58abd9da7e2ecf9fb0156fdf0f0bcb38b043ef751b598bb4766fb5b32edca7393dacb78b4f58a2d10e9ceadb80b589be66eb12359f8481e3f7860bb1b56edd26ac0411fb5b8bbf26ae630706b5b851b35df22b5847a9dc79346224ca64cc568a61ad8a56791899848169efebbb3adf51d6874715da4739a7caed1101696ed2911a871e92105da3b5e97a4fc5ab76085a997b7bd44dc5bb832133952980bfb7e0407c4a0bd249e8c1b0c2e1dace1303e3a9465296d054187614b9cb729312a56f8206d832bc74223d6824a26bbc710a70b8dc4fb57af530dd3c16b6200f3e402adb45a6161cc0370f0315cc5e2e7c2753e1f69884676a65bd8f\nSHA3-256: 3065f947ec1582653b36acbda534a62e06254c18122f4f976a1c8b8647ae84fb\nSHA3-512: 0f6932287b85df833d7afabaeb10fce24c02b6899ac0e4190e12743135580fa9e40c6b9c1e3cbb123762ffba78871c5778eccbf8f08d2289318090dbed013624\nSHAKE-128: 299000aff5bbcdb24b3ada77e32de9a88748966fac85c971b4d7f51a6d3645f8495e4eea9bb2a4ebcb0cdf9bedccfadf0ff6c52e6d5cf9d75408526e8557517f532fb51e1b906a2a80642e47e60ee862482f14ed426c20ea9352521f49c6df81f2662bfc98f7f969acf0a0915147a4555b2db2e756a91bc25d2d6e5c536ef8990cade7af4996ff617df43499c5ec5e287ef8636549bd66b14a5a162d436f978ec150fc8f9a40ec12cf92a38b0e065c611a28ddbb8cb635fae07238e90e7a3a7a56f2c4a9a53f0975ec01642074d0ed4864593eccfdaaf371e70bc1f2a4acc6bbc0b480704c7d16bbd7ab7fcee3ab6b461c9e73e2c720139a4411688685ce6a2333aae453701e5d007e34fd7d2e0b8f2eb511fe2d3bc3ec60ed9c691172cde3b82c1d9d8ebac70b13b1f372784380edeb7ec9f3e22b5ee5d9b683368909e07a214f2b4670b6359c8d33f547e039c3e28e3208b2879f6427537d4d1e3d052ccccf9f82228f068619b840bcc44d8d385fdf483fb45a8159f13446d74ff4fda4681fd4f8dfa0c166c0a0d6d0c67c8202e38c85903dc0591cbd7989e7a5396379772f271e2cf75e8f320cc29b058a2cc2d010cda7e89eb89ef5a568c3e655a6a192c099d5b8274f28888270c7ef255178a9979af61d8650396151c74e37615e9a6e65209561b519d3f39dd06551098a9547f9a17e1fb1cdb1137c2febb98cea8dd92d\nSHAKE-256: fc2f48467e634022b2a9c0bec100328efb92fff7ee18b8bfc25fce6cdf8935bc4020562e0763ba31a8414452d0a691b589dd2431cde60e30bae070aae6783fc3f7200c78fb4015d01ccdcbd5a10780fea8680b127605f0ba7d4c81e86eec20c010536429232f81c443b5c87575f5c2f4b2a20d87f0693ae6eec60256ad51769d9b91cb3a281dccd09db1cdd8768ac0df997687d45dcb8b8cceab2b4c2262255e43d46403fe7332bb9eda695134dee92b8b9116f35b0a9da251361516dd3d3e69a9681224223fba585d55d3f9d228f1718e3fe112002337725a2663aa3a9a63b49ac52247ff235f04ba32286be13ab2574caa7bdeffa699014d72f38b7bd9cc02c5f79276006f", + "0617ceb6e8674d01c9022d25071ca4f02a4cbdfe30821f68c516eb2daa0256811e57a9df9799221a07cfa1c040f39112b8cdb48a7d0596c0b3909370a8146f95a8d4ba4cd22179357e9e6fe94bbc7c4cd29db286bd0f9dd82af491a234f8816fa7cd9e68e3b7e2bf525b6cdfbd7e651380c22cf2d4616b0baeda283502bc622a4962b2f47b15699f6c517f213f0f99a4566cabf63e5850458e13b25b40cb42688b6a2357293c80e552cb8ddba6686e965b79d2b2935447648b6a9e8d3ad6b7f15fd9f8f2d247df8fd3d822edf3c1743f04b7d8cea638d0a42241a1f1effe9d2ec53e31ba032298da0b5232020b95bbe25fafafd9db04ad912d1b\n\nInput: 89c80913c88a49213f5289e3d62145846237847f80b451d6c0827030820c8ae12321e9327af53a67e6ea74ce5d16700fe764bac7388aa0d7bf75e4da97309f3d75958c1075a5761c9da6b52494deddee12ef14306fbc61fdef716ee3738f8ee217ed9cd24bb160c3f336cd7c107f59480ad4acd79d1bdea407254de5c86579f4b8421c3f47d6b78e2e6a42e3aa6736923df757ea5ee3252eb78bd20fb43a2833d8689aa2f8f6a01074c2b3ac585f9adfb769679dca94691052dfa5ae8433519f6453d1ed64264a0683f5ebe3e3bb3a0c7fd5e6af2f4a628ba8b07a993e004e038453cc1f6db6bcbfee73feb56da9e8b412844bf63c108af1fb0d7998da45082eb802f76953eb56cf1dfd4a3b011718ea326946079ee933b34f73038eb41831e065f8dd084685ed07b4015c6a9f0e003610aeb396cc1cdaa1e02e1b6c634980567a19241c676b50d5e0d207eac23bad586d63122b985bb638a3e6fcec319c5a73abd4245fc88c537b446ee532df0a3c2a9ea218646eecd0edb48fe5fe8d19f508de275244964e5e995e62d941ad26f5ad8b8f43c8b3729e25a7d89383558f89a33cfb0f874cf33cde70\nSHA3-256: 7d5df8d8a47ee90d5292bbef5ab0ae9eef1c8cfbca900730085abdc5d80a23c1\nSHA3-512: c924f7d2e2369e2c06a899232ecde93d79af57bd5069c5f611aa8c85b0fb9be61890d41ad634fcc11fcff1eceb270e22363872b4913e49c8eb19f8f0fd1f5b28\nSHAKE-128: 12e040c9e52e643d8522ea9f3aa9629fe90e98bf179bfb90b62b8245b3c5967b4a27a72586037dc36cb0915dfae3285bce2184cf8349e3542c7e853358e11ae78ad9e8ef8506fab0f33684cda340da1c17163609968ef57edf40213bd4d993706ff2890b7ee7c6e527a7949ff8233ac271c8e439b16e639b2e9213ad3d1c7e5dd06f40b11222d519dd99e9ad398ffbe787a0eb207ce8e96d40d29358aecc9940726eeaeb16dc6208f713c8d4c0df2faae04c1950d82306d274ccc055a033e41745b569fcbd54f5fca9531c955d269961607c5d83afdff3c085a2443adedb0443f52e128c705153d6179eb440a886d59d6453ff5b0cdb7aac9047d00f70aa8ca8a3de9e69d92e82601d849d57f42d8cae07590b7be47a6563ba803ccd2dc14e0a1f468d8502eff5f7fbad81a09f918d3294a63a7786a5244732231ac631c95ecd4c7ea759ade5aa2113535f87b96eedb37f46d25f9c963c65f7160d5b4780d602741ffb904a0ab874bec1b85ce5e05505e95e7e7651a93f72c4eacfed251ea5d166f9cde88ed061a70b72b36d4f61271a08c3166f7c0a64a5073fa23cedd79c92695036e468ff50281cdb7661b25f8e65105930616b5a68f514ddbbc34423c330410ad8fdc739c1f381bdd96e782571b017d63ff0044e3cd971cdf3eab577bf0849334944201949d2adb48f913a8f11b9cc5afea54b7187c7bea2a0459f17cbd4\nSHAKE-256: 3de8ed18b7c353ed4a2ded25673257829c3e71720f2364c8a73c19e96dc86322cd6adea19c092d65c63a8da6205ae695dabc29a622f48c5fa89d8b70c6812c1b9cc612cf8c2f1cee80893ab2b9347d713a242d13dcf958c6b809d6ffacf8c7aa6b28f7ca158b9197df969e82fde88a9be38796b58f4d49c7e8a1b6b1e53c15278cc08ceedc681f7ee0d1e06302c1c53d7f590777b81ade9f35de189d9d04fdcd876ae92f6616821bbb3b52898b262390f29b136639d88b993e51a20e49534081721d5aacebb13dd6cd0a1a6bb3fb3f2045b7472601bd1035ef245cc6d8172d31738272d9405f4cd33c136da97cda8baee54df25696a8ab2636f32313f9dff3395b58ef524d5d0e411231959577d00ba58e00579681269b283ce4dbb624532d103243781e9004dab956303cdac60a6544ece128ca0ad5a213735c351efe0c87e07dceb41edbdf451c5ebe283403dcb267d6f7b784fcb3d7c21ab8c501d6f46ef97431e4139820fea354737bf51c95dfa71ac70cfcad901c980b91eb12d891c8410d1e58d363439a43f7553baf30e39a76bdb06a70bb4c59c98c03666652f13d4e3545160749f43ac836f5c94b67ef61478ddea6fd8c835af0ff1171ed4348e9a040d74d8e9a7d25e5d2127d656d2ae5a5b8b5c353a6f28e7b7d4bee7bd6aa05c3e3aaf973159f7264b0b7d4f47528ddd38b9c6ae05703c4c81a86ab6f29b4dab3\n\nInput: 5a0dba9fdf3100e85d36bba331998a60babd4d82f143b8fd56230668215b4634a99b53c67f1e92288499ca9347177ef7f37d5b62f100aa7abad76cb1dbcaab11479829a73fcb99343a04ba1ba0e496e3748903fec7bf19d7541740720406b1c7b8121685a19d291606fc547fb5f7d18868e11635147071ad35a81d57ce06a5a2b81ab92822cf13efcc24764a2025bcc767bd3dc8d202f07bb1f4ef2a318155d286bb0f7ad2a457cecf322d605ded739806ab0d2a1760ba0565631bec92dfbf61348f55727cdfa778def2660772b9f9fbfc91356e9ef942adcf13ae0d6f4a9f3913089cde7db5b55a6dcd7c9010592db7973b764967d1c039ad90244592f1388576dd8cab6389aa468ee46ac2afecd35ec3e1717a51ebc2730c0829b5b68474ceb6a650dc063f200b29b35d68dff5645113d82a01faf82540dd9fd1aae68ce542b5d0ba6e53d7f82a42fb2b7760eeab6a5c473cfa35f4fddbfe18c2ce560829c5b5ac0de9dfe5d4aac01d218c8887183bfe0e9e091db8496e2b66658741d02cfad2b6df5f1cea4c0f974478349c3f0be6ba07c6f07c2c3a5cb3691cf246e19f285741ac470c20df56749a\nSHA3-256: af9b698b84926b7704c9e92f914e3b97cf41a719d62d52fbf557cedea6283e1d\nSHA3-512: 15436abcd8e668b73edcd56fee1f4da5a9976e85831bbcc9ad8883eccaa913b06ea02b2ee73072b5059fac062a596c85a17ff45ee57dcaf8092a88cab0497fff\nSHAKE-128: e45388c924e13d8c2b89cbf6b3fd12e352dc5fe59ae24132e56a50aceaad4b2638adcf48b4138ba113d6894473e8cb983f90a7bac70a0d31d4213335e80cee15a41a8a6ecdac3054719a2e273e90b6306c76a8ee7f76f55e89eaf368a64bc5a231ee01e70a35788591eb355ba66bf1ae2ced2292a58de60efedcc68c16aab2bc112f34a7a9298594c189d25c10cbf6550bb58d64055d05aa57b506b46d50dde7e5c8f1b8797940d4050a720a3fc41fd03789b76b0f9662e95ad77d49aabc134fd7c187ce129d3543a680f8937a04e185bf599aa6cb35f66f8ab8ac7f3e21a3a38c246529e50af65fef76865e110967c21e18ff5761d4d98ac6d771fd9c15d67fc66c83abd9b63e9c9617a8bec15501c31c9d587250c70f4200f1e0b5fc2b7fb379d3ad5cf85e068d54bfd816c56418daa952ab7b0631ad097ad20e940f6ab2204721b18edfb192ad43d73c91ba72185e8b058d43acc3c6b78a0fb1ccc9a39354a96a1aea43e81ad2c70e10c1df1b88df6c2b6f69acb27a0744233195df1652fc81cba76c80c84f2dc66cc1888452f902ab730904a87e8581753b78105823a686a81176ac0fab5898ce99cf9192c4f7af1958e9dd70d659f31b046d2721f6b3fc9b99ff990c4f4ddd2e8f8d69f3bb746c1804a761d8957c8db56166d7bc2fd5b96c3aaff2955c14be81f56300a8f13c8a92c58d0acdcaa1326f6ff63956463351\nSHAKE-256: ffba04f89d1d0aa4cc5ceb95135cdf885ffceeb6bb4b7d5f93bdaff851d7369db750d1162555f59fc8d97799dc3a051a6eea6bd4d77b41785f37dc268c1a4527fa622a5ce758436819a3925a39652c6bc6cb7761d7f57b2bdf3e3d56db1e52207095c509125ce17cba2b5bc48b2f853ff8395b5df0a50923c507da886cf5ac05719e6c6d51097185d3ec3360aecaf173f0965207fa969fa4016f0c39f35f2462652287b4d0b517d473a386a1fee56d2a31d37a444238aed88eba4d8a9ae2e056811122498e60b3061c132954a176d1ebfb342015453f1d2b6b0a3576731aaa27642b1819a391588e9016561c08b1a27f59c3c951484292cddfca9ca7ec3810ce2daff43325044ad172d675d3263597f6c80dc4f3971928befd40bcbdb7b0c9f91e9798e7aad5af5916c58ee898174facb870d1b4bea6ba2d80aa1d5dde3e110f4a7fca4305fac5ee43fc5a7c5682d6b013c8159e364241523d01717d896fd9cfb8cd46f50d42dfe662ce86055b1ec9d64f6b71df59297977b8c5d83c8699ccd542a7c919afaf6df01417c9694ca52a15862db185bf7009f5d6e7eb9301a075545baae2e4ad5670047e4b4aaeb6056f00f08b6dbc15ba8a4aafaaa55ac8116234cecfd4785185e88babbf8d1fcbe84f952aa8a0495d011a4e8daddc23d635f1220f180002d41d63d635cb013eb9ed3382698a65b2cb3c009353133b8a6bb4bd37\n\nInput: d8bab2e9f53bcd4364ce17e304ff93aaac343696e1e4acffcfaeeef6bb15921beeec489be47ec6c6742fe30c70b76d807da97f5c3151be9fd12789b721c8bed05c509d2ff9edaff67c5686318f6931c81e99a9c4ae3deca14285acf11af75312f14518e0f82dfdb8ccbed2a5809390c7b94fba3b6d6383cee702b752f4e811c0165a160e856b1458b67346ab44b71533426e88c1ab2a45e1e8002499c2e092bd9a7ff6ac6887216d8c061a1ef898264cd0eec46bd2e91f0dbebfa2fed254f2f1a39079353d4b02765131f764b3e02d4672a00287f04909d762f0a8e95b1bd6a25f6dc628c0628ec9524868c643e973471e21dc1b0519a926faacd060e56b630ac97be03afe1555155479dc8e31353a73751a8a274cabb7dc079798d4e49f79e23696a4c39842b5be9635e0acfb5cfd70ae09bf2a587ee6866cbdefebd36c54871f597e5d9e02a3639baba06e34ce02aabcdaf83858f308bbe92eaa2d469c4f81a2453221a728f2f77b020287dbbdaf4c95e57220af7058b548fd275d384e6a6c76ad258591e670154fa3003b454016463656997832b628229fd73b4bfb4c56ebb5af3711431f372f742cdb\nSHA3-256: ba24cf1c46972822e1e8886ee87a8cf62f3d26314d43b412c3c759fc44c3190e\nSHA3-512: 4a91ab97d4ff35b53dc42d8a5140f72548f6c45ef7e7d1df787af5f5176838ab1ff3f4e389bec99bb57348a7b945b326aae1914bf30dadace641df2735e7b2a3\nSHAKE-128: 4c5585b63a5ca3019c8b5556339cac8e7402d617fcc9e459edc9e5dbb48e582d6afb9d7000674818cff94e8c3bcd0c824b1e7167537274c6b96fd8f0cd67ff687d7fc3ac99db3b4d59e0d88514a49597a36c81376596c0b072bd25122d91907eb066823495cf0cf0fbb420edd55f490ef94ab9bbe0460296421ce2da179d5e45bbc51dff7fc4d826ec5c942a622a0e82aafe2ac8bf4cad4e4a35576", + "4f688c972ceb79468f288151fc5382672195bcd48e3400b16118ddd137c263ffd503b658afe32a71a8b2052b2bfa2b15fd5ae36fbd552b3691d4529e89723191126fc74735a979e14032a42cb26333951f3e0fcb405a15db656790d9aa74bee907201a4719f26956740ae889e808dd3c6d02f5ced3f4a9ce1546ae5f8ed6b5340921f41cde7f2234d635826c14b8617c0ca239eee241555120ebc11902eac8dfcfca2dfcfa0ec328d407afa3b3a6ac16ff472c6571796a8e14d1133bf77aa3f9aba20f0e4be26be1006ac4c6ff5eff00f1ef438412d0d0908dbefac4767579f3b25cdc565ee71bf766a9367a8676a696fab13216e0a75dad1effb45151f3aacde6749db420fa08b441f7b91c3fc1875e0fd23425f6c2aad01a086f7d7a7d6899f2700da8151803315eb29bd3ae86b330934415689c5b24911a01ea8ae94f8b44dfa2508b14a3e697e24dfda2cb290e5b655ed12b7f3cdc9652d988519afd49c417f470ebf\nSHAKE-256: 099824826a71d14430e6312abb787a210abcb38ebf3d6e98184c82834bce862fa69559fca5c11d5627e84f9c7762609cb9e98132eb828bd514a564d8ebec8c99f89f9b4a4ba78db967fb44a35be514ad11e0df2cc2f217e3a493c347ce2556a65d77cfe7ecec8330e0e83cf252fe30bce19da1d636596fc80e3735f162e49e2442250677a8d94be272b2c722ba4e88a9549ee6033e92da9643eeee50c38231228acb99b3bc3ef56f2b181451ff089b8202cf8211686cadd649a166d4f606fe9d25feb9f098fd885cbfc66aa65ab6b8f1374368f43cd37bb66879c65851acd30dbb5b6aa5935a2ed4fd3d5f8531220de8bc9d13c2448314273dac0c4e23333024e265b29f4d9bfaf50576e8dfefa667a156c6557345a418351b0156b5d92f70be0367cf459115901a30cbd663a42a19b9e24423ecf9da36f4cbd2b246bce56ce286d8de8a4901f4e26dc4bee6b1a2d4b9d6529f0c7f5c15d963d9bee8d22155922b3c90ded69883a038fd5067b8c9aa42c5fb8dc6100f33f7ef0a229ffc925a7e8b2bf75e80398793168acf0d57c5dd5fc1a2cba5a0aec63de8421857cc5bf94c7435b2937add60eb751e3bdac86015eb48ebfbe99922447574eea8c2b5c3f4d7ddb7df461f4fb92312e1f2dfe232e047c2bcf159e6e471a1b2a0867463e121effae07e28d4cd64b1e0bced4b727a9ca07944ca704f9de009f5d8d7c1a909efcf\n\nInput: 11c79b87032c20cd7f3da817b74b67092215884f681f117a3ac67fd20efee642986ea8db9f738c5e3f37d8b86f6f572c7cd9e9286b5c44908569d4d28746746abed61c119eb741c727cb8e7dea2745d646bb81eaa732f5f8e52b3ee58b921342e260df3437162dee31ba9eee39ee540aba185172d0581b0c4a85819f0bfff6f306607ecd3ef2d013f0ac4e81b9da5ef12e45fde08f9ed8d0003a4cd1be0fa25550804f35e1db218ebc5396e32f9cfe1aac115abd19864a2a2c03cfb16740dc83c91107c2bf4a7999f00414b5fa585a6e9b2080d69f59877872d77d426d3271f2c9d5d924f17b7b01feafaf574f42c00cda69822794ba6d285a50fd2c022ab7eb0c63a4bab21417de5d6b3c5916fbc14f746608a03ebf112bc7b728a9e8f8f284c7ce84864d59b1afba11b67fc4cc3337566917f0c38cfc7d5bbfd2cc01d2761723bc118407e8f2696c320a6b714374d22b5fdf355717f5ad5f44d28a287617c0418789912cb9ff6667b4052c32cab61f0b2b5a5848fe731d5120f6578a19ead99c8d2b5bac2defbeb8ef8aa0bf2a625a25ba7f0cb5c892752cc02c196ce648d57e205a0b4e83dba29956169c\nSHA3-256: 46f61e0c3fb514f2ffa27c02e90d6f217ac778d1cd0a75753fd0a5f38157ed82\nSHA3-512: b76fbe28d4432ef367b9a8eb89a4c2aa6d34ebd09660f6ec8c92d1b844567329b71c13887047e688efea82d6e9c54377b0a0890db67f12f14b1b9dce165b7ff9\nSHAKE-128: 99206001d54279a2e911a83bbf32bcac933f62792a2a790d1b87b3475249d42ebc4e43d25e8995207f229bef6e2d26a18e9fdf671b62adf8edeb20c3e65c4247ef8d3cd093336741c5955ae0ef098203128870453cfbd5b5324224d50dfb2b379c8d8c4e4f364b5cf80e4c839a36e09461e70050621359667cadc5e035dd691e7f5a94ee1f5ceb994e8727547f5dd6776dba8d1bbe5ae2271e2334bfc1bfeb4f69dffeb2fd0e59cca0ebe40ceb409ebd63ce87212ea09908b934a92326ae1d88dfcc517bacf277ff999ce470c9cc42b0de9f81308df63973bfac35ec0ad3f288ff00714592543c2ac91e637591e07b56b080de67e3cda882a113ce9f60e6f0451cad63a8397cb299fa2c669b561f7650fe18e5b19afbec54b2c8b6aa9389cbb170baa533e712a9b01ea4f59b41c95082361cdab5f776542154ab545a781b9d14fe879be376533325d1c091b433c23b76ca21dadbb4f8adeac0bbd1fc59faa2624a3bf039880d971d16c091c28c6d09ac419c97951fd6892498287a4c32048bbd188f955873ff1eab07613ed041d60782995759fd5d03c95d8c15a633f3b488e1b554057d54fba9f8c418fe898a84c5b135c501fa6521f317ce65ffa1b54bfdec9cc2d0d0600f050ce593726ef6c96d90a38db4559945a0423a615e6f44b21c645f4eb1e1f7f709f3fea9e4d2bcd1e7034b5cc15aec2931a61eda7b4ccbc4fe60\nSHAKE-256: ad3a7249942329ca43dafab636fee31329aadf277a86210a58d2d0c2c991bef9e7294b4b50cf129482faf5d97a1c508c2e291879125e25e4862707f6320103300b30b171a0b6bed9f124ba9aab188b186f02a77469b46ed0277fed513331ff0107d92db83330a2f8505e824316b842c948ca4fba6510e9072e4569f0fe77bf234fe60e8202df85f41b925b9f98adb4a9600193d0d81fe0222bd9cf65ea7dedcea0df2b9fd5203eecac9578481614d48e297b9e4f371ffd153b11dccb3254cee91677fcc42fdc4373e0201414342be7f8f5018a1697490a3333df6c52200bfec5f3471a0b8bfc5a777e4682e4e8fc4965ef78fe42c86bb563014ece248b805452a0a570fd972cb03bb65d93d6f43021f42180a07049afc21e449af6afc5d6539d0e4c6b3e54abfcdc4abd7827f09037c2ff09f6aa19374cfb88a54090a8cb93bb46a8b395233520ebe1fa655731cbe9f334446734adc29ec762f2989f500085a3fbec5a4ca27c3b097d7e576a1eb6d22c36a69f98cc81c338db2d11c8ca16f276d0fb20aff7ca066e9172eba8e3b13ffe8c1f22802bc5e5c234228e25a780288db5d897c665bc62154cf6511f7ed0091228f9404bec1e49cd83c78fa0f051238fa67dd89a812d1caea71fb20161d63afc7f9019ef123818da33921ee53695b254f240277d1adf6ed89c1074a5d1b581d6eb684dcc0517c8294ef3346ae8dcffc4\n\nInput: 5483f59fe603c8a309c9db96ddbdd5b782ae878036a09c50afba4091cfb3e4174f547868f5c0339ae0eb6590470ab07bcca5277c8d6a9b8ac63fe616c322827b75fd8b6180b21274c3a8580f1dd826ea746999fbe37940ab39bee5c3c8f7c9a1565163ef2cff32d3112c004e22bd960b8e3c74cabf7b82ccb3f8068a163511fd4db5758c3ccc546d206de924e885c4d27f75efbc55e34bb89e4805b42cda2afaf80c0b6f0eb2a97bbd78a399d4f5c528aef2ebe2566a36d369c5732476f8b051b28755cb76671625bb3090880a31dd26a9f431ea4839eec3d13b974b9119eacaea7f7fe464f7228db452e2664a3919a6a7d4eccb73900190b77d11dd816a31ae56da367309f606745d4303c135f868af5f77e0dd955f1d66a8d17ee865483bc4b832e68af892a8168eb2e2cbb3f7d369be4dd992e8608842ac895306e830e6fe68019a60bf22a6876e35098a628ea210d752e67cadc360955a4c21965326a5458c01623eb60dda8192bb5752a437edaaf049da567d4c378f342755c3116f0fa4bcdbae9d9f6e1c1d063a7ea41e0c8f4b084f9805a507c541487bb672faf461a446964f40801f473fca133658c7\nSHA3-256: 46d72950c6e5563a5d7e7e80cac515b464e96508a1b392bbd572ebdcb0dfa301\nSHA3-512: 447604c5a058c93b71cf5d714a34813335e0ff2be6236927328c825fd42d1d5611ab8905d839b2aa27fcc788035797ce80f50234331d4a86df2ba807ade68afb\nSHAKE-128: fd5ae52623cd254721a6e1ad38b4e0ca84774f0d19869c361ea68f4c6eb8e1e915cec793facb4791b2d59ad6d79ec49b831ad33dd5c894f344be2b0ecfa78966021e008e4cb858ae3a72467dbcafb19fb3243fc47031f57f72569238a8c0bf9ca583accb2c44ef892e33717d9607c690214e222de04adef490d05e6ab948fd2732be828056d77b6275c74a46ddeb05a023933b387863b7f2002ce7c1e69cb0e123c9d34314bbf87a0c6e6c49eb4b385ea93bc1c2c1024b6ab50a2985661ba6381257ab9ec0d0802eeba83582aa7271d09063260d9e06a3043f1cc319ef7c3d07455852c629cc1feb197afab8fefb458b79045d0165cd231795816655ed1a9bf2f6684d191ef389cbd729314955d7447c4c4355213b21cf075ed992f9afca765c47f6dba333085d48084268ca144640ca7b3b00e540966936e52a0845f4063ac739f5feb1463b3e14eefb62e882f708b2532175ad5ab64ff9c8bf9b4b941ef57a8e9dab350db8e59f6a67592228210fd3f2ab57156091d7a4f294a74738c356fff49df7ab4bc8ebd0506a64fb4b1794421376cdbff6e75ba216e5d41777471501a13aa425891a708e27f1b8b9318a0f2ddd3b9718d548d727aab9ba4e143ac451426bd968fe7e84f4a73f6c469cef0ba4c74fc19b27f965e8080fa6f1c681f8f8073da572e42730c32cefb4d9664c823836349666589e9f3b228598c45ba93eb4\nSHAKE-256: 51dbf26ee171b9fac8a762ea8371362b599ea851849e0bb3dd6140a43842c2fae6869944be86f4f21982e08ba04cef730da705cd920662bf81c39f61a8cfc6f570dc01756b3bf4f131780bd847d9cf63e461bc5b7ef1aaae4821813897da55e4fbf38b1d3433f22429a8b08ca39933821e105a6fe9ece4ced6ae3576a14b1915f3825a932b18cd3657048816744bd8a9bfd3de4e903e97614a3518f1d480903a9894ea9e41055790621b144631f185fde79dcaaa382ccd31bf88f36430d9a7a2d7b2e358c9d3e74e97c870c06eca058e0b3e654d2207a2778de2c373f024a336ef2f798d25d7408b3843c861b8be1e3290419efcb3e5c02b3c3ecbdb00dc7f7171638490ae3b59b8b024ec96ace522b6f236c7f2aef6b02445ff09422b7075a29425b5c5ff3dc5dfb2ee951daf6a8b6a18eae8c95a3ca3f24304aa6719e24eaf17c558a90fb2141b2f76ec9fc6deab914e6a8b6bea73cca420c96fb0f59e6dea89408a7c6fc87a3639082ad0ab075df67a22fbf681c16c6209c0d26e0b9ac249a043ba15b9af2c8b04c81cc70f4d793b044fbe2fc87cb2ac56e9128e5d718c167a5fb784d82ed883e1c6f7b52b0356c84c9c7aa48930ab74497b40915efeda37a8de37b1d741649e3fd0e5f5301f26221ac8a83efa12aedf0f6f74e097662343f1a4728bfd4f730a154fecd3baea2c9bbfdb1d2ec43238263a8c3445ecd56aa5\n\nInput: 311f729d490d2d2a1301551e2004f61084e3c8cad08d57fd80408603ce6772ee1f89303079baaf36b6be884be33501d57266c63fb556967e989e6c496b27f1a93d", + "0e85540adc16ab85c552b73e4e14c51d081807e8763849b3f61011991965e6b46e0aa644a8d3e131b724954d72a0a3e9eeaaf6e34790c48175e597b7689d8255ad030d9a2567e10c1e896f93d5329975515f49ecd288f4ca84a88b2833ba07206d08272e42285fba5149a13582f392870f11d254a515b6af13ca17664036523525084c26acbd59dafe8324c12b3ca4ffa722af9de00ef08a2ac1b8707a778bd768379798b1233e14e50473fb0a6fc37e8379597330812355d0a9b8dbb43aa915cb3fa97d97e871987113277b36b9f6094db893015dda8eff8b2470e82913e52a82c769f84872f9737e59231270bcdf55ac8d84ebd9157966971bc91a9a0e2b5d1b9b6b3380b2c50440b1a627a8b2914e76fcbed0cf73687ba0a85029e4cb1ebeac4c1a22aa4c3c31835436b73d87eb8b8a34d4f919f4831230a6bdc93db5fade4ad066aa3f413faf58215cc51a1c56525efe4031cb7f77c29616660a36e1f4bf28d7d9395d6d4dc839e09cbda9\nSHA3-256: 2ad16246e73b208c52726f78a621a137a26bf994c5e85f9acaed209bd6fe29da\nSHA3-512: efcf452757b25af2af7c5d078a6ee4c5f9153df85a3659511ee0b298b940de4694705b585de505011ef1f285b4b3bd6bdc828efd0298694abb9e4c676cb79821\nSHAKE-128: 0f95dbb3bf82ea2b1e9d651a4eb888f4260ba9ab8040bf7fc9723407e0231684dea0ce263f6cc5cffd826f08bc2c3eacef4a13b7ee4b0654645352136be9553e73473f3f8292f74309693fbca1f8dde8833d9528125f40da5dde47367b972d6a7b71efd95d415c926ddc0dce2433d054fbbc2088cbd58e3f335760b562a269505dd043789addefcc8fe7048a9e890f20f5a2eca48241563475bf63535c01ae54b4cad00e7dd4640157c834089f8110ffc13ba41bfda600e9ae9bf879588d7d2217c35645781d8fed66719d604080aca9c08e693a2eaf37f349aa7def8bfa4c9c21320235cbf19872d7f9bbb97905487fe2713e3b2871cdc26bf67900261fa83f0fd21cea450155fd125614b0675cec3c50f07bd714ea64ff9e18fc564954cd14ecf5bf136b17b3813a32f88c064a22ad9f14203723c3d029af1265c7295a1807d7322e70e883eacfd3726b555fa87e8aa41ed570a818a8570473ab3d12a26ebb18b9eab20f8f3283f20b69d60b9f8c2eb817e73a6ca7a65fbcd63ec4e83c02ac386392a94e84fce80fa7940e030d2736fc160ae9463e86f562820d003075b32be9a74f6dbe8228819223217d9fc5965d1ce4f979647219ddcace0f244378b8ccc3d200836aaefc7a32895f763c6a106321ca6b55e66b5c05acd8c5cbbf310de9f99b73746a9cc9c41de4ab9496e24007a234a495755b04e130fe568db9289bfd\nSHAKE-256: fcf8f7a9363387f9132262031c42d0937b21c574943927da732ec62623687c6efde62e1ffce359a27403385930b3761951e4bdf34905108c16145c3f9ec868d42a5e0ff438d26392e43b435ff286608c3b003bcf2c181babedc206d2239cd018b322c43860af3fb09cc136e0f460e1d7a9f95b3f4a0e0500fd005e8b3ce5c3b349ad0f0877815e8a8c9822685c489c3fd72e708000d737ea80cb213d5080c5403bec71393bc26423984612c6c0b7d4ad9038f5a89f839bbca2a15509d7be42fd7c3de3f5b60fbc7cf122b5e2a9bceced23630d543346d882b6fffad68efc9dbccba48ab87dc0ae1ac50075ca71dae039b39d9773aae6979320705e4418ba761d471b5c2cbc0ff00f0540cf3bd62256897da29a6454c1aab67aa5e845d02e7915e755f442dcd125a48ec6813639648cbbd993fb39a45f663bd8986d6917b59b6a8773c5510e76ac353ce8c6d62abc25674752aab11a68e0fa5f8df29d6372ac50776a2ca6259a423c3fbea61e303ff9a34391bab1c2417f1c3b215b0d0cf70fdc1ecc3ca4079c6e01a6863ce07668df53fa4c5d8e5bdfd020a39622e76bfe36f053e5c4df3f293e6fa423d102ea05fd4bdd7f8941ee4433cf0d2116f585e9fe27351b49ac49c3c3d34c7e139215a213981d06ba4b52c128a121ecae8531913f77a996a8fda1475a4dc5bc3aa514e3a7710341fcf4f1e70cc7a466192648d23475\n\nInput: 6e10ae04b1539b6dceaa726e36637b772d993f8ba06de646913106c086ec436ccb8e353fb8e7f0dc31124c8e938e4075216c5fc3da4f7bbd77804bfac1d36c478b759a37070b8c48bfa7d1bf38f493e4c32b9c710357f1411eacab7afd66474fb7a3f70c13e8c53f2cbd04ff35b5bbf11a7e2c1884b7a74cef2c45f23a2ed47d8b5c71170e22537022d334c1acfc6a0c1e1158174776706cf874e118903eb445c4a680bbd40ec789b7dc6f74be6c2353f695cdb2ff23b07f55fd8b1fec265ff48d179adb52ef83fae6545e2d67370e9106a8147cdb14b0fd4cd75de794c5fefaa5a9b56087d3b69dcc706a53ab931c924faec3cf78f2a44c0739317e3638139e7679edc84e9adde4a779893cf577a33d370b8a48d07b1837b59f5fb83815451ce2d139de4f9fadc82ab82d8b997c9104361cf3ba7ebb8e001de40eeae35035f36d813b978581b6404f6e3ca6d282b407fe6761f570d8167f6311deec586722bb4d9fef66ee146b092d4c1c74fa37c6221c7839109fc10033ab4c00a1be8518973fcf5cc274336330139121c4fb386f343b00337864088ac5ef3220125394345bc90c4957688085aa8295893dbf1986\nSHA3-256: e29f57c73fc4d589acaec784664ea420dac6f881097c0e6cb45ad365a2ef4734\nSHA3-512: 6c19bf7aaffc9a6f28c305acbb827736b688f65dc407c830d2fc5d66d7b88ce70b6416408ae797bf4c1896dfdbc3614a37ecb27d0467cdd15ff4a31da607db71\nSHAKE-128: 1ca1b3440309fa17cc879fbb89b609dc8fa95bf0fe7f1968f91d7f7d2c36661bb8e5aeb2126169dcea1411e0cf052ea47db60cbdd68a1c76e14e58cda263399228aab409e71ce0bd4740e19a6fc7fdd336cd19c8b7e2a818ade1532a4f32dad85f680cd06c8feb1a47c30ffc83c48798848b5940341eeabf20567ac3f405568e6ea2dcbafc17a60268f906f2d0180d9aa4baa4f346726ae53d08032fac2b1e2ef40f76dd040481c83ef88dde8cb03a650498b93a6fbfb8360a385089c3528929a3d8df4df1424f49f386f179ac3a0d7b926b5a9f9c490b7b9070335d507aa77406728905c7f4a9edaeae90e8a0b27a885e727b3f05c1dd31934911a24b4923ec8d9d17d4a7369fe88b8712544fee0777a72a02e99136cdfe8e652eab772f49a0cef2abc9a3845ef39890146337fa3c644ea8a1e758e6a7a7a168f64860b38f6e93126f33abd46b4197cd41defc203c69e8a2cf078227cc1d3f229d747442b30e9598da06ee281c8f1c88751dec0897b9c15bf9f8578d3d73925eebdfe1275849326f63ab68466fb4b3b4a0c7bfe0118638bdd05da217a78bdb3636e8609e6e395e3ab2d63f575d24885884039c4b1699dea3d7afb317676b3f71ed06adbe30847e4fe5efd29d5888986e82f020e7c252cb8c887c8b80b01c487028eee83a0521112a4440fd6cefd071fbbb5939a6be73b45c9e6504c28fb6cd78df9fbaa3a298\nSHAKE-256: 4feefd54e510007102ec356043d442aed1704ee12402f29ad2cf653c2f1f1d92ee32e31c8db9ef73fc21eb3f0c0bc25727e0c7fdaf79fa051be3979dc12d0584e96c12bc222a6b6df4ff468e792f15d6701be48d0e8a1d1916183ff8d4c95ef4e5ce7852f22ea8e82e59c0964b1310d6e48548b5fb66df8211b31ed7c963bf5b03a86d04137e9272bad48696465c26af0e0a0324fcb5c8bf425d2a33db827ae7cd17554b01cd848b45fcda62e3b5f4ddda2abe20ad8d421cb9b2eb9154d937172f523e540fbda545228b47dcdbdf8d661066f674cdd8005a5dad917d2de0e27572c1b934da5cd36642739c84e2bd2e3ee54ac0a700df72bd1f8fe13158794c36d1762ff395a3ff83c1f64b95617fa0b0e4a66a0dc92679fc4023580d25f0e525c4bf4ee76a5712cd21c0a2b77500f5b423b0a0959e97fc7cc0ac3c71f1d3bf69895412f83547073248c2a601f890708075fb561276dc10d2388443fc2e1df7836a8252fcf10bd59ba692e5b9e39b9b53a812f78cb09b4cfe2dacea1e48ef7675c75c3ec64ab053209fb365ccac3593444b234633b3c6147fa27871bf0b3056af6fdb1c30e6551e4c0357408c49f8d7f02c3551e576b897761c120c8d24148f2c448350aeb504b834bbd08c05ee40d9003bc873d3a6f9ae28171ef098e4172b4e154b4982073c24aacde5b84b15e0144c1bf674b35eb897ea8ddd2f3da69aafba\n\nInput: 890817ec343f0b3675336ba8089083822d5767bbbeef6ab7905b3a910b582c03f64dbe36cdfadde5c20705fb1553687ac193e22f5cb953d47456fce75bbf8c0bc48f89b57a875eb69aed9abd676ada7be12a04d169e96e75fd3defee9528dc000edae4c99e1f1f2d122222563cdf3f9c17fa61d455cd6afca6afc80a35a7569c677fee4becfbdc1c8a4b627421857b05d5d9d647367d533582373f5d6bb1d7f625f342fb6f2649bac416a4e5686d0b0e3e6273b3bed5d21322007517fd890c4f27947d4ad53b64e884e9b17f5b69fbc92b3af06f949c0de27ffaa63a27d349916e4f9d85761756c86986aa02f8a72f55ad0ad833b517471af562c1fb393ab7a1e84aa7354dcbe55d93c43b72aa3c5bb484e5aaa789ea71c5cb77fe1de0e53c0e50ae64339aaf68056b0c7d86e263a5c2874dde7f1fb69f278537a18f121ce9d5e2fc6c548635229ed62d22b09cb02c19a38931533ff0958077134125b8a85b452f0046b239aa95872f9bea0ed05010ca72a6782e911a7f87f5b6f3993914156220699ca8262b024b3a0c8a3de59c6accae895e9f79b4c518c22c22b22f1ee35f6594a1972fa76a5fa31dfbde28314c1f\nSHA3-256: 2a92f178990c4d600d414f3c0b9c9ca1701c4bdc106e54e7006913e8ecca8106\nSHA3-512: 470f2c86ed49a7400257f7482aae0ba1b2be238e79b18d809d41fa0d8730cb2aff01720d1e971bdf6b9fbc489e005df8e50a3e6134b368c93e7b64d1fc8ba7d7\nSHAKE-128: 051a637a633f36e5d219447f55f1ea0522658a26a968be5889adc0d936e560748e86e8c0b45e4aed240fe152b85dd1e28b52ffbcf3ee177c89cca8c15fa9b381e95538b26be54d92bf148b6fb07d54bc551022664c701ab78cbfb42c916f3c7f06ade83bb7b85c0f53987ec5c44b8912d0997814d8316fac2e0593cc53bafebe4f798171d488159002a455b85adda65ca3a83fbe6b9d3f173a100669ee4d9ddd47ce8cedc940faad1fed6ffa18e011502f5f6dd517f4648f4016c1956889d4faf3b46d58dd51717316fae114541fd534bda877b222cf9e55eddfa89b80afa709c6d85c071963e257e6a6fcb8dfaf54ce3c775330b9ad8b129c63e802896a498e5c01bce8b2f71a9bda5fd8c915494bcde4a612e3428a045dfd57647dbdad12c7ac8aadde673c4b43b75eda8ad27ae954b2524f475dbe520a08a696c48f2ca24c769aabdbe3525cc99a38049da3c8ae230203d564701354219da356a844ee9b0bda9c90ba9ee7ae26066acc7134d5b8afcea4ad0458f4bce739f451cacdb18bf8a306c3045f3bf268981db5f4deef42770f58ad20699f53bb043bd222c8d3b484d61e4ea3bd8b6297edd36dfb7fc5e3d0fdfa115a5fd52c4041179adc5fc6d75eb63cc0c8b4b33f984b1d0f72", + "accabb7d3a1595cc86087f9d1636b8dd3edec1a22432f81d99858810892e739e76cf477c7fef889d96c60cf953f3b1d00f5f2583\nSHAKE-256: ebaa5415440491f02d5a8b055e1c7914f9d091c6178ab00979e544c5cc69500a8bdf3fb582e9caa1cc1e50173838283384272bf8a65d770318a7f6b12a08d3464e9951ecf3ab7a5d62bbec6ad7176c8cf8f18325da3a9f3b89139413b640a58cb793936fe2578a98b51d1f75520a81185c0b42c7ceab32e0cce63c8bd4e7c9953a9ca0c384efac3a219acf1cde839c29dd90eb67cf7b251c9af897b525990b6cbf6a7d7e76f8fb46c20ffbc9efdc9b5e149e78b871aedfb31bb633b7489b31972365d7fc4a32e1f0b5c50fe11039e0833f445efc1a05c9651677672d35df9bb240a9a27656f04de652540d1051bddd7b19a58d128c16c14fd76f38be3130a2680262bb9cabf8daa3c54dc0cbce905f2cb72a9ba009d6e1c86a09ed613bf9990a9439d1146c988aeec4bd614a66024ade5b865ec59f47717233bf9c0712d7f2ab8e2efe3a8b59e4987e05b31ab7e75a135096e0306c3f46eacd114f38b4c694bb64b6f860bd3749e5ab5aebdbe14d0e7c0ad4f0e152006c5e2dfc48483a13515488e4c462abf8949e5ece3d0ec983ecff798e8ff29a78bdbccb5fdb90060d20608f2c8a51dc7469485201cae1e9c2175d9471c704553e0d3b6d3d11e6ee281731d85851e8b110f4cf67f43be731a13999392f3ce206406f250d39eb5ebee8c4b363b6eaaeb1f67ca512a988ce736f47e3b9c888c8ea5cfe73ee88d9aab32bacec\n\nInput: 325fc965eede4b0c81171f6418f5dc2f9264f6bb4d2a84800abb21d30e454d2372e5d3cd65daca73dc115d1ca06c2fa96f7fb70399aaeea6f70cefbfcffa16227116fd0677d7d8f0851871ab0eb820d4075f1b7c5c11b1e7584a4a7840af3af00b3ddfc25a43410266237ecb05930f295b7165a576a5a1f726875f22e88c96d272844bb63ca117a4fdaf1528ed93066e66bea38ef207285eaf1bbab01f02e842b2231b8f12ab139cdd2fd1f98af698b936fca5d7cd622f8eace4ad276b47a2620caa8c6a8726202c9923ccdffa27cff3d4a1f8d3425d727a5160ae3b1076f694ac683477e841b737c14fc4759b3f3fdd13b2f4c22632d79e598a44093b0d434ed97fd810764fb26672ab24402def8b49b035cf0e0b6b059451ae4c330ca54aa7e8070a6b196cec620577f4eb6707635a0fe0373b36a25c4a53702438879408c90ac34622e74677041eed7418e904d7dd6d709e14400e660b459f75c1a1b1c3e1fdcd4955d2fdf676ddb8131085165b94e2ae4a9bd0707495deffcb2116ca3f8e54969f8361b51122926077a6230ecf69c02e28a25aba96bbb43accdc92549d09b9b42c849f4af85e526d50968eecc16aa8\nSHA3-256: 7eb14d40ae231c9535b0205caa479140d126b9efe6e85a31a7f78ee015d12052\nSHA3-512: 340de0b738b6bfa44f1405745c5b686318f13cfa39f7d50eca45b0ef636d46f57b96a162567d9b026ce4fd35f631ed0cc3742b702044854049e8066c4bfe362b\nSHAKE-128: 45315b0a7518ea8e35e79b6453abad02c731bb3ea27e2d508cd7cd4a604c37345e18842280a26fc328e7af89464686b133167691eda3bea6cfb9d1e639e0ff46087d12b0b6ef2816f909b8f52ecb22018ae70bfef7b4782487cb187e46699555eaac43a2aa2e1c0f50cb515a7524d1116fa98df741b1a6dd741fbafe116052f7998bc77018dc18ed16eaef5fa0fa95caf9b399f36d12fd592c8d125029d57e3f2920ae91b8165484d4d7ff76ba874833896af7973338db93201ff5cad2d623ee8c739ac2a5a39598c7b49cd347e491b203911ebc3948d351239e0d122787d5507ef5d5df33b49a7b39fc2ffcab20d860e4aaba9b3bcd6e78818cda1b073f641f1b4b8417d5506c10bfa2304f38059a32da330a5d902da1f8b365cf50ea54b740b1fb60dee60da0af2c1be06a1665125ffe227be6fdba3b818db1f36a6a43970bb17d3482184dec43b26277bfe4cae980d6afc5c3f754f17b510d5e570876cb7009c13630faa9967a8b6edfb9cdf537fc65d2a5c0f20f42dc0f157bb94492268e13dae8be28de6a01bede3edff3c6662e4495aeca3158e9912607bba5feb39267a1689435ae9a20ec914b76eac50b91c62de7cdf236fbe9643e78ee17ab130f2b7ba88a0ab2550a086d2b4457b51ba0da1929370bdc17ff8deeed17afdc7779fcb0319dce077ef52e14d875d1ed20fe1440e4d50572dc05401d0b65f180aae5b5\nSHAKE-256: 64d8011e69a13f5be2841050b63ffc3263a39ef7f896d79965e1b201a6f3b172760dc23d644ce822a0dd3e3a1a5dd6ddcdb5278d2923416640b3502e46545fc643c50cbb37a0d8ccbd93667fc093bfeccf04e42aa183e3d26c99a8a97ae8787dd07884a327baa49fe59ed93797ade9eb9de3a5823183a33c50de24188c90914efd654598798279b615d6319607a247bde4c9dbf1842e7eeec429cb3f534aa8a0ddcfc21fb32d4c5356de361a38ccb3bfd37902064d5d0626d37abe11a50ed56bb0ba1e77fe0483582a96bf816ceffc62989fae306c0dda7bd3bb5b6f83725a4c27a871a7dcd2257c5af5dadac6ad125f915c166e75f8ba469d1aedbb72ee3a49fd33dbadfeb40e124e1745d5cec8c2af94fc1902164648ccf8a2add8f672d222ea0d3d35580d919918bcfe5a8738ba820557efd754688c4bd342fa4a4f920b62b8deae395edec3173660cc2ccf9b5003312fdf4244585a68ba152de1c421c39319ec28c1c735d3009b10cf07812744f4582fb2cdf1c7349156e617a11be74672f6fb80c47387d88b70fe3c94e3016222a2d27aafa6cb80d8db90701b17d48a1b0fc6abc6230fadfe1d0bb23c1fef1de23453b73d2429761da2a70b5e784b4bbad30769e8559f5d265f542853285733e33a88831237f728bcc776afd30c97d3a1055a525c771d85682d1cd3c696449693d1d3792a404c3c213e87cea9ca969098\n\nInput: 53da1f33b72ad028900877332f0512f80be8e7cf565557e2de58be31bf976143a00028069fd437db4f402013ccb9ce7e9157ac8f39509e0b27fed3ade62088e188bc26af0a75ad0bf99937d6bd8f68631d011fd956c8512a41e512bdde86329903ef9542a0cdf6de92d07a5abdbd5cbdee63ce5a63ab109535edcb3dd5890e92d3e44e79e94d1cd9c9328b0507f32c5503332b4816bacbb38e7d6acc7ba81215236597b9fe2652cd4d25820908621032213f4e68b88cb32e98e10fc4d243c0d57bd252caf12ededfd9a283c3fe84ed25638346fb0878090c35e29f807535fb4b74006262c586d98043fcfacce1515327585d3d071e76021846544cc54e1807580b1c1fa2c86692e34a04a74d169478b02464cd911d7fcb928e0cdf941785cce46dae566451687cf4c3a8a9e41d14a07861f51c552269162f959b22fbd6b32ec7cd10b0308167bd0c714c50bf7d2be0f1512a2c06a6697efb65435b2e939771d519c12a11b57622fe40a3f08bbb8fe176e56bb58d9e33f905b8aec2c65af5635da70ab54952d89bb9c993c1d6fa2b417ab7ce8cb700c94ad61fedec4a85f173f896db043fcb2abb8b8a911deb64e276c5c735\nSHA3-256: a05f5a917194140f132b32f9b3469cd80277fa919ccea96879486ba5ee91085b\nSHA3-512: 8cc041d8129100c884e407453be22bb26f76fb40948d9a9db301ff1ad7d3be77a8998715cd76fc6545d5572962eb8305f8af3c0421175d23ddafeda7bb6cd3ae\nSHAKE-128: 6e84a8bb06acbfafca75faabe11fff24c6070a0b82cd420c1d92fdd935a0f047b94e26648be69c632bdf3aa0d0f52f88e1eefa8199255ceb3b13d15a0fbaba74aaec8abe278950e7a72f9f482141798f003093ee648d58c464495519595407c67d9c198b974c55392493d217dfefe8337d5d4c2013f958b3521d13233fe11ac66e7a77bd81cc4f26cc6f4fe8473e3fb92d7fefd1faa20adaa4559ecca22f84a99ad97b68e9be3513257f47615a64aa6924f2401d051989eec4452a8add1d05ee1ba8a345358119f1570b210ffb453b9cf201b166e76843bd5677b146ca49405e8d8554cde1763a1d7f9d38caf9093880f940fccb1996465c648f63fcd4dd3c41e6a2fdfd69f86d3440d7da0229a9b6a61c7b0b4a329204a35813b37def776639e466fa7f63055dc61e9af53821953874122971ec62ffeab67f769718eecb24517473d0a17fb25cd98604bf6f708eb0a93ff4275328d97a65017b97d3b824399b7769e5fb10162c33983bbafebba282779e962205ae3ed57b892dfd0b66ee3b8ff47f404073b5bdad2e42a12f66860aa78db2bce8a18e34431cb23af0ce599b340cbd764b90af2df856072b9465ee26c9630bda052b0133160bc7d52308504022425fe08844a18e285d28e7622f4f121ad69214184d792a5789cd4d3bd20b55d6b26cb3c6a4d9e223f9ccc848379843474a67e65011334b70a4dd9569820b2994\nSHAKE-256: d0a79b4f8f2e670ffe564b4ec2eab465f70a8f9b0f8c721c1a55501442968d64fd79e2424c1d275eda288d90eb0115098bc57297dc38d7035ebc6e699dc33c3827682b8379e2e0ded3d7711384c17f07d7746efb21c81764acc6ce4bc9373374c01249c920677960be72a45b795fe22b7efaebe9608f8e161de62ba9187d6cd40c9645f01e3b85b12f6b4855e9b3ab0cf34af38ea7741ed389794c972cd2935caecc62d4802bb619aa629c3458f8d78c3f911497fb3dc6ab71831745c25ef2ce2e2c27492da7d8b1a8dd1ab5e580fbe1a07aacdd9e705e6555228a4988dab17b51843b849fb132a3256f5437b75f6e3d8ffa6be220586446a53b6aedd3cad131aaa1960331a034332465f7a02dc16b82dd61620fb4d02bd42f0f913e579fd57bfff1b089109067306d6e6d874ad44eeaf5bf72ed4eeafb235703b8386748363a89411d18e549ba39072fcc64151397f5dd0ad9e6518d9072d539aea79b4cd9af1f4a7050502149bb9091833d383e0eb0a254356308d0c7bef497dcae2b0dd9abe4590d480e3958bf976ebf877c4c4bcd10a609a705a00ed4fb0c64651c749fe0ccce0c487e420ffe19939facaeb24e303e595ac7a67a7938fbd47b1e554f5ded74ef5dd91f813a57385cabc8fa47eed53b4eedc8fa13daef08e11d8834d85a990129be5864dde91f04da38c25d3d58470a7bdea02ac0f6195e5e0983c367a3d5\n\nInput: 004a5ebcfe6a71c234a240fb9c60144cb978168f95a34b4f9b5753d46a6e7953323621525d7854e1041690fd5a1a57ab5e430a6e608edf2f9b0ed6626468bd937249d7d79922db43a935af1bc850a038cb7ac44eec40f87708136f114646d78650133fb3a259bbd8ae2836059f7f750ce73b3de6f819d7f9f7cf945b9f791a96cb88f78c46c2c64e368f4f3518e8b5f0a801a909697cce8a57c4d337c33a99b1dc9628c743ef435fbd374da935a6706524e6c646f197d2d2487abc37f4534cd0797f94421cdbea6fac2470be362a30497e0bf11c3e2561347dc20ce7ed6e3707a048defd1ceb0ac1bfdb853bddf1f2b7c23c4ef4bd4ff3ddb0054fe64b573ddf5988329cfbc492326022a9df41c7c7ce7bc52a6bd859a2a96001677ab8dc35addc43bb2217bcb8d31fb7621bcf81edfd45627141f494ac6ae9e5328e57bf2af3c1ecf3ad77563ce4ebb46b6b7557e0e85418b441c94a891af67cc1fa7d28a59afcb5baf806eb385", + "86b5eae7c5e6dbdea7fabc92cbfdf1a1b981d57b415541676c3ef54c261212e461845ec02c12253f7a1145706c89d08d80806358f6886bbfac89a3c3135b08f20998becb8acb220ec177201\nSHA3-256: ae875684cb784c3575bbfa9e01203dfabef996c66db5729061e86189385c6312\nSHA3-512: 92a50e4dd0eb994ba3fc0961d7d4d854e24446f2af7632dea049a39b3d144d412e258e4167803623680fa62b05950ffd5cd8eefc6a1ca84409c7e8bb154f0b91\nSHAKE-128: 7e6e968e35494e96b881901745f70d04ed9790f9d30aec498a9f3fd5c1b22fcf18099ca4feabef3bcf5dbbdda252a8af8dbe72aa0ea90d5e01b889867e4895ae2f0d958618ad531dc3da5e76d672b1d74d915c2e48b0b58d23f16b3e2f0609a2972ddd0af3796dbe5ef12b5d3cb215d48725fc658cfac56b9148a508dfbbabc601c06013074f389026e52afd7becf49fa2304b3cc818fae59df0b4b17de7330b217f137f84ffdb11c590dc417b0a2bc9faeee3146d436e3e06bd5565c636cad692d39c51f8b104d126e0220846e2904f4b293df93cf0d835e848d1f3d00bbe743401c19f6fec5c9611721304b8dff84e4b6a9c1ca3a8e75f4212bfe7263c9432729bc7e50dac8fa91aae038ef2e01063c8aacf23414876956aa7c09563542a66d80830dd560ae9a7051a66c3e8d3d9a3011157733ddb61eefc423a7a51c0f8066b0b02aa1e285908f1197b69ee6878d7eaed509063549f3a4efc532a1b53f5123418348c4d85f2a5319bc382d59a3225af9102b943a7b65082c70e6a194eace5abff0ff58350229b97c3a1a6e69caf67769bb2b9b29a7056d5147e3d440f396ef6941f0b4c308c43deadc1826061e78501d6eef28ae1fdf0ab9462c0c5e77d9d966c54cc70072d4a5d2d3f1fe3ac6cb74c4d852dee97fa013c7280066d39d840c8aba68365040643766aa7a5663bf41671d36d207ce74cd23b71dae234310a42\nSHAKE-256: 76357e53eb1a19edbd8a0ef55405ac50351168ff237fbd99c0887d15f4dee3ee21ee794bd5cb3edfcb33ebfd59e42c3ba86aaf00492d6563f50a94ece8d23c58a66eb69aab50337abaf7eab70d453f8c513a1a6c7006fb7ecc10cbc23c47f92a66043c512384e9d9547ac3431355cd62ce3b5dc1fbf00a89193e8d470ec6797456186f7072d7712e87a37ff4d56fc2098bf05ef1345f2527864c632379fc471877eac9d88e8b8be4d184b43fd34c39de01de99ab46fd466662eeb3af89d22b27c2e7254a5bf7271c57e8cda7dbf4e82aa8f196d021013eb25d0e00f04a4bc95a206b469877558972efeaf3bb23fda409205756f7c878d6c30c97fc5630aa8decce0b52f33caefb27780a2693234f5c70b3f903db53c974cbe21cb03df67bbccb39e773cad484fc7b7261be3c107ca1fa4eab64cfad80135707c2f5571c1dcc80bbc7df802cc2557d0155337457f851e1e9948161d738b322458c727fdbd5758fc3fedba1840a1b7789aef44209fcf8a1b96f9579aaeb34c8bf5299dbc85e635712a1df6e8b3010b1f67625813efe49c2da28e3f4c634e2fd92925d780caad0b3bc38124aa1f8ab6c2646efb6ef774c66bd8e47155c457921d5fc4e9d119c0315065e449273fe5cda8c8495f608d8e5a880e3b03f1488adba72a7a314bf749736d3e6ef2edbc793c63b16c574bde1736d2535f24acbcab5e8be65486aaddcf782\n\nInput: 70692ec1adfaaaa9d1233a75464edb1835c26dac0fd2279724dd528945d80c0806f1d50dcdc2f761066a4ce19599cdf25ccf7aed12662a4c0613ed57dda5cfeb9cc12be86c233bb09b3ab5aee3374eae76b4de4824fa27924b9dbbdc025eefdcbeba5893c9d4ed62836cb6c8dd2c38278109f74c2f665895b485f3b5cc4673657210c44688e89360bb6ecbb341998214281f898ed65702b6f768cfd4b57aadff3b7f7ee548b7f72d8f878b61dc4efa5bb977ed08076a8d49d3ec0e26683e5789f95a7ef882f90c6b93e02fe5cec7a71dd9061998472888e3b68841ada4ec2e8bc60765cdacf3e2acbf4dcff2bfe505f0adb6f6f98320af17488579b54fc40d2664bca96e193d240a8efb99c189e18dc3806cf4add5b3cf29c31689c2d91bb98b8d5ce274db285ee99b36feb49bc350b00deeed5aceaffbf211a9b40e70333e61571b21b5d76eac5bec93ac3b51ad90de10bfbf8884ce6c21f6acd75a7d9de8bad028cda496a5cc94e136de32d1a66b5eaf2fdc2a3dfeb775569ddcaeffdcbf7ed201cf131550fcfbcf811918042ad827666beb4eaeb4722005140c3de4e8988fe24d429d6326adac8dd1cd6b614ed9de084a49bf\nSHA3-256: f45cacd1f4e2b4a16f695e8f84f98415c9fc4d075a59d4a3301e9eda1fb11243\nSHA3-512: 50526d671c985252fd9a31db60b0ad496e0845a0024db1797aff00db53cbad30072732c14bc488dfeca4f29bb1b38d2df740370f2a69abb59a437048e8a3dd42\nSHAKE-128: 964b0be34277f268dea4554c573b5c7962404dbc1e02689b406ba22b8b7a947d9d9fd80da4e06ca625128dfa7acd1c26f05665fd5e40bca1758b3a332b643dd8218b0e2b3e19ed3cd768ed49cbc134090adfe874ed559a93cdd3a9cee42c8c4605df10f71ae4ee58c4e7e91aeca5ee6b41ad76c7eb74068cf2fe3eac82e85682e1e0396ec48389399ac6dc4aa60984f35b739f427a010282bf0de38c590b8a39f6603feeacfd6334e80efda7a8ca05456cb038c63f6a323ea04e3cfab621fc948c898116253888c9b97b39e63c5d88104eecd273eed1cf6641937a86926d7102fab775c706cdeb21bfe6fbda66e43e154816d53ad58dface799141c5d7d143f561f8f43bb8e41c19a806deff2272be65a75841218ffce79b4d0ff1c250c678cb017e367e037016c5cfca2ffe118e6ee0df3dae6bc816927f950f8956df14c038ebcd687313757d6a8adddf4438e3f02667cd391a12372591d1140aaeb95450a34d777bff276d80d748af96cdf84a55a6f4a69ec053317f69fddb5afec6286027495419e371a0c2c69357b2fdab6e9e8bc592f351143825a752276bcb237178b92b9b562a7efcb6275fb8421dd74ea43001b8392a464d37508b755529e8fc101851b8d7a57269c979ef70047e874b67b196110f253c18f10faa52edea796f5d3ef54ba664fa74230416d668789dddbd66b03b2d1b49b7d92b9278e77d825d8500\nSHAKE-256: 3174c2beedf485f0e7de3d4afa71c2ea92207dcd3b29c76626328fbf15a0c8ea0121a143c3b5d6edb12aba1c3af20f2ecdfd475c5e27e9b998b33e1fce1751c39df17a7d43eabbb230a51bef18c553ea70238616e1da15c5ee1cc8f21fb4f45b018d549f750c890ed5147e4a2b1f4c4d403ede330f86fa83bf0ea0fceff1c5abe56ca51d818381e6f4c631f449cf7fe3a73ad1e98d1d7453720e64ae4f0b9009a8ecd8520d8b3f07703ad83fd6bf681b43494c8b1bef85e131df76df174588f093ceeffde9b642955412c0f9fa59a7d4abd32aeffcf0d8779effd7835e2842393da0dd519f14d0d89e10ed8d098570cc6b0d90f04b4a90a1a18d5f07f70fc1e1166917806d493cf9178ad5f5800f919bf0d0fa5f986d477007bed3f68c018b48df819fb1fce1924b7f728e482234a0d679a8c3ef3eb2da7f6ee2784b477571bbbd14fd198145f1e9a29a120ad6dff8027395f8693b7d7a0b6b0eedb78808fb69d593b310054ee44b87eddc2c51501c5d97788d67baf137379f75c5b32fb97e20a44aaac66490c6fb83aea56cb8b815fe5b956b7012aa90cbf23768a839041c50e64d80f5b86011b8860b7ccfaa71c71126dbda5c946841807e498ad1007dea49a0145ade669195d3aaecdb04d741e55c990821caa362ed261f901b7485fcdccd5d3b552d1d52d9ee814eb443d9cf101c5bbc051d0c29dc433630e32de86fb041\n\nInput: be261c10e37bf8ab2071e613db09d1c5dd1a4715169b89af024885b226c45ad6b731917d33cfa1119c553a3928e6d766db8145db612516ab8c61697a68bf3071178aca1355b2d4e3feafd5005674ba02c80b3fcd5fa4397e96db04e37e982690ccf4a944d29e0f72f130c5b4e9fe0c7ceb9a4bc119369792d49ccb75e2f821dc57801bc8da8d2a16bd09f0fca911bd7c39dc08b334384670031d568b80ae8002f27b3ca1eb99d8674ca01ed6289f037c3f57f67cf15cebf765ee6a2bcd1e702c26f2052ffcd681d693188cdcfbe951e29dc5530a2a1cd3344fbc6122d8a62a6a97dc0a1e57c76f0336b90c3cf17a60ce28aacce8810c37af1302e8d5aeb153adb65bdf4fcf930aedfc9482212bc7e20a6c5107897948cb777757668d8e1a6d06bb93102047320ddb29cff39c3f65ecca631630cce06e493d32d8c2a7976b08977e570838fb7309a8c0df6081781592b3588aaa6f25c9e4ccd8f62652af271514d0058cf93c2dd3e30c6f0dc6a8fd32acc669eeac9a8ae918144e282b10cefd7db1ceac539b2779f737ae2cf0da8a65a51c95a6560336444e7d43e9b22ef7b2d18b54bb91cb26b660f137bed1f369e0f5c08db62b14\nSHA3-256: c521790a233a269a553bcf72a94fd6dec012a6bde55d977660d302a4118a8ec8\nSHA3-512: de5701c82e392cf977dc580ab7bf0bcbf88f32f3397fcf0fec6f5b99abc4b4eafb33b2e1738c74e6d4322c3154ed286584c21839e65ab36c5ca2a01e22aeae94\nSHAKE-128: 7cae177adf11eabf6d460a5da6e4ec8a875f153bf8e74367d0085c13e7ca560db7d979e2852077a23ef526f20916ce1aa4bd10f18406e7c820ddb3b892551729e27d8ad47b2e86475cdcf798076bd6707d9b4df80f21cef6d1d0c61d36e7127b4b23f1c264f39fee2c2e3b828c94c04785e9a5744ce65a6670ae2c25dcdd258702c1eecd39a3d142f0c4e353f9df97a3d52d04c6a855a9b75ce8a73669cd017dc2590f6f3c630f86a20087bc5b1dee352f3ee2bc5159197451087bacf0a282ea211a337dbf5a9938577cb864d2a21b4c36b191fa36a63091cb0bfdc3967525ec5668d026400c331713ffbfac027a24d6472f7dc0e2008820c20f65c083aa2fc24658f9bfb57d865a6e7eb4fa8aff3d91e8544b219b0b4455382f34ceea089e9ee899b7ab301a02c1d5ac3efb2e7f3d4a2ba0639dc12e4e0362070753c6c5d6f71cc50a8dfe2ff6800eb8a9ec521e9faa191acd5ed6dd0bee129aaeee1797c3718292dc5fcb8a08d15030e83cf9b0f3d9c1d5ae6d7785a10c5bef64f2dbae674f0efea5cd107043198e8daa6634f5dc4482df34d00d259d09ffab0ad695a5347166059f7d643d5dc1467d9c3fbb8e77cf43d669d59129a1ffb88676a0f4c05303e2bc881efe65d4538c92395e24da69e1e6fa893d7389ca05c95763b5bf071f1e07f362846f00bc01e873e732945897d4652af835e33bb83dd2287af9b03d6562\nSHAKE-256: 8cb418f1b9ca1c8af122c9ea1ddfbc73881e384e2b4b3acb3d7dc9adcd7568bdf42a744add5a579eae523f109374eb55ed95193df22430591fa59e1faba2ea09c0c101dbcf1ad587dc71c82bfeaefd1f68093085978fcbfae52c9dc221d146496c8d9c08e06e485d879fa71ea535e8b7874f9b633859f8893e97235f9a83ca1f1336449c05477fb82f32c6d4defa811ce55c6b0b7f57c57c0122474f0c906a37488597390b208b5ad9f14296e6111090940ef0f2796d6d5c1cca86b83c1324989f4d22baf99d30f17fa19e795798660b8f70f54a9d7b5414c3cecc5ee9e", + "6be9d7c78a5ed296627bc8e436658c7c0a3644dce286afc4b2f7c3e436fab862f101ec904f6784ffc4b8ea8c993ec53d245a57a7bb7bd633fb2217bf5dc6ed8ffe1b79bf2aaa7f7dcd2c1adcd8e007e34ef6420237941f07a9ba825b9b07ba3c4b47bcf8df1c270b35b9876a1233f55a06579dfda0ed3f7742eeb572cf9668e7898da202ee50869f26809e18fffc59673e11d901a918c0c09973baaec956f88436e566f1075d60264c1b0c247c9cef6b2842fd6c15e1bafbe390fa9e8d312343e9014854eb82ec7299cf5689d64b31de3fa18acc6090e011d8236176fa79da74a9078fe37538070c655c6b1c95b50edd4647054fb0320a63a6f820001ca05c89ee639251232ba1e207d3388780458f85b22cd9f4861c22a79a00d3202d6278b3c08d6\n\nInput: 23ae66fdc58f09f355bc24ad89a041a9d88d3c2ac77496d18ec3b404690254012e7243da11328ff50b40d6a1cf84911797b67ee52de8ef306261092caf9f361e75c75043ac3dd429a040f9c21923d9bbb9281b5f8ca38cada35bd10bd1ec7d032a3a11d1a33a47c5eff3fd7fbd65b02a5f3a0572ef5df26185ace8a9a5714952b8653989154a692f0325b418baa08e6d617674ce14d9955a68625b63f9e4e0f75364a81b97fba0ebf738a65ed6c3847b9216a5e8dbd52418d9c568d7bfdbfbb3f2951199ecfb57dbd95b6669ab6ee92e448aeee48fadd3ea6a2ab5d1c4ec032299522c37f0cb493b8a1c72fe561af4961626d654c9ace39f1d89828ce783f62408c66a01ef069c8ca23830e0788b6d5065b082ae3784308e92b773cf8624188cba79424745cc5bc5e2c18b24f562dc7da40a1d3621e182b3e8b190004f78088e35faedb88791e7efe20255a1a3812080a66a6f6937733c7766e0d14d4d3bd98e2579b046204daa9a51ed517921d4894020b7d824ac9b0afe268352747dc5ffbabbe1d244bf77dc36b8d50e7bf00e8285be9d6042d71e82b432bf8f03d80ac46fbdae7172053250eea2ba01d045f7e30ca56b86c1346e\nSHA3-256: 78c2349e5e301a27982af0e09d74bc220f01d8b52e4169d2dad2729eb082a98f\nSHA3-512: f630fd47dec8ccf3a88edd9989808f8efc4aada7e7d585a8ec7c854d074573313a3e4b8ebd5100c0e3f05ac756ffd87cf3df906862b4200cc1f88320ce2ec50a\nSHAKE-128: dd8d67406cda912483a6dea5a787c3348d4cb3d0f78100cdbf14d82612cd3bef69661c9ff61fa4df77a269d4f194595efd20d654be78e6acdd1b303b7c2c4f64150194aaee2b0c5d9436d2ead3b2333faac703d6157d1c5ad34e502d6f1cb424ed914ff0df59eb0fa58e6e99542ec612d4d7ddda81ebddf9289b5ea649a00bf749987b25673a012c1a6c83cb95e983fbccb8fb65aa2c7694563513dcb218f3e3d88dbfaa17f331201a1399e1c895bdb66b4b20273280863156fba39441c4a04798bfd493f2bb6f94a448f03d4639407f39e191015e77a477c08dd3f35456d132e2b15603115412fcbcbe0e4693e0ac211b64fea24d356ad57aff1ac1199d1b2e81d6fe689988caa28516cee8b28bdb7f7b9fbe97c1609815cb5ae221624dae5d46a2fce58f68c5aefb156c0ba4285c8f054d05731abcc5b2b3ab688cfaafe26349afacc8b605f67a014688df0bf1ba9e55eddbf0061a76ec34fef6aea92229cc4f9be78b590071c2756230098e753d947a8bd767b5a23ffac4a696cd65533aa327d66383470025fd3f66f317eba56effbacb6e72f02da58cf9be98d1892b4d375fb59920ece36b7a34350f4145347d346625933a477a5a3ee9a80abb26454ec3e9532326c28bc4ae6d8aad8443f9ede5e285a3a5513fa84a1e77a2b9bbfe18766fe0eaec501154667ed0b45089d1c481a2bce76932f402f94b497b614f9e8983\nSHAKE-256: 8cf0e5e86015febf37b834f370e036bd9d54c3e94b9974016509139e1e1d955f146d7e5dba35a7f5b6aaec02009123855b3d2d575968c8a6789152a6cfd3051dfb2a33e1fad0f533a8957ce7bcfe248cb29d87f74809cbdccb6b97bd4ca44d95f970969bbdec03319c7b91a7439f4a3aaab033c592a258ad02c76241afeff1883387263d6ced88e23ee562cee255a6682347d14cd46c5ae3f66c195e9069d668b4cea6f5d46bf745f363f2840c99e466ca0e715341cc6c2113a1a38910781dfb8666093dd507409cac67562e047f586e2e3ebd8eb0a7d58af523b2ceeae5240916de9b231e06f964b73bad27edfaddd0aefdc4ee29a6614dd51323e0e9500e4bf249202a2582bd0ca2cd318b92faa3e36ba37c6370c6b9618c50502b116b11fc10ae23462b6584e19c348761db86c44d5ec477f0c7532b7e33c067b5458f3e2481ba494f3c7b834c1bb052222437300f4133f123d2c754b66c54aa16c97370e81d6df72a6e6b065090f893fcb05eaf374113dfe83ab66a4c58244cccdd30b6f7b56e3fc069b872302a838d67b2b57c6d3692797d70de34652221924f57a4bbf283882d6e7a27342a990f5e64308135047b9742fab5d544808b7c86bd5b6a378a373d6a51a23e8a0212ae555230183308bd85a8327ab6e0d943164f90da8787f6977805ba7254f0470477130549b4250c78ed875319a1088a979c54b8489cc9b2\n\nInput: edf9747313f2c3806c5128a863a10bb789f28c721ba4ea92bfb58d187c561628ad16301872bbdff47cece5a3239480e94b7da2a3548465d41f56dde5a3b358d28acc96bd7aa7aa88e688ce78cb01b690301678352c225f46543c8424b51e070e315e4995c74a644cae867ab5c437d844d7b307eba5cb40dc35d3e74ff6e07c4785c730f14b71b8c4e637da4b79a77a8f2c04a81175f866cd1f2ff61cee1bf46d4523d01c6351399c18157a8f15d9275a14a480bd493df357dc0d6db31670a5a275adf68832053614c0006405155f6c75710e1a4b2c61de403b6f09d7873bbf6f0012f65b5de4963c02b589c5400e7223f569b8fa537d1f25fbd78935ca3e960b7452c347de4b284d993cf386e517c3b7c6a40115377fb9ed3c862c110748d08020c69aeb94478a94becb20cbc1844666f8fd3b64723dd8326c5b9fa96610a4f493be226d5885c9482c9d26ccf266e8e3c0d2f4ab64f83ab6d1e6c2ea6626ed3ce262212906a7a29df55fbeb295bd3d0f63da06f87ce437ff897305eeb6cce11cd2d01d0c8760b73b25482d3f49ecd97d3b3fe5134d92c3527e2f2a53064e58ac8d6f9a1ed7c59196bdea7eb969575b7db3e1be4953a7d3\nSHA3-256: 3706da52cb41e2484ceea804c58139a79224f1d0ba646684f20f2966481a96e0\nSHA3-512: 57adfc4219c7616e79a0f9eda39f5a7a158990bc6674096427f47c09f862873ad0a8fcd5f3ca7b9c7fec5e269934c54f8134aa52c48cf1aada8f861e7ac07878\nSHAKE-128: 6ba1955103f2fb72b10e9ae41594ac8aa1126490ac0bb931e9670f6a2109f8471555b08e0a11edf5ac9429f47434b31470f607916ddd0b80fafb0eac1def563ce1bbf0c6e6ef082ee8f7dd04e15cee283a4767b2808ed1cfdf952bf5c763a5b412fb50a091bd3735c41147c880334b5ad6aa8d6cd78e67a103b55311d7fc671d92781f35782d0fb111e98536814cb480d5179b027788f4db08181a9eb61ad91507dbaabfb8fdd40b162fe7be5c00b9353dbde207430c8a6e0c603825efa716f54c6c13552c7dd8d6439eff408b464ea0ca54642b914f06f16e1189b172ce95a55f9c53c8fc502e565331d20a5a451aac4ba03b9db5cedf240e8d1f95090673bd1d969a7f075f1a559af34b025b80540dea6ba3c67401994564da3f2c0d257f664299822a6b829f70b7ead43a284ef2f5f047bb51af118fa2d09878872b4727847d9574d27aa066dc4a2eae41164e64b848ff2fc18a2e402170c39d6da5242eb6fb0da764ea405f9da6eec392fc6d871ca9396e7de5c18308386217e909cd1e6f82b4849cefe52aaacb01c41c0c2322d9e04f9f400aef3b8375c372cf04b92c3df974c40a446180a00630bbf520211ac0aedf26218c1470de1f9fd771d3b505f898b32b94152fda6a4f6492d66f2c1c7c98c71671983e892f0523b7ccd042afe7b1829d97ec8e9348f14fc7af1e3e24104e9a9f1ad977c8d97c529453d1c84757\nSHAKE-256: d738002fa6d2c752218e200d3f6aadba0d709e050d84de5ba946bbb81591bfd6b52bbf6a76dbbb5d9c6814d95ea4c22c1400227509bdef6ee359a589a16404af8529e536e62a3ab59010139488dff67a24b8c4cc1de82de846356788ba2d4d5b3b48d0f5f9c3c3ecf6ca5b21e21bd629fe93643a88a70d070cfe64efbfbd1ce71f30d56248b458a5c162d2e6d79f07983a7a74299824b92f95318c614a3205aacdea0ffed60da121eb903c2a0f86d4ba741c9ffbe8d271dd5c6fc488eb56cfe0b652e8d1b2460a34471b9bd608f46f3f50c5c50029dc70e6d27ceda7e9764a2cc10c601228def86fee915f9b613e8de18c04a221095154821363ed9c10b9ab2fbbcc1adf0858be0240f75ae9581773fbec4f57f156127131cfbbabf6651dc7e066187bdc1bb9642aab31cc480692387ed52513b982518d0c0fe00381b014cbf8a773f6b088639826d5f75825a846a6829559512e324fc36216e2c2d0974e31375913921b7a022ae3f1ed1e5404227eb0a6f7fa3114361c9769d4e3f60a2416999b2266f5ac60051738119ec7b62f02a61099676f4c80385458e50b4ae40705b9aa07b46e8859b28cdb3768b8c42c385eb03e7442d2c7293b67224dbbd888f18c14d61bf0af1a10ccc9ef62e4b94f3b64ee5b5ba9ba8b1f73f13264744ae10990d215151554363f16754d278ad374f0f8e70c0ce1d2ce7bb21609fa508adb3c09\n\nInput: ae5307b02bfcd20bb27df1245c1a9dcdd5f8eb4a1611cec4ca707aa105a463ba4cea37539ba05936d18f42370e7a2ea2e429d728164c71e1352fe5faffba43ca0d68d063c941127fb05ccb123ff4969010d6374fcc7e156cca94b496192486866505ac00ace5b06d3a83d0c186d91177b99dfb66b8f755f5a00ac97866eec91ccee4be20b1172f0635534cbe3c3162e3f2a9949196600bf49bb801d2c12a7458f3d059dea0bc4aa963507907f5f211199d815a93cde1b053a80a49762211707a37b199e933fb3977ff687b60653e381f3263edc09035d8451011af9c8a1e9344efb610237a8ad679b161b664658616be1ab2ca95ca44fe6c347093c9c2387569e50b8ace4e9d44a2aed43c26e29ad66f5d58c4a61b5c1c234dd5a992b36eaa7f0bd622a9d23e092801a1bea185d1dedb8a16c71a8e7783fe4a745cf1c6c3df7141fa6ed4c5f79423e45d1013e74be6f6b4d4fc004c34faadf02d2ff04235b77a9dbb9a411d12f68a16fa3e97170720b9127f37909e4bfc00f18d105c61a8bfb04bd2ebad12471da4ce24afe3b56ada3e1c4c384c7b29ea27424aa6a30766e453df17c12696bfa5c71fea1ae79f5e6f4e96ff1bc5be6243e1\nSHA3-256: a40e491bc1fb9ad904c97303954c62aa4debf654e2faf181efc52348de93bd75\nSHA3-512: 33ff01249d71f5edf556df68b91896fdf3f5009f808a062b95fadfb32abf788b1ff9ac855f44d534d1a4d3ca02d2c5da271695233c4dc50c6756722389ad3f1a\nSHAKE-128: 6282228b63bc113b1a7b0e674ab90a9163e66e84e09064bbfedb1aa636555777bddc29c5e3b7de4967babdea07d4788dd53983c505636d81562297c318009d923a0dc706015726b8a6327f52", + "33ed0657ae0689d65b2e26eaf5d6351ea3c784e5cdab81b341aa5b30757b4ce93c7aaad815579f5e739d369d5e4af1e2056659cfd859033479eac2217d7aa0da1d7006403ae8358e0a886f46315ddf21d887b965fb66dc634a4026f58d3a6d31aeb19688d03e9abad4947603113c7287936da359404499f05235685dfacca61b0e445b8b8b44733b3dc0c85a45ed09f8241e6ff3458bb97804774ef59017918ed42cd64bc6c0b6a77e00eb9a107abd441192b03ddcbf5751514fe81fa55358eac1c57855f3acdfc68ab16b5c1032106fc385d11db2c72f2e741b336980aefa57b3a3e18897a7eea584b3029a3ba19de0582f65bd58d5e7332714e417a490c9d5d59188927feee4d2827590dedf37aa04ac37df0072afe4d352fcfa36908628db8bcfe257d052f5a01f21ba42ab8365a78eaa0906860bd40f3ab8808ca2eb3b2dcbe717811f05439e7d20c3122f4fd88c9131db84ae97d41eea07160d65025583d79340073bc17331e5f93716d6346d423380ea177c4021442f150e5fb25939598366baa0e47d1a1bf38cb4af5c9e97280382aab68854f7c9d18b61a7a81dedef248fd021feab2e3bfddf8cf3ba92f888cd80c714\nSHAKE-256: 956855d896c57ae00e3c967b0807127f67c1188862f62b2d0433643634e08f0cdf1b9c90ef8d9e5cc11cf142bf9c49deb88be641554a10ba8ccee2e70fa73c08174c77d7ed9443ea3505964779180f27cdb638027f8e869964bd5e10774f0e1028bfd520998509576d6f11f23c6f383fd6a7fc2added81364fe5db1fdba26c316f0e984ebf813c0bfde49c2b08c3415166308c881a1f831d921aeab9fd383eedf117ab5dd4742c495637256e4995dfa148be6c99fc78d69d2a240e7b2367deb5f33b75f1c903475eb50767a213a48e8fc9b35c0ff9fed4a714dd834b88b35466c28233bcf7b3985478bfde28c49cd86aad2d2bf2ecdce7da0dfb4da3cebf5ae3ed71fe1b70b74c62407004d63b12380ddd1fac5e2ca7afe632dbdba5bb0d8afe9b120bd3ceecb92559706736bbf9941b2f3143a2fda8a89fb7894a04b5bb2a02070232b0e85191e0f790971715d88fd1b74b324dc014a72a3d9d1cd57d6ab1a07b883b6083126151f01a20b23ae65c151003dfe1c9d8efa2415e1a2d4ad0b10196c6ef11b3b65523a305de016b0337ba8747fadbd7df01ca4ea96b9bc55e61fce818bc58c6d7b76131480f6d3d75607b2e535b3399246c46f7117eea9958ed4337c152ee7d4aafe7e24da828fdb041832cfd5a35e9e6a995e6a1c9b6fcadc4a8ae1437380d043ec41dc86fc88d0582ef0ee00c31771bbafe3b259c5a265ffd48\n\nInput: 51bc633773828121ca25772b64776580199b042cbd6a8827f3e9224c942451082ab226d16ce4ae3a3946fa349431341cdc82f7d60a2831df09ab672335df4ba1c4c1572880d103db966bf255c96b5616fe9914afd0ccfba27d9c12dd962214743b111de96b9f6aa5983176d2af9b4fabcafdca98e4188421b2d0458eae4818484415e8009a1443fe0d411e6f5688469b8cfa9b6f5976114ce142477f9d93b23558138e7e1f0c591ea95a0e26fe30234a2ae66c8a7042978b4116614bde53068d929a9346ffa06a60fd0c3a7b688e21c1a8c631cd22b81e6208d028e23d89f78b9b85ef8bb314a8628366cdff9c31c35cadfb7d3d1fa76aba25314b5e7259356d8bb871c0cbf5df060e3c1965551307fb28571e550da2c2ec751152e7377e1b74222e18043c2cfb48ec6d404339d843e5d708045f80f53869209b5e4892c870a65fd7282970c22b99af43c63753f1f0224c7807829bd7b1faf5d7766baf537be4ac933e07cb474657ffa24625562c73724d3e5ce86732d80e65a0a7d0fcc8ce60e774e99347dd0609fd726390eb017ebdb6e00fcc21b7cf137d74c53f04796b14482a54d25559acb149c673c2077cef58310658e87ab47bd928\nSHA3-256: 17da9d43100fbe33617e152b83d6e012066e17a109cb450a9d64999ba7e99fc3\nSHA3-512: dce0819a549331a65b8f123f28c7de613eccb0da5b7e1dc8d264b10415636e60263e524a01df6c427eb905f10710ca60cc07bbcfa8b268c54e9d445acc5ae752\nSHAKE-128: a5bf7e5b90c788e3ff10ec648d8072840ceb3276791f2ec64d49767b109bd9c5e51a7862d4aca292472d14addec93ba39dc0154ae93c049b21484a11a62fe47416ff8948fcbc3074a6a289477e4f0731714a5d394feaef09531cceae6428e98dcbffe3335908e2f38db702aeb306850c67b9370153cbb4412127dbe39947a3b39283a3111a5d4de2c29d014afaff85e0e3b2625a15110ac03b598a877c58c52ed25c1e6dd9750410186fb869d0e2fa93eaa7fe9af3624fc4bd9077ee59a7da192a092d3243f41cf354fc95fe23c8282395e3535ebd3df32174fde653b6b1af4545325a96b9c1fc3dc9202e61ef03cc5357ad25946b62485468e80620904c31cb9b9dd071f0f3eb5ad2a3c3693bea2a4c3232f680d2cf1cfc8a5fca1a7af40360b2c22c373b558fa276e87692670b48cb0f3cea2d6b69cf3d33f415c606a8667b7d6868b578c53a59ad57d666ac78b920edefc195e180be072c1ad3f534f3c29fb7fa2563af16a34506b1c6f035c3222f84dc27b2027c04c5fb9838ccf54be3d18f4a86082b238e5c3001db5546f853b453ae09f141543f1135b23d1e626bef604c56b07651d371687a7e2c426e7c28db0e92d12d5e5a9c191a487f167de1d496504e802e7b9ef61a01a2d1e879a3b08c5f58b32b422dd87dde855c8b8cfc57cbee2e7d51537a3ed9b2875800e46b267264a35d31a1da53bb309649fa570a89ca\nSHAKE-256: e778e94f133a1860eb78b8cb7aa90b359f95a531efce829cc42bf7f107a06255c8bae3e1260495adf3aa5bdd632d9856bbb7463f67aae6cc848083803dbe54db72041b94f7b6617328a67277656a0cee832058a4d65c925b4a6c4c0573b2d56ac7ba4d47524026d7cdba1437c10a2190a7bbfb550a224636dd6062483ac0dd1cbb29aabedb99d9398bf9d7ac93a45f88216873c452cc2f1ca2771f9f76ff287b0aed4af8ca0fc0a33b320b39fb345186826840fe1bed065ecf6331515bb04456919aa26d8415768c10201ac68e5fb234785eaed2df2fcab1e858def4848d698773352eda6c4d7975f2677c13efef0451f280eab71a00a8f669ff177d1e0a06ec0760eb2dd75bfc0482505ddfe9560a28455a4674da8431fea9e1fa2f86eff4b8ff3533a1ad986b1f9572c0aa9aa829acae00ee223383f8ed4aaa6771ba638e89bb5caf7a3473e4e676cfe6a30ab387af0489fe458d79d25a0dd2e1c337e7deb9e642159721c639a68bc315c58df800024a8f232fe783461248e8458ca741567795d6052c61ef9d3d8bd83fa947010e4ed3513ea81ca990d1c3bcea63ad7671a23558da7600ac1e7acbd92a95e706078259ff544f7491f2f14fd168677c74c5030d8495ad15991b57282aa9af7695577e8e18062ac99d4edc28c6a1fc4c030c5e8e065b45d114939405e20b2daac1b996a187a13a025f0a7f62b63e1c76672635\n\nInput: 6a80c9539de86884846cbb32adf2a4d486e45f15541fc5f0ddb4e2612c0537ae899eee562cc9ca1042b58f3ab94a42533ff45da686260738b72e19373ce5b30dc7f9ecf54042a5e2274ee02f591a629a12022fde8267ce14031241b27c20992a833e72c16657ae23b1e390c88e918bce80f38b61c48fbda39e5391e7cf1c1897ce02e5fa368095bd8e73b18437bae9501c13f1311472d135e2bac0380a112ed99ded2edb914149a0610e1da0cfd70f4bce82ae5ff5c36717ec565904e7cabecec569ed17aae19a1ec19d8ef4403fd4617b407b9f2bd6eb6702b0425c9a81babff6b0fd0f3ffe645bfd0cd024765cbf932ddde8489642888dddba163bc6098e7e81f64cd130a89f6e41f2ca393fc26579dbdfe3716884652115ad2bce855d4da2aa411998f675baed3257b8d46ad2010d4552798992b66ae480fb0a8516e03ae972ef92b78ee0a687c062bf1908b0425702f0803518da80b4c297ebb9a1130962dddc367f2d556d5b1600da7ac667126278bcf08b8c0a85d312e51f3c030e897ad0125f6c107b32ea566d57dc8c1e1687f3d78a5ceec32ffac1967e609aa9913a78057b734df163e20a00e712a75900415b9e69cc63445dbb9fc8\nSHA3-256: f759ff0023bb3864383dd9a2bcc23c378fca02b44f4e569f4716447dcf01a7ce\nSHA3-512: 64cb03171b17e4d19558e95417ebf015e44a7ee630c07c3b77725330744df4eef3ae02833879c0e8dff2c8dd9bdea79276147275e80d999c15fc44a67bef5844\nSHAKE-128: 5628a948da4d76fdadc0b0a5b282bd4447f0f5e805f6894e40c04e095e3af8e88950dded116524b5cd085d1fabdef72abb3b52dadbaa2020fdc756775cd1b7f0976fdde0d80ffd3e4a2d4f3bdfa7aa0fa163480379f378bc3b9cbca2712a6da77c2168aa04ec4eabfc3d6a55422c9a54123341a0bf1fc76c5dc2cf0de005f39d88189af920324143a931b172c26cde384516a5f0559c9fd9b2d94a12b8f0e604320cc8d7c5870650f3845132d93f183ff77ac7cf6ba0a2efe42f0ace47e9fdfdb922d186dd7bf58faf81fb5b2aef387555ea204bf37e921f43fdcf808e836cc4653b69f49b1a61a613169db0cd0b4c126852839fab173cd5a7c7a789e0f63ff204d4958e6a588b69077aed2a17270209bc637234ff605915d6c3d5fd7aca3df80de543dfada3fed60e22cb6a29f931121901d88e9b484d9f0320430686107fa2f38e550d6cafb7fa90562a83f1fb12c9d7ef5cfcbdd3d20e254e98865c78782d867e5a3c4be6ac7fb5f309ca90f7b795aff1a30b561a07ae7a131d8039e15b4e21ca23638f66914bbe9b39bafd98d0b04cca3d3daaac396d409d1830d3023b7e2a849c9f6f6bc60c29b6b7542d32c625d981e126248beb31851d418fd8dab7890fb3cda9a89a9270fa91d051b4cceba63f2da05b3910945ea25ece17e654e278b125fcddaa1d4b28bb48cf91d884059acee0c15a8ca3c48d115440625f8715a1\nSHAKE-256: 3233fb431761f72724e30d79dab4eb7f79fa588a7391c6ab41ad0cd3fe87096469d5fca2e755c5f899ba15b5de8e10d2e16a44c0cf93c0c561d8e136ec94247ea5729befd55119934b18b146acbdb8f29478b5f958268a06ba6d1d0982f8e55340ea2181861b3b09d41be39553ce802a54b54a48935d17d833aacbd1f6448f6973111991e529171b2710edc972b2932de56fff0c055ea2a93616b6f9b8dc7e821dafedef6a26d0e1827d093c020e57ec0e1ab18c538e21fa8a40d99071294706d3deb945b508b39628de52193796b5f74c6ae0280c09dc43ab76fc70ce9d7da79ca70c24574264de15cb22cb5a9d8138b24877d96bdd58bd53bf68d31fe9676bc1337cca18cfb5ad91e9288b808cc6f665514ef2a1308a901ff5121d65e3d05a7a8bab5f0b3cdd1a0d0bc92afba079da60d6a3b570f279ee083bf9176754af52da85baabb646fe7afc661c4c34bcd3eb426f229a451f2ebccdc62891a9575f6c5b3e061d002254af5abae1aa86a2d2fe3a533f52341c0f3131aac3ffddaaebda72889919c00b6da40ced07b9db81c51979fe5044c9ec6e83bb241d1e5ee5de081704b265a348830b2dedabfcf4e99a4979c06243935391262a204bc1d2ea416cd99d941604bb1fca41d9e95d913f920fcc18778d179c2d9de1ef1073", + "d307a2a21d962311c7176bdc47b4078e7299f04bed09381c0dae467bc2dec6a695efa3c0\n\nInput: 0e1a026018e6dd62aa6b7b445dbaa8100543923842c276186501c56b00e88615aadb5edbb289248a9a76247ebb00d49774cf806d0850a6125a42cb9ec36b9978a3195c11db9609ebd65077cb0b09b52aa0d72cd5159288923275dc04005f2c1bfa313206e43862dfe555e5debcddc304c845f3bbf02d3912df37e2e356e863ed6cee6eba07581eaa3eb0968c5fc036bfb1226e6c08b7652a96af40cb8eca74a3941eb901c738c439df002d7071c544a1f0eaecff21a28e2a41c6fc3442c78834ee023fa7a074f2c1a0eb71bb905fe187136e24ad4aa8a2a948e1f48c39bf7593f21cfdc712dbe4824d9501df5cc7273df92d59079a04f1b9a03ca31272ba5e9cc3a47228208417e0cb02d0de546ad645366afd78e2bcc2b3f1eefe55a1db513d3bdb550ca093f2d7929f7b7b095af18aec1da9a2c79463a433dae73f1d420f8a0f30218a1a9e1e93fb3f04c3094a4bae8481bb4b2d0483016587db4c5be2cf5004af9f52e1e141aac586829dd6271e4d572ed9e40f5a9e80f37b4d647b2e9d818f536218cc5609377d9b04bbffeea66e3b5d3c9ca76da4aa392629881833b3ae58f50eed8557a0463fe94e351e4b39cb5abda7aeac0bbb9f113a29\nSHA3-256: 7f63be8aa0814505869404a1126f6602be2c00832732cca64e327e8021cbbdc4\nSHA3-512: 57f13c2d767a5672bb82011d28da74b996bbe0b8523fbf1a2c4a6bae31aee8d6586b7af4d4522938bb6cb97e8e8dad248719be9db1b6d19b1745d6f19b70b587\nSHAKE-128: 168a0b4ee05a49e2d94fb6c052a9cabaf4ace827efda993390e97cb39cb4e04774185c3fc952948b60b81eec7ab4f78aed97437fa4294787a2fd90a228a8faaf8a5acbfa8c8765315ff280cd1c2a8dd3c7849b66163e2026a29899869dfbc149eed3f418dda3516396c8026ce59636a75897539120a2f57fae589f4112b192a75741db1d722a931001c13af6021f1bc73a694ef99c9733fa130922354b035c6ef438eee1f860b33d65c7a0ef94a3dc2b48d23f2d413315b89cbb38fac22c00d33a84b2f7eb28cedeb7e1d333adf3e5da3d95b049ad1606fe1bf030a98235d31f75a988fdc43a548e938b02b57a575d33b8fde3fb5da1b63e647f8c26723d352a406d3fcedb74e11cf0d5c55bad86b450646dc10afdc6f3c175d577f6ed7077b42dbc6001b92c4679520f7c49ed21d6824880ab80c43eb829dc11aaf5a536abeb65b9b8622ec0559399639041194935346ab9a7c5dbb2614d387199cae01fcc3724d7a9983a6765a0d2db2458f563e97075e768141528896dd5d694d1b401492f8600f350fc73689a94ac2180d75b48f25971e2206d80bfabe00d72854afffa7f2b265cdba47e84dd3d309ed69cd9ca00da61c5a25a990f6a61e5acede343016901f34b731b04c1d83967bec2c3df00bfcea9257034eae086b9a036de6f97cd30b8fd56643219a231634e5b5e6491dc0cb92d77c9a855c21956fd4924947c09a4\nSHAKE-256: 994702c59f3226a1336ae531054ba669642272577229208771ac1ddff8eb75a979f049ebb279eff2b3e2c6f3d34ff4bbbd7cacea6b3c43f56d42149424969251bd96913470f6bb5c1c9968a085409738d6ebe9963deceb0be4ef4f9f79c00d588b35528cd8bab75fe4593bcf2d317b7413ae8c296d54d29576ba258cbf08e4acd3d96995266634fb994bc4f0e7634fb6f48f824a839c5e6a4bcd7f661046c8727ebfdc3137fcab7dfd558dc7471c5a06a76e98d84396f58a4613b3dd5b14b9823bb06a2085c38617b41f5974bf5eb4f32697ab1a92e8a91722fc1e59a008b6f3a4114b460b0fd94c9fd3af851d9469596f7a46a37a11dff948fe1b3998cbe74e98707e7d2e014f604d7ecb8cb93d4974852ef146f04d3f2ab9666786cfee4b20fa73afef503554774d2b4bd14e140ba57484364263f495402ec48cc31d4721be6fc1452bf3de05c4d0f1a1cf794ffd32a4492551ccb181d46e0ceff878425eb4ff337f5dceb849f38f9fc937823615d47ff965b858a7e3764c17782f3f4c67c2905067f5649257ebcdda334b818f984f7dd09494e52335399a1de64c31a2757fec7122404cedcbb2dc9ee583f6cdae740cf97497391ff75bd3c404b2a2d9eb25c6cc3138df4a70b843b66d8140a40303739495d614937da6620adc4eb69751ddc91a712b40ff22ad11448721b32357d1dd0569cdae2cafe16b183caecd242036\n\nInput: 63b2c3b447a8a0b39fb643dd48648a28f61ac2e3834a3db1608ab1220592f633a1797b588ff7378a0a1a7367646db5d458398b48ce88c8f378f89ec7e70d6dffd378d1921cb25247977531935db30a6500a79a3b01ad1f107f4fe02fa06514ca6aac7442ac802278f60a43414f4844869b5f186f8f7bdff8fe368823fd737deae0f1a85961d5fd458113568a7091d432e64c9f2d245643e254793901ddc8bbcd4fc95b8c8e82437b5f54457e789f7839e68c6333888e6862e5092534ae26ab3ccc73e474877330cc4176a10b0f225263ffd32ffdda3670384599e3e0318088d9edaf0d6ea1473c5c16855ec59a7e4a22f2af481541d28296bfe6765b3a477075fd5d8d049e9de3f1dfad750bf1567cd56778fc4676c4e83c17bf25017ffe90f63caf2ab46e8b249aa7d3bf8afd88e5ec181757627ccfc2fca618ba072b64f0fa0ead1470d90de28cd022e8b5dcfbb0c0c2ee14143b3da7c85e6a830af1a4eabcd77b5518f25e7d7489c2d188d011e91455e06676698731f779708486622e6e0c41b151b530772c880daf482e1436662e0525936e02622d92d6f8a7cd39486931fe36c22198384959b1bf0608c5945e62acd5d53869d06e0dd6f80c98\nSHA3-256: 1fe96fbd2736177cb5ec675cf6e6f265a7d0e87448ee7d42b60161fdcb845304\nSHA3-512: 025ca502631b3f1090baa7c690d8bafbc28652a30ac36672546bf1ffa1d92b68f5b27f7f3c1fa161310438ad4968b213216e186a69b9c83f05391a6d0547a4dc\nSHAKE-128: 89c039aa97e0cb41adff3a914556e55c857b9f8461633ddbf0f2bfc02d110624f94d47e56f3477896bd2399d6b29d8d29c9144ecb79f91781b7d0a133148ec229e1f626472418cf170198a26f16636eea9a4a570c8de820498eb05d9e56261505c6cf250616ad9ab3162c3c275ed45c52fccbd3c4c2f220b52018f2f4c52104ec5165751d48f0238faddfb05267d909ce1c3d72846fb9712d81664c0b478166f97239762e4ce57fbcbfc1092004ec834e3aebce327eb7c646cd2c2ae7b38ce1f19c1bf668a6d50c6c6403f406f69a9c3a277fd5b4bd3a0dd743437719bb9e257221eb74323a25ae8055877dd0145393ea9f01916f8f87551b53bd274ab4787a9c1ecf974d570f256ef776cab8f93b07aa7f5199e502d9a4123787e5aaa798cf854d1fabd9b1d24a38133693eb4f59748e34155cb78448df69359273ffcaeb8e014b830ecda68a2fa0b53fb752ea0952757069a7d2930d2108d712dda67fe0fbedff7aaec416da7e172258fde30942f38e34bc607f8d3df7a73eb584b26e26694a6f178617b19f3753c948e9810de379bcca332849a562e02b32d1ebdddac8b986cf6610c11c7ecaaa559cea8ce160e0f962ba600619c799e4e601861be2554be0abdadecbbb6e278bb73b75fe911235bcbe524ffa363bc75d20bcde05ba6c544a3fc3094b9bcf056e3e8fa428784c860f53ecc447ed3ffc6a300a89d1b712715\nSHAKE-256: 3effa44e398f72cb86a1c010cd54aaf973d8b670af1e7d41a01e2846ba6f6b3fea2c63d5fdba2bae0586f212cf5041e5f082aed2a6fac98f52828ac864781a3ad1f85e160e13666912bb71c5b43fc806160ab1be0e48f0fb1d5105aea5bd9c8ee287535275c818b7c1e6ab1fbda7ae7e710802f3ad2bc0cd031769edbb45dfc1199e4bdc3c74ee875f4dab3b880152a5aa802e5f7a2d0d8c7e694c9cf4ba68b0d2d12ce730b67e0e03c3c6cf22f254333991e07aedaf4e335d1d2d85567d8e6163b7ec9bc78783b3aa2bafe69d93d66a1e0e4b0e7cda4b1a9ce695227b2f822cf87e7971d2429b1a9191cadb8698073036680c9b0aa37713ad1e2e009e005a4352e4c55bd18878b8bc99be0bdcdcbc468ee9b7d5474aad7375fd57196a6cb564eb3bc8c3b51d5ff1a0fdaf2fcdbfd6b68d3106181ca73972008f8f576a1bafaf42d8931ff097229351ba59e8221f0a36214012f16d5dc59e5d5fb9f92fe7704ba9641063c363d2d476329d73ff9253fcd637c906517ae60bea83033f0e23aa3806b6fc6214e15ce85a5b13398e03514f48d468aeb6256d274536f116724ed2a600669d663047198ad436f1bc9dddd55c33a061e8ee40b4395c2f5930cf51206d502e0ca5ff84dc65b57aed2e3c91db185779b55134548bea4fedaaf51b9d4160b578de2772dd1ed7789ff6fb4e8740c95070191e654b9d21e013ce438852428a\n\nInput: 1ef95bb0ad9777ca5111ad9e30842022583c6114ae17ac533b6f3fe73bd4943bd556670e01be8e5b85fc977ffa959043228d5661f804f37e075e708247774e64cdedff198f2914113ed851e32b78284b2e5dac156315ac10bed5771d1100784d09aa73cba29351581d5f829e914e0ff1d0f49bf2c4efd416eba1f0ec8337ce9238d2c84a3205ca05b2d0f14ca65cc8a8d898d26306a14f43fb9cd4f29bbfe97ac41abee098c4a49ba3bf31b2e1fc2942dfe9a9b6a41f1b3ea0979df23865aaf3c27f2d7e1a8a11606d8fce6b3085807bde5a6d40102cbf138517c1a7f623e18204bf54a6c59c0358ef139ebd7bd0dee3fa0db93ec20d3db30ab6120f1c9c58af934e7718c78a4e8f71f7a8e95cfe74740f74f5de8cfc586b601d28921822b8746f0487cfd56f0a97a77ad484182241df7efc3c86390df198c3a1b8981239677c7dd3d96b70aa7df2f9b2ad2e4496f77a2671eac2b4c873b9ef1fcbeb3d9100b1ca4c98b2a34c6676688dcb90f5d91192885b0b5c4a8da568cc832c22bae20ada7f2afd4ff8202c79da40b319134e83eeb113cb090bad29b5b3e4305ecfa83bde4b7e48a98179b4e6e44d4e0b32ac28d5a978904fb0f50be40cc97d10e7\nSHA3-256: 0c354026a9cb8d105deb5169d9c2dbce9537af04fb52d8c74d8683570d1a5efc\nSHA3-512: ff3572eaae59c95fb0dead2005db00be219fb2ddbce474f6c5095423ee0ca499d89718e4ea8a968e21f35090ce5f76e935d7873df04bb4ee0cbb3353ea8efcfe\nSHAKE-128: 55bfe102d691cfb12b15aec793bd977c234753250ce08a54bd124155aef6df0259dcb20ac53babe14086b8904ba6649bd6168fea876ef7c59d65d4227128a0004a0b5e40b8f0fdcbdbd6c7f74cf2aa0e74297727631db3da2e1d14da54f0c1d05cbe511390b898a63dc689695474d69ec9bd5d050e6881deaefcf124cd35dc59c78a2ae8bb246b51fdfb8d8bac48b2a1966badd7bb64c4bc5ec4e69cce3a5e001b8e332b8b03ba619687ce038cb50e820dbed14767a8404e3b9ddd3d32060204362c36430e0c2ca87749bbd3b3bc9d7f5b948f9d9c113717ab0fa9c4150c2365a2225567380aea8e2bbb2fa31e91e3f2751b42ee971405714f1e9fd3ae3614c6ade0148259f9e8f6fbc27d322d43420670d4550347a52de3a43f9f73709140391c1151f8a7821574a07703d78fb1ff745015d1443f77aa1246b9d53", + "625f55700bd3b9869a6d063d958e94e7a391e9857551e2e5c511e1e79821c2bcdf7eb262174ab07a115f7274b8d1f7dd8bba9dfefdbbdc3d9a82108471ebd188521ea2c94cd9326f484bfe03e9fbc00c96acdaef2f825d04c64aade7ecff37c3e409033c3a8625462c2949467520bc5a8b9893e7481f64070f30cb52bd6e90a55e24f08bb74f5cb1b395bc9b89790fb1a3fc90d6ba1df4e450fc3a9f0702ab37dc841a4ee73486ab6d8f692a80bd581b0c6c9d6e7f7c31c2179f0c31a0e0826ecaae8a150\nSHAKE-256: 4d10efa75cda8081f2013b67b6aa6f10d3d3c9076a0f9148c3cdacbf047d708d8291de7d0208deb94d87432325a992f7d90e862d00cc4eebb1856931958768d08201f1ec88af7800b99d221dc845d700aa3d4518a6018a84486cb834e003e8d787a2023c32a34ba8986055cac903808fd2a08bc3249eb62ce6e72f9a9c43d44ac101e37915aac92614619d005dd9750071535a57bbc608befc0cb4042fbf898488a78315fea10a91748493a52c1a629c08130bad8057dfa6df85da465916944db967a7ca7b5a2b4f19e2d2dad1f1b45a7ccfe988cb8cd5008d6c5328a94caad2f242785a02e4ff4c5797daf4c05060b02cf75f0a550015782ea0bc382391075083ba66382bf371f5649a184844e2e444f3d7e57543e41432ecbc34d27f939987364884111e134ce73bea9f43147760ba4128eda8cec8e9ab8c8f930236a200dd7e7f7f4158d8270ef9c47c88782b68a883ead8b4becb595b4ea1fb462877796548b83a89c2c0bc47f192b90df6817c1a80ea3b3a18afdccc7ceb63c8e005e29df159e395c17172f4e26b067c6fbfcff1889027e228c2f39da24ac0320faf8ee29d2eaadc8a04c758ce499411f72f1098b8b4f5f0275ef6c927784c9a5438ea41bb221a05e073fc08828a0000fcf5170faa5f56b202f8da6e26db03fbb9a72fdd8754eccaf26d10553d8d1a7e2b6006bb297373953c76a257e4038f831cedfe21\n\nInput: c6152e58ba1b4260d33e5a433fc2d80ecfcd95646d680db7c5f6890b3ce8daf0e6201dd2622c68618a8431a005a7aa651f4459dd740edac0abebccc0da4e1d311b569b8005fd43f31ad79e56a8ac8312ce10786c111a7c25bbe31284e0ddf8e9c622f114facd7ea27b02bf4243d29689c1465bc643740e34de2e2e243fe0e9c35283674d3b856b1fdca1232a54d3cf3883216aa75155a42a161c89a26c7d6e35504d8eae0013c5fc055c8f1a773c043daa9fda127106ef8c8aec9a5789c114dfed6cff32420a50019ad9611cca164acbb508a470a2d5c19943d2777f00cc891e863d200f8d4bdb2fec48b0539d44de06755d4d4a11aa9f12f001b7c3f8db33c808927f51b71b862e9112f755c5562ff19328854fb07ff3870efd8e71a6883ba50e71b14ba8276785dac4a0b65a48cb3ebb52f9437ca5000c27113ca863cb75225e930ae5947474fe33cb5d1a0e496e177123b9709869c000efbe241dbea3a0d64ce7da69d894fad2f9dc62b9cae800dbd5c7d3047c8d703ae36894d77a21e0a47bbfe851f16a24b87ae4632bfbb7c6e4aad64e9c3a3adfbe51d512478e10afb374992f538f0b33790cfca53f829a5c18222019e6b78236f14538822ea66a\nSHA3-256: e497dc9a15c8364734c858571abf283d684efdbffe4b9676fd3d3c6b149ae0bb\nSHA3-512: acd7ef2fc2be672ebc4891066ff4240f1f6dba3d59161959f41355e89bc013b4db30d17a4f2c294879a52266f50e75234f20c72c7b1fb81af950ffdb17e5a1cd\nSHAKE-128: 55e1c01c18d54398473d5badeb5ff69f94036044d2504496244c55973b195e30023fa926fcc8b7ea9bf96a3df929bc7da544fadebd61384338f1a86695cef6b80e06af2f0d6d052eb3873770626e2342d5c891bcecb120d36354c58be59d4829cc1ded8e1f9c96f681085b227fb1ca24b3672d1a8a398f306e11e223ccb28de6aa802209ca8d3323d26ee32bc800d8509b2a4db1345b81e50187e69c16e657d76cd8676af515a6ca65fa0a5986f626740df7da44b51b4d9e6a181fbc745035a454fafe94a2021076702a69a2574a2eac8d4634e8e5ab02b7661f060dcde99664518f929f5dfeff301a73dd23547b51dc41020523a7fdb905018a55116becfe2eb4b5de94bd32a0fe903a1e9145e2c39c80689ba4476da2d978938285cc5004bbbc9a2642840b58f7c6e0a9307bbcf7bed212bf0db2fcaee36dd78663b66c2c1191e2757a51ba0b42fbc9a3eab4e900dd896530aa93cd242df821468263c433af070bab3ce07081437dbbaacea8899b3417eff0c3938f5795ec0326d8a40dc337cafbe8f14acd411b89581b15e1f50ecc25ff09935ff75a7e3c11f808c09f2c9e61d9ceb714bbfd5fe3765414f3c22f1ca042568b367e2c2c66ec8e4fc33e211cc4e7ebea0b9066f431f18d5a1cf103f02a8bc4495ad39ed65a9b696c011032966d0d4b59fa29cfea5f0e09d833e97af6291d394f330b4947e85b71bafe5ea87c\nSHAKE-256: 8a6462552f57ba125fdaa54602b4e6633f469c81cdc05919e6db3da791ece7dc295676bc8c031dd2d205c8e949f92bd7898ea26a6e67563dd8718d5f2cd5e3d571d2781fed1af260df3ca99b25a6314328c833961dd41b8075a793d78aab1edc2754881062ac93b7df1b171b74795879e2080282b46b11c07273f7fe03df6157dc676a72b43d6cedba6476fb0ec7c3e071e35c662d43eb0d792a276941a1a049611977cbe77e3224d81f711d4106b3ce66255b73563f86b97ce8b535dc4f99d1a9f13987bfda1404170546ca1219616bbd54898a8f359c765870c3d78e605a27b4a8a216e03e5aabe2eaf629a7b66082e2ec07f7846352a30bd8ca5c3c0ac43e477c8fbe5415746939d41adcf361f03fd1b006429fec42a24598b7575414c9c407e2ca326e32fbe6b703e086ea5870c5fbb794202c4a8d000f928de4e42a8acd69916b86e5dfa95e74651275a1ffcfb20ae93b8e40d8b7705f99fded92ad25dc4cc848ef40dc82395c654bf8fe7b4f1ed70f4a828186a0b228741b357d1c72dac45b2073a5ce58fb7247012f60fab823ea4a3fb44d22052a384da777c14a437777e136fae7d2ec3c0857d53a4f1ab1ac04756fc3f8ca1b372c4d062b2a0eb36a07d7ce5c22fa53da8beb4d3eab8b2af1fe1954919e9b50739d055ab52af7bb9b59914a33d7db9ab28c3fa11e0ebf09e9545ea63877651ab9c7bda0bc040aaa66\n\nInput: ff68813224de5bf57ab7adfb9d7bf349a2ffc4694b169a0b14280ab400b9d7882195a61f5dd42dcbf95c7fd238cd0867325f3c51ecf0b30e14c5826fd5175c661f99e8c3fd31cbd253d165ae37bba3346e1f2cd8547dfa93a0d68eb87db41169a40e0d5471f90a65f71933e556eaead5d85935efc32e133c640b666d4f6db028aaa1b3025476d13c8c2cc7e905b9bce6f052506273833af1efc89b792b812828aecea2e563f7cf6c29edbfc498e47aee745a8aef2f2871b1742d807895f3a6df86df1ea25e0bb018bd969d731d23c2c5c9b9b751970e36e62101a952db5f631da4d52a7d0b5f540e32361300974a2fb71a6adf1e9f8b402643d3b4d7fec6abe8fe4fde18c419f6eb4156474adf3cd3219ace00fe5acb23bf8795382dd7c4f800d0e41b99f3f5e6abe8e35b794249e4fd34e03f2368d9f098fe2bf92334d6cff0d785ebfe0f8e217079f04bd69d889046f7385ba609a0428e988e1e6ea72acb3f0197bd376562682b69f2592a502c6947a148b8e7cdd1a2d2a6a787cbaecee097148142a7275372985cb7611605544ec3a127e3f471be77abb9c1ee5a1e35a4e433da91f2922187ace997a664b7a1fae99a1c1fcc4c4587017044bfbff38264\nSHA3-256: 348111b988064d39d8393cfa6bf5a9691a78d76c7f6e3d1210f33da4606dd33b\nSHA3-512: d4bc58e9aeb2df4c61ea6cab58c3afa8b78c55d822522c89d42c65fadf71eb4e5c02d5a74f5660acae0ef6ae893d0afdc0d46b9304e1e40253312eb642ff98c5\nSHAKE-128: 6394c24043e6127ca844f7d70f4966027878f615baa125beafc3d3a7afe93a6f9951b74358d9961cdb765fe6fe3ca37cda56dad0db789e718a161ec0295f43334405cd9771e93d1f8f9b5d781efa00e97b62bd2b56847644a6b4a187bbbcbf0eebff4d8c7b42f42310a2290374b82c4e3c3f631a93ae516efd94c957f9173092319ee912df99dbed55a9246e0e6490eea008ac96f95e2936b311219bfa285f8e8d5aca2e9e64c70c1e5ef7ac6313a02cd9ad1c2dd0ee0de333827d2220009ed7ac1502a1d6c03daf66a36fe4e280f949a4a8f7542843a9a5b15f32d55eb715c0388a80d73b10e88b376fee0e0ca0d0e3d323818bc755a11e7bd031be78361ba0031814ae02177add644f3d27c7281e38ea497b16ab99a4e4500787d1cba55d530893c4aeade98f52c7d66ceb20543313b4fac9249c8be1057e640a84df9a718cea034aef725cec062391fb72dab5f382e32dde8421259346f6393921d2b7ace108428fc34c69fc0495b6d7de233fcf8284bd6b5a16991a7faa93f2bb8a5a20e82a16203b5d3a906c12363f11e52354a4e83db9346daca7373361824735677ebf01bcf8f9e0e2354ecfcedb631f6f41f80aa8875f550d7142d5698ffdb20238e1a73f6584a38d443360e5b4f8baf570cfc2a0242255998090f736d3b2035574f8d09e8a4fdc7235bde513396bda0a28fd1bd8c73953485fc66d6c99e1a8421791\nSHAKE-256: 0131a264608f1e1be72c2e9c3c88d3b8857a04d6cafcea749998be7b597890f779a9a68c994ec04ef97280dee0e0267314b572cf75bb8f041e9695bf233fa4533e66a590edac1e44c280c4e249b7a5582443a0b8080c6ee136f7e0850e8e18449aeb81879b5f5df2db9634400687719b3cc92aecb61e58ab2718f048a043680b1b135fd0bdbaf15ae24d1d2fc94c40848b32faeb42da803484505e80980ca77e5268a74ff18d2e4fbbbc8c3c8081396983d8ca03df66fc37719ef54aa17aee3429dab07f815cbac81ed38cc7982d90cee75c15fc01b19144d420079b2d37242621263f2870a18b792f38bbbe80534f9e7348a81881f6f0b32b3f7b7f092f028fb0105b87a6d61ad0097e6968fe6e7385df1c42c24a47cfc0c863b819908504b70cdbd3529603727302bcbd68685a1f5d6ce1c33d35bb72982aeb853dcc1c134ffe81de92ca956349cd0702646dc6001190b6f970edb8091837c4171e609df2d6f8174be054271001dd06f332a9f8f5d0eac4c70ff878300d7587f2b61ea3cc6f0a4d0dba3e7113424829ae7d1f89a28ddf81549a3a4586b37a721d6295498eb8512b84de6cc13bc175f0a7d894f4f337e23edf71365370d8312bcd3162991263f6584161ccac70c4dbd3e84f03609a7a82018eb8f2a922e33cbfef8bfda563d392e6609c6982fafddae6be81f701188789a12d5bb4abd638a49a327a660985cd\n\nInput: 468b8fbc5ac0237f5de28a0af810e401fdae51efda3c31b54150ceb50613d783d8ad76ae3c466da04f84c02658a69e70b198a46b5534c118e51662db4ee1ab17fed6c1b15bdb8cbfa0f0b7125c35d2d14df3edc935ab49a716573b36993304e95712cf2bb7c6eaf7c14ce36269a9c9e81b4e6915bfa214d51416c8a2241c37d03f34ad17a3ceae51fd60fd902bd1be24a472923daa6676c89b1539424c4623bcb89a5950c645f88c19b2591fa2538ffe366ee6434080fb1e00ad33eb49", + "23d75cdd9a666c91fd1c46beecc438d25ae295dc567ff8297dda94f7c5045f13cfdf1aade9ac51b0dc9416f904ad2a15501e0a85b4f6c93f97c96d1743bb8461eff4a5cd7f90fc4f4180672f57e54afd70c9dbe53d6f339426fa4561e60908ef9ae4aa54c6d29905585bfe0d225bb881909ed9cb3c901d0f66eb7da6b80148cfd38feda9e802f92c2bb3b30fd88024d6f8396e8606e83101634a46291607b7a0d611e2d255bcaea1bd44cf42f0877e04e187c9f8de798d9b3cd1b7757856ea99ebbfb89e65b32f8dbbd86d18ecd3a7cdd20ff9883c72c60ee298732d0ba752502865687e77879cd5202aef6e30ce722564724895dcfe6196a01408e727cdbdc9db956f\nSHA3-256: 633e61e6b5472eb51ce3d034c2b0b14b05cdfd9ba4bfaefddba1d11a495126d9\nSHA3-512: b1bc7a489b407991ed622219995348f9d272439f9ca68e9e5b789f1a63efcc34e4cf312c2cd683a728f9891309dcb4989c042643c484f22139787215eb89e6f2\nSHAKE-128: fd0e96a07a88869855a1ab7751f3f1ea90e7e4a629ffa81ccd6d0101279423ee28449b59deb6fc0bb69111bda90485bbf6d801c257c9989f9265dd32205185439e52b7be436825315ad4ac2e196569b89859acb2c2fb8aac3c61a4aae5c0f4a935e8bb9785f2c4e9690185e4b71d1c62fc4c426ad0ba6912038c521980103acf514cdd72505eedfdff52b8821738eddb29d9063d0a247d71aad0a1d681a5874de41654198950c00ef4af7538f4373e74fcc958988306b0f143aacd8e99bcc60152c5136625387fe5223c594d213959ff9154b3c443993d9d5a11b8b46657f1170c31c883e01ebe6b35dc367c516b6c4040c8be2c1ea3618eaec5fd818fce3f0a9ddbdb3d6deeed719b91c087ea6e4dcee20742f0fc0ddf9fcc556b20773e82f86ca0531eddeb0c2dfb6d63e293ebfa8f678c421b5322f64f101a91ded899836ce7be5956c08d058b0906beac8e9117b6dcf84cf9afd53e6e16436022bfd8e60bc2d79569ee2fd7afcf69afcde7a6ab42d4c87ea7a403443a3f9e4cfc4fb5fa11346a612da288d152091c94789b06254fc86c3577c45c4bfc85315a00fe03e36afc564fd1888a2265121f856cd8460fca9eabc58395425a106c4c9dea5ca967e6a5af0f081c90558be7534979f50abb52ac5b7643d67e3dbf603ac5cbec38162318d147ce8d88e3e0ca6157f94d2f3a93ae1676e1d2255a53ef7de49ea885683b\nSHAKE-256: 45784c867676350f8e3a670fe301d265b7ac811dfb61452b3b73d3792df48b9e5b0c1988690c1d43099baeb739988fcf40b60759d1dbefbc29bc1c03f641d0d82e914627aa6063d0ed11cb91fa6b1834dc66db50062d67e06df0df5efdc770687af22731f3bace387f831f96b8066afcb10a8b51420cb8da48dacd25c2fcab37ea10322b4cabaeb53bd8e8d5cee7d802dba1fc32ad01a955cbed57159d3aff0ce58bfdd41ebc8727a630a158dc261820d21470a43f3baa67e6728134f02e7b0e60bd75f7f1ee0917704658163c2e50fca94f5de7781d13c6e7af0a56e79e83e8a50fa17017c67a463d9035f1275166033c6d478247a755ad2e2d4bb89fb7be9f38b3cafefe85873e9ad7bbdf5ec800ae1fb5820a3dbf95112dd5adcf54ebb26e6f6b374cd8be7c0d9ab23084ea2d9e5f269bd3afc7f1344b329f95daf841d7633f798c0a330b7031c7a69bfd97a9285ca2accf3549ec1b5769bb968b7d8bf785292441fcab4ef3ffb493d0219cb7f212df125aacb978ed7311dace3792cd74fa96bf95e97e411645181a600bed008e4fb268fb4a2d28356ff11561dfe6d38f1a5f9611d7882a0bfdab091c83c6b66ca6a8f08da253fbe60dad2c72f31c171d090338df27e9c688f5ed5697cae800694aa0bb9462bb923dede6a80c458560e0217dc70afb37ae9f8f56349da900ae531cdc6b82cdb1a7d923e6e4b8c4016c6b1a\n\nInput: 0f52bda5ec59345973e39247ad2ff5c15b81c91016aea5db9f50a81e38e7bb8f404aeeb5bb2cf470d048dbf6eb27a30a115ba3dabd2d37fa64288501f5c1c6ed2b8e9841e59dad2197e9b31381fa133c79566b3251686b5be5c513aa0f1ce9689498574cd9aff42e66c8e9f3d9e127676c2d8eed4541312eac1a83026a107329d0befa3510d9bf2dfe498cbd4f1070bace8777c67cc141428580ce167532e6c199abd44f5d6d4abded7374a9da9ad962e96651469f12ee19c660c3e044ccf1bf2786b0a85420e6e43cb6addc6e603ebd41683136dba08ef4aec7467943d5e348990cf2572c0ebeb1cefd3b8490800c38d55a7ff1ae2359410a5f2c613816844c26e1f84de3e6d823fe4c58ed0cea50c6e0c21623fd31336bae5e0cf53b7d4819c3e4ca1a2bc31bc42372db7eab08aebd42be2e1731c8f9eae28374746681ff1f2e5bdedffe0f356099b5306a7e6d562da9b678ff7dec4731710e691147a6960f476b5313d1e9041d574015cf80e0af0946a552d0cb9d4472d7bb2c353df4da0b37aff9069e38ef3080adae82ae62372090478c26a02e08f0180d359d361cafcb834b620d7b31c141bac4c95c630787c0e3b951b1b14351a068efd60f2279c54a13\nSHA3-256: 80015db0f4b39ce678af8349f337a1e9e25424998dcc9a3a0f07cf8b857f0646\nSHA3-512: deb57dc06f8c0275eb88c0ef221fc01502b397daf89be24c1accc61ea3ac4275ebf2b1e66e8981b30a031a8b7d16ddd5d2a8a443541304a28be85540213fe348\nSHAKE-128: 7d2269c6f98ed440570db0be876e1252a59a6b63c4324329277aa3e1744c288d107ab0c0521dd7ae2a6b820d12618d67f3cb38cd75ab49723831aa094229880cda1d107020f397cdb4fb73e3b5c246fe66d73b5e8e3b94fb7f5e1dc1c663a247bdcc6c75cabe067105c1b9b93effa4b8821151a50081df466ecbaef31479cc7f3364c9f8528caebb8ac700a7a6d7d6646e24b59fd7bff83608c96b93c8ad4d3ca50889aa5eed9fb69981403c26acf527176aaeb5c4f3afbebed3aee659d1f68e9e2368e18dd19c3e24042b3a118fd81c465357f102d06fb00f62d62a10b8654c35e6fb9980e4308c0cef1cac378c4b9fd9ba77e3f6f6ff613e1f159436935b9b344cfa8f32dc05776682503618f7d303a115e923528d61839d34a715bbf5b76410d0dd1d158d374dd40423d19be908c1d5ce6472be01bc4a1194b7c1df964d02fd1b0e2a079b8faad0d6ca44240c3f9ef40898f5096fe9bbd77b322a3a61757a6d9d1e8f674db6d5889a358e6625bf2082069f73afd4e007d9a75c794a8493ed0c474fae298e885de45ba85adfd13553b9444623c9a85cb3a3d7d4c55f5d53517408df63b469816d3f40541eb5f64b4d2410fdf34b73ca9c5a0cb8d781c2583532a042cb8cb423a1bf3bd2a1023fe19d622aa1e0a8f072d57ab313ec9a5ae0fa0f2ef506b1142687894b702457ad8d11afdb7717919e1b39a08d86c2fe57494e\nSHAKE-256: 742db097c802137221f46888528642b9da80368a6982122fc05c7e61592ad1ad00e2354bd7d723b60751a1bb3168f8f93540568951a08eba6d8c04929b1abbfc767597cd4ad684141c2e0174e14906294c9c60cdd9078041de790c37ee6d0ae2e18f603896d0149ce75f18d543016f19421d254b4530e9ca7cb3d3bf44590d33793771d5c395e87a32a13a78a56351ec218ae611938d2e2e550aeef2e6b4a4bbda6e6aa8b6ef3693d84b92088485b231bf443adbcbe8025adfdb6519b62541bb247cc33b73b9a5339cc6d0c2295b7def59a21ede3aee7b3da889f1cb1e1db6e993fdf6adfdd81d3fb846b83a4ce58c3ee539003c31c42c85ac53fcda3e4c1f8cdf3c296ab2ec143feceab1bb9e7057e73b95258798d40510d40d9841832ba02319e9080d5f3ab24841f646538eaa115862b319ad6b55b1c99abc0d25f012b5f499461c3754d06d13f4ec59e43544b40654a4eaf643829ed0eafec95e5a202f5d8b0b301bcf9b92657283fc9133e0cf3b9b1b7541b049776317c514b543613ded0e159770da3611167a0b7821e20589a95a0fa1bf3a5ee983a23ca03348cd686ec341754932ff31fd3c9c52f8fd0524e3cd2c4fcb17267ea18b66cc8a1431895cfc7f5ed6fb5c52e48a5dcb8ed45811d2cc1095f6f9bcc5893cd47bf587a2c86e11b6d4cf6c448543e355698fd12971ea148e28c3ede3e598dfeceebf5b7f49b9\n\nInput: 6ac8be4cc9f0ba7223f8348fb9292b0a08900d8de0446191b2bcceac3ae530a1ac7013e558f61dc65e879ba97434874d6633087bc13b42062f932469ff98942fbe8c3f133624eaa8a94833033d6c68a0b163f9ad95b060a4d67bd4e4b1331138ea605ceb6d2781041845af4b4f795c057b905b8d1fcca232a8b615fad972352b281e6c3c2b3dc9be6d45e0321e0d0e77c75597766de5172ac180e334fd6bb61a59589f07e61fbd26a297849e985426c8a1b118ffc7c9d7bdfed57642cbc7dba1b4998d4cdb9aeba2a4c06d136726e36d4a74a3d4488b3cbf246b6bf1a55a0d3725aca4d1f98c939f8f355c0cc4356bf8a347884d5290689b3dd8da95a629f860271b1d41e8e9c0a6f04ae3102d56058e2bdeaaa0607960b2ec3f8af58cef56d7522df4d6c45ddd17f39e8349de0decd83bcfb55435e6a479e1a937e7b941be2c54854f8c1a0ca271005dd5bf284db4383d43543c12998190a2eec6d4386ab8ac8ab57db96ea3332cc4b2afd1e8d31016d47933ea2f690921d8475759c1a7c15f74c945f50d53cbe74b61ac7cc6909245802c7710591c475e2fde02a4923ba51f81f3170e57c273e91f279853febfe6e37c2aad643ebf9fabae00ad6be2dea23bcf4b\nSHA3-256: f51935d013780f423a687d98271999ce3c44850127fdcdcd3181ef729828f4d7\nSHA3-512: 98d002c797ee5bc35a5867dfed873ceb1950e0f712ee932d7c0dd17494e2ac8402bd5a39f48bd610ad0d2ce53498b52f53347da870367746c4ce70a66bd22ca7\nSHAKE-128: 470bad7c154059faefd5b6373baa71fea7779975e30a6f84164369785d65cb5241db3adb97fd1f74cbbf3b602e98baacb75cc34e6c60d02c73ae1ffb861363f71a084e50696c1f4a68e768c66a7b560dbee500d5cc9757f126be83a40c215af182550a1f93bb33a9e32f6fd5cf4df6c75e5faa185491be869cf232dc643e0869eb40ebb79cd721d4e429ee4985d91eb4d90ce2ce89326d26f6e0f892540fd8b3811f28c5327e9e7a097a32c91d0aa6b4400b17468c17d72eb44e72fdfbb52307c25b02c1ca6de77e2e3449226b63443a13695aa55588fc39bba98545e75c7ec4f6b51c74a4bb5eccf1f01f6c2ec40731a651b30e15c740f7d18cc26cddccb56bf96f08b614d16f15fff826de9f45dca568d14290ec9c5f60d829ec7852b6e899109b48a0c50ce43353dbc11d82d6c4e254990eea3e7e6cff5f6b58dd41c45438d6f8ed929bc503820a87afddfbc6580250ca47ddd1a410f35aa671c52237a790d3adc0f612e1f8e4c4f17d93800289bee58dafffbefe4bd5cca13ab8581163ea08e115a665c63ce65aec9843d64d7c5b2afbb802055b80fa16c2f4bb4726f91a1c09f974838e6dab3b5af07c53805dcbfa78a9b971e12692b93227eca01645f50768e00b6381f81577e341b4e21ef41709302736e399ca7027430c7384984dc68c9531aeefc267e25ad3779c2091a35fd1cc52f310ced71434bfb81544077af1\nSHAKE-256: b1dfc6b0e7f81ceda9bd58f3", + "b75ea9b4946dc86a7fbd07e7a13ecb9bb104e34574f6cb3853c4a0653ae88095cab5f5f3f7bef8a103f690c16e9b62b8188b2e7d64c72bf5e6f30ea5867f722d395fb2dbf34c09dd3df0640529d9ffffd089479f9765b9c40fbebf6ff27c95cfa37ef8be0b24a57d8a6370eef95710d89e88e7b5e6bb905c0ee02b0cff8d9c7d91ace6daf38fb9776a043ac7979346de7a9548011db12e7985f0bdc9f1875a6fe05ca0a8db692ead9288bfd71d161221017d3ac4a29804ebd68cf11160bebbde892c2bd6030261f2caaa35ea3aea4c18722668b516ce1bdb0ba9d9d727ce8a1254af7f80c247e3e40da5fa4a10fa69f1382524ab4e84a43605735e8acca64420bf6bf1e1dbe0f813d3d3cb914e1e396cf0afd433cd6ea056ef772e0acbfb407c3ce0efcd092fa4e65abc83d04fc46754b2f4ed81396a25e8ba2816a8553221d48f10c0c5dee6b6ed46c07ef118403880f3771603f52c49130bed02f61f06e277ff2fc2b0cde0f6a1fc217a464ad4a3506bed074a2331149e645252ede565d65150e1fe10e47ce63a08d175881e2b5cbf6439cd02acb209be15615087cafea57e5bf52e80be96fdbf1a30c232d68826acda45b75278d0226471fde1ab0dd61abe93ba20aa050ed919bf9977b0997ce40322eb02ab8c9cfaf4f876842886713f461ff6e2008f5d8ce95c40172a177c5c87eb91bcc7\n\nInput: e468c626abb0002058871b228b678f1519d032ed77afdca657c579d58099e8abce35fc6576d8adf69040fa6007ddcb7b947deff1c0c6f83bea834647c682dc129c05620802e17b5d0d68febf5ff47fbb2f92c7ec8589f1a40e967855b57bdfdf16f4be402ad404025688ac86a90ec497670491b7430eb008900f58d4237f6c38f99943c25af57c1c7df1645c3eacb2508ab374b268a17bf7a20e8c857177086b96766201612b3c68e415a09882997ec7dfed968ca644fb8765766514cd8366ec464013eb3dacbb62ec0b920b61c27b1dece0aa277622ba34f2e7c24d603213ba2bd831b8bab8afb26c9a7193a7bd194f0a0488e60056835b440024714c18d60328df29aaf5c9f28783c9d7ebf12e86c942e2079e69b84ed6be99969d0c5b13546ba73eef1bfbf00b0f6a7c847043e992b4d8fffb83859a4b4ed9485de068557545300c095826fe30a280c9575dbeb92668c90d7e8be7715abe9ef1a2e6ece8b526be6afc9c7eac98b5f52e1fae70ec9bd2cc026ed040b31dd7ad675ea670cd3fdda43927bded41e4312382f08d2f845ab8e1f1242892e3268dc48c0741150628ccdc22b201f523f46ae579b23ca845235eb5c5848621b597387c90ded7266851bda30a\nSHA3-256: d5b5046879c90cdb052aea7369912f75b67c8c2cdd7d6195485551fae67bf48f\nSHA3-512: f4d7c5eb8016bf36cf2c239c735d133c1c900d7456a15c75206097c869a2c37cd25468fba909bdcc5ae7a6869b75ef7a4eb0d5cac978547576bd8fa5b9f1bdff\nSHAKE-128: afe3b36802cf8a75d83f89a05dc1fb268c4f767da17e5a223859d91f3a0be30dc425b469b23e001a2f2531c7c767e4075c33a19cfe128e2ca1849cfe5dc35b16573e7f416a53291dd7da4858b5e67a219f5ba148fb13b32e81a61f6d323810e7af353e74b430da60b388bb05ffac59a7e4d0b62585c196e7ec3285549a9235f27cc2c310e493b9572bd520d976f05c80e85e485523f6dd9f005d59cc547729e23c14ea41eccd0fd4d98313b4b51d42c71e759e6f1f5349e77d97eb2e802eacdf9d0bc8fd684b2ec1bf162f320f46fad3cd98b7d59af61af90921a41956ea63faacc2045e58cf6b296d5627c43063fe9300aad29e2f9a1479dc2f73b7fad9b3b9e952fb19e04cc8d88c51bb71bc0b5d9dca52f0c3d5579b91df051c9115e1c6503a10e4d8dfce74fad92567d950723a636af4883b27f275c18610c5c096f8666e8de9121177e222eddebd8c4869e353b0900dc015075f58449ac89d9577fb9fbb31677b017a9a0e9ba87043f444aecaaeea4cbea37d4c7a722ccce6b7aae41f4e5c617a49b2ebf58877d41d452d7732ced4f33ec3eb70ffde826ffe3b2755e23ac43026a1fbdadcd434fc151bf23e8ffe7fc146ff8e0f4a1cbfbbb9ca85f9bada6784f8f016088acd3d2b77c1dec04c2abb5c12f62db95d04c70f8828d041e4ab62e3bc1a536321bce3643c46c852922f5285f61d82a35f92c75926d21c0a852e\nSHAKE-256: 500d6e374bdcb9f850189e5b877f7bd72a0e24546923c9e7683a45f29940fa0a23a4b7b7e0ddf1e5174cb41f1f76e427caecc37da78d07bfeefa70da7a91a75e246810c165fb9b06de8e612793a8838f7f1d591c4b17533e846891d107cafd4b6f7ea3231d7f41e09f5733af146d27fb7e9b6a818a1c33b41d8112269bf04dc610427644f13d74fdca39223132b166c8101ab78e1019725be8a1cf5423fc5d3e1e73d6da809c9cdbe5ec31137e47dfa9324889d48fa885d1007eca4aebb0dab2eb5afd03bd01bc8ce0a3a27076ee366c3d56c6e52faa9c597d490d5b8086142d26da66dbfbaa327b585afe378536fcfe1ad7efe85018c8cbd0b3252057d39099faf979070a11f12e1a64b4eef61735b66be4bd3365b14ad8f44b2f06ab8de9bfa47de972bd629b584879708b186bc90a246236fa00707afe3cd2170a9fb899c9775516cd2fb9b64d3184240642e2fa4c8b0b7b3cbcc4233bee37a96dbae228a4f472ec36b9ec1d52166e8cb63251e8f97d3183940c033279e88e9625661584908b81699329c9c8e0df8e79e6633c54100baa6f169a1d77fd3d81c30f39aae60f3366ddd8ac9520f41121e7f652d125736d407488278850561517148d2bc6adef0f51158200ec7945d95e4349e2e7d5ad7e15bbab9c7ff729e4b108ba7b7c6a50df53aecfaea3111be12f80ee6ac559b9197c91c92c41dae1018c024a3366f353\n\nInput: 052878741c9792dd4a3a3d70585bfaa39c50cf0a5b6a0b6ea8b2418a626b3a2577ecb35bb60548bafc34d9c6f73e29509f4056c5ee0dcda369368def73b783fef9e0652c0659955fccd98d8e85a77a73770f2628aa5bceae000e859b6329e5e60becbfa5062613ed5085bcca86a27b5ca057b09c89fa0d46e448e1ec95099a3627ac1ce21dc23206ee2aedc08b7225ccd35652e2ff78633d0a675e07f9fac333beb9dcf6971cd5286728f29b1c16f3e834309227a8b292db144f6df525b8ceca57d02eec80e805e8f801d5071503bf8475dcbf42b419f18f42fc2ba54a028f5415fdc56d7cc2be1d37e46b6d562c5672c40d529826f7d9b9c47d132e75ff0d4ada99cb08a532dd50bb900253bcf13b74ba5901ce61e685099e2b4983c639d9ea830be05555001c9c9a2e0558f0596c3f1bb47a3653171d41fb7cff088491fbc71d5a2fe659bb791be5f432b075b4d23887e045541fba3914cb4dd9c16bc2a452896d30e07841d487b09daacfd1ef84a44b51e17d6c2ef2e66ba2fa3134d76d93f42e9ac4049693d9b507a5aabf08be27939a67d373d7f38651bf6187de0e63cc1eb0605f363f380f3ec6fbc1dc063c2cd4d39e1f2c1d510e416b52a128259babf6ec601f\nSHA3-256: 8a86803345ff71baa2898b7ec8ae970fd287de6ad70e5c82f793d3d7515d1963\nSHA3-512: 86d28f50241437b73f009e0df6f3ab85c985b562def3bb6590c3dff88ec2d8bc614b280eaace69dcfab15b1966735429cb555e6d0e613034d6509f8b18c68637\nSHAKE-128: d976b96fb0cc072fe5b01e7db382063cb5f2df303330d59c272efa45d024e8217b529384c7bc7e573bb5f8f09df40b3ff4544d8b12a69990e1ce5bc19b559f466b33fb62efb5197dca06a58186885065600f191d0f8b6fce6d91f39502ccf9911b2020150db96ec20976956544ceab630b8092feb7974de5fcce1e821962b6fda4993bdfb05300d7b123e5ad2d4b99ee650ed5b017368fbe64429e47892bfe148d1d4452cc91c774d0b1ac2280e16cb6c1264bd380cc6dc1396ab1c02b2e98be685c8a201a869cdd927bbd8b7897208374f5d4202fb701a05f9c16b3ba54e5670fcf664149243a2c4aea369456a9b919ff0749014bf8301570bfa715979a0fdfd6d075d15af69f71157a835c898737a5fde47368abea2a58c28436cb59a520f85d08a419ff4db58506f8bd219330c671cbfa833f99bcfc294e8fc8d4b30c4de71779adb66215cf6b15880e08c2a037e4338a2ffb29cbc93222e1bc810531040987df13d0b2411df31c62e682dd82f72a1b43d546eceea8e9c7b4932b277117f74ba610e2d30a3faca7d4e9c822979407f829a3bad622b6e96c9d00a9e826972112f838a4890def023c2651537539e95495b5a5583d584c3cae8e67935f7499177fa6b48cd2ca77f90bd01797dfef190ed86a132c6536b1ce8becc88cd8b1fa8889532fd223b2b7ef4f975c26902c4018f10b2e386d21da96df065a06b15ce7a1\nSHAKE-256: d5f7a76cb4a5ca5993275efccbb1309fbd2e54282fd5af683503493a112131e38d41b6425fbd0e6c8dd7f061e4db7f7eafde5e2661e7b72f6bceff59dc6486995d020308c264585a13b2777689429a25d83064c9279e21abab43c58012498441121db738bcd7a6e065ddb87b5787cf29900500cebb6914fc3c099c69dfdbe2d7874dbd447672087f4d78a84e1c16c713173ac2fb47fdfff1ddbe466fe9d2fdf483f609347aef9c94ad335233045ba6aeb2f434e1218164d9873531ba5d5ad8e4558da26c3e58625e3b12842b3311eec20e635c9a15fb470ccb45b5b080022a980a9fff64960b9bddd4ee849bab07bfa0142d5d7d89a448420255b42fe3517988b290b5a63073a2fb57fd0791e59ddbfb4a63d24adba2dfcf01a3ef3fbc53c0f95f127ac221d50f8918ba8e1a7e6c042fe89fe958b3f693b61f43e0f6f6b8f3a1c224942f133d02783091ae8249e57c6d0ad253bfd9c8cafefedc45990474ca9bb2249baa0ca1f3beb805464962694293cb8b905f0aff13390831078333d33ff5cf980d9b184c2de7c1b3e4cbd0daad29e564385ff66a17d9bfcfe71b1a9a44c7d8800d49552135fbc7d24fe01ad59bf4714230e66ed87dc0366db4d77c177d7a58b320baac4ff94f6ee183126c691e6ad7afc4f21e1982316510e7688a0ef07798c0e67cc27da5f5706d569c6f5f2434574c71e7a2ff6aa7e41f85444a06cb4e\n\nInput: 588b18d22a0948d96a5f947d33f1999d970c558a219755d9de014379724c654f2054d55be3f8136ce1e7901fd35eb5a0ca7b85960fd0ebb3eac2924b02affa731ae6ecd2310b70eb0d1b49414373d086adb330d172513817998c2db2e187c08b582553b10505e3c75fe93b8fe4cbeaae9015d099ba6971e640139d87a154496f24dd2bf6c0d5afbbde4b60535147b35392aafd0f0e446f72600aa2953cd400e46e0414194007d585298382d9cb88d97abe5e538506181830356c0007b5bfff0ac4094c7a95a6b939f833bec3963b4d37da40378d35b2303deae5b6cf8320af0d62690dc6fffe7c8308aca9f5a5365dee5ed9b8fd5058c141e657cdb59c1330263629e896cdba9b82bdc559583ab1b3fa2155e4093d28df570374024a9361e929e2cb1b1572cdb8a2c884041f02cb9b266fca72ab7a4efedb548794cb13ee6c5a20a7bd9bdb14b8c2f7b9eede4078f42478346649b1ccd317f8d6666e2fa8d3aa8eaedfc0d5fea2dbc9c7b0d14b989f211b955418da9ad74c7b6918d7491005a618f86a9e8e90e438573", + "391766faa3c88a6b1f5dd57e958e33edb31b53b836d75cba64b0aa16f2f75501452e296952519b83e0c1971a4adf291228aabf2ec818cd4281be5aa\nSHA3-256: fb7b91941328b746ca65f49cf1a5b15ae9e2044c8c0a92254e43ac24c96a8772\nSHA3-512: eb3d3fce17ba663fab1681635f964032e2a41609dbee234df4e0eb8fabeae981ecaaf9c5684d4e3d0ca075a0a4dee849ea6828901d5ca39d8275808c71a623d8\nSHAKE-128: 8451689339f873b86d8a27e3e56323ff0b313f6342c15afd55ff9593d1131d5f4f8c192bf426c9fe754ad1b8deb9fdfdae9241c8097f65abe9876df0ebc07a3877cc4265ab7aa641f98fe49102626347d40e35db8a531d8687433f83ffbe85e8f7fb33e098e88e18bd1fbc61e82641b74b7cc8a7b27ae1b1cac28c3c2e70299d7545a6c9aced78783809bdb10272accb8e706601a4cc0307050591ef20189fc7fe5888f575d10668975115d53cb1b157601dc4724fd31810758af8863341a4bdf2bdc5a9f663c07710b71e7ac3f588bc7ea342fed331f87462da288ccd1b5f7d2c7213c8094af58fe7f2e03c601eb7ecb1252ae39b24b376597217a8aad6124d1bdf385d6b34201a62f6902ab4b695819444aa38b80b31b50862bf02c72e57cfcc73e179f75ca3637ac4dc18ea5cfedd0aad7e017c5d439949341a5b34519196fc3793afc505c17803016d03cd939a852c5fb2d4a5bd10238bfebfcbeff8e540e4e64aceaedce7251a41b5b08a5eeb85e539592bd5d5a7260dbde4a86ffef72102564ccee65cda58590ddad3f3a2d9e16046ae0591cfda8ff280b12f398d51a69db32e1b23ab356c748f3d9d02051990b0420cd49d79884afd46957dc2c404a64cc7b16c189c2f8c0f989762087edcab14bf00cb09faa1dbd03aa70d73e2975ebadcd64fce79d37931cfeccb66b52a81e968c91bb8a8f57af62e78f74bc3ec31\nSHAKE-256: 4546c8bf6a7146f38555999ae79ccb6735fbddff3d6fcf0272bb3e7c41d26baf96f1ffde9709813c9610372cbf40d7fc7d0617be61ef1579811ac1fadda1304d00ca30388e04a1dfeeb12d27fe05e503182420a84c36420b3d133270f3fdbc84535ebe8500a57dbb11070713b8f4adc63c04a4819155d4d4a8238d24a2d3cd5afb37b609c6105c21ad3abc6f798758573c3b728d9dfb2b2d8ae04f9a061a27c6db7080c389f1563eb9e1de028850b06d920fff426ba81b6ace384208556d896fe09a5152e6363ab91f47d3b4747b175f68a0d3d0b5eb4cfd589f8263d535e61d41e4a73bd8282faba90c4332fab362982bc3eb35ec8da0a6237d5d5fdd12d56ce58b445c465307c8011c34c4e39eb1e4a7622272bab7e0c541368a8c499493c69439a6126bc45c35a74db4be1ceb5cdf8a8486e4f7be2487c5d8c7b9044adcb788a7a434d3de5c98332273aa440ab698a01b59bfbcd9d476ad7d299c38a79975fc6fd867d454c65fadcc894fb31e31bcebe9e53b18e0b6b9f68138064cfdf2cb7dd89383628ec148557ad96da6994c23f7da0171855284dbb74dbcc35fbad615daf132e257b024d8b413eee89e954cdfa4cf171764a529cd7bbc618d143d9aa760d19c41382a169f776db783e68187bbd7b17ce1eeee3931312f6c77740e2c8d8877f07b254756bdd38bd278008034f652ccf8491c16c88fb6546ed9b996d789\n\nInput: 2a356c464f2b73e17155a58472d9c72d3e9c3827247a708a04c61d231467594acdbd29db8646f3df025548bad45ed31c33e4138ece4fdc1df5e1b973b1c2e66bf9f5c8f7c851470a514b52c8c8f9e7f11eee03e7249783ef0e4e0ebff7119db94abc7f667843aecd14854aca39419a7d1676a85035fb1a5a83769143a9c2589ff1a6558427fd031585ce7deb0a6810e3a381dac5c8a4ec651bd5027365d5c1bf31b3fdc147dd3648dfd45cfd0d015217220f0a0e59787a9d57bc677fbe2204f5325918e55b2a92670ae2fff1a573b78d3396d28be544b4ae75a78ef9944f4565a788d63fb810887c24c1adc16fd6a5b50e3edcba4149f0e959f3cc54873e910fd8e49b7522aed9fc07ef06a171c780d6b19601ce3f1014995b8ba9f868f733a87f74bc148312b2741f89cb559772d3a6ddaf3d83d01ebbd2a06646c228105d44e0eea9398b907a54851eb626f78c0962ae5faee81dd75dbeda907a0ad25157f4186e0d05fefffb840ecd8214fff883e5d8a2bcb6e14d789b50c48bd37dad86922c0d6f5b21d563a9e99525b076010c5e52feef576732a414f5c11e3653c9df212dd2b359cdb1e7e5663bc67be88715ee5e7da6253b5aff1d9619a19f574d257e17c4a1075ba0\nSHA3-256: 2024a961aab0cf91adb92ba9d8926ab0cf953b1398336b3ac73fd337ec8e261a\nSHA3-512: be0de68286aa9cf357ca3bc6d0e8479a512faf1ae14f858576be7b6bf6c619a922f47a68fbf61ec5d8021ca4ce28f08e433beaee1d9467dab6f6f3b48789bb15\nSHAKE-128: 7838792577c9b2a2f67d9d6be15bb7c136d13b5d7a0ee2472c394ebcd05c56f461b5f5e64c8af796086df97124255c8ca89d70da080d7e41e2a22ea883b6bb4857c5d377425cd447372e3276cae78537fd39628f4ea14a195434eeeb69f1d551d1bcb47e2ea0cde0b5765dfc421ca584b7e190abeeb564525695b144fcbf14f4b94972f7ae7036f128e46f7d8a6eedbc75b65f74de4b3ac70c16a5f565f7ae9d0ca8040a1db830580fe44bd37d8a5f62490a9dc1899a5013919cf57bbe18a9b43f18fa6260d5a2b6748e06d5104108f7a8f46ed1d33696bcff3ed1ea6498cdde4ca714021ba244c46f38c47564e9f34f42bcb7a9dfa6a3b4aad78c078942b5ddda196d42c13f5915d39aacbf682b60505f5d8f5e50d828a64f3a41e3e9ac1d0303aad6a49916d4f233ba0a9c81594dd62295252a14ce42703d18e2fcb6d86f2faa779e988ff5593d2d20d848287d932004d9cbd735b1a9b38f5e48ca970fa735451dbeb51c3084f427cb92b060b57aafa1118366a68278bf69bc5a178cd109a3ee51361fb309fcb21e825acade58cb9434631ea53d4e18c0882d4c7b9d36c0530291100259ee9cf86b99047eb9b793a55bd0ccf4aaffb62623ac1e66f775f43187a38f2630c181a324e9a6935654070fe2cfbf5b5f7eda238f7ab22c94d20b7ebc947263173a6725c9b322ac4448c466810d23a9326cfe0eb4d11071c327d108\nSHAKE-256: 16b3d2929093d3c744614a10e6497809e304dfc99fc5e8f8b4a76ef1795dd72664d6ee13db3efeee6b1cf5319b08e3dcc449157e8cce46ce5363b671b7c7b15681421e74c844bddf62af115435eb84eef836026c868d22c60b2c098714b47498f0a2d9c7fa9d18f521aba37288dc3521c1b6847f3680d79bae22052b069be765c05c8ebf7e32ea9c2a1268f96553037d7125bd98bb31e9fbf2f2ee32c642006661418812fc45167c3a66e9d0f47b6c338774792249663bbf0751e90371aa6c1b3b64c21d6f7bea5e84d611e3cbffdbad44f0d42a1d0655f736d4e9fe928642ab50f4f8e7a0b8e0d7ddda046d5c2ef638163a1c6e8792e4ad4b46b1a7a5c6353aae320339dbad56b15008882e67cccc52b130dadc07b344769e5bba8f00e408e39f34fb140943357892765b40fd3067623b135d622a75ae861f4f785718f7109b716a9d9f0750bcc1784c32def14ac857c297e1f9244fd82eca9730da297e9901b6cc0f033369012c53a431d41b87c3a1260fe6ad339396767a1a8effca8402b99d436ea6d7310ee04b5fadfb87475f99210577587a00853341e20dfbd6c53e78e9d39ee6f9776e7951151969f9f125d0a6ed91a5fd249c1a8a4dd183371c2bd81ce4a2fe95f8c5f37a20c8e25e24de9325ad531fde70e80607074afd3d12af0450defa40011dbe70e78f34aeabc2cd169281420fe4109ff72ef1073ed706ae54\n\nInput: 388ab05d656084264bd2b47820184eb2a3f546a13335dec58c79c3d8b604abf6402b3c5d4d483d43f02637504e388d297085090b7f9e5d48515c54d7cda11fcd4ad5823d7a387c08debc38990d859ef0e879bcba73450aa54f45ac86093f5d998fff522395f3825dac12f3cfdbccf99f5dea304f7ab975b634b50d6dfdd51f7560d46005cf6bb735d35cb56776b06014e560131d8474e4184199770e514b4395e2a979cc9d51c832e9014a6cd467a5a49738521918b944a2cf95cd4e0b3ef6e98687c2c10a51eacb3ccee278b66a93b3208b2c8a73ef7b19fad8e454593804d9dbc27023e26bff8e7cf9cc8d85102a79d2da54ba7a1c51dcf8774ad77a6880247411b5446a0821050eb27f354da38a727c059c0d9e350e7cc604edd10e5335f98954b364fc41a752e7842e66d9e32991d4aedc2bf6b34b87fd914f726e0954ad8eabae101b866ecff885d6105b095a3dd5508db9cca7f7c688febf82a6f7ca9f340e237d47ab74303293f51e776f1328b0df5b660d5bc2e4cc78d70db73c80fe9fbc8cf656417ec6a4a702bcb42358f6af705bebd74f26c7d80abd90d022df7f10e66355cb2d5fb4b1bcdd3b15b9bf58eb49f3a9242bd7434b8966adf3545ece427c2b7859a1c1\nSHA3-256: 44a1bb69a67aeef6ca70ab777b18f0760d9f888381d6f54ee581afe4a3fdc087\nSHA3-512: dabd8f52ca31877f26414ca538443fe8c7d60822c068806485a5fbc46eaa351b04c017a20bbecf60a88af9c8de3139e836d1bb322b8a5868daa6e2c88e2cc0fb\nSHAKE-128: 0e5b7f88db52a81fa6cbccd1d45e5170494efcf8f5ae136a12fc9dee14364fbe751804741cf6f7b6cd6c20cce8e5c15f4849a9c117e5b9a81b2b04d868b47b64d07cb3f1274c9b80a322eaa95828d5396c5b758cbd6f446911337b5ab9384abf8a29651ebd1de01a91a9acc11ecf32e86d6d864547afcbad7be937f5fca42b5696ae5ba6ec46bc97fb5941fa066055f5d72cb33a14b07e68be6c551f013324c8508b55a300944ecbc59633a1be655e35314a5759bfc663a82c1c7e543a2a3f89b5466bcca97f9bc00a6ebe0170c35e56dc3981a0dc8bca151c724f8db573c58b19ecf6c1b2ab8b0ec7bacf14f862b12df0a15940338e45bc2ac950144c232e2a763667d8dd8515c641f2306a3e0fd90bf1eee68fb7d166c40539fe64cf7e166083a33481b7306ab21bff9ca1cbb97e0ed7a51c77451187285e0ce4407b4dc01c76f5a08e95e1a946764e39e5ccefc1543c30a84cf93f82813c6ebf889bcf5819054b7a4be4c3104a448504683f80f1ab6ff6e1d01ec8e57652ae62bfdde7e3dfd4b71f840c0e25a6aba24d24cacd74dd92e06f79625c43d68aa2f05952e51a85496c5364c229eee0296b9a461cce9c4c18df65138ff639b3e58504d83cd7583655bdab578205424e6cf27f54136f02c5a9daee21097e04dfc9111a558999ca5a819abe461705be70a10def9e6246a365ef01b206751ea0297fc8fd7b8f9c81ed\nSHAKE-256: c3fdab9ae16e2bd8057205208a91b2a62d0eb303ce6eb5be949a94357a2b31d4c048ef4c3a6f0f7a4ee8fe2606de1a3525caf1985ff343253928655c41606fe6aba604c2906f4a73ada8e64d0a325089569428df784c8e4a3e6885d24078acb12018fb26842697823350a003d9944c30c0a93f4c75ac3f7c097b01d5217cb08e2bf98ff928d744aaa3843d21a091be0d8e3353b3a397e166c2b575f4af8355c9dd8ffd20efc53841ca3866c9250a9ab58abdc24707f104d26463786c28b63d21c1d8fa371208b30bbc4", + "5a31ace2b3ee843f93f9f101bf25ba2a304615b1711e4504f582acc6178a12022b9502f6e7d625f363068ea57fb428eea84d2673e5e69a53c7d57fdec4aad8402888c33433e0437ededf20704e881a7ce9effc7b97aba2efad3ccd1ea8654ba2d2ab1d9382f966e2972862b3a8f8221cd51062e7b6b7b8a552954d3eadffffeb916a9bdbb1c7ffe5d8759158e358ef7af1666f4c0cb4162425c46d2b657217ef156ca87d82ef06361d19889c46ca3f01df997d9aa791c584ec26615b7ad0ee94059185f371afbebacfa2f682c680c6f0fd6dfe4b5132f6bb85bba0968fce37ecb99938e811eb54af9e671c9e335edac7051d8dae33aa3827f0763f231880ddf35a9fb05321c1788b31917ed7bf91abcdc03d39576916969c235e7e4112f4a75a7d55fc59f28352cbf9117d46754bb3b7da05cdb7810c8\n\nInput: 426fc389980b3e9eb00a56347fce308335a170aa49ed46bba21b81e4f493bfe95bbc24343ea7fa6062657eee750cc62694ecea335a7ba5a9deb388f9560d84b51ed84668090dd1d95cc7795e04f0c3e69e5c2387447170fe42c36217ae1359fa5151965c50f15e79cd0dd4503d6ccd5153ba2459cfba4e9141ba4c972e1539c260e0b8bcfd5875dde0e61c6da5890d4ceef9d600be5cf7a3585421ff34a45ad1a5ec05bb8cece330dfcce6f8d9c0ba8dd210f65d9ebfa0584a30b5aca028b492c9e71d5fcfb9a2ac31e866e94814e4efd122209593084c10bf2984a0eab13236210c729140bc0c042c3d4ca4c8814039f799139023979914712afed7b713ad8e3cdcc54730e1e73f2dc7210360e3ba4a66b3751e10209bb777636ae45f960de2b66b801826f569834f3a26d66ef5f238efd38afa4eb9f3f89c43fa7c00c427de8a1a9fd1b036379b01e00fdf9edc5f1409dc0b24fb6b7326f60b148d241ebfb3fbfb37e315c8a8d5855ca3873c2ec12c43c3a08cc74c880b8574cee52a6ac902abb7d802463475b7ef994a40c8851d911e6335a6cbec3efca12478e388d3aafc61914762ad71c7a67f10f498d3788bc1031b9679d3ae7a2e3f4e7ee25c08d09bd6c95668f5cd99d0\nSHA3-256: f0b87945ea36d101fcb0dbdce3a0e17542a6f73c3d28bf1b405ab03c98780da6\nSHA3-512: bdecb75db800eb32bdde34d37daa8c6ef6e37014639c418bb63ee4f803c79b984920cba983143e9c7cd96b5169e1990b56116fc5bfcb0c9a2885461aae4b90ce\nSHAKE-128: 667efb50210cf97456c693c4c5afa0db8c6306e1a02b1cf77368fd2afcf89dd3341484022f7f8533378750372ea07d03743b2e6e0e08185546135110fd0683b092e283cc96c9a99c9dc11284b6f73dbd230611c0f1f29a9a74054ac5b2512c97e6835ac06c385a9af2fa6d6c3de82d5e29cec9d8f9159fef886adbb02eea392025c5b94be6bcb106cb61f5da5fdc10942c11563f80c6cee973874a881c585d6c7c60c839f97730b07020246f88c18e65000d7b635e327aa71513b7f84095403743659b074fd254af80a4fd75ad850f9c6eea73c7849eefdca6649ee5c67884296c7a2c051bfe8d66c5c6d3b31ee254dbaea758f23b13e956cfab5fbd28f3d49e733b1c0fb935e2d86662c30afe413815826ae275e2b8fea40a95d2cc864af89b093f31dbad7d4ab3dac9484e76bb4a83170ed1b0d3df08f6eb5c679ac53feb9811b4c697ab97ba4cc2c86d0154a207f256477a01ab96137741e9fcd66e448c08da3a03890f54961bc4db29b33aa20251b9f041749848d0d72a770038aede59b6843258a67595a6c86706f824eecb6c36ef4f5596858a295cfd85e1b88f62aa9e354f69561c0facac07f979fe8e75495fba1636350b8a3fb1a09a07c11be7867bd525a278e527a56228f311427ea1bf7f3e28b27fc36c01ae93abe7d35b6206f9e313b6e37d163ae42815e02493c19e5c2f87e0d74b0d46e366fbc3fa53fe6c6d\nSHAKE-256: 0713124a25756b723ea120e8582714e96c5ea0fbfdad350cefd9ee2025a2d2dee859d51dc1d773cdada1113c53a59ce7172d1187610155a13926966c6a1821cb1c5b2484267b92b7da5a6b5a6446cad7a881284a97f2ab25b15b21d53e1964d1bf049cec6904e0fb9cd8b0e835f4d7bf0402f0a568875a02912a9c866547a714057e9734aa1cdf9c42265bcca3465df3144421ad08af4c112b724735dfa068506796631b8f4c9975c578626b98ac9d5e4d292a5e980cf8b4dd206d8f3109b625ea99607bd131ba067dbabc8f9b8c27d95c5de5c8376555317a1e747703cc29b41730fadb1b37307d4ac548152334f384a55d27e35707f925a0d304a1602b047ba5d1dbb79df0978118532f77a548e54d554948967804298f52652fc86a81f2764202114b97da359b1d9e1de99c2f228098d176b65abfd6ddfdc0aa04490f68e9f111c27b4515b1cfeeb8962b5842d194490bded19be7f082f16ad6f8ac16def2803986e1d3052d0d21bb1a06128f691c31df699a4380e09b7c4009b2eca22c1b6a7f393a3f3828e3b25fef6bb48119b648be015f1c245ad4220d633c89d4b4c68b403863ff9f6fced1dc7594487d31bdb478c2176f73ed68d2fbb1388da171792496f69e0671b31745086fdd5bef77de398d89345aa57d62e068e754522608c202e8a2a54d493c5b998c565e26fe83a23daf82193aae68b2409f3ae461e09a7c\n\nInput: e35f594f413c5d5f7760f76061605ef51611a860b386552f95272836a9216b8bb4d9080a0ec13dba44837ac907a9d34b14791a7ed36f9d1d691647f1208d50b9f9383bafba9899e5a2a6610aaaa5967d432535a3bd7c3aa94be2ae1e469c90922d0796698fbab7104bb045906a73f7340528b86b14dad90f1ca1d37c5d28945329d0d0bb4b70ef501471ae48765703e961c1f5b25a73ab7312cf9c3f95817b041c9917187d22a7239ce56d5e990b135898b809e77dc443119b5dc611448c6e55e42b13882465c50fd026fa598e0f392e5551c64e9a09d94933c59455664febaf3e77f1c8c9ee86a95e6b345a1be493f2847d2abdd98e459fc7d4a52ce44c3f3cd0216ee2432cd563a2f621cc9f743c6cad55239f02d3610b4b20b5e012398011b3bbc0be7b1d5399c1abf3824f696e1da03078dc9ab095f3608d92c748fb895d73e3913d19b4a6a826d964c85835dfc72630cb2faff4a5f445bac39998e49306db56d88a5619cdbcb94b43eb6c1f5a406f00dd860570d403a06a4521d00cd4bb6494fcfa34bbb980fb5ab6c773ad834ed452c2ac302c8726228a384a2f34d941723ae192507062e12b1dca5adec3879e760acc3bb1a30947a842cd0af75fcf3f14d8631a5dea98247f\nSHA3-256: f0371ced8b1d53c83d79f0c12f9c7eb51ff3395cf8193818728a1f834629d422\nSHA3-512: 8dff95fb245f204f3778895d9f907fb04f71c2d218fd4fceb8f3f7de52ac3c18486a9d95cca8b0dd60f3e11fb23d60be7a1f7255b51e0ff39455b2a94e2f6497\nSHAKE-128: be7f6404f94f2a45680a25a14975f5e48568cbe119f1038f1b4aaeedd62dddc6ea206dfbd81fc31f70ab83b563cb1441521cd42c850e134f9d6a2fb2d9d24d99603a891a94af8e43985c64bf8ac8de3d19d7fa28ab5a92682c1ba4c3d81ef758b6f603daba26edb5298e98d86b879701a1db43520884ecfcc1cd8fad12982a0fb2b3e1ada57ed383429318e1d884de8bf76b75742463ac30b35e85abd977d12b2960c59cb27fa1e3060a23e5e5f430b417bc0a36a5c04f8cc12f1dc24bf8ecb5ec3fa96ba3ca20531aba82baa6abc5d3c69874e121db16412ec8a55f1cd42004981c71e6dbe0723cb8b6a0b499973fb5f2424cdda52335d3b25d7a5eb04c3e33c3889226948b6a41861d54062c00a3224205123761ddeec38fcb11ee8e99107f02cedffbce42f796bf9b381ed00969cf37ecea9d27bf42baab6efa55602236c5e50e38a8e3b0b34a5ca039609bc6222eb15d0b878c68a417136ff4080867a5e1544c5c3be5b659761851473df014c2b585783a9005d02ee9da7643560081f3a4814623a67b4cf5d611bbf76e2424025457c8f84c85883656744977bdd8a1e666790de33b1bdf0166946eb3b566dab45d588bb7bf35ac5c284ba380717d25a4cffe13d1dd741ddadca4ca208af993ceb324705cc9b8e96a19daabcf8a849cbe56c46b9b047d9338c3daaedd16f3afa58a35c0f9de7a0912ec1228b412f139e66a\nSHAKE-256: f14c26049f0c918d86f5810cf50ece65307b20cf8e10413b231982663695f8ffca09b09c504d7c76798b2f28688ca005e055bfcf34fc6f5d8d0d71a4ea550f3eec2d67d51483e4b6c9d9a5f9dca6632284fd9c99929b8357dc96356f6bc393743b6b6d9f67781f45ae44425941f57bdea2f69f20f25224b2192dcb37cece2c367416893c5e604f3c70a9f68dc0edd617f2cb2c0062509e52998afeee66aac9d27a0fafbe65641e50a585acdb618051912c8d3bfdd1a83beb9d5c6da945734a3877e6d9551e63ab4af42b575373402528d582129799e3079e6c0d8ba52899eae277d1ca574c351d4f3d0b03c808b8cc26724137eeb6242ec86168f7bc6298f487c81fe3456e4d59cf70f6d4133dbb62c45f5a939f137c91bcfbe98e174992b77418536b9e63b5a2b4200233d0c25f6828117907349af38bfb52feafe30a3098b9d5c73f5851df4982698eeca17ed1922925beccc26c195f57f174de9ce17ce889018b8c7fb143327089c73eb561b1f6b263e8911f099e771c43bc73f8da1c86fb819c4a184eb66da3ff1b5e10f78b8fe715e7c34c44b5d07e526733175de01eea3fd20b5753a2b528b0f769ba9a4dcf6abe137474ccec5191e42a99903e75d51adb5348de0626d4d614620ac71a7e8e26c5b28c7e94e23d08b6ceeb31ae91d9a2aaff4ef6416fbd9c4c128d86c9ce16ac2f2ef2ba18df0210cbfccade94dcc795\n\nInput: 288a40d07d085180723f0abd3fcb73eccc8bc076e7e168cfe0ede84ba86a8229bf3f1456adae9e1c3a57408da430ec2491761c1c114da67a3e6368dc06b86edc8b748c6f85442b3f191ad0924248fa7542c7d02231ae85c90da5ce64a6bd7740a621d7b9c1f106293210bb166edc2a6039d180bf4ab9b33f32e1faf5b09908c8c7f43f74e0497f9b36e360fce7a8bae824f83cd57547a8206d305d522b7de3ea011f1f986c73ed83528bf3ad52600ed1f4434f61cd2f9a5971defbb25d62ed27940ed97df7b05ec7b3b2f23d474544716c726cb3adab3f8123400fcef6cb0fcd9b00c1954b178101bed74c15b0fcce850c43a4516f66721b70798d538ad85706126e46194b6ad5e991f4dab682d9cc8b8c2f8bba387e1575dbe5d39d573d6e07424214c6e74b09e5533ba6d88fcaefc996abf0f43bbbee17f8466a22cc324316a550501a8dace6a64fc1c9c10e6e56e79b9d905fcba7cc50bb6c079fda5f3c2596398087b83b0f74751f97a88c12110c5a703d1a3239ba8e3a148128bd96dd949d516a06ac196a36c491dfc78953362d9a613c32f737f62168c194e90e7bc0624914f7e771cfc6f8def06e4156ea1a319c76362a930e30762faf6babcfb07329b5297aa64cd4a15caa45\nSHA3-256: 6cfcdf957ec0fc26f60b5f9aef850dd936b24f029a1d99c8a84dcfef062839ff\nSHA3-512: d4de60d90ce1aee11d30b91ecd1d9f9b35992d7b6773a1637d13b03e0a08eaa3a80f2aadfe10810de47d963ad35447d765915d3b4b48ff8ec49c2e2dd262214a\nSHAKE-128: a3b6", + "057d5ba8860dcb588eb85543cbb7a0577fb988f2eb73ce8818c29f7e086c9398827c0e95112f9e4ccc19cea74bd40c49fc519af53b3316cfffee883e6a854894405ecc08a11cf2c3e2856bb325c9491f68747792326f5a09c41d1e5b0d016843f4b5b701209abecf9067edca5bd50391f70016935d8bf97c34b4f00243b955a96d3cbfb1c1e8e6b32a795c8b08350f434783b71384f17abdc0de51733786eb05de0de423859537f4b493889806ac91d9a14d460cd695ec2eac29fa8efd2894630ccbfc69935a82c876757117301d6d0094f47db76e73f8614f4f679ebde50d656cfa1e90cfe06ff653826c18e2e3659cd019f12ddb9d88a97701cbda1a59abf11fe2e354833210f3e372c21239989b515c22ba3b4bfb5222b4b5107e4069f09f6c3a2d5537e41ca07799df231b7281f499aa223dbfde90969a510690db1e5b8552487e01ca3f1722d8c304fe873eca1ad567ac6b47b73a872002177db538733b435e1fd67d134b647d3016132d5f7fa0698b539c368187f25890a6e88dd3bd94c5b5e8768d906605ee6cffa18a5ebdc36169f8874113c0a43d78cd72751f127960bd6812f85884a1445907b0bb9284f9f0d59f60f31deb4c16425d9e23d3030f748e7760007ab10487890cd1e7d8cd1762a6aaaba3957d323e7401e07e190543a7bc00bd9966ee705da7fa343ff547ab2cee6095e8c36b05b378e1d636c6\nSHAKE-256: cf33f3e93bc45406aebdbe80c989c03c4a9615830fe84534f4352e6565e124ae40186cabc1025df9bf8637c0107329341dd9f6bcb542e3453d3ebd6c2e060c79fa13a01587a95870ee1bc35aa5726c47e830c0eb619ecda12e3eff8a2b012e62ba7107a8f1a3250bc47d5fc43a2437df8d2f5d8a1e4dd8c36b9429c620c323e8dc80f2bef5f197e5792fa5936dafd4c7b76df72b68489faa3df46dc5985c3756a79ebf636f7886ab56d9581e1e30353cfc7de57442597af7e6de26a419cd44a7833f063faff6a71f9008221e332a57e83ec64ef2c43b5c6e1fafd83152c2ce79508298d9698503d585c46ed7536e684b99898cb5c04b3532e364e9dfafd0796c1313c6341e4b798eddc69b6231009fb21425561ca63746cb1d089415c1c24320fab89cf039fc25a1dc1d8c60a1deb126c43c0b49dcd468388e015404fe002d97dced216034a04c489b03896450d53249afd87e7036102f8fcd86306e835de2b51d722faa4d6086cf67c313b87eed6763d16e0c6a635bd0e1e8f4c06dab55c4134991be23b971b4eb823bc899180f197992b1592e107a40bf6c042554f064887f519fa97962b6f7783134853b76fc874299986899648d7d8c41ccabf2ed0566bcbd4938c728485b65346530ec170d3694e1fc662967cb51304bd5744efdc94b6dd0c817bb0ed3ad40ca1ca9000e11acf5fd2667304d69f80b8878dfe0c82e3d6d\n\nInput: e4b274d4f3ebad86c87de7b19c1131ef6bc5c9d9c550304843edeaac354957e70b34bb36ca1f82a134875de9ccb9a9b6f16942e0def4da2e8e845dbd0e1875db2f88735c9cf54eebc9333f8fe3f4607504a9c372a442f3c420418856a375d90a84a98a74f9a584a8741b205b7a7b6fc352e7f2efeeefb2d2c40ed1112fe39309e44c6147668494cb36cfd8642d543183ec56a4b0e353f8bb95612a28b839683708c1103bd6b58720fc350c7cd5eff548b28a8373388419acf7ef3b415de028b68465244a7b13fa406c9265a5d400196ae6d51c541f1e78c2a02c133ddd667074d7faf9ac39a360022e53714bc76c12e3d1d1e7ab97530ddcc5ee85289bb050a68a0cddc169bd9fe2350eed179acfb93c6016688614497049d223be3c50f028b7c8670ded12926f303e28eb6f8dbb2d20b0ee9d0533edde7cb726585fc071420dc6a7d96615f819427f6f247724f2b2a389fd665fa3a8ba40a0ae49dd3877f398167103fdfed635bc0b322d261fb9fc8b7cbdd6306f995717189e24cb5723ac43592636900591b28ccfa3cf6d9db1876ccec1a69fcf387a1200ef5be417c8a59eb95b7b70f54a03021786d3b3085f931721b2ae6ff44b2c2cc6cbd1c1b708eac510fd2974a0b6075198fbc5\nSHA3-256: ee5e44a25b7ec7d217ef5a9c6dcde7a7c9c1a61d4b1bcf8e3e9915d3e3bccfed\nSHA3-512: b18075b727382eb32c795e08f62626ad485486a38e924b646ac3ae690a79b1ce5d892e79af3ca23b343936438858ab9127a7d006266faa32f44d0546fcca4b3a\nSHAKE-128: 5e43c51f407bfbf17ef552e753e48689943b094fcdc371c4a72e044c91e48e2a5a543e1fb1ed217415960069d80ce58270ef7a14d57f8781c942e407279871cb5d55db4cb5af1a0a289400b1394a4acccc2bed94f9ec0ebdbd76d7137326909b1361e660f8c1e1cf3a672a41bf77b8c6d364477815249d98826cbf9604567684e5817639e10ffb83ba43e8d84254a033b1995b3ece9ab2a868e76c43451dce269b9a86cd1a093baaf3d8b2903b17398e74cc3f6790cb2cb145f73997b05f796fd2a725f070670a662ebb18f83763c3d60fd95374fa95a26ac0b39976e655644f900454d1bf13835068724571c6ef73fb08279da77df8743ee23455846173fae0655d903af8bc56ef191449ccfb30a6b91173f171a645aed023c4a9b31e144faabf1189b255a787aa5a071a22733afcedb61b094b9c726ea29c5bf1d0909736e4f6778bf895992d8bd0ad7bb1d1e742c76df08c2981fe7db97188531eba0f60bdced89ed592076e31257037747bff8f3afba99122fbcd509006cb4f6e03987487dc0a8426888d0616935e15d9c8ef4ec234eac61d9413bfc518f0616fed59408df29819ad0634cd1786a68ee1b3e17f58db943126eca1758d65ef6d06f7f69a75f1fcf8d98f0f154dceb20a3847534d238ca755b48e40b227ba2dca29df64ce326e29f311e6150c0169ac87120d179f3c0de7a080fcd33224e87a5be064486b88\nSHAKE-256: 6577c5b08b205263f0817ba9a0143737788ab67057fce0a05ff49fd0b203c299e36a4b9160663d687e11c2758b704698294de430f1fc2307f63e5d253d9de57d48c4df90f3b02d93ca678800cbc4198c42fe9a1fafc2634b115ee1657cbc8412bae9ff48da59261e0435a7705298e7246e815478ff597f2cf4a3b653130f487766f5f9380dd4e4adfe731bbce10bcdab8cfa1c4355ca2688cfcefc816822e08eff1e71188d83f5681e6ea2d6e1d582a2d7cb587926072634910930eaca5d16d76614cbd8ed42bd9976d7f4c72242eb7c0fcae81ac72c2315fa7c9b2842ee387fcceb47ddfd94ecab2e4f81a336c9872c7ba7165a62a4dd6594986b59f37c379b138c27ab3b9d928ce3e5df1d09828493ab9238ea1f36e4d386701cd154a219b9357d130456dadf0dfd5f65a0b0eefaea42be9770a3d5ed24c31e956dd7ed9391dc054555c13b2b869eeda2a9c5eb6383adea7093edaf08f16bc4fa34f656393563b13cee635f773c3ed96bdb66cc4aa64da86553fd44e35c7aa3c128891bb0914c9ba88fd64df3992d01205a0b9dba6763fe70dec3f444df22b97c86fcca2da530538a1fd557893a73ad3d51b1df8db19467b2c8737b61a409a2e4bd46e1cefed8b4859eb64902bb10d4913c067b40d9f714f1e2848e2ca6031e5c5489d2c98bbd65e74e1623196d5d84161c0b8362d9db14c5c89e41790da53f52964ec6969b\n\nInput: 64b6dc4bf2d25c2ada9d1ff1728fcc2a678c5482e0fcba6a7fde65aa76d3b4792971495fe8c8741795aef6a3f4e2bad3e16fa65d93a9daf1c7628949891ee4235fcf0eb166627821beadb497318c5f5e6bf52411d3e79b7d2bd5d16ee38cd7ce4e993d25ab47da4302bcabafe15e651ce51390dd96140911cd07c990f7055f8b2a873327a79190de7b88c7e10916e7fa8d0efae70018d704e8ce25484946c17813e9554f3c2bf1ac49083e285ca7afde4b0a4df520ffdde63e5db38ede6ccfeed1e817715fec0c6f7117e629ca74bdf8a75b57915ea8f71c352f78b9ece13ce82a32ffc535c8690eb9456e72c171f3d304ded2beeee1ed98d4013373226e3da825b3d1d2e42aadd97296b7057c9ba840a0b9f1c97f055c57aacd3e1c948aec7dc826794e6503b5a91a0bb7c62744f61b2836bdcc39b5b42edf689b21dd90fb0329142283a9856344c5da5c0996f52e028dce487f3fc177bbaf1155f4c0bfc9722769d30888c0bdcacc59eb6ebeca4bab7418a16fa8600f6cc6b14bdbf9e616fd6f59e7cd773388c998fc7f40729a34eaef96d44869b7a0eea7cb64ca3eac02efe08c9584d2611d7ffc00bced356572ca8f594d7c80396cd03dbc32525c250aea66a05d67ce0134d0462a6021\nSHA3-256: 2ac590e219987d88a7f00fb0dc30077c62ded8fed2fb88467de0070189929a0c\nSHA3-512: 9c30f5080adbb2426b59e701484c519445ca4caed469eebb98bbff06109fa331f663b9bcb65390c744271c25c83bbd9f2c989e5cf502383cd2dbffb00e2a9ce1\nSHAKE-128: 77ec7bdca874afd0d205ae9f5371c295d91c9114982a98e77be26cd868b13401c815fba5e0bec8d8bc38b060161eb2cb7ff8a18a5807f486a85ddc133aa97d0e3ba5ea28b9f5da9b01c751cec820cbc8bededfd69513eb09f26931b31b4e2e77fe6056987c8ea72154067b0e1a511c4bc61c20cc6f90b4997f703dc292d3d6e5c6ddd5c3b48df190941b385337102fedca82fec425ab1ceb7f9972f6146d913660453a9dff075a34a14e9cb565cfdbb30e2c51dc3e81bb7a8fd173d1b7e2407fca7ce2829cdb669945af40f58336a6470d628a806f657342f9feedaaa54364cd2d223d7fe6f55e03fdcb51043422aabf12e7fa20a82ce49c70e8d7c816f96c9a1f8033dff4366bad9297d61a367ade20ab324be71547506fb6f099e376532a3a5673909e8e2b975d3ef01657c1317de8d6f2fbfc8e47663c50c2aaa02a668cc507e00f6f6ab130574f92a9eef856628259b4a7ccbd051b1bea67fd2f51e207792a5ca7ebc7a5d4c72a010ce45acd9baa4a64b24c2278712df153bbb2f330a87df36da2ffa1030c0a149f69ab076e9abd932be47428016125129669e11cc370ec10514ce6455d297260758303437ac00235ef6ff0d1833c8fc4e981db9a12dba7bb5fdc3ca18d396950fde003449e42a2e303ce70d41f627a3ae57b370cf13f9e6dfae93b454b7bcb6e81c7ddc42a71dba7116c8df79b75ba92c5a88748ca2241\nSHAKE-256: fe82e0b1a041795c12ba5c783151d289ca558f6a4286051a60588d268c64c84245b3bab5782464b612d4ab573ed361c9b186f31e37a7a6a65e3131b925bc84a554406b3e8c6cac71751bf80f22985df6bbcc54f5ca84727fac183b55b096682721b36ba2f460a6701a9a604f984afc01c94040ab2fdb319ff552fd8f1767aa52fd97b4fa18fe380f11b99055c41298f394faee39872c9cf140ecc8b208c086f3e4bc45689bf25bb4caebaa44ebc3878d59a22bff45548f2f9494294551c250f22156b076b65197b6f12011319db3387ebf8d0a42025e4de6df24aeb16c94b668c6e4c638e0df82ff171e5a6881358f79d95b7bf589e4c7e1936cccf0419e5bbf9e91736faf915ae68fe6b3a37483f493bf9beac17475009755002ceb8620de5c6ef9c2010383f5266371c218b208dcb28f55f49fe3895c1f009106c80ed39feb04886d23a76c8280e29b41d53f22562329f5128f7891ef7e634a860d6db15d8258d0ec68439077b84c652c62c132", + "eae6f3afa871792ca956ca83b21c2ac1366bd76cecdff9333701bdf49e8e92147b9d0e9e199fb2f0ff160fbc78ef3c3f46de64c8b0b475f98a0d01c5b851a1a6d998274fce9ddd8fdbbb50ed9aa1283d0855cc85e6097ae32270c801c47c67a0923023070768a081b06129057c29d2c3238697a750bef11d132b59a484a0d27d3c03a94e9ef1b1106fe1c39e6f9c9f6fc2cc\n\nInput: 2a9ea0a0d6a008b539a51fc68e19071ce0658d13c12f5c5a2c05a7097d52b4466c21d3428c2bbc63561bb4c156e2474b25c03441fac38339916c0fd8dbdd8fe7092e19e1582b958a55bfba6b0fce9130302cad3431d0e4fa948ad65cf968168c9ed8a9a9e3aad2f6b4bfdb14403cbcdea75a61386e624eb4c87c2cd581c9026d9ff26c152596ffd84b3581c3bd6a9e797f8e292276cc97f43c1d62c27008984709ed1aa22459d0d58c52266a2b1b37a152970ac910e886a41fa9455a6665bcd524b48935ddf844d0ba72a86f3f4cea4e01ec613d02ca8b4c050e8dafa516e0881808d13fa187efd5558a5e7a7aa3247145363bdbbbb5116aff0f437105c898b570610230a308fbfb96146148e0ced4ba0a62990fa2d605e19d4c9afce44bc2a55cb94683010984b19473b42b40f712977912402e7ba6abf4d951768a2b73107307f6654f9d530cbb85976d7dd3808bc8887b0268b12a59b59b21dd12e0a274dd673cfdaacbab2aef8692f846d7b8a4ec080dc1eda7a2c1581d92d7cf0b9d076097808aad44010d9241cf2af3f8d8bb68507e611dfc2471eb7fb4ad339cbcc79d813d4155e3486a18d83344926dafda9e1aec526e9a3e09b9d1eb8d7e46109a9d6d49a25fac7f085feaed1f6cb1\nSHA3-256: f9539896bbcc99c791ad0f7f079f6266cdb1b65e07d73f88b52f6c62b5890dd5\nSHA3-512: dc5a65e2a9d7204fbf39680da247a5a944d2e1406dd768da20a9eebb31fe6dd80f958a6d39c02deea5481bed65055ac28734923c33d230159d82bb34c54be6e7\nSHAKE-128: bb9a450532b66310b6312e096bf8ec3e91023a8ff39c70d2d89ec2a8cfa6553209f782526e4b0ccfa3f3805e64b70cab396406f560d92c8e86dd5445ae6af09598cd80bd19e471b232d3daaa58007ecf2f603375f556495ed88f9815dc1bb27aa5348c7d76e58d9769a8218b555048322d630b84ce6cea75cf0fd9ada0328f727bd9cecf537720654c5fb437e504ea5469e388cfa5ad424a97bd3435dd56d6de591d234d5687c024e0a6688879b2b355007a6cf05eeae3778d934771d14dbfe55ac5bf370f4e0e6864244ea25dc7d4ce5a7f498287930d2586e1374969201cc1cf00f7c19cae65d2cb94e5f551ed20d0690f3ab06630703c8af2bb76362d0b598a81ee86ab7d7fa9657147b7923cb4ab626579807eb532a75c261badcb37c2947098f9b3fd236ff194dbf25d40566e936054ecbbe97071f2c60e2a5d73d5809de539d502624c88577ac717b2b32b3b55c484839fdf365ee6a49b9166d14c49da1532b5af317db3eb889ca31e92cfbe3ee4f0008d7408fa05f4b8c646ed055a90f7e21f441dc1826fe3ad13fc54df118f0ae3007d729f6c4297214463101dfc50e0a37077e4acfbdfdc56f68761fb6d69dcbc87da1f6f68d6d89b8ab8d614ee651f626dbbfc0d643d2f72c8de72ced39a958d776e09cec356b5eba79fc4e1aca23f508aae0d8f7c7af7295df9150eafe8450fbc46f1b71183e95255d3e1a651d5\nSHAKE-256: 8e1af05970eecee9362a559c92e26657949e0e4fe2e982c915d2cdac45f2995502160dcc1a885aacda75d587956460cf2d906c149d644e70bfdd441ae8cdd75041be16e749efc8921d606245b89ae68d4a27ee363c301c6fc375406def225645d0ca19d4df05c08bd59f7a871f458daa573ef32568345b47aa68504a05479b924d0da241839ebb77da7bf62ea9d2e3ea518c0273ec533b3d6660254e7099b9f93b44dafb70aec536e2c0fbebc545e01f1f1cb6fba6801153f445693c0b768046f60851da80a15a4a7964ec6a21c3c0a3250cfdfa050bfc5457e43b37306ae417f0342671abd315c00be43d083e1bd5bab3b1a5f65983942c558e71e9a6443aee953d7d5a6779dca7d3ab20cf7e0d38beb1ad43fec3c4ddf995c32f80e453d96433849c3d76941f83c4ecf6b2315df9b98a8c219502b3e456a544d56fb5803ecf0685856a5f35e3d151613ad42f7430d50bd8457c7f02eaed813dda2ae4c16ca5b9ed89cb9ae231ccc5c93e9cb3b995b9624aa39a594d1d647a5d8193c7da86a5f73330fd15dfce3265b5ed7072fdb19005fca2d6e0b7951c5e884b73e88e0cccd98e3187830d2ddeb9a8fc242e7a8f479219c41f1e1e0ab9468fe1f3359fba9d18b4a16de3b51f63d43f5ace991791822e6a07d467f0833fc9a8af530eff5db603e907fdf23bd7f120a53d244bd1538fefd208b37476f5a931875571135a74c9\n\nInput: 145d013efdf7e5cb918483548e447d67b558c4145908135ba3d06fad6cff12f6ba3ca91757fbf56f6824e0c4fdeb6bf652e6d65090f2a3bfb81636c99c884978886bf64e40aaee1d7f4e7e0aa5688d588dc78cee316f00f85144c68d67855c72b074cfcee11bdafcd92fc1e00b9928724be807e66dd156c251db3e2b5f1be71b415de1af8e26fce6df7ed467284d56726d75a26f0463d25e6b8db8723050ff7819efb43b90ea258db523de9b1bb907a7164495f6d75fdcbd8cce9349f060ca9f709883a98a98cb55e4320e97c9da1a4a777ba354369812a48e556501d1ad77b90fc694dca644b0a4e7a52f31477e71b85eac27fc4cead7a1fc959b6621cb7822e466c935c99d4f0d2cafd1886109706d5639a206ae8a7ae6d3d476b05d1102593172a36cbfc450e53b1952fac35cbab5d3f0d9d6a862a0199ab699e69556034f74f7ec62bc71d3b329ce7d3c151619633faf385470e1a023cfe49ea3ad3d0564af5bcc3a279c2b73c5909bb1cb0b976570f02edbe4ad4fd04395dd9c501e4b4062519e61a6d2e97b0b59b8f81c049936db4de3ed197959b4f3f913d7dc5e945f57f1a01b3ec76fcb504d55df5fd22521d01378560ffe141108a01fb2d182bc1f812eb6608b226294f8c647bc8aa0\nSHA3-256: 074d8a98959349ba18b39dd4bf552d1b7588296359c08963599990e7a058a29c\nSHA3-512: 9bc5462fcefe134155d97174fff1313a8103dba8dbde0bd54895c7e74642c257ac33b78fd12c713155f62a4b8aab0177c86440badb526c1f2b493a687bd68482\nSHAKE-128: 93304f4f9535213ad7b6e640511f54badb95a3e2349797ce067037455836ccf407091f602a0a8452a1280e5a6571745b58772ef876830c37fc86497d684d04017f8794e0d4fb553b39a563631a2d5299d34c82e0879f3597b353602fae106a2d96d034bf85655036bf2a875a4739f5933744030804b8d52a2f68c7a87bd4e1fda95e4231859a7c63613304eca34f9b7fa9b3f04768f28a3e1a8dc6194e7b30f5690a9665220975daa5d2ac827b110cc275618a5a6130a0ef7dda08b2263eb761f4c918facb00b16ae03d839e89e5d7f0399469cfc68ed2f08f30dd4978b34251c6c4c26c4985b41c6be1b995429b08e640f76cf98d627ce6125597f1259055df01716c7b0b7ee61132a1d82fe2e0facdb7799b5f87aa304c52c50c7f32fdd3f9e66c83b71bf5696c179c14482a6d2f50c103d68d714f77b87536f0918adee40b752ba42852b9b51acbfdebe1ce5d9e73afd3ee3d85d5aee27c543bff1153406d2726f79c119b9d445e89393c4932e4f2950fb691c1f709e357e80a87cd25ec3fc9fff5c377cd953021ebcbef71fc92f4713583f72a13aa6ea2f7fba1f76c238affbfc6fe4996ed586febb4b2261b53358477b9337746f7494d2ae2a6f04ee7b630e7aea179acb21874c0be1c21f45ec0fa15442b944a8d82e83121aec55eae10250cae4465132b1f9166faf00a391be338f06060ddb2c649e989db169b21b037\nSHAKE-256: 5ae546f8d4f48b2897f50c322fc83f0036583a5240aff3a8ec33bdd6c4018fd8399cfcf214540a05d1f97bc04e0b9a586073532f88ade6cb6fa01564f6aae87358f0c2c8ce8b8cde37a9b4bc66e78666a6da84768a86e2c291cfee3e115836c6f74c2cfdb722f9eef81c30260c4d5a2802c2dc108755ca6783e9f647e2a6819c22790111a186e1f87be5a54afa353ccc28e4b57b2f597d2e055d2974898128bc6c8d1f055f368fb88959d5a43bd27b2c85cff5bf888e4f448da37157ad79f9932877f57e7467a86675ee9dfb353bb0075a8b587a696294c44bbfc4deecf73c225b757a212bc034fde13da2eca725f6d8a5512f32b485f94ec94c656fdfc78d73133f04c9334fd7a29c31ac1e9744fb1f93b04b1130f692b09e00b16ec6a92aac5e1182244f1e2c7bdd86b8e5d6128f30075978ea3cc156aebab64ccd2ab03f48dc7f7976e77b251e664d16d278919677ccd5d0dd01203dba88242384983129b8e4e167100502be0785240184efa81388b05cf2cbca05582e877409317dc55d73cf25c4daf821517a3120ed10150bfd2a02026e468b241538b8453cd87829a6dd9685ed53172fdeb51cc7b18d79a324b5d31f88fb10fe6bc01b3230a1f12e75823f64d71a5507ed6d8b8c5e056addc26e404c6d23ef5b48284c2a80fba15c47a1a64a9796d057a94d44a10391a4dca530b2d25bb37ec8f2087ddc51090f67087c\n\nInput: ec21f38a415500dcb8c79bd6d403fbaeb911cdc5b871b63d40593da6b45018c52e417b8c3a157a54ce5f9a3de4adb147f2fb3465a73f5037ec6d4b6011f9a0ce702e262afc95a0b26e11cb685b9229bd10ab01352a2488f01d93dbadf715fe9990a8c694e5f8517cc3762fae63918d8491f2409ee0a9a7d8c4d3f77e60d36191da8a27fd6b53d7481285a5eacd98ef3a57d6a1a853d6addbdd531a5e012c10de75d146303c313488d2e5843329e188c8a786ad4191e36eebdfcd76cde4379d4dd92b7cbb54675bbeec1419d23d958bc7d4a1238262997a0dc987f2908a4a17bf18de5945418d819e70d9fee7a62f97c8a9cb8f0161730858ea8b4ce1739ee1f1695413efb9dff0ea9ac870a049df605405f256ca9a9811dd8aafb9f4e4579843704cf0811a33012531c200db5ca4745c7e0f295fda9ccf15b24dfd14b373d68793e6b74c98607c2cb9c207a94bdef140d8427a56dc6cbea1e9d8a6f47f8630c7cbaa56de2416e29ea199473542cf1ed6615d8f8973edcfb3632dcc7e4e548b5ac890d32f50bf791537c4c08a162b966e5c9e712c80696b33105df9d4fcbd0e05528a46c0e0d6fa2f8f46b98a382808475789d1bb9717e692eb19df285d63b36c2a57dcd7f3d49bd3d26fb8d1263925\nSHA3-256: 1c31808c320a186ed73424518009491b2c6ad4d9fe239636c2ad583850d4a12d\nSHA3-512: 21b95d358d179167c8cda19a8a43643617b747a674213750dd21240a5ed8c430cf68b0baf4b8658baa719e29639a5034e2c26394f6da33dad78c72967c5e9343\nSHAKE-128: aa827e953de6714b5aa46f67fd593c9427f4dba19847272f0e5c4856b50ee4171b7b0196d72e41add6b4e6e5abfa30ac13e36f3178b59e78e4b668d636ab08b9ad5963422cbd3c70fdc272f178d5f8fd493c64f002342b2339fec057ebd5a257af82ee1390db3f899f5d063a6368c21ba47dc614ef47f77c0e38d59cd6f6e76d08a62f906161cc5a0ac0db4185de75df00f0ca5ae497ff9", + "a43fb634dd2bc86862e36f27571d02545587bde93ac1a2525ec233b8d7f0af12c12503425046d52c804b49d9a497bcbc45934d60241a57cf449e9dac692aa04f2f8f72f3737bb3b0eec51e2a57cf2ca770ac500b2a61e6fe09c6ae837bb67aa2ec91ec8c75f84c7eaceebe7fc68a27de0390c07f27234b7f02734218d852e835a9cd54f66dfc83677f5ab346e12d02adc1c4dcda3d619194e6644d37ac7f403579da795ef0bd85564b049dfd0df014ceadc7848b9b98ba4a5c988fa19de73c2b220c00be277414e732a577316ddce6c682c869c4feb2bc69792db8c48fb1b6f890816ae29a7c11862e55839fde5c19efec661d925ce59df2b1278e4b63f3ffd6035fb943a32b2657a528c28495af0b4e57f90156d8f3b3d011e88cc5936b781ed80510536ffe42233ccdb7642cd1f35ab066dc8dad716f1ed0594ee89625805ed00e985833981018877404812498f3a819c05903abc77e5465f781d9eb18dd1489b65c4ee9e5503a6\nSHAKE-256: 7326368cf444ded99231985d5ff9834504232f244c96028f8738eb9fec0c1ad180f3bcdd53d7f38cf8783c77f8bb25f9dc295296e90d5dcef8919b587bfe9ab58ff86e68abc6e107b74f7a678a0997b99c8cb5c692f2dc3643ef9676287825db1174e26faf690ceaecf8ab209a615e7ca425ebfa1356d999efb6abf622b9a5e4fa5f7faf98d56247e1b52a4972c5e10acc5a9ebd23643b708a945928362622afce08166658741569d441655401f48a37c40308fe834e69a2934d3ef235c61089b65fd409005ae7bd7af60491baf9630e9537ccc1ed91cc2a245df1094e7dec09f06b298ac9c65cb0b25c8292d6286e5f77e47ed544be9d35520793544794733030b4ec515e144cbc1790e4adade58ec37bcda16e82860c92498962635af6d4adc42dcc83a62067eef4addd0e303238953134de74d9fb76b3189f2238fd1780aa9edb1bf8c4db7c80348e001a4314268911b6bb004766d55ccb1d73c1903b7f73017ad9f89613ccef9658bb5355ebe5cfb89d37514459c15b04c3e0dafe6614534742e319ce7e95ad7483dff0f28caed6da3c0642c9c8fd7ff403243110fb15c04ed2d2d48a2825430914b7e4d7a5464a2c880cbdaff03eb308d21804f8d6f1e0a00fffa8e82ed31afdcc7475768dc188b8d608dd9ccfe7652726acf9d6726494eee23b188abfd2c785c25b089c84fbeaf27f76e7b204f61ed734eeaced43d19b\n\nInput: db2e181b97e326fa029d9638262363cef9fcc402a095d9688c6ee0e108edfeb956f3d053a18c790092c88abfff57210e14ea0c57f50263cbe009695aedebc98b90144ad5bcb3f0e5556395d7ac1bb8dae064219e0d382f1474feff369e1c4b602d78522a5c4aacec4bca5257189dcd7d9bda457eb2bac45a6002fad410547a01ed6e39104faeb6fbe61e1f6547904891ff8db37e157a44c03d61efd3713bc43c1417f2d1b5a92f6facd6f00afed08a0292fccd7f72b7a6110bda4469fa04bf66879f428b91a6fc7b4f3cb2124b6468078843695593d30141dcdfb30177f0148d42fa0c59fecea55b7dc7f09f2176412219f9c99861cdf13a92a87613291c8c76db09569d5f6268037f2bd77ab901e4c980c717d4e347941c46ebedcfed897c10c48aee0fd5a9559e16f231a717f97450c857ca5d00a551061b4074bc5d8552a78e8569ec6283f1508ea7488b8d42c6548612c227dc033f5622e5f6bd1708b12b06af753d464a6a5d5cd5a1180263814d67a2c75aacee98cd42c95be7abbb172692dcc006ff4bc57e0d3f281c2c3a2c496b0842c90070fc881a7e990992359b51f6878a18be628e5334959ee6aa625403ec0ad7c12d0ad0df8f5fcc3839e92b3aabfb3e750012fc4c8ec7c40fe6a399af\nSHA3-256: 27bc8d95be9bb63598d858e827a248733109efcce307bbf7f6028b596bcca6e6\nSHA3-512: 2f7be32705e48d0b6f947101d66d15b85d43241d56b43a8aa6eaea306a72bf343ed1af5816df70c5a16da7db5a11f6950be1a0912944277d79724dbdc2fed972\nSHAKE-128: 8d55c09fcc76ebf9a3d76b6b4d093778267d3712c7b538cd7f1f5ebeda8a8169a8b69abddac802f3b2ef8e616e6863f1112032aaaf49ec0199426f325a0c02aadd51522f4464c2d4824e85446111788e4096dfd3522ebb944e10e57fd4d5085ab3fdf2345d26cbc36654e35f502a2a39e86521ebce7f1c0c1eec453137191f5da67e821c69401890f0c33137aaf25a8d1a7e9f668ed8a86351324a0b80c6b605f3b743e963f5e6c9915c53d6e32207d9c65da2ec89afee1f83030d5d37a2356a75e2a9c55ac45c80bb6f13c27f5d5374db2c53f4d28c6f0ba3e87d4401661ef2b8fde5b4e5efe089b73816bff94ecb15b7badcddc3eb44dcb8540d318e53d6faa89ed62dda63f03256fca62871ce4ed41bf3696ec7b371dede5a12d9cb34a6a9b06bc9149d805f0f1b304ceaf0d3457d428344fec3243652f44791b152adcf6baf24014cd56ba6b1d75aa67bef8dad484b2e173530a97f47f39704c1564090d6795f0b5732c17c22ef5f634931c40fd2b91d07581e29351811c6bae1e443ddad6c9c2f2941b18425111c2265ae70fa2f5decbb279f38c6878aa153693ba35f4a60e0aecbd6050feae62600cc720b07b6de0be4729ef34d9bd67b8df96d50c0de07190db430edf954c9f06fb9b04ad9f980df3b8f9a6a1931f40a177f362bb09049766c01bdd233c09e09b48b1da2252310fcc65192842d4f943c1f5fdb32082a\nSHAKE-256: 9e6ac3fcc9383e77aebd6e41770e2f782cefcc8d1e6ca052b38e1a956d386c6a556dc12f9103376175a3094dee1430551cd8a04cc4e755c5f1d94b8c75ef725b41524ca9ca7ef2307765e0d5dc11af310dcdeb621fc987a88f946559ba2e2e755120762b98b22a37c51b67cabe721aa8ab2bc113e2fd48485475d32b97513776cf6e3cd3c99ee2fb8a6341aeb03854270f97f781c3ec1b57e7e71db682117b019037bd44e0057de0ffbef4e1fba03e36772261e59602d5aab49df483580e63e1e0b341eb8d72643d50d04f133e3abaa9a398b1c3666e8123f88ecd67fcbf1d284e9f871eb8ce48eb842f5cb345a9cc1b4f97f6fdb04c71c73790c58c92b293c801c037724d1267fda60dd0d6d05018b48be62551c4f213e65532ca41ab0007a6e9e4989980660c836505f06e86d3420fa27fc069902fa4f4d455613018c6eaa70b4cf8203495e8505eccf78b58c419969c53fd2569ed865a8115ffdc649923e0b7ea33e2c830bcfecaf849c7867135519b094be7a2cf5912e9058ce012a69ed0f4c810ad97b5bc32fdb2fa4628441c4856e9e881563a6bce8e45cb709418c0bc9a6e80be2126631ce03d87ad911ddad8cafec733c1948384b4f849ea89a42c593d79d55be99ab8f9e1c37a0ef5c09df3183a8f133151b8ac14f5d8adf9568daf7e77bb998b6a5f23c814b28cad376629a211c77f118c44d309925f72d372da7a\n\nInput: 93744fd07d7d39b791d691fc1c8671156a1b0335163cc7dacdd241dbdcd18cc1e05860be9032a027fc04840a7c43e3f16011e49e25fd14bb578f49e858d402bae3195f09a2e4ec41e62e4184bd8f949e918b7d4c92ed2e9df16272dbd218b90e4a4a2e979de1f4fb9f79c1a5d890fac89f7b58441d2ca1c6f4543dd155686eb2c3328866fbda83880fb7f0803c7103668310189611aba43e04bc01b8b20802e8bb168df71bbb91f75d7b5ff4f6d6f597cd457e3237bd1ea50b436042b6928ba16e4ebebe199917931c58ee3244d4eeae164b2c3f77c23924c58c667d27f3583fe5d5a9b752ada13b488c7b239070e4f96a68ddb2a93dbb6e1e2925df3db39f43f8578662af31d7e9f1e610a06276beb08cda42d6b1e946242a57580f5798e28f0a51e606c21a9207df275f367b63fc3d32e28edb8e519cac87590a9563ed4e3b7c945054bb587f063db61376099d6f887b5b48c877614b0d37f46c9bb50352554e5402dc017163c326cb2ad965f2521f41946905118d29c97c9c0f2c2d58b7587c4de77e217ac0dc40b9784796a33ae45c701437f68f60b7a5b0d804a41d6285ce6d5f6aa8346649a420cc2ec9fa6545f6424ac8b7a2a67e8b462985700a5f397e77c8e6fa181c3250bfab8a99e23fdeda\nSHA3-256: 21b5d21ff563ed8a29a0c0141ac43f5cc26243faff158f2f33be84e0bf49bb54\nSHA3-512: 2f85d2fe4fa4314948dbac0e03c9d399df6ef93b7c9903b774665cc7f255d985b4f3c6f8f75d49884d4dde58af039fed474b11954d0b976d4ebd71a137a07636\nSHAKE-128: 0b95726ad716961daa6de1a85b9b0c5872b7716e5589df1869a24b5f04d828134bcc2c11fe62a45d1902d02fe19a32c17704feb1f893e52625373e05bf06329758ba91f1f9ebbdba6346ba60d94ae7b687b3bb51c6d05daa0c61b97192c77fba834a2d133a6695d44436747ae4e114bf601030c5f21ac4e2ac6ba7cafa393a7edae93c49719af6a10919bfecbf4028c325285fb0fc02509944506d474a814bb7ff191ccc639311e3aeb65a6e5e2a1f63a0519f5f46cbac947c67dc0dc9305ec942917aa90e6a4aefccda50bd011b43a1f408c17980c45e424712de7ce676f4afbd127de4f35b71a976fdfd37e2126cbb09a6a47194342449b65a4bdc70f54b76bf15c362eb70eac8e7e7f5f264ed4b658a2a02383a1bd618e313e28c690c807f8618c2b49ac5f8bdf2746ce8ed73dec21d6df347d28190b418c6300d010d3995feba5e8065de1947d0c3c617271134749e4134c9d59442c165f5a891fb34cbe4d7c395b634dc07af4543631c0d057b5fa0aeea4a7aceb9eeef5d06cdfa18109ddd15062ecd453e5a369bfee6296ef6214dff0c5065b34ae3271765802938fec36333b9b59c98de92ce476055ba42ee84761730682c22db5a92a90a8bb11f3bbd14bbeeb0921e3a29ebd31af8639385874a57b4048d5394695c6d44be47e6f18e156d59ee45735458b6dab61ce4ca68b286253e9140772eae53842c90f1c724d5\nSHAKE-256: d70bbe8013888eecd27eb7b3123ad98c01308fd51603ed876a4561c51b7d7c43f280d8f893b1902bc1601df797b3c45f2f4400b6dd99d9501b797a42234adfe6a31337f92092550651919c47ad0e060eaad6551cc8726ff89be253a96df4e9d6a63fb166658eab7b15ece3dce3559c970560aa767c69c2de00bc1d4bd08c23125db6406ccac19254e6129c4b81e90edd0a1985717414722a20114c327ff3509bd774b755a31ccbdcfd044242cc6d1e16465dc02c1dbac47b078e3d3d72cf9edaf5d84f62442c7d41c2c81ea5cc271bc73127823c4ac7c513ea0cbccf68a0e85d581846767782cbf7239a3e556f85ebe46d9408d1f8d659881489cfbe2924c4b01f825bc19a7ef3caaae4fd83d25e719cc524bd4a132f54e815e7b45760379d0f8feb83277b07ff65d4b0a698e3376b623b99b66e96a23707a344add4a7dc304529fa207485b1ce338f0245ff413bf1fb1b51853980fc067517b262510f1b063b9b8d8bf353f207b42fc056cd9bd48e78a94659e99b3bb24463cafc05abe46765bc1d8d1d931c828bdd4760ded7cd1963a7b952a0fdafdf99c5fb9c9ecd4d6b60263157adfab30344754b7db359eb7dfa3457ab4643fb4d2b90fdd1678693775c5f56bc533b5c7ce2229c58a1531b410f4cf0dc44cb2d8710ca3b85ec47daebf70e59fea0cdb213dfc4a0b8fcb53aab05d1ba36ba63c3e1a00ea", + "611f02bcce5ce\n\nInput: 0a4eeef7f587d37bd13805a5834468009794d9998fbe6b50121007cf87754557e5c69793658e18aae9ca2563ba5c7fe7e444f7746fa8dfaad5adc88970853040f482117a0e466a976944c4fdd83a0095ebf717d1b7939781b18a56aa9fdb2bf55d108fdfe0e67d5200751a59b1c3ead6e7a77c9de569679f084e06b97e358c50f0274a969287c11c90f25d3fc04ee0bf70fa6eb5760222ae18fc2357ca33f9638441790fb0dce725eee36bce6e00b09368d3a4de48c12c365b575fa9f711ba69f1f5fb647705edc3c42fb8e4ed48496e5434b850929d073f62f52886f88c6d1dac2c703c8c017e2f32ef18085b962774159b7637b1c578b53b3f93a53c00b09a61556d92f434b691e86c9078c940db83d54d2dd459959934cce2c7bd3d45339941d93ee4f0b8228822b0a37879979430dddbc05baea980ef8c64c2d928f6828e6177a638d425f35aef61c50168c36d06f649cc56d6064e39bc6100aadda3c5c64204867aaa728830a9eb45c0c84fa341794d7e89ffaafe2451d841c73153aa138b95b088a729ab47fe1727a6cc26a3aaf71f9d6254b43928d51cf7603ecd101a00ddd9877d9c7de9d8323e38ed2313f57826c1ffb7f8625bd625ab785707a4f632903ba8c90e6dae616d55930d0ef00fdc85\nSHA3-256: 5df5e7ee932de137117767158d9989ba42bb91a6b8fc4b6a5d9215600b8f9b11\nSHA3-512: c6ae1871a09e8d0314cd40ed331dc4f5e77984c2824ba1893c310c8d26f7e7fdb34cd0730f3006be5791a149fd89a0a11bae13cb37b26800b46359e7bb83b87c\nSHAKE-128: 1e489988215545383c0fb2db73c9bdce6abd7365459958abe206279c1846d272636c50133c1440a8b18a78a5214b4d05c85166bb475a19744bfaebb358c7108d38ab17651bf41e0c8a6fedacfaad00b65a19e1836763bd89b5a32c9b2a21b7c0264d4bf688e902de31c75d6ab8b1beebada0d8ed843f7d67239bae1070e2a7460de448dff5761455427d356a368be999d1be0b3675b767d27daa1abb2826e20816339d45b8ef1896e0b81a39afe294869db3d541f12dcda2f094a710a55c03bbc94b363e9f30fc2a60472026d0662c7f96916dab736f9f80f458c6af3a2374fa661cf375893e90fbee301604b62d15ca68b75c29f84f17458f615ece52b03690cbfecb71e2c91d84ac8607f3ea9e644edf6976cca86cabeb833b33957a84c23b64410bebb266fe88f55742931834b2e418518ba9974b5531f5ff17362ae45c3895511b0b0597515787b9018ddfa1b91d0e4cc19660808638332ad8e1581b0d6ab5fd9d7d749114063a6d41527f322f06b4c5069b80a5c70f218e5cf8f8e31959d0c4c8de9b471e8079bc7bde6e2fa12fe21a374137acf8667bcb8e8f5ed5edab83b6342bc12b3b33cc74b0b56d3584f28cb6cb085b240044f220c782932c33a1dc5cd45e9bf8b365c97695742c5bd46f4dadc313cfddcb7898175e811001c74d7d6e7105a3ca283ab31854a1a0652eaff69db7cb5e6b9b32baebf42bbe2e4dd8\nSHAKE-256: edc1f99bcd012a1984cbebfca245e208706ea771f80f273b349575244cf60101f0eed45d7f1f42f9ead69c9f0017b263d93ec7057d731ae6992bc659d629f3681d079e085d33e9952fb662292b28a6731a518f5bb223a4b8ddf391d2ce6fef87f6dfcd97a956b93d740d2398617f24b29aff3ec3ff49fa65967008e0d9be30ed01eacf5923ceb2f9cfe9a48087bc7608a931abdb5d557daf3eaca13b7f2e5eb3ffb7a26c3769cb318546430e48df773d502cb7faa031bfffe9b8685a014f8917c695893ea292176049bb5f26314cdbcfe9933958d5a40cab34f10ac4c2c051a19338530ca5c2ce7eaa493ac9e0a58a10cba24db76b2662a6afb2676913ad2d349c2c03bff3be4a3f39435248a1f2c24c0ad47c61f9550e4830cb06b21ac8c2e65d8958ab8e6d484be9cbe6354559ec912c327bdd866d9e183a08c8f79d87d7ce1be2b5d14db90eec1fb457e3f9b814c29fc47f38b2b42323f4654ecfff8b04e7003faa261203a5d6148da0fa1291096c7c942de68b42b0d343bb8d423d3624787d88e581768b8354a219d6f31f4949190b1c9b48b71d3e0c9ec75579a0db23789661b594eac56c4e342d1d96b2bb8c24faf5ab3ec932d768e6ea7b9a6cbae0e4d859b847b51ff90c5989cc42a99f8750d4c400a6a3fe861ce6976b6abd25e7271fd8b54f80cea1a6ee66503788f640be2f09aade1bd3a6132c15f5d5ef337800\n\nInput: f58897f11205f51551cda59ef98b60239f7ad45c5c2ab42779795288226ad6a1363927279642424ba817e397b504ac4f5ced35fc936cee2c348b4c4c3c470a23fc21c0078e3914ffb34e8d726b482ef88da1ac1c0ff3bdcd99377589d55dad3362e194b7bde63d26d1217fa442b56c2931438197eca0071381c891bae734a95b3678e6dc5efa596dfa2a9ec6d2cebb495f51117bcc47458bd555e2c91c4bff2de629693fba30d20501959df6cda4e55e472bc46480237bb86d336651f8346a8c6e01a1f4c3b6f0da59f24181b94791ce6718d57aa3c0c8330abd0ebd85a0a2bc5bd1d3564ef265d0a3d4025ec2ebbbbf8a13fb5e177bdec54a69eb582fdc683a5e9a20b43ad5a13070e035d6cfe5820c0295320798f215a66c5b05f366d26d2f1f5f64668f476efb95bb9bf4c69d4c2bca09851f2bcbd3ee37f9618eacec75050be52fb1dd3bf5d8d1c0ca329b2dcc54c9d8e5cac8b81f75508c209eb121e760187a09f53191fe557ad598fd9245acd2751aea3bba2df26ef0cdcf9d3e53f028b86c8926e8f94b17b63160be71a6b963e4d6036893f16308abcc2644479b3dd7767a4721dea8e8fa76985061e88dd74a9fb6a9dd8071c391229fcba2cdcbd07b78554321382a8818a3267f40d73b791699ded5\nSHA3-256: ae8de1405cf8b05bdf368aca6c71092b9191b9d05cecd1e6cf165fb59245e712\nSHA3-512: 492312fe6b0becb235e8b9ef8a0e52c78fc8fc71c21a146343e76139215c48bf00a2136d72a6d14fddc718c238896d4a8e631b3ddb5b0fa3933b3d936672e9e6\nSHAKE-128: 089164a8cabd81dc48c86874caf9d6753dac5819db322dacf6c83145f78deadecd68de8c43dc748b97b3b83b34d11ed4b033f3a4d01f93d2087d0aa14dcb9d9a3191afcafcb12f80d8bb5c7ac4275d66bc50f58e67941dc9f5dc0245826f9a5b970d38a57a1cac206e0561203b29406901e9d435a81ffd453f817f5a75f5d65d0cba23e743369e9cbc72fca1c79b6415e6ed168fbb5f478cefcbc7c25f02ed600f71754da022c1aa2ac687c9f6d154a52f7642f370f85759d5d36fe2c0974ed086c2cfe2ad2be11e651fcdc74217250def92c7459e9b0c6a3c7221fc5997cc9db2703f5f1218a83dc16bdab40e6335ccf52478ad5df54540fee1045da44bda33e9a58452793abfe0c1c3dfce2ac08cee37878064ab02551284053c7b06883d6d5d332c2eabc7fdc59d9b5d7ff88b1b8cefb006ea49a9d0d95083225d590ee74f1b1b3f3ccae0433e5a364e7368de029a1404ec7f3370aaaadb1f455f2896720198a78118ce27ef3c04d2584535fddc1030f7604737fa9ff153c2bb9677309fa6b33cc74ef2fb423dd0f00d99fd6aa12f4d4d52de922cdc6ae727ed748f15f829b3630ae4210daf92ee57379d3cb9c7924f1d0788329fa9e4a8669fef546dd78bf35d8ee8080b1ad7a29b2d3370c8e680aa28e4e637df8205c89988810350bdc4351c9e264ac79950691e0ccdcf7c31dbdc855801c6104bb873a6d9b746ce420b\nSHAKE-256: d9fc5139b5d52885d56239d990b4c97de3f29a5f9000104de75ed01fc5aad78a89447b37736aa9b87c49cd1433d567037f1fce3518098ef5064c6ea579e7cdb86c0b3eee38a5f7f99177f1c591f77f9524d141b896eb4368b703d0da74e3cbeef04c85ca4a15cb8510855f9834a4121a3f7c273caba338b87e8333fbbd9548c089da39d4d47e976aac16879c236b4d5ff2b1ee63fa51f44fc8cb52d622cfd60aeb06b573b1462780d4ade1b10f06f2a8ae56ef78cd6f84259b759115525731ff45592c5d9268ec7c9c640639d72d408f2941446fdfd61d527c56dbd64891610e1909e850a02bc6cb5c9feeefeba88cafceb244b180ec9be49a2d9f274df03cc9c5821a1fa906fe8730602318526210f5ab397a9a1a99ea597be291e65b0d377c5582ce1e8a530896ccd8e9bdd0c4bf171f7d131217d2f033f788042c17367d124b4e5b53cde3c1a8116821a74063bf6a2b70cbfaab3a7da1598ba3fd8094294134cea16b1a0d6aa5d07b2cf3f6659695a4887ea630f7af440fcf73c02d310bd9676c1b62aa56d4e1e7763dbd96ca4323be53c8482c1f7b4897e1855044fe5d9990899420565fdfcd6f62f2708828b1877f01c18e54efb005746274f212cbc134c5df741a763f55429f98b071fad1afb4418b8de457b8acaebe66ff5bd836a16b5d7aac967875c48cb576c227a9d0cc810da49108da85cd8b9bcbf6342b0394ce\n\nInput: e1448c56e1745fb3e57a55b833d91b019aaac1fa6a4d6d4ac6591dcd432f8ede40af8bca870baa4d1a80d66559bb631c0fe70e06c63fec8d39bba8036ab66caff5ff5c235d91cbd9aa505786e6ec28f1ed76230e068db928fde799f4dfaa37aac325f8222e4ed69273046fdf3d4b3d8938fe7ee4b9ca43100a932c3e053c477e2852da88d535842805baea37096398abcec20f974d7787b73ed82df49069ec39a5206c97bcf46c8f6e7a49041093d4af8101d3a7c796d148cee3cb6e389a4f7efdb44085fb735d61523715c38228ba83add965dc6fa4c07961bd0b843377c90e172292be69fd5b814274b484f1e5f3462b3cfd3ac3ab9e36fa5e1f274c74185936b3bc341e0a499338abc0e6a48340588cd69558d18897c5896bc5ec5c5978d43c14e6f483b70a16119ef49684500c4d787648003fc4bd23d7f687cb69de85ac28da723c34e27e478a611b707b99b2b217ad5555dfb2ed6700170aa452593fb76c6db747c84da6e3162164b14c569653dce6505b86b64b3e3265df875b259a141f2c98fd61b187ef8e8e99fcfb0c3786340701b2b600744d25da4ddef940487d8105f60296f2fc49cd4c31dcdc81265401e83c568a5b3c945e0a6bbf03700fa2b8ef6cc28df9d2ee428abd229ec19a90c7c3d44d\nSHA3-256: 10cceada33309f79509c42b4bc162a8e3fca667dde693ec4d497f484771331dc\nSHA3-512: dc1843bbdfe0772395bfe9de0929b7c426cf97843d940658af2dd0ca7193931d77bab8aa401ea04c914a0d063d1b231dbd04ba12c9683edb5d337c620674ad99\nSHAKE-128: f91b1e584908a6642b756d23103e7f02c55c1a2ce02a484f82c6e6707fb15b326523bb094f78f511e87e46eba362f790db4ed0193c240c3277cac62ec8833402a9b5517ea6e290c770edb85c7ab534bddb2708455f61bbfd5fe9b4dbeed817b09fc566a8c3061a4442d1f8706d7afc42712deb5331b5c1adac716c3227e3de8118dfa7e44633a2c893a2a5ff11f75fd884ed04d996ac1c8ad228714c6db8b3dd6b2def1ab060937200ee3a5a97704be6bb0a276b93fb025a4f759a736f9fc1270f157bd401570f62e90b05a6d2e7227494bfe8f404e921eb7c1278f9826f703824b542ee9b357a0d1fb7dbd2cd82a092a040f5e7cf968b47309fec8e335601a0cfe611789a161d552a13dcc335b12edd935dfb36", + "856b865f257a9175c84cdda317ca30bc60df8a72254c1372bea1869997505db62d894ff7be0916f3e17972767155c134b65949a254b280d0b1cbae2f0702e3261c570ba57e8b10e16a22fbbab84fbb02865aaeff0c0854c230c2fb90aaa4939b5f58181bec077b7c8ecb05a10a46d6f625dc8e0174cc3a2810bc44686c72ecc60ec655b79064cef00bdbf6714b3635a65ac56dda0efe1bc0e9a2831ff69226119204970e850e92187c88234e62241ca1971402937f8abd9a3cc1b8aa308e35023158412daf5cca2000f02ac4442cc7c0a60070b50cbefafb8d8e94b0bcc2f767875d0dffe97bdb00328c76b9\nSHAKE-256: 7c58f3121ab3a48a587f25af2e132ef50fd869eab9952ce9c06cff6b799e7a174a8666f9362e4873074164557a5979451823b7b0d1ee30fc24c27dcbe491dab96f4af28e08fa55e7049e539eb75b9dc7472bb70cb1dd548f1404350d378457352e9cfac79b53606400dcf58866af8aedd55bf916b8fbb4d239d158bf407ac64ce8e9dd6800a9fcbc3b29f246cc1d537ba0a3c89b26495c451acc46c35f7480ba7774d72f5d1e2a1d1526a049b4aa8eba30cb0e23263b93913aae1a36e63b7c582bd7deb189e55b10c8f8c487a128bad5f212952bb2caadcf33faef2854dacb5a745ebfdd661c2b54eef5d2f9d71cd46e1c443bcb413a51eb66288ebca054d7a820574852b8fa56c22d077f9a220894bb0863b6ba3c120ffb38988330a8b837523c9cb4e1cfe4e03f3d61b4e15c049b175b7e5286f5433b5846719246a0ed9f055ed93eb4ae461d902d860d164162f5abbf6aa1ce33e3a2788072c6b5d66c4061388cc39aeba1a98f7c6bdd8f19a91efe7fcdace4c69578981586ea089c4e7f1e62859f07f582a21fde18618717f3e4d2db651468a54a1fcccc27dcd03c423145942db0fb3c5bfb1166ac90ea5aeb34a7f34c5a8987ddb23ab33e391dd512ac4ba5426ad4e672b65a21c5de3548b3e5aa51921ed765571f41bc72e9a86581744982a4c804c357cd7cb5064fb7d8556dbf92ff9735c3d103a76bca9872af40a4a4\n\nInput: 7e2611292b81669b9ccd37ca0de1a45856160d2db246f8c2bfd717f346566b87046d1e4a41b131403f6e730b3c7a7daa412fb2e55eb912886d871d4dab186654eac9b5e3843ee76ca8e4dee167977cdf27dbde4094e770ad97aab1ed1a9be485dce2eac76c38187778e1de0db67b8fdf7ab83984b00089302f15d84a7c34c7614b47ddccc9ccfa13bb24082d5fa3f90a79fecc647498f242f7ae5811a746d2b1c93994981e089953ec284d669c1a9eca9d879888b2354fe1ca439568e7477071c37ec6bdb31a3fd562455d15beff2ccefb59a911d6189f74b18c593cee487e063bd7ec32a29492aa400fc974a86d0e7109bd2717f4ded25636c8a08de051b572aae7e8842f0b11b8d0aab5c753e9b7994a3c7966ebe070610f8be21008740574344cd01e9e6ef66e22b2e5f68f7eb259eede3b4a277083988505aaabf7116bf90c7efff7836f8aa9afd2e9cb9766d28f6bcbd27354172e6a8f5f7f6bb5b6c5731771a0395ee4cf3dc5a15936c6c07c47e8915f673e6991acfa488eb1624a53d72951be550c4817b42121181e56107d6875ec4c40f1efed48acdf91c65026881e0cb0aec2387a3340f327ebe940b41f637e2f23e2a6c50affda87a42557539d3dc752277d806bee8d3240577d4b797a28c607d027ed\nSHA3-256: 6551ed29edf7f4cbc452631a954245d031b78a21f5dee6155e2fda5545c75f8b\nSHA3-512: 7bb64b19057191f5a1dc109407b78e69ff24e2b45cb054e353d93b76382d2df6e620a238d0df346aad68806ab6375a4116b27b12c7bc23d5b67e7d4353a150e9\nSHAKE-128: e21fd71ca9971a8d84d7563f4192855fc45bde06197ada772374a4fe003778dc5c3cf62ca96211df6694085db8ea36e08da72a88e131cd58862b2bb6bdf62497c6a032a908f19f4a466c212fa0f535b2cc6ff333d7f75ff89af957dd08afe526526f96acf8d56cd1b10ba735948b4239275b04eeec6541ef069d565ef63d4e277f5c1019edd03c410049795866e67a8c213d9e0a0c02ff3530604fa36d55720a1e893545645cfae92a89a34f12e12be738143efae5a013754a7a84bc6f7a2cc1ae9f819b70c087c2f633915760959079365bf7042c6711d7ad11d5b7c171ff780ba60ed52805677f8f95d92aa8b0492a778fedf9361f49a842de249b3b62863efebce1e1a7faa1bb6579132513a3df64b02f25eafbeec1f28396c398b70f03af5178c4733842193421c4ef6ab63296a1d062d743552f281059b0320085a12e4d64c8dbd42a9852975d66a7b8c61f96dcb83eb9f6a38941dac4577058f27bdfc26b6728cac8f7b1fe450f930de5ef9acd8ed641d11b683bdc3e72be6555874be2b921969632cacf9b1ee6e1e4ecaa8bbb492608a00a2047ce2eec40931463c4245e47e7f0eae72fefb8fee337bec96ba7d27f1d3e178826164f1d2c36a5f40c59d18a2d1e184b58547bfa5ff93b271be5760c0c0069def021957f8724350e08687dffe0386570a401118b884dcd3df5634d0f84890cc07fad2ef94f542167752e\nSHAKE-256: bef00eeab6ec2dc691ab95ddf71b4bcdfa2706c7b7d76c3142c28e98c434e6c98b979c81f17c09588393a8088fb6f468022c1b299247fcddb4eb1cc132dee0be837882a388830124fe0b6986ab96c3ce24732a2f9d55d7f1c09671f9d25606d50d5c9782b48f44c6f0ca1852941108d3cd97ab7e9e924450c64067f1b2403afc1cf94d87612b4657372009919a8c4721b33926f281adeb0f4e40a36a636c0031a25290d8ce1df26580cffbadc4b96426be3d98dbb0607e10d818ca1414f512e28dfbd87f01e905a19a89424140d054945ff9e9f5fd43af2eb77addd43bfb3a6ccd5ae032edf73cfef80830275f2bd84a848c5731ef0dfdc08866e813d0f05efd31b158e84d45b7786066367551aa1fa0b32379d4aebd56a3ca4153ea7d8513256d01b0c5f1431e9a4d57190c63973b0e6bbddff2acf105c6d0b7c129636841b81e1df005bb4d805a75e1bff081c07d743ba94ab0cb85feb03d3440a92bd81225c8042fc5f9ed18de0b3bd901066aa53eaee9a052cfb47de80e5ce899ba315a6729df9d22789eb2709ef3e5bf88f3867708c7e14c47080d55f4e35f87738d78fadf5bf848fdcce61677328d7099dba84a86aeda31891eb3b651ec0ff3642edb4f9ff0ebc4216bc94ce2d629ef867bc90405ba4072445e7de0390342c97273cca1c4913f9342ba98ced643e43c3fcc04b9259b2e27d220476b4b404b3915838ef4\n\nInput: d79305431715aeb9f49b1965f42a4f115fc057c5e7de542a473452554a602d7eef7b0cf3e635d0de3a86cbcd93c9bb4e64a51d0b1591b8c1a6e8adf5d7ae16e75a92d26ce664ba3288747c64276597f347051eb811a5f2ad35b52bd424d9841d534da1a37f3719a9fbef9432f872fab3e82def2226d823002d14f7f7a37985561eadcca23fa0196626c2de248d1c124fd9ba9d1ab753eb572f11712f518fc10876324dc44f3a01a5ffbe1912838e6be2ab6a685c1a029d10cb6ac109f1d7c0ef91ab17af72f170b062814446ae36675d678e16bcfb3af79007b2f559b4f44aab2657d8807435722981702b067e1cde8b431cdd09a84be1661937003f2a826554a54ce58c021011272ca5e63ded90ff6090c546e443313640a23faa8297a2154ce38e2cc0fc6e386101d09789f7f8dcddb004052d7c4150176da8c085cab0718959a04d1972f3b9367fc2d4d79437923a05a229eb08d062be956405f7978b6d2d4184d6454e6fe1815e3a46e7d957cdd735b4b4439577c37eea5ce5a716cb54acbc8d840e60b67fff52d4ce130342acc06864e93b29964803be4751931619860b79b02c2bd6e10e4850b07212d356a113526065d1922ef4bafc48fa6b65a4e5af5605a2d146d0e0d0afdc8d0bea6576a64f17fa5fe290\nSHA3-256: 9cfecd7a040ae0794a394e8950e7b84745758ba85118788ccab2aa676e303c09\nSHA3-512: ebd88a0043b7c70b8a5cd9636b1892bace25b292e982e921b0237d4f06f3a1df8598a71594130d1b1bf7acb4e1cbff71b97a9184d443277824cfe4ceb9d1d686\nSHAKE-128: 5b00d7a8e5055e288fc558230afacc23074f2d75b498cc13b40672ed0d2913710c84c99206be27e646d785f34f2355c56ce78a17e90b71e54b9cd7ddb90464249475b95ee67eef6468c7880cd32deed707c77c29e57215e0d1d04ca21e7f03d4e75bfe94a675b4cb32c630f7572d432e2dcd97081a6e9896a551bae648803bbe71048a4d356521383545a741a91483fbf356d752914371cd4768bdc035d795272c7888c00a0a4077ba1bba13e7dbb5e5add5fc31665bec333486227421e117b12b8ef65040b9739a3a24ef382b66fd064564a53be12ff11cee76f624650c0a3e55cf14c8e03725ac158ba13971856780008d016ceb777e37cec8778f08682dcf8a9b48b7d02d97f1119b4b161be7172708ddd16d396b9cb6ecd3d159bd338558779dd996d8f721830c5280af737e9a5c0dcd8c9a32de26a34524f563a68c99b4ff4974ecdb9fbd1cf3d15a4b4e9b7776ce864ddeef464c8b9f9e8096052203053ebed168630d00465c27b9534ad82570fb9db4edc5b95fe4ecb90e91a768a196a3b241b0f27b27bd5ebc0e6e7ff1bc0a2dfe3c7e340da66f967ee428b5f77e8c1a606f036c0a1bfaae24e77f05e63dbb5e5f755d49ba8d14fcf39ad7922f8c5bd5905a5b055efb46ae9b5c583babc56fc8b8ff191f7436fab26d66a8ad9149c795c9052b6cad9b86c224a68c5028a4add4ccc58c3c373f2d06fcc6eedeceddfc\nSHAKE-256: b40cd7e20c8e8f1dca5debdd31cfe76ad476b40e146591c2403e02ad45335cfedf43295f08c0ff95af59ff7c663031692f47c7d9c18947bfc13d42e9d46dad2f748e6ecd5770def84706a44922076e9be2a978ef83f80f92f639ca8dbe5ae6dccd69bd83b8b92606bd0afc370f78babe901fd2815cdb87709bae449a8306eb2a05c4c1f3622ed49908d651e45674496831fca97bbd1df45d9095ed39833b2586c9204c10961fc9e8955ae6b133dd6848ec349d8690ecd180580c3ff8b15a3734183bc906375a03d565c018617cb4c0772479f06751b226bf1e127f485504ac818c0b626e9ce64837b2190a6fb72bd54e5c7becb9b0c2045cfd7bba6fad457a257ce90123c66f1de5c9f5e637adf1ee00f927ad185ef57097116e02ef5231e29fed0d680937883c57cf9f404a9b03bc465fa2451ee849a72b886623ad4634ea661c30eccae577ba9a1cfcfce216d310cbfcb5355b450f7ce9a114af4fd558e44a584cbe65e2fc90cf6560135502ded17a27b3f89b8b58d0d3d603b240a12b170ccf10c35378648f8e7875d51a14047926c020e5dc8f3940836fb29422f5667e27eab27cc26fad67603ff86a9fcb7d8206f12176a805ef0218614d986abce39a3b932fcf37dd13ac0a64bd4409a2a2ac7b6c12e7ee3de5e8077ee8cba33e093a4bf0b6fe9640454ccdb9b00cc2d0fb4d18485e274701e3f98f0f816831f39f46aa\n\nInput: 27307e40885857ca1eb7de738aeec72e358524d4a0a9e16100f0ab8064d8f43d5d4eded3a147c3f5e83457093181dab376d491c8c87b82ba9d7f40549bffac7ed567da7380dbc842061e16a680865074060687aebdf100af5f91b67e60dbed6697e809c13815636", + "56280461d615b99de65711d9178fae6056f64cdc3a467c4f44ae4f354e7b3df767d16ecd7e517497ba6eadd3fa567fc3eb8bb195a94782f9e58209280381dacfbd16e37ab5ad1be7fb53c4417ff002cb8de720c3db80e920dfe6ebbd4e61138b91dbe8cdc2d28affe4933827c4963afa25c78929bcb5c47b8a0cc4a64d0a96105b1c906a106d4e00e3bb68c1b00d509e69f88e09b2710249f9c1a0fbc7580ad6a597aedd004c21e9a33d1447721004f8c73f4c840f2d068019905bf6e256a3eb7f0d12fa7ef1f167c21bfb9cc6fb4ced073276f4272cb36603013e4f58cb7ee6bd41bd33ec73c8750aa76fd8a5ba137ef4e010688ce3f4a90d9c98594ab6902a16db6c680ac2c129efc3e5e73dd7e27722f23a00ddeea7287a37e7eaa5eb9ea9efe7b256b89d51a87a5ad2935845317e475671810bab7a983ff88bdf04b24b07e96baf57dcadf4eec641dd770eaef7c9bfa0cf340160884a12adff657cb8023869169f3e82f483dddc8d7c265a5ce59\nSHA3-256: 0f8a4b9d5ce645edd4b7b15553f6bab89afb5da329dab255394260e61d3bf16a\nSHA3-512: cffb14381196c3809a5db4f458af1f9878ea5c388b8d75cbb95243d70199ddeefdb5a6012736f34626e11bcc975e161535bf7727a951f3787ded8e881481fb99\nSHAKE-128: fc532547f135988c2a888b33290f6c2e5728a5e0bb6c3b147bb0529afe86f2c1cfcdcda00d4553edee763a3138c9ba32aa6ae866eebd5ed77fb028c1038ca0265cc61d97367ab1dd3b0e48a86dd9b952568d8b8919c1a0e3b2b9ac0b5e9ef597439601ea12464bcc23e0425e018cce33924346c6aa52c2ab52c7f7d837776d82c42913e55a24a3fd405ceaa682afd4b82855886e599f1d6634d5f1b2dde8495142144de6e61a81ff64d6ffb6c2c8939d9741c79f92d1fbd1db59c4669b0e478df98aeb9d2403de2f124354ce4172697a7322d13a8ec3a38810a1e9d548b4144fc805a4278476a8accd61b1a3c28a107b3abc9693a1d3bf729962e11df7560b2ec8d4fce98a10e651077e05128e7232c9dd111f6fc508876bf9f3b3ccbbd650c9ae609a2d424c550d4d90486af30097e6541b2ad3eadb5dc952e46bd389055b3ff6979f0ac43fdd598c0183ab6fc172a20f9a62c2a3f921e244a619c367503e8038bee73e2473280699fa775bef5728f48df836adf3fc0a97eef252bb0681139e84f99df2d79f4ad739edc26229dab01c813180be86c47218fae684eed0673e4d16a4678da148882f39da47f237a44bb85bd72d0825a7f086403b113069da98849dbcd5bd7a0c303e7c05c787e4d5d5edc4269c377092ffc93f87adaf322f0d0b56386d8f02ca2cac86508a1b986c9d2968ce32c4436c3aa29ebba06c1a124846\nSHAKE-256: 48b282bf43c4d4e8059f9afa77e7ee6bea9fb84b58bb15bf040ffa244d4bcff81fa7677159885c86c862fd0510357d0f63691f0c583b924052770a0359c5fde45ab4ff7aae727e5ad4560f8b6afa36a70d69acfa3d22cb12fc4f9b6d295d5cf02f7198821c39eaa23052d90dbde6b79e54b9a54efea90bdab219e1ff9aa5d6ae6e5931e419fa0d1a2fe8d595a631346b7bcaacddd831fcee981ca9ce9a5f1c98904ada4030a1039be0463eee273b15c0541dc39664e5704a046b1d1f0b72a7ca35233bfa14e7860578416403d2de9c6627f5afa93477252244cb911cc3a1ce212c20cf9d2bb66bfb940c3b7fd99df8db2df718d7e68f1050bfd5457ae0d289b8e13c4e2fbbca659e79e40b9bf0213391815ba7b69f9730c6000290ab3a670b7255df123700bb8a3dfedbd4dfba063956fd3f02d247a6cc648116063d28de81376d0835722fd5c8e76bd3d4774623c94319ae968f29bf8ae2f99d4aea602ab81aedcb3b70fb807a4591cd992d0de6fd8ee39459ad11636530d7554cbba85fb3f974386392e37286aa2372c106d20baa8d7b8e217cb101e03ef9f75f7c5ccbeb10214797de0b477cb38ddcc4b2ac2f33f176038cd4c6db34e204ae0451ff0766d2cc630fe7c85076c95f26a457f93fc34624a1d27bac4006c041d4bf0ebb3bb5ff4bccab659f557f5926fdf54ea5d12e3e990131bba12eebb4be96796752305c06\n\nInput: e61d3bebe9f35801eab9e3057e10817a37f87c4ca137c10dbfe957ca3f89fbd97716fa6f6dc8e7c5084fa76a637fa12826dca88ca430c99e06ec1a8877b3065f694eccad8ddf20d70b6daa6679ab18f68156eeefaf2c779c2f7264e50a36fb26567f762ca102378dc27cab4f2e4cc94a035c8b2f1a5f378c74acc6e2b5edd89a447e690437666c3e010abe4284a4dbeaf8fb9534297e5e8a2f3388abd329d2375a036dcdb8ad121c9af6c3f0a8f4fc376cc8f722c2de3f847db74c0c9b2d98c799c55865bfea378ec8b1ca00455b8dd06331e2559083c16400c51f591dc282d66ca4635b4ac4330de455d4a7af027cf274dd0c962370b6e26f199249a3e8445a22534b5819a2dce26a7958f645c6a713e92fdc16dd52223e5c1e0e1ccfc2840dfa7c2b49bb23d0ac65ebb5ad143a5f591c6de3f094f448fd2e0a74da2f7cdcda360743de7f0ee30ff38ec8a0ffffad137044b8b93c30ac308f64c97a9377d900fe07a530fc7e23486575346b725413b1e9af902fc083d7d68d268a8eb4a39c19d8a93db8f2ab910dd7b060f875d68e851fe1b69a8e75a64fbaa49c342c7111144c95511454d626fcf689a3e764629b15af5bdb6958a23f3e58ed4ba66ca3fa6777f2695ef2d69c24aa92748fcdcb588d48452c0c924175b6\nSHA3-256: 187d3e3331d3157198ed7e910c4d95a1c187504468383e607baa5548d7e6a5c2\nSHA3-512: bca0154b4a797cfde18ea0d2fe1ccb90181df22f85e86fe3f50660b936d42840b51078fd7a2b2009fcc4268b8b363c1595d1a21c6fe536bba793cef8cd7fd7af\nSHAKE-128: 27ba1160e90da4382273490ccc1c381f044a82d11dd9bbbf0268d764d192959dbb498d9045fa4e005b991b30c31e8b12cc7ed90a7414bfb12ef92b0716a2282e072584681877ed1869ed5ff30ae788ea06aa561fef372adbbfafcaf7dec30ac0356b3571515a421728a9c9b6316ebd3db2038b658f2936fdb65ef22fc349632e4c29eadca4cd6e12e3b66bafd8abc46ac24f230685614bde3872b3b21200f6398e0d143a5ecb4a169872b0969e44692531d0124642e48cd4d0968d9e0041ea297511305f6b4976e6a34368ed26b65108830a6b439aecb5fa964edc54a8cec99f9100c1f101d5d98367ec04df399f714accc7111a8019f8a857d3ec1741847c96e23e1be330d67f7e0eac246511424b5ef41cb18649b202e23b41e43f991a2e49f507fe437cda923371717db33a5a6a056a00aa2d861ce2e1352cafa7e529e478d00c2994cefbb2d14ec74568d1df7f8c0f8ea24dcb05f3d0f98b30f36a60605d1d3d7be55c5d8fcb1a380ac2eb1abbbb25f28304e17ddce15ab163f5aeca5f12c25a908231ba485207e4471f6105f3894e9470bf8711bef0925e49ec58a48ee869ad8e60b4317215321e07161c713970ae692a008e7304ef6c17ef4e248238c62f357240f1065b35a907c326d528c8529b703a382bfea504eea9b390a522d45d1645f3f5e7d47f2ebf152fcbf352bf6f48f9ac2cbaa6d067bf072c89caea152b\nSHAKE-256: a20f0ecfa25a0dc4ea3ee9f192bd368420558864cc242d76e168ab5f54eb9df8fdfb4a00a69a4e96610488a42902b1b5aa5e4f72a9f343dbe45515bb27dfd76c7f968c08b3e91695f69f736195d49fe7ea36627402c4c2b2b5e954354c8991412c6e8deb561bfa796a07d507b298182e1f6a19f52d98adf5f00e3f7a3312b3b7fe28b58aa4c303166ef926e4634b8743a92a8e1f089f313fe860dd59fd9a53f9b897f8be65737e7f8e2ff89545b734db4c349b3a00219e45ecd54fbb0c8090607ccad6aff0c571dc7abf198d5d1bb45a0167c284be46f2000d7af794a06bc25faa9be1776a99a93afde9e6f70b5157b049c9231ed94b9365712de8ff0b0d2534f5df92be0e913285e6aef03deec9718b039f4e35cb9fe54e727e2671e71f7df4f5873abaf8f994736d73dac6047702bdc7af7f66f6673199573baf06f8ac552be4d78f4db1ba8189f2dd230f47f6b14c974e12ebda61eefba1400a987d17524c4060c7f42729b5e6005d9c00ee503d1ad851d091df1ec302813f33fd4e9da4136059c1ebdee6d33f0e350d553e25390b03a13bbbe4dfc88a0068a039320f27f18aa460c9e5577431699387b75c2bd536c0fb000370f0e1ca131630f733b1a7b7a1dab67573ba9462f18f927f3bbdbb334911144f6d4a6f1063b18a4da596e7eb225309aaa547b364a3520b36ffb93654ff8ce165e02fcdd942b247aede4c7e5a\n\nInput: e8e220ccbe1cbb8d069b01c77d9d46eacc61c2473c3a2b802264506c86fa8c971288546efc6ac8fe14ba9c1a9ce46c28cf87d07c4c380ad342b35b975706b9306d133d1db83b4e517362bd00472a0a5eb06520cd23f039c43c7ac627163836681ca6b6e2e733eb0f6ea0d152ee23172834236fabee5d9914340bd743a458cf3daa0e937e229ac6425781db7378db711df0a6be6512f489822772f252ebbadfb1ffe0db369589f4d1b26f74e02363f1b837db130722d24a34be760d8bec1cdf6dbc9f924be8d6e2e40043298ece5aeab2331375f7bcb7f42fb25cdf6b5f8a0f520e3ed8081cbb5dbf6b61afab36f51769c395305717ca9e842d5b4ded265444491ab58765557375d0aef1e29739ff1e9d381e0aee4aafa8ae706dc52dfa0dfca098816e23c4bff7e83ddcfc1c3ca2f7c5530cc171bc1bc28692c51d4e917979f738674dcbf1da5d22e849255faaeb44ed2e0204fae65010037904090127f7afa2ac977050e516fd4436a8fa6fbfd8dc5463e229d7f3a0569cf89ff11253cae61aba47c3d67eaacfcea4139605dd495d72e91edb5e5f5aae9de4cbeada7393489cd7e222b14d20a9f42db0e7c4b7f0637a57def3686f786cf8b49d1d1719e90ab742bc84fd9c49eb40d952046a911eeb5f5032cb7961d788c8b4\nSHA3-256: 51f97563623fc8bdc42706eb06ae40614c916b9580fc86242db6cdf7f7c4f4b9\nSHA3-512: 41dba5e136c6c3d49a8fd76006b00f4aaedee5c378ad68027e221311017d4ef688c411d03d51112f5e7c059a01dd74a838f4bb2af38f752c76360f0b92792a83\nSHAKE-128: 2baedc8c5fa56a99a4f345d3beefcf7a40682da91b13246e1eacaa1dfd05b3097a7d9b411d769e37e674fe15844eb41a1ad154a136d4c113c29bf9c2ecee2f498805c50914b150a39a741236bd23e3109021638a305dba6325a9c349dbcb150296f3f3f5ce7ffe226b4cf99a41be170426624ed8816df7411d655beb7c4a785c375f865faae2c55dc9f84980c889845e474f915cb15c12ae43cb2631dce2f1d0e865b9072cc8727414a6d00bbe4b916164f25d64764aab0a70094534bc55c641c9402b88c7d03408874b665be20fff58fa5e021fed2c279f1ee7859ead7ee173f44a3e104d481ce2c718d86e2fb6a9bee0c535cafa12ddf47ea272d12066ad6ec8539ca474a7dae60de64abfe5bd5a2a2141bc4cf5c2b4d1f6b2ee3f5bb9cc700da11a57fdd00fdeb649c43745af6f0903e911a3388b25b7daba5499a958c306654e2b71c27bdec2ca306c9fc16ecb65a37947e2b7364a8b138c7f5c59ffa22b5e02929606a30b2c2c9ee8b96bc5793a7bf8d3a13ec669f", + "472c4a052b37a24ca866bbca5689927cd8d6f373618a7c5d4e38e82055d906f47c4e121a7d56fa4ca953864cf4cb36621eec3229853235f0d651ee63ebfe393dca0f9d8bc2462b39001d8ba22b4201b3abeeead01905011cadda624280ac8a8e821b70dd04359bd658d3cd838059bede2853f63ecedcfece37b566b45722f2a7cf1ff9527a577c777\nSHAKE-256: 6745d503ff3e061f782928500ca062e6d4381884d00886c492c62a6c5899b0cac187c5bbe3f593bea2afb52e9a58934050e9e988ca149f2037578d76cd31728b1e901ce7281d32641fc0309841693b69c3659c558f16a1a8b46483f3076962bfbe599845115e4752216d5dc341212bfbfa14ce742dedcc99114c7b9e47c4a4e0c5cbd482bb920ff351937bb4ce6d1fc09e0915c6005f09312bc7465e0ab3fd2ea3c8f199628d761617c2cad4eb1f09b83e62270f57ca105666a40f8fda376e95c9917de5a090049c50be5efa6bb369aa19a8c099abec64b330d3b04ea8056f25a2851a7290e00295017560158ef1f7a3b7d3eab841faa77b64c9541e8675a56a3f5a694aef70946c1ed2c8e05791793d52521b0bc8896782ecec4bca6e584536bcd7b2c21365b101fd71bda6384ca2fde1819e1d21eee07e58dc46066ee30b1fba34437c7db373c60b8fed2e0c8185076f0fe777b4039f2c05a909c014c7f7517d2d8cb2291e068571fcd1611307b2c48128d7506704cd89b526f55aa77cad3ba367969b8a5478b9160ae15898526dc4d5685a2184c6252597e27aa9c2c6a90892e9608e11160a69c8afa3f0fb4522f394e613dc3ae03c5667a7c0e690fa0cc1996c1e434fd2ff185ecc8caae1887de628d71900d02c6b1aba83eca54ff04203d9bc097f4928db55608d0559941a810ba7e79faef70f0cbd36efc84791eae393\n\nInput: b4d3022bcb91f04ac30fee0d98424251bf4d3da3a56bb59586a4e8fa371504532be89a2dd8755644050ba116906b81ad3b8a8cc3dce0eef3a1d92cfabf64f18ffe8ae728e0dd574deca6212fe8d81e9e6e483a8a2c834c9dbfeffc83ac2d40a3dbaa1b474136a33a069898cf8659e7685275a6814ed123ca9ff8070f2ddb94d8d3c4fdfa4c93fdc3504bc41de38e554e82f8d00b6b42962a3d11c8fb392652d97dc25f0f541723f54739149777704feec6763954f209a70b3f767719b5b4dd95ccd665d4587588fca31023abc70e0fbc6ce0040ab11a61a18b38e58967e4669e0891f20241e3d5e1331a80a4387564d59abe6027cd587f0c9abd0aaaeb2428de74708b6faca5f92d08d9e6ae2cea3a82193e240b27d455364e3d32fc7fd7620393e071305684c089c524d8c5949fefc7a65b814c161207130ae2d43473394446724fd98ce6b1ee179493f979b72c9ad244da0487792efb8d5693ea0f4eeb3fb94d6e609b3e343b2e9598f6afaf4960bb65cc659c23d2d725e25fa2e2fc4ffc79a89fbf65334c575704b27af7db94c9be07b2ce90c8201ac831ae365c6212f1a99852950432c54d2daa8c2608639d30e80ece969124adb23a29239288aa60081e3c1975aac27ab6c83e2318452c2d9a13d048e4d1bf113064020e\nSHA3-256: a6e3f8528c0d781ad16f0a513371748381399d670f1fa7bb0a4f1461157a36fb\nSHA3-512: 881bea53700f2b432ca4b905253737d54f9d59e6ca2bc312538f6c3b435869a386e717a6b8eb5aba6e1ed1b038eff85ccbf87670dd7c455fe0caef41d1d8f472\nSHAKE-128: 422a2bae7876bbf45c6d237fef8abf5f7d0cd5a58f4e013638cb57fd9a2053233bc5334c6f4c3116d83f84f0fda902a4152d56009dedd89ec45f3d870dcc92531351e2ae4da7d92426a31e86a45ce937c1c1a8c69768ec019341fa3c681a72307cfd218e12716bb668d39eb75e295bf3c7d1454fc8df0777f4673eec1016b5c9050745712ea5a8d95271b96ea18490918a5b6acbdfb8cbf23f6526a932059415829dd57c79d96932af942218c9014d96c4108610b7618026528b06ba363de76cdf9548084c55c38535acdc25b6a1bfb97004bbd817b3a3df3d22f81b75447116d1ca91c1f7822350ed1762344b796919c568b7fe053aa2ec9df921e32c4179281c36c03feb87ca4d09cdb2bd120e0e6dcb0cccb8e54d4555286a10023584530de28c14f580420e90b7b8eb634b527c9dc0d3cea0c4858922ab2032426523e3bfd954d2c6fd87b33e51951cf957a388254886407e161a83b9688383168475a87f196e0a5e33737b2944cb42d175efe5693f2de0289555f573de0f58f9dcb851787cfe79a11ef9913fb198d342d80faf1d44ac39a0af5a3d30445dde667f268cbe2f6e2f43d3e43a81259f0761f54dd8d22b3ecc88699069bb6c339d4ccbe58dba76405ea841548bfdf124485cf99ae94d766249dc8d1b05dcea4d82b0084dade144007cd58f748eb10f7f2e51dbabaa57eb77f55f93c2f494894fa8dd98929233\nSHAKE-256: c5f9e06a5b94001e4d3069e6169880baf40a710120cfdf186f931be3961d5a3c2fb19cb4e0282f22ce5c23d14fdc4efeca833af354c692fcf821b8a7a83fb2b8e6740968ee24f33e37be74226cac135f7370c024c1558b974bdb0e00c1b92aab705c33cbb0ca15e302d987dd45c28417341d5ee66d66b884353d5689126f10371b667d7fa9032082f2bd0c443e778d5c1b375b007e809a9013ea5c74b74e666ef44221756df4bc6f4829a39ad2b36ff1c5794b5b45ab279f39955a1c0a98ef0d7082b56ec2b3b81ca6b68f574146dc489ee2e46b6a9fd9120b0579d26d90723560b86f1b3e53c5302843a46f17ebfc4a89ae0406ca5c665f1400fecbf90f3b8926accff86b9eb3c3917cccfd3e715d3e2521ce1061b08cc0dce16c94fc82d3a708f9520e17c02862ec57ac8c47799d944a93591c18f6da7e38fbad41f559a8bf0a1f572caa22b1ee4684abaaa26ccead04db40457cb4ad3a58f694e22968f50a3b18b87ba570e229d6dae7633a36d8104835c7ff48197aabe22328db88e9f986c5ef138ce16b362d0f80fe2d4455efd718c3de382d2bd0ac91a7c03119db65751610266fe586094ed0203864b5ef04f95d2b5cb4e1fc1fe572373442c2f1d197d17aa3ae5f9e65a8996dad8720b9ab00dd52a643525c627c93d77fbba03befd6a3785c01ac6b400f9d558999fd40d70741079a76321b8c576aff70f60b6eaeaf\n\nInput: 6507dfc3a836e0675fe761c5ec3ac804211cdbbd3bd79786fac74bfcd17dbd6a15514c818390b773288bc0235b31c6c99e272d31fcaef739fdf9894de347930cd1f21a78ba34c3216a48987c85dcea8a6a231f109786f46096279a0ca179940d724811b7f14d43bd91e9baffbfde07f61902e2d9581af09cf8dac29a4ae4566872f93e9aa33ab3bb119a618684a2fd5a64f5bc5c9552ae2434f6a3c421a1ecfd1dfa3f100dc3df71987b3c4ebe6ba4cfadbe229c11936690a581c48a7e52b5028b0d489ae5b2cd0eb95f140617aefef344f585616aaf76361c3bb0428fa6ff42a30c0f41d7a2247d0da38172b9f05ab80356ff7bfdb5a44f2256a490d01df9dbbb1608bcbadec05a79934dab1d8f400ae92a90919d8b4f9f3ee8a23b6cae3cfe5da3b2a0b45c624d0ccf42de72b012897e5a2eb0eabbf4576542f6cab3aeb95cfcd9f38b3d169d37213c4cc5319a24b48eb12f54aa993268f3334497ad9f36bc9e91cb4076704160c3a23641ef2afaa88fc7850b2455008a80380bc34f87c211f57fa012af7155b5bc15e9061797a6647407fd73a53197a941bb6e15b2196bf2d911d4f404c586d2991d1c8bccde3b3d6949642602ccf209aecbcb69163e08213efe54015b12f19b7b4f308159c79821e97b84d99315fc8612c77f\nSHA3-256: 206ec7dd35fde1b697ec2d7bb53008656188f8c111b24aaa86fe9723efe3cc6d\nSHA3-512: 2ea140d263ecad9532762093bdb93b772b3ec8e384784f15464993c31cf00794b86ec1a264efef890727666b7d51506ab529483b58215f3cd21d3ca1d41892df\nSHAKE-128: 5f72193815db9df9c95b07326f619c68b6c268f26136e6b1898bfe5556e1001a823742c8f1bce28e37052e7a7d1d3d8dbc0acd8f4d6ba30f59cd60c29ff3ba3fb022168225e00e57448cf950631a035b2563703963d4a080e5c1bf5c5778f8e200db6e5a172faef2cd403fb9e0722f9d32e57b4a967a22c61fc3db3e0a7d17142232b8f031cb483bb2c83b630061ce19c284814cee08fa1e3bf060861353b89053b1f9bf08de00255dd52789d99b395f02b2251500776300f6ab10557b932b770d5d5e7021a5cf0a071d023cd9c8e07c6adb68ca880acde116f016c8de9a6bc65497015705447f3b0ec746f01ae86cbf3aafec45cd41b3984a5c4ee8af8fe205af5b511709798894b2566efbb9c54ae86b9c43d10181bc47511ca209657af1378591eadcbfb0238471f41e016c8d671eb31cecc4ec7aa9ff55015d79fe2de2dce7399f6583e54382777ebe553aa4661ee7bc501b4611e2fd2b9da10e9b02907a6cb170239cb81bd78939794f800d22ab3a396b6f90b1a6217499e8f937560841d960fc2ef9415a0c7f045b24c5ee901425dc2664c136964e24d10ba8a47c26b2a3463422a5dd50faddd1c43f26f1f0d82e7f5f1ef35315dddd2b60280b64c4cd62adda1210f8616ee51bb3b743b67b47f05dd7832587035ba27c030f003afda3bd5028a4520c7c901a69dab456b314aa6d92fc530fac25f643ac7fd0351175ac\nSHAKE-256: ebce28395b88df2f0a52b0acc1c6ade85e947da14d5266bdda229c64f098a15c228c46ee1d15298f25a91a7ad8995f44c1b3e53277cf21da3a4182768ead635b32613cbc2084cfaf0841306c09984b3f70ae28473b59fe65d78cc16e04ef4efd26acf70c1a67f85b784da2a779d6dfa5e0d2b8806e1dbb5069e0b52bf722b672c28c62c247258bbc7ce44a718f4007ce67a24d58a8cf2b430bc07ab17735f77cecd14fe1223a06a985d00ee06533f1270d349c089600f5b8ee99a46cb7400e8aa552c43c632c05f911bb86cb36d35511c9893ee1a3d635a83e35482e5d542fbe16d4a30ecd3c9ad53ea7b83fe4a970098f4e6a3cba363502c99b872ef08cb92b3366df4d380e16f402e811e2d9b7b61a9d0a162ba2437f35f1066c65da8fe0e861ea8c41587a18296094aa1853da201dee36e56c6cd0ae52e37ccd4fc3dce7ac1cc3c2a28d0e2b73f543b5a8bb967f272aee2da2b8426074081549a467fb4535b0377f96eac1fc9ee1f56314d52204c595651450443770ba5dae7b6ef7765007d314e50020fa7f7f404e12406673a52b3e46672826d603dddbe4d9ad1f5e91e84d23a729efdb4e73c26bfd6e2f69600a2ecc39097a5a7e4f1c7e60f9f050ccf2b91c6af4a9e9f4ab44e8d77bd1a2a8261803891ac60e91b605cd26835d0babb0e8e9ab0ad04be943cbb325b47966e133e59f6838e40beaacd4cb1ea3b0cd3ce3\n\nInput: 3b7c8825d72798ed1f7bf71bbbd2ad0150df742ce34ccca2c7151a83df603e1af8dfdceacf17080f9c8bf6d33be1272c650fceca0b18c629d8715cf43ec53062014ae84616acae8b4e9154adb7d025f3094d45850da71bc91ca4f10d2e18a8e1da42e71723fc6103ae442776050a89dc84476a268e6e7a1fb4e01500a83eab7668b698fdc1648612771714cdf3a16e11d3d24f710a43c947cc39d7d218569e684031018e53894b94c0a1f76395904e966ef04a3ebec0d192452a1adcf30f7659ff", + "70b0d8f24f1239b677037151f7cc4048bc7d76a24df2ce19d5dc7d76c0e6c096df79370bbb1c16331100527816c1f6dc440396a2570a9f4dcccbe637fc3ad1e0a9bb32e20030992e600190049190cbc6d503ae69a5c11fe92db46841ae26fd6de8cf0231eaeb11e90eae7aef0cc8ea98d0c58f3681bfe7332adfd1814c11bfe40787f74d67de3ae5076e0374295ab431c5a6461605942a6e076378521b1f9aa9320c21193f8ceb759c9667ad12f475a2efc062b3ae09b83b1a0072956f6390b2514278515e05939821bbdee89f2be1b607bd330146d6a18027c897916bd791bca24e91aedc4b1c9bd30fb46dea0a9b239b105c7f73efd6c06b063ee16d69781390e8383bac7dc86768c01630fc83013725f1bfe9c6c5e06134c3e1\nSHA3-256: f00a604f8ecc7f4943953fde9ce30cb7d803f1a657c891240ea154a5cff2bdb2\nSHA3-512: e5ae1d5ef3ad03b50fe21911ce08619ac70dd0f91bacd7bb5a85ffbc959ad7aeea872f69903f64fa29ee455ef5a55ec70499861b93f8d07ef6e46ed71569e89d\nSHAKE-128: 461053fca799a61779fdcff5c8035cba9293933d51a3c60560d795aab4081d670a01dec137f14e3228997b77ee44d717952fcbcda0a1f5ce648fc83fa20121fcd536b1d4159dc80b81f1c62e027a813afb501e1e12709dc9c9572bf12ec3f860fef95ad73f9a9f8178080233f0e2403dfa688234711762d981652db87004457bc415a6f16deff2006eaa1d5e0f085b9e25e4b8b5d659782e9be818254be4c5cfcfba105fae37158698e952b28f7d2026c224813969385dc81482d22c5d3ada6cad7ebbafedbda1c638a93b43c2137e05e38deb2d6818518727c6a4523b4c8e51cd1085872cb900065408eee415d3c1744fa9db57b7b894c6a0c01a0ab5672a836614432cbeaea67fe2e03ea9715147306701b376060f320edb23aacd47d824df93b845bba783708eac2aebb541847e21a350806002635faf4346047498080018321e7ebc6dc6a8be04b6c1bff980d37c4efe6a0570a94e5a530788bb9e472c2a8984d140b1081b77fb5aed7ac41b81e29ce2821341355897d6494148afc4158ba7735a6159d1744fafa6c99c584f3ebc56c91d3279da26b6ae7adb293e36a55237c223d2c4ab470b80a095edc22fb70a0aea3726a50188f8d3cb2edfc7ce67934ac6703010ed4f48ae05ee4e9c8e80126df2ec67d42898108b3ada796614cdf3a0ae2d13d4c5895f91adbae13ca99b5521e44ada1aed666c9c0fdc099c41a58a\nSHAKE-256: 56048699a68219c711552ec2fed9de656e52c501e5ecc925bdbfcfd7c48dd8740bb8761c5fc94a92433d6a0e39b0f5280cd43af26144c356d4bf96d8feb14f3ba6ea484a9ba01235e6330f6a15f1fb22ab57c9f44b67561651e2a745a7ae061c9035e1d50cf3f83a190c3d5e214c48d198b6a7f1f30ed7858cb864747525fc7661b462c49b90919b8bae8f184288a0520230e57717471b892428a396c652b708310764d20e81e17b4eef3479d3922716deb08b2767d7507b13caeff05d157443d678d96e086f4d01ad608216e75bb9e0750b27c934b4a4b8e02c6c4fb044aa20f4b02b2c3bf09cd0b60a98d248d1a5d967fc0c7e20085282e2ce4bfb4da0413ba7530b45485355b7556ff2e95606d8b75bc2522dff1ec283c22c8925f532537a67f830cf5fa14d95d3dc971e7c3497733cf31b6014eb8dab1b4fdb6c035a50a930f5c813b1b6267370c344eef2a39131e64b10a032bbad808182c4aa5f0532888a45ec37f1a3734c8756cb701ff16c5326d6ab131f11df9c8169f0f9d0f1e8576c9bb0b89e6666a0013baeede8357d5e502452de29beaeda345001f810cc43679905a043838b1b76d85797033b8c6e03ddc4fa384d87f99cf10b44316029c1b94693b9bc9cd18ea86726d6f0055527fdd92c278a10ce4ca4aa44161fdafab463b6b483be6c8b0824ef998cafa2447aad4e595f5dc53215f4c126031729e2fc79\n\nInput: f7f4b8e8433607a927480cab21d263b1a7fcbd9f58c26b76e9a60ff99e34423a2642b561fee9331a2b34d59895226fe9ccb1c6d6bf32919f7139539d57477796f7ef8cb20392a137db19df15afaae54b4af2d58f143a364b85b92135762e1f04c6099c3e5ee05610c6b78d71c733fc9cdc89e7cf45de71bc7f3b24a073f7bf4ea7e7db1dd995cf8e067647ab386040ac9b14d5c796bd4617c7c4e95ec76e2750e8fd0718a82fc0bd2a2f671cc1e8cdab4d9f48ab76aa49bf1797d87c167ecf89477306eb4ef9d3abd96e1d9d99418ef4f14b8d8ed6a79eb14b2c71cb16ba6bf94ebc1e64a4324b344362941508d785d7f3d710b41d0564bbea58f0f6e843661ab6e187c15aa0cc0d6d09fbf56ecd2b5ad54781b74488bc69dbb90e5f06de6ff5e020ca7db54ac52648b76e47b68e17f35cf32c22ed16cd88c27e6d54e5a2bdb00c8450cf85a332f6221eb02bf049d09182254a32caaf37b697c69ad841d374a0ee779b13d709386530f506fa3593968250e61f06e4fad62889cec65d4f65aaafca7de615af08e59270cf3722c0ed03edf170c10f47ebed651a74a42d9deb17fb3e0dc9f860d78edff5597694baf6e928f20c2c1be2c157518fa2bef37d72d1e5dd4f03e63e4364d31333ff7b0d9d1a231e3e4c4871aa77baaf4c1fae9d\nSHA3-256: adc72d265b2c6e016cdd026027804a2665c86a758e123dfafbd9067ef91a8252\nSHA3-512: aae4be63b00bbbb7f4d595ce7dcb4cdac179c4e406701473b16a7a3903cb15fb13ad1549eb31d04a52b60e21ab0e7eb5d2d9fe2d6874c37029702eae81420fe2\nSHAKE-128: d880037936802bc555f4bf20964c36a015069fee4911d2ee65e32fbb8ed4e22ef1eafc82ce60d60faf1626c8b136e01a7adc9201394d0dbf6d9f0556110cd40e9d24903027af8687d911ac5018fad88613d54be0b4bd5b36be75ffc923cad4844a6ece04c5bb166a491dd326fa9e204f7ee4450b78b691c9f99083df89ce937d6249f8b8f9f74f2ba04d20731289b62be217b25bd8e5786eeb0272fc04b52364425b51e50d817b1572d5066b44b5ced71a0193ab20675e8718680d5668d351d71154940cebf3ef8d9d0cceed0ed432ccccbaab1f47b85ed82964c3e05829fb08811e104566e0dfbca7a5586fcf29b3265c82e25d3f5c703855b5228bcdab8520e52289fda23050785f63c72cfc899530d5bb5a9b509fddaff02588d71316abac9724032be8b4c8e0068738d610571625027f016b5b1e5f4f7034dbafb22b4d01ade389b0e8dab57ed2c25dc4f91ddd5135e35882c15f47d776407f40e0bec98bc04534a5fc535617f3cf372b4f5682991666607c42ba9ea5155e79d35c0133b92cf192bec37d8eab47c307ce18a288880687027e553d48f9910a045ec301482d877d1e34911635e906770e06c7786065489216ba4a9145980252ca0ca9ec93f1d7893e7a9da24164aead6bfa60c2c69a771f7340ff70fce5f176bc64be040a0c237a0fcb7ba09b84d52c8cc7ec1cf43e2fa0171b555ab6d3be0998ddb591590c\nSHAKE-256: 5680a78f8f098956eb6f18310fd7275a1961d3dbb1dda3a800f0393c6294faf8378d6bd8d38ad1a4cae117ca4723a72306f68c6fb9b2e66a3f4d474d0466b0f1210c8cd0fe055738f75de6b3e875bc2d65a4da807e7d053c4a37863cc49cfb909f33551b29fbc8b83ee496a5a674ccf64bdd99967ff2103028495de93d6b3588c439363e77888823ad3a7e4bac0ddb0673d31a5a49a258b34d8817f15857b169a85aa4ec4ab12875f9a351bdf25b5a03569d020e32c674fbf58b111ea87494bbe02a735ac8cb469dc29cd99f11b0152bd26cbf9f6eccbb28c87cf4757ea02458b9aaed1a95cacdb4326bb51de46568b40ba2d31b93214a7bbd14cebb764c342a54accb361c67037c16e89c93d6280e1f49df2cbe3dd69d0c523dcdab18cdd9ed3ee2efbcd3454aa09dd89465e1c2e4063d825d71c5f75dfe2032d8d1ae22b5f2ef0df5cae38a88436f3b577bac1695f7a37acec0e132c25dea78f5547240b678df27d74323fc2104769c90f6f59b0b8416873d700d7e52de7b78bc8f680195271f3cf277e53955a976f4588f66b8307cf27e79f3d98b09e5af787a6ff97fc123fb34a9ce8f5fe93231746cfec223f9a0a0214c5ea31d949ff59c6bb0cc0b31a4d5e7dc5669b95f1a4d2657b7411b812cf249b4145b9b435a45e5cc6341f9603388398123f2d3e460c9276451ef15c7d234c283b92225633c7dc32ddf7ac8383c\n\nInput: 35f0e1c9f8f94d8d2b83a6c2cc4cbd573d340a6b515183d57a7aaf9aead1728045d63ecb759a774b8a7ecb2a17dddd010b2c188b56058e88e4ec5ea81492f7919a2410190019fd27b7d9d2a8049015e601f722b536455ad914b1e8fbad9cebf8a0d3b1f670b98b23eb6a66ce1410cab59169e08b2a1d21fafcafac2d52e54951c63594d512e289490086c2ee3ab43c0d8c0d20d6c431ef94cc907f83878937a7a6d8fa884ebbe09c7d251a10d9de550506a34a4e09f0123aa3a26a891a43c36adbc258ca114b24c607acc0e95443e60183d9c02c8982c3dbba8687b587d2fc3a92f8026946559ac088e74401a05d76f47f7590181615e68c2da9cc8b595add1565df8dac95577e3db486f4324889e08be7e3a82c61d207fac5b90802334c904824181bdd0f063eca26405ac4122cd5ad65a0ddfe3804c3649cb8fb8e3fdb6f74b7f73674ce2efa2515a93d19f83168aa1b00f4d9aaa919521511f568db45e6d8bba52e65e55ed54400eff089a4b2e7b1df322203590089aafa40a22cd456a1e0d41e5e4ba43292c5a1313c0ccbddf48c79786a513fcd1b0317260f9c28d7245ca53cac7e62752e1874d39cffac75c2c867d8b6ff01e83852dac1378140d0e3be14d35df05a2cf31fc0ed8aed910da71e4c18597d439c409b5858a13c7baa\nSHA3-256: 11567ac107402f32d9faa4946450a53dce3e633d09fe1296a2403736147db02e\nSHA3-512: fe35e2c4e06f2872065da653f5077662f725efa1a064df04454110518a05a471226685de6acb008e738f961183659d030388fb974b3dfb194fd64d83515660fa\nSHAKE-128: e3214d0fb863d585b1517f2a8c68851abb518637b2e8e49f6e998fd1f98d95f74854ff0c1e9acff971cbd7a6785da89b0b9f75398576b1120b3cd1a79a88bfe7a6b7763ec4f4d7f970a55a651a9fc4c4edcf149cbd5fb9d420914527eba3e49e8a55727b2e36535568daefbb7da1e3e62898b084d92bb8127b6ce59fe0d99f884fd16690499f5994660380693d625975ce1e6d3f31b2c534b4a4506903f871e4b1036dd5f376e4b37dd4b1faf3cdeab01c0a866864b4a9d1f5065cfe13afb1f5a58fa76d89feebfd0c62a50a717bb298d94c8b8a84eb69b8b8502c620c649340c5725aeccdbcbd54d0dd006b2b456f0f98314a372c5ec03af52a3c31a4de5276b048f5f8074d51cfa7c96c818243ec5430edbf2b9248a7c6f57fe027bd445762dac5f8b4922b349910d4452ed00031e1c1da31dff0e711dc682bce9164a79c2a177db529c269ee4576f16a67e2a50d77b67d2b9a0f3aca584764d6df89259e3179d266e0972c1a06f678205ba63e7427ff5e0766c5b945a3453021adbecf371e8cc439e7802887dc2aca633c414c91ad6312dbfa6187b42fa7bfb1206c39665d45e8ee82ce2a86c8ccb525d762f743341392f2eaaec03194d3f19745edee016cec5f", + "3085871b7a6bb2feef2dc773fd46d8a88e73959b7587c117402024491330c5c76ba6cd9255bc1182d4eb88eed52e42ac315f4ece90dd297eb92803021692\nSHAKE-256: c2f1d20d1102c7afbf81ba2a618f00afcfb52a19efd912d298f3541439296576973ff83fc6eb1927573a9b341fef3ad7dee77d97401623e18a69d7772781646c4fe676a832e17a7b9535fac06147fc06fa5940dbdddc52fb08afcd363febbeb956b1358d75918ecee991636d2c5d381bde250bda6ed8e1b541be791d88cde6ec0fa7d9ff3c8e17295978ecc3ffe9914de749c13b5729fee92b5ba20396699cf09b886cb30fdf5ec533bee21f5fe58d1b125f6498445e3153eec27c05651f2033c9805fbb4c84ef648ba76d405d65c3380c5aba8301ab739642b6bbb2507b10b54cff5945a12995d384eae25a2307f2705147b04d069500898e9f3236c686342f9d959acd30fe45bcb3b8253df9ee028609a5c390d5303478f4b9bec783c1ef372b34e04f56eb18a195dce1be36cdb9e9f492441efac0f791e3e4560d9a347bd4803f38aff1a556b117c41ef3e2bd26032d1ecfde94c2704541b68914af6ee55e4843a9ef41e1cbcc5bf3dc442e5f524cf6306072d18574b571a84ec504c954215ea1898071953cef4a15b18e7ed5daa4aff763687fa63376f893df940a1afb66553c9f90bcb2b30a2d26728d0b7d1a8842dd6e10b808a49611b72f64198d5680865902a3fc3ceaaa3adb252281e2c506997c1c0a7a515318b56c0a668ee703ca647e5e1c25581ab60727f99de09c46a53122918a7600575614b9ca644881f1b7\n\nInput: ac540ae54964328e9d7c2d579ea72dff9182ce3fff95e90ee61460fb7ae2599a30da7b1b33e5d9bfbed7436c021cc7f72552a44961d63dbdb0732f384e51611f910f4a8382291160654cb780bb40b0b8ec0c7c87629c5305d19fa34b70639304242583ea35338e49db05b97d3e12e2084df72edc49fc5c401b674e70f45d213f020578896638df2ca15eb28f6d1886739c43f48128f2ebdc1f59c825ab3f683739e7e2bccff2a7e825140730036ce9e16386bc0a785b2245b799e713a633342a598ee08c81016d49af45b39b1da8e38d0b77775d84f9ab77423ccdd97b67bfa2139490becb6f52819a32d80fd285d3dc0aef383bef34c14aca50319100cf92fc044d7ee66563f32c048475f5464525d5bdc36427c88caea6eb886a98c6117da0a368dddcbe691d1e220231c8434d055a1f23f6f87380fa5d621cd456d26bcc3286d7daa56ce005a88c149082c9255fe2c5c899a578f4bfe5ef6ed48556a3ee910a4729f37192fa544bfc8e44b816b92baf6abd2a05d48395c36fa41103257e9f44a14ef8dc2d9dfc1712ab465c9675ccc84964fec56d22035a64106ffc300664a64298f3cecd519af3d1ee85000310f48473eafd82bbf3b053ca18714d6810c65bac4eeb01239a8d342fa28c4a3252e1059bde687e092b198d7be08ff8d9f4\nSHA3-256: aed4f59acee7d7d2f985faf2190e3964fc94bf9a4be10bc16706e52d508cc4e7\nSHA3-512: 070debad718d8baacaf6eb6d545f0a2de4d0568b4c28510b729b90bad9db7c1713c98130f1fb7b1a2891907f73ce7bd1eb9078cb7fc8409983293406224673a8\nSHAKE-128: ad1e4c9ef1602b6a30abb2cbf36517127f770b570689d3193e0f4c31355437792e86c7498d3876c5f527cc2f82ea17f688f01cee8d31d43a7c6d8f89978979496638a655c06be486322ce978c13bcac09e0142275a66b624d6c06ea5a6887862c2846147049fb35dcd1f37519eea308a7f10fa635c6633ece682a830c1bad99d1814591eaa3a97595ae6c6bc1c37c8891e6793e182681631c61bd4e087c0b309177b06739496a1b042c46cb504eca3ca79231ad12f7ae69660fbadf476ebf470441348b15dea01dc89b03e8f65f5d034b1229c1817363cb681d473b43ce9d299133b7199f20b838fc4383ecbb6c4d87530f9e8ea36cfae0086017786615109f2a0eba2353b7e502afbf74db86e7879adc6c06351634407d1f46cfbfc2d5a55342786ab8b11b1cca0a6c79914789f38ac64448a5ecf7e5a4c6d887772086c598bd3e8585bf525e5de7350c3917a07549c848c3eb2ecdc291463b23a77e088e3d78882ce75c703cec3878090245ae4ce08c65b183eaa08a93235a78e6ccb489b3177d3dfb3419ceef89aa837482f2f92b5b81e9074fe10fb548926ba6a85e5e906b1840694a86e9db206fb35cce798c4d9948f80fa2598541d95f6e95765db37c6681ba2df8bebe7a2f633aa25c021549576f47b0b0bc49059bd55422dcd8e5d879afe7e225aeb9e039885b7563303bb51c520f993003941157bd1faf3c51101be\nSHAKE-256: 58ef9ef2d82d263e3a1e33f9ba0670a7bda43c9a5f9073d12830092bb2edba799dbf79edf37803a27ae45fb274db7ae3e8dbde30174875b744375b42608c899e9e815595ee1a0ae8da04069fae2d58c1d91faeae91f0580efa9e5149f83ee3f1c594701b81aba9dc6e0c2e94777569f52c073888f56d76cd6cc76cdbba840626b0756e9e393a02976d3107519624ac0d73fc40e93e30c33e9abc2301c02e73ec905d6067f538d35598fe5ef345d64091ba2184d75ae82c31d0355f90df778d6d4afc0bdb213b0e159c89b6b458dc4e9ba5d19f4fc59c61c1419336d2dc2ce44ecac1f911d188215e0866893f7289467f01555773db06154eb0e177e9a0c368cef88c952559ece865401e8ac4e0c387e3dd59d7a1a9e78f4470e607a9db21694de8b3d85d6b526b13675fbf2856682a40677c6fbba1af50cb362e22ad9020cbe3b974e8e056c3bad61029cc4f83ffae42c5b7349523cc5cfe64fb5351c874a91e465e001820be70c7a0d76837ae264dd6b11687c497961673358681d0ed5b7f03d8202c41d7210cbeb54f41f57a314baef7dbdbfcc6a0e33984590b72725280ce6f75a437867465a52f77e8961bb6cc4dff4b5bcd5d6aedcae9b5d69909eb7f8d38b94ee369b09c133b1d5176fd2ce80101694f3686e057c003638fa575cbc0341820ef3e4f9a9476e3795ab6eeca3e59b815f0245afa9bfd9ba3c8e03366f896\n\nInput: d605f0dbb7cc90761c57f304000512f95e402c12ba319581cb3cea7cebcef2c5b15cd9dbdcf62a5b323c589c119ca492758cbcfc191e6e066eab4d76edff3e2d74471df29651ad1bbfb86b67b9ecfdad35349c81354b6400fdb625f71d22cbfa0afd52e767e12b0e8ecbaf14faaf252f22c940fd2859c43a3e37d8be70f3415fe928b03754cd64a2e1ac8ab7e49df941586df72a86e3d1c122a2e54941160dd7fc2414caa4b66c0aa0f5cc71d60511bb8f5e0849c3e93b5a6945ce9760eadc725a87a43ac5668791e74bd6c879997073d3d65d4222a8500214b14c9c299c0b629417e408af6f552a598209c3256cab73f95c9bddfca0e915cb19cec4830fb4916efcae57d64ddd8964dea61c0248a6d10937445bcbbfbb7d47746b97da1cadfa0fcbda7dcd6cd8e4a36d003a5739d9536be6aedc13e68a7415163ec1efd0cbcd86fa27a394fcf3cf58da9671ff0d1ad7502510788137a01d1042c91b253b1e41569e0693ca4374ed24c0342c238456343843eb205c8a5e99b20bcdf329c0d3084b00327032569fcd8c0aa53bf28f69e4e82c26a34a83a5bb256fcad2c9a64126f4f5b26e96cfcb530a9612af917d6802791f958075f600c49212f669a6379831b4c8aa0be2cce523c0f6520d2d15ac03a6b7d5a8eb371bef970797fb1791c368\nSHA3-256: 7a65748249de6e690b4ef7428126186b7aa3680900be69f86d9cba4f9841dddb\nSHA3-512: 355b3de93c86b9e8fb4908accd21c0e6324b9948a38fb3b92bc5f0faf95c6bd980f5abaffb843eab04b34149561c11da4d669038d5bc655864ca2e4c208812b1\nSHAKE-128: a2423729cb67210f0d0b01d538225b7590f42a92fe5b5c82a126195c7d74c3fc0363398dec5cdaa1bf8fffe4aeb3d705b11f77e9362033c49a6dbea3deff887d591b1dec433c329c9b46efcaa59ff4edaf91a4edde9a636eabc16e21a46a05886a073eaaf84cbddcbc2dec51ae9f9e1055f226422dcefd9d3b32c12aed03cee89bbecc48bdd6ee814e9ee3433b0dcb85f5ba70d1721d3b2d916ca2b4c44dc1867187eef39e38c4044fc888404f62ee8d724401f417ffa1c29033c806c9a535debe9ca67e1e59ca996afb4c1541bb114937e30ad03bbd07c5bfc04c496d784e9948a5ea7aa9e20fd978b4d73ef8c0c8aeb10453002bec0f61f00e15de15f3fad8135fb46aeeb6c63bcad09f1fddbf9c8784aba8247b124cfd60c2eb0e2d52eb5cbefa377efb83efd42cec4a215802676afb301cdb065f1a996dd728b4d52f9f07c2e89db3859f163bdeae380e61095412f3e000ac33c4218f039fd716d4d74acf920202da3f67b2d93db4ab39671975b50c586866b5fd00fe480ab445957965a290c3041f170041121e70cf8859579b486b97957f935637ac05060a412788b9fe80819a125fd513c707cdf5af326760645538d975c76579d01de86df903223da8c72f68756bf3e42505f33311fd90d3cc1a2c1d795862bfc01c53a8bc9d18888de192d151d05d00965f83cd675527ac92271bf4b4c5f5c1edb43374fcc6ada6b0\nSHAKE-256: 5cbb11585987298de72fa2e909c0daa303ee8212aadfacfa3072efd3c3848fd2d9a336f07efa6c927f241340fedf06a2ffbc6a1898f9aaa4afed4e7fe2aef93efd215c07327d035bb07a7c1297e2680404734275a0d41730b90b403ec6978cdc181d9dbec2422a12caf0420c5bc516fdb9df8b39b2087bde474c44a9b2e02068fe1a3b810358c80a5987ad636065c61d635cbd1e78baed4c346ca48750dfc3329d5de73c0cbe53e193735b84676feeeeb519ae30a33141fa1c0c8625659beb2d786f6ee484e51b71da1ef9b777fb6a5f1e2bdf717641951d45a4db637200f300c0484e342bfcd69831ce8403df60b3061adf15c27007805132fad3ca24e252fdb006ef1ef32eeb576d5c967cd93487cb3709246cb23a0dafbd9fe333a8d9d1de30fa9bdfa13725a7df51fc1219205915256693ee071830b26549cad2c14eb04c11a6435ebfe7e91afe11c6c91bc70c800accecbd855eea25e938104a5be78bbdb878391bffd9b6258541cf1b773a73801e9bb1b740078853a978e921c87826fc5950dd38ccdf053daf79f3ea33dbc2f571a92c1030b55719397489f986d69ef37ae99b0b1e24c5e48f7c102ad84592b7838f6599dc881dfdabd743ab551476c569b79273e08a76ba7126ca1e297c5be17fced1fbf692c441451acdb09d2271a29e38f15a9965000aa286c975d8482b77b033124558554b3ea44162166c08a8db\n\nInput: 82da51641b8b2f30614e0c50343be97cabd51998c60ac0a46509db3f31376e76917bd0b631acbaab3b06daecd3ff1ccf7cb5718d655fb34ab0e9a9cab568d50cb2af8ef36959d20c6c9b414e8050d03fa50c9143de657dcf4173fa6ccb627872c7c19e2a14980f9d13117c85b2b54e30450e0af2ff880151c4713a3cce448b0be584a785036643ccf9033f123baea6ea464a3d5e23654d8bbcb4388a99caf23d53a7209adc3ccfbf597abd0d569314464caa75cc5fa7b507c405e16024c7c3a45b6c491fcdfd2cb9233f62dd4d7a282e38177b1cd7f6f90b2f2561199a01d76e0b8be8fe970acc03442ae93d69c03d0b3d1a996efd43c30b6ebdaa08ca8e35ea9b7", + "fa7597da537dbcc86158bd33d60f210228f231707eff34d3e93660352af01383bdaf0ca498d5e12cb08262259f2769e02bf34eb10c6160a9fe747c7265953733baf8915f2344747e2a4038c332e7402cf868ebb822bde475e334cd0a4516fcd5fcb00f86a865113fdb5a931fbddb5022bdc302aaa4fb2dc6c68e89ef1f70a6d4051d5ebc8a4d1ba748b2dc915f37b006a439b4e5d81ea54014493dea3ab02b71c6541821383bd7ceaa78ef6f45fff54a83989e8f4b72ef0e5741706cdeded70dcad1075e234d4604b29f1a7366384c506ee1ff8fbea418ea97cb0f8321bab6e\nSHA3-256: 4585ec2e46a070090485c6aa2ad1ca508f2783b254f91bbc3125bde031813ee2\nSHA3-512: dbacd8b4978ff05bca77ab1ab02da90ccd804f0f4ec65907b8ea08c52a8e1e9999052e5f58ce2f08265133d573501979b365d7ceafda59446193323761d05374\nSHAKE-128: 8199ffedc66359278e4204d5cbc01c77c1ec7f26c649f0cd5e8ebf92418a2f087dc05427da9aa277ea212728c3d52e3d4741e97093d4a92cae158e405e5c7f6f4cf1e664fabb9573a2d269494ae27fb4b954a1dff8512eb2602933ff7bbf61f5d6ff99ea8211c21a4e1ad46d0d443c0d5294f531ff50581f3f813915d226224a5dbdd2c42adae80728d508630f23b701be79e094699e20f575f9c43295f6a1d76010fa299fb6559df6fc5d236c4d9e388356fe5ab0e860e3abebe4cfe5f80ce1360e6342874c4c1206a9ad3978e6e5dbbbad7839f70bedf6f0c7a240d0f510ad7eda05c1f9dc9de462fb023f548b1d401ca304d571568496f083e33a1401d23465696068e085529a4448656c07487fab20907cb8ca64404283711ea6ff0e97cb81869dc6600184a2502a82018003ad5fd525c5e404d1d69cec0d4dd5730a0920d83a0b5df68cca51a7972fc5cce05945f49b6aedcaa9d3c9f3b99a681fa34cc21fc89050d5e052f8bdfad23db4a1d6823f1fba6bf834bee4ccac8a1f92ff68c058f5e0a6e0375c99e416a3a95a7f997a45ba0a52a262aa84b95ad4e5b25cc54c648b38dc2d1a02cf757464d1a1564171944fb216047d31490f8f6fa182ab36ac776b75ed1ed2ca81b1452be59f9ca7352428ef72b4c410f13e313224551bf111ebbedbdec260ade059b1fdde65562ed09c81cac23f3c74630bb078365a42a4f4\nSHAKE-256: 2b2a758a6fe977633f784de8f7747db37a5b58950136799255c4ea7997fd45f40bc787dbd44633291d1b181e647d59ac5d0d4269b67d53a101725b76a33e12ee91d83e58bc0644e19f38895b687df7f22b12bae0c8d20057b82b2da5a954acee114ec940d5ce7e884aea3f9e2b70480a0afe517a59f3b767cf72774003025f2b858596bb3b3111fd270a69c1c6edb6a6bbc1653b6e06616f69e9f4f4ce3da768f415cde5f4151caa204e1f5b51733e8bf1de00969d64abd66d6e30dfd75ce0e0f6e086f7fa787e14068fc87129fe179df55e80bc13a0222375edfa2ca523c4c95420065a7996c69343af9aed2df1188117913b6af358251d5903f6b4000100c64f68140345d3b4dc56248a2f7bd17d18b93870a81120d34b6331c8a300c2e88de8b0a7a3b08a3128d63948fb7116fa1c27b1199385ca2308f5c2e851e84b061cb19b84137ab041cd0a8beacaec4ddfc28a49ed8ae94b8c803ad8425001f29ad1c0fe351c640fd9578d941c0edb216d22108ec587307f5fb3d73a3106eb33ef66476e76d0e8be4d4c9eb8a9e6e2e364d6d26cc054582b7dc666fa9c046830f609a044089f8415edbbac2d8dd2b350258c64a59b49435e2cb987ea07cda531a7b7a73fc39e58abc2b22c11f0d27419f906c1b8fb556c80f051e77b5c36d6e9452d534da4127e543174654ff8060c362694325e723ddd0b531e8c9a234c2cc45ada\n\nInput: 0eb2246571fd8b80a04e368c17a107daf2c9aac6b90d5c2c27f1bccc03ca28a869bcbbbdcd27bd8df68870581d27e838fb6e4ad509ec9238c19c69496b0cc1b10acf095418342d0acb64c44e0e0f61cb51e5cf7c388c10fe4c30b21e36bb6670da7752e4fb9f81844f0cc1ffe5efd1b463e235234e863e2be4249de94ab85e5295dad965f7e2e65a4cbb080e69cf9c67d6a4c7c3884646e577ba55cc4fa47147e5a94ec1115a33f16b609f8f5944aac3eaca2d150492265681abc5dee66e27c87ab6cd16e847d63d5f771d809ce295d116f32ac8bd83f1616dc9664973cba09e9936f6a8d038139de4c18c350d293a75a6fbe43086ed7f75603a29f73dc69c6ba397e86ef05d576c3e26faa1586673d7df62915cb76d5f10ded811ecb952e91206088df1eb533d8f18199799b65554d372a6c4e9e357e7b2a1593368e05f85579efb81bd7ccaa08c7875b7fa80d34929a4634a3212c8faa1c27011106d038699419384b939891bc9dcd5b63ef55673ff2954302cf5b0d24e78a7aec363d4f3ce9532f8f7b4c40a8db58d6ae0f1e5105741d1b45417d54861de4ef84279c9769b8d539951112f21afb35bea7053912a02c92eb003173a1b8a36913341f59b961994dcbcfcef87a849766de0945295c3886831e4836974029fe1b82a9e0413d95170a9\nSHA3-256: 128f6788865299758445df5ea69187447722563bdf5a63d0e265d086ec3c8eac\nSHA3-512: a07fd478ae89da38d4e81704acdf1e2652917ec041af628962572b202fe2db9ca50dc03c9a2f33f49b06faad75c4397b50db2548b37f11536ca0725eceb3d34a\nSHAKE-128: 730d6d42e751971608b5c5694db129734614072b6d35fa9a1d517d4ad5dcb2577bf3180ef854231ff29cd0a4603af5e1c9b0bd14168f9879557af4c008cc44a62ff5bf893e4919653653f2dbafe83df22bc0ebcefe8b7889a3fc1c86704edf4657d2c9523e5be0736f1938277f39fd1a7c3615c12a9759118dedddd4ef3eb5b4a9ddf741b29a265d1416b6275c678a0c3921b188f9bce89624990baef69e2d74084d040600c003b8001375fe3aa6414b90d29810e0b9e92f70abbf28e75b1bdc2693d2dc70ecb87af49c62c3ad8c6fe4627e490af6a8e0b700bd29a6e124d5d9b7fa8f7978a93a7c5beef7968f3fa224038235e7a1aee5e1994618cde9c927a140f338f89719436e9e250d2c871fd2e0db88c6a38f5b38fb5eed1e1aa53507d33673742069f3913d5998beb32e5afd866f46b58f99250840693d2f141186750020dd5dbb903500daafbe2aaafea5ed737e2b1b53a602561da91de6ab8810fa49c1b699105dfa9c353562f01930a135116fb90ae48eaf4ee400e04b0c54ba90b42921a0f9a95420c678c0230e80630a411abe1de1298d7a2882efd27bc5d5699ed7e12d3a8160d2c52a2e813f0ed91e41d59f7ff7c9ca188822c2d81bd4926dfa1632a8e357f6169a7314c7b52e76a9ea3e6b3dcc7347b67be62a18372e85380f7f3c2aaea8bb371e645f371c18bbf169813baaf024465ce4fdaff3d8e7ba7db5\nSHAKE-256: 2da6159c24dea9d9cd98b9bb2de6a02ac832902bb204624e33d6fe03206ac0899871e930f70ca6d0dd9c1b709e62c3598ae77570ebeb393672756e47b6f20d035b7fe86b69087a8e9a6ff905a83efd5760c094fd993b6e707746439625c36d8bea9a3ee5b2ff69f645c505551bb511b7f96898878d3fc555bcc6153e17177fd5150ec6025e22b6b73bb94ebfb578c3110ec9b74d6a9a32e0543b201e7ddffcc41d2784dbc08a4bbafac64015256fe0d2acac9c60058cc3511ed1373d77e8d09e80dcfa510fcf674e56e5bbfdf2bad4909288289c7067aa233553ac6294debaba3bda6a462736cc049d4c9784047eb32d0f36829f4b1ab66c45b70318b89328804e712419a55a3005f38023a863a527d0990f5f00c9ee5078ac2ed3dbbfe6da3d6ff1d9186ad6c7bde61defe85ad28588c84a4cb1382f160069c0598136a66d7ea0e7fdbf3797c96d4f52e3df200b381553f91e6fbc24eb07751bd41d10170cdc2b14ab12d470fd82a66d084e5d54ff22fe414bcf085d6551cf66a6671dcbe1a7fc7ccf6497e21ee2dba9f1d7d17ff812f05592240973837b68f2d8d95680522f764fda3c57bde42b3ec62fdb89647aed1028130a76be8a42757882faebb9f8e3732265ec574d671e6f046bd3802f70b315cb2020b4e9453862b6a2217ea271031af1367a9713d49f73f681ded9ddb9ff32a8a6a1118d1453c131c0d62297d166\n\nInput: aeba8d24c903ca7915df945ad8c8f723357d3f6fcac1899d4c9d134de762da51052f6ce2cc34ce99a225f08876f2c8cc9a336d1abb02f8203160a80d23880d4b5ef1b56ef554189c058cbf3f33798d5fef6412f0faba1e7620588c5be4dcab6f1806f9094d2531a75a57ee398b340a49dbb223ee932951b8b46f18174fdeb0e8143a15c1c09834f2277ba02926946172d09c508569a50b5149557c99c85b3bd907199ef8d2c3df8f3686233c6aa14bb2fa57df32c0e77b689d3aab80ae7c1ae74630911735f3ba2d5f5e2eb66025aa5cbacd49a256929e045910af6bfb3d7bdd102e8260294d7510fa8985853c4a5ad638e69aa645e902f67e697f85b58ca36487c2c7584620757418a39cfd40d4be1070e20b8c4e4979ecf04fa9282f474569521655d7b88fae5a75531df38a4ee30d59a89807e30e99bd02d49e97577ba1d7f03f12cf05685c622854c51e1467d2aec1fd9768b737d4b3479864cd6d2048291736871dc0ef13c8870105c1ea9fcec9637c9ae62709251c47bd4a073bd9722854b9aa1cb721b97817b87485a825e9d8d0a77124efa406453cab6c9bacfd7548dc4ad56b458a1c796d05e428159d06a169292871cae3068f1f4d2ba3b74036166157c92afd6ef5afeace0925bb5b13e57060ae2a8303d8d8486533288901b42940a5c5\nSHA3-256: 4ac7008d9906ed41b2185218f24c8fd3d9a0fc741380ee0039ff052d7aff0902\nSHA3-512: 8ad40fd770d7da8772069bc2c2ed44f715e85948339bcf2dd2a708310b3f0b150990f2fe27c496883d6406d384a94f7d530212012fe1b332e4dfd01eb0b0b89e\nSHAKE-128: 0a3ccbbc987d24b0fa3cc365eccdd4ba35fe9b4fedf37640218619d533c94bfd0609603294d078d8953d5c022ebee8c4bf7a2b02feee80ec8e2247014d4f3c3294fcd767409f9965d2aeb9c2abb8e4dd12670bf76282f6e1f784956b9080ba8dfea9d2099d7067d0751c1ed233bc1c45a092ae8fbf7308fcfa545132a0c6808987a83ba99aea158d72e5315fe7d8e0735b13c9c7df00e6785f8b341c5081c4225bacc0b5cd10d3344af8fea1bc25cce480f0b59826a6cc97a07bfd73015ed6694307c7a511481a8fccf58e694e2d3a0c8dd48fa7f31c89720d52e438accb4ae799af7e276e24e60e93bbbd5e8b7b5306f4c824ecf20e9255f85ae7abfebbeb4e975c250b8cc55f092c80a0788ee4e14ca553d22e3c521a8bf2fe318124ca26bd6ab870c2292b7c1ba2e1282d703fba4e4fbbb834de11d1c7ca172a0455a33fd1fad679d2a519a814c89377ca8accdd709fabf26288242111813815cbc54df14ceaff4c208d276f0c07fa3af4d447df1fd353e5416e5acb66bbe93e4a889c98a77fddeefa7fa1462e5ec5319c97bef63307e10d7c1bb6e2d306f094bca77091ae8d32332860d58b88ccf2086bc712eec1dab1bcb0b50928ea9967dfb48a46ace9237a76cb9b43831bd3be827e4d56d09ec2c014903a8a89181207f663dc24e4b0fc025a0cde4497ffefe5c1695e83a35ff649c3b", + "56e30fe02d970d37cbb78d6c4\nSHAKE-256: c366e8ea62850ff418d3990da96e0e8aceeee05885cab6240ed66d13b410b673b5bc9e0ae320ea01c2bd87688bb0ea7272944af26d9112db77a8a435e6f31000820c0dfd29a85ebb3b92f2b43bb79b2b938597b42d83bf8e92d61e47343374b91902eca1d054930e79ae15c7ab939b339505d9d8ffab1f43ce9ed4426ff7583716159ab0f4fc618c175e2372ca10588c0b6eca5db29942aa7fc3934128625264fbefbc52d19d9919f4ab72cbf1e755469939a3f15bf80b3f0f061c04b6127cc4e6ed76aa6628f41cca91281d17b07e1fce3474a4c8ea6e7b5636689fd63e5b571266a0000b4d7fef5d05f6ca23d52eb4f52170eeb3e7cec492891e8b273d521aa3d2d99913a201dad216382650c74927c863a45180c267e7615aedc1b7bcbefda94cf5a7f36a17d7c1f9205e64cb69614a7be4f6a06c6b1fb1a4d217cb4178b1be70f89609712ac1f50ca396f0b54ed4fddea6ca105c4c9ff4319492b9cec6347ca141ecf39aa639a7ef9cf4b47b253476409e30a3c78a793ab0d87e7d0b6ff0e21b126a14b55957d41778dce4615b1771504ffe34ad88c1cea286deb239454c54109440a85da12054b79bba1198e2f86eca4e4751d409db543a513c5d53afaeb2ca32d12f679a9ac1e2d8948334c47e8e38c951f640d3a10d2274f2b29179588d9f2b497338946f3d8992a191eeca6a4d747e54c0f46d698765f07f4f5a9946\n\nInput: 0473d44b87d10450e16255624312eda73ba0dd45317a77e94cc9bbd51799c557c6221c95f5a35346a7a050bfc8817069b814392946a2e5e2f81e103de1122c02c8fc5e7e713700b3660d93337e6d29a7a53da92d9459d4364578d0eeb4585bf1bed47135ac01993160bc9bfc78f662daa4f7852248b3e9a64bf2af201215adf7a15028960375883879af6842f206aa419e8cc7d070fbfbdc2a4751c880ac7e2084e2aa68d570f33592695f45af53e66f121d2a77af281a4480ba68f510e11c030c97b6b8ffb8b46243b696af5e336607614a70eda2deac4d427a92769cd4b66b3efde13db5bfd5495ee2edaf28b7991e8d6e0cd440d3743a6b66b0e73d1d06e70970d2ddd15f8e23baf17253fdf27b5174700eca757056938a728edcd1ab652ce7b4277afeafe19638a2accef0fdf9c5f1eb8441ddfac7b390464678fbe4b646398ffe7fe1855976bd7f97497f151d4576fa947553fc0869eab75583c88485c831d32c5bc39887ac2f50615dab81733b5fa333cf16113f55df43a53b905b03644e2d5322dd8c1a00d430f316528cad65603490fe6a5312c06d33cc46958fb56621d047cc7c0792e956a1db2c283d710fdf7754871143c678be50477e139ff69f4bf3b14f7c1889e8dac6f5457798e621be2a4a1eba2fa70b00697637765995cb224e6bd2\nSHA3-256: 92847f825dbbcd0a108d88579e10daec823c47436aecb6eb4cfdee12f1911ba8\nSHA3-512: 7a2bafc05a49494fe94c95b8d7f1ba052420247ac0872e3ac4638be4fe0bb32c4729ec2b9e30962ac70bb9b81d7c80ed5c70d4448c6dede24caf8a6f5ff9ce4b\nSHAKE-128: 8eff8182df1d72b749c3a514353941ac1e970d1071f199ce7920680fb97ea21e7c5c222f1721e0af8cc2ccf8f53e79a9826c391671f580f2c438a166b050786c19f592e7461f82705d400872d9f02e816cedb6f21a2b0c251b5e093a694c1fc0f742b96df6ef24d6b7ce443a4c3693c6c552bad2249435427d5bf9ecf876a940eebcdb857be0bdd324dd6304d3e8a6e0d38ef068d05865bbc8d2093695bc563b5ee67ebd4aa57da73a23e32b018ba1eb486dab1a0815c78a09264cb27bfeff7276920084d7f0544171b13c3f8fb72d7e6bc63c0655e5556c5bb1212efb93a259fd562d269b5630fd328c365887c10fa15c3f100eec0a60e8a515471bdc658cd165108f8c021c89cf3c804e17ca57388c5936dc06e58c5e65ee9f577ecbdf3e0fbdf48b03f0b07726f14d0b5d3b1566b09295ce114e29ad50f4c7639b94aaa7da379453ac45cd872fb782c78fa1a2047daffbff864e041c97d5b1f0b27fb685b14100572b8e5bad1253072f928000ca4b58baf5e858753a95a4453b3dacfe4f22fcde1a2a972114afb09f6334945404d230ed994fad0bab55f07ef2e7623c45e4161ad04ecada1e7e9411d99672a74536bca6cf6311855e498fd41d005d354a20836d7576a7e366c34ed531e84e35d8466cc1ea0ee7715b25a2b80afad12a9b6b93baebf71bba00932778d09ed335fe53bf1478cd59cbe328643ba23cdbed9fc9\nSHAKE-256: f06e1e7082ae6e9a87c4ed227a5360a7919973a5f5cfe931eb190fb8a6995652ca2dbb123525fb1f8fc5b11985cdf3579fad61949f991d8ecce71ea99511d889e59c5262fcbf4adbcb2980fe87fb2e64273782d34c1dbb8f07ac513d7f7b08bb13a1922f6f62ca64b08012e89bbe3582615e323e7dc398239662a862c607d0e71dd7f9d3e8b4d481323acc5277ab66541b60009fde285522588fbac6abe7edb3b3e746d13aac141f4e67332abd19ea97569079ead4435b98e4490326b116d87434292ba1926c3d02c47829c8e949e9c130003d9a657abbcf1ffd80fef50f95b6f09bdb82f0c8be1caffa2f77c1fedd951e4880222590feb5755fed551b1b4977c2c353e663bc8773a503ff3e4f6dd7eff9406b46cc56d72543313caa1514511a21aa7beeeefb47e8e6289c43900f808614f39ab2d66312869bf3c360005393c0e1909c6225e1351d92087c7adf676ba13c42f1218a0cff0a8f5838881c8500399b9abc78f9eb918be530e108340c9606c99d1708996a4f9580ca91be9c82ad1b1814c62dff9bb8d6e187198e4aefd56049e56d240ce25dfc63a4e3f0fa7aeaf157f8f1a4bc02ab52a2555c2688acdacfb29e49a97462f9c5f8c81ee272032a99de1a2530e9cc7bb72c4483eb885ab0a1071658699bcafa49d392933d1550274b4175ecd6ea3c6835cd0ce82c9235bcde60b19aab6f3656ce9e46f760e9e9b324\n\nInput: 9fc04a07048c65a4619816326be35244268d362f6acad6cbc0256d9ab4aa09ff1bd390919c16bee0981cc16ea7414d0ed2d8a24cbf6cdd5f41534eee23addbd0686988d2a7faff38197bc9e1067f00270768a2dbaf76e9533487567a7d5d067a1fb4c3dde070bb4d06e34ff9184147aa4b1a777db972df23163ce5ef3e2baf0a43255ac1f5493472ea12186e785c9c4f1b52ebbf49398a6cc1d09615c56c1f19be314ef17cb1255dc3895fca0615f63fe14478c7ef5f37882f5af11925299d5081e58e60a91cd94327ca680dbb8574f4b2284b81af5b6e568681c3d3f54587b5228fc80d448337dd5b5e07ab56382c04d03e15b709d84880396afe5e02f67263412a933a19eae24523f231a6977b2702feafe8a5b51e45ba37e26cda1b21d85f1cab5ae719f971a2a21b21e32f72a4adcdb8f1fa5271aab422fbaecb1cb6bae439abeececa66d59c561a9cc4ec088e523b44336f0ec4ae04f48bd695fa78b69d1cbaac64d24e9306550ee03c52b3dbf201fc490064cb0a0f996f1b3245b3f2550612ca313503dae7e6297c3c43836d8eba978ebe42accd974ada78a47b596780856fd9a242c9bd7a0fc1763eceb328dbed4218979aec58fe3011806480725a76f07277b292a6e5f9e642d02ff5ceeae100564437f923ebdfc3fa74d07e56f4efccb4880c7c\nSHA3-256: 7c66d831914b7a863cc52c3d0bd25396ac9643a57fead237f93e63f9030966bc\nSHA3-512: a210ed0ea54e8f96d28a985a5d1a5b9d6543f57b706c8e6c419b2a32f27b57c6657a430d8a370b6c4fc1f814ce6f6524b4b4113793765e2b9b4f287c8283077d\nSHAKE-128: c5c455900de6ee39a99756b926b1762f96a101acb9602a55901409fabe6d6010d4e2f366365a101fbba90afdd7f6ae837e9ae4557d8ea7f85dc3a18551e952445a37807136783f4201f1d456b61c4760e3ed1df8d6f1d5de2b571269534019a3251658fd898159e6bc55890065fcb3d17c03401babe42357a075caa71083fa817a6ae59ec35bbe6897ff5266f9207856fd7e8872c8ed34f3f72861168919b2f8f82c15704384c968a8104dd7fd567f5b9d06556a81cf676a3f8b56a8eda55c7a8d96351a2a9494d1cc5988b215b8702386beba21c1e11531b98e6ff21ad67b7530f7b4496f700689ef3fb0361bb792483942929deec18abcb7d2a1de761ab027258c44b5a56fd28d24226cb84a04795226b53fc72045f2bd22d5b2b7d6437a2c4a301831f410942877993eca3506aae97690e21fa1da0c3b86e733b31c405cab33fb0f1f635d2a59b71d62b939f32010e011565e0ce6e83350bb17dc0a2ad1a69ec26a62d8ae2968020a984cfc57580946094b7dc8929f5216fc1654b29739478165cb065cd44ad7ccad9db5915d32ef26efa111853f0c256265898ac6536440e1055012f4771d7c3339fa7d188cbc5be4698421cf0df83a2c4d31cc84ed73eb9d7683cd9e79eca1456174a6c6553079bc34ab0e25a28f9be7643d4b36c691617c5461324a5c4b5ecf5559819f10d85bfd6b8c54113c23a640d3c97128ef0c2d\nSHAKE-256: e3492d1862a62fd28703c638442341c4469109276d81d5fc13f765b26b30ed73ae841b2faed11a48742b651e65964315a059bf5c7a5323893b250d9a0acf7247bddb73cc081a73ccb246cbf60a51549392216b046a7c73ecccafec57054f7f455e8bdb360ebcd09b59a7d39cd0594f998849e18e122897491b01f8c6f9497bda3214fac8abf5195664b4566f9a09cb02166c8f5492fb5aa04e78376aaddb8bd3841aa2ca403350c77f8f6b6cf5a5f69493390dc56d7c6ce549f08670f4b0efd405452b870b8135df5af01e00c9644989a83e39d0144cc9b70e1c2be455dc48b65683e55b4f3876c109f851b80092ccc23d5a98be1d1ac91982c25fad7b8403f07d1b9d96dcf3fedd569f2bd8d90cba0372c8ce846a2ae95a56fc979bf59391255959e42b9d52416f4ff2eea67c9589c39f79d3f2a1780426974aa4beab11f75004ad19896ea05853d3b6df417ce8a3d73660f8c421911b2f6d4f1da746a3cf63affd6e347e0cdd3bc4018220193408b7c68fd3f1bb50057b9a5b84223edb5c45d95e94f0eb868f87cb39bc8feef57de6abf6712e6efbb2b202823d53a4b69b02f19ca20744c375c3dc50918225d96c3732726c4f095d0abdcac08d7c3cd2ed1c1c5a1c1835bb2792ad5d5bdddafa0b3af9ad59e7a620f281b0de0135091a1c30b41438762cd788ee13ba19640985cde2e28f6a8d6f19850d9fa41ff754016ff4\n\nInput: 195d73e25d45c48a6a226d9ef7a8832c4997e6670ca350d306cf6174ba993198da0d985b1651db1cf01e2d06f6c727dc0a6841e7377219822d3654018032206bd30b4161e6c603586754d664895097364943f3e58610702f54f015b09f99de3d91e5ab645afca772d8bda8ab484685f0cb639e2d84b4cd55597522e9f00258ae8b01a73bc169e3c7b4c30c694b0df484e2417d9bb53c089f08906e5425ec2029db360ca252918d65a1f60f562c5985108a6e1dab4e765b99d0358a49423c5cdd4daeabc337509e477bc372210e4ea6ac88b9de337dfcf55f8f2d8c423d07a3247497072b00cc513c7688f2b81bc5bd65fe8dcbced9737115cf8733f40c6604b78a15f27c949fdb99a522d1741de7901efb08c815ca6e0c35928c8c2feeeeaf3c1718148dd32cc217ce", + "e422c8d681b5e547b56169ff648a436e94b78f7db8056a7d0e51ef67db368e3c5318652e651a5f09c4526dfff12ca79d1bf72bf413e0ec3e15de88e438f9932c3b6202710414e56d6cf865b39ca6fc4b251874727e2e8e1875dbd4590df601deecd14fb3841dd4d2311b1ed6dac775f43c0ce85aa6099c3e654a4a7505acf6662cf1cb96b4179617d56230e754dfabf5811b58f6e5804e42ec641748066c6b3b227db2d796a83885271281b318e46500701f73fa02e32e9bc31676c8a8\nSHA3-256: fa5a9dd432a8d176b0dcf2d89bdaadcc31387f7e08db879321504d0e4e1c930a\nSHA3-512: c61d4df6539a4c004584b21ad6fe2fe540a4aab3460e4863015b693f71591c79f25d240dab0965ac5591214d14ab4e40a75c2bcbe1a9ca3e590c0c8c3718b1e4\nSHAKE-128: 3581ab15527df1a2912d14427ada7f31ce1f2e006dc6d283f6f6a058eab27a456e0d37ee36c307d9ed5247e02c37338a974de9bfe208e05670eb93012bed8c2d19f2966b5d484a840d68c263bfb075dc1b6f051f3b0825e80251c466497f65405d14fa97270d3fde2c5a5449a60a1c405385304cb42b323bdc06796b36d4082c7584aa7e302d19dfa3ad4f5ad5aa4c08ad58a022d81a1ef6225f11ead51b787dc5a1cf78861a1979731da29021ba649b28b0f9b44ec7b6c124748ccdd78dd064d38b9ad6aadd669d44c142379bee7b86ec4b9a46e316168b0156a4c377779c6e48bde3b77b5525f5243c9250dd7602bc09127a03aebf4d8e0a2ed8aa93e26edc95f7d67fe53aa80f151b697439967778045ac2671c231c408e93e519770ab4e82b98cc999518cf9e78712a0b8664b81faf194fe27d6e0115f4152068304078d5534d3d394ed17be2e284c6c320b340e50effc8b3340c228d6300a221643632332d3e0dde8cea147894239806a8b6f7135d0df551457f99c86b6fb6fff833f8df3898949ff392fb9dfc20c4fe6895a4daa1837e6695bcb7c54f8ad5c0680af27dc46abfb5021b019f40e2c17c904cc16ae442991d70eb3720e19193594c53424d6a2df49d51a12ea8a37f43ff2d7e8aeee58577a0fb83c33ed013e6190c2da5b1b99575b858cce8231f697efb6e36a9dfce380a06838486648673089c642ddd25\nSHAKE-256: 007e33e4acc6ef715fcc507787cc9ba354e9dd0d7e59197c7ebf8e0f5d83ba828b9ece360fddddb44104a995c7b6f8dc54cc8fb37cdf0d4ae5d1f95fa1d785c9726d9d41331073ae6066be726e845654ed412c1691f2b32794fdc1a26f24ccc7b125e8e26d173a1d197569813c7a99ec44e60ee522b3527bb1cc23cbdf879936c18584de78ebad380d66593cd03164fef2fa19ed936c8518142076f1e8d312b3c2702d2861964be690196e0f38f0aeb5fe47c06e751c483e23cd424ddde8fefd65c609d9517a93b012565f8b305c4b2307919691567ba41a19a27273c384055243a02c7d60237760886e54adb84f153c87e903592bf6a5b06ce794f32ce14a7eaa774930e2c7441a579db9eef00ec097dedc8935a08cafd88961f8e2301be396f215b77c06f3036dfa91ad5e5f4604418d353c3fffb2e39c3570de8214d1e844515fe252d39e2b16671d565aec91279c3d89bff0ba10c720d4d57075f741ac564b83b922183982170ac3b8d1b4c74ec98987683a732922e37b7c722c6d719e0db2a6fba17de844f75917be065d5d9cd0a427031166627ff0651edb52fd3f53f21c1cf3f0ac5eb2e34a0c036491a80eafa1971ea4afa55ff897b53a4387bfb8ea0f870500a6ca9e0fb06c4ef675b21d9204455b052622df887a01b4bb166dd03ff66bdbad796b2fe0cd48e049e5c5b2dd89e3478b5b9067c4420c3de890179ed3\n\nInput: 7f69e890580b4066084957d70d053503c658419c49e31125ec3be95e55afcc689f557cf19b4beb7ece0a7edb4790e37a1888801eb5b3cb5479bbbb88bfca174c3fe559cdde9277c36968bb32ed15bd3fc968209740c1c0d1b3d3a454814c91f14f5c592198ee1c70ba63ec919e823a801537f8591e7d806a168bfa65de9b124f9061ffae003bb07cd9c98e22b348b57545ef0d43aafc71c24316d092cf719f38079e0dce6446bf075f1a110ddeb0b86e86fd38acdb2be1a0a030562e15c5c4bd0a122b151bb6a1f48827380550ef220f74e0f820379c6be4819fe272183fadcab8a3a6eaef2bb0730ae11ac0e7690382593740fdf6eba7ead222c476ee4384961eed3f75a8b394da5151b4a923a6a70d296cf41f1a59ef02b2796b5863c6d9c6101591e5adb3b33b1e3a65d3c5ea4c03cf51a2c251631145ebc10557625596907c94160fd4ff606babd731131c77872fca3738d3ae017af237809c467bc2acf518b78c3c36c25173796bcf5a8b4e0fdc8178ceb2db36fdc1aaf8d6d5bf012fb65bbaf4fabc174c78460af3f92f8b0833b6b4c7605b84a3c1208b34de93a99bbece9a4946c9efcf6130aa9cae34a24938f5d94e0ee52b56c0c65a910d798e713c6226ba73b943ecd1bd65cf8907a88d5ec612c5f3dfb8dde648bd146acf64db8b5c9ada3b5b125d\nSHA3-256: 3383ea99ea45979a53440ff476b0dc801dd56c1d47e6cedc017aadc379e0aca9\nSHA3-512: 4de378e4215c6d91c4eab7395b74c9b91967f0b1c09db62bad6cc97ee3dd69ebd2cc73403ee8e05e207ceb76e288055c340c2351c2330ce0d6c36e6631bf1c8d\nSHAKE-128: 2f9f1fdeba81ca8a9ba1d9a853ce30278c6c54b21aa7d9f10113a6a9dfabcd3c7052d74b07a7463b7798c112bfeb87976e269a929feeb44ca6f1c1495ba07ba2eda6ef1d1ea2f5cc90b4721c8e28412b92104db6d465e9d02f6a78902914542024c88075f3e6607224acd1270b7b8f4d303ded37eecfcfbc5a4e21037c23f30de84e45681267f6ec7aab5009bcc3ed3604b5e315b8f08436d97dbd43039b2098a8224fcd59300524d30d16e547d1066e74af19b1cfa2afbe3bc9b4c9302b5ce7519c7ee7acc4f6b2fbf4fabbf009ca0d7e2da3e9f97fac6e83123c0d550fa3e87b588bd20425d0bc2d771edd666ab2a295b4782321c317d2f2b0adeb801dd7d1b5d5b6635d69672f58711ac2f95b719b1c05e031fc0fc261b32d665bc88e15fa074b6b92160fcd28829e2c6756b4699d7d25bffc7a9ae5535db5ef21bfca757b57bc4c4af7bb32b095b18a00b7eba74af0cb85b64777ac86e1e58a2c4b8a2dce9382a4ee2a11e8869a00ae17879dee3580de3d1da46bf33eba1a79dbd579f9b74da02d54c91c9fa20c44c27f4c449d3fc158240a30bb978ed060a0c153917e604c31ffe8dbaba5525f8cf514e0094458b0f724e3253bddabed21cdc3dacca7e04e21a3e270d6f0af2a48db66df7c9e93ff8ce5b1f540a8f26e8cd2a5056c1bb2833878cf0d9605a001c568bef9ed97d0a8bf7df4d30eb441a2ceb1ece475b816\nSHAKE-256: 05ae2864eb1d84bc243b9b07303f786cfc092975df77e71c342b3552b4fbbee16038c55844966415ff522d93c094c7a74ad093e63fb8f747a4b23eaf80be56fe85f38f20ea4b1a9d72e176e501d5ddd893cb69608113bb11e58a949b1db3d14b0087fd5ead9a9e8531272d7a4fc0c88b1373f88aa15a309d45e6559acbdaefe9c237d5689c05ce683923417b8f25babade353fb8bd7c1efea4ae658744f060f7ee635d817df98ebf7ec1ef8f00a9f7e823c8f8b72018de66264cc9395935a2549cbc0709524e563f234d48ff810b2957d30f015da424b47222270448304081924ab672729c333b7b6076bfaed3ff15f7d550fa2f5a6eaab9078bee6cd791d1283bb76d93c5e852078f5958566d8f0a08c92d7ddfdc9ab01ecbc73e920d19fde326836f403fa3830c454427ea5bdb68f07beb62e203d5d51e459d9d112618a2774c5e6a3243b6769fcc98b9e4a833eca1138367ef89af7e1b30d0cd1cdbc822c77c6120380c9be53ca19b48e1f5a2c0182bfbbc9e019dd0ca0a3d4f6cc6f9a82b2fb3cfbb11e9aa5c92d79f4611657912d477de40d184f39d521b474cde739f238e9a8c709c687b8daeaa70d45bc9ca9feb3849f7ed27ca8fbd8b6231a70818b092ab2661b5be5c31c5a3dfb8fac398022d74ebd976277ebcf21a959c7e481e57915a8c79d3c7a9787721218e98303cfd8bee9ef8b483e596922dff47e068489f\n\nInput: 5a50d46b1a16027efe85e9778227f0034cb7eb688db5896870a8cf19d95c42c962ee2f36943d5761a665f2532a8407a38700272abb54d6aaf105364f102fb5b2f90b59be713f2b179c307443985e0c13b13e4eaf6751bdef677924e7f1253cc25784fc09c93046d0d89854280f498797c8e7f9830ad8c3cd6c40c3192e03ee8426db13ac0a9112a5abb5297c3f5f723606abc2e329df978369daaac3e1e69017a04a6980c740ba150f95031c316ade1bf9fb5efb9db5087395aab8387351f826631f77648a0de18f8f13f5ff6f36c422a71b3ac6ad07f252205e981dcea720ff6b90b1b4a53a998b50b28f6a8b6cb66a3e8ad898f839013cf40eb873cd09813de8daf6dcc8ee8076f26b59e61e585f103ae28634d61aa11ac65beb5995bca509ce55021924d166df1cf38484066ac91ec5ca7f994916993e3058fbaa780e92a5a9f49aa0a107f2d84d4c12f277ddb2b0249c7ae666f2938c046fb1ca02c7c8fef3535fcdfff3456192e9b51524d6563b81be9e6b406bca87f49282f71666cacf6c5f72e56fd274f7f5e10caeec7738d2b998834ccf2a50105cd1c2eda8f3befa9d6ddc1129f3b90cc719958b57b798bc7714f2e9a4058fb91381fd27b9423309b158adc1935880a499439a6de102756e5a62c224b1615bdc5353bde6522ddf8a9c5b7ce3057fb57e\nSHA3-256: a6d5fdfc60c037a0e8251eae5c401f14628ce51170797ccab4cf13f530db6d00\nSHA3-512: da1393d798a4edd0456f166da6b054ad588e6b1ad5fcfcc2d8ef5c3cbdad5debec8636ce292a144028f457b3bbb73bfab2d801525a16efe043a9f525e7f58312\nSHAKE-128: d58ee3e6c1229a6c8bcb32d01c5a876bf5df62341edda962a2fde26554103a8787374d6e04a21d28453042d58db0f8a7134bb954838db71d3c24370500d2eefa0de21800357d82031ed405a938b037f4c496168bf76f6dd4e485a8992c0aeb64ac3ec5939ffe4d9fb307cf6e8041feb2be0ae0fc7ccff5c0063c1aa0a40c7d755e92171279df4e1acf1236d6e82b39d224e262e81d4f35aa8133f4c17e0854be76d63728ee40aba5c8b7936bf3147cdde7c09258ad2f8806a63d5e7283e669e9a6b20708272038b52b8928e195703a390c4fbbb39f4454bf237c0231b091724da7ef31cffdf70ba66e2dc2c54e92882775003a62591116391eaf99aa0c40c2c65a79827a42bce775ceb46c7c40630b9c1c6275626631aa7ddac83531ff67e614fb88c95338b8aeb041324601d0e280d50ae739f37545a2148697524da4e939b3c644a17e2563e4403e6bebb3c452bbda8d7d7bad4289797a2a7bddf07726592fa93e4bc27c756f39eb3a036a023741e8809ab96acfd6e988af3af6da0cbca69b08247b2c02f35809b74ec94b0f0068918ef955ee1b2a2b74f58b3de20ca4a0f8bb2d85e803b95f63fe1e8f57639bcfc2f4ac86f9cef34620c410bc0a9b31c28551c7ed4c2a6002287b34d789cbff8fef5451be3ac930bc2e07687577a0fe4860135e186f0575bcf3732c0b40532ee358358c57378f102c52ce822a69e371c9d8\nSHAKE-256: 40aef5f901ad", + "ea15115ed69537122f493a372a6b5b33c041548bee53e12f0858af90a9a1b28a6ea767575038a40e07fc35a2f220e53a1d260d7d56ee5fc64c0e9c05fc42410434a1c0812b8d1105f10149b6da2830afcdb7472b9770849e9a606a6f1f22ce750ebfa0c6745e2b7bd6a5106b41df3ff7825068e663f26cf28eb9c739bdf18cd534fe3d44a5362689c7b09ceb21dbaf9652a49e93f47a48019ce42af3eed4125f151733431fe1499e7118dd95d7b57493a83d66f9c827b3ae484c1fd5ba3af7042631ccd785a5ae313f129e5ff6b011c4024a6104820528d60dd1bf9d9ae3f3f64165c80a375610ed7264c390bac7b97902d3ddc35c89284cefa23ed21a1cbb5991f95aa89f1257a7e037d80f10ef32ff45680acc5749cc9bf55a22c346d99a7c528fd206fcf68826b569c740d47a0033b44e8a63df685f3d3a84cb000973c4770b8dab6fbfd981665b9eb5d8eee43bd482310e8f60bc30c1ff578c4178a51848c568a1c97b911cd89c0f4d9812175f77756533a11e6d4d6c15ed0192822b423e3b94f98b0a5d7be514473fc0227493a2269add03f530ccdf314a12b478c8cc6e5f14a3da2a15fe5bda85fee8594472c0478fa007a2d4e199f619bec484e2b8ddd18376dc7107ec0842025b73589ad171914a5dd396fe6d03a4fd6a24fe696dcaf43c1f7deaf9f3f7392058b602efe0a8adfa37dbec92385b2f05\n\nInput: 8a5832b140a0b4f9e16187431277e4bf655a7b1965840bc640af05baeb217d01f06d1754c24d988da25d4cd2b85ccc3d8a3b999fdd1262ce70cbe99d92b120446370b42874a549470ba2fc9bcfe1f8dc607ce72aa48ea094e17f5554f909941e55d76bac6bd09a1e32aef0143077394d880d6ea04a1569aea30054ba6cd722e14aceb121ddf0faeea9dc994db6e390e5b34f4170c76504310911d40de4707b16c016a7b41bc6a070524b205381355f872528e4b3a5789e446aa3e885903b39eae839d1988a452a39f0c6aef7e977db2f20e62ca70bc4c35c76d3b19a9e708d139477f2cb462cba4c1857a232472afd209f9ad26c16a475daf79b40318fbc178d77c2131928daef168e2298729c89c72a55a2a0041951d2dc115db4cc8f7a954c547fdae0db6da2819d472fa9d5a3c8605116eac775a62a5d4d1d7eda8056cf6d5b2778fe8e0e8006181761c249d62b1c8fa01543e4c09fb5f7b0a92f90a7178d627d3223e67a86acb9798e866c8ceaa1a80970dc0304f733ef5b10cfe4ba6b5b3ae8bbbba1cc417c4df85ec3e5296ce2d6b7a33f050da72602ff7d5a5cc5f76d040b7cc4ed3b5aa656bcf0e712dee027f57a37b1ece91dbbe6e933418941f3ca56743f061fb1d2b369f1bfefa7a94cc6bb628a651079e2e84b502ad3b1fd2a7cd26d8e04c83224994a\nSHA3-256: ac68c97c2a33bcd2321ca540a4334ebaf75797b1e1ffe44e9d7c0df0e93caacd\nSHA3-512: 2ad65c80ff36b61007e2bfbc158bd4074e2ece850b8564f0d83e184df93a31948bbf66e67a1a77bf56b9b272ce8b9e3151fc138275c9c861578ea5753b75bbf1\nSHAKE-128: cdf93e66a56665e61e899a8730d632784539a587a7609675c2d86445b4ebc5509c380a1ba1247834f59119420df7dfd405a53a48bd6d928158f70a67222f6c0262e16faf25ad813ce9ab81711c1df5697fbcdfaad834f0f81fbe915830ad7ef1c7e5c67a1bca8ee0e4478699a8cb89428e183cd655d0b8b2baac0920b6d20bac028a7cab2751e94288ea7f433b286717096fd277e23c44b2205551b21c583ef2ce41012df93445cabbd5b97bb0f40b37d33e1837a73c2aa9aeaa801e114eba466c9d0be67742b53d0b015e840cbca74427e9e22490a2ca0132e578a25a113028628e6c818dd7cff3f47fc81055a431613d978e2257ab1be5032c67d20ca1a7d53830041a7b5058678f7be3e18e10664bc7715f01d09eeb688a5f6d2dac013f636ff09e6c281f2b5877687c3161c0f23da3b5b69d591b6b16303930953d79c3650b6d12d6f52285918e83d2de6a01f6edbda58cbe97b6b362ad119f8023ac3a29abaa230b4f608f3d2fdd511c14e1042ff2633cfbe0be8205618f4f56f872ff49650de7d99cde36c1eac6db82d41ed5ae9cb24f5065a0338b80bba1100cd6e4147dc1c59e0fec7a563681ee94f0f282db8024539b2a3e56850be7b9c072c9bf1d5dbbe1108e0506c49d06cdacf2420366ce69e4b877d8f9c4d5a1df49eaf43736714f70e972411a305233e955a936572de8f35856ebe898c3ce2a5afebbebdb82\nSHAKE-256: 325dc516738feb5036e51f5d38da498ceb01c94286a79b18c0d25b23cabe37a7387b6a5777457ffc552771a54e0e4a92b431174a5b72878357aa2efae7d18b66b5a65cf4f1c67a2e3a402c57b52147e72b35e405e9f3a45650d6acee8a7e22b40cf35b1712b14fc3fe0a1e8fd212dd6375eb9b198559fee2930b665166b4cd467134218b6e8ae309258099ec82f31a06b96820176ac107965c499ca47a42f1cfba33eb3dd21618b6168c4745ad5cfe753990f50d41202fd2187a221e6642ff9eab167326a2326941de85085f9aec347d963f7c529219b4a4aaba96ccda1e95d9a18210d031fbf7502301099134cb8d0e17c10391e3421b0eac44eaf0d51009dbdaaadfe4f96292ab616679ea488c2a21aae8650138795646557a46d451f724e864898b3038e5ea7717b8ea2ac5bfecbd809c8a5da871172602bc96afca7225665e8f948a5f2ac431d4dd3501ef05b3fff73e5079b4917608e7f4201dc85ac38331c11d78ff6456441330e6e5206cfa7796f5381d46d812f3851bea398b2b4523b2dc6d051f5a1bf4d6a97574c2bf076a5bca356fb94a1ff47f5b18ff6b42f85c70da9b25a8ade373a46bd2af4577d47944a01452ecd65d84f1131a9cd9e0304d22176283057eddd42d576fa4769929b37c695c5fe045fe8857d43dfb24c1d7807a487751fe89d0def5418fff3a8801c3d1cb720b6c33af92cc05ba38ef68b88a\n\nInput: 4d764821b45265a1d2cdc821e8bbc17ea9594281430d8b400652384dba2b6d91bf1e4b4e527fb3e76c714f41c91d34c2f3358c81b75e87244a05ae0fe6de5c6dbcb015a45578582b1e1cb225e920b3aac2a8f334c0125eb945bc36757cad0ff47c6e932fb0491d4f4811136b6ca38a6d5f8d276b4f523c12c4b4c0fa2d5acf1a38c4aadd69efd9168cee911278abb9c7be76faa83b6589a35ddee26569ce12c54ad8e86f6d2ad2e06b6fbdfbd343a0ddcbbb3b12e2063814f3a18f8244d1cfca80c78c48a9715c11b25eafc90d4022520d798fb25649585efca51c5639353508059719309ff2ef28135d00931b7059f31563d798100f9504a263d9743ec7757b70b5edb3e2c2ff5669e29dd670f4ba1234be8077183ee6909571af06cfeed84e508bb6d8c9f46330894eeb353f5ce5ab6e8dcb9c3bd5be1ef33953283fb0a7c7c6829d73e90c7f6c0d9e830adb9058830166913d32feb7a156258331659a0dc03ce5c22cb954036099c944132d7611a67df1e61ffd53bb581b4b1307c3846e238584f122893711b028d92897d43bb5cc8c34d558e49fc53cbb013dc9443cc2c8b9f858d70a65ee2c0603e1576d79c17cc6e00dbf20f5efe3333fe611a5bd94761837ed763f9a8f1165b4ae4127cf79ea6522359b06233cefa46d79f7735be0c5134df34bd04d2b535ef5\nSHA3-256: 949d2beba17b67f17643ed62a3fe9cb7d16d45f533a7caa5e5b6c60b943d5d8c\nSHA3-512: a987f642449a1c666202e4ea7e799f3ca657dfbbe2d310519ff300f04c62d2d796b69d4d3930fad15e4d1ba240d58f5cab9551e592cd48c3b3571ddbf65f4c28\nSHAKE-128: 1c5fdaf827897f33e600502555071e7f4513567d8fbbbd8e0c989dfbcf8314cefcaae1164c9e0b1d57aab3c56aea11178d0f4a3026c614ba8d938734bba8bd43300af05b370294cd46752fb8bf4ade52b60fcf92ec7aea7efba09ccdef8fa849383665207fb01de3d853044f0fd942692d6c51aa11c932240d680618065eb9cd4db7fd46e97f13e75af787df8729650aa183251cf1da89d283e56814cdd0d9b036af7319439d66dc568a3910254d3927610c14c92ad8fccaa5cc6171c24d2957e7fdf8c357f92614098298d3ea541ffc3b0a67e2a126d3625ef9f3ac56d75cccd151f5fc6d15a489c7105010475178093b82a40ae6a7d08057d567f87afab53a24c0d1f5789f41f29b841d7c42b6ec158ec8494c056d5214100684879a5ecf15ee09fda6f05b640c3640902688061a38608084d6731c6ad979c1c41c61a20a40b0cf6076490fca9f0605bbffc0e40e36c5172d69b79a5c4da1e8b7e6b09a142334318177447546df26f0c3ea65810c73f5e2efdfc00f1af8797fbb5f423caf100d7c93e54917c1a2ff8b88999a673c3774f703c53d86bb1d0e2ad578ddbb385d329e5e6b2ed23db161651272f79347daf2529667af869fa8e2d0333ad9306e7c8c5b013918fbc97236d47522a36dfd4ff01a80bc82c3ca613246d3e712a44f59bce3a562028a4dd57ed1d6be72a7cb365ee250d83322c1fdd43f7a26058b152b\nSHAKE-256: 54bf4c4cb0bb89a8aaf0275fac735252c1f456c81d128127ced9f03ee0d2b612f317cd6343a7c18104a6ca59ce2388077a8ac1a09c8aa01d9e5dfe37ce0b3967d945edd63a976c503aec34cd12b2ca33909af211d114a86a3bbaab14c9a702262f31eb41428b68666305e66e59ecf930135c50836199392a1bfcec83a97409d34ae347161ffa6eb2282f2e53799568957018c7b7b1aec268601fb3f28a145fedfe8903c670c8ce17d56a7af0d97629c11f55df1d4e813473a86270d40c3e66bc038cd3a0af4af01e57561bbc096b8e91b0138706af8e8f6be33a2b6c19d95f691d806d4884894daf811346a4995f3720e010cf9a0aecbc66d260984a7dbd2d4e83796f75f691ed8f95c9342e39b906fa54744c566b4c7bd9a905ff3231d48c702db715737f8a073253fcadd92882c7e1e0607c6e743d93c514a1245be9ebe76cdcc4f7475c4cadb389e043c9184a87d8573dd291dfd18b743a73de225d4798b620462de14ad99384620148205e1248a7a09c4f2dc24c485689dde826fd0d39d5491164aa3146b29a3c275e3b7d55ff32e9e31afee49f1a5136afb24bde581926d31a030105b7f7aca58d00b847362fdc9025ae367fc439b7cfcc0e8cdf1f5d377a7b295ecaa6b33dda5a555f0fee77abf2d9c828b37edfc3877a007836594505f84bc075343cfe2e055b97e4160454f324c9431901d780cb3e4b33d96fe04803\n\nInput: 4885a9ac08a9c5d3f089f9b55e350ca3e6e44207eeeabe16a83496da7e5ec640b0b671959b24beb855997f5148646404894e87edcdeabca90c79d110212d99e260a298d4e7e778f2a932eb5246622110cd6cdb6cc85161c120512766d6e32a38950dcc84035fb92665f8c0f217c42fbf680438c225071091437c3932c7f551465e37774e70afd7cbcd9a1ac05581df96bc939233ed027fe1e428591c78223d292325a0d17ae2094c72dc443353991a7760952ad4a19b7195c847918e2cc0d3d4fef21b4fe5dfe1e96f3e7f0bd96833edd5a88fdc74ec2040a3c28be4359248f44317caf9cdba34273376774feb42ede9335ecdd4023a8e21b4e571a60a1d505b00bf74d983980430a737cd7c485689b82a7e16983eb90176861357ac44a3591cf0494cb5eca095e8ad86eca2ca9873972f4e17f9a4a1285", + "e337ee529a28785808c6ba4837d306ac194b95efa3c5a4ace64abdee18e6971d838eae8bc3e949ce8465317471be8f968d6cf725b151826f606070e68bc649926995814093ac991e6278b07f9b398da4a3e9cd0b322ed698ea53aeabe36794a14fd5664551afba1ac3cf6716171d7d05ad7e7b92320ffa6d5abd96bc3c1f437f006fd103c620aa01bbc0cb3baa49201ff1aed515b9096c1cdcccaa28a02b107cde08ea659f7ceb8e31f6f54031c71139fce4ce6\nSHA3-256: 999a61642bf1df03511445233e02dd1e866d2e09aed23a633f10369dd803dc93\nSHA3-512: c72699d962d7dfaafe0446cdacd21724ecf262dd1ce84b503eb09c9278ee72acbf605d6044014b29bee7b47415a143a90155a549fc22d9507647673b0fe7adf2\nSHAKE-128: 0ab92e2c6e0f1a32c99b652fc061757c6cdbcfc3eee9544fcb9f60b0d2b41436c0b7c2215da80881cd08f146456abbbef106de4e93057b9b46a2e1e60ac09ab9b04b04aa54428d710a04ea836f2d302cde80592ed9db9fcfb71584b163d20df8c33cf42fc80f1c456fe0197a22147a80f01ad5a5b2e9c4995325388704e1b888132ec40286d859046155d1d2414c05c9e4e30f1c1aa72551d6810d4f4b92acf352edc50f27b23a79d59b7e88b4fa8d2f038051cccbb36e9e52632d78567e7f102387b23ef0ded677d9858cc53e634296a1d3628e0edee6390a40bbc2a3df2ae96c89f45d61a9d0124df93d0a16e8d16a27df40a0eee37edd3b78aa9b780035fdb0e59c863444200ea53c3c92f130c9b88311b02243c5bd520273ed07072acf2b7b09bd302d6e85c41528dce2da011229943e09237a76b4495c1cbd499cf9691e3696aeacbe686340181265b894b82445eea7e146d8696da89c2740957af901226d34b04841d9bef9a8966fc023771da9daf793a73bf9801f92f7c88d4485b512c1c44fef1e529d86db1384e3318df32348b781fa3c39878f2e1d53ebb009b28aca2ac8f58cb8974059572feab389ca0583603640e48be659208095da0a4725ba34b69a3a13914263903247fa3720992877385b1a03f11de0c683839a2dd64b51ac2165dd746259fafdfd552dcd4782968abed092c6a3df8f866b148918ccdc5f\nSHAKE-256: bf8f991bd25c67ce1a338d9f5a992ec2f75570f057ccaaad365030e6a585f5a54021a4aaa8ca34c8a3dad353b78cd6780534f06720016761158924c422edce93286967c003f117ce4801e8ec3aa94250e6812b04954c70ecbcf7d60b90ea631c93588d9fd8c7fd7d163a64b42d88c58248a60c52cf37901ccea4af669034096534e10dddc978d2bd5cfcdb02dee3ec943765a28ad6776b38b7246485b0a2f575adacfe74e8198bbbe0dcb9933b2fb9b4cc83386be5b0430bd69b9d65e7872481232a7a3715499d07e14d34cf5814508258b13eb386f57c7ea4c94f04f1e19e9d7a62135cd6955ea1d89c2c9457c15358630f43c092ea19e9886698cac59e38a054d188c1545492e0626064df3dc0a167380309346045e417f563628e63cda6f3c5948dabfefd2ef597e9d7a4f5dea2a6dc915247baf76ae4fdd91521490c48a45bd67f1224a99a7afe2d880c8e3d98dd6796f2912439b7175aabd18192424998e5831c661cfb4567559de5e0a47ff6cd18e306c57a026189fbd4e5122b9a2db3a279ba3900aabed4f660c9c722883e205fb7590dafc5f50b3788a414e825e9a12bb630843d6a247597829e227bb6c6dbc16652678fe7ac033a29ebdf35a5aa9e4194dc945b316d6c53850c500ed86b757d4d327b7eab12519ee89634d26a0c0cfeb677966683224d8b2edb0828bfd317045fcdcb2034f28391f62faa8e28ea4c\n\nInput: 23ec41c5e5ffc5a5ee4d7150f9e38763b007f7216c527462f89b81964241d55e78a17ad6b5c522a5de9050944353ae6f7ed70428f86f52fc0a0f285231f5e95e4daf93b31c2fdd71cccb649bed14ca36b7a07643142f4280082ec296f8cb1f7f55ce476896ad8422499b5572462c35c0fb9e2c66bf3a90b7f4ef6c1ae61bd738ede61aa4d78b38b22f230d9987a1be7b3ec7c4317759a244eb2b0ccd4d47daf746881f64fff748bc18fcd85976b7608d574f54aa9674bb8ba43a96fb78bdea09dba871366e5419805bdfa6e7ba969464c57e4bc40afb408d300aaa33f890190b7ec33207973198054700a65cfa2175ab878c61bdc3ff19c103481cf814c70c4c25a14355c3bc8891efd557bd8b5c20685c86cfb8a43f2a68c6b6dd1a6f0f18ad708cff3113c38a78a1a0c9f0cb7e9a5320e4ed6cbc07c9d9c32f65b20a169ba8b217562b47db42f08d0a286e376aca5fcb4a6b125e129aeb5e9f210b5307fe819d9434e46f02d916467373edd2be2c33f73275d8d8bc0a5bccdbee633272c7150af3fb8ff1a35081370b5b83ce285bd229b1d38b6018ce1e7f0ef8302e007c16289f5f98d1abc77112be69a3c0c191496393e0bb33d417e4a01804e41a359f50e19842e650ef01a36393e4a33481b8dd6397e4dedeffcb259d8297cebc2247e959be7cb63a3ae71cfb6fde83\nSHA3-256: 22240d5a5104d8a5a87d0d9a4e99ae19c3a8a7220544dbca32d4140004d966a3\nSHA3-512: 5786f7a0ff1d2c988a4e766538a1241b4ee94cedbd6ee576ace0c507edbe0b284e8d20ff547edf1a7d73165000fbf2b140925d812ccc39fd6663041b59ddcc7c\nSHAKE-128: cc7db292a3d7692de8d2094172e4cdb4369c4c69baca3c0d810a705e00ee309c7b544d63e01652663b2cea5301715e53962511125cc43062dd8f354f231c3b96778e7545516c68794952d9403b20e85d9e5b588e9d59b898de7b0af24c71323f7570f83596bb4e865dd74790db3cbf154a2db396d3c5dc6db59f6e54355b333cfad65280201ee8c085462b7c0fda0e557edc801ee3de192db70ae6fbb098fd71bdca71aedcf9f945536968862cede646ce9929cc47382f08801956871bfe4f7a4318c43d16218097ea00cb52a3e236c8299e4f6c1623ad878454af1e8fd8cee926b812c79b5ff7a1e5dfda80f788921264ceeff4a82f5a4a88183ff5d3c6575e5845062ba91f62c13948e4fb418f67e2ed38ef7dfef118e8cb1d7043aa3a589accb6b12b0d08be63377a133e9c14fb5acc7b8f8e301c409dcb7b39f04584a11f69c415e8ce03253565dde95371aa628490fdfc16d31fdc232fac46595d45887249339b322faca0621fe071dde3d09644d6117b6f4101eb9f6cc7baa86e9dc00fe5e41a632740ac3e0427d1308a8358f3fa90bb1f26144483d61f5dc54c44d39181b3ab3ecdb5ac64adfa9dbbb5f0531405492995e489de675f176bc4b801f9dcae9b3fefe067162e45c1e71a9b6ff929273b9ae5b254d137ec2f58a9b0e3be12d82b175f500f66b6aea185affbe9107783bfde009fb680b1fcba52434b7de941\nSHAKE-256: 748236d04f3f2b362769624c4487b786e584cb1eacbd8b6eae352778a2b01211f0e7c6dde7fc86fe74225e863f7a9be872797418c4359e4712431a9c09caf146059aa0f2ab5626e18e255cf93e3a34b77571328fdcbda20b4c0b81aa4b7d35aad8018d10e730685d33793f5d0fa62d3da1bc3310880054d4ef36732f8dc13b7e765a812dbde59a8d6bd4cd275265f5d802966d2177b555a610706b4b261c2c76005612cec244a52562059e3533d0536b49051626cde31262d9fb27941bb985a8372fe011dfe6a3f88c9bf0d8b732c139ecd9446bccfa0c2b3745438079ffc5f997578899e0bf364574b486c8d327d14eddc05954d3b158fdfa67769907fab6e2282acd5a936bb1ab74ae3123f5a73e4cf9eef10b4bb6f96b971d02be9194d087928fbf1ee6845376bcca257cbbcb92b33e83e769772f8c446759c1fbc4a0bda3cf2dc818de9d41d5e8efaf8313a28d4b7d60ddfe2df2cfc5414de608ce4b6fd3b3f2e881889dcc7f2927f568c1e655a41c3c800a2d4c1ba85a79c2ed9f06583f58d8e14414da4af2a0c7141575ac83e6c9fe865c4fde899627212424a2ec76a87b9dcc4323aac400539bfd72b10e8c979ae897f9b6c817437ee3d387c79f1c4445a37209e81ae42ce88b04e8295b99a55b8a40cbc735f8661eed7273c8c5cf494f91f105128ae2f9f6e573519365496e442c86a6adce8c9d5cd72ff621cc5e2d\n\nInput: 151c273dcde140224b47bd9aba66db7db5be99b261e30506970922d9b9bf8a35c3a142cd76b31bf2bd0081e2600f0dc01b0fd25df18004d680de5f963d2f59074a49313f310abcecf216ecae0384ab97188cea4f5d5a6015bc020b2574ee21848d574a3078493b19633c657105cf354065ee3d9302292bd6097f740516de65165c5e057dc8dc57a327444bcbce4098b7c3b88415bdb82806987c9de9145808ab2468d323bdf4f38bcf8ef0a259f9fc9553455e910d988e0694fdd65cefdc2c2ea79b6d6f734f0b68c049e41926682fa423075a339ea0ef5cb619ba5b22afda01d93caeace7410ab64e87ac7c7f3ee866b97fc0b89a3680adf77a2bd41bf0456d8a99ed666ffa2fda5657451387846dd777dd0e5489d309d7ee6631c8aa3356a19afa1d10e59e47bdcea001920576b1f9a8afa69dac1a2afd6b4a3ebffbd9954f4842d80d9209900aa841bf0453bb5b04e54812743c311305488c43758704a2eb2fdd8d7175f05b56cf38a2366e9e4a3734c3c0cb6c11bfea681c505d3e9222f07ef8ec306e02665fdbafa4fc6290f91cf18e2d1ce24d9d52376e9fa653c9c4c96550ee985408050719236c9aa32e76977282060a7769b92938cdf46508d875286dab65a270adc7a6fc06d7cc2da50b8c80c9ef03ef606d65acbad80b883e3e49d0b8c2479045211d93f54e2c27\nSHA3-256: ac3b241f1c4418393c1664e533ffd4eb09dfcc471dec3349f596329d5f4c5f18\nSHA3-512: 2f0318f0a43a0033efa0a8d274bcd7063c4c163fa2e421ee207f18fe001bb72d878265eb24e401d6902b58ed06d37f7801019dd0a5e48110dc22f721d9883348\nSHAKE-128: 53e1ae887fd4533ebade5b227a26d3fe2477a30063f3a2e3f84c948f08026433c8deefb9377179834a68366043403241e43779a13010cee2eb8d244163e889f71733c72759841e0a77f67b0a3f5bec4d1c66be7cbbf6d2fca7f43044ebaee5ce2762a46d172bea460c64026cb47ddf689dad38a94c4b6ae3fa4ce47bed3b1ce2d5ae62337a9d14f3301ea1262ae5b38ce27ec29e9b4812073fffae3109ac25723da5a401a08552654f4f818f781f600b7151da8685233b7bb637b9ad9823d179f28735ee5a5f39c959933b393aae3d808d38330d2133bca4c32330efbdaf16e46732d54d87b3e2d01c0b3abd95b51545e273b2e262a371f55170d2e953732e3b0662bb4c594f1ccee9102c1ce322626fd1f592026c42b514e8bb25649d6a5c13d564f3ef1fe72069b73804e80f2d9d925e0ab58897a7ebf84e1007b200f620e427813c3adbdd499f04d374bbe33ec918d82e648c19ef012c3c0938269cc6430b7dad864a1f6f24bc36693fd82ac6004fa5487f4f732bd5c103a652bcf825f732d84bfca58c4116c426b6da9a4d768ba1b5b537084874b3183ece9688d5e7e6990d2020c1165e789f89626a84aaf57a4dc1c297020e09b6b7cc1f7e49f8b4dedcea9cbd525e6b042b7ce39ce2d37297f6d4a10ca80db9aef1259f6a3186d7a46c2a1bf2d7ced78da80543925369c6a96d4de7019990c21fd69d3b9b58eb713707\nSHAKE-256: 3d1b0023614", + "5b77fd516ae0f045b66981ea1eeb1ff24f0d89126624f78e92c3e00c6d40dd0c7cfaef3a08f98b432d7a43e784ec289012015908484477383630bf12ee05701f3137acca3a2e0fa24dc3e5b3db0d54460b480cc5a339068c06ee978b150c73e2432ee8e9e76ab71b8ac7c5c562e4c2d7a1ba28d1b6e882cdbbbb2e013eeded0104cff2f58da9f523efee2d5a9c34d3f57757a49553080fcd67934f501c9623114a6ea005a7ad0216e5509d97dfe88351b1a8cc15bfcd65af521e17108de786726152c478c08c15844654bcf38b2f96e60519de368090a07215805040aef0fbb74358799bed00f428f30d9aa770fd760070e8f6859d4af3ab0f11cdc608d761e04628e402b873ee6fdab7cdd55168933fa7a5219d8fa62532c0ff7e3f89c336d8cb26338d818276bccb4b7d2da34cc438462887210c4b88dbeadc70dbf4c7423925309ab0fc3109a885ea3c8fafe4d6891ea44824862102f206deb6867f3e89a93712363d3aadcbb5c5ecc58bbb5692f001ce434a84df1b2ac748abaf17eb64dd50e16898deced602afda1bbbe89e1d4b8637e232dcd7791d17bae13d73fbb42d657320551fe1470c5d267558833580cc6d6b7010c52ebb7195dd790bb8de4ea91a2b7e63f90117a21162da7a924c9311e67292ef763b6526f5586c96d367d6c95b1edd8cc7e50a456fa8ad5d6ed0626b3cdb360ee7809e72e433f\n\nInput: d837f35aa29b5d29d2696b1eefb39d441f81103ea4a7cc3133b50b96fa6bc33360bb2e4b02525c63fe614aa4b44c1c9120e1770833af0ae442d4bab0567f0c34c8fc0b32d71eec0b4e925dba8df9c310b86a16c449b3776cde4e42e928242e8b945df4bc513a91c83d7c97e64a2e833b20bf534f4aa49a92d3d7c373756f9dde47312e4ba1d0f83c1b18149c5c1cfa5ab0e72d88a7e3ce61c411d48f4e1d1be22b13d42dbef018e633c02c0f8c251b3aecc59de13bc329a8c377590599ca986b87c70783f7e1bdbcaa4d05269ad6daf10422211a9babdd0d26d0144a00c50f2cbdfa9bc5fb3573c3b9b80cdabe25df84d9f923b612c16c412ffb5bd3b5ed667bde177ec9a2c6df066ec48447dd01bef2d2fea693f67b7150b91d9a46c3f97a00f4b9230466079bc876256fdcaba7a208cf2eac2573d366a24ce151ca0845635e1407f289744df564c8ffca7a96c5162f973176da11147265862aa179b2ca34d18287d9c6d2f1156da6a8048838370047e9db697cfbdc96bb739487b706c835e5f88a3e3be301c662f8cb08277e5e676c377421e132066ce855d9b89185a7803c55a2f152e349d211d4c831970fc44897bf2bc5d66bb93361588e8e8ea176d0dd3ab422b5bfde43161c5d777d5304f4329aa1bf9ce9e1cd3085eabd26af0bb66beb32a910c4850000ca365e046704\nSHA3-256: bb703f84a7bb4eeed9bc15d9ace7a408042c34476c32cabd3fa11f3e53d80799\nSHA3-512: 37f01652957316a4165e5899d21eec034a5ba772f18da009b81fee5a1d742995bfda878b8197ecba4816b598a8a06e034766b0051b558504e6a6fdaffc753ada\nSHAKE-128: e230b219642791b5c6188be2bf4a9fad9c357a64869d1157d7973793b98501d8b14079118bf4cc7787828512f5218234d2207c2c58e708631780eb03d0f2fd1a8b5d8b8ad26bbb66793a89fad1e6827eb72524f841214c43e192ac91e0cb4007574356fe864cc383545b9eed4d9ee99007ea0b9f6de7495a7a4270130b7b4994231a1c6bd03df8e2537bb7be8ea89c461af0147b872cb3295118dc215218eaaf4f3c482a1dba0878c7301439181adfac5c0de5e3c1674cb3364e640db0921e1a926002ddd5e3713ca1b60297bd68811549e25625ad98a5af5b1eb9c7c7b8b7529811d874a6cf0a20f9398e2d2bf60bf9335dd734424c43f6d4568c2697a53ac2a48ae3d7aa9b154feead9e9b47b64695937985531e48acbf2688d7e78f6f15fd7ee7f9c369955495695f3f4d9122068a9cd5bf99ef9252398beeb35de7b58875656d271adf2eac0fc021ed1eb15bc0dc2609f497939ca459d53a49e9c7d4bd533ffeac5b041ac513de97c06c462fcb534d1b5daad6432c005b9620a6d859636b43a071862a96d808b6f35909bde4fe445028306d626fee9649de6fc56b77410907d530722336c659274b01a1a520bf9da4de9e1e36b395d3f25ace1091f8f9c5232dd4ed1404139a8bdb8a23226cbb0e080f56df21bf82bc023149c04d0def8ae97fe96515d821cef2f63b34f135c1c4da74f35c0cef932eb6ce4e152b24587e\nSHAKE-256: 9b943f24d6804fe5cedcb0628ad40c4ed5d0da5e4fd2895d82a3762c65e84bd5f8620711861a46252b8873bb09c35bcd1cdcbd5ac0634e29cf3169dc948061d86969ecf3ec8231655c8ad0d029a9660b7040b94d355e2aa83a4093b6534b7bd6bfd66a9b22ccb57a6ff72422c0de5b9489af20d5ce0502469ae8ea2d6ff86903f4bc5b85fda8396286ed9cd870b4b1668cfba24fe693b1d87d2149a89c4087a81797b25901966b1fa2f76b1f5bdae0309b294e0090c45aaf7974d0159858393ba870d70ab65544246f8ab6e9c8cb59f1ae954306998156ee4abde4854a2b938122d34ba0e3caa4753f73b0c9b0de3cda80960b1e1c91a47eb5fceb8b78713cdb96a8da99aa4375378f9bc58eb1ef4962ec74bfbe7f89a64496d30f42f5b078e048606e84f3d58c3a3e8b027ce76c30c1f94da232c04f6f5d3a5e29ea302d330407060c3d5ba920c9a68aabaa3c4375a4a578c88974eeee1278175e555c8a71f5b807fa5d6784043359f27e418d882bacca03e79a3311cce3c8ff2b5cd2bd98ceb5b5de2ab87ecdf150f87266ac71c29e058d078749057fea88e6dfb8fa22693aad82d267711e8abb1cc3452e2437c7d79b75c0ac082b34040671da7b0a9274465c18d2c3414fac6e8483751c54cc3c08cf60a75fe0ae1dc447a1e3d7b020dbc2742ad8eac592903d7a7442b036c3efd211f97d06ffe983ffd5b59b66f03ad6b5\n\nInput: c903acc9c8e70f62d031db284ed6b52e4de1eff957e4493715f77c4cce415f8799a50d91a82e57aaddbefa599b007b2b9de9f68e77f537dbc194d0fc8e65a7b4fbba4f1a248ec927a346c71eae57830928d069af934c1203497937b2c80548f2f83632b4fade2fdf2d0fe1d5fe3266cc558af64a459f77ad18feb0ab0a3c0ed012e6848c0858d48dc910043f73106546162dfa881750e65c9cdd9d4bc3942730077244b83208835fb2ed927cc2eecf8b0fd7049bfd19491dc539c85ecd1ec625d389518cf99a73b8582a74df9bd15fa0a7971a4c618858a84fc1ee561a0828c84355dcf7911789f371ba9c62b70eff6ce67ff511feb3abd900ec0cc648c1ae40c64e62a1ab3b98d99f492efc4fc35236c544dd7706165b33b9db94dc9d0a33093c6198826b7d0725a7a2cf62e6357cf951bc97e4a9ae7f89208048724d8202d1316657a9123d79d954bb3a4d0362d264ab4edcd534b338698d8f60f2ccc71be6e5f4ce0dc7916ad047a74f5753205db19f5be21aaabe9de5737f2352731586a871597c41fbd30061437dfdb312f56782666cb32169f5e61112f9d54153cc48a5c4089b9298666892583e34ccad14186e96efbd4a8fb2a7ead6741ad88ab55e864e744ab6056aeff3ec5ddb992c021f7dd24bd30f7d19b5e07120f840845bc9da9b096c90e85ce79c85e219aae04cef\nSHA3-256: 05f0e21170e704990cd04297c9fdf2a67a23e36b19c21518b2bd72003c832964\nSHA3-512: 5e9fd833f5540423bf38938efc8bb3dd498c79ab05ed3f25f4fc776ec77bd7108129bbe23f4bd1d4816dfc3099219bbf13387804499c93b9fab8f1a8214c48f6\nSHAKE-128: 7fd81239edfb41b2192b97899ea438884ed419e493607067e8373673cf7a8380a8949d9191c50d827a5a5fbebe69b7c3ed3a2ecda963238400cb0e32bf3099d1fb44aec1099ca8fb3a86a29e8dfa8e705ba2b24b9c87de1b9ebcb46d9ba62399131910f3cb900a57d3f8f97ebd3f39b701e2015911427ff180b537db1e92347c5e41922930bb82eb88458022693e52231fe7f89d033109d3d2831c96bd8f4d8a6804e3fb3f1fb0b9c0ba2fdecc7d1f040fd08b75602fb73f0be09c77f1f5b3cb99438374e0ce48cc88845890a21934c1b5dae99a70db74fcaf0654e36202a6a383656cd752cd3c659ab8b8b622546e9f7db04f2b04a341b0113117548b258257b54ce95898eb90ef0a7325ce04f93045d3aae50c58c76273459b67a6249bb30a17750de55557accd20f6237360d3bd0545832a9a31415770924c223ae58a030d116f6ecd4ac826131d0763d3619b7061cc075fca92f83e8a44615106f8fecdd6045832779fb71af496504aca984e7c48a9dcae1f59d6081f74c9e68c7835fe5b51bb71d82f2302bae5df4966e319313bd7ce724f2ac510cc6ada4fbf5efab7fc93a849221f12e7234ad37dd1aaecf981e0a764322248425a0cf4c39d7ecce6ab2b25efb037e4c11d1b3a51a2f9d3cc1ce616c1431e017ab2b16741c59b8145a18031123d8aba9bf72787f04f13d0ae77fbf5a179e7488f794f447147f252788d\nSHAKE-256: 15e5b441d9724b771874f838772667a10f7e2e97991c3348f6f72ffc44333f9bd343a90a2f8d08da401864e9af262cbd4f293bff29a3039aaa846c593540abd438f0e6f9c15c8c99a8adb5dbcbbfdd332ff412369fbbb3f44a5cbda7127f0125755559c185418076270ea615574826141bfe0bc35fafbc69d2468ac00f92fd140fcd832036330cede2c958fdca17c3fdef32ea0f3330507dd7f4878b2d16ae31d81f0e0b8f089b1422944eb99c5425f5807d93e000eca437daa00a4b2ef6bd8fb07fee249a836eaa404ee6005b65dc1717bc5aa40b310feace10f37a63e1ab84745f71bd255b800ec8bf0af961632232803557288d564e19eae047975fab8e23f666dbb03e3751dca21ae3044280ae9fd35c0fe78b10f73cc64657a9194ad9be9809526cfb780b944cd9fcecdbe5afa0560cc4f35de130abe60441e98a3115c255ec01e5e268125adbc8dd3579c05c280b8af00c3eadcd7dda49c7f8a489c1cbc5d34a5726fcde141eca29245cf36ced0b5cbbb20a3c0dc6e46833099bf2cbc5efa1fb98ffb9b1bd5317388568d34eff2474bafae0f62250255dbc25d3af66e915642e398754626ae669707cf471980854a495e90ab0fdd860d63b13ad3789efe02713ce528423e41af6c8dd201a16939ac881f2560fb913dc46e49b25c2232226584e2f83dda1d8d148ae7913e98835a4c2df9eeb015b6da5ca5fc68695f214\n\nInput: 5fe2a2c792290da77a7676ed43b0a6f5f51326392133640362f60e0474f88da751f8de22e6dfecc479d635560c8f28b6675f5350cee9906fd296916547f83d1b24b937cdb0900acaee1e3ef0b2e617445f5ca7011311e93d78c33af2875bd8fc69cca9573ef45053a3fc7e2e8728b4de2dd4b272ad52e49ffc03c9f3965715c71f219d088c2eea59603ea6fc99da1a008e48e2f5e4779f07142baca179bcfc8c726c9297ea01c482b6c9e84a8e93508ac20c92f6e34b4124b4e348c83072595ff6d6de5d55964e2dc4201eaedca65928daba4c8d4804142989a40ad60965f131a0e841d115faa50ba0eeb226a34116554b4e31303af0b84e748e098ff8f45cfad0a42cfb61e2fc3a0c2c5198a4590790357512cc0595fbc05cc1159579319d8e553721f3047b79f0febbd6863d", + "6f55b98d0f7ef6731115297c5216f8ff07168a22e0c49f4011284718e6abe213dd5a11171956203084f76a676e34c088f21de2ad4f51aa5bde9f56710bc7488816d0a5b74f7d9c1c297721012f13d9e96a80dc203439e53b8bfc980ce538acb88aaf3c4d69d4ef0530abd5693153d4ca4394af423ebf36cd72913b5390fba24f749973a97f99ef455bbe53f29b88250df5de5174e9c45ab4c710986f216a3b87c6ff97970042ea4491d661e6c62950513d6c6c6f7228feda462219997019a26b8053f5\nSHA3-256: d4afa593a790ae763e5ae2c8bd171558eb1ce7f43de59684ce789bb4d8cf1cc5\nSHA3-512: 95df45078879e3a1089841a519cd244d6bfd77e40d9cd9902ba02e394f694187e914b33a2eb8a798db471de99dfcb1e84f8bfc93a8730d8bd2091e42c214c426\nSHAKE-128: a5560d5e5407f00cf5cbbaad95e47903886886e42f280a203e9f58c7732c56daad4ecfbab84beef2f44b75fafc8de823d99e596ba4a9cc22bd3d032ad5db829047647af0dab8ea29a24f280f9210bc292b981e7be99aca6be5930eeef8766adc5c8cc70513b60efb893a684d4abba3ab3fc4fd3f643601e46639a0f75b5bf666d28c6e216071fdab9f04f3b2c5e43946f758bfb2cb108ef24969d5ae7b4ae089ec3452d3d359a921d7f449d0de4b16e637182e1cd2a2c13a17e4abaa79617292fc3a0b7d6db489573091fca826603d0f6b4b4dad2d3e1a1bc2537903c45d71b316e81c38009ed5cac8a3ee33542e8a010f50a98c8dd3d94e3231f00e980a32cd0e618b4038f262ca285cc7b7f9ade1051d30cf28135eb6caf1c85df4272dfd90e8fdb831c227fed3a05f811031de8fc201441f1b45368a6a3c36c9b2ae759d251496de732a6356689b2a187fcceb7f6c7efc0ae95ecfcad9550002b8800e72db2c022a1dd390db7f0cce400d6913b20998245b71fee51a0133f50dc3cf259c4b2c6507acbb61ee4d8104da861baad135e719724d414b6cc3f5ac88fdd03e444adcaad1290086696f7362ab15442373c44893e21dba407abc941b7549b8ad821ff95434d3c1e860e9d46469e46db0f85956bda355b762ff2c00ef021f81a7f439f5178ff3d5b86dce5c9b8d4095609afbe22dc1a84d8b3818b0c67ce70370b2a6\nSHAKE-256: 982a433a86ed8d3c6e4695f56ccdd077addae57fa06f65f71cf007f50005f5efb2f5d3c4825f988c6d4b6692d27c1849d8e8d85cf975cf97ce2d1d3165ecac29d77330b6bdd77a155ae7a9afe2eff7a37c62d4bb9b94fcd47cb27d3a88aff28b08476724a129a31e4367e3bcf6dce3562f74380ad1a9187d0685173d0e69a085ae27054611f62064bdf14ea9e2da7ab2e00e6c85566f2357f224aa9794aea29d6b9b159b73693d6d94c6c7d1be9089a1df3a13c1999bea7b942b27138770a64d27e70d8a57c047d962de3cef865d529a484bcdb710927d1eee089959a41e685bbf916414ee4d2c4f6c6d4eea8357f15a4bffe5059bd3d6d17396808845654684376907b7450f934934598389da4cfe5e52889e87083e913622c92d25f0714478724b2744a1a82dbac8eb5fd41c25050370785ccf23b347bf721c54b9ed93b66cbdfbdcebab0e7868528fc9950c76cefc0b155dfbef081610eb20a19c651f6076f7c4b025df0b7ac5f877cd3825467f59dd1942d092dc02f0e2381ce2cda3d35df157f2dc87852ce0b2b9c0a0af5cb1ead0386b47271c59927afa2170126450b7d5e401df5b72d6e0bce057db855e774360ee9cff52eef822cf4d17a42283dfb8bba59a0326582eae2aa767b3c78c7150417163e04e4f232cf4f245e5f376e579985006d2f5e2f2096ddb01338efb1404b2d9a4ac440092a137ebdec353747043\n\nInput: ca3437b491242dff86f942aadecc8af47f2a9a33aa6b40b1338651677b060c3f9074379196b6e7061c78eafb1f433e0f86366b2a7f7ea1a6c209d161d55cbb0e568ce2d9a0860deb6057501ea1982b5a9c908c355ec0ff1b6ed7f4676d4a44db0da9506c767d8c158438dd8d24739b40afec846a08027a8ecd61b66d71423db740d21e1776607d541c693637b3700744a38ec15bc569ffc1579fca30ae1eab77ea1bd93ec0f67a9c9594ee7da13aa850a5d2e99eab99de41cb22ab6d314f4dc3968da253a8fe818b9d38b288c764c7815ee4d66f179c011e9af6c8a11ef8d3bc9b71ada4aa24157ff55f05adfcb81e8fab0aaae122189d72ce4862c3ccae2009bfb0416f5803623f7acf3b0b31b2e2af5c943ad3fce71f0264eb14ebac40346c46ef6a4d5c87fffe6f9714562353619ece1bedda2c5c6362ce6845750c29ab51c724e41194cb8b22cc03a8f22da8a819703fd2272b99739581f234a5cda2bed1b925a2529bf451e03102d196bedd985cdf67d84beb4d5fdcb1cfd42eab6a1ac51bc1248e5109ce56ad75dea4b55bb652a99558b51bc466eb0f91abceccaeb53baefe9e4b121ade4d9489af7c7ad67003cf1f2076a19b30b0e35e766a98085eca79e6c6d75252f6bd8dbc39672ddbf58b26cd7cc4ea85a5a2248679aab3db70e620ec56d6381b65cef71d15cbc98a19b73b\nSHA3-256: 49373db0fa11e4b92a98e09b5513a63857ed21cb90a7aa49d654698c71fdf61d\nSHA3-512: ed0d27cdd0c7f90edf081014f9e3252acb36f67820ca834cd49f8f7aa382e6605acfeac3c72f7c2f2f260c3cfded17dd5e2657cd84529a48e51d7ed548e64c8f\nSHAKE-128: c34298256ebc1e895030e4f94e39514f66a3ffa2f10b3c782360bf8f00b387d2bc072dc763b87db0332a732685498479c6d4bd62ee3eef411d7648a0571e5857aa06f07470f8521a3a1010b1ccf3c28e2b8b2641dabfd7bbe685e4096b63477c6aff6eed9c00b5c9567222afe1195749ef037c3947d626041e07c8efb37e28a47a6f1e73a1724083b9e50377c14a60119d3890969dbf3c907cd35bea3c335966dbaca201925640e37d6e4e5df580c78b63f4dd4db1158c95028855dd681d12b1b0afbd6f2d621d4c9a11ea0ba07d58565b5e3527d68f57f277c6bf873e47bdf4eee5d9008c2518534876e0fe668e4a715f442a5562c8ee9720dbfb2969c229e92c55f0bbfa73f4e53eed76e076be0dbce8f594e762a574764b78364cba7cdc912ca6f12f5fc885f8daadb8c4d241d8bf977e8d8aa515fcac096bcaf33a9f9e5d2111d24e26b12195ea53c1ab6fda1b2ff413947df5fda99a6c046e49c46af02b3357fecb633f3716d0435a4a3ccdbf12273d461a360f933c81ab378e5bf3903fbcef160f38ac482433334373c62218c13aa0e8e7bf77a7fc50078efcdb82d1f1e756a664cc5d19ee6cc7c3a124f9282b89f2ac731c1c4d14de4caea7aa90cd8713e7235d322d5e38e6fbe269f70aba8d4e1c23cee935fdf9db9b7b7b0680aa023f39d2728219dcb99536478ad1d48bd4e3a43e6313d3bdc48fca7c7d55a89947\nSHAKE-256: a15cbc896549a6756ec090a4a4ad94f7ea6ffcd472e49d0309444e38d26b937aed0646c0d7806266ba751feb8c48f7478b6dd1e580d92a38fa3261a723c0c2be4efbcb3acb4710c7a5c45df662e8c8b6a697bff5b003809a4b092dd6b7defa981621bfd5054a2993b73985063119058a54ddaf430632267ad057267128703d2e63424af04c003bf5ee129b06e8dc1b07e99c40c28951f5964f9560ffc42a6bec112bddf32f804b43b549b828206ebc2822aab16dc6a433baa1f18c74025285efe455577fad01152e1dd817db762a44854f373f68f1217f366817ad9bd50ae95870e0b386f69f65aecd5cdb3f976cb6312b96f343f1ee887a690a897c771a2a0ee564c9c2a3823dbb96b12e5552c42d5601cea96931f05b05e4bb714ba8665ab17f0d5b107fe9a58cb54fc457204b1dfb4c1059cada467585b95fd190de69ecffa5c00d7f2d8b39777ab281a178e9bb2ee4a43ee3265c1f0cf255f445f4be171858ecdc9a35b55d82eddc56700e7c54143295a16085069d1ffa8f2fe5bf11b40c60452e793fe009406176b0beee4745bb27a7a6d6bfcd7770a811f027ca0daa4f77331fea2124e9bc188ef1fe0d07001ac457bd21beb7356630a444cc0ecfa248faef242ccf760dbc69db80d6211ccbfc5f021ffa2b5f7f691d6d005920d1d4fe5685ec8e8b66d0a07142bdda860c4b5fe3fedee88dca3ba36f7f91aaf32f4cc4\n\nInput: 87d5145e9edb4232cebac82af76781eff02e70c017fdbe97bcbc0acec6e43447cd9d5fb768b44d9a9572e542ce9ec7bf401f6be835d811fe3dbe9bb95e5ec304877ca003516de7f2f260cefa6895a7d0b1b5700a91a4228ec5af756153b1fbbbb76dfaa5ccd65f7202a2fdfa3c6e2d34c066248bca0772a172534ebab6a312cd1b61c19e140fef7021332c6a40dcf353134610a62fdbb39178f91ccb856728aaec318e7d18a1e84e604efddd4424d78206bfe5d2326a3f36810188e07e6e096585e6c913febcedf92a8bbd7a1a46d02d3c1412a8160ab5060a2ce8e1beba8214e69e635652c030bf854c541d4d260707db4b2626b24e5ec8e122fd16a14b8310f9feff9fff7e3ffea94fced8f9002f8440c7f5e2519d47c472f6ed92f87e702f95c1062069ebd986d106446370ed5e3bb0eadeecd33fe1056fca6157b8fc799017a44d0a1db95d0c27e3f41a3cfcc2d06f4f5821c384bc1eda9858f9ec3007dcd6e9dcb8e83aa2950619c0c4815aab7d8a44935f3bcc16802e6620231a55eb600306d90d25e8d47f871d241055b3efabbe183dd478e0d71b0e473fbd041108b109100897f2a78156355406581675985d20f7c6a7c34266e761d71436daa7b1803158550af05d78bbd9b3181e88002a482d9b34054ce597aa251f2601ffa23df2fc89c723b4b6a7e895636af16c84754c3855\nSHA3-256: 6503854b971f2b20a65833bf89c243a9c17c2bc90e9df3c87c519ee2c63c954d\nSHA3-512: 6b3b182dd3f5aa16824df4a53a217bf7d6347f4c65ff3cb71ace5d7755782c2f6f5ee496785591c86b1215c30df55c86a40a8222dfbd1f94cd07d57058c845a7\nSHAKE-128: ef1162090d27b7c9e70beb3e08278f41c7ea02e028d60989f6e444f867196c7bd2537e0c1aa19d204f607e448929c3fba1f44af108e3a4c8472352d88ce19086069230b8b3149055635afe83e803c8fe8023d6106ac164a151f8f45bf95811a6ca3a198e7704ac128a6bb44529e7af50818cac6f72dad906f198432035f998e7eb15f843448c7bd177e7649ca9b42edf5ca1d62e82d8ad3ded7dee30a2522368f8944b70cdc66ceb52021b8fce6b6094ba3b111459a14ad3d1bcdde649fa69e3fcce39d4dd7fad61ef60f0ea540c16015fea2955db239f3c88ed7ab9e18c2e2e0cea4680a409179dd9c8441b4f5f170f7df5cf4d0d4e62e6fe902b7b0fb92ca2f0f875ae04c97aaa0112326ed2677d58492b8dd37b92d6df1efd86ceb791f3ca0d66b8dff08d9e10469c06574e00c1375846d5b30c21c128e7647a8db6c248d81d2dcfae00c0deddeb994440ea59ddd0fe9a2f7359d525f4252c9996b6b0f052492fc06c8ec7e11d4339fcb22296b74765d099bdac6b687e6c20ae51d16e5a4519482adde530a028314e9fbd7a79514252d3b057ec1fd49682e9d5a2bf3f6ce908491b5ec918b15665953f9357b885e0ac178ce3685b48d1542ebb9b6727ef4a443d8af2cdb3ee276d2925b4f1736d6e14b303392a6da20442b3232df0d23c6ca347769b57f4d08094a2f7ce24b48dc657d7", + "9d5c137108541a7755ef13185420\nSHAKE-256: 697c09b7790392eae5848cd1d929a39bca91ac656e143054a5f61233c6ebfea2fe865915f4ffb90f250eb219341785405ea04d7e9cf20f8e01a6709e88eeaa0415605441f226878e081705eab84479e9b87cbf8b2509d46ef708742fe36695b8a74d1476145ac4d2e1f8cd2452d34f7de1d3a250c098fb9f0db00f4c0001d4a64309a4a14ac1af9ebe342a9e967650b26f0f048279919fb7a053832ac2d6f5d6f69a9c59eb66a2143fd17697f6aeea088b60ffab30c1ef3935fb54f61b5d3b9fb3d3dd4ed6e81324e83c50811f1e1477adceb4c5d93f80d9aa4356f9568b93fe8b887f580c1371c96d9a92f899709dccb0c009a579b8cbf595debefc836c661f2c9fa2aabd549a7887403e750b0a3feca28ea8073f8ba6f682bb243975c3e61651a8864c80101d0999bea4294cfba0e800fa65e12f3c79931ad6b6e0c1197f97dae28a66d14ef2b0169fbf104ac66a943bb95ca3757e93c5326375fb596ccd3e7a24cf4939578158d885ab878057f7fce6a8538457e303486a3c7e88bd93ab8d83b42aff1e5bb0feeb1293ba9d17eec73b708aca7af2ca9d56295c330e639882abd3182837fc5a47f56ad0cbdac1f2ffec871d63f38865825c1fa8eae5ff41eb71b104085fdb2be95d0cb08cbc87cf27d9b43de4e0af647c576d85e1889dc3026388351100afbdb9b49c374d3a536e77cbf86dc32016fc895884f2544f8d8208\n\nInput: 1bd6693335cc1ddc0d9f0052e7972e3d3d020ef74f7cf13af3a3304c0f5021f204cb5dee866fe2675b97cd8aad3e4289e16470799dcbf54fd70b730720c7cbdb50928a767a906a55d07f671482fccbefb88c4f7af627c834ed23838405d0269f7b508e43e72466e82f0a3561beac3c5b13495f1caa55cf4b96a1191f2afe14dc09026bc165b1c0e22533c54febdfb39b5501f3ce88ebe5caac0ef8d2662c25827e81899a12fb64a8e0eaff518916e3c3b08e2bace2022e59062564ea08127078c50efdddb31716268fe989ac61ca5bc80222b6b5d85463d7e4b4fd499d738b4f196936714d09589a4ceb4eb29781880555d69deaea676dd3db57f663660fa7cf3c52ddb9547ae8e492bbc9b0393868be34bfb9579481825db989af212020f72e3c1d0d890b454b0f3c7dc1b37b5f86e9454a9597626b7f11e35b22cb727734bb844245304f11dd535c3ba3aec24966aaf190494a156ddb6c0ea0c4a9fbaaaf54d535e52e97e9b1c4eb6a82694eb6e07db800daf598f9fab6833f080c56dde7fd4614f6ac0b7a071704a368045dde1792e7fcee161ac76d92246d71655df405efb9df9c7bd0478580b64ad23efd4ab3eb4d625f0d5452bb127fdd8ce457efeefbe956d975df820f3aa51832a968f022fab0fae6f121c806c17066dce1689bcddfaef15ce9f467289aa71191933d3ae85dfda16c\nSHA3-256: a06c83b440d4db63152a5b83f8ba7af7e9e48836f05b261ee7cc8147c376f3fa\nSHA3-512: cfc881f1b2d0a43d537366cdf90195ae7fc14ecdcf906ebad08c9c82c1521b517ca6c14d1a746edaf0debb933b1c3788e641e4a44ee186d605087473934104b7\nSHAKE-128: 329ee513dd00becf467a23e58e2181095316166049a5a05c1466c5f497a903115ad369ebe9118751f58086efd2e0f6db15401b48a48b49fc4128febfa761ab4550a8d0509938a3bb748ae1d5aacf81047790a3f7419a405e02a2c7259c1f278e99c0089e67d59c0c21817e93236984fc636fe56e98cb60460443a6258dcbd53c2b4b6b3669b36f05c4820c29817d0949f2112d3f5fdc205a9644adf65e8fd547b4adf716da212d7da1f4c571a1b95e18e97345870f45e70962dd926423c8a4709acd788f9aff5f80e1d963462a035321c5f63a261ed23d0e3d3450a67cfe1c71a746c8ac8d99481a27b71c14cba8031f53aa7445336dfa39a47d962c06214e062ccc433c5db155b258d359be496dd35d04feaa8a4838f871fc653cca89c2d069db1f7480aa5b657d055aac0cedc05f4f61de2d10e00d03d58d214f748a9c18bd6492684ea2817d4a2ce698bfa0b31aeffa15a43103d947ccac497c8ea6df0aa05687382132f4b62518ad23888c65a7ca0c9d663410590f401f6c0c7d34728c7e74ee212a5b4b905b5999aadee6699fb77a8b4ef6c4700520b693dacf4985c44f634ec3701c7dfc349b22eaf07707ca739648030c10b16bb6fbce796ec7f2fd1952b71e5e2c3398c36710456cec54bcb513801de144eab800ff85193f6ea48ce99708fe5dd9d3e83242a83717d7ba2edb8554410afc4e6c51e42b2a94d82cac68\nSHAKE-256: c58ec045195f7d4c6457692abea9e4f796a960031557b254987c8fc2c3fcc1d31a8a60e93c1fb52b058678b73a5757a0f34c3c5c6fe4d4488b81b3927d1a83cb979e11573fe23f3bfa540428383b6b4f0e35b163a88cbb7391f246025fb64c61ac0f69ee2e9ef68a3e95ddc2d2a6549f67fcd932d58f867e79b41a140c2358c888d5176d085f72c855b79e565d776cf82d8d9c91a32899403f7d08b9d9f877ebb814c09084e0d8434bfe278ee7f9c25ea2791d22446cea89e59ca06e258d375d4e499aa072f6cb5ec5c387b97595b2abae64b57d10627be128650ce01fba1266856a7d4b08423269a3a2c4045cd587ee4b7a29035ea08dd7f4448aa34c12fcac5d8f4978aa097e01741cebaed63dd365a558ac86fb5a276b6a380d948be1c81fdc3c0ea1129a54eab5919ab4f950a65d9280d5901e2960ed9c6ed55c5c324cb00d7a5ef4001b9fc36422010656f50d5068c54335ab066a5ce5220bcd6b3e1a2651bf9cfe178b6f511c938d1e52213b6beda4c20ea276ac8bc7cb5c256f1258dd363a4043cceef0870da9283ca5f57e240fc58c945810c559c655f5268898746dc53a7ef1b86b31e34e5d10864b2567165f97d5f6ae980d9af977cc955984c2d969cbb9f202d2cd3094b47c288cdc480b70344f2b2d0db4b9f548df782aa08aef35062c633a751b7001f01c1707e714318b59b823a0229ce783467bc1c2a551d8\n\nInput: d0ee7213ea0cd34f99e8278c24b0063d416e64da5aee9639a18194e3956b5fc84ebb17f592c2ef45f9ec9b75c648c808dc4369a74215ba8940d640b3d002dfb5aed7c63884ba6e52278b657f70de0510ce8865faca5531d422a8374975add8cfa79c058a942d55f32dd761daeccfb8c52861045d4f69a9176b0909d928ef71f91eb181866200bf0fc3017a9802440a9bdf78a23a8d086963aa9f3f33113bac5eccd08f4b2b34da4c7a6461bd5c1f1b4e29338d211b87fada3f486a13017485db83395f22d4f92aca953453df165b0abfef9babadb16ee76ac46843d9c976f860e6ffa960c3451162f64815475b9c91f3c98c60c33c6f0306a8c2c230aa6981205d74facf69b298b0b96e29a024a9b2a48cd5f3da5a6171969f9adf4a798f36ebf61f3e4018f81ff90ffd9ce26d638428f7be4249b6a28148e4c6e9d3d61f68be103e6d430c151a0250de138b5770293a977fa9bf5f5208b38a9ff99d08363b9dc9cc65f266b968cdf708fc31598baa3c10f3ce7a50b3b20a35acb424dca404cdf99fdebba60ee19b76aca124bd90bee9a4d54efa30b7144913c52e84837637938f2d27135119ef06d0df74180ca6d99cc1aaa6654e93f54f9e92d12e18a047f30fe5319ffacc1d46e5cbcc5653ab24fac1c2342e8981f97f44835eda8801526b2d7d1b9c15984087467b6c391eb0acaf98da311d\nSHA3-256: 29ff7168680bff0b61b64812435b9423f279284c4b1ea34af5b670f018370a58\nSHA3-512: 38f54d2abaed9e343f8b33049fd21153d9901936e7857bffcb40d71565b5a9e3a80c6a8a8487b03d1b19dc71a91d78f4e8b110e485188af6d33db3a3515422f4\nSHAKE-128: 402e4968ee3f9a3efc6002652cee0fa90ed21f76ced9bb5fdaa69a654ba09f564ab7927ca77b4888bef312bdb8f9a6892350f594c81ade8d90d3000a45e6604e3bafd7232bdc48203ee131f80922dfed863880f74d0d180bb41f3ab3d4925a53c02bbf118b07b4e03d8810ff0f695e7f0f27595df7b79d4d7eca27da5de3c2723b95f324beac863d0d6532443a29c977cd529b57f9c2f910be6a604893237fd83bed46dbbda4cd72112faba11441b047019d7d7afe18ac2a90c8b15fe7f07db0ffbecadb062076b4d90b1f025b9c2c45835e642529f208d6d44f04b7d604df49530d9c80a5df306bfb553d0789ed831612544647cd47445678d391d50aabce700d18a14cdf78427d545840e9ad7045286b62eb51ec49e3b100499da650b092e29aaf5cfd6d6289da9d4914d534aa4126af728da9b6f579a0360e57f5b9e37cdc9cfc8a696a9c2ad9fdc334e79970af8d655119f9ae86d40a5f47e9bf1d059ea329973a43142ea3481e40c6f67f8a26ed9b27982d27a561d9f6a61355d8b4735ecf7b0885748242110f01ccc32ada45478487a2a541c0e187c5ee1dd257bc7c810242b7f63a3ab14ee7c457d3bf6def869046bf4b82e99f5b4062a99c11fcd77939f62a44e83d0b7a19eb9287d55dcd35fe89b82584f0fcfc470edcb75ff8e88b13a71453cfd4eb259f9e0d0461ae9a440e678590ed0e2a5f4cd9d7be946164dc\nSHAKE-256: 6b701d95b48da589eade36f621fd249b859c7125d26330be02eeabb57e139234275f7805865d1c74d3b522791680ab2971a72852c8f0246ef2a4157aee78ba5d75586c3149de3229bfb321f6b8bd0ac7641b159221027b51d3b38a573afaa90e79f4b7cc0aec99816c7861a97b6fb545a2a6c012ce0b95580f250ab3398714b88c2afb87916a096e6d1ad6c399abd32d4ab22b22b95a701e93d7917fbd16e9431ed36844604fe0c36aa9d105d81bfab8ea7bcf82b12c420c176e96d6e5d0bd1d7f6636314844605d0d690023e4cc728409d2d34f4763cbc31950aa5769bf5a0865f8e1bde0ebed596eb9ee8c58e40a43cc38391f28adab3a5cae5c6b23d0194981a8978c5917b3841177ff3319b6a9a9a48c2f0fb9b312a30f8984d4c49feb27a661349a2a2cc53f45cce6ad2fa3167b42da34aea858c1e3f9d5effc64bcb6ad6a7117092106806a19b60a1bb9e0f54387e4847e5f09de9731dc9fe8d8dc1d6b01fa1ed0111f8b288ec14d4f32272d7c4ac23c8598f2a45a5aaa1fac35efca816bf2cb833397b7468e992748bc0f85acc2c73158111e88d6c68ead22a83fb61628cc284a054f4e526ab2e14b57c79aa43a00b55b1be2ddf32ff8e7f4c50a8a7ec490b1c64acd669ee98ade150716e7dc2316b3b2e04b949dec9f506b7050b2b0121146164eb6602283276c7662b3b78391d7103fbf7a3b395df9501d0546a0e7\n\nInput: 9692c57e41855a52af7534adba0fd2f515206cd8fe0aff5e5db74e26a41c54f29afc2f1dfa20dab39d37be3f04aa4f92ec17580648c87171e8268200c0130174a967d8718e1f0ed71c13f08079daff46f38392d6943ba1a1e38840251a49dd6a7205ee5302638806f573e7885af7b4f18cb19e838025d1e54f15a294ac32e82250211dda15b056e0f4d3cdefa75902e1ea7a26938fa9045f701cd72aac354c15e0e0b82eb937ac9c5e4e2460b3e46b399c8194c58177149074f1f99aadbeb58702f5e63c90b90d251bcea5319b01ee5d304d762b7da1b7d837f96abb1b256b310bff212a0bd1c59ff945aea4c460a9207e080b969db08fbeaf98fd7db1640e79dd0ee2212ea55a41f29", + "0088f76ad1a602fe82e997c3bee41d2fc0608a1a5d5f5ad08bd9e54383cb95e80e5d1c3ea2c0da5691e1a16d7e3b72604f107b3285e6807c027aa211179741d9daa420e4e7abfdb58deb68188caa85165aa3d04fc66bb779552ba5f9ceb0872e671cefef1c08a59d4c034129ab1b120ac5052230d8956eb6922025d86e894dfd918cef4a5fa3bf137294999e6a2712b6dafcfc29b103b8a9ad038c585b4e3feed3918a41bcc3f75812de6f806c68ed7dadfc38436396eaf17f1f7886fb642c53112d8b8ad5b7a2c803ab08241dc848a55a0481a3962e207c715dfda054c24e33de9e2b6874fd26041bb7721\nSHA3-256: a3e4ab92b72c4bed1f761848062617e049491a9fca84de0cd741c4e7742a30fc\nSHA3-512: 366bd209232fec57fa420e30fe19ec7b68e9e39171d1f1415666a07a9c876d92eac1734e63b17e3c150c5be977a466c723008de7c6e42d4a342021c7f81b92b6\nSHAKE-128: 9175a94e2f1be42af73175989d44014e135ce01d263d90d5f44826e4135043c0411401b822a0478a1889f3fe0b24d56ebe1364f2a291cd0b9b6dfc04d46c029d911a07ce3a220d1fe7844404742f43471261c822d9788bfb84de077329f1383f41dcbf9eb8634a4a852e8458c1b77d76f3dd36baa28d1bc5ca396f4ee6a78c2adc2c73061d707f86ad4119f85d43d2e044153e6c1fda5ad44bd7dcae23b3aafd184053de4a06111858ae11e3ae0d99349698bb789f476ef294ac8db418b7c30a2cdc69c9842ce621b6ab4452b606619a027138085ce17a06e543e55e3b7e60062715ef8db4e19f25b5e53e6fa764bedba52ee840bc1aec3d3d4fe9423db4cac8818160b8b3ec250f9719f109f3a4c221be5adbaedfc6d01eafc52f633530c3ba5f122c611c25f1e3c1b633b258f3731c74ec17313509d9d3d7f63ef803f3d31569cfd8f9bafd026c8cdf353dfe62abac149b560b853a9ad433198cbf818e213fa5d653f10b29f3835e770f6dadfc870880ac0d2d2df94b0a301f869b6222370385287f003a68269ef723b95fcac9992da6e3c3d472145b759cfc7555e9c50de6361a8c65cfb6ab96afaed426c915ddb560eb26190f8ae4bff48291d99e513a420562420246bc586e7ab80425c2dfe6a122e9c9ab075b1f31e7b4618a92021e0cc6dfdf4a776a7b4106825a676822a23224fef5375d537365d9f19112c4610363\nSHAKE-256: 572bb428cd35738d3ecd8cafc1ab9e7e04004137e1d60fb967801a8fd13ae7d42880ec1a7d8353f45b80c13ffada53deccbb2965df68f97eb0e39a85145bdc201b4fdb066cbe6844e74da0af581024925e60c36642d87efc25e4848fc5fc1990d4cc1446fde98328805147bd6dcad79e18a1f260f24d2be7ee1bd11db56a46a926f3165daaf6064e09d7a91b691efd7bf7c38f861fff8f349b858222a83cf8121f9c33a85599d491b0f9bd187afed6475f7ea637705e6599f7f7cac9c9b356055693b35307182a4f23b9f6e57b51164157650328ca47fe5f95883fd03d7b6f6e959478991445b91a1de4a6611163aa8729b7716f08d202dc37b31184e7fccc8c30169872181d1d6cccdd9ba57b10f60f228e6716dbcfa999bc1f1b29a3c15f1db1f7e427cccc5936f300033cf1c04e076c8e8323c7adb5fd8b2627634a747b054b4a78196c2fdd957c3a0c558f0a5f8c6acf691eb1a3ebc6c9b8b0212321bd2c8bf1eae8d8ee3ec75e2bf9f83c1afbeffd120653252db09b1c4e5481b4faf46b455e06fab3623e0feb64f31ab21620d1d951b68609ebf71b926979b397c8b3c683b27f429d044ea8d8d5778ea8739f2701ca90e979c8493194c04cab546a2af91d2f3f7ebfa33af5a2991bf1dac74a92699dc814258d6ee90b4fff5144cae1c2431aa6424088b6bc3d6e39ccd799a4f0fe4d78d623567b0032b68a34cb06543b\n\nInput: e4abad8b782eda8e41d4be6f206c6a1c5eb96ac16e92d310c7fa14acba27cbd8d501a6100089e1b61bc14c0a4665a3d60f4896d9d6e34d201beea69a755de878d723807039aee0ae656b1001fe4fc8cbe9deb2bc4579345b5a0788fb0061880c45027d0b51556c50949f9df998bd4b37a6da1bcb7cf9d10e1c5736b32c6b585dbcca436e6c523c41c530f254e3925bcb2fb7b29ceca077b013d694e9a254eb699e4b63557de363aa08535c58c0853de6ac5b448b7f0bcbc6ace4abb5400995808439c0e96c02db715113cfe80e1b6d5ee757ed3b73a1594bce25c0346288c6c5a547dd18bd2af623ebef49ac90949dcb9447d7e59fbbfa06bcd12dd98a12f2598a1c2168b72a2b4f693c8f25f99464d34edb2546cfb098e1275a3506fcc1c3522b843f241b945a166bb271183e432e72d66593741b4119971544eca7e81de64641b6d363f1ff0b8639f9ff4f225ab40df92849bf5f9c54d6776c6c88c402e80da0ee1062bbd4245612a4f937ea340efe6305993812880ea3ee294d81bfd7e5ddaedc26c3b5d18dd79aa18e0afcdfb5bf47253437b0225db795519ae4354ae280abe5e0c38760a11dd42f6510f2ddc24746089fe4e38081d32617f836b687c26d53fed8af7a1ebf6b00e5c471cc4a609d14f443c888696d2da39f80dd018bf9f92641f71fbd95f6ee714770e2c34882681ff3e7bf3617\nSHA3-256: 7499a373ecc73c30a4056b4e90c2f3d2edee9f022d05a9e6d2ec973bb4a3f206\nSHA3-512: f1e4668add81334f73758b1d0b3192cafa8accbe8b0bbaa0af689c7bd0b52e17df2b065da4bb2455c8da64f21b2bf38b2529c5a2f05a733d1562974c0a1644b3\nSHAKE-128: 20adb1ac501c5d6ba9a32eb336ab477e2aa0ab19014d5087cbfeca11996b4cb12c61c3e2c340a7380756d01f282f71ab68eb83b9aa440f5e53ac028fcbb73921e6ff9c0abd2a5b01829759f46d60e75963e70590a7da9f0fea310766582bbe3363422fb83283c1d83b1707b5f4f16615c311055edb5d498f6d01f32647fe0de6eb00328284dd2361171b1aff5928d6d73d901979d165e1b7229dcf62bd908995c3c588b868ac080739f7ef9b34c4e83063eb0d85b30952c2d774b9122141cb94a3aa51f9b04f5d55c2b4de8f60df428b4bd98d1275688124864dd907fc240e7eedcc4ad4ff211c4baad20c7f0e428151b7a6f64b3f78b1387d2c4e41c9db963a9fece7e844f5a3711aff16be8f54fdeec193f56333a56c16c522aa54f0be268bb6f102f5ed3cffc3e77bef0dc345ce95c90b3c1ea0514b3d4016b3d66132fe4ff52d22fc0b3ba24c671530d18c4762be8c88cef3b1ae57729675f31d45c52c224227d77f9d21dd903213ab5eb82c07054783835100a044dddfb2e3e83aca2d937dc6fa538afd7d5dea92a66611ce0ffee444aba4bed490d367159ead08155b3dd76dcb032dcc3a10a3353ab6b66afc4f47e99e8afe8aed0b789562a11a62ab9731f6d08ade4dda30cce5936697448ce0871015feb798ae538c833cca96dd50339123b4624f3beb0a0b8fbb7053c98b1c5d50a8d2d7e30f685db4510bd82730cf\nSHAKE-256: 65c1abec801bf90cbef825e8372c6cdfe87dc64ae4b928adaf661e7680d21b6599ce812555716f6c2450404dfd2077394e83d73e7e6ff74a74a83bf96b3f04509901e95931565e786f687e6988194cedbc3548fab8184c27fcab09980ddd69da99f9510001b837c812a7bc8df06a2f382ed2b1d5799d455af60cebddfecd1f098109a947afedccb0dc0c597d31a81faecb9f11959bde953865816936c4ad6cc5b3b1f431bc1430c1d4bce94bf9b142ba1d484567a11f14c712c3384d0de62aee76e3319f5ff14067c97b8eb05c573672f86cb9c0b9d6352b9d13dddd6e192b38f78f48acc36f84a68d5cb12d0b7ef73f7a2b640cb039426f8b1fdd9b84cc5ae699d1a58bffacc7b37e04de4423ac734662bc4990dc5cfa55e99fe1e977dad92adc12b6f3c9bae33046872c223556415a0874e6b352a056ea639cc6bf8452cc3d4d9abd0faab31603b3efc5c3d9ef37b97c0f6acac441a5e5a3387d09c3b1c123cbc4067ef52b266e1360bb4913d0ac12b99fe1590eff42c5d2d0f2ab9f7f08dcbd5af9ae12dbfbfd3d02e7e53ee14ba442c8e30f70aff3dfe77bd333b13c9beb37ab1a3cde94d12dfc6632725d8713c3b1a6b13b28a7d8856f14ba625fa402acc5889fd5b53f6b0605b8c0ce3e8ce948c4c5f79ba6a073b795119f6c110fbf4331551f48003495ccbc708249127be84ab4ea7051309861551a28fd022aea5e64\n\nInput: 8bc2e1eb09c9226d50467e94827719f05763aee14151304c4ecc4cae42c5f4a2a82bc431428454aa12d05747c4f8ad55b759057080d1453dddf10d12c1ee474390732145fc1be2ace3edb0645b1b65263ead2480a2467572c296941b5b43ebd6acfd004ca93a0de6ef1d41180f6c064eec92644c5ad151f3968ac14d3ba9fe064115ee06fb5e2957b228d2fcda4608f9a1a7336b87a1c47116f7305a11abf20bcd20e1ba79f3055661a8fdef4d1cdbc4c2eedb3c0caf76826846dc9f7e3768c524fe8c1c8bf38f20183b9767d04f222dac4f9ffba6985652639b8da5f4ae02b870a67199555af3af8555b05f090e0d7bc73bfbe6562f1318fb7aed6a734d852f6dc3ae6574bd605d592aa6aa0334c0b69069f39d4e3b3763addba7d9d2223ce90711ca75c613e3c4fc6ad90b929d5350c6c5aa55f4f201971df06cae9bafa72318e61151027843bccc47d192a43b44db8ca099b002ad7ff9e9cc8485bdbff78cb836e0b551bd177f17606ee3bd9abe4991ed6fccaec9709ac1457c46d4b80c36b73899a4c6e37c879b0c25f411e79c512d2007d99bbef35656049145af903a12e1eae95ccd920f77e2f9b2fd108e1a106d902009061e0fe876176d93728ad5cca8c776979d3de83ab97b47e38f824f55f3b9a6da98c97e0e556cbca29d4c3f5c9d902661ef17d159ffb157064244f084a4d6ed4c9662f1\nSHA3-256: 93835c31955d85cd4c09cec6a02b7f1d2f644268d61f2ebf1d30dac9daa967f8\nSHA3-512: d80bcd984ee9bb21e6bbc038e8959795580efbd21ae29dff4b1b92f942e494188df2d05aed15aab3b1c8133246acb77eda80e1b6b817666a2e9e7273cfc239fb\nSHAKE-128: 242b87650552a1b768dbd89e41dc84fb35968646f058c54b2ebcf6bea79bfc3356abe8b4fcc21444789fe817926a6cbd46be0c79b1789698245cf48cd138898d9ff45f84704962efaa66c3c700b32ae685e2f269f5a189cae21cdeb4ce65e9b49472b41fcc098bd6a3b9549feafbb9b6e181d5f12ed0e36b360a1fa4fbfdcfcf1272ff6563c57001ceadb78db6b636ad015f015281027f31fba15d576848d11b71e2c5d8fc274ef32a12820978dbaf3d21e452b9e7cf1a81c508d4a035251ceed8e35b3af3839ae8eba848def4c30c2672fa1b5235db421e6eb5138110f4b9b98e95f12c6d340657bf1767ff6971ba9aaf37dd5aa38ce360684d6d2d2874db5516e508e3d17efd1c8823c70979efebd340aec40895693d09c4f5ee9cb442b3a57299823c519d5cb37d5e27ee03a2969f9eb6548f4fbbfa85dffe075ac40b7fa7f79ec4600cb8ae3a0d5d2e5f7f852395e71eb60e9c637500a764abe5deb8c0bef9d1f8d3e4191fa2062fcf2945016f9c25087536d49cf3ce1f284762ac49fa52aed90db61ed07bcb1e5816494de22b691172df391a8e4a0685aa12690e668aa0b54dcf1b11e770111f84969d1d317c09fcc461d0ed2e414d125040ad7ebd052", + "203531a53090fd1d1f294d08daf942cc01b53d56cbe0e348191b53c3bbef9abd1453e7ed4102785fb0a25859263501bc102568cf9b9a2870f87e0342afff10478\nSHAKE-256: 9fa085eb108049fa49ea8bc4dcbb234ae57233fa3d58185e2910afc3f719f42e09a247b74d14a9317d45a8d669894039109d1c000284d53b6c086d45524cd114ef2f1c799e8baa7d2a5f3efd4c3cd059e7d645eb004740d3d2bd03b4d1eeb859ff4b30b17ab9f945949197bca2eb14bb217c4d55575c794fe16131526e65052741154005f173e37f1c82eb1e704d53c5157e2ca4483356f51b887fa1436b16cb047bcf2da930dd4097193a4f0bcaffd3f027c88abfe9226fa4e056e37f9d6461aeb0e6aba4aa968ed073193138c70696c83243dd5fa5f61469617e06250fcc21095ce2001f14cbbdd41e96e48aa22baa0b3603fd7ad01efe4960e143660544e933959c05565058e259b1e137a35154a5fb1c3ad5cc8b7928c60644265491f213df275ae8a70e48710ce273ba0652306d35222f1a0280e98982d27d93deb4cf4937bbebb610f58030955babbe43d67329e67f5d21bf9f509345a0414760f25ab8ab156003339de8181dab492253afda0628e86987954ae09e73fd1e65c36be0f08d2a562aba4f4e520a31368857f24bb0b75ec2dcbb03b01130d68681f857d40b77345e13d6eeb5dc4d5d01865c099d977fbd1aec9901cb4f13c004e60e003e3b41bf9807f4ce02352d32a7cb43b7ef8250d74efcffff6cde8841bfcbc8eb821ba54e1605b8ce31cad4080adf123ca70ece922ee718b5ff0e32720cfc58d137af\n\nInput: e1484acd138e7652f55c68dee2c28ad909ea255f9948e0ae2c42756e37369aef566b9d62938cbe4a3162d83774699edcb8e54262b73dfabfc881d4bff6d613d63338359d17e9a66fe0e4148df4fd7f830a0d1cf6961339ba4d59d41adb5b92e891825f1b45c26e68ffa72cf463e5eb2253f3037b842e2b1c82f3ef6e50892016e68b30a2f43adc26d54b5dab245c8488756958b3c4d6d0b1ed0b2b5a7e15114458e6f3760d50999aee832a974bf56a46e52582499811d54364e75e746f6a4d08f1ec8d1e54cff686c8cad76a5cdbd8d1313fa4830720529d89aaaa662515d0eda6b103a4ffb51ee9c70a507e9007db8546f26e71cd9a6c9f1aba926346dc8090a76cf390bdb01aba5047de1ca45adb2b5a743b2cb19f711212eff5b435084d0683c835806c96fdffc211255a6e6ec90527c7b019c0a5c438c8947b59cd4167ba77ff9a81a8df16eef6cb83afb49f8de4c0b1426ed850488836a60c8c2f71fb3c9888496ca348148c9750687796920711452ceb41e92a5f6cf72d7038614770494ed3861e3aee391d86856102b213ec75db26bcd0c578b8fc3719ec6274f1211fe232db1ae2b07968a81065bb67964341452eb16d2b328e7f072669a2d8e326a45438f0669a2b8c5638db049e97d576b0a1cfc8d5268eb674966edd95e3595dfc6eb889ff1a83222990be0dc6dc3434d578eb8e10099c4397\nSHA3-256: a4a5884de3234d48f426f4d5248ab57b9979d68066aee931dda0c9a178786bc4\nSHA3-512: 18d1384402d2d906474b6ac5c5e036ece3f245934c5c50c7c1b471ccc84a575a2b8bf87aef910058bc409067c760aa7575998a305bee684d21e4e8ac5b55614e\nSHAKE-128: 46028906bf9b0829b5822428b41b3a3c5937de851e12f7a13e27d3dedf726394aac924dcf316e51e9d08e7e315b589dfcd84dfbb8f6588ce5af31c54755dc78abf71b66aa51000afb5535b61ce0e1b55748697fe8a4f5ac8ffebf5f431cecc72a74ad768c62d851dc685518e6252491070af8889a78b43c430975e6e5681b1082389ec92a0a9f4fa0db46d5f9ea93a1611a432d9f91c04e093cf2b811e8373f60b8ad5903a56d88ac0567c55be8173c103b844859281d93d42e6667f05e0dc2587fad938bb75ff9b6d213bc4ff89af1d0ae498d6b56227958bc55ea99824e7c97dde8a7c0c6c9c441d4dfba58404b32ec5a3278faa0dc4fda2b21fdcab91eefadc6a6b0ee5d111bc110967f6bebfc20978f4c70cf101c6debed3bb7204c1d67779a52e1679e6a57cce9e04940f3cbdd281a26160d2c084559fbf5658f7022ac14234b7228015a3bc75c233232739daaa418a8445bb6b96f97ad4f6682f240d1b3bfa7b0f2885e5c9a89ed0e0a83f581bced3b3f329cea06aaaa29807c5f9004e9fab0d8176e2ffd79306f79970f59dd7bf67783ca98661f373dd1c58a1546799f11d65807d11620fb460d175c8e922f792495a75557707e63afcbac78c5b1e6ea8db3248401b3aaa102475d01304d6e659253ce3876c8712cbd2728201fbac19f4dcbb8c0b7d3e5f84ecfaa65ae0971ce95159c671b215b4b7692f3cdd9a3d93\nSHAKE-256: 4880c42d64c60a4ec23b185a0f79d139777e449a59a0186476439cf87780fa5b68c65c19836ec5e37cd793f1057a1eef7746ab32a711c2aedd47d1b0bb95178fbe61ad8401fb712e6d8310879d324ff35f17db3d1ebb6298ac64a33f43f904de8cbf7dc623b62a859ec86bdeb546f46f568637ca4785817b5b0ae550ca8490edfaf1ef1fc222a78fb0b0da2df7593cadd1809bcb0bfd0b59ef15c9312c8b2fb6b209fcfe66354b2577a175f274d4c731e50808844a22dcf0eb1b9e4d73bcc8a0f03c13cf9bfc911922d62fbf5ec2d44a78b0520864ee93d9feaa94bba269af0849e80c7e545e6580082b6c62b0843cdfa51f7a7351d06d40be1b333760c427f5e49c032b9de9d046ae8ce94625178d161d9c72bc33c8cffe75eceb875180c9763403ff6d1206f5217aa3f498b33f35aa600867a798790e79549fd2481880dcec0533bb984d513e60ed7c21289fb19150082b6f2b083dac2b3cc1484d5cbafcc8716ec85d7373234fbe3aee32c0ad4ec343d37c42be5ae943f0077c396110c1cbd71a2e4756ea0d0654611197705c212311cce6caf35c76e8c90d45e5395bbf94698fdeaeb6afcef34b107b6b39193ec0432a8d02162694a008eee35fa198c4083ade7736c65fb2f461ebd6c897411af2ad28e47a83b3699fa491358d3f11e0e9ba830796a94eaf6a0ad43b74aae42774f99e61bb93657aff57f8a8556d7fbb17\n\nInput: 76c47f5f4aee787cd2bff758c2555ce66eecc08654f7ab5ba90c3faa20ca0c85093e79c3b689bb2cbd8d485f7a4c386077ec101747e355d1296bae5a381f4a43ee160307c7003e992a7dd8bceb6e400cac72a1b8ac7c2a7b87764208476d36ffdafbfd0e89429343e5e6b775b61eacce1d85ec91660e43416c2237b4d20e3829549e3a5398647aa5df7c2477da200bf52a4fd0d135a0196cd60cf85526a1cf1580efd008301d6b973f7e943cfb7f1a47b0704914788332f7a9fab775291a20992c9a0c8f5af4c8b4c00af8136eebab9b449289326211e53e0960b73ca8039bccc23b92fb54e340c350a17f8bdb11b7398a509f826b2dcd1ed41b036ab0039944ffc0c246ab73748b20623c69f6d3e9904ed1146d5345be5e73afc56ed8672965ea684cff2685cf84c91f90763b3eb95ef9b15c35efb95aadccc6c6d76bf3544d849637de7f78f6fb971a1396bde6cd63b521b05922876a34f927dc8f35b0cb41726db51dfbfca773e7acd374dbaeaee03f62f31b0f52f883fbf5b2e925c9b65f659827dd364cdfbc9a41396e3eb46d1bd14ea9f5e9b588207ece3aba1a47b7b6bea78a577dce68ed5d4e09de7f38d0bdea6f4c959e583904018a1a38c8f892e08e834320863463b2948c833e14092235fa5f44c3ad4fa52345f80817108fdb5ca3d3be03945d0300d94e41bb50ebd06669be7149ba1bf9ed28\nSHA3-256: f569276d41918a004b784087cc6db0612a4f92571c498b29b66d4c15478f5795\nSHA3-512: 0a25f1cd6de6ca6dc2474ad38090e3ccdc9a58cb3af850734a70007ee18b54fde56f0655d4f248ae7ea9f5d4f1a8945d0157170b7c2e22a7b9de5e09917bbc52\nSHAKE-128: b7a89fdff826619c52ff1977548dd18bb8eeb09f16ad9f01b8a558ecd245b96e427e1db0b6106acd2c911f0855f558509eae1a092ca4465bc00606d29f16fa69a6722f8d16ca5a08e89bb31e63f183e07adbcf0179be8aa0c62b1af012eca0e961e800fde6aab1790b27b5caf89178a8fb0da37b7953273011fe1cb8052a8c69e7a8f07c4f44d4deedf26e6e202a9b73216f52cb1f3af5398dd3a95beacd124dedd94f5504b45550a90593d6e8ed80911f8c52c58b2bcfe63ea390f31aeda2f01526919051122ebabce99403b3ee1e1f11aae1b38d5a08004bcb4d736e7f5b1bde1e12f2c4b79a74e54e85de0da41847ad225e50a2e2543459a56a7b55c29d1ed95c6629e33a9e0b454d74bd1128db791e8b90fd8054018eb67c936af9f99fb3e92d09c036016a70f81e180b43dff206fab5395326b64dfa3a7bcb35464e3bb879c5940c03e4f31fd0432d7e39ce733e7e2940340c7409a998f9e5e7e6d70540fd6fceba48cd0bbee1f4a76d66dcb3ac8bf12cfd71b9888af2407942a3cae3831e87638e5279fe11c0aed09a6f8385cda47a4a80abd5d0d0e215fcf2a8889c5e4c4177a88fc0c99df6ba383ecfdfc04bf895c412cf2f564b91ad7bff243919db0b9ac10b10189098d33a0927739e937d9b0624d4fb2aea00fbe4d30e208235cea9ab0f4f063f5af92525402cbe7f28b26769b648bbe48984ba712de587d650c1\nSHAKE-256: 34eb9386312120558cbf34d22d3aa996bb015bae890cbd67afe975e777c26e4409eafa2f0525c4b22903e1345ddf88eb5e7573d5a9273b9e64dc35ce46e5e1d06f44f86ae84bcfdc9aa2c8a0bfb0cd86d479cee2b54bf9b5c588be9245d5a28cc7922b7cf9cd06f19e3a6cd35f754386f23d5fba1a7e406b239b709fe104623600e0caf87acf242574f6656c6f5b117a1df05c0f7b7fd60319fb44df93dec4a59a9785ac63276e90b6c87f920a0cec601548cdd50efe3adb3f4ea03958ff2bd4c1fdd8edf5301396008f93f84b9e0b2c5f0eff48f7be8240584a41bc54812a8a9ae9aecb2a0dbd0f596a43f3fd5314a5053b8b05662d4498d75c1f9e2fdcbf4f67cfc929cf1aa6b31dde5db4a33e1d4baee4ef850ea3194a597d28dd014aea57034cbdd278bfaad22bcfdc8d6ca59c86c28aa721751bc70b0b0e8d1035247e9a07910240539e77e17dabb8c4c7c8d92a8a0a86e3f797173939778561356c42ddb2847a7f6317ac020eea673e34d566a99cc8fd037ae46a399dacd60b8732ccf7e610c9d3f34a599025974d7ee28bf8f550e744ee6bc1421b29cbf5ccfd0298d870b399d878de8d7334bbef21fef4e728fb6699ae28ff90bd5850e0f37010ae9c5181e8f66d57b9b6a3dcc3748b0367e197954f404f74b040a4ca4fd5a67b9101dcc65ddc76707d9b798008de1e525438a46ce69f11d0da92eb447a70b6881816\n\nInput: 8caad50e95b807f91bf02b052805e6cf09a412c35c39de0b00ac54409c4bea9177af23861d1a74efbdba1c90642268c487056d3d0c133b33b9c896ea9e39aa903bce7c64751ec1ebc67381093010faa0b0334fd932ca08d9705a3cf4bba85048a565127072238168dac7298115fcdbc969eceef673a5091211a544c23e5dc9e7351f37a6679f4b49166b55743414769fb782359ed5c25b11054bca3537b91b9b177f5896f37e7a16cef2d707b4ef27e68cf56983474242a5b37243082ae96501f91d0450759608c06525fa806e", + "4ed33dff4ccba0c4244ac63500e5c09520deab693358b697ac5884b122bee86e9a2863a1a7cf52df0f8fe1fd43b5c1da9148c552efa02baf536431dfc3b2393a60e24f0d93f77c3a7f95320b44a29f194c804341345cc32caaaa1f78e3219a16c35939ca79a80c954eae5e236755ae6549d8d1484f5e14c3f5c6fc9da8333ba96fd022e931f418d299958e2985ca4899cd7fedb0189018c04680d26dcf8b831db06fb27267eba1290b696d3e03809374690f82ddc661c8331466f6ad4cf9ea21acf4bb55cf92e95ef988e65a64223ec1d0bf91b36f9d5ee58ea964de85b62ede7814a63b296191688083f087abdba9f77f5b5659effcbf07ee969305b2db8379e5288117d4f7b1f0d29d5f6d26409b4912587076ea7633d1c2a3585cdcd5926b48de9b788a43f6ec8c6971fe1e\nSHA3-256: 36c413524d1d21120963a2a8e066cc52e34739806ddb1aa09873a9d20e7274c5\nSHA3-512: 079e76bbc9f9123188729fccb49b46c1216c501416683443b9ace7a70391c1f29fe6c7dea23b788c3386a7587a24eeb2be2d1a28643697156369b7ee0eefd72f\nSHAKE-128: 3ba84f080f5868f6033761086b6994e51d26b37d9948c3d0b946b82a7622dda5a19affc6929da3b4ae298c269fe3fc49bd3802d42f535370d3418b17d2ec23d5f33dadd8d5a4077453680ce13c9342a7c50d02683d769866b921b47929faf7cff605d4569f71ea51a084e7a156db2e300bfd0a39ef8780e68713d48278c902a41a97f131dfa08d5f3a955d52bd99b4042ef778887a1eff558ddee2d63c4015126068d64f758c635586edf24a1b15f6120eb6894432ab97d5aa3580a1941093a100b337aa2a1398c92e592a39f9fb84aa50ece2b39d3ba8bea4867bff7b6a985ac7b4958029699076b38b7219f8bc09d2e90de438c01a56e33092c582fd94f0d4bdcd2937d68fdc45a7891572d0ef6682825496fca7326acb779bb831e953143e431db2dde49cf69d00d493cf8e8265278ef90e0bb59848b74de75e57d0d7825a9b69742199b37376b281e66b105725ea95c86392436b5944e33fe6892627e85dfcb0612d7707cfac59e4aa631af5c4f31b719e1b27a4e53e9e68e8d7aaafc639095e4434368427d55db137a75e46d5c04428a76c64633efaf3fea2d40725fc0e80396358ccd678508c3bb63571b5e196b13ad4fc9dd17227358c174082b3e9c939154e08fa79626fbbeb51cf22e2b0defbbd34a062b1b6f1b11ce8a2452389357c38790f678e55e6dea6aae7d48494e46afc47a285e6b8a2d240e4d26cf5c52d\nSHAKE-256: 443636b286aafe10736cc300e90a42ecfa08df05691d2371c3bf193bcba18ffe27ef1a1909ea09e939d686f1c9bdeaee42c2f1eead2be16cfdf7f6df63c54a7fb83cbcc0df5920f3df96e8387066cc202878ef129fa0f1bb0fb5587261032d02ad02ed40e95f8fbcc81a6aa34f9a7fdd7ab11440873892e8307f11e9c37388c976914e764cf48ac4432233c960afa17b9c0df5961096df69d321b7bca434b6b30b243ae50c7aef8c2f5d0ae3107faeb4a56fd56d5d4edd39dfbbd660f51e844826fa533ece800ba086f04e6bc6fdf4ac4de73f1678fd918d12328d8f25c1b4de44381242f218e5a80043e09573b0ba9acd49d783fdbed33feba1c954bc80dd941d956c1b059b71cfc54ec45847d0310885d6a954abaaa7e5a17f7829685eeecadc98912aa5ae747d6e29283640bbfc7f4d4af46b273a62edf2a1dd9a359c0c0436fe84276b467f600bb7120a1b6ad85219093c3f5aa11e22e96fb35a4e2bac0fa45ca6cbd1b6a2b75e75dbf24ec871b212f42a3dc4fd6a683a4295e68c4be6cc506eb956ae68e9b54a57a30caeb2f5453e22786b50703517dbcc9756b03a2289dd0059093bf8852686b9bed16ee734eb9892164e944b7df74cce7b4f2783d867a7d564b564a5a203c764f93e3c17e76b12f8b115f10aaf417d8fa6b2e095832073a81cf3177980fe48ce15bb46d3aa0238c9dc6962f3403011a7cf552d677c98\n\nInput: d0889c94ac0b7203acaab8d75d2cecb09e67623caab5bb3bfac8f83dc03771c7434af638e53a1ceecc4a6c560b040eb3b6613220878a5333c1aa6fa087d04dca91fb4cdd6efa90de2289247fa834b541e638638de816aabe92b6a84b8ef4f952149758ae0e50c27c304a2c918a757504fabc261b69a300f295dede54d77d645665126542386808510a7369155ad5d6fd4a428a0ea5b2eb8eaf08a1a624ace709ad14baaf3e1a0dc0c09be39c97b2c24543c8fca8bcc105dd6eeed36e034e52f680578011e2a5a5caf7624c192dd6b052829a560eb0e6200caf861c9431f768b4ba0357ba7bba8b43e9181e175fb87819928b5ae801704794b17464b0327c4fe84f6d030fe7c21d851a873861567113efe0573dad95a972afc079c4dfbb7ec178df324a77e77324608312c778d7b356156d59e1f4329e5ca7b06013c98f198ded33f0ab7ed6d4e6abf23dd28a40cb2ae613e7435d084376c4459ac47246598ca438de09ac9c6eb1e7a7c3466c43a0c3bb178b1d255863e048084d05d9b2b404a0fee8fc687c7cdac702a93067dead5f3d0d4b5f480eb3410504dde6e639bf7e106b4d6a8e2478bf906beacb8670a5a86d2e2e5314c87969f08de9b4c7e55883623f4f5b20a36288b41216bdfdcceb0d1e77a069a05e909446de064b07053b9b2fcb8192838f5805ddb90d0f25496b8ce7f432aca7e5e4abd133d733\nSHA3-256: 96de1882dcb62dc049e8b7a1ae6bf22d2502fd0e6fa8324a745880afe02d40c3\nSHA3-512: 523091240dbd8675d09dfeb0a8c5948cc408968744152b3267a54c242550e5a57d708e2e1858b34d9e6a9f7e90f3f73aa8742162217c9f8e754f01318feded74\nSHAKE-128: 97c03041d4a7e029e1f65537d2ec53a14af4f4df7ae2a8dd6f9d517a3735cd7a734683f2663da6d51f83d6524b8ade4984216cb9ac08723de2554b2f9087124bcf052cb82088c9a81b1bcfb47d17b991c2a308fabc2d80f8a6f3f87973e13fe0923d620aa4966251e88736f30ecb71518778eae9c948ce36317a77356af3ec9a4f4d2240fef0ad5c8af418fdc980ea21525fb31e120229597ddfbdf976d0b21f535da5ca2c4d9ce4dd4af9115f28b327114d4f7d6828fa11f4cd54cfb895c86b83b6633e0ece422a1cf1d00c016a76db9fbce2bdb718917f658f50c48f3daf657dd40188a2751dc6b06029da0f053dcff6b48479e5e2fbcdf0629abfcd243109201b67ad8d7725e0a30d6acfeb31852ea2289bf481962ce4709e995fcc2d38064a109a02b2284ff3cfb48fc4b2904d20e9040c23520f67ae83db1848e75a38c3bb1dc2125d91d11f60ac9a75835ff072505e5e54ffa64ab8dfdede00e8e9d2496c85a091024014a7cac4944a44a894af9f7abb0d7e0da47900ead144947dd8949c2104162307de9a926c891de5f7a405210774d150a6a62dee7b9ce9fbab792582940255f78b501632f9755d1696d5cbed21087570218d6d14e764575337c377e858fd0cc4f219b321c32d1a5c5eaa6ebcf5e3a25e08116c8f5d52236778738ba9a24c65dca537a1ed0ff1832fc6720125fd6ede4af19107e7f4ac6488ff2a82\nSHAKE-256: b27c92e87da4a91875e27eb7142e50854bed565dfa8d9dd9985557f181ae32392aadb641e83688a4143693bb64018e65703109a856df42f2afb651e5a87b176ed0a93efdb6830a7752e1453c6ed80252159994e900334745849938e08435cfa38fd5fd2df2ee65b0b204a3c190c8cf8b644e5cc58102952bb9147c12abcfd9a787e80870e90642d8f92319847050551e48b93dcc5d6c276f61cccdabdc3204a687dfdbb506a926e4c9b5aeea8b14d8d000382433449c4986514967d7287dc754d3dd35eb22ac8439af244687fea193a08fa1ef3d85ab0127b5d3cd696c6379319c30f36c7ca6a7ab8a9ced2312f5e0deef075a12fec60351698f9ebe4e8c2912e9a08317ca0fc13606337fe94a8c0e9b3b4ef70e40722ce96e0e33ef92cf8a7206b81cdd2140bbedebf4043c550368d0da222c5b91300648e816b4ce0a1b0716b4c6b895ad4681f0d4c345101973e1798bcdb150db2d5d6485bc99d06843960360322e6aa78b2e44de2db6acdf340144d077623e9352935c7ae4ef94e072db685fe7bff7a9ab1754f3654e53f7b4fcac58ca200a5fdcff9f3dd651fff961158e98c48459c04784c83066ce1443f22a4ee641b547755049ad42572ff5ed96f29b76472aa26bdc9009b28cb51ece42b155479019a2a0e24e9799da923ad41a4d665565765e7ae4f2d42f0d175e26a4d3d849d10299acd6318c62f74e388a052e9b\n\nInput: 41029e77d71d9d2fc348d79bb41f4445f9cb45fa77f553f37a03cd14776780102e89ca63a6e8246947722aa29faff22b8e39056171c86e418ffc65db776f429230a4ad1a1c93322bb0c4f5a73b0da4f4e81e7b7ded078c9e66156800024f7c37af75a0b9c6411cfdd5ac572901c4504c6ef6c481919fcb86be5b43f512ec0fe7cd13b4ec12322b8bc5b2fe113e1ce65ea04da9f425cc688b43ba1eec4e9bc4d9a9d97e03182e4deed853d7215f9b4e5a1ef229408fa2729c9e090db013554b0395e72febb608e5f9005b0e72949d379e85900dabf3c1906420074811defde645d4e44c314e9aca5532d52f71864092b2692f73fc4197a7c612f3085d88cfdd8a99f7c7d05c5552d53b89a529d21e4524e0103ef4ea7fab1bfaedc0477c03cb984ee9c62816a27185ba6d61d1874f47b24e7b993676d79d07e874e19a646d543dbb96aa722551b58ee7219542638252f216cb7c228c1a5434515e6de0573632441ed135cccbf6ed5e510cb728a931a69f9320cdec5fccad066701bdd348981438e24615768f686046bcf1002f19444c271243b6f0659b049545f705ea635ee61f9dfb6d44eb258c9ea2a4f50b3307746f2f61b97fb73b05784fcee419d8982662a30c02a38014a8864ddaf350036765f9bbb60d8ba0667777d66642fe9c85fea0fe41ed243c21026c76291d75154357fca56e90f3c746e60c8013ad64\nSHA3-256: 5c239f911cc201bfb5274dc8e474831a8b211122767f70321507302b1b6c038b\nSHA3-512: 28622f0532258185f6dc49f785e9a2cd20ac871e15ce9e44f18924ab3e1409a8e4e25e21caca23b3de9439893e2dea3d15540328d1d3d14eb4398d0edd82ef0f\nSHAKE-128: ad5012e0b759cb8c445cd4f5d0f98c0787dbc5ad72810d0b27bae565cabc2205d8ec43fb9db2ef58540090007d9ac641578b40fa02b2b002f1c0d941a13aff1134975a6d34413c00182521f7a87cc1074d6355caa81c6fbdae2cb35271ce93ab835bb9c9d27166a7cad28fa74a90d1152e536c3fcdaea086cb341beab282f4599b8b2c50fa2fc2acba17e37df1c370fce369acb4bb1ead3875d0f3e93f57f74302d4fab11947b20b15e57e7942d0ede2884f83b10ccebc7d667dc0fecc9190ebdced1696c0c6a50dcb35491a663ec1845a9306afd9794082fdd485913e451173b871da7999e5b5300e8a0083887ec4d5e46246ba98eabf56976d7614460f940297fe903c8217d95a0b8737e93b62171af650b8c3adddd58a098db38f4df53d1cd26e0acea92fa5bd75d37880c6a9313d85a306a2d97cd45d5aef6c5c97444aaef7c93918732e08e6ed9df241abe8762492f50e5d85e656c872fbbbf30648004ac2bc402ca370f13511c6a984ee5f2cc5010936e2", + "b2fd4be1b948c8eaf8ad790679e08cca0065a849da5e4038166eb9fff0301b44db645206c3c76252515f0b3e19b0ffa690db8e431296760afd4589f292bf5aed03115f92acac150b71a3470f4dd3d33f8784e1cf0a6d7e19439361ec1de96fc0858350ba3b04a2a798de4b67098b5e4b4ef00c8a22e458617ca36ffc8d59ec0906250958bd3c8bbc5870e718\nSHAKE-256: cc8caf92486e7f9720e735eda0af34c606f65b854129692e7ee6a8231b520925adb5b9f5d599e5721a4ca4dac74f2bd1a9cd066ce827f90c6d35bb4e83432f441885b84b909e70c10f19da5688425f076cb8deda4233e99566becb205101710d9a3f10de9104b124fa974e0ed0b4503d2205bae8ea06ba8635078f5e2ccf93c10d2c7c608d74cc9cf1b4334631304ff1de23ff14b2750512c99e597b55e22510afeac209e412bb0a2bcfea62f5497263ca413516290d1a2081662b612a0305a1cd60285ab92786b82839711a19fa79a48bb3fd4022d565cb3255204e3654a7f2e61c53ee54a8b865ccea6bf6d2e30ebe9c30f5bd948ccfd636304ac3fe29656992e510b8a0ff0c3d6b1433faaf7049b959b65393dc8eeaab26ff16d836d53ec14a248b548cef84cd328fa8fe53c69611c5e2ab1b6c6f0c8beffcfd66ec4b7f8defe7ee6690e5411398305eb5a26a52c73b75643bda05871c88ae5f0272fdbe7ec40806071549bb2c19434cd518a1cb8ec5dc3f3d8f28e6ed5503c89fac6e4a4429d4478ba64ea54fda56f35623bc877a761ed926fbb32891c231f41577e11ed983b6b34f3a2df95ee35059c58285ca85a31c9928b72e08c95af3862cb22fdc69322153ce1d35462d4b0b2c45ec955b46e8a83e594e4bf84152ef6d64030965051062608de8681d147b0b4db6168022cf17cef7e1f037535bdc576d346a43b49a\n\nInput: f5e94186ea504a9c836d32f9ea85e61afe9646c2093e5387944d626e213be9b839c136ea24e2dddc1f4ad0e64f8892213698493a067efc5d5461b8a1d78029e7d7c8430fd32d701d19a4a7b35f360f3299eb3f8577ec4aa6f34c130b02d6f8bb7d86566864210634b5c1d6b73096cd297809407871aa531b68be0124b001045fb2cf6cd458b5fdf769dcefadb1082453692ba8fa940e7599693164a2f4d174f258462cef379ebe5f68c0e98fc1f12173744ec759541f03ff501c5d4a704cf4acf6df5050e524c28a550db9e40c642be26c430eed401f9a8327f3aa875b6f13edec522c257a487cbc6cce036cd83773c4f4f86963216b1389bf7479b4a09190f82b5ac677db1c3b63b67b863924c5371fd881ccd8814ae9b9a1c9f6297c73c03b2bc5cd6d6f9794d8c232a6018c3a98ae10b6517749fa131d096cba733748d4f5ff3a78f58556408f735978657c0629d31dfb29a05ef1d06bd3248d6d5a33962794440ce986d79e4fa031c35a918101c58951d86d561611644ba49cf9e121cb95ff82b2655b7e313349121c2784a3f8098ea0e1749e9f403c90bd74ded17c952cae1b8f353552fb7e47b97b7a4de139c6d5d2403f955c2d1db9f495aa5f2e1155713263ed42d7c96e8dfc37c85b7e89f4fe86c0daf5cfe0db50bc9208b2a179da1035f20b033588f2b2b963815eb118c2419b77fb106f47e7361afefdbe\nSHA3-256: f2ba8762e9507a75f6935cf46fdebde3d4d2023312c08fa951334b7e2fa00bd8\nSHA3-512: 66549e37d7287d0c76d39a3a8ac2c5f073cf45bfd8f70936ec1580120184b397584b7b6f5f666839208fca4667207f5538442f545bb2de01ada69268afd3a90a\nSHAKE-128: 8ce25ea63e76d706951716b09c58bd5e79f73d6b858c7219f16bee3850ab85573de91de627a0596490ad980edc8053537b35fb46c0d2ace6f517a61181d99c0560e8105d982b1897a396a125e7f239c129344706085c356d29d7984f63a056c01c80df283580262b90a492ff1eabddd503c2c77edb550cb45637a649e4b3a5fb2945a10ffaa840788635df8df6647e5960af7757a15303cf75769c21cee9d49b5feb7c8184ad2833ed849da20626ed938d6f0bc8789caecf6337250eac570bc22ab1ffa67d5954eab9b1657d10546fd30f0265169a0284416fd9d2700de8a0b68485912ba6e30ed09dc5aa049b3fada66de1f04a20a99b0001551a7330e02afb77e627e8855241a43f93314b658d5c00c1b97a1c3560353d439de842ea93d15bb494faf3c820063ccb0ec2edd9d03fad936bc0b4c49f005d0b6d1bc7ec730d74baccc803a4b8fbccaeedbbe2e78c3974be9cd712bafad361d47dd57fa3519b9f02e1cf41a1bed523ac9452bb6d0f0d94d34838df8a70b0e8326a077196ea3eca112ad2d8e0c6318a077f79ae13f7500d985e9e4881989e2b29c6ebffc4b0f52d97ad27f4f378ad1771b34faa74954c3475c6b5dc344ccc9e085c3dc84d33dce337371b34796491226b7ec6ddd0bb8ec010980becd3655ebd4934afce487e6e642b4547aa85ba60241f56e9779a1cdacc4814e43d900189438ab13fbf159619c5\nSHAKE-256: 74f527fb3fb0d239e0a615ea9492886faff24db03ab73a060344c30a8480ddd8a71a1143c30b38387002e973119b7b6118a1c1a1f052ea4c92e6a270f34c04274ff667b3a01632ce688d12d70f61ab01f5511839b8fe8574682077f1593f3e5eb08757b4e245a69748e450b543a1b3ed5aba6781c5acc383081312f74818d5dd796172ab6a22041ccde168158798dab8891db9095e50d78b53469057f37f04b10fe4a0982653211fc7e18ab45119e018150ac51496747d478941b247e661911d71424c51b16647e14dff8b77d7f0b6f4e7cc483a161f84874a142b58f17f6b56e133a353bf9ff4ee7c76baf061a09736a682e715c6f718366df0373083bee6fba709de9ee29432774d871a12b11348e15ab75d6a7c539aae95241cd7484c7eed382df0ec5a89a6304f02ce3fb58150f012c7463d76c0e182bd31e870f78138ee1db9f301a80ad6a0a0966fd712796ff95ff6f5feaedadb44fa3506c238d49e025bd8ffdf842724ba5ccbf1e42c1bf6c3401dbd97cd1325e92e1ab6a678199b9f42b7a6983016b0cf492aa3a82a0a271f69b927382fbeb5f84aebe8fb5f2077a7d81a3949506b306032cdd0b12c59272df703130b0751799cffb1121672afb40ad3b3fdab88b0ab370d37967b382e129b48ad6df7bc0f88b94057b33f8d9c7d61862c05e24f67e29642b38eb2cc702c8de41256fcf761a010e250daf3095691d4\n\nInput: 0b747b5621a882829c350b45c0e4462eb367fc185a22faef6ce92ff203a42c253e039fbda10251a52c93afd5679fad1cfa4b084c0655cd4912f9a98e794f520d726858a6ebc0db4cb0cb381952a3fedd4df80c9b6dfc37e2259ae1ba6e2bc124227fd4e8cb49f3404fbdd4490b05013908def280ce882b4d85d48bcafa97b3c41802a7d40e0df359f98f59c6a5129579f3ce5123125a1e7ebe28ae9642ed9f463b034c9adf8d70b25a3ea7696e0435f8b7e7c8c0be0549762e5de6e142751470a161571790874130829def39f4144b40b9043652af8f547914e497fa2806745e11e22ab19bca735b497d5a8856596a37899d6b3c08c7e9cb7e3b65422266bc9741da457180eb1559f737fe50824634280a24e05400a32f4cc1f13b211b21a799d2915682b4ba84cde34cb5cd1531ef05827356a0a92e04c3a4a85f38461815b9d008bf6071aebf952adc0867871a4923032e6565dde803740de02e0edfb0c9b2c8f56ed6b4a8b504e33bc6d84c6f747b4c83a8b60b07fae5b15c53bdfa14d18f8eb335beb0bd28ea0baba23b7903c9f27a83420904a9a2884f74094d2650a9f1d5139fa434b7097767041bcacb74c01f25276b5cbe707e98ff3e29c833ec58a3f3659b7f0eec8d506c6da3432aee90faa5b3e4c8876b385310c01d56a586b89c02a036a3ba8da4bf4af7642e912788166e03cb326482b4ed43dbe2995598\nSHA3-256: e35cb485992a4bcd27f71af043b8bb16c7c1e3a36a4d1160980d51e49b650a15\nSHA3-512: df7918b9094bde46e50778d46c268249517b674252251cc8dc0b6bd27d3d7e4017463f57c78ca57e048361b406321adf020fab26ca2a75a977281a06f4c012b6\nSHAKE-128: c6b9414d60943abb0344b486ea62d6b34dc6b6167882601fb0863566235197c38f414e906f7624a1e7276d83537c50521a033a436578dc21a7f9f30847d75d22cdfffaa04bc867030f4582149bde9c5d14748e7162251628abd5e9c2d406284dcdf03cd0fae773669f27febb86bcfc835193f0f72ad2346387588541c2437174fbf0fb3c268b675b2763545fdee92ee0c9c357e761caea60b1ed77f26781b60e41b47c87e54b22c7b67b8c99fe49005552b85d02b7183988f03d9610fad3e44342dd97efecff9b7ae9850af873af31ad067fe7b80bafc1f0076971247eea57e28b6dfecaf3b15c559305bd06527bbb00eeef112b0c16b9845b80385a5f2656cf3c90acfb01c511fb355ce63ef7aa35fb004d876867c737cb493e6a9e85e2683aebb95621eb19968a6c0d63930b4bf902a6b8e3b6131974b273f2a49c4bb452d453b68915d35c28ea2945d11fbf2f109086da7a1af9e944bea9c182ee4e74d742a31ee7a32406d72345245a1434cf6d9f52f7dbc8dc87d2f84825bbf72dbfcd8dc9c6c30f90b0b1e269350f69dbfb5739d05b965c26d38838de8dd5fa041a81eb3253f3123a3cacf51cc14d5abe46db1492b2bfbc427853d5b4d4fb9f548b17fe5bda87d08ff5fc06b8c817143ce8f0acc7bdb8f9a42523d0c407398c2958a95701d8c29efd8303e93e0500dac15df31ad06375a0f6ddf63436a9b2ddb1c6ddbd\nSHAKE-256: 1fc37824fb86b751a3cd26aac6235c445ea5cd0a7c1f7ced0fc8af41a985c830fd6dca5aae34eb3c0bdffcacca58d0a8bfe677c8799854902111a1c4cb86b518acc0013b65cdd146cc4aac42cb3959a17aac1ef686bd4bc62f3ce778df22b89f12476ea5e5f63d8266e16f0f0ca816fe816407a4d742c59801ff91ec5271c6ac3382e3b5c9ec913c0bb796c11e2156edb601a9150e5ec16c5a0ab100efd1cf1e3fd2a9da5ce4c07815575364fd2a361aaa42b7dee815511f45b42777bfc5fc8873d0d47b9b83ff66e4ada9f0531738956a7e00bf956a111655e9085b792dbe76ad34ac93cba7b8fcd7b4f61de067a7c32d1e5528dd71bb0ba804b499584bf99a1b76bb5c5fe4eda28b7d45f9101f82703054ca260f3fcbd9070d71ad55f9e4fc69a624904982e7c937691776978de3878eb2ed65a122ca0dac09b55b8b28276121a9c301c18e1797c0cf7b573ba97eeace1c808fa5c24819cbbcd0fc3d5b8826505d4bb84eb1f820419e088c45f8787539ef0a6ebdcaae8f18d33df73696e50486c6311d9c31f5353a609f1420708376d483c00e1353432bd8b4799fd1d99ca201138a2de110fe54b4647f5b63d77f5c6d4dbf85bba533c296ef17ade3713d5509390d10b6ac860cfdf2b0a6872c9c9a7d08e89e1a5972ea58a6685788e4613a44fa3ae0a52fd3331e4a7bf4103691197ea3537f8e307b9f2f4fb9def21a96f8\n\nInput: a98d5c71ed25e354f9df148a2819ec43a5bba6f469040675282c43b91253a23460e7595520449cc8d4cd4da5ae259ca696d0e4164a170fb10344fef80770dcd8894e22eb41af07183a5238d0f7dc30b1c9fcd7b64f91c75f419f3f05b6de81fb57ed9318690ea57e95f95815e9eccf2217b8d89ba81874d", + "671b5b00b0706407b6a127ba6ab142cd9fa83345224e3cfe82105533c87511396e00bb4f6c34a9aa18694a0965b4acb3ee8320b6c8f106979142cb2549e4e2e489cefc7747a7d31285a7570b0edf02c63e3babe9eda1f2f14d11185e19b11dd5950f7e51270ae007e5b059ac03bda1767587882223be12c6af2db6aa7187a2516975cba5134825c315099514c9180625095be91e92d8a1ae9320cc37668f3ddcaea46cfe99414b59ee4d284db7773b21e6e33123225c6039a6707e17c3373a5814c5f2d8f5e34cb4c1a9742fb79ef0ab315c3a6cfa1b60e1c9e346461087410cd84369e141c86ea1cb82520b27d65a9155afded16c8f78bc70be88976323ceaf5ee0e57c54103da79327d2fe767821051cc96e64ffa6f3a5ae7d7ae05b23719301575a68c352f8cdebce533e4ef85b5fc48d34133deb606db8522fbb87310ae0296e77b0d69d1391175ef21733f0b655a554485a1ce98232297ae6e9cdb2905eb4cda87aa949d0dd86b0cd63086078a2451c8baebdefcfa03a0e4c7ce9974020411549d1b7a151f\nSHA3-256: 9379fc3379d734aa4bc9462dffe1ef4d6a0990dd2b7f7c962c80de66096c255a\nSHA3-512: b07e25de63d2a244b8bdb473a551dd44a6c5e41da72061062a42a44a7278c6aa678b8c127312ac265eaecf354b0a0243144d2de65356a885d29ceddb7951cf89\nSHAKE-128: 77f56c76c4f40d6a51f7b4e3d19b34e358e8a1ffb14cca68f23f1608c95358e1e64581d297a7a062c06db103f547486932c1c43fd95cda0e17168afc0a703993e52d0e0251f09c0a04438c84613bd9806fa8777112fd6d6df5ce97db1c68e58164bf1a764c1a192ee27c97eb313b822d5a5fdc0b8a911208ec051d76395d7756784c23ab7e0e98a21b00123afa74371b9482ad80378419b9214e3b4ba49bc5bddc24aaf175e6c678a86eb42e1f3a12deef554481cdca0b0032dfe55749fbdd09d3eb9f792df57357f2cdc3aa215f01031db33598efcbe183a52e4b4dccaf19e2d79ff220d075af9fd5f16bf73f783754b75110268919041969e7bcf6be326695aa4bd786c94bb22873c3f99061f932710c9b66f9403470a4ee8a4489199162817eb72b5ae3b457c35dc973c6a33aa3e5feba69108e98cbd67270e507f6558d8c973be74ee782d4b0b91714ecb55ffbb7b13dfa60f02fe4ceebb535814449048f4c260e98e8b80e5002b46b3e7c752e43f1616b8fef82b50f894182061e91cf06cfd42ee23bbaffceb8d2ba93acfe242f68dc980e857ac1d71f25d7fd7622fb50e6a8c39f5de9c70f4e2d0cda35a8b4713d4ce7aa96437032c5a2569be19e7ef87405b14ee0107ab71f731a2bc014c2691af1d8f2ccf456505c3d42d6eb1af75168b1cb4db9a35d29c9b2ca7fa5c444bcf8035c816354f6a4aee63e0cae8c7c3f\nSHAKE-256: 83158939de50f9c0bef1c8270affb75cb13f23b84742f6e61d36961e9c1596fbb1b2fabeaa7e42db160befeaa74f82374cac494070a355ea2ef4b2c51ccaba715040214530f6ae3403fd3e999bc7bb57d5af3e1fc1248576a055cdd0c57d6774e6100ce42cc94e874896b9acacec248082715229acf1989a8f7cd7bae1e6cf0b1934a6a8a7b867fe269531157468de1005205e6cf7f749fbbc7d7cbc84e938e276828430b2e42a4726b990d63198d93a8f2854100de586e3d0af355f24895e3754cc2b24b80b2be9c8c33f269ba7159e2c85f6dc32c4436343f226a8983926db9c62bf5a45e61ee518564e431d685d139fcc2511bce799af60c7119de67bd7eaa6bfe58bf1e056305ebf10f737b3970bf4a72a12b9d560f0d0989cf981525f8756d297ea7fb40dca79bf695736e2a97cacc943cf8ff1cb1513bd2f585746932011e92d477a7a923ef31da315ad3908058d16d3ba1e7f87914c8625866cc23ce891e01b5066178f5eb19354c5149807c555d7d4839ecdd5b24fbc2aa3a0ad0801aebbeff872d2de5af1bd39e780ecc883fe070a2ef42308fbef4bc031b763cccfe108d3509d1f8b115019586fe711d0f76435d2e560e50542da472cb32423ff71b754e4b993fbc6213adcf729e4d4c6c725c0defd22e666c7ec6a66ece8e555d0f332b640ab5f5146a697c24f46c7dfe4288143c8024813f1e678d30d54630909\n", +}; +static const size_t kLen61 = 978389; + +static const char *kData61[] = { + "# Kyber768\n# From the NIST round three submission package.\n#\n# https://pq-crystals.org/kyber/data/kyber-submission-nist-round3.zip\n# NIST-PQ-Submission-Kyber-20201001/KAT/kyber768/PQCkemKAT_2400.rsp\n\ncount = 0\nseed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1\ngenerateEntropy = 7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f\nencapEntropyPreHash = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615\npk = A72C2D9C843EE9F8313ECC7F86D6294D59159D9A879A542E260922ADF999051CC45200C9FFDB60449C49465979272367C083A7D6267A3ED7A7FD47957C219327F7CA73A4007E1627F00B11CC80573C15AEE6640FB8562DFA6B240CA0AD351AC4AC155B96C14C8AB13DD262CDFD51C4BB5572FD616553D17BDD430ACBEA3E95F0B698D66990AB51E5D03783A8B3D278A5720454CF9695CFDCA08485BA099C51CD92A7EA7587C1D15C28E609A81852601B0604010679AA482D51261EC36E36B8719676217FD74C54786488F4B4969C05A8BA27CA3A77CCE73B965923CA554E422B9B61F4754641608AC16C9B8587A32C1C5DD788F88B36B717A46965635DEB67F45B129B99070909C93EB80B42C2B3F3F70343A7CF37E8520E7BCFC416ACA4F18C7981262BA2BFC756AE03278F0EC66DC2057696824BA6769865A601D7148EF6F54E5AF5686AA2906F994CE38A5E0B938F239007003022C03392DF3401B1E4A3A7EBC6161449F73374C8B0140369343D9295FDF511845C4A46EBAAB6CA5492F6800B98C0CC803653A4B1D6E6AAED1932BACC5FEFAA818BA502859BA5494C5F5402C8536A9C4C1888150617F80098F6B2A99C39BC5DC7CF3B5900A21329AB59053ABAA64ED163E859A8B3B3CA3359B750CCC3E710C7AC43C8191CB5D68870C06391C0CB8AEC72B897AC6BE7FBAACC676ED66314C83630E89448C88A1DF04ACEB23ABF2E409EF333C622289C18A2134E650C45257E47475FA33AA537A5A8F7680214716C50D470E3284963CA64F54677AEC54B5272162BF52BC8142E1D4183FC017454A6B5A496831759064024745978CBD51A6CEDC8955DE4CC6D363670A47466E82BE5C23603A17BF22ACDB7CC984AF08C87E14E27753CF587A8EC3447E62C649E887A67C36C9CE98721B697213275646B194F36758673A8ED11284455AFC7A8529F69C97A3C2D7B8C636C0BA55614B768E624E712930F776169B01715725351BC74B47395ED52B25A1313C95164814C34C979CBDFAB85954662CAB485E75087A98CC74BB82CA2D1B5BF2803238480638C40E90B43C7460E7AA917F010151FAB1169987B372ABB59271F7006C24E60236B84B9DDD600623704254617FB498D89E58B0368BCB2103E79353EB587860C1422E476162E425BC2381DB82C6592737E1DD602864B0167A71EC1F223305C02FE25052AF2B3B5A55A0D7A2022D9A798DC0C5874A98702AAF4054C5D80338A5248B5B7BD09C53B5E2A084B047D277A861B1A73BB51488DE04EF573C85230A0470B73175C9FA50594F66A5F50B4150054C93B68186F8B5CBC49316C8548A642B2B36A1D454C7489AC33B2D2CE6668096782A2C1E0866D21A65E16B585E7AF8618BDF3184C1986878508917277B93E10706B1614972B2A94C7310FE9C708C231A1A8AC8D9314A529A97F469BF64962D820648443099A076D55D4CEA824A58304844F99497C10A25148618A315D72CA857D1B04D575B94F85C01D19BEF211BF0AA3362E7041FD16596D808E867B44C4C00D1CDA3418967717F147D0EB21B42AAEE74AC35D0B92414B958531AADF463EC6305AE5ECAF79174002F26DDECC813BF32672E8529D95A4E730A7AB4A3E8F8A8AF979A665EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922\nsk = 07638FB69868F3D320E5862BD96933FEB311B362093C9B5D50170BCED43F1B536D9A204BB1F22695950BA1F2A9E8EB828B284488760B3FC84FABA04275D5628E39C5B2471374283C503299C0AB49B66B8BBB56A4186624F919A2BA59BB08D8551880C2BEFC4F87F25F59AB587A79C327D792D54C974A69262FF8A78938289E9A87B688B083E0595FE218B6BB1505941CE2E81A5A64C5AAC60417256985349EE47A52420A5F97477B7236AC76BC70E8288729287EE3E34A3DBC3683C0B7B10029FC203418537E7466BA6385A8FF301EE12708F82AAA1E380FC7A88F8F205AB7E88D7E95952A55BA20D09B79A47141D62BF6EB7DD307B08ECA13A5BC5F6B68581C6865B27BBCDDAB142F4B2CBFF488C8A22705FAA98A2B9EEA3530C76662335CC7EA3A00777725EBCCCD2A4636B2D9122FF3AB77123CE0883C1911115E50C9E8A94194E48DD0D09CFFB3ADCD2C1E92430903D07ADBF00532031575AA7F9E7B5A1F3362DEC936D4043C05F2476C07578BC9CBAF2AB4E382727AD41686A96B2548820BB03B32F11B2811AD62F489E951632ABA0D1DF89680CC8A8B53B481D92A68D70B4EA1C3A6A561C0692882B5CA8CC942A8D495AFCB06DE89498FB935B775908FE7A03E324D54CC19D4E1AABD3593B38B19EE1388FE492B43127E5A504253786A0D69AD32601C28E2C88504A5BA599706023A61363E17C6B9BB59BDC697452CD059451983D738CA3FD034E3F5988854CA05031DB09611498988197C6B30D258DFE26265541C89A4B31D6864E9389B03CB74F7EC4323FB9421A4B9790A26D17B0398A26767350909F84D57B6694DF830664CA8B3C3C03ED2AE67B89006868A68527CCD666459AB7F056671000C6164D3A7F266A14D97CBD7004D6C92CACA770B844A4FA9B182E7B18CA885082AC5646FCB4A14E1685FEB0C9CE3372AB95365C04FD83084F80A23FF10A05BF15F7FA5ACC6C0CB462C33CA524FA6B8BB359043BA68609EAA2536E81D08463B19653B5435BA946C9ADDEB202B04B031CC960DCC12E4518D428B32B257A4FC7313D3A7980D80082E934F9D95C32B0A0191A23604384DD9E079BBBAA266D14C3F756B9F2133107433A4E83FA7187282A809203A4FAF841851833D121AC383843A5E55BC2381425E16C7DB4CC9AB5C1B0D91A47E2B8DE0E582C86B6B0D907BB360B97F40AB5D038F6B75C814B27D9B968D419832BC8C2BEE605EF6E5059D33100D90485D378450014221736C07407CAC260408AA64926619788B8601C2A752D1A6CBF820D7C7A04716203225B3895B9342D147A8185CFC1BB65BA06B4142339903C0AC4651385B45D98A8B19D28CD6BAB088787F7EE1B12461766B43CBCCB96434427D93C065550688F6948ED1B5475A425F1B85209D061C08B56C1CC069F6C0A7C6F29358CAB911087732A649D27C9B98F9A48879387D9B00C25959A71654D6F6A946164513E47A75D005986C2363C09F6B537ECA78B9303A5FA457608A586A653A347DB04DFCC19175B3A301172536062A658A95277570C8852CA8973F4AE123A334047DD711C8927A634A03388A527B034BF7A8170FA702C1F7C23EC32D18A2374890BE9C787A9409C82D192C4BB705A2F996CE405DA72C2D9C843EE9F8313ECC7F86D6294D59159D9A879A542E260922ADF999051CC45200C9FFDB60449C49465979272367C083A7D6267A3ED7A7FD47957C219327F7CA73A4007E1627F00B11CC80573C15AEE6640FB8562DFA6B240CA0AD351AC4AC155B96C14C8AB13DD262CDFD51C4BB5572FD616553D17BDD430ACBEA3E95F0B698D66990AB51E5D03783A8B3D278A5720454CF9695CFDCA08485BA099C51CD92A7EA7587C1D15C28E609A81852601B0604010679AA482D51261EC36E36B8719676217FD74C54786488F4B4969C05A8BA27CA3A77CCE73B965923CA554E422B9B61F4754641608AC16C9B8587A32C1C5DD788F88B36B717A46965635DEB67F45B129B99070909C93EB80B42C2B3F3F70343A7CF37E8520E7BCFC416ACA4F18C7981262BA2BFC756AE03278F0EC66DC2057696824BA6769865A601D7148EF6F54E5AF5686AA2906F994CE38A5E0B938F239007003022C03392DF3401B1E4A3A7EBC6161449F73374C8B0140369343D9295FDF511845C4A46EBAAB6CA5492F6800B98C0CC803653A4B1D6E6AAED1932BACC5FEFAA818BA502859BA5494C5F5402C8536A9C4C1888150617F80098F6B2A99C39BC5DC7CF3B5900A21329AB59053ABAA64ED163E859A8B3B3CA3359B750CCC3E710C7AC43C8191CB5D68870C06391C0CB8AEC72B897AC6BE7FBAACC676ED66314C83630E89448C88A1DF04ACEB23ABF2E409EF333C622289C18A2134E650C45257E47475FA33AA537A5A8F7680214716C50D470E3284963CA64F54677AEC54B5272162BF52BC8142E1D4183FC017454A6B5A496831759064024745978CBD51A6CEDC8955DE4CC6D363670A47466E82BE5C23603A17BF22ACDB7CC984AF08C87E14E27753CF587A8EC3447E62C649E887A67C36C9CE98721B697213275646B194F36758673A8ED11284455AFC7A8529F69C97A3C2D7B8C636C0BA55614B768E624E712930F776169B01715725351BC74B47395ED52B25A1313C95164814C34C979CBDFAB85954662CAB485E75087A98CC74BB82CA2D1B5BF2803238480638C40E90B43C7460E7AA917F010151FAB1169987B372ABB59271F7006C24E60236B84B9DDD600623704254617FB498D89E58B0368BCB2103E79353EB587860C1422E476162E425BC2381DB82C6592737E1DD602864B0167A71EC1F223305C02FE25052AF2B3B5A55A0D7A2022D9A798DC0C5874A98702AAF4054C5D80338A5248B5B7BD09C53B5E2A084B047D277A861B1A73BB51488DE04EF573C85230A0470B73175C9FA50594F66A5F50B4150054C93B68186F8B5CBC49316C8548A642B2B36A1D454C7489AC33B2D2CE6668096782A2C1E0866D21A65E16B585E7AF8618BDF3184C1986878508917277B93E10706B1614972B2A94C7310FE9C708C231A1A8AC8D9314A529A97F469BF64962D820648443099A076D55D4CEA824A58304844F99497C10A25148618A315D72CA857D1B04D575B94F85C01D19BEF211BF0AA3362E7041FD16596D808E867B44C4C00D1CDA3418967717F147D0EB21B42AAEE74AC35D0B92414B958531AADF463EC6305AE5ECAF79174002F26DDECC813BF32672E8529D95A4E730A7AB4A3E8F8A8AF979A665EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922D4EC143B50F01423B177895EDEE22BB739F647ECF85F50BC25EF7B5A725DEE868626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F\nct = B52C56B92A4B7CE9E4CB7C5B1B163167A8A1675B2FDEF84A5B67CA15DB694C9F11BD027C30AE22EC921A1D911599AF0585E48D20DA70DF9F39E32EF95D4C8F44BFEFDAA5DA64F1054631D04D6D3CFD0A540DD7BA3886E4B5F13E878788604C95C096EAB3919F427521419A946C26CC041475D7124CDC01D0373E5B09C7A70603CFDB4FB3405023F2264DC3F983C4FC02A2D1B268F2208A1F6E2A6209BFF12F6F465F0B069C3A7F84F606D8A94064003D6EC114C8E808D3053884C1D5A142FBF20112EB360FDA3F0F28B172AE50F5E7D83801FB3F0064B687187074BD7FE30EDDAA334CF8FC0", + "4FA8CED899CEADE4B4F28B68372BAF98FF482A415B731155B75CEB976BE0EA0285BA01A27F1857A8FB377A3AE0C23B2AA9A079BFABFF0D5B2F1CD9B718BEA03C42F343A39B4F142D01AD8ACBB50E38853CF9A50C8B44C3CF671A4A9043B26DDBB24959AD6715C08521855C79A23B9C3D6471749C40725BDD5C2776D43AED20204BAA141EFB3304917474B7F9F7A4B08B1A93DAED98C67495359D37D67F7438BEE5E43585634B26C6B3810D7CDCBC0F6EB877A6087E68ACB8480D3A8CF6900447E49B417F15A53B607A0E216B855970D37406870B4568722DA77A4084703816784E2F16BED18996532C5D8B7F5D214464E5F3F6E905867B0CE119E252A66713253544685D208E1723908A0CE97834652E08AE7BDC881A131B73C71E84D20D68FDEFF4F5D70CD1AF57B78E3491A9865942321800A203C05ED1FEEB5A28E584E19F6535E7F84E4A24F84A72DCAF5648B4A4235DD664464482F03176E888C28BFC6C1CB238CFFA35A321E71791D9EA8ED0878C61121BF8D2A4AB2C1A5E120BC40ABB1892D1715090A0EE48252CA297A99AA0E510CF26B1ADD06CA543E1C5D6BDCD3B9C585C8538045DB5C252EC3C8C3C954D9BE5907094A894E60EAB43538CFEE82E8FFC0791B0D0F43AC1627830A61D56DAD96C62958B0DE780B78BD47A604550DAB83FFF227C324049471F35248CFB849B25724FF704D5277AA352D550958BE3B237DFF473EC2ADBAEA48CA2658AEFCC77BBD4264AB374D70EAE5B964416CE8226A7E3255A0F8D7E2ADCA062BCD6D78D60D1B32E11405BE54B66EF0FDDD567702A3BCCFEDE3C584701269ED14809F06F8968356BB9267FE86E514252E88BB5C30A7ECB3D0E621021EE0FBF7871B09342BF84F55C97EAF86C48189C7FF4DF389F077E2806E5FA73B3E9458A16C7E275F4F602275580EB7B7135FB537FA0CD95D6EA58C108CD8943D70C1643111F4F01CA8A8276A902666ED81B78D168B006F16AAA3D8E4CE4F4D0FB0997E41AEFFB5B3DAA838732F357349447F387776C793C0479DE9E99498CC356FDB0075A703F23C55D47B550EC89B02ADE89329086A50843456FEDC3788AC8D97233C54560467EE1D0F024B18428F0D73B30E19F5C63B9ABF11415BEA4D0170130BAABD33C05E6524E5FB5581B22B0433342248266D0F1053B245CC2462DC44D34965102482A8ED9E4E964D5683E5D45D0C8269\nss = 914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29\n\ncount = 1\nseed = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F\ngenerateEntropy = d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672\nencapEntropyPreHash = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046\npk = 6DD406B49B9CA035467FD26C6C0B824BEA310F435FBE8BBBD3430B5C39889E6B117E994E2F08823A33789FF858B72715323C6204A241D9835EC0DA85C5884A8A96210219099C8C383C182632280356C1B4F298405258A170E81624E861FC1082D31867A9037E3B90B0AEEAA064D27020DA7BA79398FA92A963A8A294E7720BD4CD9EA213F08063079C4D55B094BEBC4E979444F462B967972E61206FCC80337911B02C7396BC64405FFC0B77CCCD2EBC121A734037CB90B77846B2359C30A451BEB20A6D72C238284E5DF2AD1CC1A33FD5A104965C86251A596360D541240A4828231A827A0168B6D8AC7E27328173886453A9C91498765C2BD9EA9F666BB4A1D60F992538A1A746DF845574F99ADAD23B9744AFA81C7FB79A32B175706454438F46B8985132B8E1CCA10C2B0FA011EAB2428B88CFEF9378A5228E55D7463DFA5022C998ABD6354118B5116B3BC1004F0008134B85A1CF2A9F409A10E14B6D06C26D8E355864C35BC71B60D5CAC33A513EFDF6B9BB83BC880983682C8FB8A81B6927CA52E93835956795488181A8CD82B1A50DD18A25F35E2643CDD76C282E7018BB99624F031418FBC8052C4179B43A5998BE9A20CD2D8A883B313EC282598202ADD6471971C88CD9607D3A8052519930BC5BC71CA4652352B4D02620B8D983B9849CE8B8935F1A4DECC3250DE7B0CFCB49EB7B74E0B5792AE97633B092081C3C6BF58F1B242CA07610C3387098AC3F0F9043901C614590C4EBBC64CE1971E824694A999CBCC430AE923A1432B6A4911162213C429481394A27006B9D48C0AB5801823D756BFD8C6919502D613594AEC81F5669BD4E8495292606959292467CCAC7F688333B3F48A39FCE5C42C9C2653886A5ADF4747CC943B2416348F46DF5B58E4916BA64E9664A4BAAA3E0A9652408C8E5076C226C3A7932C42A846949A2A26B4E2C452F86CACFE5C201AE1321AB5C2CABDA557648A849241F077A799EDBA3582202CB27763047219F5546CF18819322B9C63974B322B949BAA491D97C70F20545886C87086721D3CA2AEAB441264B516975ED0C6044A425853528424532E4D721E85CB0BF65C26082C790765B062916FAC4A0DCECBC2E900C6F600270838E2DF20EE0A907E3613DCEE049C445640362C980A292F123C6C9B5918F21443C996016C44D2A124C5925A8E0C48E89BB167A129FCBF67ADB89903E1249F6028BC176BACC722366139858E583EB582ADA714E79B5AD1BC1A6F18754E100624620968D0702E080BEFEC425BC16B650A307802004C57590897C87E65347F32C324569051D798BEBDB421EB28B2D1A0C662444C7DB32BF97845D7225C7539F457894EB87606FA85B5E804053FB6ECDEA773566C006E540EE65101D99BF314181D666680985C78B103DD00A040DC69CFF389FEA7C18E48A363B943FF042B476DC86BE953A5925076CF749A62A77A9406165D31DACDC3A677B9114D8BF84B43F59F647FA4023535140FDE04285921184809C5F193A7DF45F62187854061A4D6754DA528F3B71A134AA487D9B5F7CFC6838108B8B95B51F5540C9EA5F29990F7BE07EFD502461033F103723093A16DD96C098977F81330249183CF35A636841BD1A9B9796F13F56BE785D942D7EAB011805CF3504FCE325B6A5EF1AAADBBB11C662B9D2\nsk = 94B49EA42526935245C45A7D580B6AEFF8BBE0F5342BB8BD2550212AD5935F45CBA7CAA6DF914007FBA79E9946C9433A86A2C4202BBDCEA008AF78975E6619D3582787530DBB7318A530B7B5A27D24258C7CCAAAF505CA92CB853A5818D4269BE812BECF169A05E71EB957557787C2F3B72315281DBA87476B157A06095A30D52B388AC22840755B43440A931DF8A709DC435B415A7BABBB04CCD93CDA00CA1FB090646B1D6514813368A794D38C907163B5917496B018C519B160C5144D6424495626E3A5AB9FFB8D8D3168D77599A88A1D12C07D86498D88DC1AF7FA7DE15073FD4B62801C1A902B215E7CC3EAC350BB63ADEAF9C7594844795A9A6274AA3ECA0CD10891F05795A77B30ADD76B6B1A35338B8156690CA2EA1C9C3B602B23324925314F726535B36DFB355225D37E7C85BE15A5976A8A6AD4E2C35D4C45ACC954368BA6DF88A47DBB8C782336F7EA507A6C2D26D952DC03B4BFB89872644084783AB493CD72D3BEFC2C803B692729638AF69B03E6DB9B82E678A42969FBE770FEF65723F77DA6437C20B203601C884A9B9E08C0B1DDBBC1A66517DCFC76B3F125F7795E5DDABEF0CB00119778575513E05AC38A7901A0E8C8794685C0F274050097BC50168818A74ABA5D71980F5C76279EC0214CD51EFA8A21391567FA052E6DC0CF9BF216CFF9287C80693645A53D71B3D7509F6A432D51B2B0AAD129B594278DA74FFACBB713357D735A744B7C65E482B7E172C67A5B4EDABAAE11222B8BB6B4564AB4FB20C28B4981614B69BB188DB6056607E089F64803D89210C7E604266B00548A2AE27996196A6D6F762C27B22731F7942543CCEF3856EDF9AD1B1B1652A33C3E038DD9B2CD9A4612CE174315E67B26DAC767E50E68508D104BBAE1A2B89B78266D27B109F90BCE1581A8B8888C90C1C4EA5FC1F009D5073780CB4545087C88026B9B9ABDDAB923DB52620713C8B5AC3301E8715AC39D13084926E841FAE41A7BBB7912E10680A78C0C363A251720B2D69467B6CAC5D894F862595072A7C9B14BFEFAA2FDCC75CC42892CEC6184B52962B9B73D663B7D76C1EA499D538BB45A4CAECEE0C8EB93BBA5EC1A8C936156382B10102E3211B2DC15663412805F60590EC33DBAB80D2A3BC05FA8AF5145644F712E004C20F799650159C40DC952C9A54C27E816C3A6A95EFBAB24A31F6C402300F9BAF88A46644B4DF8A24979E80DC30425B9E75A753A36510B87C5FA95CBF36E19A12245876003B54D4E008EF7AB9D83C5A2406014B5CC33B6167F4C452AF45084B7412EC19556D82B0A6A90C1AEA60A72312D8A7A8E5060189717094FF950AF2B503988964F0AA227C523487471D3BC905B6672BE20BC714729B7A71478B07A19F777DEC546C624723AF7B5F6C142274AC5652A7C2D7ABBF1171F2BDB12F1ECC876681A600806D6FC229E6A8F6424419187BD22E49B8F27486DB25371C169B3F61E81131B57659B1030A959790BA5D6424580B1F588326DB9CD01A260B21B8C42062B883854FB173EA7613764D41DD6B89468C7BA6C4236D1A0436B945B8B340983023139293FC48C07659B955453BBA07B0EB4E2A91F594232A47C65C66E1C5C8279F179925C55EE3A0B6DD406B49B9CA035467FD26C6C0B824BEA310F435FBE8BBBD3430B5C39889E6B117E994E2F08823A33789FF858B72715323C6204A241D9835EC0DA85C5884A8A96210219099C8C383C182632280356C1B4F298405258A170E81624E861FC1082D31867A9037E3B90B0AEEAA064D27020DA7BA79398FA92A963A8A294E7720BD4CD9EA213F08063079C4D55B094BEBC4E979444F462B967972E61206FCC80337911B02C7396BC64405FFC0B77CCCD2EBC121A734037CB90B77846B2359C30A451BEB20A6D72C238284E5DF2AD1CC1A33FD5A104965C86251A596360D541240A4828231A827A0168B6D8AC7E27328173886453A9C91498765C2BD9EA9F666BB4A1D60F992538A1A746DF845574F99ADAD23B9744AFA81C7FB79A32B175706454438F46B8985132B8E1CCA10C2B0FA011EAB2428B88CFEF9378A5228E55D7463DFA5022C998ABD6354118B5116B3BC1004F0008134B85A1CF2A9F409A10E14B6D06C26D8E355864C35BC71B60D5CAC33A513EFDF6B9BB83BC880983682C8FB8A81B6927CA52E93835956795488181A8CD82B1A50DD18A25F35E2643CDD76C282E7018BB99624F031418FBC8052C4179B43A5998BE9A20CD2D8A883B313EC282598202ADD6471971C88CD9607D3A8052519930BC5BC71CA4652352B4D02620B8D983B9849CE8B8935F1A4DECC3250DE7B0CFCB49EB7B74E0B5792AE97633B092081C3C6BF58F1B242CA07610C3387098AC3F0F9043901C614590C4EBBC64CE1971E824694A999CBCC430AE923A1432B6A4911162213C429481394A27006B9D48C0AB5801823D756BFD8C6919502D613594AEC81F5669BD4E8495292606959292467CCAC7F688333B3F48A39FCE5C42C9C2653886A5ADF4747CC943B2416348F46DF5B58E4916BA64E9664A4BAAA3E0A9652408C8E5076C226C3A7932C42A846949A2A26B4E2C452F86CACFE5C201AE13", + "21AB5C2CABDA557648A849241F077A799EDBA3582202CB27763047219F5546CF18819322B9C63974B322B949BAA491D97C70F20545886C87086721D3CA2AEAB441264B516975ED0C6044A425853528424532E4D721E85CB0BF65C26082C790765B062916FAC4A0DCECBC2E900C6F600270838E2DF20EE0A907E3613DCEE049C445640362C980A292F123C6C9B5918F21443C996016C44D2A124C5925A8E0C48E89BB167A129FCBF67ADB89903E1249F6028BC176BACC722366139858E583EB582ADA714E79B5AD1BC1A6F18754E100624620968D0702E080BEFEC425BC16B650A307802004C57590897C87E65347F32C324569051D798BEBDB421EB28B2D1A0C662444C7DB32BF97845D7225C7539F457894EB87606FA85B5E804053FB6ECDEA773566C006E540EE65101D99BF314181D666680985C78B103DD00A040DC69CFF389FEA7C18E48A363B943FF042B476DC86BE953A5925076CF749A62A77A9406165D31DACDC3A677B9114D8BF84B43F59F647FA4023535140FDE04285921184809C5F193A7DF45F62187854061A4D6754DA528F3B71A134AA487D9B5F7CFC6838108B8B95B51F5540C9EA5F29990F7BE07EFD502461033F103723093A16DD96C098977F81330249183CF35A636841BD1A9B9796F13F56BE785D942D7EAB011805CF3504FCE325B6A5EF1AAADBBB11C662B9D22CEDAD700B675E98641BEA57B936BD8BEFCE2D5161E0EF4EF8406E70F1E2C27C003271531CF27285B8721ED5CB46853043B346A66CBA6CF765F1B0EAA40BF672\nct = 68F11F4A8D07DBA08EAD094A93BF00141CED64E2CB3E68A59987CA3298E259ACEBB820650F861C6AF5FA565920825AE4A61A5395CEA7DDC6806E7D15D42635C8177E17A9B7110118C3FBCED5B2A73EA79B86D5B41D92C14C0302B6B1B9DB25CC2F923B32CCAA054C7B07E58EA2ECFE4F0B17C97E4E5571E04ABF67468B6DF3B64AA545B7E348E45DFB18BD186C7A17C7A3EC326E65BF7BB025D7D23B14F733698FDB79CA9CFDB85AD40F35170D98289DA8190F50A25FAC16043377736664411767C28978664444A2DA6F630D0FA54230F0DA6CCD158C5986921A356A3BF528C996A767A44FF765967A06773C4F392CE9209CBA2CE05DC63A43D1AE40C2E86DAA0F56237962B058E0D40DCE5EFF7AA165B6A9D1DFAC0D19BBC0A94466EC53DD1E28A8B01722E28C761E8AC0B97ADE7CAA0447465C40A54BA799F8A011EC1BB0E7DA7D4362215F5FAB54373791102FBCB77480A805008A5E89E6A74B15257B38BFD906841A841A475F47720AD19F34409ED6BD37C2BCD7DE06E4E04181116D0BB2050F9C60F635FEE337DCCAAEB870BA7494CB2CA590570720DE061BDD6B522EB09313EBB927BFFC920E649D98E5A4A86C2C5E3815E777F302802D98B6C616E6FCB784A16D6BF8C8AAE9BA44EC43DE816084C4C3BB1B02A603680A64FF1AB5CD8AF48774C5B5057D6682CFF3E265A63E551A20633DBF5BFEDAE646CCB99E872274C71BD61E1A518E8A2657B1FFB37701BA26B1AA36B109D75E399AF0F07D321A8E839812E6CF8EA29E95CBA3E6737F6F2113D8990ED939F86082CF5A3877144A8EF89FB5C0FD726A88DA00E986782C53D313212A9A2D20D012794E9A89866367C10EDE99EB8B03F30C376B50E7009A51F2F44082DBB62C4AC91F53399838BFBFF7ABB851C969E9003AF3FEFD138D7C5C4862F524FD97F95F9E6B5CF8CE949F748239F6DFF3535D24BB704EDF896AA06515DCA4FE776B987FE7C742CBB2DE50CDA6A2BC99455CF741F58B094BB832F2B645112F11050E1A8CB2F770709ED3D58A284012C9084CE6DE8372246CF4B4861D2E43516483E7B66F6EAB1A6AC61EA0B85F7103D9FDDA34AF13C5674ADB690EECE71CB7EDE7B02CEFDC8B052F2C8905D60D57B58576C8E9CEE41D00B7C51F8A97237716617CFC3D554D56EB2AAEB13E018C334B6D0D7A68B3294D475B910E860F17E9BAAAF7FC85FFACB18BCCA3230507AFB91620061F2FF221EA8614BFE77E64838411D7988745BF103D37F93D3E48C9B93577F1B709D58F386D110979B954B41095D58CC25E8343B1CC03C5A103B39433C844154CA9D0EF7D5E8004A44F4500BD06481DC6B8073085657AE915A3322E6CD27016B1091BA8D78EFBC32C70CCBFB8E63827D5D875302006A4554F6655D9C2104189733BF3FC5388B978304A23248D24FBCEE7BBCC9501479AA0BC19DD5C4FA6580993F4EDF4438CC7EECCD8622231C4925BE40E9FF57DAE6617BDCA8E964AAD894267DE70B45C414280F643F6F23ACC9D142CDDE71F624D69238D45B5FE54\nss = FE8AAA6558FD8087DD7CAB54B4BCE50FC625A369ECACE58B2EC36F3BC5BB4F5A\n\ncount = 2\nseed = 64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868\ngenerateEntropy = 4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade\nencapEntropyPreHash = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9\npk = F5A35B4EC7538B62289DD1204DB91AC492B610538C93EB5F2637AD97DC88F0035FF3CB735CEBAC9BE7CA78A4149CF10B6D93283050167E737596B711A9F32A0F6909975055CE6632F4B42CF9A2361CF69047B5BDE1868DD745A82CF473EBB30D86A71793364F70B1255B1C2003F166683C936A7977DF156A84051E69B95E02616DD3090DD38086EF3BC12353BAD25377618965C2810FCA929DFBF46F20360FC847818CF90DBC044EED16B3B9052C5C70A5A430441E53A5527A689F49B35CE82B84D6057C5269FB60C710C5731F431A970B86431125910277FA7C310A2285117B47B95054E4174A1EB11DA3E3C26AC25619D36712B11B2EF7405BCB943DBA10D50C0436B50DE5B04D96488A38F53DF37895AC20C10D959D81A29FE1F319FF871831D93C54654172A02E65599F9D820AB037438E62714BE6C7D868B66AC03C31C8753A062318CA36B6E59D340B9696D47C38F115104765865353A05C8FBC4B0A62A96577E94C17094DE259006F169E75B8919BB4C37DF6787B59BEC8FAC999A90B73123A5CC8772AD67585C879EBE05B5C06AFDB440ADFBC4AD400D0E634822A843E9B165F2F0BB748E231C0E0CEECA8806046B5DEA7CAC614A5E2CCA3767556448785DBC739CAA9C58FAC291A0BBE96E9AD36A4A1D9C96939603BCD76A81C040FBA27A5A39A1C387CAC9D1B086E512468D378E96039AAE2622FE5483673850D411AB64B892F2C29853822EAE76FEAF5716A660B55C2020DD3323A150CEEF9AB79925D2BC09CC6FAA31727A5912A7F5E9051F8B94D8866C4DA173D3F2A388E6C44218338CB85702CBA2F602C24E1788158B0129E7C15DCF2CC6ED55C54B456CACC07D179B432A5AA63E8AC59F0B6979A833D99C13AA0C56CB65928032E2F30583FA6C038748CEB77A91C631DD09B575F13126F1447CAB00BC9C85FC7601DA44AC5FEA5ADCBB599A409BB1A67B24EF438D750BF87A8814DF22449C9256DA1286DC623E81546C283B80CC88C48F003678AB35380A6DA551AC7041CD5112D59D15A80032C28B61A1BB3B8A7267ADF4662B5963468B3BC5918418F980CD7DB3946C5A67F864DC1F3ADEA12142FB71FDA590E070007662B5C3B8B31AF169A092A2E466AA01AE879641BC4D1D62523CCAA3ED436CC089B2621456114215D1A9EEFD1016DC81D5320956FD942BDDA40F3A033E5170CA6A2C57CE17EAFC97AA0959CF37B92E789636F159FAA827DDB895553540D52A61EDC1B3DCEB22A7231C48037CC78594718902333D0BC4FE6B29352991E2BA5D31217457007057B9D3C07C39B7C7EEECC222D4415D6D9272EC50B81520BC607592947C86D2612E434C22513235536CD08F10022B97675B89F1DE58130EB6797380F6B68773DFBBA0664BB7CAAC84F7B06711587C6ECAA383505F62751C8346BDD502A58E9326E4A0D2D29226F794AD0064B2CF0A56E6A67C18B331F5537D2FC6C3AEB52A5C3313118CB7D159B8372158C1A7BFDCB65D426458EDBCF8797383E272D3B18BEE68C4D74E25751AB1CE4567D66B714CD62A8E9B886BAA812A9F50739E30F296791414727D55003BCB52AB6BB74CAB215B348AD06F974192CBD61576BAFFC815999AB8556583024CDBD1C4398F4A4AC60E8CB68627382A145F91BE9D78FD51BA5E3FCBC3155B62BC07751DD\nsk = 72408D44C2BE6E83C803DA2846D852DEC1848EE41504B5C91F774F6E512B51F71DD1520203C486F63240BAB4C1DBB212299753B8627F9BF2117CD6A83BE4075A385782AB804A420972EB25BC553EB981AAE7D7A715111338529F6116C10B10BBC20B31C3161D4BC1A5F050220B5584ABD6A546AB51A9A10120ECC131220502697E9D61BDBAD346FC43824135692204B49B5B377B870B7B28C86946077A215ACAA11ABD851ECA479988BC69CCC9975EB42A33523C525434BC594217912123957DCDC18E410A6D6A811BED8A0B4135B56F4562F343AAEC34396BB0556D7962679A76934B016B4B4BACC14650C55C3AEC9BC2E85B548B5D3EB891B6596F0C44009BD0982D98BF81AC77C8DA98264A719CD8568E48279DF9C8E9552B94AA773B43A70742C75F041915752551347F00447D72D934BEC553BF1014F4276015E0B4DB77CDF8C546AF05861804A5B7D92838744511AC6C8BE55E883ACB7775B98C4B4C9C8789AEE317F8F02B4127A6AE879D02C13772A003928041C53351D8D70CE59B14CAB5CA31D717F69129C8FABE46582CA5298ED156209C25BC57870EEA34255CE1B4C426211F957D74876DEC169C4C516C8716B3DDEC6C3E610C31F0C52E13650F0B1C70124DEE27111A76ABEF82C8FD3172D554121E6A87E9D3B58E11379CB812B7F4B95D46104934CE75C715771204D7C46AA9439836453BDA709CEF3BC1C9341994F25C48B5C80FCC8A67E316C431BD302B20904456B3283E9BA1BDDE494CE9F8A3F0B432DCA69D0BA9C43C703E1616272CD6B904D5B6279C55A539B7E46A601B28493E38A2CD9BA66D997C8C5C3B7631822C529FA48835F8A08F322615E96B9087C71C9F262B68851F00486489D25C92221C2759C89440CE733614B8C7A06F26B374CB4F8A6A7D67DA521EBA7232C0A4C066886B8450755896CFF77A369BC8FD4B3B5B0731452A908ACC68366B8EDBA66D09F212C9330C83990AB2DB7095D708B6C3589BF929FEA31534646537D2AB023887FC286F00F46F8A360476998E4FE7315F03C234929247BBA2A05297A5E01AA9CC6158458E2302513274A2E3359D66126F5FD44D348BA2B634642EA26C6CB616F64A2D2C819ABAA48BC565CA0AB67E6CFAB1129A0144C10A003B44BD3879B4E62E0AD3A58BD86A7030BE34309F3309642B017B0AA03FFAB4012B36ADC49A95DDBA67CD81306EF6BB20B546BCC55EAC2B815FB38BAE991D6AE7AA87D42ECBC740CC816A3EF42E9D204CA0177CDB30CDCB870386C320FF51B137578B029125BA518A5B887D7B9050DFF113468608F6335EA81A59B87CB753724ED0E159FA4709AC018A31194247A6A9C65443A35AC36E11BFA6A8559CF20E50116EE5FB3780FA03DCAA77846B18C04894E50486ACFC3B8FEABB8CF860D79C2734A700AB731739244580653699B51B7FC440B8CB1D6BB1360291BDA5B11AEDA3C77A25B40F96763A372", + "512561E0D52848FD6A3A8241DEA49C4C24692CB43AA22067072FAC2DFF7898F298CBAE17F9CA68A132321932295161A1F31C178932004D17854D7D9C69F6640EE216747102280191A5695433763B6CF3B86756AAE22A37F9F6920C361C2AC68A7E11C8F5505AF2100651595BFF5A35B4EC7538B62289DD1204DB91AC492B610538C93EB5F2637AD97DC88F0035FF3CB735CEBAC9BE7CA78A4149CF10B6D93283050167E737596B711A9F32A0F6909975055CE6632F4B42CF9A2361CF69047B5BDE1868DD745A82CF473EBB30D86A71793364F70B1255B1C2003F166683C936A7977DF156A84051E69B95E02616DD3090DD38086EF3BC12353BAD25377618965C2810FCA929DFBF46F20360FC847818CF90DBC044EED16B3B9052C5C70A5A430441E53A5527A689F49B35CE82B84D6057C5269FB60C710C5731F431A970B86431125910277FA7C310A2285117B47B95054E4174A1EB11DA3E3C26AC25619D36712B11B2EF7405BCB943DBA10D50C0436B50DE5B04D96488A38F53DF37895AC20C10D959D81A29FE1F319FF871831D93C54654172A02E65599F9D820AB037438E62714BE6C7D868B66AC03C31C8753A062318CA36B6E59D340B9696D47C38F115104765865353A05C8FBC4B0A62A96577E94C17094DE259006F169E75B8919BB4C37DF6787B59BEC8FAC999A90B73123A5CC8772AD67585C879EBE05B5C06AFDB440ADFBC4AD400D0E634822A843E9B165F2F0BB748E231C0E0CEECA8806046B5DEA7CAC614A5E2CCA3767556448785DBC739CAA9C58FAC291A0BBE96E9AD36A4A1D9C96939603BCD76A81C040FBA27A5A39A1C387CAC9D1B086E512468D378E96039AAE2622FE5483673850D411AB64B892F2C29853822EAE76FEAF5716A660B55C2020DD3323A150CEEF9AB79925D2BC09CC6FAA31727A5912A7F5E9051F8B94D8866C4DA173D3F2A388E6C44218338CB85702CBA2F602C24E1788158B0129E7C15DCF2CC6ED55C54B456CACC07D179B432A5AA63E8AC59F0B6979A833D99C13AA0C56CB65928032E2F30583FA6C038748CEB77A91C631DD09B575F13126F1447CAB00BC9C85FC7601DA44AC5FEA5ADCBB599A409BB1A67B24EF438D750BF87A8814DF22449C9256DA1286DC623E81546C283B80CC88C48F003678AB35380A6DA551AC7041CD5112D59D15A80032C28B61A1BB3B8A7267ADF4662B5963468B3BC5918418F980CD7DB3946C5A67F864DC1F3ADEA12142FB71FDA590E070007662B5C3B8B31AF169A092A2E466AA01AE879641BC4D1D62523CCAA3ED436CC089B2621456114215D1A9EEFD1016DC81D5320956FD942BDDA40F3A033E5170CA6A2C57CE17EAFC97AA0959CF37B92E789636F159FAA827DDB895553540D52A61EDC1B3DCEB22A7231C48037CC78594718902333D0BC4FE6B29352991E2BA5D31217457007057B9D3C07C39B7C7EEECC222D4415D6D9272EC50B81520BC607592947C86D2612E434C22513235536CD08F10022B97675B89F1DE58130EB6797380F6B68773DFBBA0664BB7CAAC84F7B06711587C6ECAA383505F62751C8346BDD502A58E9326E4A0D2D29226F794AD0064B2CF0A56E6A67C18B331F5537D2FC6C3AEB52A5C3313118CB7D159B8372158C1A7BFDCB65D426458EDBCF8797383E272D3B18BEE68C4D74E25751AB1CE4567D66B714CD62A8E9B886BAA812A9F50739E30F296791414727D55003BCB52AB6BB74CAB215B348AD06F974192CBD61576BAFFC815999AB8556583024CDBD1C4398F4A4AC60E8CB68627382A145F91BE9D78FD51BA5E3FCBC3155B62BC07751DD3DBC65B722A8982D058E27D409F04F744551ECDE9015B62607CF67BB8ECECBB8E82FCC97CA60CCB27BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219ADE\nct = 972B0906D175A187EA54286F9929EAEBE5A4F147DDD71CEE94EDC0FE2672884EABE2E09DCF524EE839A08CE037E6DB27B0E232172C0B0B02784C57E13B52CF29C7F38D60CFCC0032A48C1198B02B8FBC01BEABB54378FACD94ABB9CB8BC488735CB826944AB2919CE853DA9B9B3CB99829611802EBABCC6CDBEFCD6EB5F65C9CF5871CA093214EAC807904DEB63B700CBE68D54B676B7FB489A04B050585591E4B2A921194DDE55684DDBB86AC1B52ED882DD0C93EE672C692FD94D8CFB0030201DF1D34E227A4EA150174E0FCB6A0FAFBDCA499306C752E8CE6521591F7CAC0BFE6BC77F8284BDFD36166F46526584B78FA94F645C805B7DCB561574237F2340836BFDBF367B2FFBCEDC2FBC6C974F157D99393AB842E1106F2ACBDD660EFD1082D016DA6C4D1260029DE92A37AC87E3A1CA207650644193335847BCF48A4074E6306F5FC2EA28E0379E844F6B5C00B9ED56E7E4EA35D7123254695A2670C5FC465AE5CA630BC1DBF187CFC3BF5F855ACF2855026A53790FC1EDA0195F6E32DEF74C34D0404FB51990B5AC709068BB55E1C4B3D30F8150263DBB9978C8B194A5DF5B8FBBDF4BD1E68A032ECD3F2ECD94EC3245AA702196E357BB30CED0EFC42B425E00D206817AD467EEDB156F23FA760C1B7A156E1A37A4AD95450A193DD1183BE571AAF14AE7529C534A7F6149BC8FE1567563D33CF153480A990C44383EC362276FEA37431AA3DA830EF0273591C526D9A0604E1672936E157E4E646DFDC5A13EF2AD14284BD8AC344565DAB3B45C9858EC2F3A8CCD445A4610D80C5263234D2E6F57DC7490D621566DDC0145488253E22DA3061E7645773BC2F95BBCCF7628822C3A861B8829F0F85AE2CEB1C4B4CE87A50365F9369BE6BFF74556644BC131B7A062B94D6AA662651625735689E70E19407E68F3AF50A4506A8FB345F84C81C0330516496E5940565D148975FF03FA4AEBA113080861FF63F9153200635362022418C9E28AECCED7021FB8E650D07A8639FBC0A84B5AD21914BC4C4475AD4C8F8A127C024DDDA9102FEA90187A6235E3B689A31403D0CDE12F6D7AAE4D1DFDA6CA09F9D78FE141DFF66C483C6028A22DBE6BCEFE54E07D9F58B4EED7515AE2E1032F6CC01E8C2AB9E417FFB3123ECA3EB0665935CEDA2426BCBD93F8386EB0B7457DDE5834483BE7BE3F25B133D76B2FA823BBD4A0356AE6AB87BDA1F807A00EBDDCFF68FED900A3145C3EB368EFE091BF271FC7488166F34EB62961FD9806AB91F15C726BF7B436B47047A5A6DFAD40451C59FBCFB45BDB2C25569A4C58AA277AD195F6A2A16DE0A11454BEDB867A93F53F8A0B8E395A37EABDF045B5665E7998D4477D4F611F3BCCB1F5C289EA5E1AFDA0DDFCF620B782FB019DC29BC376C2AAE914B721D5F6D6E32FFACBE67FFE15F2796FD95110EF9A46B358799B6E53869D6E326DF9AA607FDCB657F060B6ED8703E928F03BFE658A8105D7114D941A7CF108072E97CC1BE3345E43A541F7D5B7113804F5075B033475DB3AF0684\nss = 86435AB2AFF9CEA1DC653CE819721A56933841F29330869B63E36604A6CEAFF2\n\ncount = 3\nseed = 225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A\ngenerateEntropy = 050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60\nencapEntropyPreHash = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85\npk = 25949FAEA67E908040A25908A7E33199D586F22A3CF5A7AC49EA41BF83452528C7F12118E0685B09D30947AC76F4F72E89BBB7579BBA13D3CD4E262FCD385EECA8B780D7B6D3343CA7EC1958569C49808B97586C263903989928AB9B63EFAC00B27037637897556B8AAB33198C144D226AB9284541400138E03A31F10CBF1CC4BF633C3AD70C65218C1B18770C91D139971574DD90317A421B8BDC56C02C2564B2496793A27A12009ECCA141AA337E911F0B448D913394EC1ABBB46A568BA749F0FB0A2C4562637A220225A0AFAC0E9A53CA4F506391D7483932814DEA886C89879237A95C03684CC0C2D2701B40E5B3A340316159CBC56BAE84130F2FA830501257F8A8948F482AD194CCD4F6BA6C01BACC4C1B9C3188C3D002F8F18F62393B373396F6C510308B6754B8CA81F53D5A1512FFC3428A6C2A543A61FE1193A86B97B260339FB43A9F0375B1C2C62DDB4C1F6629DB701B2D2A50577CC7D5D55A30766400842938D83A6818A128310D16648614A6B6DF6B5D8D9A8D0EA4A127F4233B9A50BA539F5F01B62513A5C7BB8EAD8463C0A346252C94F753A34751B078A06DD785AC6532C2730CAEF7249515514F8E18713C2A72D8949DE781C698E708DEB35448CA1DF99B8E09AC4FAF694CA71B7BD41BB7024C0435424831424F680A77F13506A56C97B6966AFAC4B90FE60BF5E7507E6A7093C47B5F8CA47D86C767455D645C502D82CF5B1CCD8880758BEA855DC71B1C98494862030202C06B935125654EE498A7E7F37254084AA1795484FA77926C8B438592F4D7BAAB58978329CF12F461B1F93AACC7117980774E12355AF27E506A2AC63C4ABFE585B2123E2404B9EA9753FA101604663D07E153C07B743B23C56B86A91CA34111803A1F5865E47807C012A81885104495499884B495EA3F457A2AE1363221B2A94BE84E27CC9E8BCA44F8FBB92746821782B3B92B1BFE87127F34076BD4ACABF60E4F9B97A8F63008B584D0221AF927C67D616BB9933BE9486E38D7BEFDA11A27175F670600041A6DBF0C9A4364B3FFD28ECEEB0C8077C3ABA19C6123A20CA72C0776AA8E21A582168591C7C1EB146BA820C9EA1AA3374625C8744612BCAB37250FFB34A89D305C35169660DC9B09F7C960A4C4450B1A2E56088E8605FD75A35EB620C3C90B93FB001E03C006A15B67136EC1C354D405A61014821FA9590DD212CC6095DD011BD8801A10F08F15DA21C14CACFDE606CA02B7E2E1483E3514CC6BC88C2987587458D77851E476AEA14A94C176A4EAF865D58C033BA2280EC0521BC53DCC3772D48258593A5A1F9974228652B8CB4A08296EEAE869C733A316D926D400CBB09A2DAF532DA06522DA9694CEC2A29CD4C87F6A6C837C6EF6182A30548AFDB807BF447953A3827DB3122BCC7E33576A33A943492A61F3625DCF412793996C664A4664B3666C154F90B40C3EC514C4B1A2D265A23B897177342B76C69637D52E356620F468480472923313A658683566DC8F8FC1079F248F9D8AC67D4CA703339AE28A86EDB4BC21DB231DFA970249AEB1E2138BD4791352151520A73B0792A0E77D4967BC8B46740CF5599D4056F382C9006B79938825DFE2806CB6AFE7523D940792782D978970256C691434F939B02C14F42B1874087EA68917C2F3E31315E22581\nsk = 548A01803A231CA63843872ABF16B2C4B9AB7407A093B354F8882C6775BACF2931DE0A501C5A7EA7EA5C3BAA067290B9FCA059D69CC6DE9B772CC058470544B64B11ABB77F490746384B83283740F0702E17D046759B61E75030F187C2283045B22B4F9E222CA44980DCD0A42E5704504BB3E097CDF93A99F057AB21E3AC305666710C3B4C1B750AA3AC0F00A6F592770D8082F6157ADDB170A956456C7616C856657835970578B35FA87D8F79C2AE54AD36823C6A13A4207453FF324F17D13D43A400A2102B6F6224E6F2132BB14A32FA3F10A446D7944428B66E0E0A04B204C5993C03C294927C60540F836572793C8825376332B64D109B", + "B7273147A878FF0B0BD2808B62104515D0824C90A4E249B4EC8C0F6B572BB621B7A74089DE4B49EAC5A3CFB61A5D6B420779A29E1C5AE98AB30E01A0B45538C9A14CE61C4DFFA27A4E462757A3BDF00C0206C5BF5233132C47B7111771DAAC633E22132AE82CBD616EC92B4E9D1C88E7285B84D9A12E14897A020C06832E9CAB42102AB999838A93A77141D12FF068AC13DC4C685328C7036CCFC2087BD92CA5A675CFE40AE4C32B28EB770DA04234A456EB889EF92A93A0D3ADA8061599D99CD8A96880A2B5E440766A9C81E7A24F14C295283C333A0576B49C569C99450F8714160C4CC49828090BC2CA390094E14BD6A3011A5C038F0927FB4BAD38440EA9F96FEE99141C564A91F9C86DC72498F89D05B047461699FBBA62EC28698E273E2B8436A6EB8C9C094D3404853A45137881C691352F6240ABD2298488299331CC03B1A3106F242D2871525587888E448D0F45A61480BD7E377DD5B63E143093FCC8BDAA563264BAA458649CE7FA5826E4B9B49159E7541D432143C5093A2A5BC5B835535FE7395EC556BD467A10975CE26304BB892D056A6EA4C5CE08D033E9334CF7F6750CB62209BA21F6B147AC875C3F1195D9D991E333C7C25465176B8A566A71451B8305F35D831A36C57C64B664C707F3BF08B54FF3847F1EF0AC4B32BA7D563AF40228B2957B8A95063A65BAFAF86609B4BFE1127C029C2EB224465E1C178C74CB5DB4C0C2AA46456761EC4A528AB2BB8F92C120A1B78A9517A29C8EE408AE7FAB4FDFB1941CBBAE4C3630F407A2C23C4D10A58A8E64546727153D61766D0242C5132236F637B7323905F4A7811C1B8019A808946C11A54F8CA6C16E06AD9A685EDB094616A80383A79E482C611760C249988547194266000722743346D13C80F72117C25CBB48490E05789C6A5E85ECBFBC73669F249C10A12ECA037DFD15994CBC450EB40868ABC2FEA05B5058429B6B04DCE2C4E2630A13DBA2BEC9BE9C30B9F90B45A97040A1F227200CCB4A4413C8B0C5B169830D451BC7993EB3D5B4D914A02C3183B7423D61101B0E3AC0A2A18673126F69511F27EC55E28B975E22A8CE800C37473CAC71788A42CD39C26C176C9C255C4355A62C0B84CDA33819A1AB6C07BBC4F2847AA23A600829CD516485DFF565DE9C392791B84BDB4580326F5128556D160100622AFFA2756E1CBD0A0A1F217A0C198A6DC043B1C50813BCFB3C2488A5C02C79393B65F39990B610274FA77B814BA93784562E0794C179549EA0927D9B4A25949FAEA67E908040A25908A7E33199D586F22A3CF5A7AC49EA41BF83452528C7F12118E0685B09D30947AC76F4F72E89BBB7579BBA13D3CD4E262FCD385EECA8B780D7B6D3343CA7EC1958569C49808B97586C263903989928AB9B63EFAC00B27037637897556B8AAB33198C144D226AB9284541400138E03A31F10CBF1CC4BF633C3AD70C65218C1B18770C91D139971574DD90317A421B8BDC56C02C2564B2496793A27A12009ECCA141AA337E911F0B448D913394EC1ABBB46A568BA749F0FB0A2C4562637A220225A0AFAC0E9A53CA4F506391D7483932814DEA886C89879237A95C03684CC0C2D2701B40E5B3A340316159CBC56BAE84130F2FA830501257F8A8948F482AD194CCD4F6BA6C01BACC4C1B9C3188C3D002F8F18F62393B373396F6C510308B6754B8CA81F53D5A1512FFC3428A6C2A543A61FE1193A86B97B260339FB43A9F0375B1C2C62DDB4C1F6629DB701B2D2A50577CC7D5D55A30766400842938D83A6818A128310D16648614A6B6DF6B5D8D9A8D0EA4A127F4233B9A50BA539F5F01B62513A5C7BB8EAD8463C0A346252C94F753A34751B078A06DD785AC6532C2730CAEF7249515514F8E18713C2A72D8949DE781C698E708DEB35448CA1DF99B8E09AC4FAF694CA71B7BD41BB7024C0435424831424F680A77F13506A56C97B6966AFAC4B90FE60BF5E7507E6A7093C47B5F8CA47D86C767455D645C502D82CF5B1CCD8880758BEA855DC71B1C98494862030202C06B935125654EE498A7E7F37254084AA1795484FA77926C8B438592F4D7BAAB58978329CF12F461B1F93AACC7117980774E12355AF27E506A2AC63C4ABFE585B2123E2404B9EA9753FA101604663D07E153C07B743B23C56B86A91CA34111803A1F5865E47807C012A81885104495499884B495EA3F457A2AE1363221B2A94BE84E27CC9E8BCA44F8FBB92746821782B3B92B1BFE87127F34076BD4ACABF60E4F9B97A8F63008B584D0221AF927C67D616BB9933BE9486E38D7BEFDA11A27175F670600041A6DBF0C9A4364B3FFD28ECEEB0C8077C3ABA19C6123A20CA72C0776AA8E21A582168591C7C1EB146BA820C9EA1AA3374625C8744612BCAB37250FFB34A89D305C35169660DC9B09F7C960A4C4450B1A2E56088E8605FD75A35EB620C3C90B93FB001E03C006A15B67136EC1C354D405A61014821FA9590DD212CC6095DD011BD8801A10F08F15DA21C14CACFDE606CA02B7E2E1483E3514CC6BC88C2987587458D77851E476AEA14A94C176A4EAF865D58C033BA2280EC0521BC53DCC3772D48258593A5A1F9974228652B8CB4A08296EEAE869C733A316D926D400CBB09A2DAF532DA06522DA9694CEC2A29CD4C87F6A6C837C6EF6182A30548AFDB807BF447953A3827DB3122BCC7E33576A33A943492A61F3625DCF412793996C664A4664B3666C154F90B40C3EC514C4B1A2D265A23B897177342B76C69637D52E356620F468480472923313A658683566DC8F8FC1079F248F9D8AC67D4CA703339AE28A86EDB4BC21DB231DFA970249AEB1E2138BD4791352151520A73B0792A0E77D4967BC8B46740CF5599D4056F382C9006B79938825DFE2806CB6AFE7523D940792782D978970256C691434F939B02C14F42B1874087EA68917C2F3E31315E2258194391B7A41175A41C15CD995EBC69C83B29E4BCEA6C186611DC4A79578E37F4CDE950541FD53A8A47AAA8CDFE80D928262A5EF7F8129EC3EF92F78D7CC32EF60\nct = 82A0E7AFF4A571BCADC4F8379F16660071EA01B9DB2E2F8B4792A099532461E924BE531A9334D56A47380A66DCF49A91B7CCA99B6522CD273326FBA64569CD2543C488E95CCF27E9CCAE17B14ECF68C13A94DD7901F7AE15A92E1C7B499DD79DAD5DF3B789CEC56581B33A190C6EA00964BD9812EC9B06DDFF1FEEC5797320D98EEBD856A42B87FA94C0971B62A79AE6CD1900A706417CE9F47B8DF31E055ACD1D852E6305E607DDFF39092864D9D39D456ABA08A104ECFDB3E5ABC9A75A3072D72C59625984F38C63ADF8E617CAA5E4E45CADEA8339A9F8FA6C8302FBA5F20B51CEF477B56F537C0FC750526A1EAFB2A424A727945DCBE1809D14544856A28702046E319F5F8159694EC2FB9BC545BA1DD6CBFA514A196F556C4884030AA2E7C5445987073A882BB053DDD48FA3A4C7EE0787F15A3E175976688E75358460BAF148118336E54C34052CEAB04C1CDE9A177C655777E403AF016A147A4236E2715F8D03639EE81F57B318D458DF85DE4DA2F8DEF589A7691220593692C12EE7CEECAD2AA996845889978C7BF0475F72BFD8A8DBEBBE2702AC7F60AF6C40ABEB30DE0ADAA583F62978E085954362A98CA1D905C7C8BBAE08346C6B5EAD4DC3E37146C75C8F546B14F52EA0CBCB26E3945F4925C54EEC227F8DC4F1DBB1A3332C47FE9CC04F7BF87F0971193B12325B72F8ADF3246C3AB847C2F2F84161B773B5600CAE25A4B624BCCDF9F889FEA70142880B15047674EBD974C6442C13CF0CBDD9868F8EF0AF7C0DE183EDBEB49D56ECC26620E6F100068F303F949A8280E370BB81F5A31E3141D3005E67BDBE3AF409B898039CA038EA1478ADB3C95ECF88ADC1F9FE9251AC07BA4214EF8E6B25312D7267FCD612C893CA8D32C0F07D6BD929815D399E13CBFED2745D31D2C783019CABCAE85CA659F68498E4D0BCFF75804958C1BE7C86F102D12C0F05C56F59646DD1C0DBEDFC65BBF8900ACE1861D98AD20E87A2E1599F6CD768385C85ED30867A43F44DDED91F2593E25AA9D8481318C3546875C8E95EBC8DD29E3112293127D02D2921F30FD2C377BE89087E4222EEE4D793D1D9925BF28981EF52AD688516251A2EF7AA3DDF34B6AFDCF2C92BBB197FC7C4882015F836E99C9BBA1E310E25009C1FAB7137312DEAE24EE1609D59B46DDC4FE5C13202AABFAFC92B8BD5AAFD6EE9FF7BFC6A5E36F0AC30E5884A84B6DCF601B4BFAB2948EFEEEBC9DE0C90FFCE407923ABF2407643D6C1B1860B796986BAB3759E08A42208E96F179555FC97B933C4F759F38F2B648276A31BCDB7FF698CA966B5B182CA6C29C2EF20DAEC7B510EB8C79FD20E33770E6192941B6084B7A7A7FB254C332F3337BBBD6979B5DAA682D36F707EFA44785098B775F38F1DA67686EAD81EE659F211C4D547DB678729B223CFF0F487F7042BA788F9ADD7DAA2122A939D76203472AF237F81BD047D6D9449E57A5AB8C3CD62FF88DAB360D8B2B3813FA36DE70F69129E112DB46CE8CE8A59241CCA8F207C4686EB27DBAA22B901\nss = F9A2D73F0A81B5829E7C7CAD8FCF5F1AD55B384B2427C288BFBF4C29540F1DB6\n\ncount = 4\nseed = EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9\ngenerateEntropy = 66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854\nencapEntropyPreHash = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216\npk = EB14CBCB226951857BE4B3BC2A1B578B148E824A2414412A3D57C8213793C418BF2E0803DE4A16EB9C8B5D53718D38AE40299B89793F14741792BB10D9C21D5F06633AA3CF1CC78D0DC99983076F8756B2F96B2095E0B812160FBB9494038A88057671DC692F14A956D5E6565FF752D28237C70B8F8528CB1A04CFE5E6495BD3B46A3264FD7364E0D54F2AD27DD27B022EFB3D3A632A7F99551BC3317250207F2658F363164A9631A34B468E9B3C9B34B27A3A02FCBACC516469F69B3A51554B93E05FD6DCB098E8AF8A3681CE89548CA311E2F5421CA1496A532366435CFD56A26A245BA68655DB99CD113C1AD1170BAB16A22BB3399E45C6A9BA45B5DC5DA04A426C635C844744C557AF7E49CA12437CF455B302C037BAB4954627A2363020C4AB5CEEF5AAF2E352DED62FD6A52ACB70C84723A527BA34F179204B26AC10692822AC66CC56BFECEBA65C33295FB805C596A48A0C59477405C21AC3EDD2C27E56C19BC84D710584ADE48647C681746038AC74AB73591FDE872CCDFBC3CB1218FE12ACBFEC9248C00E19424B1FBCA70FC5193151AAE1415416BA2D7FAA6A2C745CDEDB94295438BB182DADB77182B2BE5BD1CE0CC028B7EB71BA8CAC8585CBA3CA01620B63FC91BF3C210F67C65C92F893FC616158C104A5799720AB0FD907798F0678746475C8502029865DD653209A39C0C362258A266B1B244A4F42B4ADC1C6BF602FE61125C3B989C018C0A0E0C73E35ABC97C9EE695CD265909AF82548B865EB4238376A6AB53A6BAEF185799489F64E200FB542EC3D1B42E8B3960E02730936D620360FF4570B4079B369A83629B599E7B27FF48C37F727A4F93BBB2D4B7E1C73FC0D6668E53C1EFE0A0B547B1F38C51F4001654F45BF0E5766CA1C662F2C", + "B99A6BD42A17F89C80A4DB03C990A81AE9487E1A52C13720266083E152061AA08C03A7A703DE58251F129546A42282515A3E27195CA97CEB39B00566CF4ACADAF320D5C88C75FF310F10BB5AD738D38AA47C945235E1730B6CC227A194DCB04CE046A22C37319D910060B594BF8A64F2C4B8F26000031948046721E6546893A341ED2C32804149954E3788EA5054C51A43DA89F9C789EDA6727BDD4BE32B15D47B9C327EC68422813B00950BD73C96C7175274A5EA8BC128A7C0993031B4E8A5D3C074D2D1ABDE8239D5AF58C06509B24109C84297E3FEB447FB3926DC19F39211119C4597711A222B341CDECB0698580E422A951DB2305D4A7A871967DB945A60439DE206955C371EA52452F865DA438130D2B8EAB3669A97911258B08931A2E36C6C390B6845E8076A0D621D7692971BA71BDA0B8AAF7BA0AD3C4F05AC23621A146C68BBC501854062B924C3A64916A1B9B19CE5B466F8672EDE621EA987F83495106DAC22FFAB6F4A5CCA797587126CE50589F68A2084875BBB505C7FF46922EB496DA260E3719CDB2F23950455DC8D36E3932518BC11BFCC067AC533360B86550B6AD09E93DBB092BE410721D48BF56B3594B93CBECFC785A5852B598425E4C4CDCC7CAE1907ADEA5772276B2929B9507DB5C06041E5F9846506055417C6FA091652A4A424BF6396D46365BB40601E3A55801B93A1CCF39126BA7F025A2467F6D44DE229C527F6E4E7071CB826CFE76FEA483D9163EAA84F6AFAC495A\nsk = 944AB695C2345BB67894D451EA2A5C92561A5467C769352379950879899C9CAC9D05E89CB2729B2BB47724923FCA357623C69643569D66912B2F9B3249908090D4C5F68388A6141163C931DF430D70290950B07DE410AF913C0E5A215C3059785EF05B824545ABA0B95E7279D1C5726B59890B82131D5C62E8B3BE33B8016BA0C321C248A5293C71ECA570C9536F958B84663B1DD5BB6F272C3E201F014AA3AE05640ED92200274D45D9BF4410CE8EA72D680ACE1EEB04CD8B002DE72795DB60681BC9ECD387FCEA796FF7726FB29877F895E6832EB7EB179A5956499CA3BCF3283FC8489D494A88668E6614B1F49824F12A448B31A42861190CE3A9F73C6FFA25622D7A504E0694BB7C75EE71CC8E718CE9D57AC86A11721721E6181F157C333AE098F8A6823F765B60F0300F4733CF65240C779569620213B8A331731A7B31937104BECC0995EF57255261AD9B246009F855CA82AF2001B256760C1543074D70B3C578279B35137E16AC2089A4C60038B8671D308964B68A2211187154746C27F59C8105981C8C7D0AD58717978C01A66B5EE1697188BFAAC9B927822C940C5380409F38459F5B302CF7DC9D6BD823A0308B0DA45C35D541D2346BAE4173FB0C677EEC26A94C4158B28D4D7B4B0F62A4AB06BAE0B42208B099A174BB4C482C7C321AACA49C4A517114A5CF408750E8588545134F83A67769CC6E0B413BB800C04093184625A7EE24134A721D5FB1571CD82DD1D7C5F9103E0C2C4416CB775AA28DF48643084B391DD2CAF39278E9A31D2254871B170AE1B60A4E39B1F5A8473F580C7153CAA1369D8E9CA381660A57CA8D2523202816767CA8CAC0914C16F1CEC8EA4EA5DA930E0403E7A876C390BA31FA250D946A2EEAA479888011DB7942F7676A120338357BCA38C4C95088A4A0884B8B4C14E9C09E831F8AA658ED77CC164124CB281F61856BD6C965B6B6CD60B1B1034888F3970555443F0F5CC29C800F578806BEEB4730AB9AF4B9BEB89502AB48761E188CB9AA95BA06B28CF4B89C200B2145A4339A53406B6790A518F54902EBA0230A8C2A45447125B7330F12645D935E00651CB4996E395543B7E643137ABF3DF59E042ABD6FA11927062D73D0A107BA6FEA0908FF6759A972C11E864EE7393254051BDA558D4B272E6CB2C337747A7EF46F5AC872D5D5238521C09E21495EF98B59C22961E5A4967370EFC4865F06A72A41464D37CE4DD1803BC117888B681D35195C857A47B764C6799A86E27327EB0403931E29F90FEE8628AA43B333615BC0F251707024AD41A24E3C4F15B99E72F536DD989C0325225DC682E3611640D99C1552506E687E18A883F90882056C14385BC08BE82616D811A4FB2DC93670945B7EFA17593C4B7BFFB76F9A805F5230C50B065DC77B409CA8CC0B7190AA61614C528AF2D1AC130C19E4362E85A40693A87C00935A887B9B58699777453D8278C445BBC8D225412BDA6FDF026207E3B207613D2ED74C085707EDD555FE4C00B40B2A83AA219CD643F1D83EC0FC21BCF94FBA6A8262D959C9FB345F2221082C40A1501C46C55082DB2709230B04090558CB6D6815173525725D8CC0BC93C881C99A16041757D6A05AC71A15E887EB14CBCB226951857BE4B3BC2A1B578B148E824A2414412A3D57C8213793C418BF2E0803DE4A16EB9C8B5D53718D38AE40299B89793F14741792BB10D9C21D5F06633AA3CF1CC78D0DC99983076F8756B2F96B2095E0B812160FBB9494038A88057671DC692F14A956D5E6565FF752D28237C70B8F8528CB1A04CFE5E6495BD3B46A3264FD7364E0D54F2AD27DD27B022EFB3D3A632A7F99551BC3317250207F2658F363164A9631A34B468E9B3C9B34B27A3A02FCBACC516469F69B3A51554B93E05FD6DCB098E8AF8A3681CE89548CA311E2F5421CA1496A532366435CFD56A26A245BA68655DB99CD113C1AD1170BAB16A22BB3399E45C6A9BA45B5DC5DA04A426C635C844744C557AF7E49CA12437CF455B302C037BAB4954627A2363020C4AB5CEEF5AAF2E352DED62FD6A52ACB70C84723A527BA34F179204B26AC10692822AC66CC56BFECEBA65C33295FB805C596A48A0C59477405C21AC3EDD2C27E56C19BC84D710584ADE48647C681746038AC74AB73591FDE872CCDFBC3CB1218FE12ACBFEC9248C00E19424B1FBCA70FC5193151AAE1415416BA2D7FAA6A2C745CDEDB94295438BB182DADB77182B2BE5BD1CE0CC028B7EB71BA8CAC8585CBA3CA01620B63FC91BF3C210F67C65C92F893FC616158C104A5799720AB0FD907798F0678746475C8502029865DD653209A39C0C362258A266B1B244A4F42B4ADC1C6BF602FE61125C3B989C018C0A0E0C73E35ABC97C9EE695CD265909AF82548B865EB4238376A6AB53A6BAEF185799489F64E200FB542EC3D1B42E8B3960E02730936D620360FF4570B4079B369A83629B599E7B27FF48C37F727A4F93BBB2D4B7E1C73FC0D6668E53C1EFE0A0B547B1F38C51F4001654F45BF0E5766CA1C662F2CB99A6BD42A17F89C80A4DB03C990A81AE9487E1A52C13720266083E152061AA08C03A7A703DE58251F129546A42282515A3E27195CA97CEB39B00566CF4ACADAF320D5C88C75FF310F10BB5AD738D38AA47C945235E1730B6CC227A194DCB04CE046A22C37319D910060B594BF8A64F2C4B8F26000031948046721E6546893A341ED2C32804149954E3788EA5054C51A43DA89F9C789EDA6727BDD4BE32B15D47B9C327EC68422813B00950BD73C96C7175274A5EA8BC128A7C0993031B4E8A5D3C074D2D1ABDE8239D5AF58C06509B24109C84297E3FEB447FB3926DC19F39211119C4597711A222B341CDECB0698580E422A951DB2305D4A7A871967DB945A60439DE206955C371EA52452F865DA438130D2B8EAB3669A97911258B08931A2E36C6C390B6845E8076A0D621D7692971BA71BDA0B8AAF7BA0AD3C4F05AC23621A146C68BBC501854062B924C3A64916A1B9B19CE5B466F8672EDE621EA987F83495106DAC22FFAB6F4A5CCA797587126CE50589F68A2084875BBB505C7FF46922EB496DA260E3719CDB2F23950455DC8D36E3932518BC11BFCC067AC533360B86550B6AD09E93DBB092BE410721D48BF56B3594B93CBECFC785A5852B598425E4C4CDCC7CAE1907ADEA5772276B2929B9507DB5C06041E5F9846506055417C6FA091652A4A424BF6396D46365BB40601E3A55801B93A1CCF39126BA7F025A2467F6D44DE229C527F6E4E7071CB826CFE76FEA483D9163EAA84F6AFAC495AC5DBD68B3A8C148B2E7AC049BB986E14DD1CEBFA1CBF3EDD6BAE85A4D2DDA082BE2D3C64D38269A1EE8660B9A2BEAEB9F5AC022E8F0A357FEEBFD13B06813854\nct = 99CAF6EAD87C4258D41204468930F6669BE4D28877F95B4E4E7F15F975E3F8F7CBFCD8D24FE79C7CC43154878BB576F31C5E59077DA847B648FA8EA91A309CC32508B3D6A2A7FFE37B38901D15B489689D71EF0E5ADFB052AABE970525ACDBC79DC95AC0A62B7B151AE209BC92FFB4CD40002CD061E9EC8CC7B6D82B0340D798BEEE0C4FF22888A5E7F90D2782FBB07F4D980CC0126D7CCCA78358C86D9E399625AA7E67CF6E9935D3B02948AF9D4E02422985E5F067218B0682F576C3DBCF7143AC7452391C899C31F7BC2369CD4158AF829A6F8ADE7BC59C727244FE9EEB85FC20ABC87B82B1A8233CDCAE93D51BF7DD544F8324BACFDE234DDC364909AA9451B8452A2F959DDEFD14E055D3F09E8B9B34F43CF5F61227896C85EBCB76C25F66D78F2C9BD9A1B9ECC209030EC7A494C909337D3196B11E0FF8EC06AF26F82B8FE3D95CC5EFCD7A620C410358896D7AE138C5A35E4A7F56C2E1766D9CEE5E3A883217DFB6AC66B014354384BE3B8B36B29945755418558DF46BBF07172F778128668449D0D42092E24CB530F77BCCDBF9A732EA3D68623847A1A377B2D0CF9AB3E61440453516C76B7F8477EED10CE40F0C10D5FDE3BE9E20CF629D232F85D6744B76F8801E691BA9CDE389BEDB87C5683F47C031DF57D17A0241707650BD78A753570A1DF4FB30E952B000239A0ECCBF75954FB6053E509AA61FF4607204175BF10F500735611053633A2E77E1E073C5B5DA9C41C56DB9A368A6F9B2FCBFAAC2B899A487FB9653FEF223A24D788DAB079C88B47B08C7B300EEFE66BA4A95CE44FB719B495C3F1530BB1B4D8EF0E940603D142A6DF06DA11C9CD06A983BCF834A1253D472BD5A344694CF01CB3A7A75A3954B6DA6AA69F700FBB5A9C6D21C29D9DA5622640E730D44DAE3CBA7269C9F7B5A822069FACF10EC7710C89D56D92C56DD9E5048C898CD1A1AE0658DB7530A27C9AF44E55030EADB9B1CE92EB8129E5CCFB5AE7E3A3ABBEF6F441ADC3BBA1FB94AFFBD154B4E6FE014EEF5863DBB3C0764D0F4808EB19F2E6249B809E1BB558EB8A7DB7EF4CABF353B331F8F1A85160BE83D34DCA53FBF0C654D2BF2FB594BB2B26F9E6BC875542306CDD623638D8F36CCD98A4357C84C06CB8594FFF92ECDBBA23BC3FFB3743344C347B29106FF5014354011062CA7A1F7B2F0B4229AE5857A769B6C83E3423C6EA10605A168DBCE3F5FF5ACC77A17CD0C91E50787290AE26BC68F4C9F9DCC961AFBB3F875A77F5DCC7393B818859FD9F41F1BC1C1AFB814B0EB7BAC59EA36A9BEEEA70524795CCF733A315618818C165EE31D93C198257DD17D36F7F5531F58EBBD0D195068F0BC0E559BB658A49572FD0F0D6E587D9D8D3D5B838C11019D7D306A1A6BD88C1155DB8498FE0E7262FE683448C6C44B83A416E9FB99149674F93663B119076CBD2EF018A485084676DF141E7373E3F96BA2D4FC23D175FEBD6AC4A63BD910ACB190EA203F9408DF92413FBA0CFBEF9AC0098A0B40FADC42531EBDDFD3B8E5095D2C\nss = 83E562482FCF5157C75D3D2F0A35DA861689A1009104A071A7BFB10BC4D8CD02\n\ncount = 5\nseed = AA93649193C2C5985ACF8F9E6AC50C", + "36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA\ngenerateEntropy = 7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082\nencapEntropyPreHash = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88\npk = 86B5C9A75157E73CCC2E138518EA98A246145DFB6BAC9B2FFC333C0BA5806047CA9BA8AB797937000270E773C9863709E59786F8EC948ED27660AA3758E33F59140E527787FA74A2CE22A4A8F3037A26903665CBFE8A0677EC273F590D64C97F69F396DB78448535746B43296BFA2BF0A251BF986A524074C1F96077F5219CFA9124D1458520993F627AA8B7B6A0F191683233E0BA6BDE24561A666FD10151B0C52C9982C301E0970C3363DE27825A5BAB078848AA5CB75A90C1CBD24CF67A68F3417780CCA947131E4573934F9959787B6320A4B47BB311048289E2C915E35344E3A144E2708893138A15A03FCE3816945464C229C587093B5CBBB519767FC65C078D6C684B8B81C1F9CC2B3BA749FB3074623E3C9124A8E1A513510357656B37087BFD02773FB59157EB885E1501740483F3EC070BD492DFC217D7DB99CD7C9D57B937297634C3494DEB585B8C93CD4EAB1865F8A9C8BB15DFE583C7DC0427274F8DF3C693FC351289964A89A3C745967231261D949552E0809BA9B7C5D258AF579A4515981E991D93154BCAA170491B06752415B1D52BC2A98B7F39C5B91A87EB759A9A4537218156746930A347A5026911ADC0412F10A7A7C200A1514D500805C10A276C327E4899AA3F9B95D1BA2347E0140184B1235A719E6C4A3011576235215D77084034771129C33199B70774B2130898A0C69D8F39C3A50B273C665DCD8031B4454D144A4356B9C2B16641311856CB65466991B06D1A8A74A5AAD6B5B935B65DBA8374EE690CD1C701A5A28B41732B5F88A9AD919A7FA563BAFB529885488F544E1240B3CD673F94EBBC91B4757444A302578AA953161993CC918216BC56BA53EA17664BC5B543A38C3516D4063C35695791D8821240BB749CAF98896C4718A9DB33C1A7E9B91B9B6D06FBAA58E507F8A105E2F71F6095621E354B3DEC1F9C979ED7B3AAB56B4741110FDA601FAC78C2EDC386669118A425C634157875F61ADF10C43D2184D3252EDEB11A61EB67A349405EC74B9FD307558A887EFBBB46C904F9469DB491605A3582BE433BED57363426055CC4852ACC0317F24D89903A918875C949556A6A458FA3CFB5797D6A3A68EE9991D97A38E16B9A727C5B2E7B5E5A0029C1513D5A1A98EAE78713785BD4322261D90109A0806E565EBD9308849CC6708B536C83A2FA35995C819D99B850251C1D50EA902A053C7CA31FAAC37BCB1B40D6123CC4D52002909D0AC566F7D75DC89998036AABB267C5AA70184AB4CFFEAB018F195F62879BE0A51B42B843CAF7C494C181C2F06866CB2287A00349EBB136747DA52A3C4A3C581798C413929CE3E698FA594F019579AE329A22D4AF66F27B46453F22E61AA6EC5D7D854FF6D3C3D4117BE2145B5C2BA7A57AC968A5CA43B461F808167FB5A76A942C95145098B95CD46439669C00366960E2162AB613C5ECB151359B093C27C04AB230FA7C0074684996F44939C81FC31373C8231BD0B6679991A32A031002B257B2F31101317B3E2B6B28B8911E3991479444C6086110B7A70125CA71C6659C970F94D0942124C17CE3AD50D5A7019146BF51B012D1CFA0F59B220A795DC6B3D7896AAC680ADAD383EC46762B669D35909A47C12DC8EE619E1A0C8915822D574A243F67E14104D4F021CF95BF33271C9BC9\nsk = AC65AF9FC8B905D09638374E58C551DA08AC4EF86A8FF04489BA462841A85D907ED0C70E1A790297AB2DF7D6CDFC5C6AF513144DA105DDA2C75F00736DD91564A79668E335FBDCA1C9D31592E73D60066B959A2FCBF55474F9C21BF058F021457586766FDA4FAD521F64940D4932B07AD8CA7E1A06662730EA6C15AA1C2F9662552313176AF04FA4A98962101492566ADB8BBC3EC04F9CAB9EBFE5860F886D57A2C73FA050A3607A8C0998754B417C9C5AE2FC3F829CC3A2EBB1E927AE87B68C6DB355F4C661CD000D10D6BC31CA1C249A9B3931A4D1C57904DC6DF923839D9A90AA2B93A87C44B5F82E6A925D22E679428064FFCB9621067B75477FB7D51A1D3B9D9DE4051CF874CCEC12976562752CBFCFC59F56C2C60B8B4610A9BB36E9019B974502407D57289726AB8A38D7A6C880074A5686619ABFFFA5757DC79E1449408851502BEB8196F493F4A724B9D681645A07B193586C5C05D8D10E2C968BD251B88691C368DC18CF8270DAD3C22BF5093DB4CF05668F8C6315C0EA3F55495E784CCD6055AC451363FD77A91686AD77C5AF53141EB5E7534FAC4DE481741E48B414302E4743789E250C39C45C0A15CF42E7B3631B6A8C0971C8A34B8200BBFE11004AB06BFC5949C3615B02947C73E7A0717C6B60F2679DAA21AFE4C55768A08E70105868AA6AB4AAA848C79BF125883907B9DAABE367AFCE273E2C168AAB02ACD27855E2944B67B938170A9258F67397770136E466758C260CCB7DA226B5A95692514727FD48953C62959C88C8784A8A52131C4BA5A6D757B4311048B602B554E8AD509B0C12B0A64553CD4270CA92F36CEC227E16A217C769A2BC1AA6C356A5A39C69F4963BA6273DB9232F1D8A28CE65B5B9058F1B8A164AB0380C42A8EDDB6C2B8B19F26B557C387E4DB9AEB92C4D7D0A2CA1E35F97E05CF590BC511AC5EFB2357E70525BD027B36C6781C4B86B0069E7B89C8CA643FB9990ECAB2CC5A8A5A5B2B0441076CE934D96BCA9FFC10EB6E7BB093675E97B68894BB030581D89123642C1118364115A76AD1C181EED4B691BBC15DF182DCDE00C71F8685B71883A184396D3475CBBCB674360DC14C42DD6461514479C85557194A97A654C4BE7620FA84C59DB5057A0886D760460CC4A3A713F4FD4BDEBAA93B943C48E6348053703ED818FDD9CBD62E246C0B69A265AA381822D6A474C5AA530AA5306A0C8572C413718A278194367405789E1F749AB4A02AF87B362067F3DA12EC01A83ACEC26A390CB5419B351BC95E08C7338FB933B81476EA950881275A186C9E9F99DAB63634E6B7314188BFD686D74EC203B71542B62B1C0C7712745940F7B9237551467470E5B1BA2F8E34CF585ADBAF980317C9DB1147382946C12223C3A45973B879A523855BEF121151BCE620216DEDC6C3457CA03951FF45B662F79A1A7A5CEFE9A846DD5774C7C2A22F842E4E465A94314E036BB55A2787A1A0F0F111143872DAE74AF706A369CA54259B80578BACD497700871842B98CAE2AC3B572F98F145CBAAF54569779B616242060B30B2A482DAF335C9A502CD318296958C696F7080C7A3926C7B62F36A5DBFB87EA0518358155E8E94390B6C0F808B91C166577037D86B5C9A75157E73CCC2E138518EA98A246145DFB6BAC9B2FFC333C0BA5806047CA9BA8AB797937000270E773C9863709E59786F8EC948ED27660AA3758E33F59140E527787FA74A2CE22A4A8F3037A26903665CBFE8A0677EC273F590D64C97F69F396DB78448535746B43296BFA2BF0A251BF986A524074C1F96077F5219CFA9124D1458520993F627AA8B7B6A0F191683233E0BA6BDE24561A666FD10151B0C52C9982C301E0970C3363DE27825A5BAB078848AA5CB75A90C1CBD24CF67A68F3417780CCA947131E4573934F9959787B6320A4B47BB311048289E2C915E35344E3A144E2708893138A15A03FCE3816945464C229C587093B5CBBB519767FC65C078D6C684B8B81C1F9CC2B3BA749FB3074623E3C9124A8E1A513510357656B37087BFD02773FB59157EB885E1501740483F3EC070BD492DFC217D7DB99CD7C9D57B937297634C3494DEB585B8C93CD4EAB1865F8A9C8BB15DFE583C7DC0427274F8DF3C693FC351289964A89A3C745967231261D949552E0809BA9B7C5D258AF579A4515981E991D93154BCAA170491B06752415B1D52BC2A98B7F39C5B91A87EB759A9A4537218156746930A347A5026911ADC0412F10A7A7C200A1514D500805C10A276C327E4899AA3F9B95D1BA2347E0140184B1235A719E6C4A3011576235215D77084034771129C33199B70774B2130898A0C69D8F39C3A50B273C665DCD8031B4454D144A4356B9C2B16641311856CB65466991B06D1A8A74A5AAD6B5B935B65DBA8374EE690CD1C701A5A28B41732B5F88A9AD919A7FA563BAFB529885488F544E1240B3CD673F94EBBC91B4757444A302578AA953161993CC918216BC56BA53EA17664BC5B543A38C3516D4063C35695791D8821240BB749CAF98896C4718A9DB33C1A7E9B91B9B6D06FBAA58E507F8A105E2F71F6095621E354B3DEC1F9C979ED7B3AAB56B4741110FDA601FAC78C2EDC386669118A425C634157875F61ADF10C43D2184D3252EDEB11A61EB67A349405EC74B9FD307558A887EFBBB46C904F9469DB491605A3582BE433BED57363426055CC4852ACC0317F24D89903A918875C949556A6A458FA3CFB5797D6A3A68EE9991D97A38E16B9A727C5B2E7B5E5A0029C1513D5A1A98EAE78713785BD4322261D90109A0806E565EBD9308849CC6708B536C83A2FA35995C819D99B850251C1D50EA902A053C7CA31FAAC37BCB1B40D6123CC4D52002909D0AC566F7D75DC89998036AABB267C5AA70184AB4CFFEAB018F195F62879BE0A51B42B843CAF7C494C181C2F06866CB2287A00349EBB136747DA52A3C4A3C581798C413929CE3E698FA594F019579AE329A22D4AF66F27B46453F22E61AA6EC5D7D854FF6D3C3D4117BE2145B5C2BA7A57AC968A5CA43B461F808167FB5A76A942C95145098B95CD46439669C00366960E2162AB613C5ECB151359B093C27C04AB230FA7C0074684996F44939C81FC31373C8231BD0B6679991A32A031002B257B2F31101317B3E2B6B28B8911E3991479444C6086110B7A70125CA71C6659C970F94D0942124C17CE3AD50D5A7019146BF51B012D1CFA0F59B220A795DC6B3D7896AAC680ADAD383EC46762B669D35909A47C12DC8EE619E1A0C8915822D574A243F67E14104D4F021CF95BF33271C9BC962E0447F7B5AE8A806B741CA5C302230B555C3786C11F3EB43894A8F45E3F7B1A08CCF451B049FD51D7A9AD77AE14A81569DF8C9BD3A8F1EBEA86FDCFB823082\nct = D4BCE18C62FB15E635B2061B99A2D1BFF919EE09A76A8598F64C8F52272CE533DA3180B71A5F1A710EE5D924B1725834D24EC3166E3A2D6C0EBEF6B4AA2DCB9AA3CF2BC0E3AD19590AB3520B3145CBD5F36E207AD97C9AA2276F0FAB6A5918F9C0D67616FD45B4F8BE0C461488F17F57ACDE6432D8B36541ED62783DD590B6AC71FCF01805EEE76EDC2583CF0A0626CA4B0D6AB6535E2251CA533992336ECAE5B26B0E06525F08D53D04A9E0CAA603381E6C033F26661427063E3B6C84A4F82B9120BF58A3560D7B7234F1C6E7A5A4E320C8C8DF4F6433F646951F7A719A79B9D22A663A2E33A39CBDD054D870F447C9F3053795F96134DF95B277CD95B6D7580225F919E5119FB5C2C75704DF380CBECF276D28FFED759C8BB7252E24A39A1A9AB3FE42204727A50508ADF6C274B6D4976DBD6B7DDE7753A9E58CF8FFC6E31BD3DCACF9CA083B3C482F561CAB1C0DE32293D35DBB69368E8A62765AC4E6945D8D", + "982435545F2DA7DA1875350BBC242611DFA2BB9F36B407E70C27A7A0AE0EE2371C33BBD7B958F4A233ED13BCFA73161DD89E559EDF03845A0F8513A865ACEF4DC5EE33E40793284DCB5226FCEC925A4F1195884A72993F34457073365E35A1346F6453DA6262B137EBFD7EF78711CD1319D23493888BE93C75522F3645E5F83E10843C4F688BDE241537249926FC901E9BE192A126FBD910194D0B3B26325D59831BB82D9A2F357ADD6C823D46E3DB51646E09C22F750F95237CDA8A00071BFDEB8CED9863B89019155EFFBD27337099E08CB72293CEF964F28FA1DCC644B7D022050900524B2A1F7AFB0347FCC6E8402011217FA77E3A6EEFE5C4A63F775EE2DFA5EFA3F9CCC2E70366B88F5AD9C0B73CF81616B32D38D30B2741A04DC6AC179B90FE61CB66EF31024EC35093BC140EE79BCCFA149FC69B846EEB3717BF18A2358FC9C56EE28A7E384A82EA0D830123A49698E63A17D70C1C9F1169F1B62A409C5A64FF6D73372F419E12201D8AAE01D09BE2C3D26E8D651884A31F6B2456410DCFCB79684B00A163ACACC2E247476CF53DD66DFDF3646322971E918C0B9096F86A8EAD17558D6736F4C52B1684F952CD93BD39CE4A4D67EE2D7470C710F86D1688AC90BB1CE23C6E500B6EF99FFF1102BB23FCA16D96D30DE29B4AC4BA252063DFD14F7834234274A49BBC5E78B01914272F1A84BE414AA871A7B5072183CEC33EFD9C3FC702FBFEC2CA3762D22722B98575CB874219FBF0F82C3F768878AE2AEB9D3FCA8A8877CB3B78B9A9E34DDBCEB6659E3D632B37F6402D734E545BDA4027562089993DA8D4E8F388243E1D8EF9504F52DFC668E69BE634797EEE05C6C2CBCA705FA1A088E9A8A2CBFF0C9F8827310FFA1DA6E75B0BD776B4437A6CDE2A9683374910FD5E5218353AF004F1D1060B6BAA31B3460D01B3E7675261DF6C409009100E70A4391F146F04839F0C175837DFB4E6B9DFD402032380236627093C9BE3F8EAD7F81BEBB8F8853C549C875AB0EE4BAAAC49B73FA3D410EA646E\nss = 445B60A142D4853702A102F9CC37FDFB1D0B14A9A7E210C7D290F9402F0A2F40\n\ncount = 6\nseed = 2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049\ngenerateEntropy = c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96\nencapEntropyPreHash = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b\npk = 05EB362461C4A2E81885084505C3862C3B647D181805205EF3E4CA5C30C46A0C21EB97700B70C2BEE78D862B3E19DC1E0CEC0AE6998A7B3C4FDAC39A950027FB2A3BEE027A8E54B4A5B981BBA01BADC0B5BA6A36A2913F1C1A046036960790CE2CF2583E6C62A778290F242B49606ECF24B3A0DC023B22AD8945A0B8DBCCC9356475B36B2A990D7435B12E1536A21079FB7802B998488E690F763646C3B66ADFBC8161855B20EA18AFD87229D05E60372694E4C4C6215344DA04173559D7954B029555E6CA4356F6CBE325A39431A64DF06E75C63ED0E40BB0CBA6ED68BC7211B02F1165C370ADA1E0ACF4AB61C87CC32F7017B4A26FF8CC0784F76047316AF6398DDECC0C62E9A37FC4CA685017B33AACF597767312192CD330B2F3A84E0BB858480A63A607295A39F61510DC2C6998614013F45D319858DA8228FE5BB6EAF3B03AA60F4B721A3F046D3088671930672C61C92D6005254372D8081BE322CCEAD06CDD472CC5A481EE385096A5B8CE64B57781CBFC4457E917162DA007BD7BAD8E3803E05B08876842D9E6A0A545407A5067EDE3510CCC4478C040310AAF46051454D855D1A5521E2514AF676846650E0043BEBF453E7488B6DB8AAEFCC16E26A75C52BC0EF3C80DA3BB39F73B9852B54D9C606363438C45DAC4FF1A1913D81B9A80544177BA7DB6503A04A5405299F80A83FB7135FDE04F8CECC0962461C0E80298D219531C9CBF00A3BB5B84908B5A807739A63485128512C0478084C8964F9064CD4514CE92C30454AC25B48919B719C5A853010A2EB712B80975660456562C4C448C39162CA63AED14AF7F28875149857F9B8965BC1D04CB8EE2E67C14A493A3822FCD0A2DBA2677E719B8F2C8BD09431B82BA56007584BEEACAA1F081D244B0D771BDB0C8033B18CA9597443FF8CDF754569DCC2DC4D4C212E2BBEE88925CE73034E19167CC7AC46059CD3B9EBBF6BC3A476F08438C61971AF139A248821002480F42C2B9C0979AD3BC6868565CA3FCBC124A7548D53F56B51C9F8AA387B59B07638C7AA45704420B3C24642035A7884CB42F877260C29697809AA7482E3FC356D8CA061C1C443CF24C4535BDECCB02C3E3B8B1D90E5B47BD11615CAF849DA5811AA743B9BD7810C470187E81AF9BDB4D1307303F615ACE2A58E7ECB3BE260E9F7C1E10EB3A84F207D2E75A30C7C741EA45FB04A9473C1425F80A9186A7F2625EA6ABB4AAEA3BB50602DF23ACF8E452CC01A909EC9034ACB47B969D904213F0A79EDB7766D0290005C954A1DA0155F7318BE854FDB038D019C1904B714F0514AC331C3813BD703B45076365BE4B47EC510A9F585907BC0F461A6BEFE13A2667593E12134A86AC139777A50CCDAD16B6891A0871621B387684B5226368400164B29109328F672CADADF7648377CD11C9232094165BB1CF12F694F940C3CD784C84925BA74C8A49DC27CDA4C553C85334A860A8A55D8A75969977AD1F505B9B20CEECEB24A262C707843310F39434390EA5315A67491F0592BF722A1C2658C8A720991B26561E14B178C3A1028003CAB8B69F60828F47B876D43D3F193C3820804068A5CAE76DC3F27F5F1323E6A2797B9A13C86713A83BA9C161899CF295CFB4A4AA443F32D16B72616A0DB4D3849FC41A7A6BA87F4AF757A0AB1956518F\nsk = 67A93BB27ACD00C9B95AA03552809C38A08480DBAA67A9584A460345E20E5F381C9A82710EF1709CA51393F916345719BD3144B3121A8608C0A48017963387F7A31C5FEBC6B6749E6BD9BE3C58A9A77B53D7762F5854A3467A85941CA2C03873C0458B940275E5AB85B83A5C2027894B92246DD8632D68A310FBC6D214381128528B375FBB8C3C7923AC6A8C7F9E37C2EA4C6B72E3451922761AC274B5CC8569CCB93917A748E93C190320E3F1381E08CCCCA70903975AE25689C12709C8E9096B16A26E4439C2552A088194368B36EFE3871A6A1CD54CA0C70974AC936E45DCA01DE296A14C7D20652999E61841DCBA6C0171FCB406E14A95B0C02517447BB9370996176BFDC5BEB4316C0ED34A13431E34AB27D9DCCD3DDAA49D314659BB8D89325099D0B06931796CE65C0628C817393BB1870F19A10CFE3546D8BBC2509058327626F490A1BBCA6FBB653EE1C3555203353509AB14B64CF8A29C32B17096805B8D751848DC4494279266F2CC474228B2B703CFF81F0F29152F4570151517995262D705AFFFC08DD413C12F37B605BC32ECC1292B9AC99E4A34F911C8DB990ECC9A3DFB37517446908B91B1172A3D4F547B3AA642709BA40C3939734545DDB6B45C66A1A3E58C6D1929E5721BFC6A6021A635D86C8378D4A0BA68CE385B6B7FB983EC4A95C8B20B3EC750B082BF2CEC89A6F8C2881650E5B71A0135C865BB3FB12A4C2C3C917D655A2997984C8557ECF1943436A9FECC5C84808E38701CC26A251F458334F59BD40BB0D8F82E74071A5AE3C9439541AEE59C6E46A5852834CE5712B3665018154C5339467D606AF189CCF20C68C583C96D969815109CD3ECAD4F5AB0A8BB8A7B68359B0319078A7405821C2709A615864422BA0A3970C8EA138FFC1522B1A53ED1C71D396A0ED6B782C6552C70216679BB4761A600634276D553CD703897C6943A859112CAF9A7AC99517C23CE6457AA069B6FD2775EFB262DBC27B02FE6923D14B047A25CDC6B86D20A55D85108FF276F121A352E098E5D4CC3EF92B3A1C4A38244621B055D5F812189F6941B492330FB1AB0A442A656655455B38B522DED5640CC4136DF6CBF4C4B0651531CD8C95280E2AF13FC57C977BBD1A8BDD253096EA98C3AB33A516448A8301A4B141AE213BAD2F640B2D5846C99A25884360F604333197816BA9DD1D0C427C5B8D3A6B434207B8539CE5092CCDA67A755D6A6D7E8BB6BB02AF1CA7283E797F24A1042D29B64262F29B0482B840BD70A3D6D54205DF412DD6490E3DC38C1236758F65E461B11CA480B476875C692508E7BB90C430797E1917041642D88506C07255AA92EA32508462C2F4A1661C05114C9361F651B7C5FF70B42659FFEE71F58CB79E445536B8948142CB4EC16CFE5B21DA659C2DCE452346323F1632C37F128A6525F40E03D6C073E05476252B2B0483C4B87C1C1FD8C972CF651EB9684FAFBA3F862C8619C089F01277C14BE7CF7790712CA1E8877A48909EFA31D814C1C21F4A151B886076840546419A1C8B6CA4466389A3F6DBB69E8494D7B25A4E9B234A8D928A26B946FF305B8A33B0BF8B3EB992D68C312B4074788E69D1A5A211C3B55F8C654AE778FBADA1D75FB2305EB362461C4A2E81885084505C3862C3B647D181805205EF3E4CA5C30C46A0C21EB97700B70C2BEE78D862B3E19DC1E0CEC0AE6998A7B3C4FDAC39A950027FB2A3BEE027A8E54B4A5B981BBA01BADC0B5BA6A36A2913F1C1A046036960790CE2CF2583E6C62A778290F242B49606ECF24B3A0DC023B22AD8945A0B8DBCCC9356475B36B2A990D7435B12E1536A21079FB7802B998488E690F763646C3B66ADFBC8161855B20EA18AFD87229D05E60372694E4C4C6215344DA04173559D7954B029555E6CA4356F6CBE325A39431A64DF06E75C63ED0E40BB0CBA6ED68BC7211B02F1165C370ADA1E0ACF4AB61C87CC32F7017B4A26FF8CC0784F76047316AF6398DDECC0C62E9A37FC4CA685017B33AACF597767312192CD330B2F3A84E0BB858480A63A607295A39F61510DC2C6998614013F45D319858DA8228FE5BB6EAF3B03AA60F4B721A3F046D3088671930672C61C92D6005254372D8081BE322CCEAD06CDD472CC5A481EE385096A5B8CE64B57781CBFC4457E917162DA007BD7BAD8E3803E05B08876842D9E6A0A545407A5067EDE3510CCC4478C040310AAF46051454D855D1A5521E2514AF676846650E0043BEBF453E7488B6DB8AAEFCC16E26A75C52BC0EF3C80DA3BB39F73B9852B54D9C606363438C45DAC4FF1A1913D81B9A80544177BA7DB6503A04A5405299F80A83FB7135FDE04F8CECC0962461C0E80298D219531C9CBF00A3BB5B84908B5A807739A63485128512C0478084C8964F9064CD4514CE92C30454AC25B48919B719C5A853010A2EB712B80975660456562C4C448C39162CA63AED14AF7F28875149857F9B8965BC1D04CB8EE2E67C14A493A3822FCD0A2DBA2677E719B8F2C8BD09431B82BA56007584BEEACAA1F081D244B0D771BDB0C8033B18CA9597443FF8CDF754569DCC2DC4D4C212E2BBEE88925CE73034E19167CC7AC46059CD3B9EBBF6BC3A476F08438C61971AF139A248821002480F42C2B9C0979AD3BC6868565CA3FCBC124A7548D53F56B51C9F8AA387B59B07638C7AA45704420B3C24642035A7884CB42F877260C29697809AA7482E3FC356D8CA061C1C443CF24C4535BDECCB02C3E3B8B1D90E5B47BD11615CAF849DA5811AA743B9BD781", + "0C470187E81AF9BDB4D1307303F615ACE2A58E7ECB3BE260E9F7C1E10EB3A84F207D2E75A30C7C741EA45FB04A9473C1425F80A9186A7F2625EA6ABB4AAEA3BB50602DF23ACF8E452CC01A909EC9034ACB47B969D904213F0A79EDB7766D0290005C954A1DA0155F7318BE854FDB038D019C1904B714F0514AC331C3813BD703B45076365BE4B47EC510A9F585907BC0F461A6BEFE13A2667593E12134A86AC139777A50CCDAD16B6891A0871621B387684B5226368400164B29109328F672CADADF7648377CD11C9232094165BB1CF12F694F940C3CD784C84925BA74C8A49DC27CDA4C553C85334A860A8A55D8A75969977AD1F505B9B20CEECEB24A262C707843310F39434390EA5315A67491F0592BF722A1C2658C8A720991B26561E14B178C3A1028003CAB8B69F60828F47B876D43D3F193C3820804068A5CAE76DC3F27F5F1323E6A2797B9A13C86713A83BA9C161899CF295CFB4A4AA443F32D16B72616A0DB4D3849FC41A7A6BA87F4AF757A0AB1956518F0C1D832AF7B7282D8BD81A2237107EE60D81E28EB64D6A153AE0EAA1A25797C284EF52DB5EAA6DF8EC3A0BC5FFA730DB0DDE8C5F38F266D5C680A78D264A7B96\nct = 7E2B3F001C83AFB604595634A841E0D71327502B46D289E4D5DD27ABBD0400206BC1CC315DAE0F8F9BB8C69676B5FD0DFAD5DD4D05609B5AC327F77EECED6D72139E4529574CBE4EFC1A796033DCE9DFF2436E18A627FF4B30748002AA858BF6B9F12ACCCA22088B727D74C1C3EF565956ED029B661FFAC19F00C54CDDE3D86EB59725EF82FAA2AB55BF3ABF0789E037CB95F233E93C7B73471EDCAC5CA8D5D94968EEC87E0D9CEA8F2ED79C3BFD8456FBB1727E576371264B22334CA4492D0EAE431AD6AEA4524F22C08F8C3928B703D7D7C23481622968AD7CC52D10E38F0B164C45F3742238555806283C1D781E8714030BF60D3CF414D00FA1C46F5528DB038618E918E98A6A36D7C092575E1EC5A6961485368147A38F52BEA70089244EE06DA2A814F0478299AE34896089EE6A7A2701512443E492E9FCFDE204B45965CCE878355E23A670779B140DEB556DBAC7448CAE69A90BF2359F8D6A8023233BFF39C195B16754CD1A43567B449742E643F16BADD4907922F9C7E3B333AE55F2B28D3FF896E83AD412ACE77AA18D76A50FFD417BBF2F5CAB1E23AE417E855F697E4937E988C0040DEA224BF0F99D3521252A4F8EA00F1311ADF4A61706610BB2A84D761A294806B03DE026096681A0D249BFFF4226F1CEE5164C3D54180E7123D2069663505014B0B445CC0ABF27AB73209E89A1FDE1BFC0229A6D2E9FCD9562B7BDC5D4E63A7955EA8CC5BB8FC0C2AA23E1D576269E4CC0696DF1A404BB9E6821BF0B541E1BC2EB643691EE390E662A8A8AF177DA61720336183CFE8B5963EFFBFB97CF9A12DF2B6FE59A613E693D25A672FFE633575D5A2E5B6F97C122D7E1823A299DC87956C0CC6E35F055BA9F08916E163D3D0609EF7225C9C507B8C3021A6FEDE3E48DF94B21E235A38A6A506C9436EB83B19B33EAD5649012CC3EB866493965E55B09024910DF0E45962E46C33DBFC7E1F7B854BB30197BEBE2956108F67243D52DAAEDF84AA65AF71373B8BFE221C70EF833ED27B2CAA2FA744B322A4AA7EDC1854ECB932BC4008A284F4C06EB87592068123E6A137F4D5FC216DE6B17C5C6F9819928C9ACB9E9054B101C320DF769B12D9ED4E0D1579781B91F9C97D2D55C34CF4309C33E26D7D616A3B52E3D3C59938BCF11F6BCD70FB420A6590A4BE120630ECD6C2368BCFD7632B522854947C0251ED4906BA4BDA3292019F1730A17003802A43562469E6EAA1C23E41CF88D2FE7AE803E4FBE44968EEBD1B714E25DA525349E941EB7B651AA391596E47AD9F3E298D1A748348FB6A322716DF3A027050501E5ADFAF41FCAC0D5F22AC5360A049F3638B0C90FF249FF1A6A1208BAA375DD19E79A6DCFC33BD9920D854C8EB12AD4C8806E3DE032A3751F005F59377D51D5E70012D318D553AF10162674DDCB19F11C1A9C07DFB948C700EC50F87802A9A18C8FCD5239CA762350CF436AC84CF467003035638D9D8B9B145F2D7F35BEE3BD00C59D6119B634111E1896DE86F5FBF359E9C86BACD73F9F432ABBBA\nss = 71156980B8970FED7F2213594630CA825EA8EADE58CC8225DF8111460412B762\n\ncount = 7\nseed = AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB\ngenerateEntropy = d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209\nencapEntropyPreHash = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663\npk = 89C28969078E11664CA1554ECA81B9542BAE2EA8CC12B44E81B3354818141AF0B494543D4674160A086F7E8755A87258E7E6A6AEB96955286924B42636E04583F74184133D8ACB9067925F4969642F274085F70FC12361FF96C3130B143E23797F2A3A6CC757C97454CC8AA5D9C062F9254F4CC7335B44CB66DC712B4677C290CCBBA08CFC3948C535BE29F44736A23B4C8CCB3978404E419A08A67AA555BECB48BCC161CBC5492B55E3498E74BB515C28A7A44A3AFA0148EC3411D82A1AE103513074A13938A5FC17DFABAD006D90455B4B5E45079D7BBE956C7A18A8BEC9A64C1DB72544CB00C6997D545AC7E3BC5C6565885536AF486417E728CC99C78CFA12A1F7697F1AD26EFEB7262800AC4E0121E766AA9BF0A74AE635074C62FB6CA79975761419B12A985ED7A2C8788C9020462FB5764C087681BE1595A5EA4EE7234AA2D22F4119B559A536E0DA0E8D0B2E493C2B5BD576459994ACD684A81A0955684818E1B88E348446A22C9143A4EEFC7D8EC678624763D4548FE2451F078582C93C986B0417E1AABABDD76DC0532E252B59E47370E81951EF75AD48C223316A40237152E3508EC164C7375594F73B5F0483C560F52F250AAEF28431E9D1B2B9DC650D2371BBB7C8360C72369755BD8696FC5C83FCA76A7FC02EFF54CA60579CAEF6341385AEEE34C7182445BFDB549BC59F70B76368DA88D47386F75968ABA093E8F42DD3C7CD68C8028A90CB0C93CB44D42EF9D15E6CA978ED5B88914C4E20768028F2C927A33433D33C5E6A45A6C5AE8C252A83E68EC121347B025865F26912B89A9DA7472B75B9ABA75581852B97D27EA7C9C5C7E8BEBC0094C01947F43A2C6501C97E43231310167ECCBC4C3A2022839584A12AD5B51B4CD308C94302E58C70EFF7B24FAA051CF548B5A73AB4254179EAA038EC95D4D4182D2971084CB33A6CA1106076DFA76EC0C4B3BB5C7266A481001CAD07D12051A77E31603BF47C62DBF959C89774587111DB1B038AE834E0A08C27F2B772A967179A9BADA1AC12BCB8FD3B06CA44B3F11A6762AB51A9A0B67FB83DEF8C9A712A1469B719F2557E5A03C6BAC808D0E0AA304955A3E961618920D0BC2347C74AD6725A9A855D1D8456D2C26ADDD849E59B7CE7C85765064ED6D63039E368E9F18D4FA11E16F8CC88BB3FFB40B4C6269996DA8A6B5586365292B5B1C78BF4161C171E2FC7A6A8293A96D61D683275EAFCADFED74473E30A1026809076A1025398B745BE723A78E008C85B558D2B76392F5015D1024C171C0FC6C7C0C0E631BEF57166E660269231C3216FB08B6CFF0A420AA413EC1285B7B5AE9FBB15F9FA6B8AF29EC061996A7612DE524C7E0724766BB51E1264AB50C3A095815645B1D1021060B90C96555E8A001044D16CFFD7719858065EFCA6C2654EA25506F0541FAE242DBB154E420C0DD4E13A79053B431B7C00768BF0F781810A0832A2B814C5517AA1A0949523E12AA35893912256A7370BCD9FAA30788B631B87731CC5C831A26E8F48AD7CF9C935301AA8CB006AC59FD2EA5BDC1736B2A5523FF3C4D8F429DC037292E863A087BB29CC2732BA30BF11490DBB1F3ADB3448D6110A774B25D242602C250999CE69D1B32AD3702602E6D28FDACDBD2A03546764C4FC1C62C0EFB3462C7C88AB8D94E20B\nsk = 0FCBAC2FD83A9EEACE0215C784E20260F0991B225897E94ECF93368B79565B478731537EAC74550CD599D5268E03A25CF327606686AB8864677907A3C3555018B478FBE125498652D5259A31C2B4649C14C89BBC5758A9B53C64E95BC9CE30C306372D431CBC642C0D60E25136C3919F3BB48B280B9D5CA0B21BB4E1510AC49AABDF02C9FD66420B475D0731918A4A5D3C7A963A468FB7A86C128988EC36C34F475F2B87791F5604863BA6DCA297EE29238BA79EEEC5096E9B336CF0B24DBCC9FEB8BFD77AC888554472D7732E7492C231302A073680C684870B86A05592355BAF2620B51DDC7B17C9328D7A74DA6367D9EC2B87E9221C297B5398CFB55C10E8A68323AABBED806C2272C192FB180E7A5B958A02DCA5C55654A43C74216B192522BC2A2DC05BF865062CF56839831EBB837A3ED8C7368C15933730667B7463AB7026848BC9BA14616B2E88E17ACA4109B5DB56510B408465523307619FCA752919B947EB40E5E8C19A7B4A9099734D648DAAC8C81C1C628C895400E245DF8A324899273EFB441B564305EC48AB305C69D37E846AC9B77A2917915E82286DDB397936769BE7E37FA7F27A003090C7F2B9B395A41370B5A38C07C2D8314627267FA06BFC416D8AC1155DF645C6150BEE70C4CAD8C6A5C564BA2571C9BC9BFAF0C2D12578C8198D49E1414CBA5749D712556A537A4131F3F085F9047735482E23342B218101AD30122113060CCA4196F778C77CAD2EE58B6F23071A85B79C1215F0A7C8745ABCDB768C3C26042D09A9A0355A5C45745D1ACF52C205B949ACF581AB75CAC74F2364406A43A74269645166FE167642900D169A1E84929DA4CB361E80C42DC702A79364F1D664528B6CEC667BF230078AF06A0B48466DC90B34EA7101512E37D8BA3A351D7023AEE652351AE514B8D217FAF09A07654B0CBA1850041D7206CECB05C8F6703F762C97DBF82255DAAFCC3608E8891E3AD8B3D4E18DBCF6A1C2E74CDEB87D15236D70943DAA722481692890A548D7C69A14FCC1155202CA4941C3900B57A452F281091A94781C64A9583C8D302C21484CC6159B88A931AEDC4291E097982EEB0528C152A43B97DEA2A0B36922FC60C226B61068C792F377B9F655940D73702D41BC515086E8F9266C53A4C15A35907CB2FC2A2F19BC5F974034677A33B648322CC9BFCC6B947B5346DF2044249623E53430895295327C9B35F59ECD4A9521F4B93A4C031A624C12F40BA17B9F36908E462B928AD452EC74B84F9B5C1C69660038C85D6743F8A5A65B3787B5640D683B7A45009A1EFCB5E50A35244C9431F21F1B6826311673832CCBC1794FEA917268F5323726698F67BDB41BCC012218929649C972149393845DCBAC7FB58582964405D4ADEB814037A39E512C3FCF72A22AB70E21FBA3822B493DF9983866412F0439E1A613914042C982739031949B2780D8133E13E632FC4281DE567A333C5D8AD458B848CCD65BC87A8B6B29134556A6780EB7B02E4437AE69C09E304210D5CCE3CA3DFEF261A809BC5DC44787A20AFFF49F3E0156E7B428AE1CBD3292C9D818844D4767342708E4016EB9BB0F7099876C26729F443E7CB3B9666441DBA01C8397953F586E3DA45789C28969078E11664CA1554ECA81B9", + "542BAE2EA8CC12B44E81B3354818141AF0B494543D4674160A086F7E8755A87258E7E6A6AEB96955286924B42636E04583F74184133D8ACB9067925F4969642F274085F70FC12361FF96C3130B143E23797F2A3A6CC757C97454CC8AA5D9C062F9254F4CC7335B44CB66DC712B4677C290CCBBA08CFC3948C535BE29F44736A23B4C8CCB3978404E419A08A67AA555BECB48BCC161CBC5492B55E3498E74BB515C28A7A44A3AFA0148EC3411D82A1AE103513074A13938A5FC17DFABAD006D90455B4B5E45079D7BBE956C7A18A8BEC9A64C1DB72544CB00C6997D545AC7E3BC5C6565885536AF486417E728CC99C78CFA12A1F7697F1AD26EFEB7262800AC4E0121E766AA9BF0A74AE635074C62FB6CA79975761419B12A985ED7A2C8788C9020462FB5764C087681BE1595A5EA4EE7234AA2D22F4119B559A536E0DA0E8D0B2E493C2B5BD576459994ACD684A81A0955684818E1B88E348446A22C9143A4EEFC7D8EC678624763D4548FE2451F078582C93C986B0417E1AABABDD76DC0532E252B59E47370E81951EF75AD48C223316A40237152E3508EC164C7375594F73B5F0483C560F52F250AAEF28431E9D1B2B9DC650D2371BBB7C8360C72369755BD8696FC5C83FCA76A7FC02EFF54CA60579CAEF6341385AEEE34C7182445BFDB549BC59F70B76368DA88D47386F75968ABA093E8F42DD3C7CD68C8028A90CB0C93CB44D42EF9D15E6CA978ED5B88914C4E20768028F2C927A33433D33C5E6A45A6C5AE8C252A83E68EC121347B025865F26912B89A9DA7472B75B9ABA75581852B97D27EA7C9C5C7E8BEBC0094C01947F43A2C6501C97E43231310167ECCBC4C3A2022839584A12AD5B51B4CD308C94302E58C70EFF7B24FAA051CF548B5A73AB4254179EAA038EC95D4D4182D2971084CB33A6CA1106076DFA76EC0C4B3BB5C7266A481001CAD07D12051A77E31603BF47C62DBF959C89774587111DB1B038AE834E0A08C27F2B772A967179A9BADA1AC12BCB8FD3B06CA44B3F11A6762AB51A9A0B67FB83DEF8C9A712A1469B719F2557E5A03C6BAC808D0E0AA304955A3E961618920D0BC2347C74AD6725A9A855D1D8456D2C26ADDD849E59B7CE7C85765064ED6D63039E368E9F18D4FA11E16F8CC88BB3FFB40B4C6269996DA8A6B5586365292B5B1C78BF4161C171E2FC7A6A8293A96D61D683275EAFCADFED74473E30A1026809076A1025398B745BE723A78E008C85B558D2B76392F5015D1024C171C0FC6C7C0C0E631BEF57166E660269231C3216FB08B6CFF0A420AA413EC1285B7B5AE9FBB15F9FA6B8AF29EC061996A7612DE524C7E0724766BB51E1264AB50C3A095815645B1D1021060B90C96555E8A001044D16CFFD7719858065EFCA6C2654EA25506F0541FAE242DBB154E420C0DD4E13A79053B431B7C00768BF0F781810A0832A2B814C5517AA1A0949523E12AA35893912256A7370BCD9FAA30788B631B87731CC5C831A26E8F48AD7CF9C935301AA8CB006AC59FD2EA5BDC1736B2A5523FF3C4D8F429DC037292E863A087BB29CC2732BA30BF11490DBB1F3ADB3448D6110A774B25D242602C250999CE69D1B32AD3702602E6D28FDACDBD2A03546764C4FC1C62C0EFB3462C7C88AB8D94E20B2B757AC0425152BEF72ED852AB1EB44F4359499407BB6A020FF843A31657C5FE99DAF37400CFE59841AFC412EC97F2929DC84A6F3C36F378EE84CE3E46CD1209\nct = 269412479F44C884A094A5B259F76D28CDCA0361BA64C402491F98789F0D46B7E31E7E93B17E8931AA3F83E3D6B6DF59B1DEC49C1532EFACC9718247529E38856FC982E92AF949AE1BDEDA805E8C43E05D2D8C305E2A753F322098483616C9D48568BB341C3818A7316EE7D19145238C38CD3E04DC1CC6E7934783D3979C0827D0BFA69E5BF8F8A8F3B0299090F7468E1094DDDB0A231E5A516AE2F38275D2F125F850D7B3C6137F0DA50BF680F13BD7F001E978A54C06BFECE1401039215753BEBCCF7B1B99F219E4D562E235BF48976CC59F3A3AB470ECC89B426787AD39C326CFC2E53DDD55FE02D0863C0F9BF1B1E1EF0D397990F9C13A6993D63E140A7F936B8048DECC487576DF2722A00335ED4C620452188C5FE9356169D8C48EAB7E2AC66471A7E35BED338DEA11333B190DA230D8A8063CE734D208141C9EF622F30E5CBC1424488B708F955B5FD1A0E613580BBA1866C1A027CFB83DEF2CC92063693EAAF7C087ADCBAED63F891E2A9CB295659E2B72B0C3CE8C6DB44B9DEC84A0AE491D07DBEBF355C4C05FD2940B30774DDAB5E0E448245D39E13634C1B49450B0E77F9F22F76C053884882C4F32B34748140A4A3DC3A296E6577F84CD047563067ACBB315961278D667E6FB67325F3987A37149F463F2F43416DADC28679A0EB3F1D20C36AF04DA09384DA537AAD03BDD880AD06A606CA720A42C4034801E5DCA8E250140B3C09B9F7EE28E242915E8B23C936529CEBE9C887095B5AD25798C10B474E4D2D682E3C5E7C83CB2B4ADE983AF27636A9C2882DE397DBAF486EFB4464D19F72AA8C6436EC561F9387E4B44B9831405B2462D8293A954688804E2BC620BF767CA7468F5A0431C4A871D521C416A36C8C0039D02CAA91A633838B83B6AE7879E2E9EACA55C1792D9DC0C098B243406A773B79BD7AE46A377341766A1FB173D38A32AF97C75F395248402899ECB0AE883A6E96EC34677E8B14293E8E5F67CF4ED94D4A7EF45B7C3DF12647D3D9DF00A6FCEF8221050E861D539A86438D7694474449DA409589205A7B513C434B95563AEE108FFACDCCD8CD54505F55E086BC615D15328BA7E72C81737E1A2E8B6DC14746B21CAD2273818CCFAA1C9B01B22D347554533FAF1524BCB2AE638DFDE9955F74CCA13A9FF82FD9EADC556704626214E2C928DB464CE895819A4A12D4C4317FB840E8444EABA4C412805D63AD74EDDE6F7A9770FE679FBB028485F210725D0DB99EB221AB67F60EDE0C6EFF26B914B7D887A97F80C752C0035D632D903D2D7351EBFD0B07B50935AC4054787D83B2B98E23C1C8E03E6284B83569C177194FC2B85E9A2FF15FCCB4CCB66D7AA53DE89167036DF23E4DCEB6113407E6C14DF4847ADFAC1628464327F59A37DD26D60E433D4DAA8BFE4124F225E339D91CB9D2A57FCB5968488C29514CCED169E8DABB400B26EC2377D0EA71C1FB3958E4927EDE45DFCB024AD7C16550C69187FBF6DFD055322725160F8C32D8F48DE48E0A52872058A7C6B380510E028260CAE\nss = EFF5E4CE44FE0D0B77CF8109D46C8A888399D1608AD9E2248181BD205A0B23D9\n\ncount = 8\nseed = CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41\ngenerateEntropy = 0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004\nencapEntropyPreHash = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2\npk = 764B51D1DABF923518DE898C5E7CB5E0066FD69522F5889DC05C41A472C983583333132052A1C93A464120B325764B8665CA42555B98D8D6A93C88A0A383AB51280F52873F2BE26E12C131677027C616711D478342CB424B0463C88161ED84BF6E869ABE9CB915D13534D2756DD72343359E9911624DC7C6E828B19D6CB178C43A5CEB9360D2939DF2744ACCB4DFE8AA5ECA35BF87C6BA265FB4AB7C4888516EC91E52C4030F5453E6BC9103B9C19CD83E69048272855B11B8AF3EDC09B04AB31179BEE59ABC76726FBE9612D271B7010844F62535F2F30D8417C35F17C1619B055FAB6A0F5458568C753310299FCB335A7697E7CBC9B9EB1B14AC2D0DDB765B266B6D68BDB5B0236895328540B20F91BBD2910625E674B33A4F8B6C1B4F66C4130C2E973AB72D809282CA63EDAB71268C02A9D020BFC805410AAE2DD4B699448A56049D1E9A58C5FC2ABE159DEC69C5027099A3B57D3A2560CE24A6F5017D32E00F3078B792309384421878CCA555B7065D57537C804E10BAC052788769B7C1121A78911A153FB56A365A2F97B070D7B61724D0C4D14C295D78BE57A8AADB873D3AF6B74D020B8654CF48543DE8CA22371A48DED585B7073ECEE0C44EEC27C85B5A68F6B454B0CB10692039CC68EC2C2BF892804520C71BE5B7BADB807B4059A3D87D32548BA3E4B698CA150D784A8C2C35A67A8C92C68AC0037888B65A4C9800BA7A1EC050627AF648FB61C87CC55B8243545AA514CBC550A8804C8598CD35786EB8C6B06077A1E2D4344E4A6BAA789C305B6326E0BBD4402DBE26CEC08A7C1A19457BC2677F15B984A74FBC52CDCE48618D50C47400011B392908AC2CF08A579783A80FB2990CEA90EEE90B7DD81E6CC9C961372D8C720D7EB223D5A6A16D4571C1A93213B32289934F7B30A63527C6399920086940B7696503E623E63A050F4B69810B6E6F6729E5782B572221F596A09A1879BBB46A62A955043A30A2AA3E62E02CE1AB6F3D03693A8CB653E361D8783FFA37274AE06A3F2292F1A6557182006E493FF2653437A64DBEA950BF6A8CA8836407FB489D42A6F6257770310F28715BC6411C81486CEF3CB9AB500558F070F4A15817F8C177D63CAFB176CAF3B2B1CB7B7254C18FE15111FCAB9E9A9682F41C9FD247EC532CCEF514860A3FED330255323DAFE46EED198041D732538C9424D43FE2F5481650470F08906791B2BFE65A445BB26AC87D9BD04AA648A54DC13A137B60E5C2779FE4B5A866620DC2829D42384AEA9AB1552FCA920F8929B7BAA059DEA53E6A5B3E492A6E45B5AE11F6AD24D035D4246A0CD53436687A0204A1DE29AAD2C8B53AD4B938A57C2E29555219544FF64115CBA2668B54C6EA8779146980B58A2E669124A81ED4420C87B0601DE23E3CCBA915FAAD0C2B47EF6238DBA9449274C64CCCCD85E91712470E8F9A2866720059A8501C7762C0883CF9827BFD62BDC0882EE03B457BE2B2794B8BECF74EC0DA4684282200A294C13C8A9FF376C1187911121BDD886F27514846F740B72AAD5544CBD97A7E208635480ACDDF404FC067C82A45B5C97829F06ABCA5201429E9A516F66E65D07075CBC0C60C2A9734BAADD68F421617FBF9515B569FD08BF3AEF948095DE1AFE74BBC3BDBB45FD8F92EDDBF0C682C81A98F930F6165\nsk = A5C7981510819EA27D27A945A0F6619D730DD196B6F3A158A4C48ACFB82D1C348540160B0CC665C43C4C0E4567B46867CED06D2CF228D0B64706227593DB7392395B7EA95360105C1BB05472787430654AA03B6E894C2ADD2A0467EA51B9486F3DF18274C0A2079459DF3B9AEAB15D203B466EA426911572251B0C8FB51A31AA142BDC4142E393D3C527C841A03F796E0CF7CC71DACB47456FDD386527BCCF6E43013EEB755924A22E3A55F74A8974B38E06908349FB3DA5887D1A041C8ACC6F07A75198462353942267D7600D5243095BB012D2A70BE0A3FB2BB599832F8AA68652846BA501BAB3AA574AD08BC991C8B86717B87A45041657D0264F35F0C2B70324EAC43D591202CFDB9A7D357489F70F86D6308D3382CF9139106CB28D947AE3BC389EF18B728C1568436B3EF80644009A80F01EF550C794011E44F2812EF507BD55820A872B90E797626B8EF2D94012B4CF639BC5C8A7B87306753F93CB12E46A66C4B2053C037B87C51436CC83B884F7634A6", + "950C419684AF3B78D41006467105F753194144539DF45AC7FA46E71815F53D2304B474A434B02517B083B058AED078DCF86746313BD8108148EA34658613560CA722A126DDA147AF8C5733705BC8343331BACC5B5B80E424CCF6114955056329A68A2A6403D65197C21DA02A390C41EF713A814A798A434145B9E3A5C31A9614CDAC8A8BCAB6B5274490F5C45B2A307F492C28FF40EE39C2068A5826E8466542559E9409FF11B463E9A4EBA0A2172EC8EA6332D3A5BB66531B670C52CC2F8B651B513E60A9E64795369E0C2CF56A9921669299B6B5399537E112AC358112810ABC6945BDE69AADA92552A10219A630E26E4AC7D9B5C7469A960AC64A6D127971296C53A15DF4C847D061E69CC030B9CABC6E58903C5ADC88882CAC147F2888263ECB6AE97A9B2AA245F131E2E2939F5C8BB8FFC012CB578B9BABF90DB062502B1923CA88B35C424FC6524128FD1D7B5CA719F5A9A538A51A97ABABCE07B006EB701AD8490B74462F93648FC39A2004DB6E951B4C8219CE49395891594353B92B6B496D09376FB28711D87221851A5FDAB80CC52A6352C062F06C80F891DA2A07573B42BF0F6CD5D6B63FD4B1C5BF2572FC8460385A642E6290FB79A9B1CB18CBCB34BD87F7EB595F0598C67709D72011FBDD07A0EB6616A88B8E33571BFA7597BE4CBD6976B93E32C2C088DE3AB59DCF2234E553A5B2AB143C46DF13211E816AED6D02BF6C13FA7F8B282237F249AAEDBD3A6FE8771014C1B811C05FE86102C0B0E7E9B961C1000C82408D8A8AA381552920803418C49E1662C7ED8C3D35763C510585A78664EA0012A8A02F34B2BD7E96EE5C298DC296537C985577CAC3E310568353EC2CA8EEAB4BB1EE2393D5B3CDD25305B148FD8AB11F60B5871E9C9359A46A5DA003E98B61D82C51CD9262764301C86268DB87FA6273F9FA3C35B1C1FD822AAF2F74EDF73AB5AF9175070BDD7D5CC7600A516726C3E49348D138D19836391A54954AC4A0C029B1441C37965422019C2CA49CFCA81317A211E22EA2297B865DA163A0AE2A9DC25701E71847A05754CB733620A824F090D591C51C345420E226B8F3B846FD356E78B87764B51D1DABF923518DE898C5E7CB5E0066FD69522F5889DC05C41A472C983583333132052A1C93A464120B325764B8665CA42555B98D8D6A93C88A0A383AB51280F52873F2BE26E12C131677027C616711D478342CB424B0463C88161ED84BF6E869ABE9CB915D13534D2756DD72343359E9911624DC7C6E828B19D6CB178C43A5CEB9360D2939DF2744ACCB4DFE8AA5ECA35BF87C6BA265FB4AB7C4888516EC91E52C4030F5453E6BC9103B9C19CD83E69048272855B11B8AF3EDC09B04AB31179BEE59ABC76726FBE9612D271B7010844F62535F2F30D8417C35F17C1619B055FAB6A0F5458568C753310299FCB335A7697E7CBC9B9EB1B14AC2D0DDB765B266B6D68BDB5B0236895328540B20F91BBD2910625E674B33A4F8B6C1B4F66C4130C2E973AB72D809282CA63EDAB71268C02A9D020BFC805410AAE2DD4B699448A56049D1E9A58C5FC2ABE159DEC69C5027099A3B57D3A2560CE24A6F5017D32E00F3078B792309384421878CCA555B7065D57537C804E10BAC052788769B7C1121A78911A153FB56A365A2F97B070D7B61724D0C4D14C295D78BE57A8AADB873D3AF6B74D020B8654CF48543DE8CA22371A48DED585B7073ECEE0C44EEC27C85B5A68F6B454B0CB10692039CC68EC2C2BF892804520C71BE5B7BADB807B4059A3D87D32548BA3E4B698CA150D784A8C2C35A67A8C92C68AC0037888B65A4C9800BA7A1EC050627AF648FB61C87CC55B8243545AA514CBC550A8804C8598CD35786EB8C6B06077A1E2D4344E4A6BAA789C305B6326E0BBD4402DBE26CEC08A7C1A19457BC2677F15B984A74FBC52CDCE48618D50C47400011B392908AC2CF08A579783A80FB2990CEA90EEE90B7DD81E6CC9C961372D8C720D7EB223D5A6A16D4571C1A93213B32289934F7B30A63527C6399920086940B7696503E623E63A050F4B69810B6E6F6729E5782B572221F596A09A1879BBB46A62A955043A30A2AA3E62E02CE1AB6F3D03693A8CB653E361D8783FFA37274AE06A3F2292F1A6557182006E493FF2653437A64DBEA950BF6A8CA8836407FB489D42A6F6257770310F28715BC6411C81486CEF3CB9AB500558F070F4A15817F8C177D63CAFB176CAF3B2B1CB7B7254C18FE15111FCAB9E9A9682F41C9FD247EC532CCEF514860A3FED330255323DAFE46EED198041D732538C9424D43FE2F5481650470F08906791B2BFE65A445BB26AC87D9BD04AA648A54DC13A137B60E5C2779FE4B5A866620DC2829D42384AEA9AB1552FCA920F8929B7BAA059DEA53E6A5B3E492A6E45B5AE11F6AD24D035D4246A0CD53436687A0204A1DE29AAD2C8B53AD4B938A57C2E29555219544FF64115CBA2668B54C6EA8779146980B58A2E669124A81ED4420C87B0601DE23E3CCBA915FAAD0C2B47EF6238DBA9449274C64CCCCD85E91712470E8F9A2866720059A8501C7762C0883CF9827BFD62BDC0882EE03B457BE2B2794B8BECF74EC0DA4684282200A294C13C8A9FF376C1187911121BDD886F27514846F740B72AAD5544CBD97A7E208635480ACDDF404FC067C82A45B5C97829F06ABCA5201429E9A516F66E65D07075CBC0C60C2A9734BAADD68F421617FBF9515B569FD08BF3AEF948095DE1AFE74BBC3BDBB45FD8F92EDDBF0C682C81A98F930F616553B9D62E64F9069D9FB94EA2C0806459B201531F4FDDD708D162981CC1FB3757DA1804DDB5AA9B1C6A47A98F8505A49BAE2AFFDE5FE75E69E828E546A6771004\nct = 106849C5DA689EF3A848336B4AB6542F621C0B9B5E8C5AC0B06D3BDD7336EFFB87DAF2DB0ABA609ACB904FB291FFF9B6CA74BCFDBF7C563B16C0553E608E8D094B8C195BCD2B2D58FE731D4A4660F4743DFF2A16267490F7F00AF42946D0981C7AC0394AC78A44EA1D4CE07751E064A27D8B223ED37A2AE3B74E831CD66855545AB08B7D28473A031A33BD606F0DEABBB62A06812CA11D9D1C33A70C5D214F42BA16C5CCF7D0E9F2B23C76F4E9ECD8D9D80CA64BD04E473A308539570D5959937D0B7670D8554D82AC97E8A0AE8497FFAE014DDBB6A138B37C08B75E8110F2F9BD372153CDAAF3379E88070C16F177D96CB115E14863C098AB2B3B207FECB96122ACDBD207FCEFDEF90AB813AC6D5E1362903875D5B6DA35276069C5C0D3BF1F0261AEF6719EE0861B3E2C5938DDE47860352D02E354C363CAC9D0CD944BAC7C61000BA976B20516998672EBA11E68785C8B8603C1BECDACC1DB883430DEB8501638959D489D8F51BA28BD299BCD46E9188031A906C06D0F54873A8D065900822372D46C9365CE129173201FF301AA423EA13D35896D8CE6491B7BE61190A803F9C53847C22205D011504E1B4C4E98EA395DAC99193B9F44273EC4E0F4CD6468371CABC76708831DE5201ACDE1C5A3A10F51BF5F986E038F26471A1FDC7803762EE240994CFA3C2E9A5C12C4954FEEDDBF49EA264645BAD8BEBC1FF536B02BB4207F2FD1B2E70B3FBB6C23CBDA0DEDACBB1F090E5CDD5210B650990E862F0A6AB2625871FF91650D09D7EA4DA7DBF6CB166AEED23AEE7ADF2379267C708FC5D22BD2C12F22B3B944E04A79C10FFF474A982B6CBF699DECE2104DEC8EA7F6B4D9E486CBD748CD9CE83E76F3F05111753F021D1629D62CD16B0FC4A39128B8B398179F1B33D94017DBDCEA084A9508AABEAE589E6365D48111E849D1656560D13844FC4AD7A2D0157E706B0BDEA00D60240DF2C5D70C223162241EEA92CCA23969CBFB3BE7BA4FD278D831EDD8DC941F74D21E7B296456303D82D4B3E6E5058220804158E23EACA8068354676B94577505D6414A27DE9FA178AE851346FE3254A5F9490917ADB080F332C2F9169D313DAAB26C034502E311685CD57EB66277685EC7AD6C5D53A02909128A348E097F5E0F7B75A7622B88818F8971C0840FA7592D245E32ED9B4A958370EAA14010A0BD92D28220E0F9CD7EFB0C0A296C46DEA9819C6AD0861164C39E7BF6F1B7AFB0DF2D290E233A30B1D6C27B74D2A4F4DD6B3953ADA3A7C0E4E3A4F4F07DDF2DB4F7460204761F717FD5C69F156C15E8206E93CEB426FE89FDEB4282BFE746F50D0B4BF9E5950CE8F03ABAB8B211BC619F580678EBBF9AEB439578BD3F9ABCB44F2C53B7B84495C876B2E1911F9F1ABFAD34122B8B7B660F5D2E84DE2AC504A59AF5E0C722A9265B83B8440B73B9CD130576F3EAE5525F757E23396A755619349E5B168EF891BD742367FF2EE5C5628245E7FC0D0D03FADCF651B4AA7C33C69C3E1F580DECDFE50263200D5085E0D8F19C2AB6\nss = 25C35F5858D03291C0132C970E6E072D8A7B33419B984B391A12891F878D981F\n\ncount = 9\nseed = B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846\ngenerateEntropy = d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9\nencapEntropyPreHash = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b\npk = 5A1278BF11B37FBAB1DB212359473012F3B545301DDC833C69A75AFE16744557B5E28BC0EE895DA16C2C5DD34FE6783949D555E580C1BE7994BB008DAF27A47F554932B87222E82EC670490CA5139FF49D5ED896218825056A8639B31D3AC8550356A408A01404C6AA9C2B7284E7C7C27036256B7902445DDE00630D81930F4CCC518B9EFD8AB24FC16A365B8068C90F7E09BBD23C2A6AB12792D245551A9894F704042501C8FC49EEAA0132701E29A3C97834530A7C61F1B8440822CD1BB6B11DCA2A5951B4DEB0B1268C2F5AA8CF76A6BD0BE3013A37CA1A903AC634405ECB3714BC54610BAA63BACF0A263D8CB018B03B0A286083998A7E8B2A573E570179712130A19F9EBC2337D43926F9C96460996CC03199D81A0E19259DA696FECCA7906931A787A5C264826099A3E03339295B587E7A4EFEC6A11AAAAB057AA8689473F1F211C6D85499C46746BB00BA687A17877E6650C678D13861337FAAA7045A16B8EB7173E7C08B6394B5F2B99EA3083BA175C55D350FD61B73AA790CA6F479FD4B01282B6BAEFA00A1946F6DFB855CE7BD50389D42856823301E01A228AC754CB65A0E323A0943B75741CB498CC499C8649B6BF87E991507194983AAD1B57994B7D79BBCF2EB3B5F8734CCF3CEA2662E95D486989144AEA22C94C363571AC7DCD81F577645CF19B313F849B422AFED963CDB701395020C2D18601A40A42429896AA9B0B1C10C4876928AEAC59862414E143722A0B94746ABD157343D15BB9FE500763B18C61B184407449B1B5BA8FB1554E4BB58AB99FAAAC9CDC3B698E64179B089B786204BF95EDA86474EE799440478348989C91C3462446724340CD2376C682907EDB58C85A4CE3EF46CC5D0CA345590AB14844B224735DC05E0E66EDE94258F395FE867AB9D8C1B0FA80743002A15DA197614295DC358F40758C9CC05E45BBC659B93ED611AA58845D94ACC7AA75DEBA56D4D83C640C252975BC3165254C92957B78C9583B370AD785F2C16CD5CB9913839939C7293E6B956E23CC5D14CB3AB2A2E94F179BB076355157920085236F60B84449D43AC89C2B46D", + "AFA6B784438F3510BFC48357A5681043BA7428583BB5E912B08786562579DF58A41BDB82114344B3EA3574B997F8564248210D4E50AB2277100B9A5423178B1F138E9D427762253CFFC3CD095CB53A776F4FE015B5168B1A9759AC4ACC77F90C69B307192B7B866753872A69813B1BCAAB5CBB8126D8998E78D99F5A527992B89495A28E3FA83E75337CA2B896172AC244AB7E30761C8E3A00890046E5F599EEAB65BF1A4CDEB5791CC10ADE7197FB5BC754233F3B10C9BA2240ADFC61C05231C36A6CF71AA752AB3C95C3756EF9373B677105D11F86E68036348BDD181F27407E344BCD297CB02BC44F077976ED588D6A846C2F839BC9BC4872617BDC17A7BAA97AF9A9322FF015956678E8D622CFB1A11ED929F29BB1F094C17F49417C09C1C443369123CAF8701199C43BFF97034EFC6999424144C9395D9063BB153C0ED82B1C5659BFB23D4CD2C758A26B6C448525060F686BB14873CBF5046B3A3033C5C8081027BF5E3C51F6FB6A1D54A77C46B0EA4299A9DA4AB03B95F9D3601F553D46800F661E2C9A7E548CA42E385CC6A0678F9E9D268FFCE02C4B465A46773432109A75\nsk = B04C33B257B199352A85B55624F1A1A42B2AB72C4810B839B2BB2F51A502CD498AA258373EB3BD43E03973D129E4FCB61DF58986809EC4EA4333659F03DC0FAB236CD4E815D3F9524E90A28A3A0AF869735B362FED9837855429700CB815C43A6E650E54D6267A832DC0385696274E1E73A12B5960A8409A4B4564DE909B797771B4839782526FD69ABF516A73F9EB8130F41CD6103A6E67C6724186D1C709D3D90141B1BC1C028E28324DE4846BCC6837FC243C54DBA144C40FCC6223FD19B8F54C11BC0982FFD366530ABAD387946E1495A3C05D9CFBB62B28778905AB7D576610A74B3DAAC9767A051B153AF7C6BF0177A4074397BE410411CB33DDCB895091990DFB85AEE15E9F288D01EC5628034A4ADB01DA09283493BAFFD36D224B1EFE096289A2AFD427B82F8B04EA44319F4A16BB07BD21026F2EF550B919AD01CB3744B37103EB54E62400E03367001510776698E28B4FC367A77F1B4690CC2916E8CCF1FA55AA3495014724F1E66EF7CA8283D917B501C931274D9808A8103004176BB69783C094BBBBECD5B90EA14E7CDB9768498B22332283F6A079991988AC6A85BB591EF299BC57027B0CA9932A41C14C193467374F133BB8539C2D5164EF11B70B4A2CFCDACDF6841CD835C4F4E174BE3C26B55770ACF4137666A431D669FD5775A71749922C0B223ABE36284FC880C3AA2A41F45A4A299C647D6738585287F7A47B88EA1C6C088C6207646D99CEF5F56A2E02CD3EA85202C7725DFC99D04B2D52600F0F89366A3A83F8DC74E4A27FC58A622061A6332403AE8CBD0179149B841F5E0BA193EC237AC57A4CD5528C10545CB75E35A20C3CE63950C09A7B0810B84124F3A00C9EBB67BDA9B2AB42113E631123B4A85897160637A32EB856D55C2905F7C655D40C84E92E773056D2392D43E33C4F9256DBFC7AA0683802D04D218139F829AE362C1F48096FE47B09756C36873CADC5300CEA8094E6F8925C1B81ADE69FEE5420B7E94555286CDB596E08CAA81F758022B3A949059AE91AA9B78A825703CD53D1235800681DBC7657A777BC267637CA2954C09344110A05E2BB90A83F95990986FB559BB1282778933631701393B705A5C122EC3645C1B364367C83444D30FA438EB3A478A0BAE14270CD49556399085C566D9E6C467DCA66A3F36370693AD5F86A9932773AE5064E9BC73FF7979A5510C88198BEEA7EE2AA494EB046E4D70A3F9CA0F88B234F6918F7EB41DB97A327654836510276E0154E7A4DFA088B8ACC5F02F598D1494BFBD07C3132C5EF6C3B466606B3D93DA2E69C96744095435FCACC2D24C3016002B5C4B988877CCDB9233C490A8B121BA7821B529DE85E638168B0565D50F735D1CB54CBA91CFC1B9EFF882A643121E877C43B6147A2A8266196346859CE53340208253CA419276B884DBB3B7A30AC3DE983C75AD73995A0B62DE7563EC9A4A715BCDF376DFB6433DE691C54E660F4AAA4B184015026B6189415E66C90DD32C0B015AEE63B5D8B3CB9EA206E45AB4938BC86FC54C7598C6553C29AC34B2213B90AFD144C8B4629A560382778B28D666667CAAAD49633A8F985730318EB033374B5CBEBACC7F453CCD8E77C5A9ABC12DA1BC1733E5A1278BF11B37FBAB1DB212359473012F3B545301DDC833C69A75AFE16744557B5E28BC0EE895DA16C2C5DD34FE6783949D555E580C1BE7994BB008DAF27A47F554932B87222E82EC670490CA5139FF49D5ED896218825056A8639B31D3AC8550356A408A01404C6AA9C2B7284E7C7C27036256B7902445DDE00630D81930F4CCC518B9EFD8AB24FC16A365B8068C90F7E09BBD23C2A6AB12792D245551A9894F704042501C8FC49EEAA0132701E29A3C97834530A7C61F1B8440822CD1BB6B11DCA2A5951B4DEB0B1268C2F5AA8CF76A6BD0BE3013A37CA1A903AC634405ECB3714BC54610BAA63BACF0A263D8CB018B03B0A286083998A7E8B2A573E570179712130A19F9EBC2337D43926F9C96460996CC03199D81A0E19259DA696FECCA7906931A787A5C264826099A3E03339295B587E7A4EFEC6A11AAAAB057AA8689473F1F211C6D85499C46746BB00BA687A17877E6650C678D13861337FAAA7045A16B8EB7173E7C08B6394B5F2B99EA3083BA175C55D350FD61B73AA790CA6F479FD4B01282B6BAEFA00A1946F6DFB855CE7BD50389D42856823301E01A228AC754CB65A0E323A0943B75741CB498CC499C8649B6BF87E991507194983AAD1B57994B7D79BBCF2EB3B5F8734CCF3CEA2662E95D486989144AEA22C94C363571AC7DCD81F577645CF19B313F849B422AFED963CDB701395020C2D18601A40A42429896AA9B0B1C10C4876928AEAC59862414E143722A0B94746ABD157343D15BB9FE500763B18C61B184407449B1B5BA8FB1554E4BB58AB99FAAAC9CDC3B698E64179B089B786204BF95EDA86474EE799440478348989C91C3462446724340CD2376C682907EDB58C85A4CE3EF46CC5D0CA345590AB14844B224735DC05E0E66EDE94258F395FE867AB9D8C1B0FA80743002A15DA197614295DC358F40758C9CC05E45BBC659B93ED611AA58845D94ACC7AA75DEBA56D4D83C640C252975BC3165254C92957B78C9583B370AD785F2C16CD5CB9913839939C7293E6B956E23CC5D14CB3AB2A2E94F179BB076355157920085236F60B84449D43AC89C2B46DAFA6B784438F3510BFC48357A5681043BA7428583BB5E912B08786562579DF58A41BDB82114344B3EA3574B997F8564248210D4E50AB2277100B9A5423178B1F138E9D427762253CFFC3CD095CB53A776F4FE015B5168B1A9759AC4ACC77F90C69B307192B7B866753872A69813B1BCAAB5CBB8126D8998E78D99F5A527992B89495A28E3FA83E75337CA2B896172AC244AB7E30761C8E3A00890046E5F599EEAB65BF1A4CDEB5791CC10ADE7197FB5BC754233F3B10C9BA2240ADFC61C05231C36A6CF71AA752AB3C95C3756EF9373B677105D11F86E68036348BDD181F27407E344BCD297CB02BC44F077976ED588D6A846C2F839BC9BC4872617BDC17A7BAA97AF9A9322FF015956678E8D622CFB1A11ED929F29BB1F094C17F49417C09C1C443369123CAF8701199C43BFF97034EFC6999424144C9395D9063BB153C0ED82B1C5659BFB23D4CD2C758A26B6C448525060F686BB14873CBF5046B3A3033C5C8081027BF5E3C51F6FB6A1D54A77C46B0EA4299A9DA4AB03B95F9D3601F553D46800F661E2C9A7E548CA42E385CC6A0678F9E9D268FFCE02C4B465A46773432109A759CFECA12DFE978BF0B7AD7271487CF61B2B8F7C60F389F33FC18439A95BCBB6356047447B810CC094D400AB204CF9AE71E3AFA68B88586ECB6498C68AC0E51B9\nct = FCA7E41C5BB5460CE12E4A40CFB3E7E7DBF18E2D9D386396586475AF17A830D3A738237C05105735E9B4DCA87D114F017B50484BD0381873A5F4DA24C420B6D56EFEC00891BABC52AB22554B68A0E3D3AADFED71D3BFD75FEDBF946C55EC3FE0C050C623636FD486192DDE50EBAA7D12DD8B80418FDD64A5F7979CD660090C05893E3CE334B1F489149012C00F8868BE07AA3FF50B2C255F43040DB1F603C00C5B3C5DD56DECED7B510B96B9A1B31CDEB0E5A73CBABFA0742631D816CFC2A701EA64DCC435578512073E3BC1C78D5EFC68772A971AACDC89448B1E0BCD2B558CF709A513866CD0609A4C314BECA92E894630822C324FC3AB177DFF0EC1C89C92C49292AC28859FEADEC5BF5BDF3FC8C806F2145D0E9B3E9981C40AAEDE9ECA94747EB32DA509D089FED91578E6F7B012F91521974D722416C5EE640DC2F8E46FF56077E1370270839FC131D89C22BCC4107A1CB65E6714A9503F46988EC651E222970372B462314183D54ED825ADDA32C1B807DAB5EEFA2CBF1F910E4B2532377DA539280C9808504EEC2D43F6A24623374D4A9DD50A1F3DD250BE40B20B23CD84B7F1EE317D7D937185528EE1ED4482DCD6F93CDEE40E2469853FECAD614627CA7410E690B3BD2F0736A5C5FE53B14C3DAA2A12B2790D41FBA12E39FA647823831979042878A70313B4CAF8AC0C4FF9005BBA914B636EA375D3259D21F8ACE9D3D5D963ED085FBA924EAADB6EDEC0488CA9E9A629FC3D46D987B8CBC473E8C1EA5B85E00F03AF99F8451DBBB5B8EC72AA7D91F8F6C9B4FA03965D04D2FC652F5F76991D95463EF0D79D5238ACE1A1D6A3452ED8E6A2B482F8B0AB3C9FAB41929B104B18E23F5F49616B704EE79E8B893C998A88D88BBB3A22305EFE28A9BC526D2A8DC6B4D820130F2288469D9D8DFF20673492C6C5F3AE967BFC74162DE3502BFDF498F038F34309FF4FDBFE5DF00B0E568F49562051E24FB2ACF1489615B00DAD14627F04E2BD5B63020A77B0901336A905F8BF20BA788898C4E6754E2788D80BD4B8CE013A3173B5E7EF84F63116833631FE8AC3AF8A0B47BA535C9A88F522AEE02FA077EB056D3AD2DC2A70B22E81A8A4CDB2DC27D3DC92F28024EDAAAF133BCBF691D7F5F28C48207302FD0CB11CF8C8A7EB862243A045D3AFC6FA9E64443A1E598FB6AB325DCD4CB7CDD6E24D0B970DC6667FCD9D448B30DD33BFF1924880C4C42A59F035E9C619EB00E3E0761F994ECA9EA469479CBFB6E1F18447AE8A6C0639774B428E642BB39ABCA7A6F1624A68A810F6482C1B6634EE4A6FFFACB99E28029340EF8AE8C2B456F5D73F79DD704645FBFAAA61897047F5C3297837BABFC16970B88BC1B73E33F17B3D3E8BC7980FD98CF7CE13C3944C8F0B4049E9C281709F990B45EE22628ED9DB89ACB02E01A058E6038F1417F83A4B295238123775D87141E2A5DAA476318015EA84445FDE78A40376486F4DE25B7925B0BD3A163D8785D7C50FBDD9C5038B9A6006ADF424426567AE19AD69F09C6825923BE7\nss = F9EB1C87813C712CC3054109ACB5F219FC1E29DB10FF33D093A5CD67DF995015\n\ncount = 10\nseed = 980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3\ngenerateEntropy = 2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363\nencapEntropyPreHash = dca92dbec9", + "b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2\npk = C4A90087866B29244C3641310E94B8311A1303465975649288713E79CA67A9085C8F7449C0BB9A6AB196245B0DA028CC1765A8BA0501D5E360CB3064E11554F3FC2914F1260509073B67B4A0570D7F708CA7C435EA987762F2A5A23CAE53907FC9DB26942136D72202D0A0BB10B65D422091ABAA1C21D152DAD59C25D20C016237634741DEF8CA26B9CCE3097FFD896F1BF08300282FCB7000C7E1956673223902AE5B43BC63B6806C469A4EBB8BD34B057B375E725B07EE856FCC0453379B96F89888D21A7BD5EC91F837B90A2C334A97AD70D87BDCC12892D588D06655F6103E033547CF5933EC237B21B2956E5921CF10A0C55A70E4A24A57B93F6FCAAB2A44BB079987EBA57223B4B9DEB60EC6464FAA4058283B8CBA6956C792AE8FF9184E93C2E2152823C15412C102518462C2691DB1C64412EB1EC6D75D47C82FC5A9214670B3297067E30C6D9CE0CF3EB314CC1A4CF35342AE419513EC2BD47182C4EA52626A56F7831DBDC5719F532A5A421A7BD5A115C2195D0532E7C1C0FFE40166404137A5B45D7B2CD31752E1646588021508293FB881123F61034318700EEAC429500905179B283162ED0B69590541EBA0848DECC94BD18C888170A4C030A89305FE97A2B0292390A3B1FD6AA22909CF0134A2754728B6FB5180276B7D65C2FD530B4FF48CC7C7093DFC2B418B97762C42BB0980C7F41D9651C69387173A6718038010F50B79B233187BC3A0F7C770E50ABC62E8ACBE297C58C58055387BC7711473D81CA97B6A6E6504870C0DE1D806E3603ED0B04D01DC62529434014C5068C3AB3D4A909A079947127A8A2746CC8126F0212E21A0318EF273D5E0BE16253848413C5CEA22853C6E63B675CFAC1D6590004A2BB3BB4974E79ACA0DD927607A71D4B4C9980A86E5A2B5A84BCD2E694190491060411B332AA7E7766A4C693B00EB9D68F34E5B0564DE24377D3A6D45F72D82EC24FB268537C07B81AA79B5B28EF5A657E0F8B6B2F3A4279ABCF06CA2A79401312943D1D1086D91B1AD3030D0C0BB21806CB87B56ED391E6BC6AAD974034664B4902336D6E45A7449CB656207D59367F2B142746636E44726F111603B28670F47113D28CE6BB11F464B181CB3205FEBC13CC70D3FB35924A641A1117DF5CB65FD9A69C71BB800FC22A6BC47E52756C23533A3A494733B74D9689D64A849D048A2FFAA62B24BA53CC76CE8489D7515834AD3A2EA920E4F2275F4F7BB361866647C04C573BF47E6B54CD31810C7814AB5CD27DA1905FC5976286B781787D2DB606C036A2616AF7946935713CE2C7AC3FC4972ABAA2229C4C294E7A70F97BB6D119BE54553EEBAB1C80C8DA7459258E44A234357A1C9CC46412794116123D21DB27455063672245460EBC8B6B1116B34F2401169ACE16A514534154E798AE3155809B651CA963F854BA501407920765A14F826DCFA4BC4F21766B05BCEAC55E6854F1AD080D9B2538848A8DC7857F10C4C843C46B172ADECE3707E01C03059313BB96BB144996B127A16006DB4063CA1251F550836E167ADEA545B3A0C55C0AC5DE3FCAB6E8242C2C5C09313646117A95EF46536DC74D869301335A2F9040484FB0C9CB85A3D034D55B03C66725D000C47537E0D5AE249EB884B67DADB110119F1D0A5EA38CDF9F2E0E27C75A43A\nsk = A5019E7B82405CAC3C8F45BEC4E70E20590BD7E543D465BA702CB1447C0F114CC44F404A31B091C638347CF5A464106A2F92A0B4E600A3D86AB9F57EFFF088D1887865C695C3AA29BA08356DA1B4042146E8817F2BD56BC014071B896D5B2CBA9FA124CBA45E294A0F30FA01E4EB18262059CC987C64F9185AAA12D7EA1F2780308A91A3B2F171D9C41D166872BC7B070D44AF8556A356B631A6EB2E804CC09C531EECA476ADC8143EEBA767298BF29C19FB2496E0C573938BABCD749EE2D02E9817A3EE5A687F9324E7E1082892142C04AE9715C4A6980D73C6A54C16BEEA97A659DA476E49C1DD1B8292E04321783E0A66A36267673E92C2C7463668B1742987405C1621F94B87CE88AEBAEB7BFD787116B30A5B64A7E8956321463B351A9753A0389937B7AED431A5028D309CBED2D8AE67F859CE371CD1B3CB11A8A70D3B9B92E15530A260D1874118EC505FD451897712AE4104E67B1D2BB2676589AA4E8833E03B017AEB2666464C87BA809F2BA29106B49647666FC58C712B5B8127882DF3723E74A9B9E4B0E5A96BB325144111C75E96A13B5566E8258E36D34A76096F9B013236B3036BDA5E3D431AAD3CA33E9A0916D8CEDCD3466C75C1B5603A3E724C60A796E0844CC0D79686F086C510CA0CB11C2E936ECABA446560AAF0931C6A82298BDC7FA82AA6A0B32D361B3335CB83DDA38417720E9E745BB9CA008908CF6931AB2B4A7B78036704153359DC4FDB5742AB3C39A346005374CF3107B95CB771FF1C9592D59C810A93E3593169AB26DE85077DD79A3B3AA03C332A9D177D7EF88624C285A90099D1D0209A0BB0C425CE6AE9221613B2CD596AA77BA2BB98A385D2898D504D68117ED06233E69C43B541438B3274B579C1A5C27B0D85159836AA48907F768C97B6B2B19F475655022691182B2D9C80AEC12ECA0890C9E47BF764684FF1A94D1083D85905212431AFE09342004B44A090CD71357D2431C923B3CE08BC836B3EDB82AB2FA3C508867EAE87BF2768AD61D4894B123B6F861DB52B9B3EB77A8C99839E9108704C907E258F8D8001567078037AA1AB87B03A46AD3A0A30C753B8BD790923B7454F84C67AB6BBBCC105EDC36AB6AB67C28C1D3A54BD06F9C09C12CAC8483E015301DB6650CA3228ABB8353D2B3D95FA5D99E96BCAB65B37DC8A1E958F7395391BCBB4A944AA955BC2176AA6600A0D40489D0534423776184C85057AE00E9636BFBFA76C2D329625747968F53D1EB26CF4F95D6CCA45C60B2DA0F1899A7A1FC651C12BC2C3A2CA16D8ABA4E05C0CBCBB2B72C48EF55403462AB49CF6576D8C358A865DE1F795CC0629F4B13837B6B1704250B8E97F7A116FB63A0DBC12C955B49A67094CFEEB0E8C7B23ABE4BDABB787D3E45EAD108A96D3206A4977AA128866E596DFCA9D68996D82021A4380C0991561AE40A96BF490DD5538F0718098479A5763787939453A7A87A359643885BC5D6149EA048B5EF1ADC65C78E4A9C917160BDC625352596034B3558F98637B33061F769CBE341F9C764238318882CAA978996D1C321A92838D109C187011BF84D17FEFA0271EAC7D5EC90743130234E79089F5B9A6F0267813939B5A3B22321376FB1792D8BCC4A90087866B29244C3641310E94B8311A1303465975649288713E79CA67A9085C8F7449C0BB9A6AB196245B0DA028CC1765A8BA0501D5E360CB3064E11554F3FC2914F1260509073B67B4A0570D7F708CA7C435EA987762F2A5A23CAE53907FC9DB26942136D72202D0A0BB10B65D422091ABAA1C21D152DAD59C25D20C016237634741DEF8CA26B9CCE3097FFD896F1BF08300282FCB7000C7E1956673223902AE5B43BC63B6806C469A4EBB8BD34B057B375E725B07EE856FCC0453379B96F89888D21A7BD5EC91F837B90A2C334A97AD70D87BDCC12892D588D06655F6103E033547CF5933EC237B21B2956E5921CF10A0C55A70E4A24A57B93F6FCAAB2A44BB079987EBA57223B4B9DEB60EC6464FAA4058283B8CBA6956C792AE8FF9184E93C2E2152823C15412C102518462C2691DB1C64412EB1EC6D75D47C82FC5A9214670B3297067E30C6D9CE0CF3EB314CC1A4CF35342AE419513EC2BD47182C4EA52626A56F7831DBDC5719F532A5A421A7BD5A115C2195D0532E7C1C0FFE40166404137A5B45D7B2CD31752E1646588021508293FB881123F61034318700EEAC429500905179B283162ED0B69590541EBA0848DECC94BD18C888170A4C030A89305FE97A2B0292390A3B1FD6AA22909CF0134A2754728B6FB5180276B7D65C2FD530B4FF48CC7C7093DFC2B418B97762C42BB0980C7F41D9651C69387173A6718038010F50B79B233187BC3A0F7C770E50ABC62E8ACBE297C58C58055387BC7711473D81CA97B6A6E6504870C0DE1D806E3603ED0B04D01DC62529434014C5068C3AB3D4A909A079947127A8A2746CC8126F0212E21A0318EF273D5E0BE16253848413C5CEA22853C6E63B675CFAC1D6590004A2BB3BB4974E79ACA0DD927607A71D4B4C9980A86E5A2B5A84BCD2E694190491060411B332AA7E7766A4C693B00EB9D68F34E5B0564DE24377D3A6D45F72D82EC24FB268537C07B81AA79B5B28EF5A657E0F8B6B2F3A4279ABCF06CA2A79401312943D1D1086D91B1AD3030D0C0BB21806CB87B56ED391E6BC6AAD974034664B4902336D6E45A7449CB656207D59367F2B142746636E44726F111603B28670F47113D28CE6BB11F464B181CB3205FEBC13CC70D3FB35924A641A1117DF5CB65FD9A69C71BB800FC22A6BC47E52756C23533A3A494733B74D9689D64A849D048A2FFAA62B24BA53CC76CE8489D7515834AD3A2EA920E4F2275F4F7BB361866647C04C573BF47E6B54CD31810C7814AB5CD27DA1905FC5976286B781787D2DB606C036A2616AF7946935713CE2C7AC3FC4972ABAA2229C4C294E7A70F97BB6D119BE54553EEBAB1C80C8DA7459258E44A234357A1C9CC46412794116123D21DB27455063672245460EBC8B6B1116B34F2401169ACE16A514534154E798AE3155809B651CA963F854BA501407920765A14F826DCFA4BC4F21766B05BCEAC55E6854F1AD080D9B2538848A8DC7857F10C4C843C46B172ADECE3707E01C03059313BB96BB144996B127A16006DB4063CA1251F550836E167ADEA545B3A0C55C0AC5DE3FCAB6E8242C2C5C09313646117A95EF46536DC74D869301335A2F9040484FB0C9CB85A3D034D55B03C66725D000C47537E0D5AE249EB884B67DADB110119F1D0A5EA38CDF9F2E0E27C75A43A9AA64A30BED5AA8300772066EF577F79BF4813E3315A15F2C28B2665E4DC7E2F8D6C42E7270EE2B77B6045385F3D175984A0E260363166C73B0C70C971644363\nct = 3639A304E4F743B4E62271BDA171EFD8912E067073B2F05FC8253F82733FC36C76FF5B6C5F17C40CB86F33D033BE899B7995251F678DED9E6CDF423FBA7C5E7014854818E08378459ED5723597AE428125C299356F6621D62F204AF4C3BB80A20B80772443CBCE224A0C0AB0FA5EE004CB11908619E40DBE2772C02E03A2A6D3C7F9A0BB5FB931A6C99F2342432CD7B13DAD5263AB489AD70500F6A855FF44D89C43073BF12F6A21D92C514B0BC4A5A839870E74D83C5B20DE67A88A01E959E587F74EEB2A9F53D05F5EF61022821B554D267A44395494453EBDD237223906F6253C3998F4271D3F1CF95DB10C8EBF18A0DAA2068CB945FA42CCEB8B0C335EB6E7991B57C153CFAF9AF85F243866E44470D32010DC7680826A9B7C85439A69571550C4AC82DECCA718C069BA2D99E832BE9A36EA810F02F82DB81DF7D449DAD5C157B0F10FD01F2BD589313F7CB3042E62912800DACA907D72D967E1DE39EF7258FAFF4EF6A8744B40F2ECEF0FFC151C78C215F98B106BD9577AEC1A3E323E705A202D4A855A0979EF439F8A27320E09F7347B316A24AADA46040B3B49426413565C0A7AA8B471F5FAAF88C9AF1375A7395B006F834D9EBE9EBF178B16A115C8346D31FEAA9E6B04719E9F35ECF7621AC1EBEAEF3EAC0EE7431CEC9E", + "06D7A65CEBE7E6297113FF1D151F02C56C83E7DE1DF7FD00DDE7F91EDC126FBE07CB6CB888C1A2F8FAA35AFDEB10AF14A2F8A8B080891E8BEE23A5AFD86A4D749F97DCC6A3B98DBFC5DF4591A16927C33B9FE08AAEAE00979D178A1882FC1AF0E65D8B6F33DFFB235DD06BCF574D55A3074F8BA607A2178E34C76C72AFC1B8E1CB9F482F0162BDD550078655B0F95B3092B132164358A72A6A48C9550553FE9BC874980404955F481C6A614923B925931337F7E2502880A443CEC707B7238AC1ED70B4B94501EA74EA9BCD989B50B360B891D97FFC786A46E53EAAD2F5D714546A80FF90070F281C16A7BA543EF9A0CEFAD3217FBD2133CDC4F7AAEEC5AE444AAF015614D6625471790F714B68E881C0D6ADEF3A6D6E8FC9E273374FB2CC1C9D6D406B4812653DF1276171BF253AD4B80D7B5F8DE0B4BBEB50E2E2607A4CACE04698D7D0EDFE5AFB900C661A5020B7CB88DF34712FF4325D362435BB45D5A9D352BC13EB66BC599C4A07677103A1D7B40F0AE8393E42315BB62D6AC8CF953B8051516807451033B5404BCB12BE7ABFCC9F6CFB8C9ECCC4998CFED0653808463188AC22961BFDDF8F1AA97AA067DF0E9E9954F79547998759FD08542D0A71CBDD32E6EDEFB11331CAD655408CE2F5DEF7AED94B37E8A4B8B75946A677030C3903A4B201C1F3D2DFA65A06BAB8982A4DCE33418D0ED98E29A94E556F0B4C3AEDB44D887DE5BAA0374EF291C8552F0AECD7DC5BB3CFBE79FC92F0A73020489474C8279CD8044BEC179C7E5A1430965B9BF130314A35F9DE2DDBA517D28ADB3D253EFDE18BADABD6512D516C8147E91BACF3CD43CE5E244767ACDAAE8C2AC56A72E1F0089100\nss = A2B1D4028AF3777BE109A51FAB5B7014681B0BE94A7C06E8C2100565667F21A7\n\ncount = 11\nseed = 6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC\ngenerateEntropy = 31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5\nencapEntropyPreHash = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641\npk = E9718A491B3262D206BE72A9CEB000E81B6BE6668D14A124BB49BE524ABB09B91942A60ED38B1974E36376A7724DDC7E5A993EA9C25F40B80C766CC57E807BD5932603403458B84703CA58F8E57C451227128654DF4537FCE6A57BD1BD6FD8C5BE1135B2C82CBFA4B96D577575406F92538034D22D6198A9CD000FC8DC8988F95608C1974C4359ADA14F7DD4870C63BF79886AB2D4CAD1C89A8FE232FC1C8C515B7D2AA9CC35759EF583244EA767916478F8415FDF7B1CF85A80F4D6960298B977A7ABF380709EF904C1706EE3F51ABF415028321E4FC79FB2E15454C47B3572BC09C62C0DC466EFAA759F116E8BA4717F91220F125656BA7C52338AB1FACB0FA6A75CE61F3135911D5714FCDA7A5A271205547018CC0607C5AA7104A4A77266C0525579F054ECC6C62522068E79352AE7A1C3265413459939764A4421CAA937C8F9B2B276A2C77CE7814FE9034783B8AEC29881E2563A63780CBABBCBE72501D68F1B72C6EF3C5D84A4BD7CF4A84686682FE36A151BCB3BB76CE5FA67AE545C9621BED149BE06AA2E72F72D1B24B086836B525915B93A49D90CB3C45877C54204A605CC27F1828DE6CA1E95056938A6C9651EB3B4A9B09C5AA9FC4401215D9EA9015A996F9A7B898CEA466CA14F0065A5B1F374D422B4A277A011F3B3E8143B053507BEE829E582528DCB3C9E950F39D17AD0A849C701779D070E34CC606C84A596650B7776A468659344446BC19186B43CBF042516A7B133065393C83B85313C53B71A5BC4421A91694BEEB39760806D3B910AA8EA546F53763B656C99EA50A179986DC3786A554B819317FB58564DD69428BB1D7BC45A642A8AB9CC013F932A67222D1FD42B455930B8147D6175C66330217246C400C4B619B922182101B2D8165F93BEE58757C14CBFC958552137B904009FCF845321841F8648B8F9E58D1572119B11CBCD59480246A46E255ADCC1649817A052736ED9C18A262C36F7C37918DB789AB177ED39ADD0850A509319888073B54BC3ED81000C780FC87AC5C302235A959B1164B491001B92811D4AA76876065E841B276A27B868822FD1DA7C3FD1831D88C9F5D891FF610CAF264FBC9280B8D4085251774EE20C23576ACE6215B3EB8C1610CA2405115E89421418A7610C05BB526FFA39918E9558C6CB2618A612B6D38BF8A2569B4C3AE902A4AC744ED4BCA8ED783C4EBA450470AEF5EC5370B87DAA419145298170D64CAAFC2EDA7C989645B9285A3FBD16C16E0C1E3FE085A6BC05248426EF106E7F6012E80882682660CD05CE49520785EA66325078F9A91E5FFC3BA0833DE333326FECBCD8878F286064CD1B672F210133E30D106C61AF9A75A7FC64FB5B1E1A1649FAB356C0F26B9062C5DCEAA7CEE502C750A93187A21C11B1B7FCAA45F8B857D38E18287B1E878C7EE59E07966F3619BEE70253D77065C02926BFD9B031260B5AF95846573AD09C42573C8338609FD3E5C0B50092B17A83128A4A9F1A6A232252884504846B3B7DF82981DBB036F6A57C5C19136789AF9690A978145EA6ADB74132EC55840965083F388877A93FC01B006FE4CDE4012A1814B327A12CCA8991CD18027F4485B4025B5583747FBB37916585261ABFEA163B617347ACAF453AE235166CDD8AFBFFDAAAB9919F0CFFDC75D8796FCC28\nsk = 7EC737EBF52EB7905DA8B3C58508928DD74462E8968A1265BB3B9780649210C8202E2950AC11863BD78AF3123AE9899CEFF1992608CF5BD1B4EB0AC1C13CCAAB4CA89A869424BC1AF777CFC7D90A071273F5AA5DF310493FAB17CE5B6477C773D8CC81D995509FF3A40CE80E734A9E8968B7FBE79A9900AB85F7B442077A890688DCBA0BD5E64AE491CE5D39B554E6B82B7602A149A686C19FCEE21B8E3B1792E7529F2307505C77ED84A63A68258E832BF0F118BC05C91A6B216EBCC051B90143B9748B365EC841B6098C4EECE8AA8231BC24B03E732A0EC55AA5B0E3231EFB7C7F0AB21E2544072C22B6B4075049B63FBA05C68A936989BAA2E55AD1846FD1E335568B01D4ACC869E710357708BDC25DB545447E41727224545CA8C16BCA5458EB24D746A12E170EF191CC8DD840E26910CD9484B4E40D0C7446959A521618B9BC472C8001AD0D1C8428C43C0FB3230FA9B17694284375A0E1563FDAEAB6CAD367C9949C4723802D6931F0C212B03004675652B958518D31C8D4B06DFD99820702319E668DFFB5C88622170B0C0EABA56EE7B77EF5D7600B9C0BBBEA5B99E05A9443BB81A68C22C7904A1755D4C80A47AC148ED13C3981C6BF4122A7880FDD597429A32D6046981146743AE85CC8C0CCB715937F29C933D63AB475C2C5483CE07ACC5B8BB4C7456398A9236D02BED9B951F6D43A67EA06F7FB803ACC33E9552E7150C34003A2E2E11BFC0BADFC537EB2B69122352FFB62B285B6CB0935ADFA0385DDA074F7A63ADB76BCF4A80AA83A1C32F87BE3A786537ACAA32178B136C8BF817AC1CB1E25B44654266F4B2B14F33358B9B75A2D916D78E89D3CEC68B782734FE052449598D847B2A02C3056A64E72C5A3B34685E9FB2C0037736E0A21DF39A356310777A36FCE908C243A4A50216B6199CD63C7BDB18B95FBE4615E9799757176FA4A88C93459BC3030E09889EDE148890CC221362472586E3C026B0DC10BA5A823F07ACC1C693E9BF31518B90359B7AAEC54473552835B3590174109337B6171EAC38DE29BDEF8095DA13A8F7014B3F531FC152CA5EB19859673D52067E28C7513141245376BAF368B07627FB1B844FC033361994FFB3B39822A2A2DE17597D16601329866F42C3697A6F5132DCEA2140B871480E50523C3C5227537A5089FB6742CBFCA55BA9C307A321ABE440241E34151B2C2AAB6AD55817B115330C0B15891FA35BF344BE7D93AD44BB27962101982902427242F5B06F85204E738AEC7A333A15001252004B21B5E6FA95A41A4456F74C9522657A9A40F8C4A162F4951CD5BB8A4F334F45A3A73266E1C386CAED53AB52B9A4DFA173B96869FBA6C72987F4B328A0E56A08C96A00D78854D6762EA2394C2A102162143CD40192749CFBC5031739711F1EA8C37DB5B635BCFE9B6396E2902D56BB135EB8975E1B0A171258D39A7AE84AABD46BAF4DC2A6FF18FB6002CE232B7A45A532DD54D3DA8C580D6CEA4209098930477D207622A7CDEDC2E72C24EAF5787D4B2B461889D23AB93A4BA327C371EFF58CFF7F65738886ABD046895834AA06A6CB57973F1011353FCC1452B015A324C406515E9290AFF4356FB393B57F4066077B2152819B6A69DE9718A491B3262D206BE72A9CEB000E81B6BE6668D14A124BB49BE524ABB09B91942A60ED38B1974E36376A7724DDC7E5A993EA9C25F40B80C766CC57E807BD5932603403458B84703CA58F8E57C451227128654DF4537FCE6A57BD1BD6FD8C5BE1135B2C82CBFA4B96D577575406F92538034D22D6198A9CD000FC8DC8988F95608C1974C4359ADA14F7DD4870C63BF79886AB2D4CAD1C89A8FE232FC1C8C515B7D2AA9CC35759EF583244EA767916478F8415FDF7B1CF85A80F4D6960298B977A7ABF380709EF904C1706EE3F51ABF415028321E4FC79FB2E15454C47B3572BC09C62C0DC466EFAA759F116E8BA4717F91220F125656BA7C52338AB1FACB0FA6A75CE61F3135911D5714FCDA7A5A271205547018CC0607C5AA7104A4A77266C0525579F054ECC6C62522068E79352AE7A1C3265413459939764A4421CAA937C8F9B2B276A2C77CE7814FE9034783B8AEC29881E2563A63780CBABBCBE72501D68F1B72C6EF3C5D84A4BD7CF4A84686682FE36A151BCB3BB76CE5FA67AE545C9621BED149BE06AA2E72F72D1B24B086836B525915B93A49D90CB3C45877C54204A605CC27F1828DE6CA1E95056938A6C9651EB3B4A9B09C5AA9FC4401215D9EA9015A996F9A7B898CEA466CA14F0065A5B1F374D422B4A277A011F3B3E8143B053507BEE829E582528DCB3C9E950F39D17AD0A849C701779D070E34CC606C84A596650B7776A468659344446BC19186B43CBF042516A7B133065393C83B85313C53B71A5BC4421A91694BEEB39760806D3B910AA8EA546F53763B656C99EA50A179986DC3786A554B819317FB58564DD69428BB1D7BC45A642A8AB9CC013F932A67222D1FD42B455930B8147D6175C66330217246C400C4B619B922182101B2D8165F93BEE58757C14CBFC958552137B904009FCF845321841F8648B8F9E58D1572119B11CBCD59480246A46E255ADCC1649817A052736ED9C18A262C36F7C37918DB789AB177ED39ADD0850A509319888073B54BC3ED81000C780FC87AC5C302235A959B1164B491001B92811D4AA76876065E841B276A27B868822FD1DA7C3FD1831D88C9F5D891FF610CAF264FBC9280B8D4085251774EE20C23576ACE6215B3EB8C1610CA2405115E89421418A7610C05BB526FFA39918E9558C6CB2618A612B6D38BF8A2569B4C3AE902A4AC744ED4BCA8ED783C4EBA450470AEF5EC5370B87DAA419145298170D64CAAFC2EDA7C989645B9285A3FBD16C16E0C1E3FE085A6BC05248426EF106E7F6012E80882682660CD05CE49520785EA66325078F9A91E5FFC", + "3BA0833DE333326FECBCD8878F286064CD1B672F210133E30D106C61AF9A75A7FC64FB5B1E1A1649FAB356C0F26B9062C5DCEAA7CEE502C750A93187A21C11B1B7FCAA45F8B857D38E18287B1E878C7EE59E07966F3619BEE70253D77065C02926BFD9B031260B5AF95846573AD09C42573C8338609FD3E5C0B50092B17A83128A4A9F1A6A232252884504846B3B7DF82981DBB036F6A57C5C19136789AF9690A978145EA6ADB74132EC55840965083F388877A93FC01B006FE4CDE4012A1814B327A12CCA8991CD18027F4485B4025B5583747FBB37916585261ABFEA163B617347ACAF453AE235166CDD8AFBFFDAAAB9919F0CFFDC75D8796FCC28241E5C7B836862D7482D507973AE3FD8DAE96EEC4ECEBCEDB68FBDA75E04B401812083BFA3B670E3EAF9B443702FB6DB16AC1197656BBD61A8E25ED523B8D1E5\nct = 6B0D9B262990276B654A5AA1A91DDB9EF72225CB2CF1FAE1108671F4F44BE627C6285ACEDA812207FAB12B6CA0A147C2B36D08818DDFD16AF799F9873EE7DAF236F33A607744147A944790B2917D381435B626003C8DF54967B99786D3B610E449DBE49840355A179E6273FF2B3164B50A0E818AEE095807855641772B2B158B5CDA1EB09BDCB98D3E124C0AB285E105E0573A5A6C7256D3455CF59227D0B421FDBB7399F851E910CAF0FF6D96A4BE8A74C7EEB54261DA68024237EB7E561386EB4EA13C56CCDBA633CAF6CAEADE2657A50EF4E0ECF611C18D2B46AF6E993F7279ACE11439D9C8EB857ED097C9D1208757CE7898CC980DE4635988F398758681307B42F64C86867F5F3177022BAC3C4D8EBDE5960BC9095591DAB21CE23D799FDA79C97095CBADDBC43E2324B8DEB736E43374EA884055E4741508554B309D946FF719006C99DEAFB7154BFCAD158A76D8858817BB0EDD928D9C56E972C8DD3D5E806DA47A0C855D23931D1412A5B801B42121EEF3522A8FCA12575703865DC2350CA616ECC39D1E9AFAF9A87D638F72E1861FC8386ECDA284AC0C220DA5E3BB55895F82186DFE69569EFAF2F4A7346348099704B11E5EDB304C42B78853F376A4C4DFAE3E32F1BEACF3D5C2F1744E02F819EB22927013407D82D9687F83757D3D944524E5957E6AB542C83840F5A2F9B31CD9678C7A589DAB33785F06A94C1B71E4AFD3460F85C2A7C6ED7F83CFC009BD88F1241981AD098D1521C0A09348B816E1458291E58314C10371CCDABF96EF994D2C6685A4C781D4CF8263865A18BA57711269449E509BF8460EC4C1CE7C9788816A31F8F91D3FAD6F27B4F351210FF5C41C11E5B0029E66BB655ED20E8011BD16AFAF2F02CE2BC5188B2A2C34AB074515CC85477FA4B541D4C61611A1DF6AE7D1782A311BEBAC32A28DF255263E308E2B659150ABF2DFB955F7A2D7FAD7EED45E18796D9BAEA414F9F66252A4A7CD833E54F1010585865A66FB23F8B781FBF1E1BEF7771C6E73DDE8A059A0ED5837B9DCB9B5A037A3D77F6DE09F3922C5F7C715B00E1ACB1DFC91C934AE04932888192875A126AF8DF70B21D64CB22D430F64FD4CB836C3B8967063E22C647435421C4D0601A3A6D54E7051C84CBC4BCC6455D19B4CE18E79813B33A562F3780A92AC9160A1CB7A22C79A7B8B67BA7824A914E713BE0C889DC6BB420101506FDA42B2448970A11B3C482CA873EFE65856B1DC7C8FA50A6412B8DA94235488DC67AF11B0C8E988FC844B7F0E6AEB685E4B63DC7C0C0184830410C486E6BC03F87129D99CB6464EA70B6C2B01D58EA3F18DA93B4933567A95472556152FEEADB88C9DE0D5A69D6FEF8EDDA08A34B39BFC5D5138A403E3E2D5E6A15A020E8E463B71F8D90A53FB36A91A825E43CBA2433BAE0F17569D3A83EE793EE99D44EBA560C7EB57341AFF091654DC3FD0E24461962CE9D50F1B8BEEE9BC4A23F232BEBEC8B61236D78309B16DD5B4690E8BC495EE43574398D01A62B0CD0F57CD4EE0B64ACAD4\nss = 4A2BAC4D2A30597AA5B528D0E20B1630B20A36E8D747B5EC41EEB57950375A5D\n\ncount = 12\nseed = DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F\ngenerateEntropy = cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c\nencapEntropyPreHash = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c\npk = 14345D52853184AAAB60195152259D9B643D864C4EC5FC4978C657C3365EA81212EB91339AAA4BFA87A197A04D46A7B666837F55DB6F16C095DB449E9BAA879AE14016EA4F8BA975DA26CFCF59401237ACCB908EFD17146E9439B1473BAFA07703F2932D5C598276B59B419402D681D87111F70C20D2710E10A407634AB216907D7363AF0BC4647DBA208F9C6744D71A8A1C1A99082A3BD8A843E4CE581412F04877EDB1709D1A9623C3C428EB111A1189073C9A3D34AD16AA1F1551A07E6880147360E60888DDD5B0956036951021AF4699C96382CC0C16B3F0B960135391C6692B0C556A5B9AD2F8A5ED0CB0BAEA2406868AC6F7A5A44B722721535E098FE832C9AF148AE027604C47CE4D3214A1BC974675289AC7BFB9A644DB30235A664417C57A8A46A86E18A10F81B87F4B4727F7234017088F447F28680B0600AD1DD672F0EA19E38A39FCF964CCCC64528C97FA474EF3AA6777676B3DB443D0A2042C744555049C48B2BC2577738A698BC58910F55B0EDE555B171838F6086CA365AED981AA5354561411990707BD3305CF4D10161FD3124156691DAA5CF3795653E2AEE1C4BA021B0EDD0809B14905E46C2CD0BB1E165C8AA428B180EA394E6C92BD6873E12328E5E1916C94C81393172DF3815127B937B9646A783524671FBD8B5F01395178C6A9FF42C47D8B25FB37A2D1DA975F69C7A8286504FAAA6AD5B05307C2D20B4F27640FE59B1EF407110A317CD72023828192B131CB9AF96899A69B0F51125B2828F29493A997A33023661BB7811C4593E4E579F8B17D0CBB6037D9273932AF4EB235F7D01DD398B70752A925968ADBF56CF132B85680ABFFB937C35425C244345E805BDB608CB0666984775AC1852690908CF2A60214F6A888004AA41A44831537E55A5DFAE7B2A4448FE6C562EA66764DFB5FA508B6738C4F52F10D4A852D38F5354981CDFB7A851A675C5A01C2FBE886192582D1F08AB37753BBD81BA6D848949731C99BA92278A2833CC11AC3BF603512BD6557F9684EB980C7588424DB0C1E2BB2BD09196A7DA29D79208DA50C4A0C839284A44D8861706E991EDD099E0B1467B88948C89778787C26DD4436FBC4BFD12B0ACC00AB4D85B613BBA4F928BBFCB04E2EAA51B81845C3A710BBC8458027A4F055061D0B39AD28482646AEBC5458D0E70D396C99A0B456837376110488F49A83F48372327467AB87870D11B3C1E6C112AB3D6D486A99BC2B9B368A0695C6C6251D6BEA5B56FCB96FC23475719B8CC82806875CAD772E4716332FFB02189438E27097E565159E4B1790558273CA887FCA2A6E7226C53879ADBBC07AC1072E6AAFDD2A1DD89677842041F33C447204A3FB91C1E4935111AC739CDC9FD6F2BA8C0C66DFF5552F3B2BDFDB19D4F65CB3B23777292CF97CC54BFBC41ED041E53318386173D229B9288C5D68E87D0CE2032D481C46B646EF71940D97AF370732533260C6AC943272866BB2BC90EC64424C67B1C877F5D2B35C39656957BBE40C53ED88C4124764B726A5E24ABA7B0C866A52385C85C241677F75487D4156C85DB639AD741E0412438BDBCEB6092FA14501FE1C5E95D90833332DEBC0441554A8CB5A8F7826B047882B415B78A0C2E966AC7C67B03EF5106F0A751017B67CC52A3D0E1586C74513D2B5F13260\nsk = D62C6CE5E7594BE682A8167743106A44482E3A79CE257635773513F0B0BF77A161C8274A705B93D2EAA899D8C0126AC8ADB7B3BBB5891711380DA1A9DE0541E4160DCCABC13A165B5C54178DA95B919457C684B9CEF81E97637C73F22A3CE9295DE79BEDD83C3FF871087B9412301863E291B04779457807ABE4687368C84B3408E26AA30BF58BBE4BBDED32ADB03607598714464222524B3C2CD4C15F98A2E6695463257BB8FA9A84131A64D45A57B9A539094B5E957496B79008878396D3B9B2EC41CCA75B66FA6D069A51AF611D4BC03E20CB12A216072D7834D996AE99E1CC6522A42B48C54282CD0AE8CFDD1B874FBB4EC17434AD584AF5B4561BC1597AAB63390B60FE7C052E57846E1A8C4F6C6758798B70503507554946382FA6E2004A616A40DBC2B0C596C2CB2873C38E6FF82FF159BA93563D23671DFC433949D3705F398B3752680169657623937A8C357864C39D82C16DA5C1EE407FC7FAB357C0B114965E89815409964CCDC54CD8D5B17039AA9283A59E746A45A2800E4806064683C292B425C18F73AA2F720A6521A050C5196BDABC9B094895B9527759C1A7210958E11A3411B05E67097FCE2C11ED024A85A22684B51EDD652DED89C23E1440CA5616BB754361C549776222B8B297F8F4BB7F818D3B29B16C369CC8BA9D91E6012BF006999C7057AA2A44C30237314079B2A55C63990C3AB657CB80D41022651097ED680D200195BE82A9B9D08B24F039BFFC42C66459B0C8889DDA6714B63762494A5E6106F34223990772B1CC12DC660F5BE62EB0A15C16D4A0303773D768C7DDA7B749711F7C12720C150D30EC6B625624E3F94861483BE03271D8B05780AB62E0294A8CB193238530B49455718C872428BEA1D84955F54A3BB619DADC6106EA3EF27094A085634624377312648AC46559D7A7DD902497AA9F22879D131A08B9223A05E5B76A00807225B304480F6105CBEC8A11CEA18E8910A9BBA691047C95676C9E2DC7AB76537691DBBEE397738C613E1FB00A79F06698C10EC26C97DC00B82A54AF572A02801AAC20983311F42BCA18699A2684E4B5AED83C7AD89A1705F1605A87CABEFAC499A56058D8B02BD597743524A90C3686D9405E33C3D70880B6449D41A76F83E23759664F1F301D3935998D690A7167AFA11A59CF8B87624283A738C0D221B1B55453504AB64FB89824351A49EBBCC291465AF92F50D7B53874C1190A766DAC5E70706F88097BE4500942534DF5E5887C48B234C11992F32BF3F2867CC055D7D6C3A4D25D2A141BE7D706BC1203814667552888E3BB13221A10DC3A4157D811A7CA23088BA5AA1A3FD60C0C6AF29B3B52AA6DA319D8E359D842C6DC65C29ECCC0523115D15B19A7B90D1090C5949CC66A004F0A0513132640A284A87384C7ED06782607584BF5CDD8F099ACB0229CC9588B024B0F3B5BA80B962218B3BCE4C0F542BAC9E8C235362E33EA30D789094FE82FBF64569907755ED7BFD00C3F6F446DEB00A27B37BB92E454AAAACB69DC854532C718C85508AC8742C7180EA805A78999111915BD414275E92D75C1953C10968C802E4AA6429ECA0A5EF49FB4046ED2C93914400B0D882B67C275C483037E859C8C015114345D52853184AAAB60195152259D9B643D864C4EC5FC4978C657C3365EA81212EB91339AAA4BFA87A197A04D46A7B666837F55DB6F16C095DB449E9BAA879AE14016EA4F8BA975DA26CFCF59401237ACCB908EFD17146E9439B1473BAFA07703F2932D5C598276B59B419402D681D87111F70C20D2710E10A407634AB216907D7363AF0BC4647DBA", + "208F9C6744D71A8A1C1A99082A3BD8A843E4CE581412F04877EDB1709D1A9623C3C428EB111A1189073C9A3D34AD16AA1F1551A07E6880147360E60888DDD5B0956036951021AF4699C96382CC0C16B3F0B960135391C6692B0C556A5B9AD2F8A5ED0CB0BAEA2406868AC6F7A5A44B722721535E098FE832C9AF148AE027604C47CE4D3214A1BC974675289AC7BFB9A644DB30235A664417C57A8A46A86E18A10F81B87F4B4727F7234017088F447F28680B0600AD1DD672F0EA19E38A39FCF964CCCC64528C97FA474EF3AA6777676B3DB443D0A2042C744555049C48B2BC2577738A698BC58910F55B0EDE555B171838F6086CA365AED981AA5354561411990707BD3305CF4D10161FD3124156691DAA5CF3795653E2AEE1C4BA021B0EDD0809B14905E46C2CD0BB1E165C8AA428B180EA394E6C92BD6873E12328E5E1916C94C81393172DF3815127B937B9646A783524671FBD8B5F01395178C6A9FF42C47D8B25FB37A2D1DA975F69C7A8286504FAAA6AD5B05307C2D20B4F27640FE59B1EF407110A317CD72023828192B131CB9AF96899A69B0F51125B2828F29493A997A33023661BB7811C4593E4E579F8B17D0CBB6037D9273932AF4EB235F7D01DD398B70752A925968ADBF56CF132B85680ABFFB937C35425C244345E805BDB608CB0666984775AC1852690908CF2A60214F6A888004AA41A44831537E55A5DFAE7B2A4448FE6C562EA66764DFB5FA508B6738C4F52F10D4A852D38F5354981CDFB7A851A675C5A01C2FBE886192582D1F08AB37753BBD81BA6D848949731C99BA92278A2833CC11AC3BF603512BD6557F9684EB980C7588424DB0C1E2BB2BD09196A7DA29D79208DA50C4A0C839284A44D8861706E991EDD099E0B1467B88948C89778787C26DD4436FBC4BFD12B0ACC00AB4D85B613BBA4F928BBFCB04E2EAA51B81845C3A710BBC8458027A4F055061D0B39AD28482646AEBC5458D0E70D396C99A0B456837376110488F49A83F48372327467AB87870D11B3C1E6C112AB3D6D486A99BC2B9B368A0695C6C6251D6BEA5B56FCB96FC23475719B8CC82806875CAD772E4716332FFB02189438E27097E565159E4B1790558273CA887FCA2A6E7226C53879ADBBC07AC1072E6AAFDD2A1DD89677842041F33C447204A3FB91C1E4935111AC739CDC9FD6F2BA8C0C66DFF5552F3B2BDFDB19D4F65CB3B23777292CF97CC54BFBC41ED041E53318386173D229B9288C5D68E87D0CE2032D481C46B646EF71940D97AF370732533260C6AC943272866BB2BC90EC64424C67B1C877F5D2B35C39656957BBE40C53ED88C4124764B726A5E24ABA7B0C866A52385C85C241677F75487D4156C85DB639AD741E0412438BDBCEB6092FA14501FE1C5E95D90833332DEBC0441554A8CB5A8F7826B047882B415B78A0C2E966AC7C67B03EF5106F0A751017B67CC52A3D0E1586C74513D2B5F132606AD1D739F1598A16C608A240CD13DFAF8263D74866315E2898A3431CF19E46858E9A30597E4B52FFA87A54B83C91D12A5E9C2CD90FCAC2C11B3A348240411A4C\nct = 3ACCE62A918EBD3D80860DD2AAA93B594682527418B4DB700CFFEE66A66C30C228F2566A4F717C8505DD17CB7CC71990AAA00BF04EEEB254154BA0D20025E02D0F476B445E3ECD9E90904695236BB7D6345AA360308AF8A9698A46FF10DABBFDD4537CD96EE0054FB3E7E53DC2D72DD642E079CFA964B8EE9A7E9806A5724C4D659D24AF5EE2669AB399AFC6DF41F1E8CEEEEC0F5910C83CC40A9287F0E44C22CA0CD3ACE7BA56DA39C29402331C3DCA0F6DF27EEC203225C5F2100944516BAC3AAF3470F793966CB9B4DE1A9581A6412CFAF5E058AC21FAB447B5045804AF6D75C27E24C48B4DFAA3B48EBF59B9AFF804BD24B98DA9D29556BC95362E207E662855D927015C92C69034CF0DF2FFB8FE3052713C74843D3BF90516D8627213E1D52167D13BC9C47387D57C8843AD16A102026E9AB2E430B70BD5EDDD8898A5E62E7D6CE8650B18805996118BB95CA0AC22A43FD92D3EEC07D5BEBFE80A7ED737921061ACBB42FC009C59A409EB3327C2931C642207145B826EECF2377374973219834C3E36E31F459793D644475E207AB0DB525649F05873E811988186DEE8A0E07AC3CEA66F3635F531988D9798F0503FDFBA624A350C299C1339435811620FD6B75EA11CFF36B300E6F2C79F5F0B10FC07E1E9E6A9ACAEF599F95DC8ED5C43E95617D407120C5F9A5A7DD2A804682B8214BC5C913A4984FB69DF0CAB7C0B3146592E43FB9869A526CE58148AAAA39E70A378CAB1648F982C0C668675E3522AD1C8647F3925F7DB726B1E50F352234E5CB67F9B55954831E819BDDF6628935A807A468E9724AA2917A2FF8E84D30DF3643275897BE01A2D9B2CD296B4289A4D84C2A5EC6AC1669EA42D9A19294CFD8AD9B9E4F76DF7879D564429BC55459421026CA3ECBA1CCFB04E41546DA705D6B27D193B86A695746FD2A8DE6D39B616B04C468469F69C23E1FE2BB7A554D70086DFE50F5B9F0A12114AF80D146BBC6A6E1E745905E05443F9177C36002C26FF322DEAA7D27074ADE6860B4EEA93755F00E35BBA8A721ED9CEC554A9ECE670C9D8EFE4B31DDD0565F2C18ECEA9326D3A5F8A1D7CC208247CE5F45A75E23FD5A4FE1CA5A20B661A48E2C6E29D847DDFA12EE226310D65D10E3F461998B4A7480F6F200181E6A003FA671010B87EBEF9FC8A2C14352102E1153816ED9B10B3E2F370EC7F8FEAE82282AF5FEC46A5D2B8697A59D1FC354F3854A1344DB6F6FA91C78844B3A414D3FF02BCD1333A88AFC9D55947237A743BAF81F0AFC37A10EAAC892EAECD15B1265A6B37AC075A778FE2466E1D3A7C1D9C1677AE5FA8737DDF4040D7C3D76118540D244CDA0A7AD5C9E4D7DDC377C15E57697F6F9EC14689C085E986F16BDE6884B2978F217C51ECAA2AA9C8FCA9CF6E9ADE1E39BECAAFF2019B5691B70C06286341DCAA4F21B87B38622C1BC996A38BC0428731AD3EB3C7BB0D08EC4B4950DC5EA20095088F317C43C073D2E2CD61B361EFE2CC13B12F1BFA59A309D620F4F8FD58B3A8F32ED9DED4BE8CED\nss = E09C8D7E5D104C0A42B47F031EFE22A79BA1008EFDFB80FFC7532F40FC9B3A94\n\ncount = 13\nseed = BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418\ngenerateEntropy = 4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b\nencapEntropyPreHash = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e\npk = 8BD98BE4597242C95C9641B194A093A928B8D3B30F33C10BA326943A8B704C09A6DFA55F700C488C38A3334716CCEB6585008A853162E40A544C0A16878328F47C4E67B5AAD276A2DEC4C320047E2EAB345CC14982B96D1D13566DA409E93072377A1729546117A04CE291A2090B60030A35D5B360F9F871CAD52F37E63954DA0E0A8675ABCC3717972F89469978730607293267CAC89E3C96A98576C2351D8756429722A1278A173A75114BAA4F0EEC6A12B09CAFDC99FEE2C1AF7ACDAE3C747B94B06517464F654ADAE25888A15CB4C5017076C9D3FAC3B1560DD9112D88B2BCF31B15AC420FE5A698D52AB41EF33FA6CA8D8CB9B94D58648F39A138974E8016A972308C7B040D2FA32BFD1096503A3A0E84B9941188A6720E06E6641B896D365190369766995826B72122D780477581BD69B348BB6C5C8F65B4D84AC3F0768EF6645E422B3ED7E38D0A423409C285D0E21BBCA97BE6707557BB0027E755F9A81912D04B9EBB374BD79411B2C283068670431F2DE58D346BB525D192F128C9316742115275E9214DEF7A61DA509B5848013B304216F783D77C3F57B76FB8DC984F05AB557709DAE4691B519C44D41813E4B61E6664AF5C970AE7A810714217745AF087BB00575B18081921A854B7D953E29CB1DE704E6578283292168EA73A03E2082B8B641C819649270011861A7B301DCEF74E9B116A86F717E30BA6C5398E34390072E20C82F570FCFAA2BD8847A7187052E6B9D0D9BC9FEC0217373BCC7B8D38245E40A1597077BB00A408E9EB2BB451C31A746D2AA07FD6432CF176382B6665D45343CF32731817023EE046577ABC342BBE25416DAEE417F2971A8ED4C839126E996A8DB40A55BD424C0E534CAB677FA1C6B692D2B7E322A331305F75289A1ED102ED604722737E76501C7E7ACC69842D6FFB2D31D1003C3B3BD8F4458D93B0270CBA21DB21A7D16E22E18584E68EA5B890EE839DE75B68D60B25D5452BBB91658F3220AAAB200EE7A8F070A5B5AA7FA30A768275970012324FE01910E8647945AE6F8B3A17D08E5C36AF468A7F6308751C4141439B567EAB03D72538DDF71DEBD2AEC5DB13537A2B0130B4C2F6662182BD08EB750EB681FCE77981A3012102C45642BB8A44AD5CB27CDA8369EC28190F64987EB600101ACEAE7A807158CC8100555A82644B3B513D7CB283A363C70A4EA090241C8A96AC562E7FB3C38F3515C3A68FECB271713729FB77A1A68695FCF995855749C1F0AE09F90741EC332E7602CADB69E55438B9D8CCC213119627410488145777907D280DDB7391D2EC9F27371277C266BB1B14F6EB8D46B2C8BCCB0C68F3BEB2D87B07044904D5B08E84305B0686F923985A49ACDCB1A662D1A08948C9B8D95883518D0AD3933976C464A41C18351216D84066D71164A32D41886A153703C584B747555EEFE8309F0810D49C0DF8C5512B245F637C9448C47E1456995E922460B8210C7AC1063047C3764077288A1345C23EE0C8FA6865FDD52ACB49614207285D241C14114DB55CC0C92049F3537ABFF81B8A30A02E5AB013741B36D92191691B3197CCE8D2328BBB6FF61932434899AE01412B231B0EFA18D8381555866091C77981E753F8A2B95E8095765EF7A13BD38F9FED3BF36477916CB802690A213C83F6624A067A5E2C\nsk = 212393FA68C40D1153EC29801F4472DB30B8E6516647CCCC6A160BDAC4299D515717D46BB4248673D11558D8AF5A6373720A9C96A4C51BF12AC506CBE51B560AB742EC684DDF86CB08121BDD412E2476842D051E3182C415C49B7184C9322242F70B63A960576296A8AF5451F5D474019C47E1822E2B1503D30CB8EA20B3CEC334A2114FC2381D910A98E633716EF9CA2F7939C7033BAB756371D6C2E906061DF822113C57DD5992C8826ADECBC9AE381931473558AC94FE8A19C9C4BEA3DC40DEFBCBDE234A211623F8D80BDEFC74F657A797098EBBE2B6B57438C2253F89D13BCBD5C0C4204DEF79BB37859E36E920768CA7D0651A7EC9BB63336698ACBFB6C9A384084DEFC1BF5D9C050087B691D40344E107BEF0241BD99463532A05B795F820213392CB16D668605CA86DF134C03C4A7DF581F8CA7DAF732F5AA75146457163C3ABFA9C655F966A607A69AA1234FD1CA2A97213F280A10E84C4AAD26C0EA2CBA6773D63B39EF7350F6D284830EC3275E5BB9A318B03F87CD3F3BBA41632C0F9A1E65989B74B91B23A82BCC22D617AAF8B14C10D0037AB970B8CEBBEC0CB866BE5057964B7CAE6C9B3084A696602A25961DC53558C065D6D8B25248ABA262B1B635322BB82165A8CBEDE60BBF6B72459D47B64A964B3C32CA563BA5AEABA8ED912D81B2E733B4B4587A99AE5", + "037DD21DFC9ACA5D869596E36547C0336AE774B8BA637622A597C05DCD43B092D938429886C708448B24A45A701CE9FB9DB54C67BB531BCFB82EBC15C127409B02A3350D6168F1296784B86F7310B9160681F0133A66356843401B9C0414D7F687AAE41A36857CCD3B26BF8C11DEF30769E30630169365AA3C3B53CC89D9CF47C2CC6C166F197C9E5C5B2408B03C41B0613703CC4872BE78DCC4B28089D7118CA1186BAEAC1355D5B9D4E45515897AE233A26810356A373DCBF6CD5F02CDDE8C468BE006DBC67E60A69908D1171D4A5EC1643B87059CAC80C259788EAF195F4FBCCFC4C0284BE822F94C2978FA119371291657B927F8B332124D61D17E21A36485D2C3F2893865F305589A8D048B06FBA7BB9F087F96D5785678A7F2D16C892CBB2273677ED0CB70F5729AF0A0403B0BF0608ACEC1CE32F2924535C16E8423BE0C8854E439EA395DD792399DC98AEEB7493B64965858BE35977DC053B3C0B3788FB4244CD3B49E40934F90B454C983DA38B2B5C88521347788F832E9C64A6CD012511234275C9F6C251442A87B496743333A161D8C04E3D78BE3097942AACCEDE09B9CB673E1FA261BE71DBEB5C4E1049B2B2A00311ACAD4470F8AFC85172476B949AEFBC0110A261461291B5FF7A74697C88AD40C82770FCCF68B9AD5382125879E637B7CEBC1AAE95B03219CF2488B2E3B2E51480C8CD8022C2092470236FE6042DCEBCA24CB9EE9379386D80E54C232DEC93B99B694E99AB5E41CC8CFB8928D5C08EDC7A707044B49B8A131986A3F37BCDBCAB5255B64B4905A93A719D01A32384A87543B6BA1A22DB75C9BAAD257BC8B9D8B78641B394C7AE064087454CFB17B307BC35A97CCCB842602990747D60F30D220ED3171FFD7A2B77049DC210E2377607B817F24C011DD736D7918874AEA4B8BD98BE4597242C95C9641B194A093A928B8D3B30F33C10BA326943A8B704C09A6DFA55F700C488C38A3334716CCEB6585008A853162E40A544C0A16878328F47C4E67B5AAD276A2DEC4C320047E2EAB345CC14982B96D1D13566DA409E93072377A1729546117A04CE291A2090B60030A35D5B360F9F871CAD52F37E63954DA0E0A8675ABCC3717972F89469978730607293267CAC89E3C96A98576C2351D8756429722A1278A173A75114BAA4F0EEC6A12B09CAFDC99FEE2C1AF7ACDAE3C747B94B06517464F654ADAE25888A15CB4C5017076C9D3FAC3B1560DD9112D88B2BCF31B15AC420FE5A698D52AB41EF33FA6CA8D8CB9B94D58648F39A138974E8016A972308C7B040D2FA32BFD1096503A3A0E84B9941188A6720E06E6641B896D365190369766995826B72122D780477581BD69B348BB6C5C8F65B4D84AC3F0768EF6645E422B3ED7E38D0A423409C285D0E21BBCA97BE6707557BB0027E755F9A81912D04B9EBB374BD79411B2C283068670431F2DE58D346BB525D192F128C9316742115275E9214DEF7A61DA509B5848013B304216F783D77C3F57B76FB8DC984F05AB557709DAE4691B519C44D41813E4B61E6664AF5C970AE7A810714217745AF087BB00575B18081921A854B7D953E29CB1DE704E6578283292168EA73A03E2082B8B641C819649270011861A7B301DCEF74E9B116A86F717E30BA6C5398E34390072E20C82F570FCFAA2BD8847A7187052E6B9D0D9BC9FEC0217373BCC7B8D38245E40A1597077BB00A408E9EB2BB451C31A746D2AA07FD6432CF176382B6665D45343CF32731817023EE046577ABC342BBE25416DAEE417F2971A8ED4C839126E996A8DB40A55BD424C0E534CAB677FA1C6B692D2B7E322A331305F75289A1ED102ED604722737E76501C7E7ACC69842D6FFB2D31D1003C3B3BD8F4458D93B0270CBA21DB21A7D16E22E18584E68EA5B890EE839DE75B68D60B25D5452BBB91658F3220AAAB200EE7A8F070A5B5AA7FA30A768275970012324FE01910E8647945AE6F8B3A17D08E5C36AF468A7F6308751C4141439B567EAB03D72538DDF71DEBD2AEC5DB13537A2B0130B4C2F6662182BD08EB750EB681FCE77981A3012102C45642BB8A44AD5CB27CDA8369EC28190F64987EB600101ACEAE7A807158CC8100555A82644B3B513D7CB283A363C70A4EA090241C8A96AC562E7FB3C38F3515C3A68FECB271713729FB77A1A68695FCF995855749C1F0AE09F90741EC332E7602CADB69E55438B9D8CCC213119627410488145777907D280DDB7391D2EC9F27371277C266BB1B14F6EB8D46B2C8BCCB0C68F3BEB2D87B07044904D5B08E84305B0686F923985A49ACDCB1A662D1A08948C9B8D95883518D0AD3933976C464A41C18351216D84066D71164A32D41886A153703C584B747555EEFE8309F0810D49C0DF8C5512B245F637C9448C47E1456995E922460B8210C7AC1063047C3764077288A1345C23EE0C8FA6865FDD52ACB49614207285D241C14114DB55CC0C92049F3537ABFF81B8A30A02E5AB013741B36D92191691B3197CCE8D2328BBB6FF61932434899AE01412B231B0EFA18D8381555866091C77981E753F8A2B95E8095765EF7A13BD38F9FED3BF36477916CB802690A213C83F6624A067A5E2C9510A2A0B4FCBD414FC61AFF04A8DF579660D14B13C40EC0470C45F639B65A588AEC87A9A79204CEE2986867A2906EB851B734B8B22B91D6749B1A5F07C44E3B\nct = 9DC66C77C56800C40A5E71DC3CF139A83AC4308527DF4ADFBD930307EF72D020AEE3E44C3D548C67CAD24E04C21FDCFB69EF121985A565CC897A06CD2C7F4CDD767A5FF8F9353FFAED3363CF5F315ED386AF41BB5A3B0E395DBF12DD24FDAD29FBCD6056FBBC6D354739710EF74B1F4F7C212785F1451D3FA18443EA1F8E4357B7D0368C086C395B4FE548240F7F085DB4A361490412D034363F3514ACDA224E4F72FD7AC410FEC9D7E194FC9F074E8435D4A2049F9FA8663773D1087AC0721AF6665C1057AF23C2B5F3C478F16DAF711BFD0FA253DC1185F008FB8604568EE21C8B93CD1C0BE2CF4D7869C9DFBB94F4B7A1C038F834EF1B45144E8C1C4F3A7587CC0F9BFE3C6A2CF22AE9B835EE38B6D6CF89AB32316D307DE771DF9444B6B23E7054182CCF799CA0D0D0D3034DF22AB6FC27C507782E8196CEA3550A76B3246DDD1B9EB68AA110955C3F3FE19EF762CE5EBDA48A0B59DCE90550293AA4D550CBE5AC94E5FD79901D11B7C5BB261C598CF0C49AEEF25ED8ADB9042791B7377035C41638BB4D06551D80472D159A33854BCFA31555D95506466D118E6B2051E900EB7BA9B6DF3CB9E7D51BA93271DF965F274C4370266F8D0E1EE346D046250486173F96FFE819C231AE3E08EA12BDB2EE3B47434E6F68E19DF6043465D145AB978860DB6918995DC8E995069773ABB5F033EBC58DE26E6C4214177F1CEAAD65FF523FEED2761BDA7ACBA7340077FC0CDE9A938D3B333333FD32B9618459A180D55A34892E6B569810ACE45421980D9A1A2489BADC1E617F4E5A8B3B628DB737AB8668BF047598FC79FC74DD21FC783DF41833E033688CF3915F8328D557C1F482FC78EDE767EC705EE6767D25691DFAEF3A1EF7D076480CA1621888C6282FFD037FFA0128769A30530D92EB7FF4C4E1C86C0D5EA911C7AA2F2B37F1019B061CD6D6BF0F70E76E8139131EE149AA4197D2F2F284CAE33B96B5FE8C5F846D277C59F04DABA036DA670B821A4E5FB0532D0FE03F90AB8E223F06EE5FE9D982047DEEBFB69A02B145E703DC60AB95918971CA3A25DF7C32DCCEA0019F19D83E245F532F5207F8ED19D9A2F7F94F22FA60B1FB666DC21CCDEF046215C50095301D2902FC0D4882908A16B810FB44409B9A23D8228D7CCD0D510051256E4879395FAABECC95542C07E8A07458FCE35D1D882606B41794BC69481E22C53F7BAE8B5BF6492BA14AC16F8E80918360C3C7BE0F2E6985A2C32CDFD36EEEA99B2C5C140CD56E1AC51ACA07DFB53D58D8DB395A28057AB62EB16DE9DA139DA54D4934DD7E5E0997F35FA77FCF0E9C6387E854DE1D9DF06950FE039719B5F278FAB8BB81882EDAD67369D0D0FB1ED57BF36B00D961D87BDE080787729753A9ECF0A48F5B92A369FD71F8347E97170CD0F0A9CED646A120F73A414D6CB8217583BE56255628CBBB91F088C2CA1B1C0E0A302D573CE50D13F22D76AD4DD03908B9A84F4EDC74A234C16CD210E4A7D4880F96A43AC6C003D011CAA39CE78EFB2F8731FDEF17B6B4\nss = 1F8D087B541B57A9D85F0737C39E73FDE01DB5BBE539834D8F918426A57DF9E5\n\ncount = 14\nseed = E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260\ngenerateEntropy = 38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a\nencapEntropyPreHash = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c\npk = A6BB3B93C181B651918A25235E22779CF052E1D30E6852557CA32AAF841834B423A9E61CC24B5231D7590F863E814AA19F123C0CBA97CB3773740871AC23868731748355A85F03B275B3273486142153BE4920BC9EE77AB5C05D2B96228906586EC831EBE8CF6F9BAC3631B7CC904DFC768B1A717274B33F70D08B6A79C4AEC3597E1C9664C9472B6C100C1601F27BC0AED37152E20B327B5D32646F2980BD780C8F476715AC04BF1E03C2D4A31DA23B14DC0233C1A2C2D983627BBC845F023E349CA59626A99EEBA5DCC12E8B82076EF2295238667308451C2052C6F9B127778A3C656213A23DC7E25660443183298753475BCAF667A9483192C6BF553B7E50B44A84A4B881B0365FE513FC661A03689581E045D2F921444C6A76E6344ED8A335B6681CCBC7B42B50B9B03558C64DA65088F60B136882012135A8A659355503918BA25DA1C167B9FB9F771B5727493C921338C1ACCCEFA80201039D28C968AA3A40C2A28835F63BDE23B9722A245EE3C859997F45E10A11F1906C1485B0B51093F51819963393A692ECDB1DDA2C88A6133F69F401B124CAD796217C818152A528F7D073BFCB9EACCC6CC8825AC4612533126C1CCC736DB53F648201FF29A6C3F77B41E01DE2087986F237200014E5FA540735513400004B5925CF64B0FFE9575E27AC19AC5644F355231BCDD70348C4507C80780F1D51ABF6AC4C5E2957A94325A3F64E83A0A192516F6CBB40B8ABBA5F8B85BF2AA60E44B46585BF009A723FE1A44FC97543F269F670C593935BDF87A52A1A31CD2B9AD92807407B5851B49EB1A2318611CACAA7710B6764A7E57F8962BC3FC483A8393640E602CA55526EB1BE56F2C61CE802B9592F24C14AAA75AA4B002AC9B81FC1327B2A93AA889C9EB178BEBDC91579CA7BD30796CC324447892558D2C052308946A451CA49816C06AAD39603DD3841EF03CCC1075DF164739FEB342ADCCE87AA12F550200CE94765EB4F291A5152941B4EEABA91C3A59257C03017C0B7E0003B07657BA60B4256A8A4B205D7646813246385B348EC157DC6EB3BE4546D7EB85C29512840018968743D2CE147F071C8F96C7436596337D69F5074485BF4A288833F2855787F8A18D874C5A2A41422157F65B62B5E581C2181A7023698FDC1AC60A8340A34B29F81B03DC35DA2B453FA61293070B1C6DB57F3040C3AF7766C69B84D624DBA1163FEB0C71FAB6582473F93C8753D67B0259A2EEE1C847B1B8A73", + "455A74FA10C3A4C21A35AD20FC36D563BE9BC55350F565E4076670F0C77B3C4AA2A06F7BF2AD1BFC4FC8721618454D640189A6F8B3D6C71086DBA68B213F4C51100A6037E717147893CDAE20A97759204B2C684D8206FDCB10DF575799AAA3DE388CEAD4446DCBA8E14368F7202520C71E453B41CCE426BE6C1E29AC475C45742DDACF7C520DA15780A9056183900559129E5E3CBB3FEAA288B25B6FC69BB8B164C1DB8E24391172A8C23859545E98A13725130E45C3D1CBB5D6F5C0DC275608163916013E6E466C29502902C97D3BC33DD006ABAAF2AACC40C046E55951D744E31887155A3FA880058A8767B35684445982767C697540CE339A0F4C29C2AE42B5DAC5047C12C22BCC155A63A8610DB945708CB5425CE0C3C651532A43D32473F236519D54FDFE0A815D\nsk = 69E774DB244D05192A2E064257F3A7B9B08941A2018ACA28C610B8BFAB59176BAD88B9A7781222CB03AABE6A4C2937BE24645A28C3A7931240503769EDD1865F72B44C4842114980BA64A59A647438C5476A700D0DC4A63277C4DC73A3DC9B59BFEB0DDF0817612AB73AB14378E93FA4982D15131C5016B36A639E4F689E9B6B2D2BB2501E130EEDF72AFE4861AE7CBE7E717B4C4001B78BAC719C6AFD40969392CFB1D918794B4988A7C03A23C8C5A751ED2C39D3E18474B43CF8B7814A5932224141FD543871AC102BB0A349153EB4A13AD57AC06602BFC6C1B4425284EAD058572A1C7C0CAFDC6756555B2033D2CE67F9155B16726625928EA26D13E2C0C0A66988EAB99643B4CF23AC68724CE635188DD8B3F2F421E8E8A9F838B707A16FBF27445A7555CFC052982CB002130CA3500CC428AEF14281564997D5F37D0A1C411CF73D3D2082E4C26C3BB7BEB9FBA2D9EC631F8953B3D03075318B4B720B4FB5B177D43C11E8979C640639136FA20B718C0846404B2F0604C55CA82F519241D811A697000DBCE1C743410E92922E83446410A93150178A4A2B52123174DB128B2EB97DF4E8A617D5876AB9977DAA8B7845537DB0A2B6E0599C0CC165438329D1251D6AA09D5B30F27040082A135C2B831B7722C416072C655C4D511E1FDC0284932849126D49B5A03B3593894BCA250B0D198601A02900C9406D8F5B69BEDA735A3512BD355DAD587BCA7330364031573B44EB9C2BD103BAFB7283C1B923AC3A41F0607D4B7B7E1E681AAC9B4090538B6B7975B9C5C64C6196577B7861CC88ED6C3365AABCC9B97A6A318A39A2BA8B17376509A563B58DFBF4584E6B00D56BBBEC309164982D1B906635A146C04BAD613C02C8E2C2D0597FC285779C628F3E290A84D8710745C444410F129A140358991D601FDC787FAF4506C6003E2130C2E03B3FFED39CA3B9BBAAA34ABAE794D4266E59A80EFB44528B2B234D70025767A5DEA09032767722C61E53423417458DE9E809A42257A27001E9C8AD43B775BC853D8475ABDAC86811D568E9E38747618AFF0B0901283A3913B6595CB2A85B6D42101DCBC90146AB85EA5449850BC9D8B1356F820EF365731F176EC0A0A5B7F35D9848C426F32D6A37046574A93CFCC043614E8708026621A06AC00582DA7B64421D4F50AAAC1BB10D6BBAEA31808712B891344B7B865243614CD706C2DC098B0A069FCEDB89ECD67DE8319C92F3AA0A9B92A1FA256302587A5859408B5CAB563EF1814CEA386BECD756DB669FDF87A003EA1E7654CAB281220B21CB234AC1C4B459EE48517BC838082191DE35B265D5264119C05CB500A05307C806AE8246128A8194F61024F5B2B7C410689150C0A8F68E1B3A51DFAA834B7C8ED989B351E683AF7BA73DD91E9733282FA2559AC53AA2819811190B5827000D98433241A3DA2B77F4E588B0088E3D3318CFD049C4777F7B08678144618E2406B9B6B72698888C4529B7E3B272E92620BB36792266C3DA4C9C403D1D49650B5530BE017C3B99C068890F2705702440AA0BFCA823059822C18981A03B16670E127386265487665ACA4C171E023621A853965A629757148E37833D31E453DC9B20191C94230833A6BB3B93C181B651918A25235E22779CF052E1D30E6852557CA32AAF841834B423A9E61CC24B5231D7590F863E814AA19F123C0CBA97CB3773740871AC23868731748355A85F03B275B3273486142153BE4920BC9EE77AB5C05D2B96228906586EC831EBE8CF6F9BAC3631B7CC904DFC768B1A717274B33F70D08B6A79C4AEC3597E1C9664C9472B6C100C1601F27BC0AED37152E20B327B5D32646F2980BD780C8F476715AC04BF1E03C2D4A31DA23B14DC0233C1A2C2D983627BBC845F023E349CA59626A99EEBA5DCC12E8B82076EF2295238667308451C2052C6F9B127778A3C656213A23DC7E25660443183298753475BCAF667A9483192C6BF553B7E50B44A84A4B881B0365FE513FC661A03689581E045D2F921444C6A76E6344ED8A335B6681CCBC7B42B50B9B03558C64DA65088F60B136882012135A8A659355503918BA25DA1C167B9FB9F771B5727493C921338C1ACCCEFA80201039D28C968AA3A40C2A28835F63BDE23B9722A245EE3C859997F45E10A11F1906C1485B0B51093F51819963393A692ECDB1DDA2C88A6133F69F401B124CAD796217C818152A528F7D073BFCB9EACCC6CC8825AC4612533126C1CCC736DB53F648201FF29A6C3F77B41E01DE2087986F237200014E5FA540735513400004B5925CF64B0FFE9575E27AC19AC5644F355231BCDD70348C4507C80780F1D51ABF6AC4C5E2957A94325A3F64E83A0A192516F6CBB40B8ABBA5F8B85BF2AA60E44B46585BF009A723FE1A44FC97543F269F670C593935BDF87A52A1A31CD2B9AD92807407B5851B49EB1A2318611CACAA7710B6764A7E57F8962BC3FC483A8393640E602CA55526EB1BE56F2C61CE802B9592F24C14AAA75AA4B002AC9B81FC1327B2A93AA889C9EB178BEBDC91579CA7BD30796CC324447892558D2C052308946A451CA49816C06AAD39603DD3841EF03CCC1075DF164739FEB342ADCCE87AA12F550200CE94765EB4F291A5152941B4EEABA91C3A59257C03017C0B7E0003B07657BA60B4256A8A4B205D7646813246385B348EC157DC6EB3BE4546D7EB85C29512840018968743D2CE147F071C8F96C7436596337D69F5074485BF4A288833F2855787F8A18D874C5A2A41422157F65B62B5E581C2181A7023698FDC1AC60A8340A34B29F81B03DC35DA2B453FA61293070B1C6DB57F3040C3AF7766C69B84D624DBA1163FEB0C71FAB6582473F93C8753D67B0259A2EEE1C847B1B8A73455A74FA10C3A4C21A35AD20FC36D563BE9BC55350F565E4076670F0C77B3C4AA2A06F7BF2AD1BFC4FC8721618454D640189A6F8B3D6C71086DBA68B213F4C51100A6037E717147893CDAE20A97759204B2C684D8206FDCB10DF575799AAA3DE388CEAD4446DCBA8E14368F7202520C71E453B41CCE426BE6C1E29AC475C45742DDACF7C520DA15780A9056183900559129E5E3CBB3FEAA288B25B6FC69BB8B164C1DB8E24391172A8C23859545E98A13725130E45C3D1CBB5D6F5C0DC275608163916013E6E466C29502902C97D3BC33DD006ABAAF2AACC40C046E55951D744E31887155A3FA880058A8767B35684445982767C697540CE339A0F4C29C2AE42B5DAC5047C12C22BCC155A63A8610DB945708CB5425CE0C3C651532A43D32473F236519D54FDFE0A815DCFBE9649D9D1C384BAAD67B91B2F3E21F2FADD6BB582A0B9CB016051DD82C75AA2ACF359556DF4A2ABAEB9DCEE945829BEB71185B4D6BD18B76E5668F253383A\nct = 438BD56B10F4813575D7CB4D4F502AF16B0CB43BABB8B636088AB627CADAFAC7FA8A3B3AC3E8903C6F72A6A060ECFB81F2F86974E324BFC5A6EECA115AC1F632BD83BE1741204499997E1255C547E3F6F4D2B4C92D8671FB3342C1DF8C0B1B927E33477D589F74732BD047DD9898CFE6293D1F6108F74924D68215CA691552AC1CA07487FC7099DB19BD26B16B4474873D352384ADC22AAFA0C36CDFE4A5A486372398E2117A894C3FF3DF86F724553A419362BD1AADBA1730A85EFE908BEEBC4AEA15C83A02E0C5424CB39261697E3BD534652DA23B6E64118DB7A355438BDEB1D3D895D281F0B095871EC4B108354DDA84D252C819019FD3C0469014EDE38B16FAF69F12688FC7A17FF074414A6157E4FE4C9F92699D3B57D00D31232FC8BA2A05B4253CAF6E9F550FF9DDD063B4D2939A5431021450DE80538614DF20CD2C21C644DAE73C1621B6B7DE5CD08EA474383A9F842E69EC29C37BDBAB43012313C984D8EBDB386DDAD5429467F6E3CA94D1EEE89F77783724ADE7D1D375C6DFF1F483D6849BA5CD09C6EB8740CB1BC463F0D4C9441B6F248C029D8E94F994DB46E892C2B546C1DD3C1B71C78BB5B4C4D15F3F3382DC075E8CF29AA3D4700DDCEC71BF6C836CF84FDFBC60C145DBDCCC49929CC989A206E104A72A6967ADC2B1CF682BB4AEDA52475851DFC72EF76A33231DE8F44266C13CF3323FE8142D73FA5A6D021D31C15FB95DC3998BA113154ADB6CA2370B9627F7C15A8E858C15BA769AFC33339DC55F783322C41FDCE25EFD438879EEAB6293A1E47C5089C1CFECE5F194740567B2488998F7B10D0C63B5212F556B2C0B1F300A22A54185AA8431FA20F2C59B898339C6A9A2462EF5330C9CA2CCABD333666689753440882152E7CD74F965111BD75AB4A1B9D50F8F09C8E63268CCE09BE63C293E875C3CCD5518C2B9665226825FA269D8D5C078F50ED5FA2B0278E75E7AB2444FBF4C4B33E3C2E9FF7EA7D720208A582399D0A381CB3EB087BEC172F99F76948ACD97D7CABEEA2D2EF4859C087DF9F8216B904CA595993D81CB21FADB7E5DD1BA854DFE16B4E4818A2A4C7BFEF3FF1F499D30CF53ADF2E9DFAA03147931760A359213F58A8ACE9BE58E50B888F85CA6F022F7D1C152743E341B68BD6DF17CA099FF891A5F702E8AD845F092C8DA5A5F584FEBEFBCD0280473A7F4AEEDF0701D7F69BF8B94311D87F1C03222EA9698ADEFC602D7C4FB8ACD59008AF4FDD75B5A930323B742887A0D91CA209063754E55E21E8894FCAF8944675002244D0134A41E43270A9E918753C1224D2992B34CD5E0B8C1E79EAAEB74B70A215C7B75E9298C7AFD0F4B26CEC3EBD13D7462FE0569BE3145AEB4393B3BB1F5D13281C7FC4214168E062F76D7EB2A7B7D16A1EFBE155025CB0085DFC4A706E79C0670CBFAE9BC7A8390C6DDDDF1FD4E83D56D242AF36DED7B0C38BF82081C631A3905EE477F70165BCBE327658768EDAAA49548CF446AA574B7C97071EE2D0063A8D8D2FEE0092D2687F60E005BF0\nss = 0DA3B9B56FA25F4CA356D3206B99AC83FE84A09CF7FD55A33268C122A8FB51AB\n\ncount = 15\nseed = 669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488\ngenerateEntropy = 97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5\nencapEntropyPreHash = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183\npk = 8452A77401C4E343BDCBDC985B70189EA976E3D65C47649593C9CFC112A4292238302253118CAB8EC52060305392E6A131F0445A0BB4E11A1A8D7465E704B3134C3807D9BE9F8B2ABD57A00758685392592FA0B01E116410706A66", + "9A0EC5ACB524D1561A265E307C24068B12897568490458121C572C2CC43B2464F2703212641202A40B27A41FAFC4B24BEA9F26711F28B1050645A38757708AD607FF6763F14C15A2CAADFC2BC4D23C576E5CAE6A20B10CC9CF610A5931AB4C59ECBE67EA079BC3911A96B24B86A0D6B99CF85AA44094B0F6C55924776C4E1BC9CFC88A127B8195145DA3515288F933DA602F1A2747A6856657B2102774BC1946163B534D02A1CE2E641CD9FC7F7D48B6F643AB53045BC690A249433553845B34A5953C873C1C686C83BA46ACEC4E91046F9E7590196C9C24A747C6D986B4B414C223A52A6C88475405232C78AB3AAE8861A45A817EBB16C3A3070B8E842527E965013244FE50907BAC3883122393340B1E06728FA0400791B1DC3BA103C8AADB6CB0328B5EFBC85694164D0934C207B63614CCA28ECA71E5F63A58604599EB6D1D248A37EBCB17335713C4C9A0500FBF893DF475CF7C19792FD56FE0A7505DE0158F34603E0071B2AA0BDC8A12376A1313F571D33686D505660C4BACE8EA40820918E05BC15B381B90D9B31BF52E1B18C422C3935D04140170542829CDCFC883BC344606E75A2EE7AF469C5A81DAA1071771FFF275F2358472B409B1EC31EC887FD6E76CEEC6812D40BA4469B3EEB028A0A6875A19B7ACA51465CC3FE78566A3EB1B98C621EB3BBDA4E7BEB5F2344B64013EC233FB5714BC68B767DA8B60A6B0FFC8565369C19877C16D7C70F17B85F7A228D28A5936968915D026CF683C762714830C1742AB4DFF789F1F43782622A070A4AB52633EFC52693B695DAB939BC24944733905AE86801C4577324C625159B141C5A1014A6E458B71A959001839C461E17A3AC46DA47AB687D2342FF63B83D3331510C98AC484F44B7FB6A31F6926CF047982C400008BB3B0D1EBBA3CB2345613680531B0708A64B937C88B2985C01A10EEA22FE5022912F9AD2BC667CEA16B0A091F3FA9BBB9B8C30160717B21CEF9D74458241BEEDC215D44900CF40709F6671F221D39C804EB6756C812364DF0503355B8B01102574AC3F07234BBB1B658EA822D52A452545DA3544C041C3A3F89BA30005A992B432178BFBA078686A07971601F8B12C22B23B69C05A89ADC2469287F052A6D4F58798E10A464DB4AA71AB30A94854D1B8C16893B432A8DC2859C66A168C8C5AD4D04559056C4588B0A8755013E378545B47EFBE90CA97552C9B8711D3281CC7B9057F78A68A59D5AA642D1E9233DE093DF5705D8639D702097F0DBC98451A46905AE72D876E1243546590599FC5923B37B4CF0A3F7CB47DFE8AF00F6A999127A256681A5705BF5100D7096713C49149C7C561C0783E048CC3444776BF8997671970535C2CAC5360C9B53E0D952AF348A28E4826DB9810F07110A48771C2C9B21DA3CA719C7A5407B92020AAA0180B4D6B3AE42A1C09CA38FA59D1ED02A3A0079F2E922D0B36D9795C1FA42354CA51DDC11A315515A45BC7E1E21BCD3287E18BB0AC3F8119A88D1FBCE1D3419BEF67B6694D9FA1BB309CC61C819176964DC\nsk = 48C78CB714B9CF88A8B317A6FBB681B8F47D56524122156503823B600236D3726EDD9087504705CB4698A1515DC0D80B3F87C63D575170F45D121A848D897C3C0063DFE9B2D616A96552384FB72D6226A193F90E15B364AE667C34BA27FDD0AC0DEBCF450578C6D182DA365D40786522C37B54E0126ED7B3C6BCCF28F40770F23736B394210B67EBFA72F6B27799FB1F6E48CB7407261A86884621C529974635B35F5B4C530E68BEE8CC213387B66A4127D01223180067A2EC24B2EBB579F74BFD5417FE995BBF816737722912B5B4DBB4C938D0686D1C2A44880FA7231944C195FBD67C67E60861D169DDC41F8150B52A68C14425190BE2ABBCF5BABB734AA03538899678D4290738CC63EEE611E4344EA73B9C41F36C712A4C6C72422000CB93E144F3C588A2299D5704CB347B90B2905CBF69CF1DC5C670909C478094E88C01BB3B3E4FE246F8DC3C62DA37BB13B6E2046911D85D5790869FA4A54FF16794620480919C0DD74B9887BB5C125C34D76B3527A42A46B689FC4C57571AF13C44B7D30A041028E97C0A1E50621567374DE7A4207ACD4CB18417C7984645CF4F2B5A5434BE8F119798C0760229301E14431B0B652C643C0EA0CCAA13CBC6FA6DC8D348B908B78343978FD5A0EEE90CA5104184F33F107837B3EC667EB207000570DD33856939BC8BA671B3731EDB2A94596A8F2F37BBBF5048087091FD2AB164F5C6A8F92F65239F08844ED4F605E3BC1BF780877EEB3F4C85BF696C691F85A947461331AA33B15973AB4923F429C7913731BC025539232217F801EC7078E2F0AF3EC7494684BFC40B4FF31798467746F60BC9BCCB5B1E397DFC6165773A965E55034DD1094966694D7806F2F505CEBC3B3DC307405431FCA21614089C633B522510A5FCA73462B32FD69200DC614C5E88454F181D845B19B8866259A2372BB3361B9ABD5AA278B1773057E26108BB020A9610BC19AF13454DF46B4FB5A68C3E7ABA6E7197AD63439C7252CF9507E32072E437296883C93902250165A1AEE8BE0CE6ACC2029E10E97536EB958B691AE3E3AA9996986805C6D1F6356D26C1E63C550381B292FB1B95E183CA933D5BE1BAF6294C4B248B4264724712B2A2816ED3D09042287EB8A17AD6C86255AC492F53A21EBCC19B3C8BB1E78F58BA98BC8AA77F6A5CB90C0456E1CD663137E11185536B02D8708644539701B193BA52258064B289D053404BC78A397AB86895BAF1934E8B2F6CC3AE48869BE7422E581A6FF748519BC30BC96C716B0A24A02679ACD5151CB2A0FA127C81EA513C3CCC3B84A34025522486CE424BC04C860EDC5758AA990FED372DB324614FE91589D78ACC88C43C2643D540A509F090EBFA6214832C76CA982FAA1CA4465F9C14AB4E6459F072558946CEBA113B5FC7024A364970C72933331A6A4B0D4196B9E6219595E229F3E28FB2D5C6C4C041DB226AB611B04C3A80FB5A7F15E08DF3347DEF02663AA39409AC4E8C8BB0934B46B6A8816CC70C8C0B11A7EC1CCE57BF5BAA30E69207D7E59C9E386D5CF7863C133BA1B510F5E06C4876BA7849611BACC369B039EFE173DF6B8A22469E1F200F2AA53FF84390B88302D9F9915C4B8257754B3423097E7C6B8452A77401C4E343BDCBDC985B70189EA976E3D65C47649593C9CFC112A4292238302253118CAB8EC52060305392E6A131F0445A0BB4E11A1A8D7465E704B3134C3807D9BE9F8B2ABD57A00758685392592FA0B01E116410706A669A0EC5ACB524D1561A265E307C24068B12897568490458121C572C2CC43B2464F2703212641202A40B27A41FAFC4B24BEA9F26711F28B1050645A38757708AD607FF6763F14C15A2CAADFC2BC4D23C576E5CAE6A20B10CC9CF610A5931AB4C59ECBE67EA079BC3911A96B24B86A0D6B99CF85AA44094B0F6C55924776C4E1BC9CFC88A127B8195145DA3515288F933DA602F1A2747A6856657B2102774BC1946163B534D02A1CE2E641CD9FC7F7D48B6F643AB53045BC690A249433553845B34A5953C873C1C686C83BA46ACEC4E91046F9E7590196C9C24A747C6D986B4B414C223A52A6C88475405232C78AB3AAE8861A45A817EBB16C3A3070B8E842527E965013244FE50907BAC3883122393340B1E06728FA0400791B1DC3BA103C8AADB6CB0328B5EFBC85694164D0934C207B63614CCA28ECA71E5F63A58604599EB6D1D248A37EBCB17335713C4C9A0500FBF893DF475CF7C19792FD56FE0A7505DE0158F34603E0071B2AA0BDC8A12376A1313F571D33686D505660C4BACE8EA40820918E05BC15B381B90D9B31BF52E1B18C422C3935D04140170542829CDCFC883BC344606E75A2EE7AF469C5A81DAA1071771FFF275F2358472B409B1EC31EC887FD6E76CEEC6812D40BA4469B3EEB028A0A6875A19B7ACA51465CC3FE78566A3EB1B98C621EB3BBDA4E7BEB5F2344B64013EC233FB5714BC68B767DA8B60A6B0FFC8565369C19877C16D7C70F17B85F7A228D28A5936968915D026CF683C762714830C1742AB4DFF789F1F43782622A070A4AB52633EFC52693B695DAB939BC24944733905AE86801C4577324C625159B141C5A1014A6E458B71A959001839C461E17A3AC46DA47AB687D2342FF63B83D3331510C98AC484F44B7FB6A31F6926CF047982C400008BB3B0D1EBBA3CB2345613680531B0708A64B937C88B2985C01A10EEA22FE5022912F9AD2BC667CEA16B0A091F3FA9BBB9B8C30160717B21CEF9D74458241BEEDC215D44900CF40709F6671F221D39C804EB6756C812364DF0503355B8B01102574AC3F07234BBB1B658EA822D52A452545DA3544C041C3A3F89BA30005A992B432178BFBA078686A07971601F8B12C22B23B69C05A89ADC2469287F052A6D4F58798E10A464DB4AA71AB30A94854D1B8C16893B432A8DC2859C66A168C8C5AD4D04559056C4588B0A8755013E378545B47EFBE90CA97552C9B8711D3281CC7B9057F78A68A59D5AA642D1E9233DE093DF5705D8639D702097F0DBC98451A46905AE72D876E1243546590599FC5923B37B4CF0A3F7CB47DFE8AF00F6A999127A256681A5705BF5100D7096713C49149C7C561C0783E048CC3444776BF8997671970535C2CAC5360C9B53E0D952AF348A28E4826DB9810F07110A48771C2C9B21DA3CA719C7A5407B92020AAA0180B4D6B3AE42A1C09CA38FA59D1ED02A3A0079F2E922D0B36D9795C1FA42354CA51DDC11A315515A45BC7E1E21BCD3287E18BB0AC3F8119A88D1FBCE1D3419BEF67B6694D9FA1BB309CC61C819176964DCA19C2C9C907B129D01CC44A95949121C39534CC98B6D105E60FE519A000CC2AEDF05318B5F655EFE36F1B678CF4B875108A18DB2FA312261CAF839F84BD956C5\nct = 38E00521B95D89079394AEE0B444233F135FB37AB4337A575430DAAFA341059049A49D1E7D3B6EC52EF44F73154A6827BF791A2986309C7D88A855A3E278F42880B35260C340E913FA227D0ABCA526065DECA1837ADA0ECB4D4911BDE561E6F3624AC6F4601CCBFB5851DC74A80B5C3DAC2C3B3E4FB0B1D53653C9FFC4440025F70D09EDB2EC62AE4330A85B0E1D1936E9EF2E82A7E7C3C61E74252A997F4D5B0A5C9070D3DFF6855455C94D22498583016B9C108F8EC0D80BAD19272D982A85BC2688736D50FE7BEDC3D1DB893D42331A60658A4FF202C46450D24A2F1F5BB90342D26904B0E07A3E5D23DC9CA9E8901FEA9CCC49914549A913D8CFB3F0ACE306176E377624DF734967FCBA76FE125BB1B7D9FCE809617114B0F761B4A8381F28F20B5B53DA07B0B31A644D7B11FE444B9B59E4110589CAF921488E176A830DFAE522DE3C651A0E17AE0C42CC9981E906534CF95A013653636A655EB564B89ECFA9C538CD3C6D8AE6D1DD541538CEC73669356E18F2D7D1B668C5A7BB9B9F6F96A590E31FF19EA85FA9AB51418BFE7ADDB99D627645152AEF8E518C625EB3B49F22F93E827784EB5272F9D04826A04D89589F52E16C7B1B48C4C5625E76F2DC8CE6E1F092F9CB9157766E15286149513BA24F9F64016B165E6441F97137629526343520FFC30BC48B4523FE68813885103D0289501275238B7E9F5832E5A0299804A00E3AFA2F1F3D0A247DB2AE9D58D3B8FE09763AD0C5EA658820C540026D4CC5A1528C63BAB66AB97CA8E4F1C81CAADE9491DAAACEF0940866756CBBD61047D882E3150AC1E47DFF9AB68D4B0C282887AB37E2", + "EABE5B265B9BF3910C3C24B8125752F4006F9625918D2DF1FFBEEFEAE895C5B31D865F16EFC9FCDFEEABD6EB1A688FC45D197FE5D4CC8CAACFA1E264A203234375D8A4F141E25FB263A63EE1FAA6842BE1B935956494775B379D91D828E9981013A7E6CD049EDE515D4EE4BA74976C9D68417A27FFB03BB3E2A0FFBD8C801C4AC78C41E9CAE33EA6BC1F9A8ED736724F9EDA52E3E2BDC8BC11E67DEC594FF4AE3DEFB5B643CC5C607102270AEEFF76238D7B5FC858F7FAFF305F300D99EA7989E3141DEA159C32D622B693939F100E8F5B4A633C7BC6E3255ABFD45DD80C7AEB51896813864FFC75CEB576B681F8967C14C720E01950B6DC7AAC1C845EC01E21F378A8B4512119B3DAF1EF9DD5FAEADA667F599C953C0BA321B3C2D03987F3B169C3E5BB4ACDA824921759E557DCCDF82EBE520EFDB1D3A3F082AB063B51ABF1CAF89057B807591A977BB89C659C14A2BF12154956FB3EF13486130272BD8B8655BFAF83A304B85F38D07CA0E5D5854191F0B21B59296A9377E83972F665763D405CF4C01D03104E4855D3B8573961446FD1F5199A6DA97AFDDB8F4B0822C4A1E9F668D04DDCE81D0192F32BF8D0B94AC57895F3209E616D3449309832DF9FAD95233FDD4B3036AC0075E3DC2A25D70C1B922FC9925F20C296A93F307E5933B4C62AE1947EE2D35EAF6389\nss = 806390146332DAF2AC2CE5499D2ABEC128137CF7DB02C27FB457663C18A0D7B0\n\ncount = 16\nseed = 9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048\ngenerateEntropy = ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e\nencapEntropyPreHash = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f\npk = A16730C3D8A8484295A1D995716A3BF93C7270671AFB7886F397AF65F5BAC1B1A1A49084D1A672A1F98BCA762287E90410AB01098C74869B42479C2CAE5906AB354970C05CD256514F5C2E763230B6770884E7B700544977993DF1F57969E0265FAC4F474B76648B36F5711163638069820232B8A64F16BDE83557B0540405D7987CC39069923DFA984CA4045999A77483E04FE6EB0BE954A74C13CFCEA79ED0D8124B01B740A26ED961B2BC496CBDC539A10B8151E0078F66751FE78D2F3A5100761C8BEB514923A7B4F3AE208766FD852222DC31FC1A59A883C401459DC73468EB35AF61D28EC1DA147C882CC7F5AD5204BD8DA270E4C91DC37BAAE1811CFF4CBF8605BB48AC8585094327A8C17527BF5B3968AA268E152B6896A288A9722183E199F608CD7A412CA949113E87A956E4AD12737D53C3BE4752533BC755F7A1C4B07661E988210AC72131B4496941893A9C6F1180BA622436EEB02F3A3A090C00B1FFD310E811A7A8B87984D275D76B0F99ABBFA45CC5096A1562A375F0599D9698B18012A84A0628601C731CE1CE6824907F1B16878A75418C2FB0751202FCC988779BE2326E2E5228C9493A0E628441B13D58B3C79DF34B7B53C7BE816CC7368F2F31C380296250B33269158C4F9706D75B3B5536ADFE5B0BCF514899287B4B637BB4249DB25A0413533D628597DDD745A7F5270D136763E48A517CA62E116913350E7361580CF77BCDB5B607B38D49E1581654A61AD9602F4415F484BCCBD833255A29D2E76262B401F7FA5A1E68BB136771C41B29333B653602B79A2ABA21004E8A257DF7362163B6512EDA4E1376ABA1FACF04D1AA56C814000D718B5B504F1B9D2E627B8A678D0294C5E3B186A67C082B90ABB1C839232912C39C3E02717A65E24A185A5D96E99851EB538A4AB872148C2D7BC52EC4270F708690D0678D43C783CA194B4AAEB6F2156297355D7823E0F80890608768C65073E04E7E5B45ACBB1CB6446483E7C315A0A0C2066F080A53818A4EC0E4973F630F6822A437F6684FC9431F20A306A055F9906435172699B3CD0D46457BE26560F692864A97F80B493093270B5225980287F1F5711B355F9CCC018D670ED8BA64F10BA98B0068E7714074E14736087819EC2CBC960FE6939A4E9A4DE2045B53E81FBB845B0E546DE6B34EE9E91ECF0C9F74C569DEC949D3EA11785639126BBD45137021E9670735488E46A325342A2B4A959297816D1AC731CB501D628BC09083AB5C4DAFC09A36C7C70F2885A6622BB7162AA2C999927A1FB749BAE280237DB21418E2CEC419990288B813E80765B47E4C314171B849E570C7533CC5BB77CB9F10272926C382FC0796F39924B6971FE6B54638C4CF25318E146AA02769E64C47E4DA2D5264B282B32933D8C74242AA73C15875934E99D6C570572E03C54E47726E3B0416D3737A29624169778970E99DE64BC2B16039AE97C7472A41C9A6C6FD45BD7738CB662505BB26A307A2CFB9680F5CAC086F9BBF7799263C0B5367032196F1BD842534601094668A33BD339DB59746D63BA6007887AB750F5887453E02B22C3148BF6C48C806A94CB7BF23568789A1260C87AF0548C71881401C565268317756A211B6955ED03C49E0BEB46C4EA9FF7BE444932E61D464966BFFC96BEC0647AB34F2\nsk = 953B6E6F452FFAB6B9E27B707F600992E228F5FAC92680AAF31300154B218AE51A012A4CF53840CFD714CB63CB4C7AA0E8EA6E50803CA370BB38C7205D9365448B38308868C83348ACC365BE62B4FA763ECC5112A48558E57230D92B5869D77D99A5C0BEF49819500B333300910117E05B082D15368AE529923C6BC9D3594AB33C91B81549829A2EE55AD152493E80AA80399F770899EC05417A698E6493AA647691FEDC92854C23702CAAFC8AB3A3194CE8437B8E2A7F69454ADF3170C282972ABB93CF152DD85587F6272B0B71590C81B3A9F680D19445FFF0C395310A17F55272CC3E1364A9AEA7A67AF4561CF10043B7B7EB4AB0791A8D62814F4B6536CFA69CA0493FEC1A53D58709FBAB9C87578D83C9441D62C267E7AA4EF0AFC7106C9F834A5A13206C4B58D7378AF90B85F7E05237559D6D7819F455AA01D68BC297A8DD760A0DF971542919979218B4861A49E45AAB12BE67080D197C25CA53483D781BA27893D23BAECD393DD1643DC2A53275C84A19900B364CCC94A8BA3B5768F8DBBE08A7B08FD2746BEC62C98C5E5198695B12048BA5C98753AABA88BFBBC6C8DE490AFAA8343D334AAEB72532C63D60667079B41B6A287B04C797458ACD9104C94E96BF18137B0868737DC00A8E2164E0980B9B2135DC7C0E80E1B930C22874FC2CDBE0B5542732E8FA80E407A1A6E5AF0AA3168A963587379AA3E6A2B082A8A35604BAD827BD6AA1FEA76A608100DDC40B17283EDDAB2335B8796DC1BB57887787A4273C4185867368BE581F6E5767BBF0580F07B003556ECFFC3AE336260FA0A80A2C9E4C9914144551C89A9D68373ED9C7AFA83C75C6B8AFFB54187D3B46ABDC61D9E070B5584BE7564F932985EA4C739CC906732A7CF79A65F0F7B0682CAA5D2070B3E0699B1BB3AC0B38CAF22CA4DB9472D06B02954E36C0A3D8890473588C77E43990DA1C7103985761CA711109BEC0B805607D732A36BAF897E93C6D9A988B94C67A4592B7583126FD452FF0B45A033824983715C60478685B9C2D013D41B47EB342A05FB76232554DF30990D6F1B37EA9172020C66FAC8F415615EBE07833A2588EF622034074B214CCD9395648071821D1109DAA87C0E00CD9573254538EC3B8459CE56578C09CA66A508E88C4DBF6183A268B86FA4B7733A8CC89AC81619AF8F56D8ADB1F665A7AC413005BE730AA41CEF2B06A7FBA535552C8CEF73E90A8584A8B799C323F61FAAD4B8C25D06CB883493147069EB1C9C8FB262B699693D0601262E9CE5B383A0D27C1572C49547BC908C003490827343A690859A15B20119975C35AA991183052F117B53D06C5F4683D19CA5BA6F5595B8B269D96C1B3524CC8FC6EEC750CA33B5518603F59B50741D246642BB88EF61A8BD4C54F48AF3F573D4CDC5143ECBDDAB5A281400721544E16E35EA7A05F161003A6C3ADAF690189BCB074F546BC2033B1E8B00D56CF32E0733DC81D05EB358D148A91FACA963B814A9C5FDFDB4DE79B729DFC26C3D9B48A4730337B0BAC8C2A3628268159979F6B10AA9AB90ADAB98B9C0928FC4E3570AB01F02D5A64C5F605596E3498EA532472760F61CB2EB734C174E48237C656636645886B65C566BF95D927A16730C3D8A8484295A1D995716A3BF93C7270671AFB7886F397AF65F5BAC1B1A1A49084D1A672A1F98BCA762287E90410AB01098C74869B42479C2CAE5906AB354970C05CD256514F5C2E763230B6770884E7B700544977993DF1F57969E0265FAC4F474B76648B36F5711163638069820232B8A64F16BDE83557B0540405D7987CC39069923DFA984CA4045999A77483E04FE6EB0BE954A74C13CFCEA79ED0D8124B01B740A26ED961B2BC496CBDC539A10B8151E0078F66751FE78D2F3A5100761C8BEB514923A7B4F3AE208766FD852222DC31FC1A59A883C401459DC73468EB35AF61D28EC1DA147C882CC7F5AD5204BD8DA270E4C91DC37BAAE1811CFF4CBF8605BB48AC8585094327A8C17527BF5B3968AA268E152B6896A288A9722183E199F608CD7A412CA949113E87A956E4AD12737D53C3BE4752533BC755F7A1C4B07661E988210AC72131B4496941893A9C6F1180BA622436EEB02F3A3A090C00B1FFD310E811A7A8B87984D275D76B0F99ABBFA45CC5096A1562A375F0599D9698B18012A84A0628601C731CE1CE6824907F1B16878A75418C2FB0751202FCC988779BE2326E2E5228C9493A0E628441B13D58B3C79DF34B7B53C7BE816CC7368F2F31C380296250B33269158C4F9706D75B3B5536ADFE5B0BCF514899287B4B637BB4249DB25A0413533D628597DDD745A7F5270D136763E48A517CA62E116913350E7361580CF77BCDB5B607B38D49E1581654A61AD9602F4415F484BCCBD833255A29D2E76262B401F7FA5A1E68BB136771C41B29333B653602B79A2ABA21004E8A257DF7362163B6512EDA4E1376ABA1FACF04D1AA56C814000D718B5B504F1B9D2E627B8A678D0294C5E3B186A67C082B90ABB1C839232912C39C3E02717A65E24A185A5D96E99851EB538A4AB872148C2D7BC52EC4270F708690D0678D43C783CA194B4AAEB6F2156297355D7823E0F80890608768C65073E04E7E5B45ACBB1CB6446483E7C315A0A0C2066F080A53818A4EC0E4973F630F6822A437F6684FC9431F20A306A055F9906435172699B3CD0D46457BE26560F692864A97F80B493093270B5225980287F1F5711B355F9CCC018D670ED8BA64F10BA98B0068E7714074E14736087819EC2CBC960FE6939A4E9A4DE2045B53E81FBB845B0E546DE6B34EE9E91ECF0C9F74C569DEC949D3EA11785639126BBD45137021E9670735488E46A325342A2B4A959297816D1AC731CB501D628BC09083AB5C4DAFC09A36C7C70F2885A6622BB7162AA2C999927A1FB749BAE280237DB21418E2CEC419990288B813E80765B47E4C314171B849E570C7533CC5BB77CB9F10272926C382FC0796F39924B6971FE6B54638C4CF25318E146AA02769E64C47E4DA2D5264B282B32933D8C74242AA73C15875934E99D6C570572E03C54E47726E3B0416D3737A29624169778970E99DE64BC2B16039AE97C7472A41C9A6C6FD45BD", + "7738CB662505BB26A307A2CFB9680F5CAC086F9BBF7799263C0B5367032196F1BD842534601094668A33BD339DB59746D63BA6007887AB750F5887453E02B22C3148BF6C48C806A94CB7BF23568789A1260C87AF0548C71881401C565268317756A211B6955ED03C49E0BEB46C4EA9FF7BE444932E61D464966BFFC96BEC0647AB34F2E4174B6E7542FBE80AB2BC06DFB802F691AFF147FF90332D5EA739216C18D872DF7D92DDA83E6B2EF4CCE08C9134563063068A196D7B1A1A13623E48AE12528E\nct = 7678F9F69052E083A490965D779518878DF36A286624797D9A00D562D4BC7072292A63B24C01A747DBF24822CA2EBC078EC3BAAB0DB9DEAFB0F3CBD655AFF659514016EF3D93E8B52340A850089E5FB8292F72C86A879485387B190ACC8E9277AB4A8EAFC7BE2F32138504BB7B67ACDFD9B912D66E76DFC7F66F6E46231FAA4D01FEB97E1913B602477DA05EEA0158C4D33C2E701986411F9EE8B8518B8187EB0A98484800A2FF2C483CFD811A64D3A9412EA798996C87801F1227C19CE8139A53F42DA6E5BD508B429ABE96AC93147FD660B431FD2E146017C037DFEB89F8C5419DC721018B1979044A20FCAACB9D7D2F77FA0A370D469E253B89E58A1EB7DAA6BFD983642E45D746ABB642E0736D20595E8A4E67583D9366D66CC8DAE93E0F579BCA7989C97D9EC0A175194AD55E54ADB1988803B208322041A6F3CE5DA12C0279909CDD937DA9E4CB781E98DB46FC57733F8DA3DE1F86E5DB7103AE7D385F1F0980A669360D67DFA4F91E7F415B545E46D6F0D702A838BA8F248B3A86E18366B6EC489AA8F4196BE731C8FF811A079242640A5FBBD2622253525AC11E74237727BE9F94F376C81755303629D34DDA91F4C0157FE10FC7FB7D9D3E86F6B7646A0332D09EC2A8DE94F6530D3C93A85CFEFBD7BBA955BD41B433158EA148EDFE6F9441D1969DCA81E0319FA2CFDFA528C6B0846EA08C9C36D786D164C80E6938B8CC8BACF096A4E196A601DC1DFA5F85EF588752700215E4DE5A6E7D312EC9EA6704CB5E57EF64CDEC044539D536E5CDCA0F288864EEFF859A9444A078913942EA0A909B4BC3A9F4669C45C242150711DA385AFEE36C2C9B4186D74059E54C111682FD5E75B46CE6A971E9AB0263EED4BF29522E2D60F9599D594ACE2B5F528E2EBDA0C32045F2A90361AEA23733479749F168539DE860146FB9687EF7D0F2AC8C5DF48A3C4A5D44CA2F464B92BBA5756503672184A48A6CE33D5336BE21DBBF177DAC7F70230DE92EF9AC6E510537F7966FBABEC20CFE0E3A7009C8BB54E07AD7B3B4320ACB6D9425467F83D1C9C263627835685A3B2637C1D199ECB1B4C6C2094FB338D4A9BF78F599A533F0B115A4EDB9F58D5ED0FF59B8B2FFB02D1B7F44119D7F0DF89B05BC1772E85555E8CA00D38F95F62298455B6EBBC502ED3C5EC0FC7051C58317B3ECD7C1B6F1DDF9203C98F901423F337C81FB02663D06161271247F139944D6C38C5EC86EA82A542657838EFF141A1CC0BD88511D57709F751F7B2CE7CA6CCF57C9BEE805B81E553C9322348DC35D9C09AD45F167694ED753FFC8D9D0FA4DA6EEDC97BDADC4F0360687299975F9798F70F8E47D40B94039CB416A08FBEBEA26FA87D32621CC509472C19E8A7D83A00C82F00A6A1962CCBBC6612C8CA884DD88F3B0112CEEC63EF74138E53FD14DBA053B7BB39DA8B0D43313D18F75F5E6AE20895BEEA14E7FF3E94C504D5795162CAC8B168A2DBDE89F3AA874F4F9287DBD34252BCA7B3557C00E191ACDD44AB8ADF8931FAF6E6336E4441045\nss = 5C32A0ECC8FD7E70C1B389FE25C91899C37CE4CE672E299A41C7732F4F0D03B2\n\ncount = 17\nseed = 8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A\ngenerateEntropy = b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252\nencapEntropyPreHash = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2\npk = AD735E9E838DA63AC7A3E1CD3E574DB17C2601D3927CC2A9D228A05F5C1E51A63634383FF5E03151F43C66A07BE9E992AA65CA4CA17B1E021E06B261CCAA89B12A4916A5A4E39826A94C86BCBA9FC7D65FF04549DB70B300B1CB280B3A41E82B6C8B0A4A3C5E40EBA59FD18F004CA3E4C15BEDF22E099C99A3D114EB0C5988BA02873B9581107A23E54A8E51AE62375A887929F7333D4D763E23B20A246785E07700BB16C531692531433EB6A6594D1464BCA7348022C1D4219CD8AA6614862C42376C3A0C4674181983F2A2CE8B7F32659AE87ACCAB6023938592E188A3C1015E98720EACC9AA837A49C4617A850C89E1212478F3C6BBA51C30A64A8A1C225274C92EA953872342A96CA3235CA7A9467BE55250796126B30694F71B2F75B56D84AC89C4B635118145C7B8967DE515ECC719E35804194B7EA9304636283CBF72339474CE1DA00106110A596725574747DC07B3F0C7C527ACA703CB23BAA080BB7A4CFC1009B3E5AA89659121E365FD6CB6FD15AFED70779A978B3FF50F915B6C16A350141721EFD61085189C3265530C1A17491B317031B4E4667EB8314AD34CB7DAA50566A9812377CF24076FC3DC748FD58865B1B02DBB831B25B7B7383579376FDAA6C8A5323230025A4BC66977F6A458374FAEB14E47F70E654C42C94A5FC5E386A57ABDE3F29349623E4DE92F900527C165870FCC26A2F95FA1850F2C940FB7B87686E253DD54B6706A84A0C70E3AB04CA8446EFB77609E9815A261AF5A135836064D44A485B5E850F10153653838E5874B76568516E847A2A9B186E8A50C34C2D2B0839EE58024211018B0A13FC781623CC313B30C26A258106941A66B3CD9481ACA7C7E3CE3202F098746C42C58F4C7DBE52FB5F606FBF31B9B5022E691CBEF1464F6942AA503147EBA081817AE28581ECDD867A96195DB320BD2D91C36DB01ADE9AFFB6B00F86C13E2E252C988300B05AFCD007470CC3022E96AF0768DBEBBCF62B53345B213C1544491F1BC75BA96BD73BE57A2CD6874511B44BF2DD27F4FC87C167815FEC59F7A043F699BA4D23400886A7214160C23DC96056BBCC7007A0049435C534B66971E6E5C90EFFA6645C45031C0C905B9887700181565B53165BAB605A51BCACA0DD0C308A46432794C38F21E04172005F4348211C63A40CFFD7C32BCD57FDE852FEC793CB7013E74504721F6BFB7637F73319F75B08E3C25777C969C6EA000C9B79D6F16A00CC4B00AD7CA4F8704B2E54D9D27524F6B80A6D51F85447B22C29AF0036C6BA486862C8B4FB03F26042A0E195A3E91BC303770AC844E77805E41EC6ACA920FF3A1A3ABE81B598C193723B20C8685590131DA89C0ACE08A592489791911C92C7E6ED55F642CAF918173F190B2FB8CC0CB2139FB6CAA259B5A4634CFD0A532B719903E32831489A2D390B4C5A5066B4AB5A3316441B162407096A0BC0342599804752FD4F21C45923705A7A04012AE4A900C01D584F9F41676C36681994C2F4037BDFB84A69A81FA561E5BE05777B571922988EAC714FF249926FC9CC4E93666E198308A434DF74DFF3C5A440948437A7C500582124574AE225F52D322D0909B5E946A5E22AC8F774F69C48B7874417BB1C0B93CC0A90D2A9640377808CCC2673495C4839FDA0D1038B27BEFE3D22E2B727A\nsk = 87C0B4D44CC9EB48C126C5877FF87929B08485FB81E479139C3299C70C43C3FC8C238A81D4E61E62A33DB2499C866B7107D116B7FCB1B0530A7E758A8D487D11575079265B3158302A23732BD07330071BD7CB7199476C39B583A2446109E99FD5C95BE21A292CF37490906E84A82605B8455825C82ECA4B7E218644460CE581214C78AC4473688BD6A9A826217490AD791B7835A85935782847981CA97B6DFE88B63701CFBE3929A2DBAB1628155506C353639D153656B90C5AFF36BAEDF1B87DA5BCE2A108FB6C3B29E77DAE803A0DCBA48AC6882F6C1194E88387F30A47C27D02C37D988346A2A29584A55CB5D3C44C05A18619A4FD412BABC31A046221B3994C8F22CE272C9E6E948C3D043295F413349796C38911F8DCADEAE47351C15E9A1743EB65BDC7471F37FCC93CEC867CD4808ECB281FC17EFD004DD64AB432D664864B43F8A9B1E763529AE2C413ABBCF30A4A478A30A0104D802037C4A8AF01B534DD600E31A1630FF13B2F730924CB790166AF3B7322BAF4409CBBA500C1BB32894E65445F04E4B4B4933DE51267635037FAA44E2775CAA4212F4E0600E51069ABA662C86145E2117347BB1748D63E412550C004237CF02B02AABB18D8533D19B1A879A079B31D529AACBF5258483C80738B380C83119C12B23CDCBC7D027506F3705CE1316DD24594A4BD32D10382F8AB47478F23763898398D7430264203A76B0C4455237F3E765EA5516388595CE9E2BCE2DC2258B5B96C782865FB5354427A2D7806123B0CCA782B1C329411C6C133934BA4A959DA88A072BC6E2D63A007572E36B82C5643564BEC47BC8953D4AAABD146AB5EB36E33F825FB9CA01E223253C320F76C98F810CA52A2C604622F7A60378809A59B19680AA69EED2003E272B8A1F3C8A55BCA129640C5A00D187BCAF465204C73CEE66A2FEEA414F02859C9988356D26665196674D25E64CC5689965CFDB2C0E47A531CE32B3DAA9C649954342A3F62253FDF826AAFCA7DC85A7A8E15161435212D7A4A3BD4B57A2CCCA3506999D407D9B6ABCC97209FA97454B0974DC2C7CF3C3FA40306CD6239DC450536974A8AB773374504B9889CB42BCE4EF4606BDAA559346F18D087BF8B7F0D9B21B0C9B75B5903194B0744A1C47483488EB4C1CA2C83D8198CC6A523D9329F6582863CAC2951268C01770A8081C1C26587D7610088E6068E020E10472C825C395AC6783F074EFA8597FEAC3734399BFA247E4E1531EAC70FE49355E44B3BA5439EA1E65EDA94485FB710124BB968490F1C8B68E87A4C4682156FC06A33275B6B202AA0D508B3789AACA627F0F0C19026CEC38A95F7547D936B255BE7A7525C97AB4282714C32A23C4723A82298F2CE90FCB4761B9EEE869E4D3484BA2B222DC28BC612B1F41607CF57781990009F29617549C0B2179705A34916DB154AA3747867C3EF6A0693BBA5C1D42E14B3247B41059F92607A60AFCDECC1C6F3839DB943F5EBC4D340AABE21269095B3F7D9BDE9EBC21DE788794B63E1098CC2903A83CA2027E8BCB78B855FD56FCF16B45E47994AAC71FC815C521AC1A1B697A18569AC2816F52640CF9059C4EB95E6FA1B32B77BD7CBCB6AB384DE74B6A2708400E980AD735E9E838DA63AC7A3E1CD3E574DB17C2601D3927CC2A9D228A05F5C1E51A63634383FF5E03151F43C66A07BE9E992AA65CA4CA17B1E021E06B261CCAA89B12A4916A5A4E39826A94C86BCBA9FC7D65FF04549DB70B300B1CB280B3A41E82B6C8B0A4A3C5E40EBA59FD18F004CA3E4C15BEDF22E099C99A3D114EB0C5988BA02873B9581107A23E54A8E51AE62375A887929F7333D4D763E23B20A246785E07700BB16C531692531433EB6A6594D1464BCA7348022C1D4219CD8AA6614862C42376C3A0C4674181983F2A2CE8B7F32659AE87ACCAB6023938592E188A3C1015E98720EACC9AA837A49C4617A850C89E1212478F3C6BBA51C30A64A8A1C225274C9", + "2EA953872342A96CA3235CA7A9467BE55250796126B30694F71B2F75B56D84AC89C4B635118145C7B8967DE515ECC719E35804194B7EA9304636283CBF72339474CE1DA00106110A596725574747DC07B3F0C7C527ACA703CB23BAA080BB7A4CFC1009B3E5AA89659121E365FD6CB6FD15AFED70779A978B3FF50F915B6C16A350141721EFD61085189C3265530C1A17491B317031B4E4667EB8314AD34CB7DAA50566A9812377CF24076FC3DC748FD58865B1B02DBB831B25B7B7383579376FDAA6C8A5323230025A4BC66977F6A458374FAEB14E47F70E654C42C94A5FC5E386A57ABDE3F29349623E4DE92F900527C165870FCC26A2F95FA1850F2C940FB7B87686E253DD54B6706A84A0C70E3AB04CA8446EFB77609E9815A261AF5A135836064D44A485B5E850F10153653838E5874B76568516E847A2A9B186E8A50C34C2D2B0839EE58024211018B0A13FC781623CC313B30C26A258106941A66B3CD9481ACA7C7E3CE3202F098746C42C58F4C7DBE52FB5F606FBF31B9B5022E691CBEF1464F6942AA503147EBA081817AE28581ECDD867A96195DB320BD2D91C36DB01ADE9AFFB6B00F86C13E2E252C988300B05AFCD007470CC3022E96AF0768DBEBBCF62B53345B213C1544491F1BC75BA96BD73BE57A2CD6874511B44BF2DD27F4FC87C167815FEC59F7A043F699BA4D23400886A7214160C23DC96056BBCC7007A0049435C534B66971E6E5C90EFFA6645C45031C0C905B9887700181565B53165BAB605A51BCACA0DD0C308A46432794C38F21E04172005F4348211C63A40CFFD7C32BCD57FDE852FEC793CB7013E74504721F6BFB7637F73319F75B08E3C25777C969C6EA000C9B79D6F16A00CC4B00AD7CA4F8704B2E54D9D27524F6B80A6D51F85447B22C29AF0036C6BA486862C8B4FB03F26042A0E195A3E91BC303770AC844E77805E41EC6ACA920FF3A1A3ABE81B598C193723B20C8685590131DA89C0ACE08A592489791911C92C7E6ED55F642CAF918173F190B2FB8CC0CB2139FB6CAA259B5A4634CFD0A532B719903E32831489A2D390B4C5A5066B4AB5A3316441B162407096A0BC0342599804752FD4F21C45923705A7A04012AE4A900C01D584F9F41676C36681994C2F4037BDFB84A69A81FA561E5BE05777B571922988EAC714FF249926FC9CC4E93666E198308A434DF74DFF3C5A440948437A7C500582124574AE225F52D322D0909B5E946A5E22AC8F774F69C48B7874417BB1C0B93CC0A90D2A9640377808CCC2673495C4839FDA0D1038B27BEFE3D22E2B727A2006A70FA33FF4A65B00553734C5BD8CCA0A65EB3A115D96B8AA90F8FDC5F8F40F6AA3E88F7FA8A96067F8CDAECEEAC90C2D0B5E277E56E9C405EC9420C30252\nct = 8B6066F2A728AE7D0BC110336DCCC3FE0F6357DCE815FF647B494FE508C69A7ED6E55C11453DB91AEE3BA1C211216EDC8DB6A45EE71552A75B6B168FEB3FB85EC871C7DB796DE7BAAF09511EBDB584EA318A07A7121B1F2DE7A99A08A0F9CFEF11900FC897DC8B315BC62DF134D054E053777E39436DFFCFCCC673DBF48440276467329301CAC24DB50EB48BDEA5085D50E40E7D2D34E0D193419D423DFA565B0B8278718EDC2839B764F97C796EE6C719285BF2CAEDA377845382E29B614CE12D31702D98B0BF73CE2B695D407BEFCC62B69634CB5BB3803251697C1660B1411C475C62AAB58F5AB9BC4C8DEC50921FC21452E08B27095A8D87FCD581CC81C223A5AA2DD679CD19F87127065C1368C8B29454A9351A0B17A85873BABA9132D4F905DB6A15BE3EA0E61DD4BDB7C506E7014137EEB3943794F5AC765103C9F2C596401CF443D0979557D15F930580D34DB141403E278E2B79E4E2BEE3CB69F1187326D55A584DA85C98A300931E0DEBED6CB3C200ADD1CE524CC7230AF50A93EDAD2707E452DCACF7F81CFBCFD47CD9457A6A713E1FD9B8F8DAAB5440A7BF30E10A244238D02EBCED353667C1F5EDED23E1816DFC8999E46C7E1CFB910BDC06388D12B9C7F32D3611A7F7E38AF8EDB14E2E80EA10E9DDD676FE4D921B4E24DD175CA69D82EA6896820F5311447AD8A37774AD535781AF80F98B89F982C3600EF2101C8527F0B1DC2EB39F47D21DC7112D9F6E96D6D74FFDDA89F3E1B0CC0CD09C2D1061D0E2725A30F88EC62D95633F40303811458954A0178BFA7F7F9D44FAD3607D96475B0BE47E3182216E561C2CA147298D1EE0F23884E658AE146DAE13AE35B8C4BCB6006279955088AA34E0E31284A39AFC316E5F83B05D2271FC3AA5172DC29B751AEB2E854691E5942012B87C2A5C7A0D97551D77927610C01D60CEDE43C4489650A3C4BF1817B12C61DB829386EC110431DD09CC9127EABAF96673B8795C8AE2BD97DAFBEDC4E4D726E90207D43402A761D754DC0C0FEF6403C23F0F8249E8AB153C768B1A42EA982433C45141853A4755D93B62A9DE2C29D83FE8262B1D8D0D6E7E918FF2C8E88CF20705701C8A86A9986E4BAE2C697F45D4DBCFAAC1F11F11A2A1A728F44D70D31F85CE8BBA588C095ED854DBCE17C6751BFB2EE1A86713A796D968BB0271293C9210B420CE454D329EEEA558DD60052466B051477D25152F6BEA1E04C521FAB8D00BE3B0C5CC166FEA82BA49773BBDAA958C5C7E8F50BFB5E345C29801024C39E597F66AC08FA1510FCED31E21F599097F5FCB604B88E3FF893FFFFF9F81AF2D5E1CE0FD4BDAB7A541FF7DC9B55D0EB4D54EADDE6C5A9D688A3C2851976FF51FA915DB037155BBE715F0998C17CB2539AB0300CDA62A0F84817259B2D64DF12AE065CBEF43648F5181ACDCE5B434877F4F90E95E19D5ABC106F568F1B4C48305EAD8A35EDDBD35404E2D46C8ADDD2CC4DA632F2BACF96A0529BB37EE7530739154E01F50116476333D4D0EF1CBA1A85E4338896B\nss = 4FC71B4D0A7CD5D80824E137B93F8356AEDA6A13A55C0515AA74EEF21447CACA\n\ncount = 18\nseed = D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856\ngenerateEntropy = 9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f\nencapEntropyPreHash = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33\npk = E0B9190B548BC164BB826874C1800980DAB529866B951C01C20CB4AD363C681336B13105FC338B1788AFBFF321BD981974C33D98A35666EAABE3612E61839D6AD65490D71AE992111719AACF12A060648667E34D09343D93DB88ABC69E0E098A63749BDAD39F8C6B93D75990B0731621CC04E6E2061E93CC4B51209EC92ABB303BC638C52AB2AE40D746CFCC43B7576A240540BF410C14744F80A442D0555D474192BCD9B187A56691B63965973C7793668682852F91CFBCE70D6D4832A1855CC4B83A847734C24019C508B2D29539FD1A114F787285E197B51BC092F80B559446F1076F02E984A1B27CAE7AA1D0B50967939AAC74CF2335AD421021E3225D94FA3B09148E60C20E8454C68A8022043206B7BB1E799C9B69286509A188DB29A9EBB078420A0844C858CF4B11F9B4959934002BE0229E714350451B9C2775A5CC8C45B07E121290EEE32A73D46F8D7C55311A8C29027356139F153CB405FA14064C5C31060D7A964B33D76BCD4809D21B34A2F7806486BD2835B7F871164AE496D4264F89FB4EB15B7E5A7232B6C68B11351A41B09BB0C92C8437534D2B4C0CA2538023B29DF93D93C98136780FF6F82846CC2868664322AB28DCD7279F68994BA5A5ED406D4D717D16C14DFDDA58DB1524F7C53F3CB170D45A411B07CD64F001DAA0AD1BF63A11550C0C154D20F5096DB44D1AB0A1C9D66581891A9314C18F778330A0936E7A2F3E19C18F7BC87CF078627770DFC5A2FE71B27EB8276863C3295C11E08703EF4A4FF6B3A1871C7B42C43A6EEB6BD1526AA95B7DCD6B38EDC207C630BED1768CE9505544E9053E5C8CBF6A181A1A0F48C8A98B59C3ADEBCC3A5C99E61588834024CFC71C9DFAB1DF558711B311404A739F79B45B1A8A7633081A27A08C3C16478C9D24C1229723ADDCEA225D39BDE7851345B18B1B08254181B01623347A9A57F5D902290B10476083949556663309059815626C3CCB5302B978B2CE82AF231934FFC7732352B990B21B69210F2ACC048387B95C346974C2181148078154416E08564D664DB3045DBA82C9A7934DE51AB5C1D7346A391BACA48209C8C7235309943C1CB9CAB4771C7EAF59321B510D430C88473AB16F54AE461A5DC613C6FEC61A5E899552E835EFF57FC34B7992755D178A0365C52B3F020AB40020CE21B45717654634606DFB2917FCC266193E2E5B2C4559CC5652AAD1121CCA0711E26C23EB33C1F7D389F2D742F384725D3268F8159F8C463585998289E58369FBB883CAAE21B87139E52D7EBB92B011CBE6426390458247C45F06F2519AB35B35675BF93325351617AD3AC470F73D3D3985E10277A647C96A6C56CC2346563CC496DB232FD742AEA3ADCFBC506CA8CBADA7B040A04F6E329FCEA77BEC0683E1A87C396113639159D9CA52A5A5484D2839869A2E80557A6BF7CE2EE295A464AAF835C542457D021C65C2B2A457C771FCC47F8B1056C8B7AA61D1843A40C4C9B083269B2E89FA3BA5959F89972805FA4B46E35ABEF0C57D875C54804DE77071F1219195BC8B4F7C18A19A7953573E7F4157CA03BE2852461A784E736110157BA3F83A6947AAA09E9BCAE730B9B212BB837627293A485ED6B42CA1CF26792676C1F4BEF1609E71524B877F53FD3133BF71AB13912BF37C2CD7A359EAB035CD\nsk = 4DBA785B32456E16A8E9A20FA7536F1B4555A9B403A09738657A148361788D3C358A7BABA8B4C58AC979C4F786E588AE245CB0C12C284F848B89585F76892FD65CB906D39B385A04D2F5B2154ABD1E77AD9501ABAC73237780B33C601FAC50BA3FC07E8525819593B7D7E69FDEA46F14F1128A475E4784AF38985501DCA6D20BC8DC1C5C7740B33804358F71B6E97B2A0E7350F7608321736083DC54E0253C6E5C5665D0B7E68355D4E98DAA753C1ABC1429B397DA773B043459E5AABD093A5B0210502BC2CAB250041997861286924AA0A190307431719588CC2E6FB68711C964FC20393C73B7C967C603120A3CC11B2EFCA3DD6616D0E2C835FA92946A40C4CC2F4655301ECB09424286B3C7A07AD3C6EA37BF6132AAE2D9A335E34B6C816D93CC7EDE020AB723B272B70F494834CCD93BD7800BC39919DEA4BE4C585F827A4351E233026760DC83377329CCBFF180A562AC50833C0F861E795C00EE74B584F693222B28EEFCB445F19B06154ABD0110C6A017ED525B5FA30C64E60663573B8691BA68E2BC580157F1C66EBE388AA2747C50919AF644ACD903A801A5C04A6A2EAC686C89835CF59A791AD5642274A0F78244491670C66C9BCE24BA5CF6B86967AEFE6728DCE8973FD29045DB844DC80022297CF530C8ECA4808F603A90A840AD70A803E6A0BFB44B38616816073C5D7BA26A64048F81A3BAD3A0C9CB0672C7466E38824529298A7C0D82940540C312F429411B403F64E419CF720E1F73026184CEE538B27CFB91F16186DCD3904BA6A34254155B3CB3157937D5618568F46F283C7C0E88696324A4FD77C3E6FA5B5DC0A13116274E5792FED69EABA973730A79878103BF6393", + "4D179143DC23ED39585D40C06A99AEE0F4462F123B8A6B539DEA9E05117B08338DD6754398E7496F612B4D892CA54A13EC9B2DC7022CF779668809AD6DB97A6E8B15FF0A862E664D292C4AF549195A23C19E2B9FCDB9B4A5B9AE517873CCC644993196DE5C2716D58D50E7CF11558F44A16580C980654C8CA581671121CB2F8CC6F90529C9754CF0700B30943EEA1A7B05F0BC8FDC1CF776B0CF2C2EAB927DC83197A4071DABFC07F983BF4D2C613E087976ECCAAC031B88420CECEB6DF0350F04BA61AB39CAD4C6B2B32503D773A34514B7D5BBB9D5E7BB6DD9AB5BDB8F34A9880C49AB5C40970C435508E26CBA50705C6538686249D344BDB7C820A5C8869B371B8FE13922A5AF390BBB7B809C392266541671C75CC2B7A7248D0234FCA16DA64265E5C70257D770D2E9982D5A1C6D19BF0BA48B53AB900FC8280C754C14774939B83C63592A12F35D198194679942EC227B46CC8F353A0547E929175C3585107239AAAFCA151DF3C835E770921E5C9B134CA7E27A18C7656BFD6A4FD2431CE1743576E575DBBA8905F4CC38108E3CDCBF0155B5300A100958AA99940BCB473EF64B05BAF55E91952C46851D313B0990EBCF2148CF28130CF49C8D080841FB81384E73367C792A11099F5B898416946826714E252457B23A3A1E33A36EE2612372CB2C04030840A87F96A31913A428CCCDD2817B38372DA4637F46044F2218C28D525A57D9C0CD2864FD43AA5C9A003A09A35BA786A7520CE0B9190B548BC164BB826874C1800980DAB529866B951C01C20CB4AD363C681336B13105FC338B1788AFBFF321BD981974C33D98A35666EAABE3612E61839D6AD65490D71AE992111719AACF12A060648667E34D09343D93DB88ABC69E0E098A63749BDAD39F8C6B93D75990B0731621CC04E6E2061E93CC4B51209EC92ABB303BC638C52AB2AE40D746CFCC43B7576A240540BF410C14744F80A442D0555D474192BCD9B187A56691B63965973C7793668682852F91CFBCE70D6D4832A1855CC4B83A847734C24019C508B2D29539FD1A114F787285E197B51BC092F80B559446F1076F02E984A1B27CAE7AA1D0B50967939AAC74CF2335AD421021E3225D94FA3B09148E60C20E8454C68A8022043206B7BB1E799C9B69286509A188DB29A9EBB078420A0844C858CF4B11F9B4959934002BE0229E714350451B9C2775A5CC8C45B07E121290EEE32A73D46F8D7C55311A8C29027356139F153CB405FA14064C5C31060D7A964B33D76BCD4809D21B34A2F7806486BD2835B7F871164AE496D4264F89FB4EB15B7E5A7232B6C68B11351A41B09BB0C92C8437534D2B4C0CA2538023B29DF93D93C98136780FF6F82846CC2868664322AB28DCD7279F68994BA5A5ED406D4D717D16C14DFDDA58DB1524F7C53F3CB170D45A411B07CD64F001DAA0AD1BF63A11550C0C154D20F5096DB44D1AB0A1C9D66581891A9314C18F778330A0936E7A2F3E19C18F7BC87CF078627770DFC5A2FE71B27EB8276863C3295C11E08703EF4A4FF6B3A1871C7B42C43A6EEB6BD1526AA95B7DCD6B38EDC207C630BED1768CE9505544E9053E5C8CBF6A181A1A0F48C8A98B59C3ADEBCC3A5C99E61588834024CFC71C9DFAB1DF558711B311404A739F79B45B1A8A7633081A27A08C3C16478C9D24C1229723ADDCEA225D39BDE7851345B18B1B08254181B01623347A9A57F5D902290B10476083949556663309059815626C3CCB5302B978B2CE82AF231934FFC7732352B990B21B69210F2ACC048387B95C346974C2181148078154416E08564D664DB3045DBA82C9A7934DE51AB5C1D7346A391BACA48209C8C7235309943C1CB9CAB4771C7EAF59321B510D430C88473AB16F54AE461A5DC613C6FEC61A5E899552E835EFF57FC34B7992755D178A0365C52B3F020AB40020CE21B45717654634606DFB2917FCC266193E2E5B2C4559CC5652AAD1121CCA0711E26C23EB33C1F7D389F2D742F384725D3268F8159F8C463585998289E58369FBB883CAAE21B87139E52D7EBB92B011CBE6426390458247C45F06F2519AB35B35675BF93325351617AD3AC470F73D3D3985E10277A647C96A6C56CC2346563CC496DB232FD742AEA3ADCFBC506CA8CBADA7B040A04F6E329FCEA77BEC0683E1A87C396113639159D9CA52A5A5484D2839869A2E80557A6BF7CE2EE295A464AAF835C542457D021C65C2B2A457C771FCC47F8B1056C8B7AA61D1843A40C4C9B083269B2E89FA3BA5959F89972805FA4B46E35ABEF0C57D875C54804DE77071F1219195BC8B4F7C18A19A7953573E7F4157CA03BE2852461A784E736110157BA3F83A6947AAA09E9BCAE730B9B212BB837627293A485ED6B42CA1CF26792676C1F4BEF1609E71524B877F53FD3133BF71AB13912BF37C2CD7A359EAB035CD631E1DE2556AE65D57E600C21E8E355A4ED586D667177CA0B7545CB5A23D669F4F3029E1BE4E1C0258C3A22FF5B50B2674CC094BA7018DA2A61569845C17D26F\nct = 35B5A9E583FD8BAA2044FC15E93BE2D0D1B199196F10BDD90D274C4C56C3DAF791A9CBAE48772EF76AF0C325C7DD84029B2D44B4676558A5A409F6E64D3538E9C7F6C39A19CD737916A1C4DB7DF79AE1850A0F3EA6DF53A956C93BBB5AB3D5384AAC5030AAA99111B17AD156A9307004AB9C3B1C7ADDB735A16699C0A7FD69CE08C244B6258CE70285F56875AC2343A18868A93061DDA2CFE9E6AA2C0CAF7FD0EFC593D9D06A4F6861E0643ABBC0A91E71CF244384F45E7D3DD88A27887AE4695572E98506DA6E32DAA744AD32F0A44A7679F3F0DC7C868207AED7BCD90F62F36CD695B6B4786C5290D74CAC91A28A0D3EC3D6CA53A7DCDD4353476E54FCDAD93E21C4F9CA58B069BF5BBD9BA268B058875FEA449E68B3F93839C1B6FFC1B095BD0AA6BCF24BC5AB14FB4C8B975E701CA0190F9381FC6D47207A53F3C281CCCC0145748222390F364F6F5444614325AB382B3F7EB659EB61CF2360270269B93EBE68825EEE071273BC880751548C281AE9D94EAA1764CE70FE1857E4315C610D776BE9DDC12E6848E09192E5A7AABE46BF12A268614D138557630737ABE83ABCFBBA6F886F5DBA7D1090854432BAFCFB1A61054A1F7DED94A9B1E6C1DA0E6ED87DA24ABFD24A61339F8241C87C7AA8927744137EAC239190267B338FEA6F3F564B0E30F0C08AC24D8D17C6A7C748695957680E775F494CA2472614E5F6B6B6C703673DD9C93FAE721292981A45C714E9E50FC0FCB173D5A92D52167695E4F659A5BBD6920F61F5FFC6B63E0608689D85A919E1544EFAEE4E2525B4A20B1B89FB4D5A20F2B2FA389196EADA7F12EC01901828EA8D726EAFC62420BBD9074E753559361A9CFB371D459AFCAA3F11D893B5907688A12A99FCCBD8F390EA00E4ACAFC5BA86BA6D735045CCE689CEB35B3DA81D6F21CD8E6BFBE2ECB870DF4B3AEA67948FE7426471D3325A39BB041A0974C8768D832398B0EE9273F1F488A0D8829454E17AEBDCA048B7B3014C5C3E93E5BC15317DEFDAA4DE18094523B0491A3537896689027F57436557F65D70A5440AC28681FA0224DE0958B60DED0A4A6846316B8DC836BFE99855AFAAFF6A4EFC9A5149610D0E1C3D8FD8AE4E7B489734444258A30F14681D5DD3179F530E9C0A5FF42100AA851707E3216FDF5B5DC42C0DE6EC2031E9DF703A6BBE7385396C711218B445CCC15B83C1FC1E19AACD8507A60034BE48C59C23C71EF836A7F4F05A07DD953B6DEFD09A7ADD8697097123A4DF8EF6ABDCFB74F9711E8F2719033585D63386F32CA50F72F833FED12EB70F2C1C34DC7F26205149D68652468B7D156C3B957F64BE1272766FD82725BD00BEEFC5AB6F52E0740F7E37FCFBF0D0988EE07435B41BB58DCDEC0D8B0C90C43DB5130A153DB8994A1E54EA218668CDB2C42380FE4AD204A910F0AD61777CA661B8A68F43808235C01187E6101131A32DFACF091021F9107B4964A55A3F19CD55218611AA5C479107A4EF33D76B68B9809D4CA773C4CE0347C64D13100B44A837AC87CFDA\nss = 5A864018C4C8C17C01C5EF38D7154668D9099994D92ED2EF55F02CF6B3623FD1\n\ncount = 19\nseed = 822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827\ngenerateEntropy = 851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf\nencapEntropyPreHash = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34\npk = F1390E49F3B488AC39D0E43292B70042C52355EB48B841887EA256055A688FCAC5A71C896414CE75F57BBA12967215C50D4B5BE692B6DCD1AD2190A3D785C19E283F87F784A03C8F52A23E150734FDD7BEA2AB6D122C928606BFB60570BD696D9676397AC3AA1D062EE1AB3922A2C9B5B02D14557164149C62E8029B139E6950B3F8ACC9E8C30274B69926C1658F7836F479C8CC70138B829848C7698B179643B7550E9193D6FA87350503C2B69136B08CC298B5C335B1AB95054D13C9260625E34C6C2FB8186E1916C137AD9907C8B2AC9D88FAAAA0375236751A47918F96477B7EC01819F8AE1D72951E21608C87532A9428BDF4CB5658440CB025CE3B271652961BD935624B9EB70047E63184B9503ADCD057B6744FE42908CFA325E401B9D0DB5ADA201F5D64350D392C4FB842823895E15720DD7785C7F5986F15CC2565A71F6CA11B854A293C9CE6C9A1F4AA3917130308F2A2ACA964790BAF960AA12DE3334D146E64DB81EF09563C9667381424C809441EE989EEC93597E7C5B558A89DFAA976F6934CD18B8EACB6F2F54E8F748E4BDB69B0764FD59352575066DC242DC0F1356FAB4467C8064FD23F8823148B77A4ACC642EB2C181FD5CA251B323561191CB15F2FF0784900A15F67014B518453C4C3663528FFB53271E195C27533FEC8C3B159AC1BF39C6FDC69DD5A5FE5872FFB6B2271A09966A5C738C48E63E141D65315051610F0F5588AC97F14100027B144AA23774F199D0D9A122953ACA8782A4136820FFBCC1F2692BB919B674AA1F4D679E8418E8597C74D60C5C287CDE6D44492411222636B03CB661AD66FB442193690A5F1D6B80A947442A46BDD239FE3989E6DA86949474E395056A5E6CB42B25343A7C73B650D843527444243852518A9034B9EFA7A6BB8505BF605EC238FFBC08CBEE35A94845D7319144B381819D0928C27023B727656EA843140649C03098FE74C717AABE91948EA7698DB0A86D34296B5E50DC0A9949C8BA07F64CE60DA2B6E62458DA229D52C08B9B696A124A8CBB791C0D255D3E4A69ED2C242000DC6476B4555552DEAB63EC19FE8783151DAAF78E561E1844886D4418E7510BD025299B1C83C7BA22F63335B9823043336DA897A44FC6A28B44C68A49B436B0DFA406BE642A5BD303BB0D633685364D80440CD7189B6B34F6535101979BA9D251474FC91BF2497670BAD0DA78AB3C13EEAAC864572A2F919546A57C719BCABC9DC8215B492D53118C2D379E879234A700638370A530577700982C4334673AA5D71DB98627384E8CA876E24B5A31575EA3C334D3C7D3ABB6D8891B4904B8F5DB93D0531CAFF25BE53E28C45C94758E309B83ABC2BA66D98D3BDBC53B7D06592F2712663C777DB60AFF496A217E82D8272C3A218AD8C8B04AE7C66BE35C08E3A", + "955FBC18EDD07E8E68A806FC3FE218B87F87BC332B86C2625D8FF01C9FF6214B75A20CC465F847511030B47EA664A75B3D4ED9038A9C747C6872DE0A57F3B76C60585ADE64570A21CF8548A5BE4996BC22B3D16A7BBBD20149034764B820892B9394581697E39F9B35077EAAADB06702968A5E5418983110A97D4749D3160DDB2B9C587767FB56B9ED9BB3D91CBEAE141769C2128E0ACADBAFD72FCA96AED457CAAFAF51DC8C30CEAC70CB4621CD4D7B4C\nsk = ED55584416844E1CB3C75ACFB3771013D1AAF1FB3CA8A5B718A8CE02A15AE26BACC7534F8B084A665B0608780E532A161686B07FAA83884C6A0EFB490A8A3FCABB50ADD21F58AC43EF4355246B1A661C5937562FA6067E7AA66978E4B36EA1431ED41E4E4282D4003D5BBC06CDF7AF225B6560C44F43A278677ABBA8C6B79741B3CE7C0D0769AB407C9B39C032F0E42D1866ADDF2115E2F3336384C61CE9319CC92AC1350B264CBC4059B94372631C8241CA376AA6F76111537018C01D1346019D628F1F00CDF828B48C47CBF958989B846ED893BB0B6444BC2A35C6443F77D757A0CC957716373460A7A94151CC548F0C78AA5A323581C192D00B4D96219806A04B1A0AC829002B7FCBC8CBF8A8E3ABAFD3DC2164D03A24C19D50133E967C7668AA8B81977B400067FAD2CA802A76716B95E3D28BE5603E4977C33D3BA5DF2446F6265827464641204ED972286B58567BA129BEC0CD6F1644C4032EDD6239309AAA259A3D997B1ECC535F17D773AB1C5350E3C82C600175269700A56B0D4211DD02C13D4BC7C54238F40163441702613A1DE34BA9B0B42EF0A29300098667E8003588577E64B031139DD2180DB113623FC4B74E946EEF86A1A6BB52764C6C12911765E37A685400888AA9140A3ADFC48712688435258D56337FB8D8A9E1F34BD2E818AE3B7480F500FB6BB03BD50019C33BD37B060BC2C45E8A2267D18927C0AF66076619889FF6B1769FE59E5F131F5FE40DB2815BB6886B7BCA9DA659935DB493DED9A808157E4151B04C153E673333424B7AA939559E4CA973F7644A813B8D9C1DB8C87CAC6365C0E008E329403C69490976CD3F006F3138114A6B3E6B3C4F054451E5BBCB7D232F285A2EF5202B81740053512F8E4B33FDA87EA61042D1F9736ED58E9047C8744735A728B636DBA7ABC33B2DE0B1572A28B23C25A8668CEF9291990A499BC8935F955E1CF0301A65BE870B7F01F06099192431F3436AA5AA6564C4689C1D2E11540355138C91BA6E0182B6DABA0E7A177FF320C6B04977D47DA0D51672EB96CA054AD2D4A0F72930061775592AA40E9C9418CA611893044460495D8A46B242201886CB52E38D91D25D7FA8262290628D91323DD2A51F8C7A33487232F4934133117699028381751D8594FD94910EE4115389C57262BA579220567A7B5B42441A641FD6630D7BC06802878C76BB9EA576965EE45ACB90BA549A01B6E873A1D8C741662067A116E64C8897E83204170C9BF2676EF60C20F3450804C7A1B80725DA17F9DB18F715B7894CCBB53321CF01755D168D19A96356EC07EFC62D9A8C3A8FFB15500433F915137AC42A474B8E43F283BDB2B46CD62D509A5AEE8CBE23B74CD48079D82293BFC9CD931289A0AA27D8A930BEB2000ACC2019E3CCE107A18E9C4408C516FBE19E45459ED77231851B88B6B73156EC820A4C097072C2FD61C83D23413AD510662894DAEB238992138F98185042B53A637AEFA83378B026FA7BC314516B25D343F0E0AA7772CD2DA27F8B39A8BECB44923792A7D586631B2AB963AE537768E45961F5F96CB42320E75738A964168B9403D5B3591AC5679A61857C818B2A486BB299019C7B03BEB50D2D40A17E84712AAC01F1390E49F3B488AC39D0E43292B70042C52355EB48B841887EA256055A688FCAC5A71C896414CE75F57BBA12967215C50D4B5BE692B6DCD1AD2190A3D785C19E283F87F784A03C8F52A23E150734FDD7BEA2AB6D122C928606BFB60570BD696D9676397AC3AA1D062EE1AB3922A2C9B5B02D14557164149C62E8029B139E6950B3F8ACC9E8C30274B69926C1658F7836F479C8CC70138B829848C7698B179643B7550E9193D6FA87350503C2B69136B08CC298B5C335B1AB95054D13C9260625E34C6C2FB8186E1916C137AD9907C8B2AC9D88FAAAA0375236751A47918F96477B7EC01819F8AE1D72951E21608C87532A9428BDF4CB5658440CB025CE3B271652961BD935624B9EB70047E63184B9503ADCD057B6744FE42908CFA325E401B9D0DB5ADA201F5D64350D392C4FB842823895E15720DD7785C7F5986F15CC2565A71F6CA11B854A293C9CE6C9A1F4AA3917130308F2A2ACA964790BAF960AA12DE3334D146E64DB81EF09563C9667381424C809441EE989EEC93597E7C5B558A89DFAA976F6934CD18B8EACB6F2F54E8F748E4BDB69B0764FD59352575066DC242DC0F1356FAB4467C8064FD23F8823148B77A4ACC642EB2C181FD5CA251B323561191CB15F2FF0784900A15F67014B518453C4C3663528FFB53271E195C27533FEC8C3B159AC1BF39C6FDC69DD5A5FE5872FFB6B2271A09966A5C738C48E63E141D65315051610F0F5588AC97F14100027B144AA23774F199D0D9A122953ACA8782A4136820FFBCC1F2692BB919B674AA1F4D679E8418E8597C74D60C5C287CDE6D44492411222636B03CB661AD66FB442193690A5F1D6B80A947442A46BDD239FE3989E6DA86949474E395056A5E6CB42B25343A7C73B650D843527444243852518A9034B9EFA7A6BB8505BF605EC238FFBC08CBEE35A94845D7319144B381819D0928C27023B727656EA843140649C03098FE74C717AABE91948EA7698DB0A86D34296B5E50DC0A9949C8BA07F64CE60DA2B6E62458DA229D52C08B9B696A124A8CBB791C0D255D3E4A69ED2C242000DC6476B4555552DEAB63EC19FE8783151DAAF78E561E1844886D4418E7510BD025299B1C83C7BA22F63335B9823043336DA897A44FC6A28B44C68A49B436B0DFA406BE642A5BD303BB0D633685364D80440CD7189B6B34F6535101979BA9D251474FC91BF2497670BAD0DA78AB3C13EEAAC864572A2F919546A57C719BCABC9DC8215B492D53118C2D379E879234A700638370A530577700982C4334673AA5D71DB98627384E8CA876E24B5A31575EA3C334D3C7D3ABB6D8891B4904B8F5DB93D0531CAFF25BE53E28C45C94758E309B83ABC2BA66D98D3BDBC53B7D06592F2712663C777DB60AFF496A217E82D8272C3A218AD8C8B04AE7C66BE35C08E3A955FBC18EDD07E8E68A806FC3FE218B87F87BC332B86C2625D8FF01C9FF6214B75A20CC465F847511030B47EA664A75B3D4ED9038A9C747C6872DE0A57F3B76C60585ADE64570A21CF8548A5BE4996BC22B3D16A7BBBD20149034764B820892B9394581697E39F9B35077EAAADB06702968A5E5418983110A97D4749D3160DDB2B9C587767FB56B9ED9BB3D91CBEAE141769C2128E0ACADBAFD72FCA96AED457CAAFAF51DC8C30CEAC70CB4621CD4D7B4C87F3829EFF562789B3E19FAFEC92E4B5F95B45F3786F12D9C24915CA484A49CE1C0EC046899A777655233E4E1B5CA44E9AFBDC67964BFD5D5E3DBB45E60D03CF\nct = 8AC0D6E2C157FB04C753D97F8EA4C0415FFC46D2406D65B51E3991A286A66A87FD7E7F5DF13F446F0DEBA8D783CCD9164EEC2CF4AB002DC6DE315F3F6A3BBEF9E2A0CBC833E12F1097D11158D73C579836B41DC1C0186844E2CA224855F8A2ED24F31B92827F0A3125EAF79140612ECE54F5A9DA73BF775D8112220FEDE4B590C32B08F4A7B91B7497739C3EC80E64F2165E7F032D5A583F0AD2D7AF369F903913114A2829C8DBE77B460B06ABC23D184A7ABCF6853283828623E89286CCD3E4866C57F28146203100665792E128AD7E105DF6F283ACC30A1BAAB1E84A78E86C3B49D0950F93E1B88E655DD6B3C689988EF7E2517812006D38EE0F9FFD7969A789AE2D8ABFDE2A8F1423D628737DE52AEFF8362218317968163A5A562BE757C3E9F806AC7F8A0E5B5465841016A694861AA1DF8637A345D25EF933EEA840C5CD37E67E7489F48914A07C3D6E8118ADC55CB436E8F283ECF5CD46084B41F24430A80C6FC1099FCEB3C05CBCFFAFE17F129CCE938C0DFDDA9A440E1BA6FBA8391F84020E7BC29ECEFB06AEED4272FCFD947C689EBC9FF59848EC8D5D8F69360F74DE5CC384CC547B31249D06EC288A013BA2E07C05AC634FB3BCBC284268458D441C42545F823C546AEEA8E2DB8832D683709B06B7E6BE4D68EAF8A5EC172EC63E625576E32A5865E2F124FBF6A513FAE2AE5DEF871E89BAC25AA35D026E7121D4D2DE17DCFEF4F021AAA8AFB7B5CB9B5A424652320468E658AE8AB9141F66C35EFC4C1E46D7A8145D9CA9D57D0D5BE1723E7B13585F16919988F7F4FAEFFA4E9FBFAC36968E96B3DDA7F6F922337B15BC910C25CD3ABDDFC4938B21519D914EB51479ECC5ADFAAD5E844BDC958659F38E2A31BAE0F1894FC5A39446FAE1EEDB445CB1ECE0B0FEB796AF4124F60A318E5D52F59995478AE1CA6433A1338B132DC236366CE44D63C1930CD3BCE9EAB66A911EB0E25512631C96D7B45F53BE8C0D0E9D37987167B2FEBFEC0ACCDE2D31FF4A83150674DC11863CBAFC2BDDDF72232287A7C9D05221FBC916D6AF6A9043575BE8BC086795504DF62C50B859FE9443A08322F943EC913B2C3A3CEFF992480590BA4FBA1A956301125F7F1EE6FD5A78356554E5123C4587C4CBE4D4ACE2A00B847494CE8F88C60ABF6D4F86EA6C3FD05A01678E212734911A1F1EB0FB94FBB5F10003342E8DABD2C6FDD670652B77A8CAB31ED4E15DCA52421EA6328DFEEBB387B64BC3474A53D0CE7BAD442ACD0C6C9A615B32C1795DB075D9B25AAA48D32219FFB7BCAAF2B5B53F03CF4BAC5FDC6F0045067DD9F55D8C0B4DA63A91B8C40CE5BFF3E6E6BF71943A67FF828FB69E7C1A0EC4E10099F1EB76371DD43044F0007A22AB9F9EE22F663CCFD1E0F2E5849913C89808E7609F594E14A7135C94B4088F726A0A3BDE5CEDF9BE2F7402BE553D1A5BF8A15B90E711EB5BD84454F0219BF7DB0F9E031F93175BBDEAD918BEF03C68D279368FC8DE7818811EE6D5B09F4B773BB3100B688FDD6DE7C8A5B3218D4B53\nss = C8B9932975C3EF329424392DA29B103F367FFF38CF402B40A0299BCD2CF10FCA\n\ncount = 20\nseed = 81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8\ngenerateEntropy = d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73\nencapEntropyPreHash = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940\npk = 2D7B0180596BE297A4631ABE0D48A046DCC99C8912B8255FC45592A2A61230652BC7C450A674CCC3ABB27395738D177E7579AFDCC30E74E7C7B5AC5DC235176343CFC4920ED8D9472E13C9B36A6D38BB44756BC31FBAB62893656DA065901303700A14B2F785D98896AE97953BA358FD53091012B97498CD7516B0E1898E2F6803C5A13D70F5BEC346917249940BA35E3EA954F6CA13C343A09CFC02D8E66852C1AE0FF8B22E7424F53B1897EA11268A6B866C09EFE8694031754ED1A2A147C0086283284133AA6C324E0B0570469F09E0901F25", + "213FF9B113147990B54CB241268E0B6C7A3A90C638B7C483C71AC1344BD65C988736C4756E0B71111BF5B810FB3CC4187363A94EFA020DE1C3CB9A005CF472BEC5685322FAAD5BD1CB0F240458B56FCC5A6167F22577565DAC1BA9B984C33C348BABB70506B87926540547389B805BA01E4443B5D60B9A407F8B060FCD96C4B717BAAEB72400EAAA9853B962E8A0C8D966458CC4CFF31E960C447C6B205629419478360CDC945D6B9A55504D853C1E51364E7A9AAD82B64FC37A02E4139B9E6C392DC83C04005F6D1299D990A89ED68ACC31B5D1D224F2C8B3CD5280A12C6E088CC2F9D3C59AFCB9FEE458AF5135C9B4B477D878F34723E3912189D2764F9366AB8752C9248A5684296ED46F404A1739BA72D5D652C614860D41898E45B72BF66D587089FCF49E3B94CD26999D7539C32BDBAC0139B20988CC7B578ED880048885355F193DDB1690B9092AA2A86AF03A41797120BE84334EF25C2E70BFE8E0A658F03435B65787F38BC9452DDC584162955F8B8560991C407FA0C12D770E80FA4A2CF7B853708BEF2A44F959B9D05B6FAEF83F6F41A2454257B0157C55047AE7D0CC17079E118C8A4EE3358D877251970EAF86684EC70858A94BBAA4BD2FD1895C2223320CCADCE636C2156471B76C48D53E6A6C12A1317C39C48BF3A0AA0DBC8AFC034B43398B9F1C56D407A4B7C2BAC134024DF6AE9800B230E2592F529F79F0AB048867A349684B242BC4D2284A6106DBA36DE7B3A114B6353B479D014A69E33ACF5C465CED6669B22027D6657F12379ABBD248C6967834239E2D3A0211B73A77D681B61892877B7E102A53CB4602E3DC1704EC92A9E260D9817C6393062BF520F7A845FFF19123A1662FD241090AC81EE1748EEA878D53969FEA20FB95688FCB3D235910F154BD09A75556D890409CCE0A20C6CD2A59664BC4ECCA3D4725910D210DB0C848CE7242CCA945F1568561BB90D9A4C3DFBA83074A16FB3AC934C865DCEBAF6FD90D5B458C22542DED5111E77C12D8656908557649E9155A8472D5213B46F739F095B5FD4A2418074EF7DB9385F19D6630AA29B28881AA3474B7AC352C5DFBFB20FD7B8A0B87CF3933547CD498256A9E17733AD6967D7B9C7ADC64A951EC5C8ECB75B9190064F3A862D10CB5707215F456CAA10A2C240619925A140B6CBA878A0D40283EFB9E1562C227D716D2935E8D96649C06AE9465AEBF552D68DA1E7991BF987A4DFF4371049A0DC9E56F110779D562959F278B069B3C7712AF29027AAD6109BB0C3201565C0B0892A62AA74CA7BD6B48039066A95DBCA4E76A3A323612269546B18BA1BDA19C123C24504ECDF72189DFA1CD24EBF011A3BB66D35F78633E1EE7B249FF\nsk = FFD8874D8B37C946409D69CB03529B7D1A43DDB24792D4773CC723643567671B8E0FC2B903D302679A530118AC453B0541A2389C46B38F317B43130972271D8146A66593B8FE659DB570C941F1ABB4F295493085A85277062C3D4DB168E466015EA506B5B8A805A435EF6812A6B68AFA9372776717C1042E24E7A10A842182E7C40C4CC547B98FE007A1D98804AC5BC3C31B6511425A558C73E5B1935C7A664EE224955B6D67CA54D47B04E1622716A27B21F12A2EB27C16D26A541CB0C1BA5A1A8629B7F2222B84CDFED9CB6F666B41C92FD0B074F42B5D2EE72E8C5443F34C5DC2920DA165558AF074E3CCAE84C1CBF1F70624E1A3A30A7DB045A2C4A79BB1A4B0F01187BBD8B29A8C60B07068A72264D9B305B5E391521BB945D53CE1D65436441932EC5867549408B47F28D3BF37D7AF0DF432CCFC3667F4ACE969542CD626637B570FD84210B3AB5456B23B8B339F4885E9A96BB17CCF1CA4A962C5667D0C3DFB356146C04BB8391197D54D0F4202F160824D900B27B36BF8ABC7876CA331C2C3A8A161D98523ADFC1EF9D538C9203A6729CFCF6089F7D72F57093EA3A34113749F23EC21C051AB2C836679B0210A549F2678C7187691DE949994A25769D4647FD992BE411E24E302C07569CF26C11F3942CA505391A794D42C77DA0A324B05908AEB9C70B88B38A95F371B1902E06D071457BBCB382AE4C36F14AB3A747A30CB7E9D35791879873A0333B3FAB967770465A056DE9C4420662C046AA8CA32093AE23ABD80406FE60BDCD1725DAAB0E50931C575A0C9137FA61442B1101B05686D398A6FDC0BBBBB25A073E99C3702B9268CA91420A1198B5C54501A03C878B6827E6D586AB42C2FA47258D1255711654968FC80E1364886F18E98FC10EB85645B399788DC225B1A233FE564604A86397A4483C102203188DF667961BAC9EF19B99432475C0A2C9978C81CF5314A2B2AB37479549B14C8D70ED8F0C6625938CA4A92BEE5A7AADB286E507EE8890772C3353E35C2DE8696041BCC8B81997F8C7800417C91C32E9B8B34B62A25E5C2AF2854CF902269C3C5B50A5209DC1C63F8835B3A73137D855C69F9335FC66EFB985933F4A66B084AA58909E658998A15AE8B087120F59A00426CF9A327DD48467F8C12CFBAACEA7BCA7407060C42950CF9543CAC1EDF9C296D978A2C36AAD92B665D6C9513B59278AC1CC781204E555E27F81E976A74D3055A48035203472960E596C7C4C2D0158A006D884F40681C6610F1124574EB9FF5323E10480D0E306F1E398AD1E6CF8057024D072DEF4719E3A6BE9AEAA07B56077BE495A635C67066A2945376C9836EBF4C413A05A9B1348C31329884BC7D820A6BAD7A63BD62518878A97FB525332433573973DF74A00EC02D50198A2B1306005335E6A51191505FB244999CC333BCFA4E7845B766B050CF66607982014D28548A4454F86A06E9321C82781478CB938C709EC5CC81EA1A9269543DC8EBC6D253BE1698990C81C587D7263E7445BAF53316C23EB8863D151A4E5659928AD704C1C7B2BD2A1987907A05CCBD2F0C78232A10653452E3DABB7598CA83D37166791EF11A2524F371180984BF72A6E2291301606B7351A284A1A62D7B0180596BE297A4631ABE0D48A046DCC99C8912B8255FC45592A2A61230652BC7C450A674CCC3ABB27395738D177E7579AFDCC30E74E7C7B5AC5DC235176343CFC4920ED8D9472E13C9B36A6D38BB44756BC31FBAB62893656DA065901303700A14B2F785D98896AE97953BA358FD53091012B97498CD7516B0E1898E2F6803C5A13D70F5BEC346917249940BA35E3EA954F6CA13C343A09CFC02D8E66852C1AE0FF8B22E7424F53B1897EA11268A6B866C09EFE8694031754ED1A2A147C0086283284133AA6C324E0B0570469F09E0901F25213FF9B113147990B54CB241268E0B6C7A3A90C638B7C483C71AC1344BD65C988736C4756E0B71111BF5B810FB3CC4187363A94EFA020DE1C3CB9A005CF472BEC5685322FAAD5BD1CB0F240458B56FCC5A6167F22577565DAC1BA9B984C33C348BABB70506B87926540547389B805BA01E4443B5D60B9A407F8B060FCD96C4B717BAAEB72400EAAA9853B962E8A0C8D966458CC4CFF31E960C447C6B205629419478360CDC945D6B9A55504D853C1E51364E7A9AAD82B64FC37A02E4139B9E6C392DC83C04005F6D1299D990A89ED68ACC31B5D1D224F2C8B3CD5280A12C6E088CC2F9D3C59AFCB9FEE458AF5135C9B4B477D878F34723E3912189D2764F9366AB8752C9248A5684296ED46F404A1739BA72D5D652C614860D41898E45B72BF66D587089FCF49E3B94CD26999D7539C32BDBAC0139B20988CC7B578ED880048885355F193DDB1690B9092AA2A86AF03A41797120BE84334EF25C2E70BFE8E0A658F03435B65787F38BC9452DDC584162955F8B8560991C407FA0C12D770E80FA4A2CF7B853708BEF2A44F959B9D05B6FAEF83F6F41A2454257B0157C55047AE7D0CC17079E118C8A4EE3358D877251970EAF86684EC70858A94BBAA4BD2FD1895C2223320CCADCE636C2156471B76C48D53E6A6C12A1317C39C48BF3A0AA0DBC8AFC034B43398B9F1C56D407A4B7C2BAC134024DF6AE9800B230E2592F529F79F0AB048867A349684B242BC4D2284A6106DBA36DE7B3A114B6353B479D014A69E33ACF5C465CED6669B22027D6657F12379ABBD248C6967834239E2D3A0211B73A77D681B61892877B7E102A53CB4602E3DC1704EC92A9E260D9817C6393062BF520F7A845FFF19123A1662FD241090AC81EE1748EEA878D53969FEA20FB95688FCB3D235910F154BD09A75556D890409CCE0A20C6CD2A59664BC4ECCA3D4725910D210DB0C848CE7242CCA945F1568561BB90D9A4C3DFBA83074A16FB3AC934C865DCEBAF6FD90D5B458C22542DED5111E77C12D8656908557649E9155A8472D5213B46F739F095B5FD4A2418074EF7DB9385F19D6630AA29B28881AA3474B7AC352C5DFBFB20FD7B8A0B87CF3933547CD498256A9E17733AD6967D7B9C7ADC64A951EC5C8ECB75B9190064F3A862D10CB5707215F456CAA10A2C240619925A140B6CBA878A0D40283EFB9E1562C227D716D2935E8D96649C06AE9465AEBF552D68DA1E7991BF987A4DFF4371049A0DC9E56F110779D562959F278B069B3C7712AF29027AAD6109BB0C3201565C0B0892A62AA74CA7BD6B48039066A95DBCA4E76A3A323612269546B18BA1BDA19C123C24504ECDF72189DFA1CD24EBF011A3BB66D35F78633E1EE7B249FF699FB2F061A75F111F4A7A60195D9045DC01716B6502CC107CBCEDF122E8F6196590A2E5C7ED86CF2C5C2A898662BC9A81418720BBB632EF9CF0B845ED052D73\nct = 88BA446E3DACEFE9158DDF1619C9B1C6BC274B8E8F819342BDECCE593F705B29EDC21B69F1B65EC4674F71CEBE673D7FCB0CE2FF757F8EE5D5A5F8F5035A58E1D75713EDE33F0E7B98056F1EEFC0C692DEF07029C0EF3A857D6972723C7F49B79855703461A3F83857AC0F2331E7F8B3889FACDF6373F8CC49DFB5408B57DF0CB0484862970993C5DA712D87335F7F7D8C4B818E8B96FEDDDC435E131F47DEFF13919A470B25332F346A8317F0D3F8B13CD16A12C63FF17F7943275E2B4BC0B3F4AD52B67EED6A0F499DB79AEEF56964029E1FC686B78631FE0AC8162E2D3C3D36E2958DD95312FBD18ECE60716E398627437655603D1428771F24D2F39FE6D1B759A46E303BA9ACD68866F2729CA6FFCD91FFBA30D8DA6433383DC8755772C94975A6A1AB6B5A2105901363C8B94A20A48618311E4E59975C87E46AB0687D30A7BCA3E13EDCB560706405FD83184F98784EDB59535CC3CDFCDE98EE989DA0990BE3FAFF402220AC0070FB31CCF352E26727B06F253F8A5E47C10F95456705FEA41AA9A41AF7BB1A5E3DB02F9E1DFB406FD4F27FD78C25E86D9C04FA5B0C6B2D6A6D43D760F2D1D01D1AEEEA971A9BA64A95FD63C9A95B0EA5B4A83282C920E0E395110AB2DBC59C8FCE8307B6106AACB58AFB4C38A868B4D20D7772810E9DA53A5AAEFB991CFEEAE0D54A1A4934A22BE3F8F33D945F66F79AAF3B88A6D18963660D8F1E8EB23644E487E4EA68897C34628F30FF3EACDEE3353269D87B2FE2FD837FE2A6EC7B1EF99341E470AA67004DDE57EC6A2B334A2B1B90291D73D8C1BD43C38FA82E088893ED5D2149F568BA80A68E08131CEAB491A61FCAF07DBCFDE77C530C60BAFDCF55DC8BA1F9478B28D9C6A53BB9DDF4491026B754AC31214D5E774075DDED90B670181300190F9A5B3F47CB3CAA6AC0233E7AFC708DEEB1590266DD8FBA964B32880AF48EED81534B9D47F63A7195CF60EB827D2A0D94D84EEACE28C34711D116D011074B118C65", + "5380F6B2E3106ABEECECF7186B2D45A324452BFFF6EB37DD17C4CB034DE10D5F24963EA898B5F19641BF1177B64F6832331678EAF080B9A65F93636D2D4F5DCEEC96DDE5C1E8C7EB505D4638A6ACF4746AFF7EC6456E1DFD2035CA2CE87FE16EE3E69F5C06CDC5BAC084F9605AC9F07BE61787B1057C1CF5F7E3AF45064BF8920596522EC0A48E73F385EA60A256ADFAB1EED0E08104FE20AA1EEA2CC466E0B64E4F94AB0378605B7A2C38BE7FD606229C74B5D3A35B2BD5F46A3A4F180111E6F35594BA9A754C4D00E57B0C62BBC3D326DF497DEB7BD50401CE2E5AF6F75CCD6781BB944922329AB94BDA5557869E28133AE070669BD9818397C5E5A1229C145BDC17B95834BDFE9A2FC672F091C8F71735499E4A032D34906FFEF9D297AE68DA67C76770E2E9EC362B6DCF520B9338E170BCD1DC4BB9F94C564264D5B6439CC128AD54FDF6CFE5CA16AABBC65415B91485CEB77120E03B56C558D4899952F64CC140BEDDC8B3AF3BF805C12D21F6BA22C2\nss = 578E4E308F2B426A7B1ED7D80C72396A914CE77A4A7A6D16B26E4AF3D59B491B\n\ncount = 21\nseed = 30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994\ngenerateEntropy = 89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465\nencapEntropyPreHash = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6\npk = F3576FF861541032094855B18CF574D868B0EB783CE9011F28FC14C486B122CC80093897BFC8AC1082421F99767BC42B0FF41B22DC7B50D5556041338E6C4368AB190E92608F6CC69D8B33F1AB04DE68CF96D9C5882C97CF28C30B86924AA57849954369C5427C876A9B1CA341E8522E1357E60A4450B69F150658715403D1E1C957E5A914B9A3BC4C45489053306329C7984E76F169C8639DE4080DB1671ED01A24724A101DF89E45B5B385CA2EF663586AE58D9B33ADE9738F84482E6E28909E7641AA673AD772B125161A316166E1717FDBDC8D02B2B2B6DC21805619D4FACC40E9A21BCCA9D4DA71220A4631E95B25E960192A22A39B904BBB02F1184B79A97B3CC16B5E4B5EAF278913B7A195F3107342A77A68CAC90C1B5A3CA9B354A6095C29C09C5AC2B44C6CB28A250834D5F2A307EA3434977D0087017CA2692B79008640B770B41EE2C2C77BCC2605F1857368C8E12983AFA8633C870115A3818D6BCBCEE864A8DB694F4B77BCF63A8AEC407A45716AF6358065C30B77B68C2198B2FB558F463A7477B9FA7680F1E65706A888B8740A87CC7E7949156F896C182B53E464721E46A258820201887CE9B83D43250B63E2AB29900A115084A6E66584F767853B2E684C547D97266B36B6838AABA73298DAB79C58C88F1B51113EE752736B7566EB5759CC4DBC37551135BB3C87B1A6C83AC5A38DBD78106EC0C5E9967A6D81139CD516027C25AFBB6C47E3802D56079E6265C4F21F1315A96AB994597214B814CC53E8566330CD51FB4045F605DF1C7C9C255166651DE6041B7FD85C7E376E28076AD352051C65494A1054C30930621C53EE8947DCE3C55BD686F186CD5AA21AFC17664D36A2D7F5008AE83950B93AE510847552A5C2F761207B0F478C73C4D6313C8ACC25B13EA64A72EE3334013CBC0A855B55E88EA17466534786B6176B9053CA9D0494C6B4A940B70B68F40BF570C461F11795952E69F21EC4562DEC99448263188EF44E71A1681D626CAC69C6B56AB51AE656BE1CA028672D97D044E43577F26329D50851B0F8A4A1B6C2B673AC6418CCD58005AD400C27D274DD4732E56B5D7C0B6EE731A99E15229F7295C153AA3A873C20C23A35B6137C824F6FB021A0E28F98BB3BE8DC07A5B038DC89944952913AF7A39A9B00F1A038A628686A735DBD4C45E0B8BCDC1C1A902CC4D0571CBD589F507A0C0DCB81BD39811E723358D6320A3049BCC90D776562EB34877978C9929548286A85EFB85F7C6C76FF255F13A0CF5E70304F1CC838FA398FB34E26CA662759C8F3657125DC2AACDC4615653EF074A784500EC60980BE4AAC94B0C7A9012DBE73CDBF1687A684AC63526778926654A4AE4CC779A600A836E3273ACB95A802051F18AF32683F52363572583FDFE30287B2632874CB04832F55E0944712C86D37420137C56F6251A1352AE37A0C3FDB885CB561E63A493A15BEB5E3B123ACA6B6B7294D8002E7EC758AD2C22D336AAE3C067703821842CBA2DC0B1B7A45CC0A48202A002F927122C040F84A884C1334C1E17347108B91C055D331C0B170C6F06048B40CA0BED838AD963FB8747CA714CF1D3267B701132046699798421ACC06A3BC1ADE172FC62123235C2D8DBFE40DD56CE5DE6756CC4B6AFDF64050DA2EECD9953E893C53BF7FFB\nsk = D32CBC1116AC88219F9AF2C33BEB59BB94B372F97815278F0FAB2C690C94B8F209DD1575BD7C0BC7F48AA133BFA068CF1AF1612C3325B8D08963BBC66D938F46843FEE424357E535C2259ED958A75CA6203286190BE53A9B46373F8B41CB38C1CAE2BCB91898669A872F1A8D9CD21227E42ED655569202CC6B494CC6A6BDB08731CDE417F48B86554CCAF953B8FB70AEC727085510CDBAA7CD2A0BA853928886332FB1E3A419C49B34EC90FD31B716252ACCE7A79D05CC04074D69AB3CC9809102261A2191A086231DC70AA583E86912E5BEB2C1A22E841F39DB531D5C26CC333834A20480D6B1CCF19A654149045791D33B414696375DC3C7B0644626E8822C5325D52BA764F2361D853D244416CB9A5BC0540E1238CCB53438C90A196A45571F743894F060F6031FD623ABEBB4AFEA05190DD9452C981352A78E09579F05E24DB2033AACFB10D9335986E8542D9480BF5603FA932D2D0878C3753E6524A809324AD6F169D7FB6D9C0264423A632996ABF297707D8412A6B86160B69980E18ADD1C372FAA406F540C00ED0A75C3544811759C3B5026E6C19102B7160883ED002DE5807B5933934FA01559C4A790230EE93C215BD75AFF117D0F170B4FEB7AEF5B007ACA616E688161FC00CB037C8232CF2DCA569F01A2E1DC2AF7ECB6111181F2EBCB1DF27C6EA84251D8A2B6B6582EF915E2B8C7F8FB6BE8844478FC570B8054A067B34120B47FC6AC68125CCA8514DB4540B7796C9FD05523E7014DB34B8EC94D5EB66C9F5CAE2F838191D2234F43C72262A18DEBA17AB495B7F0529D89B8E1E407BD5A185EAA2444D20C6C9566526B8707B13BB0CC8D9589773DB90952A5CD78E43BDC68CFA4401D7912618F456EB4F97AC1B49AB948592976233F962B1916531FD1672BB69BE320A2985B38B80279572488C5F86BF3D55FB9FB90449B66FC874B94292000466786FB7E393765C7057051999711D234B4D277419320E0046EC0925B41D6B89C62133BD2734E296DCFE90BF6344219A6A22D2CB50C75BC02B07FD0DA11FE0A0A0B9AAD76001D5D7C8FEDE065DDE87D5D47821E756A926638395883879A91B94C6164A40895476269917CAEB12944DC956174B6CC5154944571A6F6553F604D3212728FB08AF6E8C0EA00265AC0C5464595B31A9131871D79298867AAB426D009480C0BEFC08ACE14991399079CB62DE9E6BC80C88C3339640FC667EC837B691C3DA4556A952B3E63C162EC911101C5A49B35475AE68634A7B0CEFCCFBEE608CD4C43C8EBA7A8F957DB595645C64ECF08B50C7438BFBB415C27A45AE940AD077E5A533825D998A9095A735B5D23887B0048AF49CA85F18395C7D3CD06BB687C92CDA9AC9C03A9333A866A9639803C76B5B189294A269F389ABB5010789D410B88215C554008CB10274F781ED6B0BE3903576CD16934C4B6B65296C477AA174043F06792F3944EFD0206E34042D827CAFFD2989B936B91694825C4BD8B10C0777B11971CC1EFB93EC1B3674AFB4FD07568FFE89C707B5785C140D51B433B7942D88A6EF9BC9D091472833004005AA803A050CE03B2BB551F62FB1FAC6649D3E14F0141B2EACA73B700489B73A8D840834A7802A96864610B10F3576FF861541032094855B18CF574D868B0EB783CE9011F28FC14C486B122CC80093897BFC8AC1082421F99767BC42B0FF41B22DC7B50D5556041338E6C4368AB190E92608F6CC69D8B33F1AB04DE68CF96D9C5882C97CF28C30B86924AA57849954369C5427C876A9B1CA341E8522E1357E60A4450B69F150658715403D1E1C957E5A914B9A3BC4C45489053306329C7984E76F169C8639DE4080DB1671ED01A24724A101DF89E45B5B385CA2EF663586AE58D9B33ADE9738F84482E6E28909E7641AA673AD772B125161A316166E1717FDBDC8D02B2B2B6DC21805619D4FACC40E9A21BCCA9D4DA71220A4631E95B25E960192A22A39B904BBB02F1184B79A97B3CC16B5E4B5EAF278913B7A195F3107342A77A68CAC90C1B5A3CA9B354A6095C29C09C5AC2B44C6CB28A250834D5F2A307EA3434977D0087017CA2692B79008640B770B41EE2C2C77BCC2605F1857368C8E12983AFA8633C870115A3818D6BCBCEE864A8DB694F4B77BCF63A8AEC407A45716AF6358065C30B77B68C2198B2FB558F463A7477B9FA7680F1E65706A888B8740A87CC7E7949156F896C182B53E464721E46A258820201887CE9B83D43250B63E2AB29900A115084A6E66584F767853B2E684C547D97266B36B6838AABA73298DAB79C58C88F1B51113EE752736B7566EB5759CC4DBC37551135BB3C87B1A6C83AC5A38DBD78106EC0C5E9967A6D81139CD516027C25AFBB6C47E3802D56079E6265C4F21F1315A96AB994597214B814CC53E8566330CD51FB4045F605DF1C7C9C255166651DE6041B7FD85C7E376E28076AD352051C65494A1054C30930621C53EE8947DCE3C55BD686F186CD5AA21AFC17664D36A2D7F5008AE83950B93AE510847552A5C2F761207B0F478C73C4D6313C8ACC25B13EA64A72EE3334013CBC0A855B55E88EA17466534786B6176B9053CA9D0494C6B4A940B70B68F40BF570C461F11795952E69F21EC4562DEC99448263188EF44E71A1681D626CAC69C6B56AB51AE656BE1CA028672D97D044E43577F26329D50851B0F8A4A1B6C2B673AC6418CCD58005AD400C27D274DD4732E56B5D7C0B6EE731A99E15229F7295C153AA3A873C20C23A35B6137C824F6FB021A0E28F98BB3BE8DC07A5B038DC89944952913AF7A39A9B00F1A038A628686A735DBD4C45E0B8BCDC1C1A902CC4D0571CBD589F507A0C0DCB81BD39811E723358D6320A3049BCC90D776562EB34877978C9929548286A85EFB85F7C6C76FF255F13A0CF5E70304F1CC838FA398FB34E26CA662759C8F3657125DC2AACDC4615653EF074A784500EC60980BE4AAC94B0C7A9012DBE73CDBF1687A684AC63526778926654A4AE4CC779A600A836E3273ACB95A802051F18AF32683F52363572583FDFE30287B2632874CB04832F55E0944712C86D37420137C56F6251A1352AE37A0C3FDB885CB561E63A493A15BEB5E3B123ACA6B6B7294D8002E7EC758AD2C22D336AAE3C067703821842CBA2DC0B1B7A45CC0A48202A002F927122C040F84A884C1334C1E17347108B91C055D331C0B170C6F06048B40CA0BED838AD963FB8747CA714CF1D3267B701132046699798421ACC06A3BC1ADE172FC62123235C2D8DBFE40DD56CE5DE6756CC4B6AFDF64050DA2E", + "ECD9953E893C53BF7FFBD3413880D082F26986FCF452A84A8DA934ED06198B290ADA1789E74D9081A9E7B6591121E25D64010C25A18676033E1D7278AC5F2D0B43A31F3A4156AE710465\nct = F33AA44E8B475A3E664A1585C8A1058B26E2849754F17E4FECB0414D2EF214AE903CC1B8436B302A06BAFB52754F9908496F00B79C8EA49C3FF6B3CA9F7AB4FE2DAB7B915958CCE56FC53EA3F168E79898C06E99B2A5C7F39987D21084317FD5B99BD6B1121A1E2F719B64E54A40C1766A8A0487133272801A7D9B589119104886E2914356BC14C7B9A1DD2B424599A059AFFC963B5866A7EC744C20166B0CEB632ADB3722CF0DD49C85165B6FC05D5B20847A416482472A567A33B8653CC9E455291ABB5E65C83D051EAE887C946DF46D00CEFA7313406674FF748EB33C6351E3A18821801CF0379FC77DF7A3291515AAA7BD5538C7C5DC49EB8CB61463984A3BF34ECDEDFEB5FDDB630BFA20EB3AB4BDBAE85AC6A15162C6D27833F50D9B00DB134601B7D3B32A4D1A6220B98966E51CC1D59926DFACD2EA8EEBD5B9C1B0581F16E5E79389A7F716B0C07E353BCEF084778A9C61491456DE86AC155309583B512F719B6D2C74549009AE11583099812486239A69AFDD7571AD30C622AC4BE434F25A4D70A7EEBEDA51085A918B0E3BCD20C1E1421A527D62046AF8CDB6EAE295E10DC25C4DED82E9067CA0E1B0B289D1DD14866CE32F6D12EE0EAA215FDFBA68DF0B0C5808B76A2C24AA00AA92B08AC4C0ED48A573841D265FD079EE835925A224D2055639BD642ADFC9D5AAE4885B0F7C17163A53D0CE55246DFA31943BF03B6B1D90A7CD2AB06B099EBB67A3C28661789A9D7DAB10F29E1D4BC4D3C6102667018935BD9EAF14CC8501F9A84BFB0868B922C16417B227B2C149BD3D176C429147112AB1DA57ABBCB07D85D936E62053F4EC915792080BEB2CC142BDEC7AF12919CA448074A601BD3AA1235B499B96FC9FEB8C5B3108AF77BB1D0931F92E527ADA040A1FBEAE4A7AD92CABA96F5DE69C0FD78DB39DC2BE90F81F2BE00B4949BEE566B80B7881905B59A824506852BA8DD37E44C4A534A7A6A790D9A243439CC5A548B9B07AB0D4050676EDBC6DD4B84823E7B8DCF4EF8021D5F6FDFCC470DFC8FCB717C2FCD5CF26AA1EC03CB72FEB58A50B831C5E36B63E6A5AD7C8D57B6DF835F414D3B2D0A86ADE0F85E76E5F3B770345D3A2DF2370BF8E994E4A5116D5AA3E2C2BCEF9D1D268781453FB3D1E9BAE21595BAFAEBF72B1B4FCCD32C84897D712B720DD962C5ED46803DED0AD4FC417647DB85C22970EDED391F065143A7CB8BA660FFCA69327C2CCFDDAC83C0215818712332A79881ACA7321098AEE4F733D44F31F3A79BD78CA4B932B1EBCCFEF5C3C987FF95485F6239DFD607E3F68BF6A746F17CF0F4F438020BFDA627C5C01C65E0049914C822ED9463B6FE957847722F659621BAAF475014FCE9CF5B1A11D7392DD286CCC616EDABE08C80E56E77A41584261DC2F09D7E55A8BAE0B0D3354A1C00A6CE7D3C65BF61F3B45D81C75BBE8A0C3780CBEB6C5CCE34CCD76318017215ECED1C686224D322C3239A0E3ED6D007195207DB057125ABB40CCADE2ADA3C09ABA1F66AEFFC81F119EFA0828FA3D\nss = 70080E3BAAB3FA55E8A308E84FE9ABAE780BE8C09E211651F6EBF6053F8F264E\n\ncount = 22\nseed = E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F\ngenerateEntropy = d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb\nencapEntropyPreHash = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925\npk = 4C376BA98C3A0415A3BFB0AB42D0A3D68CB171109C5F83147C33ADDA2CB07C62A9025B44523B0AE4CB8A8BEA5E550B717CA6C8271997CFD6C5ED76AA44E43DA2A02D35610787F22966298FFBB45FD78A8D36EAB454675D6951A70472CAF06640BC1B97D6760E74B41C577855BC0756ABE528EB4894E8776F1E739DA45A9F84C9BF3C72B43262525B547F75176AB2E12D8EA808D3B0355766BD69D964EB3B450A96C835D7B238220FEBD62443B03985731333C54382D20200E30E4CBB2B607AC998F20DEF865BDF47CE78AC3DBC1ABE33245D6FA7583B31B6FE7B6EDE7A8EC776B20F7BBE7E376578F0933B761BB0952161123D61282CD6C80CDC8A85F9632ABA1A8EF5925E410BB80BEABC67735D07E4ABDD587827745A3220A24A7B3902416BEFAB3073C2CB1FA76FF04315B653B3E7C18343391F92015939829DABD0289B5AABC4CB5335D963AB842865BB7C38106EB1274ECCD0140B415901279E8719C0415517B5101394F78A48F565317909371A3154D291698B0BEDE17052F30786DC2D46E71EDC438C288CBD44445F993926BFF0A8CA1A033B656C2362A659EABBCF37B2CB5916940AA9B3E850E51039C08C8588347E1099A0D8380CCC4B8CD0C87218BC24F09126A82A3D530A75500254510AC765CC1DE612A4CEB14DB78A7141109F947B4329158F87E4C8B41A92AFCCC9EB749D66A71159DB90E7A36642636AF22CC0D541CE52DB7AB44BAF30560691A637C93193A11A00EFEC075289953FDC9DF3EC3390342AEE44C08D661632FB0303681E1F89CE1300B0C1A36E63E5A45886A4C76534FA78B87A75CF96AC66205C28766BA5EEF7062363C19091C61C543D5C1B8A547372515722EE515E8EF52BF8E089D93377E2C8458E626D3391953D658CDB05C7A40077F4E19DC0B132BE719014C12B0CC242466112E94809630B63FAD12C99D271DBD38E5AFA54C894542B940415354203A0C8A785AB94200EE0CB976991C642257D9AF6998B61BA27B236FDFAB86F834FB2D47CC0904B9D6ACD2F8311F0D4B8AD81A24F712D92272587220E8023A8BC13BD17572D38851778F319607752466CB0DE7C5C12103FAE4C57D953B96BE93262BA9CB05405A5D2A9E012B21A22A2EF33A385C898C80AA9663565B63241A1B206F3379ABE8262CFA49BA05C3B43E9485E60CD38D66EAED114EF81AFD66B2594BAA361D3C3B02069B1A164BC387632E24C82A91BE2CA390EB585E900173699A8B26B8916E52BD643645D3225DF38BA50A50EA013B4B2A86EE1F76278E27F5A4142F034004B567F309C52ACCA3C7530162ED744A67481CA338861CCC3E8331E1C67886023743719493CC3CAEA51438E28AC4EA06B906789A65220E3C7407C874C6322BE1F9B627386081753AD618A8DCC013395F20F5017AE2B57BA908617490460D5A67FAE2660A56C4C4D97BABDA0BAE0F494260877F7077AF2536B2CA46E297C61DD8422BBE515519210DABC02E7047B13F16607AC15E4950574C43BF8C39A2528ADDFA2782506635E5626967A1F30C02FA3442FA93250571A8173999A88DC27B43C476468A6A4739972DC1B68493413A2743B9B563283CC886916ECA5887796A4F833AAED6639B9D531EFE5CADF9225573A23664C9CEA086428DCD19FF40A06186A41FEC0723953781475F648\nsk = 818B55FA5AC30A81891F3A3643924B2B046FEB6765A61CC81C9059D1F82F6A0067A102825C88A530D15F0DD95F0B4742D29ABE7044C62D45A05BDAC46130305E3C3417D67F60B92EDEB6B2A398119AD160EE3CB0FB52144435A5BB5412C0512DC6121BF6E72D0F87A3834AB5338196FDC950A3CB1B7354C4E50369BD4364CEE9066A221DFCD580F1B914C0C335F547748BB19264B7879F206A9C610573B8676BD0BDFD777A2A0CA5EC891A1317C5289784DE114E84C53B983778BF8933805256C9A9BD05A11AF8F5AC271AC3F1E635EB9A8263C855BB230F58EA3B7E8287D76258AA57646B97560E593944C4CB3567A2C382A795C991F69BC2DF2CBA8837C9A3B58A9DAC5E4D84B50722A144737EA38B14BE51C41CC55C53340ED158AB4A0B0F0A2612962B89CC2AA8B29198F2E04B0F0CB586F271C6414F31A71A45ECCDA8C597C38415D262571BF0A7BFA17115E0C7731C70C2D01C492C85DE16C511102C5A96973C724F3B58B504EB65F56116AA7779B76B2554736D9D6176DFC6BA007A590A311D4B86A7A6251FFFE6086AB3319DB48C4DCB91FE680F45A9480241242E4AC9861B62860837CC813FADF00751C8021F7A1C4D7A1E5F13BC3E8462F372CD7498197D172EFF98B1F8BBC37974B025295A80E3525D282FBA8467F8079D78FA6068E23BDBB3349A31506E474EA228C3927A554D7747BD3621A0343CB155BC786075C3015C3692C0FC65B194A12152A14153A03D5147B0CDB423A3B50ED6461813F9AE1FD63AB7A53031DAC2D0F87CACD1CB81461C8C08BF367C4CCAE7626343469D417ACC705546293498035195240387FB1F2E7C005DE000E530B9E21CC7DBE463E7D24ADEAC1127026843B87CF6FC1BB94674399B0636506B1ACAB72F623ADEF866F883762B5B4509CBB2BE142C5C550046E10D29FA431F9B7D977253928A8D2D4C33ADD899AD736B40CB4FC656BE02D90BF8D393D632A1AB509C432511F1CA16B01139CB0627F6503BBA75440414AF97A04BC5239567C060EF94C9BA7221D4612EAA640BDBB8B72E32A4668401AA79421BA68115261A8D94878C90A0468510B247968B7463FF49A0578044C5E9147F0739F6A17B18828BDCF56966B1CAA125CDE7BA6DCE939E56D350E896CA6219A6B8947E3909361754593FB8A85E742CACB74E1D45704FA4CFC91C142453BA5C08558DE1321AD6A6A2804769A0BF69770A1264BA5148B40A3A9BE3C513A382CFA3C244C9A138EA9CB8DA7627B350CFF87AB064A079876893D893250EF59F369C41F9EA40DAA5A5984C19CE06CF9BEC2947932133A4157BB8CC3C72A1FD25715962A9C88026C018B7202885224019466540C9EB5482A87E665157BE7722BC64133C827C20B97D9E692342F23FDB1B75AB2CCB6FA5973820B92EF1BB45C2B5ED1330C1417CCFB39FC6301B8A749D3613B3803A6ABBA20990151305CB32BA6A5B558265C2E27D8D49AEF3E91819920DB20360355919D5F641922233A1C24C0045172CB10F9564A029F07578A48A4D215248F3AC7A912EF8E56E366B03C567AB978C750D85454C68A5806AC38B7B3395F19FE78A001C5867D3E90E9B54BD63954761AB7F4A57B1FA32B65F285742C1207AA0684C376BA98C3A0415A3BFB0AB42D0A3D68CB171109C5F83147C33ADDA2CB07C62A9025B44523B0AE4CB8A8BEA5E550B717CA6C8271997CFD6C5ED76AA44E43DA2A02D35610787F22966298FFBB45FD78A8D36EAB454675D6951A70472CAF06640BC1B97D6760E74B41C577855BC0756ABE528EB4894E8776F1E739DA45A9F84C9BF3C72B43262525B547F75176AB2E12D8EA808D3B0355766BD69D964EB3B450A96C835D7B238220FEBD62443B03985731333C54382D20200E30E4CBB2B607AC998F20DEF865BDF47CE78AC3DBC1ABE33245D6FA7583B31B6FE7B6EDE7A8EC776B20F7BBE7E376578F0933B761BB0952161123D61282CD6C80CDC8A85F9632ABA1A8EF5925E410BB80BEABC67735D07E4ABDD587827745A3220A24A7B3902416BEFAB3073C2CB1FA76FF04315B653B3E7C18343391F92015939829DABD0289B5AABC4CB5335D963AB842865BB7C38106EB1274ECCD0140B415901279E8719C0415517B5101394F78A48F565317909371A3154D291698B0BEDE17052", + "F30786DC2D46E71EDC438C288CBD44445F993926BFF0A8CA1A033B656C2362A659EABBCF37B2CB5916940AA9B3E850E51039C08C8588347E1099A0D8380CCC4B8CD0C87218BC24F09126A82A3D530A75500254510AC765CC1DE612A4CEB14DB78A7141109F947B4329158F87E4C8B41A92AFCCC9EB749D66A71159DB90E7A36642636AF22CC0D541CE52DB7AB44BAF30560691A637C93193A11A00EFEC075289953FDC9DF3EC3390342AEE44C08D661632FB0303681E1F89CE1300B0C1A36E63E5A45886A4C76534FA78B87A75CF96AC66205C28766BA5EEF7062363C19091C61C543D5C1B8A547372515722EE515E8EF52BF8E089D93377E2C8458E626D3391953D658CDB05C7A40077F4E19DC0B132BE719014C12B0CC242466112E94809630B63FAD12C99D271DBD38E5AFA54C894542B940415354203A0C8A785AB94200EE0CB976991C642257D9AF6998B61BA27B236FDFAB86F834FB2D47CC0904B9D6ACD2F8311F0D4B8AD81A24F712D92272587220E8023A8BC13BD17572D38851778F319607752466CB0DE7C5C12103FAE4C57D953B96BE93262BA9CB05405A5D2A9E012B21A22A2EF33A385C898C80AA9663565B63241A1B206F3379ABE8262CFA49BA05C3B43E9485E60CD38D66EAED114EF81AFD66B2594BAA361D3C3B02069B1A164BC387632E24C82A91BE2CA390EB585E900173699A8B26B8916E52BD643645D3225DF38BA50A50EA013B4B2A86EE1F76278E27F5A4142F034004B567F309C52ACCA3C7530162ED744A67481CA338861CCC3E8331E1C67886023743719493CC3CAEA51438E28AC4EA06B906789A65220E3C7407C874C6322BE1F9B627386081753AD618A8DCC013395F20F5017AE2B57BA908617490460D5A67FAE2660A56C4C4D97BABDA0BAE0F494260877F7077AF2536B2CA46E297C61DD8422BBE515519210DABC02E7047B13F16607AC15E4950574C43BF8C39A2528ADDFA2782506635E5626967A1F30C02FA3442FA93250571A8173999A88DC27B43C476468A6A4739972DC1B68493413A2743B9B563283CC886916ECA5887796A4F833AAED6639B9D531EFE5CADF9225573A23664C9CEA086428DCD19FF40A06186A41FEC0723953781475F648E6EEC2929FEAC2A86C9DACFA6214E2E353FDA2D547C3829F5678025FF8418A1A76EAE84D11C4528382828F7A689A0D5CFF87B8CA0BBA97FEACB39B935A8788CB\nct = A91F16FAFFAD2674D7E14B4CA55F230D862469E3FD04E9FFBAD5683615ADE14CCE1B9C911004C7B3D9B934A6C9294544D6CD1D3B97FDAC0D5BEFB7303F349FA70739A9C9017A0EBA508367B01D14733BB3C7DC8334EB2177FC553B7423BC340412E57BFBFC622E45D32E2715C37CDF1C856173CB214673A4CC53C79AFCFE81535D66F2A60F1272ADA087AEBD39E86E820CEA4D94E9271A1962127E4B9FC49FA67F9F3BD931373BF8B10B813917A339848AEE8DD118182E5C2D9CAE2C3FC1421474B78C108804AB7B3B546F46B7862D65BB28D33E260CAEDC91583EFB84B0535BD17C6CB4461E05253945700716E1C40CB829E729136E5073B0B86364934E26F25BABBE1D1F1F0D9E625DF872E6C136832E1D4CCEE3EC60126ED28841BB39A390A6F9289B4878224E3E857B1BECB231099822F337EE5A69577D3522174F7FB4E6B539CAA67734ED07BD8F73ABE46EFB903B5B9965FB414720CE5A8BB43DC13D441D4C62F10D4AFD7FC574DC802E15156C7FC4C76551C11CE3D2C7ADEFBA4ABD98586577BF0A9B54B0A433093B9AF348AF3C5F8E4FEF6C07C0A0DE1866F4BA1244DC4B815909FBD5397F0872079DEF58563D5E044066D898A9D738D8E5F4979980ADA72855E3C8994BE26C8670B8A4ECFCCCEA8809AF9B692FA184376C739A99CB46A050C825DF16039B92AFCE8D9F8894895A189BB544130A11096ABB902EA8924A13C81E00C7927C0D28B4EAD8E859CEC719FE9C914B0DDE9B36AB400135AD3A21382FCFAAD250A6609B971867A5EECAFF42A8AE051BCE111C4A154F15C3FAFCD92657A65F179E0FB050B2E4DB6E8CECAAAC4DE222FEF1B502B55F327A0E2E17059073E03C1AFB260B2242BC90BFC0ED6A035BCC5C8A56C36CAB2F12AB315F174750B6CA4FC7E9C1734B652D3FD97A1EF442B7BA7353FAF2BAA855EBFA3E329A4901D3B82A23B49513550D432D29B4098D31874E9772CEC94B208AC079ACCD959A4D71979B57A7AD48B7CA2E06545CC85293F7ED2F6CF474DBBAA31EFE9F09B2191076DB3B691E3CC790E35D249D2F37B3AA045EEE5D2D15E953BFA0A7AD6442D87C3D51F319A0E9B69F0D6C1869216348A033ED2331D9AE51E2F5BD0491EC12739BB567436F5F1D425FAA076565D868E7BA2E60C30E61C3DC9158C8245EA97CA49C5697A721FB0CC21C069D1064BAB42B1FAEB337FEC21416FA7456743A7FF7D523B3455035B590B2CB39ADAD6A290723837EC393D468721DBD5FCC116022F7DF742353863675DB7D83EB7AE2E71CDE3623B0ABE8C7BC8AA50C5E875F158802E3E3B115A3BB4728E111E09CA5226AACD911C70B737D7839C9FA2393734D06AC51E1DC80166ED17BA95A10B20E65494289598CA8EBFD57FE8290F7AB7CA8942FBEEB8D017FE52823F2BB7263C2C029E445375B0523CA565BE10EC0C7BBCC14EEB49AB97A382E315495F496672F8A8B293622AF02C74D4DB911C735EA9EAD60ED4427DC68E45E8449C0196355A593E6B84E42717F32C9ED2404E72B508F447E87\nss = F804333E26C5981EB749E8E9FECBE8F8886E493CF8013A6760A1BF5D4A37200E\n\ncount = 23\nseed = FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D\ngenerateEntropy = 5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552\nencapEntropyPreHash = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a\npk = C8735813347C3C7C05F81A176264A5FF791D9801AF88047574008C870635457126B4069071242C24DC0977A8C13D43B889D27F08984D9EA657D241922BB12AA28A1408825B02663B970778BF669D585A975ABBA6BCF8513C11BC73A0C33897991C3428A5CB4DFED155B9A2909E6597DD8CAC1AD62F9CFBCB27088860512859761885C5B6C5D89FD6B18F9E324EE8F80B4C507626762A22F4CB7F4527527896AAA97A69B8AA4FB09B16CBAFD73A667E9CB085F7CA36067D4F740694E6C83C671071762FBBA26A640C86422197894CAF01B0AF66960651998073BA7FCCD3189148187BA22DD2661262766399A6B8BB943AEDC590FA048816D1B9D827CA80935D30E1830C8115B18B754F20ACD7A376272C119CC8210C9AA112D604B2022326F51AD674AA1579C081F12DF04A9A2B4571FC1C21A8A4AE2C701EB2EBB0CE65CD2FC22FEE530FB3DAA6D82B3D46E33E9C918F6D33ABAEC34F45391245453EF4D128C4C068227A6511800D69F6A31A1421E2D322F897145961ABEA377C9393ACBFA72AB3C3AAF7F04DDAD50077E7C36AC46E083075265C58DB4B7B47DA253B8A9361C08A1248B53098C6B797622E228939F110ECE18C02AC613E00B624C61EFF4524F92C1EA632553D9B90CD886FD2C364B25C877459BA6DE0AC8CC2A8B0F2C6D71A051F8727C2892D1934857EB995A8D728B9739872EA472E6602F2C39484D290109BA924933D6AE52C30EB4D80935F0D2C87D4DABF07582CAE3C2F21692F0825C079EA6700065A6086B197582B76CAC90A58451D7479965475AC8A6AF662C7D23055C404246264C97BD23D280B43CDEB59BE0CB31E04474CACC4A1453FA10A9E1E4050F97CA3E9AB31E561AB18CB3AF721570380023A9349ED6BBC5DF66BB243928DD3A4B5E113A0F99725C9C8BF673818B89030DB28EDC536C9620A1625C8A647BD3D7055039753E11C4B1BE3AE79EB565E6367690B5338C554CFDA9369E9B1BA75651A0234D2325ED82369BCD415089692547B325EF28189482714C80DCDC5BFF72A6152B70AC2F16707C63A42830DD6CB88EE646D882338D3DCB202408FC5210C71D1A8BA02B8C2AB7E06E43CCD85CE39A215E67914369C749C3978778592D9E34B7671283DC787446B5B70A32C4C1CA4613B01A5D0BFE55016B897130D1BCFB49BB5F08C5DF9F15B6D531B06C53A389500675AAFCA9700FBC310FFF968300360AB631AD95649F0BB47E55B90B2593D9A60BB0477BA848C0DB9F8BF6C774CF8348C65695B31B921E4439E976B4306A47069C25E4A7515866C0BD77B44C7881121025CD2F28430383600E4BA0BD28074B7BBF2A2A3BD62A73BA240D644AB1F89ACE0C8A83AE62F642237DE265765458D6744273E4372ADD9CF5215BD39FA516575BAD72034288CA3E0D3BE57DBC7ADA731F5F13FC0252BC5A9213F502C342A451B933D3060A2AD8A9C13013E3D93455327C187547809FA57FAA299A843A251F8368A715508C32AA57A42F9551520433F9675ADD0359C5997C341464264986FCF67261D16B7A6989EE33730754A2CA0F66B6C98CB421C8E4B36002561B1A5550B93B144D5552AFEE236357C8093932829F864963159A8E7CA992B8FAE006190B55C6A4FC08AD10190D2A178865ABFA35607E1A88B47EC8EA71B102D7F1567BED46A\nsk = 91C087E623025864C3C5D9049E865C6226CDD2B39F8A1578EB69A864CCB2FA155DB32702DEF5B50E973495997E18C6C21756568802A4BBB86C5018016FCB0655B09E6A4B39A8BA2D70E32BBB255BDD296C998A21F5716D49968DD02A9C4F4CB9DC72C874C232011225F8E8840F7589C2D285C1E72C8588C0A33A502A385D0527186CC6809185408E9C7FE6262725528A439332F93A5BA2943E6DD7B30D79A25939A4C0802BF57C755A5A0EBBDC8390F8AEE407A541C46CB1530FE1642215556D20AB942DDBCD1627826648ACC3FA1367DB0B45075470196B46697D9EC6974F477EDA553F80B701E853398C69A6E4970A746534928631E6B811E533A4D1E89CDD6969BFE0C861D2CEC3E16D0035BB50573ED61B5DBD45C8C5B223CEF4266C5A6DAF104949EABD27D3319BF12A7AAA4E5F636732B28E902A1098972977D98C00A267225B84AF1C8C404A52472B8D1A793E370B17A9935EE590331256620E302E390474DD6A17D17A50291B6BB940BC43F89FDD22109A72C8ECF9ACB1E67EF6A423396225E6ACBFF2880C35673135C5183BA37DF968330CE992DAE04E9455267A195A41893194BC51C67393251A11ED3C0829D99A3D23CEAA387208E00974E73178459BDA539BCBE89F5EEB05EE21BE3B1159018A3262120C21D4972ABA1A1350231D3A646BA70FA5B641EBEA1B130470A5EC7C40627035B03D15696BE1313B458CC9AC8460CF281A6976A9D2CCAEB9FB157300B4289A55ECA386D3D8A7D16C21102AACF361578010042C3A6397E2CB2EA5224141A1D451B38FAC14D7B64BD7B72DB17408B0A8906CEC108BB926DF54299261B6B5C6A636B395ACB651CE6B6018EA9C92C1525DE1624B5570F7000466CC09A909CF36F34687265B61DB6BF2882514705FB37346385CBF4DF33B98686E0189BDDEA7268F598DB1B6CC7B32792D5546E242A807E760ECE7080392823004453048C6F743B87C1670C6D10E3001008A24590294BC9AC899BD588197530FEF9C2B85AC66520A195C77A7AFF61672C8CB74", + "C07D43A2BAB7A764E750663091A005C9AF8CC4B55D502169D4293E79B365F60085B1CC2F4900541588819B5EDCAA3B80253178639F63A3091701C7E7B04E95435BDD2114BBD3ABEFB23355591B0FF102BC94B56B338083B82328712733F2762C5B1D0845073CB3B46AA28CE2CB282A4347F2118A6E062D7E8524147545488A01378A853D489C03EB0C6527307FB0CA5F7AAB6C328438D33CEDC10733AB8A68C7AB88E0B06FC51C92C557FD59488B6245796B7DC291728121BC7643AA5D56C483186CB55086D7E8654691CD5EB97580F0A553A2613C486C0B9566A6F05F9D2B82B57345AEEC1368CC126AC53B9E794BE471C16A498B743C1848A14D53478FC341A0ADA42BC2E0717FB6965737876468515195050D64079D624DA1596F88819FDF95653B8217F9885D151821A9529420AC95DD928FC429674025882C9758226194615304F1F5CAAA456182C1BB11F0A02B6C758EEC4AB6441879A42450A024559697C4494D8AAC2F7045342234CD8081C0077C9232E66838460EA26274329988AF3A82B898C4EFB033FF4101F302A898E84BCEDCC45E369CD1BB7F3517280D6655C8735813347C3C7C05F81A176264A5FF791D9801AF88047574008C870635457126B4069071242C24DC0977A8C13D43B889D27F08984D9EA657D241922BB12AA28A1408825B02663B970778BF669D585A975ABBA6BCF8513C11BC73A0C33897991C3428A5CB4DFED155B9A2909E6597DD8CAC1AD62F9CFBCB27088860512859761885C5B6C5D89FD6B18F9E324EE8F80B4C507626762A22F4CB7F4527527896AAA97A69B8AA4FB09B16CBAFD73A667E9CB085F7CA36067D4F740694E6C83C671071762FBBA26A640C86422197894CAF01B0AF66960651998073BA7FCCD3189148187BA22DD2661262766399A6B8BB943AEDC590FA048816D1B9D827CA80935D30E1830C8115B18B754F20ACD7A376272C119CC8210C9AA112D604B2022326F51AD674AA1579C081F12DF04A9A2B4571FC1C21A8A4AE2C701EB2EBB0CE65CD2FC22FEE530FB3DAA6D82B3D46E33E9C918F6D33ABAEC34F45391245453EF4D128C4C068227A6511800D69F6A31A1421E2D322F897145961ABEA377C9393ACBFA72AB3C3AAF7F04DDAD50077E7C36AC46E083075265C58DB4B7B47DA253B8A9361C08A1248B53098C6B797622E228939F110ECE18C02AC613E00B624C61EFF4524F92C1EA632553D9B90CD886FD2C364B25C877459BA6DE0AC8CC2A8B0F2C6D71A051F8727C2892D1934857EB995A8D728B9739872EA472E6602F2C39484D290109BA924933D6AE52C30EB4D80935F0D2C87D4DABF07582CAE3C2F21692F0825C079EA6700065A6086B197582B76CAC90A58451D7479965475AC8A6AF662C7D23055C404246264C97BD23D280B43CDEB59BE0CB31E04474CACC4A1453FA10A9E1E4050F97CA3E9AB31E561AB18CB3AF721570380023A9349ED6BBC5DF66BB243928DD3A4B5E113A0F99725C9C8BF673818B89030DB28EDC536C9620A1625C8A647BD3D7055039753E11C4B1BE3AE79EB565E6367690B5338C554CFDA9369E9B1BA75651A0234D2325ED82369BCD415089692547B325EF28189482714C80DCDC5BFF72A6152B70AC2F16707C63A42830DD6CB88EE646D882338D3DCB202408FC5210C71D1A8BA02B8C2AB7E06E43CCD85CE39A215E67914369C749C3978778592D9E34B7671283DC787446B5B70A32C4C1CA4613B01A5D0BFE55016B897130D1BCFB49BB5F08C5DF9F15B6D531B06C53A389500675AAFCA9700FBC310FFF968300360AB631AD95649F0BB47E55B90B2593D9A60BB0477BA848C0DB9F8BF6C774CF8348C65695B31B921E4439E976B4306A47069C25E4A7515866C0BD77B44C7881121025CD2F28430383600E4BA0BD28074B7BBF2A2A3BD62A73BA240D644AB1F89ACE0C8A83AE62F642237DE265765458D6744273E4372ADD9CF5215BD39FA516575BAD72034288CA3E0D3BE57DBC7ADA731F5F13FC0252BC5A9213F502C342A451B933D3060A2AD8A9C13013E3D93455327C187547809FA57FAA299A843A251F8368A715508C32AA57A42F9551520433F9675ADD0359C5997C341464264986FCF67261D16B7A6989EE33730754A2CA0F66B6C98CB421C8E4B36002561B1A5550B93B144D5552AFEE236357C8093932829F864963159A8E7CA992B8FAE006190B55C6A4FC08AD10190D2A178865ABFA35607E1A88B47EC8EA71B102D7F1567BED46AC74F3B7FA6E2EF8CE99508C89CF3C71D666AB065A262581A5FB01B2C9B9444FAFC9EBBE336DC464489861DB8253606971BD0A9008A433ED17752D04023781552\nct = EEDF2D6926813F52F9128C8EC075ED6B5D0B8B0BBEF802E11D302B47A3E53FFB33C246E79CEC593AED58A77B29C69DAC0E76B0A2B69C596ACA154034AEDF3DE6BEC9F7A0A3D1EF7B4E05EFB0789670E0575FD82A042E35EA81B9AF40546B266B42828439E1BAA4A58D3DBBEB1935578A5D6556F48A839311218F47B18E99CF20E406D968F446C575128E4AEFA43943F9804B6AAFE944AA03682F5FCA2DB078B6CFF32834828FBF0DAD0DDCB41D20AC649A65E009666644B0D3337FBF8D0CE4A95BCDB22AA816BC8037F5DD83AD82CF49E2A9089B778691EFBD5688B2F544CD67D419B6F230CC008FB0AB871C2825EA97EE31D4D72F2970D95276E5F3E156021C595CF1D522B8AB8CD3AE352519A3C733F7EB6A35564D8722725E5CAFB40CD178E3C680F6D531FDF024C0253BD0B9F2613662A35673F68BD1A9C322229C5804E594B7A5BF0EF05E10DA09DDA2AE2CAF143279A60586E9FBC920CF6ADE5B03842EB71BD4F38107C065642F0D80CD10BB866C9C2E422B6B506277C7F87E4A2957A0AF81C276A3FA84FDCAF11C50D708C798B1B136895FE50528D14DF38E74B173823750F7C1EFD787402F9C67D5CDA236AF22D2E189CCE0AFDCC1B6F96163C2C4DD65891E2E39683F5472FDADBD3D4EDF0AC320FD157C0BA236E98B6002E58B42AB9010E27028625D9DBF17EB8DE52AE9928C6390D7EAD758E62C21367AA2D24F07302C6FBA6B5E220467EF632CB331353F62D13C385CCBAE56DCD7B5C7A915855F24C41107B3E512572C31FF5CA29DD7CAC21A831EC1076D7DEBEAE0E51471DABEC57758EAA84903CFCB4710188287C07E5E87FF678D5CE229EDC40F532983FFBDFABFDB0DC4B14C74170B4A2B575C1E929C9466633FB78DD1CF72A42EE3D9BA4E0366FEEA959DD1056E38E18FA56B7B4C6AD7722048D8F3E639823BF26CE29333E60088B7C7C097229D784ABD1326B2C65DF4143CE50579BE5DF3F66FFA725346F0508EC94A4611AD088DB7C3F7825D5A8D0C7CF5E90FC9AAC1000D62F3366CE0EC54836FFBAE061A5CEFD72946D356FFEC1D2047B7F269ECE849A1473E83AC86BBC3F705C0980F380FAEDE71D5AA64A64C0F3372AA3B0F03B4850E1A1D17715D0B546A0D1959F739D520E330627BFEB52519B209255DCC60D6C7F25D0A256E15CF932FC98A392FC390CAF61FD3855F2E9D871E163E08E9D70A895BFE95EDF93432B98E330C7B228708DC2947B13FB3757A9BE1BDEDD859EFE809650D92BEE40D6C4029AC4B41C8F55188E56BFCB5EF665A11FCF62ACEDBC0AD627B46ACBB9444725AAD4A6DC8EB45AC1099F48E451CBEF50C71E10149D91467BB04582CBF7B7B3F26899E22DB449FD5C53DBFF4BCEF470F622C50F133611D7F3F9F8EEE66F1142CC8218580BB42F84AA7E6083C3EBC0DF6571A0425B2DCE8D1F83A5A2C97F055479DED547B8836B7BEDE8177818EAA65CB9286172D9C9E5AC9C7F01AAC5421F6826147DD0EFBCFD92BB4156B03D2B3AD62A0EBBD28B879FE5E6F43881000C521\nss = EB9B44605E6B8FF3A59E567C1C16C6F96B6079F8E2C4D70F706D30DF82F09902\n\ncount = 24\nseed = 7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813\ngenerateEntropy = 293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558\nencapEntropyPreHash = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60\npk = 04A592C364AACB2C89689106ABA29029C58DDF7050A2C78787358571AA506570288E747A4204C43E8C6020AA3E2D77B36C3440A618C55F3CAE6D43B979786E6A181D4107CB723BB6D0729CE3EB98E7A979CAEA9508563D5A0B7A7BA55B8985B71F3C489B370D37A66CE048A9DD27AD17B38C66880491985B2AF8916C547E9C6CB16B506170F29304C4393E8274EE254A3F13C6B0E31105442BF92799F21774BE9A0F64970E6AB581626115A1AA3EE4DA7936504D036B75BE6046E5778F58CABA93F8640BDB24982C17BA3445F2AB983B685644B596EF66ACF739039AD0A3CD61BB80B000F7E8BF53F60EBE235C0BF22C7873AECC6B3AE2F3B2CC3BB47D1B88423A188393C43C4999C32A886807CC4262BCD5A588C5E1BF8ED6A6EA9910C19A6042679926F314E7C7C85BF550482735E7FA088C857AC1578560A1A2F7E831223CBDE33A46632B7E24D400A82A8C7307C23D6CA25075B58E727673D7CB5554042CFB9B7F95B11A55A9FD63B1B9F0B60F6931A0BA1AD28B485753446B0005E8710D7189BF438407B8BA36A1687A48E550FA37CF4C6B591AFCB0AF6B8D2EA5A97B6C1729E7AE22E28F2082A5E653B5BABB0D147A8748F2606DDCC7847C24F0D32771B910CCBA85BEFCBD2B89C5035B2062E6B9BB40828902B82E12B752D48D52B7A6599AC014731E8DA091CB30186C849B61954DFF867899E5BF27428229376AC7D97FA03996160964ABE56D3D0278F9F91FEC6BC821FC822949AD5EC8A9D728B95B19052AD9442FA0527B3935F4697CFA3C7413CA2E81B32A57F69479E89760A46D710032EFBB662F9467F0D03C806B619B9228135076FA235D502230E56669E2354C1B412ECFD01A429B5C76B17AE2AB99C73B4110957AA38C22C8FA39C00261C78AA571B953D868690761655FF700803A477917AC8A6105CBFC220A30A0CC1466D7598B2058B3899C567A71A66D5C9DA75085686AA4AD4015100360C6102C84C336C13B229FF599DEE4CB2C90A1516682330722DA110F42F7C0A4F23A2089ADD65438DC66246671BE41E7766641B4C9139777E08CB4D5B953E602931A7DB3E1CE70D765516242AE8987454B898F19C5103BAD39207BB16771B5D4191ABBBDCA9B5BEA711081CA6521149B60975E02CC2250A355897960A8E203BA148F8BE76452420D2134B607976F7809CE97597D8CA57337FBBD6748C03227607FA082195B49753C43047B95A020C7D195B01DD3CDDC4C091916C37E447ACB606F2D232C37C9871831C1FB9A8D00717762F18E62E7995A7393E0A82617DA4674078D8F10065A28649E53377A88BB0F996D84FC83E9496564344D65B73AB96C4E887107D6C14488E604DFA15E55004FDA8B65AE19006EA7C8A7471B354A4E746703D5C79857A02EC222B78B966ECF161D97BA7CF39B37FE173485A0156C3712A6ECB14E629899DA9163709B672A243D1B87E15C0AD611419D85522252BB5A02AB725CB5EAEA5BDA73976D534A881B8C32C5328D117306FC5217AAB89CF51C6174489AD241D1CB261D449F24A235FCD46FC19A8D14A4281906236738A060061A494947BD91604431B1A2871080616E", + "E2E915863B2BF2D9CD86743B0CC12A5D21C6C745B34247C17F9447579FCB9BD38AF3B64CC94782E299E1D98E68F8BCEFA20D1E8DB8552516\nsk = 817471E55466B5BABF92A2AD879C9C951BA60D230ADD630984B2528F9AA07FF755D7D79A2F9AB53D8986FD90895D5401DD97AD3F7A922516279B5858F2087E6491B7BC42B8A52A5952F23622D5603A0A3152990CFD6AB9CD863345D8BE5E295C06B79332B0AC89282E61E5534FE0AAC95ACA140398B64175235B94417B8799A4B6D6933A8B815BFBDCCF886664E7B8C5CB0B999BDCB2BDB288D569666C421E2A950D198158C0D36CED3A74D9032AB7A2B9F276BE025296A773266E516826480E520B844EB69710120373A94705F9030CA200A7F85A94DB1F55D46081570925A476099C3EBDB32C532A6D8F16BE4DE6416D0C30D450808CD3C08131A92551985B92255282BE6087703F182156A13CD144ACA3924FD15492DFD253EE5C9E78853590930521E843A0E37A26994197B3161EE1A60861C344720286B6566796787B05CB8FD76A419C364F1830FE2BCD3A2970E2DAC1DBBB3803F8053591B29BF64C2DC660EA9938200738E2C0C318B77FF86749C43C72F9667D80D462D549BDFEA30CB0D9641B29308A461DF72914B4B40213B62E68B161F83224C1A45472B5464F97C6D6371C69CA0D520426DB8C1E938A934D50AE0B03BE706B74CB8C674EA955A4D8AE1F6C0B56263041FCA1871A5799921C45D9BBF13C01F0A9C5D973086B33ACF923A2721C8B2FA7B058BB2E64F43BD80260B6BB19F26A4F55D53E7CCB1BFE3AA424976132C3B4B3A00908E722557A3657D285C8580EF45B76A207CB31A71402BA1EF280048378B80DC3312F78A74065B2DC873B22D37990E465E425B992722A25009A93A7A005D91B9460AB7C2336BD303883A151E829234C964265E42FBF8252CB89858D590CF0830E59C54021B83DA94884A173BE6BC454AD5A719252BEB52A4F7544A7FBC03CE9091E9ACC0568306E5BEC2ED942B39A8455FA341B84571AC3FCA43C14563F91395D117AB021C8F141A4EC7364BA4ABDD8896BC6B281C751A66C767AC960AB52058335E14E7FD8A4E1D44DE2670F9BBC67F682A0657530EBA11C31381897D989BD392FAE02D0AFBAA5AFA1748A80847AF4B326F970C6161E15B212A1C66003A4317348374E66B29FE87F36D01AF5F1C75BE11BFEA21DD8626765C46F0C153D0555B419227D50DA5232810D8517B1A5E4147A52AD07012D8DA23829F39A40C70D565937C58A11B1A25B27C8207246C4E1B40230E39E4F089D43D562EF954F332B7EA6B36EA28A9D26EB251AB562C0E44BD238874E93A4D3B900A4B2B08A0B68C2B82C0CB56325548DA3316279672913D2021D742C3619823C4391E64112B5B77E8D707F9C1A37D3464CD5F96543F720A0CC6C9631458CD9CEDEA7B6FCAA76D1E60C44F74B986A772CF593AE712214E21179519C39FA533A724FE8177EA59B1123E831E1DC561543A7E559697572157B60499C4C615D02099D34B0738581061A85B2DCAAF13556208B3E5AF388392490FC338DBC55BBF7D25F49F61BD7363CBE3841AAFAB88524B0CA3381F5B22DC84C6A112979C3C39E45157C0749C04B022F83F53733A21E1F1842E0E72F78C6AE1E337B53215AE8563B16D99EBD6225766185A0D92F9A28BBF4E2B444B7C8225148F601D014BBB8839B4B04A592C364AACB2C89689106ABA29029C58DDF7050A2C78787358571AA506570288E747A4204C43E8C6020AA3E2D77B36C3440A618C55F3CAE6D43B979786E6A181D4107CB723BB6D0729CE3EB98E7A979CAEA9508563D5A0B7A7BA55B8985B71F3C489B370D37A66CE048A9DD27AD17B38C66880491985B2AF8916C547E9C6CB16B506170F29304C4393E8274EE254A3F13C6B0E31105442BF92799F21774BE9A0F64970E6AB581626115A1AA3EE4DA7936504D036B75BE6046E5778F58CABA93F8640BDB24982C17BA3445F2AB983B685644B596EF66ACF739039AD0A3CD61BB80B000F7E8BF53F60EBE235C0BF22C7873AECC6B3AE2F3B2CC3BB47D1B88423A188393C43C4999C32A886807CC4262BCD5A588C5E1BF8ED6A6EA9910C19A6042679926F314E7C7C85BF550482735E7FA088C857AC1578560A1A2F7E831223CBDE33A46632B7E24D400A82A8C7307C23D6CA25075B58E727673D7CB5554042CFB9B7F95B11A55A9FD63B1B9F0B60F6931A0BA1AD28B485753446B0005E8710D7189BF438407B8BA36A1687A48E550FA37CF4C6B591AFCB0AF6B8D2EA5A97B6C1729E7AE22E28F2082A5E653B5BABB0D147A8748F2606DDCC7847C24F0D32771B910CCBA85BEFCBD2B89C5035B2062E6B9BB40828902B82E12B752D48D52B7A6599AC014731E8DA091CB30186C849B61954DFF867899E5BF27428229376AC7D97FA03996160964ABE56D3D0278F9F91FEC6BC821FC822949AD5EC8A9D728B95B19052AD9442FA0527B3935F4697CFA3C7413CA2E81B32A57F69479E89760A46D710032EFBB662F9467F0D03C806B619B9228135076FA235D502230E56669E2354C1B412ECFD01A429B5C76B17AE2AB99C73B4110957AA38C22C8FA39C00261C78AA571B953D868690761655FF700803A477917AC8A6105CBFC220A30A0CC1466D7598B2058B3899C567A71A66D5C9DA75085686AA4AD4015100360C6102C84C336C13B229FF599DEE4CB2C90A1516682330722DA110F42F7C0A4F23A2089ADD65438DC66246671BE41E7766641B4C9139777E08CB4D5B953E602931A7DB3E1CE70D765516242AE8987454B898F19C5103BAD39207BB16771B5D4191ABBBDCA9B5BEA711081CA6521149B60975E02CC2250A355897960A8E203BA148F8BE76452420D2134B607976F7809CE97597D8CA57337FBBD6748C03227607FA082195B49753C43047B95A020C7D195B01DD3CDDC4C091916C37E447ACB606F2D232C37C9871831C1FB9A8D00717762F18E62E7995A7393E0A82617DA4674078D8F10065A28649E53377A88BB0F996D84FC83E9496564344D65B73AB96C4E887107D6C14488E604DFA15E55004FDA8B65AE19006EA7C8A7471B354A4E746703D5C79857A02EC222B78B966ECF161D97BA7CF39B37FE173485A0156C3712A6ECB14E629899DA9163709B672A243D1B87E15C0AD611419D85522252BB5A02AB725CB5EAEA5BDA73976D534A881B8C32C5328D117306FC5217AAB89CF51C6174489AD241D1CB261D449F24A235FCD46FC19A8D14A4281906236738A060061A494947BD91604431B1A2871080616EE2E915863B2BF2D9CD86743B0CC12A5D21C6C745B34247C17F9447579FCB9BD38AF3B64CC94782E299E1D98E68F8BCEFA20D1E8DB85525167378EF967195C977D43A50D03205044006715A6A8A8263D717F40170B49E6BD0FF8563038AAD865A817CAB9CE98846BA75BE9363718ECF5FEA538AEA90B2A558\nct = B36A4CFD44E71ACB92C3E25C36178609188A91E88AE7096874ABCA6C47E37ADF762D028541985915FFB85F3417B024C47B9C0C2BBF682E76C04F6B69EFAB7E2B4DD0B1E72E9408BBB61C0200272F02A8DE1E7ACAAF9E6A7EF4A4C54C224CB35C7782A503C0DA7577D4696C491870ED05F930E0E93C1A16441B603E76E125AAB09BF1EE9152158C9BE7AACAE8688BA2FCCB23E5932A818EE089566F8D0A3EFE3E59AB73F73972679215710E92235219692F27FCDF08699E5D1AE5CC07F9508512EFAAEBB86D86E29C6368184C7B4EDFA14901274EB3E19E0D3B542550F03D3E8CB752376FB9A23E467C4DD8062ED6FB10B53433A9A122F52621D4138AF03F48D3CCD10F701C33D0324A3341595433215E00AC76959255332DC35EE687045FF208ADD581F3AD9BDB7C7D435954CB437F995EF3BF22C0A475979D97BE46A91F9C3934170505037A79B29112A2D3F3AFBDA3188BC43E3C3B746647E8D722455D0844957557B355F424AF2909E46B9DDC68F4B287CF7CABDFB703D92DEA065623E9A3B7F4622E7C5365C04D667D04D172FC2E9E82A2A526441EA71B524DCEF1844746B06CBF7D083C09A020268F8FBEB92491B8556813781F74F32985267CD7457619FFE986AF32254F5538329904CFD8E438C248FB005A085B81448C45FF17BA45223E2B47246FB6B1B4A2444505FB372388ED77F4A8CE7AA2B9145E2CBD7DA00663E58300C919AB354C77E29A276E2D6DFF26594DACB12F56562447BADD8DEC8476F56567A65C44B791BED29E50AFDCE15FCCF57A5531D7614ECFE51AF936F6E4182B281B1B39DA59C20B3B0807A770DE434A8B72BEBA95D2FDFBF08AB29DE3E1C417DA199F98EADB3EAD1F25B40762D7E7487A3DA02E3072E0A15A33DBEDB5209C3E32CF9B19FE4825FAEABEAB1E2E63DC8E8B4E5A50575DF7103F7B58E4CC1307553ACDA05172787CA52BA594824AD90FE1CC702263C8BAB4AD690E11ACBA025BDCD9A299FCC1F801199272FFB5A39A6137F127B83B98DF5B19D940BE257FB0844804107F6D5A7D1089F17C8DAC90D59035C28297DAF136600C18515DBEF0036CDCBDCAF8BE6C4AEB1179E389AA345CB5DF024F9907342435657D5599FA424E51AAC32CDC57E025B672DDB87658DC23C3C54BD8DFC916863829E3F7DEE39B28B93B2001B8434EF90D1E5FE0BEDFF2D31B5AF01FE5F996951F31AD0D6F173F50CDCD5A7333E7B3908D8B626E3F08FB1D9EEDCC360E6ECC4B74BC33834AAABC355CD4432B09C40C011CF7AA90AD8A756340D30B3D7A3E465C9A19173B58245B1A8F42C875F96336D39CF60F1BB341680177D31724E6ADBE668AF76720C2E398A5B42C3C2C84384EADB951914398C1CB092B870449C8AE1BB844CB5DC7B32B8F661CAB9B298E8F90CD4B4ABC63B590A6D6D183DE03B3F61D5C266DA83C14847F71E5E344441CE178DB44B2CD4C644EEE4371E7B9793343F86361E13D1F8664FE439217241ECF8C68467941F48939485046BD833A3ED8582B9415F25C2C7650EA1E51\nss = 5635FED1A43168075134D0E6DD4C9CFF6E85F3860B3E9F1CAC06B249D62892DE\n\ncount = 25\nseed = AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4\ngenerateEntropy = 74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9\nencapEntropyPreHash = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376\npk = BFD11FC259A2115806F9F68AB15859A763A49D169D615B4999714D550707E8A0C0A93C8DB2FB5E4DE7C93111206F052A7D7A5E0B5632D94C7A87596D24E950B361A185F065FA96435F312745164693FAB8D3A741C56C6F10D8BE52C06A5D83CB1BD327E5B28DB12291D907A2888136B6FA3A20A48990C6B6C81499DE2BB12D19B591234D55C4549A3861626167C5A17CC2A4CC9F668DF0707D26795DE7F771BC614B994B574FA309A1E1C8B4A0A4AD6240286BB78BA701ECC430269A37843149E1F1AAB731523359C735694F09298E2A1A08C6EC273B4A1D57118B20524FDA18190C2029DA4095EAD53212F609A76A343D5C68FF17CE6B92B340DBB8CC6C03AE4B29DF243B93233AF6B95EB5A7A8B8643B0CF5A8114152B8EA54F0E3668511CEFF536D888BAEF85A62299C641769023B7B92088546F338448C1977804B71781A554BCA5F13C0480B42C5A66269", + "04516139ABAA54B429E7A0502B17A5A2727A7F230D63C5764DD497F164B24E5BA3A626785AD1B917A6B77B175E64323783C9791832A7C442B895EB338E6A29EF671D4D7C0230668C14BC794CF11340229AC905891CF1C51EF62B6A4A0553331F7F581054DA45C370BF606126B39492E4A3B8592BBE0359BC017557379471EF922367D82635D8494C88BD38A7720669A1F9145367A92090FC5DF15C034B82CDD9B7CB9CA76E74B2069C36987556012BF0746424677F60ADE29C9CB52C6D9CC2052394691D7306952C65EF498DA41279EEABCCC66B3A41747A8B447D7EE81116EABC04F4B776923C93A28FFE888652FC34415BAAEB6854D4732745A4BD5BA61C35678780063ED874C81823CEAE41B9684A05410266F7ECAFFBFCB5285472E5B02FB8C15D126410F0BA3BA8536CFDB65D23797414A55F2620BE653A98F33C95690714FBD3418C6893F8693908D41D6D69A744E63B2B0C190E3B1696A5C8B1CBBAA4719A0BD184F896C9D8F926DC933BA81B2785C05A51B22A95191F43DC23B42C050DC9133DE2B003A5B6F1A5730F490454C58AF291CD8D46ACDE69842DF79353670A54E2C88CC693745516EE64C2AFEBB95DF25EC0608AE4AA9C89215D471BBF68DC6530FC0FEE495FDFA09E98BA8D37F9636B270BD1102579EB7F1BF0B911CB79F03537168867EAF60D77D48BE27BC935B02662929DBF2263270670E0601E5E43008BCC07F06451E54755FCAB421D584BB603008C9909CAA61CF99A4B43A93EA8A3440991BA402C9A8FC51F90584C55EAA450B7A600342E98420D728A8B6344659F2A0263140E69AB86BDC6B20B3AA0920B90C70C0108358C8A92B27635154AF9A0A76080EE593CE3D37E40FA33D0C654AA77171F822E0082C95CB60B54A6A26099443F671E863889F35A0B9597B3442A71FA704F164834FC9C8E2C63847C9992CD73C1BFE7ABD3D75448D21926DA0938F92B9133A92E426DFD2634A677878EA9820F5C26A2382FDB1C4B8ED59DB74B4490B87B0DFC35F5B22112E5110D494E53C50D3FD6C64CB485BF5AB37F7A1B709122C7086D3FA56FDDC966DB2C53E09B976F986A334290DD8C3C7E6582C4EAAB182766FF70503B03B4E68261CD0303F7A83732795CBF84A04D78A541A0929691C94A094B7B8F92C5D5A3BC95122A6A7968DBB1334A712823D470766B3B9E7B55672D02AE\nsk = 60E93BEB5544294BBD612141956430CFF041E0F969E954A48298C7B5F321B9E1B70B7C796A753CC5BB93722B20380ABD6B8AAC4F0B102DDAB380B88AB9DC040FCAA8B775882A673864FB757A3453273627DF0690C90000B54112DCA50235BA14FEA59A764736A018A091B822A636AE7934A33BC5C15A7B77E1E53289C9757EC75CBBB792645325D6755D79B972AE993C9E3413AC040B3BCC85C4F98A2E185BF4EA1D19A4737DC78547847B7EF385D2A07BFE272764CC873BE8CB1286A0E7C83539D2B9BAD5A17F0893CCF41E2B5CAB8F66706955C5E168A99E9820A8402CB25A434F1A149F0148761014D32A51BC73A8CDBCB104C29BE554B2724107EF314C25D082C7252E0CE68833A47A619A611B08394960A64D8C22C25AA1121A8033605C9BF35221730B15E6269CC25FEBCB8E3336870B3C1C9D3A89DE4A9042758F517B55F85133B403C501590A0F53542239118F93874B319BE0D063AD82144ECA6156051424235D785C92AC00C412F8AC0FF5B88F056142F8A0934734B09BA14C00089BBA136279A5FE462082AB4B0709A6DB3279F8E9544F3909FF78B264399C2ED129C803B341D816EAE96BC531952D55059EF0233B0C18E1F7AEE5498FF6F11DBE801DFE193BB61B870008AE57483DAEB8CA7CCB460193C68A509E8DC738FF227FDA89B21EBA0053992A4D3A1F8767C0D3F3419838C8C7A2C0B3D68E737BA77221C68A8570948A322A143E5A03888C08A1BB7C42E9DB9111819ED94523848BC32781A881A468D26AA7FA4ACB926AB8695B24A094B8CCB0423192CEA88C1FAC818A6B0CA19E423B7AFCB51B121D48EA44037963EC1A325DC0BF7555977F468FEB49B8346338DB983E512B2FDEB35A300495F437CBA88C36D01536F7A56BC9DABD1000B77751031102CABA7182E2C440919435A14BC1AE1B354499324862885C9C301B7258FAF778CD0A4721F26EE32C5DCC7A7283DC10E3CB04713255D0044BF1D9234F5180F32483F7079B2C0558B95C622DB01BE885B2580931FC8617B6940DDFD54CB327712DA02F90A6A8DDB6BA17A31FB1D7231D94CAC2FAB88A43B0F56968FE2B724FC8A97E1A371C96A9A17A94FDA08897BA1EDF959F37029A84E707EF676B89FCB5E94B8997D95542E26CBD28A7D01B1FEF76B1C91AC327874C04F01B2D6280FDC60CEAD3587BC0AA6EC76F064B3263B2419BF3120AA7791053BFA6E089F6CB8BB020B5C5E2517D4B2F34EC3C4237AF98DAB3F4D44AE161773ED53F391A689D7B38F01155FCD080869656E15BAF9A2A6419B38C2EC39112B4216FBC5D94771FCC4369EB90AACCF3A752020E24F97C30C4C67632180E9B928A0941C23C03CE588F7D841AAB91B74B7959BFD8B5B042294EBB094B523DFC425E9EF70BD2E2BCB2937EEDBA0AD018737BA91A3691030C1A6E54C0BD4336A4BBB7C5DC79057EF5C574C04DFCF9C8407CAC999A54975B1A45519075CA167B8285B2D554EB81702E30626897413051AA546BC63A42723BB95F0DCC525944C967D7A5793C34C7638EE59608C8680F2418B648B7450B09C31BEBAABB956E1203BFB3D377373B5483C93378F15DCF2959D0E02A15E2277B7AB78CB2BA78703F13DAB307BA1B663C86BFD11FC259A2115806F9F68AB15859A763A49D169D615B4999714D550707E8A0C0A93C8DB2FB5E4DE7C93111206F052A7D7A5E0B5632D94C7A87596D24E950B361A185F065FA96435F312745164693FAB8D3A741C56C6F10D8BE52C06A5D83CB1BD327E5B28DB12291D907A2888136B6FA3A20A48990C6B6C81499DE2BB12D19B591234D55C4549A3861626167C5A17CC2A4CC9F668DF0707D26795DE7F771BC614B994B574FA309A1E1C8B4A0A4AD6240286BB78BA701ECC430269A37843149E1F1AAB731523359C735694F09298E2A1A08C6EC273B4A1D57118B20524FDA18190C2029DA4095EAD53212F609A76A343D5C68FF17CE6B92B340DBB8CC6C03AE4B29DF243B93233AF6B95EB5A7A8B8643B0CF5A8114152B8EA54F0E3668511CEFF536D888BAEF85A62299C641769023B7B92088546F338448C1977804B71781A554BCA5F13C0480B42C5A6626904516139ABAA54B429E7A0502B17A5A2727A7F230D63C5764DD497F164B24E5BA3A626785AD1B917A6B77B175E64323783C9791832A7C442B895EB338E6A29EF671D4D7C0230668C14BC794CF11340229AC905891CF1C51EF62B6A4A0553331F7F581054DA45C370BF606126B39492E4A3B8592BBE0359BC017557379471EF922367D82635D8494C88BD38A7720669A1F9145367A92090FC5DF15C034B82CDD9B7CB9CA76E74B2069C36987556012BF0746424677F60ADE29C9CB52C6D9CC2052394691D7306952C65EF498DA41279EEABCCC66B3A41747A8B447D7EE81116EABC04F4B776923C93A28FFE888652FC34415BAAEB6854D4732745A4BD5BA61C35678780063ED874C81823CEAE41B9684A05410266F7ECAFFBFCB5285472E5B02FB8C15D126410F0BA3BA8536CFDB65D23797414A55F2620BE653A98F33C95690714FBD3418C6893F8693908D41D6D69A744E63B2B0C190E3B1696A5C8B1CBBAA4719A0BD184F896C9D8F926DC933BA81B2785C05A51B22A95191F43DC23B42C050DC9133DE2B003A5B6F1A5730F490454C58AF291CD8D46ACDE69842DF79353670A54E2C88CC693745516EE64C2AFEBB95DF25EC0608AE4AA9C89215D471BBF68DC6530FC0FEE495FDFA09E98BA8D37F9636B270BD1102579EB7F1BF0B911CB79F03537168867EAF60D77D48BE27BC935B02662929DBF2263270670E0601E5E43008BCC07F06451E54755FCAB421D584BB603008C9909CAA61CF99A4B43A93EA8A3440991BA402C9A8FC51F90584C55EAA450B7A600342E98420D728A8B6344659F2A0263140E69AB86BDC6B20B3AA0920B90C70C0108358C8A92B27635154AF9A0A76080EE593CE3D37E40FA33D0C654AA77171F822E0082C95CB60B54A6A26099443F671E863889F35A0B9597B3442A71FA704F164834FC9C8E2C63847C9992CD73C1BFE7ABD3D75448D21926DA0938F92B9133A92E426DFD2634A677878EA9820F5C26A2382FDB1C4B8ED59DB74B4490B87B0DFC35F5B22112E5110D494E53C50D3FD6C64CB485BF5AB37F7A1B709122C7086D3FA56FDDC966DB2C53E09B976F986A334290DD8C3C7E6582C4EAAB182766FF70503B03B4E68261CD0303F7A83732795CBF84A04D78A541A0929691C94A094B7B8F92C5D5A3BC95122A6A7968DBB1334A712823D470766B3B9E7B55672D02AE16FE956BE4601573D72306A251F69BC2181253E2417E178341FD6553303AC189E1FB7456AC0AA1B97068F452CBA64EBDC138BCF5D36B0A0FADA2A3B374141EB9\nct = 535A002076557FC2CA495E8000B26F513DC41524C6E04F786763FF14F915D56BD6BE3F26729E41FC2E43456CC5F70DD25EC772E9030FF80A81A16E352CE7B6FFB5BA34DE56290D1EA1578A56B8D17A0CB5AFAE7987D15CE029516D88ABB555AE84B9F626960FD8DA732BF8F1A650307030316B8623B0596DC6CD8C72354584FC806DA654B0ADF1313ED3DD6A4B8F81A5C2600E36C57F28AC00AD18A48C00C8CFF0CEA1F8A53D227E89D78D533834816ED9B2A9EF48F6C5FF4D572EEDF497342ED6EBBA80EAD83EE6764F84DD09C5F372F263CD7195A50DD5695CB9B09C8E996994D7C94A19966FE74FED01139D2658AD75AFE22E0ED321D12D271CE2DEC1099E77573A3983574A63BFDFC9EA559A220135C9D8FC22F4C7A3A0506D649BD4EDC66D67A398B4B1B6040284AB0BDC60EA62F0B67D42F5CB6F5A3C6AB38EB3B2BFF6D7385143F40EC5CBDDAE52DC941235D980E4DDD79059790897FE235C11BF88A92EBA7E6EF524A4AEB827C057B75E802539BCCFCB33B5BC5B00DA2731B8F4A5A42A7AE901EB8B7783A017128C3765AA8A3BBF92EEBADC48D983BA16FA0043499302781AE46E2F066C312DE84EF0C0A837E8B6F9F633F8D2C2190A129D9A00A18E04B2DBBA18A0590BD6B50B31E470D85C803FBD35ADE162982AB659D7A627811B76217435A104860173AED6865A3E1967939BC8465D4F3E5D3C88091D1013FE12A2110E6FA39EEAB39A9EE545DE65263E1BC956BBC5ACEB6D6EE2FC0F1C4EF945C21C36CD76DBDBEAC43D440C1128A30A0CD581F434B2E5F45AD26B4C59CB6B003D945343F8413681B590C6627B12058D671B220DF6A0270DB87F1A81F01ADF0E33AFB686E76DC414684023455EF3465E26208E66F4A4C5C4C685B415DE1182DA6782DBA4CE1370D00E411CD2709D3596B337788F40574B43691F6A13741A75C8A973C626FE6B5595DEE15F997594C873605E8DD3F0137D358A2A5B1BBA8A9AF285E1C02D05944041CD7082BA247C24810140E5E9AF32D010196EF97CC40B95F5040469FE88E7557EB30F2E638647CCA2DC1845E582416345F9DE6DBBC6A007DD368F1827E7B29E296123FDDB818D9A25FDB429D45CBC59D0D74D5380E582EA7C73EBDBA8A4CDA6582B68FC07A402FC1EF8F24C1473661C091A942E4F316602470F779067D74B1B", + "6BC61B8133ADF1E5FBD374DB3EAF8CE169E02DFD2162AF1718E7F21CFEFB86EB5AB879615408A91B0EDF44281A5693FEBB6C229A0203E66E6746747AE342EDD2C3F7B528EA2A86140E8041F7FE6D671C999DAA5A50C5B01B3CCC35CA43ACC3DABF6A1ACADB4208D83CF49DBAA37843C51A55765E5F5AF141DAF67D3D5AE31A72F7A4756AD27BEBDA0B7B5AA204C8A8E726B42FCE4633DDE43EE434029D60938A3C4C3AAF119E2B3116D5299B6B7C80F9D49D17389101E7CBD668A038C223E7B820FB057543F8EFD37760006006F61035D41ACB177BD95AA8F44CCD4EA8DCD8309D795945ADE186EF9BC22D9921DC2843BCB627C2F865B1A56E\nss = A920DF59AB127D563D7E7E96AFE8075D8A7242B0AD88D72F367545FAC6DAA4C5\n\ncount = 26\nseed = 7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46\ngenerateEntropy = 013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72\nencapEntropyPreHash = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830\npk = 12422CEA108045D2888E2C29CE0BCD454B95C09730D6C4698E779987523DE0E972332544C34350D29C7BC030BB6273B9F1C98C3A63170ABB2641C54DAD64790E83387C51AAC922814F834C4745409273AB00051B2A819EEFC9A048F222626409FA7B3F8D27A0DD754F9372AA37EB92F6454FDBE3116D406B571203DC05201C31A52BA8B2B95B191A7B7B55E743C4CCB80A710863AB741B727F176224012C539AF2BD062BA6BE7A42EAC08C5B6B420BECBB41B55454EC1F41347CCD984F11767BFC82665286A56DD31598834B37CA6EE93658999798EAD094298160B7E6C76978370DB3180273401532315168A161E087D4C6086846A3B60B80103C1AD814843BCA7AB329C7914982ED32BF16507B3024A16F231281A732D3D155FA60260064919C484C1741874BA96CFD91AEBE5C314E407A66D7CC4C846176D759618654AC2A52FE69C69A375ECF625E2889ABEBF395FA20561BA6300A72A2091356FCF197C866AB5468A3AF7BB3DE755836D9784F7C0949445D83B3358721C7DB3C09B5120F7F757BFE3366AE4365B677255EA680F27C310F768E56F1AAB8792259340BD6B984406148A254BB605A291C0946C83B1E9C5BB3F879A787B9106F98809E94BDC23C062D592318F9854DF04BCC343D64387BAF398599BB352F82B1F0A5B530E824CFD69D7A4A15CB5624F70CBEFE1C61302B8FCA337D70D1900DC817837619FA893208DA873C350F02892097708CC637093EB25BFB4B3C793331F0FC73C5446CB11276824CBE419378A224A683FA0D17C671FB8C4BDAF18C20C53A21A4BB8FBA9AB7A1B7ECCC81946BB5FCB15E1D08ADA7761A55D503DBA912B73765FF93A6AB642B5FB72ED4F16657AC448A1957413CAE547CCD76D9936C860C70C5635C28754421AF13448959D67CDEA3997EE923AA326129B5397C15AB90F95832F263E080A42460CF9F081152AA59CF17263D008ACBF146F34A7808257689A3148E58A0A0117FBB47BCA97810A42A7E0F734C0A17745AFC6ADE752080B39F3267399C20B1FDFA195437B83EF5125405ABA8D2CA42040371C541A5FC339772948A21B7EFC30C909C7938779BD012642441083150118CE431BAA72E989425210945A7C47479F4873E3C3CA6698ECB2A050415066D0BBE5E240222A2884B3CC17BACC14164BE0D21330456A279547579F8A4E9443D913A154210A3FD1A1A263186445A8E1B884BBE8B54D0196AFFDC47544C8D10A69378FA139BC8A422C44C5568555F9080F170BC6E97284F448E6C23885D603A732C469B376A762B5068E29E80B74F994588D9822F3E81BA6FFC273A9C905D0910062BBE94AA1E0C8C3424303845779F8C9B515DFA0864578A66DA8AD7B56DA2810C11E1A2888B88BB55B8C096A145B62AD9D2C98E003658C9729D7B82550527411A9C0B981F3479251C1774014749D211687DDA83626C6BFCD5B08F8075954BC10F48623838A736E38C1143B9472B4DF5D30D37F0BD7C727A2F16A3CBE0015DAB5A12E27A63F7AEDB841D6D9BB1A79A5C3E903C9E374DA62A298C549B9842B77C33AAB6B4939AEB55704CB610D084950C41B746AFD7157613618F6F1574BA51B36F7828AF0AA4F79C0840EA3D679013DF619046E935E0BD96EC59643250A0B38F9779B0142A9E546EB525E72AD204D1EB31A6\nsk = 3A756D6DD157ABA65D60721C41EB4EDBEC38834C22E9AC88F03119B472BDA0961D1F5C3268EC6492F92D5D066DCBA69CE9C20311E1C15FA81FA5014C6C956F88055FC2D35E6B295D05D6167E4375BFF23257BA72C0F97F452B609F22B57F7C27F71A4F259938B5AA18097399A0D32C3602203BB6769015495B4BB7317C9E99C966215C58D3455EFCD36003826C2C7B1BB437A66A968DCBA35DAD7098FCE9133110A109C2B91764719CA25866C98550082E88F29E78B38B40A53C4D626FE63390A290B54389624C597909D79FD6A658E2166704C386EB1C8E951B4C7619B7B79349C3F59505809B1095405949CC55C109A1108649552D5F83A970083BFFEB6550893B5C5106417B0CF1E44B6B05A9F9093E386C9D43F14D4CFBABD3B17EFB49AA2C571AE99197D2E4B7D58775962570D528B8EBB8032E8065BDCAA391837D483A27239A4A8C0B8F13013F4AAA6BAC0CA86E532523D9620BF9C2C3E2AED2365E90A1699A4CBF454C4D2E2C4273E93456142F737C8B3697B9821039142C3E25B346D020C829850D6CE2649087AB762C25BAA2639C8C7A852BC76D456EE69747FE561E267844A7E51AE05C5820F0C2B880B05CC935A3BBADE2C6A4881CAC21938A304C4CD2C1CC1BFABD932B777CC459BAE4BE75389862464367C6318A0521DD62C5F070A139A95522D10D2E4134C06522CF52834562A208B22A95431014934F51EC49F5EC087D1435DB935BB5223C3EC87BB7F7427A458232474AD9CC222B422149977C7F366F48B0B14AB260BD0A8C04623F9B12091AE049725064D0BB4A249075816AA249718F1A7768C3469AAC7182D2F01D6373038D7C4CA24802693A354C19C66DBA1C05EB180AD04C1FB095B42947D16B66139384C71206BD0BA9AD9BBB5DD7593D08616C214FD9013E792A5B4930122D1C571F1315D235562C167D7546C8EF7536A929982F6A55CE7209B0D5735F69AC6C52A824E508D2481A5BE01075C54D8743BCD76767B69B5E350989E629C97AC1982A75806126245FA692DEF22B15A29499C82EF7F993EB3472F850527D900DA2F513A9366A4FA978038B9E46752DBB8084FB12CBC591008D692544078343E9AD67909DBD77C18BF18F02607210F4A0F5DC749F8B0BF371309027968968678B0135AF65138C5544ABD57ED8A646409224D32052BB14BAB4D51DAC981CCD838B4A513A36A351B81A0785CA281D7106872583B8BABBD62A5787BAB8EC9019C7009130EC6BE4E25D9992AA1DD13DA9C1A7F1CA27FD78968741436003789B8C781C599C98D2465C7513CFE85154D7A655216E5B3B800DEAA6B9DC7C0D998B9CE2B99DA6AFC27A5EF6C152EB16184D91CD038CBA69835AB3500AC2E87368F37888BA90F219CE9DA24109F0B3E1894DB5F640A17B0E705195A350A61EC62B2C7A216231C530F557D4C5605346A6500B7C1484012FC87DD4526823C447B71A726D65753716B30C212565DAC474CA3ACEE664218285A5C4A726F681E98619E2A289D08895BEA26BD6A3BFF3A5C5C1EA894CB6440D075004F879B41A14EBB82B74AB0131D0B3348742DB7244E750AE2B7BB57F8A95379502827880F8A50ECB1394DB2553C07627C113A300078DB1BAC7B5007812422CEA108045D2888E2C29CE0BCD454B95C09730D6C4698E779987523DE0E972332544C34350D29C7BC030BB6273B9F1C98C3A63170ABB2641C54DAD64790E83387C51AAC922814F834C4745409273AB00051B2A819EEFC9A048F222626409FA7B3F8D27A0DD754F9372AA37EB92F6454FDBE3116D406B571203DC05201C31A52BA8B2B95B191A7B7B55E743C4CCB80A710863AB741B727F176224012C539AF2BD062BA6BE7A42EAC08C5B6B420BECBB41B55454EC1F41347CCD984F11767BFC82665286A56DD31598834B37CA6EE93658999798EAD094298160B7E6C76978370DB3180273401532315168A161E087D4C6086846A3B60B80103C1AD814843BCA7AB329C7914982ED32BF16507B3024A16F231281A732D3D155FA60260064919C484C1741874BA96CFD91AEBE5C314E407A66D7CC4C846176D759618654AC2A52FE69C69A375ECF625E2889ABEBF395FA20561BA6300A72A2091356FCF197C866AB5468A3AF7BB3DE755836D9784F7C0949445D83B3358721C7DB3C09B5120F7F757BFE3366AE4365B677255EA680F27C310F768E56F1AAB8792259340BD6B984406148A254BB605A291C0946C83B1E9C5BB3F879A787B9106F98809E94BDC23C062D592318F9854DF04BCC343D64387BAF398599BB352F82B1F0A5B530E824CFD69D7A4A15CB5624F70CBEFE1C61302B8FCA337D70D1900DC817837619FA893208DA873C350F02892097708CC637093EB25BFB4B3C793331F0FC73C5446CB11276824CBE419378A224A683FA0D17C671FB8C4BDAF18C20C53A21A4BB8FBA9AB7A1B7ECCC81946BB5FCB15E1D08ADA7761A55D503DBA912B73765FF93A6AB642B5FB72ED4F16657AC448A1957413CAE547CCD76D9936C860C70C5635C28754421AF13448959D67CDEA3997EE923AA326129B5397C15AB90F95832F263E080A42460CF9F081152AA59CF17263D008ACBF146F34A7808257689A3148E58A0A0117FBB47BCA97810A42A7E0F734C0A17745AFC6ADE752080B39F3267399C20B1FDFA195437B83EF5125405ABA8D2CA42040371C541A5FC339772948A21B7EFC30C909C7938779BD012642441083150118CE431BAA72E989425210945A7C47479F4873E3C3CA6698ECB2A050415066D0BBE5E240222A2884B3CC17BACC14164BE0D21330456A279547579F8A4E9443D913A154210A3FD1A1A263186445A8E1B884BBE8B54D0196AFFDC47544C8D10A69378FA139BC8A422C44C5568555F9080F170BC6E97284F448E6C23885D603A732C469B376A762B5068E29E80B74F994588D9822F3E81BA6FFC273A9C905D0910062BBE94AA1E0C8C3424303845779F8C9B515DFA0864578A66DA8AD7B56DA2810C11E1A2888B88BB55B8C096A145B62AD9D2C98E003658C9729D7B82550527411A9C0B981F3479251C1774014749D211687DDA83626C6BFCD5B08F8075954BC10F48623838A736E38C1143B9472B4DF5D30D37F0BD7C727A2F16A3CBE0015DAB5A12E27A63F7AEDB841D6D9BB1A79A5C3E903C9E374DA62A298C549B9842B77C33AAB6B4939AEB55704CB610D084950C41B746AFD7157613618F6F1574BA51B36F7828AF0AA4F79C0840EA3D679013DF619046E935E0BD96EC59643250A0B38F9779B0142A9E546EB525E72AD204D1EB31A6633BEE89571E8FC16151491EA71234AB83289426559F90C67903A36E4AFAA6F49DA0C5DA5F195B80FBB99C2E8B06926074F3F604B3F6195B5A5B9737876BBA72\nct = 66290E0ECE573C5EE5C15E6FED6DAC0FEED44F3A2C6FDF910F5816097505979D8822228DF92F10708F9AD6C9", + "AD71F52BF21068B9E7FC986358C5E7D9B822A359976B5C5D8DC2EA584FF47B3CD97BF8DED0318564BD8263FD6E48FA68BE689DAB249B21B7F4DD81C7B5985260689EC56179975E3CA1597A76B35423172DA506967C0017CECA7977BB31A607B6040A7C92AB6F028A6FB641A2CB4496C25630604095EBBD767465CAB5B39AB0CD296E910AD218B8114BA81EB02E19B317AF3CE56856C8C24176125FE51A0ABDE9CBC44CEB3A5F40B24B6AF0AD28C238BB6D24BEE9A584C368F916DE89F7089B80BE3582B0152E5D775195E643DE9B9947AEBA9E2626CA018476087E35299083E937CB7CEF1B4AE0D42ECCF9A65D12959AB715B0361553C124708EB86F91A986BDF98E1338B692E2B2EE1EE862E6956E6B03E6340A6DC7799A0928EAB7F34DF2F39B990D4E5B7E2E6004642A2B97B9E927AD7668A0C7E56AD51E24DA07FE4139B2876A6C9C22CCA399E2C288C6A9A72F2AEA27410CD58B6216BEEC4D0EAC3220B019CC1D9CA094B73B57C487E8852467D0F3EF354F49AEE5971000B7058F69C6D470BA6DCE6DE957004F1835DF92EAF70FD4F0B9B6C83082D24859DB13547C93B3C3C235BE12ADA95897BC6C151B2147579135B69516CACD5D65AB08726698B7BE6FCC8C0631A3BD7FBF0EA06EBB09999A33A9C6183FFBA9789318A8CCAF16DF3078AFB5CC2C2767D32ECC24A562290F9C1C803F8DA15547E59C38C10673894407930D1F6062D805CAA53DDFB271FF4D7E70DDB921261549478C97E0FE218C319377C9266C518675C53D68E7D2A8705F88A6DB7159D7E4B79BB134098539AD9746B080BBCBC89F7B95B664F3BBE078C24C4BDF833FFA4BF22261D48C4E23B08E330EB523C5E62C15713C07A52183E6D4B539FF789216D39C8C6D5CAFC1C956AEC2931AB89D852AE9C89C74DE09E4052D5955A1CABD0995E1CA0779699BF12511D822CC06CD8B6C225E2B4C8ADEE2F56F0DF582674361FC457117780D60E5A33EB00B609239AD032904A85031A1A9F493904DDFEC5DF8F7B660893650D40C103F9912FE2AF880A7C29817B5BB59A3C5378558152461936A0EFF233B3896DCDED4EB0ACB36246B0B474996C147F7DC2150C5AEEEE1D36C96D0BBA1085A0554E7A4FFC2D7BAFCE6D5353A38C312FBEEADC5D41281ADE8198062A49AAC73FB69E0F657F536418B71A16F04C33C6348025BB2CA8D2544413C6D371B3C7A87C1D8ABC6A1B4DC32C39FBEEDE611AF4F651B536E82468736AF4EC3AE521AAB2FBBE823E76A4A3CCF8853E310E644999528A8D0F4CD434A5B1559367B87FE108FABF95905D98BAE6046F29D3C7EEC102B93072EF8003F2AF04522A5C03FD0B60CCDF3AA7069BD1C6D4E05C964305F6B7065905FF650411B017634D3C0D843F0C1266E7FE6D2F4FE86851F9158936C7038BCB584B1D73F4457EE50D4C491E86BEB7F03815F86484A3A8C106C45B1F665B2ED341789D10E53070B\nss = 462F8AE0143A9173E7FB5A0B476ADAC03F2600FFF5779CC1DF9DCAD9B1E7AB84\n\ncount = 27\nseed = 54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5\ngenerateEntropy = ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f\nencapEntropyPreHash = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54\npk = ACE2AF54375D684A6CB1FB38BD9C803A158483F91175263779E75B6D42734DC72FA02BC3B09630A0F79E2F95CB067C7DABF42F409A9635D55106E91E32341AAA4808DF6528C3BA98886184E0195E3CA09D9CC525980CB5A2E9027C6A88E9042BF77653B9DC02AD3CBB04F594BAE08DA4683DFC960708D85E39A28AD6E6A7DC81A2F0F8167633901298628B695CC1868756A97D80B1AFEBB71EBA5969A1086DE4D611F737AF56A83C7378C6E5E04E79A8967514CC668BC8FB7C7A1A671E29D55068E34D883A8320438AE7A44F01DB1D4DD07304081D684796A9257154381EC44562A8D005F3DC4C94D5CE9E36705132ACC8876142194DA54934095C2D5725A10E376432B17BF7D1B085D342CB3C633A085E950248CCC9C7FF350EFC341D07D0CA06E6BEC943353C479506691F2347A29CCB34AD09C929692ED98640E6B8560529CB17030EBFA4C769FC7707C75D86C234EDD78E7B3010FE86BF71748CC1C5B00023944774200B2163B403B8207093DFC959B6AA09FE6B98F6E83F972A50ABF113E9DA2FB9FA10D0D05789CCAF05C448854249BA8973A19C537DD69D3F39744DA89DEBB58705EC90EA56CDF428087D8333B16B1A9E59794D49A40B513B50867979230243B27F3D784932E1CAADF8B58FE11BBEA62DA4875D004A73FBCC90B566AB998A45099194D449CC60B0562570648AD588B213CB99A01283706878287930A71B68B43F87023D2F49829ABCBDE6A37A941182B78B8CC1B93982C7A24457A9E1683D2BCC97B4259518E0102760100E1C26CDD85022A04A91168486BA3413613DDD6C42CCB563379A08096B287B41A011FC9594D132E33957F2A5BC1DB4C57B4C8D9D3135476095DED35B2FDC09D8F996E332BAF7939EFB1032E529606677BB1144374C41C08807C9C0868B0C32772F18B755D7BC5C5B12F8EB9CA9DAB589185553B74408301062C90B2D68504F0718D42A1989F050F9097889AACDC175CD7E6768D626A8C9AA1B0CD6CBE91B10AF1A3E507575B47B6AC8C2B7C801A81985A81AD4AC04B32D0DD880D43B3D36857738369B7898B231B24CE6E9944526B9EF370354E21E38F6AAEFACBDA63497A85327A2112A5DB95179C5285D805698209F2A1B67A7730405B02B3507B4E4B65298734F5EB1B66BCB68F9369ABC01C7E4545568D432A685A6E038122253987EDC55EFAA3D926413DBDC43F9908DF1925031F45D28712734FBCEC3724653B019F7D5698DA7B0C3C90EECE1A1BE3567A253A143723B9550C8F7333DDAE88208667353A6184853A85A99C0C463189EB5763FE59D678349F536C56D014CD92B56ED2AA6B0518F1221A49FD6588650057FF00AA29B93F182B3437386F1F846D2A3C60CD900559425B2B7A5FF88CFABE24BEDCC825552577B5C12E4856DDCD91B0713526098B5FA555F105A0F1219110347AF9016254951C3CB5C7EBE602564242276399B0048AD8D370B544B1CB9789694C7753EF2CD4AB51513CB33F38BBB10C83C9A1A5FD1489D97476D9BB314849581D688C3DBA01662B539C50B0DB8E889A4654E6AF708A64910FC503CFA0ABC21B8ABC233AB978965059C41D1123A4BB90306AA09263B25BE885F4DB186D0E720E97524464C7F1B57E338A864D6C447ED4E29D88C30BAC7D2D0CDBAC43E9F4176F0078C715ACC\nsk = 0BAA531A985251B6B10153C8FCE6938A280E93F9ACE7A56DC7F44FA8BB2F88C09290888DA8134A0FC43CCBB75B50B6A724D6812183ACF876036DC252FC893419280314C7611750875821B2F3AC4F1C20B06365709BC07AD4161C94C41930568996F8CCA58C4A0536CD5668488715593E66621F96C87A2178A36438DD4C390CA0532D30B88DB712CD3C50D30BAA91C98CF0BACF32C60C81468307CA35B47ABFE59174E53467CF7B1D376758F1A5926FE225F0078FF288AE24D23241709E471624285C4FBD35A333088DD643CF6CB0AB6B27C8B679792ECB8BA4C28CD8B09677F0A7EBB692ECA6777922C4ED6C20402533CBB9A3F1E0C10250209EF128A626B763B30B5E49C4C4691E3A13C2C2601B6666ABA1D099987990BD1BB00AB5806390CE8088CAE30A5B20567295ACA7F0191CBDB4795E78BF150C7954F9A49880C218C23E59014620E18F18C536DA0B7807B0C9E11B1E341C2E7E5BA799653FC669C1032AA014CB79769361B01091B5E000CBE100933C6D05714481F491B2355E72638831D0C4F4DAA18C6B4AE6E825E688CB812490FA13B43D306E5BC857FBC18A61923F6B685E5FBB5BE9C1871A9822FF07CAEFF40318482144143CECC5B0C579C84FC949EF359F0B24B20FC0A9F3300A3217A8058469C78B7998744024E275CD1C70A96A75FD86019CA031FEC081DBDB796A56186D9A1DF8C098940527D34A1DF2DB50B5136B6737829F0CB1DA3B131AB238207A011F02BCD346A0A7138EBE3CA2D78646D7F98D5A886A24B83F8FE84AE81627011A2633F1C159C3870F7C69126B3C31F50D356888F9077FC207168CB075E0940FB7A0BECC556DE78089ED512A39A6ADCDA9C3C5126D874B50C163BA7B091656E52F9813CB318C87ABAB12A3F8996A4CB446D0793055CA177A1BF455CB956443E56C160F4788CDC6B008C086403BC910332D3E3274F9825E9964484D7A52C91C275E153A496801C0E6C8084B25B53C8EBA77A9412291DF78BD39895DFED82FD3C92947A1BEAB598D33DA8344C88A9E073E28549FC939CF5C6978B6F74CCB23675616899FB69C5ECA0C6B68090A338EAB57A222FBB5A482837C097BD40141659A2A71D81E3BD38D60D0A903592B768B0CE60A7044350A75FB02F19482138603A9D8CB89BA6A32D37A15549548AACE4636047D66CA4DE6CF7643C2A5939478A39873820578150172F965D4DC6CC6D7ADFC360568A53C97D268900B7B20122E50CC5E460304927333BEB7BF73446064D76C3AF1274B503203804774B00F02534772CCB83CAA8475651460B156A7238DA2A9847D445F55687A84BAA06DD69D4A637EFCC1C09F81BB97B541FD77A96883869731AC776913ED6C02EF03183B27B4655639509B1E8BBA74837375628152814448F270B6DD865C888180AA071A2AB42740E93F05B32A9C85A069420BE2ECC5335738F9D46C90C5AF1625779F3A329DD693706618AFB300B5C7099C220126C8398FBB8F32A2A35888BCAA187950365F022585C2E08243F53122B6C5EE9A95B84151AFD10B2110135C2A940BB8370565BCD8739609C44F4AAA7C5C266C6EF7CAB87B351236702E327B3E53555E24ABB670CA6E505DF0E0AECF7513F7E36374988DACE2AF54375D684A6CB1FB38BD9C803A158483F91175263779E75B6D42734DC72FA02BC3B09630A0F79E2F95CB067C7DABF42F409A9635D55106E91E32341AAA4808DF6528C3BA98886184E0195E3CA09D9CC525980CB5A2E9027C6A88E9042BF77653B9DC02AD3CBB04F594BAE08DA4683DFC960708D85E39A28AD6E6A7DC81A2F0F8167633901298628B695CC1868756A97D80B1AFEBB71EBA5969A1086DE4D611F737AF56A83C7378C6E5E04E79A8967514CC668BC8FB7C7A1A671E29D55068E34D883A8320438AE7A44F01DB1D4DD07304081D684796A9257154381EC44562A8D005F3DC4C94D5CE9E36705132ACC8876142194DA54934095C2D5725A10E376432B17BF7D1B085D342CB3C633A085E950248CCC9C7FF350EFC341D07D0CA06E6BEC943353C479506691F2347A29CCB34AD09C929692ED98640E6B8560529CB17030EBFA4C769FC7707C75D86C234EDD78E7B3010FE86BF71748CC1C5B00023944774200B2163B403B8207093DFC959B6AA09FE6B98F6E83F972A50ABF113E9DA2FB9FA10D0D05789CCAF05C448854249BA8973A19C537DD69D3F39744DA89DEBB58705EC90EA56CDF428087D8333B16B1A9E59794D49A40B513B50867979230243B27F3D784932E1CAADF8B58FE11BBEA62DA4875D004A73FBCC90B566AB998A45099194D449CC60B0562570648AD588B213", + "CB99A01283706878287930A71B68B43F87023D2F49829ABCBDE6A37A941182B78B8CC1B93982C7A24457A9E1683D2BCC97B4259518E0102760100E1C26CDD85022A04A91168486BA3413613DDD6C42CCB563379A08096B287B41A011FC9594D132E33957F2A5BC1DB4C57B4C8D9D3135476095DED35B2FDC09D8F996E332BAF7939EFB1032E529606677BB1144374C41C08807C9C0868B0C32772F18B755D7BC5C5B12F8EB9CA9DAB589185553B74408301062C90B2D68504F0718D42A1989F050F9097889AACDC175CD7E6768D626A8C9AA1B0CD6CBE91B10AF1A3E507575B47B6AC8C2B7C801A81985A81AD4AC04B32D0DD880D43B3D36857738369B7898B231B24CE6E9944526B9EF370354E21E38F6AAEFACBDA63497A85327A2112A5DB95179C5285D805698209F2A1B67A7730405B02B3507B4E4B65298734F5EB1B66BCB68F9369ABC01C7E4545568D432A685A6E038122253987EDC55EFAA3D926413DBDC43F9908DF1925031F45D28712734FBCEC3724653B019F7D5698DA7B0C3C90EECE1A1BE3567A253A143723B9550C8F7333DDAE88208667353A6184853A85A99C0C463189EB5763FE59D678349F536C56D014CD92B56ED2AA6B0518F1221A49FD6588650057FF00AA29B93F182B3437386F1F846D2A3C60CD900559425B2B7A5FF88CFABE24BEDCC825552577B5C12E4856DDCD91B0713526098B5FA555F105A0F1219110347AF9016254951C3CB5C7EBE602564242276399B0048AD8D370B544B1CB9789694C7753EF2CD4AB51513CB33F38BBB10C83C9A1A5FD1489D97476D9BB314849581D688C3DBA01662B539C50B0DB8E889A4654E6AF708A64910FC503CFA0ABC21B8ABC233AB978965059C41D1123A4BB90306AA09263B25BE885F4DB186D0E720E97524464C7F1B57E338A864D6C447ED4E29D88C30BAC7D2D0CDBAC43E9F4176F0078C715ACC3217D034B472A846CD317681C0F36FEEA187BD40E546DC4AD69C2E67FD9D830371600A8982C350DF524CDE514431DED7AEC23576530894BCBF0EC0BFEF0BB64F\nct = 7613DDA749B9B371C3430BA4A29B0E4BE5CA55287B1A1D0C760939DA3C998C7D88B2C8FD7D43F1F2C5B573EF16B48D339738D0D3AA0CE094D5F1077E23EDA6E6E8189C6CA76A7517FFED4C3C59184E8D96E74C0B284E8D21076426FDCE05C3A4115CD8ADFC0EC21EB5B86059D415D515287E44EE2E733EC27D6AB5945DBCA92B9BA4339DEE417428ABFE9F113D5E13C602AB11AE380E54421C4F713F0AF28C9C97B430A3B6DD7113EF98A93752F5F7FE4C763D3D7EAA53C8DEC6A796A37D97CFF28ADD820D317AC023DD3202C072303D5F172492AEEEF6B1486399E45167D8CFCB35011BFA166DAC078F10B49A776F9A00A227531E4B1390E3C9EBFA49C1C80046A093CCE478E1C91F0AABEA97BC0042330B26D01BA19C07355FF5612BCE097E351D891184725F2D1F95B544E615020DAC8691365149E5AED1E387B68B0E7914BF8E3E94267C5E1E525D8994221401A4048ACA3AB586B352FCAC09D41609012683B748661B5F60FF64C95F410D4163B07225E9D429A22B3DE3A8E391352331216C3D229DFCCA782F832DC7D0A830ACA4B9B1ED37AF42E6D9746286AB161A719F02B4A241CC65156E5A05359AEA4FEB750DB28B6799523CD42D70A1F84EFBD98D5F02229A97071D9105948C372AA52E9F132DD96D4AD3391599D155DEC585DC0C423B4175F5DB53BCC6DFBE384CE6705416C64F8D60A8704822E20AA05BF226C512B0AAD25D5D038E1D33FEB4376364CBAA41116D9B79D061DD61F8EC03E6D731574C83BB05EEA5AB730E51C31F7CAC2FD4F675824031AB5ECFD784AC57871092FC3CAD566E460856F77308424C7418FB6F9C4E9F3EAA8F3F2A5AB544C18579DEBB41B02347294E6816A873171F8C2A6E4C529205B98C1D77638FE2DB105CBCED66817051DAA83E89ABFBA25DDFD1D10620C94245645265A1094B8BBD75851925448629673BBC222B93A2DBAEF4B58A370204752CD993F3A10D6CF379A17DEC1A909DB1AD047F84BB50B244D15742543F097CA97E2597E2EF03DA5E50F054B8B439059EF9E82852A6E9A22C6DC6782333F858CD4D6B07C3BFA8ACAB2271E32D13297235934F4272969F5CFFC744CAB9BA3584AE869B52E97FDA0D77C11D255046CEC3D57E2408EB5AAEFE91E541C03247E28E96905997372D9ED7A31378351A4433F1624CE6A1AE1CA2A7B27DC2F41E126B776C3B72DB38CE2D7C1AB8E3CE8E7006D0E98EE2B9F3CFEB5697F302E5AA5B59064FB5CC2BA5C688B7056ADC0D204578EE44DFE1D113310BDB08CB49051363D8BFE16F2F782FB3BB992E3815E84F3EB3268A21A356178D09F4770AD6BB62CC8F82A29BD18A854F05E2F3135AD8BB60B752A8460DC53C869D4695E44B6BFEE3AF8920113DA5BA5747EB35BE4D5DF27DB9A77C6181143F0831410B50A487F918BA58A30FDE87ACAA561E662D31AEAE4672894E7EF8382027FDBF019893503209352FB63446C8E851AFC0DC22D62DBEEE29F43BC40E49B66DA3AE7D1E2ED93E760BC94BBA7FD1F47CF4D41C9E7A3C7AB2\nss = BAD63432A274BEC85E9C361191A3431D6F211F1FCC69173B9FB00C0517AC3B3C\n\ncount = 28\nseed = CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387\ngenerateEntropy = 2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f\nencapEntropyPreHash = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3\npk = A9C823EFC5C946DAB44B5B2068D61F00E7B0D87CA67706343927BFE4C12D20D69C4A5BA892F97EEEAB7B5A45742CC4AC4D37219AD72AC312051D31B8385CA2293415A13BB8983B8457B8AF9DCCA9E6322094CA68399AB77DBB9F6AA7CED5F224641C3FA07507DA9A08E0D180D52585DFB3B2FC95CDC733A573A888D403CBBB71C120BAAE2A195278370BF33299B9B2684ACCC5288A3CBA1277FD3999839A6ED29BB91D71A528BB2E4F953778BA23341CBA4B9B3C17F9A8366212AF3B722397419E24874B163470B3B2B7F24AE62258983B6161C6773B5AC90969C03D01CF4669B9D1F46E05705D4F676D464264D7549E1E2C3290C9B2BF5A71132057531714BEDBC7A91BC0AD56254D298908D33D588951333B3CB7924ABF14B0D70652C45AA62CC3062D851E45C866C6200DF4E74A9E559B9E6AB738F2B0DA9693CCEC3D968A866F0220CA95B7C6E8B04EC41D39C17EAFAB77444AAD4CA3A9D6B5B5D4611A6C074FDFB01F7DF68AD2440EFC5588F3B4A5C4106EFA3B9B6BB35C327465C7B656D1C1C6409993FD91CC20172E53190DAD63CE02691AC326904CBB6424C906BD091312C1BFE6969BA6AABEF954B5C8D439DA5064A248C92988961FD2254479946DEC829C76CBA61690E3C541648228B59805D7FB2ADB6AABA70718985279452A2FB1414E4704AC3DC84D3EB767101C8F4FEB24BC8148316609BF963AFA826A9B87638424052067CE8FB393D9AC579AB1080D1C549FD5103312A1FF9988DFE7805ED906FE9228E25942D49484A4510E0FF9A4A54A22CBA6BE945126EBE461C5940A74E1517C60603B2651E8371973DA7051EB7197713F5583BA51B92A9EB3179B45A8A8A5099B40C29F59146F25A563291364F236038C79B784BF09524FC6810F91B777BAE252E5B723E8059C06157653E335549784A15553FF9A7A29407D87725AA6B7A2A2669CC776BB810672967CB5B8B9A9BA751A9E69A8DDF796B1F324348712FF0C23F49A1DEBF210C027995B8A7CC5B288C4C74218E5086112237128CC57F4BFEDDC21ED23BAD00C58D835B5A3F0C8FDF1001E0AB26C2CAD47D5CAF2252CAFD3520E36AE21119E56FB456F277132059CA18623BFD994878C794545BA4A04436D804231F430B12808FB01647FA15D94B975BB6798AB7C3F6355B9BD50BC1CA00EE76342C8609BE0BC893DEB398B65A453BA08BEF83B805B61945229D98422F59C27E86022DA5620D737867828540C20B097076BC6C03E5435AEE1B9AF19958A7DFB921DA414280429DA389EEFE23FC9578B714B4F2E5B19B792903FF45ACA045BEC0B3D83C204747A2E24971B440C10119941D9316F45A87C4AB2AC0F7C4BDE9BC8EF73A7F42513BE3420C56720DDB984CB173587462AED9996D2A848D11344EAC02351E6C5A18CC7AE813BFDC50D5B143F4D07AC72A213A0577F9802043A585D95031D017B319358A24B06B7C2EA19F22B6634146CC0A123A8051C51E6AD6A956B1A935FFE00BC65C44A60534D1375570BC036EDFBCE66255F523BB377B2256C29B870DA2C870868299828F6FBBD8E0A109386B8D743A6E7A38384D5933E64565A037B9F520ECF8466F2073EEAF03D1B606F947CA2D2CA49E4B41DE9011FFBD23920C0D2D0CB20E3A9C63BFF3E047504A8965639E8FD0DB690FFA1E791FD\nsk = E0C2121F06048FBC565FDAA305202D439AB3A81B31FA257AA6F4273547C1465610AE51C2C1C8603AA36D1575754A86C9194B1CC6A9B8C9F77CE6484C5198A193EA4369293798943F7918142F849C8D7479EB0588E6E6B4ABC4CE81A406642414EB4137C2DA905CE4AD2B750E7D966D34A3B1BFA8CA5C8070456B1F6D5B71E582C9E1E2BF9DC37AB60A09E797A43F66B27B04C13C034FA6F594264C9D7DA884C762B159D775F7750A1862216E8BC992C9B2E0D18513F409DF8B0811EA89D2A69B66D34E59BC93F5C7BDE25140A976A3195541EE22A7EDFB7F9D647616B31399B6C924022F036225AF7C34E6D221213AB5F7A20B908325835266DA1B456F5649B895BB032142FC5C700CFAC4C2A44CF1F96D57B8BA1EF2C9332A612E8BB9043559B5567090873D3F9450F37670B473A96F812CE1D71892E43C9FE61FA594601A27A98EC817DD822C625B98E0FA8F2D5A311A87A6C23B4DFDF44D7511373E64A4A18A833D654A946B0DA9694329023086013A919971CC4C8A45916901B45C25C28EB6051600644660796935E65A4700496BC32204201D5C8708FDECCBFE949D1339947C6BAABCC67EC901659D220FA4D1A3DA1A4ADC2B1B323BC4CABB6065D9032CCCA3DD3C8689C9A35810BCB30B99B3F55CF2AC8258C5B85C696A372C7AAB5B0DD62ABA06804466FA4C22B2CA0E09B7D47C4644898AACF6899C79B5321110F010CD40253E40C5920DB980A57C01B55C506A6662BE1253FF171412820272613940704F63E70340414322B69B60B50BBB4459C1D6A0F25065DA032455598EDF678505F54B51713209565FC4812AD5F8A05A926340FC3853719146D049017475A09A1FD2D47B35371D715C455DEBB3A40A8A0E83247B6B8FFC05B2E857B5D8B201E56C109DC155B720B2528301C49237F7A629234231FBA25C75D600BD360796A68991BC68CAFB5B0B7C748AB7039D8C4FD1B3B4DE76C193123E50109BA70956B9556F245CCD4330B888D43A84714E8CF17E5713B5AE5A9FC3A331718C227EF4BDCE131F31028D68529F06A218AC32317E9B7634C572513974DA2BC3DDC4C07F2C6B8D3AAF5734B5D9E691D790B0FA67CBCF36C0372C056C268E0C243132DB5DE7365310F5732151B80BC98A2BB76F9E8C616FB1C90A5B83CA5738BFA9CF1FB96242998A44D667A57B517A834834AC0F2AC00E91B32E4E7AAB4522", + "49D31575BC96C8652CA8E4C3C0D3277A60F5CA7BEB80B563391A3B8E1A1A97C85823928877954C28D052A2C116BDC325B687D26D1CCB3386CAC9BD4C10C3AC381E056F9060C89E25A910C78E677964D153B74554C8F38939F881543F820B6F11989589302EAC53111A45F7664616999D7A64AA26E4CD74539DD496A1F0FC530415B16FAA4AC86341C5400CB1BBCFFD2707BE12C31ACC9B5C94B806B71DAFAB1EAAA087EFC1419CD2978EC1B973336D27B69AF2FA85F6C33B73770C0F6B85D855938ED8758E6AA5724B8C0D457B29A9394A3528DE99CBD7A875BB5B299C8A6DFE416104A59AA9E958E3828D3C651B5A9A7E81D7738374692033C4C68254D5170204F83A9B8520016466FD9189EFBACAA23AB8F962AF7D66AEC2E27E468B9C326711673839541262A9C823EFC5C946DAB44B5B2068D61F00E7B0D87CA67706343927BFE4C12D20D69C4A5BA892F97EEEAB7B5A45742CC4AC4D37219AD72AC312051D31B8385CA2293415A13BB8983B8457B8AF9DCCA9E6322094CA68399AB77DBB9F6AA7CED5F224641C3FA07507DA9A08E0D180D52585DFB3B2FC95CDC733A573A888D403CBBB71C120BAAE2A195278370BF33299B9B2684ACCC5288A3CBA1277FD3999839A6ED29BB91D71A528BB2E4F953778BA23341CBA4B9B3C17F9A8366212AF3B722397419E24874B163470B3B2B7F24AE62258983B6161C6773B5AC90969C03D01CF4669B9D1F46E05705D4F676D464264D7549E1E2C3290C9B2BF5A71132057531714BEDBC7A91BC0AD56254D298908D33D588951333B3CB7924ABF14B0D70652C45AA62CC3062D851E45C866C6200DF4E74A9E559B9E6AB738F2B0DA9693CCEC3D968A866F0220CA95B7C6E8B04EC41D39C17EAFAB77444AAD4CA3A9D6B5B5D4611A6C074FDFB01F7DF68AD2440EFC5588F3B4A5C4106EFA3B9B6BB35C327465C7B656D1C1C6409993FD91CC20172E53190DAD63CE02691AC326904CBB6424C906BD091312C1BFE6969BA6AABEF954B5C8D439DA5064A248C92988961FD2254479946DEC829C76CBA61690E3C541648228B59805D7FB2ADB6AABA70718985279452A2FB1414E4704AC3DC84D3EB767101C8F4FEB24BC8148316609BF963AFA826A9B87638424052067CE8FB393D9AC579AB1080D1C549FD5103312A1FF9988DFE7805ED906FE9228E25942D49484A4510E0FF9A4A54A22CBA6BE945126EBE461C5940A74E1517C60603B2651E8371973DA7051EB7197713F5583BA51B92A9EB3179B45A8A8A5099B40C29F59146F25A563291364F236038C79B784BF09524FC6810F91B777BAE252E5B723E8059C06157653E335549784A15553FF9A7A29407D87725AA6B7A2A2669CC776BB810672967CB5B8B9A9BA751A9E69A8DDF796B1F324348712FF0C23F49A1DEBF210C027995B8A7CC5B288C4C74218E5086112237128CC57F4BFEDDC21ED23BAD00C58D835B5A3F0C8FDF1001E0AB26C2CAD47D5CAF2252CAFD3520E36AE21119E56FB456F277132059CA18623BFD994878C794545BA4A04436D804231F430B12808FB01647FA15D94B975BB6798AB7C3F6355B9BD50BC1CA00EE76342C8609BE0BC893DEB398B65A453BA08BEF83B805B61945229D98422F59C27E86022DA5620D737867828540C20B097076BC6C03E5435AEE1B9AF19958A7DFB921DA414280429DA389EEFE23FC9578B714B4F2E5B19B792903FF45ACA045BEC0B3D83C204747A2E24971B440C10119941D9316F45A87C4AB2AC0F7C4BDE9BC8EF73A7F42513BE3420C56720DDB984CB173587462AED9996D2A848D11344EAC02351E6C5A18CC7AE813BFDC50D5B143F4D07AC72A213A0577F9802043A585D95031D017B319358A24B06B7C2EA19F22B6634146CC0A123A8051C51E6AD6A956B1A935FFE00BC65C44A60534D1375570BC036EDFBCE66255F523BB377B2256C29B870DA2C870868299828F6FBBD8E0A109386B8D743A6E7A38384D5933E64565A037B9F520ECF8466F2073EEAF03D1B606F947CA2D2CA49E4B41DE9011FFBD23920C0D2D0CB20E3A9C63BFF3E047504A8965639E8FD0DB690FFA1E791FDD1756ECFAEB695001AC490F36C4638151BEE98D367FB7ADF0E06A470844068AF0E145E44AAE52CFC609E6F47FD7A6F6AF877190FF52256D0AC5B05B89C3F449F\nct = 626889818F1C1732EBE9F4D16EB41D7A7BC195CF1B20D4CE5EF88D7AB66480D993C7C4D9F5538A0B6CD7789EF1483F18727C32165CC2A482D33EDA191877544F8ABD849EFF8F3F7C7032D95B34E8D8D4307FFF26CE4E02F031FE8DAE875A5CED281B114EC35BA6569FAEB5DED0A3B945E4B249154EC199732DD0C86487A3B9CC8F7867C5D10976413D5A78A8C7AC92312E1F47A33BEE8352389776ECE26A02926CC9E7992E40BEC9BCBB4206E498C27999567F421BFBC4471CC7C3C4E34521694C67465B0902910DCCC207056203790DC3D11D42BA445D0C9038B727DB8D7C0649CB7217E362020F3552071D50AA00BB05C1799841DB2D9625A6F9F2E3EEF16D5374BB46F839AB64A1314ACF5780F6E5894AB344A257894A2AB5CEDCEF54A5248040A2093639A63FE91F2FF779767270188DB6FAB919181633EE0E2D0F93EE0D5F9792BC0B73A1E3C40DC04DF30EB2B1752DC1B620E683619A0CB3C3B9620DF3FC2E517EBF7B457E5B4F331A1E5D54C107AFF06909040D1773842B44CCC74923C997F8AB0901542CA97C4C74DE7310B50F091ED8664A6DB07FADFFD1E815C3258753B0BDBF652BA5FA35D128B786804F7C7AA54DCF8A50ACA2B1924A95C8567F597934BEBDB6268EE2D4B95500203E17CE616CBDC69A379B2F26A4948899EEB69852442B2CA1F447E27FB865E64952CA9F80E7CC2A4FC734FFDBEBA2EA5D4D4BE1E36F39991F63AC0664399FFF6FE09F35BBFB6F4C15FF925FCDFB633B9D66BFFDF5EEBDE9BD1A00878E12142C3E49278B3BB6385E421E5DCF42432E5FAC086A270CEA48C475C0F9539DA658A7F4144F3B751666B93975A2E590923ABC30E02C068A3F11999626DC3DD49CFDD5CB076CD683F18880BB2651CAC442C45B4121ACE9E0AD70C3EF99C0E76ECDEA7C038A8E168B31A13D3F54710062B88BA7397DCCF6E433F463B6E9E587EDFDD1AE54EA1773496AC41CD6DF262B79F607396C9A3BC94944E8C5CA41CDEAE9CCC5B27ECD6E3FE10995AC59886B74C2C5E0B9D7C95375327B22FF6B713091E740E3B8DA20C07AAC0115A7706D753A0EC5EAA337054A63E089A0855ECC74061CE44F5D8BBB229F19A5C772C40D362A0EFBFAFFFBB9D71BC0B52AC16DDC02541086A411E45EA131AB12D6D7EBC007374D3C916FEFD01557699E7A713DADB5B4C385CE17FBE90F04844BC9F496520DC3DB1FEE0CD89D3F5C9F71342CAF8688BD0DC6860F581512AD1E7B32CE166C78430A9BB7B83F3FBA095330CA3E5CD0707C436B0A065E5208C448EFAAD85F246695039518CFB88DA79843B95DD1186CA5D71CD4B80ABA89ED704CDC93072632AD6B8075ED8F211F7F193F4A8DD4505F6FB8AFC9FD1F5F6DD086F2DBB314E1FA14DB5D7FBC4706D09688495EAD12EA3C331B4E13589CA3D4BB63499DC54B4893F838C103B01BA7C49FEB8B9202E3D86A06F80C932FD182A1CAD2615B1DF729D00E9F6C3D881A6CB6A837ECC400452C015F8E263BABA09C258B293576F2EAFD79A60D308CC0DCE6B145\nss = 50CD9D6042E7708F347B3D187430D070F0D8712E0BF68350AB47F4B50F04962E\n\ncount = 29\nseed = 265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222\ngenerateEntropy = 174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed\nencapEntropyPreHash = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df\npk = E71B4FF986BEE57636F904C856AC93E0C18775864B7B932AF200251B0328F5B3CAA38116C5A187305622B4A152CA337ED7A3690C31161862447B847F5639C5851133F627B5980572023B4ACC37C32F6B70B3555E0EC4C5809C9582407A0E59A866991564CA55B21A48EE530676A435D26B749C1264F9E58C3FC619D1A23EF5F6300E96665EAB70E7350852115F5859BBF1A8308977648AE5CF5A55C9FB42801ACA4F0592254461A632A94A9C3A7CCD05C8B7C3B09666BE54F072CDC58D8CBA687D609D1F021115085C340153CE63A37750ACBDA01A6944A46CD16CAD098464A109BBB611A83346CE6B59A5F4CA3CBB4394DACA06E5708459CC777534EB80A620C308DD779B074C11F31679AE98AE569BBE79CB04BB127208E24BA008BEA28C5DB5EC18F31C50712171E27042651701C3004E057A6865D54763843D27873220C174C57154C9A9705DA162E8685A035B34E15C411FD1B7220C57265C2BA7579F4BD9AB1461650E8027C0BA79F2BA3F14093CAB6015D8CC092905A6B8F09DBFD5743818489ADA2BEDF88CE592396074A79824457F7CAEFE334FC84869FF43641821AD60E80407649EDAA8BDC2FA877ECCACCAAB8A1F35A1573546AC382222C193BDDB31275B84374CB4679A5FFD803EFF07987ED085FBD43E45752DD9A32F5EC03E7B74567ED9674E1070B026801E99CA27EBC0ED24742530507E19B97A09877A1B511DA3B9835268AC35AE44187EA14B996DD96C35686EB98A81F1B2AD90A80D0C989B12813E7DF2B34573B876289E7C79481C7247E637A60F9B2D3FC129C379A759756408636048565CBEB24C2186A875606A43D20BDDD8B9D70781B1848BE54A075FE978A3E112A567223D21BEB3395921D1A100C578E7EA0455949B7B420B6494688AEAC00697AE1914084EAB375D86243B50A948874DC973B7670C8F9173228B64647E58761442A2CC90165B188B58025F8EBA65CC654575A1BB3823A1A29633AAEA1763F24486AACAFD611C28774C98D89B3CE8A696E29F62775B5D5C50847C3AD4BB968C441086AA070097508DA888B5B202E5A3B5DB579943F0861A5B6E2D58415019182262C444FABB77679E019CCED4E0A3854507FCD0935BF81B0E8500DC6C0B3C154ECBA94D166407C5DCC67BFA6AEA8B4EF0C53859BA4416D5C1975C1FEB6BCAD8076E6B020A62B077F0141DEB5AB5986B386D51CB7E8C779654AF5E5485A969467012C572F62DAF788D1F58BF9DDB4BC6E04B00218CB671CE8B2515B072B76CF253A4006AC5437C107A077F162A3984586978CEB3752B1FA1A2B525961F96C63D7207ECC4C0268A354AFB00231B1CB6EB4E4A694524448E7A043C22A5BC1094B23D3C5D0A9641F909A778EB64BAB84FEEC3A53730405C92130F756050771999E469CF07CC8C308ECE9B827D7558BF882630556150A602D9400E3D4ABB229A9D8B8132A7F0C0C5475BB852000B63228C490472B42488AAC0ED647B1E834F248534FE2195ADF6952B83B6705593A1E53F0315613D2596AAD44E27A26D632B9C71E9C9E5A6AB733C7E81E54DB3437D894A19B4710A3CD5075602B176EC369F5116638775574C74425789154B0BDE48BAD6E52C91C451C87B48EC406674A75B0CD39D1173C3F411AD1EFDD8BF4BE2AFEA69C2327BD070CD1432C8D219\nsk = 25933617206AE881C4DE291B4F269F2E51897FF29D3C6803E1A4C58E53051E879F1AF333393C75B366CFE2E84CF9CC930D1928298897480571D705075160", + "1BC119B1071412EFE8873AD325BC00420D13A752D33087BB6F884628DEF98F4FD21D01113219203F93419875C91CD33C7976B7A45F510F70E6002957AC49B862CD35640CE84E6B989201A74EB76422F88B31C94ACFA811605A32634199BE1639A50B709E89683C5CB0C975D627B76223EA48A2352C8BCC254ABC60812A6A5AB7747CA82073D1D31FEF708866A9801AD067A6DA0D848C409861C350DB559A0AB1D91C9BE0C149D6C241A13849D9EB2DA4B9B9B30B348217491449A43EA4544467824FF954C4869C8DC0B2BA2744C8D38BA584CB78EA6F6188BCD090267BA46882F16964AA003E2C60105415F937CF13B9CD00456D3545BC5E48B6DDF61A14ECCBAC23BB1D071BB14361B4C9ACB7B48805B7890C3676B550238391B388260CB0E2567F725B0382C7174440D82BA8A6D226D325CDD1C26ABD510ABB195B73D203F9DB7DB44ABBA87581A3C57F079B44A9455E3FA16EC87A0CC14368569B35517272220BA7760A8A0508BF0033031D42763FE89B611366B8B93D2D523D5C872BB99BBB099515A5911F1182404B7B4CCEA91462C6A5ABC16C64F55AB38A763A03BA48E0268819B6DF8BA88704AB4C7BCD8F8A150CA434AB0632ADC522A49C0E45997375D69901416792F845FCBC1A18789B22870401D6872374B15C851ABA4C3CF5A8930D34C74FD444A2C87F90D9353CD77361E26C99C8027B50504BC5B3F2BC27F3978822113E13D71E19E3915A9A4F0646AEF6D513E155B41237B2AB08BDF38322BF4C00706C0F22854D080BB8ECF58CC9B75D19A0185412A74B3C7D61A04DD8CB07BB37156C46221A7183BEB9321C58A924048AB86032F54815DA1BB33AD4312391C1A6778D9070B1A4542AAE231AAC97BB5E1A1CF42792C9921313C07ABA3A8C15DB5D1BE417C3888A2E0921A7AA1926044AB865935A2738B4378484B44471DA250E41925E976BEECA9F93D191B0C85B487BADFCEC4BE7C7683C508412E096AE888BAFB97CEBD3266EF7397004CC56741F53683034FC3160522E6BDABAD190C51F31926AA94B2F2A4506D69705623E3047176B46169AB8A715B84848BB4FB9830BE744CAD7591DD8D128C1A40F8A5B2829A92177D73CB1F319C0F45557A69AD790C87A6B8314E618444081C221C07C4BA5C1C450B8080DB278770A0C110DC386FB8411D4B983503964F7B6AFA10AC5154CCEA9E6222B4A70E5175F125B0A83010474311F8EF84FDF3AAB6D508B313A93C29675ABE12CDE50BD4B5B7E13C7228D9AC9DF569CC1BBC995EAACBC2290B0293A2BBA70AE8757C5A7CE84386093E02B3201573C56BCC368A7DD404371453C38823BA4752EDB663E5FB99C5E91CA9BA94CAEBC9D60A6318CF62168A86C0C419CAD1BC4FE514A745BB2C81701B89BA371CC1F10B50D95086D99778383108DFED849A1F74696464AA1D67F7F40BBC69C1FD907696D6227CF20750D68A3D36C600448C91A523A16E5C84B40819BBB2BFABB2CB03B658FD0656F410752F52BFC9BBA4A3A8D09D5835B1540F5DC673DF71540F560E71B4FF986BEE57636F904C856AC93E0C18775864B7B932AF200251B0328F5B3CAA38116C5A187305622B4A152CA337ED7A3690C31161862447B847F5639C5851133F627B5980572023B4ACC37C32F6B70B3555E0EC4C5809C9582407A0E59A866991564CA55B21A48EE530676A435D26B749C1264F9E58C3FC619D1A23EF5F6300E96665EAB70E7350852115F5859BBF1A8308977648AE5CF5A55C9FB42801ACA4F0592254461A632A94A9C3A7CCD05C8B7C3B09666BE54F072CDC58D8CBA687D609D1F021115085C340153CE63A37750ACBDA01A6944A46CD16CAD098464A109BBB611A83346CE6B59A5F4CA3CBB4394DACA06E5708459CC777534EB80A620C308DD779B074C11F31679AE98AE569BBE79CB04BB127208E24BA008BEA28C5DB5EC18F31C50712171E27042651701C3004E057A6865D54763843D27873220C174C57154C9A9705DA162E8685A035B34E15C411FD1B7220C57265C2BA7579F4BD9AB1461650E8027C0BA79F2BA3F14093CAB6015D8CC092905A6B8F09DBFD5743818489ADA2BEDF88CE592396074A79824457F7CAEFE334FC84869FF43641821AD60E80407649EDAA8BDC2FA877ECCACCAAB8A1F35A1573546AC382222C193BDDB31275B84374CB4679A5FFD803EFF07987ED085FBD43E45752DD9A32F5EC03E7B74567ED9674E1070B026801E99CA27EBC0ED24742530507E19B97A09877A1B511DA3B9835268AC35AE44187EA14B996DD96C35686EB98A81F1B2AD90A80D0C989B12813E7DF2B34573B876289E7C79481C7247E637A60F9B2D3FC129C379A759756408636048565CBEB24C2186A875606A43D20BDDD8B9D70781B1848BE54A075FE978A3E112A567223D21BEB3395921D1A100C578E7EA0455949B7B420B6494688AEAC00697AE1914084EAB375D86243B50A948874DC973B7670C8F9173228B64647E58761442A2CC90165B188B58025F8EBA65CC654575A1BB3823A1A29633AAEA1763F24486AACAFD611C28774C98D89B3CE8A696E29F62775B5D5C50847C3AD4BB968C441086AA070097508DA888B5B202E5A3B5DB579943F0861A5B6E2D58415019182262C444FABB77679E019CCED4E0A3854507FCD0935BF81B0E8500DC6C0B3C154ECBA94D166407C5DCC67BFA6AEA8B4EF0C53859BA4416D5C1975C1FEB6BCAD8076E6B020A62B077F0141DEB5AB5986B386D51CB7E8C779654AF5E5485A969467012C572F62DAF788D1F58BF9DDB4BC6E04B00218CB671CE8B2515B072B76CF253A4006AC5437C107A077F162A3984586978CEB3752B1FA1A2B525961F96C63D7207ECC4C0268A354AFB00231B1CB6EB4E4A694524448E7A043C22A5BC1094B23D3C5D0A9641F909A778EB64BAB84FEEC3A53730405C92130F756050771999E469CF07CC8C308ECE9B827D7558BF882630556150A602D9400E3D4ABB229A9D8B8132A7F0C0C5475BB852000B63228C490472B42488AAC0ED647B1E834F248534FE2195ADF6952B83B6705593A1E53F0315613D2596AAD44E27A26D632B9C71E9C9E5A6AB733C7E81E54DB3437D894A19B4710A3CD5075602B176EC369F5116638775574C74425789154B0BDE48BAD6E52C91C451C87B48EC406674A75B0CD39D1173C3F411AD1EFDD8BF4BE2AFEA69C2327BD070CD1432C8D2191B1B0A8682CAF72DF2E0A48513A7358EDBC77A615D6BE6FE2A7145BE66B7C50950A7A2354F7E5CEFA6F4A4E9A1C411EB9364506E9E1204A8ACB3CB77FBD2C4ED\nct = 589B45383FD87E438A2036E96032F3FF220B23EB53244CA47E77379D46C333F3BED4F24D0582E9949DDB32AF9EDA732E6DC529FA9250D635E160316F7585A473BD3B59B0084122EC07E73CA921080AD90729565C5297B624315ABCFC027253642C6972EC426833EFA33FED5399F768B422259857F40D0A11C3C2CFA2920DE96CE3DB945DB087C39F0D97C041457C21B0E9FEF68927ADBF34195CF17871515357CE6B72BEC5D3D77D10E1D1A3CE3740600841B3E58CAF96C4C3F86E60502B8618FC918118E14699060E5E87851990EA933B0E60A7F750FE7947F449442C24F5FDA9E39B68BB51EF9AFE2D2A786388921A01F5C228783DAE97CB91CAF9C5D21C64098CD3B290C77462131BCF46DA587267354478647083BEE9110A9DCAB4EF3B2AE080E8F991C7B641DD7A0F0DCFA5F133636658853C52BA1F36F23C6EEBDF9FE230819F77B39086313F6A96FEEE877D9855D24A8582BC2D38E05384043FC23800CB0447DC2708AAC562A39889EC6C341F88EFFE499F970E0AC8BD3636EFF3DD5919C679680DF277CAA89829E03BB0D01D0D1BF2904BF8734D45AA1A5483762CF3704B1A756357179473D4D6DDD30FF0D180843C3A9C6CA2E9C8CC7BECCA7BF76663C7F0483207423F30FB219F330073787D8C6928499657B9B17208B0C4A37E5BED81E166B69E708A0388C2ED1EE4892A9B48D0CD1DE52C747ECF25694F2B909D368D5AEC537A0EFBB10F770D2C444BAF1B25AB0C1DB0EBAD0A5BA111443010393B330898B2C4251C9E682B1AD66D4E58B9C898A77AB6AA0D9E60DA99D80188580A7D50DC8EB976F3E1C75FDFB51866D7FAAECE97D56A440C96398E76BECE663FFC53D2B06EE6D11062805F7AABAAEB65568BCC6510E26DBF3C8C66C7BDB2E70264AD2B68D6D066304C15D2228ACCECC8CC0ED3FB8DE863F56930DE5DC94D80CEFA1EF24C0746FD78A5FEE6FFEB6FD1DF1E20A0F21875CD22081B12C68B73E7BE9FE7125D503D0BA57F8F4D210FA0E39668509E841F8664D52C65413E8FDD715BF34C852988C9E1857977A503A6FD5ED158BE6371CB29E4A2A13DE00006062C56F160704E1AF1B79E0EC175E11FF0F705291BAA1825FFBFFF4384D2003B726D794EFA99B8E9061C0D20381A892A67ED2B0155ED494D8FFDAD329E9B4B610FCF34183DF518C681F8CA2D7E36561C9A7271B9DD4A18A71949F9991EE0F6F43F5DD5D44DBE793FC512F13B7463BEA6682CEC42713A725E1E71F06550435963C9AE8D7D908DD9B5F99555E4A668CC9355FC2D931E1B68001A6B3E20B4594304DABFDFE9BE0EA26F92627820A849B6A1E2C68F97EAE111EE4786F1908F268A56053C739E44F7DF80EF8A85B86ED0CEEFD7B0FCA38A91DCB1CEFCCD1034097A0FAE6127A0C47F1FFD2D044F808BE041B5968291FE4BA63444CAF4DA65B7182C654F1DD45771B464302D9B0EE14FF0AD361DB76FCE8C808049C884DEAAD6D4EC8A201B99BF31CD1DC9A8C1716EFC01ACABD5965FA97371274E385DBD75E47D5A61A9E56E\nss = 2E610015C6B440280D6F28D5E3CED35CBF65A70A171151363C4CC882D7899E0E\n\ncount = 30\nseed = 806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA\ngenerateEntropy = 351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda\nencapEntropyPreHash = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9\npk = 8518C8D8DBAB01F270C3131AC1586BB783B35DB82F3C24AE2B767E2C4A7D15C2A86EB19FDFC41113A7501367CD70D73D0F63705487AC4E0BB1C84001FE6657610C7D64FA3DF4538BB6069128C4597EC9B291938EA5D7CD46897AC2179B52F1CAC91B6C36F37A59780E454C50C5DC354B56A43040804DE2394BEA14C2D385E082C5F181228D62307F5A6A1AAA1EABB84F90F34310844DF95A4E6D423D8C993FA7F390E6984E482024C2968254B54B7D3418D6F859E295665262246E1BC8CD6C9B726581CEE69140F85C02024C5B59AA0711813D66433AA384B2A4A3447939378A1E6A98936BF04AD075981D93C53E9635B5E285F96755F8689B5CE5429142AF6FA02EDEB1A719B272F6B0A6211A5B9807CE6FF368739B51D4D9480BD884C8B456569027B08A3CB928645D450C6264C5FCE2A2DE2B241F965034A08716649A3C71020A6986FBC8BFB5B4A2CB162749264CC1E44BD66223F3DB1B9BD2C68744B52ED7BBA0B9773DF128883110D2CC4757DACAF7F4C90FE02884E1A581D89AF687AC79444C9D801D156325590A3A24441B7C2C893B777386198C16374329E640B6A439FE5BC71AB3AE195575A71CBAB773AE6F0B5AB2D750D222A5D36B86EA2AA2006C54940A5F84", + "3AB708D19D5937643309C12D522DD479C3B2D57DD5696D25615ABBB573FDB62EEE5C6A6546CB1FB188F356800FF4177C69B636CBBF9EE9A7C7D512CA156490C96B347A5BC2CB257A061452DAB5FD15BDF5026677F14967B6C825D03EB782CD0422BD1078B7781624DC318A33B0C437D6C35997A22E30496E876762BA5DCF5146C5188DDE6C684C265A8F05031904572F7554123832C78767FF4B5FF525680C773AB3BA1A93776897D57B0D507B9391712344326F090B3D964DF8C293B6638FA36815C7CB9B7962956F903F62C4CE3D7646EBC1A8EC04A815191CB4BB085EC8693F2188F490731C087C23A8BC7CFB32FC019D106934B2D17706526CC6F787BE424BCE5B26329591C47402D57548110CCB42955C422323ADDB4987FB0F3441558964BF14021A54277BA14C5773A10B81C1427F51173F5C6CBE1B7575A4B6766AC355BC443E479A2953A51F7010F7B04B23E0CA93D08836432E3AE5A1A6BB62F5476C07914F88532CECD00CEB340588AB675F93C286E7288DA1C6CA3621AD6A4AE1FC64AA15B27A7C3EABC120E7460737585B5773AB18E23EE185C900ECC3B765983CB807E2F7047E6C999C6716E26801EA938302ABC312AA797535358196B63309846675BCF1B33343BC3D4D172DB81947643A84FD2173FCB0477AB87B57B55899A308D51311C9BA6916F15947D707D88B9228D0488DDACCB25455CF782B7A18264E55C9B6798F39A53F53240C82FBAF461364CD5202C5C94CDFF23E0F731624E69310E5B47964B2BFD3A59A5B0D55A026E260731DE346F74938ABC607B4F579B8B200ECEBB633614A46983E60E442A4914C93FA62219025E4A99D71032F0B00906126365C467E0A235570A544A7640F23800CD5F2A825479A632343F20801F1774F0E8B7DB96A860FD40A43CB7ABAE76039C6BC80B94EC315AD49E9904908A20CB444BFE219452C464EEB2914EC19031152CACAA00DD541FDE81ECAF1F339E468BE45459E708BFB464D0C480A1BECDBC021A06AF7AAC4772545EB\nsk = 719950ED1960FF6C2D7D59BBECB83AABE1CCB569B76CD9B053389C552CB6BF847CF4FC1F18A03E66F02CDB284C15D656151644F78CAEEAFA8B12CB7C616256C032CE6112735A74285D66A90F3A745ED8733C195F6B1B9B272897520A02FAFCB958A9669990B73420BCCE373ACF5A1C86A555C3C48F78166C0FBB023C49608592261060884B408C9FDB1F4B023506D3516956B02637AF26FC7B1D9345F8B54B5AF96997D39FA32C01AB64A6AB7491D50303B4E8A134086110D220462395B9D89D9651205AEA9E1B88BC80C4C8BAC44AF4F1886EA788A0B259DDA78116051059853D2CD073ED8CADAD9AB04F7175D57C3224E953509588E788713D5A6714D0AA48E972F4FA55F16579D9BC6988F562CCF1286E87AA785929BF8266D7E340022C0221736C3CB372B85723042382092545A45032EB727BDC750449C786145ACF42B85D4618B0D6F009D0224A816620F1DB67F59713090B0849559A51B9589532CE2DC25DF8F09AEBDA932073A2AC2115B12C5F94C64750220D645B34C14AC1B2208565377D61426D7F2A25CBD969A2705EA330B676EA6EEFCBBC6CD40DA9C0716D147B398B7D469A919D83BAACCA80F0E41414382804B0A321362E14E766DB2450F599963CC2899E1048D839754858910D12C23F99158A9A3149362690A9C5540133E5F217A7B66B0D627321C810F7D1639CCA948D708616047F85BA41CEE9211DF72731AC0986D1C3149854B71683FAF68179799B12C031A2A84574B9A67C96A708355F7A86BFABE63DDB94B6C048359481CA7A45CBAECBCF34407D8E378733F812926599DF5C156A94945FC7911DB26BEF17074470A7BD6B60F771CC3F396E847195CE26444B641F91B468FA1670D0184942472667AA76E42976FAC48E78DA72EF0C207FC7400F92699B46345E4C9972A35DAEA31ADBE87980438DE4F211B005C8DCEC1A6EECB56D891677F9006C49385E8AB20A19B74325A9A95083BC711537480DB30719815352616B2C5721979BD4267FB134188A75B9CB303215A76A246D8F69ACBD173D069B2B99B727829AA5469A0212C006A88AA4A6B614674674FA75500AA294711C178B741B0275280BDA27813647A5DCAC3A258991DB4BF436C23F37C697115143A2755FDC199FF32B19209D7FF904FEAABFF7383884C1BAE3C0CC20D019066653B99C1CAFE366567C9238785B0F0B4D1432A9E02CA2D9A3B37D84646B157684D7AC720727AF4533749A9FF99BAD8F3877DBE5CFF9C75B38C4002178CE30773EE36A14F1497AB386CB36420F04D85C8312CE25B357D3108226925F6B85C7A3729064F81AA66336163C00506BBFC82030F4F33A5BE7330926BB3F849D1DCB09F5CB814BA8A722506D0A037E6EB26216AA3C4D4C05D5CBCF0358501936AD2BEB3563C341E2315DE6D68404ACAB0149BAFA84491AB67A2DD82972220B0DF528DA7C4D441C8CDAF508CFA2C0224932E7E5215572AA433C9212022899E43A93CC7C8F4AAC6ED5ACBD0162E4DA4B897B7BDCD72A0B2A2354F61A6C211089C11E476715F3369859C3021584B6593B5784344D53B40DA0725A90804C45D02F6EB7670071660478C53281B5E290BFC77AC46602B530B1300628A7A4F20CE227688518C8D8DBAB01F270C3131AC1586BB783B35DB82F3C24AE2B767E2C4A7D15C2A86EB19FDFC41113A7501367CD70D73D0F63705487AC4E0BB1C84001FE6657610C7D64FA3DF4538BB6069128C4597EC9B291938EA5D7CD46897AC2179B52F1CAC91B6C36F37A59780E454C50C5DC354B56A43040804DE2394BEA14C2D385E082C5F181228D62307F5A6A1AAA1EABB84F90F34310844DF95A4E6D423D8C993FA7F390E6984E482024C2968254B54B7D3418D6F859E295665262246E1BC8CD6C9B726581CEE69140F85C02024C5B59AA0711813D66433AA384B2A4A3447939378A1E6A98936BF04AD075981D93C53E9635B5E285F96755F8689B5CE5429142AF6FA02EDEB1A719B272F6B0A6211A5B9807CE6FF368739B51D4D9480BD884C8B456569027B08A3CB928645D450C6264C5FCE2A2DE2B241F965034A08716649A3C71020A6986FBC8BFB5B4A2CB162749264CC1E44BD66223F3DB1B9BD2C68744B52ED7BBA0B9773DF128883110D2CC4757DACAF7F4C90FE02884E1A581D89AF687AC79444C9D801D156325590A3A24441B7C2C893B777386198C16374329E640B6A439FE5BC71AB3AE195575A71CBAB773AE6F0B5AB2D750D222A5D36B86EA2AA2006C54940A5F843AB708D19D5937643309C12D522DD479C3B2D57DD5696D25615ABBB573FDB62EEE5C6A6546CB1FB188F356800FF4177C69B636CBBF9EE9A7C7D512CA156490C96B347A5BC2CB257A061452DAB5FD15BDF5026677F14967B6C825D03EB782CD0422BD1078B7781624DC318A33B0C437D6C35997A22E30496E876762BA5DCF5146C5188DDE6C684C265A8F05031904572F7554123832C78767FF4B5FF525680C773AB3BA1A93776897D57B0D507B9391712344326F090B3D964DF8C293B6638FA36815C7CB9B7962956F903F62C4CE3D7646EBC1A8EC04A815191CB4BB085EC8693F2188F490731C087C23A8BC7CFB32FC019D106934B2D17706526CC6F787BE424BCE5B26329591C47402D57548110CCB42955C422323ADDB4987FB0F3441558964BF14021A54277BA14C5773A10B81C1427F51173F5C6CBE1B7575A4B6766AC355BC443E479A2953A51F7010F7B04B23E0CA93D08836432E3AE5A1A6BB62F5476C07914F88532CECD00CEB340588AB675F93C286E7288DA1C6CA3621AD6A4AE1FC64AA15B27A7C3EABC120E7460737585B5773AB18E23EE185C900ECC3B765983CB807E2F7047E6C999C6716E26801EA938302ABC312AA797535358196B63309846675BCF1B33343BC3D4D172DB81947643A84FD2173FCB0477AB87B57B55899A308D51311C9BA6916F15947D707D88B9228D0488DDACCB25455CF782B7A18264E55C9B6798F39A53F53240C82FBAF461364CD5202C5C94CDFF23E0F731624E69310E5B47964B2BFD3A59A5B0D55A026E260731DE346F74938ABC607B4F579B8B200ECEBB633614A46983E60E442A4914C93FA62219025E4A99D71032F0B00906126365C467E0A235570A544A7640F23800CD5F2A825479A632343F20801F1774F0E8B7DB96A860FD40A43CB7ABAE76039C6BC80B94EC315AD49E9904908A20CB444BFE219452C464EEB2914EC19031152CACAA00DD541FDE81ECAF1F339E468BE45459E708BFB464D0C480A1BECDBC021A06AF7AAC4772545EB2C54DF6E9020E1E44B11B471DEA97A382A2FE8D1042565BCD51EF21CC0884D68F072D9B5A99F9C7A0A011E4DC10F6B600D611F40BBA75071E7BEE61D23FD5EDA\nct = F3F451B8F76002C10A67C10AEE76209E067B1B997C3B476373F7726B3F631BAF10D274224E86AF9D333D26522A951F3FBD36C72C6A261059016FBE4B3949DA0616205FC724ACFE2946C4D694AD1999CBEFDA3F0167D1CFCBD8BBD51A630687014AE826305E48D6E3AD6E68AD5542C3358CAE7141494821DA7A3BEE623096A5128C6DE1AB616DA91BE228BE402990D81F73031BFFF794DB1F8954738115649492B630FF50DA5F06FEF7D712B3BADBD175E290FB78351C1F408B5ADABAB395BFC0A5D5D2414C2131B4014592E2D5583E81286E677FA1F858EDA8708B2BF25147887433BF56D523636605F91629FB49B1CEE98CBCE6C6C9E76C587F50FC8B56821479BF3B97ABCA13804F08DFF1EE164AA269F6DB96DF267FA32F5B2EBFB3ADB3029859B5C802B0049B05CEF0A9BA390C49D38B6E11483B255856E0B2BB23685AF3843F5A6685FAE0A3D7424DA52B061DAA81390BC1335A841990C94EE87FD4AC9F2C56136BB755460F2698822D1152E33BB2294DBDEDD3A6630699655723B99B285A3707E194F2A7E53CACE9D4B4A60D78B6A8C74DB6F47E50C3B46E589D59F7EA24A051C143884FEF1C0A1B5DB65CB2C9982B86AF978BD6416617544AEAC67220B85746C4A304DA347636A23780DDAC9A5E79BE26BE127B0D3EB11E8372561C13A998B4B2123EFC24150048E8516CF1A2C6E7FF77090E472CBA93CE350C858B5104E8440CFBACA0D765FC95D7225E37475D048F89E6245A2147207475772F65399EBEBB920569137ACEC2AB035DE7C661B25356F5AE0DD99F016EE6460D999402641503CF6DF3E6F3380719A13A76C6FF6E54DFDB33D454C8E42E0A7B482BC8FB8E12A13E2E8105E876E1AFC9B9E5F28CA61E280D714224F835D8434401979B7635996627125EBDFD40EEEF5DA6D249A7FF15FAC662C9A3044C0D95D2B5029DAFBB535EC065EE675F4B76847F54BA66135126FC0B95D69D6C484ABAA11F60441E50863C7B27306283E58BF97E43E73164CFC143673940E2E723864488E48451F891C687F33BB24E4464ECC4CCDA8813947B54E22C3C368D97670980038BD6A6CAD485CDB8DADE3856069476E6F7D54E772BE8FB2E7B4C6019AD2EBC84DB2BF3D680385A93C7802B1F7534777A8E9C5E060C5F2148A5159140DF4BB35600344863E9F1E86F70BA9815D3051D865C7E6456D624113E6C76521884B1C2B59E6C2EFE4575E125A7E22776A80A756BFE25B0C0A5942C450AEF71AB8ED5CA425A09DF67670908FBB6F3BC4C7E8F4D3B9298E796D6BE36106F22FC6FFC0C9BD4BF1761B6859377EEBFCD5646A3D4B044D3424A743DA85116521A3FFE3C39C898591E669E", + "204DC317928A7EB77DFA7B915FF832E7D7D9F1DA40AC7926F5B8733D661A4205228F0CE968FA3AD4EB5707D184EC4E72A9D6783A3641637957A2B6B22EA8BE95414DC06685CD7DC06BFF16479F490017DC78CE2D2DAD427DCDBBED163AFA58E2539C410BD8599A2DFC66D0C14DF9255A86B928F17094BDDC4A8BE4A202B36CB4\nss = 91961EFE34B53285433FA9F780A04B8E47261E7A6EF77D46658E7671D800E2F2\n\ncount = 31\nseed = AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809\ngenerateEntropy = 9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad\nencapEntropyPreHash = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89\npk = 5E55633267468551B3EE117792C80C1A802230AC805F769807976C06399B97B3C93FB83BDC136CB3CBA70BB4AB5F11602E977ED051115508668C244A44E09569A13507D4009AB72B16CC3BC615C12ADA7C56D50BA6307D00801BEDF8526F0A9366869A4830314D162F63AB8F51996663C1138641275E164DDF60C7708A75376BC235E16D5C22033DE1A149153D1868679E1825F638967BECAB5B9644A6E201906771A703B7844CB5CAB61748D202D38B5B8F03CC45626027895E23D0C1C1B526C6D519620436ED593B58732164A39639C813F6032EB902B05DB15C5D8825C8B11815768D29522536698A751BC1F9964DC579358ADC57EB83A0D2201B9B9354B1B39C6E7008D5F3189902964973AF9A9C694EEC1298D68D3372783D34700B0280D692998B49A9BB76293D7A95363B317670352A71822F415B1C97742934713C5995FE5CA9642C3AC18B73C43357D4D497B3905DF7F58C6566621EEB25DDA29D97B598970684C5780F665243FEB854F9F566177200F9331CE353CD1A23CCE8AA4529BB667D1B9E59B1A312A7C6FF08871CD95C6934419F475C1C08395CE1A3AFF83DD14784303B4BA7751054AA59F5710E4AC6039F3168C1B601A5278562B525ABB11E66193DC9D34446BBCC8163578CB8065F89B9F43407F79246CAD2B6B8B40F16B839A060A95B76855237BAB2FA315DB48E40842F8306125FB04145356BC50B00E3389DCCA26FF048AF5A730AC573B5B80331D2597C4188227682075BC0000186B8FD26A383E1BCE5C19F13B18CB21602F2160DAB202BB07B63D925B71708095DAA662CF25DCBECC99395400A79842F5C40E79B46B5384CE730439F537BBC8A8608F61520E120EA9843456118A0A4CF36384832B12076044C65F06C8F8CC31752469C8A1E33DC529AC05485548A6E075F46A089AA8446C0D465BD43CDF0343ACC9668FBA2A7F7191A9D29BE7E9300CEF33D13A11EDB2B409DE297F30B8A7B077FD4CA4D1AC74B31092ADED0503CCB5818D1834A734E15B74D3FE550EE49773A800D86F129B4E0250EA1C43DA3A3B802B0757C6401EA090F98A28291621341A9D98C67BB001E46E89973F40C1C4950B0E34F07772BA6379FB6A93ECB57369B48B3ACA26EF815C615B4A97AC2190FD2B15E83AA10545FB859635D084A57B0268FF085D9EA4B7EE1763B914E67B33DC46037F39815A1F8C58663C88662B91BAB0DB6758288C682372A269C64CF3AB5C46DE2C8F0F1B7780A068948B9480C6AF10251453C1FE213855D74675CACC7B162917730AE74EC7A8E7673A7D0887EDC175791309AB28E6CCC629BF79C6D69B19269A19488B7B88A45A199841916BA4A2A1C2456A108A5CB4DE1B15356CA737369668B0B5C7BC10E22377D6B5FEF7515B4F348015872E3518C2676079B8A06DE8B53BD189EC9766C04C084E74C6E747C783FF3A99B930547A72FC3A179CBD62B52D46207E79E37D65C9F3C4839D1AFC167AE4041671E2C1BF3324D875B78615067DFE11653E6BD4DD5414579AD8C942081DB4F1A10B0E1054FA3D79AF6A285F2107D4232700676B8A007057D15C923A7889F115762B4C242392CE7C4438C68C6C3FBCCCAE4A071E404C24274F5066DEAF5359EB3382EDA6D6338F166ACD09E376826299B77B781250C2224486EF23D424BDD\nsk = 4DA026F053C3EC1712C7F294DC891E26196894A1B620F97429574EDEE9568E113FEB564D89A1883D5A0329929CA57AC001925C8D616791842DCD291627D61C7C2C3F842B547F074F46F082A06BB4282323A291C3CC07904079125CD5A854168D83BA8AB6B160B5E1881D25403B297C73048E3298287F51529A8BA2DEDA6B4D7665A373171B03B1C0BAAB6482C50CA3A028D485CA8491B1B73767EC9EF8874A54D4CA414895D2E49FB2AC0CC80C9D248B97DDC51D00A10CA3324FA8A6373A99C5DC1BB7A389CD9A3C6931FC7BEE05ABCBA579251B742F46383AFB48FAA514319B8F9A0491F9212DA443ACF9B9CE5B29A6E723A4EAFBA5C1A7B3E017870FB35DBA8A69F1F7995EF2AFF817907DE5C66899824889A760CA4A38A57B3AFA880A3524E138B37487B2EE7332D2689F99A5A3748020FBCA43ED6045A5ABA65F6C67783CB74C217BA987AD381938B4A651B6908FA4F18E6D073A6992160438BA3C9547E4557E1E724192414C912648D25907BD8B069C845465616969161C483927F5D610C815638E242323465839D36A8149BAD494B71F1336A3F0A954369D4265B6CAB935F06694C482B500CB77BB32C4D805A295A692648A31611B206D06C2E86C61675577053A747BD3A748F452B480028EDCBECA8A10EB843EA8A71E21E9B822D80860764D8C5A77EF0222F8004C902C832F1A344758776EEB99C3EC8B24CCBC03F5BCBE59027FB424E6C580CC3B41C041984EA552BDD6396D52867887430A2534A44BA544A0B285C061D7D6618C76945A5C3B29BBBB09A724B1AC53E5954F66708C8C0B2D7DA57C62FC8B80E73D737741F9141F7164B4EAC08822A4C340B5B74CB5C2D407B9D63365C55C14C5E6AB43A8BC68908C34074A9BF4816E000DDB464656C379FDD829B6961C22E5345674243CA64705212D52E616664587F90947FEEB4366A7ABA98B76D9F79A1ECC4BF50571A07CC57E0CB1AF828BB26263A8A898BF3B7B0ED07988E82DBE3C0405D46B1CDC37600570FC37AD9B2237E3032BAB1A0AE420B6F011A653987305AACC8876AC4D014B7E619227B8B35BA2616C9575506870FAD2585549A2F902B185D7A61139C027912EE2A00EE460328B16CCEEB259149A0881F8152D563BC0243302D29FB98CC57A45369517640BF0BF63A555A900269878C4BA567F8D376176D6941D34957E1373B7520483394C3606089D14AEE0917059227BD848BB22E088DEF4194BFCB36EAA81D4DA713E37BE79E52F51BA2C32F05D06405947838625E49F5F6BCDA5E683D014A12FCC0C81601B52F80C39B6659606A8FEA82C62E061A939CB4451869922083268561E16381B026152170104E11F30B2399F4097B94078ADC66F23F85BA6651E861237700BCB1AE92E2BC652CBF19BC0FCA0D7F7577C9C96DBC9B8B07B917F258C15661DA17621DB1287EBAA7714A54052FA660F034F227198EA14C2467B46CF9877F4E0C29962992B560A7DB93C8EC13343F734D86BC548246A57473D1285463D0942F288245D933DDAB7A09766A9F8C178EF539F9CE9A0E97364CAC0366B5B08B4C1B081E01D198C2AA5288617A50019EB3A40A300AF538119D733F2544D18B9094F387A3F4C17BAF01523F1455E55633267468551B3EE117792C80C1A802230AC805F769807976C06399B97B3C93FB83BDC136CB3CBA70BB4AB5F11602E977ED051115508668C244A44E09569A13507D4009AB72B16CC3BC615C12ADA7C56D50BA6307D00801BEDF8526F0A9366869A4830314D162F63AB8F51996663C1138641275E164DDF60C7708A75376BC235E16D5C22033DE1A149153D1868679E1825F638967BECAB5B9644A6E201906771A703B7844CB5CAB61748D202D38B5B8F03CC45626027895E23D0C1C1B526C6D519620436ED593B58732164A39639C813F6032EB902B05DB15C5D8825C8B11815768D29522536698A751BC1F9964DC579358ADC57EB83A0D2201B9B9354B1B39C6E7008D5F3189902964973AF9A9C694EEC1298D68D3372783D34700B0280D692998B49A9BB76293D7A95363B317670352A71822F415B1C97742934713C5995FE5CA9642C3AC18B73C43357D4D497B3905DF7F58C6566621EEB25DDA29D97B598970684C5780F665243FEB854F9F566177200F9331CE353CD1A23CCE8AA4529BB667D1B9E59B1A312A7C6FF08871CD95C6934419F475C1C08395CE1A3AFF83DD14784303B4BA7751054AA59F5710E4AC6039F3168C1B601A5278562B525ABB11E66193DC9D34446BBCC8163578CB8065F89B9F43407F79246CAD2B6B8B40F16B839A060A95B76855237BAB2FA315DB48E40842F8306125FB04145356BC50B00E3389DCCA26FF048AF5A730AC573B5B80331D2597C4188227682075BC0000186B8FD26A383E1BCE5C19F13B18CB21602F2160DAB202BB07B63D925B71708095DAA662CF25DCBECC99395400A79842F5C40E79B46B5384CE730439F537BBC8A8608F61520E120EA9843456118A0A4CF36384832B12076044C65F06C8F8CC31752469C8A1E33DC529AC05485548A6E075F46A089AA8446C0D465BD43CDF0343ACC9668FBA2A7F7191A9D29BE7E9300CEF33D13A11EDB2B409DE297F30B8A7B077FD4CA4D1AC74B31092ADED0503CCB5818D1834A734E15B74D3FE550EE49773A800D86F129B4E0250EA1C43DA3A3B802B0757C6401EA090F98A28291621341A9D98C67BB001E46E89973F40C1C4950B0E34F07772BA6379FB6A93ECB57369B48B3ACA26EF815C615B4A97AC2190FD2B15E83AA10545FB859635D084A57B0268FF085D9EA4B7EE1763B914E67B33DC46037F39815A1F8C58663C88662B91BAB0DB6758288C682372A269C64CF3AB5C46DE2C8F0F1B7780A068948B9480C6AF10251453C1FE213855D74675CACC7B162917730AE74EC7A8E7673A7D0887EDC175791309AB28E6CCC629BF79C6D69B19269A19488B7B88A45A199841916BA4A2A1C2456A108A5CB4DE1B15356CA737369668B0B5C7BC10E22377D6B5FEF7515B4F348015872E3518C2676079B8A06DE8B53BD189EC9766C04C084E74C6E747C783FF3A99B930547A72FC3A179CBD62B52D46207E79E37D65C9F3C4839D1AFC167AE4041671E2C1BF3324D875B78615067DFE11653E6BD4DD5414579AD8C942081DB4F1A10B0E1054FA3D79AF6A285F2107D4232700676B8A007057D15C923A7889F115762B4C242392CE7C4438C68C6C3FBCCCAE4A071E404C24274F5066DEAF5359EB3382EDA6D6338F166ACD09E376826299B77B781250C2224486EF23D424BDDBDCAF7B417DA8B8933279B33068F6FDA313826C2EEC500B224CBE046ABEB37A75A4D0A8A41C4F666854E9B13673071CEB2FD61DEF9A850C211E7C50071B1DDAD\nct = CC162C96F45C1BFE20D4EC4930FA6BABCC176B7B28948F6B3723F9A652AED6B8814C7C2F2BF11BE0321AE217EF12836547C0DA7CA4E7881AFA5C13B089F00249746D4EF05731B7F0A9189F6D092D267F88BD6064B820C0A995D27EFEC31FEDEFFA29BD61E16F35564627B8C07FD5100CF4512AF33689E215D92635278ED6E6135E14ACB1C167C8C3E4B843F4DBF0549468FB047C837125E8E80D453E39C44FF524119149C5", + "5AA31C7CACB5088EEFE93B7D493809A85330A67AE11F188EED63821340FAB8A7E9321F53FA389635E800BA2F6209D36F79EB7099F43B98B484730E95B58CEF65DC8A751FF3CC07B7644C99C243F6A3F314B239233E458A2BCBB6FA612B764EB5051A8DF7343267A7FDEE9EAC48E9577AC389B7ADF2653791184B69942B6191918BB3D6F88B80E208261C8D393002979026E954559634DAA1700FB328327DAAE0FDB1097837E91263AF9EC3C1864B509D98E039B666C875BD5CD390B7219ABB32ADB52EA6C3FD81C52F1A31A3A77366F7A44EBC666F912FBC898EC79B7FE554753B7EA41E0EB5EA366A329CEBB3EEBD449639EB8E2ADE3E5E92C44A587CBCA397077A4B756EA4FD425E2B780CBB3C8104D5CC5DFFC7A38318506BB8993979E0F00897F5F3319526F049470A37C9BCF52B0426332B9717D6336B4E277C363186D1A8F58B6107E382C77B5E25141EB6F5DAF19DCFA95676D2037524772E804D3BEB87E75FFF624CA9F5BB6098E3239BCEC265A88D2D7870560888CDB6805E68177489C21C8B3A2FF9949764F1A8D9D80F91F27C180245A7046717917650FD6F550296D8655F4E546E0780036FD90652C02786910F230A5E2C6467E6EC1687FB6AAC12C06451FAF6B7B2AB3C8C0C1885451E04FD54E05956D2174099E5F691D690A48BF5DE1E67BB5D84288415E429184ADCE1DD7B00EB94C33ABF63F5AE80AF202E772EAA576CD65E65B63ECB1F98FCD96DA6C58D4985021A1EB5A953AA105C73CF9391AD3633919BA794A26F2052878E4607D4489AC7E084009A582731990E8CC087A459470042ACC5BF481DEEFF132C86615A5FB41E47C8D7D18C8CE3A478EF621F965099A1554597BC32FB119367C25DC0373739B8E228DBE85F688B005C9CE688E12142D51D4D06DAC00690C1076702D8BBDF608127F7745BBCCEEDA28CF9A067CF6235742A230506C5DD4B9FB38CB9EFFDB2E97C07316131F7A47FAB847EC5BC93C88275DCE4F1781590043208A838884778A58EC5296C1935DB4F8F32F11C209A697B40726293D18AA908D4D7BFC8C4258F4535295708DC80DAA68ADABED79FC459956E1A7BC277789FA94DFB5CB69EADCA03A0B9C0A21BD5A7DE051FF255D6DF229F306E75A8095A2A511DC372EF601AE9D8A4575A4043380ADDAFD25AC1D044A73722C0255974939D9FFC2B2658C5FFD7F1E7E0F33AC809A1B1648527AB57EE858109D30FD29356D74C79087CBD2FC436DB8DE5179483CF4CCF6511C2CB58FA7C5431C25D1EF9CE8C75891449D738BAF2457E1F8753485E38\nss = E4983D6021D6C10E71F474D76650F7B5E23E02805F755F57A1012882DAA77ABE\n\ncount = 32\nseed = 288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7\ngenerateEntropy = d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a\nencapEntropyPreHash = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b\npk = 420A3005A17C7B4A08178B83F8540601145B102970B3FC29F30A4CA1A8A5BC4164051931ED68A59EFB2B50D549BDC1A65E9909F5AA690B0235D32B1C6B2886CE2959FA189E2CE24224E99255863E6D964D4F422C02646A461BB5ABF86F4B4C0975765A5B0CA01081677334AF26C3467DA771CDF40EC4293608801CAD9C61D5F80839774EAFF772B139051BEAA65632120F00171AD020276A1FBF23517582149AD2C73450B11315CA4B244E7218800350AEB5808DA774030635BC247508144740634AC4A078A5AF2816E9206A645287DE06263277242DBA12AF2A82CE13BA6787C5AC3020E5D30CBB92452985AE41027056F492BB1A5E23332698240B5038302E552C5ACC0443A8795804126E15369AE96CEBD7C9765233982458AD6520550BAAD77BC74296BADCD4CC37240D0163CAF8C806A0CCC3F4125A0874CDC1C67E4626C9C753453FA37B208CAF5F523388D6308248B7688C80F6C925895670A1397880933AF0152DA1E54F7A7B512AA87499F7A718E62A7CC5BF5687ADD09060426B0D3CD292AB9B8372083EE462182872815CD740FD69ACDD24615110BB618CA1EF662715F028864BA0872B8C199ABE40F35F91906A821B8CE0742F931C661C65AA2445371A300E68F23B767382F3701CE685CEA5F59C50E82E45234169C3BBAC814AB9D68F83842C513A8FAF475590B3BAC2E3A4685B8F71208357D221AE41310E8454D315670C3A3409A2A95258B9057B42DEF7A7C6F588F6DA61183ACFB18A7CEDF138C7984B50A940F17C687E5A2F83451D94398F4C82C93A375BE195B4B219232E9A766E77040D3B9125E70FA4097D807A6D25323342508F2490A59702575D64AF146088F59802AA2CAB3537A8B4E92A10EC447BD89F9FE738D92A5F83C2861628601E42BB427B87C2153D4BC44B19413B79BAA5EF55325BA8A42E1A88548155D03AB116E47EE0455F0E5A71BAE3A03EF476F77A9A9CC6526DF1ADBEA64930B6995F60181544356C0982E957C5E5186F321B9467D05DD5970A96E226C89673E50A056E7C0A8027ACA8A5CD93723353CA1991730DFEA1AEE943CB0D62537CB5AD88C14F52A78CB6228EF4750EB7DB0AA831A4202B178EF47446A06A17E7CAF5274F384B36832A07AE0A66069BC59FE439F7B6005F064D865B550505210768BD636C61F0E7A1BDCB3C3065908D51302EE234A3FA113A1A1A2A618750075A6EC277CBDAC535FC1524A62E3C0601AAD1C46026AB6B8495C1B7093F776F9E6B3B533267AB99801E83BD18570166387F14ECB4D279B86CFBBAF90649E5C514E432561F850497D47C2BDA1BC2C398B306751991392C399DF6F408FF836F989C41CF76234B9445D9F81F4AAA987C1721C0C726EFE44C311A589ABB5E0AFBC4ADD9BFF6F87597A52E16A53D6C3551B7E6BE0A1958A89A739E0717F0A86BE0385C5CA433B68AB9506BA3A6E00DEBEB1AD0519E228B5B2D9AA3C9B4A2BFC8B35BF0A04B5A9D0154AEF1A9478DF4C8A0354F8878331F76C8CB6851940C996109113446367497CC73D395B34A9C7DD9621C9BB277BBACA6D976C3E65FC3FB4588643AB523BB35F551F1F30D0CD1C40D14B09429215E0C5325BB2B069B85C9E0BD9FA841771AA7C9709046B442990CF89513930F122152632A3C3D7C15C8018E1C23AA33CB89AD\nsk = 1F83902BBB77A97B032277079CD0CA70D09D57385CE5C1B3C08B80ED95B2BBE70C101CC1912B71B29B87DD08254B593D616A31FF4957C7C0C325F82024F6A7B125B0FF799FFF47AFA6A9A7055382BCA08CBFBA71EA1B530BDA5A4548922C90C6DE8927494370EFA6C96780086BF585AE6534DC05344DC1941EF793EAE214312A371ECCCEA680C1A166BA97E128064748269922C9A19CEE4B8A669ABD146491ABE31A57B724F3A173740269A33309F651C934E09A564627896150ADDB8BA181CF2503256512B0DD5588F4372781F35CFC0328C0DAC842A1B3F418B6E8C567F410568F2C6BE8EAC9BAB558DEB08389BA08BBAA50E1EC5DCE044EFE5830743402402A167A9369E1D281D37713EB656662600840409C4FB971C0FA7771BA53B6C13EBFFCBB85AAB3316A3A99A9CED8BC4596932B3D052FBB13A5CBFB762AD7A08CA4AAF33862B6325BADDB0E56D395E8F92EBC7347E847956B471695C978DC2431EF7286C0E0A880F7871BB05160209900C0C403DA599B988A8EF0A716A9535B71002B3BCDADE60053F5A8BC66419FC907F1EA718B7BAD6BB76FD3F710E6778587C36BA5E4C2D7796185BB72C5FBB839B6C91119AE6C954E9B66C3EDB500D884428BE2C7CB6A6C86B807A6059739E23F70433D8A7A4AA768975AA6B0C3924CC8827CFC731A464121090A685820068019197F489315A2274A7133422B2968830271FC94B1C775C5A21E3B07BCE543B32F00B7250CABD0D04A2529347848830C975261A54717324533EBC0EC627F2064BA693A9BF9A16FCE87A8D7270759A06C00EAAB71A5CC25034120445334A39D63BAA2AB3254D77A921209750F6869E6971D05DA1E1BB29CEC9CB7B4962370E5C139BA472A75114B28BBB8E7069C5A8201B730DB571C1EE0B10E1C42B4A97FB7F7AE54670D12859D68199443157DDEA85760445895E7175EF8BB919C7213F427301C4F6561AFFFB0B03CF1AD05613C52DC5CA71A74545ABE77D239576303BC9678272873D9B28F4A4AACFDB46940F59B0A82A75642A0CD794D63D03D43F65E753A6AA2B58E0CC664A48CA3D8A3B18C7B05CF8293D3E23FDFDA93506C831455B648E2017FD866C87683AB307C6FD9CF24212509D777F34B0618776864EBAE9FA5318E739692C5AA86648D49778B67F81347B434CCFA990EE9A79DE94C94054E6E4A8A152B5F4757B89F075A27AC464CD1801D02AB64BBBA4F932C0003458FF73011282BF444961C54C5275408C4F79C3C553424AA4AA13A53D59B1B785C0FFB686FDA185D5438AF5C494D98B80381C821C493BC0E7797CD1995DB681EC9E18859A9229C497CC251AF12D9CFEBC6A19C599C9D364E587C7D32245145A60CEEB54CC7EC5B541B71DAE959C800A747EAAB53F8CD24365C91F53B7B0B9D3630361D41ADE4C82C85E04D8BA243763B3F9DD65D60921F962337A3421051D36889253A423939ABEB0AD962CE1E1A9931C960D9F4948723CA17A731ADFB4834615693F622470225CFA7B036B931A2240564CC35E59A7ACAE48707491576CC1410A304E0885534F577692C5A237344A5F674EC7C45BDA3242D70B004D5AB620CA2B1AC0A56C0CD5B942529B054E0F840E3C1837E0053539B4A420A3005A17C7B4A08178B83F8540601145B102970B3FC29F30A4CA1A8A5BC4164051931ED68A59EFB2B50D549BDC1A65E9909F5AA690B0235D32B1C6B2886CE2959FA189E2CE24224E99255863E6D964D4F422C02646A461BB5ABF86F4B4C0975765A5B0CA01081677334AF26C3467DA771CDF40EC4293608801CAD9C61D5F80839774EAFF772B139051BEAA65632120F00171AD020276A1FBF23517582149AD2C73450B11315CA4B244E7218800350AEB5808DA774030635BC247508144740634AC4A078A5AF2816E9206A645287DE06263277242DBA12AF2A82CE13BA6787C5AC3020E5D30CBB92452985AE41027056F492BB1A5E23332698240B5038302E552C5ACC0443A8795804126E15369AE96CEBD7C9765233982458AD6520550BAAD77BC74296BADCD4CC37240D0163CAF8C806A0CCC3F4125A0874CDC1C67E4626C9C753453FA37B208CAF5F523388D6308248B7688C80F6C925895670A1397880933AF0152DA1E54F7A7B512AA87499F7A718E62A7CC5BF5687ADD09060426B0D3CD292AB9B8372083EE462182872815CD740FD69ACDD24615110BB618CA1EF662715F028864BA0872B8C199ABE40F35F91906A821B8CE0742F931C661C65AA2445371A300E68F23B767382F3701CE685CEA5F59C50E82E45234169C3BBAC814AB9D68F83842C513A8FAF475590B3BAC2E3A4685B8F71208357D221AE41310E8454D315670C3A3409A2A95258B9057B42DEF7A7C6F588F6DA61183ACFB18A7CEDF138C7984B50A940F17C687E5A2F83451D94398F4C82C93A375BE195B4B219232E9A766E77040D3B9125E70FA4097D807A6D25323342508F2490A59702575D64AF146088F59802AA2CAB3537A8", + "B4E92A10EC447BD89F9FE738D92A5F83C2861628601E42BB427B87C2153D4BC44B19413B79BAA5EF55325BA8A42E1A88548155D03AB116E47EE0455F0E5A71BAE3A03EF476F77A9A9CC6526DF1ADBEA64930B6995F60181544356C0982E957C5E5186F321B9467D05DD5970A96E226C89673E50A056E7C0A8027ACA8A5CD93723353CA1991730DFEA1AEE943CB0D62537CB5AD88C14F52A78CB6228EF4750EB7DB0AA831A4202B178EF47446A06A17E7CAF5274F384B36832A07AE0A66069BC59FE439F7B6005F064D865B550505210768BD636C61F0E7A1BDCB3C3065908D51302EE234A3FA113A1A1A2A618750075A6EC277CBDAC535FC1524A62E3C0601AAD1C46026AB6B8495C1B7093F776F9E6B3B533267AB99801E83BD18570166387F14ECB4D279B86CFBBAF90649E5C514E432561F850497D47C2BDA1BC2C398B306751991392C399DF6F408FF836F989C41CF76234B9445D9F81F4AAA987C1721C0C726EFE44C311A589ABB5E0AFBC4ADD9BFF6F87597A52E16A53D6C3551B7E6BE0A1958A89A739E0717F0A86BE0385C5CA433B68AB9506BA3A6E00DEBEB1AD0519E228B5B2D9AA3C9B4A2BFC8B35BF0A04B5A9D0154AEF1A9478DF4C8A0354F8878331F76C8CB6851940C996109113446367497CC73D395B34A9C7DD9621C9BB277BBACA6D976C3E65FC3FB4588643AB523BB35F551F1F30D0CD1C40D14B09429215E0C5325BB2B069B85C9E0BD9FA841771AA7C9709046B442990CF89513930F122152632A3C3D7C15C8018E1C23AA33CB89AD61E27E954728E2E2E230C94FF009417D7372938E2C29C38AF22184EED530FA1F36B817736CBC5F7B1DD6EEF5FE6332FB1A598F3871E5470D440FD2EA631DA28A\nct = 6EECD129797B2891B41E176111251FC114AF2179FD711D4D4C6F0E825AF1251C686757EF29970B63D621AD3FD6087CAAE604D416E06F444465245F34272980672E099F0BE19818760FE474F0E299AAFFFAA6551A0592EEC262000456377E54AFBF5E217F39D7C8C9B19E03B472EE47947580481B451B535486C28E3C61E983BE8A5802469CC95AC9CE38BBC371BD45F9783D0DA21253A478A042427D490F0247C8542648488416970BB58F7F0849502361149DCAD935AF84987BED520EE79D3FDB1B6D478652C892ED1BE4BE91601554D092F0EA15889D4D6B3D8BC38D0A2AB98B19A2213BB688B92325236CBE248B183A6C94FBC22E89250286ECF018AAF17416196F3D1598B63A6A3A780147197895CE6A814C130984CE05A9FE30870395E4289144B529B1D1E04ED3207B0130EE490CE86C49966DC6F0B58DD651D9E650D7F6F7B6F2B6B398CB3DEC5DBCBEEDF1D448892FED8C9EF32D681608E5ADA2958C3D47B0749AAFA33B95B1DCA91E6975EF842F1702777937450157C1B7739EE03B73B7601DB13747C4762AE8245D90D706636BEC3EFAC18F88FFFF3E2068BE9E18FCCBFE34FF834D937BE6413AC20A3E49C9CAD9E7E5B7B7E64D10A99C8BD916E2F3691706A2F64592CEFBE5563B68425ABA971D80A2D7428C623D42099F1B37B679F0EF039528374FA8F7A3D6D4C0A6FE7A110F72636B6C2668ADEF2261530BAB8FB057D26551D97A491E735FA3AD4845ACB832EF4EFBA71D565962AA94E46E17849FAEF065C888912AAE678C0C3314C8A05F2007F3AE1DB1AA4AFB1DFB3F74E937530953FF48B280C389CB13A42AB31F275318885801195B92FD167D17A46FC897E4EFEE985279195889E58C88F88C9F907B9315FC66F9BCFF1D2F0B2EFB7D4ACD7EBA6AD108B5220A1EC22D7EA83E85E5280D2BC06C62FE7615635EBB5C2C25507E46FFCF32E19A3E662AFC952511B2F0AC509CE93910D995A26AC5534CF2B181D624CEC786B86AF927D4BC1BDF396EA99F6DB7F259E30059595A654B2381CE1419E75A5B175455E127E7F1AEAC0B8903CE4F0CC6F26C72A40C358AEDF833AAE85B975F1B4EFB40D7C4A1708574CF0E98A2E787B9C68E568B465A53A0CF492BE54BF76E0C804BF51A5B74981593F3088367829CA08683986EFD8C9D777816158139E8EB22B6EDD93030F3F279E80D958C5592B0E39BB831AB6826A7923D8A2208B6C2D2BD8CD32604DE47722AFC0AB9E5D7FCCA2CA1391AE4AF8E43A5A878229D54EC256A6E42BB89750E97FBF3679F9FBDE1EC3D901B82CC45330BB2CAFB861665542A4FD34317A12CF9C75F6D9ED49FA081FC31212874E74D2F6514040C69A70CB56453618A4F983E63DA0ADE52BE5840A9508EA3BDCF70313173F018485209DC8DD229E36F854C778095C2C85D3B5B2F8E23EC88608362AA183D028F8988C18EF88373DB13CED999479A325FE49E9DA01844E1CF37D5BA098AF7B8005F1F1921B850B4CFE545E7F0441F24548DCEE473BD11846F0B6EB9CC412672CDB0EE\nss = 807703887AD9601806D0BFD5F9D9B6CB01BEE01F82500F525CF4CCA6E4B21FD6\n\ncount = 33\nseed = 4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44\ngenerateEntropy = 684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6\nencapEntropyPreHash = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7\npk = 63992E0D6A8F811B3F0D30807456C84C8BBB008D3B126A31424954CBC6CDBCE91E25B19928F4A41B1371447BA3D173915580BBD7899E9ADCA37B4B5A21E715101717710BC7EEC56EC2E58002127D1898BC55F8A3BE385D607B3BA6561991AC6F0913617303830DA25F0CF0AC14E67ABB8097D17B0AD1EA8C6C267ADF51A15A9A363D7AA5C8EA535A89115C984AC5D6BFA922C6FC44A3B35CB667F939FA6B2676BA212C17BCD25C82E8172F6A7506E8B77D82CB21D7066DA93A7EB3CAB8E881A24C7592BC6B656E459AF33A06FC2846D71221F1DA641004B68BD65DC28A59036CA678508614B15A93E74F89B8AF58200D50E718DAB1C41C4556CD47B43F14092CA47397243983406E12E423233C90CFEB661A32CE65AB464DB58C922BB693F56553961868B064E17A11162A7F0E3AB0B0AA76B8494BA394C902C598C23721DC16C51D46B8258C635763776B922FCAC747985B94C006696F18BA49D0C5EB0525CAD1349745691320969B6BCFF69C30851B41E66AAC3353C6894AB0097B4EC49783CFE4960D61A6F94B317D488D2D04A8B42C7FB7D89D52D89B2DE30336333C50895348870BBC311611F27845C7775128A9CC831966FCCC06292D86B582A18C6AB2FB3CCE03701BA91047227A9FCBC6F16130710756C5DC288BA92402B5B7DC90C39193737C206F3F8230261852F1694258D47C469C7452156E70634384825BC52B03E90720066B609A4102862433E2621987E23AF51121BED807810501200B776F847FF615C0F594420DC29CA6573276559C1C84B0723569DC2A76728909D9D1279A8C240A3979B0B44003687A412389581B8EBF0CCB06C797F7F5815CCBB434132ED5F1340E2C669430B13A709F7D1612AF876454F06CCB7841F84C60F3806D5E423CB34B23BBA90AB630403A46783329707388A1F4232785D4723C993CC62284D0E35242E52CFD6981268B86F598B11472900F83333C48627D402ABBA59C6740B4A40ABC3200B5D9E13010FB4DD6BB503548C777256E0729905A89BB386459E0B885B6E3017C94BA93C7518F017695F5BF5B99214C8555BDA863FDD11D40053C0D652696286D2BA14D569915E4532132527CE1B88122640AD668A20964476DB20AFCA5CA663C6C17156AB3CC8E4B723B3A5209D2D10767DA52B2443764F91A7F3AABB35137EE18A1F744562E22385716892CA77D518C4BEC578E0F1145B3241C1831BF782C760F9081A1191812790531648954163B10E6A1F02B2B9E17CDD439C6707AAB0DF09236BA33D9B271196A398FF0B2C9521E57B6C8833489C5328F4866C14D2CC1CE037400DC610B28CD99150404A175662102F9617205C1CBC24B5716C7B9B0E8635BF960BE5B632A976156C64078CBB23EB86B7BE9A2D3E12F5B56406CC51796C66A6E871DEB601CC767C0B8E45744346DE60BB160808210506C5779BC275940E000314F30555677689F23009A583CD6F9779C83530E5B2A5A0A771BF1376F0091C627AFECAC104FB2BA251C074E359E5FC44DEC244CCB78423532A7EB27C8313A341DC1431035162838835C85C677A420B67C847DC6605821587C8064E0BC2F4FE6A6B22113E73519125B92B3A66F15564666023EA99273D0D5657CFE1B1B3BBF85039A8189076A3752784E23D8A802023FD0743EB03D989A6968\nsk = 8B78635AC351C94BB6B1D2B861E4914DCBA415F66CCC465B370578E136330A2C5CB0CA2857E1CB733A75E5CC4FCDF7A12580017F1C0FF484401CB23318A98000637B3D065608678103940D8BA75CCBE58206C130ED62BBC0132317B6556A9C2AE8F71A43712002D795CA52007782652D291DFE535F75034B0D624277527A6EF623168AACFBF721A9E8753195B82EB9855467322AAB0AB1701546C470AD139944B6736E1C97C9768370846B45693AAED9C80A7B53B863830DF61FE9600AD5717BFA2C8E59E30C8A20179B27B59341C855677880330AFD1A227B6C6313E17C46E87D109A4AEC4C1795908DB6046598483159907A667378F80BCB84472D5A748043B1BAC10BA5BCF61B07A2B13B12C347F3253E26C25EF0AF6A003A67B0BEE98A7C5A489C9EC9AC1F042C6F2BC7585CB01BB4B55496A93DE903EC974398E277CA7CC25E3265A879420EA0BD8451716AC21F1BB806C12B3488D408EBF18B89B79B1F8C09EACA235F1C165F9504FF987139590F9977513EE037249B4E25E51A296526BA76CD3295895A571CAC279BC65642CBA501C8F131EB52B5C7CB73B17757440B1EE4E9295D404177E542BD744AA587738BFAC0EF3C1FA0F19B0A5C5E28B53C2340C7FA061AD354C85AD26993087B61AC2002795D5ADA7A3E6747AB8110367C824988CA705B818D7A921DBA33371405AD235B18E463A8AC88180C88F071579FA5AB6D904A2F53B03F7C7EC39C473632369F984F8CC66DBD1924206A6376706CA36601BE7B16EDD17E93CB9A0437B3615374329B0712794F5058790D88182BE4863293133A83AA00E07C8E79C6F12C33FA9437ED984A1392903DA89BD43184DB6C8DACE3789AF5CBBA092010B889CA98AF99E5B0B3D4399BF61266E833A55A85E11784708B98EFAB223A27AEA1A16E76A73C2027759FD97A7DB870F9FC79AFC89435D092DB556E0A738C133B259F86C98D78A43A49744F306DA8CC6C9098A5A9CB091C9BAD94970F03B543D669A9AA4944E0C08DDFCC1D7D485FA414B0765A88F175AB6C94B12A2177DCD4998E6AA263EC3FD5BAA2466CA04568869466887F7BCF636C7A1F084277532841F51C3EDC5C1873BCE0F07A8871740C4AA82BB5AB164916082B795EB0660BE32DA9972840C927B7BB4061343D56757258BA4C91624F21DA11CB265B00B9AAFBB1665679C86EABBDA12B74F1C5917101D0EA2BB293C71AD5B556369378A8D5B7297C9731705DD4493DBB173AD01458686A93287B6DA0A6923B913989B69612A915A03A0962379BBC466A03F5517AAA0C0B030C6CA420636B2EE8821916E9C7F2BA228BB2AEABBC292F6C07AD85C6F43CA90D42629759536046394936C3AC5AB979D5CEC1A1CC19B5C1", + "7EDB47B0F47F34D616027B29A12725BF14B62FBAC4F2CC6EECE89CA0467D4868C11C17299373687B657D132C55785080F5B87F0E3C1504673825B98E8A0AA35F2C8D84F41B060AB43A930E7BE1C9D04746169BB4AB403ED8C74AACB868B4A93F1DC55144738E2736749AC64170CA7D0F0348A9550EE494466A49617B541068F2C57AD4108AB813DB58526C7647D55C1CB657CCD1143343AAA8421C23BD0C822F763B6A82B7D0041648A143BCC43163992E0D6A8F811B3F0D30807456C84C8BBB008D3B126A31424954CBC6CDBCE91E25B19928F4A41B1371447BA3D173915580BBD7899E9ADCA37B4B5A21E715101717710BC7EEC56EC2E58002127D1898BC55F8A3BE385D607B3BA6561991AC6F0913617303830DA25F0CF0AC14E67ABB8097D17B0AD1EA8C6C267ADF51A15A9A363D7AA5C8EA535A89115C984AC5D6BFA922C6FC44A3B35CB667F939FA6B2676BA212C17BCD25C82E8172F6A7506E8B77D82CB21D7066DA93A7EB3CAB8E881A24C7592BC6B656E459AF33A06FC2846D71221F1DA641004B68BD65DC28A59036CA678508614B15A93E74F89B8AF58200D50E718DAB1C41C4556CD47B43F14092CA47397243983406E12E423233C90CFEB661A32CE65AB464DB58C922BB693F56553961868B064E17A11162A7F0E3AB0B0AA76B8494BA394C902C598C23721DC16C51D46B8258C635763776B922FCAC747985B94C006696F18BA49D0C5EB0525CAD1349745691320969B6BCFF69C30851B41E66AAC3353C6894AB0097B4EC49783CFE4960D61A6F94B317D488D2D04A8B42C7FB7D89D52D89B2DE30336333C50895348870BBC311611F27845C7775128A9CC831966FCCC06292D86B582A18C6AB2FB3CCE03701BA91047227A9FCBC6F16130710756C5DC288BA92402B5B7DC90C39193737C206F3F8230261852F1694258D47C469C7452156E70634384825BC52B03E90720066B609A4102862433E2621987E23AF51121BED807810501200B776F847FF615C0F594420DC29CA6573276559C1C84B0723569DC2A76728909D9D1279A8C240A3979B0B44003687A412389581B8EBF0CCB06C797F7F5815CCBB434132ED5F1340E2C669430B13A709F7D1612AF876454F06CCB7841F84C60F3806D5E423CB34B23BBA90AB630403A46783329707388A1F4232785D4723C993CC62284D0E35242E52CFD6981268B86F598B11472900F83333C48627D402ABBA59C6740B4A40ABC3200B5D9E13010FB4DD6BB503548C777256E0729905A89BB386459E0B885B6E3017C94BA93C7518F017695F5BF5B99214C8555BDA863FDD11D40053C0D652696286D2BA14D569915E4532132527CE1B88122640AD668A20964476DB20AFCA5CA663C6C17156AB3CC8E4B723B3A5209D2D10767DA52B2443764F91A7F3AABB35137EE18A1F744562E22385716892CA77D518C4BEC578E0F1145B3241C1831BF782C760F9081A1191812790531648954163B10E6A1F02B2B9E17CDD439C6707AAB0DF09236BA33D9B271196A398FF0B2C9521E57B6C8833489C5328F4866C14D2CC1CE037400DC610B28CD99150404A175662102F9617205C1CBC24B5716C7B9B0E8635BF960BE5B632A976156C64078CBB23EB86B7BE9A2D3E12F5B56406CC51796C66A6E871DEB601CC767C0B8E45744346DE60BB160808210506C5779BC275940E000314F30555677689F23009A583CD6F9779C83530E5B2A5A0A771BF1376F0091C627AFECAC104FB2BA251C074E359E5FC44DEC244CCB78423532A7EB27C8313A341DC1431035162838835C85C677A420B67C847DC6605821587C8064E0BC2F4FE6A6B22113E73519125B92B3A66F15564666023EA99273D0D5657CFE1B1B3BBF85039A8189076A3752784E23D8A802023FD0743EB03D989A6968672E53B28D579974D268132187E7BD72238639C6F2CA154D50D98C74096EC33075D12195EC32A8686D0600E45D4A7F54219B0D7A3826D193A51B9156ECF2EDD6\nct = F145A8D9CE4F94ED02E2693AA6A5458962997E212A3DCC11C56BAF8DE75A68F67C69EBD87B212596C90201BEEAB5E2A0DD8FB0F9C3308EA0B0797A6921E7B7A036047A78F254ED699393FFC4B904EA2E00C7CE3D149BCA5D763C2CCDDD386EFA74DE0D1E42E1F7E96B1B92C346F5610612E30E970360DCDC541435974C33976B13B069270DC5D78072E9CBC434E92D7B30CE2459812D5A25D33AAC97D3DBA1A4ADBDD08DA548DDFC83D22EDCC5015B09AB361DF9AEE747572A4229E6BB5F5FA85579BF47DF4525880A6BE4D871D38E0354DB9FDD331F8A1591566938C747F14F388395043FEBA7678FFE17D712BF651D544E6F307E30DE4AA7022ED3B758D306C8D526C29048BE699A9E5D77EE1CFA5961AFDD94C867B46D74FFD16EE258E6E8D3F4BFCA7D810796A2BBF456CB5D00ED9C736286B2E57D10633227BF7B91BE1B08361C90A57D6D4AEF79271B1AC6E2295797671B7F0C7DBB5830D2EDDB2B7AF062BB73967964C0D740F7BF562648634B40E5F2DA69260FA4DF1CB9A99247157A8911B8C2916E6307CB684CED9FD738C05179931992BD64F7541699F8DB7DCDFF73085E9BA500FC1E7130CEA36E4C67183179654913E33D9C47D76A3FC74F553BF32CC2B0167C4D3357A7C5CB26428FDA06A3BFF9CEBA276F2A412B21E04216A052BC4C201E5D36BB704DE258D30E5CE1112D9AC8E0940C4035789A1C3C2194A3FDCCEA8F4FF9CFECC01CFFAE1334013113ABDBA5D6574167D1AAA2B95257AFE1DAA39B8EA30F7F3843CCBD2B0DD373E9CBC9CE254BDBAF462A0486CF38EB7F90B5A7FA77D007636641639C7BAAC4563CD27B44D9B104C04990EB0D45B9FEFB05D987B64A5FE8916F906720628961490A91252DBB44972B7FD2BD5C11292F40B6C92317BA3641B4DA563FAAC61972FB552553CC006945311B8C79F88F7A59103306565447ED94AF5C2D1C10DF6D5BA6754932FCB98F3AD1D47D39394AAA810739E1E326AF312D94605198FE30E7174EDAB76391D4956ED0E4C2AB6954D38E00DBD02E76F2357C350F7E93C1974D2C1CBB3C638604DBCAD41790E7E402B80261405A52C2A0F9F0CE637A769CEF5BD800CFFC976598869C24FD9F8C83C55AD840BEB08EABB33877C2CAF3F8328C2DB2E575254E4F129A1E969D91EA02C77000ACDBEC1CF6B1003CA9C8AF77B22F6F9E8E831E4196585450B61E0E9AB6ED12B703C990FAF295FEB56FE39AF4B9DBCB2447B250FF4C13078FAD781A6CD5703FB4DC4A49FFA0FCC342E3638C6FC407602818E0F3C557EA1E9455272929E63B6BF746882769C5C482A413901F04623DD386186392922E0CC3B051F87C4783A90702B0FF33DD37AA924A2557E7461652444C9DFCE842DED51BBE97336FFF712974A3B60344FD9A7898FDF1F5BCF9AA6F0F28EA66FF64A76EE2D6080AA47C8829E1E8292185DB9921A4F4B3FE28786AFA28B25E87BBD63087A08A9234C6F12351B7F622A00F81E46462882936219FD8434CEE7B5EC0F18ACA21B13B5C995918B13B852121\nss = 9D28091B20946B5507AE42BC4355A71ACD2B5EAD20D4181B22A5031EC53CA00F\n\ncount = 34\nseed = 5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE\ngenerateEntropy = d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f\nencapEntropyPreHash = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65\npk = 192042D43A4271E44D1546306137A4427130C86A2025BCC297EB36D3C44E7CD4B0B1C22005FA702AC12569BCCCCAF6AC9256A1693C8B677C5CA243B9C8556CB3A268165596FD0470400CCF5E3B56714792F7A87B9E03019751425695AD70E4CE0B2769571901C6C2003B58152FA9757922BD28A094771B0CB1DCC73741B14B402E8AB86DC0F647525C131E9AA1A9729075EBB3CDEA4D31F6C3B23A5BCBF74A3C653D4C015CE5F65FD1042A137453462B8710704BEA463204C463273BB71056378850AD28F37EDE664E38514DD735BF9AB9B95D367C54D84FF085650AD33EBBC982A329C6FE3A516EF387BD0A0417C2655A5476F51A68CBDB4AEBC53F00C11E78E5BA6692A516C076330C20D0A09F167BBFE1C956A619825A8305D1AA9AC5736E6D24145924B2409A8688B41F33A181A9E4858325140A797F2BA81D50F21AF88650CD0BA8E662077708551A947C97C0A3355852A77576CA5B054D3B0B9FD973DADA618BD02FFF1CB59EB56B12C71B24BB1F02E27282D21281493AC7D07A20B124AAC30B7BCB8C2FF24B2C927D3D62ADE0357BBF7C1281FC94DA2B21D10A5E5EE07A3FD9CF93E34615B871C8DA7DB5441020D0522C12711E1963BE54739BD43949999083115988A09C6020CA88124B35C34EBFB0743B494B2666CCF5B5235968275FABCF9A054EF92833D8EC816D68C07FC53634A02CA192A411C87DD1F17FFEA094B6868638716CF593B33483591E4049E4E7C65C8618B242B17D6021BF0A70C7C59BC81C34F5441B063B9A1D95481E6529602B95F874BF1C649D95A072E70A52E9252E1DD1BCCDF64332345355F7CC48EB7DD1AA2F2C31AD1FD58B8B3A711D113C270A90AA2C5C79958F3907AE3BA071AA6144B88BA6C5575BDCF5331729A65D8ACF3DB97ACA4191B72A2BC1433FB3483EFFF09698C291DD868275DC5A86D06D97305BA596515E434A8D956B2B73B3C00821BA055AA7541E4F35896113ACFD9320FA91585F3212CFD5B023A77D7C5C0CEB746723C2C7D7417BFB740E4BFB2299B29F987698EDFC1B8D7B33DE2C80D0CBCB44F05B1DDBC667005B6E4335751AC281022CBCFAC0A55226FA69CFF845007B9A16D2B6BAB3135B325B12C263A81FD423120A6FA639910159B693406411A289863736557A028BBAA23E0C984F04543E61916D9BCEB4F64FD48823A4B13E4F83B43D443F62ECC72FD304F71772CCE318C1DA9A57A67502A1119313B93C4A66D03C2316C2CC5C2285B1E80C413B2F29C447DC975923D9100BEC9DB958ACD7850AB0777D82814929121BB87A6F4F07880510331EE6171797BDF23850D5FC1802E432B2F51B3CBC37631C9729892B6A09BAF6717E6EC39EC2B3489B33BAF257C35B9CBEFFDC1A1334380FC35DF386116BAA9BAD3A0A8381C4FDFC4B1B98836F23AB923175EAF72C59D9C500E10944FB0FD701BA5142B3CC358BFAF2732D643D0B135C8F991B0C73789C465A7E1B3EA6804B5AB9AB2E42CA1E91158019306855A5767893BCD17E92A41470D721F6432448FBC370C64C3E330D83987F3A9479F000C75320A296393E253A68E0E1C05969784F5612ADBAA2662459B09638202B74D8D5CBD2B01A915AB2AD06B08670546D8B76877B8B2EAA1ABB3132E55D8BD5B08678BFA4243430BB4D059B58A4B0CF0FD26E\nsk = BDDB6A1BB704F8B530860B719752402098C84AE4809B01C8EC7583A66A3F4BC290BF2173ABB41868225606D54991F5B547C2254C74391717045997A57BA534A97B3605E1AD9F7C6446AC08BBFB1999179BB8F67731A63CE1C717F30B57FD17BC00605E8E14127EB0C26E324AABD45138484A51A15DD2464440178CA7E966D4D58383F6BF9BB2A971729074781A8D978965F9A51EB2729BA8C308474D56089F2CC869B523C41C409507A671F0F3621E057662454D49C49A", + "398343D64CCA74B7822D773373D5185426B7B3951256154A7B78CB1F5049DF0371B840AB21B83944FB383CC84AD9E24FF42B2731276C1D26B6120534438B029C4AC7C0739453C2860D32ACD75229C63A23A7201C303032BC0A410319035D38A3C9802D41A56A8C6C2496DB10441A2BCD13A81F90CDA2564CC9E4020A47595A30994888B383E996115AA282EAC3E3594447110C2D07774F9312D796C6B74A7634B6C0DA2291458A35D3022BEE048483461CFEB152E1D2CA9195AFD1F9AA82131804D35E739299C539B913C54A0C58683259B3137AA464B9C6E03B0EB751999B6C5354D6171C78CBBEF1B456EC4C88199764A5761D18C0849C1B0A263EA401B86CBA549C712E4A251830F7B6EE16B2BFABCA3CE018C3833BB881385C272DEE151AC35A2C9561B3C1266855219B0C6B485E669FCBC49B24C50C6C3237AA6B116085085405115E0422D956BEAFF9360B58BF915654B9B887AD9733F425A5C6990B3F0223D8099BC0E95C6A5702CF5667209ACE08FB4697D02DC45CACA8074185F54EC4641B35BACD2F0B770FC215FDC171C98BAA7AB6C0450BA6E47A838575A528F7BE221C3C91F02734269A9425A2EDB76CB6D077ED76040A716D39C9C87A58AD8867954C752367A905AA158E0A9019DDA50A6213C260F7BD8A0A6E8CF581FB74CB17283F3A1A8AA9A0418C79A948199365A6A1045238104280AC704B33791E156A2377BC83E9B9C86D0A3D2AA3287272BE6431BB4E598232312D10D03BCB13B4D838A9A624566C6A25FA44A0934AB6CC333E6D52AF3EC26A6FB97615CC3C77102D1A315486BC69C555A3E8271660222A406022E8D97251308A90A15F748153C1168CB133593C1641E164C8A06CC008059C55449413C2B28667B99122AC42B8BFFBC15FE395003249C676DB7589D2896E7405BEF8AC510782FF204454C8A0390C332CEB7A5A3123EB1A1AD0470096058358BA779DF70106E24990DA77AAF09705110993F16A2320A941D8865B387236CB8528BABBF2D9196C15898BF71040D3BA500CB7B1AC85DF11003A058D838C2652D4577306023C756AE9715136E91B20699FEF425E48953FECE15BAF27489D929876803EB0B5764E6338BF5970C2F35D1E815BB5B0B1BAB630138859B729923343C3D24922A8522E38E19868B8A4585ACF14B795FF3A609D93B1A5CCAB08F877C5B71EA78C2819113FB3632D5D995B02926663F2AB8E3A73DD6AB93503192E0243F2593618E3A809684BB6A31674E77802828FEFEA3A50FCAEB1088F7EDC036CB84329C988D965071E97C1311643BB1CA2B43CC57C84CD5EA9109AE36DE2801CBDCA3BB6F977959578954AC17D303841D5726631663F12816EDAB5192042D43A4271E44D1546306137A4427130C86A2025BCC297EB36D3C44E7CD4B0B1C22005FA702AC12569BCCCCAF6AC9256A1693C8B677C5CA243B9C8556CB3A268165596FD0470400CCF5E3B56714792F7A87B9E03019751425695AD70E4CE0B2769571901C6C2003B58152FA9757922BD28A094771B0CB1DCC73741B14B402E8AB86DC0F647525C131E9AA1A9729075EBB3CDEA4D31F6C3B23A5BCBF74A3C653D4C015CE5F65FD1042A137453462B8710704BEA463204C463273BB71056378850AD28F37EDE664E38514DD735BF9AB9B95D367C54D84FF085650AD33EBBC982A329C6FE3A516EF387BD0A0417C2655A5476F51A68CBDB4AEBC53F00C11E78E5BA6692A516C076330C20D0A09F167BBFE1C956A619825A8305D1AA9AC5736E6D24145924B2409A8688B41F33A181A9E4858325140A797F2BA81D50F21AF88650CD0BA8E662077708551A947C97C0A3355852A77576CA5B054D3B0B9FD973DADA618BD02FFF1CB59EB56B12C71B24BB1F02E27282D21281493AC7D07A20B124AAC30B7BCB8C2FF24B2C927D3D62ADE0357BBF7C1281FC94DA2B21D10A5E5EE07A3FD9CF93E34615B871C8DA7DB5441020D0522C12711E1963BE54739BD43949999083115988A09C6020CA88124B35C34EBFB0743B494B2666CCF5B5235968275FABCF9A054EF92833D8EC816D68C07FC53634A02CA192A411C87DD1F17FFEA094B6868638716CF593B33483591E4049E4E7C65C8618B242B17D6021BF0A70C7C59BC81C34F5441B063B9A1D95481E6529602B95F874BF1C649D95A072E70A52E9252E1DD1BCCDF64332345355F7CC48EB7DD1AA2F2C31AD1FD58B8B3A711D113C270A90AA2C5C79958F3907AE3BA071AA6144B88BA6C5575BDCF5331729A65D8ACF3DB97ACA4191B72A2BC1433FB3483EFFF09698C291DD868275DC5A86D06D97305BA596515E434A8D956B2B73B3C00821BA055AA7541E4F35896113ACFD9320FA91585F3212CFD5B023A77D7C5C0CEB746723C2C7D7417BFB740E4BFB2299B29F987698EDFC1B8D7B33DE2C80D0CBCB44F05B1DDBC667005B6E4335751AC281022CBCFAC0A55226FA69CFF845007B9A16D2B6BAB3135B325B12C263A81FD423120A6FA639910159B693406411A289863736557A028BBAA23E0C984F04543E61916D9BCEB4F64FD48823A4B13E4F83B43D443F62ECC72FD304F71772CCE318C1DA9A57A67502A1119313B93C4A66D03C2316C2CC5C2285B1E80C413B2F29C447DC975923D9100BEC9DB958ACD7850AB0777D82814929121BB87A6F4F07880510331EE6171797BDF23850D5FC1802E432B2F51B3CBC37631C9729892B6A09BAF6717E6EC39EC2B3489B33BAF257C35B9CBEFFDC1A1334380FC35DF386116BAA9BAD3A0A8381C4FDFC4B1B98836F23AB923175EAF72C59D9C500E10944FB0FD701BA5142B3CC358BFAF2732D643D0B135C8F991B0C73789C465A7E1B3EA6804B5AB9AB2E42CA1E91158019306855A5767893BCD17E92A41470D721F6432448FBC370C64C3E330D83987F3A9479F000C75320A296393E253A68E0E1C05969784F5612ADBAA2662459B09638202B74D8D5CBD2B01A915AB2AD06B08670546D8B76877B8B2EAA1ABB3132E55D8BD5B08678BFA4243430BB4D059B58A4B0CF0FD26EB86D5B13BB8B72A9FB81245AB712F0D10F0E2E09B222143C420E3F2C3ACEA27B248C0A21EA0BB6D6F56F12300E8584D8E9A34E0E6F52227281151AE4C305FB8F\nct = 62CF02A7A2D09168AD13B88990D97D6A9B0490491EE43B8234B585382834B03FBA539DB1958800624B86051987EEAF09091C288F6564383E1AA98094850CD37C2A695D8AD8548B12FDC9FE827C63A360135EAC409C76D0A8B2390A64F012161A2DD3AE0DA8F626E2F5E053520C6DEDE4EC8D64B045B278B1E140988B3A13DA6ED4DE14513E04FF00EE7B07A05A79CE27FC8A183582F2F987B44B95770083CBA46A2E2DC384754D0ACAD94FA54EBF73568552318EE862C87D22315A7BB4126B2ED7D9E190456EDA589994EAF5991253A191FE3D7156BEE8FCB9A02213A477339507BF4A1CEEB0C64AB07D1B9F3A492437269FD8E932077C80EA7E3701F6AAE89718C2C96D6C46244A3A1E760D0E758A47A5547D403DEE7135E876345D0B725E2218A9A004C567F5BB00905A00039C3B6850CF5C8EDDE3FC1A4118118EF1EE524D312BF82C3F9A089DABAD769C4D459C414F06BA28DDD48B86E079367FC77285AD70D0ED6E46BE65DCAE0FC2A68312397B8E2771EDA4911E4C09E88D0F3055D01DB4B3B1ABC968EA78D8784CC0A0A429490E862B3A6FA629CC335873B55E88E5A0F320125BB16C621C4CA6ED3C69DC3B190D595EBF8685E7A22CC63451209D29413E7260DA471B602F9C7203877D69FB0DB331BA950F0AAF45C8697704A3A641CC04999907D70BE17EB56D316D6F196941E130AF65B0C1E4555BBA7A2C69676AB4AC7CF9FCBE9B498C46998A396A5175F06D31887DD119C92A02788909AF9997FAF43D148E4B00751249B6D569D16758503EFE6B808C5909DF65485AE901A32000D0023F034CF9A20729A7901049EE12DF1A1611F609F060DA51B0016A988054F5805D37920BB7DF00E5E7B99C19299567CF93CA8A9C13516C7B8CE59E0A71B6BDEE58290911D9B44A26D1C48400DE5C246AA5FA3159324BF31DFA3D1F223FB2472FCC0674D6FC19B0B730F2BA7DDAD33428A78E087F751061C7E21AF59F3945151DA4F97BA65064E8D4792FDB1A29D9B9ADA763A0F743CEE9A535A19A2260258BA86F21F0874A8782F5F36883369A655CB3D622C8F828EE4ACFE15B534B8D81775E0CF0C77625A2965C8820D1EAE140D940C1ACB3AC9C216DA291588C8414B91DA8E08F5B192CF007CED7F1B1110670F877B4F8132E6E53B3D47B4147129407BD14AECC4250BC5F054E3C25B255B1F15583B4DA510347A6BFCC5C0C25200D9DB9ACDF58B1E2B7EF968D1D18DE9C67D05BDF49C28D8FB4845CF634E490DE1E99D8398123C9730FE0CFC63B5E34B3E7D73A970A1AD1C963E442B9528D8530DD38A6DEE6FD64C24093BB650E1D6A9C79C05A9282025185DC4A08BBC50F1E335931490638283EFCC4618F2023F06407F70F076B30A7C3A3799967CD707E578A2EE156CFD9249852E5EDC08CC27A1AAB18A0846D066E61596B928BB6C994CEAED604C0ED5B42F9AE38756E8AEF19C47CECBBA7A56FC7EE51E394D0B8AD32DCECD50031C047C519CCDE7EB20E61D8944D5AFF66626541982FF2DA65F211D85F5E89D8BA\nss = 98498206D1F4D3C94A054C3C3A6087760B210D2F3628C71CCF3F0ADE9694ED7A\n\ncount = 35\nseed = 4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4\ngenerateEntropy = b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71\nencapEntropyPreHash = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335\npk = 38E84DF3C6A2DC2389897C3745183E08C1681B5B9F57C16AA2C12778528510868964122C1747662CF97D8B0353BF23693A70B3B2A7C8CD5C5508A227261CB7C3022058E318D3DC39E320770724351AD78010EB423FFBAE6714999226895AC23735A9119622BBC0811516D617353C7F769628925BBD49629FE0AA333D1909A16C5C27604B7DB0B4E602AB27987DF23C3718630BA4C2846444B83FE914D840CC8ED79A85B645A32809CA069FFBB8B3201131CB129DB9282B73174F8D4A14A37393552B109D2271EDDA8D968AC3FF67AA3374A2355C2EC895441873325DB71C91020E91F19347D965F1410F606862F69643216B869673B5A70583FD1218639B5036CC11D051A13D219F3969C817326D2B60BA5C13CD8CBC9313AAB478833D73716A2A48438FC529084C241BCB4FD67179D1F5494B4BAC2B05A5767B9647EC8829A500D1365BCA7B8CE7B75BFEA0C68F8A28EDB7BC4A3817C0D32C4E10169832B9ABE271CB0B473AAC2C3DD39CE895551A297A61F47162D97C41F051D48B62E5A8882DA62FCEE16EACFB89B98A12AB626E69D77CEB3B6B02878CE346AE5CF754C3F6097E0B5EB7AC80B9B8CCD9418F63E545D01C7D17A71E45EA3A6D927484D4976CA936FE392CF2052535C201DE9464008C932617CAD94085C5816AA41973A8D21610430AC4B3080DD480169258E65B53E340759BFB70D68B15B868C4098847901A6B255938ECD15D5EA94232B2971E3BCD56205FC6F0425F50AB880821F56C7B25F51F2412CD7FA023852CAD04F2704D4103D4362E965473ADD3563D9B36E509", + "7C982506865454BA30AF132BC17C807309723847257C697C525E27CC570A88A1688134F4193DB67EFF018F54751E578483A77A119210106FD03066C403B3303CE54B39493323C4334D4A7A20AAE04D8EF529A15CB7D0900FBC4236C717310246C9CBA14D6874BEAC61B566593B5EC5887272B914EA655D254D595824288A666F10C7DA583F933052F43B0B0FA59248B0584F193AD548A12A845FDF14A73A0A37ADFB4D1845AFE6B56EA50B00A5503CB542C254A26F456AA3286B0126350272638EF0B4A3ABC56FC8D0AEA2F7396D97B64C56817D58C32103996DB88345D377FB7B2644FC99A24258C50730045B897AC908F7FCCB81BC2B51C286899C8C499C1757C6B0A6AC0A8482159D564CDB746037A1224CA72177F79ED19A398040426664ABFBBB7B7BA99906E7982B665A551881E0F02A97409A3E2ACD37FA96A4F9293F786A11B21E1F0BB22CF400DA06081BF68111A9BB64469487D4CBC10578106B381B8B054EE29339E1830DD613E19A9BAF9A81C2B9AD1D121A47D40234BC9D4B79C2F5F165BAB5A2DB68C59C0737E0E4786990A92476AEA44105F3C77FEEFC342B458E4310B9B110A8B2C01593B512F069944828A3F6A219354BBDBB1C344F24AA0784160CA704BFD89C4933B6123C4434CB9A6CE16D3F042F1FC571DB728119F6A33E4A9F6981193D60BE6AB916818B8E1FF9A1D1A59DE8824F808043A1949A5520B675D8834EF65C1D47AFDE2710C6B63998D43AB47A681F0A856D166C24494081E076D5FC05B541145D3155E232A5AF0AB96ECC0B09C2C41E285D350500A4F8BB32E99B4B05D558EA7918A7881BCF516457AD2C3AB72EF2E04E3A4ACB85A987C2\nsk = C6389F081CA0932AB66F658046C1278B38BC42B5C4E1A7C7A51B09D8A159773B67AAE1C2AA8666000C6E6A014B5C0369DFF147688AC6FD48C73D783E3025C92D782A479ACBDE8A7548384B763A868C46178345A773A9852016B9FE765DB0BBABA5751E8056B7564C53FEE8040D3C0125115D323C62A3F0A2B518330B6CC4ABCA84F62C792D07C1E1A0BBBD7C5B9A698CB683981F8828EE69912600311A0281DBF9C6C9E69DAA26A446D136E8B0310F236D7A5A49B2BC616FD346C3462AB09544998C8D5EF641E7B48C35BA7A68F25414F703FB02B501C69C58A9B798C8C76923272ED9BF432208BAB30F2DB45E1CDC56F6EC11792A33EC1A62B3FC992441527E63328A46003DB49B7DC07F73F705CA0220DE94BEA4967213D612B5A03B2C16A9BD4C66E0AC893263169A87AEAE67843944628E6374B5518BF40919840B8E6C64172BE3A35EE5A29777C035463380203072EA50E7DAA4F906D01C502560621137B91649C97417CC2D3E1677006226D4621073CB1AA213525199BBBFA78F1899A53CB2B8D00819869867A41B2F48C615EFE2C8DA15A4E6965BEF0C4207A499A2156EBFB611478182D85A71C9F8776D28051D1A6E4A104E54615992E0595CA9B0CB2A0AB0159575863F3145B3401498949502B2EA4392C77728215F8700C93F5846A1A8126EB6B72248BD1047BBE62AA58737268428509E53575F945735E75B42DB2BA2F21B24C990A847241D2C3533B10D50847C85D98143FBB2EB5138ACCB055A8B8BCEC8AFD7B5697306165AF982190821A14301EF0A90C3D829ED9035430725A99C67745CA415600D10D7C29B228998D7402EFC1F0D0476C4D74C34754AF9A1AA1213C9A0198065378DE2D023EB73B3A4BC5801D98213AB7040CB63318B8395DBAD6C7C604760CA679B301AB08EF1A948A5A83DEBB39651310B368C736A56977F78AF0916364F278A4E3973374213F7A28BA70296D1916FC65CAD3B33C4E1597F818CBC489BA970680999C373DBC246740C07D97C5E1EA5AA1D627757F4467E84AB9C5BAFD9BA484F1212706788CF5AC1829C7FF0A66F26C30AAE327BB7E167BDE95FB5829340B187162A5FDE3A7CC6A0A05FDB6F26902BDB0C6C4F75692E67AB1C8B1B46A40E53FC901DD892A3E612AFD1CB2CD52BC5B0C3191137E602B0A5872D3A961EF7168990B634F438B744375D75995943CAAA47E3CC5DC634432B6CF2DB29B637A5E22559A59971BE46004FE2A40F7C330610377A5B0EACF79D85F3C86223A4C90C31C2495314748601431FA1F49ABFF2575410AF33F7367C5540084B75D6736ECAA010290839EE2456EE16BBCB57C601F26AA104916254A689C24CAE98296E4BCEF8770ED7485511F55A46C75592C88D6F76005356C397EB1E61CAA04BF55A05C8409E644055759A7E60C1C8210221FB97780B92C2C8AAFB6B94C259A9CE6291E18A801A82456B93C221A625129A1720328F11574A5C35C3650A7B57619C61F47ED6319329F118F4C31358A26A7E9191CAB61012A71B27B47FA13CB0B2C959D913A2F4BBB3D106AB695A4C13D41256A0B442F0428DE78F90609A11B8CBB475083712539E1AB034903C30F6B73BB8229ED50F901B142A597E7FE48B38E84DF3C6A2DC2389897C3745183E08C1681B5B9F57C16AA2C12778528510868964122C1747662CF97D8B0353BF23693A70B3B2A7C8CD5C5508A227261CB7C3022058E318D3DC39E320770724351AD78010EB423FFBAE6714999226895AC23735A9119622BBC0811516D617353C7F769628925BBD49629FE0AA333D1909A16C5C27604B7DB0B4E602AB27987DF23C3718630BA4C2846444B83FE914D840CC8ED79A85B645A32809CA069FFBB8B3201131CB129DB9282B73174F8D4A14A37393552B109D2271EDDA8D968AC3FF67AA3374A2355C2EC895441873325DB71C91020E91F19347D965F1410F606862F69643216B869673B5A70583FD1218639B5036CC11D051A13D219F3969C817326D2B60BA5C13CD8CBC9313AAB478833D73716A2A48438FC529084C241BCB4FD67179D1F5494B4BAC2B05A5767B9647EC8829A500D1365BCA7B8CE7B75BFEA0C68F8A28EDB7BC4A3817C0D32C4E10169832B9ABE271CB0B473AAC2C3DD39CE895551A297A61F47162D97C41F051D48B62E5A8882DA62FCEE16EACFB89B98A12AB626E69D77CEB3B6B02878CE346AE5CF754C3F6097E0B5EB7AC80B9B8CCD9418F63E545D01C7D17A71E45EA3A6D927484D4976CA936FE392CF2052535C201DE9464008C932617CAD94085C5816AA41973A8D21610430AC4B3080DD480169258E65B53E340759BFB70D68B15B868C4098847901A6B255938ECD15D5EA94232B2971E3BCD56205FC6F0425F50AB880821F56C7B25F51F2412CD7FA023852CAD04F2704D4103D4362E965473ADD3563D9B36E5097C982506865454BA30AF132BC17C807309723847257C697C525E27CC570A88A1688134F4193DB67EFF018F54751E578483A77A119210106FD03066C403B3303CE54B39493323C4334D4A7A20AAE04D8EF529A15CB7D0900FBC4236C717310246C9CBA14D6874BEAC61B566593B5EC5887272B914EA655D254D595824288A666F10C7DA583F933052F43B0B0FA59248B0584F193AD548A12A845FDF14A73A0A37ADFB4D1845AFE6B56EA50B00A5503CB542C254A26F456AA3286B0126350272638EF0B4A3ABC56FC8D0AEA2F7396D97B64C56817D58C32103996DB88345D377FB7B2644FC99A24258C50730045B897AC908F7FCCB81BC2B51C286899C8C499C1757C6B0A6AC0A8482159D564CDB746037A1224CA72177F79ED19A398040426664ABFBBB7B7BA99906E7982B665A551881E0F02A97409A3E2ACD37FA96A4F9293F786A11B21E1F0BB22CF400DA06081BF68111A9BB64469487D4CBC10578106B381B8B054EE29339E1830DD613E19A9BAF9A81C2B9AD1D121A47D40234BC9D4B79C2F5F165BAB5A2DB68C59C0737E0E4786990A92476AEA44105F3C77FEEFC342B458E4310B9B110A8B2C01593B512F069944828A3F6A219354BBDBB1C344F24AA0784160CA704BFD89C4933B6123C4434CB9A6CE16D3F042F1FC571DB728119F6A33E4A9F6981193D60BE6AB916818B8E1FF9A1D1A59DE8824F808043A1949A5520B675D8834EF65C1D47AFDE2710C6B63998D43AB47A681F0A856D166C24494081E076D5FC05B541145D3155E232A5AF0AB96ECC0B09C2C41E285D350500A4F8BB32E99B4B05D558EA7918A7881BCF516457AD2C3AB72EF2E04E3A4ACB85A987C285441CBD71C18717E9DE7359B920A9A3BB7F32E619806F4E4718C585085BE6241646460817A0FCE5836BDFE124A7448E7ADF7B8ECC2652AC6D280E986682DF71\nct = 47F3F5F8E8ADECA6F32B9692FD13D7E042FD9C7612634D5E3886871D5B18006B8BCAD0E4B8E91BF063FECEC9E54D10A2980C24369FF8ABC2753EC4E45BFB30FBE64CF5BD5B53F3101913B558DFEFC745D3C5CC96C1D71607A933E98314C340330BAA8EF4A08916E3A2A98177D4C1FF6C499BE66949A14D44361383E6A6C23A5E2A99856126BA269BF386889B8493CDB375D27AF17ED20B504E74F2A9FE4C00DE019EBEDD147591F8A53266C56A9ACE2DF3DF3CF0182596D78B07A67FDB0745CB0B6457F4467A7C9563947B2BD0B112819AD2471B8019C3AEA82ACB84954717CA91FB62099AEFF49F81226704B8D268177FC77A422CC951F1CB68D25028C94203686F3A43DC95611AE78FB30BDC987992B9BD810C362E29C8F8C4C50B94A4DD640C70BBAF28A2C77643400848B0EE5E4991CEAE312F0EFE2FA0B90205E170F44F8708CA30446F83DD743989575425F5960F30CB8A2A36EA62E9D2FBA6F13E555366191B0EBC79C0F8D0CD0E2F25EA617370675CCE484125C7B6699F3A83B265F43FFB29C72499A9BE90AD58660FC69435EFDEE5C5EA405106C09B00EA849FD9CF7AB0F4B55D12690C1E65C4F5369F32D337E319BFAC00D8D8EE8FC4697A5248C096FA4CCF6D95203D85D9E2AB4EB1F4953B761DFE76DB5D987EB0167A535C43AC756A68E3D08B99E71182F2FA3D13212671393DC33DEBCC3F080F03317128ED38CE785C3ED0772CF86FC7411BDC840AD1C754AD6E871EEB8ED6927EEF33148D31DE4B4B3EF5A7F0885B4E9792677480F518C250172D985981CECA7117B79EE38C99092BBEA8FA1B0036FC35BA1DDC545130BC23DE8EDE4EC7A2908A1C8D3FEBD0C1EB811CDC90B74BE2C0A4AB7F2D75828D0BB7F4DDDA80813D381016795F49045F31C0AEC4FCAE74134F5E799C2528DB055C1CB3C748ACD9DEA26B07A817594B902A76DF4AD66F641C65A609514BDC608103609387DD7BD80937B791EE7D14928EC937C6438D62E7C05EFC089D3FF646E8C04A03BF00094E3B04DEE0B81EFA2660392F03DF2CA7DA4231EBEC0CEA1C57599FF84617E3458D40A762BCA1DD3C777BC790B7C366980B8D2FB4183FB71B7472E448878D7F50BE104657302EA90FF27AF7CE9AEA771D7201C8AB3EE0754F77452E8056D96D4CDDCB69C1458A5117713DF0FB210E98B8270F378BA4C551CB469B10014422CF48009AA936A5E0E63847235214AC5D62FF0C4628793D7C4B9659967450ED3E1365F946A7A0445590D260FA87CFEAB8DE4F2BE784738DD534D0C6EEA04691C21396A406FFB15006D4E5A19C137D0776B63FC37AFE8618D4E10208823DABFFF3C80BDD953B758B89E81108AC146D05547C2E3139ECF4E2F3FE41125AB7D5BE50CDB427D46C2768EAD3940D3F4CB701EB41DDE06A191629A3E94082F203B2736F6DF03E206D2937860235B6E4DD1F8AAA4BD95586CFE18BF5FE4522D5F85E77C0FCB472ADAB84DF092C4CEA53D14E0FE7703F3FF8787827555697CEA6A8011E4E525B8BAF", + "1ABB6E216DC617\nss = C93350D1F27F771801B7C3E03A2E7672146809D37F33BA262E9E0CE7809B2187\n\ncount = 36\nseed = EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074\ngenerateEntropy = 056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411\nencapEntropyPreHash = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732\npk = BE390596BAB505E51B3FC147AF616E0F94506635A758964B3E7CC067B80827DB21DC87450FE1415EE41FCA8A2B56B355FFF13616622FD1A19A7CD98F5084610D1AC9F1B8A6E78CAD9281A0AFA5A7C2A9A87916710EC9C5B3544B76B4808D01399F219B745962536026C79841F11961B63C10C99074EDBCB4ED786F7E8C3826609533E5BB4CB80F3E515299EB757C217DA2806D26664F154C0CC2B4A644B224933502ADF5A66F5B54CD45A71589219AAC65BE0623CF5B4C0DF17E72CAB64B91BFBD903D75E164E2A0C9E2C997F36A0B432177DE617F5E6746BD82984BB9375B4A0A12E96D06045A3A984667D03D8C08CD980B59CB2B0983B13F9C53790FD43653E78255882F9B0C980EF6B062789332A6B67B2B78E9E370B78181531846B9980A8AF905FEF403F47B891A6B440EE71CC5D6BF3BA5C7B087A31123AB61EC9F2D0C89E1EAA7DAC36613A15F147938D32673402164B001975D9C4A8BA5CE84D20B47F26EBA5909183C6FE1343D062389B9B99CEDD21E30D5841FB68F3450A47F4C4BE5E8C413C37EA4D5AD629141D7430938158CD04492BBA8AEDF7477ED13A0B97C8217A300DFCB22DE05449547626D21409F491098162D7AB477E3EBAF0E15124F449F08E47D8EC6847A0AC839BC5D237B3D509A8B5C44C8FB6705A467A3D4D9102FF2B6ED976CA9D856E9F257D5D586C7D8A4C2617DCA73AAA65719A21538D9E6997C5637DF8C5A2AB98A169A5BA8F708BBA55F2C0A9463C9B4EF0C9822FA64ECC72C8BDA4030157BDE5073FAE6A6E6F036121125DFC5A9DCA1504A1225E6DA9DB4D0665F6413386153AE25BE78B3410369BBDBD84A86C6C7BC924DD70005BEC0C54E07B4ADFA2DAEB8265DD98BCB8968A2F683A3B07633AAA0290550665C01FDEB22398ABA31140FA7494FD6A0087194673F51AC7D759D649A2FA4D7520FC67138F445287B681F5C3D1678B497129BC6624163E3515C8381E85C173D6A4CC0038DFC2064A213C557931E2E7138FA1A6BC3EABA08965BD803BD5759332CB1BBC4C41337BCCCA153905990970C261CF63A53204B6F8CB228D4234F08837425A82F1DA9BE43775DF88A20A0381F70044C76B3524B437CF365CB131BAA14EA6F24502336762C8E126AFD009E1997B8B3BC20C246070DF7B33BC9A7BDFA8CCD576925968915F186CA4A5A4934528DC75282E246B0824EF7118D39DC1F07449A218836D47CBB7365B677EC7D6222ABAF33068B5730D9E674CC008125226CBC5382A76A9823DB1B42976C5C90C23BC02EB7B874DFF93699E6035A838B22A7126AA42D62682505F9BBC77143DCA061F5C38E99652FC2E28E30CA8D62127AF02186BD9C95602992E20BAA636AB050AB870B11C52DA19B3A68B7A07A8CFBE7BB016A2537E50464265FF6F065D7A8C30F659998A35D79032F887B4629D07BB2DC895F09AC0387CCA9C5CD1AEBC08A687798721F24CA43C2C5AD42D1B6641838EFC2A72EF210BAD10218846F25DA336A4C00C4A29EAC8A608F2261B8C76B18F10B7ABA755771376DC7B876152F9FBA5370262919511D4AD50D76AA5CD6566C29225DABB3B668608D9DE5BAC08320CFC3570A0AC8DEB4BBF3D941F9325AAF546FC368AF005CAAB7AC6A7DD70D90506DDBB5F53A83079ABA0927BD52A68E278D3F01AC19EBA6BD\nsk = F75196A57024BE817EDC544DBD552F6B42BA121C2B8EA95E55017856A10C5905A8BB2590E63B449364802C6B438FC19EEFC875017ACF652A8F0D6AB0F7F5ACA1F1833ED3551D37419D906D2B55123EC14D5F109ABCD9382E990628BB30D882CCA8665957346C3A08553C870D32F77E66348CA9DC321960B7D50B09DE64178411439C021899F2B8C583762043A4508C3160544ED2264735C600A6AB43C8515532130583298A11450AE3B7C99FF559A1D33115DC2D2489934518BD52FBA1CB9A019D918464B59CC90941599253957364DCCA9F95A08035F8BE5BD36DB6B19F1F191A6E4B7FCD493B7A41C90BC76FE882AA0F3B39B6F454785C5DD1D106C80960BBE5846D90BCDE837CD277A039DC22427B86A6658F97A60101665F3F69125445647F3BB2D3125C80D89AAE6096A01C24902321933909A8A2925FAA1E7407B3C90C8A53D958C1C83465E557AB620E53509EE8C960B3C547FEA08D4FFA215742113ED9661B57AE1B30BA5768645C632DE76B96161A9B6C34B8DA48B75D176C2C849AAD55C6680BD0863273C345C4C7379CF3F873FA5953F53B9A026A4DC120C96E279085566C7D090EBA276A0928693E639B5564A59C08AEAFD25915F5478DD86E938A11529BB9A2B0B83487C696E79F1FD034EF000FA502328184BE42B8959D9C0683F3BC20E71902423AB14A4744E162F6A2B474DBC4A6F21FC0432CA7422CFB253D0F952BE9C13125458DF8753F5D551CAA38BCCA1625B533051C5226C8768335854E7477064320CB765AB9EB311A1859B4B5A006D918BD8508A971205E6902897CF95E0B652E09030794B46FCF7A784560C0A18B8E6334A57EC177BA56A8BB9A857013C6B9998975379BB04B540015A14A76C658F856BECCA363CB37997BB85B185AA0104063696F1020BD1B443419989798826E141A24A3533494391FA233CF848451CBD609D014508FE137534C42D6F22ED2CB82363C847865AA243CA993B14992572CBF5535845CC708BB09A1E8A7834C200D8036768755AFAB53ABA85813EB859EE83EFEA7563EE4BC158599F0CB04033393C829AEDBDA289ED852E1EB1FEDA9484777051F967E048041BA3C313A1414D463CF3EC36801AAA1AA540DEAB122AB530ECACA30101A1089087311972B338B045A1637189020C3030E63F707FEEA9AF844C7E1B20B4A5348C1A432F341BB9F598B8C0C2F6F55C4D2C2C22B187430748F82842DABA92283DBC4BD20636B6754B20A7127F01FCFD4013A1155E4746DBF3CA1F34991FE7C39ED99BDF5760D39DB8E6C428F2DE8157BE0139415AEA96BCF6FAB633F2257B582312D3C7ACAF6A5F8E55AD699672160CA01246545059E58502E28199CD0F5505ADCB91900A283F0B059F33D1A8B352010A3C815717FB3A9482C946DF0C74A526353D5C9ECD2590C5050996393A02286841580AB599BFBC8838A53301BB11D5FD492AF40BA26224505969D88F6B193EA42B0348954180E17124EC2C64B962A92AA9C3FE2D72F94301531C4AAF847243702BC8F9C37D64B54F20AC003B844C52417E1436D2E75AC09C313C83B8575E791A7C95D0412CC61521A6826997561485DEC26AD7BAA8E065E9A279ADD7301C5C74C5B95C1B6915EBE390596BAB505E51B3FC147AF616E0F94506635A758964B3E7CC067B80827DB21DC87450FE1415EE41FCA8A2B56B355FFF13616622FD1A19A7CD98F5084610D1AC9F1B8A6E78CAD9281A0AFA5A7C2A9A87916710EC9C5B3544B76B4808D01399F219B745962536026C79841F11961B63C10C99074EDBCB4ED786F7E8C3826609533E5BB4CB80F3E515299EB757C217DA2806D26664F154C0CC2B4A644B224933502ADF5A66F5B54CD45A71589219AAC65BE0623CF5B4C0DF17E72CAB64B91BFBD903D75E164E2A0C9E2C997F36A0B432177DE617F5E6746BD82984BB9375B4A0A12E96D06045A3A984667D03D8C08CD980B59CB2B0983B13F9C53790FD43653E78255882F9B0C980EF6B062789332A6B67B2B78E9E370B78181531846B9980A8AF905FEF403F47B891A6B440EE71CC5D6BF3BA5C7B087A31123AB61EC9F2D0C89E1EAA7DAC36613A15F147938D32673402164B001975D9C4A8BA5CE84D20B47F26EBA5909183C6FE1343D062389B9B99CEDD21E30D5841FB68F3450A47F4C4BE5E8C413C37EA4D5AD629141D7430938158CD04492BBA8AEDF7477ED13A0B97C8217A300DFCB22DE05449547626D21409F491098162D7AB477E3EBAF0E15124F449F08E47D8EC6847A0AC839BC5D237B3D509A8B5C44C8FB6705A467A3D4D9102FF2B6ED976CA9D856E9F257D5D586C7D8A4C2617DCA73AAA65719A21538D9E6997C5637DF8C5A2AB98A169A5BA8F708BBA55F2C0A9463C9B4EF0C9822FA64ECC72C8BDA4030157BDE5073FAE6A6E6F036121125DFC5A9DCA1504A1225E6DA9DB4D0665F6413386153AE25BE78B3410369BBDBD84A86C6C7BC924DD70005BEC0C54E07B4ADFA2DAEB8265DD98BCB8968A2F683A3B07633AAA0290550665C01FDEB22398ABA31140FA7494FD6A0087194673F51AC7D759D649A2FA4D7520FC67138F445287B681F5C3D1678B497129BC6624163E3515C8381E85C173D6A4CC0038DFC2064A213C557931E2E7138FA1A6BC3EABA08965BD803BD5759332CB1BBC4C41337BCCCA153905990970C261CF63A53204B6F8CB228D4234F08837425A82F1DA9BE43775DF88A20A0381F70044C76B3524B437CF365CB131BAA14EA6F24502336762C8E126AFD009E1997B8B3BC20C246070DF7B33BC9A7BDFA8CCD576925968915F186CA4A5A4934528DC75282E246B0824EF7118D39DC1F07449A218836D47CBB7365B677EC7D6222ABAF33068B5730D9E674CC008125226CBC5382A76A9823DB1B42976C5C90C23BC02EB7B874DFF93699E6035A838B22A7126AA42D62682505F9BBC77143DCA061F5C38E99652FC2E28E30CA8D62127AF02186BD9C95602992E20BAA636AB050AB870B11C52DA19B3A68B7A07A8CFBE7BB016A2537E50464265FF6F065D7A8C30F659998A35D79032F887B4629D07BB2DC895F09AC0387CCA9C5CD1AEBC08A687798721F24CA43C2C5AD42D1B6641838EFC2A72EF210BAD10218846F25DA336A4C00C4A29EAC8A608F2261B8C76B18F10B7ABA755771376DC7B876152F9FBA5370262919511D4AD50D76AA5CD6566C29225DABB3B668608D9DE5BAC08320CFC3570A0AC8DEB4BBF3D941F9325AAF546FC368AF005CAAB7AC6A7DD70D90506DDBB5F53A83079ABA0927BD52A68E278D3F01AC19EBA6BD065FB6156ACAAC591F1BF3CE71C4A046BE8C6C55EB9A84D29569BD2B144C73E279238A80DCFD7C992D84B2DFFA67493E669243D4FA38C46B090BDF86BC548411\nct = 8E4B06F53205ECA407728FC67D6329388825377114DA064425E780EE4F23C8CC01EB544DC02C70950C6F2193FBB7959E5459325514D1E76FEC98ADFDA3CD84A8FF0AB0AAC32A0E6C0D184D6B6AE5B020F3BCFA7612A8A8469E3B97CFDA17BFA20080B493451DBC852E9B59055381C382C12B1D8CE94AF1207408F2909E2BFF4C38F7D244182441DEF635C7B46721161597105271DEFFB3EB435F596D88D3B60BF26EEC93DAC19BB52DC05605668D9789EED2CC785112ED45B098D7CB1E26FEB3582FD505D933AF94265B100C998A7850F3A58937E6B3EC8FA19F229021C5441B93FE82B7D20B23EFACB18DB8208A141844386DAA9CE61BE318B0B410AD2C3FEE8B448C649908E282F9D172E62A507F26D1ABE910D98EDAEA3E8429CE1144", + "522BFB938BF0509EF0454DCC4DB999AEB0F9AD283A3FDB5EC6BEC935182FAEE081F8DC6D42CF9DEF8296F2C30A691A2ED84E759A8EE4F3AC8BC3498AD3F7B96C9140647E81339107F1614E0DA2B0F53E0309F19E5FE6584C37F2931BB1BCF93B9FFBEB1A10B0835B27AB81672B2C2E65FE7D1B7F2C75B4247A8FD03F5BB18B0B45693495C5DFA4DC3C50FBCA60347AA9463333AD7CF27743FEE4E0C50D439834192E4F62CB29B3BF7C0CF222403149796916D4067F82BD26F00ACEDFF40458FA66DCBEA64A0C1F885812F505B120292487294D531C077C376D90489B70D51984E35B687C5DA6A153564A31515CFB9E484EE16F2B0EE8910AEFC2CF34E9328BA1DA84F5FA671C4E043BBBC19C032E7A871A74A9BD5F2F3A9722465861E19646E6ADCEEE098FD3356B6A7E356DA59052C2DDA1462CC1711C9B3162243E47E3BF45930D6F3313994FB1CDA44C60C0871AA424C9796AF27505D0B743D7AA1E2D5EA502301116FB607DAF2039FD6DDB1A5FE4D5A6D53A32E7AADC7C7AE0E8EE23F8F55A8643EAAC5A8FA38C1C631DC65F0EC02D3226A85092847AACB7C03A412BF89FB046606CB3B0C2AF16712286FE4EDAE49FC7A0526B2BE181C0074E62E2021A1F80651EC53A24E5B48F5FD20058EEAD3706E40FD8D9F9FE81212550425F2FBC3D2049035B267617696DE3EE56A11B4F6B7D9BC0EE61D570799F7BDA55065BDA83A15A252B1F587628F9D082D9F969A776DED5EAE9364BD9628C1FBD70CD288E515614ADF9DB015387AC8CF37DDB74C05080D993786642243B04F9DC44DEE0EC2C396478F8A6BDF08A0174DE3086A39FB0E555E159E862C997CEFBF359395D4D1EF80002EAB509144A619DE33307411919A90E35168AE2953054E0D2CB5805653BD6A9DE76CDEA4078B46BF6BB631CFAAFF55186F612F4A04B2A9884C9D15D5CE6964DDB3671F63059A5D38DD5E75DB1606057A9FA272263AA2CFD17D7D09989CDA1DCA94B94B1FDC691E6E51D7AE2DFBBAA8D82CDA242A98A78E84F4E3B5D8D9FE10D2503E25B9B3C6E0D9206310B7698EA3435B3A6AADAC0795B5302A653AEF8ABE079E412A2B2182883F4B80B76EA49402D966ADD85D72F1DEC212AA890D4CB7091\nss = 387E023A733BBA407F35D4456A9EDEC3922B151C3B49C67BF3541BBEE5BDA18B\n\ncount = 37\nseed = D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389\ngenerateEntropy = a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c\nencapEntropyPreHash = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152\npk = 99315A88D083BF5196F65CCA4541BD4CE3526E514DCCAA8ED176BA58014BD0AC486056240CE06C6C182040606DD98978D6CBA367EB0EC18401ED348743780DDBD277F2BA22E1B34208F215F8F91A048CA497EC37A7663587AC85F221810E64ACF87478A101062535287250907D0854B93A9D4BB39CD5788BE361C00FAA87BBE078B26353A51B7BDBA58D17E5496EFB263DF826A59296A13535ABD799CB931FA5886E35476DFFF97E82870653D5C4BA09C2658A9A22838BA0C6AAA4AB7B19699B8B27243C42634045506762AB1817534F419591B04622C650B828B3D4A66D9B163D09847BD172BA8FF452759184C07B11183665C0185E0A089C957135DCE64BDA52338B6492A27A1238AA567F017DFFA796DE84532FD5BEC8FA800FF4C5E34791CC5AA02901B73885557CBA188F72AB5A35B489E98AB377691033934029118A34AF7D176A436139AAB3AC127A8F510C8719936E8676CAAC2211C8292A42F274C7FA85C542B21422C5790079F34A26F0678C005818BF4981A2B4C7DB780C0BD43AD55C0ACDF1AE0E0761D7527813076F3174A1D49C74659A453E09C2B4468DE6F185D5F3C04F2B7E59E05317586E743285E6817283CA11FAAB44271A4667912DF262C0C03843730ACC24E80E2EE0251CCA86A83853E6251E3036714576B1C171A112E7A15CA215F63039AAA7632EC77880B89EF8A45CB0B3746202ACE1D7221FC98AFB73A28A6AC2AE443F16E6072D6B3DA1A3BE5FAC533A9175A5F176FE131F021795F8880D320C6096AB63F53525D01B32A2CA90E1A9138E4CA72502785976BEE4E566DC0CC1F3827733B0A7D00CB58B6B89C5E26D2DA00429A2450E269DA77C46B5C954CEE6BDC0339BA357A9B9951802A255B74A4F4CA1297D124056147A0F8123EB903071546D2C22723367308601A22F199F9588734FE1241450A45FD7395DF965F46574A030581CC714A50C08DA03A51B367B524A2EE4E56752DB9B66D9C6B07702EC23BCEF798D68300859383C5BACA9D8F08B71409AE5552209B5237E697BA55328A1693AF7FA0BA27020DE2C35F643514DB292C061C8E2085D06C101644C94D17C07560811C093AFE61C6B4FFB970382CE9FD25F76C6728108842B3841DBBAC62504185EDC32DFB817C45878189A7AC02859ECA77AB445797E030E910243B121A859A05D8CAA3C32FA54D033714D20A771C7CCA73999F6D91D4DB4683A9543D3C978F1D56816D75590642CD4AA7D9E9C709C6CB5AEA8832D7C84C576AFBC837B6615B8290078E2C0AC9A8CCFA8338B36649B9F7C41D0064DCA53B8FA1793CBDC8F7B75306F19C4127A214E5532884274646B91F49A1E36A3B42CFB90B27425D2645C5ACC2482289D0B4B84A6359007F23B9F528718E6C499590D6BB2A5BB674E89561AB1A48E3988927AC41D05BA143799214701B2F6D708D365BE84BAA60DF8BF7D969A425C93452A0277F218790C80C60B4B59FC6131E7865D1135AC84A6655507C1D98F6665C932093D61FA578E7ACBFDF49F2E15C138BAB4152C005ECC44FEC299094A285FF50B09388B6AC3972911CFB8ECC9F0EA58761741ED23CE16FC02AF5A341F65043F0802C0353D987C718FB72D3D922CDC861BB6A8AE003197C8F9C878A367C021DB7E9273FE2E03A2716683DAB6CAED5C770F6E7984\nsk = F8FB5BA9D24C8681558CD13593F0CEBB335B6F65BD5DDA6DE6D19E09F15165051F981AC6472B263CEC43883A79149707093066FC129AE148B04F860C2DF119F8A51056EAA5DFD89BFC564226E56DC391ADE1CC2A1DF58EDD4572C5A147BBE21283B97F1B213BC276A471B63A7DF1CDC86C7A69A34ED17A425B37AEF969C1CD079529BA29A2E2C3412C5615E23523F3124C00C778752BB9B3677B90885CC21B0E257BB7F335FD53928B737D19DA3B3208219E6C898E96B45F801135A09A1425A0986C597E2B4042C1A4E6D7A4D0E30E729C73F2BBBE85B579C3C13A34344A7403B95D425936486C3B602804C08EF6F5AB22C400B9523EA3345ABFE666023BCE6A1B63A872C33E3AAF0CCAC2C40A4D5A48107D0C7AB09001EA67CA6F4C1FA7137D259C860D032C396BCBCB4177F82439852463B640855CE604F91C8F2E4A0899B2102C6059DC077D5EE6054355C546C2148077B8DEFBC313C71F1A420DACE126B16C21E40064E2522F9E224CC8E3526B1A99A2F4A81EFC2DD3609043246D461C7C1AF025B56A9C7E72ADEA57584CF044C2F0BB60352C32400D1631C034572EE46B71EDBC0334031AED7BC26AF543028C3918109DA52A6ABF3217A2219C0607BA9EDAB5B4DAAD5EC7948393C4A670C340688541AA713B596843E5CCB9616B54E92610539BFD39159FAB36D4928EE9CC8B1291AC0134257E242FAEB595100AC113AC416FF517866021B550B6D063512DC37477117D025964C95C13535C2F09A96740037FE1846EFEC4446EC03F93FA6B6FD8B539F0196444A61823B08CB74B7520618C08324F0667F142BEB3A34C2C5286B3D159FCE3B046079F07E558BA28A8893A8C94F9711C227FAC6900114C8BB6AA5369B059DBBCA008482A1843B62A1B06C68C6B2F40BAC6F02B6CAC1633055A178A396EF35F59F1A76543953D3B07E2B8BE217C5D5B1A82F9C080F4119D22275958026280BB8C96626C1D0BAEA6658A29546E09418AAF85A121F8647CB4789484BEE0189B9AB10852C397A2E25B9B15B71EF17440DC3554DB740289BA05111979614AEDCCA79699021F4BC3A4C68B39D0256D88CDD7A24E3AC31DAC35388720671A12A765D705F8429D0891C3E0D8062AD45A0B882BC53016DFB007D1C550998963D7E12FA51C7361D86156EA3A8AD7018C627A9EA18F9D3787AB3B88A27B3F9443AA87AB75EB1364A4C66C50E8170892A08FD15CF2913749D0C61305C4DE45A1BA2550009726A0873C70049705009DC8327BE3610F61F9BC60A26D14DC0C3E67CDAE4B5AC0D5A0638804D6C6B4CEB351F0C19F0974324CFA28FAB704B4677AA3F2BF65686C22100B74CB9AB5F7215452CBE8D6909754304573A9314B3C8362CFC34C6302B3CBD5DC482E76576FC5900B367016C03A860A88744928CAE55413231CA8A5008D210CD2E317D1BB6BC8624ECB83002E66092D8AA77FA0C6766532178A8CFB532C70F1114E5156E91486C3C7658E2A22CF0A77873C944A5A4BD70BA1686146E18B328D30813C9850C3003698C5AFA2082B3425C785200596592FBFD7B2AD5568F9D278FA24C523251BFC966A69CA882E707426563D2E099295305FE2E2A96F968A92E9423DC4A1F6662F68299899315A88D083BF5196F65CCA4541BD4CE3526E514DCCAA8ED176BA58014BD0AC486056240CE06C6C182040606DD98978D6CBA367EB0EC18401ED348743780DDBD277F2BA22E1B34208F215F8F91A048CA497EC37A7663587AC85F221810E64ACF87478A101062535287250907D0854B93A9D4BB39CD5788BE361C00FAA87BBE078B26353A51B7BDBA58D17E5496EFB263DF826A59296A13535ABD799CB931FA5886E35476DFFF97E82870653D5C4BA09C2658A9A22838BA0C6AAA4AB7B19699B8B27243C42634045506762AB1817534F419591B04622C650B828B3D4A66D9B163D09847BD172BA8FF452759184C07B11183665C0185E0A089C957135DCE64BDA52338B6492A27A1238AA567F017DFFA796DE84532FD5BEC8FA800FF4C5E34791CC5AA02901B73885557CBA188F72AB5A35B489E98AB377691033934029118A34AF7D176A436139AAB3AC127A8F510C8719936E8676CAAC2211C8292A42F274C7FA85C542B21422C5790079F34A26F0678C005818BF4981A2B4C7DB780C0BD43AD55C0ACDF1AE0E0761D7527813076F3174A1D49C74659A453E09C2B4468DE6F185D5F3C04F2B7E59E05317586E743285E6817283CA11FAAB44271A4667912DF262C0C03843730ACC24E80E2EE0251CCA86A83853E6251E3036714576B1C171A112E7A15CA215F63039AAA7632EC77880B89EF8A45CB0B3746202ACE1D7221FC98AFB73A28A6AC2AE443F16E6072D6B3DA1A3BE5FAC533A9175A5F176FE131F021795F8880D320C6096AB63F53525D01B32A2CA90E1A9138E4CA72502785976BEE4E566DC0CC1F3827733B0A7D00CB58B6B89C5E26D2DA00429A2450E269DA77C46B5C954CEE6BDC0339BA357A9B9951802A255B74A4F4CA1297D124056147A0F8123EB903071546D2C22723367308601A22F199F9588734FE1241450A45FD7395DF965F46574A030581CC714A50C08DA03A51B367B524A2EE4E56752DB9B66D9C6B07702EC23BCEF798D68300859383C5BACA9D8F08B71409AE5552209B5237E697BA55328A1", + "693AF7FA0BA27020DE2C35F643514DB292C061C8E2085D06C101644C94D17C07560811C093AFE61C6B4FFB970382CE9FD25F76C6728108842B3841DBBAC62504185EDC32DFB817C45878189A7AC02859ECA77AB445797E030E910243B121A859A05D8CAA3C32FA54D033714D20A771C7CCA73999F6D91D4DB4683A9543D3C978F1D56816D75590642CD4AA7D9E9C709C6CB5AEA8832D7C84C576AFBC837B6615B8290078E2C0AC9A8CCFA8338B36649B9F7C41D0064DCA53B8FA1793CBDC8F7B75306F19C4127A214E5532884274646B91F49A1E36A3B42CFB90B27425D2645C5ACC2482289D0B4B84A6359007F23B9F528718E6C499590D6BB2A5BB674E89561AB1A48E3988927AC41D05BA143799214701B2F6D708D365BE84BAA60DF8BF7D969A425C93452A0277F218790C80C60B4B59FC6131E7865D1135AC84A6655507C1D98F6665C932093D61FA578E7ACBFDF49F2E15C138BAB4152C005ECC44FEC299094A285FF50B09388B6AC3972911CFB8ECC9F0EA58761741ED23CE16FC02AF5A341F65043F0802C0353D987C718FB72D3D922CDC861BB6A8AE003197C8F9C878A367C021DB7E9273FE2E03A2716683DAB6CAED5C770F6E7984CED77D358342759291C2BD225B0BD82D659D28A24BBC5EDA8F47975B780CD1291F135CF64B6403E103AFAE34DA038613E2853BBFC36BAAFA3C6A95347193F37C\nct = D3327E35289A936A09CDD9B5FA00BFD73B28FFCB330E1CB018EC9970FEB3CA6EC7FBA6F9F8EAECDDD84B38C52BB98519E52FD7F7B91249C091C7543C142F0898D489F811BCC6F6A8ECC355C1957FE73E8ADFAADEF10495AE5DAE171DEA5965C3F303D9B731A5579089B1C99EDB32BB02BEC73304CC2F3677571FDA0BE46A90D36CB6A2F3DCEBFD7041ACB2EE2110676ECCEEEBDF2EA834765D9984BB335AE06CAAD76DFCD95D385E91C63D18702989B8C739F59B129BBF421FBA018E04B96F5FF08E7C05498681E129A1D84C378DABBE83E9B7EEA55AE4BDD1FE7B5544F6328E82899777E2CF76A4B23B6DF71F76A8F0475B4A587D8A0B8D12FF0B76CB59BAA831F6F7901887FDE2CF58B0661016FAF6BA44CADA98AB984A7BCBE8448C86B1E7E1E21873B034E0ABBC0A9C77BEDD69FA62278C41A08C83AD8B3E3EFC601595860E6ED1A1E4EA6382CB92009CC15CEFE8095604250593032F1E4F4564FAA616191ECFD79F8DAE40E7831C7B23DB7789D9D3270ADA144CBA1938D6FDCB1EDB624D8DDE05CF82E13F422C05883B6EFD9E0EBE538E3D7D6348B205DB5D282AF9D77AAFA42152EE11F58E2773E2666CFB3582C24F86EB8B20353231F5C2A5E91FBE2E40351D48DF2C7207FF2E77AD345DF3A79371E8D5A0708967A979C9114A887D52AF199EC2445CD21478876D097A0CC4212136AA12099FC59D6E2296C4FAEC109516C8464889DE22CBA68DD230BAA33A544C8A01EE58CA60D3199E90B9E2E262C68FABB8E255CFF75DD4280AB779DED376751473DE107CD1499C85D2B5876A4E0284406140692B4F1620BC945F737557EF3ECC54CDF0833D7A7E5085FEDA3275C991B533DFB25603826C88DFB0EBA60A709D3AA4AA69B5C04D455257F9053CD2769161281D6B5C60EF7EF10D10A1D7BA229B667AA9FA7BECA9729EDB18A166D991B57B15B1139F63B25BDB1BEFF61B38ECEC8DCBDBC984CC164D92E6A418F625B59EE736B66C154F9ACDC5B30FC3105E87CB2FF8ACC4A85AAFB2042C0F34C1D04CEE54387251D89AAB11A12953BE99960A5FC9AC1D384FEE498FF315531F50A7D6D4EB58814E224569ADE954316EDA1C2EEA60A39A97361547F82D7971BF27D5EE092BA1ED514552361AE54616D1007C7688FBEAC04AD4E3B9DA9B96ABD4D3A5284E008779297A01234D8C2A51727D9C8CE9715882A948A3B93B87EFA6C9821D439ACCBE562D00EA6298B304795606DEC5AFF0590E55516C9A8BE95E5F2D9B5AB426B294D75A0F689F8CE080CF01080FA1F1712EC169508BB7C49BD8D3F65FB12028437C524C5BDB1A72062D7D4928595B55E86787469B81D4BEB8A0061150A7465D36EC838249AD80D55E6F7B5EB92C62D381093965BDFD3810050A43E7539D556FB4C835C5E4AC6156BCC5E97CA5F85617448822EB529FF1F794C8FDA9E5D222C1BE8A3B68AF5FAC61CDA9996EA1E6B4394E9F7BD74A70C7A766CDEAD893673F7C2B54D077BCBAFF31539CB9836792149C563E52B1D08EF2748515781237C8A6\nss = 4D91655D2BD77339BB81F82916A1A77329071B3919CFB35CC1D1655C2DA5A2F7\n\ncount = 38\nseed = 6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC\ngenerateEntropy = 952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed\nencapEntropyPreHash = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800\npk = 2E7240107059C16C3EACF4A1A8342B73911DB6A51D3CF12BB168229A1B29F7C334D0D1AD99932F21BABFD8153BAE937FDD2393D9748518F12689CA7627A1041D868094AA7440C6724B4430EBD20776B602940C9D1FCB5A109978573434DA891962B645002508E46992C0C148F5A039609826BAF5834BA7271C443B69DC5110C4B7089068D16202CBAB2E1E4525738A19C8315FAE806FD139BE91F4C1E192A2C04983291340DAD4018A8A83C27A57C622408F933A51B7618148B16375A80E0A901F10AAF6E7803CB2A693ABCD4CA8BAFB942086F42F6B743937098E3D2A607F212F766603C9D89ACCF7AC584491F230BB1108B1465B865F824215D79FED2525D7E95C7976946E22A9E6510AFA2A9E8AF29DDB65C47BE8820561661050B70EF3B7BB249B7FD0CEDD688C37D7A3DE667626C2B389B38BE066089405703BD51FA32199E9C83D5265BD62A2AA2CE521B69973A18777E32151D3D5BA1983C8659A79AC978FFA15CEAB733B49EA8F7A853D4B06CAFDFC64C9D00E55D814536171496037036A078D026164D7B07E3277B7ECAA770B06DD291B9AD29241C3BB43553BCCF66A1DD81FE2E2BF79F1A21E1539D0BC517A9BA8EDE2C39DEAC4CDB7C65FF96048461BA2E350017095A35C1BFA25C242B000AFFC8AF29495A2D349133C343D680EEA815CDCD89C4FC283CD5136B89ABD473B4AEFE2228F4CBA5E0C10EC7A1083833735F081034AA7BBF20C11319CA263B52262096E505C45805E73619E2CEB242E559883D20DDDD4120F0C9E49F4995376284147CC2D2A96A046BDB3F56B6DC1889976AE1ED732EBA43AF5941831B2202D6091C16B680001A82D98CCCCEC212B79B5A884756C75CB2545316FC072D903C670864D5A13534E545D836276EE594D3A7841E5F91D6B738D97E73A7274671D6470CD2719B0515FDD67C6E4969AD213254502C5AC9BA23C264A375237369B46D0C45745041A20511459D3321EE9B395978F2C575EBE1C6CAED03AFC7027BC457E03F527B0CCBAEC71850E0955F0A2B54D9BCE69B6C8FBF90850168ADAC411AD5C973B578424C55CE01B3EC2825B0085232469968B8A96FE7B9F26846F789323A15AAE6397242A712CD26B0465BC038A4AA30DAC42C0036C062C21C3A4178A0C92B8992CBD54A6044B789D943F1EABB0BB24C3D0D4C067251779374579B27C84FB435E6C745334485FBA84676750A27C520F79366D008E4BE93FE8A958E8D06B8EC323BFD5BD01E86B1F13302EB17AA3AA8FDB3445AE5775111B2124E2A35021C04945661B2C510A29264AD855836C7D8EABC069011F8814934BB4B32176C0B59B04C5FB6CDBC8BC41B0BCFEF4423635C0C7AC43E4D5286C74920EF37C951266B92074D239B2BD0A0D6C096141FB6A718A213A3387D75B927CE176169738ABE0CFA6B68D3B064157C3CB03C5793A7400C1960351B059E43A7F1B28AE5073780CC606F7E40AEB458DBE95A31C23AF7E760001B0BD601647AD1805C4329E46F490575CA928FA908B5A30FD31520C61C9F1CC5EF18578B350A929164DE33B008338180CE41C45327152090A91B8C9B3928C2629A48D78ABD1992720E841A52CA91A15A1C7953D18B4BA1F990AF34CA408BA2D449F94385651C3B4C0503726CAFA118167110E848FBED995526B458D362061A1\nsk = 5B47B61CE23572623C431A498E378C6B71A5CDCCB58E225310217F6F2B1B7140B97349B965D9C95332A66D7A9879F24C479851A0EA485254755DB347BFF9A06D00502AE3A910C06771AACC0A51ADD07A291496AC10E2899B6562DCDA7B6B9B7EB516335D222C43498859D87A44CB8AD589A06E609FC5798CA06744051533D5C6154608C790A8ABD776CBD2984B57E1CF4E0638C77915DD89249D3C0775B45CC159B44BD32F49A51A1E398763E35DBF5C6CCB100929C9B91047A1AB98A140E00F77F5076310C33179A8C80449591C4156C244EB8C8B3009328139C18F8C59E1961A2B91C840D552C2E4B3897265B16C28DE6ABB72D218EF713A1D179CEA38561663C9BF21B68166AAA45748316877A9A5BED6F5230D3015193AA5A9E1B34DC6576B57692B543FFF321B14879A24728DE3D6A297C06AC6CB28EC3482DA708ABAB28FA815272624AF6E26A879F65C6432812470C52DE01EDCE20681DB43A967069DC9BB34F9C540A21B8D7322A3675FEE059F5F655CFC480BA31255E899C48A7C25588303D67055434702ECCA24D31A9D69796DF408328912ADA084AB122C6AC53C3C349C105270C9AEAC73923614EA9129CE4C9FD8D78BD33045D8557AD3D0A698B34A7C073B93783670662F8558375647747905402A6AABD1698D1D3B430CE8B5EE8665771A34CA73B2DEE04497C997C9E74044230690354B7AF23BD94AA02CF599554391095C0D53F5C1DB19AC33189B2B9AA3C48BC4E09BCDC5029BD3B45A370C59045ABCBFB257DDF30085DA053056C17DD0B5DDC6494524875AC189E6C7A7CD483288F03ABC155BC2022EB427B7D5093F4616C124B7C29A0043181C7BDED83DE7592511E3617A75652D4568D7C7B3AB2B7464C514CE6CCF54FA8D73E61834E534966620DC59196AB44B736151A27C02E065A000611542FC296A69A24989331EF980F708142D7274EA863669A52039B59D48B90BCC75CE4B434F5751CEF621CF3A29873C003A57276128E70BB4AA5DE581834946741A8134890491D37B6051959739FA8EB81C6947141704683124136C1C382760E13F00C59AB5BCBCEF98B973831B91BA87FEC02216619F012859FAA6B01B1649786B626348182398226CF794095681D1C25800B18BF33CC71123898AD2AEE46905A8118916BA8651328A051697F8041667789C874394E96A0EFCDA8998D420684217952496AE9117C6C618513C147148979F5C8BFEF8C7CA1836430C3CFB66B17CBCA63ED1A2157961CEE600617157AAD986B5021F4F69C3BEE6AE181A076C3CABF076903BD59814352F4EE2C04A138AE0EB018A2193CED58981CAA3BB032317499E6EC4BC5CFAB8B389467EF295DBE7305BD1CD099364D7596B1801008ED734D7775C5606AF0F1A2978733DD7F55556DBC5FBAACA5A95BBC287B6D3A43AA9B78AD10A025F46AF233512B126230CF928FAC14D753160BAD961BDCC4D5E1B4EDD241609A0ADC6B3C6CC9660E5371D6C1655B4465F16D535ADCC54F8376371B758CACB81D84A7B3E6B8754B430C0753982A89D5CA8B2F4", + "244AABE0BF05F75ED0B092F332AA83808F897BA21906AF25E68A88B61A357A10ECE1977199203E465EF9BC020E145F6421ABD11B182E7240107059C16C3EACF4A1A8342B73911DB6A51D3CF12BB168229A1B29F7C334D0D1AD99932F21BABFD8153BAE937FDD2393D9748518F12689CA7627A1041D868094AA7440C6724B4430EBD20776B602940C9D1FCB5A109978573434DA891962B645002508E46992C0C148F5A039609826BAF5834BA7271C443B69DC5110C4B7089068D16202CBAB2E1E4525738A19C8315FAE806FD139BE91F4C1E192A2C04983291340DAD4018A8A83C27A57C622408F933A51B7618148B16375A80E0A901F10AAF6E7803CB2A693ABCD4CA8BAFB942086F42F6B743937098E3D2A607F212F766603C9D89ACCF7AC584491F230BB1108B1465B865F824215D79FED2525D7E95C7976946E22A9E6510AFA2A9E8AF29DDB65C47BE8820561661050B70EF3B7BB249B7FD0CEDD688C37D7A3DE667626C2B389B38BE066089405703BD51FA32199E9C83D5265BD62A2AA2CE521B69973A18777E32151D3D5BA1983C8659A79AC978FFA15CEAB733B49EA8F7A853D4B06CAFDFC64C9D00E55D814536171496037036A078D026164D7B07E3277B7ECAA770B06DD291B9AD29241C3BB43553BCCF66A1DD81FE2E2BF79F1A21E1539D0BC517A9BA8EDE2C39DEAC4CDB7C65FF96048461BA2E350017095A35C1BFA25C242B000AFFC8AF29495A2D349133C343D680EEA815CDCD89C4FC283CD5136B89ABD473B4AEFE2228F4CBA5E0C10EC7A1083833735F081034AA7BBF20C11319CA263B52262096E505C45805E73619E2CEB242E559883D20DDDD4120F0C9E49F4995376284147CC2D2A96A046BDB3F56B6DC1889976AE1ED732EBA43AF5941831B2202D6091C16B680001A82D98CCCCEC212B79B5A884756C75CB2545316FC072D903C670864D5A13534E545D836276EE594D3A7841E5F91D6B738D97E73A7274671D6470CD2719B0515FDD67C6E4969AD213254502C5AC9BA23C264A375237369B46D0C45745041A20511459D3321EE9B395978F2C575EBE1C6CAED03AFC7027BC457E03F527B0CCBAEC71850E0955F0A2B54D9BCE69B6C8FBF90850168ADAC411AD5C973B578424C55CE01B3EC2825B0085232469968B8A96FE7B9F26846F789323A15AAE6397242A712CD26B0465BC038A4AA30DAC42C0036C062C21C3A4178A0C92B8992CBD54A6044B789D943F1EABB0BB24C3D0D4C067251779374579B27C84FB435E6C745334485FBA84676750A27C520F79366D008E4BE93FE8A958E8D06B8EC323BFD5BD01E86B1F13302EB17AA3AA8FDB3445AE5775111B2124E2A35021C04945661B2C510A29264AD855836C7D8EABC069011F8814934BB4B32176C0B59B04C5FB6CDBC8BC41B0BCFEF4423635C0C7AC43E4D5286C74920EF37C951266B92074D239B2BD0A0D6C096141FB6A718A213A3387D75B927CE176169738ABE0CFA6B68D3B064157C3CB03C5793A7400C1960351B059E43A7F1B28AE5073780CC606F7E40AEB458DBE95A31C23AF7E760001B0BD601647AD1805C4329E46F490575CA928FA908B5A30FD31520C61C9F1CC5EF18578B350A929164DE33B008338180CE41C45327152090A91B8C9B3928C2629A48D78ABD1992720E841A52CA91A15A1C7953D18B4BA1F990AF34CA408BA2D449F94385651C3B4C0503726CAFA118167110E848FBED995526B458D362061A12FDB7C7E39CE1625C20A13A1C91AA5909D8B03B064D00877DCE2415020370C7262D7033947AE42CA53522A65FBAFE18D3BC3E0CB66164E9A094FE4B44D8977ED\nct = 1B064FBEEE1ED7023765654313B62170F23F4C7E4AA5F23C5498E7F5F82A8DB67780CA831E660289BEED5DEB0C8D6D49E8CA85AB1738EF7F0C487F61BB2535730041398D2FB4F2FEB04D4B238C3DF61784F226D31BBFD6D92FA486B344E713506F12F625653380D8CB3FBD2095E9CC32973194561D9F2B6966D17133936CA643105F9FF845760596BB95D12E7F9FBD5DFC36AAC052D64A7C08E26A641C938D83AE795977FD5D2757DFC9166B38687043CE1DE9AFDD799FA18A164269FDBAF52AC4B1DF518DEB9138D55D161018BD64B74E125943F42FF6548B2C673F647237ABB78CB3D87CC9B980C1D5F46B1E73AAAF600B628BAA2FD4D20A466DFD4B3F6EC33E91497280B782E5D4D94DC40907D0CD7A53B99948E8D39C1E059ECA344D697D009EA926E95957A10B401C436A95133A219DEED9BA76A8B87D2A9F6D0FC9CCFA183622F794A1CB29061EE4561796DA05659FCEF032A65613DAB8CFD117F5F1CEF02EEC44A13956FE83E796FC8E5F4C589B8574AE1E1E702A97C6268F34E809BE6ADA4BFA00D9EE7F890A8E54E1A6FD0F33C111BD835466EB64C1622CB349B1C15D648CE49C951391ADAE8380CAD2EF3D615DCCF177294072FFDD678F55AA814DF60B6FF875B28D2FBC3BFE3A2675A63E4CFC60634BA08E6602D449D76B29FBC7AEB54E97550A1995C6A9B47A48E6FF23CB62D35520BDC492F1AC12CCB9F18AF78C92494F22B56C684917C0A768D030426121321B1EA5B41442A791E7FD036F7010C25EB45FBC472F526C82C956F0D3AFCE7C16055FC470C61CC3CA1F05ADFDB3DF3724C5D38D9289E49D702E620ED0749D5C13376CCEC5666E8F46B60BE05D005E1F59DE58C70833172A0E0728A26C6658AADD56A9A1145E1C1FD6F3077E75DE450137166445DBC096733DFC8B8BDEDFD13F2E8FC53432F794BFDC09E9FE2070147A8EB260A4069B097CE368A7171628A6D06E5091A85CAA5D9819973ED338AD1FDF261E8A4C70DB6E78B6BE4B908D5CD3A875F321A24C4D1375AA6A97C76489D005E475ADD32524DE9B64E4468B44CD0F730B10219A0FD481800FA857C67ECDE250AF0EAFF95B43E377C32BE2F794ECA806F09E10EB4B0FB038E07535534CEE9816BB4E6EF0244043E49B2676F837079F2EE3CE9C29897202D75EB19322E6440C49D58E984DD441231A79D479851A0CA63D33E77E3191CCE8CA1C69CFBDF06D63AA52D1CEF72AB7B3F57C179B7C382F1CB7749C197C9BB0B501F97E96E893AC60336C8FA3E97631E770C3F2F544805767E3BA0FAB80020A42CF64858BC001D156ED33336F8207A439A82F07CBEA0D00F5D5942C1E9528034F60875422BA40F0AB503E32E61514ACB3D6F3F3F4AB1F9EB6AEA8BB6197E7EB0E143223532DE74B12834B889BE7DB31B93551CAA8F464E1F38F8F882A252682623459CA11DEFE125334FD0C0718974A3B6DCA46FEB0AA49D104ED96C301537A3174AB466DBB164AD68B59358F0CDF1D8A159CCFB9DAC867424F4504D3DE7BC0D686E24967A57B70\nss = 3D0D1AD5E2825DB1F539515AF2392F0D212E8166B34F3D8CF2EBE97E51785EC0\n\ncount = 39\nseed = CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F\ngenerateEntropy = 3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9\nencapEntropyPreHash = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c\npk = 45FC2D1BB1872A743763F12D29D937F3F2A41D257531C1172AF59C90806C7E5A15972A8CB9DCA049BC92700A72B4FA5A739033437C946EE062AA86C12103B557822A08084BE63C4C74D1B92608C3B02C6520B2991F8499470114FB659F89A937A25897FABA6C0DD142D8D4868EE3C6483128241B287CBA0AE49430DD6A28D1339605A4B750E6029F73BAA1FA8CE6219C36A40E5542AB45CC781A613FDF416502743DF8CBB3C4B864D0B448A20C0B0942A829601F2B131FB038587A99B80EF44033061B2E4B8F9A12C3C03193506B62AA1C7AB08569C7D0A88C8A098F87061EE41000FD202E2C3AF4E625B34787BCE55F74AA58EEB9124DE7089E51A581893354B36FE035CE5FECAB74018EE6209B75FC2702429C932ABF71D89B8C82C047D77725CB6ED98608F2BA0B3462C1D428352C6376F6269D9869AFF4BC821870B63F2284D296677B6145683BA6282C12C72512EF015EB19BA86B3571BE7438F17311655C118A530266BBC6D9D10636B6347C630607864949DABFA558522C100F6C7941A076109253B5FFD76328C99590F48B3FC7AE7A5847CC958FA5523F540AB54EA0A302174E6C401341759C121B355C9280D2AB6A84F9028634BF7E3CA90679ACA188667D5086DF35B88D95B262E8478561A414B627F43B0FB8731D3BDA73C6396594694A9F7024CFD55D3AB88342516CB34A922E6835EB8C067BD35CE0B3711D7BAD2D7529464C493ADC40D8EC8679C903E8984850034EF4A828D3FABCAE9474F7278CBE79C8E5C1C948B94798D4C68DA8255237AD8B0B38CD4A8DFDE5ABF6B2CFAD98A677A8C40E208206774661490C3C212D23327A46A23DD6855275B78D29830B23900B13C638E31B4745A917D4FBA95A04956C371212E475271CCF94F6295346118806316EC01D08454B0CD922D6F1A3E4A651A7A931F380042A09244BB39973EC5872C28C8D41C4BCC72CA4409A363C49995C45C7909522128C03814612214A5EB01527B67BCE4463202CC14E31225B36A7D7D10E26966BEB389877AC0062F9172C0517CA8676F5A44A10106FE75A31A4AA86688C075918A4D8A7461DCC1EA1193913C259E3B44C2D976EC67613468358886A9108ACC7D0C6A25F5A991D7C53B8638C24A585F07AA074B5A2CB514BF7178E14112C8B31727A38BDD20A5AD087746768957F837179D50D25F6697F4A88D056451A593E385B74DE8A01CF0244E70AC9AE36B2D76CB91E5419165C6507D141148869D6676F28645653BC78C96B9E7F382CB0C6768E2968C513C7AB076928781A6530CD3AE3286B0C681743A58D9C524BE5120C880605BC139F672E30174095932A000800D58A926CF40873C44AE6096940A3BDB6E7966595BB3D23C9915BC7E29AAAC9F0344C9B6BBB25CB0AA084F616332197295163989E1448784082C327075DACBB7D912025E4786710B0C7452F827ACEDA11A73ADA09C3E54B404419DBF3A8F8B6096A73528DC50FCD230155A97A614663174683D1095D97B7C0E994764DF2095AB7BC029B7DDA3799E5A88ED825CF1674AEE01BB0C17A5C84B8AC1BA061302BA9CC20CD46F769E1021C03C43AB07BAB1BB0C7F3426D252A15ED5A27854CA7B177A6F79502789842E229637FD32A677F68DABFA371062D8B8CE9DFE0D90BF06044AC3A840CEB626B16E134\nsk = 2C021F19322A908456F1677D31DC8A4A2A734A2571D19C421C47AECC507C3C53A931113290B693AFD1B7FFECA87CC90B0419C48BC4359D64146D9932BEEC78766408F59216C692228FE59B768C92F4D5A3CCFA6A35599DA2695766D754C1F682AB13C8966997F37A74985551C36828224C177D3A3ADE3C2C20A907C830BC32906DF70B021B47C38C606EF951ACF7C1512AC15FC0D761C9057A7DB1AC6C56198F9A8ED2F67A0F159A5EE6612109254D57745736CC3CDB634F5658FB684D805888FEA8582135BD4890343A545E4E0A6F0C130B8539125AB06358F8BCC0A4B44A7A4903D018C960CA45779BB564A30CF1B340B4C317CB77DA50BF899C10B4676F3C295B90E93C2540A9E17C3BDE560F351C81C58B545306449585718E9199A6302E3B0CA1E737C07A4B7E21EC154604590D", + "415F4B82778778905360CC2E49BE4B08C94A744995F18959D4492F0B7A3F53A98F9A8D914863B9583D866712FE583FD2677E8A3B8BA5341902178824F4C41BA21CBF7A4B666ACB413C31CFA744B9A5405EFC5B53A2C64481270484134753C1B0407E23B95850A8C026843643E42B329BCBB7422DF5CBB968B04F39210A4EC959E1B5C9CB32A180588B9BAA690F7459B1282D9E9200BD1A0E910A3EFD948C3BD0AF04D866EDC61C866B48D7AA22E6FB5025C6892C66116E271B998B888E0481ABDA592C8B36F7464704FC22C51B5BA995928FE03594A8073AD790798AA304579822255E61D11557092BC9B5BD4C94068C60B2940C180831C5167487B7538C9AB47DC268215C8C7F324563D3973FA73BBAF07C771B15070D880478D2693535425FCCAE0F8272CD7224F3795A70241D480425E4A74922309906E1C11C5107E9F34FAC3536354100F911234D55769B763CF2408B9812AA6B7C2601161953CABF0733CD3AF819F5158A136621FB159DB3DC6C3F3220ADB8ACAA8CCCB7CB2EE583B9909C903FF43612D178C568AA7E9217E345CF4DAA9AAF17CCA1B5A4A5A73CE9B0581E73BCC019BCE2B68C8C273DFE588BA0861C5A73A6EDD9BBDD66935AF04E5EA81A55D62C9A8C51B3E6A402587FF4F837C16380AEF5640F333DB08A6CDDB425CB4189ED773D8ADB91E2708F12B78A0105BFFEE30873C1B6D5D5469F6464705741EC4310A8185A1553372F6091C769109F19527E95A6802C2A49127077B21126E7531A5941298BAE199309CBE00D97513BDE1AC82292CA1A76957D20A306932F83994A00F21D89519E16138F0477667F338A67450E1248A682142A79D9AB6B58B88754362A32AF3402D062A554CA8A40DA0481BA721A9B023DA71987B744C6B9AB5E80830F8B7200241007F0EB72AE3694EE92814DF4B1DB269F4404CD0C77A844D2B751F5A0BD1CB93D61A628098D0EEBC941827F77139831575B98E47B7DC3676D887B56D0AD96BCAA1F280049776339CB3FEF6489DBD26205530CB08C53FB0839B49909864AB06B2C3FE15957DDA96CCDA90C51904DF02C6A1E5846F892A1683838B9760AB900664A1A039B6A1C75F9C4B05340EDE9881F48869DC881DA0191E24BB5AEC448EA052E57E69EDF254575FCA87A1B50E6D39520630688B04328A70CA1A871FFBCB0A8823DFD4747DC859B45FC2D1BB1872A743763F12D29D937F3F2A41D257531C1172AF59C90806C7E5A15972A8CB9DCA049BC92700A72B4FA5A739033437C946EE062AA86C12103B557822A08084BE63C4C74D1B92608C3B02C6520B2991F8499470114FB659F89A937A25897FABA6C0DD142D8D4868EE3C6483128241B287CBA0AE49430DD6A28D1339605A4B750E6029F73BAA1FA8CE6219C36A40E5542AB45CC781A613FDF416502743DF8CBB3C4B864D0B448A20C0B0942A829601F2B131FB038587A99B80EF44033061B2E4B8F9A12C3C03193506B62AA1C7AB08569C7D0A88C8A098F87061EE41000FD202E2C3AF4E625B34787BCE55F74AA58EEB9124DE7089E51A581893354B36FE035CE5FECAB74018EE6209B75FC2702429C932ABF71D89B8C82C047D77725CB6ED98608F2BA0B3462C1D428352C6376F6269D9869AFF4BC821870B63F2284D296677B6145683BA6282C12C72512EF015EB19BA86B3571BE7438F17311655C118A530266BBC6D9D10636B6347C630607864949DABFA558522C100F6C7941A076109253B5FFD76328C99590F48B3FC7AE7A5847CC958FA5523F540AB54EA0A302174E6C401341759C121B355C9280D2AB6A84F9028634BF7E3CA90679ACA188667D5086DF35B88D95B262E8478561A414B627F43B0FB8731D3BDA73C6396594694A9F7024CFD55D3AB88342516CB34A922E6835EB8C067BD35CE0B3711D7BAD2D7529464C493ADC40D8EC8679C903E8984850034EF4A828D3FABCAE9474F7278CBE79C8E5C1C948B94798D4C68DA8255237AD8B0B38CD4A8DFDE5ABF6B2CFAD98A677A8C40E208206774661490C3C212D23327A46A23DD6855275B78D29830B23900B13C638E31B4745A917D4FBA95A04956C371212E475271CCF94F6295346118806316EC01D08454B0CD922D6F1A3E4A651A7A931F380042A09244BB39973EC5872C28C8D41C4BCC72CA4409A363C49995C45C7909522128C03814612214A5EB01527B67BCE4463202CC14E31225B36A7D7D10E26966BEB389877AC0062F9172C0517CA8676F5A44A10106FE75A31A4AA86688C075918A4D8A7461DCC1EA1193913C259E3B44C2D976EC67613468358886A9108ACC7D0C6A25F5A991D7C53B8638C24A585F07AA074B5A2CB514BF7178E14112C8B31727A38BDD20A5AD087746768957F837179D50D25F6697F4A88D056451A593E385B74DE8A01CF0244E70AC9AE36B2D76CB91E5419165C6507D141148869D6676F28645653BC78C96B9E7F382CB0C6768E2968C513C7AB076928781A6530CD3AE3286B0C681743A58D9C524BE5120C880605BC139F672E30174095932A000800D58A926CF40873C44AE6096940A3BDB6E7966595BB3D23C9915BC7E29AAAC9F0344C9B6BBB25CB0AA084F616332197295163989E1448784082C327075DACBB7D912025E4786710B0C7452F827ACEDA11A73ADA09C3E54B404419DBF3A8F8B6096A73528DC50FCD230155A97A614663174683D1095D97B7C0E994764DF2095AB7BC029B7DDA3799E5A88ED825CF1674AEE01BB0C17A5C84B8AC1BA061302BA9CC20CD46F769E1021C03C43AB07BAB1BB0C7F3426D252A15ED5A27854CA7B177A6F79502789842E229637FD32A677F68DABFA371062D8B8CE9DFE0D90BF06044AC3A840CEB626B16E13486BB11E7D9C1368FBBA34CE3A2F169C2464EF5FBC11F73843C456467B6CDBD4E01C8E376FDB140EE343106C093AF7CB149B316BA79446CEB4E5E0CEDB9B164F9\nct = A2877C3D4B092D4196F99FCAC16B38EA10D653E03446CB3BBD61252A938ABB30F3F4B32127ED8936F48A28B0A5202506E7D4CAAC4A073C5CB940B89711AD903E4C43EA9C783A0082F2A831B5FAB803D97723DB32CCB3C0793B1B858E6F71A39A1BFF4700953ECD249CD244AED4FF748110910313585D19F6562F2B5AD187A2FA5383A55E6ACD134A97DEA0AB34E464299DA2C7D5C25A06DC9728FC48DE1FA9A72CB51E08AC79D09D2266831F55AC5BED2A383E8FCA1E2B402C0AFF8AA8EEAB9E277F80C474F8017F8CAEFAEC1480E8FF37EF2DD6E3A8223CBC0AC6AB488084A257BA0F65137C9F9DFB573F9302168A77A8CD7EC9DF435D0CBE0AB9EBBA107FF2FB8ED9548F816DC367777BB2254F8821F22128B9F1624A6B45CC91BC76D5C57FEFC1BB567A2CDBD66CC9970E08BABA6F8C25C3FBE1AB9703BCBAD4EE3C0316738EEAE7488AC7081EB97B2C7F9B236344DB66692B9623384CC8F6E3A6247DE3A75890CA89C3C56F0CE28CD448CB17C4F4C19E727CB2B3724E2FECBCE57AB0BC80147E6B2032E876790A15933FB3822C89C891B8034B081AC74A68A7704BC9435E085B50260480435A6E9E87E12B81F64E75AB3753DF34BE96DB9AB2E49AD18774DD4B5AE0EA2C319DEDF6E0AF04AEE38CEA0B14BD58299AEECFE63FD818055854291C0E81C97EB485592CA06D1BA83A61010E5B6786A353EC7C7C46E658BF095D34A01F486D7CA278DCAA2D92FE3D13103F9241F7E949AB007F362B54C504C4B92C9A40C980E3EF925476E5354A2FCCCD8FBAE94CE8574B7B461632C56EE33FB2D7E2F41E7E759D0945D5A9DF0CC07D6B01059C71CB05AE9553AAF3B60266D422DB11AD1A01ED8757F1931968A16E7945A6EC9DFEA453322F9ACA9639F0CCDE621E95D01CA58FD21BA030E7EA518F601AE849796CC83B5D02E6152C2B9DA2394113DBCF0BE0F2781087370AD6F581D75AF5D6C979E1D3F43105E48E62F6EDF377203815DECB1690C914FE6B5C5BBCF1C4297A253BC2ED7D3E53E90C1FCD61CBD8C1640AA60CCA213CB8E58F137D6BB6FFBC30697AE85782F0A4AB4584FDD332BFCB4A2BF45B5059F9E87EE76EA451B5F684517BBC1407B06DA076AABC83CA7532650C45CA468A07CAE1161B4AA88BCF0816F4CFB0229CD993FFB428A9E5AFC8C0C94C922333692551890FFD307D87CFD4681ABA84FD82035ED32007B4B96E963324BEBAFE589C5D65552F379F1B8C4905A5D7C9F93B0880B9EBB7073A0DCC35E77A20D358115A9C0C9C007AB49B0BD78EC1936D301F39C976176B2B8DAB9CA040ADAAF26A85CB616002834D630D2DB28A48362C15A5637A2CB45DF5AFB1DD3C632219723F55F4F65D2EAEA810DC84A4C243D30BD49E0214BD97CFBD1968275351B0D1182F316067A9F43776F923A429E6EAF29E5E620CDA06008030735A1D3AAD5C47A0F12102C0F28269D7F2CB89E3DFF8D9B73A5AEE6C395CD9D6FE209134D46BA65A4F8AA59A5C37F180A5C287D8130678EFD51406C52858EE1FE24ED2B038\nss = FF9A0D1AE64C97E4C51512B315D044C14CA34771DF320BA0C16C8531D6A40D78\n\ncount = 40\nseed = 197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F\ngenerateEntropy = 588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4\nencapEntropyPreHash = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2\npk = F6446774B30FEF5B426F563962CC29FF78ADE42B497DC3B970F1B848B1141D7A5F45A37C25B125AED61863F22732A06128BCA08EFC8CB176AB6343239B572E1C8C138D829810227AFAABB81CCA0A73131155377730A120558231E8F8A598A2B730578EDC7800B0D6C5627530EE92930EB2B40A9888CF648263B688F0A12E08F004F4BB449A25282029CFB73C32F8D31229D0A58E6AA08698517FBC5F619837AE3331CF763631D305E88C8F85413E9D5420CC282BAD24A783011184011A79A3B305DB5B3032B75C55907CA5C7F839320028305C439C39484895212B1E87925999681819416DCBC7EAD45AC2B1262154BCE16866C04561EBA2C9EC6022B07A57A67C7B901B5DA3BB8025C7585C86BDA0810C442C39374040236A82884199159729834663D3B1967DF9955DE3A387D93D50F5001924C4FE433D016BC2B6614F2D3BA72FDA226864AD6BA5B8C31681DC104348EC2B29C39FC9F567CAE17BDF1C6E215C92EFFC60E2D6A3A3106BCED0BF301B542F7987B582B0780B6D398631EB8559459B1DB01A0443100DCC731291C737499C2F86452394C0B6662401FB57A4DB232E40D1B0F2511EE1EB15DBF7B603E2A67808C064FC5103FA7C9C954FCD12BC619582F82590B323698A328CC14ACB87C217E39C309421C7E6EA15BA6C3BD8587126C5AA02C26308C9912D7262DBB91AC2C2CDBB9CB009A3AE10761771740B2E6558FAE775DEBA7A66086859270EC07B584334900C278002D8A47D01547DBA3036336616A8C12415B86A1423A6C9AAB5F085C7FABB6355B3DB4023E47C7917C10C284333110BC978B2C08E16512BA95A07237CC35C97BFA51BB1B25E30750E65664377BA49200AA6E935B4C7451E547859EDF03BCFC6904DF05220C02F5E576604A873EE82B7693B962853B5522A5B0986348DA63DF86A64671737C17201ED556E92ACB56F065EEBD31BEF43CA85DB1FEAC395E19110A2F0C5", + "B90459838CBF779C27247709765569E5A649BF160301003169E4AC2BAAA4C4697F25869AB99179F9F792D9B19DF0C148DF7C6B9AA20E63426697D83A6E33B35F4C7E798175BFD73CE60A050146A3D893C4DC9B2FABF5960BD80FA0679433BB33BB91915E93C1EB2AA16CB13E0B9870FEF99835A674B1BB76946BC4064CAFDE3063498CA30AEB3983F5CDB3A6B9C4970459D969F4D8B6BA27755B6CA8FBCA178DEC28DFEB2AC03318BE7002A9A4CD7B1749A7FC7F09A6B560740DA89BAAB8130872510C99630F3B588069D50A9550C97F8198B7A46148FA7AC1580632DB1EF49528F9125784A5BB2757235FE44E74529A7CE88E91543B2FF81D9ED78E2647AA07033CF3422D34942E7830191B104C7ED56B8951A9C8706E4CB33CB0B918387B869084386420C13B09BE75D2A5E9276246B674E96BAC7782541E1CA441E53FF3B9C702CB95CEAB628D1617704A448EF743E8B811FE52C659CBAAE22377F28646C45642A9886628C9B73C510BBFB645D4077C1D8B954BDC8B707B7F6BC4701BB1AF0F28B88DD282B78B7EE96732521AA6180B6021AABB415839DC3A1F6F545C1320C58B965B62993ABF6A10C18A22CE6A45539685F297B1F04A130465845D189D17552E2F4917E924CC0D2DBC2DDC739F6B876472EB12CE233CCD402DDEF61523FD6FEE69A88F34A34C\nsk = 47A7741316BE87861AEC518A9B38146B43AA54A98F47E242866B8D79F731D98C754B572A2A9170A7EB4B0D73B38D6665D1E43AF0B61AB95CB54879707805BD787913EE369D231C600B76949BF86366579AB62724CAA1BEABBB02FC945BF007CF57A225AFA67393CC58804A15016A12DFB90D5A52BE41F907B1F2C4FE93712F555B0AE896E85931020089642A23E4C38581D4C40A46AA8DDB3C26DB0E29FA5F7A12B6CA32CD2AB6B50327AD0DD8139AD83DCE676AB2DC0C2774C86A2C72A5FA2D4DCAB588A66D6551C040E91AE045698AC0A1DFB95048C545D08654C1B560384561AB07BD8C61182F99C79A2267C961AE66434321E8501D474AD84AA71286A948C5AD187232CF72576F167D63992F62D3423CE75577C2052EF84019404B0E1706BA704FE3D116A518293112B8B80708C094BDE829AC38E362A404BEB67026EA6782362035CAE099302C5660931CE31B93B665059633699EC44C28C2BD230B1942421F12388900081618BB29E315BEEAA090A06AC7FEDA567FD1A12D1A41EBA931C279ACDB875D9DDB7CD9A6ADBFB32239E843012A8CB91776775408316B056FBC42758772C1E53EC0344479C2791B837A6A34AA77710D35593A55E57572FA99711BBE5A83454BCA7990E834BA285A09AA11666CB2B2F39704904354687D0524888CF6461EF302139B042540138E322453619B3DD715B617230E08C4585478F9996798E9B47C712F82BA45857551EA4C79B4A0577938666403174E84585E684783D33F3B701420F66D48473FC6BB627B399E90697E760783A3E09D6531CC524568DEF8507F0437314488AF7376BF2A6BACF783B632197D8565F9456D04A8476DA8CD6C988D26A56D29479A2DBB85AFC18DC81A8611BC4ADAAAAA440471B530053ADB874DB67102B6A64FFCA8BF8487E18B2F7582B71FD78D85F819C24B892741A83E67585B6B1AE5AB6AD1F5CC02AB78D0ECBE01087F46AC9BFCA464A4B9CA817C3A1AF5CB0A6A3F1DD3A2EC06774E805E001B44C8194660A280D0D59BFEB35EBE9C943E626B98E488F8984275401BDC4959993345C38BC801B95D56BBB47A2B23F5F1223D5A0E2A827D4578948CFC5432627C9586275679202E3C970FCC980AF56757912080072A4AF234DD030EC481A6ED8030921691D6126839635C6B270497CA4A87D4BEF47CAC60752383712636752A4AA18AF13BB36EF445FE653628704E4DC2CADD62839F9842F9B2C264AB4FF648C59D15708F55AE4A396D5F4BC75D20603C03CDEC4252FACC579A0CBD1F64A734E8350F03ACEAA2734DE2B486F6B93C36AC11803E564070ABA97D2309078FB43768F98EF5D03B09FA10FFBB0BEB3B5FE01310065508100206A640B93DE87BD94A634907730E30800803B233B95D1CC7CCE49C08AB143734347F3459A5BE0230F9481D50B4B835A91736D6A7B351C8082A4D080967B43B0553835BF52943A380051F48C27823C5AA0B20B7B733DCB004B2A7819BEBA4B3FCB1F991789C2C57CA01B50523214AF309FDF421187492C411C14128744BF4A83599A30B86194473C2BC9222FB4BA34108689AA8065AA24FF3559A76F759768C81A8CC5AA2A6792F3033B2437B05068BED096475D9280BF349F6446774B30FEF5B426F563962CC29FF78ADE42B497DC3B970F1B848B1141D7A5F45A37C25B125AED61863F22732A06128BCA08EFC8CB176AB6343239B572E1C8C138D829810227AFAABB81CCA0A73131155377730A120558231E8F8A598A2B730578EDC7800B0D6C5627530EE92930EB2B40A9888CF648263B688F0A12E08F004F4BB449A25282029CFB73C32F8D31229D0A58E6AA08698517FBC5F619837AE3331CF763631D305E88C8F85413E9D5420CC282BAD24A783011184011A79A3B305DB5B3032B75C55907CA5C7F839320028305C439C39484895212B1E87925999681819416DCBC7EAD45AC2B1262154BCE16866C04561EBA2C9EC6022B07A57A67C7B901B5DA3BB8025C7585C86BDA0810C442C39374040236A82884199159729834663D3B1967DF9955DE3A387D93D50F5001924C4FE433D016BC2B6614F2D3BA72FDA226864AD6BA5B8C31681DC104348EC2B29C39FC9F567CAE17BDF1C6E215C92EFFC60E2D6A3A3106BCED0BF301B542F7987B582B0780B6D398631EB8559459B1DB01A0443100DCC731291C737499C2F86452394C0B6662401FB57A4DB232E40D1B0F2511EE1EB15DBF7B603E2A67808C064FC5103FA7C9C954FCD12BC619582F82590B323698A328CC14ACB87C217E39C309421C7E6EA15BA6C3BD8587126C5AA02C26308C9912D7262DBB91AC2C2CDBB9CB009A3AE10761771740B2E6558FAE775DEBA7A66086859270EC07B584334900C278002D8A47D01547DBA3036336616A8C12415B86A1423A6C9AAB5F085C7FABB6355B3DB4023E47C7917C10C284333110BC978B2C08E16512BA95A07237CC35C97BFA51BB1B25E30750E65664377BA49200AA6E935B4C7451E547859EDF03BCFC6904DF05220C02F5E576604A873EE82B7693B962853B5522A5B0986348DA63DF86A64671737C17201ED556E92ACB56F065EEBD31BEF43CA85DB1FEAC395E19110A2F0C5B90459838CBF779C27247709765569E5A649BF160301003169E4AC2BAAA4C4697F25869AB99179F9F792D9B19DF0C148DF7C6B9AA20E63426697D83A6E33B35F4C7E798175BFD73CE60A050146A3D893C4DC9B2FABF5960BD80FA0679433BB33BB91915E93C1EB2AA16CB13E0B9870FEF99835A674B1BB76946BC4064CAFDE3063498CA30AEB3983F5CDB3A6B9C4970459D969F4D8B6BA27755B6CA8FBCA178DEC28DFEB2AC03318BE7002A9A4CD7B1749A7FC7F09A6B560740DA89BAAB8130872510C99630F3B588069D50A9550C97F8198B7A46148FA7AC1580632DB1EF49528F9125784A5BB2757235FE44E74529A7CE88E91543B2FF81D9ED78E2647AA07033CF3422D34942E7830191B104C7ED56B8951A9C8706E4CB33CB0B918387B869084386420C13B09BE75D2A5E9276246B674E96BAC7782541E1CA441E53FF3B9C702CB95CEAB628D1617704A448EF743E8B811FE52C659CBAAE22377F28646C45642A9886628C9B73C510BBFB645D4077C1D8B954BDC8B707B7F6BC4701BB1AF0F28B88DD282B78B7EE96732521AA6180B6021AABB415839DC3A1F6F545C1320C58B965B62993ABF6A10C18A22CE6A45539685F297B1F04A130465845D189D17552E2F4917E924CC0D2DBC2DDC739F6B876472EB12CE233CCD402DDEF61523FD6FEE69A88F34A34C29253478090CB4D580BC2A912645BC685061E5D4437B3811EDA69C865EA9923C0E860576285483BB5FD36E2F944D32C4317BEBC1E441470C1372046A790D79D4\nct = EB55C9D3D46D32C021F0D7E61E5382C2B74BF1608E0C8F09E080C2820AB0CB10886E141A282A7C80B73CEA0272D08E16366F2C900DA1144039E5A8EF7031DC26A5CFCEE8F47C3F997C940A056D68D3507E7481E13835B911CDE8976F0E7494170D98386316AFE41F97B56FFB8B5C85C70048FF2B5E2508D19B06D8E03A91F6973DE1F903452D0A95F5E8FEC22D033669FEBCBB2E09904307FDD7BCF55BFF0C097D31B62B08D75A144E8064B7001DE832BD6AFD9FADBD00BA148A5DB0B0085FA6756AEED4E2D1CFF7E8BCDD3F8E6096FBE2EB19F10E1EE84678EC8E140CD4101D300FD0E110BB7ADFC580EC1EA5AF38CC6CF984DCBA6921230304DC19B38A1D3C9BE8C479FEAF98E097FAA5C45A957D8F33A2928C1692EA8E8B528B33D49460516DFD50FEE3F5D0590171ECC3DC287E4F63AC5FAAB29D1B6436195EE4F6F29AB15C9C3C27683554C44F0D9CFA94920E9000BFE9DA83AA15A605A6E2474D29460AFF929BA74A38C465FDC8988C7C2F02B5CFB44C16BEE8B9065B049FD6342F976CDE143BA0D48CE4AC03F2CCB0767F94FF4DE46DFF7077790B1F1FE14093034F8E021C2857A148C14FCAC87797E455F36472F3791073F5F47C5C02BC40063A6C0435958B9CE3B403051CFD6A538B05A63B924950EADA692FE82433DEE2F7BE1202B5E1DBE0D5D17E0532F09F7C3D2F815BDA7A6D6E61B6BB2E755C1A181EFD721444A928BAF9EEA4ABCFFFDE4A1053BE769077146B4487ED00B2F3CEF170FB7EB4A3B61BB19706AF4C6FD9B6A29EB698101835CB24FF1580E00C36274220FDD56200D74716053C38F7D4E3FB1D733F54DDABBB14F3CFAABE62507D50920FEDC87E5190BD84200C96C6967CAA3912C6126EE409DD4BDCF8859AEF9561E523A26B31F5632816FC9053DA5B9EFCD9CC05E6A1D81078D6ED3246A46E2CE4F0C09F11CBE1FB5994EFD758207F7B9E2AEDF2A8386F9175259325B9B7AFBC9C8B9715E973EFC1573526D6CAD3579BD57920172694C7A5A02B2CF3DA1C78CCE8C9E204A4D2605C510552836E2231841873F2153A60E77E381EA4345A0A4CB0622020CC5D3FC168D84EAFE1D38E0F2DC8B890D7843BAA29E2925D5F1BE93A9E266DCC99C00C5D6681190E07A833090AFB8575AADF55333E8B3F3D9FE2E7337A3C122DE1EC3264C61B47EEBAEFC7B1F276F8EBC1CC53DE806801A8EAE9FDA8BD5E7D2F83CEB6C072103D190ACA2AFE8313B43AE7083845B6FC26ADB1A7E3C17C0FDEE0A1590FA66127EA4423B6F7AFDFED7C7E2DAF1B7490F09DBAA9CE15E209E1405E71531D3ACEFCF6096B8B76EE28246697A41C6AC8E0CB4E0CD1CFD80997E19014F083167FA47BB4BEFCF207A369051C5F37477A2BEDEA8A65913D557F896EA0041D77182BE50BD355F7544245624F6DB4E918E1308BE489CAD3C7C430D707BF91B79763691EF5FC0DB233895B361CD85158250DCFD5BC90A3850B60118159B3EAF31B8AD3AECC555330D1E084C06033CE41EBF6A5A6928B624D308C48919BA8FBD6923E\nss = 0E40BEF57DC97B87EF89E5308F9DB94FFF59A475DC35EAD3F2D5B6B89D24CA2D\n\ncount = 41\nseed = F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED\ngenerateEntropy = 47550e9edacb6ddce3d9ab8", + "1f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92\nencapEntropyPreHash = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495\npk = 5FD557F7434FCB61B199E793C5E763764C48DF412ACB7C756E1370CD117F8C10CAFB39CBF0C8C3F5DC8DA1855203D02B39647856B55C38E944617B8348D16A8221962A42398FB61978F40328C83A0B49BC843060D1711E289434DB4B5B0838CD87949DF5AC0727D8A528B8B5BF30CCB9E37A6664050CC5880D34C13CA42C1779B8D098C5E0876627C17A79B6BAD44A9A38C56883D97CF2D2B114A1C4F1A502AB4A9B7B5398D9E73E543B860F87062E27A9FD1A2035185F0D98857B0759BF1C39A41984C8C1A1A9027944417F84CCA0DD4206E9133F6EB6A989075D004ACCD9F57CDC928CD455443F0222DCAB9A8890004C2596EFEB06903B5D0AF33A88F14FEC760FC074A3DCDC744E9864E7EBC608A56002E483E60B8202B31377DC7F5A486D5A060733FCA9836AAEEAE05909C6B6B0DB4531271FE4F3548BD5BFF1E92160321218F963081C518874C0CBB792FDA4513F7902BE6547745A0879BA6CCD7C0F73B123DC605BC7995BDD14B018D8278C8C3966AA87A24B4A4BD3ABAFE0C8173C028DF14DAAD39C288943EAC139210392BED70C38D7AF7439697BE96977D23A27CB6E7DE7B785673C9D1B33A081A9CD417129430C6C6300C496B04E1796C9C781E4211915162DE147501B7BC55F8913C66C5CBD209BA6D115F753BA739417C8EB182200113CE17C935A0622DCBC674553B9DABCDA17BDBFB4865D58143C149512CC2E74A2B508F67BE8058461252D95042F8B7641E1D85161521B81A616A02110D7EA3BCA4723D003A4DB1673D64273B34C9432AC981A0C01DC8B8C0ED5A05D20C5331831CE56014AB0732B301CA2F8569FC061DDAA95D63667B9ACC7A1EA656F821D55A31B41F32DFB3B66DDD5CD2155438DB6923069430B61C85AB309BF56B0ECD990427C1B7D93991E783A647B1DD66696659B5C926485E1642854F0839033138A3A54C349C138977275E71E0FE985493CB85E0923095804037462AE248780006D0778334F664262E88498FCBB22D46D4F4291BB90AFBBD40FBF2B302415CF195542DCF3375E78602FE1067638AB995B70E6DBAF7B75BC11701207E489F361512B590A860401A3FACC1EF1375D8B64E0E5C7F863786D3984710C2F55ECAC578C41170194D832929075671B814FABF45C6E2BCDF8C0CBE2954C5A414E3F8878AB68CA13189D97F316517ABB4C5187DBB03413DA654E650EC1CCA0BC9472BD4BCC60CA6FCDCB26E77A025EB70EC0E60E20B19D30FC261AD11D3C0C56ACE53DE82C6A38CA5D59E9C24568B7CD15A0531315DEC20D9CC957FCF8958E3747471A8D944A6678F6AC8A8763A1759B3DC83EDD18CEEDA5036C31A897B65612D2B176E9648352899BB2869F48B1E70C1FF04864487258526226A7DC64306B6838F4286B9A81A3193F5C9C711DFC5B9FE79BC6CC14C934591F93860B66511AAB061295AF186B8CEFF5772FE50DFFBA4F5256522B5C7C55A6BA9B13B615FB3B3BDC4B159A1C84C85D717824A0573CBF219FD9B2A32AB66BF8A498A04AA4E22509A5057997B74AB5A1B27B96656BC194AF08114551709A41142B715C6E167E5BA5945729BFA702C236073FDDDB4CEADA972810253D642EC094333C028B0AF40CE2E29993369EB7DDD07164969A62466B80918873A4EA56CD80A8E559FB30F6CCE44F1F8FE60A\nsk = 35E4451348CFB9A06F1836296178B6AF41A1C0196F26525831C081EA779E6B8C4B3F150AFE2963AA756968358BFCD47D76415ED4294F02A843F89B87D6803BAD504A9165B9BEDB0C946058965B64BBF953E719160B53552C100D251CC9C111837E0A7C4C043BA0777E53B39F658B41B5F8900D4721268A8AB868B15A12C3B8F41316DCBE117AB3A027B8FC2CBF3566569A130D6DB132DDCCC5EED69A392BAE8E4A7BD6C9708A48BADEBAA79FA1AC1E729EEE0399803A374D3733AE501F1A846CD2F5166DC31B4D53750BCCCF937B1CA43C3A6CD5601EEAC251F9AAB8B2489E22CEFF436F1142CCD1BB17DFC75DB6125A1A433325A5599FD23B49BBC3D1B9195B984303735F9F2646EFD050097AB23A8AA5569AB744A934C2991BA046CB012467D39C3936EBA9CFEC4268E1A0EEA559980133B4121F9D5A603E092C199818C057B7C841A7DD00AF2C0AB3637878A9EA90BF377874FA38BF290FEA6131345340857A1A53D4BDD9201B99FB628D975A91001F907A2E9AD37C9B99B8AF915070339FDF76125D9556B1716CB74A9F18092AFD887880526FD82CB002CA49E879C50E33AF2E747104674EB1F30859E3C22F3AAEBFD30FD672B6AB855928C4085130488540C8CBDB832AE25249F46B7178AF9769A4B359664BA48DA4A746C215C58AC2752E43835B5C2A9EF0A3FCA159D29038CD60CD60F5BF508521D3D59C4F083653264776501B4FC62337FC37562973A1F9BD9532B4BDB25C21597A11E17096B155CD43C76874C44F25C1AA1BBCEA897367536ECF4124FEB6CDF2360CD5A082AC03B5E94232DFB44E1F124FDF65A4BD03B16ED729884065D77135F1F730A7A91FC2EB43271C0B2BFB8E615C07DF54041917A95B0544E8513E8C6060D14C0FB802C0F2680051341960654F3594C9972C08664B7BD30B2F031827307B95FC525A2632C2456041B1286D6F175BC0B41942E8B8BE69BB364A11AB4CC199F20AEB516CED1ACC1F4B2B91B860331677290C643BB9A00B4B65644592C5CA5BB19B25D2A7080CC32B08910C137946A3FAB6C8E31A1E97A4735A5C0A239B073C6E056053CD6498117497870718D35235019B3EE6050DCAAC31A27167FE35CE57586C364C13BCC7587CA066C6E05673E2BA0186281D94843DF10BB3A93C05025C0C691A0C41B229A55B7B506724026C4F1B48313788A212B0C951783EC9447E64314E878734AB59401923ADA0586225C7A5C00A5F97BB76632DEC47C15C06C7C20090C790404B3044136C79F46181CB1123A7D3CF969B72F6CABE063A35774A60863267B1BA34B93A5D3DB25FECE84A02429A9D142ED897320BFCC114391BCC097A078B04BD9356113B3CB993C19384886DF182E37BA659D5B8BEE24445411E318CBD092B8F8E53C63BFA3896A2CDBDC66E27F25C83FA85C260A34FD6CFE6872172F1361AA125E6C5C6C902CDEC68708C14C175E910CF002AD647A317F78F52F76BAE006A3AA51780D37A00AA20C6A532281719C5AC88641A9D15549088B5A4DDA23F443335ABFC5C2F7C5BE2A142740CBFD612A83AF271AF0AACB43833B56295B51A885D798825C3A2C04B399C528530CA24117B6E762C7B6527B0509B5963B68560015DB4D4895FD557F7434FCB61B199E793C5E763764C48DF412ACB7C756E1370CD117F8C10CAFB39CBF0C8C3F5DC8DA1855203D02B39647856B55C38E944617B8348D16A8221962A42398FB61978F40328C83A0B49BC843060D1711E289434DB4B5B0838CD87949DF5AC0727D8A528B8B5BF30CCB9E37A6664050CC5880D34C13CA42C1779B8D098C5E0876627C17A79B6BAD44A9A38C56883D97CF2D2B114A1C4F1A502AB4A9B7B5398D9E73E543B860F87062E27A9FD1A2035185F0D98857B0759BF1C39A41984C8C1A1A9027944417F84CCA0DD4206E9133F6EB6A989075D004ACCD9F57CDC928CD455443F0222DCAB9A8890004C2596EFEB06903B5D0AF33A88F14FEC760FC074A3DCDC744E9864E7EBC608A56002E483E60B8202B31377DC7F5A486D5A060733FCA9836AAEEAE05909C6B6B0DB4531271FE4F3548BD5BFF1E92160321218F963081C518874C0CBB792FDA4513F7902BE6547745A0879BA6CCD7C0F73B123DC605BC7995BDD14B018D8278C8C3966AA87A24B4A4BD3ABAFE0C8173C028DF14DAAD39C288943EAC139210392BED70C38D7AF7439697BE96977D23A27CB6E7DE7B785673C9D1B33A081A9CD417129430C6C6300C496B04E1796C9C781E4211915162DE147501B7BC55F8913C66C5CBD209BA6D115F753BA739417C8EB182200113CE17C935A0622DCBC674553B9DABCDA17BDBFB4865D58143C149512CC2E74A2B508F67BE8058461252D95042F8B7641E1D85161521B81A616A02110D7EA3BCA4723D003A4DB1673D64273B34C9432AC981A0C01DC8B8C0ED5A05D20C5331831CE56014AB0732B301CA2F8569FC061DDAA95D63667B9ACC7A1EA656F821D55A31B41F32DFB3B66DDD5CD2155438DB6923069430B61C85AB309BF56B0ECD990427C1B7D93991E783A647B1DD66696659B5C926485E1642854F0839033138A3A54C349C138977275E71E0FE985493CB85E0923095804037462AE248780006D0778334F664262E88498FCBB22D46D4F4291BB90AFBBD40FBF2B302415CF195542DCF3375E78602FE1067638AB995B70E6DBAF7B75BC11701207E489F361512B590A860401A3FACC1EF1375D8B64E0E5C7F863786D3984710C2F55ECAC578C41170194D832929075671B814FABF45C6E2BCDF8C0CBE2954C5A414E3F8878AB68CA13189D97F316517ABB4C5187DBB03413DA654E650EC1CCA0BC9472BD4BCC60CA6FCDCB26E77A025EB70EC0E60E20B19D30FC261AD11D3C0C56ACE53DE82C6A38CA5D59E9C24568B7CD15A0531315DEC20D9CC957FCF8958E3747471A8D944A6678F6AC8A8763A1759B3DC83EDD18CEEDA5036C31A897B65612D2B176E9648352899BB2869F48B1E70C1FF04864487258526226A7DC64306B6838F4286B9A81A3193F5C9C711DFC5B9FE79BC6CC14C934591F93860B66511AAB061295AF186B8CEFF5772FE50DFFBA4F5256522B5C7C55A6BA9B13B615FB3B3BDC4B159A1C84C85D717824A0573CBF219FD9B2A32AB66BF8A498A04AA4E22509A5057997B74AB5A1B27B96656BC194AF08114551709A41142B715C6E167E5BA5945729BFA702C236073FDDDB4CEADA972810253D642EC094333C028B0AF40CE2E29993369EB7DDD07164969A62466B80918873A4EA56CD80A8E559FB30F6CCE44F1F8FE60A286DE7DC142EFE935E84B0AEEBBD32D050FD9D8B008A94E59454B19EA401611DF89D7D99D5C3E0D10D6EF9AF054D842375F695ABB28E3B8EB495100F04306E92\nct = 5DC80EE57203C2A3A593240F5C226FB63EA02A9289CA40186D14AF3D9A02094554F7B14EF4453AE4F183E307BF7B9278D01E0F2C3335BD69C14642ED5FF79C29C45AFE9B515675C913AC83BBED109F7EF75BA845F6595EBAC11A0E80AD13B284F035C25E9671D7BBF6D0D2C7552DA1888B61A5F011BDBD83C63C2B03C8979D3868E08B5582152F4D3127FCD9E587B08A1860DA14AB9D078769E7114A40D559754637E0141E3163215B30587E985329A2683BAED7523E46BF08AD415E8AFF8E92AF2815A8129BD516119E54815A2A529EC01565F1A6CDCE2D60343BCCD6B705A2FFF6EEAFC75B73B7187769B0AF07879775557278F537FE44DE5D57F4854C9E0A2E7E6B55435D801C5133D133089B15064F702583F228257D9A0CAD4162230596242AEF6A26E5E8C79F9B405B2F196EEAA922C464EAA9F3D312560DDFE0DE9650F53B07464EA6F28FDED35F78A351397E23FC38BC1A790E39DA5D41D33494DEFD5A5533834A5095ADBD2B03DB0E560DF6BD4C64B41C502309B89F73C0EE40B9C6AAE58D835D95E650EE2AD57CD0D393D76D5C9BF0B90915", + "878942DBB05D8C5780734821937C929F1BA55C487FCE1C1831524BAFAAABF4D29472C82C105798A9BB324112E1B28490965C14A402E4E855DA0F3E83A2DF80F3F3BD8807112FE74907FDAAAF6C8D4DDF5C1E57DA71B4680F81BACE717B766A38C261CEED6245B9662530DAE047872C4B7655FCB0BA1A3290A34110BD31A97A51D92443F6E6540B0516B1164D783A610A3F87BDDF21593FB5EE66617E2BB370EDA0C1DA30268A6DA145003CFE65114FFEA6AC3AD209D9B3DA1F39CBB1E564D91A9AE448C23690B77E8C9292AB6820C793E767B26CBC2EEDACAC6B04F0F1F742D147FC0E2B898052E1E56BAD108335CB72B6D6AE792794F804DB1FFCE2B40C2C97048B5E8A1C6CE5FA34966FA6445ADCED31F6921D56A24CC323A4AD2AD53EBF4CD336998D06496724C1F9805C1B3A89B3511A143DEEBCBCAA4B76C8F28D9DDE856F35CC7BE4FF03D7C147486270B6FDBEFBB08C502225AED31489ECEEECAD5626A028F7A7E4535211B2E85CDFA40F1380C91AB7D6F6B544BAA8A1E6FD69001D0D47E2215C5158BEB50BFD8CBCDC828207C5027F39CDBB75FFB878AEBFB0D713DDAABD1872BF36775457BF5C2CB50B499CC3237AA4BA7AE6E62C69E317916B7548F14684CFB0DFCB1614F2D7F344BB8CC97014ACA7787A133C59EEF7EF6D010E9BA76367E0065BD41D9CE4D38C1A98838A43296B6CEF7C1FCD671537ADBC2F00AD206D742ABC670ED2A52793971A63F2678E37426A34616C69EF57430568F3BCFA11973ABC280FD527DCFFAC2FB7E612C168AD943F0AEC1A7945DD77109B18901A3DF62CDCBED7DC4F75D6AF7A1458D0FD1ECB7CBFBF09F94AE3B593BC4F842C3B2B42934A2B62963E8BF6AFF0CAAE36C1C887C97D2E5FB89572551DFE322593B2082CF2B37B807C2A60F23CF191FDEA019D05E39A36403D595F97F46910D2AD65D812481402CE51B810\nss = 6134219801B78F6FA5A998377643F828C19AB6FEE69E7DBA03C7B8E20915DE13\n\ncount = 42\nseed = 44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE\ngenerateEntropy = 610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd\nencapEntropyPreHash = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b\npk = D5F135D06AA99635C9B53244E1F898D8494B681312BFD243C8EA5B7E71CCB7A5386E477D01FCA3EF4122A63934843450A446CAFF55184D052923A393FD887DF6B045659CC282D1424B19B17CC2A2384132EFF067A0347F88C6B392AA56A3519A440438D3F90F6941112124C91FC31187AB0CE6752D9B336A1E230F97837A657599E253B7798C912A66A48314447C352B84590941355C6BD1C0951374105858A46502EF39CBB58B8E63A64E2B99C4825912155695893A62AF6745E76058D551A946161F25F1B8FC045602344A7F342FACC50E9565C1D59A459D34233C1921CEAC6E0BD936B496C8FD6A619D8B0649EB458F8943EAC97293635092666688DB559D255CE9F280227755C3605D6ED007CA718527227FA1F40DBCD88792801D8DB6B2374A23178A72276C790F902D7E969F2686C9508186788905E77132DD909397F6B6BAD3CE77E8CD4C4A3B9686CAC35ABC86D57E911CB58B0C997C1935CA64918370809D3B1B70CB09641878E7C0A141573030AA2B687761BF43AC89A81E73376793ECB32DB53368EC9E079172E9AA482FD8652583B9155683DA3467E4546F26AC98371487527C37B6646CA582017892A188FB2440CA7240C3C22577230B59AB8EC038BB95CC49C2A2F59A4A22C0C482713544FBCA9D7404B3A6AD86E8764A601B7084289858BF62A2828D3091FF015089726CA23B1CA0F87195BA1ABF80B01F101F8584C15289196744500000B431A60267174F2CC56860BC5AB4EC20D19BA8ED47535EB42FE1D33F2980BA211805A3618F2FF64D1CC634CAA6B40FD23615538366DBAF41971D8B5857298C1E406A293C1B8B7F4A499A97BE8CC51B5382020EA9C7CF809FA7323134290FA461218F4A6F495CABA2D1511EA48B7E0905B0465F7A6711F2716B17DCBB4B9A1B31933D7D3622315C79F3F11A93C8058FBC01C4839A808A5D2D45B99F7918FAF52DB1D81D669C7988BA7EB8847187AC7B76404B1A139DC4E4917C9B4E29833FD9FBC36E4BBA96E25BDE691CE0C369ACE7183C762BD04785EFCC6B614165C014A0FC4B64B24B3B46418AC5B6B7BF69CBC75090B69AAE46B4A12FEABD4E134BCAF14922367B50F17976C6705E175FF34612CF7B086ED733DEAAB0CA815A53C99B2985963DB89BDC284D251340B0E3AE20990EE93344DEA18063DB6EF4374A331244EDE00B46676475937A9472C82E124B1751A9E4203BECC77ACE092B055ABF0892637B39C3A9A011219C88139277B8BB73B9508142421939380ACFC2B81523C72E923609A0505E2979E086AB85F9663E549F3350A694458CE7B02BD8716C0F8B8946A21D99D97632952BEE898989C1ADEB710E15BB25B0A22BE598A65465BF2B899719D00F9D16367E9436803BA8C17B6B3BF62A10A017C177125396BF6745163FE24C455319CEA69393CCBAE42508156167B28A1D1050BDEFA5A789BC389031BD86E72AF5F5BC80A215260737839654998295D5ABA8C11A5417B55D67201243393B7593400D46CCA1D321C027BFB09CB08A1738C88B7D47E876EF7517F8D96CC1C93B9E93B7062227A55996FA958A684AAEDA89587B015A6B336DFB610721298AC6AB713F3A2E37B2AA7B1CCD2A876F03C72546B861E351A73036F4B363137340EFA7764C439F68D3C8E0723683AA8254A66284F447\nsk = 03A941A829C025261F44172ACF806BEA5B216B58BAB845328C36CB925A5169D6B1FF141BA44010FF2C1A446113C443C6D98CA879E673CCCB84D5519067619EDF59C23798B9B6BBCDC0D49DF5F4B21563AE54E287DCCCBE4C53C62918A6A213C460EB8C92377CB57A1B6D6467D40297FB90C6907B6BE5B03DB314C3AD5B2F46999743EC7FF0B055AF2B2753695395C6157C60115E183DDA398D136806B7017BB4FB4F36B7653BD17CABD1BFFEECBAF2EAB65B853C710820818B05AFB86388F327FEA6C3562A027C610AFD9C0BBB23A571489120C2BAA0D7AEFFD196B2DC8B40D4016FDA16062512A64462FE806D5959C49DFC0C9B2955E6480B7AF0011EDB2D44C6A43D08B5F469656CB9396C9C640BB077CC24AC0F293BAB4CBADD998ECDBA31534408B74420CB432826CB5DC8224C48159626053096063841153F723761F83315629C945778A24F826A28A90A5854BA7E80C48E44929EECA17E28304BABCD0AF4198962A045292F09AB5B7197A685A67D07EC9769B69E64EA1457FB8E1A70B23AC4A797132B021244944143E936C6E5D840494B674FDC9AEE84A091175F8E3121150B1375E028D0AB6B709A443F14C56AB67E3A8721A4B698EAC9615FA12C0E5277E4A412508446ED4999687AC5AC626CCF5468F3E944B8D099FDC319337C85E5024A0798556CFABFD47A40146691D32C0F179B5BB3C3088F2CB29E2B961B630610D1528FAB952DC75D23339C26A38F68421C12C2360F369ABCE128CD64551CA29455E02AEC7C359CF9182F5642F1BAB42814AEA8F2844AF15670421E0E113063B4B8C614487F6B6236DCB21E48613C0635E5F6A6A6E070FB665756F98156C65A6F407E1014BD6540A92E8A09EF6C944DB876250B951D16332251C5BB6B79F88928ADF6BEF819A241068B08337136B8BDC33476FDDB0292B68EDE75490DB193E267BBF2F8459FABB17D10BEF7018AE895995200453065AD45457E3E86A12C554DB3617A99613767598031C86BD5815585444DFA41CBE068034FC0A1CC2636D010230870776D2645DB640B409A292ACC909AAA11D0D05A1B1469EA2673020BB7EBC7381190C271E2CF73D37F61F12C8389843B0540117C7AB924C140D1409F701AB0C0596103A1AEF3C93A2A79BE19C7870ABE83232A7DE265A1A1280D30490FF50C414A006D8A403C50948DA4B1054B18BE35A8F9252079C5ACB2104BD42CCB51617839E07380FB3A62B3A5080295BCCA410215AB5C30A89B727363185363027BB1A6B09FE83233D79E4527371ECC8B879C81A25B3E6E088D2E786976396EF8D6C383495B52EB69BB718DD7FACF5F120303EA259FB2BC32A5269AB45E6BD8AB9F9456A68B869A4C13A0B6C98DD1BF276572EFC9A31591ACB33B9945919FD20495DB284BD4BA7C66620754E58396C0A191F20304B545AA2279CBE62D08EB4C82E60569598147F9910EF70ABF792D375420BB999E4A9CC28DB0193A124D0CC78807A54D13933B25B350A16C842E4B31337BC7734104FE564C20F27ED6AB800717BAAC4A9C954C6EC5238BCDF309C6FC497A6A9B9E4973D7D44EA53B90DB26912AC7796C327D24D3705DB5BD0266B17B145FD8CA77624C8ECCAC1C209073B2A639D5F135D06AA99635C9B53244E1F898D8494B681312BFD243C8EA5B7E71CCB7A5386E477D01FCA3EF4122A63934843450A446CAFF55184D052923A393FD887DF6B045659CC282D1424B19B17CC2A2384132EFF067A0347F88C6B392AA56A3519A440438D3F90F6941112124C91FC31187AB0CE6752D9B336A1E230F97837A657599E253B7798C912A66A48314447C352B84590941355C6BD1C0951374105858A46502EF39CBB58B8E63A64E2B99C4825912155695893A62AF6745E76058D551A946161F25F1B8FC045602344A7F342FACC50E9565C1D59A459D34233C1921CEAC6E0BD936B496C8FD6A619D8B0649EB458F8943EAC97293635092666688DB559D255CE9F280227755C3605D6ED007CA718527227FA1F40DBCD88792801D8DB6B2374A23178A72276C790F902D7E969F2686C9508186788905E77132DD909397F6B6BAD3CE77E8CD4C4A3B9686CAC35ABC86D57E911CB58B0C997C1935CA64918370809D3B1B70CB09641878E7C0A141573030AA2B687761BF43AC89A81E73376793ECB32DB53368EC9E079172E9AA482FD8652583B9155683DA3467E4546F26AC98371487527C37B6646CA582017892A188FB2440CA7240C3C22577230B59AB8EC038BB95CC49C2A2F59A4A22C0C482713544FBCA9D7404B3A6AD86E8764A601B7084289858BF62A2828D3091FF015089726CA23B1CA0F87195BA1ABF80B01F101F8584C15289196744500000B431A60267174F2CC56860BC5AB4EC20D19BA8ED47535EB42FE1D33F2980BA211805A3618F2FF64D1CC634CAA6B40FD23615538366DBAF41971D8B5857298C1E406A293C1B8B7F4A499A97BE8CC51B5382020EA9C7CF809FA7323134290FA461218F4A6F495CABA2D1511EA48B7E0905B0465F7A6711F2716B17DCBB4B9A1B31933D7D3622315C79F3F11A93C8058FBC01C4839A808A5D2D45B99F7918FAF52DB1D81D669C7988BA7EB8847187AC7B76404B1A139DC4E4917C9B4E29833FD9FBC36E4BBA96E25BDE691CE0C369ACE7183C762BD04785EFCC6B614165C014A0FC4B64B24B3B46418AC5B6B7BF69CBC75090B69AAE46B4A12FEABD4E134BCAF14922367B50F17976C6705E175FF34612CF7B086ED733DEAAB0CA815A53C99B2985963DB89BDC284D251340B0E3AE20990EE93344DEA18063DB6EF4374A331244EDE00B46676475937A9472C82E124B1751A9E420", + "3BECC77ACE092B055ABF0892637B39C3A9A011219C88139277B8BB73B9508142421939380ACFC2B81523C72E923609A0505E2979E086AB85F9663E549F3350A694458CE7B02BD8716C0F8B8946A21D99D97632952BEE898989C1ADEB710E15BB25B0A22BE598A65465BF2B899719D00F9D16367E9436803BA8C17B6B3BF62A10A017C177125396BF6745163FE24C455319CEA69393CCBAE42508156167B28A1D1050BDEFA5A789BC389031BD86E72AF5F5BC80A215260737839654998295D5ABA8C11A5417B55D67201243393B7593400D46CCA1D321C027BFB09CB08A1738C88B7D47E876EF7517F8D96CC1C93B9E93B7062227A55996FA958A684AAEDA89587B015A6B336DFB610721298AC6AB713F3A2E37B2AA7B1CCD2A876F03C72546B861E351A73036F4B363137340EFA7764C439F68D3C8E0723683AA8254A66284F447029A2E12C3E6AA668AFB5BE8A82576813FAC7B8E61C5A88AFF94ECC2770C585ECD292E4C5F9E1A55E0489BCEFFB204D672A6215F4F3980A646D9F880817C52DD\nct = B998B14D416FF33BFB8B90CEA80CC3B15F1B2B3904EB8BDF16AAF43944782D1158949BF229AC7DE3739AE24D00BE3C97354F87D52DB95D38DE1CCE5861C2C6B51879022ECB412C5A5F6B01968BA26073A2B4D50B3D5187EF0983EA79A5787BE6E23C148979E9AB236630819C8E115063514054590670E7FA6FF25913708DF4C7A30A193021311899BA6E7F33F749EC04679CCC6E24C23CBE59280213056D2C71F903BDB769B545CFC1BF53C9C9E825345AD6EBBC6A6086B19E160B1B11CCE7D76BE9F2E335E115A6FFBE367A3EDAB359216FA57C6DDAA927FE58D1A824EEA6BA19FB63C54BC9C25C83F24B51954E2772BCD80246776E5E5950A30F85E05664C54ECDCB55ABBEC7599ACDD9AC8FA721D6EF099C65E033D2CC319D9C6649D5491E0F7160DD4E7EB998442C45B28A6537B999952A77B908896560DE0DE523329C98E94E440814B9BCC1E3ED4103872EAC7DA049831DB43F643766B412BC417A18591AFCEF418F898B0E1CF9D7E8B3961718F3D8066C2A220F6323C68C2A208DC6503563EB2A0541CB98B50086DF84AD0807378360F0997D51C2A7F803CD3435758002F933A44D099A1D72E791D7B8753EE116D5B896A270C4D6559ABEC9EBDD1FD541073400208332D78934953F0C69C5AE9A3CF1E9855B54DD0080E1108CC38F83D6B4BFEEF37C49668B4AE5CFA7551A5FAA8C3660D92C8385CB64495E243423DADE733E03AF0A6E6513B4B272182BE4B5360673E68AE4999A25B090B063C956247AC6781A60BD0DCD72DA26186DB0597C7BD796C7676387B59148FC19280F6B125448600F19643A2B5C7B65DEEEBCE490928BB42C176D51A41650155B1A528CE6EE74B190032F7EF7D337A45ADB2E3BE9BBD0DDDAC77A1B9336B6560518D098BCC8E24C8CCC4C992B8E2ECFFC89B46794918D6AC78A29E9BCC724FA487CFE1EB6D23AF5F76CCEF6A497CE48A05548B19955174997961085133048F3CDFAF716B6097ACDD43CE2CA1CCC1ACD7FB02EBBA182837246D62C0D12195D8424BB998D093E6E578214FADC5CDEE3B41D11727677BFCB381E38F79731FBDBE585E4A5477225DF9730C5108CD0D4E199778168CA84233B35F362DC40DFDDC120C1E033C508A0673687461874F5FC402AF61A62E5DE21B4B62863557794A851DDDD094A20A59219748BF71D54D4D35A14EEE2098D90044A95B4ECE40A679CCF781214E8C85A5BBC8974206713C659A8915753434314117F9D46011C8C687A4BD867B81405E1B8C53D493FB2443514FFFAA6A11A02EE5EFB90C61F1B93BE985FCBE6189635A35F50F81B0457534FC5A76F541B67C2685BD06D9A00AC4A56DAE3AE6FD44841734F89D2E0B42C04F7CE9A4F0B5BA28BDFCCD378E60E2D6101FF560E379FDCDAA13EE79CCE316C4E4D4D4ADABCE0C1FD7D90FA81360B6DB61F8CA5192AFF6E174B227A2975EEC7CF1A01F6A4CA5488B1263C693F5208B36D21C484E205709D5569DA755E5818CE2D04A04B35063FC2A7AEA853AF1E1DB3550FC7B05BBBBEE59D94\nss = 787ED075F818BE6A0EAE99B113DBA31002097E0B85A5480003C505A40793403F\n\ncount = 43\nseed = 49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091\ngenerateEntropy = e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c\nencapEntropyPreHash = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689\npk = 26AB73A3355199A1833A1268A37A087DDB57AB621046DB1F407C804C488E4196048CEB762B9024C2157E7DCCAA1A762881280715A1467E766DCCB159F4780A39BC4F4A59715700070318C2AE03706B639F79A8A81AF34FBF6C9ACE4843151AB5C3CC81AF08CE392335E4FA913052119904745EC68CF3502F4663BDA74522DDD61A318539E10A853BC90A5B06AA12018C6BAC4A8123719C567719CB723B420540EBCD84C2787F37A76C6C40FC983436C26F7FDB14DF17062BE752AF2C1F1CD1026856500F3831CCA75EFF7A08D4D9C819D295674550C1C951FF9A0155856C3CC143824556C09025D55B0DB7192D969926C18912BF5CA8629401B8C53E23832CEFDB369020583B360595541F48573BA1557FD0C1058A8CC5EA7CA7F092B7DC7B4B04490FA4E72A37AAC0E33B1746ACA327258D9D29ACF140C5F70B8F94A23195D60D30A498259C6F9D06BD69F82398953B4FD39ADECA972851431B59C9614B7867CB1228E2519AC130F003903D801F70BCCD776A9B916684CD89CD71723CA732A21FECBB90D547646B987155CF5425ABBB2406CDC1821AFA8DA120A540D1C3AF175032444E1FD85F43F47903665BE922636755B5E75A90931C66E89345F57CA4A032959BDB4521CB62BB1377DC5C99FBE36C71347B81A80B6B7251FAC3732475009A719F4374BD5FF01CCE4601E761A754E05756968F33FCAC4D6A540D93951D0BB4D0D838A3112872020C2DC67718888DBF408941B877EB6543432675C879AA85F102E608AEDF267E32D333CA9C3860F907F17B553580AEC75902EC304E6C7996EE34061B40A9F4F8BA2CCC55775490DC9C2A6D5C0134E809BD305D7445C9EBF7B89F9604146B2E55A1090597033BAB2A25A3886DC524F4908ADBE98DC2D74386806AD641712D9C23A19562E4AC7F57A86FC98663E455BD963C4E63D8471B504C14EB718D8BCD6475CC45687F55099F8FE2035F3812F081B6DF2A174999765CD69433E5312BE67698346FA1030A40943F8927B2CD8A1E2CF2514333BCE85A89A6A99D03C4A5C0B847550972F9D1448D1819B3582B99A50FF97C124398CFF30967013C4DC4D374379B4E8B037EB0E570AEC147A1C99CADBB651BFB576AD61BC5449C5737BC4BA4A01F24AAD80375ACBCBAAFEB564665A192211B4D6918260C1251EAA1014C6F41427465609310D8B665C6763639C71AD48019905CC0874BE438023936856017B5562A9EE79686BCB55E04A38EB9B3BBFC07ACD4865860A77AF3B5ACF7DB344F139F79D5953778124C2C92D29CBFEDC21678E54861ECA5CD350FA09B1365FB74435316F37386B9B510E2BC585DA30A71ECC7B9913921EC8D8FBA2DBC97807B693B1E306832507CAC90410E0576611BA79C1CA9C0B106D0147680790EC5051798592D3035AEF57A0174CBC70B435710C51695852841907D41A8180123A4D911787B674ACB513C84047BBD5851C3E83A8A046062C06BD84397858241C95B8D8D2A2C53038856247506065A70A5A29B701BAE1B488A68C2BF02472D86BCBFE263E7820902102C612747CD60344957A871C7774A0980B70B56F7BC45F8E2BD2085AF080CB923B55640BAB2AA2C30F206CCBAD17BC9F58C1CDA80399962268F2AE99C43BBC1FA7D8949CD772A745BD9AB018FD3F6ED02F32CD2BF845923\nsk = C842401604C8C4C78D8417C804C2723B14733044AA2755897F65987951218361A07AA84D6AF8A956454036B79E145C93B9D4B862146BD4DB824CABCB61FB91BC306F851C9E93AC266E3C9E9C939BE422B07E512D28503A6EFA9D3EA8861E39B1AD481B8AD1805A8C0D48179AA1203C2ED7BB59D5C8EF651281C77F83AC7B49EB997965B161DB025B47CE6E2C09EDD41F5EAB1C8B7B4D20783D60C90DBFE6AC387B629BE10351868186F6A0BF68905F8C1CF34303FB577C25212919533C7044697D9425BFB76BD9D367F43B2D3613351D95395F4C2BAE63B2A4608C69364F41E85D542A08F35B940FBC3B48F63360B50AA88259C7CB4634E5A34300C5957A3644F6AE381389B53210110329FC61519113C17E64782239941CFBB11A647B814372E313205844592CC3C17319B41FF21A0BDA3F5ACAC3F18BAD085C8F27B7758B7519316653BA9C253DC94CCAD37F98D00B9FE67E2A13662C77921E4A9A86C8089682811E53A60B1089A1038483E615E6EB109A3B7636E02A44C2C3A81B96D84336CF594D24172BE1BBB9C7B3685EA45E45B81D731B9B75CCADBFDB768119B20A0C346156CBCD5BB107A00A0E3C6E949B9DB0B4AE21026C915908C5F38413C648EDB20623F35B382B0CD5F4A8D7062BEBBBCC9E809BDBB5C84042BCE2E81BB0D795C6786AF95A7E7B0629F7978A03558F98709A86319570273BEA71986AA92560260D022569D4C98A85BB98AA198DEFF63DC6BCCD1E6032EBAB8CAEE5CF4717B17D89125C67A8A472C371153A4FC9045FD3304A74B983936060F42C80454A005342C1318A284BC5B9A71A39E748A94739536B517DAC1619C00DB64C81001ACBC2793F9F29B42214442FBA962F331D48C300DA2186D21A4DE61C4B5948C7EDD1B9FA5865CAF2280A81B9F7171137D6A678C92745B1AEB9DB686BA84D65F6BEABE332FF036BD113161FA068E74032CA5736D3EA3A01F1ACFE067DFE5A5B398575BB9B148EE6155BE2B4B67B348420CE758C5855102FD06A1FE8D347EF1B073F064F1F7926BE5B2343029E5B7468E93B8ABEC6BE231B6BEE714031E04ED23C6DA37032ECC00374706EFF7453DD931D80029382F17E82A85AD7A8B25EA97D1D2AA21238B25517008B0400281168328B02869889F7F142CBF1AE8DDBA5EF2713DE649AA9AC56229494DB211B90B96AE3B2829AE528C634110A3BCD355A243F3654295B0B79B9B7D43272321959B3632313AAC107C8B7AEB83172778B7B199E736307FDF5AC6AEB40CFE750B7227F46A00B9000880D405877B63FF6C616BF4A51CA11C863A79B0E099308B42CBB7997420008268A3B762B9A5E181DA14A4A92A5B55E7950268A9A83402889A98835CB9562A5A627750A5348B3398B39783009A081A058BBABCC7740AF00B8CDBB4E0842C7F14B47FF4CB424B6252CCCCEE30398023A9B50B4BB4A2C1FF0A007A0A54EAF421FC2113F0353C7A1DA6CBF3C7F5B448B86534FCE3B3B82C3B82C3420BCA7C865AA22461B3D95522E9792B37B78C5555A62A3439F3BA7646076111336079BB8352A286E542094BB58B07CB832E2B288021034ED4934469B1723E57E57E358942730196140F47658258A761EDCBDC046C08BB89726AB73A3355199A1833A1268A37A087DDB57AB621046DB1F407C804C488E4196048CEB762B9024C2157E7DCCAA1A762881280715A1467E766DCCB159F4780A39BC4F4A59", + "715700070318C2AE03706B639F79A8A81AF34FBF6C9ACE4843151AB5C3CC81AF08CE392335E4FA913052119904745EC68CF3502F4663BDA74522DDD61A318539E10A853BC90A5B06AA12018C6BAC4A8123719C567719CB723B420540EBCD84C2787F37A76C6C40FC983436C26F7FDB14DF17062BE752AF2C1F1CD1026856500F3831CCA75EFF7A08D4D9C819D295674550C1C951FF9A0155856C3CC143824556C09025D55B0DB7192D969926C18912BF5CA8629401B8C53E23832CEFDB369020583B360595541F48573BA1557FD0C1058A8CC5EA7CA7F092B7DC7B4B04490FA4E72A37AAC0E33B1746ACA327258D9D29ACF140C5F70B8F94A23195D60D30A498259C6F9D06BD69F82398953B4FD39ADECA972851431B59C9614B7867CB1228E2519AC130F003903D801F70BCCD776A9B916684CD89CD71723CA732A21FECBB90D547646B987155CF5425ABBB2406CDC1821AFA8DA120A540D1C3AF175032444E1FD85F43F47903665BE922636755B5E75A90931C66E89345F57CA4A032959BDB4521CB62BB1377DC5C99FBE36C71347B81A80B6B7251FAC3732475009A719F4374BD5FF01CCE4601E761A754E05756968F33FCAC4D6A540D93951D0BB4D0D838A3112872020C2DC67718888DBF408941B877EB6543432675C879AA85F102E608AEDF267E32D333CA9C3860F907F17B553580AEC75902EC304E6C7996EE34061B40A9F4F8BA2CCC55775490DC9C2A6D5C0134E809BD305D7445C9EBF7B89F9604146B2E55A1090597033BAB2A25A3886DC524F4908ADBE98DC2D74386806AD641712D9C23A19562E4AC7F57A86FC98663E455BD963C4E63D8471B504C14EB718D8BCD6475CC45687F55099F8FE2035F3812F081B6DF2A174999765CD69433E5312BE67698346FA1030A40943F8927B2CD8A1E2CF2514333BCE85A89A6A99D03C4A5C0B847550972F9D1448D1819B3582B99A50FF97C124398CFF30967013C4DC4D374379B4E8B037EB0E570AEC147A1C99CADBB651BFB576AD61BC5449C5737BC4BA4A01F24AAD80375ACBCBAAFEB564665A192211B4D6918260C1251EAA1014C6F41427465609310D8B665C6763639C71AD48019905CC0874BE438023936856017B5562A9EE79686BCB55E04A38EB9B3BBFC07ACD4865860A77AF3B5ACF7DB344F139F79D5953778124C2C92D29CBFEDC21678E54861ECA5CD350FA09B1365FB74435316F37386B9B510E2BC585DA30A71ECC7B9913921EC8D8FBA2DBC97807B693B1E306832507CAC90410E0576611BA79C1CA9C0B106D0147680790EC5051798592D3035AEF57A0174CBC70B435710C51695852841907D41A8180123A4D911787B674ACB513C84047BBD5851C3E83A8A046062C06BD84397858241C95B8D8D2A2C53038856247506065A70A5A29B701BAE1B488A68C2BF02472D86BCBFE263E7820902102C612747CD60344957A871C7774A0980B70B56F7BC45F8E2BD2085AF080CB923B55640BAB2AA2C30F206CCBAD17BC9F58C1CDA80399962268F2AE99C43BBC1FA7D8949CD772A745BD9AB018FD3F6ED02F32CD2BF845923E3EC3671CC7675A321AF8584A0961101C04A432772431E77F5740BA3B2EF488D8C64C049C6DFC0F1476CFFD520B055756162F7EC94243DE6B14AC0B9E5FB366C\nct = 2CBE4AFF154B9B03FA6B19F8A1CF698078A1876ECAD645E7BF54C76787FB3A9E0E8C80574671A194238B8E9C7C42EEC9BD0A07618D33654F392C2E9D8C2A817A4F9F95232E603B9F047A379788EF8D0C548929544E393BEBBE5733ECD4BC716B0B6ED6073E30D93A064D5F714E697446821D182968FBF5A116D7E3BFE5B941A9ED42B6C5F9EFB7252529F8264200387B846AFBFBE670D72D00708B663262EC6E80308B0DF2EE80CC1320C091F8BF309F84FA5941CDAC43906E009C29A7F7B2D3D300B6DAC7DBC0551A50D449585737D7502C37A06C0297CD0AA7F49AC1CEAB3EA844EFC57851816CC01160AA0E62D5330464EBF8DD7A52A126B4CD8DE48E449749F61FCD56E786FBF8AE843FE7E68F050778BAA5C871EDD2DA3141C59C0C92A2EF8F7ABB6FF994843B77599DAFAA571A2AFDC0D5CCAEAAD4F9E025002D06F2BAA7EC5540D81D19E37A46D1DC4BF96F0F85963ECEAA0ADECE063B2730BD51C1D46A345F25E918ABF9E056F8B8D6AE34FD0E0D06120B3D91661DA17F8E4B3E68AF6915D33ABE1ED9FE8B81D7A6ADF08043F0622F5544FC9450D340E35A27B78272F70348F122D744691F5350AF7A3FB6508FAAD9EFC859FB712EF016964CC7D07940CA8B3F2581F29265369EB6D3F52B05CC82549B325CC3F8B2A4EB0A321700EFA8D86F575EB58C73199E02D04D106E0BFF79F65CEC84995DCB55FF4726B84957B25175A47F13368DE3806B386397DF10E64C365F2821B0C4C52AF2E9FB4BF0989F97D102FD70913E0B8E1E6A540710B62006EC62CFD7F907DAEDD28A7BA49BAD94F60698FDC0E6AEC63B3379D95BC84DF7916AB5A07647A777022BDA537F7E8622C642710CE2D3B0B5024E137D46080217BFB3B28EB4E58C4A9537745C88E5504AE10059B68E1FABF5AB7D3563AE2BB167530B9F9B59ABC5D9315A80318EF928CD0C785383B397F3D0244ABD0E53CC2C8E3ACE455964A66D79742C1EE9E871DEAFF22AB04DBA95BD5A5E41BF08CB7DEF3281E4D5DF9A1FAA70CF30ABECFC907A3FBC64FC3E18E8C86F4BEF19BDF096A311F0ABC76692730FA86C39EFF9451EBA149118DE84A70CD6EA2088F52EAAEC913214C79BEBFC6189E0BFEF3F058358C069A5C1CE7F55A00E951B72221BE1F324190D03F6F2005588BCB76B2BB2D5DAD1287D5E60FAC5A4C07331AF3213EF3AA063AE15A26A983490310AE8EC1F1B9B9C1495473207F0C399D4FE27DC56BE8BB7C8AF3AAC5344CEC1BCC14BCC15CFA9A8F2D58B4BCB5A6515E8FAB65EB21731A6465465A2F16D7672AB6E7BDC3F052727A2CCBB03F76F2444CECBC52B5C79E32D757DED4BD925625E3779BF3725402480F1134D707D9EA3D6A6A30D36B3033D3019D7A537B96EB47908007A396F85B5E20D2667149A3B09A3C87899B58FC1BA0C36A1FADC5D4CA07D435798E1C15D01695C40C6497020AC8BA979E11062957416CF08871AB93BFF007F86C771E3750F7E648C37C95161DD141A80D72F7D73200859FCF81D60A321962A5068CB33A8F31C\nss = B81E1EA69C6A6E1737C78FE18C36CFDCD26CEF62DEB805F22A92C49DF6596C0D\n\ncount = 44\nseed = DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE\ngenerateEntropy = c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd\nencapEntropyPreHash = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9\npk = BAC16E6E3C5E5D9C8CA207A5C77C7883B917FE0463D3101962B802549A87BF39B9BC7A30A5B654C9C96B14BC61506371E4768429DB8F7C0A6204903B9BC9311C66B907C5825621B7EBFB52F6C7CF75C169C17129595631A2FA95920317AAD4CB338329ADC69C6795158558638C474710C78763E012240CBDC2E586ADF93C028522321A94CB766F9E983FB5110A10476ECBA92FC0C120CC83632409940DB249EC569ED5740471C86623B06962910307781349F342C759886F7C376CE708091019FC407EEAE76409387D151C97CF7270319143471A84994BB596F9B5E1A78D33428740FCBAB415C575E478DB4B4E30771802E409B8C1AD4ECC9CEC1B7396E664645CCE83A40D512684E0B2750D8445D2180BE5B4CFC09BC9FFFC8D6E49B49D68C4D849B584512CBB55283722CED5566149811545609A4C5459F523C1C76667859760E690385F65768331B7654C30B8C0B26F2B8089A3C5B4F21EED42179C54AE61D22736512FA3AAC6EB018946A47CD79ACD545719C829B304477541EA92B10A1CCAE8B36BA83D5AD83083FCB51DF653CE899227C52581699B7150456CFA1910212F7678056A33755DDC7D0648164AA297F196057060009DEA8D87E86B6ABC0106A5536D7C83933AB12E294B4F50870FA0BEA16AB49B88A60BA7790549CCC0E6571E81875D5632DD8A5627E48E0395BB4C243ED9D53CCE7B591949408D2C87A5E295E3C3231F4132E1117B835529456A53D3D748C16280F4D597573685B04780F611094C665C66164A1323C290BA8C8B1031B142A3B53062AD5C59D8D112F9926E5AA591ABA711EE2BA1509AA09B86C60A969020D74E238B849374BCAE7788FAE61296D5AC7AD0927EE30912C4287E3981B7851D5823295076365196BFBEE4A3CC189020254F31B06FD8D70C43A94CF380C01936465A334FA59B3D39296305DC8B775269EE204639BB3A30AC437936CBD734A5C6477B2A451EAA0159E571BB12473B77698621D5247EB5012F608C6F070A67551F6F63ABE87BA12A56B2B2DBA44BF72E01C9A2C490579D2C103CE91A841C4F4B3AAFDDAA0CC3D33D31EC3FFB4A3F9AB87F93494720D386BB13CC482A4ADAC46395479D1421AA91216BBF56BCECB89F11588B4085A62BA0A47EF9A184C2C9346525CE006CA4819857FAC8B1498C9CA1222175CA5B01B6BD502F69F8977A0B3B04987A1897A8F2F20DCDDB098AD070D15C15C099A5672C17087C6B58245BC25C382ED3BFD5BA9B8E48932A27546A089113F37E8C85971FA10D465970D61446F106CCA6200F85EB2DE2947BB4EC57E58C1F7BE6B6FBC025A4A41EB05C516578AE9BA4C197B692D20976116BA35660CC5B612B616269A837012230B65F2913E5D0362D0B510F1272716A4DD2832D3BACC914929FF33354C01217D8A0745C9263B5D80A4F497D99D98A4D895B59A59A1DC173CA6945FA54C398F351C8C3AB8D66CB8971A68157CE3CE82104094FC83C7306D242F1F0497180842BEB8E126988C5A830D2A39C2711B033490FE1D53E432C7A453B4CEB05A5644253797135231228F246BC6A1445EFC16B2F2BC674327A62EC32DBC209F2C4A5C600920D2856DC34549BC4656F7953E697CEA6F2891FD65321F89BF2D90CF3DFC681C2FD81792135E1938CA482EF3C253D8976201852444E\nsk = 0C9C633FF39D1C6C29F8356AA02981DCF189D6535E2AC00750C30B111A88B21024E4823E7D543614F30112F7C78F1679DAB68B71AA992538658FD0C8E2984ABDC09647453B3FD99DD860238CF40C9112A7DCB57E06540148EA4AD6F97020474AFB65C5C67AB4FDB1515C6592941B1E38D4097155BD194B5324F464DBE678ECE9B5F8F57822F87ED7F3A6B470CA3FEA3314B4BB404CB66E3BBF8F2953F2682CDB65CFB47906B3962443775796564D75CBB4B9BB24A8A98D7723269E8204BA89782F974AE591808E97CB2468252C8539C2454041C9232F33B43ED8359DD6856C98BA4FC09E92F9A4AD497F8F1159E159B5AF795AB09C20AA753931F47764B6CBAB6968C7A779802B469ABB1E7F677A0A485FF5CAB2F028112EE8C35152703BB14127B33FB00A0CE21CC607E49A73544029BACA215A67091A9AD89A408794C4D2DA78557B1D31686C6B4C3749958EFC60891F12C9E0B7C19613823EEAB1D8F672089339E46C16DAF0C3B7D53727605C26A723518A2651D8762AC373817BBDDBEC1EBCA2CF91FA2A66896C55A4C946A791E5502FF19AA21CB132322BBFD127C10D87563028BC49B222E540", + "1ACDC81991828E4C111A54566E5724B40A452C0F4632B7B85F0445C881938134D516113560B0065BEB409FCEB25F796C0BA0AB190FAC0214007916CA93C2ABB11BD88553AA34C3C518BFEC423728C86E529C300A1F70225F2F683911040FF9405614E1BAAC070E0E90337E134E3C93081514A937F9798EA7B57B3A3A0B829A2697B0778C802116C067A5C368576395C43D33882F97C770519C16426284E19BAC180A2A6CB85D65B1A115316B08541DC231C123C184E82C691F20749A4B92F2D1040D09519DF7678AC282FFF9CF5124ACBE04388CCAB61BF71B87AB3B830A3EF6700A68B06770012424031E89A895AE81C8ACA9169D6495CF01CD8BA0C27AE132C16AAB0EBC4B13ABB37D67CED10A0246E87BE1233FF09A6802F6371858972D21B48D410D8CF3A8A1E664F62028CF851A134037142C20E8EAAD7DE32581B39B5D93221CF72124A73DAA2B61F3D7C8F25A973A815B351206800BBCBA60AC8C2A86A7758B38339751C23EA5523D84EC982A260256C69AF739349D206CE9C9A70DBB0A950A0B63815994A6878711578BC22942914DF8489EC5A09258EBA796E8A6FF5483A71887E55783A94201E5B88898870E67D32EAAB132519624F4B28F22E80903E591331CA792C0CEF824BC62168BE6EB8F7BA299BC519B0C370509E38377F171761521F8FC882D1B8D0DB3C2109A43D1754F75529F7B071B7492B753688FEEF12FDA217CCBA484AB79192B7933781811986430BCC010B50A5621EC15DC7BB545CABC77C336892A0DF4436E732B905D70769865CDEE0A9906438E9D921F521862A3227BAB93202DA0CD19F6221BB68FDA8155AE38132CF2A30A4A5C3DC0B17DF0016FAC3BDD56CD9D06CC8F2C6B4AC41207FC1AEAD0CD87506CAF5C043941513F0A4ABF725818C7686F0745ECE93C23F2951EE263F51A3FB3630076DCA4EA80A156DC6B4248246F638024B8782C9757E076CEAF18CC27284C321BA91766454640AD32D97E65650B39C9B23FA80405F8CEC82ABF70EA4FBAC16E6E3C5E5D9C8CA207A5C77C7883B917FE0463D3101962B802549A87BF39B9BC7A30A5B654C9C96B14BC61506371E4768429DB8F7C0A6204903B9BC9311C66B907C5825621B7EBFB52F6C7CF75C169C17129595631A2FA95920317AAD4CB338329ADC69C6795158558638C474710C78763E012240CBDC2E586ADF93C028522321A94CB766F9E983FB5110A10476ECBA92FC0C120CC83632409940DB249EC569ED5740471C86623B06962910307781349F342C759886F7C376CE708091019FC407EEAE76409387D151C97CF7270319143471A84994BB596F9B5E1A78D33428740FCBAB415C575E478DB4B4E30771802E409B8C1AD4ECC9CEC1B7396E664645CCE83A40D512684E0B2750D8445D2180BE5B4CFC09BC9FFFC8D6E49B49D68C4D849B584512CBB55283722CED5566149811545609A4C5459F523C1C76667859760E690385F65768331B7654C30B8C0B26F2B8089A3C5B4F21EED42179C54AE61D22736512FA3AAC6EB018946A47CD79ACD545719C829B304477541EA92B10A1CCAE8B36BA83D5AD83083FCB51DF653CE899227C52581699B7150456CFA1910212F7678056A33755DDC7D0648164AA297F196057060009DEA8D87E86B6ABC0106A5536D7C83933AB12E294B4F50870FA0BEA16AB49B88A60BA7790549CCC0E6571E81875D5632DD8A5627E48E0395BB4C243ED9D53CCE7B591949408D2C87A5E295E3C3231F4132E1117B835529456A53D3D748C16280F4D597573685B04780F611094C665C66164A1323C290BA8C8B1031B142A3B53062AD5C59D8D112F9926E5AA591ABA711EE2BA1509AA09B86C60A969020D74E238B849374BCAE7788FAE61296D5AC7AD0927EE30912C4287E3981B7851D5823295076365196BFBEE4A3CC189020254F31B06FD8D70C43A94CF380C01936465A334FA59B3D39296305DC8B775269EE204639BB3A30AC437936CBD734A5C6477B2A451EAA0159E571BB12473B77698621D5247EB5012F608C6F070A67551F6F63ABE87BA12A56B2B2DBA44BF72E01C9A2C490579D2C103CE91A841C4F4B3AAFDDAA0CC3D33D31EC3FFB4A3F9AB87F93494720D386BB13CC482A4ADAC46395479D1421AA91216BBF56BCECB89F11588B4085A62BA0A47EF9A184C2C9346525CE006CA4819857FAC8B1498C9CA1222175CA5B01B6BD502F69F8977A0B3B04987A1897A8F2F20DCDDB098AD070D15C15C099A5672C17087C6B58245BC25C382ED3BFD5BA9B8E48932A27546A089113F37E8C85971FA10D465970D61446F106CCA6200F85EB2DE2947BB4EC57E58C1F7BE6B6FBC025A4A41EB05C516578AE9BA4C197B692D20976116BA35660CC5B612B616269A837012230B65F2913E5D0362D0B510F1272716A4DD2832D3BACC914929FF33354C01217D8A0745C9263B5D80A4F497D99D98A4D895B59A59A1DC173CA6945FA54C398F351C8C3AB8D66CB8971A68157CE3CE82104094FC83C7306D242F1F0497180842BEB8E126988C5A830D2A39C2711B033490FE1D53E432C7A453B4CEB05A5644253797135231228F246BC6A1445EFC16B2F2BC674327A62EC32DBC209F2C4A5C600920D2856DC34549BC4656F7953E697CEA6F2891FD65321F89BF2D90CF3DFC681C2FD81792135E1938CA482EF3C253D8976201852444E79836213A513BD4CFD42ED281304E3EE4560E4E0C60FA53781F83D5BD2BBEA52E40771856EB77E4633504899FCB86C6A3D433D0B8D60E26F07BD61F1D4ED69BD\nct = EB1E2D9E00EEC89D9C0133C36834B7704FCB880E87D28F6400D5B6FA85C9585518C29C860958C2B6B1A239BC55B212796ACACBC4A2657D67DD1B61E9C36EE9682FAFD6E2231883B27587CC5CD4C36B7BF29D982D729BDEDABDA928370989F0F3FCE00A44561EFCC2A5B77F16B4C982554783D43CED6A55BAAF9FAB462813A8BB2A98CF16478AB4F1E79D0120D753EC0BCE0B4884FB27E02FDB881F7B28023D91E23340A67DC9E61B64AB16AEC77D36DCD0CE1900A7C6F3758A49D36ACA01E8E24711171F756A3A01923D896BFA63763244794BA3D01710FE2EA4064B70702ED34DB2F715B2E59683EAC0E66B6BB392DC22FC398CCFEF06764CEA27A3E2FFC329DEF35F16F357FB9A7ED25066B6A6310EF657FD348C716B468EBA86594CE6A5314CFB9BFE3FA04F849ED485459980D0FAE670A2134908C38727021AC148D041B496A97D09EFC807F2EF9A2DBE5F1C3043D3082A9E8108C020CE7B7CA6777FB3275CD0C8F8299E8CE81C1972C079BA37BF2C8BA717DA95E26225F7CE0D32A96D42045A1163A384988DFBEB1C9C68F142F1DBE10BE93F0FE5B2A2E4235ADC8300DE98A6FDC2EC76D34C4EE15DCF33DC939E80AF2DDE285E72D33E4E49A6B7DA54E5E29A072C5D19BA548D714EB4C50C9E8FFAECF92CF0B66E2D365127836E4B0B6151F29F7B8081E7DA720AAE3C66EF3D7FF2AAF0693858403AAFB7C8CFBB4104FB2F1F286DBDFCDC9A9652C724CE3F46396DA21D18A8CAC249FB2C564C638A90A3BA10295A3995557E5A171626323B1D5248798E99C8A5E0AB96EFA39BFBB2774BEFDD5939B385F881FD60CF6F86697141738307F8D9EE27863B58D83DEE565FE12308D56887AAA93DFB8DAD892792E9D2E417C4AD98E93969182BE4EEBE50102B2DF3FA72A21D271913342283F679ED232C1CB519F152EF163E3CB85D2C3F7A5E0BD44106ECE5FEC8F7CF339C4ACAEF04A1CE520EF5AEA622D63738848D7E9AC753F95267D141F4369A1E2AD2117C57523342A32716FF775F332DEAA64B6038A4099A8AD44ECF7F38C1395DD2C45ECFD9CFD7F7E3565E48EEA8C90DAF62908C402E2A421613BD321D7DC3065B6825BA8A3ADD20EAE7A9BF762446023F2DBB70AF8722C9B1CB20B4622A79F442C548502DED82CE1762DF2131BBAA0A5384B8ACC0AADC823A0042B91A8A3D32E8B003794EFAF87F28FBA18DC7D4EF29016F59D952722CCF1CB27771E5DD17F395BBD1F1FAED18BBBB579E8FB8F5A704AB587BA645EF4B51EAF09D938C30F9B79C7D67D665A9824738A547FAAE4A6C0953A3C529209C175AC946F733C5606516725A1E0626BF684A4D3AF865FB95EBC5ECA314369D5FC97B53A76FF921371E0F161F1E8D32B471906174A0B667B9C16881442FA631A169061E6B545C2BC32528AC40370884F3E9F362B2CCA5461A92605B0D7D270176B68EF60645AEEE9948FBCC1E1F26F6100E82C1FBA412F5D5BFEE5158044416CD9D4C041B17503863815CAE0ED0792052318B288B5DA1CDEA8C0A49AC381376\nss = 5D014FDCC992FCFCBDF3AF29E8DBC9E5024F2AC41E71A3EF0EA43A063BF44E79\n\ncount = 45\nseed = D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488\ngenerateEntropy = e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8\nencapEntropyPreHash = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4\npk = B873B2397A7C7ADA2F4B0B589EBC97C50174E4317ED5D9CF2878C924937BD258BACBFC83283A218D443D8EE43F8CF3C64459B189E6B3AD100A6C6A3EDE9916F89B8BB67CAC332C0519F502A4C427F5C9AF1A16A59A2122521A0C624A20149765E986339ED63567CC29CFF15D7E8AC026C96F08D6AC4E057DB4E66361B18CCDC3BCFFC300A996AB7346232DB7310662C75B39AD7AA080B23763ECE54960397B8DE836071B8914D56F95A681ACCB8FCB9529E5E4CFC2EC0601F7B0B291524E180AA0A69FA74AC2F17AA88162C481F51543A5A527DA5C42B59F9A72B14DC91574B51E5806ACE3F022D1F19E3EB621560478BB70BEB8407719A01E16313D2F0C785E3B9886F679ACFA465BA974676C0689A149AC04996F4132DC4974F2FC322B56115A64B0B5DBB8DC71869CC655DD61390B032F062B024BB71505640A41CC6174B68870DA11EAEAC28AD061F3ABCCF4E12231655EAF9285B205251EA69371D90527793495835715AC005868A78B1CAE80025426848C4AE869B52034BB266E1B97480AAA7A31E384780442D9933FDB750EFAEAC0BFA802E5314D28A17D374CAA05B46121E16362E8341DD923A66872DF3C942177B58951C40AD1641F53A53D8708EBCC22AAC67EF262B6155007DC6880A1F45CAD3A5312B282055B1E0B181D9B396591FA78DFCCB9D6A92D5CF8189C14C68CF4238654716F0A1E4F2542CD35A7E4E2185814C1F5B16D8C423213C69D5958C46960B8DF589C185087EC5474DF3C5112B5BB6BBCC6AB7160ABDC2AB28801D775CAAFA049479A837CFC8847763559EA86239889385BAA43A2848B489087FB43AA20ACD7AC05606767798500F9271271E52032F21FC2A82D8D15BF774771B69C570EC488053743DC5398C4363AEB3932A5C54D16F45A033386DBE3B2D0A851116C2CD2FA4671B95CF7E60BDCB4976A2393647B714031870B1A6B2D486A5CF2A8093B7B948C9418F3A27F6296EA12336B8A6DD5A5715CE9A70DC6978038369A10332E3AB6C2971961D5C66441ABC3290113B21C46E96C509AAF09E658D9B77928935B9A122E42BBA23F920B58EA48F3F19A7924128669C09E135F772C275E55904400495153A691794A8D182EE1314446371501E87C41A944F850C9CD288CC2EA90A4", + "E27864C79E554CC5924C4CA9A217DCA424EE8B76E49993AE4B085E9809EAE27401EB9C6C794A67A31705876243478F86D5B9F9CB3295422816526439950A412B4D1D28A70C6B9794C959BE155AADB39E00B418EFD0664B08843D20B71C547F1468C5FDD92B9D818336282F34F19B515946A7961B5A9319D9444CDC1ABA840CBB57272E4DA4AB20FACD5FE4958A57C3C812978FD772C2862DEA8B60B30A601B692DADAABA0F361CFF27C5C734A42265341641B861B7899CB311E7E0ACCE396BCE2809F24289C5361B91CBA88493991987C0ACA3B070411481E154104C15780ABAFE725DD3E1ADF00BB0EFF4A29298AC10C63FC0669DF6379294AABB4588AAD2087C9C16C9AFB654F0C9C213D79CEE1A843A84742D574DE252A4F24795E9AA631D5198F07511160300A2E02A402B4CF8AA556CE67BD341307CE5A1EB6609EFEA3F066379865489701783B2C95EE6967F0893D44D76104BF396577FD719D69EB306117F3ABD65385A87AF12D1BB6D0433\nsk = 2ECB7CAA911A2F615A13CB82E5A8BE85E1C2BCF06C71B9696682532639B57A91537E470E8514390949CFADC80B0E5C3EE3ECA869E22250560D8896B5F6EB0FC6EC0A6D01760C9108B7A26CD79039BCB3CF9EA0432FE0581626CFEDABC12F758B407C8E9DFA373F45C377FA6D41A7205A7322B737CDABC8114DF437E864C4ABBB3DD084964F971B36E24406A7A7544A260D917C0EF95CCF33B1833BB6D4232BFCE37B96004ED7779258FAAEDD9ABAEB5051D8F605EB85BE0F9599FF28B40587488FA376729685A8336C0DD213F55447E2C4895111B98E73BD783B2D08960ABCE22F6F894AE5456577A81156C66F6F1BBEBD9C04D1AC43B77936F13060D3305A3893A825781E47928FC492ADC16B31B2669882FCA10581603B400F297B7FE7525D20E82958099B2D118ED3A14A8A915731525C470B7852A9B0EF04B4A3B0B65B4C5D7D486366175540A91E752993BA979D8A446F94088C7C3A02FD5C051F900A141957E63CBD71AA012DB60A02B3872F3A623218A6B1F628FE8580E8725D9FB647F128C2519A8A0CD0649671616B462B83904CE621C95FF44697CA71CE930EAF0B28A6448A1C6B38C14800427683B71C954E49B6A3B978417B78DDB1A1B9729B89160B4C7BA49F312E23632460913D82D655D6E00B5B17A635827D8A0781E12A68C536AB40909F46A7173FA9CC9990371DCBC0B8A433436133AC123A73664A14E1409B4476AB001C17F26EBE968ED8C6A9D491B92F234499435E2DF615C849BE5F6422C8BC9DE8F148A7C0713D93642DC852B33652287010F02B1D7B77972C797ADD3A38651B4C11EA968CE53F10D38DF4160101FB0EE557BCF5B3328E12150A7C0D769812ABF2AD2C1C7661844E6B34B25E7A30EC64B6E7D4282F48344BFC6F33AB3C428C76705CB9B1E9637721C9EE60874017013374082892B4AF174749041C606B3F6690146BF1B0C8D2844F80594F265A8FB639E209C9B7FC418A230AAF340BBA34C1C66B7D570918ED6CAF8F62768620058CC7CB4FE1C762AA96A5015B82216E204C5821022CAA84AF9B12B9C9BC683747A2724C88E650539779742EDCA6A6A6C5F5D68FAAF73D4CC7AAB9B105F3A1B46CC96C915912E807AA6C841F6BE63812062ED1D07BC9164ECCEC7E6662056313CC32F63C6181CF3343ADC9073888D5756F508D65025BF6490A5F6B164A942466E60C4410C72AA69D2CA10459B890A4CB22A7613D44E70AC96ACA21169F932A6134D27A6C05582E830C0BA137DF060C6249B360831CC6B993E3D455C2E61694B11B520C64078BB552A65A3BAB407D46C0EE173BBB52A95C7CBD8612380FC0CF1655C8E691BB0493103EC80A5FC92B4951A0D78768504284AD52580F16247B3C44AF0A397F28CE3D0C0E4D34CC48B26B3998B060F2A9A013889685446B6281B3341C08E8300A013390A881A3A4937B412BF4745B069ACBF5315B9955AA4999BA827BCCBBF776829291A9067272059104522D69D1834886BDE76C078A6061305833FEFA710EBBC0DD0729493A285ACBCF2708CF93ECC76B85691E20BFA4379C8521420C231F68429BB5C76E69378F6EF3475FCA5760A5BE829C2B4FA955E0E0931423B0A615194C26225BC538E2DB29B873B2397A7C7ADA2F4B0B589EBC97C50174E4317ED5D9CF2878C924937BD258BACBFC83283A218D443D8EE43F8CF3C64459B189E6B3AD100A6C6A3EDE9916F89B8BB67CAC332C0519F502A4C427F5C9AF1A16A59A2122521A0C624A20149765E986339ED63567CC29CFF15D7E8AC026C96F08D6AC4E057DB4E66361B18CCDC3BCFFC300A996AB7346232DB7310662C75B39AD7AA080B23763ECE54960397B8DE836071B8914D56F95A681ACCB8FCB9529E5E4CFC2EC0601F7B0B291524E180AA0A69FA74AC2F17AA88162C481F51543A5A527DA5C42B59F9A72B14DC91574B51E5806ACE3F022D1F19E3EB621560478BB70BEB8407719A01E16313D2F0C785E3B9886F679ACFA465BA974676C0689A149AC04996F4132DC4974F2FC322B56115A64B0B5DBB8DC71869CC655DD61390B032F062B024BB71505640A41CC6174B68870DA11EAEAC28AD061F3ABCCF4E12231655EAF9285B205251EA69371D90527793495835715AC005868A78B1CAE80025426848C4AE869B52034BB266E1B97480AAA7A31E384780442D9933FDB750EFAEAC0BFA802E5314D28A17D374CAA05B46121E16362E8341DD923A66872DF3C942177B58951C40AD1641F53A53D8708EBCC22AAC67EF262B6155007DC6880A1F45CAD3A5312B282055B1E0B181D9B396591FA78DFCCB9D6A92D5CF8189C14C68CF4238654716F0A1E4F2542CD35A7E4E2185814C1F5B16D8C423213C69D5958C46960B8DF589C185087EC5474DF3C5112B5BB6BBCC6AB7160ABDC2AB28801D775CAAFA049479A837CFC8847763559EA86239889385BAA43A2848B489087FB43AA20ACD7AC05606767798500F9271271E52032F21FC2A82D8D15BF774771B69C570EC488053743DC5398C4363AEB3932A5C54D16F45A033386DBE3B2D0A851116C2CD2FA4671B95CF7E60BDCB4976A2393647B714031870B1A6B2D486A5CF2A8093B7B948C9418F3A27F6296EA12336B8A6DD5A5715CE9A70DC6978038369A10332E3AB6C2971961D5C66441ABC3290113B21C46E96C509AAF09E658D9B77928935B9A122E42BBA23F920B58EA48F3F19A7924128669C09E135F772C275E55904400495153A691794A8D182EE1314446371501E87C41A944F850C9CD288CC2EA90A4E27864C79E554CC5924C4CA9A217DCA424EE8B76E49993AE4B085E9809EAE27401EB9C6C794A67A31705876243478F86D5B9F9CB3295422816526439950A412B4D1D28A70C6B9794C959BE155AADB39E00B418EFD0664B08843D20B71C547F1468C5FDD92B9D818336282F34F19B515946A7961B5A9319D9444CDC1ABA840CBB57272E4DA4AB20FACD5FE4958A57C3C812978FD772C2862DEA8B60B30A601B692DADAABA0F361CFF27C5C734A42265341641B861B7899CB311E7E0ACCE396BCE2809F24289C5361B91CBA88493991987C0ACA3B070411481E154104C15780ABAFE725DD3E1ADF00BB0EFF4A29298AC10C63FC0669DF6379294AABB4588AAD2087C9C16C9AFB654F0C9C213D79CEE1A843A84742D574DE252A4F24795E9AA631D5198F07511160300A2E02A402B4CF8AA556CE67BD341307CE5A1EB6609EFEA3F066379865489701783B2C95EE6967F0893D44D76104BF396577FD719D69EB306117F3ABD65385A87AF12D1BB6D04330C2E803C2872400C49E1BB10232946AB939319E84FF32CD354DC15D082CDE5A3DED5EDAEC5DE3BF5B4D7C2F2E18E87F499C1968993EFF196753DB8045E2C8BA8\nct = 388475CB89B7F408D2A18DD764070424C7598C459F203221847E08ECF1FDBD3B5F1878CB148EA1E42A1790BAA2432029C674916130A30AAD99DCA2ADC8AABE96C9437AAA361C0E28110A8B6BD9AAC047191B728D9C84EBEEBC7EA2154EDE6065F9313C47DDB6A05413FF5E3571F69BCA571770E9E217136038607BEF7F60CF079E766CACA7875DECF7BF7A8B54D688BCB63EF920586F4733AB3D86BBA18540A20D27C135119CBB7DB4E0F8896B0744557DFBB3C0F615130505E59FBA005B57A317FF4C87BE8906B54870A0C46136BC89E144502F41A2B4564DA200E0AB5A3FA91836F4858FF298456F0C475BB3B8BD057A63B6F9B5DAFDD76C2C111F7B3A933A2F3CE069427077C58EC94A158B6CB4C13FB027CFF9DF3FC7CAE5BDCCD31E3F6A3BC95E6EFAF8CA24F773056AF6C8D9B2798057E2366BDD54FF417B8BDCAD4FC0FF8E64C6D258438F98DD0682A716BA2FCBA64B4CB559630635D115DD846B7182DB50A7B92C73463673CB017EBE6CCE190700E73EF73A790FA85F04656D0085023F483F50DCD5BA9F0EEF8B3E5EDDCF0F4090BC2D243215321E606C4107FEA5564041C07705C545D7956A8E163B9B641C7CEA51AB67A2C29BFFE9C7CF0D3941C0E45664A40F2AB5031C2BDE8EE7E5AA4228685A845F4CBDE42DC3F9157F4FA03631299C84149206B7E087CD56A5809BE0A7CBE54509A29AAD8465BB737DF2631E86DCCC3ABF5ACEA6091813F1E9DC49D9F998C56E72972D9CD51A95A95B59B9AC98B8EB07957E59547FDB243F873FD5A3E77478A6F2368177BFBB95F2D8B2F7924655E271850A72680D2C7ED2CFE57ABB59BE1DB29A84C715828AD7E06E1928747CFE2E1351FD07534AB50855818EFF4CA87A60E86217F991C12380255CCCA0FEFF97C35C7214157F533AF3605B54902AC8300C8E4CD496033D3D05752B3AAA85F5CEFE81632B19263F944C637DCE318E55A8A4BC5AC296DE727708D86367970C17DAF3012DF0AF19A32169153E6C07C28379761B64CA1B87D7A1B8680B9749936D205DA28B2E8E9AFCDFA26C975914332538A54730D96037AE74439289AA97D76045103540230003A430A067C58C881BFBF224DF4DA5841D1B6781937F933267C32698908A6D31BC0402E3274657ADF416C3C9D7378338593442D4CCDCDF7ABC61A45C4EBA05C0737EF175C6F01CB7022A7905A365866961F7D45FAFF18455553012D1A79225A08871971D926D978B5ADFA1723314991467782B9CF2FD063CA70A49EDAFE31BAF3CE55016713CD15F8828A09FA4D6D093C29DE550EBB0BE37FCF1C5A4B6556153578587A0762054EC01E0A114AE186FBBD97BD83F30B411563B4E4369D7A24033ABDF1C0CDDF0958F2CA2272AD358F4C60EC7251E899C6C11B001E4025A6733B270A893F384EAA93DA2F6C4D8C2DD92A1B9305252BE65C3776F5B6DBD92EBDB9E12955C1358C011AFBA5FB7E52AC27D64FAEB290177CF6195658E6D2BE5D6040DE2D26677D47349FFC38123B576A6382ADF7816344D7E257EBD\nss = 80548D4687DA93177D06D98C1E2DEF33FE85E770F8B871D2F74CAE533F654692\n\ncount = 46\nseed = 6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493\ngenerateEntropy = c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2\nencapEntropyPreHash = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a\npk = 0846C63E2C3018BC8733F05F8CE3B614088A78766920", + "5AC9889BCE2D3B523F366F4BF811F004666B2B654431B135D97A70A00FB9A3928C1A4A2C7285F6F7B19BB766BBE6B966B4013EC06833EC6F1118A772C2465D81B77BA740B7EA33129218542A41E2F1B10F42BB42396E9A6C5011351E783641AA692A982272D9544AC93580FA6A51B8C7B6A4B5B1CE3B58F1D901855BBB2B68B988953AB63607D988999ED96E5A4B963497A061AC69BD90C4EAB7C0DC17820B6963B0293D4CA30D82F5997A877A9AA71C5C7893C1D153AC6779D0A88190B13DF828BF3AFAC9D7EA392FEA899EF844535187AF673972399A5FA31034C02D70B57B97434ECBF3B1985C86EC75B23AC0AFAA67225F12A257B78341966BFD2569670680E012899C112AD3873AAAF26D2F4A5C8CC133C92B9A446530C169B6B87B118D03329374A71ADA1778A2035986CEAE200C763A12B6E2B2FDB672B4D58D8BE640E61576F2CAC617A5ADA5D1B874BBAC9D272EE4C881BBDCCA1C9A84626012B988395EB5A4A48BAB1E7551B6CB57EA7B627138C3AC252BDA1A83CCFAAD69E38CEDA6B149C1B3BA295FD5025C63225CE88CCDFBFA6B3950CBCDF96E14DC0962745A5FA32D10525F71D895A2085620C89024D922359741BE366CE9038AA3B260320A456858A7B8D01BCA12316E9C6D1782BEDCB590A1D2AD9ADA0C26D3818652CE6F3B6403C94DBCD1424D090E9DEAC559472C9AC19CBB26C16E8B27DB9140A1161EA96A171728689CD6B6BA0C8002BA6C46719A1A0C175638770CD088AE29A7FA958209788ADE14354A1B0880F05EF7C15A6786BE063B357FC7521973ABE4FCAC0A8C26F3EAA052959E2F973709C9C6BBF4C889C8B76C0AC81353B4A4DC81B7D316F75ACCDD1911DF10A7E838A7C2023EA1EB0A956ABB53FBA02C48396807229F492966796805E04AD62B8107493AAB264A5BEB32F5459C06AA6E7F79ACBF171899A911FA910DFA6687B2C28C1D419A4817ABCF656FF669B587B72374F3CC20B92858361D21BB85A3B9ABA157100875C993B54CCBC84DB2D72374BCAE29C5479CC95197E625DA047447EA5797551595853651912DAEC4891E68901BB67FAA98BC5050BB50E913645874FB7A0E51C816ACC88A7F8A4AD383170A583A2E17B0D5766E12DCC827386BA8D868EE16B2FB892ACA3941CDFA7A487C13AF9787A309779B759CDC037C13E839314803BB10A3AB19B7FAE477C8C322BF05BD3AD9CFB0B241371C85FFCB607748CB518A6C896830B191737BA289B15288AB59869E22637C57019818801EF9A6B7160AC1B5B4D7519B41905E6687B3FA7230EB88A3C9530813561308B68BD2B740E7AA08CA72CD6468C008CCAB34AB99B6773C533B3914B19B2B80BF7E783E7BD9366C8962E7F3410F34651EE606EB737E6C9C5F6D306AF7348CE955228CF02D15B8ABAED16994B56260221BEB1A29BE5596E204B9CE111127989BD2AB49CF27C976F74AA7B084FA6B8400A25F3C36213F7C2D160045D865C75AA14542F5A4E4D1459B5676491C6A3FA0A2F0319CA1A63A401C9C3A14C94F0016A9A69E64C522AEE93E8B96B4F6691322242B20353E0D8B995A6A9129E961AE7349F92C92A90B833E82B9FAE1AD459AD417635C409C28F9EF936AE28D221563E30F83162CEF01B482889E\nsk = F3AC3178BC3E6B8002EB20046EE3288F9CC63C1ABD0B14A118D52E2C9A998D4C67E2014415084F520945F55B985ADAC8C503079789AECC491EB7BA540F32BE8823A4A837786BE140D260CFF5D46186588F4FE2419E0C4BA1B619567B9D8206B53AB1289640520F2259F5D6854871498B23696A321813D7A544E77FB3100B34C89AF2C63856FB43BB0A74A6073958D1199B4098386984847962B353B4D81AAF4CF65349C8197DB8C1B29A91FDE5AF1F9749A96B3B82C567207A81A163347919AEA565304B4820369799D352CE72415CF1C692537A48AB603B9DC741A08A66D874BF46DAAD570B6F1F4133067A1D900CA87CC25E91C4CE1C84B46D3C5BAAD46FED227268F1A9DBA968EFF27249B3C6E4C7C19E8A13046A2B45BC24F4304A80C09D37AC289F924F33E97181B8393EAA82A6FA54F2E76DD88791B5C3773707046C362D94EA547C3050AB251953464F4E540764B08103A88E448446F6B82375C15E3CA9A98798639B83638ADA857BDC1E3C6705471975C51B8087A26348BABEFD234D27D6C055D3AAB7560B28DCC13D343A79530AC868B5F6AC83AF04B8D7A20B64DABE9DE32A5C1B2C2ACACCC4588C1BA26F5462AAA5C1BDBC36467F346A1AB5C5840A07BD33CEB44093659BB0451C4C87CA4852172DC0BC3674B4275078CD2B9A3AFD61BFE454107D092E5840C4968C547ADC723C1970CFE705C5D33E3A4533F0028655C6BA44AB22C2A4C85A82B4B6DCC09765124E43C985459CB2AB1519DB1EC6F348D017A785484802D90E0222CA2313B4FBC465DEC0CD4F3A5675E33CF0DB79145867D5F0B8F340526C8A744929728CECCD146B6E66D03F660AA4E2E15D200B5960F3A03B571BB2E59160048E498C15379027E07987DDD841BDACA79764BCAA1C9843FCCC65B53695335D9D4CC789E062571665DA99B4E10368467AA551775C39C7C9DFE7624E8940F294C8655503F2F970071B40F6BA3544C64C41887184828BE6057A9E972631604901A7870733580C6AB8D4AA18B49CB4D567577AA8B0CA2490EDC68B168583B8B38415D32F5558996CC911A9470951430C36F71712F1C579A12327C41C441C980C286B71A31748EA54DF2A557FD1701C3173944B7B40117EF9CB08A7D03D45531B8DE4C753F697EC4B4303448C260B0783C81ED599425D9B16806828BF795C8CF65A95F366BB90110CC75D3E6064BEE17CF1497F36C48E68B46EC07417B2A876CB556C705C7DDC387D74F2B0AEEC9070D227AF09A324495F551680A474328D379AAC253A6F4C42C865A183D7C2F4F8CA94A92388B1AFBB5408CB1C0FCD3C945E2923ACDB7E16A45C03EC3298B3C44E9C1E75D049B2EBBCF2F29A2D3B7FC68644530010E052A0D357809009CD786604A39898B385B70AD7B3BE011EA83B93D4426F4F20A3D0836FC6FB532FA14536285013050C16D01C5752884E49A82A4A0BDBC8BC2C7598D548278703AB4C607A16B1BAB64052F40A06D3915CD03825F12C069D956F2A5662E05804183932B5216CA66274214ACF5C01A7F4C77EBF522DB776068F94151F7AC33831259B53BC48E99C50B260FAEC0B7BD3CD4FA9B5A5C2588CF098FCE5AAEEB15FE651355537953D9B8580313B56336F0846C63E2C3018BC8733F05F8CE3B614088A787669205AC9889BCE2D3B523F366F4BF811F004666B2B654431B135D97A70A00FB9A3928C1A4A2C7285F6F7B19BB766BBE6B966B4013EC06833EC6F1118A772C2465D81B77BA740B7EA33129218542A41E2F1B10F42BB42396E9A6C5011351E783641AA692A982272D9544AC93580FA6A51B8C7B6A4B5B1CE3B58F1D901855BBB2B68B988953AB63607D988999ED96E5A4B963497A061AC69BD90C4EAB7C0DC17820B6963B0293D4CA30D82F5997A877A9AA71C5C7893C1D153AC6779D0A88190B13DF828BF3AFAC9D7EA392FEA899EF844535187AF673972399A5FA31034C02D70B57B97434ECBF3B1985C86EC75B23AC0AFAA67225F12A257B78341966BFD2569670680E012899C112AD3873AAAF26D2F4A5C8CC133C92B9A446530C169B6B87B118D03329374A71ADA1778A2035986CEAE200C763A12B6E2B2FDB672B4D58D8BE640E61576F2CAC617A5ADA5D1B874BBAC9D272EE4C881BBDCCA1C9A84626012B988395EB5A4A48BAB1E7551B6CB57EA7B627138C3AC252BDA1A83CCFAAD69E38CEDA6B149C1B3BA295FD5025C63225CE88CCDFBFA6B3950CBCDF96E14DC0962745A5FA32D10525F71D895A2085620C89024D922359741BE366CE9038AA3B260320A456858A7B8D01BCA12316E9C6D1782BEDCB590A1D2AD9ADA0C26D3818652CE6F3B6403C94DBCD1424D090E9DEAC559472C9AC19CBB26C16E8B27DB9140A1161EA96A171728689CD6B6BA0C8002BA6C46719A1A0C175638770CD088AE29A7FA958209788ADE14354A1B0880F05EF7C15A6786BE063B357FC7521973ABE4FCAC0A8C26F3EAA052959E2F973709C9C6BBF4C889C8B76C0AC81353B4A4DC81B7D316F75ACCDD1911DF10A7E838A7C2023EA1EB0A956ABB53FBA02C48396807229F492966796805E04AD62B8107493AAB264A5BEB32F5459C06AA6E7F79ACBF171899A911FA910DFA6687B2C28C1D419A4817ABCF656FF669B587B72374F3CC20B92858361D21BB85A3B9ABA157100875C993B54CCBC84DB2D72374BCAE29C5479CC95197E625DA047447EA5797551595853651912DAEC4891E68901BB67FAA98BC5050BB50E913645874FB7A0E51C816ACC88A7F8A4AD383170A583A2E17B0D5766E12DCC827386BA8D868EE16B2FB892ACA3941CDFA7A487C13AF9787A309779B759CDC037C13E839314803BB10A3AB19B7FAE477C8C322BF05BD3AD9CFB0B241371C85FFCB607748CB518A6C896830B191737BA289B15288AB59869E22637C57019818801EF9A6B7160AC1B5B4D7519B41905E6687B3FA7230EB88A3C9530813561308B68BD2B740E7AA08CA72CD6468C008CCAB34AB99B6773C533B3914B19B2B80BF7E783E7BD9366C8962E7F3410F34651EE606EB737E6C9C5F6D306AF7348CE955228CF02D15B8ABAED16994B56260221BEB1A29BE5596E204B9CE111127989BD2AB49CF27C976F74AA7B084FA6B8400A25F3C36213F7C2D160045D865C75AA14542F5A4E4D1459B5676491C6A3FA0A2F0319CA1A63A401C9C3A14C94F0016A9A69E64C522AEE93E8B96B4F6691322242B20353E0D8B995A6A9129E961AE7349F92C92A90B833E82B9FAE1AD459AD417635C409C28F9EF936AE28D221563E30F83162CEF01B482889E5818AC8D7A38C781E3A0BC43D088E6D391D1D67D9639B260BB6F58A19A57150D1C96249919CEDC2369D8D739AB125E0D2CCB82DFEBCD90240A545CDFE07511F2\nct = AF94CC0284B48C7858A08B77AE1161A30C07A30D48FADFC030089988BF1B24FF5607C9B5C714AE299658BC5E8801AF51E8876908120917B00751B558FFB7F54E875B71D91E02FB9C218EA63F2BAEB28A16F912896652D7A20861311BEDCB97846CA5F5C43EFC5E09BEC6B699C2EFC6D634F6C310E97793F0FA496970E2B9A3F74B35F96890468FAAB476C179AD7F0D3C601CD54D583C6763DE4A839B7855E68F3BA4756A2AA1EC59FECDEB1D7FAC0B9EB71184240AEEB740A9579BA6350F8F6B930A8AC33D3BFCD3D28DE47430FC34248EE1B292B94BB27BDDC9D9B1A6CDD7B5AAB7FA324295E1B80AC76E04465A50310E0F3DEE3A8414C1927CA2AC9921A50E970A48571C8B73D07C54F58E7D3CDA82BC4A609A9840F3FFEBFD7EC71E52D875712EE5CA94A500E28F5D3193A3EC22C83A2159DEF810FB3640440BDC870295C70CE4D45B9FC902D5F8590C0E1B45A5BC150D379053F277E3D8368EFA67D333031A2B131B8FAB6522D6701BD119E5493C5E6B4862535D4C119265FDF2682A7949BBC1D4BEF0893D979E35719F0D418317D0A828BE60E9F81A35DBA44FF1C286DB5D7BCD3734576C6F5C8A7BAC8DD8364465378557237BF26F539FF9D68FA86244BDB364FB1F6C893CFEF73A9D312037F161482CE9480ABF28809B05318F7A4749983E3577CA3F19E60492BE75DE65171FB51A87301DB5DF692FBB49906696842636B85D6DD6DD020C5B67FEEE25B7FDC6", + "8B0FC389B76DC02DAD17C2B58A1B3DD2C7FB17848442F49A674ABE74838095A97949F664F474DAAC1E708F9BAEDD23A32A2A5556F42AF0F2FF57C487E7C97B5CC6E4CCD3E923976E5101AE7C4AE8EEB07FA20CC7BC1EE39F26B002AA0149B84AA7E868ECEC02C304ECF5AEFA03B98F613738D23C09903901481D8F14160BD18DFC0686DA00595C7178DFFEE5A4A9A1F4B8F27B563C4EE84B8BF033EEE964277944D86E416D67F663AD2200922762F1900CB0F65A81EEEE4F758BB20962A85D2FA0155296ED38AC8A4A642E6BDF4E772B7309F4E0280552DB9FDF107D2C3ADED893A015764069D3D6D5E689F1DFAF26A8FDC8628F6B33E8B5D209AB3F3CC4960409486C52D539E32D27687C2BA004201CCFAA17DEECF6533D47CEF4DDF9B6CC8E25F3648BCE3298423485045762E4CD4B85E28B5FBE22C332EE0BC587B2C31AF7B98FD97E95CA1FBC9A57E654BD8B5E54C9D1B3FB59527B1C8F9736E95293BB74613708721281C0E80B79C73E1DB9DBC4B1378A18174D068C5A2B6CFB4F2020EDD74A40FA308D5E60174696E8DF28063198F58605B5DDCD759B6BFB1C0C2CFC9F31FD5E041F047EC94A716758BF66782127771FCE174DC0F141E866241573D48AB0EFA04497686BB3948C785A3F3381BA34E44090E02F5911FFF19570341A7AD12D3E7A487865950462C7DB9F7290E8453981EA4DB3F39619F27DE8B68866BE3A2C1BB6901A646A180E152802831D12FB305CF084DD64C5ADA579BE82A7C55846B550FCD3F4C3274297F08AE37C4C2B61\nss = 2F2F58E23DBA54D8A44BA11AA4546EE3F1819C6243E986249B7102019DE3A777\n\ncount = 47\nseed = 730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3\ngenerateEntropy = ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d\nencapEntropyPreHash = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147\npk = 964435FC16BE2CD2276B7BC78EE8B5C963AF2AF4673A93940B429131663CC124BE5A706BFF5C157DC17DC5CBC2A11418DC4B8A28C841C5A831B1A2BA989A20FDD17DD06706CEABC0D20714D5595D54216E9FB6824E3272DE0A1E262AA246494152B1CFD95C970F38AA35FC0337B26E76C77A0A76BC2C57B80757550B11807A423B85E32DDB537AB6D4694CB8B9ED58B11C9A6ACC746749C21011A66DBD7896329C3A31D0A7E1E78EFC93574CB7B051D79188EA4981DC6299EB9BD1BC1A133A41565305CD4A09FBB10934E7A3D132BB0EB83559C484EBC92F7CF93E445020B7187E2705A2D1A8386C008EC7F22FE172088360CD3FD160E7020B6D0C747CCBBEDDB1B84FA7549F625DBC064621FC2E13F720188C200C1AC1F10394FE4117018B9640632FBED570C942575FF61A7149A51F9993B90827EA2A08C32A330747CA27ECAE452154CE1A6A67A8B63676998AF929E8A7A9D2AB709E2162A2E0BC0721BFC7E49C5B2C9BA975B3BD881AA3782391F5CEE4CC1835C83732C84F54B373EB18869B2C90E9F986A0EA345CBB020333893B463671C95E6AA07193D06F7E62BF4361CD0009B1E528C85D147D0E650CEA7B0C67F1B4FB754BF2F1A7B9CC621D4C34682A6195776BBB9B2CC866CFA94C368A2B4B346C75A2A6BFE946CEF09416AEF21B15D3C72B7CB408141608C058E506271380841656963174C70E09C1F593ACDFB9BF4A3A9387B693F882495149C62A77595574C0BC745B51BA8338C6361A293402E74DF74A7A70B49FAA1AC4D66B89FB6C31DAE59F318B610F00BF4F4A282F752A070582F2F3C141E168F6FA037F23945893766215B9EE9A3A1DE662060A5B1FD34BC8DAC56C0875A6F82ECF8863C1692DC2073CF517CBED3C362A853BEEF1A8CF2247000CC4CD8176CE980D683B8AD89B3EABA3B962624F5AB3695FA10A88055DDD664A2BA0749E439A39C6999496999BE3BA7BBA2FFE06388B1A6C83068AE70A1C6F8A36E788B8AA148933C896EDA61EFC86CBB7D5C9CC96C9F137C6A9210347289010979BC1E16700A610C7C990D685550F537AB0C45B2BC57E5EF4C08B2220961C6E17E95E2E4482A4A94DA2E17B6854CE57C263D69429E1566BAB646FDB216E0444CD8FCB7DF4168AE66223A0CCAD971583B5917C4805271A17B4A1E17462815CB39332699AC447332A3F7ACEDC03541E93A822A96089D6A1F47A7DF35CC9B659CF419BCD2131B98AACA67343CDBAFA3DB35661C38C0BA1E18043A4C945067ADEE46E428A16011ABFEB58C1BC8B2330288B57CC319389921857C9D015A0471128C34CBC13417DB24B91A3567AC299CFA6D4C2F1123661A3CE0996111D340D9613B966955C6A758FA7F3556F6716E5AC7AD3A93174B2032A983CC0C73C0DE302F9F83A0DE89A1FB576CD3B41505B5BA712C387730C45399B8CF0B0E548CBED984E7BB5095CF7263B05CBA437AC6FC369EBCA85E0211715133BCC314723D79C9B93ABAC57AD3D3A5E77F2986A3539EB795A5B4967AC7753115B916236A97900870B658B9D4B3E35827E1AA9ADC3500FD9BA18FC6B03465903858C61C1259CF485338CB700EB731F31643B469BB259210CEC78C158E3290573C5228518E4697F19171D8F1A3A633448FE9C83BD28097BB29A168DB5AF1D1B354B6881A2CE509B\nsk = 37F7089480382622AC6687B4B15BBDBC1A9AD7467E8FF4CF44F0614DE74B9591B9C5410D2D7084BB57AC27963AAFAC148DE80DDA6232F4A0C634D677A80C226FE67063191C05A54AFC026080877538F63DF93CC6FDECBBC0A9A0A4215488DA1A2F7B1EA8F8B917F32F397B94C80170BCD423C1F1BA4C736449F84BAFD6711B0070DAE72DE1EA3923435FE15A4FB35AC98D6379F0A44C200A37704B5B269BA3A555961ACA5E2CC1518FA4BAD3C23438E06952C9317D198B0C112D79A89560DC3361F5732F820CE4D16ED448AC2ED221C8EA3601602C27F640DCC394A7ECB5079978CF52B80DE15C3015839A44B9EE36837866C5C8E9579849B331E53DBC049E46DBB524C2090A54BA793C845420A7C2C29E78A9B8C83C310D780F74127C02A59AB68C1B29952DFF1196D0940EDC338DF3E1C1C8E34FD0DAC4D5596F97A2AFA98B1E8BE46BC0A96DF412639AE5B52229086229B5BC79AC020B61A56C04091C10CF9940F798A9C50BA1F5FB30BFA947F20B62A60215C5A88D23B70C0E299C53F49A1ED511AC5812558133D9F195E1FB5D77314559EA79E63A88E781C4224155ABB5CA91F089C0C609CECCA32E549B0CBA167D9307A3A64681A815A69C5D7E787751162483E7701437034F0864D8D53201FAB9763C7921ECA6F11247E7EA364298C1C3AB893549572BEC45C1A8C3B88659CFD526810B23F2095AA6C1424C7178187109F83063B52547B9C731F9933622A33C7A8B927A50191593488F9A0D12331017919159C7A027C3956FE109393A167A6475CEBB49224736847319D161490EC52396D7BABFB638BDEA29F50C9CE37314FC858455F63FCC70CFCB751DF12274FEEB45A124AB1B997C917A550C3469A0C185EB0238FFCB4DCBF751E12CA17A71B807B1446EA7180EE302E6998EF8D12A857C84FFC377F5E42FD41238A54345229916A715977025B3B4A6060F778DE7D426A2F95927335CB202BF4080B8510CC0DA12C4EAEC4BBFA42997E21504B8C5D32604F1D66E8D55B50C393F973ACD37A236DB595E3EF08239C42FB5E9243D967181B9B94F4521C104A8AA726DEC057ABD419BC8C6CF350C91ACB78B0832144F409F78992652E30EED7BA2375B3245D877C8E8B873F0427071C956633495381A2C642B15282B9945C758910FE469CD091B4458218105DA96A479BE0AC6B3BA155D359B2815916E93E9BAD3D431945B852E519DF0129174B24A32CC9FB8A62DE96733D153A799CB8FBA3C86B9101CF3D4A97BD3B699467991A57129607C27274D3224CD1848C17F1550BE47B71A119873045E215BB817CB92C12A7BDC6347DF8B64DD686873D800B4672AADE8AF56D2995546CC37C06F9212A54745C5597184EA85CEDCA7B980386FB91B8AE677A035A4547B5848879C2567C8CD6AC285F6F2460DBC0B73F5AE0993C988418C234895380C556042ACD15A6C015A13EBE16CDEA4BE38528A9D244230A0AB053C568E31C64D06A3D7BCA0E5207B7669811A3512F8AC6887137B0B7627D2401CCD604AE786753FB6568CB522B28712211208C1849D1F75CC4FB951D2AA081ADA952998B0B0E938B77359233A76C135897E91059CC5639E978C12C6BBFB735FEF4BCB1D60180DF21D964435FC16BE2CD2276B7BC78EE8B5C963AF2AF4673A93940B429131663CC124BE5A706BFF5C157DC17DC5CBC2A11418DC4B8A28C841C5A831B1A2BA989A20FDD17DD06706CEABC0D20714D5595D54216E9FB6824E3272DE0A1E262AA246494152B1CFD95C970F38AA35FC0337B26E76C77A0A76BC2C57B80757550B11807A423B85E32DDB537AB6D4694CB8B9ED58B11C9A6ACC746749C21011A66DBD7896329C3A31D0A7E1E78EFC93574CB7B051D79188EA4981DC6299EB9BD1BC1A133A41565305CD4A09FBB10934E7A3D132BB0EB83559C484EBC92F7CF93E445020B7187E2705A2D1A8386C008EC7F22FE172088360CD3FD160E7020B6D0C747CCBBEDDB1B84FA7549F625DBC064621FC2E13F720188C200C1AC1F10394FE4117018B9640632FBED570C942575FF61A7149A51F9993B90827EA2A08C32A330747CA27ECAE452154CE1A6A67A8B63676998AF929E8A7A9D2AB709E2162A2E0BC0721BFC7E49C5B2C9BA975B3BD881AA3782391F5CEE4CC1835C83732C84F54B373EB18869B2C90E9F986A0EA345CBB020333893B463671C95E6AA07193D06F7E62BF4361CD0009B1E528C85D147D0E650CEA7B0C67F1B4FB754BF2F1A7B9CC621D4C34682A6195776BBB9B2CC866CFA94C368A2B4B346C75A2A6BFE946CEF09416AEF21B15D3C72B7CB408141608C058E506271380841656963174C70E09C1F593ACDFB9BF4A3A9387B693F882495149C62A77595574C0BC745B51BA8338C6361A293402E74DF74A7A70B49FAA1AC4D66B89FB6C31DAE59F318B610F00BF4F4A282F752A070582F2F3C141E168F6FA037F23945893766215B9EE9A3A1DE662060A5B1FD34BC8DAC56C0875A6F82ECF8863C1692DC2073CF517CBED3C362A853BEEF1A8CF2247000CC4CD8176CE980D683B8AD89B3EABA3B962624F5AB3695FA10A88055DDD664A2BA0749E439A39C6999496999BE3BA7BBA2FFE06388B1A6C83068AE70A1C6F8A36E788B8AA148933C896EDA61EFC86CBB7D5C9CC96C9F137C6A9210347289010979BC1E16700A610C7C990D685550F537AB0C45B2BC57E5EF4C08B2220961C6E17E95E2E4482A4A94DA2E17B6854CE57C263D69429E1566BAB646FDB216E0444CD8FCB7DF4168AE66223A0CCAD971583B5917C4805271A17B4A1E17462815CB39332699AC447332A3F7ACEDC03541E93A822A96089D6A1F47A7DF35CC9B659CF419BCD2131B98AACA67343CDBAFA3DB35661C38C0BA1E18043A4C945067ADEE46E428A16011ABFEB58C1BC8B2330288B57CC319389921857C9D015A0471128C34CBC13417DB24B91A3567AC299CFA6D4C2F1123661A3CE0996111D340D9613B966955C6A758FA7F3556F6716E5AC7AD3A93174B203", + "2A983CC0C73C0DE302F9F83A0DE89A1FB576CD3B41505B5BA712C387730C45399B8CF0B0E548CBED984E7BB5095CF7263B05CBA437AC6FC369EBCA85E0211715133BCC314723D79C9B93ABAC57AD3D3A5E77F2986A3539EB795A5B4967AC7753115B916236A97900870B658B9D4B3E35827E1AA9ADC3500FD9BA18FC6B03465903858C61C1259CF485338CB700EB731F31643B469BB259210CEC78C158E3290573C5228518E4697F19171D8F1A3A633448FE9C83BD28097BB29A168DB5AF1D1B354B6881A2CE509B172CF4F8DACE8A96B8F70DA966080A5E3F132873CA7544343377A99B65E8147FBDC370460375A778D1A31D01C42B66367ED8D9E8F84551002F552F0E52102B5D\nct = 2E1DD8799B0911BAD860CF08F4A53162A559277EF400A1120A024C0B0BA064D1746AB3926225882CBDAF2B01013FCFF1AF978C02CF3650866AF47564DDDDAB692292F6A1233B0BC4C296DD98FC24FF962E8F3A8336729268EC7FC97D30EFCFC45C2D77AC5FFAA428E1D3BA6087F0CED8406F9C86F1A2119B0539CE5B3251C9A0C0836EF690DFADF37F16040DA580814B865777882332591977D4181320BE97A091E8281ED130A15FC6AD629EC1103CFA0AF8FE257F3C3DBF737231C023C1314484A582F2599BC1249BDB7C5C9088B60E760F57621F4D04D9F32C8B5B354F8943D8917C68030CB263B78C4DA1BAD57C67B07DED2BAF8B52D3F864380DBBB0DFF30152C11F86A0529B29C78E97F91E3DD901676F97E6E1EB3756B213BC19D90DEBDD774F805B30E00AAD86956014C64C09B816B149EA939232B4CBB96F0DA9A9FB422F1154314171BFD2DE10F69767834B90AB15099D30415D66F8442589B8855ED001CCC2DBD6A633AE846D25BCC754838F8316DABD1A58A61C6E7EB763611BDC4CAEA5FAB7A19EC95BD168A4742308A07E8A0E0214C1173FC7D2386E33D187F2D2E5ECCEC18A3180025129065644A8E917554DE34A1CCEE3E9509F9DE89FD35345A9465D02D25704318D5E6EDA8CA7F6A6FBAEEE2D519929DF566062F672825F8BFD3370FCCC384571A1C82575BD9F6B3B4173E255446A5A3F2E2143565C11F12D8FF48FB8105E2E19518CCB1B60F04E7988C58DFC76AD3D1E3FA107A7193AF691D80D3DB1F940CC2E5F50F02D5BBAE18E1F598DF690E82E7BAE5334936B8D1C194663391D3F819CD2FAC47D185192EB9596DDA35B0A8DB158C025961CE2F570F7097D076384F9A548A1B774624C5ED3BF042A06E50FA6E24D7796F813F5C63DDDC70A1BBC85E730ADA2A2FADEBBA236CD0A9BE983FA40166823E52218F729ABFACE09D7AA6F6CFBF6BA25DE959A779CDF2E385A83B2666B5E0CD8A049428B18786D93A125832AF72A6C3202DB30D83E34DB9C2E127B1D7E027A0D8F30AE69C90A5CFD4D3BD610F77751940536174247CDB7A9DD7DF9A010E28E8BF22E346A3AED521FC8B7E3891847F27B7EA06157FF21F14CA7F474D7DF1CCDB371DD9155F8A8958D391A934072EFA43625244B1A79FF2C29753053C42378F338D11D722C283D1436D87FBD38AED972EB4BCCBDD3DFFB9F6F7B2CC2B1EC58F199E0E09ADA57200031E3B26F0556AF815A04112A784E5762AD828737F7F26B55969FF023BF853E4FFCCCFA3A6E3E5D7363B039C2AFEF6A5114E7D2D28405091E258CFE54C3B991A5AED242DBC60430A95EA07776314140BE80C633DD3E2171B2E9121F16FF37548E52650F6241960E6A6C23EB18EC2C6FAEA35B8E3AEE9CC2F7CB0E3DBA2FAD334255CE1E92F684A2E1F8281CEB9EC7A497C41ED0362F9D25281064AE282E8947ECA454E3ECEE228B0F219C243BCEFE589ECA239EA619B152606EED03F788E9824226E2FB390207DFBE953AC99FFB9BEDF0C0F602F0968490BFDDF86E7D0F0E\nss = 0936224EF45E29DFE9263C6237A22798E94E81A932796174271CECCB78188554\n\ncount = 48\nseed = 5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17\ngenerateEntropy = bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246\nencapEntropyPreHash = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c\npk = 58718343322DB0162D26965D5E946B700AB88D702FD5A1376920B5BE702297AACDE28588DA91C719D40C1FAB0AF109742AC26C456961338C44C93C83AB58581635499545CCA66160E15A35BA4931E2B91FEE68A8734ACBF72755E8D452D17215457161284435EB6A7A2933C8D146A12679143B80740F68AE052087EEB988771A8FB43B34D6EC79868A0670551BDD19CB5313892BCAC9E4FB500D3375AE471A3ED551B2D9C76142B22607615454A910F8578E44B448AA9200D805CF4C15EB635013BB80A65593FF578C794066F05ABDDB850FF976C74ED6ACB4C41064FB5EEAB479A13BA57DCACF7F02421603194A3CB549F08C0D700790809EE0E585DCE4088F96A740320C57D5A632C8BF5DC173F0F841173AA47CA42004B808EBC2A6A1770AD9DC06027557F80420DB47B0158A1D1FF32007FC058875C4F5D21FABB67BFE8909E10B51BB35C76D0605D0E6A97E56CB93DCC58F722D95F33008B0A237B711420A20269A7097396A4A98BE20B8226E103CB1136EA3FA39D438B305B63FA049C420CC378392B9F911BD7800BBAAF2BDD7586780C7078DEA622DF51C7190841585BB16BAB9A0D83625D55826E3949AE018E7C4703CA082466B9A078393C30A4F6B7B1FC775C9DFF7CFB5909CAFBC66EA946E6F098F881B3039C251FD3AC142029E8728082F838A202CC3586672CB6285B021C41E3C16F5787CE6E319D849483FE40D989C246F7C36C11A991234AE7FEA68770C79D8290AAE3BB72BA014AA1279FD13977A49B0CDD494CA00C610CC2306059B695686399C1590F274F735142639425DD88026F8BE0F260CD66672A12B5C7B5C7323408A2711677F062625EB8F3541098D079C13208415DCCF3FF72D1999721DB3C271F7521DFB0F129B3CB6885310A0689166A3B97B09610347CEEA5579650720DB621DB20EEEC24EEC2144FB523ED2D30F64B9C6655928B3D06E1FD9B088AC8B7C964213E5674757C7BD48A3D066355F0249A50548F430C55A6CA0471953EB7C67E140AAF6322B7741225931622DB114ED46B9EA997974C9AE2F54B87125CE79E8621D712688B50C7A49877D52091643A4A43148550135F27BB30EA131521583F5B79255309465F4B9F2233027855CC0E7C93BB33705136C88392CCA717254640C540573D3A20032C9B297EB5B02C954C744C4C6143A56EB48F1D15439F885803BA5ACB524F3D54BED37145CD9173ED92A00F724273787CF1B89C788184DE0905BEA74FB331DDBA00CDA70C1547C634C706A8447145489752B0633628BA4F5286851E1B5FFB8A7FA2BBAD3F92C542ACE74E67AA07B467E70B6A7D3056592B36A7A37C6C7114C610721E9C6EA933742E43609C41F6F3803E99A8D5A27B069BB73C892BF07524A8B2989633C96CCF33791BA29F3D575F249C640093046D1684FBC701AC633381BB349BB7D351230A8BB1A22223DE3850258AC7043B887770A307C3746002CADA2826E47F7694EF51F94FB9E3645AECE6273298592BF00C0FDF14C07D8C9FCA401FF351D2E35491AEB55AED9B1B0EBC2424CC729AC7EB07630B8B11D0E47C323D6B3C0BA12DC235D5C310CE2C7BC1F0A8467D627568A185855750E12717760355A0B8A756468E95406D375F6A1289B8CDBFED9F6518D7031C57FD3455D4544735CF52680424C90F14F\nsk = 5E43BFE8EA443466AB6B087DEADC672E7AADC85521D549B978B054A9B8949E519E3FC3A653607D794491341039713037D31C9824EACE39E7127A974403441E25B714FAFBA4B98041E85B2FD8D8ACC2A69AEA9C80930306B46BAF5245A505D48E293A77AA4174D1C095B0B4A45754A4A94BCB01D4543BF7C7DEF2AE2009408725C58BC76BDE03ABEF3C4EE0831D3C6B2632609707B3B861F093E857902D52A2A48619B1EC20DDE7A923412F79C22389601473076965959B2AA3C79DD31B98CA9847731C89B0929EF5174CC6B92972CE2C07C8139A62C901216245CFC92B2DA158079E1C93C8E08FF438A02DDCA4CA948F47A106D40AB6A5B0AFAF52052F237E44F0765B3436271421308611845785E257CAE691C39FB8C80BBC1C5FD687A547B7E8E3AA1D7C15A918984B6B359CD24711CBBBB95716EA54A8D3511C5DC983FA1B019E0B0D7DE90C3C0A9E7652C18E72CAD6F9C510E64F0CDA8CBD86502A5880EE1536EDD16AB36BCFD859CE879B3F5D6A0D90630668B7385C8599ECB1849A4942D87A91497129E196309156C9AB245F4C637080C963F9648FB2BA6F32D2566F88BCE680203DFB827438295F8670C9BCC34A98497851BDB0E631EA06ACCC26373809986DA62FA714012D2579D5D61443330E3B882C800B6C9D02C98E9859A4022DB4A09510FC91A3B95BCBF73B3A09311CD13E52B61733E02DBB400E8A54A30668311AC02FAE2B55FE05C95AC43875D92F3C2ACB3D4A6B53D363D5D75A697061055A3A788BCDFA051EDF97C3515CA920EBAC9E7A998BB598B8436BDB63550E416D2AEA5057562A901B609B129D92B27536E02C26EC6A3B2C5F6B733D0529330E9A89600B089DD30A0BB52530A3062BE741B09818A78B4FB9F274B7262CA23B3F2A40542CAA64FE38A6ED06BEB5498733A38A7FD0B5AEC2673ACA2B07E00909E68D40AA207FB179CF7A60A9E13719635A15CB221D1CC88B921E950C94CEE17D60F80CA5B4A656F501D7136D1245207479A1DA42C26C48664297562A0BAE0E7906E9D853FC7C490E4078B5B3B226B37101A31B5D05A26F1CA1F231A853F23F59D86A3FD269A0256EEBD02CC0C6B77F1B1C613114E1084D8D1CBABD0C7702F43D2EE01DB985382C562F1B7885A7015EDF59BD8988B5BCEA1CB04639BBF5B119E6293F908245455070DA3013D2B6E2116776694B44E3A7E433407099A51940870B336F547677665C7066E181CE266FF0E508268731BD13AFA2ECB4546276A5DC50772A6FA38541AF968AE5C59E2D04C3B6002C7120A6A970ADA2671590411552E48E7119C7B7F7AC97429E9B7CC0B5242DF277CC10E7C48976266643A9B2308CF1799324780743F95E65851C03599FEA7129D5552B86AC35AED10B5F00058A8742C02A3E4F6CBF5DF61C66143EBE933060C98A4BB55318566184601BB395625FC86E4BD47377B54459B45E50C145596B9178D57D01BBBAA9A63BF444889FC810F1E40E07D289E0B04A58F84348463B9FCA3176AAAE6C1C119CF679BACC6EB685B9F443C2A9E304BBA0ADF3888B42698AC1F68F1626439E796E1967C7BEF581DBABB6C22C9C16029E18D8493A524FC2A41738A25E735C665E79AC423ACA37B5222D970358718343322DB0162D26965D5E946B700AB88D702FD5A1376920B5BE702297AACDE28588DA91C719D40C1FAB0AF109742AC26C456961338C44C93C83AB58581635499545CCA66160E15A35BA4931E2B91FEE68A8734ACBF72755E8D452D17215457161284435EB6A7A2933C8D146A12679143B80740F68AE052087EEB988771A8FB43B34D6EC79868A0670551BDD19CB5313892BCAC9E4FB500D3375AE471A3ED551B2D9C76142B22607615454A910F8578E44B448AA9200D805CF4C15", + "EB635013BB80A65593FF578C794066F05ABDDB850FF976C74ED6ACB4C41064FB5EEAB479A13BA57DCACF7F02421603194A3CB549F08C0D700790809EE0E585DCE4088F96A740320C57D5A632C8BF5DC173F0F841173AA47CA42004B808EBC2A6A1770AD9DC06027557F80420DB47B0158A1D1FF32007FC058875C4F5D21FABB67BFE8909E10B51BB35C76D0605D0E6A97E56CB93DCC58F722D95F33008B0A237B711420A20269A7097396A4A98BE20B8226E103CB1136EA3FA39D438B305B63FA049C420CC378392B9F911BD7800BBAAF2BDD7586780C7078DEA622DF51C7190841585BB16BAB9A0D83625D55826E3949AE018E7C4703CA082466B9A078393C30A4F6B7B1FC775C9DFF7CFB5909CAFBC66EA946E6F098F881B3039C251FD3AC142029E8728082F838A202CC3586672CB6285B021C41E3C16F5787CE6E319D849483FE40D989C246F7C36C11A991234AE7FEA68770C79D8290AAE3BB72BA014AA1279FD13977A49B0CDD494CA00C610CC2306059B695686399C1590F274F735142639425DD88026F8BE0F260CD66672A12B5C7B5C7323408A2711677F062625EB8F3541098D079C13208415DCCF3FF72D1999721DB3C271F7521DFB0F129B3CB6885310A0689166A3B97B09610347CEEA5579650720DB621DB20EEEC24EEC2144FB523ED2D30F64B9C6655928B3D06E1FD9B088AC8B7C964213E5674757C7BD48A3D066355F0249A50548F430C55A6CA0471953EB7C67E140AAF6322B7741225931622DB114ED46B9EA997974C9AE2F54B87125CE79E8621D712688B50C7A49877D52091643A4A43148550135F27BB30EA131521583F5B79255309465F4B9F2233027855CC0E7C93BB33705136C88392CCA717254640C540573D3A20032C9B297EB5B02C954C744C4C6143A56EB48F1D15439F885803BA5ACB524F3D54BED37145CD9173ED92A00F724273787CF1B89C788184DE0905BEA74FB331DDBA00CDA70C1547C634C706A8447145489752B0633628BA4F5286851E1B5FFB8A7FA2BBAD3F92C542ACE74E67AA07B467E70B6A7D3056592B36A7A37C6C7114C610721E9C6EA933742E43609C41F6F3803E99A8D5A27B069BB73C892BF07524A8B2989633C96CCF33791BA29F3D575F249C640093046D1684FBC701AC633381BB349BB7D351230A8BB1A22223DE3850258AC7043B887770A307C3746002CADA2826E47F7694EF51F94FB9E3645AECE6273298592BF00C0FDF14C07D8C9FCA401FF351D2E35491AEB55AED9B1B0EBC2424CC729AC7EB07630B8B11D0E47C323D6B3C0BA12DC235D5C310CE2C7BC1F0A8467D627568A185855750E12717760355A0B8A756468E95406D375F6A1289B8CDBFED9F6518D7031C57FD3455D4544735CF52680424C90F14F268B6356F92C57DA6DD34494B927E8764ADF0AD519612EF0D1B8951E50966C2FFD5A08F656A6EB8CD20679930A31CAA6A6331C4B133A6838C223EF9F769F6246\nct = 19444F1E4399BA6307612AC8FF6794B0708DDCC06538D89BB5F49FC3B8AF7C2F31C965417CC17555AA48A9C17445580F27AD4C825937FD7068EFBCBCF3B5AB055DD0D772E5A801935F475D45A63541A9CC892C87AB0CA912731819E4F270564F50BE11E0EEFEB954EB6F4042C4ABA4595AC8EEC5896AEBD7D66C0D1B8E34ADA6F6C4903986D9E0C17E8ADB7A4AB87917B9584C6D43FFD09318D867710CB41112FFBB8D888A536E3A4AFF8CC1896C7AEA3700B501FC468126D0EB82519A336EFC13BBBACAF4C1F48D187CE71BCB2B8F95CA66468485C445629EE33A3EC1C4EC34A193F68C752DB1701D07A9CF6D815CA93C93C6E4FCF4B21F8B0523DB993D25F581C91C5DD94B594EDCA516D6046354B4309CD9EC53BE0F9FF210213DEE06C0066665D325A10C5D2491DA37498644907FDF719515EC507217DCECF16D4B3CD45EAB811684198C48567BFBD65D831ADF41FF4612E9FFFA0587B7B3FC9F2B726DB5D4FD1DCD3D4BD06E309EFB1007C39401FD0A98B2BD6E3D354FFB8FB556F289E858A1244A602CC1D0A41055087A714EABCB42AA85F484F2F27548831B2F32D883A488B74D1C7BB28A8F735F161F2086B346CF0C45153354C690C92D68FE943D723F7E243D0AAC615AD54C3FA336B7E43262E14C850E9EB89978AA10EA10507230209E255192A3695D6FA3CB55EFD7BC69174A44EA0A2C15FD17A22856E571C39A519E94A5A022B04DF98E6C84FCC6D5A5AE3980E651731753517FB87333C02044C12531730F3445AFC02CD54A0A8460F7146F98187CDA6555A8EDF2CBDF6CE301950EA5204DFEADAF64952BC871F7F01517ADADB0A1AC33C34EEF75B7DCC1F64AE20A9101AE95AE24020D8AF3242AE911B3604284D93DF937E74DF3F74F26275D7413CB6D07ED995AB853E180A50F8D0EA305528DDE43F5413F927289CBCFA6B426B615320D635B85B63FFC640E7EC4B121AC71E85811815EC5DF1B9A5A2DC7F79C8A7E6380CA7D49CB3D7901BC28D1E249BCC86EC54EBC31D92D5324A0663222FBE93EA2CB0BD9BFC5AB43D63C8DA12051A4157C210DC10E737B37962C1DE186E286944E1C588B570766F81E944850FB4269491E0FC23F86602CAA9968CDA290D83E7B2EE9917693E47951EFB86F6CFF49CDB80CB04774E51DED7A184BA8E2656861ECC8A90795DE698D70AA85216FD715A11AD8E1D5D07C16A1F10C22DAC064F011D1829826D34C242F8D0DC853DF36D4DA431489785373C8E050EB8A34CE55C6F2FC1745DE58BE0B903C9CC25392A9378A379F6353F04C52DC5AEB80048BB0F13DC7DC9548266729B410C7B809C10116F30A6204AE7F46F7CC68F5ED8202832FF90E1C482B3AF44E85AE6E44A131BF9789147C21B1D5658493CE4CE3BADF7458C26870392494A65AE4F53CFCDD337D07C801A6AC90443A8F78DAD7A7E3ECD7DE8448809FD38B533A3F41512FE7011425E6FD360395F62687EA7E66977B0C3AC4FEDCD1C91F1026E216FA754A4D64F0265B0AAC854C8AEC1F25EC93F70A10E3\nss = 2073CEA69B598292F44EBF4AF3F7035E1738AFB7203AD67531A7140150176E5E\n\ncount = 49\nseed = 1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB\ngenerateEntropy = 447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01\nencapEntropyPreHash = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea\npk = D8279F9A0681CB98BC38CB551320031F46262799C182B0355EEC82CDB58D750596A4E6BF1213490810415A4B347E13C9E8514890A0995843936BE342E81C7F4971BF9B75925D61AC8C961492A85D83FA8E33C12FA37BA08D7C681C521ED4060481F58BE673007A081321E01E21419E232283A01CB1A4481550DBADE263382EB93B7E42470B265027A933C480CDA340A9A4065B4BC47990833786456AAAB5A81C0A46E0076B91BA5BB4D4ABE21C6AB193B3A3671C18479DB082A706768A63109D2C4224D71C7C95755CA24B056C355E9C22CF5006662B3218EDD4B317B19962CB514AF123245B152EAC41391CB432C6CAF9295C66DA4E5737AE3D60023F46AA7A604C64A6C403306CA4B96FC2929AED5B4CE7E6C631B473D7D61CBCD19826AB82C0C58880D77CE8F9BCDBF59D645424BAACCCE334809B43ACB99248BBD966C88793A273AE857946902649F97B5516FA2EA2A84FCFBC054653852D8421B6B78C289B49080C8EFAF85DF195AB5562A03E7099C43C439A25AB41390B86DB4F57188F002129F3EA1FFDBB9E9C688EBBB26E0D7AC6EEA395B698A134F70F98480E87313B79444963557CEE82534E9C1CF10B74718CAEDE3BCBD98A68D9956FACD8A45E2184C16B14048B9D28E8BFBF5AB43D1B650EE8CF13148CAF451CFB144656052CBAF82E2F765C8C9C66C23B0CBAE0257D6000F247200AB87F93B5167478A27B42AD7681B6919529BB1430DFCC809E171A334B33A0527A1D9519C18130971C55F6EC172B86248059830FC57C7356C9BD8263F7D571D0F7BD87D2A1686A7C41DB9306558CBDF39F0176959A188B4D457B40C152B7EA09F6860D4D945E78C45EB68B579D48774EB26AD43BC1BE3C0AC327C80B4C1115C2CB58BBC24A18146470ABC223AD51FA10EEFC311F1AC02AF4C7432210233A4ABC408B1DB484E7885D239C0C2B9C4952E577A8EBC3D6A7684E711E12DB96E1F988DF423A395301D2C15FE2F1ABF708BC64147A30E2717F7868FF602D50FA9A3D0B3A0097259AC52057DCC14319C438E113DA967F6DFBA4279245B72CC86CF724C81769DAE271E18C0B6CFA84B916AC89B12A1F8B05D88527AD40346775CC832713146806A2B2884E35628169BC12F67811B507BEE3BBEBCA81AB93B5D700AA92898B3F5CB6E9D345483CA3743457FAD8CC5BEC2A8E7A22A41BA8B67641AB181D42ABAF94D0055206B648C81361F8486408B610BB3552299316B5C0B7D301D9F1C3D55621859AB2EE922C59B11EA9F2A1EFE277C534128F2CAE6B598C0FA059EFC2C24E8A0C2337BC2C57A0BC64A7FCE190C656B529D21244EB66A900288B5C484BB033020B9B9BA3019B72387F2746B3B893A1427882BC3135F0A17F8271F9C8480EB60732672D44336B32F851A283224144C480AA302C05836EDC1AC4569A6020130B341466322D17811229441C4513A2E8041C85E035113992F16799DFE8C1EEF3AFF8CA2F341628808A81E8B66EE5BA47AD0863C735A904565F036A85FB1203058137AAD2206C303F22D3027E732542A342CAF3376D6B065A745E31E865FC2243DA31CE08EABBF8183B4294700BF8928DA8CA78BC08490810C39747FD3851211B22F26451F6772E0C75659133E8D8C063CD3044DA1719855FBBD9796314B11DF8459EBD2D92B7FDC94C4C\nsk = 469963001D4D93DA7CBAAC0ACDFC833C47601AE334DCC0022A9220138C16B9ECA73AD1863431A34F593ADDCA4F0EA393FC4595D22A7CADD0A8D89827086A955400ABAD84226541114CFCB3E3A240FB600DD6C0960A7976175C56B0B48C66721E13882E3AA5784E12869F0C8518037955F876997975D27A7C92D4CF005AB859590504C768B02576A94263C87C4BBFE1AFB09B8C0A5C067776A0D96A5D12925B44AB3D3E57C6971B0A86617F65A16C7E9B42C283577219409E1CA4DE08A92DC5B4E8E87051680C1B24068DDA801FE871E0B28AB0611BBB97CD49BCBF159B7785830BC9D302C0A61AD138277AFC2374AA64E983506BD11288F4A20376B50AE1C1233A1ACF30AF1DA67301A5A420AA826DB58322DC1C7AD8BFD25C3B21025B565C357B4A0802E615A35A384F1794A0612E030228A865A0390197E7C27F45A4258FE26082C850170CAE86721BB5C68CB32153B9934DE4CB11528C570AF363925AB0FEDAC79748B3489B7180E81FF6DB702D5A100336955EC02FD2B9C86C2CC001833B0BA1B7DBC9699C6556B448324D29B0F6A4028BF48A49B1CF60B4A9F91321AA64CA849848CEE2BE0A29219F783008417DA307710F87CAFA2603FD206E5698177E81470AF4C608A6128908541183A5B4769E74166349E55B4D2A2A84600EF712C2D1F13F4FB3C91BCA8CAD209CB5BA0FF578BD6E29A0CF07A972D262A2EA3C4DD44A5D55446C174B345B96871076FCF785CCA68545EB6BE64BC9BE17A7D5914D8A50B2", + "86D3A2A8E1A53FAA53815ACF0237B8BF204C34766E97883071E56539361BBDF29187C180414C83D9C09E30983995AA4850A6B2358AA6240642CB9B0FDB739FA5A93EC60C11061AA8B5E71316A517BE2BAEA2F74BAEE32EEAA0A75D2030F5E8BBE1B517F56511FD8AA499621A9EF6C88B96A9F33B2B3CF04381B5C97B743063A6286751AD9EE14903C4674B308DD5E28BC700134C43C788B04460DB78A0E795E24698553722B4C3A095784828960672CBCAFC11AF32C918ACE0580D5BCEAA574409854051A2419F148809147133866F9B651A38622F21E0614F10139BA53724831FF312157146169EA29293D2A3F1250AB9CC877D448ECB53139E6C5487DC2931D45B4A74C34BBA11CBB965E1E664ECFCA54DB7BFE7E61DB2382E50076A70A9AA028670A354013C894B729945830B1125AA53F4D352BFF33FDBE7C64BF70A4C3ACFF3680976FB26368693D928122ED5707B453A1DD714FA9C5A8E6534D45B53A2BA464E217DC0461BE31C5763715BB66B6F3A4C0E7A3A4CC107602CC3B67487A7D162422468B5CF33C8E5A63F801C2016B15C40398F914CBCDAC9664B7601680346FDD3A499D89B5CDB7E77CC8A1215661AA34737149BD0734F7BE6A0C20BB94E6A89DFB9B0A9D6C4BFB86408922FDC9650DF7577E5A89215C8636D5C376F4596C329158964084200C91AF4A7699018C6D139F521204BC521110AA222203774DB88AC0AC94CB97720A71411EABEE0B2863C35607A617E761298825ACD91C73685198BE96B84A98AC7295142F6C19BAB0082C53A8A50A3A39EEC2A34E859CFA2C88C9CBC77B1BDB5377981F61C1FC394D70820336BAF21820D44C0956E09A5D8279F9A0681CB98BC38CB551320031F46262799C182B0355EEC82CDB58D750596A4E6BF1213490810415A4B347E13C9E8514890A0995843936BE342E81C7F4971BF9B75925D61AC8C961492A85D83FA8E33C12FA37BA08D7C681C521ED4060481F58BE673007A081321E01E21419E232283A01CB1A4481550DBADE263382EB93B7E42470B265027A933C480CDA340A9A4065B4BC47990833786456AAAB5A81C0A46E0076B91BA5BB4D4ABE21C6AB193B3A3671C18479DB082A706768A63109D2C4224D71C7C95755CA24B056C355E9C22CF5006662B3218EDD4B317B19962CB514AF123245B152EAC41391CB432C6CAF9295C66DA4E5737AE3D60023F46AA7A604C64A6C403306CA4B96FC2929AED5B4CE7E6C631B473D7D61CBCD19826AB82C0C58880D77CE8F9BCDBF59D645424BAACCCE334809B43ACB99248BBD966C88793A273AE857946902649F97B5516FA2EA2A84FCFBC054653852D8421B6B78C289B49080C8EFAF85DF195AB5562A03E7099C43C439A25AB41390B86DB4F57188F002129F3EA1FFDBB9E9C688EBBB26E0D7AC6EEA395B698A134F70F98480E87313B79444963557CEE82534E9C1CF10B74718CAEDE3BCBD98A68D9956FACD8A45E2184C16B14048B9D28E8BFBF5AB43D1B650EE8CF13148CAF451CFB144656052CBAF82E2F765C8C9C66C23B0CBAE0257D6000F247200AB87F93B5167478A27B42AD7681B6919529BB1430DFCC809E171A334B33A0527A1D9519C18130971C55F6EC172B86248059830FC57C7356C9BD8263F7D571D0F7BD87D2A1686A7C41DB9306558CBDF39F0176959A188B4D457B40C152B7EA09F6860D4D945E78C45EB68B579D48774EB26AD43BC1BE3C0AC327C80B4C1115C2CB58BBC24A18146470ABC223AD51FA10EEFC311F1AC02AF4C7432210233A4ABC408B1DB484E7885D239C0C2B9C4952E577A8EBC3D6A7684E711E12DB96E1F988DF423A395301D2C15FE2F1ABF708BC64147A30E2717F7868FF602D50FA9A3D0B3A0097259AC52057DCC14319C438E113DA967F6DFBA4279245B72CC86CF724C81769DAE271E18C0B6CFA84B916AC89B12A1F8B05D88527AD40346775CC832713146806A2B2884E35628169BC12F67811B507BEE3BBEBCA81AB93B5D700AA92898B3F5CB6E9D345483CA3743457FAD8CC5BEC2A8E7A22A41BA8B67641AB181D42ABAF94D0055206B648C81361F8486408B610BB3552299316B5C0B7D301D9F1C3D55621859AB2EE922C59B11EA9F2A1EFE277C534128F2CAE6B598C0FA059EFC2C24E8A0C2337BC2C57A0BC64A7FCE190C656B529D21244EB66A900288B5C484BB033020B9B9BA3019B72387F2746B3B893A1427882BC3135F0A17F8271F9C8480EB60732672D44336B32F851A283224144C480AA302C05836EDC1AC4569A6020130B341466322D17811229441C4513A2E8041C85E035113992F16799DFE8C1EEF3AFF8CA2F341628808A81E8B66EE5BA47AD0863C735A904565F036A85FB1203058137AAD2206C303F22D3027E732542A342CAF3376D6B065A745E31E865FC2243DA31CE08EABBF8183B4294700BF8928DA8CA78BC08490810C39747FD3851211B22F26451F6772E0C75659133E8D8C063CD3044DA1719855FBBD9796314B11DF8459EBD2D92B7FDC94C4C4C6D304E0494D88D83B5E3AA5761DF3B299551A24F28994D2747B2B08945BEAD20A7237801F470FCC2BD9FD7BEA8322859B850F7882D362947432913DD068C01\nct = A95AC6C09FB64C6D773EEF1690F3B87550BC37513FD8AFD9B1BD88B7B51BDAF9EC20EF1E5B2F7856C02211A7936FECD414F991C098A77F7C2652B0BF095D368F02A2A293F6300932BAA5AF1311D05EE3C4EF967003DDBE06DAF30277636292E5F435DF449904A9C47597DEEE95152D0296F0DB4013609A986A27FB8C50C453A76906D8494416434B048A2B411D25AAE800469B2ECB73592A2BBAAD4E392F3C5367B7FFF2C9A4DBF65C296873230782E4CBBB2C613FBE8E5892ED04524F353F97B6A83CBAA6ECA393BE675AA3FADC2615FB5A2DDF89745F36C83C1FC204580B7E4CE24029E0273DB147666A6550DE9364BED46F3C20E80F42CC013196FFE4E06CA8FB9FC421C798B6A287189861CAA148EE2B6B4326D73F51B9FFC2B97132EC6F4C0D52DDECAB76ADE333C6A53E090759AC5D8B43779911FD98C080463938E0FB7DC6F69FB35F71919179D82DEF20AB425CB56554893541CDCE3652BE623D49052EE9DEAFB39549B85DB84CDDF45F3D113E815CC0D32B3F180E59FF69415DD50B756624C84579071DE883E2187FEF0A63189EE9D342679FF0DCB98A2E963B490BCA4D60A309D08FB6C31A1CACBDA0D004B6D666676725EAEEA9D31F7205D3C02D12939C3926EF259429642A9D9C375D77F51B8356CFC1F504858BD56E445F05CCFF5109F73B89560788EC833AB196A51E877C751B70A67357C70CEE24DAA81BE2C666BA20D1B7DF9818CF9900D2CBD83FF74E47F999689D2F5BB178E9A6D4B4D49538706136F4096A919469B4006766D5279453735B84D2066389FDE6F600B49D4DE09BE55E09E7C462F314C921F225E0168342DC4D306DDE23B39139627E6AEF656E1F803EC3DB9697A8FA5772994C7F5A0E6E23F71B025D007FB106E81E76C3D9C718930A1A33767DD2B24B3DCBB2728E9746429625330006CC71604950F1A5124C3A820AD98ACC2DCADB4A1FE4EE3B04FFA3FE7305700AD11C06183AA4864FC8A254D9B6319D3C8C42BE03DB71EB74E585EF4A8D8066FC9D6C5D4FBAB3345D8241A9E6F960E238007F8897A50C6FD1EE62EB24AA67EDD962A2F2A9286A365282333932BE877227D0F5E77767CD69FBC6001CE647F29D89E145A91A16D477DF0424F73C6D310C68897E50F3DF553008DE313D9F9ED621E3C43617FFEB5E969C015DFC361A06E9E649195ADF7C4E9BB6AAB204256F1D7F6D0B080E2981932281937175940EA11583F862D7A001BC33A0E142AFD918CFF3764E99E52D3E920591A0030B3AA55C88589C0AAF243EAEBC6F08E2E3B3083E6A41E500150B90C0172F534B597C958B0430AF44204165344E218FD84BFABF8F580489F89748103B451FD9F5462288A03FA317FC72BF986EE03CD87709B646C4C611143536FFE596DA2BF049EDF32F8E40B0C465B24EB81FA09D775C7C5A99F5ACF2C6F24BD13616E6D7E27CF2DC938CF5BC17D8F4EA78549377747A23E341F19455B7C95764A8476AA41F1D33B2344938BC3FDA480F646DC973321108BFB7638767660FDE1FADC387EF\nss = 633D9672D83A112A260B9D4C17812359B5591900A3B80424B3590B403A5DFBA9\n\ncount = 50\nseed = 027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09\ngenerateEntropy = 2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9\nencapEntropyPreHash = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24\npk = 41AA7B69158362A41767486EC3DA09AB4335FE2A25DD6C07366478CDA91C691C5ED9264F771124C1F3693050802F480F5DF89D5BE189DA765337A69C5C838488A0A4BA7880E91871FE346CF3ABB0AAEBADB211B5ACD3B773C9146CF97920E509DC202F79B14734C9777A567CD44A43500B5EB8005BF4C5A387701286639E6D9AC2574B33F2432B3A787039E34B2AE511A27825CBA7A8E09B401CFC6123D3B4C42318E7B032331230DA960A09F61A6A196DC185BB8BF1C1A6B691A06CB57F12BE1E45269C56490E256A83C13352A878C724242FF0681881160ED03166612D69894951D65B95E690DB46129D149AFBA2C835D3B138036931423D2F84CA51179466A1028D1601D5C397CC81B1B5E468869185B25095A0E5B5DD6A421B5C7ECEB58C4CF97B7FEB114FBC435C78857C65098D3017FF8A58F5927E5EE7712FA0C2962939B9D8C84BB6428B3902881188DF17479EC01E4709B7840235CCD77ACB0BB3A05995693781FB711D61F2883827A96DDACE29A9CD43EC6ABD4691BE1A758B72A629F6AAE1C795981C0D8BF8160BFB3B8F5047E1A410CDD49C6A42ADF0BCAFED1B21EEB95D504B1A48B1ACE228BB5E1508BF05128F0CB63F5597851B9DF4CAA5B6AC10F7F6188DC41B02761F840CAA42871C55205CD09771AC9125D6265DDC56A466249FBD774EE53756035349CA12A48237221BD53D7FF1AC18242442935BA818A3B50007A3FC14A2FA3ABE437FF14705DF0CB5AF97561A608A3FEA42A809A7A7D5491453C849DAB7ACD99636931C007A70D01655C7302F9A26012C494DE47839C1EA2951A87FF73968DAE83A86F392F021873BE4C75D2B0700A3B540F50CF6FB664A4627DDA9C75394032F434655755D12D4C781E2324AE00DD61744CEF6C5EC9680F379A26284BF9590A33350905E080E9B70547AC1CF3AD888F30232FDEA7BD2C184F9E1A9B6835401E737204C5EBF2B28F2B58EDD399F873C7849CBA8064B8A20C9C391841875B4963BBA2097B958D752739383BF26787E64EC215974B45848185F44B8780C0714B9651A7685E673CD1B6230C5D6639EA5629C20659802BC6F2B95DF274836241165A524EA99A941312FEFC7CDD2FA8016D69B652C3E94E73C70C97F65B3ADF14BBA2D31916522701D80252E9C7FBD7A17D306A4E1E02CDA405F3F07B38EB65824D5C9D8B91F7013784FBA0DF0348F21B00EF5A325C745A829714A5B9ABA16ACBDF029771D5415E867590CC5A57360A8969407F0749AB8A08A65E37E70146FC1B7BC40D789EAE83761E77749A07859BBC046B5A87E3A92A5368251127F12D2778931", + "8F8B9C3C1F79211922C852A0B0E10BBB631599190B49A66937920B3F113185D89C6E37DA5F7CE9C12D37C12CC24741CB9A79446606EABE8C9AB06D8963C959955F198E03A0BD127242DBF2A2180281A7B65F54C28EC9C6CAFE64881D6456C07607CDFB89E2CA2FB3BA8F8357720051C30952734932B08B508402A6A2F4F9C76B053C12A267618928032B5D9E41990A18C2C04BA7C2868AD9F4538FF1B494707EB9DA6B81374D7F9731F9A26089D7033A8C24600944D65871D313387B4101C0AAA27AE19D978653638577BCF4CAF48083EEEB57F401544D4DA3B73DC1C5C4A047B0A5EA85EDAC7BEC66F4D87FD2FE422E7DBCD02D1455\nsk = 3C14BDD913CDA0F267ABAA8B0A30A5EAA527638C01926623B0BC2BA55B0B596A92BAD72E92845828E8050F4C2F40873918E4524CEA8505208D345783F71202496721E361A582C5445FA31FB662A64941ABF9FC203AB4A741C9214C1B80B4CA617C4976C819794F53CACDB3509978A6DF5900016278388234CC1A09B804679F36718255B2DB60A7EEE5BC3BC78BCEEA8060354B54031C4C76B30A1A8B1EBB697FF8606CE408FBA72DBF0856E5B53B1E4A4ECC746CDFC77545B46060974C8A788A1D59529A9AAA571B895BE01ED5C23A0D22707D89467A5B9C662767A0D77D5C49ADCA983CE7401F34526DAB1CB9FE744BDE8C54C230705548B9ED00B9F4EA055466CDE77019324C0A7C9BA404B641A6530AE64A964EA47E6E80AAA4652C9A8B66061103F385479E50A780249A909C92B7913329A478880162D8857D58FA39D3283F5A2A7F8FF6ABFFE2463DB40728D06166627E9C92283FA57A2E46190AB869B6C21FBEAC86911284153B259BD2A442070D1CC581FDD333E5990F84AC67F47491DF01128F0959ADA0891C236E0ACA87755289C0E6C8FB136974C97DBB1B8871A4C70AA001FC950F0CBB3ACE4AC44F800252F5BD76FC1DC09A3D2F8860385A4BF8D765B49C5379140E0A2801DAC947C23803AB6B467F2BB1B019B9D53771418312F51B28DB18BE216794A0467D79AC8ABAF2C90F4B1B3474C168BCBCC1E6AE59C5781296467F2B8D63D5842D67935DD429BF8319BC0B8199CCA9D3F78C483B8E0771622EA764FA610EE13C1A188C56D0B5C17094C1B7A45321BB69D99A666A7963268A1D0A0491B8B5CB700A7D86AB9039330EDD8BB17CF1AC79355A82166458D2323E070AC109C98D201358F22BF9A3B513B8BBA43905D1A790A7B1A11F682583AB4FE0A82F3E316B7C70AFDD823C8FB7ACFD330B22F378E8597CA5357454A71197CB4039E9A81D7995D14587B479657584407B281886D6A7FE9B6170A056D2003BF898027C275B7C1C3D1D0C157145BA52D264699B969D60AA3873A9606041C20B17C90055B8016EA703539638CFF8AA0A219542BF51B68CF153A86149881C087D898EF9C3A089CC70A8656117131AA3F233C73CBF439022D224422920501C07243432AEB925C4023185D3F897A79A983D857C6D1422F9B22234005E00882F77C7704CC74ADEA4C8F3971E7964BA1A530C1F722EF696828C46946F0B329D909A47B83353330630359EB8E9B7E78ABC50FCA8C3AA9AF967C89F464430C815D1959A21A226A966A6434301FA600A4D129886826803EC49A54A34ACD62B50E33FD782937571816421341CD76A3570C17AC9C338E4AC4C51077650B98AE445D236904DA694F755C1A5B288275B517B4C9B896C49BBC18933E52D34969B6AD8ADD604B526488C6397842A54B6657B93386B0ED7D36FD2F448EFE43B0A144C33F729DF530C8B6340CD61897B3C50B0D8BA81228604F7A4BCD120CD2A7BBBA3B4818177C435A2B0C3AD838C6D9BD3903D64B32B8A8DA5D93589021251D14C920328C4063C2AF3C8C41228355527ADF41037E1AC6AA69A427A55354CA9D54025306C16F93154776B4A7AF9C9EF2298DBA9B669C40BD0601ABD410357B8940511BEB6C96541AA7B69158362A41767486EC3DA09AB4335FE2A25DD6C07366478CDA91C691C5ED9264F771124C1F3693050802F480F5DF89D5BE189DA765337A69C5C838488A0A4BA7880E91871FE346CF3ABB0AAEBADB211B5ACD3B773C9146CF97920E509DC202F79B14734C9777A567CD44A43500B5EB8005BF4C5A387701286639E6D9AC2574B33F2432B3A787039E34B2AE511A27825CBA7A8E09B401CFC6123D3B4C42318E7B032331230DA960A09F61A6A196DC185BB8BF1C1A6B691A06CB57F12BE1E45269C56490E256A83C13352A878C724242FF0681881160ED03166612D69894951D65B95E690DB46129D149AFBA2C835D3B138036931423D2F84CA51179466A1028D1601D5C397CC81B1B5E468869185B25095A0E5B5DD6A421B5C7ECEB58C4CF97B7FEB114FBC435C78857C65098D3017FF8A58F5927E5EE7712FA0C2962939B9D8C84BB6428B3902881188DF17479EC01E4709B7840235CCD77ACB0BB3A05995693781FB711D61F2883827A96DDACE29A9CD43EC6ABD4691BE1A758B72A629F6AAE1C795981C0D8BF8160BFB3B8F5047E1A410CDD49C6A42ADF0BCAFED1B21EEB95D504B1A48B1ACE228BB5E1508BF05128F0CB63F5597851B9DF4CAA5B6AC10F7F6188DC41B02761F840CAA42871C55205CD09771AC9125D6265DDC56A466249FBD774EE53756035349CA12A48237221BD53D7FF1AC18242442935BA818A3B50007A3FC14A2FA3ABE437FF14705DF0CB5AF97561A608A3FEA42A809A7A7D5491453C849DAB7ACD99636931C007A70D01655C7302F9A26012C494DE47839C1EA2951A87FF73968DAE83A86F392F021873BE4C75D2B0700A3B540F50CF6FB664A4627DDA9C75394032F434655755D12D4C781E2324AE00DD61744CEF6C5EC9680F379A26284BF9590A33350905E080E9B70547AC1CF3AD888F30232FDEA7BD2C184F9E1A9B6835401E737204C5EBF2B28F2B58EDD399F873C7849CBA8064B8A20C9C391841875B4963BBA2097B958D752739383BF26787E64EC215974B45848185F44B8780C0714B9651A7685E673CD1B6230C5D6639EA5629C20659802BC6F2B95DF274836241165A524EA99A941312FEFC7CDD2FA8016D69B652C3E94E73C70C97F65B3ADF14BBA2D31916522701D80252E9C7FBD7A17D306A4E1E02CDA405F3F07B38EB65824D5C9D8B91F7013784FBA0DF0348F21B00EF5A325C745A829714A5B9ABA16ACBDF029771D5415E867590CC5A57360A8969407F0749AB8A08A65E37E70146FC1B7BC40D789EAE83761E77749A07859BBC046B5A87E3A92A5368251127F12D27789318F8B9C3C1F79211922C852A0B0E10BBB631599190B49A66937920B3F113185D89C6E37DA5F7CE9C12D37C12CC24741CB9A79446606EABE8C9AB06D8963C959955F198E03A0BD127242DBF2A2180281A7B65F54C28EC9C6CAFE64881D6456C07607CDFB89E2CA2FB3BA8F8357720051C30952734932B08B508402A6A2F4F9C76B053C12A267618928032B5D9E41990A18C2C04BA7C2868AD9F4538FF1B494707EB9DA6B81374D7F9731F9A26089D7033A8C24600944D65871D313387B4101C0AAA27AE19D978653638577BCF4CAF48083EEEB57F401544D4DA3B73DC1C5C4A047B0A5EA85EDAC7BEC66F4D87FD2FE422E7DBCD02D145572BE2F5CD569E6229F00014854633F7B278E90AF4EA593411909467A03E29CFB7B534537ADDABA4ECF14F02AB317D36CB9F0F50222CED7CF029DFF8A0D3D2FD9\nct = 90606786779293D177977750726975F4EB4D2843F8F693800A1DD52AFBE25A79C5E48D83D02E9CDA1E3909D1C23DB2E382ED3DE92FBEAF611F326DD2A34E597CE9695E211FF7590CEA226B588A5BF394E8AEA1AA959B45E32E7AF8DC01500F950F9AF77878B8F280E917579650DD9ADD147D1879F249FFA2B48E170B5172B97DDD0BE9BECA1843BE63C7532F7BA2B85E508A600B1592759EFFB657EED4162855ED6B6BD143A91523A3D033BF5F6199F8D1BC7021A37ABFBB82886777797EAE296F9D5748FFC0A1276575FCDFA8056030AF0DC936AD79D24E68228F9C50F3F406CF0DCFC8C7767285B67EB6BAEAD90391D8DD18781752FE025407B96C6F042D251556B610755D1BDF36A806230A11C2852827A048E835875239F99BC4A31455E13ED565961E1EC56AC4719993F2D02CC08F03941F9FE37A7E18A66DCB2E5EF5A591FC5A4C5128EFB1435FB97A2A396B749F911160CB4078F5D34FCC42572B95E4BC5929302E1C77F5E13F633CAC285A61C2DE38877D8CB44D9110FB415C4B7B7132A04050890602D7ECFCC1747600E8F2CC27CE59C9389B227AE001B1133BA633D0B332EFB1D2E1E6CBFEFBD162CC62002A9603CC2F0B580AE0C541D4DBE47E527BE1095112855F97CFE206A38583EC34D7B87CD37824206D7EA069FE35A9C8AD0F14C45E5324A28013C1A2D705364B67D710FE03EB273218CC5EF9DE14243B6F097E7129D90D770B7515E214DBFE7BBB53D816EFF35714CA0B940027145B80598A2031180251C5B508B52970C98DB719F53C11A16E4E8161FD9341AD76EEDCB6AE20B6FF1C0AFF2E78E538515B8819BA6110ED4BE125037533489E0C76E52231A0EC0569DB5EF47F6492B7D6ADA2276F93AD2D53B08E45E8872378AD44710C2254556435483D4BABBA906E60EBEA08D652C17DACB971FF31350EC86E61B655D106D0A7D8BB8D224687C77D9BF70FF94E55D658CBA09EE778ABE08D01FFB05252F98B378DB8467CF5254CE62269C1D42DA233FC59D032B7E69FDCCB57B568BFC40A1050FD73D9E04D29BE0B4E63FB7A817DB603EE7CDBE280E772F7D18B4C2E3805F6EFEA65F1FA09A9F3175F4104C2642B0867DD997AA26D55428F41B522B8CDD48206FBFB97DA0E7CAD7BAB9215B7850B6AD4389148CFAC1F9DF17D1F6B8F629BF5AB4409E99B24016EC0F425ED4EFAC98FAA2166C6B6CD39022BFA01B3FD57D30EDF1F2298601420DC2CF757E3702E34B7EBD285D2DC6BD0FD07967EF1BB9447DAF0F0B5F52F2C61DB0E7849FF02D03C50703961A5C03FA23807218A04FAB9466633563B8833784DAC8E23B11A0D895A5EEDDAB644C23F6332735FDB0AF36345DB18EBA4E5FB4F4A30000DA7AAB1860853103792D4C32FE13B8EADE1451F6537212DDE6D0B1160A151BC4F33725698930774D5E26FF1B57FEE3D2C19A5E5AD0FB0A0093C4875159947DC8B7D915AE10FBDBE2FD73ED5342BAE093D764C26ABD30271EA1AAE78FFBB55B2CCF97CB8D75FC6438147718B4E844D14EFA5965BD6\nss = 7EFDC40486793DCBC7C030273F8EDB4178075955EDBFBBF0F21B793206A172D4\n\ncount = 51\nseed = 450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88\ngenerateEntropy = 25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451\nencapEntropyPreHash = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917\npk = 32B6C92F059443501427AC964FA569CBB074C71053F179BF1963AC704489EBB9936E23950E51AB7E26A98D6031C652701FA4AC59AA7C15D88C0337A067257B8D916DB0456FAD9622F44A928DF6CCE84A3E6634C9CACA246208920C487B9A666342ABC389C14C499785BCB91A95DC868FA20D25B08AC0E48C72E9B486151F21B11731D1BF049174ADF279F9020AA98C", + "38372877299C4F54A4493A3B20F8BC71CBC490B363C4162055CF3A5C13650DB1154687462FC01B5E5B78C9F603255A24189B808358E17E01B9CF736A77D78A32520B6DDC9C1DD65A00E84B562B607B6AB472D5173AB53A97DB08B322E95CB3378D5D088CD3CA6FA4739C6633A27D686ABF040DCAA766BCC18D6B8A2F91E51ED6D49AA37AA44531BD9DFA25C116A842E50F53A68BF1617245E8B7DA778EB3343D3F2575EA84627C640A6509133F4C5D78151A6695245659955CD3824F264A7DF58EC87C8AA3066ECD1B68D848CB758487E647223C0154388912ED028AE364A9FA9A018D8558C3E9B179B66F2488C2BE8792B1849FAC0401A9756F209889FA637CF7ECC4F2C0249EB5C6F7E0219FAA2A9433759AC70DABC7BAAB623C2023CF7EC869B75BCE953CA3316B7A6FA685BDC7C8D467273268A0797B8D6FE57DDFDB03FFF7AD3D5B9C80DC1939720EE8810933A04F51B78262910D7E28C0EAB06B91980B65056472A293F2361183125670AC2426E514790B945D6B09C9EC354FE7C895A30231D95794F89EE60761AC9B2AAA9A75EF168C0950AFB498915B2518E010C3800764BC5A65C0C54B2AF686B7D954E77BC4CF8137AB398FE93429DD0AB80FC846D4CC8DB2B9B2B4BB36D4C4121639C1E74622E59250701302301B4DF96B2FA62736B29CAF0866096F842898B2C6012B93B5AC23D1F39E192002FF0B9005FBB8CFEB8930562A4E0AAE7A40C5032B8B33D0760D96C7C203920E2439D3EA02372C7F5D80B92259349076BA20C3AD4FD21752A3963CC5126342A963A363C1157F33189732F7243E465B14969F1CA199AF45B50851266742151A235A8BA9A595534BD6AA31CCF52B8C5885D571A93D2577C57057E2CAAE68C9C84F565C72681FB15056A345236B02A1E5B13289388F035A2F8E03402F8B0A44259179A904C94725319ACACD28AC1E449B87E8916091940E33861A4A35A8600267F04FFC6A3E06C60858D578BEC60EE7716FD4B0225E5CCEB5FC5437387522200F66FC880E0C874119C71F462CB4EAA24E67BE77CA67278344199B27E2A55B50F372B65345122225D7324CA9504CE4D12BC101639E93B331E3B60E1B520E03C9703A69F54C2B1A52254AC44B86F310A711263A5A9B87A7116EC5654F7297EA76B63F939C1F49CE99D52BC58876160401558193AD98C7C8F4B6822712429679214BB2B6E8B324B58E1F57695DC8968BCA7EC3717DF12C1279408183B49679B349E2E45686E722C3A57BD9547A65656CBC79AEC1D3B129837D84A6975D018C7AB04C88775E9C68839955775FD66AB02AAD69B76307F51DB2AB33915ACA61969AEFF14674A557C322AF6997B1A8D9C51445884779227EE742986446EA1719808996049038E0D9AECEE828BA054417CC3A683A7295066AAEE9CB429C4740531990744A987152DCA2388BA27E3769C8BF287E54E41CBC0ECCA95CE621F2\nsk = 2D149D32C41889573CCB5166C597C3FE207CB806BD13A8A7BDF86267A93DA7110A31F22221A17A5381C367EB1B9CD00810189C1F12358B59ADBFF2060ED6AC6712C660B51B553402D406BCC1D2444A863B6FF261E17AAFFFD01BAA2B05CD83050AB460CED09BC7C0C2963784B7F9798D837BBC0483001539F0EA65A0574B46785645019B25130095725FB71556ADD2832EA245E250973F504DC58A4BA3C45CC8259E7906588D688F4F4CC79A1A955EE31E0FE931D16CC9DA767C3A48BAD09874F7730FA74C349D2163638AADFB59A462E904C5530A0B485541E391B6037041EC6A0560563F186BE2AB97A42520A7DACEABF1216E16870437CF012A6B6D082BBB23349628AF4DD8CA9EA986498A80EDFCC2418C3F5A627BA8BAADF3739B3C578B2F193F57B72DC2827A2DC379AA31B6127C65352338C012CFCCE0AF1B33150D488CF47134E06B5EBAF0432C172090FA6671670BF7B66002E135E7C43D938343D5729E22E5597A06209E0793E65417DE945B5E1AAEB2740FB1B350C902C1390A97586564FA94120CF7538B21AACC0AC0831B477E37C9E984B73EC91ED88705EF4CAFD2F15A50227C0E4C0627D2A6D7875E9605AFEC339799690BB6F0A5B01141A6976FD51AA7A079827D37CA89726686BA95D6F275A59341FA229B4C163C260C4DBC4587C50AB8F0AC777849B5F700209F17C15251854C35AA23C20D486122EC8145565966F4A067251B96461950AC2171F1996E94517610338B88C091C356804CC691922449DB0645A404AE4A641D1482B58E6230C7965C23605D66E96C8F0418AD786801D7530CFA2B5B757E06ABC10518B274E3992E538922B717866C7EEF827D2BB4C05FFA3322981CD8069DFE028D878A8B7A002472D302253A83AB84ADF5530CC5F4671BF5219FE600BA97ABD2555C52857ABB76CCF4760ADB30346C55AA5340B189E1968F72999E64C0B76297D232412B3C9384783457B83309BA7EF74ABD50D16EA1C32A2362AAEBD02DA7790FB8827FF368261CEC14F3A2095323502446703783CA9B6AA595D690031297C59B25414455C155924A47896716AC45330CE7069D131B75A57769FD4B4CA1990170A3570160CDBEF1C930063D56E3546F09B1CD913C82057C0BB89111E6B1BBA88EB8CBCD72078FCBF5059FE25C84BB5607D7B20BD0733FD96DBAE2ABD9531DDBE3CDD89A926361BB56EA0E5F9181B2C8C1532312F3F9005135C07DC211B824B1E63AC96E64845C35C41E0313511A5D429663796ABF2443908D353766D40F47A910FD04A710BA5D6A5B301832A5B6016338D8858B220E8219512B643B8B60CA2A9347EC39638B787FDB44CE72408DCD2504DE24AF91130ABC09B2E7C9BB26B3393EE06FD77019ED3466E019AC92A416C9683DA22CAFB1A9AD3475AF17A15EE9F97446096647578F77FA02E79904FCC008FE509425446CA2A4C1DFF32CDFA4CE120230BB5CC9CB49A2E2841BF69A1C49A762EC171698CA0445201C485A15FEF2562EACABAD3259119C9BA4185677E03AA0470CA848709C4BA0C8E5814416C5678033C819773DB36E7A90C65FA82FFDF6921C38285122163BC0744DE5C5363C9A973428A6DAAD20E5A62D37017B464DA7637D32B6C92F059443501427AC964FA569CBB074C71053F179BF1963AC704489EBB9936E23950E51AB7E26A98D6031C652701FA4AC59AA7C15D88C0337A067257B8D916DB0456FAD9622F44A928DF6CCE84A3E6634C9CACA246208920C487B9A666342ABC389C14C499785BCB91A95DC868FA20D25B08AC0E48C72E9B486151F21B11731D1BF049174ADF279F9020AA98C38372877299C4F54A4493A3B20F8BC71CBC490B363C4162055CF3A5C13650DB1154687462FC01B5E5B78C9F603255A24189B808358E17E01B9CF736A77D78A32520B6DDC9C1DD65A00E84B562B607B6AB472D5173AB53A97DB08B322E95CB3378D5D088CD3CA6FA4739C6633A27D686ABF040DCAA766BCC18D6B8A2F91E51ED6D49AA37AA44531BD9DFA25C116A842E50F53A68BF1617245E8B7DA778EB3343D3F2575EA84627C640A6509133F4C5D78151A6695245659955CD3824F264A7DF58EC87C8AA3066ECD1B68D848CB758487E647223C0154388912ED028AE364A9FA9A018D8558C3E9B179B66F2488C2BE8792B1849FAC0401A9756F209889FA637CF7ECC4F2C0249EB5C6F7E0219FAA2A9433759AC70DABC7BAAB623C2023CF7EC869B75BCE953CA3316B7A6FA685BDC7C8D467273268A0797B8D6FE57DDFDB03FFF7AD3D5B9C80DC1939720EE8810933A04F51B78262910D7E28C0EAB06B91980B65056472A293F2361183125670AC2426E514790B945D6B09C9EC354FE7C895A30231D95794F89EE60761AC9B2AAA9A75EF168C0950AFB498915B2518E010C3800764BC5A65C0C54B2AF686B7D954E77BC4CF8137AB398FE93429DD0AB80FC846D4CC8DB2B9B2B4BB36D4C4121639C1E74622E59250701302301B4DF96B2FA62736B29CAF0866096F842898B2C6012B93B5AC23D1F39E192002FF0B9005FBB8CFEB8930562A4E0AAE7A40C5032B8B33D0760D96C7C203920E2439D3EA02372C7F5D80B92259349076BA20C3AD4FD21752A3963CC5126342A963A363C1157F33189732F7243E465B14969F1CA199AF45B50851266742151A235A8BA9A595534BD6AA31CCF52B8C5885D571A93D2577C57057E2CAAE68C9C84F565C72681FB15056A345236B02A1E5B13289388F035A2F8E03402F8B0A44259179A904C94725319ACACD28AC1E449B87E8916091940E33861A4A35A8600267F04FFC6A3E06C60858D578BEC60EE7716FD4B0225E5CCEB5FC5437387522200F66FC880E0C874119C71F462CB4EAA24E67BE77CA67278344199B27E2A55B50F372B65345122225D7324CA9504CE4D12BC101639E93B331E3B60E1B520E03C9703A69F54C2B1A52254AC44B86F310A711263A5A9B87A7116EC5654F7297EA76B63F939C1F49CE99D52BC58876160401558193AD98C7C8F4B6822712429679214BB2B6E8B324B58E1F57695DC8968BCA7EC3717DF12C1279408183B49679B349E2E45686E722C3A57BD9547A65656CBC79AEC1D3B129837D84A6975D018C7AB04C88775E9C68839955775FD66AB02AAD69B76307F51DB2AB33915ACA61969AEFF14674A557C322AF6997B1A8D9C51445884779227EE742986446EA1719808996049038E0D9AECEE828BA054417CC3A683A7295066AAEE9CB429C4740531990744A987152DCA2388BA27E3769C8BF287E54E41CBC0ECCA95CE621F20831C75B153FA17D336A79FF6E88DDF485DAF7B1B0BCF39D8DF15319D52AC67EF48A9254DD40B117941FA35A66BB50296327B725525DEEF70E128CA8045EC451\nct = EAC0E656E53BD64C8F7B2BE3647A96712E4F83B04FA4555F1D3B8F9B796B9841C2D239956674CB51CA6DD945F2B9C40CB3341881E883A6A4B356538CC01E6E42B72DE8754BF38C4363C5F39C9661C13B207DC92767B34AE07C3D38BDE0BE4910E4AD5DDADCD4AFD41C5B6B8A00D537ABA8F5796F940B892EA5B797D2A19021168CF55F0054B6C6C7D43B192632F3DAAAF4DC99C2157EC5035E8039809A95126DA22408AAD3558C2C52528B46F313B32D8730CD5C5EFAC4F58F539CB7DDDF931C6EB9AE718BAD5B5F10561A922D4C0EFE6531FA7012568E5A372F6380D5C31A5F722768B2E9395B8D66768E4D8305DE645927D91BF7627977E9739563761581F438E05A50ABEE8178065406D40CE6818EDC2ED16FBF346DE6B40FF715CE1621FB2D55357E359FC3B67D1010FB65A732F4AB7C7BA83F4A9F8C294C7D96DA285B931F78AE792AACC355B8527FF2CBA6EE903B666691DD4F6ADFBD58F21EC2143571E061F6049B61AAF0A56885B34559DF49BCDC71B1D2DF11EFD96BBE1EC331C8483AF5D9EDFCA14F3955CDED0A2AD957759DDCDB02A93C5876FAF55EB8A32B74975D5ECFD3296B00694EA1DADEBD5932B306307943680AB5A2B25CAD113A22AADFBB9DD8F4C462FD6EFEC2560EB8BA20A0B2BFDEEC2193E8D8EEB70F759E32B3F07BB3F7F5AAFEFB74C5C54D7AA8369D8BE515EA5ACEF7FFBE63BE3AFFDCFF6144FF59BB0E4EBC711A9F001E05D3A4BB4971377462E695FFCB41D81AB63ECB228D47049367504E279E5CEC3D1CBEEE4B1B9AFD9EEEB8565CF6AE4FCC0F62F40686DFFBC7E9A4148EB3AFF9B876987E7D67756FC83DF5B69CF46FD3AB096E5B58F16756DD1EFFF6B898CCA1BF81E19B364C3854420DC8570CC2C5B0E9CEF31180712BC4CFE86646540943", + "3B57577EE869F77A3D713BF983195B53D825D6B3A6F1DA471ABC964FDAF6A9CD64D21C979C4609FF77339EF560C793DECC75A6C78D01A8A5A6D1071708FEBE38C7DD95CBFAA4685B5C8E22FB0A17849AD8BD0EE1A613CB2A3C6D1EF0A4D32BC535E45FB5C4022B870F7C410C9D93157D13C47E8C4A89DD9742EAF9603AA98E98020B0EA05E9C6D21752CFBB0D77995DCA48E0CDAD479364AAF3ACB4A99204A006EA3BE92B9819FE611FFC3C9C73F240B147C038151BA94CD1DC0E78EB7EEC32ED7B1D2DECDFC6751664B80EAFBA4600737FC2939413ABC36D14100DDB3F67EDAC9317ACDCF043006FC01FD97FDEF6ECCE4400B542A4AD2BDC4107D975DFB762761739ACEFC9A6B2EC26AB9C80F24059B46CB52DB1EBC929ED159497989131A7B67BDF78E141D8BCAE3DCBA7948CF843C2E1409830B2234EA1638C378B40C87907B1557A81044A5D4407CECEF5AB2DD55A28CF30AD06E741BF47A5652E56DD44AE96FB93E57259542F4EF268EB9221D714E472B4C633D2F4194BBAA72B629B83C7108AD2DDE0122B3A31F5D028C911DE14F1E80E23001FFAC0E8434226A1F0834CF5A5E0CA419D46759CB8D9A7236EF949A9CCACF70DFB4\nss = A33BBCFF1EC8C4D3E3229AEC78463FFEAD5B96C6C1FA857921F8907A9180AF07\n\ncount = 52\nseed = 5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F\ngenerateEntropy = e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b\nencapEntropyPreHash = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e\npk = 7C6B065EF3308AFBA0CF3607B2C98D83F76F7C058262B55F7C0746B3C22437F00DE9D7CB69F40AFD60AE74B0506AFB96E30669F51C464A27B4F177666F92459B293DC208A0DAC5654A8058A8FABC2D1853009743A598BAB2C248068750F01227BE5A4F7C4C6948F9167E88894D43B5AA44687FF177DE837E2F0537F708A8F73A11FE6632DC285C9026BB23424AC2D1CBCE39AC6A0A7686F088D617B096436C9F773E7CC50CEA1C08DB20C2949A7878D18E7372CAE746B04558A8FBE97DF0B9A69090449A507E6E1C07A35680412033127037607B2F0502690B47BD300A84C041650DC748AC2C060260C933A0B81847243FB3267F3CC8DBEA4CEA40790F37CD0373A71EC00634BB3B3B087A82CCB1E1DAB77300156D8094A1D61D1F1BB3F977B749C938AB8092D71C93394856ED133075E2BBDD3CC0F27C2A2D34BC0F633F5E55C0A6C989B1E277EE9132F8779923EB2E22F78A1502BA5E55B6D53A05137867C10536E672C7336A3EA1F237263A6046F260ED3871F1D479BE589744361A0D819439779075CC47A5A33E18326615134D9F09B68B6873C6CCB682F6B75662CECDF5432C37189AE09FAF36735EA01C12F9CE64F4116D509C70E0072A242FF126710D178DAAE86539226C92D090D9B60DC63539F51B46DBF24CC8D54EDA255E0AC19B03D34F5A270B6FDA6D6408BCF1D2A46824B5290B8A26A8131402C9AEA052D0101759345F86A66A4D238A20C6531D792170C52DEED889AC3050FF87C659524337830C205622A989736B788092101933C0073C0B686106A9B88C17958A8711D272392AC448B01507634DF4A23846AA9D594C80BCA99F17505AC1793F2877BAB4F1B211D2985842795C4C1B9FC018DD15B510556EF89B687E6B01701CBCE0B56159A90F7B2C6FC1039AA38449A596C087A62B2EE5A7C3799F5A601BFAF8B9C598834FA115AE010F71167FD41B5CCCC45146009752F380CDC56453E554CC779604F976FDC34E9F135261EABFFBF00AFC514F2699AA6A5ABA0638542891C6858C7F6C6C4A12E4CE2D89B50B04C33EF262EE8B0D9A7777D3C56C85B1BAFAC7052FDBAED24303C843110C1892381887EB351134798B9745BC229208B277C2C999570075903DEB530BF22F7906B75DB35C3B24B04751BF6ED41724058C70988952D86B48519264D25EC2B817894AC370BC081362C841EBAEFCD7625A67A48E3CA492D63BB9036A5B9A35D21470586510ACF76FCC683035B18C05ECA7D0702E0453AE00A8144779117D7C19CFFB568A3C0959193D689A6ADBAC13DF43907FD45FBF3313D49425D32AB9D81C6BD9B3486C3636E6E0015152C1CC78C809F3A3FFBC6F0628609B996980B3C43294C0E293940CD65A34BAC8FCF020CC611E3E2C8E52F5AE886B8D9480551D012885318E5E6C1ECEE0A3D75B342667C691D19F34FC7946E7A7047097F7938516CBB6C7F3ABDB85B15E302A5547198AC0B89E7C2BFBF74050970E8DC746CF16BEE6147076BB89C5124A89E070A785427CEA590301CEA7AB28ADA228EE7BC7FCC17074063358A706989C8D6C82677287905722CCA0A24FF91958C44A3044787EAB3599EAF241EADB932B06B151A1A02BA8B244E9262B96144302124DDDB5584ADF5FEF6BDE5872A551B6840E3A082A8AA6DFB7232A6813367038CC\nsk = 85B01A4A587BAE308D39792B47F71997FC55FDC2746F881DDF7BC215145C56D399C6447ADA39230866384BB718ADA160A7349747867CF695CCCDB8A4F1FBB3E573ADE85CCF38924F36482BACB9798D481521A0CAE103CC9FC9675184490F281D3516CBEE910287758A4C374C0A4313F1C29251B1655522936DC329F540A1FD887F0C775823436DF736C367AA3013341E66854FB39A9EB90B23CAEC3E84690AD531141F39914A77A767A47B60F2868CF11311AAC9DA94C72E9624D21814CDC99C89A4B35E1C4C63CBB3EDEA06888162E180503CFC6616B24D270601D0D275C03109DD9486220B66D523A8111B4DE5B99D236586A09A4F77A240CACB4A737C770BC4915F55B609075EE68499654BAF90622647052A8369872A93114C80C60FCA1345E20114552119669A0D3A7188D3326017CE92112F0B715C26B40851683478E5C719C11088F00AAC577F5A8763D4A76E3CD00CD9061F021672847BA0D4785EA7B1B28FA364E64C4FB7F718D2352B1FC26858B6552419A4D8E1B22F8C7992E3B5373183D040948777C356D514FDFB2D0C5A636BC5416A799270E5C975C0A62F3A76FB134646B333B75582F7F2C51CF4BD37835C3FDB2CE1EA86306362F8216D27E40CA43A45EDC9554F08C604624659AA10EBD29E59A60F7BD66EEE447F4398ADDC73387579148BC4A26B6749C961926FD34296DB3044CB0D2D1312CA6A6755EC48C46865A36A6330A9AA5D39167C6062EF1A7C82CA5C0AC1B163B85E43C278312C4304AA127D66576E7218C2D0C850108076109919AC6931264DC2E919FF441875E607A97772FEB45F14881FBCB37B4D00B45F416CF56C9501C6598FF9425249740EACCA49D92E31D679A4F16C3CCB4384DB45E47621719C6C585CCC03355216D43625C08760254AE3CC4AEB1287CD5C3F0911641B05C7036C9BB360C72902325830BD25EACB5A88ABDC926E0F205EE857AA66C8C47E434D8BB4A6CFABBD8B681C427846F0E18A2762152B170063B489A3E6B8BA06B00F14A3F2E6AC00725E5724CB629B7A312B3A1221C9460917C07637B71050BB644A38A8192270C857D43EA9304495206BF62B1C4C11B04A817AAA996B2A266CEB8A80AA46674F16207B61BFB484AF461B6DAD9A9E6C22C56F81BB355A6705310E921239497809012159E78A8A249796C155A9DC7CBFE7384DD092239C29773F6610E536A77B879EEF054C5E539A381043C1B53D69566A96D1931B166C6F066CF0EC81E7492A200876D42007724AC916460A1266AB77A327EF1282479685BC43A2718C93A806C3DE3A0CB918C7A734CB04759341C5B1496679987AA5DB93B70F903A5F4024C3DA6FE8BB2EBC27182E1179611C61F8F6214069AB83C7165A46CAA74BBCE0897FABEA9B6B58CD34E7535B0297B4359960D23E4A498CF7610601D92AF2FB6163C4B2761615121B62A7900B08D61065C83A69D51253D48399FC665962AD36275ED3774F114A079F13B8BCE420B44638CFA6CE6018B58BEA422A8287A6680EB21C75456592E8B24CB6C26EC3D3C1DC4A19CA16888E9B7FEA1A863B7A0143307530B533269A8B692CB4522AC1AA27B01D38603FD009E1C02017BBB36DA2049A2C5045A63081266D7C6B065EF3308AFBA0CF3607B2C98D83F76F7C058262B55F7C0746B3C22437F00DE9D7CB69F40AFD60AE74B0506AFB96E30669F51C464A27B4F177666F92459B293DC208A0DAC5654A8058A8FABC2D1853009743A598BAB2C248068750F01227BE5A4F7C4C6948F9167E88894D43B5AA44687FF177DE837E2F0537F708A8F73A11FE6632DC285C9026BB23424AC2D1CBCE39AC6A0A7686F088D617B096436C9F773E7CC50CEA1C08DB20C2949A7878D18E7372CAE746B04558A8FBE97DF0B9A69090449A507E6E1C07A35680412033127037607B2F0502690B47BD300A84C041650DC748AC2C060260C933A0B81847243FB3267F3CC8DBEA4CEA40790F37CD0373A71EC00634BB3B3B087A82CCB1E1DAB77300156D8094A1D61D1F1BB3F977B749C938AB8092D71C93394856ED133075E2BBDD3CC0F27C2A2D34BC0F633F5E55C0A6C989B1E277EE9132F8779923EB2E22F78A1502BA5E55B6D53A05137867C10536E672C7336A3EA1F237263A6046F260ED3871F1D479BE589744361A0D819439779075CC47A5A33E18326615134D9F09B68B6873C6CCB682F6B75662CECDF5432C37189AE09FAF36735EA01C12F9CE64F4116D509C70E0072A242FF126710D178DAAE86539226C92D090D9B60DC63539F51B46DBF24CC8D54EDA255E0AC19B03D34F5A270B6FDA6D6408BCF1D2A46824B5290B8A26A8131402C9AEA052D0101759345F86A66A4D238A20C6531D792170C52DEED889AC3050FF87C659524337830C205622A989736B788092101933C0073C0B686106A9B88C17958A8711D272392AC448B01507634DF4A23846AA9D594C80BCA99F17505AC1793F2877BAB4F1B211D2985842795C4C1B9FC018DD15B510556EF89B687E6B01701CBCE0B56159A90F7B2C6FC1039AA38449A596C087A62B2EE5A7C3799F5A601BFAF8B9C598834FA115AE010F71167FD41B5CCCC45146009752F380CDC56453E554CC779604F976FDC34E9F135261EABFFBF00AFC514F2699AA6A5ABA0638542891C6858C7F6C6C4A12E4CE2D89B50B04C33EF262EE8B0D9A7777D3C56C85B1BAFAC7052FDBAED24303C843110C1892381887EB351134798B9745BC229208B277C2C999570075903DEB530BF22F7906B75DB35C3B24B04751BF6ED41724058C70988952D86B48519264D25EC2B817894AC370BC081362C841EBAEFCD7625A67A48E3CA492D63BB9036A5B9A35D21470586510ACF76FCC683035B18C05ECA7D0702E0453AE00A8144779117D7C19CFFB568A3C0959193D689A6ADBAC13DF43907FD45FBF3313D49425D32AB9D81C6BD9B3486C3636E6E0015152C1CC78C809F3A3FFBC6F0628609B996980B3C43294C0E293940CD65A34BAC8FCF020CC611E3E2C8E52F5AE886B8D9480551D012885318E5E6C1ECEE0A3D75B342667C691D19F34FC7946E7A7047097F7938516CBB6C7F3ABDB85B15E302A5547198AC0B89E7C2BFBF74050970E8DC746CF16BEE6147076BB89C5124A89E070A785427CEA590301CEA7AB28ADA228EE7BC7FCC17074063358A706989C8D6C", + "82677287905722CCA0A24FF91958C44A3044787EAB3599EAF241EADB932B06B151A1A02BA8B244E9262B96144302124DDDB5584ADF5FEF6BDE5872A551B6840E3A082A8AA6DFB7232A6813367038CCB30CEDC4316B63D75B641FBAD2F33241A3FC47AB8B3EE1A3ED597E5B04F77C68E6C45C7FC62329B13C8D29844405DB8FF6860DE474BF727ECD19E54E6E1A141B\nct = 3EE8CAA61756787B200AD5EC90EF835F55359F55AE04C8CAE6D2FA90CC2E32ED38349B52E4A6BA4ABA658A972B95EB04BDF9D9F007FF1DB61055B41052095687D07626DDAE5F9C2D2E7931C6C45250F5604EBD6D6C4044D18C0A193C9CFDCB212393510F1E966377F0BF34DA89597CDA14FAE339D2A82D3415C7652A4B95945AD0BCB12992472766699FD0F5876F728681AF0EE76D6FD4E45563DCD52AA7C2E5E783CF2A6DEAFEEC004C87EE47B2B3DCC98D59486341ED9B282AF0705B69EC8D498517D0CCC5847D6431677A8FB7B5DF6BEA0E5821CAF8D14A81A0AC674089953179A3DD7C0198A9CE8732663261530C138EA09466E68F2A485A492D5875736D590C6BF0AF9238752EA3949593CD15AECDCD783DA5934BA69B70E1D9AE7C56B8885A3AB409098C17A4820CE2BFC365644A8180735EF122F41ECDB5387E87CE5EAFA8AB1414D48C7B57F52F3338AE5E5758E83E560178DE13676A49D69EA415622CED3C09A42F354B3E48205937A660EF1F9053CA4A1FDAB50FB5E83898B6E5FC8A11D6DDC1B06A29EAC43A5F47F2F70FCB085BCDA559BB3CA3B035E119970ECA86B5F373ADF2BA9CF6B5755445FDB574A40650D7E75D7E36F90CD7C96343446A87882AD03464E8ED40797EDCD84DF74FCFAA83584E8A75774DEA67C74F8C5CAFC18F3BE9B2C11EE6EC6E89CE7452D0A98C64C8F6DFA6198D9CA561E86A1631BA17A6FD6D4181186ACDC327E71FB300A9397DB532B88823D8D310ABE4FDABDFEBA7521C939BBF7413BB5199AB40DAE9A8B7EDDCE3C38293D30D6A5F18FFCB12EA2E8ECF1A942E20F8310825BC6960CDD7041BD9186F723743C8C98432536EF35E69F0E7D8E0A0E05F3E40199EB1F2F7A41B18B0E7F2245FC7BBA28B83A3A4F0CEC6CB919D0CB7B66745200FC4074C510795982665FC880D3F6E3820D4CE2333C717D94DDD36C4341F01819002E21C41B12EC7E1184A1F7E3E6FCA6A18971B1C438C773A7124DE94320443C7D80C727237890CB13825436CF0ECE3FCB867A86F8C2BECD314E2274B9BDFEB3971EBE1730BD44E26B587C464E86404B8A18E35C6FC427C7160C4079C394D11CC93F473153967A394D126DDB344441AE12729464DA5E813E5461439B6FB0925A97B726A2D724850829EC1D6E1F3881199CE47E93101D99439304B00FAB1E6875EC82E4D8766912505121628AB17BF0A5094649E8D5803A59CB35999D8E9A2A7D14646A26F9DB4BF0FDAE3527CAE7CD04DD9EC949DDBB122616881AFCAD30959D5022DEFB1A2F86903CC0B1A63DC1D21D477319DF95E7B39322B69F8E3260B0F52D1EBFE21D0754A2076AD4BE30E2E47165EA3EEB054465AA4B5DCDEE133EC90A4D9C9326F153FCDE75D9E3A3351041D13EF0B9117098F2E266EDF666A3F333D8FD17C514A4A351CD2CFCB044FBF406E1DD5C99809731B988458055EB888E00665F3B2EFC0E4E16F81AAA6F28F1C87495B078B236971CFF1148C71C374D52AC1C5E68CEF548A30B0D6223E995D7216F6604409101D7B\nss = BBC0B0A4782E2BB9EB19257F5B80338D1E239AA6A08710CBCBA0ADB974D7DC64\n\ncount = 53\nseed = D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E\ngenerateEntropy = cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922\nencapEntropyPreHash = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2\npk = 9E686B49D538CF32A05AB82372F7525DF40085B3413F078226B97C234B815EC615B2683F1D9AB32DC0314C6CCE6E9620C8E73B1DC85BED5205CDE5A44F40427865A62356CE44751C7278A3B236BC2D208C7B383129661810A6A2962496D058CA4875AD234C2DF951612E665984BBAE791C279EE835B105202D4751F1A330DC6B0BDCC38FDD6458B0CA7A9BDA026BD64E80868B87B58CCF2A37CA94CB06279EE77A6731E847487142561863B5F38C5AA4C0158AC28E95012C10A8B8E99EF7DB12C05009311A74791C6C8B355E4A861DD3CB6FA085884D7A7E8CD270F656CE29F9BF3B91B798032C16B00F8CD722A1CABFBB25C3002324C56B66DF87182504581A76297EE1181CF05A6D89698CC94021B16574264435F2CB137A7A667A4548C96F835CBBCF27805AE37448674AA998818CF26D15A63689777A9B98219AC3B9ECF84203826EAE294800F5A07FFA886CC86E7D095F42C471C121A69A1972A7906ABBD31003F6C8C0D07EF481B55FE185811084D9A472CCBCC586B6A9A6F24D269AB36126A3F0381B29532D027C2D5E21CC5B9C6EC8303E4B388A6B7216B3E581C0566558107C8B94C599F09C2ECC4B7A824FA3DB9A29722317D5BC5D43827F4BC6D3A91F65DCA56BC26DE9D40BF2F69263CB010A9A24A749C931631EC2D13EA4D5136AA8A97EE019AE1291EA34B0807886FFA323AD3B0F83F82E5D9A2D748945A3CA34B9535D0460A6F734BBEEB66A4E3C257BB079F5D80F6DEB0DBEC130FE4A182FDB16291403F37A191C381723965C3FD90D9F2B67C36CA3AC141030AB516A01453532AA06B73A91B5BA7D1A308E286FCED38F2858801022A453320A857B564179C55F0436B25CB191865DE69877B47041D9D0C2C9BC42CA513F207A72EA9A5CC48B573FB402BA8B5AE6D73F2E0B044B8CA67C1031577099B9975FAD7103C7F6BF80099BB51138D8A7AF7BB509B761A9C6407DD9826B7FF87879098248D779D6F26AA0215084F286AC77C50849AD19F29A32B07EF517000FF71799D6BE1D177508BB969D9479C6C037A5A18BF4302720E240DFA603B7F8745144906BB88522505B19336BEE5572188853A47B4F8ED8A040B251307299BE642E086317E1504784990F2149CB2D89B1A8542E4A19CFAFD57ADE9A234545142AFCB3E544B49DF75B0CC78F5AAB935752746EE7A7F7936777330A66C1063C50BECC4286A3DB4AA66CB602553849B5BAAF83965AC6BDB19A9E5DB8251DE0267EA3C0EEC342B51505469AA7FE936A5829463892645438A3A182859DA136E033B926695421A1891610816E136DBBE36ADC08CF00E4B44649410B2A11EF254144C27787E54CC5A533E8E54F11EA94F7E9C2009D25A6248321F04A53C31787C12ACA9CC78FCC06B161701852215BC6C29D1779F5C183152CACB583A90399746F75C5BB337F1B580B9029B112579884F792EA5A52187A109F547CDA89B7FBBA90C66065A33423DA4515D13BB5FFA074AADB0C55119065A51239511BB33288F994B121DA8913992B979A59BBD64036968621E76AE336096FD6125CDAC4F767A883E6448B078DC04B1F2B7AA49A1180C0F3BC65D2A93458291982652063419A9CB7F1042C38F483C4A90E17ACA78E9FE10B44687F9AA606CAE8888E4C21AB0F7B85EB3D3A2A3D2FE8ED883D1DE0\nsk = CE732E28B21F42F2BBD1B049E6B80264B218B581CBAB8C9186E325F7617895E6320FE5C697FC3B82546681B3CA5F4A52F1F7501B652F86D35CCB9756E869795C166362FAC89C7B5AD41C7C74C596E2A7458E419CD10C10C890C94FD3564AA25F1EC3A3282607D8B1864022CDCCEBB1B1E48961207E29264A9CA86C94B71D5382C9C6B8004C818F51A52006706285BB3281618A157C80C2C00905C33316516C17F04460124FD79A1C330417984220334C84D96A66FC8A5556814C58F7826EE86F17319DA3F504F0124C3F06CA50792C1E1800FEEA8A8E8805A54BCB90C52ECA144677327F5058CCA151617F443DABBA304B353F4A5CAABF0C179A772582711C033B3F3C1225F191B887D8294FD18914850DE6B194B91C250374963BDC7215B07CDAA8001372A21F0C3845979386C27949E0BBEDC0B004258866A01EC5CB82FC751BA2F4510E514A3FA09B6AEA7E5E45762076B81D781C2BA91DD6F40CF13C91E947A7D7ABC2A2AA91A1404D87462B42AA71EB15209A9B0D4990C2265B051163CD2BA8319576758237482F500F7E94B3FF099616225737A766C10B6AEB213B5B073EFF93C3AC91BBF2B93FF47C84D7CA2E794990E2DB4A7E9AB19CB50CD522427E6A935CE3976490B21792CCE5E4B971668C4793CA4954B477703730411DF1F5AD2557CAEF78C914D0C223D836C407936EC58825F3B2A1925A5164B097A94A13D8AD3A27BF1FFB0C08C72B92215CB1B67C7D2C4A7BC7A6A8A054D2A34DE69C78195BB149E4B4CEBAB78F41612DB19540385F2F74757C662C2DA3C7B03A34A9524E2AB90F5CC21FC0D2AD84BB996E6C73426770FFC1C9942CC22AA2934D97A66037A18760C51B0236CA1B1880A2286EE5241FFC220A4C6EC0E296090874B3CA751DD701086A15F419C67EB4514744047D7848980C036107586D36818E74AD98989C8C02AFAB4134EE0B545ED707876A613FFA10BE7C3F10B758B215827ADA9FA1C83B129C6BDC5B621D3A5DA7F396D6E29B184A38D8091B6A2C288EE2CAE833A68A3CB6B30BAC5AD7567C788D8C803A7B622FBD8A253B274B93593115B5B7A5282EAF93706C88C178BAB897B7198C23B844219852A60410E8AFA85C902EDCB9A5E87A31CA84AC6B89A75830566062BC159CB129277AF0645D5817C8822E384040F1621D66D41643897DF21C1013CB1B426A703F120F21C780C67BB011FB3E8CB746C0B14C9F847DC1235F72E6BDFDA1C55BD26E377395C4B17B764A41E0F7312782BF71820DD379BEFE58901A011FADAC1EFAE549E5933AA9F9C64CE2273C486B56251674D56212C0AD7637854C7B8447A135FB960FFC435AC7553DFE935CAA98BF32186817B5ADB42375E96C30D0A96DF39658EDE95912946813CB75CC32B395AA73A916514533857B4C3405FC32C2946CF4F4251B2091B6CBB00CE296459C45E558B5048B79CC4CB8AA01BD7E82320637A62E2038D5B3C0593B42D32A38BE8312AB022EBB496A5FC4A991A1BAEB660A23988FBA329A79DC7144D20B5246466F25AF4AD971014970EBE2B36316B86B3585F6B0753711A0BF3952C688B4CF6C8A24C0964CDC1F5C1C34B3C28359BA232840063AC30BDDA83F0611042FD8B7C2BB439E686B49D538CF32A05AB82372F7525DF40085B3413F078226B97C234B815EC615B2683F1D9AB32DC0314C6CCE6E9620C8E73B1DC85BED5205CDE5A44F40427865A62356CE44751C7278A3B236BC2D208C7B383129661810A6A2962496D058CA4875AD234C2DF951612E665984BBAE791C279EE835B105202D4751F1A330DC6B0BDCC38FDD6458B0CA7A9BDA026BD64E80868B87B58CCF2A37CA94CB06279EE77A6731E847487142561863B5F38C5AA4C0158AC28E95012C10A8B8E99EF7DB12C05009311A74791C6C8B355E4A861DD3CB6FA085884D7A7E8CD270F656CE29F9BF3B91B798032C16B00F8CD722A1CABFBB25C3002324C56B66DF87182504581A76297EE1181CF05A6D89698CC94021B16574264435F2CB137A7A667A4548C96F835CBBCF27805AE37448674AA998818CF26D15A63689", + "777A9B98219AC3B9ECF84203826EAE294800F5A07FFA886CC86E7D095F42C471C121A69A1972A7906ABBD31003F6C8C0D07EF481B55FE185811084D9A472CCBCC586B6A9A6F24D269AB36126A3F0381B29532D027C2D5E21CC5B9C6EC8303E4B388A6B7216B3E581C0566558107C8B94C599F09C2ECC4B7A824FA3DB9A29722317D5BC5D43827F4BC6D3A91F65DCA56BC26DE9D40BF2F69263CB010A9A24A749C931631EC2D13EA4D5136AA8A97EE019AE1291EA34B0807886FFA323AD3B0F83F82E5D9A2D748945A3CA34B9535D0460A6F734BBEEB66A4E3C257BB079F5D80F6DEB0DBEC130FE4A182FDB16291403F37A191C381723965C3FD90D9F2B67C36CA3AC141030AB516A01453532AA06B73A91B5BA7D1A308E286FCED38F2858801022A453320A857B564179C55F0436B25CB191865DE69877B47041D9D0C2C9BC42CA513F207A72EA9A5CC48B573FB402BA8B5AE6D73F2E0B044B8CA67C1031577099B9975FAD7103C7F6BF80099BB51138D8A7AF7BB509B761A9C6407DD9826B7FF87879098248D779D6F26AA0215084F286AC77C50849AD19F29A32B07EF517000FF71799D6BE1D177508BB969D9479C6C037A5A18BF4302720E240DFA603B7F8745144906BB88522505B19336BEE5572188853A47B4F8ED8A040B251307299BE642E086317E1504784990F2149CB2D89B1A8542E4A19CFAFD57ADE9A234545142AFCB3E544B49DF75B0CC78F5AAB935752746EE7A7F7936777330A66C1063C50BECC4286A3DB4AA66CB602553849B5BAAF83965AC6BDB19A9E5DB8251DE0267EA3C0EEC342B51505469AA7FE936A5829463892645438A3A182859DA136E033B926695421A1891610816E136DBBE36ADC08CF00E4B44649410B2A11EF254144C27787E54CC5A533E8E54F11EA94F7E9C2009D25A6248321F04A53C31787C12ACA9CC78FCC06B161701852215BC6C29D1779F5C183152CACB583A90399746F75C5BB337F1B580B9029B112579884F792EA5A52187A109F547CDA89B7FBBA90C66065A33423DA4515D13BB5FFA074AADB0C55119065A51239511BB33288F994B121DA8913992B979A59BBD64036968621E76AE336096FD6125CDAC4F767A883E6448B078DC04B1F2B7AA49A1180C0F3BC65D2A93458291982652063419A9CB7F1042C38F483C4A90E17ACA78E9FE10B44687F9AA606CAE8888E4C21AB0F7B85EB3D3A2A3D2FE8ED883D1DE0EE044DBDF6787FF038DBF9C133557169C62FC1CE2580739369AA87DF00B496485A3407F591791A5DB4578B5972093A95BEC3B8E70C1D542C9B5C9789729F8922\nct = AB24A548B90EF59F7595D625B44E8A9B3CB8EE09A1AC6213B709B1CC1833B6D3E3ED145524647D33C527F0E7052DF7FD94C2B1EBD99577600DDD3266100218ACE8C5AEFBBBB3C045C5440AED44856616C5A4456D28A304D3D00B51EA20ABFF1E0A1C671BADE1E8BE2E3BB9A41F1C73612803DB0FF713B5C717B9BB751F750C1FF6310DDC3B25A012F3902A6BEF8F2E7C3B0EFEB6C8B267E1BC9152D48F53591CBBB2010E5D40E778368B9E7E8ABBF52BCFD5B61E4B2E84E8CEDE9FE87CC14DF8890FBA78466246888DD36D71742050C8271261BED8199B5D4C7C341F5E34673E47E58F42AA3F9D28CCDB1DE32A7C6E6AE11C346DDC6D7A9B4E1384E85A466711B2F5A5FFCEB0D00C4F10C8B656A878CDAC8D1738B73E003DC44FAD15AA4E30819C98DE28883E02E501BECCCBA97019D18EBB0565CDE8784F0210A9E6199C55A60AE87559A6104662CB9631BFDFD6E3A7F9FE3D7D542C1D01520984455947052C0C9E8C985C0F247CE9FB8C0D8F2E5EBE09BC6D06D1A1EEB2C97CAD3F557CFD8723D2C3D036F1EC38CDBAD6006A6B0002DEFC9E0599D9950157324A3045DC616786ADE0A56E6378793938485C69411EB7AD38267C02E44DD902E8C242C139DCC336997DA91D1659C4582ED0021B4E14A4E77DEE7803B927B8C12383911461794718355C74F366968EE72289A8AEBCD3BF800F9E91C83F22F6D59D372134CE5154E29385CA973E9BBA04CB674F8C87D4DC29386144F577D6B177791CB28DE72CC33226B9003E42EB040C635C80305996A303F8AA82B6DA9BEA52FD11618F9D04B00D5A1540D836829FB363AD62F63ACF4EE550B09F665A62CBA6AFAA9509E5AB22C02ACC0470B144A110A1D497EE5D2A764CAD986F7F96F3BBB4156C7713784D5D7F343F9D4FBB9E7F75114E5C60EFA58DB8499CEB533B4B9E50522364BA540AA3071C80E5FD3139C64DB8279058BDAA72E1515E483609B537A5D524A766E2914F45875D08F7BE6CDBCC08C9357FF06F897FC3A17DB8341C8E2B1D63DE212E512A51D60129A1375FC9261FBF5D8CEC9252331D75F7A4D180219EA5A6BC18E8A612042639A8B33879F2F8073C23A5B8A983B131193B734B66547426541ADABE13990035BC87A780141972ABD4F98559A6D92B9A605D7AD4F00B8D96F3A4EEA619D9F45D4C2F834A00064CDF2C58B51A9ADB542CF8051B73455BE9881E5097CA9D6F81B0240012A4E55369A056DE74C277B5A0915417A5EBA7A572A9B81121B4057F9A50C94191A446844225860096BFFEDF8B7AEA605F193CD60CCD0A2697D8F8DEA9262A3C5D89E8E94E2721A359364FE1B08245EBD344040746665FA6EC5D2B9D113EEAB5CC42450B5330A232D928FE674D53166416E0E8179100E421341DDFAC2E0E5A80FE51A6C6E8F044DF8EB5596809774CCAC4C255710EFDFF2D4614CEB463BCCF6013A74E1F22760A68AD214A1F5B6952E1935DBCCE1811EE19C2CDF8FCD3D38F7B6C6533DD9DE19B67D917BAE686BD9A9A30FEF043FC8C9055AC8B6DCF\nss = 3EEA7528610DAE3539F5F81EFD9BEEDDA4D45EF0B9FF91D3D4F3561B4981D286\n\ncount = 54\nseed = A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7\ngenerateEntropy = 6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88\nencapEntropyPreHash = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241\npk = ECD4C65CEC93A9B26EFE3B667405482E3AA37D48AEEA67C1698008DA4B68683697DFD34FD72A6F39EC0AA0806EA5C59B4554182F6034B9C5B7CB438E21A14774D58AFAB0099E478A4BA8568E192C71DB7C208B7115D29BF649BFB3D23C2D70599682C549EA28DC16597A43AA6E65C77C432F554B067A64AD62AB71492A1AAD6045677C74E3E8773FB8665259ABD821BF07D2157C09199435BF41992628534DAAE814EE4AC64AD89FFA1547442B8CF6F54664C550DA5CAD0D828174805DA5D66F01E584789992BF0A4036D770B6C5B3E21B78F5DA2467DB42479B478F0570D48071F028110F555857E4ACB555B9C7D5B5D913B75D5B393BD4B9B2C12D34027AEDE4A22FD80ABE26A9C93C938C6B1348708D1BDA7FE6C55BF66981695487AB81362F50B7376C6A52CC39769B921F575E5D7A9666ABC2DD9459A5595E3AD631A0C638C3A2181B649704748141394053849B4F996F9B8A68567B73227B8C9E4588EE4A13B75379D2776A7510ABB21941C2B36357E8248686A5D973B946B82E40802290651A073636B367671C9C001AC91AD03B9D6E83721AE1247CC188FC05B0249571656A276EEA09B6D3376C208335618B1FC2748655CEEF805C39165D0CE9BFED062ADD0C0A50E43167C80E5301A076C9CDC1F13852A5987AA3CEF5E5864A706B3DE947D2AC8E8CEA0C3F83745BF3185BAC9FD0162510F70BD20129D7C5215026114C4B5EF044A8A29A3F01FA02A0A3CE928A65CE8CB566848110994E7CE20EA5C30304D6CCBC7477BB78B3EC527758B7828B836DBB2742AF6095A0BB882C2C9D8E162618029C1FB5AAF4B963FCC4A35AB78B0D9942FBDB53D4684CA85218DC27678719CA0D4A8CD8E9BCAEB944B7C0670AB171927C56C35034AD92BB3E6714D0F7C137C2B9A1FC5B72367C35C55D5FEB93D1274B88BC558158C5D478C34B68240AD193E95C0311AA501B3C1C44B20AB6CA2D2DE1C56B65618CA53F0E91550851BFBC289206D1406B27047FE610EC01A86E8BA94516AA926B99879836DBB27A7056C4D54BBD19A44096D1B3F3E9956CAC29E7AB95F175B9D9A0078DA633F10A6FEE899F400533F0F77102DA19FB02610003674828758E23B5EC724C6829B95B8A6750F1988F431E7537CA9D05701AC8AE2034688082C5C20A122C6349DB27AB958504FDB4C527B223B2420DB7246A4A69B58085A3C1E6997DB19FE17A2BC23BCD60B924CC393EBFCA864DA054BA38BB733B00FDF57AB147B922278FB132C5F5774BFE368DC2B66583790D30D282A248B7E9D43A562BA1892A985B75A7AFF961762A05FB35B9420905BB8C4DE00A3846E38CA7D71411E89F9E2C9489C597834C7A5315080130648F5347639184F315BFF2D580FFD0227C9185ADF9203ED50BAA43A9174A7AE9B5655F2245A15C30F877BB7DCB2EC184138792738113895A980DCA31BAF6B5261E10A1D98AB660C066BCB05AC25429775C3BD1550D4A823FC96442CB2770751C812CE67613E48BFBE66A0FDBA909317513220EBC3C55FA1364F318812199009AF24F9F70C36F81B22B20BE53208F0DC44DD3B6ABB7236E1FD37C53FB1EE8C86810863A86B0029A58955DC73EC8A436112B5C3A75CEEC356BBD91355E4C3941A07E45AD3ECB9AE67E7527F70F6E07A757BD112947074D5120A1F2A1\nsk = F76C7D8002B7CA65BFE6A59AA3645A8E51AFE5FB80145241134CC072A60AD4B72D80C2BCBE1630EEDA661CB62E01B0798203A1A287C4B8F725DD422BEEE6627C864149EBABD84280739193067A2348F2861DBB7F1A0914BA2BB3AC6C80D5CA1F483C8B86C1CF5A2C3BF8F6728555799381A1B1F3CD02E445CBE798AC0361E15335380051294667B9149F38D85A1839AE43D331BF14091C4ACCBB24C8E8105A9D1185BA880B7E13CD3563AA235B899E7509525280A37162C043B089D5A0BD48B225EBB2D0538F49C8AC3C3B0677D8093CF70B3404016B4686D653CE4715A85953171BB937F5A1916271AD53318E8155269DBA4D0A520D057963E70CC01E680FE8408D03D3275C95A2C528190924749BC32DC31B21B58C6F5E4B59C157CAB7653C0D146DEC9A3F94E241993B09BD62446F35AD7772279E116464FB316DB8449A3AB7525B3E89B12B54F14FB19057C39510B072894831A5747782D404487926AD756B1BF81CB416D94265DCACEA475FCDAA727D0B5F01B376250B123F717FBB0B1976B7704FE5AE5AC10CD17B87FA8BBD3D824D3B91B567B5C20243677D741AE2CB1C1D049A842B7F9DA9CECE8931851BB35776CAED97C27D395108E42661AA60CC181ABB2774C67773FB29B445F3554D386C87D489D895A43EF268AF0C81F6065E57E744F719120323B013D35801E26BAC2700968566512106F5161EE8528372D45A42B41022239FB0B3CD23C4251927B355719A1F2A0689A4ABC508660DBC282706B765CA4BC1887FD064CF8285B1155863E15B112BCBB1962255B362CE8FA4C51C97CFCEA7004DAA9F746766F2F5487C93B99EE9825CB78AB0A98BF6863A083758E9279245E495AD0A5B86724C1ADC3E67D756C1C8647FB4BA32B75A6DA3A05A870FC1E12CD279666CA046E064A74625530E742EFC72C1D5F959C9", + "D256389C4C63609FA11A8FB5E70E1E2256C8164D80C69FB8F4008A647AF7F3AD960265F55CB786E8726B65689A6A751FE045B7D45AECF50605D135A44793AD2C6BBA5A59D293528BD94D65F54BAE4798EBA5B26DE8B225728EB8836AD1F373F66A2134B8B429A8457B600C5A3274B0157F66F091EC88436D5667802A15749B4C9C499A36C58FC5A7CCC10A604ED00DE74BBF433502C02AB0ED949F5DA8B9EFB83C4A2395E49413A7030F4F95901E8AA2716A3EBB09AAF61C9384586021301DE0F8C085421460A10FDD176C68B4C115C91DAC04121924213855AC22E8C98E3643C3D7C3B6C6C4CA964308510525C5AA00C32AD9BA258BC44A9F521A2873BEDAF7C56BFC26A320C0FE95CFBE12C0038C1A65B62C18C37E61A2B9194C9EC1DB8B9FD036C7C3A620B5C661D8AB0B46A6CD3391E53218E40CBDB082C2207630C2715541B10E3C395BF2A5A15AE8B506880DDE937432ECB150F9B3C136881058A750024D9B247232B7289BD07462C051B7BA599C985C6EB08C7AC22135C99E85930113554C59AC06AE298D5935658F513644B01132B4C1AB84677E342A1F4A8A9D5C6A44659805CC8898E563823C8286D54A1CB4B8DB866A8F5C74F782784E4B6FBAD380C5131FCAE11D4EC89DF82490B4F1BABD4673D7417B9CF04513718F2CD0CFC29707145034ECD4C65CEC93A9B26EFE3B667405482E3AA37D48AEEA67C1698008DA4B68683697DFD34FD72A6F39EC0AA0806EA5C59B4554182F6034B9C5B7CB438E21A14774D58AFAB0099E478A4BA8568E192C71DB7C208B7115D29BF649BFB3D23C2D70599682C549EA28DC16597A43AA6E65C77C432F554B067A64AD62AB71492A1AAD6045677C74E3E8773FB8665259ABD821BF07D2157C09199435BF41992628534DAAE814EE4AC64AD89FFA1547442B8CF6F54664C550DA5CAD0D828174805DA5D66F01E584789992BF0A4036D770B6C5B3E21B78F5DA2467DB42479B478F0570D48071F028110F555857E4ACB555B9C7D5B5D913B75D5B393BD4B9B2C12D34027AEDE4A22FD80ABE26A9C93C938C6B1348708D1BDA7FE6C55BF66981695487AB81362F50B7376C6A52CC39769B921F575E5D7A9666ABC2DD9459A5595E3AD631A0C638C3A2181B649704748141394053849B4F996F9B8A68567B73227B8C9E4588EE4A13B75379D2776A7510ABB21941C2B36357E8248686A5D973B946B82E40802290651A073636B367671C9C001AC91AD03B9D6E83721AE1247CC188FC05B0249571656A276EEA09B6D3376C208335618B1FC2748655CEEF805C39165D0CE9BFED062ADD0C0A50E43167C80E5301A076C9CDC1F13852A5987AA3CEF5E5864A706B3DE947D2AC8E8CEA0C3F83745BF3185BAC9FD0162510F70BD20129D7C5215026114C4B5EF044A8A29A3F01FA02A0A3CE928A65CE8CB566848110994E7CE20EA5C30304D6CCBC7477BB78B3EC527758B7828B836DBB2742AF6095A0BB882C2C9D8E162618029C1FB5AAF4B963FCC4A35AB78B0D9942FBDB53D4684CA85218DC27678719CA0D4A8CD8E9BCAEB944B7C0670AB171927C56C35034AD92BB3E6714D0F7C137C2B9A1FC5B72367C35C55D5FEB93D1274B88BC558158C5D478C34B68240AD193E95C0311AA501B3C1C44B20AB6CA2D2DE1C56B65618CA53F0E91550851BFBC289206D1406B27047FE610EC01A86E8BA94516AA926B99879836DBB27A7056C4D54BBD19A44096D1B3F3E9956CAC29E7AB95F175B9D9A0078DA633F10A6FEE899F400533F0F77102DA19FB02610003674828758E23B5EC724C6829B95B8A6750F1988F431E7537CA9D05701AC8AE2034688082C5C20A122C6349DB27AB958504FDB4C527B223B2420DB7246A4A69B58085A3C1E6997DB19FE17A2BC23BCD60B924CC393EBFCA864DA054BA38BB733B00FDF57AB147B922278FB132C5F5774BFE368DC2B66583790D30D282A248B7E9D43A562BA1892A985B75A7AFF961762A05FB35B9420905BB8C4DE00A3846E38CA7D71411E89F9E2C9489C597834C7A5315080130648F5347639184F315BFF2D580FFD0227C9185ADF9203ED50BAA43A9174A7AE9B5655F2245A15C30F877BB7DCB2EC184138792738113895A980DCA31BAF6B5261E10A1D98AB660C066BCB05AC25429775C3BD1550D4A823FC96442CB2770751C812CE67613E48BFBE66A0FDBA909317513220EBC3C55FA1364F318812199009AF24F9F70C36F81B22B20BE53208F0DC44DD3B6ABB7236E1FD37C53FB1EE8C86810863A86B0029A58955DC73EC8A436112B5C3A75CEEC356BBD91355E4C3941A07E45AD3ECB9AE67E7527F70F6E07A757BD112947074D5120A1F2A1E965AC6995D525E324E8252D8E2C2DA909A29B24BACA8B68DAA5122CB539A474B9402BF02481CE4B27A52E87FEB92C4399C7F2988D40E942E7496AD15AD2AA88\nct = 9D503732B866FD6CC6482F203FE35AECECBDD76BA5AF3887AF66020597E9ED58EEE4577F0A07623C03124574A8F263775C83DF468839D2E5F17D5B21E811E0A80B0CBFEA3E370762AC0C47E741C234B5A24E803A60C532B92B658D5E46244F96224B989E6EC2BE14FD13A384EF64977D370B06040AD74D11EF41D126BB07CBBB5CB3CC1BE087F8FD7F61B8B8935F515207A26EBDB29DCAD93ED2159926093097F402EB6A2D4DCC96B7F354D3B46C514CAD7230D0A03AE48FF492CEA84B35F5086A2BAB86E37BE1080950674FACDAE004CE59858E2A2D9DF1D83A3E8719D057848A081BC262559DE7F0D30FD2193788CABA528CD3145465F3F1703D1955F87A896F114213752F389170D6B9E3B45BC4D8CC25A09D35D8C182766A97419302ACB59B18959F68CBE30572CD507D32280B9B3DD03E08F7F912DCCDF6465541FC1776B76E884EA1A1F0B6E7B44326F1C984972AB1FD82D1A095D3F8703F26D15A8FDE507E99100FC4204322D4DAAF774CA4CE9A470D560AFD097745AAE98402B1E8E5C0485620F2996E4369EA9B7D91D66A29AB0E8980AB477E6732F267EFAB52F24D1D19119B82FB1FFE9DBF3D77A0CC9CE84729CCDCD5B27D4321B23B1E9FC40F443AD753C0B876507BBA1DD7755914FD861E3006504D7E406BD8FE652E226D3B21CB7510F570CD1EB1BFE43555886E29AE1389C0791ADBC762EFFCA02553D7026A3820DC6C0DE0808FCED176BC010B0B91DEDE1A6770833AFCFE359E4228D04920870E20DD9892D0A5340C93C2EE86115244A43635DB46D28AE4982C3CB8705C250026C3A18DA5DC2DE6320DC4A4E40962FF78AA98B1C17F2BD49495663282E019982423DB6388C972B4540D7F4C26FC3037356011C090EB5AED0706336AABF252B879799BDC529CF75D748413BC2A499354D0CA2E47957E3F032C1C9B6F398C80468A03CBE6E1857C1EC3E6C046BCCEB9D8417FD3E1C7BCCA9A0ADDCACDA0BCA99966994F6234380B5E58163AF74255D6A9FF8397493DD2987633A4A6C5BA61B00FF125C06A1615F993F660EB8CE966551586BB30794CCDEC762C67843A68A84EE658E629AED04191C8BCE6DBD7A112FFBC6A483AF6D0A3F297340E6E9EBDE6D73F39F4DEB96FE0326A8D25CA7335938F502BA77EC126D5A2CA584C838B2166AA0DD926F645F7B4570AFBBC7345F4FFAC34588B54776A35F24474FF2AE8BE60D7A31A415FA32F194875A0D2792DF994E054378BF15D8502F8E2887DACBA3FBC3FD17C7657DE1D099F4FFA8250CCC9C6EFF5C517B90B7C7035017732AA964A4A2941557391836624F8AFE0D5482143B009A633092829612E6024254F1EF8BBB15B5A6B3644C9142B148C4C7337EFDED7A5246674E2739E5823C785A16EF4254B97F86EC3EBBC28B4A1161A66CDC07D3FF5A3FD1DE52F00AC6EE6258821854943FC73B357B27FD154EAD141B187F3B8A7AF61C80D3F324C341F92DCF9F4962C6EB1AE5B0F0711FCCB3E5AEB439E8A7C8F20A580AE50C1EFB1F27923ABCC8F2DF1DF\nss = C5E2F0C1EE4F13FA8FBF2D09A78B04A5E2069AAFA978598F96424ACBCF41AD44\n\ncount = 55\nseed = 467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91\ngenerateEntropy = 2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4\nencapEntropyPreHash = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175\npk = 8C5785417B65B2E4235CC67947D7B214627D326AC1ADEBCCC3A64017E004499A8887C4A649E443E74720F0B1BEDD52B1A8EB78B3AC2D5516B7A3233BE9448575209675F4A813120422684191D6771EF2B44D92B2CA3BCDD5F5AC20A63EFC237FF9D99BB4F5094AFC187EBBAD39B8B9CE75902190741640BABF653886162645A84262A24B1885C626403F23136707816ACF28950BF181742C98347022CD5941B7B69E21B5CFC2B4C6C5F301BD32A2E7882A1E1A9CD94743FC86AF0CD26B51B3512003CBE8628D299663DA40BAEF443677033DA8B8C21E0A0F12FB93F4D63809375FC877866394A1A5409E2F13B3E5011A2A5877732415281B7B19991E6EE0A470561B6BCB46D87B4086F18CA29C5FDCD622F4315DCFB11DB2C6CF136B7B0A870AE89669AD1011477899B8F679E5C9A8413959CA0CBFB3B54AD58C98B94760058C6F1F499435118D9143723DA05BA8F13E5CCA1813F91CE01092917BA1D798BA3481121026713BE1889B58375E5C4F9BB0BCC5FA808E2C00A36CA575C68B1D232778F71BF0927C5F2092D0629588826D02005DB9BC0DCE456E2B928EC9FB9C7A138E7B1065A2B660C287C3D062144CCA71E5C1294442073AD48AFC555767F1BEBAF550D520659496AF9237A22C27670A080F8A461778AA42C6CA9A954C28A658C73847A586FC3EF266562240ACB6978E026152B1149B8D426AEFE37BBD263A00DA05DF48375E53BACF9C4C11D4BBB055666AD008736B9C323A9974661215495E032AAEC611AF0E6A9244C2BFB6F3195D5121EDC3C0719C3FC1365C2BFC70D5C6140E6A383714A0931CCDFF946ADCF73993AA113C90AEF03374E251ACE73770A350428EC32A9DDB4AED8832526968412863966228644B9AF9842C2E967957F10D350A3499876F25D157BB2812501C8DC95365F83BC64B6340FA6CB4C2816B31824D028726DE0112AA9CCC9E0B6869099D310AA6E5B79609487E7A20A56BA75C45986F92F5A4D1672F3D99927A1193BA15BF5DF2586E823292593C49321BAC9044E4844A7A6BCB08309E2520B6ACF20E73BA5B05931E29BA43B2000A48C72A5DF05EF715CD8865CF16A835A83C271402071D1068A426839CA424CB666545664EA5E7461AF147B9D84583285EA1A05A02732031BB0BA40B14C828BB0E82807FC57882B31D9CF509BE7B712F56994721B55DA921EEE8AD45C8B4E99931C9B71B473A89A2D4821213A1ACFC453A41784D35B522E93C2D994D083674C71583782128476B04FEC71F17CCC65B9C83F52C207B08ADB10824A505B6DA8A78D4C599A5B09979D9491E1383EA155576730614FCBDEC1A8C801B94083A0FB55790B136BC5F37B752F3A6C636481DEBC5DA8892AC1B04AC7447953015E7251838ACBB6E24B508578B62D7450C46C76272806AC407112B73F7946D9654A45E943B406776E057C22E669B34A39D92F87928F8689CB8363B5B07B861BE5A750BEDB4A909605E6E26A489A5A4", + "D9FA7BE3976479F8ABAB955200C479E75983BE821E79682FFB18553B72CF0797B2D2117ADD5AC0ABC71CF0E4CA83C26D218295AEC75872BA3A8B3CA22A2AB83404A046355FD394BF35D66DF46A6124D18B9A4606305A5968C4CCDF6B77A5EF23C5D54C68389E610B30DE122C2B2CDCEA30B3C780612FB9992721E26273\nsk = AB150A2298917B1707AF1AC0941ACC5B6B259D1AAE8F878BB0A37089B845991B203EE4C8F1A58CF9D2CC0059ADE2DB131BDC5FE3049E17F350A805C6F30479BE91B12A36190A5332ECA4737DF5A32FD60CCE222B592060ADD75A62F88D5BF6426FB18A944195F1ECB1BABAC1DCF20C39339ED45AC8C3AB582382480851107683102FA1914E753731964FDFF686F0A354703858C15C99F30A19D9C281AE93004C718D1CA5452FE58183D806DD666792DA7A76B0927DC77793396E4508200EF5097E45095A33AF5683A4DD1A5F6878C1E6FA85771A990EA16F7A28034A897855769DB8E4A9A425860FEC7031D09E96B665F57662B2BB86E362C3F9A706E354C12423AC6CDC74973A0767D73E75F5739747433C3451F8E5B85E5311B6E009F79C00CC07BA26B74D512520496B1998A4445C19249729225044CFFD51679B495511223417B2BAC86CC242241F2B70966E9A7A03C3CC0AB526ABF857DC1A140AD85825757D2B5A59B97B7F8C5015DA02159D013C1F15491FF4CF64C564E50C389F6C85B7C060F98011A4518CD3B48C2DF68C67F3497F439C11F8504E577CF49ACFAE704A2B093238520292602CC2138762D87536F6285C001D6975A242654DDECB5663AC44228BBE5BD58D9B90426C66802B466B21DC8D7A23893A953033874D0A93626C00B6A4FA3FE9EB0DFEBA2F3E789AAD8103CA153FBD7218B95547DE700CA526AED4F159639C59A7699296486188C3CA111479DDAA747F99AC825C7593911D6261683CE92EE8AABB77F82AB14838DB54149194B12791C4991181C66BCF05C67E19F05DCB658D8DFAB09C180967311F4E2AA03D9B8218889F87C5A5680299A7459AFDD69DB27302D9761DAA20BE37900B971694D3B6AEA8C6B5D53A686BEAA478F2ABC17C1C461807597148719925590C1E482AA05BB73077C017C1010EA576BFB5A63031875A23B0A019D608D64A30D0DCB39D750099D1C7583C34AB1CB1DD99A115547E3E4CCDF2A872E821B2330A5F6B30918226B7FCFC9FB4F37D8103437DB12EE073A49D29A7359316F8D922F783797E49B8C2B6146F76C7F8A66838C86364A788D3C4AE67D02CA09391E8547EDFE86CA1D131C5B96CAF479D9562688D1238C6196526B17844B475149AC3A76865C94993E518941A63A2E4559E81A46C8A99AFD2A73B36C633DDC6B32B14723F04A83AF89A420A3D04810311A28880247236A3761236B068A9A4EDF55317E8841218441EB1137342977215992BA99C1EEA7DBEA33AA83382B909BF1EAA9030B4386F8BAAEA643E41531204BC0DF8243F81367F4D979BF0125B84EB5D5DF53318463102938A85214AD7355960300DB40719A2ACAB9297381A6708391C78A8D4029487C324291A7E4A0945A806E0F24368C7A2AF91B8BB155D04C557759228673B548B6A4FEB8944B7334BCCBAB144C84344457B8B794A3D3B4DFC2357BE9227F9C4CE8B98003452C1D8D19C7A8332403A41308086346129D3F929B847BAB1AA5D88935D816A708C6A5E41023BCD4252569CBC724A53DF1B88909267A932186C751339863C8DD49CBE200797186924C26EDB976DE613CC2C46BEB06B39F5C264716A76E67831E4198822D77386592C777A088C5785417B65B2E4235CC67947D7B214627D326AC1ADEBCCC3A64017E004499A8887C4A649E443E74720F0B1BEDD52B1A8EB78B3AC2D5516B7A3233BE9448575209675F4A813120422684191D6771EF2B44D92B2CA3BCDD5F5AC20A63EFC237FF9D99BB4F5094AFC187EBBAD39B8B9CE75902190741640BABF653886162645A84262A24B1885C626403F23136707816ACF28950BF181742C98347022CD5941B7B69E21B5CFC2B4C6C5F301BD32A2E7882A1E1A9CD94743FC86AF0CD26B51B3512003CBE8628D299663DA40BAEF443677033DA8B8C21E0A0F12FB93F4D63809375FC877866394A1A5409E2F13B3E5011A2A5877732415281B7B19991E6EE0A470561B6BCB46D87B4086F18CA29C5FDCD622F4315DCFB11DB2C6CF136B7B0A870AE89669AD1011477899B8F679E5C9A8413959CA0CBFB3B54AD58C98B94760058C6F1F499435118D9143723DA05BA8F13E5CCA1813F91CE01092917BA1D798BA3481121026713BE1889B58375E5C4F9BB0BCC5FA808E2C00A36CA575C68B1D232778F71BF0927C5F2092D0629588826D02005DB9BC0DCE456E2B928EC9FB9C7A138E7B1065A2B660C287C3D062144CCA71E5C1294442073AD48AFC555767F1BEBAF550D520659496AF9237A22C27670A080F8A461778AA42C6CA9A954C28A658C73847A586FC3EF266562240ACB6978E026152B1149B8D426AEFE37BBD263A00DA05DF48375E53BACF9C4C11D4BBB055666AD008736B9C323A9974661215495E032AAEC611AF0E6A9244C2BFB6F3195D5121EDC3C0719C3FC1365C2BFC70D5C6140E6A383714A0931CCDFF946ADCF73993AA113C90AEF03374E251ACE73770A350428EC32A9DDB4AED8832526968412863966228644B9AF9842C2E967957F10D350A3499876F25D157BB2812501C8DC95365F83BC64B6340FA6CB4C2816B31824D028726DE0112AA9CCC9E0B6869099D310AA6E5B79609487E7A20A56BA75C45986F92F5A4D1672F3D99927A1193BA15BF5DF2586E823292593C49321BAC9044E4844A7A6BCB08309E2520B6ACF20E73BA5B05931E29BA43B2000A48C72A5DF05EF715CD8865CF16A835A83C271402071D1068A426839CA424CB666545664EA5E7461AF147B9D84583285EA1A05A02732031BB0BA40B14C828BB0E82807FC57882B31D9CF509BE7B712F56994721B55DA921EEE8AD45C8B4E99931C9B71B473A89A2D4821213A1ACFC453A41784D35B522E93C2D994D083674C71583782128476B04FEC71F17CCC65B9C83F52C207B08ADB10824A505B6DA8A78D4C599A5B09979D9491E1383EA155576730614FCBDEC1A8C801B94083A0FB55790B136BC5F37B752F3A6C636481DEBC5DA8892AC1B04AC7447953015E7251838ACBB6E24B508578B62D7450C46C76272806AC407112B73F7946D9654A45E943B406776E057C22E669B34A39D92F87928F8689CB8363B5B07B861BE5A750BEDB4A909605E6E26A489A5A4D9FA7BE3976479F8ABAB955200C479E75983BE821E79682FFB18553B72CF0797B2D2117ADD5AC0ABC71CF0E4CA83C26D218295AEC75872BA3A8B3CA22A2AB83404A046355FD394BF35D66DF46A6124D18B9A4606305A5968C4CCDF6B77A5EF23C5D54C68389E610B30DE122C2B2CDCEA30B3C780612FB9992721E26273A3D8A85F38CFDA38C66AE39B2F9186EF7BC1E0C98E8976A6CBC6C4875D73D7FB24C3DA70FE850E80AA818301D60C70F3038153866DCD5D179E22DB59B8991BB4\nct = 05ED6A301313B34C67A40B05211E451869D148917D9CFEAA4144521DAFB1BC3CABE8FC527D998CDB6F1BA7A0609FA2144A3BD8DB8460612C8281586F4AEDA3F599CFFE70130A9C8BB5A91812B259167603B8282E96CA090EE6D83588980AE78ACD18324FACE44CBF68340002F1E0F6483DFCCFE092933D5A823F5ED4F06D38EE5747894CA0ED4A64438B1C6DB6DEA5D1A7DEED2A84F4622764FF3739924F3102912357F030CA7491D1A13F50B891294D3271D029E3402351D78479F253891D726B2C9AFB763E7A12BA3F150C54CEE377A91852B4C669A263D882D98896DDEDEEAEFE850159C3638408CA155BCC2D7D5579F156FCC2F7B77758AD4A5723AA45336054D810181E8BC9EAFB7ABD4349FA0F8A22B0E1418767E62EA6C84C2A7BC74E6E575DB8E6FB7EA79AB108C4985F3DC0424AF17B2BA1BA6C6AA2161D872DAA33B3C86D49CC6C0D5C8C07ED16FED4D2FD7F342B41D3F9B616766EC9CEFA0F1A2FC91CF84925243C344B02D6553B4F28D172ECA7A101B3A2EF6081A101DE8E95B1C32BC8B3327F24FF93C29DD66B9F508BA045339DE2C600469A73A65BD72CC348892AECFD3753F489566479AA7FF5390312081E24D9B64CBF8780D959DB66F9BFAA756EBD7CFAE55F991F81E586BDC74EF77A2FA3F3765905118F19443D3482EA18AC6BDA92A754CDC493E052D4482F57FB4ADDA00F9761F9DEED1B77FDE37FCBDFAD1CAE385BF05DE62880932DEAF957891FA11CD255E7C65619FD71B2641A085A5CD9FF4851FB57CCBDDCC10EDB41376032D6227ACF702B2E6265AC9AEE41A2C183EC16ABA9545E88988BB88EF7C0967E1164FA4F8B8943000CE8261420C53AF5A465F15BC6C76DFE8431439FA598D4EE11C3673EA9AB144893E4261454570702E6311392F79728C54DAB95D1329FD70D33E934FAF5FE220FCF9AACFC4D573798BB0D7DD218CEB8413629154745E6CED8A4A6EFEE1E93DCFB3F3BF3811513D5201F0B0A2C213E307767F989FBE19AAC74BAE70013B5D73905A709566356D4212B68349CFC4C7147F09CF0168AE636600BA31C87741AFE142D1CB03F56095DE4BB034991E54D863A9E56C6B9D1786D54A41C08BDBAE1596AADAD9118D3CC0B8121E25B0EB080A5E089EBCC32438A1DB1B72AD7D7B743A15118674F64992395316F426E365AE04DA9919E1A8FBD0959A2EA2A0938BFE7D2FBE844D89F36683E076F8E54E27AC5805128D0B58CDDC93793633FEDD427989AEF1463AF97643D628CC79DF9725C37F745839E85D9916D1C5337A16B47034FF2A36F3B022232BDC881577845CDC8A5621FC21AE5B5BF8EE0BB4E2ABDBBA1C348F2FD58313C9251B8E84FDEFE3915B8EA3CC13A5687AFFD790EBF25C7E761C90B1A0C7F6E9A3BBE04D6595B45D6FF3BA2D238D85ACF7206B0AE25B326E2191291510324A9FDBAED3BB5C770DB6F215DD693D4090BBF610F2208FDC7ADEC620D82F86CBB17DB7D31FB758A332D17E7FFAC763BFAC78B0F3C8A746BB60530A168FB5A06BC129F8F427BCC\nss = 0B642D9427CAAAB926DFC155993BCB41BFBFB91E6C6D1C4165D8750222CC3688\n\ncount = 56\nseed = 687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235\ngenerateEntropy = 63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93\nencapEntropyPreHash = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3\npk = 605471FEAA9E92B94016A9A05F585F3C52A993A91A6DB73C9AE6364DD2A07B6C2AFB449122E76A3B273D424B94343B3BD7E7B1E1366204820819C8BA8970218A22262CA649D8E3223167BE77D9A466C860AD7C320B227E873A0D68FAAA441C0907805996D64F7759BDEED65CCE25B367F02094714BE404CA9FE56F6AD99E7D38B5396281314898036493002CB516878DB66AB19E09478872C0F76ABBE0F754B443B13DD5AFE610C1ADFC52FB3C82488984DBCC4D9850A0EE4BBC07D0051208C87914A3FA5159C775AD91A552C2FA2AC573787FFA68F456012AF600AF60183F97CB3E2936EF683FD8E2B5742C6DE946B96F825CD0F4807640A532561C70600D4995BF8D2CA543DB1E", + "ACD68D28B207617C23CD9A57BBF75ABCB620D941913E6506AA0123F89C261CE9C39C605646904D22586643F4AD250870AFE94DC950913602CC1CDBB77BB9B4DF518D1A18AB0C5A25948302C0535908E70F84587EFF169114161C3E646740893FAAF6B37B42168FDBC494549776D528BFA2C2BAF6A00A7498F403347A646C9A58328C59274AE8CFF8B82787A29D67336DADD3404FB5509640C29C9456FCF82D4ABBCD9899AB108A1FEF872617C5CA780970182861C046A594D62757D33247B79E12873493634C16FA70983C9B593814E69BB160120B4129370519327AC2332063992AF4370D9871E7A27D13420A6FB16ED9B579D1CA1D36A2094EAC96B537109AD83F4DF1A1D2E184C309AB65D75A3E409C57578214EA4035657757AB92AA930A76D251A1B87BC6B58F9D900E38156D73A1961C43BE2E044314C89EA9601937C0A87D9C4B14CB9E79D83E722CC40B048BEC5CCD038304AC0A65BF93B9A787105EB31B5BE8845C5C57B9A9CAF6243F54438ED84159F5B1B8B246073B1715B0F635E8078991118DFEE2CE08887F9680BD4E672D3AA78DF8954554D398D1675D785B85DD28A1675944D7597968F22855999F148CCEABFABC2358C315076C6B4333A82520A8332543AA100034BB0A6776CD959BCB263074FC28956726D0D99B9D81A7DEC14F13AC5CEB5B9EAAECB28E282BB517CAC09809073C3D085718D1DBBD75EC83707CC768BC79A3B637D0ACB34F37C9C2B4C0EEF3233CF91C0BF5A6A9279F6AD136808A9A3515B02E303F4DA26F93264C5AB9010A9C8550B9076D6471C196675EDB08223672C1A229AD31C05EBC4FAB557F46B4BB37DC2B605A87B888A1F475516DB87B92451127436EDA7922BB45B8B8462122542DE969C31622CDD62676A8FAAC5663A8BC2191711383EF4C1CD7A183BB55CC3C83B566E5514F233D79A2963710C5E5225F7B09B0B6176F451A7F77570B1C17B7BA335511BC3C3FEB884E459ADD3A594DD35662419272499B4E9258DC9ACA946CA80911999D455D06407CF9C69E814478A9F5151780BD754A440BC69925155FFF0A675E0C322C69174C27CD804279EBD3260FEB62C0E24EB63C7A042996C25BC9342C589C340E99999F9C5054FF35C760A43974096C5FD23BB9E51E2483722A132B0277BB24010297C4BA2C58BB286C49ED20B7AAE98C5D9B0601F06EE53C1808E07FDA53114EFC6D36B28B906611BE3A29E68A8DA76457BE5419D70059F7C329AAD28692D45892F335D02D36153217D5DB379B621E416A54CE8071DFDA35F639A04B14\nsk = F80C63DD6CBDA93B6CEE719FBAD6BDBE1A03F18B3379306ACE5625FB38C5EDAC9C8C94525C85961E14A76082BBD760CCF9B5AC777088B0CC80E0304FBCFC697CFB13DCF1CF777325EB473D11A43DA4575B697A860445B02CF75E8B945FF9433A337C754E19453D4BBFD2F07C76E8B7A68B92ABC870B56202F7634B9B37902D39BCA04653FAD9A0E4F0BE548ABB97C7A1FA18C34CEBBAE3987F4B3C52A5006629159AC6875276053908B389D931BC7E2871751169B6D81C8D8B5F52854A3E644C5C504675D688BA030E9E78A79E7788522516FFDA2EC9946AA9791A634B6AB6D04456003ACF348BDCD859567A74A7B73556820F8DFC12E467AE2FD11025E430114A5A60D3B42BB43845721637A69596EB953AB7B3E3B28B3BD9923DBC5189A37E9FE7BD9B763FA905314C0A35387A8E8552BF7135698E15B8D99B0777A0A5AF1B7DAFC172AA6A4D69202F10351603771876C580A7D24479DB0D804B6513A09281F291F2706AB128905663AECB0BB31A41046771449D12C335051A2EB50CA81ACE90940A8A6A355B21A9C7505491EA3B48B5323CC567EAD909FBDB380FD504C851452BD34F0F65A39AC62D922A3C50A8566EDAB03358745D701332E4011022BFD4839AE7B6745C66ACA80ABAB8213369E299253B40A7922DF02AB70F9723BACCB1AD563AD20C5EB8A01AE564BE24F40CE91A0F06EC68C0604C74250909D317F8968947A12EA297A279821F1B5377B02653D66897AA526CF51553C268481F7174BD9495DA4B0305650358A637A5FC31C99BA7BA304C6811B555E4B1C2F80EB4223C54032D16238861FB650BCBA24B127026FBA51F5985476103FE1375B94007A06BC2AB048BCB4A78E6D3C748B141BE410992733630B8C917F89960273740A595071824A9D02908D52D334373E8A575D5D52E96E5AD0CC95BF2C761AE577B9EF6BEAD33103E5033E0765D748C409F8A44227B8F55838B38695C5E132F2CB9BFDD7CB8522906E9BC03DDA468A04012277417869277E2169C63112E6A8942A1C13AEE97300FF4CAABF862058B6E7CC16F34C79BA200853701A98D630936A8A595098C8B19820AC91F47451E011069AA688BFBF5AC4EE018C53639A1B0573C8A420C4619166B011E79BD0B843D97766810A48E55D5CE389B5DE4A739F77CCC5FB70D52B3CA5D01729935BF7E4BB984576F2ACB7466C8248F975BAD539B2260568DFA34CF2974D83699761C95405943A7A88374112F8AE79B4D244BF2D683F7CC7A533229BBD8B5E822C8B3449548634FF34BCAEFF25A41AA84A1FA1F52F486F89630A7730E4F81AD23C14D6906816A849810951727042ED0782EF26C31281C0AADE6C9334A88ACB917B781C4F16327196422C24541065B5E80F4374DA0853D478625A68F728A20C1C82CA4FCC4D62744FA658059141221A917D6121187D3B621179AA8F7B7CD0904E6E0787F9A5F65EAA78011B6B63290A55542C80A4BFAD64677467DD1B12785E6BFBC31C1F3D46DB55C0A035604EF658279DB3232C675BC0BC97717CA3EB71D4F44CAAF1B07BDDC90AE982886594F98C41AE7481562CB63D0B2539EEC589146735490A4A87B6EC5CC77BFC0810627AA3452CB061A1648EC7CBB4937605471FEAA9E92B94016A9A05F585F3C52A993A91A6DB73C9AE6364DD2A07B6C2AFB449122E76A3B273D424B94343B3BD7E7B1E1366204820819C8BA8970218A22262CA649D8E3223167BE77D9A466C860AD7C320B227E873A0D68FAAA441C0907805996D64F7759BDEED65CCE25B367F02094714BE404CA9FE56F6AD99E7D38B5396281314898036493002CB516878DB66AB19E09478872C0F76ABBE0F754B443B13DD5AFE610C1ADFC52FB3C82488984DBCC4D9850A0EE4BBC07D0051208C87914A3FA5159C775AD91A552C2FA2AC573787FFA68F456012AF600AF60183F97CB3E2936EF683FD8E2B5742C6DE946B96F825CD0F4807640A532561C70600D4995BF8D2CA543DB1EACD68D28B207617C23CD9A57BBF75ABCB620D941913E6506AA0123F89C261CE9C39C605646904D22586643F4AD250870AFE94DC950913602CC1CDBB77BB9B4DF518D1A18AB0C5A25948302C0535908E70F84587EFF169114161C3E646740893FAAF6B37B42168FDBC494549776D528BFA2C2BAF6A00A7498F403347A646C9A58328C59274AE8CFF8B82787A29D67336DADD3404FB5509640C29C9456FCF82D4ABBCD9899AB108A1FEF872617C5CA780970182861C046A594D62757D33247B79E12873493634C16FA70983C9B593814E69BB160120B4129370519327AC2332063992AF4370D9871E7A27D13420A6FB16ED9B579D1CA1D36A2094EAC96B537109AD83F4DF1A1D2E184C309AB65D75A3E409C57578214EA4035657757AB92AA930A76D251A1B87BC6B58F9D900E38156D73A1961C43BE2E044314C89EA9601937C0A87D9C4B14CB9E79D83E722CC40B048BEC5CCD038304AC0A65BF93B9A787105EB31B5BE8845C5C57B9A9CAF6243F54438ED84159F5B1B8B246073B1715B0F635E8078991118DFEE2CE08887F9680BD4E672D3AA78DF8954554D398D1675D785B85DD28A1675944D7597968F22855999F148CCEABFABC2358C315076C6B4333A82520A8332543AA100034BB0A6776CD959BCB263074FC28956726D0D99B9D81A7DEC14F13AC5CEB5B9EAAECB28E282BB517CAC09809073C3D085718D1DBBD75EC83707CC768BC79A3B637D0ACB34F37C9C2B4C0EEF3233CF91C0BF5A6A9279F6AD136808A9A3515B02E303F4DA26F93264C5AB9010A9C8550B9076D6471C196675EDB08223672C1A229AD31C05EBC4FAB557F46B4BB37DC2B605A87B888A1F475516DB87B92451127436EDA7922BB45B8B8462122542DE969C31622CDD62676A8FAAC5663A8BC2191711383EF4C1CD7A183BB55CC3C83B566E5514F233D79A2963710C5E5225F7B09B0B6176F451A7F77570B1C17B7BA335511BC3C3FEB884E459ADD3A594DD35662419272499B4E9258DC9ACA946CA80911999D455D06407CF9C69E814478A9F5151780BD754A440BC69925155FFF0A675E0C322C69174C27CD804279EBD3260FEB62C0E24EB63C7A042996C25BC9342C589C340E99999F9C5054FF35C760A43974096C5FD23BB9E51E2483722A132B0277BB24010297C4BA2C58BB286C49ED20B7AAE98C5D9B0601F06EE53C1808E07FDA53114EFC6D36B28B906611BE3A29E68A8DA76457BE5419D70059F7C329AAD28692D45892F335D02D36153217D5DB379B621E416A54CE8071DFDA35F639A04B14AA73B40DEDD61E6FDAAC86971965C03AB14AE69E8130426FDF830BD57D0974CE3AFDB8A246A56EE71465591831C371F2EB87467B0559DEDD776BA063EE6D2F93\nct = 909F5615AFD3C1E5BD517378A979CF9A4267592AE7A8A723314DCD337E5296E07C686EA98FB8FF29067C99D0C8214DF3E1A4A3CD694DD8F53F9B1ECEEFFC203A6BF9E7022ADD6374B08B0C009A0F2B57CB55221FD486E4787ECB8CDE273E980C25B831CE8504E9125B4C402F826EE5F4E2965FBA01771978EDACA1B9AE19E0E302CD019AFFA2FE3714B7C136FE5D3B6F9D7E6622493942323B33DE56202A94D4CF505DF02AF304CB7339460A2DA004D783024AEDE73BEEE0C388816B90B36449F84FB145D99FBED6D46A1B57369F2F1AF1B4887E5AD0B318B527E25F81B0A847188D0BCF722482B90B1E96B114CD0274C8D00401B0A39B29E4C6B07979199A547A27D9EC39DDC7B29FF2D7033CAF8463658113451FC604C0A01656A2968871E153D77D6A1C328EF92ABD4EEE745A3C58D518A0AF004F2C636E2F0BB636436B0517D6F8D6A4323727518B720F55D993E2C9E1653DB50A43F10C4A69FEE9B170C98DA672C1B21A9987E0A231AED4241114D605555955A4FFA66314853FE8E1E4306ADDDF09BFFF1F22EDD64448A2F59ADD8237A759C2B5112DC3AD69404C65C2CA5F97345B492F0100882C83CF33F15E6DC2459976FF8870507865F9616AF8F0AEEE21FC008C9EED3565100F7443A731A5D6392F0D5E88AFC84D6A3F3C3274187A39BEDEE638E5C56E9A1A17047303DB8920A77F17B322C9573FE0096CE446ED1457CEE4FB2BA448D9A9BD690D89C58E47816B08995A36ED6C1A965B4C78CC5D7E90D5EE1CF5FFFDD6874B6B2ABCE7EA3ADA69BEE4CCF3892E8DCC8538CAD74FCED9DC8AA13B976E891ACB8EDA3700BBA39091E4FCB25EBE17F011D392E54B98AB4743FB7DDCAF0840CA05E8691E1C6FF4F46B45663DE89F4BC9B4ABDA850563336C0B82FAD2815D879131F58C4C5850B98AB57EB36A4A3E540E80F7115186754F93719794FD73D7236059A4DBE8169C71F01DD7C4FA1E6E3B3E80E5551C29C428996169E863CA1EC09189138588FE85B759D75C6FAD53746F5B6A6CCD6C2A970D1860FCC12998A7E9CA3DE51050F3B9CEF4A303F80591683CA7FA17909099EB288BE4", + "6819EC8E93C54BAB05B67854D7A105AFA20E62DAD71C90924A7FE13C5B0FFCB47DE697B9CCF4F33ABEB151E63A02B1835AD4FB5D4D0D858CD9F0A857801A6AA316076A4ACBB4ADE6F55DEC9B9F77D1633CCB4B391A4F879336AF32C7B54D45DA9683BBD83AE8D8E1A87BAA2E98D1D5C8ACB8418A2BEF076B9C35C45B97B7E5EE24BEE56FEF50D7FE9F30449440EEA673D96F3DEF3FAD0009054C7F4B1F36FEE689BFE6907453F2D08830D7524E311ABA74DB389DF58EDFB4F3715C880779352388ED09E5378760C42105F023574CF146E6A88FD7CD42660DE906BC57DC7F49F6691378FB8575C637979D445E2E74D36961FE0BC675A84E638F8AC4CBB0B85F365B3A73EFA97A4BBBA437A6FFCFF21B50226741F19400751B5B47C1657A259B427FB44FEBE3442123FAEE30EB71EEEBDBDAA798FF7D4DF03B2E5F08B1F248\nss = 79462708F754BF842716F900E850C228B00996B0E3801B43F6A928BFD4AA9E50\n\ncount = 57\nseed = 4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3\ngenerateEntropy = 6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7\nencapEntropyPreHash = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b\npk = 5B668AE6721C79E07EE5D26233936D195B62B192058CFBCB0A5A73EA0154D78224EBE84B7B611CED7256D0726492A4B41D4A8D6B2CA73A3668F93A77294439B0D8CA9A725C5278C21D896CA5D706E5F03D71526CB175ADE2606E3C3A24D510B4D9816AA6846A77663A80F5AC0D364747307068DA942B15CD2E02A3EED2818F9056D697897B509BD5048B178240C841580BBB77A79423996072F39497869007B19442F401009BA1A039C18F191CCA42F9551713CD791C9FB847690CF6247BB752A17A9873E97BCC36B793B6AD827ACF418543054698D77693F9C38C84354CC81C7A3B6A43ACCCC32DA070FE29411F17A420521FC69C0D09A6425A20AFFC98681568B8CCEA88E54B8DD9F12AEF4B3C10F256EB1519671091984A1DBE972A901BB4B24246D7DB01B86665374BB6CB841B3CDB2593BA5C96E32C20936ECBC4ABFD24AF76158B36A2C752A9BBA8946B34C414EEDB355A3CCB87431221AA2E936B0BD7540E697142DA0817B1B51314FC71CF4017F50544474C572C70BD142C676B69AFBA4292F5F19E88163F2FFBA3B1685073C3BBCAC825B095B5D259228A459FA7E866E09735E4CAB8FA733D4DB6A98172846397883394059C635D23C09FBEE3CAB350B9976C6A8A900C8E1693C3704E779049CD1221CE767651BC23755A3A49C6BE0C314A8C501579F7A447070EFFE0314FA3687AB92090738434E55280A42F22A66EAB77A2932B07E6857A32E31A527A2A909865E053A32148B59CBAC224C12468E444916CA375DC204C600899F90BA7C854B3646F2AF3981797AFC4E261C7A93AABC40A93990DABC82564336D01B2447FD35E8E86A0CBF676CFE6C3D229B256E585D8373D26C3AD66161890325533818F845301D9311BC8035714A722ED9206967123E65410562A745FE28F90D50D772A9CDED6354132688DDB1AE6956EADD896CFAA71C44AA925FB3B2C6B7D5E47CBAE00A91040456F4023174C73DD8A4D50F9714AD1CFF718321677A6962587BA6CA82C341F02A7382BE9715B41994DB91E6D0B487207B9B660793E62470B806A7444B6FAAB38F48747484062FF443AE1DA9E7EF41F797398F0527406787E00E197AC3248EE4A0E5037CF6C754AB9A24D08936E9D3313B99AC18886CFA9972030F1A40E58B25939A21698C434391785A3A98F0445567A9DBC0B4284D49652BB1862BB76FCFC6ABE60831CAC9AEF6469464319411A30F7601B5358568B014E67A76EA42ACACD7C3FC2F983BCE1BC0667897B92590DC724B5284FECF7C36B3842C61C27AF1A2F2EC95899591E707272BEA384CB9C8C9409BB26D743FAF196D3B8B33119A379D5CBF6823D4176CA83BA4E2A426745F346A42861A7B5343AD3AC26EA8895F24A379C449156123ED91A4CA701BD789DA84BA0ED5C707D373634AB7A65680667191F806B6F62CACB4B40AFDD649CC9D1650C3A5E40C8346C91B27EC1B1A957C778EC9C968C670FC84645FC07881C54946B5AB0B6033F45AFCC6A61FBB99746F3991F5B827C22972939C5FF620BDC4B131EB393D108C56556719ABBB978452FF0A12A1D138C9065C304C8514658193232C832B05B0B21A10483C6FAAB378C6B1415B75B43796F314542B9D7C87C1CA5FC13A12E8459454D36096C3BA38E979A3D4C852032429BFE1E663E0C256C2E93\nsk = D809438C90AEA78B897A528534FB009D716DE8D513D32168A1537489E52255D00F49C424BF5B5DB0E15A3A9B9845ECCF287776F9700FF5BB7AB9F40FFEAB7F148A9633546846B672CDA9AB8A37C8F9711B76474E7975AB7E16675A8626F8648B605066A4FB4A5C255A0A39387B03BB7F618C9ED1B37E488D4B7175B593860F6C97D637A2D8761D3B933291B2CCFA6BACC4DCC4DDBCA804C7C55EDB9FC5ABB503036059DA4D2929447CAB1BB1CB746AB01293A2B2F2638BEB06030D476BCD2C335DD5226B7450F8B5B2B130332DC9210640C10DAA5FAAC16C1381C2A0C4AAE3174BE4FAA53CA9CBF29769084715D6F8C163A0185030B0C7C9621336A9875946FBB73BDA9774C07615711451F5594A44313878204C291AB7550AAF981409D4D7CBEE727BA689400DAB7382605F03873F38566421A354B59A3B48BC8F62A09519D932AF5800A9A0C6EFD5783BD93483A0AAAC7853C890C3BA18835D1A2E8F14BD0768CC7D0B951909825C988648F797F5711FBC654380E661BBC41CF89B088E1410F19669AEF65FD817564A4A4F40281B5E16A69BE2B503495A4B6B680A08A54FE0B80AE668041AA120C7A363E38AAF2156CEE293BFD4396DCC503646ACB74B9460142E4476807C058D72C9610E3CBB50A29ED7244419C2C258659B3A8A23E7E69A3047298378424B7A12DF3CCE34F1364732B292B105EEE6A487126815BC0013D66FB7099EFD4931E4301D570BCF2FACBA0B433B9A03147242C298052650416651DB690CE81C268381032B17C429A8E418B7E2BB63D30B570DA588CBC36DC3798C65F81EF05530B9043310E182E88BB3E58356DE408898738C9B3C457FACA42B9B81ED7C4118869D5153338EF4260006C6BE294B528C779BD6C8FFCB16E2AAB439D3032B8AC45216282346200CF1C812033A4F9667AF842481D807F92245BB322E04343971A656087CCA8CE9BD3117013AE816BA745888A4AD51A167A17482EE5B88B0BBA455A565B1D97BD3B9BEEAEAC0B4F2879A727028D4A1C61900D0770F15451A01964366D8A6AD1B5BC520392D43BCA270CCF9A72DF3D68B955C4BED0352B3F78151C4716512097BC92F2CF0A2560923D01358AB1B5F8B7BC687F5C110B04C6512372F119FB23BB852398A6F599F4D145A8AFABAF8AC8726ABAEE569C4579B494A01C67E232B93080D5DF1542DD59F21760A24747E98E26466280C04D1784D9B581B4CABCAC1C3DDE1CA8E00588E0732F76B99EC844032D99EF65C8A9EF4A661E78A47B0542B3129E850647862132C208CB9B3986EB5B510EA1854300EE966B0D3BC09922260FFC96B894A181A95A41F1BB3ACB2572475B3FE8933FE3902C965678B95512289CFBAC30A2B159B8F2B3535E40881D81C204CBA9080B9A7B23190965EB660754368955C0C7929E9447B92AC78E7867C1B4770596047FA820C03A11CAA3C2BA48120E29AD46C289920222C511C9E18343AB20067F926435C6D6B040955F9394601B805E38A751BC8A1853FC05857EAE658A8A7CAD729373E73253E7728FDCA89E347BBFC48A7BAFA48CB167111367F40C93BF71CCF208A891C383BA3B593F2663148D779ED82B23F4B6796209D51425E9168CB22224F39F0695B668AE6721C79E07EE5D26233936D195B62B192058CFBCB0A5A73EA0154D78224EBE84B7B611CED7256D0726492A4B41D4A8D6B2CA73A3668F93A77294439B0D8CA9A725C5278C21D896CA5D706E5F03D71526CB175ADE2606E3C3A24D510B4D9816AA6846A77663A80F5AC0D364747307068DA942B15CD2E02A3EED2818F9056D697897B509BD5048B178240C841580BBB77A79423996072F39497869007B19442F401009BA1A039C18F191CCA42F9551713CD791C9FB847690CF6247BB752A17A9873E97BCC36B793B6AD827ACF418543054698D77693F9C38C84354CC81C7A3B6A43ACCCC32DA070FE29411F17A420521FC69C0D09A6425A20AFFC98681568B8CCEA88E54B8DD9F12AEF4B3C10F256EB1519671091984A1DBE972A901BB4B24246D7DB01B86665374BB6CB841B3CDB2593BA5C96E32C20936ECBC4ABFD24AF76158B36A2C752A9BBA8946B34C414EEDB355A3CCB87431221AA2E936B0BD7540E697142DA0817B1B51314FC71CF4017F50544474C572C70BD142C676B69AFBA4292F5F19E88163F2FFBA3B1685073C3BBCAC825B095B5D259228A459FA7E866E09735E4CAB8FA733D4DB6A98172846397883394059C635D23C09FBEE3CAB350B9976C6A8A900C8E1693C3704E779049CD1221CE767651BC23755A3A49C6BE0C314A8C501579F7A447070EFFE0314FA3687AB92090738434E55280A42F22A66EAB77A2932B07E6857A32E31A527A2A909865E053A32148B59CBAC224C12468E444916CA375DC204C600899F90BA7C854B3646F2AF3981797AFC4E261C7A93AABC40A93990DABC82564336D01B2447FD35E8E86A0CBF676CFE6C3D229B256E585D8373D26C3AD66161890325533818F845301D9311BC8035714A722ED9206967123E65410562A745FE28F90D50D772A9CDED6354132688DDB1AE6956EADD896CFAA71C44AA925FB3B2C6B7D5E47CBAE00A91040456F4023174C73DD8A4D50F9714AD1CFF718321677A6962587BA6CA82C341F02A7382BE9715B41994DB91E6D0B487207B9B660793E62470B806A7444B6FAAB38F48747484062FF443AE1DA9E7EF41F797398F0527406787E00E197AC3248EE4A0E5037CF6C754AB9A24D08936E9D3313B99AC18886CFA9972030F1A40E58B25939A21698C434391785A3A98F0445567A9DBC0B4284D49652BB1862BB76FCFC6ABE60831CAC9AEF6469464319411A30F7601B5358568B014E67A76EA42ACACD7C3FC2F983BCE1BC0667897B92590DC724B5284FECF7C36B3842C61C27AF1A2F2EC95899591E707272BEA384CB9C8C9409BB26D743FAF196D3B8B33119A379D5CBF6823D4176CA83BA4E2A426745F346A42861A7B5343AD3AC26EA8895F24A379C449156123ED91A4CA701BD789DA84BA0ED5C707D373634AB7A65680667191F806B6F62CACB4B40AFDD649CC9D1650C3A5E40C8346C91B27EC1B1A957C778EC9C968C670FC84645FC07881C54946B5AB0B6033F45AFCC6A61FBB99746F3991F5B827C22972939C5FF620BDC4B131EB393D108C56556719ABBB978452FF0A12A1D138C9065C304C8514658193232C832B05B0B21A10483C6FAAB378C6B1415B75B43796F314542B9D7C87C1CA5FC13A12E8459454D36096C3BA38E979A3D4C852032429BFE1E663E0C256C2E93CF754F2EE43694865A09CA7BEB0DEDA9B1328FD0ABDF30CA5C338E27E8BE04B5230E05B7114FF0395CC6", + "634DB1EAE8258072D09C09F291E92D6620B177DC50D7\nct = 78E7B98228BFDF95F03288762317F3EB2AD2750F51D4078A9FD1F14F002AC59489B6EA1AD30D86EC7AD46296F8D0C69DB4AC9970137901A93F02377F7AF74746C5620A853BDBEB7D706C9B743A78F5AC0F80DD34EA8CC9737EC8DB9B1DA502F14BA2D578EA6836AD314DB2A07133D7C0F80E3A3BD196361CE8E8F24884DD9F602F894656FB68520BA493D064F93F48A9D4D219C8312B9476859A462CB15961F0B045CCEEB860CEF99D4496ABAB16A5FFFC21483E9FDAA826AA9B960F395E8AE4C433E69D10C2687BC17005BEFD809FFCC76070634BF58DC37CCB9806F530EF6ADA63CA422A35CA1349A74A5D0EBDE8036A0801F3F61E838242189D9CB1A8725BE3B93E07AC509CACE9A58426D9CC6D084BEEFF08D8FD3F1020ED2E0A3C0BB7E380049C76B4C8D18F8BA2309A813CF36F247006C247C6A418FE9F070703B80FBCD2AD45DDB3F9707C4F685736C680376D622F79644C2B4EAC7858B960C954C7F1772E708CEDA6812ADB59A6A9A277337C44D0A3156327FED348976D07B500EF61046D2B881B3882AB2358EF741EDD947D72A0EB26C19912DE1D2C77B6F523D277AB762585BDB095162ACA9FD027BBE2BCBB6C4C57EC0B01194363FE086048FCA61489AF4E9A06D8367B28EB465A9F8BF986C207B26BB9EDE3200D6F407DC957A0CE7866882E83CD89AF5702F38FBDC974EDAB62F24BF50C53037437260659EA579348950652F93162BF1A9BCDBB72E44D04B4B3C3975588922EAFF1569837704CC6BB60404E589BB0E1CDBB79E503D0F946186FD35B4E0A294E2CEFDE2C0DCB2B2383348F899176FA5B620B941C68805B52959D0571EC26B9DBDD75F0895561396B3ED20BAA07B7D20D0DEF905B805DBF334601BEB359B93E9D30C56D91AD58CD93193D7DB67DEDDEB02D05B64B23F765368524CDFD40F8F59DFD5CA7280A03E0DA103DB6976331514B965F1D71861A846A59CFF73865BFE35690AE34BA8978876C809BDBADE6726E4ABA2447DF9F0399A06844B1CCA43728EDD3FA348B34B7F15DE627550B1392DD3E0996EE3D8B7351D6A5601C796C4FA317641100ECC8EA2BC8827B6B88344FB5EB4AECC3F24B78FFDCD278DC5D5C7566031DA41BF4B4AF39D11F5355DF82FA68986FF0E84E931B520F600030495E6DDB4AC02F3DFEA6F182FB1332C5F6180D476501118D32A79217A9FDC3CA8DBF3B942158A0CD42C44A426A03101E444CC84DAED5CB8A17DA4E84F56F2C0B9A665E4C144994D982595A22D7E4F1F1E1937E8B0B4C70959621E0EE3F92FEA44FF164B6F7DDBA625C97152494834E604526B8CAF76F995B18F9AFB0BD263ADA10751F45DF9FF83FDF1A64ABF7874EE144E225E39EB4A22179622E7D45DF70BC61237D35BA64E11468C408BEBA085EFE12ADED232044F4BE8EBBC019512EAE687ADA59B8ED47ED82D2B593C46080A75D2B9DD5BD6A612C7C1AF0D76A231DF4D3BAD49F09EF01A38652DC84FF60F3E6F22B471113BDC51DD5C33B73CC65AC2C701F4CBDDBA9B361680FBBD0B4\nss = BF535EEBD3721E4D832FA4C11369808A154FAED4602220B4070B78900B008358\n\ncount = 58\nseed = BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE\ngenerateEntropy = 6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9\nencapEntropyPreHash = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f\npk = 98CCA518437873F144E7E261E8465B3720582CF7706D684F84E618E8834F35857D4A8BBC303134B5E235DD1B2387A81C663876C5530293F99571B97AE5A299DF0C012E9662947089C9F81687722FBDC30CE50689690B30932A8A3CE7BCF6A353BF988DD310A2C347BFE6B30999E69C455B9F472B9BCA0216C84265E5D9486F6A7F1F3125C16467AE41B9F85180497B255ADB06A406A13A221388E14C0DE8CF73B6A952C2B2501644831C3700B7C273B7A3180A7641621F33B41C0F9255EFEC1025FC46F658C64FC89352C54C264B97E5A91C2386CD3790605127740DA2076EAB4876E128F3746843205B8328CFCDC65FEB92C2D973BBBFC68FD7A46DB51641B7830E73589F41D413FB571C37685DFF142863078ACF00043395BFAB3589B0CB435981B84E54318AB46E398389B8E146CAB2A9666330EC4C90A652A0F036951519880A45BF5D000D4E40C6B6554CD222880D0B91B67153C43909EB2C0926354D436C2318C593F9FC214B548E17245C0C9B83174A6783508B97AC6A8D8A88ECD278E2E52C3C9138B1685DABBA2BB1425075B298CB9120E790AFDCB9792C88698CC156CA5A789474992F470B1D554514823E87BCAE52CCC872C951B0C24B4A2B0460F488EE7768D56B07DC79B3B4CC321E5878AC0A5C3146AAEB6CA123206B0C7B5AA6E0BEC5D0A903AC9415DA345AF199CAB86BA99234C9526E6E8812F6DA8001F31337B8498A8374AE527B6032A0CF3142D1D34181A5AFD6AA432A588AE1F644F5A100FA593F0ED2753F441AE5677484738FF694ABCEC58781B06D0213579F827FB4F97B3FC343A445BA3035AEE989685E7B20BE6103FD39AFABC334417379BD666181925ED369680B851A54C41B6546B9C04CA69742B2A814763674ABC9CBCB03E96F9466CBEAEC698CB5C9ACF814E90887F8D15BEE556B28F50B739185EB7A5A06E896ED0048BBD905E016436477A68EBBAB1E172928AC8FA9A8B0A0D999B135A753A29A47D0136865B0F382572B0697D0FCCADC8A77C1B591BD73B639E13F9C21B6F0969B0ABA3EA807303377AFE0F49421B68D0712823FC448FA9A468FA000D5964BCF9A9E7FC92DECE03BF6732A36935B25023B47FC94C15795DD983BB4531E935A19778305D0E8A75C2CC770EB46B6D5759DF503BAC33F0669C775729C59EB94D48223D763880E8B58473683CEE48E309380F7B442E6C83F0EB9BBB0B1AE805B1498471AC1149D578B454041AAA2F5CF13390F10A72DF3385C6A8A1F990BB946F4C888E585069B5849882788A1BE27DA0725276FF9DB130519050B74CFF69A68534222499CC61F5845A8FC0AC5629E0CDA20D3EA2F0046B78A2267FA0187F15721EC53083018772097892BE85C1BE99480247E6E30AAC8FA2C593C630B981E57515E0F7414CFA8B606D931280A950E567C93B319FD23CA1B682FC0B960DD309F80455CABBBC71979C59A025008462C0681465D748FF2A6AE24E86C79922E2845568CEB5063FCB81B78295B93A80B221AE7E14A9A9BB7182C1ACF347F2FA73784835F3375A29ED05E4BD120A119CD0FDA29F76A1EB873AA88D0CB3C661FF0D5652F2B4604E2BDB1497486687F17B8CE7A096A59E0922260AE99BB7412E306CC0B25940FFDDF25214EE4DD4E1AEB851878E2493C05E2BD5A30B5B99D369454\nsk = BA45541CE7B3DE134E6B17030710BCCE09BCDBA837F23566DBF1928C99CFFCB674CAB9C41B3151FAA3078177B9126C7973E25687452DA075965BAA804276859B092D9D4095B5E3A27943776DA65262511F62A3AA875B258C7929B502AD6CBA00E3B38011C943310BB5CB24791A71BC5A2796D6197192D9594936089D88BFE976058CA16C152193838A3D7306B312F8160DF15288F9063514A403ACB76BE298F5C92D65A90A0BCB28A4F438EA447A9C881808A18A2F5C3C1B876B3AE94ED28478FDDC1E98A64FD797A0931CC4A18777E5D481D9E92C0CF2B5F5A58635B368CBC8C25DC733550774C0861795939B74E83A23757C212927805663DE14A0FA00CF10F51850DBB4CDD7CAABD5C09B2818CC0A09A58169E3827969518E8FC7BC8325B45656861A848347A358EF1155E5D43F7910A738A132C8892977075C9A19C1EB6399F2E7BF1DBAB593A907BDA509EF5B0DE35A222FC951A0829A838591A0441294C35CA0B86BE6FC02E1EA1B7D4004E5BCBCAA2A280EF37067D72790BB5D59587E050272DDF8B117286FE80C1BBF078E6D259A9B53BD6FF1B43A86B24ADB27BBFA3546C179B8F295726AB768BC7FC8DC2A62715030D93581165F1E4A03D42374A31039D55741C9C49A1C807468CC826F0380B90C9C3F319CF1F73811D674B05C147BB2613BA56365EA04872B9244B236B0D480DD0B47B7797A23286269F97450E13791B205C8AA3310B72F3423B263D93CA320AE1FF04FE6E3BB703A6C4FC17DCFB6341AEB485576B53D1CAB71D9049DCC68CF86008BDB6152994E70152F96C8AE4A0819102BA5077B26086B2DC6B04B324A31AECCB372CC18976BB9DA42C8EBA89640149ACC544511546C5DD293C3173EF28CA92B85B86188BC6FC09E2725307A2C3802C6086F922CDDC62B5989C5A6846496D2BCBF7775A4B3737EE6C6B69CC3373C96E79675CBC781146C7A78824AAE4322E1A69DBF64336EFC3348E414ECAB04010B9F7399310253679B48AF3C23961BF345B35172C1D472F9A31274C730373A29154A581631A0916A21259A46EFA387B36CC9272B5284085709E46F07BABFCC835959D841B3647F51147A013987DD9556111435124101E5D42FF0848BFE2169A49485C094226EC6994CB50BA9F6476FB2A39522A08145B987593F2FE67A2B2CCB036C4E6540145758C6745A389955CE9744CB8030BD85A838A5904198B318A4D265EEA61C70E5A34156BA00A53F05C9BE7F1AC214F6A75DC8154EECCEC7CA6218B34B8E063231C450EA3A8B48F7C97D9C58FED709C350A28A34873CE76F0FC7A4237AAEA0804E2D3874D726AEC41C3AC8E02706DA459C01736B7A5E0936B3ABCCBEBF146350EA2A246C225BA897473817F28C8D6BBB55FE98A48DE682A91770EDB1BDB190A0EFD677A7FC29FC62690668924CB5887F4078179AADE85C0DC8E3529862B2760B187B7778A56C6B026769E339ACA5F8C948801FDDC4ACC3BCC7FF548DD9FC12CD7A394C24A7CBE18D3D22AE3B48BEB295905B217AF384393705107F33B02547822B0A2CB1B57B6FC637E071C0FDBA2F87F010D0C81C42DB454F5C7BE69AC0069C33330BC40532248FD0B90A28908F7471FBCC543FA94403818698CCA518437873F144E7E261E8465B3720582CF7706D684F84E618E8834F35857D4A8BBC303134B5E235DD1B2387A81C663876C5530293F99571B97AE5A299DF0C012E9662947089C9F81687722FBDC30CE50689690B30932A8A3CE7BCF6A353BF988DD310A2C347BFE6B30999E69C455B9F472B9BCA0216C84265E5D9486F6A7F1F3125C16467AE41B9F85180497B255ADB06A406A13A221388E14C0DE8CF73B6A952C2B2501644831C3700B7C273B7A3180A7641621F33B41C0F9255EFEC1025FC46F658C64FC89352C54C264B97E5A91C2386CD3790605127740DA2076EAB4876E128F3746843205B8328CFCDC65FEB92C2D973BBBFC68FD7A46DB51641B7830E73589F41D413FB571C37685DFF142863078ACF00043395BFAB3589B0CB435981B84E54318AB46E398389B8E146CAB2A9666330EC4C90A652A0F036951519880A45BF5D000D4E40C6B6554CD222880D0B91B67153C43909EB2C0926354D436C2318C593F9FC214B548E17245C0C9B83174A6783508B97AC6A8D8A88ECD278E2E52C3C9138B1685DABBA2BB1425075B298CB9120E790AFDCB9792C88698CC156CA5A789474992F470B1D55451482", + "3E87BCAE52CCC872C951B0C24B4A2B0460F488EE7768D56B07DC79B3B4CC321E5878AC0A5C3146AAEB6CA123206B0C7B5AA6E0BEC5D0A903AC9415DA345AF199CAB86BA99234C9526E6E8812F6DA8001F31337B8498A8374AE527B6032A0CF3142D1D34181A5AFD6AA432A588AE1F644F5A100FA593F0ED2753F441AE5677484738FF694ABCEC58781B06D0213579F827FB4F97B3FC343A445BA3035AEE989685E7B20BE6103FD39AFABC334417379BD666181925ED369680B851A54C41B6546B9C04CA69742B2A814763674ABC9CBCB03E96F9466CBEAEC698CB5C9ACF814E90887F8D15BEE556B28F50B739185EB7A5A06E896ED0048BBD905E016436477A68EBBAB1E172928AC8FA9A8B0A0D999B135A753A29A47D0136865B0F382572B0697D0FCCADC8A77C1B591BD73B639E13F9C21B6F0969B0ABA3EA807303377AFE0F49421B68D0712823FC448FA9A468FA000D5964BCF9A9E7FC92DECE03BF6732A36935B25023B47FC94C15795DD983BB4531E935A19778305D0E8A75C2CC770EB46B6D5759DF503BAC33F0669C775729C59EB94D48223D763880E8B58473683CEE48E309380F7B442E6C83F0EB9BBB0B1AE805B1498471AC1149D578B454041AAA2F5CF13390F10A72DF3385C6A8A1F990BB946F4C888E585069B5849882788A1BE27DA0725276FF9DB130519050B74CFF69A68534222499CC61F5845A8FC0AC5629E0CDA20D3EA2F0046B78A2267FA0187F15721EC53083018772097892BE85C1BE99480247E6E30AAC8FA2C593C630B981E57515E0F7414CFA8B606D931280A950E567C93B319FD23CA1B682FC0B960DD309F80455CABBBC71979C59A025008462C0681465D748FF2A6AE24E86C79922E2845568CEB5063FCB81B78295B93A80B221AE7E14A9A9BB7182C1ACF347F2FA73784835F3375A29ED05E4BD120A119CD0FDA29F76A1EB873AA88D0CB3C661FF0D5652F2B4604E2BDB1497486687F17B8CE7A096A59E0922260AE99BB7412E306CC0B25940FFDDF25214EE4DD4E1AEB851878E2493C05E2BD5A30B5B99D3694543A842153DEE9E035299D7E268C9492D71188F9FB24BDC2DD20C1DDCA647A15231100CED48ADD211A5C937B8D6079D8E271AF3F949EDC61F70E60453AEF20DEA9\nct = D793DFE0884A98CD776624207687CA1753B04CEF55D5DC4B9C5C94264ED0AA15B03251EE0FAF7C60C6221FC790F6E32C36DF947183BA0F3371CAE13EF196F36EE80ED758DF37AC6D9F45F14F351849FA5A18A4B9904B4E47B400B7BD80F7F458B92EE9A1577289A0CBABE7B8D7BDCC1D9BDB1605C96B509514DBF7FC9C84327F692526233F6723B04791CAEAF19B687052CB36CF248A254D4B1ABE5C2AA0D7EDE7174DCDDB2FDE19F5E91014967169A2DB30AA756D794012C290811361DDF4818C6BC1D74C7BB6E7830051C7B3EC51D66C3B1613C8144711CE70585F8FCA8001BCD9CA247DFE8449BFF0F7D52F384E496617449F003F145DDA4B53015AFECC31A72E3803AB561C35A72716D8CE3566A66AA0E921A1098CCF09712086C22C1CE4951791A46C78CAE8734B49C571710EE0EE2CF1138E1FAE19455C4C2B573EB8183DD9892E3D0DC150DAB5ACD32F8237B680865BDDCAAF0D5176FFB2382DCD75EDB2CC8398AE9789B7C49D44E4D4D18E705CAA7E3021229A52D45B12677D8D208EFE1DA2ED0F17C60BEF179C36A5B40B4D2B52A43CB251B65508148666111078D1D0E9ACD129526E48CC09148941E1B53E31392C6BFDB1406B7447589D2FC121E106830935B94AED6AEB66DF8FE843CCE9A0B91AC388E5C4C023E2522026CD518F48345411590AE042B607BD38E33FD15398C721DAA0A1023AEB4704B34125CCD18856EE95910B9044A83560D6EC6B2DD6BAC5BA82F47275B39996BE603485B9A8C8CFC71550F21F1F98458BB29FDB6D1700D47603F64734A910E143094DC3B0FD1B035C6CA03C57B009F4E3DAC49EFBD95D522A130CC70A98145F1B670463BD70917FA0AA10514584F180AD500FCE41902D7C5D1CA1E0BDBA213998FC5050419E2C5D1A149A9739DAD7F64B778D1CF6349939CA95BFD6797DDF9E6FDB14B770874A7F29A8C3CAEED48CD08BCD44931B194E648FEFA354CC754D2DBD1C829DC084EE2292BAEF7F221871E783E5ADC8DC8B2385D24CF98BE75C43628D990EE4B3CA96852F83A300E8FE2A84C1D894B0625036BE83CA29FE97C56DEA2E55C0261C04D5646F2E18CBE6AEEE22EAC0FC9E1A29DB9DF885A612DAB313ECBDE8CA25DA4D689B2D426B55B4FE36BF4512C730F55355CB5A7A980117FC1E63E50BE364D54C91B3001E89C36158D266F36D403CFB90F9CF73B86FB7435FEA20581ADFD570DA4C4C48FC689C1B67B4F457B7EC1C96E9C484FDDC58A27954402CF1D8E2C44BFD518F6B509B8178D4BA3C1B7BD2D1E8CF79C031AAAC3DBE6A9DBD211796A733ABAAF7F43684391368C98069CC42D069815EAC5046E13A8BD6DD39BC4ED2D3F292DA8EE67003947AB77903D72F97E9BDF0C3AF3D916534400545A3075570626F51C00F2BCB9DC611F0BFF8807BBA0A5E8D28CA8B988EAD01B7CD106D61F5D2E72FA46F8B9C80DE2D12778EF8A59444AF28F101B243660CE379C006B8AF92B26C8F1B6186390FEC31183227FC770ACA96B4583773FEE1ED5B1C96949D5DC66F2E76\nss = 3602269C7AF9FE28EA1019208DC3AB33BA09239D435C509903CA67345717E845\n\ncount = 59\nseed = A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179\ngenerateEntropy = a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba\nencapEntropyPreHash = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16\npk = 5E451E4C8C85A192C91DF27C17C0684BAA6375B17586F8BF1EF12B91615BD08A340C58629CD45F7A392F10A04916C249AF956B180BC418B8A95F66B2D0847E79D247B430812D682B1FB91879FAAB68F25602579BF0D895073780007B7D61940239913EB217CB16A63EA08B29656712A21A32C754953335C29E769DF17125D84C32B3250EC96067B975BF524091EE4013A8B67A19A331DAF38A396A765F7820A5E3606A734F5BA854D1E6B6E70CB9EE5B00D4D18D928921EBB8048E284A3A05A3DF9469EC53195180AC9F869A8E8866D69019E9730FD6E672DB024B6ECB4DC55729024033703B6FDB7BBEEECB2345782815843B7B7664627CAD52038F98DB605FD23D24080F809A276419C876AAC69977998B1400395829656C97BE262E053197EAD738D9BC995145CB2713B5E181223E04497C8114EC5A05384AA31CB84406F93365D7059DD88DB8F94A8F068FCD10BE96E32A0E926DCA518B3FE9286A755F29D83CF667407758141B2011FBB1764D3334F3A763A17CCE33C2816AC79EC4CC4C2D842B004C352ABA419BE87281779300708BB20143A43413A2A55C41E36444046A3C021A4D7818DD146D1DC335C66152866597AA69A44F39A2814A4830E002672731D93B7FE5F77587B782AA279CC9807D6126392F812E83662D49DB231DD3060F882D71D2A0A4C94ADB3784BA1785187423D7E8A82F379EECBA7E6F6A67B568698AC3A2C0B096B015100BF9ACFEE522A0192E49880439CC1FA9B30FB7A10544E1867B0C34DA981CE6E660CEBB8853545994454815178C60B04DCA7073531AA2A5095F7B8578CD9889F3428A7D1C72B8FB320F304FE5D23A4291666BF7AA1AFB5086532FC5AA347DC29279A4484261614F2774C81374AA453024B68D384B01565A36D98B751297477A61780E98135375AF8EF68359332826DA01BA6A73D5263ABC659454F57D83172D0E515D3754270AD84543D995C0534788A6786927B952698ABE693BFBB358E9E393151AAC991C97FEC8C55CC407BF027DF7E2A505DB531D47344552321107B651FA4E47D4B389C5825E02CA1F42839ADA4D7EEA2CCB24A74E34672BF1BC4F33C88C3603A3FA6CE87AA5CFE30125F99E81550C19B58A807BA8A586415C2924A6E467CA8BC85A5400F910457E8B9D74A11E2668C0F1A2A1D0389361D09900EC6671206139380EBF9390B2401555BA0A57FCA36D2742F569A573096A2B442C5992C3FB65271479291F097CB94589FA15BF73CB9319D93860EACF1CD1BF7D380E03587CE3FAAEB6360D79574803B5C49841B74918768EFB518CA46B26929F68639EB8FA9F73E61A8B69B004CB5D9D92CF0DAC9ABC03171444A03409714DC1514931182701C19E242AE73B465AF335C8D3588FF468346ABF76604B6EF887A7EB8E8B44005BB55AF328155AF7928C732E7805010CF0A50EC68E29ACCCEBC4A39E2ACA10084E2543746BE6C81D482F6F3C1FE0D31C6A69329D783A1BFA0B43E289A2F843C71196809CA4B82C75C59C7AA5D311350AA55E89735D9C34E6982D17C033937253D9778CA31A14A9894C5D801415056552C410484970CF2AC86B374644A37976EC4A123C0603CCC01C6C6E994514F13885BCEB2F8B0A57073E0F3130DACA54C038DC1085402160513337AF2B6DD900B04DC3BDFCC90BDB\nsk = 2D80A415A1B29961459E396204E5B5E65540A2A9AE9CD52D867A9E20952FC7565B66151653448353697B09723B17E3B1EF375A3E260A5869B579883FD1EB3A06DA5C11E493F4CC9D18381856FB2C36223E7214AD78A178B2153DCDE882451776478A4E06B392CE9B9D0310A5A134B42C37312A8932151571D85CB69D9333FF8685569568A0FC4568682EC2F5506F59742601C46DB34EFB9665B5815574518FF677BE1C0991B644B5931B112220C6EEE10C37C19316156BCBF354FB661635E42F6B26B07F9552D7B1A65D51C7EB6A132034BD755674DFC14345AA72ACBB85D4724B2BA14925421E570543AE904F9BC4016BC0389FB9922CB12A393A24DF219290DC506E501003C0AE8CBBC685A25A91147265207F93F190B12BAEBE7CC7EDEC476553762EA45E48694DDD172B6787B7D9719E89D77563C9C2CCB77CAEB23D7AA9181B82B6CBA09AEF1851235C7986194C8322280B4192B94262FC79CEACE4B894C86814D4929BD773E6A73FB0C7C36C67391A314555674CF415292055BB39319DCAA7B07230204C068028B3AE7A7223DF112032D60EDD1B6B52EA1ED13B86231A1EFB2969A691CEF0D219835A44E907BB0CD2CE6DA1442AF1460F2AB882959E0862BCCFCC6E3FC2BDB5EB673B218D6E9C5DC6461D8796945B614C81A68F9CF381D256BC1E63285141814077AF5F54C2C6B487DD29CDB1D2CE08F09122D09632AB823CB00D86A57F8933743F347C203894D0043F5692A6E12283ABFA1B98B39C6D638132EA4B94644E89A0ADC35816BE01A408F752B3215029D7661B554BD39ABAA906AF32F877CD4B28BCC217825AC897D06A4C233462FBA602A81321DB93279A19BF44131B86035DB3C4CA911F1FA30146F9BE0333650C3C24A5C85BF5E252413853DEFB040F8A16F4ABB9E18CB3D496A69B356D8206C106864C7464A7A7EC5E998B3FD5B18DF1D947E171272EC5AA1137CCBE50AE73ECC106250C0392A41A73A4861ACEA19257BE33CEF406B7EAC1796F605A709A4BC06BBE40867966E830E8AAC19AF626A4642A8447276F09CFBA6486564079E1AA38D7E179D9634E3398B743A1812F02818E979B4434A4516C2C77672600D5", + "B7D3BB6D7E3253189C3694120DBE2519C62C80558AC1D522855682962DF611FEBC9F33FA27A0787501A42802863B5CDCC6AA81B964CC2C9B8081B63750A6358DB5566A0D3229D2989E98199855A2448F54688ED2487B816F5CD651206350FBBB5CDD995A9DB37B089CAA57AB0DEDDC9392EA1C0F99031A42C350CAB7B6F54C1E4ACDD0E28D7975A188502FEF055FEB5889BF87929B6006562626335B05EDFC544F10CBD927AB3C4C9E806700349B9A0099801D5948CFF3BF0977A9691A25AC880D593A36D1E5436EAB078BD9A6BF25BC3D6B5BDFA02AAB06AB5842C440E40D430AAD9311015A8767417B233FA8CFC64914533031AB39B845A3C50CE00BA0F1A586053768EA48293044F3A831B456320600404761C7E826A0B111AE37DB49B31BB3E9389BD3E354F08879906996DF2036AC49B9C773AF5FEC5375519AE7B8C61CE475AC544D13A5B421B8A686251B6D1C64F8A353406248B0430C8A3A308B600D0C9506D6509AAC9A460935645E451E4C8C85A192C91DF27C17C0684BAA6375B17586F8BF1EF12B91615BD08A340C58629CD45F7A392F10A04916C249AF956B180BC418B8A95F66B2D0847E79D247B430812D682B1FB91879FAAB68F25602579BF0D895073780007B7D61940239913EB217CB16A63EA08B29656712A21A32C754953335C29E769DF17125D84C32B3250EC96067B975BF524091EE4013A8B67A19A331DAF38A396A765F7820A5E3606A734F5BA854D1E6B6E70CB9EE5B00D4D18D928921EBB8048E284A3A05A3DF9469EC53195180AC9F869A8E8866D69019E9730FD6E672DB024B6ECB4DC55729024033703B6FDB7BBEEECB2345782815843B7B7664627CAD52038F98DB605FD23D24080F809A276419C876AAC69977998B1400395829656C97BE262E053197EAD738D9BC995145CB2713B5E181223E04497C8114EC5A05384AA31CB84406F93365D7059DD88DB8F94A8F068FCD10BE96E32A0E926DCA518B3FE9286A755F29D83CF667407758141B2011FBB1764D3334F3A763A17CCE33C2816AC79EC4CC4C2D842B004C352ABA419BE87281779300708BB20143A43413A2A55C41E36444046A3C021A4D7818DD146D1DC335C66152866597AA69A44F39A2814A4830E002672731D93B7FE5F77587B782AA279CC9807D6126392F812E83662D49DB231DD3060F882D71D2A0A4C94ADB3784BA1785187423D7E8A82F379EECBA7E6F6A67B568698AC3A2C0B096B015100BF9ACFEE522A0192E49880439CC1FA9B30FB7A10544E1867B0C34DA981CE6E660CEBB8853545994454815178C60B04DCA7073531AA2A5095F7B8578CD9889F3428A7D1C72B8FB320F304FE5D23A4291666BF7AA1AFB5086532FC5AA347DC29279A4484261614F2774C81374AA453024B68D384B01565A36D98B751297477A61780E98135375AF8EF68359332826DA01BA6A73D5263ABC659454F57D83172D0E515D3754270AD84543D995C0534788A6786927B952698ABE693BFBB358E9E393151AAC991C97FEC8C55CC407BF027DF7E2A505DB531D47344552321107B651FA4E47D4B389C5825E02CA1F42839ADA4D7EEA2CCB24A74E34672BF1BC4F33C88C3603A3FA6CE87AA5CFE30125F99E81550C19B58A807BA8A586415C2924A6E467CA8BC85A5400F910457E8B9D74A11E2668C0F1A2A1D0389361D09900EC6671206139380EBF9390B2401555BA0A57FCA36D2742F569A573096A2B442C5992C3FB65271479291F097CB94589FA15BF73CB9319D93860EACF1CD1BF7D380E03587CE3FAAEB6360D79574803B5C49841B74918768EFB518CA46B26929F68639EB8FA9F73E61A8B69B004CB5D9D92CF0DAC9ABC03171444A03409714DC1514931182701C19E242AE73B465AF335C8D3588FF468346ABF76604B6EF887A7EB8E8B44005BB55AF328155AF7928C732E7805010CF0A50EC68E29ACCCEBC4A39E2ACA10084E2543746BE6C81D482F6F3C1FE0D31C6A69329D783A1BFA0B43E289A2F843C71196809CA4B82C75C59C7AA5D311350AA55E89735D9C34E6982D17C033937253D9778CA31A14A9894C5D801415056552C410484970CF2AC86B374644A37976EC4A123C0603CCC01C6C6E994514F13885BCEB2F8B0A57073E0F3130DACA54C038DC1085402160513337AF2B6DD900B04DC3BDFCC90BDBDA43CAE3C4DA51D69A57EB87094A03CD3A9C3E6B4ED864CC691A60F0509CC6467A3CC8AA3239D4C52CE4C95AFDEFF6EFBFACAC10D294EDC0E7CF4535059BFDBA\nct = 2EF58C14C9258E8E8D59AEC0096B1645D2FC8A2E12F8BDF9813CD87A32835FDA60F096E647CA601C29C41D3331ED6AFF01978D01A0E7D9774211BBA0CBACB6226379A79C8B6575993589B5D73205F92A21A7B30B175CD228B5A449554A99E0C6E6547BE25AC510B9D1E2EAA8E7AF3A6F6F4D43B4887BCD7C5BC9C4C8A1AF737575802AFABAD38B7CA3EDCA440EE9F62F36F5566809572D5712BB03A1936A09E55365905763A631D6FA6D3C441B8B0C90FE04D2CBE0FBEB2ABBA2288EE38AA58E22453A7109F1E0999B3E9E4EBCB39A5763BCDE0290FA7213D9B357359E06DE0F6033433E78585AFE7CAB779A088A9DECF5619BB8C35DD51AACE7A5C3567162017853595D889D57AC96FA8BEDFF46CC035B15C51A72FD865923CB60F8A4562F9C30009EEC7BAD7A9E0C4188EA89A7BA3F719CA1E5243F94A95C2E3B74336D5BE81AB156528B104007F4CBEE6F88346537865CD9CBC40980462890FB2C994119A74A3D65078E24DED0F91718800B72B66629B4E8B534566EE45227A30EC724925066766C4D450AEB655D91B5426B8F2562DB6120BD8EBDF0F96758DEC90DCA1EAEB3479242E65F097EBC602F0AE36B4DD0FF2F7FC067A33B281582E51F93A5948ADFCDBFFF34A51BF8B3826EA030056CCEF16C9288CA0073EC8C50985EECBC97FEADA2C3139F33AF954C03ECDB4A01B468EA4EAE5FF407F27B6F26C1AE5FABFCD592E31C47F8E4567E3D985FE6D93FD7B0255C8D4E00497F93AE1DBF56F55037F2F5D58012757484E9785CC7052778D3198392CB3A7A1CA0E17A9DE34206FEB0BEBC7E454C90DC6351D3C7B8CBA681B8CA70993B19D47A8D12DDBA0105BA12441592FDF4205656A36BB261A42181BE2CB3C967A54C1BD20DEAF6B4882BE7DB475DEF1EEE3F2083A72B77F1C8766DF31C578B48EA5955752E836017213818DD12B0BA8DF7767C5CC432983AB3D82199DFAB7BD98346DF7BDE7D795B96F61417B768F188D3777EE7A17E6D957BC69BA16E1F345D44E4E18E5189705DF89C4BDC10DB1A6CD1429B10596779FF942A703349FFCF6D1144F105A0BA48E04D4A26AF9C9DFFDE23B8BC66B69AF9B7771DBA70A77ECE86564E266B330937921D695145DF0402C8C81B6F2789ADBE07CFAC8ACECDB8D6F8AA0B053FEEFAA1CF4503AB6C3AE6013B93EAFB5AE3C58EA090F1F26E8A96F5BAC73E53FF9FBA367DE06F0B98CBCE936C4C5DFCF19DA140DBF528C431A99787F0698DAE81AC2DF8F5BD837CE013618CB342F8234AC64A5B40A55FD1443F477215A0E8CEFF7A4C0646B0797CE22C495EFCCBD0BF9D6F46B5E2A4065F5E7B0E6196BE5BB6872D1424A1ECED35892FDC4BA8361C21197E5DCBCBB26D34C39E156B2B60EB9105B4172DE9FB8D5950D92E25B4EAC39272D3010792A39943F00C41804D2CC3713E7E321A044F726132689853F954E727FE0B822E5BE6BB0CBD39F6642379C273C0CF30B5DBA4933EF09E9A8C069089C57C6CEE8FEEB1F51692FA5FDFFB0F6AEC6E827E0245E72777B91BCF\nss = 5E039D591CFB128E51D0804E0993084FC92B0BCA9C0F2D84E24F5FEA5EFB3B8B\n\ncount = 60\nseed = 99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E\ngenerateEntropy = 47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787\nencapEntropyPreHash = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1\npk = A20C8DA5745F754B89A990746EF771CF07A6D8109998936B282757F344A1B00B851EAAC27A9A7FBF480D44262868542128461598B5597B10CD3A2A26E3F941A9A4719AB2033FA1181ED08E3247BDD396A834E43F5700522CB307FF4B150BBA9D8B6AAB47361A7947B7A04B8D923202AB1A3D6644BE06BC6C1E0735D5D92821C5B8E9B9A83C343D0C456B181B6FA566B0E83602428B6CD33405A95ABB623A73299C5B4550A7D6C31D6EF81473489BBE457E744B5D1E39AB74D8A051951ABD01A6CFF3942A102A33080327437635C1C17966834340C26654A3F38616E5EACB0E489141B14E9D1B15B7FB30927715273547999B93EA2A1CA2189F5645CC4889943F3CCD95496B71F392F78A82AA1A21D66382C37154323C0616804F50125D6B0698E5DCA3E2D5658CE153BBF57E4B1908C92587B8C863FF4872E9E1963AE6C971C6AC3932BC974B9F15E5743EC069ED203C3624A022F9A7420BA951425A432B46C5E8BB666091D6F223E357CE96C55BF067B3C3F51ABE70ABD85A73A42233800853031313AE9971D280B3AED18489E75CDC16CBB3EBC95A8C97A768AAA6C0BB0DA7943037BF2B4A523E33ABF669C262941F326B11EC6BC8EF51B0666268D6D433B5190BB6996F65925A7EB0761EAB6906178BE9A923D1C61C0B7683CEA681648C44608217D6DC86441A8F423A9D1C288B32EBCD049C15EC151E256A322EE79E2C689A23A53B8D473F4C643AEDC646401761A7B75F7BD4145E837B756003BAB223FF1A74FEACC2E449B5DD9B5777D62FF0E20E4B395821474AB428AA2EA219BFA169B95039616598DAE0B9282C69CE329B534BC7AEA58E17467B1348B1AB2A031324BF835C985371B0F53877DCA53570199B23BC4D70A9425A32B54749082E794E10012E9B458205E106DA807C03AC3202A4350050815487626BD018706C69A6AB02FCB92621114A16CACFBEA02AEC424F82FB874800C61CC23BC6618ED75674A70A6C43C4068E2A7C9723A054967E4DAB09F337695BBB01053A7C5DBC764A0856D2B75DD4A94A9898AF8B95A62B487EC7FA9F00AB75325C9AB8248F1DB65FD7661DFB0B8EECDC2A4134103380988758379D0A73B0F348B00B4B13B115E74674AAAC2BA8C2A7FF440340B622B5C0BCE05CB601259913C488FEE540D7C058A28A0C28B856EA800D26A6A26F8BCDE7D78298314CEA6056B00A845321A245949A8C7C98D9F8821F1264C658A8061A3014249B7E522D586A54AD7A12AD805544247D74058BC9AC0F603A44AC5199BFFB69C1570C4076B345064EC00C5AE0D6A2308947593A84DDB6133BA40577B7B245C20B5D04C5D08281CA0AA10DA2A358386D2A4C048C89A2402C9150A7419C0A1AA17562FE786F00486DC82A9809DAB08F7B16D9432981087B6741269424598EAA99082525D5DB0DEAF1B96F55B41EE209F57ACEB895BABC38828B712724204744834303C496B7171FC458534F46892627AE54800FE6F11D06B6AF2B6B9259144F769B1F16C0586C9CAF01F8491251907FD213AA6C0BCE5B08F060124FB99822D964C502AC49C16CE9FB17EB0C91AF559947C056AF77CA687C4F675C89BE35AAE91584CF82202734379B56784FC5CE56E3852D89B052367D9A5D375D06EC7863E051CB44929F17A4656A2CB2C58D8D4578", + "97A1AA0D\nsk = CA481DB6775F3D276A56CA0E60CA79BE147E63B6898F4B814C69A06F55111C9824CBC1C109A01A7BAA259DA651A1A51D60BB358432550BC1AA1CF3656E0667D726C69A39AE564BB99162C824634B8B8A706D82175BD9657EC09A308B51A3B429822667A5135FE4350A8B3CA10E8B03B6DA0BBD616CEEC0A08476909C6182EF0314B284CC3F43C337307FACF7B617348779D7493AE0A25D415124BC5D9134182169238CEA1A46A3001A8165713A3E5C16AE03A477207B99C2CC674FCBB14CA439FCC3032E4C2F1E92841D73859C76CFBE245193816D87C12BB3F12763174997760D6887A429A37F78C32CC1AC8FACC587AA235821C254A2341B7C6BCF8B52C908836B67D39D63458AFA9530FC2748DE4A698AF346F8B5405DC7B43B05953554021AF73C585B6EF248C07ED23116BAA18C845571823D25CBAE0AF57D4F6AB2473B5919CBABDD7B4CCCC1BE89150CFC585953389172590EDD61C3885446B500495247AED57A9FB1140CEB6B29F7F9A9F524106D8CADA3432C12468F9BFB9A50B920CDE85654C25249350F6760293DDAA28C771963497C4C5230C05862A4391330F54CADC3B0C92B9798F5BDF8B21016725AC8F565466464C2033872684608111248FCCF94C61337EB6B1A9017E342C29EB2B148936119797FDB2757BEF51A9A2601A00C6F0547B1831B1CA1118CD2E1CDD601A0B491C588CB5ED88AC36AE183848B9F87264CC5B020B2E965E5B89FF74C58CD2B338177BF1350AFDA9A74516A5845381E5FE132B4089506E8CDE6346FCC760759592345927C5C6A97045B0AD3973E806778759B35988953C80B3E7574B7CAA225C744372EE3042E07CCE978A3F964395D40176AAB7905A4BBA98250F594C5A96BAC41851E09F897DF0376A89516040C1F8FCCB93D44AB474C56913826C9E2171EF67510B53EB31153FC028B3625AA7A353BBE79CC76D393E209115DD00B5D6C98F80101705544604351CDB87715618343BC3FA227C1E9FA1EA3989390B02C59EC9174E5165239427592A2D973774CA62DBD9410164BCFD95834C11621F7DA54DC55C44C594785FB0016448F2CC39A05E01D8581658A2410CAA630347C3F0F6C86F344816BD13B3A04313A730F2DE9BB50659B642353F6463D2E2A1A78B722287616CDC266B01098B3544632152DB3B23938D67C63E51949496E13182326D5B7D70B81D90CC6C5D84D4E5907833A7A76D3850AC4993A696C4B210DCF352A32B4C83DC9114305308129BB4FF73A91D733303BCA92FC0083D95D32CA54557A6FF3C42C2BAB46FF913E1D39BA3F6092E30AB47F9985C7C439448C92B245259D388E291C04DE427F378011CA983B21B2BA8BEA9D6EB36001AC4FA5061EE1670066F9252524848973782774CFA795A2285A2669515D4FDA7093BC54439753FB6B4E6B781EEFF574155B2438E074B332417D751EAB1BA1475436E8FC1B670C3928A3553D2BCFD1A59C46EA2542884F91F98A38D42ECC026EBCF91258ACC99A50AE1EDC88B90C98B74C3961B70759F39B3C20175FA80386376CDE2B66DFF213151B800921AB6932B45B720932A540C79CCA0EACA0A9D5BC841C3ACF3C08096C0446326114F05CB09745EBB986DDB76913FAA6A20C8DA5745F754B89A990746EF771CF07A6D8109998936B282757F344A1B00B851EAAC27A9A7FBF480D44262868542128461598B5597B10CD3A2A26E3F941A9A4719AB2033FA1181ED08E3247BDD396A834E43F5700522CB307FF4B150BBA9D8B6AAB47361A7947B7A04B8D923202AB1A3D6644BE06BC6C1E0735D5D92821C5B8E9B9A83C343D0C456B181B6FA566B0E83602428B6CD33405A95ABB623A73299C5B4550A7D6C31D6EF81473489BBE457E744B5D1E39AB74D8A051951ABD01A6CFF3942A102A33080327437635C1C17966834340C26654A3F38616E5EACB0E489141B14E9D1B15B7FB30927715273547999B93EA2A1CA2189F5645CC4889943F3CCD95496B71F392F78A82AA1A21D66382C37154323C0616804F50125D6B0698E5DCA3E2D5658CE153BBF57E4B1908C92587B8C863FF4872E9E1963AE6C971C6AC3932BC974B9F15E5743EC069ED203C3624A022F9A7420BA951425A432B46C5E8BB666091D6F223E357CE96C55BF067B3C3F51ABE70ABD85A73A42233800853031313AE9971D280B3AED18489E75CDC16CBB3EBC95A8C97A768AAA6C0BB0DA7943037BF2B4A523E33ABF669C262941F326B11EC6BC8EF51B0666268D6D433B5190BB6996F65925A7EB0761EAB6906178BE9A923D1C61C0B7683CEA681648C44608217D6DC86441A8F423A9D1C288B32EBCD049C15EC151E256A322EE79E2C689A23A53B8D473F4C643AEDC646401761A7B75F7BD4145E837B756003BAB223FF1A74FEACC2E449B5DD9B5777D62FF0E20E4B395821474AB428AA2EA219BFA169B95039616598DAE0B9282C69CE329B534BC7AEA58E17467B1348B1AB2A031324BF835C985371B0F53877DCA53570199B23BC4D70A9425A32B54749082E794E10012E9B458205E106DA807C03AC3202A4350050815487626BD018706C69A6AB02FCB92621114A16CACFBEA02AEC424F82FB874800C61CC23BC6618ED75674A70A6C43C4068E2A7C9723A054967E4DAB09F337695BBB01053A7C5DBC764A0856D2B75DD4A94A9898AF8B95A62B487EC7FA9F00AB75325C9AB8248F1DB65FD7661DFB0B8EECDC2A4134103380988758379D0A73B0F348B00B4B13B115E74674AAAC2BA8C2A7FF440340B622B5C0BCE05CB601259913C488FEE540D7C058A28A0C28B856EA800D26A6A26F8BCDE7D78298314CEA6056B00A845321A245949A8C7C98D9F8821F1264C658A8061A3014249B7E522D586A54AD7A12AD805544247D74058BC9AC0F603A44AC5199BFFB69C1570C4076B345064EC00C5AE0D6A2308947593A84DDB6133BA40577B7B245C20B5D04C5D08281CA0AA10DA2A358386D2A4C048C89A2402C9150A7419C0A1AA17562FE786F00486DC82A9809DAB08F7B16D9432981087B6741269424598EAA99082525D5DB0DEAF1B96F55B41EE209F57ACEB895BABC38828B712724204744834303C496B7171FC458534F46892627AE54800FE6F11D06B6AF2B6B9259144F769B1F16C0586C9CAF01F8491251907FD213AA6C0BCE5B08F060124FB99822D964C502AC49C16CE9FB17EB0C91AF559947C056AF77CA687C4F675C89BE35AAE91584CF82202734379B56784FC5CE56E3852D89B052367D9A5D375D06EC7863E051CB44929F17A4656A2CB2C58D8D457897A1AA0D6533C524A32345EEFDADC74A3C6AD7E981832797FAF1068955B79F118DFF93588F1481D7CAB000E33FA07DE8DC9627A85E76FABB4428A3376E66300CF12A0787\nct = CC18BE84B498262137E39C8C5540DE67A3474E2F9E94953081CAED1A428F3DC8FF3CF27DFFAB8278AC4402A1FCD4C285FC13F251BFBD2E7D5F1E79030BAD0D12F4BA296F374546A5C03A8D270FFC8093E276C62E887CF91BC7B17F2C37065982DBA258B0F8ABF6FB391D5A077A0167E16D046DF535A703412D4C9AE46467AB0DE3B2AC5B80BD5E1875E727DBD633E742DEE2A2166303F7998878A0F96A364ED5B92F9BB74505D8F8694613062353EAF64C50AA7098BD142C431352BCCE1DC9D874505A60EC6318B71158ECC0A6A9C225C19C52D8DDDF1C7B3984A3D90896E89D443398BDF1FBC2569280F22353A9307288B0D99D31FBFA3E391BF4B530165870133645310D41BBB4132A51F8A9F4B62D950CDC33C4C0FC231BCF79D90DBD78D8BEB891EEDBCA40FEF6136C488D474217A77EFA163EDAFB5A23A7D424233923F1E7A4DFF5EC8AD07FFEF39E6ED8F5733A7CA4A484B926FE4268728FF7CE3323E67B3891175677DBADEED1EE2612B58791A6E93D3A9B9662015916359E775BF6357F2ED5A71DBF6783873443BAE37E4DE66B14DA166A4410B2C3D1B0CCF2C26E7A5FC9252B7D7077C32B53BF40D745DB6D32D4C9D7ACB4BD1192ACC55F3BED993871547C361C986AB1B356296E17E34F69F41EE8C60CB97999591484DEB6C6D9EC55ADCBED8D21A6BF236BBBF1981372E6CAC0F688945BCCA2EBD6F76B39C705550B38A10BA9B3F8BFA789E5A80310AF1EF038472E960BD7C2FF20B94E347DD985A702A9D63FDF2CD869BD83D132DBC29E2495B29A8DF54CF7551A68541816CBEA53F3FBB7F32FCA6F9971A7E65CD9147BB81BA13B82DCF914254D7AF5BBB3452346653020870C33AFCA72F5DEC04EAC5B834F29FFE71A9B449306F04FC847421EAB8F42AA045F70A2748D56F69A1AFA39F9B24D04D57D7FF7257262F7E4833A50E617B8AC649414A74278225DAB5AB45B1AF3B65E5C4C8BE12E7CA0F2A74F881E7ABBA0B6402A315EB4FF7CE84C6C0F60309612B53C2AD943A5FC485F8766D493363533B13FFE17B9F8C279213E8F942E35858B3D19627394E5C71B74BD84593976BCC50390557942A4DBD0C4D413AA6B5B4492B957E61EA18C61FBB2C719FB1F79890F91B65BBD173C55B29F01853BAAFC6680629682FD16CF8413488AFCB4CC3C70CAA02B02466901ED472836C4384E8B7C0019436553D4D10FBE261CE1CD1B82494F047947C14F11643EFC41699A6DB1E7803382C51BA88783CE64E3952049897E03D181B4E17AB6AFD40A96AB682A97573CCB1E1B1F09D19547BC746A12F7DEB1447CEB4CD54F6F5E2305CA3F10EC3B4EDBC2B2BA34DE88EEC1218EB1276E1C29CDBD9615C3751B278077A05FE2A35863748207D62ABC17435C2DB742BE8FDEDD9EADF5C71258C906E68EEAE12D438A10F409CD9CBDC3CFE72D116B7C3F1D288DFD9A01899B0FAD6AB18FB34687204620282844DDAD79C457BAD5E03C6D6E6AEEBC7AEBEA18B60D34C106EB66A6B07209D2FBBC99506B0475241E2E6C722D\nss = EAE95E643381DF7A1CA1954EB0D529DB88A8001B8C1ED98A4B055936BBC6C038\n\ncount = 61\nseed = C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993\ngenerateEntropy = aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78\nencapEntropyPreHash = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb\npk = DB55C6CEC7B63C0721AAD84D2B6551FA941167C78A0C105ED9E5300A24BB2C8B2265251A38EC2B9D05A0635B2849A81A2A7C6F2660504D5602FD2763046820CA168D70B76E35B9641CE46A44F2A394F496DC32353C1A84302381E8D74CE4294A4A260A5B0704797567AE831D7C4410593CB7B9AB74D2042C84805C3AEA6EBD193A927C8189082333B3A5E96857E3970BE7DACA4C884D7BB0B3B9C250CB4135D0B8C90AE320DCB3C423E8A6DE79AD594240AE7AA036E320AD8807CCB7A1BC80C704C9532960864A9528347636B4123337DB7E2DE37823C6AE084418FDD05FF7E904211924FE5A370537762DFA012A2153AF96A46987776D245FDCB9434D66AA10524A3CA74E494C9DE919C8E23C3FF77C58CBD1CBAF5B8A69803A32E23959B2A7D9F808689906A0985AEFF5A8464A2AF64BA053A3C18D89B2CAE3814CD712484288ABF7655063C403F635D7A2AFB9D804E2E89677131BBBF7009C981548036726D25F05F004D605A24B7C2BCCC4294F065C013C8ECB242D25611B5C82BCABEB9E57", + "8758F2F3AD3F087BB6813DB1F3990C867A2E679F47F074FD012E87B3B6F51CB1707B9287D99FDBF43C8E58940109C376789E16C4A30B6BC34C870364192C555B81AF58962AE771DF477FF421A9B46C6E64BACD1A8A6D00DA4D9507212C910ED2C62D199C7E330A11982C514F27AAC092A5216B13AD54BEEBAA4049065A68D8CE9B1C969EA01599A71D633197BC33C2F6F958F72CCF14C7C09D973770F170F1F7BB9E458A00936D8677717F4A17655BC7A7EC56119779F7AA391D2356AE3A97D7CA04971CC2515154E148568C176A659A8DECBB2C5C449CCD914D3CB7431CB3A0A400A8C7B59B1CC770C5BB5B64E0932C61783C9979D6CBAC042216A0CC5800EA160C8C8556E0721D610FCE13992396C382E93BAD1514D780CEE046525C443FAE063C5882A01E5A73658A30864B1D6344A6CC46729BAB7810C46F5B480D309A263E30461769A55A2965BA6BA0B44054F211B98C6C2355150ACAB81881E5AC1E561A4BC4B39F9902D1027E56155F5D71B7CA67415185319BA769F88345611CA2C20B233DCACA9DDBA42EDB204576BD028A79BFCA57C9DBB0A54B933C970DE35032B9B51D00C9922ABB5106897CB896065FCA846AA486D9C27F5B616E99EA0ADA711729B75D86669645B9A223959B3C1C2F3AB6536D74295473C4C055AEF8C2CD2D321E9E73CBB872698B3A60667BC768014332083139D08C321157CFF1481F259ED56A7A3FF1717BB64FC951297C709A4AE3C05FE3910D6507AC947F944B970070570FDC9843A8A5BA564141F80F1654766F93048BE6297A1CB76C105A7BA3ADA06A42ED1AB3C17542201712F11824766C07BF14685AB0A9F69A15AD6574E59709D2411B37B509DE3B7FE5E8B0AC65922DF23E680C33141418F9551660467ACCC0C794A67CC530A5B130B4CF1C28747601D26983764ACBDDD30E42EB96125956A5870142574419977209A12E09AB3C5E8A22C1C5252527C90987A816B8830A757EC44B12E2E2BCBF19097D02B19AE47CC7BC99189370A1AACEF36415DED82FA7A63BE809B515F79F06612DABCA5768201C59E2C92EBA6D13B72C31648EE1D504EC3E89C8D796E77FA9A772499AEC973B63E864CE36A29DE99ECEC9695D12112C\nsk = 90D7129B79C095B3063F53058A4BAA74C262A99C822894254A050409215FE67773C26C7A6DCC739D8406A6055B388204604C7B065C0CDCCC16FA880858A36D6200C6CEC473BF81B245E09C6E5A55A8D8314334C23DC14FD6A9C011A2CA93753AFA8609320B1D01FB9A2A4263DDEAB8D5A00C40346B8F84AFC7B945F521321103A5219B533F52BEE42256EDD1B9A526013A00CE07D44EBFD66C0BB67775D1ACDE4AADB7C98731931E54F5C458264894971DF5D0CCD93817BB77A2E7D29CE47ABA205C0971F34096280CC725A3C22A4EE24A9938CC2FCD9A670272A463C852EFC04388CA8CE86A8E9F63273AA208610C2274709C55922AD371C197741AF0526218E84C3BCB61355AB94D5C94DCBB4BC08986AC075E01134B4029C8C1D78F829796C1CAB0EA2075BC25B797D82A8E0385EF1094D0A2B1731624308487991A7164D8A507F2390F354B4FA3A225D5A46463145EBB57B98724F1D3CABF11AD4FDC00BFA267D8F3107CEB7DA37C060AA23E247C28AD0069D30681E37807117AB841F23548CAA02212AFBC1BC54297202FA549DEF55DDEB5BA4D10ACE2650511366EBE9C1D61FA9D5574C86C0714AA523CDF946E1FD259148A7E2AB5C21884314E3B8082BC210B5209CCB6B95EAA2EF62203A0B707BF9C5DB1A155169B07D41C0EDB9709744CAAA36622F189773AD7A59DC142317454D9C81D55D1C637876F104B6836A6842B87174290125505461EEA77D63A8DAD03C7941B69D7F66E434922E13A8182FCC35E51C9CE81978E35818504CB32E4A6DFC777227A5484409A38B2A1E2243110E84D024B1FE0E0BB36D4AAC0622152599FEFA177B294BECE391D47553983E420DE5462C72AB588B2934680A399AC40EF35A5E8819458E0A7BED1AFBB29A446ECBCD4E45A50176EE201526E314CDE085AFDA30226039CEB41A14D87256BF566DB30AC77ACB80B29B1F9D602E919707C96863304372A353771E1CE994241A12369FBF42BCB4315592724CD5085A589B1B4CA46DC49CD65A1247178151E455741C8B5D7C9CAFCB75BF27A5B4ED05B22E932B1E3BFB0C93248400E5485486E0C39FD5CCEC680C78E6137BE96823DECA37C6306D31C9142FC03EC540AC0120EBBE9BD5237583E1972D0C4676708AD35B559FB89BD872428A3E0504350451DD65F58BCB292C0BA437394DAE55E6DF13A8F41827939016A081935D1788C4807A53A011B89528FB60F386632E725B163E83E105324C3914F26F389DAC199A926A25A02624D9A530BF0AFAFA4C5FFE6A5EF9422E422019FF337D1BC2FE16A07D9A046D183137D477DDA378E17A95FC7E02ECDDC0D551724A4F36EE7648C9AA771BD15AE29B7259ABB63D0983917156EDE6557BE445735EC539B2199F9816C562842627CC83BCAA659075F5179ABDD1A7056D27F7DD96A6813A940A9321CFB1946E95C16836EF028106BC26A3EE450D8E569EEB23B70722BCBF828821648B1668E6E47869AFB16C0E4B827C4CEC3C4C9948A6C7F874968DC80160A811CD06D58A885D033210341A6F7907F53A82C98468F6BDB7CC7A60107973DB0E70F9A387673234D6665019676215EE4597C65A13A2636CEE74266F373A4E48BB1DB019BF44EBFB0A5DB55C6CEC7B63C0721AAD84D2B6551FA941167C78A0C105ED9E5300A24BB2C8B2265251A38EC2B9D05A0635B2849A81A2A7C6F2660504D5602FD2763046820CA168D70B76E35B9641CE46A44F2A394F496DC32353C1A84302381E8D74CE4294A4A260A5B0704797567AE831D7C4410593CB7B9AB74D2042C84805C3AEA6EBD193A927C8189082333B3A5E96857E3970BE7DACA4C884D7BB0B3B9C250CB4135D0B8C90AE320DCB3C423E8A6DE79AD594240AE7AA036E320AD8807CCB7A1BC80C704C9532960864A9528347636B4123337DB7E2DE37823C6AE084418FDD05FF7E904211924FE5A370537762DFA012A2153AF96A46987776D245FDCB9434D66AA10524A3CA74E494C9DE919C8E23C3FF77C58CBD1CBAF5B8A69803A32E23959B2A7D9F808689906A0985AEFF5A8464A2AF64BA053A3C18D89B2CAE3814CD712484288ABF7655063C403F635D7A2AFB9D804E2E89677131BBBF7009C981548036726D25F05F004D605A24B7C2BCCC4294F065C013C8ECB242D25611B5C82BCABEB9E578758F2F3AD3F087BB6813DB1F3990C867A2E679F47F074FD012E87B3B6F51CB1707B9287D99FDBF43C8E58940109C376789E16C4A30B6BC34C870364192C555B81AF58962AE771DF477FF421A9B46C6E64BACD1A8A6D00DA4D9507212C910ED2C62D199C7E330A11982C514F27AAC092A5216B13AD54BEEBAA4049065A68D8CE9B1C969EA01599A71D633197BC33C2F6F958F72CCF14C7C09D973770F170F1F7BB9E458A00936D8677717F4A17655BC7A7EC56119779F7AA391D2356AE3A97D7CA04971CC2515154E148568C176A659A8DECBB2C5C449CCD914D3CB7431CB3A0A400A8C7B59B1CC770C5BB5B64E0932C61783C9979D6CBAC042216A0CC5800EA160C8C8556E0721D610FCE13992396C382E93BAD1514D780CEE046525C443FAE063C5882A01E5A73658A30864B1D6344A6CC46729BAB7810C46F5B480D309A263E30461769A55A2965BA6BA0B44054F211B98C6C2355150ACAB81881E5AC1E561A4BC4B39F9902D1027E56155F5D71B7CA67415185319BA769F88345611CA2C20B233DCACA9DDBA42EDB204576BD028A79BFCA57C9DBB0A54B933C970DE35032B9B51D00C9922ABB5106897CB896065FCA846AA486D9C27F5B616E99EA0ADA711729B75D86669645B9A223959B3C1C2F3AB6536D74295473C4C055AEF8C2CD2D321E9E73CBB872698B3A60667BC768014332083139D08C321157CFF1481F259ED56A7A3FF1717BB64FC951297C709A4AE3C05FE3910D6507AC947F944B970070570FDC9843A8A5BA564141F80F1654766F93048BE6297A1CB76C105A7BA3ADA06A42ED1AB3C17542201712F11824766C07BF14685AB0A9F69A15AD6574E59709D2411B37B509DE3B7FE5E8B0AC65922DF23E680C33141418F9551660467ACCC0C794A67CC530A5B130B4CF1C28747601D26983764ACBDDD30E42EB96125956A5870142574419977209A12E09AB3C5E8A22C1C5252527C90987A816B8830A757EC44B12E2E2BCBF19097D02B19AE47CC7BC99189370A1AACEF36415DED82FA7A63BE809B515F79F06612DABCA5768201C59E2C92EBA6D13B72C31648EE1D504EC3E89C8D796E77FA9A772499AEC973B63E864CE36A29DE99ECEC9695D12112CE2F60F27DA7F318EB94A74B437F8E0BC9513E9BCC38DAD99C174C1D75E0145F1E2F8D320AC3CB0C52EFDC753282F092BC39BAF4A18783A48EA031A191865EB78\nct = CBEEC8C5D1013221D499DF4B687FC8DD032863EEE2A09D95CCFD7CCB41BAC0B0A3122FDC92EFA08BABA7D722EA15C19BDA3F4977AA8AFEBDCDFC3F0E1F4274680048F9E060339D3245E7CD07C368B0A132C6AB6C5FBBE6FC4D87BCED0AE4504A62B3E81DB9F586D2F33C61AB9F04939946AE1C38C0D34D97DB4097E424BFF268243D2CDE37211A073BA22C10FA87BDBC19AF7A7F5F07CE8745458F9EF15134BBFC4EEBB6889D668111C83AF7ACF73E63291A25A47650D2E0471B020B06BE0C34B191550CE2D2AB8323A4F224212EC47FBEEF84B36D17E593E4DC3441196F5B091DDF778C6127A9AB08F6B84997CB057BBA3508B7C31982A0A8A017BFB99279BD375DCB94D8F3AC4C6BC61CB3E63CB1FDC5CAA637D1C9330ED8A251037075D44375450E4224176F475A48854D58652637189D2DDBBE38EF9D34F059582F8796066D8D18362A708190AD0ADC3E91F2F51421EA2172E0170600BFBF23730C6CB025ED8CA4B9AE033F6CBD6EF7F69A7DE1E6F711F42D091A79908C7493AD1B68DED11F32DAA940CD4E92BBAC9EABCE85B3FEA56828A10E01847B92C64CE819E72F62BE4AE0C0F4B6FAC1ED60FCD91C166A4E0C17C13D52075F41113D03404BC422FEDA4B37F990C039218C217B5106A095587E2812E66437D8786B8FC9F3365EEAEBFF0C2E6FF6848F0AA570033471A9834EF83FE62884C2022C8934133970DA578C441787E17423EF9CF2BC3A40B8CC481FE29B8380AF23C42E2A808DA7E5EE6D1D7C96B13031898A8AECCCE1928C49C0A81D47BEDCD8CC53ABA9E77BBC83174AF15C7DE9869DA8FD3B924850FF97558207D7134EC48B9FF33501D4021B6F89208E8421BC07F1D37519614BFD0FA4FC195D54D2F05C118681B2465ADE4375807C5314CB21AFE0936098F6ECA70294F6D1F6DD9E512E0D87CDEF023E317CA27D2F1B373BDA5D96733379CA70731D3710FDB7592DB380CC230E13ED0DC3FE8D8CFE15D730CCF7B6E7151353C21CFFC8B53B5DC2BEEB3FC3DFDD1E4F3EDAD81EB1745353B47668022AE0FBEDFC534AE4248286117550B9BDA0E5643FD95B3293DEA31D9F4F2EEE4FFD4FB3964855E9947CB520EFC349B28B42EFEF607C416BC4A339F04D6EB7E1743F631F061CF4FA5440CA2410AD3088F08190A05FAC211345EB0EAFF7DE7E2294A58B7F27C792FD39DC3B8084F390DB55548E45EFC9674249482140B33C8219C7EDEB1ECBFB17C9F4E07A99ACD348628780138ABCE0C1", + "5C96840F04EBE7176090E13D0A08990096149CE1F07C865D35E19B9E1873347D25C03ED113CDBDB3EAB39532247EF19EA00361C4388EDAFDE0B12BEE641310C8AF0C184E3C2D8D5BF7769BAF1F7F6C6B7C7CAF0C1E40E6063E6E601ECE23874E7016D2FDC98ACBBB62B1230CC7C1CEAF1699D004E63F1351501D99D6F23760003C2BCADED3A44CF7B0B572243D8E137DC4AA785ACDDDA836D986C1DCA0587827ECB85B579241C5EFA06E30AFE5CD363C2F63C0E3ACD503F8277FA867626845E6578B40E983\nss = DFFF52CA2AFC33401B4F72F5E6AB5D9BC21C08A6843FFB2CED24775D786B5A0C\n\ncount = 62\nseed = F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5\ngenerateEntropy = 6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445\nencapEntropyPreHash = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d\npk = 7A2912329482F244226AE33507BA8FC8366736352380B346CA39A936190F09576C5188C5E82315E3532F34D41F1B50BCCC42C1138802CCD5B50A7846FFA7BCADD91FE757AB7FE30E873BA233E13B21D25461030593433F4F66482D94B916AA8D1B4B8D6786926E9364CB579F52236218F199C3925142B53500291A3164516FABB941F98F0DAAA1E2D619C9622D649A0408AC02D5CCB9B787C1F9B196DA37020E362ECDBAB03CCCB63B659C6347104074B1F8254499C8452364726B1294669A3A24AC8B487752175B30CBA68860184D5F78B845B107BEBA80F8750475D059DAD57CAF827878B926FACBC00B54388F24B7B431347E334FFA046C45E234124C958CF66023DCA620E1400CD5C08B89554A474D7D04086E5CBD0D051C03C4580D3442A575255C833026BC19DD301A70367FED300EF27779D2A49819A370519C7FC404ACB3FA441A931C67A3033799519C883BEA134242F35F92393DC134BCE15713DDB33E252B991AF10C7134A8ACD09408C8CB2ADA36BBC25224E8867A4138ED9B4DAF403A477321614B3EE5C7BC2281441936B0B05513C1525421871D007346BCF52D6E09B756B4529BB5480AA3165E617CEF41720167707F35A4415975A62114C7918AD83BBD8905A283D14D22B2400CB29FB1E102562CBEE5A9C10929229F8C60A4B153C430A361812E75B244E4C3954A945459F735D45572E83B505030C13867C720567FD681C539D7094F5558DC5A86DA79B38049B0A45A1259713AF2C1640EE0279BB7191F0C0EC59C2F91184CA70A2E8B7576CE493E32F2C549C4BAD6C925039C4C57114075281AC7631FF4D94EE0723C3400CB2D73C184489AA5B440AD470CDE548F2F70903D08B9B4CB6DB68A5D4FBB049A5A9727F50F9E6C59295C62BED7182CA96D6093578DD014F7EB0B121AC6FAF917FA9B47F6650C6C7336D8848DEDB92A0F70971E456E9AE625CFE266B1000C4EA6252DE1CE20C014BC161FEF405FF327CDDDA37BE4919C2A0C097D6995B0EB743FF66A548307CEE1080A13841ED12333E62EFF081514A5915022C550C6021A27889BB0421DF3A709AB2F9F3B0C0F6019FA8810CE3A9C37F53CD651ACB4E5BC1D8B231F373B7A4CA6723A9710681016943F29697B09F6ABFC1C60E8FC4C201A9AB05C260D2452C83B88423B904DF74F425A9B4D116DE0D059D96779D61017C2E984C2BCCD6159C82DFA5AE7BC63E59304B1105CA054A71D753E7E583742E715BFECC80E51245FF53C16854AE0AB41C581402221CC8834A5F4556A84C19F6172C7C80C759299A42C71BD67040A29185A45C14B91B56A4AF9178E0BBB0C4C197549B5C9765A8874686C63445DEA7A85D43AC4D0B979B4CA13A80BF8DB634A163FE3F4327210A7A128716B9805BC1920DD322B15C74FC722A126069ABB8C95BD090F84497D832A1AB72358D4193B6542BFD627A139374404DC1998416F46054D1B4B538E778D6D0507FBF5571BD01CE56362164793E58355366495AEC80EEA35463C4044B202451B3604D6AB96ACC3617ACC1015379564D6A5FF1A6AE4D802712A94422A99D90988206776055545172B0282B5162B479D748A2E9D22356AF11DAF2629036665EED0642044B76775CFD9417DDACFDCB371AAEF7ABB3C2CFDCA88891DBF808A90028D4F12C57E4985F7\nsk = 0246C2025246911B525E6C3421584BFDBC83D73AB936E76A26236A85215C78DB7DDD010C2E038E3DDA69B5AA2E9F4997D8589BDBF918BE1C046CD518E6958AE6925146009D185B53456B5E16D59257F20CD0F6677535510D02602D5BA5B61C440FA07FABB1B5FBB38437E90522665776892EF205A41A1A2083902648844DC9D65E633266AF871481F036A2888D3FB9901355397F37875A4494777C781EC40478D09A820204A4115701D25A74B4BD91676EA6391FA160617C80CD05B0A80E040CDF22B29978CA55282F2C40316A35433DCC8FF7CCCF4280C0B11C548B5CC08FA45BD0760CE03A02F25689D0F057FAE44CB1574C42E760CB331C2CE4BE16823DBB2870592BA844F30DC407298590A088425E023B856E106437C6074547260A856E648CBA07E51A23E70D7CC65656B4692EC24277F04905C4AEEAAACD36341C705B504CFABA73201C2745AB06B056F1768447981E0D676EC904698EDB230F369190D8C1DADAA5CA59001EE8A68C302F04298DC5700C56B2B577D89CD9A585B239089847CD3E96CA80D928867B27F3657987724FF9031649C246CBCB4673F6CB8544150C9975A13938C89A68CD0B6DE5237FC8D2B7A6BB94E0C0856F00B821636801E9AC84F35276065EE4108BC1D755C1C428566A1CA3762D050458DBC7093567A4465453AB8656272A3C03B4A3C55929271437724471D5D4926109C9792BA49D117813948106D27C33069EB3C40AA8370B79E23F35934AC28666FE72B43F722151F3C26C96CC3B6A40D9E1876E55970F252811070FEFC00D70A009E4871F136A08515AB239C33E2DE638C4260D0C89CFE30B8F8E5927F2C59FEA3947FFD0BD636B10876C3C387C00E15469B42B80BFEB8681DC7715C2B248CA6FED92A9399B72D1023F9507229593BD9BD936A0F6ABBA09BC3367782370B60D9CBD0E8B3D5744101C8CA97EAB822FA4CC399B5BE3195CB1E3C9260030AF60BBE3295C4DE898C502543589142CF48DBC7505EC9A9D93CB6DD4C9678C1CC0A082C5631A255142603DCC01FC07C27D628D89F09B473816B5D5171C18A3F9737BD6D3420D4BCCBD3A5624A2686E54062CE4696E061C83BC2586F1A618639E51E63BC6C64825EB50D4F88334B29145BACC49E28DD564B7A578217FAC230AD00A44F3ACBF8753AA572D66E1AB9198CECDF9BC722455BD267FAF98424EBA4031C3BBEC8298A9388CABC6B3BEEC7A7FBB1C814811117A9D550407C9E6099CEA65ECE641F69454B6A0CA9BF86A3DD472F7C0A7703C6A5B25464C0B091B29258DE673220857878434EA14CF50054FB2E63547E9BE15107BEB7A78CD5C00CBB1462A0347E72B51A15CCB5C333894ABA511295B37C97C7F4C2EB6D97219559B40A67310F457108015AC1B8E3AE15ACF85689C4058EC8A0BB18B75615011F2701BDE8BA70986B39D3368E1F978675A49FBE8509F1239A1C88F1DF4ADF0AC8B68A87E2A403373FB808A7B1192371C7E68B80854B0E4335739090B953A2B67999F9878A32415B78C22289EEAAEFE3298FD38ABEB6ABCF5A55BCA388004E46375A729CC45926A7C3E3BC8B4E2A2B196AABE5651B642C1CB50F666A1BB6DA4D1CCE8C6344356A68DE044214453D03B5C7A2912329482F244226AE33507BA8FC8366736352380B346CA39A936190F09576C5188C5E82315E3532F34D41F1B50BCCC42C1138802CCD5B50A7846FFA7BCADD91FE757AB7FE30E873BA233E13B21D25461030593433F4F66482D94B916AA8D1B4B8D6786926E9364CB579F52236218F199C3925142B53500291A3164516FABB941F98F0DAAA1E2D619C9622D649A0408AC02D5CCB9B787C1F9B196DA37020E362ECDBAB03CCCB63B659C6347104074B1F8254499C8452364726B1294669A3A24AC8B487752175B30CBA68860184D5F78B845B107BEBA80F8750475D059DAD57CAF827878B926FACBC00B54388F24B7B431347E334FFA046C45E234124C958CF66023DCA620E1400CD5C08B89554A474D7D04086E5CBD0D051C03C4580D3442A575255C833026BC19DD301A70367FED300EF27779D2A49819A370519C7FC404ACB3FA441A931C67A3033799519C883BEA134242F35F92393DC134BCE15713DDB33E252B991AF10C7134A8ACD09408C8CB2ADA36BBC25224E8867A4138ED9B4DAF403A477321614B3EE5C7BC2281441936B0B05513C1525421871D007346BCF52D6E09B756B4529BB5480AA3165E617CEF41720167707F35A4415975A62114C7918AD83BBD8905A283D14D22B2400CB29FB1E102562CBEE5A9C10929229F8C60A4B153C430A361812E75B244E4C3954A945459F735D45572E83B505030C13867C720567FD681C539D7094F5558DC5A86DA79B38049B0A45A1259713AF2C1640EE0279BB7191F0C0EC59C2F91184CA70A2E8B7576CE493E32F2C549C4BAD6C925039C4C57114075281AC7631FF4D94EE0723C3400CB2D73C184489AA5B440AD470CDE548F2F70903D08B9B4CB6DB68A5D4FBB049A5A9727F50F9E6C59295C62BED7182CA96D6093578DD014F7EB0B121AC6FAF917FA9B47F6650C6C7336D8848DEDB92A0F70971E456E9AE625CFE266B1000C4EA6252DE1CE20C014BC161FEF405FF327CDDDA37BE4919C2A0C097D6995B0EB743FF66A548307CEE1080A13841ED12333E62EFF081514A5915022C550C6021A27889BB0421DF3A709AB2F9F3B0C0F6019FA8810CE3A9C37F53CD651ACB4E5BC1D8B231F373B7A4CA6723A9710681016943F29697B09F6ABFC1C60E8FC4C201A9AB05C260D2452C83B88423B904DF74F425A9B4D116DE0D059D96779D61017C2E984C2BCCD6159C82DFA5AE7BC63E59304B1105CA054A71D753E7E583742E715BFECC80E51245FF53C16854AE0AB41C581402221CC8834A5F4556A84C19F6172C7C80C759299A42C71BD67040A29185A45C14B91B56A4AF9178E0BBB0C4C197549B5C9765A8874686C63445DEA7A85D43AC4D0B979B4CA13A80BF8DB634A163FE3F4327210A7A128716B9805BC1920DD322B15C74FC722A126069ABB8C95BD090F84497D832A1AB72358D4193B6542BFD627A139374404DC1998416F46054D1B4B538E778D6D0507FBF5571BD01CE56362164793E58355366495AEC80EEA35463C4044B202451B3604D6AB96ACC3617ACC1015379564D6A5FF1A6AE4D802712A94422A99D90988206776055545172B0282B5162B479D748A2E9D22356AF11DAF2629036665EED0642044B76775CFD9417DDACFDCB371AAEF7ABB3C2CFDCA88891DBF808A90028D4F12C57E4985F7D4BF608793939ECBA27DFF5889D4D921C583999A57E20A48085AC549573E6ABF393308641A9A4647F230201E1389624A296B55192A9819FCB19AB77C25F95445\nct = 3A3E99CDFA0AFF52920DA4CA405CB98307CE61FAA8BF07561C783E8D1636003E6BA1A0E38FF422D21D7E842D98ABDD2632FE1209D662E08A8E3E1459DE3D8F206C6FB378019611CBEE5A835A23AD221F07574E9AE19DABA2AA1E619D25CB73F7", + "AED357D2A68BEB6CA21A905DD876D55FD28B251C94121F4934E8046DC44E31821E44294AB66A42BDC3A0C87A74352872FADB4CF156977B539666718B51F3F725E0F4BE96AA399DFF16802666ED4DF9CD2D83470B90E3BD5B7CF395D029082F0923285CED2148A983AB4D11F525CD9043D261B15EE0D51287E85DB7FDB7215C3363E5E6D2DBC93A546AEE48705A40BB9C8580864AC705499639E7536DB42044D7DAFC6D3ECC7F843CC1AC3374EAD10F60A0F7D31414C3893777A43FC2D9F99BC46D175640A105A0E297EF62D8BD7507A54060ADFD1654AD8446D9B359E6C331D9112DCA7AD22A5A4319EC7FC9BC4ACA3A32CD5F4F34FCB1035521E46E52FF8538A4AD7EC024E9C49F03A6720C55514FB874553875CAFD8924DB711971CA4BCBF8F29BD7571CBF318FAA88E2BD408527A627A1268C96979505FBE85D47720C01DD721795C3A75ACC8DE5184E8EEBAB9F1FF4C4D12FFD3A7C4625C23A2893B1A4C45F4544530F3E9AC72709684B3B3DF2E47E405E84A5339073AD3BBB6C20D9E2300998BE532DB686DDFA4D8EDDED3F5EF868EC100B1D517197313165ED23EC974880D5ADA8D915549121EAF1F0851D9572844D804596573CE5C1A32D2C7BBA0E8FE1190FFE1AF0280E6D781DD31D767FD38899BF7D46BBAD2F7AC2E4CB5FD6E949E259E1EFF9C8A27D8C9C383BB02385C47635D7F631438C560AFB7E4331F1FE6786B6F07379A1CE0A68FEA618616E3F1E5D59C9928C98BA8F00EB1011641F0B2718AE378E4F9CE04C5A539AD899988070E4FFF6CAED2F74F885FF9541BB6B3B713C12FA642C86B075489D06EE26EADC5DFADB91A619E9BFD0BC00B9645605B4B10E5E4029CD30D53C98CAC5C449014E460674F41664F953F624AB6D15DB60365C4FF87AF8993371AE1ABE09428DD55A04154D5A6183D7F2FC1F02B714839A5C7A1EF97B96A3C77E5032191468C43A43107004857F360A0FABEFC62EEDFBE21FC76D148FA89E435CD0004460FA6DCA391393AC3A2E4351C6DA5D9C504E49E8A3988FCF260DCAA781B2882897C6C6913DC72B813634FB39A67C7D341CE8BD5494DD499ACC1824F7585D9A0AF542B8C8D50C6CF42BD79DE25F4575AF276544A3A55B11081CD798053B56C36BA4D0F4BC68E197A4B6BFF7F00E5A3EF02878D5333C0E35C4288A541EA49991C5652D6B751307A15CACDA2774D676EC53C0D36535ECA12BD7428660FA8A8C1C1BE54CEF68D23DA94C0BF547B3EDF5B3D4BC618A5CF67D96A9E8F71839098404573C83E3B0E6CD698B1344697BD4E348A5D56EC3D87C32A1B083C21845251DBB844B16EA2528571E42B631F5A48698658AE63ABCC46E36E721997CDB747F05492BA5701DA2848617A84087D31D040F1DD2DEA513AE87C4\nss = C870A7BE3DC7BBF5836727E5BD82CF977B1332E7DB276473E4029ED95204ACDA\n\ncount = 63\nseed = D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC\ngenerateEntropy = 7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951\nencapEntropyPreHash = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b\npk = 8E892A62437CE84445F2E82B495C9730FAB393DC6F3B36BB2A63759A79AE27B162250076A608522440AC1E04630BA766B4C256341C6AC967B36E6934DC58CDA15621827B9558076361192E89708ED88A71826A20E8EC948B9C7915566C70A7C15A72C36ECC7A3CC644EAE696022657C53500A0F13A8AE50FDFA432D8D2530999275E5B9C1D341FB34B8A5A7421B7D290CBC3218486B555C92572BAC8F1085F058A87FD48796824844553261CA11F06978A03F3A8D68657C22064AF83166280AF52270E004731D20B18982283E51CA3DB7A2679DA6FB0AABA1E75A2D283ADD699A797E1BE93502C6823007BA5B9760A338768615B671BAEDC6A6A6937B9E1C35575776A4A791FEC7751079C6683BA29EA28BAD199175B9629C44BBF219CD88A19F1089AA551946E58032A9C9DFD29BC4CA3B654F494990CC02BBB8E1280B54BA3920EF98903F171C27A5C0FB679C8E84774F22136E89915A534D973733410A96280A3207407235CA0D81A636A35B9DD628DEE9A64A12918D0DC6D4C600989168A163730FAB8C78E61A57970C16C813B791A0EE9F625C438CCD1A9429A93062C4AB38DA5890188829AD116A6F1564A43A2E4F3BBA3712207B65E701995C99B29D691C86BD9844AF2471EB5CECD934F764629DC25839C809432E395FD8582CDA980359246EEF0637B9771FA5853099007F173C8598164DA69C8E67A910A50B9940B213547815E0589326B02FF21B89BC4200219652DEA6CCD59883E29127E2ABE3787738B124D839A67E02195D64989520737E3AA99C6822F2C32249256C45455CBD931A5A1FB27CD56A21E22B51C03217AA387E151631CFA445B2B77EC90AE01828601961ADA8A8E6192104F02BA5064C4EFC27CF2DC3353FC98F34BB947B21EC5235FBA6CAFFB6BC6B1C09A783AB8EF14C4921A28A3896BAC07AE8BA98C117B3624E01ED0496A8C649A38A33FB679BB535A7D1960028CA6C8BA825178E74F0E50B5D74C2A9119B595B863D0375A3DA173C63A03D8C60A8D613CC08064588890E3894A9BF4580704038841526AB84E27CABC8FA4CAD6DBBDE9B53017F100778478B86138FBD6BE713A7E695358538BC4CB5A4FFF531BFF178BB16ACE5A295CA0340985F34267A3A931998B29A36935D3B13AF0631CD37777689CA0B43B9208AFBAB88EF886A8672B331224C66C6086B8B15A8EB86107FC0AE260BF08F970CDEC98ECE9A197751B6996258FFB6DCE05306380770DC63498E9B5D65ACAC5A179D8946B27630525B39C3755C070A120C9F468AB3AA8B1A48848081B888BAAA1156BD600733BE887ABF962C46107C432C34EDCA8E549977D9A6F7EB77EB9974BB353896E8261502820F599257CD9C2852328B0FBC5C2B98658D67E4A636575A46E074A1EFDA2CFA50A0594B0A421661D81D95A9AE0CA1C037532BA7EEAD089961C29765C443D428BF20767D1F08615E85D0C08B0FA5076E297143249283C13486F61A4D9D39780624055D6043120A510D4A686F9B490C74F2DA782AB42157A00991BE019E093A509C0C00B7C1E6AB611DFC4373C640A2F488E7632BE1289666206CBA2B096A479B2140C6AA301BC448B13B6839447C4675AA1BE46EB6ECFCB4DDF2569B2D79ABE93FCEAFF0F0FF88688C870D19759A41D3D361A0CEC73CC908F52BAD8\nsk = 34C91F6EC981B1830501D8969F8847B2C6BD5D5C43DFA044C43B551E610D5675BB7E7C9E393B411E69575301BF4EF4C7FD0B4B59E213905A254EB5540ACA856C370DD28899541B725091C23907C04390AD32A56385075F42A7545672544FE177B74C7ED99507E4D95DEF7C4A9F84C9687B9BC318A23EB452FB7635D5201165A47391D21A7CA732FE9B3455C44EE4E54FC3A6518D51402CD5A2D49429B9C8815CD4B1A22C59ED368ED6C7A9DF83B958CC83C4654C5CD040245543431C0D2C9091376611CFDC2EB9181B21C8417E3931AA2B1141C1051CB82ACA4BBBE6DABDA3356BBF4962C3F883D0578580477AC56353AC7524F3855DE2B00967B7BEE0668112D51CCBC139FA73374DF2685A3CC06838B150F92A64C17772053DE2B05CC4D51832B8A2B8428436D99E1F2484B127CE0D861DC8A11AB0B0019E0B3439733B36A7A600F4638D820BA5624B445349A86465E1B25DE787207DDA0B629CB472D415A42A8BA191B76B5829D4D987A2B0C235521C187A0BADDB603D755EB37396CDD57FF76276CCCA997B00CD481587CB8728830021DCBB8478A267B744A5BFD08B4ACB2C1E726121996E55B60D40F6975637831C392845D6823D4B9092151149992794F4AB29D4164A44239F07C365A87ED9786AF7A57AC0BC0D491018007B6BF7705A21B082D1E040A4F4C25E329EF9A8518956044E7683AF94728487A4F95305D4E15AAD45C040F1CF9C442C519B2AA47A4DFC29063243C21F8B838171701B4B73516944EFC4B61FB5BCA63C3ED12A123F55B832E6C312E8BC48F145D62953F5901F7530068F2C9C9F51CA8FCB342852936D414FDDC2C04F551C827071F99C7C24C991F9C97E10E051694C86789A9442D79092B6547D67AF70D8C8B074CDBF854718A882DAACA3B8EAAD0BB1C2D3E859D3EB03C0A23B290518EF88CE1BB02FE71399EF71B380EC1AEC4C7C6BF3830C1B15F7718D0E471D10234393D94FBD3305ABD09CDF070A0ABC09D7497D2F9B939794B923EB3F28B40904A53A05216A526132D9F3CC64606B40F26434142645D79481A8316E8CB0A9321A4C530A0AD139ED5953168A4AC864C726874E1366AB09A249F251CE5B1A7F5CA60AD66375BFDBCFA3D7AD23A13649C03327D409FDA64581CB00A696557945C58E96C1C889BE648C4885958ADEA79AB212A0BB15506BF5635E437ECEE47B60032B4273B8C96806639C87031B6E23B71996B4576626124281AE4CA0A8FC081E1C91667967B25F76C4F72624CB29BD0A865FD67A4DBF14ACC7A09871BC7ADEAAB37B298F12B60B6372B741681627E4C8346C0D34392716EC173B1B711B1C0A1D010DCA486BD5167223658A5C55BCD0739DCFE30DFCF9BD8AA45B3CA0B5A90243547767A1843E4C87922031819EF9249800C6DB8B0270F9CB8F2624ADF4199741870B0630E1BB1B325768C79984D5E33283A991BB3C98B6BB8BE0EBAAC47C4310C51EB565BABA36BE54F6A3151A104911C38EF78E61F1654EF35B2C836C2321A52FAC710D6B03811444DE5B8403569C8CE0444EF615DAD54AE5649E68AB437C00A2C9EA9B18F59346D8B2A5C6582D763730BBC7F24A7EE7C23607C0683A2826FBB4BAD4A58FF6E3BB3122BC8E892A62437CE84445F2E82B495C9730FAB393DC6F3B36BB2A63759A79AE27B162250076A608522440AC1E04630BA766B4C256341C6AC967B36E6934DC58CDA15621827B9558076361192E89708ED88A71826A20E8EC948B9C7915566C70A7C15A72C36ECC7A3CC644EAE696022657C53500A0F13A8AE50FDFA432D8D2530999275E5B9C1D341FB34B8A5A7421B7D290CBC3218486B555C92572BAC8F1085F058A87FD48796824844553261CA11F06978A03F3A8D68657C22064AF83166280AF52270E004731D20B18982283E51CA3DB7A2679DA6FB0AABA1E75A2D283ADD699A797E1BE93502C6823007BA5B9760A338768615B671BAEDC6A6A6937B9E1C35575776A4A791FEC7751079C6683BA29EA28BAD199175B9629C44BBF219CD88A19F1089AA551946E58032A9C9DFD29BC4CA3B654F494990CC02BBB8E1280B54BA3920EF98903F171C27A5C0FB679C8E84774F22136E89915A534D973733410A96280A3207407235CA0D81A636A35B9DD628DEE9A64A12918D0DC6D4C600989168A163730FAB8C78E61A57970C16C813B791A0EE9F625C438CCD1A9429A93062C4AB38DA5890188829AD116A6F1564A43A2E4F3BBA3712207B65E701995C99B29D691C86BD9844AF2471EB5CECD934F764629DC25839C809432E395FD8582CDA980359246EEF0637B9771FA5853099007F173C8598164DA69C8E67A910A50B9940B213547815E0589326B02FF21B89BC4200219652DEA6CCD59883E29127E2ABE3787738B124D839A67", + "E02195D64989520737E3AA99C6822F2C32249256C45455CBD931A5A1FB27CD56A21E22B51C03217AA387E151631CFA445B2B77EC90AE01828601961ADA8A8E6192104F02BA5064C4EFC27CF2DC3353FC98F34BB947B21EC5235FBA6CAFFB6BC6B1C09A783AB8EF14C4921A28A3896BAC07AE8BA98C117B3624E01ED0496A8C649A38A33FB679BB535A7D1960028CA6C8BA825178E74F0E50B5D74C2A9119B595B863D0375A3DA173C63A03D8C60A8D613CC08064588890E3894A9BF4580704038841526AB84E27CABC8FA4CAD6DBBDE9B53017F100778478B86138FBD6BE713A7E695358538BC4CB5A4FFF531BFF178BB16ACE5A295CA0340985F34267A3A931998B29A36935D3B13AF0631CD37777689CA0B43B9208AFBAB88EF886A8672B331224C66C6086B8B15A8EB86107FC0AE260BF08F970CDEC98ECE9A197751B6996258FFB6DCE05306380770DC63498E9B5D65ACAC5A179D8946B27630525B39C3755C070A120C9F468AB3AA8B1A48848081B888BAAA1156BD600733BE887ABF962C46107C432C34EDCA8E549977D9A6F7EB77EB9974BB353896E8261502820F599257CD9C2852328B0FBC5C2B98658D67E4A636575A46E074A1EFDA2CFA50A0594B0A421661D81D95A9AE0CA1C037532BA7EEAD089961C29765C443D428BF20767D1F08615E85D0C08B0FA5076E297143249283C13486F61A4D9D39780624055D6043120A510D4A686F9B490C74F2DA782AB42157A00991BE019E093A509C0C00B7C1E6AB611DFC4373C640A2F488E7632BE1289666206CBA2B096A479B2140C6AA301BC448B13B6839447C4675AA1BE46EB6ECFCB4DDF2569B2D79ABE93FCEAFF0F0FF88688C870D19759A41D3D361A0CEC73CC908F52BAD865F03ADD3941D22C80D50659F501F8CCA1B448D84462CCB93D5F065889484BC0EAC9D531A532770837A854B4F5531F6E0C8D6C10183B30D3435498C2DD142951\nct = A37E48A5F89B418765EE73D585AAADF3AB787504364574B84C2ECB3373AF7DCA5582D287A60588C9514086C3A56486D832F0BB56499F22BD19F437505760C1948B04E6DC667881565B63EEDE3D6432F073C7F9F3569CAF3E9E62A6EA7E6B2C2D290ACF3502C87C9702681FE4C6A5CCB0AC957EA2ACC8DD68E574E64508B5C3F8823E8E23ECDE3A8CDA95136D4784F2A17FF9E0E4132A48F1FABF69AD502EFC4DC4A2EB5C05F56FDA2B8243FDEF423D1DA695966F6BCE461B2468F5603B78B1BCC9E8DE0DA3D5CEBDF71A4A2DBCBD653929742EF45E550B34A4B55CF6832347BD9BC0CC56F1CC72F2D92C37689FB2CF08B37D3EC7782941DFDA884F43D58E3CF9DD73F359091DD89D2AEA83C0E5D163775841D41CB6B7E1CD1DAB4C8396F507613E2F842059F5CD8F8D5EB60DEC519AD7D3473A61A1EE79B6EE2D2011F72CE44FC72294C1A8147A6C2C6916D1A88A2BEAB3E886E0B11B815C4C9AA57A253270DD14FE11590ABCBA02E750FB3190C486FD754247FCB0219634A74ACD1F53FBD3A193E6F36049BF3C920D2F0AE28E6F3F70C414BC5EA3660E8D192C1DA4AA6834CCBF2CE4F7A943FF6B32F0246401F6EF6914F5584551290DAE6C3A97F346551A481151796A507654E99819950DA5CE8381F142B3F6AC31B0E6F8B34315FDCE5A024928EF205C2A6A989266D0A4123A5A98CDD9002C29D19D497FDC6F0C77F3B4B1BF569B89DDB22A73D0A59C518B91321277064EE8C5C9765E54C99B60BB9ED63E2D43D9EA7246CB6F8CAD230FF95B622F64748E5E2FCAD034754069997DD003A5FBA93B8D29476C91FBAB4FF0B90C180ACD747EBAB9CD7066F995FDF389874B926478E4A10EB749455DA26CF1D7E78D119E34F0AF246FD5D7DCBAD8479E85C51E59941A0B0B0DEDEED9508DF28198DDCB34624DDB45A50519809A2931594AB8292E96C54D5EB7342355083C2B6206479B50ED7FBD1C35958A94017D40E9E86A5C442E9EF5780357E47AE64631B2F803427F90BC408D3AB639C065F75183249229D8C27716E137891BFF8EE4EE1467B61708E385ED429624EBA3E53440F3248E0C32DA91DED4F934CEC4F872B78283B8E701FA635C941569E113F87A92373091A78DAC58B4AD5521C8472C9F145196D0B594C73126C226B7625D6B7FDE4BDF56E3B32E88ACB3575DCE80AAB36A1A09F9B646AA12D60637EABE185FCB81F45D54C952FD721FC74D761BBD405D50730CB81FE7A6D45B3551B8DC57A78491BC41A310F2478AFD09A539B2AC1545C4796B11DEAD5C4CF2D7342A13B7AA8CA9BBB86BBBAF965DE4D3513EE114F53FB1FDB4C52BB638B2A06C9A93FC93C50458B4D3AF86274258B43A7323281C4E7F2AFF58B43A414708DEC53F4BF23AB3EBE2BF3D51547472F4857F84A697A339AA184FF98A0E980438CEF69EE243B112D5F182F071C4F7BD78410867E3A07D274A7E4A15BD04BD6801D19A3CCA7F50EC6C03D5EA9C495737D71AD9D3A019CBC2C6FD5954680CC6D63722C4AB581BA095A39C29270DBA\nss = 3A14474E05DF3FF59C6105B1F2AF004A8B8164DD049EB6929B9C9881A873AB08\n\ncount = 64\nseed = 5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93\ngenerateEntropy = f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d\nencapEntropyPreHash = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5\npk = 61101724795296A2499158C8E1B50E4C900D65C8AE65503932DCA40E058E8192CEC2A997CF12C8A1227567B12A1B21BB31D3198C85C4878C6EA1967668E3952D04B4123CBB9CD8C77F3A7397A9133D99654E6C56E7465D9B98BDBD624C12E36C62B60B6A32C9086A8EEB9B8919706F4573A33C393F74BB51D5609231F1707E152F23F36F6C6830EF28253C8CB81EC5C27ADB02FBDA5302212826F0B88AA4B4D72A509E29CB1BFC8177C019C60598E693BCE999AABC4621123415235208E7869F62AA7B50A51724C13DA2DB59D5BA5302C772F2C1820FB0882EF32F73321C17F40D019CAD39C3B12C57C3519CA0B38366AC4353B133C39262BE6EE47ECF660286F6CA8EB7090418ABA0D9833E22B46B761FA2872FB80972B551809C02775BE07C796636A2C619FC748B90D28E1E702FFB0653E250C8C3759178C39E42411327A81C7E7887B21915A5CC032C37A11382C4D9186221B1C66AFCAE8184559910201C8BAAACEC62BAB984E080433B9465E64A2D987028E9D9090CB2C41753742CD77F0998C672441E83D45F2D06C22899C2136362271B731F6BA3965B32E2517463E627AECA0AE5644BB8602F7FC599ABC120AA111E2E549A276A18D2A92C39502F6F9519CE76C0BCB514E8084C7122A321479338F59ECE08A0ACD30F0AD68F2091855D5980219083398A6C0A63C70D3743678A1C0202A69DC526DDB77E30B779C36AC2575704EAD94DDF1661A38B2624E733F2E2AE18467CE2C3083B75017411390314AB06ABB4D0FB58BFF99DC3949E92994703E85FB6B863AE1C29BDD6656CD75D9BA453AA115A32745F2DC1829881A9F4D5CC2CC053AB79B89D107E6054C69DC93F5AA9C8CA6CC1A7583F2E2739B102378D93990CB8280B21A5D5BA8415C48EC17288044623A9631577C16639922978258CEE0B6C51BBCFE3F70BE07CBAFB7C58111CC7F2F922AA023D5AD01D2D31A57E0469AC428B6FB88A97D957AE22BEB768C3CB7C9F02F583FA2513DB7C580D2986984314E8B346A06501D8972E31AB8EF5B983E9A15E8FFC624D0041FD523570960E09E57D616A06297BB3F9D938F5655628B06C4F6C4FA5F8136F8CC05DFAB7389237EA75AEF46117BF1B67AA978BA622491260128E743F28F95F533B708F3C59230B23FABA96FFB5C239B32B30A65B36FC5A0A76B76F04A60C9C7D5EB78EBE44B736EB56A0812F59D9B5812916246228F2523175242CD1F432F9FB054A8B52D824349DC0756091B2F7C21E2A899362157BF9F631287B90D6C80FB55B1469273F79892435D031B62982C49A1464E2274F815F56F3B6F8C949BE11388DF1151E7077F603AE592623E4259853A2B90159344B041AA29C8AFC5074BEE81959102E0C57A761F1B1AA65B1DCB66A18BBBBE12B2B2942A37D13C77C77B2BDE758EB1901F74C7D57D373A47737D6E23998E35DCEE70983359B4162C7135126E90A807604034D52ADD3530456B66F0DA64453150AFBB67D67D9B359137C2420250C279A1C537AB06952E4823F09372198C253D5B71A7E70A1C48B1DCAC3A85FEAAC35A11E670B2840A57F2A7C77B6A00CC80A282F0A1C8160080C702D619A6B6D68C757306C93A5B21BA8185B1A46C79B03C35880A7B265A3E05B2DB868482FCDBA0367177BBBCAD04F3A50ADEB85DED90BD59DAB\nsk = AB4545850434076342EAE8409FE0590C34955E860267305FCA05C347BB3E53BC714E3134A6E9B338674A9AABB02F021D1A09A190757F03D573C27687F7E35F2D77294D10CDED732218395B344523F1B704B27689DCC286B5C98217F239C159AE5D655436F00517A50C6DC6B7F4F111E7F37A0F319BF6ACC7B0E3345C9367B2A2B8D9D644936220C0A817FBB38CEB3469CD55C661E1C58D06807504443448C4E53204DC59C60A5153494478EB4056C9A85967A42EBBC287AFDA51FDD6B84B285523D41D80A56F7A68A168A4527D902311B18D5E381CFDD578BB7924FE687D3AEA5607906815181171A727E4DBCE1B678762A8B03C2A2BFF1635CA85332AE90F14B880C5EC4E5389B7816AB885C44A8D83C5EF0C4C754C7B6E673D984938D3CA4EB0F5B83B90BEC27172AC85154EF27B91623841E188D76B040F958C38C8A112C05B54103E55A159DE0954F2477E798A573339508B7C2AC3872A623429777BA3179060135C083E2198D1E0AA01967C39C27372A1A36A92BAC3BB13EE3C94B1F0391E2702C50253DD497F16F39BDCB9C68CCAAB6312084884B113E70F38555422767F4E613B2E87AFFC01395FCA37DF0A1AEF74263C1001392732D9D1047CC7C6FB910AE6136C33094526876A113514F2918909532A759617DBE2C97E72176490995DC82B663655DF65324B1996A42150BE41B2A1C90F03B2A6F04174DA1B1CC7FBB024C3C972B9714300C683C28A90F48B01C28607922C3ED25601A609673481B365544B7C36A9550EF20C37005B0E395A268E90CE1A5271E1421B46303B80CBCC81E2894D7569E82C2F5D8C6996C766BC505976628CADD84A3F468C67C209117C8254BBAA1BA584DC2661728A69E959949ED6C9F1B42F01EC8E55614AEB7168CFBB5E16504EB9F585C7789C48E59C17B5975C444BD6E32A6654BCE298A605043BD367400C14B1D8E1A592A034543C04A44C85711AA66C807FB07378FB525600C19D9A4A9A8C920BA7DB0B1D912A45F2B6D518B469E9121D25CF40499196376D3D92827E1B96AE255AFF288037793C7DB07E1D15533C07162AACAE3255C0CC368E2FBA3FEF09540952910EAC0FB2F3AE376AA666FC97A3E122570CCF797C79EC575835E0BE6E808B3CB1B72D8241C3679BF15020B6A63BE65B95A2C9147EB98C6553C71C550E37603E6B73C877C94E7B603A22ECA456C1409D5AA049673D0EA17C123B1835692253FCB589186BAA498F39481C3D0640A4D34931033B30F26EBED6CA9C49BA6FB219D6DC84619372", + "84235A6417CC9C0CA0AD385B04B01C81D5A7B97A34977250E3679AC55C3D76D83B1F7B99DBA039DC179147223B5D6C11FC9109DC062A1E4B7C88C710C449320949BB4405B28EA2C04D48C58AABB46EDAA58E442F3AB6C9810B6D702855F7CA91AF71B0E574BAC1040DBE864DDAA76827874839414CF3418D1702C6F368A10714CB25E208C8A5779F639837A07E348841A11714F41399DA175C49678307D3634D6B9921880FD43CCB8D7842E5F34CE44A4923E7CE6B671C7A989AA748604D147CE7AC25A1533E80AB321B7AACB8D523A3A6298BEB0CFDA435D77714993173D080827FB07B7855769EBA987696AFDF58231F361D61101724795296A2499158C8E1B50E4C900D65C8AE65503932DCA40E058E8192CEC2A997CF12C8A1227567B12A1B21BB31D3198C85C4878C6EA1967668E3952D04B4123CBB9CD8C77F3A7397A9133D99654E6C56E7465D9B98BDBD624C12E36C62B60B6A32C9086A8EEB9B8919706F4573A33C393F74BB51D5609231F1707E152F23F36F6C6830EF28253C8CB81EC5C27ADB02FBDA5302212826F0B88AA4B4D72A509E29CB1BFC8177C019C60598E693BCE999AABC4621123415235208E7869F62AA7B50A51724C13DA2DB59D5BA5302C772F2C1820FB0882EF32F73321C17F40D019CAD39C3B12C57C3519CA0B38366AC4353B133C39262BE6EE47ECF660286F6CA8EB7090418ABA0D9833E22B46B761FA2872FB80972B551809C02775BE07C796636A2C619FC748B90D28E1E702FFB0653E250C8C3759178C39E42411327A81C7E7887B21915A5CC032C37A11382C4D9186221B1C66AFCAE8184559910201C8BAAACEC62BAB984E080433B9465E64A2D987028E9D9090CB2C41753742CD77F0998C672441E83D45F2D06C22899C2136362271B731F6BA3965B32E2517463E627AECA0AE5644BB8602F7FC599ABC120AA111E2E549A276A18D2A92C39502F6F9519CE76C0BCB514E8084C7122A321479338F59ECE08A0ACD30F0AD68F2091855D5980219083398A6C0A63C70D3743678A1C0202A69DC526DDB77E30B779C36AC2575704EAD94DDF1661A38B2624E733F2E2AE18467CE2C3083B75017411390314AB06ABB4D0FB58BFF99DC3949E92994703E85FB6B863AE1C29BDD6656CD75D9BA453AA115A32745F2DC1829881A9F4D5CC2CC053AB79B89D107E6054C69DC93F5AA9C8CA6CC1A7583F2E2739B102378D93990CB8280B21A5D5BA8415C48EC17288044623A9631577C16639922978258CEE0B6C51BBCFE3F70BE07CBAFB7C58111CC7F2F922AA023D5AD01D2D31A57E0469AC428B6FB88A97D957AE22BEB768C3CB7C9F02F583FA2513DB7C580D2986984314E8B346A06501D8972E31AB8EF5B983E9A15E8FFC624D0041FD523570960E09E57D616A06297BB3F9D938F5655628B06C4F6C4FA5F8136F8CC05DFAB7389237EA75AEF46117BF1B67AA978BA622491260128E743F28F95F533B708F3C59230B23FABA96FFB5C239B32B30A65B36FC5A0A76B76F04A60C9C7D5EB78EBE44B736EB56A0812F59D9B5812916246228F2523175242CD1F432F9FB054A8B52D824349DC0756091B2F7C21E2A899362157BF9F631287B90D6C80FB55B1469273F79892435D031B62982C49A1464E2274F815F56F3B6F8C949BE11388DF1151E7077F603AE592623E4259853A2B90159344B041AA29C8AFC5074BEE81959102E0C57A761F1B1AA65B1DCB66A18BBBBE12B2B2942A37D13C77C77B2BDE758EB1901F74C7D57D373A47737D6E23998E35DCEE70983359B4162C7135126E90A807604034D52ADD3530456B66F0DA64453150AFBB67D67D9B359137C2420250C279A1C537AB06952E4823F09372198C253D5B71A7E70A1C48B1DCAC3A85FEAAC35A11E670B2840A57F2A7C77B6A00CC80A282F0A1C8160080C702D619A6B6D68C757306C93A5B21BA8185B1A46C79B03C35880A7B265A3E05B2DB868482FCDBA0367177BBBCAD04F3A50ADEB85DED90BD59DABB8A3B8CF4709204A2FDB19889B0022EA655DFD58FF27E17D530510E1EEF457933FC3D8392CB53F36ED647364A04E37278A0E0A45B720F4A75C580C9920EBA98D\nct = 25E080415EF5CCB5D8C322634C5DB0F0ED10C73D5A0BAD7B2C5B899D74E6EDEF6B2A8EB9DF8D415BD41DDB01F670B8939D464561ED8C37A2B2217A49D4A0C7B5BC13D4A481FC383BACFC6CB979901098929B9FF7B5ECEB2BC21BCB830B4556C36151A386E2479297066521935A10D3F16222B9246C2885FAEFC2F8597D4AF4F13EBA79C30499435D93420E9F2E46BA2D7C54244A3EB47165ECE9255511DC524D697D13EFEFA8B62B6E61461FEA69830593D894016E83264103A876920663383E13BDADCE37A85D29744751EEEAC229CF89C282A56EE0959E46106E12BD94F4ADDC061442DFF73D7DE2D6AFC2AAE8230A88E53E7E4978B6B897AA6AB040261F9A5BB22F578BC03B0E81D2CE5A05A235EEF3A6177D4064443E20D9603EFC34816E688F515E5A48AF57A98DE730B0F5747D9F3F691F6BBC5F88A7B137E9244EAFBD539F9FB4F2989AE16881DF8036B3ABAE959A2FFF2313EBB7D044EC566A8DDFEFF1114029A30E44ADA4DBFA56CC1EF04774721A507795C10DE58E35F3BB1B1DC4D62095FDE786821BB410EF6AB4972B0A681DDD1A7FE8CA50828DAA7D5D19865644528C2A5A4C475A6B9BD3897E8DCBA0499E6DD75595ABEA0A485F7E41A727353DBD7D45ECB0AA82E39FE03B177710F6180421A465C1930EC9CEF35797E708227BD67451F8810267016EB07116BE1B4327902F538C5512902E6E64364B9AB0392A43892D4396549DB5EFF4EA7DF6754E34125E303311FD6F1CAA7F90D7361F201AF5B4D2632FC7815FE27B93E5B4251A4B1FB4717726E0182EFC9E9A07568871F9552DDD1C986FFB24B88F9EA5E591B07CB8A3E207053D3547950A5DC042B44341F6D178975A9BEDC001451BF7FB6CC4BFAB92972CB5E4217E28A21B8664C6C405C642A6E6400973ECF0F3FA7430936BB58F7D62EAA15F469577CCF957459687ED56713450913641DF199A0747C840FAB4E2B5F7323AE1E736BA0DCE06105327168A457EB1CF4F4B6C5E89D95DE5D9C65A6DF684812D00A22E4890F18EDED894472EF37DC078ACB3BE6997E0E4B34A6D3475056322E3B19930CC5C3482051DD8E9EFB5FE1A288EE3D9CCD181B57D41C7C66BA732707902CE5B9806F63621FD064F387FF413031F04502B482BBFF950BBBE9E854F8E58770A55CCEE324FDBB830FDF4CB47CC579FB49CC092614CB5789239C96D281BF065326B8F58F006BBAB07602C0657A616300286D89C5FDC2CF0D2E4A43152198755AD777C23A6DD8A9A8E64832119D0818CDBFE3CBE8B7EA5E2739E54790E0685203B2CFDF8831E339968B4770EAE40CA9A0723BB1CC9BE0FC4CBCB91A29514418FC04CEE2CD852A222A131927059AB5233FA77E8520211F42BC91FFF9646EA95434A2E867F8C0D4B43FA2E7B72B6C0E2AB72CBEDA1F8538E20FCE37FE6E0B9C4E03A9091A1D7F7B081B2B220BCD0C686729E2CADF8DC00612DF4A8AEA565CAA001EAA4F4309093ECC4FB9FDA290EAFFA313C3796C72F57EABC1CD4FD58E272C9B1471A3806212385A4C4\nss = 2D26F4DA925E01CAAEAF4A89F5CE81148A000F7A36DFEE74E059A933D973DDBB\n\ncount = 65\nseed = 905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B\ngenerateEntropy = b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d\nencapEntropyPreHash = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4\npk = 657B941F466659FCC971C1174AA4459551848E7A116B751E5E4022C8F2A4B3152A1B26A3096539C9B0BD6A435EA1E33413AC4D5F401F5DE8570CC11CD4BB9FAC473328D55501702743E2C8D1B97CEDC8AD3D55B67D284158EA8BF1A4A8A17A9DE6D5669E8B9571200B05300CB30BCEC4A58B06F70830C2B32D28992B70427781854456129CBAB53A7C72FF557193D3A221D06177D002095BC04E993B8606245416C3B998B01716AF3B43A535F7A6BEA71270B34EC808CA00E9453AE660B732963BA634F14378B1691A90E3708125CDE31BAE3D10451A5643F526CB790A8D6E091A725681FB539E9B05BDA7B04C48A31B39DA6E39E6BE624663B6284DE9F958C50149CE4090E6A486B68511AE90A0F093297BF090DB3C81D34400A40CBE11D74271E23BBB7A49EA875EA7F7CC25516A899198362ACC52C8A8CA14BEE12BBCEA9A6E3509B6887A3D1D4C3B2B4314C4C44F44C96F48B29A8E7B85339037ACF131F2692B7E7A49282237C8F37267C835C24883D1A189D4DCCB7C6BB1FE622FC31301A6D3612A448084E0A210449B7E15A4FD84A9A538B2D5844DC170C911FC1282BC513E8C18C469A01A548D1CE4853128A03A8B1D369B353C3003B0A29D210AB6AF23ACD010AE3671493C774EFAD8B3746180746401D0E5862A3265E7969F247C954955B4AFC13FC420143C10263EB1C6DABBBF5A8857A7F3BEE7658C8399503C21A9A38BA554132344E214CD2036C2B30D0770CC5DD87ED9B246E7F955EA926965748CB9E58351A938F7E4AC249CA5C970CFDE48C0ADE051BA873D36A581E0FC50D9583109A79549FC5B32BA432444046AC0A66F3C64AE1498F43B1B36D8082442B5AAA7BBCFF2C4CDA8C0C4D2C62CF9135A75709CEB5B82BA4EF5716C4986A36BD7B4AD5C3A505869FD34AEC2D7CABA492F4BC30D232382B2651D5923242BB50DF87092ACE5566BC5A18FB2925CAB467B641DF7B5B91142318D120456245F2F0887FF13516D23216637393C469CE1F776CF2426C6577844CB3D4E0A92ABA85FFB59979A7C33EAF51EA2BAC9862160BF8A85553A3D4EDC05DA102106F632C91B8D1DF2A9B2734185283941EBCDFD788107B307738786D6C0A0E7D4957DFB17488C5D6CC11B83E3504EF2923034A06270563E18A18BB29F48C36A64C132AA626DCFC5A615E4416DF76746673E500186A117A27C5007A4B04867213C33739E27058ADB23C0DE35CE6158C99E59B88B147E2AC05F09F7C0A414C3240ABAF65C24CFDB6857ECA66BFC58E52472861BAB1E03CE70D2115480B443A9BF799379AF9AC978D0072F75BC7923816A189DA5974ED948B8A709A8191CC9BE60AC2A383A7E27CC62543A2A0CA9EA6897D284AE79B595D0893514F75DB35C9254B7AC47260785C1B86A98A5DD733D3DC2B947D148F698C5A117821847604151068412268169C86D50BE92D77683386025704575177AAC0B9D3D3196A610985E860E2F799F480B1331BA346DB0C379CB1833223836D88FD4E11DBF2985825C78330658B9A189233BC76B172127BC7A98E6C644D28DA7B0857F67157AE2C27659297C32A7EB653697A295097A32AC235A11887388265ECB3B46A75C865C239395300D0F8152CBCBA77B4D655C9F1EA4B448FBE32C4996FC298D26CAE25D276BCF6E66BA65E3E97791\nsk = D7E3338B3CA1D6118B7485BF85AB9E8F6C36E158B67D2C3530B0A544B8AFAA0A8604710987429D0D1B1EAABA8F06422E992C475DC4CF909061EFE673A3547575E8B00BA47D5A158C22E6B2C280B3152165A5A01A43D801E96791B6D99C92C0B0602C94C0B13F2672146A7044E4372C5FA884", + "3FA7974692B0F292AF9FC3B5793092C705421E6AA39B7B3EEC76694F5555985A94879ABF737949BC33CFD1F8563565B2F345B6B3389FE061509BE046B3A048A73599AC20466F0707E9B46045352F94507659BA428CC6994EE3375B07D09AD3BE1872C15692C7394626CFC01BF5435D7922BF9199533A22CC4FF021A97C571DB311485B36E2A3344EB880C67819AEA18B09919FBC57CBC11CB228F8C24F38A445C512245C3A5CBC65D20269EE849BC268899981B9F334704499B60A891139D9470A1A147F38470752C4EAEC5B14D51817FCCA22E7BC1C585CD2189131960A9E9284AC7940B2949707EC7A67F22DB280775D8163394A3A9557BD48F50C26F177FFE83030A3455DE1196A763F8AF156DF73CE3BD07AC70447573A79DD04A59E8B40E39C6FEA736E14F1B1B67B5CF556C3ADB29FACFCA4E6D8B759D37737863DA2A7AC4A645A8F202AD61C17068385C21415F7E14146D896020B89CC73AAD60135D5A3B94879184E086F1066A9F56041B6029D1F538FB5B18A7A741E04E2C158B69927A1A7708BCC411988C0C315D0D1BC3A31B0CD473FCD3ABACB1BB3EB23224379B5350081EFCB8C45584D3B845E2500420453718AD83194130983A355B1388BF246B9FE7400443C52629812FC1125C3800C3F824C0FF95BC24A2E8B306D5E3278FFFC585843BBFCD06D2EC3482295717A5111AA7B6475040083106A01491CF981197EEB77D9B01C2BE476F07C59CBEB5C4D19A2000D61546A9CC149A149BA8E57CB0ECB3105D94715C7B1BA7800785EDBA95A7352583354B93CBEF98C78BFA946A7431813EC36AC45488B170859C098B7C6813CAB2FFB519814C3A9DE3C254ED7A144FB6D15B183CB48A9021972233382FC8C388511ADD6A86837801F4BEA0DF0103B3A152648BBCDA68499352691BE0C3E5218A7C22C8CE49790AF1BCD4F6717EAA18CB489B446D24F5CE239C79A6E34215E87BCB8461B5B509C895EC22F94C17C3BCC5904D968C469B200D3322B423761E3749556476D925A915971A62A5A330ACBD106AD77DA7897815CFA31CD44310D44915D762164B6170B2916B5427C694FF3340FB16B73500E92833ECC35BB25DB6E652701D85AB215B366A173604C2797C2A9C420E069E7E4B3D1120DBD1C196D105211134478D23CC4428F8F56182FF3A51C7B84F01A08BA157E86B9374FB7C2E7ECA3D4B65F4A73472E38C6F7C06883C99C4CE934F9B04436D250EF262C42D4862B90C11F4924087469210A25CF4CB29D139D85D9C904004CB246348C60736D707B2B9B111C91ACD3937D9E8934032746AA5025BCEC8BF637936448A0DD67A27DB2A74B60BBA82BCC87D73D4A9033C427A85883613EDA43829C7CA3C7A8F24364633610D8199A5EC8038D0B6686ABBD47692ADA94282C40799ED4BF8ECB65EE7C8B2047C41EB255318C139B89CE909831FE3024BAC10B4110CA34F1BD657B941F466659FCC971C1174AA4459551848E7A116B751E5E4022C8F2A4B3152A1B26A3096539C9B0BD6A435EA1E33413AC4D5F401F5DE8570CC11CD4BB9FAC473328D55501702743E2C8D1B97CEDC8AD3D55B67D284158EA8BF1A4A8A17A9DE6D5669E8B9571200B05300CB30BCEC4A58B06F70830C2B32D28992B70427781854456129CBAB53A7C72FF557193D3A221D06177D002095BC04E993B8606245416C3B998B01716AF3B43A535F7A6BEA71270B34EC808CA00E9453AE660B732963BA634F14378B1691A90E3708125CDE31BAE3D10451A5643F526CB790A8D6E091A725681FB539E9B05BDA7B04C48A31B39DA6E39E6BE624663B6284DE9F958C50149CE4090E6A486B68511AE90A0F093297BF090DB3C81D34400A40CBE11D74271E23BBB7A49EA875EA7F7CC25516A899198362ACC52C8A8CA14BEE12BBCEA9A6E3509B6887A3D1D4C3B2B4314C4C44F44C96F48B29A8E7B85339037ACF131F2692B7E7A49282237C8F37267C835C24883D1A189D4DCCB7C6BB1FE622FC31301A6D3612A448084E0A210449B7E15A4FD84A9A538B2D5844DC170C911FC1282BC513E8C18C469A01A548D1CE4853128A03A8B1D369B353C3003B0A29D210AB6AF23ACD010AE3671493C774EFAD8B3746180746401D0E5862A3265E7969F247C954955B4AFC13FC420143C10263EB1C6DABBBF5A8857A7F3BEE7658C8399503C21A9A38BA554132344E214CD2036C2B30D0770CC5DD87ED9B246E7F955EA926965748CB9E58351A938F7E4AC249CA5C970CFDE48C0ADE051BA873D36A581E0FC50D9583109A79549FC5B32BA432444046AC0A66F3C64AE1498F43B1B36D8082442B5AAA7BBCFF2C4CDA8C0C4D2C62CF9135A75709CEB5B82BA4EF5716C4986A36BD7B4AD5C3A505869FD34AEC2D7CABA492F4BC30D232382B2651D5923242BB50DF87092ACE5566BC5A18FB2925CAB467B641DF7B5B91142318D120456245F2F0887FF13516D23216637393C469CE1F776CF2426C6577844CB3D4E0A92ABA85FFB59979A7C33EAF51EA2BAC9862160BF8A85553A3D4EDC05DA102106F632C91B8D1DF2A9B2734185283941EBCDFD788107B307738786D6C0A0E7D4957DFB17488C5D6CC11B83E3504EF2923034A06270563E18A18BB29F48C36A64C132AA626DCFC5A615E4416DF76746673E500186A117A27C5007A4B04867213C33739E27058ADB23C0DE35CE6158C99E59B88B147E2AC05F09F7C0A414C3240ABAF65C24CFDB6857ECA66BFC58E52472861BAB1E03CE70D2115480B443A9BF799379AF9AC978D0072F75BC7923816A189DA5974ED948B8A709A8191CC9BE60AC2A383A7E27CC62543A2A0CA9EA6897D284AE79B595D0893514F75DB35C9254B7AC47260785C1B86A98A5DD733D3DC2B947D148F698C5A117821847604151068412268169C86D50BE92D77683386025704575177AAC0B9D3D3196A610985E860E2F799F480B1331BA346DB0C379CB1833223836D88FD4E11DBF2985825C78330658B9A189233BC76B172127BC7A98E6C644D28DA7B0857F67157AE2C27659297C32A7EB653697A295097A32AC235A11887388265ECB3B46A75C865C239395300D0F8152CBCBA77B4D655C9F1EA4B448FBE32C4996FC298D26CAE25D276BCF6E66BA65E3E9779146FE6C37136273736CCB11DF5B6D55DEBBC087DE802404B72A003C5E8C809719D7E4B5D8021C486B9C3114D7CBBEB7CD49EBA8A61BC2BCAE1F1BEF30A1DAF76D\nct = 1D597DA26AFA055E20E20CB3DCCC730B73075CC9B0C01499A4856D0218E744654023B54734E6428408884C182AD6AF6B2FD3CA2F245037F7F540706C5EF18CC520FFBD5CEA84D308A4BBD9999EFE0B95B1F599A141C383DF89D2BEB33077CABB7B10F332526B1AC199576799444B86377AED9A18D6CE0C94B157DB14DF2BBB515464A622E32661CADBC9E6ECFA9733635F3847F2363E58F7E994563375D4E4C0B3174A84AC0CD4408041C4A11563AC5195C1DA47C86D7B88E7323B5ED66D3850A04A348C46BBC627F497B49E3E1D7BD8E23162AD8C232F750D3FBF55C267DB2D9FDF0854972E8EAA6898BCB21CEDEEC79B6BCF494FAE1D6B174779C3F70C27B64E196EC8E8A7C861CF75A5C62AA8A71A7677B995F16A8727BD5E1BC0FB2638BCC864CB1AFA8F793462ED0AA445592E1142CA2FED5792CFCAB5F6FF8E7B7A335043AF926C7C0175C92899EC0E3D2B5BB945334A4379A3533FA1607F6406869191B2F4472F9742AAA9C66BF9A843AA4DDD8F32F4113412CAFFE113DD80C55ADA924D5EF5F5D8E2A7DF5C764F53062730764368589B76B5C6399A8674AF24C02337EEE30E1FB44C8C9AA85F72BF07A61246043B21032FBA0E675A1D1B0C4284228E1EA990FF7803A1992C53D0BD85FD3A4D753DC1F9E1B873D64D5898B78C7DA9F72969D48A433F5AB9766915BD24E9BA07170338EE670B77F68C204A68AF32E3B6DE3580A973872BC756B5EC976A393966AA452F5757745660A15E4E2D4D3E549E99F309E18774CD74F73D5D4572C3A0C49FAFCE2342F1BDAC88D35D22E8663E27470F5691C150344508214F0B0F9F57755AFC52F5590615C64C06D4D611F6920CE7D0F51178DBBC906D71947C1DBBE1D98A7433860D3D21C2E83C4C3EFED6A738CFB48304746E5A7CB7E32CDB8AF44AB7F09E98EBD18B8B4606EFA2C646E37C6123B4FBB37E3DB5C3AAF550A536B1B86B47AB17865E6AF273628F3881937043A56FE323B5368B021F3723ACA9A3937EBA3828ADFB9873A3F2D027C9264B56FDF4CB608F5451EBA1FB1EE4734FB5B1D4ACAAF29ADC1F376D23E45D188D4086F4DC4942531DB72E586AD70350B04036D63EAFE4234FE90DBD68D83E91CBB0F43CD87A8BD3CD5E6A6C81A0706CE2EDB2C9C00ECE4F86D9B82157B4E82BE4C6D655F2BD1376DE64410D0D77CDBE737D8DF1C3751B0B33D1503B1354E70B5A6B3BF5E21435FC575FDDC26F9B261B19DA5CD045FE041FC6C35EA7A4C1C24307D2F4DF6DD6C5D4B211F0C5A98093F7E05815496F0B3B7A80E0079F0E60C5393A6E9079145137B2E89093EA7DF4336B40DE06CFEE5FDEEF322770B114729342B1A24892B0C759147B08275FFA24B5BCF679A5B404B292C818DA88631919A403110959A560D81AAAB2BEBC33F796E2F179CA5F25D3EA7C7DE3A310ACED8DCAB766E02E22AE9130D963DBB3EED2D0316D26F25AF53FF23974CAFCD2543B97F8B13ADF08FFB687926A51403F811BF3606C1C73ECE86E0A724B9A15325278D6F2C6481EDE68FB\nss = 5012217B85A1E5DBA62A2476D7A441411D8ECDDBE2D3A291F658B7DC1D1197E9\n\ncount = 66\nseed = A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4\ngenerateEntropy = c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643\nencapEntropyPreHash = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384\npk = EB9B77F8C16DCE72611902A8CCB81E8CD4C5A2FB1D8FC30CE226BB45779F41073FF3EC0362BA152102CF45D3A95874A551C14C8A621436E248FFBBC4CA3B4033D50EFA392DBAD9C339745803F845736C30BF309546229EF52788AB223758C03491F62913FB4CA4307DC6B4C7FD9503A701AD21671387CB2CBC728ECFF4641E312779C7034CE720554A948A021751D4628890CA7367611D4B9F269C5CCB2381F1F6A01B0634D9C5C954FBB934E4144922CCFA2035892C4CC2A8457300946ABA4FFE77868D34C7A90507BE43748A366C49D0A927E66610A08CD0152A2C1BADA92A05694B6E3D2610ACD4579D5634FD2675F2101290E2BA1855252B57A438B50FCB854EA7B6A89B109EA9857C23AA38333428B94CA5A524977D72077B56978328C18980382EBC967DD37E6136360A958D5F00C3B9996DE3B97B6468B9F98C3C50F37A9E73AC8E8364288347D9B018D437B3B065C120D26E9033078B5838DFC7CE68F244B32C5B4AC04DEF068F58FA733E99A418176575EC2BA0F78D4C402D67176DB5717023B57F8D26C636A11F49B926D20B277D2613941C3E786B1A9A3C1135993BCE22A1DE16434A5902C0F101993B65777399828BA52330A2F356203521A3C59B6007C3AA41D198A8232D27C05F8E0280C9076D54D5AEBDFBC95C7C06BCE24507892641F90D2B774A2D98764C42BCF009799432B706DA59BD84", + "CDE4892427C0586929C99850C7D769AD9A221C85A4062A62B2A1847454554224C4CC47898574FA66D147C4AEDC59FF612F49285DB54170508C89E6787A8CE6515CEC673D4545970CA8EC486802933E319800FBE46D5CC14C8363656DAC0600D895FE383FCBC3614FE334CAC0A94C185B73DB30CB5A56A8D04CB271B13859862F164F980625D78AC35ED120605CBD69E6410EB05168819440816EEBF8CC9AD153CDA5BC2EFBB00A7563A55856711231CD12873A9A56996C174AE43B5C172A1445BB40CB3DEEF9051035B33214A61E26852EF3BCB3FB319E1B4D6BD832D6B9BB54B6021D180881D59D2458564ACBA148B0AC36CB501CC8242919064EE24343F26A87A0696000533A20943445C72B9260B4C8A46A1C921C582600D978C5370B400B2412F73541A13BA0349E66FA4025735CAB6402AAC51E08A019B48115C49C665F415244FA91C208C6B1F2BB02BC18C47A5AEE366EDBE3BAE1E41A8B405DDEAA22A2FB254A6B70DC5A16C0217E4DFB933A127039B788E6C035DF8993FF86923500BA466A81D34A0ADA271DA4262F33123A1B81A13621211845A167449D93370BD95A89725A56A8452B510A7FD2642AF41A4A7856ABD9688DD7C85433A868103679A8EB2BDFAA0CB52CC141267E91E2C1E57162C6B4897C9004A3D375C1C8BB87C5AE2CC80C2A107E0F904E5BF8065AC96C9152AEB07322FA181A83A9CBA0224C9FAA0F06CB67E2787EBA832D3F53AC60B7B014D28945361759689C3EC65F8B885EDA081443A2AFD2A735B1C57C201AA4D273B1302267E5A63ABEFBCAE8E1B2D3883439E2BE2436382EB9BD62146DE0E446B6E2BAF8300575091DB145A646C733BF352989938FDD8003218A607739C60DA6758BF448BF18A22630B08AC40635382E3BF86D16625C45E12EBEEF4308B229C948D425016D674119C0AADEFEB21338BA6CEDBF7DF723\nsk = D338B8576C1FD9168551A681F9C590095B6B8D8474F571226A4B68EE81A83738BB964356EDB663D925960388C92896029A201EC7F046CDE497E3384F613A444634AA3C41656C6031D5233720241603612BEC1032AFA7B3D41242CE374C8B118CF6219FB5E645002530781CB4660403F88287D115BAAA07CE95496A7232862282A653367FBBCA1E337155A3C8905E368C1974418E735F93B6965FEC11CE7B43D81710D727A4C4B434003B9110D013568B7BBFB341212543031C862FAC505944B86394554772047B2A864A6675ED984583269362759CBB464E7E248A48C3554B8054ED9342AEDC8E221439F812697B691BD5C89B7FB11EC716BFF96C97DD73C45B00980BC6B1F69117C2329386518058E97B26626D98196025724BAF0C5729109399E035ACE9A630CB6D7CA9CBC16AB560DA5C01E37601BC0DCA7A3AF891B80418C0056145C7AC8C176605411A39BFE843CAFB4FA61463B20A504E984308F2B82CA7081A97951D0961B2664E2D7B41DF902571D02C1FE24EC0EA998609248CF51CF2F81D96A983DBD29BB37B9A7D559C72FC0BAAE894583A842FCAC92D910C7D682DDE70A4A7B26E3259B290A182392CBE36B68D2E321708E9C00D8C06DCA5043C1A461E76438B7801E8FACA17045B272B16999471F8FB42F53A43294124C3B2B7F7A13EEE8B195A01871909A70E41A0CEDB37F3F733EE259F40C1CD12C79DAF90788D78CEAAAB9E1D20B7FF8800A17AC28953A4E90B257D099DA195B6701A695195BC730389A84A499AB784762631935A5A974398C6988A59822BC6382B9CDC6072F0A6CF65C9DFF2309D1A433AC52E6CBAB472E788F76558D57986BAC5C79B921F06E509DB18C70EE88AF044B527E221E5A5105A19610F059FBF6009B985190AC81640607CC4FB69D4892B5D9AC12BAC26765AAD5C874FE3080BEFF77961CB9E747A8E4B4ACAF3F3B81D51A4A755AE8EF2994E8A722DCB5B8014C1CCDC6A79046664C3B75C02B91E0B4C5C250B8EDA5D67E9A0984A6052053D22266B2413B98D841E8AA686F4E0AEB8D5B2ED2C8BBDDB0374D0AD8CD47A0E6945F0AC352307AC0DB224EBA29BC09397F05B1308828CD42B85C556BF0A938959FA7CDE083D3D0163C21B016133145AE0C47EF73604999E76F9AD19432F82E762BA8174F89A23D09333F7E677F33BC15BF996AE6999ADA8747BB0C454412C2B651D2A90382937427EA555B3856D0250AB1E3663B8D78F3D96CF9EB90B5A501129715DF5DB38086076C4B351305A9718903ABF12609FB1BC8A59162E2152F8E0C62241CA5DEB5260D71AE162B7EA827A342584576B00DC674A5BE149C7744D7FF43A5B04A3EBD38C110630FF656F2FF042EB603403D14F18EB17CF675C995C2790E936CF8B60E758484BC04314E50105B28346829077AAACA72ACB46D331E9127B17DCAE5E639D2B33B9F3CCA468F731BF0B332BA41D196AB77B3C436702078730369CF59144540EA08B5025A4C880C1530F40A852E35F96519C91EAA680D90D25A4256FEB1878B48E39143CE43378EB3335D3E03F2A358782E0B54AB56860148DC0FA5CFD149CF26A7260639A347AA72B977B6F38BF29E1472C26B4D7F80E4BB3192DE06EC05A6AEB9B77F8C16DCE72611902A8CCB81E8CD4C5A2FB1D8FC30CE226BB45779F41073FF3EC0362BA152102CF45D3A95874A551C14C8A621436E248FFBBC4CA3B4033D50EFA392DBAD9C339745803F845736C30BF309546229EF52788AB223758C03491F62913FB4CA4307DC6B4C7FD9503A701AD21671387CB2CBC728ECFF4641E312779C7034CE720554A948A021751D4628890CA7367611D4B9F269C5CCB2381F1F6A01B0634D9C5C954FBB934E4144922CCFA2035892C4CC2A8457300946ABA4FFE77868D34C7A90507BE43748A366C49D0A927E66610A08CD0152A2C1BADA92A05694B6E3D2610ACD4579D5634FD2675F2101290E2BA1855252B57A438B50FCB854EA7B6A89B109EA9857C23AA38333428B94CA5A524977D72077B56978328C18980382EBC967DD37E6136360A958D5F00C3B9996DE3B97B6468B9F98C3C50F37A9E73AC8E8364288347D9B018D437B3B065C120D26E9033078B5838DFC7CE68F244B32C5B4AC04DEF068F58FA733E99A418176575EC2BA0F78D4C402D67176DB5717023B57F8D26C636A11F49B926D20B277D2613941C3E786B1A9A3C1135993BCE22A1DE16434A5902C0F101993B65777399828BA52330A2F356203521A3C59B6007C3AA41D198A8232D27C05F8E0280C9076D54D5AEBDFBC95C7C06BCE24507892641F90D2B774A2D98764C42BCF009799432B706DA59BD84CDE4892427C0586929C99850C7D769AD9A221C85A4062A62B2A1847454554224C4CC47898574FA66D147C4AEDC59FF612F49285DB54170508C89E6787A8CE6515CEC673D4545970CA8EC486802933E319800FBE46D5CC14C8363656DAC0600D895FE383FCBC3614FE334CAC0A94C185B73DB30CB5A56A8D04CB271B13859862F164F980625D78AC35ED120605CBD69E6410EB05168819440816EEBF8CC9AD153CDA5BC2EFBB00A7563A55856711231CD12873A9A56996C174AE43B5C172A1445BB40CB3DEEF9051035B33214A61E26852EF3BCB3FB319E1B4D6BD832D6B9BB54B6021D180881D59D2458564ACBA148B0AC36CB501CC8242919064EE24343F26A87A0696000533A20943445C72B9260B4C8A46A1C921C582600D978C5370B400B2412F73541A13BA0349E66FA4025735CAB6402AAC51E08A019B48115C49C665F415244FA91C208C6B1F2BB02BC18C47A5AEE366EDBE3BAE1E41A8B405DDEAA22A2FB254A6B70DC5A16C0217E4DFB933A127039B788E6C035DF8993FF86923500BA466A81D34A0ADA271DA4262F33123A1B81A13621211845A167449D93370BD95A89725A56A8452B510A7FD2642AF41A4A7856ABD9688DD7C85433A868103679A8EB2BDFAA0CB52CC141267E91E2C1E57162C6B4897C9004A3D375C1C8BB87C5AE2CC80C2A107E0F904E5BF8065AC96C9152AEB07322FA181A83A9CBA0224C9FAA0F06CB67E2787EBA832D3F53AC60B7B014D28945361759689C3EC65F8B885EDA081443A2AFD2A735B1C57C201AA4D273B1302267E5A63ABEFBCAE8E1B2D3883439E2BE2436382EB9BD62146DE0E446B6E2BAF8300575091DB145A646C733BF352989938FDD8003218A607739C60DA6758BF448BF18A22630B08AC40635382E3BF86D16625C45E12EBEEF4308B229C948D425016D674119C0AADEFEB21338BA6CEDBF7DF723A074ED1F76E97D68434BA4AF2AF0E549204222679E9E643580C35AF3CDD247CEB2DCA81E3F5F748D23C9D356A2209F6B2D60247B2E45C9808DE497F64F124643\nct = 62A20A2BA68C9FBC4E9AB487FC36DE9C902FB6E2B9D42A040328B8798E9C8115A0C4CF5F39B0238FE74442936D0891172D6B97C219B4AAA3C628AFE98C56A33070859D5BCA5AD6338CF9491FE2DBBE4F2993F773D5A19C9CC70CE7364BBCAC0CCBD1723B4234265F4C643E425411F3665B7A2047E1C8E07C28B8CBC548BC4740903DFC6A7263B6800DF39DF6519720A9D1D0F7C9B239EEC124FF99F5CAAB64715E595CA1BA9F6A81583F4825FF9E32711AD3F741108A6888905B79DD7342B903488CBCCDBAA690ABC5E49A2534C8CA791B729E116C4304E55BB636C0331BC9C1520A1667356C4698D7D5CD8DB4B8C0CCCCF770405C056FA881558A2E6E1932793252A3CB7C1AE07E7135597E0B8BB173E7544CDF583EE8B33E24756EAE89628AD34C31C5C66590FD2D037512D309A2DE438FA13098A64AA0955A4F5460A8F19E3F1DA1E8EB7BF3B56F3E685E685906818F030B7FBDAA9EAD26F2AD8EDAE76006835BE6A5F07219451ADB37D8ADB356C4B3FD07DDA85579369071FDD5214EBE2CCE89819C316B0F43071367C6EB871947DAB8A2FCD14E656DC27F7A9E8E2596E6479440348A661E31F5A1AFF7347CD890DC3B9728762375E562788BE050748E6E00343E88FA11B165FFFBAB52D2C9004F63526B818DD4128AB69797A661731AB37534E0FE4306F865A353FAFD10B18A7E9438B41D9A9105A52292AB0488F2417C2B2D9A0B74D688F2BA3AB686CF4B08DCEC84C603AD326302684E2768AAFBD1BD7D2FDA5AE14664E287A1F55734A761BC363B91E31F5D5430992F4A6A377930623329FF9169A03736DFD875623A034D7BD4178CD01DC84F6384D6D001BFD22A543E1E9DFC2AC0AAB237FCF8DC7D4D7B3DCA4C00EBB191DD5C24B64B7730F7F4865E8DBD9739C8A374FBCA4DF0A99E8BF3EB0B7ABFD123CDA4DB5994AF01F3FC416A860C3F012C2BC6038D8AC9186ACC89E61F9B820F226CC26B5EBFC6DA09FA5141A1C8B2C2BA3C9C7F8975E73E825155B70FAB089103BFE2D3DEA873FB566E7C70E78CDDA058FC8EE87A58C98986957F5B5C6D25E33C856CE0E5A79F4A9592E223998C34B8459562D0712B7762699A382B470BAA29B4A7186F89F603F3AC17DF82BC52FA30D533DB99E1884B5D58DB45F0B5BE099DF8F27B7CFF57DD5F1F38F58345B43268A24D2B97F8F05334D0DCA0FB01F6F0E271AE002657887A7BC26A140D8761765909253D625CF8D5C3B16F27A9D055E5E4A055DB9E0F5817B9F64B7122D14EB54D3B2881F70D89C07D5D3150F8273731B245A99689B2FD31D089B3D7925645732C890BCF6058EE829A7DB67C34D8B6E0CBFCEDD73FDC7B83A038B5A044C6D9FE947C2608A9200EB21438BF942E66E0E3786ADF6B624FEA3F86185D84C0BAC24FDFB8956FCE2DC60E62721F89F2538503", + "1CC0948247E5EE3E6DD849474F4128409363C99BF4035CC43976B9B0EAF70E464833E99701D6708502037E5967490CF5D94F05E62844A329A36F819EB4ED5F93769C99EA65B57CF7F542E36B\nss = 0DCECAC51C5261E34023D2E04146CCEA10A0B39AE7EDC50736127184FECFC8D8\n\ncount = 67\nseed = 074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0\ngenerateEntropy = 334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523\nencapEntropyPreHash = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302\npk = 9BD11C902A159F41CB5395BE189B1B7E98CC23658DCCC7BF9A843A77B2A6BFA27BC941B04F391950D998C607A59B49330811200B38B243060B55E381C078100DA84975091F3A0ACB06F22AE3FB1B7D756D36F54200A367C109B13CF40F3671231D5B0CE9E5908776768767209F4726C54277D0F8B0E05BB4CD50BB5547A01051C89ABC4A352745316C8D85A3187D68382EF05DC96294446972F4C76C7B9B91A4BABE06FC634E76AE4B778F939C308F22B8C816BC3FD6B48E168F5DFBC19FD8CB7E4686BF2325CB060638C723364B27C8E3123FE26CF9862F247CC31C844AE77754206B03B497BB3283CC7E38664B23771F709E1D308CFAF5086F25ACBD04CBD9F1612ACC2712D129C9C195BC024CB057B0766AAE7B533E60F04D947947F920470BC37E5EB4AC4FA1C48066877B4456D4EA2A5EE089DE38A7FC7573FAE5480BEA823727132651A85D873378CB97D6F7BE1250A94621ABF5EABF0114952665CD2A5005AF338B36D19F6E4C8F77E2CFB6F24D3CB7A909315A026B5AAD50A9CD4BAF3308059A91323B1C226FFC76B3565CD9386592476B76057E3477C8B7CBB201CA91546A2354B59328D411A724CBD8B3689EFA335D879996FB0D1D2244EDB361BE4B2489E84086F4A995F20FFA9404082C4E66061D3EF668FC155BCE04916C92B8FA46B77A4A9FA82C8C0CA5A5A5245883D25FDED230E74B22394169464BC33FD51FB7F2AA9214B1ED546DCFD00AD554AEC80882EC170C6EC44794204170D738EF9341D6034920A7AEC3B68FAC00527B2812D88969C6207F9AA122464A4D76320EAD6271D2836E574155310A756CD4249FA7474B301CA978A0653935B7740A16C50DF1EB678C1BC3EB451CF6FA35BEB903CD89CDE0AA58A43BCE9CF591286792FB3B5E658B5A32196EA24A4252B093D2AB40884C39A4ABCBD19B108B81172E18A84A288AAC2982D113454335423148168BB6B9D97494179BBA1EC8760BE59D06251B94B4BAAF82A6481C4A8F33B0FC3164635452E6497F992308688352CBF44537C618000536F9C41A64361EE162236F9227219B8B84A3984C649EA82211207C974F6C7575027AEEF57E496A58CE2719096A58E2E31E82844F4D674A4CD9CFCADA79AFB0C63E634D2514BA4D8604CCC42B2EEB64691AAF23727C93C4ABE1423C27B3B7ABF0B649334760056E591C32FE812A753723F7C93EF5524C8E0267DB177E6E55620715688CD0AC70B2A90E133CAEC86945BC74D7EA1CB88479A37B45EAE4993BB7048E5316BF66B9715591148C9A20A35412C2404BB62C512B3800B9AE104453D95ACFFE000D3AE85B96D8092532796A03039BA2154F84AFA4A402ACB673B8799441BC505E836C3B558E1FE2057FA79153E1630D72AFD96AA4FE9C0ED4822AB33A559719B81D274EF0A2773E405761A036521278DF5AB3617CBD89D7543CFC7C6AD373B2D0B781DC78DD3B2AFA34B6565979231681FFFB8C62843DCD11686EA59406E23CDF96AED95554E47027C5B6976F5515BC40B0E3A31C556219F89B73C0871E1FF552CA04C33DAA4A363794CC7C0E05249B53D20460EAA8AD217787C8C9423A7EB71058B5A8081B82454DC91F77F8608D60CAFF30A7C42424542A1746F0F10FEB3F0FA52EAAD4F2D4C36E59CA0A5389566FAD53898992A17BBE0A0F\nsk = 9BFC3A71FA83A4070DB5064ADA8410A770845E818C49B91E09A251E1925EDB226EE8AB153F94B2417560D88959113A6BBC854B0065748E6A7DB90977ADA0216F3C41CFF70E5202B306CC22FF8A138C360D75B9CB1BBA849C5BCC8C9B55E80647E513C9E3E15F66A144F013822DA24266765E3F1125F435BDA4C46EF57430EAE331E1D54C91960EEB363CA25387D0D441ABB930E4A7C329191C5FF7A87996A4B1AA74162611E67B303E284C7098A65069356B55304B11B8BBA66C5829647493C09BF62166017977A988333092EFE98D9C13A2BCE53F8EA2C81A0099B7D5C2B11704971366A5565CC14610DF796C604700680226CB165E9ACAA6AB507A923B4D472A4B6C9424E7F5A622F87F4F8A1083B4755067A93C285CC0748D241C7051971128CC5AF4DB5C1F7C144F98B6BF9703F5338628CA22DF4B84D10312EDDA9DF71442464A24491A62687928C22455DCC23ECA964E9248543520790D813924CB58A0C156AAFBCF63906EC5FA891936C7E16B5FAFD98026D64EA2012BD75B6C5F376EEB74AE9B29CFF7041C650B91A2B852C021562BA33B66EBACF787BE40810F22AA43F4174571C77710F775D1719968A5523780B613262F94BC36B611B63F460DC6E02CC588AF99F164302276B0386E697469C55928C0E62438C25AF90577DE0883CF45819262905ED30D9A1A7918B82F9B4A28CA5B8DD1D9AD4326ADC7BA69C087765CC6511668CC0BE83D510245F8834E890662E06774F389C0C623BE3212AAE5ACCEDB101C43463B68889EA9A2C21AA0ACB5329FF80A336F8914FBC602E2B9AE452647777651CCC4BEF70AC06423B66EC5982C861AD9723DFBC834CA6A6433174C1D6C1AB9569265A96AB5D48495D72122763B3A7275B297713F1A729BDC48329B64FFF9C45955C6091375D4D77FBAC540DACB140666610EC7A15FF18BC741AA69425508D5CF682BAFB6D3C9DFE02D80349597F56FBEBB7EC8031FE71B6D6C065C4E6B5E5D17ABF3B412DED81EFCC8B6B1935FB37B467A5CC61F318AED20678800726509BAA73BBA244030500050D4B23E4AD71349CB0877566AD100BA77F8B409BC8F0EF8CFBCFA3CD1BAA1935C9ABCA798FF6965EC7B53141B6709597BC4F9983766403ED80DF4095D59AB482FAB7FCA432EF5E76AFFC77F74F4CDA522A0085A4917D04167A00B09863850D6CAA0621C2D473DE0763B7D3168B6147BDB009EB260901FA82013C8C0A3F6C39DE3CC49A773D08B357EF932077B5BAB86391239B3C366C43010AD15EA2EB1E05267029E5AD8139728A907B98761B65DD6DAB895363159B48875FB6AA80882256A04460B2977280688745C5914C089B37BFC949A8F9864AFEC2E4DC13F6092070EB561D09B530EBA2CCD66B87B0986ADEA1933448066521E28AC2ED9C57EDE492799B401CDBA8377D593DAFC1A0D233004E25877242C30070779D8BC5BB488DD3988004B5A8554861B560EBAA5BFFF7C89DED193EA077F421C216996C1445B165B912901B217315636A168C0216AC026FBBD4239858837B02DAB5A39D1BE6B072468A264661C5E34F42380C66526377C990092434BCB551A744227445C5108FCFC3CB4526D0B711DBD4539CEA05A08A78FBA723F9BD11C902A159F41CB5395BE189B1B7E98CC23658DCCC7BF9A843A77B2A6BFA27BC941B04F391950D998C607A59B49330811200B38B243060B55E381C078100DA84975091F3A0ACB06F22AE3FB1B7D756D36F54200A367C109B13CF40F3671231D5B0CE9E5908776768767209F4726C54277D0F8B0E05BB4CD50BB5547A01051C89ABC4A352745316C8D85A3187D68382EF05DC96294446972F4C76C7B9B91A4BABE06FC634E76AE4B778F939C308F22B8C816BC3FD6B48E168F5DFBC19FD8CB7E4686BF2325CB060638C723364B27C8E3123FE26CF9862F247CC31C844AE77754206B03B497BB3283CC7E38664B23771F709E1D308CFAF5086F25ACBD04CBD9F1612ACC2712D129C9C195BC024CB057B0766AAE7B533E60F04D947947F920470BC37E5EB4AC4FA1C48066877B4456D4EA2A5EE089DE38A7FC7573FAE5480BEA823727132651A85D873378CB97D6F7BE1250A94621ABF5EABF0114952665CD2A5005AF338B36D19F6E4C8F77E2CFB6F24D3CB7A909315A026B5AAD50A9CD4BAF3308059A91323B1C226FFC76B3565CD9386592476B76057E3477C8B7CBB201CA91546A2354B59328D411A724CBD8B3689EFA335D879996FB0D1D2244EDB361BE4B2489E84086F4A995F20FFA9404082C4E66061D3EF668FC155BCE04916C92B8FA46B77A4A9FA82C8C0CA5A5A5245883D25FDED230E74B22394169464BC33FD51FB7F2AA9214B1ED546DCFD00AD554AEC80882EC170C6EC44794204170D738EF9341D6034920A7AEC3B68FAC00527B2812D88969C6207F9AA122464A4D76320EAD6271D2836E574155310A756CD4249FA7474B301CA978A0653935B7740A16C50DF1EB678C1BC3EB451CF6FA35BEB903CD89CDE0AA58A43BCE9CF591286792FB3B5E658B5A32196EA24A4252B093D2AB40884C39A4ABCBD19B108B81172E18A84A288AAC2982D113454335423148168BB6B9D97494179BBA1EC8760BE59D06251B94B4BAAF82A6481C4A8F33B0FC3164635452E6497F992308688352CBF44537C618000536F9C41A64361EE162236F9227219B8B84A3984C649EA82211207C974F6C7575027AEEF57E496A58CE2719096A58E2E31E82844F4D674A4CD9CFCADA79AFB0C63E634D2514BA4D8604CCC42B2EEB64691AAF23727C93C4ABE1423C27B3B7ABF0B649334760056E591C32FE812A753723F7C93EF5524C8E0267DB177E6E55620715688CD0AC70B2A90E133CAEC86945BC74D7EA1CB88479A37B45EAE4993BB7048E5316BF66B9715591148C9A20A35412C2404BB62C512B3800B9AE104453D95ACFFE000D3AE85B96D8092532796A03039BA2154F84AFA4A402ACB673B8799441BC505E836C3B558E1FE2057FA79153E1630D72AFD96AA4FE9C0ED4822AB33A559719B81D274EF0A2773E405761A036521278DF5AB3617CBD89D7543CFC7C6AD373B2D0B781DC78DD3B2AFA34B6565979231681FFFB8C62843DCD11686EA59406E23CDF96AED95554E47027C5B6976F5515BC40B0E3A31C556219F89B73C0871E1FF552CA04C33DAA4A363794CC7C0E05249B53D20460EAA8AD217787C8C9423A7EB71058B5A8081B82454DC91F77F8608D60CAFF30A7C42424542A1746F0F10FEB3F0FA52EAAD4F2D4C36E59CA0A5389566FAD53898992A17BBE0A0F26659F74FC9EC372FE18BE4ED6AA28B7CD84AD1C0F0115DAD011A11D20FDA9EDABA5068AF837BE962F439F233593D193CE5E08F7D66EFB3389885927B89D2523\nct = 454EBF31D8AB7BE6F8615035FD4F13BD40EE3E6DFD58E307AC2496B25BBB30222661AA2F65A314902C74FD897EDF3230AE401EBC263393C017195ABCF2EE916BF5B8B0A5F5AD109A7F8C049EE62C8E907719593BD3B3D2D35B0EB548C4EEC3C8C11787591967D8EFFE9C9DDB995C98520B4A9CB0A3A3B00CB1EFDE9334671FCE0D5C3052E0FDC48DF0D844C2960419B23AC63BB013BE9761D621DC41BCDD661452EC7A2FEBEFFCCC63B203F26441A366CC8C94ECC89F85404999584FA1B27D66BAD84BD997847B04BF1A594D301ADEEF612BACD232010BB54A", + "8F5C06601E1F95F2C976017D9DF439BBAA02DA479DA944A71FE08082186BF464F3EE043CAD702E5E1F38E76793F19D7ACF46B40EC3D1773183F083F85FB6B2D6DBFC42ED98E78720B11E8C524FEC0A6F86A2A407957FF6D5E4137D8E0D080080F0A9F23CAD84224F558DE68B5F88D05850B29914E9A25AF725C39299546181E7390BF26B1A058F65300E351277EA19AC971FDF2943B44F13D690956C4E864891E397A06BBC70282F229DA50403BC3E354D898F5A079F8CB1333B1F6B0186B83B5DCF264682FAD6281F94FE08C370B2C29BB7FB9F3BEE2BD3A0E408CD1A14A497AB300CB7B39A2C15737F29D3FD9566092FAB82A01839700373C836CA73805C072A9E940E7B7C8739957B7561E90F601B7C50D2A4387D89E1CBEDAA6605062CAD5AFCCE27339CBECBC1CC13B1D690892816B7EDEFDDB90116FC14C6BEEE6D991F72A749830E82E3159B1632921B776EB9B9EA222573BA96355E10140EF9A47695C9F551EF7E2ACB055E54E712F44852604A46057F84358F6C886F2440E55EC68C0ECDE354C99BF5A912C68EDD8F488468ECDB968BF15C9CB764E67315C1A5D585615CE989DA13C8BAA041C448182BEC6005F018437036C296475B83C887E87C5D560DE293C35C8E942BDBE271CED6DD26FBCA0CAC7D1600188F65F32A9B20BE73CED637FE59A24D43B7896A33E58A2858AABD699A4C273C6B2D3AEE18253238F7E44DFA959142ECB729F5011FB840CABC16C183487C18DF53386B81C2EE131DD8959E3894BF36D74B91EA2F117FCD3596BFDC34926D5598864F5FAF775D71B6F17B471AA5EE0FEDF7461324D125AEA4441A1433B908CA4D4693945235B9153A2F1B17B2EA2825CE21101521D52488AE9FBD69B6977A17DF0269AAD0F22F1670AD5D4B95FC4292DE7037BD4E90A2AB0C7356F39951F76A8746C6D16C94861A205DA3F09CD84ABD40C038038B77D61B90FE747E86E41F9CF1E4B745C88556D6DDF1C817D352AE7DEDD801AC158CF4D1C036E39EA1CD1E10A2E1BAB5115FBF61BD52CFB2ABD6F5E96CB7DF1442BFC32F0A3D011691FF429BFB73C5E978E7F349776886FED906480E945103F109FC7616EE73A2F8F0B027E87BF9F4C5D88D085751DC708E1B9E36A6DBBEADBF37A8D2C641AE45A4F31747EBFAD00EF64BD00BB5D1DB84E5F395A914979C62791607A9F9A9AB421A2243329B755DB72A6C26DAF6713711E4D65E287983\nss = 0D403F00C22FAB72899D302CB536854B934446B62F9DA6D9D6CF1C0F7ABAC2E6\n\ncount = 68\nseed = CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA\ngenerateEntropy = 6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6\nencapEntropyPreHash = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b\npk = 8683354B3C3F035586B50B88C4140F346A05ADA7CE4BEAAA5F096614CC767AF89FFCCB95124B00E8379EFAF76CA381AE4886ABED9240BDA4710DAC62A71017059B07921C770DA1CA2D209338536C3A9B5238313BCE565FB861BF8AD3A78F030B3F646B34347F1D215E8EC1789D602D92A971FA3C2E892A09CFA68968F96F206A7535766ED7533497FB051C8036B0AA81C2C802FB7333CC6744EC830E4BE56EF1E4874371409486C477CC4EE90092D2919F585BA21F32BC973ACAEF42B4969746AB2618631B6536EC298B2828ABF41E24776BF288CA6A4A8094D63C7CEAC44854BA9E4837E44B3A7B269D6CCBB6D1712E9FFA937EC5194A3541E3FC9C685102F9A47FAA077FECD688D607996E5B60C1715E617994B842B46574B87086A061488BB2445B357A38934B612C16168E662112756BFD764A4FCC5F7B1634F6F28094464D600046EE03B4540C1049BB3D18F783FBA2AC5BD36ECDE662D9E08E2A89CB754B090DB7175277941E5973D010AE08A4B4C922AA99F47F657A49C3B81FCDB54C905A3010405ED544BDDA9942BC857B6D979F796C859E0627A5212543477ED791C2ADC95FDFAC9D21D19750B8B5DDB95F02D721A9304099BA6B2CD0A40C1A2F9DC1649B2318ACC93A5FBC52E3F4900BB44D20A7250142AE5F3B77C0720C77104B74C78EB821BD32E260051C499B5CCDD9D716521163557B5E4526ACAF09A2BEDA04994188A5065B4A975B215171EB288024581CFFA37D6289813773B29F1C0EF5587F9C98049F548D2A0C3A5C71C1693B5EC8C64CE0267FDF625485DCC4B5553C5736A0D0623CFE20596F984C014AAC0380BA9B58257A993B1BE3BD2CB9AC25912B36B2C085443074F093510A46CDE5441EE3CC88DC2CD636A5EF77310F91CB21ABB149DB2541407726582B54B50306CAB4B5356492C220C138C64B4AB293680E01C2AEB369BD611064FD8955B790222BD5997DD76BFBE50A2BD039C1F14F0469B623C53195A3B2FF068182D951DAB05FFCE9A6C8FAB42886987B7999043C12870965BD463980AA6B35E13B5BF9C25B64920D7788A291A98EBC30D3785783C27E53CA9AE809004F23706E3CC0B9AC0BD571084100299C932DB2933CD91566AAA367371B16069A706BE664E86107B33B1CF05360248C808EA250FCACAF9096715478463932A1C632CC9A185EEB08583A9309259C567743995AF013216B1086815B851655D0F14FCC43682720ACDFC36F35806894177EA2144F6E28837CC887E560874DDCAAF60A3580FCC7A5F1733180B1F1202A08182345370CC5C46CD28A507AD846D1D9415AF679D4B22EE560C6C1B2499D5B74AA2758DA090E62713343B3A8B14C68E415A3F196C2573C5E828A16CEA51443104F9CD899AD03C3B727774B48AE61DB98FEDA4C1E029B57F89D1735381166B70450215AF92120CA61A8A38E575ABF2CFAA54C613031A9BA60275D23178BA553A3ED7179AAC44FB3607E93C1C57C7BAD6854533844BF3D6A9B95A966F891612239CF6CC41DF1A859AFEA9C0CEC6D2679CD7C71C2CF251DC9759666C871853A1012294022FABDEB2269B430397F337B3F416E528748903CCB8B24C8FA28197244C0AC3A0345E699B247C863E9A58D8CAEE564224FAA36C70ECD281B67EB98908468420B38F3C24DA9290EA98B24\nsk = 5E484946337E3F4135D738B0862B69F7B247A5BB0812D56201300C53BB87B798B2B551CCEA75A87F002D7DE7878ED08E976A2CB62B4AA559BC36816E9690973F608B262612F89B5BC784365E33193FE9013C05818E0A7151297EA53C95089388BE203071D0335535436C799F6D3AA3260A9C8C9C9E36F79F13135C3DAB92914137C33773660AA15557C32B7A086A5A1CFD125DEA60183ECBA94DA22F0F3A18DD2131BC792C4013B7BF84A7840C976C53117653C4F947839D8CB35538BB97899418688A9E062F9FC17D77450D85261AAB01BD9EE77E917966BD26BD3D3990AABC8561CBADDC5A22F8C80D99453FA7350B2A022E4CA48DEA6C9C07309543611ABFC7CDA76AA03E51ACFDF0CC73921EF2D02F45990AEE50CA77B93F14E4BEF44576134391F7B67658E1CC7876713742267A556EA8F562BD858B24E04314B025CCB5BE0650642A23460C3C65E0D6CB68232CFF709204B7B7CAB0741807100A712686B982F632095D7730DD9385A7A26C23741474E12CD8FC259EF346B5F287EB01B046104EF8415372B47DA145AB0C5C1774626B5DEA7D72DB4C62FAB14C03CA51384420690A799194E8AA05BB914DB21956BEDC948299BAED7289C884AB9833C8669422ADF51D4E1A0466056EECA478F11AB55CE2CE34430ADDC889044A5601357EA6A5B097B54252B046FA83C0211C236953954C36840E390D2707848C0B879ABA2354EA200FCA56CBB86C0C2269A81C790B966893F782AAE9A4BD1B02FA85995A757FF2083FD26347C97711E07560AF77CB59C7CD64F7CDBC880AD26A7BD7FCB9B210710E581C49453A3200AC08554A641068E6879BA6665AE9F281FC14C8FBFCB0CAC0081C1A06DB017D80048B324248F699825A489D0726893E109127A0AE802CCA29AC56F6118D209A54CB842C9A8C539E43B9681CB868018C95D872C532A10A77BF52A796D33187FB8AA3FD780BD2C4B30FB7394DC64B0FE05B81128763A1325BD00EBA411247B1C22A1146FEBA1B255C51F74999DD29A9453151BD9869E3D548347B93C1B798FE92A053B88C80D7AFA5C561D31435D61251253B9A4C2B0F42830C81E990006DCEBDDB7002240EE8E276D4E31C2D249B84414F3997B9C4F5C0698CB2A24C48E3605F6D704E5DB734EAD12D62634DEDC68ED6A1248273BAD5ECAC0651978B098FFCC148667671D4B59EA6095B0B363C31299E5B90282F914BEBC66F6291338BB7600C8310B83963336952EC33854ED7C979B71F30188180B11BB66314C93242ECB890123C9F2AAA786ACBC7DBF560CFC1625D06C3828998ED51B79D28C583BB38719706D1D67B9BA5A556CB9EE1DC4FF2C53C33969F2F97BB93056729F65FD90AA2D7113EDF611C521761BE671FE37BAADA7A2B4A114DD458A19966A2A42914D61B47AEF5ABCCF8240C88AF752B51BCD0A3788C2AA38AAD8DC00D835476C8386DD3A8628B261F1D6B2B9F771842C97DA7BBC3D03696F60524BE6476430044F6A8AA48C22901F750DC55C1EA7813EC3518B26B3FD0657EA6FCB6BE94C026244A0401593664673FAA680F866E174143B0CC086FDACC1F7126C3E941F090332D8487D5E66061D5311C9B5C8EDC39BDFC34948400A9A3AFF3A85A8683354B3C3F035586B50B88C4140F346A05ADA7CE4BEAAA5F096614CC767AF89FFCCB95124B00E8379EFAF76CA381AE4886ABED9240BDA4710DAC62A71017059B07921C770DA1CA2D209338536C3A9B5238313BCE565FB861BF8AD3A78F030B3F646B34347F1D215E8EC1789D602D92A971FA3C2E892A09CFA68968F96F206A7535766ED7533497FB051C8036B0AA81C2C802FB7333CC6744EC830E4BE56EF1E4874371409486C477CC4EE90092D2919F585BA21F32BC973ACAEF42B4969746AB2618631B6536EC298B2828ABF41E24776BF288CA6A4A8094D63C7CEAC44854BA9E4837E44B3A7B269D6CCBB6D1712E9FFA937EC5194A3541E3FC9C685102F9A47FAA077FECD688D607996E5B60C1715E617994B842B46574B87086A061488BB2445B357A38934B612C16168E662112756BFD764A4FCC5F7B1634F6F28094464D600046EE03B4540C1049BB3D18F783FBA2AC5BD36ECDE662D9E08E2A89CB754B090DB7175277941E5973D010AE08A4B4C922AA99F47F657A49C3B81FCDB54C905A3010405ED544BDDA9942BC857B6D979F796C859E0627A5212543477ED791C2ADC95FDFAC9D21D19750B8B5DDB95F02D721A9304099BA6B2CD0A40C1A2F9DC1649B2318ACC93A5FBC52E3F4900BB44D20A7250142AE5F3B77C0720C77104B74C78EB821BD32E260051C499B5CCDD9D716521163557B5E4526ACAF09A2BEDA04994188A5065B4A975B215171EB288024581CFFA37D6289813773B29F1C0EF5587F9C98049F548D2A0C3A5C71C1693B5EC8C64CE0267FDF625485DCC4B5553C5736A0D0623CFE20596F984C014AAC0380BA9B58257A993B1BE3BD2CB9AC25912B36B2C085443074F093510A46CDE5441EE3CC88DC2CD636A5EF77310F91CB21ABB149DB2541407726582B54B50306CAB4B5356492C220C138C64B4AB293680E01", + "C2AEB369BD611064FD8955B790222BD5997DD76BFBE50A2BD039C1F14F0469B623C53195A3B2FF068182D951DAB05FFCE9A6C8FAB42886987B7999043C12870965BD463980AA6B35E13B5BF9C25B64920D7788A291A98EBC30D3785783C27E53CA9AE809004F23706E3CC0B9AC0BD571084100299C932DB2933CD91566AAA367371B16069A706BE664E86107B33B1CF05360248C808EA250FCACAF9096715478463932A1C632CC9A185EEB08583A9309259C567743995AF013216B1086815B851655D0F14FCC43682720ACDFC36F35806894177EA2144F6E28837CC887E560874DDCAAF60A3580FCC7A5F1733180B1F1202A08182345370CC5C46CD28A507AD846D1D9415AF679D4B22EE560C6C1B2499D5B74AA2758DA090E62713343B3A8B14C68E415A3F196C2573C5E828A16CEA51443104F9CD899AD03C3B727774B48AE61DB98FEDA4C1E029B57F89D1735381166B70450215AF92120CA61A8A38E575ABF2CFAA54C613031A9BA60275D23178BA553A3ED7179AAC44FB3607E93C1C57C7BAD6854533844BF3D6A9B95A966F891612239CF6CC41DF1A859AFEA9C0CEC6D2679CD7C71C2CF251DC9759666C871853A1012294022FABDEB2269B430397F337B3F416E528748903CCB8B24C8FA28197244C0AC3A0345E699B247C863E9A58D8CAEE564224FAA36C70ECD281B67EB98908468420B38F3C24DA9290EA98B242CA3D8AD2DAB1DD8A2F4320658FE6EACABF70D907920593919119CF3745163360F4DFF8E56F68440836A072412A30D851ACE2C7C6F02D60E7A8420001A63E6C6\nct = CC6EDBDAE7FAA07675568A32E556B25F34740418B3603A6ED17CF2943C1531B60542379810B7BDF525790222217880D92343AEDEEAE9D5F1FF7773C676B1894399F36037DDA6A1F2DF2D894FE157A64BBD04A0948DF19303CAF2A59188FB0415291246E115F0663C17DDF4259F2326C3E1C6ADA0A12E69A6DFAE45E3B6C6F8952B09D9C1721886076BDD8FF34878110ABF83EADFC84DFD1F9A426A533E1AC51D87AA50E3EF4F05DB558713D78ABCAEEFC2C98B9900D0A3BCCC818D5572E6F47F99CE87F687874CE23CB1ECFD88D3107D61C2862FC306BA30477BB7A0D121DC6E378D6C20A4F1C300FE69EBDC020F2585A539D972A3A935A2F1D49697F9696313D7AFBDEBA2E97A2107AE83E7D3CCC6ED795C77263D3B4C3632241E0F95028A2B3EB37385B847F67BC4E0F5BAF7EB89E293BBC95F77D609453023934B5C04D34C4AAF06CEBE6C122F76A3608C48FA264A59477B5F41C63936CFCC1E86CD443F9F8FDFC5741CE9CF25F4D4B7FEAF143237D6C03B684514D9C67CEE6BAEBF58A43F10383F72E9CF74B2FB8B865A450756764894640013F2C569E1DDA9DEF2DFE70A48A78510DA2EE18F17279688BFF62CB2F48F6EF0D72AFFE36CE9F656E723B692E418CF98E5A2A4D72E908F148788FD04D680497084CB01795FCAA77EEEBB0AC2C600351C84B4A3D1F6C537E9D9CCF373B2A26E7EECCA9B02183EF4AACBD24BAE4863A40B1A5F3C60F514D718B345A62C15B9F38880D00E50A01A18E7573B213A8DADFD54E2064C9A64CC6354DE8CE3E70C2F1457CC5F0F54055E5F0C05414C125CE82A398F025EBF224302429D818BA3838AE58F895C97130C1DC5CA577C05152FD543F7E6C1E292D8B7B6757023685D8F57A0F44BAEE68375F4D226973007275426EB9EC937835A2E26A1DB9F4DDD63F415E3225B6689210FB7FA323A479A59702F13C11425EE68C982F0106BBF4F6B01127F3BC7801D6B52F3B6226E73EC40659E1FD9A22B33F8614F514A20580C56859470FBA19AD5A558252F939614D1CAD9E3760EA33BEB784D311305EBB0A00CBD28C6DD9902F0C3CB5A88DBA565A4F494E1ED31C657A81685F706B1B0532E0DF6B8D9D90E3318125F1ABF6EF69E3044C04DD09599DBFCBF3E473C022F4B5A2DD2437AF91784767B2763FB99494BD13AF326B0403118DB6BA8271E34016548F56E4E5C75D2002CF237D5F5C26F5AE692444AFB5F6C51958B83B3ED983D248E0FFB8C0ABF455C34D17DF51A8F86C5B3044BE0660D7843033194A1DC4B84D475C089EC2AC1820A0B79C26B7CA3F888F24F784A54536FB852ABD51B0CEF758C855FE33FFA2155F4CB1C0F4AB9AB5B0D74B31067E2C6651460A151D16252F32CE4E037516978EECB123E23671B453B31893601D2D79F22ACE7EB3DDF6A22714C5AE97DF6BEF6EF3ACBA526AFD8920F2CABA016C10CDA20D0C39B32E78D0BFF0CC7A445753CBCAD615B55CE00851C70A92DA2421CC9105A85B6E642052F2692FB84CF642AAA44A9EB7572A6974FD3B767B4E0\nss = 8C0346216CC65F95D2E0CAAEEC4BFFAACCC49132CBA2DEE8F2A6CE1F922E6DB4\n\ncount = 69\nseed = 6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA\ngenerateEntropy = 995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc\nencapEntropyPreHash = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50\npk = B147B4694B12C461130F3126F8F71673E4643B2147DED2A7270AB360F6303DC05B03A314BB776C488318686069C3A4C91CC62435E829A6A8621EF5CF838311A4278D7F453EA5484D32F94C2E9628F5532FF93771DAE106C8AC9CC80AD07D306B1DA78463A08226657680E5ACABA6819543CD96194AA5973D4F7B8682B13A07E7A5194C91EC95A2D671A2627710A4C78AA107B3707942D0C78F3EB2B3A58B7833FCB0FD7785E349A2F0027AFF079B62A68E3F425122F7BC0A0B4C053A6696F90A67088F139B2A39F542D6439091E4C1A0824734D8B6E5E6483F48CA738C39A5BC2016C0746CFA9C1889297F5377D614ACFF2833CED20ABED0AA6C7024221B73D53610575C6D91A262A5E834ABB63CF74207437B31B1E989ECD7416B2C4E7BF807B5F8973006877E204A42774C93A1B394E885CF727B7FD286DEF2B4C8D5684460219C31B1B225AA08AC2EE1DA3922E935E981B3B5E2C3D044A784BC965A580D3052AC48000EF6183B94B0A870E65207BA8029C0BD34A10443E5706792207FE2224DA533D307C3E3077E6E1CBAD064B0399ABC6F445B651864F18B42E1A518FEA187BDD08072E47588527C3B9A5EB244AE9E910F93C92B69FAA7250BCF38E68E9C3A2B2B733B18032F37673907097A4CD65A9B396DB4859312D59113E07B39746C52126EA697A69929B1B625B5AE1B809CE9A811D13CCA70971AE8BD6AD223206691AF6897F136CB451699E0A19739D52D60CC89DFD654A320A79B2C7CD55116843239D6847B8BDC1EFA29CDC0A979F0E3A8F225A16FCB7996FC8CA3E79FAB55B93DC2A395117426A17AF4D404151814CEC80E856B777EB35085F1AD14285078803C2D76AC1D25C3F8609AEEEC4ADBCB64136516A2077CFF4C13748C5D1FE6386782688D944E0027A2F8C9AF77B79352EA5523767CBDE4577877AF1F8017E4DB244E833E99DABD0FC70824BC3C50A38275040446A5C74406873BA0B5BFC2570A406570B424727379E5C1C39EC194A29A8AA249844BEA2A078C1C0F25A400D6BADA80731A00B87BB5A19325B4E79B78AF0BBB2C52C3DB38AE552CA972C3927291145438115A952BF2A85E78F6141E1CAE8516B056E614B7015017E71D54268AB9919B7EBA09D196768D99651D60A334FC443C8CCD9064A420263A68531F0E86CDC48776A3D44B4726916273A0D3002DE095526257BC5E6246DCC10814D1907885207A53241A184AB7E40D87148A336A33262A4BB0826B417ABCDF957F68737ADEE682194115348AC58814661765BB321254A874C4A3C6745CF984528C2B9726AC35441015233219E169D0EA761425C06513720881B330185B48BC271B275DC024419D8761EB23801EB704F6326F162656713ACC2915A1A6F877A583C8372CC391EBCF2CB22873C5BD22C58C80640CCE759B2C09B368AB4AB504C613493479B7725A18811837213F9237734577AF09C4BE0B3FE07AB78B712B0683060BE76920CC5FC56993E56C7B46A543AD675B2D13357C008911320E0D292268768B8370C66CE757AF191BB703CB5732113ACB8F02618EAC98693224ABCCEA04E7B3157C03B27A3CC4F0B880DC4877AC35077C1C2D5584B971261D2C4BB767C75907827AD7370F4074721445E155A3A1624CB4ACA373DE6947F148CA7E2B3C93605E706EDDD992\nsk = DE4627135B3976B8AC07C0059BB28D09E98E3428228C1786C2E8A1D6029D93CB9EED217D09B03E9A7561AF7441E4271C7B6C8C862C5A93E955A05A87B01A63D9E8A334B26E1FC0346051BF31D078860A9AFE939F4A90C2A395B2B6C205475164E36A0C2930CD26E26420470B0D068E36971A978B17BE984A418A3CC5C6B62AB00D6DCA5657F71E08B215EDFB88A5B6751EAA525DEA4B0BD41430388E0CFB445DA3347EAA375B86858F19C81B73A4BF88C2F807638D808F78535B9FC6C6BC0C1402E16F0B784F9A22A30E5C6C1932C2063BC558A7B2636C76D5C0CB77E6C5518B3B31D920A23B2BFFF3AB93FB03B3386F670B07655989C5185D5D393631E9ACEE701DAD333379A63EFBCC636BF2B4FA05B84A375559079C5909651E481DA96B01A771BEFC7BC407DB7D9F94B819A468D443A7AA8C9B4741266875268602336C1B1160A4CE5D41C57FB915335C87A72A7345316373D921A6D0CA09606154199C4F06C244A7C568BC5D82449149F92AD3350B51D3C474E77A3A1053160570C876132434AEDD92C8961B95588910102C62AE1A75479175CDD666AB85478EBB6133920E9154441F1383B0F147137614DADC823F1848FA478B1F301D3F745C647C216C741DFD3B3195483F24F1A5313CB458273FFEB559689004CD534EC1369B0C68A873651F7413037118C6F98C538DAB9C1EC649FF2301A03A650CC0C138E79D15F9079A639737E840A7DC720B173BB329A34CF65418495E4DF2805A491A4C96B47D452725850CA8EB3944399F9D14157FA46B76F0891525461113766DC025EE1C2E735198C3DB253A2B8A566CACB81B65A1C9473C6C6DA9743D780685CF83CEBB441CDFDC9FBA20A9CE2943759C4D08C57A0E74BB0E1888E94723169437AEC19AEC1A2A46C81AE4645DE32BB18F3527F4DCB8221A0F7BE74F3F5A8CAB0609BE216465819FB858232B008A855C9E6B54439A67AAFFD9701967BC46A274D1D6AC1D45CEE7C54CF49669E89A44FFD7B73B2A12327A85BF5938E6975B949C03EF3A1D824CCDE033CB175A3356C8A998E4C69D94630A896606FC1979DCB5C172A54EEA2E99D5AE331BC64D708FAE45C514A2544843CA59C3C122947BC3660DA7357AC0E33F55485E79EB3117D14C42EC5C56653E0DD1A4E8205FE571823098AD8D9844A25B92238063A92040C500CC0BC2B25B493E4CF69DE95C87B03B773A796D13F42014847727345888EB06D9251AEDE24D03E292CB452A3A38A0A461C8B4F9CD9F87B09BC0CA98E62E5027595C24792F818865777A346004FE3B5B587452648263AAF688154526D591ACADB74520F3627D7395EC7B71DC3C6E8414985D591A05C88B6455870C48B12C576D7B328B88795295C051CA6293B0FB4DC61AB8AD34CFB114A4C7E44AB4667D4B1948C83C28BAA424B19370AFE997D8B08E447A2EFF376024F5CA54DC8EC0", + "972B96F057ACF5A6B0D32869FAB3E1797EE2571B1620A076082C4BA6799C27B07FB073092A7A2F7AA110635CB94900E487A6664B318F54956039C57CE509EDE489FAABAC96CB11F58C87708A8ED3408A526701BFB8507D67415FE64E7D41081AC12C21F3092AF02810C604F02C4064E348B4F98F6BE65D87650EB147B4694B12C461130F3126F8F71673E4643B2147DED2A7270AB360F6303DC05B03A314BB776C488318686069C3A4C91CC62435E829A6A8621EF5CF838311A4278D7F453EA5484D32F94C2E9628F5532FF93771DAE106C8AC9CC80AD07D306B1DA78463A08226657680E5ACABA6819543CD96194AA5973D4F7B8682B13A07E7A5194C91EC95A2D671A2627710A4C78AA107B3707942D0C78F3EB2B3A58B7833FCB0FD7785E349A2F0027AFF079B62A68E3F425122F7BC0A0B4C053A6696F90A67088F139B2A39F542D6439091E4C1A0824734D8B6E5E6483F48CA738C39A5BC2016C0746CFA9C1889297F5377D614ACFF2833CED20ABED0AA6C7024221B73D53610575C6D91A262A5E834ABB63CF74207437B31B1E989ECD7416B2C4E7BF807B5F8973006877E204A42774C93A1B394E885CF727B7FD286DEF2B4C8D5684460219C31B1B225AA08AC2EE1DA3922E935E981B3B5E2C3D044A784BC965A580D3052AC48000EF6183B94B0A870E65207BA8029C0BD34A10443E5706792207FE2224DA533D307C3E3077E6E1CBAD064B0399ABC6F445B651864F18B42E1A518FEA187BDD08072E47588527C3B9A5EB244AE9E910F93C92B69FAA7250BCF38E68E9C3A2B2B733B18032F37673907097A4CD65A9B396DB4859312D59113E07B39746C52126EA697A69929B1B625B5AE1B809CE9A811D13CCA70971AE8BD6AD223206691AF6897F136CB451699E0A19739D52D60CC89DFD654A320A79B2C7CD55116843239D6847B8BDC1EFA29CDC0A979F0E3A8F225A16FCB7996FC8CA3E79FAB55B93DC2A395117426A17AF4D404151814CEC80E856B777EB35085F1AD14285078803C2D76AC1D25C3F8609AEEEC4ADBCB64136516A2077CFF4C13748C5D1FE6386782688D944E0027A2F8C9AF77B79352EA5523767CBDE4577877AF1F8017E4DB244E833E99DABD0FC70824BC3C50A38275040446A5C74406873BA0B5BFC2570A406570B424727379E5C1C39EC194A29A8AA249844BEA2A078C1C0F25A400D6BADA80731A00B87BB5A19325B4E79B78AF0BBB2C52C3DB38AE552CA972C3927291145438115A952BF2A85E78F6141E1CAE8516B056E614B7015017E71D54268AB9919B7EBA09D196768D99651D60A334FC443C8CCD9064A420263A68531F0E86CDC48776A3D44B4726916273A0D3002DE095526257BC5E6246DCC10814D1907885207A53241A184AB7E40D87148A336A33262A4BB0826B417ABCDF957F68737ADEE682194115348AC58814661765BB321254A874C4A3C6745CF984528C2B9726AC35441015233219E169D0EA761425C06513720881B330185B48BC271B275DC024419D8761EB23801EB704F6326F162656713ACC2915A1A6F877A583C8372CC391EBCF2CB22873C5BD22C58C80640CCE759B2C09B368AB4AB504C613493479B7725A18811837213F9237734577AF09C4BE0B3FE07AB78B712B0683060BE76920CC5FC56993E56C7B46A543AD675B2D13357C008911320E0D292268768B8370C66CE757AF191BB703CB5732113ACB8F02618EAC98693224ABCCEA04E7B3157C03B27A3CC4F0B880DC4877AC35077C1C2D5584B971261D2C4BB767C75907827AD7370F4074721445E155A3A1624CB4ACA373DE6947F148CA7E2B3C93605E706EDDD992DE62EFF56F6B49A156D065D85EAF0AA21CA229A20FA4E1372A410AB1C4AB6E7EB28F7E7A15A005F92400CE33DB073D49B53871594A88FC45E0F94207B5F0F2DC\nct = C543D4032D1E98D70EE56B5B7AA1AA456F157F9405CE77EBA7F9C61C8D4634834B2A3DD128ED8022D30D6300EC237AA27B302302932082D9974B04DA94EDB0288EB04855E224669CEB3814CB91854F47FA0BFDFD376B0620DEB5A230C1705555C8D45BFD2751F57E2CF296276AE1A4078DFC4A98DDD7E5CB419B0F0AE1C3CEC1FF4FF1DE6D316CEF569D428C89B9C08EECF992B80CC2C4E5432C1DBC505E3A361F8570E71104591049F72B2C9B17869DB01F14AB30630726A7AD7B6AABE63270B81C033FFF7BDEE9E4189FB9D53BC910DFB3FB5773B8EEB63FD38B32DE2AD0EBB24FD3C7E0AF6BE8970602A270107C0B227A3D35677694CDA2128DF7EF7BA60E5F3D5255C04B817B3B01316D6B6E3D1159693FC7B27C3D5BC8ECB1C82403C7B736CC0844089DA19D5945FAAC08B074605D14B7B3A51DDC7ED207D84820465E44AFF42E9C5871E0FBD1DC147C79868D65911E5966D3480ECF644BEFE22A120C8D069E867D3132F44AE3482A1EA00A1EE14A5240C8412E0E07637BB2859A9C6A6F5B5CE2D7C810B9281A949992FF7A6CD4A7E3474625013E86F6F2713932D2C33C5D65AE15F26E7E45A5A24B9205574282900580338A26D07A2066C050FC5C44972ACD5DC2C2A0FD1D8634B34A4D839B5809D3AB4C14800722DB9F8A94D0239AF0A5C756AA815B1F733999C6F2DBF7E144BF2E2B8C6999394817A1875F4EC794680A4C509046FFC64C4D84D8606A19EA5EC8CDBEE7F5199037A8BBBF9F69BC4159A505B68BDA0E450695977A586D9917E843098E3C7F97A80DF5D092172E89364B1EDC37E8A1738E21FFF20170B157775B4F8F6B9DDD5D0202E735FCD380649C0F0EA7E7C708ACA92A3DA4AB0727907646C78203C81B9816ECFBE1D2B00C85ABFE0EE7BF92B9F9381EF3684400F5ED6625599D472D859D9A21060CCA7D37174945048EC244550EEABD26747F8D2F6C2D0293FFCD68046E5A83E651D65357CF82CF59A6183158F11C114934DC98E9E74CD9AB8CFB4C0811DE80B44ED75E37D1459B614801A548410909E2B9763AC2CDBC1B31F11C5DA7025E909C76465A1BD2E7F0813FFB2E75BFBCBC79B92F0F5220103F2AE62D957B9D69787491A556F45CCFBB7CCB005D5106817EB97ADBE2B83180D242190A54B88BA1FED0FA8B5BE2B264B1D9541A28DC321F0F3DAE9EE41723840EC7B703F41B6635AFA3E683B42364D69F5C5ADD12B20F60F5B3D1E19FFEAA3A98F4D61B3BF1F5FEB947DC586E5D13805C710EC734CD680EB89FFD9CBC1DB5AB3B2E01DB928C7AEAF6F91EC3AE0B48C3E133CE87B6561175C65F9A1417D048F8E9636F5751C62DCFD7EE7BEE93FC5CEF56E0D005AD82CBE3B93BF7E07DF37A8958FD74113F6765BA3614D89DF1A27C49998C88B65A2087118264FB5851581393100EDFF4A3FA54E807B042E62981866ECFE07D4C1E5DE3D49283E18E306074A332ED1E090DA35912DDE3C10416FF0A5E056C0F3BA4734668404E02EE2476C3400A51D7D9EECB09074F23CAC5FF87603BB4\nss = 35151C059E5220D4ABAB9380FB0EBFA061148E6096D8F5678E4308CBA0226261\n\ncount = 70\nseed = F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F\ngenerateEntropy = 3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473\nencapEntropyPreHash = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76\npk = C0C8122855031D7BB0CA735042BB43B8EC6EE13061046ACAB9B873B13519C22678ACE2B59F92AA4E8269844B1DE5E3426D66C0451A8D78CC07E719033A536C2BF4C7397C64C6478BE5F42A06413B8B44111AD9742B8B020711446D63CDD64490C0917557B884EB429B05DBC0DF7ACEC032ADBBA55D3E104F7BF391CBA28B903A07712A8DA3A1A92F5682CD650A628573844032A307704FE77AF738696E974181A85C5CA1C14F7546F8713701115883480BE2CC686625A37B62292367B5E1546F4189592639CDA4CC20974C6A87C0377D15B8EC5C84B70233B64800B79C62E536553B43263532C6BC2B726970CC58BB20F0C0BD35B317D9B66B327BBEB5175D9611985AD799EBB19AD0587AEB856C288464D983256649827DE9AF0FC79AFA1AA5817C06D3447A25AB3EB8248167BA60A4462ED47C007107B1EECB630AC4707B837F24D26DA46BCDA77C4B6ED5B4118B79294744788B9A9C21B168565D9398B41EDB91517493F5FB48AE5CC04FB95BB13A8FCDB8615262408AE25C2985189BA8AB99643624B70557A984011474586C357F1C7551F0BB069336FE85BB903040F48C4A111113507055F2716D37EA6A6FFA48F40584914C4738397430D65756F298AAD345671077DA8A4173728364A493BDCA944B1879B114166CC3B8293937221257C2E78F8F1C7794ECCBF0368CE34921A2EBB01E32A92255A676E77C39564B575AA5D1F9C7D1388226D636F4F12C5636B2E2F712C59CA583A811BDFA56448C013CC820F21A36C3351AEC3C2C6F01243FF47BF17181ECAC752108C43A97729C6B9472270FCEF5A7C08665F7AA9FAA55B152163E8446C1BEE5082192B5ECEAB269EC13E7879DA3768BBEDC0A104C5E9496C63E9507881A4C8E758211076653F369E58B59BD7CAE5B9A64772C2A84329E43F492FECABBB56514CBE70970F361E6D3C6595065F6CC668C64BAE7D587FA8BBAD129136D5C9B6F757A51E653D2754AA0E35307845A55B80086D5A0E86302D306B9EE1550419B495D424F701A098220897FC47333D5A1E994C8584A00D79804E4989A1CF02DCF9A0AC2AC52BE1090BB149778235FF6091075A5360CE095CB705C81E3BE126984F51AA471F90FF98C21D3989FD936502A8A2B38C4A2320A618DF751C7099D1063495A6A5936C744A094CC1FF1B04BA8B56B0464E852BBE06176034CBF5239CD2C687FACC2CD37329ADBEC3A77B4842AEC40BE902E8AF72FA5805345668408CC7B6073097391921E765E4D76025FD5C78E246DA268A4DB21446F2CC3273861D2081DAACC2CC775631927B709DC1FA8993B1E92619590C08940342219682AF351495B2E0AAC74786C897FAB196ABB609E216997C2C7B283BFEFCA4B1F2B1B6E98991BB32424321AB7D61E4D13C44DC93295A75F6145BF2D4B8F1A03109BD7038EF4B16FC15F44CA6EA3411B68400EB20C46C11CBB98201D705A6CF4F4B792AAAE80D97A6AB830576AA651142793FA7DA0B8BEDD877217D54897375EC285849A79268BABACE85176842C601EF8C740A21C2C5321436A21CB968ECB5410E811912CB0962F713322021516535907914B86E9411D27CF164B580528768AD37B57300DC201557BB0A142D9416ED7AFEF52D284175DEC18F24979EF5BA8EDDF7CAA3880AEC7B42A147E75F0DD62B3D0\nsk = 84D7070EE80107976BFD1B0DB6CC33F3C98178817D8460B63DC012311638AA43B253A705BC994931BAB38A62C5D1DBA793B8437BD600A8725D36AA898E353D6B955B80F8578F855BCEE194CE2C6E4C6179ADE8176E34578FB24B6D60C395B674A7A8A4C72550F83A09D24582F94125690428A4E76972B77A53E852FF3718A440B67D6521CA699E5A8C434DC47A38032129BB76BCB4C810028938FC94F1741A1FB26EC95252E259B8F9176BBAD8763CB63DA6F295B460CDE1479BE8D6B9E3C49AB77845C21C8F3F88741759461E339F76376AB81B4F07E7BF0DB861A4AC5B24E09D4144AC900B43CEC07F1D", + "D2CC4F7C976EB0BAA4D8637BCAA70946391109981E978CA023313B200092D26CCC823EBBAA85B8BA1680636D0BE656F01769555B058AF7825FA00D10A38B0A2B127A773CAB406C1D4310A0882889759F20B44AECF68DD24416D9491CB523A1AFB1A1ED87B28E5589F4059132603E228B185D426F49031AF8FA21B11CB0F37C4557F94B2F158340921F95091128C5616F54105D47253F150FF335081D231F5B308A526B9506B03E0B5C6A88394F0C9C6E7C2B475C7508A3A8B1E0D571D1C364784CC8A7CA7AE6C2B24366A0D2865658D42A8495B24A16C9A9D8B1EA77332A1058DC292EC02C4723FA7204E93EEFC24F10C4877425975CBB6142026A2AA649FC6C77E8C72DD3E5B0D9E9495A02C251B12B7AB51F6A9853BFD151A4873CAB4102DB62676496A8B38C8038E4C6D988880A6B2774875A5FE69693D9726AF64A51D77A03E523BAD8B2A6DBCEA137A051D19E81059D07437E38DB7891956C5B2C8ABE282B5A02A5530C56A7B4B46DAAB256588B04344365313A3AD94A2D7ACA4BA7072CB9259E2676A5C86215B24FAA159BC18BCE05451C69D2699A056ED3F6A7F2BC7676F11BB06CB72DC53D7EA6BAFEE89797B57445F3AE11262543A2882B863CDB455D5EA03EBA56946DC61D798A76BDBC4CA7F2A102C518224A2091211EC4D251CCFB08AA2598065A79B8B61A56E925031A579AC5BDEEF1A6E0B1381FE180DB008F19E775E030052A624B91D1550FE5365260150CCAAF228ACB8FE471D2C8B4B27BB57D62AE9AD9CE15A0B72ED98B8A619CFDD3A17ADA37CC455D77640EA327088E9C33D4281B65DC9A27C68D27088B1F2A5FC586BB0993753E62A67BC3886048274AC267A95B42AAAC3E60C2699321A79301ACD350B92899A2C0CCC4703B243660A39C5901E3B6BB146C588DD3431C4A5BEAD8AA29E04F8FDC0D04783751707CC25AC359952ABE7384F839B42D9C9982DC66A21C7FB5CB7316748423E25005D389BCD56FC498080F88CD75EC974CA9CE9F2BA995B50ECA85CF09612FCBDC492CCC6D0662A59F8CC0FF3355F17424ABB6C774A377B81C12B9982F60777926BA0B860123434CAE8F926E902A5E633019E3C62087A1BDDDF2186768BAF91656D903C4F1CA88163B8DCA041823BB6EE525583816CDFAFCCBCFE63DCAE0B93C46A14FB72114194CD084C208921925E7C55EC807EE6C0A8DDB71C4AB3BD5836B7FA160009DABD1E5498D005718548324B0339EC71AC4A75C81F522DFD92B64E3676B337758490E068C3CC747BC004DA30CECAB9C542FFCE826C0C8122855031D7BB0CA735042BB43B8EC6EE13061046ACAB9B873B13519C22678ACE2B59F92AA4E8269844B1DE5E3426D66C0451A8D78CC07E719033A536C2BF4C7397C64C6478BE5F42A06413B8B44111AD9742B8B020711446D63CDD64490C0917557B884EB429B05DBC0DF7ACEC032ADBBA55D3E104F7BF391CBA28B903A07712A8DA3A1A92F5682CD650A628573844032A307704FE77AF738696E974181A85C5CA1C14F7546F8713701115883480BE2CC686625A37B62292367B5E1546F4189592639CDA4CC20974C6A87C0377D15B8EC5C84B70233B64800B79C62E536553B43263532C6BC2B726970CC58BB20F0C0BD35B317D9B66B327BBEB5175D9611985AD799EBB19AD0587AEB856C288464D983256649827DE9AF0FC79AFA1AA5817C06D3447A25AB3EB8248167BA60A4462ED47C007107B1EECB630AC4707B837F24D26DA46BCDA77C4B6ED5B4118B79294744788B9A9C21B168565D9398B41EDB91517493F5FB48AE5CC04FB95BB13A8FCDB8615262408AE25C2985189BA8AB99643624B70557A984011474586C357F1C7551F0BB069336FE85BB903040F48C4A111113507055F2716D37EA6A6FFA48F40584914C4738397430D65756F298AAD345671077DA8A4173728364A493BDCA944B1879B114166CC3B8293937221257C2E78F8F1C7794ECCBF0368CE34921A2EBB01E32A92255A676E77C39564B575AA5D1F9C7D1388226D636F4F12C5636B2E2F712C59CA583A811BDFA56448C013CC820F21A36C3351AEC3C2C6F01243FF47BF17181ECAC752108C43A97729C6B9472270FCEF5A7C08665F7AA9FAA55B152163E8446C1BEE5082192B5ECEAB269EC13E7879DA3768BBEDC0A104C5E9496C63E9507881A4C8E758211076653F369E58B59BD7CAE5B9A64772C2A84329E43F492FECABBB56514CBE70970F361E6D3C6595065F6CC668C64BAE7D587FA8BBAD129136D5C9B6F757A51E653D2754AA0E35307845A55B80086D5A0E86302D306B9EE1550419B495D424F701A098220897FC47333D5A1E994C8584A00D79804E4989A1CF02DCF9A0AC2AC52BE1090BB149778235FF6091075A5360CE095CB705C81E3BE126984F51AA471F90FF98C21D3989FD936502A8A2B38C4A2320A618DF751C7099D1063495A6A5936C744A094CC1FF1B04BA8B56B0464E852BBE06176034CBF5239CD2C687FACC2CD37329ADBEC3A77B4842AEC40BE902E8AF72FA5805345668408CC7B6073097391921E765E4D76025FD5C78E246DA268A4DB21446F2CC3273861D2081DAACC2CC775631927B709DC1FA8993B1E92619590C08940342219682AF351495B2E0AAC74786C897FAB196ABB609E216997C2C7B283BFEFCA4B1F2B1B6E98991BB32424321AB7D61E4D13C44DC93295A75F6145BF2D4B8F1A03109BD7038EF4B16FC15F44CA6EA3411B68400EB20C46C11CBB98201D705A6CF4F4B792AAAE80D97A6AB830576AA651142793FA7DA0B8BEDD877217D54897375EC285849A79268BABACE85176842C601EF8C740A21C2C5321436A21CB968ECB5410E811912CB0962F713322021516535907914B86E9411D27CF164B580528768AD37B57300DC201557BB0A142D9416ED7AFEF52D284175DEC18F24979EF5BA8EDDF7CAA3880AEC7B42A147E75F0DD62B3D066F161D27DC34E1A2F4B98B14A2B221D7EAE26A593BFE432487D9994CB480656D8128601C28B1DEF8D393A0DB283229F7C7383152A814E7CEFE8EF9D9768C473\nct = DA35DF2985BCD9A10982F3A0A88AF1EE00F083E6A7CF8C64D49E72AD03269EED600E6FEEDBB202CC5FBB12D0F35020B77FDCA235243A2252C82EA4E1D6120262A8CE8A668087D8AD506212240371E5BBE49CF86FCF157E7E284877BBA3FDDD12D2B0BD809C0C29202F07914683F5A248EB748FBFE64C8186CF4B14ACF2F5DE8755E35FA7AB5CE21221576EB118D2D2F9CF5AA0C1D5F8E6ECFBBC5B58D58B6EC340D703685933136B0544016F4974FA814B4AE34688E8FEDF457FD28DAF52784EFA7667041D272275264542B3E04279FE41B74F463E1D77918A5A4D6E1735771CBA792F7B9B014113A96E7A37D318E5A0137770A8F8535D8E54AB1E1CC4F879DC0FC5EBABE4711D940FAC307DA1D1152EADD5BB2883D47F4004EEB4AACA12991CAF663986B4D02CFF065C653B6689FB17F219808B5338319A357D4CDF9D293DC4C4391E88C481B1F7954BC875D6B0959AB89E540291968346632FF24D722A8AFE0E085ABFCD28BE0524578A97DDE657EB9B448DBA91AD1CB58F86FE7626148EAA1962061819821F95D221E7469FDDEEE982B47F3DB8E1B330F84DE756673EDCBC484C645199D92F637173E853E02A805D3E2D9E311E5ADC58E762E8F8D5B64A4CE0EBAC2BB9CC7D738C018FE43FAFDE7C8A1174C2A81C1737901DB8B1F230EECD6FC269EC01396E6893F23BCA652A1A6E3C501FCF016E4592AA5419149BEAF877B8DDBD2B5F9073D5BF532CD1C65161026E0D0CE1969B3B0F208FE23611F8052D54D35ED967E327613B6EEF23A473EFB91D9D23A0B429593F68C61DF78035642DEF971298B70820A43920FE8CF29BC3EEBFECA730DF4E9BA41BFDD3A00E494451F3F19498F3DE4398AE829E5DA0EAA288F9757E7DBA0CE162DBED3B8D7FA9D22D5912B147BD8B88613BB9ED81A9EE73B8FABF3456537F8AAD9B9565C8A638F96F05C9E83B8F147CF1FA829489352AA273172A577FE238A231EDBFFEB6953AB06D5AE7DC63F46B0340F78BF836EB2BD5DC4D72A31260188A888882AB30556EDDC2283879E6481A31EC28A8F3CA1A8DE59E1909B5A0B5A49E4F530E9A0FB285E970A8314F4EF7E8FEE8826A84B062D6DB950D3F15F6ED870678317CA86515485F5922F51B6921D5405F434AC153DBD18E153CDBCCAF0938CEBBE40ABA7795726233FF439D09B03A47F4E9EE894188E5629F8121366222836E8E382C7BABF7A7924991B7F810BA3FCBBF9B286929D67134B55BE9452F54B844BB2D7C8AA76EB76B11C7062A69FD5F2C4A477BBB1826FD5062905B4E89403DBC582125DA4149AD5891A79D6191C95AE2B3041C603F8DBD339FD855FDF7658974878F5369501C8E69C5A561CC2620140F01294E86B2CBEBB393637B8580934C0DEE84A765797BEB43C730C758F83DEA6C5F7BE36EA53C70D33FA62C808BA9A81EFE57F8EF9017FE1EB19CBFAC3556BDCD2FD77E9B39CF7B033F88F43D974923C04DCE51E215BD10667EB54CFC5ACC416EB447E3FC2A4EB309439FCDD2AB4470F660630BA09604626C0C\nss = FA4C0C7C5BBB803ACD4AE91E49CB8CC659A94490E8B786CABFD9B92E949FBB0B\n\ncount = 71\nseed = A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D\ngenerateEntropy = dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f\nencapEntropyPreHash = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83\npk = 80B3B92647A1DBEC6BB883A4B2160E4DCC84C89C6ADBD955CC055933D3238E325FA826ACEF899A555873A5B9C189117844202C65E40EABA07D9FA94D421BAFE8F3A5E3346B6B93CEF8B75628E4418E2885660B1D3DF32D1BD50CC50757C5227928B32E0C567872E66BCB58128B15C8696710A7B33BFDA469128996F6979F896B93D22910383C90D0D877A56B4B7C77C53C99128719C2995497DD36877276A25FA8B74A4947E223215A314A075585DA457DAAF17C41711363950EF9013A8AD95F9E07635546485A3568AA502D608321061A6999057E705C46B6691183874FA9EA38BC392F718C99DDBBA59A1865A135207A00058A408B6C61772CE777456C92B28A51CE823F7524A26639AC64AA49D6903CC2B2B5B60B59643BC950230362CABA6ABB5BA4F6964331B1F62099CF385BE3F5B43C2B8402006BB3386F5A16354E45118F0B759C3363AB4069EC2C4C15CAC4E07A24FAB0C682548337D157E6BA213C7801DC5A0A7045A442B4939D611469746E9DA665E2E910B51C56B77A035900B25490216C0BB53E04173B3BC454A7A17D77283EE278E7D30496301480C8C1AF6B3E1DCA213B174F968C8A45A3BA2044BDDB1492BEF2AF610B4ED2481AE0823DF53282BA7750FBC7A764DB58E3789CCAEA778083C27ED101E3C75BE5486249F9818A08047F97447773C7DEC3BA7C59AECB5778A09CB7F1182B2E0A01C182A1BD13AB7D72AF97F96F564607A9A970B35A6ADFF275C35C22C2444AD6E997D821C065EA49080900E766C0079B7ACAE7BC7CB3B31301656FD39591E0BFEC2C33F05A0DD633BBA463781F1C519D902342BC12BD16C1AC8305EA9769E489073297784EE45F99B248670749C728385F601FC84C1FFB298B", + "CC447537785226BB5DE712B7BDD04A0CE39226919105F06ECF6BCDDB0CB5EC3B5505B5A169B05480B2587CE4934D2B232A44A6683920A81A6038C59497C9B47FAA62F4F2120B15C360616E6573BCC5A23A88887B50D1A7DBAA429BB00A9F87B63829B1B641922425016C979DB571BA0F1A139267BB362C68F47689715CAD6636402049C2B5C616C321CBA6E43C1C1A48A0E141CF3A71C0099BD183A5C0E59BCA9A2FB637C1B534CB6687493EAC495ACC7C5FCC4898A52E44094FB1B7014A15C88E11A9E7244EE53C2D5B16708C233ED37859268501630A296D63C094F563F0E559C59453ABF05A93722AED5AC0C3CC6A0BE7890F8C3191677C21F70C8153CED3E2BD96A4BFDCE27F86B809D8AB04DFAA837FE030F420B845D23C78CC82A2D7C440897C91C3B726B4622445899DE72BFA263B93C3CCEAA8500B4B0C240046387B25BD98B5901AA670180A2A8B27DE424F4D804A68DCA2E044430D701B67E9B4AF33C60FC54BB3A94A8B8604FA5882A401A5647B8DFBB20878E4B4094136BD4B5BC14288463C2E87F0CDF6D9497FDB5F42F26D2F9CA2E048A757A59B440C2C5642232E714D11FBA959AB9AC52126BF689864AC98CBD1A633BAA3ECF75C09C4C6878994CDCB3E882798EA02AEAF39915DCBCEBFE2BA14E620F53B3D83AB58BBF99509033DB99B0ACBAC29FB4674C95CB94982AC398C2771A8AB6DA1CE9B0771E3D5C2E7655B4BB99EBBB57ADBC7A540F228114639B811C5C1D3B614DAF84266BC4C312FA43C4109DAFDE79000AB39\nsk = 47318B2CC6A9D8BC6EBE7C12489017C03214325B61A2A8541FB783C448C3A31C1D82BA7906B09E3512AF8D00D0706A3D391281F0315044C9C4F92B0AD72C60E18637577B942A442589CBB466AC344438750B86CC86B97D16339A9DB0365E6696B183041543B031C9220E82BFB89C21A5B0A0D301109568B1C00B2B878C9284375949C88394F141ABC188EF7607CB8151BAE654A7B7BFD785B44BBBB5C5A68CA5F96BFE5ABF179CB83A58AEE518202C9119C80081BEB38CAFF81F5EA51811F13BE9491F431B127783227BF9B691031145D6A144213FB4F1C89C38C00C81ABF075C4415586BDF28B946380C948B94D7A0C3A793100842230663F4EDA9174DC7214884E0F552A50D16DFD0A5DDFA7920B0AA50437BFC735A546F5B0F4BB22E174B061BC80E91428547576B6205490CA3934C9B15FCB69611A1639974478800B2CBA3D5243A0E2762BE2F87035295FFF40B56BE37DDC71915434C4AF6472C1E5C519506E691703C49C715B50B360A5C2FCDB79F59C7ADE27380F9905EB7AA6F5042C6A32BAE657C699EB85A53395C0303E87E89800131F96969BF45B3F574A40ED813268603A24F1C3180607814914775350B88A1FA7E1034C9CB155879668950AD5950803ABC0CC58BDFC408FC1F2BF7D3A2972AA66B58844C048150C0B8C89ACA3BD3269474875BF10A94D2B9EA3687AB9547EA59731B73A8849AC7B7C4B946D70B8B87C56B81B77024503BA87485BA3655F669770410E89FC84925B87C008C3CC13C7B9447D82FC2932A1C641230725A422B6219D9BDB5CEEF17E121132E6615075E0B26CF71E91A1593210A09507214716A3405B2503CA5F29D4479914CD10B3457AA62A6BB71BD08736E1519E69F709B8C8439B4441BBAB5D0911BC6737CA742747CA592E5ED734A8AA1B77450A9D4188E05422BD9240E285865D530E718C6F1A816153CC27414446BBA8129A1716171AA60AE086AD09951C2B9AA2744E0153CBD4EC9D1736908CD78E7CD75D0333434715C517633EE6603F7993083724A596069F3270C071B6BAB955844A081A896096F76059B9738D819CA3B6588D5F578058D28D2D0710B2BB2E307A5F9E18533713C41E172A99614A97C00AC0A83A25526C399CC9FA9B74CC4774830C8E754231B04274C90C526DEA7FE3D203688114E7A90D3AC02AE69A139649B754581BB56825A215C3BA282A26C036E5D5785C07C62956B612FC37FB73A7C6EBB506B998D54979FF29781CD09CCB64993299745B34B6D7F897C0E05E1A6966E6757DBEE29AF2EACBBB7701DBC39294DB584C7C3A7841112258951D88145CF73404A17ADB8CC4D11788225557A83B652F95053E8507093B2A8B00CE77E7BBBE83233DC18880F2274472C05E646B90952FE92440D164092A058D69C96869D8A83377A2DA92C2D668607DEC3CBEFC6242B49A9DA97C19C2067722C8D309CB898593B08B5D8138BF2FD1C59081614F764ACB392D7FEB205A85270DFC1129929CF7B53D41031C92944972B8BC9A9C494AB384996647E177A87A101C45C747660AA4A38088A5F7919CA46DAD338576463A1C1425A6C4409E2BA8217827AE83BED4E6C80AB528A6BBC1AD58C868B995D9F72C77E84173C9CA80B3B92647A1DBEC6BB883A4B2160E4DCC84C89C6ADBD955CC055933D3238E325FA826ACEF899A555873A5B9C189117844202C65E40EABA07D9FA94D421BAFE8F3A5E3346B6B93CEF8B75628E4418E2885660B1D3DF32D1BD50CC50757C5227928B32E0C567872E66BCB58128B15C8696710A7B33BFDA469128996F6979F896B93D22910383C90D0D877A56B4B7C77C53C99128719C2995497DD36877276A25FA8B74A4947E223215A314A075585DA457DAAF17C41711363950EF9013A8AD95F9E07635546485A3568AA502D608321061A6999057E705C46B6691183874FA9EA38BC392F718C99DDBBA59A1865A135207A00058A408B6C61772CE777456C92B28A51CE823F7524A26639AC64AA49D6903CC2B2B5B60B59643BC950230362CABA6ABB5BA4F6964331B1F62099CF385BE3F5B43C2B8402006BB3386F5A16354E45118F0B759C3363AB4069EC2C4C15CAC4E07A24FAB0C682548337D157E6BA213C7801DC5A0A7045A442B4939D611469746E9DA665E2E910B51C56B77A035900B25490216C0BB53E04173B3BC454A7A17D77283EE278E7D30496301480C8C1AF6B3E1DCA213B174F968C8A45A3BA2044BDDB1492BEF2AF610B4ED2481AE0823DF53282BA7750FBC7A764DB58E3789CCAEA778083C27ED101E3C75BE5486249F9818A08047F97447773C7DEC3BA7C59AECB5778A09CB7F1182B2E0A01C182A1BD13AB7D72AF97F96F564607A9A970B35A6ADFF275C35C22C2444AD6E997D821C065EA49080900E766C0079B7ACAE7BC7CB3B31301656FD39591E0BFEC2C33F05A0DD633BBA463781F1C519D902342BC12BD16C1AC8305EA9769E489073297784EE45F99B248670749C728385F601FC84C1FFB298BCC447537785226BB5DE712B7BDD04A0CE39226919105F06ECF6BCDDB0CB5EC3B5505B5A169B05480B2587CE4934D2B232A44A6683920A81A6038C59497C9B47FAA62F4F2120B15C360616E6573BCC5A23A88887B50D1A7DBAA429BB00A9F87B63829B1B641922425016C979DB571BA0F1A139267BB362C68F47689715CAD6636402049C2B5C616C321CBA6E43C1C1A48A0E141CF3A71C0099BD183A5C0E59BCA9A2FB637C1B534CB6687493EAC495ACC7C5FCC4898A52E44094FB1B7014A15C88E11A9E7244EE53C2D5B16708C233ED37859268501630A296D63C094F563F0E559C59453ABF05A93722AED5AC0C3CC6A0BE7890F8C3191677C21F70C8153CED3E2BD96A4BFDCE27F86B809D8AB04DFAA837FE030F420B845D23C78CC82A2D7C440897C91C3B726B4622445899DE72BFA263B93C3CCEAA8500B4B0C240046387B25BD98B5901AA670180A2A8B27DE424F4D804A68DCA2E044430D701B67E9B4AF33C60FC54BB3A94A8B8604FA5882A401A5647B8DFBB20878E4B4094136BD4B5BC14288463C2E87F0CDF6D9497FDB5F42F26D2F9CA2E048A757A59B440C2C5642232E714D11FBA959AB9AC52126BF689864AC98CBD1A633BAA3ECF75C09C4C6878994CDCB3E882798EA02AEAF39915DCBCEBFE2BA14E620F53B3D83AB58BBF99509033DB99B0ACBAC29FB4674C95CB94982AC398C2771A8AB6DA1CE9B0771E3D5C2E7655B4BB99EBBB57ADBC7A540F228114639B811C5C1D3B614DAF84266BC4C312FA43C4109DAFDE79000AB397537E68CCF14E8B7E57090D8F648529DC461CA3950288879E88116ACAF57B4A2B6D75EAC6C76CED1B0A025B40A55440712AD8424672E761E9BC400D63812006F\nct = 2AE65FF9BB3921463D5A4FA59032DE79451B71137E7019EBCAC2234F3478E1E4C4172B97515BEAA552B9580D76BAB278B304B83B05390BC98EC094559F3D21FAAEA79E5D0CF3F9892155BF0E4E989D3C85350C66A94DB3D006530119E4E44BE9B2312EFF20F06D762D4CE489BDDEBF30BCC765A1553AA5A3B5F620DE634F64DE66F1E56D288266195795794441353674E93C69B7D86D829695EC15353186460C20ED184D5AC56917276008772AB381EDFEBAA45A36B8294D9B84C4E5518163E98DA4B5D7461D28493039AC8F378A154152CACDD3D3AAF66EF966C0FB298978D9C293979D0582BD8271C79F5922769D8210F4C7F198B73CD0249330F5B25ED55964F2300694FD1C1D438E7BA0FA0A6AD12F66220A390ED79CE1C40A7A6F50C64435BF538A3A2A1BC859118C35477AF3AF986CCE9BE6FE75BCAA59ACF3FF7FDB1C873AFB6CC5B69621F6B49715A0F362CE441961C452CBF81C128A2B81C1A1B667017026C09DD36AF0DBB856F0D7A4B21CD44003A878243955A12E62F41737D81C16180BD83297AC9990976E506684A24E4F97737E463823B025BA95873954C153BD42DDB06209ACF5BD7E9C9CA404D57202F7236FBD5949004F73828A59FFCAD810E038C741534F044A4BD4FCC0668DF733A7609E493D753FCABC6359B959582A5DC66CDF50A8C88A97B9738F2CDAB363F01124526CA23FB047432789D6C1E430974329411F8C1C63936CDF937540F66C2CC9B76BAC4D9A44055386918370D8051CB79C8C703CD37D3B6C1D53675EA2BFC7976D40ECE547FBE3B969804341FF267CDA5F583A95D0169BB2359ABA56378F319F8587E602459AF732CB1559D684CC4F776E1766F1CEB1483A4D1983E8698B56B37940EA9A7FDA8C8CF9C9E0DC724CA1D60E0C572894D2B9835AA9E82C058FB28271A5979E397AE0C2E72629BD5A56B995F2E3D9DE0C7FCD608E4DDF8A4B0638B1810B70D2B3FDC358CCF45DA5A22C000E4BB70F4067884BFFD9E419C7825145BC80491B417A26567A6B91ED7D89E8E9E9F47B24B0FE1C3DACED4EABB3D1571DBCEFB3E3AA7AE52DCC66AD97BC87B629875165FFA709588B4725E64B07781420D6F6CFC2B485BFDB7CA3D47314452A862050555FD324C5A56BAC047F43A3073F07B05BCF14F505CE528BEF347A2CC2C846675E4EA9417B7E741B776DE1D767A4F3573E78E7D5976E73C8F7CD24AEE462294B4E652460C66E6A4A5F1591446FFEE52A0A61526D16392AA40A4111D4715709FC70AED98E128342F7DA9EA80412C749C80DB3D64C5DBBDE06244C18DE5EDE7F550A8E086F21654994628413E9EA53644B2CCCB530CD1B2288BB9E51F529271E9A9EB795FCE68A74DFDD2CBCBBF98407D68E691C11A979463322B1402629C2338CFB2B14A7BB2CF9AC8073E6E5543E3E989B60DA52F1E07859F591DB172A877483FFD523633E1B8DA9E68BA748F2FFEAD7F9D3882E9FC56D4B4329E1A22CE06E11D0F674C568A2B1218BD4A16A60AAC59DC30FD6B8B76C06A230C39393BD\nss = B7A8E7B3C6D244B6B0DCC45947DC91F795ED21A5B5AD545205CD5B210DF37325\n\ncount = 72\nseed = ", + "6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A\ngenerateEntropy = 1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6\nencapEntropyPreHash = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b\npk = 03A20A0337040ADAB8BD449E0BEAA93B07512485BA33F291AF1A44540BD04AF4A3DD2A09F6454D7304D0944674A580551061BA5F88217AA57C10640DC1A97396F138C1A32CF40B0BD9286F88C4087F9084A9012D248C63EFEC072D77AB0E736719A23A913B7B8B62AAA5BB40BE97CBBC1C29EDB283C776AEB9B032E2C2691AEC9CE89617B84B09712B40E2B713E566C714E0BAA75957D6BA5062BA76471357252B72AC66BA97E10921CA2313A232A6BA908DEA13645B5617938381FBCD748A11F61CBCB615C458D056F0D55A449C4F544C6673322EF106010CF139D1C586AED5A5DC210FFF7A60F3138C34A4244398B692C567ADE5BEB55C1EDCFCBD93183E1ED0C2AFF5BDAB67B51E39A58BDB8388D67CC1EC0D7313B7EC8A56CF3C9B73214C4ADA14592794749B6834E9B81A2BA47DE929E9AC7856B56549F40F38F0784BA0CDFC195952D3155222BCEABA0E3C233FF7E19A65822437217A42721F9C060AC2CBB9C4E6BFA9FC3014D8ADD7B4BDF78291423511F9874A07E06A82B6369FE349E08333C7F56B7B7B808A0B4E888A95799A2DF4873944CC43EB958B1508C66E571268E79A69178793E7A4D430507E1259D01C86F999C16772CFB7B4B330114FF55A51EE5407BCE95A6D27875A91773420C24F8734B3023E9DB777819CA2163C431DE46F22F38398D46EE352B815B6B07E1A242B01A4230B59EA8C7B0C3C3DBE2B7C77B4C860660DAA04C452E391C710722C67BC0632C072FC1E5296A2E70932D4D38EFBB96BD636BB41260A7BF27CF5E71CE3708E6884CF0B8584ADC3CD3B5C5EE1003A13731704472A203C8F9B49534309BF2B60CC3E2448E02B5A46D889FFD78FBE722A709A2D5B5C8A7D805BCFF44052C553CB990AD016079BD87DB7573EB1D431D1E549EDC8AB56A0BF52999F32555E8EF2B03182BD8D812CCA638055A73B548C8B432A2A7D4A6A074AA212D50362D1382747CA8DBB95E03945D95B995D6346D7DB47B24B86E4F774F3767DB7996335B789733CB251F9B1EDD04F8F8CB7AF4C947AF224DFE0AF6A42C7B65120B9C18ABE9161D88CC5C4780FD74403CD177F7160281884A11CF686F0F523F39CB7AD39B780F13A8EE83C0D646F9D85BABEB306D53A7DF53AB00B5A1AA8C215914A48222940FEE10D1939BA5C93617690CAE113A59DE071C969436B3771FC50B2F4AA641A4C852922380A420FCDFCCB81816F4B474A2AB293A4D97B2B280CEF031148EA7E4C9C0DB7E7CD0E50B203A6B7519C3CBC8062C9B60B8B81CD956463B8180C67F34BE4868E3BA94B9F0226D9F010D9EC5EF0BB62C865C807184B96526D94170AF9474BBC100530F7C77E46B98C2AA41F92A48D8027C855C7F84684389BCC8E7C67164A204BC5C0C90828FAA439FBA235B6F20785CC8EF4C090A708BFBBE26E1933886CC96AD9B4562A119D4C66589C85BF0E55606886206734142D432C1B032E0AA93EE3731F069A8CC069A03B95A8AB873B447A04EAD3A32BE3054AF834882BCC581712BE18539B805577E50FF5D982C98C0B0DFCCC96A4C6429281068C8429997DC17A6600F0736B8453E3D77636FAA8D0CA89F9193BB34819CA1117EA368EA23198EE11345C613993EC052992954099BB9A086057DF0C5465326E1932AA50DA74AA8435D9294FD6B7C05A153F30\nsk = CD28AA8C74142A0508C2534D5ADC64284806BB2C653BB9783ADC640E9945C253AF86F57C19B42C6697AC85D1BFA46B5231559C11F5A0DA9B2BF43C40001D4E6C00B81237343E15A41DA190CF8940B641A4B42B72D9CC8BAC681369DC07D80AA62F135B0F956355A4A68E575F34393C42BCCEA68A7A63C269A5821557299FF63B9F0161368F6084132C8B56984F4D1626D7436DAE2596E1B24A86562374B066D2483A1B354FFF9766845480FF396F6AD089B724B0F15A34C2288DEB05A8418909803CBFE2F3C63C30056F358FAB798F4E385EB0E35ED0C38ADE7382787A2502D117AD0BC6CC0A4746AAAD23345F10074B21970C18EACC898472766B2313472DD3348C82F69B7D961CD35A8C61984E7CA20AE6382F04A977A72B532A1395707CBB7CD595E0DA0202498058E59F22E0C340C438851674E3AB1E0D872FDA3BAA7F87B67F449E6BB461BDF1CD771475D5B59FACC30181599DDAC8CE68DC2DE5741B21422FDD512B39D9633ADB202AF3941E323C9326297CB58086C3282F722C4D50B94B32153FF30B91F07A811A9D9E07B7667846806B6F7071AE29323156B668F831A9F79AB7949CB363DCC8D151349DB4B5EC1266E7F5AF98105C95C0A4D47648AEEB01FBE1113948B407FCBE199BC2CDBA40257745D765C6A0766012F19DF41A770E96CC95D3CBC70549F7E61914A73DC71062F2A3A377EC26DED59E0CC85B11A74F43C3237C7561CB7046C0E660B5BB0BA0634FF2B211438A9B9B906F241B04B2439F29A3CF0AD9128D683F0C2C26CA050978CC179872B1664A751458C072106FDFA07D97105188278268B0481018782F361D08555FE5799A0654398285B378F7A9F143CE20673184C75E8B662085899812912FB8A60485921B2F7B3FEAB95CB7AA327D8B9DBCF7C7256A131270B731E33F8F555CF4F8B7A1E6AABB4C83D2938B7B21BEB1C3B3CB3BC08BF52FC1F5715FA89EF8E205D85862F6A2CF420592AA24568FA0B8DCBB90D0B654C7C82C7411B6C3E219F46C352AA034C4FA0AA4FC47DAAC204B351497727B96714359A66466F6C4CC2B83BF6B87785367C7116489D6C5FEB975E41C4BBB2A3D8FDA920021C523227A438374D96032F62C41B17422584AB5880475CDDA8B7F4844E5420C25D97235B0ACF71012ADAB59298BC80052AAF1807E8015695D92184741BAD318BA9AE27C306A2E42C80512534963B70B9D0B7F5AE70326C33E7D43249E8C9CE386947C167C8F33C88947244989C45B4858203249FA5A136734153CD94F1AD467B5043F7ED77F58D34490D1B5F9E323F3E2146011921B8A9F94E419BB85AD965443E7F4A73534457BE43EE5F677A63A7738762B799600FA0B9CD328AE4CF507C1D9845EDA77C30BB7C39C618AFB402CD9B016F0092CB61E8BE13A18925CA122A142409B8DC637A364093CD76925A194AEDA21C61709255BA2DE330693B888A6C2C6F0C39FA5B4C7FCFBCC198B3253C0ABC5AB5EDFB438ED3A82B72B5F54A39D21C37879480C4A648F182A94EA566C598BA4CF697140A20FDF4CABBC540B80E8664216A6E880553899964A7B239D00C68E720706512CD2A58B9C49BC0ACB90283B506CA196F7855ED69AB21F059A11FA3FC4670D03A20A0337040ADAB8BD449E0BEAA93B07512485BA33F291AF1A44540BD04AF4A3DD2A09F6454D7304D0944674A580551061BA5F88217AA57C10640DC1A97396F138C1A32CF40B0BD9286F88C4087F9084A9012D248C63EFEC072D77AB0E736719A23A913B7B8B62AAA5BB40BE97CBBC1C29EDB283C776AEB9B032E2C2691AEC9CE89617B84B09712B40E2B713E566C714E0BAA75957D6BA5062BA76471357252B72AC66BA97E10921CA2313A232A6BA908DEA13645B5617938381FBCD748A11F61CBCB615C458D056F0D55A449C4F544C6673322EF106010CF139D1C586AED5A5DC210FFF7A60F3138C34A4244398B692C567ADE5BEB55C1EDCFCBD93183E1ED0C2AFF5BDAB67B51E39A58BDB8388D67CC1EC0D7313B7EC8A56CF3C9B73214C4ADA14592794749B6834E9B81A2BA47DE929E9AC7856B56549F40F38F0784BA0CDFC195952D3155222BCEABA0E3C233FF7E19A65822437217A42721F9C060AC2CBB9C4E6BFA9FC3014D8ADD7B4BDF78291423511F9874A07E06A82B6369FE349E08333C7F56B7B7B808A0B4E888A95799A2DF4873944CC43EB958B1508C66E571268E79A69178793E7A4D430507E1259D01C86F999C16772CFB7B4B330114FF55A51EE5407BCE95A6D27875A91773420C24F8734B3023E9DB777819CA2163C431DE46F22F38398D46EE352B815B6B07E1A242B01A4230B59EA8C7B0C3C3DBE2B7C77B4C860660DAA04C452E391C710722C67BC0632C072FC1E5296A2E70932D4D38EFBB96BD636BB41260A7BF27CF5E71CE3708E6884CF0B8584ADC3CD3B5C5EE1003A13731704472A203C8F9B49534309BF2B60CC3E2448E02B5A46D889FFD78FBE722A709A2D5B5C8A7D805BCFF44052C553CB990AD016079BD87DB7573EB1D431D1E549EDC8AB56A0BF52999F32555E8EF2B03182BD8D812CCA638055A73B548C8B432A2A7D4A6A074AA212D50362D1382747CA8DBB95E03945D95B995D6346D7DB47B24B86E4F774F3767DB7996335B789733CB251F9B1EDD04F8F8CB7AF4C947AF224DFE0AF6A42C7B65120B9C18ABE9161D88CC5C4780FD74403CD177F7160281884A11CF686F0F523F39CB7AD39B780F13A8EE83C0D646F9D85BABEB306D53A7DF53AB00B5A1AA8C215914A48222940FEE10D1939BA5C93617690CAE113A59DE071C969436B3771FC50B2F4AA641A4C852922380A420FCDFCCB81816F4B474A2AB293A4D97B2B280CEF031148EA7E4C9C0DB7E7CD0E50B203A6B7519C3CBC8062C9B60B8B81CD956463B8180C67F34BE4868E3BA94B9F0226D9F010D9EC5EF0BB62C865C807184B96526D94170AF9474BBC100530F7C77E46B98C2AA41F92A48D8027C855C7F84684389BCC8E7C67164A204BC5C0C90828FAA439FBA235B6F20785CC8EF4C090A708BFBBE26E1933886CC96AD9B4562A119D4C66589C85BF0E55606886206734142D432C1B032E0AA93EE3731F069A8CC069A03B95A8AB873B447A04EAD3A32BE3054AF834882BCC581712BE18539B805577E50FF5D982C98C0B0DFCCC96A4C6429281068C8429997DC17A6600F0736B8453E3D77636FAA8D0CA89F9193BB34819CA1117EA368EA23198EE11345C613993EC052992954099BB9A086057DF0C5465326E1932AA50DA74AA8435D9294FD6B7C05A153F3082F68B15681CCA5C2852C18D6E88BCB102A059C1D21936582ADB71790CC0A335273B38BDDC18488024EC90E62A4110129A42A16D2A93C45439888E76008604C6\nct = E7657F1E554DDBF021C005B3B9453285A16D4D8CFBA2358A97FD2AAE89F83DBECD0447BDBE9589DED04BAADA5114F3BB1B4B775C8BA614008BA2D5929EDD4D3DAE28253164D131CDA2FCA2B1D4588E176892764848B62172F56AC74C2D9052347F857286781015FC8CC1888A3FFB77837B1C79128D15A405DCF2A68E47DC7FF1131C89E5268033C9304088E6924C59AC82B424122E5B85A55059198598E2BDB173EB0FE9E407B46228A4B16690097BC82941A66404EA7EFD014807CB4CE9D8EA9F4CD3B3A7643A5FAC11D493197DBAAA40BEA54ECB8E0FFBBD887B2501985C019D252D3D663EAC74466008FF6749AC901F3470E755269BBC1D77690F4880B0BF0FD8F0115C2B90BA408D3E1FE46A845A47DCBB404E4B12A296E304920C3828191CBD9B9C81A8BB02EEC087FC9F018EF936297D7A52339DF66396129E4A1C18820CB1BA69B26C9BF1B68C886F8ED7C4F61EBF", + "2AF19402AE037D990C77FC2699D4D22683F4BD46A105459055C5C713E8C1DB1DDA5CE6A658184D26ECD10E5B1D523241E494396A99DD172372737129C29F8C74BC30858076FA33034C44997D084A6C5BC791C4E8C9869B1520AE29D7901B743ED50E9AD108B37132F34FD1D05FD4B5AE9634AE0B1B1C1C46FC1FA1B73A794DA19FBA6FE28A299E6EA7B738E45FD1FC0628968F32906D9486E3AAC29B488A17A7D6437A9F139DB14C0B6F387DFF426E107D2BCB3FB9EC5658B4351A20487C31AA367858355AFCF508F4B6740D912F726C45DE57359683FD9CB65F7F0BA8AB8A319830E6E586C293E953539F85A5C264C30721137128D0E0217D69CC195772FE97D536B8B47643B1A67B90E198D320652833C03F0C382A45F86522966303E3365C6F5B743C53B4F7CDB931BFC894211F71097EBEF6ACA00074DA9465528A82D24718D54473E333C9070EDAA7EB6DB2CDDC806F5AB277EA8EB3DD1C93EB6F433CFF71694EC6560D2F664EA4113CA1FEC25F37BA7083780A2D91EA6F679F3A40172154A053983099F83D48F3BF50C795A832C9F70C88407439607844BB27EBE20F602E0A88781B767D6C2002960B2BB98754A4618301D9973E3FFE8513615F8B0F13175376AE222FBFE36C8125A570719F62152C2945BA648F534B85CA8270CB7DD5B955E25961116DEAD8915466ED19AC772D256B7DE7B10A597E44FFCBB0032C85FC9E5A8F609E2C1C9BD888ABA0F0708B579729E6B7E5377641DDF0649D1B506677D316076E482A8F166CE186448E504B4B9607CF5F3AF8F7B5389049A79E15473F130904C3BD8DA512EBC26951134E767D6D5BAFEE7C6326FBD96DE4239B7229D69331E76EF0D165276E5A2D229D49E3215803E0B82A63E0B20231271DF111F1C27F9F1632E4F86E90DB18A4254521939F6CA60AF9BD7AF584B2109DB991D9E2B9223E0ADD7D5D92B597D0AE7657629B256B5ACEFA958422606C84EBA6C136925815007D126322E9854497907DDE52CB68F65AF75370CAF56467DD1D6E9DA860D26DD4F1E33006A6F41CF3423E58\nss = 70CF00481198A97F14E0870C268CA55B6EF787D130A4C32314EB7C0A531CD188\n\ncount = 73\nseed = 53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864\ngenerateEntropy = 3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99\nencapEntropyPreHash = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b\npk = 611BA36D3A65C0D17CB22B7F3A682B593595B1C682D521A16DD621A05A7D22C9B2D29C9BB75CC5A8567ED3A545BAD39E2C85CEC0F83F37C6AAF101BEC273BCA5D606A5E76FDC183175A233C93373E956580A522BADD22D97D71199C1A7B4149E652686EDA541E69187A2ABB68F89AE9492443547CFDE7B5D609B4835911D154C33E49248C4CBB244ACBF03E93E52E71ED87A75CBC43C3F505422C1AC31C014E82009D4B13BF2CB7DAB16896A320FE6C0476F37767CCCCD80850DC94B410B983FBBCB484DD09B44A817FD95686106C710D983CD2BBC11DC4AE59091A401A6941BC704142C792C407F7524EDE1A71A726E2F921B0626768307C31DAB514A783FEBD67B50E93479D2C7D1787142F591607B7A5626A718D502B37A6F5B8766E8175C6EF276934A12AC1107AA3362840513D3F5C02042AE681181DCAB30F6810389DB07C3FA1790345E786031E3196BCC01C22BD064B2F9C439D7B7A7B7633232AAA4D88E0288CDB791049B8A8C64883637098DEF7C88FBCB974554AF0F3C51C70A758176215871227869766452871602093D6949E1D078691537D9D7030B36926147AFF8151CFBA202C0364795122D1D748A18289CDB33982900B38EF9AAA5D10D146985C757CE5CF82AE0A2489E0C00C83550D455A03FC885DC7A5EBCD71529ECB0CA13CE1259186F9B0CEB4B90789ACA0762C8BEE063780801CE365540F440B0AA0128103AE0F5B4A5D9B98FF3AEC5793E8FD046A7E15B517C5C4164105E87C593DB19B85792B6C705E615C4D95C38BC4BAB4F30737A20241A3189EB38865C6B60F6341DFB931626E729CE39313E122687862BCED934CCF88411730FD066BE831542ABC5B15A1CB2D3F0AEACE904CB419754D9A5CFA35D72E570C8D3B0BDE5A5B18201F14CCA3E3564C16769757A2DAA89B03DD993EC8B7C9FCC63098478AF1890346A8824A4B142F88759F382292AC404F436BD21282D6A3242417B36211C84B75F388151F087186CFC01E59383E8218039DB15DA50120AA1C5489743BC42335A774F8494A4244ACB6677B22A46224DF7BDD8A9292AE58E07F3068CD975ABB51E44631172535E52C910B48748A190C50D877903A4C7B9F4B18993669D254EF566058528A157428111D43D360AB54343ADEBC2A3636720F1E0C8CCFCB0FC3B71B55353C2682946408CAD171FB711CF0B3AB561BA6722647ACEE4B8DAF0AEE2C43352609DC617549841ADAC54ADFD3319EFC715DD917AB2B887DFEB49CBB6323ACB566E43638A5C9B6F865DA4157CC3F866066A551230A335510F55733CA4F3A6329AA0830894E06A05EE578C45B3117FD07D62718A9842CED5F49710F7B15741BA5B06298C550B96BC6FDB0561926240FAF09012E2CB49C66868E27EA318AAAC50BF882C5BB8E674381A96645B7A7DFA936201933C31955E24912E436528027B39F74A909AA5EF4653CC23C5E448BE6F81088FD322FBB1779BE52AD60005C2F57241932EA3B435C47A39E6E0477B989C00BD5EA71BA671D8A37DC64D36216CCEBB14E6DC7420C362926B555598B92F6A78061423A4CC8961D57733982FB8C78573C35584185FED801EA674A7FDA06008517B42D1A45FCC50416883D0963D3B744EDB5E8548C3B3DC474F7843C49A8DBFC939C41AF7F8EC6C8354AEB0C67E05EAE0\nsk = 8DC4A33D0A013D102A7ED6A5303693669033816BCE0C8A83594695531999647A48F6708C65220BE4D9A60F013201A36EE053796356B26E3617126C3D0A354D2FBB82312A372FFA37B939A7BAC8AD0E127F18EABC771462FC57B542A73BB7067FDE6BCFFE4982E6DB3394264D34DAB222318856BA8B6919C5A0A667866C0D2166B69AE04432C044F289BFD7255542CC7946B82C2DB388C8B656F234A3B607C2F6611ACC3A5A12C8111E42138ABCA9B8DBA79921A177682C2AD1138B133636951F5AA77A52B7554943AF52F7B53D0B84ECF44FD77018F7062E564C5E58753994724242D6B3A8F8A66DF518F7E13A0A5C1C4B253DCE12AE197342F5D72C296498BC9888EC347F528958AA689C8DDB81870184C9E2254F918B7465354826870300790044165216C8BC279AE93854381C28CB438BCE444B2258AFC3A84CD4F91DE8373F877B30137C4CE4664E4D330BF763B344489604E97F4C9C24FFC226D07C5824CCABE38CAE22487EA2EA0E89920F304BB911B401F45735089512DCA2298EA1A57F643CD7524A3D6C9F055B25EAA62FBDA318A7B8C8DC9C5CEA953AD5170C0452A7BC04469987712D0522256A1EC52961561175C32ABE93DC5ED37289B9D4CBD3966911FAB85FE47B3C68692CF5A845286BAEF91493E15C6D23437BF7517EC5CF609C8628D82FF7CACB54D4A5EAD25C85F59AB51151F9350247782459B598A2089A85F2C9BF66797E863A4CA0732268A4E40C57009D0C7D1AB1FF46B78E350DBFC19FCAE823BCC040183A27182ABDE00A966A6075E68C011AA62EEF913024CCC85B460098FACC9C4C81D17C577BC009B8F9416D225D156C4E75B84691A90948D31883B1B2AB3635DC357AE867B2496983CF9595423C541E3C17947042B3D141EF825C99862302BA911C67619434B3F9CC489E8C8ABAE92AF1EC3045C895EDB41F745AA1F3D1A625E47EABB49432129A5608571431C4890C8FA5769563B8B1F9BA3C1B77B034F568038865C90304A4F79F65F74C17FAB9E6B52236CB636EF5B686271F955A9E889B7A1EA1A010828AEA1A838DE1723F0149CF172F48890161C34039E99B36185F068B5707FA476D650BF149479B8C928F93089A4B941047B5B528135685797E0B9E65F595D9016A614393CFD630C6A217D0A03091853F606B238EE13C92C2B5D9E19B2C57638CE82A3D767639E115838B8EEAA5A47B7B686EA05CC088ABD47A10AE593AE39A07F55CB4C1347ACAF7CF59422182749E6AEC39D62CCB876094BA3CC0B871C57A03A00AD67C5C1C6EF911C6DC36B13CAB713BE1A6610CAA46DB4EBB86B76572A0BD60ADF163B325C89B506C33CC343C37A2BCA7CACABD90494F044B550778677C2EBEE76E03622705556B509C204087B5C5E5936C0153857691C3149521B800B76C43195897067529A4A87D68E974ED57178B7980EEE227E4150AF1234025757EAA3B645064202D632EAEA3943B40CB10922BF569AB2C44867C411BC8240D110134D78143D3D44B450056BE166B57921FE64A44F80968A1941D91A971E10C347ABA369702B1ED542984F28B6254BF61D94B69F015B0E32B05E8897502238FD21D87978EAAD45BF5997654B40A903319CA64095C9297611BA36D3A65C0D17CB22B7F3A682B593595B1C682D521A16DD621A05A7D22C9B2D29C9BB75CC5A8567ED3A545BAD39E2C85CEC0F83F37C6AAF101BEC273BCA5D606A5E76FDC183175A233C93373E956580A522BADD22D97D71199C1A7B4149E652686EDA541E69187A2ABB68F89AE9492443547CFDE7B5D609B4835911D154C33E49248C4CBB244ACBF03E93E52E71ED87A75CBC43C3F505422C1AC31C014E82009D4B13BF2CB7DAB16896A320FE6C0476F37767CCCCD80850DC94B410B983FBBCB484DD09B44A817FD95686106C710D983CD2BBC11DC4AE59091A401A6941BC704142C792C407F7524EDE1A71A726E2F921B0626768307C31DAB514A783FEBD67B50E93479D2C7D1787142F591607B7A5626A718D502B37A6F5B8766E8175C6EF276934A12AC1107AA3362840513D3F5C02042AE681181DCAB30F6810389DB07C3FA1790345E786031E3196BCC01C22BD064B2F9C439D7B7A7B7633232AAA4D88E0288CDB791049B8A8C64883637098DEF7C88FBCB974554AF0F3C51C70A758176215871227869766452871602093D6949E1D078691537D9D7030B36926147AFF8151CFBA202C0364795122D1D748A18289CDB33982900B38EF9AAA5D10D146985C757CE5CF82AE0A2489E0C00C83550D455A03FC885DC7A5EBCD71529ECB0CA13CE1259186F9B0CEB4B90789ACA0762C8BEE063780801CE365540F440B0AA0128103AE0F5B4A5D9B98FF3AEC5793E8FD046A7E15B517C5C4164105E87C593DB19B85792B6C705E615C4D95C38BC4BAB4F30737A20241A3189EB38865C6B60F6341DFB931626E729CE39313E122687862BCED934CCF88411730FD066BE831542ABC5B15A1CB2D3F0AEACE904CB419754D9A5CFA35D72E570C8D3B0BDE5A5B18201F14CCA3E3564C16769757A2DAA89B03DD993EC8B7C9FCC63098478AF1890346A8824A4B142F88759F382292AC404F436BD21282D6A3242417B36211C84B75F388151F087186CFC01E59383E8218039DB15DA50120AA1C5489743BC42335A774F8494A4244ACB6677B22A46224DF7BDD8A9292AE58E07F3068CD975ABB51E44631172535E52C910B48748A190C50D877903A4C7B9F4B18993", + "669D254EF566058528A157428111D43D360AB54343ADEBC2A3636720F1E0C8CCFCB0FC3B71B55353C2682946408CAD171FB711CF0B3AB561BA6722647ACEE4B8DAF0AEE2C43352609DC617549841ADAC54ADFD3319EFC715DD917AB2B887DFEB49CBB6323ACB566E43638A5C9B6F865DA4157CC3F866066A551230A335510F55733CA4F3A6329AA0830894E06A05EE578C45B3117FD07D62718A9842CED5F49710F7B15741BA5B06298C550B96BC6FDB0561926240FAF09012E2CB49C66868E27EA318AAAC50BF882C5BB8E674381A96645B7A7DFA936201933C31955E24912E436528027B39F74A909AA5EF4653CC23C5E448BE6F81088FD322FBB1779BE52AD60005C2F57241932EA3B435C47A39E6E0477B989C00BD5EA71BA671D8A37DC64D36216CCEBB14E6DC7420C362926B555598B92F6A78061423A4CC8961D57733982FB8C78573C35584185FED801EA674A7FDA06008517B42D1A45FCC50416883D0963D3B744EDB5E8548C3B3DC474F7843C49A8DBFC939C41AF7F8EC6C8354AEB0C67E05EAE0104FBF09445794C0EA0654F5CAF70EE09D51C8386D4E1F467B10633C710AC2A4A3729672816F3EBA84C9638A79676EEAC0F22C8A48E0C5D50A26FF0844C66B99\nct = 8B40CF1A2D7E21F68E130A85C5A680C65DF56B5CC055D26AD8E6A7E6E75BF88FCC88B5212F2B78521DF1A8F3B1A1D3091CB9270D1AA7865FD1E3AA8BAF208FC1A8B80CDB1D0F229489C15FB02D60F44E09E942D9E36ACEE57013F2F40C17477DC8D2BCEB137E92C140314E8D6F38328056119C757493633D2CDECA9C0E1E727F47406BDDBB7A9B056EF6E4D149498CECC738D835D0D99A5703B0B9BFF04883FB064009F6961363323B7C47E35983F04ABFC00F74A63923DA69CFE3784F8999F6E4ACDC9B9E06E743C03B4C0CC2A404DDB7654888DAF0FDE21FFB1A96D81D95EAB5EEA064938BC105439E287EAB89AED0824DFD4CE65ED0B8A8FFB674AE38BA39A1FA3A8DCF36CBA494A5855ACE0B4F8145AB9C636F1A4D6AF147FF23F94C021E2DA8D0D05564D6C85E502E753B8EE49898B66B6F078A99675435FCAB58BA8C9979761906986DFA4BE67314A3515AA24A0C2757A95509498E08EEB103AD02BA5711E2C84F25E651A611C5C5E48DE5BA54F9C2E6D9930D7F861D14F5CFEF3D297593ABB5E77CEC126846E15238FA7984D05E86DBDB12CB1D44445F9538F89FEE20F677F05437BC27068C61D4D095CC68327ECA3764972B494FD2838400FC3A6F6C64D4B17683A7E778C3807C6F1C1C6A4D92AFD6CAD80DE8C57F06BA5919B10AABA0605F19F61ED80AA119035F37D3F6D8A01E2D72E6C53E47489B5DC876CB99FA742618C9E5016EDCF26D78174AC028C832A1C1AE30514ABF95C35A35F9387D3A30946AECDB5642C0B84150FB8F0ED1DD06F59FE575330EE2D9D5675AE705986D1308923506D47EA2B2FFA7B92FC2C7B2745A07F6D331BA484145C98EF78736A77AECD75C56D719EF112646F57F6166986FA33655D8DB7D2171704C5D69AB50A9588EFAB7ED1B834D8903F2770CFACB204A4B143262AFA85E20DA03D94C22A39A9145B9143E4952722C2CC6DA0723566BB2EB9E1F2C30814A9B80DB5192A673D3A8E8003D30C910B9D31191941E824563B41DAB9FA47C6725986D5EC406B8E43915057D1EB15F68EAE588289D5C4D5AFC0BA4FE38D765786C4F4820415678F79330138D2FEE5E060DF6FAE9B1CAC289FE2D20B298100D0FF4EE76B59EE7DBCA227F4579BC507EB05AF390A2A445BDFE1885D8659A776F3DC6BBB760F93598DBF29F80108A2F007C901F158EE5328BEA6893550FF0E2B2C51FD5FE1269177149B89CE127A7097832003DF2A420FE8D674EBB2CFAF2385C13643ACF832E2D27309A6246FDB1CEC405F1C39AA2986BE172A48F8054989DF59EADF564D99E075CF9053574FBE0B5FBDB1E4E173D4336A8ABF77A6348CCCB49B5B1DC1D75ADC8647792D3A6C4AAB50FF8C0BED7E3A094D0A6882F4547317275837DC7BF460FD37A396E6A4F3E13C404239C58C9EC850FD89C7359F9BB2751FB60A932EEEBCDFBD21C8E3527E4455352AE13D402D45CA7948E6211CE31ED48FAB0ECDAD75D0FE5CF564D521FD2EC76BF52829606EEA3170BD44545B710F2D731A18BBA457B4530EF9BAC\nss = 2E8FF9C053137CA6B6C31CE8BA7F14135A7E102C211E68EB99DE12B94273F9E2\n\ncount = 74\nseed = DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E\ngenerateEntropy = ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c\nencapEntropyPreHash = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f\npk = DB0A138C9442FD3A7580E68EEC01077D31525465BABEF901806363A2D664EF8C1908A30491E336E27B0F8690AC71C30ADB145805A15FC654AB8982565EAA96FECB93A2EC7EBB697652965FC5AB837F6B7A20E224E4361977B71C694A88E5252F608CAC97E97DD7C80A5AD10D62681B57162269F7B8D812AF039226CE2A7930E43007C0B3EC6A4CDB3897EE85796D051CB053881E1B9706A572CCC75D0EF32F92610C40DB4553824F1A352FEFD979A310124B9456A9106367EC6A50DB6FE0B057FDBB00A46028C0D6A638BB7F2139CA6DF68F014C4E1E0B79670869353912B5D67EDD4B77C70C067AA76D174CCED6C7A901C65737082276188CFFE28BCFAA2604447E68D490C0F11CD22B8C351C2D63E7A01EE460BC408E174BC4A6CB023492C6EED42F5D85244EC883B1B49B8E3584F27835F21B6B2E6060E0671F289771D124168E196EDACC1ABA26CEC9E09FE7367F46893C2EA3677CAA3005E34E722608A3B64A3B987289952DD695A82DE89B9034390355C5E33546EB833F602CB9324C095BB4CF66C05FA0AB98D69BBDCFF155C3169F3DF2A575901724B678FB080B67F32240AB8F0198CB43176F6FFC93FA602748D591F0B2ACB9AA67A8D8B15C27140C320B0EE040E737077A8C9FD6A20DCB865FF51C41808757B0CA750C502A356B1C7D821F1BF804AE2B337819C5EA89542E079045C887BA6550E4F05693F5C7012424D37A17E2294669C0538CE69A1F1C1F121784E3C3537424BBC4D73CF1A685F03A24C4BA8FD603B328D2A07FA2B714DC1EED17693727732EC7BE2B02C0614CAF3D42B222061DDCD758A0674133E6CFC5362F855B717695ACDB971AAF16320690606C1C42238856D757B5D610BD64427F04C97ABE1BC6B0185116CBBB2DCA28B5D7A9AEE205DBD37E92BB36311C8936D958AA1744CA67332A600D8C719377273C7FB0029F27C75817746E1058DD196DE71B0E4302682DA21B4EC1BECA3CBDF690509573959D816CF5FA034CE01D6A4AC477E3BFEA75732678AEA6C0A5401C623DC225C7A9A7AE6A572F738387181913CC71B9379A5A2BBDC45773C6A1167FE756E13731F47226BC678331312B99428B07B2122B2B9DC86B01C5F090FF632FA83B598863C0B42623549CA831F66BDBBBB1D4747D56A97DCEF9C81766A3D90043C1A99CE5E81105E9113043342A539DE446A7C5F9C4B46A8CADEC388FBB8BCA527D90A56C649200CB2A7F968611934014F9A7B6FAF3015BF6494EF72FBA0C7BA40C499357ACC96562C65B9CA7C53231045E35771947172118EAA02CD95F7137C93E2159D9389607C3011A76363560A97DF950B0329258B0126C7BC10E4081CE46B7C7B0AF0752B038386E9AFA2D0A7543D85AB909376B618C0A2D33875D264B76941430E81C48832F43270160176ED5938492A06CC08392237CAA8487ABD3C83019000BB6671784109C7BC4C2A0362A5B5122E620ABA511C49CA42D75091B3B1ABAAD9B8162BC27F182AE310872E789CF05F6C949598C41C3B73A1A9CC0808E68F95C8AD8392F021F77C79618685DB2FB1D04A9A8ACB8441CCC764AA3B191736F5A24AE31C23428390C1C22C6A6052664DB63B94960A433584036C05E031A07823A03CA153015FB2665C77D8FCC529F21AFDE0D4F32CBFA399F2973D812F516C86B\nsk = 38BBB649E7520A59AC57783E32A5022489365713CCE30171AB46AB219B7E81369AF44BAB6F5BADCF613E963938A0829ACE625BD8594ED3C0981C5963F68874AA87685599041C4C296B4CC181E57667D499B2F961F44773CA958193E97988D816D702078C0147E41390F503921F139384D75EFC91CD08544536B4C9C09BCC2914A807E090D98B5C07C1A4A0C16FF0EAB557E5CCC1871BA1A36FF66B1ACD113FACD6BD16053F22CC85634A3D56E564E30862AA1409D48AAF92643B62009F8E206C2C8BB7F357B9432A8474349C3E1679F1D154CFD4A373665A86C481B9C3163308CF3A1A265A6313D0068BA2181AE5E5A1114995005C8FB574C4A7DA80562953348A80BC23CD90C37A2D166EE4E895F2A429AFF3C9EEEB869EC9982D367C5809396987A2EFE93DFDA2CF45E774CC3541BFE655A7280AF9B7601FA5183AB62682465FDB273AB435355B84563047BC4C6204AEC310D4B91E8B849182C16A57605A6F5690D3804D8857379E11B324977F30B461954A17CB16C4DD93761224A47F4C680373C51DE251CB69A2C737CBB1F76D7278033AE86480C7776CC7CA02393F333B6CC00C200AE58922756D3664A30D7B262302672C27A7496746F8F56797726340C734473522FA880819D76A004A480F48B74F7C6EE1998741D39FEC12759670B4E8057AEDC67950B929E200526BA5A27E0BBB67570BAE100B77D525AF70B7B6143A7419A35273C14B492E1E42C5B5918A62F3C829A50C1FD8715B030CEC454C90C72E6509AB1936AE7490C6B62A6720A840AA714F7B6B0134335C75C44A421598B790631E2CA497E256BE08910B69C01997BCD20591D1967EF5EC5C035B0C1F19A01BC0103DE6CAFDA45DB70950CF551DA2442741EB7233B36396C124C6365A83B66D9CC896FF448F54194FA05267B8154895173075039143DCC58062CBBB1946A917ABB184788052920D1428C856BAFB3461A463627EC7430671CE75BC2ADC95622EB2925A582A15E487787389BCF14DFD84801A37BC39136CC1A49CAB7CB924772606D48D3941BCCD3221EB418B12A6342AB6C357F273795339BBC720439AA9CD5A478122B8B01769EDB013686C8E872A4E2C049A755A8F954614665C61D5D9AEC7D67CDDB779512A308BA3CFFD5C4BC642C091226667C40957C17B3C92BEA102143DEC663B6155464AC7A9559C533A647C5A106C38972A26BEAB45C2F04C974C9BB860BCA64615B6F0782305C81862ABC973D280088BAC791876D3172D4E340F26452F60009A49989BEC107B680B62CDC12751F9079ED07C28143A405A600A974230B20719B0953DA3C2DA574CE2C31786C77600646E25B3C305F6507D91084A836366C273D62C526E0630F9B483CAF335D6BBB5BCF4ADEB4143443A07055349CFB690948487F7795B67DC2E45430E7A5C9564CC84CAC0AD0832480AA844417446B9B086A493B7AA163B76A50F35B7384BD054147A8621674843C3040CE06EAEC68B6CE8A2C5B42390C76350E10DDDB35C9F4C4A1CC148BA08601F92B2FB12C9088922C3463139239A62E878E4DB61A3529A8FA7905A7A1AAF90216DAB5026469B27D4122AF5561BB91D111A721A78587EEA259A4C7F6B743574398E30A1", + "19DB0A138C9442FD3A7580E68EEC01077D31525465BABEF901806363A2D664EF8C1908A30491E336E27B0F8690AC71C30ADB145805A15FC654AB8982565EAA96FECB93A2EC7EBB697652965FC5AB837F6B7A20E224E4361977B71C694A88E5252F608CAC97E97DD7C80A5AD10D62681B57162269F7B8D812AF039226CE2A7930E43007C0B3EC6A4CDB3897EE85796D051CB053881E1B9706A572CCC75D0EF32F92610C40DB4553824F1A352FEFD979A310124B9456A9106367EC6A50DB6FE0B057FDBB00A46028C0D6A638BB7F2139CA6DF68F014C4E1E0B79670869353912B5D67EDD4B77C70C067AA76D174CCED6C7A901C65737082276188CFFE28BCFAA2604447E68D490C0F11CD22B8C351C2D63E7A01EE460BC408E174BC4A6CB023492C6EED42F5D85244EC883B1B49B8E3584F27835F21B6B2E6060E0671F289771D124168E196EDACC1ABA26CEC9E09FE7367F46893C2EA3677CAA3005E34E722608A3B64A3B987289952DD695A82DE89B9034390355C5E33546EB833F602CB9324C095BB4CF66C05FA0AB98D69BBDCFF155C3169F3DF2A575901724B678FB080B67F32240AB8F0198CB43176F6FFC93FA602748D591F0B2ACB9AA67A8D8B15C27140C320B0EE040E737077A8C9FD6A20DCB865FF51C41808757B0CA750C502A356B1C7D821F1BF804AE2B337819C5EA89542E079045C887BA6550E4F05693F5C7012424D37A17E2294669C0538CE69A1F1C1F121784E3C3537424BBC4D73CF1A685F03A24C4BA8FD603B328D2A07FA2B714DC1EED17693727732EC7BE2B02C0614CAF3D42B222061DDCD758A0674133E6CFC5362F855B717695ACDB971AAF16320690606C1C42238856D757B5D610BD64427F04C97ABE1BC6B0185116CBBB2DCA28B5D7A9AEE205DBD37E92BB36311C8936D958AA1744CA67332A600D8C719377273C7FB0029F27C75817746E1058DD196DE71B0E4302682DA21B4EC1BECA3CBDF690509573959D816CF5FA034CE01D6A4AC477E3BFEA75732678AEA6C0A5401C623DC225C7A9A7AE6A572F738387181913CC71B9379A5A2BBDC45773C6A1167FE756E13731F47226BC678331312B99428B07B2122B2B9DC86B01C5F090FF632FA83B598863C0B42623549CA831F66BDBBBB1D4747D56A97DCEF9C81766A3D90043C1A99CE5E81105E9113043342A539DE446A7C5F9C4B46A8CADEC388FBB8BCA527D90A56C649200CB2A7F968611934014F9A7B6FAF3015BF6494EF72FBA0C7BA40C499357ACC96562C65B9CA7C53231045E35771947172118EAA02CD95F7137C93E2159D9389607C3011A76363560A97DF950B0329258B0126C7BC10E4081CE46B7C7B0AF0752B038386E9AFA2D0A7543D85AB909376B618C0A2D33875D264B76941430E81C48832F43270160176ED5938492A06CC08392237CAA8487ABD3C83019000BB6671784109C7BC4C2A0362A5B5122E620ABA511C49CA42D75091B3B1ABAAD9B8162BC27F182AE310872E789CF05F6C949598C41C3B73A1A9CC0808E68F95C8AD8392F021F77C79618685DB2FB1D04A9A8ACB8441CCC764AA3B191736F5A24AE31C23428390C1C22C6A6052664DB63B94960A433584036C05E031A07823A03CA153015FB2665C77D8FCC529F21AFDE0D4F32CBFA399F2973D812F516C86B0F353D6A29813D354471EB8B4C38DF93939EB3B1DB80DDD1CDD6558A9F2687A3E03FF73E02A217659F53D8C47556BF3D8C94040F630D63605E2D0F923579370C\nct = 087B75B8A26B2B4E3C850D95F4504A5CE2D9F2400F84645F51D95F572DAD4AAFD3C99F5A8ACD682F7655E23765502705A4AF1574AB38705D4EAC749C78EFE1532F45646BC3358DC2188DDB8A271E8CAA490F81078A9DC3602948F68D392A22E62D584881DEA33F273F1B400C41AD60ED97C67AF9594F44340A49FA8EC7FFE1857CA2785AF21B5346F275D5303BBA6F0D4A0D5A105428B444FDAF0990931E49228C18F90B81A9A8B1B85466986080D0F8D5ECF6256484CA2222F075A718371D15C4AE79FFC2480496C93E2D9909A61AEDC1D29F583CFEE4CEBE3EF54A0A2727E00D5D0525679AABBDD574856CADA9A7A112DF04F7395910D9BEDC5D8B3A373CBD2603012AC33D3523D55C0BB4AE0472BC04C5ED974F6954CB4A7C0D9672BAC55840DBAE2323258746DF9810F0A3CF4C4155C943EB2FED097E481199BA5BD6D853EC00336C751D5E0E853A271FF1F735E4C431B3B349A0874A49592D416554C65D18F7C489DF1F8C633DF432EDBFBE05769FB6FBD780D89451FAF60EB9230F1DE745FA3A68E200FE2DFBACC5C530E6DBACF9022872C84A84390ECA3763402518857C111151F68FA31954892C4F52CB2506B4EC11E466C43225C146530C39387D065A3481DBA695EC9F3EC7FA0859DED1AAF74961A03330F47F213F68F2053840D488B09D72466EF48E3CC7AC30415B574DA8F45C636E19AE109693579D9D66AEFC5CEFD59DC4BBD71DD16F8A2243B113D04B0366B00799A8B4167CDEB34D3CA6ADD02F91578A31B97A4ECF993A34D40E69DB8FB294DFB3EF35E3FBDA0575CED7B1DD09F3C05D645A1D67B73AD22AF881C658D5BC0FDF5E03CD57C77996F22F6E55115D962AB57068CB6A83A96ADF997742DAC616F40BBC391BCE131A18B41FA51D3373E1A70BCB8E40E333BD13BB27C8B60669C610FABF07B83E5A7B908B116233DDEAACBD9511ABF1BAB725C1C15BE87F16C7C82237D37B3916D6A91C55B668801EB4C37E5BCBCB27CD25DA2D218C6FCA8D0AE1EFDDF6C31C1EF2F1BCC6AF451122FB9BF9E7F75DBB5DA4CDB5F55DFA3E56C099C34F624C83939A38EB99D3B734E9EC0959AFA21DE5C2C4BAAC40571218F0CE0193CD912788CA2794F9F48B7C23800FD0F312795A58F723CF1B3DFA86A5D9A1EC9D036F29D6DB54C3DFFF3731E1A0827912C0580DBE616D12B2904212189ECDF5DCFE363A07DD51C0CAAD17CF60AE567C4A2663273D3A639483665AF1A0FD17AC29B9487CF883F1F6726F49918E161419399ABBA4C60FA27471C61B46392940E83B447B1D56D98A2B64B907DE903FBFB88F9EB02E89C46CA3F7B963873F607BC7FBF4B1561DB504DFCF2CD78E4C5F859F49793AAE1427CA2D2FA70FC0E7067F7E5AED5DA6372E95F54186F72971FDED9DE28F7405AC23463A4478B1CC9721EC7D2D07A302DE94AD42E990699D71C7A5290CF3B65E316E3AE2CA9CD349A0A7F7483970B0179352AB93D4A4B110279C9E5D4B0554D904FBA60A710FCCEB98423BA7FCF5F6C73165B8D29D74058FBC\nss = FFE9448FE824EC92022890969F1FA8E2FA87E5B3E95A9A155839177CD3C8E359\n\ncount = 75\nseed = 8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13\ngenerateEntropy = 6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110\nencapEntropyPreHash = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002\npk = 35A0C8EA287462D8CF8841CDC9016796500E61E89EFF672E87C667F453C8CCD148B94C9A9A3765649CCC6E1C05E5350218D091783B6C7E4958A0807E73E9839992C8C36A87891B7CE5D7122E38B5CDD745FEB1058FC2827B882DF77CB564323746855392247B054527EE862ABC91A557C431E55B81D23B1C1A94992EF540E07338FA944D24B17ED4E693EEB8224A0C5307202457C8033AA4651B2B30F85A9BD8070D1B11675FE240A1009DACFAB21D50036426A6DC9C3DFC05CD1612BA91DA51BD5A0F7EF9B235F1B3B2641747AB8A380B42C060357BF259548CB80788CB41DA4C7D3C4B9401925588920DF255167240F6B092C1329799F0039B74CBD549B2C053A71D4641071A3A95A460B2B3A8ADA727193267DE555E6CE87986AC06E647C4B7967CDBE5083C4B99A1B44B5DF58959C48BEABA0818608FD4046EA0C09A28416C6A97A1066C0650CA619D14A056252D38539F1C2676B69CC53502487389648FE596783BAAD0D7627CC6AB2DA5B6788410B67285841A323E04D037F25E103B38B07672248186C969B04661AC6B2753C5429EEDA389599B78E84608DEA89556A9510627B29E13B1713A1442158561DB8F435BBD6234A420618985DC4F71F0A5F15762FA16084F178E0E76BFC9EC5C35FB52E52301E6809CBB287D42B7591828AFE605CFCC93C337BAB78B55237B075A8BF08C48C15087E82600655234FA99F6987DA7904EF50A1599867D56760AE1D70006925ADE67157508289F137DEF9B9714F4CB72A017EE6A6325F9418F3A0EA3A8762C55987AB406DD9A6D248A33EAF264774AAFF6F00607F37BC20041D3A170E07407792A43C5407FB3622CCB065B74BC1A54F86AF9F7246D288FEE725A6FD85E82477483F778D5388728C4565467A9BA3216D92089BC1C742A20B03BB526B73573CDC91AA8E085F1ECCD1866280E791BD1E43D4843A440E050E2967DAAE26686CC2D32F512332CAC82095AB0005133023E75C9C92B0388BC8B2822A82F93FC3520972E2E0A062A388931092BFA8758F251895C641186D1B40F6A332DF3088BB24381DA133CE40D3461A7D87A93E702472E49AD91CC013C936B02A96C4CE14C2B23AC79869C6D139C8D85B58DA27C6EB4C4250BC3DDAA56DBBBBFFAF452C09074E013A3C7599CD5B8A876076523C6B0AEFC6A503BCEE0FA76407B779DB92453F7AAA4E58401CBC6F3718A3352013E1383B4222572118878C99289B91B02D929DBA06C6DEB6F4C2B0459F86D04FC8D287B6A676B17E45997027568BF7BCCA05C3D394C1557873711174242CA50CFA30BB3D715D1400807CC5FF1049CE720BE3C360FEBCCB61DD7244F4352B655A517485AB13B413983CC089749AC7144312966B2C67AD50096BC176142858881F09E3A075F8FA6BF638A13AF572BA026A172B23317A01A999C8C1EF478422CBFA9802F98F2856BD6A11F8584C532807771C19C411A2900C5A57C9B8E44B4C07B3BE3477BAA738AB2C407653A309D7A82CFC6B86A1B59AD1251E008598E453E04E3306C1877DC703869DA25A9B91FEC80AAF4F30B4D0A83E2DAAAC73990F05A9002D6ADA0409450454291E37112A9AD97147CC89999DC89A30C809757933C5D0356F329BFA3823D34197B7D9E60E307BBABD9B3E8272A0EF1B3333269A7AF6A5BB8740BFA\nsk = AF361347809757C2AE0C4A60393C90222C394CF136E95517552721FF136DCC234D64715A1AB43D15708187F89A6830791E0062CD43253EE486AC54179D320FA6A8BAC4D0C07B7158A1ECCFE52C4847403849982D73288877D04EAAD37D392AA487597F80F19AF7444E5A82CFBE51609AE515C1B320B6C75AEFC121D5E2904A0185654A418E5C7A379B41838ACE149B45C5A4040DD239ADA846102A6BBC811EBED4710B2393ECC4BB8C6254DC815D2667831F962887A74EB883A5A8642E0B427450D01321246A8797B7BE1211EAF64B0C706EEDFA17CBA2B010626112AB6B2B2B928DF38CCBD9B639B9C6AD090E92DA98B5C9914549BEB6A9B5505579A56943D210722BF590D63C1ED56534A96552005226C34CC1AC32572D2AC0823BCE348086096525188088DF229536BAC34A1C95083309A0971F31D975DE0598E4E009D24661B2A79DFAE85343B94FB1BC171493AD77D767E0814837348616205652EB4F98838CE536", + "691DE8C3AF0A4970EB0C3600B4605841BCB0884E08BCA3198B04B2AFA6F575229C56462B9516026D32D2CE33A4B1ADD3B411371EA6516765F457613CCB50F94AB9395F6FBC94395A6C9C104CE3B79171A83A49B22ADD3A915086B804C3B42301BC1F14630EE3217F059AEF485C019A4248B4A78A516D75919EB2B15BB1E5A34CB6B470CA7A797BA1B5193CB4565497F98BFE30A7578044867897C332687D925C8BAB05D0C35693F557F541B571D6AB7E4A752B80267B0329D7558FE4BBC54C8612AA95C03F81641A129B1793160DBA78C4E0269E9361087328A73C67C0044217A25C2E05B64A1B8EBEC972606BC220B1A456D8BA86A76AC4A3C06429CFB6035EA50549DB887A5F6170EA282BCC295A2EF000F571038FA97B6BD98FE0399ECE3755D4B55E16261F7FAB678C394C83676CB9F080BCC915C8B1C67DC998D7097074249585E31C5B30BD0250ABC570531DB43F546C2E05983A7B5219127809987343CF722FC38525B2ECAAD2CA703679CBB7500420F83960D7505BB7B7B59A8B6F0C876C7A53D893A10468A516FA7A6A08C04D3259AD003DB768559E173DF06A08793B10E5A1A46145B6F0FBB230CA504424B4E9617CB3F509993567B4CB94CB2CB39811BC1EAB31B5F5691FF4108E5A6EAA9B15DC2AA45FC4AD26B9CA007A7C2A680ACEFA88F12790ABEC7E3DA1C13A355C1C669117070A7E1976F6859921E273F53632B4144B58E0A74207100D2CADE0C8A0410814D40A4234843A44978D0D4A173BE52434760423235F5D7C8E1F56C8181487BBA930CC9272ACD524EB6C9D71D753FE62B0E9BA33A478B7E82B36D9690607550ACA261085A08725281B02E531432B35398B7ED1355B8172776926BFE41880DF90AF6951A58981C708724DEBA6B6C2BB8AF1C0009C71A0B82AC0D14CB0910A8EC3988251DC9E93F17E067608115C85BB6C47D33A2A9359A35BEB47C3A04AB65537F59BC1EBACBED4B97855F753A954929B6449A4DB7D2098CDFC04008873004BC535BD5C74DD49247419601513C4E8125731307BC858845896A67D33902AFA4B58B50BE969B947851BBD791D66887CC6E92E19A2B92BA6BCC2825C4239AB2894B2467547FF3A63BEF65E35A0C8EA287462D8CF8841CDC9016796500E61E89EFF672E87C667F453C8CCD148B94C9A9A3765649CCC6E1C05E5350218D091783B6C7E4958A0807E73E9839992C8C36A87891B7CE5D7122E38B5CDD745FEB1058FC2827B882DF77CB564323746855392247B054527EE862ABC91A557C431E55B81D23B1C1A94992EF540E07338FA944D24B17ED4E693EEB8224A0C5307202457C8033AA4651B2B30F85A9BD8070D1B11675FE240A1009DACFAB21D50036426A6DC9C3DFC05CD1612BA91DA51BD5A0F7EF9B235F1B3B2641747AB8A380B42C060357BF259548CB80788CB41DA4C7D3C4B9401925588920DF255167240F6B092C1329799F0039B74CBD549B2C053A71D4641071A3A95A460B2B3A8ADA727193267DE555E6CE87986AC06E647C4B7967CDBE5083C4B99A1B44B5DF58959C48BEABA0818608FD4046EA0C09A28416C6A97A1066C0650CA619D14A056252D38539F1C2676B69CC53502487389648FE596783BAAD0D7627CC6AB2DA5B6788410B67285841A323E04D037F25E103B38B07672248186C969B04661AC6B2753C5429EEDA389599B78E84608DEA89556A9510627B29E13B1713A1442158561DB8F435BBD6234A420618985DC4F71F0A5F15762FA16084F178E0E76BFC9EC5C35FB52E52301E6809CBB287D42B7591828AFE605CFCC93C337BAB78B55237B075A8BF08C48C15087E82600655234FA99F6987DA7904EF50A1599867D56760AE1D70006925ADE67157508289F137DEF9B9714F4CB72A017EE6A6325F9418F3A0EA3A8762C55987AB406DD9A6D248A33EAF264774AAFF6F00607F37BC20041D3A170E07407792A43C5407FB3622CCB065B74BC1A54F86AF9F7246D288FEE725A6FD85E82477483F778D5388728C4565467A9BA3216D92089BC1C742A20B03BB526B73573CDC91AA8E085F1ECCD1866280E791BD1E43D4843A440E050E2967DAAE26686CC2D32F512332CAC82095AB0005133023E75C9C92B0388BC8B2822A82F93FC3520972E2E0A062A388931092BFA8758F251895C641186D1B40F6A332DF3088BB24381DA133CE40D3461A7D87A93E702472E49AD91CC013C936B02A96C4CE14C2B23AC79869C6D139C8D85B58DA27C6EB4C4250BC3DDAA56DBBBBFFAF452C09074E013A3C7599CD5B8A876076523C6B0AEFC6A503BCEE0FA76407B779DB92453F7AAA4E58401CBC6F3718A3352013E1383B4222572118878C99289B91B02D929DBA06C6DEB6F4C2B0459F86D04FC8D287B6A676B17E45997027568BF7BCCA05C3D394C1557873711174242CA50CFA30BB3D715D1400807CC5FF1049CE720BE3C360FEBCCB61DD7244F4352B655A517485AB13B413983CC089749AC7144312966B2C67AD50096BC176142858881F09E3A075F8FA6BF638A13AF572BA026A172B23317A01A999C8C1EF478422CBFA9802F98F2856BD6A11F8584C532807771C19C411A2900C5A57C9B8E44B4C07B3BE3477BAA738AB2C407653A309D7A82CFC6B86A1B59AD1251E008598E453E04E3306C1877DC703869DA25A9B91FEC80AAF4F30B4D0A83E2DAAAC73990F05A9002D6ADA0409450454291E37112A9AD97147CC89999DC89A30C809757933C5D0356F329BFA3823D34197B7D9E60E307BBABD9B3E8272A0EF1B3333269A7AF6A5BB8740BFA12E89C47142418C26396EF0174C02F69DC00022D56494D31AF935490EDEE63859F684FB055ECE19459EB464E91E126A7A6E3ED11CCEE0046DA234D964C985110\nct = 1F2D0A172AF9DFCA569878612151E46E0784B0F2DF0F81A2DD709CB8ABF57585E9AE0E68B50D48B506C84A8710F42826A0CAA795495203ACCF99E76AC2A06B184C9C3F011367F9431A4EBFDD0F57CF8B3B5F0BE55FD0A1EC018E1A2D898D1F126980CEBCB135CBCD5A23E9468261C46592082D9712DEFA7913999386CFD2F69F7907D28BAD9E0C1DB983DBB9645BA4CFD15FBA1AEFD667CCBB497AC67B77C382DC498E5E4407B5E3805FD1680A723B6CD64FCA2A962ED8117BDAEB3ACEEFBB7B1D943B91AF4CE217842EBD7B67BE89774258C2639EF840CCFF2E1C0B0F1B03FD536366B99200B48F110E9ADB48A9AC3D77AB8BE563F5B89C50309180C4233416CA2B0606B7AEB390BE541A468B878E49C79AED0E5472539762C859E1B04CA23BE4D12ACE5C9511B9AC563272944577CDAF9495F95B55CF91BB2D4FBDCC513452C32F080B11FB49ED6866FDD443C3BA3581B9DBF550CEF4B4C18E7A8E2DB5E442DEA3C09AD5A3995E5D4691D13EC4710C1ACFC2CA3CFEABE621D54AA1E13DBF3FFFEC5189E2DFA14C382F21D17EDD9CFFDEDF5AA835301428110333A723EC6A8BCCECC0B93C62A763105F1E32F6F6F15B31DDCE5F6F95052A50CADB5143D195C47B317E7633D37BF11DDA9F0698299BCD25CF53DF532C2684EFD4B6166BF5F5EEA80CEDBA05B8703513767F158EF78D1E19DBFE7B6F38686E8538B6924A0EC78A5D9E4E2A12D4F3EA7CB55FC334486AE00F7A9289694FA7B59C64C2DFA003015C9785DEE363E7825CDD21815521E4438DF858EBA176E1849305D87E0D128CE5281EA24B6DBF821025DE118C52DDC6B60ECF5E527486FFA58DE8A1EE1C4F3314400A0C72687617A03E0FCD606D4B6A4A36B777FB333661DA0BCE06E96A497B5A2B915FCBA5FC8E652B486E5641BF62FBF01278D62C73884EC4BFF145674FB8220E69D7EC8ABDF220AA8F44C90EDE9B1EF5A026817E6BD389C365FDCE6DA3F268F3D4B1C98C9321098D76FAE308278FE8877F7E3A9EEEAEB57DB7B5D9CF671B969AB9998B048E4B37787ABBF9D6B384EE41756EFA4B2235C070A7017475BC808FEBD77A6EE3FFAD7A686BEBE6E84BB3B0C8537399EB39292FCC986D8FDDA05DC3E358E5CA02FDFEBDD84AADD7F78E77E2C8FDDC372E00AB5332683D6FD2BC00FE3758C616CA954CEEF955498699D653F3E35A22B5B8A385588EBCDA436A9DB907A5B069BD8CB0AA5852EE037C31D9C3C7A6AEB30624600D33625DE5DFC69CCB4DFAF0876F9A85536AEA7F67ADA95CE0C3426B9F3F2C51352D721B2EC3862A9B57B4CBB3495CF41883FFB772307166227759F745C9904AB2ACB946E5D38CE5346B9EC712E623F9D4F9DE43E5BA41159BA3D6C18F515CEB0775A38A2DF97A042A6673FAE30F1C957CB6B6E1A1E9C90992E03CDF0D2D79B9EF3D00639EA26BD33E8495958D8696FDFF69893B956E61024137C207FF6B46C2E00C1CE77BE0F3AF4DAA3743E420C2521640A159891CB26C539E1BBF35F6833D64E62FA1DB57904D88681F\nss = E3F110E7D74400CB476B0E34141A107D874986A3732ECC103D9BDFE76BD492F1\n\ncount = 76\nseed = 9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C\ngenerateEntropy = acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7\nencapEntropyPreHash = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e\npk = E4749BCD8577D50A102352B869402EFDE59F5FB54BBEE919E7D4A8BB8CC40FB8C7240401113152BA727CECFC8E4B817C5D537DF050902BD03DF866317006A2AEF59CAC269813A47FD337A0C5B694F4B080F100089255614634A2B0BB1ECBCC3F1D84CDFB3054FA749736E531C2E673716079CF45C89B444B7D821D892C7EC39A74D39B815C2B9981CA47F5E56840341FF9D23FC877285F9B90FC78BEA1B9C5C647AC52D066AD7B8CA2AA01E0729FA22C39D9C3C6CD833C6AAC061AAB1C1EE6819D2A245997B8580A9E1630112CC6B62C4952215A3281111675F25A10CA0C32BC68C7BC920BFBC7BCD82EDFE130B0434AFA29B2B9D90AC3F1143B5664E5E51984B52D976439794507D92CB256A1520078972B843FF3DBC6736602F68B289E0850EE845E49586C889CCDC104CBF13470F6F6C0E6766007E5C3A1348166933A45A1A62E0B749EE14A38E11A094BAE60A38C84079D81AA655782138671A0FA186A727457D351A8A45B6FE05369F7B158DE844E31117DDC47AF9FE52075C6ACD5F93A31C38EC7F608FF9096C8562E0271A35FA7265A56B24BF31C6A727376D1AB3F600573342E60884F41D355B2336E464B94554B7C108614C3394FBD561A2E74BA7045C0D74032877901E4F8A95C41CE9FC72013C51FA93B5C0B3C3B0A8C90CE0960F510A9F6A453B8B0012F7C2430350B8A4B6143AB5ADC7AAA6F3533E230C3062B7CAA33B1E9A3BFDA7BBFFEF8341AD0A33AB272BADA717A4790F4C99CF430BF114B62854810EAB7AF582A2EA327A599C490E25795CC5C42219771391B33DF4C7FC01524C4C520EB4559C2EA8C38AB5CFE27035C756248662C1E969EF478A2D2419ED9DA7125EC32B0557EDB5B77E0DAB221544E5F7A57A2941B89B803ED1C7D8DE65F64A29D8E7BC2020B723D391987F83DB0BC35E96AAE7B2772B37159A3257EAD277532119CF55959FBEC482169C5391A9409877C79255CBD1C8D2B8352CBA074BC4714DEB09F9CD81624D2782DE91EFBC30882C45631E96E35C9B53F77CC0D268722BA5EB858A1DE719A88", + "EC240DA229CD7766B9A237641C1277C006A6672BF61AB5DAB4C223B7381FD3C16704CF7920B2F11210C969B6B46A152B72598DE4AAC1665D72A45BF51370DE61559F83081DCB6AA49339E489968C80498550AFC467C8AAF0C6C1B9085699B801C75EACC3142BE38DE6F6A64AD6708C426EACC13B09D8BEA819BDC200258D31A8D1F308D0A7470DD35161379191576A03B81D70EC58565CA7C4A6BB333338D8113D70F5BEF45B6835917E17C2945A06CBB7F2225675252F351593B06A6DB504B6E67C6E88763FB06879187C5053029724B3477281CC5C5294B36B64F12A08084EEA098489D5CAD338A0CFA61231268BB866C2C524C71BD6A467C845AC7A4EAC579049734970859A2EA753C6B93EF01532B130A103C6244A17870B75023E0014E6D8433AE5CD2B145BFE253A8BBA300B6465FCE277E2FABE36D6C8112887CB0A6DAEA4A54E258CF89071E407594DE1BF1F4AA2BEB50263DC5D5FC729B632957375B5CE6373D9B93211A66A29736A6ED616EF8538E95C45BF595B2EB743D79436D6385BAB74C80D88C1A1F4022E6C3BB3D2294C474C2C554F3BE4D7FAE86455763B97EC8FDBE9640219B35FC36033966A3525D485F1\nsk = 31CB44A14C3FF840758055BF2AFABAD14A723C048D4D20C5908BB781844D574A96A0807C59D5192548A0089396A78B953AA52677B9A111CB012954B674571C5D0C7C5E6488D498290F7665F4F32DBA7228ADE2A724413798EC32619901215663B2C26360612558070BD06261BBAB86B4F96056A498BF37B1B84238C5099EC8F1AF4251C0862B861F334EEE85AF8D364A54F6BAD0E44A23A0577933CA8482889A955086EA3A2C94B057C1C20D540CD6D2976126854AC123CD386A855CAA385927318825494861079AC84606AC0F1810EB78A8398740BE69CFA1777C61A5CC1D758AE28C072D6087C379A567648558AC8A1883734C64361DB33CDD156FD371A2ABE534B162C6E336143B944DC2309AAC106525D6586793A2B3420358185FC787C2CEE3875E3425BE5627C1D49313413EE498B17E8C295908B718B3C4A6E03024D77F1EC37EAEB7462E09C683CB9B272431EF0ABBD0422AE2569FC37902AB90BD2C236F4DA66D78301A61765A77E43ACE81102C7355749C1463B55F10E26727086D73A1800924C6B0EAB6EC905D5B01ADC538C9EEC7A25989B85F24B1F68B9A22637613E9ACF609A67CB20B38BAB1A8D81CBD22A5EA8C7587A13BF8EB8A37E5949084C26B4433741A31C502A4C412535FC6A1C5000057C65103027F78F81DDFC4A8843C59F8563BEBDA15DA543BE2146A3EB7B521700958BB2A5064923236193D981BD1E2920D00B1CFC504E32495DBB116C5BB7AA21B6CEC5C9FC0B1AB73330544E7AF5BB1CEB7C159E3509938D0332CF51ADD245606617DCEC688F117BFEDC27DC5B8B4884446861B592B720B53FB23CF08513F66C3B51833E51B9A63E297054A8C03F8BAA257C64C2C8A265A8A92052C41146BDB3A32CE0B7196AA33564806DAC33AC05A20178C2A0CB04000D484F0325C9D16956DA0AF88F68BB72B7BC6B122A486CC1EB01BD3027AA316C6D7C1AE7D8B9A747443C5D7237989A93ED939D905832E76AFAE4172D5F70589E54F7B5CBABB536E5F316B3D38911513B400AD83F7B2A3C72A6C09EA3B4F68129ED285FB99442FE61237D61756A2AD78B7790EE69748B79E42EBBBD6B9B0D803A3EB77477609AB2CEA5920128356C369878855126C22F1AB66A3A4C202892C8863B609F7926175CF1E3967EA93B7ADE7A8E6779672023DD5D81BD4D9345AF36A38DB17E96B8D85B7C0BEB586AEFC9FD9EBC585F071C1B9C34FA2283A60884A0CC5EA210887AA677D24192DB582F05117FA189C868A3CFFE8B2FB584686EB3D009733E1D86C07D6A9893C7E9410B4CA99A4A880B48053878A45340D0056031068A63113BE4B51A630016875541E099935EA92B2668AE84C5A183CBBFED619691038973CC07B72ADB803CBE26986C827AC75428CF183CD5FE7C9C719378438058F470B62FA977DD658F219983F97B517BB1AED01A478A18DBB89AC1B916419A3B25F388C276C190B866356EC84C33B29022286C08A34D26948C59341A789CFA168ADC0C7A73DB36A72EC6C2C688C06AA3EB1FBB25B7B828CC3719C7B2473719F4E2B5C4AB8A4FC172A132439E0E3AF22A1BEAE17BA4CF39A155925C62A4C9CA76436496646906630B9349A335A4852C01B018F77DA15E4749BCD8577D50A102352B869402EFDE59F5FB54BBEE919E7D4A8BB8CC40FB8C7240401113152BA727CECFC8E4B817C5D537DF050902BD03DF866317006A2AEF59CAC269813A47FD337A0C5B694F4B080F100089255614634A2B0BB1ECBCC3F1D84CDFB3054FA749736E531C2E673716079CF45C89B444B7D821D892C7EC39A74D39B815C2B9981CA47F5E56840341FF9D23FC877285F9B90FC78BEA1B9C5C647AC52D066AD7B8CA2AA01E0729FA22C39D9C3C6CD833C6AAC061AAB1C1EE6819D2A245997B8580A9E1630112CC6B62C4952215A3281111675F25A10CA0C32BC68C7BC920BFBC7BCD82EDFE130B0434AFA29B2B9D90AC3F1143B5664E5E51984B52D976439794507D92CB256A1520078972B843FF3DBC6736602F68B289E0850EE845E49586C889CCDC104CBF13470F6F6C0E6766007E5C3A1348166933A45A1A62E0B749EE14A38E11A094BAE60A38C84079D81AA655782138671A0FA186A727457D351A8A45B6FE05369F7B158DE844E31117DDC47AF9FE52075C6ACD5F93A31C38EC7F608FF9096C8562E0271A35FA7265A56B24BF31C6A727376D1AB3F600573342E60884F41D355B2336E464B94554B7C108614C3394FBD561A2E74BA7045C0D74032877901E4F8A95C41CE9FC72013C51FA93B5C0B3C3B0A8C90CE0960F510A9F6A453B8B0012F7C2430350B8A4B6143AB5ADC7AAA6F3533E230C3062B7CAA33B1E9A3BFDA7BBFFEF8341AD0A33AB272BADA717A4790F4C99CF430BF114B62854810EAB7AF582A2EA327A599C490E25795CC5C42219771391B33DF4C7FC01524C4C520EB4559C2EA8C38AB5CFE27035C756248662C1E969EF478A2D2419ED9DA7125EC32B0557EDB5B77E0DAB221544E5F7A57A2941B89B803ED1C7D8DE65F64A29D8E7BC2020B723D391987F83DB0BC35E96AAE7B2772B37159A3257EAD277532119CF55959FBEC482169C5391A9409877C79255CBD1C8D2B8352CBA074BC4714DEB09F9CD81624D2782DE91EFBC30882C45631E96E35C9B53F77CC0D268722BA5EB858A1DE719A88EC240DA229CD7766B9A237641C1277C006A6672BF61AB5DAB4C223B7381FD3C16704CF7920B2F11210C969B6B46A152B72598DE4AAC1665D72A45BF51370DE61559F83081DCB6AA49339E489968C80498550AFC467C8AAF0C6C1B9085699B801C75EACC3142BE38DE6F6A64AD6708C426EACC13B09D8BEA819BDC200258D31A8D1F308D0A7470DD35161379191576A03B81D70EC58565CA7C4A6BB333338D8113D70F5BEF45B6835917E17C2945A06CBB7F2225675252F351593B06A6DB504B6E67C6E88763FB06879187C5053029724B3477281CC5C5294B36B64F12A08084EEA098489D5CAD338A0CFA61231268BB866C2C524C71BD6A467C845AC7A4EAC579049734970859A2EA753C6B93EF01532B130A103C6244A17870B75023E0014E6D8433AE5CD2B145BFE253A8BBA300B6465FCE277E2FABE36D6C8112887CB0A6DAEA4A54E258CF89071E407594DE1BF1F4AA2BEB50263DC5D5FC729B632957375B5CE6373D9B93211A66A29736A6ED616EF8538E95C45BF595B2EB743D79436D6385BAB74C80D88C1A1F4022E6C3BB3D2294C474C2C554F3BE4D7FAE86455763B97EC8FDBE9640219B35FC36033966A3525D485F12FAC52CA60594E514333EAD02CB1BFA5CD1D9ECDA4A0B25CCDFC47AD3F632A85F03A8ABB0A5010F400AE5722A75BDF5A2F6D5B546B34D73857CB1BFC7E587AA7\nct = 2C0B8450785EDE64FBF91E190C6B063F50B0AA80BD41C9AD969679FEFC58C69E1354C123AB70C1AF7E44AC63C8A8062E5BAD5313EA0565966301BB0556FB4B7C490463B6CD940AE2D9651A274323F799E25F1888853853C5EC2A4FD34F8AFF4159194E3FBA5FAD3C799CE439C84094C028EF6FC333FBDF19CB40BA8D1228B97CF602A0F7FDE3D15BF5382EDE4AF8A4C6BDC6732AD363735A28ADDCA063AB702F1BF656B474985D31DD68B51DD92E773D3359FF8A02BA792A06689C37EEB3815DCCA7FEB88BD5ECC79E5404ACA3621B3F81AB7BD55BBB293058F61BA5A93A7FEB9A90617EAC208DEF7C6737B353B4C3155B59726CB97A211E1DB42CF2F6805DEE40A68A966BE225A4D94542E9B972D3CF07F3D81EA54535E25AA7F56B8160ACDFA6097EE7FCC81A6F9FB05FB975BBD18315D68740FBACCCB17ACC9132B6622FF91EA8A2AB02CAE313D67A11DB654440A9B63A819A9A51AAA593FE1AA99D70A6ED17C99A25CE4A424DCA9EF9E6DF285818ECE4D4D596505FEC0DE68DB54F7EF7AEED7542908A8A47E07BC69DC4AD657C66FC97C2F3E79009C14A1E115E77D17948D9D599EB85D91F3B07EABE2BED6C549672A751FC75ED2FF131210A14C03987F09B61E24B144C4F7A64D8E0BE83642777A8CC9897379649DF060E5173F5C09BCD2C630DD7CDD51BF995A053DA7590DA319BAA2F8AA4904443AB1E9C5560F3F3624A744A20EFC8F2F7401DF81A228003CFA0F0196F6D57D0AAF7BF962994A60857EB5949BA5ECA8683324CEDAE9BDAA636B1EBE97F43C31A5AF9C51E78C6745231A3E5ED0C0B1E637FDA928F02A3C04B6BCE519EC653971F74E07544EBF78F0F71F58081EFB797F08EF9698A6665889DD1774C551B30158F4FFAF9B6C3E2E3A34213E4147A8437B118C12F5DE786D0EBCA5BB74AAAF88885EDBFCD96A3CE37864D522F7FFB5A1516E447EA2185451B408CB880721B09BC17F33A75C1B1DDD2A33D74D5F24E0F658E4DE0B049074992FF844F90B6E0D444F3612E7C53502643266FC97CD6D94899E5C131EC29F472C991BCC618C8E8786F83952FF53570D32A46FA9CE0A88CC4F4C2A84F185DE78F7CB1B428254886916000E4F030859556E2C5C172A7B73CE74999A58DB2C48CF23E55C43AF92557484DE624ACE9C4930B7A9E0BE561788D645BF8CB2EF2DA50CB04BF3889F39801686B8ED02D94B7C8A0DD936820791267AA3443AB4EB85CF794A80E96C2BBA992FCCFC655FB130569F9A2C47B54A0EA5EAA76C78A56729A516ACB6FC67067467518D79BA9CED47DF8E13113B12BBC467536994E1ECB8628D86AF891B30F4545EE20876340141B8043C0022031070691FDB2EE4F9A043F2AE05693E62434581900DE61A659769FB901460A495D90EEE56948FE26C517EAA0905CA92CBC47BF9CE4FABB881A6AF68EC1EA10AF30933BE24B791A0102F29733D9C1251B679F1CE2F08AEC8B19C75C010822A8439A704D51AEB55B63C958DB26CB0F839756FFFA5D1465E7F3F40661ED966229C193\nss = E26737292D1A1FC6772D9C14F9D74F0F4E830C0BA04253AEEA21E69830A3A360\n\ncount = 77\nseed = 542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A\ngenerateEntropy = 241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15", + "d\nencapEntropyPreHash = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b\npk = E26411E0CB6648D36C6236468793848AA4B7F4510377E0A24BDCCB712BC98CB21CEABC08101328D3D032CFE9C82D21372924C69AB5A402E9B3D88C87E9BC5C90335E5AC231A1B87EA3C2527B82445D7C8596B10A609616E4DA431C9593B91A1AA21A2E436A359A7A5901902A6B516D562363BF95890501AF4C5946626ACE3F276AF8966709CBB9B666B9842102F3077978E4872307AC65EA11002CBE4DD0BB83677419B89C9E0C9847FA6441C86B8B601663E40357831D1B3C21B4A8985ED50E546C2917F332D4ACB59BD64D9BE88EFB981362458B8D868DA7EC516EA9C807A29C5D51385781302072C1F3295DA2559003D4265CB330F43AC5B774562C182BE83636FA034BDBC3CB25AB6C8C21C69B873329321533A788287A40C1659F457C5E6E15456DA54A7FDB18C8BA246447606F2AA340A48B4FC667D7E67EFEC47910E05C3DA4463B75359668821711530835357B6A8EC62A3E7817C508C79754063F7110362BE73416A46533341CDE577C17A75B3316AC59575EB1A1575EC0104EE77F70941E91786AD457832E1493466A3FAAA55911E9BACEF8CE49F579F1753B5138797EF827F0BB0821EA69BD9C43ABF2181D0775FB64B8694C74F0323600FD3E5F1BC5CBDACDB2329928247E4759747C02CDD924CF1C93BAE5C37BE8C3B9C7E09B4660C3B9901EE33B62350A695D799B52743D5158C015CC609E891C87F9BA02616ED2D3A1C14AABEF101B4B42AD5C47916481BEF01B11B9496819AB76A428C0F5B8A69EBB24FB5B3407E1C22E2020341575C7098E63379406C9B60B6A1733C171682B1776719DB5ACBD2AC6AC4B97AA0A3C8C168A5AB389010A01B4DD01829EE4A402E54E633A229A94CF96E01F72EC4054C13335B89BD6E91E965BC324924C028B433074C9705AC4CA2682FB1B385F058D574515319397754CAC9F68CB70022882A24242D1C3F1242CABDAA4D68A91DDC8A22C939BDF1539645A912A33C1D11A5849211D831ABC2C86834BE35BC3500CC44522BF9ACA86988AAF580BF45A5FF7F8192E110E163356B8A52486F772204BBBBC19BEFC631433F081E8556579D288B3B27C1A8209ECFBAA30A82B34EB722FE2BE60534E2F625C0AE477826A9E75B7C5AED2398525358BF0AD127C15915133A32A9ADD47A72270A98F942807FC59F2420E14365A758C534F289160A65CFB34619C7C9B2992083CC699F554BD64586DCF379605581711D607235C944820CC28416AC761498D8B54193A8CAC8B815D7B19A21B02A6D5A737C4984F3A888C0B9E3F51B95ED9430327642A082787132E94D6C26B298B77554E7F2237AC286F419266580697FC9316EC1176C4D763B194C52D79B25604974C1BC899560B72094701709797C5183391A268853B9FF3AA277C707906BE0B078FD6619050E14B48BC73F877BEE69A3EBDABBB8B2198CF51B14B2CC9ABE673CAA803B419BE1C34B6341C2E83D2013152B557A87AC4FB55C5C86CCBBA995492CF960479B044B3D6233317677C78A453D4E247ECDAB3FB200C3D2A0564C4100A995C4F70597E498CF0897B507AB35E4587E2B875030303DC2CA8CEB41AE2A9725085C12040C8D0CB20ACE46F1936725BCABD60D0B880F7AABC887090195D95FB6EC060B5257AC37481FAA2ECCAEF99C0DA37285D53BAEB0E25BDB9\nsk = DE9A3F4DC6A54E98C850E3AF0F7ABC5CB5B363BC668F2C10C6E197927C89E57088C4960C46B767E27129FE78C7CAE38717E6A2A7FC16DBC1582AC697E8915C90281A0A784C4B75345A13161BC6A586166D4385B507748D3B9516B10550F05782125C10F3761AEA2C631AFA83870C003950B891D96AE721317B192F21A50F2B2CAF49F81177790C29C02216759B005692CCAB4281927A46739FF7A9583E9A5EB9A62314E4967F5BB375FB627E5A45B918C801B4B1DAC24D55C13AA7FC5CFC104647295650B5CADCAC2C74AAAC28B82233F64C1C01AB50F16213154D0312C5ADD25AF449CFDDF494045000A01C449D1084C876163C83C13321B1F6F87757DC186D4C30CE916240E538F196936AB9BB419093FD593409F3A308827AD9002E5A621FB1387AC06B442970CDA9C720AC9049CFF1C307806E9FF9209FD0CC52B9517C685C36C45801875DBCE490163C91C707755CC8701AF04DEB9AA0CE460F24C72E5D811C4ECC297ABCC4C9BA304C75812196409C19BE10C494A8B138A6F05FB5558E7F2CBF6F1694E7D417F73781205B941EAA3ECDF91C71E998F9A8B6B72400A048A77CE4AD17EB265313303CC86150D477E42A39CB4B8C5A3723D03550F4B76D5FB7B524EC2658D374A8C955B0FB3FE878072EBC0201B2328B737F9F19BCA8411F35980890D71E7BD9707C917545AA6A659C3C70877134BBB0A1E970E7035021168C4A493CE1C9950456A76CDC05FEF147FDD625D2B4BC51B39F3B9BC73A35A06A7485306457544B88C168B22E81CBE9BB0174A2B526B6BA0641456A3CC941569124557D3BC652DC8259AC66552DB0AE06CBAEDD091C268C2C6F4BC7E948329778CF48C3B37F9A3ED714C5C8E0099036514D9A052631B256FB7E7F7C91EA0311B8DB8721D5001AE90991111C5873499BBA20A9D08A135ABEAA544706DABF7338497C578084E1BDCE9155F87417B29313DD39505CC90C45C12C324B5D5AF01EB2656D58607724725485465E33A6A64DA220421C038F0A625254AD127AC941EB23362649D2049F8AE8C057321AEEAA31E0E98FE3DA74D53938F4F900B6A33F1305A383CC12B35894AD498293957950010CF7912174373967C294BB89A90331C828048E3FA862FADC95283025E2F66DCA10104BE8B9F286C198B8C9F0F24C79A454E8DC0742283CBBA84B95B388D8F6912F4B74198AA52AB561CE59508CA6CC09251FA2780EC0DA59D8B12B17179320D23B822A3395466DAC34384A364D06882592734F72AB0D2DD7131196AFD4DA54FC5801D85928CF61BB257274C98479EE0C2F65FB985F6C669D948FAC153158530849311F0BC51AE72BB8C23AB5FED55E793A4E8489B423044A1B017273A4BE35A305E19934B99B45DD2734AD4CB4C5B368C7A32650F306B7148C199A44BCC3A297429CCA6015E906204C827CFF8C9DCD48BF1B638091F732DFDC570CE6618DFC839B4A4648A52BB8302E32098C26E9A51A6571C9C290005265B6359F07598B10C7674F5356B0365CEACBB55B1A1822811C92C44F0E4BBDA4A13364749C5384CA7670ACCE69BC48B6A0B0B2BAE8AC5CC40ACA6CE24957167CC0F24DD0CAA3A0228C13934FBBB0C205F53D713AA441F5B0FEB01FE26411E0CB6648D36C6236468793848AA4B7F4510377E0A24BDCCB712BC98CB21CEABC08101328D3D032CFE9C82D21372924C69AB5A402E9B3D88C87E9BC5C90335E5AC231A1B87EA3C2527B82445D7C8596B10A609616E4DA431C9593B91A1AA21A2E436A359A7A5901902A6B516D562363BF95890501AF4C5946626ACE3F276AF8966709CBB9B666B9842102F3077978E4872307AC65EA11002CBE4DD0BB83677419B89C9E0C9847FA6441C86B8B601663E40357831D1B3C21B4A8985ED50E546C2917F332D4ACB59BD64D9BE88EFB981362458B8D868DA7EC516EA9C807A29C5D51385781302072C1F3295DA2559003D4265CB330F43AC5B774562C182BE83636FA034BDBC3CB25AB6C8C21C69B873329321533A788287A40C1659F457C5E6E15456DA54A7FDB18C8BA246447606F2AA340A48B4FC667D7E67EFEC47910E05C3DA4463B75359668821711530835357B6A8EC62A3E7817C508C79754063F7110362BE73416A46533341CDE577C17A75B3316AC59575EB1A1575EC0104EE77F70941E91786AD457832E1493466A3FAAA55911E9BACEF8CE49F579F1753B5138797EF827F0BB0821EA69BD9C43ABF2181D0775FB64B8694C74F0323600FD3E5F1BC5CBDACDB2329928247E4759747C02CDD924CF1C93BAE5C37BE8C3B9C7E09B4660C3B9901EE33B62350A695D799B52743D5158C015CC609E891C87F9BA02616ED2D3A1C14AABEF101B4B42AD5C47916481BEF01B11B9496819AB76A428C0F5B8A69EBB24FB5B3407E1C22E2020341575C7098E63379406C9B60B6A1733C171682B1776719DB5ACBD2AC6AC4B97AA0A3C8C168A5AB389010A01B4DD01829EE4A402E54E633A229A94CF96E01F72EC4054C13335B89BD6E91E965BC324924C028B433074C9705AC4CA2682FB1B385F058D574515319397754CAC9F68CB70022882A24242D1C3F1242CABDAA4D68A91DDC8A22C939BDF1539645A912A33C1D11A5849211D831ABC2C86834BE35BC3500CC44522BF9ACA86988AAF580BF45A5FF7F8192E110E163356B8A52486F772204BBBBC19BEFC631433F081E8556579D288B3B27C1A8209ECFBAA30A82B34EB722FE2BE60534E2F625C0AE477826A9E75B7C5AED2398525358BF0AD127C15915133A32A9ADD47A72270A98F942807FC59F2420E14365A758C534F289160A65CFB34619C7C9B2992083CC699F554BD64586DCF379605581711D607235C944820CC28416AC761498D8B54193A8CAC8B815D7B19A21B02A6D5A737C4984F3A888C0B9E3F51B95ED9430327642A082787132E94D6C26B298B77554E7F2237AC286F419266580697FC9316EC1176C4D763B194C52D79B25604974C1BC899560B72094701709797C5183391A268853B9FF3AA277C707906BE0B078FD6619050E14B48BC73F877BEE69A3EBDABBB8B2198CF51B14B2CC9ABE673CAA803B419BE1C34B6341C2E83D2013152B557A87AC4FB55C5C86CCBBA995492CF960479B044B3D6233317677C78A453D4E247ECDAB3FB200C3D2A0564C4100A995C4F70597E498CF0897B507AB35E4587E2B875030303DC2CA8CEB41AE2A9725085C12040C8D0CB20ACE46F1936725BCABD60D0B880F7AABC887090195D95FB6EC060B5257AC37481FAA2ECCAEF99C0DA37285D53BAEB0E25BDB93EB856043B822DF9D60B55FCCB537AFA3CACCA9EF50433BDE1DD9831E534D192A59B3BD23B49A95BC1FAD20070FEC930B6060BD827D742B077092E422268E15D\nct = A86CEF6CBEC42D8AEA488688BCD2F5A1DCF7716149399BEB3EB373810B7976F4D76A37CFBBEE50167F2F38B3E1CB60EE8C74CB60B7FA62E412A341794891A7FF3603E926FB870B876B94AA0F52909824A8EDF9699C5F5A3D309E29097F48B5354987DEA5BEAE36BF29DF79B0733622F1C67623A006D79A9909839CD70DF5A1C0BB1B18FA1602FC2D30C965DBB7433F972E73CB3DD31C6F9BE7C5F19C0E74C8F653CDC115725C7E77099F90B2FA2914FD713775FA619AC87F129CD9BD9A35393281BFBD18C56A0164C0C470C3AB1E4B4CE754E1466EE17DABB944A5953849E2DE8A5E69C4CC1B46D6704A03BA021EF55B240210148AB0380970440CC686D8F50E26DB02EA4281AA99BE5A35618576A1CE9CA39D7E4BE2F3D7ACEBB603F602030A995AF41F3441DD939AB30C19CA6D262438424EDF43375D28642F88AB6EC7BC75247E17399942EADE8F8A9DD2E9DE6ACA95256839EC4CBB280B6F7B86ED4016B95AE567BBB8AE138DC77763ED5BD71EFD669FEF71E37BB02EDFE11B3FCA0404C46B4B300476A020ED6BA561E231E731478D47154F35D5D9EE02D52D82482C490A32CED521C81B8BFBC18AEE4375B1C8A31C58ED19F7ED744D8C7EDC471082480CBA60E0B36CAF6B7B95404F", + "427CD47FC93D548E8B5FD014BB045288BDBC2C8AA4164554535F5A3B36F7871EE965965B741F57386D15AA545BFC0E405831166A9D8496FB49894D3F2B3E7635E6C7EA7BBE009489736D506C808DFDF20103A340AF5206B227C9D913522608BF5593C6D08F596DC0341925497765BB68D3C9C9D34B6AB026CDE93CEB535BDB577220F59B87B7272733E9106856CD2E9C6A225F94011CB54E65670855C910251649616D9782A34CD4DE063CFDE8E1C3144B910EC2F83EE3D5A1D0C7B282214F467B3534945723130CEF32B8D8F56C74FAB9DD7750B4858DE350FF1D3B2674BF78076F0282BA0CB74244A4D6887F188BB8DF9ED1663B53543E8A64CA604A4189F0FFF339B8AAD602D39C9877BD96513439C258455F9FF7BD0B05293E8637F8A56F3A96D5B47E122B1367AE7D8F8C65FA4EE444BB8ECAD8D96BA05D060BB03BAC1B63D1A257576E672D77286402B3832297949400E4E799BF2DC14DD2FE364B9EE06F528DB197A9DDD93B9DA9426F7D8DDEBB8F809C6ADF1602F4812C01B002A75728325E3A9A148E0C85CABD9415BAD35C9347E45AD4D01D5D1DA29A6A13CB0949B75BD07A942F26F2851946AE9DEFBAB4094293EB2FF4765F99068DE9328C8E0061C7A6C858EFD839D9725061E9A04DDCEFC0A2D614FAE5D0BBE0F8ADBE61B1AF37CE882ED75397FB228AE317FB91CA45C498AD05B5F9CE1E81D73E94F4ECDD0208F58A363366625E0408136637514A194F79501209C7FD5D798764AC5AD5A88FCDAA776B7D2D134A00759497B469E7B91ABEE9734961CF5A8EAFB4B8DCDE96BE81405A7C06C541FBD8881AA352FDB3B5AF4D00194274E86CA1D8E5E76A60A12E4DF51884E7F8F9EC171383177E7D7280D36623101A\nss = 1D8DB19740E2F6BA7C8C04216CF2398FE9221B2404ADDFEF8996A03EC72EAD37\n\ncount = 78\nseed = 6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0\ngenerateEntropy = b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969\nencapEntropyPreHash = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9\npk = FB262AA9A031E49084A6127B8410A5A46CBCABE6B18F607C97D4AF6C6A598A089BB40C1998D16CD307895035B15DF2C34BFC05F634813EEC780C96B83FAB557075CDE3B64EAE6BA98B65106E729B81D11C926404E99164BAC5B546997D2A842F6AA9CE1F6BB7AB7551A06A3649E1CAF7872AC675CB8981A124CA05A318BFF9A234853821A3036A86404B0F056491A5B20AE09DEDB123DF8B4E9EB612A00207C6CCBC580373B0921FE2831F50610340865232C60660655184D8A0867A47811B88BCDC4E6DEC5874839919188F63740588BA97405BB1FF2925C1553188C0137336948F7809DBB96D2F910A9C0AA95D49267E543057976E3DC7346CDC7560E68911B8829D37BD0EB20DD5E2B0EB1538A98A76A68798B5469F9DCA82A08648A2DA13BDC1A9B52A7B6F345626BB691AECCD14EC20F1C252B4FB2595474B2DEA0EDDA47B87CB51F020072D489A2E79CFCF9A12B52BB4F626C35BA4C0888C7939F38E6126484A7932F5D6A029E1CA5CEA27D729065D7137BB518C1885A299B58E1F6446FDD8449E58A21453CDE7AB683BEC6D84876CEE590D1AD93852885DB721B85D4061DCA1327179ACDBFC329416B23234572901B3F63A2CDA36AA65B17035F449AF2B404691957C30028F053989C501D8C2CF8A8CC0C04AA59F3B19A98777F814A18A0753A7180264E59F2BE7C9F0266B8DC481CAB4833BE8B3B599818AA930571748D41657256015F68A8C887C23205A6655F30C51084925167BB75C98B8A25B7579BDF40A912365164814794BDB0B78824FE9066CC63473496AB9CEA06248D883D1846FC8084D59F05277AA3EEC0C3186D68BDCEB6C240CD0128A6BC1361467B861AB025309C82183233C37B35E8AF1B464331CBE7CC3974A48A8E015A491677567472F263E31188966EB556151819CF52772053936ABB0D0A48E99357E558301DC8157A8A7853212828269786919A8F9032E17F9B692BA8EFAEBB602E83BD4B75160541500779D1907B1159170DEA870E6F57F5229222E85B178DAB32F897BF45510EAD084887566942656357B7896570756AB1614994F982841A525C8EC63CCC8E4575DF03BE2F5CF96505ADE252FA4E80FCFF664F6FA8C337980251904A9135ABCC509DB15A49FE4C6D57B41BB6383B3483CA5F5CE11641F9EAA423C0C3254A508D4319DFE72168070CC8C771ED3E06CE74C93240947A8DAB87D889F9AD894F37243B25259153324E103B73C708371400EBF007BB5459EE084BE938A18D055AF7CC7AA98FBB88A156849765936E7273BC385A1BCA94A74368168CF26D8806C7901EEE2359C8694B5439F1E82C0A6892E4A68C4858A9A00B1496E177D1EFB57EB9C0AE382B56626595673230903CC19C79714364CC4B10891823535E21CBCD45C90D471E684AF1FE243E925C848565A1989637F7614C900AF1BEA9049B78E07F00950AC800EF72860E209C192A4AA0B901090987BF15A2DB6165516AD0238A40B0BB233A365BBF2BAB2F60EEB8A54771A8D8E5279E2740298563AA2868E2DF1BE582897C7A9A0547ACC2D8933ABA9CBD5D937073455489A30E8CC3659C03D37240BFF084D77F09DEE76B60952221ED2C1AA73B772CBCEA4D7A1FD64561E88BB90327B7C13C809696C0E4711CE152577517BE0A2FB3D597FA5804E0C106A4C10\nsk = C65B5692B9737BD5BCEF94376A685FE08CB59C2B94884B47BB6A4B292C4EF8DBCFD1D9392BA3C464442CBE0879FAC60CB733496FFA7116011CADA07377EAC759172DB45C9035532A5A48C18F3343E7FB3A0A7A1DA9C75F647648A822BB8FCC59A2E0476FE958CDF968433B46EA296056A8460EDC0B7D4430252B227CC38C8DFA639A72759DE9325D3BBBDB1A5305E546580127B11332BB666236924FF1F13105176B81A777EBC946BD4B962E8050C0F80BE026A513F7C9C74308F8336A9BC73BCABC8353AA10AFB69AA502B3B6E9A53AC67F8CD8784BE4519AB3C6E8E47212BB59EC3958BE442BF2162DDA987C602030770555C0BC62B1422367B95A91399642155CD0B17DBB848B642C765FDA2400358040D4CD154A68DB36265BB525FC90988FD0C04BF0B66CE052BB216D6183B444CC385BB8AE17388D5E8024AA41563653B5F72899CC16B37D642F6FF7385F557C941571A1C73BD9425FEF3C343ED9B88BD02A9BE5652736AE69949E43B5C9719C4B8E42C9071C10E3D454B3C90D315C93579CB106A3B16BAB7163983F5C514B818516BBA802B7FB1166679EE03C4C41EBCFFC6322DB61A7988927DD83B48C24BFE82A4FB1901F70E2C39C411FA65C43D56C02C79849E7745BEE15B70E405939B055C2A76FE1021E094B4671A290F5D708EBF0B1155B94FEE9B34CD9858D3A8DD4BC27F5FC0627F2A80D6681C11324ECB74639540B72A23083C3758CB29AD40C979B42679E1436FC56B3A7D1115137015E2A2AF9A8BEF038B6905C8847C16558BA2BC6EA92AD90B026228695D664720C15E6708B0934064760A745EA4A5587BA211312C7203005F838A2D5B7BB09B8DC7AA39D4956D494472F71A268991CA907AACF8048FC98C095798D0EA043C42C437F6762ED3678B6D701560016F405CAD66117C786B56B3A88FB5968C26869F73A2227B129553B220F67CAE75B5433B29259553AB4375A0AA6766B2AA0AD480B6969201ED21CCDA0A39F8B8F565112565065D8D26DBC1A57425A29FE0A606BA826FFE45A69493B08B11712E88A2B4B0371DB5C0EC0125E2659ED08275D18277B9C0CA51797D46CAFE91951737868483A418427733EE2637B4AA9496C30FECAB67B0B7278A76DA2DA201874711E6928B7A40E7859378C867B9BA81529656200584EA9A5881B657B68980EF8CB201338AC1B856C4EC5B0C48A80BCD6676C0CA624F05296E59155D5587C2C20BFA1BEF1005BBE9840DB205D9658935A67614595BB3FE48E52877FC5BA639D023F54D534C58CB90A0A98BD1C2E9E940FDC61193D4753D17463D7EB8C9C6575E0F6845B5C0A5BC69C5F90128D3078960671394B75C5C72EAFFC1E8EF4AFDB395FFD40A2F6BC75FB9B79E1D8756705B710B0BAC1DBB4AC312FFF30745590739C08BB25CC9EC62CAF1226176C161ECE62AEDEC392A3591EC2AC80E92571C1417BE7D82B2F9A1990D50DAB78C1DEE631304AB5AC57274846A8FDC6547B224C72E0781B233FF8A6C876ECA3A3E060A00B560F661042E85340C4A8257660C0592A429C7B81B5137D410B5492864E156DAD292DABF59035FB0E02247E6C6847CFD86B6958C74209A8F389041E5389EBF5B9B633B7FCC08CFE14BAFB262AA9A031E49084A6127B8410A5A46CBCABE6B18F607C97D4AF6C6A598A089BB40C1998D16CD307895035B15DF2C34BFC05F634813EEC780C96B83FAB557075CDE3B64EAE6BA98B65106E729B81D11C926404E99164BAC5B546997D2A842F6AA9CE1F6BB7AB7551A06A3649E1CAF7872AC675CB8981A124CA05A318BFF9A234853821A3036A86404B0F056491A5B20AE09DEDB123DF8B4E9EB612A00207C6CCBC580373B0921FE2831F50610340865232C60660655184D8A0867A47811B88BCDC4E6DEC5874839919188F63740588BA97405BB1FF2925C1553188C0137336948F7809DBB96D2F910A9C0AA95D49267E543057976E3DC7346CDC7560E68911B8829D37BD0EB20DD5E2B0EB1538A98A76A68798B5469F9DCA82A08648A2DA13BDC1A9B52A7B6F345626BB691AECCD14EC20F1C252B4FB2595474B2DEA0EDDA47B87CB51F020072D489A2E79CFCF9A12B52BB4F626C35BA4C0888C7939F38E6126484A7932F5D6A029E1CA5CEA27D729065D7137BB518C1885A299B58E1F6446FDD8449E58A21453CDE7AB683BEC6D84876CEE590D1AD93852885DB721B85D4061DCA1327179ACDBFC329416B23234572901B3F63A2CDA36AA65B17035F449AF2B404691957C30028F053989C501D8C2CF8A8CC0C04AA59F3B19A98777F814A18A0753A7180264E59F2BE7C9F0266B8DC481CAB4833BE8B3B599818AA930571748D41657256015F68A8C887C23205A6655F30C51084925167BB75C98B8A25B7579BDF40A912365164814794BDB0B78824FE9066CC63473496AB9CEA06248D883D1846FC8084D59F05277AA3EEC0C3186D68BDCEB6C240CD0128A6BC1361467B861AB025309C82183233C37B35E8AF1B464331CBE7CC3974A48A8E015A491677567472F263E31188966EB556151819CF52772053936ABB0D0A48E99357E558301DC8157A8A7853212828269786919A8F9032E17F9B692BA8EFAEBB602E83BD4B75160541500779D1907B1159170DEA870E6F57F5229222E85B178DAB32F897BF45510EAD084887566942656357B7896570756AB1614994F982841A525C8EC63CCC8E4575DF03BE2F5CF96505ADE252FA4E80FCFF664F6FA8C337980251904A9135ABCC509DB15A49FE4C6D57B41BB6383B3483CA5F5CE11641F9EAA423C0C3254A508D4319DFE72168070CC8C771ED3E06CE74C93240947A8DAB87D889F9AD894F37243B25259153324E103B73C708371400EBF007BB5459EE084BE938A18D055AF7CC7AA98FBB88A156849765936E7273BC385", + "A1BCA94A74368168CF26D8806C7901EEE2359C8694B5439F1E82C0A6892E4A68C4858A9A00B1496E177D1EFB57EB9C0AE382B56626595673230903CC19C79714364CC4B10891823535E21CBCD45C90D471E684AF1FE243E925C848565A1989637F7614C900AF1BEA9049B78E07F00950AC800EF72860E209C192A4AA0B901090987BF15A2DB6165516AD0238A40B0BB233A365BBF2BAB2F60EEB8A54771A8D8E5279E2740298563AA2868E2DF1BE582897C7A9A0547ACC2D8933ABA9CBD5D937073455489A30E8CC3659C03D37240BFF084D77F09DEE76B60952221ED2C1AA73B772CBCEA4D7A1FD64561E88BB90327B7C13C809696C0E4711CE152577517BE0A2FB3D597FA5804E0C106A4C10306AED2A804A1C9BAD4AB9E59F6126AD7C8633CDD0C2DD9D4C6F639D312ED47BE99C0E7B82BE89BC3C1EAEE6680AA4EFD394E40C2B3F30523C8117F7C26A8969\nct = 23664DABDDC72005181DEDD4683615FEBB4936288AA5E632624426F07B51A793B5E7A469F91895314F08278C98C5D6B8A184830209A05F7D9C38BCF5F84CD7DA273D7C64615C78FCA0FE08910A506CBF7DFB28B4F9AA5C0CD4CDA71C9CACA34BF27B15CA2E603FF4CDDB14A639277C1DCAC2242B534737922863E1551307071394ACBC98AF20BEDC07163FA84B6C63B08A1380A3D4157FD2006306C95A0D488A83D9B22C3E1B492A97F4921D5099509FEA1D08AE5EB44117B1C7E9417B9A3E6FAC0D519B56380A8B5C5207F454779FD839426E0988BA8936FF50545BCF0E9DDAA818AC0EF08BD2D5A3FAB95BD157C13EF512267278C2F94512A8D5642AC6323F668F1002230DF845D6D5CB5EB02FB4C31B8EE5A820C30A53B74A87E0AB2AF7C51E0546CF5E41CC72B634ACBC96ACE5257B1C221019B4FD70CD0D958E5200927BA66B154613191A0E139CBAE734F2F78F7878373E4C4178E2E3C3E2A7A11E06BDC24D151B475611FB1DF5F39FB5D0FAD043211E16066210EBCE0F31503BF8E62431C863ACF928DA8EEF07FFB5F60E01A6DCAE1C558BC282B3090759F7239A20EC0F5A37CB48B351432CCB3344E25EDD5965422F559C6493FB8C5DFC297DF280536C37CCB41D2625F455BEFC77B71E7D84DC06DC50D32025609D0928EC8BD6B1F78F1784A72FDDB987B5999D1F289D29740ECD423193B9651BE956750D31406FC31A8BE3465F8C06B5742F66F4609E120AF2EA64F6C99895BAB22EF2F19D9F3CB6D7BC27B5550F34F6EBB51B02AFFBE626F051FDCA7C47C57123EEB2EE8865A91AAEE9BEA87F5B5BA63B86696863A9CC67F765C4C0E8DD90D59942710288F0F8C446533EB4E74D22B5F89CF1C714C139E487FB0DDFAE6D900E3B6FB7E568AB7116BB92E04754415C74BEFF6BB6C5D814FFB7A198C5771845BE3B0E2F2D397BE8083E1CB0F87A965D78768E3EDDBE3F234124CD92EF5C55F28A76357413EB2C4E26E7FEB772770733AF930B5C7251B2F0FAA388EFB08D45900738A7D1FEDAE2217914CB18FC3B0C1AEEA2B2C93C72F1811F7BFFB281EBD38020D006E286E0132C5C4875F8657C3E5B141294A69AA98AC26748DAFC3172222314F9B5B9EF0DA13BA75B7B2D8EAF62D50D7442258F6EE56E399964514290CA006095E125AB63E178DCDDE424F03BF59EAA68393FB7D6C36E1091FFE079BFC9BE2FF099722E1BD33F9FA47DC0766C76EA6FDD660DC2D6FAA41CE8B268136C6B050D449A47FA4051817831AA555CCDBDAB8853B377CAFCCCE731849F64539BDCE72785ED15C0AC3E4ED94AE3D4630D7E6AD08AB5B48C018CBD943FC968AD687C5F4117BCE83A663D622A6FFE5A47D44A409EE9D47D32BA9EF5A6453FBCD81CD92C27F9C033E32E83E1A2E7B32F4ED094A79A387F90A6F7F45AAFBEDA7FF11B35BD732BC8F3B75CD84682929D20419BA2FD2640DB63867532639DD4D1CC1042AAAE6821011446EA8E7D2B0BED9B7AAA6C17BED3955DDC566685D7E124A9A01D460DFAEFF51A32405D74ED\nss = CB0026C186440C0744C1C1C708D8FBF2B7AA1126792A7363576BCB2E64384117\n\ncount = 79\nseed = 7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851\ngenerateEntropy = 28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5\nencapEntropyPreHash = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91\npk = 5226AA8EDABD5A4A5A7CF6633A394B756AB38BC652EBC1BDB728C74EC316D039AC982B118F1AAEFEC04E48448D45F72B319289691A93A20283C3CB1FEC992364CA83226332107704D3390F71E1883B46BC2F31B4242744E0847E72D5645586AD0B8C0FE48AC04A003045AC2D2101B52C7C1D494673BEA69766A5ADCB38CE3A978209471B5D7095A720A4C1971D94970884F11FA90C5C8B7009E2E1769B382004C93A2D9187B23929D941468444CDDE233DB3791656C860705B714E3AAF076921458B8DDDD61E09AC461E96A1B1E9AF19AC6984129B6C8CA9D4E39D70277B5D9A6A4B605F5E0454AC05729C2691E87A8D79353289678490A822C41C52A2F56B91A35F89918AEE8935EF2BBC48485BD747CC5C59066B7577739B669AD21A5561018F021663F5CF48E08F39881D221552C846AD789810030326C8530DBB369681C69CC00C2390FA857A37AD81623EED4262DB69929353118A0886E6C1CA3D36C65898968EB7C187B7B866F18A8BB369AEC780E0033EBF1B0DF846CD60633A461C569683598C7744FBECC54282725E337CEC503D12A87F9CF5BA6587BAF31B852BD45A871ABB81E88C8B8A56D324C87A777BEAF543BA153A222418BBC57D7E1325FC2A075608988BDC44E276AF10CA2D7E52B045514080597A0FF73732789D0F955F93BA77E8034900251416B43E291984CAD36C53C947CC954A8320C11424BE43283A6DC586A9FB39B2927867B79772DC1CAA16234233ADB5AC819F1A172DA5194EDB997F924A827A85FC7C7A8281C98F7A9CEE443F68A2AEA6001DE7C7475B46B55EE8991DCCC6527B5FA1393C9107C4D35A073CE29A7EA205A9279B62F5CE21F3AAB0838B42E6679000CC4C182504A2A4E81757B7F6A183428786F09C76C69E2D7598F1E5049CB57738DAAB6972ABF6D8BFD2AC7137493BD2B8B5F997519B2026EF38623294B91999A5419356BFE03E338194E471926FE5842E79740F416ADAE2A24F441BA4A0C08ACC175F347EE3B614664496A5E51C01A55B1D2A3E8486CEC4C3BA461970868502A0F9553D776514857BB8A872C7F736CCB432B1392E99568B51B9C9A56C441AC0CCBE785693722F90D63A0F78C8EE777236EA43DE2583D0E093EC8BCAB7C8C6DDD8254258B7A5732939D953E491A6BF310449083986B2A0F236C5B9A300DB22299146B9A0943115845F3FE98045CA844BCB1132E0BC98CB54746937B1479DADAC5A4F9320DC572BA81CB250F13869D132FA259604A76A5DD56A7543B96C3096D3046389A917DCE53CBDD9AB04A65B31C6C5CFA23A2AD53FAEA3BFF3985FDFF9CA3E3965989C072F4659EE8914DDDA0ACF30A64A1A823B78561D5A9304950EA3056F50B82915C71AE0B6883EF319D061464D8050F37C24C62C7693F204DD4B4D74B66DD7526FDBD707A3490769764ADBEA61C09A2D7F464D7E932705212D6A9151B46C2ED93A7B99C1148F679D622419A4574310AC20941B3E51591CA5D53CFF51A6ED2C081EE7B4BC23C8BA8B1AA2924406618715731B1CC404929A38911020FAC6647C24306E349F1ECB4E2F530E8F200EB9C0A315606A3E130498F96AD5865EBB4CBB55265E69316A3BC96E51745B02F4A593B796B5951F48DDD5D61BCB3F79106FB3F881087B21E528BDC627A8A1FDBB3B1FF5D83954F7\nsk = 52D431D74363BA07B7EC47C2A5B98157F616B8C7B7D3E68CE3F2A31365BF4E21747203C5EDD758000A8C09D38A83457FB7B015BDB187E842B46CB9BFAB29A917435431184219339DF7CB81018A81B283814FF8B15E3A526AC35185BB45C7A865C45AB0CA1C7C5CAC9E35F753D378556A62C8AAC92F0FF59651C1ABB789970A32C69D153B14A687FC2A56B9E0C382BA4F907A0BEF79BDDFF781776ABD042044A1C84C4C80AB9CE9A76BFA6374E9CEE06081E3661A09CC3272331936CC85D6B2319CC7873227303191C36842B61013C0A41082B82034A2E1BFC8C47916859EDA53033D5427741510E842265AE36D530A19E5D7365127BCAB5B506321ABE2B69DE823B660B4699F8859DE76899098159C211CFFE51C7198CF1025BF9EE69236C913B16AAD84AA4C381A577B6C7A3403627B323F11EBC1F304747F47407DB9A8C9E4B866082597F28B6EC272AD2140A43A52188B061650BFFAE19761BA99CA724B71191B6DC5B16450CAC50B247415370D5B207701AAEC3A13CB477983F180388050175658CCB4714ACB603B6B3AEC340DC6C164FCB81331EC194C382FED024E0D962B056627A5B05A00B5511D78BADAA489F8BB3F3C5B484F9C1450708B89828EF24B815EB43A6B8B127BFA49ACACAFC46434987BCAF5F91A926140BD56504FB4525EE1921B63733DB2986DC133078CAA44518871BA12894A553BD024FB731A0AC44AB80199394A2385BC440515877CB69B73B0C847E40ADF238847608908C20BF7E1B86FA84781371D4CB52FCF2CC30306C8D98C679D4CB41EAA0EA8B395C08CAC6DF2348474A9504592ECD34A93B3262C9751E42193719B617355C59A25679D909A5E756C8DB03E3B174E1A063EDC733B9350B4F738618648BAEAEC5B76376D05329BE6E706E632BD61292755F361096CC4565573562053B4402C42C85B5299B1CCA0B9CFEC4605D63665F24561D8C1DCFA896D1C6D8918A3E6F2A8D4224FF97503D1EBCC8D5395F0A64D1454623890BB7AC6B87B29333096535118CD243C52E49CBC0945385E38781B9BCB6B220A66D96D426B9A1F4C4C4D0349CE2BC790732247EC5D98E43BCD37CD94B652BFCA7B988B063BB102EA0772DF0AAEC74C228261B4FA7A49F3B329F2C7C6D04C859C9816D5BA2AABB85E52DCAE066B9AF4D9951766041CC783DC672DDE42558F50473BB43BC1F93BC6EA7D33F46AC4999CD33698EEA603C7DA265AD713E48691C8B048B21134C9998DA19060CFB6AE31CB5A3B7387F2257FE94BB3EA4C963D01849FB021741395F1862085F031B6B05A7834551A6C8F0EF91397A29E12DB6D776B05C7F12C8B260CF128C02E48A9F403A487AC3A6C0888C5299414AAB1D7283252F62F465867A851BE9A82C9A79A25CFA727C632727C765D4C496D466942147A8A7B65AEC4BA84E4E2745671BCB207654B087A26F93AC77C82CF34A7C2F86FE8F48FF9A0B663D79BBA6B2B8908B32FC145E4F65C6A8A379A99C9E68A10C278130A1969E0CB708D0CA6FF1669D8756D1D530ADE051ABA3A07903B5D801456315057187758351588BED222785C9FE83A0FB4C59245CC2A72B309767348EEDB7C2097B457BBAC8AA96A67D785803744E149B3F131A85226AA8EDABD5A4A5A7CF6633A394B756AB38BC652EBC1BDB728C74EC316D039AC982B118F1AAEFEC04E48448D45F72B319289691A93A20283C3CB1FEC992364CA83226332107704D3390F71E1883B46BC2F31B4242744E0847E72D5645586AD0B8C0FE48AC04A003045AC2D2101B52C7C1D494673BEA697", + "66A5ADCB38CE3A978209471B5D7095A720A4C1971D94970884F11FA90C5C8B7009E2E1769B382004C93A2D9187B23929D941468444CDDE233DB3791656C860705B714E3AAF076921458B8DDDD61E09AC461E96A1B1E9AF19AC6984129B6C8CA9D4E39D70277B5D9A6A4B605F5E0454AC05729C2691E87A8D79353289678490A822C41C52A2F56B91A35F89918AEE8935EF2BBC48485BD747CC5C59066B7577739B669AD21A5561018F021663F5CF48E08F39881D221552C846AD789810030326C8530DBB369681C69CC00C2390FA857A37AD81623EED4262DB69929353118A0886E6C1CA3D36C65898968EB7C187B7B866F18A8BB369AEC780E0033EBF1B0DF846CD60633A461C569683598C7744FBECC54282725E337CEC503D12A87F9CF5BA6587BAF31B852BD45A871ABB81E88C8B8A56D324C87A777BEAF543BA153A222418BBC57D7E1325FC2A075608988BDC44E276AF10CA2D7E52B045514080597A0FF73732789D0F955F93BA77E8034900251416B43E291984CAD36C53C947CC954A8320C11424BE43283A6DC586A9FB39B2927867B79772DC1CAA16234233ADB5AC819F1A172DA5194EDB997F924A827A85FC7C7A8281C98F7A9CEE443F68A2AEA6001DE7C7475B46B55EE8991DCCC6527B5FA1393C9107C4D35A073CE29A7EA205A9279B62F5CE21F3AAB0838B42E6679000CC4C182504A2A4E81757B7F6A183428786F09C76C69E2D7598F1E5049CB57738DAAB6972ABF6D8BFD2AC7137493BD2B8B5F997519B2026EF38623294B91999A5419356BFE03E338194E471926FE5842E79740F416ADAE2A24F441BA4A0C08ACC175F347EE3B614664496A5E51C01A55B1D2A3E8486CEC4C3BA461970868502A0F9553D776514857BB8A872C7F736CCB432B1392E99568B51B9C9A56C441AC0CCBE785693722F90D63A0F78C8EE777236EA43DE2583D0E093EC8BCAB7C8C6DDD8254258B7A5732939D953E491A6BF310449083986B2A0F236C5B9A300DB22299146B9A0943115845F3FE98045CA844BCB1132E0BC98CB54746937B1479DADAC5A4F9320DC572BA81CB250F13869D132FA259604A76A5DD56A7543B96C3096D3046389A917DCE53CBDD9AB04A65B31C6C5CFA23A2AD53FAEA3BFF3985FDFF9CA3E3965989C072F4659EE8914DDDA0ACF30A64A1A823B78561D5A9304950EA3056F50B82915C71AE0B6883EF319D061464D8050F37C24C62C7693F204DD4B4D74B66DD7526FDBD707A3490769764ADBEA61C09A2D7F464D7E932705212D6A9151B46C2ED93A7B99C1148F679D622419A4574310AC20941B3E51591CA5D53CFF51A6ED2C081EE7B4BC23C8BA8B1AA2924406618715731B1CC404929A38911020FAC6647C24306E349F1ECB4E2F530E8F200EB9C0A315606A3E130498F96AD5865EBB4CBB55265E69316A3BC96E51745B02F4A593B796B5951F48DDD5D61BCB3F79106FB3F881087B21E528BDC627A8A1FDBB3B1FF5D83954F79BB3963CC1C5CF2B2D1C6CA76226328AB765A79999CCC71FE98D5BF3B34F51B19C35D165453E5FCDC6F9DF64526D9DE698F2BD3E6BAC6C7FDD86601B9BA5F4A5\nct = A7D918C3251367B43A2CAF232D30CC44BC8313689F61C174CD6055E0939DAFAB9EE9C4CC5C451F6836D2D9FE0B6F1B737BA4B6020737487095AECC3C972201925C7A3E4C6BADDDA7441B89B2A35F8D2E4878D316E5B92E5B6F28EAB2E2D1A98843853324D35A023741F11C426442FB3A8D50A0F9BF5209059AC1E47BBFA11724F49488111C551F11DE6BA8C28E576758F2C30B219AE6BC3C79D73E5DA64F03E0ACEF5BBAEDB7DB863B7E8255F76E5C7FF26E42DF8F82A5435F5BBF861283710FA7DE3AFAE930013F1B6B7DDAA122121C83E0DF00F231020324312B077CA26E4E9C2BD815F93824CA59FA9F4E3AAD70E4D55A853187A4E3CA642710EA0109C00750820AAAFD98BE4A25BB7E1D18164F9A4D439F3FF7169696A108F7274E2D50F269F93967DC2371BE9AAC3716DBC499C9CF6639D02EE86438E2DA002CFF11D70C5F025E4A9A446D0FA9314C1E6B445AEC37771E579182D494FB5C448354B1ABE91FEBF5512C11CA7D2DBD0DCFDC37C91F67613C64B76836A5D91F57FC3678B12707D8451277F776EFF18EF083A00FD39332DDED503819BF343A5ED505059D15BF011766BC392188E8483E64B1438A1B2C270DBB1ED0521212B0BEAA0545FA703CE2FE495113FAE988C7F23282F536EFA269B81A75921A56888BAED7F23FA82195A78225AE72534D28650394AD9681278BCEAAD1A8A1C1E6AA0D51EA85717BA3CF304C67269E0562E90E8281D5C96645B8DDA08D3508DA723554B1CFB0E0B96C3367B49AB0D74793A772E6468B79AF1EB6FF720521361A2D2D70ACEEAADBE408A0CB8349F5083E899B6FE37E381D28B5CBA394BB9B7D943DF0167E1CFA7B263E942BE68F1BE1050AC3B51D5772C5EC02E7BF5A4D585B6031EEE47C35CAFB5D74DB20D643E39F382B8E69054F397CA6FDF47384328FBDAD37BCB29AFF15F2ECA75E7F9D8E8F5C24026EF6E4695345E07AEAB117B347B322B44F150E1B66286E24A31C5714E3D4191283D0AC8D8DB9DE4454710439758381D7C1392219168B8302CECE11F26D6B04A77F8A5DA32B22909498E154486AA5B4425700E1D08EE9DDB319217F7A9E5932C5BFC021EDD7E46FCD67638248C79A6C6C130EED0E8E634F332CD5ECB25FA65CE4B6FEE1CE618CCA6DF05EB9187D0B3D0B200B454753D7B16C7606470760B9CABEB4C3F13D4CBC63A96D2B97A403CE1E85075A7BEADB8C34E94508E87736B563848C1AE9CD34DA56D06DEA69811ADDA02507FFD9C3F10F6850BBE5585A507FCF0F79BE02B677EFD4FF3E4945EC800C6AAD1ECC53B9EA6A2C35B74FF196EE7A25938E267FDB83ECD8E5691E5644905FEC3FFBE86676DC30411C12EA05BFEEE31FCD4A804EC59D73BB15C931D031E8DBD36AFE294985AB20D87E8E338733EC6A6B7B4BFA1E0AD6A9905EBC7D4B5B23CF36C5B589A04357F792BA8D3B9F3270F3EE491DC0683E16DED773A9A6595D43FCF9EFE8C0917A71637C4A03598EEAB0CBF1F0DB3E33B1DA48987C00D85B207B7E960E866469CF67A05BCA16\nss = F855334CDE90E9E858863DBAED7BF4C45BF189861750EAA59355A3648B1CA1CB\n\ncount = 80\nseed = 09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E\ngenerateEntropy = c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df\nencapEntropyPreHash = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d\npk = 724ABFCD15255F0A5EFB7783D909031ED02C52A203DE570873C7A7C556202D53A6C086899802BDC877BC6A813AB59B781BB95F4FCA9EE76028AECB9142A992DD7180BC1C15DBEBB66765C5ABBCC5EBF764D5234D89A378D5925FBAF63A00E35D568804B973450A045E55C7C5F4907FEE390FE6877963E386BC20CBE929C3D247611E346EAE401ACB972843DC204EEABB043644EEA29BA2C1A160B98F0D28CAF0677AB2ABA362B7BFADACA4E1197F54F03AC8033814A71E1CF407972B3F1D9A986637A972B46D3AC46509C053EFBCB9A475BC4055265961C79E1374C2159BD2409A84F22755A1B32E4B604783BCB2AC49A27A5B0B07AE346AC38F54A2943559F02270BBB19508E903888ACA4BAB72E332285837B9EBB466E5CBA74D5AB6BB3B2A0FA26209A97F959C905BB4B058BA8ABF30A5A6C190A018A9803AC29D84BA710B30DA9A0844CC1A1478C289C32737144812355E0D7589B9AB765CA3B23353A350876F05081F3E4B14D8F66C998B81F458A394CC68C3B7BFD37366EC93113DB928E5F9BF0E9AAAEAFC619E332A7EF3898A66020DFC64F671879691C023409B53686770F8148A2B6F7B62B6AA42981EA0CEA7753599585034B9AD99C9AC8B12872B1A47A088BD8AFCA2D42093928A4FB770198C4CC50B0214C4C94FC7B62B5E636423C6ADB553B138591F6372CA6D53343FF7C70782A2DDC4801B262F220A539181C13F3C3E8E0A0D7191A43A54AB008D326DF803FD8757F88AC9BDC8BC75CB83517AC71FF8613B3BA713377FDAD2199BFA332B8C22C136350ADB9553E3643D0C45413782F3BC9E941965DC051DF98738CF50113AB422E4A22759CA016BEA6FCBA390ED64540112842F5B1373A2847107A43403B4AA5CCAE154B9C54831E3911239B79F1FE997BAE30A542560FE6647A2E7C4916097FD484C3D040456EA2BF8B63DBCDCC8577B7AED99C05FA28D468272876B614045095E918600F7C94BB0944F62235C169B58789AE8BC3E6F677CA8D238602399E307553E235D11836BE120B3BAC41B0A668E0841AB11F49E27AABDFC27AFCAABBF542911B6A220CDD626D819C44C72556A3946DF86C43D1B8693944D399A3B5B1309B9780E34330CA387CDE8E4C9B2D0775A962F447828D6295873CC1629777FD93C062098B6149A3E7C383E2C33CC3FE7730537416FC1ADB6C09F4CAA736E4C796D2A97FA3807C9EAB72993B4B876136B856C7BC75AD054288EF491EFFA872247A99AA39A9C2B7602027D65A169317CAFCBB77C37D89ED32489E3C2557998A06689B06AB96615BB5752D439DA446354CB0640686AA794444A806C31D721B8C6B820810A5AFC00932A885107B5F968B5C8EC98207293D8851892A01DFAE4A99832326E3863BCDA75190C4A487B46E3914B702017B1B520CCC30A5C475FB2DA94EA217F76556BFEE825076533973BAD3AC7305B5C764CD040D723617090AF4A7811E9AB206C6A331A647D9385A5E7D8BAD6C89B390B617018C4A0691D262429BBA173598B37D7C245452853506437E756A399670AD8E292B0D820E3567047C82870E82236389D99D678CD9B49526AAC30D1B830B12F4E62407A59C8F88B7B5D088A2D08B9F114C3F158650F32C682EA6A76CB62D3AD7357CC617D597A3DBBDF515F6852D71220768859D599BBAA\nsk = 28BA2F24DB8E2A5B21092964F1871E97E10F2727C8B27916A5068EDD27670D26B91A93332157AC686205E23616EB0271B081B51923C5996743CC114F3AD310CD6791AEB05F77960991513EC655533921A8D14CB2589399EBF18F7BA89BB7D6CD2D7336ECE1B7B63B98F26A49D356578CE7275EE67677D1482E1BB3D85B88325BAE0A00CFD1288C34078D73965442B7B140705F0FB76EE3D0921112C400C7A4D1337D6A3A8CDFF9AF05C64C079C64DD143F1FD56C28096313E82D51836A2DC1B0F37A2E00545F802B417A9406E55420B4D71FBC2210D05A771CDC164AD50932EA40A876051828236153B4E1715EDB1453045721E89A60ACD0066227704B8AB991E8A06812226BC59943C0814C847A1865C19DF4B7FA13BA3EF95543E724EF854CCB28BC1DB49B75C1ACA3649F848BC6F32C139AA79197543C628238ADB755F4DA6BD67130772B4790B28C9F1544A4E9860E875E68C1CDD9CC0CF17451434C7C53F3A9BE39849720B1B80A836BA4C531D49BAD16077E90203C9120C23239CEA972454B08A5F10812443CA75B913DF98DBE29C3312157E156311F67354D414AA041833F8454ACA5B3898B3572E819FB2C4CADA43C9C5191D6F7AED8F310CF77CCAF0C478686952E71A8A8173D0C223B04462B96C04EA7B218A13519B90CBE", + "3BE8C32B276F90D349ACBB6362706DCD54AAD0497A058AB0138A8E57D514D5D431043184BD1A07B77C3299BA6C7205938ECA8403F31A1C605A942B73775A1AC11C40D81988E69C15079719AA769B5F618052D5290D84714CA57418366C15B74DA4E98DF96ABDD19884EC1703F7978C4DD72B48528789D7148F16C23EF8BCD1F353CC4A76E7C238AEB1035424300F529ACD46926874190556133021A6A9283DDFE02EDADB7DE23A4D141B0787539B68110B4882A51F95403865BECEA06E2D7A1C1F534FA3366BC1AB387EB867477B92F00C0D09615BFCC1138137CEDE4098AD57894FF74982D71BA2ECA6A0F502CDC9C89BC6A44BD84FD8B62BB5D84332FAA830E2A732259945028D2830A8AA866F92C24E46D164C4F4658791C11F0703D906A82546C75F81285C24597BBA4B1BE3972F069D6B383D61CC32B9B66604B7CDC4BB39058C74CE770F04F758E6124543E13D2365A915802F75E90997B10B15E650AEE33A291C87030517B6C29CF10670D2DC5C8889AAB7518B4DC86D86E25C52ACC4DB175A5957118F983C3A4443B33803A3161AB24004B7A789778C8414A8AA8C819468EBC28B68AFE5333F7E666D44B5A961533280B0021BD3B24E2AA51BA58F2F45767A5722E918B1204656A2B44CE628A3A84125F918999A6311CB3569431C7B0D6B58ADAB6A30F9473B3747E33C7A2A9BAF87B709353A77743949277147928273F112B5E618167A5715157B49CED69A2492203A08730ED07B7AA14BAD136CFA969DFA68C28AF40B9763872ED1B05D4161489BCE1F473D4CC067A86258F6B664D2436D4856166CC60467887F9B97439F607D336114E46B2A2964C228A18EB532CC4C6813DFB841E60C3BAA59978234A06FC95AAAEABEC0123230AC33BDC48A4452403842BD6158C668F28F20BB5501984C5D3992594A9238E03798D178702B86973350724ABFCD15255F0A5EFB7783D909031ED02C52A203DE570873C7A7C556202D53A6C086899802BDC877BC6A813AB59B781BB95F4FCA9EE76028AECB9142A992DD7180BC1C15DBEBB66765C5ABBCC5EBF764D5234D89A378D5925FBAF63A00E35D568804B973450A045E55C7C5F4907FEE390FE6877963E386BC20CBE929C3D247611E346EAE401ACB972843DC204EEABB043644EEA29BA2C1A160B98F0D28CAF0677AB2ABA362B7BFADACA4E1197F54F03AC8033814A71E1CF407972B3F1D9A986637A972B46D3AC46509C053EFBCB9A475BC4055265961C79E1374C2159BD2409A84F22755A1B32E4B604783BCB2AC49A27A5B0B07AE346AC38F54A2943559F02270BBB19508E903888ACA4BAB72E332285837B9EBB466E5CBA74D5AB6BB3B2A0FA26209A97F959C905BB4B058BA8ABF30A5A6C190A018A9803AC29D84BA710B30DA9A0844CC1A1478C289C32737144812355E0D7589B9AB765CA3B23353A350876F05081F3E4B14D8F66C998B81F458A394CC68C3B7BFD37366EC93113DB928E5F9BF0E9AAAEAFC619E332A7EF3898A66020DFC64F671879691C023409B53686770F8148A2B6F7B62B6AA42981EA0CEA7753599585034B9AD99C9AC8B12872B1A47A088BD8AFCA2D42093928A4FB770198C4CC50B0214C4C94FC7B62B5E636423C6ADB553B138591F6372CA6D53343FF7C70782A2DDC4801B262F220A539181C13F3C3E8E0A0D7191A43A54AB008D326DF803FD8757F88AC9BDC8BC75CB83517AC71FF8613B3BA713377FDAD2199BFA332B8C22C136350ADB9553E3643D0C45413782F3BC9E941965DC051DF98738CF50113AB422E4A22759CA016BEA6FCBA390ED64540112842F5B1373A2847107A43403B4AA5CCAE154B9C54831E3911239B79F1FE997BAE30A542560FE6647A2E7C4916097FD484C3D040456EA2BF8B63DBCDCC8577B7AED99C05FA28D468272876B614045095E918600F7C94BB0944F62235C169B58789AE8BC3E6F677CA8D238602399E307553E235D11836BE120B3BAC41B0A668E0841AB11F49E27AABDFC27AFCAABBF542911B6A220CDD626D819C44C72556A3946DF86C43D1B8693944D399A3B5B1309B9780E34330CA387CDE8E4C9B2D0775A962F447828D6295873CC1629777FD93C062098B6149A3E7C383E2C33CC3FE7730537416FC1ADB6C09F4CAA736E4C796D2A97FA3807C9EAB72993B4B876136B856C7BC75AD054288EF491EFFA872247A99AA39A9C2B7602027D65A169317CAFCBB77C37D89ED32489E3C2557998A06689B06AB96615BB5752D439DA446354CB0640686AA794444A806C31D721B8C6B820810A5AFC00932A885107B5F968B5C8EC98207293D8851892A01DFAE4A99832326E3863BCDA75190C4A487B46E3914B702017B1B520CCC30A5C475FB2DA94EA217F76556BFEE825076533973BAD3AC7305B5C764CD040D723617090AF4A7811E9AB206C6A331A647D9385A5E7D8BAD6C89B390B617018C4A0691D262429BBA173598B37D7C245452853506437E756A399670AD8E292B0D820E3567047C82870E82236389D99D678CD9B49526AAC30D1B830B12F4E62407A59C8F88B7B5D088A2D08B9F114C3F158650F32C682EA6A76CB62D3AD7357CC617D597A3DBBDF515F6852D71220768859D599BBAA6D029BB2121C788B5B6EAD7226DF664490DAE362C4BEFB615717D81C656B32735FE6141A25F7AB9F875F79E0A82D6EA5CDE5A017AB637D5FDB7C42646A1D71DF\nct = 72A78ED97EC6F0DAFF51A9BAE85D1873B68DCFAA8EB163FBA6FB07A90DFDE6AAC88F65FB4BC7E7EFE6EE951364905859A26AEA558ADDA81619A3D073190F9DF2D0B68016BFC247BD2C3A1CEEC29912EF21B27EB77C7D5FC0CD9B774B75E3E2C584D8116FD0417BFAE6D2E4DE494841E45A217C2A10ED1BD3F158589DAC32DEDE68EBFC3707C473ACA1C9D44B1EAE40339106531779EA144367C767729D4991E7FB0BF3173E3DE8937FD489D09EA263AEE0DA2561E43BE35FCCC2D58EB25DC424E528B9C5575C5E1C53D0581BCF9D5148013A8CFBB5F4C2683AC792F2BE1D4DA00B136262300D51497CA16A2E6CBCDCA91A006F3CE6231D31AD90ADFCC92CF09420A789FCCE4F6254A6BBF1385CA5985C9DC9D8CD57F98EBB445DE0BAFCDD98B8B3FEC85743D9BC78E2CA193B3774E3C5DCA74EA7A8AA51A468AB4587F6C97596F7E66121BB61EAE71A9965BCBBC415D52C826016E84B204199FF893AA7A9212785E456B86775EAE7479B9E109959E4BB26F4E1ECA3181E9FF9E26708616316D5CAFD25F6169CC291B65F555590942871F3E4B62D4A41D9D9C75E8B215006A4371D8AE773333043FA33C0F293119B94E9D0E5E43EE298B7998FD6CDD1A9752BBB3DC19933A3BB232C37D4E5BFC279FA1405B7030D3C3AC2D47C999EF5FD2948DFF6A21855398D0186175923FB9C0A5D9018C74693C6123C52268A28A5B42550B965BC9DA6B3DB2F86613DAE9565646A4CB39A3D3F47C1583CBCA427F7F0B53FC60B31D474C810FDD85C8996189BE93FA1DC6935AC3A9BA2E62CC45C32F74D7C0490EB6E1AAA4F821ACCC848003D83C3B715D43ADB0C7D1D9B7FE54BDDD6A34FDB5A99158C8EE4AB3B9D1B4D4DB6F1518477E3931A56C014E3981AE2B406FD12CB1C6F275CFA4B3AF67457BD10D70D681C00ECB97D5D99EFAC58213FE364E2CB532C198F51A8B5773297CEC7CAC4342189FBDA4C2902A8687E8DFBC0DB4984FDBB9ACC6CF1E7C93B2AD02E7D346D22F3D36187A398F2D28BEBB8AAF98347130835EC07AE255B8BC6D4E50271C6C9CFE29D099DB6C8547A6526B5AA8F30B1E655F82E85ED78DF36215E2FCC5E127BD3670ABA5A368A4D16B8020634590DD1C6FAF3AC0DCBB74B006195F24F503F3EF13B5AE09B0730F9C140AF4B3481A0F50C3C65B90CADB05DFA01EF6494D8FC06A3D2A30B15D4324118CDC330AE4581B2DFFE0D8E7570B5082A9DF811B492F4F9F5C607990056B8CC03F74203F9BCC38E5BA90734142E7DACF63D2EBB1AA4F4A4EA4E29B0849054B57D8AF63F028AC835C50735808039EB602545BC1494592F30BFFB0C1ECE40726F335FBD052FA5CB6CD3FCACBA194850A05BD81C7838624AC8350E64AC910AC805DFE584A680CF9E43D6DF0F654540913DAA58CB0D14C208117E198271DB03E978436C193688B8809DEC85E7E4BEF4F2BEB731AB4220738477764DBFA8DBEE0B1A969BCF0D0BB1468DCF14C20C25D4A02746D0932554FD8501967F2DECE5FD18925C30C0B81AB2EACE088819\nss = 3030433313514EA95B5D6A2FDFB64D4225FC84EB70336323507AED63C5755481\n\ncount = 81\nseed = E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D\ngenerateEntropy = 0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c\nencapEntropyPreHash = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21\npk = 30E92DBF312758B73BEB83625DF3B8D5C47A7A334D4E140915CA1401D461D7052E9FF05F73A1598DC9622C324C1C8B5DE9B0386EA3CD95B86D80085588AC69AE310BE6B5B5379202F4F14878FBB5508907B99490E4191B1E13A6890A9209F0A12910A3E096747EBA94A337AF9E609DA4E8A9F8003633EC099983B8E778CA3D72BCA1C19B4FB4A0FAA4459EA06782367580B7AA49AB74B60C4CEF7AB3BB9BA081227A7E1AC2F5400F8F7395F96567403B2401A2ABB0B70E92E6CA2102C597F496CC8881D7B688861C7988363112155B5B88271072A7A7D68B76036059CA5E402532CE8763C52CA237A334832832F2A49BE3907D15852FCED4675547796D3046535390D44580C24BCC3D67A50CFA2AD8936D46121A7F60179BE7AAD0746E8A2C8CAE124D27181A374493DA6A68D47387A44460B39A45B2619F1D29B08BA4495230470B87BB926279EB760B9041632317C4D7A19E7753458DAC07EB73331D808CE318555E1A2828DA2F1D101CDC9B8363990B85064F63226C36C71061444E17A28C3B56332BAB4BEC2602F5C31394C870DD21030997564DE52602C2628C41CB7AC2388EF35371F870A21675AC522660268A1802A2E4CA4C7152A9776410910175FD08C5E0307F4C2A61C877ABBD2185CE58738FDA15335ABA2C77A804F94077A777FB49854C7A78462263E435A1D7B4A5205AB879438A91EB60397704CD937E66C7310625A6276182D86894EF9750F1817D85709BC578092D3B65F5C84514361264909DC2147AE6F3A577097E64BBB2C679C845D827B1AC393497575E385BB39563E125C3A3925A21160201897072F03F45D6BA85DB7EB1D5B8EC7111DD785EBDE07056653507E967385945389493B95C0A95827583F01DCD473FD3138887D3472E18B24C1B7E2C837668FC6917175471F3CAA1323A34432B72C7B68F658868A2AE87306109B1053ED2BCEDCB7037AB72D8C2BF48D29A0822575CC91CA1E5698286C9B19A7471A5B652F6A900659DF9183C76417F0FC89D743AA635791D588CAE6F650F3D314D65A6AE81A935F38B964F290BE7A1A75F256776F17383F9BB9F9203415622B60B2A152A7CE3420CB49C3592AB8AAEC009A237A12C2C04ABAA08A382622DC84A053C94881664A97381AB88CA41846E82C02E00C6033B4721DB29B71FD29069297A2CC387F2AA5336816C66E75B594BCD144171C3F7AC6DF8A9A10A71F35B39A3DA", + "7D53571CB33860315288C2F7843E855D27DB6F27B38940F973B2B063EBA12B3A8B73D46C6781AC87F44C91E982CB27E534161212B367AB74A318B0F41E7A060823F17814F9A6E4F5A9093A6379FB0291D99916B15ABC596550F152BC79703F1B0393B720CB85A510D4C9557ACF3E620CF994C0BF8C06C2606041E7C3CE6044879A7612C3A2FA587B1B7676B956291A7BA5A78527A163AE08696C7C881076189BC1623C8D360C8D85C287A9C0C6965D0FA315E2037EED604084416FE31B2F01C7678311ADA765ACD7F70DE59A9A85A8249205C78CAC786AAC9A0A0A7352B18F9CF936165A9C39D99AAC7C175A5025F1C66D04354480175FC3249930E66C9D06AA50E7ADFEFAB6AA9C205C1507A8F40512A45CEBFB2B39F3330A962ED717408E0934FDE42A5E1CBF04C80F37D7DFC7EB53A785194C4A1232E61C37A5\nsk = 2F766AD78A0112B8CD4BF28DD0F589873553BF114F19C2719F61A32CBC85C71975B911237BC6AA6ACB32B613CAC9DC80C85493FAF63C3E337C274542AB4729D02ABC5DC07309032C7112540522575D663C89714AA7A456410144D7C2BC1041C03D5A56E08CC7E5663C01F52E5077288BB8CBFBA21B4A8A19C055691E05C22F94C62C3CC2B6A9C155E2A4EB2BB9D95B8C9D5A6394D05AF87B038C210D9FAA266CF07088B3CC7AB56FF3366FBD595B3C790B5497B34B94A72D8153FA13B40BE96B51315CA4D22BE3828C3556843545C47B0254266A802A44BEE6E5A19A446472322C6AAA4CF47218EE3C99247564C552C93ED589EA8BB2C637BCF7277D5B5058DD80342815B2E8864B4C330920A82EC76B4A7BB893E0D18278F47F84743223A67F2983AC8C4A1845A61259670B02D6053CA181BA4C1BCCA05B7AF2A27C59C1E4E38DA723B787AA2F36C71E3BE05039183BFFEA6AB3BC779DE2273326B327D42517B6C6ED8C7F96C6330D4C39E3D2A7B81A538693329ABBBB5947B068C3CF7B45C173C1BA9964C86ED91D0BF64E209C1910C218434311A50A2128D52754148159891E00475654AB30B9693AD507B2E19ACB7FE6B14F27C09C6B2570B861926683A285014631C2D7CB8C0C10A25D073D3C067AB819B9DC27971825AE21CC2E50D377E3396F0266A5BA598BBE9A868B0B6CAD2CA3A8CB503778967BB930D90795719B237238C1F831007C690186949C600C6F587AC0D81C8334C57FE0C59DB3E2815D63C26C620FDD75836261644D99327A334EA5A40571F0CDA39CA716D2BB894A50BC4CC84D6621B60509DAC77ECAA39B9779A3696749CE83933EB70C1E85BB2DC3421AE9A0EF40AC2D83A1FAC16C6DCCB0AA16AFF9A94BB6D125665C3001B845E7F20E7C90A3DB636950B0836BA008DA33500FE47FD4A81DF0E268C62974BAD02A6D3B2267F917E2046DF3C1883187683F030A28A129902083CE26730438B0DC0042998C9472F5A7FDBA371D74481DBCB9BC4CB281E7CC1DC4455823AE1AB8B233E83324544913DC261B6274464B656BCB645F87B0CF4512AF443959E67C47D679020C2905D45E21DA586EE8291085A8A432AC6AFAAC594081EC298DC13175779B8635FC8EAE58982258759999A57B704A5B040245D282A9B6C9CBCA838399523F26695F60389AD42F6512783AE65A0C25B7258674398839AF28866671329109A58E579C026549F0B7041DBB6623665FBC9A2EDE41C0436635325912366AB1364B5A3162C4B8C2A14480AA6BF165588B8D26EA968291CABF66A4E26722F87977DAB7807A2C65A26A9CBD339BAC0B24E6B46E0A8082BE95BB7A41B1B8B670ED3105EAF994A06A6414E9ABE2A1B608C29C94B846012A0FCBD6959ED411D8D0C70A32559C68C74D94B2A9707B9D9755E3C69AC40782E97A1F904A32DA824C7459B59B174A9FBB6B41947F47B3361D5558D831B2B444818FFA4C17F4BFCF8B9C7CE451F4CA99884C13F85C24D3CC4740D2567A54AB0583A175759FD7E197F3000A39717BFD9C768248518D50791CD84DBA795E85388DCA21507BC669FF0B906BF515F38C04DC838D0D1357377B1601887AE1B0A0C4490D38A871910C695C50008E5A5A30E92DBF312758B73BEB83625DF3B8D5C47A7A334D4E140915CA1401D461D7052E9FF05F73A1598DC9622C324C1C8B5DE9B0386EA3CD95B86D80085588AC69AE310BE6B5B5379202F4F14878FBB5508907B99490E4191B1E13A6890A9209F0A12910A3E096747EBA94A337AF9E609DA4E8A9F8003633EC099983B8E778CA3D72BCA1C19B4FB4A0FAA4459EA06782367580B7AA49AB74B60C4CEF7AB3BB9BA081227A7E1AC2F5400F8F7395F96567403B2401A2ABB0B70E92E6CA2102C597F496CC8881D7B688861C7988363112155B5B88271072A7A7D68B76036059CA5E402532CE8763C52CA237A334832832F2A49BE3907D15852FCED4675547796D3046535390D44580C24BCC3D67A50CFA2AD8936D46121A7F60179BE7AAD0746E8A2C8CAE124D27181A374493DA6A68D47387A44460B39A45B2619F1D29B08BA4495230470B87BB926279EB760B9041632317C4D7A19E7753458DAC07EB73331D808CE318555E1A2828DA2F1D101CDC9B8363990B85064F63226C36C71061444E17A28C3B56332BAB4BEC2602F5C31394C870DD21030997564DE52602C2628C41CB7AC2388EF35371F870A21675AC522660268A1802A2E4CA4C7152A9776410910175FD08C5E0307F4C2A61C877ABBD2185CE58738FDA15335ABA2C77A804F94077A777FB49854C7A78462263E435A1D7B4A5205AB879438A91EB60397704CD937E66C7310625A6276182D86894EF9750F1817D85709BC578092D3B65F5C84514361264909DC2147AE6F3A577097E64BBB2C679C845D827B1AC393497575E385BB39563E125C3A3925A21160201897072F03F45D6BA85DB7EB1D5B8EC7111DD785EBDE07056653507E967385945389493B95C0A95827583F01DCD473FD3138887D3472E18B24C1B7E2C837668FC6917175471F3CAA1323A34432B72C7B68F658868A2AE87306109B1053ED2BCEDCB7037AB72D8C2BF48D29A0822575CC91CA1E5698286C9B19A7471A5B652F6A900659DF9183C76417F0FC89D743AA635791D588CAE6F650F3D314D65A6AE81A935F38B964F290BE7A1A75F256776F17383F9BB9F9203415622B60B2A152A7CE3420CB49C3592AB8AAEC009A237A12C2C04ABAA08A382622DC84A053C94881664A97381AB88CA41846E82C02E00C6033B4721DB29B71FD29069297A2CC387F2AA5336816C66E75B594BCD144171C3F7AC6DF8A9A10A71F35B39A3DA7D53571CB33860315288C2F7843E855D27DB6F27B38940F973B2B063EBA12B3A8B73D46C6781AC87F44C91E982CB27E534161212B367AB74A318B0F41E7A060823F17814F9A6E4F5A9093A6379FB0291D99916B15ABC596550F152BC79703F1B0393B720CB85A510D4C9557ACF3E620CF994C0BF8C06C2606041E7C3CE6044879A7612C3A2FA587B1B7676B956291A7BA5A78527A163AE08696C7C881076189BC1623C8D360C8D85C287A9C0C6965D0FA315E2037EED604084416FE31B2F01C7678311ADA765ACD7F70DE59A9A85A8249205C78CAC786AAC9A0A0A7352B18F9CF936165A9C39D99AAC7C175A5025F1C66D04354480175FC3249930E66C9D06AA50E7ADFEFAB6AA9C205C1507A8F40512A45CEBFB2B39F3330A962ED717408E0934FDE42A5E1CBF04C80F37D7DFC7EB53A785194C4A1232E61C37A564C819D9BF66855F6AE70627F04DA8378547E5867E2EB9759FE0971EFD601C4A11EAFECA9E810796C34E8CFCE9D59342884456007B01DDD12EDCE6D10ED87E4C\nct = 98322D7A13921EF76042F6DF285A8BD2D0618D843820CD3FC35706C97D92720BAECED43615976F33A50EB4F4871B2CAF187088AC58BF63793322CCBE9A510CFF90786A7C3F28CEC3BA32C2D90D280A6411BEDC9046AE4A13A59FBC3FE2330C34D78C6743009EFDC3554392C4139CBB5855659A8A4C814F89BEA551FD3E8C219DACA38F46F8C6FF101E07A31F0A07B8BE8EE2656C189B30C9C6BC69DB6B6F14799A239B0D8677E2A76F31E081182BFC44371F8592B1A4A8A01DC524BEBCDD43F8E48A77550628253B5B78688E6C73CE990E967C6D67383EA3E66B9D8349FCE9EEC43DC2C2301A4AF7A9BEB52AA99DF13C8F578210647E8935871546416B46BF2ADE02A6AAE8B36DD9F0722DDBB5A06FE93E496427EDE60CCB84CD6B29539AD2D7F608D825D6B10AF253852912E2C959EBA801E3D895CEB04319D3791C31855E40D112B93B5444DA843439805F9C154BC0436859A4009354D0497334739EFF86318AD7ADCB4F64B4E67775D8294F92B8501A88FDB13462D82A568CE39FCEF1598A56E3E0188FE62AC5E456F6D87D37CE482D59509CDBE28D909D452A5D7E2A8D8CF90043E23C330026811BABBD9CACFE298C77B487A9814356133CBFBC0C1BCC9FA503012AD5536432313B3A88596D44D16E2B7339B50456EBDCA6345D95FF6E36CCA50B0036A79A86C8500B532AD3159444455DE6EBE469820EC9B9FD8C956134E99A85D4BB83B02F1AD116DE1249750391D9D9B860F9B75817BB09C688FA9BECAF9A5776A8CB6EE94A4540EC7B9B790A7E787B746BA8343CCDD9C73AC6B2F19CE9A2106EE0E2FBC2399DE6B4250B963E6BF5FCB0FB58F4F182A4375077848C09A1F358B2CCAFA3BD7784DF29B099171E74DCE17558934198C0FD3FA998245AB3BCD782B32B810953C845685408AF76D6C6CC252DF2A339247A5C97409B7E59E652C3C70B4D7B10BC4AD9D1DC5B5572ABC7DF75B0D335ED85C98AA6EC2B9A1EB49533B258BD1BB353339D3BCF303232CA1742F7B3BC69C959CF9A540BF7A5B08564D997F467EF6FBB69747B56C4BC07E7E3D6B4738AF1BACA39417DE8C34D72798336D2934162B6EBFA6BF46EBA85B1CD94BF04CC7B5E36A1EF66A9BF687477114295F8EA84C80267C64BD617722D6F7DE3601216059D7E82BDC18728C2F2CFD63EA1029CAE451B15AABF7BE2D13D7191D1EFFEBA909B05A419B820424CB464E7DDBD0D272BC464E689263FD501650B7AD691565625941DEE3D6DDF9195FEC5718DDFF43B067446A32E2B34D1482348446DCC8B92E0A8077C0DCD1E59F05C9B6A7B1FA867F878DCF731E5FA38ED9596F207DBA7BA0FCB3EBF2E1B0A8BCAFFAE5BBDCDBF62FA40F5AE8612B1E319671FBC71DA87F5297DFAE4BD161E02B7115E9C5C6F09A1C44540D5C8435C7E2CDA96B9BCF9414E8EF6F1D938ADE592AEF958996D908DF29D589857A422B620AE1710889B58CE7A59A4DC96AA46A7D194AE8E530DF9DA7BD319ABA09F94F2F02FE5C4DF2AFC59F77453742F35C08D943F59E6E3\nss = B8B9F3AF55E8C616D07C7042CCC26BB4B83D20FD502BA5CC7B72310990EC50EC\n\ncount = 82\nseed = 373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE\ngenerateEntropy = 2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28\nencapEntropyPreHash = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f\npk = BE0AAFF4D255D72C6E8424C2D5D23F0AA4C28094691AC4BF0F56A51EA4799810CFB024C151C35CC3C6CC90A41AB964370C2BC953A84A73C87A02813DE34B933F233DA28643A93388F944", + "C033236372FA6E6ACA085B598123F27122A40074A4AF57684D46398E5D58B13A863B0B984E224A7AD52C1C4EB26909451DCF2A15DCB11AC4CA38D93CA350078138E0AE87F1390FC9045EEA420260C913C6B54DD93495F31AAC32350CD03500DA308FD8BA0777C999CB4982C91E569A1C52396EDC506AC7CC43264A05CC880191501860F1A32F7760AD3B17FF693508339FCFC05FAE095C6A96C1E6864BAF147186BC22DD882620E5A5F4516DF92B8B715394C5677D0DB913EFB25459D6C636442A8CE22899F8943957BB2B281A8ED14BB5D0CE6DE3086EA8B6165798619B2ECBFB22727CAFC6409E23088C6C940C23E86A603788C07BA89D6BADCEF07D79174ACF70C55B7B30C067BD8202A1A70998459C54384196F814515EC9C7F360061270090EF37AD32115242C2AADC0121E1A08623038B311982C669DE3DBB1C7789530191B07A947C9637BFA241ED35AA1D03C81F0D70F8B95112A3B1B08B25C34DC7E1D577FD30A808AC574DECBB51538C2A017287E62128F32AFB0F7A73EC8831E6B975007592B5C652FA636C7315BAA474F873A5DA2E82FD146268DC951689BA83E046C0F4820447C3B3E6C78CD240BC4D21E0A4660EB1C69402B617B83057874122E203BD6313D7874A987F2987599CD4D7946E50665F7D9A80651CC8DBBBC4DF605F48274FBA0640F8609B6554A7760856259C32DF00D3056AEF65436A285583CFC9D9A644F66E382D4907C6D78AA461A2B6BA8887C238F81D31E796A675EE8B7A598AFD5D79A0587965420A2E9F2782B71331737680A499AA759824D11ACF1A001F9A5865B6568ED8A1F4F4CC38F74C24E231965E9830232924526BAA377B2EE933A1FC4677EE74FD98A0881628315AA95085C7415A1A51A98406FA345A69802BA71CFC885816EA30FADEA0232B13EAFBC24B84347124BB41F8C663506665CE4C3801B09933C19675C1F9CE54C418207B69215C91B10451730DE65A4AAB6C97804AD33C50233F83599133510BB334D9C1F4B7970087700EF45500CCB31B7933FE74A346AEA4C9BD409BC5A186F00BDCA67CFA8D041DFEAA56547A71C35CEF1B664629AC9D4F431CFCCAF62A781A4BBB2ADCA7A7914627DA380873977E6E1A11FEC0938A3A886E9B328A8A539557F6C700285693266742F779BBE2E7A0603060673C7BE9591BE19A57A0CAC91CD1C61860A86356B90715886ACAC2306190CFF686883A61E56140F64BA76123C1B07614FF5C8A4B402CDBA738AB68B749C1151DA62C30DFAA3BF826D4848C4910C9EA20669735CCA4DF583E0C5412B610BCE816FD17AB9C203A7EA42081901C8CD78940F090EFB49718AC90AD6A101093580C13B5FFA0AC0D7B094D913A9DDFAB03F835F79173E966746C69A0228D06A2C363E94522EC68312CD312ECCDC688C4A88F6A5B7C3464CB7EC842FC1377359A162032C8C504105461936714F451481D8A4942D1715B6A65583999B96B0C47A914F2F721F5EC6315C91B009E714F6518BFDC75E828256F25740C91E7EFD93A5D7DB1850127DF85B8F086DFC57F1F62A86D6EE7E45AFF3F27BC1\nsk = 6C33B8AB2B4FEBAC9FF7DC3E4A689F468A4F08D5C87EF8A142B4766E24073DF336EFA5A0D6FC17B6BB2C615658EB04AA9035560FF7979E27C65A85CA6B1B9BFAAAB23D89C6A825CDF7E312F81066D516BE72680E5A665830F74E371BC411BA86F00704DCD3C40C8C1295D6B52ACA51AD41732032535AF95BEF907127EAB1EEB54899A36961793EC47B91D9725643664082C4375F4843B0031B815C8DFFCB7F25D4414191746D5AAD14093BF2C005DF655F69917BAA956721B4CB8B8B51531A4A6C0CA50F8AB21DFC7CD9F81D730157A59B971E4B4A0FBA8EF49754A7C2BE0325C8BC623FD2A94A6CC4226677260FFCB64D75167D63334E395DF5BA4505495CBC8C3A3E40AB68796D6C646775339C29683A21F921A7C6A79D39A95C876F782A27A6365908381D793B537D1A681CAB5599817E050CCCF7803BF9A90CCC4084743C96069183B08702979C9DCA2B9D9BC26E1DE849976AA1465B29EB260FFC64478C39945A9B402520172CD7861C5A0CC089A028C8200208B3E4D7B3A91CC8C209C5E1D201278B01CAB34126C701BFC2913DF501F6D73D9424CF1176B8616C04C10940EF9832957585EC350E9761505162AECB28884F659EA23125C382CF24F383F9B09FEEE8AACB981DF21A6BCEC26E2A67493B919FEA06170C18B79E5A01E6E89516707BCC7CA353727825514AA0D52504606013E53BA916BD133814C36B98FFF15F847B7383854F692450AAD28231F2BB4FD839D2B532066114DA65BE8CC5073F9992E03836CA3A623C301999A56FB00332D1BA8A26D599D0F5A97975814BE81FC9DBC536D1C165A131CA3C55D04A05D7A53FFF1299D3860CAFD8BC6E3B97E72A595D294303A12994510F74887FD1D7BB18DA70BFC5BDD58C1F6C1CB56F5994B7F2225CE0AB29E8CF3DC851F1AA5BF2BA255F7215CC71C5DA95115D6A98A2317224BC6DE1B2C79353BC5C3C046A7A0933A73419F7B117B88F3A53777143546CD29014E15E37C33770A8A9A11BC2F38777E400132A812A984908B3D2B87FC465B564045E79453C0666E3682A894C269551AFE25286FCDB681CB50B260B4327B46C2D0699BECA103965B0A218902EB4680C1B8C3ECB2011A396B0DCA97D56AAD231168FD9A7CF177B85B7729DE4A4BF035482AA7758ACA9E1F36BC9033EA34C6DFF91091E8B36FD2A2C6B1094A8338AD540C8F53CAB80D73E7DEC3977452915B616D0F0BF9E842663CC477CDB5DC94579D6222D1B647EF4D358C5435D3D0799242B66818A683E8C5651B0B26CE4909F8656FF35CD7FFA1C5988074FFA32DF093BCDA32AEE2003825593B545B44190787C4C8656D85CAC293F615811CCB35EB0413F44B1722E0A182F09481712AC68E3C9D31085EA77946A54BAA91C8AB8E814C5B94206070C0A6037BC02A292082018933A5AC32141180A6DC760C2C9ACEB3B1A1505464150A732664AA51B02A721B63759379A638BBFD07FF9A7A84E071FDA70200C61894A8891DACC375C120A35E0A4F296A02845477BC0484FB5BC539C3B8BEA3ED2511D480B1DBE76C640622B67A1A8E000B954057322CC005F88284D6290A5D720E32B5F6CB6B992BC182D66A73B5019572867640343F267133B060545D4B2BE0AAFF4D255D72C6E8424C2D5D23F0AA4C28094691AC4BF0F56A51EA4799810CFB024C151C35CC3C6CC90A41AB964370C2BC953A84A73C87A02813DE34B933F233DA28643A93388F944C033236372FA6E6ACA085B598123F27122A40074A4AF57684D46398E5D58B13A863B0B984E224A7AD52C1C4EB26909451DCF2A15DCB11AC4CA38D93CA350078138E0AE87F1390FC9045EEA420260C913C6B54DD93495F31AAC32350CD03500DA308FD8BA0777C999CB4982C91E569A1C52396EDC506AC7CC43264A05CC880191501860F1A32F7760AD3B17FF693508339FCFC05FAE095C6A96C1E6864BAF147186BC22DD882620E5A5F4516DF92B8B715394C5677D0DB913EFB25459D6C636442A8CE22899F8943957BB2B281A8ED14BB5D0CE6DE3086EA8B6165798619B2ECBFB22727CAFC6409E23088C6C940C23E86A603788C07BA89D6BADCEF07D79174ACF70C55B7B30C067BD8202A1A70998459C54384196F814515EC9C7F360061270090EF37AD32115242C2AADC0121E1A08623038B311982C669DE3DBB1C7789530191B07A947C9637BFA241ED35AA1D03C81F0D70F8B95112A3B1B08B25C34DC7E1D577FD30A808AC574DECBB51538C2A017287E62128F32AFB0F7A73EC8831E6B975007592B5C652FA636C7315BAA474F873A5DA2E82FD146268DC951689BA83E046C0F4820447C3B3E6C78CD240BC4D21E0A4660EB1C69402B617B83057874122E203BD6313D7874A987F2987599CD4D7946E50665F7D9A80651CC8DBBBC4DF605F48274FBA0640F8609B6554A7760856259C32DF00D3056AEF65436A285583CFC9D9A644F66E382D4907C6D78AA461A2B6BA8887C238F81D31E796A675EE8B7A598AFD5D79A0587965420A2E9F2782B71331737680A499AA759824D11ACF1A001F9A5865B6568ED8A1F4F4CC38F74C24E231965E9830232924526BAA377B2EE933A1FC4677EE74FD98A0881628315AA95085C7415A1A51A98406FA345A69802BA71CFC885816EA30FADEA0232B13EAFBC24B84347124BB41F8C663506665CE4C3801B09933C19675C1F9CE54C418207B69215C91B10451730DE65A4AAB6C97804AD33C50233F83599133510BB334D9C1F4B7970087700EF45500CCB31B7933FE74A346AEA4C9BD409BC5A186F00BDCA67CFA8D041DFEAA56547A71C35CEF1B664629AC9D4F431CFCCAF62A781A4BBB2ADCA7A7914627DA380873977E6E1A11FEC0938A3A886E9B328A8A539557F6C700285693266742F779BBE2E7A0603060673C7BE9591BE19A57A0CAC91CD1C61860A86356B90715886ACAC2306190CFF686883A61E56140F64BA76123C1B07614FF5C8A4B402CDBA738AB68B749C1151DA62C30DFAA3BF826D4848C4910C9EA20669735CCA4DF583E0C5412B610BCE816FD17AB9C203A7EA42081901C8CD78940F090EFB49718AC90AD6A101093580C13B5FFA0AC0D7B094D913A9DDFAB03F835F79173E966746C69A0228D06A2C363E94522EC68312CD312ECCDC688C4A88F6A5B7C3464CB7EC842FC1377359A162032C8C504105461936714F451481D8A4942D1715B6A65583999B96B0C47A914F2F721F5EC6315C91B009E714F6518BFDC75E828256F25740C91E7EFD93A5D7DB1850127DF85B8F086DFC57F1F62A86D6EE7E45AFF3F27BC1DB315CAFBAEC2F8A0142F45AFFFF65289E826C9244AB1CB03F9F65DF3E3CBCF711136E2681DF2EF881B51A092A9BADBE72C9772C169808521C47149578621E28\nct = C324CF3A1900484410A1DE432AC56A735217564A14F75A75526E6C83672BE590AFFF601320226F0C0614068ABB30B7B0AA66D54B4FAA789F9D9E0E48DAAF7CB452F4897CBE76FAFD89BE2FE0C32F9D0D4ECD61E6AD891998D5C4B334CB9DD402C2284E0F03A85DF505C876D300DA586E398AC16331D8F8B8E84B7347EA13D50DD1A33B7116520638E8BD779793F6CBDB1ED82D8ACE7F25E50F94EFFA23DE36BEC9210B1DCEBB1319A8AF22200A33A49C09B63998A18B4D438E1E4958F5DB78CCFE9E10FF0537F35931F05E629D8BA4A5B18E9C1EF194089DA0C96105BD287EAC7ADEBF758F4355B560404351C58646BA01A955644D1FCEA3A30F7AFC01641D360E74EA49BD27C1C3943092FA740075AF38EAD19E6376E4C91F9075BE124B4A43A0DBED278B3ABE532698E57B60D1DE574F31E159D98EE07896B6E9D88A4F2594BE1F0A0C73D7466FE92F8464191B7A7E54791981EB2A8D39A0B712F5D4507F8FAEDFC7E49EC6F31ACC77466494EF73277330AC837272D68CCAE0D05D75A235E353AB29216A2E8C7ACCA8123D24441CD51CDC6DFFF3AB4FC70800A427642C1E1795D41C9BA9FC87A3035E7F1CFE390F1EFBB9B955EC6A0918BC45411E8325FE8F4D6BD928D4029949508DFD4978395B6D021C92453B8599D8705951E2FECDA5F03476ADD8B6D7FD9B1336E70A57F42017CFBB329E925180E034A438A50623589871E47EA8994C1ECE7E35EA42384B1E66DEDBB3A111513B6DD7F25D95F5FF0236B717BADC740505777B2CBBCAAB063523C6A8D1EF6A9CC9F689DC6EB2759D5916C4AF1656", + "4E6C23F38A4C27DC1219094A023EBF5B56827EA897045DC881F0A89A853645942356EFF1A1A9BEA7F2C12C68B5EBCE0706FAF9CD72E453E0188071856C7FF37B952CCBB53CAD0CBF604DF59438C4022F6F26D71E9073CC1A45AC6BD3F6A71F3EB284FDE720416CCF1ABCBA0C9239144A6AA38AE655786A2C3820407C77F8378858F0877E6CEFCD5BCD8E5FAEDDECD68C1E2FCDF9BDA5EEF60FB7E8AE441CB8054FF7C94A8697BDE5001893ABF8140424583DF49796D1FD10F4DC493BDAF3C1C3B76FC1D34346CE5A5B7755A68F8C5490CE8827CB8AB61C3339F0DECB83F09230EAA58E6154BD8E1A77291654450A4949C3DAF8B4C05B001D94F21F0698C426A93D64B2D1005D1217BE6783588EDA458545CC1D677B2770B25491224D8D194285AD612F741ADAADEC5B2882D13334B9BECEBB39F9F0D4DE237FD36D7B4E114A079BEE6D7C2AFEE75C4961F81C75887A616F1E6497A4825C939128FDCA95DF452C5F4D27B1D516B33DE9336E394906547AB7FA5ED5A45CAFCBB56E324B606DAEBF25E705590EBE36AB32F5B4A4171AB7832DBB66177E9AE6C29E5E4F503AB861488D5AD246988D4CF8A41276F1048E4D778776D34577679069E4248CC09A5EC7F533685E137AC32C984E91E8830E1934F6B2F91B33A3605C53E51A8B7264D53B69AF57507F5B5AB6D4F1B1B09AA1E50CA13CBBAE62AE464E99C40C2072\nss = 2E4139C499A24CAA334754E10C6BBDDC7A0830499CA65E941AF8D87EE022D483\n\ncount = 83\nseed = 16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F\ngenerateEntropy = 9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32\nencapEntropyPreHash = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48\npk = 690B34B6586039100E84215EDDB39AD2D40BA9F80165623122A2C5FAF3437AB0376894CE67397D32A67C3BFB9761850C1C68AD988348725C83A378143D504400F995157903B9D04EE43404AB2CC7C35B8E0E09CCE4559945F5640450703F81C35ED332746162F7B8328F78BFC3359E7C1B4FCF06155FC745C70245FFEC09ECA957C8475C62B05BFFF288A5E5A5C78206E48C3EF373658859C3D9636786980578C07B764641D6A87222224557D10436FC72B563883ECB0934E50B6EC89429D7792EC0BFCDA416FC2AC323A58DF3FBCDB6E023140478868055251B1C09FA023E240E109869C1D2967F598A529042D9859F97CCA2E85A635418707B3AA1835B77DF93AE4DC53F228083DE6A04BDF58655C59BF57B107987B88CBC001E010B9C2458BDF138288190F955B62C7013DD5784C809A7B1A29F8C3C33F0311A555306327392DDD44EC8F72FD5893F56F58BAF207F9EE98B7E31092F761C390763A8B57409C7C5C665A913E20C9B62A5E80646364AA8E3B95030FB2FB289991B8637EA57C7B324A25E0389CE979B5E816FF841456261BF042C85DAD84F80D788076B7C69CABB8E389A72657D7D63949657B934A468516C36674194DF1AC3F595A294C28D24C26E1B1B5AF5B542E025A182868E1555442E0B0D064865ED5CC1665074E55AAAD601779E591E1ED2AB07CC551437603D24CA743218FA846822B2857F871FA26834E0422746A6C7DAD256BC0B4BFFF21BD7309482D7669F8857543A0436140EC684C959D26F2F827A84B37534B7AA3BC0A08163689F01141B511E7D11A316D2AA7D73909E889DD000C20E38667DA048278B5EE87188607B4210642F5C38866FAC1549637C600C8BE8C60C11AA394E8344B6C6536E687EF6DABAC397ABF1CA7486F6AE87D8A3DC8070B5687F7C6A73225B9233685C6B703D33677998C24E40A72894193CCA1C5ACBE4A133D85A6912587AD4AD522214974CBB1F877E16164683021EA9C335D41B000CF52A3ED45B2D95B7E2D061B5213DB4C6BC36D76DF5DB9EE6984D31BCB1F6757DE7E51871F1AE7F388C5134956D3286A49BBA39967889C9A424772BF5DAB014C94893A4C8B74AB099687919243C7633CAF297B2B73AB15DF419F6EC22D15A95553831BE379ED0489749C495E3B6B8E190049A8065DBA8933FB21BA3A751CFF289A2E2772B06A4687338CA88C0EEF1488B848AFA1041F4F9607EB18BC0650055803041B728F2F1922CD984D228096FF29E71F097921423CB82254C40A615240A2482A3F5F095F5B399A8F9ADDEB6B726F43E3AF64D09038CAFEA26686CAA2CE2194CBA660EDBB083F92DC2A51142BBC922958C86C62CE7A4B3A4C95240D72244A912C3C193485208CDDC4514495B35863CFC6CB41FA721A78080FD7BA72669AC6B29ACCD3B832D35AD70F7584E197D695B78C832000C1C337FC019F0AAC04B2149A469420C15B2DAF5281DBA5DC3618E0135C043F139CC74B14E7451FC11328F06B73F124766403541131D94506628C30B7BA68564179FAED9C9D2A20F3B61793A33A65E92B699A47FDE974EECBACE22690273A757DA903A886778002D283A819CB1EA2D34B8462DCAB57C85653E363629D9270738434AB1BB46BB71890031FFECAF8FC027D2DFA2A4AD271DD702F055836F40CA137E5D0EF9\nsk = 2220BFA6A447DB5013ED5811B45742B6E95C723A35851518E04B1B619C5607944C341A1ACA4C0EB297BFE3990D514ABA3DE30867D646CD76A1EC1176F1E84EE60704B0E04366E27ED0F321BBF42322F5289F5167435B880851B48DE717E40A1B56387D4705815701BC2B80C55F33B3C20244E0E27FFCF43C457A3674000A4404B4157CBEFA05C54F50021684059939A3AA088DBBA13BE56047DF450AFE33C8742ABB0CF48E0B1C24E8719EECE41EC4A3254836B4E45B4EEBBB43D398A813BCCC0C42CC4E437050740C892B657765B252943896325E3F4C45887452847AA315BA8C811B39254A5C3EE64F65823FCF2A92E3198D2981289E021530AA4CBD210FABF51094392E25E755D778A02CA145FFF47165711AB9397A0F9B3DEF26BD0E5143C23A815C8582976521D63BC74D8B42B95280CDC77DE3528628862F44D475F49AC204C87D2647414A4A136A094B7FB923BFD3496B187592E81B8168BDFFD9522F60BC37052FC579CB3F7A398DD677BA14A3FCA1248057A59A58531B7A1F1773735A27612520B03121390CF624D46927CEC7C7D00AB13DC2BA6445236BC68642EC9659D7BBA40AA692C40794BC4BF5F13FBB617E711A54BD825329AC6A9AF2A88A54A600C0CD6754B4A3ACCADB397CABF2AF41463C00512D6D206D011BAF6D833E4ABB8DFBF736DF8036278A8125389C3B99940881760AC150967464483242DD52358A075271FB82D949AF57F345E5DC46845A94A37893613A76B6E7B4D0DB0EDDA213302677FB73C493A349704333278B201B6BAA8315731A348DED27283DBAA05E057C26C35D68A5252F1715337A1543895DFA4C395F9909B7B1283B450B71730292C32DCFFCA05221B14849AA5F94888E2A3FD33CAB3B380F8093742247AC27012E8D7A6B8702983DFBA43601677679568A8051925133FBF6550DC318E387C3E3176EC9C3CAD6A739C6BA5B72FA587F000CA8F06EEA003CD05970652B0F3F92B8BD4AA1570B02CAB21D2BD0A9937A499943CE285B32706589C11CB662461444629F5C755B4A09805DD5659127BDCF5466270A5CB6328FDD0583E701AA98D34095506284B63A6F7B39D0B31FEDC43E20E4BCB39B99D82515E041627FC5402290BE758A062822C26B750463141D9DE8793B385F556A3A3F74BD8AB61F69304AC4082E08F2CD05E5BEADE17D2C87B9535A084A6B0547389D08F548030B1DDA0137D170039E082C5583BC83695AFF0898F7E19E54204582989556B924DF35A00C518AB95CBB466B5BA0D8AEF007A8294294870902E74152832365FDB79508B69E45484139B4342DF8C391864B80E807B9DC8DDCD4463FD1A986986B81A62D79AA9565308AC1471F09D09A23F24E4EE5522B00265770674C61348FDB3BFDD539994B20FF22B210162961B56DBA538252610FA607372DB1317497B85307B61D890A62B90E4DD37246763DC6093AF5F4CD0DC20081BA4CE2D6BBDC969580607022C590A1687004B0730AF71C60590D1A6B2A5E51C742D2CBBAA826600055F4811287A062DA1696A22808507AAC327A9194C5C6D49C823557100C158E60B845AF953539A855D217C5A77599B1783F7488AA85F222DF73B837E4B8D1006A8FD6B5B06083690B34B6586039100E84215EDDB39AD2D40BA9F80165623122A2C5FAF3437AB0376894CE67397D32A67C3BFB9761850C1C68AD988348725C83A378143D504400F995157903B9D04EE43404AB2CC7C35B8E0E09CCE4559945F5640450703F81C35ED332746162F7B8328F78BFC3359E7C1B4FCF06155FC745C70245FFEC09ECA957C8475C62B05BFFF288A5E5A5C78206E48C3EF373658859C3D9636786980578C07B764641D6A87222224557D10436FC72B563883ECB0934E50B6EC89429D7792EC0BFCDA416FC2AC323A58DF3FBCDB6E023140478868055251B1C09FA023E240E109869C1D2967F598A529042D9859F97CCA2E85A635418707B3AA1835B77DF93AE4DC53F228083DE6A04BDF58655C59BF57B107987B88CBC001E010B9C2458BDF138288190F955B62C7013DD5784C809A7B1A29F8C3C33F0311A555306327392DDD44EC8F72FD5893F56F58BAF207F9EE98B7E31092F761C390763A8B57409C7C5C665A913E20C9B62A5E80646364AA8E3B95030FB2FB289991B8637EA57C7B324A25E0389CE979B5E816FF841456261BF042C85DAD84F80D788076B7C69CABB8E389A72657D7D63949657B934A468516C36674194DF1AC3F595A294C28D24C26E1B1B5AF5B542E025A182868E1555442E0B0D064865ED5CC1665074E55AAAD601779E591E1ED2AB07CC551437603D24CA743218FA846822B2857F871FA26834E0422746A6C7DAD256BC0B4BFFF21BD7309482D7669F8857543A0436140EC684C959D26F2F827A84B37534B7AA3BC0A08163689F01141B511E7D11A316D2AA7D73909E889DD000C20E38667DA048278B5EE87188607B4210642F5C38866FAC1549637C600C8BE8C60C11AA394E8344B6C6536E687EF6DABAC397ABF1CA7486F6AE87D8A3DC8070B5687F7C6A73225B9233685C6B703D33677998C24E40A72894193CCA1C5ACBE4A133D85A6912587AD4AD522214974CBB1F877E16164683021EA9C335D41B000CF52A3ED45B2D95B7E2D061B5213DB4C6BC36D76DF5DB9EE6984D31BCB1F6757DE7E51871F1AE7F388C5134956D3286A49BBA39967889C9A424772BF5DAB014C94893A4C8B74AB099687919243C7633CAF297B2B73AB15DF419F6EC22D15A95553831BE379ED0489749C495E3B6B8E190049A8065DBA8933FB21BA3A751CFF289A2E2772B06A4687338CA88C0EEF1488B848AFA1041F4F9607EB18BC0650055803041B728F2F1922CD984D228096FF29E71F097921423CB82254C40A615240A2482A3F5F095F5B399A8F9ADDEB6B726F43E3AF64D09038CAFEA26686CAA2CE2194CBA660EDBB083F92DC2A51142BBC922958C86C62CE7A4B3A4C95240D72244A912C3C193485208CDDC4514495B35863CFC6CB41FA721A78080FD7BA72669AC6B29ACCD3B832D35AD70F7584E197D695B78C832000C1C337FC019F0AAC04B2149A469420C", + "15B2DAF5281DBA5DC3618E0135C043F139CC74B14E7451FC11328F06B73F124766403541131D94506628C30B7BA68564179FAED9C9D2A20F3B61793A33A65E92B699A47FDE974EECBACE22690273A757DA903A886778002D283A819CB1EA2D34B8462DCAB57C85653E363629D9270738434AB1BB46BB71890031FFECAF8FC027D2DFA2A4AD271DD702F055836F40CA137E5D0EF9C8D853E65B5B118E28B7CB6F0D5D6F282E0EA20FD72F3690A6B232B20A8A55EC6CEB14F7662BE0C42779459F69A145C0E2CE9F0BD9A0CD1BF32ED5694CC9AE32\nct = 1F5D4D55EDE2DD05BE7F87C0FADDE30550A5D90923B7BA8E773B5EA78DD3770B9CAC323D98A6E08C19BD600C830E2C2FEFFCE4DAC32376EDA9248E0CBBA9FA0EF6656DD0CA9B3797992C92869164EFE226FED579384121C0FA2B417D5A9F1EEC78ADE19AD9942730593C9AD039EA26883991A02B93F7459EF9D461D5D4894EBCB31025F095F1B6BCC6153D5A998B50BEC88D447A8FF33224D2BA9E9A58D2299EC6D3735096CA81244B315CFD39DB3B85FC718AFF5954B017724B3C6BA3F6780D87E637B0EFCA63C4523099016F78F2DF9BFAF6B0DFAC64332F1C5CFA54A646000F00196FF0686F0BE1728F6407EEAADA48F9E7A6946815527972C9B661A7CE051E76F3B6767DBB186AC7B923BC7284F2840F7B321873B2E46206489771533324248CADD5ABED7AFBCCB43FE0AF06F2C6D6F867B189522261A2A7F042679E8C9E15AFF58FF305D6FA288B1471F46AC82F664012E1C1375DA9A100AC4FCD9D093F191FDF8B12088897B2D8E9E0CC9A986A458751717FEB6438DE9186CCA6B8D361A29D2FA7742DE825ED2FDE97A021087D2DEBA129EAFAF10F370C2833C80818B26E062DD34CB9A4B23377F79C20AAC87C9F93F7B7AB25F74AC0FE18F092E1BF6E43A82ED4C456682F11DD7CF5B41E94FBBAED42A1EC9432E36514214C6600B053A0C9DA4F99587267755E95C3B45BAAB7FBC3570A2749A2533E9DCC2BFD4AC1D477D585BDDBC1F44626E40A3B2678ECA64316CB6B9FCF232BB26D988B3EEA81E9568BA4868FF8DD72D457513552F6C25C5C5C605401922DE6DC878688CC6762B3904B7AB8F06BD64F239CC5103863A7D066570235F53D4811361AC876A15770755F9834B7D49C831D97C5602BFD14B9EA2B37DFCAA87E9FF0F7EFF68933C5CC9D8E5A5DBB5ABF8B7B7239D384DD2C3A500AE16C50511F3B464F07A1DE801EC034C3533E55FC94398DEB4E9E6099EB40A75548EB34DD62201D39057D2D3AF3EE71EBF3458267672DA7650CCCEC7D34F8D53B3B63C4BEC77DF151483331A461C724320F4B8C14F0BD96E0B932A39D41DFDC8D256F213DEB9DFA7A9C2B43FC15D807B3F4062D0C1C80FA96EBC28C0F4ADA8E47750AED8089AF233686E9AA2463DAF738CF0E754ED0CE169A1C7B99396BF71C61C81C924066045481A88A2995D0578786CF787ACC37287795CE12A14C7E128556ED72EBF3C25C60F8A4909233EFAC38BA1068E81CCFD3236372565985C41909CF5E40A8962569B361A026B2A5F5AD411E6AFB36A536920C977DB512AC027E1C240A0AA0A0176FC61334C5FDD25099164227D3D4755045EA9414D3D199A16A8C4D9E6DDB25B187928E7037E6E42F895AA598A9CC3F04B1BFD9E8122D1A6F4D8076ADE9F9C33EE2B9AAFC78B685FCBEB2C0B39B84C5B12D0AC4DDD3421F8D20FE77540A78816D364658B49B7161DF6B87D3D7D7F4FC26FA13EFE503C1A50D3EF67B9E367B4EACB81082E3A29C29E708F988D888A80FEDBC9ED2B2ECD1DA8378DA262113FE18A9EF88B8636862D9A92542\nss = E412F3AAC1C0284D999D5A7F8344B4053D10965FCBE1638F7EF666EF29C521D2\n\ncount = 84\nseed = D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8\ngenerateEntropy = 9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714\nencapEntropyPreHash = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42\npk = 44BB530C48419ABC7578B33D6DB56C76179E9DA3808BA4C8D7C227BA5C64AFD5C87E01C1AD12A294758F45804719DC7369950E9E6398BFCB60A7819585A689462346AA5968DFA83BBB3B8A51BB59311C9D100A4A0C7586056201FFC3CBD92C3A42D6851EC064A89227B4D1551CA7AF6B5B3E892B4E44571669412E4240A08C42551DCC50086389F9E0C0290956B5AC58844A84BE308D0A5562B57B5CBC594CEAE87910A13167F27CE63B822F201AF5E9C33BCA746BA7C5E8541FFF17324228321C7A0EC976646A6B5615F80FB56351D319B31960AA8823426682A610652652994D4A78C25659B533F5B40E6236A6E704CD891502E9C2D1858CA64C94D3734AC0BBCAB2DB2F9E03450E721A38C82A4C26A487F006E1966FBF8063AB115E74F441837506559BA5B7266F62B17E4D959209B657193689A0354149880D08434FBC282713118D9DAA89C52186EA918CE2C170D8380E45A32E9F710CD6F89DAF91C9210B767D743F61655A9702051D7C8A46F17A681B136C0863CB62430D084D282099D1636C04D6B1EC212A74046D2D8108470123DD751DB685A1A1FB3A3B2C216F51302FA13AD73B919A439D424A4AD9E12994D1963B3C0E0316739CE50A1A7C23D65ACEA61423A5792321A84AD2E1B3F5B595F11637EACA77FC753260E04CEC9CCF55D70D4D567BB78749EFD005C9525F6E921F0630C25CB9A129781B9B864B7556272D5B4164E340D9464BF192979A073384F6A5E52AA0B6B74D43FAA5412C5914524974161AFCD91660705659DCA87BA482D67C8C1400B069E66A19905B331243701AC8261952C5B736B25290235669FBDCC254631294FA2E97C440D97A0211C35C2FF4B6009AA66E27CC09BC09307C7B3794A5D189892EA60B2B323E95057FF355114AB48613E2760E00BAEB82B0A763067E216AAB899E7CA06E195A5E92486CE8911BFD5C7D956318AC3B029436A9D88C56AAE2A3DC7B382F2C5E7265A037A827761447FC59A40A3C8693BC996CA786FA7AC1BBCC6AA404A1BFDB3D227C6ABE42CFC463C2F1542AE418CF4B38CC2C1595F9343D41B4A1967C7C94A7A0AE91CEC8235705805AF096CBEFD0CAD6DC0BB5130907D64E76E4BE957A117D121D66071598112EA7D02B9648CF53E57AF9E7CC3C9803AAB327D87C53E41CB9BBC42368D332E0A963C3385C18936AD7483A5F4292B625C844C2282F25AF0C86984DDC09371AB555D57DE146664FAAB59DFA514F8BB8D397A987BBC8DBE147EFC2A34DAAA712BAA1E36C9C5113A7F47BA8C4A83DB2DC79AE93688AF7C480DC8ADF0B12D7F5453E669BE2D805DD6961454BA8B40C6EFA961E53DA19EEA2243C998B504C8AB9EAA2DB11B2F9B591990040954A1567074E69154AD6E618D0830D3B554FE4C99F48B51CF6609952CC9693ACAB000C335B98126B4B45A9F317F80A6049558FE9D855A026AEFDC649D295387C530E075CCB32AAA202171C6F6907A4A2202A9C5FCF252D98328F12F927E31C596047140AF9B177E0352B120954D00529A07D6B2BCE5026A6D7CBA01231A85BA39B1692694788C9215B69FCD111FDC8934A1BA24CC7890EB479AEF01FF29161B0A7AD921BB72A8B495FFA74C62C880BF03F0BC175EB865A17ECB56E0AEA501BEF8E12D3025185BA4CF8EDD1B0F297471D58C26516\nsk = 7934A9FABC835BF9A77BB807332251DAA00876E5500D2C59F07485ED01BC934911A336ACDE5527DD166476CA1D1AA558CD88CD7BD17CE1791958E851991867C0525C9472A953C8B04A730E2E132C6C26811CB86F3234229F4CAA2AEACD2E3C840E97B8F1805B94D7317B08354BCAB64887A4E6A98FFD90A7544562CEABBCCE6489C6E8534119C9589C405D7A96DE3230094A459549B6F37078F2C01FC9080F049464B0A969EB742419147C8B39B8065A769D400A17BB25DE51A699B69D54BA460D33AC6A6965916829B7A578D0B24BFF786CEF9963BF961ADCC20F9A0CB1C159865A344A0E36879C67852DF50ACA08A46E72A4A70C027CE283DE5BCB219808F2635BD7540915C5485AB70358CB017882B12ACB4426B22B02605873F2BD0DA59A658075136CBE15418CCA0A11386AAD43A52E3C5AC97F36BC7F648808C260643C325CF456E6166EEEC74EE8476AD62C73D7D334AC279D84B66B6C8AAC217A813DBB3DC6007317A165E6A1657D0277C1E683BECCC956D973C7624E959724FF9275C1AA2BB5ACA75159721B8C6D7B299C7ACB4704C654335982E83AB3724CCAB3709D20601C2A943D5BFBB3D384A7E83A7793905301B1704CF49992077B19F0204F3394717C9AB9A173113004FD325EDB797A30155D0D2A1E4984644F245F5B495B56A98FDC487B29B4A5C6DC4E3047A8DA2C9325F1705613705628458BD525FB333087CB4B967A61A994CBEFC504D18C1B8A62898AF32BC454A57E264722897D5DC71E32C2495CA857E1A234AE61C77083BA9B780342D7CFDFF8B7EC1257B79CAD017113A3238510C5683C3A8C396986ED392B0122C16E34A7249691EA7A931C44087FA1731746C1F3855BC72414FE3484D85B5E2586B6231B4BCF27831EA7B57070A815795F43E90B2112B235F5959EA253DB76192BCB11D4E16399D40C5DC0A15D98C3B3B0289F07839F7738ABA3281D45AA0A9CA1D349A64E79246C2C7770227F1E1CC74DB8AB7EA7B0E60A9DC0E45443B30CA656CD6A8897AB105BDA51B02179936F04374554A52992710F2A70972479462A2859736C2FE4359A474939AC3531B2905F90BC38860B5615ABFB1A1327814C01048BB93C9725C7C3B0547921975766A97E29D529E4D8A090C36820DB0FEC33277CC679CD4A51F7CA05F204BFF20ACF63EC403AC7CCAB951A8EC166C545ABFCE8734833274F724E77E68137967DA75515E3C270CE79838839721BF3A14C952085071D6B3A555CE62D96E7736A583F44F726AEB921CAA340D4BB788D63645DEB2621629DFF8A2C51D23BFEE95CAA7756F1884A0CD263039C37F7415E83D4908507C1B17A7308CB329D829C86953422B8B2F1786A4B86B980751255339258572A02AB22AD845632F859EAC223E1245AC3533D359246316A3CC1AC58B4E6386592859547171CE05DD7A76BF8E93901EB7F40114175AC45E0B35109AC57BE844C52D31A7BA60A24F30EF0E45581242C02E020EC86AF106836B3DBA8071BB8E8574FDF208100982E55F4B0DCA72521440A2AEA68C57B2039D14B21A56274972ECCAC7EED41C4B26CBE2C973507F1CDF4E618077406CCD3C8C5118545178351522485730B1A1CA7971B01766B914E835244BB530C48419ABC7578B33D6DB56C76179E9DA3808BA4C8D7C227BA5C64AFD5C87E01C1AD12A294758F45804719DC7369950E9E6398BFCB60A7819585A689462346AA5968DFA83BBB3B8A51BB59311C9D100A4A0C7586056201FFC3CBD92C3A42D6851EC064A89227B4D1551CA7AF6B5B3E892B4E44571669412E4240A08C42551DCC50086389F9E0C0290956B5AC58844A84BE308D0A5562B57B5CBC594CEAE87910A13167F27CE63B822F201AF5E9C33BCA746BA7C5E8541FFF17324228321C7A0EC976646A6B5615F80FB56351D319B31960AA8823426682A610652652994D4A78C25659B533F5B40E6236A6E704CD", + "891502E9C2D1858CA64C94D3734AC0BBCAB2DB2F9E03450E721A38C82A4C26A487F006E1966FBF8063AB115E74F441837506559BA5B7266F62B17E4D959209B657193689A0354149880D08434FBC282713118D9DAA89C52186EA918CE2C170D8380E45A32E9F710CD6F89DAF91C9210B767D743F61655A9702051D7C8A46F17A681B136C0863CB62430D084D282099D1636C04D6B1EC212A74046D2D8108470123DD751DB685A1A1FB3A3B2C216F51302FA13AD73B919A439D424A4AD9E12994D1963B3C0E0316739CE50A1A7C23D65ACEA61423A5792321A84AD2E1B3F5B595F11637EACA77FC753260E04CEC9CCF55D70D4D567BB78749EFD005C9525F6E921F0630C25CB9A129781B9B864B7556272D5B4164E340D9464BF192979A073384F6A5E52AA0B6B74D43FAA5412C5914524974161AFCD91660705659DCA87BA482D67C8C1400B069E66A19905B331243701AC8261952C5B736B25290235669FBDCC254631294FA2E97C440D97A0211C35C2FF4B6009AA66E27CC09BC09307C7B3794A5D189892EA60B2B323E95057FF355114AB48613E2760E00BAEB82B0A763067E216AAB899E7CA06E195A5E92486CE8911BFD5C7D956318AC3B029436A9D88C56AAE2A3DC7B382F2C5E7265A037A827761447FC59A40A3C8693BC996CA786FA7AC1BBCC6AA404A1BFDB3D227C6ABE42CFC463C2F1542AE418CF4B38CC2C1595F9343D41B4A1967C7C94A7A0AE91CEC8235705805AF096CBEFD0CAD6DC0BB5130907D64E76E4BE957A117D121D66071598112EA7D02B9648CF53E57AF9E7CC3C9803AAB327D87C53E41CB9BBC42368D332E0A963C3385C18936AD7483A5F4292B625C844C2282F25AF0C86984DDC09371AB555D57DE146664FAAB59DFA514F8BB8D397A987BBC8DBE147EFC2A34DAAA712BAA1E36C9C5113A7F47BA8C4A83DB2DC79AE93688AF7C480DC8ADF0B12D7F5453E669BE2D805DD6961454BA8B40C6EFA961E53DA19EEA2243C998B504C8AB9EAA2DB11B2F9B591990040954A1567074E69154AD6E618D0830D3B554FE4C99F48B51CF6609952CC9693ACAB000C335B98126B4B45A9F317F80A6049558FE9D855A026AEFDC649D295387C530E075CCB32AAA202171C6F6907A4A2202A9C5FCF252D98328F12F927E31C596047140AF9B177E0352B120954D00529A07D6B2BCE5026A6D7CBA01231A85BA39B1692694788C9215B69FCD111FDC8934A1BA24CC7890EB479AEF01FF29161B0A7AD921BB72A8B495FFA74C62C880BF03F0BC175EB865A17ECB56E0AEA501BEF8E12D3025185BA4CF8EDD1B0F297471D58C26516F69BD52CB1D071F1CC7720F949D44F66F40C917EB30F3A4B0EB519ECAD2D03DCFAEB2EF44D2F608621E831187CE79B2D2F4A20F1568BBE76B0D3D5AF36111714\nct = 55B89334DD971C479417D6D70BAA960E1BDF4ADF3DA2D9D2AB18113F740E0558502F016B99254163B21199E2BDFFC897FB3B1022B53B9BFA61C200C0F071BB74507BD0BECB61EA9E4D9F860D376F3D9D23D3EEA50FE0BE1CE6C40B27323C17EE5E9A9DDA5BDEA6021070927A035D822B44A6D457BC9227E162CB2C27CE543BC19A9B3437613C037AE5103B5082F7BA35EDAE372FA5965D00EF8E6CAF2E856B4F0F57995512328203D9524BA18E1912EEEA55DB3E1CA0B8F0AD957E04D009E71CED4F0767BCA4CC3673C33BB0A06AD8C0536EA5B6DD0C093339A0324623F5D4C007F23F0562D505B2737F9482D41B2C293D31B2E9BC5EC86FA8A140E2D1FEAE33FA5E7636C94783F61CB0068CB7AC71DBD06FE2BB6A58010A391B1DEDBEBD34093F6F8DFB6977B1B709C895BD0F2A8D8A39AA9DC3CFC8E8D522BB9EDB8555F06CC418E68F4BFE6E449B069573AE3506D8D8E8167F0B25AFCD48F018E03762AA85B2474C6AEE304ACF649EED0E9688D6C62ABD8638590C74E0359881CD0ED9204777955B6135DE3A777074BE90669DCB9400AC25D55E022A9362224BFB9A830E237113ED56B89898957854161EF6771E58B6A1A7947A381216CE20A97451555D3D2CB902E69BC762651412EF5852C823B1A8DC477426DB5A9DBA4818B76B40E59C8267CC26CB28E2E050502D8506E9511FF57A5A732082170FB25907B272136485D4EB8F2767332E1156B4C7A54F567957CBF0530F7293F61736F44A31FA94B1B6EBF7D79E2A87493C2B5FFDF03DEADE92C1983DF596E16439B6B0DEC17CD95D600748EE2074A219E43F06FF7B93124DAEB91A2ECE0D684559D8A820B4FB35C1B647065EFC0C98EF4A38DE1927C499178F4DE44F74F1849D057FF153571D5ADE12845E0C61E35171DB6C63EBCD9C8269458A3A1C5CB26C20EFB664E79306C841DCCD240A2ECC86F69C00FAC5332CFA28D874847E1A8A3AB531324BF13377D7ACE16DF5B960B1EBEA092A40F5E1B09BA3BF56807FF9037A1BA0C903A7A1BE491D7B27A78A10FEB3A3030280766EC0A75FAE99BD4CF2CA5BE940D45064B0215628C09E4D6FFCFCF7B1B69B1C05A82838FF64C414E66FE6F2816DDCB90887EA23A9F0DE07F7509F005800E2202C63C1B241DD470B48AC484786AEA204AAB301B15F0B647A5776491A7857AF5DE8EE4D77E6B84C1697663A72F28934F5ED40EE72419E7700E18DE42C0365BA0D5F55FD644A874ED0C047D198D379AAC2D60B233A3D8F97F336A7685371DCD1849996157FD921DC42D2A63755B82F4B776912C27837E2AC17C24485E08F7BAC7FEBE512FF7A92F8ABFB262BD53F887D54E77861ECAC9E14D68E27E211EC53DFF507295A0D82B58E2E8E00CE698FB0199D5D7F9F200D876090613D6ADC34A08ED46B55303917373464E5C7DA621E73738DAA1D3CE09DA22B98B48ECF37F8A0D4A44A3E8B086B2F7FA078CC5714F3CD296508DAAEBDBFA565D3ED8010816F4DE58FB4B25DA0A25161A91A38CC42287DEBBF8C30F28B288C\nss = 4F9DE6E4CBD9948D2DE9250654D5DB97FFE24CF222F68BA51D6261F02F4DC5E7\n\ncount = 85\nseed = FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792\ngenerateEntropy = 6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b\nencapEntropyPreHash = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13\npk = 9EB92FFF176A27197EB4AB0171211DC7FA954C652698C50105B5C2E9F7A2A887BFB40880F8624E1FC67B1B43A51139AC6025B9EEB60925D424BB82C58B4B617618C43C99B07FB14E5B86538D29700E1CCB4F53A52BDA2EF566B20D8CCE1D7616DC81398D14ABD03964940C794E6100DA994D5BC0BCF28B04A8971214E7AB9285515EF09A7B486ECAE5C84655C9EE15255B715C3B784D9C243993171C604A3E29450728396E7572228610BB9AC04B06577B3636C137A24E2139B48DB005553152C6B040CF0B2408248675EB90AFB66D6105537A316C7C989746F43C3B284342E2CDB5F2183A16CE71AB39C67797112B0B907C00F6A47F17DB08D924826D526CF88234A25676D82449F93B2859076978860E499A0DE134A936E35F06A7802456008C23970818318AA2B55A1762A9394DDA7A49EBB4B38469410F5945DBA2801AC25BA39A2DF819B0DB194B53C4247FA5065FF99F73E71D51C22F51FC262DD2809EBCC6879B0D90004DA5BA7CC9462F6C822AC8FAC8AB95B769A465CD743BA2BABB26958AB9C3494D329A0C736C28A9CF84F5C90C5A0594485A9B339212D01BF6910105D44109B09BD063B4F2F3B903C94DC650812AE5CC87527754D476FFA82F34F39B5462006029875712CFB1DA648DABACE5AA1590B5CCEA82C20E74795C71BB70826EF4D0BBA580A447693A42D8AF3256C64CE327B370CE576B6343F2BF8FECC76E1434D5E448AA8A3B326584DDC56496704BE54108F8572170C2BC39680598017641422BB81645959B8092E82A54C68AFF60B78BE78107E7BCACB241B09913461579B52AAC5C6C8627CC033BE2273580A523D4CB7979CB65D7056643856BE187DDAC112799559A87168AA96A18089A6C547E87DA949C62B8EA876AA0192AF409BFBC354F05DC08FED46904A2688FBA59FB71B83031A19BC8A6350BBA93552BE0C01B73C89964563FE588A5B76971DACBA69868B588BB2F9076532D6A8FB4316DDA4C85C2945A2A29B6EAD3900E50ABEF2B44375AC36BCB0E028A20CCE58353C827F1D53A9A0510E3827CBD1383A6D18C0D22C374E2B6061C2197A6CB094CA9DCB42F0418C24A9CB893C45423447CD5EABB0B9B410C9144013543E5C3BAD525377CE8073D4A5F4A22BB24874B7E21523CCA731265572B487E3B42AE581A617437348C290F00AD09460AA0C7B6A1A53128E4E01B3C406A296CB35CA0BD0D1917DFF42A4848AB3BC28A2A28044C719CCAAC45C513CA007653BC854DBDB79181157AA17220153CA3563B21BE77ACEAE06BCD02531FF5B7F5453DB0119364DC4E97AC7A495287815B5EB512129643AAC4F42B3AF35AFC1207DB0A3194302FEF097BAE37BF382C154E78154B3407BBD90BB2143BC285AF1EA0B1B4FBCD3EA373A077C6107AC2800C89F20544CB7A83BAF26EF19367724B1C989C39BCB4337DEABF7D531FE2B3327F4AB0F6457C5F3869590C49664923993CB2B0103B8E8A41CC5793ACD192A047972978A2EA1B9E354CB135F2AD8928574B2C14FBC1A4C02715292C9052B69AB2A8329C02938BFA0994C209F816A24EB13F4365AF2D20240EF66F9BF6B39D54AB5D350C7CB3CD6F645379815AA3028232BC89BB89BFA2C62E351A3C6401B7B384EC61A83F9056F3665E523A0C28D48E778B0314C1EC2A83EE9805D0\nsk = 46F47850E2B9AA4A6D209125BE58806002C278A6295DA7A4FFE85551529F17D83B358B243F2A622F353EB6138CC6380F8AD3340D7575E865A6CFD34BF473A3DA8B9FC961CD921452D09B3209D041D6612576C573B08422715160B891A3370268468078F5464D7E5B84B3A3793F0C7CB2A0A13DF37B9763CFBF054C768B1E65A00E8366B406251F812C5D428853D0E00F7BD58A8E348275461C1336C2AC6A39783A35D849AA9A847F37F50BE0B95F617BC7ADB28C0506C16EA3CE89AAA28A9252F0E228D0FCA732289D05D9395133A82D8CB76DB2023924273B39CB52B5A846F338B96C5B6F3ACB41C7265A0C5B13094231F05943D58875BA7C2A6889F16107D325AD1B810A0B3C9E8928169D440194BBB90F771796856F9878158A432EFF742FBFD5ACAF59521E361F448C0BEBD805A1B4435D0761D0448D83E1201A506A0B0A4980172D05E88D7D87B42054680CDA74A386027AA4C3C5193FB1A893BEC2722D55AB9B840D99CC81408153B383345192649EB99825BB4B1957326C4791A2722951C0AB67472F4841C20C23926C3C331F24C360E81977C2791FF3171C2C489B68C923B65D8EE6BD2D510E6AE97FB771BAB401BC1A42935F38A0FD43AE2F8A24D8FC3F6E15C2C6BC800B73CCD8E91C592452484B44E6B2A624881064526182950349C78C7D58180B1676B5191EB6065C50596232B9566E4B8F0635A7D71927F8EB8572E62D57996DDF66CFED2147DC3451E95C034D6B9145BC0D30C915D66B1CCE367406212F8BB40755091C9CB0306A490EF5336E21F82C1B7B6CCC8980DA28A348815112F00C57362EB163A36E016D60F020BD12B679", + "6C9A88A8AF4E833FC4585652E76F2FF77DEED799757C7F64E07EE6E6A300DD1CBBC840AF561746D279BEAA71DEA5318AA3CB3C4C63C4A91E0FB60D6DD6ABF1FB24D1B078DE9413F1B0BFD8916577C4CC9E0B0C332625A5FB705E94BABBE0659E022234586529A194012A6E9E7650C504C380436E1DF83E5C5C9E22F79F394BC0F22A0ACF114B90829B43112FDD617089C8B9D872B70D7027D74402B65058347B56074BA33FB91998E5A559D46622F5423808C8236317767A32E4772AE66CA472EC7828D682D045835EBC5E0089B0FF955DCFB9605214A3E5087F7EE57D5369ABCFF1BE00C7BBC5B5B25A0C1D853424123C98FB330318432D324BBC7330342224BAFF909849D65E1D08A77E07D07CF16CE6F64FC71374EEFB66BF9C742E518F2E30C480F82652B81C4CE7BF42593B990980D94062F96A7178258F31E2B90E86241C04B7B44057BF4700A040B6C0B08E4E8A6BF1CB1EEF738F51CA9BEB9C19B94B1CC623704A6C2455009F48B4CDD0F4A5D7F06320457670DB92C7A4371743593600022DA4600C56296D336A52E98888818CA10282D4767010A7ABDF81BB6752048B5B163DA385D7C5CB134108ECB03398500C1612A1BD563B21A0BC7B94C9719A75BF3B3E02143BF04A7E3D9B0070C4B449CB9594A1A8BBF871E595178BBCB611B466A8677905443ABFA1601A9664C5F54F36DCC1DDF35381F586B4AA4566C02BE610186DF8493A30479F4C72AAF049A6666E806B13FD77C3B738721F81218B48984EF374BABC0156F94E9EB92FFF176A27197EB4AB0171211DC7FA954C652698C50105B5C2E9F7A2A887BFB40880F8624E1FC67B1B43A51139AC6025B9EEB60925D424BB82C58B4B617618C43C99B07FB14E5B86538D29700E1CCB4F53A52BDA2EF566B20D8CCE1D7616DC81398D14ABD03964940C794E6100DA994D5BC0BCF28B04A8971214E7AB9285515EF09A7B486ECAE5C84655C9EE15255B715C3B784D9C243993171C604A3E29450728396E7572228610BB9AC04B06577B3636C137A24E2139B48DB005553152C6B040CF0B2408248675EB90AFB66D6105537A316C7C989746F43C3B284342E2CDB5F2183A16CE71AB39C67797112B0B907C00F6A47F17DB08D924826D526CF88234A25676D82449F93B2859076978860E499A0DE134A936E35F06A7802456008C23970818318AA2B55A1762A9394DDA7A49EBB4B38469410F5945DBA2801AC25BA39A2DF819B0DB194B53C4247FA5065FF99F73E71D51C22F51FC262DD2809EBCC6879B0D90004DA5BA7CC9462F6C822AC8FAC8AB95B769A465CD743BA2BABB26958AB9C3494D329A0C736C28A9CF84F5C90C5A0594485A9B339212D01BF6910105D44109B09BD063B4F2F3B903C94DC650812AE5CC87527754D476FFA82F34F39B5462006029875712CFB1DA648DABACE5AA1590B5CCEA82C20E74795C71BB70826EF4D0BBA580A447693A42D8AF3256C64CE327B370CE576B6343F2BF8FECC76E1434D5E448AA8A3B326584DDC56496704BE54108F8572170C2BC39680598017641422BB81645959B8092E82A54C68AFF60B78BE78107E7BCACB241B09913461579B52AAC5C6C8627CC033BE2273580A523D4CB7979CB65D7056643856BE187DDAC112799559A87168AA96A18089A6C547E87DA949C62B8EA876AA0192AF409BFBC354F05DC08FED46904A2688FBA59FB71B83031A19BC8A6350BBA93552BE0C01B73C89964563FE588A5B76971DACBA69868B588BB2F9076532D6A8FB4316DDA4C85C2945A2A29B6EAD3900E50ABEF2B44375AC36BCB0E028A20CCE58353C827F1D53A9A0510E3827CBD1383A6D18C0D22C374E2B6061C2197A6CB094CA9DCB42F0418C24A9CB893C45423447CD5EABB0B9B410C9144013543E5C3BAD525377CE8073D4A5F4A22BB24874B7E21523CCA731265572B487E3B42AE581A617437348C290F00AD09460AA0C7B6A1A53128E4E01B3C406A296CB35CA0BD0D1917DFF42A4848AB3BC28A2A28044C719CCAAC45C513CA007653BC854DBDB79181157AA17220153CA3563B21BE77ACEAE06BCD02531FF5B7F5453DB0119364DC4E97AC7A495287815B5EB512129643AAC4F42B3AF35AFC1207DB0A3194302FEF097BAE37BF382C154E78154B3407BBD90BB2143BC285AF1EA0B1B4FBCD3EA373A077C6107AC2800C89F20544CB7A83BAF26EF19367724B1C989C39BCB4337DEABF7D531FE2B3327F4AB0F6457C5F3869590C49664923993CB2B0103B8E8A41CC5793ACD192A047972978A2EA1B9E354CB135F2AD8928574B2C14FBC1A4C02715292C9052B69AB2A8329C02938BFA0994C209F816A24EB13F4365AF2D20240EF66F9BF6B39D54AB5D350C7CB3CD6F645379815AA3028232BC89BB89BFA2C62E351A3C6401B7B384EC61A83F9056F3665E523A0C28D48E778B0314C1EC2A83EE9805D010E01965F9C196D2F5F90CE3CE8F552F8A0D76BA8F5345365392FEBC50560012A2985C1C4D203778597947D710DEC806E36B0CD949FE460EF141213BFC525E5B\nct = A94180C718B23E998B15D6104564B5E20E1D102DA4EFAD7A9740C473EF19F3DB7B226847DE6CB72BE56BEEE3E1BD44D0AFE0A4B55498B4475D8D936D441566CC182E0264F93A6024CF478E3658CD02DAC2C21CB6DE61F8EE7983FB6D79CEE0CC5B134E6887B4C4F79C635533A19BC8819BA2A56715825BA29836CBFC51479CB2C2EF8B0B50332DDB523008F6AD3B5EBA02C767ADAAB5D930760EB496D4C3EDD90BBB24B9CE0DC76013791565D368641F2B8F25A8660810F48E3A12F65BDAD160F3605E2D573844432509E598B3FEE53FDD4A9B83C1B187B66F5E9F2111062E74A3A7E006D638E3DD4990947E0AD370B0F29E183A7FE376C00D8A0713B02D7E1CD8132B7AFAA3FADBF7CEA991B3D9A96EF80A75010C40FA3A31153F15E23446A9491304170E2432112B84F86714A9CAC0F8B60391734EE6A94EF6DEFD30A02079DCD29D938387669A0A3893597AE4F036E1D7020F132B1AF3C8F135033D224CAA5F2791D9943C067257389DCBDFE8544981D6C1C3D5DAD7FD953372FC8910A16BCE4865DEFBDB413CEB80F13374C9D83B54B201C7F4345C97B51D22B33DBFAE34535D9F7F2AECA05D2066B2E9CA9F3C4F7D3DF5FCD1B1153B35418B7C7BC318A9E0810E2328065317F50D5239088AB28724642428CFDDD933032A72D95CAAB610AFA65C968E5381BDF0C7892D3E0696CB75BF1ABE5A14ACEE27CB73CABC5BB23A1AD12EF4D4E917EC4E13B736D1DD50C68B7AB98D8CB2E1EF75E3C1AD1DB7355B484B6AE44B5B7F963B772ABBC5B0ACF47D158853F65CEB9C8829B70481F6D531F59703F7233205806A91061E45FDF6B9EE5546CEBF701CF54BC0805FECDF48804E95956AB9041898AA623FF5C6D3D6F45EC370680F43F138FB6E36018B5D92858A29A17621D9B844F513AF8C021CAFE10687B180D7CBD9FE1B0880B6857947C55C40488F3046E76FC8A00BC4F9DA531A036AB71174AFEF52B3FB4686FA471C34DDFA2F1740A88BE223B536C4325B9CAE46E0B0479CD4CDFA0FBF05F0718052AE62486461D423E4AB819114110FC48A676BB83F3CBEEAAA474C4066CA54DE523DBABBB29DDC39BE50898077649925042F28D15C4C95BB6E745E5367242DC7650E45DD9AD2A5769930099BA2C0F20994D304EEACF8FB3C86EFBA0036D82C8E9ABB01C1F3260EF78D7AFE632261B0012EB612F8A98950018FB12AF3AA0524FAA597DB80873D2FBFED5637098CECD7B2CE5C32A51AC967F277470FEC875E7C00B895AF511D17731519439498A51940733A891E8A2DB137B06E425BB07D0D9D84A6FA70E26F09D61C8800AB74357AECA7BB223F324B9E18A2EB4C0AA1D996543AACE1882726BE7283C0220DC74EC51B6CB82755FA14AA487563053C773A6BAB1547265FDBF4DD4C5738271B410031128A23D2E25289758F4F1C0AEA20C2D30AD81DAAA919B30E268B1A44072A66B0846A436B72BB9FB2A8ED78B551257030DFE5C13B116B8EB577804CC0375872FD0622D96C6EEFB72BAF82B6429C8D7BB0D0098C6D\nss = DA6373247F33971B39D955418425EF1D1A233FAE7FB1985C0126F541AB8D58D7\n\ncount = 86\nseed = 1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35\ngenerateEntropy = 6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102\nencapEntropyPreHash = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba\npk = 5C405485D51FB10CB0F150B9DB466C53E070F5849049D225047BC47AA15F630A6D62C5B179906EE6C067FA3384A4C22748F984EB31AB4CD69083DA31A5B45F586560371BC99113C44D05828FA7687AA649B261BEB0EB4EEBCB8548139BBD6A0A844CA1E4E59F3D7C4372EA8632B278A7E68B59032012C5518A8021BD5367557077C9C1B4A50944EA1A834BB61004B2CBA7F6401A57839A3CB85B326449A25457851B4A2BBA2E2187F040745FB608079C8B59D2B191813D51C5C3F329B1F5E40771E1B33F63CA400555CE5351CFFCA2DDD268D7855151618587C8B037E7CA290467E4A7C2C38290B84AB8DC4A839F57102DD559114092165B13B130B41BEA2F857C84AE45C1734375A3EA91021014D29AC58F12BD5A44B91CE986E094A66089479DCAC23A6275B864195DF24F2D4A97F1B26B508C3A5BB89B9F0A913867C1294C252D5022D9FC60FFEB3FF3C29B2DD1AA97F22271C5C8E749CACEA39F2C637FF4A235882747CECA1D95E093966462AD401510EC112026BF0FBC106270988B2C35CC7269DA693A7D67052F9156D30C916AD6552EACAA3AC2396BC56668686EA8A1578E46658A71B4B7365AE56A263C783973C1B63100B1AFF4C3FEB64856A781334C6E83519E541511B4D581914C697FF31239DAC56662A145316AC4D14E522480782C4EC52B1A2B8A85F657217ED11426A2A606C01C17171FD10824C07042B189225D40919AAC5CBE05B031689B1EA61041F6091D961A8910A205E62FF21909C6B4095B270D87C9727A2B611118C84AAC033EA9CAB5F40EFAD6117F2160A56505FD775D3F415AAE9271A9B2B1FD1964EDFB772A9C4875F06826A49C26E93F0B1846E006468DE71B98AC6FC0F81AB146236739C9A7B6C13952089D621936E8B265B50DD4016547A2ABD52339DAA0B459D265558A1D9B61C73E49346396B6155195C9C3A437614E68E23143F09FD28857AAEA50AA808600F5C5CA33C5963CC00C4B1C1CE2609486AC4F1B2DDB7B06ACB62398A32320F315DABCAF5D4A833E2A01A6E7C971CA15E40C459EF18DB8452AABE1584412B4C4DC52E6004CA56B5F48555041CC828A7A6DA77C435F05574E5C25EFC3C6057443EB77993C987CAC2363C3030D88E288F4D08966E624794078A39C53ECF273DF178CB022A5FB025A2687409A785CD6C019F5761B0A3087AE91844A69C2A89C1A00B1CAEC7C1F7A67425B87BE02D80B67CA6C7DC3B45BF425DFD33DC5A13E7531907ED6329593C333466D9628668B98422C985182F8C0952CBF5052225363398E516D23678B5320A9CCA38E21C6BE86822C4FCBB9094277BCE80992858C5498C6BCC57DB982C196B1A78C317975544FFDF33E57A30DD29A5CA4A22A918746FD9A84EE1008DB920432E39B", + "6FF182C930243CF350C6F486832A807A36C8A9242A5C39140EAA7A45BACE0086A86FE36BE28ACEC756B5E9A47225638659B250C52B564751CE8C42C39BD1046D2B6CDA70B7951707B63073F0EB5EA3FC5229F816EBF4007CE97307C6607B4CA17CA30330570D4F39BF76998147060CC04B33D4B91294F85F4A717EF9C288E3741F70FA5823AB8329F56D9D0B05C996701A050A387362DB09427D5587E7751131953146EA3591818F0DDE74E33983C010419218B08822DA9C3C62EAE1F2284801B3E4\nsk = 8747252C693A0D6C06AB66071B13517E1C45ABB370D26ABA3FB31641A170B365C5F6235D1FD688D81C72716A3921420D228A7BD5A1C48FF445C47489B8116B7CA14D3EA78B20A7B5E579C5681187A2AA8FC900557501003FB9BEAD185BA9E7939F247BF1757EA66A4392095EA90239A3C67A8CA70186047D9A6B06B8887FAE01BA8E556319A003934C88DDEB05F9F3B4964A6545E8443F57383A2BCDAFD96C794B399296615BCB9C59F8703595709724B6A4BCAD06E116F4542C4322072E3C6713015B1339512419B4DAA8C87F5A8BFF481964A8AB8A101943230F9527A10A604DF6275E1EF18FE54A57D7544402134AB77802333897D4769AC23093F9B951D735B5623452C90270A0896ED3A81BF1191E451A4A67A4542556AF78F1690982360FF1BFCFF66386827DF93BCD894AC8C996BE6E0A29DE70CCD459B9DE46ACC9E8043BB82D01C40E5785845FF4B0DDB8184AFC5E52A72E899093669A9EB110A100A1159241BDD40612A9B1955B1752810764E7B68D89704A61442ADF68108AA229E406CD10B6527A39A6B46068685B5E802CC25614492DBB6E06BA2160E930733956E7B29AB9981D4B477CD4EAB880E56EB711B278F540AC204A996B32FD06B8BFCB7729660CF5125FE1626199F6285DA628FAF491DCE2CA3BF285902350D52C0649339F31EA3AB764B90701BD647194FB27383681C13470B8D5CCB61DD74C5F666FFEA7B0714C469C4803107235599C998349B5BE7AB9E9DC6F01E928593939270411EE2490F16C54BA672EE03B710978760B962319BAB3C2FC67CD9C2E9D4C153A8717826BC4C3D6C7444C051A61A06A2C87A1207A20754E9D7725B91077766871509CCC93F5A1FC1C20680263082801F6B81E8F319B92110F2DA22F0D8C251EE4531B127C44B378DA6A0D26F55DE3285190BA1357012E42521CD1855252147D1ABCB1582422F55091B5EAADE93194CFA0BE536343A282C4A948C355984CD20A7CA454BA034AC7355B02730107A71B3986FA01FAA38D17E07494FB510E5526F690BFB27294FBB963A0606E140A182A9A247029ABDFF6BD8E876EC92207312432CC2700EC4C6A4A7037C5B612EEB2099D54872A5884E28981D794C7855590F1F1464017C8724BC92E0B644DE92B5B80A573F641E4E65BD6F0396184086D6A5A50662F9CC6241FB7241D194B6D23AE6FA3C59FE60C81309FF7E39F93F72BCB0696EDC771A80CC5FFC74138AC9D01B95DEFE7258BC555E3E28CAB6A73372337EFA0B4AA0C7D13B312A7313F8B63426C6677407903822AA1ACF4ACF4A130C4C68DD4DC47DD061ED0A4969E5AB630BAA11FA0AA51133C6509C83E603425A385730AA0E07A2BAC0754358C812F483F5CA6BEF3105CCE4CC33532116C6493F19880F693581E08999BE24DB44B84970C8FA4F6784D50614CDC9E626A31966ACF81309EA6A730EB42011663CF10A90A9EC12F3FE133A7D02CFB95CECC6B52CC08571BD03E8315532B7C76C2040B60E9021A24734854B6A3D77CBFD087015410B7322AD5D9B04F651F895AB5BFC25F8CC9703BC67DC5EB5AEDE41682A17FEB1B4339335EFAA44A64E8B4EB0BBE17FB00875A06318C1E68C42E6CE0946A59C61700A72779765C405485D51FB10CB0F150B9DB466C53E070F5849049D225047BC47AA15F630A6D62C5B179906EE6C067FA3384A4C22748F984EB31AB4CD69083DA31A5B45F586560371BC99113C44D05828FA7687AA649B261BEB0EB4EEBCB8548139BBD6A0A844CA1E4E59F3D7C4372EA8632B278A7E68B59032012C5518A8021BD5367557077C9C1B4A50944EA1A834BB61004B2CBA7F6401A57839A3CB85B326449A25457851B4A2BBA2E2187F040745FB608079C8B59D2B191813D51C5C3F329B1F5E40771E1B33F63CA400555CE5351CFFCA2DDD268D7855151618587C8B037E7CA290467E4A7C2C38290B84AB8DC4A839F57102DD559114092165B13B130B41BEA2F857C84AE45C1734375A3EA91021014D29AC58F12BD5A44B91CE986E094A66089479DCAC23A6275B864195DF24F2D4A97F1B26B508C3A5BB89B9F0A913867C1294C252D5022D9FC60FFEB3FF3C29B2DD1AA97F22271C5C8E749CACEA39F2C637FF4A235882747CECA1D95E093966462AD401510EC112026BF0FBC106270988B2C35CC7269DA693A7D67052F9156D30C916AD6552EACAA3AC2396BC56668686EA8A1578E46658A71B4B7365AE56A263C783973C1B63100B1AFF4C3FEB64856A781334C6E83519E541511B4D581914C697FF31239DAC56662A145316AC4D14E522480782C4EC52B1A2B8A85F657217ED11426A2A606C01C17171FD10824C07042B189225D40919AAC5CBE05B031689B1EA61041F6091D961A8910A205E62FF21909C6B4095B270D87C9727A2B611118C84AAC033EA9CAB5F40EFAD6117F2160A56505FD775D3F415AAE9271A9B2B1FD1964EDFB772A9C4875F06826A49C26E93F0B1846E006468DE71B98AC6FC0F81AB146236739C9A7B6C13952089D621936E8B265B50DD4016547A2ABD52339DAA0B459D265558A1D9B61C73E49346396B6155195C9C3A437614E68E23143F09FD28857AAEA50AA808600F5C5CA33C5963CC00C4B1C1CE2609486AC4F1B2DDB7B06ACB62398A32320F315DABCAF5D4A833E2A01A6E7C971CA15E40C459EF18DB8452AABE1584412B4C4DC52E6004CA56B5F48555041CC828A7A6DA77C435F05574E5C25EFC3C6057443EB77993C987CAC2363C3030D88E288F4D08966E624794078A39C53ECF273DF178CB022A5FB025A2687409A785CD6C019F5761B0A3087AE91844A69C2A89C1A00B1CAEC7C1F7A67425B87BE02D80B67CA6C7DC3B45BF425DFD33DC5A13E7531907ED6329593C333466D9628668B98422C985182F8C0952CBF5052225363398E516D23678B5320A9CCA38E21C6BE86822C4FCBB9094277BCE80992858C5498C6BCC57DB982C196B1A78C317975544FFDF33E57A30DD29A5CA4A22A918746FD9A84EE1008DB920432E39B6FF182C930243CF350C6F486832A807A36C8A9242A5C39140EAA7A45BACE0086A86FE36BE28ACEC756B5E9A47225638659B250C52B564751CE8C42C39BD1046D2B6CDA70B7951707B63073F0EB5EA3FC5229F816EBF4007CE97307C6607B4CA17CA30330570D4F39BF76998147060CC04B33D4B91294F85F4A717EF9C288E3741F70FA5823AB8329F56D9D0B05C996701A050A387362DB09427D5587E7751131953146EA3591818F0DDE74E33983C010419218B08822DA9C3C62EAE1F2284801B3E47C3991FA7983D0DD6E7157CFB152538466E9D5C3998A2B8ED862162B91CA851CCE7683F8A03D3CF04E46970FF7D6A12494AE12558346DFC8FD9370BF944A0102\nct = A4DB79E6DA55191F585544DD32928AC432171953F3A57EAF2FD786BF1641EF364CD03DCC519FE94C40AD5D3851A820B90C43EF631F15A48FEF9191281DDA67EF23C6AA3093B26C36A7B6F69A86DC1828498540AE4F6C1FB170387D62EAE9B73313D39D07E94A903BAF6DD09ED3BAF005A9E35C7C87CC6724B37BB80FA2153F150F9C811079D3D545BEF636476FDFCE30DC32561F41FDBA2EF7B4F21C58E1EBC033F5C457FDA302AE3D32FA0BCC4F3CB0897AF041C562D48AF1DA6C9EF4CCB651335A825394544BAF7D8914F0CE818E68D711CCF45B9873E108C48AD3876AE59DB02B553B6581B9A5BE72D31CA4033E4CBB767C1ED34D3356541A113D2CF60ED6BEBE3134F8C0A9BFE30C17E2F18FA8E308BBA726429282C7286D0904BF78925B09CD47973566DFCAAD7DB814A3500181EB93D438159358C075F4CDC270E14D74CBAD91A493F05AFD4C8AD851694676103FA00C156E5EE3CC4B9F3C6762E3E5D5AA4E245568BB730DE5C2E0E32EED4310D9FDFD30C68A67ACA0BB692BD5453BAF3056BB10E031CA15B342E6DA3D891FE40DC17CB6ADCF6B3B72943ADDE54D7B01A5BF3A129DE2846817D7C2D9054158D08117A69D5A7A0DB6ABA4286DA7D76E85AABEFD343BFEE54395B046AA35E3F7F5648C84B5C1B6610406FCEBBC01CE448BC8D533198BED851792582FB421C55C5FBC989983D978AA163CC88E01C12437CE22C58A6B5186DD0652417775500146236E12420DDB24054E607E11180A22687744226CEF0CC55D2CEB94E1C0675CE338F2537A3E60C126A91A81702DD3FE1FB7C2FB310571FA3DADC83DDC4B18B1AA5707E907142311FE4988196EC6B48814AD55A0EE7724BEAC278C7D68229B3F63357D81EF5FC16F2C7EE9E8A8E7FBF7FFF7B958F0592C5E1246C6AB95474DB7183FFD15CCD227DA5DD1A3DB842814AB5D4B515546BBEDACD42E4E9ABBEFA9416AD009BB072B5D691C1ADE296BE26F87FBCD82EDA2C93AE73AD7171D1EF1840F26014D8F152A720C47E24F15209E2A478DD7DB0EDDE040403A0655804720F8643B86F37776A2F7DC6B478D77A87EAC0194693787B6439F4B045732866237A8A2EBF9934070737B89DD2AF08C59BA182EB239FCDC476495AC756FAA7451C719156C1DBE099FA7BAA32C16156F4209C9F2C66544CC54DB33BBE0EDAD660CBC13E69F4D808BA98A7854CEFFBB2CD50A5B727762038A216B8B5E85DD01E138EDF154DCE1DE6E832374F0A0614390F76D1E658277FB909C1E95B4E81A9D6852DAA5368281AB21799C6898C07992BF5F7EED402522449461394C87AF555FADF1932DAB0CAB6CC80AEA73340181E91FD99EEB65A013B42F577D9436C75A7166BBF845EDE506AF88E6B1F915EF43043627CA208435E805D5588F4265346A7DAA1C9EFA72592FC999E84E49E6E0872AEBACAE9ED89BCF98CB40466AD61FEEC016E629527923430C13E8CA8C009EBA5D307D29BFAA6E1E6F56DED592573B75FEFDA3955317126A9B2869608C32701FF0F62447D1369765\nss = 037452D74A46B60F415DAD3498ADBAC608DCABE4EDC7070A358E7325C72CE76F\n\ncount = 87\nseed = AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C\ngenerateEntropy = e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722\nencapEntropyPreHash = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d\npk = 7E395F02D56D41B5C5889BB6B2F149425A2AC8AA06FF23A82841887DE199B56C91846392A026B50E87453F44588EE6AD4A443F54D25ECAE39AAF286EFB47A760DA01B6C13FA178811C47A0DFB14110FC6482543E8A3A52ABEC3A8D7176AA2868B2D46CF68538C27514222A34371C25FE832184206E5ABB699D61426027A942581D0BAB075A367793C81B7FDC11E2F6772C8040D271BE5D07D00B330A6C874B46D26F51DB8F43F22DFCD72613F8C22D15C28A2B384051142C148B07F7362EEA4771959B", + "635A215B1351F650342D2A071ACB16DD8AB50539096F295E44173BCAC20F3CB271A8041E3008A742057EF2FB2D78F8A3A3C252F6D38D8E85BD57A75D45AB4DC21B8033992CAA623866E8989F98560DE33004D3409F233020899340B2591E1A4A0223A79E20B4B85C632CE7609C0C45A0246251468C1B6C20716315A54520C5718F4C5C7066331FC7E953ED91AA5F3B92E69617B29C256657124242AE8305780CC0CAF00C92896929A1648BE9B47F86F144A3B12D9DD51F347875E6DA935F0BD043ABBFDC7B85066A7836D442872C56FDD41D9A3A01D9AC6A12531079F74B273CA129F36A7AE463F6464436E50FA70CBC2756BD25234893B50A2898345E588B819C0955E9C50072517D58B0A3E4BFC9832B727C7F2FA924AC672D4D104A8F3AB81200A624C61EB6AA7B4553AEB2084360F1C03E443AB99ACB63AC699443A638BA9B8013C7ACA95ACEBC9ED6B12E8BE5A6CCC74EFEA7CEFC7A0F5EE18857250D08F03CD94CB4C455141D7AA2FBFCBE3EB896C2404BFA3580BC63B73265581D87618B206CAA9468C65BB1863B18F560413D1B1D392259F37C00F7D89124C56913483513006FEFF89092F218FDCBB8B118B206B64F2DE52BE0B553665C32831BB4CBA3762991716BE65E6A222B30A0A5CB246207352732BC3C8AD7A2C3243C62424AF222A922787F7FE44DF05299DA1105F9EBB0C5AA18B6C6C73F43390AF9C2454442110AAB4AA629C8F300DD38318C43A25D269885F970DDD8AC1E5918E59A3D53DC8A44873EEA97C31F34108B893B634284D69153779230C28B2A1636B6B839A4D91B7E23F0414B111F2E7C1B3ED58613120FEC37C78308587494233313950D82CE946778E044C3D245A19C29B09A80C3B55416A811AF33032A0068C7A4767F05E9AAC3E8B99B967F88D5281A38B072B8C4E194794C40BCD5366714525E846048E55C008CB48B5EA0C61655B8819B08FBB88337E20D63003F2453462598CA66181ACE033C707C1AE9760CED165596B2B163E54934540C4F7097BDF14D29EA850B95BE6FD42973436144270549A81B5F73192C2C6AC2474686A9A3EE556B6F26A9039866176026E25A60B5864E963850CDC8219D21859B5C5C3714434EA53BB16786DDE8036F317C430B3BDB025E6B62C097340F1E961B90E0C5182183DE05B293A05B58DCC251D8A2911C6E71A635F5179D06D93D33D8CB332C8B835C0E2973261BDAA43E414153118B66C641F834C949E77FCDBCB59DC27089138A2E07A5B40C7666794FD8E6B97685BC4A3C2A65912C35F50A278BBAD765C8C775BACF28181D61530E54AE7FDCAA2681A01BF51C0D7A033D6B005893B98DA86005381F1C6E600B1787BBBC13A01210C0764A4A2578D4BF90A24704178F06A4E4B110F5\nsk = A32B081D2579D7737A984126B05465963AC3D0FC3D471B94E30B242699AE3EE7A305D187D9371AF3568D7BBABDC30CA69BE166AAA07C67799DCE7345B2024EE41C5A6F35733CD12EFA19256DDB74440829C6B52AAA25B258BAC8D950CCDEA410535BB3A44A46EBC44F5772CDAD96596980C32A14916CF5C4A2FA8538491F7EEA270543ABC467344FF098EDB4762F658B6B26431B9863CFA7546C1489A25BC9061B8CA0165528241B4BC173BF17B4E7873A5081016A1C55E4BB1E7F71B849274D03E05E866656C126485979CE9660AFDF3622E3051F76D02243E660A5A78C663880A7F9765DF45410926A86ACC7962878B4037CF2960B06F072367B476EB24B8C57924A9C699815BBEB0BB10B2A88B0C63F0171C759D59CEA91C5C043A41A8155E462325893685F18C5458A0AC3E5BF2C696C8F07727C090E1D3502D075A706551C54A00A710027C52CBD83FB9DBD7567ACA2B6EB809C00838E56B209E0C5AAD2E6235E2C157D3659D906452F4A8C60B26F838A51F6789E42C00580E4595A5C0A12B796CB44240A4724C298ABFF1332BB0970A3EC475A434EC4DC2A4AA92C42E22035A4499C66827C882B542A8FB22B6B6054984FDCBD6A637583145010D89A4654BF0BC0A0C3B86788459B659A539833629C1B585A13134D766C9E8003282683AAC1486A934EDD3A7511319A7952B5EB7C5947B69AB5C904B2481A7709C95BCA352DF45E8BB87775A9CB566581C3777E7B975C629C89063C8F0E982A24D344EE8A22221A02C6538154217C453AC0ECD4BB1F820BAAB94D920765C4AC15972AA79BA974F3B5055EFA7FE5BCB454F7AE70E1C017322A20C73EBF278054060687C6301E13B52952459C56BC8D8795044302FC9123921143EC2C73278939826682126B65C7D9BAC044AE6CC7CA40F92C8FF28470E41D51895ADB53AE30216B1ABA552FCC14AB277A872029F3DC8D56794D842BA06770808F1C097787973B0A14280C5FBCC45C102C23821A07EEA6C3ABB4B52AE116F4B38E4A50CFB849177766495463197BCA3197B53AB72B172C163003C9AB89721EFF925F56B59373F5ABD1430B0731419A12BA80641628D78D712BBB74579C0A18A4CB2AA6EDD76FD7605FBF8214A00AA44E486810F3AC6E36345431C23F247F251112CB8A6C76444B1A5277B7C68AFD2C49D4A81FC5069B9A004CDF0587A4A193D243BC5F16357E1B1F280706B4C16F9D8B3B6A5815A1597C49076589D5303A5C89AD320CF6042F2F819CDFF04B850870E807B4F2B6BF99AA8F3FD16E95B3BEDF247CDBDAB048586116DB7A4530C360BB240FB2964FD41A5128CEE9FA6AD434B536345A49BC758D849260B78CD9F3B3E8461CBE906E93B209742C0ABEC1C1BBA9BAA05A8FD05637D26548F48512F5477B93D0BD54F6674158B2F6EA0488191EB023A641B175CC689A2F326214793228138D6DA03BFE4466DC962FD2A7C57102CF3F96CF3A6619D2F613CA063A35F4515C0473140B8EC3C53B1D9974021616BCA2459BC31502DAAFC861990C1B97EA1AB5AE018EAD781A67A075CC4924F9EA364BEC33ED167637F0A643C3A810914A49366AF69B3CC25938E77422832B7078C6BE562513EE3648758515E3C04F7E395F02D56D41B5C5889BB6B2F149425A2AC8AA06FF23A82841887DE199B56C91846392A026B50E87453F44588EE6AD4A443F54D25ECAE39AAF286EFB47A760DA01B6C13FA178811C47A0DFB14110FC6482543E8A3A52ABEC3A8D7176AA2868B2D46CF68538C27514222A34371C25FE832184206E5ABB699D61426027A942581D0BAB075A367793C81B7FDC11E2F6772C8040D271BE5D07D00B330A6C874B46D26F51DB8F43F22DFCD72613F8C22D15C28A2B384051142C148B07F7362EEA4771959B635A215B1351F650342D2A071ACB16DD8AB50539096F295E44173BCAC20F3CB271A8041E3008A742057EF2FB2D78F8A3A3C252F6D38D8E85BD57A75D45AB4DC21B8033992CAA623866E8989F98560DE33004D3409F233020899340B2591E1A4A0223A79E20B4B85C632CE7609C0C45A0246251468C1B6C20716315A54520C5718F4C5C7066331FC7E953ED91AA5F3B92E69617B29C256657124242AE8305780CC0CAF00C92896929A1648BE9B47F86F144A3B12D9DD51F347875E6DA935F0BD043ABBFDC7B85066A7836D442872C56FDD41D9A3A01D9AC6A12531079F74B273CA129F36A7AE463F6464436E50FA70CBC2756BD25234893B50A2898345E588B819C0955E9C50072517D58B0A3E4BFC9832B727C7F2FA924AC672D4D104A8F3AB81200A624C61EB6AA7B4553AEB2084360F1C03E443AB99ACB63AC699443A638BA9B8013C7ACA95ACEBC9ED6B12E8BE5A6CCC74EFEA7CEFC7A0F5EE18857250D08F03CD94CB4C455141D7AA2FBFCBE3EB896C2404BFA3580BC63B73265581D87618B206CAA9468C65BB1863B18F560413D1B1D392259F37C00F7D89124C56913483513006FEFF89092F218FDCBB8B118B206B64F2DE52BE0B553665C32831BB4CBA3762991716BE65E6A222B30A0A5CB246207352732BC3C8AD7A2C3243C62424AF222A922787F7FE44DF05299DA1105F9EBB0C5AA18B6C6C73F43390AF9C2454442110AAB4AA629C8F300DD38318C43A25D269885F970DDD8AC1E5918E59A3D53DC8A44873EEA97C31F34108B893B634284D69153779230C28B2A1636B6B839A4D91B7E23F0414B111F2E7C1B3ED58613120FEC37C78308587494233313950D82CE946778E044C3D245A19C29B09A80C3B55416A811AF33032A0068C7A4767F05E9AAC3E8B99B967F88D5281A38B072B8C4E194794C40BCD5366714525E846048E55C008CB48B5EA0C61655B8819B08FBB88337E20D63003F2453462598CA66181ACE033C707C1AE9760CED165596B2B163E54934540C4F7097BDF14D29EA850B95BE6FD42973436144270549A81B5F73192C2C6AC2474686A9A3EE556B6F26A9039866176026E25A60B5864E963850CDC8219D21859B5C5C3714434EA53BB16786DDE8036F317C430B3BDB025E6B62C097340F1E961B90E0C5182183DE05B293A05B58DCC251D8A2911C6E71A635F5179D06D93D33D8CB332C8B835C0E2973261BDAA43E414153118B66C641F834C949E77FCDBCB59DC27089138A2E07A5B40C7666794FD8E6B97685BC4A3C2A65912C35F50A278BBAD765C8C775BACF28181D61530E54AE7FDCAA2681A01BF51C0D7A033D6B005893B98DA86005381F1C6E600B1787BBBC13A01210C0764A4A2578D4BF90A24704178F06A4E4B110F58AACD8940FF6FC27F175342BE74D48075F8AE9320CAE20A41C879C27C1BF815D7F7054814869CF7625E45647BC1547AFF288DBB90699B2AD84893F3B755D9722\nct = 9E0D9479CC0C6672A85DFCAF8C259CFA1CF68A93825FCAD76CBCE06FA3E40EFC821CA036B349FE50EA23E7E22E1C9CD7F8A930F2DC42F867E33884D0CCAABE685E7A7516CED70CAAE58FF50151AD1932F41AF9BDE629F2E96B3CBB7592B178699179E9CA85DF7FD2BBCA8DE9F30AFBE3F8724D77042DCFB19C31CF239BEDF529482BC947E85334ED7C541B2CCF368D2EFEAE1582A0622AA52C24905EC634D11BA0D1B20A946F2E571DB7F867E8EC9E3DEEB544C77D20CFFF9A0A44CDFDC42CD972A01AA8822E0BC728A66EBC0038A7ED1DD7BEC0E0E66CEC422385E0DFE33657EED638341F08BCD32C6BE72EAC5A378BCD02ADEA563734105C7EA803ED2D6260993182EECA13A4A3C999A209E78E4D64ED1E4D7BBBF91A72F02F760B654895C6398F3DD7D270D28133D66C13E899B8EC69A70F5983B539F975EF2294651305DCA09ED622CF151E337A7027145C9B3AF2849ADA810A96D391DC6F4FBDC1745DD30BD358EA3507A55F2E3C19A7F27D212397148C52698B59EB1477F8C6CA3FA829DF3447FFF20F6AB7F5EC445124F29C5F7B79CBAB1B1D23E8EC69EDE923AA3E734B9C999337014E813BC9E310C6850901993133F11019C95E1BD421896E3D2460E61DA9A6A64C7EBF0376395F509AFDB8460420F26ECD066F33EF121E41DFBE769BE03E25716D7F347D9E9BC0BC65A579F5508BD0562B9AAFB98A9B2E5986057632CB409FF5C10FC3D40CB5582231E5BBB4BE2871B8EAD348C1B9D9E81B876D70D03B9DDDAE0AF4DD5CC6F898817753B35EFB191004229B0754E69C9428AACA4DAAC582E1DA39B5983A5A4DE38998D26197A4171F5D6C28B90428522F50FC212A923E90D1E2005348A5E47E6E6F6D005788D2B455A3E35349AFB822AB5F4F1B9F696E0B186DD2B66A9236179763C639DF4CB6D4FF80D3B9942421D11DA771B184EDE6AC47F74A9250B7AE35B4BE975211A9E12972871F702216995DBE6E", + "39688EAAE21EEA262AA89EAA8A8434120FA4252EAD0BA0FFC4F53EC1AB745A171A0F73A60D84B023A4C4E58F173F0C3455C1B056988897C2DA23D6CAAC0DE7A36334E5AEA093C5D6485CCF06F736CCB18DCDBE853FE6B9441545DFC3535F16D936ADC69B9D2BA08C8CC6DAD333190788EC3541E4C19B38D4319C0038F5BC41D4574141F819FF48385F45AA0DD7F6D5CD5E70E05D3A4366F9878E74BACEE5638B3AF0521A50399043C856E9F3E4ED2951BFD758662C82F8AC8325814349110D696B84ACC146AB30C00484B241FDF4BE8D179F6C8B618F8FB35340AC61FB9E221DC9226A1C59896389B3E24FD844197550016A53C5CF67D7A9F8FBA80B7E61B4E39D36CCD32C7EE8948820810811ADA941BE1EFF722EB83CC69B42C396F3AB0BAD3118C708C51B73D41C9C1DA494C0998C183AC5E592A9E0663753584C0364450847D906F5A261652BE33BC0CD359A732B9D1696E245FF04252635540996A57D8A625D37DE41A80EE1D51770777E709E673E31C83C739E2173381F4BA99D8E7FBD6D9D31\nss = 2CFCF5FA2B4C0AAA85C6069616E19E6715FEC913592D6B8F57EBA9CB4E3B162A\n\ncount = 88\nseed = CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3\ngenerateEntropy = e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0\nencapEntropyPreHash = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2\npk = B5D6022EF207E7629736D614527619E33CB92600A1E39A20B25A5B16EB0EC1070E5D566B28449BFB38936F44721ED428CED5768EE647A771B7D76A30C7E5563B515F5AA89FFE994CFFD9277B0695049C355267B3A07C61F3C5A2C0D4AB8DF76129C19F44F762B51BC0374A43E6F6C1155901B2430B2B77AFC9BA4E14D3658607387DBC2D12B99EC0C0B0C2721AF298A6EBC92A7E6B97BC460674931E21F68377C8303B24CAE8D5AB720C79C4399414A514254603B565397857A7078B36E24A262CF9070A92C034C76614D5AB455B60B3B3388500946677195CD587942342A6FC91BEF144EA412ECE186A422B85A213C43FD0C361AA00698458F5C5370C6C553A9C238201754E2B2E2785BB03053E0B414E472087A0276BF2D805CF477378CA34D8F01C21B433F33B49A8B9BCF762451460558FB9C3CD071E654C250DF04B6541BAA278C1669BB49CA3AB4C78CC92D0137A2864BAE0C904E23AA28395EDCB435D9C1CF742562D603BC61C521145CA16F69192B137EE372F04402527BC557B754E187355A388410751267561A6B1F59E04190EBC604FF64A2B08B244B57ABE84F18938C5A9ECDC972191BBA33915C653A84B1A970AAC7343AC98BDB7BB877A3170E8B1E8693FA5089F421281B5763865C584CFDA6AAD7482D00A0520D947FDDB173947865FE178F9800570D4B2B9529A42A514A8691C8531A271C18E5F84380C20CD9A992051D29B5BE76B2235B511514904E3B284E8854556334515162DB1B09894B18A3127982269509BBC5E8758015A5B810569E544BEF9398F7D195A50A958DD78BDA187CEA0B7B2BCA04E2CD90DB634A3D52B734E224C4C60BA3C8240D7B2755AE5892A09A0E7EA1B2424402C45A0AD59563AB97ED906A1A15B8C4412219203CE6826B91DD00AD602089EBC5163B416C0D02009A7A5440350A00A7B49309CE39BA26DF79ECE038F23F4B4300C01287A51F5FC619EBA04AB1B78E6396BB23C1CB86A0F3BB11F7D31A161A480B8F33734CC63EA7219D76BAB759B1AB3405CA61B535B893B1BF2B678849751A6A4F18923EF44470E543924D0C462D8A078782B80241334F547D2AA474D95B8709747162B228993BA15A0C4FBD8BD662A1A2F01CFA859CA723A011949823FBB55947B9C27C2BAD547B0E6D29665071B30F3C8C536651E6437C0D4A314AB38A8F707928C0C2B864A3A67397A936DBFB98FAB2C0935441B83157D05072891A43573882BE97686534C8BC7015AC267B75F0A79C6991CB6C96C735A4BEA90ACC9BB6BA1B12388F0821A074018909F76944D9295B5EFF73E70AC1B0E1644E3A40685305F8A0626B2F05969FBB4CAE07C61F6213159B3471654A88AB58EC3A648F2944625820F6592C67126BC085DCE216FA708089D4947AB911AC14C00E53782A01580FD967594E0B2B2A3272D590AA70C7A3F419ACCD33C1B1294D21242C739A3E8E577316C23EBD4B4C4D0577B2BBB12CCA71841B54C0B76729320BCE26DBFE5BBC017C92491762A6C938D4BB0099AAEA190813A3A78E5685D83975050D719D6B6A80AC313D3018D25B9054B5013F832C1353401E6CBA3FE527B8D2906871B79836CB35284725E733D8FB60E6A8410E5F61428A3CF9C25FD45802D5699F33205A71D6404704483BD2C82E92BA9457926A45BFA0985\nsk = D1F46E67CC5AEA63CA9EC413938661C2F8156CC79E10A64174774545B597E91A8CADB58DEB15B27F343073B071873870BF858B5FA3AC3689698DEB68C570406972210C2B9909571A12753448E00E6A0C165A101469828E8F60A16B55478C8899D9A38C1751BF220A60A999B0D2A429B375137DB8BC9B85AD5FCC073355AE630100F8FC68EBB8534135590CE22D0A0672AB54936C8665AAF476B50293A32135283777C375767B04547501A53B72A14D3C4DE4E001D16B2B2B598A22D784A3711C39DB183AC82CF895B242954B41C713BF464464917D6B608D21B67B3519A6DF161AD237359E262B95C6BE3A8522B9248346785FD0DB03CD083A21092F4D91AF156B12F4C9C77C11CC0B68ADBDB813BEB21289743758F8136661704D0C5CA9302A064040334017D47815B7C35363F5C730298670536C69C122CC91CDFD18783EFC4C39C8C29CB1023F1488A7469F1CFC1D7EBB3D1CEAADBA3B07310000BD89C043290ABED896E655CB1F43A1C7335AEE30044D9652E6D3B8E394218F63072C7050A2984032C45735A3AAA4108AED8B9A19C13B9BAC28CCB123D9987C45B91E89B7A949B5B4AD56ABE4237F21DBBC53AB651BD4B703069F82133C54ACC1AA415DF9961A4785337535869FB758CD04B798907E36197EA428C66AA516F602404E87341E154A0E09C881725CBF00761FD9645B658D97D21F33059E4A898DEB0C826D9057AC302663897D71567117FC4416C860775B026E51A52663711868777D542F1224B277EC005F2BBCFC0C84146591CB36CABA82692B010DE229797CAC57AEB64AF446A896527BED9B3E55539C0F6A0E9ECA5953890B95B0B282C3A4C46A44A8705A54A8806CCC0D3C736A20D34AAB118813651D85F12906958933D69679D0457A4817DC83B525CCC63E94C1BCB1C869CB3A0BC46D47084481C2563754AA8F44682B870ED04996CB8886F43B91AC8767AE12856CE5B85F55C8802830BA1BABF5797D0DA723EEC24616A195AC809371D93F89B19C874C840EE9C39E7370CA561B6E91552CEA47F1D09C9CF633E7CABC9EF85F89D01A29D9CFCA8143BB05C3015B3C6035AFDC45AC7B08B5406566BF864657BB3A82322793906462C03C20969F76C2C8C8EA2622A373C3E40164A77055EBAE05787965B60A861C09658C32D4194DCCD7AB1DF87826590890B1785F0385B965B5AB3B870A0088696A783B5C7A69962B86F789BD43588705315258C117C4313198AF42E2B7FE39894A86189FFC4E8C6BAC5E7A0F03D86D18089A6999972F309A6DEBB365781F64197165D259BDA98C7A920A9E790BDDC587E7C08040D649B8B08FBBF36D1904970354410BD77B87889668566CDF4A94E1C65B04D33C269C5152B049850857308BA1310283A976A31DB34722E97C97DA85D14372E14A8A95BB45C63670BD7712686200D451CAFE599AB0D3A183D2B0DF7B8FBF0995042BA0CE682EBA8B71DC6C0744262C75B7638B51B9C4931D4F7C842328486A799D06027CD5CC75E4B1B6816C2AD66B86ED047EF978184BD344C00AA1200432C5D142246B883B5B85AD5CC8F8FA994F4A790F3B6C201353F77AA9B7E9BB195375060282B7DA42ECD36295FA55F8B5CE94B812BC421BB5D6022EF207E7629736D614527619E33CB92600A1E39A20B25A5B16EB0EC1070E5D566B28449BFB38936F44721ED428CED5768EE647A771B7D76A30C7E5563B515F5AA89FFE994CFFD9277B0695049C355267B3A07C61F3C5A2C0D4AB8DF76129C19F44F762B51BC0374A43E6F6C1155901B2430B2B77AFC9BA4E14D3658607387DBC2D12B99EC0C0B0C2721AF298A6EBC92A7E6B97BC460674931E21F68377C8303B24CAE8D5AB720C79C4399414A514254603B565397857A7078B36E24A262CF9070A92C034C76614D5AB455B60B3B3388500946677195CD587942342A6FC91BEF144EA412ECE186A422B85A213C43FD0C361AA00698458F5C5370C6C553A9C238201754E2B2E2785BB03053E0B414E472087A0276BF2D805CF477378CA34D8F01C21B433F33B49A8B9BCF762451460558FB9C3CD071E654C250DF04B6541BAA278C1669BB49CA3AB4C78CC92D0137A2864BAE0C904E23AA28395EDCB435D9C1CF742562D603BC61C521145CA16F69192B137EE372F04402527BC557B754E187355A388410751267561A6B1F59E04190EBC604FF64A2B08B244B57ABE84F18938C5A9ECDC972191BBA33915C653A84B1A970AAC7343AC98BDB7BB877A3170E8B1E8693FA5089F421281B5763865C584CFDA6AAD7482D00A0520D947FDDB173947865FE178F9800570D4B2B9529A42A514A8691C8531A271C18E5F84380C20CD9A992051D29B5BE76B2235B511514904E3B284E8854556334515162DB1B09894B18A3127982269509BBC5E8758015A5B810569E544BEF9398F7D195A50A958DD78BDA187CEA0B7B2BCA04E2CD90DB634A3D52B734E224C4C60BA3C8240D7B2755AE5892A09A0E7EA1B2424402C45A0AD59563AB97ED906A1A15B8C4412219203CE6826B91DD00AD602089EBC5163B416C0D02009A7A5440350A00A7B49309CE39BA26DF79ECE038F23F4B4300C01287A51F5FC619EBA04AB1B78E6396BB23C1CB86A0F3BB11F7D31A161A480B8F33734CC63EA7219D76BAB759B1AB3405CA61B535B893B1BF2B678849751A6A4F18923EF44470E543924D0C462D8A078782B80241334F547D2AA474D95B8709747162B228993BA15A0C4FBD8BD662A1A2F01CFA859CA723A011949823FBB55947B9C27C2BAD547B0E6D29665071B30F3C8C536651E6437C0D4A314AB38A8F707928C0C2B864A3A67397A936DBFB98FAB2C0935441B83157D05072891A43573882BE97686534C8BC7015AC267B75F0A79C6991CB6C96C735A4BEA90ACC9BB6BA1B12388F0821A074018909F76944D9295B5EFF73E70AC1B0E1644E3A40685305F8A0626B2F05969FBB4CAE07C61F6213159B3471654A88AB58EC3A648F2944625820F6592C67126BC085DCE216FA708089D4947AB911AC14C00E53782A01580FD967594E0B2B2A3272D590AA70C7A3F419ACCD33C1B1294D21242C739A3E8E577316C23EBD4B4C4D0577B2BBB12CCA71841B54C0B76729320BCE26DBFE5BBC017C92491762A6C938D4BB0099AAEA190813A3A78E5685D83975050D719D6B6A80AC313D3018D25B9054B5013F832C1353401E6CBA3FE527B8D2906871B79836CB35284725E733D8FB60E6A8410E5F61428A3CF9C25FD4580", + "2D5699F33205A71D6404704483BD2C82E92BA9457926A45BFA0985149E0B6B49FE8ADBA1217C2C57C83F2B8C5F1D92F319E502B184A65869214F75D82C2F1BF2E6AEBDE5660FA73356982E12999D8FDAFBB3CB186341D0386DEAD0\nct = ED5E2079428744F1871BCB3803773997FD3CBCE4D574D7489A7907C84716AD220EFF0C0CAEAF0F784D0A633F8724D0D70A4E40F115C49BF1C5133A3A99A5F6027BF2BA7BDBEF436D1D8E4A9DDA831DA76E127BFEE0CE3C0483646402F789205D95D406421FEFB2C5A62D60F4C47FFC7C3AEC46BE075BF05FB6336C78B098F47BD1B368F2E5C3DA0E1732F43E67C14C556EC3F7D977B70491A35B5539B8532CA72CAE5B5B8E9936A6FB3A565B535D33EEA5C1B35A5DA0F3BC589B109CD12280DB6557377E9BDDD74B06E583DA873B78F96F323DFEF547D6EAA42D4E450E7CD213DF9B598C9D2134DF772E64CF09D7084ECB4DC6FC079E6B736C2D4B2FDA87B9ED23000E8558C90F5CB9278FFBAC209702CB4F3228944067CAE55CECCCF609F126465754D1040BFF976623811E7A9A1CDCE5D9001074DC30935A06B6543FB5B1F4943961B6330FA0138604B1102DC0F0C643E409EB350E15CCD2EC73280C73DC513E30264EC961366EF741D9CED8F116FC73728AF6CEEC1B61D934124522068D063D5E9479335336C33B7D8EA0EAA02F2E20D0BA7663D863EC198C3D4DB75F0787EE80AFE016BA37F15949C2E7B84B72DC88419DB17F2E992D0E89C451200AA97372331E3A8237BA5AE4B527E33F724F45A8507C22532F064E6843512613D762E5DE7B0FC41670089C15D2F78F8EDDD1DF63D350AC99708459DD6B667E9244D6CD1D3DA09D9B0A194E2E169D5EBFBA9DFC84E62F678A3BF6F0D7BA198B8A1DFC9023AAAA06890FCC8ADE8769C0B049C3143DEC8282287C07C9244CB5CF4592E48CEC9FB6DB7B26C394EA09405194845588F8F29D872502C81D55D11DE84C1507C29F7EAB440D3D5F9D43806E2C3006E3A716F39D9B3DEEF5FB68D3F58121DD5DDD0FB2DF785B6C6A02FF04DC67DAB0928D8CCBB8E8D60F48214F4BB1BC770E940501491AF59F951740EA8C052BFCDD5F22082C46AA94A0E0279AACE1B3A8AA11EA177F8C193E1530B65033F0DA63E1396E5F094EE8D87E87B0738804FEDBA103C38B2422C712B48E1C9515FFBBB7808516C3985250FDF5727E4B3799D242977E9DBB35EAEA63971D2807EA18290CDA801A8654D3C6035FDCE27009368846D18EB5C80615512ACE4C93448552855C4901AC2D3867FBE4A1279CB9F63BAB8348E2128D8435A09DB1ABF5112E8D72BD5D3F77A93544021EC281494267EFD97CFD2B21881DDA6C49CDDD56BBE77E80BE8143C1F38FD47DE797F45A054DDDE6B3117F5D02F78222936D7D3B10135C0942812C049BCD5B257B7F6AC111C92E43C250536B85171EF4337E1F7B55CAE372C943226FC29A06B2AF4D2B69A6A68E91881D6781806510E565CA3776204ADED42213168C22E6D33F167CA62E552F057D8F0D3E0648FE810D5514C5BF4D78410CC41333313716CCD5F0B5540E9106F7D0813ECAD7D180AF071464088F6D233B606C495D78B372C16FE8F94CD574DE08C7369195620704682D7F1465D02D04A87CCBA9BC55BFBF2E4EC387B84AA70E8ECD6EBE7870\nss = D3551ED0FD716E4887C82A6F24C5008BA80A9B5C3FC9E50F188EB224BE8102C8\n\ncount = 89\nseed = 96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0\ngenerateEntropy = 470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a\nencapEntropyPreHash = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b\npk = C55170FE0945513748C0ECC9098A02E9D51E44ACC267272633645AD562816D479466B54D2150AFB682B4F32265F1F4BCED21CAF7C7980105B08056CC4192BFE0DA9AA5E00864B0A34712204CF6AE82DBAD360A7C840B4804826C39A59AE029056C1B2542B6A589EB47C14A70ACD1731BB0A4D657656915B91D696B2F92AFD82245945C7B77958A5B6A3B6CBB179AB83A0F32591B757E8B68368D6A5EE63490604AAE70EA7FB4619C91A455429A6B195214BD28BC717385D3CB8235991C05088C7939BF852125DAFC3BC368479165438092B530BB2B869246988B8F85425A2A523ED108C6D2F54358580944D64D801078A4B621F58012F9D8A17A92AB8AD43821E24E2F87BFA844ABD0C6B08650AB76D5397F2CB0060B31AF689FC8612249D46374848F496B360E733FC991809DA804DCBAB14030A4BD18CFE37B41CAD91A66A263437B7DDC2484ED55ACB16AB95A1A8C9345A898E89C37248F9768524C616BABD17A8DC7924F37345DCC32DE04273C5A0AC038A133BA01CE2481FFB57BA153826A7CC4123570293C82082B6A75FA05031CC7FDBB9031E10CA94AA283AA26EB3546F894B646B9A85AFC5DF3B513DB522EFB340287C64492AAAAC5FC25547129B56B9541EB0912222C2E60A11B9304692A749BB174CB47679CC294253B0F768A7872F698C23493FD908C9FF95F9275551B947BFE84780F86C1E0BC105F6CB7C9430369B58BBB07B3B0C87D8541618C76A43D52C98A08166E052B4487177AD222E6A002F7FA3F3601CF1EF0B4C02AB550D76447EAA695561118A46301B544B493C368B5B77AB17C5AF4543FA6A8C682A46AF39CA48046B1529684A53D0E492E1B8596F55334ADE15591DBC4B411537C88A5113458F187A6D77278675B0C85BB017416B6E9543FA1B924B631AC1DDC5556127548FA8CE0C90125139BDF13428E2C7805607A44251A5F289BE4E3A2C3C95C5B5CBF7C87B4A7D87A39A44B672BBE9AF8343DCB062EA3A039E949A7F151C8900484368F1CFA385BD13CF55685BFA4B959F8634ED7C437FC9C044B401683CC7482722C98583DE24EAD414C1833858BE987672C557DB87AEFE4CE2DB8A676D14083462DB35862DC0CAE95F88EC1F59426FA2E24E9CFC54813BE07C98F78A87B9703276B455E15474D7A283D5738D4B639369077E7790DEAD3336E1467C871A571080004A91162FCC31D2912646A9406902248FBBF28DAC4343B081C327743335B9EFA4B7FD13D5177064A5B6E8065B64D8C6580B47E6472C8F5139268145BA7A23A02F59ACF680692B20EC2DCC087A99BE036BF7E9C8C0DF15F168C508AE28E33D951740A9B0F0321E35CC01328B7BA860592B566CB369B21F51B7AE583D26652DA729F07F5B8D59CAEC65AAE42C7C9CBE73C68504F26670BEDC542FBDC67A95C9F2DA1A08E559797170EE63147A4688C8E101E5AAB48A4D1862506CFCD297C7EA61A9ED4A54FD3A28380292FC1570FA2AE43920B0E940675B60534425C69F35BBA714C88B3A6C323090B4C56B7F89963059F8CCB0994373FC1344412F694175C2EABEA110E035BEE6ABF546396D79472EEDA164BF49350F54C2E75754F502DE4A42721B37974A8266C49B57C6837B38A28CA489F02FA05307D7163B35BA6A4C5024B70BA27DB0DE8D64BB8B55C83BFDD24\nsk = 09D0009AA9878C697E2EAC9CEC9675A9570660346547D7AA8D4548E3AA917E238CBBC10C389445D15714B237566CB44132D6983C9610E779570B74482D5BA2742A1BB51C68142C1680B800F1938795367B6D8A56C32A0D77922C78116643530AAC01CFB2692F4BD6BBDE615A3335B397487DB8A1175A043719EA58D0DBA627D7C8511468B34442879CC227E6B39E084DBB68BE71CB988766114A80B1979118ECA08217540F032966688C99FEABA06D0A0A1E701DEAACBCFF9C2F2948A209AC8EE505C85FE0444B5C70D067100B63CBD6D98F9AAB73CB06C97FF31D7AA0CE188707DDC5C07D495B27957B369055650ABD5D9B9F75761770920DD0B574A5841C3BBC9F6F1AB0179C118C7A83B2934E950B3DC732C84264C66FCB0DF78975FCAB5FEABA4E6AF97131696A0CDA1CC9E2C40A266FBE6667C1ABB361F063103311A792B95CC525FF872BF3F394FFB48B30B334CA02BB32A901E3478F811505DA066DE6A5CABA425DF83C27565CA48B16BB2855A797A72DFD57615D5117B24374C2D306473A349521A8107790D268AC6B5813C593CB9E8621F8C68FD2E8082C491C95C5AC74C86DD37B0A4EA0CB66AA576AF50FBDB0A31235BDC9E8107F1859ACD2674FC72C6669A3465556F90269CC30B0A8F53563378EE016A7ABCB5460D5371B01754BD7373C2314E2A42D98636112F3CBE0638E513B38D4850AFD6A1D3D485308181FEBD88B75F532E4541965E0BC592885FD1C1B3108C33F74725850617B526AD4F2C8CECC19B0A0ADE15057C90AB086C26CB014BFF92988903BAFEFA3C4C96CCBCEF178F988A40D339DB324257DE69A119125C52A4147360B1274808299446EE768680170457ACEF18814559996FA96B418275E031199E0D578E86C946381C369AB839B1A75E9D6845C98AECA24253B3B0F00EC7E92CC6F6A40A4D8B04900CA3E78CC7A5C51886E0901A908BF0A08947E3B524F1C606B055451AB6EDA2BBCF832510B3075E2CB0ECD493B71102F4EC69565F96651A3A2C3B738C2D55805798253E055DC8508B98822E6803785130D22E494B50025B0CCBC69667013C4CE4A140C2E9BA928D41D7FB5237DA8C5AC0310EF5007B2B0C6737BC17A747C5A2C1F3C1166BC2B0AD7AAAB1D870E54694C1CA293665286C4EAA35D34BD6EA7AACEA04871C257CF63641264AAA0DB4F65337274356F71D02310A57E44D23EC6B4185BC5CB45A65D3B592AF3138216332060264A6E53702D766D0F4A0F14F70B75B780688591CC414283A59AD2F84D665354D71C2AAA1C278AB6C8BA902283B286F82761906C9B2796595BF5AC01455ED2B43607207A30C949AFB1BA5C50659143C98237279003CA820B4B5963B0882A088CE09C99F4A6368971A7D6885237BCE28580E2EC483FA305FFFC0ACA173A89CC41727A55D4E29A8C410B3FE851B3D58B58C31920759ADA529DA162CCE47618B2F715F3658D71F5455365C67B04748B371A5A96B75F342CC4C031C713C04D2B6CDEC0CC92B7596BF4A2A0C91537A0C8174B3456489D2DB70D3AF2995C4830245120E9411E92ECB2293700973386983A0C6591CD5EAA34D5CC00FD672D20A604E78696D5542646C120E02C8DC5162630E71465ACCBC55170FE0945513748C0ECC9098A02E9D51E44ACC267272633645AD562816D479466B54D2150AFB682B4F32265F1F4BCED21CAF7C7980105B08056CC4192BFE0DA9AA5E00864B0A34712204CF6AE82DBAD360A7C840B4804826C39A59AE029056C1B2542B6A589EB47C14A70ACD1731BB0A4D657656915B91D696B2F92AFD82245945C7B77958A5B6A3B6CBB179AB83A0F32591B757E8B68368D6A5EE63490604AAE70EA7FB4619C91A455429A6B195214BD28BC717385D3CB8235991C05088C7939BF852125DAFC3BC368479165438092B530BB2B869246988B8F85425A2A523ED108C6D2F54358580944D64D801078A4B621F58012F9D8A17A92AB8AD43821E24E2F87BFA844ABD0C6B08650AB76D5397F2CB0060B31AF689FC8612249D46374848F496B360E733FC991809DA804DCBAB14030A4BD18CFE37B41CAD91A66A263437B7DDC2484ED55ACB16AB95A1A8C9345A898E89C37248F9768524C616BABD17A8DC7924F37345DCC", + "32DE04273C5A0AC038A133BA01CE2481FFB57BA153826A7CC4123570293C82082B6A75FA05031CC7FDBB9031E10CA94AA283AA26EB3546F894B646B9A85AFC5DF3B513DB522EFB340287C64492AAAAC5FC25547129B56B9541EB0912222C2E60A11B9304692A749BB174CB47679CC294253B0F768A7872F698C23493FD908C9FF95F9275551B947BFE84780F86C1E0BC105F6CB7C9430369B58BBB07B3B0C87D8541618C76A43D52C98A08166E052B4487177AD222E6A002F7FA3F3601CF1EF0B4C02AB550D76447EAA695561118A46301B544B493C368B5B77AB17C5AF4543FA6A8C682A46AF39CA48046B1529684A53D0E492E1B8596F55334ADE15591DBC4B411537C88A5113458F187A6D77278675B0C85BB017416B6E9543FA1B924B631AC1DDC5556127548FA8CE0C90125139BDF13428E2C7805607A44251A5F289BE4E3A2C3C95C5B5CBF7C87B4A7D87A39A44B672BBE9AF8343DCB062EA3A039E949A7F151C8900484368F1CFA385BD13CF55685BFA4B959F8634ED7C437FC9C044B401683CC7482722C98583DE24EAD414C1833858BE987672C557DB87AEFE4CE2DB8A676D14083462DB35862DC0CAE95F88EC1F59426FA2E24E9CFC54813BE07C98F78A87B9703276B455E15474D7A283D5738D4B639369077E7790DEAD3336E1467C871A571080004A91162FCC31D2912646A9406902248FBBF28DAC4343B081C327743335B9EFA4B7FD13D5177064A5B6E8065B64D8C6580B47E6472C8F5139268145BA7A23A02F59ACF680692B20EC2DCC087A99BE036BF7E9C8C0DF15F168C508AE28E33D951740A9B0F0321E35CC01328B7BA860592B566CB369B21F51B7AE583D26652DA729F07F5B8D59CAEC65AAE42C7C9CBE73C68504F26670BEDC542FBDC67A95C9F2DA1A08E559797170EE63147A4688C8E101E5AAB48A4D1862506CFCD297C7EA61A9ED4A54FD3A28380292FC1570FA2AE43920B0E940675B60534425C69F35BBA714C88B3A6C323090B4C56B7F89963059F8CCB0994373FC1344412F694175C2EABEA110E035BEE6ABF546396D79472EEDA164BF49350F54C2E75754F502DE4A42721B37974A8266C49B57C6837B38A28CA489F02FA05307D7163B35BA6A4C5024B70BA27DB0DE8D64BB8B55C83BFDD2429B1BFF7F12EDA28DFEDFBF0AC16E27008C9FDC62C35E53B28A312BDC91C40BF8B2809FD40008BE70A6B184981101724BC3D5EC5E1956B510B82FD5AD0668A5A\nct = E9E8B57094849BF2A09A5431B0CFC2CE5A1A6C288B1E7B825A28C5991F8B6D5DEAD55E5BB9FEB5F98A8DEA6A33F9CAB55751C5C8B841B69F3769598F1A1016F0FF9CC42A9927D98607DD7FA1B25E1C2EF43909115E09B6FB434225FDB20A1E3A1DDBC4B7925B34B696A50DF2AC800D00CFF4C0C0E31510EC3D8D0B44D2D80EE5CEE9039802DF9E7367BB0E6E2E71FCD3B5F6AA97CCC6866AFA43619F5EF2726D9E33D2E6404156CADF8EFE1A356C2F2235008A43027720270C3FD0BBBC01CC07A0894247275F1E9A54CF22C819674CADED80C2979D720A6F233C6A0BAE986EF0694007816BB504806769B52177C23753E706D94BE0F5BCFB4E2607A723DA0B2018A1C1711940A353E96C3C6F34A773591ABE5F4BAEA44BC45670A6B8346B0C6EBF8CA3A5DCD33E82913440A9C28FC5A6B8E03D600D2C13A210D4F7A43D66DFA8214060F05754F7B76BE16199F19C5FD0B832F2FDA4EB447640BE835A34F5C9C73DEEE68776C7BFF2BAC601E501A1AE72535067377DFD3A0D07462C3DE3728DC5C02585F4E5CD7B1EE7A47052CCE9A90F098180BBA4EFBEDD10866BB2EF1389EFCDE7D48E9E8F3AA3B0419D23A97C4F915423A26E8181817A2F0B0B9C3AEC1DE80D355CB0313A806ABCB25139980488FFB2084E5A93162CF027D0271050D69E563A42B61107B3CB2BC17562D2ACEC2169BAA778B0BBECBA170C8C40A8E65D3CA9F8409FC14BE20D236846D50BF1019189CFD2AA44F199FDBDA6AF4AC5646B1890817F93DBEDA0FA1BF0EA1E00C1467048F36D8E996D5757A36D48C73DFBE9B9B8F42004A98600685A0500DB9BC9912AA10A7D8EDE8E8CB2CDCE5F67E5AAD00B4D0E17AD03873704DC62769CF5629BD3A3F281FDD75B6E682E1B9CEAEEEF7E3218B37AAD6D4C3F1786B7E5BFD657E3DA0D69AD6E21DB3F00480A56528DC09A72AB06C786EAF3839599F2AA4E7B34F072BF50F28E03A90819894B6F886DA655865F96AD4E6CD8EB3E440351E60CB9FE6D018B3712C32E2E904FE932B49D1590869A19315FF6352F1CC9D97E7D3DA89716F5F2931FCCBBD6ED96EDA6CB5E021A6F5048545585DB127C8CFE7C3AB905A35879CBCE540A1348ED02602A1C3AC0C9CDCF6F3366C396219938AB002736AB1DDE1165F44C90EC3D22FDCC3E86B32BE8677B914BFA24F21036B11C8EE5ACF390E10247E85B71EFC50BAA05945C09771D060F83D7FDB02688732D852507CF53BBCE32DE17703278C71C46026D72870732D822F8F8D0D216A397AB4CD5C6AEDA1FD35287AE6720CD4106D64A8141307ABF41FE68096EA51C59B2827ACF7E54C8E9A00ECCA352B276D588F4E00C54D0AED2E098E6BE9F174C3ACCAF83FC7E5D7CD6B6E6216F54BC9E777DE0A239574D85DF930B00E61C3096962298C2B5D644740FAE2A1867288A2ECD6240CF4E8D207CC2B7362FB1CC064763F0A7CB3696987C33BAC822F431F981885BF7C0377041A2C7EA34F0FB0E3F0147BD0362BC5E6D1EA51289BB1E5187DB1DE6656BDA982BA0A91458\nss = 03139CF9F20FB6BDAA4EE906AEEE834815FA924E05ED7E7E3BFB432AAD944D6F\n\ncount = 90\nseed = D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A\ngenerateEntropy = 6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5\nencapEntropyPreHash = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec\npk = D3B1CDAFCAC7F6D08082DA095A7658B3A45F7BF717D4B80A3A050A04CB23E01103FFB1731B2C35A9DC23C4341976B188F5226459A02D348BC9D2064D574040147B41612914CFC2954E4190905446E5AB8632EC96145B917DFB4A9DAC62B18CB0120679E739901D9BCA662024335A083911AA53828D6D79C948425422C32EC471C2FA843B54F6731FC401475612A135AAE4B146FA829871C0654C075DCE41190483C3EF60B7336200A4A39CFB6787AC09AC85F4CB3DBB494727A20ACC8A1CC9CC765862B0D402147A08A5E4AA6E679D482786910399BAC7A36EFA477236B1A01BAF452BADB3F184D7D6AC6EF64CDFB89D1CE66A059A4659D8137DFB3C95CBC9E8D86E064CBFDFA50C68130A8D82258407BB7B926F7A802B53209F3AB78784102E88FB91E6311D496251F7B574AEE5797E881BA1DB16AF40281586267D826C0F33A0518C26E6533E19EA0EBF29474A131D882A189AC03B835C16C34C9AE7A1C4D9F5159F85B8542284E0409DFB0876FA6488E6519867B5C53896867772210E95399A1733D2E78532B7651CA9704AC063DF086CAE4AAF65150093F27054F34E2849449C7680EF1CA1A0AC399A01A9B74484A967592CE85086230582518414C247BB7680ABFC2A04A35A20A851B73548A8E4CFC2B84CB5EC24108396C28498A6614790D56BF8D1B9F9E40BF574C497218EEBC06217C9BD361BAA5D0715E666C2D3D299346A79BE0BBE4B7CCD49F948A60438514129C126AA1F3875718922C5124728F09FE5437AE83194DDEB81F0D744FD2B9B59FC223E2792501B4932924FACC16C1E5444DBD6A823016B3AFCB46EF59CEEB49728AC541BBB6BB64B7E196C59910628C8CA22B1138D884842C387B594B544E5D99784B06ACC3B5D80BA81CD34739A20AF11F7735D645D9FF25C07F8AF9B5902524A1953CA2A58D6B796E3695A006AD6C703DD161C12C01B9BC995773C5D2CE59470C765C3F5401CC07885C77BFB3C15D7F766F0EC7CB3F601DBFC210D599093A21C87D82002212B06898A5A878D4EE913EB451DCE14A1BC424838D4797ED14D9EEA2473B304D6624F1725C820751A9D313CBDC79AC9A26548587FB41371C5F48A4DA04D37AB7189685AAA054853F0491A0388AE4B7AF4259969E29EAAA2B2EB9503518C7C53BA0E6BD20EA8355A63F1C481EB5E662A0B792014AE4C0981274D902759AF794338072A839B05D9D42C1EBB1A3DA33B54066D1A63024A3B1D1437B37A83BBE816075CF416275A6F58336905937105E63A1A017F87911CF0B41DAA41A5DAE3856A606E2A9333176628198B49D2517F54A9182E4BA877760517DC94A079538822251204B4C4A2382CC7889BF84923C09072F86BD1C5879ECC3A37678E6D031568C24012578DDE5CA01005B2DF71A4A0B0455A03AFBE7C366BF1B086973038FB5DEBD793A303B4C867B611772733F66574CB0D7C303563C389B2F1B46E98945A94B142B2B0D647521F4B58F12326FD86286A448909191BC600BC7578B0169A45C071C77F280C583788F9C2AA1200A73431AD56D23B20471BB67A627A594BA9922B1FFB75D2D030432A954C71235A9278857C3010A8A8906C070B77060FB831842140770ACB92E856C8A95E163D5181CAAD6A478AC9AE82EE27F7256F4D4CACDDD43F45CFA4DE4DD067CDCA\nsk = 96D9C668915384C2847B7991E5F557949C99A3D46A2FC9AE7448A229A89EF7F405C2911777FB1E2F44721BE8CC326A80E524486A16A083527E22D51E4EF624B02625FD6A857BEA2C0590A3A4E39F0E041B7284BCC501201842345ED5CEB097A5A5F730EE53176F8ACBF9E03C6DC4A069718DD64C47E1D17323D29ACC630DB2DA9922804802CC768070245380CEC6672F6A5A9D14E4012BB13CAF8C320A320ED63B0591087A0C5A76EA29B57D5C997FDB372E9A57E3F4827A2441CC485718A421D3C45BD0426A87589362E52953822CF785802B2C6AA441ADAEF93DC6451AC68A9867C9B9703ABEDCAA540146BA6DD8ACF7DC317A82A4C1396267032FCCB53BE9306E20E4713B82842E03B7FA984E5827C441E293352B2E2A51566EACA8D9C4206000655F761729020F7FF9B230D6C4B986BC94551175A8ACC7E2A2C174C500666D3CF021A9B40F1A465447291F920865AD16240309B5C838A2DDC5BEB8AA11BF987AA9D7C082E8C55C63AB01D0664E545E505B4AAE50606136B6B01499A5BA10174852224AC6BD242D5D21758C4342F9A02A3D46A9A845112ADCCBB73488CFE3055CAC398B0245C467B94EB342E1845969D70511BC7100F886308CBF21C13840BC17626AC93DFCC4EB22BA18F62B15B521539901166598F25555C32587637A341017885AF1A6D1841AA1C747D918253E1C873C2CCF292BAD45805D8946B00DD23CBDA03878F66357D175D67A1B743C1E5428CE90661067011874B062E9AC8A0F726B55B76627C53338549C3F2605840A11D5606ACD104BFADCB51253AF718835826628235878D6160F15033844D76AE946AE6C240053C2AD6C3A3D72E721D9565A6C79B56840CC5A878C6A4033BB9C88DC43B130348082E41C269CC0D3B05FFE356B5695BB01C95F8AA9C30E50CF31F11419E13ACFFC7192B75948E06A68458DB80A8F71573B6EDC1513AA5B060CB77B12C62761BC188159A49C95180249B3E35C3100635012637CB9CF17CA993678", + "7AAC954BCFC655AEC8B4215861A7709F2846A1C14889D0384591753E3F19CAD2236DFCB7B225ABC430A7B61E6018AB30146D60A6563B2F980ACF66186FEE70A458750CC62C433E651F447CCEF8A773BB2731A866832AE535F0D82E605371F6B35FD6FC1188A52080C609BDD8748C321CA37190321B286C849D35224BB5107D83E2827EF0C63859133852630B237247AA8C100678E43618289239EF19C99AA6B9156704643285BEC89F0B0C21F3A091E2063E5D3029F52C33AF97529E701298D3961F492E6B731D4E2064D034533F4611FEFB64F1899EF563AD71A52E20B199F0D80C557CC8CEDBA3CD1746D3A6AC2E697637F08A43D681ECE3769C8980C76A26ADCC585EB1194D28AB163ABA5563A5C7985720248662BBC21470022EF4110B33B6B8B744A80AB36D0A9B0A7988A0C98C6A597F8CDC76791C467B0CB53A020928F7A55981B520017BC06B36D10A21433797C15124E0892A81230BD6BB4774D46F73B874602588D3F8966469194041BDEE87AC54059458B19724949E7998AE8018755D491BFFDA76A70A64EFF902A4281734A7484037C739B7BF71B658B779CF6370420D2073FB820BEA1B1DF29C3B12C54ED3B1CDAFCAC7F6D08082DA095A7658B3A45F7BF717D4B80A3A050A04CB23E01103FFB1731B2C35A9DC23C4341976B188F5226459A02D348BC9D2064D574040147B41612914CFC2954E4190905446E5AB8632EC96145B917DFB4A9DAC62B18CB0120679E739901D9BCA662024335A083911AA53828D6D79C948425422C32EC471C2FA843B54F6731FC401475612A135AAE4B146FA829871C0654C075DCE41190483C3EF60B7336200A4A39CFB6787AC09AC85F4CB3DBB494727A20ACC8A1CC9CC765862B0D402147A08A5E4AA6E679D482786910399BAC7A36EFA477236B1A01BAF452BADB3F184D7D6AC6EF64CDFB89D1CE66A059A4659D8137DFB3C95CBC9E8D86E064CBFDFA50C68130A8D82258407BB7B926F7A802B53209F3AB78784102E88FB91E6311D496251F7B574AEE5797E881BA1DB16AF40281586267D826C0F33A0518C26E6533E19EA0EBF29474A131D882A189AC03B835C16C34C9AE7A1C4D9F5159F85B8542284E0409DFB0876FA6488E6519867B5C53896867772210E95399A1733D2E78532B7651CA9704AC063DF086CAE4AAF65150093F27054F34E2849449C7680EF1CA1A0AC399A01A9B74484A967592CE85086230582518414C247BB7680ABFC2A04A35A20A851B73548A8E4CFC2B84CB5EC24108396C28498A6614790D56BF8D1B9F9E40BF574C497218EEBC06217C9BD361BAA5D0715E666C2D3D299346A79BE0BBE4B7CCD49F948A60438514129C126AA1F3875718922C5124728F09FE5437AE83194DDEB81F0D744FD2B9B59FC223E2792501B4932924FACC16C1E5444DBD6A823016B3AFCB46EF59CEEB49728AC541BBB6BB64B7E196C59910628C8CA22B1138D884842C387B594B544E5D99784B06ACC3B5D80BA81CD34739A20AF11F7735D645D9FF25C07F8AF9B5902524A1953CA2A58D6B796E3695A006AD6C703DD161C12C01B9BC995773C5D2CE59470C765C3F5401CC07885C77BFB3C15D7F766F0EC7CB3F601DBFC210D599093A21C87D82002212B06898A5A878D4EE913EB451DCE14A1BC424838D4797ED14D9EEA2473B304D6624F1725C820751A9D313CBDC79AC9A26548587FB41371C5F48A4DA04D37AB7189685AAA054853F0491A0388AE4B7AF4259969E29EAAA2B2EB9503518C7C53BA0E6BD20EA8355A63F1C481EB5E662A0B792014AE4C0981274D902759AF794338072A839B05D9D42C1EBB1A3DA33B54066D1A63024A3B1D1437B37A83BBE816075CF416275A6F58336905937105E63A1A017F87911CF0B41DAA41A5DAE3856A606E2A9333176628198B49D2517F54A9182E4BA877760517DC94A079538822251204B4C4A2382CC7889BF84923C09072F86BD1C5879ECC3A37678E6D031568C24012578DDE5CA01005B2DF71A4A0B0455A03AFBE7C366BF1B086973038FB5DEBD793A303B4C867B611772733F66574CB0D7C303563C389B2F1B46E98945A94B142B2B0D647521F4B58F12326FD86286A448909191BC600BC7578B0169A45C071C77F280C583788F9C2AA1200A73431AD56D23B20471BB67A627A594BA9922B1FFB75D2D030432A954C71235A9278857C3010A8A8906C070B77060FB831842140770ACB92E856C8A95E163D5181CAAD6A478AC9AE82EE27F7256F4D4CACDDD43F45CFA4DE4DD067CDCAB990059E901097D00E0EBAF40C5D5DAB009C66798489D357E760478CE884CCE5C95FA08ED106CE84660E8A4C90BD2B22634E40769AA0090A101C5DDDAD45EDC5\nct = 922014A568044CA7D9086946CCDA46596385465C8065A9BEF75A70EDCACD8DEC0BB08233AB0E0013CB4DC03F59052091254AA8D8895AE1E73A608ED4D913658FFACFEE15EFBDB2CA0ABC843E2FA32AC1DC6FAAF8ACF19E6D2FF14356DD4DFC6171470C9667309AB421FC8663807FF4C614126C4BBF4ADC193CB58465FEC7A70BD508D75838A349827227CAA2F1A4C02461646557A467C73715E4D8B309DE5FEDBB0D8827EA6503C814587CDCCF916BA51FF1B72A2546AC78C170FECF26B84D8D80F6F51131903C5982FCE030DB8C83A6C1D4304E72DC79D77D7E47C7131229FA8279820B627F3DABE4B64B356DCB6E982BF07B1537F656C3DD57E71434AE394FB9E30C14589378AC83D84C6800837445C4610EF536D8C8CAA31A52274434BE4CC66B6B21A6F28463796CA5CF0CDDEBF6663EF308D3066B689FE515F30D0F5B014E49E4971F7B68BECEE860EA549301753BF8FC95EC7574B51DB83389632E7F9291E20BBF20E898E52AAEBCAA3B9FC67CA7F8D63892F355D365C166961A5A3E07D7549E5910CCC06DDBED484002B7B8A0AD3F977FA92BDA8DE05D711C95486693BD79F4D43CDCA8D5FD162A400D8F33D7535774967943282C52164EF50FC337068A374B01D75757F9F36631C963E1981B83F6CFAB6FA528350AE7FBD39C795BA1967402065949296AE14BC734F12BB5559CCCE061BA8579BA3DED45E8C763EF76DFBA1099CEBC9CAD903C5703515FCF3C5867DC73C8C73E176154D41BD4A6F0C039BB56F6FD7806E0F6EFA0BD0F57BA4E64D759C51BB10523AC8673FB236D7502F68532778BCF6ABA52FF6F43A45457CDDB8975623E5A80D85D2119F1828C44D8D5D2610B5D2AFCEE960E85221531B2D0E9C67389B791820D8658D312B2F1C1BA567C297D3D9307568F84BB7CDA8962BBF35A2B41665732121C938953ED1784304B5907F3429C1038522CD7C29E19B33AE7CD8171C7EF05BBF46AA069F05495E31C2357A13D478971F4657FFE95A1F867832BA3DE2A386A46C511BED2E63541B51695B4CFF7AA0D7E453BF56F16BE0128D1D03CAA79C5260BF27C4DEC61497B47D7E7ED1A1795E5D4DE8EFD141A44DB98FD8588663526EA7382E7C36E5B6983EFDEF927BBD8B78E71B8328DA1DC87F84CADF0772E5E01E920EC0DBD625701368156D91D00D621BE1F439AC76AACF8931CC5840358C6DBABD03148CDE362D7E2DD2B98F6CB50B2BE7E8DF737F5044F96430A121F1A9B93A2E17DF7AAC2F17C2D9032F5DF61F98810167300A1075A81A74D3280C603908A236B6042B6FB9F8FAC23B7E4B967DDD3D3FBD7FA1C01A78E9AA44221E0273EBADCA5515F1F8ED6B07ABDD73E7245E865A2E735BB2D309764EB69D32BDB2DA08EA101FD86E6BA18019422F9A1771AE69DCF9525A2D4F4E7C56A80668995F3BFE8D37CB934F34722EB48C841E54277202156DAC0094901D061D9A5E7A9DB61247028728A41262946311662AD4EBB60750FCFAB13ED586E70E4BD7D45D5F3B6F6E2FE1122900948F1BFA130\nss = F87CFFE1A96BCDED4FE027DC8006065D67D0190B87D805135BDAFCB5EDB9803C\n\ncount = 91\nseed = C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3\ngenerateEntropy = dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde\nencapEntropyPreHash = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49\npk = 112B1DD09313B9A25B7094700639775F89B8D0314EEF0186ADF7CEABAC36CC9292C270717F27CAEA51B1AFE1CFE6B6A1CB1A7DA53C6715C9C9B2694BD5A581B733AD4841B229FB7A17BC213B969935C672D0993A94EC170BDC8B7C800E66BC6514F84FBC81C7D1C9417B79A82E5B3980ACC792A19C46D13A2E75A3AF791BEB401F7555793D94C0EE1B9E98A5B6C52777E537BFB287268CA9524A4438AD87A0E85279E474C5BE7740B7867D8B04781A2436A8D343F62274E236C736DC3C59D5B326563B9C86798AB14A6C9A0E67B36DB89A82AF690DA7016418BA2D6C435E39095BB81A0E49C01A73A31EC9159844D1A3EB233D16B932919421E6A342473A71DE629477183E8F34B2B7C8ABB7A3B6E516107CB5229D780B93417F9BC94C38BCAA58F34DD88835308C742875CCCF4928122199CD932148F48A94C5C2252295890BB4645761D3C2C0F33AB3E1021AA56B573E9C6FDAC37C83F678B97148CE573A244B0487F3CF771BC7B6A13FE53A6BA58854B87A67A6A17D6A301C85F7C061071B4DDB27B3F404DC402EBACB8254A0568D48B2D299BD831188886A65AEA5CD8D987F6017A2F4392F455C2B4F9B63E6CC1A27EA38F2588B0F8086D7A5C5E4B05B76D2B8918820CB8851704CA6D730861B512FEFB0A76B61401E23B01EA710C5E3B73FA716DFA6408A635423C61372592DBF174D6D811EEF7C4D885BCA5FE669233A141E43810AD10235CB59F824728BD7ACF17765BCD354A493AA60438F07D266D728B640CB07D50275BC2605FA6C964614B2C8143B37B184F3C30668662149BC18C6038706C12F0D31B896B69A7D588D0004497E4808D8C12253987F000168EA758A5B32C195F03F23A07C5A546A6607084CF79E073BC6CC1CB372E385CA827C490A42D900035BF735C6242031B8332BC57765ECCE4792706F1CBA0C7CC390E7BD3595AB876C4E397C58FC325C9607B0EE39692C31730EB4744E967E7FF8139FD1A545622EC870516B2925628BA782CAC845B2429C3CC0EBF7747F414E8D35CD4A91C959D2276404A5DF4790F4363104E6A0D1D60A48B65BBD92B417B51A5338CEBE36C0F218BF27968C05D99947E9B44B4B5B2934C538F85CD7C8B9E3C31637E14C5C0279CDD6386E20CA89A53671FB2F04249565491AC2F900AD380D1A68B67693B185F26A232AA1B43503398002085713CA4B2F94CBCF6E837B020404B7F519A2B520F93B901943C918393F26061346A0193CE9BA8A48B5C4B01B0EFA231EBA0528C5B38CD32CD5D22586494734FA746B411759303A51A12EC58B03FC99A1EDFB1CB01375032054878A6EC9DC4425945AAE387E7FC6CD399C90049854CF51B3DB690EB78A0A2DB04D05102DACAA9834620ABA427B5733BF1D1693643C88BD265AF0280ECC66344B81129C491B3998C6C70CCF03257C2D06115B72AEC35B4C8774CC7936C578B29FB3B0A5C66709363B73F41B08DB919CBE57AD817CBB5DF62B7836AF6FF4AB8CBB07C9FCB7E3D601B2117E6A7242ABB24EA96CA867B597E9E9B45C01ABA9B54D2D323DF8B38D3D37B72C2790E1041037", + "355F274CCEAC2714A92955B31C55D4903A85BCA55B2BC22C536AAB22557D912FE2234423E7BC0894BB5F846A2DBC4A0DBB11C51840059EC11BF6CEFA3AB473E1CB0F0BD17EE0BC3C59\nsk = B1C127D24808FB2B9922332832131C4FD67FE8A1A070AC8D17100BF9F6291EFA0BC8114D98F65C8F4ABAC3AB17B4241DECCC37688B881BCB68503B54379838BBC100B5BAB306327E7965B694644C470A5148666C7FA89872D39AFF60BC533C83F280ABFBC26F073331EF40B694AB25FEEA5B2F55196798B70681CAA21537DFB5746C66129775852E5850F57C2DB2E8A0E90530A57B387B1C429101D04096C3E0BB6E9AF19F83B1B0B74C47BAC678B0F2269798573FBCA5D8E687965B13E495827ADBA63DA8A17564A3E68037B3A4991993401C1C6B149895FFBC03760C13595035A713140EB7A42FF6ADFE6BB371C9AF5A686EF858A8FB7A63FA137492B53305685205B08D44A3AC8F8948F2B7BED9CACE27AB6265722D8F2950E0C9ADE053A4C4CA8E3F80A907A39E33DB78E6065FE9DC050A5A730595AE5EA32E38C512EDB79DCF345F1D9C238A1732C552AB8DB2CCCCD11822972896B323CC43AA03633617F82E89D63D4A1003CF9C5CE3379B1D53A63EAC57ADBC91510316ACDC30FD74A1A2E6C23584AD1CB28444F9231661079B0913E20B3278D8A2E8B18556F336CB750694066B6C82C5D267A903B624CD440D8E187D9E438D178C8394706F016B835E1522AB6904F80CC24358B7DD3BB271039ACC174164021E8A522FAC473054D5B4CB3BC64BB107C6B637CD6360E312A85A3B1E3D2B64436A87E81016ACB763A23CA9B7463023148B0C4888BFB18D9441841F723B9436B77B09C79FC714385A3AE97B5BDE0A2A0C541DCD2B668C696281389EC270BC6D088FC42506CEC85BCB4B611342AF0A61B1B9D75E0DF43BE293CEE6EB0413363716EBBC48EC6C361A48B9D871BD5742FEF2AB286094A92B508CB794F2F69A8EE15C2D748D8FCA8CD2284719815E75B3B0DF76298E48280BF530E09A34D166CD5379777D472F0994BA8E5629EA7691FB973F45869635B61B277C375606B911AA1228271C85B047942A52187BB231412B50F5BE423476720240E62B9D3CFC5B7AF5CE9FB38E03349063741ADE945E994A2D6492A92B1250880318B9B9CE845BA29BD3733228AE960663050888BB98A0FDC21D6FB34CFB5C1AF6D9B98ED6AE454C09B89B6067401FB30A17DD331A845C713715B5BD4A087BBC14CBBC9D2EA83D0F9B0D56D939D01B7D590B3082D2405A20724E2C44B5123BC1407B11DA3DE5889AC52B7B7821C4AF1303D3959EEF3888B8847F3E0695B5B844E8E3C221718A25057E707A50E0159AF4462BB1D103B9057FF7FBC1740BAE1AFA44138AA2B7E3270CF80A6AC745CF701040C97253133EA195648E929E6C6394940B6ECEB18844F1C862DA6597A46F64E0CB5D2803EABA4A08110A011A32452185A6425D9D44B43463893369514957592F519C22D2B06BDC762C519D5CB84E9A68456AC60AEAE85AC6453DE2BCC103E32DD509309FDC08E3B3698A193D83D62DF74719703BB5F8CC5DB7B88B80110D74D6949D00469B840FF7FABDD4C0CEC1A097A6117C28046B06B82C8EE8204296428AB703840ACF7F3333D742726B114D3292B3154B2C4095B6D465657EC0780C488A0C60443717109363C45777271955135E60B46104BC18BAC09A18690B37C8078A22645532112B1DD09313B9A25B7094700639775F89B8D0314EEF0186ADF7CEABAC36CC9292C270717F27CAEA51B1AFE1CFE6B6A1CB1A7DA53C6715C9C9B2694BD5A581B733AD4841B229FB7A17BC213B969935C672D0993A94EC170BDC8B7C800E66BC6514F84FBC81C7D1C9417B79A82E5B3980ACC792A19C46D13A2E75A3AF791BEB401F7555793D94C0EE1B9E98A5B6C52777E537BFB287268CA9524A4438AD87A0E85279E474C5BE7740B7867D8B04781A2436A8D343F62274E236C736DC3C59D5B326563B9C86798AB14A6C9A0E67B36DB89A82AF690DA7016418BA2D6C435E39095BB81A0E49C01A73A31EC9159844D1A3EB233D16B932919421E6A342473A71DE629477183E8F34B2B7C8ABB7A3B6E516107CB5229D780B93417F9BC94C38BCAA58F34DD88835308C742875CCCF4928122199CD932148F48A94C5C2252295890BB4645761D3C2C0F33AB3E1021AA56B573E9C6FDAC37C83F678B97148CE573A244B0487F3CF771BC7B6A13FE53A6BA58854B87A67A6A17D6A301C85F7C061071B4DDB27B3F404DC402EBACB8254A0568D48B2D299BD831188886A65AEA5CD8D987F6017A2F4392F455C2B4F9B63E6CC1A27EA38F2588B0F8086D7A5C5E4B05B76D2B8918820CB8851704CA6D730861B512FEFB0A76B61401E23B01EA710C5E3B73FA716DFA6408A635423C61372592DBF174D6D811EEF7C4D885BCA5FE669233A141E43810AD10235CB59F824728BD7ACF17765BCD354A493AA60438F07D266D728B640CB07D50275BC2605FA6C964614B2C8143B37B184F3C30668662149BC18C6038706C12F0D31B896B69A7D588D0004497E4808D8C12253987F000168EA758A5B32C195F03F23A07C5A546A6607084CF79E073BC6CC1CB372E385CA827C490A42D900035BF735C6242031B8332BC57765ECCE4792706F1CBA0C7CC390E7BD3595AB876C4E397C58FC325C9607B0EE39692C31730EB4744E967E7FF8139FD1A545622EC870516B2925628BA782CAC845B2429C3CC0EBF7747F414E8D35CD4A91C959D2276404A5DF4790F4363104E6A0D1D60A48B65BBD92B417B51A5338CEBE36C0F218BF27968C05D99947E9B44B4B5B2934C538F85CD7C8B9E3C31637E14C5C0279CDD6386E20CA89A53671FB2F04249565491AC2F900AD380D1A68B67693B185F26A232AA1B43503398002085713CA4B2F94CBCF6E837B020404B7F519A2B520F93B901943C918393F26061346A0193CE9BA8A48B5C4B01B0EFA231EBA0528C5B38CD32CD5D22586494734FA746B411759303A51A12EC58B03FC99A1EDFB1CB01375032054878A6EC9DC4425945AAE387E7FC6CD399C90049854CF51B3DB690EB78A0A2DB04D05102DACAA9834620ABA427B5733BF1D1693643C88BD265AF0280ECC66344B81129C491B3998C6C70CCF03257C2D06115B72AEC35B4C8774CC7936C578B29FB3B0A5C66709363B73F41B08DB919CBE57AD817CBB5DF62B7836AF6FF4AB8CBB07C9FCB7E3D601B2117E6A7242ABB24EA96CA867B597E9E9B45C01ABA9B54D2D323DF8B38D3D37B72C2790E1041037355F274CCEAC2714A92955B31C55D4903A85BCA55B2BC22C536AAB22557D912FE2234423E7BC0894BB5F846A2DBC4A0DBB11C51840059EC11BF6CEFA3AB473E1CB0F0BD17EE0BC3C59175EB63C3144108548720CE7EE0F43A9FF3F52A9924EFE9F2F59318BB93C86B5E15274A8E2BC08FE818B117BA28C5DFAE74D54FCDF6F20052F79BE333EDC8DDE\nct = 3E4CE5CED61DA4C323AE10DB3EB49FB68477E49A4D8A7EB19064F75CD640538F0AF831553F7690E3531E305813C18DEC92A0FB67A341F6E551DEEB0B3438A1A22391AD168A5FC16D6483D0A0F2002D5F43153674B07F6A5C5E337E3351A5DBD3C315D460541EE170E2E7CBA41942C1753A401E230D50D7B80884FD269F913EE4F326FACECCDABE1510EB55FAF17155EB4568F19F4E396213C9A7A252E1815AA0FEDF980409F218D5BA5B383BED0D331D50053DABD30C98619DA2223D746ABC4486EBBE371E33313AF8225E435CBA697EB1B3B99F7A209640C4C82A99CAA9C9642ED63878CC886CA77C45360A2234550E68EC486BD584E1BA6BF122AF1B931CA3D7C6BE30C281D6C5F6E6CEE2C9AB2CE047E56F8F80CE3EF606A0B0DCA9CA7B2B5945E065FD6E50535A3DF08C2FC90B2F02A2638BCF88679D669D7C16E32586CA509E960B73032F223A65EE1286BB54F0780194A0961684E5D4D1E09D147068742488267781305863FC1E2F4EA2CD37B1E34F4179C75F9BC433F279791A62A1D3646B57784AA401AF9AD6082A8F2850602B8EE534250C68223B77E23C7D2A7740D51948BDE1ABC0816F2EF176E9C15AC7A4F40775AC5B9641B7F08C3B084D79FE86464CB1848AF41E52DF272DAC4576319923E22D6845867422E0A07C4AAD7A60B8CF2F344CF82F492704D60C5621F798F9911B24BAE1C04BCE123E40F35A5A78DE33F89CA5BC310D4DC5FDC021159CCF412B875A985CEBAD40E723C9AB585267D1AEEE9737B0422C63F9D84660927A29C88E78660CD989BBA8C29CA60F83FEC307D4C9A676B49A4DA9DD9396E8A7A33CC72842378CEA52F9115D44E99D78B9996D2C8DC3C4198C67007E1F2972F434989B8450C8F87AA7BCD03AFA3542E937AB649FFD3E66E44BBA1747BCA1514C3B00F9B00391812D1AFE38524AFBD89D09948FD648D7945EE3DDD0BB0C67E063362B70F7C96EF09D1944CEDD28C371FD5A4F8D7BE55E47E052D72C95C362D8D1D1C83CA29F70B2422C1F909D14C4D404C39F2AA52EF69B936AE27E0F38C4B564E47399C0E58321AFB00BFAF647ACE5B18582968987A20766CADD4DD7B166DF9CD2DF9B3D339E70FE5BECFCB3A486B0A7CD616CFC8B439012C1A6E87DB9C0BE4CB9566051D5FB0712C5C80AAF79974EE299BC7526D2E351A7A8CBE2F35196C0028CB8BC451049876BAB7D2B6EA233A16BF2F052BDC82CDD43DF3D4DB55FC52DB36FA70AE7F98601BD6C89282AC94FE34854C86BAD00A597A5A684233929F1CA77F6200BE14E2D3F93D089089D800C73DBF4416DD831E175522CADA8FC004FE5AF3581F34FF2084D34ADD151AC9EC634BE82D9C2E149FA94ADF14B03827DE33B1B08C15EB890029713AEF895B413A1992078C1CD4ACADDAFB0546BFA8F940BE6393DFA51EAD36703900E35D8E8D05E02920A37F2F5C4BEC938FDB4B5AD058A9CEDA464A8D1A70AD936A5F7CC55B37E3F1651C3D8CDFDD7CFB1CB33B7E5D59F87E1102B3A534713025B6855DBDB7958708897D3\nss = D2D4A23DEC18FD2C413D0C64D58C1D14E19D2A18AEF1CB038D14C3C2E79F6A69\n\ncount = 92\nseed = A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8\ngenerateEntropy = 690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f\nencapEntropyPreHash = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467\npk = DBF001BFA28B07E21ADC142C75111B9785AA2109A795AB792DE4CB7B6298A504200F8850D32CC44E54182761A1C9C9BA591A9FA6873A61025515B068099BB1E63751C5B887D283077F86B733E4344D13310CE12D22322F254A0E92779A87067D19C53C70DBB927E14E1F2892B5273949428EB4C70C49DA8AA7FB87048961DB4892A6F89F18F0BB69347B9575025A964047AC7BD2C7472838383A6072F8338B23AA07D6B7B221E18D4E3C62641916106694315A2FC5BB88C6D664667680DF556C3C046398A88328421F32ECB758BC64CF246815A25922021DCB67C995FC72CC6B46BF5CA9EF3998535AC5CFAB70AA54318F9532DCD138A4C03E2FF5024C52BB486BA7665B27610B822975C412331ED6C98E66721DAA1897936371113A4F17D96EA735A5CDC019809C3907C03FA950C00EBA9DFFC69A902151A39163F2", + "931E1C0271D491562E0A87FDF7B7846C31151017EF08727DFB68F22A8585295659EA358CC1B85C9AB4D107413225B8259804B31850EB347E1FD37F5435617A7A07B15321CC204B1A6B7C30D67E91C088A458BEF5CB704E6B662189A9C0079E224A94E21502C0F1A4DFF6028EF6645CBA38C0C86EAF673E9B2613620BC216914A9781645FC48E33CB9EA06182637439F1D1A19FA50CFD3B5E2CB8310229B74ECBAEAD4B079D535521B8587A2995FA9B8C6694BE6E432343C97C16CA23BF53883E23CC38F10C38E54F5639B9FC0943A4F41CD0ACC8DB40CB12E644CB74B9D4B858F7D6767830B92381A42368476CF2602ADB9ED08B35FF5C4D1EA93C94AA75E218779825401D859902D19822E9820D86C7E57562795B89CDA97EBA773070BBC502884A6F437D7EA7A459C0764CD943E0B6A5B61B8358530459685E2842AE9AB867FA712172207E692A7AFFA872323779087547C3D8B89F368CE078ACECD55AAFD5305371A5BEF24FB255211B2169F4543927C845A3049F7A88513A682303960C2D12BC277656F15738C4368DEB70CFF2A32A1D179F4FDCA57812CEDB21B356E0AA63270788B510E58B4BF613473FE931DC80A9CB8BAFE63AAAC3913936C8A939C413CCA10A1277409250B5DA321EE5C24AD3D093C1C7095FBA34B81380E5DA561BC039E3A8C15FF3982A7938BC16446A3AB2679A50C2E5C1D1A08127DB4CEA30340B5589B2327988C97B78F003D1315DACB301520A11F9F0B4FB33CE7C0203FF11C6A66136C0AAB83928C145F4B968783B131281F2153925DC13AD133FCC5247B595CEF0F03FF0DA0A429C0DE9A54F66C03F1A616C7210B7ED3624FDD27E99F38472867A9283C6B294B0D7014CF9EB62F0D7B051B190F093450453C056081370B45F5EBC4C03808FBB5C6D8B659BD22612C2872DE9034B11C6AA6D356B2BACCEA0F909DA0C775969C12FD5BB0C8A9BED5172A9358E01C29D308636B5D668F5B2C9DEF1380BA23B5C84259D887D3DC4882702B41D99C72C800DD5B19935D7722610741A105C1D227C38C5665CD5A6DAAA991A9868499830C1697FA430BF4F95B03004126FAC283A167281E4B847EBA8487B0032914EDB0B67B1E320C25BAB50499378115CB07A9000E0156C9C93C1D90693B9C22623A3EB15618FA1C470481C4CF292B7462410D057C2E5851E08E31FD88AF2F84B0CF79A88DE834C1F17C7A5FA17D329CAA0\nsk = EEEB8866B17CDA12A45FCC6F9D05AFD103835147647A7301EE071366398473C8103AB3B064E340F4F9866190ACEDE02473FB49635BC38DEBCFF0F34C5175AE0EC025AAF19CCCD46D658C2A6BA62B50D1452B09C21B430EE9A3CE05D36A8E1AAB2BF0185F35664B4999CC8C0DF049C01056AF6AACB025708C184534F1172B28FCC94AAC2FB7012E20443F11F43478E7B1DD8A5C7D9B5A8818C0D2259C7F710F51003777B060F8DB5FE06C3520D35E97F6B5792B0AC3304349387B637686CAC1A6E45149173041FD7C3CFFF5A398BA832DBA04DD7179D0768122A701F4E0BFA48149FF140E2978A723FB985B939458B081E1068EE5102E5F540365E6ACCBB8C28DB84125B21E8D04622412C2F075CB57019EB828616CAA245A8B099A01BD86268CF491823E440E984335AF59924FAC1D43263AF725895C717E827532D35C7DA9AC1420B46AEF13C9F33A427BB5A1BC646F7B54A21760527D303BACB2A21AA39C5577BCD5F416F126741FBA9C2CF9401EC20A14E9A7BB927CC8135BBB0C3180696093289F4B19539C58655B8698A5D1339C9490BE7C04AD3311FD422045A5027B203407CB5755462C21AC51F523389E803F30E12FA9C0AA7B4A1FDD85C66989AF558CBA916C9A037AC7DE1A3F7F1B5BD3208FB6F28661696AD0DB88D10A3B224A5BB5C99CCC96820E153E478AC579C65BEC5A3D4B85AFF1C4AF5BB222E7AAAF9E9149AFD11EA5E86990913D2B543913942D148639D9815D4A8908362A84BFB6AD20B8ACF9596DF4187009E7B773070450010744712F9E7A9B8E9624E3E2B1D6140A9E4789775ABCBD2657AA487740314EA1E446DB5C09746ACCAEE29783B23EBFB255BA5C9706F1254703C676EA09801762E9FA45D858732AE7218B37107B3708EABA05D2C035FD447CEBA46EE446AA324BC184E7B929F7513C16BFDE5C5E55C05E6B5041552C17DD223AF273CBBF65A44B4B6DABD51B341464A9993EFFD671481592C5A655D116B963975006B13503BAAE38332248F58656620098F42F97A813DFC7B4DF880E5E783AF5D833B89079474040AC05A6A7EC5E9EC1BDB282443C736514514F1CB7455958608A62503428464D89C66B209C417445416A54AA66234B1A5BF1C0C3F7064B6D0A7243E170B6ACB01C033C5B1670A3BA6801024C03B24CC1786025FBC56BF04F3B241E4BE701C9764938695BEA4316ADB6ABACFB44F2041D2C29BB867379374B211E990F194B872A7B684A212DC179A4ADD943AABB1E6BEB93F5CB100FE342D0781AA80989406571D1B79D08E31AE15B81740A22DF02270F920EBFAA3C9D74392CD64E71F363DF221134E9BE32B6B855FB76E15B5C91CC6C3F750AEED71071A0803987CA7F35882AC31413A6001A6023C0A183961722B6EBBA16F5577D95BEA2C5AB446AC8E57ACC96281A07599A8D335C2C12388BB0CB9F8633CD2251C8A7563B396072D0CF6E7B8E3AF2192E5731341214C30708E128914C124973E759D4221F1735386B874905220C41FC731A22B9C665CEF0CC5353B799399905F0ACB549F13C6FA56FAE2907D0353FF2054ACCEC40310A2C4B62AAC3F392B014BA88FC90EB868693EAC83516336BAA601F600518FC820BC8B0E76C66DBF001BFA28B07E21ADC142C75111B9785AA2109A795AB792DE4CB7B6298A504200F8850D32CC44E54182761A1C9C9BA591A9FA6873A61025515B068099BB1E63751C5B887D283077F86B733E4344D13310CE12D22322F254A0E92779A87067D19C53C70DBB927E14E1F2892B5273949428EB4C70C49DA8AA7FB87048961DB4892A6F89F18F0BB69347B9575025A964047AC7BD2C7472838383A6072F8338B23AA07D6B7B221E18D4E3C62641916106694315A2FC5BB88C6D664667680DF556C3C046398A88328421F32ECB758BC64CF246815A25922021DCB67C995FC72CC6B46BF5CA9EF3998535AC5CFAB70AA54318F9532DCD138A4C03E2FF5024C52BB486BA7665B27610B822975C412331ED6C98E66721DAA1897936371113A4F17D96EA735A5CDC019809C3907C03FA950C00EBA9DFFC69A902151A39163F2931E1C0271D491562E0A87FDF7B7846C31151017EF08727DFB68F22A8585295659EA358CC1B85C9AB4D107413225B8259804B31850EB347E1FD37F5435617A7A07B15321CC204B1A6B7C30D67E91C088A458BEF5CB704E6B662189A9C0079E224A94E21502C0F1A4DFF6028EF6645CBA38C0C86EAF673E9B2613620BC216914A9781645FC48E33CB9EA06182637439F1D1A19FA50CFD3B5E2CB8310229B74ECBAEAD4B079D535521B8587A2995FA9B8C6694BE6E432343C97C16CA23BF53883E23CC38F10C38E54F5639B9FC0943A4F41CD0ACC8DB40CB12E644CB74B9D4B858F7D6767830B92381A42368476CF2602ADB9ED08B35FF5C4D1EA93C94AA75E218779825401D859902D19822E9820D86C7E57562795B89CDA97EBA773070BBC502884A6F437D7EA7A459C0764CD943E0B6A5B61B8358530459685E2842AE9AB867FA712172207E692A7AFFA872323779087547C3D8B89F368CE078ACECD55AAFD5305371A5BEF24FB255211B2169F4543927C845A3049F7A88513A682303960C2D12BC277656F15738C4368DEB70CFF2A32A1D179F4FDCA57812CEDB21B356E0AA63270788B510E58B4BF613473FE931DC80A9CB8BAFE63AAAC3913936C8A939C413CCA10A1277409250B5DA321EE5C24AD3D093C1C7095FBA34B81380E5DA561BC039E3A8C15FF3982A7938BC16446A3AB2679A50C2E5C1D1A08127DB4CEA30340B5589B2327988C97B78F003D1315DACB301520A11F9F0B4FB33CE7C0203FF11C6A66136C0AAB83928C145F4B968783B131281F2153925DC13AD133FCC5247B595CEF0F03FF0DA0A429C0DE9A54F66C03F1A616C7210B7ED3624FDD27E99F38472867A9283C6B294B0D7014CF9EB62F0D7B051B190F093450453C056081370B45F5EBC4C03808FBB5C6D8B659BD22612C2872DE9034B11C6AA6D356B2BACCEA0F909DA0C775969C12FD5BB0C8A9BED5172A9358E01C29D308636B5D668F5B2C9DEF1380BA23B5C84259D887D3DC4882702B41D99C72C800DD5B19935D7722610741A105C1D227C38C5665CD5A6DAAA991A9868499830C1697FA430BF4F95B03004126FAC283A167281E4B847EBA8487B0032914EDB0B67B1E320C25BAB50499378115CB07A9000E0156C9C93C1D90693B9C22623A3EB15618FA1C470481C4CF292B7462410D057C2E5851E08E31FD88AF2F84B0CF79A88DE834C1F17C7A5FA17D329CAA09BC32A138A2FB5B6072464172ABE0FD97E9EABF357C3FA5391D94A415B53ABD381C38C2CB5CFAFAC81B96A810AB749B61806B6D54C9F8CF4BF1BE0192423288F\nct = 7C87310316CC1AAE495EF575650D79BC38E091B72BF809E003C71ADFF6C4729139CE41CB1F669F1E1281F223781293E3D9AC647D16EA0D08402CC265F1F4C26D08B7D4651D88F2332BDB9F9F3B417AFE26A433BCE1E8A975D86B547E77E8D4189BD9E46F6F2842166D6389A5CD399E735686BDF4779991C1242E3BFEF69552D6282C476AC51EDA2C9D7A4E3100F8BC8FCDFC449EB57DA0F392CD889BCF45C337A84E48E3B83AD72C50C9D2905A4E22E59CC73AD7FE85D6BEA30550BA2BA5929A3847A9B78D886CA1B93E0C4C14DE5056360E7DD398CC271D96A7950F4C439526EAF8505A37C0DD6AB037885E48D8B66E9C3FB3C218D74AA7F31FCE3FCB58C2FBBCA23D78F994A4465907A6328C2E35D83259CE735CDEE26D516BE175C2BBD5E24616111FC7A3D95AE11D035AF9497BA41692A12900926E8FAA3A80A5349269D2786E4A1F9F57EA473C6173C2C88D6E4FF2371EA3FE8261C21C63D7E29AC72A2995762A378A45A9C8D811F2F92229967C3A7A409452F4EB01083FADD41A0948DE85363733B7C0349DD1FD4D231ACAB563CB5A908A19B819E579AC1A599F5B8135C2794B34A3314D1B8559961FA26E9396BAC778A6697363EF60A60158736C92F7C1BA912791AB962B327E6369C6EDACF69FC9AF49379387D5E8C4CADEEE9B3D5EEDC6919BE78A199DF3341F23678C6D657B5C65279484F18E4A9789B675085EDE2D55BD10311617649DED74918A752A44FF9361D7402EAF97128BED4147EF3CA81B159B304588D22802A2E05A0B2AC5031F9162FA524D28EF0381E166BB81FE396124C4247082EA6DD755F48D8B419BD6C52CAD8CA084CED3AEEA060642FFE0FC7E6C1630D056B449FFC1DA8E693F64925FC179938CF5283F6E3584EADC904338857396FE810F4F3175868578BC21608EDD7A8109AC5A8635FF8C4C3C6DA0C3C618CB2B3448E31E8414D16EA50BAF6A4564F686D12692BFE4AEFA5A0E57B84C55589D0B4CEB2F358AC33254453E001846A2C7C299DED877A07A28D0DB5E7A5E6D41C246775F951CF114F3CE64AD839681C17E995CA123CF2A24006400B4969B99E75D066B774FE4E994828FF84F171D9C618FD2D5A01EF845379831051C84A734C40871CF53935FF8AD0954902C017E8C323DD751CCF1", + "4BC50638A31629E4FA70EA6E912B6A6422AC19442832E8A051E7019A820BC6AB81CB9715998F34014DF73DB8F62F5957D53D1FD3192D9F76CB8E2587DC9A1738207F956F6BC706C3B3B7DB0C578D220F30EF2925A7E35CE01059BE2B8AC6561EA7AC253D5F50706515947771C052B015F61FF347ECDFAA1C895AF5BC7E8DC7463A301221AF6C95EB65B8FCD77B1CB4577F5053E34766631E75A0A320EC678ECAFEF5084E514EB48AB6490658492BDA71D6ACEC26488D29DFE809F576FD7F5F38ECB4918657E4C8F25FA09932F435F211E41B207A61D60C9BECFD50FA6D498DE3F4647D6AA922D5A82B33CE96399B67FBE369DA888179F95F655122E0028512944875308EDE8CE87E67A6\nss = 52E36F81DD9A23FB9BB2363C31B715106D38520A31A3304CF754A9432E757224\n\ncount = 93\nseed = 92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2\ngenerateEntropy = 32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884\nencapEntropyPreHash = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4\npk = 2DF84A0272C13DA5A495942BA848AC92D302A98A3E55937B8B1B49FE588BE32A540EC90B5CEBBD90D1B80DD24D32EB85FC041A7CA307E522B8C5FA9C85BC258C8ABB9F2678D29569F313A1E660A2454730261A6766945CE42C140E5181C68461EAF12D1F185C358233B9BB4902FC5089F851BAC83CE3F07BD7B185EF08626D7029129703334084375BC5BA27BA023CA6722319A916BAAD529715661E3A413C8137CBBB206E313906DF1CA77CBA73E5499F54FC53047741AF2341D5623278F76131AB47AF10BB4DEA8F493B6C0E4829ECF4C425A46D21755E93E5A80D0A927739848695BE93444A98A45D02D1131E493DA5A0A1117B41D4AB3DB35A7A2E95C6055BA70EF159E7AA0DD5452598F91477087BEF1396ACD48E747B962205AF92EB99FAA809B4BC47EB93BFD3860102D4ADCBFC39BE80024550656C42785A6788C7A851B107823A02A3DAA4CAF25097F1F9AFB29416DBB360C4A824E3CA2A30E19F94B805DE181D0A028E685C378DCC225112899A6B79869109CA4B094909B21042C179C6CDEB22564CFB6F89135022FCA3028CAF7ABAB19A4045DD5A60721C6BB47AC53E40CD932511F2E5473D3B4CEEB44BE1A00E090A886D345B13A58620C49CA0893F23058412054AE5069C1014361CFB0379C2215F330ABC647114A3C597765FD014C64C8C1B1B45B3BD02BE9D5A55B0CACFCE297581FB48FE0256F4C0CFC84AAE1C542F36730E5F10795C72157C653210686801210418B549A7398CA8B7C70ED007CB153D2A55178AE23A5B095EE2D116B9F3A1A9F19FAEC40D75256CDF76AB8E393210D3AFAE375A7BC384799A6EFC5B76F287499C6701368B8DDC219A9F2295E6E01D22C4A50BD08179A08044B702FFD786FAA088F867B63B951A92751CB0F839CD554A83745444C3BB88D3609A9A4BC2E0BC73108A71CC7534217872539BD6E942CD36A09AA0374A3894D279A1F7C38A56E7C0298948C330B8C3A5B6AEC3BBDBB87384677ADA78017564A7FE40C2983A9ED3ACBCE5E29E3A78502952A9540A44975572A1512B1D4284D9BB528E538F43A15216F4B4F2A5208E06C43896A19C416C99C3B677564975948468792EDB6532F9B0567F407FC6D6C302766C6D1373BF78A18896188CF20CCEC39632269F6A193DE5EC5DCA85CAD6BC79023C691D5682643B6F314827E0B24539E2AA91123B3FE42308F041DFB6C876D079D60A3EF5735AB8A36ABAE34F4A12729BE4A00F753C7E4699572375E6C7B037948684206C08A27EC12B26F7349CDACC3559AC29D5CBC35C310870597E391AC4E4C02991096F37492083BC1C43304BC3D5925843622494C735942DAC8904CF195387ECCDCFCC8A999B6D1B744A542359E6B167F91022BE1660BBD218A6A6861AA17C57152552172F38B43D5281956CAA77DAF9B94CF60CBF08CD9D9B4C1EDB6C4A17BAE3B36800891910C280C3E7CBF4AA11F33A7C70E3B419C2B2B9A64709C31878F913FB934D77B4C36E329BA98B44F394631E0A289042061F527D67446D6AB55CE7B43EE1080FBAE67085A2A03B36CC9AD9B5B546156C3C5A79B092A67912A19575F6B5546397C15AE334B451C3D919422F28B70727C75FB631A2AB012BD5971B5B2B75F80E14BEC0494BAEAE3C7AE947BD69827E1FB86388052C3BF3F8B4CD25A568\nsk = B27CA8D40A1CF8AAC1A62553FF541EF56B4B4E352E38C0AE8C2CB2240C2D2525ADC52B1953A1C239E3ADD71B5F7693196875BABF8B31EDC528F3B320E6569997639F1C9B5279C38D5DDB3B691B0228AC4480D45077DB55BAC24285C5820C49BE25632C4AAAA23ED84E10A1256D9CCA9B584D423A9FD37276CBFC5953C9284A4097BF71706069AC413AB857C64EBD179EB75496170778AFD74180D877C9D69E1956450B1289948323F64227960A0B24B442E78C551C5B35E89B34B018B80BD094F7594365195F44C05BACBB2E0A976A86559BD6B23D220B5C900375C6B188FB353C3B064CED669BEE6751D5D22659EB89900A92B7BA84EAB58B7E95CB8495191CA0491EF75A3ABB9469A7939796C2F8C15CA22283235852B0A96DAEC403C5C057B5AC91D09CB16E01BB0D078170E0CE9596B913E953C5AA67BD8A2FF20C0261CA814F334244886DAA0694368293FD858E14E23D13E66AC89A58867574804786C4C48D2FC003336C002A7776217ACFE7084588455A0A85B8AA51C33E99B1CDB75541855577911DB00475DF42168E7A21EFE57402303DFE37AB5BF10200395550A1639DA2AA8E358748EC38946BBD3DFC27DEB08F4F017ABE33A2DF3B9B96CAC0E8C261E487CFFF31A1484CA5E04036797CB4FC87AE6CC72F9EC0835AE2B160B425ACFA8B75236D92870E4D43BFA7EA5C98827F95DB6DD4200068650E3D8812DE827C3F660CF8049933DAA52793AC10F57AD8F2A7445927CA6022D5A485F9424662A175B2A6349B248AAF4853BE709D42228C3CE3B13990794B9698869842B81649CBD9482C2435886441ED9A7927384371D02005A514717ABEC398BD183B321134A4DE85A1FC9B72F7268CCAFBAE289C15DCEC18BC26B81EC43C6B8A3919625165617D60C33F1E6B04CD5492414A15BBCA5CE84284557C9CB481A951FA5DF2E444E2C20969F38284E60FF15B0EE707115880BC6D3834230C7D22C7CD69229D1EEA957F58B2D47B11CA97C926070CF1C1934EF83F5A26241C7C73959C8A0501C2C1C70671987243635FEA56CE6EE292B1D6AA26C4CDDFAA1751520FC3218E7E20C13C6A1DF4835C7D6C0BA45923CEB2AB40FA7FE3732E47AB652309CDF28091D8D86308B73F90D86995220ACDD9C544C95FCD24A77E7C90F2F15E52AAB595E11B1AC0799A3CA95E0644771420AEDC777A9048FA89CE94780C8F2B903548BD46A2C22E453B68736F5CCA6C35EBB027C0C7035678F7F69A9CA02FBB4B23746759660251F6757BE3AA1767D7280AA75B60A7A0CC892F70F67CDA886CFCABB451A36023C688D7AB5E0A3B5BC88514CED3597A594D0E28C7AA25859E57BE9FB12691C047A8A7373FE1695AE742027A8F5630CB2776721815742C66A4BA0C7E7E8B8281144B80288CC7296BFC8625A2CB995B548D48294B2FBCA97D375B91203392CC27FE835F62DB97B14739F6C8B1880A53DDD388E2636F866416817A110258A098D9AF4458A64C68654E97099746B9B9E23ADAB5653970C00719B54E4A2D2092CD7BD62AD9317357E35224184A4E24B4A58014F666B33E1530365070B73AA6DA432D04F2588F34AC1CB3B3F7FB4AB200B459966FAFC689CC40ADAD0C26108859A2943E2DF84A0272C13DA5A495942BA848AC92D302A98A3E55937B8B1B49FE588BE32A540EC90B5CEBBD90D1B80DD24D32EB85FC041A7CA307E522B8C5FA9C85BC258C8ABB9F2678D29569F313A1E660A2454730261A6766945CE42C140E5181C68461EAF12D1F185C358233B9BB4902FC5089F851BAC83CE3F07BD7B185EF08626D7029129703334084375BC5BA27BA023CA6722319A916BAAD529715661E3A413C8137CBBB206E313906DF1CA77CBA73E5499F54FC53047741AF2341D5623278F76131AB47AF10BB4DEA8F493B6C0E4829ECF4C425A46D21755E93E5A80D0A927739848695BE93444A98A45D02D1131E493DA5A0A1117B41D4AB3DB35A7A2E95C6055BA70EF159E7AA0DD5452598F91477087BEF1396ACD48E747B962205AF92EB99FAA809B4BC47EB93BFD3860102D4ADCBFC39BE80024550656C42785A6788C7A851B107823A02A3DAA4CAF25097F1F9AFB29416DBB360C4A824E3CA2A30E19F94B805DE181D0A028E685C378DCC225112899A6B79869109CA4B094909B21042C179C6CDEB22564CFB6F89135022FCA3028CAF7ABAB19A4045DD5A60721C6BB47AC53E40CD932511F2E5473D3B4CEEB44BE1A00E090A886D345B13A58620C49CA0893F23058412054AE5069C1014361CFB0379C2215F330ABC647114A3C597765FD014C64C8C1B1B45B3BD02BE9D5A55B0CACFCE297581FB48FE0256F4C0CFC84AAE1C542F36730E5F10795C72157C653210686801210418B549A7398CA8B7C70ED007CB153D2A55178AE23A5B095EE2D116B9F3A1A9F19FAEC40D75256CDF76AB8E393210D3AFAE375A7BC384799A6EFC5B76F287499C6701368B8DDC219A9F2295E6E01D22C4A50BD08179A08044B702FFD786FAA088F867B63B951A92751CB0F839CD554A83745444C3BB88D3609A9A4BC2E0BC73108A71CC7534217872539BD6E942CD36A09AA0374A3894D279A1F7C38A56E7C0298948C330B8C3A5B6AEC3BBDBB87384677ADA78017564A7FE40C2983A9ED3ACBCE5E29E3A78502952A9540A44975572A1512B1D4284D9BB528E538F43A15216F4B4F2A5208E06C43896A19C416C99C3B677564975948468792EDB6532F9B0567F407FC6D6C302766C6D1373BF78A18896188CF20CCEC39632269F6A193DE5EC5DCA85CAD6BC79023C691D5682643B6F314827E0B24539E2AA91123B3FE42308F041DFB6C876D079D60A3EF5735AB8A36ABAE34F4A12729BE4A00F753C7E4699572375E6C7B037948684206C08A27EC12B26F7349CDACC3559AC29D5CBC35C310870597E391AC4E4C02991096F37492083BC1C43304BC3D5925843622494C735942DAC8904CF195387ECCDCFCC8A999B6D1B744A542359E6B167F91022BE1660BBD218A6A6861AA17C57152552172F38B43D5281956CAA77DAF9B94CF60CBF08CD9D9B4C1EDB6C4A17BAE3B36800891910C280C3E7CBF4AA11F33A7C70E3B419C2B2B9A64709C31878F913FB934D77B4C36E329BA98B44F394631E0A289042061F527D67446D6AB55CE7B43EE1080FBAE67085A2A03B36CC9AD9B5B546156C3C5A79B092A67912A19575F6B5546397C15AE334B451C3D919422F28B70727C75FB631A2AB012BD5971B5B2B75F80E14BEC0494BAEAE3C7AE947BD69827E1FB86388052C3BF3F8B4CD25A5687EF43A72EF04766F1E899D25C9A005009C788B5FAF985123CFB3FB97975DE26DC06C5BEF7B6508409DAF847A64C8D30D0974FD3BA7476DC76C46B458A036D884\nct = 4C5CE3680E598066FFE1EE7645E55CED8C9A55B6902A491AEB9B64", + "47F58B6184343638F13F4F79D067A0A8A4F10CA355188FDE778B848886E2F38979B5AEF4F14DD0B47E7A95AE839F6A1945D9B32D830189F3994C43DE711F71E8439BCF957B62A8F97CD869EE551D167B4C97E209B972E175947E7C5423EA86B5FF5D4004BBEA6163EE2858FDC9D8A04180D01AEE7E75B8616BD1E37EF33DB050FF02674C3D9C58AF7C1A76D79F4940E29B3DD1365C8259B2DA36E8B8A7D05887BFD3E145E8C78F01CDB63FEDF457A1AF4746828734F23B947F68D217E3FAD14D7CF15B26651915C371D3CD4C58094F15DABD0013E7878EB8ACAAB33EFDD47B2B20688A85A3F92C6A4D90F6045127A17AF0F8643B064A4A30A983F7DDDCE4D8893A3F964578D0529113D9D248E09A41792D4053B8B04942E866AD0DE54F8FE31B64024E647EAB8A10C87526899C6FCE476314ACA7B9B5E2F809721D2660DCDF9FBA5734714592BE7157ED459BFA0500B94242C48E2EFAA774E0F78B0EFEE997658CC82C2DFC8C686C3406A6D997296F2FD3281D3E44750DEBA5B22CBCF7E45BA3663F2909A643838C9E7D5FFDA9AB840C9A0AF6D6FE29BE8A7615D896D8879EC16BCB9999559A645627553BF231FAA4344F6258FC4679C790668D09AB7393CDE99170A770E3BC4491C35F22BC7234C346191E09CAC7CE819B8E43DA70880BD3563622196D860DB3FD4B1E1E814660A024EDC779BDEB38CB686318EE950AAF42AA3B0042716D5365A102C5FEA90A7C0DBE71CEF891F12CA3D20F0A35F7D59E8EC5B35972FDB474D52D780C54B5C79D1C165DB237AC235528A42B21E3D667968418019AFE9F68F44D46DC96EB87A7DA38F2B0B943C9C6C2E87C724C99C65E5CCA40D6C85E32778CE1065F65C95795E0F1ABE400A4C78F22303D8ED54F9BE517CE2EEAE1AE6DBC04E9604DE79952DC74758027C616ACB8F586EE0F7BB7274D3E1E147E27039A44E3C1E0A5A874BB0E70A60F897AAE005701DAE3A9696652869F541EE178EAB5118D3115C923321BD28F9D6358FA012633076754110877C00376C5CCD57E6917DF937AF1C6F449993088D01993E4B470E98CF8F42F7A81120D175CA4CFAF063F76950D2E75046AFE842BDC15FE4CDB69369CC112050B62369D4820C97F407D8355CEE5D8C4B682E7D184F6FA02992BAE0FBBD2ABDAABFF5BA49F4571FED93789E52ACE387AD29A7A6EB8C0FFAB868A4542A42C1B35FD3D42E426714C01F82C8B11D77D768CB5908E60934678140524922EE339D3783C912151EAB2F051C1E61EEA79148F442FB7715855A0C9D6B857412D5CC3526584131180EC763AFF11813EB16446E876F48A25B8FE13EFB071991FF1DEF484AA00A976C4CA8D65B4AF8AB6D59EEB6957932F218DACE7BA7D57D402A9EDA506220A22F03BB70CB60134BC3334B005AAA26A7EA14808F13DCB1EB11BB40DF9A8CAA714A5F0B076F1C64BEF4A0607B174406155E77E531307EB8C5FE2A53D1BE40301EC59AA2CD995FFD5E55708\nss = D072CB81AFF4AA5712E56F0E9567DD89F2B03488735BA4751A7F0DF1C786402A\n\ncount = 94\nseed = BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7\ngenerateEntropy = 6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34\nencapEntropyPreHash = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94\npk = FED53D194419C06B92E51498AC2601869A1024EB0370CA3A420C48A765A5B99BAB88A759251CB83259A628603C54A831AC0147F3A97B8329474258B7BD6067476605A2B2B8311252FE54565C865E2DD96EA9E43B23121C27AB02C348310ACC38D9D583B0D8105DC87896C238069C689027910F9BCB5D29AEEBF57C2B9C78F76866768C0699C6BF743C0B43108C128A5277F39B32C351926369FB8754CD0197EB9AB602F391C4BA564BE2C3423005266229A10B21D31A7CC3D40C2E7192CB6628AFA692D3E75AACE66E7BB1169893C8EE45BDA5560E7F79C711D32D52C0C783EB40BF8977C3063CB114B6368A8D1486A86CB108D146A648E080751440F4D8087116701987C328D8547D0573F8C03D321AC07138A60954297CD832DFB989FD99ABA8B213E7501CB3D25B384C023F66776EFA3AD4981037A54400729634A782ADFC24404BBB4F2405A27A8500CD79E8521DAEE48848E485F53A28DE91089D849EBFB54D97D0CFB3CBA46A27438F426EEA1A0122F2180630864AE46CC5F3A828725CAE89331D540B5B3633EEBC0228000D75908F21277104D7816F56854C3289AD1A5C72C1655830089CFB9C90B1306724CB2828BE679B989A3565758B058AE983C1EA9B71F10553795537D454EED50F50A40274592AE165C846D85527E479E3FA8D8865047BF68D200287C0A5B8A6A78C4769BB3A795979B774713A522DBB723F3628F2F4126B639E3B4C5C4B076D321A208A123D82852AA0DB6FF8457E745B6B710B396C8106E635A379E22C59F17DF7B7070EAAB38D5448E4AB67E6B21078D5B9F9979C6D7365CD1423CEF6B4C2B186AC6B792EF9351B6040F423CA22E7A1455A0473273E3B53B92A132D7C44556477907FB41F981A06CAC9BEEB9655FE90C4FE93CC33337D78294F7C128FFEE82B0D4211E550342C599C9932A201F3CB8BB253A0559FD667A3D2CB46A4936F5CF9C4D0D105880A446066AE06841E12F259E4E6220D932633F77F9A6B463E180778D53C37E0BF423717F4D476ECAB6BFBDA7E461AC3CC9806FF4B38FB80C0AC9B0DCEF56E9B27881D1AA0892657B12A913A8AB84037A6C78399F53816D79C6A1FB40F1CE200334A7E74760999F8A0294C3029BB23EE0CB81700B95BA20140CC5DE537ACA62C9808240E74D508A93263EB14B7D202A31DDC2147747192BA1F38932538241AD1DB35CAA40097393038957B64E716D4CB3675AA9EA46257BF55A6D1FBC2C356B020073E16EBCBDDB3692515BE92DBA54CB62C702165C74864C3A7CE67D8AF92EB78496C4E8EB78B55DB7963B016A252A85E655C95936D6006BC07BA6250E458A387BD7BB43A3F5A16CD8733B66565377C1A74D5488C1A0DBFD7A6DFB474EAF29FA80AADC83267D0B98EB7A8AD3AEABA977A0A5E55B8937AB68E385F94DB13FBC6C26BC23B0B8BA331A578B99B493D875F206C278A3B4F63E156FD386FC13104D6DC96AE9BB3055481B846183DE71ECA09273E58C466EA225B1824246C799AB8B045FB844572882299BD6F1B2787E1094BCA102FB20E0A274257062385DAC60F37A15B0496ED23C465A3BA46BCC0BA9B5B78C93B45CAC0151687859B155AD62A8539CC6B872AEED63847CA64797460FF5F477504DF1B1894FEE3E6BBF8218590936E0102DCE8ADF459D590355576E1\nsk = 2735BC066A2488726C89432E56452ACB24A2A5407522988C0732CE072128C8D5147C42988F94A8516C77873858394A2BEF65B87741C5B9691B6DB84E3B1B2B2F851B1305832E4210E5D05710A5BB7195B8BEE0CBA9B5BA21BA57B962A280565AABE1C9015635CF1A7121A8581FA0A78AB26FC82838B6A405C6FA5D46469136CCCC34930664240915BA5C86E67ED9E73F4B123233C92D73BC05408005DCD6CFD62635C3026C990753C55CA8DD385A29B1C79FDB97C0B4CC8F26B28BA573B5194D6BCC065F5B97DF702009C43A65ECCF452447AF91200EF68F18CAC25E5C71E62A39FD7A26C6B64B47E29D1E4084801599ABA838A3808ED83454B506965507CC6D0B34BB139300D1014168A79D5707C74BBC7B980461249FC31734DC384C9DAC4EA6EB4701402084719593B62AAE53C8D55719945975CFD25BFF31C886640FEC37CAB3942676C840A453C6751CAF16A4743495BCDE6528A942A47E7C2D6499B2A872A76E928EF4B0AABBB21604F33231235A7CB47C96D9C976A2AAD533A06A24024AD0925007984D99ABA3AA8168A8AC92F662348686F756BDC1A23F8537545D13AE9F657CAA801788C9368864A05F40AF22E33E10705741F06EF577CADE6CCBF1D01065565A5B13284690BF611093E45684D6C69FC0F548AF852248DB6A6E86A2A907C95CE0053FD942A92B024DD18803474B03F73FC022912257454C008D137C5E8404379DB2719581AF17108A03F58DEA58892912C5FAB701D28CA845068761F6BAB69BBB75584F7D289DD921AB30379248C91106A784738B17CF0044418BB9CE34BCD913BB26D04CA04896109A255A39BEBA1A2B58490862409E473CA623933AC14C90F64CC74AF396C3186917061B5C8C28F3E8B694535FC2C73AF9843031C19166D2C8A3A76A2ABA45ECA36321BA367BD5B176B5C7B8D7B7192C95CF2803E2C3CA5D585C4EA63009C7B850F08759C278F1027C59499526A8B2E494203197A9304022FA0C4E47A3A6FBD8BC59A7C1312A6D19D3063E8078B1A1BFF964AF48151E4CD3CD87F49BBBE01AFA3A5BF46A7F9BC97DE729285AF35A6A9168683658EE37BA6D9499CBAA8CB44C93BEB287EF7CC7B1EB6491154C14FC2027AB49316B70B8237A546090C9687CC70CBFB82208A7F61F63AAC1A42961568407343A050B1048967C5334F3542860249FF9C2FAC8639EF8C125D0B9FD537FCA93C1006A77499658C0286267B910C10B12A6136152BCBC03E782C41B1FE94A000CD974A3A9ADE3A3B8B4BB8ED8B403683AB4EA3B84B84C4825F61F99D72EACD894337523C6B6AF765BCC99393213938D66B18B2B168D6C73C2EACC42AD22255CD3AC6D75200111C0A6076F02F906B1C96213E80310B8752B1B619E72366F9A0BA4283520333EBF8693F93A7FD6C3560058A8D16CB50B585B3D519E4263B050259A9A0A8823E3CADCD0B81C1CA53820323A9539133C68B0A6CAC1FC834B808D9375431F961FE3233C49FC9E88EA1ED0A068A271B502C0A0376A1309F86013B4947BB671C1B048C0905C8CE16D8035C7C05B9CB8755C7D7B6DB2907DACC5A91B61B666837F209075E8AC5B86444B49AC878F9B2E18D42E0F791AB7CB7C973CA8E0437F158889FED53D194419C06B92E51498AC2601869A1024EB0370CA3A420C48A765A5B99BAB88A759251CB83259A628603C54A831AC0147F3A97B8329474258B7BD6067476605A2B2B8311252FE54565C865E2DD96EA9E43B23121C27AB02C348310ACC38D9D583B0D8105DC87896C238069C689027910F9BCB5D29AEEBF57C2B9C78F76866768C0699C6BF743C0B43108C128A5277F39B32C351926369FB8754CD0197EB9AB602F391C4BA564BE2C3423005266229A10B21D31A7CC3D40C2E7192CB6628AFA692D3E75AACE66E7BB1169893C8EE45BDA5560E7F79C711D32D52C0C783EB40BF8977C3063CB114B6368A8D1486A86CB108D146A648E080751440F4D8087116701987C328D8547D0573F8C03D321AC07138A60954297CD832DFB989FD99ABA8B213E7501CB3D25B384C023F66776EFA3AD4981037A54400729634A782ADFC24404BBB4F2405A27A8500CD79E8521DAEE48848E485F53A28DE91089D849EBFB54D97D0CFB3CBA46A27438F426EEA1A0122F2180630864AE46CC5F3A828725CAE89331D540B5B3633EEBC0228000D75908F21277104D7816F56854C3289AD1A5C72C1655830089CFB9C90B1306724CB2828BE679B989A3565758B058AE983C1EA9B71F10553795537D454EED50F50A40274592AE165C846D85527E479E3FA8D886504", + "7BF68D200287C0A5B8A6A78C4769BB3A795979B774713A522DBB723F3628F2F4126B639E3B4C5C4B076D321A208A123D82852AA0DB6FF8457E745B6B710B396C8106E635A379E22C59F17DF7B7070EAAB38D5448E4AB67E6B21078D5B9F9979C6D7365CD1423CEF6B4C2B186AC6B792EF9351B6040F423CA22E7A1455A0473273E3B53B92A132D7C44556477907FB41F981A06CAC9BEEB9655FE90C4FE93CC33337D78294F7C128FFEE82B0D4211E550342C599C9932A201F3CB8BB253A0559FD667A3D2CB46A4936F5CF9C4D0D105880A446066AE06841E12F259E4E6220D932633F77F9A6B463E180778D53C37E0BF423717F4D476ECAB6BFBDA7E461AC3CC9806FF4B38FB80C0AC9B0DCEF56E9B27881D1AA0892657B12A913A8AB84037A6C78399F53816D79C6A1FB40F1CE200334A7E74760999F8A0294C3029BB23EE0CB81700B95BA20140CC5DE537ACA62C9808240E74D508A93263EB14B7D202A31DDC2147747192BA1F38932538241AD1DB35CAA40097393038957B64E716D4CB3675AA9EA46257BF55A6D1FBC2C356B020073E16EBCBDDB3692515BE92DBA54CB62C702165C74864C3A7CE67D8AF92EB78496C4E8EB78B55DB7963B016A252A85E655C95936D6006BC07BA6250E458A387BD7BB43A3F5A16CD8733B66565377C1A74D5488C1A0DBFD7A6DFB474EAF29FA80AADC83267D0B98EB7A8AD3AEABA977A0A5E55B8937AB68E385F94DB13FBC6C26BC23B0B8BA331A578B99B493D875F206C278A3B4F63E156FD386FC13104D6DC96AE9BB3055481B846183DE71ECA09273E58C466EA225B1824246C799AB8B045FB844572882299BD6F1B2787E1094BCA102FB20E0A274257062385DAC60F37A15B0496ED23C465A3BA46BCC0BA9B5B78C93B45CAC0151687859B155AD62A8539CC6B872AEED63847CA64797460FF5F477504DF1B1894FEE3E6BBF8218590936E0102DCE8ADF459D590355576E12C0DB43F39B672B2CD912F907CF76A0F6FDA925EB2D205546431BE0B37B204114F797C007E4061F95C7D56CFC7EE5C49E849DDE3FEA8F25E7876DF2A18515C34\nct = BAFB19B80A5CE997C3664CB158299C969C9020D74B644EA41906922A18329F70271FEA4912E7A67335279F58CB3E5E4B7BD7FE3C4A18327BE182BEF8D989E13CF8CC43955E9F6BFB3D4A2C8AD71DC01BF30C34718D01D5D4460C3F7F85E881ABC66E483F8406ABA076C08F6BA3C796945D4E286E9ED09E8B64204FED1354A33EAB64A60EEAC0296357E5AE0058FD67FDA21B0A6DB5029732F86E9C9B92F7D3B5380BC601A5FF35A037862BDE3A399D27E6119F0C43CC8CF852C522EEF46B4867753684E30B27F4D98FE039F203164855CFF6315769BE970D0AAACD411D35679B33BD68A852F836374921C99BCE48C782321E68B16DC964463732ED2BC4002757C7587CC3C780DB57BC7F1BF936A6F685E0F82DEF692568B99DDCB49A8376F2774F2E77F7DE0D188258C4E1BBD0652BE82112371D92EB01D8C38C9A84E5237AB8F6A333642B2A86C9DE4993703428104F76F8BCA911135C78101DEA18F0929F6A00B0F07854E814764F15832F18F60B6F25262BD448453E51686775A824FF5C743B811625FCDB7503E0834C79596B066B6EE2C3548CD6062AC11663E5497632280CFB8BB33B392C8747681A84831CB37799C4E42A25E16552354756CA0D41F19FCE9B3C9F8BAF18D05DAD841740B110F2C1B4E101F76158F307E9543E2015AE0924628996E652588E7EDADB51855ADB306CE70B1223EC445C425AD76D26E89514AB335CE2236E6A3AB1A7BA399B806609E5D22857F3ADF23DF5CFA3C4EDF0AC3EB60A00C27D7C02E0AA3851FB6EC063ECEF6E819AD52F92F260BAE7F83BB44BA8FAB3A608251C2B1DF90548F9DD2BEAC4FDDFB54FA10B251E42F3FC4FA9EB320BBC8AC34BBAF8DEE65BEF1C83EE499397F7930D61B4BED065D809A1F5E6E377C9563C660DD8DDEDA94058861B4875504DAC970EF8097EB7A75822D5EB139D10159D6007CCEB08A8EA28BAA27F78BF60E825353C5AF62F2DEC4AC0E7876A004DCDB4F12854EFF4013166053B9108F5439AF99FAD00C61169BACD84876956E53F1C0267B6E2985DAA07E34BF852947C247450A6AB3BC1820C52BB3AC9550BE7AADA0F8AA692806DC57A748F2C355555C5C58BFEF181E7277DA1C25CCE4B995E6B8A90833AABCCE74E7DE925A2A2C888930D052B9541908472C79E7A5B8E9E08E4CD3DCE557B35E34D94A741121AF0A7DF97131567393826F86A7BC0B785965C5BE0DA83FE4357D2A36E57EB1B1DDF651CF7EA1497563F4CFA4BA171DC8343A3FB549931479DD581FF018B5B10B9E1CB529CA248C00EC45B3F36C1DE804254F54C9B68A328319B59555FF57D832B3F9C047F2D343289582099685AAD6BF96FB956334DBFA7E86589D8D643780C431434F64411CFB85E9898288DF9207C7B38798CF8C68DF372C2A6BE4C11CA29D29CAED09345BFE47071AA801758331B37F658DB6E7EC1408A43486B772807646E5186A40E73EB875DB09DABF293AF7083878248306E2318C72B6E0843F852CEF164446A25481ECE7432B974A0C240CA35DF4AFFDC\nss = DA1085CBC7452CF2AC98CA36631C6EBCFFF02E60485F9E807CDB3DB77BC92243\n\ncount = 95\nseed = 121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F\ngenerateEntropy = 527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c\nencapEntropyPreHash = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c\npk = A0E473A9D639B1299251B46D07C79C0DF1CEB995A968B5B707B760D8BCB120F6226EF5B742F34548902A7C73338A8CBF8D6B02A83470874B1EC5845DCFD3A4067C420F8485FAE1286A23ADB7373B9217C6DC173748870BFD164A16D62A3A6608F5E2B7FE78B92364A4B821967DB45AE29AA1B11C0CD67CB4299B32D263AAD7A26EEB3A69BA56790FD806ABE3935D82487AEC3205A856B4981E7F53B8F82A30D13C1B725B1418607B6619B0E8A8870BBA6070E33545730182FB5F6F9938AB2CA68C50719FDB472A88384EF210B0C22785367DEDFC840979AB758479506064B7971426D70AF9A95E7D585DC8B67D4FFC2082BC45A4FA9B4FB9541493C3DFB88FCA757ECCB50F1A9CCED9C046F37062E3879E13958BCF063041E858810B057680276D2CA12A307F511217FD626561587617674319382A4A00CE5E3BCFC5ECB5B3816133910650A469AC663F7A4A742DDB87C4E5BE636213880C246370B1CBB8ADAAB6BB7E1185E1F95C945BB001A0210CF56F326B35051B8DBE85245F9BC6D973B39AFB3A3B961501862B4CAABD0D55693C201390F48FB7511990571985764BE7373A7FC4BBD5E82B31F52494B15B6C2C8B5B593182028BD7AC7A40FB446EA756463C396DE29D0FDBA2569B9001E169F7C824C8A42D313A15B682BD52004867837344324E2F91A06A4C9F7CA447D6291635257CB0934E015C1937F732C1BBA2C13591CCF4ADD16960B2303476000D984A8FC8036772C3B7C5721261387AE535129A7921A1711C98103161A95EBE16C0E0A28555DC3598CAC2D701A98CA249801A4BB10379A5C29A1932ACB6F6C3D040639FA98FA7297C6D453E35587488576DB9BB2F9D1C37F8260CBA3BA90E4B779867AD97DB03FF005ECFE3470D2C25D54105CA287A9E0C039C2A2B71A1CBC6260D59A268D60C05D61202EC336CB8285B41A043BF58949DF50DEF5937BEE1AF32D174E8FB463D03449BA747E92A79A1EAC8DED247AA0A50821A16AD4C9F533A0FA24684D452A71DF461AEE15CDDC2185551112682B4867C6CC27C43BF835432CCA184840B85886A5D970E9F515F7F97151410C401E9BAADF41CE2B8642313C295D28587A327C41C24DA18967A6426663642DCF389C50892D6847718365CBBBB80723C1397B90447B197842C96A141BF6CD317BF12BB64C664FD237E886A9F793313AAB15F668C91C71149C4B90B35B147F7C34B8AB6948799897855B22283050B113D64A60AAC739948844A9F99C448D21C414425D77560670C298F493D891128AB1665D8141D2B1C8E67950A68255B7F9376332B1CD7C6630AC05AE7C127FA7ACC35E640E94285E78661B15B21685A36C889A8CC890CE53C36EF23C2F17CBD8C31351BEBA827949F8707A05324ABF05AA71857BCBE690405AB0030E648FCD3BFC0F2AE2C627E04F490BC3BA237059AB93085DE218029F056B0F57ABD342170F5B16DB069073A3C16BB1C0BDA5136952919B22AC477AC2489237BB0869656614E4AC248B003799C761B2BA5F2711B24A01419C88937DC4CE745ACC16C796E0123A4228EC623A2A4E059B80B72BEB1329C9204B6555B0A62C14DF0B19B4A157BCA985090B428DBA8587B53CA2714B2EC2A04D306B3CD5D09045252960A068412F1BD67B83A217049D0685EC3D63D691559A327B2\nsk = A680635121C694AC4672C809BB3B913E8CA2F659C756DB1D7BB2369F41AB4AC9B3F5141216F3C997B00DCDE37352D46463F371FEC14B26AAB239498D44975F787504815552E727329DD78428F5568B912C76B572AD9B3D335A9F5BC0283C76AEF8D81369A0CEB4523BDC4BB0607C29D9998962F76B217774D74A3453A61FF1F40F89A51365212F39A07E913824BF36B6DBF6C8934014DD8716E998A982B124AED8B082C3A2998708BC1C4733773B73E0BE315203E8E264A032797280CA0AB023A9D81FBF0565F491837CF031E219084B640EE8710589E05E1701870BDB7BF0B0BB539A0B3AB0028447110288C1D7D83F89578413A46B0B04406657B4E7E5A6D04BBB91055BECC8AB907CA9647C4B8B144045B6CABCB974A47A35308A23E9C9281C61C556EC148C9A663AD9518CEA36AAEC71B6995110FC01CB66B75E128478280FCD31A3416A12E28C15BA617574730437DA8BDFB86B58D88C789C4F9E23ADCEE53B170C6A0B80033AD52CFE1A155EA1A568F5B2EF77AB74878E0CE42A1F7C3C845713D17105AB2C91B83836E11B9858A66997B22E8A67682588CA78E6B6D736298EE34B100BCE61E0AD921A9F020A7032351DAED655D35B3659A96B32DB9E68D882FC986DA904408A98C469A84CD29CC999B2B071F84C921C585B9B3233C5BEDF82637BB1253A4B29B36B42B54751DC629A215656AA1890C0C56E0CB62A3C02252B771D72375A60374BF8D84552080E0D456579930B3F2A2A3B7913C031112FABACAEF75BB2DA5202D7671359282CB4707B52740D9CA06AB7034B48A292404D26B6CFD08C8B0DA61550044069F4CF27488C028001F2C29292840B60B321DE5CBDEF1CA216838091C3172ED26D141C957DD93BB6A59D9E883640D87A2A85605A9730DD5333843805374B58747C7262D5A65EF442D6843DEB731C943269B4A9BF00F39B4A3847840C1BF4B9907FD7B9A66C5DA724CEC467102F080D4D0BC519D0B2504A05F7207EDCE7398D009348F64267E01B0EC207780791942565AEB061BF03719D706F87953C4757A75A126EAD15C6C9447C02938C3B75A58AB25CE65A5CAA21898FA8050319880223899F5546E0D253DF7950691B86F8E3115438C3B80CC2E7A6178A96A0F38A0CC47394BE36C9B0721580D646A89B9327210D40728F4BC4ADBD8B130EECCC", + "F528A5A09595F32C0F64E602F6898B8A4C82D79A8ED31C4172A7812C295C93841929B782B334490EEAA38C17CB4E77664306BC7B01726EC656E24311C51B0524C72F0745665D43073604C59EC88DF6FC9EE2F2A0476079BCFB735E562F57E2B0E1987A0220C98F0B4CDEBC70F93CA709C5C2FAC7098A7B866662ACCDF09C85974D7C88CE9AFB01F48276EE320D70C7C0E15950FC0775E13173B60555A470302D0A0047260E5CF85EA2F3C326968D3C308C15EB400B13BCAAA65EBF941EF59A069BA0BD3D00841B6124574303BA8C2BC9F90F107865882C18EBA462F6B09EAEE05796E43A8647C59C64B7A8DB9C0941299280AF728B872C303755B682A3EC10C5876F040543BBA028E870C02A4312AEE9CF2BD1302DF80BD0FACBD0765A778A7FA2D3A4C9675965D6799FC7BD4E28A4E2A53948790234F62BA0E473A9D639B1299251B46D07C79C0DF1CEB995A968B5B707B760D8BCB120F6226EF5B742F34548902A7C73338A8CBF8D6B02A83470874B1EC5845DCFD3A4067C420F8485FAE1286A23ADB7373B9217C6DC173748870BFD164A16D62A3A6608F5E2B7FE78B92364A4B821967DB45AE29AA1B11C0CD67CB4299B32D263AAD7A26EEB3A69BA56790FD806ABE3935D82487AEC3205A856B4981E7F53B8F82A30D13C1B725B1418607B6619B0E8A8870BBA6070E33545730182FB5F6F9938AB2CA68C50719FDB472A88384EF210B0C22785367DEDFC840979AB758479506064B7971426D70AF9A95E7D585DC8B67D4FFC2082BC45A4FA9B4FB9541493C3DFB88FCA757ECCB50F1A9CCED9C046F37062E3879E13958BCF063041E858810B057680276D2CA12A307F511217FD626561587617674319382A4A00CE5E3BCFC5ECB5B3816133910650A469AC663F7A4A742DDB87C4E5BE636213880C246370B1CBB8ADAAB6BB7E1185E1F95C945BB001A0210CF56F326B35051B8DBE85245F9BC6D973B39AFB3A3B961501862B4CAABD0D55693C201390F48FB7511990571985764BE7373A7FC4BBD5E82B31F52494B15B6C2C8B5B593182028BD7AC7A40FB446EA756463C396DE29D0FDBA2569B9001E169F7C824C8A42D313A15B682BD52004867837344324E2F91A06A4C9F7CA447D6291635257CB0934E015C1937F732C1BBA2C13591CCF4ADD16960B2303476000D984A8FC8036772C3B7C5721261387AE535129A7921A1711C98103161A95EBE16C0E0A28555DC3598CAC2D701A98CA249801A4BB10379A5C29A1932ACB6F6C3D040639FA98FA7297C6D453E35587488576DB9BB2F9D1C37F8260CBA3BA90E4B779867AD97DB03FF005ECFE3470D2C25D54105CA287A9E0C039C2A2B71A1CBC6260D59A268D60C05D61202EC336CB8285B41A043BF58949DF50DEF5937BEE1AF32D174E8FB463D03449BA747E92A79A1EAC8DED247AA0A50821A16AD4C9F533A0FA24684D452A71DF461AEE15CDDC2185551112682B4867C6CC27C43BF835432CCA184840B85886A5D970E9F515F7F97151410C401E9BAADF41CE2B8642313C295D28587A327C41C24DA18967A6426663642DCF389C50892D6847718365CBBBB80723C1397B90447B197842C96A141BF6CD317BF12BB64C664FD237E886A9F793313AAB15F668C91C71149C4B90B35B147F7C34B8AB6948799897855B22283050B113D64A60AAC739948844A9F99C448D21C414425D77560670C298F493D891128AB1665D8141D2B1C8E67950A68255B7F9376332B1CD7C6630AC05AE7C127FA7ACC35E640E94285E78661B15B21685A36C889A8CC890CE53C36EF23C2F17CBD8C31351BEBA827949F8707A05324ABF05AA71857BCBE690405AB0030E648FCD3BFC0F2AE2C627E04F490BC3BA237059AB93085DE218029F056B0F57ABD342170F5B16DB069073A3C16BB1C0BDA5136952919B22AC477AC2489237BB0869656614E4AC248B003799C761B2BA5F2711B24A01419C88937DC4CE745ACC16C796E0123A4228EC623A2A4E059B80B72BEB1329C9204B6555B0A62C14DF0B19B4A157BCA985090B428DBA8587B53CA2714B2EC2A04D306B3CD5D09045252960A068412F1BD67B83A217049D0685EC3D63D691559A327B2AAE8E61B905723FA092FB95B839F6DE3670C39CE0498C27B87D20C24E7F64E22E32D432B4F9F751BDE0496C580A181FFED762AA35454A02D3F1F47EE0394C89C\nct = 8F9648D01A9027F4E1AB3D988F096F3470D09707E288699141A14A78A88C95E1771E6E12B02BD13C2E99207B33F9AADD87C79715928CF9FD76956FC73C2A21D24AF756AC54F75ACCF2667AB9D8458380743A1609A7DA99A5FB521D1061C263964800096B930CE7D448AD1CA9BF48524892960A762B382A1EF36B4ECE3EBD9515EC7295692546891C10C53C6829AE866943E569F539FF1101B5F0B2AC7D1C94EEBAF6378B13BBC1C8A2B144A62A10D752A1F05DBF1A9CF7F1192FB7919CE51FD6CDCBD6BA26B6B8AD7FCAAAD17F3B96DDB8CB78CD0EB4E96958AD38D2FE9BB71A87547AA7CB0ED2AD6CDE695112E6379A333D135808DE697F7FEBE9C179F627F419689B2050E5DE6C87BAE3FDEA59124D39F06F264E2723683A092FB8382186F1737048026459D6E242C0E7FD386F6AE6C8B09FB6613F26745DA21F43FF145C83DEE40C927918C26E8C855038FA8F994790C799393EB031D3DB7F499138186CFF085F3669B45351CC0579299D1E37578D753E447EC2B161DC50373065D20B44712EB059040F72F98F51858E0A250A97409374EF7BD73D58798697B0FCFA35946933856CA5A0A964B7DCA6617EA2D35D16A8B83F536972BBA727BC3C16EE363B5B63CAE7C13AB11B4287568EE64229671DC45F06FEB3DBA8ECABCFC16FBCFFCFDCB4227EF4E705992CA8978A19D1190842A4099A21CE4F96814FEB88E094A69EA7B7BF0EEE9932A1C235AC2ADE53897D3D8BE0E4F02FA7F0CDA13C4EE78127F1FA8C611F50CA159DBD048E9D888234BE8D80B49324621F7980E490A13CA0C5CB8D4CFA07528E808839FB9A21FC167BAA489F3C96AD67B89FFDB4145F3FC9A827C2DB3588B0B348FB8F5F469315B7B89F5C25EDA806D921DEF1768029F99777ED29AD1031CD40EB1C12A92A8D2A130D2D0C1560598C430CB2CFD73E19E290EA864E80384359188D67A53A15A4F31DF7502BB3123BCE2614B87C82DECFD29C0264286A9641AF0EAE2A38E6CA1F065A9E619E3CF39C1158A4BC46A40EBE72536F4607372471D5D6D6CAE5E2FF6265B7BE9DD3B466C159D54FAFEAE8E3CC62ECFA7BD2D047C0E3E93D163D93C7EAD30CD0CB41B789546CF11DFE9306CCAFECB8519C08573268FE46DB18203F6C4CA916C4E1133D5422EB966F716622DBDCD7DB21834BB10BB36631AA2C50FA46D2909F0EEF33B3C62846267A9D5E7187623337950DA98496A703A5E9F7BEC4C2E1CCA8CEA8FFDA5BABE1BE1E612DF7E9625EFFEF36733097CDE4E88ABCF2B8878D3CD9A47C6F907ECDC63E87E89C6CCC6AF8CAB530DCCAF3597E33AF7DDD3814D9FFA5E90A335E31DD2ABCAAD72807AD5C6D89F6FCB1581AEC0F0BFBE7315CDB428D905795BACE3138178A8B1460C665398FD57295014F82C8630EACBBBB4C52A1D22E58FD028B5097758AD913922F6ECCFCFABD165D9959F29C2DFC6B4A548D6E75544D70BAAD0AD24D74DBE1E51EF9C9EA4AE3345B121AC8F0D041F359BC653987C4215EE7253FD0BC21384D0BA14630F5C049A398\nss = ACA83F1DC628FA87B20133BED4C2EEE34B98021F295AB585DFDCEFC9E3C032F5\n\ncount = 96\nseed = B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420\ngenerateEntropy = ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec\nencapEntropyPreHash = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4\npk = 4D960C98359F5719B20DCA6D1E2916F2829E73F79B55B468170B64F2F8B0C788796801C8EC244E1973C7E033B768414C55D43079B2711BDA630E678B184A70DD161C4DABBCB91C07FB634620D1450664A444E82D22A0A4F54AC6C7C02D74120B2CE205FE49A139B9C8194341F4295EF126B37F3B22E35792A8853B60EB3F7ED01314491C4451470870A5EA5B1D23442019BC1DEF547FB8935ECBEBA0833228B8D7BF2A4ACA52436A3F993F6164666EBB3C38317BF5B48CC7182C00D58D4A095D0FD4C60E4229E77803C4F38F22464C7A4259E45AC71E8CCDE6E5738DCC798777317F9847F8357DCE21B24AE462D0465F1D58203F3B8590D88DEB9C6DF4722A1420A9EA0813EC3777A6CB11CA0271292B6C662A870C292291164004299C82442A8DD5404E74CFBCB45175237AE5649F7136CB47B9C6C053203F265BAB420EEE2C95A5960F8A87C3333785E1B89FF841A6AA5AA964F3A853E512ACABB60E29C3A4810DF33830134C0E49BC5E1BA41B07B671E1BA6BFDA82576406E6DA854920A46914C8EA986B1D6A0328D4A450FC0CE698B9D16954AAA0C52B6F2B5FF7B5347E84C3AF403E9B31EC180238CD5AF96F5C6F0D3644AB51717F7255AD6551F44378294778937CC56B610680704BFB37E3CCC07C5276777E37F36623DEC8225388C3A5A2C7026EB902C63260CE27FFE657BCE34A47DB43667B9293E04AB9677B6FDB0B0A429A4435A9F5624628A2C07BBFA8AFED562BE4233019524E67CAE6F955226437433BC59835561C462071AC38058C145787C242D4B6DC055170675190882792EA49726DC8B2CB638763784D3C23E1791C93A55383A8C4B59643626F8948D228B670312893AB3CE5B123401B1B24432545889D4D124D2B846070C1663B87A3475C01ADC4F4DF286FC91C76B018C05B5A26A696DF86C4B1FBB2ED3050CC9B54CA2786839F854B9461655972FE21C3C98007A693A4D0B8AAFA3AB73F1C411DD283CCE59528477B6E089847CE6518F29B523602F80AC573618070BCA649EFB84FC3947D43B229E05682914C153809521EC9B7978A6BD667F59B18F1D986222DC9AB345AD2C7C7CC5799C15297C22C3734DF18A218C5BACB364C9136B8E055053567A1856C21B96A1A2723913C98CC364BBD1FC4EDEF37E1853C523727A6C677CA4C82AC4D49238E1B60C1531D1DC9835C4A96124A0011C09350353AAC4568A84293E8666F6016E56C38371489EDDBB3DF3E53E6767BD01E231EB122F13F59A83A35101844AB389954E8068F6D7128C738AC1774EDC6465EAE8CCBABCBB41271467C407D36928D9E3174C99665E3A9AF0FC1B2733925B254A3ABA050EC3925DABC511427C0B2930BCA63BA7629366C1BA620CC0D7090752157B5D70C098745E37DB7316056C7BB37C024226425107DA8BA0E9C30E2606752F31A017E50A0E10C05332677EC851EAE14F594A55D07392C23A962248CCEE1221FEB2C8F801860892B33EF2247B801E5FF55BA97675A71037FD133133840050B8B7914125E9D30165847319EB1E483005CA0BB8338B75EED618C47408D0260DDFB1527640A148F29E64F65FCAFC59A8715A8126830024767009BAD41A3385C0173BE51A35F3825843B59FE06B5FC03DC21F6D925B9F6D92FFF175C9DD625BFAF502B4E2870961858852\nsk = CF8293B02A9A6F579F51066BD6E51ABD270104634CFD482823102F2B63B18A8BB4F45A5AF4D8202523CC1779B4", + "4FD283860BD004307C399CA5D8EACADE156AF824A988F5AC6BB50EAFA6177A95B9752C922BD6A7C4265A6A88B11D0403E47127B1E80787742669E763929483393CAD6EF91F18143E9D2B7CD3E028C6F56B91768113259BCAB926A082A2A6185A1BF18656448A628258E21A3C6CCA23449B4F9483AE9D01BDD4BC674E06566300AD2A215809E547E2626F8D9437BAA727F3F05C31E85E4D34643148981BB6A82C3C75099A33A0E7528D45303D98223E1A4EF6536170F53A0C61004BEB75FA34B8AED5156E4A538269775808283CB0BA5282607D50661D2A626FAC2737C98CF33050353BB83E1C1136F1C26FE48D81973EB974AB1BA4B97C95C0DEE065523430CC06620DEBBA3DB92888497658BC5C64B98BE65AB2A0738F0750022B95A66C583354A63865B5237FE7098D279C53F731F3FCAE8689754194A7B888199B89761FD09FF75677B2C500D7359905E76357163834712659F26D0D8C9B47192404975CFB89969A77615D1A3FB404BAAA54511FF1B3B08C1577EB274F5B3B0B825434E87F60D18FA73141F912701A99A7C11305000789229A144A0899685596AA646F13573EBA0B54DD3205DE2C60C3CA1614066474B89F2377994BD14EE0A77E1D4C0AF77748C1E623CB8947A98636694C4EFAF0CE2BF779C66A317989A335A0071505831471C8D845A5FA4B3E42D195074244F70578124C4C7894AB84584DAEC8C13A6598524C023CA99F4C0499A68ACA3E6827798B10EF9A4639605E2FE8656606438274AC8ED8C87AE0A16BA3B8E5857A7F25831D8B85BC7105828575320C6BABA75489455154B31E50074A313BA9AD10B747F39405544F44949DDE165070C8271F1BA80E57BB5BD1320C8A1F8FB47354079532BBA51282AE3197026E18C46AE6B2AB9940EABA9F1EE421592770C9A9604263A4917C825C084C3534381F22C057592DD97940ADB1A439D5128CF795CDD25640FA9229220A1CE4A6624CC9956105465246334C77FFCB9907159461CB1416637D8DF34AB4B401413C27B6D5A1D23331F88273222653ADF9685A614BEC9840355B1A23A0C4CE60B0B678AFFED200BCB383BEC2580C89127B2870745C15570BA1CEC89F5DCCC47BE517BB020C57959E433C11DF10810D5B37AA8AB3392B3358793246F11ECE238646724BEB859C861463C42B5030D9A1FDBA3E1D391F9CA5A99DF58A7948C66FA2B50864B73A40B52DC7CFF031B3A3B21009268CD5CB00A89B44C156333B802AD03B2F07F70F7C11057CE78705AB6EE43681AFF0874030807412A7743399CAE832F6F3B65DF56AB1B30D6967379E10B4EF53B9EFB5632A23B942F832A7FA22CDE494B0C7393D51AC807A38AF119D526A5A3B91068E107812269EC85410AA739C288C20446B68880343F2E12157094DD424A349D1523E76C0ACB9C29C22B6346386B522B0466BC8A85B97430A1DF80850510C4825EC4F2AAB987C4A07F11693E7BBB4662A4890A3C54EBC0CBBD75CA468428E38276E81C43D81A8D0E3BDBEBAC9AEB89FC9D7870BB88C5C16A137C41FEE75640774C4B536BB1D7BBCE797844D960C98359F5719B20DCA6D1E2916F2829E73F79B55B468170B64F2F8B0C788796801C8EC244E1973C7E033B768414C55D43079B2711BDA630E678B184A70DD161C4DABBCB91C07FB634620D1450664A444E82D22A0A4F54AC6C7C02D74120B2CE205FE49A139B9C8194341F4295EF126B37F3B22E35792A8853B60EB3F7ED01314491C4451470870A5EA5B1D23442019BC1DEF547FB8935ECBEBA0833228B8D7BF2A4ACA52436A3F993F6164666EBB3C38317BF5B48CC7182C00D58D4A095D0FD4C60E4229E77803C4F38F22464C7A4259E45AC71E8CCDE6E5738DCC798777317F9847F8357DCE21B24AE462D0465F1D58203F3B8590D88DEB9C6DF4722A1420A9EA0813EC3777A6CB11CA0271292B6C662A870C292291164004299C82442A8DD5404E74CFBCB45175237AE5649F7136CB47B9C6C053203F265BAB420EEE2C95A5960F8A87C3333785E1B89FF841A6AA5AA964F3A853E512ACABB60E29C3A4810DF33830134C0E49BC5E1BA41B07B671E1BA6BFDA82576406E6DA854920A46914C8EA986B1D6A0328D4A450FC0CE698B9D16954AAA0C52B6F2B5FF7B5347E84C3AF403E9B31EC180238CD5AF96F5C6F0D3644AB51717F7255AD6551F44378294778937CC56B610680704BFB37E3CCC07C5276777E37F36623DEC8225388C3A5A2C7026EB902C63260CE27FFE657BCE34A47DB43667B9293E04AB9677B6FDB0B0A429A4435A9F5624628A2C07BBFA8AFED562BE4233019524E67CAE6F955226437433BC59835561C462071AC38058C145787C242D4B6DC055170675190882792EA49726DC8B2CB638763784D3C23E1791C93A55383A8C4B59643626F8948D228B670312893AB3CE5B123401B1B24432545889D4D124D2B846070C1663B87A3475C01ADC4F4DF286FC91C76B018C05B5A26A696DF86C4B1FBB2ED3050CC9B54CA2786839F854B9461655972FE21C3C98007A693A4D0B8AAFA3AB73F1C411DD283CCE59528477B6E089847CE6518F29B523602F80AC573618070BCA649EFB84FC3947D43B229E05682914C153809521EC9B7978A6BD667F59B18F1D986222DC9AB345AD2C7C7CC5799C15297C22C3734DF18A218C5BACB364C9136B8E055053567A1856C21B96A1A2723913C98CC364BBD1FC4EDEF37E1853C523727A6C677CA4C82AC4D49238E1B60C1531D1DC9835C4A96124A0011C09350353AAC4568A84293E8666F6016E56C38371489EDDBB3DF3E53E6767BD01E231EB122F13F59A83A35101844AB389954E8068F6D7128C738AC1774EDC6465EAE8CCBABCBB41271467C407D36928D9E3174C99665E3A9AF0FC1B2733925B254A3ABA050EC3925DABC511427C0B2930BCA63BA7629366C1BA620CC0D7090752157B5D70C098745E37DB7316056C7BB37C024226425107DA8BA0E9C30E2606752F31A017E50A0E10C05332677EC851EAE14F594A55D07392C23A962248CCEE1221FEB2C8F801860892B33EF2247B801E5FF55BA97675A71037FD133133840050B8B7914125E9D30165847319EB1E483005CA0BB8338B75EED618C47408D0260DDFB1527640A148F29E64F65FCAFC59A8715A8126830024767009BAD41A3385C0173BE51A35F3825843B59FE06B5FC03DC21F6D925B9F6D92FFF175C9DD625BFAF502B4E287096185885264E085F67E48F00A7A7F82963E8C67176BFF839A54FA1008328C0612F98D83D35AEDA108EA4D6C6BC0FB958286850422BC357CA67B83C986048E0D0087FA11EC\nct = BB06BFEECC7B7777B56768C6165C5347166BA71E8DC7E9E0258FF889BC123E6B6A1461F717FFBBC9CF11662E6FFEA09EB65AA287ECB4D7206D103F931B0E3C9EA8D71BE6F87B03EDF777EC1427F839922A7C8EEDC8DB4C8FECCA7665227029D6E23F5ED9163253D64D715042A5F301B41E2C59337F282DF32195EFCA03BDB3BD1D8B65C562ABF51EE8FCB39F51CC69DEA3BE7547341608444CA2EB9A9EFF2A3805224504440CF702C95A1FABAE452BA47A25E4D6401D24C0D8FC61962D4E11842FF6C6F82084D28F921E81E818DBE81B7E6A25596ABEC6809157A90C6F8779F4810BB3890D93E6F30546D982732AF2CBAD9E054AB510B64E6377DACB97104C64D9AE8CB451700F9A7776BEC488786733BAF3FBD6153B8B80C468FEB5EE28338817233A34A35E35F97D518AA8C07C9921E3D1BB96984FE1D543630B4FF34CB6AA6C64D7E3A7EBEA73E4B1379A8C53ACE1F2F2F07DF7017262FF152686BA28D8A3A348125F33BA2E795BDA25D2869F8DECB8E02453169E6EC9AF252D673D09060AC1F8E6E203E5950B11D1EFEC554D7E405F918E3472F25AAB2FFAB059EA043038031D23AF3911743FBEDAEC446C316B2801AF1152393F55820A5A7BB6D0DDBCEDE3F9E02423D7C8FD195F0194D2C5BD5A4BA6A9A5C934C1F7CE98D7476E2CF77837AAC2B738B1D6925797CD8752103DF9DE929119340993E36993956EB1CB7B8CD3CB067FE790A36BCF52CE218E9D5C009651EE835C724ADD8872ABB9E360742609E10EE43656719F140A155644AD25825AF6DD160D0CD944E1481AAA174A265DD18DA10AC0DC9F68337C5780672A36001209D8901E28F449ADA470A7134AF449A57494684E98124AD3901D680BCF62BE505368F8277ADE5BA33C3BF448462964728CBAB403FE5B10581E2BB377E10589A06B4C1AFB54927A87A016F63CFD1EC46A8C1A1764EBE07958FA2DC54C2CB90336C4769C7D118F56848122255B995752CF2B51133A4F96753A47B9B7C14E3A2565A326237926C870C8F67FA709F50EA174C3D0D57BD660438244EBD6C68102F1990FB1F1E06F0428A5210159EEA9C1774DCC4CBAEFF4461BA6966F164121EA26F328E831EAC62702119B42C7F430487145B68AFC16E7BAECD74A7EE349997A5244B6E9D74F17F00283DDD99808103AADF2365E4EB5DB20B40C3325333DD9877E019EFC9F1B95FFE67E88976A796DD735A68405C465225E951ACD794336FF7D7C5420BAA47ADA9C9A8C5700BEE94F0C80E693939D73C5C3A0C029DB9053D8D3C2E3F6EA47378FD225E704185D29C30F0C7AFAF47B3B9DE45539B026C77F788D00AB2A2CB41B5C995C0120C1229E9C138E6480BD9AADBABAE6CFD7ABB5FA97EC99D35B76702E8D84D2DF0333E3C9F4002D0C68E98E81440CB0D551C77AB6DF66348E2D798AA8092618B958317881F01EE209CEC22CC8EF0123A0C346EE47A158518C43FE926BA6F49056EF387F023AB9C57A6C0832E53C178A761ED7C382F76A81B340D98EE6FEFE208108994BA3F31F48\nss = 3CC0EF85A74184338A10FFBFAD5F6D04860D51E7DACF3EE73033B70969785AF8\n\ncount = 97\nseed = 59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4\ngenerateEntropy = ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab\nencapEntropyPreHash = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947\npk = B49B9264FAAFE731C0DEE965AC981965A28FF907CEABAC477E2C9B6DC95AAEB0531CBCB65D8B3F6251BE17ECAA89A5B57C1198EA66AF1F4461B91C360E4531C4D49269896107F10ED1F1070E68CDDB2A4E06C387F3126087A71A366A250B450BE1567DC957BBD034B66AB65FD4EAB2D89B8481EC2427A4AF3C1B861C799263F492779053A0128508C86EBD6201C876BBE8AB8053B790314047A1901C9F327207B2130BE5BCE8504BB03817A380975CD81FE0C0416986A7B74A16A21146636ABE4D2B2C5C1223D39265A6845804D49E5F160ABFE3CA21A345B5D044AFA5636C37B976F2894869BF4500C62AE9941B9B3C3E6064FEC351268243FD75BF287CAE8AAA9AAEFC1CFBA1032AD2623A6239A7F834A4826F86132B59AB24EFC9C57CBA929A64BA90271B987BC08A913298911650399429E9BFC40742DF735F7CB935EDA73A41F96CAACBB34324B29E64348C6063AEB0BCEE9066028B3340AA147B09C42752CFD6D491FFA497E17AB6C0726AEFE59C2577764A1A996FD879E58C23F1C0AC9E9372B3F0BE42C829B7B09ACB722E3189A2B3E72124895CCAB565DAE583C6C76C34C2C0075568379639869325F6E92E0B91A2D410", + "0B2F4AA6486B756CD521E1B781A964A21B8B0C72637A2E4299FE15C1AC275FB077CF42F36453E7603C91A648E09CBF128ED188639B7247584B333003A2175BC587925111654F24680C540B32643B035FF38BB4598785524504EBCB26163D513867D74744C8B562BD48989B3A328374A125CA05FA962AC08B0D22277E578206A165A9E3D31A084B4492C664448AA62986B55FE8C8420816A5A9C035644F592969FD0951B6E9AA57303D1F9927FF6B3DE99263E2E11CD8317CFC899A45706746E9850922B9A4F9CDE515623F3C48B86379C969969934CCBEC4BEA3E9796889CBCC56285E9A85F0B3471BF9692F3C72FFD945089B9A262AC1A8844C38C807F7274708AA0587F94A107089A99694FC627291C30FD6B0430ECA692DB54A96019EAF89635CF54F579A63048070B7F32DD2C32A18E2B7E8400344412E9DC5943BF3AF11B4AA6C328499DA7C220670958A22BFFC89B8F0091C8665B6605571D8A1B5C934CE4686C7C047AE416BC6E39B7CCC92CB076DE94001374217E9B8820354351CB377B4F06B7FBB69F64C7B48F781DED2CFEE998718D875EB94866E7C5135358EA4EC92849978438C77CEC1BA1803BF9933C8856657C953125EB76014BACCA8EC9BE6290936130D166B187E1463E55CAE3AD85E96E81BC574220AB0CD374AA1F657ABEA849259B4431F1A00EE59B35486BEB09302BF71B4C2E840963333B4A3BE37F8048D42A0F67C886DE9B47611555495248AD4C587577D45775F52135518793EA14582BF153C74210C36B9251609A4B28559ADE5A93203725A475971B92BEB88A69357BF83F384577CC1DFB62C70FC65401073C67A66AF878FD961BACF46C633E7CAC0E5092458CBBA0C3B69494C4C0C0DA6025CD6516C1AB89B3216BB9BA123040051563610251974A0B11BE7190504522A128CA3107938F5B18E4441B52F7944B0E54CD3946C57E7AE3475BEC06791A9F5A83EACBB12F40AC971CB475610A0E6C546998DAFE5C2ED852D7715B3DBA61B94849DEA30E28720BBCB90C7AF7FEB0AF619A0CF57D173405C82\nsk = A428A1343429CE9C3DADBB6213410E264426D1CB5C69C68E7F377BCBC454AAF867771258FAA622B6367FC5CC46E960682A3984A13230B3D7C25A69CE4AB9AF0234A109878E0CC42A9B858DC559AD3FE82C4060539C08828C51B337B7C0EA768BA646A2F04900A235A4042B88E8934D3B62821A13B67A912F162AA80953CB71C396D91B91521B6665062551E0A6CE453C233460789138CB16AC6E598F670C70D6325804CC494466710D984E3EA551F5EC60C5031E94421919F62C301181831B7FB4FC61DA443FE12784CF84B5ECF240DAECC87D711AAD10808B96233D345BA80B0469797DC03583214355E8E9A356E367A593A6898355AD129A8546A0D03B2279021889C118DB3583DA691A9AD544086540BB2178B2125F00C94AE753038486B6CDF1CF7E5A2202290B4E5AC807EB04BEA95678B52FF76C4757C68D2EB9283B8766F1A39E06C999015B1F1D5C3164338AEB432D54B338C361B9A7258981555FC2563E585A6FF60886C32343E0045746E50FE78A0A9BCBB6281ABE3474BA50E1267B3276A1327A8F128E2B5AB077618C59902C35488553F745D2A0C942B81C0AAB7AFD0C869B9B9C66C1847257CB22B018B81B25C468A9BC35A180B090F4BB90C4EC035C0078B799046833CD90F7BC2678CAB9B75B95A6B457DCA8FCB84937C01479A0B7B6DA9643DA507A2B8B1AE25373825189729BDA8B35FCEA315B3B359705CD5B486582379093E64F431309F0389FF899BEB4C3CA9689B412A210EB654F183362AB8398B1E3696DF7432BE662CBE62666471F2C056504A5C1C91017A6326ACC7306524058FD0937DDEAB972B00734F60D065A1BA8655DBA3093D161B99E698FC778B2FE782FA8EC7C62D422E17B24FD107B87A8338AE7AF6994C70D959CBFC3720B3174B9658F5D43713CD47325EB926320073F384F04E6831435524B686F2CD377C18363F8E554DBE6AF09F93C2FF2A1F4A87159472E7D7A4DB9243A1C6A636AD50735B870F1297B6D6B5303E2552A54AA5991340AA40301CA2D6BD9A765B72FBDE1C3C44A7649EA350E00CDE59628E06ACAD29888C9B73CF0AA65D44B60F086C21C6ABCBD544295317B55EA9AB1117989AB7B7304304E5612119396727943678C31CF2B1779C946B82420A557A8D6426263D33C7F71591C7857E90A7FA05158E315AE19D1046249B3011B22291CAE30501D1423674824B852C34C97258AB972AF6C5195FFA20B6CF05BA0498A529756F173349BEC8C180869293C5967454D01CB3C8EDC7A3A776DBA54C37513727A69CAACFBAAD8EC4A529A1872CA25CB4A99C38B225E379ACE27485D8B91FEF9CEB97C04322B59F533745D23720AE457FA11B3A0B831DE777D07F88ED1771FA1D89DB9ACBC7BAC471BD423ACAC482BFB29DE13881AEAAAE2F340C1E747A73B9071CC551EA59B03646B65BC2E6E04875754A77025985A026ADCD321574AB45CDA47134B560219338FC93B0A398D7F85169B4B32C2EC3A06529F8E3A57FD353327B03F87D5CB60C67074146FB460476C92619D9C23BA7A371FD9425CFC6486992959109CFA1C1A75AB9EBA4235AF63C6F8648AE7855A4EAB5C9D3923386996181980B16B02A53060E5A64A8CF3CED087BBB49B9264FAAFE731C0DEE965AC981965A28FF907CEABAC477E2C9B6DC95AAEB0531CBCB65D8B3F6251BE17ECAA89A5B57C1198EA66AF1F4461B91C360E4531C4D49269896107F10ED1F1070E68CDDB2A4E06C387F3126087A71A366A250B450BE1567DC957BBD034B66AB65FD4EAB2D89B8481EC2427A4AF3C1B861C799263F492779053A0128508C86EBD6201C876BBE8AB8053B790314047A1901C9F327207B2130BE5BCE8504BB03817A380975CD81FE0C0416986A7B74A16A21146636ABE4D2B2C5C1223D39265A6845804D49E5F160ABFE3CA21A345B5D044AFA5636C37B976F2894869BF4500C62AE9941B9B3C3E6064FEC351268243FD75BF287CAE8AAA9AAEFC1CFBA1032AD2623A6239A7F834A4826F86132B59AB24EFC9C57CBA929A64BA90271B987BC08A913298911650399429E9BFC40742DF735F7CB935EDA73A41F96CAACBB34324B29E64348C6063AEB0BCEE9066028B3340AA147B09C42752CFD6D491FFA497E17AB6C0726AEFE59C2577764A1A996FD879E58C23F1C0AC9E9372B3F0BE42C829B7B09ACB722E3189A2B3E72124895CCAB565DAE583C6C76C34C2C0075568379639869325F6E92E0B91A2D4100B2F4AA6486B756CD521E1B781A964A21B8B0C72637A2E4299FE15C1AC275FB077CF42F36453E7603C91A648E09CBF128ED188639B7247584B333003A2175BC587925111654F24680C540B32643B035FF38BB4598785524504EBCB26163D513867D74744C8B562BD48989B3A328374A125CA05FA962AC08B0D22277E578206A165A9E3D31A084B4492C664448AA62986B55FE8C8420816A5A9C035644F592969FD0951B6E9AA57303D1F9927FF6B3DE99263E2E11CD8317CFC899A45706746E9850922B9A4F9CDE515623F3C48B86379C969969934CCBEC4BEA3E9796889CBCC56285E9A85F0B3471BF9692F3C72FFD945089B9A262AC1A8844C38C807F7274708AA0587F94A107089A99694FC627291C30FD6B0430ECA692DB54A96019EAF89635CF54F579A63048070B7F32DD2C32A18E2B7E8400344412E9DC5943BF3AF11B4AA6C328499DA7C220670958A22BFFC89B8F0091C8665B6605571D8A1B5C934CE4686C7C047AE416BC6E39B7CCC92CB076DE94001374217E9B8820354351CB377B4F06B7FBB69F64C7B48F781DED2CFEE998718D875EB94866E7C5135358EA4EC92849978438C77CEC1BA1803BF9933C8856657C953125EB76014BACCA8EC9BE6290936130D166B187E1463E55CAE3AD85E96E81BC574220AB0CD374AA1F657ABEA849259B4431F1A00EE59B35486BEB09302BF71B4C2E840963333B4A3BE37F8048D42A0F67C886DE9B47611555495248AD4C587577D45775F52135518793EA14582BF153C74210C36B9251609A4B28559ADE5A93203725A475971B92BEB88A69357BF83F384577CC1DFB62C70FC65401073C67A66AF878FD961BACF46C633E7CAC0E5092458CBBA0C3B69494C4C0C0DA6025CD6516C1AB89B3216BB9BA123040051563610251974A0B11BE7190504522A128CA3107938F5B18E4441B52F7944B0E54CD3946C57E7AE3475BEC06791A9F5A83EACBB12F40AC971CB475610A0E6C546998DAFE5C2ED852D7715B3DBA61B94849DEA30E28720BBCB90C7AF7FEB0AF619A0CF57D173405C828DAB879DE09B58D0FC7ADE140393FFB5343ABBDDABDC118FAD519B14436A964CE63F8FFDA3565C2424C89B20974B748A65A5ABA75133FCB3156DFB6626A83BAB\nct = 48E85341492FA71D05723CC0673917821EF717D8C55F9BD6450037745A043EBE12E9A233C310791AD66C101D93B88861FA516333C842C610009DC7F63486830E641A34D44AB9F1E5CA2B7F8513C3C89456EBEA4859AEB7117F90ED1AAC3DCF53EAB33C5363CE46A7AE78CDD0473D4B5EF5DAC4450B95C5CF335A5A656720046E4C12A9054857946B4F356B79478E864E32848DB05A51439A8A72567CD04D82E2CC61ECFF93C154190DD3AC16910AEFF13723D93775B1626D55294BB16958BDBF6CFFDE4B1BEF349AF5E0C7A2C902066A0440E7E5408F9D840AA74C34A6A318FBD810FCAE361B3688EB8CA9EE0FB214B386FC3718EE9141EEE6156280A8236A5EE0EA14A017C08C5EB6A90DCD4771EABE95E33B3966B6C259E2C65E4C1C0D0B34CAF2DBA11FCBB30B10BF337D49416B3E20C492F6CFFB6C83DB5A5E09A8E4CFF44AF0675762E43CA34559E14C1FD7E7F9FC5CD48B02C7CB9B0B788FDCB86B17E302F0C4F9C0DF1672C59DAFC240267D59737B2E6E4DB21982C928810B58A2443AD99E64CBA79AC9FE77249622BDB56503364ABBE7B5ABCE8EDF18F1E710C4642CF794CC22DF0837EDB785D0FD3D60551C5AFC94DCD4F52F3973F4C9434060B0C2A61E046AE5600FB4C9B00271DDF543A0EBD1DE5E41B5A6C7EEB573F862820E92AE2D9D9718E21B93366F54FDC58B9E83285350AEF35191463358DB9FE8860739F6A4119A00F5351F66B06F6EF7A08DD9D387FEA300EE7059A98661D808B50E75F5415D7B82738B73E3BFB58B7905F572C7E47483781BFCE45A805E5D647F9197E5D829B0D80F5B5A617E68FB2FBEAF1A8906F6A5C72CB5D90A04F0109871FB3743D3F588056101EE96894218A2E68CCACD3FCBA9FF4791A985352CC60F7B006D95D66F4903CCBB2607C37B8DB8EB88567A4ACDD1552F8D558C1396046856AC2A828F9117113372FBDF1002A70C9EC7FCF1A8F74DE26D48E44787ECF27BA4383448AB4FA6813A9F320FB4165FBFC363488DE37D3A540D4C55610425A8DE574870CCFAACCC5414B4B9BB029D85F8408AA033EA4D7E7C3074F848A188E13FCE09840C11C3DBCECC928A2079D954BDBE08037729AA6135B68D208A9C1CA2BE8323A949CF303C8486D5258952DCD3190879E986A5EBD406B8D09CA922041643E9E647C9C4E61453C0EF9D64F14E56EFD043D257936431D287FBE3E7B0E4CF301C5A7CB0730DE2C1CB0D22CABD61C1D0006B3E3F310123FD000F41093F4A3054974BCB39E9F474055C1001D372F21A880F864147BCF855FC9351651DCCD8288C2525C7959CD9F2FC6D410278856A5B2B10AA", + "0FB6EF76F5F44ACDF0C01380E38E4A8BBE861815DBF2FB0723E60ABA41B235EAFBAE36DE07F2D478EF39B05D20610772E5D89B7C74D4F626586B8A4BA5DE91D5380A84A8092EEAE7515EF70FD9DBBC54CF9FBC41B3876489FDD481CC2D2CDA5B4231C37CEB508EBBC9712B304EF4EA2BF1E4F75D8D789FE73CA2F7FB9F03C4B48C796980FF39DF52CEB477C1B2D6C4AD1C\nss = 1DB6E99F80628E170260354EE6F3854F905D198E9669B4FAAB478F4B39CC2F0E\n\ncount = 98\nseed = DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12\ngenerateEntropy = aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9\nencapEntropyPreHash = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb\npk = BC962535672A8D77C9EAF9726CC1A8B8D87D61B1461F33B7F7F5A003A8657297CD100324FEA561BA879FFA75287D9A838275734593ABC2B842D9353906334D3F9324C7D00EED794C78310421DB45CAB6900817348D67490BF1485E85A3DFA255694915D286AB5243B62D3A91F8493F0B19626FB89C0B9109C6E1084BD8C848C06B3472A65A2646DD89BE2D922A0D2C5E816652C826854AB36F44809EE56C9F7E26A1DC30823535997A05255756704AA1029B86601E2853C2D34A192A9B2B76B31C69C1A048A76A6A58E48BC8E512B1C767347AE28AE046076C20179D0977D2D54A3F78ADD2EC6BC06071D9447F0461846FB1A5E91A760112424082C2994A98D07AAB29E818FD15134DE437C7FBC59469CE8BA80545A4A5BF337FE142B72E602D8A1B3009CC95975759AD38274E234AEF0552B8AA65CDFCAC975495A84C124F8426A9C87D8DB03CE48B0382642CB9E31CE210B774724912B09B16D88AE007AC4542C092F9BBED9C262D823D9D5719B357821D4C245F384FC923CD334B9DFF579E324A0BCFBCBA61FB7AE9F69B3AB88693E005EE32BD1A6A3CA950A22421125391A060276B07242A795085D0098906969C421CBC469128FB5393B72590FD391DCDFA3CF87B9F7A4C6CC3A1791AE1717478A5280A3B7580BBEDF88F0DD7C1C09AA67D6B284334049398BA983BCBACB8C56237BC3EFB3FBFDCB358A006457832DF7A01EFD937E68B3299580CBE1C9F69E165D22683B3721E4189ADAAA91846B7717D41BAF8D9A1DC76C387F0B55C2552533326597466ECF06ACA624FBF73226E471D835B0EE4A24A8F1C5FBE359C61D974A4D57C2F7C49822286CA27116839B784D6782C13B606B87804BA0969C7C47C7A29CE16CECFF5514028C3D84944EC8CAB4B4ACB5B681723511087E25B8AE84F3741A2DE6CC21E7A370B35C255C34555F29645D4B420494C4D993BA3F092EE240F1D3691753420891ACFC9421C361CA2186B563ED63456096227EAA738A33AB56029976C1125DCA790114AEB83AEBCF271ED59BBC2E8377301B53D697CFABB4C6B40BAE19B6CECD421A1109F9CAC7B71C749E60A2005A30179C393D5033CB4F8795DE4C98D91538FB9A8CB1654B1E6A82918471470461F54CC71FBA50DEB3E1221C55AA616AD5262E352ADB7A89CA04557A2090FB05704B9521809B8CABFA325892AB46765CEE83850586918422212C812373A1C6217BA890B4C5310F7B0D5D8275B884AA9E4914C85023AB53BEA88AD4281A7F501A87534AC1D806B0F8691E9F1BC7171001043015B391CFAC09B5FA88F840C63194632BD5A012B34B50441BA08C879C44654F136CCCBB7114F7B4099016E0193CBBAE63522927DF4B740B3CA5B32B741EA15A47370B98926A1F90618F5235357E8087443C93444803DD22BBDD5340C876D41F3AC1DB59E9EF17DB71369A315600FC6801A54483FB015AD3766284A97CBC241AD73461F4B2A0F6645EF428805762A6E57474D29288404AD98FAB63AE95E25436626BC66EE10C01E55103597288AC521B463886F863833948455319D3455110B68BF7BC495D1A922191A1A230A5F036C3C4AC05EE2609D09891CE368C01F037D818805A566193A433E924B30F4E86DC76AE2B345932A0E7025F8CE6101884469E31AEACAF4D77E3F1201BC75\nsk = FA198BB15B4278509DC232002C75A8BBF1853C474C8248B5062821E4D77FD5880979922016D17377F76A89AB9477A1024C9780FB728F6DF3295666828143C52FE817B9688C70EBA292D2716AB4970840ABC4603F597B5FCDEB0144813602242625A067EA48B426738DAD0AB986369AA5326DD199C72212C59AB20C8F63429683721A2C682C5AA853B86542698732AB86FE39C340DB2D452286FDD599336B9923599B66C144C0C7848C20A6979133FB7B5EFA3726A4F44389CB93D6A9C1B7E300CB852698C236AC00B2855861C88BAD062A25423362C7774C1626834EE59880762508FB518F926A3F475D01AA8E5C8C4140537091D494AF66B0E9426359032A2264AF67E63541C2408B1853F87C68C28C8C13417F94D77F6AC3315F23405C233E14F7762C152609AC34842553DE175A6FE1C08B44BAA9D15CF09A6049B05B69F71DF322171701AE91D050778A6754E374878169181A2E1336677889318CB54218AC055491B918BC2553023167151C98B30E1340403E0C59B3252F4D0C85EBAC1877798C41AA43C5C7B738B7CE116428C049370BA6665BE646B3125AEB947B1F3B2EC5357C7566C13EAB148C453D6B2274A9295A06C822DF9222CB2026F19603B5602D08D46D4C71384E776AF2A441894826E4559F5975C586E47BC0236B4897622AE4396160334CC97ACA101805814AE44786D1E445147A4728275C32554B9BD148AE9605E10C5A6B556704F1C17297A32EB311F1E92EE5F160E8522E06554B93B5C796E44086E75D236CA88ECC533C3B348091891E35639BD6CBDB3A408720B6E3A328C4268454169267A5C5348703C412C58846C192E0A162014600DBB351424FA8D0599775BD2D851DB4B07438F655AAD6402628563DB3A435F75D440636CD64041DE162D178C923490839F190F106BE0020AB63E7B3EB718A4FB59E01057C416C330CC26E485A6D9C72B707DA0B297C0A25247D26D40F044844C2DB883A5BBFC2B06F1BFBCCC6D10B65C9BDBFB806D7A04CD71774DD60BC423C1DFA897A0512365CD54A90BA6AC509298BF6455363583843925281AA405C291F11695CDA995A9AC5F742351560B38F8720D66327B4DCC47626744241679247CBE42695B8D81C37C718CAD53D1B318F9F900757267C43B982F26639901028F8F636C35091F1CA90A1E329D5CB069A918F45A078F33AB4DFD248390627926AADDFF47ECEF1718B2B048304CD40E72FB0872B6207856A61BD764034E82BB426747405E1AE5B93C63CB12C7BF09E47E27117D26ACBC102B043616E60B714316DFC17306A77800EE87E03E4B74759794EE6943DC274AEC1A08197A841E68F258202B1124803064F6E3295DD51AD18949A5A383A81363BB00118A8569A38D138BF8835362C723E999402D3CF728B0E11F647CE2B9390615B9E50487E23CEE6F9CEFC4A1CE5E83D28D642E3C16934B43931158CCEF3832A457A5E833F317918858807AB084F687A394C257ABCD8435CD717D1E6B79E78A37BB71A236729839B89A9905B5D935AFDC2C1E6C71C597898C6A69765BA05E9784B7849C685AB5B6DE3358C6299D8A4B075045D6EE15B639601AA95603A67378157B54889C3021453E373208CD06C0DEB77BC962535672A8D77C9EAF9726CC1A8B8D87D61B1461F33B7F7F5A003A8657297CD100324FEA561BA879FFA75287D9A838275734593ABC2B842D9353906334D3F9324C7D00EED794C78310421DB45CAB6900817348D67490BF1485E85A3DFA255694915D286AB5243B62D3A91F8493F0B19626FB89C0B9109C6E1084BD8C848C06B3472A65A2646DD89BE2D922A0D2C5E816652C826854AB36F44809EE56C9F7E26A1DC30823535997A05255756704AA1029B86601E2853C2D34A192A9B2B76B31C69C1A048A76A6A58E48BC8E512B1C767347AE28AE046076C20179D0977D2D54A3F78ADD2EC6BC06071D9447F0461846FB1A5E91A760112424082C2994A98D07AAB29E818FD15134DE437C7FBC59469CE8BA80545A4A5BF337FE142B72E602D8A1B3009CC95975759AD38274E234AEF0552B8AA65CDFCAC975495A84C124F8426A9C87D8DB03CE48B0382642CB9E31CE210B774724912B09B16D88AE007AC4542C092F9BBED9C262D823D9D5719B357821D4C245F384FC923CD334B9DFF579E324A0BCFBCBA61FB7AE9F69B3AB88693E005EE32BD1A6A3CA950A22421125391A060276B07242A795085D0098906969C421CBC469128FB5393B72590FD391DCDFA3CF87B9F7A4C6CC3A1791AE1717478A5280A3B7580BBEDF88F0DD7C1C09AA67D6B284334049398BA983BCBACB8C56237BC3EFB3FBFDCB358A006457832DF7A01EFD937E68B3299580CBE1C9F69E165D22683B3721E4189ADAAA91846B7717D41BAF8D9A1DC76C387F0B55C2552533326597466ECF06ACA624FBF73226E471D835B0EE4A24A8F1C5FBE359C61D974A4D57C2F7C49822286CA27116839B784D6782C13B606B87804BA0969C7C47C7A29CE16CECFF5514028C3D84944EC8CAB4B4ACB5B681723511087E25B8AE84F3741A2DE6CC21E7A370B35C255C34555F29645D4B420494C4D993BA3F092EE240F1D3691753420891ACFC9421C361CA2186B563ED63456096227EAA738A33AB56029976C1125DCA790114AEB83AEBCF271ED59BBC2E8377301B53D697CFABB4C6B40BAE19B6CECD421A1109F9CAC7B71C749E60A2005A30179C393D5033CB4F8795DE4C98D91538FB9A8CB1654B1E6A82918471470461F54CC71FBA50DEB3E1221C55AA616AD5262E352ADB7A89CA04557A2090FB05704B9521809B8CABFA325892AB46765CEE83850586918422212C812373A1C6217BA890B4C5310F7B0D5D8275B884AA9E4914C85023AB53BEA88AD4281A7F501A87534AC1D806B0F8691E9F1BC7171001043015B391CFAC09B5FA88F840C63194632BD5A012B34B50441BA08C879C44654F136CCCBB7114F7B4099016E0193CBBAE63522927DF4B740B3CA5B32B741EA15A47370B98926A1F90618F5235357E8087443C93444803DD22BBDD5340C876D41F3AC1DB59E9EF17DB71369A315600FC6801A54483FB015AD3766284A97CBC241AD73461F4B2A0F6645EF428805762A6E57474D29288404AD98FAB63AE95E25436626BC66EE10C01E55103597288AC521B463886F863833948455319D3455110B68BF7BC495D1A922191A1A230A5F036C3C4AC05EE2609D09891CE368C01F037D818805A566193A433E924B30F4E86DC76AE2B345932A0E7025F8CE6101884469E31AEACAF4D77E3F1201BC75919A696301240CD6129F66BE58E19D99B0D827D9932785CD9EA3D92F7BA54463FDA268813EFAB5204EFA60F78BF81D320D01AC09AC06244F7AFBD2D80FD356D9\nct = 11A268DB2BEE6743849F2492BEA30B6C7458C3AA74364BCEFBC00502E30BBC3D38A6B35E56F73C84774660D3DB94F1224715F9ED1DFF8B76E7D714C68D85F5681DAE7E6928102EA340FA3D892D6E0B22C7CE2D4156BF0B68A63DD0390B49856E397E063B14AC2ECD40CFDB807F794B258F2893B4626A7D1A6A2B9CD1F1D3F0D74249E6CA9ECF42E527F11E1AF6D4FA34DF25A1E2", + "36422F83965A5535533BBAB735114794A16A3378A7E64C86FD33402C4E1A5244750EBE3AE44086134B25C7317A60B1F0989D12348618C1BFA05A9E2A9B34B500637DFB96471186F63AC4CB7407F2C636440133B30B8D9957CAB6585D71EAE68CB330431AE66B334B3B90A299E890852A785FCF51B772E3C0FA0980D89B51ADE1BCA47F6F53384566F03A0F2BBEE9FE38931F593401C4A14D9070B18CA7A905C698063A3080256619819B593BFB31FB7CC643D073B166F5D41482041871ECE479918F1F1F121F55EE63A2D12A581E839436F3E4CF5C338518F84BEE8FC08BFF8B107ABEBACC3AB9FFBB0D922D9AB1C0EFAC50D5C82F458968413702719800DB5AF2AE8DA624653889B642F09ABB3EC2464ECF548FB8EA1AED42318EFC9AAE51CD7EA08883C1546AE0D87950B9BF49DAA72F3006AFFCAB882681C8F6DCE038EF3C7653C7D91E975EDB5B6283CA48A93CA55F84027CCAE22A666351633A4414DF8FDEC7004157A174A38811351BAE1339D897FDE8BED32D491B88648EB022577F16C5165D1323B7203030B649E89B07571933AF62B5F2764A05DB9842332AD171B6A7968F87AB14809D0A5C11EA8541F733677AAA809979F4F389201F27EB240F378BCFA6D5AB63AF483CCEA73ECA4ABE515810D89C8E472CB7BECD19EBFE54D70CD035FBAB8E87AF97E1396AB607B64A752C869A92214581E0EF343305E1174236D26FE10F36810872B08268C59385D7B03A5D3389F5F840E65C12C50C576D4D99072929F378EDE448A5AAF01CC582D4692C655004C561E4A653120F9A3D27789D63EF5EE62F340D2FBCB72728A64D3FC0C04F19C7675A80A1001889F7C2A8FE7761475A26018573F9B079B7C770A3B0DC8193F1C86B29483F0725D3F52A1C9D7004AF1DCE7794811F98C1BB8320FC3AF0995989F583A4F6112FC00B05D1CB4EBB1D8A40F8F99A8085B28DEB6129AA524DF1AB6613AF704CCA378525719C71680E189C19E8E49157F29E2289697DA776B4EDC11502B75FF7B62BEF945E04A195759DA9522F9CDA1A3F8DECFB227A734A7D16551E57659B7AA9F9C5D27C67F02FA1ECD003446B58FF6912B274B22ADCC05048FD7CAB9E151B933A641E2441D841352CA90C2615058AC1206101A3CE973609EBE82F3FB0443C96107E52E6346B68F248626FBFEB726CDFD3F103A1E2E9733DDDE3E2D6A5D5DC482657FA26EBC2D5723E6506F1624B745380F1A515FB6498A2AA6BB79681BAC39242C6ADAF4D02571EEAE7DF7416F833D74EBC0929D9F7B53A439C185B9C8D50E2BB9B81F3562A56B756929FA9DF3CA7906A28E8CF\nss = EF8DE288A7CE14CCD5172A4A2F91588559E3780A75B1DF329A53B1E400C4C7F5\n\ncount = 99\nseed = 2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B\ngenerateEntropy = 195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21\nencapEntropyPreHash = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176\npk = 28441CC07C18856568C4FC0EDDC04175F564BDA148788608B71756367551A5709127668EFBD60B389877001B948F2C50CE62C7ED63122DAA7C1889400A4175AB959D09AB124BEA2C9D3659B8B4861E482EDED950DBF57A47C87F79FBC143D20420F4162F711963C47DCF7B8EA7FAA329D6A70F601D3A1B15A7890804917C84477D95F916A3761E3D94A0B0D69D9B7C39692B7F4ACB9091F87583810CCF67BDF86C4BE8F08762F2C3428646A3D33DF4B67EB87A2662353A208403BF59334BD9758A9439F8D8BDD45195F2255282A73456D168A2B249E8D180D5B310BA828685B3A1DABA2FB88783BB5062C13B79C2B0C3A10085664377EADBB477329567D1158882085850B95697248C6271F44988218777D33823AD70791BD40E29825ED124B963E05D06547C740A5AB7A1488E38C464B53B6F016BA1B7648A14AAA111907846C5DF162F61CC62747386915724A3B054E868BC04C934D64B7F2FF461AAE980FA806CCA7A9C4D7255564B420887946F7A72E4D1384D8222C70330B09C08D9A70AA176529F0685D087B8F9EB464A776F93606B05D0729FD2AFA7969EEC2662EBB7C7FC821D6B5393707ACF25C0C2C81702CB195F8CF730E8A46442E91E18FC7577F4AAFD6933450491EE24763BF6786D794D889C3005A323CEF2A8863C7AE00998D2E3CCC1F5A6C8A933D5D615CE82AF312990969C6288B6893C42142AD87AB483362461B87C641F646410EF5B393283230220A34730397188920B6873F16478331CB22A5A2C73273D865985533A1F8E109DBDE719C10C8ED87A831AB65562751EBBB15D3D5B6E01F78DB26A54E47943D6B31F916A552ED01A39F96DFF820765D6AE52265010545162D509F6AC3F9B7C0FD0ECAD4008732D6A9DF9449B2017B389522F11870704127BC6D018E0A420DD441EBF636C31B3B63DA9C00DC15BE0B3188371BBC855254217B99294815D78194FDABCD1970E31E38D37B4B1CC69BF428514F50AC9BCCA9125E6473028571BE535FCA274651752DAC691FF8A28C555036378B260ACB060FABA9573B0B65CBC76B892425294D65658F4A1B3309B424C6865BF1AB307B88022087F97F6882D4360ECD91F3D2513059A784BB256E47670AFD5C1AD5C177142A2955B082FD0B546577CA5286E0F1C85AF8B0BD5650038609E8EC8344E6CCB6DF93A056644CB89294FA19266948E9A561BFA66517A900B67F6BE5EFB853C703CCB4A296A493C24607A6AC4A749361D8F738080A80CA62AAF658B6A972894E6CA402AF3C09D2A6E9C181005E0C4D193361859011173BC8B97755FD1085B52808373B29733A7D0488C5F890364ABB9716920C074645AE023679BC9C2B3AD29B9051A94A124A43688A1027C35B90F9303664AA37AA92284F97DBCC7AD0F12B5B6BA38CE0A07130110518C74EA36CA6D6A44399A3983101458F926E0BB3357BAC5A294446463814806AD1623185F295D27F2C913C9608314174B2BB8BC03A92DB6CC6F044D964A7E3E289EA8F064D9B5C0D0EB43357495D09C0FBC4069903BCDC683763BC4C6ACC2517B7C94E3E0265029BFF55773421BC6143A38F57410BFB50BF21BAFEC948548A87667D95439BB78CCA2C9DA670BEB4C816478683B5487A4CE6401EC27A1605F879E2D9C53BF27E165246401CAD7840A077934B8\nsk = 55873EC8C5BAC259501E025FAED327B9B659B0810E7D43B8BF7A25A8C1A51062CFBC9BBEAB182747196797913398DB1C1CA41C1CC3A883400A29797AB4CBB553076C204167AAD2208355279F504DD9A476985362898B4E423821CC2642C335C3C953C866451CECE03098D5A2AE366DDAE1A06E05547E1C0C0667CC98494BFA778EEBC5CBACCC3038F93B82E57F814799CB7A921FB14042AAC83A1B4897BC6A15C87FC94144828966C49B6CB8F842A3157B60D6B3271C3661529D8A93C7DAF7B4DE1396308C0CBBFC9F984617CBB5B1825C88BDBC4C74C58EF3D54D089613A6A431E3A59ACF4201FBB6828DB0061F1BC514DCBFE72023CF8102E9834D5D6BBA8A354FE04C6008B37F9B07857CDA1238F5A562F288F3217FFD1A1BF8B2A0FCF3AF0310C84BD6CD805C246C4A227C9BCF963093A9755CBA968E7C06CC4F987B516171461B69E013076CB652C2A0B10F1B0FC9D6B583A929FA3905BA4B6B41F19D862C82B5F170277530A278773FA740ECA749C00A61735AA1A27719CFB75EB0768956718239F43239E25A316339DB665EB9784AB581137D020B992782956522B824B3EA4CB540A4B12AD7C512046711B0463F779E1279BCD2B7238580C72DF6120850376DB48978DC717CD1424D0B5E7331B76D0AC0B024C6283C8418E5B1A7A297AA483E5D2A65F2181EDE32C69CC4B9A8C4C0B90BB17EC06336D2100766AED931876CE45435B5662DD8A5B9F545292C870A16925546AE0CECACFB737647504EA1A29D13E0BC2D060BF7480345051E9379CFB0F901B9A426641802E5522FF8B199439026B123CF9B5827FFA147567912C46C88CEF0B41D9526D227A72262C0E3B3157DC4898E07CAEBC8038142B5172A799B8A6DB0F7703730C98E1957FEF13D5D7B2A52945EFF5C4337B6CC5004BACBB419BA73568AA357F61C70383447C6015A5896B9C0C0A2F2C7A76D940278D736D6B685F4FB3CC392CAAC1830B439468B6BC73585B4205751E55103099986308702A477588611A990580D88657024FA6D371550141405A8240109824788675D2546AFAD54628E93281ABCCAE4EAC11D200AA5C40A9E440D9F2A40DEB31C2688A3266C9E16B60461087DA271A1973374C99693C8111F9D458F92AC3208268078B177C818038305AB421B6D8297063061BB36F1318BB2108163A723A4BFC3C2A25F958F28B2B806A15E4310B8852103843C8AC26C7773084F1F82151C52083E69772A049123027916F039FD08713B98039F3B84CC83A8F88B2C19F48A958A443339A5A2158DFD7A08D11983601A1892A8C1152C602EDB1592C3AE555B2EE54C5DC6020C0B95626FC06D85D78120AC135FD369DE6B6AA902BB015A7BC3BA13A7391960C533D2F1A6278494E78B6A3C5B91A2B1AA2A0752E5C0A30E33CC86DCBA2E3232C98B9AAF1BBDF9E825B15A6DC3A741D43A53EB10AD18E93541E224EC5A952D673984990AF0D81577D1BC83B09856794D11707FAAC63A1E49A799224B51464916BC07F0A69F06F26696F5806E92CA4ADA050CDA48A9C90635A9C68ACC753A711115C35488758A68256A32F4964C431D50C0A8C5053D1A41126A952270A309F69931C32194FD201BC3809DB548A000558528441CC07C18856568C4FC0EDDC04175F564BDA148788608B71756367551A5709127668EFBD60B389877001B948F2C50CE62C7ED63122DAA7C1889400A4175AB959D09AB124BEA2C9D3659B8B4861E482EDED950DBF57A47C87F79FBC143D20420F4162F711963C47DCF7B8EA7FAA329D6A70F601D3A1B15A7890804917C84477D95F916A3761E3D94A0B0D69D9B7C39692B7F4ACB9091F87583810CCF67BDF86C4BE8F08762F2C3428646A3D33DF4B67EB87A2662353A208403BF59334BD9758A9439F8D8BDD45195F2255282A73456D168A2B249E8D180D5B310BA828685B3A1DABA2FB88783BB5062C13B79C2B0C3A10085664377EADBB477329567D1158882085850B95697248C6271F44988218777D33823AD70791BD40E29825ED124B963E05D06547C740A5AB7A1488E38C464B53B6F016BA1B7648A14AAA111907846C5DF162F61CC62747386915724A3B054E868BC04C934D64B7F2FF461AAE980FA806CCA7A9C4D7255564B420887946F7A72E4D1384D8222C70330B09C08D9A70AA176529F0685D087B8F9EB464A776F93606B05D0729FD2AFA7969EEC2662EBB7C7FC821D6B5393707ACF25C0C2C81702CB195F8CF730E8A46442E91E18FC7577F4AAFD6933450491EE24763BF6786D794D889C3005A323CEF2A8863C7AE00998D2E3CCC1F5A6C8A933D5D615CE82AF312990969C6288B6893C42142AD87AB483362461B87C641F646410EF5B393283230220A34730397188920B6873F16478331CB22A5A2C73273D865985533A1F8E109DBDE719C10C8ED87A831AB65562751EBBB15D3D5B6E01F78DB26A54E47943D6B31F916A552ED01A39F96DFF", + "820765D6AE52265010545162D509F6AC3F9B7C0FD0ECAD4008732D6A9DF9449B2017B389522F11870704127BC6D018E0A420DD441EBF636C31B3B63DA9C00DC15BE0B3188371BBC855254217B99294815D78194FDABCD1970E31E38D37B4B1CC69BF428514F50AC9BCCA9125E6473028571BE535FCA274651752DAC691FF8A28C555036378B260ACB060FABA9573B0B65CBC76B892425294D65658F4A1B3309B424C6865BF1AB307B88022087F97F6882D4360ECD91F3D2513059A784BB256E47670AFD5C1AD5C177142A2955B082FD0B546577CA5286E0F1C85AF8B0BD5650038609E8EC8344E6CCB6DF93A056644CB89294FA19266948E9A561BFA66517A900B67F6BE5EFB853C703CCB4A296A493C24607A6AC4A749361D8F738080A80CA62AAF658B6A972894E6CA402AF3C09D2A6E9C181005E0C4D193361859011173BC8B97755FD1085B52808373B29733A7D0488C5F890364ABB9716920C074645AE023679BC9C2B3AD29B9051A94A124A43688A1027C35B90F9303664AA37AA92284F97DBCC7AD0F12B5B6BA38CE0A07130110518C74EA36CA6D6A44399A3983101458F926E0BB3357BAC5A294446463814806AD1623185F295D27F2C913C9608314174B2BB8BC03A92DB6CC6F044D964A7E3E289EA8F064D9B5C0D0EB43357495D09C0FBC4069903BCDC683763BC4C6ACC2517B7C94E3E0265029BFF55773421BC6143A38F57410BFB50BF21BAFEC948548A87667D95439BB78CCA2C9DA670BEB4C816478683B5487A4CE6401EC27A1605F879E2D9C53BF27E165246401CAD7840A077934B8CB6D7232426BDBDFDACD373C9190722E7BF342825F7D829185DCC9120588FC76AE77E0F9F21EABD8C0C6EEA7767F4E10FDE5C2D79B8400BF96B19014B457EC21\nct = 7F60D2E6EE01AE6FBB198364141AF9A1AC4BA1B161CBDB16B86224FA77129864F00B71AA221DD1F300BA3EAFB2694610CA8F27C24CDFCD240961C27CF42D01561CCAF742379B19085C462270636676D6DCC5786E23D3881C83CD5FFD667C017FCA1F404A15A5BD368CD95A8FBDEBCCB9771B95958BDE3F65533190C0A758586094EBB86101582DC69FCCD7C2C1900D30648F360B4C805F143C8FE201D2DE242C66378439CBD304A30C67213F364F8FCBB202FFDCC290E85E8F0F718677FF8CB81D4AB3CF0DA5640C5F61B11A240099201D0BFAABECBBBB27A4623D77860BF52DC53A3AFB65ED2FCD4E9C9B1D1A996A643140CCE0D8B801728ED51BC3A47C9003375D8B19401E1C6841379A45BD2BE02A41222C4FE63E19C978D480E2D4E353AB957A1B81B74BBC7655A3D0261C8B2B06F6642BA4A5F8DD87B98B9AE355F57F8A5F978C6372BF594DF54DD8BF7650803EE13D9094B3EE86A1C3E2C21E4FD1F143D8A95CCE869DD365C29FA004070B0BDB899138FBF1D83EB9F76CBC112016C8CE1118FBDF76C3C907D1D3CAE2BA0BA5E419814DADEF0887CDC5817CA9C7B050574CF84009A6731136B39807687D3C3D6863C5D780BD6303F10A7D311D1C2A1C87039C17C6668501D572FC9D56B249ED0E95E17851AEBB45E288A32A1206C4FA475455309CD3D759CA19C47C0128A95DBD07E67937C0324B4B53BAB7402363FB32606387E2C419C0350943C8CB4760C2AA7D2FF9B1392E528B98493A61D2DC6D85CBF9E5759106D6BD1DAD276FB3AA45AAF75EB80BDB5D83AFFD7880371562100226B4E373B421B9EB3032938205012C6C083DD9E44BDFA842E280F03373F6E7E4DB5A50B4AA0B34789AF9AD051709B1E9ABDD71AD733DCC021DFA3A63609994F0FAFC5C1D88A39D46F81FA70E6164575321C2EBBB71F32893348AF887BAD2B1720CD5A86EA3774C1EBD53B15B9F01A4B5542A5F54053107E38ACE2594170B81DCD98D1CC47FEE808BE78DEBA05491F913ADE44B8914D65865EB0EB0F7E02DCBA1DE0D4B34E70485F83F96A5E41BBC064E3458473F43A70D51593F442EE2BD5B39E2C77C53BE83B9188101E3455C513BF4B8F744286BD529DA2804F804CE48E864A15F391A6793E4609279EAD144CDA084F3087678CA971EB22ED3B4B7FB740BE0407571F58DDE930D895140AD8EA096F06A3E255CD95AD48C4A46B99FF777B16452123A28D73B4A0CC0899C0CDAA1286FBE1C5FE95FA9418B5A473CC6ADBA14AFB06F080A544E49E148E492A8CE4BA9F4B5F781436F8FE30058A46F4D49A44E1FDE1B6F07E2A247CD3973AD76D3F473CAE88A2BAB3BEB78BD1875B240B23A901A9AD3F4421E5E355EAB0D3E1E197B246EB4F0861AEFB55BFD3BB54BF2CD6FFDCDFA0B78BAA674130CA2512B7069E7C33903A0A5EEEE7AF46FAFA52DD3F2E952CF909806B9CD2AA6826E823959A4BF03847BA50A4026FA0A72B78CBF6AA7FCD4908BA3BBCBDDE68708EC0AEC44B1E35C4E9E1EB7F01AFF0D9CE48F99BA01D78CEE\nss = 4793F705AED572ACE61DB13BEDE3900F2538EADDB904988C1F015BAC605A1093\n", +}; +static const size_t kLen62 = 982; + +static const char *kData62[] = { "0\x82\x03\xd2\x02\x01\x03\x30\x82\x03\x98\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x03\x89\x04\x82\x03\x85\x30\x82\x03\x81\x30\x82\x02w\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x02h0\x82\x02\x64\x02\x01\x00\x30\x82\x02]\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x06\x30\x0e\x04\b\xe2\xb3\x39\xd2\xbdZ\x8c\x0e\x02\x02\b\x00\x80\x82\x02\x30x\"\x01\x8c\x16\xcd\x11\x86\xa1\xc7n\xc4w\xa1\x8d\xb4\x85\xc3\xb2\x02\x63p\x8b\xfb\xb0\\\x8f\x1c\xec\x0f\xc7}\xb6\n\x03_ \x00\x32-.\x12NZ`Ho\xd0\xe9\x8c\x15Y\\b\xe6$L\xfd\x1f\x30\xa1\"\x8b\x0f\xe5\x37\x82k\x19\r\xcc\x85M\xce\x64\x9b\x82)\xfeJ\xe4\x11\xd2\xe6\x01\xce\xdbTdk\ai\xb5\x19\xfb\xf1r\x84\x8a\x9c\xf1!$\xebR\xd1\x7f\x32Wh\xa0\xac-\x94\xe8LY\xa3\x43\xfb\x18yL\xbe\xc2\x84=n\xb3/\xc8r\xbc)\xec\x06\x87\xc3\x9aH@\x0e\xe6\x34\xc1J\xf7*n\xe0\f\x9c\xa2\x32U\xd6\x43,\x9dtK\xf0\\\xaa/k\xb4\xa3\xb6\x10\xe1 \xad\xa2\xb7\x31T\x1c\x92U\xb1G\x9bV\xe7\x89\x90@\xa4\x87q8\x95\xec\x43&KY\xadm\xf0\xc2\xf7o\xa0\x9a\xbb#PD\xbf\x8fI7\xc9O\xd5#~\xf6]\xfb\xd8\ad\xe0\xa8\xa3:>\xc7\x8fW\x8a\xb2[\xc9\xfc'%-\xcd\xcc\x9b\\D\a}\xf4\xad\x42\x12%H\x14V\"f\xe5\xec\xe8v2\xe3\x18\xb1\xac+\x0f\xd2\x92\x82\xe2\xd4\x42\r\r1\xb3\x8eS\x17\xc4\x8a\n\xf9o9\xd1\tU\x04\xe5\t\x15\xe7?*\xf0\x89\xff\xb1\xa8\xe3\x8a\xf8\x9b\xa4\x34\x93\xea\x46&\xcf#s\x82\x87|\xe3\xd2\x9bIS[\x99\xa9\xd4\x87\xa4\xf0\xd0\x82@\xb0\v\x8c\xb2r\xca,\xb1WTe\xf6\x88\xbb\r\x93\xac\xcbs\x90\xa8{\x16Us~~\xe3\xe1\xc5\xc4\f6^3\x91I\x9cq\x11\xf5\xd3[8\xbd\xe6\xb5\x0fr\x8c\x34\xc6\x18l\xc9\xe5@\x9c\xbe\xd8>MB\xd3\x96\x98\x14Q)\xba\xedLO\tPG\xf1\x84\x14\x65\a\x85\x82\xadr4T[\x0e\x44]\xb8,qgU s \xb9VziF\xca$GC\xd9G\xe7x~\xc6\xfcY\xe5\xd9u\xe7\x65.\xd8\xa3nX\xdd\x96k\xf4\x30\xd26\xbd\x15\b@P\xc1\x8b~\x9b\xc6y\xe1\x1e\xaf\xd9S\x82\x61\xb2R\x8a\xf2Vp\xc3r\xcd\xa9\xb5\xf0j\xc0K\x89\xe5|\x93\xb9\x1eh\xb4:\xc3\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14?18\xec\xb9\xf1\x45\xe1>\x90q\r\xc1(\xbaNo\xa0\x9c\xed\x30\x31\x30!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14\x7f\xd4[\x84\x34\xb7\xf9\x87\x88|Rzy\x02\x96X\xcc\xdb\x9d\xf2\x04\bb\xf5}\x8f\x84\xe5\x64%\x02\x02\b\x00", }; -static const size_t kLen51 = 882; +static const size_t kLen63 = 882; -static const char *kData51[] = { +static const char *kData63[] = { "0\x82\x03n\x02\x01\x03\x30\x82\x03\x34\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x03%\x04\x82\x03!0\x82\x03\x1d\x30\x82\x02>\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x02/\x04\x82\x02+0\x82\x02'0\x82\x02#\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x03\xa0\x82\x01\xeb\x30\x82\x01\xe7\x06\n*\x86H\x86\xf7\r\x01\t\x16\x01\xa0\x82\x01\xd7\x04\x82\x01\xd3\x30\x82\x01\xcf\x30\x82\x01v\xa0\x03\x02\x01\x02\x02\t\x00\xd9L\x04\xdaI}\xbf\xeb\x30\t\x06\a*\x86H\xce=\x04\x01\x30\x45\x31\v0\t\x06\x03U\x04\x06\x13\x02\x41U1\x13\x30\x11\x06\x03U\x04\b\f\nSome-State1!0\x1f\x06\x03U\x04\n\f\x18Internet Widgits Pty Ltd0\x1e\x17\r140423232157Z\x17\r140523232157Z0E1\v0\t\x06\x03U\x04\x06\x13\x02\x41U1\x13\x30\x11\x06\x03U\x04\b\f\nSome-State1!0\x1f\x06\x03U\x04\n\f\x18Internet Widgits Pty Ltd0Y0\x13\x06\a*\x86H\xce=\x02\x01\x06\b*\x86H\xce=\x03\x01\a\x03\x42\x00\x04\xe6+i\xe2\xbf\x65\x9f\x97\xbe/\x1e\r\x94\x8aL\xd5\x97k\xb7\xa9\x1e\rF\xfb\xdd\xa9\xa9\x1e\x9d\xdc\xbaZ\x01\xe7\xd6\x97\xa8\n\x18\xf9\xc3\xc4\xa3\x1eV\xe2|\x83H\xdb\x16\x1a\x1c\xf5\x1d~\xf1\x94-K\xcfr\"\xc1\xa3P0N0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xab\x84\xd2\xac\xab\x95\xf0\x82N\x16x\aUW_\xe4&\x8d\x82\xd1\x30\x1f\x06\x03U\x1d#\x04\x18\x30\x16\x80\x14\xab\x84\xd2\xac\xab\x95\xf0\x82N\x16x\aUW_\xe4&\x8d\x82\xd1\x30\f\x06\x03U\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\t\x06\a*\x86H\xce=\x04\x01\x03H\x00\x30\x45\x02!\x00\xf2\xa0\x35^Q:6\xc3\x82y\x9b\xee'P\x85\x8ep\x06t\x95W\xd2)t\x00\xf4\xbe\x15\x87]\xc4\a\x02 |\x1ey\x14j!\x83\xf0zthy_\x14\x99\x9ah\xb4\xf1\xcb\x9e\x15^\xe6\x1f\x32Ra^u\xc9\x14\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14?18\xec\xb9\xf1\x45\xe1>\x90q\r\xc1(\xbaNo\xa0\x9c\xed\x30\x81\xd8\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x81\xca\x04\x81\xc7\x30\x81\xc4\x30\x81\xc1\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x01\xa0\x81\x8a\x30\x81\x87\x02\x01\x00\x30\x13\x06\a*\x86H\xce=\x02\x01\x06\b*\x86H\xce=\x03\x01\a\x04m0k\x02\x01\x01\x04 \a\x0f\brz\xd4\xa0J\x9c\xddY\xc9M\x89hw\b\xb5o\xc9]0w\x0e\xe8\xd1\xc9\xce\n\x8b\xb4j\xa1\x44\x03\x42\x00\x04\xe6+i\xe2\xbf\x65\x9f\x97\xbe/\x1e\r\x94\x8aL\xd5\x97k\xb7\xa9\x1e\rF\xfb\xdd\xa9\xa9\x1e\x9d\xdc\xbaZ\x01\xe7\xd6\x97\xa8\n\x18\xf9\xc3\xc4\xa3\x1eV\xe2|\x83H\xdb\x16\x1a\x1c\xf5\x1d~\xf1\x94-K\xcfr\"\xc1\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14?18\xec\xb9\xf1\x45\xe1>\x90q\r\xc1(\xbaNo\xa0\x9c\xed\x30\x31\x30!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14\xd0\xb4\x17\x1a\xdb\xa3'\xd8\x9e\xd3\xf2\xb3>\x96\a:\xf2j\xc2\x1c\x04\b\xb5\xa8\xb9\xdb/\xf1\xa4\xcd\x02\x02\b\x00", }; -static const size_t kLen52 = 2636; +static const size_t kLen64 = 2636; -static const char *kData52[] = { +static const char *kData64[] = { "0\x80\x02\x01\x03\x30\x80\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x80$\x80\x04\x82\t\xef\x30\x80\x30\x80\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x80$\x80\x04\x82\x05w0\x82\x05s0\x82\x05o\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x82\x04\xf6\x30\x82\x04\xf2\x30$\x06\n*\x86H\x86\xf7\r\x01\f\x01\x03\x30\x16\x04\x10\xacq\x8a|\x89\xcf\xa8\xb0\xd6\xd1\a\xf0\x83Oz\xd0\x02\x02\a\xd0\x04\x82\x04\xc8\xeaQ,a\xaa\x9d\xf3\x90\xe1\x38\x45\xb0_\xfd\xe2\x04\x65\xe6\xff\x87\xb6xi\xb0\xcb\x14\xe9\x99\x39\xe3\xe5p\x84Wh\xf7(\xb9u\xa6\xfb\x16r\xe1\x34\xb8;aQ\x89\x18\x94@\xefs\xda\xdb\xd7\xb7\x44s\x8f\x16\x84\xa2\x99\xa6\x05^t\xae\xe2\xcf>\x99\xca\xcdv6wY\xec%Y=KE\xa5N{z\xc9\x8b\xdeOpm\xb1\xa8\xf3\xb6\xb5\xe7g?\xe9\x64\xb8I\xf4\x11\x94\x9d\x1c\xb0\xa5\xfb\xb3\x61\xd4\xf3\xa7hf\xd7\xa4\xf0\xcd\xc8@O>\xa7&@vd\xa1N\xf1\x91\xc2\xa3\xef\xbc\xcd\x42\xe5\xd2o\xff\xfeM3\x01\xb4\x99\x63\x1b\xd3\x01U\x00\xa6#\x9b\xa9\x17\t82\x18\x36\xbc \x02\xfe{\xec\xd3L}\xc9\xc9\xce\x66;4n\xea\xf9\xb1\x1a\x83\xa3<\x8d\xc7y\xc9\xffk\x1d\x35\xf6*=;\x83\x16\x64\xcf\x9f|1\x02\xda\x37\x1a\x16I\xdc\xd9p\xae\x99,\xc7\x01\xba\x42\xab\xe9M\xa4x,\xbd\xa0\xf1\xb7\xcf\xdd\xc1\xdb\x8f\x04\x87\vGO\xd5\xd5\xe7\xfcnB\xd5\x91M{\x1b\\<\x02p\xdb\x05\x91\xaf\x35\x43\x05\xc2m\xcfY#\xfc\xc4\xf6g\xf1\x84\x61J\xb6L\x15\x15\xa3\xea\x8f\x13\x15\xe3\xd2\xb5P\xc8\xae\xc8\\\x03\xb5\x63\x93\xaa\x10\xd7V\rn\x13\x45\x8f\xec\x17\\\\s\x91_l\xaf\x11\x13\x32^\x14\xf9\xaf\xaf\x43\x04`\x93\x42\x30\xa6u\xc0\x83\xd2L\xa5\n\x16\x39\xef?\xf7\x9d#\x19\xb9\xcd\xd8|n\xeem.\xffZ\xf3\xb9\xab\xe5\x64\xdc\xc2g0s\x19-\xea\xd2\x19\x1f\x1f\xe0\xd9\xac\xc9\xdb\x38t^1G.\x9e+\xcc\xb9\xe4)\xf8\xb2\xbf\x1b\xbch\x96y\xcf\xaf\xf2\x1fW?t\xc4qc\xb4\xe8\xbeX\xdb(b\xb5y\x8b\xe4\xd0\x96\xd0\xda\x0f\xd2p\x93/q\xe0\x9f(\xb7R8\x9c\xcb\x8b*\x8e\xbf\x0e=`\x05\n\x91[\xb5x\x10\x31\x00\x80\x31-\xd7\xb0\x88\xc7\xd9X\xc6\xfc;\xf4\xee\xec\xba\x05\xae\xae\xff\xcf\xd0q\xc6\xe7\xf3\x8b\x64Pz\t\x93\x0f\x34Y-\xdeK\x1d\x86I\xff\x63v(kR\x1b\x46\x06\x18\x90\x1c-\xc5\x03\xcc\x00M\xb7\xb2\x12\xc5\xf9\xb4\xa4j6bF4*\xf0\x11\xa3\xd6\x80!\xbf;\xfd\xc5%\xa0M\xc0.\xc0\xf1{\x96\x11\x64\x8e\xb9\xdb\x89N3\x89\xf5\xc6\xfc+\x99\xf5\xc2\x04\x83\x15G\xa8\xa5\xc1J\xe4v\xab>\xf0\x9b\xb7\x8d\x46\xd3R\x9b\xbd\xfd+\xbas]#gh\xe1voV+\x17\xe4~\x9a\xfd\x05H9\xc9\xcf\xa5\x83\xf7\x90\x9c\xa4(W@\xe9\xd4K\x1aKoe\x14\xca\x43\xc1?|\xec\x82G\x0e\x64\x8bo\x8c\xb2\xf0m\xeboq\x8f\xcc-`+\xc3\x9f\x13\x94\xc7#\x02\xf5\xe6\xdf-\xa9\xdb\xa9\xf3\xee\xe9?*i$kx\xffj\xd7\xe4i\x8c\x17\xd5\xc1\x36\x1a\xcaw\xb0\xb5k\x96J\xb5\x0eM\v\xd6\xd9x\xc5\xbf\xe3Y\xfe\x63\xe3\xd3<\x9a\xfa\xd7i[\xef\xd3\xa4\xa3\xb9\x1f\\@ \x95\x38-\xf5\x04\f,yw\xc1\xb6\xcct\x94\x42\x06\xe7G7=\xf5\xda>*:\xc0#\xd9J&i\x13\xa6\x93|\xf2\xaf\x04^\x9b\x88\xc7w\xd0\x93\xab\x1b\xbd=i\x90\xab\x41\xa9\xbc\x84\x18M)\x02\xc1\xf8\xff\x63\x18$t\x8f~D3\xaf\x88\x8b\x93[\x9a\xaek\b\xa2\x82]\xf3\xbe\x61\xc3\xf0-1L\xb5\xb5\x91\x0f\xfa\x81\x61\xad\xfc\xba\x91\xeb;\x9d\"AE\x0e\x8e$\xc7\x1c\x81\x95\xa8{d\xed\xa5\xecZh<\x85\x8d\x92\xb7$\x0f\xed\xf5\xc6\x31\x61\xdc\xef\xa7\xcb\x8f\xda\x43\x05\x42\xf6\x9e\xbc\x1b\x9a\xa1\xe8\x1d\x8d\x42\xdb\x80\x83UR+\x95\x00\x05\x82\x84\xc3T#\x8e\x1d\x00\xa2\x16>\xce=\xcc\x9e\xb8LY\xb2\x12\xa2#\xc1\x46P\x86\xaeu~I8w\x94\xf0'\xd8\x17\x38\x8c\xe0s\x00\xfb\xaf\xbf\xe8\xed\x85X>\xb4\x88\x04\xc8\"\x1b\xb4u\xa2\xc4\xdd\x06\xd2\x83\x42!W\xfc\xd8\xae\x9c\x0e\xd8jp\xd1\xeb\x44\x9c\xb7\x37\x04\x05\xf5\x17\xbe\xf3V\x1b\x06\x36\x1cY{e\x8d\xbb\xbe\"\x9ap\xa3\xe9`\x1a\xc9\xdd\x81<-N\xc0\x8a\xe5\x91\xa7\xc1\x80\aGztO>J\xdc\xb2\xcc\xff\x37\x66\x05\xcb\xd6\xe9\x90\xf5\xef+~\xa7\x66Q\xcbH\xb3\x8ao\x06\xba\x8b=56\xdf\x0e@\xe5\xa1\xe3\xdd\x89\xab\x64\x9c\x01\x15\x9e\x93\xea\xf9O\x9e\xf5\x8b\xf2\xc2\xbb\xe5\xc3\xa3\xe3\x13\x63O} \xe4\x66\x96\x84\x8d\xd4\xcarR\xdc\xb8\x93\xd4\xa5>nBV\x80\x46w\x86I\xfe\xf3\xb4[7\xfc\xb8\f\xd7\x63\xac\xa4\xf6\xe6\xbd\xa7p\xd4\xdc\x9b&\xcb\x31p\xaf>\xa4\xb6\x8d!1g55\x86g\xd1\x02l6v\xc9 \xf6\x0f\x30\x41\x83\x19\xf5\xe1\x33\x90\xbc{\x8c\x9b\x8ah0\x9e\xed\xf4\x88\xc9\x04\b+\xb0\x0f\xae\xc7\xe0nR\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x39\x30!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14\xe0\xf7\xa1\x1b\xf6?\x05\xadUj Lq\xca\x62G\x13(\xd5\x05\x04\x10>\x87-\x96\xea\x80K\xab:\xb9\xee\te(\xbc\x8d\x02\x02\a\xd0\x00\x00", }; -static const size_t kLen53 = 982; +static const size_t kLen65 = 982; -static const char *kData53[] = { +static const char *kData65[] = { "0\x82\x03\xd2\x02\x01\x03\x30\x82\x03\x98\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x03\x89\x04\x82\x03\x85\x30\x82\x03\x81\x30\x82\x02w\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x02h0\x82\x02\x64\x02\x01\x00\x30\x82\x02]\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x06\x30\x0e\x04\br\xdc\x9c\xcd\xe8i\xd5\xcc\x02\x02\b\x00\x80\x82\x02\x30\x35\xfd\xeexGq\x12\x87\xc2\xcf\x1c\x12\xc4zhj\xb5!\xd6\xa4\x1a\r\xd3Gk\xad\xf0\xe0\xfcXk\xd1\xf1\x1a\xce\xf5U\xca;\x85\x18~\r\x1e\x33\xcd\xf0\xd1\f&ggD\xbaq\x93\xf8\xa4\xe0\x18\xe2\x1a#\x8e\xb5\xc7\xdc\xe1s\xa9\xa6\x03\xb1::\xbd!Q\x04\x30\xf0\x9e\xb5\xc9\xee]|\xf4\xaeU\xd7\x15\f\xb3P\xa4RIt\x1a\xb3\xe9\xe8\x95MW\x11Z\x8b\xf2\xdb,+y\xb0\xee\x1f\xd2\x02\xa4LD\x1c{\xea\x81\x8d\\\x1dR\xbeh\xf1V\x96\xf1\x14\x62,4\x12\xbc~\xa4YFm\x9e\x97\xd5*3C\x85\x93\x06\xf7\x8a\xc9\xd1\xb5\x91JR\xba\xde\xca\x34\x65K\n\xc8\x8a\xb1\xf1r!@\xc6o#\xf7\x42\xb9\xec\xbb\xf1\x43\x1b\x98n\xba\xe4\xee\x33\xc3Q\xcb\fg~\x19\xb3N \xabZ'\x81\xbbt\xd0,\xa6\x16\x18W\xdd\xcf\xf9\xdc=mS,\x91\xb6\xf1\xe6\xe2\xee\xc3\xc4\x06\x62\x98\x83*\xe8\xc7\xdd\"\xbc\xd1\xeb\x1f\xd5\x33IRr\x01\x84:\x9e\xbd\x98\x9b\x44\xffXfn\x03\x9a\x96R\x9e\x1d\xa2Y\xc5[2\xe1\x9e\xb0\xe0\x8c\xfbLA\x04:NA=|\x01P\x8f\xe9!\xaa\xfc\x8bVd\xe2kHt\x9fW!>\x7fy\x12\t\x84H\xa2\xcd\xdb\xb0'4\xf1\xef<\xe5\xef\xe4\xe2\x1f\x04\x85\xc6\x00P\x19\x65\x1b}\v`\t\xe5\xe1\xd1q\xdc/^\xfa\x86\xf0\x8c\xf0\xf0\xf0\x46\xc5\xff\xc7\xcbo7\x94\xc5\xb7\x62\xcb\xbc\x44,\v\x96\xb7\x1dO\xd6\xb0XP/\xd6\xef\xe6\xfbuL\xcf\xa6#y\xd1\x94|\xaf\xffN a_\x1dyY\\x\xd2\xad\xda\x87\xb9 [gP\x82\x8b_\xb0X\x99\x62\xa6\xd2\x03\x82\xbc\x8e\x89\xba\x9c\xe5 \x9a\x42\x37_[{\xf0\x64\xf2\xc5T\"\x9e\x15\xec\xca\xf7'\xad:\xfb<\xc0\x11\x9eK_A\xf1\xcd\x0e\xca\x9b\xb5\r\xab)vg\x04\x1b\xffR\xc7,\x14\xd6\x04#\xc9\xcf\xf4;q\x93\xb7\xe2/\xe6\x1a\x32\x19\xba\x1c\x93\x87s}Q\x1dku\xbd\x17\xff\xef\xd0\x8f\x65\x37\xa0Hg\x94\xfdjq\xb3?Ni\xa9\xc4\xae\xd1\x9bx\xdd\xeb\x06\t\xca\x38\x13;*\xed\xea\f\xdf\xfe\x1f\x15\x86k\xec \r\x19\xd1\x32\xd6h\xc8&\x04\x91\x46jgR\xba\x30\x82\x01\x02\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x81\xf4\x04\x81\xf1\x30\x81\xee\x30\x81\xeb\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x81\xb4\x30\x81\xb1\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x03\x30\x0e\x04\b2\xe5t\x9b\r\xcf\xa3\x05\x02\x02\b\x00\x04\x81\x90\x7f\xa7n[s9\x15\x93\x42|\xda\xc0\x16\xa0u\x96=\x95\xc8Rke2\xe5\xce\x62\x9b\xd5\xac\x38\xd7\xaai\"\xcc\xa9\x8dt\x15\x87\x06\xbd%\xd4\xd5\xa5\xda\x12\xd9\xd9GB\x05\xf3\xb7\x17LT\xdb^\x1c\xb9\x1dk\xe2\xa8\x95\b \tq5h\xb7\x1cjl\xfd\x99\xf9+o\xb3SU\xd9\xbe\x8c\xb1&\x12\xab\x8aXh\x84\x9f\xa1\xa6\xebp3\x14\x0e\xf6\xb7\x31\x81y5\xb2\xab\x10M\xe3\x16\xbd\x7f~r\x12\xd5\x04\xd8#\x97\xca&8b,\xb7\t\x00?\x01\xe0\xf7\xff\x12%&\x99\xdc\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14?18\xec\xb9\xf1\x45\xe1>\x90q\r\xc1(\xbaNo\xa0\x9c\xed\x30\x31\x30!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14\xd1\x96\xa3)\xa9\x45\x1d\xad\xa1x\xa7\x1e\x30\xb8v\xd0\x87#K\x02\x04\b\x9c\xff\x9a\xa3\xf5p\xa8\xd9\x02\x02\b\x00", }; -static const size_t kLen54 = 2469; +static const size_t kLen66 = 2469; -static const char *kData54[] = { +static const char *kData66[] = { "0\x82\t\xa1\x02\x01\x03\x30\x82\tg\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\tX\x04\x82\tT0\x82\tP0\x82\x04\a\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x03\xf8\x30\x82\x03\xf4\x02\x01\x00\x30\x82\x03\xed\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x06\x30\x0e\x04\b1$\xca}\xc3%>\xdc\x02\x02\b\x00\x80\x82\x03\xc0U\xe7\x7f\x9c\xd6\f\xd2i\x1dn\x8b\xb8\a\xecJ\xe7\x06g\xd1$\x1b\xd5h\x13=\xd7V^\x15@\xdb\xda\x88\x36\xc9\x02\x96\xb5\xb5\xf7\x81\xef\x88\x1d\x66\x62\xa8\x83\xf7\x91\xb1&\x1f\x9b%x\n\x04\xb1\xc0\x93H\xa2\xf0QO+\xf8\x03ga\x1b\xed)\xfe?\xdd\x83\xa3\x93u\xa7\xd9\x37[\xa7\xc9\xf4R\x86\xd2?\xca\x61\\\x1e\xf9\a}\xbd\xdav\x8a\x03\x8e\x12N\x8fhnrn\xf0\xbe\"\xc7\x9d\x97|E\xc0\xaa\x31\xe1U\x81\xb3\xec\x98\x94\xac\xf7\x15\x9b\x42I\x8c*)z%\x92\x64\x92\xbdN\\\xec\xff\x61\xbb\x8e\\\xc8\xdb\xba\x97\x30\xf4U\x9e\x1b\xfa\xbe*\x90\xcf\xe8\xc0\x9d\xb0\x0e$a\xe7:\xb7\x7f\xda\x63\xaa*J\xa6\x91R\xa6v\xc9\xbe\x9f\x1b\x1d\xa4\t[\x0f\xd1\x64N\xdf\fDY:\xef\x9a\xd8\"\xa2_\x80\xb5O\xbe\x84#\xe3tw<\x9e'd\xac\x65\xf4\xbb\x34\xb7\xa4\xfe\x02\x1a\x88\x05;K\xb8\xd8\xb9&i\"\x97=\x93\x9b\xe8r\xaaM\x8fvQ\x12YX\xf1\x1a\xa3\xdb]\xbc\xea\x84\x19UO\x00\xfb\xe2WG\xca\xea\xbe\x8f\x85\x8b\x1c'\x8d\x81p\x7f\xf1VX\xe1&\x94\xd8/\xde\xac\xc8\xac\xbf\xc3\xc6g\xa6\xf4l\xec <\xbc\x9d\xd9\xd0\xa1N\x8c\x11\x19+\xb3\xa1\xdfj\x8f\xa2\xc3\xcc\xf6\xbd\tz\x96\x61 \xd4\x06\x99Lo#\x9bL\xccs\x8b\x42H\x99\x45\x8f\xcb\xc8\x46\x1a\xfbQ\x03j\xf2\"\x85\x88\x9d\x61\x8b\x16\x33\xf4\xf7\x9b\xc8!O\xb1\xcd\x30\xfc)\x88\x12\xdc\xd4\x30L\xb9\xad\x34\xde\x01\xf8\xc1\x12\xa7M\xc7\x31\x99+E\x88\x06\x34inm4\xd8\xdd\n=Yt61j\xed\x91;[\x88\x43\x46?gf\xe4\xdeR\xb4\xbf{=Ty\xaf\x8d\xf5\n\x80\xfd\xeb\x31$\xbc$\xd7!\x9f\x87\xab\xbdu,\x13\x13\x96\xabv\xfb\xb2\x44\xd0\xd2\x19\xf1\x95\x9a\x91\xbfz{v\x95r\xa9\x16\xfc>\xa9N\x01\x15=Cs\xa3\x8b\xefH\xad\x11\xbdS\xd3\f\x15\x15\x1a\xb4:\xe0\x7f\x9a\xa1\x36Gr\x92\xf0\xdf\xb0\xe2\xbc\x35\xd4\x32k7iOG\x9a\xe2\x35\x8a\x31`\xed\x80W\xe2\x9dX\x9c\x7f\x46\xd2T\x0e(S\x8b\x1f\x46\x34\"\xacq\xc7\xca\x0f\xb4\xb7z\xfc\x34W\xa5\x86\x8d\x66\\\xc7:\xdb\xf8y:\x8a\xf6\xa2\x1e\t\xc9\x10\xe9\x93:\xc5\xed\xb2\xca\xbb\x66\xf1\x9d\xc9\x9c\x42ud>\xe4\x12+g\xf8\xbf+\x98]\xb6\xa0\xbay\x98\xe0G\\w\x85N&q\xfe\xab\\\xa8\x32\x93\xec\xd0&\x90\xe4\xda/4\x8aP\xb8;{L_\xa9>\x8a\xa8\xf3\xc0\xb7P\vwN\x8c\xa0\xaf\xdbY\xe7\xac\xd1\x34NbG.\x1e^\xb4\xc9\x64\xf8\x0f\xf4\xf8\xb6\x9a\xe3~\xcf\xb7\xee\x11\x14R\x89;'\x98\xfc\x95\xa7\xad\xbf\x61\x34\xad\x1a$*Hfeu\x9cY\xc0O_=Z\x8c\xee\xd0\xb1\x17m4F7\xa0\xbaq\xacws)\xa3\x37O\x02\xd3\x7f\x0e\xe8\xce\xff\x80\x11\x45\x42\x03Z\x87\xaa\xff%\x12\x1f\x43\x19>\xa9\x62\x96\fo3\x88\\\xaa\xf9\xe2\xb4\xb9\xf7U\xae\xb5vWG\x83\xe3\xfa\x05\xda\x86\x02\x97\xb4`\xaeY\xd5l\xc1\x33\xe1\x36\x36\x94y\x9e\xad\xa3-\xbc\xb5\xa2\xeb\xdd\xcd\xcbHB\x15\xb8\xe6\x0ev[Wt$\xe6\x89\xc4\xe8\b\xa9\xfe\xb3#\xa6\xcar\xe2\xe4\xcb\xc1J\xd1\x1d\xb9^6\x97\x19|\x15H\xf1-\xeb\xec\xadRo/\xe1\x19\xcf\xcf\x98\x13\r\xcc\xb2\xa6\x8a\xda\x93$=]\x83\xfe\x8d\x9eG\xd8n\x8d\x06R}F\x84\x04i4a\x04P\x1f\x86\x92\x94\xe9\v\x13[\xf6\x16\x81\xeb\xfa\xf1\xbb\x04h\x17\xca\x35o\xbaNL3\xce\xf4&\xb7t\xab\xa5\xd0\xaa\r\x85\x11\x30Xb\xdfH\xc7\xdf\xc9\x38\x9eo\x96#/\xc1\xd4\x8d\x65\x9b\x46_\x9c\xea&`\xb5\x95\x85q\x18\xc3\xf4Ta\xca\xfeU;\xbe\x81\xaf\xd9:'\xe9\x1c\x30\x82\x05\x41\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x05\x32\x04\x82\x05.0\x82\x05*0\x82\x05&\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x82\x04\xee\x30\x82\x04\xea\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x03\x30\x0e\x04\b\xd9h\xcb\b\x16\xc8\x93W\x02\x02\b\x00\x04\x82\x04\xc8|\xdb\xa6\x1e\x33\xa4\xc6N\x13\"z\x1f\xc6\x82\xab\x93_\xf0\xa4\xe4@\xac\xdf\x16\xec\x8d\x1f\xd9\xe4\x03\xd6\xc9\xc4\x1d\xfd\xa3\xe3\xba\xfc\xcb\xd0Ge\fn]\xfc\xd2\xd4\x63\xa7\x93\xf6\x8a\x44\x8c\xfe\x84\xd8\r\xa6\x16\"\xe1\x65\x10^\x18\x44X/\xc7\x64t_\xcfs4\xe1K\xe4\xb3[\xdb\x81K\x1c\x38r\xa6\xc5\xebV\x9b\xc7\xe3=Tn\x05,\xd3W\xc9O\x80\x1e\xd7\xd8&j\xcbyFp\xfc\x45\xa7y\xab\x01\x03\xb6\xb1\x44\x41\xd9s7\xaa\xd7\xf9\x44\x93\xaf\xbb\xb5w\xeb+ .\xbd\xea/\xde\xa6/\xd6\xact\xa5\x34\xfb\xdf\xf7\x02\xa2 \x15\xc8\x61r\xbb\x7f\x04\xf6\x0f\xf8~\xc3\xe6\xab*\xe6\xd8\xe1\rZ<\xc0X\xae\xf8\x1b\x15<{\x7f\xf5\x9f\xec\xf7?0O=lD\xdd\x0eL,\x93hC1\xa8\x97K\xf6\x66q*R>:\xe6r\x8a\xe6\xe3\xc8\xff\x65h\x1a\x46!\xb3\xf0\x46|\fe\xd1\x8e\xa4\x91\x11\\\x93\xeb\xeb\xae\x46\xf4\xbb\xf8\xf3~ 0\xf8\xcd\x19\xcdT\n\x7fO\xe8\xac\xa9\xacr\x96\x80\x45*Jc\x90\x01\x19\xd0~&S-\xc4 \xa5\x1f\x89g\x0f\xd9uQ\n\xf1\xd4\xfd.\xbe\xe6\x94;l\x8c\xe3\x0f_\xceXH\xde\x8d\xeb\xd3\xe1\n\xcd\xdf\x34M\xd1[\xab\x41\x41k\xeb\xa1/\x01Jr.\xf4^Dv\xc7\xe6\x16\xb9\xfb\x10\x37\x00-\xc6;\x17r!\xdb\xac\x86{\xf5p?s\xa3\xce\x0e \xbbYL#\xc2\xe8\"\"\xe0\x02\r\xe4\xa2?U\x9d\xc0\xeb\x9a\xc4\xf3\xaa\xb8\xf1s\xecG\xe8-k\xa1@\x94\xf6\a\xb9o\x03Zx\xe5YA\x1a\xc7\xcd\x43\x10 (\x95\xe0*o\xf2\xf8\x12\xd6\x13\x7f\x37=8\xa7\"\x91\xc6\xe3R\xde\xd8\xbfx\x9a\xa4\xf7\xc0\x8c\xbf\x81( \xb8\x01\xde\xb5k\nV\x12\\b\x1d\xaf\xb7\xf2tf\nz\xc4\x9f\x1e\xc2\xa8L\xd6vmt57\x12\\\x95\xee\x98\x1d\xe2\x91\xde\x13\b\xd0YMb\x92i\x1b\xf7!E\xaf\x83\xf8\x64\xf0\xfb\x92\x9d\xa1\xd9\x61^\x00\xc8\x1anj-\xad\xa8\x1b\x0e\xaf\xea\xb2\xae\x1c\x89\xc7M,\x0fM\x8dx\x8d\x15\x9dL\x90R\xa1\xa9\xd8\xb2\x66\xb9\xb1\x46\ni\x86+\x0f\xb2\x41\xce\xe8\x8eI\x97\b\vp\x97\xcb\xa4\x33?\x83kl\x17\xce\xd8\xd5\x9b\xd4U\x9b\x99\xe1\xba\x61\x31\x36y1_\xa1\x8c\xa9wB\xaa\x8c\x45n\xb6\x90\b\xe8.\xc4riB\xca\xa2\xd4\x8a,7\xe1\xde\xb8\x98\x36\xeb\xccX\f$\xad\xab\x62\x44m\x80\xd5\xce.J>\xa5\xc5\x34\xf8\x32&*V\xa4\xdd\xe9\x92\x06\xad\xe8\x85wk\xf1\x1b\xeb\xacw\x19\x1cj\xb7\xef(p\x87\x92\x33\xdd\xaa\x30\xc1\xa0\x93\x64\x18\xa2\x91\x7f\xf7\xc4\xa5\x16\x93\xb3[\xd8S(\xc5^\xb1\xce\x97\xbc\xb6\x65\xa8S\xcd\xf4Mk\xeaoo\xa5\x1c\xf1\x0f\xcb\x04%J\xfe}\xfc\xa3\xbd\x41\xd3\x96j\x8b\xad\xd4\xaa\nv\xea;\xab\x39U\xa3\x89\x9f\xf6\xf5\x9b\x9c\x83\xf8(P\xdf\x31t\x83\xdb\xf1\x0fL5j\xe5\x64.\xb9w=\xdd\xff\xa3\xa7\x90y\xc6[\x01\x16\x38\xa8\"\xa3\x14\x13\xed\xd0\x89\r\x1f:ALWy\xfc\x1d\xdf\xad\x1a\x11\x15\x31~\xdb\x99:l\xde\x94\x9a\x45L\xfb\xa5\xa5\x31\xee\xe3\t\x13m\xfd\x19\x37?\xf6\xed\x8f\f\xceK\xd1\xe1=\xfb\x85\x00\x84\x19\xeb\xa2\x63\x1d+-!\xee\bZm\xb0\xb1\xd6\x81\x00\xb6\xd0\t\x90\xb4\x84\x17\xd9*<\x1dS\xc6\xc1\x8b\xda\xae\f\n>\x1c\x8a\xc4\xd6\x97]H\xe7y\x80x\xaa\xde\x17`](\x15:B\xb7\x85\xc8`\x93(\xb0N\xc9\xf7\x46\xe7\xfcN\x9f\x9f\x12\xdf\xcbn\f\xafq\xda\xb7\xec=F\xf3\x35\x41\x42\xd8'\x92\x99\x1cM\xc9<\xe9\x0e\xcb?Wew\r\xdd\xff\xeap5\xcc\xf5\x38\x1bW\xdfm\xcb\xfd\x13\x39\xd6\x04\xe2\xf1\xc2\xd9\xea\x8c\x9f\xfb\xb5\xfc\xe6\xa9\xaa\x0f\x43\xc9\x9c\x91\xe4!\xaf\x37\x14xF\xe1)A\fN\xf5\x93\x1d\xf8\x33Go\x9d\x8b\xf3'\xd4\xbb\xf6\xae\xfa\xa5\x8b\x41\x8f\xb4\xd7/\xc1'\xeapU\x1d\xe2\xd8\fJ^|\x87\xa4\x0e\x84\a\xd3\x38g,U\x11\xfd\x1e\xdaMf\x01\x12\f\x1b||\\\x82!5e\\z\xd2\x66\xc2+^\xb8\xb1\xcb\xdfY\xc9\x31\xb7\x17&\x96^o\x1c\x62=\x8d\x88\xf1\xd1\x01>\xf9o\xb9w\xdc\xee\xeexY\xef\xcf:\x87\x88\xa2\xea\xfd\n\xa9\xa9>\f\xf8\x7f\x97\x32\x17\xc2\x97\xcb\xa4\x9b\xae]\xe7\x39++\xa8\xe6{Qu\x1fST7\xf4\x00\xa4\xb0\xa0\x93\xb4\x33\xe7\xae(\xc0-:\xb3\xaa\xd7i\xad\xdfx\xa7\xd8\xac\xf1\x80\x82\x03\xc0\xcbX\x11(\x1d\xbc<\x8c\xe7{\x15g0\xf3+\x94\x10\x8c\xbe\xfd\xaa\x11\xd7\x99\xee!\xb6\x1bOS\xcb\x44\xffO\xbf\xf6\x43=\x12\xe6\t\xe8\x05\xdd/\xc5\x39\xde\f\x88\xe8N\x89\x8f_\xdf#P\xe6\xb7\xba\x1a\xdd\x1c\x63Q\x0eq\xb7\xf7\x39<\xd4\xe7RP\xc5\xd7\xbf\x65\x94r\x97*\xb9h\xc2\xbd\f\x97\x02t#\x7f\x11k\xea\xb4\xe4/\xf0\x8b\x91\\\xdb\xae\x10\xbf\x89\xbc\x62\xef\x99\xbf\aYX\x12\xef\xaf\xe6\xcd\x30'\xe4\xab\x44\xf7\xf9\x14\xb2]\xfa\x97\xe6\x9a\xed\x85`\x86\xd9\xb0\xd7\xa4\xe4\x00\xa8\xee\xbb\xfc\r\xe8Xz\xca\x02\x1d\x02\xab\xbd\x16PO\xfc`\xdeH\xb1\x7f\xea\xba\x45{)\xfe\x8e\xedH\xd2\x31\x64\xda\x89\x84o\xd1\xd2\xb1{\x97\x19\x38\x16\xd9?\xd6\xdbo\xabV4\xca\x34\x9cWAn\x87\x85*\xa8\xfb\xe9\xf6=\xb6\x83{\x02\xc9\xbe\xf1\xbb\x8e\xe5h\xae\xaa\xe1%\x8d\x1f\x1fRE>\xef\x33\xd8X\xd9H\xd4\xb5\xe1S!\xb5\xbd\xd4\x63\x1f\xbf\xe4\x30^\xc3\x63\xce\xdc\x12\x8c\xc7\f\xea;\xf3\v8\x8d\xcc\x9b\xe7\xa0\x14^H\x9ct\x86\x8e+w\x80\xbb\x85\xa6\xd4%nu\aY\xd6\x88\x00\x35\x03Z\xb0\x86~\x01\xa7wt\x13\xfa\x9f-\xe3\x90\xdah#6\vb!v\xdal\x05\x35\x80\xfc\xee_<\xac`*\x9cnL\xaa\xa3\xd1\xdf,~\x0e\xc0\xa0\x84\xe4\xb2\x33\x1f\x8c\xcbt1\x18[\v\x18\x41\xc6\x87\x13\xa2\xad\x1d\x43^g\xd0\x31\xf5\x61|=\x16U\x01\x94\x45\xa4P\x0f\xb1\x1b\x81Q\xa7\x92\xae\xa3mNUF7\x98\xe1\xe4\\)y\xc9v\n\xb5\x9d\x1b\x8a\xf6\xab\xebin\x17\x88\xeb\x82\xfax/\x8c\x30\xfd\xf1t\xcdSx'C\x82\x05\x37\a\xb3L\x89\x9d\x00\x1ds\xad\x0f\xcd\x63\xbe\x9b\xa9P\xa5\x43t\x86\x87\xbc\xd9\x97\x66\x84\x35>g\xce\x92,x\xc7\x88\x19j\x1c\xa8\x93\vy!\xe5\x39\x1b\x00h*\v\xacj/\xc1\x9c\x90\x18\x86\x63Sr4\xd9\xa8\x92\xce\x64:\xeb\xba\xd8\x31\xf3\xfb*\xac\xc6\xe7\xd1\v|\xfc\xbbiW\xc8\x97=\xdb\x81w*\x9f\a,yi\xbcQ\x0eh\x11\x00\x10\xed\x9f\xb8\x8d\xa0% \xd3=\b F\xfa\x89\xefiL`3\x80\xb9S\xb4{\xab\x38\xf1\xcd\xb8u\xc4\x85\n\xda\xab\x19@\xd3\x88\xd5\xf7_\x8e\xcd\x8e\xa4\x1c\x9c\"m\xce\x66)\xfa\x62o\x01\xdc\x46\x45\x38\x64\xf7\xc4\x94\xfdHDpM\xef\xf0K\x95\xf8h\x8d\xb7\x35}\xc6\xf5\x97\xce]\xad\xe8\\\xebO\x9b[\x03\xce\x33`\xf5\xce\xcc\xfe\xfbw@\xc4\xf4\x9d\xf3,\xdb\x83\xc2\x1a\xf2\xb6\xbe\xfc,\x7f) 5P\x00`\x03\xd2\xb3\x03\x18\x64\xb9\x64\x98\x33\xdbGC\xe2\xa1\x85y\x9b\xb1\v\x0e\xbb\x14_\xb9\x16\xb6\xc3\xf6\\\x01\xe3\xaa?\x03\xad\x18\xeb\x0e=\xa3\x1f\xccMHD~\xda\xb9\x9d\x17\xe8\x92\x46\xea\xf5>\x05N\xa7\xb5\x94m\x95\x42\xa7q\xfb\xc2\x45\xd6\xd2\x86\xd0y\x99\x1f\x96x\"\xeb\x05&\xf2\xa1gg+\xae\x1d(B\xd6\xbe\b\xf6\xb7T\xc8\x82\xbf\x92\x0f,\xbaG\xe2\x01s,\xd7\x34\x84/\xb6\x41\x84\xebz\xb2\xf9\xdd\x31\xbe\a\xb4\x88\x05\xd8\xe1yU\xe6K\x8c\xdc\xd1vXrB(\xb3\x9f\xd0\x05\x37ket\xce\r\x01\xa9I\xc5\x90\xab\x90\x16,\x9c\xba\xcb\x94\xc7\xfa\xe0\x39\x82\xa2\x88\xd6\f\xc4M\xfe\xb4\xbc\x87\xe5\x63;k\xf0\xd1\t9\x8fQO2\xae\xed\f\xffyR\x19\xa9NE\x11\xc3_\xd6+f\xe3\x9c\xbe\xbc\xda\x65%\xcd\xf5sE\t\xf5]k\x83\x45(\x98,XD\xca\x37\xeb\xc3\xc2\x10w\x14y\x9b\xd8\xb2\xbf\x45\xd5\x63\xe4\x37\x42{-\xe2I\xb3\x18\x8e\x86s\xf1Y\x8a\xf2\xd3\x8d\xd6\xb5\x8a\x05\x02\x02\b\x00\x30\x1d\x06\t`\x86H\x01\x65\x03\x04\x01\x02\x04\x10\x61\xa0/\x8d\f\xa1\x03\xc9\xdf.\x81\x65\xe0\x63pU\x04\x82\x04\xd0$\x1e\xf9\x1d\xc4\xe9\xbfI<\x1eUJ\xd4\xb0\f\xdd[\x92\xb2\xed\x18\xac\x66\x90\x1b)=\x10\xad\x02\xe7\x17\x83\x44g\xba\x11o\x05\xf5\xf7\x37\xcbZ\xe9\x0e\xc3K\x1b\x62\xee\xb2\xb7\x14\x85\a-\x95\x83\xa9\xdc=K3\xadh\xbfT\xf8\xef%\x05@\xcd\x61\xbe\x12\xebxu6\b\x8cZW\xa1\x98\xd5\x42\x01\x1bL%\xc2\x18\x9f\x91\xfex\x88\x99GZ ,71\x05\x98\xef\x91n\xeb.\x86\x90\x61\xb1W\x1a\x05\x82\x14\f\xa8\x94\xaeV{\xd6/\x8b.\x91\xa6\x12h\x1f\x06\t/\xa6\xed\x33\x99rV\xe5\xf7\xea\xcc\xcf'\xa5\xadIZ\xbc{\xe3\x62\x63\x8f\x00+\x96\xc5?\xaf$\xba\xf6\x8d\xe2\xef\x18P\xd6\xd8O\xb2]\xb7\x96o\x02\xf7}\xf2\xa2{\x9b\x13\x98\xde\xddn\xb5HR\x8e\x44\xad\xe0\xcf@\x9f\xfd\x88\x33\x66\xcejI_\xe7K6\x93\x7fIb\xc9Z\xae\xa1\xca\xf7Z\xbe\x85w\x9a\x8f\xceM\x84\x81\xd0\xa2\xee`\x92\x86\x16*\xd5\b\xb6Xc\a|A\xac\x97O\xf0\xcf\xd8\xd2\xb1\xd7\x1d\xe5\xb8|\x04+\xd9\xee\xf7\"\x88\xa1S\xdb^[GI\xeb\xcf\x04xi\xd1\xfc\x8a\xa9\x61\x92\xbf\\\x7f\xdeIB\xfc\r\xc2\xa2\x8f\xba\xdf\x12\xa4\x62\xfb\x8d\xd3\xc5\xf9\x85L\x17p\xb7\xf7\x99)R\x92\x36\xc5K1#\\\t'<\xa0v]\x92\x99\x63\x88\xca\xad\xed\xd7\x85\x98/\xbe\xaa\xa5\xf3\nv\x13\x01\x90\x8a\xe7Z-+\x1a\x80\x33\x86\xab\xd8\xa7\xae\v}\xcd\x64\x8d\xa6\xb6\xfb\x83\x9f\x91#\xcb\xda\x63\xd0\xde\xf4\xdd\xaa#IlD\xfao\x12\x13\x90\x37\xde\xa3rE\x1a\xa7\xab\x01m\xd6\x34\xe7Q\x0e\x33\xbc\t\xbf\xb6\x16\xf8\xd3\x11\x11\xd1_\xaa\x32\xb6[\xe7\xbc\xdd\xaa\xe4\xed\x42=.\xf7\xa1\x06\x39\xd4\x00\xc6\xc8\xed\xb5\x96\xc1\xbfL\xf1\xf6\xc6Y\xf4\x99\x9c\x10\"\xa1:\xcd\x94\xac\v\xc8~)\xbc\xf0\xae'z\xb8\\\xa0\x13\x36\xb5\x19K,\xc1\xceIW\x1d\x36\xf0\xc2L\xdfm\xc9\x64h\xcb\xea\"2\xd7\x11,w\xbe\x01\xa3\x82-\xa1K\x13\x93\x87=\x01t\xc6\xc6\xf9\xae.\xa1\x44]Glo\xc6\xce\xef\x32\xf8\x8dSM\xa5\xf0\xa0Q~\xd8\x35U*\x04\xb9\x42\xa7Q\xba\xad\xce\x88{\x93%\x9d\x03\b\xfau8cx\x13\x11\x9d\xf6\xcc\x18\xe3\x99\xa9]\x90k\xbf\x9ci\x99\x63'5\x8a&\ag\xd1\xaeW\xec\xc0\x45n*BF\x8f\xe4\x84\xc7g\x06\f\xa7~\\ \x80\xdc\xc1\xe4ztv\x8f\x41x\xcej\xf9\xcb\x7f\xe9\x17pE\x01\x9a\xc3\x9c\xa2h\xa0y\xfd\x44L\xc8\xa0\xaf\xa5\xba\x0f\x03\x30\x43J\x1d>\xd4\x8e\x1fm\t\xf9\x63\xde\xd2\x9ew\xe7\xde\x61Rv\x0fm7\xf7\xc2i\x96\x9d\xc5\xd9\x15\x10\xf2\"\x1f;\x83\xb3\xb4,%6\xc3:$\x17\xed\xad\x11\x1f\x46\x31\fj<\xd2\x1a\xe7\x41\xb3u\xd8\x80\xb3\xf8+\xab\xb5\x81\xc6^@\x9aw\xaay1\x1fy\xfe\x0f\x0f\xb0\x36\xb7\xdc\xca\xf6\xbf\x80\xebx\xc6sj\xb3qi\x9c\x1d\xdd\x90\xd9s\aC7\x19\x7f\"\xa4\x9aM\x98\x66\x10[\bb\xb3\xd8/Vh\"\xdf\xd1\xa2ZE\xf9\xb4\xb9\xf2HN8\x1a#6mBV\xbb\x32\xe3\x00\x84\xa9\xe2\xba\xb6\x86\xc9\xa6\x64\x8a\xd6\xa6\xc4\xd7>\x8b\x34\x1bke\xfe\xb1\xc9\x93\xe1\xeb\x8a;\xf1\x0f\xdb\x84\xe2-\xf8i\x04\xee\xafX/\xc7\x96pM\xd9L\x1dR8\xc6&'A8\v\xa5\x1c\x16\xd0\x1d\x32\x99\xb9\x1f\x35\xaf\x02\xb0\x13\x0f\x95\xd3\x9b\xd6\t\xcc)F\xe8\xf1TM\xb8\x96\xa6\rYa\x1f\xee\xaf\xbc#X\xff\xcf\x96\x91\x1f\x00\x80N\x9a\xa2\xe0\x00\xf7>\xb1\x91l)X^\xe7\xc7#\xfa\x88\xf7\xfb\v\x0eJ\x04\x46\xe0g\x10\t\xea\xc0\xa9\xbe\x83\x11\x33\x8e\xfb\xd6\xd5g\xef\xb4\x13M\x17\xa1\x44\xb7\x98w\xd0\x63\xe7\x9c\xa7\x96)\xe5\xferL\xa9\x85\x9b\xc9\xf3\xf6\x05\n(h\x99\x31\xe8\x64\x30\x9c*\x90H\x84\x00\x1a\x66\x0e>\xf7\xaa\xc9l[W{\xa9\x17\x91\x1ek\xe8\x12\xa1\xd4\xde\x1e\x38\x14{\xe0\x9a\x15\xaeZ&\x93z\xd6\x8d&a(\xf2@q\xc7\x8a-ir\x04[\xb9\xc1{\x17\xde,\xfc\xa9\xf2\xf8\x34\x33\t\x87\x91\xdf\xeb\xf7W[2\xe2\xd4\xe4Gx\xe8\x9b\x1a\xab\x44U(\x98 \xa7\x16\x8bNB\xf1\x91\xbe\x00\x87:\x91\x63\x9a\xc2\x8d\x13\x34\x8b\x33\x02\x88\x1e\xb1\xa8\am\xb1\xf5\xb3z=\x17?\xbd\xa1\xdb\x04\x0f){\x0e\x98\x18\x63\v`\xcd\xa5\r_\x1eS\xcd\xfa\xc0\xc7\x99S_\xb7\xe5J0\xde\x14\xc9IF1\xb6\x92\xf3K\xc1\xb0\xdd\xecH\xff-RSd'Lx\x96\x80\x90\xa3\xd7\xfdz#6\xa0v\x9e\x96\xfc\xcd\xecX\xf8vK/\x8d\xb9\xd6\x89\xa1W\xe1\xc6\xed\x9a\x1e\xde\xc7h\x93+.\x84\x1a\xf9\x8cX\xb8\xf0)\xfe{\x03\x84\xe8R\x1c\x01\xbb\xcc]\x88\xcd\x37\x8b\xe2-0\xd1\xbe\xf7\xc1\x95\xb7\x01\x43\xab\x30?\x96GmR)\x87\x10\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14\x14t-R\x8e\r\f\x06l2d\xd3~31h\x8b(\x1au010!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14/\\\xc6\xaf\xa7\xcc\xb5w@\xcaq\xc3\x8c\xc6i\xdc\xc6\x7fT\xef\x04\b\xf8\x9c\x8b\x12'\xe8\xec\x65\x02\x02\b\x00", }; -static const size_t kLen56 = 2691; +static const size_t kLen68 = 2691; -static const char *kData56[] = { +static const char *kData68[] = { "0\x82\n\x7f\x02\x01\x03\x30\x82\nE\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\n6\x04\x82\n20\x82\n.0\x82\x04\xa2\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x04\x93\x30\x82\x04\x8f\x02\x01\x00\x30\x82\x04\x88\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30W\x06\t*\x86H\x86\xf7\r\x01\x05\r0J0)\x06\t*\x86H\x86\xf7\r\x01\x05\f0\x1c\x04\b\xb2^\rm\xda\xaa/\xbe\x02\x02\b\x00\x30\f\x06\b*\x86H\x86\xf7\r\x02\t\x05\x00\x30\x1d\x06\t`\x86H\x01\x65\x03\x04\x01\x02\x04\x10<\x04x7\xb3\xb2$\xd3\xb5\x46 \xb7\xd2\xdd].\x80\x82\x04 :\x01\xe4\xf4W\xd3\xed\x14\xd0\x42?\xd3\x61\xee\x84\xcd+\b`0\xbdr\xa7\xd5\xa4\xf2\x13\xe9\xf0\x44\x66&4\xe7,]\xc9\xb0K\xabG\x16\xab\xe6\x06\xa6;yA\fy\xd5\x9b\x02g\xd8\x7f\xc8\x36\x37'\xb4\x44\xa2^\r8\xb8\x41\x8e:\xf1\xe9\xab\xe0\x19\xd0\xe1\xc7\x92\xd4[5\xf3yH;\xfc%\xfc\xc6\x9f\xed\x35([\xfa\xeePB\xa3\xc3\x96\xee\xe0\x87\x33^\xa7\xc7\n\xfe\xda\xe5\xd5)jW\b\x7fV7*\x1a\xa0m\xe9\x84\xac\xed\x0e\xd8\xc0\xd8\xc6w\xb1\xdd\x1b\xa1\xed\xa7y\x13.[\x9b\x80\x44\x9e\xff\nn\x99\x33\xcf\xf1G$\xaaH\xe7,\xb3\xe6\xdc\xd4\x1e\xe4\xb8^r\xaf?\xd3%J\xac{5\xb1\x82\xa5\xd9\xf8\x01\x12\x92IL\x17\a\xb2\xb1>\xcb\xfd\xd1\x17\xb5\x65=\f++\xc0\x37\x9c\xe7\x04\x9bqZ\x10\xc0\xba;1\xde\rfl\rL\x99\"v*u\x7f\x84\xd1\a\x1fW\xf0\vqA\xea\x38\xe2\xe7\xbe\x11<\x92\x8c{\x0e\xb4~v\xc4\x80\x41\xaeL\xe2\x38\x36\xcb\x82\x39\x38:U\xb4\xe2\x35\x94\xc3\xae=\xd1\x03\xf3\xdb\x00\xd9\xfa\x96\x62%\x97Q\xc5\xcf\x84\xe8\xf7\x8b/1\xeb\xa7\n\"o\xad\xf5(%\xaa\x99\x0e\xb1\x83\x9fpy\xaf\x10|,U\xfe$}\xea\x85H\x8ez\xf7G\xd8\fd\x97\xe0\x8f\x62^\xd0O!\xa4\x46\x8e(\xb0\xb1\x90\xec\x01}\xc4\xc8o\xf2\xe2\xb7\xc4\x35l\xa9\xf6\xaf\xc2\xb6\xa9\x02m\xb2\x8b\x43kA\x80\x9d^Q\xa7\x31\x00\x1b\xb5$\xed@\x99\x33\xde\x87\xd1KvxWL3y\x89\xd3\xfap\x0f/1B\x8c\xce\xe9\xc0X\xe1\x30\x30\xf1\xe9\xab\xc8`|\xe0j\x99\xe7\xd3!\x1a\xcc\x98`D\xaa\xff\xee\xec\x34 \x19\xba\x03;go\xee\xd5\xb3\xa7!W\xd6I\xaf\x91\x8f\xecp\xd0Y\x1ay\xe2\xd2\x94\x82S\xfb\xea\xd6\x83IJo\xd6\xed\x15\xc3q\b:\xbf\xde\xa8-T\xafJ@\xbc\xe5S\xaeK=p\xfe\x1c\x03\x1e\xb2\x9d\x1c\x35\xbd\x9a\xf8\xc5\xd1\xa5Jc\x18\x02\xd4\xff\xdd\xcd\xb3l8\xd1\x9a\xad\x16q\xf1\xc6\x1d\x8fl0\xfa.\x13\x9d\vN\xe6\xd3\x37\x80X&\r\x04\x97\xe6\x8d\xcc\x63<98/zs\x01\x0f\"iGT\x9e\x42\xc8Y\xb5\x35\x43\xb4\x37\x45Y\x85\xf2G\xc3\xfb#\x13\x18\xef\xd8\x11pt\xce\x97\xcf\xbf\xd5-\x99\x00\x86V\x9b\xdf\x05g\xf4I\x1e\xb5\x12#F\x04\x83\xf3\xc1Y\xc7{\xc3\"\f,\x1b}\x18\xb6\xd2\xfa(6\x8bQmX\xf4\xd6\xdf\x38\x94\xcflPO\n\xf3\xc3\x91\x39\xa5\xc9\xbc\xa8\xeb$\x1a\xddX\x9e\xdc\xb2\xee\xe1\xa5\x16h\xc2\x63\x8c\xc9\xa7\xbe\x1e\x30\x84\xa6(\xebP\xd9\xdd\x15\xea\x64\x34\xf0zVj\xdd\xb2p.\xearf9T\xaa\x36\xfah\xaa\x06]H\xca\xadN\xfeK@\xdf\x43\x46\xd6\xdf?\xa1\x9eL\xdc\xfeL\x01\t\x7f\xd8\x00\x84\x94)\x17g\x00\xd3\x46\xd2\xba\xb9\x62\x66P\xcd|zpFJ2b\xc2n\xe7^\x04$\xc5\xfd\x9d\xf4\x9b\xc8\xe9\xebs\xf9\xaa\xa4\xcc\x63\xa3\xdc\x63\xe0\x30\xecp@\x9e|cy\xae\xba\xfd\x95LF\xf1\xc4\xae\xb9\x03\xe8\xd4\xe4\x90):\xbb\xdb\xd8\x8f@\xc3\x39\x9aLpT\x9f\xc9\n\x04#\x98k\x9c\xc2\xe0\xad\xae\x30\xef\xff\x44[s.\x8f\xd7+\x12\xf0\x31\b\xfb\xb9U\xf0\xc3\x62\xbb_m\xa7\x1d\x61\xc2&\xce\xab\xb6\x88%\xce\x8b\x02\xb6\xc5\xa2\xcc\xd4\xa3t[v\xf7\xb4\xd9\x9c\x93\x86~\xac\x82\xe0\r\x83\xe1\xc9\x7f*\x86\xbb\xaa\xfe\xdc\x17\x9c(w\xe1X\x18\x15\t\xe3\xda\xdb\x8d\xeeU\xf6\xda\xad\xe5R\x84\xb4\xf0$\xce\xa1TK\x9f\xea]M\x7fS\vy\x1d\x87\xcb\v\xa8\xef\x03\xfaXW\xf6\x02p\xdbzd\x89\x1f\xc7\xca\x87\x02'3\xc5[*P\xc5\xb5{-=\xa9\xbc!{\xf2\xbe\x9cV5\x83\xba\xce\x34\x8d\xec{\xaa\xe4\xcb\xd1OJ1\x00\xd1\xb8\x30\x38\xaf\xe8\xe3\xd7\xc2\x8c\xe3\xb4#\xb3'\a\xc6\x88\xecX\xe9Y\xfb\xa9\x11\xa2\xc8w\"j[\x86\xde\xdc\xedvnsy\\\xb4\xcf\x19v\\k\x1cK\x03\xcb\x35\b\x94\x37\x01\x98R\xd8\x31\x42=\x7f\xa1\x11\x06\a\x88\xb8\x31\x35\xb2I(\xc6,DC\xb6\xbcXvlO\xc8\xb6\x30\x82\x05\x84\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x05u\x04\x82\x05q0\x82\x05m0\x82\x05i\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x82\x05\x31\x30\x82\x05-0W\x06\t*\x86H\x86\xf7\r\x01\x05\r0J0)\x06\t*\x86H\x86\xf7\r\x01\x05\f0\x1c\x04\by1\xf9\xe2\x42\x33\xf1\xaa\x02\x02\b\x00\x30\f\x06\b*\x86H\x86\xf7\r\x02\t\x05\x00\x30\x1d\x06\t`\x86H\x01\x65\x03\x04\x01\x02\x04\x10\xc9\xda_\x96\xc8,\x85]\xa0\x30\x82\x16k\xf4\xfd\x91\x04\x82\x04\xd0\xc3\x89jVj\x84Xv\xd7#\xd5\xa8\xc1/C8\x99\xf8\x64\x97\xe7\xe8\xd2\xcf\x36\x9b~\x04\xe5\x87\x80\xff\xd5XPZ\xb3\xc0\x15\xc9\xd5\x61\xd6;\x7f/;\x98PU\t\xcf\xc3\xdd\xbd\x8b\xcd\xdf \x90\xe1\xd2\xcd\"\x9f\xa7>\x10\xd3\xb7&Te\xfb\x18\x12X\x81\xd8\xe6\x97\xdf\x32\xd1\x04J\xdb\x05\xb4\x13\xa9\x86\x62 \x94\xdc\xaf\x98S\x16\xc7\xb2\x9c\x44\x30\xc5\xaa\x14z-\x93 \xffm\x8dGio9\xd4\x15\x81k\x85\x36\xf9Y\xa5\x8e\\@b\xf8\xfe\xf7\xe6u\xf7\x37\xfe]S\xa6\x66\xe5\x0eJ#\xa9\x80K\x04\x11\x0eP\xef\x9e\x88\xed\x39\xd1_\xfa\x90\"\xa3p\f\x8b \x9c\x80,\x90.,\xe0\xe6&\x84\xd8j\xe4 \x1e\xbc\x96\xba\a\x9d\x1d=l\xd1\x04\xc8\xd1y,\x96\x0f\xe8\xa5k\x03\x06Q\xfd{D\xab\x66JA\x04\x02\x64Z@}k\x1a\xbcn\xeehp<\x10\x32sv(H\xd9\xa4\xe1!\xf6\xe4\x03\x94\x10\xef\x82\xe0v|\x99\x30&\x9a\x95\xa2\xc5\xb9\xa7\xae\x9f\x85\xcb\xf1\x82\xcd=\x06\xec\xafr\xc1\x33\t\xf9Q\x94\x42\xf0i\xb9\xc6\x04\xe6z\xfb\x1c\xee\xac\x95\x9b\x88g\x19\xa8yg\xc7\x1b\xccr\xe9\x18\xd2\x96\xcf=\xf8\x98 S\xc9\x37\x0f\x92\xb1\xbc\xaf\xc6\xecO%\xda\x95\x14\xed\xb8>\xaf\xd1RL(;\x84\x8cI4c+\xd4\xf4x\xb1\x8f\xb0\x35{\xd5\x44\xc3\x98\x9e\x85\x86\xae\xee\x05\xdd\xa1oS\xe4\xdco\xf5|~\xd8z\x9b\x18\x43?{*\xf3\xb5\x39Z\x1cr;\xdd\x01y\x97\xff\xdbX\xe5Ma\xde\xcf/\x13{\xafk\xa4\xf2Y\n\x13V\x1c\x05\x00\x0f\x18\x66\x33r\xbd\x62\x8d\x11\xf7 R)B\x83\x33\xc1\x0f\a\x80\xd4X\xe2\"\x94\xad\xec\xbf\x01\xb6q}\x92\xb1u\x14\xf2\xfbw9\r\x82\xb5Q\xba\x1f\x65W\xaahj\x17\x41\x13\x38\xc0\xe5\xeb\xcc\x8c\xdd\xb7\x00N\x01\x06%\xab\x87\x1c\x30i\xc4\x15\x0e\xf8\xf0r\xb6\x1d\x92~\xe2\xe6w\xed\xb8?\xcfW\x8d\x90\xe4\xa3yI\x9a\xe0\x1fJ\xde\xe9\x44\x8d\xd5#;\ac\x92\x9f\xde\xba~g\xb0\x82\x41*\xcd\xe1\xbb@\xf1\x8a\x66pt\xf1\x99}\xb0\vj\xa2^~\xc0\x8c\xb2q\xda\xcf\xbc\xfb\x9c\x03\x0e\x33^\x13\xb2\x34\x38\xc1\x83\x95\xdf\x46\xfc\xe0\xe0\xaf\x93\xe0p\xd5\x15\x8c/\xaeK\xa6\xeb\x13\x8f\xaf\x1b\xf5q\xc4\x62q\b\x97\x10R\xfe\xbd`\xd7\x9f\xdf=\xc5\xdd\xcd\xe7\x8e\x85`\xdf\x61y[\x90\xd9\xaaV0m\x0f\xfb'\x84\xdd=\x04j\xe0p~\xbbY\xf4\xeb\xe8\xc0\x62\xaa\xf6\xed\xca\xae\xb2+\x0f\xc1VE\xe7$k\xaf\xeb\x15&\xb2\xcd\xae\x1f\xe7\x11\xc0\x1c\x19J\xc7Q*)\xdf\x14\x82\x43\xfeR9\xba\xe6l\xa5v\x8b\xb1!\x9c \xb0\x10\fD\xf2\xd4nA\x1b\x8f\x90#\xe3\x87\xfc\xf1\x46\xc6[\xae\xd0*+x\xf5+\xb9\x9f\x46K0\xf8IW~\xb4\xff\xca\xadM\xf3\xc1{B\xe0\xa4\x37/\xe2\xb2`\xe8\xaf\xd7\x39#LgD\xe5m\xb3%\x11\x9f+\xea#\xfb\x1e\xce\xbf\xa4/\x88\xec\x18@\x16\x43\x9fq\x9c\x8d\xbd]U;\x92N#<\x87\xed_.\x8f\xde\x83\xad\x30\x42~\x1a^\xf5\xc5u\xbb\x99n\xf1\x87\xe0\xf3Q\x1e}\xe8\xfc\xc6\x88\xf2\x39m\xaes\x9f\xad\x9b{g\x99\xdb\x90\x0e\xa0\xfc\xaf\xcc\xdb\x8b\xaa\xc2T\xd5-\xb3_\xa3\n>\xd6\x8d@M;\xe5-1\xd8\xb2\x12\a\xca\x36V\xd9/U\x82\xdc\x8e\x92\xa9l\x91\x9e\"\xe4\xc6'\x8b\x1a\xa2xV,Z\x19\xdf@\xf9\xfb\x44![\xdf/\x99\x84I\xcf\x1a\x15\xa5Y:f\tM\xc1\xf2\xb1$3\xbd\x86\x41\xdc\x33\x9b\x03\xc0\xa8\xf8\x94x.\x16\x97\xef#\xee\xa4\xac:\x90\xb6\xd9\xc0\xda^&4&\xce\xc9\xf8\x45\x37\x83|\xbd\x9c`@a(\xcd\x9c\xb4\xe4\xe6\\O\xd1yB\x13\xa9o&#\xc2l\x8e\x8d~?\xee+M\xd2[\x80\xdct\xda\x1f\xbc&T\xc5\xfe\xee\xa9O\xce\x46\xaf\x90\xb0\x12\x9a\x18\x0e\x06\x05\xc7\x98\xef\xccm\xa3\x46\x91\xa5\x0e\xe7\x35\x1a\x7f\x9d\xae\xa0\xb4\n2;\xe4\xcdK>\x89s\xc9\x97\x38\xe5\x86O$\xedJC\x04\x02\xc1)\x8d\x85\xa2\xdd\xb2\x61<\xce\x8bG.\xedK$\x94\xb7\xbf\x9dUB\x95\xc2'\xe5\t\xd4 \x03 !:\xd8\xd2\xa2\xb3G\x93OZ9\xca\xd8t\xa9\x19\xa6\x9a#\xb1!\xa3\xb3\x14\xcc\xe2\x12\x91\x30\xdbP\xf8\x44t\xd6p\xdd}&\x7f\xbf\x32\x93\x1f=@\xbf.\xec(\xf5\xb1\xaf\x11\xc7Nd\x13<\xbf.\x19\x81\xfe\x35\xba\xecn\xb6\xa9\xfe\xc6\x85\x33\x41X\xab\x06\xae+\x96\x62\x1f,l\xad\xec\x1aYUZo\xe0\xebq\x8d\xb5\f\x81*9\xbdg9H\xfb\x91\x64\xad\x01LJ\x0f\x30)\xa0\xcf\x30\x96\x43\xe9\xfc\"K\xf3O\xab\xec\xbcZ\xfb\x7f \xd9\xd5\xc7\xce\x93\xa3.\x82\xd1\xa0\xc6\x16\xd5\x64-?i\x15\xfd\xf3(=Na\x01,\xd4+@Qn\x95\x00\xa4\x34\x31%0#\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x16\x04\x14G\xf4\x18\xa5K\x85\xb7\x02\xc1\x97\xffW\xb6o!E4=\x92\"010!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14\x17\x45\f\xdfSv\x9b\xce;\x12\xddG\x05m\x16\x90\x9d)\x9b\xe1\x04\b\xa1\xf2\x82\x1c\xd1\xd1{\\\x02\x02\b\x00", }; -static const size_t kLen57 = 982; +static const size_t kLen69 = 982; -static const char *kData57[] = { +static const char *kData69[] = { "0\x82\x03\xd2\x02\x01\x03\x30\x82\x03\x98\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x03\x89\x04\x82\x03\x85\x30\x82\x03\x81\x30\x82\x02w\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x02h0\x82\x02\x64\x02\x01\x00\x30\x82\x02]\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x06\x30\x0e\x04\bAF\"\xac\xe7\xd6~a\x02\x02\b\x00\x80\x82\x02\x30\x9a\x05UZ\xa0\xf6\xd4\x8c^\x1c'\x91\x11\xfd\x1d\xe8\xfd\xae\xf2\xe6\x9f(\xb8\x1e\xfa\xce\x88\xb4#\xd6\xfan\a\xe9\x33\x81p\x1d\xd0^\x94\x04\xf1`\x8e\xbf\xe1\xef\xf4\xd7\xb2/\r\xe9p+\xe8\x62\xfc\xd3*I\xf3\xf1\x06o*\x94\x8c\x42\xff\xc6\x80\xa8j\xbf\xa3\n\xd3\x8eYR\xea`\xe8Zd#\xac\x8d@-\xc9\xfe\v\xf3\x93R\xc3>\xea\x34\x9a\xea\x42j\xe4\t%D]^\xb4;\xfb\xe0\xc2\xdf\xd8\xaf\xae Y\xb0\x8c\xdd\xb3J_\xcal/\xe3\xb4\x99\xc6\x8fu\xc5r1\x0eLF\xe6\xe1\xbf?\xdf\x02}\xde\x35\xad\xd9\x9d\xcbt\xa7\\R;\xc2\x9cv\xbd\xf7\x96\xfc\xc5\x9d\xc7\xa7y0\xa0\x89\xd6\xd3\xa8\xe8\x63\xd2:?\x88\xc1\"\x8c \x9c\xa0#\a\xc3\xe4\f6\x19\xa8\xa3\xc4\xbc\xbc\xd6=\x80\xcbT\x91\xc4\xab\x02\xd2\x43\x30\xe5\x01\xbd%\xcd\xe4)U\x0fn\x83\xb8\xfbp\xf2\x34\x9a\x15\xc6\x16\xdf\x89\xe4\xd4\x83&\bb\x05\xa6\xea\xf3\x63\xc3\xb5ib\xf8`\\(!Q\xa4\x43v\xdd\x41m\xbdm\x8e\n\xbaI\x1b\xe2\f\xb6\x85\x9b$<\xdf&\x9d\x05Pd\x12\x96$\xdbMy\a\xa7\xb2<\xf9\x42\xca\xdag\xc0m\xf2~\xbc\x1e\\+K\xf6\xf4\x35\x82pk\x81\x16\xfc\xf1\xa9_\a,\xe9\x1e?0\x82\x01\x02\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x81\xf4\x04\x81\xf1\x30\x81\xee\x30\x81\xeb\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x81\xb4\x30\x81\xb1\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x03\x30\x0e\x04\bo\xb9\x01\x93l\rM\xe1\x02\x02\b\x00\x04\x81\x90\aBjZLAA8\xe4\x15\xc2\x85N\x88\xc6\xd3o\x9f%\xd8\x66\x86\xf3\x65]QC\xd6\x03\x91L\xeb\xbbu\xce\x8b\xf4GCL\x1aKH\x92\xf4\xaf\n_I\x96\xea\xaf\x31){\xa3\xb5\xd3\xe4g\f \x0eR\x9e\xcf\xcfj-E8Ra\xbf\x10+\xc1\xc5\xde\x04\x1d\nR\x88\a9\xc2\xc1\xd0\x44\x39\x9f\x46\xf2i\xa4\x30[\xe4`hi\xb0\x95x\x05\xef\xe1\x81\xc2\xd2N)R9Q\xfc=(\xe1{Xv\xcf\x35\x33/\xef\x95v\fR\x11i\x17\x90q\r\xc1(\xbaNo\xa0\x9c\xed\x30\x31\x30!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14R\x8c?r\x8c\xcf:\xeb\xc8\xff\xc2\x8cHB\xa6\x1c\x42n\x18\x43\x04\b\xea\xec\xdc\xf6\xc4\xdf\xda\xd6\x02\x02\b\x00", }; -static const size_t kLen58 = 2566; +static const size_t kLen70 = 2566; -static const char *kData58[] = { +static const char *kData70[] = { "0\x82\n\x02\x02\x01\x03\x30\x82\t\xbe\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\t\xaf\x04\x82\t\xab\x30\x82\t\xa7\x30\x82\x06\b\x06\t*\x86H\x86\xf7\r\x01\a\x01\xa0\x82\x05\xf9\x04\x82\x05\xf5\x30\x82\x05\xf1\x30\x82\x05\xed\x06\v*\x86H\x86\xf7\r\x01\f\n\x01\x02\xa0\x82\x04\xfe\x30\x82\x04\xfa\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x03\x30\x0e\x04\b\xb7 UZM?\x0e\x89\x02\x02\a\xd0\x04\x82\x04\xd8:\xcc\xd6\xcbMT\xc0\x04V\x10\xccI\xe4\xe0\x10s\xfb\x1a\xdd\x1dOnU\xe3\xa4\xab\xf9&\xaa\x42T\xa0\xd1\xf0\x8d\xbfq}\x18\x00\x17\xb3\xb7\x63P\x8d,\xeb/\xe3\xc3\xbf\x93\xc8\x46H\x99G\xe2;\x8dq\x01_Y[a~\x1f\fn>\xc4t\x99\x98\x30\xff\x37{0\x19\xb5\xfci\x94_yi4\xda\xb5!\xcf\xfer\x87\xe8})~'%\x90\x80\x98\xdd\x8d\xbf\x42\xb0\x10\xd8}m\xfeo\ra\t\xfd\xb2\x9b\xeb\xbf\x1c\xca\x33\xbcN\x19RUS\xb4\xa5\x98l\xa3;\xf8\xa4\x8dy\xcf@\xf2\x89\t<8\xab\xae\xf4\t;\xb6\xcb\xdd\xd7\xad\xe0Zqd\xc9\x0f\x18\xac<\x12\xd4\"T$\x1a\xa5\x35x\x99\tJ\x18\x95#\xb9\xf7\x89?\x13\x43\x1f\x8dvk\x04\xdb\x64\xf4\x8e\xf5P\xa0\xae\x1c\x8c\xc8\xf3\xde\xf3\x11-\xfev\xf0\xac\x46T#\x03I\xfas\xcd\xe0\xa1lfM\x1b\x99W=aa\xeb\x61@\xc7\xd6\x41\xbe\x63!\x1e~\xb5\x0e\x94\x93\x37\x41\xe8\x91\x06\xd7\xa3\x33x\x17\x17Yx\x8f\xaf\xed\xf9\x90\xfb\xb6\xc8\xa9\v\x10\x1a\xf1\xab\x10\x11\xbc\x7f\xa5-4}{\xaf\xc8\xb2\x00k\xd4\xbb%\x9b\xc7\x14\x8bP\n\xd5,\x1f\xa0_\a\x1d^\x1a\xa4K\x85\xb2\xa6\xe2\xdd\xb7\xda\x11%Q\xbfrPS\xa1=\xfa\x1d\x34u\xddz\xe0\x90V\x14\xc3\xe8\v\xea\x32_\x92\xfc.M\x0e\xfe\xba\x1a\x00m\x8fu\xacILy\x03.\xf2\xcc\x8e\x96'\xb8\xe9\x1f\xd8\xe0\x06\x18\x1b\x8e\xb8\xa3\x96\x34\x19;\f\x88&8\xe7\x65\xf6\x03O\xc8\x37n/^]\xcd\xa3)7\xe8\x86\x84\x66\x37\x84\xa0IN\x8f;\x1a\x42\x9f\x62\x1f+\x97\xc9\x18!\xd2\xa5\xcd\x8f\xa4\x03\xf8\x82\x1e\xb8>kT)u_\x80\xe6\x8f/e\xb0k\xbb\x18n\r2b\x8c\x97H\xd3\xaa\xf2^\xb8%\xbc\xb5\"J\xac\xcf\xdc\x8bH\xfc\x95\xf2\x17!\x1e\xda\x13\xd3\x1b\xe2\x37\xd5\xbf\x92\xe4\x81\xf5\x98WQ\x14\xda\x80}Jj\xce\x17\xaf\xdb\xc3.\x84;\x1e\x02QJ\xc1%\x8cZ V\xee\xecY\xcf\xd7>_9\x9f\xbfMN\x94\xb1\x1d\x83p\xc0\xab\xff\xfa|.[\xfbW?`\xb8\xf3\x36_\xbfj\x8co\xe0\x34\xe8u&\xc2\x1e\"d\x0e\x43\xc1\x93\xe6\x8a.\xe9\xd9\xe0\x9fVP\x8a\xbdh\xf6WcU\xbb\xe7\xfe\"\xca\xdc\x85\x38\x39\xc8\x66\x02(\x0f\xe0\x1c\xd6\x0f]j\v\xd8\xe5j\xebT\xb2\xe0\x02o\xe2\x42\x89\x66\xc2\xd5\xc6\xe2\xb2\x04m\x8a+H\xc2Q\a\x8e\xf3\x91\v\xb7Un\xbb\xbf\x11Z\xcb,\xb3\x1e\x61\xd3\xdb\x90\xad\xba\x10\x96\xe2\x16\xf4\fG\xbd\x64\x66z\x17\x63\xb9\x02\xcbSz5\x92t\xc3*}\xc5\x11\x18/\xa3\x62,\xc0\x87\xd3\xd3\xba\xcb\xe0\x86\x9bK\xc5Y\x98~2\x96U\xc1=Z\xcd\x90-\xf8\xb7\xa8\xba\xce\x89\x64\xa6\xf3\x1b\x11.\x12\x99M4E\x13\x66\xb7i{\xc5y\xf5k\xc2\x1d\xc8?\t\x18\n\xfc\xf7\xaf\x98\xc2\xc7\xcc\x85)\xc6\"zw\xab\xb5\xac\xf7\x9ep\x8e\x7f<\xf1\xbd\xd9z\x92\x84\xc5\xb8V\xc3\xcb\xf7%\xad\xda\x0e\x1c\xe4hf\x83\x91x\xf1\xe7\x8c\xaa\x45\xb6\x85t\x9b\b\xff\xac\x38U\xa5j\xea.uq\xd3\xa2\xdc\x1c\xc0\xc7\v\xa9\xd5~\xf9\x63\x82\x87\xb7\x81\x01\xb9\x31\xdf\x41\x35\x0e\xe2\x1fH\xbf`\xce\xb0\xb4\x38\xa5\xb4v\xa3\x80\x1f\x93W\xf2\x05\x81\x42\xd1\xaeVm\xc5L\xab\xa6$*\x02;\xb1\xc4u\xcf\x15\x90\xb5\xf2\xe7\x10i\xa0\xe3\xc4\xe6Rc\x14\xb4\x15\x91\x8e\xbaz\xad-\x9b$t61\xca\xcbKZ\xbf\xd3N\xb4\xc1HDt/\x83\xe4\x39=\x90-2\x12\xf7\xfa\xd3\xe3\xdbO\xe6\xe7 ,W\xc0\xf9\x80\xe1\xdc\x1c\xf2\x05T5\xf6\xbd\xfb\xbd\xc5\xb2\x82\x32\x63\x32\xca\xf4\xf7\x14\x92\x87\x8a\x45\x37V\x93\xdaO\x04Y\x03$\x93\x1a\vN\xdbX\xbf\xda*\x0e~\x98l\f\xeb!\xf9\xbf\x9b\x1f\xc0\xef\xd3\xea\xcb\x99^\x14>\x10\xfa\xad\x38\xf7h\x9f\xa3\xcc\xdf\xe5\x31\x91\x98\xdet_{\xce\xe4T\xd9Q\xec\xf5K\x17_\x99L\xf8\x00\xe0\x10\t\ad\xae\x61;`\xa3\x89\x38\xc4\x80\xf2\x1e\x11&xr\x05\x97'\xba\x83\x33\x1b\x14K\xc0\xc8\xb0\xcc\n\x9b>L\xde\x12\a\x11\xd5\xf0\xc0\xddp=\xd8z\xf7\xa2\xf2p\xadT\xcegA\x12)\x1f\xe1I_LwA|t%\x9c\x91\xd1\r\xa5\x9a\xb8VL\x01\xc0wQ\x14\xc8\x92@\x9a\xbd\x7f;\x9b\x17\xbb\x80nPd1\xed\xe2\"\x9f\x96\x8e\xe2NTn65\xfc\xf2\xed\xfcVc\xdb\x89\x19\x99\xf8G\xff\xce\x35\xd2\x86\x63\xbc\xe4\x8c]\x12\x94\x31\x81\xdb\x30\x13\x06\t*\x86H\x86\xf7\r\x01\t\x15\x31\x06\x04\x04\x01\x00\x00\x00\x30W\x06\t*\x86H\x86\xf7\r\x01\t\x14\x31J\x1eH\x00\x65\x00\x65\x00\x36\x00\x64\x00\x38\x00\x38\x00\x30\x00\x35\x00-\x00\x30\x00\x36\x00\x64\x00\x39\x00-\x00\x34\x00\x32\x00\x65\x00\x32\x00-\x00\x38\x00\x62\x00\x36\x00\x38\x00-\x00\x66\x00\x65\x00\x61\x00\x62\x00\x35\x00\x65\x00\x66\x00\x32\x00\x38\x00\x32\x00\x37\x00\x30\x30k\x06\t+\x06\x01\x04\x01\x82\x37\x11\x01\x31^\x1e\\\x00M\x00i\x00\x63\x00r\x00o\x00s\x00o\x00\x66\x00t\x00 \x00\x45\x00n\x00h\x00\x61\x00n\x00\x63\x00\x65\x00\x64\x00 \x00\x43\x00r\x00y\x00p\x00t\x00o\x00g\x00r\x00\x61\x00p\x00h\x00i\x00\x63\x00 \x00P\x00r\x00o\x00v\x00i\x00\x64\x00\x65\x00r\x00 \x00v\x00\x31\x00.\x00\x30\x30\x82\x03\x97\x06\t*\x86H\x86\xf7\r\x01\a\x06\xa0\x82\x03\x88\x30\x82\x03\x84\x02\x01\x00\x30\x82\x03}\x06\t*\x86H\x86\xf7\r\x01\a\x01\x30\x1c\x06\n*\x86H\x86\xf7\r\x01\f\x01\x06\x30\x0e\x04\b\x92\x16mmh\xd3\xb0\xc1\x02\x02\a\xd0\x80\x82\x03P\xeev\xe8`\xbf\xca<-\xe5)\"\xf6\x33\xc3Pj\xdb\xf3X<\xd9|\xd8\xf9\x83\x89\x17\xa8\x1bk\t\xc1\x99I\xb0\x43\x06\xc6\x42K|\x85K\xe6i8\x91\xce=<\x97\xd5\x14O\x15Z\x81Mw@\xe0\xe1\x1ci?\x1d\x65h\xb3\x98\x95\x30l\xb0p\x93\f\xce\xec\xafW\xc6\x9c\x34\xb4+\xaf\xc3^p\x87\x17\xe8\xc9T\x06\xb5\xb7\x83\xff\x46+\xb6jf/m\x0f\x96Sfe\xb8{HU\x83\xd3\xc4\x16\x93\xderY\xf1\x9a\xab\xd5\xd5\xcb$\xa6JNW\xf3n\xca\xb1\xeb}\xdb\x02\xd2y\x89\xef\xa2\x8b\xeeo\xdc^e\xa5\t3Q\xb5!\xc8\xc6\xab\xed\xd5P\x93\x39q\x97\xd3,\xdd\xaf\xb1\xc6\x9bKi\x98\xae\xaf!\xa0\x8a\x90%\xe0\xf4\x8c\xf2\xc3Od\xb6\xc6\x64\x90\xff\x95\n\xcc\x8c\xf4\x86\x80S\x8dQ\v\xcd\x45O\xcf|\xc6\xdf\b^\xa7\xdfO\xcf\x84\xde\xb8Ms@\x06\xbe\x33\x82\xe8\x41\x1b\x9a\xc3[\xb6\xf3\xfc\x32\x98\xcc\xcc^\xd5\xb7\x86\x0f\xc8Yr\xcb\x9a\xc5I\xd4-/P5\xeb\xb8\x10\xa7\xea\xb1\xe2\fj\x84,\xe2z&\xef~k\x1eGn\x98\xc0?\x92$\xe7\x88\xf9\x18x7\x8aT\xa6+[\xf0\xc7\xe2\x98\xa4\xa6.\xc3jufQ\xe8\r\x90\xfd\xa7\xec\"\xb3}\x9d\f\xfer\x7f\x98\xf6\x86\x30\xd3|\xee\xa5\xc5 \x89y\x04\x8e\xa8\xb6\x94pNu\xe5\xa0\xae\x8c\x7frL\xd5\x9f\xd2V\r\xb2(E\x99\xf8@\xd4?BJ\f\x92#\xe1\x17\xafh\xa6\x0f\x1d\x32\r\xf8\b\x8e\xdcyh\xf0\xfe\v\xda\x94-\xa6\xa7v~\xd6\xca\xec|7ROw\xcf\xa3\xcf\x8a\xfe\x89\xd9>\xbc\xb5\x06\xa0!\x91\x89w\x84\x85\x43*e\xecuM\r\x1cy\x0f\x61\xca>b\xbb\x41\xf9L\\;\xde\x33\x8e\xdfQr\x93\xca\xa6\xc7\x16\xe5\xb3\"\xb6.\xbf\xae\x1d\x91\x1dI\x96\xa3%\xd4\xceo\xf0\xfb\xb7\xf5J$\x03TK\x7f\v\xb4\x31\xb4\x33\xb7@\xf0\xd5L\xee\xe3K\x12\x8c\xc9\xa7\x06\xb1\x02Z\x14o\xe2;h\x9b=\xfc\x83J\xcc\xb5w\xe7\xf0\x1bR\xce`\x89\xe2\x45v\xaavp\xc2\xfd!\x8f\x1dg\x1aL\xe8\x81+.\xa9V\n'\x0f\x81\xba\\O\xfan~3}x\xed\xd2\xe3$\xae$\xb2\x1b\x62q\x0es\xfe\x8a;\x98\r\x82\x8e\x8d\x0f\xb3\xe2\x65\x87\xeb\x36\x91M\x8a\xfb\"z#,\xe1\xb6\x94\xb6\x90\x94\xcc\f}\x02\x36V\xda\x45 \x90H\xdb\xa4\xf5'\xac\"I%\xaa\xd8\xa7y8\x80\xc0\x95\xc7\xd1\\\x17|\xa7\xec\xd2\x63\xc6\xc6U\xfex\x99\x06,nO\xfe\xd1[\x8c/\xa1\x42\x03&Z^\xda\xef\x43\xd2\x0e\xf9_\xdb\x1d\x9c\xd1\xcb\x65\x84&\xed\x91\x8f\x16\xb4\x1c\xc0\xb3\x8dy\xae\x9b\xcb\x36m\xcdg\x1f\x87\x11*|\xb1\x8c\xfb\x06\xab\xd2\xd6*\xe3\x45l\xa5\xc0\x19k\xfc\xc3\xb7T5\xda\xdf\x12\x97\\\xacY\xb4\x42%\xef\x04\xf7L\xdbt\xb9h\x8f\xee\x37\n\xc6!\x86\x0fo\x8e\xab\xd5{8^_}\xb9Z\xcb\xce\xa0V7\x13qK\xba\x43|\xc0\xb7\x7f\x32\xd7\x46'X\xfc\xdb\xb5\x64 ; \x85y\xa8\x9a\"\xaf)\x86\xc5\x9d#\x96R\xca\xc7\x9d\x92&\xe5:`\xd6\xad\x8dZ\xd9)\xbe\xd5\\:w\xda\x34\xe2v\xcb\x98\xa4\xf3\x33\xf1h \x83\x95\v\x8d\x93Y\x02\f\x8f\xe4\xc4\xb0\xe7\x61\r\xf9\x80 X@\xea\xb7\v\x1b\xad\xe3\x30;0\x1f\x30\a\x06\x05+\x0e\x03\x02\x1a\x04\x14-wyy\x90\x41u\xf4J\x7f\xf7\x15\x94(b\xf7i\xd4\x44'\x04\x14+/\xd9$\xc3\x8a\x34\xbbRR{\xf6\x0e{\xfe:fG@I\x02\x02\a\xd0", }; -static const size_t kLen59 = 74392; +static const size_t kLen71 = 74392; -static const char *kData59[] = { +static const char *kData71[] = { "# RFC 8439, section 2.5.2.\n\nKey = 85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b\nInput = \"Cryptographic Forum Research Group\"\nMAC = a8061dc1305136c6c22b8baf0c0127a9\n\n\n# RFC 8439, section A.3.\n\nKey = 0000000000000000000000000000000000000000000000000000000000000000\nInput = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nMAC = 00000000000000000000000000000000\n\nKey = 0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e\nInput = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f\nMAC = 36e5f6b5c5e06070f0efca96227a863e\n\nKey = 36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000\nInput = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f\nMAC = f3477e7cd95417af89a6b8794c310cf0\n\nKey = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0\nInput = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e\nMAC = 4541669a7eaaee61e708dc7cbcc5eb62\n\nKey = 0200000000000000000000000000000000000000000000000000000000000000\nInput = ffffffffffffffffffffffffffffffff\nMAC = 03000000000000000000000000000000\n\nKey = 02000000000000000000000000000000ffffffffffffffffffffffffffffffff\nInput = 02000000000000000000000000000000\nMAC = 03000000000000000000000000000000\n\nKey = 0100000000000000000000000000000000000000000000000000000000000000\nInput = fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000\nMAC = 05000000000000000000000000000000\n\nKey = 0100000000000000000000000000000000000000000000000000000000000000\nInput = fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101\nMAC = 00000000000000000000000000000000\n\nKey = 0200000000000000000000000000000000000000000000000000000000000000\nInput = fdffffffffffffffffffffffffffffff\nMAC = faffffffffffffffffffffffffffffff\n\nKey = 0100000000000000040000000000000000000000000000000000000000000000\nInput = e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000\nMAC = 14000000000000005500000000000000\n\nKey = 0100000000000000040000000000000000000000000000000000000000000000\nInput = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000\nMAC = 13000000000000000000000000000000\n\n\n# Additional test vectors that are long enough to ensure OpenSSL's SIMD\n# assembly is fully tested.\n\n# Length 2048.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72", "c924bba2a8b4e8354188ebfed\nMAC = 69d28f73dd09d39a92aa179da354b7ea\n\n# Length 2049.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc8\nMAC = d6a26654b88572e875d9661c83471c1b\n\n# Length 2050.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe", "23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852\nMAC = 9fbbb7f7adcd0cd5b46a4a520b22499a\n\n# Length 2051.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f5\nMAC = eb7cdceb97ade2a07622f8f5a4b1ce15\n\n# Length 2052.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f9", @@ -2745,9 +3173,9 @@ static const char *kData59[] = { "90485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21\nMAC = c6e5d1810fd878ac6b844c66cef36a22\n\n# Length 2063.\nKey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nInput = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21df\nMAC = f6eaae369c3cb5c05748e8d919178e00\n\n# Regression test for https://rt.openssl.org/Ticket/Display.html?id=4439\nKey = 2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea\nInput = 89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a91c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a620334270372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f141300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595\nMAC = c85d15ed44c378d6b00e23064c7bcd51\n\n# Regression tests for https://rt.openssl.org/Ticket/Display.html?id=4483\n\nKey = 7f1b02640000000000000000000000000000000000000000cccccccccccccccc\nInput = cccccccccccccccccccccccccccccccccccccccccccccccccc80ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccceccccccccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccccccccccccce3ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaccccccccccccccccccccce6cccccccccc000000afccccccccccccccccccfffffff5000000000000000000000000000000000000000000000000000000ffffffe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000719205a8521dfc\nMAC = 8559b876eceed66eb37798c0457baff9\n\nKey = e00016000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaa\nInput = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000800264\nMAC = 00bd1258978e205444c9aaaa82006fed\n\nKey = 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c\nInput = 02fc\nMAC = 06120c0c0c0c0c0c0c0c0c0c0c0c0c0c\n\nKey = 00ff000000000000000000000000000000000000001e00000000000000007b7b\nInput = 7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b", "7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff0009000000000000000000000000100000000009000000640000000000000000000000001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff00090000000000000000007a000010000000000900000064000000000000000000000000000000000000000000000000fc\nMAC = 33205bbf9e9f8f7212ab9e2ab9b7e4a5\n", }; -static const size_t kLen60 = 90795; +static const size_t kLen72 = 90795; -static const char *kData60[] = { +static const char *kData72[] = { "# Random test vectors generated from another implementation of SipHash-2-4.\n\nKEY: 5a174c22c487d0c5c1161e570d10d145\nIN:\nHASH: 9f06a76d8ae7ff05\n\nKEY: d56745469ae42734c2ad87e7c13ea101\nIN: 3c\nHASH: 9698cd8e2620362f\n\nKEY: cc7c78ae24ca106c5d771742b530cbce\nIN: 6cfb\nHASH: a94c8f359a6034d0\n\nKEY: c8de6d120462739b29b25913f75f8be4\nIN: 8bff10\nHASH: 5f12329867deb530\n\nKEY: c435d95c06085dc26060e488f0691013\nIN: f575791b\nHASH: 38824fa193583e1c\n\nKEY: 5d5853675bbe37b0034e019c8703bbea\nIN: 20be54d583\nHASH: 5586f5ed0a52d560\n\nKEY: 77fdc2467cb5cfadba4dcb02f08d5de0\nIN: 58ff9d2af71e\nHASH: acc2bf8eb5308b5b\n\nKEY: 3f1abc8a74470e697aade7bb409d8c36\nIN: 2a0d12d99b8c10\nHASH: 2349992cbb601e73\n\nKEY: ad977640b6902db5fb05c35bde85e221\nIN: 336ddbba25fc15fd\nHASH: c7a610c0743b7f8c\n\nKEY: 9eeb5f0ce1545597c93fcd236e022df9\nIN: 123569d0a53d5399cf\nHASH: 7f25736f962974ce\n\nKEY: 56d9ecda6345127adbf79e4ec0871116\nIN: b472f565c1370a620c66\nHASH: 3f3acf72be80cb20\n\nKEY: 4b5a67fad0b4c6dd41656e79e47e4ccc\nIN: 317e7ef64c39cf111212cd\nHASH: 4c8ee337c7103c0b\n\nKEY: e0e04322fb57cf43fb6809a33d392565\nIN: a783aca573cb07e82829eb47\nHASH: 3d5ca090c68d3a94\n\nKEY: 2895c38788e064541584f222900a45fb\nIN: 6381894b7947f3cdb6eca1e8c5\nHASH: 8ee7682323bbf06b\n\nKEY: c3a0b4ea71d4e824459acac0aa2caa9d\nIN: 6a9257065f991f36ba175ec177b8\nHASH: 078b76ac3dc840e2\n\nKEY: 56e7c5dc7ba9c37095117d3b78b6be0c\nIN: d9a8402bc9303b5a67c3aa0f1975ac\nHASH: f5fc32c55915e9ff\n\nKEY: ffcd0ca31dbb4c0a64bce83d4a876e2f\nIN: 4c50fca688dcc34a62bf77554af22fca\nHASH: 9e266efdc2b55efa\n\nKEY: a358acb475fe3a545aba172e6a2e606b\nIN: e2e6007adac976736a222ad2a607d4d15d\nHASH: c4bb7312a7d39486\n\nKEY: cc611d043067a99cb5572bb0121beac8\nIN: 7428cfc5fd76f0ffc59a216b142576d9ee5d\nHASH: 67dc4aa8a52069df\n\nKEY: 19c44128e61c992e625a1187036566b5\nIN: f6b8f9422f6eda5c70999737573142bd0d503f\nHASH: 35d6199bb8b26627\n\nKEY: cc690d64cbbd6766af28d5e8809804e2\nIN: 80b9e15766ecf0fd988658701328a266220528f9\nHASH: 8da47f7d2c8a24b9\n\nKEY: d097c32707d111358a8f6470c4bbd3bb\nIN: 4a174edf086a5406f36aa20f1dc5f854df264ec159\nHASH: 8dab02709978b647\n\nKEY: 79a047071edd76cc634f9510dd0113c7\nIN: 247ba72455b9a97dabab6905b0a1227635f79f3e530e\nHASH: 1364c8043fb9baac\n\nKEY: b3092acdd6023215701aa9c99ae4e218\nIN: ce36b755300273c22805eebdfe7dadb59fff0bf8167fba\nHASH: c8e50f39c0605ecb\n\nKEY: db6c7ce746a0431f8269407f8c35a4cd\nIN: 40dbedc0f4c351a6ffc058a2ff63794419b1c2ecb4759f6d\nHASH: 9f46bd8f53a03217\n\nKEY: 110301071f6676fc2ae41a5cea83b10f\nIN: 7947c7e55c5fe0fd584ade5a30f8af69cfbcc4825ca4e45fd8\nHASH: 7305e77b0e3dd8bb\n\nKEY: 976c2ee47783766ea8235001f65d256b\nIN: 912be0ef8e0e7becfa176ed4006ee8f2e77107f022e42351cc20\nHASH: 2f05ddca521adcf1\n\nKEY: 58b1de6e33ffea228e144b4f25e5762e\nIN: 02e8b89312479f1b0a6da0f7f35e6ccb50ade322e70ba2f5b0a354\nHASH: dd0547e80e8505e1\n\nKEY: bc57f28c8f461d9714b48c087164a695\nIN: 990ceb64628bbafa3c0c4bdabf465a19d075fb66918dd240ebef176f\nHASH: 7ce492853fc22eb8\n\nKEY: 16c2ffc4e03d5f17064f22fe0512eebc\nIN: 42e78f029eaaa1474268d534d1542e6019af7c311b70a3b80d89fc8394\nHASH: 5830bdb3f6cdbf80\n\nKEY: 546cec4ec1ccdd1dec16ffd684fba160\nIN: 36fa97e2d20f91a56389c84d3c2670c25afd2d551de8930c735f30dc0f8e\nHASH: cc29ae6a40051fa9\n\nKEY: dc04255c1214077c60ed57c00719c4ae\nIN: f6eddb62225c75e47636587d992abb31fb1429cf0e4bdf7ca7610833c6c145\nHASH: 8959c817d89057b1\n\nKEY: 66fa7b74c5d112044e6e26a8f056672e\nIN: 9c303c5097358b4671f2b282d2286ccb9925e22717f3e1bb16a2a7f088c89efb\nHASH: ef44eb07b3dabf20\n\nKEY: e68c0b8b0fc194402a074069fa79bcc9\nIN: 68740dd32b54ab57313b7aba7212eeaeedcd00fc34b5a295c3742361acb450c331\nHASH: 31c38d85506f95e2\n\nKEY: 5a9bda075c2c3756bb03637b833a2c7c\nIN: 0a20ae05077a2775accf3e93197c2cbe58ec0c8cb2d666a6d1c5ab8f6a88921b33a6\nHASH: 83ac7417ef2f78cc\n\nKEY: bddb529beb2c89ee5f3e6b91c786f7be\nIN: a963b7e8a6ab9ebce913d39af035540d1172488c29b85217edf02143c23183da52a3ba\nHASH: 87bfacf3844aa239\n\nKEY: 65bf6deca182d55e94ebbf8fe0df1e01\nIN: 7c95a702ffec11b19ddafcb53feb2571214b06219feae9b8a058509fde4b54e1f16cb89b\nHASH: 170b6b574e480859\n\nKEY: 7ef0aa07183687c13f800f268a00ea86\nIN: 8c2b513a5facec6f5a34f49eedcdcda7bccf99fd9de0526ceff7c81ee11797d451d62cb689\nHASH: 5d0f521bc4b1c1e1\n\nKEY: 490cc83d84a0102cd83c11f8123733d2\nIN: 1f7312100fe65f082abecc08f276ff81164b21ad7ea83d7729dfd1ef622b5c39c884b3f82e49\nHASH: 2b72bb41af9f002a\n\nKEY: 81e1981c81e5c3010ca4b048eea1cc72\nIN: 012273854b89fb3c66e4427d460e8493927d71f44ba7ed7dc2b3cd3178faeb6f0471bc31436a85\nHASH: 6d67485ebe1e15ad\n\nKEY: b47f522fa34143dbccffc3b1f4093b09\nIN: ba235ce1ad78f2566f78270021fe9f31417c3f65f1533c43ef71d6d281d17722ae4bc8eb87636c2c\nHASH: 390e3fe50119cac3\n\nKEY: 9a3fedb06d1e550dbbb4c4c6c42c7b58\nIN: 95f641d66e88414ee49060d1b7bbb2d62f326eaf6cc3c77a359ea2dbcb0526f737b4a1797e7026d813\nHASH: a58b6f3f1df212fb\n\nKEY: 9111abb078f38c77eed9ff96e25ec5ea\nIN: e1476ccebc8fd7a5f5d1b944bd488bafa08caa713795f87e0364227b473b1cd5d83d0c72ce4ebab3e187\nHASH: 30527d54ef667563\n\nKEY: 42808b700fca9f85fddfb5d590807f0a\nIN: 5f81bd275320d97416e5e50d5d185d5542a157778b2d05521f27805b925e4f187d06829a2efd407ba11691\nHASH: e58617ceafeab62f\n\nKEY: b609075989500f06abed2bfc45c83d13\nIN: dfedfc41d8a98c617adab43f94b8d55a4fb1c02bd9c4939f8517e7207d3b8227d2bb8af086dc37e2ac24f437\nHASH: 0037588ae129b9e4\n\nKEY: c9afb75085e1759dc2bb6790ae29ff1d\nIN: 01a06ae550215331ad34fc87c2e9597d2a369753009c5a5fa2044481c6126bbbeab1a9f3d49f6198565fc6db9b\nHASH: 236763204e7ce6be\n\nKEY: ca4a9f84ef63e8b62514d34f2d74b4b6\nIN: 5f670e9e199c590700b7a7fd6b777f325ceb90f05b611ab77a970dda67db8636ba82bfc8770f742a22e66d39a59c\nHASH: bb3bd93cf471803a\n\nKEY: bbb3452a0a57a75460a77f238bdde048\nIN: 6279c2ee80f83cfc3074f24e5026a3fdbbc29e95f46a4e2862af2dda8e0c49b896f8186e0a3aa527dc4fad02a7c21b\nHASH: 823931f402c9d3ae\n\nKEY: c1f2268a501653c08ce64a34b1eda186\nIN: 2b55a854ed9125c148e97ed0fd128ab7a48bd0abf150aa86f60292feb3cb02da159698a01adc48bea1bd38a8f0339496\nHASH: 050afb47067c73d4\n\nKEY: b4a12074ce0969ae5de1cbd25e4f6f5d\nIN: a1543098dc8e85c7319269c590513eafae8bc5bec292b7718ea49018e3a0ce80843ce1aa644732eb083cfdb418582a4a7f\nHASH: 7c0fb55d3f5e8363\n\nKEY: 598233eb95280098c909e3dd3f93dcc7\nIN: af6e57e39dbfe09b91e57c212977b9b5ef48d30bf8bc8764e3796b5aa82680fb590d7ec73f4ef2357c34aaf2e12b45dd1f47\nHASH: 78ab42112974448c\n\nKEY: a91a39cfbfd3a01ba163294d96d99477\nIN: 092c683817c7484996b32e6c1fb46f3754b829b1b46120bfe1bb9123d139d46f5565c8dbc11a60273bf6b8e1bc38bc9a6f1995\nHASH: 7fa74c95642f9644\n\nKEY: 0b564ed2eee9e3649ccf53fe50d8b1c6\nIN: 05f42bd7cc89c80fb6eb8d09d4f4968fc47aabc0db6ebdbdf70a416815622d6e92de69cc675671db24d021be0b6c7545aab0becd\nHASH: 708bebc79de07dc6\n\nKEY: bae7c48ecb04834a577ad26c87022cd3\nIN: 9f5af8c66983938b16fe3a2de4d59faef425ca769d3a31c62330aafa1aba57e53bfc3d61357b618f1ae01bba3efecc65a70edcc8b8\nHASH: e9d43d98f790f1e9\n\nKEY: ac86394cf9e8668900fc3e731e5573d2\nIN: b832f6c610c6f3bc5ae50b656709f26777a9cfa6266faa80d788376d7a4b0af3c84e2f14a4b538bcde23e45f0554e7a333a95224b474\nHASH: 689de641675e6b3c\n\nKEY: dd60e6ec34522428fe517767fd94a5cf\nIN: 3ed67357449c3b24b6d8a381d92a443d333532aafd1c90411a29b80ffb6566cb13762c5c8c8ef87741023ffafe8ca473f77934acbd25c6\nHASH: 30ff83beb6a4eb30\n\nKEY: 9f5c48c10551808854f2c5965f2b8402\nIN: 9b160f17162a71a9aebbca3a32939cf09ea4aaaeb98c75aa5fe0c15a8a94cdbfb7716ea37b7f0aaa9e058d93ef5800e9ec863a5df85d51ff\nHASH: 987b4b16546765bc\n\nKEY: df955ec1e84432fec581bc446b10ba8a\nIN: 44ae821f9ddb1e1bfbec2259fad2042558fb216dee7c56af074d24b94a61074f37a011a46fc7542907af3a5c03ad64b34f1940219e3c129b8f\nHASH: ed3e957005bf498a\n\nKEY: 5a901ece66329a9488bd17ad3f350ec9\nIN: 3e404145993bf0c296c97729f9f2e6eb3bf22010fe642312c8136c0da176ed4c314eaee878047cfe0705a835a8a22e7d2b29c9328370032d4824\nHASH: b5e479243d036ead\n\nKEY: 6835a439c331ce630ef771f866f045a5\nIN: 5f2d95f898406fce05b36d1cfe21c57541bcbbb9293c3dd56e6fa8519e1ee76b40c2db8097ed008e84dd47b8aaae3c2b33037f9f7af38f3f41c9c4\nHASH: 7ce56ef8daac6676\n\nKEY: 84b224c92018a348dba300d4e17cd139\nIN: 9c520b111bb008086c5815f450a6b7b6daec0925c4b0c8cf99f9f9ddb6198000a379fcb62527d7c361ccbda2597deecdd055850abc6a17251c08577b\nHASH: 3e5ab339d1f90e72\n\nKEY: b3af10ef15d3e728b36171cd7e0bfc54\nIN: b0c30990fa7d8451403c84c7cbd650847dab3e087fdf2985eda79c48deda583bc9c4957e24b0502ab6004a85bbaaba74efe9bdf2377043d008ae14e169\nHASH: 0821d1f9e241ca1d\n\nKEY: 3f0dfe713054af061ab05dec911b8895\nIN: 0d3ee8fcd134e9814641fdff20b22ddf17ffcf3f23af7327e203cf1971329f92e99622d1b8329f9a8f9244c5efbd4ce3e07f1b9779f1d84927e8fb16c030\nHASH: 0a5fe88", "9f9475d8e\n\nKEY: 62663e655ae3a122b869b11182f16a11\nIN: 82696187d910792ac92d50900677a1a0238d91cee3cd72ad949b50c53a0613add3bf0ab02c78e87f96847d5bda2bb31e4e19d92c933b1637aa00be18eec696\nHASH: a2c05353cb689240\n\nKEY: 1d3f1977fc1aaa27f459cb4de22a736e\nIN: 935e1cd9a08b1d0b57dbbc640915c6de3eec62f481cc64a27cda6a08db9e7dfa58d13dedad1ce2abfa967f059185b41f2b72114a4ba51a9a5d279f067ed9fba6\nHASH: f64a0fe86b7dffa1\n\nKEY: 96bf9034f02772a5150b0f2dfdd49c88\nIN: 2315e242205287d3e9dc5cbe317ddf3f286ad02fc4385c82bfdbd43ff6d5f425347e229faf0521acf9bbf3eb6f3abc2029c7af2506972444425e1b92aa1d6601ea\nHASH: 2ceb3eded2754829\n\nKEY: 5e2d0b77b3478b1d041b9b6784bd4e0c\nIN: f10b956532deea1838bebcb192cf256817525cb95242e5295830db8cee586e5cf3fdd0d9a5277d5a50a8dc6e4878d2cc6a549eb52bdc5beeb89ce870e65a87702eee\nHASH: 8fc78a2ca1ba1f7f\n\nKEY: b2c34273ff91123facb2e3f4ac03952d\nIN: a43e581d35caf54ece5b668df2f4a77e29bee3e1fe26add027b07e814991bc538da16f1649886e42be0a5be8b221ad155eb7489e81330ee91b194904086f91e9e71a78\nHASH: 36ea4accc3181075\n\nKEY: 828238257380186239aad56fda379060\nIN: 46f7fce30d03f04bee6559ace020e6ce72379001c20e5fb30bc7a500ce91262e0d7af70d8be30c61fee623e67a5e46db55d1dec64bd4be6af45bfff65050800194ba175c\nHASH: 7a1a36cfdd778b12\n\nKEY: aa751839cf5a43613a3b686bb22f9e02\nIN: e0848a835142871c489c772d01ca0115f226d39f94efde92178a38f87fbb371d4791f13954feb4f493bc0707c4dca732e24642cc6effa26da527ee7472c1c34c4b0b4834a2\nHASH: e144d10851a7e0da\n\nKEY: e3d027fcfc629cc735fdb70912799363\nIN: 08a51183fb0396a1633bf7a2c6ce4abd1e44d9153d7bc2a269f478269181df5ff29346366cea689a8301efca949693e1836d27d9cff181099e878b2bd53da75866f4abe0b64f\nHASH: 4a935a091f380fbe\n\nKEY: c9852a9cdd185cb16fd88ef793bdf598\nIN: 49cb5ab1bbb45afb32878b059685a40016f3add53623e23859c9384641c537e13aff631d814deed607bb6abc375c855f98744e455e937ee1c9e478c4878854166c30d0b686328b\nHASH: f2df3a49621a40ad\n\nKEY: a713bd5752e392d99947a0a0fef98da9\nIN: 15064ba012aa36887257f3f84261ac66134c36dc02d4d8688e2fb10ea36974c4fd3963144f8ff01e3132d2c69e5b57cdba82f98453238a51653facc718467ca781e73044aa368879\nHASH: f187bacabe914603\n\nKEY: 5292ed7c7317c2aa71831d03b905d0c2\nIN: e3eea270140e52ee204c78b9a4d86c0be9c74127acb4f3957b1fd380417dbd57f91fe69509126e531a62144cf7ec147b36aee7931b883a028f93993bb8068552e1ac9736775038c8cf\nHASH: a9a8c0bc50104e8d\n\nKEY: c3117a19ed788199add874b10f62190c\nIN: 112a91dad631502ec6d9a569d14cc009779bcf2ffa489ea4df85c275ec37148b25a133dcb6d4c3dbea8ed4375e7cf26885b991f96ad984880bff76a62568fc115d3762dccb4522f1a27c\nHASH: 4fc2a87b168477a8\n\nKEY: 45862eabc24e2b62acfd8833595b329c\nIN: 921a7d233720992b5d767b61f86b4d6857caa99d39e18656de8c5571f2a7295af7e0d703467e4c0b83f6f7079c63b55657776d3020424443756388ea217c2407284fc8657d3935a9b34573\nHASH: c1cc6da484446857\n\nKEY: d185262e194717d27be06c1297b8f27b\nIN: 7804f030a6d67847f53cc93052953516f66c915affba735df79df7da6d70bd511e4edb33fd712b58bfdff47d98b8acfaff064bd4e1f64828d61a82a5e72ad97573f4631fcec0ebfcbd16e67e\nHASH: f9d37ca5a7750584\n\nKEY: 53ea30bf7b1aeba84ae8e0b434a8657e\nIN: 65ffe0a087ce955a6170462711dd53fc057aeee9fb5e7a8cd866527fdce70aa4b8acc65ee4a366cdae649cb5342120cd7cbb9d536b1697cc45326a44494aedefb4f7d96fa5d0ddd104bdc6a84c\nHASH: 965ba9830abddee5\n\nKEY: 79bad8d7ff51922ef1d540b7d8d7663d\nIN: ed536d02d21049bfe6c1428ebb6a8faa481321a4977a685409b0fb2ca39d72c92d3db0ac406d56e2f15d6b6b62c73246807215bae613d283b8a35678df263fdbb6d3172c16909deb8e97d78694f3\nHASH: 4841b9dd5502f605\n\nKEY: 104104e76e645e83c7b40c6674906d55\nIN: a7546cb4e6b1b1c112aa28563028e910915c6b44b668bb57bd6623b941af4c3e22c7cf6eff2f6c474657fc5ee293db60a84944bafed2acabdbe6a6e7f0804ebed61786c2cf29cdfb0c62e8d41df81b\nHASH: d21db84542deb383\n\nKEY: 8d3c174a295a9d859e009f73e113403e\nIN: 16ed05c2b7b0c54df274bb67804c5d7671b915d899e15b2e166c3f1e4d9e990ab5be59c5e9fd70e1967a8021797ed8b2e40182f860dab2d0208dcc7c9fdb7bdcaabbc81f5b9b8751c558c5418dd654b2\nHASH: 0c4d09f8827c0c37\n\nKEY: 55bc19da3d5e60a3308379d5900165d9\nIN: d18ece72cd2f5fafe52fd55def2e6af0370e420d7aff7968f9cb5efc44ebb161a6bdd22132aad0aa9685e9168ebb9578209e51865625a4cc86c8f7898ad629b64e400a7d4687a5c3c000ad724a281440f2\nHASH: 7c47369a6d8387ff\n\nKEY: 58a3165308ef3c5e2a7c05070085455e\nIN: d9382554d5b633afa16065e6dbc0d472ee26629e6217a293b63af73cbd4a5dc3cf61ef7ebd5b6900a34bf4ade833c0dab9afe9d2d97369bf2814d03349d6e917adb5e0e1388772fad1a4baf64d7836fe3ffc\nHASH: 2ba3e3082bdd312b\n\nKEY: b636290e491b0ac22476c91c958ab313\nIN: 3d27f5c20db62e3abe1068c018fe8e09e4823b8c1209b74a50dbc19302e190350dba1c5ad616007c72be04bc21d7ef0a82804f266ba95fb3047a6a05de3f0d7ca3cc7c4633a02dda4f367051685535d8e1a155\nHASH: d14da7a2dc3b015c\n\nKEY: 667094c06354337178e646e23e453403\nIN: 215f856c43336295b5e4d625d8cf5b37c4a5b07a39eff2b42427d5df683982ae78ec85ba085740a28446c7928bce24be1b66a087898634a3f6260a3926c9a8f953e235e469c4de23fd32dde181168525b716a2cb\nHASH: 2f7cb69c5e4f942d\n\nKEY: 52eebf5170c603985982122bd8eeb1d6\nIN: da1ac8ccb4c66979633092524e42ca05df667ecc3921849a24c8fbf6aee70a01504ee2a80a000ffbc7b7629843f15270982a59ff9f3f081963a109ae8eee0a1d59baac5207f44071e51c64535b6920bc07bbc9048b\nHASH: d3a5fe4ac656bef1\n\nKEY: 1c1515cae3eba8cc9ed94c10f8a1c211\nIN: 4348d387039f7fe59a1d94a9e6d894241d62eb3ee91c19ebb09064792abb126710a619073fd293b59fecae7d90655d651e542be56a01ae5d419f14b1cee06cd90ee68e0106cd48130dd6e0d73db8fedbad3b00ada87e\nHASH: 57a4daa6abfb5a2d\n\nKEY: 8a8680122ba96ad89992741a8802f79e\nIN: 6ae10dfa31e5d06aeed3bf640591b9810245ccc175a8ff9f36893ad6e10c6dd9347d001f37c41123e4ea16b86b08aa3498c75bf5b8702228fb654595fb930cea2bb9ec97ffe1fba10fdbb7e8b16a2495df30abdfe1fc4f\nHASH: fc353ccf54b8c294\n\nKEY: 40d3e4941056b2585e1ed3bbd3196b24\nIN: e1764c110b024e2c406a18d6a6cb1b2d8dc05f8cbf635d9c6b59f8c54f7cfa1c9022f719d28979dfd75f6a221687690a046404fb1204cb27ab6502f6f24ac6d9c272852acfccb2d51948ddb427950c95ae4045699ec002c1\nHASH: 47108a5f3f664b98\n\nKEY: aa377b72cf2c282946fb87e6f3f16fbe\nIN: 4bf7833eb1e828df6fc190ecb568e3e175307408c4f851532afe731986d05c2e0a6d21c40b0228af69a0cf4f30293ba119462f3f95200386c70a4c49ad7251bc797be0b504efd50c98c3099b1119772deb764ba799bed28d35\nHASH: 6afdff80d074b585\n\nKEY: 304b7a8d2825ab0b4c78a82b202b1942\nIN: 43094418f2f65b85acacf5b3190711332fd3fa7c1e471a49a7d5134ab7f22def6fa973cb135a0add46fa482e7e29976abff74c3bc33af797b46540c85eecca45b848b55d3e412970c8937fb97d2b61af68ff3f2876bf8cb72dc3\nHASH: 8f89c9b9a3b9bf62\n\nKEY: 1b54ae53fbea3567a9678350ae934303\nIN: 8d02b02800d9605227fa73cc920962339645c72b560ba8c266b0b9e94eb8be0c9748718ba9cc48f1afd12e8b458d745596b763c7e65cb8a0fcc3d937c56e04a6873ceeefd3a77f3c545eb957a9a7bfbefabd47dca867ea92203c9a\nHASH: 86f09b1edb5f7934\n\nKEY: ada9526398c0ffe64b200ec1823a0d16\nIN: f6fcdf72c13acae3886dbf6a842806fc9ad021d0329e595748a8cf82f375fd357e1cc37a7d995d869373cad1dd8ecb8dbf0e5333767470378fd7e5b0d1fefedc18fcf045cfac7d883e67a8a32efbccc1a87a8e089f34186f7ea4ac41\nHASH: 64e098ae04f9e06b\n\nKEY: 30f08a4322a8c71e1e1a6353b371fd4d\nIN: 80df14c6bb51846621cd95b57c02e34afe6a96eeba8bc29002b2514f26c3ce53dc81330ebdfe8bce32d4e789f5bc354b03b4d10a64a10248dd1626726ff607529386f7becf9d716664bed65656629cef7fc7482e9046af09aa7ed60072\nHASH: 746b10b00aafaf2c\n\nKEY: 9bfa27a589f425dd70390c6ca1e1760b\nIN: 79fc7caea4cf78001a8d601de3438584517972e81d55c8e00b5c8ffd1e1aa5896058a56e636a4e66842d31f5287e01587601a9f79488db6f28f0a5644b34de163831cf462493ec579ee0c7631adda09f5e135cd70e6a4504e52823c1cbc5\nHASH: 1899998766305ccb\n\nKEY: fab33b56c2b97f9899438d8c4448a721\nIN: fb7e625072c6dedcf31d0fbdaaac81585465f6227d1a37d60befeb9662823d2bfb70f0dca67af4c1c60f72a524fef0c243a758f8b2883f17f2b113277fd71d28378c027cc9aa8c79d5dadcd65c2ff275f29a428437f424ab2171c33f819df4\nHASH: 208be5482e6ebba2\n\nKEY: 6ede0e899a0dacffa8c8ae3cf7552310\nIN: 9865e6577b8811c937447194caf30ca9db318f3949a0a095a148fa0fe0fe7a0ef4efd7c04c7f0ac13206841ab8b30b6b1a55b1555da37a40d5abf1543d59f1331309c1ce5f2adb39259c152628dfbe10c0c5e81ab172c025f9b84abc2d996834\nHASH: e46838d2cbfe6c33\n\nKEY: 2f0b8714a8f0454f62db8dc4fa506a6b\nIN: 6c45eb8e88bf9e63db9d1558e381f4a6f831727d866daaff9d402ba1c3ec6911aa4c62dff1bfac2fb00a50be2c2d945b4c1cd10d1ab0d96d201a5e38d80a5ac2cbee6b2945091e91aa40ccff6f37656392758bbb7da5ce2ef3c933b1bf83f82201\nHASH: 433657c53e5fa081\n\nKEY: 85cf9b7e4bd9af87f8fff9d854fb894a\nIN: 0e808570f9bfa7fde488e3fedfd61905b232a2e6c512ff4659b6b03722d4d1a8ab0b757de0eb114c52620054364d51d6087417f2ecc73bfc78caa8dc5c3063722b8c7387f5cf1eea7369baf108092b1736f34f3c85a1a64caaf188753cc348ac09", "34\nHASH: 25272780593c358a\n\nKEY: 903764f0b9bcab23a0d1e7b0d8248711\nIN: e63b264edf7a3ab19e8f38ae22fb9e00ed7c80d25e3a9d76def3c3cc7975ed5a19aeb552a559da1cc6d6f4d7ad5ade44bd7bb57ad1910a469fc7082267ce9644e9d4e24f1ce5afe6cb3886172485df77b3e47dce36e549c62129788648c3738f836caf\nHASH: e995824b960f3012\n\nKEY: 902dea339b29a5a4c54c71ac3486b509\nIN: e33910d372dedb9a154cd8b1ffd4d98c58c4b8c93b5d7ff59a87a40730547ffb145a820aea56bca4f7c043c40aa2f5e0099b9a91683d2d2927febca53c727ecfd8dca77830012c0d33135a2d1a5665c013c4126acec9073cee84f429c2a1d57abff643aa\nHASH: 7a6d533f1d13f598\n\nKEY: d760372d5a2224bdd096ca9c317b315d\nIN: 868257422e5898c7de261682a088bf97a19bddba87650eaef967e4085d5145787dd8a2236859c67b1d96e64a81934210b63ee44adeb5cedae03cf3598496f7b77caa7f2a2f123778e3720229ee7eeef87837a0d5de7ced3baf40114d663bc0e576ce6cec70\nHASH: 05eeed619f335b0b\n\nKEY: d443db5067af5681f8b61a489400d3b3\nIN: 2f69ba36de9d7f2489ad092263f06e04b87179dbbdc3725a8478abf6930f19ebfd1a23823d41f851618f6d533ca56273e602918c27926cd77e7380de5af322bfa2704ec669ef402971bf606da799b85c8d51ea8e2f8b8df3e9e4ecd9cb03f9c1bc387fb69a02\nHASH: 3b54dfef0537f65a\n\nKEY: ff85c309dd953710c4c450015a92db7d\nIN: 3b4cc08fb998a83c0bcfda112957646e708a5e7f457c33a4e31fcfeba9fb5bc37be521bf351eb5ac1bf11144c3fd4837cf9d9728b02b75c51fef0342140e3a0d199fe0a67710a3a7131c6d3c33e0ca00259cab1b7cd1d6de7ef81e97dee7ecaba9e2073c08096f\nHASH: 0880d53fcd40525d\n\nKEY: 50703fdb1e055a0f72353a13de243741\nIN: e94047f4276abc898fa1e268b53ba5effecad744a315d93f1218a47725ac6512bbf0e418681cb15e6a98c3a82bb3fff9f64583ba39268a70a45d91f432baabf3f38335b1e9f52a4141bfaa1c55570ab0ecdfccd5d7cee5bbf692277849891625deb64a8850a477bc\nHASH: 758c1f2f92b68e49\n\nKEY: 2b022fdf4bb13146ba014e1f2abd73d3\nIN: af723b77807c45b4aaea43e9d79a9149fcd1fdc59849b1bffa88abf27c6a779fd8172f325909ae43e49c2a44d3991350a377d58643e5f6ca9d8743c7842d58cb8706814d783e2c7855b8d63e55164cbc1fd7a13bb963d6c5bf4be737a0159c1347a72b88c0c5115a4f\nHASH: 2275a762396e6942\n\nKEY: d6c230457b3494e373c113c4fbfc8fef\nIN: 7820e1b5f75780ae7e6360c6708ec8bb5f82f948e656deb214a29d7887162c67aa1dc547b9b1b878f870cb44b22c61f804c6a9bfefd38588253360532a558c4176c98b63872df3741a718d8487e9bf17d5da3ca9145cb76a9ace837fc9b1f3065b8a777e10fa95dcfbb3\nHASH: 53b8f6e69f5a89d7\n\nKEY: 17f7716d7d49fbabdf1583287dda7802\nIN: 96ab47e1979e30b418b98f8b0f86ee5f5a773b3ab1d062274a4335f2f8cec6a0586aeaae7dc4d0da82e52c3b4b670b0ccd724b0100af58ddc74899995bf000fc626490b19b8bbf4f6352879a0530e97f9bd2418104a1a27e7252df3a6b996b27f54503ef8a718a8123d580\nHASH: 8aedf4fc510a8fe7\n\nKEY: b12168e2e46319863bc595aa421cb4ba\nIN: 0ce0a170319192d56484fc847a8285abe28b3ba3f8aef58702df5bf50e4d0ad2320946d8256dbf2338c8c0a6a1da48496adf9941a4d38d74e0c8aa52dbb5c757e28fe3756421964a3e4eeb9fdecf2529d70216b00515d5869087b611ed0ca1607a650ed6a3707ec6bdfa4d5b\nHASH: 4d85e666f836edcd\n\nKEY: b05bd753656eae367d8f37b4907e4fa7\nIN: fa2a52f77554506d25e8847bfe613139565cedbce07110a7a5af53d024204af9e0bb08c8266616dfc1e21bd5c651de626e1303b08c0c90ab709613caf2713848ff1ba3310852a575d07e12c7691cb081157147a413e80d53a55248240eb5dc566b8dd67d616c5d4dd8199d5d69\nHASH: 885116def6316c20\n\nKEY: 0bb368a25169217504ce1bbce5820394\nIN: 34b4df9ec90072e91548fb40a35128349986b7e50e425d894664a270f919456abc031284b29b6bebd734e53d5241919a8dccb05c38c633fcbad53979d92eb7cfe111584155a4c352f06c29242178ed4d904ed739a04d4ebedd27b7043d79afa9b740df4ad58c5640da67eb121997\nHASH: fd965ec9c1ef4449\n\nKEY: fdaec5633f8d54859574792bcda87468\nIN: ed96b9cd567f55d1d9e087bd63abccd07baaacca8a6d375d2576f00b1e09b5d920200a74cb12e8721e550c80b8c61ac7a8e733e1a14ad0311c30afc83f5aa7a8cd9fca47aafa84babbef5f93a86eacb5d50f696b7a60f0ac48f9b57dcab2168ce26f6390ce3c091a947397db050ce5\nHASH: e92615340f232b12\n\nKEY: d529ce056cb054580b538c81752d63b5\nIN: 75677757aa8eec8e44411d238aac77fbf1158c1c9c3174b78eab4a70034c325e52cd1a275fc0a24c432f82a10b5920a922981dac43571500263c0bbfb95d08bf20acb526bc6a180e6519499cd571414f7bf69d704b476d62083d53049674c46fb616b028bd269e1b822daae40ae4ec31\nHASH: 9d6ee722d9af0ac1\n\nKEY: 28b413218335bcc2f9031dc3554b0585\nIN: e4ac05d0860d28f45b7dde35028dfa67c25c8364545bf27a016228c4f1b5cbdacc418806d229d1fd2d30570fdb1304e38c7443c02d2e55ddd20718dd09d0b3a667df71c2040f079c9798a7f5ca7b09186df6c44edf4740433ec17873180038f7c5e0d4220d3755e264b0543ad5a5c1d537\nHASH: 7d6d8be4026abd19\n\nKEY: ab31c8820d2d02f63dc3ac5acac3828b\nIN: dae9931233787d476b472cb8e7ca4f86c2f8b9cdc38f49a50857f99e4e64b89d451e1bc8e5afacae36579d51b8bf67a4be36a65f9b464a150c1fc012c115bec08e45bea214b80ad39e1a705cb9b0b759901133d6619812ded8abf7848a67758f483aacd11297315dc190746a44e9ed56708b\nHASH: c9cd54ada0139758\n\nKEY: 145d3281341d26c75cbffbaab06d783a\nIN: 9859eb836c49cb41beb29eb493988b459f5d0b22a4dac9e64c34f93a71a700612cd568f76b84cf71966edfebaf6b27ef52524208e4905b83f8d52e879618180101c1ea0e326a44bb4d59539f779a0157af835c5bd7009882f16bb2aa2c87d49b6db49e996390a3ace578794c4d0f1802dc0a82\nHASH: 219b0dfe6c21ff2a\n\nKEY: db21409aca53c06e34752eaf651ae7ec\nIN: 962ec5dbe61976d91eca580b50d3b21c478bb8139da94be0a90e68f89b26b8b28d3484cb938791cf729a269c54af470e528a72ac9122ea10c08e836f8f32f1c1bbcf10716ef243d2abbe31bbf52dfd6c6884b81d6c48f18f087842b055432e5f67de978a2e7bdcd645dec43feb33f2be7fc8bb5d\nHASH: b31faaa12c80d2b3\n\nKEY: 0a92a6dce6418f53cd3823b9a40c5183\nIN: d1f4d53bd0409a3127ef19482d47964197bc061bc779b32ca5ca6f546c18180dfabd32b5a8519f868ac3ab67cd72c3bfea3ad96f5e40fc09a64046ff818928ef87ed043d0a0994c1adb8b0bdf446188b98b20dc65ada689654c5fcf8fe26d66baba8c02d8b39ee2be9217c09a62a4fce8236eda6f7\nHASH: 3e9be4b24cd3f47f\n\nKEY: 868dfe7c81ff02bded7c42a242d4c1bd\nIN: dea44a7466a4910b89fe6abcd824e65603a17ac436890fecbf4f6bc6809be8b13c0a6d593840d48ac59de059787dab1c1ca09a6834114cbf7ff2686a71ec12921aff5e13e9cd80c77ba7adbd361e72429c2b46eccbe27b25068cf457f865bd0149da14383317bcf8fbf949e36eabc7f8dde08c5483a4\nHASH: a0b3afbcb9412ad0\n\nKEY: bc662a2870b8baf74a1153e5d24b4832\nIN: 503401e821133e2ec69942d28503993e0337ac43502466f788fde4821e5bb2be6b0aa80a6886eb10dceec3225762a1357992b740d5ada6f6acb26761c57532599c66c9b55812ced61bc0293781f600fa1b2d211a7556702f41203b7824654207894feb9e2f744e03f5d79682ba4570756050e42eecb3e0\nHASH: 285affa883d1597e\n\nKEY: a51217e323aaa13dc0debaa2d26a7141\nIN: 52c40d6b8dfd5fc99158481dd889643452c533643534298382d2f3d159a7c0f019cb614d8773299451ff87520d9680e5f283e9e9a2fe9a8a7b5e4bda6b94e578b97948eb9bd868ac3c33ba79df325c141eb83ad6be7c1b5c9001d59f88a4bb2208ac62dace5922b6df16f09092b48d432bcdd79b4eb484cc\nHASH: 5aae64a7fcaf3072\n\nKEY: 89c8b8541be48278ee4cafed6616a581\nIN: 86a7c752d913e379429724ff0358994fb8ccc6605573437ed5742fd1b2934c6943259c2eefc5000f5292901a154e856df3c8b7fdf370bc72ffae5957f104fb3b07ed448def575680bc637e3804ce9cca9ce1d85fb79b33e8e4c45f1f974d0613d40c63734b9c927fd0e6e16bb4d288204bb759b199269fa7cf\nHASH: 339b0843b05f2652\n\nKEY: e8b664ce32d35f060e5a015caa287b7f\nIN: c9d496f2e1c2141154bfeb0c4a4347fa7fa002ab2573c634b2c2a376fd270c7d45d2fd6078e4d997aed34bd4dbfb308e2c1a14d07f58e1363c3fc4bf32adf4af4a6d1bcb79e4c5c3db2ed2c68fd2229b6b5fc831d7a2cce989d2ef8dce13f9e076aeabb5a30c7ae72f4e98874f885cdb52518e71a020e0bfb7c9\nHASH: 254a78254aa531f7\n\nKEY: 1ce06b6d7f0c15734448e53a4fa52fb3\nIN: fda649ace37b9fe4f4d572d8b1b74e28ba13db46f6b0f42ba9ac940d379d6d50623fc1ef7545763651818347ce38a3d86828148b14ef090dea626c5c3d1379341704f719ffbb234e423b0024ee635ccd2ee50c501d8689f84c929d689745a05bba54f99a23fb248366ab05e31bfbc18be87110d419ac43834476f2\nHASH: e5d2f7f9315945d9\n\nKEY: 84c2f71ddfa145332dabe73460c7e03d\nIN: a8a162a8b39975a998568ede08dac2c98a7da7021711e159356c13cd39f5080fbfe7f9f2ffd75174ed6bcd82fe0cb158a83d10bd64639f0c6a10335635c4aab34bc0986b898b9b4dbc013fa456a34374aee1a0d437f1de697f5fd2b87c9ad39017434d66761c0f26e81e9c99a9dd57f390f2488ebbfe7d1666cfda65\nHASH: 7c416c3bb889ff8b\n\nKEY: 63ab163cdeda549ba268896b9a677d89\nIN: 64be9cb0aadb6544d4401ba45a3d2b7d766d7d67e09bb2f141e743fa72b8dd14d7427fa2ec37ca6dc5c32861962c7744b1afeea8f28f878420cf67268281ab9ad6dcf0aacdbb52a6983cb91ebfafd294aefce90c6f3628376d7afaf4fd5818602328e215cf1aa3c9510ce53f42dc04288accde985e90224260e318d589\nHASH: 21cb18940175042b\n\nKEY: 2f8057e7a18f356d187ac98e43127515\nIN: f5c76f7b6d6cf30342c1f4673ac063091c9c02862238549255bfc2530f743c69cf4943a9d4035fa1912826673b3c9892a489e0afc011abc45bb5a251f2c80ec97962f366376841939e9997637ee1a2dc0655e9e8a1d262b046cc4c0eccb981ffb46d494d5537cdb202b840601380212f67e728cf9c3867cbc53c0a825f61\nHASH: 843747a", @@ -2761,243 +3189,453 @@ static const char *kData60[] = { "739b90eb2\n\nKEY: a96ec37c773d908b5cc732eabb877b24\nIN: 6baf8f4a20f45bf086c0003c0c6e3837cbdbee6f861d27417547d06e21feb53703fa0f896dde73cb97671e4af7b27fb175d802bf3d941e13172ef158aa6f19e27a504e46c1f1b1dac741bc3ce66b73f46941821561be24448e37a64af54c9beb16da91ee8705d13b2882b9c80fdbe249e1d3b6e5c671ee524d76f543dac473bf83cddcd95c07e82d70ed4f0d86615e6d3776e6db7f740ff7db55a949193734b2b9caa48dfafd8bb40bd8cf2eac7bb6462e92f2a0fc101c7b1fef491f6a16c1c555df9a57a1f7a8e70eeceee14bc6e81882a8fecc48ff9b171b9e8915882f281925282a479b8239bfb48d8cdcc56c22294210a484702c5a8e4d4fdee2f6223e\nHASH: d10db578e9b44fc3\n\nKEY: d5f074017db58f6e68d210b58e091d7b\nIN: 319a1100ad4e268dcc7f3ce71fac847336fbedb9046c1b1b433c373385326fcde6824b3b1ff34f86a0a27b9216afe3145945eb5f7aa37875fac08cc62abf01e2591f8d8109f102214457193412c58a393c4819812ec9fc2079df042a3f57d172d76a8f2709b942e79b3ef839f2f51dab93d225e6eaef30b2a67324481d60a9c5a215ada44eca05470337379dd01eb0dea2cd14bcfd0991d0bb11a6b0fce97b4e51492fa665ee7e29cbba50a5ce0d50c663b16ec8260edce17d548c6d8566cc76ea7270e406f9c888849d15197b37d30c64eac4eb90f3101ef65b3c1493370f8758e7d954b41a543e520394f2da5229efd6f06ca947bfff71b11425a67229120f\nHASH: 1b460b968867e42d\n\nKEY: 338962444ff46d8d1c4ef2d14849202c\nIN: bdfc2290fb71a50aa63595c3f11ffc426539678601b31bae30b1771435e3199668980adb627c738ea28ba458c0179e48a802d81afe0b2d09b5c3efb06808a22d73173049781c0822d780e360e442619dd82cfca21291eb0b793eaef44202b7a5e6c30505ce4e026bbf724ce76a05e827c526ea99bef552460abff8058142e11e1c223aa0cc31bfa2e5f9184d9a0fb9533facadfa08b5da0a7b65ea1758675bbeb1ce2faa11ce20ade70ad5fcf88fd253c75e5a2d0ec79f3468e5056309b4d46e1e96ec811a14cf6e64fdb91a044979a86b571a9d701b6663d8f24ad77c4a514576fa942f45970993dc703dbc68a06eb688b9f7e87fbae04019d54320a26a5b7b84\nHASH: 2529cebc7a6002d2\n\nKEY: 94f80db0bb92d9f844c8fcc43ce0d94b\nIN: 3d09d5fadd1e79e648ed155dde5646d2b9b90c9103d4d7b4d53d5ff184033fb17db63516b70d4407aaf3be325d66d7196d08e310851c7a9f6ecb6d3a73b7ebc9bd604db7bf93879e17c2e1d7654247295ea02b97a60a3b85261119d021ed1f040f27e456f011cb46dad312b65c1927765cad2c56227d6aed2a5d7754a57de58c11f185aee88e38ae5c8fdbfe6242eb3dfc7981592556cdaf21351648abc64667998c4003cfb8376417ff98b506c0fa51dd2a152d00f34f6ab58c883362b08c986041724d360f68b94d8d071e327ff536023c98313f09df4ecdf11e16ecfaf3970ad682086ffc7e43d571a96b7103e9eb80acdb6fb8f78107a8042b2c8893b1d2f19f\nHASH: c4746b2d19941e56\n\nKEY: 995882b99f51c4a67f5b55f90e2a9aa2\nIN: f640e51da483aadfa88812d5851ea3a0d9e605b144013ffb7f74df26cae9317fd90233e2893575d5e470df2d80a2e9f4e8f6f5e5f885498bdad37d1489ab823dab96832d48c7617b255d40716d54dc45e9bb3d88f908d573172486d88c698496faf792696ac1f446419f6459866cd4ccfac5359ad9fc8a7bf85f755d08fa5e44f4b0def68513a39ddb97698180592baa03e37220eb955c636baef003040d753d5b2c307edd1b7a24ba1df13b9bcdd72cfbea7b17aeea59c604e509f511855e3784328479de46457d1ce706cd2f9e937d71192ff215733c62a205a6f08b901e2521e1935ee33d524c3d10c73c0a593acced88f73bf6624b15de138076569945cf2b6b11\nHASH: b24f340cc0fb1d2d\n\nKEY: 8da14614383bf855cdc281b5225515ce\nIN: e17c973f19eb796bfbc57ddb9601806998a5e97f18a3eca6a1d20c3cdcd109815cd8ee13981858324ab89e8b30214e3251e6f308648552034545f7d24ca74aa6de5bc1513c20d869a310ad1a44e462666d2817c0cc225a28efa78b1435c80adca1e07683e1792152267649aeb7ee19efade02dbc631b1fc58ac59671ea5982234da90dad42430fbd85fe6527991ccea11bb805815fdd0c8a920dc9e818a5fcf8fbf680a06999c42c33c7cc712dac8badf82059d142c6c3f80a8d09c881182cf336cce2e0e088d0af39fcdf6dc29c1ef496968455e2fa149a65cc57df06fe6830895e2daf352e922bff8cc3fc757161f3c61b2ec9e7d787e1ad976595d27f0f5fc5a04da5\nHASH: 36bd2cce6ed21122\n\nKEY: 70e11b8cda2ab4a0abcb736625145d90\nIN: 7f4fa8fc41f72c8fdcce996949b74560ea9fc7a3c57e502628487144472bee4300671cc1617fa7c76850df408b92020e7f5d377f4c8f410288ff60aca90516d0f1d13969c9e5af7e348ea7f8f9a36b8c69d0645432103f5b93ab560f3113e2d86b35fd6e704116ae5e7bfdf1c29b6d5a4570e2b1082a3e6023f14e666a76af86e4661e140eb836f262dbd5d388c166215ac4f39dd9fccbe3a3a8c58a2236304e8fc0fa1fc535e860e888a0d640277426e2e2a05d855c5ffd0876ee0306cc0c394d064fc45e974d1c19094a1e83d59057bf269f581637f343a9fac376ed41f4d193aa5e3c30141d31391c02390afd81bd32b6865ddd8974a44724217eaadd7ef316e0b4c2a5\nHASH: f6624d4d13833699\n\nKEY: e974c2247093c75ef6ed70632f16924e\nIN: 71f2e0508d7d36b373e8ee0fabf49dfd69638c5a6c79be9c89bbd0043b3bc66abb3618c67299c0afc4e24af8440185ce8d7d8b1d45732f123aa8243a9a0a0bb27b3d6bf59b39e389c15211b92c93bc5aa8582c98fb1523427c84969a65e99775e9d97f382b9ab47ccfdaddac3e7201f917bb64843f2b804801a018c71bb6f632f4521c1a4e9a375d7bbc8a42e561843dd65ae3e7ec0da1db8751960a656876983986bb2be2dadca5bb312cb004eb10f1c608af4afa599d946bdf8bd52102c257871810f5c8a899580287074686738a5823f33e96d3c2a7c77b68e4a21a5ac50e06664944d0cd6bd40ae95a2e21236e671bdaef79f08da52e2a6f65131a2e80c6263ddbeb9759\nHASH: 00ab496891593584\n\nKEY: c6f1ee0aada0c076cb20cad883bbcf52\nIN: 912f5b270fe4f445134d1caad3cd04cebc9c377fd03d3e26b82d4449d4ce1914ea718a6fa8c179dcdce1d117e99f4e8cad2cc0f0c059fd94cd8b3149a38a6b271c7fe1c90943c7a8d40774817c272a9139a05e1c0aa74cfb5a7c3c93aed9303b9579200022527a0911908875e23b1d8bacd42a123fac2342723a77942523b4aa858ff284821e1ecdb82ab2858580227bdb2e297ba3680a1f1cb0d31cb8e6f6c45235dc64f4c3f986c24f9ae3a6cb9d3710d58125f20d8e8c4cf4f89adc091649bd7a33ecb58cd163baed98e7e4f4dc16955f7f09bee1a51e0f76e9575cbc2733bf58bb4be4a4e2a2b1285c1b928aae6d8d9becdbc3723b408fc01acccb95861d23a3940df799bd\nHASH: 792ff12185fc3326\n\nKEY: 5cad21c8c3805f62248b1e1758c9c392\nIN: ec943f6a3d3681cd718f532bea0e5e2839c9425d0381dc5808cbfb273f6730efd52496b0331a711fce232991dd0847b5b6fd58330f54c19f571346d1e100e2304ebf5fff1b1047ddbbbc4dae02ffa3a21f8655b8972f683a33676352908e007ae3d12ce62e77acb2ca8278161d7c6964d6b97332c19c1d1d7288542eec4743731144a0e8a0abd58d0df0664eeacd5e97e272d672e110734c84c075b9ca5ecc279010f22236063a8ed1a7ef31bd84637832ce375944eb672b51edd7b4b248dca106295d83f14f160b63f84a49cb6a0ab143494ccdf5444c464ede3ee7936f821857cb2f3cd7d29da414c10ab7db05e4d0817c1556804b1d3d9c771adafae48541f930464549cd2635\nHASH: e428c0fa3cf4f1cf\n\nKEY: f6f49ac81cbafda6579b81c9d34de602\nIN: b5e3e21c2b2104c50bdd9a96667d460c3a4c0a5975df60369ebfc0f6ace585d727292f1d37107ef0bdd7ef16fe8740e0453501405c2a863289773a4d121b37f01e1672b0339f57fb445f132262f6337f64e9df4ed7fa79ed1c722171cf350f1c1d78e7427904ff3b90bffa1eea64181c4e69440af712e37b7dea95953ebd4ef5efa7bb3b14f3f452e204f9a26fcfa104b80deb56e16e16af88fc710f68df3da7f162e3de3aa9f31a2485169411d6009014578cace09aacebda2e965cd8c4841df7e31704584aafc459e02afc978b812f8ba22e2887728243658b4adcc46a471aa357567505b17fa51fdbc4c5ddc67827cc86f66ce3a55257d00683ed2b67ea19ce1ba0eaaed8c4c1a7\nHASH: 1b44de49c45e9bc3\n\nKEY: 05f5a594c805575eca581fd6e8b16051\nIN: aefef8817ca1ec2ce86d04184ee9f5da020497d3296395cecec10af22696deb65dcf3cfa4a3b808eb1826ff421de79aeebfca796306eb3b39165ad11d8733cee89f30229f75c06dea935045439d5a69ac118c5ca26bf59a9cade2e6b80b0fcff911eaf7f4097f87751570362dc5aa42a379c5ad313fb403b15c9c6c517be4ec28a22039bafd618284b16e12bc38c39e8525b930f5a630d4d595980becae425229bee4c63706fc172f5f9ba6cd5fd36ab474112169c2ef52b2bd72b2ef3bceb8a82ca53a42abcb044b712cc1a6b37a8ca8894b9904076452ddaae641f9137a72987fe928c20b67c2ccaf9fd601fa10c5e4c968727357c4547fc68b0e11b35f4fcbdcc3784c2722eeebefb\nHASH: cd45d7070e5ecb55\n\nKEY: 0546eaf96bc197e372139dac59c9ca1f\nIN: 1e0622e2d160fe532cc789b76e99a5fc7e90078dfa0d3d9342ca8c625192afeacf6935e930bca3e7bb2d7a4db23371b6ee3e645b9c6939bc3d414ddbff363d4ecb2967962bbb1d3b86a476bedd5820d17b86747c886efb34692b87db843588d0db53c3d91f2c305e5d58cb7ab98d6387ac45400d2ad1f2435bdb0c4a76c6fd491c3f2bc049fe70426767cadb0fa897e29cfda1bcf4f18d0b15795de39ca05fd2318dcc8b9afb7a278e986521ad971a236745bb62a680b47707a7dd1ffeb98e8e61edaa038e7c2a568c4a0060c38752eae915e4f99c91d6de11574b3dee5f85209acb8a38a02d0f59f5192a3151ba8073682d191ddd26b01913e98b403a4ce771e5e020ffed080d2dcb7082\nHASH: 079a62a92c61d7ad\n\nKEY: bb1780c25e2afb8c9bc58a3dbec8867a\nIN: ed5287df6db34449db95528d55e64ff486f178d68135dcc996593592a40655c88dfbef41fecbbc09066adca3b3ceca2c9f7be48ba61587ac3c69bb5589fb257bb96c000ab5e5843e9e7257095ae087d084aa7e62e9e3f74079d1c4c10443c9d9bcbcae47c74e72c024e5cd13280f058a772afc379d2dee0e39ec0cfc219cbb2af7698162a3b84be52c90617760e84d3743909bdd5cf21bd3ea3e3e37c3734dda57a06db25ab81ff02823f6d39cf9e068698e1f597458d08a29aefef218b40e191dc3d05f089f133f5f337d98d1c0161f490849782248e915ebcf700d80667b2d0ba3fda022faeeb23ca87add7664666f46", "37571964d613bf76a22061c9f746f9fb00ff0f5c2d90f648717e1f\nHASH: fcda80db378102b4\n\nKEY: ea7247b6addced42c51c827dbb2cb66c\nIN: 0ec554948d3af7cbc2306d249861f6291d44ab2be6bb26ab629347ac0e892cc902b3c5bf9688e39d826e32609834b34644a8b39c9a91f47a0f24e73a13edeec9e224756f6cff77e1d07fac03c1d803649279e33b2f16dd2d100bd82e9806afadb022700d55f5fc9688193da02dcc9dce974b60ccc2caad064acaa0f1b9e4f24e9074ac7877b91b19c7abbe5bb7f889775cd72ab9334475dddba19d008fdb01ab9cbfb1038a486c76f3c542bac704cf795be628cb83a5d9d128c2b401cf23ce494584cfe5b4ed58d9c906ded22090ffed4894238c6d02835e6180ce662b24ea18fd84d5fcbed49790322260fcf3f193081ccdb60d8f768b6dbfa61867bf90fbb1f27e1a6cb83daad6243079904a\nHASH: f8181640a08f1343\n", }; -static const size_t kLen61 = 489; - -static const char *kData61[] = { - "-----BEGIN CERTIFICATE-----\nMIIBOzCB4qADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejEzARMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZI\nzj0EAwIDSAAwRQIgTNs2aQPDZs+Pal5LA1fAKyC4AKTNN+JE/vEYndKhFxYCIQDf\nb7IjDoXx/3GBnsrht14NUmzUBdqkQafJvC+eHIdtQA==\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen62 = 493; - -static const char *kData62[] = { - "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYI\nKoZIzj0EAwIDSAAwRQIgHdMalNLi3hzz58PdNQPAqiA5KAa/dfQWuNNjzE6iDIcC\nIQCda6js7OKQvdqCFb/POHPriXX1YXIJ3N95+SE7qFJ9Gg==\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen63 = 493; - -static const char *kData63[] = { - "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSAAwRQIgZx7fIDI65CU7Lck0t7ep/GtBkpELR0gKkUJrI09/JJoC\nIQDFPukkJgYA7RpFsAsEq77S+i9gf/S/IreobhvQm/401w==\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen64 = 493; - -static const char *kData64[] = { - "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQowCgYI\nKoZIzj0EAwIDSAAwRQIhALj37ijrYfommrWjrXMXjJyILvGNH7KxViKU1cWjX5dF\nAiA6WjePmZdKilZebpZ++MTPs5cbpdcShWYuJ45sANCKgw==\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen65 = 485; - -static const char *kData65[] = { - "-----BEGIN CERTIFICATE-----\nMIIBOTCB36ADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejEDAOMAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0E\nAwIDSQAwRgIhAIc3Cbr1SRZZ8ZusjOQjA/9Ro5ijEZbMaD1ClW62/GqSAiEAy1tU\nNo3zRwTUcuyAnav+XbXkS1a5Fm2/rFBoWN8ZAxA=\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen66 = 465; - -static const char *kData66[] = { - "-----BEGIN CERTIFICATE-----\nMIIBKjCB0aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejAjAAMAoGCCqGSM49BAMCA0gAMEUCIQCQ1/Ca\nRanCM+PIUqVkCpfumEeLKawHMYIA2ZM3Yy2wngIgZg10Sd25/POZKIXlMAiwlDrM\nUQcfzZiBh8T5JEWKeRc=\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen67 = 623; - -static const char *kData67[] = { - "-----BEGIN CERTIFICATE-----\nMIIBnjCCAUOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjYDBeMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAKBggq\nhkjOPQQDAgNJADBGAiEA0XamFS9fNIkvjN4muFP3EYEuO3/y+WiNhewBtusrhD0C\nIQCmTHE7J6c+Pvtv4Ro2S/I3Pypr8sJNWdezoE5Okhf4Gw==\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen68 = 619; - -static const char *kData68[] = { - "-----BEGIN CERTIFICATE-----\nMIIBnTCCAUKgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjXzBdMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDgYDVR0jBAdJTlZBTElEMAoGCCqG\nSM49BAMCA0kAMEYCIQDKVSKO0wAESfYL/ZRzKj3rBxolJ9+GHKxNTXnmf7w6sAIh\nAM0mSwKy1M+w7th5s0XhfImVfpi+V4Xxbtz8AWN6Grfm\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen69 = 619; - -static const char *kData69[] = { - "-----BEGIN CERTIFICATE-----\nMIIBnDCCAUKgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjXzBdMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAVBgNVHQ4EDgQMaW50\nZXJtZWRpYXRlMA8GA1UdIwQIMAaABHJvb3QwDgYDVR0TBAdJTlZBTElEMAoGCCqG\nSM49BAMCA0gAMEUCIARJW0WA3S/H8amVP7H8BLJj6AnNocXOC4FkQY1YNNdSAiEA\n/Y4tQ2nvQhDuBGxdkDfR5wyYLOuS+t/CWIiV3A63VsM=\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen70 = 615; - -static const char *kData70[] = { - "-----BEGIN CERTIFICATE-----\nMIIBmTCCAT6gAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjWzBZMA4G\nA1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTADAQH/MBUGA1UdDgQOBAxpbnRlcm1l\nZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNVHSUEB0lOVkFMSUQwCgYIKoZIzj0E\nAwIDSQAwRgIhALzNOt3jZR7ZP0DWt0hw3SRu5l8dcKYy49xVNIY3D8OuAiEA4KHg\nSfy+XLtLvVG9Tnbbh3XS+iLHiDUsYCGivpTAb44=\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen71 = 619; - -static const char *kData71[] = { - "-----BEGIN CERTIFICATE-----\nMIIBnTCCAUOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjYDBeMBMG\nA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wFQYDVR0OBA4EDGlu\ndGVybWVkaWF0ZTAPBgNVHSMECDAGgARyb290MA4GA1UdDwQHSU5WQUxJRDAKBggq\nhkjOPQQDAgNIADBFAiEAtoKHHh57yauGrcGren78p+jqfq41XmuwaF6vQ7BfmxQC\nIHCPCJcys8DqJOXId0F6fyk/Dk7jixFnmwW8S5E8N+Ee\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen72 = 639; - -static const char *kData72[] = { - "-----BEGIN CERTIFICATE-----\nMIIBrDCCAVOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjcDBuMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNV\nHR4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgFTYJwndHsZh13cYj4EfDZFNe\nckt9rkRJjEP7nDGyD44CIAE6M7HDjbJRjJbYsAfc45ax00i9htFjb88t6AJyDU9M\n-----END CERTIFICATE-----\n", -}; -static const size_t kLen73 = 644; +static const size_t kLen73 = 489; static const char *kData73[] = { - "-----BEGIN CERTIFICATE-----\nMIIBrjCCAVOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjcDBuMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNV\nHREEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSQAwRgIhAI49whD5azejKejI1xowdbu7\nLHeT2wNanCCU+KCOoBFPAiEAoog5xR90Z2lWsLJEPWiw7WLJMNuZBDINLNVDCA5d\nD0k=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBOzCB4qADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejEzARMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZI\nzj0EAwIDSAAwRQIgTNs2aQPDZs+Pal5LA1fAKyC4AKTNN+JE/vEYndKhFxYCIQDf\nb7IjDoXx/3GBnsrht14NUmzUBdqkQafJvC+eHIdtQA==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen74 = 611; +static const size_t kLen74 = 493; static const char *kData74[] = { - "-----BEGIN CERTIFICATE-----\nMIIBljCCATygAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjWTBXMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MA8GA1UdIwQIMAaABHJvb3QwDgYDVR0OBAdJTlZBTElEMAoGCCqGSM49BAMC\nA0gAMEUCIDsbBMbAWuJq9VnfrSjLBTK6TSfskt3i0ns2y/9FEW04AiEAkjyacdGb\nsk1wvjrVc5ny6O96NvUGkdO1/GNdPNKPYWQ=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYI\nKoZIzj0EAwIDSAAwRQIgHdMalNLi3hzz58PdNQPAqiA5KAa/dfQWuNNjzE6iDIcC\nIQCda6js7OKQvdqCFb/POHPriXX1YXIJ3N95+SE7qFJ9Gg==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen75 = 688; +static const size_t kLen75 = 493; static const char *kData75[] = { - "-----BEGIN CERTIFICATE-----\nMIIBzzCCAXagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GaMIGXMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93\nd3cuZXhhbXBsZS5jb20wHgYDVR0eBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAK\nBggqhkjOPQQDAgNHADBEAiAJtROn4TOAvfttoQJ6RsqnsaR1WaP+CKzWXjARJxtQ\nLwIgGmbRenVTFx8ho17JY8ncV5qaJqc0EXN56twt9SccKqE=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSAAwRQIgZx7fIDI65CU7Lck0t7ep/GtBkpELR0gKkUJrI09/JJoC\nIQDFPukkJgYA7RpFsAsEq77S+i9gf/S/IreobhvQm/401w==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen76 = 680; +static const size_t kLen76 = 493; static const char *kData76[] = { - "-----BEGIN CERTIFICATE-----\nMIIByDCCAW2gAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GRMIGOMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAeBgNVHR4EFzAV\noBMwEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdIwQHSU5WQUxJRDAKBggqhkjOPQQD\nAgNJADBGAiEAj6hhgnfiI0zt38N98eQsfJCJ8ZGkLfH+69OOUISls2QCIQDtyWhN\nL/7L787+zkUazG4HvZ/YHO7hbWQAfMQVbk/iRA==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBPjCB5aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejFjAUMBIGA1UdEwEB/wQIMAYBAf8CAQowCgYI\nKoZIzj0EAwIDSAAwRQIhALj37ijrYfommrWjrXMXjJyILvGNH7KxViKU1cWjX5dF\nAiA6WjePmZdKilZebpZ++MTPs5cbpdcShWYuJ45sANCKgw==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen77 = 692; +static const size_t kLen77 = 485; static const char *kData77[] = { - "-----BEGIN CERTIFICATE-----\nMIIB0zCCAXigAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GcMIGZMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATANBgNVHQ4EBgQEbGVhZjAXBgNV\nHSMEEDAOgAxpbnRlcm1lZGlhdGUwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t\nMB4GA1UdHgQXMBWgEzARgg93d3cuZXhhbXBsZS5jb20wDgYDVR0TBAdJTlZBTElE\nMAoGCCqGSM49BAMCA0kAMEYCIQDo/XMevx8IdL+LOl55riE3otGDWKDDPgaZKA43\nsnAJAwIhAJtgm2YNclXG1i8PzrSqZ5Y5mvBMgtjTfW/7ld7ED3pK\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBOTCB36ADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejEDAOMAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0E\nAwIDSQAwRgIhAIc3Cbr1SRZZ8ZusjOQjA/9Ro5ijEZbMaD1ClW62/GqSAiEAy1tU\nNo3zRwTUcuyAnav+XbXkS1a5Fm2/rFBoWN8ZAxA=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen78 = 684; +static const size_t kLen78 = 465; static const char *kData78[] = { - "-----BEGIN CERTIFICATE-----\nMIIByzCCAXGgAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GVMIGSMA4GA1UdDwEB\n/wQEAwICBDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBARsZWFmMBcGA1UdIwQQMA6A\nDGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20wHgYDVR0e\nBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAOBgNVHSUEB0lOVkFMSUQwCgYIKoZI\nzj0EAwIDSAAwRQIhAJwe+EZy9v2fW6bYAE8T2NEJjc0SDLoHshJOae3yOYMoAiB1\nkTrY4iuQKBwbbAokFgnHr+Ev1aXcmjRn0sJFDesUAw==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBKjCB0aADAgECAgEBMAoGCCqGSM49BAMCMBwxGjAYBgNVBAMTEUJhc2ljIENv\nbnN0cmFpbnRzMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAcMRow\nGAYDVQQDExFCYXNpYyBDb25zdHJhaW50czBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABJEq2LxVbZGSZr4q32NCQw2K2UKzSXnDy7dJLCbsdlES+ZwEIkGNUhERpxGo\njS6aHNHZXk0vMEE/3I8P8D4KHlejAjAAMAoGCCqGSM49BAMCA0gAMEUCIQCQ1/Ca\nRanCM+PIUqVkCpfumEeLKawHMYIA2ZM3Yy2wngIgZg10Sd25/POZKIXlMAiwlDrM\nUQcfzZiBh8T5JEWKeRc=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen79 = 688; +static const size_t kLen79 = 623; static const char *kData79[] = { - "-----BEGIN CERTIFICATE-----\nMIIBzzCCAXagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GaMIGXMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBGxlYWYwFwYDVR0j\nBBAwDoAMaW50ZXJtZWRpYXRlMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAe\nBgNVHR4EFzAVoBMwEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdDwQHSU5WQUxJRDAK\nBggqhkjOPQQDAgNHADBEAiAoWszkhUlrT+vn0BqkA8yuuyCQ7HvK8KQOJsvzFYkS\nqwIgbzwpATgcK7hhRG+GIO8v/MWqomOLExlQYcGIPPODHH0=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBnjCCAUOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjYDBeMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAKBggq\nhkjOPQQDAgNJADBGAiEA0XamFS9fNIkvjN4muFP3EYEuO3/y+WiNhewBtusrhD0C\nIQCmTHE7J6c+Pvtv4Ro2S/I3Pypr8sJNWdezoE5Okhf4Gw==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen80 = 668; +static const size_t kLen80 = 619; static const char *kData80[] = { - "-----BEGIN CERTIFICATE-----\nMIIBvzCCAWagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GKMIGHMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93\nd3cuZXhhbXBsZS5jb20wDgYDVR0eBAdJTlZBTElEMAoGCCqGSM49BAMCA0cAMEQC\nIDBcHYVfj62g5y2gP/TTvH3VQr4XG/QNZLL6N8H/A8arAiB95102dlC8zVt4beDe\nejD7/YA0FNMSgEnAZ1VgzPejxA==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBnTCCAUKgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjXzBdMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDgYDVR0jBAdJTlZBTElEMAoGCCqG\nSM49BAMCA0kAMEYCIQDKVSKO0wAESfYL/ZRzKj3rBxolJ9+GHKxNTXnmf7w6sAIh\nAM0mSwKy1M+w7th5s0XhfImVfpi+V4Xxbtz8AWN6Grfm\n-----END CERTIFICATE-----\n", }; -static const size_t kLen81 = 676; +static const size_t kLen81 = 619; static const char *kData81[] = { - "-----BEGIN CERTIFICATE-----\nMIIBxTCCAWqgAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GOMIGLMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAeBgNVHR4EFzAVoBMw\nEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdEQQHSU5WQUxJRDAKBggqhkjOPQQDAgNJ\nADBGAiEAurYkjuxVgkxbmI1D+qM5RGXPPs7V74okqeQdURcL7HACIQDGNT6gcPDw\nAx2Hm5GK3H5UrNEmD1K4IOxfKl9zguiffQ==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBnDCCAUKgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjXzBdMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAVBgNVHQ4EDgQMaW50\nZXJtZWRpYXRlMA8GA1UdIwQIMAaABHJvb3QwDgYDVR0TBAdJTlZBTElEMAoGCCqG\nSM49BAMCA0gAMEUCIARJW0WA3S/H8amVP7H8BLJj6AnNocXOC4FkQY1YNNdSAiEA\n/Y4tQ2nvQhDuBGxdkDfR5wyYLOuS+t/CWIiV3A63VsM=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen82 = 692; +static const size_t kLen82 = 615; static const char *kData82[] = { - "-----BEGIN CERTIFICATE-----\nMIIB0jCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBcGA1Ud\nIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20w\nHgYDVR0eBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAOBgNVHQ4EB0lOVkFMSUQw\nCgYIKoZIzj0EAwIDSQAwRgIhAOgBejpWnjlxO/K8FMTGO7J+sHS6PAQohwvEgLmT\nKWhMAiEAuc5uRycxN44gGka2Of9zw09o50sKgS1Ckv+VhkDqgbg=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBmTCCAT6gAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjWzBZMA4G\nA1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTADAQH/MBUGA1UdDgQOBAxpbnRlcm1l\nZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNVHSUEB0lOVkFMSUQwCgYIKoZIzj0E\nAwIDSQAwRgIhALzNOt3jZR7ZP0DWt0hw3SRu5l8dcKYy49xVNIY3D8OuAiEA4KHg\nSfy+XLtLvVG9Tnbbh3XS+iLHiDUsYCGivpTAb44=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen83 = 574; +static const size_t kLen83 = 619; static const char *kData83[] = { - "-----BEGIN CERTIFICATE-----\nMIIBfDCCASKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0cwRTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAKBggqhkjOPQQDAgNIADBFAiBd9AxKvRMSY7ll42h5jjYh5QtK\nYu3fxeME1IeivVNzQAIhAPov0l/2FYwZmMGI9ihR3iD/8petRfp4E9JLQQd3TgL5\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBnTCCAUOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjYDBeMBMG\nA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wFQYDVR0OBA4EDGlu\ndGVybWVkaWF0ZTAPBgNVHSMECDAGgARyb290MA4GA1UdDwQHSU5WQUxJRDAKBggq\nhkjOPQQDAgNIADBFAiEAtoKHHh57yauGrcGren78p+jqfq41XmuwaF6vQ7BfmxQC\nIHCPCJcys8DqJOXId0F6fyk/Dk7jixFnmwW8S5E8N+Ee\n-----END CERTIFICATE-----\n", }; -static const size_t kLen84 = 599; +static const size_t kLen84 = 639; static const char *kData84[] = { - "-----BEGIN CERTIFICATE-----\nMIIBjDCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHSMEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIhAMVD\nOFcNzmPEdD2dJ3KWRGR15vQbXEXvimZgJdKtXdbLAiBfJOocLiQfPU7Nk3Qo0Ti1\nEn0QfUATxx8DNR15cfcupQ==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBrDCCAVOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjcDBuMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNV\nHR4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgFTYJwndHsZh13cYj4EfDZFNe\nckt9rkRJjEP7nDGyD44CIAE6M7HDjbJRjJbYsAfc45ax00i9htFjb88t6AJyDU9M\n-----END CERTIFICATE-----\n", }; -static const size_t kLen85 = 574; +static const size_t kLen85 = 644; static const char *kData85[] = { - "-----BEGIN CERTIFICATE-----\nMIIBejCCASGgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0YwRDAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYDVR0OBAYEBHJvb3QwDgYDVR0T\nBAdJTlZBTElEMAoGCCqGSM49BAMCA0cAMEQCIB2OGsfTIUGaJ3iTXv2oung5pLKH\nVExVqc+KbnIyDbnaAiBwgxjlX+01/ERfGguz+W+00m4IZlzbyAp4dEs4rW9AXw==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBrjCCAVOgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjcDBuMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MBUGA1UdDgQOBAxpbnRlcm1lZGlhdGUwDwYDVR0jBAgwBoAEcm9vdDAOBgNV\nHREEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSQAwRgIhAI49whD5azejKejI1xowdbu7\nLHeT2wNanCCU+KCOoBFPAiEAoog5xR90Z2lWsLJEPWiw7WLJMNuZBDINLNVDCA5d\nD0k=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen86 = 570; +static const size_t kLen86 = 611; static const char *kData86[] = { - "-----BEGIN CERTIFICATE-----\nMIIBeDCCAR2gAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0IwQDAOBgNVHQ8BAf8E\nBAMCAgQwDwYDVR0TAQH/BAUwAwEB/zANBgNVHQ4EBgQEcm9vdDAOBgNVHSUEB0lO\nVkFMSUQwCgYIKoZIzj0EAwIDSQAwRgIhAIY8RxbluUZ2M2PPy5IHnvdXRaQdIq3Z\nDFg9LwkxXl8NAiEAzdE/F19Upl4E7LmdnmGXz8BxhNB6e5CxiJJEdeexCn8=\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBljCCATygAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj\nopP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjWTBXMA4G\nA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD\nAQH/MA8GA1UdIwQIMAaABHJvb3QwDgYDVR0OBAdJTlZBTElEMAoGCCqGSM49BAMC\nA0gAMEUCIDsbBMbAWuJq9VnfrSjLBTK6TSfskt3i0ns2y/9FEW04AiEAkjyacdGb\nsk1wvjrVc5ny6O96NvUGkdO1/GNdPNKPYWQ=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen87 = 574; +static const size_t kLen87 = 688; static const char *kData87[] = { - "-----BEGIN CERTIFICATE-----\nMIIBfDCCASKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0cwRTATBgNVHSUEDDAK\nBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA0GA1UdDgQGBARyb290MA4GA1Ud\nDwQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiEAt0anuhA0pecFMnlB4+M9lcy6\nVZsopjCniyHxfaaf1jQCICPaxHg+ztBFtOjCsr8nbgSy/JWYejF1uTjLYZKj5z6I\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIBzzCCAXagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GaMIGXMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93\nd3cuZXhhbXBsZS5jb20wHgYDVR0eBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAK\nBggqhkjOPQQDAgNHADBEAiAJtROn4TOAvfttoQJ6RsqnsaR1WaP+CKzWXjARJxtQ\nLwIgGmbRenVTFx8ho17JY8ncV5qaJqc0EXN56twt9SccKqE=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen88 = 595; +static const size_t kLen88 = 680; static const char *kData88[] = { - "-----BEGIN CERTIFICATE-----\nMIIBizCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHR4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgHa/R\ni3/yXzHD61xU8mVWSnH39FP5V0mzcHqxKvGSlk4CICsg1HCVLPvYIVUd0Kc8bv6h\nuu6UUup8MlUdFrRJaOus\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIByDCCAW2gAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GRMIGOMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAeBgNVHR4EFzAV\noBMwEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdIwQHSU5WQUxJRDAKBggqhkjOPQQD\nAgNJADBGAiEAj6hhgnfiI0zt38N98eQsfJCJ8ZGkLfH+69OOUISls2QCIQDtyWhN\nL/7L787+zkUazG4HvZ/YHO7hbWQAfMQVbk/iRA==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen89 = 599; +static const size_t kLen89 = 692; static const char *kData89[] = { - "-----BEGIN CERTIFICATE-----\nMIIBjDCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHREEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgZ12y\n9EulwmfqICXtykhGr9Pjfcdg6SacCreLx7454cYCIQCQkP5Ji2SW1Huzp6hE1oHw\nXwNwxFXV6XMJ+NylMYoJ3w==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIB0zCCAXigAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GcMIGZMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATANBgNVHQ4EBgQEbGVhZjAXBgNV\nHSMEEDAOgAxpbnRlcm1lZGlhdGUwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t\nMB4GA1UdHgQXMBWgEzARgg93d3cuZXhhbXBsZS5jb20wDgYDVR0TBAdJTlZBTElE\nMAoGCCqGSM49BAMCA0kAMEYCIQDo/XMevx8IdL+LOl55riE3otGDWKDDPgaZKA43\nsnAJAwIhAJtgm2YNclXG1i8PzrSqZ5Y5mvBMgtjTfW/7ld7ED3pK\n-----END CERTIFICATE-----\n", }; -static const size_t kLen90 = 579; +static const size_t kLen90 = 684; static const char *kData90[] = { - "-----BEGIN CERTIFICATE-----\nMIIBfTCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIhAOOhlyJ15KAUZlokr35Y51mJ\nIc8V3490rloGXldPJajUAiADevilj44K19daaJCFDSIRByO23doY7AmoeLt6YgNJ\nDQ==\n-----END CERTIFICATE-----\n", + "-----BEGIN CERTIFICATE-----\nMIIByzCCAXGgAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GVMIGSMA4GA1UdDwEB\n/wQEAwICBDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBARsZWFmMBcGA1UdIwQQMA6A\nDGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20wHgYDVR0e\nBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAOBgNVHSUEB0lOVkFMSUQwCgYIKoZI\nzj0EAwIDSAAwRQIhAJwe+EZy9v2fW6bYAE8T2NEJjc0SDLoHshJOae3yOYMoAiB1\nkTrY4iuQKBwbbAokFgnHr+Ev1aXcmjRn0sJFDesUAw==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen91 = 18852; +static const size_t kLen91 = 688; static const char *kData91[] = { + "-----BEGIN CERTIFICATE-----\nMIIBzzCCAXagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GaMIGXMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBGxlYWYwFwYDVR0j\nBBAwDoAMaW50ZXJtZWRpYXRlMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAe\nBgNVHR4EFzAVoBMwEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdDwQHSU5WQUxJRDAK\nBggqhkjOPQQDAgNHADBEAiAoWszkhUlrT+vn0BqkA8yuuyCQ7HvK8KQOJsvzFYkS\nqwIgbzwpATgcK7hhRG+GIO8v/MWqomOLExlQYcGIPPODHH0=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen92 = 668; + +static const char *kData92[] = { + "-----BEGIN CERTIFICATE-----\nMIIBvzCCAWagAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GKMIGHMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93\nd3cuZXhhbXBsZS5jb20wDgYDVR0eBAdJTlZBTElEMAoGCCqGSM49BAMCA0cAMEQC\nIDBcHYVfj62g5y2gP/TTvH3VQr4XG/QNZLL6N8H/A8arAiB95102dlC8zVt4beDe\nejD7/YA0FNMSgEnAZ1VgzPejxA==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen93 = 676; + +static const char *kData93[] = { + "-----BEGIN CERTIFICATE-----\nMIIBxTCCAWqgAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GOMIGLMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAeBgNVHR4EFzAVoBMw\nEYIPd3d3LmV4YW1wbGUuY29tMA4GA1UdEQQHSU5WQUxJRDAKBggqhkjOPQQDAgNJ\nADBGAiEAurYkjuxVgkxbmI1D+qM5RGXPPs7V74okqeQdURcL7HACIQDGNT6gcPDw\nAx2Hm5GK3H5UrNEmD1K4IOxfKl9zguiffQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen94 = 692; + +static const char *kData94[] = { + "-----BEGIN CERTIFICATE-----\nMIIB0jCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBcGA1Ud\nIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20w\nHgYDVR0eBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAOBgNVHQ4EB0lOVkFMSUQw\nCgYIKoZIzj0EAwIDSQAwRgIhAOgBejpWnjlxO/K8FMTGO7J+sHS6PAQohwvEgLmT\nKWhMAiEAuc5uRycxN44gGka2Of9zw09o50sKgS1Ckv+VhkDqgbg=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen95 = 574; + +static const char *kData95[] = { + "-----BEGIN CERTIFICATE-----\nMIIBfDCCASKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0cwRTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAKBggqhkjOPQQDAgNIADBFAiBd9AxKvRMSY7ll42h5jjYh5QtK\nYu3fxeME1IeivVNzQAIhAPov0l/2FYwZmMGI9ihR3iD/8petRfp4E9JLQQd3TgL5\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen96 = 599; + +static const char *kData96[] = { + "-----BEGIN CERTIFICATE-----\nMIIBjDCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHSMEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIhAMVD\nOFcNzmPEdD2dJ3KWRGR15vQbXEXvimZgJdKtXdbLAiBfJOocLiQfPU7Nk3Qo0Ti1\nEn0QfUATxx8DNR15cfcupQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen97 = 574; + +static const char *kData97[] = { + "-----BEGIN CERTIFICATE-----\nMIIBejCCASGgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0YwRDAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYDVR0OBAYEBHJvb3QwDgYDVR0T\nBAdJTlZBTElEMAoGCCqGSM49BAMCA0cAMEQCIB2OGsfTIUGaJ3iTXv2oung5pLKH\nVExVqc+KbnIyDbnaAiBwgxjlX+01/ERfGguz+W+00m4IZlzbyAp4dEs4rW9AXw==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen98 = 570; + +static const char *kData98[] = { + "-----BEGIN CERTIFICATE-----\nMIIBeDCCAR2gAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0IwQDAOBgNVHQ8BAf8E\nBAMCAgQwDwYDVR0TAQH/BAUwAwEB/zANBgNVHQ4EBgQEcm9vdDAOBgNVHSUEB0lO\nVkFMSUQwCgYIKoZIzj0EAwIDSQAwRgIhAIY8RxbluUZ2M2PPy5IHnvdXRaQdIq3Z\nDFg9LwkxXl8NAiEAzdE/F19Upl4E7LmdnmGXz8BxhNB6e5CxiJJEdeexCn8=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen99 = 574; + +static const char *kData99[] = { + "-----BEGIN CERTIFICATE-----\nMIIBfDCCASKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0cwRTATBgNVHSUEDDAK\nBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA0GA1UdDgQGBARyb290MA4GA1Ud\nDwQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiEAt0anuhA0pecFMnlB4+M9lcy6\nVZsopjCniyHxfaaf1jQCICPaxHg+ztBFtOjCsr8nbgSy/JWYejF1uTjLYZKj5z6I\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen100 = 595; + +static const char *kData100[] = { + "-----BEGIN CERTIFICATE-----\nMIIBizCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHR4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgHa/R\ni3/yXzHD61xU8mVWSnH39FP5V0mzcHqxKvGSlk4CICsg1HCVLPvYIVUd0Kc8bv6h\nuu6UUup8MlUdFrRJaOus\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen101 = 599; + +static const char *kData101[] = { + "-----BEGIN CERTIFICATE-----\nMIIBjDCCATKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto1cwVTAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zANBgNV\nHQ4EBgQEcm9vdDAOBgNVHREEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgZ12y\n9EulwmfqICXtykhGr9Pjfcdg6SacCreLx7454cYCIQCQkP5Ji2SW1Huzp6hE1oHw\nXwNwxFXV6XMJ+NylMYoJ3w==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen102 = 579; + +static const char *kData102[] = { + "-----BEGIN CERTIFICATE-----\nMIIBfTCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk\nIEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw\nMFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI\nB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E\nBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\nHQ4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIhAOOhlyJ15KAUZlokr35Y51mJ\nIc8V3490rloGXldPJajUAiADevilj44K19daaJCFDSIRByO23doY7AmoeLt6YgNJ\nDQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen103 = 18852; + +static const char *kData103[] = { "-----BEGIN CERTIFICATE-----\nMII2MzCCNRugAwIBAgIBATANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDTELMAkGA1UEAxMCQ0Ew\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6C9qEGRIBQXV8Lj29vVu+\nU+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/IlsYdkuq\n8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yBXFf4tG3C\nBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSVFj2irCZb\nsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ2/xo70Om\nH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIqY95CKy25\nAgMBAAGjgjOaMIIzljAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUH\nAwEwDwYDVR0TAQH/BAUwAwEB/zCCM1wGA1UdHgSCM1MwgjNPoIIZqDAJggd0MC50\nZXN0MAmCB3QxLnRlc3QwCYIHdDIudGVzdDAJggd0My50ZXN0MAmCB3Q0LnRlc3Qw\nCYIHdDUudGVzdDAJggd0Ni50ZXN0MAmCB3Q3LnRlc3QwCYIHdDgudGVzdDAJggd0\nOS50ZXN0MAqCCHQxMC50ZXN0MAqCCHQxMS50ZXN0MAqCCHQxMi50ZXN0MAqCCHQx\nMy50ZXN0MAqCCHQxNC50ZXN0MAqCCHQxNS50ZXN0MAqCCHQxNi50ZXN0MAqCCHQx\nNy50ZXN0MAqCCHQxOC50ZXN0MAqCCHQxOS50ZXN0MAqCCHQyMC50ZXN0MAqCCHQy\nMS50ZXN0MAqCCHQyMi50ZXN0MAqCCHQyMy50ZXN0MAqCCHQyNC50ZXN0MAqCCHQy\nNS50ZXN0MAqCCHQyNi50ZXN0MAqCCHQyNy50ZXN0MAqCCHQyOC50ZXN0MAqCCHQy\nOS50ZXN0MAqCCHQzMC50ZXN0MAqCCHQzMS50ZXN0MAqCCHQzMi50ZXN0MAqCCHQz\nMy50ZXN0MAqCCHQzNC50ZXN0MAqCCHQzNS50ZXN0MAqCCHQzNi50ZXN0MAqCCHQz\nNy50ZXN0MAqCCHQzOC50ZXN0MAqCCHQzOS50ZXN0MAqCCHQ0MC50ZXN0MAqCCHQ0\nMS50ZXN0MAqCCHQ0Mi50ZXN0MAqCCHQ0My50ZXN0MAqCCHQ0NC50ZXN0MAqCCHQ0\nNS50ZXN0MAqCCHQ0Ni50ZXN0MAqCCHQ0Ny50ZXN0MAqCCHQ0OC50ZXN0MAqCCHQ0\nOS50ZXN0MAqCCHQ1MC50ZXN0MAqCCHQ1MS50ZXN0MAqCCHQ1Mi50ZXN0MAqCCHQ1\nMy50ZXN0MAqCCHQ1NC50ZXN0MAqCCHQ1NS50ZXN0MAqCCHQ1Ni50ZXN0MAqCCHQ1\nNy50ZXN0MAqCCHQ1OC50ZXN0MAqCCHQ1OS50ZXN0MAqCCHQ2MC50ZXN0MAqCCHQ2\nMS50ZXN0MAqCCHQ2Mi50ZXN0MAqCCHQ2My50ZXN0MAqCCHQ2NC50ZXN0MAqCCHQ2\nNS50ZXN0MAqCCHQ2Ni50ZXN0MAqCCHQ2Ny50ZXN0MAqCCHQ2OC50ZXN0MAqCCHQ2\nOS50ZXN0MAqCCHQ3MC50ZXN0MAqCCHQ3MS50ZXN0MAqCCHQ3Mi50ZXN0MAqCCHQ3\nMy50ZXN0MAqCCHQ3NC50ZXN0MAqCCHQ3NS50ZXN0MAqCCHQ3Ni50ZXN0MAqCCHQ3\nNy50ZXN0MAqCCHQ3OC50ZXN0MAqCCHQ3OS50ZXN0MAqCCHQ4MC50ZXN0MAqCCHQ4\nMS50ZXN0MAqCCHQ4Mi50ZXN0MAqCCHQ4My50ZXN0MAqCCHQ4NC50ZXN0MAqCCHQ4\nNS50ZXN0MAqCCHQ4Ni50ZXN0MAqCCHQ4Ny50ZXN0MAqCCHQ4OC50ZXN0MAqCCHQ4\nOS50ZXN0MAqCCHQ5MC50ZXN0MAqCCHQ5MS50ZXN0MAqCCHQ5Mi50ZXN0MAqCCHQ5\nMy50ZXN0MAqCCHQ5NC50ZXN0MAqCCHQ5NS50ZXN0MAqCCHQ5Ni50ZXN0MAqCCHQ5\nNy50ZXN0MAqCCHQ5OC50ZXN0MAqCCHQ5OS50ZXN0MAuCCXQxMDAudGVzdDALggl0\nMTAxLnRlc3QwC4IJdDEwMi50ZXN0MAuCCXQxMDMudGVzdDALggl0MTA0LnRlc3Qw\nC4IJdDEwNS50ZXN0MAuCCXQxMDYudGVzdDALggl0MTA3LnRlc3QwC4IJdDEwOC50\nZXN0MAuCCXQxMDkudGVzdDALggl0MTEwLnRlc3QwC4IJdDExMS50ZXN0MAuCCXQx\nMTIudGVzdDALggl0MTEzLnRlc3QwC4IJdDExNC50ZXN0MAuCCXQxMTUudGVzdDAL\nggl0MTE2LnRlc3QwC4IJdDExNy50ZXN0MAuCCXQxMTgudGVzdDALggl0MTE5LnRl\nc3QwC4IJdDEyMC50ZXN0MAuCCXQxMjEudGVzdDALggl0MTIyLnRlc3QwC4IJdDEy\nMy50ZXN0MAuCCXQxMjQudGVzdDALggl0MTI1LnRlc3QwC4IJdDEyNi50ZXN0MAuC\nCXQxMjcudGVzdDALggl0MTI4LnRlc3QwC4IJdDEyOS50ZXN0MAuCCXQxMzAudGVz\ndDALggl0MTMxLnRlc3QwC4IJdDEzMi50ZXN0MAuCCXQxMzMudGVzdDALggl0MTM0\nLnRlc3QwC4IJdDEzNS50ZXN0MAuCCXQxMzYudGVzdDALggl0MTM3LnRlc3QwC4IJ\ndDEzOC50ZXN0MAuCCXQxMzkudGVzdDALggl0MTQwLnRlc3QwC4IJdDE0MS50ZXN0\nMAuCCXQxNDIudGVzdDALggl0MTQzLnRlc3QwC4IJdDE0NC50ZXN0MAuCCXQxNDUu\ndGVzdDALggl0MTQ2LnRlc3QwC4IJdDE0Ny50ZXN0MAuCCXQxNDgudGVzdDALggl0\nMTQ5LnRlc3QwC4IJdDE1MC50ZXN0MAuCCXQxNTEudGVzdDALggl0MTUyLnRlc3Qw\nC4IJdDE1My50ZXN0MAuCCXQxNTQudGVzdDALggl0MTU1LnRlc3QwC4IJdDE1Ni50\nZXN0MAuCCXQxNTcudGVzdDALggl0MTU4LnRlc3QwC4IJdDE1OS50ZXN0MAuCCXQx\nNjAudGVzdDALggl0MTYxLnRlc3QwC4IJdDE2Mi50ZXN0MAuCCXQxNjMudGVzdDAL\nggl0MTY0LnRlc3QwC4IJdDE2NS50ZXN0MAuCCXQxNjYudGVzdDALggl0MTY3LnRl\nc3QwC4IJdDE2OC50ZXN0MAuCCXQxNjkudGVzdDALggl0MTcwLnRlc3QwC4IJdDE3\nMS50ZXN0MAuCCXQxNzIudGVzdDALggl0MTczLnRlc3QwC4IJdDE3NC50ZXN0MAuC\nCXQxNzUudGVzdDALggl0MTc2LnRlc3QwC4IJdDE3Ny50ZXN0MAuCCXQxNzgudGVz\ndDALggl0MTc5LnRlc3QwC4IJdDE4MC50ZXN0MAuCCXQxODEudGVzdDALggl0MTgy\nLnRlc3QwC4IJdDE4My50ZXN0MAuCCXQxODQudGVzdDALggl0MTg1LnRlc3QwC4IJ\ndDE4Ni50ZXN0MAuCCXQxODcudGVzdDALggl0MTg4LnRlc3QwC4IJdDE4OS50ZXN0\nMAuCCXQxOTAudGVzdDALggl0MTkxLnRlc3QwC4IJdDE5Mi50ZXN0MAuCCXQxOTMu\ndGVzdDALggl0MTk0LnRlc3QwC4IJdDE5NS50ZXN0MAuCCXQxOTYudGVzdDALggl0\nMTk3LnRlc3QwC4IJdDE5OC50ZXN0MAuCCXQxOTkudGVzdDALggl0MjAwLnRlc3Qw\nC4IJdDIwMS50ZXN0MAuCCXQyMDIudGVzdDALggl0MjAzLnRlc3QwC4IJdDIwNC50\nZXN0MAuCCXQyMDUudGVzdDALggl0MjA2LnRlc3QwC4IJdDIwNy50ZXN0MAuCCXQy\nMDgudGVzdDALggl0MjA5LnRlc3QwC4IJdDIxMC50ZXN0MAuCCXQyMTEudGVzdDAL\nggl0MjEyLnRlc3QwC4IJdDIxMy50ZXN0MAuCCXQyMTQudGVzdDALggl0MjE1LnRl\nc3QwC4IJdDIxNi50ZXN0MAuCCXQyMTcudGVzdDALggl0MjE4LnRlc3QwC4IJdDIx\nOS50ZXN0MAuCCXQyMjAudGVzdDALggl0MjIxLnRlc3QwC4IJdDIyMi50ZXN0MAuC\nCXQyMjMudGVzdDALggl0MjI0LnRlc3QwC4IJdDIyNS50ZXN0MAuCCXQyMjYudGVz\ndDALggl0MjI3LnRlc3QwC4IJdDIyOC50ZXN0MAuCCXQyMjkudGVzdDALggl0MjMw\nLnRlc3QwC4IJdDIzMS50ZXN0MAuCCXQyMzIudGVzdDALggl0MjMzLnRlc3QwC4IJ\ndDIzNC50ZXN0MAuCCXQyMzUudGVzdDALggl0MjM2LnRlc3QwC4IJdDIzNy50ZXN0\nMAuCCXQyMzgudGVzdDALggl0MjM5LnRlc3QwC4IJdDI0MC50ZXN0MAuCCXQyNDEu\ndGVzdDALggl0MjQyLnRlc3QwC4IJdDI0My50ZXN0MAuCCXQyNDQudGVzdDALggl0\nMjQ1LnRlc3QwC4IJdDI0Ni50ZXN0MAuCCXQyNDcudGVzdDALggl0MjQ4LnRlc3Qw\nC4IJdDI0OS50ZXN0MAuCCXQyNTAudGVzdDALggl0MjUxLnRlc3QwC4IJdDI1Mi50\nZXN0MAuCCXQyNTMudGVzdDALggl0MjU0LnRlc3QwC4IJdDI1NS50ZXN0MAuCCXQy\nNTYudGVzdDALggl0MjU3LnRlc3QwC4IJdDI1OC50ZXN0MAuCCXQyNTkudGVzdDAL\nggl0MjYwLnRlc3QwC4IJdDI2MS50ZXN0MAuCCXQyNjIudGVzdDALggl0MjYzLnRl\nc3QwC4IJdDI2NC50ZXN0MAuCCXQyNjUudGVzdDALggl0MjY2LnRlc3QwC4IJdDI2\nNy50ZXN0MAuCCXQyNjgudGVzdDALggl0MjY5LnRlc3QwC4IJdDI3MC50ZXN0MAuC\nCXQyNzEudGVzdDALggl0MjcyLnRlc3QwC4IJdDI3My50ZXN0MAuCCXQyNzQudGVz\ndDALggl0Mjc1LnRlc3QwC4IJdDI3Ni50ZXN0MAuCCXQyNzcudGVzdDALggl0Mjc4\nLnRlc3QwC4IJdDI3OS50ZXN0MAuCCXQyODAudGVzdDALggl0MjgxLnRlc3QwC4IJ\ndDI4Mi50ZXN0MAuCCXQyODMudGVzdDALggl0Mjg0LnRlc3QwC4IJdDI4NS50ZXN0\nMAuCCXQyODYudGVzdDALggl0Mjg3LnRlc3QwC4IJdDI4OC50ZXN0MAuCCXQyODku\ndGVzdDALggl0MjkwLnRlc3QwC4IJdDI5MS50ZXN0MAuCCXQyOTIudGVzdDALggl0\nMjkzLnRlc3QwC4IJdDI5NC50ZXN0MAuCCXQyOTUudGVzdDALggl0Mjk2LnRlc3Qw\nC4IJdDI5Ny50ZXN0MAuCCXQyOTgudGVzdDALggl0Mjk5LnRlc3QwC4IJdDMwMC50\nZXN0MAuCCXQzMDEudGVzdDALggl0MzAyLnRlc3QwC4IJdDMwMy50ZXN0MAuCCXQz\nMDQudGVzdDALggl0MzA1LnRlc3QwC4IJdDMwNi50ZXN0MAuCCXQzMDcudGVzdDAL\nggl0MzA4LnRlc3QwC4IJdDMwOS50ZXN0MAuCCXQzMTAudGVzdDALggl0MzExLnRl\nc3QwC4IJdDMxMi50ZXN0MAuCCXQzMTMudGVzdDALggl0MzE0LnRlc3QwC4IJdDMx\nNS50ZXN0MAuCCXQzMTYudGVzdDALggl0MzE3LnRlc3QwC4IJdDMxOC50ZXN0MAuC\nCXQzMTkudGVzdDALggl0MzIwLnRlc3QwC4IJdDMyMS50ZXN0MAuCCXQzMjIudGVz\ndDALggl0MzIzLnRlc3QwC4IJdDMyNC50ZXN0MAuCCXQzMjUudGVzdDALggl0MzI2\nLnRlc3QwC4IJdDMyNy50ZXN0MAuCCXQzMjgudGVzdDALggl0MzI5LnRlc3QwC4IJ\ndDMzMC50ZXN0MAuCCXQzMzEudGVzdDALggl0MzMyLnRlc3QwC4IJdDMzMy50ZXN0\nMAuCCXQzMzQudGVzdDALggl0MzM1LnRlc3QwC4IJdDMzNi50ZXN0MAuCCXQzMzcu\ndGVzdDALggl0MzM4LnRlc3QwC4IJdDMzOS50ZXN0MAuCCXQzNDAudGVzdDALggl0\nMzQxLnRlc3QwC4IJdDM0Mi50ZXN0MAuCCXQzNDMudGVzdDALggl0MzQ0LnRlc3Qw\nC4IJdDM0NS50ZXN0MAuCCXQzNDYudGVzdDALggl0MzQ3LnRlc3QwC4IJdDM0OC50\nZXN0MAuCCXQzNDkudGVzdDALggl0MzUwLnRlc3QwC4IJdDM1MS50ZXN0MAuCCXQz\nNTIudGVzdDALggl0MzUzLnRlc3QwC4IJdDM1NC50ZXN0MAuCCXQzNTUudGVzdDAL\nggl0MzU2LnRlc3QwC4IJdDM1Ny50ZXN0MAuCCXQzNTgudGVzdDALggl0MzU5LnRl\nc3QwC4IJdDM2MC50ZXN0MAuCCXQzNjEudGVzdDALggl0MzYyLnRlc3QwC4IJdDM2\nMy50ZXN0MAuCCXQzNjQudGVzdDALggl0MzY1LnRlc3QwC4IJdDM2Ni50ZXN0MAuC\nCXQzNjcudGVzdDALggl0MzY4LnRlc3QwC4IJdDM2OS50ZXN0MAuCCXQzNzAudGVz\ndDALggl0MzcxLnRlc3QwC4IJdDM3Mi50ZXN0MAuCCXQzNzMudGVzdDALggl0Mzc0\nLnRlc3QwC4IJdDM3NS50ZXN0MAuCCXQzNzYudGVzdDALggl0Mzc3LnRlc3QwC4IJ\ndDM3OC50ZXN0MAuCCXQzNzkudGVzdDALggl0MzgwLnRlc3QwC4IJdDM4MS50ZXN0\nMAuCCXQzODIudGVzdDALggl0MzgzLnRlc3QwC4IJdDM4NC50ZXN0MAuCCXQzODUu\ndGVzdDALggl0Mzg2LnRlc3QwC4IJdDM4Ny50ZXN0MAuCCXQzODgudGVzdDALggl0\nMzg5LnRlc3QwC4IJdDM5MC50ZXN0MAuCCXQzOTEudGVzdDALggl0MzkyLnRlc3Qw\nC4IJdDM5My50ZXN0MAuCCXQzOTQudGVzdDALggl0Mzk1LnRlc3QwC4IJdDM5Ni50\nZXN0MAuCCXQzOTcudGVzdDALggl0Mzk4LnRlc3QwC4IJdDM5OS50ZXN0MAuCCXQ0\nMDAudGVzdDALggl0NDAxLnRlc3QwC4IJdDQwMi50ZXN0MAuCCXQ0MDMudGVzdDAL\nggl0NDA0LnRlc3QwC4IJdDQwNS50ZXN0MAuCCXQ0MDYudGVzdDALggl0NDA3LnRl\nc3QwC4IJdDQwOC50ZXN0MAuCCXQ0MDkudGVzdDALggl0NDEwLnRlc3QwC4IJdDQx\nMS50ZXN0MAuCCXQ0MTIudGVzdDALggl0NDEzLnRlc3QwC4IJdDQxNC50ZXN0MAuC\nCXQ0MTUudGVzdDALggl0NDE2LnRlc3QwC4IJdDQxNy50ZXN0MAuCCXQ0MTgudGVz\ndDALggl0NDE5LnRlc3QwC4IJdDQyMC50ZXN0MAuCCXQ0MjEudGVzdDALggl0NDIy\nLnRlc3QwC4IJdDQyMy50ZXN0MAuCCXQ0MjQudGVzdDALggl0NDI1LnRlc3QwC4IJ\ndDQyNi50ZXN0MAuCCXQ0MjcudGVzdDALggl0NDI4LnRlc3QwC4IJdDQyOS50ZXN0\nMAuCCXQ0MzAudGVzdDALggl0NDMxLnRlc3QwC4IJdDQzMi50ZXN0MAuCCXQ0MzMu\ndGVzdDALggl0NDM0LnRlc3QwC4IJdDQzNS50ZXN", "0MAuCCXQ0MzYudGVzdDALggl0\nNDM3LnRlc3QwC4IJdDQzOC50ZXN0MAuCCXQ0MzkudGVzdDALggl0NDQwLnRlc3Qw\nC4IJdDQ0MS50ZXN0MAuCCXQ0NDIudGVzdDALggl0NDQzLnRlc3QwC4IJdDQ0NC50\nZXN0MAuCCXQ0NDUudGVzdDALggl0NDQ2LnRlc3QwC4IJdDQ0Ny50ZXN0MAuCCXQ0\nNDgudGVzdDALggl0NDQ5LnRlc3QwC4IJdDQ1MC50ZXN0MAuCCXQ0NTEudGVzdDAL\nggl0NDUyLnRlc3QwC4IJdDQ1My50ZXN0MAuCCXQ0NTQudGVzdDALggl0NDU1LnRl\nc3QwC4IJdDQ1Ni50ZXN0MAuCCXQ0NTcudGVzdDALggl0NDU4LnRlc3QwC4IJdDQ1\nOS50ZXN0MAuCCXQ0NjAudGVzdDALggl0NDYxLnRlc3QwC4IJdDQ2Mi50ZXN0MAuC\nCXQ0NjMudGVzdDALggl0NDY0LnRlc3QwC4IJdDQ2NS50ZXN0MAuCCXQ0NjYudGVz\ndDALggl0NDY3LnRlc3QwC4IJdDQ2OC50ZXN0MAuCCXQ0NjkudGVzdDALggl0NDcw\nLnRlc3QwC4IJdDQ3MS50ZXN0MAuCCXQ0NzIudGVzdDALggl0NDczLnRlc3QwC4IJ\ndDQ3NC50ZXN0MAuCCXQ0NzUudGVzdDALggl0NDc2LnRlc3QwC4IJdDQ3Ny50ZXN0\nMAuCCXQ0NzgudGVzdDALggl0NDc5LnRlc3QwC4IJdDQ4MC50ZXN0MAuCCXQ0ODEu\ndGVzdDALggl0NDgyLnRlc3QwC4IJdDQ4My50ZXN0MAuCCXQ0ODQudGVzdDALggl0\nNDg1LnRlc3QwC4IJdDQ4Ni50ZXN0MAuCCXQ0ODcudGVzdDALggl0NDg4LnRlc3Qw\nC4IJdDQ4OS50ZXN0MAuCCXQ0OTAudGVzdDALggl0NDkxLnRlc3QwC4IJdDQ5Mi50\nZXN0MAuCCXQ0OTMudGVzdDALggl0NDk0LnRlc3QwC4IJdDQ5NS50ZXN0MAuCCXQ0\nOTYudGVzdDALggl0NDk3LnRlc3QwC4IJdDQ5OC50ZXN0MAuCCXQ0OTkudGVzdDAL\nggl0NTAwLnRlc3QwC4IJdDUwMS50ZXN0MAuCCXQ1MDIudGVzdDALggl0NTAzLnRl\nc3QwC4IJdDUwNC50ZXN0MAuCCXQ1MDUudGVzdDALggl0NTA2LnRlc3QwC4IJdDUw\nNy50ZXN0MAuCCXQ1MDgudGVzdDALggl0NTA5LnRlc3QwC4IJdDUxMC50ZXN0MAuC\nCXQ1MTEudGVzdDALggl0NTEyLnRlc3QwB4IFLnRlc3ShghmfMAmCB3gwLnRlc3Qw\nCYIHeDEudGVzdDAJggd4Mi50ZXN0MAmCB3gzLnRlc3QwCYIHeDQudGVzdDAJggd4\nNS50ZXN0MAmCB3g2LnRlc3QwCYIHeDcudGVzdDAJggd4OC50ZXN0MAmCB3g5LnRl\nc3QwCoIIeDEwLnRlc3QwCoIIeDExLnRlc3QwCoIIeDEyLnRlc3QwCoIIeDEzLnRl\nc3QwCoIIeDE0LnRlc3QwCoIIeDE1LnRlc3QwCoIIeDE2LnRlc3QwCoIIeDE3LnRl\nc3QwCoIIeDE4LnRlc3QwCoIIeDE5LnRlc3QwCoIIeDIwLnRlc3QwCoIIeDIxLnRl\nc3QwCoIIeDIyLnRlc3QwCoIIeDIzLnRlc3QwCoIIeDI0LnRlc3QwCoIIeDI1LnRl\nc3QwCoIIeDI2LnRlc3QwCoIIeDI3LnRlc3QwCoIIeDI4LnRlc3QwCoIIeDI5LnRl\nc3QwCoIIeDMwLnRlc3QwCoIIeDMxLnRlc3QwCoIIeDMyLnRlc3QwCoIIeDMzLnRl\nc3QwCoIIeDM0LnRlc3QwCoIIeDM1LnRlc3QwCoIIeDM2LnRlc3QwCoIIeDM3LnRl\nc3QwCoIIeDM4LnRlc3QwCoIIeDM5LnRlc3QwCoIIeDQwLnRlc3QwCoIIeDQxLnRl\nc3QwCoIIeDQyLnRlc3QwCoIIeDQzLnRlc3QwCoIIeDQ0LnRlc3QwCoIIeDQ1LnRl\nc3QwCoIIeDQ2LnRlc3QwCoIIeDQ3LnRlc3QwCoIIeDQ4LnRlc3QwCoIIeDQ5LnRl\nc3QwCoIIeDUwLnRlc3QwCoIIeDUxLnRlc3QwCoIIeDUyLnRlc3QwCoIIeDUzLnRl\nc3QwCoIIeDU0LnRlc3QwCoIIeDU1LnRlc3QwCoIIeDU2LnRlc3QwCoIIeDU3LnRl\nc3QwCoIIeDU4LnRlc3QwCoIIeDU5LnRlc3QwCoIIeDYwLnRlc3QwCoIIeDYxLnRl\nc3QwCoIIeDYyLnRlc3QwCoIIeDYzLnRlc3QwCoIIeDY0LnRlc3QwCoIIeDY1LnRl\nc3QwCoIIeDY2LnRlc3QwCoIIeDY3LnRlc3QwCoIIeDY4LnRlc3QwCoIIeDY5LnRl\nc3QwCoIIeDcwLnRlc3QwCoIIeDcxLnRlc3QwCoIIeDcyLnRlc3QwCoIIeDczLnRl\nc3QwCoIIeDc0LnRlc3QwCoIIeDc1LnRlc3QwCoIIeDc2LnRlc3QwCoIIeDc3LnRl\nc3QwCoIIeDc4LnRlc3QwCoIIeDc5LnRlc3QwCoIIeDgwLnRlc3QwCoIIeDgxLnRl\nc3QwCoIIeDgyLnRlc3QwCoIIeDgzLnRlc3QwCoIIeDg0LnRlc3QwCoIIeDg1LnRl\nc3QwCoIIeDg2LnRlc3QwCoIIeDg3LnRlc3QwCoIIeDg4LnRlc3QwCoIIeDg5LnRl\nc3QwCoIIeDkwLnRlc3QwCoIIeDkxLnRlc3QwCoIIeDkyLnRlc3QwCoIIeDkzLnRl\nc3QwCoIIeDk0LnRlc3QwCoIIeDk1LnRlc3QwCoIIeDk2LnRlc3QwCoIIeDk3LnRl\nc3QwCoIIeDk4LnRlc3QwCoIIeDk5LnRlc3QwC4IJeDEwMC50ZXN0MAuCCXgxMDEu\ndGVzdDALggl4MTAyLnRlc3QwC4IJeDEwMy50ZXN0MAuCCXgxMDQudGVzdDALggl4\nMTA1LnRlc3QwC4IJeDEwNi50ZXN0MAuCCXgxMDcudGVzdDALggl4MTA4LnRlc3Qw\nC4IJeDEwOS50ZXN0MAuCCXgxMTAudGVzdDALggl4MTExLnRlc3QwC4IJeDExMi50\nZXN0MAuCCXgxMTMudGVzdDALggl4MTE0LnRlc3QwC4IJeDExNS50ZXN0MAuCCXgx\nMTYudGVzdDALggl4MTE3LnRlc3QwC4IJeDExOC50ZXN0MAuCCXgxMTkudGVzdDAL\nggl4MTIwLnRlc3QwC4IJeDEyMS50ZXN0MAuCCXgxMjIudGVzdDALggl4MTIzLnRl\nc3QwC4IJeDEyNC50ZXN0MAuCCXgxMjUudGVzdDALggl4MTI2LnRlc3QwC4IJeDEy\nNy50ZXN0MAuCCXgxMjgudGVzdDALggl4MTI5LnRlc3QwC4IJeDEzMC50ZXN0MAuC\nCXgxMzEudGVzdDALggl4MTMyLnRlc3QwC4IJeDEzMy50ZXN0MAuCCXgxMzQudGVz\ndDALggl4MTM1LnRlc3QwC4IJeDEzNi50ZXN0MAuCCXgxMzcudGVzdDALggl4MTM4\nLnRlc3QwC4IJeDEzOS50ZXN0MAuCCXgxNDAudGVzdDALggl4MTQxLnRlc3QwC4IJ\neDE0Mi50ZXN0MAuCCXgxNDMudGVzdDALggl4MTQ0LnRlc3QwC4IJeDE0NS50ZXN0\nMAuCCXgxNDYudGVzdDALggl4MTQ3LnRlc3QwC4IJeDE0OC50ZXN0MAuCCXgxNDku\ndGVzdDALggl4MTUwLnRlc3QwC4IJeDE1MS50ZXN0MAuCCXgxNTIudGVzdDALggl4\nMTUzLnRlc3QwC4IJeDE1NC50ZXN0MAuCCXgxNTUudGVzdDALggl4MTU2LnRlc3Qw\nC4IJeDE1Ny50ZXN0MAuCCXgxNTgudGVzdDALggl4MTU5LnRlc3QwC4IJeDE2MC50\nZXN0MAuCCXgxNjEudGVzdDALggl4MTYyLnRlc3QwC4IJeDE2My50ZXN0MAuCCXgx\nNjQudGVzdDALggl4MTY1LnRlc3QwC4IJeDE2Ni50ZXN0MAuCCXgxNjcudGVzdDAL\nggl4MTY4LnRlc3QwC4IJeDE2OS50ZXN0MAuCCXgxNzAudGVzdDALggl4MTcxLnRl\nc3QwC4IJeDE3Mi50ZXN0MAuCCXgxNzMudGVzdDALggl4MTc0LnRlc3QwC4IJeDE3\nNS50ZXN0MAuCCXgxNzYudGVzdDALggl4MTc3LnRlc3QwC4IJeDE3OC50ZXN0MAuC\nCXgxNzkudGVzdDALggl4MTgwLnRlc3QwC4IJeDE4MS50ZXN0MAuCCXgxODIudGVz\ndDALggl4MTgzLnRlc3QwC4IJeDE4NC50ZXN0MAuCCXgxODUudGVzdDALggl4MTg2\nLnRlc3QwC4IJeDE4Ny50ZXN0MAuCCXgxODgudGVzdDALggl4MTg5LnRlc3QwC4IJ\neDE5MC50ZXN0MAuCCXgxOTEudGVzdDALggl4MTkyLnRlc3QwC4IJeDE5My50ZXN0\nMAuCCXgxOTQudGVzdDALggl4MTk1LnRlc3QwC4IJeDE5Ni50ZXN0MAuCCXgxOTcu\ndGVzdDALggl4MTk4LnRlc3QwC4IJeDE5OS50ZXN0MAuCCXgyMDAudGVzdDALggl4\nMjAxLnRlc3QwC4IJeDIwMi50ZXN0MAuCCXgyMDMudGVzdDALggl4MjA0LnRlc3Qw\nC4IJeDIwNS50ZXN0MAuCCXgyMDYudGVzdDALggl4MjA3LnRlc3QwC4IJeDIwOC50\nZXN0MAuCCXgyMDkudGVzdDALggl4MjEwLnRlc3QwC4IJeDIxMS50ZXN0MAuCCXgy\nMTIudGVzdDALggl4MjEzLnRlc3QwC4IJeDIxNC50ZXN0MAuCCXgyMTUudGVzdDAL\nggl4MjE2LnRlc3QwC4IJeDIxNy50ZXN0MAuCCXgyMTgudGVzdDALggl4MjE5LnRl\nc3QwC4IJeDIyMC50ZXN0MAuCCXgyMjEudGVzdDALggl4MjIyLnRlc3QwC4IJeDIy\nMy50ZXN0MAuCCXgyMjQudGVzdDALggl4MjI1LnRlc3QwC4IJeDIyNi50ZXN0MAuC\nCXgyMjcudGVzdDALggl4MjI4LnRlc3QwC4IJeDIyOS50ZXN0MAuCCXgyMzAudGVz\ndDALggl4MjMxLnRlc3QwC4IJeDIzMi50ZXN0MAuCCXgyMzMudGVzdDALggl4MjM0\nLnRlc3QwC4IJeDIzNS50ZXN0MAuCCXgyMzYudGVzdDALggl4MjM3LnRlc3QwC4IJ\neDIzOC50ZXN0MAuCCXgyMzkudGVzdDALggl4MjQwLnRlc3QwC4IJeDI0MS50ZXN0\nMAuCCXgyNDIudGVzdDALggl4MjQzLnRlc3QwC4IJeDI0NC50ZXN0MAuCCXgyNDUu\ndGVzdDALggl4MjQ2LnRlc3QwC4IJeDI0Ny50ZXN0MAuCCXgyNDgudGVzdDALggl4\nMjQ5LnRlc3QwC4IJeDI1MC50ZXN0MAuCCXgyNTEudGVzdDALggl4MjUyLnRlc3Qw\nC4IJeDI1My50ZXN0MAuCCXgyNTQudGVzdDALggl4MjU1LnRlc3QwC4IJeDI1Ni50\nZXN0MAuCCXgyNTcudGVzdDALggl4MjU4LnRlc3QwC4IJeDI1OS50ZXN0MAuCCXgy\nNjAudGVzdDALggl4MjYxLnRlc3QwC4IJeDI2Mi50ZXN0MAuCCXgyNjMudGVzdDAL\nggl4MjY0LnRlc3QwC4IJeDI2NS50ZXN0MAuCCXgyNjYudGVzdDALggl4MjY3LnRl\nc3QwC4IJeDI2OC50ZXN0MAuCCXgyNjkudGVzdDALggl4MjcwLnRlc3QwC4IJeDI3\nMS50ZXN0MAuCCXgyNzIudGVzdDALggl4MjczLnRlc3QwC4IJeDI3NC50ZXN0MAuC\nCXgyNzUudGVzdDALggl4Mjc2LnRlc3QwC4IJeDI3Ny50ZXN0MAuCCXgyNzgudGVz\ndDALggl4Mjc5LnRlc3QwC4IJeDI4MC50ZXN0MAuCCXgyODEudGVzdDALggl4Mjgy\nLnRlc3QwC4IJeDI4My50ZXN0MAuCCXgyODQudGVzdDALggl4Mjg1LnRlc3QwC4IJ\neDI4Ni50ZXN0MAuCCXgyODcudGVzdDALggl4Mjg4LnRlc3QwC4IJeDI4OS50ZXN0\nMAuCCXgyOTAudGVzdDALggl4MjkxLnRlc3QwC4IJeDI5Mi50ZXN0MAuCCXgyOTMu\ndGVzdDALggl4Mjk0LnRlc3QwC4IJeDI5NS50ZXN0MAuCCXgyOTYudGVzdDALggl4\nMjk3LnRlc3QwC4IJeDI5OC50ZXN0MAuCCXgyOTkudGVzdDALggl4MzAwLnRlc3Qw\nC4IJeDMwMS50ZXN0MAuCCXgzMDIudGVzdDALggl4MzAzLnRlc3QwC4IJeDMwNC50\nZXN0MAuCCXgzMDUudGVzdDALggl4MzA2LnRlc3QwC4IJeDMwNy50ZXN0MAuCCXgz\nMDgudGVzdDALggl4MzA5LnRlc3QwC4IJeDMxMC50ZXN0MAuCCXgzMTEudGVzdDAL\nggl4MzEyLnRlc3QwC4IJeDMxMy50ZXN0MAuCCXgzMTQudGVzdDALggl4MzE1LnRl\nc3QwC4IJeDMxNi50ZXN0MAuCCXgzMTcudGVzdDALggl4MzE4LnRlc3QwC4IJeDMx\nOS50ZXN0MAuCCXgzMjAudGVzdDALggl4MzIxLnRlc3QwC4IJeDMyMi50ZXN0MAuC\nCXgzMjMudGVzdDALggl4MzI0LnRlc3QwC4IJeDMyNS50ZXN0MAuCCXgzMjYudGVz\ndDALggl4MzI3LnRlc3QwC4IJeDMyOC50ZXN0MAuCCXgzMjkudGVzdDALggl4MzMw\nLnRlc3QwC4IJeDMzMS50ZXN0MAuCCXgzMzIudGVzdDALggl4MzMzLnRlc3QwC4IJ\neDMzNC50ZXN0MAuCCXgzMzUudGVzdDALggl4MzM2LnRlc3QwC4IJeDMzNy50ZXN0\nMAuCCXgzMzgudGVzdDALggl4MzM5LnRlc3QwC4IJeDM0MC50ZXN0MAuCCXgzNDEu\ndGVzdDALggl4MzQyLnRlc3QwC4IJeDM0My50ZXN0MAuCCXgzNDQudGVzdDALggl4\nMzQ1LnRlc3QwC4IJeDM0Ni50ZXN0MAuCCXgzNDcudGVzdDALggl4MzQ4LnRlc3Qw\nC4IJeDM0OS50ZXN0MAuCCXgzNTAudGVzdDALggl4MzUxLnRlc3QwC4IJeDM1Mi50\nZXN0MAuCCXgzNTMudGVzdDALggl4MzU0LnRlc3QwC4IJeDM1NS50ZXN0MAuCCXgz\nNTYudGVzdDALggl4MzU3LnRlc3QwC4IJeDM1OC50ZXN0MAuCCXgzNTkudGVzdDAL\nggl4MzYwLnRlc3QwC4IJeDM2MS50ZXN0MAuCCXgzNjIudGVzdDALggl4MzYzLnRl\nc3QwC4IJeDM2NC50ZXN0MAuCCXgzNjUudGVzdDALggl4MzY2LnRlc3QwC4IJeDM2\nNy50ZXN0MAuCCXgzNjgudGVzdDALggl4MzY5LnRlc3QwC4IJeDM3MC50ZXN0MAuC\nCXgzNzEudGVzdDALggl4MzcyLnRlc3QwC4IJeDM3My50ZXN0MAuCCXgzNzQudGVz\ndDALggl4Mzc1LnRlc3QwC4IJeDM3Ni50ZXN0MAuCCXgzNzcudGVzdDALggl4Mzc4\nLnRlc3QwC4IJeDM3OS50ZXN0MAuCCXgzODAudGVzdDALggl4MzgxLnRlc3QwC4IJ\neDM4Mi50ZXN0MAuCCXgzODMudGVzdDALggl4Mzg0LnRlc3QwC4IJeDM4NS50ZXN0\nMAuCCXgzODYudGVzdDALggl4Mzg3LnRlc3QwC4IJeDM4OC50ZXN0MAuCCXgzODku\ndGVzdDALggl4MzkwLnRlc3QwC4IJeDM5MS50ZXN0MAuCCXgzOTIudGVzdDALggl4\nMzkzLnRlc3QwC4IJeDM5NC50ZXN0MAuCCXgzOTUud", "GVzdDALggl4Mzk2LnRlc3Qw\nC4IJeDM5Ny50ZXN0MAuCCXgzOTgudGVzdDALggl4Mzk5LnRlc3QwC4IJeDQwMC50\nZXN0MAuCCXg0MDEudGVzdDALggl4NDAyLnRlc3QwC4IJeDQwMy50ZXN0MAuCCXg0\nMDQudGVzdDALggl4NDA1LnRlc3QwC4IJeDQwNi50ZXN0MAuCCXg0MDcudGVzdDAL\nggl4NDA4LnRlc3QwC4IJeDQwOS50ZXN0MAuCCXg0MTAudGVzdDALggl4NDExLnRl\nc3QwC4IJeDQxMi50ZXN0MAuCCXg0MTMudGVzdDALggl4NDE0LnRlc3QwC4IJeDQx\nNS50ZXN0MAuCCXg0MTYudGVzdDALggl4NDE3LnRlc3QwC4IJeDQxOC50ZXN0MAuC\nCXg0MTkudGVzdDALggl4NDIwLnRlc3QwC4IJeDQyMS50ZXN0MAuCCXg0MjIudGVz\ndDALggl4NDIzLnRlc3QwC4IJeDQyNC50ZXN0MAuCCXg0MjUudGVzdDALggl4NDI2\nLnRlc3QwC4IJeDQyNy50ZXN0MAuCCXg0MjgudGVzdDALggl4NDI5LnRlc3QwC4IJ\neDQzMC50ZXN0MAuCCXg0MzEudGVzdDALggl4NDMyLnRlc3QwC4IJeDQzMy50ZXN0\nMAuCCXg0MzQudGVzdDALggl4NDM1LnRlc3QwC4IJeDQzNi50ZXN0MAuCCXg0Mzcu\ndGVzdDALggl4NDM4LnRlc3QwC4IJeDQzOS50ZXN0MAuCCXg0NDAudGVzdDALggl4\nNDQxLnRlc3QwC4IJeDQ0Mi50ZXN0MAuCCXg0NDMudGVzdDALggl4NDQ0LnRlc3Qw\nC4IJeDQ0NS50ZXN0MAuCCXg0NDYudGVzdDALggl4NDQ3LnRlc3QwC4IJeDQ0OC50\nZXN0MAuCCXg0NDkudGVzdDALggl4NDUwLnRlc3QwC4IJeDQ1MS50ZXN0MAuCCXg0\nNTIudGVzdDALggl4NDUzLnRlc3QwC4IJeDQ1NC50ZXN0MAuCCXg0NTUudGVzdDAL\nggl4NDU2LnRlc3QwC4IJeDQ1Ny50ZXN0MAuCCXg0NTgudGVzdDALggl4NDU5LnRl\nc3QwC4IJeDQ2MC50ZXN0MAuCCXg0NjEudGVzdDALggl4NDYyLnRlc3QwC4IJeDQ2\nMy50ZXN0MAuCCXg0NjQudGVzdDALggl4NDY1LnRlc3QwC4IJeDQ2Ni50ZXN0MAuC\nCXg0NjcudGVzdDALggl4NDY4LnRlc3QwC4IJeDQ2OS50ZXN0MAuCCXg0NzAudGVz\ndDALggl4NDcxLnRlc3QwC4IJeDQ3Mi50ZXN0MAuCCXg0NzMudGVzdDALggl4NDc0\nLnRlc3QwC4IJeDQ3NS50ZXN0MAuCCXg0NzYudGVzdDALggl4NDc3LnRlc3QwC4IJ\neDQ3OC50ZXN0MAuCCXg0NzkudGVzdDALggl4NDgwLnRlc3QwC4IJeDQ4MS50ZXN0\nMAuCCXg0ODIudGVzdDALggl4NDgzLnRlc3QwC4IJeDQ4NC50ZXN0MAuCCXg0ODUu\ndGVzdDALggl4NDg2LnRlc3QwC4IJeDQ4Ny50ZXN0MAuCCXg0ODgudGVzdDALggl4\nNDg5LnRlc3QwC4IJeDQ5MC50ZXN0MAuCCXg0OTEudGVzdDALggl4NDkyLnRlc3Qw\nC4IJeDQ5My50ZXN0MAuCCXg0OTQudGVzdDALggl4NDk1LnRlc3QwC4IJeDQ5Ni50\nZXN0MAuCCXg0OTcudGVzdDALggl4NDk4LnRlc3QwC4IJeDQ5OS50ZXN0MAuCCXg1\nMDAudGVzdDALggl4NTAxLnRlc3QwC4IJeDUwMi50ZXN0MAuCCXg1MDMudGVzdDAL\nggl4NTA0LnRlc3QwC4IJeDUwNS50ZXN0MAuCCXg1MDYudGVzdDALggl4NTA3LnRl\nc3QwC4IJeDUwOC50ZXN0MAuCCXg1MDkudGVzdDALggl4NTEwLnRlc3QwC4IJeDUx\nMS50ZXN0MAuCCXg1MTIudGVzdDANBgkqhkiG9w0BAQsFAAOCAQEAL2zj4W3+BzBa\nUA0pBD3K5mXq5H94uVT3YFiS1Yrrv1aGJjnb9iabNjdPNRFq7eBm1OajFTv8UtE/\nWJR0JDvBTs7yvpOgTy+JY9RY8NP72gdOOvpZ3DbJ0bbSUFqBVQlM8771Mz9RVQX9\ni9oCqVkakKI/9guAU2XHx9ztTB6N3mULB3QkeFmlyrqeeVK/2lFErArRxyKQXjxb\ncfD76JGADWpp6p1/QUGYmPNYGxHMtWzAhzX1zs/OdGwVVX7g6xxfFdOw0z2PVSPL\notKS5E3GWvqe43Edz3D6AI7jp6ibtH32HX/D4lLLd9nSiQURvJJ0nrMYZI+7p1DE\n6BsnsA2jNg==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen92 = 26473; +static const size_t kLen104 = 26473; -static const char *kData92[] = { +static const char *kData104[] = { "-----BEGIN CERTIFICATE-----\nMIJMMTCCSxmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowgjO+MRAwDgYDVQQDEwd0\nMC50ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nMUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nM0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nNUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nN0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0OEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nOUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTBAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDExQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxMkB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0MTNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDE0QHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQxNUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTZAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDE3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxOEB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0MTlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDIwQHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQyMUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjJAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDIzQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQyNEB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0MjVAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDI2QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQyN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjhAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDI5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzMEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDMy\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzM0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nMzRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDM1QHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQzNkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzdAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDM4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzOUB0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0NDBAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQxQHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ0MkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDNAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDQ0QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ0NUB0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0NDZAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQ3QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ0OEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDlAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDUwQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1MUB0ZXN0\nMRcwFQYJKoZIhvcNAQkBFgh0NTJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDUzQHRl\nc3QxFzAVBgkqhkiG9w0BCQEWCHQ1NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NTVA\ndGVzdDEXMBUGCSqGSIb3DQEJARYIdDU2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1\nN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NThAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDU5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2MEB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0NjFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDYyQHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQ2M0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NjRAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDY1QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2NkB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0NjdAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDY4QHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQ2OUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzBAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDcxQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3MkB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0NzNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDc0QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQ3NUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzZAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDc3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3OEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgw\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4MUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nODJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgzQHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQ4NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0ODVAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDg2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4N0B0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0ODhAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDg5QHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ5MEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTFAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDkyQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5M0B0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0OTRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDk1QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ5NkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTdAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDk4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTAwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTAzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEwNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTA2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTA5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDExMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTEyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEx\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTE1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxMTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDExN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTE4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDEyMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTIxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxMjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTI0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTI3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEyOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTMwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEzMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTMzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDEzNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEz\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTQyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE0NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTQ1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTQ4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTUxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE1M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTU0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTU3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE1OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTY2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE2OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTY5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTcyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTc1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE3N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTc4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTgxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxODJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE4M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxODVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxODhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTkwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE5MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTkzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxOTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTk2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTk5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIwMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjAyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIwNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjA1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIwN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjA4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIx\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjExQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjE0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDIxNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjE3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyMThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjIwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjIzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIyNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjI2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjI5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIzMUB0ZXN0MRgwFgY", "JKoZIhvcNAQkBFgl0MjMyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIz\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjM1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIzN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjM4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI0MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjQxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjQ0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI0OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjUwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjUzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI1NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyNjBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjYyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI2NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjY1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNjZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjY4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjcxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI3M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjc0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNzVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mjc3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzhAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI3OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyODFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyODRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0Mjg2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyODdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI4OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjg5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyOTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjkyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjk1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI5N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjk4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyOTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzAxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMwM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMw\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMDhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzEwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMxMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzEzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzE2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzE5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDMyMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzIyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzMjNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMyNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzI1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMyN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzI4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMz\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzMxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMzJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzM0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMzVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMzNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzM3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMzhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzQwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzQzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM0NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzQ2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzQ5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM1MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzUyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzU1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzNTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzU4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM2MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzYxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzNjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzY0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzY3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM2OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzcwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzczQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM3NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzODBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzgyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM4NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzg1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzODZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0Mzg4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzkxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM5M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzk0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzOTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mzk3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM5OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQw\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MDRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQwNUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDA2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQwOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDA5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxMUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDEyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDE1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQxN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDE4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0MTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDIxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQyM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQy\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MjhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDMwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQzMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDMzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MzRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDM2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDM5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ0MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ0NEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDQ1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ0N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQ4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDUxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1M0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDU0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ1NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDU3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0NThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDYwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDYzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjRAd", "GVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ2NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDY2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDY5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ3MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDcyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDc1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDc4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ4MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDgxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0ODJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDg0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDg3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ4OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDkwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0OTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDkzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ5NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1MDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwMUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTAyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDUwNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTA1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1MDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwN0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTA4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDUxMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTExQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MTJAdGVzdDCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmK\nM+EKbcMue/hFrLGQXB6a2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4o\nBEiEhBxIsaIlws3qQa4baeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0\nvIqPfad5amdQJMvmjZXDI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+\ndFPM2/5kc2HiLNkeuS1Hbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3F\nMSaDK9T0zoJ5hE9fViR+D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAAaOCFeUwghXh\nMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8E\nAjAAMIIVqgYDVR0RBIIVoTCCFZ2CB3QwLnRlc3SCB3QxLnRlc3SCB3QyLnRlc3SC\nB3QzLnRlc3SCB3Q0LnRlc3SCB3Q1LnRlc3SCB3Q2LnRlc3SCB3Q3LnRlc3SCB3Q4\nLnRlc3SCB3Q5LnRlc3SCCHQxMC50ZXN0ggh0MTEudGVzdIIIdDEyLnRlc3SCCHQx\nMy50ZXN0ggh0MTQudGVzdIIIdDE1LnRlc3SCCHQxNi50ZXN0ggh0MTcudGVzdIII\ndDE4LnRlc3SCCHQxOS50ZXN0ggh0MjAudGVzdIIIdDIxLnRlc3SCCHQyMi50ZXN0\nggh0MjMudGVzdIIIdDI0LnRlc3SCCHQyNS50ZXN0ggh0MjYudGVzdIIIdDI3LnRl\nc3SCCHQyOC50ZXN0ggh0MjkudGVzdIIIdDMwLnRlc3SCCHQzMS50ZXN0ggh0MzIu\ndGVzdIIIdDMzLnRlc3SCCHQzNC50ZXN0ggh0MzUudGVzdIIIdDM2LnRlc3SCCHQz\nNy50ZXN0ggh0MzgudGVzdIIIdDM5LnRlc3SCCHQ0MC50ZXN0ggh0NDEudGVzdIII\ndDQyLnRlc3SCCHQ0My50ZXN0ggh0NDQudGVzdIIIdDQ1LnRlc3SCCHQ0Ni50ZXN0\nggh0NDcudGVzdIIIdDQ4LnRlc3SCCHQ0OS50ZXN0ggh0NTAudGVzdIIIdDUxLnRl\nc3SCCHQ1Mi50ZXN0ggh0NTMudGVzdIIIdDU0LnRlc3SCCHQ1NS50ZXN0ggh0NTYu\ndGVzdIIIdDU3LnRlc3SCCHQ1OC50ZXN0ggh0NTkudGVzdIIIdDYwLnRlc3SCCHQ2\nMS50ZXN0ggh0NjIudGVzdIIIdDYzLnRlc3SCCHQ2NC50ZXN0ggh0NjUudGVzdIII\ndDY2LnRlc3SCCHQ2Ny50ZXN0ggh0NjgudGVzdIIIdDY5LnRlc3SCCHQ3MC50ZXN0\nggh0NzEudGVzdIIIdDcyLnRlc3SCCHQ3My50ZXN0ggh0NzQudGVzdIIIdDc1LnRl\nc3SCCHQ3Ni50ZXN0ggh0NzcudGVzdIIIdDc4LnRlc3SCCHQ3OS50ZXN0ggh0ODAu\ndGVzdIIIdDgxLnRlc3SCCHQ4Mi50ZXN0ggh0ODMudGVzdIIIdDg0LnRlc3SCCHQ4\nNS50ZXN0ggh0ODYudGVzdIIIdDg3LnRlc3SCCHQ4OC50ZXN0ggh0ODkudGVzdIII\ndDkwLnRlc3SCCHQ5MS50ZXN0ggh0OTIudGVzdIIIdDkzLnRlc3SCCHQ5NC50ZXN0\nggh0OTUudGVzdIIIdDk2LnRlc3SCCHQ5Ny50ZXN0ggh0OTgudGVzdIIIdDk5LnRl\nc3SCCXQxMDAudGVzdIIJdDEwMS50ZXN0ggl0MTAyLnRlc3SCCXQxMDMudGVzdIIJ\ndDEwNC50ZXN0ggl0MTA1LnRlc3SCCXQxMDYudGVzdIIJdDEwNy50ZXN0ggl0MTA4\nLnRlc3SCCXQxMDkudGVzdIIJdDExMC50ZXN0ggl0MTExLnRlc3SCCXQxMTIudGVz\ndIIJdDExMy50ZXN0ggl0MTE0LnRlc3SCCXQxMTUudGVzdIIJdDExNi50ZXN0ggl0\nMTE3LnRlc3SCCXQxMTgudGVzdIIJdDExOS50ZXN0ggl0MTIwLnRlc3SCCXQxMjEu\ndGVzdIIJdDEyMi50ZXN0ggl0MTIzLnRlc3SCCXQxMjQudGVzdIIJdDEyNS50ZXN0\nggl0MTI2LnRlc3SCCXQxMjcudGVzdIIJdDEyOC50ZXN0ggl0MTI5LnRlc3SCCXQx\nMzAudGVzdIIJdDEzMS50ZXN0ggl0MTMyLnRlc3SCCXQxMzMudGVzdIIJdDEzNC50\nZXN0ggl0MTM1LnRlc3SCCXQxMzYudGVzdIIJdDEzNy50ZXN0ggl0MTM4LnRlc3SC\nCXQxMzkudGVzdIIJdDE0MC50ZXN0ggl0MTQxLnRlc3SCCXQxNDIudGVzdIIJdDE0\nMy50ZXN0ggl0MTQ0LnRlc3SCCXQxNDUudGVzdIIJdDE0Ni50ZXN0ggl0MTQ3LnRl\nc3SCCXQxNDgudGVzdIIJdDE0OS50ZXN0ggl0MTUwLnRlc3SCCXQxNTEudGVzdIIJ\ndDE1Mi50ZXN0ggl0MTUzLnRlc3SCCXQxNTQudGVzdIIJdDE1NS50ZXN0ggl0MTU2\nLnRlc3SCCXQxNTcudGVzdIIJdDE1OC50ZXN0ggl0MTU5LnRlc3SCCXQxNjAudGVz\ndIIJdDE2MS50ZXN0ggl0MTYyLnRlc3SCCXQxNjMudGVzdIIJdDE2NC50ZXN0ggl0\nMTY1LnRlc3SCCXQxNjYudGVzdIIJdDE2Ny50ZXN0ggl0MTY4LnRlc3SCCXQxNjku\ndGVzdIIJdDE3MC50ZXN0ggl0MTcxLnRlc3SCCXQxNzIudGVzdIIJdDE3My50ZXN0\nggl0MTc0LnRlc3SCCXQxNzUudGVzdIIJdDE3Ni50ZXN0ggl0MTc3LnRlc3SCCXQx\nNzgudGVzdIIJdDE3OS50ZXN0ggl0MTgwLnRlc3SCCXQxODEudGVzdIIJdDE4Mi50\nZXN0ggl0MTgzLnRlc3SCCXQxODQudGVzdIIJdDE4NS50ZXN0ggl0MTg2LnRlc3SC\nCXQxODcudGVzdIIJdDE4OC50ZXN0ggl0MTg5LnRlc3SCCXQxOTAudGVzdIIJdDE5\nMS50ZXN0ggl0MTkyLnRlc3SCCXQxOTMudGVzdIIJdDE5NC50ZXN0ggl0MTk1LnRl\nc3SCCXQxOTYudGVzdIIJdDE5Ny50ZXN0ggl0MTk4LnRlc3SCCXQxOTkudGVzdIIJ\ndDIwMC50ZXN0ggl0MjAxLnRlc3SCCXQyMDIudGVzdIIJdDIwMy50ZXN0ggl0MjA0\nLnRlc3SCCXQyMDUudGVzdIIJdDIwNi50ZXN0ggl0MjA3LnRlc3SCCXQyMDgudGVz\ndIIJdDIwOS50ZXN0ggl0MjEwLnRlc3SCCXQyMTEudGVzdIIJdDIxMi50ZXN0ggl0\nMjEzLnRlc3SCCXQyMTQudGVzdIIJdDIxNS50ZXN0ggl0MjE2LnRlc3SCCXQyMTcu\ndGVzdIIJdDIxOC50ZXN0ggl0MjE5LnRlc3SCCXQyMjAudGVzdIIJdDIyMS50ZXN0\nggl0MjIyLnRlc3SCCXQyMjMudGVzdIIJdDIyNC50ZXN0ggl0MjI1LnRlc3SCCXQy\nMjYudGVzdIIJdDIyNy50ZXN0ggl0MjI4LnRlc3SCCXQyMjkudGVzdIIJdDIzMC50\nZXN0ggl0MjMxLnRlc3SCCXQyMzIudGVzdIIJdDIzMy50ZXN0ggl0MjM0LnRlc3SC\nCXQyMzUudGVzdIIJdDIzNi50ZXN0ggl0MjM3LnRlc3SCCXQyMzgudGVzdIIJdDIz\nOS50ZXN0ggl0MjQwLnRlc3SCCXQyNDEudGVzdIIJdDI0Mi50ZXN0ggl0MjQzLnRl\nc3SCCXQyNDQudGVzdIIJdDI0NS50ZXN0ggl0MjQ2LnRlc3SCCXQyNDcudGVzdIIJ\ndDI0OC50ZXN0ggl0MjQ5LnRlc3SCCXQyNTAudGVzdIIJdDI1MS50ZXN0ggl0MjUy\nLnRlc3SCCXQyNTMudGVzdIIJdDI1NC50ZXN0ggl0MjU1LnRlc3SCCXQyNTYudGVz\ndIIJdDI1Ny50ZXN0ggl0MjU4LnRlc3SCCXQyNTkudGVzdIIJdDI2MC50ZXN0ggl0\nMjYxLnRlc3SCCXQyNjIudGVzdIIJdDI2My50ZXN0ggl0MjY0LnRlc3SCCXQyNjUu\ndGVzdIIJdDI2Ni50ZXN0ggl0MjY3LnRlc3SCCXQyNjgudGVzdIIJdDI2OS50ZXN0\nggl0MjcwLnRlc3SCCXQyNzEudGVzdIIJdDI3Mi50ZXN0ggl0MjczLnRlc3SCCXQy\nNzQudGVzdIIJdDI3NS50ZXN0ggl0Mjc2LnRlc3SCCXQyNzcudGVzdIIJdDI3OC50\nZXN0ggl0Mjc5LnRlc3SCCXQyODAudGVzdIIJdDI4MS50ZXN0ggl0MjgyLnRlc3SC\nCXQyODMudGVzdIIJdDI4NC50ZXN0ggl0Mjg1LnRlc3SCCXQyODYudGVzdIIJdDI4\nNy50ZXN0ggl0Mjg4LnRlc3SCCXQyODkudGVzdIIJdDI5MC50ZXN0ggl0MjkxLnRl\nc3SCCXQyOTIudGVzdIIJdDI5My50ZXN0ggl0Mjk0LnRlc3SCCXQyOTUudGVzdIIJ\ndDI5Ni50ZXN0ggl0Mjk3LnRlc3SCCXQyOTgudGVzdIIJdDI5OS50ZXN0ggl0MzAw\nLnRlc3SCCXQzMDEudGVzdIIJdDMwMi50ZXN0ggl0MzAzLnRlc3SCCXQzMDQudGVz\ndIIJdDMwNS50ZXN0ggl0MzA2LnRlc3SCCXQzMDcudGVzdIIJdDMwOC50ZXN0ggl0\nMzA5LnRlc3SCCXQzMTAudGVzdIIJdDMxMS50ZXN0ggl0MzEyLnRlc3SCCXQzMTMu\ndGVzdIIJdDMxNC50ZXN0ggl0MzE1LnRlc3SCCXQzMTYudGVzdIIJdDMxNy50ZXN0\nggl0MzE4LnRlc3SCCXQzMTkudGVzdIIJdDMyMC50ZXN0ggl0MzIxLnRlc3SCCXQz\nMjIudGVzdIIJdDMyMy50ZXN0ggl0MzI0LnRlc3SCCXQzMjUudGVzdIIJdDMyNi50\nZXN0ggl0MzI3LnRlc3SCCXQzMjgudGVzdIIJdDMyOS50ZXN0ggl0MzMwLnRlc3SC\nCXQzMzEudGVzdIIJdDMzMi50ZXN0ggl0MzMzLnRlc3SCCXQzMzQudGVzdIIJdDMz\nNS50ZXN0ggl0MzM2LnRlc3SCCXQzMzcudGVzdIIJdDMzOC50ZXN0ggl0MzM5LnRl\nc3SCCXQzNDAudGVzdIIJdDM0MS50ZXN0ggl0MzQyLnRlc3SCCXQzNDMudGVzdIIJ\ndDM0NC50ZXN0ggl0MzQ1LnRlc3SCCXQzNDYudGVzdIIJdDM0Ny50ZXN0ggl0MzQ4\nLnRlc3SCCXQzNDkudGVzdIIJdDM1MC50ZXN0ggl0MzUxLnRlc3SCCXQzNTIudGVz\ndIIJdDM1My50ZXN0ggl0MzU0LnRlc3SCCXQzNTUudGVzdIIJdDM1Ni50ZXN0ggl0\nMzU3LnRlc3SCCXQzNTgudGVzdIIJdDM1OS50ZXN0ggl0MzYwLnRlc3SCCXQzNjEu\ndGVzdIIJdDM2Mi50ZXN0ggl0MzYzLnRlc3SCCXQzNjQudGVzdIIJdDM2NS50ZXN0\nggl0MzY2LnRlc3SCCXQzNjcudGVzdIIJdDM2OC50ZXN0ggl0MzY5LnRlc3SCCXQz\nNzAudGVzdIIJdDM3MS50ZXN0ggl0MzcyLnRlc3SCCXQzNzMudGVzdIIJdDM3NC50\nZXN0ggl0Mzc1LnRlc3SCCXQzNzYudGVzdIIJdDM3Ny50ZXN0ggl0Mzc4LnRlc3SC\nCXQzNzkudGVzdIIJdDM4MC50ZXN0ggl0MzgxLnRlc3SCCXQzODIudGVzdIIJdDM4\nMy50ZXN0ggl0Mzg0LnRlc3SCCXQzODUudGVzdIIJdDM4Ni50ZXN0ggl0Mzg3LnRl\nc3SCCXQzODgudGVzdIIJdDM4OS50ZXN0ggl0MzkwLnRlc3SCCXQzOTEudGVzdIIJ\ndDM5Mi50ZXN0ggl0MzkzLnRlc3SCCXQzOTQudGVzdIIJdDM5NS50ZXN0ggl0Mzk2\nLnRlc3SCCXQzOTcudGVzdIIJdDM5OC50ZXN0ggl0Mzk5LnRlc3SCCXQ0MDAudGVz\ndIIJdDQwMS50ZXN0ggl0NDAyLnRlc3SCCXQ0MDMudGVzdIIJdDQwNC50ZXN0ggl0\nNDA1LnRlc3SCCXQ0MDYudGVzdIIJdDQwNy50ZXN0ggl0NDA4LnRlc3SCCXQ0MDku\ndGVzdIIJdDQxMC50ZXN0ggl0NDExLnRlc3SCCXQ0MTI", "udGVzdIIJdDQxMy50ZXN0\nggl0NDE0LnRlc3SCCXQ0MTUudGVzdIIJdDQxNi50ZXN0ggl0NDE3LnRlc3SCCXQ0\nMTgudGVzdIIJdDQxOS50ZXN0ggl0NDIwLnRlc3SCCXQ0MjEudGVzdIIJdDQyMi50\nZXN0ggl0NDIzLnRlc3SCCXQ0MjQudGVzdIIJdDQyNS50ZXN0ggl0NDI2LnRlc3SC\nCXQ0MjcudGVzdIIJdDQyOC50ZXN0ggl0NDI5LnRlc3SCCXQ0MzAudGVzdIIJdDQz\nMS50ZXN0ggl0NDMyLnRlc3SCCXQ0MzMudGVzdIIJdDQzNC50ZXN0ggl0NDM1LnRl\nc3SCCXQ0MzYudGVzdIIJdDQzNy50ZXN0ggl0NDM4LnRlc3SCCXQ0MzkudGVzdIIJ\ndDQ0MC50ZXN0ggl0NDQxLnRlc3SCCXQ0NDIudGVzdIIJdDQ0My50ZXN0ggl0NDQ0\nLnRlc3SCCXQ0NDUudGVzdIIJdDQ0Ni50ZXN0ggl0NDQ3LnRlc3SCCXQ0NDgudGVz\ndIIJdDQ0OS50ZXN0ggl0NDUwLnRlc3SCCXQ0NTEudGVzdIIJdDQ1Mi50ZXN0ggl0\nNDUzLnRlc3SCCXQ0NTQudGVzdIIJdDQ1NS50ZXN0ggl0NDU2LnRlc3SCCXQ0NTcu\ndGVzdIIJdDQ1OC50ZXN0ggl0NDU5LnRlc3SCCXQ0NjAudGVzdIIJdDQ2MS50ZXN0\nggl0NDYyLnRlc3SCCXQ0NjMudGVzdIIJdDQ2NC50ZXN0ggl0NDY1LnRlc3SCCXQ0\nNjYudGVzdIIJdDQ2Ny50ZXN0ggl0NDY4LnRlc3SCCXQ0NjkudGVzdIIJdDQ3MC50\nZXN0ggl0NDcxLnRlc3SCCXQ0NzIudGVzdIIJdDQ3My50ZXN0ggl0NDc0LnRlc3SC\nCXQ0NzUudGVzdIIJdDQ3Ni50ZXN0ggl0NDc3LnRlc3SCCXQ0NzgudGVzdIIJdDQ3\nOS50ZXN0ggl0NDgwLnRlc3SCCXQ0ODEudGVzdIIJdDQ4Mi50ZXN0ggl0NDgzLnRl\nc3SCCXQ0ODQudGVzdIIJdDQ4NS50ZXN0ggl0NDg2LnRlc3SCCXQ0ODcudGVzdIIJ\ndDQ4OC50ZXN0ggl0NDg5LnRlc3SCCXQ0OTAudGVzdIIJdDQ5MS50ZXN0ggl0NDky\nLnRlc3SCCXQ0OTMudGVzdIIJdDQ5NC50ZXN0ggl0NDk1LnRlc3SCCXQ0OTYudGVz\ndIIJdDQ5Ny50ZXN0ggl0NDk4LnRlc3SCCXQ0OTkudGVzdIIJdDUwMC50ZXN0ggl0\nNTAxLnRlc3SCCXQ1MDIudGVzdIIJdDUwMy50ZXN0ggl0NTA0LnRlc3SCCXQ1MDUu\ndGVzdIIJdDUwNi50ZXN0ggl0NTA3LnRlc3SCCXQ1MDgudGVzdIIJdDUwOS50ZXN0\nggl0NTEwLnRlc3SCCXQ1MTEudGVzdIIJdDUxMi50ZXN0MA0GCSqGSIb3DQEBCwUA\nA4IBAQCp6JcB0NWRQJSgjsI0ycv1gpuoo2k/NjPlkYCcsLwmTPRVdpBHi9MJNS2i\nMKPk7Wek2y9wJw6QPq9fMi/XSmEqRcFC8uBZ9evyTwmVbzzRsEN3qGHCrVdOnVLa\nD7x7NjoTLApVNelYTxMPEennTd9+we8cl0T2TqosTnbxyvP+pnwtpazjDAFKlt8e\nJpLRlRtWR/aScZ+P8CGj4b3prp12NJIAPG9W2ZqiHNLNMhTQG4Bz+O5+zMnIbC+e\nAhc4co+A/7qzselNZL1pcFFyRtTeLAcREuZVTTRa/EXmlLqzMe+UEEinEtdktnPL\nKO0ED3qPXggpBbFaa4/PVubBS4QU\n-----END CERTIFICATE-----\n", }; -static const size_t kLen93 = 16219; +static const size_t kLen105 = 16219; -static const char *kData93[] = { +static const char *kData105[] = { "-----BEGIN CERTIFICATE-----\nMIIunDCCLYSgAwIBAgIBAzANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowEjEQMA4GA1UEAxMHdDAu\ndGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoL2oQZEgFBdXwu\nPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a2eQZFn+j3hmexeQF9T8i\nWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4baeVEEoxw+A+ISrYHTIFc\nV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXDI+jGMvFPmBRHr2/1dJUW\nPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1Hbky+dPlDIGrfaHHsCNnb\n/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+D6xcJO2RNUCUENS+Iipj\n3kIrLbkCAwEAAaOCK/4wgiv6MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr\nBgEFBQcDATAMBgNVHRMBAf8EAjAAMIIrwwYDVR0RBIIrujCCK7aCB3QwLnRlc3SC\nB3QxLnRlc3SCB3QyLnRlc3SCB3QzLnRlc3SCB3Q0LnRlc3SCB3Q1LnRlc3SCB3Q2\nLnRlc3SCB3Q3LnRlc3SCB3Q4LnRlc3SCB3Q5LnRlc3SCCHQxMC50ZXN0ggh0MTEu\ndGVzdIIIdDEyLnRlc3SCCHQxMy50ZXN0ggh0MTQudGVzdIIIdDE1LnRlc3SCCHQx\nNi50ZXN0ggh0MTcudGVzdIIIdDE4LnRlc3SCCHQxOS50ZXN0ggh0MjAudGVzdIII\ndDIxLnRlc3SCCHQyMi50ZXN0ggh0MjMudGVzdIIIdDI0LnRlc3SCCHQyNS50ZXN0\nggh0MjYudGVzdIIIdDI3LnRlc3SCCHQyOC50ZXN0ggh0MjkudGVzdIIIdDMwLnRl\nc3SCCHQzMS50ZXN0ggh0MzIudGVzdIIIdDMzLnRlc3SCCHQzNC50ZXN0ggh0MzUu\ndGVzdIIIdDM2LnRlc3SCCHQzNy50ZXN0ggh0MzgudGVzdIIIdDM5LnRlc3SCCHQ0\nMC50ZXN0ggh0NDEudGVzdIIIdDQyLnRlc3SCCHQ0My50ZXN0ggh0NDQudGVzdIII\ndDQ1LnRlc3SCCHQ0Ni50ZXN0ggh0NDcudGVzdIIIdDQ4LnRlc3SCCHQ0OS50ZXN0\nggh0NTAudGVzdIIIdDUxLnRlc3SCCHQ1Mi50ZXN0ggh0NTMudGVzdIIIdDU0LnRl\nc3SCCHQ1NS50ZXN0ggh0NTYudGVzdIIIdDU3LnRlc3SCCHQ1OC50ZXN0ggh0NTku\ndGVzdIIIdDYwLnRlc3SCCHQ2MS50ZXN0ggh0NjIudGVzdIIIdDYzLnRlc3SCCHQ2\nNC50ZXN0ggh0NjUudGVzdIIIdDY2LnRlc3SCCHQ2Ny50ZXN0ggh0NjgudGVzdIII\ndDY5LnRlc3SCCHQ3MC50ZXN0ggh0NzEudGVzdIIIdDcyLnRlc3SCCHQ3My50ZXN0\nggh0NzQudGVzdIIIdDc1LnRlc3SCCHQ3Ni50ZXN0ggh0NzcudGVzdIIIdDc4LnRl\nc3SCCHQ3OS50ZXN0ggh0ODAudGVzdIIIdDgxLnRlc3SCCHQ4Mi50ZXN0ggh0ODMu\ndGVzdIIIdDg0LnRlc3SCCHQ4NS50ZXN0ggh0ODYudGVzdIIIdDg3LnRlc3SCCHQ4\nOC50ZXN0ggh0ODkudGVzdIIIdDkwLnRlc3SCCHQ5MS50ZXN0ggh0OTIudGVzdIII\ndDkzLnRlc3SCCHQ5NC50ZXN0ggh0OTUudGVzdIIIdDk2LnRlc3SCCHQ5Ny50ZXN0\nggh0OTgudGVzdIIIdDk5LnRlc3SCCXQxMDAudGVzdIIJdDEwMS50ZXN0ggl0MTAy\nLnRlc3SCCXQxMDMudGVzdIIJdDEwNC50ZXN0ggl0MTA1LnRlc3SCCXQxMDYudGVz\ndIIJdDEwNy50ZXN0ggl0MTA4LnRlc3SCCXQxMDkudGVzdIIJdDExMC50ZXN0ggl0\nMTExLnRlc3SCCXQxMTIudGVzdIIJdDExMy50ZXN0ggl0MTE0LnRlc3SCCXQxMTUu\ndGVzdIIJdDExNi50ZXN0ggl0MTE3LnRlc3SCCXQxMTgudGVzdIIJdDExOS50ZXN0\nggl0MTIwLnRlc3SCCXQxMjEudGVzdIIJdDEyMi50ZXN0ggl0MTIzLnRlc3SCCXQx\nMjQudGVzdIIJdDEyNS50ZXN0ggl0MTI2LnRlc3SCCXQxMjcudGVzdIIJdDEyOC50\nZXN0ggl0MTI5LnRlc3SCCXQxMzAudGVzdIIJdDEzMS50ZXN0ggl0MTMyLnRlc3SC\nCXQxMzMudGVzdIIJdDEzNC50ZXN0ggl0MTM1LnRlc3SCCXQxMzYudGVzdIIJdDEz\nNy50ZXN0ggl0MTM4LnRlc3SCCXQxMzkudGVzdIIJdDE0MC50ZXN0ggl0MTQxLnRl\nc3SCCXQxNDIudGVzdIIJdDE0My50ZXN0ggl0MTQ0LnRlc3SCCXQxNDUudGVzdIIJ\ndDE0Ni50ZXN0ggl0MTQ3LnRlc3SCCXQxNDgudGVzdIIJdDE0OS50ZXN0ggl0MTUw\nLnRlc3SCCXQxNTEudGVzdIIJdDE1Mi50ZXN0ggl0MTUzLnRlc3SCCXQxNTQudGVz\ndIIJdDE1NS50ZXN0ggl0MTU2LnRlc3SCCXQxNTcudGVzdIIJdDE1OC50ZXN0ggl0\nMTU5LnRlc3SCCXQxNjAudGVzdIIJdDE2MS50ZXN0ggl0MTYyLnRlc3SCCXQxNjMu\ndGVzdIIJdDE2NC50ZXN0ggl0MTY1LnRlc3SCCXQxNjYudGVzdIIJdDE2Ny50ZXN0\nggl0MTY4LnRlc3SCCXQxNjkudGVzdIIJdDE3MC50ZXN0ggl0MTcxLnRlc3SCCXQx\nNzIudGVzdIIJdDE3My50ZXN0ggl0MTc0LnRlc3SCCXQxNzUudGVzdIIJdDE3Ni50\nZXN0ggl0MTc3LnRlc3SCCXQxNzgudGVzdIIJdDE3OS50ZXN0ggl0MTgwLnRlc3SC\nCXQxODEudGVzdIIJdDE4Mi50ZXN0ggl0MTgzLnRlc3SCCXQxODQudGVzdIIJdDE4\nNS50ZXN0ggl0MTg2LnRlc3SCCXQxODcudGVzdIIJdDE4OC50ZXN0ggl0MTg5LnRl\nc3SCCXQxOTAudGVzdIIJdDE5MS50ZXN0ggl0MTkyLnRlc3SCCXQxOTMudGVzdIIJ\ndDE5NC50ZXN0ggl0MTk1LnRlc3SCCXQxOTYudGVzdIIJdDE5Ny50ZXN0ggl0MTk4\nLnRlc3SCCXQxOTkudGVzdIIJdDIwMC50ZXN0ggl0MjAxLnRlc3SCCXQyMDIudGVz\ndIIJdDIwMy50ZXN0ggl0MjA0LnRlc3SCCXQyMDUudGVzdIIJdDIwNi50ZXN0ggl0\nMjA3LnRlc3SCCXQyMDgudGVzdIIJdDIwOS50ZXN0ggl0MjEwLnRlc3SCCXQyMTEu\ndGVzdIIJdDIxMi50ZXN0ggl0MjEzLnRlc3SCCXQyMTQudGVzdIIJdDIxNS50ZXN0\nggl0MjE2LnRlc3SCCXQyMTcudGVzdIIJdDIxOC50ZXN0ggl0MjE5LnRlc3SCCXQy\nMjAudGVzdIIJdDIyMS50ZXN0ggl0MjIyLnRlc3SCCXQyMjMudGVzdIIJdDIyNC50\nZXN0ggl0MjI1LnRlc3SCCXQyMjYudGVzdIIJdDIyNy50ZXN0ggl0MjI4LnRlc3SC\nCXQyMjkudGVzdIIJdDIzMC50ZXN0ggl0MjMxLnRlc3SCCXQyMzIudGVzdIIJdDIz\nMy50ZXN0ggl0MjM0LnRlc3SCCXQyMzUudGVzdIIJdDIzNi50ZXN0ggl0MjM3LnRl\nc3SCCXQyMzgudGVzdIIJdDIzOS50ZXN0ggl0MjQwLnRlc3SCCXQyNDEudGVzdIIJ\ndDI0Mi50ZXN0ggl0MjQzLnRlc3SCCXQyNDQudGVzdIIJdDI0NS50ZXN0ggl0MjQ2\nLnRlc3SCCXQyNDcudGVzdIIJdDI0OC50ZXN0ggl0MjQ5LnRlc3SCCXQyNTAudGVz\ndIIJdDI1MS50ZXN0ggl0MjUyLnRlc3SCCXQyNTMudGVzdIIJdDI1NC50ZXN0ggl0\nMjU1LnRlc3SCCXQyNTYudGVzdIIJdDI1Ny50ZXN0ggl0MjU4LnRlc3SCCXQyNTku\ndGVzdIIJdDI2MC50ZXN0ggl0MjYxLnRlc3SCCXQyNjIudGVzdIIJdDI2My50ZXN0\nggl0MjY0LnRlc3SCCXQyNjUudGVzdIIJdDI2Ni50ZXN0ggl0MjY3LnRlc3SCCXQy\nNjgudGVzdIIJdDI2OS50ZXN0ggl0MjcwLnRlc3SCCXQyNzEudGVzdIIJdDI3Mi50\nZXN0ggl0MjczLnRlc3SCCXQyNzQudGVzdIIJdDI3NS50ZXN0ggl0Mjc2LnRlc3SC\nCXQyNzcudGVzdIIJdDI3OC50ZXN0ggl0Mjc5LnRlc3SCCXQyODAudGVzdIIJdDI4\nMS50ZXN0ggl0MjgyLnRlc3SCCXQyODMudGVzdIIJdDI4NC50ZXN0ggl0Mjg1LnRl\nc3SCCXQyODYudGVzdIIJdDI4Ny50ZXN0ggl0Mjg4LnRlc3SCCXQyODkudGVzdIIJ\ndDI5MC50ZXN0ggl0MjkxLnRlc3SCCXQyOTIudGVzdIIJdDI5My50ZXN0ggl0Mjk0\nLnRlc3SCCXQyOTUudGVzdIIJdDI5Ni50ZXN0ggl0Mjk3LnRlc3SCCXQyOTgudGVz\ndIIJdDI5OS50ZXN0ggl0MzAwLnRlc3SCCXQzMDEudGVzdIIJdDMwMi50ZXN0ggl0\nMzAzLnRlc3SCCXQzMDQudGVzdIIJdDMwNS50ZXN0ggl0MzA2LnRlc3SCCXQzMDcu\ndGVzdIIJdDMwOC50ZXN0ggl0MzA5LnRlc3SCCXQzMTAudGVzdIIJdDMxMS50ZXN0\nggl0MzEyLnRlc3SCCXQzMTMudGVzdIIJdDMxNC50ZXN0ggl0MzE1LnRlc3SCCXQz\nMTYudGVzdIIJdDMxNy50ZXN0ggl0MzE4LnRlc3SCCXQzMTkudGVzdIIJdDMyMC50\nZXN0ggl0MzIxLnRlc3SCCXQzMjIudGVzdIIJdDMyMy50ZXN0ggl0MzI0LnRlc3SC\nCXQzMjUudGVzdIIJdDMyNi50ZXN0ggl0MzI3LnRlc3SCCXQzMjgudGVzdIIJdDMy\nOS50ZXN0ggl0MzMwLnRlc3SCCXQzMzEudGVzdIIJdDMzMi50ZXN0ggl0MzMzLnRl\nc3SCCXQzMzQudGVzdIIJdDMzNS50ZXN0ggl0MzM2LnRlc3SCCXQzMzcudGVzdIIJ\ndDMzOC50ZXN0ggl0MzM5LnRlc3SCCXQzNDAudGVzdIIJdDM0MS50ZXN0ggl0MzQy\nLnRlc3SCCXQzNDMudGVzdIIJdDM0NC50ZXN0ggl0MzQ1LnRlc3SCCXQzNDYudGVz\ndIIJdDM0Ny50ZXN0ggl0MzQ4LnRlc3SCCXQzNDkudGVzdIIJdDM1MC50ZXN0ggl0\nMzUxLnRlc3SCCXQzNTIudGVzdIIJdDM1My50ZXN0ggl0MzU0LnRlc3SCCXQzNTUu\ndGVzdIIJdDM1Ni50ZXN0ggl0MzU3LnRlc3SCCXQzNTgudGVzdIIJdDM1OS50ZXN0\nggl0MzYwLnRlc3SCCXQzNjEudGVzdIIJdDM2Mi50ZXN0ggl0MzYzLnRlc3SCCXQz\nNjQudGVzdIIJdDM2NS50ZXN0ggl0MzY2LnRlc3SCCXQzNjcudGVzdIIJdDM2OC50\nZXN0ggl0MzY5LnRlc3SCCXQzNzAudGVzdIIJdDM3MS50ZXN0ggl0MzcyLnRlc3SC\nCXQzNzMudGVzdIIJdDM3NC50ZXN0ggl0Mzc1LnRlc3SCCXQzNzYudGVzdIIJdDM3\nNy50ZXN0ggl0Mzc4LnRlc3SCCXQzNzkudGVzdIIJdDM4MC50ZXN0ggl0MzgxLnRl\nc3SCCXQzODIudGVzdIIJdDM4My50ZXN0ggl0Mzg0LnRlc3SCCXQzODUudGVzdIIJ\ndDM4Ni50ZXN0ggl0Mzg3LnRlc3SCCXQzODgudGVzdIIJdDM4OS50ZXN0ggl0Mzkw\nLnRlc3SCCXQzOTEudGVzdIIJdDM5Mi50ZXN0ggl0MzkzLnRlc3SCCXQzOTQudGVz\ndIIJdDM5NS50ZXN0ggl0Mzk2LnRlc3SCCXQzOTcudGVzdIIJdDM5OC50ZXN0ggl0\nMzk5LnRlc3SCCXQ0MDAudGVzdIIJdDQwMS50ZXN0ggl0NDAyLnRlc3SCCXQ0MDMu\ndGVzdIIJdDQwNC50ZXN0ggl0NDA1LnRlc3SCCXQ0MDYudGVzdIIJdDQwNy50ZXN0\nggl0NDA4LnRlc3SCCXQ0MDkudGVzdIIJdDQxMC50ZXN0ggl0NDExLnRlc3SCCXQ0\nMTIudGVzdIIJdDQxMy50ZXN0ggl0NDE0LnRlc3SCCXQ0MTUudGVzdIIJdDQxNi50\nZXN0ggl0NDE3LnRlc3SCCXQ0MTgudGVzdIIJdDQxOS50ZXN0ggl0NDIwLnRlc3SC\nCXQ0MjEudGVzdIIJdDQyMi50ZXN0ggl0NDIzLnRlc3SCCXQ0MjQudGVzdIIJdDQy\nNS50ZXN0ggl0NDI2LnRlc3SCCXQ0MjcudGVzdIIJdDQyOC50ZXN0ggl0NDI5LnRl\nc3SCCXQ0MzAudGVzdIIJdDQzMS50ZXN0ggl0NDMyLnRlc3SCCXQ0MzMudGVzdIIJ\ndDQzNC50ZXN0ggl0NDM1LnRlc3SCCXQ0MzYudGVzdIIJdDQzNy50ZXN0ggl0NDM4\nLnRlc3SCCXQ0MzkudGVzdIIJdDQ0MC50ZXN0ggl0NDQxLnRlc3SCCXQ0NDIudGVz\ndIIJdDQ0My50ZXN0ggl0NDQ0LnRlc3SCCXQ0NDUudGVzdIIJdDQ0Ni50ZXN0ggl0\nNDQ3LnRlc3SCCXQ0NDgudGVzdIIJdDQ0OS50ZXN0ggl0NDUwLnRlc3SCCXQ0NTEu\ndGVzdIIJdDQ1Mi50ZXN0ggl0NDUzLnRlc3SCCXQ0NTQudGVzdIIJdDQ1NS50ZXN0\nggl0NDU2LnRlc3SCCXQ0NTcudGVzdIIJdDQ1OC50ZXN0ggl0NDU5LnRlc3SCCXQ0\nNjAudGVzdIIJdDQ2MS50ZXN0ggl0NDYyLnRlc3SCCXQ0NjMudGVzdIIJdDQ2NC50\nZXN0ggl0NDY1LnRlc3SCCXQ0NjYudGVzdIIJdDQ2Ny50ZXN0ggl0NDY4LnRlc3SC\nCXQ0NjkudGVzdIIJdDQ3MC50ZXN0ggl0NDcxLnRlc3SCCXQ0NzIudGVzdIIJdDQ3\nMy50ZXN0ggl0NDc0LnRlc3SCCXQ0NzUudGVzdIIJdDQ3Ni50ZXN0ggl0NDc3LnRl\nc3SCCXQ0NzgudGVzdIIJdDQ3OS50ZXN0ggl0NDgwLnRlc3SCCXQ0ODEudGVzdIIJ\ndDQ4Mi50ZXN0ggl0NDgzLnRlc3SCCXQ0ODQudGVzdIIJdDQ4NS50ZXN0ggl0NDg2\nLnRlc3SCCXQ0ODcudGVzdIIJdDQ4OC50ZXN0ggl0NDg5LnRlc3SCCXQ0OTAudGVz\ndIIJdDQ5MS50ZXN0ggl0NDkyLnRlc3SCCXQ0OTMudGVzdIIJdDQ5NC50ZXN0ggl0\nNDk1LnRlc3SCCXQ0OTYudGVzdIIJdDQ5Ny50ZXN0ggl0NDk4LnRlc3SCCXQ0OTku\ndGVzdIIJdDUwMC50ZXN0ggl0NTAxLnRlc3SCCXQ1MDIudGVzdIIJdDUwMy50ZXN0\nggl0NTA0LnRlc3SCCXQ1MDUudGVzdIIJdDUwNi50ZXN0ggl0NTA3LnRlc3SCCXQ1\nMDgudGVzdIIJdDUwOS50ZXN0ggl0NTEwLnRlc3SCCXQ1MTEudGVzdIIJdDUxMi50\nZXN0ggl0NTEzLnRlc3SCCXQ1MTQudGVzdIIJdDU", "xNS50ZXN0ggl0NTE2LnRlc3SC\nCXQ1MTcudGVzdIIJdDUxOC50ZXN0ggl0NTE5LnRlc3SCCXQ1MjAudGVzdIIJdDUy\nMS50ZXN0ggl0NTIyLnRlc3SCCXQ1MjMudGVzdIIJdDUyNC50ZXN0ggl0NTI1LnRl\nc3SCCXQ1MjYudGVzdIIJdDUyNy50ZXN0ggl0NTI4LnRlc3SCCXQ1MjkudGVzdIIJ\ndDUzMC50ZXN0ggl0NTMxLnRlc3SCCXQ1MzIudGVzdIIJdDUzMy50ZXN0ggl0NTM0\nLnRlc3SCCXQ1MzUudGVzdIIJdDUzNi50ZXN0ggl0NTM3LnRlc3SCCXQ1MzgudGVz\ndIIJdDUzOS50ZXN0ggl0NTQwLnRlc3SCCXQ1NDEudGVzdIIJdDU0Mi50ZXN0ggl0\nNTQzLnRlc3SCCXQ1NDQudGVzdIIJdDU0NS50ZXN0ggl0NTQ2LnRlc3SCCXQ1NDcu\ndGVzdIIJdDU0OC50ZXN0ggl0NTQ5LnRlc3SCCXQ1NTAudGVzdIIJdDU1MS50ZXN0\nggl0NTUyLnRlc3SCCXQ1NTMudGVzdIIJdDU1NC50ZXN0ggl0NTU1LnRlc3SCCXQ1\nNTYudGVzdIIJdDU1Ny50ZXN0ggl0NTU4LnRlc3SCCXQ1NTkudGVzdIIJdDU2MC50\nZXN0ggl0NTYxLnRlc3SCCXQ1NjIudGVzdIIJdDU2My50ZXN0ggl0NTY0LnRlc3SC\nCXQ1NjUudGVzdIIJdDU2Ni50ZXN0ggl0NTY3LnRlc3SCCXQ1NjgudGVzdIIJdDU2\nOS50ZXN0ggl0NTcwLnRlc3SCCXQ1NzEudGVzdIIJdDU3Mi50ZXN0ggl0NTczLnRl\nc3SCCXQ1NzQudGVzdIIJdDU3NS50ZXN0ggl0NTc2LnRlc3SCCXQ1NzcudGVzdIIJ\ndDU3OC50ZXN0ggl0NTc5LnRlc3SCCXQ1ODAudGVzdIIJdDU4MS50ZXN0ggl0NTgy\nLnRlc3SCCXQ1ODMudGVzdIIJdDU4NC50ZXN0ggl0NTg1LnRlc3SCCXQ1ODYudGVz\ndIIJdDU4Ny50ZXN0ggl0NTg4LnRlc3SCCXQ1ODkudGVzdIIJdDU5MC50ZXN0ggl0\nNTkxLnRlc3SCCXQ1OTIudGVzdIIJdDU5My50ZXN0ggl0NTk0LnRlc3SCCXQ1OTUu\ndGVzdIIJdDU5Ni50ZXN0ggl0NTk3LnRlc3SCCXQ1OTgudGVzdIIJdDU5OS50ZXN0\nggl0NjAwLnRlc3SCCXQ2MDEudGVzdIIJdDYwMi50ZXN0ggl0NjAzLnRlc3SCCXQ2\nMDQudGVzdIIJdDYwNS50ZXN0ggl0NjA2LnRlc3SCCXQ2MDcudGVzdIIJdDYwOC50\nZXN0ggl0NjA5LnRlc3SCCXQ2MTAudGVzdIIJdDYxMS50ZXN0ggl0NjEyLnRlc3SC\nCXQ2MTMudGVzdIIJdDYxNC50ZXN0ggl0NjE1LnRlc3SCCXQ2MTYudGVzdIIJdDYx\nNy50ZXN0ggl0NjE4LnRlc3SCCXQ2MTkudGVzdIIJdDYyMC50ZXN0ggl0NjIxLnRl\nc3SCCXQ2MjIudGVzdIIJdDYyMy50ZXN0ggl0NjI0LnRlc3SCCXQ2MjUudGVzdIIJ\ndDYyNi50ZXN0ggl0NjI3LnRlc3SCCXQ2MjgudGVzdIIJdDYyOS50ZXN0ggl0NjMw\nLnRlc3SCCXQ2MzEudGVzdIIJdDYzMi50ZXN0ggl0NjMzLnRlc3SCCXQ2MzQudGVz\ndIIJdDYzNS50ZXN0ggl0NjM2LnRlc3SCCXQ2MzcudGVzdIIJdDYzOC50ZXN0ggl0\nNjM5LnRlc3SCCXQ2NDAudGVzdIIJdDY0MS50ZXN0ggl0NjQyLnRlc3SCCXQ2NDMu\ndGVzdIIJdDY0NC50ZXN0ggl0NjQ1LnRlc3SCCXQ2NDYudGVzdIIJdDY0Ny50ZXN0\nggl0NjQ4LnRlc3SCCXQ2NDkudGVzdIIJdDY1MC50ZXN0ggl0NjUxLnRlc3SCCXQ2\nNTIudGVzdIIJdDY1My50ZXN0ggl0NjU0LnRlc3SCCXQ2NTUudGVzdIIJdDY1Ni50\nZXN0ggl0NjU3LnRlc3SCCXQ2NTgudGVzdIIJdDY1OS50ZXN0ggl0NjYwLnRlc3SC\nCXQ2NjEudGVzdIIJdDY2Mi50ZXN0ggl0NjYzLnRlc3SCCXQ2NjQudGVzdIIJdDY2\nNS50ZXN0ggl0NjY2LnRlc3SCCXQ2NjcudGVzdIIJdDY2OC50ZXN0ggl0NjY5LnRl\nc3SCCXQ2NzAudGVzdIIJdDY3MS50ZXN0ggl0NjcyLnRlc3SCCXQ2NzMudGVzdIIJ\ndDY3NC50ZXN0ggl0Njc1LnRlc3SCCXQ2NzYudGVzdIIJdDY3Ny50ZXN0ggl0Njc4\nLnRlc3SCCXQ2NzkudGVzdIIJdDY4MC50ZXN0ggl0NjgxLnRlc3SCCXQ2ODIudGVz\ndIIJdDY4My50ZXN0ggl0Njg0LnRlc3SCCXQ2ODUudGVzdIIJdDY4Ni50ZXN0ggl0\nNjg3LnRlc3SCCXQ2ODgudGVzdIIJdDY4OS50ZXN0ggl0NjkwLnRlc3SCCXQ2OTEu\ndGVzdIIJdDY5Mi50ZXN0ggl0NjkzLnRlc3SCCXQ2OTQudGVzdIIJdDY5NS50ZXN0\nggl0Njk2LnRlc3SCCXQ2OTcudGVzdIIJdDY5OC50ZXN0ggl0Njk5LnRlc3SCCXQ3\nMDAudGVzdIIJdDcwMS50ZXN0ggl0NzAyLnRlc3SCCXQ3MDMudGVzdIIJdDcwNC50\nZXN0ggl0NzA1LnRlc3SCCXQ3MDYudGVzdIIJdDcwNy50ZXN0ggl0NzA4LnRlc3SC\nCXQ3MDkudGVzdIIJdDcxMC50ZXN0ggl0NzExLnRlc3SCCXQ3MTIudGVzdIIJdDcx\nMy50ZXN0ggl0NzE0LnRlc3SCCXQ3MTUudGVzdIIJdDcxNi50ZXN0ggl0NzE3LnRl\nc3SCCXQ3MTgudGVzdIIJdDcxOS50ZXN0ggl0NzIwLnRlc3SCCXQ3MjEudGVzdIIJ\ndDcyMi50ZXN0ggl0NzIzLnRlc3SCCXQ3MjQudGVzdIIJdDcyNS50ZXN0ggl0NzI2\nLnRlc3SCCXQ3MjcudGVzdIIJdDcyOC50ZXN0ggl0NzI5LnRlc3SCCXQ3MzAudGVz\ndIIJdDczMS50ZXN0ggl0NzMyLnRlc3SCCXQ3MzMudGVzdIIJdDczNC50ZXN0ggl0\nNzM1LnRlc3SCCXQ3MzYudGVzdIIJdDczNy50ZXN0ggl0NzM4LnRlc3SCCXQ3Mzku\ndGVzdIIJdDc0MC50ZXN0ggl0NzQxLnRlc3SCCXQ3NDIudGVzdIIJdDc0My50ZXN0\nggl0NzQ0LnRlc3SCCXQ3NDUudGVzdIIJdDc0Ni50ZXN0ggl0NzQ3LnRlc3SCCXQ3\nNDgudGVzdIIJdDc0OS50ZXN0ggl0NzUwLnRlc3SCCXQ3NTEudGVzdIIJdDc1Mi50\nZXN0ggl0NzUzLnRlc3SCCXQ3NTQudGVzdIIJdDc1NS50ZXN0ggl0NzU2LnRlc3SC\nCXQ3NTcudGVzdIIJdDc1OC50ZXN0ggl0NzU5LnRlc3SCCXQ3NjAudGVzdIIJdDc2\nMS50ZXN0ggl0NzYyLnRlc3SCCXQ3NjMudGVzdIIJdDc2NC50ZXN0ggl0NzY1LnRl\nc3SCCXQ3NjYudGVzdIIJdDc2Ny50ZXN0ggl0NzY4LnRlc3SCCXQ3NjkudGVzdIIJ\ndDc3MC50ZXN0ggl0NzcxLnRlc3SCCXQ3NzIudGVzdIIJdDc3My50ZXN0ggl0Nzc0\nLnRlc3SCCXQ3NzUudGVzdIIJdDc3Ni50ZXN0ggl0Nzc3LnRlc3SCCXQ3NzgudGVz\ndIIJdDc3OS50ZXN0ggl0NzgwLnRlc3SCCXQ3ODEudGVzdIIJdDc4Mi50ZXN0ggl0\nNzgzLnRlc3SCCXQ3ODQudGVzdIIJdDc4NS50ZXN0ggl0Nzg2LnRlc3SCCXQ3ODcu\ndGVzdIIJdDc4OC50ZXN0ggl0Nzg5LnRlc3SCCXQ3OTAudGVzdIIJdDc5MS50ZXN0\nggl0NzkyLnRlc3SCCXQ3OTMudGVzdIIJdDc5NC50ZXN0ggl0Nzk1LnRlc3SCCXQ3\nOTYudGVzdIIJdDc5Ny50ZXN0ggl0Nzk4LnRlc3SCCXQ3OTkudGVzdIIJdDgwMC50\nZXN0ggl0ODAxLnRlc3SCCXQ4MDIudGVzdIIJdDgwMy50ZXN0ggl0ODA0LnRlc3SC\nCXQ4MDUudGVzdIIJdDgwNi50ZXN0ggl0ODA3LnRlc3SCCXQ4MDgudGVzdIIJdDgw\nOS50ZXN0ggl0ODEwLnRlc3SCCXQ4MTEudGVzdIIJdDgxMi50ZXN0ggl0ODEzLnRl\nc3SCCXQ4MTQudGVzdIIJdDgxNS50ZXN0ggl0ODE2LnRlc3SCCXQ4MTcudGVzdIIJ\ndDgxOC50ZXN0ggl0ODE5LnRlc3SCCXQ4MjAudGVzdIIJdDgyMS50ZXN0ggl0ODIy\nLnRlc3SCCXQ4MjMudGVzdIIJdDgyNC50ZXN0ggl0ODI1LnRlc3SCCXQ4MjYudGVz\ndIIJdDgyNy50ZXN0ggl0ODI4LnRlc3SCCXQ4MjkudGVzdIIJdDgzMC50ZXN0ggl0\nODMxLnRlc3SCCXQ4MzIudGVzdIIJdDgzMy50ZXN0ggl0ODM0LnRlc3SCCXQ4MzUu\ndGVzdIIJdDgzNi50ZXN0ggl0ODM3LnRlc3SCCXQ4MzgudGVzdIIJdDgzOS50ZXN0\nggl0ODQwLnRlc3SCCXQ4NDEudGVzdIIJdDg0Mi50ZXN0ggl0ODQzLnRlc3SCCXQ4\nNDQudGVzdIIJdDg0NS50ZXN0ggl0ODQ2LnRlc3SCCXQ4NDcudGVzdIIJdDg0OC50\nZXN0ggl0ODQ5LnRlc3SCCXQ4NTAudGVzdIIJdDg1MS50ZXN0ggl0ODUyLnRlc3SC\nCXQ4NTMudGVzdIIJdDg1NC50ZXN0ggl0ODU1LnRlc3SCCXQ4NTYudGVzdIIJdDg1\nNy50ZXN0ggl0ODU4LnRlc3SCCXQ4NTkudGVzdIIJdDg2MC50ZXN0ggl0ODYxLnRl\nc3SCCXQ4NjIudGVzdIIJdDg2My50ZXN0ggl0ODY0LnRlc3SCCXQ4NjUudGVzdIIJ\ndDg2Ni50ZXN0ggl0ODY3LnRlc3SCCXQ4NjgudGVzdIIJdDg2OS50ZXN0ggl0ODcw\nLnRlc3SCCXQ4NzEudGVzdIIJdDg3Mi50ZXN0ggl0ODczLnRlc3SCCXQ4NzQudGVz\ndIIJdDg3NS50ZXN0ggl0ODc2LnRlc3SCCXQ4NzcudGVzdIIJdDg3OC50ZXN0ggl0\nODc5LnRlc3SCCXQ4ODAudGVzdIIJdDg4MS50ZXN0ggl0ODgyLnRlc3SCCXQ4ODMu\ndGVzdIIJdDg4NC50ZXN0ggl0ODg1LnRlc3SCCXQ4ODYudGVzdIIJdDg4Ny50ZXN0\nggl0ODg4LnRlc3SCCXQ4ODkudGVzdIIJdDg5MC50ZXN0ggl0ODkxLnRlc3SCCXQ4\nOTIudGVzdIIJdDg5My50ZXN0ggl0ODk0LnRlc3SCCXQ4OTUudGVzdIIJdDg5Ni50\nZXN0ggl0ODk3LnRlc3SCCXQ4OTgudGVzdIIJdDg5OS50ZXN0ggl0OTAwLnRlc3SC\nCXQ5MDEudGVzdIIJdDkwMi50ZXN0ggl0OTAzLnRlc3SCCXQ5MDQudGVzdIIJdDkw\nNS50ZXN0ggl0OTA2LnRlc3SCCXQ5MDcudGVzdIIJdDkwOC50ZXN0ggl0OTA5LnRl\nc3SCCXQ5MTAudGVzdIIJdDkxMS50ZXN0ggl0OTEyLnRlc3SCCXQ5MTMudGVzdIIJ\ndDkxNC50ZXN0ggl0OTE1LnRlc3SCCXQ5MTYudGVzdIIJdDkxNy50ZXN0ggl0OTE4\nLnRlc3SCCXQ5MTkudGVzdIIJdDkyMC50ZXN0ggl0OTIxLnRlc3SCCXQ5MjIudGVz\ndIIJdDkyMy50ZXN0ggl0OTI0LnRlc3SCCXQ5MjUudGVzdIIJdDkyNi50ZXN0ggl0\nOTI3LnRlc3SCCXQ5MjgudGVzdIIJdDkyOS50ZXN0ggl0OTMwLnRlc3SCCXQ5MzEu\ndGVzdIIJdDkzMi50ZXN0ggl0OTMzLnRlc3SCCXQ5MzQudGVzdIIJdDkzNS50ZXN0\nggl0OTM2LnRlc3SCCXQ5MzcudGVzdIIJdDkzOC50ZXN0ggl0OTM5LnRlc3SCCXQ5\nNDAudGVzdIIJdDk0MS50ZXN0ggl0OTQyLnRlc3SCCXQ5NDMudGVzdIIJdDk0NC50\nZXN0ggl0OTQ1LnRlc3SCCXQ5NDYudGVzdIIJdDk0Ny50ZXN0ggl0OTQ4LnRlc3SC\nCXQ5NDkudGVzdIIJdDk1MC50ZXN0ggl0OTUxLnRlc3SCCXQ5NTIudGVzdIIJdDk1\nMy50ZXN0ggl0OTU0LnRlc3SCCXQ5NTUudGVzdIIJdDk1Ni50ZXN0ggl0OTU3LnRl\nc3SCCXQ5NTgudGVzdIIJdDk1OS50ZXN0ggl0OTYwLnRlc3SCCXQ5NjEudGVzdIIJ\ndDk2Mi50ZXN0ggl0OTYzLnRlc3SCCXQ5NjQudGVzdIIJdDk2NS50ZXN0ggl0OTY2\nLnRlc3SCCXQ5NjcudGVzdIIJdDk2OC50ZXN0ggl0OTY5LnRlc3SCCXQ5NzAudGVz\ndIIJdDk3MS50ZXN0ggl0OTcyLnRlc3SCCXQ5NzMudGVzdIIJdDk3NC50ZXN0ggl0\nOTc1LnRlc3SCCXQ5NzYudGVzdIIJdDk3Ny50ZXN0ggl0OTc4LnRlc3SCCXQ5Nzku\ndGVzdIIJdDk4MC50ZXN0ggl0OTgxLnRlc3SCCXQ5ODIudGVzdIIJdDk4My50ZXN0\nggl0OTg0LnRlc3SCCXQ5ODUudGVzdIIJdDk4Ni50ZXN0ggl0OTg3LnRlc3SCCXQ5\nODgudGVzdIIJdDk4OS50ZXN0ggl0OTkwLnRlc3SCCXQ5OTEudGVzdIIJdDk5Mi50\nZXN0ggl0OTkzLnRlc3SCCXQ5OTQudGVzdIIJdDk5NS50ZXN0ggl0OTk2LnRlc3SC\nCXQ5OTcudGVzdIIJdDk5OC50ZXN0ggl0OTk5LnRlc3SCCnQxMDAwLnRlc3SCCnQx\nMDAxLnRlc3SCCnQxMDAyLnRlc3SCCnQxMDAzLnRlc3SCCnQxMDA0LnRlc3SCCnQx\nMDA1LnRlc3SCCnQxMDA2LnRlc3SCCnQxMDA3LnRlc3SCCnQxMDA4LnRlc3SCCnQx\nMDA5LnRlc3SCCnQxMDEwLnRlc3SCCnQxMDExLnRlc3SCCnQxMDEyLnRlc3SCCnQx\nMDEzLnRlc3SCCnQxMDE0LnRlc3SCCnQxMDE1LnRlc3SCCnQxMDE2LnRlc3SCCnQx\nMDE3LnRlc3SCCnQxMDE4LnRlc3SCCnQxMDE5LnRlc3SCCnQxMDIwLnRlc3SCCnQx\nMDIxLnRlc3SCCnQxMDIyLnRlc3SCCnQxMDIzLnRlc3SCCnQxMDI0LnRlc3QwDQYJ\nKoZIhvcNAQELBQADggEBAGfZxjrjcjFw5FnJMzq7SIad+JpmvMar7VnzXj84hjoV\nFuUqiclqjg1KRD7aIh5M1VEQv+AAk8UP6jMrvLJpoi5OD8ljivNA8zycj1N/LhNq\n8MjZauCTS+tuXIoh5hOE/TQqY6cUxY4LRBLIFIcbH0FGF22amCtowMVbRoaUpPvr\nGR5OXPAS3yRiEWrp703c21o3hw9QckB82z7Lxnt3oOFPg62EFPXiqE07Wkw/1xH4\nJ9yy45XW5A77kfel22hVs873QVHI+GkKoTPe/q6eQVgesR2vpDRytKDP9K4tK4KS\n6hqVxj6a8Eqund0izSV+UXkskc9iN6EPXvVTELo3hD8=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen94 = 37039; +static const size_t kLen106 = 37039; -static const char *kData94[] = { +static const char *kData106[] = { "-----BEGIN CERTIFICATE-----\nMIJqrDCCaZSgAwIBAgIBBDANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowgmfXMRAwDgYDVQQDEwd0\nMC50ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nMUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nM0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nNUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nN0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0OEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nOUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTBAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDExQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxMkB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0MTNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDE0QHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQxNUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTZAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDE3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxOEB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0MTlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDIwQHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQyMUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjJAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDIzQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQyNEB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0MjVAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDI2QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQyN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjhAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDI5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzMEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDMy\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzM0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nMzRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDM1QHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQzNkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzdAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDM4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzOUB0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0NDBAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQxQHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ0MkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDNAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDQ0QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ0NUB0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0NDZAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQ3QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ0OEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDlAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDUwQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1MUB0ZXN0\nMRcwFQYJKoZIhvcNAQkBFgh0NTJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDUzQHRl\nc3QxFzAVBgkqhkiG9w0BCQEWCHQ1NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NTVA\ndGVzdDEXMBUGCSqGSIb3DQEJARYIdDU2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1\nN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NThAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDU5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2MEB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0NjFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDYyQHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQ2M0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NjRAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDY1QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2NkB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0NjdAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDY4QHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQ2OUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzBAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDcxQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3MkB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0NzNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDc0QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQ3NUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzZAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDc3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3OEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgw\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4MUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nODJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgzQHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQ4NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0ODVAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDg2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4N0B0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0ODhAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDg5QHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ5MEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTFAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDkyQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5M0B0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0OTRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDk1QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ5NkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTdAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDk4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTAwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTAzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEwNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTA2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTA5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDExMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTEyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEx\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTE1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxMTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDExN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTE4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDEyMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTIxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxMjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTI0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTI3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEyOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTMwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEzMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTMzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDEzNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEz\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTQyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE0NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTQ1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTQ4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTUxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE1M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTU0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTU3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE1OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTY2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE2OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTY5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTcyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTc1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE3N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTc4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTgxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxODJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE4M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxODVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxODhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTkwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE5MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTkzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxOTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTk2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTk5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIwMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjAyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIwNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjA1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIwN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjA4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIx\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjExQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjE0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDIxNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjE3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyMThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjIwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjIzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIyNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjI2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjI5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIzMUB0ZXN0MRgwFgY", "JKoZIhvcNAQkBFgl0MjMyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIz\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjM1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIzN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjM4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI0MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjQxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjQ0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI0OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjUwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjUzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI1NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyNjBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjYyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI2NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjY1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNjZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjY4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjcxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI3M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjc0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNzVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mjc3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzhAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI3OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyODFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyODRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0Mjg2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyODdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI4OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjg5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyOTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjkyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjk1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI5N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjk4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyOTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzAxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMwM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMw\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMDhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzEwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMxMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzEzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzE2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzE5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDMyMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzIyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzMjNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMyNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzI1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMyN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzI4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMz\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzMxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMzJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzM0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMzVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMzNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzM3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMzhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzQwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzQzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM0NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzQ2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzQ5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM1MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzUyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzU1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzNTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzU4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM2MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzYxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzNjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzY0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzY3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM2OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzcwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzczQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM3NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzODBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzgyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM4NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzg1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzODZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0Mzg4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzkxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM5M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzk0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzOTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mzk3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM5OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQw\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MDRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQwNUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDA2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQwOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDA5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxMUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDEyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDE1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQxN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDE4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0MTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDIxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQyM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQy\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MjhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDMwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQzMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDMzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MzRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDM2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDM5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ0MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ0NEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDQ1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ0N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQ4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDUxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1M0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDU0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ1NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDU3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0NThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDYwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDYzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjRAd", "GVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ2NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDY2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDY5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ3MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDcyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDc1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDc4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ4MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDgxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0ODJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDg0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDg3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ4OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDkwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0OTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDkzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ5NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1MDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwMUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTAyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDUwNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTA1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1MDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwN0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTA4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDUxMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTExQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDUxM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTE0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ1MTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUxNkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NTE3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDUxOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTIwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUy\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTIzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1MjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUyNUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTI2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDUyOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTI5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1MzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUzMUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTMyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDUzNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTM1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDUzN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTM4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ1MzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU0MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NTQxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NDJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDU0M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTQ0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NDVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU0\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1NDhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU0OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTUwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDU1MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTUzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1NTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU1NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTU2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDU1OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTU5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NjBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDU2MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTYyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ1NjNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU2NEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NTY1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NjZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDU2N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTY4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NjlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU3\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTcxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1NzJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU3M0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTc0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1NzVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDU3NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTc3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1NzhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU3OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTgwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1ODFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDU4MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTgzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1ODRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDU4NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTg2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ1ODdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU4OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NTg5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1OTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDU5MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTkyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ1OTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU5\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTk1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1OTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDU5N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTk4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1OTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDYwMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjAxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ2MDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYwM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NjA0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDYwNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNjA3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDYwOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjEwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ2MTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYxMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NjEzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDYxNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjE2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYx\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjE5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ2MjBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYyMUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NjIyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MjNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDYyNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjI1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ2MjZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYyN0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NjI4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MjlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDYzMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNjMxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MzJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDYzM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjM0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ2MzVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDYzNkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NjM3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2MzhAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDYzOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjQwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NDFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY0\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjQzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ2NDRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY0NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NjQ2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NDdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDY0OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjQ5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ2NTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY1MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NjUyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDY1NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNjU1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDY1N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjU4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ2NTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY2MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NjYxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NjJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDY2M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjY0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NjVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY2\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjY3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ2NjhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY2OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NjcwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NzFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDY3MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjczQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ2NzRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY3NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0Njc2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2NzdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDY3OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNjc5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2ODBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDY4MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjgyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ2ODNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY4NEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Njg1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2ODZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDY4N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Njg4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ2ODlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY5\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NjkxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ2OTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY5M0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0Njk0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ2OTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDY5NkB0ZXN0MRgwFgYJKoZIhvcNAQk", "BFgl0Njk3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ2OThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDY5OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NzAwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDcwMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNzAzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDcwNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzA2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ3MDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDcwOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NzA5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDcxMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzEyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDcx\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzE1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ3MTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDcxN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NzE4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDcyMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzIxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ3MjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDcyM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NzI0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDcyNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNzI3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDcyOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzMwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ3MzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDczMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NzMzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDczNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzM2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ3MzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDcz\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzM5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ3NDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc0MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NzQyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDc0NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzQ1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ3NDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc0N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NzQ4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDc1MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNzUxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDc1M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzU0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ3NTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc1NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NzU3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDc1OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzYwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc2\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzYzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ3NjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc2NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NzY2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDc2OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzY5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ3NzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc3MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NzcyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDc3NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNzc1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3NzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDc3N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Nzc4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ3NzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc4MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NzgxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3ODJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDc4M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Nzg0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ3ODVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc4\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Nzg3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ3ODhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc4OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NzkwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3OTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDc5MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NzkzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ3OTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDc5NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0Nzk2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ3OTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDc5OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNzk5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDgwMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODAyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ4MDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgwNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0ODA1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDgwN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODA4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgx\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODExQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ4MTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgxM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0ODE0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDgxNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODE3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ4MThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgxOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0ODIwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDgyMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nODIzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MjRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDgyNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODI2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ4MjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgyOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0ODI5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDgzMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODMyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgz\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODM1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ4MzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDgzN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0ODM4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4MzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDg0MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODQxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ4NDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg0M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0ODQ0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDg0NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nODQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDg0OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODUwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ4NTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg1MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0ODUzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDg1NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODU2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg1\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODU5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ4NjBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg2MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0ODYyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NjNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDg2NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODY1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ4NjZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg2N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0ODY4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NjlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDg3MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nODcxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NzJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDg3M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODc0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ4NzVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg3NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0ODc3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4NzhAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDg3OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODgwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ4ODFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg4\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODgzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ4ODRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg4NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0ODg2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4ODdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDg4OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODg5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ4OTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDg5MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0ODkyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4OTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDg5NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nODk1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ4OTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDg5N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0ODk4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ4OTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkwMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0OTAxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MDJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDkwM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTA0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MDVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkw\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTA3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ5MDhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkwOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0OTEwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDkxMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTEzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ5MTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkxNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0OTE2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDkxOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nOTE5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MjBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDkyMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTIyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ5MjNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkyNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0OTI1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MjZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDkyN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTI4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MjlAdGVzdDEYMBYGC", "SqGSIb3DQEJARYJdDkz\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTMxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ5MzJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkzM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0OTM0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5MzVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDkzNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTM3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ5MzhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDkzOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0OTQwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDk0MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nOTQzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDk0NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTQ2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ5NDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk0OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0OTQ5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDk1MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTUyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk1\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTU1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ5NTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk1N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0OTU4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDk2MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTYxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ5NjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk2M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0OTY0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDk2NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nOTY3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDk2OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTcwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ5NzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk3MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0OTczQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDk3NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTc2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ5NzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk3\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTc5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ5ODBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk4MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0OTgyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5ODNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDk4NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTg1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ5ODZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk4N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0OTg4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5ODlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDk5MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nOTkxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5OTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDk5M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0OTk0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ5OTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDk5NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0OTk3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ5OThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDk5OUB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAwMEB0\nZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAwMUB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0\nMTAwMkB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAwM0B0ZXN0MRkwFwYJKoZIhvcN\nAQkBFgp0MTAwNEB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAwNUB0ZXN0MRkwFwYJ\nKoZIhvcNAQkBFgp0MTAwNkB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAwN0B0ZXN0\nMRkwFwYJKoZIhvcNAQkBFgp0MTAwOEB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAw\nOUB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxMEB0ZXN0MRkwFwYJKoZIhvcNAQkB\nFgp0MTAxMUB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxMkB0ZXN0MRkwFwYJKoZI\nhvcNAQkBFgp0MTAxM0B0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxNEB0ZXN0MRkw\nFwYJKoZIhvcNAQkBFgp0MTAxNUB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxNkB0\nZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxN0B0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0\nMTAxOEB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAxOUB0ZXN0MRkwFwYJKoZIhvcN\nAQkBFgp0MTAyMEB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAyMUB0ZXN0MRkwFwYJ\nKoZIhvcNAQkBFgp0MTAyMkB0ZXN0MRkwFwYJKoZIhvcNAQkBFgp0MTAyM0B0ZXN0\nMRkwFwYJKoZIhvcNAQkBFgp0MTAyNEB0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57\n+EWssZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEix\noiXCzepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lq\nZ1Aky+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRz\nYeIs2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTO\ngnmET19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABo0kwRzAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADASBgNVHREE\nCzAJggd0MC50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQAi7LIMyX5Ec514hvjROZ8b\n7i4UR3xd5IbniVSej+PKZhG2inN6aX9bksdda0ddYZeRSHAkNJuoabeankQJ/x5x\nsxBntWSVLCxz6S8NRrLAPKKPBvFb/W5ns57LP9SrLIij9l/NSd+K/CQNTlfcdorg\n4ltPVNwSMp/XXjH6rQYJSbo9MhDoxeqPpv73e4jY0DfGn1a8uwyCXalLjh4EkUyS\nYe0N7MoUKV0IucrXKdgj2sHgBFqNKJ/GVQ422xZRbYqsyIJ0bPD6Fc8VcqfVrvYg\nlCYJfu7Xij5n3mjQaSYcbVxH71X8fYhhNq1tk+WtQOXirz2EkSuh1rNGU/LT8Q6r\n-----END CERTIFICATE-----\n", }; -static const size_t kLen95 = 13599; +static const size_t kLen107 = 603; -static const char *kData95[] = { +static const char *kData107[] = { + "-----BEGIN CERTIFICATE-----\nMIIBkDCCATWgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjajBoMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK\nBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE\nYcLF6z1QWoBtrjARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZIzj0EAwIDSQAwRgIh\nAJbyXshUwjsFCiqrJkg91GzJdhZZ+3WXOekCJgi8uEESAiEAhv4sEE0wRRqgHDjl\nvIt26IELfFE2Z/FBF3ihGmi6NoI=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen108 = 664; + +static const char *kData108[] = { + "-----BEGIN CERTIFICATE-----\nMIIBvDCCAWKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgZYwgZMwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgUpG6\nFUeWrC62BtTPHiSlWBdnLWUYH0llS6uYUkpJFJECIQCWfhoZYXvHdMhgBDSI/vzY\nSw4uNdcMxrC2kP6lIioUSw==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen109 = 599; + +static const char *kData109[] = { + "-----BEGIN CERTIFICATE-----\nMIIBjDCCATKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjZzBlMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK\nBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE\nYcLF6z1QWoBtrjAOBgNVHSAEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgS2uK\ncYlZ1bxeqgMy3X0Sfi0arAnqpePsAqAeEf+HJHQCIQDwfCnXrWyHET9lM/gJSkfN\nj/JRJvJELDrAMVewCxZWKA==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen110 = 887; + +static const char *kData110[] = { + "-----BEGIN CERTIFICATE-----\nMIICYjCCAgegAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjggE6MIIBNjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u\nqGsIhGHCxes9UFqAba4wEQYDVR0gBAowCDAGBgRVHSAAMIHLBgNVHSEEgcMwgcAw\nHgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG9xIEAYS3CQID\nBg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3EgQBhLcJAgQw\nHgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG9xIEAYS3CQIF\nBg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgUw\nCgYIKoZIzj0EAwIDSQAwRgIhAIOx3GL5xlldQGdTLIvTTAvczm8wiYHzZDAif2yj\nwAjEAiEAg4K02kTYX9x7PC/u1PYdwvo+LVbnGbO6AN6U3K2d7gs=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen111 = 899; + +static const char *kData111[] = { + "-----BEGIN CERTIFICATE-----\nMIICajCCAhCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjggFDMIIBPzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u\nqGsIhGHCxes9UFqAba4wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMIHLBgNV\nHSEEgcMwgcAwHgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG\n9xIEAYS3CQIDBg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3\nEgQBhLcJAgQwHgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG\n9xIEAYS3CQIFBg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3\nEgQBhLcJAgUwCgYIKoZIzj0EAwIDSAAwRQIhAK0bRaGgd5qQlX+zTw3IUynFHxfk\nzRbZagnTzjYtkNNmAiBJ2kOnvRdW930eHAwZPGpc1Hn5hMSOQdUhNZ3XZDASkQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen112 = 989; + +static const char *kData112[] = { + "-----BEGIN CERTIFICATE-----\nMIICrjCCAlSgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjggGHMIIBgzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u\nqGsIhGHCxes9UFqAba4wXgYDVR0gBFcwVTAPBg0qhkiG9xIEAYS3CQIBMA8GDSqG\nSIb3EgQBhLcJAgIwDwYNKoZIhvcSBAGEtwkCAzAPBg0qhkiG9xIEAYS3CQIEMA8G\nDSqGSIb3EgQBhLcJAgUwgcsGA1UdIQSBwzCBwDAeBg0qhkiG9xIEAYS3CQIDBg0q\nhkiG9xIEAYS3CQIBMB4GDSqGSIb3EgQBhLcJAgMGDSqGSIb3EgQBhLcJAgIwHgYN\nKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBDAeBg0qhkiG9xIEAYS3CQIEBg0q\nhkiG9xIEAYS3CQIFMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgQwHgYN\nKoZIhvcSBAGEtwkCBQYNKoZIhvcSBAGEtwkCBTAKBggqhkjOPQQDAgNIADBFAiAe\nAh2vJMZsW/RV35mM7b7/NjsjScjPEIxfDJu49inNXQIhANmGBqyWUogh/gXyVB0/\nIfDro27pANW3R02A+zH34q5k\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen113 = 680; + +static const char *kData113[] = { + "-----BEGIN CERTIFICATE-----\nMIIByjCCAXCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgaQwgaEwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwDAYDVR0kBAUwA4ABADAKBggqhkjO\nPQQDAgNIADBFAiA2GxzMRYYo7NNq8u/ZvffXkCj/phqXQ8I64tEDd0X8pgIhAOJJ\ne+dzzf4vbWfMlYkOQ4kf6ei5Zf+J2PL6VrqVrHQa\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen114 = 595; + +static const char *kData114[] = { + "-----BEGIN CERTIFICATE-----\nMIIBizCCATCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjZTBjMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK\nBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE\nYcLF6z1QWoBtrjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDJYPgf\n50fFDVho5TFeqkNVONx0ArVNgULPB27yPDHLrwIhAN+eua6oM4Q/O0jUESQ4VAKt\nts7ZCquTZbvgRgyqtjuT\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen115 = 656; + +static const char *kData115[] = { + "-----BEGIN CERTIFICATE-----\nMIIBuDCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMAwGA1UdJAQFMAOAAQAwCgYIKoZIzj0EAwIDRwAwRAIgbPUZ9ezH\nSgTqom7VLPOvrQQXwy3b/ijSobs7+SOouKMCIDaqcb9143BG005etqeTvlgUyOGF\nGQDWhiW8bizH+KEl\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen116 = 660; + +static const char *kData116[] = { + "-----BEGIN CERTIFICATE-----\nMIIBujCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMAwGA1UdJAQFMAOAAQEwCgYIKoZIzj0EAwIDSQAwRgIhAIAwvhHB\nGQDN5YXlidd+n3OT/SqoeXfp7RiEonBnCkW4AiEA+iFc47EOBchHb+Gy0gg8F9Po\nRnlpoulWDfbDwx9r4lc=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen117 = 660; + +static const char *kData117[] = { + "-----BEGIN CERTIFICATE-----\nMIIBuTCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMAwGA1UdJAQFMAOAAQIwCgYIKoZIzj0EAwIDSAAwRQIgOpliSKKA\n+wy/auQnKKl+wwtn/hGw6eZXgIOtFgDmyMYCIQC84zoJL87AE64gsrdX4XSHq6lb\nWhZQp9ZnDaNu88SQLQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen118 = 639; + +static const char *kData118[] = { + "-----BEGIN CERTIFICATE-----\nMIIBqjCCAVGgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE\nAxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia\njQ6Dg7CTpVZVVH+bguT7JTCjgYUwgYIwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr\nCIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG\n9xIEAYS3CQICMAoGCCqGSM49BAMCA0cAMEQCIFN2ZtknXQ9vz23qD1ecprC9iIo7\nj/SI42Ub64qZQaraAiA+CRCWJz/l+NQ1+TPWYDDWY6Wh2L9Wbddh1Nj5KJEkhQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen119 = 599; + +static const char *kData119[] = { + "-----BEGIN CERTIFICATE-----\nMIIBjTCCATOgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2QwYjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wEQYDVR0gBAowCDAGBgRVHSAAMAoGCCqGSM49BAMCA0gAMEUCIQC4\nUwAf1R4HefSzyO8lyQ3fmMjkptVEhFBee0a7N12IvwIgJMYZgQ52VTbqXyXqraJ8\nV+y+o7eHds7NewqnyuLbc78=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen120 = 648; + +static const char *kData120[] = { + "-----BEGIN CERTIFICATE-----\nMIIBsTCCAVigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE\nAxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY\nvFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle\nTS8wQT/cjw/wPgoeV6OBkDCBjTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYI\nKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5j\nb20wPAYDVR0gBDUwMzAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQBhLcJAgIw\nDwYNKoZIhvcSBAGEtwkCAjAKBggqhkjOPQQDAgNHADBEAiBjYDwsWcs35hU/wPqa\n5gf0QUMvV/8z5LPX14fB2y4RGQIgMw0ekrt9K5UcgkvFupV/XXIjLRFQvc8URA3C\n/+w+2/4=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen121 = 583; + +static const char *kData121[] = { + "-----BEGIN CERTIFICATE-----\nMIIBgjCCASigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE\nAxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY\nvFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle\nTS8wQT/cjw/wPgoeV6NhMF8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG\nAQUFBwMBMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t\nMA4GA1UdIAQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiAgfcDIeqmV+u5YtUe4\naBnj13tZAJAQh6ttum1xZ+xHEgIhAJqvGX5c0/d1qYelBlm/jE3UuivijdEjVsLX\nGVH+X1VA\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen122 = 574; + +static const char *kData122[] = { + "-----BEGIN CERTIFICATE-----\nMIIBezCCASCgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1EwTzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wCgYIKoZIzj0EAwIDSQAwRgIhAIDFeeYJ8nmYo09OnJFpNS3A6fYO\nZliHkAqOsg193DTnAiEA3OSHLCczcvRjMG+qd/FI61u2sKU1hhHh7uHtD/YO/dA=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen123 = 611; + +static const char *kData123[] = { + "-----BEGIN CERTIFICATE-----\nMIIBlTCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIBMAoGCCqGSM49BAMC\nA0cAMEQCIHh4Bo8l/HVJhLMWcYusPOE0arqoDrJ5E0M6nEi3nRhgAiAArK8bBohG\nfZ3DmVMq/2BJtQZwRRj+50VKWuf9mBSflQ==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen124 = 611; + +static const char *kData124[] = { + "-----BEGIN CERTIFICATE-----\nMIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQICMAoGCCqGSM49BAMC\nA0kAMEYCIQDvW7rdL6MSW/0BPNET4hEeECO6LWmZZHKCHIu6o33dsAIhAPwgm6lD\nKV2hMOxkE6rBDQzlCr+zAkQrxSzQZqJp5p+W\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen125 = 611; + +static const char *kData125[] = { + "-----BEGIN CERTIFICATE-----\nMIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMAoGCCqGSM49BAMC\nA0kAMEYCIQDBPnPpRsOH20ncg8TKUdlONfbO62WafQj9SKgyi/nGBQIhAMhT8J7f\nfTEou6jlAilaIQwlAgZzVKRqgghIHezFY86T\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen126 = 611; + +static const char *kData126[] = { + "-----BEGIN CERTIFICATE-----\nMIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIEMAoGCCqGSM49BAMC\nA0kAMEYCIQD2gnpCTMxUalCtEV52eXzqeJgsKMYvEpJTuU/VqH5KwQIhAPEavAkt\ncSJsgMgJcJnbBzAdSrbOgHXF2etDHmFbg0hz\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen127 = 611; + +static const char *kData127[] = { + "-----BEGIN CERTIFICATE-----\nMIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIFMAoGCCqGSM49BAMC\nA0kAMEYCIQDDFVjhlQ1Wu0KITcRX8kELpVDeYSKSlvEbZc3rn1QjkQIhAMPthqBi\nI0acz8DPQcdFmHXV0xR2xyC1yuen0gES5WLR\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen128 = 656; + +static const char *kData128[] = { + "-----BEGIN CERTIFICATE-----\nMIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV\nHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l\neGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS\nBAGEtwkCAjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDrNQPi/mdK\nl7Nd/YmMXWYTHJBWWin1zA64Ohkd7z4jGgIhAJpw/umk5MxS1MwSi+YTkkcSQKpl\nYROQH6+T53DauoW6\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen129 = 656; + +static const char *kData129[] = { + "-----BEGIN CERTIFICATE-----\nMIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV\nHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l\neGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS\nBAGEtwkCAjAMBgNVHSQEBTADgAEBMAoGCCqGSM49BAMCA0kAMEYCIQCtXENGJrKv\nIOeLHO/3Nu/SMRXc69Vb3q+4b/uHBFbuqwIhAK22Wfh/ZIHKu3FwbjL+sN0Z39pf\nDsak6fp1y4tqNuvK\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen130 = 635; + +static const char *kData130[] = { + "-----BEGIN CERTIFICATE-----\nMIIBpzCCAU2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg\nSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa\nMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB\nBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR\nqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo34wfDAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l\nBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh\nbXBsZS5jb20wKwYDVR0gBCQwIjAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQB\nhLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgBEOriD1N3/cqoAofxEtf73M7Wi4UfjFK\njiU9nQhwnnoCIQD1v/XDp2BkWNHxNq7TaPnil3xXTvMX97yUbkUg8IRo0w==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen131 = 611; + +static const char *kData131[] = { + "-----BEGIN CERTIFICATE-----\nMIIBljCCAT2gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg\nUm9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAWMRQwEgYD\nVQQDEwtQb2xpY3kgUm9vdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCZ2pdiX\nUa9jvLeNxNMroxVchCvjhOoKFFgjoh5X20gHqMiw5j5CiXVuTzH/sDkUY6dRYVUs\nQA8Q9InA+d2OiW2jeDB2MA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF\nBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTQaeegH7J43rdYy2GeHpSH\nUcd1EjARBgNVHSAECjAIMAYGBFUdIAAwDAYDVR0kBAUwA4EBADAKBggqhkjOPQQD\nAgNHADBEAiBzR3JGEf9PITYuiXTx+vx9gXji5idGsVog9wRUbY98wwIgVVeYNQQb\nx+RN2wYp3kmm8iswUOrqiI6J4PSzT8CYP8Q=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen132 = 566; + +static const char *kData132[] = { + "-----BEGIN CERTIFICATE-----\nMIIBdTCCARqgAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg\nUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE\nAxMLUG9saWN5IFJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQmdqXYl1Gv\nY7y3jcTTK6MVXIQr44TqChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAP\nEPSJwPndjolto1cwVTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUH\nAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU0GnnoB+yeN63WMthnh6Uh1HH\ndRIwCgYIKoZIzj0EAwIDSQAwRgIhAKVxVAaJnmvt+q4SqegGS23QSzKPM9Yakw9e\nbOUU9+52AiEAjXPRBdd90YDey4VFu4f/78yVe0cxMK30lll7lLl7TTA=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen133 = 570; + +static const char *kData133[] = { + "-----BEGIN CERTIFICATE-----\nMIIBeDCCAR6gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg\nUm9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAYMRYwFAYD\nVQQDEw1Qb2xpY3kgUm9vdCAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJnal\n2JdRr2O8t43E0yujFVyEK+OE6goUWCOiHlfbSAeoyLDmPkKJdW5PMf+wORRjp1Fh\nVSxADxD0icD53Y6JbaNXMFUwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG\nAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNBp56Afsnjet1jLYZ4e\nlIdRx3USMAoGCCqGSM49BAMCA0gAMEUCIQDm9rw9ODVtJUPBn2lWoK8s7ElbyY4/\nGc2thHR50UUzbgIgKRenEDhKiBR6cGC77RaIiaaafW8b7HMd7obuZdDU/58=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen134 = 1099; + +static const char *kData134[] = { + "-----BEGIN CERTIFICATE-----\nMIIC/TCCAbmgAwIBAgIBADA5BgkqhkiG9w0BAQowLKALMAkGBSsOAwIaBQChGDAW\nBgkqhkiG9w0BAQgwCQYFKw4DAhoFAKIDAgEUMBQxEjAQBgNVBAMMCUJvcmluZ1NT\nTDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1OTU5WjAUMRIwEAYDVQQD\nDAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6C9qE\nGRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94Z\nnsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgP\niEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gU\nR69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq\n32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVA\nlBDUviIqY95CKy25AgMBAAEwOQYJKoZIhvcNAQEKMCygCzAJBgUrDgMCGgUAoRgw\nFgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiAwIBFAOCAQEATo0Z3YqPt4fzBXz22vyH\n7Ckr1cicKTeE3lV8LYHII4easVkueN7HrfrpTPu04kn4Y8pjprh0gRj9vcf6i6Sj\nkhPnfmXTTbeFxHs763BQVAOoutgteyUhBZ5UjqaXnnF7PYhyG/0ykxWryvius+dz\nujhW9T0aPo95GWITtj1NHzGmCjQYqUSrfkJynC8c/juTo3MLWrMnirDsAYizTg4W\nCWBfeMKRfAH6aOybSBNZh7/KU+ZiFPKJi+NKPPaZNZa0l1JZ46LL1NWVq6bybZH8\nncNZpooQKTfCaK221pbqxx4YIJT0NoICU8291LSNLz8/5uBkjUo744cF4tuNFZ4k\nsg==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen135 = 1025; + +static const char *kData135[] = { + "-----BEGIN CERTIFICATE-----\nMIICxzCCAZ6gAwIBAgIBADAeBgkqhkiG9w0BAQowEaEPMA0GCSqGSIb3DQEBCDAA\nMBQxEjAQBgNVBAMMCUJvcmluZ1NTTDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkx\nMjMxMjM1OTU5WjAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEB\nAQUAA4IBDwAwggEKAoIBAQC6C9qEGRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPh\nCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARI\nhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyK\nj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRT\nzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEm\ngyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIqY95CKy25AgMBAAEwHgYJKoZIhvcN\nAQEKMBGhDzANBgkqhkiG9w0BAQgwAAOCAQEANdpvRLqZLsYfruBHXjviZaKoHeoQ\n1ixqeSLzcP0KzWRT3H3tX46KuYABaMurK0yPMDfW6oLCfJa3fUFt0FYJYnf/w7mp\nMsmOf+7aaY8oYqI6wRwtAB0JQcC2tKsio+UEiI6hZq2ghhGa5c+YLXhN4Dt+/cK9\nUkisKL4O61jKulfaErOsUSaYTo9/PJpPcUhE/zVtsfAGJH0ojSCrSpEYv4TNO9Qm\nWOJ4hMreEOLVxw4xC65wRmOWl4JpGxle1mNzjsL4kOcDwsnepEOcpAqJronQ+HnI\n1RCR04oEnOOWYAtFxuWzTds3BjszGPRSu3srGZpaI1j/kB+a3g/7hXufOA==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen136 = 977; + +static const char *kData136[] = { + "-----BEGIN CERTIFICATE-----\nMIICpTCCAY2gAwIBAgIBADANBgkqhkiG9w0BAQowADAUMRIwEAYDVQQDDAlCb3Jp\nbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAG\nA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkW\nf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQS\njHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy\n8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50\n+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk\n7ZE1QJQQ1L4iKmPeQistuQIDAQABMA0GCSqGSIb3DQEBCjAAA4IBAQAQvYDcDDNx\nQPctGNiZTH9N2I2wdVXHmsybRW7tXWVYm+yE8IzfVUUBkCL5WvbLxlujMAbQpHp8\nEnKECVsNAklHAAQ6KFDTngyDAjdyGiNKKMm37UW/I7BkdFZE+jBYKoVU5xeLSPm1\njNKQWqjGnaZ+wV7Fl8Zy+QOr7Z35zrDNbCF/EkzoE6+i/bbqXIgu5x14rj9c4JAs\naKPpTtpDI1zt9BfGMPsBxsxeckqnG8OlNc6YI8svAK849naTAPx93jDWmDBYqfsb\nMeZOo9+AfUP7pjoDZHsQCmPdmlDgAtMvi8K1oFbw4BBTu+CaCzhNS5xEbITef09i\ntjiySH0Q5r01\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen137 = 1119; + +static const char *kData137[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCBAUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCBAUAogMCARwwFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCBAUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCBAUAogMCARwDggEB\nAHttVo+XfLdlRXHc59yGAr7wQgqIbWOD6QSo4Tb4XbAh4nc9MQhccfT4YOMyHa9I\ni1VyE9e2dna8gt9VfIyCeTnNS1RYbKagaUzo2dt/G0lQjfXRVkB1yobJEaAzZ8kg\ncbknjlrlMEtHW+ET2vTHKvOjHjHXy3GYt8ynSldnotikqVobW5Kd/nYR7s9SR1Yz\nVhweDRcWeb3IYSAx953t1voky/7pTltcyb5FfJLIPmj2AsoFSRnXrj1Sx0K+S68m\nE0TdKwOTr2QN9nmHrIbCIeiAVeBlIOY6jH8TjobwFV2Y3RlqC+8S+Vgje/Hg/jrV\nQ9fS9+RIVSOFZiOgW/1hjAA=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen138 = 1131; + +static const char *kData138[] = { + "-----BEGIN CERTIFICATE-----\nMIIDFzCCAcagAwIBAgIBADBGBgkqhkiG9w0BAQowOaAPMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASCjAwIBATAUMRIwEAYD\nVQQDDAlCb3JpbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1\nOVowFDESMBAGA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWs\nsZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXC\nzepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Ak\ny+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs\n2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmE\nT19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABMEYGCSqGSIb3DQEBCjA5oA8w\nDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIB\nIKMDAgEBA4IBAQA6p/W2ZA06aYzRXL1v/VnU11udk5+UIbGAuhSVv9a+zJ4/79UX\nXk4/otg74fq/Ayy3hPm9lcOTGbXYHSgY4eFR8J1VS/P2ZPRCyypXwLSYg+Yt5Fdc\nSaA2JVF2jrgMbIAzBsyz4CCOzajcF/he8+NmH7pDZhLGv4pIWaFqAPrGntIpPwVW\nQib62z9qzeexXIm+1Jp3nh21sXLbWdBM5tt5NNqST+cgzzrRnPtwQTbdcKk9i4Jh\n3/BairkWclVHxibtNPoLvhU91tJw61rES29x3vG//7WwEoT2aLCkp9/ZHrM5ukpe\nRxWXU+JZXiO59WWDCdK0YAuoteozepn4Cwei\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen139 = 1119; + +static const char *kData139[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCASAwFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCASADggEB\nAFMuNrMzLKfCvjDw35e5aoOPsTHKmkreUl4yHjUxX3i0heSkvy3FFcXhGjOscySF\nhBoAZU1DJaIHGzq2/k9Z3pk+NFhLg6tlHvLgcySHl4kR4sqTceJeOgy4RHJU04Gv\nwFAfRXx8QTJr1d00EPBoSnj7afDtvcRkzDSsgQ+YiQ9zjvt+uzuhZ25CUw8KY+Xy\nCZqQYE5yIMMRoKZExPcXuWTD8Ho5pVxjeLv2+nEO73NaAP0FwisCuY98ng0ffTgG\n5biORaDLzoTQv0QXtHS5TRUd6ycQ7nW28M4U1ZP9s9gj1zl+emvmi1UjNs3bcRW3\nJk0lRwKo8awDUhfWJ/YPIns=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen140 = 1082; + +static const char *kData140[] = { + "-----BEGIN CERTIFICATE-----\nMIIC8zCCAbSgAwIBAgIBADA0BgkqhkiG9w0BAQowJ6APMA0GCWCGSAFlAwQCAQUA\noQ8wDQYJKoZIhvcNAQEIMACiAwIBIDAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwIhgP\nMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAGA1UEAwwJQm9y\naW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAugvahBkSAUF1\nfC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkWf6PeGZ7F5AX1\nPyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQSjHD4D4hKtgdM\ngVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy8U+YFEevb/V0\nlRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50+UMgat9ocewI\n2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk7ZE1QJQQ1L4i\nKmPeQistuQIDAQABMDQGCSqGSIb3DQEBCjAnoA8wDQYJYIZIAWUDBAIBBQChDzAN\nBgkqhkiG9w0BAQgwAKIDAgEgA4IBAQAJ0RuKq+OgFlcm2EMk+VXH8hSo87N3wcyK\n9SzLwONh2uVYR3W1ig+/EwqK0M9w5UwvSVNdFa3m2qVXApprUm7eCJ2c7rWiBkQy\nsVCHwWVCseItZ8ipJHHz0uC5k3EFBSVbsbRdTJ8FPbRDBXXn2iSz6OzUJVZ5PfV1\nXRC81Aoi8DbhFwNga7/mJ80Ru4UGEePT6SsyUU5sgZ0w37r+5VPQgL4oOMO2NKz+\nO060CbcDcOXrCm1x0BXIOc7gZEao5mriJTFQTq4PsuMnJ9a7aU+PYPfTxptr/VxB\nyJJSi0sjTpqmWKStBjeZlEYq57nWZLmueA9xf8T1Ah6WRDRFo8m1\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen141 = 1107; + +static const char *kData141[] = { + "-----BEGIN CERTIFICATE-----\nMIIDBTCCAb2gAwIBAgIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa\nMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIDAUMRIwEAYDVQQDDAlCb3Jp\nbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAG\nA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkW\nf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQS\njHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy\n8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50\n+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk\n7ZE1QJQQ1L4iKmPeQistuQIDAQABMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUD\nBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgA4IBAQAss/sOR0J5\nrAmctg1qnUYeUKr3RN2MTAb58ZsbE9Gvjr4lgdRo4ADIwqfKYcEe3Xms0WO8gAle\nefbzrcqM1wZ6wjdcZEI9xz2L5moX0lD40Jd18OFe4wrmt7eMCaz+gTdHx+5uQy53\n4H+Vw6IUeO9m1K1wqDkwsiPWv22FqKghD07wKiNR7bkPnQDERRRN6UliCFfMEXOx\nh9IbYJQUIVvBFqkI9C/lKbrmxdS7fv3wFnu61knkh7JNIXXWNdYHHRDqNDZOhakn\n0wf3qY359CofKk+9kg/9cj1lP8HwgATxL69pBmSvM7O6ybDRhp4+/oySQCbcOIfs\nIOo8AoyPo4u2\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen142 = 1139; + +static const char *kData142[] = { + "-----BEGIN CERTIFICATE-----\nMIIDGzCCAcigAwIBAgIBADBIBgkqhkiG9w0BAQowO6APMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogoCCEAAAAAAAAAgMBQxEjAQ\nBgNVBAMMCUJvcmluZ1NTTDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1\nOTU5WjAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQC6C9qEGRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4\nRayxkFwemtnkGRZ/o94ZnsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGi\nJcLN6kGuG2nlRBKMcPgPiEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpn\nUCTL5o2VwyPoxjLxT5gUR69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh\n4izZHrktR25MvnT5QyBq32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6C\neYRPX1Ykfg+sXCTtkTVAlBDUviIqY95CKy25AgMBAAEwSAYJKoZIhvcNAQEKMDug\nDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIK\nAghAAAAAAAAAIAOCAQEAn7ufGUhwZUfP13AEXFZGo7tpWYKbiDpVnHTtj/21/SWd\nTXP1LJWIJuo8pGs/ZsXI+XoXJMk01G1wVPPUny/D7T9WXLW191UFzIGO0bJZIfv2\nM9YbRkTsCiAYUuyFUlwwSLMqMXrZjRXlgulv3DjWrDHrAqfst847Ety24P1uYG7C\nm4JV8Sa0SIKRntd00YYmk6oUZNgEzUps7moLsOEox3U2s6wTipl/++9H5CI5mQTS\nfdGMRzEsuJRfXkgMccEfDw2wvNfmNzILGDsvxjCilkEisuMPxlRptSk5agYFujAW\nD3QjJGCgGlSXhN3JuH9S2/0N5gRQpN/98beTTXpxvg==\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen143 = 1119; + +static const char *kData143[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCAR8wFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCAR8DggEB\nACRCt8NtcKkDg86ub1PiWSws4b/5v9ujPbatTrocCOXnob3Z4dnHKpjeUC0et/ex\ns4hlluZ9WHb+WgR5LP7I1eIE5C1RIL5aVLguSBi8/qQICNVgeMvZSgv/mDJ0eiv2\nxztcYlDwANPIh2RDpVyD6qUphvH8W6vrd6mo3aYgegigaDr/8d01MZh5s4120iWn\n+8XKXNep8YqLhYemn3WeXtvK4vEEdFln6WeRRlGKevX9LqOegshs8HgKjjYRH++I\nc5HtwRZFkkMnXOV0XyG5zPrsx0qDcJCGHrC20bM+ZZz60QOtb1BSMIS5KjMy5OPQ\nbueM0YwX72tPKox+3lJgXAk=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen144 = 1127; + +static const char *kData144[] = { + "-----BEGIN CERTIFICATE-----\nMIIDEzCCAcSgAwIBAgIBADBEBgkqhkiG9w0BAQowN6APMA0GCWCGSAFlAwQCAQUA\noR8wHQYMKoZIhvcSBAGEtwkAMA0GCWCGSAFlAwQCAQUAogMCASAwFDESMBAGA1UE\nAwwJQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTla\nMBQxEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQ\nXB6a2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3q\nQa4baeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvm\njZXDI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNke\nuS1Hbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9f\nViR+D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBEBgkqhkiG9w0BAQowN6APMA0G\nCWCGSAFlAwQCAQUAoR8wHQYMKoZIhvcSBAGEtwkAMA0GCWCGSAFlAwQCAQUAogMC\nASADggEBACdP7ToiiM+6TqeAbKRqsPuFX9Q0qJtjX8mGVyzOEy402hEhglMeL9il\nFFFKCgo/wux4VIbw7BVLFDfYPcj8E7snj+J0mITIFt5oCwXG+MrJUnfklBEEyelF\nkVyr1ZVIwsk/lWSaOcQocbx8/szRRhwwVTT7BySnMV4e/y7Z9beye6tl7lg4373K\nE4akVubalnkoTHP5fZ6f0AfOXJEnLw2Mn0zjwrZmasMyXxLH8ApUVruPBQHY7IQB\nsMAURzkRtcCyzhQniJFcu7oMmkj+v8FVG02792DOWP+Y/yC0ccmHcvDbdzJW5SDm\nrBvNkmnPt6sYs7/RLRaVky7cRMAQrFs=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen145 = 1243; + +static const char *kData145[] = { + "This certificate has a trailerField of 2, but the signature was still\ngenerated with the standard 0xbc suffix.\n\n-----BEGIN CERTIFICATE-----\nMIIDFzCCAcagAwIBAgIBADBGBgkqhkiG9w0BAQowOaAPMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASCjAwIBAjAUMRIwEAYD\nVQQDDAlCb3JpbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1\nOVowFDESMBAGA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWs\nsZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXC\nzepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Ak\ny+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs\n2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmE\nT19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABMEYGCSqGSIb3DQEBCjA5oA8w\nDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIB\nIKMDAgECA4IBAQCVtDpbDRnbn7UQd8sPq+XSHk2nwvlhwSKZ0XZ0vwBGkNuhO/SY\nBhVUez+uGxXnJE+MkVAAh3NOdEQV6apEX5tymCyB0vqwLQB86gANOt82kF/tOW4M\nSv5f6L8GJbYtpTd/cyAMEs7U/X9O5W1G9sLINWeukUYHPVKjj/tE3NfLCE8SWlw4\nSCnbuhs5WXnEgUP/9JgL8xyI6bxn9E2OUvqD+U24k0PbtAdk09697gUYUDQlmxi6\nMRoQYKTezNJt4DXRhqUlokWiF5D42MaMz5WXtLQaBfbqQB6n1Ln+hTaGwWP6xNSm\nMip0TYOwAQdcTvr8UoQUJR/90SX+S4m6cu4d\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen146 = 1119; + +static const char *kData146[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASADggEB\nALVhRTv78XF2RjMusWAuTknDWkju6uvtq+iTpwCWaJO2QA2L3spEiUw52PsW9gQW\nAIOttLlgQFPD3dt3OL0FBK5y79Rh/h/mrOpwbVoMOHSsgikVZhbQ0D30Y8LQYMTD\ncxDYgPbnI4Q1VatdcCR8aavSDfV4JGPpJPkz8QX6HaFAoCUAz5UhiiS3MT8IzucO\nnNOV7AH9yfWDfvCWDGyuIYphjFZ761VjZFFIGJuXZ9uDXDDjNxlLwO7sci/pwO89\nOiRM40RxkS9vl8MjIsFSMGXOR+mf+FNtQ2vF1ZqCVxPWFuHHwmXycqrLuY3fOboF\ntF5Q3O1V7sh5Bs47h29KbQU=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen147 = 1119; + +static const char *kData147[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAgUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATAwFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCAgUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATADggEB\nAASUWBIEjb0TkXJKhj3RNRRe0D+KWFpyAn/kdBgDce/LEQVywj8IeS+s9z9TcGEK\niKr8tPIsNUM1agj3gd1zWuM5rbUABQyGzeWcfjmhmhK5mnCSOu/OD+DJjWqyHpQq\n/Qf2djrpXJXKVNoSBzci4KUpFIfKMT4KjnUKY9L8lxfl9zaPeIaFeXgtyhHYnpjX\nvyomoLaL3cXeeKIffgPa9s9QZGx2fKOnFmcS3eKL9pIcj4Z6K8+Nchg6Z2qYKWtM\nhH1ZFlNDC3VOPgNkHoBrU6gE5fQv6lO64egL9pM0bpaOi7drhHKjkw2URi4C9KGK\nP9GfRmqV9Y9UlJsLSGIghxs=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen148 = 1119; + +static const char *kData148[] = { + "-----BEGIN CERTIFICATE-----\nMIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwFDESMBAGA1UEAwwJ\nQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx\nEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a\n2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b\naeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD\nI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H\nbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+\nD6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG\nSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEB\nADwQHPC6MMvgBBfgYHRvcdQqfzPb3I9HJa+Y01BAIAeICadmyB389cjhv9X1mFi9\nxJOhsuek71D4YrOghExMbGXIAlalAq/rQHTzXV6cqiSrbUmmvsLmlilOeODIjuUC\nz3Ldc5LvwU8nima46jP/ryMYaIjCpbNsH/MzAbYO/CNm8osjeJoKhGyozkj9tr2T\nJaSFe5icta2WHfjfLP7wSkIf3NdfXNkBIBKMdHCuiEgeUeSColpgAFfngFKIJ3EG\nEbgptjPoePJ0T6VOdwzSX+QhGLabaOiX0ptrhAwuCNHVAKuf5wCWKvl6mYgBaDfB\nYFmL46BAX2ghB+WM/FSizPs=\n-----END CERTIFICATE-----\n", +}; +static const size_t kLen149 = 13599; + +static const char *kData149[] = { "-----BEGIN CERTIFICATE-----\nMIInDDCCJfSgAwIBAgIBBTANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowghmkMRAwDgYDVQQDEwd0\nMC50ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nMUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nM0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nNUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nN0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0OEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nOUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTBAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDExQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxMkB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0MTNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDE0QHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQxNUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTZAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDE3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxOEB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0MTlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDIwQHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQyMUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjJAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDIzQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQyNEB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0MjVAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDI2QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQyN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjhAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDI5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzMEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDMy\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzM0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nMzRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDM1QHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQzNkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzdAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDM4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzOUB0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0NDBAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQxQHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ0MkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDNAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDQ0QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ0NUB0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0NDZAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQ3QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ0OEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDlAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDUwQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1MUB0ZXN0\nMRcwFQYJKoZIhvcNAQkBFgh0NTJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDUzQHRl\nc3QxFzAVBgkqhkiG9w0BCQEWCHQ1NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NTVA\ndGVzdDEXMBUGCSqGSIb3DQEJARYIdDU2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1\nN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NThAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDU5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2MEB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0NjFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDYyQHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQ2M0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NjRAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDY1QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2NkB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0NjdAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDY4QHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQ2OUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzBAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDcxQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3MkB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0NzNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDc0QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQ3NUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzZAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDc3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3OEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgw\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4MUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nODJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgzQHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQ4NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0ODVAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDg2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4N0B0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0ODhAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDg5QHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ5MEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTFAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDkyQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5M0B0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0OTRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDk1QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ5NkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTdAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDk4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTAwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTAzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEwNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTA2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTA5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDExMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTEyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEx\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTE1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxMTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDExN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTE4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDEyMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTIxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxMjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTI0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTI3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEyOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTMwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEzMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTMzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDEzNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEz\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTQyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE0NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTQ1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTQ4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTUxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE1M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTU0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTU3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE1OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTY2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE2OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTY5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTcyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTc1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE3N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTc4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTgxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxODJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE4M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxODVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxODhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTkwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE5MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTkzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxOTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTk2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTk5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIwMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjAyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIwNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjA1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIwN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjA4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIx\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjExQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjE0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDIxNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjE3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyMThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjIwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjIzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIyNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjI2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjI5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIzMUB0ZXN0MRgwFgY", "JKoZIhvcNAQkBFgl0MjMyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIz\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjM1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIzN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjM4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI0MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjQxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjQ0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI0OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjUwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjUzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI1NUB0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWs\nsZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXC\nzepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Ak\ny+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs\n2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmE\nT19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABo4IK2jCCCtYwDgYDVR0PAQH/\nBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwggqfBgNV\nHREEggqWMIIKkoIHdDAudGVzdIIHdDEudGVzdIIHdDIudGVzdIIHdDMudGVzdIIH\ndDQudGVzdIIHdDUudGVzdIIHdDYudGVzdIIHdDcudGVzdIIHdDgudGVzdIIHdDku\ndGVzdIIIdDEwLnRlc3SCCHQxMS50ZXN0ggh0MTIudGVzdIIIdDEzLnRlc3SCCHQx\nNC50ZXN0ggh0MTUudGVzdIIIdDE2LnRlc3SCCHQxNy50ZXN0ggh0MTgudGVzdIII\ndDE5LnRlc3SCCHQyMC50ZXN0ggh0MjEudGVzdIIIdDIyLnRlc3SCCHQyMy50ZXN0\nggh0MjQudGVzdIIIdDI1LnRlc3SCCHQyNi50ZXN0ggh0MjcudGVzdIIIdDI4LnRl\nc3SCCHQyOS50ZXN0ggh0MzAudGVzdIIIdDMxLnRlc3SCCHQzMi50ZXN0ggh0MzMu\ndGVzdIIIdDM0LnRlc3SCCHQzNS50ZXN0ggh0MzYudGVzdIIIdDM3LnRlc3SCCHQz\nOC50ZXN0ggh0MzkudGVzdIIIdDQwLnRlc3SCCHQ0MS50ZXN0ggh0NDIudGVzdIII\ndDQzLnRlc3SCCHQ0NC50ZXN0ggh0NDUudGVzdIIIdDQ2LnRlc3SCCHQ0Ny50ZXN0\nggh0NDgudGVzdIIIdDQ5LnRlc3SCCHQ1MC50ZXN0ggh0NTEudGVzdIIIdDUyLnRl\nc3SCCHQ1My50ZXN0ggh0NTQudGVzdIIIdDU1LnRlc3SCCHQ1Ni50ZXN0ggh0NTcu\ndGVzdIIIdDU4LnRlc3SCCHQ1OS50ZXN0ggh0NjAudGVzdIIIdDYxLnRlc3SCCHQ2\nMi50ZXN0ggh0NjMudGVzdIIIdDY0LnRlc3SCCHQ2NS50ZXN0ggh0NjYudGVzdIII\ndDY3LnRlc3SCCHQ2OC50ZXN0ggh0NjkudGVzdIIIdDcwLnRlc3SCCHQ3MS50ZXN0\nggh0NzIudGVzdIIIdDczLnRlc3SCCHQ3NC50ZXN0ggh0NzUudGVzdIIIdDc2LnRl\nc3SCCHQ3Ny50ZXN0ggh0NzgudGVzdIIIdDc5LnRlc3SCCHQ4MC50ZXN0ggh0ODEu\ndGVzdIIIdDgyLnRlc3SCCHQ4My50ZXN0ggh0ODQudGVzdIIIdDg1LnRlc3SCCHQ4\nNi50ZXN0ggh0ODcudGVzdIIIdDg4LnRlc3SCCHQ4OS50ZXN0ggh0OTAudGVzdIII\ndDkxLnRlc3SCCHQ5Mi50ZXN0ggh0OTMudGVzdIIIdDk0LnRlc3SCCHQ5NS50ZXN0\nggh0OTYudGVzdIIIdDk3LnRlc3SCCHQ5OC50ZXN0ggh0OTkudGVzdIIJdDEwMC50\nZXN0ggl0MTAxLnRlc3SCCXQxMDIudGVzdIIJdDEwMy50ZXN0ggl0MTA0LnRlc3SC\nCXQxMDUudGVzdIIJdDEwNi50ZXN0ggl0MTA3LnRlc3SCCXQxMDgudGVzdIIJdDEw\nOS50ZXN0ggl0MTEwLnRlc3SCCXQxMTEudGVzdIIJdDExMi50ZXN0ggl0MTEzLnRl\nc3SCCXQxMTQudGVzdIIJdDExNS50ZXN0ggl0MTE2LnRlc3SCCXQxMTcudGVzdIIJ\ndDExOC50ZXN0ggl0MTE5LnRlc3SCCXQxMjAudGVzdIIJdDEyMS50ZXN0ggl0MTIy\nLnRlc3SCCXQxMjMudGVzdIIJdDEyNC50ZXN0ggl0MTI1LnRlc3SCCXQxMjYudGVz\ndIIJdDEyNy50ZXN0ggl0MTI4LnRlc3SCCXQxMjkudGVzdIIJdDEzMC50ZXN0ggl0\nMTMxLnRlc3SCCXQxMzIudGVzdIIJdDEzMy50ZXN0ggl0MTM0LnRlc3SCCXQxMzUu\ndGVzdIIJdDEzNi50ZXN0ggl0MTM3LnRlc3SCCXQxMzgudGVzdIIJdDEzOS50ZXN0\nggl0MTQwLnRlc3SCCXQxNDEudGVzdIIJdDE0Mi50ZXN0ggl0MTQzLnRlc3SCCXQx\nNDQudGVzdIIJdDE0NS50ZXN0ggl0MTQ2LnRlc3SCCXQxNDcudGVzdIIJdDE0OC50\nZXN0ggl0MTQ5LnRlc3SCCXQxNTAudGVzdIIJdDE1MS50ZXN0ggl0MTUyLnRlc3SC\nCXQxNTMudGVzdIIJdDE1NC50ZXN0ggl0MTU1LnRlc3SCCXQxNTYudGVzdIIJdDE1\nNy50ZXN0ggl0MTU4LnRlc3SCCXQxNTkudGVzdIIJdDE2MC50ZXN0ggl0MTYxLnRl\nc3SCCXQxNjIudGVzdIIJdDE2My50ZXN0ggl0MTY0LnRlc3SCCXQxNjUudGVzdIIJ\ndDE2Ni50ZXN0ggl0MTY3LnRlc3SCCXQxNjgudGVzdIIJdDE2OS50ZXN0ggl0MTcw\nLnRlc3SCCXQxNzEudGVzdIIJdDE3Mi50ZXN0ggl0MTczLnRlc3SCCXQxNzQudGVz\ndIIJdDE3NS50ZXN0ggl0MTc2LnRlc3SCCXQxNzcudGVzdIIJdDE3OC50ZXN0ggl0\nMTc5LnRlc3SCCXQxODAudGVzdIIJdDE4MS50ZXN0ggl0MTgyLnRlc3SCCXQxODMu\ndGVzdIIJdDE4NC50ZXN0ggl0MTg1LnRlc3SCCXQxODYudGVzdIIJdDE4Ny50ZXN0\nggl0MTg4LnRlc3SCCXQxODkudGVzdIIJdDE5MC50ZXN0ggl0MTkxLnRlc3SCCXQx\nOTIudGVzdIIJdDE5My50ZXN0ggl0MTk0LnRlc3SCCXQxOTUudGVzdIIJdDE5Ni50\nZXN0ggl0MTk3LnRlc3SCCXQxOTgudGVzdIIJdDE5OS50ZXN0ggl0MjAwLnRlc3SC\nCXQyMDEudGVzdIIJdDIwMi50ZXN0ggl0MjAzLnRlc3SCCXQyMDQudGVzdIIJdDIw\nNS50ZXN0ggl0MjA2LnRlc3SCCXQyMDcudGVzdIIJdDIwOC50ZXN0ggl0MjA5LnRl\nc3SCCXQyMTAudGVzdIIJdDIxMS50ZXN0ggl0MjEyLnRlc3SCCXQyMTMudGVzdIIJ\ndDIxNC50ZXN0ggl0MjE1LnRlc3SCCXQyMTYudGVzdIIJdDIxNy50ZXN0ggl0MjE4\nLnRlc3SCCXQyMTkudGVzdIIJdDIyMC50ZXN0ggl0MjIxLnRlc3SCCXQyMjIudGVz\ndIIJdDIyMy50ZXN0ggl0MjI0LnRlc3SCCXQyMjUudGVzdIIJdDIyNi50ZXN0ggl0\nMjI3LnRlc3SCCXQyMjgudGVzdIIJdDIyOS50ZXN0ggl0MjMwLnRlc3SCCXQyMzEu\ndGVzdIIJdDIzMi50ZXN0ggl0MjMzLnRlc3SCCXQyMzQudGVzdIIJdDIzNS50ZXN0\nggl0MjM2LnRlc3SCCXQyMzcudGVzdIIJdDIzOC50ZXN0ggl0MjM5LnRlc3SCCXQy\nNDAudGVzdIIJdDI0MS50ZXN0ggl0MjQyLnRlc3SCCXQyNDMudGVzdIIJdDI0NC50\nZXN0ggl0MjQ1LnRlc3SCCXQyNDYudGVzdIIJdDI0Ny50ZXN0ggl0MjQ4LnRlc3SC\nCXQyNDkudGVzdIIJdDI1MC50ZXN0ggl0MjUxLnRlc3SCCXQyNTIudGVzdIIJdDI1\nMy50ZXN0ggl0MjU0LnRlc3SCCXQyNTUudGVzdDANBgkqhkiG9w0BAQsFAAOCAQEA\nJIFn5ymMVnj0DOFldXQzAjaosat0Z1dAca0BFO/4bf+IfvpaLvZCiSucInV0ejgR\ndP3UsoiXV8qXBax1nr5t4k+yOGYbhgj3imHFtKhFaqJ45AqEJOmzCHWIN0LkN+YL\nME6JBJr86EB+diLPBS7iljmtvN7avvmJ8AbGFI6eB5BwSjewavWpv55u52zMWti7\nCa2WpKffH74zhnGqkbMzEiiRa1L1+H/uQBJ0BEeAZbr+pSkJZJvzY/eH8a7fLHra\nLfBqD4epDm6RI6gSNeJ+G7qSfpVSk7l9bsVh7rUTSSCKBxhcImudqBuLfswoa0Ub\nZoA33vstMRAur0m/blHQHA==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen96 = 8557; +static const size_t kLen150 = 8557; -static const char *kData96[] = { +static const char *kData150[] = { "-----BEGIN CERTIFICATE-----\nMIIYgzCCF2ugAwIBAgIBBjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowEjEQMA4GA1UEAxMHdDAu\ndGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoL2oQZEgFBdXwu\nPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a2eQZFn+j3hmexeQF9T8i\nWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4baeVEEoxw+A+ISrYHTIFc\nV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXDI+jGMvFPmBRHr2/1dJUW\nPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1Hbky+dPlDIGrfaHHsCNnb\n/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+D6xcJO2RNUCUENS+Iipj\n3kIrLbkCAwEAAaOCFeUwghXhMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr\nBgEFBQcDATAMBgNVHRMBAf8EAjAAMIIVqgYDVR0RBIIVoTCCFZ2CB3QwLnRlc3SC\nB3QxLnRlc3SCB3QyLnRlc3SCB3QzLnRlc3SCB3Q0LnRlc3SCB3Q1LnRlc3SCB3Q2\nLnRlc3SCB3Q3LnRlc3SCB3Q4LnRlc3SCB3Q5LnRlc3SCCHQxMC50ZXN0ggh0MTEu\ndGVzdIIIdDEyLnRlc3SCCHQxMy50ZXN0ggh0MTQudGVzdIIIdDE1LnRlc3SCCHQx\nNi50ZXN0ggh0MTcudGVzdIIIdDE4LnRlc3SCCHQxOS50ZXN0ggh0MjAudGVzdIII\ndDIxLnRlc3SCCHQyMi50ZXN0ggh0MjMudGVzdIIIdDI0LnRlc3SCCHQyNS50ZXN0\nggh0MjYudGVzdIIIdDI3LnRlc3SCCHQyOC50ZXN0ggh0MjkudGVzdIIIdDMwLnRl\nc3SCCHQzMS50ZXN0ggh0MzIudGVzdIIIdDMzLnRlc3SCCHQzNC50ZXN0ggh0MzUu\ndGVzdIIIdDM2LnRlc3SCCHQzNy50ZXN0ggh0MzgudGVzdIIIdDM5LnRlc3SCCHQ0\nMC50ZXN0ggh0NDEudGVzdIIIdDQyLnRlc3SCCHQ0My50ZXN0ggh0NDQudGVzdIII\ndDQ1LnRlc3SCCHQ0Ni50ZXN0ggh0NDcudGVzdIIIdDQ4LnRlc3SCCHQ0OS50ZXN0\nggh0NTAudGVzdIIIdDUxLnRlc3SCCHQ1Mi50ZXN0ggh0NTMudGVzdIIIdDU0LnRl\nc3SCCHQ1NS50ZXN0ggh0NTYudGVzdIIIdDU3LnRlc3SCCHQ1OC50ZXN0ggh0NTku\ndGVzdIIIdDYwLnRlc3SCCHQ2MS50ZXN0ggh0NjIudGVzdIIIdDYzLnRlc3SCCHQ2\nNC50ZXN0ggh0NjUudGVzdIIIdDY2LnRlc3SCCHQ2Ny50ZXN0ggh0NjgudGVzdIII\ndDY5LnRlc3SCCHQ3MC50ZXN0ggh0NzEudGVzdIIIdDcyLnRlc3SCCHQ3My50ZXN0\nggh0NzQudGVzdIIIdDc1LnRlc3SCCHQ3Ni50ZXN0ggh0NzcudGVzdIIIdDc4LnRl\nc3SCCHQ3OS50ZXN0ggh0ODAudGVzdIIIdDgxLnRlc3SCCHQ4Mi50ZXN0ggh0ODMu\ndGVzdIIIdDg0LnRlc3SCCHQ4NS50ZXN0ggh0ODYudGVzdIIIdDg3LnRlc3SCCHQ4\nOC50ZXN0ggh0ODkudGVzdIIIdDkwLnRlc3SCCHQ5MS50ZXN0ggh0OTIudGVzdIII\ndDkzLnRlc3SCCHQ5NC50ZXN0ggh0OTUudGVzdIIIdDk2LnRlc3SCCHQ5Ny50ZXN0\nggh0OTgudGVzdIIIdDk5LnRlc3SCCXQxMDAudGVzdIIJdDEwMS50ZXN0ggl0MTAy\nLnRlc3SCCXQxMDMudGVzdIIJdDEwNC50ZXN0ggl0MTA1LnRlc3SCCXQxMDYudGVz\ndIIJdDEwNy50ZXN0ggl0MTA4LnRlc3SCCXQxMDkudGVzdIIJdDExMC50ZXN0ggl0\nMTExLnRlc3SCCXQxMTIudGVzdIIJdDExMy50ZXN0ggl0MTE0LnRlc3SCCXQxMTUu\ndGVzdIIJdDExNi50ZXN0ggl0MTE3LnRlc3SCCXQxMTgudGVzdIIJdDExOS50ZXN0\nggl0MTIwLnRlc3SCCXQxMjEudGVzdIIJdDEyMi50ZXN0ggl0MTIzLnRlc3SCCXQx\nMjQudGVzdIIJdDEyNS50ZXN0ggl0MTI2LnRlc3SCCXQxMjcudGVzdIIJdDEyOC50\nZXN0ggl0MTI5LnRlc3SCCXQxMzAudGVzdIIJdDEzMS50ZXN0ggl0MTMyLnRlc3SC\nCXQxMzMudGVzdIIJdDEzNC50ZXN0ggl0MTM1LnRlc3SCCXQxMzYudGVzdIIJdDEz\nNy50ZXN0ggl0MTM4LnRlc3SCCXQxMzkudGVzdIIJdDE0MC50ZXN0ggl0MTQxLnRl\nc3SCCXQxNDIudGVzdIIJdDE0My50ZXN0ggl0MTQ0LnRlc3SCCXQxNDUudGVzdIIJ\ndDE0Ni50ZXN0ggl0MTQ3LnRlc3SCCXQxNDgudGVzdIIJdDE0OS50ZXN0ggl0MTUw\nLnRlc3SCCXQxNTEudGVzdIIJdDE1Mi50ZXN0ggl0MTUzLnRlc3SCCXQxNTQudGVz\ndIIJdDE1NS50ZXN0ggl0MTU2LnRlc3SCCXQxNTcudGVzdIIJdDE1OC50ZXN0ggl0\nMTU5LnRlc3SCCXQxNjAudGVzdIIJdDE2MS50ZXN0ggl0MTYyLnRlc3SCCXQxNjMu\ndGVzdIIJdDE2NC50ZXN0ggl0MTY1LnRlc3SCCXQxNjYudGVzdIIJdDE2Ny50ZXN0\nggl0MTY4LnRlc3SCCXQxNjkudGVzdIIJdDE3MC50ZXN0ggl0MTcxLnRlc3SCCXQx\nNzIudGVzdIIJdDE3My50ZXN0ggl0MTc0LnRlc3SCCXQxNzUudGVzdIIJdDE3Ni50\nZXN0ggl0MTc3LnRlc3SCCXQxNzgudGVzdIIJdDE3OS50ZXN0ggl0MTgwLnRlc3SC\nCXQxODEudGVzdIIJdDE4Mi50ZXN0ggl0MTgzLnRlc3SCCXQxODQudGVzdIIJdDE4\nNS50ZXN0ggl0MTg2LnRlc3SCCXQxODcudGVzdIIJdDE4OC50ZXN0ggl0MTg5LnRl\nc3SCCXQxOTAudGVzdIIJdDE5MS50ZXN0ggl0MTkyLnRlc3SCCXQxOTMudGVzdIIJ\ndDE5NC50ZXN0ggl0MTk1LnRlc3SCCXQxOTYudGVzdIIJdDE5Ny50ZXN0ggl0MTk4\nLnRlc3SCCXQxOTkudGVzdIIJdDIwMC50ZXN0ggl0MjAxLnRlc3SCCXQyMDIudGVz\ndIIJdDIwMy50ZXN0ggl0MjA0LnRlc3SCCXQyMDUudGVzdIIJdDIwNi50ZXN0ggl0\nMjA3LnRlc3SCCXQyMDgudGVzdIIJdDIwOS50ZXN0ggl0MjEwLnRlc3SCCXQyMTEu\ndGVzdIIJdDIxMi50ZXN0ggl0MjEzLnRlc3SCCXQyMTQudGVzdIIJdDIxNS50ZXN0\nggl0MjE2LnRlc3SCCXQyMTcudGVzdIIJdDIxOC50ZXN0ggl0MjE5LnRlc3SCCXQy\nMjAudGVzdIIJdDIyMS50ZXN0ggl0MjIyLnRlc3SCCXQyMjMudGVzdIIJdDIyNC50\nZXN0ggl0MjI1LnRlc3SCCXQyMjYudGVzdIIJdDIyNy50ZXN0ggl0MjI4LnRlc3SC\nCXQyMjkudGVzdIIJdDIzMC50ZXN0ggl0MjMxLnRlc3SCCXQyMzIudGVzdIIJdDIz\nMy50ZXN0ggl0MjM0LnRlc3SCCXQyMzUudGVzdIIJdDIzNi50ZXN0ggl0MjM3LnRl\nc3SCCXQyMzgudGVzdIIJdDIzOS50ZXN0ggl0MjQwLnRlc3SCCXQyNDEudGVzdIIJ\ndDI0Mi50ZXN0ggl0MjQzLnRlc3SCCXQyNDQudGVzdIIJdDI0NS50ZXN0ggl0MjQ2\nLnRlc3SCCXQyNDcudGVzdIIJdDI0OC50ZXN0ggl0MjQ5LnRlc3SCCXQyNTAudGVz\ndIIJdDI1MS50ZXN0ggl0MjUyLnRlc3SCCXQyNTMudGVzdIIJdDI1NC50ZXN0ggl0\nMjU1LnRlc3SCCXQyNTYudGVzdIIJdDI1Ny50ZXN0ggl0MjU4LnRlc3SCCXQyNTku\ndGVzdIIJdDI2MC50ZXN0ggl0MjYxLnRlc3SCCXQyNjIudGVzdIIJdDI2My50ZXN0\nggl0MjY0LnRlc3SCCXQyNjUudGVzdIIJdDI2Ni50ZXN0ggl0MjY3LnRlc3SCCXQy\nNjgudGVzdIIJdDI2OS50ZXN0ggl0MjcwLnRlc3SCCXQyNzEudGVzdIIJdDI3Mi50\nZXN0ggl0MjczLnRlc3SCCXQyNzQudGVzdIIJdDI3NS50ZXN0ggl0Mjc2LnRlc3SC\nCXQyNzcudGVzdIIJdDI3OC50ZXN0ggl0Mjc5LnRlc3SCCXQyODAudGVzdIIJdDI4\nMS50ZXN0ggl0MjgyLnRlc3SCCXQyODMudGVzdIIJdDI4NC50ZXN0ggl0Mjg1LnRl\nc3SCCXQyODYudGVzdIIJdDI4Ny50ZXN0ggl0Mjg4LnRlc3SCCXQyODkudGVzdIIJ\ndDI5MC50ZXN0ggl0MjkxLnRlc3SCCXQyOTIudGVzdIIJdDI5My50ZXN0ggl0Mjk0\nLnRlc3SCCXQyOTUudGVzdIIJdDI5Ni50ZXN0ggl0Mjk3LnRlc3SCCXQyOTgudGVz\ndIIJdDI5OS50ZXN0ggl0MzAwLnRlc3SCCXQzMDEudGVzdIIJdDMwMi50ZXN0ggl0\nMzAzLnRlc3SCCXQzMDQudGVzdIIJdDMwNS50ZXN0ggl0MzA2LnRlc3SCCXQzMDcu\ndGVzdIIJdDMwOC50ZXN0ggl0MzA5LnRlc3SCCXQzMTAudGVzdIIJdDMxMS50ZXN0\nggl0MzEyLnRlc3SCCXQzMTMudGVzdIIJdDMxNC50ZXN0ggl0MzE1LnRlc3SCCXQz\nMTYudGVzdIIJdDMxNy50ZXN0ggl0MzE4LnRlc3SCCXQzMTkudGVzdIIJdDMyMC50\nZXN0ggl0MzIxLnRlc3SCCXQzMjIudGVzdIIJdDMyMy50ZXN0ggl0MzI0LnRlc3SC\nCXQzMjUudGVzdIIJdDMyNi50ZXN0ggl0MzI3LnRlc3SCCXQzMjgudGVzdIIJdDMy\nOS50ZXN0ggl0MzMwLnRlc3SCCXQzMzEudGVzdIIJdDMzMi50ZXN0ggl0MzMzLnRl\nc3SCCXQzMzQudGVzdIIJdDMzNS50ZXN0ggl0MzM2LnRlc3SCCXQzMzcudGVzdIIJ\ndDMzOC50ZXN0ggl0MzM5LnRlc3SCCXQzNDAudGVzdIIJdDM0MS50ZXN0ggl0MzQy\nLnRlc3SCCXQzNDMudGVzdIIJdDM0NC50ZXN0ggl0MzQ1LnRlc3SCCXQzNDYudGVz\ndIIJdDM0Ny50ZXN0ggl0MzQ4LnRlc3SCCXQzNDkudGVzdIIJdDM1MC50ZXN0ggl0\nMzUxLnRlc3SCCXQzNTIudGVzdIIJdDM1My50ZXN0ggl0MzU0LnRlc3SCCXQzNTUu\ndGVzdIIJdDM1Ni50ZXN0ggl0MzU3LnRlc3SCCXQzNTgudGVzdIIJdDM1OS50ZXN0\nggl0MzYwLnRlc3SCCXQzNjEudGVzdIIJdDM2Mi50ZXN0ggl0MzYzLnRlc3SCCXQz\nNjQudGVzdIIJdDM2NS50ZXN0ggl0MzY2LnRlc3SCCXQzNjcudGVzdIIJdDM2OC50\nZXN0ggl0MzY5LnRlc3SCCXQzNzAudGVzdIIJdDM3MS50ZXN0ggl0MzcyLnRlc3SC\nCXQzNzMudGVzdIIJdDM3NC50ZXN0ggl0Mzc1LnRlc3SCCXQzNzYudGVzdIIJdDM3\nNy50ZXN0ggl0Mzc4LnRlc3SCCXQzNzkudGVzdIIJdDM4MC50ZXN0ggl0MzgxLnRl\nc3SCCXQzODIudGVzdIIJdDM4My50ZXN0ggl0Mzg0LnRlc3SCCXQzODUudGVzdIIJ\ndDM4Ni50ZXN0ggl0Mzg3LnRlc3SCCXQzODgudGVzdIIJdDM4OS50ZXN0ggl0Mzkw\nLnRlc3SCCXQzOTEudGVzdIIJdDM5Mi50ZXN0ggl0MzkzLnRlc3SCCXQzOTQudGVz\ndIIJdDM5NS50ZXN0ggl0Mzk2LnRlc3SCCXQzOTcudGVzdIIJdDM5OC50ZXN0ggl0\nMzk5LnRlc3SCCXQ0MDAudGVzdIIJdDQwMS50ZXN0ggl0NDAyLnRlc3SCCXQ0MDMu\ndGVzdIIJdDQwNC50ZXN0ggl0NDA1LnRlc3SCCXQ0MDYudGVzdIIJdDQwNy50ZXN0\nggl0NDA4LnRlc3SCCXQ0MDkudGVzdIIJdDQxMC50ZXN0ggl0NDExLnRlc3SCCXQ0\nMTIudGVzdIIJdDQxMy50ZXN0ggl0NDE0LnRlc3SCCXQ0MTUudGVzdIIJdDQxNi50\nZXN0ggl0NDE3LnRlc3SCCXQ0MTgudGVzdIIJdDQxOS50ZXN0ggl0NDIwLnRlc3SC\nCXQ0MjEudGVzdIIJdDQyMi50ZXN0ggl0NDIzLnRlc3SCCXQ0MjQudGVzdIIJdDQy\nNS50ZXN0ggl0NDI2LnRlc3SCCXQ0MjcudGVzdIIJdDQyOC50ZXN0ggl0NDI5LnRl\nc3SCCXQ0MzAudGVzdIIJdDQzMS50ZXN0ggl0NDMyLnRlc3SCCXQ0MzMudGVzdIIJ\ndDQzNC50ZXN0ggl0NDM1LnRlc3SCCXQ0MzYudGVzdIIJdDQzNy50ZXN0ggl0NDM4\nLnRlc3SCCXQ0MzkudGVzdIIJdDQ0MC50ZXN0ggl0NDQxLnRlc3SCCXQ0NDIudGVz\ndIIJdDQ0My50ZXN0ggl0NDQ0LnRlc3SCCXQ0NDUudGVzdIIJdDQ0Ni50ZXN0ggl0\nNDQ3LnRlc3SCCXQ0NDgudGVzdIIJdDQ0OS50ZXN0ggl0NDUwLnRlc3SCCXQ0NTEu\ndGVzdIIJdDQ1Mi50ZXN0ggl0NDUzLnRlc3SCCXQ0NTQudGVzdIIJdDQ1NS50ZXN0\nggl0NDU2LnRlc3SCCXQ0NTcudGVzdIIJdDQ1OC50ZXN0ggl0NDU5LnRlc3SCCXQ0\nNjAudGVzdIIJdDQ2MS50ZXN0ggl0NDYyLnRlc3SCCXQ0NjMudGVzdIIJdDQ2NC50\nZXN0ggl0NDY1LnRlc3SCCXQ0NjYudGVzdIIJdDQ2Ny50ZXN0ggl0NDY4LnRlc3SC\nCXQ0NjkudGVzdIIJdDQ3MC50ZXN0ggl0NDcxLnRlc3SCCXQ0NzIudGVzdIIJdDQ3\nMy50ZXN0ggl0NDc0LnRlc3SCCXQ0NzUudGVzdIIJdDQ3Ni50ZXN0ggl0NDc3LnRl\nc3SCCXQ0NzgudGVzdIIJdDQ3OS50ZXN0ggl0NDgwLnRlc3SCCXQ0ODEudGVzdIIJ\ndDQ4Mi50ZXN0ggl0NDgzLnRlc3SCCXQ0ODQudGVzdIIJdDQ4NS50ZXN0ggl0NDg2\nLnRlc3SCCXQ0ODcudGVzdIIJdDQ4OC50ZXN0ggl0NDg5LnRlc3SCCXQ0OTAudGVz\ndIIJdDQ5MS50ZXN0ggl0NDkyLnRlc3SCCXQ0OTMudGVzdIIJdDQ5NC50ZXN0ggl0\nNDk1LnRlc3SCCXQ0OTYudGVzdIIJdDQ5Ny50ZXN0ggl0NDk4LnRlc3SCCXQ0OTku\ndGVzdIIJdDUwMC50ZXN0ggl0NTAxLnRlc3SCCXQ1MDIudGVzdIIJdDUwMy50ZXN0\nggl0NTA0LnRlc3SCCXQ1MDUudGVzdIIJdDUwNi50ZXN0ggl0NTA3LnRlc3SCCXQ1\nMDgudGVzdIIJdDUwOS50ZXN0ggl0NTEwLnRlc3SCCXQ1MTEudGVzdIIJdDUxMi50\nZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQBjxDfYTob", "CREWVHPrt1T9iT2t0gieS7hVw\nlQaezO1n+m0MerQ92DHhMXBROBiMXIWyvTa341xClpYAwPqqAIUEdS0L5r4Jq/Ep\n4uglb+eZXMvTAm89KH3L8xTugc8UtHMqbfyo92v96wgFXBrcDDXIkGdPkLyz2s2J\nQjpNVG/La/EYTQdHPgv6Rg0g+t6RNN1JJ0p1wQ5ItDc8d/bfWdlG/EViWVRsiSBh\n7YRbkGWdnHnorCe0yIg0jKCk3UhgXaYY66/alpmE/QVXSaLgNvdmJ5m9mixY0ZaB\n0niy+KzIgBczvDcxVdL5/fsxGvA4nI8Gi7Z+EJDKXeED+FwcTDJD\n-----END CERTIFICATE-----\n", }; -static const size_t kLen97 = 18982; +static const size_t kLen151 = 18982; -static const char *kData97[] = { +static const char *kData151[] = { "-----BEGIN CERTIFICATE-----\nMII2kzCCNXugAwIBAgIBBzANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJDQTAg\nFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowgjO+MRAwDgYDVQQDEwd0\nMC50ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nMUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0MkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nM0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nNUB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0NkB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nN0B0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0OEB0ZXN0MRYwFAYJKoZIhvcNAQkBFgd0\nOUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTBAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDExQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxMkB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0MTNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDE0QHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQxNUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MTZAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDE3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQxOEB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0MTlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDIwQHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQyMUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjJAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDIzQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQyNEB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0MjVAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDI2QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQyN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MjhAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDI5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzMEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDMy\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzM0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nMzRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDM1QHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQzNkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0MzdAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDM4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQzOUB0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0NDBAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQxQHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ0MkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDNAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDQ0QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ0NUB0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0NDZAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDQ3QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ0OEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NDlAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDUwQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1MUB0ZXN0\nMRcwFQYJKoZIhvcNAQkBFgh0NTJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDUzQHRl\nc3QxFzAVBgkqhkiG9w0BCQEWCHQ1NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NTVA\ndGVzdDEXMBUGCSqGSIb3DQEJARYIdDU2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ1\nN0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NThAdGVzdDEXMBUGCSqGSIb3DQEJARYI\ndDU5QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2MEB0ZXN0MRcwFQYJKoZIhvcNAQkB\nFgh0NjFAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDYyQHRlc3QxFzAVBgkqhkiG9w0B\nCQEWCHQ2M0B0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NjRAdGVzdDEXMBUGCSqGSIb3\nDQEJARYIdDY1QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ2NkB0ZXN0MRcwFQYJKoZI\nhvcNAQkBFgh0NjdAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDY4QHRlc3QxFzAVBgkq\nhkiG9w0BCQEWCHQ2OUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzBAdGVzdDEXMBUG\nCSqGSIb3DQEJARYIdDcxQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3MkB0ZXN0MRcw\nFQYJKoZIhvcNAQkBFgh0NzNAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDc0QHRlc3Qx\nFzAVBgkqhkiG9w0BCQEWCHQ3NUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzZAdGVz\ndDEXMBUGCSqGSIb3DQEJARYIdDc3QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ3OEB0\nZXN0MRcwFQYJKoZIhvcNAQkBFgh0NzlAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgw\nQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4MUB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0\nODJAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDgzQHRlc3QxFzAVBgkqhkiG9w0BCQEW\nCHQ4NEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0ODVAdGVzdDEXMBUGCSqGSIb3DQEJ\nARYIdDg2QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ4N0B0ZXN0MRcwFQYJKoZIhvcN\nAQkBFgh0ODhAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDg5QHRlc3QxFzAVBgkqhkiG\n9w0BCQEWCHQ5MEB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTFAdGVzdDEXMBUGCSqG\nSIb3DQEJARYIdDkyQHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5M0B0ZXN0MRcwFQYJ\nKoZIhvcNAQkBFgh0OTRAdGVzdDEXMBUGCSqGSIb3DQEJARYIdDk1QHRlc3QxFzAV\nBgkqhkiG9w0BCQEWCHQ5NkB0ZXN0MRcwFQYJKoZIhvcNAQkBFgh0OTdAdGVzdDEX\nMBUGCSqGSIb3DQEJARYIdDk4QHRlc3QxFzAVBgkqhkiG9w0BCQEWCHQ5OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTAwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTAzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEwNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTA2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEwOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTA5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDExMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTEyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEx\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTE1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxMTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDExN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTE4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDEyMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTIxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxMjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyM0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTI0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDEyNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTI3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDEyOUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTMwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxMzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEzMkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTMzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDEzNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxMzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDEz\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTM5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTQyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE0NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTQ1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE0N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTQ4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTUxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE1M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTU0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE1NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTU3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE1OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTYzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxNjRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE2NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTY2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNjdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE2OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTY5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxNzBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTcyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE3NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTc1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxNzZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDE3N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTc4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQxNzlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4MEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MTgxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxODJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDE4M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQxODVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTg3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQxODhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE4OUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MTkwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDE5MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MTkzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQxOTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5NUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MTk2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQxOTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDE5OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMTk5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIwMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjAyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIwNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjA1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIwN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjA4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIx\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjExQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjE0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDIxNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjE3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyMThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIxOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjIwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjIzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMjRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDIyNUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjI2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyMjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIyOEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjI5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDIzMUB0ZXN0MRgwFgY", "JKoZIhvcNAQkBFgl0MjMyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIz\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjM1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyMzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDIzN0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjM4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyMzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI0MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjQxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNDJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjQ0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI0NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjQ3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNDhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI0OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjUwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MjUzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI1NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyNTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI1\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjU5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyNjBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MjYyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI2NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjY1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyNjZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI2N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjY4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNjlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjcxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI3M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjc0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyNzVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI3NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mjc3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyNzhAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDI3OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQyODFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MjgzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQyODRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI4NUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0Mjg2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyODdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDI4OEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjg5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQyOTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5MUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MjkyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDI5NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMjk1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQyOTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDI5N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mjk4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQyOTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzAxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMwM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMDVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMw\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzA3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMDhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMwOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzEwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMxMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzEzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMTRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzE2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMTdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDMxOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzE5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDMyMUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzIyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzMjNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMyNEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzI1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDMyN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzI4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzMjlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMz\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzMxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzMzJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzM0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzM0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzMzVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDMzNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzM3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzMzhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDMzOUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzQwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzQzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNDRAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM0NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzQ2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNDdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM0OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzQ5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM1MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzUyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzU1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzNTZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM1N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzU4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNTlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM2MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzYxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzNjJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0MzY0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM2NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzY3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNjhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM2OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0MzcwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzNzFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0MzczQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM3NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQzNzdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM3\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzc5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQzODBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4MUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0MzgyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDM4NEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzg1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQzODZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM4N0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0Mzg4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzODlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nMzkxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOTJAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDM5M0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0Mzk0QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQzOTVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDM5NkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0Mzk3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQzOThAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDM5OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAwQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQw\nMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDAzQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MDRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQwNUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDA2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MDdAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQwOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDA5QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MTBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxMUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDEyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTNA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQxNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDE1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MTZAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQxN0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDE4QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0MTlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyMEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDIxQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjJAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQyM0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI0QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MjVAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQy\nNkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDI3QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0MjhAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQyOUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDMwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzFAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQzMkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDMzQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0MzRAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzNUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDM2QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0MzdA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQzOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDM5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDBAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ0MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQyQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NDNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ0NEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDQ1QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDZAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ0N0B0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDQ4QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NDlAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1\nMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDUxQHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NTJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1M0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDU0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NTVAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ1NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDU3QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0NThAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ1OUB0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDYwQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjFA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2MkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDYzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NjRAd", "GVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ2NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDY2QHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0NjdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ2OEB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDY5QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzBAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ3MUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDcyQHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzNAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3\nNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDc1QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ0NzZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ3N0B0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NDc4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0NzlAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDQ4MEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDgxQHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ0ODJAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4M0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NDg0QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODVA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ4NkB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNDg3QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0ODhAdGVzdDEYMBYGCSqGSIb3DQEJ\nARYJdDQ4OUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDkwQHRlc3QxGDAWBgkqhkiG\n9w0BCQEWCXQ0OTFAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5MkB0ZXN0MRgwFgYJ\nKoZIhvcNAQkBFgl0NDkzQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTRAdGVzdDEY\nMBYGCSqGSIb3DQEJARYJdDQ5NUB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk2QHRl\nc3QxGDAWBgkqhkiG9w0BCQEWCXQ0OTdAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDQ5\nOEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NDk5QHRlc3QxGDAWBgkqhkiG9w0BCQEW\nCXQ1MDBAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwMUB0ZXN0MRgwFgYJKoZIhvcN\nAQkBFgl0NTAyQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDNAdGVzdDEYMBYGCSqG\nSIb3DQEJARYJdDUwNEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0NTA1QHRlc3QxGDAW\nBgkqhkiG9w0BCQEWCXQ1MDZAdGVzdDEYMBYGCSqGSIb3DQEJARYJdDUwN0B0ZXN0\nMRgwFgYJKoZIhvcNAQkBFgl0NTA4QHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MDlA\ndGVzdDEYMBYGCSqGSIb3DQEJARYJdDUxMEB0ZXN0MRgwFgYJKoZIhvcNAQkBFgl0\nNTExQHRlc3QxGDAWBgkqhkiG9w0BCQEWCXQ1MTJAdGVzdDCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmK\nM+EKbcMue/hFrLGQXB6a2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4o\nBEiEhBxIsaIlws3qQa4baeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0\nvIqPfad5amdQJMvmjZXDI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+\ndFPM2/5kc2HiLNkeuS1Hbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3F\nMSaDK9T0zoJ5hE9fViR+D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAAaNJMEcwDgYD\nVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAw\nEgYDVR0RBAswCYIHdDAudGVzdDANBgkqhkiG9w0BAQsFAAOCAQEAQA/0vvY1gLA2\n0jrPkBVWte7OHzWVkwq7mqgQPR4L9qLLu7Vhelp4dW8n95s1wCbca5j5SJEGv4Uv\n0fI1OOK7XQeYdNlHBmvMVW47GoBSo6tuYNPI/y4xnM6ypEZiPKkdj9Ar9qNgURfV\nz3s1czip915dyTWgwBy7CTxOlG8NW0uiFgEc9iiDDfQsPwVXiVtxOPtjhPeI3F0J\njh3wctFxBnAvLV9SsDxpWujM1dd/1SSQ25jKQhbKNtiDAC8v+Q043r8ZGHjRdxe8\nW2tVWH/iz9c+ze0P0ao7LKv8eGzoIsrBqICS86X4Zv5lGeTGaD2osF1oNvmmoSlh\n536yFa415g==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen98 = 692; +static const size_t kLen152 = 692; -static const char *kData98[] = { +static const char *kData152[] = { "-----BEGIN CERTIFICATE-----\nMIIB0jCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAeBgNVHR4EFzAV\noBMwEYIPd3d3LmV4YW1wbGUuY29tMBgGA1UdIwQRMA6ADGludGVybWVkaWF0ZQAw\nCgYIKoZIzj0EAwIDSQAwRgIhAJepDBm/DoCSSUe2wqmNTjSJxbdQ2I9abl66G7Fs\n6mguAiEAnlJysXppr3jMa5yOFEXRNGRVoBKr6GS/MvCwbeuIXvg=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen99 = 692; +static const size_t kLen153 = 692; -static const char *kData99[] = { +static const char *kData153[] = { "-----BEGIN CERTIFICATE-----\nMIIB0TCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATANBgNVHQ4EBgQEbGVhZjAXBgNV\nHSMEEDAOgAxpbnRlcm1lZGlhdGUwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t\nMB4GA1UdHgQXMBWgEzARgg93d3cuZXhhbXBsZS5jb20wDQYDVR0TAQH/BAMwAAAw\nCgYIKoZIzj0EAwIDSAAwRQIgB1c3+kIZdUX0w3ULyHU4ybkbnlpvhNZDEpqWueYU\n8C4CIQCdJv6LWwvdGNQ9FJxQhHpmZUaB7k/rqih3BYxR50m54A==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen100 = 692; +static const size_t kLen154 = 692; -static const char *kData100[] = { +static const char *kData154[] = { "-----BEGIN CERTIFICATE-----\nMIIB0TCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBARsZWFmMBcGA1UdIwQQMA6A\nDGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20wHgYDVR0e\nBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAUBgNVHSUEDTAKBggrBgEFBQcDAQAw\nCgYIKoZIzj0EAwIDSAAwRQIgORtSwqcycbej93AjlQp5UNCkHVIfvRcekoqAyX8d\nG9sCIQCQHEk/0/BK/KCigzr8UyCyjniemH99Ka0O9nGF8xoBmQ==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen101 = 692; +static const size_t kLen155 = 692; -static const char *kData101[] = { +static const char *kData155[] = { "-----BEGIN CERTIFICATE-----\nMIIB0jCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMBMGA1UdJQQM\nMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBGxlYWYwFwYDVR0j\nBBAwDoAMaW50ZXJtZWRpYXRlMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxlLmNvbTAe\nBgNVHR4EFzAVoBMwEYIPd3d3LmV4YW1wbGUuY29tMA8GA1UdDwEB/wQFAwICBAAw\nCgYIKoZIzj0EAwIDSQAwRgIhAPlqfHIXlF4u9YZclOy8GQAAyE/lVQTSvZT9psfe\nKA7wAiEAt4/kRnYsDJLmJC2g4YwQlVVzIdmaII4GvsDqtPFtcBw=\n-----END CERTIFICATE-----\n", }; -static const size_t kLen102 = 692; +static const size_t kLen156 = 692; -static const char *kData102[] = { +static const char *kData156[] = { "-----BEGIN CERTIFICATE-----\nMIIB0TCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93\nd3cuZXhhbXBsZS5jb20wHwYDVR0eBBgwFaATMBGCD3d3dy5leGFtcGxlLmNvbQAw\nCgYIKoZIzj0EAwIDSAAwRQIgTevxULZ+ge4Vb3FHa0xFQD1pdiXxHrwkCU81GHgd\nkhMCIQCTahPY69HhJNemXhCKX6cNU9ciRqo5ZIijleHXafLOnQ==\n-----END CERTIFICATE-----\n", }; -static const size_t kLen103 = 688; +static const size_t kLen157 = 688; -static const char *kData103[] = { +static const char *kData157[] = { "-----BEGIN CERTIFICATE-----\nMIIB0DCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GA1Ud\nDgQGBARsZWFmMBcGA1UdIwQQMA6ADGludGVybWVkaWF0ZTAeBgNVHR4EFzAVoBMw\nEYIPd3d3LmV4YW1wbGUuY29tMBsGA1UdEQQUMBGCD3d3dy5leGFtcGxlLmNvbQAw\nCgYIKoZIzj0EAwIDRwAwRAIgB5sQf45OpqWJqqKgPHMwB0tOcOv9K6FLdEQM3rLl\ntkcCIAFMvtwlvfIzbw1V6leaXucRfKrI6I2gqq9jyC+RdiMZ\n-----END CERTIFICATE-----\n", }; -static const size_t kLen104 = 688; +static const size_t kLen158 = 688; -static const char *kData104[] = { +static const char *kData158[] = { "-----BEGIN CERTIFICATE-----\nMIIB0DCCAXegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk\nIEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw\nMTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR\nEvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GbMIGYMA4GA1UdDwEB\n/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBcGA1Ud\nIwQQMA6ADGludGVybWVkaWF0ZTAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20w\nHgYDVR0eBBcwFaATMBGCD3d3dy5leGFtcGxlLmNvbTAOBgNVHQ4EBwQEbGVhZgAw\nCgYIKoZIzj0EAwIDRwAwRAIgZX4OegSkMvAY822XIS91eOzMhwt8jMS5aAp+jPwh\nS/sCICiNfc8gZkH72TTz8NYdKPJ20R9l4k42tDSz5DLabc78\n-----END CERTIFICATE-----\n", }; -static const size_t kLen105 = 45577; +static const size_t kLen159 = 45577; -static const char *kData105[] = { +static const char *kData159[] = { "# Imported from Wycheproof's aes_cbc_pkcs5_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: AES-CBC-PKCS5\n# Generator version: 0.8r12\n\n[ivSize = 128]\n[keySize = 128]\n\n# tcId = 1\n# empty message\nct = b10ab60153276941361000414aed0a9d\niv = da9520f7d3520277035173299388bee2\nkey = e34f15c7bd819930fe9d66e0c166e61c\nmsg = \nresult = valid\n\n# tcId = 2\n# message size divisible by block size\nct = d1fa697f3e2e04d64f1a0da203813ca5bc226a0b1d42287b2a5b994a66eaf14a\niv = c9ee3cd746bf208c65ca9e72a266d54f\nkey = e09eaa5a3f5e56d279d5e7a03373f6ea\nmsg = ef4eab37181f98423e53e947e7050fd0\nresult = valid\n\n# tcId = 3\n# message size divisible by block size\nct = 514cbc69aced506926deacdeb0cc0a5a07d540f65d825b65c7db0075cf930a06e0124ae598461cab0b3251baa853e377\niv = 8b2e86a9a185cfa6f51c7cc595b822bc\nkey = 9bd3902ed0996c869b572272e76f3889\nmsg = a7ba19d49ee1ea02f098aa8e30c740d893a4456ccc294040484ed8a00a55f93e\nresult = valid\n\n# tcId = 4\n# message size divisible by block size\nct = 137c824d7f7dc36f24216dde37c2e1c10cee533f6453de92e44b898fc3037d2e9e19d67a96387136dd9717a56e28614a5c177158f402ce2936fd98d1feb6a817\niv = 2717d10eb2eea3b39ec257e43307a260\nkey = 75ce184447cada672e02290310d224f7\nmsg = c774810a31a6421ad8eaafd5c22fa2455e2c167fee4a0b73ff927b2d96c69da1e939407b86b1c19bcfc69c434c3cf8a2\nresult = valid\n\n# tcId = 5\n# small plaintext size\nct = 599d77aca16910b42d8b4ac9560efe1b\niv = 155fd397579b0b5d991d42607f2cc9ad\nkey = e1e726677f4893890f8c027f9d8ef80d\nmsg = 3f\nresult = valid\n\n# tcId = 6\n# small plaintext size\nct = 74e20bf03a0ad4b49edc86a1b19c3d1d\niv = 4eb836be6808db264cb1111a3283b394\nkey = b151f491c4c006d1f28214aa3da9a985\nmsg = 27d9\nresult = valid\n\n# tcId = 7\n# small plaintext size\nct = 3f7a26558ba51cf352219d34c46907ae\niv = a8446c27ea9068d8d924d5c4eac91157\nkey = c36ff15f72777ee21deec07b63c1a0cd\nmsg = 50b428\nresult = valid\n\n# tcId = 8\n# small plaintext size\nct = c29d1463baccc558fd720c897da5bb98\niv = ef026d27da3702d7bb72e5e364a8f8f2\nkey = 32b9c5c78c3a0689a86052420fa1e8fc\nmsg = 0b9262ec\nresult = valid\n\n# tcId = 9\n# small plaintext size\nct = e24a717914f9cc8eaa1dc96f7840d6af\niv = c9defd3929dcd6c355c144e9750dd869\nkey = 43151bbaef367277ebfc97509d0aa49c\nmsg = eaa91273e7\nresult = valid\n\n# tcId = 10\n# small plaintext size\nct = f080e487f4e5b7aed793ea95ffe4bb30\niv = ce91e0454b0123f1ead0f158826459e9\nkey = 481440298525cc261f8159159aedf62d\nmsg = 6123c556c5cc\nresult = valid\n\n# tcId = 11\n# small plaintext size\nct = 27cadee413ed901f51c9366d731d95f6\niv = 1cb7bc8fe00523e7743d3cd9f483d6fe\nkey = 9ca26eb88731efbf7f810d5d95e196ac\nmsg = 7e48f06183aa40\nresult = valid\n\n# tcId = 12\n# small plaintext size\nct = 59bf12427b51a3aee0c9d3c540d04d24\niv = a345f084229dbfe0ceab6c6939571532\nkey = 48f0d03e41cc55c4b58f737b5acdea32\nmsg = f4a133aa6d5985a0\nresult = valid\n\n# tcId = 13\n# small plaintext size\nct = 1a0a18355f8ca4e6e2cf31da18d070da\niv = e5b6f73f132355b7be7d977bea068dfc\nkey = 1c958849f31996b28939ce513087d1be\nmsg = b0d2fee11b8e2f86b7\nresult = valid\n\n# tcId = 14\n# small plaintext size\nct = cef498ea61715a27f400418d1d5bfbf0\niv = c7cd10ca949ea03e7d4ba204b69e09b8\nkey = 39de0ebea97c09b2301a90009a423253\nmsg = 81e5c33b4c620852f044\nresult = valid\n\n# tcId = 15\n# small plaintext size\nct = 7ab43ddc45835ce40d2280bcea6a63f2\niv = bb8c9af30821dfeb7124392a554d9f01\nkey = 91656d8fc0aced60ddb1c4006d0dde53\nmsg = 7b3e440fe566790064b2ec\nresult = valid\n\n# tcId = 16\n# small plaintext size\nct = c70b457c945ad40895cf4c8be3ce7c66\niv = 54c3b90ca6e933f9094334d0263d3775\nkey = af7d5134720b5386158d51ea126e7cf9\nmsg = 7cc6fcc925c20f3c83b5567c\nresult = valid\n\n# tcId = 17\n# small plaintext size\nct = f9900afee2acfe63f8f15d81bbf64c39\niv = 9a2c5e91d4f0b9b9da64b46c5c2c8cb2\nkey = 4ed56753de6f75a032ebabca3ce27971\nmsg = 0c8c0f5619d9f8da5339281285\nresult = valid\n\n# tcId = 18\n# small plaintext size\nct = da4137bd8ac78e75a700b3de806f2d6f\niv = cf7951501104e1434309e6b936ec1742\nkey = beba50c936b696c15e25046dffb23a64\nmsg = 821ea8532fbabffb6e3d212e9b46\nresult = valid\n\n# tcId = 19\n# small plaintext size\nct = fed05321d11d978e2ec32527ecfce06c\niv = 90f5cf4fbfd2e2a1ab8eef402617bd5c\nkey = 501d81ebf912ddb87fbe3b7aac1437bc\nmsg = 2368e3c3636b5e8e94d2081adbf798\nresult = valid\n\n# tcId = 20\n# plaintext size > 16\nct = 8d55dc10584e243f55d2bdbb5758b7fabcd58c8d3785f01c7e3640b2a1dadcd9\niv = 54f2459e40e002763144f4752cde2fb5\nkey = 831e664c9e3f0c3094c0b27b9d908eb2\nmsg = 26603bb76dd0a0180791c4ed4d3b058807\nresult = valid\n\n# tcId = 21\n# plaintext size > 16\nct = e9199842355ea0c3dbf1b2a94fef1c802a95d024df9e407883cf5bf1f02c3cdc\niv = 088e01c2c65b26e7ad6af7b92ea09d73\nkey = cbffc6c8c7f76f46349c32d666f4efb0\nmsg = 6df067add738195fd55ac2e76b476971b9a0e6d8\nresult = valid\n\n# tcId = 22\n# plaintext size > 16\nct = 19beb4db2be0f3aff0083583038b2281a77c85b5f345ba4d2bc7f742a14f9247\niv = d9c9468796a2f5741b84d2d41430c5d3\nkey = fda6a01194beb462953d7e6c49b32dac\nmsg = f60ae3b036abcab78c98fc1d4b67970c0955cb6fe24483f8907fd73319679b\nresult = valid\n\n# tcId = 23\n# plaintext size > 16\nct = 84904fc92bd2e7590aa268e667370327b9446f41067dd40d3e5091a63a0d5687e4926e00cc3cb461c3b85d80ee2da818\niv = c98b47808add45c0c891983ec4b09846\nkey = efd9caa8ac68e9e29acdae57e93bcea8\nmsg = 3e1d2001f1e475b972738936443a5f51eedaf802a66fadf2406cfaadb0549149fcb9f485e534dc2d\nresult = valid\n\n# tcId = 24\n# plaintext size > 16\nct = 1d1391593a336be4b207295ad0542bc4ef2f39053066e12c38f71603f377fd42f4f0b2b5a42cdfeaee2af039f06fcf347abe171af3157ff07f3cdd3b33e11a60caecf9890325c132eeb66ab847278d165c26bca7c30486bb2fd83b63c5ff7ae0\niv = 08e9410de244d3f40607ebae38fa74e7\nkey = 37e4dbdc436258d5a9adb9f205c77cf3\nmsg = 24a874aec067116ad22eb55846ded3f5e86919a135585c929a86d92b2958fed110e52e33804887243584a6a94402cc9a105e0c940ec335bd2890f16dcce3fc8bd02873c80ade6f1ac08683130bcca454\nresult = valid\n\n# tcId = 25\n# zero padding\nct = aa62606a287476777b92d8e4c4e53028\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 26\n# zero padding\nct = ada437b682c92384b6c23ec10a21b3d8\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 27\n# zero padding\nct = 26c5b3e540ee3dd6b52d14afd01a44f8\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 28\n# zero padding\nct = fbcbdfdaaf17980be939c0b243266ecbc0deb417e98aba3ee12fea2921f8ae51\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 29\n# zero padding\nct = fbcbdfdaaf17980be939c0b243266ecb1188ff22f6563f6173440547d1e0dfd8\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 30\n# padding with 0xff\nct = 726570a34cea08139d9f836579102a0e\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 31\n# padding with 0xff\nct = c8ef7ac3fd659ce7157d72a25f0a5048\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 32\n# padding with 0xff\nct = 6123c889bbc766acd4bca4cb982f9978\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 33\n# padding with 0xff\nct = fbcbdfdaaf17980be939c0b243266ecb442cd16f7410fca70924b573f7967e84\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 34\n# padding with 0xff\nct = fbcbdfdaaf17980be939c0b243266ecbb20f899b0e7c1d65b931af94b5c44c25\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 35\n# bit padding\nct = 50aeed98a820c5a037a5aa4d4ef3090b\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 36\n# bit padding\nct = 25ee339006f948f42713543c", "62467ef9\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 37\n# bit padding\nct = 97914574676ed5b8db0b6f3931195b3f\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 38\n# bit padding\nct = fbcbdfdaaf17980be939c0b243266ecb2874a1e2d28dd18e5573df9fd59fd789\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 39\n# bit padding\nct = fbcbdfdaaf17980be939c0b243266ecbb547c4fddbdcd3e02f438a2e48587594\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 40\n# padding longer than 1 block\nct = d17ccbb26f0aa95f397b20063547349bac24c5429cbea591e96595cccc11451b\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 41\n# padding longer than 1 block\nct = fc07025e81d43efa85f92afdf8781b1e88598e12d6812df43733e93414b9e901\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 42\n# padding longer than 1 block\nct = deb1746f4e9e0be4a21825b071b6e93303031651e0c59091e2ae0fbcce11b987\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 43\n# padding longer than 1 block\nct = fbcbdfdaaf17980be939c0b243266ecb563d35096fde10ccb6f768438c9eb4ec90f399b76924c716e9f94143263306c6\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 44\n# padding longer than 1 block\nct = fbcbdfdaaf17980be939c0b243266ecbc8fd2e2c5362acf5212bd47859aa827d8469b87b0e6adafe3dba98c1885b6345\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 45\n# ANSI X.923 padding\nct = ca5dd2d09bd56eec9e8acaeca20af68e\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 46\n# ANSI X.923 padding\nct = 01e53a5ec9b0957c45f79ed0f4b2b982\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 47\n# ANSI X.923 padding\nct = fbcbdfdaaf17980be939c0b243266ecbd3909bb3457e5b946ff709be9a2ed84d\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 48\n# ANSI X.923 padding\nct = fbcbdfdaaf17980be939c0b243266ecbc5ab3ab637166a6a067b82b5672c08f8\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 49\n# ISO 10126 padding\nct = ba0726bd6dea11382b19c842e2ddead2\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 50\n# ISO 10126 padding\nct = 22f18b85c729903744fb8db5ed2840d4\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 51\n# ISO 10126 padding\nct = fbcbdfdaaf17980be939c0b243266ecb6b103fbe43519a18880b7e6d9153e1c2\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 52\n# ISO 10126 padding\nct = fbcbdfdaaf17980be939c0b243266ecbe00bdb15b8a61285447498700d35e0c6\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 53\n# padding longer than message\nct = d17ccbb26f0aa95f397b20063547349b\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 54\n# padding longer than message\nct = 2056dfa339fa00be6836999411a98c76\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 55\n# padding longer than message\nct = f92628f6418d8d9c9afac233861b3835\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 56\n# padding longer than message\nct = fbcbdfdaaf17980be939c0b243266ecbc0c41093b495a7d5a080d976493fd0e7\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 57\n# padding longer than message\nct = fbcbdfdaaf17980be939c0b243266ecb6770446a5ccaa26f7d4f970cc5834eba\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 58\n# invalid padding\nct = 4ff3e623fdd432608c183f40864177af\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 59\n# invalid padding\nct = 6a1ef1e6ae6a788777aabd9ccf3cf43a\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 60\n# invalid padding\nct = fbcbdfdaaf17980be939c0b243266ecbee1345cd513161b241f4ae2799b0327f\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 61\n# invalid padding\nct = fbcbdfdaaf17980be939c0b243266ecbe0d539beef6f2d4f7cda4fd9f4f05570\niv = 23468aa734f5f0f19827316ff168e94f\nkey = db4f3e5e3795cc09a073fa6a81e5a6bc\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n[ivSize = 128]\n[keySize = 192]\n\n# tcId = 62\n# empty message\nct = ff0c315873b4b1872abef2353b792ef0\niv = db20f9a6f4d6b4e478f1a4b9d4051d34\nkey = 3d6bf9edae6d881eade0ff8c7076a4835b71320c1f36b631\nmsg = \nresult = valid\n\n# tcId = 63\n# message size divisible by block size\nct = 7dbd573e4db58a318edfe29f199d8cda538a49f36486337c2711163e55fd5d0b\niv = 69a76dc4da64d89c580eb75ae975ec39\nkey = f4bfa5aa4f0f4d62cf736cd2969c43d580fdb92f2753bedb\nmsg = 0e239f239705b282ce2200fe20de1165\nresult = valid\n\n# tcId = 64\n# message size divisible by block size\nct = bd0258909e5b72438d95ca4b29c8a79c6228fd06a3b2fa06f7659654c7b24610f23f2fb16313b7d3614cb0cd16fabb8e\niv = 6525667350930fb945dd1895a3abfcd1\nkey = 9d11abc1fcb248a436598e695be12c3c2ed90a18ba09d62c\nmsg = aa5182cae2a8fb068c0b3fb2be3e57ae523d13dffd1a944587707c2b67447f3f\nresult = valid\n\n# tcId = 65\n# message size divisible by block size\nct = 6cbeacf8de25d7dd9dcdc087bf2f80873b1eb335400589076f8d2bf81e294c5d72b85eb8ac9558b0de9e9fbee4b18716e5220c507fbb9d319a08f67816765ca6\niv = 3943d8fddd5bb2a59772df31a31a8fff\nkey = 7e41d83181659a2c38da5ead353cdb04c2b4d4a3cfe58e25\nmsg = 8a32d11c7a11aa72e13381632b1310f4fd90fc209a6a350e61c069a561871214f9c04fc1df7354cbe4d8d639c525d324\nresult = valid\n\n# tcId = 66\n# small plaintext size\nct = 519925956d32e4fa350b1144f088e4e8\niv = 1379d48493f743e6a149deb3b9bab31e\nkey = 915429743435c28997a33b33b6574a953d81dae0e7032e6a\nmsg = 58\nresult = valid\n\n# tcId = 67\n# small plaintext size\nct = bfb90aa7de1bdeed5bdc5703bdfd9630\niv = 48c7f44b43a1279d820733e6cb30617a\nkey = f0c288ba26b284f9fb321b444a6517b3cdda1a799d55fdff\nmsg = 0f7e\nresult = valid\n\n# tcId = 68\n# small plaintext size\nct = b1a25816908c086f26037d10b7be9ad9\niv = 2c287b38cc30c8c351b087b91a6a97ba\nkey = 6b55e4d4fd6847a80a6bfb0dcc0aa93f9fd797fc5c50292e\nmsg = 33f530\nresult = valid\n\n# tcId = 69\n# small plaintext size\nct = 74dbdecbfa94b71d2d6ef03200c7d095\niv = 61f6060919c9c09ef06be28f39c344aa\nkey = 1eb21a9e995a8e45c9e71ecbd6fe615b3e0318007c64b644\nmsg = 3aa73c48\nresult = valid\n\n# tcId = 70\n# small plaintext size\nct = 10c860aaee23c3c3c1b9306b189dd80d\niv = 7682005907bf", "ef3ce00196a17ad2246d\nkey = 710e2d5d4a9f0bc7e50796655e046a18cc5769d7764355da\nmsg = 7e4c690a88\nresult = valid\n\n# tcId = 71\n# small plaintext size\nct = 673dcd444386930a0cc577fab4501e5c\niv = 1f6c912997ce007701e5fdf407c6b421\nkey = d8c09ea400779b63e774bdacd0cb7b5dd6f736ca23d52acf\nmsg = e9520280973b\nresult = valid\n\n# tcId = 72\n# small plaintext size\nct = 059e5f72a81d8820add8eae8fabcdd42\niv = 5854033ae50de090678432781a168b6c\nkey = 8e67e9a0863b55bed408866f1cbc05357abe3f9d79f406f2\nmsg = 4880b412287a0b\nresult = valid\n\n# tcId = 73\n# small plaintext size\nct = c412159fd5ae20d771b7d2e734124d6a\niv = 003b2d86d8b636c58cf664565572d5e6\nkey = 28d8da67806410e5565bcc5a9d7ab9fb357413fa0158378c\nmsg = 004e3f4a4e6db955\nresult = valid\n\n# tcId = 74\n# small plaintext size\nct = 4aba571c2c5ab9a6140f16efc68c8ec1\niv = 3f22b50f888ab9424ba871d15aac55b7\nkey = dc968dd89fd602bb7eca6f3a8a13e4f59c08d02a514b1934\nmsg = 41a25354efeb1bc3b8\nresult = valid\n\n# tcId = 75\n# small plaintext size\nct = 66d1b9152a8cd1a88eab341c775070b4\niv = e4b8dde04b49fa6b88bfccd8d70c21d1\nkey = 7658951c0f620d82afd92756cc2d7983b79da3e56fdd1b78\nmsg = f0e82fb5c5666f4af49f\nresult = valid\n\n# tcId = 76\n# small plaintext size\nct = d9377788e2881a48f9347786db7df51f\niv = 7753f616cd8796c9b8a3bbfbe6cb1e7f\nkey = d9574c3a221b986690931faac5258d9d3c52362b2cb9b054\nmsg = 178ea8404ba54ee4e4522c\nresult = valid\n\n# tcId = 77\n# small plaintext size\nct = db825f4434ea3bb53576fa7385fb7dfe\niv = eae9ee19ccb7f8b087675709c4d35f73\nkey = 704409bab28085c44981f28f75dd143a4f747106f63f262e\nmsg = cda5709e7f115624e74ab031\nresult = valid\n\n# tcId = 78\n# small plaintext size\nct = 3e7287df2a5ed9de4d817e352bd47ea7\niv = a6aaff339a729d30a7ec1328db36d23e\nkey = d8d06ef6a53bbff5c8f12d791b8f4c67e574bf440736d1cc\nmsg = a1171eae1979f48345dd9485a0\nresult = valid\n\n# tcId = 79\n# small plaintext size\nct = 17c3ade4b469ae614760039a8fa6250e\niv = 92fda71e88c70d18ed71b992735a2150\nkey = 71129e781613f39d9ac39fbde2628b44c250c14deb5ef9e2\nmsg = 967593cc64bcbf7f3c58d04cb82b\nresult = valid\n\n# tcId = 80\n# small plaintext size\nct = 9cafecff2a28d02f732573f65a2cadca\niv = ed6596c86b98123ad2f3c573e974d051\nkey = 850fc859e9f7b89a367611dee6698f33962d8245ca8dc331\nmsg = 586f4f171af116519061a8e0e77940\nresult = valid\n\n# tcId = 81\n# plaintext size > 16\nct = 401ad889bdb9d38816c782e00b168ccccde9bf75f4be868ceb91237e8b37b750\niv = c45b52a240eba3bdde5dfd57f3d474fb\nkey = cfd3f68873d81a27d2bfce876c79f6e609074dec39e34614\nmsg = b1973cb25aa87ef9d1a8888b0a0f5c04c6\nresult = valid\n\n# tcId = 82\n# plaintext size > 16\nct = 455d516e87851e6c894578a0f7126e0acbc7cfbb1d80296647ab89a79dfa6f71\niv = 07ece5fe02266e073499fd4d66929034\nkey = b7f165bced1613da5e747fdf9255832d30c07f2deeb5a326\nmsg = 289647ea8d0ff31375a82aa1c620903048bb1d0e\nresult = valid\n\n# tcId = 83\n# plaintext size > 16\nct = cbf541330a5a9bda24984976b0cf96ba08ef521fa2cdb3df839128570e222ac4\niv = d799157bc1f77c182027be918b30783a\nkey = 9bbe6e004fb260dadb02b68b78954f1da5e6a2d02e0aeefe\nmsg = 665423092ce95b927e98b8082030f58e33f3ec1b0c29532c2f421855f00f97\nresult = valid\n\n# tcId = 84\n# plaintext size > 16\nct = 03225f08592efca14ad8ecf822465e8be4157465d0be150dd3d645b6fef1b19ca7bbaa5940b2a7895fa2b0ee55b0d4ec\niv = fdf97645e4192ba84728bbf6683f79de\nkey = 1381fbd5e79045d40f29790fc1a436c95b040a046ebf0b0f\nmsg = d575dce596dd0a2cd1c18dab7eb0948fafb8669969a48b6314493bfb8daf8acacd51382f9bb5b357\nresult = valid\n\n# tcId = 85\n# plaintext size > 16\nct = 27ad00313f328f0d3e6c3238ab560cb7243a9f54f7dff79b5a7a879439993d458017f09e8d3f694098bc19e61fe54085138664abb51a5b328cf2c9ce5d59726fff5e1b7553c143d9e0493c51cab23ff2ecdad91bd72bb12b32f3b611f9a4225d\niv = 059685f59247eea5d3f2a1532cb9d6b2\nkey = 1bb4ed0e8435e20729f48c1b7e3af6e69e4cebf0731131cf\nmsg = 6d29dab6a0568c961ab3c825e0d89940cef06c63ade7e557cd3e92792eaf23c8cd5a0f029c63b1cdce4754ccfad7a73c7c9e50ffe081e9136f5e9a424077339de12ea43572afe1b034e833e5887763aa\nresult = valid\n\n# tcId = 86\n# zero padding\nct = 2c010faa25c68c3b30b8c1491c316d5f\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 87\n# zero padding\nct = 818454d433154a8e00e8f590b8a1c38c\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 88\n# zero padding\nct = 0a7423fae3f4c8d4633f839d36f2e9ff\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 89\n# zero padding\nct = a7cfcdabcc5a2736a2708c1cb0b61432e83f6e522c371e6e71bde539595b70b7\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 90\n# zero padding\nct = a7cfcdabcc5a2736a2708c1cb0b6143254d15f47701fa54f5957828f386e1d97\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 91\n# padding with 0xff\nct = 6ded36cc7603e514014dfb7199900676\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 92\n# padding with 0xff\nct = 839f772f8e5f50afdc02f954094869fe\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 93\n# padding with 0xff\nct = eefe3553c099c187929b287e54f95726\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 94\n# padding with 0xff\nct = a7cfcdabcc5a2736a2708c1cb0b61432d0531a2641d40467353542d79ce20ea8\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 95\n# padding with 0xff\nct = a7cfcdabcc5a2736a2708c1cb0b61432aaf08a090ecf66167ba5958100be7950\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 96\n# bit padding\nct = c0e402c8bbdda18c8ddd86470bd4b244\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 97\n# bit padding\nct = dc185d4572565e01131e471ec4c48125\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 98\n# bit padding\nct = 3ad1ddf3c3b320398785e6ec6544e9a2\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 99\n# bit padding\nct = a7cfcdabcc5a2736a2708c1cb0b614325876f90cfbbdbcd85e8252d37c44c638\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 100\n# bit padding\nct = a7cfcdabcc5a2736a2708c1cb0b61432d18f57216b0e6426d911998a0e44156b\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 101\n# padding longer than 1 block\nct = f1605abb4e6628347c616da350fe243043a8d7b6aea244ca013f45241d802213\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 102\n# padding longer than 1 block\nct = a5f027fb9514ec8844534d452c940feb2c1807f57ed628156cf753f2ab698356\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 103\n# padding longer than 1 block\nct = f346fbc9744d723c42bbb2a4c934cdd4f1019e58c226cb2491fed621271a38f3\niv = a3fe6f76e8f582830bbe83574a7bb729\nkey = 9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2\nmsg = 303132333435363738396162636465\nresult = ", @@ -3005,9 +3643,9 @@ static const char *kData105[] = { "99\nkey = 64be162b39c6e5f1fed9c32d9f674d9a8cde6eaa2443214d86bd4a1fb53b81b4\nmsg = 195a3b292f93baff0a2c\nresult = valid\n\n# tcId = 137\n# small plaintext size\nct = 4ed0eac75b05868078303875f82fb4f0\niv = 2d4cead3f1120a2b4b59419d04951e20\nkey = b259a555d44b8a20c5489e2f38392ddaa6be9e35b9833b67e1b5fdf6cb3e4c6c\nmsg = afd73117330c6e8528a6e4\nresult = valid\n\n# tcId = 138\n# small plaintext size\nct = f4d298caea7c390fc8c7f558f584f852\niv = a10392634143c2a3332fa0fb3f72200a\nkey = 2c6fc62daa77ba8c6881b3dd6989898fef646663cc7b0a3db8228a707b85f2dc\nmsg = 0ff54d6b6759120c2e8a51e3\nresult = valid\n\n# tcId = 139\n# small plaintext size\nct = 5e1c00e2ec829f92b87c6adf5c25262d\niv = 38b916a7ad3a9251ae3bd8865ca3a688\nkey = abab815d51df29f740e4e2079fb798e0152836e6ab57d1536ae8929e52c06eb8\nmsg = f0058d412a104e53d820b95a7f\nresult = valid\n\n# tcId = 140\n# small plaintext size\nct = bf3a04ddb2dbfe7c6dc9e15aa67be25d\niv = bfcc3ac44d12e42d780c1188ac64b57f\nkey = 3d5da1af83f7287458bff7a7651ea5d8db72259401333f6b82096996dd7eaf19\nmsg = aacc36972f183057919ff57b49e1\nresult = valid\n\n# tcId = 141\n# small plaintext size\nct = fdcfa77f5bd09326b4c11f9281b72474\niv = 35bc82e3503b95044c6406a8b2c2ecff\nkey = c19bdf314c6cf64381425467f42aefa17c1cc9358be16ce31b1d214859ce86aa\nmsg = 5d066a92c300e9b6ddd63a7c13ae33\nresult = valid\n\n# tcId = 142\n# plaintext size > 16\nct = fbea776fb1653635f88e2937ed2450ba4e9063e96d7cdba04928f01cb85492fe\niv = 4b74bd981ea9d074757c3e2ef515e5fb\nkey = 73216fafd0022d0d6ee27198b2272578fa8f04dd9f44467fbb6437aa45641bf7\nmsg = d5247b8f6c3edcbfb1d591d13ece23d2f5\nresult = valid\n\n# tcId = 143\n# plaintext size > 16\nct = 3a79bb6084c7116b58afe52d7181a0aacee1caa11df959090e2e7b0073d74817\niv = 9a1d8ccc24c5e4d3995480af236be103\nkey = c2039f0d05951aa8d9fbdf68be58a37cf99bd1afcedda286a9db470c3729ca92\nmsg = ed5b5e28e9703bdf5c7b3b080f2690a605fcd0d9\nresult = valid\n\n# tcId = 144\n# plaintext size > 16\nct = 642b11efb79b49e5d038bc7aa29b8c6c3ce0bf11c3a69670eb565799908be66d\niv = 400aab92803bcbb44a96ef789655b34e\nkey = 4f097858a1aec62cf18f0966b2b120783aa4ae9149d3213109740506ae47adfe\nmsg = ee53d8e5039e82d9fcca114e375a014febfea117a7e709d9008d43858e3660\nresult = valid\n\n# tcId = 145\n# plaintext size > 16\nct = a9b051354f0cf61f11921b330e60f996de796aeb68140a0f9c5962e1f48e4805262fb6f53b26d9bb2fa0e359efe14734\niv = 6eedf45753ffe38f2407fbc28ab5959c\nkey = 5f99f7d60653d79f088dd07ef306b65e057d36e053fa1c9f6854425c019fd4df\nmsg = fcc9212c23675c5d69a1266c77389bc955e453daba20034aabbcd502a1b73e05af30f8b7622abdbc\nresult = valid\n\n# tcId = 146\n# plaintext size > 16\nct = 5074f46f1a6d0eeff070d623172eb15bbfc83e7d16466a00c9da5f4545eecf44adbf60cf9ac9aa1a3ec5eca22d4a34a7b21ca44d214c9d04ab1cb0b2c07001de9adb46f3c12f8f48436b516a409bf6cbdf1871dee3115d5cbb7943558b68867e\niv = f88551c6aa197f9ad80251c2e32d7663\nkey = 95aaa5df4ccb529e9b2dc929e770c1f419f8e8933bfb36f632f532b3dcad2ba6\nmsg = f5735567b7c8312f116517788b091cc6cb1d474b010a77910154fd11c3b2f0cd19f713b63d66492e8cc7ee8ad714783f46c305a26416e11ff4b99ec5ce2550593cc5ec1b86ba6a66d10f82bdff827055\nresult = valid\n\n# tcId = 147\n# zero padding\nct = e07558d746574528fb813f34e3fb7719\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 148\n# zero padding\nct = c01af61276368818a8295f7d4b5bb2fd\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 149\n# zero padding\nct = 97dd9716f06be49160399a5b212250ae\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 150\n# zero padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce783bb4b4e18d7c646f38e0bb8ff92896\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 151\n# zero padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce64679a46621b792f643542a735f0bbbf\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 152\n# padding with 0xff\nct = c007ddffb76b95208505fe7f3be96172\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 153\n# padding with 0xff\nct = e9b7719c4c2b9fa6b94cb50e87b28156\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 154\n# padding with 0xff\nct = 77b31f474c4bd489dbadd532643d1fa5\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 155\n# padding with 0xff\nct = 8881e9e02fa9e3037b397957ba1fb7cea0166e9e1c0122cb2e2983fc0fac7176\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 156\n# padding with 0xff\nct = 8881e9e02fa9e3037b397957ba1fb7ce6f0effa789cbb0b875cc53cc8f7b3caf\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 157\n# bit padding\nct = 4dd5f910c94700235c9ed239160e34e2\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 158\n# bit padding\nct = 94d18b5923f8f3608ae7ad494fbb517e\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 159\n# bit padding\nct = 0c92886dbcb030b873123a25d224da42\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 160\n# bit padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce851be67798a2937cd6681165da6dce03\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 161\n# bit padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce45658a37aaebc51098866b0894007e8e\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 162\n# padding longer than 1 block\nct = 524236e25956e950713bec0d3d579068f34e4d18c4ccab081317dae526fe7fca\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 163\n# padding longer than 1 block\nct = d29eb845640c3a8878f51bc50e290aa4a65a34a93728fe8f82fdb8d3d2b7c648\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 164\n# padding longer than 1 block\nct = c34563be2952277c0f5c67ae1d6f847118730dd7f6a502ceef3c4bce5999f7aa\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 165\n# padding longer than 1 block\nct = 8881e9e02fa9e3037b397957ba1fb7cec0f74a1aa92fd9c96f9d15d193d1695c1eb33486e269277612f90f509f0535c2\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 166\n# padding longer than 1 block\nct = 8881e9e02fa9e3037b397957ba1fb7ce151ade309ec5200bacdd83b57ce794cd2b3bf9f8957def829e8465f7db266f9e\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey ", "= 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 167\n# ANSI X.923 padding\nct = fb38cbef13f1d5be9c0ac7ed9cbe023c\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 168\n# ANSI X.923 padding\nct = 18cf8988abe9a2463a3a75db1fac8bcc\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 169\n# ANSI X.923 padding\nct = 8881e9e02fa9e3037b397957ba1fb7cee16d6fc4b4d3cdf6f915996e437fd4cc\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 170\n# ANSI X.923 padding\nct = 8881e9e02fa9e3037b397957ba1fb7cea8f41f61ead6e9936cbe7ee5a1163b9b\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 171\n# ISO 10126 padding\nct = a05c14da0109093c195b4998812fe150\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 172\n# ISO 10126 padding\nct = c477877250c8e4ca2869f35c4757cdb4\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 173\n# ISO 10126 padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce69f57c6e99c7b9df7d4879ccd15caf3d\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 174\n# ISO 10126 padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce77f89a247c928f147748ce6bc8fc4b67\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 175\n# padding longer than message\nct = 524236e25956e950713bec0d3d579068\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 176\n# padding longer than message\nct = e03b6f2ae1c963b6dfa40b42d34314b7\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 177\n# padding longer than message\nct = df14f4cbbccca57b9727d68270a1b6c1\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 303132333435363738396162636465\nresult = invalid\nflags = BadPadding\n\n# tcId = 178\n# padding longer than message\nct = 8881e9e02fa9e3037b397957ba1fb7ceea228bf1edd41c390e2eef140142bc00\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 179\n# padding longer than message\nct = 8881e9e02fa9e3037b397957ba1fb7ce3937e0e9abf7f672a34a500ba8e9099a\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n# tcId = 180\n# invalid padding\nct = 32ac6057df2a5d1e2e5131348c6ebc4e\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = \nresult = invalid\nflags = BadPadding\n\n# tcId = 181\n# invalid padding\nct = df4a7c3b9f4756d30fca0d18e9b28960\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 6162636465666768\nresult = invalid\nflags = BadPadding\n\n# tcId = 182\n# invalid padding\nct = 8881e9e02fa9e3037b397957ba1fb7ceae2855c47c7988873d57f901e049494b\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 30313233343536373839414243444546\nresult = invalid\nflags = BadPadding\n\n# tcId = 183\n# invalid padding\nct = 8881e9e02fa9e3037b397957ba1fb7ce0714c8de200b27ac91d9257fc93c13be\niv = f010f61c31c9aa8fa0d5be5f6b0f2f70\nkey = 7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a\nmsg = 3031323334353637383941424344454647\nresult = invalid\nflags = BadPadding\n\n", }; -static const size_t kLen106 = 52732; +static const size_t kLen160 = 52732; -static const char *kData106[] = { +static const char *kData160[] = { "# Imported from Wycheproof's aes_cmac_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: AES-CMAC\n# Generator version: 0.8r12\n\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 1\n# empty message\nkey = e34f15c7bd819930fe9d66e0c166e61c\nmsg = \nresult = valid\ntag = d47afca1d857a5933405b1eb7a5cb7af\n\n# tcId = 2\n# short message\nkey = e1e726677f4893890f8c027f9d8ef80d\nmsg = 3f\nresult = valid\ntag = 15f856bbed3b321952a584b3c4437a63\n\n# tcId = 3\n# short message\nkey = b151f491c4c006d1f28214aa3da9a985\nmsg = 27d9\nresult = valid\ntag = bdbbebac982dd62b9f682618a6a604e9\n\n# tcId = 4\n# short message\nkey = c36ff15f72777ee21deec07b63c1a0cd\nmsg = 50b428\nresult = valid\ntag = be0c3ede157568af394023eb9a7cc983\n\n# tcId = 5\n# short message\nkey = 32b9c5c78c3a0689a86052420fa1e8fc\nmsg = 0b9262ec\nresult = valid\ntag = 57e1506856c55dd32cd9ca821adb6c81\n\n# tcId = 6\n# short message\nkey = 43151bbaef367277ebfc97509d0aa49c\nmsg = eaa91273e7\nresult = valid\ntag = e01adc3be6a7621824232c4285dd35b9\n\n# tcId = 7\n# short message\nkey = 481440298525cc261f8159159aedf62d\nmsg = 6123c556c5cc\nresult = valid\ntag = a281e0d2d5378dfdcc1310fd9782ca56\n\n# tcId = 8\n# short message\nkey = 9ca26eb88731efbf7f810d5d95e196ac\nmsg = 7e48f06183aa40\nresult = valid\ntag = fc81761f2f7b4ce13b53d36e32677332\n\n# tcId = 9\n# short message\nkey = 48f0d03e41cc55c4b58f737b5acdea32\nmsg = f4a133aa6d5985a0\nresult = valid\ntag = 1f1cd0327c02e6d00086915937dd61d9\n\n# tcId = 10\n# short message\nkey = 1c958849f31996b28939ce513087d1be\nmsg = b0d2fee11b8e2f86b7\nresult = valid\ntag = 555f462151f7dd16de698d639fb26760\n\n# tcId = 11\n# short message\nkey = 39de0ebea97c09b2301a90009a423253\nmsg = 81e5c33b4c620852f044\nresult = valid\ntag = 9b004f15b7f6f366374954e64bc58f5f\n\n# tcId = 12\n# short message\nkey = 91656d8fc0aced60ddb1c4006d0dde53\nmsg = 7b3e440fe566790064b2ec\nresult = valid\ntag = 76672ed16c29be449e0c80785cc38e89\n\n# tcId = 13\n# short message\nkey = af7d5134720b5386158d51ea126e7cf9\nmsg = 7cc6fcc925c20f3c83b5567c\nresult = valid\ntag = 2dc5c88cf3b80ab6c0199f40be904abc\n\n# tcId = 14\n# short message\nkey = 4ed56753de6f75a032ebabca3ce27971\nmsg = 0c8c0f5619d9f8da5339281285\nresult = valid\ntag = eab4366d97e99a0850f077329ad058c0\n\n# tcId = 15\n# short message\nkey = beba50c936b696c15e25046dffb23a64\nmsg = 821ea8532fbabffb6e3d212e9b46\nresult = valid\ntag = 22f33cab09c173f75d3401fe44efeead\n\n# tcId = 16\n# short message\nkey = 501d81ebf912ddb87fbe3b7aac1437bc\nmsg = 2368e3c3636b5e8e94d2081adbf798\nresult = valid\ntag = aeb784a3825168ddd61f72d0202125e6\n\n# tcId = 17\nkey = e09eaa5a3f5e56d279d5e7a03373f6ea\nmsg = ef4eab37181f98423e53e947e7050fd0\nresult = valid\ntag = 40facf0e2fb51b73a7472681b033d6dc\n\n# tcId = 18\nkey = 831e664c9e3f0c3094c0b27b9d908eb2\nmsg = 26603bb76dd0a0180791c4ed4d3b058807\nresult = valid\ntag = a8144c8b24f2aa47d9c160cff4ab1716\n\n# tcId = 19\nkey = 549bd282ee21b4d7c3b1d02e3ee20ef7\nmsg = d84bf73c5eecbd38444f1a73556e2fa3253f4c54d6916545\nresult = valid\ntag = 7ed458afe02f4a513f59715b664b1bbe\n\n# tcId = 20\nkey = 9bd3902ed0996c869b572272e76f3889\nmsg = a7ba19d49ee1ea02f098aa8e30c740d893a4456ccc294040484ed8a00a55f93e\nresult = valid\ntag = 45082218c2d05eef32247feb1133d0a3\n\n# tcId = 21\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 96dd6e5a882cbd564c39ae7d1c5a31aa\n\n# tcId = 22\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 43802eb1931f0032afe984443738cd31\n\n# tcId = 23\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7acfbbca7a2ea68b966fc5399f74809e\n\n# tcId = 24\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 95dd6e5a882cbd564c39ae7d1c5a31aa\n\n# tcId = 25\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 40802eb1931f0032afe984443738cd31\n\n# tcId = 26\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 79cfbbca7a2ea68b966fc5399f74809e\n\n# tcId = 27\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 17dd6e5a882cbd564c39ae7d1c5a31aa\n\n# tcId = 28\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = c2802eb1931f0032afe984443738cd31\n\n# tcId = 29\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = fbcfbbca7a2ea68b966fc5399f74809e\n\n# tcId = 30\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dc6e5a882cbd564c39ae7d1c5a31aa\n\n# tcId = 31\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42812eb1931f0032afe984443738cd31\n\n# tcId = 32\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcebbca7a2ea68b966fc5399f74809e\n\n# tcId = 33\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6eda882cbd564c39ae7d1c5a31aa\n\n# tcId = 34\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802e31931f0032afe984443738cd31\n\n# tcId = 35\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbb4a7a2ea68b966fc5399f74809e\n\n# tcId = 36\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a892cbd564c39ae7d1c5a31aa\n\n# tcId = 37\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1921f0032afe984443738cd31\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7b2ea68b966fc5399f74809e\n\n# tcId = 39\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a8a2cbd564c39ae7d1c5a31aa\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1911f0032afe984443738cd31\n\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca782ea68b966fc5399f74809e\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbdd64c39ae7d1c5a31aa\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f00b2afe984443738cd31\n\n# tcId = 44\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea60b966fc5399f74809e\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564d39ae7d1c5a31aa\n\n# tcId = 46\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032aee984443738cd31\n\n# tcId = 47\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b976fc5399f74809e\n\n# tcId = 48\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd56cc39ae7d1c5a31aa\n\n# tcId = 49\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f00322fe984443738cd31\n\n# tcId = 50\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b166fc5399f74809e\n\n# tcId = 51\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c19ae7d1c5a31aa\n\n# tcId = 52\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afc984443738cd31\n\n# tcId = 53\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = inval", "id\ntag = 7bcfbbca7a2ea68b964fc5399f74809e\n\n# tcId = 54\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39af7d1c5a31aa\n\n# tcId = 55\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe985443738cd31\n\n# tcId = 56\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc4399f74809e\n\n# tcId = 57\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1d5a31aa\n\n# tcId = 58\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443638cd31\n\n# tcId = 59\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399e74809e\n\n# tcId = 60\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1e5a31aa\n\n# tcId = 61\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443538cd31\n\n# tcId = 62\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399d74809e\n\n# tcId = 63\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d9c5a31aa\n\n# tcId = 64\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe98444b738cd31\n\n# tcId = 65\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5391f74809e\n\n# tcId = 66\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1c5a31ab\n\n# tcId = 67\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443738cd30\n\n# tcId = 68\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399f74809f\n\n# tcId = 69\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1c5a31a8\n\n# tcId = 70\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443738cd33\n\n# tcId = 71\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399f74809c\n\n# tcId = 72\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1c5a31ea\n\n# tcId = 73\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443738cd71\n\n# tcId = 74\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399f7480de\n\n# tcId = 75\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbd564c39ae7d1c5a312a\n\n# tcId = 76\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f0032afe984443738cdb1\n\n# tcId = 77\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea68b966fc5399f74801e\n\n# tcId = 78\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 96dd6e5a882cbd564d39ae7d1c5a31aa\n\n# tcId = 79\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 43802eb1931f0032aee984443738cd31\n\n# tcId = 80\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7acfbbca7a2ea68b976fc5399f74809e\n\n# tcId = 81\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6eda882cbdd64c39ae7d1c5a31aa\n\n# tcId = 82\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802e31931f00b2afe984443738cd31\n\n# tcId = 83\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbb4a7a2ea60b966fc5399f74809e\n\n# tcId = 84\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 97dd6e5a882cbdd64c39ae7d1c5a312a\n\n# tcId = 85\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 42802eb1931f00b2afe984443738cdb1\n\n# tcId = 86\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7bcfbbca7a2ea60b966fc5399f74801e\n\n# tcId = 87\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 682291a577d342a9b3c65182e3a5ce55\n\n# tcId = 88\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = bd7fd14e6ce0ffcd50167bbbc8c732ce\n\n# tcId = 89\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 8430443585d1597469903ac6608b7f61\n\n# tcId = 90\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 91\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 92\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 93\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 94\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 95\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 96\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 175deeda08ac3dd6ccb92efd9cdab12a\n\n# tcId = 97\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = c200ae31139f80b22f6904c4b7b84db1\n\n# tcId = 98\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = fb4f3b4afaae260b16ef45b91ff4001e\n\n# tcId = 99\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = \nresult = invalid\ntag = 96dc6f5b892dbc574d38af7c1d5b30ab\n\n# tcId = 100\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 0001020304050607\nresult = invalid\ntag = 43812fb0921e0133aee885453639cc30\n\n# tcId = 101\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 7acebacb7b2fa78a976ec4389e75819f\n\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 102\n# empty message\nkey = 3d6bf9edae6d881eade0ff8c7076a4835b71320c1f36b631\nmsg = \nresult = valid\ntag = a8dd15fe2ce3495ec5b666744ec29220\n\n# tcId = 103\n# short message\nkey = 915429743435c28997a33b33b6574a953d81dae0e7032e6a\nmsg = 58\nresult = valid\ntag = e13b3f7f7f510c3a059df7a68c7e2ad5\n\n# tcId = 104\n# short message\nkey = f0c288ba26b284f9fb321b444a6517b3cdda1a799d55fdff\nmsg = 0f7e\nresult = valid\ntag = 06ef847f5f9dbf03a4f283da8c400220\n\n# tcId = 105\n# short message\nkey = 6b55e4d4fd6847a80a6bfb0dcc0aa93f9fd797fc5c50292e\nmsg = 33f530\nresult = valid\ntag = dd135053a47ca8f282c299e83b8c", "57c4\n\n# tcId = 106\n# short message\nkey = 1eb21a9e995a8e45c9e71ecbd6fe615b3e0318007c64b644\nmsg = 3aa73c48\nresult = valid\ntag = 1e93fff846934a6eea0575eecb0f0e1f\n\n# tcId = 107\n# short message\nkey = 710e2d5d4a9f0bc7e50796655e046a18cc5769d7764355da\nmsg = 7e4c690a88\nresult = valid\ntag = 016d4df06c68a6a788a9ea052e1b550d\n\n# tcId = 108\n# short message\nkey = d8c09ea400779b63e774bdacd0cb7b5dd6f736ca23d52acf\nmsg = e9520280973b\nresult = valid\ntag = 8030ae9f98f5d20c6089f6b1bd87c29e\n\n# tcId = 109\n# short message\nkey = 8e67e9a0863b55bed408866f1cbc05357abe3f9d79f406f2\nmsg = 4880b412287a0b\nresult = valid\ntag = bcaf50785f062a8fb8dd3c2c4cead2e1\n\n# tcId = 110\n# short message\nkey = 28d8da67806410e5565bcc5a9d7ab9fb357413fa0158378c\nmsg = 004e3f4a4e6db955\nresult = valid\ntag = c4c2c0876be9eabeb5a956da53846b08\n\n# tcId = 111\n# short message\nkey = dc968dd89fd602bb7eca6f3a8a13e4f59c08d02a514b1934\nmsg = 41a25354efeb1bc3b8\nresult = valid\ntag = f33a62caf397f9aff71fe42941ba41d8\n\n# tcId = 112\n# short message\nkey = 7658951c0f620d82afd92756cc2d7983b79da3e56fdd1b78\nmsg = f0e82fb5c5666f4af49f\nresult = valid\ntag = 4d724d05f3402967eb65ae1e32d5469e\n\n# tcId = 113\n# short message\nkey = d9574c3a221b986690931faac5258d9d3c52362b2cb9b054\nmsg = 178ea8404ba54ee4e4522c\nresult = valid\ntag = 64a0e0b6757309ab58d74f72c310e473\n\n# tcId = 114\n# short message\nkey = 704409bab28085c44981f28f75dd143a4f747106f63f262e\nmsg = cda5709e7f115624e74ab031\nresult = valid\ntag = 6ab2074334be14a95b6a241f897a43de\n\n# tcId = 115\n# short message\nkey = d8d06ef6a53bbff5c8f12d791b8f4c67e574bf440736d1cc\nmsg = a1171eae1979f48345dd9485a0\nresult = valid\ntag = 7aa57cf98b24897cc9230e3316758e61\n\n# tcId = 116\n# short message\nkey = 71129e781613f39d9ac39fbde2628b44c250c14deb5ef9e2\nmsg = 967593cc64bcbf7f3c58d04cb82b\nresult = valid\ntag = 6cc488b0a40eadbe4bcee2623239d126\n\n# tcId = 117\n# short message\nkey = 850fc859e9f7b89a367611dee6698f33962d8245ca8dc331\nmsg = 586f4f171af116519061a8e0e77940\nresult = valid\ntag = fb11a360c9776991d73d6e41d07710a2\n\n# tcId = 118\nkey = f4bfa5aa4f0f4d62cf736cd2969c43d580fdb92f2753bedb\nmsg = 0e239f239705b282ce2200fe20de1165\nresult = valid\ntag = ab20a6cf60873665b1d6999b05c7f9c6\n\n# tcId = 119\nkey = cfd3f68873d81a27d2bfce876c79f6e609074dec39e34614\nmsg = b1973cb25aa87ef9d1a8888b0a0f5c04c6\nresult = valid\ntag = b95a016b83a0ae4194023333c8a7345a\n\n# tcId = 120\nkey = 648a44468d67bb6744b235ee7a3fcd6ed4bdc29ec5b5fa1a\nmsg = c59d0d6981cca1be1d5519fc7881e6d230f39f6c12a9e827\nresult = valid\ntag = a1b96272ae7f9aef567271795f21d1d3\n\n# tcId = 121\nkey = 9d11abc1fcb248a436598e695be12c3c2ed90a18ba09d62c\nmsg = aa5182cae2a8fb068c0b3fb2be3e57ae523d13dffd1a944587707c2b67447f3f\nresult = valid\ntag = 8597d9a04d1c271d61d42f007b435175\n\n# tcId = 122\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ed12390ea0a7ed15d9d37a6eca1fc990\n\n# tcId = 123\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c81307df60859acb911c7be61be7ca90\n\n# tcId = 124\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f91bde0069a6e389573bf04e7cde688c\n\n# tcId = 125\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ee12390ea0a7ed15d9d37a6eca1fc990\n\n# tcId = 126\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = cb1307df60859acb911c7be61be7ca90\n\n# tcId = 127\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = fa1bde0069a6e389573bf04e7cde688c\n\n# tcId = 128\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = 6c12390ea0a7ed15d9d37a6eca1fc990\n\n# tcId = 129\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = 491307df60859acb911c7be61be7ca90\n\n# tcId = 130\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 781bde0069a6e389573bf04e7cde688c\n\n# tcId = 131\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec13390ea0a7ed15d9d37a6eca1fc990\n\n# tcId = 132\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91207df60859acb911c7be61be7ca90\n\n# tcId = 133\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81ade0069a6e389573bf04e7cde688c\n\n# tcId = 134\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12398ea0a7ed15d9d37a6eca1fc990\n\n# tcId = 135\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c913075f60859acb911c7be61be7ca90\n\n# tcId = 136\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde8069a6e389573bf04e7cde688c\n\n# tcId = 137\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea1a7ed15d9d37a6eca1fc990\n\n# tcId = 138\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df61859acb911c7be61be7ca90\n\n# tcId = 139\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde0068a6e389573bf04e7cde688c\n\n# tcId = 140\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea2a7ed15d9d37a6eca1fc990\n\n# tcId = 141\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df62859acb911c7be61be7ca90\n\n# tcId = 142\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde006ba6e389573bf04e7cde688c\n\n# tcId = 143\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea0a7ed95d9d37a6eca1fc990\n\n# tcId = 144\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df60859a4b911c7be61be7ca90\n\n# tcId = 145\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde0069a6e309573bf04e7cde688c\n\n# tcId = 146\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea0a7ed15d8d37a6eca1fc990\n\n# tcId = 147\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df60859acb901c7be61be7ca90\n\n# tcId = 148\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde0069a6e389563bf04e7cde688c\n\n# tcId = 149\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea0a7ed1559d37a6eca1fc990\n\n# tcId = 150\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df60859acb111c7be61be7ca90\n\n# tcId = 151\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f81bde0069a6e389d73bf04e7cde688c\n\n# tcId = 152\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = \nresult = invalid\ntag = ec12390ea0a7ed15d9f37a6eca1fc990\n\n# tcId = 153\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 0001020304050607\nresult = invalid\ntag = c91307df60859acb913c7be61be7ca90\n\n# tcId = 154\n# Flipped bit 77 in", @@ -3016,9 +3654,9 @@ static const char *kData106[] = { " d609717c3a4ef822ea200b297d2accec\n\n# tcId = 246\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e210cae26dad29bba32d\n\n# tcId = 247\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101e0089727691b7fb\n\n# tcId = 248\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2eb200b297d2accec\n\n# tcId = 249\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cbe26dad29bba32d\n\n# tcId = 250\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0109f0089727691b7fb\n\n# tcId = 251\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a26a200b297d2accec\n\n# tcId = 252\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e2904ae26dad29bba32d\n\n# tcId = 253\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f2089727691b7fb\n\n# tcId = 254\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea000b297d2accec\n\n# tcId = 255\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cac26dad29bba32d\n\n# tcId = 256\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0088727691b7fb\n\n# tcId = 257\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200a297d2accec\n\n# tcId = 258\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26cad29bba32d\n\n# tcId = 259\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727791b7fb\n\n# tcId = 260\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297c2accec\n\n# tcId = 261\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad28bba32d\n\n# tcId = 262\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727491b7fb\n\n# tcId = 263\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297f2accec\n\n# tcId = 264\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad2bbba32d\n\n# tcId = 265\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f008972f691b7fb\n\n# tcId = 266\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b29fd2accec\n\n# tcId = 267\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dada9bba32d\n\n# tcId = 268\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727691b7fa\n\n# tcId = 269\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297d2acced\n\n# tcId = 270\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad29bba32c\n\n# tcId = 271\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727691b7f9\n\n# tcId = 272\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297d2accee\n\n# tcId = 273\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad29bba32f\n\n# tcId = 274\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727691b7bb\n\n# tcId = 275\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297d2accac\n\n# tcId = 276\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad29bba36d\n\n# tcId = 277\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0101f0089727691b77b\n\n# tcId = 278\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef8a2ea200b297d2acc6c\n\n# tcId = 279\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3f3b5f83e290cae26dad29bba3ad\n\n# tcId = 280\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6af0a293d8cba0101e0089727691b7fb\n\n# tcId = 281\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d709717c3a4ef8a2eb200b297d2accec\n\n# tcId = 282\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58ee3f3b5f83e290cbe26dad29bba32d\n\n# tcId = 283\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a213d8cba0901f0089727691b7fb\n\n# tcId = 284\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d60971fc3a4ef822ea200b297d2accec\n\n# tcId = 285\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee3fbb5f83e210cae26dad29bba32d\n\n# tcId = 286\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6bf0a293d8cba0901f0089727691b77b\n\n# tcId = 287\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d609717c3a4ef822ea200b297d2acc6c\n\n# tcId = 288\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 59ee", "3f3b5f83e210cae26dad29bba3ad\n\n# tcId = 289\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 940f5d6c27345fefe0ff768d896e4804\n\n# tcId = 290\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = 29f68e83c5b1075d15dff4d682d53313\n\n# tcId = 291\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a611c0c4a07c1d6f351d9252d6445cd2\n\n# tcId = 292\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 293\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 294\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 295\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 296\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 297\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 298\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = eb702213584b20909f8009f2f611377b\n\n# tcId = 299\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = 5689f1fcbace78226aa08ba9fdaa4c6c\n\n# tcId = 300\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d96ebfbbdf0362104a62ed2da93b23ad\n\n# tcId = 301\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 6af1a392d9caa1111e0188737790b6fa\n\n# tcId = 302\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 0001020304050607\nresult = invalid\ntag = d708707d3b4ff9a3eb210a287c2bcded\n\n# tcId = 303\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58ef3e3a5e82e391cbe36cac28baa22c\n\n[keySize = 0]\n[tagSize = 128]\n\n# tcId = 304\n# invalid key size\nkey = \nmsg = 00b9449326d39416\nresult = invalid\ntag = \n\n[keySize = 8]\n[tagSize = 128]\n\n# tcId = 305\n# invalid key size\nkey = 0f\nmsg = 4538b79a1397e2aa\nresult = invalid\ntag = \n\n[keySize = 64]\n[tagSize = 128]\n\n# tcId = 306\n# invalid key size\nkey = a88e385af7185148\nmsg = dc63b7ef08096e4f\nresult = invalid\ntag = \n\n[keySize = 160]\n[tagSize = 128]\n\n# tcId = 307\n# invalid key size\nkey = 003a228008d390b645929df73a2b2bdd8298918d\nmsg = ad1d3c3122ab7ac6\nresult = invalid\ntag = \n\n[keySize = 320]\n[tagSize = 128]\n\n# tcId = 308\n# invalid key size\nkey = 94baaac150e2645ae1ec1939c7bcefb73f6edb146fae02289b6c6326ff39bc265d612bef2727fa72\nmsg = e3f75a886c4a5591\nresult = invalid\ntag = \n\n", }; -static const size_t kLen107 = 44166; +static const size_t kLen161 = 44166; -static const char *kData107[] = { +static const char *kData161[] = { "# Imported from Wycheproof's aes_gcm_siv_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: AES-GCM-SIV\n# Generator version: 0.8r12\n\n[ivSize = 96]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 1\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = \niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = \nresult = valid\ntag = dc20e2d83f25705bb49e439eca56de25\n\n# tcId = 2\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = b5d839330ac7b786\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 0100000000000000\nresult = valid\ntag = 578782fff6013b815b287c22493a364c\n\n# tcId = 3\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 7323ea61d05932260047d942\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 010000000000000000000000\nresult = valid\ntag = a4978db357391a0bc4fdec8b0d106639\n\n# tcId = 4\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 743f7c8077ab25f8624e2e948579cf77\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 01000000000000000000000000000000\nresult = valid\ntag = 303aaf90f6fe21199c6068577437a0c4\n\n# tcId = 5\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 84e07e62ba83a6585417245d7ec413a9fe427d6315c09b57ce45f2e3936a9445\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 0100000000000000000000000000000002000000000000000000000000000000\nresult = valid\ntag = 1a8e45dcd4578c667cd86847bf6155ff\n\n# tcId = 6\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 3fd24ce1f5a67b75bf2351f181a475c7b800a5b4d3dcf70106b1eea82fa1d64df42bf7226122fa92e17a40eeaac1201b\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nresult = valid\ntag = 5e6e311dbf395d35b0fe39c2714388f8\n\n# tcId = 7\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 2433668f1058190f6d43e360f4f35cd8e475127cfca7028ea8ab5c20f7ab2af02516a2bdcbc08d521be37ff28c152bba36697f25b4cd169c6590d1dd39566d3f\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nresult = valid\ntag = 8a263dd317aa88d56bdf3936dba75bb8\n\n# tcId = 8\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 1e6daba35669f427\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 0200000000000000\nresult = valid\ntag = 3b0a1a2560969cdf790d99759abd1508\n\n# tcId = 9\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 296c7889fd99f41917f44620\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 020000000000000000000000\nresult = valid\ntag = 08299c5102745aaa3a0c469fad9e075a\n\n# tcId = 10\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = e2b0c5da79a901c1745f700525cb335b\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 02000000000000000000000000000000\nresult = valid\ntag = 8f8936ec039e4e4bb97ebd8c4457441f\n\n# tcId = 11\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 620048ef3c1e73e57e02bb8562c416a319e73e4caac8e96a1ecb2933145a1d71\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 0200000000000000000000000000000003000000000000000000000000000000\nresult = valid\ntag = e6af6a7f87287da059a71684ed3498e1\n\n# tcId = 12\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 50c8303ea93925d64090d07bd109dfd9515a5a33431019c17d93465999a8b0053201d723120a8562b838cdff25bf9d1e\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nresult = valid\ntag = 6a8cc3865f76897c2e4b245cf31c51f2\n\n# tcId = 13\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 2f5c64059db55ee0fb847ed513003746aca4e61c711b5de2e7a77ffd02da42feec601910d3467bb8b36ebbaebce5fba30d36c95f48a3e7980f0e7ac299332a80\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nresult = valid\ntag = cdc46ae475563de037001ef84ae21744\n\n# tcId = 14\n# draft-irtf-cfrg-gcmsiv-09\naad = 010000000000000000000000\nct = a8fe3e87\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 02000000\nresult = valid\ntag = 07eb1f84fb28f8cb73de8e99e2f48a14\n\n# tcId = 15\n# draft-irtf-cfrg-gcmsiv-09\naad = 010000000000000000000000000000000200\nct = 6bb0fecf5ded9b77f902c7d5da236a4391dd0297\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 0300000000000000000000000000000004000000\nresult = valid\ntag = 24afc9805e976f451e6d87f6fe106514\n\n# tcId = 16\n# draft-irtf-cfrg-gcmsiv-09\naad = 0100000000000000000000000000000002000000\nct = 44d0aaf6fb2f1f34add5e8064e83e12a2ada\niv = 030000000000000000000000\nkey = 01000000000000000000000000000000\nmsg = 030000000000000000000000000000000400\nresult = valid\ntag = bff9b2ef00fb47920cc72a0c0f13b9fd\n\n# tcId = 17\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = \niv = f46e44bb3da0015c94f70887\nkey = e66021d5eb8e4f4066d4adb9c33560e4\nmsg = \nresult = valid\ntag = a4194b79071b01a87d65f706e3949578\n\n# tcId = 18\n# draft-irtf-cfrg-gcmsiv-09\naad = 46bb91c3c5\nct = af60eb\niv = bae8e37fc83441b16034566b\nkey = 36864200e0eaf5284d884a0e77d31646\nmsg = 7a806c\nresult = valid\ntag = 711bd85bc1e4d3e0a462e074eea428a8\n\n# tcId = 19\n# draft-irtf-cfrg-gcmsiv-09\naad = fc880c94a95198874296\nct = bb93a3e34d3c\niv = afc0577e34699b9e671fdd4f\nkey = aedb64a6c590bc84d1a5e269e4b47801\nmsg = bdc66f146545\nresult = valid\ntag = d6a9c45545cfc11f03ad743dba20f966\n\n# tcId = 20\n# draft-irtf-cfrg-gcmsiv-09\naad = 046787f3ea22c127aaf195d1894728\nct = 4f37281f7ad12949d0\niv = 275d1ab32f6d1f0434d8848c\nkey = d5cc1fd161320b6920ce07787f86743b\nmsg = 1177441f195495860f\nresult = valid\ntag = 1d02fd0cd174c84fc5dae2f60f52fd2b\n\n# tcId = 21\n# draft-irtf-cfrg-gcmsiv-09\naad = c9882e5386fd9f92ec489c8fde2be2cf97e74e93\nct = f54673c5ddf710c745641c8b\niv = 9e9ad8780c8d63d0ab4149c0\nkey = b3fed1473c528b8426a582995929a149\nmsg = 9f572c614b4745914474e7c7\nresult = valid\ntag = c1dc2f871fb7561da1286e655e24b7b0\n\n# tcId = 22\n# draft-irtf-cfrg-gcmsiv-09\naad = 2950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0a\nct = c9ff545e07b88a015f05b274540aa1\niv = ac80e6f61455bfac8308a2d4\nkey = 2d4ed87da44102952ef94b02b805249b\nmsg = 0d8c8451178082355c9e940fea2f58\nresult = valid\ntag = 83b3449b9f39552de99dc214a1190b0b\n\n# tcId = 23\n# draft-irtf-cfrg-gcmsiv-09\naad = 1860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f\nct = 6298b296e24e8cc35dce0bed484b7f30d580\niv = ae06556fb6aa7890bebc18fe\nkey = bde3b2f204d1e9f8b06bc47f9745b3d1\nmsg = 6b3db4da3d57aa94842b9803a96e07fb6de7\nresult = valid\ntag = 3e377094f04709f64d7b985310a4db84\n\n# tcId = 24\n# draft-irtf-cfrg-gcmsiv-09\naad = 7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296fa859c21\nct = 391cc328d484a4f46406181bcd62efd9b3ee197d05\niv = 6245709fb18853f68d833640\nkey = f901cfe8a69615a93fdf7a98cad48179\nmsg = e42a3c02c25b64869e146d7b233987bddfc240871d\nresult = valid\ntag = 2d15506c84a9edd65e13e9d24a2a6e70\n\n# tcId = 25\naad = \nct = \niv = 438a547a94ea88dce46c6c85\nkey = bedcfb5a011ebc84600fcb296c15af0d\nmsg = \nresult = valid\ntag = 596d0538e48526be1c991e40cc031073\n\n# tcId = 26\naad = \nct = 4f\niv = b30c084727ad1c592ac21d12\nkey = 384ea416ac3c2f51a76e7d8226346d4e\nmsg = 35\nresult = valid\ntag = 8b2b805fc0885e2b470d9dbe6cb15ed3\n\n# tcId = 27\naad = \nct = 04c7a55f97846e54\niv = b5e006ded553110e6dc56529\nkey = cae31cd9f55526eb038241fc44cac1e5\nmsg = d10989f2c52e94ad\nresult = valid\ntag = 48168ff846356c33032c719b518f18a8\n\n# tcId = 28\naad = \nct = fd9521041b0397a15b0070b93f48a9\niv = ecb0c42f7000ef0e6f95f24d\nkey = dd6197cd63c963919cf0c273ef6b28bf\nmsg = 4dcc1485365866e25ac3f2ca6aba97\nresult = valid\ntag = 09df91414578f7faf757d04ee26ab901\n\n# tcId = 29\naad = \nct = 6eb905287ddfafc32f6b1c10046c089f\niv = 0e1666f2dc652f7708fb8f0d\nkey = ffdf4228361ea1f8165852136b3480f7\nmsg = 25b12e28ac0ef6ead0226a3b2288c800\nresult = valid\ntag = 4ff9f939a77c34b0cb1ee75fcb0dd29a\n\n# tcId = 30\naad = \nct = 6f62bd09d4f36f73e289ab6dd114727fe3\niv = 965ff6643116ac1443a2dec7\nkey = c15ed227dd2e237ecd087eaaaad19ea4\nmsg = fee62fde973fe025ad6b322dcdf3c63fc7\nresult = valid\ntag = ea727c084db2bc948de0928edddd7fcf\n\n# tcId = 31\naad = \nct = 80133a4bea7311f0d3c9835144c37c4ef0", "ef20c8f2e36be1\niv = fbbc04fd6e025b7193eb57f6\nkey = a8ee11b26d7ceb7f17eaa1e4b83a2cf6\nmsg = c08f085e6a9e0ef3636280c11ecfadf0c1e72919ffc17eaf\nresult = valid\ntag = b92f47c1af6713e14fbdf60efebb50c6\n\n# tcId = 32\naad = \nct = 778b308e4ca17607df36c0b94695bc64603173b814701a9f69147b42478a0b1f\niv = a2dbe708db51c68ef02994a6\nkey = 7519588f30f7f08ff98e1beee6a2a783\nmsg = 1851956319256ebb0f9ccaf325a24abfc5c3e90b055e57cdc0c7ab2165ae03b1\nresult = valid\ntag = b75c98952c0aa11958a55c9c2ecf33f5\n\n# tcId = 33\naad = 30\nct = 173ba6370171be47dbb6163a63a3b725\niv = 4bad10c6d84fd43fd13ad36f\nkey = a5b5b6bae45b741fe4663890098f326a\nmsg = 127b150080ec0bc7704e26f4ab11abb6\nresult = valid\ntag = 53aefed6e971d5a1f435f0730a6dd0fd\n\n# tcId = 34\naad = 743e\nct = 959f0ff12481dedc4302ad7a904f9486\niv = 2186a3091237adae83540e24\nkey = 0cecb9f512932d68e2c7c0bc4bd621c8\nmsg = 437aeb94d842283ba57bb758e3d229f0\nresult = valid\ntag = 0215be2ab9b0672a7b82893891057c9c\n\n# tcId = 35\naad = 25591707c004f506f4b51e85e29f6a\nct = 8ae3a16a237f1358ac8cfeb5f4cc2818\niv = 0c908e58cddad69dea1a32c3\nkey = 55e04c122780be52ed9328928039008c\nmsg = 26eb70672eef03667b34cc7d0df05872\nresult = valid\ntag = 28f5aa8a34a9f7c01c17759d142b1bae\n\n# tcId = 36\naad = c07092d799dac2b4c05fbddd04743c34\nct = d5220f6a49d1e4c10d38c77c8156ebd0\niv = c30968c967e53505621628db\nkey = 5f0a1b5f8f8673d566ec7f54e7dca4f2\nmsg = f6538476daf04524cf134309dd84e187\nresult = valid\ntag = 80b50f526286dad22d40984636f0e9ce\n\n# tcId = 37\naad = 3ea12d80f40f34f812479d2ecc13d2d6df\nct = 3e771b9376e1d1cde3d9b73349c958bc\niv = a51c37f467893c1608e56274\nkey = 671a70e883fb0611dffd0b1dd9b8cca2\nmsg = 3baf3edf04dc0c97aae081cdeb08021d\nresult = valid\ntag = ebd3ea678a1e87839a4356584ea89bac\n\n# tcId = 38\naad = 5189ea6f39b2a78c0202fdff146c5cc6bdc7491d4786f80c6c6aef65634c05da\nct = 05b568a589d0a77a8ee9c6f06415c6b6\niv = 52c20979cdaaade573dba650\nkey = 63f03172505d90e94900125cb8a4b0dd\nmsg = 602c98997ee03fd11ce00e92de193977\nresult = valid\ntag = 91ba5089dffb7538199c441728d5f84a\n\n# tcId = 39\n# Testing for ctr overflow\naad = 395f4091b410c373073bcdc79e02d3af\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 010101010101010101010101\nkey = 00112233445566778899aabbccddeeff\nmsg = 43488548d88e6f774bcd2d52c18fbcc933a4e9a9613ff3edbe959ec59522adc098b3133b8d17b9e9dad631ad33752c95\nresult = valid\ntag = 00000000000000000000000000000000\nflags = ConstructedIv\n\n# tcId = 40\n# Testing for ctr overflow\naad = 616b2dff4d665e5f7ab890723dd981b1\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = f012c6a7eb0e8af5bc45e015e7680a693dc709b95383f6a94babec1bc36e4be3cf4f55a31a94f11c6c3f90eed99682bc\nresult = valid\ntag = ffffffffffffffffffffffffffffffff\nflags = ConstructedIv\n\n# tcId = 41\n# Testing for ctr overflow\naad = 387a8997605fd04ae8951c4759087864\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 030303030303030303030303\nkey = 00112233445566778899aabbccddeeff\nmsg = 71ceee58179d6fb968521e9594dbf98cc0040f6aa38fe873c32a9b122d6cbfd51aa4778b3f4f37be7348690d97e2468b\nresult = valid\ntag = fefffffffefffffffefffffffeffffff\nflags = ConstructedIv\n\n# tcId = 42\n# Testing for ctr overflow\naad = 6783b0d5e9d8a2a7274065797097d1ae\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 060606060606060606060606\nkey = 00112233445566778899aabbccddeeff\nmsg = 2e14f9e9a09ea204557367898a80dcad117af3666bea25762b70633a9f3614fbe631ba617c371fd5566d5e613496e69f\nresult = valid\ntag = ffffff7f00112233445566778899aabb\nflags = ConstructedIv\n\n# tcId = 43\n# Testing for ctr overflow\naad = 2933810c146f4f7dd146dd43f35199c6\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 010101010101010101010101\nkey = 00112233445566778899aabbccddeeff\nmsg = 27fac75879c9d87cd52a0793137ba792f6f145148158eb538f2081e09cd0315986a7025045ecbb2ca1bb18a17bfcd567\nresult = valid\ntag = ffffffffffffff7f0011223344556677\nflags = ConstructedIv\n\n# tcId = 44\n# Flipped bit 0 in tag\naad = 27dd62060507dae87c4f93f391ba15f9\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 45\n# Flipped bit 0 in tag\naad = 9ea3371e258288d5a01b15384e2c99ee\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 46\n# Flipped bit 0 in tag\naad = ce24e3ec0fe7b8550d621b71fdb5d0eb\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 47\n# Flipped bit 7 in tag\naad = 1471f354b359c235117febba854a823b\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 48\n# Flipped bit 7 in tag\naad = 11f820294fc9d13f1895d2fb5509913b\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 49\n# Flipped bit 8 in tag\naad = 45e7257b814f09de44177b27b914822f\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 50\n# Flipped bit 8 in tag\naad = 4c49780b5438c4a7ea9795b9856fdae1\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 51\n# Flipped bit 8 in tag\naad = ecc2f2f4142837a34f9cd1fa030a5d7f\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 52\n# Flipped bit 31 in tag\naad = 69c7f5605da8e0684990b087411f8cf5\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 53\n# Flipped bit 31 in tag\naad = 20b346be60e7e97588bf504ce707ce0b\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 54\n# Flipped bit 56 in tag\naad = 3955107da2e9938c6b19bb19ae9fc09f\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 55\n# Flipped bit 56 in tag\naad = b1385d46a8accd7022c142442a0b13e9\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 56\n# Flipped bit 63 in tag\naad = 19b298f3a061a73cb774da927ce11ca2\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 57\n# Flipped bit 63 in tag\naad = bff8c631e61c18a050a523ad4a750a20\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 58\n# Flipped bit 64 in tag\naad = 7b6171302b689c926852163e310f08d4\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 59\n# Flipped bit 88 in tag\naad = 4e79aa30003226402245893e91f2024c\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 60\n# Flipped bit 88 in tag\naad = 9312e1813a05b8682", "555061b05edcef1\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 61\n# Flipped bit 96 in tag\naad = 643684185211af58061022efa360d54b\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 62\n# Flipped bit 96 in tag\naad = 786d8056e26150918e3cbe520cafeb50\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 63\n# Flipped bit 97 in tag\naad = 555036128fa18ecadd090cb772ac0bf3\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 64\n# Flipped bit 97 in tag\naad = a5b43b8e1dbb2bfbda1b625fee4064a7\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 65\n# Flipped bit 120 in tag\naad = ae47cc5d7681dd480c23469c5519b647\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 66\n# Flipped bit 120 in tag\naad = d53dd677184702eaa660f1349195fc04\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 67\n# Flipped bit 120 in tag\naad = dc78584e4599dd4b2fb333db2f9ccb95\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 68\n# Flipped bit 121 in tag\naad = 0bfd9271e79153a8afdb7f3d96fe446f\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 69\n# Flipped bit 121 in tag\naad = 1e0537a95b7200134d0b440657d50fd1\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 70\n# Flipped bit 121 in tag\naad = 7633155df35857258d23b0651d60847c\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 71\n# Flipped bit 126 in tag\naad = ab0a064b473de43598adf81ee297d856\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 0fed395814f1750a\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 72\n# Flipped bit 127 in tag\naad = f62bdc3f4fcb699ee12f6e87dcc704cb\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 73\n# Flipped bit 127 in tag\naad = 1320051031807b8f44e9d2cb1ec6aa92\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 03c0e39b77bd62d32568f4c86c90bfdb\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 74\n# Flipped bit 127 in tag\naad = 329b813d3ae2225d3e15f97a28037bcc\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 75\n# Flipped bit 0..127 in tag\naad = edc723bedd0078696acdea005c74b841\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = 63995888995b338c\nresult = invalid\ntag = 00000000000000000000000000000000\n\n[ivSize = 96]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 76\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = \niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = \nresult = valid\ntag = 07f5f4169bbf55a8400cd47ea6fd400f\n\n# tcId = 77\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = c2ef328e5c71c83b\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 0100000000000000\nresult = valid\ntag = 843122130f7364b761e0b97427e3df28\n\n# tcId = 78\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 9aab2aeb3faa0a34aea8e2b1\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 010000000000000000000000\nresult = valid\ntag = 8ca50da9ae6559e48fd10f6e5c9ca17e\n\n# tcId = 79\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 85a01b63025ba19b7fd3ddfc033b3e76\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 01000000000000000000000000000000\nresult = valid\ntag = c9eac6fa700942702e90862383c6c366\n\n# tcId = 80\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = 4a6a9db4c8c6549201b9edb53006cba821ec9cf850948a7c86c68ac7539d027f\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 0100000000000000000000000000000002000000000000000000000000000000\nresult = valid\ntag = e819e63abcd020b006a976397632eb5d\n\n# tcId = 81\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = c00d121893a9fa603f48ccc1ca3c57ce7499245ea0046db16c53c7c66fe717e39cf6c748837b61f6ee3adcee17534ed5\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 010000000000000000000000000000000200000000000000000000000000000003000000000000000000000000000000\nresult = valid\ntag = 790bc96880a99ba804bd12c0e6a22cc4\n\n# tcId = 82\n# draft-irtf-cfrg-gcmsiv-09\naad = \nct = c2d5160a1f8683834910acdafc41fbb1632d4a353e8b905ec9a5499ac34f96c7e1049eb080883891a4db8caaa1f99dd004d80487540735234e3744512c6f90ce\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 01000000000000000000000000000000020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nresult = valid\ntag = 112864c269fc0d9d88c61fa47e39aa08\n\n# tcId = 83\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 1de22967237a8132\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 0200000000000000\nresult = valid\ntag = 91213f267e3b452f02d01ae33e4ec854\n\n# tcId = 84\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 163d6f9cc1b346cd453a2e4c\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 020000000000000000000000\nresult = valid\ntag = c1a4a19ae800941ccdc57cc8413c277f\n\n# tcId = 85\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = c91545823cc24f17dbb0e9e807d5ec17\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 02000000000000000000000000000000\nresult = valid\ntag = b292d28ff61189e8e49f3875ef91aff7\n\n# tcId = 86\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 07dad364bfc2b9da89116d7bef6daaaf6f255510aa654f920ac81b94e8bad365\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 0200000000000000000000000000000003000000000000000000000000000000\nresult = valid\ntag = aea1bad12702e1965604374aab96dbbc\n\n# tcId = 87\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = c67a1f0f567a5198aa1fcc8e3f21314336f7f51ca8b1af61feac35a86416fa47fbca3b5f749cdf564527f2314f42fe25\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 020000000000000000000000000000000300000000000000000000000000000004000000000000000000000000000000\nresult = valid\ntag = 03332742b228c647173616cfd44c54eb\n\n# tcId = 88\n# draft-irtf-cfrg-gcmsiv-09\naad = 01\nct = 67fd45e126bfb9a79930c43aad2d36967d3f0e4d217c1e551f59727870beefc98cb933a8fce9de887b1e40799988db1fc3f91880ed405b2dd298318858467c89\niv = 030000000000000000000000\nkey = 0100000000000000000000000000000000000000000000000000000000000000\nmsg = 02000000000000000000000000000000030000000000000000000000000000000400000000000000000000000000000005000000000000000000000000000000\nresult = valid\ntag = 5bde0285037c5de81e5b570a049b62a0\n\n# tcId = 89\n# draft-irtf-cfrg-gcmsiv-09\naad = 010000000000", @@ -3026,9 +3664,9 @@ static const char *kData107[] = { "2030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = d04846a01f472262e60a1cb4cfcbdcb05c3f819628a3a49395c5dae96c434b2417ce071699afa74a60c32c0bafd9c01a\nresult = valid\ntag = ffffffffffffffffffffffffffffffff\nflags = ConstructedIv\n\n# tcId = 118\n# Testing for ctr overflow\naad = 2e34d12622a441b557eeb1d647c6cb73\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 010101010101010101010101\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 79637cee9decf33e3080de3d2c55bd21cd529ba8080b583edb6cfe13cda04bd00debe58b8cd48d6e02a1ecfc4d87923a\nresult = valid\ntag = fefffffffefffffffefffffffeffffff\nflags = ConstructedIv\n\n# tcId = 119\n# Testing for ctr overflow\naad = 0814a95481bf915a4097949e3525c7e7\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 000000000000000000000000\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 6492a73880dac7f36743715b0fc7063d3e46a25044310bba5849ed88bfcb54b0adbe3978040bda849906e1aa09d1a8e3\nresult = valid\ntag = ffffff7f00112233445566778899aabb\nflags = ConstructedIv\n\n# tcId = 120\n# Testing for ctr overflow\naad = b691ef42f2ab8d1b4a581bb08394b13a\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\niv = 010101010101010101010101\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 7848d9e872f40bca1b82a4e7185fb75193b3496cc1dc2a72b86ed156ab8389e71687ed25eb6485e66561fa8c39853368\nresult = valid\ntag = ffffffffffffff7f0011223344556677\nflags = ConstructedIv\n\n# tcId = 121\n# Flipped bit 0 in tag\naad = e144878b0bbbf01b75231277e1e0d114\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 122\n# Flipped bit 0 in tag\naad = 0289eaa93eb084107d2088435ef2a0cd\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 123\n# Flipped bit 1 in tag\naad = f3bd6013669b7d9371727fcb1aafea75\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 124\n# Flipped bit 7 in tag\naad = 922e91b2c5016e4303c737d1608ca25f\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 125\n# Flipped bit 7 in tag\naad = 7195dd0addce5dd7014bfddb2f23206f\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 126\n# Flipped bit 7 in tag\naad = 32fc2a53e9678f1fc6d63081c36c6f2c\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 127\n# Flipped bit 8 in tag\naad = c55ba71ee250216f8ecfe822d712dd38\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 128\n# Flipped bit 8 in tag\naad = 5546acf865fc305fbd7ff1092cb9c2c3\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 129\n# Flipped bit 31 in tag\naad = 6b060eebe1843b409a4dfd0be8f86a2b\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 130\n# Flipped bit 31 in tag\naad = c4adb92f1a60eb2faff88675f62a7276\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 131\n# Flipped bit 32 in tag\naad = 70c5a8591f52f869c6415a6d7000e253\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 132\n# Flipped bit 56 in tag\naad = 46c788111083d8913153a6e37e5506a3\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 133\n# Flipped bit 56 in tag\naad = 1ed7665962378cec4039c793a8f744d0\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 134\n# Flipped bit 56 in tag\naad = a0f7587c5862609c6dc983780bcda180\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 135\n# Flipped bit 63 in tag\naad = b5fe79f182cb9f2945208e29513928d1\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 136\n# Flipped bit 63 in tag\naad = c1dbf87e4a586b040c53f6dd9063b4cd\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 137\n# Flipped bit 64 in tag\naad = 845466e603ca85a224693d150ae13ba3\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 138\n# Flipped bit 88 in tag\naad = 90a992a8443d65870b4d8bca85e4a698\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 139\n# Flipped bit 88 in tag\naad = e1737a834410e5fba6cdc1d1f7d12c12\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 140\n# Flipped bit 96 in tag\naad = 445c8fffa3d960e39ca86260c66418d8\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 141\n# Flipped bit 97 in tag\naad = 18cb9f5eede6224fa3fcd525cf9f958b\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 142\n# Flipped bit 97 in tag\naad = 8c4fbca37d2e361856b9f80adf455fa0\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 143\n# Flipped bit 97 in tag\naad = bc517fe140abf2b42eb1cafe8c0715a9\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 144\n# Flipped bit 120 in tag\naad = 617e1c5ef62ed35cf678e670f116ff2f\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff001122", "33445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 145\n# Flipped bit 120 in tag\naad = e71802b7a37e8ef1f001ef0c52c636f2\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 146\n# Flipped bit 120 in tag\naad = be647e37f154d4a8edca5a29ca221cc5\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 147\n# Flipped bit 121 in tag\naad = b3caa01f49c7cbc56c7c92547257957e\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 148\n# Flipped bit 121 in tag\naad = ab0347a2aec4cc4c366583062442ba07\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 149\n# Flipped bit 126 in tag\naad = 62573ef39a27f77b37fb7bfc84e46cee\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 150\n# Flipped bit 126 in tag\naad = 28e3cadfb16834e824642e965588c200\nct = 0000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 759dfbbb8a251ccc\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 151\n# Flipped bit 126 in tag\naad = 7edd2fc15bed224a46dc8608e1766080\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 152\n# Flipped bit 127 in tag\naad = 7e0e03104e2c0ff20ba4c35742180c5b\nct = \niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = \nresult = invalid\ntag = 0987e35e40981a2730c1740c7201731f\n\n# tcId = 153\n# Flipped bit 127 in tag\naad = 9a24dc75c5ddd3bab57ff532eb86d224\nct = 00000000000000000000000000000000\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = f663044a4e7dd822aba0b7de2d869981\nresult = invalid\ntag = 13a1883272188b4c8d2727178198fe95\n\n# tcId = 154\n# Flipped bit 127 in tag\naad = 3196aec499c15bc043b6866ba0df6e6b\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 155\n# Flipped bit 0..127 in tag\naad = 55a2987aa94bf46ad1b6d253a44c1622\nct = ffffffffffffffff\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\nmsg = 49861b1fb6bcf8e4\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n", }; -static const size_t kLen108 = 81097; +static const size_t kLen162 = 81097; -static const char *kData108[] = { +static const char *kData162[] = { "# Imported from Wycheproof's aes_gcm_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: AES-GCM\n# Generator version: 0.8r12\n\n[ivSize = 96]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 1\naad = \nct = 26073cc1d851beff176384dc9896d5ff\niv = 028318abc1824029138141a2\nkey = 5b9604fe14eadba931b0ccf34843dab9\nmsg = 001d0c231287c1182784554ca3a21908\nresult = valid\ntag = 0a3ea7a5487cb5f7d70fb6c58d038554\n\n# tcId = 2\naad = 00112233445566778899aabbccddeeff\nct = 49d8b9783e911913d87094d1f63cc765\niv = 921d2507fa8007b7bd067d34\nkey = 5b9604fe14eadba931b0ccf34843dab9\nmsg = 001d0c231287c1182784554ca3a21908\nresult = valid\ntag = 1e348ba07cca2cf04c618cb4d43a5b92\n\n# tcId = 3\naad = aac39231129872a2\nct = eea945f3d0f98cc0fbab472a0cf24e87\niv = 0432bc49ac34412081288127\nkey = aa023d0478dcb2b2312498293d9a9129\nmsg = 2035af313d1346ab00154fea78322105\nresult = valid\ntag = 4bb9b4812519dadf9e1232016d068133\n\n# tcId = 4\naad = \nct = \niv = 438a547a94ea88dce46c6c85\nkey = bedcfb5a011ebc84600fcb296c15af0d\nmsg = \nresult = valid\ntag = 960247ba5cde02e41a313c4c0136edc3\n\n# tcId = 5\naad = \nct = 54\niv = b30c084727ad1c592ac21d12\nkey = 384ea416ac3c2f51a76e7d8226346d4e\nmsg = 35\nresult = valid\ntag = 7c1e4ae88bb27e5638343cb9fd3f6337\n\n# tcId = 6\naad = \nct = a036ead03193903f\niv = b5e006ded553110e6dc56529\nkey = cae31cd9f55526eb038241fc44cac1e5\nmsg = d10989f2c52e94ad\nresult = valid\ntag = 3b626940e0e9f0cbea8e18c437fd6011\n\n# tcId = 7\naad = \nct = 8a9992388e735f80ee18f4a63c10ad\niv = ecb0c42f7000ef0e6f95f24d\nkey = dd6197cd63c963919cf0c273ef6b28bf\nmsg = 4dcc1485365866e25ac3f2ca6aba97\nresult = valid\ntag = 1486a91cccf92c9a5b00f7b0e034891c\n\n# tcId = 8\naad = \nct = f7bd379d130477176b8bb3cb23dbbbaa\niv = 0e1666f2dc652f7708fb8f0d\nkey = ffdf4228361ea1f8165852136b3480f7\nmsg = 25b12e28ac0ef6ead0226a3b2288c800\nresult = valid\ntag = 1ee6513ce30c7873f59dd4350a588f42\n\n# tcId = 9\naad = \nct = 0de51fe4f7f2d1f0f917569f5c6d1b009c\niv = 965ff6643116ac1443a2dec7\nkey = c15ed227dd2e237ecd087eaaaad19ea4\nmsg = fee62fde973fe025ad6b322dcdf3c63fc7\nresult = valid\ntag = 6cd8521422c0177e83ef1b7a845d97db\n\n# tcId = 10\naad = \nct = 7cd9f4e4f365704fff3b9900aa93ba54b672bac554275650\niv = fbbc04fd6e025b7193eb57f6\nkey = a8ee11b26d7ceb7f17eaa1e4b83a2cf6\nmsg = c08f085e6a9e0ef3636280c11ecfadf0c1e72919ffc17eaf\nresult = valid\ntag = f4eb193241226db017b32ec38ca47217\n\n# tcId = 11\naad = c3\nct = f58d453212c2c8a436e9283672f579f119122978\niv = 32bcb9b569e3b852d37c766a\nkey = 28ff3def08179311e2734c6d1c4e2871\nmsg = dfc61a20df8505b53e3cd59f25770d5018add3d6\nresult = valid\ntag = 5901131d0760c8715901d881fdfd3bc0\n\n# tcId = 12\naad = 834afdc5c737186b\nct = bf864616c2347509ca9b10446379b9bdbb3b8f64\niv = 9c3a4263d983456658aad4b1\nkey = e63a43216c08867210e248859eb5e99c\nmsg = b14da56b0462dc05b871fc815273ff4810f92f4b\nresult = valid\ntag = a97d25b490390b53c5db91f6ee2a15b8\n\n# tcId = 13\naad = 4020855c66ac4595058395f367201c4c\nct = a6f2ef3c7ef74a126dd2d5f6673964e27d5b34b6\niv = 33e90658416e7c1a7c005f11\nkey = 38449890234eb8afab0bbf82e2385454\nmsg = f762776bf83163b323ca63a6b3adeac1e1357262\nresult = valid\ntag = b8bbdc4f5014bc752c8b4e9b87f650a3\n\n# tcId = 14\naad = 76eb5f147250fa3c12bff0a6e3934a0b16860cf11646773b\nct = bd64802cfebaeb487d3a8f76ce943a37b3472dd5\niv = 9f0d85b605711f34cd2a35ba\nkey = 6a68671dfe323d419894381f85eb63fd\nmsg = 0fc67899c3f1bbe196d90f1eca3797389230aa37\nresult = valid\ntag = fce9a5b530c7d7af718be1ec0ae9ed4d\n\n# tcId = 15\naad = \nct = d33bf6722fc29384fad75f990248b9528e0959aa67ec66869dc3996c67a2d559e7d77ce5955f8cad2a4df5fdc3acccafa7bc0def53d848111256903e5add0420\niv = 5dfc37366f5688275147d3f9\nkey = e12260fcd355a51a0d01bb1f6fa538c2\nmsg = d902deeab175c008329a33bfaccd5c0eb3a6a152a1510e7db04fa0aff7ce4288530db6a80fa7fea582aa7d46d7d56e708d2bb0c5edd3d26648d336c3620ea55e\nresult = valid\ntag = 8bc833de510863b4b432c3cbf45aa7cc\n\n# tcId = 16\naad = \nct = 17d72d90bd23e076d8364a87ecb9ac58acc5de4629bfd590409b8bf1fcd3a2f602731b4614cec15e773ea65a65e7210994256bf5450a25acb527269c065f2e2f2279d1fe8b3eda98dcf87b348f1528377bbdd258355d46e035330483d8097e80c7de9bbb606ddf723f2909217ffdd18e8bdbd7b08062f1dcba960e5c0d290f5f\niv = d767c48d2037b4bd2c231bbd\nkey = 3c55f88e9faa0d68ab50d02b47161276\nmsg = 5d6add48e7a5704e54f9c2829a9b4283dce0d3a65b133eba3793c4fbfa1d8e3a2539d0d4f3de381598ce5b2360173fbd149476c31692c5d6e872fce40219378949c2e70b5f1b9f0a1d5f38352ad814b2a035bb3f3f26425d831a2f7a5e65c5dfcd91a315c2b24f53a662605ea40857dd980e9be5cdad000c569f2d204d4bd3b0\nresult = valid\ntag = 090b8c2ec98e4116186d0e5fbefeb9c2\n\n# tcId = 17\naad = \nct = 5bc6dbafc401101c7a08c81d6c2791aa147ce093aad172be18379c747384a54a41a747ba955cade8fdfb8967aa808b43fee3d757cc80f11163b800e5e59df932757f76c40b3d9cba449aaf11e4f80e003b1f384eafa4f76e81b13c09ec1ad88e7650c750d442fe46d225a373e8a1b564b4915a5c6c513cfdfa22d929d5741ca5ebefaedcba636c7c3bbef18863fdc126b4b451611049c35d814fc2eb7e4b8f1a8995ecb4a3c86652a068c0b2a3e1c5941d59c210b458d5d5d3b06420ec2053465ccceca7c20f67404985460379e2ee806a46e8409dfab2e0dd67ea3cf46d5ad4eb78756827358c3ef1fdbd07c33834f3d9eca3ff13b744a01059a6c17a315a8fd4\niv = dfe20d1c4350e6235d987af1\nkey = a294e70fa2ac10a1fb00c588b888b673\nmsg = 6ed1d7d618d158741f52078006f28494ba72a2454f27160ae8722793fcebc538ebc2f67c3ace3e0fe7c47b9e74e081182b47c930144e3fc80d0ad50611c3afcfe2dbc5279edbbba087c0e390355f3daffcd25ad4dea007c284ad92e7fcbecb438fb60623ff89a599dca2aac141b26651386ca55b739b94901ef6db609c344d8acf4544568e31bb09361112754b1c0c6a3c875bd9453b0ee0081412151398a294ecad75add521611db5288b60ac3c0128f6e94366b69e659e6aa66f058a3a3571064edbb0f05c11e5dde938fb46c3935dd5193a4e5664688f0ae67c29b7cc49a7963140f82e311a20c98cd34fbcab7b4b515ae86557e62099e3fc37b9595c85a75c\nresult = valid\ntag = c7587e7da41bed682c37377ea4324029\n\n# tcId = 18\naad = 75fc9078b488e9503dcb568c882c9eec24d80b04f0958c82aac8484f025c90434148db8e9bfe29c7e071b797457cb1695a5e5a6317b83690ba0538fb11e325ca\nct = b6786812574a254eb43b1cb1d1753564c6b520e9\niv = 5046e7e08f0747e1efccb09e\nkey = c4b03435b91fc52e09eff27e4dc3fb42\nmsg = 8e887b224e8b89c82e9a641cf579e6879e1111c7\nresult = valid\ntag = ad8c09610d508f3d0f03cc523c0d5fcc\n\n# tcId = 19\naad = 8ed8a9be4c3d32a5098434ee5c0c4fc20f78ef5e25ed8b72a840a463e36b67b881e048b5e49f515b2541ad5ce4ebb3a917c16bcdc0dc3cb52bb4ed5a1dffcf1e1866544e8db103b2ad99c6fa6e7de1d8b45bff57ec872f1cfc78b0e4870f6f200ff1291cae033defc3327ba82792ba438e35c4bfbb684fec5ce5e3ae167d01d7\nct = cfb631790767d0645d8ec6f23bf7fa8b19ce79ee\niv = 517c55c2ec9bfea90addc2bd\nkey = 7e37d56e6b1d0172d40d64d6111dd424\nmsg = 6a7dea03c1bba70be8c73da47d5ee06d72a27430\nresult = valid\ntag = c5767ddaa747158446231766bd20490c\n\n# tcId = 20\naad = 18526e4efd995a0bf6405d9f906725c290278958d49554974d8fe025e7860daa225c1285b0573916a4b6741f7cc2e29ce4e525e12f436cb7ce0ad47df3d0f5bd80fb27e47635a4985fdaedf0e821f1c8959985cac49c97a4a02438d92b4afd4c855dcc7ef41ecfc36866334fcc05b2bb93ef13f00c5ea9b921e8a519d77f648e0efe9b5a62305a2ecf7d4999663a6ddfca517f1f36f0899b0bdef9f433c4bb2663c0cc1bb616e7d1949e522bec85485d371d1134c90eede75e865dc7be405b54c33f0acbace6cf780c78035b8035b6ea3f562a8d30a156c199fdafd25be06ee895581195ef125cb4e629e4f18e0bee979d31513896db8466e448e6b4600a316757\nct = e4d3f4898cb3d9732641d1f8d9d889b2c98af930\niv = a2712eac5e06d3cc2864aa8b\nkey = 3076741408f734ce25d48f982e8b844b\nmsg = 414ec6b149e54735302dada888b98b7fdb4c127c\nresult = valid\ntag = 76d4fbb69d529b64175b328be00b1068\n\n# tcId = 21\n# special case\naad = \nct = f62d84d649e56bc8cfedc5d74a51e2f7\niv = 000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = ebd4a3e10cf6d41c50aeae007563b072\nresult = valid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 22\n# special case\naad = \nct = 431f31e6840931fd95f94bf88296ff69\niv = ffffffffffffffffffffffff\nkey = 00112233445566778899aabbccddeeff\nmsg = d593c4d8224f1b100c35e4f6c4006543\nresult = valid\ntag = 00000000000000000000000000000000\n\n# tcId = 23\n# Flipped bit 0 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d9847dbc326a06e988c77ad3863e6083\n\n# tcId = 24\n# Flipped bit 1 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = da847dbc326a06e988c7", "7ad3863e6083\n\n# tcId = 25\n# Flipped bit 7 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = 58847dbc326a06e988c77ad3863e6083\n\n# tcId = 26\n# Flipped bit 8 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8857dbc326a06e988c77ad3863e6083\n\n# tcId = 27\n# Flipped bit 31 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847d3c326a06e988c77ad3863e6083\n\n# tcId = 28\n# Flipped bit 32 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc336a06e988c77ad3863e6083\n\n# tcId = 29\n# Flipped bit 33 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc306a06e988c77ad3863e6083\n\n# tcId = 30\n# Flipped bit 63 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a066988c77ad3863e6083\n\n# tcId = 31\n# Flipped bit 64 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e989c77ad3863e6083\n\n# tcId = 32\n# Flipped bit 71 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e908c77ad3863e6083\n\n# tcId = 33\n# Flipped bit 77 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988e77ad3863e6083\n\n# tcId = 34\n# Flipped bit 80 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77bd3863e6083\n\n# tcId = 35\n# Flipped bit 96 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3873e6083\n\n# tcId = 36\n# Flipped bit 97 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3843e6083\n\n# tcId = 37\n# Flipped bit 103 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3063e6083\n\n# tcId = 38\n# Flipped bit 120 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3863e6082\n\n# tcId = 39\n# Flipped bit 121 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3863e6081\n\n# tcId = 40\n# Flipped bit 126 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3863e60c3\n\n# tcId = 41\n# Flipped bit 127 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a06e988c77ad3863e6003\n\n# tcId = 42\n# Flipped bits 0 and 64 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d9847dbc326a06e989c77ad3863e6083\n\n# tcId = 43\n# Flipped bits 31 and 63 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847d3c326a066988c77ad3863e6083\n\n# tcId = 44\n# Flipped bits 63 and 127 in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d8847dbc326a066988c77ad3863e6003\n\n# tcId = 45\n# all bits of tag flipped\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = 277b8243cd95f9167738852c79c19f7c\n\n# tcId = 46\n# Tag changed to all zero\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 47\n# tag changed to all 1\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 48\n# msbs changed in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = 5804fd3cb2ea86690847fa5306bee003\n\n# tcId = 49\n# lsbs changed in tag\naad = \nct = eb156d081ed6b6b55f4612f021d87b39\niv = 505152535455565758595a5b\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 202122232425262728292a2b2c2d2e2f\nresult = invalid\ntag = d9857cbd336b07e889c67bd2873f6182\n\n[ivSize = 64]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 50\naad = aac39231129872a2\nct = 64c36bb3b732034e3a7d04efc5197785\niv = 0432bc49ac344120\nkey = aa023d0478dcb2b2312498293d9a9129\nmsg = 2035af313d1346ab00154fea78322105\nresult = valid\ntag = b7d0dd70b00d65b97cfd080ff4b819d1\n\n# tcId = 51\n# small IV sizes\naad = \nct = \niv = 28e9b7851724bae3\nkey = f3434725c82a7f8bb07df1f8122fb6c9\nmsg = \nresult = acceptable\ntag = 44aca00f42e4199b829a55e69b073d9e\nflags = SmallIv\n\n# tcId = 52\n# small IV sizes\naad = \nct = 03e1a168a7e377a913879b296a1b5f9c\niv = d084547de55bbc15\nkey = deb62233559b57476602b5adac57c77f\nmsg = d8986df0241ed3297582c0c239c724cb\nresult = acceptable\ntag = 3290aa95af505a742f517fabcc9b2094\nflags = SmallIv\n\n[ivSize = 128]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 53\naad = 1a0293d8f90219058902139013908190bc490890d3ff12a3\nct = 64069c2d58690561f27ee199e6b479b6369eec688672bde9\niv = 3254202d854734812398127a3d134421\nkey = 2034a82547276c83dd3212a813572bce\nmsg = 02efd2e5782312827ed5d230189a2a342b277ce048462193\nresult = valid\ntag = 9b7abadd6e69c1d9ec925786534f5075\n\n# tcId = 54\naad = \nct = \niv = fa294b129972f7fc5bbd5b96bba837c9\nkey = b67b1a6efdd40d37080fbe8f8047aeb9\nmsg = \nresult = valid\ntag = a2cf26481517ec25085c5b17d0786183\n\n# tcId = 55\naad = \nct = fd\niv = 9477849d6ccdfca112d92e53fae4a7ca\nkey = 209e6dbf2ad26a105445fc0207cd9e9a\nmsg = 01\nresult = valid\ntag = 032df7bba5d8ea1a14f16f70bd0e14ec\n\n# tcId = 56\naad = \nct = 2f333087bdca58219f9bfc273e45cc\niv = 5171524568e81d97e8c4de4ba56c10a0\nkey = a549442e35154032d07c8666006aa6a2\nmsg = 1182e93596cac5608946400bc73f3a\nresult = valid\ntag = e06d1ef473132957ad37eaef29733ca0\n\n# tcId = 57\naad = \nct = a780bd01c80885156c88a973264c8ee5\niv = 1275115499ae722268515bf0c164b49c\nkey = cfb4c26f126f6a0acb8e4e220f6c56cd\nmsg = 09dfd7f080275257cf97e76f966b1ad9\nresult = valid\ntag = 2adeffa682c8d8a81fada7d9fcdd2ee2\n\n# tcId = 58\naad = \nct = 7e47e10fe3c6fbfa381770eaf5d48d1482e71e0c44dff1e30ca6f95d92052084\niv = 95c1dd8c0f1705ece68937901f7add7b\nkey = 0b11ef3a08c02970f7", "4281c860691c75\nmsg = f693d4edd825dbb0618d91113128880dbebb23e25d00ed1f077d870be9cc7536\nresult = valid\ntag = d01444fa5d9c499629d174ff3927a1ac\n\n# tcId = 59\n# J0:000102030405060708090a0b0c0d0e0f\naad = \nct = 00078d109d92143fcd5df56721b884fac64ac7762cc09eea2a3c68e92a17bdb575f87bda18be564e\niv = f95fde4a751913202aeeee32a0b55753\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 152a65045fe674f97627427af5be22da\nflags = ConstructedIv\n\n# tcId = 60\n# J0:00000000000000000000000000000000\naad = \nct = 84d4c9c08b4f482861e3a9c6c35bc4d91df927374513bfd49f436bd73f325285daef4ff7e13d46a6\niv = 7b95b8c356810a84711d68150a1b7750\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 213a3cb93855d18e69337eee66aeec07\nflags = ConstructedIv\n\n# tcId = 61\n# J0:ffffffffffffffffffffffffffffffff\naad = \nct = 948ca37a8e6649e88aeffb1c598f3607007702417ea0e0bc3c60ad5a949886de968cf53ea6462aed\niv = 1a552e67cdc4dc1a33b824874ebf0bed\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 99b381bfa2af9751c39d1b6e86d1be6a\nflags = ConstructedIv\n\n# tcId = 62\n# J0:fffffffffffffffffffffffffffffffe\naad = \nct = 64b19314c31af45accdf7e3c4db79f0d948ca37a8e6649e88aeffb1c598f3607007702417ea0e0bc\niv = dd9d0b4a0c3d681524bffca31d907661\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 5281efc7f13ac8e14ccf5dca7bfbfdd1\nflags = ConstructedIv\n\n# tcId = 63\n# J0:fffffffffffffffffffffffffffffffd\naad = \nct = 2bb69c3e5d1f91815c6b87a0d5bbea7164b19314c31af45accdf7e3c4db79f0d948ca37a8e6649e8\niv = 57c5643c4e37b4041db794cfe8e1f0f4\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = a3ea2c09ee4f8c8a12f45cddf9aeff81\nflags = ConstructedIv\n\n# tcId = 64\n# J0:000102030405060708090a0bffffffff\naad = \nct = 127af9b39ecdfc57bb11a2847c7c2d3d8f938f40f877e0c4af37d0fe9af033052bd537c4ae978f60\niv = 99821c2dd5daecded07300f577f7aff1\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 07eb2fe4a958f8434d40684899507c7c\nflags = ConstructedIv\n\n# tcId = 65\n# J0:000102030405060708090a0bfffffffe\naad = \nct = 0cf6ae47156b14dce03c8a07a2e172b1127af9b39ecdfc57bb11a2847c7c2d3d8f938f40f877e0c4\niv = 5e4a3900142358d1c774d8d124d8d27d\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = f145c2dcaf339eede427be934357eac0\nflags = ConstructedIv\n\n# tcId = 66\n# J0:000102030405060708090a0bfffffffd\naad = \nct = f0c6ffc18bd46df5569185a9afd169eb0cf6ae47156b14dce03c8a07a2e172b1127af9b39ecdfc57\niv = d4125676562984c0fe7cb0bdd1a954e8\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = facd0bfe8701b7b4a2ba96d98af52bd9\nflags = ConstructedIv\n\n# tcId = 67\n# J0:000102030405060708090a0b7fffffff\naad = \nct = d6928e094c06e0a7c4db42184cf7529e95de88b767edebe9b343000be3dab47ea08b744293eed698\niv = b97ec62a5e5900ccf9e4be332e336091\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = a03e729dcfd7a03155655fece8affd7e\nflags = ConstructedIv\n\n# tcId = 68\n# J0:000102030405060708090a0b7ffffffe\naad = \nct = d82ce58771bf6487116bf8e96421877ed6928e094c06e0a7c4db42184cf7529e95de88b767edebe9\niv = 7eb6e3079fa0b4c3eee366177d1c1d1d\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 1e43926828bc9a1614c7b1639096c195\nflags = ConstructedIv\n\n# tcId = 69\n# J0:000102030405060708090a0bffff7fff\naad = \nct = a197a37a5d79697078536bc27fe46cd8d475526d9044aa94f088a054f8e380c64f79414795c61480\niv = 0314fcd10fdd675d3c612962c931f635\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = f08baddf0b5285c91fc06a67fe4708ca\nflags = ConstructedIv\n\n# tcId = 70\n# J0:000102030405060708090a0bffff7ffe\naad = \nct = 149fde9abbd3a43c2548575e0db9fb84a197a37a5d79697078536bc27fe46cd8d475526d9044aa94\niv = c4dcd9fcce24d3522b66f1469a1e8bb9\nkey = 00112233445566778899aabbccddeeff\nmsg = 00000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\ntag = 62a4b6875c288345d6a454399eac1afa\nflags = ConstructedIv\n\n# tcId = 71\n# special case\naad = \nct = 45a3f89d02918bfd0c8161658ccc9795\niv = 00000000000000000000000000000000\nkey = 00112233445566778899aabbccddeeff\nmsg = bec6fa05c1718b9b84c47345bbed7dcb\nresult = valid\ntag = 00000000000000000000000000000000\n\n# tcId = 72\n# special case\naad = \nct = 1cd5a06214235ceb044d4bad7b047312\niv = ffffffffffffffffffffffffffffffff\nkey = 00112233445566778899aabbccddeeff\nmsg = 4d82639c39d3f3490ee903dd0be7afcf\nresult = valid\ntag = ffffffffffffffffffffffffffffffff\n\n[ivSize = 96]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 73\naad = 00000000ffffffff\nct = e27abdd2d2a53d2f136b\niv = 00112233445566778899aabb\nkey = 92ace3e348cd821092cd921aa3546374299ab46209691bc28b8752d17f123c20\nmsg = 00010203040506070809\nresult = valid\ntag = 9a4a2579529301bcfb71c78d4060f52c\n\n# tcId = 74\naad = aabbccddeeff\nct = \niv = 00112233445566778899aabb\nkey = 29d3a44f8723dc640239100c365423a312934ac80239212ac3df3421a2098123\nmsg = \nresult = valid\ntag = 2a7d77fa526b8250cb296078926b5020\n\n# tcId = 75\naad = \nct = \niv = 4da5bf8dfd5852c1ea12379d\nkey = 80ba3192c803ce965ea371d5ff073cf0f43b6a2ab576b208426e11409c09b9b0\nmsg = \nresult = valid\ntag = 4771a7c404a472966cea8f73c8bfe17a\n\n# tcId = 76\naad = \nct = 06\niv = 99e23ec48985bccdeeab60f1\nkey = cc56b680552eb75008f5484b4cb803fa5063ebd6eab91f6ab6aef4916a766273\nmsg = 2a\nresult = valid\ntag = 633c1e9703ef744ffffb40edf9d14355\n\n# tcId = 77\naad = \nct = cf332a12fdee800b\niv = 4f07afedfdc3b6c2361823d3\nkey = 51e4bf2bad92b7aff1a4bc05550ba81df4b96fabf41c12c7b00e60e48db7e152\nmsg = be3308f72a2c6aed\nresult = valid\ntag = 602e8d7c4799d62c140c9bb834876b09\n\n# tcId = 78\naad = \nct = 43fc101bff4b32bfadd3daf57a590e\niv = 68ab7fdbf61901dad461d23c\nkey = 67119627bd988eda906219e08c0d0d779a07d208ce8a4fe0709af755eeec6dcb\nmsg = 51f8c1f731ea14acdb210a6d973e07\nresult = valid\ntag = ec04aacb7148a8b8be44cb7eaf4efa69\n\n# tcId = 79\naad = \nct = f58c16690122d75356907fd96b570fca\niv = 2fcb1b38a99e71b84740ad9b\nkey = 59d4eafb4de0cfc7d3db99a8f54b15d7b39f0acc8da69763b019c1699f87674a\nmsg = 549b365af913f3b081131ccb6b825588\nresult = valid\ntag = 28752c20153092818faba2a334640d6e\n\n# tcId = 80\naad = \nct = 73a6b6f45f6ccc5131e07f2caa1f2e2f56\niv = 45aaa3e5d16d2d42dc03445d\nkey = 3b2458d8176e1621c0cc24c0c0e24c1e80d72f7ee9149a4b166176629616d011\nmsg = 3ff1514b1c503915918f0c0c31094a6e1f\nresult = valid\ntag = 2d7379ec1db5952d4e95d30c340b1b1d\n\n# tcId = 81\naad = \nct = 0843fff52d934fc7a071ea62c0bd351ce85678cde3ea2c9e\niv = e6b1adf2fd58a8762c65f31b\nkey = 0212a8de5007ed87b33f1a7090b6114f9e08cefd9607f2c276bdcfdbc5ce9cd7\nmsg = 10f1ecf9c60584665d9ae5efe279e7f7377eea6916d2b111\nresult = valid\ntag = 7355fde599006715053813ce696237a8\n\n# tcId = 82\naad = c0\nct = eb5500e3825952866d911253f8de860c00831c81\niv = 98bc2c7438d5cd7665d76f6e\nkey = b279f57e19c8f53f2f963f5f2519fdb7c1779be2ca2b3ae8e1128b7d6c627fc4\nmsg = fcc515b294408c8645c9183e3f4ecee5127846d1\nresult = valid\ntag = ecb660e1fb0541ec41e8d68a64141b3a\n\n# tcId = 83\naad = 956846a209e087ed\nct = feca44952447015b5df1f456df8ca4bb4eee2ce2\niv = 376187894605a8d45e30de51\nkey = cdccfe3f46d782ef47df4e72f0c02d9c7f774def970d23486f11a57f54247f17\nmsg = e28e0e9f9d22463ac0e42639b530f42102fded75\nresult = valid\ntag = 082e91924deeb77880e1b1c84f9b8d30\n\n# tcId = 84\naad = ab2ac7c44c60bdf8228c7884adb20184\nct = 43dda832e942e286da314daa99bef5071d9d2c78\niv = 5a86a50a0e8a179c734b996d\nkey = f32364b1d339d82e4f132d8f4a0ec1ff7e746517fa07ef1a7f422f4e25a48194\nmsg = 43891bccb522b1e72a6b53cf31c074e9d6c2df8e\nresult = valid\ntag = c39225", @@ -3040,9 +3678,9 @@ static const char *kData108[] = { "e5563f8f826\nresult = valid\ntag = 20529bff3c59222ec33353af337b1d40\n\n[ivSize = 160]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 208\n# unusual IV size\naad = \nct = 073a5291b11df379f31b4f16\niv = 130c14c839e35b7d56b3350b194b0da342e6b65d\nkey = ef2e299dd4ecd7e3b9cc62780922cc2c89f78840564d1276\nmsg = 03f59579b14437199583270e\nresult = valid\ntag = 17205999491bd4c1d6c7ec3e56779c32\n\n[ivSize = 120]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 209\n# unusual IV size\naad = \nct = fc213602aa423b87d7c2a874\niv = 17ca250fb733877556263223eadde1\nkey = e98b0669a645eb14cd06df6968fc5f10edc9f54feed264e3d410cdc61b72ef51\nmsg = f384b3ed7b274641f5db60cf\nresult = valid\ntag = 36b15bab6923b17218fe1c24048e2391\n\n[ivSize = 160]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 210\n# unusual IV size\naad = \nct = c1d76233e8c5042e92bf8d32\niv = 0f9d6ed7eef362dfa4a7dfa5c0f74c5b27bd4ebf\nkey = 849b3e6b8cdd85bdcfb8eb701aa5522ae2340fbe5214e389622cef76979225c4\nmsg = 8c5564e53051c0de273199b4\nresult = valid\ntag = 7cf036d235d3b2dd349a8c804b65144a\n\n[ivSize = 256]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 211\n# long IV size\naad = \nct = 5348af57fafe2485b43f2bc4\niv = 365e0b96932b13306f92e9bb23847165bcbf5d35e45a83d75c86ecca70131f4c\nkey = 5927bae748bb69d81b5a724e0a165652\nmsg = 316bf99bfafc76f1bfc0b03c\nresult = valid\ntag = 019a96c5373c031626b6c0300d4cf78b\n\n[ivSize = 512]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 212\n# long IV size\naad = \nct = f559b70fe1149cb34406a2c7\niv = 967fa7c990eb2becbd450835e28ea3a9000c7216285cfa7696e8c3dac3ce952a1fe638d7c8c73e1d708dce01b5a20fcc9aa011949d2a835f777423c172fa3aa0\nkey = dbd3676f293409273f27b375e03793a3\nmsg = 625efedb8b7f1aa62238a8f2\nresult = valid\ntag = 94180ddb7bb1995abe0219eab5ce232f\n\n[ivSize = 1024]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 213\n# long IV size\naad = \nct = 5291dd4da91ccc2e77306d83\niv = 494356c3459d60e3a83433c9bcf2c0454a763e496e4ec99bfbe4bbb83a4fda76b542213899dcf5521cd9bbbe5d11545bda44a3f4a681ce2843acea730d83d3930ea30991ee1a68ebf6d1a5a40f9b02a1aab091298df8dd689dc7613bcbff94d35f2ca43377d81618562bcf6573411ec9bc97c5a6276b554054c0fa787073d067\nkey = 7e5a39dcda7e066988f19adf4de4d501\nmsg = b04729b4adbaac63c2aaf8d8\nresult = valid\ntag = a7f7b21a3b7ece509e922647fd905f06\n\n[ivSize = 2056]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 214\n# long IV size\naad = \nct = e3be947153a26a3a54e3015c\niv = 6fd260bba87339539c37dc68fdc3656f63c83028cb8adcb531085e98bd570c6b735d0cc4b4b924696000a2d893621ae64dcce992b562b89a5285643a08febccbc52243cbfc8d45212e047b00c87c6b6bf175f8bb678ec55c1091315cbecb8b85700f4a4653623fb78e63cfff7d6235e48e9832c9f0716d10992fc5b0ad4e6972bbeeb1ad670cd7ec8fac82e07ea5a64f9761a39714aaa73affd2cb190a7ac2df5e5dcea6812ae2c872c7ac70453c5e7ec4d0b5b18c6ff3bfb9ae15fea44cf392615b80034edae596b8821f97fca58d167fb44a093b0c009a0bd5631355b0cb25d93ba9b79b006301d99db657e801933fc2764a0ce650eaf5a1299efe60cb53b634\nkey = eac3f28cd937ff29eb6158a3721b5145\nmsg = 098912a302773377b9c26ac3\nresult = valid\ntag = fd042bdde22f67c4fd298d5dc0867606\n\n[ivSize = 256]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 215\n# long IV size\naad = \nct = 8c2a9823a3b3d413be696387\niv = 36e4b381574d171c7769a788cbc147224fabd8b773f16b8ae84d8f2603aaa440\nkey = 8f9ebc67a9a6430c2b0ceeaf983e1356964bb928635b9ca4\nmsg = a3a96ee94f94caa81ebcd66d\nresult = valid\ntag = faaf01ceb40a7e145e8fe65aa9af58c0\n\n[ivSize = 512]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 216\n# long IV size\naad = \nct = a660ea5bf07a78fea0120173\niv = 90743bd5d794d52ac848b7e2384545a25846acf143be84c0ead0432fcf3172631cf58d0ca78571c03053c1e1b85ed79cb5303d0e3a98ff4f56c4f0a5eb4f0eac\nkey = f4bbdfd06f7fb1434880e4166d38d56e02a3f0df0d5301ce\nmsg = 39d2abe6697f17ec27f2a39c\nresult = valid\ntag = 7404fc7b7354694428236f203c130244\n\n[ivSize = 1024]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 217\n# long IV size\naad = \nct = f400132ff38c04ed747dde34\niv = fbb3eab379c9b8689dc30b0713690e55d51c956ca36fbcc73eeeee16a46d7c41a7a9626e68e25d685c008c19d3b2b1792bdc99c35441a6fcac35e0d6446dd914f543abd9ecd6b0cb5201c243026c4f13641d67c8d8cd5114b6e11ebbc6b1dee2a18db2150a5a575dcd21648e0337dadbccd3deffd6d979e03e6b9ddfee0abdc2\nkey = 1761c77798ef9cdfa40553f34614fe7402212087f0509411\nmsg = 35ca4eb463a2000138210b4d\nresult = valid\ntag = ca1534e7dd0336bbb32a79830c71a447\n\n[ivSize = 2056]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 218\n# long IV size\naad = \nct = 13a95a06c1bed4845af9c701\niv = 3569fca7c9d06e2a03fed1aac2484fd4416ca07d55ecbb333ec674f0ea5c6e75a10dfb9c738b69dab2eda10ada721a61c7f02b7e7f79e8a9e2dc36b3fdf609e436054c82a774ec617dceec84a577037ff1a3f120d9818d042063acb36c9584e81ec94f11f1ee240f2e45e944694a9c8e535acbb01d93958411cff68e3d32f8931746a4a0cece65e93c51c70b3111034b6867b407e0147f97c576d3ed8cec7e8ec26e95643e46e97ea3595c9c3172b4856f2d2b6dc8564666ddac92c794ffb2d4dc7f461761f0e326650f48d327604e095bd8754072116c96360d09f010ac2f39eb96b227f3d738deb756c8699460d88cf716170ae15267b14f4a89164720f1c602\nkey = f795ece7de1881fbc6843eb740f812e41e3fc49ff6c7b940\nmsg = 22dbd8037aa05b14cf81dd23\nresult = valid\ntag = 03379836b0c82f64a1bccdcd763acbbc\n\n[ivSize = 256]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 219\n# long IV size\naad = \nct = a295c2cb27ce23d26874ade1\niv = e826a79361f9d582b64450e3edc82589487853d5b22feaa0c889875bd0d87cd4\nkey = ee4171917d2337496812a2784d6a71300e6b8c1ac3b1ef58cee77c229aeaf2c5\nmsg = 94d2f8697facaaa191ba617a\nresult = valid\ntag = 04650a78bbb61db337c9c32aa3e7b6fa\n\n[ivSize = 512]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 220\n# long IV size\naad = \nct = 9cdcfc3aaa8d466f25588e4b\niv = ec51ee18cfb46897d3666c7df35c29ca5d898241c4a34f893eb1db5d5c6b76e24617459d1153868154437a0e95aa3c26e956b494a52dd5ac3b9331116c7c775f\nkey = 132c59b4bcb8afb31637734a81105bb2c9878f320ace9076d5fd7c5d216c8d12\nmsg = 12c7be00facda49596e19134\nresult = valid\ntag = 7e80f51e7180f1cd3ba84349888fcd5c\n\n[ivSize = 1024]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 221\n# long IV size\naad = \nct = 3f3c151e984d059462f9e5a0\niv = 7d08b226b4a5d03f6f8cb3a3cb8d1ce31b059dc5112385275e38a15c97e0f24022b249a5f7019ea577198cb26ac64e82b2b04681537c4198775a523b0e6494b84febaef3399b35c27b0969fa43572bf5827a763aac1af69526f37e38acb5d354f2b68487f275f4361ed39073f7dd6653ac17c0794118a0cf143293ac0be66229\nkey = 7b0b12491901d62d097fa26dc71e15cfacafa3226719e47126d99c79d98ec222\nmsg = c80312590700c3bbfacd1a40\nresult = valid\ntag = e559f5f755aa292171cc35fbf911a64f\n\n[ivSize = 2056]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 222\n# long IV size\naad = \nct = 5496ae94c3322ebf959ea9a9\niv = 92c2cee7e9138b186da51f146fb21fd5b491f1a19eef61d4ed14ce6b21b04fdb6ff8ebb60fddc55926e7bda2a8f35c610bb795232412739d6c2d74458ef5a1a1cde9bf17e47e3b00db0b0504d56dc8b8d3de23f7c3a5d52e8d0aab1e64405aaa852ec2dd667ed9c1fd8dc1fdbbc8712c7a38f30faeab594f33897b41b1720f3c2f954ed91ca450d82c3dcd35858c608ad42f36832e56b04821a132f72e0da7b62cbd3925250f64fbb3f5c4783495893097adc09a32d776e04bf72558d37830b372341f6536d8ee9df4a82e4074e7774ab6917a04fa8c499eb4b46a92def365da8b5eb1e0b438779507d1f5272a6e8629a3f9c7bd4862c5691ee8b56bfe292deb4e\nkey = 3bc3bf39d0d5ffd94cca2b45c678a2d049151ed2babc713be53cb66f54a16337\nmsg = 8125ee7637d7d0e03bbacf35\nresult = valid\ntag = 70717cc00fd1ffa59bb04329226a0c0a\n\n[ivSize = 0]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 223\n# 0 size IV is not valid\naad = \nct = \niv = \nkey = 8f3f52e3c75c58f5cb261f518f4ad30a\nmsg = \nresult = invalid\ntag = cf71978ffcc778f3c85ac9c31b6fe191\nflags = ZeroLengthIv\n\n# tcId = 224\n# 0 size IV is not valid\naad = \nct = 00a29f0a5e2e7490279d1faf8b881c7b\niv = \nkey = 2a4bf90e56b70fdd8649d775c089de3b\nmsg = 324ced6cd15ecc5b3741541e22c18ad9\nresult = invalid\ntag = a2c7e8d7a19b884f742dfec3e76c75ee\nflags = ZeroLengthIv\n\n[ivSize = 0]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 225\n# 0 size IV is not valid\naad = \nct = \niv = \nkey = 0b18d21337035c7baa08211b702fa780ac7c09be8f9ed11f\nmsg = \nresult = invalid\ntag = ca69a2eb3a096ea36b1015d5dffff532\nflags = ZeroLengthIv\n\n# tcId = 226\n# 0 size IV is not valid\naad = \nct = 509b0658d09f7a5bb9db43b70c8387f7\niv = \nkey = ba76d594a6df915bb7ab7e6d1a8d024b2796336c1b8328a9\nmsg = d62f302742d61d823ea991b93430d589\nresult = invalid\ntag = 2c9488d53a0b2b5308c2757dfac7219f\nflags = ZeroLengthIv\n\n[ivSize = 0]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 227\n# 0 size IV is not valid\naad = \nct = \niv = \nkey = 3f8ca47b9a940582644e8ecf9c2d44e8138377a8379c5c11aafe7fec19856cf1\nmsg = \nresult = invalid\ntag = 17", "26aa695fbaa21a1db88455c670a4b0\nflags = ZeroLengthIv\n\n# tcId = 228\n# 0 size IV is not valid\naad = \nct = 7772ea358901f571d3d35c19497639d9\niv = \nkey = 7660d10966c6503903a552dde2a809ede9da490e5e5cc3e349da999671809883\nmsg = c314235341debfafa1526bb61044a7f1\nresult = invalid\ntag = 8fe0520ad744a11f0ccfd228454363fa\nflags = ZeroLengthIv\n\n[ivSize = 8]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 229\n# small IV sizes\naad = \nct = \niv = 80\nkey = 59a284f50aedd8d3e2a91637d3815579\nmsg = \nresult = acceptable\ntag = af498f701d2470695f6e7c8327a2398b\nflags = SmallIv\n\n# tcId = 230\n# small IV sizes\naad = \nct = 0a24612a9d1cbe967dbfe804bf8440e5\niv = 9d\nkey = fec58aa8cf06bfe05de829f27ec77693\nmsg = f2d99a9f893378e0757d27c2e3a3101b\nresult = acceptable\ntag = 96e6fd2cdc707e3ee0a1c90d34c9c36c\nflags = SmallIv\n\n[ivSize = 16]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 231\n# small IV sizes\naad = \nct = \niv = 0f2f\nkey = 88a972cce9eaf5a7813ce8149d0c1d0e\nmsg = \nresult = acceptable\ntag = 4ccf1efb4da05b4ae4452aea42f5424b\nflags = SmallIv\n\n# tcId = 232\n# small IV sizes\naad = \nct = ba3e7f8b2999995c7fc4006ca4f475ff\niv = 8760\nkey = b43967ee933e4632bd6562ba1201bf83\nmsg = 5a6ad6db70591d1e520b0122f05021a0\nresult = acceptable\ntag = 98f47a5279cebbcac214515710f6cd8a\nflags = SmallIv\n\n[ivSize = 32]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 233\n# small IV sizes\naad = \nct = \niv = cc851957\nkey = 4e9a97d3ed54c7b54610793ab05052e1\nmsg = \nresult = acceptable\ntag = e574b355bda2980e047e584feb1676ca\nflags = SmallIv\n\n# tcId = 234\n# small IV sizes\naad = \nct = 1b84baea9df1e65bee7b49e4a8cda1ec\niv = 7b5faeb2\nkey = d83c1d7a97c43f182409a4aa5609c1b1\nmsg = c8f07ba1d65554a9bd40390c30c5529c\nresult = acceptable\ntag = 5c0bb79d8240041edce0f94bd4bb384f\nflags = SmallIv\n\n[ivSize = 48]\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 235\n# small IV sizes\naad = \nct = \niv = 4ad80c2854fb\nkey = c6a705677affb49e276d9511caa46145\nmsg = \nresult = acceptable\ntag = 1e2ed72af590cafb8647d185865f5463\nflags = SmallIv\n\n# tcId = 236\n# small IV sizes\naad = \nct = 18291aa8dc7b07448aa8f71bb8e380bf\niv = d1dafc8de3e3\nkey = eba7699b56cc0aa2f66a2a5be9944413\nmsg = d021e53d9098a2df3d6b903cdad0cd9c\nresult = acceptable\ntag = 9c0e22e5c41b1039ff5661ffaefa8e0f\nflags = SmallIv\n\n[ivSize = 8]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 237\n# small IV sizes\naad = \nct = \niv = cb\nkey = c70ce38e84e5f53ed41c3f0d2ca493412ad32cb04c6e2efa\nmsg = \nresult = acceptable\ntag = 08d96edb5e22874cd10cb2256ca04bc6\nflags = SmallIv\n\n# tcId = 238\n# small IV sizes\naad = \nct = 6c5e796ba9a3ddc64f401e68d135101d\niv = 0f\nkey = 74c816b83dfd287210a3e2c6da8d3053bbfbd9b156d3fdd8\nmsg = f2b7b2c9b312cf2af78f003df15c8e19\nresult = acceptable\ntag = 96a132ed43924e98feb888ff682bdaef\nflags = SmallIv\n\n[ivSize = 16]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 239\n# small IV sizes\naad = \nct = \niv = 75e5\nkey = cbf45ba488932aea1a10e5862f92e4a7e277bda9f34af6d0\nmsg = \nresult = acceptable\ntag = 1f0d23070fcd748e25bf6454f5c9136e\nflags = SmallIv\n\n# tcId = 240\n# small IV sizes\naad = \nct = 550b48a43e821fd76f49f0f1a897aead\niv = 8989\nkey = e1c0446f11ae6aa4fa254f9a846fc6e13e45e537e47f2042\nmsg = 3a2f5ad0eb216e546e0bcaa377b6cbc7\nresult = acceptable\ntag = f6e0a979481f9957ddad0f21a777a73a\nflags = SmallIv\n\n[ivSize = 32]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 241\n# small IV sizes\naad = \nct = \niv = 68d7fc38\nkey = 567563bf4cf154902275a53bc57cd6dd7b370d27011bdac8\nmsg = \nresult = acceptable\ntag = 1475563e3212f3b5e40062569afd71e3\nflags = SmallIv\n\n# tcId = 242\n# small IV sizes\naad = \nct = 309133e76159fe8a41b20843486511ab\niv = bb9d2aa3\nkey = 834d0bb601170865a78139428a1503695a6a291ebd747cd1\nmsg = 6f79e18b4acd5a03d3a5f7e1a8d0f183\nresult = acceptable\ntag = 03ab26993b701910a2e8ecccd2ba9e52\nflags = SmallIv\n\n[ivSize = 48]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 243\n# small IV sizes\naad = \nct = \niv = a984bdcdcae2\nkey = 99fb18f5ba430bb9ea942968ecb799b43406e1af4b6425a1\nmsg = \nresult = acceptable\ntag = d7b9a6b58a97982916e83219fbf71b1e\nflags = SmallIv\n\n# tcId = 244\n# small IV sizes\naad = \nct = e08261e46eaf90d978ea8f7889bccd4f\niv = 52aa01e0d0d6\nkey = b77b242aa0d51c92fda013e0cb0ef2437399ace5d3f507e4\nmsg = 4ba541a9914729216153801340ab1779\nresult = acceptable\ntag = c052a55df3926a50990a532efe3d80ec\nflags = SmallIv\n\n[ivSize = 64]\n[keySize = 192]\n[tagSize = 128]\n\n# tcId = 245\n# small IV sizes\naad = \nct = \niv = d1c61cf8532531b5\nkey = d74599b3d2db81653de43b52fc994c50d0be759fab87c33a\nmsg = \nresult = acceptable\ntag = f94f2049a6560c470b3a7ca7bbc31a3d\nflags = SmallIv\n\n# tcId = 246\n# small IV sizes\naad = \nct = 3c6ec0ab1b827bf238a5384fb7e212ce\niv = 8f075cbcda9831c3\nkey = 0b177198c8b419bf74acc3bc65b5fb3d09a915ff71add754\nmsg = c4b1e05ca3d591f9543e64de3fc682ac\nresult = acceptable\ntag = 7db7402224fd583e312bc0e61cf11366\nflags = SmallIv\n\n[ivSize = 8]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 247\n# small IV sizes\naad = \nct = \niv = a9\nkey = 8f9a38c1014966e4d9ae736139c5e79b99345874f42d4c7d2c81aa6797c417c0\nmsg = \nresult = acceptable\ntag = 2a268bf3a75fd7b00ba230b904bbb014\nflags = SmallIv\n\n# tcId = 248\n# small IV sizes\naad = \nct = 7bea30ecc2f73f8e121263b37966954c\niv = b3\nkey = 144cd8279229e8bb2de99d24e615306663913fe9177fcd270fafec493d43bca1\nmsg = 976229f5538f9636476d69f0c328e29d\nresult = acceptable\ntag = 8bbad4adc54b37a2b2f0f6e8617548c9\nflags = SmallIv\n\n[ivSize = 16]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 249\n# small IV sizes\naad = \nct = \niv = c332\nkey = 7d31861f9d3536e14016a3216b1042e0d2f7d4614314268b6f834ec7f38bbb65\nmsg = \nresult = acceptable\ntag = 1d978a693120c11f6d51a3ed88cd4ace\nflags = SmallIv\n\n# tcId = 250\n# small IV sizes\naad = \nct = 9c39f5b110361e9a770cc5e8b0f444bb\niv = da6c\nkey = 22b35fe9623ee11f8b60b6d22db3765b666ed972fa7ccd92b45f22deee02cab1\nmsg = 5341c78e4ce5bf8fbc3e077d1990dd5d\nresult = acceptable\ntag = b63ff43c12073ec5572b1be70f17e231\nflags = SmallIv\n\n[ivSize = 32]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 251\n# small IV sizes\naad = \nct = \niv = 6b30145e\nkey = c224e0bba3d7a99165f7996b67a0fce3e12f2c01179b197b69b7e628bca92096\nmsg = \nresult = acceptable\ntag = ae6f7c9a29f0d8204ca50b14a1e0dcf2\nflags = SmallIv\n\n# tcId = 252\n# small IV sizes\naad = \nct = f73f72f976a296ba3ca94bc6eb08cd46\niv = 5110604c\nkey = 093eb12343537ee8e91c1f715b862603f8daf9d4e1d7d67212a9d68e5aac9358\nmsg = 33efb58c91e8c70271870ec00fe2e202\nresult = acceptable\ntag = b824c33c13f289429659aa017c632f71\nflags = SmallIv\n\n[ivSize = 48]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 253\n# small IV sizes\naad = \nct = \niv = d4d857510888\nkey = 98e6f8ab673e804e865e32403a6551bf807a959343c60d34559360bc295ecb5b\nmsg = \nresult = acceptable\ntag = 3db16725fafc828d414ab61c16a6c38f\nflags = SmallIv\n\n# tcId = 254\n# small IV sizes\naad = \nct = ed463f4f43336af3f4d7e08770201145\niv = 1bdcd44b663e\nkey = 0bd0e8e7781166e1d876dec8fad34ba95b032a27cac0551595116091005947b7\nmsg = 91222263b12cf5616a049cbe29ab9b5b\nresult = acceptable\ntag = c8fc39906aca0c64e14a43ff750abd8a\nflags = SmallIv\n\n[ivSize = 64]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 255\n# small IV sizes\naad = \nct = \niv = 0d10c5c84b88d688\nkey = 61ba694897925d1b4174d40401469c3ef267cdb9f829edb1a10618c16d666059\nmsg = \nresult = acceptable\ntag = 1311f9f830d729c189b74ec4f9080fa1\nflags = SmallIv\n\n# tcId = 256\n# small IV sizes\naad = \nct = 7e0dd6c72aec49f89cc6a80060c0b170\niv = 04102199ef21e1df\nkey = 115884f693b155563e9bfb3b07cacb2f7f7caa9bfe51f89e23feb5a9468bfdd0\nmsg = 82e3e604d2be8fcab74f638d1e70f24c\nresult = acceptable\ntag = af68a37cfefecc4ab99ba50a5353edca\nflags = SmallIv\n\n", }; -static const size_t kLen109 = 140567; +static const size_t kLen163 = 140567; -static const char *kData109[] = { +static const char *kData163[] = { "# Imported from Wycheproof's chacha20_poly1305_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: CHACHA20-POLY1305\n# Generator version: 0.8r12\n\n[ivSize = 96]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 1\n# RFC 7539\naad = 50515253c0c1c2c3c4c5c6c7\nct = d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116\niv = 070000004041424344454647\nkey = 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nmsg = 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e\nresult = valid\ntag = 1ae10b594f09e26a7e902ecbd0600691\n\n# tcId = 2\naad = \nct = \niv = 4da5bf8dfd5852c1ea12379d\nkey = 80ba3192c803ce965ea371d5ff073cf0f43b6a2ab576b208426e11409c09b9b0\nmsg = \nresult = valid\ntag = 76acb342cf3166a5b63c0c0ea1383c8d\n\n# tcId = 3\naad = bd506764f2d2c410\nct = \niv = a92ef0ac991dd516a3c6f689\nkey = 7a4cd759172e02eb204db2c3f5c746227df584fc1345196391dbb9577a250742\nmsg = \nresult = valid\ntag = 906fa6284b52f87b7359cbaa7563c709\n\n# tcId = 4\naad = \nct = 3a\niv = 99e23ec48985bccdeeab60f1\nkey = cc56b680552eb75008f5484b4cb803fa5063ebd6eab91f6ab6aef4916a766273\nmsg = 2a\nresult = valid\ntag = cac27dec0968801e9f6eded69d807522\n\n# tcId = 5\naad = 91ca6c592cbcca53\nct = c4\niv = ab0dca716ee051d2782f4403\nkey = 46f0254965f769d52bdb4a70b443199f8ef207520d1220c55e4b70f0fda620ee\nmsg = 51\nresult = valid\ntag = 168310ca45b1f7c66cad4e99e43f72b9\n\n# tcId = 6\naad = \nct = 4d13\niv = 461af122e9f2e0347e03f2db\nkey = 2f7f7e4f592bb389194989743507bf3ee9cbde1786b6695fe6c025fd9ba4c100\nmsg = 5c60\nresult = valid\ntag = 91e8b61efb39c122195453077b22e5e2\n\n# tcId = 7\naad = 88364fc8060518bf\nct = b60d\niv = 61546ba5f1720590b6040ac6\nkey = c8833dce5ea9f248aa2030eacfe72bffe69a620caf793344e5718fe0d7ab1a58\nmsg = ddf2\nresult = valid\ntag = ead0fd4697ec2e5558237719d02437a2\n\n# tcId = 8\naad = \nct = 3cf470\niv = d2ab0abb50a8e9fba25429e1\nkey = bd8ed7fb0d607522f04d0b12d42c92570bccc5ba2486953d70ba2e8193f6225a\nmsg = 201221\nresult = valid\ntag = a27a69c9d7ee84586f11388c6884e63a\n\n# tcId = 9\naad = 6c8cf2ab3820b695\nct = 610925\niv = 94f32a6dff588f2b5a2ead45\nkey = 1c8b59b17a5ceced31bde97d4cefd9aaaa63362e096e863ec1c89580bca79b7a\nmsg = 453f95\nresult = valid\ntag = a8a7883eb7e40bc40e2e5922ae95ddc3\n\n# tcId = 10\naad = \nct = fe6849aa\niv = 7aa5ad8bf5254762171ec869\nkey = e4912cb75a1174345f1a457366f18885fe8460b06478e04be2f7fb4ec9c113e5\nmsg = 9e4c1d03\nresult = valid\ntag = 99ad07871b25c27defc31a541bd5c418\n\n# tcId = 11\naad = 15d93a96d0e6c5a9\nct = f4710e51\niv = b7f526e3fd71cf5720961aec\nkey = e05777ef3d989ace7d2abfba452bfded54801dbd5c66e91c0c2ef00479d85572\nmsg = 17bfda03\nresult = valid\ntag = b957c6a37b6a4c94996c002186d63b2b\n\n# tcId = 12\naad = \nct = f711647ff1\niv = 9447bf85d5b97d8aee0f8e51\nkey = 1a4c4f39abe890e62345c947bcf7de7c2e33bd5ceeda0a0abf0e7ef935ddf3ee\nmsg = c15a593bd0\nresult = valid\ntag = 22b12dc38cb79629f84cdbdc2425c09d\n\n# tcId = 13\naad = 96224835610b782b\nct = d171f046ea\niv = 3dbe876bd880ec8ea2017043\nkey = 800e9a24791700c9609736695ba2a8b99b2d57f1c3bfb61ed49db1c6c5219583\nmsg = a7bfd041e3\nresult = valid\ntag = d179b1b9c4184378df009019dbb8c249\n\n# tcId = 14\naad = \nct = 9351b1b1b082\niv = 27fb58ec6a21e84696cb8830\nkey = 208c2c376c9430433db20e1a6b7ba817f8ffbfa6827f26759ccede42e591d3ec\nmsg = af104b5ccd0e\nresult = valid\ntag = 560785509f60f26b681933d9cdbfd29f\n\n# tcId = 15\naad = 6d52feb2509f7fbf\nct = 41abff7b71cc\niv = b5965470c383fd29fe7eaee7\nkey = 2eb168e53b07ab04355ea792fe11a6be2ce9c39cfe15a997076b1e38c17ad620\nmsg = 6fdf2927e169\nresult = valid\ntag = 9b5174297c03cf8902d1f706fd008902\n\n# tcId = 16\naad = \nct = 5dfe3440dbb3c3\niv = 3c4e654d663fa4596dc55bb7\nkey = 55568158d3a6483f1f7021eab69b703f614251cadc1af5d34a374fdbfc5adac7\nmsg = ab85e9c1571731\nresult = valid\ntag = ed7a434e2602d394281e0afa9fb7aa42\n\n# tcId = 17\naad = 84e46be8c0919053\nct = 4bd47212941ce3\niv = 58389375c69ee398de948396\nkey = e3c09e7fab1aefb516da6a33022a1dd4eb272c80d540c5da52a730f34d840d7f\nmsg = 4ee5cda20d4290\nresult = valid\ntag = 185f1408ee7fbf18f5abad6e2253a1ba\n\n# tcId = 18\naad = \nct = 8e9439a56eeec817\niv = 4f07afedfdc3b6c2361823d3\nkey = 51e4bf2bad92b7aff1a4bc05550ba81df4b96fabf41c12c7b00e60e48db7e152\nmsg = be3308f72a2c6aed\nresult = valid\ntag = fbe8a6ed8fabb1937539dd6c00e90021\n\n# tcId = 19\naad = 66c0ae70076cb14d\nct = b9b910433af052b0\niv = b4ea666ee119563366484a78\nkey = 1131c1418577a054de7a4ac551950f1a053f9ae46e5b75fe4abd5608d7cddadd\nmsg = a4c9c2801b71f7df\nresult = valid\ntag = 4530f51aeee024e0a445a6328fa67a18\n\n# tcId = 20\naad = \nct = d9d897a9c1c5bb9f01\niv = 8092fc245b3326cddbd1424c\nkey = e1094967f86d893cdfe2e2e6d5c7ee4dfef67da3c9c5d64e6ad7c1577dcb38c5\nmsg = c37aa791ddd6accf91\nresult = valid\ntag = 085a430373058f1a12a0d589fd5be68b\n\n# tcId = 21\naad = 8c32f47a386152ec\nct = 8fdb429d47761cbf8e\niv = f1ca81338629587acf9372bf\nkey = 236f9baee4f9da15beeca40ff4af7c760f254a64bc3a3d7f4fad557e61b68586\nmsg = d7f26d5252e1765f5b\nresult = valid\ntag = 8ef647ed334fdebbc2bef80be02884e0\n\n# tcId = 22\naad = \nct = 700d35adf5100a22a1de\niv = 4c15a71dc6791a8c005ad502\nkey = 4de207a3b70c51e5f23048eed5a5da9bb65e917a69aa93e7c8b4a815cd9724de\nmsg = f2c54b6b5e490da18659\nresult = valid\ntag = 102d992ffaff599b5bddddeb2dfb399b\n\n# tcId = 23\naad = e1e27ccddb3cb407\nct = 04aad66c60e0bf8ebba9\niv = 6220527aba88e27f766658b2\nkey = 6d667fd79e5fb725f50343dccc4863227c75ee3f7a578476e3e9f32598d81559\nmsg = 0c8c5a252681f2b5b4c0\nresult = valid\ntag = c15f69a4d2aef97d7748756ff49d894b\n\n# tcId = 24\naad = \nct = 1c3d53baaa36eaa1d8ec4d\niv = ec1e2967f0f6979e5f5b07fb\nkey = 8f4bd94ef73e75d1e068c30b37ead576c5344e093ece1330e9101c82f793cf05\nmsg = b89812b34d9bced4a0ba07\nresult = valid\ntag = 4d94ebf960f12433bec43aa86d7e6e6d\n\n# tcId = 25\naad = a9bc350eaf2e6e3d\nct = 1c8578f8e75203d0336a52\niv = 28cce57a5db2cd206321e340\nkey = 2aa3bc7033351cac51364cdaf6ffac2c20f64046e1550a7b1c65f41800599019\nmsg = 83016823123484b56095b0\nresult = valid\ntag = 5910f7a9d5e4df05d7248bd7a8d65e63\n\n# tcId = 26\naad = \nct = ff7dc203b26c467a6b50db33\niv = 9a59fce26df0005e07538656\nkey = 99b62bd5afbe3fb015bde93f0abf483957a1c3eb3ca59cb50b39f7f8a9cc51be\nmsg = 42baae5978feaf5c368d14e0\nresult = valid\ntag = 578c0f2758c2e14e36d4fc106dcb29b4\n\n# tcId = 27\naad = a506e1a5c69093f9\nct = 9f8816de0994e938d9e53f95\niv = 58dbd4ad2c4ad35dd906e9ce\nkey = 85f35b6282cff440bc1020c8136ff27031110fa63ec16f1e825118b006b91257\nmsg = fdc85b94a4b2a6b759b1a0da\nresult = valid\ntag = d086fc6c9d8fa915fd8423a7cf05072f\n\n# tcId = 28\naad = \nct = e6b33a74a4ac443bd93f9c1b94\niv = b776c3fddba7c81362ce6e1b\nkey = faf4bfe8019a891c74901b17f4f48cee5cd065d55fdea60118aaf6c4319a0ea5\nmsg = 8dadff8d60c8e88f604f274833\nresult = valid\ntag = 0c115172bdb02bbad3130fff22790d60\n\n# tcId = 29\naad = 5a8e1c7aa39810d5\nct = b0a7500aca45bb15f01ece4389\niv = 6d62f159731b140eb18ce074\nkey = 841020d1606edcfc536abfb1a638a7b958e21efc10c386ac45a18493450afd5f\nmsg = d6af138f701b801e60c85ffd5c\nresult = valid\ntag = 0160e83adbec7f6a2ee2ff0215f9ef00\n\n# tcId = 30\naad = \nct = d3017e0bb1705b380b34cc333450\niv = a9ea4d619fe405d04cba7d7a\nkey = 470f9ce3d2250bd60cbbefdb2e6a1178c012299b5590639c7797b6024fa703d8\nmsg = 6ca67dd023fba6507b9f9a1f667e\nresult = valid\ntag = 5708e72ca2bd354f487f82f67fbc3acb\n\n# tcId = 31\naad = eaaaeab26957f9a1\nct = 52e9672b416d84d97033796072d0\niv = 0e23c942a0c9fb526586eead\nkey = e4b97e91e4c8e85eb7ce0a7f30bf8a0abf4468251e4c6386c0e7aacb8e879aa8\nmsg = b84b3f74cd23064bb426fe2ced2b\nresult = valid\ntag = e83839dc1fd9b8b9d1444c40e488d493\n\n# tcId = 32\naad = \nct = 0b29638e1fbdd6df53970be2210042\niv = 68ab7fdbf61901dad461d23c\nkey = 67119627bd988eda906219e08c0d0d779a07d208ce8a4fe0709af755eeec6dcb\nmsg = 51f8c1f731ea14acdb210a6d973e07\nresult = valid\ntag = 2a9134087d67a46e79178d0a93f5e1d2\n\n# tcId = 33\naad = 6453a53384632212\nct = 32db66c4a3819d81557455e5980fed\niv = d95b3243afaef714c5035b6a\nkey = e6f1118d41e4b43fb58221b7ed79673834e0d8ac5c4fa60bbc8bc4893a58894d\nmsg = 97469da667d6110f9cbda1d1a20673\nresult = valid\ntag = feae30dec94e6ad3a9eea06a0d703917\n\n# tcId = 34\naad = \nct = e9110e9f56ab3ca483500ceabab", "67a13\niv = 2fcb1b38a99e71b84740ad9b\nkey = 59d4eafb4de0cfc7d3db99a8f54b15d7b39f0acc8da69763b019c1699f87674a\nmsg = 549b365af913f3b081131ccb6b825588\nresult = valid\ntag = 836ccabf15a6a22a51c1071cfa68fa0c\n\n# tcId = 35\naad = 034585621af8d7ff\nct = e4b113cb775945f3d3a8ae9ec141c00c\niv = 118a6964c2d3e380071f5266\nkey = b907a45075513fe8a8019edee3f2591487b2a030b03c6e1d771c862571d2ea1e\nmsg = 55a465644f5b650928cbee7c063214d6\nresult = valid\ntag = 7c43f16ce096d0dc27c95849dc383b7d\n\n# tcId = 36\naad = \nct = 02cc3acb5ee1fcdd12a03bb857976474d3\niv = 45aaa3e5d16d2d42dc03445d\nkey = 3b2458d8176e1621c0cc24c0c0e24c1e80d72f7ee9149a4b166176629616d011\nmsg = 3ff1514b1c503915918f0c0c31094a6e1f\nresult = valid\ntag = d83b7463a2c3800fe958c28eaa290813\n\n# tcId = 37\naad = 9aaf299eeea78f79\nct = 35766488d2bc7c2b8d17cbbb9abfad9e6d\niv = f0384fb876121410633d993d\nkey = f60c6a1b625725f76c7037b48fe3577fa7f7b87b1bd5a982176d182306ffb870\nmsg = 63858ca3e2ce69887b578a3c167b421c9c\nresult = valid\ntag = 1f391e657b2738dda08448cba2811ceb\n\n# tcId = 38\naad = \nct = b621d76a8dacff00b3f840cdf26c894cc5d1\niv = 37270b368f6b1e3e2ca51744\nkey = 37ceb574ccb0b701dd11369388ca27101732339f49d8d908ace4b23af0b7ce89\nmsg = f26991537257378151f4776aad28ae8bd16b\nresult = valid\ntag = e0a21716ed94c0382fa9b0903d15bb68\n\n# tcId = 39\naad = b8373438ddb2d6c3\nct = e0a745186c1a7b147f74faff2a715df5c19d\niv = bfd6ff40f2df8ca7845980cc\nkey = 68888361919bc10622f45df168e5f6a03bd8e884c0611bea2f34c1882ed9832b\nmsg = ff97f2eefb3401ac31fc8dc1590d1a92cbc1\nresult = valid\ntag = 917baf703e355d4d950e6c05fe8f349f\n\n# tcId = 40\naad = \nct = d6e0ed54fccef30bd605d72da3320e249a9cb5\niv = 2343de88be6c7196d33b8694\nkey = 1b35b856b5a86d3403d28fc2103a631d42deca5175cdb0669a5e5d90b2caafc5\nmsg = 21ef185c3ae9a96fa5eb473878f4d0b242781d\nresult = valid\ntag = c68bc6724ec803c43984ce42f6bd09ff\n\n# tcId = 41\naad = cc4efd8364fb114a\nct = 29e54d608237c3c3609dba16e6edf43842d72f\niv = 1af1d90e877e11a496efa3df\nkey = d6484e3973f6be8c83ed3208d5be5cfa06fda72fbfdc5b19d09be3f4e4eba29d\nmsg = 7335ab04b03e706109ec3ee835db9a246ea0ad\nresult = valid\ntag = d3365fdcd506aaaa5368661e80e9d99b\n\n# tcId = 42\naad = \nct = 7fe606652d858f595ec2e706754fa3d933fcc834\niv = 1e7e67be948de7352ffdb727\nkey = 422add37849d6e4c3dfd8020dc6a07e8a249788f3d6a83b9cb4d802362c97542\nmsg = d7f5e611dd3a2750fb843fc1b6b93087310dc87d\nresult = valid\ntag = 78d59235aa5d03a4c32590e590c04d22\n\n# tcId = 43\naad = 956846a209e087ed\nct = 14f707c446988a4903775ec7acec6da114d43112\niv = 376187894605a8d45e30de51\nkey = cdccfe3f46d782ef47df4e72f0c02d9c7f774def970d23486f11a57f54247f17\nmsg = e28e0e9f9d22463ac0e42639b530f42102fded75\nresult = valid\ntag = 987d4b147c490d43d376a198cab383f0\n\n# tcId = 44\naad = \nct = 1003f13ea1329cbb187316f64c3ff3a87cf5b96661\niv = f9d6320d7ce51d8ed0677d3a\nkey = e79dfc6d2fc465b8439e1c5baccb5d8ef2853899fc19753b397e6c25b35e977e\nmsg = 4f543e7938d1b878dacaeec81dce4899974816813b\nresult = valid\ntag = d2323ad625094bec84790d7958d5583f\n\n# tcId = 45\naad = 093053e20261daab\nct = 2d48b0834e9ffe3046103ef7a214f02e8e4d33360e\niv = 50ba1962cdc32a5a2d36e640\nkey = 1d7b8f1d96a1424923aef8a984869d4a777a110990ba465627acf80396c7f376\nmsg = 5d3efd5767f3c12efd08af9a44e028ae68c9eff843\nresult = valid\ntag = d533ad089be229ea606ec0f3fa22eb33\n\n# tcId = 46\naad = \nct = e9917ff3e64bbe1783579375e75ea823976b35539949\niv = c9cc0a1afc38ec6c30c38c68\nkey = dd433e28cfbcb5de4ab36a02bf38686d83208771a0e63dcd08b4df1a07ac47a1\nmsg = 8a3e17aba9606dd49e3b1a4d9e5e42f1742373632489\nresult = valid\ntag = 074a890669b25105434c75beed3248db\n\n# tcId = 47\naad = b2a4e12a19a61c75\nct = db4c700513818972b0dc0e531b1c281ca03e40c60dea\niv = 8ba77644b08d65d5e9f31942\nkey = a60924101b42ac24154a88de42142b2334cf599176caf4d1226f712dd9172930\nmsg = c949957e66439deee4b2ac1d4a6c98a6c527b90f52ab\nresult = valid\ntag = 63f4478bba2af469a7a4dc3b4f141360\n\n# tcId = 48\naad = \nct = b5f14617491fc923b683e2cc9562d043dd5986b97dbdbd\niv = 4b3dca84ecc407f424f281a9\nkey = 1aa42027836965b1e6086fa137f9cf7f1ff48676696829bd281ff81c8ea0a4a9\nmsg = 37252a3eb5c8960f0567e503a9035783b3d0a19a4b9a47\nresult = valid\ntag = 972ce54713c05c4bb4d088c0a30cacd3\n\n# tcId = 49\naad = 413036411af75745\nct = b7ca3879f95140bf6a97b3212218b7bf864a51e5bb0b3e\niv = acad618039b317470d21621b\nkey = 5d40db0cc18ef2e42815d3b6245a466a0b30a0f93e318ac10edde3bf8ad98160\nmsg = 959dde1ef3129b27702c558849e466f2baca1a45bdf4b2\nresult = valid\ntag = fe558fb570145470ea693eb76eb73171\n\n# tcId = 50\naad = \nct = 42f26c56cb4be21d9d8d0c80fc99dde00d75f38074bfe764\niv = e6b1adf2fd58a8762c65f31b\nkey = 0212a8de5007ed87b33f1a7090b6114f9e08cefd9607f2c276bdcfdbc5ce9cd7\nmsg = 10f1ecf9c60584665d9ae5efe279e7f7377eea6916d2b111\nresult = valid\ntag = 54aa7e13d48fff7d7557039457040a3a\n\n# tcId = 51\naad = 3e8bc5ade182ff08\nct = 123032437b4bfd6920e8f7e7e0087ae4889ebe7a0ad0e900\niv = 6b282ebecc541bcd7834ed55\nkey = c5bc09565646e7edda954f1f739223dada20b95c44ab033d0fae4b0283d18be3\nmsg = 9222f9018e54fd6de1200806a9ee8e4cc904d29f25cba193\nresult = valid\ntag = 3cf68f179550da63d3b96c2d55411865\n\n# tcId = 52\naad = \nct = 1d218c9f1f9f02f248a6f976a7557057f37d9393d9f213c1f3\niv = abfaf42e0dba884efcf07823\nkey = 9460b3c44ed86e70f3bda66385e1ca10b0c1677ef4f1360532830d17535f996f\nmsg = 5c5cce881b93fb7a1b7939af1ffc5f84d3280ada778cca0953\nresult = valid\ntag = bc88344c6fdc898feed394fb28511316\n\n# tcId = 53\naad = 84cdff939391c022\nct = 9715d344e8d3f3a3eaa98a9cea57c0cd717c6ef5076027c9ec\niv = 85f18ad8ff72cafee2452ab8\nkey = c111d6d5d78a071b15ab37cc8c3819199387ab7c1933aa97b1489f6584ba8e2a\nmsg = 6989c646a10b7c76f4d9f7d574da40e152013cf0dd78f5aa8a\nresult = valid\ntag = 3056ff5ee0aa8636bb639984edb5236b\n\n# tcId = 54\naad = \nct = 9089bbdb8bcfd124e227bf75c4bfe1cba2004a274fc31aa32358\niv = a6f9a8d335fa84c3b27dcd2a\nkey = 8a1b1e699a0c4a3e610b10902daedab1bf1ea0d505c47d7842cbcee0d3b1b6e6\nmsg = ee6a15fc183108f0877e7f2b8a9615f4b3fc36e1c83440f66aad\nresult = valid\ntag = fd2e21c64a019621c68594826cd7b1cd\n\n# tcId = 55\naad = 85073f2edc13d3a1\nct = 796ffb70ab43e7fa79f95583e384524727bb3e47fc45b969f714\niv = ebc19fc9ecb2339908ea3836\nkey = 74b384e6e013ec4172ed7a28a10fb9bb79b4be2a24f6999e3d3caa28e64a8656\nmsg = 3aa9f7372f056e5a0729752d9a37132d6dd07c56792e1c7582a9\nresult = valid\ntag = c3322b4445de5f3c9f18dcc847cc94c3\n\n# tcId = 56\naad = \nct = 49c81d17d67d7ba9954f497d0b0ddc21f3f839c9d2cc198d30bc2c\niv = f3307430f492d2b8a72d3a81\nkey = 77d824795d2029f0eb0e0baab5cfeb32f7e93474913a7f95c737a667a3c33314\nmsg = 0c4179a497d8fdd72796fb725692b805d63b7c718359cf10518aee\nresult = valid\ntag = 50009899e5b2a9726c8f3556cadfbe84\n\n# tcId = 57\naad = 73365f6d80edb1d8\nct = 4c129fc13cbdd9d3fe81ac755bf4fbea2fdd7e0aca0505a6ee9637\niv = 342ada4f0c115124b222df80\nkey = bec5eac68f893951cbd7d1ecd3ee6611130dd9c3f80cddf95111d07d5edd76d1\nmsg = 481433d8b1cd38af4a750e13a64b7a4e8507682b3517595938a20e\nresult = valid\ntag = 9cede1d30a03db5d55265d3648bc40d4\n\n# tcId = 58\naad = \nct = a6fa8f57ddc81d6099f667dd62402b6a5d5b7d05a329298029113169\niv = 9544d41ece0c92ef01cfac2d\nkey = a59c1e13064df8f2b8df77a492b0ca2eae921b52a84b305a3a9a51408a9ecb69\nmsg = 1c35b898821ba55c2617c25df9e6df2a8002b384902186cd69dfd20e\nresult = valid\ntag = bb24e38b31dbbc3e575b9e3ee076af2a\n\n# tcId = 59\naad = 770f6e6e89a3fe8e\nct = fd42cb5cf894f879e3cf751662aaa58a2288cc53548802becaf42359\niv = 829f005e980f0a6e2f983eaa\nkey = 084b5d7365f1a8fec6365939ed741e6ea5893e0318d82ab47500a97d77aaa041\nmsg = 7510016efadc385a71ed689ceb590c8ea9cc1e81b793338bddf5f10c\nresult = valid\ntag = 188329438afe1cd7225d0478aa90c773\n\n# tcId = 60\naad = \nct = 402302b56140c4dcc39774732c55883de124ce4bf0a0261cfa1569e2cf\niv = 4946a0d6adea93b82d4332e5\nkey = 5a7f850a1d9aafa77d59ae1b731965e8aaec6352280fc76a7b5e23ef3610cfe4\nmsg = 3c161d791f624fb0388e808f0f69ed790dbe4cbd089ebac46627bcf01d\nresult = valid\ntag = e830bfe933a96786cff2dd72b82c4bd5\n\n# tcId = 61\naad = f2415377ad283fd8\nct = d052932bad6e6c4f835f02019e52d7ff807dc2a5aac2040883c79dd3d5\niv = 2f90a65e9e48725de6ffc727\nkey = e6d5a4246f6f05618b59c8f9ec3ac8068cc0d3f351c571aa52b09cb251f9c2f6\nmsg = 964fc9e0e8355947aa1c2caadd7b3dbef82a1024e623606fac436ef573\nresult = valid\ntag = 655f93396b4d755dc4475721665fed91\n\n# tcId = 62\naad = \nct = 83f5c77396cabd28dfcc002cba0756d4ea5455e0261d847d5708aac21e8d\niv = a797205a6cacdd7e47a4789d\nkey = 09e822123adbb1ed89b79a58619c64853992f8371d46338712f6c91ab11a68bb\nmsg = 80b71bbe833629841bd3aeaeb9db6123e51d367b436", "fe9d2d3454b62cfad\nresult = valid\ntag = 705a05820a21f381d244d40e58d2f16b\n\n# tcId = 63\naad = 200a9c95946ff05c\nct = 209b7539385c8b19ecd0fd8b5011b2996e316f1942064e68edfa363acbcd\niv = 9d8cdf289dddd09afdc1b02f\nkey = 625735fe7f8fc81b0c1edc3d08a78b41268f87a3c68488b674222630c1d587a5\nmsg = 67ae1882d0b1c1b2485bec98115ecf53b9b438deb1d0400531705038873a\nresult = valid\ntag = fa2f454b9fa2608f780f7c6f9b780fe1\n\n# tcId = 64\naad = \nct = 45c7d6b53acad4abb68876a6e96a48fb59524d2c92c9d8a189c9fd2db91746\niv = 04a9be03508a5f31371a6fd2\nkey = 2eb51c469aa8eb9e6c54a8349bae50a20f0e382711bba1152c424f03b6671d71\nmsg = b053999286a2824f42cc8c203ab24e2c97a685adcc2ad32662558e55a5c729\nresult = valid\ntag = 566d3ca10e311b695f3eae1551652493\n\n# tcId = 65\naad = 374618a06ea98a48\nct = 46a80c4187024720084627580080dde5a3f4a11093a7076ed6f3d326bc7b70\niv = 470a339ecb3219b8b81a1f8b\nkey = 7f5b74c07ed1b40fd14358fe2ff2a740c116c7706510e6a437f19ea49911cec4\nmsg = f45206abc25552b2abc9ab7fa243035fedaaddc3b2293956f1ea6e7156e7eb\nresult = valid\ntag = 534d4aa2835a52e72d14df0e4f47f25f\n\n# tcId = 66\naad = \nct = ea29afa49d36e8760f5fe19723b9811ed5d519934a440f5081ac430b953b0e21\niv = 72cfd90ef3026ca22b7e6e6a\nkey = e1731d5854e1b70cb3ffe8b786a2b3ebf0994370954757b9dc8c7bc5354634a3\nmsg = b9c554cbc36ac18ae897df7beecac1dbeb4eafa156bb60ce2e5d48f05715e678\nresult = valid\ntag = 222541af46b86533c6b68d2ff108a7ea\n\n# tcId = 67\naad = 2333e5ce0f93b059\nct = 6dad637897544d8bf6be9507ed4d1bb2e954bc427e5de729daf50762846ff2f4\niv = 262880d475f3dac5340dd1b8\nkey = 27d860631b0485a410702fea61bc873f3442260caded4abde25b786a2d97f145\nmsg = 6b2604996cd30c14a13a5257ed6cffd3bc5e29d6b97eb1799eb335e281ea451e\nresult = valid\ntag = 7b997d93c982189d7095dc794c746232\n\n# tcId = 68\naad = \nct = f5982b601c7a18fc72a65b218c44974dc564d8314cbe6f87fcf6c6cfbe618b34b1\niv = c26c4b3bfdb97ee6b0f63ca1\nkey = 5155dee9aade1cc61ee7e3f92660f7590f5e5ba82f1b59b850e3fa453d2fa6b3\nmsg = 2734e08eff8f5c4f84fa0c207f49c7fd78af1ad5123ff81f83f500edf4eda09edf\nresult = valid\ntag = c43632f55760b5d1ed37556a94d049b5\n\n# tcId = 69\naad = e99698241c599b5f\nct = eaf6810e6ec1cb7a2918856257d1aa3d51a827879146c6337ecf535e9c89b149c5\niv = ad8050dc6d122dce3e5639ed\nkey = 573f08ebbe0cce4ac9618e8c3b224bea0a32f055c6996838a32f527ca3c3b695\nmsg = 668d5e3f95fe030daf432a5fc5837af3a79c81e94b28d8204c5ee262ab3c9908a7\nresult = valid\ntag = a2950c2f394a3466c345f796323c1aa7\n\n# tcId = 70\naad = \nct = fba78ae4f9d808a62e3da40be2cb7700c3613d9eb2c529c652e76a432c658d27095f0eb8f940c324981ea935e507f9\niv = e74a515e7e2102b90bef55d2\nkey = cf0d40a4644e5f51815165d5301b22631f4544c49a1878e3a0a5e8e1aae0f264\nmsg = 973d0c753826bae466cf9abb3493152e9de7819e2bd0c71171346b4d2cebf8041aa3cedc0dfd7b467e26228bc86c9a\nresult = valid\ntag = 8f046956db3a512908bd7afc8f2ab0a9\n\n# tcId = 71\naad = b3e4064683b02d84\nct = a1ffed80761829ecce242e0e88b138049016bca018da2b6e19986b3e318cae8d806198fb4c527cc39350ebddeac573\niv = d4d807341683825b31cd4d95\nkey = 6cbfd71c645d184cf5d23c402bdb0d25ec54898c8a0273d42eb5be109fdcb2ac\nmsg = a98995504df16f748bfb7785ff91eeb3b660ea9ed3450c3d5e7b0e79ef653659a9978d75542ef91c456762215640b9\nresult = valid\ntag = c4cbf0befda0b70242c640d7cd02d7a3\n\n# tcId = 72\naad = \nct = 9a4ef22b181677b5755c08f747c0f8d8e8d4c18a9cc2405c12bb51bb1872c8e8b877678bec442cfcbb0ff464a64b74332cf072898c7e0eddf6232ea6e27efe50\niv = d61040a313ed492823cc065b\nkey = 5b1d1035c0b17ee0b0444767f80a25b8c1b741f4b50a4d3052226baa1c6fb701\nmsg = d096803181beef9e008ff85d5ddc38ddacf0f09ee5f7e07f1e4079cb64d0dc8f5e6711cd4921a7887de76e2678fdc67618f1185586bfea9d4c685d50e4bb9a82\nresult = valid\ntag = 9ff3427a0f32fa566d9ca0a78aefc013\n\n# tcId = 73\naad = 7193f623663321a2\nct = 5fbbdecc34be201614f636031eeb42f1cace3c79a12cffd871ee8e73820c829749f1abb4294367849fb6c2aa56bda8a3078f723d7c1c852024b017b58973fb1e\niv = d31c21aba175b70de4ebb19c\nkey = 97d635c4f47574d9998a90875da1d3a284b755b2d39297a5725235190e10a97e\nmsg = 94ee166d6d6ecf8832437136b4ae805d428864359586d9193a25016293edba443c58e07e7b7195ec5bd84582a9d56c8d4a108c7d7ce34e6c6f8ea1bec0567317\nresult = valid\ntag = 09263da7b4cb921452f97dca40f580ec\n\n# tcId = 74\naad = \nct = d0102f6c258bf49742cec34cf2d0fedf23d105fb4c84cf98515e1bc9a64f8ad5be8f0721bde50645d00083c3a263a31053b760245f52ae2866a5ec83b19f61be1d30d5c5d9fecc4cbbe08fd385813a2aa39a00ff9c10f7f23702add1e4b2ffa31c\niv = 17c86a8abbb7e003acde2799\nkey = fe6e55bdaed1f7284ca5fc0f8c5f2b8df56dc0f49e8ca66a41995e783351f901\nmsg = b429eb80fb8fe8baeda0c85b9c333458e7c2992e558475069d12d45c22217564121588032297eff56783742a5fc22d7410ffb29d66098661d76f126c3c27689e43b37267cac5a3a6d3ab49e391da29cd3054a5692e2807e4c3ea46c8761d50f592\nresult = valid\ntag = 41865fc71de12b19612127ce49993bb0\n\n# tcId = 75\naad = a11c40b603767330\nct = 7545391b51de01d5c53dfaca777909063e58edee4bb1227e7110ac4d2620c2aec2f848f56deeb037a8dced75afa8a6c890e2dee42f950bb33d9e2424d08a505d899563973ed38870f3de6ee2adc7fe072c366c14e2cf7ca62fb3d36bee11685461\niv = 46362f45d6379e63e5229460\nkey = aabc063474e65c4c3e9bdc480dea97b45110c8618846ff6b15bdd2a4a5682c4e\nmsg = ceb534ce50dc23ff638ace3ef63ab2cc2973eeada80785fc165d06c2f5100ff5e8ab2882c475afcd05ccd49f2e7d8f55ef3a72e3dc51d6852b8e6b9e7aece57be6556b0b6d9413e33fc5fc24a9a205ad59574bb39d944a92dc47970d84a6ad3176\nresult = valid\ntag = b70d44ef8c66c5c7bbf10dcadd7facf6\n\n# tcId = 76\naad = \nct = 294a764c03353f5f4f6e93cd7e977480d6c343071db0b7c1f0db1e95b85e6053f0423168a9c7533268db9a194e7665359d14489bc47172a9f21370e89b0bd0e5ef9661738de282572bcc3e541247626e57e75dec0f91ac5c530bd1a53271842996dcd04d865321b1ecb6e7630114fe780291b8dc3e5d0abc8e65b1c5493e9af0\niv = 8a3ad26b28cd13ba6504e260\nkey = d7addd3889fadf8c893eee14ba2b7ea5bf56b449904869615bd05d5f114cf377\nmsg = c877a76bf595560772167c6e3bcc705305db9c6fcbeb90f4fea85116038bc53c3fa5b4b4ea0de5cc534fbe1cf9ae44824c6c2c0a5c885bd8c3cdc906f12675737e434b983e1e231a52a275db5fb1a0cac6a07b3b7dcb19482a5d3b06a9317a54826cea6b36fce452fa9b5475e2aaf25499499d8a8932a19eb987c903bd8502fe\nresult = valid\ntag = f2b974ca0f14fb9f92014bff18573cff\n\n# tcId = 77\naad = 0587af8530ad0547\nct = 2b90b4f3de280c44913d1984bdd5dfa0566c6a14a058659a9b623277b0bb6e82101e79395d12e643f62d9a822bae497907493e4f8213fcf99da8a78fdf867af36bc8b0931c1886b4f0ae5729986494dbd59737e956cd8f226c7c522689d082f023894d54acab0c4d609f3746a67369bb8876008f7fd3dc6681c5fb9d728c5911\niv = 903188433c1ce8971aa19b9d\nkey = 80be86fb6fc49bc73428cab576f6ad72ff6aca04001b8b1c57a7128be73900aa\nmsg = 67ce499cd8ed68bd717dfe61c60f27d260b1c163a72e8cc8597253d3d987c2dbe1bff2e44d9bd4765d3e53d9c3f8eb3b90e751f47c7157bdc1142bc33f5833ac1cd1262cbb239066b334a4ed99ae82c74f2b49540f1a614bc239d8fc5add8c178184e41281f6e66c5c3117fd953547f7c829425b5082aa69686847eaf5784692\nresult = valid\ntag = f005ebe1c1ada75a9cee8d630881d5b8\n\n# tcId = 78\naad = 02\nct = 7e72f5a185af16a611921b438f749f0b\niv = 87345f1055fd9e2102d50656\nkey = 7d00b48095adfa3272050607b264185002ba99957c498be022770f2ce2f3143c\nmsg = e5ccaa441bc814688f8f6e8f28b500b2\nresult = valid\ntag = 1242c670732334029adfe1c5001651e4\n\n# tcId = 79\naad = b648\nct = 85f29a719557cdd14d1f8fffab6d9e60\niv = 87a3163ec0598ad95b3aa713\nkey = 6432717f1db85e41ac7836bce25185a080d5762b9e2b18444b6ec72c3bd8e4dc\nmsg = 02cde168fba3f544bbd0332f7adeada8\nresult = valid\ntag = 732ca32becd515a1ed353f542e999858\n\n# tcId = 80\naad = 8b71ac\nct = d46e8265a8c6a25393dd956bb44397ad\niv = 25b7bdf4a6dcbf7c9a3ec2b3\nkey = 7afa0f59dfcb5ad3a76490c5c804327c8d052be737a60fa8bcbf0a2c36630a43\nmsg = 623e6ba6d3166a338bfcc7af90a230c8\nresult = valid\ntag = e28f3ad9e3ef4a3d94ee07bf538eaafb\n\n# tcId = 81\naad = 3a5ddf40\nct = 2d3cb2d9303491e264f2904f0e0753f4\niv = 6fb0d1417cdfff4df37db08c\nkey = 2ec25b0ec7ac244224e9c7fc2fa5d3ef17809e19fd6e954158dd0d72738a4cc8\nmsg = a1c933768a6d573ebf68a99e5e18dae8\nresult = valid\ntag = 6c1db959362d217b2322b466536bfea0\n\n# tcId = 82\naad = 9eec540bb0\nct = a988c03c71b956ff086d0470d706bd34\niv = 2538fc67afb9eab333f83290\nkey = 0a2cf52371cf9d9f95b10108fc82b4fd6110a8ba9a88a26083685ad29826891a\nmsg = 0d8c691d044a3978d790432dc71d69f8\nresult = valid\ntag = b35d7cbf2beb894b0c746e0730429e15\n\n# tcId = 83\naad = 56e014d97c74\nct = 32bf95d4c195dbaf58d9af4001c6e57d\niv = a071be999151e2a1c41c81e9\nkey = 307e886b38bb18b445f8a2c6d6f8932492a9cea8d041ba72eb5efdfa70d0b8d2\nmsg = 9aba22b495cb7ec887ddaa62019aa14d\nresult = valid\ntag = 4393808703d67a90870578046cd8b525\n\n# tcId = 84\naad = bb5a3812f0aefd\nct = 2a2", @@ -3062,9 +3700,9 @@ static const char *kData109[] = { "fffffffffff025d1565924f6c7418de9babf8be4407ffffffffffffffffffffffffffffffffc35e56b05c9d78eb406fb3f474f36294ffffffffffffffffffffffffffffffffc35e56b05c9d78eb406fb3f474f36294\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 19de9b9ec8b247d42bbee2016d6715babf286fd979807951b183a188930ad15ecef0b056a2eecc51d30838e640615e1464413d71939b9cb0a4d32ef115da9e1021d14da7b4f76f9f68fa8903138d563cdef8a3be837efbea7db940f762861f45\nresult = valid\ntag = 369cf17011cae47539e2723f010cf980\n\n# tcId = 283\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = f9ffffffffffffffffffffffffffffff005d1565924f6c7418de9babf8be4407d2ffffffffffffffffffffffffffffff5541133fd4554a1a89a3216ce40b9d0bd2ffffffffffffffffffffffffffffff5541133fd4554a1a89a3216ce40b9d0b\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 19de9b9ec8b247d42bbee2016d6715babd286fd979807951b183a188930ad15ee3f0b056a2eecc51d30838e640615e14f25e78fe1b53ae416d1fbc698522618f0cd14da7b4f76f9f68fa8903138d563c48e7e6310bb6c91bb475d26ff27ee0da\nresult = valid\ntag = 532eb8e272a8d171378b0d42dff2bed9\n\n# tcId = 284\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = d2ffffffffffffffffffffffffffffff98f82782afd996d0efe3800d48c1ca05ffffffffffffffffffffffffffffffff3a0c9639358f7c6d1ee0dc082de4d96effffffffffffffffffffffffffffffff3a0c9639358f7c6d1ee0dc082de4d96e\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 32de9b9ec8b247d42bbee2016d6715ba258d5d3e441683f546beba2e23755f5ccef0b056a2eecc51d30838e640615e149d13fdf8fa899836fa5c410d4ccd25ea21d14da7b4f76f9f68fa8903138d563c27aa6337ea6cff6c23362f0b3b91a4bf\nresult = valid\ntag = d1be7426cd12446fe52e8d45331e0835\n\n# tcId = 285\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = ffffffffffffffffffffffffffffffff6b3fa796480ab62f9884dc7dfb4daf88faffffffffffffffffffffffffffffff79858179ae42311dacad2f325a8d3007faffffffffffffffffffffffffffffff79858179ae42311dacad2f325a8d3007\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 1fde9b9ec8b247d42bbee2016d6715bad64add2aa3c5a30a31d9e65e90f93ad1cbf0b056a2eecc51d30838e640615e14de9aeab86144d5464811b2373ba4cc8324d14da7b4f76f9f68fa8903138d563c6423747771a1b21c917bdc314cf84dd6\nresult = valid\ntag = 62630c18de8c10876adb9f30f300963f\n\n# tcId = 286\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = ffffffffffffffffffffffffffffffff7141e89bc0455e348313475fa4bdb3cbffffffffffffffffffffffffffffffff97d10c4f5c7356f4ef3e5fd79afe6e08ffffffffffffffffffffffffffffffff97d10c4f5c7356f4ef3e5fd79afe6e08\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 1fde9b9ec8b247d42bbee2016d6715bacc3492272b8a4b112a4e7d7ccf092692cef0b056a2eecc51d30838e640615e1430ce678e9375b2af0b82c2d2fbd7928c21d14da7b4f76f9f68fa8903138d563c8a77f9418390d5f5d2e8acd48c8b13d9\nresult = valid\ntag = feb6412b9031f076eddcd9426fff5b31\n\n# tcId = 287\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = d4ffffffffffffffffffffffffffffffcf5e1ff522101a6eade8cd6049b76f0dffffffffffffffffffffffffffffffff20c173ad1d88a70fa8cf4367eef82a8affffffffffffffffffffffffffffffff20c173ad1d88a70fa8cf4367eef82a8a\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 34de9b9ec8b247d42bbee2016d6715ba722b6549c9df0f4b04b5f7432203fa54cef0b056a2eecc51d30838e640615e1487de186cd28e43544c73de628fd1d60e21d14da7b4f76f9f68fa8903138d563c3d6786a3c26b240e9519b064f88d575b\nresult = valid\ntag = dafdf430c8124483c175404b6bff5b41\n\n# tcId = 288\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = ddffffffffffffffffffffffffffffff7817ec25241bcc26c5b27dadbcb12b0f61fa3a21712933597b1da91633f3e64761fa3a21712933597b1da91633f3e647\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 3dde9b9ec8b247d42bbee2016d6715bac5629699cfd4d9036cef478ed705be5650f575882c3800f757ea6e0f8c6d47acc6e551e0be2fd7029fa1341352da1ac3\nresult = valid\ntag = f8800c5b6283dddfc41f935c01bd0d24\n\n# tcId = 289\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = ffffffffffffffffffffffffffffffffdba35e4e633a3c646379bc7f82db98ce07f07c0b2132c73943308806721c542707f07c0b2132c73943308806721c5427\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 1fde9b9ec8b247d42bbee2016d6715ba66d624f288f52941ca24865ce96f0d9736ff33a27c23f4976fc74f1fcd82f5cca0ef17caee342362a78c15031335a8a3\nresult = valid\ntag = 38bfb8318c627d86c34bab1f1ebd0db0\n\n# tcId = 290\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = 14cada5efddb046351f2487c56a6e4f6e5ffffffffffffffffffffffffffffff8558412d1bf9b512930fed3d4b054406e5ffffffffffffffffffffffffffffff8558412d1bf9b512930fed3d4b054406\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = f4ebbe3fca96bc4885b35582c43e0eb3588a85431430eada56a2c5dc944b6aa6b4570e8446e886bcbff82a24f49be5ed42e0943e30f91ba41b4362fa9ed6037b5b76f37550f12572040a9bc1a777edc5\nresult = valid\ntag = af7293eb09957d9de7432dd41316f0e4\n\n# tcId = 291\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = faffffffffffffffffffffffffffffffea6f4576d71568cae5ceee80e97eaf0edbffffffffffffffffffffffffffffffd1d2b02fe01eb32df3f3f0f6dacc4f05dbffffffffffffffffffffffffffffffd1d2b02fe01eb32df3f3f0f6dacc4f05\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 1ade9b9ec8b247d42bbee2016d6715ba571a3fca3cda7def4c93d4a382ca3a57eaf0b056a2eecc51d30838e640615e1476cddbee2f185776174f6df3bbe5b38105d14da7b4f76f9f68fa8903138d563ccc7445213ffd302cce2503f5ccb932d4\nresult = valid\ntag = e178b0d5eb9bc551fa645c49f9f17667\n\n# tcId = 292\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = ffffffffffffffffffffffffffffffff0344dfbdb8a569b44dfc38ef4c796b50e3ffffffffffffffffffffffffffffff7a8b7d60e12965e60abea0434ec70b07e3ffffffffffffffffffffffffffffff7a8b7d60e12965e60abea0434ec70b07\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 1fde9b9ec8b247d42bbee2016d6715babe31a501536a7c91e4a102cc27cdfe09d2f0b056a2eecc51d30838e640615e14dd9416a12e2f81bdee023d462feef7833dd14da7b4f76f9f68fa8903138d563c672d886e3ecae6e73768534058b276d6\nresult = valid\ntag = bdbf63db237d195ecefdc251f5f17677\n\n# tcId = 293\n# edge case intermediate sums in poly1305.\n# poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec\naad = ffffffff\nct = deffffffffffffffffffffffffffffff3812dd4103ddb68f86081010aac51901d3ffffffffffffffffffffffffffffff1c98423cdb89c7e94daa2af16e06d505d3ffffffffffffffffffffffffffffff1c98423cdb89c7e94daa2af16e06d505\niv = 000102030405060703e76f6f\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 3ede9b9ec8b247d42bbee2016d6715ba8567a7fde812a3aa2f552a33c1718c58e2f0b056a2eecc51d30838e640615e14bb8729fd148f23b2a916b7f40f2f29810dd14da7b4f76f9f68fa8903138d563c013eb732046a44e8707cd9f27873a8d4\nresult = valid\ntag = b4ccb422bc5f7264aff73f3675ff5b19\n\n[ivSize = 0]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 294\n# invalid nonce size\naad = \nct = \niv = \nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 64]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 295\n# invalid nonce size\naa", "d = \nct = \niv = 0001020304050607\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 88]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 296\n# invalid nonce size\naad = \nct = \niv = 000102030405060708090a\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 104]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 297\n# invalid nonce size\naad = \nct = \niv = 000102030405060708090a0b0c\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 112]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 298\n# invalid nonce size\naad = \nct = \niv = 000102030405060708090a0b0c0d\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 128]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 299\n# invalid nonce size\naad = \nct = \niv = 000102030405060708090a0b0c0d0e0f\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n[ivSize = 160]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 300\n# invalid nonce size\naad = \nct = \niv = 000102030405060708090a0b0c0d0e0f10111213\nkey = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = \n\n", }; -static const size_t kLen110 = 232513; +static const size_t kLen164 = 232513; -static const char *kData110[] = { +static const char *kData164[] = { "# Imported from Wycheproof's dsa_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: DSA\n# Generator version: 0.8r12\n\n[key.g = 0835aa8c358bbf01a1846d1206323fabe408b0e98789fcc6239da14d4b3f86c276a8f48aa85a59507e620ad1bc745f0f1cbf63ec98c229c2610d77c634d1642e404354771655b2d5662f7a45227178ce3430af0f6b3bb94b52f7f51e97bad659b1ba0684e208be624c28d82fb1162f18dd9dce45216461654cf3374624d15a8d]\n[key.keySize = 1024]\n[key.p = 00b34ce9c1e78294d3258473842005d2a48c8c566cfca8f84c0606f2529b59a6d38aae071b53bb2167eaa4fc3b01fe176e787e481b6037aac62cbc3d089799536a869fa8cdfea1e8b1fd2d1cd3a30350859a2cd6b3ec2f9bfbb68bb11b4bbe2adaa18d64a93639543ae5e16293e311c0cf8c8d6e180df05d08c2fd2d93d570751f]\n[key.q = 00b90b38ba0a50a43ec6898d3f9b68049777f489b1]\n[key.type = DsaPublicKey]\n[key.y = 173931dda31eff32f24b383091bf77eacdc6efd557624911d8e9b9debf0f256d0cffac5567b33f6eaae9d3275bbed7ef9f5f94c4003c959e49a1ed3f58c31b21baccc0ed8840b46145f121b8906d072129bae01f071947997e8ef760d2d9ea21d08a5eb7e89390b21a85664713c549e25feda6e9e6c31970866bdfbc8fa981f6]\n[keyDer = 308201b63082012b06072a8648ce3804013082011e02818100b34ce9c1e78294d3258473842005d2a48c8c566cfca8f84c0606f2529b59a6d38aae071b53bb2167eaa4fc3b01fe176e787e481b6037aac62cbc3d089799536a869fa8cdfea1e8b1fd2d1cd3a30350859a2cd6b3ec2f9bfbb68bb11b4bbe2adaa18d64a93639543ae5e16293e311c0cf8c8d6e180df05d08c2fd2d93d570751f021500b90b38ba0a50a43ec6898d3f9b68049777f489b10281800835aa8c358bbf01a1846d1206323fabe408b0e98789fcc6239da14d4b3f86c276a8f48aa85a59507e620ad1bc745f0f1cbf63ec98c229c2610d77c634d1642e404354771655b2d5662f7a45227178ce3430af0f6b3bb94b52f7f51e97bad659b1ba0684e208be624c28d82fb1162f18dd9dce45216461654cf3374624d15a8d03818400028180173931dda31eff32f24b383091bf77eacdc6efd557624911d8e9b9debf0f256d0cffac5567b33f6eaae9d3275bbed7ef9f5f94c4003c959e49a1ed3f58c31b21baccc0ed8840b46145f121b8906d072129bae01f071947997e8ef760d2d9ea21d08a5eb7e89390b21a85664713c549e25feda6e9e6c31970866bdfbc8fa981f6]\n[sha = SHA-1]\n\n# tcId = 1\n# Legacy:ASN encoding of r misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 302c0214aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\nflags = NoLeadingZero\n\n# tcId = 2\n# valid\nmsg = 313233343030\nresult = valid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 3\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30812d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 4\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082002d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 5\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 302e021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 302c021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 7\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000002d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 8\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000002d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 9\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 10\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 11\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 12\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 13\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 14\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 302d028000aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0280496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 17\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 18\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 19\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 20\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f0000021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 21\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 22\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0500\n\n# tcId = 23\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3032498177302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30312500302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 302f302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0004deadbeef\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3032221a498177021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 303122192500021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30352217021500aa6a258fbf7d90e15614676d377df8b10e38db4a0004deadbeef0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3032021500aa6a258fbf7d90e15614676d377df8b10e38db4a22194981770214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a221825000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3035021500aa6a258fbf7d90e15614676d377df8b10e38db4a22160214496d5220b5f67d3532d1f991203bc3523b964c3b0004deadbeef\n\n# tcId = 32\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3035aa00bb00cd00302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3033aa02aabb302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3035221daa00bb00cd00021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = i", "nvalid\nsig = 3033221baa02aabb021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3035021500aa6a258fbf7d90e15614676d377df8b10e38db4a221caa00bb00cd000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3033021500aa6a258fbf7d90e15614676d377df8b10e38db4a221aaa02aabb0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 38\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 39\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30312280021500aa6a258fbf7d90e15614676d377df8b10e38db4a00000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a22800214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 42\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080312d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30312280031500aa6a258fbf7d90e15614676d377df8b10e38db4a00000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a22800314496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 45\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 46\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e2d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f2d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 312d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 322d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff2d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 51\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 52\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 3031300102302c1500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 53\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 302c021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 302c1500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 55\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 56\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b00\n\n# tcId = 57\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b05000000\n\n# tcId = 58\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b060811220000\n\n# tcId = 59\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0000fe02beef\n\n# tcId = 60\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0002beef\n\n# tcId = 61\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f3000021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 62\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b3000\n\n# tcId = 63\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 3030021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3bbf7f00\n\n# tcId = 64\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 302f302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 65\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 3017021500aa6a258fbf7d90e15614676d377df8b10e38db4a\n\n# tcId = 66\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 3043021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 67\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302e02811500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302e021500aa6a258fbf7d90e15614676d377df8b10e38db4a028114496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 69\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 302f0282001500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 70\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a02820014496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 71\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021600aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021400aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0215496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0213496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 75\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30320285010000001500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3032021500aa6a258fbf7d90e15614676d377df8b10e38db4a02850100000014496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 77\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3036028901000000000000001500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3036021500aa6a258fbf7d90e15614676d377df8b10e38db4a0289010000000000000014496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 79\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 303102847fffffff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 80\n# length of integer = 2**", "31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a02847fffffff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 81\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30310284ffffffff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a0284ffffffff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 83\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30320285ffffffffff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3032021500aa6a258fbf7d90e15614676d377df8b10e38db4a0285ffffffffff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 85\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30350288ffffffffffffffff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3035021500aa6a258fbf7d90e15614676d377df8b10e38db4a0288ffffffffffffffff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 87\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d02ff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a02ff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 89\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 30160214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 90\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 3017020214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 3018021500aa6a258fbf7d90e15614676d377df8b10e38db4a02\n\n# tcId = 92\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021700aa6a258fbf7d90e15614676d377df8b10e38db4a00000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a0216496d5220b5f67d3532d1f991203bc3523b964c3b0000\n\n# tcId = 94\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f0217000000aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a02160000496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 96\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a00000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 97\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021700aa6a258fbf7d90e15614676d377df8b10e38db4a05000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 302f021500aa6a258fbf7d90e15614676d377df8b10e38db4a0216496d5220b5f67d3532d1f991203bc3523b964c3b0500\n\n# tcId = 99\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 301802810214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3019021500aa6a258fbf7d90e15614676d377df8b10e38db4a0281\n\n# tcId = 101\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 301805000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 3019021500aa6a258fbf7d90e15614676d377df8b10e38db4a0500\n\n# tcId = 103\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d001500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d011500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d031500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d041500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 107\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302dff1500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 108\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0014496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 109\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0114496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 110\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0314496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 111\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0414496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 112\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4aff14496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 113\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 301802000214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 114\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 3019021500aa6a258fbf7d90e15614676d377df8b10e38db4a0200\n\n# tcId = 115\n# using composition for integer\nmsg = 313233343030\nresult = invalid\nsig = 303122190201000214aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 116\n# using composition for integer\nmsg = 313233343030\nresult = invalid\nsig = 3031021500aa6a258fbf7d90e15614676d377df8b10e38db4a221802014902136d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 117\n# modify first byte of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021502aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 118\n# modify first byte of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a02144b6d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 119\n# modify last byte of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38dbca0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 120\n# modify last byte of integer\nmsg = 313233343030\nresult = invalid\nsig = 302d021500aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964cbb\n\n# tcId = 121\n# truncated integer\nmsg = 313233343030\nresult = invalid\nsig = 302c021400aa6a258fbf7d90e15614676d377df8b10e38db0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 122\n# truncated integer\nmsg = 313233343030\nresult = invalid\nsig = 302c021500aa6a258fbf7d90e15614676d377df8b10e38db4a0213496d5220b5f67d3532d1f991203bc3523b964c\n\n# tcId = 123\n# truncated integer\nmsg = 313233343030\nresult = invalid\nsig = 302c021500aa6a258fbf7d90e15614676d377df8b10e38db4a02136d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 124\n# leading ff in integer\nmsg = 313233343030\nresult = invalid\nsig = 302e0216ff00aa6a258fbf7d90e15614676d377df8b10e38db4a0214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 125\n# leading ff in integer\nmsg = 313233343030\nresult = invalid\nsig = 302e021500aa6a258fbf7d90e15614676d377df8b10e38db4a0215ff496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 126\n# replaced integer by infinity\nmsg = 313233343030\nresult = invalid\nsig = 30190901800214496d5220b5f67d3532d1f991203bc3523b964c3b\n\n# tcId = 127\n# replaced integer by infinity\nmsg = 313233343030\nresult = in", @@ -3095,9 +3733,9 @@ static const char *kData110[] = { "= 54657374\nresult = invalid\nsig = 3008090380fe01020101\nflags = EdgeCase\n\n# tcId = 881\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3008090380fe010201ff\nflags = EdgeCase\n\n# tcId = 882\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3023090380fe01021c5d7b4b5342bc7befef73fd33e4bbe3c2f7995919dd72c0605e6ab4ae\nflags = EdgeCase\n\n# tcId = 883\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3023090380fe01021c5d7b4b5342bc7befef73fd33e4bbe3c2f7995919dd72c0605e6ab4af\nflags = EdgeCase\n\n# tcId = 884\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3024090380fe01021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695c\nflags = EdgeCase\n\n# tcId = 885\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3024090380fe01021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d\nflags = EdgeCase\n\n# tcId = 886\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3024090380fe01021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695e\nflags = EdgeCase\n\n# tcId = 887\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3024090380fe01021d0100000000000000000000000000000000000000000000000000000000\nflags = EdgeCase\n\n# tcId = 888\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3082010a090380fe0102820101008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667\nflags = EdgeCase\n\n# tcId = 889\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 300a090380fe01090380fe01\nflags = EdgeCase\n\n# tcId = 890\n# Signatures with special case values for r and s.\nmsg = 54657374\nresult = invalid\nsig = 3008090380fe01090142\nflags = EdgeCase\n\n# tcId = 891\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 30060201010c0130\n\n# tcId = 892\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 30050201010c00\n\n# tcId = 893\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 30090c0225730c03732573\n\n# tcId = 894\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 30080201013003020100\n\n# tcId = 895\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 3003020101\n\n# tcId = 896\n# Signature encoding contains wrong type.\nmsg = 54657374\nresult = invalid\nsig = 3006020101010100\n\n# tcId = 897\n# random signature\nmsg = 54657374\nresult = valid\nsig = 303c021c296410b8cb6200edafd1205e7377a09ad2011ac7b15b8bc9b9b4c6db021c25ca283c868dc2a5ce86aafcf681ce21d660b461da48270f15b53889\n\n# tcId = 898\n# random signature\nmsg = 54657374\nresult = valid\nsig = 303d021c347c4f6875bf4476afbdd6b2b1f9e35c870e785e708e661109bd068e021d00b0b908a617d3ad6c8bc277f397095c00e659c86ca7c600090571ab17\n\n# tcId = 899\n# random signature\nmsg = 54657374\nresult = valid\nsig = 303c021c3c76bc6f17369414d4c21c5361ed0cca6e79f73f90706f1f7ca9f05a021c3cc60d8a0d44fb967baa0e5621e12cd434aafd748cba3e7cdc733b2f\n\n# tcId = 900\n# random signature\nmsg = 54657374\nresult = valid\nsig = 303e021d0086a5efea8e6a8033b8a0034b52ae614e1f14fbcbfa0bb50194efa6a7021d00b3d66f6d2b10cfe62fe96b78fcf41ca7b442aceb98ab109a01409e4a\n\n# tcId = 901\n# random signature\nmsg = 54657374\nresult = valid\nsig = 303d021c16727d52bd711e9a63e0dd2c4db045cfb993942b1e39e4f43a65c11a021d009fb9c02d10c968e75bb15acab8467f30b84481f679e136e8af65a266\n\n[key.g = 16a65c58204850704e7502a39757040d34da3a3478c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f37eeb1e09f3182d23c9043cb642f88004160edf9ca09b32076a79c32a627f2473e91879ba2c4e744bd2081544cb55b802c368d1fa83ed489e94e0fa0688e32428a5c78c478c68d0527b71c9a3abb0b0be12c44689639e7d3ce74db101a65aa2b87f64c6826db3ec72f4b5599834bb4edb02f7c90e9a496d3a55d535bebfc45d4f619f63f3dedbb873925c2f224e07731296da887ec1e4748f87efb5fdeb75484316b2232dee553ddaf02112b0d1f02da30973224fe27aeda8b9d4b2922d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1ef17dbde]\n[key.keySize = 2048]\n[key.p = 008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667]\n[key.q = 00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d]\n[key.type = DsaPublicKey]\n[key.y = 00848177b9bcff136c52caef2a4a9bcb64dbefbac69e18aae499696b5ec7b270e90478b413bb8ad8f8eee8ad32107d7ba492c36b007f9ef30ebe1ee484d0ea7cb0ff4afaa8c705ad5e16576975414f1bc0efed25c2190a3ed0068bffa1f03bf6f21056c9bb383350851997cbc89cf8729b394527f08ab93ce9b360aa055a47177e82a4ce6fe76c8dffddbd6ee20fa08d0085d3983edd2c8d9a366ad2245b4ed28d6754769f5f3a798be4be19cf469399865d464e3f640438bce03c962c2344d0d550542aed3db55c153833bea44b4146878ba347c8614436c6aac4fd1a60f25c62b3f869a7d55cab4b7122d5e9af4322a3fc8214fa55dc1ee021459fb2c4595827]\n[keyDer = 308203433082023506072a8648ce3804013082022802820101008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d0282010016a65c58204850704e7502a39757040d34da3a3478c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f37eeb1e09f3182d23c9043cb642f88004160edf9ca09b32076a79c32a627f2473e91879ba2c4e744bd2081544cb55b802c368d1fa83ed489e94e0fa0688e32428a5c78c478c68d0527b71c9a3abb0b0be12c44689639e7d3ce74db101a65aa2b87f64c6826db3ec72f4b5599834bb4edb02f7c90e9a496d3a55d535bebfc45d4f619f63f3dedbb873925c2f224e07731296da887ec1e4748f87efb5fdeb75484316b2232dee553ddaf02112b0d1f02da30973224fe27aeda8b9d4b2922d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1ef17dbde03820106000282010100848177b9bcff136c52caef2a4a9bcb64dbefbac69e18aae499696b5ec7b270e90478b413bb8ad8f8eee8ad32107d7ba492c36b007f9ef30ebe1ee484d0ea7cb0ff4afaa8c705ad5e16576975414f1bc0efed25c2190a3ed0068bffa1f03bf6f21056c9bb383350851997cbc89cf8729b394527f08ab93ce9b360aa055a47177e82a4ce6fe76c8dffddbd6ee20fa08d0085d3983edd2c8d9a366ad2245b4ed28d6754769f5f3a798be4be19cf469399865d464e3f640438bce03c962c2344d0d550542aed3db55c153833bea44b4146878ba347c8614436c6aac4fd1a60f25c62b3f869a7d55cab4b7122d5e9af4322a3fc8214fa55dc1ee021459fb2c4595827]\n[sha = SHA-256]\n\n# tcId = 902\n# r,s = 1,1\nmsg = 54657374\nresult = valid\nsig = 3006020101020101\n\n# tcId = 903\n# r,s = 1,5\nmsg = 54657374\nresult = valid\nsig = 3006020101020105\n\n# tcId = 904\n# u2 small\nmsg = 54657374\nresult = valid\nsig = 3022020101021d009592121ed12d93197f1ffb863ac63937f28ef4f62f1e009a30aabab1\n\n# tcId = 905\n# s == q-1\nmsg = 54657374\nresult = valid\nsig = 3022020101021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695c\n\n[key.g = 16a65c58204850704e7502a39757040d34da3a3478c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f37eeb1e09f3182d23c9043cb642f88004160edf9ca09b32076a79c32a627f2473e91879ba2c4e744bd2081544cb55b802c368d1fa83ed489e94e0fa0688e32428a5c78c478c68d0527b71c9a3abb0b0be12c44689639e7d3ce74db101a65aa2b87f64c6826db3ec72f4b5599834bb4edb02f7c90e9a496d3a55d535bebfc45d4f619f63f3dedbb873925c2f224e07731296d", "a887ec1e4748f87efb5fdeb75484316b2232dee553ddaf02112b0d1f02da30973224fe27aeda8b9d4b2922d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1ef17dbde]\n[key.keySize = 2048]\n[key.p = 008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667]\n[key.q = 00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d]\n[key.type = DsaPublicKey]\n[key.y = 629374929537e2c3b09f30d881554ca7357f89e25105474dbbce06e4001efd61481a457aa0d7d7e565e90b7a3d9c688005fb404bf3b6d3e61e402300beee7c58ceeaf00b112ddfeef3cbc2020ba2206dd4ef0563d7fa52c321b4ee6280eb8585041d03cadb9244dff21dc90417bbe6f06b91c2ca6484437c3846926b18ee22275081b60726e7a26a29a947eabd035ede83d65927b3ceb0d4d8c2f34e94a3de0f57e4ea99af059657529f6954b1ac9bb4484ca76b4083e1cf4264eff028662137761e4d7f35b1eda3cf516856f25553840e43ae38379d234b06c891822132081d19f0d5db9f23b4bbd5f5667dd78f3dd7f1fe5f25ca48515f6335ce1c9fd0a64b]\n[keyDer = 308203423082023506072a8648ce3804013082022802820101008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667021d00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d0282010016a65c58204850704e7502a39757040d34da3a3478c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f37eeb1e09f3182d23c9043cb642f88004160edf9ca09b32076a79c32a627f2473e91879ba2c4e744bd2081544cb55b802c368d1fa83ed489e94e0fa0688e32428a5c78c478c68d0527b71c9a3abb0b0be12c44689639e7d3ce74db101a65aa2b87f64c6826db3ec72f4b5599834bb4edb02f7c90e9a496d3a55d535bebfc45d4f619f63f3dedbb873925c2f224e07731296da887ec1e4748f87efb5fdeb75484316b2232dee553ddaf02112b0d1f02da30973224fe27aeda8b9d4b2922d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1ef17dbde038201050002820100629374929537e2c3b09f30d881554ca7357f89e25105474dbbce06e4001efd61481a457aa0d7d7e565e90b7a3d9c688005fb404bf3b6d3e61e402300beee7c58ceeaf00b112ddfeef3cbc2020ba2206dd4ef0563d7fa52c321b4ee6280eb8585041d03cadb9244dff21dc90417bbe6f06b91c2ca6484437c3846926b18ee22275081b60726e7a26a29a947eabd035ede83d65927b3ceb0d4d8c2f34e94a3de0f57e4ea99af059657529f6954b1ac9bb4484ca76b4083e1cf4264eff028662137761e4d7f35b1eda3cf516856f25553840e43ae38379d234b06c891822132081d19f0d5db9f23b4bbd5f5667dd78f3dd7f1fe5f25ca48515f6335ce1c9fd0a64b]\n[sha = SHA-256]\n\n# tcId = 906\n# s == 1\nmsg = 54657374\nresult = valid\nsig = 3021021c5a252f4fc55618747fd94b13c9bee62bb958d85777cb07dd90710d24020101\n\n", }; -static const size_t kLen111 = 133793; +static const size_t kLen165 = 133793; -static const char *kData111[] = { +static const char *kData165[] = { "# Imported from Wycheproof's ecdh_secp224r1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDH\n# Generator version: 0.8r12\n\n[curve = secp224r1]\n[encoding = asn]\n\n# tcId = 1\n# normal case\nprivate = 565577a49415ca761a0322ad54e4ad0ae7625174baf372c2816f5328\npublic = 304e301006072a8648ce3d020106052b81040021033a00047d8ac211e1228eb094e285a957d9912e93deee433ed777440ae9fc719b01d050dfbe653e72f39491be87fb1a2742daa6e0a2aada98bb1aca\nresult = valid\nshared = b8ecdb552d39228ee332bafe4886dbff272f7109edf933bc7542bd4f\n\n# tcId = 2\n# compressed public key\nprivate = 565577a49415ca761a0322ad54e4ad0ae7625174baf372c2816f5328\npublic = 3032301006072a8648ce3d020106052b81040021031e00027d8ac211e1228eb094e285a957d9912e93deee433ed777440ae9fc71\nresult = acceptable\nshared = b8ecdb552d39228ee332bafe4886dbff272f7109edf933bc7542bd4f\nflags = CompressedPoint\n\n# tcId = 3\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004e73a6ca72f3a2fae6e0a01a0ed03bfa3058b04576942eaf063095e62ca16fd31fa0f38eeb592cbeea1147751fdd2a5b6cc0ead404467a5b6\nresult = valid\nshared = 00000000000000000000000000000000000000000000000000000003\n\n# tcId = 4\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a00045763fa2ae16367ad23d471cc9a52466f0d81d864e5640cefe384114594d9fecfbed4f254505ac8b41d2532055a07f0241c4818b552cbb636\nresult = valid\nshared = 00000000000000000000000100000000000000000000000000000001\n\n# tcId = 5\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004142c1fd80fa2121a59aa898144084ec033f7a56a34eee0b499e29ae51c6d8c1bbb1ef2a76d565899fe44ffc1207d530d7f598fb77f4bb76b\nresult = valid\nshared = 00000000000000ffffffffffffff0000000000000100000000000000\n\n# tcId = 6\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ed6f793e10c80d12d871cf8988399c4898a9bf9ffd8f27399f63de25f0051cdf4eec7f368f922cfcd948893ceca0c92e540cc4367a99a66a\nresult = valid\nshared = 00000000ffffffffffffffff00000000000000010000000000000000\n\n# tcId = 7\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a000408fcfc1a63c82860be12e4137433dfc40be9acdd245f9a8c4e56be61a385fc09f808383383f4b1d0d5365b6e5dcfacdc19bc7bcfed221274\nresult = valid\nshared = 0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff\n\n# tcId = 8\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004d883ed77f1861e8712800d31df67888fe39f150c79a27aa88caeda6b180f3f623e2ff3ab5370cf8179165b085af3dd4502850c0104caed9a\nresult = valid\nshared = 0003fffffff00000003fffffff00000003fffffff000000040000000\n\n# tcId = 9\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a00042b8b279b85ee3f3d2c0abeb36fdfc5aad6157d652d26489381a32cd73224bd757ef794acc92b0b3b9e7990618bb343a9a09bdb9d3616eff6\nresult = valid\nshared = 01fffffffc00000007fffffff00000001fffffffc000000080000001\n\n# tcId = 10\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a00048bd5f03391eeeae1744e8fc53d314efffafa4d3fa4f1b95c3388a9cd7c86358b273119c537133eb55e79c6ac510b10980b379b919ccf2e2f\nresult = valid\nshared = 0a15c112ff784b1445e889f955be7e3ffdf451a2c0e76ab5cb32cf41\n\n# tcId = 11\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ce9631b6a16227778625c8e5421ae083cdd913abefde01dbe69f6c2b95386aff2b483b2c47151cfaabfd000614c683ce2e1778221ae42c1b\nresult = valid\nshared = 62989eaaa26a16f07330c3c51e0a4631fd016bfcede26552816aee39\n\n# tcId = 12\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a00041f441c98eda956a6a7fdbfd8d21910860ab59d16c3e52f8e7fad6ca5df61a55fc508fc0499c55492f1e87bb2faa0cb4170b79f3a85ec2f3d\nresult = valid\nshared = 661ac958c0febbc718ccf39cefc6b66c4231fbb9a76f35228a3bf5c3\n\n# tcId = 13\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004be74583cb9d3a05ae54923624e478a329a697d842dfae33141c844d7d9ba4fc96e0fe716ac0542e87368662fc2f0cb9b0ae57936ddec7190\nresult = valid\nshared = 6d7e41821abe1094d430237923d2a50de31768ab51b12dce8a09e34c\n\n# tcId = 14\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004a281ad992b363597ac93ff0de8ab1f7e51a6672dcbb58f9d739ba430ce0192874038daefc3130eec65811c7255da70fea65c1003f6892faa\nresult = valid\nshared = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 15\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004be3e22133f51203f631b81dde8c020cdea5daa1f99cfc05c88fad2dc0f243798d6e72d1de9e3cdca4144e0a6c0f2a584d07589006972c197\nresult = valid\nshared = fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0008001\n\n# tcId = 16\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004af14547c20afbd91bfe64ea03d45a76a71241f23520ef897ff91eff1b54ca6ca8c25fd73852ec6654617434eff7f0225684d4dea7a4f8a97\nresult = valid\nshared = ffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff\n\n# tcId = 17\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004b1e484925018729926acda56ff3e2f6c1e7e8f162b178d8e8afb45564fceaa6da5d998fe26b6b26a055169063a5ab6908852ca8b54e2de6c\nresult = valid\nshared = fffff0000007fffffe000000ffffffc000001ffffff8000003ffffff\n\n# tcId = 18\n# edge case for shared secret\nprivate = 00a2b6442a37f9201b56758034d2009be64b0ab7c02d7e398cac9665d6\npublic = 304e301006072a8648ce3d020106052b81040021033a0004937eb09fb145c8829cb7df20a4cbeed396791373de277871d6c5f9cc3b5b4fd56464a71fc4a2a6af3bd251952bffa829489e68a8d06f96b6\nresult = valid\nshared = ffffffff00000000ffffffff00000000ffffffff00000000ffffffff\n\n# tcId = 19\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004000000000000000000000000000000000000000000000000000000037cac269c67bd55ea14efff4eadefe5e74978514af14c88fab46ec046\nresult = valid\nshared = 3fa0b9ff70b884f9f57bb84f7a9532d93f6ba803f89dd8ff008177d7\n\n# tcId = 20\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004000000000000000000000001000000000000000000000000000000012ea2f4917bdfdb008306cc10a18e2557633ba861001829dcbfb96fba\nresult = valid\nshared = be1ded8cb7ff8a585181f96d681e31b332fe27dcae922dca2310300d\n\n# tcId = 21\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a000400000000000000ffffffffffffff000000000000010000000000000073ca5f8f104997a2399e0c7f25e72a75ec29fc4542533d3fea89a33a\nresult = valid\nshared = a2e86a260e13515918a0cafdd87855f231b5624c560f976159e06a75\n\n# tcId = 22\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a000400000000ffffffffffffffff000000000000000100000000000000006fe6805f59b19b0dd389452a1d4a420bfeb6c369cf6fed5b12e6e654\nresult = valid\nshared = 31ef7c8d10404a0046994f313a70574b027e87f9028eca242c1b5bf5\n\n# tcId = 23\n# edge cases for ephemeral key\nprivate = 2bc15", "cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a00040000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff77c5cfa4e2c384938d48bd8dd98f54c86b279f1df8c0a1f6692439c9\nresult = valid\nshared = d1976a8ef5f54f24f5a269ad504fdca849fc9c28587ba294ef267396\n\n# tcId = 24\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a00040003fffffff00000003fffffff00000003fffffff00000004000000001f0828136016bb97445461bc59f2175d8d23557d6b9381f26136e3d\nresult = valid\nshared = ce7890d108ddb2e5474e6417fcf7a9f2b3bd018816062f4835260dc8\n\n# tcId = 25\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a000401fffffffc00000007fffffff00000001fffffffc0000000800000012d8acca6f199d4a94b933ba1aa713a7debde8ac57b928f596ae66a66\nresult = valid\nshared = 30b6ff6e8051dae51e4fe34b2d9a0b1879153e007eb0b5bdf1791a9c\n\n# tcId = 26\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a00040a15c112ff784b1445e889f955be7e3ffdf451a2c0e76ab5cb32cf413d4df973c563c6decdd435e4f864557e4c273096d9941ca4260a266e\nresult = valid\nshared = 77ec668a00f72d85aa527624abb16c039fe490d17dd6c455a1ed7fd8\n\n# tcId = 27\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a000462989eaaa26a16f07330c3c51e0a4631fd016bfcede26552816aee39389ee9436d616cab90032931aa7fbbfcfc13309f61e2423cc8dab93c\nresult = valid\nshared = a3f432f6aba9a92f49a5ea64ffe7059a9d9b487a0b5223ddc988208b\n\n# tcId = 28\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004661ac958c0febbc718ccf39cefc6b66c4231fbb9a76f35228a3bf5c3103b8040e3cb41966fc64a68cacb0c14053f87d27e8ed7bf2d7fe51b\nresult = valid\nshared = 1530fd9caf03737af34a4ba716b558cbecbc35d18402535a0a142313\n\n# tcId = 29\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a00046d7e41821abe1094d430237923d2a50de31768ab51b12dce8a09e34c276cf273d75d367820dd556182def0957af0a314f48fed227c298dc0\nresult = valid\nshared = cfc39ccacb94ad0e0552b2e47112f60fbbe7ae0dc32230b9273dd210\n\n# tcId = 30\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a00047fffffffffffffffffffffffffffffffffffffffffffffffffffffff7d8dbca36c56bcaae92e3475f799294f30768038e816a7d5f7f07d77\nresult = valid\nshared = 73bd63bd384a0faafb75cfed3e95d3892cbacf0db10f282c3b644771\n\n# tcId = 31\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc000800174f1ff5ea7fbc72b92f61e06556c26bab84c0b082dd6400ca1c1eb6d\nresult = valid\nshared = 85b079c62e1f5b0fd6841dfa16026e15b641f65e13a14042567166bb\n\n# tcId = 32\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0126fdd5fccd0b5aa7fd5bb5b1308584b30556248cec80208a2fe962\nresult = valid\nshared = 8a834ff40e3fc9f9d412a481e18537ea799536c5520c6c7baaf12166\n\n# tcId = 33\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004fffff0000007fffffe000000ffffffc000001ffffff8000003ffffff20cfa23077acc9fbcb71339c65880cd0b966b8a9497e65abed17f0b5\nresult = valid\nshared = a0887269766e6efcbc81d2b38f2d4638663f12377468a23421044188\n\n# tcId = 34\n# edge cases for ephemeral key\nprivate = 2bc15cf3981f4e15bbad387b506df647989e5478160be862f8c26969\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ffffffff00000000ffffffff00000000ffffffff00000000ffffffff1c05ac2d4f10b69877c3243d51f887277b7bf735c326ab2f0d70da8c\nresult = valid\nshared = c65d1911bc076a74588d8793ce7a0dcabf5793460cd2ebb02754a1be\n\n# tcId = 35\n# point with coordinate y = 1\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a00043b5889352ddf7468bf8c0729212aa1b2a3fcb1a844b8be91abb753d500000000000000000000000000000000000000000000000000000001\nresult = valid\nshared = e973c413cc7dd34d4e3637522b2e033c20815412b67574a1f2f6bdd7\n\n# tcId = 36\n# point with coordinate y = 1\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004bf09e268942555c73ce9e00d272c9b12bf0c3fc13a639acc791167f6b05df0023c9bd41d0b0c461854582d0601182213f2219d44ea44914a\nresult = valid\nshared = ec856e807808a9c5332e886759e03f01be02437cfe0214613e4e7dc7\n\n# tcId = 37\n# point with coordinate y = 1\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a00047b664cff2eef0a4f7dce24780113432f66feb25cb0931d033d63910f548ee514f6fdf1cb6f5709581c197d76a5eb218afaed19f205f4ab80\nresult = valid\nshared = 91d424e122c9c01720bbed6b53ec1b37a86996fa4fcf74bfd30f723d\n\n# tcId = 38\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a00045a2b3ec1053390550b587557712bcc0bf85654d23099420154877ec4138322ca02e5fceae870227a43ae8982b67276f6d8f1dd7e12692474\nresult = valid\nshared = 012879a1ff456acb8726455836bc4f504c1bd799a4d96f514b3730c6\n\n# tcId = 39\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004fc229bb1df3e11351e7e4224f68f40c0d0e194023c6e0840cd45ee5ca242112fbab5736e821dad26493e4006e2c6125342e7d9bc25272856\nresult = valid\nshared = fd6e5edb54d7dd554f8747ec87b8031258fc0bf1d2404b64db4540d4\n\n# tcId = 40\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a000469a65f62d4159235801a246f2d13e45c8983a3362da480e7a51d42a65b7047abfc2a179d943bb196fede7ac3ad8a4fcacd4c4caa717b6b26\nresult = valid\nshared = 164e95bfa2a9c3a1f959feb88720bb7a37f988a08124639d8adf86df\n\n# tcId = 41\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004dc68eb945528af0051cbf23e3eea43b2bc4c728976231e7031e63a2744ba65a4e1e34e8ec50cf7e8df4458582b16413ab83f568508c59037\nresult = valid\nshared = b0ffd55fa112aa48eddc960db4a1200d406e144aac9e109ad9892b2d\n\n# tcId = 42\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a000481c89369d7be252920e08e2d6c6841b887efb4fc747db31dd1030b1919bf8ccb629b58fea6234e39812083fb0833a0c937e348eda22ea0c0\nresult = valid\nshared = d6ab4567eff21277284be082d9e09eb08bb80685f4929dc3dca4b333\n\n# tcId = 43\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a000451d830f792795409f1ee972d3b94289f59206fe09e12166920739a73d2f1831b26677901bfaf8323f82b81e1012d9d3f1c9296c59c97970f\nresult = valid\nshared = b43de12912b40cbdd56e30fdfe9a2c24fb72687168c9cfe6b7476966\n\n# tcId = 44\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ab63ce55145842149f99023f37a0a89b9fc4ae6a878fdae8caf31d17ffd0d55830eed46f8255f94b6dcf98a22f1ff26dabf773d556788881\nresult = valid\nshared = 588ee0af3bc60118a715325c6d56c850f73067dcb37b7596d0cfda5f\n\n# tcId = 45\n# point with coordinate y = 1 in left to", " right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a00041d64535d54bfcccb38165acbfac01ae33db20e802c5687343cb21b7eb59d86f1892a974741925624477eef21f4e72fa04ee6ce35dfffe5f2\nresult = valid\nshared = 7219ef73ac9e47ac2e03dead23fa8382ae898e2415017cdeb4739f0f\n\n# tcId = 46\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004d9d78436a3f9c1fa20e8c2318e61e62b94623e23a0ab746c5ac0cbc38262bd66c17515d3048944dae43b2bd6dd9d7c7a0f7042de2d1001c6\nresult = valid\nshared = 267b069aac5d768a720acc62c92f20b786fc48c7da42f1f5677424ee\n\n# tcId = 47\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a000465eb3750c6401339caa69ebe6dec86dfc4d79bf657d68bbdd082c5a03eb81e85931352ff338ccbc3a1d332e2d8bc84342d516da06bef220f\nresult = valid\nshared = bbdd4ac5890b9c0412e4ef3135f666e5b3ddb658ec837691e8129be8\n\n# tcId = 48\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004e92d3be1614555ae17a90647979fbb37468c55a1fff9e15f376d49994e470f515b7b3fe50cb55def16142df594c3e46d9d1354730778f9e8\nresult = valid\nshared = f793ff0d14bd7690840c733162b589cd3413d8c41f4488b427da496f\n\n# tcId = 49\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a00043c92710c9a7f6f98bbec9d2a4fa617cc70e96bc96ecd4597e329143f4750a027c6972459c091ab02c0e2a3082fccec429a38d3596e7aff2b\nresult = valid\nshared = 56c703d4716239c954109b9b841db75b04a790f1f72aa966aece3494\n\n# tcId = 50\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004568dfbfa42efc94ce207322e637b4c94f37a5668ad230e987a91d048dcadd244fc059cffab5fa8820a969353620e708e85bd5eec8a0c68ec\nresult = valid\nshared = 7823fe7eb642d50984fb32f911ef289419d85330c3398423d0eda05f\n\n# tcId = 51\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004ec10837e495b644904dba58d8dd82133c905a285ae7c2a06d5ccaf6bf0fbf00d13e21a399dc95ae5524a1a37044193e94e3300259b70e058\nresult = valid\nshared = f7014d38f460836a51075cce9667b56b8851ba19011c8b0274b74a4b\n\n# tcId = 52\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004bee2f9352f42ceeb3bf3109e90e6578d0bd4888458df7d179d746977e50e53503dee83eca1824a290566588fa3591645b1a2d56861bda760\nresult = valid\nshared = 777f99f2bdaa72a1185388465ddda1d059872ad043c7cb85b94e28bb\n\n# tcId = 53\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a0004546facbcaa8b551c51715a9add5edc3c8a66dcc47a6223f605614cf7af6d92f5bdebea738658a42c6231e53c08237ccf52f79399579b2dcc\nresult = valid\nshared = a1db178b716e51e0fa46c1d74a2603005326bca7e81170d4b33a3d2a\n\n# tcId = 54\n# point with coordinate y = 1 in left to right addition chain\nprivate = 00938f3dbe37135cdbdb9993a187a0e9b9f0def035fbc52ad59fc50421\npublic = 304e301006072a8648ce3d020106052b81040021033a000423b1811fee891adb33c8bfee289964e92a9d3358daf975d0efb73e229a3332668b7d6da290a2edc941e8bd6f2e33745fc606756eddc013bb\nresult = valid\nshared = f455c8273416199505019861266ddb9bcde7bee3c3f15a98ee54607b\n\n# tcId = 55\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a000458f53d67332415fe5b4b81999f8332fb6dcdb965d96dbcbab0fac375f29efef7ab4d94bb2d25d25205eae29fe8d9a85b811114a50f6c6859\nresult = valid\nshared = d3af1857aca1689514fcfee8d8c40b8637d40452ae35c404f9e67494\n\n# tcId = 56\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004f2d6e58fcd3ed3f656a9bc687fe4c789ba9614d0359967bc0468eabfa1658a14ef0633f2485e29141e2c4a13bd328ec9bf6af4c7a774131b\nresult = valid\nshared = 933c385d5fadb57de53e4a5d385118fce830430703c3f585a5d4d0b5\n\n# tcId = 57\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a000402ca5d1b7638b7b88ad02176bd10ff1cfe8812a62f9769a6d62e0c6c787b3e3b2a063940911bf987fc38deebf542400b8bbd9dfeb7d90a8a\nresult = valid\nshared = 75aea79d99e5c7edaab0284443b548843371d1d9b55f2d73a1a9092f\n\n# tcId = 58\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004a394d8bf9b479ec3c7ac3fc6a631d01d57d338b9fb5a0ed6e5130e050cfc600cfb08e67727ac5a33345ec1d48d4a9a18516c2203acbd2667\nresult = valid\nshared = 8c1d0850691cda7523ffccf1cba44b4d472193e6a3bb0727e490a8b5\n\n# tcId = 59\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004642e26421e96fa88f956d098ac26f02f1d6faa80e460e701a3789a66c38dd95c6b33de8768c85cbe6879d0d77e29fe5a18b26a35cb60c0b6\nresult = valid\nshared = 50b9ed4d99e2f24e0096eaeded0b552cf8deff5ca8f976964ae47e92\n\n# tcId = 60\n# point with coordinate y = 1 in precomputation or right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004f974d1cbbf4171d4773c3e84eab80bc3c6c2858dadcfbd11d64316905df36fbe345f28a3ef663125649474c6fc1ebe175c3865c4469e192b\nresult = valid\nshared = 5616ee3e63dfb424d329c2b9b50cf378bb77a8bd7e314a241b5942c7\n\n# tcId = 61\n# point with coordinate y = 1 in right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a000455561db3cc8fb08a71654ee9573a1a36a44f0913ca8ad7582cfafbfc62b31e5e78be98ad8c8ceab4bb82e8efc0acb29f1a8d031ed044046c\nresult = valid\nshared = b1da14507b5c05159e15f77d085c017acd89f158011357a97802855d\n\n# tcId = 62\n# point with coordinate y = 1 in right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004a363bcb9bddd5de84a2f4433c039f7be3fce6057b0d3b4a3459e54a2ba32302871e7ba5c3dd7ec9b76946cdc702c15a8d9ec0f4a04e7afb6\nresult = valid\nshared = 2f1bd4a5a497481c4a21222320ff61f32674a95d540cc3f4f3ca5849\n\n# tcId = 63\n# point with coordinate y = 1 in right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a00043a656d0e25bce27282f256b121fbfcde0a180ccd7aa601a5929fc74002f89e45b4dcb873c56da5d1a28fbca33a126177b217a098e0952e62\nresult = valid\nshared = 8c807d65ba7b9fd3061dffef26c025a89524a26b942edd3a984fe51d\n\n# tcId = 64\n# point with coordinate y = 1 in right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004bf5f49ba0086eec289b068b783438ef24b6f28130bb1ed969ef8b041f11b0de95f15edcd835f01bab1f5faaa1749c2ca4f16a7d99d916ff4\nresult = valid\nshared = 8fda76f4d124e6727f855e5f4921cc05c48e2a8ed0fee7c75d6a8047\n\n# tcId = 65\n# point with coordinate y = 1 in right to left addition chain\nprivate = 00c1781d86cac2c0af3fb50d54c554a67bd75d25ca796f0486e3fa84f9\npublic = 304e301006072a8648ce3d020106052b81040021033a0004a57232560d9d604655181f775859b0723d4e", @@ -3116,9 +3754,9 @@ static const char *kData111[] = { "ed = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 312\n# wrong length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021033b000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 313\n# wrong length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b810400210339000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 314\n# uint32 overflow in length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3053301006072a8648ce3d020106052b810400210385010000003a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 315\n# uint64 overflow in length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3057301006072a8648ce3d020106052b81040021038901000000000000003a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 316\n# length of bit string = 2**31 - 1\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3052301006072a8648ce3d020106052b8104002103847fffffff000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 317\n# length of bit string = 2**32 - 1\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3052301006072a8648ce3d020106052b810400210384ffffffff000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 318\n# length of bit string = 2**40 - 1\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3053301006072a8648ce3d020106052b810400210385ffffffffff000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 319\n# length of bit string = 2**64 - 1\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3056301006072a8648ce3d020106052b810400210388ffffffffffffffff000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 320\n# incorrect length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b8104002103ff000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 321\n# lonely bit string tag\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3013301006072a8648ce3d020106052b8104002103\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 322\n# appending 0's to bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3050301006072a8648ce3d020106052b81040021033c000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da620000\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 323\n# prepending 0's to bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3050301006072a8648ce3d020106052b81040021033c0000000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 324\n# appending null value to bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3050301006072a8648ce3d020106052b81040021033c000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da620500\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 325\n# truncated length of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3014301006072a8648ce3d020106052b810400210381\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 326\n# Replacing bit string with NULL\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3014301006072a8648ce3d020106052b810400210500\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 327\n# changing tag value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021013a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 328\n# changing tag value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021023a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 329\n# changing tag value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021043a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 330\n# changing tag value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021053a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 331\n# changing tag value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021ff3a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 332\n# dropping value of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3014301006072a8648ce3d020106052b810400210300\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 333\n# modify first byte of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021033a020486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72f", "a4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 334\n# modify last byte of bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021033a000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3dae2\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 335\n# truncated bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304d301006072a8648ce3d020106052b810400210339000486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 336\n# truncated bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304d301006072a8648ce3d020106052b8104002103390486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 337\n# declaring bits as unused in bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021033a010486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 338\n# unused bits in bit string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3052301006072a8648ce3d020106052b81040021033e200486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da6201020304\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 339\n# unused bits in empty bit-string\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 3015301006072a8648ce3d020106052b81040021030103\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n# tcId = 340\n# 128 unused bits\nprivate = 00a1b9444f59642d428e2f299055004165a34c3b8796c5057ae8a1a572\npublic = 304e301006072a8648ce3d020106052b81040021033a800486e2f72bccd974a3f1a4fc2cdcf22043eaf8be047de6be726b62001fda6f50f6df0b51bee99195d8a1a1c97e59e72fa4fcf8c1d21cb3da62\nresult = acceptable\nshared = 85a70fc4dfc8509fb9ba1cfcf1879443e2ce176d794228029b10da63\nflags = InvalidAsn\n\n", }; -static const size_t kLen112 = 196857; +static const size_t kLen166 = 196857; -static const char *kData112[] = { +static const char *kData166[] = { "# Imported from Wycheproof's ecdh_secp256r1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDH\n# Generator version: 0.8r12\n\n[curve = secp256r1]\n[encoding = asn]\n\n# tcId = 1\n# normal case\nprivate = 0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000462d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf\nresult = valid\nshared = 53020d908b0219328b658b525f26780e3ae12bcd952bb25a93bc0895e1714285\n\n# tcId = 2\n# compressed public key\nprivate = 0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346\npublic = 3039301306072a8648ce3d020106082a8648ce3d0301070322000362d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26\nresult = acceptable\nshared = 53020d908b0219328b658b525f26780e3ae12bcd952bb25a93bc0895e1714285\nflags = CompressedPoint\n\n# tcId = 3\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000458fd4168a87795603e2b04390285bdca6e57de6027fe211dd9d25e2212d29e62080d36bd224d7405509295eed02a17150e03b314f96da37445b0d1d29377d12c\nresult = valid\nshared = 0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 4\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200040f6d20c04261ecc3e92846acad48dc8ec5ee35ae0883f0d2ea71216906ee1c47c042689a996dd12830ae459382e94aac56b717af2e2080215f9e41949b1f52be\nresult = valid\nshared = 00000000000000000000000000000000ffffffffffffffffffffffffffffffff\n\n# tcId = 5\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000400c7defeb1a16236738e9a1123ba621bc8e9a3f2485b3f8ffde7f9ce98f5a8a1cb338c3912b1792f60c2b06ec5231e2d84b0e596e9b76d419ce105ece3791dbc\nresult = valid\nshared = 0000000000000000ffffffffffffffff00000000000000010000000000000001\n\n# tcId = 6\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004e9b98fb2c0ac045f8c76125ffd99eb8a5157be1d7db3e85d655ec1d8210288cf218df24fd2c2746be59df41262ef3a97d986744b2836748a7486230a319ffec0\nresult = valid\nshared = 00000000ffffffff00000000ffffffff00000000ffffffff0000000100000000\n\n# tcId = 7\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004e9484e58f3331b66ffed6d90cb1c78065fa28cfba5c7dd4352013d3252ee4277bd7503b045a38b4b247b32c59593580f39e6abfa376c3dca20cf7f9cfb659e13\nresult = valid\nshared = 000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff\n\n# tcId = 8\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004767d7fbb84aa6a4db1079372644e42ecb2fec200c178822392cb8b950ffdd0c91c86853cafd09b52ba2f287f0ebaa26415a3cfabaf92c6a617a19988563d9dea\nresult = valid\nshared = 0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00010001\n\n# tcId = 9\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004c74d546f2fcc6dd392f85e5be167e358de908756b0c0bb01cb69d864ca083e1c93f959eece6e10ee11bd3934207d65ae28af68b092585a1509260eceb39b92ef\nresult = valid\nshared = 085ec5a4af40176b63189069aeffcb229c96d3e046e0283ed2f9dac21b15ad3c\n\n# tcId = 10\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000434fc9f1e7a094cd29598d1841fa9613dbe82313d633a51d63fb6eff074cc9b9a4ecfd9f258c5c4d4210b49751213a24c596982bd1d54e0445443f21ef15492a5\nresult = valid\nshared = 190c25f88ad9ae3a098e6cffe6fd0b1bea42114eb0cedd5868a45c5fe277dff3\n\n# tcId = 11\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004d5c96efd1907fd48de2ad715acf82eae5c6690fe3efe16a78d61c68d3bfd10df03eac816b9e7b776192a3f5075887c0e225617505833ca997cda32fd0f673c5e\nresult = valid\nshared = 507442007322aa895340cba4abc2d730bfd0b16c2c79a46815f8780d2c55a2dd\n\n# tcId = 12\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004f475f503a770df72c45aedfe42c008f59aa57e72b232f26600bdd0353957cb20bdb8f6405b4918050a3549f44c07a8eba820cdce4ece699888c638df66f54f7c\nresult = valid\nshared = 5f177bfe19baaaee597e68b6a87a519e805e9d28a70cb72fd40f0fe5a754ba45\n\n# tcId = 13\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004f3cb6754b7e2a86d064dfb9f903185aaa4c92b481c2c1a1ff276303bbc4183e49c318599b0984c3563df339311fe143a7d921ee75b755a52c6f804f897b809f7\nresult = valid\nshared = 7fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff\n\n# tcId = 14\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004cce13fbdc96a946dfb8c6d9ed762dbd1731630455689f57a437fee124dd54cecaef78026c653030cf2f314a67064236b0a354defebc5e90c94124e9bf5c4fc24\nresult = valid\nshared = 8000000000000000000000000000000000000000000000000000000000000004\n\n# tcId = 15\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047633dfd0ad06765097bc11bd5022b200df31f28c4ff0625421221ac7eeb6e6f4cb9c67693609ddd6f92343a5a1c635408240f4f8e27120c12554c7ff8c76e2fe\nresult = valid\nshared = 8000003ffffff0000007fffffe000000ffffffc000001ffffff8000004000000\n\n# tcId = 16\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004a386ace573f87558a68ead2a20088e3fe928bdae9e109446f93a078c15741f0421261e6db2bf12106e4c6bf85b9581b4c0302a526222f90abc5a549206b11011\nresult = valid\nshared = ff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff\n\n# tcId = 17\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200048e7b50f7d8c44d5d3496c43141a502f4a43f153d03ad43eda8e39597f1d477b8647f3da67969b7f989ff4addc393515af40c82085ce1f2ee195412c6f583774f\nresult = valid\nshared = ffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff\n\n# tcId = 18\n# edge case for shared secret\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004c827fb930fd51d926086191b502af83abb5f717debc8de29897a3934b2571ca05990c0597b0b7a2e42febd56b13235d1d408d76ed2c93b3facf514d902f6910a\nresult = valid\nshared = ffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff\n\n# tcId = 19\n# y-coordinate of the public key is small\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200043cbc1b31b43f17dc200dd70c2944c04c6cb1b082820c234a300b05b7763844c74fde0a4ef93887469793270eb2ff148287da9265b0334f9e2609aac16e8ad503\nresult = valid\nshared = 7fffffffffffffffffffffffeecf2230ffffffffffffffffffffffffffffffff\n\n# tcId = 20\n# y-coordinate of the public key is small\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200042830d96489ae24b79cad425056e82746f9e3f419ab9aa21ca1fbb11c7325e7d318abe66f575ee8a2f1c4a80e35260ae82ad7d6f661d15f06967930a585097ef7\nresult = valid\nshared = 000000000000000000000000111124f400000000000000000000000000000000\n\n# tcId = 21\n# y-coordinate of the public", " key is small\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004450b6b6e2097178e9d2850109518d28eb3b6ded2922a5452003bc2e4a4ec775c894e90f0df1b0e6cadb03b9de24f6a22d1bd0a4a58cd645c273cae1c619bfd61\nresult = valid\nshared = 000000000000000000000001ea77d449ffffffffffffffffffffffffffffffff\n\n# tcId = 22\n# y-coordinate of the public key is large\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200043cbc1b31b43f17dc200dd70c2944c04c6cb1b082820c234a300b05b7763844c7b021f5b006c778ba686cd8f14d00eb7d78256d9b4fccb061d9f6553e91752afc\nresult = valid\nshared = 7fffffffffffffffffffffffeecf2230ffffffffffffffffffffffffffffffff\n\n# tcId = 23\n# y-coordinate of the public key is large\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200042830d96489ae24b79cad425056e82746f9e3f419ab9aa21ca1fbb11c7325e7d3e754198fa8a1175e0e3b57f1cad9f517d528290a9e2ea0f96986cf5a7af68108\nresult = valid\nshared = 000000000000000000000000111124f400000000000000000000000000000000\n\n# tcId = 24\n# y-coordinate of the public key is large\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004450b6b6e2097178e9d2850109518d28eb3b6ded2922a5452003bc2e4a4ec775c76b16f0e20e4f194524fc4621db095dd2e42f5b6a7329ba3d8c351e39e64029e\nresult = valid\nshared = 000000000000000000000001ea77d449ffffffffffffffffffffffffffffffff\n\n# tcId = 25\n# y-coordinate of the public key has many trailing 1's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200049a0f0e3dd31417bbd9e298bc068ab6d5c36733af26ed67676f410c804b8b2ca1b02c82f3a61a376db795626e9400557112273a36cddb08caaa43953965454730\nresult = valid\nshared = 7fffffffffffffffffffffffca089011ffffffffffffffffffffffffffffffff\n\n# tcId = 26\n# y-coordinate of the public key has many trailing 1's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200048e5d22d5e53ec797c55ecd68a08a7c3361cd99ca7fad1a68ea802a6a4cb58a918ea7a07023ef67677024bd3841e187c64b30a30a3750eb2ee873fbe58fa1357b\nresult = valid\nshared = 0000000000000000000000001f6bd1e500000000000000000000000000000000\n\n# tcId = 27\n# y-coordinate of the public key has many trailing 1's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004293aa349b934ab2c839cf54b8a737df2304ef9b20fa494e31ad62b315dd6a53c118182b85ef466eb9a8e87f9661f7d017984c15ea82043f536d1ee6a6d95b509\nresult = valid\nshared = 000000000000000000000002099f55d5ffffffffffffffffffffffffffffffff\n\n# tcId = 28\n# y-coordinate of the public key has many trailing 0's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200049a0f0e3dd31417bbd9e298bc068ab6d5c36733af26ed67676f410c804b8b2ca14fd37d0b59e5c893486a9d916bffaa8eedd8c5ca3224f73555bc6ac69abab8cf\nresult = valid\nshared = 7fffffffffffffffffffffffca089011ffffffffffffffffffffffffffffffff\n\n# tcId = 29\n# y-coordinate of the public key has many trailing 0's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200048e5d22d5e53ec797c55ecd68a08a7c3361cd99ca7fad1a68ea802a6a4cb58a9171585f8edc1098998fdb42c7be1e7839b4cf5cf6c8af14d1178c041a705eca84\nresult = valid\nshared = 0000000000000000000000001f6bd1e500000000000000000000000000000000\n\n# tcId = 30\n# y-coordinate of the public key has many trailing 0's\nprivate = 0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004293aa349b934ab2c839cf54b8a737df2304ef9b20fa494e31ad62b315dd6a53cee7e7d46a10b99156571780699e082fe867b3ea257dfbc0ac92e1195926a4af6\nresult = valid\nshared = 000000000000000000000002099f55d5ffffffffffffffffffffffffffffffff\n\n# tcId = 31\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4\nresult = valid\nshared = cfe4077c8730b1c9384581d36bff5542bc417c9eff5c2afcb98cc8829b2ce848\n\n# tcId = 32\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000400000000000000000000000000000000ffffffffffffffffffffffffffffffff4f2b92b4c596a5a47f8b041d2dea6043021ac77b9a80b1343ac9d778f4f8f733\nresult = valid\nshared = 49ae50fe096a6cd26698b78356b2c8adf1f6a3490f14e364629f7a0639442509\n\n# tcId = 33\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000000000ffffffffffffffff0000000000000001000000000000000138120be6ab31edfa34768c4387d2f84fb4b0be8a9a985864a1575f4436bb37b0\nresult = valid\nshared = 5a1334572b2a711ead8b4653eb310cd8d9fd114399379a8f6b872e3b8fdda2d9\n\n# tcId = 34\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000400000000ffffffff00000000ffffffff00000000ffffffff0000000100000000462c0466e41802238d6c925ecbefc747cfe505ea196af9a2d11b62850fce946e\nresult = valid\nshared = c73755133b6b9b4b2a00631cbc7940ecbe6ec08f20448071422e3362f2556888\n\n# tcId = 35\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff1582fa32e2d4a89dfcfb3d0b149f667dba3329490f4d64ee2ad586c0c9e8c508\nresult = valid\nshared = 06fa1059935e47a9fd667e13f469614eb257cc9a7e3fc599bfb92780d59b146d\n\n# tcId = 36\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200040000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00010001684c8a9586ed6f9cbe447058a7da2108bab1e5e0a60d1f73e4e2e713f0a3dfe0\nresult = valid\nshared = f237df4c10bd3e357971bb2b16b293566b7e355bdc8141d6c92cabc682983c45\n\n# tcId = 37\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004085ec5a4af40176b63189069aeffcb229c96d3e046e0283ed2f9dac21b15ad3c7859f97cb6e203f46bf3438f61282325e94e681b60b5669788aeb0655bf19d38\nresult = valid\nshared = d874b55678d0a04d216c31b02f3ad1f30c92caaf168f34e3a743356d9276e993\n\n# tcId = 38\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004190c25f88ad9ae3a098e6cffe6fd0b1bea42114eb0cedd5868a45c5fe277dff321b8342ef077bc6724112403eaee5a15b4c31a71589f02ded09cd99cc5db9c83\nresult = valid\nshared = 11a8582057463fc76fda3ab8087eb0a420b0d601bb3134165a369646931e52a6\n\n# tcId = 39\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004507442007322aa895340cba4abc2d730bfd0b16c2c79a46815f8780d2c55a2dd4619d69f9940f51663aa12381bc7cf678bd1a72a49fbc11b0b69cb22d1af9f2d\nresult = valid\nshared = 4e173a80907f361fe5a5d335ba7685d5eba93e9dfc8d8fcdb1dcd2d2bde27507\n\n# tcId = 40\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200045f177bfe19baaaee597e68b6a87a519e805e9d28a70cb72fd40f0fe5a754ba4562ca1103f70a2006cd1f67f5f6a3580b29dc446abc90e0e910c1e05a9aa788cd\nresult = valid\nshared = 73220471ec8bad99a297db488a34a259f9bc891ffaf09922e6b5001f5df67018\n\n# tcId = 41\n# edge cases for ephemeral key\np", "rivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff2e2213caf03033e0fd0f7951154f6e6c3a9244a72faca65e9ce9eeb5c8e1cea9\nresult = valid\nshared = 55d0a203e22ffb523c8d2705060cee9d28308b51f184beefc518cff690bad346\n\n# tcId = 42\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d0301070342000480000000000000000000000000000000000000000000000000000000000000042be8789db81bb4870a9e60c5c18c80c83de464277281f1af1e640843a1a3148e\nresult = valid\nshared = 2518d846e577d95e9e7bc766cde7997cb887fb266d3a6cb598a839fd54aa2f4f\n\n# tcId = 43\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200048000003ffffff0000007fffffe000000ffffffc000001ffffff8000004000000722540f8a471c379083c600b58fde4d95c7dcad5095f4219fc5e9bdde3c5cd39\nresult = valid\nshared = bdb49f4bdf42ac64504e9ce677b3ec5c0a03828c5b3efad726005692d35c0f26\n\n# tcId = 44\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004ff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff5df80fc6cae26b6c1952fbd00ed174ee1209d069335f5b48588e29e80b9191ad\nresult = valid\nshared = f503ac65637e0f17cb4408961cb882c875e4c6ef7a548d2d52d8c2f681838c55\n\n# tcId = 45\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004ffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff2c63650e6a5d332e2987dd09a79008e8faabbd37e49cb016bfb92c8cd0f5da77\nresult = valid\nshared = e3c18e7d7377dc540bc45c08d389bdbe255fa80ca8faf1ef6b94d52049987d21\n\n# tcId = 46\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004ffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff7a116c964a4cd60668bf89cffe157714a3ce21b93b3ca607c8a5b93ac54ffc0a\nresult = valid\nshared = 516d6d329b095a7c7e93b4023d4d05020c1445ef1ddcb3347b3a27d7d7f57265\n\n# tcId = 47\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047fffffffffffffffffffffffeecf2230ffffffffffffffffffffffffffffffff00000001c7c30643abed0af0a49fe352cb483ff9b97dccdf427c658e8793240d\nresult = valid\nshared = 6fd26661851a8de3c6d06f834ef3acb8f2a5f9c136a985ffe10d5eeb51edcfa3\n\n# tcId = 48\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047fffffffffffffffffffffffeecf2230fffffffffffffffffffffffffffffffffffffffd383cf9bd5412f50f5b601cad34b7c00746823320bd839a71786cdbf2\nresult = valid\nshared = 6fd26661851a8de3c6d06f834ef3acb8f2a5f9c136a985ffe10d5eeb51edcfa3\n\n# tcId = 49\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047fffffffffffffffffffffffca089011ffffffffffffffffffffffffffffffff267bfdf8a61148decd80283732dd4c1095e4bb40b9658408208dc1147fffffff\nresult = valid\nshared = 44236c8b9505a19d48774a3903c0292759b0f826e6ac092ff898d87e53d353fc\n\n# tcId = 50\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200047fffffffffffffffffffffffca089011ffffffffffffffffffffffffffffffffd984020659eeb722327fd7c8cd22b3ef6a1b44c0469a7bf7df723eeb80000000\nresult = valid\nshared = 44236c8b9505a19d48774a3903c0292759b0f826e6ac092ff898d87e53d353fc\n\n# tcId = 51\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000000111124f4000000000000000000000000000000000000000d12d381b0760b1c50be8acf859385052c7f53cde67ce13759de3123a0\nresult = valid\nshared = f1f0e43b374feb7e7f96d4ffe7519fa8bb6c3cfd25f6f87dab2623d2a2d33851\n\n# tcId = 52\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000000111124f400000000000000000000000000000000fffffff1ed2c7e5089f4e3af4175307a6c7afad480ac3219831ec8a621cedc5f\nresult = valid\nshared = f1f0e43b374feb7e7f96d4ffe7519fa8bb6c3cfd25f6f87dab2623d2a2d33851\n\n# tcId = 53\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000000000000000001f6bd1e5000000000000000000000000000000004096edd6871c320cb8a9f4531751105c97b4c257811bbc32963eaf39ffffffff\nresult = valid\nshared = 3ebbace1098a81949d5605dd94a7aa88dc396c2c23e01a9c8cca5bb07bfbb6a1\n\n# tcId = 54\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000000000000000001f6bd1e500000000000000000000000000000000bf69122878e3cdf447560bace8aeefa3684b3da97ee443cd69c150c600000000\nresult = valid\nshared = 3ebbace1098a81949d5605dd94a7aa88dc396c2c23e01a9c8cca5bb07bfbb6a1\n\n# tcId = 55\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000001ea77d449ffffffffffffffffffffffffffffffff000000007afbc0b325e820646dec622fb558a51c342aa257f4b6a8ec5ddf144f\nresult = valid\nshared = 1b085213a9c89d353e1111af078c38c502b7b4771efba51f589b5be243417bdc\n\n# tcId = 56\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000001ea77d449fffffffffffffffffffffffffffffffffffffffe85043f4dda17df9b92139dd04aa75ae4cbd55da80b495713a220ebb0\nresult = valid\nshared = 1b085213a9c89d353e1111af078c38c502b7b4771efba51f589b5be243417bdc\n\n# tcId = 57\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000002099f55d5ffffffffffffffffffffffffffffffff152c1a22d823a27855ed03f8e2ab5038bb1df4d87e43865f2daf6948ffffffff\nresult = valid\nshared = 67cb63566c7ceb12fdd85ce9d2f77c359242bbaa0ea1bf3cf510a4a26591d1f1\n\n# tcId = 58\n# edge cases for ephemeral key\nprivate = 55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000002099f55d5ffffffffffffffffffffffffffffffffead3e5dc27dc5d88aa12fc071d54afc744e20b2881bc79a0d25096b700000000\nresult = valid\nshared = 67cb63566c7ceb12fdd85ce9d2f77c359242bbaa0ea1bf3cf510a4a26591d1f1\n\n# tcId = 59\n# point with coordinate x = 0\nprivate = 00e461c5b5e63d75b4c8c123bf8b9cd45e712af08f7e2e494a8f255ac9d80e058b\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4\nresult = valid\nshared = d11c640b4382e60ec8d254ee76f09b8fac57651ab73b6dd3fdc935a61564a3e9\n\n# tcId = 60\n# point with coordinate x = 0\nprivate = 00e461c5b5e63d75b4c8c123bf8b9cd45e712af08f7e2e494a8f255ac9d80e058b\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004100121f1a09443851c9aa2ab6ee6440e2ac5e1be648274bd5d26c12fb3ba3f7f032a1c219fa1457cb20588297e0513cfd4901f9a95414f7e914f9179f38567a6\nresult = valid\nshared = 90e712e2afd14171c19467a2bfe7abf1c477d1f40f6675f00e622fd5604fa16a\n\n# tcId = 61\n# point with coordinate x = 0\nprivate = 00e461c5b5e63d75b4c8c123bf8b9cd45e712af08f7e2e494a8f255ac9d80e058b\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703420004cad02ab537c80831ccdd395129fc4bfe4a89ae0c866f6619a3e1", @@ -3145,9 +3783,9 @@ static const char *kData112[] = { " = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 440\n# incorrect length of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703ff00042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 441\n# lonely bit string tag\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3016301306072a8648ce3d020106082a8648ce3d03010703\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 442\n# appending 0's to bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 305b301306072a8648ce3d020106082a8648ce3d030107034400042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b0000\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 443\n# prepending 0's to bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 305b301306072a8648ce3d020106082a8648ce3d0301070344000000042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 444\n# appending null value to bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 305b301306072a8648ce3d020106082a8648ce3d030107034400042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b0500\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 445\n# truncated length of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3017301306072a8648ce3d020106082a8648ce3d0301070381\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 446\n# Replacing bit string with NULL\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3017301306072a8648ce3d020106082a8648ce3d0301070500\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 447\n# changing tag value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107014200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 448\n# changing tag value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107024200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 449\n# changing tag value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107044200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 450\n# changing tag value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107054200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 451\n# changing tag value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107ff4200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 452\n# dropping value of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3017301306072a8648ce3d020106082a8648ce3d0301070300\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 453\n# modify first byte of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034202042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 454\n# modify last byte of bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034200042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add6eb\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 455\n# truncated bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3058301306072a8648ce3d020106082a8648ce3d030107034100042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add6\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 456\n# truncated bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3058301306072a8648ce3d020106082a8648ce3d0301070341042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 457\n# declaring bits as unused in bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d030107034201042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 458\n# unused bits in bit string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 305d301306072a8648ce3d020106082a8648ce3d030107034620042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b01020304\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 459\n# unused bits in empty bit-string\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3018301306072a8648ce3d020106082a8648ce3d030107030103\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n# tcId = 460\n# 128 unused bits\nprivate = 00c9551ffe53ce60d73cbf8af553d0cb5f7632ece499590182c28cb6db2e3978d2\npublic = 3059301306072a8648ce3d020106082a8648ce3d03010703", "4280042998705a9a71c783e1cf4397dbed9375a44e4cb88053594b0ea982203b6363b063d0af4971d1c3813db3c7799f9f9324cbe1b90054c81b510ff6297160add66b\nresult = acceptable\nshared = f0b6d851dcd8e9a8c474d695137962f082c4f2a1a2eefb182df58d88a72829e4\nflags = InvalidAsn\n\n", }; -static const size_t kLen113 = 236047; +static const size_t kLen167 = 236047; -static const char *kData113[] = { +static const char *kData167[] = { "# Imported from Wycheproof's ecdh_secp384r1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDH\n# Generator version: 0.8r12\n\n[curve = secp384r1]\n[encoding = asn]\n\n# tcId = 1\n# normal case\nprivate = 766e61425b2da9f846c09fc3564b93a6f8603b7392c785165bf20da948c49fd1fb1dee4edd64356b9f21c588b75dfd81\npublic = 3076301006072a8648ce3d020106052b8104002203620004790a6e059ef9a5940163183d4a7809135d29791643fc43a2f17ee8bf677ab84f791b64a6be15969ffa012dd9185d8796d9b954baa8a75e82df711b3b56eadff6b0f668c3b26b4b1aeb308a1fcc1c680d329a6705025f1c98a0b5e5bfcb163caa\nresult = valid\nshared = 6461defb95d996b24296f5a1832b34db05ed031114fbe7d98d098f93859866e4de1e229da71fef0c77fe49b249190135\n\n# tcId = 2\n# compressed public key\nprivate = 766e61425b2da9f846c09fc3564b93a6f8603b7392c785165bf20da948c49fd1fb1dee4edd64356b9f21c588b75dfd81\npublic = 3046301006072a8648ce3d020106052b8104002203320002790a6e059ef9a5940163183d4a7809135d29791643fc43a2f17ee8bf677ab84f791b64a6be15969ffa012dd9185d8796\nresult = acceptable\nshared = 6461defb95d996b24296f5a1832b34db05ed031114fbe7d98d098f93859866e4de1e229da71fef0c77fe49b249190135\nflags = CompressedPoint\n\n# tcId = 3\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004490e96d17f4c6ceccd45def408cea33e9704a5f1b01a3de2eaaa3409fd160d78d395d6b3b003d71fd1f590fad95bf1c9d8665efc2070d059aa847125c2f707435955535c7c5df6d6c079ec806dce6b6849d337140db7ca50616f9456de1323c4\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 4\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200040161328909675213e32098d35a6b8308a8d500cca39dcee5e804e73bdb8deaf06fe417291fd9793b231ef5fe86945444a97a01f3ae3a8310c4af49b592cb291ef70ee5bc7f5534d3c23dc9eefde2304842c7737ae937ccf9bd215c28103e9fe2\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 5\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004af4ae964e3bcbd923accda5da3175d411fd62d17dd3c3a1c410bef1730985a6265d90e950ac0fc50743b1ed771906ff33b68cf4d3d83a885a87097fdd329ce83b189f98cec5be44c31d1a3a2bba10f471963232b8ba7610fa8c72179050eb86d\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003\n\n# tcId = 6\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200041478ab6e032b9545eda9ac2c264e57a11f08acbc76d16a0ab77b04dbdaf20f215c4183437b32afc471eaa603d14c7c5d8a4c84ee0e895bec5c37f0a1ca075e106ff6bf38801b5c697409d39675231108d33c4a5ea65aaa8c03e939c95d96c4c4\nresult = valid\nshared = 0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff00000000000000010000000000000001\n\n# tcId = 7\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004f63208e34e7e90bb5fb036432467a89981444010663b8533b47bfa94bd2bc16f38aa516b930a4726e3876d3091bfb72ec783ed4da0cac06320817dc8bc64f59ccf06f48abc4386a150913fa95743a7b4601190e1c6ee8f8bf6354b254ecace45\nresult = valid\nshared = 00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff\n\n# tcId = 8\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004033271ef42d92ad47b273b09ea2f45401161baa52696590d0e175ff2d1c0dfa3fea40e4266d446546c05e480d57fabec7889f16a8bcc176602f6d46561614a2f4284abe697b7cb9ce79f7e2e71b155cb1f155ce925d16391a680eda23152e6e1\nresult = valid\nshared = 0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff\n\n# tcId = 9\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004737e8437e18683de2455b68945bba31daec3e754d72f0a0776d3192b2f9298bb95ca1464baa6687aabb679f804cf6ec6c2b4d47d61a60404df63b1e9ac0954b3419bbc2ad52a0409aeeb82f4703758588059165b20367dcb4b235b0caf71d727\nresult = valid\nshared = 007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0008000\n\n# tcId = 10\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b810400220362000437f9004983156bbd9c47891e75237bb13016bd7fe6f4e0f71cef0e63f16a672f0d3b0e20165c33407e146b6a4ae6962dd3b57ccb99e7aaf1303240516d0ebe08e585513e3695d42c467dcab5340ef761990cadc8d8840aacc944481415c07feb\nresult = valid\nshared = 3b5eed80727bcbc5113b8a9e4db1c81b1dddc2d99ff56d9c3c1054348913bde296311c4bd2fa899b4d0e66aaa1b6a0dd\n\n# tcId = 11\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200049655d8e5622718b317cfbc09894357f75a6b13fa516bcd6630721b869a620196cf0c3dec8860b32d27ed9bac2cf263af17321698116d7d811ae8da9b9cbbf9382c1e36e2b67d6c6af9bcea7d9de00ca72b398606c098a0a0f0c4b8941943ed65\nresult = valid\nshared = 6a99a5acd4a7edb1c707d7f8be12e81140338e3e14ba563c703c681a319a3f9ce1f90f032bf840f3758e89cb852ceca6\n\n# tcId = 12\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004ccb13d427b3c4bb33dd4f20cddabc68600eaf97eeb2c81e8c218ae90743e74ff38ca56f0c0224379db464dcf4a40f04350cd7a659b2c4851a5dcf8c990fc920c07d4d5aa50a2185750e6b84c42e83cff635050482decb4780f812e4c49fc7404\nresult = valid\nshared = 7c25a4f57f76ab13b25cab3c265db9d9bd925fecbf7bf93bef1308778646628decab067ed988a9755cd88e88de367104\n\n# tcId = 13\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200042664624307c02ef487030a632162c515f841d15ea3152d98ff2364232d7aab39343d5f703a4d5a31092aa7356c3a2f671c1cd603addfd8b5477552a3b32a18edaf3e33bec22ee2167f9da729636002a7974eaeb5ff082b2aabf8c7056b84c3ab\nresult = valid\nshared = 7fffffe000000ffffffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff8000004000002\n\n# tcId = 14\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004665f1f320b6ab1c1b52d144e52d87a154c2b4489838c9119de622c2d1b52b65b0a3955e44e0d4859175360c0f63dee813f14f69972f18caed7916c94a4d20ec344591e7536a4a7a4d8c9832818c96d60b1a81fabe64ea02c5f647e361bf5b60f\nresult = valid\nshared = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 15\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b810400220362000491357ca87dbb08e85d7b1acecfd1e086078a82d19f81474da389364a39fe2543eb934b440173c38e61a1d9407855b5d89ef0d9e920764b6d7765b084cf9541dacc43d1dabaa390b0fb856097b0c00a8556f4e3848568ab4ae790c3d346ca01b6\nresult = valid\nshared = fff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff\n\n# tcId = 16\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004d5a833bae33b2d10fdff6db7c54", "77adb614b191c70d97c6f130a14e93931cc1dc058053fee54a264a00fdd16d3166fdc42992276b79925bafcd183b03ed18235350980abfe67b814c6c11074c38f74cd4e734ad58cdb49d9fcd2181d1b8f1119\nresult = valid\nshared = fffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000004000000\n\n# tcId = 17\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b810400220362000467547cda7fbe8f16be5a4477cbb02979f1af72fc0f39302773552fbcf4667a8e23abc0e12856ee6234deeca5f22ae0503a4df7c068e7432417260cb9fe0d68b9c7fcf7e16a2ada05687d8f8900b84723103edbff0a42b27517da2760b7d38843\nresult = valid\nshared = ffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff\n\n# tcId = 18\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200041363e3b99008e09bb3f085949b9b6ea26a318f496de568a96630fdb9d4c72c2814df3087a1741f32f24989b428167f93c653cb3ae8c3ecfaec57efd54bb8ce9d79c7bf6cc70fb1114f939be8f1a99bf1e42b97431124ef9fa33450faa4e76839\nresult = valid\nshared = ffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff0000000000000100000000000001\n\n# tcId = 19\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004ba2be8d7147e2417c2ec80b24b4c1aa94464ffd0aae1fa2e078b3afbc77c144489ca9d064acbb7a9cfa6196d0f467b7e65ee1ca1eb1351ff9968f553dfe2e4c59ff8ba34c22a42b3baa13a9a1adc7f13abd40f1fd25d46bc5330852b9371966a\nresult = valid\nshared = ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff\n\n# tcId = 20\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004d69850ccbacc4736ea200ff2f8488f26247945a2ab48dd3708f494b293d8cba83417f48974881c7fb03854089bbf66cc1c773ec03cb8cd5f007ec3b03bdd05a409b352103f0decf25b41673ab8ca3d04334babee01219f15701f2bca22d40b37\nresult = valid\nshared = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe\n\n# tcId = 21\n# y-coordinate of the public key has many trailing 0's\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200046fcaf82d982d222d6096ba83e55b1c7dcb71a41e88f323333f44284d95c4bd3616da7a1bef928f31c26f885ba7adb487826fde2ed9f5649c11cf8465f8bf8ad50f68914936fc39666f68219d066506bea4001fdc816c9a90e7e2afb19bea085f\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000001f03123b00000000000000000000000000000000\n\n# tcId = 22\n# y-coordinate of the public key has many trailing 1's\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b81040022036200046fcaf82d982d222d6096ba83e55b1c7dcb71a41e88f323333f44284d95c4bd3616da7a1bef928f31c26f885ba7adb4877d9021d1260a9b63ee307b9a0740752af0976eb6c903c6999097de62f99af9405bffe0227e93656f181d504f6415f7a0\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000001f03123b00000000000000000000000000000000\n\n# tcId = 23\n# y-coordinate of the public key is small\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004bfeb47fb40a65878e6b642f40b8e15022ade9ecfa8cb618043063494e2bc5d2df10d36f37869b58ef12dcc35e3982835fd2e55ec41fdfe8cabbbb7bcd8163645a19e9dac59630f3fe93b208094ff87cd461b53cef53482e70e2e8ea87200cc3f\nresult = valid\nshared = 0000000000000000000000000000000000000000000000000000000036a2907c00000000000000000000000000000000\n\n# tcId = 24\n# y-coordinate of the public key is large\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75b14f5a6766da8035cc1943b15a8e4ebb6025f373be334080f22ab821a3535a6a7\npublic = 3076301006072a8648ce3d020106052b8104002203620004bfeb47fb40a65878e6b642f40b8e15022ade9ecfa8cb618043063494e2bc5d2df10d36f37869b58ef12dcc35e398283502d1aa13be0201735444484327e9c9ba5e616253a69cf0c016c4df7f6b007831b9e4ac300acb7d18f1d171588dff33c0\nresult = valid\nshared = 0000000000000000000000000000000000000000000000000000000036a2907c00000000000000000000000000000000\n\n# tcId = 25\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd215d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e\nresult = valid\nshared = 6092a1757ddd43a04e185ff9472a0d18c7f7a7dc802f7e059e0c69ae16c802651719406e04de27652ff83da4a780ef2f\n\n# tcId = 26\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002732152442fb6ee5c3e6ce1d920c059bc623563814d79042b903ce60f1d4487fccd450a86da03f3e6ed525d02017bfdb3\nresult = valid\nshared = 89c804cb81443386b185bcd9e2e6c35ee6177c3b90298985c4e81a89d520cceb17d729540e56ecc343c26bf314f2d052\n\n# tcId = 27\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036660041b1c7984620e8d7fd7ccdb50cc3ba816da14d41a4d8affaba8488867f0ca5a24f8d42dd7e44b530a27dc5b58da\nresult = valid\nshared = 35513157e804bd918d04de202778b81a6fc7ad8aa541ee94116a0f18466725d75e71c6942bf044b1b0ecba19db33e0de\n\n# tcId = 28\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000000000000000ffffffffffffffff0000000000000000ffffffffffffffff00000000000000010000000000000001141b9ee5310ea8170131b604484a6d677ed42576045b7143c026710ae92b277afbbea0c4458c220d561e69404dc7d888\nresult = valid\nshared = 102080c047881d19aefb01c29c82a4fb328a8ea6e6d6c914af73100507c8ee499799aaa646de0ea8c2727c0b5ed2439b\n\n# tcId = 29\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b810400220362000400000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff70370385413d3eff6fa3407ba24f682c2b01b51445dbdf5ef7b0dd0979f17e713e09081571f1e94dfb66bf282002f39f\nresult = valid\nshared = f689f6e475b4e15162521acab4637a3cdb9cb42aa92f9114b0ee300ddae89d5eafff3463a1f5004a2a1bd4aeffa47b78\n\n# tcId = 30\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff112e191f1f78bbc54b6cc4f0b1e59ae8c6ff1a07f5128e41dfa2828e1b6538d4fa2ca2394c6aab3449dcb3fc4eb44c09\nresult = valid\nshared = f3486244119b3632fd55be9e6951eb5d9c8c62f6a27042f94b924155ecfd4ff8744ba3d25bcf85a7b925bd28a12b897f\n\n# tcId = 31\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0008000028a4c8da5a05112fe6025ef41908969de20d05d9668e5c852ef2d492172ddc2a0a622fc488164fcc1a076b872942af2\nresult = valid\nshared = 8171b7c80d4c90bb58ae54393921ab9c5c0b3196f045e9fe5c8b168f0e5f6a77e1aa34ecedc5481ce55ab34c14", "e0f2e8\n\n# tcId = 32\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200043b5eed80727bcbc5113b8a9e4db1c81b1dddc2d99ff56d9c3c1054348913bde296311c4bd2fa899b4d0e66aaa1b6a0dd7b7f0f28d55e2f3a50f1f1bef3976834a05b43418e979303bc0363ed16d2d0b4011cc37b3c06ad73154faeab7915cd87\nresult = valid\nshared = 1fe6fea5f00d3005abaae2267ff18e430915838d87909ab503885edf38be7618ecb321f0a4df71b0913fbf12c76fc1f0\n\n# tcId = 33\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200046a99a5acd4a7edb1c707d7f8be12e81140338e3e14ba563c703c681a319a3f9ce1f90f032bf840f3758e89cb852ceca63cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd215d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e\nresult = valid\nshared = f58adc13ff997d38383910db7befb17670393a33d95b049c2aa19d760c8e728ecedd32168476b90b26a3742dcc121b07\n\n# tcId = 34\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200047c25a4f57f76ab13b25cab3c265db9d9bd925fecbf7bf93bef1308778646628decab067ed988a9755cd88e88de367104562ee0c57e71d96cefe31b4c4045bd4086a38e8ab9adf2d5567be318051d70f3aa68b753f271ab032b6abcce919e2962\nresult = valid\nshared = 56299684ec5ceb09ba4d94d1231005a826c9c08a5219c757e0136cbe8b6430badd4925172f2939891da7c7893850512f\n\n# tcId = 35\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200047fffffe000000ffffffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff80000040000024480ab33cb4bf7cb79c024eeade3fd641e2f3003698400e8986a7343a5da59a3b26eea4b4176e53239371437d834a1a7\nresult = valid\nshared = 1911a0ee6aebe263fdcf3db073f2598cdafabec2123a2f24a28c3d9151c871f32d6dc2f31d25af9c498fd68da23e5bef\n\n# tcId = 36\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020797da4c0751ced16de80d16ab7c654a5dc27d092626d0865a192a1c5ea7c1b88c9fcab057946741e41cc28c80ec0b9a\nresult = valid\nshared = 15900643e2e0583976974b05f83c7a96611425f7c4a6eb51916ab958a037fd9cc172bdcfff4540a2ff3ce64e6505557e\n\n# tcId = 37\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004fff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff6c70898ae6fb31fa2f086562af2d10486ba4c6fd5e41dfe4aa61598b4707a3bc276a62feb1b98557e3b17c025f7adf4e\nresult = valid\nshared = 88a544a769d5c34a051416bd509dfac911863f604c83ea844bf0e4c5c272dec86d057a88b152a9274701938c705900c3\n\n# tcId = 38\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004fffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff00000040000000eb1592858b6e6e3a199c0f3e7c5f0b4a92915936efb8bc0407680eb7274be7422156ce8cfc8b505b2d902c39992380f\nresult = valid\nshared = b7db26b286e7527cb1f454782fe541862ff0f8d7eed960e22855deb7ac2a69611668c777c53bb74c2bcd40edfbf7944d\n\n# tcId = 39\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004ffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff4987abae412809c2fa48fd23b1bdf9e622f5a606c44117215ffa61b18ef46e54a7fbbf11f9a6ba59c991b4ae501fedce\nresult = valid\nshared = b1e8aab1aa633d98dc6b768594e1e3edb801a9ef483f287c83e19744d2ad343ad3debdc4dc178213ad6876b52284f552\n\n# tcId = 40\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004ffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff00000000000001000000000000013691fe493d4d28bf8ee1dfec812d6c306eae0842919eda6dc525f0d49ac2d26a992251912139a2936849f9d6fa949a68\nresult = valid\nshared = b0de006f80f6f89e4eea6e46dfe305153005612d1e903171ec2886230971961b5202a9f3187bdac413ac24c836adf7a0\n\n# tcId = 41\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff615842aa06b06f78f0a66f7bea88d4b6ee59653eeaa00dc5e0a2b658f969b71af90c9b4e96bd3ca33846955bdccbd359\nresult = valid\nshared = ca8cfa42c5e374914c14d6402b1a99208e47e02ec49818913694ea0822a2cc6c310259a8f3ab7559b9974bc4c2fa337e\n\n# tcId = 42\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe732152442fb6ee5c3e6ce1d920c059bc623563814d79042b903ce60f1d4487fccd450a86da03f3e6ed525d02017bfdb3\nresult = valid\nshared = edf040bace18d90bf9ce720df2a3b31d76d95b7ed9530a159ac0b24e82a871033eada40552f9e606f7115e6a78927511\n\n# tcId = 43\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004000000000000000000000000000000000000000000000000000000001f03123b0000000000000000000000000000000071bd1e700c34075c3cade8ce29d33724af68a7672b265a4e157055360440ab7c461b8e9ac8024e63a8b9c17c00000000\nresult = valid\nshared = ea817dff44f1944a38444498f1b6c1a70a8b913aa326bc2acc5068805d8ddd7a5e41b8ee5b8371a1cf3f7a094258e3a6\n\n# tcId = 44\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b8104002203620004000000000000000000000000000000000000000000000000000000001f03123b000000000000000000000000000000008e42e18ff3cbf8a3c3521731d62cc8db50975898d4d9a5b1ea8faac9fbbf5482b9e4716437fdb19c57463e84ffffffff\nresult = valid\nshared = ea817dff44f1944a38444498f1b6c1a70a8b913aa326bc2acc5068805d8ddd7a5e41b8ee5b8371a1cf3f7a094258e3a6\n\n# tcId = 45\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000000000000000000000000000000000000000000000000000000036a2907c00000000000000000000000000000000000000007f57b69a014783dbfa4967b2f9cfa678a6f0b6e9cfd41648cec5b3c498e72152da3f82d3da2e8e9f8ef37b11\nresult = valid\nshared = bfa93e184f76279fd707d53ddcb3628855cfafb111bcbd0b4df6ef77aee624924d681626a153fa4e59c923b71fc090b3\n\n# tcId = 46\n# edge cases for ephemeral key\nprivate = 2bc15cf3981eab6102c39f9a925aa1309db59c2c02a54411928d73c3945d157848dc36959efef7495c8528ea284c1c97\npublic = 3076301006072a8648ce3d020106052b81040022036200040000000000000000000000000000000000000000000000000000000036a2907c00000000000000000000000000000000ffffffff80a84965feb87c2405b6984d06305987590f4916302be9b7313a4c3a6718deac25c07d2c25d17161710c84ee\nresult = valid\nshared = bfa93e184f76279fd707d53ddcb3628855cfafb111bcbd0b4df6ef77aee624924d681626a153fa4e59c923b71fc090b3\n\n# tcId = 47\n# edge case for Jacobian and projective coordinates\nprivate = 00938f3dbe37135cd8c8c04182952f6e6f9bfe7a4cff4eacf90612a48865dc43e9b5d230f761d1fc4dfb69be20e84ccc8f\npublic = 3076301006072a8648ce3d020106052b8104002203620004fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe732152442fb6ee5c3e6ce1d920c0", @@ -3178,9 +3816,9 @@ static const char *kData113[] = { "ublic = 3076301006072a8648ce3d020106052b8104002203630004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 400\n# wrong length of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203610004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 401\n# uint32 overflow in length of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307b301006072a8648ce3d020106052b81040022038501000000620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 402\n# uint64 overflow in length of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307f301006072a8648ce3d020106052b8104002203890100000000000000620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 403\n# length of bit string = 2**31 - 1\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307a301006072a8648ce3d020106052b8104002203847fffffff0004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 404\n# length of bit string = 2**32 - 1\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307a301006072a8648ce3d020106052b810400220384ffffffff0004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 405\n# length of bit string = 2**40 - 1\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307b301006072a8648ce3d020106052b810400220385ffffffffff0004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 406\n# length of bit string = 2**64 - 1\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307e301006072a8648ce3d020106052b810400220388ffffffffffffffff0004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 407\n# incorrect length of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203ff0004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 408\n# lonely bit string tag\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3013301006072a8648ce3d020106052b8104002203\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 409\n# appending 0's to bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3078301006072a8648ce3d020106052b8104002203640004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed0312510000\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 410\n# prepending 0's to bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3078301006072a8648ce3d020106052b81040022036400000004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 411\n# appending null value to bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3078301006072a8648ce3d020106052b8104002203640004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed0312510500\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 412\n# truncated length of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3014301006072a8648ce3d020106052b810400220381\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 413\n# Replacing bit string with NULL\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3014301006072a8648ce3d020106052b810400220500\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 414\n# changing tag value of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002201620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 415\n# changing tag value of bit string\nprivate ", "= 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002202620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 416\n# changing tag value of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002204620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 417\n# changing tag value of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002205620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 418\n# changing tag value of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b81040022ff620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 419\n# dropping value of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3014301006072a8648ce3d020106052b810400220300\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 420\n# modify first byte of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203620204c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 421\n# modify last byte of bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203620004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed0312d1\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 422\n# truncated bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3075301006072a8648ce3d020106052b8104002203610004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed0312\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 423\n# truncated bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3075301006072a8648ce3d020106052b81040022036104c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 424\n# declaring bits as unused in bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203620104c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 425\n# unused bits in bit string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 307a301006072a8648ce3d020106052b8104002203662004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed03125101020304\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 426\n# unused bits in empty bit-string\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3015301006072a8648ce3d020106052b81040022030103\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n# tcId = 427\n# 128 unused bits\nprivate = 4b065d2dbbad95d7eebed00a3e79f772ccddfd93101c1b1f393e8adc465d94bc21346d8f341907a3c27a2562dcb49a3a\npublic = 3076301006072a8648ce3d020106052b8104002203628004c2bed48c5e15e8208411b1a14c77c440b9a8c3b6b2af6eef05e4fbae13cfe7ba5e9af208c54e3035e3b4559f97b0f2798dbe522a47ee950419b5faa273d24ff2748a8349c591cc80871acf3c6702cce129c68351a713207a69f02b5bed031251\nresult = acceptable\nshared = 40c344fb1185a5a97dd00b114f1b9c5ce4009f90c593f236fe465518f9ff27326a421e05b5bc1bfe3768d5becb9ec797\nflags = InvalidAsn\n\n", }; -static const size_t kLen114 = 333824; +static const size_t kLen168 = 333824; -static const char *kData114[] = { +static const char *kData168[] = { "# Imported from Wycheproof's ecdh_secp521r1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDH\n# Generator version: 0.8r12\n\n[curve = secp521r1]\n[encoding = asn]\n\n# tcId = 1\n# normal case\nprivate = 01939982b529596ce77a94bc6efd03e92c21a849eb4f87b8f619d506efc9bb22e7c61640c90d598f795b64566dc6df43992ae34a1341d458574440a7371f611c7dcd\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040064da3e94733db536a74a0d8a5cb2265a31c54a1da6529a198377fbd38575d9d79769ca2bdf2d4c972642926d444891a652e7f492337251adf1613cf3077999b5ce00e04ad19cf9fd4722b0c824c069f70c3c0e7ebc5288940dfa92422152ae4a4f79183ced375afb54db1409ddf338b85bb6dbfc5950163346bb63a90a70c5aba098f7\nresult = valid\nshared = 01f1e410f2c6262bce6879a3f46dfb7dd11d30eeee9ab49852102e1892201dd10f27266c2cf7cbccc7f6885099043dad80ff57f0df96acf283fb090de53df95f7d87\n\n# tcId = 2\n# compressed public key\nprivate = 01939982b529596ce77a94bc6efd03e92c21a849eb4f87b8f619d506efc9bb22e7c61640c90d598f795b64566dc6df43992ae34a1341d458574440a7371f611c7dcd\npublic = 3058301006072a8648ce3d020106052b81040023034400030064da3e94733db536a74a0d8a5cb2265a31c54a1da6529a198377fbd38575d9d79769ca2bdf2d4c972642926d444891a652e7f492337251adf1613cf3077999b5ce\nresult = acceptable\nshared = 01f1e410f2c6262bce6879a3f46dfb7dd11d30eeee9ab49852102e1892201dd10f27266c2cf7cbccc7f6885099043dad80ff57f0df96acf283fb090de53df95f7d87\nflags = CompressedPoint\n\n# tcId = 3\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004014c643329691ba27459a40dfe7c4ce17b3ea14d0cd7aa47b01f1315404db51436fbbfe6de0842e0f7e1265f6ff3aca28750677d3370b2fb2a6ef497356f4b95811201051b14178639a09a41465c72d3743436ee1c191ff7388a40140b34d5317de5911ea03cdbb0329fdeb446695a3b92d437271a9f3c318b02dec4d473908158140e97\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 4\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040029cd32125c23a41af24fd4b729da0faacbc35516ef0ba59096602571693cd282e26d67e18ef4643d0f6f158d7370d3394ca9a8de7938032ac178c6fd34e3702b8d008649834e2b41be3a8b7510bfe570f4c67075943cd0cbb9d9e1d1da52618b5b96d6aec9b650daf1ca6624c13e5116302b9c79c8c4d3d351915d1e8e1ab6ad76098e\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 5\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040032c6f06ce6a15ea064464d35aa368d299c9a9e1e368f694aefb603876248f898f223ce0217bef37d61eb09b27c93187cf8e61ba7b14e3c9bee692b06ac6d95f836019fd19f8480e21c63211d48d45f96f6365cf55f958e1a0fe7ea6b6b9ff230a87b70bb1b14d3a5fb6669a91641c6acf4570c1d3a9e709913b7fe6b35ff81c394d6a7\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 6\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401f7eb96e64b1a62daf9e0801bfd96a0b15b68e5f5cb3e90b434495a473907338e53098e1c2e493335d09c6aae6fdda0345b98aaed588f2abe82910713fb6c20252901396b17cf250bc018f4cead097e7e09863f14cf1239b065e57d884949eee141926f7e7c9f7f34cf0536368767bc0e1ab5142877293a4c722693a73fe14a5390af93\nresult = valid\nshared = 000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 7\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004006ddf9b10965d5fc129e96f7a37667ccf66cc44384772906fedb21f9de4629e01aaa09ac7c9866112064bbc9bd58ebc123ab2fe19d8fed1a056d27bfef0630509c7001c441311ef20a16346332ea42d5c65788d68f6817b0267fcab11ea9c948ed108115dda8e823a380b601460742d3772d6424c67b240da24772ff0d2ccd9a1e0cea6\nresult = valid\nshared = 000000ffffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff0000000000000100000000000000\n\n# tcId = 8\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004007a8c547268c948b626da636cf54428ea2ab23861d499a84ad7be1cf691b92872a06e26c6dba08ca9ed386f83d396156d5fa023f57d5ea6440ec7401dad2c08ad70018c3815b1b9a2e42555419a6c19043fa2b0ddcc4b5a6e372fee9fcb227d85bad704687e7e1a818b612d5c046cd75972f7a2dd5c9a200ac5582cd59fec47ac525ecf\nresult = valid\nshared = 00003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff\n\n# tcId = 9\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040029153cf062f88f303e5d6f9aac968bd901076d5994ea7f831833b1e69b67e9e9fe20cf9c5623e00e0b9e3592fca2a03324b5df7c93186aff697aca864600d44ecc002801a62e2f4106f34106da23dc93d50e3e975a1d47510021835290649b7a4125109f656b6b0b5bd00b24d84ea1ba4e1ed49e61c526fb1011005131caee7ee0501e\nresult = valid\nshared = 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 10\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b81040023038186000400a61eb994e28722c59b3c6007dfdf8b37893f6350f461b26a00e1a45104314aae9989da87e4facb2c4ef721185b7d96d9a45a28a102756501a1acc5d329a21bbf73010e8d0e12f5a9a40e0d59c90ce73043d39730aeadd3788e31d7c2bb62a1166161994664afa658ce2e60a13f45f27f914307c8d6f8d4ed16ab041b8f69908a62782f\nresult = valid\nshared = 010000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff\n\n# tcId = 11\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004011dd497b30c73709906b164a9a79dc7f2a98c0148ed63016bb95243834fbcdf8eb74b0ff652d54f59f31aef51da6e8974d363655b1da138dc4de0f2a8d800f475ae0057bd4b84607400d863ffbf45a3cf58999ee24ba05e93eca7b0e4ae760eb1733559a45d15579d3370d716ffa3ec4bfdae418e32fb06138dfca213720a938577610e\nresult = valid\nshared = 01ff00000000000000000000000000000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000100000000000000000000000000000000\n\n# tcId = 12\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401283eb93fa369fe7012b647d21e0a97cf9950e5fbed819ef56158f20c8a9473a418eccbca4dc2b47f4cb6d322f917005859bf221e84ac9827cab82a801c627fb1ec0075c480cbafb352fcaf93baf23a1405fd81febe09729a908d1077e177dd8993d94b251a0d52652da3edb6fdf864e80cd51540e73d0b5107e3433576dcaa4e18db43\nresult = valid\nshared = 01ff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff\n\n# tcId = 13\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6", "b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b81040023038186000400173beefe35ee868d497ff6601628f65ce18a1591f7e4a3a406622f3f508e2da68f101ed02febc38418c6ddfc26a5ec9848c42792463b1e945f9e167db34bdf2d660053070647aba7cd60eb295ab81a268a3903f393c5d28bbc5e022351c377cd84f02c19deb36442372cae1332e92f95ba60b6c852e0de0718e89d24e43cd479c9fb11\nresult = valid\nshared = 01ff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff\n\n# tcId = 14\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004009829cd5432687739ab6ae10af8ea73d2cb53b81ebb06b5961b7badc1676b3ef7b00454f7cde56774a01312d574a9193c1a5fe5336fbe62623ad9bf81143789f9f90012f955697ed578207197bf9aac3896521615dbacc8dc665d4f1715b08439f49c2aa6ed337023ffccc5075a85944936826db92f919737ca3afeadba1847084bdef7\nresult = valid\nshared = 01ff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00010000\n\n# tcId = 15\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040126e3c959cd41120bb83693b1d6a034b385137c1bb3213b776122fed96056e329885718a73bee639c0ba4b68818682f498ce5496925002bd7652516405fcc4fecad0073a9c6e3b0c694bf7cc8ccbbd09800e81e3548ba44a0c2381cef0b07bf702a19054bb5d717a1b79294609cbdafd4e2018064f7b2c4c204d818eb7ce521c3268ce5\nresult = valid\nshared = 01ffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff8000004000001\n\n# tcId = 16\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040153dc481ab3c5dc8decd24ceaee1bec77f59f21f7f31c19538af047d281ac9e2567933fd3d21096b185d4098919571931bb9b0be7197995e2fbaf21c8a10007ade001ad69f08fcae164390be826256b50fae47502ce0e9ca46af0c490cb4033c886f88661a99ff2bd3c9c8e7da30faf2b4c769edc5831810ac05054c97e41063f496e1f\nresult = valid\nshared = 01ffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff\n\n# tcId = 17\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401f586611c87150288c3e86116c5db94a26718978829d701ddac05e9b0ce22dee4b18e95f60cba783ed3384da373deaefc57b8265d3a34eeb458bf24b9d82be32819008456e0f1d80492ef0078cc246d32fc7c7fb6720b4d458b51b2098d35746752b0ef0345bd0d342dfee6dd2f12ed12b34bd95d058c2811fd479d2dde32180e6c9ef2\nresult = valid\nshared = 01ffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc000000080000002\n\n# tcId = 18\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b810400230381860004015edc87fd499a73eabffd14d2b6a70a8fb69b6a39d0d9c4dda2337b53cc72e49a9e3d5a2d9e8930cfa11852dac33443227fba6684bd74732e6879884b6ef9dae98f010eeb8d2e3360ea9726628085268af3f2a05ad41235d0a892098bd661b636f7ef0a820282906eda3f1ff1980b98fb5937228e9edcd6332e3641216c7307e7f3f452\nresult = valid\nshared = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n\n# tcId = 19\n# edge case for shared secret\nprivate = 00a2b6442a37f8a3759d2cb91df5eca75af6b89e27baf2f6cbf971dee5058ffa9d8dac805c7bc72f3718489d6a9cb2787af8c93a17ddeb1a19211ab23604d47b7646\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040131b43002f7e687eec1ecf6a253c2ccc9e48f04d86fccd18fee0d2d22191f1ea539c40d521970b4709dc03986f647e0e8bb3340cf8a3e643a3541035437cf25f01500b27a55ac45f0296f8c9656bcfd52b5cea9f4115c06e4c64319609847d45e92418400e7868672c0d3e6e5e6e004a7190476ed77cfc33ad19a4bd2c615ad9950f374\nresult = valid\nshared = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n\n# tcId = 20\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d20ec9fea6b577c10d26ca1bb446f40b299e648b1ad508aad068896fee3f8e614bc63054d5772bf01a65d412e0bcaa8e965d2f5d332d7f39f846d440ae001f4f87\nresult = valid\nshared = 0053bf137fee8922769f8d0fe279caa4dac9c6054ad0460995588a845d0a959e24bc0fc2391a2b92f7bd400f50a11a9db37f07bef7fa8dad2a903fcf534abc8736f7\n\n# tcId = 21\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b8104002303818600040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010010e59be93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec636ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564\nresult = valid\nshared = 01c95ac417c90a520149b29105cdab36f528a23efb5621520dbdafea95a7d43499c4c8be02cd1c2de000da18104fa84a1e9ece6386f0e0efa5234a24595d7c4c96f4\n\n# tcId = 22\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200d9254fdf800496acb33790b103c5ee9fac12832fe546c632225b0f7fce3da4574b1a879b623d722fa8fc34d5fc2a8731aad691a9a8bb8b554c95a051d6aa505acf\nresult = valid\nshared = 01b47ec41e3a5abd9dd9808fc04d9078cbed72b9eba98d3c1ded70a29938f0efd5a27a7113ff721f122cb17411de307a355c685074f5766b6d1a033d2fa188c945b6\n\n# tcId = 23\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b810400230381860004000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000005f880f50ec94bfac6658fa2fce05945c6a36b266407b6fbd5437a83e2f2f9b9c50a734872e48e70df65457f13e47d06c6b8b29f4735acf105ea63e051904d18aea\nresult = valid\nshared = 013aefe3245728a08c904fe7d61cd9c2fdac63f29cf664d8f161bebacb93f8a710e9692f9689480ad498de00f00061e40e46e76e4754c1130ef4217a58933e0b1dc6\n\n# tcId = 24\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b810400230381860004000000ffffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff00000000000000ffffffffffffff000000000000010000000000000000f33ffc45da3eac1baab727ab8fd355cfa134c42047d55262651654fb50df7e9a5a75f179c8c86c4388213b5687dc43dfebb37f30128703c44ccd5c3284833b8717\nresult = valid\nshared = 0168df272d53e3161926168c4aeab5f355b8d2a6689cfd567f2b6eb2011a18c775ac2a21f8dd497f6957217020b3b1afcb7021f24fccc2523be76a2bff44596e5a14\n\n# tcId = 25\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b810400230381860004", "00003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00000003fffffff00cd2839d857b4699f5c8e8a0194786e26a862f086b4ba80746ae5225ed3aa68f96b7aaec55225830bb98f52d75221141897ba49d7a31ebbf0b6d7d31352e5266190\nresult = valid\nshared = 013db1b9241b23d33860d32dec37a79e4546a41afdfdd9c438d04e1f8b566ac8d9d3f572c293e96943722a4ee290e113fffaa82a61867d9ca28d349982354c9b256f\n\n# tcId = 26\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b810400230381860004010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000813d9829119f42ffa95fea8ba9e81e4cd6a6ca97fb0778e12e5f5dfe35201dd4cca8eca0d2e395555997041381e6ac1f18ddf4c74e0b6e9041cfdca1d1c103091\nresult = valid\nshared = 01d2bbe9f754584ebbc7c7ad74136d1c8a144948948aa8be49989dd9b4c514db2e2ab1e0713ad1699f632dd2cea53da218ed549f030a113e282fd9e3be462d9aba84\n\n# tcId = 27\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b810400230381860004010000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff0000003ffffff00878ad597d290db2cf660594aeed0f9b7c8dd68451d2d1b2cbc816b1ec4f35465b3964aff2edf1255163f5fca580132f85cade2887a017e7cd0b37196ad85221107\nresult = valid\nshared = 000f37a2e2caef54fff4126c0fa96e7c47f0cad74626ef91e589e12d2e1e8c221be7295be9dc2712b87bb0aa0f5880b738bc1242f2ba773bf9eb2a54e3c1ca4758d7\n\n# tcId = 28\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ff00000000000000000000000000000000ffffffffffffffffffffffffffffffff000000000000000000000000000000010000000000000000000000000000000000b5e1191b449fa1ebdbd677daa48f90e2d1d6c058c877087cafd9364d99dbb283c68402e6e6c5f5411b2ed42824d8b280ceb910aba6847883a7e3780e2132af41c1\nresult = valid\nshared = 017aeb254d9c8c8ee06215ff33811357da73bf7f6dd6d7f8f176d62c065a88a9005f680c630e9f2763585ea2ee76b6e4ab45e673f814ebfa95947c0c63fb24fa6e9b\n\n# tcId = 29\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff00207513d615656a1cc7505c18aa21b08e2b1d5a841de0816cc29c004efdb2d902ac1a7bb05e20722b576b64a3ddf4d2486421ac706bf4a424f252386368a5340fb6\nresult = valid\nshared = 0061bed42248a37b4625ef04c4f9c7ef69ee3c6f9503378351fcab1b8ce1343206997eec1b88449eb6f7355711ea1a818a486ee30a24126241a7e2289267cf5dd61f\n\n# tcId = 30\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff001fe800c50e54012b75a33e4be7d07c8d60f29680a395e951a6a31c5096b0ea928fc2cbf327dd784dc0a7ca46ea73992b758b5641364b4aba39e93798a4d925a008\nresult = valid\nshared = 001067d9104e296ef42b944587de11b10df05d2d959ed44cac9e7ef1c7a05d90819c43bc79c7397918f957cc98db931763bbeb1bdfc35865e8a359a013f13d60c433\n\n# tcId = 31\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00010000008dd18a1f5e482140be79bb65a21ad60c8987e532c84345f0135affd46ec71ef02b1ca3ad56f301d955fa306c122d441d6fedcf8b855ef256350bf69d23a7207ad9\nresult = valid\nshared = 00b779d83035cf7bb0bb04c7b2f46d08f6791f0d1542c9bcce7250e772b12ad8e38fce1d2b063a06f0fa3a1b072dd976f5f8542979903075162f1f5c6ba3b76cc45d\n\n# tcId = 32\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff8000003ffffff0000007fffffe000000ffffffc000001ffffff800000400000100566203dd325a081c4441f001f780365874fd3d0c9bc47227481afe76a93ae1bfde63af972203abfe22c63b80e83f7cc2184c3cb8cfd0152c54324c4759fd1f9a50\nresult = valid\nshared = 01afe5d23733728b79c743933b9ba7dfec5ed19b7737e393908a1d000918aa795d1ce0ad533983d018f927b35d2af6463356573f387febd75911a49486202ca69d3a\n\n# tcId = 33\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff0001fffc0007fff00b11c668fbd549f36889f7b63434051da26f15705839136b1b14a09152d7a182ea7806c35478a32d3aa3c9c1627a61519ebec71b36fa77449025b8829e27f307834\nresult = valid\nshared = 019612aeb386febb1a28096fe5b2f682dead02389785225b80a27df439510d08349a193839525f248b7f9bcabfd3dc8da8cc1724022299b7b5e72399d89464b82e44\n\n# tcId = 34\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401ffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc00000007fffffff00000001fffffffc00000008000000200aa75efc0a8daac1d73f32c9c552414bccf44af8e74331b47439e7dcc49a135b3ee61e9f69717d89b4bba3567a195aeda13fbec634bf2984b5ec6b6f80f5978ed5a\nresult = valid\nshared = 00570673f87adcef49c1f011e8b9f1e11f7fd3b3c93114d08d3f515aa4a895a6c701c523063bdc13ad1db0a54f6e7b476fe10db2070441befc58c8cff3c08ef76e59\n\n# tcId = 35\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0010e59be93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec636ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564\nresult = valid\nshared = 0016aaf228b0aec190d4e4e5b8138ff9cc46d705da1bf002901c6ab420f59314d5b641712b14ef3e4fb125652c47888676804fb5575b741a8408c5625bfccff4fdda\n\n# tcId = 36\n# edge cases for ephemeral key\nprivate = 012bc15cf3981eab6102c39f9a925aa130763d01ed6edaf14306eb0a14dd75dff504070def7b88d8b165082f69992de0ffa5ee922cb3ab39917da8524cac73f0a09c\npublic = 30819b301006072a8648ce3d020106052b81040023038186000401fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00d9254fdf800496acb33790b103c5ee9fac12832fe546c632225b0f7fce3da4574b1a879b623d722fa8fc34d5fc2a8731aad691a9a8bb8b554c95a051d6aa505acf\nresult = valid\nshared = 00a5d6dfda2b269f4ab895a41c3b71b6ba10d5c9f0d9b3e730275345e4721594abfd39464c227716ded8ef3e60bb1ca0b551716e3f6eebb48d5ce8e0ab58cb1b73c9\n\n# tcId = 37\n# edge case for Jacobian and projective coordinates\nprivate = 018f3dbe37135cd8c8c04182952f6e6f9bfdbb6af4c98f31ba30abc68d88e1ea980d4edcdb5b19f0610082194137ebb019e7a664b522189a186cbe5a03376c0713fb\npublic = 30819b301006072a8648ce3d020106052b81040023038186000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -3223,9 +3861,9 @@ static const char *kData114[] = { "4a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 459\n# length of bit string = 2**64 - 1\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3081a2301006072a8648ce3d020106052b810400230388ffffffffffffffff0004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 460\n# incorrect length of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819a301006072a8648ce3d020106052b8104002303ff0004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 461\n# lonely bit string tag\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3013301006072a8648ce3d020106052b8104002303\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 462\n# appending 0's to bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819d301006072a8648ce3d020106052b810400230381880004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d500000\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 463\n# prepending 0's to bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819d301006072a8648ce3d020106052b8104002303818800000004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 464\n# appending null value to bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819d301006072a8648ce3d020106052b810400230381880004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d500500\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 465\n# truncated length of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3014301006072a8648ce3d020106052b810400230381\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 466\n# Replacing bit string with NULL\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3014301006072a8648ce3d020106052b810400230500\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 467\n# changing tag value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230181860004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 468\n# changing tag value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230281860004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 469\n# changing tag value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230481860004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 470\n# changing tag value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230581860004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 471\n# changing tag value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b81040023ff81860004017ee1", "6985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 472\n# dropping value of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3014301006072a8648ce3d020106052b810400230300\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 473\n# modify first byte of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230381860204017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 474\n# modify last byte of bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230381860004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32dd0\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 475\n# truncated bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819a301006072a8648ce3d020106052b810400230381850004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 476\n# truncated bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819a301006072a8648ce3d020106052b8104002303818504017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 477\n# declaring bits as unused in bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230381860104017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 478\n# unused bits in bit string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819f301006072a8648ce3d020106052b8104002303818a2004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d5001020304\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 479\n# unused bits in empty bit-string\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 3015301006072a8648ce3d020106052b81040023030103\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n# tcId = 480\n# 128 unused bits\nprivate = 018c3c384368133e46c99ad2421ff44eed459b5d209cb2aa70b09bd7d38cc6225164a9815dff6d69afbf49f80da22f6ea33454b6544b69b3330008c6a22259f9f9e5\npublic = 30819b301006072a8648ce3d020106052b810400230381868004017ee16985c3678234d272913682a7c122b35c1c5011d1933bb7b08c8b883afcf469453079e2ef02a724a6ddbe25ee3b2e63007dd2838c5bb00fa1ff8fd18cf81eaa01116ce049d63f22f71c7d11c0acd67cacd1b4ea0125bd48e872dc5cc9fc4073b7c844c4b42223483b4aa8402b198d981dc8b7aba048749b4a0496e2537d3cc32d50\nresult = acceptable\nshared = 00d397252813d37329b9e277823e2dfccdd1ee519f0c32ccbb3f5fc62062e8c07dbf3fb86085736115b70f86f44ad852f3488ecbb5e7ec31e961e869b40b6add05f5\nflags = InvalidAsn\n\n", }; -static const size_t kLen115 = 112343; +static const size_t kLen169 = 112343; -static const char *kData115[] = { +static const char *kData169[] = { "# Imported from Wycheproof's ecdsa_secp224r1_sha224_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[key.wx = 00eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7]\n[key.wy = 00eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[sha = SHA-224]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 303c021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021c2840bf24f6f66be287066b7cbf38788e1b7770b18fd1aa6a26d7c6dc\n\n# tcId = 2\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 303c021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021cd7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = MissingZero\n\n# tcId = 3\n# valid\nmsg = 313233343030\nresult = valid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 4\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30813d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 5\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082003d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 8\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000003d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 9\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000003d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 10\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 11\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 12\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 13\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 14\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303d028070049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a028000d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 18\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 19\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 20\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 21\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f0000021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 22\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 23\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610500\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3042498177303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30412500303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 303f303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610004deadbeef\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30422221498177021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304122202500021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3045221e021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0004deadbeef021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3042021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a2222498177021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3041021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a22212500021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3045021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a221f021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610004deadbeef\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3045aa00bb00cd00303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3043aa02aabb303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30452224aa00bb00cd00021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig", " = 30432222aa02aabb021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3045021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a2225aa00bb00cd00021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3043021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a2223aa02aabb021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 39\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30412280021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0000021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3041021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a2280021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080313d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30412280031c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0000021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3041021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a2280031d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 46\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e3d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f3d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 313d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 323d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff3d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 52\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 53\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 3041300102303c1c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c1c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 56\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\nflags = BER\n\n# tcId = 57\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb3584636100\n\n# tcId = 58\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb3584636105000000\n\n# tcId = 59\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361060811220000\n\n# tcId = 60\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000fe02beef\n\n# tcId = 61\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610002beef\n\n# tcId = 62\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f3000021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 63\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463613000\n\n# tcId = 64\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 3040021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361bf7f00\n\n# tcId = 65\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 66\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 301e021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a\n\n# tcId = 67\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 305c021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303e02811c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a02811d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 70\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303f0282001c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0282001d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021d70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021b70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021e00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 75\n#", " wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021c00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30420285010000001c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3042021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0285010000001d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3046028901000000000000001c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3046021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a028901000000000000001d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304102847fffffff70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3041021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a02847fffffff00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30410284ffffffff70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 83\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3041021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0284ffffffff00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30420285ffffffffff70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 85\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3042021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0285ffffffffff00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30450288ffffffffffffffff70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 87\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3045021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0288ffffffffffffffff00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d02ff70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 89\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a02ff00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 90\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 301f021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302002021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 92\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 301f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a02\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0000021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 94\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021f00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610000\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e000070049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 96\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021f000000d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\nflags = BER\n\n# tcId = 97\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0000021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0500021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 99\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021f00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb358463610500\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30210281021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 101\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3020021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0281\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 30210500021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 103\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 3020021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a0500\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d001c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d011c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d031c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 107\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d041c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 108\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303dff1c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a021d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 109\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a001d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 110\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a011d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 111\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a031d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 112\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480a041d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 113\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c70049af31f8348673d56cece2b27e587a402f2a48f0b21a7911a480aff1d00d7bf40db0909941d78f9948340c69e14c5417f8c840b7edb35846361\n\n# tcId = 114\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 30210200021d0", @@ -3241,9 +3879,9 @@ static const char *kData115[] = { "a5f8b89bbb2a7e667aff81cd]\n[sha = SHA-224]\n\n# tcId = 321\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 303c021c753bb40078934081d7bd113ec49b19ef09d1ba33498690516d4d122c021c249249249249249249249249249227ce201a6b76951f982e7ae89851\n\n# tcId = 322\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 303d021d008ac44bff876cbf7e2842eec13b63fcb3d6e7360aca5698f3ef0f1811021c249249249249249249249249249227ce201a6b76951f982e7ae89851\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 044c246670658a1d41f5d77bce246cbe386ac22848e269b9d4cd67c466ddd947153d39b2d42533a460def26880408caf2dd3dd48fe888cd176]\n[key.wx = 4c246670658a1d41f5d77bce246cbe386ac22848e269b9d4cd67c466]\n[key.wy = 00ddd947153d39b2d42533a460def26880408caf2dd3dd48fe888cd176]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a00044c246670658a1d41f5d77bce246cbe386ac22848e269b9d4cd67c466ddd947153d39b2d42533a460def26880408caf2dd3dd48fe888cd176]\n[sha = SHA-224]\n\n# tcId = 323\n# pseudorandom signature\nmsg = \nresult = valid\nsig = 303d021c2770403d42b7b45e553308d1f6a480640b61cac0ae36665d6f14d34e021d0085506b0404265ededf9a89fc7c9c7a55c16c5b0d781f774de8f46fa1\n\n# tcId = 324\n# pseudorandom signature\nmsg = 4d7367\nresult = valid\nsig = 303d021d00b68da722bbba7f6a58417bb5d0dd88f40316fc628b0edfcb0f02b062021c5c742e330b6febadf9a12d58ba2a7199629457ef2e9e4cecd2f09f50\n\n# tcId = 325\n# pseudorandom signature\nmsg = 313233343030\nresult = valid\nsig = 303c021c01ec1ff15c8a55d697a5424d674753f82f711593828368d2fbb41a17021c20d9089db7baf46b8135e17e01645e732d22d5adb20e3772da740eee\n\n# tcId = 326\n# pseudorandom signature\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 303c021c3e46e9ba4dc089ff30fa8c0209c31b11ff49dbeec090f9f53c000c75021c6f2e3b36369416602bca83206809ed898fcf158a56c25a5474143f68\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04aed6fcad2400c4d94e55dbb6b012ce3d4c2b46843fbe99d4289e6ecf8a24a89e71343d7d151d258d2cb690349c2d56b366dd10a600000000]\n[key.wx = 00aed6fcad2400c4d94e55dbb6b012ce3d4c2b46843fbe99d4289e6ecf]\n[key.wy = 008a24a89e71343d7d151d258d2cb690349c2d56b366dd10a600000000]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004aed6fcad2400c4d94e55dbb6b012ce3d4c2b46843fbe99d4289e6ecf8a24a89e71343d7d151d258d2cb690349c2d56b366dd10a600000000]\n[sha = SHA-224]\n\n# tcId = 327\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c77b38da37079d27b837613ac3e8248d66eabd5d637076c8e62c7991e021d00d40cd9f81efc52db4429c0c1af7c1d8a22b6c7babbe7fbd8b5b3f02f\n\n# tcId = 328\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d008c03b32c166c0c8b99d7f876acd109447efb13f6b82945e78d51a269021c657568f1a0a8bd7df5ffa43097ebb2b64435c8e3335bcaafc63f9ed5\n\n# tcId = 329\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00d199a375253d30f1d2b4493542e9934f9f1f8b0680117679f5bc4ad2021c11419ddbf02c8ad5f518f8dac33f86a85e777af51a034132e2767a6d\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f173d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[key.wx = 00bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f1]\n[key.wy = 73d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f173d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[sha = SHA-224]\n\n# tcId = 330\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d008ff82699e2e82870be9cfdd8a408bb34f8f38a83a4ac8370f18f2bc8021c7e5008fab6a0d4159200077ef9918dad6592cd8359838852c636ac05\n\n# tcId = 331\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c3f3b60b529ae0f950c517264adf2e481616bc47416742d5103589660021d00f731ebe98e58384b3a64b4696d4cc9619828ad51d7c39980749709a6\n\n# tcId = 332\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00dc11ffdc6b78754a335f168c4033916a2158d125a3f4fed9dc736661021c6dd84364717d9f4b0790f2b282f9245ecb316874eac025600397f109\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[key.wx = 26e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000]\n[key.wy = 00eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[sha = SHA-224]\n\n# tcId = 333\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00a59b25b786d55f26b04dfe90ee02a6bde64ed6e431dc9fbdc3ab360e021d00fc14b5ad20f39da9900e35437936c8626fccf6632e7a3d9e587e3311\n\n# tcId = 334\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c2eda1f96c1a6e3ad8a3321ce82cbb13a5b935b501abf6c06f7fd2b3f021d00e81050c3e5f53a3c7b9d0bdb9ed92a326dfeac44791ba1abe4d6e973\n\n# tcId = 335\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c60f5e093fda08fc14ac99d820a18ad1370c58150bea0aca24fc6db9d021d00c2220a0ebbf4896e68fdb5bd824f88291c1c862b916f9c4af87f8f5f\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[key.wx = 00ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff]\n[key.wy = 41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[sha = SHA-224]\n\n# tcId = 336\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c2ead37846a5e36a490b75140bdc7b636c6e9f6d8f980f6fadb08f769021d00e1fe130ae1798c196d7be62c7a5ddb3168cf4b8d48b6b6b4dc94ab3b\n\n# tcId = 337\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00a8a4c9416d72c860573d073281cb08c86ad65313f06b15a329e82eb2021c5a6edd2f0816b7263d915d72c67d50a854e3abee5cde1b679a0cef09\n\n# tcId = 338\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c576bb86c517bfecdc930a4c8501725548d425afbb96d93f5c1e2a0e1021c77248c5ecd620c431438c50e6bee6858091b54a87f8548ae35c21027\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[sha = SHA-224]\n\n# tcId = 339\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c34e41cba628fd8787ba1a528f6015d2cae015c1c9a866e08a7133801021d0083d422ffdd99cc3c6d7096ef927f0b11988d1824e6e93840ff666ccd\n\n# tcId = 340\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c2558a42e79689244bccd5e855f6a1e42b4ff726873f30b532b89ef53021c07f9bd947785187175d848b6e2d79f7ab3bbc1087b42590b0cfb256a\n\n# tcId = 341\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00d5fe7dd5fb4fd1ea5ce66c0824f53f96ce47fd9b6c63b4d57827fd17021d00bce5bc3af705afaacb81bfa6d552d6198962fece9fba41546c602ddc\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a9", "92b9a4a0e0ce178d20c]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 00ffffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[sha = SHA-224]\n\n# tcId = 342\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d008c1da2f07cdcbce4db8067b863468cfc728df52980229028689e57b6021c32175c1390a4b2cab6359bab9f854957d4fd7976c9c6d920c871c051\n\n# tcId = 343\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00e46d4f11b86b5a12f6fe781d1f934ef2b30e78f6f9cc86a9996e20c0021d008351974b965526034a0ccef0e7d3bc13d91798151488c91533143f7b\n\n# tcId = 344\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c305ccf0b5d0cf33dc745bb7c7964c233f6cfd8892a1c1ae9f50b2f3f021c785f6e85f5e652587c6e15d0c45c427278cf65bb1429a57d8826ca39\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[key.wx = 00f7e4713d085112112c37cdf4601ff688da796016b71a727a]\n[key.wy = 00de5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[sha = SHA-224]\n\n# tcId = 345\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c0e4fde0ac8d37536505f7b8bdc2d22c5c334b064ac5ed27bea9c179e021d00c4d6bf829dd547000d6f70b9ad9e9c1503bebcf1d95c2608942ca19d\n\n# tcId = 346\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00818afcaf491da9d08a7cc29318d5e85dce568dcca7018059f44e9b7e021d00bf32a233d5fc6ed8e2d9270b1bdad4bbd2a0f2c293d289bd91ffbcf3\n\n# tcId = 347\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c0e05ed675c673e5e70a4fdd5a47b114c5d542d4f6d7a367597d713ea021c26d70d65c48430373363987810bdcc556e02718eab214403ae008db4\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[key.wx = 00ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f725]\n[key.wy = 0086c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[sha = SHA-224]\n\n# tcId = 348\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00ab7a19eecf63e9668278963b65236b2768e57cae0e268cb86a0ddda1021d008829f5d3a3394f9467ba62e66ef1768e3e54f93ed23ec962bc443c2e\n\n# tcId = 349\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c17111a77cf79bead456ed86a7d8a935531440281eb8b15a885e341c0021d00fdc3958d04f037b1d4bb2cee307b5201be062e0d4e089df1c1917668\n\n# tcId = 350\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00acafa1e33345eeba0c338c2204b4cd8ba21de7ec3e1213317038e968021c0b42fbbaeda98a35da0de4c79546f3a0f7d9dec275d2cd671f93c874\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 0e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[sha = SHA-224]\n\n# tcId = 351\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00a3fe71a2a56f554e98fd10a8098c2a543c98bc6b3602ef39f2412308021c5d1d68f9a870ef2bc87484b3386549fae95811ab72bc0e3a514720da\n\n# tcId = 352\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c132f7625704756c13f2bfa449e60952f836f4904660b5b1da07e5a9f021d0082b4abafc40e8fd19b0c967f02fff152737ce01153658df445c4d7b7\n\n# tcId = 353\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00f36a8347c6fe0397a1161a364cbc4bdfb4d8b7894cbaa6edc55a4ff7021d009c9c90515da5e602d62e99f48eac414e913dd0b7cbf680c1a5399952\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 00fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[sha = SHA-224]\n\n# tcId = 354\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c2125ecc08e52e9e39e590117de2145bd879626cb87180e52e9d3ce03021d008f7e838d0e8fb80005fe3c72fca1b7cc08ed321a34487896b0c90b04\n\n# tcId = 355\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00e485747ac2f3d045e010cdadab4fd5dbd5556c0008445fb73e07cd90021d00e2133a7906aeac504852e09e6d057f29ab21368cfc4e2394be565e68\n\n# tcId = 356\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00a4de0d931ddab90e667ebc0ad800ce49e971c60543abdc46cefff926021c550816170bd87593b9fb8ad5ed9ab4ddb12403ff6fe032252833bac4\n\n", }; -static const size_t kLen116 = 118159; +static const size_t kLen170 = 118159; -static const char *kData116[] = { +static const char *kData170[] = { "# Imported from Wycheproof's ecdsa_secp224r1_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[key.wx = 00eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7]\n[key.wy = 00eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[sha = SHA-256]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 303d021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021d009e82950ebe102f37ff3645cc7d3c1bab8864e5e03a5011eeba8150bc\n\n# tcId = 2\n# valid\nmsg = 313233343030\nresult = valid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 3\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30813c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 4\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082003c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 5\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303d021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303b021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 7\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000003c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 8\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000003c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 9\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 10\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 11\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 12\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 13\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 14\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303c02803ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040280617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 17\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 18\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 19\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 20\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e0000021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 21\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 22\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810500\n\n# tcId = 23\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3041498177303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30402500303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 303e303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810004deadbeef\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30412221498177021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304022202500021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3044221e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040004deadbeef021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3041021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a042221498177021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3040021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a0422202500021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3044021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04221e021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810004deadbeef\n\n# tcId = 32\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3044aa00bb00cd00303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3042aa02aabb303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30442224aa00bb00cd00021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30422222aa02aabb021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3044021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a042224aa00bb00cd00021c6", "17d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3042021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a042222aa02aabb021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 38\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 39\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30402280021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040000021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3040021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a042280021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 42\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080313c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30402280031c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040000021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3040021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a042280031c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 45\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 46\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e3c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f3c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 313c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 323c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff3c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 51\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 52\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 3040300102303b1c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 53\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303b021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303b1c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 55\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\nflags = BER\n\n# tcId = 56\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad98100\n\n# tcId = 57\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad98105000000\n\n# tcId = 58\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981060811220000\n\n# tcId = 59\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000fe02beef\n\n# tcId = 60\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810002beef\n\n# tcId = 61\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e3000021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 62\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9813000\n\n# tcId = 63\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 303f021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981bf7f00\n\n# tcId = 64\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 65\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 301e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04\n\n# tcId = 66\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 305a021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 67\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d02811c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a0402811c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 69\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303e0282001c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 70\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040282001c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 71\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021d3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021b3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021d617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021b617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 75\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30410285010000001c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c", "800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3041021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040285010000001c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 77\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3045028901000000000000001c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3045021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04028901000000000000001c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 79\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304002847fffffff3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3040021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a0402847fffffff617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 81\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30400284ffffffff3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3040021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040284ffffffff617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 83\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30410285ffffffffff3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3041021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040285ffffffffff617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 85\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30440288ffffffffffffffff3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3044021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040288ffffffffffffffff617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 87\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c02ff3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a0402ff617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 89\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 301e021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 90\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 301f02021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 301f021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a0402\n\n# tcId = 92\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021e3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040000021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021e617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810000\n\n# tcId = 94\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021e00003ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021e0000617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\nflags = BER\n\n# tcId = 96\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040000021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 97\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021e3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040500021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021e617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad9810500\n\n# tcId = 99\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30200281021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3020021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040281\n\n# tcId = 101\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 30200500021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 3020021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040500\n\n# tcId = 103\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c001c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c011c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c031c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c041c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 107\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303cff1c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 108\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04001c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 109\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04011c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 110\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04031c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 111\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04041c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 112\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303c021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04ff1c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 113\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 30200200021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 114\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 3020021c3ade5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a040200\n\n# tcId = 115\n# using composition for integer\nmsg = 313233343030\nresult = invalid\nsig = 3040222002013a021bde5c0624a5677ed7b6450d9420bbe028d499c23be9ef9d8b8a8a04021c617d6af141efd0c800c9ba3382c2faf758540a5dd98d1756a1dad981\n\n# tcId = 116\n# using ", @@ -3260,9 +3898,9 @@ static const char *kData116[] = { "d = 356\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c519bf185ff4635271961fa491be257231deeea9c53a6ede3b4a89ed1021c486bdad484a6a3134e1471cf56a9df0fac50f773b3e37d6f327617d7\n\n# tcId = 357\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c09fd644898b7cb5d018b52234e7b4ef2b54789afd0ce9c434e9e5515021d00f19309532164ea2053cae55df7bdcbab536c83ea7bfe6fe10d60c1ab\n\n# tcId = 358\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00ec919d4e283ccf1f71a9e3c0f781a36758d3f38b1b78a87a74288e80021c4c4663044a73c79bd88f0dc245ab1a32f89f06f40a704b31e9fabc51\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f173d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[key.wx = 00bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f1]\n[key.wy = 73d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004bf19ecfe43ffe289f699f479316145b9a7f7370b9ece5ab1212174f173d528949ae9142f818bade71a960407963be0b6482a6a60ffffffff]\n[sha = SHA-256]\n\n# tcId = 359\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00c51760478447217597ecc6f4001bd45088d53c90f53103608bf88aea021d00a201253aa903f9781e8992101d7171d2dd3a5d48c44d8e1d544cd6d7\n\n# tcId = 360\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c76be0112674ec29128823e1af7512e6143872fef30a64e2f1799bd56021c187e503e1a48c27b549fe0a4ce5e581e242c8663fc9efb02d6f2b193\n\n# tcId = 361\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c36245ef126b5b51e459f84eaaad5a495061f0471dc8c23f1c5f16282021c39e31d72a06ba8e14fcf95778e07bc16a2628e39449da8857d506edc\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[key.wx = 26e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000]\n[key.wy = 00eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[sha = SHA-256]\n\n# tcId = 362\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c258682975df8bca7f203f771ebeb478ef637360c860fc386cfb21745021c7663e70188047e41469a2a35c8c330dd900f2340ba82aafd22962a96\n\n# tcId = 363\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d0085c98614f36c0d66f8d87834cae978611b7b4eebf59a46bea1b89ae9021d00d1a18e378dda840e06b60f6279bf0a2231d9fa2d8d2c31e88bc1bdd7\n\n# tcId = 364\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00ca7b7432ba41ff2112e1116fffde89bbd68f5ce67fe5513d16c8e6f7021d00e421b7599e0180798acc2006451603cda2db1d582741116e6033ce5f\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[key.wx = 00ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff]\n[key.wy = 41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[sha = SHA-256]\n\n# tcId = 365\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c19397fe5d3ecabf80fc624c1bf379564387517c185087dc97d605069021c33b5773e9aaf6c34cb612cfc81efd3bf9c22224e8c4fa1bfccf5c501\n\n# tcId = 366\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c70f24f5c164164bfbb8459aa12a981aa312dbcf00204326ebaaabdc8021d00f5cebee8caedae8662c43501665084b45d2f494fb70d603043543dc4\n\n# tcId = 367\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c0bf2d86ecaa8b56aca5e8f8ebcb45081d078a14555b75f5be8e9b132021d009a55b3ce4734849966b5034ccd9b19f76407ee0241c3f58e7b8fc89a\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[sha = SHA-256]\n\n# tcId = 368\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00bfc5dc4434cd09369610687d38d2d418b63fd475dea246a456b25a3a021d00b171dfa6cf722f20816370a868785da842b37bac31d7b78e6751fc50\n\n# tcId = 369\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d008fdbe8da646c5642d767c7dbeb3872b1edab6e37365805f0e94ce0a9021d00bcf35ab81222883dd3526cb0cf93138f4687cd0b10c2b0a126385161\n\n# tcId = 370\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00e23a11275848fd4f8b6f4ac4fc305eae981d3b7dc453e5a980c46422021c1a875693f24a03ea1614c4c3bbd0dd7221429f22b337ea7d98348ca4\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 00ffffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[sha = SHA-256]\n\n# tcId = 371\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c76645164ff9af3a1a9205fda2eef326d2bffc795dcc4829547fe01dd021d00b65bba503719314b27734dd06b1395d540af8396029b78b84e0149eb\n\n# tcId = 372\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c32fa0ca7e07f1f86ac350734994e1f31b6da9c82f93dced2b983c29c021c7b7891282206a45711bdfcb2a102b5d289df84ff5778548603574004\n\n# tcId = 373\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c2d5492478ca64e5111dfd8521867b6477b7e78227849ad090b855694021d00a532f5a2fa3594af81cd5928b81b4057da717be5fb42a3a86c68190d\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[key.wx = 00f7e4713d085112112c37cdf4601ff688da796016b71a727a]\n[key.wy = 00de5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[sha = SHA-256]\n\n# tcId = 374\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c191eee5daf55cd499e8539cb2cff797cfec5d566d2027bf9f8d64693021d00dadfeae8131f64d96b94fd340197caa2bc04818554812feef3343070\n\n# tcId = 375\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00e0e2c08180b8a207ee9105a7d379fa112368e8370fa09dfde4a45c45021d00c717bc0860e016e7ce48f8fe6a299b36906a6055adad93b416ce8838\n\n# tcId = 376\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c1b919ef93532292743bb2e1b7b4894fd847c6e5de52a08e1b0f2dcfb021d00c2d30d6b7594d8dbd261491ae1d58779505b075b64e5564dc97a418b\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242", "a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[key.wx = 00ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f725]\n[key.wy = 0086c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[sha = SHA-256]\n\n# tcId = 377\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00e75db49ed33ff2885ea6100cc95b8fe1b9242ea4248db07bcac2e020021c796c866142ae8eb75bb0499c668c6fe45497692fbcc66b37c2e4624f\n\n# tcId = 378\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c1f81cd924362ec825890307b9b3936e0d8f728a7c84bdb43c5cf0433021c39d3e46a03040ad41ac026b18e0629f6145e3dc8d1e6bbe200c8482b\n\n# tcId = 379\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c00fda613aa67ca42673ad4309f3f0f05b2569f3dee63f4aa9cc54cf3021c1e5a64b68a37e5b201c918303dc7a40439aaeacf019c5892a8f6d0ce\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 0e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[sha = SHA-256]\n\n# tcId = 380\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00b932b3f7e6467e1ec7a561f31160248c7f224550a8508788634b53ce021d00a0c5312acf9e801aff6d6fc98550cfa712bbf65937165a36f2c32dc9\n\n# tcId = 381\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00e509593fb09245ee8226ce72786b0cc352be555a7486be628f4fd00c021c0b7abde0061b1e07bf13319150a4ff6a464abab636ab4e297b0d7633\n\n# tcId = 382\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c6e54f941204d4639b863c98a65b7bee318d51ab1900a8f345eac6f07021c0da5054829214ecde5e10579b36a2fe6426c24b064ed77c38590f25c\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 00fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[sha = SHA-256]\n\n# tcId = 383\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d0085ea4ab3ffdc992330c0ca8152faf991386bce82877dbb239ba654f6021c0806c6baf0ebea4c1aaa190e7d4325d46d1f7789d550632b70b5fc9b\n\n# tcId = 384\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c44d53debb646b73485402eab2d099081b97b1243c025b624f0dd67ea021d00e5de789a7d4b77eac6d7bba41658e6e4dc347dabed2f9680c04a6f55\n\n# tcId = 385\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c1526eb2f657ebea9af4ca184b975c02372c88e24e835f3f5774c0e12021c1f1ecce38ee52372cb201907794de17b6d6c1afa13c316c51cb07bc7\n\n", }; -static const size_t kLen117 = 132917; +static const size_t kLen171 = 132917; -static const char *kData117[] = { +static const char *kData171[] = { "# Imported from Wycheproof's ecdsa_secp224r1_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[key.wx = 00eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7]\n[key.wy = 00eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004eada93be10b2449e1e8bb58305d52008013c57107c1a20a317a6cba7eca672340c03d1d2e09663286691df55069fa25490c9dd9f9c0bb2b5]\n[sha = SHA-512]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 303c021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021c394766fb67a65fe0af6c154f7cbd285ea180b4c6150cdafafb0f6f0f\n\n# tcId = 2\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 303c021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021cc6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = MissingZero\n\n# tcId = 3\n# valid\nmsg = 313233343030\nresult = valid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 4\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30813d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 5\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082003d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303e021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 8\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000003d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 9\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000003d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 10\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 11\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 12\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 13\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 14\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303d0280691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab028000c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 18\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 19\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 20\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 21\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f0000021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 22\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 23\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0500\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3042498177303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30412500303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 303f303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0004deadbeef\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30422221498177021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304122202500021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3045221e021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0004deadbeef021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3042021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab2222498177021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3041021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab22212500021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3045021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab221f021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0004deadbeef\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3045aa00bb00cd00303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3043aa02aabb303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30452224aa00bb00cd00021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig", " = 30432222aa02aabb021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3045021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab2225aa00bb00cd00021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 3043021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab2223aa02aabb021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 39\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30412280021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0000021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3041021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab2280021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080313d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30412280031c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0000021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3041021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab2280031d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 46\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e3d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f3d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 313d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 323d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff3d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 52\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 53\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 3041300102303c1c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 303c1c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 56\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\nflags = BER\n\n# tcId = 57\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e00\n\n# tcId = 58\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e05000000\n\n# tcId = 59\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e060811220000\n\n# tcId = 60\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000fe02beef\n\n# tcId = 61\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0002beef\n\n# tcId = 62\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f3000021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 63\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e3000\n\n# tcId = 64\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 3040021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2ebf7f00\n\n# tcId = 65\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 303f303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 66\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 301e021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab\n\n# tcId = 67\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 305c021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303e02811c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303e021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab02811d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 70\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303f0282001c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0282001d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021d691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021b691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021e00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 75\n#", " wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021c00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30420285010000001c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3042021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0285010000001d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3046028901000000000000001c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3046021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab028901000000000000001d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304102847fffffff691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3041021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab02847fffffff00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30410284ffffffff691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 83\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3041021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0284ffffffff00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30420285ffffffffff691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 85\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3042021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0285ffffffffff00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30450288ffffffffffffffff691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 87\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3045021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0288ffffffffffffffff00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d02ff691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 89\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab02ff00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 90\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 301f021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302002021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 92\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 301f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab02\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0000021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 94\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021f00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0000\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e0000691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 96\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021f000000c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\nflags = BER\n\n# tcId = 97\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0000021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021e691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0500021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 99\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 303f021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021f00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e0500\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30210281021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 101\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3020021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0281\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 30210500021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 103\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 3020021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab0500\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d001c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d011c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d031c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 107\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d041c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 108\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303dff1c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab021d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 109\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab001d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 110\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab011d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 111\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab031d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 112\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92ab041d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 113\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 303d021c691c723dd6a7f5d11b8c8e8bd0825c9fab0b99ee2b25f3658fdf92abff1d00c6b899049859a01f5093eab08341ee443f383b77fed04e4a614cbb2e\n\n# tcId = 114\n# dropping value of integer\nmsg = 313233343030\nresult = invalid\nsig = 30210200021d0", @@ -3281,9 +3919,9 @@ static const char *kData117[] = { "ef6fa778b19dccd609d496b62a211021c6c51e846fa53d03d42f798e6bb90954f9a48c1794b47e84ac97b460a\n\n# tcId = 430\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021b34befa1d25b756ce76b383a6e8753741c12a59266c2c7921ff6e8b021d00bc44e3823e4d807cbc92fa786a89e62a4b217b5fb0c0f1865d4a7e43\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[key.wx = 26e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000]\n[key.wy = 00eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000426e5abf135cb54eaaa16b69e4b0b292275344e88a09df6df80000000eab891de54e3f26ff50ab989f333dac551583d468ae623c596434af0]\n[sha = SHA-512]\n\n# tcId = 431\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c224a38e733ebd3fac274ecc50ecef2e7c3189be2b9d093a8dcc6fa3a021c134fa5a4f923d296b3c6dd4683d249ccf0ad272890e4149c9a0d7415\n\n# tcId = 432\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c338d07d990879ad844e24c1788e362269d8aca70500357d385768227021d00f745cc4ebaaf1cd42830026a66e5b95564cdbee5edf853bb2cc91259\n\n# tcId = 433\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c689fce4b33d8212a663640a1ae0efaa7a7d7711beba719374fe634ee021c04bd9981fa52293063076f0fd70fc31875d580ef94f020d2f95440e0\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[key.wx = 00ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff]\n[key.wy = 41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ec627f345545d03f8c6dbd08e575527116567fe375f9ecaaffffffff41bf705697d5f716bcf78718d5393b63a98691f4a1f24246375538fd]\n[sha = SHA-512]\n\n# tcId = 434\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c2a4287e01510e7fb5fed2e1ccc3f2a6929cf7d03850e49d7ae8a504a021c355c3915f3fa9637dc8001438a8c04e15d14934cabd430feb0cb5ba5\n\n# tcId = 435\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00b5bf795a38adb052b401468ffcab81103d2d9fca2e15b8d08ab98ce8021c5ec0d2c6aec71888c941af324c7272bec192abb292f9df82a24e8a41\n\n# tcId = 436\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c100ed07f467133bf10917f7a15ab2bfda519bdbc2653b95955e22211021d00b38a081f7c2e2b775d1da868d0381c09ba1559c9613b5be7159363ad\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a00000000762d28f1fdc219184f81681fbff566d465b5f1f31e872df5]\n[sha = SHA-512]\n\n# tcId = 437\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c54e6add8ac910e52c6228fe3980d8f586218334d8d859ba9a3329917021c5836cc79ec88519eab4a6b2614c501628c9fee32fbafd93e32158409\n\n# tcId = 438\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c1230d5409f379584b4d548b7bccba64baf81d512a9f2e6398c4e3a66021c1937a298f8cbdfa85b8e6fcf0a12be4966d80270cade85a0c37ee6f3\n\n# tcId = 439\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00862f43b044fb32adb45e00378ba083ae761c84452054f17b1341bf5b021d0095d8d8e5e3a6cc2b0a06c792252ca11a642257721831578520f96b9e\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[key.wx = 15016e52b36472d536477605fb805dd3903082a062d1ea30af9e555a]\n[key.wy = 00ffffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000415016e52b36472d536477605fb805dd3903082a062d1ea30af9e555affffffff89d2d70e023de6e7b07e97df400a992b9a4a0e0ce178d20c]\n[sha = SHA-512]\n\n# tcId = 440\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00cb5cabb1ca01b847a6bc70558d1e5d3a204d1741bbe800f4b159af35021c3580cc85f218394130bddf1c4eac04fe96f59f14fb436686950398be\n\n# tcId = 441\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00c9d83dc04cf4ee89c405045d0fd1d704f627ca5bbe350f40b826bbc1021c74fedc9e55045e9759f2124460fdfb991dc620cfee6effc0b4adaa9e\n\n# tcId = 442\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c46dd65b6e7f10c0841841b01033a5befd3a0e78c85f1f390bb3cdf25021d00f33acea3d47cf0dd5273735b004104f6512ed641052509422c0325a7\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[key.wx = 00f7e4713d085112112c37cdf4601ff688da796016b71a727a]\n[key.wy = 00de5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a000400000000f7e4713d085112112c37cdf4601ff688da796016b71a727ade5a9ec165054cc987f9dc87e9991b92e4fa649ca655eeae9f2a30e1]\n[sha = SHA-512]\n\n# tcId = 443\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00ddb4a7e400a1e98118f474722da3f421f65a76eec61f4f7b699faf07021d00db80cba199859cdfe916d6ab3deb91d76aaf0ed554c8f9ed7e5aa59d\n\n# tcId = 444\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c4c260b546280604e4c80384721c9e803ef704e7fb70168e6730fc1f3021d00a8aceae219ac25c9f04231b4e0c171413db1d26df1c1e8430062eb2b\n\n# tcId = 445\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00f4098d2c0240e78fceabb0183df0b39e7ad3e7f5d6da1587fa09853c021d00d42412b2abaa614c95eb11f9b9346282ce3a1c93aac35ce7aa372f4a\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[key.wx = 00ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f725]\n[key.wy = 0086c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004ffffffffeadf7cee8d34d04cf22c8f7de35674fb2f501d242a76f72586c409309d398e60ce1e0a4c9e05a9d32627577e8ce2cc7f3afa2c3e]\n[sha = SHA-512]\n\n# tcId = 446\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c48ddc497f9a4732c677e46c0e2bdabec54fc9d27e46ab595056db4d9021d00b8219ebbfaebc2fe4311efab0c35d4392751351bcc1971e8d01941e4\n\n# tcId = 447\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00e1abaf51d27a6d7d4c9b28078325cac2d7ce3d5403916c68903760b7021c2c45a99e2770f782fee5ca1d713eaecf07e62d53c64b7cf93de9900d\n\n# tcId = 448\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00868cd127c99e1149f7fc8d878cdfa986b62e99addea281149611ff15021c16e5953820135b7d462ce5434ef85920e973eec9e4d14d7cb3cc2a3f\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 0e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1000000000e2ab0e8495e859eb2afb00769d6e7fe626a119167c0b6bc]\n[sha = SHA-512]\n\n# tcId = 449\n# y-coordinate of the publ", "ic key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303e021d00a375929718ec4e6ada9c9370c51df6bdaee7ebab2a70675d42a0b6b3021d009eaf4802efaf7ca082ffbf5ed774af43792d9b3fd711c6b1c36112ff\n\n# tcId = 450\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d00d97b32f3bf8bc11ec2672dd6320418beeed99527a63fe4c52199ec61021c68dd9006b03319ccbe651d0bdaf84c63356f03cb007a6865ee3e0206\n\n# tcId = 451\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 303d021d008ee5794dc2e66f2584910ea1d8361e5b53db535adcf5c1c35e128309021c5d1d8b9b996c0a488e05af14421b86e9841f0cba706027fc827d4d95\n\n[key.curve = secp224r1]\n[key.keySize = 224]\n[key.type = EcPublicKey]\n[key.uncompressed = 04b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[key.wx = 00b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1]\n[key.wy = 00fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[keyDer = 304e301006072a8648ce3d020106052b81040021033a0004b0013c6fbff6f09fecda1c263ef65399d4cf989ca5fc4f8fff0fe9e1fffffffff1d54f17b6a17a614d504ff7962918019d95ee6e983f4945]\n[sha = SHA-512]\n\n# tcId = 452\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c7999727c0cc02d88ef274012a762afcbb19e7fce19091a02acd00564021d00dbfacf67999f22c499d48a60a6fe4bbb746199c29957a1ec7a0900e0\n\n# tcId = 453\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303c021c5797c21c0162e42f69693c6c0244dfdf9218c01e9235760177b61a54021c5452c887b27fb342a8a00d27579c7195dddb73df399233ed0dea567b\n\n# tcId = 454\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 303d021c0eb9dc5d67bb0d4009544f8654977907dfe770e7fae4571d31d7b4fa021d00ab5cda53e868bff5198be4be3681b186cb0c1396d272c71f093f8b12\n\n", }; -static const size_t kLen118 = 131736; +static const size_t kLen172 = 131736; -static const char *kData118[] = { +static const char *kData172[] = { "# Imported from Wycheproof's ecdsa_secp256r1_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[key.wx = 2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838]\n[key.wy = 00c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[sha = SHA-256]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76\n\n# tcId = 2\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = MissingZero\n\n# tcId = 3\n# valid\nmsg = 313233343030\nresult = valid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 4\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30814502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 5\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 304602202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 8\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 9\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000004502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 10\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 11\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 12\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 13\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 14\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 304502802ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18028000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 18\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 19\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 20\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 21\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047000002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 22\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 23\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0500\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a498177304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30492500304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3047304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0004deadbeef\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a222549817702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30492224250002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304d222202202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180004deadbeef022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182226498177022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1822252500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182223022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0004deadbeef\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304daa00bb00cd00304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac", "5df4087c134b49156847db\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304baa02aabb304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304d2228aa00bb00cd0002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304b2226aa02aabb02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182229aa00bb00cd00022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304b02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182227aa02aabb022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 39\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3049228002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182280022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080314502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3049228003202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e182280032100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 46\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 314502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 324502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff4502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 52\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 53\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 30493001023044202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 3044202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 56\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\nflags = BER\n\n# tcId = 57\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db00\n\n# tcId = 58\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db05000000\n\n# tcId = 59\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db060811220000\n\n# tcId = 60\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000fe02beef\n\n# tcId = 61\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 308002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0002beef\n\n# tcId = 62\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047300002202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 63\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db3000\n\n# tcId = 64\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 304802202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847dbbf7f00\n\n# tcId = 65\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 66\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 302202202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18\n\n# tcId = 67\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 306802202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30460281202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304602202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802812100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 70\n# length of integer con", "tains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3047028200202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180282002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502212ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3045021f2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022200b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 75\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304a028501000000202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180285010000002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304e02890100000000000000202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304e02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18028901000000000000002100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902847fffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802847fffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30490284ffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 83\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180284ffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304a0285ffffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 85\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304a02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180285ffffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304d0288ffffffffffffffff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 87\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304d02202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180288ffffffffffffffff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502ff2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 89\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802ff00b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 90\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 3023022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302402022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 92\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302302202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702222ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 94\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022300b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0000\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 3047022200002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 96\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180223000000b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\nflags = BER\n\n# tcId = 97\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180000022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702222ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 99\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022300b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db0500\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30250281022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 101\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180281\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 30250500022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 103\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 302402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180500\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304500202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304501202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304503202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b4", @@ -3302,9 +3940,9 @@ static const char *kData118[] = { "6082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f49726500493584fa174d791c72bf2ce3880a8960dd2a7c7a1338a82f85a9e59cdbde80000000]\n[sha = SHA-256]\n\n# tcId = 367\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 30440220664eb7ee6db84a34df3c86ea31389a5405badd5ca99231ff556d3e75a233e73a022059f3c752e52eca46137642490a51560ce0badc678754b8f72e51a2901426a1bd\n\n# tcId = 368\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 304502204cd0429bbabd2827009d6fcd843d4ce39c3e42e2d1631fd001985a79d1fd8b430221009638bf12dd682f60be7ef1d0e0d98f08b7bca77a1a2b869ae466189d2acdabe3\n\n# tcId = 369\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100e56c6ea2d1b017091c44d8b6cb62b9f460e3ce9aed5e5fd41e8added97c56c04022100a308ec31f281e955be20b457e463440b4fcf2b80258078207fc1378180f89b55\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[key.wx = 3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935]\n[key.wy = 7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[sha = SHA-256]\n\n# tcId = 370\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 304402201158a08d291500b4cabed3346d891eee57c176356a2624fb011f8fbbf34668300220228a8c486a736006e082325b85290c5bc91f378b75d487dda46798c18f285519\n\n# tcId = 371\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3045022100b1db9289649f59410ea36b0c0fc8d6aa2687b29176939dd23e0dde56d309fa9d02203e1535e4280559015b0dbd987366dcf43a6d1af5c23c7d584e1c3f48a1251336\n\n# tcId = 372\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100b7b16e762286cb96446aa8d4e6e7578b0a341a79f2dd1a220ac6f0ca4e24ed86022100ddc60a700a139b04661c547d07bbb0721780146df799ccf55e55234ecb8f12bc\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[key.wx = 2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff]\n[key.wy = 00a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[sha = SHA-256]\n\n# tcId = 373\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3045022100d82a7c2717261187c8e00d8df963ff35d796edad36bc6e6bd1c91c670d9105b402203dcabddaf8fcaa61f4603e7cbac0f3c0351ecd5988efb23f680d07debd139929\n\n# tcId = 374\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 304402205eb9c8845de68eb13d5befe719f462d77787802baff30ce96a5cba063254af7802202c026ae9be2e2a5e7ca0ff9bbd92fb6e44972186228ee9a62b87ddbe2ef66fb5\n\n# tcId = 375\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 304602210096843dd03c22abd2f3b782b170239f90f277921becc117d0404a8e4e36230c28022100f2be378f526f74a543f67165976de9ed9a31214eb4d7e6db19e1ede123dd991d\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[key.wx = 00fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5]\n[key.wy = 5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[sha = SHA-256]\n\n# tcId = 376\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30440220766456dce1857c906f9996af729339464d27e9d98edc2d0e3b760297067421f60220402385ecadae0d8081dccaf5d19037ec4e55376eced699e93646bfbbf19d0b41\n\n# tcId = 377\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100c605c4b2edeab20419e6518a11b2dbc2b97ed8b07cced0b19c34f777de7b9fd9022100edf0f612c5f46e03c719647bc8af1b29b2cde2eda700fb1cff5e159d47326dba\n\n# tcId = 378\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100d48b68e6cabfe03cf6141c9ac54141f210e64485d9929ad7b732bfe3b7eb8a84022100feedae50c61bd00e19dc26f9b7e2265e4508c389109ad2f208f0772315b6c941\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[key.wx = 03fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e]\n[key.wy = 1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d0301070342000400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[sha = SHA-256]\n\n# tcId = 379\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100b7c81457d4aeb6aa65957098569f0479710ad7f6595d5874c35a93d12a5dd4c7022100b7961a0b652878c2d568069a432ca18a1a9199f2ca574dad4b9e3a05c0a1cdb3\n\n# tcId = 380\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 304402206b01332ddb6edfa9a30a1321d5858e1ee3cf97e263e669f8de5e9652e76ff3f702205939545fced457309a6a04ace2bd0f70139c8f7d86b02cb1cc58f9e69e96cd5a\n\n# tcId = 381\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100efdb884720eaeadc349f9fc356b6c0344101cd2fd8436b7d0e6a4fb93f106361022100f24bee6ad5dc05f7613975473aadf3aacba9e77de7d69b6ce48cb60d8113385d\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[key.wx = 00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015]\n[key.wy = 1352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[sha = SHA-256]\n\n# tcId = 382\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3044022031230428405560dcb88fb5a646836aea9b23a23dd973dcbe8014c87b8b20eb0702200f9344d6e812ce166646747694a41b0aaf97374e19f3c5fb8bd7ae3d9bd0beff\n\n# tcId = 383\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100caa797da65b320ab0d5c470cda0b36b294359c7db9841d679174db34c4855743022100cf543a62f23e212745391aaf7505f345123d2685ee3b941d3de6d9b36242e5a0\n\n# tcId = 384\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 304502207e5f0ab5d900d3d3d7867657e5d6d36519bc54084536e7d21c336ed8001859450221009450c07f201faec94b82dfb322e5ac676688294aad35aa72e727ff0b19b646aa\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[key.wx = 00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015]\n[key.wy = 00fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[sha = SHA-256]\n\n# tcId = 385\n# y-coordinate of the public key is large\nmsg ", "= 4d657373616765\nresult = valid\nsig = 3046022100d7d70c581ae9e3f66dc6a480bf037ae23f8a1e4a2136fe4b03aa69f0ca25b35602210089c460f8a5a5c2bbba962c8a3ee833a413e85658e62a59e2af41d9127cc47224\n\n# tcId = 386\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30440220341c1b9ff3c83dd5e0dfa0bf68bcdf4bb7aa20c625975e5eeee34bb396266b34022072b69f061b750fd5121b22b11366fad549c634e77765a017902a67099e0a4469\n\n# tcId = 387\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3045022070bebe684cdcb5ca72a42f0d873879359bd1781a591809947628d313a3814f67022100aec03aca8f5587a4d535fa31027bbe9cc0e464b1c3577f4c2dcde6b2094798a9\n\n", }; -static const size_t kLen119 = 147510; +static const size_t kLen173 = 147510; -static const char *kData119[] = { +static const char *kData173[] = { "# Imported from Wycheproof's ecdsa_secp256r1_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[key.wx = 2927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838]\n[key.wy = 00c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e]\n[sha = SHA-512]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 304402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c002205f85a63a5be977ad714cea16b10035f07cadf7513ae8cca86f35b7692aafd69f\n\n# tcId = 2\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 304402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00220a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = MissingZero\n\n# tcId = 3\n# valid\nmsg = 313233343030\nresult = valid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 4\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30814502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 5\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082004502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 304602202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 304402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 8\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000004502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 9\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000004502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 10\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 11\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 12\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 13\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 14\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 304502802478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0028000a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 18\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 19\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 20\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 21\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047000002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 22\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 23\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20500\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a498177304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30492500304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3047304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20004deadbeef\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a222549817702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30492224250002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304d222202202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00004deadbeef022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304a02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02226498177022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304902202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c022252500022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 304d02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02223022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20004deadbeef\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304daa00bb00cd00304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c", "2ed1dc84841359d1b34eb2\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304baa02aabb304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304d2228aa00bb00cd0002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304b2226aa02aabb02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304d02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02229aa00bb00cd00022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 304b02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02227aa02aabb022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 39\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3049228002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00000022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 304902202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02280022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3080314502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3049228003202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00000022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 304902202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c02280032100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 46\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e4502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f4502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 314502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 324502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff4502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 52\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 53\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 30493001023044202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 304402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34e\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 3044202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 56\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\nflags = BER\n\n# tcId = 57\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb200\n\n# tcId = 58\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb205000000\n\n# tcId = 59\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2060811220000\n\n# tcId = 60\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000fe02beef\n\n# tcId = 61\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 308002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20002beef\n\n# tcId = 62\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047300002202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 63\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb23000\n\n# tcId = 64\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 304802202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2bf7f00\n\n# tcId = 65\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3047304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 66\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 302202202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0\n\n# tcId = 67\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 306802202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30460281202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304602202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c002812100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 70\n# length of integer con", "tains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3047028200202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00282002100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502212478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3045021f2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022200a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 75\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022000a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304a028501000000202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304a02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00285010000002100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304e02890100000000000000202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304e02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0028901000000000000002100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902847fffffff2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c002847fffffff00a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30490284ffffffff2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 83\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304902202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00284ffffffff00a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 84\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304a0285ffffffffff2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 85\n# length of integer = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304a02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00285ffffffffff00a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 86\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304d0288ffffffffffffffff2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 87\n# length of integer = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 304d02202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00288ffffffffffffffff00a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 88\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502ff2478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 89\n# incorrect length of integer\nmsg = 313233343030\nresult = invalid\nsig = 304502202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c002ff00a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 90\n# removing integer\nmsg = 313233343030\nresult = invalid\nsig = 3023022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 91\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302402022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 92\n# lonely integer tag\nmsg = 313233343030\nresult = invalid\nsig = 302302202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c002\n\n# tcId = 93\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702222478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00000022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 94\n# appending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022300a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20000\n\n# tcId = 95\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 3047022200002478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 96\n# prepending 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00223000000a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\nflags = BER\n\n# tcId = 97\n# appending unused 0's to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00000022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 98\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702222478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00500022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 99\n# appending null value to integer\nmsg = 313233343030\nresult = invalid\nsig = 304702202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022300a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb20500\n\n# tcId = 100\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30250281022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 101\n# truncated length of integer\nmsg = 313233343030\nresult = invalid\nsig = 302402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00281\n\n# tcId = 102\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 30250500022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 103\n# Replacing integer with NULL\nmsg = 313233343030\nresult = invalid\nsig = 302402202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c00500\n\n# tcId = 104\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304500202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 105\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304501202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc84841359d1b34eb2\n\n# tcId = 106\n# changing tag value of integer\nmsg = 313233343030\nresult = invalid\nsig = 304503202478f1d049f6d857ac900a7af1772226a4c59b345fbb90613c66f42b98f981c0022100a07a59c4a41688538eb315e94effca0f4039035c6c2ed1dc8484135", @@ -3325,9 +3963,9 @@ static const char *kData119[] = { "b1022064a83af0ab3e6037003a1f4240dffd8a342afdee50604ed1afa416fd009e4668\n\n# tcId = 439\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 30450220575b70b4375684291b95d81e3c820ed9bde9e5b7343036e4951f3c46894a6d9d022100f10d716efbfeba953701b603fc9ef6ff6e47edef38c9eeef2d55e6486bc4d6e6\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[key.wx = 3cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f497265004935]\n[key.wy = 7b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200043cf03d614d8939cfd499a07873fac281618f06b8ff87e8015c3f4972650049357b05e8b186e38d41d31c77f5769f22d58385ecc857d07a561a6324217fffffff]\n[sha = SHA-512]\n\n# tcId = 440\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 30450221008d4f113189dfd3d3239e331f76d3fca9cef86fcd5dc9b4ab2ca38aeba56c178b022078389c3cf11dcff6d6c7f5efd277d480060691144b568a6f090c8902557bfc61\n\n# tcId = 441\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100834d10ec2d2d50eeebfecd6328f03fafbb488fc043c362cbc67880ec0ebd04b302210094c026feaf6e68759146fe5b6fd52eaa3c3c5552d83719d2cb900615e2a634db\n\n# tcId = 442\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 304502206894de495e7bb5566807d475d96a0d414a94f4f02c3ab7c2edc2916deafc1e1f022100a603642c20fabc07182867fcc6923d35be23ad3f97a5f93c6ec5b9cce8239569\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[key.wx = 2829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffff]\n[key.wy = 00a01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d030107034200042829c31faa2e400e344ed94bca3fcd0545956ebcfe8ad0f6dfa5ff8effffffffa01aafaf000e52585855afa7676ade284113099052df57e7eb3bd37ebeb9222e]\n[sha = SHA-512]\n\n# tcId = 443\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100e500c086fedd59e090ce7bfb615751ed9abe4c09b839ee8f05320245b9796f3e022100807b1d0638c86ef6113fff0d63497800e1b848b5a303a54c748e45ca8f35d7d7\n\n# tcId = 444\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100b922c1abe1a8309c0acf90e586c6de8c33e37057673390a97ff098f71680b32b022100f86d92b051b7923d82555c205e21b54eab869766c716209648c3e6cc2629057d\n\n# tcId = 445\n# x-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100823c37e46c74ec8497d89245fde3bf53ddb462c00d840e983dcb1b72bbf8bf27022100c4552f2425d14f0f0fa988778403d60a58962e7c548715af83b2edabbb24a49f\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[key.wx = 00fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f5]\n[key.wy = 5a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004fffffff948081e6a0458dd8f9e738f2665ff9059ad6aac0708318c4ca9a7a4f55a8abcba2dda8474311ee54149b973cae0c0fb89557ad0bf78e6529a1663bd73]\n[sha = SHA-512]\n\n# tcId = 446\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30450220577a08a95db6dcda9985109942d3786630f640190f920b95bd4d5d84e0f163ef022100d762286e92925973fd38b67ef944a99c0ec5b499b7175cbb4369e053c1fcbb10\n\n# tcId = 447\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 304402207ba458cfe952326922c7aa2854bdc673ce3daaf65d464dfb9f700701503056b102200df8821c92d20546fa741fb426bf56728a53182691964225c9b380b56b22ee6d\n\n# tcId = 448\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 304402205cd60c3b021b4be116f06f1d447f65e458329a8bbae1d9b5977d18cf5618486102204c635cd7aa9aebb5716d5ae09e57f8c481a741a029b40f71ec47344ef883e86e\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[key.wx = 03fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e]\n[key.wy = 1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d0301070342000400000003fa15f963949d5f03a6f5c7f86f9e0015eeb23aebbff1173937ba748e1099872070e8e87c555fa13659cca5d7fadcfcb0023ea889548ca48af2ba7e71]\n[sha = SHA-512]\n\n# tcId = 449\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 304402204b50e1e8cf830e04c17e7472caf60da8150ffa568e2c64498cc972a379e542e502202e3adaa5afab89cca91693609555f40543578852cde29c21cb037c0c0b78478e\n\n# tcId = 450\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 304402205aea930c7d8fffcd5c6df2c9430ef76f8b5ed58a8b9c95847288abf8f09a1ac202207ddfef7688a6053ce4eeeeefd6f1a9d71381b7548925f6682aa0a9d05cf5a3a3\n\n# tcId = 451\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 304602210098b092c2d14b5b14a23e9368e0ce1be744dfae9f9a5cdaba51e7872099df96f202210090d3e4f87bd7bc94589f8150b6b01045cd8759a00af78b24d7de771887610df5\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[key.wx = 00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015]\n[key.wy = 1352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015000000001352bb4a0fa2ea4cceb9ab63dd684ade5a1127bcf300a698a7193bc2]\n[sha = SHA-512]\n\n# tcId = 452\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 30460221009e95f2856a9fff9a172b07817c8c60fe185cd3ce9582678f8cc4b02bc444621a022100c54ca51d8117d904f0d3773911cb2792348fae21c2da7dad25f990d122376e4c\n\n# tcId = 453\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3046022100e77df8f9782696344c33de29ebdc9f8d3fcf463d950cdbe256fd4fc2fd44877e02210087028850c962cf2fb450ffe6b983981e499dc498fbd654fa454c9e07c8cb5ca8\n\n# tcId = 454\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3045022100bd2dd6f5026d2b5ad7ead74bdf52b8cbcabc08facee0a1c8584658a85ed0c5dc02203e8543e819bdae47d872e29a85ba38addf3eaeaad8786d79c3fb027f6f1ff4bf\n\n[key.curve = secp256r1]\n[key.keySize = 256]\n[key.type = EcPublicKey]\n[key.uncompressed = 04bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[key.wx = 00bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015]\n[key.wy = 00fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[keyDer = 3059301306072a8648ce3d020106082a8648ce3d03010703420004bcbb2914c79f045eaa6ecbbc612816b3be5d2d6796707d8125e9f851c18af015fffffffeecad44b6f05d15b33146549c2297b522a5eed8430cff596758e6c43d]\n[sha = SHA-512]\n\n# tcId = 455\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3045022100bd5c0294acc28c15c5d1ebc7274c9ca21a081c8a67da430a34a7fff1a564fabb02207ec103a2385b4ff38b47d306434e9091de24dc9f1a25967ee06f8a0a53ac0181\n\n# tcId = 456\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 304402203c7dbfb43dd80379ee2c23ad5472873a22c8a0179ac8f381ad9e0f193231dc1f02207cf8e07530ade503b3d43a84b75a2a76fc40763daed4e9734e745c58c9ae72d3\n\n# tcId = 457\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3045022100b38ca4dac6d949be5e5f969860269f0eedff2eb92f45bfc02470300cc96dd52602201c7b22992bb1", "3749cc0c5bc25330a17446e40db734203f9035172725fc70f863\n\n", }; -static const size_t kLen120 = 168183; +static const size_t kLen174 = 168183; -static const char *kData120[] = { +static const char *kData174[] = { "# Imported from Wycheproof's ecdsa_secp384r1_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[key.wx = 2da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa]\n[key.wy = 4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[keyDer = 3076301006072a8648ce3d020106052b81040022036200042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[sha = SHA-384]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d702301840da9fc1d2f8f8900cf485d5413b8c2574ee3a8d4ca03995ca30240e09513805bf6209b58ac7aa9cff54eecd82b9f1\n\n# tcId = 2\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = MissingZero\n\n# tcId = 3\n# valid\nmsg = 313233343030\nresult = valid\nsig = 3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 4\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308165023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 5\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 30820065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 6\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3066023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 8\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30850100000065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 9\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3089010000000000000065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 10\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 11\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 12\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 13\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 14\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3065028012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7028000e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 18\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 19\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 20\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3067023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 21\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 30670000023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 22\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 23\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3067023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820500\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a4981773065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306925003065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30673065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3", "394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820004deadbeef\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a2235498177023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306922342500023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306d2232023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70004deadbeef023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72236498177023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 3069023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d722352500023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306d023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72233023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820004deadbeef\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306daa00bb00cd003065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306baa02aabb3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306d2238aa00bb00cd00023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306b2236aa02aabb023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306d023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72239aa00bb00cd00023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306b023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72237aa02aabb023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 39\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30803065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30692280023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70000023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3069023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72280023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30803165023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30692280033012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70000023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 3069023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d72280033100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\n\n# tcId = 46\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e65023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f65023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3165023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3265023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff65023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 52\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 53\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 306930010230643012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 54\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 30643012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 56\n# indefini", "te length\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000\nflags = BER\n\n# tcId = 57\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f8200\n\n# tcId = 58\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f8205000000\n\n# tcId = 59\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82060811220000\n\n# tcId = 60\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820000fe02beef\n\n# tcId = 61\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f820002beef\n\n# tcId = 62\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 30673000023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 63\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 3067023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f823000\n\n# tcId = 64\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 3068023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82bf7f00\n\n# tcId = 65\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30673065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 66\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 3032023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7\n\n# tcId = 67\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 308198023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 68\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306602813012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3066023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d702813100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 70\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 30670282003012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3067023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70282003100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\nflags = BER\n\n# tcId = 72\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3065023112b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3065022f12b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023200e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 75\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3065023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023000e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 76\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306a0285010000003012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306a023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70285010000003100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 78\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306e028901000000000000003012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306e023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7028901000000000000003100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 80\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 306902847fffffff12b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3069023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d702847fffffff00e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82\n\n# tcId = 82\n# length of integer = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30690284ffffffff12b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d7023100e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff4", @@ -3350,9 +3988,9 @@ static const char *kData120[] = { "9023942871acb7002dfafdfffc8deace02302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n# tcId = 386\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 30640230064ed80f27e1432e84845f15ece399f2cbf4fa31aa837de9b953d44413b9f5c7c7f67989d703f07abef11b6ad0373ea502302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[key.wx = 29bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc]\n[key.wy = 009a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[keyDer = 3076301006072a8648ce3d020106052b810400220362000429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[sha = SHA-384]\n\n# tcId = 387\n# pseudorandom signature\nmsg = \nresult = valid\nsig = 3064023032401249714e9091f05a5e109d5c1216fdc05e98614261aa0dbd9e9cd4415dee29238afbd3b103c1e40ee5c9144aee0f02304326756fb2c4fd726360dd6479b5849478c7a9d054a833a58c1631c33b63c3441336ddf2c7fe0ed129aae6d4ddfeb753\n\n# tcId = 388\n# pseudorandom signature\nmsg = 4d7367\nresult = valid\nsig = 3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9\n\n# tcId = 389\n# pseudorandom signature\nmsg = 313233343030\nresult = valid\nsig = 30650230234503fcca578121986d96be07fbc8da5d894ed8588c6dbcdbe974b4b813b21c52d20a8928f2e2fdac14705b0705498c023100cd7b9b766b97b53d1a80fc0b760af16a11bf4a59c7c367c6c7275dfb6e18a88091eed3734bf5cf41b3dc6fecd6d3baaf\n\n# tcId = 390\n# pseudorandom signature\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 306502305cad9ae1565f2588f86d821c2cc1b4d0fdf874331326568f5b0e130e4e0c0ec497f8f5f564212bd2a26ecb782cf0a18d023100bf2e9d0980fbb00696673e7fbb03e1f854b9d7596b759a17bf6e6e67a95ea6c1664f82dc449ae5ea779abd99c78e6840\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aacacbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[key.wx = 00ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aac]\n[key.wy = 00acbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aacacbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[sha = SHA-384]\n\n# tcId = 391\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3065023007648b6660d01ba2520a09d298adf3b1a02c32744bd2877208f5a4162f6c984373139d800a4cdc1ffea15bce4871a0ed02310099fd367012cb9e02cde2749455e0d495c52818f3c14f6e6aad105b0925e2a7290ac4a06d9fadf4b15b578556fe332a5f\n\n# tcId = 392\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100a049dcd96c72e4f36144a51bba30417b451a305dd01c9e30a5e04df94342617dc383f17727708e3277cd7246ca44074102303970e264d85b228bf9e9b9c4947c5dd041ea8b5bde30b93aa59fedf2c428d3e2540a54e0530688acccb83ac7b29b79a2\n\n# tcId = 393\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30650230441800ea9377c27865be000ad008eb3d7502bdd105824b26d15cf3d06452969a9d0607a915a8fe989215fc4d61af6e05023100dce29faa5137f75ad77e03918c8ee6747cc7a39b0a69f8b915654cac4cf4bfd9c87cc46ae1631b5c6baebd4fc08ff8fd\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[key.wx = 00d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422]\n[key.wy = 00c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[sha = SHA-384]\n\n# tcId = 394\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 306402303244768016457c463b74f2097f216d9670b191f76281c74bc6a1a1971d19f209bf4696468f5eb75d6326a0a43c0a65290230501e0ad985ed9f95697bd17fdbe3f9ca92e0f76426d3664e6896648d9c750bf588d0ce7d011c1a1e8d6c2e082422dc93\n\n# tcId = 395\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 306402305e1af40f2480e3d97c4ae4bfd34a9f45269241356f3a46becd86a4a7c9716d73ca5aebdb3db1a7765650666683bc856b02307e7c4b473a2baaa4953785be8aa2a10006f6d36b400ab981864d69cecec046718d0404b9647454b159aa5a92d76d7955\n\n# tcId = 396\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 306502306688e36a26f15bdc1c3f91367f8a7667f7bb3e30a335d6f0900e9534eb88b260cb29344c723fedfbe7ac9c5a33f4bf0d023100aa35fddf0fdc9017860b378f801cd806f3e2d754cd2fd94eb7bb36a46ce828cef87e9ebbf447068e630b87fee385ad8f\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 041099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[key.wx = 1099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000]\n[key.wy = 00e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[keyDer = 3076301006072a8648ce3d020106052b81040022036200041099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[sha = SHA-384]\n\n# tcId = 397\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100d4a8f3b0b4d3a5769e3a0bbc644b35f1d509355ed1fe401e170f667b661f693b32598e8c143a817a958982845042bb48023004cc07578bbd1981dbf6e8a97a354c98d41b8b6f6e8a2c2b1763c7c2a29d79e24f8476075c9aed9aec6c64dff50461ae\n\n# tcId = 398\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100c286d1928e9c79fdd3bebdf22a1dbd37c8105e8ecf41e9e3777fe341b6b8d5a89b9d986827d6d1dbb381cd8239484a220230201119ae305b9360aa9b5e5d1567e0674c09e4f025556ebf81b987466b0f421b8d31f72bbe95f3ce2aa9874a84edfd40\n\n# tcId = 399\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100d9c678550167f10c511e62acb4bd0a3f7f336bc090c94e6c6b02622439c348a2159c5f41f9b5aa4b470590d40dcd7cc202301fd5eaee295abb4081cb626745f4ad279ceb44604062830b58e6c0465c562d41f02ba588fc0db1ebbe339cdc008d7a1b\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04000000002b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[key.wx = 2b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69]\n[key.wy = 00d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004000000002b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300", "e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[sha = SHA-384]\n\n# tcId = 400\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3065023020fee7c71b6cb0d1da3641ec6622c055a3b16a1f596c64b34da1b2d0b868b66a8f0a0d0db983b3dc7e53bb7295da81970231008141a931d3579aec1cac9887d2fff9c6f12d47a27e4aab8cf262a9d14a715bca0b2057cbc3f18b6fd3d1df76f7410f16\n\n# tcId = 401\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100913eecc559b3cf7108a65d6cc3076bfdf36c6f94dcc6693d06690470f34a2e81564241e1de5f5f51421de30af467f10f0230649bd3717244e8ef3c6b0eda983f84dca5ea86d1bec15386b9c473ec43a8cd0ba558eee819f791d9ff9272b9afd59551\n\n# tcId = 402\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3064023023855c46403a97b76cbb316ec3fe7e2c422b818387604bda8c3d91121b4f20179d9107c5f92dedc8b620d7db87fccccd023050f57343ab148e50662320c4161e44543c35bc992011ea5b1680b94382cf224ea0ec5da511e102f566cb67201f30a2ee\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b33600000000208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[key.wx = 00fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336]\n[key.wy = 208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b33600000000208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[sha = SHA-384]\n\n# tcId = 403\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100d200958d491fcebde667cd736c9dba0961c70db2ecaf573c31dd7fa41ecca32b40b5896f9a0ddf272110e3d21e84593a023100c2ecf73943b9adce596bac14fce62495ae93825c5ff6f61c247d1d8afcba52082fc96f63a26e55bccfc3779f88cfd799\n\n# tcId = 404\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 306402306ac17d71260c79f81a7566124738cb3ee5d0aa690e73a98ae9e766f1336691e500cad51ba1302366c09cc06b8f7049e0023032ca965d6d7012ec187c7cab9544334d66c2a7658ddefa67e4ad40429815518ecc87b1492ddd57333bd2300b4660a835\n\n# tcId = 405\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100e19a4646f0ed8a271fe86ba533f8be4fd81bbf4674716f668efa89a40cac51eec2a6cfbd92327d25efe91ca4ff712bc502304a86b2e8e12378e633dec2691e3b1eed4e932cc48b28e45fa3d464cc0e948c02cc9decf2bb43b25937fcf37e9ad86ef0\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[key.wx = 00fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336]\n[key.wy = 00ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[sha = SHA-384]\n\n# tcId = 406\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3064023015aac6c0f435cb662d110db5cf686caee53c64fe2d6d600a83ebe505a0e6fc62dc5705160477c47528c8c903fa865b5d02307f94ddc01a603f9bec5d10c9f2c89fb23b3ffab6b2b68d0f04336d499085e32d22bf3ab67a49a74c743f72473172b59f\n\n# tcId = 407\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 306602310090b95a7d194b73498fba5afc95c1aea9be073162a9edc57c4d12f459f0a1730baf2f87d7d6624aea7b931ec53370fe47023100cbc1ef470e666010604c609384b872db7fa7b8a5a9f20fdefd656be2fcc75db53948102f7ab203ea1860a6a32af246a1\n\n# tcId = 408\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100dd4391ce7557cbd005e3d5d727cd264399dcc3c6501e4547505b6d57b40bbf0a7fac794dcc8d4233159dd0aa40d4e0b9023100a77fa1374fd60aa91600912200fc83c6aa447f8171ecea72ae322df32dccd68951dc5caf6c50380e400e45bf5c0e626b\n\n", }; -static const size_t kLen121 = 179510; +static const size_t kLen175 = 179510; -static const char *kData121[] = { +static const char *kData175[] = { "# Imported from Wycheproof's ecdsa_secp384r1_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[key.wx = 2da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa]\n[key.wy = 4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[keyDer = 3076301006072a8648ce3d020106052b81040022036200042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f]\n[sha = SHA-512]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 3065023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202307b0a10ee2dd0dd2fab75095af240d095e446faba7a50a19fbb197e4c4250926e30c5303a2c2d34250f17fcf5ab3181a6\n\n# tcId = 2\n# Legacy:ASN encoding of r misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 30650230814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = MissingZero\n\n# tcId = 3\n# Legacy:ASN encoding of s misses leading 0\nmsg = 313233343030\nresult = acceptable\nsig = 3065023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2023084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = MissingZero\n\n# tcId = 4\n# valid\nmsg = 313233343030\nresult = valid\nsig = 3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 5\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308166023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 6\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 30820066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 7\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3067023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 8\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3065023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 9\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30850100000066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 10\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3089010000000000000066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 11\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 12\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 13\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 14\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 15\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 16\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 17\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3066028000814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 18\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202800084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 19\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 20\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 21\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3068023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 22\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 30680000023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 23\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 24\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 3068023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0500\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306b4981773066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a2500306602", "3100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30683066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0004deadbeef\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306b2236498177023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a22352500023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306e2233023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e20004deadbeef02310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 31\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306b023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2223649817702310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 32\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306a023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e22235250002310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 33\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 306e023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2223302310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0004deadbeef\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306eaa00bb00cd003066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306caa02aabb3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306e2239aa00bb00cd00023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 37\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306c2237aa02aabb023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 38\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306e023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e22239aa00bb00cd0002310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 39\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 306c023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e22237aa02aabb02310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 40\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 41\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30803066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 42\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 306a2280023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2000002310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 43\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 306a023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2228002310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 44\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30803166023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 45\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 306a2280033100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2000002310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 46\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 306a023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2228003310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\n\n# tcId = 47\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e66023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f66023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 50\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3166023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 51\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3266023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 52\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff66023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 53\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 54\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 306a30010230653100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 55\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 3065023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673", "854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7\n\n# tcId = 56\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 30653100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 57\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000\nflags = BER\n\n# tcId = 58\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd00\n\n# tcId = 59\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd05000000\n\n# tcId = 60\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd060811220000\n\n# tcId = 61\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0000fe02beef\n\n# tcId = 62\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 3080023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd0002beef\n\n# tcId = 63\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 30683000023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 64\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 3068023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd3000\n\n# tcId = 65\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 3069023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cdbf7f00\n\n# tcId = 66\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30683066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 67\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 3033023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2\n\n# tcId = 68\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 308199023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd02310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 69\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306702813100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 70\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3067023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e20281310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 71\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 30680282003100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 72\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3068023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2028200310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\nflags = BER\n\n# tcId = 73\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3066023200814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 74\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3066023000814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 75\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202320084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 76\n# wrong length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202300084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 77\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306b0285010000003100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 78\n# uint32 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306b023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e2028501000000310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 79\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306f028901000000000000003100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 80\n# uint64 overflow in length of integer\nmsg = 313233343030\nresult = invalid\nsig = 306f023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202890100000000000000310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 81\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 306a02847fffffff00814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd\n\n# tcId = 82\n# length of integer = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 306a023100814cc9a70febda342d4ada", @@ -3376,9 +4014,9 @@ static const char *kData121[] = { "11337e6af36ae0798c17043d79e8efcdae8e724adf96a2309207c2d2cfd88e8c483acb]\n[key.wx = 0081f92630778777a01781e7924fced35fc09018d9b00820881b14a814c1836a1f73c3641f7a17c821ffd95da902efe132]\n[key.wy = 221d81323509391f7b61bd796011337e6af36ae0798c17043d79e8efcdae8e724adf96a2309207c2d2cfd88e8c483acb]\n[keyDer = 3076301006072a8648ce3d020106052b810400220362000481f92630778777a01781e7924fced35fc09018d9b00820881b14a814c1836a1f73c3641f7a17c821ffd95da902efe132221d81323509391f7b61bd796011337e6af36ae0798c17043d79e8efcdae8e724adf96a2309207c2d2cfd88e8c483acb]\n[sha = SHA-512]\n\n# tcId = 420\n# extreme value for k\nmsg = 313233343030\nresult = valid\nsig = 3065023100aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab702300eb10e5ab95f2f26a40700b1300fb8c3e754d5c453d9384ecce1daa38135a48a0a96c24efc2a76d00bde1d7aeedf7f6a\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f]\n[key.wx = 00aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7]\n[key.wy = 3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f]\n[sha = SHA-512]\n\n# tcId = 421\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 3064023043f800fbeaf9238c58af795bcdad04bc49cd850c394d3382953356b023210281757b30e19218a37cbd612086fbc158ca02302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n# tcId = 422\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 3065023100bc07ff041506dc73a75086a43252fb43b6327af3c6b2cc7d322ff6d1d1162b5de29edcd0b69803fe2f8af8e3d103d0a902302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7c9e821b569d9d390a26167406d6d23d6070be242d765eb831625ceec4a0f473ef59f4e30e2817e6285bce2846f15f1a0]\n[key.wx = 00aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7]\n[key.wy = 00c9e821b569d9d390a26167406d6d23d6070be242d765eb831625ceec4a0f473ef59f4e30e2817e6285bce2846f15f1a0]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7c9e821b569d9d390a26167406d6d23d6070be242d765eb831625ceec4a0f473ef59f4e30e2817e6285bce2846f15f1a0]\n[sha = SHA-512]\n\n# tcId = 423\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 3064023043f800fbeaf9238c58af795bcdad04bc49cd850c394d3382953356b023210281757b30e19218a37cbd612086fbc158ca02302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n# tcId = 424\n# testing point duplication\nmsg = 313233343030\nresult = invalid\nsig = 3065023100bc07ff041506dc73a75086a43252fb43b6327af3c6b2cc7d322ff6d1d1162b5de29edcd0b69803fe2f8af8e3d103d0a902302492492492492492492492492492492492492492492492491c7be680477598d6c3716fabc13dcec86afd2833d41c2a7e\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[key.wx = 29bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc]\n[key.wy = 009a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[keyDer = 3076301006072a8648ce3d020106052b810400220362000429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3]\n[sha = SHA-512]\n\n# tcId = 425\n# pseudorandom signature\nmsg = \nresult = valid\nsig = 306402302290c886bbad8f53089583d543a269a727665626d6b94a3796324c62d08988f66f6011e845811a03589e92abe1f17faf023066e2cb4380997f4e7f85022541adb22d24d1196be68a3db888b03eb3d2d40b0d9a3a6a00a1a4782ee0a00e8410ba2d86\n\n# tcId = 426\n# pseudorandom signature\nmsg = 4d7367\nresult = valid\nsig = 30650231008071d8cf9df9efef696ebafc59f74db90c1f1ecf5ccde18858de22fe4d7df2a25cb3001695d706dfd7984b39df65a0f4023027291e6339c2a7fed7a174bb97ffe41d8cfdc20c1260c6ec85d7259f0cc7781bf2ae7a6e6fb4c08e0d75b7381bb7d9b8\n\n# tcId = 427\n# pseudorandom signature\nmsg = 313233343030\nresult = valid\nsig = 30650230470014ccd7a1a5e5333d301c8ea528ac3b07b01944af30cec60f4bad94db108509e45ba381818b5bdfaf9daf0d372301023100e3d49d6a05a755aa871d7cb96fffb79fed7625f83f69498ba07c0d65166a67107c9a17ae6e1028e244377a44096217b2\n\n# tcId = 428\n# pseudorandom signature\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 30640230377044d343f900175ac6833071be74964cd636417039e10e837da94b6919bffc3f5a517b945a450852af3259f5cbf108023032ea25006375c153581e80c09f53ad585c736f823c70147aba4fb47bb0a224fae4d8819adad80d4c144ecc2380954a9e\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aacacbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[key.wx = 00ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aac]\n[key.wy = 00acbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004ffffffffaa63f1a239ac70197c6ebfcea5756dc012123f82c51fa874d66028be00e976a1080606737cc75c40bdfe4aacacbd85389088a62a6398384c22b52d492f23f46e4a27a4724ad55551da5c483438095a247cb0c3378f1f52c3425ff9f1]\n[sha = SHA-512]\n\n# tcId = 429\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100ccb13c4dc9805a9b4e06ee25ef8c7593eaff7326c432d4b12b923163cf1cbe5fe1cfd3546c1d0761d8874e83ffd2e15d023100db1b0c082ae314b539f05e8a14ad51e5db37f29cacea9b2aab63a04917d58d008cf3f7ba41d5ea280f3b6a67be3ae8f8\n\n# tcId = 430\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100c79a30e36d2126b348dd9eb2f5db6aa98f79d80214027e51bcf3cabec188a7ebaf25cb7bbe9ec6bfed135e2a3b70e9160230241338ee2ac931adea9a56e7bfe909947128d54d5122a47b00c278e684e10102740d26e89e343290a5b2fa8b401faec6\n\n# tcId = 431\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 306402300df82e4ec2960e3df614f8b49cec9a4ee1054365414241361feec9d9d9b6909d8775f222ec385a14afab46266db390c302300968485e854addba0f8354e677e955e1ef2df973d564c49f65f2562cb2a2b80d75e92f8784042955f7b8765f609ce221\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[key.wx = 00d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422]\n[key.wy = 00c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004d1827fc6f6f12f21992c5a409a0653b121d2ef02b2b0ab01a9161ce956280740b1e356b255701b0a6ddc9ec2ca8a9422c6ed5d2ced8d8ab7560fa5bb88c738e74541883d8a2b1c0e2ba7e36d030fc4d9bfb8b22f24db897ebac49dd400000000]\n[sha = SHA-512]\n\n# tcId = 432\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 306402301fafd83d728422e1485f1e52e5b631548647cc3c76c109c3177a73751d91a19012fa4628b218f2229fc4d55f105fe00102304474f9af7b4b0bb96fdb05ae918f799024e8d5b86", "4e49ccd047cf97e7b9f8763cce015c11cf1f461c9027cb901055101\n\n# tcId = 433\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100e6025bb957ab197fb4c080d0a5c647e428afb0d7cc235c605ae97545494fd31a9979790bb2da6e1cf186789422b15c970231008ae9872291430d1bb371ef72360dad5afbb6fb001f403d9aaa1445f0326eb1eef775c9dfe1d7ef8bf4e744822108d27e\n\n# tcId = 434\n# y-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100877d5567c18fa568259005a89c2300d1b3825b732fa14964c1477d4b3098afd09384b97d497464adba41e9df8a74d339023100c40f0760717b4b3bae75742b6dc3dcf04cc22a449cfea19d305e0658cb705fda75163e7399e0b3125ca7d1919c13851e\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 041099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[key.wx = 1099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000]\n[key.wy = 00e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[keyDer = 3076301006072a8648ce3d020106052b81040022036200041099bb45100f55f5a85cca3de2b3bd5e250f4f6fad6631a3156c2e52a33d7d615dd279f79f8b4baff7c713ac00000000e6c9b736a8929f2ed7be0c753a54cbb48b8469e0411eaf93a4a82459ba0b681bba8f5fb383b4906d4901a3303e2f1557]\n[sha = SHA-512]\n\n# tcId = 435\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100e706b0045a6f54bd175e2437b48767b0204f93d8a4d9d3d00838278137e5b670de4305c5c55e49059b8b5f6e264654c90230405741adff94afd9a88e08d0b1021911fa4cedb2466b1a8fd302a5b5d96566ada63ccb82b6c5e8452fde860c545e0a19\n\n# tcId = 436\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 306502300c57ce2bc579fbd3a759dfbf5e84c3cef2414846a2e300453e1e4c5188f24432b14ca647a733b6ad35c980a880d36145023100f12a119e22d48b82049df611f1c851fb22795056498a873c730fcb9fd8f314728de0298b9b22c348abc6de2aba97e972\n\n# tcId = 437\n# x-coordinate of the public key has many trailing 0's\nmsg = 4d657373616765\nresult = valid\nsig = 30660231009a8f80697ccf2e0617612027d861a3a3a657fb75cc82810b40dd5072d39ff37eca29008390da356137e2c9babd814198023100a86537a83c3d57da50e4b29b47dcc3717c5a1ed0fff18ade8dcce4220eac63aab60b9bfed5f1bdd241dab655a9bdd75f\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04000000002b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[key.wx = 2b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69]\n[key.wy = 00d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004000000002b089edd754169010145f263f334fc167cc19dae8225970ae19cc8cb7ec73593d6a465c370f5478b0e539d69d1951d597b56a67345acb25809581f07cd0eb78d9538a3f8a65f300e68a1eb78507df76de650e8f8ee63a5f0c5687c98]\n[sha = SHA-512]\n\n# tcId = 438\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 306602310093718f6f8542725f62de7039fc193d3fcc81d622230ccc94e9e265390b385af3a3ba50c91a9d6a5b1e07d79af2bd80b2023100d08499f3d298e8afecea122265a36dbf337259020654739783c8ec8ef783d072555b5907285ce83fc8ced9c8398c6269\n\n# tcId = 439\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100ce26e42c490dec92cf59d6b1ba75c9a1400d6e5c3fd7c47e1eeb1cded30a3a3d18c81cdfdcbad2742a97293369ce21c202310094671085d941fd27d495452a4c8559a1fe24f3225f5b8ef75faf9d3fb01372c586e23b82714359d0e47144ff5d946161\n\n# tcId = 440\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100ffc4738acf71f04a13104c328c138b331fb7202aef66f583ba543ed490d12993c18f724c81ad0f7ea18dae352e5c6480023100e67d4ccdeb68a9a731f06f77eae00175be076d92529b109a62542692c8749ddfde03bed1c119a5901a4e852f2115578f\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b33600000000208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[key.wx = 00fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336]\n[key.wy = 208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b33600000000208b3f5ad3b3937acc9d606cc5ececab4a701f75ed42957ea4d7858d33f5c26c6ae20a9cccda56996700d6b4]\n[sha = SHA-512]\n\n# tcId = 441\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100e6fa8455bc14e730e4ca1eb5faf6c8180f2f231069b93a0bb17d33ad5513d93a36214f5ce82ca6bd785ccbacf7249a4c02303979b4b480f496357c25aa3fc850c67ff1c5a2aabd80b6020d2eac3dd7833cf2387d0be64df54a0e9b59f12c3bebf886\n\n# tcId = 442\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 306502301b49b037783838867fbaa57305b2aa28df1b0ec40f43140067fafdea63f87c02dfb0e6f41b760fbdf51005e90c0c3715023100e7d4eb6ee61611264ea8a668a70287e3d63489273da2b30ad0c221f1893feaea3e878c9a81c6cec865899dbda4fa79ae\n\n# tcId = 443\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 306502310091d9da3d577408189dcaae33d95ed0a0118afd460d5228fa352b6ea671b172eb413816a70621ddaf23c5e2ef79df0c110230053dadbfcd564bddbe44e0ecb4d1e608dbd35d4e83b6634cc72afb87a2d61675ee13960c243f6be70519e167b1d3ceb0\n\n[key.curve = secp384r1]\n[key.keySize = 384]\n[key.type = EcPublicKey]\n[key.uncompressed = 04fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[key.wx = 00fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336]\n[key.wy = 00ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[keyDer = 3076301006072a8648ce3d020106052b8104002203620004fb01baad5f0b8f79b9cd104d12aab9310146add7d6b4c022d87ae6711178b94d618ca7b3af13854b1c588879e877b336ffffffffdf74c0a52c4c6c8533629f933a131354b58fe08a12bd6a815b287a71cc0a3d92951df5633325a96798ff294b]\n[sha = SHA-512]\n\n# tcId = 444\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3065023100af0ed6ce6419662db80f02a2b632675445c7bf8a34bbacdc81cc5dd306c657ca4c5a3fb1b05f358d8f36fda8ae238806023046b472c0badb17e089c8f9697fd0b4ce71f0f4471b235483d4c8dd3d00aa282cde990253df38ba733b2ad82a601c7508\n\n# tcId = 445\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 3066023100e2aa9468ccaaadad8b9f43a429c97f0c6a7eedcb4d4af72d639df0fe53f610b953408a8e24e8db138551770750680f7a023100d81020846d1c50ee9ae23601dd638cb71b38d37fb555268c2fa1ad8a761fa7b27afcab2fa69224d1f976699914e09de2\n\n# tcId = 446\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 306402306bf6fa7a663802c3382cc5fd02004ec71e5a031e3d9bfc0858fa994e88497a7782308bc265b8237a6bbbdd38658b36fc02303a9d5941a013bf70d99cc3ff255ce85573688dac40344b5db7144b19bf57bb2701e6850a8f819796b67f7d0b6aea7e50\n\n", }; -static const size_t kLen122 = 225135; +static const size_t kLen176 = 225135; -static const char *kData122[] = { +static const char *kData176[] = { "# Imported from Wycheproof's ecdsa_secp521r1_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: ECDSA\n# Generator version: 0.8r12\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 04005c6457ec088d532f482093965ae53ccd07e556ed59e2af945cd8c7a95c1c644f8a56a8a8a3cd77392ddd861e8a924dac99c69069093bd52a52fa6c56004a074508007878d6d42e4b4dd1e9c0696cb3e19f63033c3db4e60d473259b3ebe079aaf0a986ee6177f8217a78c68b813f7e149a4e56fd9562c07fed3d895942d7d101cb83f6]\n[key.wx = 5c6457ec088d532f482093965ae53ccd07e556ed59e2af945cd8c7a95c1c644f8a56a8a8a3cd77392ddd861e8a924dac99c69069093bd52a52fa6c56004a074508]\n[key.wy = 7878d6d42e4b4dd1e9c0696cb3e19f63033c3db4e60d473259b3ebe079aaf0a986ee6177f8217a78c68b813f7e149a4e56fd9562c07fed3d895942d7d101cb83f6]\n[keyDer = 30819b301006072a8648ce3d020106052b810400230381860004005c6457ec088d532f482093965ae53ccd07e556ed59e2af945cd8c7a95c1c644f8a56a8a8a3cd77392ddd861e8a924dac99c69069093bd52a52fa6c56004a074508007878d6d42e4b4dd1e9c0696cb3e19f63033c3db4e60d473259b3ebe079aaf0a986ee6177f8217a78c68b813f7e149a4e56fd9562c07fed3d895942d7d101cb83f6]\n[sha = SHA-512]\n\n# tcId = 1\n# signature malleability\nmsg = 313233343030\nresult = valid\nsig = 30818702414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024201d74a2f6d95be8d4cb64f02d16d6b785a1246b4ebd206dc596818bb953253245f5a27a24a1aae1e218fdccd8cd7d4990b666d4bf4902b84fdad123f941fe906d948\n\n# tcId = 2\n# valid\nmsg = 313233343030\nresult = valid\nsig = 30818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 3\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 3082008602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\nflags = BER\n\n# tcId = 4\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308702414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 5\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308502414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 6\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3085010000008602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 7\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 308901000000000000008602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 8\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 30847fffffff02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 9\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3084ffffffff02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 10\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3085ffffffffff02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 11\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3088ffffffffffffffff02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 12\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30ff02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 13\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 14\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 30818602804e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 15\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 30818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645028028b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 16\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 17\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 30\n\n# tcId = 18\n# appending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818802414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 19\n# prepending 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 308188000002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 20\n# appending unused 0's to sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 21\n# appending null value to sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818802414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df92", "3a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10500\n\n# tcId = 22\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818c49817730818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 23\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818b250030818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 24\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818930818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10004deadbeef\n\n# tcId = 25\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818b224649817702414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 26\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818a2245250002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 27\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818e224302414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450004deadbeef024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 28\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818b02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452246498177024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 29\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818a02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf864522452500024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 30\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 30818e02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452243024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10004deadbeef\n\n# tcId = 31\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818faa00bb00cd0030818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 32\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818daa02aabb30818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 33\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818e2249aa00bb00cd0002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 34\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818c2247aa02aabb02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 35\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818e02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452249aa00bb00cd00024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 36\n# including undefined tags\nmsg = 313233343030\nresult = invalid\nsig = 30818c02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452247aa02aabb024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 37\n# truncated length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081\n\n# tcId = 38\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 308030818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 39\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30818a228002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450000024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 40\n# using composition with indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 30818a02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452280024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 41\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 308031818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 42\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30818a228003414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450000024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 43\n# using composition with wrong tag\nmsg = 313233343030\nresult = invalid\nsig = 30818a02414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86452280034128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\n\n# tcId = 44\n# Replacing sequence with NULL\nmsg = 313233343030\nresult = invalid\nsig = 0500\n\n# tcId = 45\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2e818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf", "8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 46\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2f818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 47\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 31818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 48\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 32818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 49\n# changing tag value of sequence\nmsg = 313233343030\nresult = invalid\nsig = ff818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 50\n# dropping value of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3000\n\n# tcId = 51\n# using composition for sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818b300102308185414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 52\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818502414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318a\n\n# tcId = 53\n# truncated sequence\nmsg = 313233343030\nresult = invalid\nsig = 308185414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 54\n# indefinite length\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000\nflags = BER\n\n# tcId = 55\n# indefinite length with truncated delimiter\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac100\n\n# tcId = 56\n# indefinite length with additional element\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac105000000\n\n# tcId = 57\n# indefinite length with truncated element\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1060811220000\n\n# tcId = 58\n# indefinite length with garbage\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10000fe02beef\n\n# tcId = 59\n# indefinite length with nonempty EOC\nmsg = 313233343030\nresult = invalid\nsig = 308002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac10002beef\n\n# tcId = 60\n# prepend empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 308188300002414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 61\n# append empty sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818802414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac13000\n\n# tcId = 62\n# append garbage with high tag number\nmsg = 313233343030\nresult = invalid\nsig = 30818902414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1bf7f00\n\n# tcId = 63\n# sequence of sequence\nmsg = 313233343030\nresult = invalid\nsig = 30818930818602414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 64\n# truncated sequence: removed last 1 elements\nmsg = 313233343030\nresult = invalid\nsig = 304302414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645\n\n# tcId = 65\n# repeating element in sequence\nmsg = 313233343030\nresult = invalid\nsig = 3081c902414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\n\n# tcId = 66\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 3081870281414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf8645024128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\nflags = BER\n\n# tcId = 67\n# long form encoding of length of integer\nmsg = 313233343030\nresult = invalid\nsig = 30818702414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf864502814128b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1\nflags = BER\n\n# tcId = 68\n# length of integer contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 308188028200414e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf", @@ -3408,9 +4046,9 @@ static const char *kData122[] = { "bfc9b045f8a55e1b6a5fe1512c400c4bc9c86fd7c699d642f5cee9bb827c8b0abc0da01cef1e]\n[sha = SHA-512]\n\n# tcId = 429\n# pseudorandom signature\nmsg = \nresult = valid\nsig = 308188024201625d6115092a8e2ee21b9f8a425aa73814dec8b2335e86150ab4229f5a3421d2e6256d632c7a4365a1ee01dd2a936921bbb4551a512d1d4b5a56c314e4a02534c5024201b792d23f2649862595451055777bda1b02dc6cc8fef23231e44b921b16155cd42257441d75a790371e91819f0a9b1fd0ebd02c90b5b774527746ed9bfe743dbe2f\n\n# tcId = 430\n# pseudorandom signature\nmsg = 4d7367\nresult = valid\nsig = 30818602415adc833cbc1d6141ced457bab2b01b0814054d7a28fa8bb2925d1e7525b7cf7d5c938a17abfb33426dcc05ce8d44db02f53a75ea04017dca51e1fbb14ce3311b1402415f69b2a6de129147a8437b79c72315d35173d88c2d6119085c90dae8ec05c55e067e7dfa4f681035e3dccab099291c0ecf4428332a9cb0736d16e79111ac76d766\n\n# tcId = 431\n# pseudorandom signature\nmsg = 313233343030\nresult = valid\nsig = 3081880242014141e4d94a58c1e747cbd9ee6670a41eac3c26fb4db3248e45d583179076e6b19a8e2003657a108f91f9a103157edff9b37df2b436a77dc112927d907ac9ba258702420108afa91b34bd904c680471e943af336fb90c5fb2b91401a58c9b1f467bf81af8049965dd8b45f12e152f4f7fd3780e3492f31ed2680d4777fbe655fe779ad897ab\n\n# tcId = 432\n# pseudorandom signature\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 308187024108135d3f1ae9e26fba825643ed8a29d63d7843720e93566aa09db2bdf5aaa69afbcc0c51e5295c298f305ba7b870f0a85bb5699cdf40764aab59418f77c6ffb4520242011d345256887fb351f5700961a7d47572e0d669056cb1d5619345c0c987f3331c2fe2c6df848a5c610422defd6212b64346161aa871ae55b1fe4add5f68836eb181\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a00000000009b98bfd33398c2cf8606fc0ae468b6d617ccb3e704af3b8506642a775d5b4da9d00209364a9f0a4ad77cbac604a015c97e6b5a18844a589a4f1c7d9625]\n[key.wx = 304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a]\n[key.wy = 009b98bfd33398c2cf8606fc0ae468b6d617ccb3e704af3b8506642a775d5b4da9d00209364a9f0a4ad77cbac604a015c97e6b5a18844a589a4f1c7d9625]\n[keyDer = 30819b301006072a8648ce3d020106052b81040023038186000400304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a00000000009b98bfd33398c2cf8606fc0ae468b6d617ccb3e704af3b8506642a775d5b4da9d00209364a9f0a4ad77cbac604a015c97e6b5a18844a589a4f1c7d9625]\n[sha = SHA-512]\n\n# tcId = 433\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3081870242011c9684af6dc52728410473c63053b01c358d67e81f8a1324ad711c60481a4a86dd3e75de20ca55ce7a9a39b1f82fd5da4fadf26a5bb8edd467af8825efe4746218024134c058aba6488d6943e11e0d1348429449ea17ac5edf8bcaf654106b98b2ddf346c537b8a9a3f9b3174b77637d220ef5318dbbc33d0aac0fe2ddeda17b23cb2de6\n\n# tcId = 434\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 30818702417c47a668625648cd8a31ac92174cf3d61041f7ad292588def6ed143b1ff9a288fd20cf36f58d4bfe4b2cd4a381d4da50c8eda5674f020449ae1d3dd77e44ed485e024201058e86b327d284e35bab49fc7c335417573f310afa9e1a53566e0fae516e099007965030f6f46b077116353f26cb466d1cf3f35300d744d2d8f883c8a31b43c20d\n\n# tcId = 435\n# y-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 308188024201e4e9f3a7b800de63407b8703ac545226541c97a673566711f70e2b9ccb21a145ad4637825b023d1ea9f18e60897413711611a85c1179bff9c107368f1c1b61c24c024201de948ee577c3d4e4122a52ecccac59abb6fa937dfb3e4b988cb243efe98740309452ba013112b225b3b1b1384d5f68796845199a2602a8d4505a331b07d101188e\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a01ffffffff6467402ccc673d3079f903f51b974929e8334c18fb50c47af99bd588a2a4b2562ffdf6c9b560f5b528834539fb5fea368194a5e77bb5a765b0e38269da]\n[key.wx = 304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a]\n[key.wy = 01ffffffff6467402ccc673d3079f903f51b974929e8334c18fb50c47af99bd588a2a4b2562ffdf6c9b560f5b528834539fb5fea368194a5e77bb5a765b0e38269da]\n[keyDer = 30819b301006072a8648ce3d020106052b81040023038186000400304b3d071ed1ef302391b566af8c9d1cb7afe9aabc141ac39ab39676c63e48c1b2c6451eb460e452bd573e1fb5f15b8e5f9c03f634d8db6897285064b3ce9bd98a01ffffffff6467402ccc673d3079f903f51b974929e8334c18fb50c47af99bd588a2a4b2562ffdf6c9b560f5b528834539fb5fea368194a5e77bb5a765b0e38269da]\n[sha = SHA-512]\n\n# tcId = 436\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 308187024200b6cf64861a2b16e33976095dbf45a592c7c24228c4a1dd727f303d5eeb87e5388ad05c328f824c40abd3e6ce003fef5cd59dee0069ad6348ea6e57f90f6bdc0a820241228181c180366e5451dfef3593ce664804cb42d5a8d5046b816b3daf6602fafd9ac2dc24b8c93a10024480882558b6ad3d9e905923dcd0fd2a11964754a9b46b8f\n\n# tcId = 437\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30818802420093c8f766827d6dc15c810fa30433153a5e742859205ee8389fbf695c8840dc917440870acc5b160087ffd0cd9a6081029c60a7c26d5e8aa9a0570f4efdeb13dea20242012ec3bbf75a0ad3df40310266648a36db820217ed7fa94e9c8313e03293ef4f6a40e736fb8f208ad8fb883ca509d48046910523645459c27829d54431463b2548c7\n\n# tcId = 438\n# y-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30818802420152388c6da66164b706b41dd4dd48176d6eaf6525f876ef0ff2d147f6966ebfadf1767fa66d04203d3ec9c937a1f0c945aed953e34be444c219fd3b94d3277aa652024201658c1e5b2e563a49d11c883d05c491d628f0a92c3e3dc8db9a4c8d5f0dc846ac22af8b3c5fb5bbe2cfa98614dcffd87de1cee2c5912a5899505a0c5bcaa513e2c6\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 040000000002fba6a061201ea6b1ed4265163568735ebab78600cdf6a71101dc63beaf546d97a214fc6396793b014eb1aa7a728f53deb2ff9999a3808ddfed15e9629b01993852dadc39299a5a45b6bd7c8dc8ec67e7adbb359fa8fa5d44977e15e2e5a9acf0c33645f3f2c68c526e07732fb35043719cfafc16063c8e58850a958436a4e5]\n[key.wx = 02fba6a061201ea6b1ed4265163568735ebab78600cdf6a71101dc63beaf546d97a214fc6396793b014eb1aa7a728f53deb2ff9999a3808ddfed15e9629b]\n[key.wy = 01993852dadc39299a5a45b6bd7c8dc8ec67e7adbb359fa8fa5d44977e15e2e5a9acf0c33645f3f2c68c526e07732fb35043719cfafc16063c8e58850a958436a4e5]\n[keyDer = 30819b301006072a8648ce3d020106052b8104002303818600040000000002fba6a061201ea6b1ed4265163568735ebab78600cdf6a71101dc63beaf546d97a214fc6396793b014eb1aa7a728f53deb2ff9999a3808ddfed15e9629b01993852dadc39299a5a45b6bd7c8dc8ec67e7adbb359fa8fa5d44977e15e2e5a9acf0c33645f3f2c68c526e07732fb35043719cfafc16063c8e58850a958436a4e5]\n[sha = SHA-512]\n\n# tcId = 439\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3081880242010e89470f981d2c7c5c96587121a67323bb96ff2427739d0d885ea277293efa3b25c0bda04d81466198a3cbfc441f1b1b98f6bcdc2589d9d91a17a7899f70d0461e0242017351b0da8c8d0e4aa0974669d190fa2f90aa50227160594dfb55755002365441de17ea42902128a6f81e554177ed509c0cec31fd5053fae03f62ff76579ba92bda\n\n# tcId = 440\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 3081880242011094ac23ca46a3e2b4ac3baae6504f1bfb3ddf2db9ab40eda32d8e0a05727998f8552a033bb05241e826a86a1d03014eae3aa5fe1a45caac1db3e8138b9cf5906802420147edb15a5080ee2f929f78b6ac86604aae51b674fa46eaae7fdfd90bf64d6189341155f4eba937eae74c9e480eb4fb7e6aafd4285e7fc503ee6ec20f0b1415be06\n\n# tcId = 441\n# x-coordinate of the public key is small\nmsg = 4d657373616765\nresult = valid\nsig = 308188024201d876ae174da31e128babff9f1d15507660bdc7958750844dc4f4291f75a882a22f177f704be6067bf7ce8f06b8626d971e6ef5dcb666fa975c1e11126e04fccce2024201abb12630a68b669e6ad2d8d62654d75dfbc6b54a8e3a9c915be663e080ddcc348e57a10e2b1dd9f03e1b897796ad889b075e5919dc5bf37a112d92c693456e6457\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 0401fffffffe1d5d52b31ca52f8947a35593edf164cd324f833b90935846c64db1454df9f028dc8bc36bb04cb7f0cceceba01a3844097f7c35eeaa81428db0cca6333101b7c70277d0bf78a3c7b62c937f0cb2cad2565f5514f6205ceb1a193d4fdb45ba6e6cec07827bae0b16b8316c3539a15114d", "0de6d2de407fd7117551a70826eada6]\n[key.wx = 01fffffffe1d5d52b31ca52f8947a35593edf164cd324f833b90935846c64db1454df9f028dc8bc36bb04cb7f0cceceba01a3844097f7c35eeaa81428db0cca63331]\n[key.wy = 01b7c70277d0bf78a3c7b62c937f0cb2cad2565f5514f6205ceb1a193d4fdb45ba6e6cec07827bae0b16b8316c3539a15114d0de6d2de407fd7117551a70826eada6]\n[keyDer = 30819b301006072a8648ce3d020106052b81040023038186000401fffffffe1d5d52b31ca52f8947a35593edf164cd324f833b90935846c64db1454df9f028dc8bc36bb04cb7f0cceceba01a3844097f7c35eeaa81428db0cca6333101b7c70277d0bf78a3c7b62c937f0cb2cad2565f5514f6205ceb1a193d4fdb45ba6e6cec07827bae0b16b8316c3539a15114d0de6d2de407fd7117551a70826eada6]\n[sha = SHA-512]\n\n# tcId = 442\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 30818602414ed692af1ed1b4bd5cea3aa8ddc6f3f15d8a6ee0016fa0e8eb958580e7421832ecc0e387c34aafac6380bac419ea45c42ae6426af503847f22c49c2f456338c1a702417aceadde02ace1668bc1a3360d34e125afde230f536c154d91e6c876bee1d34ae06edcbbca0c7cd17646840913164740b12e2e224fe3ef3dec6fd84a81b581c188\n\n# tcId = 443\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 308188024200e01094048fcf7a1e2ec66faedffc40f48c9c93514325bde6b4958d80f0413efde7eec1dc6de65f96009c069397e51da2eb1729efa287afd5552b25a9e427a6d836024201489e7e124f66942e642de992e60b3a86fcce576767719390c3a312fcdeaa560a7fbb0cabb35e05a6d6f3499160fd2dba12d29b613b16dec7494c950d65fdf11fa3\n\n# tcId = 444\n# x-coordinate of the public key is large\nmsg = 4d657373616765\nresult = valid\nsig = 308188024201d296292213380de133dc66eceb8bd857a5c468afe855c05da9db937373b51f9020ca11353415da76bb6af997a486d2370e31adcc0a4531952a3b59428678ee59430242015979a3c609c2c2099ae1b290da3d613b248e3a10de7ad770dffc82fb33e74fc3207533f97285cf4557a6407e9a775e59efeaee4264b2634933a6baf8c406f0c4a9\n\n[key.curve = secp521r1]\n[key.keySize = 521]\n[key.type = EcPublicKey]\n[key.uncompressed = 0400c7c8817bf2f0652a4a4b5140c773e261080a0a111395856e8a3350f5eb5612bd63b367b965e92e9538ea3b7908aef1ade4b68e17f9f9148495c167d1c4dd4913490008bf0be2979abb8111fd0d768adcad774113a822c1bb60887053b5cf8c9563e76705a391ece154b5dfb114b20e351df4014bec19fa87720845801cf06b7fffffff]\n[key.wx = 00c7c8817bf2f0652a4a4b5140c773e261080a0a111395856e8a3350f5eb5612bd63b367b965e92e9538ea3b7908aef1ade4b68e17f9f9148495c167d1c4dd491349]\n[key.wy = 08bf0be2979abb8111fd0d768adcad774113a822c1bb60887053b5cf8c9563e76705a391ece154b5dfb114b20e351df4014bec19fa87720845801cf06b7fffffff]\n[keyDer = 30819b301006072a8648ce3d020106052b81040023038186000400c7c8817bf2f0652a4a4b5140c773e261080a0a111395856e8a3350f5eb5612bd63b367b965e92e9538ea3b7908aef1ade4b68e17f9f9148495c167d1c4dd4913490008bf0be2979abb8111fd0d768adcad774113a822c1bb60887053b5cf8c9563e76705a391ece154b5dfb114b20e351df4014bec19fa87720845801cf06b7fffffff]\n[sha = SHA-512]\n\n# tcId = 445\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 308188024201ef8f785c51a25ae2cd93487b5c848d4af133217a91f51359c966e7538e68743578122df5830002f96f6fadb5bc44480e3b3b2c804e4c51cf95d059d5646c5cef21024201ba2276cc003e87bea37c3724e58a0ab885f56d09b8b5718f674f9c70f3b5ecfb4ad1f3417b420ec40810e08826efa7d8ad6ca7c6a7840348097f92b2de8d6e080b\n\n# tcId = 446\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 30818802420155978adc4b570d897511f5ecfb65a31947e6e989da17dea716625bb3fa7b92b853623eb0cd9ce2a5e2b4d8c1c2a90ec04fe79d012576ec728a45c5ce47c6d500c0024200f79fa8b94ee282a3d1815892cbf15d7ebdf62cb042c76bb3c710c23e32b75992cc249d84072198e4ed63d72435a07d2ed76f278d7399f61a5b5c997f45692fed22\n\n# tcId = 447\n# y-coordinate of the public key has many trailing 1's\nmsg = 4d657373616765\nresult = valid\nsig = 308188024201a2af29c58184ca861e7cd931f39cea064b199eee563f241cd5ecf6ebb2ade728f1be23cf007ebe8ef0c42d99f9f5190f6815446afc3043a820d7daf27e86b83b8a024201a2acd1822eb539383defff8769aad8bacd50cd24ca7aa6670671418110177808c3f4fbe6041b9cb898359ee61e04824adedd62b39fe5791907a20586333bd3c76d\n\n", }; -static const size_t kLen123 = 52032; +static const size_t kLen177 = 52032; -static const char *kData123[] = { +static const char *kData177[] = { "# Imported from Wycheproof's eddsa_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: EDDSA\n# Generator version: 0.8rc16\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa]\n[key.sk = add4bb8103785baf9ac534258e8aaf65f5f1adb5ef5f3df19bb80ab989c4d64b]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321007d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = d4fbdb52bfa726b44d1786a8c0d171c3e62ca83c9e5bbe63de0bb2483f8fd6cc1429ab72cafc41ab56af02ff8fcc43b99bfe4c7ae940f60f38ebaa9d311c4007\n\n# tcId = 2\nmsg = 78\nresult = valid\nsig = d80737358ede548acb173ef7e0399f83392fe8125b2ce877de7975d8b726ef5b1e76632280ee38afad12125ea44b961bf92f1178c9fa819d020869975bcbe109\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d\n\n# tcId = 4\nmsg = 48656c6c6f\nresult = valid\nsig = 1c1ad976cbaae3b31dee07971cf92c928ce2091a85f5899f5e11ecec90fc9f8e93df18c5037ec9b29c07195ad284e63d548cd0a6fe358cc775bd6c1608d2c905\n\n# tcId = 5\nmsg = 313233343030\nresult = valid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bf0cf5b3a289976458a1be6277a5055545253b45b07dcc1abd96c8b989c00f301\n\n# tcId = 6\nmsg = 000000000000000000000000\nresult = valid\nsig = d46543bfb892f84ec124dcdfc847034c19363bf3fc2fa89b1267833a14856e52e60736918783f950b6f1dd8d40dc343247cd43ce054c2d68ef974f7ed0f3c60f\n\n# tcId = 7\nmsg = 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161\nresult = valid\nsig = 879350045543bc14ed2c08939b68c30d22251d83e018cacbaf0c9d7a48db577e80bdf76ce99e5926762bc13b7b3483260a5ef63d07e34b58eb9c14621ac92f00\n\n# tcId = 8\nmsg = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60\nresult = valid\nsig = 7bdc3f9919a05f1d5db4a3ada896094f6871c1f37afc75db82ec3147d84d6f237b7e5ecc26b59cfea0c7eaf1052dc427b0f724615be9c3d3e01356c65b9b5109\n\n# tcId = 9\nmsg = ffffffffffffffffffffffffffffffff\nresult = valid\nsig = 5dbd7360e55aa38e855d6ad48c34bd35b7871628508906861a7c4776765ed7d1e13d910faabd689ec8618b78295c8ab8f0e19c8b4b43eb8685778499e943ae04\n\n# tcId = 10\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 11\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 12\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 13\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 14\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\n\n# tcId = 15\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 16\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 01000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 17\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0100000000000000000000000000000000000000000000000000000000000000ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 18\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0100000000000000000000000000000000000000000000000000000000000000edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 19\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = 0100000000000000000000000000000000000000000000000000000000000000edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\n\n# tcId = 20\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edd3f55c1a631258d69cf7a2def9de14000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 21\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edd3f55c1a631258d69cf7a2def9de14000000000000000000000000000000100100000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 22\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 23\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 24\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\n\n# tcId = 25\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 26\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0100000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 27\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 28\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fedd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010\n\n# tcId = 29\n# special values for r and s\nmsg = 3f\nresult = invalid\nsig = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\n\n# tcId = 30\n# empty signature\nmsg = 54657374\nresult = invalid\nsig = \n\n# tcId = 31\n# s missing\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0\n\n# tcId = 32\n# signature too short\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946\n\n# tcId = 33\n# signature too long\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d2020\n\n# tcId = 34\n# include pk in signature\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa\n\n# tcId = 35\n# prepending 0 byte to signature\nmsg = 54657374\nresult = invalid\nsig = 007c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d\n\n# tcId = 36\n# prepending 0 byte to s\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0007a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d\n\n# tcId = 37\n# appending 0 byte to signature\nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d00\n\n# tcId = 38\n# removing 0 byte from signature\nmsg = 546573743137\nresult = invalid\nsig = 93de3ca252426c95f735cb9edd92e83321ac62372d5aa5b379786bae111ab6b17251330e8f9a7c30d6993137c596007d7b001409287535ac4804e662bc58a3\n\n# tcId = 39\n# removing 0 byte from signature\nm", "sg = 54657374313236\nresult = invalid\nsig = dffed33a7f420b62bb1731cfd03be805affd18a281ec02b1067ba6e9d20826569e742347df59c88ae96db1f1969fb189b0ec34381d85633e1889da48d95e0e\n\n# tcId = 40\n# removing leading 0 byte from signature\nmsg = 546573743530\nresult = invalid\nsig = 6e170c719577c25e0e1e8b8aa7a6346f8b109f37385cc2e85dc3b4c0f46a9c6bcafd67f52324c5dbaf40a1b673fb29c4a56052d2d6999d0838a8337bccb502\n\n# tcId = 41\n# dropping byte from signature\nmsg = 54657374333437\nresult = invalid\nsig = b0928b46e99fbbad3f5cb502d2cd309d94a7e86cfd4d84b1fcf4cea18075a9c36993c0582dba1e9e519fae5a8654f454201ae0c3cb397c37b8f4f8eef18400\n\n# tcId = 42\n# modified bit 0 in R\nmsg = 313233343030\nresult = invalid\nsig = 647c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b1d125e5538f38afbcc1c84e489521083041d24bc6240767029da063271a1ff0c\n\n# tcId = 43\n# modified bit 1 in R\nmsg = 313233343030\nresult = invalid\nsig = 677c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bc108ca4b87a49c9ed2cf383aecad8f54a962b2899da891e12004d7993a627e01\n\n# tcId = 44\n# modified bit 2 in R\nmsg = 313233343030\nresult = invalid\nsig = 617c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b9ce23fc6213ed5b87912e9bbf92f5e2c780eae26d15c50a112d1e97d2ea33c06\n\n# tcId = 45\n# modified bit 7 in R\nmsg = 313233343030\nresult = invalid\nsig = e57c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bbb3eb51cd98dddb235a5f46f2bded6af184a58d09cce928bda43f41d69118a03\n\n# tcId = 46\n# modified bit 8 in R\nmsg = 313233343030\nresult = invalid\nsig = 657d1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bcd237dda9a116501f67a5705a854b9adc304f34720803a91b324f2c13e0f5a09\n\n# tcId = 47\n# modified bit 16 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1592402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b6b167bbdc0d881cc04d28905552c1876f3709851abc5007376940cc8a435c300\n\n# tcId = 48\n# modified bit 31 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1412402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b7fd2ac7da14afffcceeb13f2a0d6b887941cb1a5eb57a52f3cb131a16cce7b0e\n\n# tcId = 49\n# modified bit 32 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492412ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b7373ba13ebbef99cd2a8ead55ce735c987d85a35320925a8e871702dc7c5c40d\n\n# tcId = 50\n# modified bit 63 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab54e03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bd35bd331c03f0855504ca1cab87b83c36a028425a3cf007ede4f4254c261cb00\n\n# tcId = 51\n# modified bit 64 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce02e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bcb35101f73cf467deac8c1a03b6c3dc35af544132734b7e57ab20c89b2e4750d\n\n# tcId = 52\n# modified bit 97 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f2384d051b9cf3570f1207fc78c1bcc98c281c2bb58d2e8878290bff8d3355fdd4ea381924ee578752354eb6dee678ab4011c301\n\n# tcId = 53\n# modified bit 127 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d851b9cf3570f1207fc78c1bcc98c281c2bb978c866187ffb1cc7b29a0b4045aefc08768df65717194ff0c6e63f4dea0d02\n\n# tcId = 54\n# modified bit 240 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281d2b0576ecf8eaf675f00f3dfbe19f75b83b7607a6c96414f6821af920a2498d0305\n\n# tcId = 55\n# modified bit 247 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c289c2be5241a345c7b5428054c74b7c382fa10d4a5f1e8f8b79a71d3fdea2254f1ff0e\n\n# tcId = 56\n# modified bit 248 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2a63950c85cd6dc96364e768de50ff7732b538f8a0b1615d799190ab600849230e\n\n# tcId = 57\n# modified bit 253 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c0b543bd3da0a56a8c9c152f59c9fec12f31fa66434d48b817b30d90cb4efa8b501\n\n# tcId = 58\n# modified bit 254 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c6b8da07efd07a6dafb015ed6a32fe136319a972ffbc341f3a0beae97ccf8136505\n\n# tcId = 59\n# modified bit 255 in R\nmsg = 313233343030\nresult = invalid\nsig = 657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281cab227aedf259f910f0f3a759a335062665217925d019173b88917eae294f75d40f\n\n# tcId = 60\n# R==0\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000e0b8e7770d51c7a36375d006c5bffd6af43ff54aaf47e4330dc118c71d61ec02\n\n# tcId = 61\n# invalid R\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff463a1908382e7eb7693acef9884f7cf931a215e0791876be22c631a59881fd0e\n\n# tcId = 62\n# all bits flipped in R\nmsg = 313233343030\nresult = invalid\nsig = 9a83eb6dbfd54a31fc1d3c580fc7b2fae4630ca8f0edf803873e433673d7e3d40e94254586cb6188c5386c3febed477cb9a6cb29e3979adc4cb27cf5278fb70a\n\n# tcId = 63\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab067654bce3832c2d76f8f6f5dafc08d9339d4eef676573336a5c51eb6f946b31d\nflags = SignatureMalleability\n\n# tcId = 64\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab05439412b5395d42f462c67008eba6ca839d4eef676573336a5c51eb6f946b32d\nflags = SignatureMalleability\n\n# tcId = 65\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab02ee12ce5875bf9dff26556464bae2ad239d4eef676573336a5c51eb6f946b34d\nflags = SignatureMalleability\n\n# tcId = 66\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0e2300459f1e742404cd934d2c595a6253ad4eef676573336a5c51eb6f946b38d\nflags = SignatureMalleability\n\n# tcId = 67\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b32d\nflags = SignatureMalleability\n\n# tcId = 68\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b34d\nflags = SignatureMalleability\n\n# tcId = 69\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b38d\nflags = SignatureMalleability\n\n# tcId = 70\n# checking malleability \nmsg = 54657374\nresult = invalid\nsig = 7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0679155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b38d\nflags = SignatureMalleability\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c]\n[key.sk = 0a23a20072891237aa0864b5765139514908787878cd77135a0059881d313f00]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c]\n\n# tcId = 71\nmsg = \nresult = valid\nsig = 5056325d2ab440bf30bbf0f7173199aa8b4e6fbc091cf3eb6bc6cf87cd73d992ffc216c85e4ab5b8a0bbc7e9a6e9f8d33b7f6e5ac0ffdc22d9fcaf784af84302\n\n# tcId = 72\nmsg = 78\nresult = valid\nsig = 481fafbf4364d7b682475282f517a3ac0538c9a6b6a562e99a3d8e5afb4f90a559b056b9f07af023905753b02d95eb329a35c77f154b79abbcd291615ce42f02\n\n# tcId = 73\nmsg = 54657374\nresult = valid\nsig = 8a9bb4c465a3863abc9fd0dd35d80bb28f7d33d37d74679802d63f82b20da114b8d765a1206b3e9ad7cf2b2d8d778bb8651f1fa992db293c0039eacb6161480f\n\n# tcId = 74\nmsg = 48656c6c6f\nresult = valid\nsig = d839c20abfda1fd429531831c64f813f84b913e9928540310cf060b44c3dbf9457d44a7721fdc0d67724ff81cb450dd39b10cfb65db15dda4b8bf09d26bd3801\n\n# tcId = 75\nmsg = 313233343030\nresult = valid\nsig = 9bbb1052dcfa8ad2715c2eb716ae4f1902dea353d42ee09fd4c0b4fcb8b52b5219e2200016e1199d0061891c263e31b0bc3b55673c19610c4e0fa5408004160b\n\n# tcId = 76\nmsg = 000000000000000000000000\nresult = valid\nsig = f63b5c0667c7897fc283296416f7f60e84bbde9cbd832e56be463ed9f568069702b17a2f7c341ebf590706a6388ac76ac613c1675ec0", "f2c7118f2573422a500b\n\n# tcId = 77\nmsg = 6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161\nresult = valid\nsig = 1bc44d7001e6b5b9090fef34b2ca480f9786bbefa7d279353e5881e8dfb91b803ccd46500e270ef0109bfd741037558832120bc2a4f20fbe7b5fb3c3aaf23e08\n\n# tcId = 78\nmsg = 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60\nresult = valid\nsig = ea8e22143b02372e76e99aece3ed36aec529768a27e2bb49bdc135d44378061e1f62d1ac518f33ebf37b2ee8cc6dde68a4bd7d4a2f4d6cb77f015f71ca9fc30d\n\n# tcId = 79\nmsg = ffffffffffffffffffffffffffffffff\nresult = valid\nsig = 8acd679e1a914fc45d5fa83d3021f0509c805c8d271df54e52f43cfbd00cb6222bf81d58fe1de2de378df67ee9f453786626961fe50a9b05f12b6f0899ebdd0a\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a]\n[key.sk = 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a]\n\n# tcId = 80\n# draft-josefsson-eddsa-ed25519-02: Test 1\nmsg = \nresult = valid\nsig = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c]\n[key.sk = 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c]\n\n# tcId = 81\n# draft-josefsson-eddsa-ed25519-02: Test 2\nmsg = 72\nresult = valid\nsig = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025]\n[key.sk = c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025]\n\n# tcId = 82\n# draft-josefsson-eddsa-ed25519-02: Test 3\nmsg = af82\nresult = valid\nsig = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e]\n[key.sk = f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e]\n\n# tcId = 83\n# draft-josefsson-eddsa-ed25519-02: Test 1024\nmsg = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nresult = valid\nsig = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 8fd659b77b558ed93882c1157438450ac86ec62d421d568e98ee236f3810295a]\n[key.sk = d7ad3f1f6bbe0477c3c357a806a19eb41ae3f94025035bc87f281f8ee9fc0e34]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321008fd659b77b558ed93882c1157438450ac86ec62d421d568e98ee236f3810295a]\n\n# tcId = 84\n# Random test failure 1\nmsg = b0729a713593a92e46b56eaa66b9e435f7a09a8e7de03b078f6f282285276635f301e7aaafe42187c45d6f5b13f9f16b11195cc125c05b90d24dfe4c\nresult = valid\nsig = 7db17557ac470c0eda4eedaabce99197ab62565653cf911f632ee8be0e5ffcfc88fb94276b42e0798fd3aa2f0318be7fc6a29fae75f70c3dcdc414a0ad866601\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 2a606bf67ac770c607038b004101b325edb569efd3413d2d1f2c3e6b4e6e3082]\n[key.sk = ad9b22793336fcdac10e136c4deea599be187a38eef91c1cf7c7a4ec884dda08]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321002a606bf67ac770c607038b004101b325edb569efd3413d2d1f2c3e6b4e6e3082]\n\n# tcId = 85\n# Random test failure 2\nmsg = a8546e50ba31cae3234310d32672447be213fad91a227a19669c53d309b959782b0e6b71f8791fdb470043b58122003157d2d96a43a6cbd7d3a8d86bf4c97391883e268d50af80e1e6e12939c2bd50ca746cdadfad4edf1bda875299740724148efb1ebe73fb60088cda890317658627a5f7ab5a0c075d9d8f3f97b6492b35519e50ff6b38377432a7081f9176bb1c29a862deac1336ca20b097a47829cec10a6a7cec178eda2d12f6dc6c87f910454af0123555ba184e68804d9cced60fd5c8c90943e56599c8f0ba59a38491ba5e5a53460682474c07e40ca142983314fd762856bb1093f359da6eb0a756bd93a3160c10dd8feea6b97e7c6a17cb54bd5d7649c05c66d7bdee056671dfdaf689fa3945bb8e29a429f4bd5d355dce9687b06f01d5e33e3999f0e8\nresult = valid\nsig = 67d84d4c3945aaf06e06d524be63acbfb5dbb1988c4aea96a5ee9f7a9b9eecc29df4f66b8aa1d9e8607a58fb1ef0c2ad69aac005b4f58e34103344a9c8871a09\n\n# tcId = 86\n# Random test failure 24\nmsg = b477b0480bb84642608b908d29a51cf2fce63f24ee95\nresult = valid\nsig = 28fafbb62b4d688fa79e1ac92851f46e319b161f801d4dc09acc21fdd6780a2c4292b8c1003c61c2bcebe7f3f88ccc4bb26d407387c5f27cb8c94cf6ce810405\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = c9c946cbc5544ac74eef491f07c5881c16faf7ec31ce4aa91bb60ae7b4539051]\n[key.sk = 04a6553d68a9baef78a2175af375458eaa01cdb77350c61e282ef5f0c7116599]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100c9c946cbc5544ac74eef491f07c5881c16faf7ec31ce4aa91bb60ae7b4539051]\n\n# tcId = 87\n# Random test failure 3\nmsg = cd2212eddb0706f62c995cef958634f0cb7793444cbf4d30e81c27c41ebea6cb02607510131f9c015692dfd521b148841e9a2d3564d20ac401f6cb8e40f520fe0cafbeaa88840b83013369d879f013463fe52a13267aa0c8c59c45cde9399cd1e6be8cc64cf48315ac2eb31a1c567a4fb7d601746d1f63b5ac020712adbbe07519bded6f\nresult = valid\nsig = 24087d47f3e20af51b9668ae0a88ce76586802d0ec75d8c0f28fc30962b5e1d1a1d509571a1624ed125a8df92a6e963728d6b5de99200b8e285f70feb6f05207\n\n# tcId = 88\n# Random test failure 20\nmsg = 27d465bc632743522aefa23c\nresult = valid\nsig = c2656951e2a0285585a51ff0eda7e9a23c2dfd2ffa273aee7808f4604e8f9a8c8ea49e9fce4eb2d8d75d36b7238fe6fc13b6c5d9427dd58f8c6615d033c0bd0f\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e]\n[key.sk = c367c8d2ebeeecd70c1e8985b70c38", @@ -3419,9 +4057,9 @@ static const char *kData123[] = { "6f0ac47ea136cb3ff00f7a96638e4984048999ee2da0af6e5c86bffb0e70bb97406b6ad5a4b764f7c99ebb6ec0fd434b8efe253b0423ef876c037998e8ab07\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = d3c9aa2f3d6ef217a166e8ae403ed436c37facbbe3beceb78df6eb439f8fa04a]\n[key.sk = d8aaad0749db159569a68b46048b3d3e8266e110150251c42806f0752a84e95b]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100d3c9aa2f3d6ef217a166e8ae403ed436c37facbbe3beceb78df6eb439f8fa04a]\n\n# tcId = 127\n# regression test for arithmetic error\nmsg = 619d8c4f2c93104be01cd574a385ceca08c33a9e\nresult = valid\nsig = b7cbb942a6661e2312f79548224f3e44f5841c6e880c68340756a00ce94a914e8404858265985e6bb97ef01d2d7e5e41340309606bfc43c8c6a8f925126b3d09\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = d53280367c1c0b95ac4112218b92c6a71c51fb6312ce668de196c7d52a136155]\n[key.sk = e78d26ab5b726c9d4dfb1f634082abded90432a2fd18089c7c85253a5d2fc7d0]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100d53280367c1c0b95ac4112218b92c6a71c51fb6312ce668de196c7d52a136155]\n\n# tcId = 128\n# regression test for arithmetic error\nmsg = 5257a0bae8326d259a6ce97420c65e6c2794afe2\nresult = valid\nsig = 27a4f24009e579173ff3064a6eff2a4d20224f8f85fdec982a9cf2e6a3b51537348a1d7851a3a932128a923a393ea84e6b35eb3473c32dceb9d7e9cab03a0f0d\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 94ac2336ba97a476fb4c9f2b5563e4167ca292c6e99e422350a911ae3172c315]\n[key.sk = 8e7ca56e07f1438ac3615fd9ec77ae63679d0ec059b4595febf40be59d976a05]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b657003210094ac2336ba97a476fb4c9f2b5563e4167ca292c6e99e422350a911ae3172c315]\n\n# tcId = 129\n# regression test for arithmetic error\nmsg = 5acb6afc9b368f7acac0e71f6a4831c72d628405\nresult = valid\nsig = 985b605fe3f449f68081197a68c714da0bfbf6ac2ab9abb0508b6384ea4999cb8d79af98e86f589409e8d2609a8f8bd7e80aaa8d92a84e7737fbe8dcef41920a\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = e1e7316d231f7f275bdf403360304da1509fdf1af1fd25ca214eaac0a289398f]\n[key.sk = e77525af5856ab9df5abb64e5312576b498cc27f61f266e21f382e0526d4e6fb]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100e1e7316d231f7f275bdf403360304da1509fdf1af1fd25ca214eaac0a289398f]\n\n# tcId = 130\n# regression test for arithmetic error\nmsg = 3c87b3453277b353941591fc7eaa7dd37604b42a\nresult = valid\nsig = 1c8fbda3d39e2b441f06da6071c13115cb4115c7c3341704cf6513324d4cf1ef4a1dd7678a048b0dde84e48994d080befcd70854079d44b6a0b0f9fa002d130c\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = fffbeea71215efaf9888fec2cc68edb3703ff11a66fd629b53cbda5eabc18750]\n[key.sk = 1f43235ad716f1beb754ab0f546dfa934488fdf7472b493d7cc3c60353005d24]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100fffbeea71215efaf9888fec2cc68edb3703ff11a66fd629b53cbda5eabc18750]\n\n# tcId = 131\n# regression test for arithmetic error\nmsg = 0a68e27ef6847bfd9e398b328a0ded3679d4649d\nresult = valid\nsig = 59097233eb141ed948b4f3c28a9496b9a7eca77454ecfe7e46737d1449a0b76b15aacf77cf48af27a668aa4434cfa26c504d75a2bcc4feac46465446234c0508\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 19ccc0527599cb032e0b4c4d74e60f13901768a99df041c3bc1bf6c0ef271169]\n[key.sk = 3977785b9f8c5320e51a3a16f8cc22c4f7e64857617f9550147fa35d685ca34f]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b657003210019ccc0527599cb032e0b4c4d74e60f13901768a99df041c3bc1bf6c0ef271169]\n\n# tcId = 132\n# regression test for arithmetic error\nmsg = 4e9bef60737c7d4dd10bd52567e1473a36d3573d\nresult = valid\nsig = 519105608508fe2f1b6da4cc8b23e39798b1d18d25972beed0404cec722e01ba1b6a0f85e99e092cca8076b101b60d4ac5035684357f4d0daacdc642da742a06\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 0e726e27047563aa0a1a9c2e085d8d26af2acba129d0869c65031e3e6cac329a]\n[key.sk = 1aa4415c5db0131bec6fa188d0c23d49a65bf795657153fae94777e3f19bcf54]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321000e726e27047563aa0a1a9c2e085d8d26af2acba129d0869c65031e3e6cac329a]\n\n# tcId = 133\n# regression test for arithmetic error\nmsg = cc82b3163efda3ba7e9240e765112caa69113694\nresult = valid\nsig = d8b03ee579e73f16477527fc9dc37a72eaac0748a733772c483ba013944f01ef64fb4ec5e3a95021dc22f4ae282baff6e9b9cc8433c6b6710d82e7397d72ef04\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = e77717b54a2b5e5bce5bccb8f0c5fdb5fd7df77ac254020fc9120dc0d4df4178]\n[key.sk = 0fb7680a50d3f2940077ea4dfcb7eb040a125c4f4b5dcefa16d3af968fc8e5de]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100e77717b54a2b5e5bce5bccb8f0c5fdb5fd7df77ac254020fc9120dc0d4df4178]\n\n# tcId = 134\n# regression test for arithmetic error\nmsg = 923a5c9e7b5635bb6c32c5a408a4a15b652450eb\nresult = valid\nsig = 26da61fdfd38e6d01792813f27840c8b4766b0faaed39d0ee898cb450d94a5d5f57e58b6a003d7f9b56b20561954c6edcf66492d116b8b5e91f205a3a6449d0b\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 6220972d3f7d150b36790d7d522384876d64d640cd9913186815e1629582ed36]\n[key.sk = e222c444d6bc8a4796a0d5a2d71d19b98845cc56e39caaf8233ea4c6b0704f09]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321006220972d3f7d150b36790d7d522384876d64d640cd9913186815e1629582ed36]\n\n# tcId = 135\n# regression test for arithmetic error\nmsg = 6f2f0245de4587062979d0422d349f93ccdc3af2\nresult = valid\nsig = 4adeaff7a58c5010a5a067feea0ae504d37b0c6a76c6c153e222f13409dff2df0fab69bc5059b97d925dc1b89e9851d7c627cb82d65585f9fd976124553f8902\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 7b64a28c50ec7678a90e3e1a21522e30ac9db7b5215aea2bfb33bea037eab987]\n[key.sk = a89ea18476b9ad90cb14b8b1ff24777e4ebd015bc810a60785a9154dacf3be52]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321007b64a28c50ec7678a90e3e1a21522e30ac9db7b5215aea2bfb33bea037eab987]\n\n# tcId = 136\n# regression test for arithmetic error\nmsg = 6e911edb27a170b983d4dee1110554f804330f41\nresult = valid\nsig = 4204d620cde0c3008c0b2901f5d6b44f88f0e3cb4f4d62252bf6f3cb37c1fb150a9ccb296afe5e7c75f65b5c8edd13dc4910ffe1e1265b3707c59042cf9a5902\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 724452210a9e4c994819229bf12bf84e95768a3a97c08d8d8f5f939a4cad34c5]\n[key.sk = 69b1da56cde8d1676c2a8c0e7f95c7d0bf60739efd1304dd2ccb02729d17a22c]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100724452210a9e4c994819229bf12bf84e95768a3a97c08d8d8f5f939a4cad34c5]\n\n# tcId = 137\n# regression test for arithmetic error\nmsg = b8cf807eea809aaf739aa091f3b7a3f2fd39fb51\nresult = valid\nsig = f8a69d3fd8c2ff0a9dec41e4c6b43675ce08366a35e220b1185ffc246c339e22c20ac661e866f52054015efd04f42eca2adcee6834c4df923b4a62576e4dff0e\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = bad265b294ed2f422cb6a141694086238fbfe987571aa765d8b4f3a24105aa01]\n[key.sk = b332265cf95595f0c90221593b5a2b3c574d60dc634ddff6186f0eed7980a383]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100bad265b294ed2f422cb6a141694086238fbfe987571aa765d8b4f3a24105aa01]\n\n# tcId = 138\n# regression test for arithmetic error\nmsg = 01a2b5f7fee813b4e9bd7fc25137648004795010\nresult = valid\nsig = 61792c9442bc6338ac41fd42a40bee9b02ec1836503d60ff725128c63d72808880c36e6190b7da525cbee5d12900aa043547dd14a2709ef9e49d628f37f6b70c\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 0aaee4b723db9b51ba7d22eb23eb8a76a5ac02f4fc9dd06f77bea42e1d37ec5a]\n[key.sk = faec9764b369df0ef10890dd022c502e551a3222b43e8429455496c76feea45d]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321000aaee4b723db9b51ba7d22eb23eb8a76a5ac02f4fc9dd06f77bea42e1d37ec5a]\n\n# tcId = 139\n# regression test for arithmetic error\nmsg = 0fbf5d47cb5d498feace8f98f1896208da38a885\nresult = valid\nsig = fa3cd41e3a8c00b19eecd404a63c3cb787cd30de0dfc936966cff2117f5aff18db6bef80fcfd8856f3fb2e9c3dc47593e9471103032af918feee638a33d40505\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 812344af15a91ba83c2c91e96f1727ac0f3c4c41385b9fa84efa399ada5168be]\n[key.sk = 4eb19e278f7a30a06a7d55e42c44775f4a81b7a45c0512aae026262e71770dac]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100812344af15a91ba83c2c91e96f1727ac0f3c4c41385b9fa84efa399ada5168be]\n\n# tcId = 140\n# regression test for arithmetic error\nmsg = 36e67c1939750bffb3e4ba6cb85562612275e862\nresult = valid\nsig = 97fbbcd7a1d0eb42d2f8c42448ef35a2c2472740556b645547865330d6c57068af377fced08aaf810c08cd3c43d296f1975710312e9334c98b485f831efa4103\n\n", "[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 0ee5cb5597fbdf8dccc48b01485e39b33aa133b52d30d23740277267cfec3e3e]\n[key.sk = 1998d5949cab365a00f828e7d17b06c708d33fef0031d353a4e15bf7222a73b0]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321000ee5cb5597fbdf8dccc48b01485e39b33aa133b52d30d23740277267cfec3e3e]\n\n# tcId = 141\n# regression test for arithmetic error\nmsg = 13945c894c1d3fe8562e8b20e5f0efaa26ade8e3\nresult = valid\nsig = d7dbaa337ffd2a5fd8d5fd8ad5aeccc0c0f83795c2c59fe62a40b87903b1ae62ed748a8df5af4d32f9f822a65d0e498b6f40eaf369a9342a1164ee7d08b58103\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 9fba1de92b60b5b4703089763d0d6f9125e4dd7efae41f08a22882aef96892c4]\n[key.sk = 6164676114c66bd9887dac341c66209dc587ccf0cc5cd9baffdfac9295a00c4a]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321009fba1de92b60b5b4703089763d0d6f9125e4dd7efae41f08a22882aef96892c4]\n\n# tcId = 142\n# regression test for arithmetic error\nmsg = 4de142af4b8402f80a47fa812df84f42e283cee7\nresult = valid\nsig = 09a2ed303a2fa7027a1dd7c3b0d25121eeed2b644a2fbc17aa0c8aea4524071ede7e7dd7a536d5497f8165d29e4e1b63200f74bbae39fbbbccb29889c62c1f09\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = 7582ab1b52e1316e5c13671f43b39ca36b28133cd0832831bcddd0b0f23398cb]\n[key.sk = 4b0bd03a03b20069ccbcc214a7448473f4e7a491fa7ceb48ddbe24c83c4aa4bb]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b65700321007582ab1b52e1316e5c13671f43b39ca36b28133cd0832831bcddd0b0f23398cb]\n\n# tcId = 143\n# regression test for arithmetic error\nmsg = 563357f41b8b23b1d83f19f5667177a67da20b18\nresult = valid\nsig = e6884a6e6b2e60a0b5862251c001e7c79d581d777d6fc11d218d0aecd79f26a30e2ca22cc7c4674f8b72655bc4ee5cb5494ca07c05177656142ac55cc9d33e02\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = dd2d678bae222f3fb6e8278f08cc9e1a66339c926c29ac0a16f9717f5ee18cd8]\n[key.sk = 2fce7870be1f392d21fb1d2350ec7877db8aa99b359fe5bdd5338ff35a791d1c]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100dd2d678bae222f3fb6e8278f08cc9e1a66339c926c29ac0a16f9717f5ee18cd8]\n\n# tcId = 144\n# regression test for arithmetic error\nmsg = 931bbf9c877a6571cf7d4609fc3eb867edd43f51\nresult = valid\nsig = 6124c206d864507ea5d984b363b4cf583314db6856a45ded5e61eebff4d5e337e0b4c82b445ae2e52d549d2d961eace2ea01f81158e09a9686baa040db65ad08\n\n[key.curve = edwards25519]\n[key.keySize = 255]\n[key.pk = ccbe7cb2e4bc215cee2f885e1d22f7e0d582b2bbbd782c104e548b152d26fc69]\n[key.sk = a9ace42195ddbb3a16f366b24dd9d37a8a043ed2e6001f54652296750379367d]\n[key.type = EDDSAKeyPair]\n[keyDer = 302a300506032b6570032100ccbe7cb2e4bc215cee2f885e1d22f7e0d582b2bbbd782c104e548b152d26fc69]\n\n# tcId = 145\n# regression test for arithmetic error\nmsg = 44530b0b34f598767a7b875b0caee3c7b9c502d1\nresult = valid\nsig = cfbd450a2c83cb8436c348822fe3ee347d4ee937b7f2ea11ed755cc52852407c9eec2c1fa30d2f9aef90e89b2cc3bcef2b1b9ca59f712110d19894a9cf6a2802\n\n", }; -static const size_t kLen124 = 61255; +static const size_t kLen178 = 61255; -static const char *kData124[] = { +static const char *kData178[] = { "# Imported from Wycheproof's hkdf_sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HKDF-SHA-1\n# Generator version: 0.8rc17\n\n[keySize = 88]\n\n# tcId = 1\n# RFC 5869\nikm = 0b0b0b0b0b0b0b0b0b0b0b\ninfo = f0f1f2f3f4f5f6f7f8f9\nokm = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896\nresult = valid\nsalt = 000102030405060708090a0b0c\nsize = 42\n\n[keySize = 640]\n\n# tcId = 2\n# RFC 5869\nikm = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f\ninfo = b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nokm = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4\nresult = valid\nsalt = 606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf\nsize = 82\n\n[keySize = 176]\n\n# tcId = 3\n# RFC 5869\nikm = 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\ninfo = \nokm = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 4\n# RFC 5869\nikm = 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c\ninfo = \nokm = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n[keySize = 128]\n\n# tcId = 5\nikm = 60ab7f45b0ad534683b3a6c020d4f775\ninfo = \nokm = 73bf325f0fcc78f15b6cee7c9e7d927d4016eafd\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 6\nikm = e3db76e02278cbd2adbcb4555803da11\ninfo = \nokm = a9382b2bb04ceb4fe0543cee88753df8cb90c9dc440f7e476e95150c82e1376e123f058875c00cff6f29\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 7\nikm = d4dcb92a769f57c8bab8a420ee0aa351\ninfo = \nokm = d10d4bd0ed723533adfceaa903f1ee8836e61cd085fd951dfc6a291edded082e8478c9f8bd1f7a2611a6a049761dfc2888a9e32be9c326833c6559487c33f6e1\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 8\nikm = 2d43e54bf0c94c9cbff4300f4aa69ab8\ninfo = d674da3bb47d5c7e38b501e5251d9348af601c44\nokm = c1b8065a9ea8e79d404f882089cf423a99bde5ea\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 9\nikm = 4055536896c406d5fe14a6cd6b999bff\ninfo = 2094768a8816f7df070d6e08b7ad93755dc9024b\nokm = c7d3c9ab74081357d0f6ee3aef0442afee7325381090a2df642926a3e6e6a7e213f05ea5c39978d52165\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 10\nikm = 5b01b2da3166f217cdd68de8af60078f\ninfo = 6884cfa7ffe8f27bf4ebc6e46a7e01488c79243a\nokm = 1535a41d6e8a94c5bd51b7447bbd9c2b8fa00ba05b92e7ab0da7d1fec7d348ee7d50a4bdbbde173dd6eeff83aba9e8b822823b339a76811d62771336f4e08f3d\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 11\nikm = 467403c2ec02a235bf730ff37e8d8ff3\ninfo = \nokm = 4ab2bf78f2678effaced317249e116862d3d9b8a\nresult = valid\nsalt = 41f0f173d307d40436c25856cf559f96\nsize = 20\n\n# tcId = 12\nikm = 3352f942aa93071da6d39cc5ed8dc460\ninfo = \nokm = bbcf63065c761017f229183e767683b98633a85f4d8f32236cfa0fd3f6b182a5f41c33506636d18c5eba\nresult = valid\nsalt = 57a0db708b25a51afc4271803aa35204\nsize = 42\n\n# tcId = 13\nikm = 08867e76311126089356623ba5381e73\ninfo = \nokm = 3084fee371179b60a4fd27ea2637a9b89a3dcf6ab45d4805c99880b26e5d73efed4b421f1fea4cabb60893241765b19554aa51689bf00d7d94a053a94bfec55e\nresult = valid\nsalt = 0c164c443edcdfaedb1ab150f047951f\nsize = 64\n\n# tcId = 14\nikm = c55c41d69d2424a520414e3662aa7303\ninfo = 3fdf20538063b76901d61bbf9b72b0c18749e00e\nokm = 3917a782fed4d7f525ca16ca1dfde0faa7207262\nresult = valid\nsalt = fea9bfc92b74337e43a201a2dc199e27\nsize = 20\n\n# tcId = 15\nikm = 5d3db20e8238a90b62a600fa57fdb318\ninfo = 2bc5f39032b6fc87da69ba8711ce735b169646fd\nokm = ca0903f17759fc29df761469e3b98a5b1476977706f3c87e9d39050e5b36c7ae6bbafeb3814037b12ca0\nresult = valid\nsalt = 1d6f3b38a1e607b5e6bcd4af1800a9d3\nsize = 42\n\n# tcId = 16\nikm = 8677dc79233ef3480777c4c601ef4f0b\ninfo = a38f634d947819a9bfa792174b42baa20c9fce15\nokm = 1761915ac282909fbfd43ce31934e7a10951f901ad33f614a9394b6f5ca04e00906aa14b91132bf9e8ae0aa2102c3c7a67756e81b57d89192a62ca0cf907a3dc\nresult = valid\nsalt = ad88db718244e2cb60e35f874d7ad81f\nsize = 64\n\n# tcId = 17\nikm = 0f602703d37943e0253bed3da331aff4\ninfo = \nokm = 4a54220ecee20a84e1b7b6f5407af234b14938d1\nresult = valid\nsalt = ebdc8510499f69b2e188daab77cd819cccb95f276f46e6b2be11cbe72700\nsize = 20\n\n# tcId = 18\nikm = 9fe65737574c5c7aa67646adf8230ba8\ninfo = \nokm = 741662ad515bf9d2661aa0731eebd674f7390bd20fa3bb7cb2e9d6ca953c2bd839929c44a6f0ba5ae614\nresult = valid\nsalt = 73a34648c152443586236abcb46a090ce55ef6c7f282ffce6342d694650a\nsize = 42\n\n# tcId = 19\nikm = e8f2b1c3e6a6c3d5ee0a20dd47aafa78\ninfo = \nokm = 695807f517ba39e33eadeb6a7b71d2016163e9f5e6aaad5f493bcbe24ac06f8a6770097da76b50338a4dcbd9fac4d3a545c45eb1e733f70e9e82ca03830d0ee9\nresult = valid\nsalt = 3f5e162de91e0782cd189f3b7778cdc2ce6bfe9d3fe841cd3c70475d7b3c\nsize = 64\n\n# tcId = 20\nikm = a679521cdb56aafc5a4b76db0431a4dd\ninfo = 44ec41ab4f4e64f4a36e5e30c9f0dc1d77ae4974\nokm = e36789305dd2613dedd29e041afddf558d6fb8b6\nresult = valid\nsalt = 123033b1ddaead83a4b9cfef8a660bd8e00fde01e67c35656c6d7607d456\nsize = 20\n\n# tcId = 21\nikm = 49bf155ca102026f2a217ea1bc9843ac\ninfo = 851bda4faa8f7add2a3cbf0acf9c2786f8f955b2\nokm = 6016f537e75e1aaf2e6920827d18aa25e9fc8742c607b0cd97a38cad0bed0a6622981f97b63b08f31ed9\nresult = valid\nsalt = 76776e3b4d75f8f43dce4bded71f3b1ae6bcb012d9c0d59f78248b9427b8\nsize = 42\n\n# tcId = 22\nikm = 6cf725e939e8824d4392233eeac75d30\ninfo = 495425d9727fee2e2b7e78899868c1c3e7735e1d\nokm = b31f845aa6ad9b6803153872145a28617035e9b2d2a5c1ce8d0d2c6017f17403a67326cd06068af972eb8b734903d10b633d07de05f02fc70ed383a60bd82b48\nresult = valid\nsalt = 1e72f24b05a91a0093f34306ffced79e7003055b0833c6d0f27a4f33a1bd\nsize = 64\n\n# tcId = 23\nikm = a319ff7b5ba9b14ac72b681cecf0f742\ninfo = \nokm = d547c94891439eb7dc9e0c425adf20262d27fd9b55e7b0516e836db6b2f778c70296bc97c466e05ce2d5\nresult = valid\nsalt = d7e3bc6daed343ce77ef793e15a8246e4bfcbaf83d2ac956d0661d1df7262b2e7311623dfe4152caddbfda8fa8ed7a82656ec00b72c5adf7c9d388e5b3bc8d24\nsize = 42\n\n# tcId = 24\nikm = 34bae5a158c1678aa76a744417a70d7a\ninfo = 87ec30aa53acfc3d09ccc1d57d654fdbce403cd4\nokm = c508b4bc7503440f3ee04c5b8c5832bf70b54a6caea8d2a0ade43a0ea72c08e474904587334d699ba2ce\nresult = valid\nsalt = 1532075f363e061133780ac959bf653c7687d181b9431215d6f62dd2f1ec3019d61c50fa82c70ae25e624c849a276b0c57d7c02a4d753fe84a1a6621e9a5ef01\nsize = 42\n\n# tcId = 25\n# maximal output size\nikm = 9ab09999adde788dc2bf82c7ec8fab03\ninfo = 60999543d9cec9d3\nokm = 033293a76b1496c9619331f089d402d0deae28166bccf304bf25822f369479cf0aa1600b6ebcae43fd1f5d3389c55331b81cbe1e9f6ae29aa86d8a332d298d50516af4926f01691754981c9c92d743d0d26a94423120761a4d0d0e562368696ab78684e51a65b30cc4849a6a5a6c53a076c276db287b787dbb43d1e107f86bce19986cfcb86ec40fd74dfba08784219c2aea2152e21be5a87dacdd18b22ef23292623bcc64bd03a3a1b408a77fbbf4e18ae59a94cac72f43687190e358579d1b0a54d3f2df7f08b867af0b941deb9f7035a1a8f13c6d0da4f9e02f817ea0a92c02140ff5a7d7e398a7b410574d2e6ef7a710efbd1db628318650236ea02f1b617bc79087f5a6c3adeb7037176ef51fda844b2607a4960e3852107dd2703558a534a06ab5a1595d237fe3eb0c0ea3f14400332abb221784914e99fa5ca7a1f67338860283bf589a6b6ea0b32e2779e207fa8139dfeee954e762ebf6255250b1fc58c4c79b3d98fbbeaf786907b5fc7a8c34a25a642b7286a4b2ecdfd1dce041294322bc54b3c15ac44913dd1a3a4361e2d2a0e58c13f34ab2ead723fa01311a2659f74722a09f5b1837a7666da60728ae5cb4b837621961bf0278da749f79a47249ea0e361be3afd14ea9ead4e2f70d9941fa55862d86b53046de5dceec48a4b9f7b895693e328c59c0b2543ef2cd84b2c549a8e0013351703f7669b8346d2b32f7627b7df9ee746b1092f34033f69314a985ce2e948b9a98dabe9bf259f92b78b9a1de7285db617784001894af381618e9a2992c5738337930408b7e0fb57697bf4839e7e72ffa1010319a50aef208829950d60b6c4e57b76bc62d1923003c374710d5370249172064e4e5e0aacae369fecd4ac4bec3861fd24a6c633aca87f2d73c7accb43f9d83bce2d544563c9213e2eaf4a159520500d576bee5d3301613c31580cd6ca8c47039a4d4085dd8b959e5b8ca4835705bcba8982bcf9e8fef0a1602a76364cedb6daf92952ca58be7076ff5536403023", "0daff9fee31152d64fa0d6541d862970c2c013efd711c4f96b532fe9f4a4a180ac4d3cd41e5d66d62371616e6ea88896320944a8f3df632ae0188bd93929ce6a6669803c04be549d80fba1815ec67a0269b74e0a1d33beabc1c94ef6636722a2b27bc0f249da083feeb39ef2fa5666ee38339791602afacc9829abf6541a5ede2cd45ece276ddaa9f49fc4d02b755eab466d5bb0ceb3b7b771ce6a9d85283d4a53f53c54b63b4011110b42e9c1fc8c8dca6e4b69e6c4b3b89c53f0f990e26b84ca5f0660e712c775c1824eab5055527bd92495cc59f8d4c04ae13b49c466e886d81639d00b7bc68875a8ab6cb87807d4b2257252561d69788cc136a5273e5f3e68b9ac4ba4f7547422544edd4ca658e1c13c756420e4a6290c7db03f5ff7f44ac78fe4d353847caacd1692c1521b12f1f55362ae755c9714712a6d80362080d865062905ed0e9601c5b12b1300dca219f7676d0080a33d1a6b08718c36f084211461c0f50f6911f17746752f3a6bda656e3a065aab0cf30ce2542eda35a42821c62c838ed18dcd4dcf5d51346804c034fb2c3a16b0c84a6aad62972c84b499a370965a959e17d537acc13d5d08000d732c11aaad9e0f192a9b74d94ef408040c8bc50e7b2ba9edbac047fd4b80c16dbd3962f7eb528e0d80cb5a439eb3d6cc62e41e2cc7f4e2d5141bd48b400ffd19da07d0694e983b91744e420541c01bbfba3f333c5e3e7946d2dd245b70304c3b1a35cd9485aa6908c7a7a846f23466265c1e55e6dfdf8d0cc320033a18feff132c0e3b1216d33b954679121ff2c8795e7c4f9a4a9725d31200bfc72444cb76f50f198b04afbd4821a31a183593210789f93ed612a2e1d70facfa0b23e5aa854059b83979b55ac382777e351589d266d3ceba76a5bc345c5514f4f07e79e54a8b70a024cb031808bc13524c04b4d1fe28781da04688bad13f379a0659915ce438985428473823a70687daa8b6afb659edf07e25518b00114e9847e3d6598f23f2eecf07e59cd2a801eea6e3891735e457b7fa03872358e682571fec629cf19f17fe167a6253dee7b6deb39773e0d3606e025df91f35fc27be8c046d67489e010f743d84599283fcc418b628dc244d2f859db667c376b2953991e0db773b3e068c1da262302c391681fb414c26c41ed85eb4212e982d0e15eab5a67257a3ff913ce68d6aed6e9a8ff385c7d878cd4789ec9adee99fe25438911252de7a7cf6ef5d6662cb424208003d0ddc04d38e04c32d9beb4f6e8cbb19a8dc0835515bb5ddbc600f148861d6dec69dc8cbd4aaa7fbbe49f782199d618cfcc9820e77f2a474a3fa219c384d66bc8abccecf9f82caed37f05f3f0e1d448af96a5a8287a8c877b25b842dd9e0f66ef810f1b0be4e76f8f4e6e15d7eeadd07633fa3763c493e12a84639f76f67cfc823ab945403ce84d50263edcc95223a22acebb79b85aecd82b3aee931c891ba61bd8ff94c625cfa4d55e1b2bd996b5d99e6cab245e243e6414005f1cc4f0dea54b35e1309cc2db46cd785b294aad50ebd634d363688e3206a57fe38d83cc068c4b8504c11bb4c1d256d496513667170163f7ec98b5b9c3e23777d6a3cf72598ed68fc51466ec4e3ebd0412e002af200f1bc8800400e816ab29293b1c7ef24e30415a8e513e4a9efc851fa549b3d1e0d881fda0a6c393d0ff0c57f44260b3f5d7dd60408ca687429c4cd4274c206f80833d605290e5c992f17e05dbc9552f8c40300bc1f3480c6bb404c75c4220d8888afeaa779eb0f625c5c044bb12349af62adf5b0a18e07b37c954146851dd628dc26e894ffea95c84e78a75c25cb751cc81dc93d3146b6beee9871ca3004af6e644b65e972df9934717e075b53eaa6c878cb94f5d1fea89c3e8c9da4d0bd7d8d8ffedda0b48eee4c9877748be05a06b3e69342d5366e9db9be38f36af0f759fb6904876f5ce327dfc777fad8732e4372ada25106477d8311095b8d9dc4c0100cffd70847305695be46b2b5ba8df8ab3de333d09a7f32736061eadf9182bc4c0ea5965ba7d91d655d6942f0796fb4a05c959b6afb52a8b943065de6e0eae3639006c5b130b0a8b00b617409c5c8d5cfcdd88b1e981930ec92f21ada92a8373fc7b49d3ccc5c63b776849d5efa51de531f9387a9d11ae9fba6987d6b680fe15fc19c88bf0b5e1764044bd689554a12c8013f1e7dd6d2214c74c3fa65b4a0a35bf479d2582e948ef91c464c4dbfbea80d42bc8b1ce1fa42ccc38f492e3acf93b2b64f5e956fb171eb2c0e4ff537c4ea2ca13978dbd280aaa1d5a798b423942b6897663aa75d4c153f76d653b4fbdda2d2e141e9731679d52225fbc6dd0e81e03095b37af927e0c2aaf7eea5bdcbf59749e54e391b2af88626ef8f86920c81043334b3a09acd8c0a20e9aa0849dd56a2643803d133fefa3ee0f6b52b6109170ec5d6a15d0d20f7fb546ed78930b4298f4b5623ed912d0a5d6688b05b1b5c892e6fe60b2f1c68623bcf9a0ed513ac75c17cde5e01c3be75b1ce441174d26244873a7946ec1953666512efae05547dc8cf58fc342b262c3ab072f29ee876327e1de6c67f5c480814ea26702e1c7672de4655a87350b38f7b290cb22a3a0725f8aa2d24a794fea6f70fac5a345fc426ea2931cc3890b8cae7e92cc171d86f5f1baddae8f4b1db7aab80e629022eccfad9276c578d2a6085a446ed4b017e6a0da40343be3761f190d801283c061865610c3173753384bf87ef3ec78e63aebb1b051236f9f4d6712b487f0c407a44c7241c96e2af404a2ca14b8b6a11564d0aa2b6efe18072d6d596e26d105783a57beb5954f6066f7d2f4eefc2b455171d56364b21c3d8747d5f407cff5bd8bd350d904c17a4b91f37b48ffca09e5334420bdcb6fc3797417cf99af8773a027d0dccf56087c7e751e519c365119dd9195ee2449de13aac6d538c31d58dfb3b4183be4e71f6b4893ca588876514b581b03ac897b5e9305234740858f2b2a368b26b4d560c54a3f1018df913344d66229c56b3995a9c67d5f6db145e495159501522472dfd3d38deebf4c8cdd698325914d7472d02c49af1a9c85d20c019b03259a849130a53909929695a2f911e11f04caec36280f9653218911f4fa62ff63d77ecbeab3f2eaa235598617c424eb6caceaf365fdb7659eb06569623d38e47306ca2dfa98398586c4d5aba8ee29b9046416b3d7c6660b03aa5f59ca921e9f25090769428587428c8715f053323dff1eecbc2bec9ce90bda4d890416fcb952018f50f9ac9119d45e7ed56af58a4d0d9ab8a2a301eb17325f89359575a6277d340c8fb40f3271387fcbe04f2d3c1d63b490d12b5d2e8e592529c62d07d5d9c315f54157d30cf5ffb870b6a466c6c1f19fd0aa4b8973f1c3492b77cd7aeea7bd85f21cec76b61c3183cccf83e754d8ecca2b2e39420fbd4724f03efd9b6f4d4d59f1e8cdc3746b1dfebcad85287127de3658c2aadaa514e35c84bc772839575622d872a0e8469b3eec05e143b2129c6a75d1d4f043b2785fd2818a3db7dcf2991ea95caf73db5b2340df001771a8548db332006378466ff16dd0c60fcf6fe0c185da8e501afebcc9f566e1ff34f69b5af7997e6413c9e17e34745e131edce9820540c07ada9f500368b0f3dda452b3d1f8312e2926e20ad55fd398d21fed2ae3440834c9779d747f4553cfa2d5edd8242f3e6b1b3694031fa2c7430e78f117e69487798f1f3ac539979e29cb69ec44d8dcf6d0220d956cb4e6a5c9b8ce5263a950362f88f3ba56ad7d2f38fcfb2195cfe79baf44845dc124aeb5283962691abc25a4e016bed2f127e4e6bb78b22437ebc87cc975fc898793dd20f94784cad271dafeda980b4c6a91de39ba71eed0529bf05907db0b1bb9ff09e2bbec611d8238eac1939c3a7fabe8ab631337300ed6c40dbd5299f934790137ea875e54af87a60a169eb920522af2a50b62856a6e471e6c52f285cca854d0bc98b69622aa2c4364843279ac21eb4002c9814fec8be3de5f1e587ea62b0b2f1b5313b69ea407f1f2b7bab8c13cd54ce2a7704ee97d01c1d40feca1aa698fd90b2003507b32644043254dc61ac50f92840a408c62d6754e80108ca656b0ac977e9d1da44f87f4e8be3f1b2258f092714b9c4027b1678388546031a1c7391d9a151a33c5d291d85a457fe46b12ba6faac046630ad646fd5705a67ae2b2f85e4a79f780bf506829fc9cdcf6b8c2cad831ef7b26b37d3db8d4cf63776eb60151f17b68d86002e878c6198c171c8db609f870ef0ce62bc27b0c97788c25262020c4b42036ac3ea666429f7a47248fc41126bfc5777ea036775437b9d14154aea29884aee95e46966699a6a5707726057de573d77f31d190624dc3833c939c318784fb1d80c448fca6f0af4cd18168cb40d3c19377852195ba42da113d5953c1a0fbe5d188d884f6162503d69442798c891d1fa0c706c80565b9e6300918e6f718770058f18e80ae393a96c83a987ab08b2065c42d02f03d88385f1b2041ed70b90b124b6973990d61cff38b493c778c3eb26c722408f4060da392632be571b7260051cf18dfaea3efbc3d37c67b0c182a0cfacc1d013c38ad0592bfd868797790bc8f5a5e2a95c33bf078bfcee82afa438cd4ce48eb8698906cee16e0eee03c551d8c0df8d3448924d3d1108a6dd89739ae1745d637035af515ef94ab3ef461eb479281e743b9d7ea10e7bc1a033da2eac28a97e1b81550c32033ad630efa2a6ec9f666c34adf8dab8367a40c21f1b70fb8254976eed50be0764be04e62cb0427cfa51a9b78d1f4ddfa09c995d20fa0cc3cda2978ccc762146ce9441394df789bfd8233950f84df64d20808758f19e00b5c6aabe64d3c23f709ce866fffa5d35590801459f076e6751827d131185e36e818c30bd5ade360e4f0818a03188a5266c44747ed5e7154c4c93a87f0ce05b745bc7ebd3fe011c5169f1ca118bab34337eeb61206f251d8a0307f6dcb33aea11b1ec7eb888667c7145b2fc601dac47787c842a45ee0f5af1811b7a57759c14f5da6f8b86f73a3bea7b3f1effd9366dc6658fb3b8510f54621d8d13f330163a6530da45f7263a8fda2c43123ef46580b3990d51def937db27f9e06e87fdfd186df2fd6a5dd6133a8f3ee06e0e14719861def6cccf68f085caa631db3e85b4bcdedf83923c2950665b0187e224522060d5d54a02d5501a0c0a384bd247164caedb02c9a69f9a3638d258b945aeba029250ab549478cb855cb27404fa5cdb15a46b9f1ff8dda401f2dd472a6d6c66dfe8f5f7449238eb959c091db1c26e5efb5e7efe096489c7a25515de6399d7399b793aea554bf9fa1f6083f3c955f144171e8584b133a2ea77f49c974c2e79846e83541f37e0671d65173b3327de75c5173644959ba119f49195ed3ca26b144ca3001aa5044d46781a1336967911496da309744bb6ad244d1a96d47c7089c539486a1977a63b6523782bc2701495d50ea208a7fa411c70953cb506befe8ef37cc41dded7edc0a91de2e952abe338141e020afcff657e3eae7d11b384b0a496dc105fcba6c9cb3404dc20c704f0d37c5a96cc37ee132c47ce1ad12791d48a96ea2dfd0881b1d1d777619405b9040fb52cb1a7ca1ca993f34eaa2a7e97edeec2382ff73bfcf3ed5b6fd911c8d610551aaf92c92111d95a3919e20974ac27f3ceabe6aa3be7b6bceab0080f7ad9ee3d48bdfa7e44f6c71845c4e744726f1069324c519188d7ea3607d466ffd25b2d65a4ae1023929087e959eb8277eb495fa4dbbd1fa2", "29490db87ba6b3a46c55524e398000d7f3d50c11aad2b9e3d033e503fa279f77d2a2fca9c8bd026a006ecc4c913dd3fa519594784c9eb43a9e3f862c3014cc1f01284545004d3733e63b6832607685b329988f26dc394bf17d2d4355e5e4622f86a4a2179b48f6e3a2eb391c343364a6040a384e70babdfb557d23fbf08730f9e8894f28b6c43a8fee397bdb39555c9e1cb389388776f72ac3c88656e4f36ff032c6324d68949bd2608313651eb6662095d40ed72a89dc85b420168c1c299f78ef8601609c1a5a29625545794b89a01e13cbaa339c05f7504bd45b79239d8f0ed106450918fc0be03205e414a58c734cc9fa134e6d7af2e106f25861511c6bb1510f1a4a493bacbad33bea4f41c3d8d28488a87d8fc\nresult = valid\nsalt = 1aa93ccbc92e29d7016f71e7f806bae2027f62c4\nsize = 5100\n\n# tcId = 26\n# invalid output size\nikm = 7727bdfb91621dcd4ca5e8cea6b4e2eb\ninfo = f3fecf4736e28862\nokm = \nresult = invalid\nsalt = 96b2e11fe817e1e40fba8aa5083cd490482b2abe\nsize = 5101\nflags = SizeTooLarge\n\n# tcId = 27\n# output collision for different salts\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = bfe5a1669df67ed5638007f620875759af8c0242535a263cd4d17ee9bd9219d2\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 28\n# output collision for different salts\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = bfe5a1669df67ed5638007f620875759af8c0242535a263cd4d17ee9bd9219d2\nresult = valid\nsalt = 0000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 29\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = ef793d5a62169cc1911fe5dac7ddb3ce07404e8299296f7c139442b721a75ef4\nresult = valid\nsalt = 329f445e7de8a156cf26a0208dbb028d9de6ef76b8de67ca634f4a5a732138a1bd436a7b345d7a0314c7ed0a00b0d34ecad2cb8bd141e2ecc1c77e237094d55154\nsize = 32\n\n# tcId = 30\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = ef793d5a62169cc1911fe5dac7ddb3ce07404e8299296f7c139442b721a75ef4\nresult = valid\nsalt = ff881c9fd53adc0535d68f4690bbbd4f4990c7c1\nsize = 32\n\n# tcId = 31\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb0536\nsize = 32\n\n# tcId = 32\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb05360000000000000000\nsize = 32\n\n# tcId = 33\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb053600000000000000000000000000000000\nsize = 32\n\n# tcId = 34\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb0536000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 35\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb05360000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 36\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb053600000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 37\n# a salt shorter than the block size is padded with zeros.\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 2a031029e1b02289917618b7e0dcaf0226f84ff1a5770896c92e42cbe6d27d00\nresult = valid\nsalt = e69dcaad55fb0536000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n[keySize = 160]\n\n# tcId = 38\nikm = e2865d6bbc1abf6a815067edc4ee7aa33c290d5a\ninfo = \nokm = 1c9f5d2c19e47feddf19af9bbf38ed6aab1f872b\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 39\nikm = 8c177ab5f40e9c57203883562f01f174070ccd97\ninfo = \nokm = 07d4aa3e002dad7940089482d10e80b349da499fe7d9530b27a8dc5c61940bb44aa703fba340d21c1fec\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 40\nikm = e842a4fc1a147cf2f87de9bd5a42fce6457496f7\ninfo = \nokm = 5f426da341127db39b959cd77c13cfa4a7a29259f105f2b181067492a54ba259020a5289b0fff0ffe0b9f72606bb980c929a1aa37255d3cec453bdfb26a3ffe0\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 41\nikm = 5b870ee1bb97ee83f67fa7335b4a0f9dadc80d12\ninfo = 0a0dfb2a6e051441678788bdec04cc1b63ebe1f4\nokm = 31aa4cff955a0bc5884e1653087f9d97e284775c\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 42\nikm = 58ea7ab33acff514ec08f41e59c17a3c66c1ceef\ninfo = 1cf9e25bd70c5546ea7a79eaf5d90cacf754c4f0\nokm = 16ec1734868565540efe2967cae02d8be26a86abe83edcb4b599f08e016b25b925660179b9dcbf0bf07b\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 43\nikm = e8d20934b9d320458f4854e2442e2f0fa092f461\ninfo = 4425999958aa3cc629300c25ab15be8cea7a4277\nokm = ad2bdb5383dc53258ca2051b26c53adc156b31acaf61ecef7d0ecfa14b81b0f53b1c98ce28ee804e964f8b106312f429670287ddcf5bbb67bcbf96ac66c242b5\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 44\nikm = dc9e488c684dbf0ac8ff1eefaa0666d413d258f0\ninfo = \nokm = 65580e5feab001f31405f812d87c7d8bcc187c78\nresult = valid\nsalt = 9afa7df500d7a17af1f44422d25a62bf\nsize = 20\n\n# tcId = 45\nikm = 34b85c341a04cbade472b3f7dee4de4d1954bf70\ninfo = \nokm = e02ff2640000391f1fcb3d0fcec40150b20c5af7c3a0c4965281e1761539d48555cddb2cc35efd27ff86\nresult = valid\nsalt = b066b42acea664350a8448f8e064225f\nsize = 42\n\n# tcId = 46\nikm = 44cc641e09f7d5642f7b6007ca5a1c0813319666\ninfo = \nokm = 81c3016fe63b57cfcb13ad04eea7e2f5ab1402dc489c20824271c5a95ac1cb9b0809d76d5d7437e4ac74a36c1693d964d37d10064649fe9003503197456dc4d2\nresult = valid\nsalt = 69c0dde6c8e5bd40553a5981fad6ad87\nsize = 64\n\n# tcId = 47\nikm = 88a8880cc2b73e73b3b6ca1d4902caf2128732c3\ninfo = 6dc723df3d26f704067afb2fb6d95a66516d089c\nokm = 69614a2ebf14d74188e830ee5623c0e0366ea994\nresult = valid\nsalt = 0579f690ed32e57a26701a9f6877f243\nsize = 20\n\n# tcId = 48\nikm = 8408668b9d671121b8c7d31113f045c0d7c020fe\ninfo = b4451b0f1a217db703582881e86d8044d5f2e092\nokm = 6a6ee276cb321c6cf237360a7b30faab9060653ecad213a3aee36735e29164c6fc929b7f206ea4fc2f1c\nresult = valid\nsalt = 679b30e6930a8ea3f076e317b9595d5e\nsize = 42\n\n# tcId = 49\nikm = e6715cc4ee13c4d999d8f8f500243c321f70b0be\ninfo = ef17c9227a5ca654fbdb35dd00dd6dc77b6321de\nokm = 1532fbae2e75d854c96a0b172cbe40b91d36143a93bd1b68d26be85f19de06f585d8670190380dd0690f5fd168cd0c64bcbd99b8dcb9fda9eb345af917f75739\nresult = valid\nsalt = ecfaca2ea3301a992b4de081d9d3a4cc\nsize = 64\n\n# tcId = 50\nikm = 9a6b88f3f68f5a8e79903b51dcd733abaece1a41\ninfo = \nokm = 0b45a0d3ee381c5c1a33556af0a050c81a336f9d\nresult = valid\nsalt = 0226df3d66ee3abb275eb39c8ec3d3e12e9b87b67f85c552accc4279ec17\nsize = 20\n\n# tcId = 51\nikm = 0b9eaec88b2940a4754e83272cbf47fb6f86aaa1\ninfo = \nokm = 844af69cb0e4dbd1a768f69c4a5d2b280b645e48f11cf9f9dfd5930dacae47f5a8a0a58cda227747638f\nresult = valid\nsalt = c1616497d49246400ba68242b635c67515d2528ee1c3b71b318b631f9bef\nsize = 42\n\n# tcId = 52\nikm = c4717276e7c7f794c4ee333b2f7a2ab244be9e8c\ninfo = \nokm = e1e9d8dabba5f8bf934c933170abf15edfa69a19e32666503b00694a1952c38c16703c79ee41d76cc6219533876d162727fa738b949b74b8d04a880d7e917dba\nresult = valid\nsalt = af4c63e5b554063e83e37bf730ffa401c696088ccc4f133a8695ffcbf2a9\nsize = 64\n\n# tcId = 53\nikm = 5e43a900ee0d432c5fe6fc81db8d5f81a54e39df\ninfo = 32460280e60910b10abee2e9f80a3dab48acbc59\nokm = 113ea70eb9eb87624ca2956afa5d5acdb4a5eabd", @@ -3431,9 +4069,9 @@ static const char *kData124[] = { "00cdd0299971ac4f1cdfc6af7de2a3f131c868714a24b3c0aff8162951852aa97a29cee9eb7558bd2f384065130abc4de58ee5b268aab6b2380d885e5c98d22138fdf77bff9fe2370eff28f22a4515341d9c226a6dded964086f3bcb5342acee09451c6257eeb434b61b8d93b0850d49e2d229fbd0bb84ba4efa3fc1c2d59a2e725a528fcdb44d43a0e1f5572d52b3f526581af49043d939e9857713d04ba2a96139e007b974b2971f71a0bbdfa76998f250802eecce869bee6e4bd3e4523c3b5d32a61c9f9aa1e0bc215484a4b11bc81ba3b2562ea49d08f63b46edfdcdcb7a496f414d80f853547ae94d8654de4729774b08dfe3acb94ec5ee2a940efef53bb76d2517ffe1acc915ea5c17652ec6651d3f7734cb8b7aa176c5f2e601dc42f0700357b592d4bc72c25e42ad9897ef1fb43bec5be51b7225e57b87732383d0274e1a9594d4cc22451611ec5de786e31a69fdb3c5aa4a857e02539f1655c542c84a32f40dffc4ae8d83ae8c8f7e54dfcc4362fb4c8134a9137836f0ea40b329bb7040eacb31e7b362010fda9fabfa96622db22316c3b297e26d2b867bdee55f600e97d338cd5a2969f38a76f968d9b76aabc392bf1089c0f99dad174b6f8b8e9897bbb0680e9fb08b39f1b9d618b81e1295b546c3ddf7b8b807950199d9fb48a3c1754d97344908e8a4831477132cc7e8525a5fbbe15608619dd369ace1f9c73c67224358f4ce07dbb3cde19df4bac7bc706f18df54c17c3a8284610ae25c00913edbaf2c9fc8ef582ea3ba5c50b7d15a93acc50f632ce4473009da29a6e1852e752a15e6b7c56f5a0dfe65e5cdd00edd363469dcb9866397646722c6ae0f48502dc75bf8381225a17f3533be924a0864f60ba58341a75b1a83404d1d4380f0565c3d55533e858d4c9f427c712965c015fe91589d43a4ef4e95f4bcff164ba8752ed83cb57a7b460d2c9796177433588f800fcd518c5e99baf8ed652e61c1fb4d47a882174e4a0d2d03078b2316327799adb88d07270fc7c9d7919b6be24bbbe2ee7999ca00eae4c64c19e217196c8df9a45d7a9009f11444340eac6454db20263873c86d884d466dd75ffa5315a693fca6ed2af24452a48c9a5e36c1cd7408f5e6a8fbc41e3653986e0f355a05288c51d1f911c494540e9eb164e2cf270d4d07c334a47fdd3d870a2fe69516f8b4ddbc3c0f21179c3ba3863d2851ee1ff0f336a23add665ddbbf7a8168c6e04119eaf4944b132df977cfc826cb53768c275848a498fb3c68a352c1d0a51701bdbe7194beb546c6f9cca343a7e3d86aa74cae125b926dcb5037bf7b3ac08e15c024b1997c4d01f95fc1a941027f8efc6b8abf34c6b25aed0b4052c0bf15aa56812d90c7a43856d9134dc1140788dd2300c555a0ede7be750bea34dd3f8ccbdba143abf975879f9e374b6d417fba64e22b5c848189173a9f972176ca68e2591e4be093e51ba3775443101767db9be8dd92953ce03d91a9f1bb3ebf0a3bdc434be0197f527da23927d8ab4ce0613e363fb7acafa3f2b11ad4c1f12a1990c431bf2553d936d98822a1c893a41663b0ccae8541da379d14895584151c57605c76390b1c91dbc752acae6ad571ab4d0a47e2a4db7b88fedf2081e1c0bb0cf5f60230129711586fa5c99fd34cc3816fcc30644195c4bb72fe8578d4007f7cc16ede32eaf34ce19084782080e2815f25d117dd1d911601fb77bc0e471189fd0a4bbe01b1aa979f052e0431dae1abd9dc8e2cb7d575c5749fdd82f247f1686c24677f8d3a358b6860632d26af38f2d4c91457372c11acde9b447fa1a598b5ec1a3ac0babdbd4eb737f3c4c2f2e15b5d8df3b8d6e6b70a3cd365b57349e6ac60b8759bb09bbef1855c1468d10a777a2babb7e77313a321f2169761108d5e8f11c51c1314fe8fd59aea60551c402c4102d08f4d0c54e4a8ad7303905e42bae5b1ceb09119324e274b63c32215eedf7dc51e4f1ed19f013c5a23c8a2f0841eafbe1ae2ea5f4cf20719010a448f154397b6c65be5867508cf112f9f2ff236024c8254d921c8de4e4c39d91e847e7aef69a2747f75edde39e3adc4c653f20d5742606baaf985260b955c2b6e1947b469927a61d866f797e73fadb2821ffe03c109219078d8c24c852188e3352fe257ca3e371043470575f1b180d0747550d9ae8b55b29b06be0cdfe6955a1acba316f2e0d9fc4a99d7725d022fc240e3956bd66425dd2c844b4824cb5307af5d6d77ee97590ecd849650cab25567bdfef5661d35966a16ad5fea8ca1dad42e19bb6b2b28b06e24dcd8bb240e065ea027ca71ee286e9b8c7a4100f1f08391dfdc0ea125e35c2867aa55f21af22a5ff685ef1bc3a023453bdd381b3cc0a1f0470f0e198c8e9ece8d469479b73f3eced657dabb588b95f82de80b58a924e41146274cdd7b32aaf7c2c1f600f30353cbd88bd236c37619ec4c54f44dad9eb79b5e0f5900dedf93b43e33b94a0bbd24bcf17aa7986287232717a8ccf085ba6826f7224d4a35fbee2592b32ad48cbb30961d2412c65f6d6385107267b7595568d7d76fc8cf4ec6fb06f1c38d29357511454a28ef029da6b9007f3d6a400c381f4b0bd99c5f8371d97a7adcf122bc8d1b51f914016fc96f1ebf1628d62d0c1ff93bc16b960f93d782c66d73023685a881acef65f40e5891132e723697082b8a9bc48eaa170e5935a801914c175906b0e7a54f199907562bc2a3d919bc41b4b4fc43872aceceb494f186fd2510925d082c623a3f17f80d1d421710b91035dcfdfdb912b84270e07c9be495e8713ff51df5eda5a030e51516917605e24d29f2238d27b2a823443e8c7659c62ee4d69d3094e95e630e27e2c0c913d200e23fdfb947f7d2d2037284680aac2d002adb79848e99ca1ee7d5c40e190a3ef5f05c59eeadc97449300b0f41943dd70f3ca2f59a218a093cc036cad4f8f3bf1d488f402d5c5abf5ac9fee0263f6d44fae0d5c157ac12b78032604b618bd66a2dbec688b28a0c301ae294b1e2fffaf0f4f92030aaf4154f91baa6d1167ace84be70da0cb2c38c1f1e8a0e8a7474f3f3e508c1fc9d4a431e2f1f45d142f8cc22af65ac656b94109905ca95d33e809586d3b409ca68269bda1368ecd8e9b6e2d95327aa491b6bc162a9f6c4e8162809b0efd7bee9e4c915534083d5cb9ff27bfaa40f7cfacd1c301c740254ab4421aaeb4fdf8d6f46014a3c3ea23256ac64fb2fc95cfb99688a8788759d1dc35992d455b3ecc4a4c99ebab223d774270d7ebefa8545203cefd49bb21397b6d68664dad1b3461a5162fced871d8fc2160d57834356ec88841f89da475fa7acebcc2321f04c6cb56268b42087b52191d43bc82c29c44d451d6798758b43040617a6024b5750577ee3679f43e08a893da6c330b54cbcb6a3c6eee525d4740ad5cca9c7dd75c3d1b24801961f7a517386fb0ed2b181521ab207574fd4edfa09597afd0fe976d2edc428ea28ba9a5c96162bf891e6b50e345855bd6852252959586aaeb63c1aa0c07c422d70e5655507c090ee47e98c2b7cecfa6a4d11210ee8f22a28806b5f5dce15f139385dcccd2838a7c6c71740b80a7f0239706fde8be06cb1e8e352c176b8bb564b5cc98eec6d4a554a4d7bca07b5f72ca8131fa8479d706d367d32d1652c6f8ec4b9cd374153acdf29bdedd5d385e3b581a3142092b28cc3c8d89c3470cf56ceb9109d70d5a0d98ebe4e9432143d6ccd58fcde6a1f0eaa845175dca5ff85dcfa5448bae273be2dd5354654763de0f2fb0974164f001b42d1156ede02fce2ca912355d59e510ddef52589210506439138c230298e2c7f1b76a4ca7dbcffda66fa2a52e146dcca8ecc0cfae3340fccd033e83fb85cd3ceb30ff33a8bfaac4e9d3c28bd0a1ab89d6582c3c9cc6894e299e71551e4f394ffd81b0a67985a65c9c9850ce869635da0c769bb283bf27c1c2b70fac3b7f0ec6773351753c7527cab97a982722b422eb950b41b9e03e025c17c8dc73852490bc83e82ae956b2c546aa0b1c9a06dd9d4c60c3702753385f67df61422906f5a63cc5ff225efdfd57d9e33acc917b68661c8145e2db301777659692925511534e701ad80c46479e5808aeb1f90ed45526ccf995255555d57f987e2e56bfb04233aad88790207b67b7675db58cc00f7594bfe5089671617991124b72ad32d46b304a87c2a5074c581421652bd730808ebb039e74cdd6dfd1f8dcbb55f978458d1b161780fbbbfa52e3a2288653210c0ba901b385dd7d886cb2db18407b37e3c455b2773bc670436ff702af2bd9d87dce441ed7083231763ca76fb07389de0be1029f29c0fc873fc2c986ffb21724c6c1a746ec03729a0d9cdcf123129c550b8e1500968110c363bdf0fd68df0e3a60146790b216447f82b17718c3ceff4df0ee840f42712f9bf4b898ac9e703afd5869309d89604f2c6fdae0c8ca348e1a980303c522d89949dda61e02982814708630324e6362839f3d28b80adf42a0772c52b532ebb2636c8a006a39b0d384cdabcfab075e66116fdd9ad6c6af17cc812d4b691708f671d9a63244dd833e2c3a90aadfd68ddc03fa290663f0fc7445aee617dca94941f94ca0c6638d99b92f0ed7ebbe5fb6f1c02273751094d8aaee32772365cd8efdb5a85290bb356c4c787dd8bbb9a97ae562c27941bc68cd38f314080c89e27fc1bd7f45bca8412149be8260eec24928f77fc7a722a42e5050ab5d135985c56cb68abd5b7ec49c56ec519c63373a1c8d6dee785671e3c104ca6f5c740c7ca3bb1fd8cce68a097c540fa40f9a4f2b21a7853554556596665881038d4d4530862931aca8cd76e412bf5d2ef66b0d67ba991c4c676d95e2a8d6a4ba8b9dc70e165c697227e59323c96f28f81d79db8ac1fb80de77f13358a2255b9a8c56eeb7a4e504de72e71d31cc6e4b4166313035bb6a44dd80a369c9106e9baf69f5963f92b2bc7c16d39e0e8b88611c36523a7635bf8172b995892bf67bf2f5b4d971508f1a1a8d8d1bbfc46f87f2bc50ef30a8922a354764c66e9daa50194e3ee90ad0b59072fa84b1c2e36f93446c9b920f543ddbb0485f18191cd1aba0387d7793aa3b6e62dc49e3bb5b7ec1cc06840fb671dfb8e6c185ae1e0c62a142d244863689a5772eb78c6356122498bc088e53f0c6895cdb1cf0f646ac6db2d8efdeea5f7ff23c91901c4d496e34550695667a7db538e2a4982d34e8256f18be3d493fa2cbe46c1f04b0474328f4eb417ba155cf3d926107845f0a734488bfc5c9c3b0b236750bcbe0bed15b7a5d219a7c2df95d3505a4f116fa6dafa8b746f4d1fdb1a502d9a45849cf2cad4dbe24eae0b65cf4f38ee38078997a5ade9ccf13fe11206362300fff7628603a4707c1c2fd5eb883f5321e8882c1dcfa1867877447ed9b6813031b95ab9603ced93317b265f70229bfd702da85e3ec5df6d2b9dc2958fb9a0f99e501efd391e22c0e198eec87bd2db850058e6f42b53d888cf8c5fb400ecf6e804554fe2b8e7a3a9d9db7a7704c3a2c82643816d8362c909720a693b665d3eb\nresult = valid\nsalt = bd5cafafd71f517269ce6300208db7593c558639\nsize = 5100\n\n# tcId = 95\n# invalid output size\nikm = ac106eababe3b8fcdfe44ed3f332695aa50833d5d110632b4215a86f9f4ceebb\ninfo = 9824a5f84186c0ea\nokm = \nresult = invalid\nsalt = aac161c03b3d3cf4d94072a48fd6ca3619510888\nsize = 5101\nflags = SizeTooLarge\n\n# tcId = 96\n# output collision for ", "different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 06e27d970948bb30a9d453d843ab332ae2231dfdffbc4815788695c38368fb03\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 97\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 06e27d970948bb30a9d453d843ab332ae2231dfdffbc4815788695c38368fb03\nresult = valid\nsalt = 0000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 98\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = e86ef68c222337607de55e6bef35d9df3563cfd8754a5a231a5fb110f1ed1b40\nresult = valid\nsalt = 0102c651e047fed9c217bcf915520532d44999534c1e7e7c87311093d7a3681aff3e2d335b3c6139b9fc66dcfe35573b36a329a550c4cd20bfe2a90dfea50167ff\nsize = 32\n\n# tcId = 99\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = e86ef68c222337607de55e6bef35d9df3563cfd8754a5a231a5fb110f1ed1b40\nresult = valid\nsalt = ce4fbf306d1eecef0d60543d9726b5b3d3d5d8d2\nsize = 32\n\n# tcId = 100\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed66\nsize = 32\n\n# tcId = 101\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000\nsize = 32\n\n# tcId = 102\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000\nsize = 32\n\n# tcId = 103\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 104\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 105\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 106\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 87cf7342816d0b08822263edae8567b453a251373e2f3ce338114b6738cdd1b4\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n", }; -static const size_t kLen125 = 80000; +static const size_t kLen179 = 80000; -static const char *kData125[] = { +static const char *kData179[] = { "# Imported from Wycheproof's hkdf_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HKDF-SHA-256\n# Generator version: 0.8rc17\n\n[keySize = 176]\n\n# tcId = 1\n# RFC 5869\nikm = 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\ninfo = f0f1f2f3f4f5f6f7f8f9\nokm = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865\nresult = valid\nsalt = 000102030405060708090a0b0c\nsize = 42\n\n# tcId = 2\n# RFC 5869\nikm = 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b\ninfo = \nokm = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n[keySize = 640]\n\n# tcId = 3\n# RFC 5869\nikm = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f\ninfo = b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nokm = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87\nresult = valid\nsalt = 606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf\nsize = 82\n\n[keySize = 128]\n\n# tcId = 4\nikm = 60ab7f45b0ad534683b3a6c020d4f775\ninfo = \nokm = ae5dbce80bbab5bca5b3c6d3b7e6548fb2c23b2f\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 5\nikm = e3db76e02278cbd2adbcb4555803da11\ninfo = \nokm = 207ebfa8798c6d8d5260d797fdb9c9969173442186d9e932b18fb589fee2fd00ca4ab49d0402aba2c1b0\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 6\nikm = d4dcb92a769f57c8bab8a420ee0aa351\ninfo = \nokm = d875a072bb18fd7717ceaac8829178884b8e51a926849210caf7f42574109f218596e27b92041155d2012917c20e09539bf52016d78aac0b53a51d9cc21e3b15\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 7\nikm = 2d43e54bf0c94c9cbff4300f4aa69ab8\ninfo = d674da3bb47d5c7e38b501e5251d9348af601c44\nokm = 3d36966f29c0561b4e50f9325c7c98292b6d28bc\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 8\nikm = 4055536896c406d5fe14a6cd6b999bff\ninfo = 2094768a8816f7df070d6e08b7ad93755dc9024b\nokm = b10173a66a08fffa6cf7c1057744eba73cbbde83a3d8674bb0bc1a46d80792a9d5a0d2ca72510e02a6e4\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 9\nikm = 5b01b2da3166f217cdd68de8af60078f\ninfo = 6884cfa7ffe8f27bf4ebc6e46a7e01488c79243a\nokm = 7a8e83577d8aeb830d772d8e42fbd105e54ee3f38da12388030580c8b8935f4a2be01c5092f28d5b1bb757bec0a527250eba2549e770d21224e1cdaa5bb76a98\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 10\nikm = 467403c2ec02a235bf730ff37e8d8ff3\ninfo = \nokm = 4b1c4f54615e31f713f2364bf194d3f14f68e704\nresult = valid\nsalt = 41f0f173d307d40436c25856cf559f96\nsize = 20\n\n# tcId = 11\nikm = 3352f942aa93071da6d39cc5ed8dc460\ninfo = \nokm = a6823c9940138becba3f9baac05ec119a2715a018f51f4c0ce2add465db8635a6453efdf7c161c2d172a\nresult = valid\nsalt = 57a0db708b25a51afc4271803aa35204\nsize = 42\n\n# tcId = 12\nikm = 08867e76311126089356623ba5381e73\ninfo = \nokm = ce632c353328d59ec519023d08652a97252f2c8f3f29104237fe35261c82eed7e0df52514a157a00fd82d7e46ebf9acc23512e1cda7d5b65b92f692965943e8d\nresult = valid\nsalt = 0c164c443edcdfaedb1ab150f047951f\nsize = 64\n\n# tcId = 13\nikm = c55c41d69d2424a520414e3662aa7303\ninfo = 3fdf20538063b76901d61bbf9b72b0c18749e00e\nokm = 7fce7c021469c8e016f7a9eee111ad71df7c4fdf\nresult = valid\nsalt = fea9bfc92b74337e43a201a2dc199e27\nsize = 20\n\n# tcId = 14\nikm = 5d3db20e8238a90b62a600fa57fdb318\ninfo = 2bc5f39032b6fc87da69ba8711ce735b169646fd\nokm = d3e6274c91a88821367b1853b852a96f3ec12ed466769fdb88e14622165d5878cd736fecc93b9e8633e0\nresult = valid\nsalt = 1d6f3b38a1e607b5e6bcd4af1800a9d3\nsize = 42\n\n# tcId = 15\nikm = 8677dc79233ef3480777c4c601ef4f0b\ninfo = a38f634d947819a9bfa792174b42baa20c9fce15\nokm = 17c2b03dc593fe9bb94f5b9bf646ff15749e82cd4bf569f7806275c241c83e1fe0615663a628ecfd7c1b700215a450f9f42529800424c4707d54488150299f11\nresult = valid\nsalt = ad88db718244e2cb60e35f874d7ad81f\nsize = 64\n\n# tcId = 16\nikm = 0f602703d37943e0253bed3da331aff4\ninfo = \nokm = ff23874bcf844f88f2fb57c0c3a4e3a7a498965c\nresult = valid\nsalt = ebdc8510499f69b2e188daab77cd819cccb95f276f46e6b2be11cbe72700\nsize = 20\n\n# tcId = 17\nikm = 9fe65737574c5c7aa67646adf8230ba8\ninfo = \nokm = 19d4b9e3bf37ca1affeb953ac3a593882b2dd0002409be198718b376253f1e8522af9f276152739e2d5c\nresult = valid\nsalt = 73a34648c152443586236abcb46a090ce55ef6c7f282ffce6342d694650a\nsize = 42\n\n# tcId = 18\nikm = e8f2b1c3e6a6c3d5ee0a20dd47aafa78\ninfo = \nokm = d623e645a84b5ed4a210b9457aad79c9c3171f306bdb8bc9b60496a99e640cdef1cfb56ee336d216aa20122ee33b91c7aac3e5e7d56d87dbed3a446cd5224208\nresult = valid\nsalt = 3f5e162de91e0782cd189f3b7778cdc2ce6bfe9d3fe841cd3c70475d7b3c\nsize = 64\n\n# tcId = 19\nikm = a679521cdb56aafc5a4b76db0431a4dd\ninfo = 44ec41ab4f4e64f4a36e5e30c9f0dc1d77ae4974\nokm = b75be6d7fdb9a7c58514c81e6596973058e8198e\nresult = valid\nsalt = 123033b1ddaead83a4b9cfef8a660bd8e00fde01e67c35656c6d7607d456\nsize = 20\n\n# tcId = 20\nikm = 49bf155ca102026f2a217ea1bc9843ac\ninfo = 851bda4faa8f7add2a3cbf0acf9c2786f8f955b2\nokm = afcec12e5ba6481f144f6e6bfeab0a054b30f2710aeedea90d4be9c790c8e05e601fcb208afafc6cb991\nresult = valid\nsalt = 76776e3b4d75f8f43dce4bded71f3b1ae6bcb012d9c0d59f78248b9427b8\nsize = 42\n\n# tcId = 21\nikm = 6cf725e939e8824d4392233eeac75d30\ninfo = 495425d9727fee2e2b7e78899868c1c3e7735e1d\nokm = e70ba99926c4edd98bf001ed3c8a1557987449a6fbe58360e96c2d1a3c1f2eac7806fa406ec64c4dc2a743129f97ca449380ff495462d1b1858af83d40fb31ff\nresult = valid\nsalt = 1e72f24b05a91a0093f34306ffced79e7003055b0833c6d0f27a4f33a1bd\nsize = 64\n\n# tcId = 22\nikm = a319ff7b5ba9b14ac72b681cecf0f742\ninfo = \nokm = 31e7b971f165eb923b499460c94937477fd61cc4e96c27fa2abb552accceef42aa3a35637bce32d996e9\nresult = valid\nsalt = d7e3bc6daed343ce77ef793e15a8246e4bfcbaf83d2ac956d0661d1df7262b2e7311623dfe4152caddbfda8fa8ed7a82656ec00b72c5adf7c9d388e5b3bc8d24\nsize = 42\n\n# tcId = 23\nikm = 34bae5a158c1678aa76a744417a70d7a\ninfo = 87ec30aa53acfc3d09ccc1d57d654fdbce403cd4\nokm = b80f7525a93a3f630465033ac53f1ace76caf7dcae3bc7374ffdc6d1be60179e1adb9aa8def2d47823e8\nresult = valid\nsalt = 1532075f363e061133780ac959bf653c7687d181b9431215d6f62dd2f1ec3019d61c50fa82c70ae25e624c849a276b0c57d7c02a4d753fe84a1a6621e9a5ef01\nsize = 42\n\n# tcId = 24\n# maximal output size\nikm = 195b2a73c91f69140910664d79ee7f3c\ninfo = 5b3afef0895fee8a\nokm = ba560d02f6661eb3d0bf3a17438343b231d2757e4c8ac2d0f57de4ae267f3b3a40919c4dde2ad7d11ff636e25e4fdc21db7c2b2f20fa1ce7bd6acd2d534f1f660e0487703adde77a0f72c8e3f2b9202c94527e4bb9adf53a0b897a09abc0dddb7f94e6d6ac00d8eb5233f0b88921c8f4b97a1ebd8dfc32ac5cd089bf07720bec56f85dafe527cdbbeffeb168c8a7867fe35ff6fb57a969189d3c17b230db2d213a6860b5cb678fdc913aef231601d131588f021799625c080013a3547cdca49599368b5a483d830fe182bf4639bf830bdba4e301643c20c09434766dc554d7d4effc7165933ae420b136623ca1314383661593fe5aedddabdb44f77afa633149c832fbefd1c884d2717d61156a1916698ecb30aa2f8a43ef7238eb11e4cb1acc7e98a83f66eb8eb4387a7d6cd26249338054d9e5328d97506ecf06e9bf8923756f2f586dd8f17faf515c75d140f502fd162eb074c250b0c4430b659ee49c0dc2176d60ae2e4818b7089c1ba58cf1d80075ac3446fc8f14ad8a9fe26fc677c398bcafb401dd84755e7e550d20684650ca590376b140942410173149fbd9cbe4781bf81b3a3a2e04130e0b392d747f16aa54b323a8dada9fc690e05f75d9108d49ea10015c90505c2d500ceee985354b28fb74bf5f45c3c412ef281c372f4ee2f8df2ddbe889a9cd541326cc2528728159019bdd4925dce7d8cb6c6672298e24cc8760e8a33a5ec9dfe84725dbaba05a8215b30f0ea143d53706d99351f31fc6632f6a28b57baad13bb6768cf52bafd820ad0b2949b789bb4e4d449c8cf6e6c1543c2882bc225f94f70ca6d25855019f29f9d3ce5746ae88a12b70aca25cc16c7ad19769d63ad0de5e0207c994709755c2816febbdc3c381bcd90c5252139bfe45dc86d0ccafa5d437cb3c2c0cb74c59a1f67a206fb0aafc7282aafc7efc5de534c76425c699dff283cd10d7313f342ff79dca06a12dd44f168fe857d41658015e74f40c76f6765b57bc5827082b6ca55e57221428e812b74df3ff82d18678b619f1ac727751fc4b27f1dfcff461ad30bb17e2774288ec3e337a7c8438877f8006d8024c7a62a02d5ba2f1eb302396de86bccff719dfa721abc5be82373a5e62b69f2fd02cef4cde6e66e98c891221f0de23b6223470d34e357efac653c943ae7ce487", "18a549ce85a0c5f53b966e0ae1495efafa6f70bfd73e915b67cf9439029153161459ed07c7d3fd54cd66a89d366ff9a86f5595044060b612f2ec65e9f2216e30489545c706d79d23abc7ca26aa486480047a92ac01164c3b97fbf253b722c4545ab83741ff483d8ad28b54c072f0ea72119f2807ef71994d18e9015a6cd813c525ea838d3a437640e4f99273369cde21dd580b8e08865603ca87d9d28e1244e93e560f3fe4ce219b55f8f6753e87e59dbf51d89cd4b8aea2f45cfc1be2863b108920a5c380fc1f07b174c72a3ce791bf0799089a571a6dbc0adc4ea668fd8f6e4a8b5a92363d00f92ece0ccbffdebde591779210b34b329f943c426788661b58d637a37094744d7ff967bb27a9d4fbbf00f3a1c2c49e50c14b55e56224d98dbe7bc1e7612d1fe956f048f831ce663b85778478a8572a63ffbfc04e9db2bb307c655707548e48f2e91b86cedb00877e9fd7fea3f07341f4ac342ed020e2ac993209f7a721ae8ca4b9273790f571de9f9d22ab89572fc9a9743efe5a6accc921be33327ca7fe3d3b1f980919f2f62a58475a570ac9f08d39c6e0f9599bb8ebc2101cd9f60da8331dab6dfa3e65a6fecd113f8d28fb87d3750a7019527b388f5eac13b49640554f031e240f52e202e55938b80471560437be12619e1bbf98f3ae350f5a03722e811693285b4774505fc36ea01a97faa35ecc30fcfa8eab0fbf661293bf79877014c68cf582aad70e5c212b18588a6ef3d75202bc4a02f86c62f99a97fb0ffd980f2d7f2fbe7f1eec22c6bbbe2685b4c1693b0429a5069ee387cef60bf0cbf2fd81263085dfb22f404e09284f075d782dc3cdbc24cf242e6a4c7ef6dd65f0269c5a9b49baa1bc0526cd72ee78db3621fa294ee8b7d6cb15f0edf6d9e62b743f25c38f317d100b706baebcffc11396d5400af4657a267dedd3bcfd96527f03be8d733195c0c47d7dcc97e8c8f639c7c972338dc88861f023b5621b6b55549b47aac9630b19884b072aa58fe1a975e86fbf8482821147597914b28ea5a84fcaff9d8ad021282df1a06feae1d813f4094680c6709d63a3907e98a67a5c7a9232e7d4c01bceda04bec5a5dd8e29753af74521d01e346c29955bde6112e131948582695980b71a777e2c42c37c0cec771b1de9f737cfe5301b487e9bfcf35d2750940de6fbaaf00b9897e3fa99f6c5c79e5d27acd055212e0dea3162b27e2b1a400eabf4e8b78077381fe8bba84c8732f469972a0122b8009138ea77592f68717d66bb8ffb3e9bcf4f77a2b472a393f5c6d7758afa9f6adb1a939da7164c22fda33f290bb15fa17ffb87b445931248c9a67edc3e116bbb75fc9439ba7b451e06a589c1cf506a04c2d1c889ed5b9af2002171055580b9555b58ce083a9f5b9f05d440e7fda4eb9a62df33ce6ecd2399ad2725f1eda7568e313f3dfd85d240924ac987d9273f14259170ab30d7363929e3f22dd2e3976b5592e73ba3b4a2f58c4f490affca796ada73db38bdf8b56211038b22242dac86910c132496e9cd1b7fe0e6daeef0c44e31df2c7424d5a8cca7fd812b5b90fe1566e7558e22c35080a73a12c0057e024c60bbf849c9bf20b5acebf48acb4d513ebe9436fa6c6f2c5334504162e6a0e4297c814408483ef02a21b9bdcddb91e73809c36ba0728659eca89fc978f1f154fbdc84638e00620b505965be1b41dd7e2022fe2100cd5aaea63c2e6f1fe80b9188da7655c8c1457ec3f2b02a839260b8cd39d63a6734064ac59251a167e6d25d9d0384c9b526c10b6b258e40496fdd46c85c3ef2b1e4ba91f5c27ba1624c9135535fb922b43970cf7e9b357f2057137cb3df1375a6e6df71e392f2efd6c5ea6e256a0f7b766c30931d89b09dda788e082f9cd4cb8c9c82734d83b817de5877f3ddf0ca4f5392aebf9e70eb9f5c35ad4c40b26b0c485fe8f46638d3994011f2883a70f898fcdf84edf7f3e95309f2e3b166b0bba18f385cdf1d2e530632422c81766fe9e841c205e5e792b49b572415a5f7f5024aaee6e99c65f63df7967d8b3c1976a6c275c7e5668cfb6378bff333477bf599bdd6fc8a969287f796717f6713b375a9262e06fab02684da3ec5d533de48505e41b766540aea29ec73d7c563f2c5d131c1c758aa932a6e5bb039e725e3958b4f1556ea6e2307e2cf3f111421e4acb596aaf6d83a483b11a5c8dd44ae3ef5e3ad813495b54a5fb2688ec3d22d8109297a87fe891e9f67439f0ea7199d3bfd41ab61531414a4f858d0af8338753257934c05c25dc4618b90829c3a7714e732e4dbca579169bed379a46dbb638a7fdac8838d3b4f0769b75880b142568ce9d55e930db5f4d158262b1dc953ccdb6e0fddfee14f042fbfddc88d64b46b7ac177d26c6b7c20341b53a3f31b5c53e9b824b9d5d5d0f7917295409fb497b7ee9450b9d242b009792c8bcf25413c45ac27532d8f36fccac3922fd6a19d1868b558dafa58680e3add12a3fdbd1cdc92f2aa899ad36eae392ce29fbe66af974361a12495a041b5ffb82843750544c2a3a0e817f55877538ab75524b09ff702d04d694b9f7d4d6716a9e461249c298d2d4dd28ce99c64492477d9aa1b1294bd51b45eab201f4c42636bd2dcfa38f509ab8b49ae4e88ab4ef628491b77f073a4a128f452a7cbe3d82d26ba2d354af17cd6bf77164269da782261cf6daecb328573cf975b4d6e8a984839b1f3e6ec81c5c692e32f78f158c1f472ceceb9b448cb8676b56c7d6bde38fb9a37170492a469f936113127e01a8c3801630d56576654552504860b7677d4e49e021640003c093ba2efa8f4a9e2e3286327d7a84527af378029f4306ef188f02204bad184f9a3c977e9a270892b9c0af614373798f5a089c21db136fe3d078586875e6bda63ac7c25859b83a3d2979374eceb99039baee563ac5c6fc54e7b9d818f6d834fb240b3393e56f465ac497a95ea743d6f48a8e34f9c83915678d6dd580aaf103fa8c87ccc667bc66b8a6964d7705f739828272e4e342d495ce5b10aae5a17c68a86d28086ef7d7cc363fb73f763e6b72975f35b3e0e70d38a90d30577d86099de0d2f4570f852b52876c86a2589c199ef5b22485babf4d655a975e22c9c21db0d01dc32a3bd5b808a7434f3025e04a1559f9b1c8e74d928dade07d4fb01e37691077d4f2b9006c15e8122607a3c3176177ba1e6a8238632f705f3f25693c9a9aabee45b9296fe3b2d9333caca0935553f0fc2a57535bf459066442a922de1b96fdd69d5ff57a051eabb0f4781a46f122d393d21fb0d1856d40f6805546fe1d0778f8ee5d1d41d274f6c9edcd0a1d96bf7360389319a21aa2d116fb6ebc44397f1bf3f7d8382cd16f24ec49fa0285f293ee7c3f6b560097b60eada98927584c1bbf30ff9432e6e377d02876390dea6ef7661d3c3d3a7b481883c2e49714238dce4aa8c428f7fb4a5f601782d8b8f719ad89c2ce74333dbd61c7262a5145f5f7b42d3d642e0c393a6d5a2d4633053a4a2e109d70feea7b020b2691c28b5844bd361a442ee779b836100f8b08bd78fa9cf0baf07722570228f12971bf927e31c61365faef3d1e7692f1e48a579dcf3d5b64ad28fb0a7cdc483dc654ce82ceb69ede7f6a960d6c9fab900164aada8a0f600792caab44bd0b6dd8692d6060f90a751625968413dbe4d1d1a2ef3bbff2a21566e4cb41c3abf7006f6d81eebd0f9afcb4de724d16bb0720553523b33654ec6a0fef8af2d49a171dafad2e3751eb21637e4743375107925cb8e9c15d4f6aabcafa3a9659ee3dce219b6cb3e5205b836bbd75fa21baa00e7885613a241c2de00d0cb0b5de2b944f97b0aa758eb708872f7fb4110b852a27286092d31d2f49ec5104212068051f6ee4576f55e23447aef5172673e6268b977156f5bd5b23640bd0915d2e4313557af0ec6d4d0bf98cc881a4f7b5ccbcb77b74ae60c2e4b1c2c32e3738bde4ba6ff854f7d3912df0e28dd30b36f4008430166aff51725cc973c8c69115a219f677390b37ef442257d46d23fd3963904402cb93c6b6c6dad972478a0d8b79670f6f69f9e0cd8d819d8d1d45c38440cc749cf09ab90434d7b57fb1e66af9d09d38c3961a35cb526023b0469c948199aef59a8e1341ab2a73e42b9f05b8ce78c6ede74e9a355ffa0b81aad630bbbe9ef325be7149acb62b02ec7f0dc72b7ac576daa5b19993fb4a52ecc154935beef88abdfd133d51e9953aaa23669e423467a2be1bd35c09c5959f5861a7f9455fdbd25e4a792907b33f6db7f8ee11e5f36aa14a277785b0af2b8ac49700fcbda5aa55c47a24dfc8081003343d55973615b3783037abde6ae0bb35f4175f01b7ff3054b64ee4eb18cd50e0b879b6d41ccbda2638a33ebc23fbac7a09ccf92e19a0bd62725e555079ab1a3f4362ff43b363cae144034f33366f108f284c63ad8d4a798a540c6687823dab864832dbf299e7065594520156842659efad38e48464561bd7d5259af3e590c63cd43ecb95720cefc5b28c3d6b1c7128334db2c112991addaa5b91ac37f06debcd89852c6e8438024c5b4c10049b03169172ef733b1aadb6edf7add5477fc26a48ed428cf0d5cd336e646d17af02642837371913c7286d71aec82d4854617dd362bafc2d582e87bec7afc57ef3c81876e201ea87603b208031583c78876c3f9eaa3fd8995fe691d5ab476a91223c16ebebdc299b23eefd6e93174624021510a7fa1ee3c6cbc268c969f99eafd01f0f86e0146f9fa963c287b704d6fb11ee0b7d465cfc73d1d4c915cf2de87e94e2de498749cb2e0ee9e3cbba76b1a4b9e9e363b7f35088e99be1880fd235a06a614c3e82ceed6e27a72657a4d4f860b336f090adbfc99d4a80754cc747bf4151ab57358b6b4ca5233b17a2b2d1dfe8ef9ae0a92bc4304653b95578aeb5457ca665323292c441f91b6e237cf3a0b2cbee2f1ef8f356c2b42f4d2dee26729b89ddb7747145fd5e4344a82e4a3cedee77506ff79115f00aaa4ee1ecac6999a543d745cc0977340a2502ba6d32607ffbeb3c693a7910907da1a28f6818e6bf83fc72628cda0ec80947c5fda35ec61c3a87c89f1cba548d4a7bf0b911b35b187179d1c74ce03f14682eccf253933bc0b2bc3d4e3a8cc57ab254511075ccb4cf162cc11d36da79125e31f6ae4e758cc62afd8238b28ab8d4020006fc90854eb729edc885179b2f011b0f6d1be61a47e7e9e52110fd8eba49443bb3ec68617d4584c6e6cdfb6bf85db554d777ad8d7fb1ce7fedd3b873d8788a0103a9bf9dad1b07498eb026f455793bde9210c11b173c1304ec6bb44ec007451be41206009f8c723e9e05b3add083abbcd15ef7026af358880a3e9e66ee891c8c36d8133c13c0afb903869980c30d1df0ec297d0f5434fb3d66ffde872f3d97a723d1a30cc297a2e49b7a4590617e6a3c355cd654c9f5ffc5145ff1484b7f87a1e3ace368dca920a593580520438463900d1f079f27ebf68b48dc0fc39f7d7301b3224b760bb1170571135c82fbf1e1d653719c40a726b02262e846494e83a606a47283f002739faa870593c9e57270e36fa7ef18f490f6ada2f93319a4876b3f481880bc762d7cecd0569641b0705914090185793262c8bb5bbd669c86947bdc3b908a8f8abd9f0175dcdea4c952e2255576adf472da19d077e2988b0d5ce05a1aa5dc5c02646ecc7d5fe0a4bdf233f66cbb761e43e5c4c0863ea9e2876c9f846f6bd1b9b84d2521eb8ca0e3be5a9fcbb76713c69d29181acc9f97d73986f95e140d92b901fbe7399aa191d027c438688", "8ed49665ff8e2843745a065809990aa0c4fcccf24220fdf1e27aa789e334446e13a5788a5e9de3e575f582df12dd3e520fed30cb04d9349424b71587f581939ecfbeb7b48744cfd30e551ddce85a62b903afb33d999a5a1fdc40215a0cc01812b41a2a52ecd4def95ee47345d90865e8f4269f16214e97a7e1df0b4de2e20359a89f88ab906ae05430a211cfa0a33658fa65af3742c1541be4d3a6582fc4b20e42d9e818a62125a7d148966624cd65ebb5528c8c01dca81d20381d832add767a0126203fe9a2837d0479727876673b611afc9a7f5e87294c00deed48fae0fac6506aadda0f7e999a877f527a61d47e440c5f19c8ce12a8b09dcdcf4ea96b8af6fa7e83caecb2ca03fa35a454c419e1121f23cae9d24e53ba352c701211f3138c413d431937ed83da75aebe0acbb8ec9837e857be00a9cff2ca3eb13f045f347f7c745f56df8b73399b1f3d923571a20b5a9a7ebece39e8f379f6df72765272725bea9612e5bcf3cfb6adc56dd05f3249e799cd02adec060b809ca4425e1eef11f7ef2e5721aa37d051c34daa07fab8e729af4b981636083621d7044c13e52c987621a69ca8eac3889776d9c8aa3070aaf563f96ca393d118ce161fb7911b2952b8af451e1bdb717fc70c6e24f3e2f0048e1ca36be23c13d9957d6a021ebb35677f68fa33778ef7524dfb15ae96a296bc393ac5f25261a422e1f7238464d13e3f8726a75d10ad9fb74b480d44c2e9a6bfe0ca0c8d22fbf0f9ad53e9369d0ffecc27b8a0dd1b85cc77b81e701706231c39a045b1bd891a54b0ed1c87b282de40691dee685423f14ad5a6304fc5997482fe0d1351b34136d60b04cab130ab2e7f5721c6e021983dfd3e868cf2dd9f0b180d5218eae554fabe07a62aa7409a93e7e3b3718961106ca3d1ceb606a2e6e93e5d9c05a8d43d34ea1e14cfed1f25074cb7bdc1289f3f7a6ddaf43cc5e7508a964e0a93e26f6711cd234765f7a35c71975ed4e919f4c45cf83ce20076f5238b995a65cb0b402d3690b0a36cd2d164bc7ca986327ec955f49fad0c3f0e94c18638c5473f5b20ba654646d0178e3ba35353a278f32920a75567c7b87991b413db47a164acb93f73339bfe0f72b034c8785de3da8e22a445b5bbc0d13ff3312a13c11f8b5326e8860c136fdbf79da666469da270e0167735941648dfd8fe1b23ce03305bcbc60930906346821ac373a51eedf5c938d3c9f3de9ab43c68a2035068bcd4eb1585c0a696090c25c2825382d8eeb4b75bafd6e5cec3327e80c72b14445aced447bca79ce78d0e1869146c12fb57fc0e27529cfca81bf30b5829f903ac1a36dd560e2ab2ca33c521dadb57c3caae0298a1df936da26a6afe2c9d280f8d9861be48668150385d589ea349cc77c9f67ed448a01b4615decfd902c01ba53df4416736631256afb890af6aff39e47e5cbe59070aed031f20f16e3589d63540904d7ad5709c4830f09c1bbd5b33cd47ff3da3232e11c17d4d9eb02ceb827e092e8e7b7614adab4b3d9aafb45b083f4cb71e25ff7a865541ea185d95d1e80224c732cc5fbe1f2df689fa4ba1753d148d7f6b1846736071d9a4cecc99e96f47f6ff082cef981183d01b08fd14950878d7dc1101770fb3a1565eac3714820c0e058f83b7f85cd38a1ebe3f0fde0734e99efb883c1d08900253963e17333dc90901c56c8fcaf44e4389cc0515ff06bce030367c1301653fee32dbb8ea88c17cc1346aa072723cdf0644ad3d6d5f0608f21131d2fb7d3c994db65f2a615fb21087b4a9e73d81021d1e0316785c96b8236ac14ebcc6efb194a8f05d8120a6fbe19429c27ad8cb8db54e9404d04f94f681791b8d3251c9307cdbcfcc3619111fb10b1daf8de24da449e0e3c6f4f488dbd42c53ef2765a6e5d1a349d13489225ce8eba209ea228ba155648f59c77d5f8856e80e515741aab423e7f3ebe4700aa5c32d30756c4e37d7552f8e63be7a4612a5f1c6ff6c5846bb85611ffe0241200aa188cdd77303db4ad75489afaab6155212a1aea646b50221a9479c0c7ae53579e44c617d20e6cdadb19583835b19c41d230535cb7b4d06fc286554db084dd5b07e6dc7bb798549a68055b86ef86a119e8dbda606e006610f44f6fb62b0c1abfd3c69aece8746ab44f4993048148f4fa6d13399c70a422383be38844c0a1ba4e4b98c0dbfb2be577f62a5669d05ab1aea757959e1c20c691b1924a7fa7ff0c54a8b7388f1f9eb1641771b782a04366ad5799631fc3951ae756d2f54de50a356520be51eb6699a8e224bcf9c223947235da1286824b0feaad9681e68583697da87f55e0402d2baf68251f938930fdd1536cccac63e2ef55d90fbdc91f725846c592dd8b154e19fac278c3df0c90b5032d79ffd12203c626dcfe3091b59624451cdc9811cb5bb61e2894e0c1d5bbd462d2404302dd881109f99cc5b37b3d42ef44e55a8d68eafc143f01ec1a5d48090745f97ff747fe1aa7dabbaaee2d107d73852c38b35ade93c7e7a6cdfd8b3dba80a63626fd0d10adc304ab5c28fdfeecc83f3e04fbb298dff5233f3e7dbac1736c4ae9e80364b06f8bbade5fd619f4655f5f73ae4e978799f725c3c6f9e51528d9842a4c9df7630c857e856dfbe0d7c7753233a16151eae8bb1e018132a28156ccf9d5a085b73d0a3a530ca431a3e705f419091fad1d0dc3e163433f4b5846db6c15214580a533540dc1e14f90cadaa64f662f41377bf35a86310c9bd4ea2a890e672b5a3cc1ab945edaefaf5a7b99f6b664814c728e1ee958bbfd9e810502cacaf5b9671dc8c52982c810d9b737f7210ba7eab97ed95e03dcb75b2b4bd87b19c474a559829deb5f2459d8c25b4518821ac3e9c0294393126efc184fb52cd14e6381a976ba1bb579ca6249ea09d8fc16de82da10413b1251e9a8d85efa079f1afd02dcb8d92876e4d24fcbbe9b134183a28cdab503d18708395c33f94d50d9d4c1d16f2f417fff903f77c6de34e1f506dae723063052645c98217677ade132e466a07a2256f87aa7ad9bc1061cc9482c74717e544c2050b0ea8729bc1a34ce7ecf825b2137a815701fe04c1a3e50fd590521bd26ca7a193a45f864d33e8c7de51b3c686c47074b03d2c442a6882bc03154a61ba68a5ba5a1bc72a5d8c455f0c67371aba5140793aa1a3dc158004bd4da50b70d5a67cf250c665cb897394df202d79cfbb8917827c705a481c9429c7ed6b2cdcc008e6c33132b9173222ad2219b461d69ccbc63a0587bbb550d0e07711c9e4da24a29664be3222c7463661455021fe64027c1d31b052104c3f7a13c8b669aafc16b9558a0431ac7e997884a8a39f92511caf9647cd8dadfeba6ed0ac35813bb9149ac44f1597b00f85786ddd972474d6a572954383fbef702118754ee38b24bcb72ebe91e9ca9a84ad5cd6bac94157bf63ecec1f77bfeb5942430037378e5776d6931af7254590b90b8ccfd3e05f37bddd9dde73bfd7e3b285bcc494964d180a01ceea8f8cef3b7c34e9192f1c89310c1734dbef35fd13d612f699ffdc50e435a07f556f246ede04074b465150fd8f0d9305526d869db0f1b90386e5f775048e6bfe2e826320bdd95ae65061fae55e7a6a427bcf248008bc7d9a05ecb8ef768e24018a3c4063fc2703e650f4080ef663a80525771b147064037eb819c3f00e9b980dc091f9dd8367e79ec2d1c30ca6aa598554af86f347cb95d0f15b0a41423c27e1491a82a29284d5e0721d1ca8b515a2e2f365add9d4c577d7d769585d2e826dacf5e501b25ee58d1ed04e16955213f557b9d774c26fe2c621c0f38d4bc3a2ee4f39fb1738240cdc121c09f9ccb36fb3c839733027152d4db959a4654ed1cb50e35ab6988a551c560b62ed5c19ae6a1d28673ab5a7c10cf4bd956d14016d1d9e063a8c5135b6a4d0d6ad15195c738a9b2fd890e834b0cbb258a10acb46014c08f77458eaae5fbdcf3cc54a404578fbe639ae1a46139a906a94bffd319fd5ee35d1938dc165935bfd453046f5881bb9161ec199a1daac82dadd11df0427afd77c9789c0fa9cbfbf7406aed350f62ef54a54398f013fcbdb5b9ad58a14c024a9e8b390b06229e005fec042a74a3e169d6c54049fd303be7344695942bd50a4689f5a7c31c63e295d38ffc90802844cfa92980b429fe1d2cf4041f3131090b59bcfc7255319ce362d2dd90cf873f87ef01ee1ccbe31a8eb17cfb2660a169375068e2bc4d2a318d964c0d3a514093f77b50f28498e4fed5b90804b649002650720fb0eea7b9da0f92440c8aae5e4017c67475acca73c946425a588d50e5cea5bb5395b8db5cec759503a6e73858dc53e76bb21320a740cec4023195687cf5e82a68a40f8acad2e68df3b8949af88ce071d2db7b389c09ef55b9d7ff4d27d157bb78aa1db6acb793c82cf0c798cd204b48622a5f6af33c80d4d8068c2468c8a1ccc07e44fa27c3ec9d505a3aae1e7508254921905fa29f5c2e232ba2e5380f64603f44ac8acff4ebcdbc53b4ed75a7534bbe9ee9ceed15d9bedeef5398526b31a766364b5952ee2809ee10a58de9e7d04a1f3b729\nresult = valid\nsalt = 45cf5b7711c199f70999902eb755aefe490c86b96cf86ac20d4e67fd87a1c8bf\nsize = 8160\n\n# tcId = 25\n# invalid output size\nikm = febaf0ce3a452bdad48338ae258775db\ninfo = 572d90bc31fc1edd\nokm = \nresult = invalid\nsalt = 701dfbe3f22c13268a04871dbb9711f371bd702b2bb41dba24409578e6481bc1\nsize = 8161\nflags = SizeTooLarge\n\n# tcId = 26\n# output collision for different salts\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = e7f384df2eae32addabd068a758dec84ed7fcfd87a5fcceb37b70c51422d7387\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 27\n# output collision for different salts\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = e7f384df2eae32addabd068a758dec84ed7fcfd87a5fcceb37b70c51422d7387\nresult = valid\nsalt = 0000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 28\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 12fce691378f28f92cb26ae9cc7ec5a34007fc693944ab79b6fc461093a66c4e\nresult = valid\nsalt = 329f445e7de8a156cf26a0208dbb028d9de6ef76b8de67ca634f4a5a732138a1bd436a7b345d7a0314c7ed0a00b0d34ecad2cb8bd141e2ecc1c77e237094d55154\nsize = 32\n\n# tcId = 29\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 5943c65bc33bf05a205b04be8ae0ab2e\ninfo = be082f301a03f87787a80fbea88941214d50c42b\nokm = 12fce691378f28f92cb26ae9cc7ec5a34007fc693944ab79b6fc461093a66c4e\nresult = valid\nsalt = ed16eaa37a3cb51a9ae18e69b1ccb5950ba29ece2e94894ba05715bcc9d926f8\nsize = 32\n\n# tcId = 30\n# a salt shorter than the block size is padded", @@ -3445,9 +4083,9 @@ static const char *kData125[] = { "8e3197751cfc33c0d47e2f32a53440109bc257e171bcdcc2cd92adc8f63eeaab0a9d8111a752d37998ac37e47b1b73abe52036c418b039ca2d7214b010104dcc31ecda77670e49ce591e8c422a87243e7529d1a214a84720328811bba534b64a4a893169322d03b2bff9fdaa6df1ac474bb7ff285f3652d171a460cdde44706e757ee9b9e5957d3503734df518dfa30792b6d916877c61a96bba4f104b409f6e6c378dd331fdf6ad124b2b83b885838cc8ee3092b6b30e752058e821a66b217ccbf651dfc504450e71ec6586e5f17d68e7114a1caa8da5360a5aeee9de512ef24aedfb9b48ca3d218f2800aa0c2b8e9e7cddc99a7efda35d71f11916be2cffcf12be9dca9644a856fc64cccc93940d2ecca09b2ec74af5279a3b33eed028ca439e2aa7ea02d043aaf3bf6f13511ca11162951fb9a638de1bd4925d430a63a02da095bd1439f121de1c619627edef0d652c08e4240509f99a715c51e30c6a95c08705355a64d79df580e24700283bb31692b1d1d558187d13dbf61174585915f5da61f22792572de06a64be18270608e0f4723612ca55d295d99a12751d85a54c153713d8bd3cdd0ec92f5ac910b8d27124192cb6d61479461fac6b4b6f0bff38a67c131e3a01c2eaeb6e88673a2b7d45ae3275a19e4a127a672cd91e5497a55ae90178d8130862a223a4b20b3ef51dcf658d63d26514a22107a18051f7f70a3aa1bc69cd60de295b3ac351552b909605a48a983f6ebcfaa1bc13f75db0f92ac8ee4af89daf8cedbc64cb880ef0f2b4679935f0d1cc60a60c5024a7c16ad27ca9fc21c889387977ea6b497d7c3d5e5c45d1ece8c19cca96c4193a19b36b829334385dfab2bac6158f47eefbeec3b171069f516d0fe68fbabde4009d09735fede9298d59d70791ce0572a48283a0549165f9937f165b91003dbacbedf6341b97115710021c1c32263d0edff55d10410628ff4cb5ce3b010951cc6b16d2756eb14ade18005944f0787c1d3860b750ee1e90d1d7a7bafab9d45e29260e0f228869fb353bdf071ac6fcdc0b87071b20d131cdc8305c5a91352d9ffb376e86cd72ce5973713f1e0a2d2079b133ca8a27ca6594c4631900da68dc067dac381dc16ab4da1cdb1c494f295cdd83adc791644fc6ea04915cbe120bc4f2c0e0a93d81c9cf1ca9c302497068c854d2b26d2d39b08c80efc43ec29f268a21a1c3afe2582e5741d7e7a1f364f0fc1e6a760caf6dbdea461b273b34a501dcb7e323f5f3467949692e2548dd60781e8c98262592f73e158d58d579d7859173bd25624e18c310ea8b2dcc5eabb1581b59131c877b663e55532cfa079fd08b4ebf4e9227152d69677d6e7152cde685feaff986167d5331fe5f8d2b509abaec8d2a8771e310c5aa188daca39170f42002ad8dcffd74477ce628c5d157e6e2323c3d2e768749a4194d41a9f6a204663b9efdde8b65d9739812513374659c5ba2ecb72b29a874c814e9ac1e71c005fbbe2b9bd73b00918118a8d6cccbaf2facb4cfab078aef373fa61a7aba5bed3e4b902f2ac9e5a41672c0b8aa024eae9a3e0c9b2365e2f5d8f4b94aa80425db5e16a414499f27eb4e8103cc1da41f2f25579246e0c32d8bc09f36f1f0591ff8a7acc32b2b16dc36ae4c8eb35ccd330eb9dba0abd1646b685f90cc6564ebfd51b0541050ea10e920051c2c2d720747a0ecc8c59bfead9ed542ffe1ff84c8755a2174e6292077e1bb452d199c75fc65218701a3d65a5acdd252a83df1c39745789cd35b05b041206b6e7e7b8ca46671aace80601dfbb50a9b88d636b6c8bc8318e3fd1015f6aa06a59982104ed7d08065a7d99c52f5e03ee16e0e58ca717a899fc1d329aab6ef3f5c442cabea9c20e61e7518c637a975bfc55f5957700b16e2ee0abaae3ea3a10198d7cb7cfde8d74588c9416896a477945712ba256d458b7a076f7f5750588afffc44f53ff99f77060c6dadf5cd921661f72050af110bed15d92a9853c5190d1cfa0cfbd5d73209f00b9257f9fdfc960b338642b7007b7b449bc9858391a4e090402f4b26b818f4f0e759aa583fccb0a54f1707cc222071e8b571ad78a68a1e37601ae655666a955bc5385084830ed2bff7d48af88ef15c08a59f163670a6d908dbdc464075134ee28a8b91a82a711b0ec8eed5ae747b023f0323ad5db9c1c8e7cd1436260754363f3910a94e240becec54980cd3ae6cf82f7e0d642f91045f722bc1f62866ccda4069718c2ab6f831b9b17e87ab967f58fb50ad011c541b2ece0971eda5bfa563c9d3be13cbb3c9c00b9e0297159049ab1f798fae5d555f1b76dedee3eb174955aa76b960815a9f9d9039c45e23f0b855d1c936adbc44cf79217332bde34937e523c797355f95e1ed5ca1e7ec55df924a92abd8ea4beed019aee23d4c31dc78870c90371d02f8c499bf94d6ebc8dca987a294c705f455637ca13f486d6bdd2cc4f6c6e41576ac70479f63eb74f10bb0ed3e82e26d92399046c5fa2b77720415b25c0d86ebb435d5faa4a53aa7103d035e050aec235e848c1d30ef28f49bc12badf7e1f1e9928614e373ad0f462991f0f2cfe39b7fb10d44d6abd53c506e7b2e728ae537ea2a126dfdb3466e373fd773deacc438d55b06f78b4abd8aab4ab2b694ef7422c177cc358ee977afef5b5d50717d4856c4839e747cf106cf1af079c33e8d946cd20a240fb94efe18f0ac7b1c9ab8be58e891976b7e7693cfb0592901bb56da2918b55da38a3615207720972a028266398ef451666fabe85d79b154c0e8157057847d93c7cd14d9fd2173b0f6b57fd7aaf2fee3eb98f059c7539557679090b842186357e19fabb891957788e34264ae867a83f5c5a1d79cadca44dee4ed6797611e9731da5a98b5b43f6a48a67431fb5b1f28e5edffe36a188cb696b0861194bb809b0f8687d790d0a5ada98ab06f6c1aeed04bc1beb0dbcceeece2e0ff3dcb54615206ec070cd109dd6eb5b4a84eccab44ab4712429eb91c5bd2b22f04ea140c252db8f65c42fcb09ceebb9e1de961a8d9ce1e536a5e040f9999ebf9bd8b38cb3562fa9b52ce8e27877303d542896526d5638f8fce8b69dc0ad08e9b1edbb404d24ba86bc37297a5dc0608557f9c520007078480adff54f8a6f36cba5441d7261f1985ad48d0d12b9172e1a1bd463d102134527099ce0c919d427dc53478fa6d6276e438cf83abc94414a5f73da8cdd206613833c836edf4a5d2dbbc7689a8c1abb9cdef52944d31a65d61f5d5a780db652e55ca89dca7d67b7e920c08e95d7d0252d008194b5392c948e4c00da29c0ab2d6a8d8e71fafb5c25e006a5c60ca27179312c7254e5eb82a9797b50169b21306cadc75a96b51c76f0685ee77b13d1d05985c1fcb8dcdb131f5292b79e076f101228173700800e8cb992e2fb3f06565ea245320b1abcf4461e40e6d01708758aad1c790f7859c47d85ad07ba8e693a056907ef24c37e7b2ed52ae5a36552043dc4cb67139b5bac5cb42d2641dbaa76d16aa1471305d677eca15b2ab5a0c54ac4686afc42e541c2ca6c82b8f2a0e4ca0b84d70822d3c86c3c8344f11cac9a1d9a846dfdd55d3789fc1b48c4382d02eb6d9c1b56d7ab915e10907383770457c13ac1ed8cb37b382043b00b921dad98b35ae0f62664b612032752a11902b4abb2b57f403a8417d58467eb35566fee7508e4efeba70f10fe8eea45aed2c3ed7d1c4124d491a4a609267bbeef11f79dfd8fa009b0053cf07750264a44771d94fd7f59477ba8cc35e98dd58e3b32564449b5477abdc1626352124323a28db2340a3813fed4291d6e1ce3d247cbed072c92b0c02214673a5332cf8df8f533a1d042e63b087c0c6666082a6688bdaf355c28592e933ca0d22b271e3973f8c3e19a73eb247041f0c4888ce1933e64b9353b8991e8e6dcc4bb680a4cda36eadb8684ed368247c079e3ad3c9eca7bf36af7f45ef899345b8fb087d7b9e0d74169b9fa5a25cb01512479c6deddaceca52e56682cc4cdbe1228de2e2fd4e2d960c39dbeadf0a170dfee63c326b4a1ecad2229c8244920331aca9b2aee0e2f8734f8b33044eaf313adc11332a2c9665d11021ed9807b8cb25fd533f36e9aaa71a725de7b51b60d00f1ef156027d7170d3a3ac9f05d7ff28c985322ec94758a93ae09c916f114bced7fbf18f8a87e1e7e0d38a45609c78c3c7f4215de6319be36f4900c2a6a333b680be8997b2e5ebef0dc61c45085ac0e7194070f17d1982ae77ea146fca09f02f4fe51ebc3dee456bac5103a7e9d92c6c3c33fa401e64fd35e4ec598c61a9a3a509383cc8bf206ff3686e16a62e603ced7512249b8d0bdbfc8c8e17610e04313ef99787bb305d7eafaf61c3f4bbd655fece58867d68a49aa0569e1d4c267cf30af3096b9c6974a1e14b88ea41d390540c7b9dbf5f796d23d4fa78493eab7f2d8f9004f7ffdea1545a49e54802468d30bce39995d712645aeddbecbb0cfebff195ab658fe05c04a31c6254858af5d8e57f4098e638f1faf3361d851bc7d19e72d8347c3fd27a16fcb329bbf9130af7120e6b8551fb82466f6a75562c50199017ca29fab28b0a38c1a3787a1b66d5edc9d7937ddc8205a210b5a339170bba3fd387e776fbe0f0dc1f05a339c0ffc8ea6f5ec60a7b8d51154103939fbb09496c79e6a62acfa592654be3067ce0fb5faf4499a7bfbe01f0aada0c03f8bb84de45f09e5a4b54bc6edc14588b705688fef1d0188c8726e69ce8c6cf22b576e96810c586601feed56c7926f4fab1cf71802fd25f8ec4ec5b27a5e163ea7a9562efcdb31cf49d310e073287941335babe8d8b1df469e47ae1dd068fa820453db30c3cfc4f6d5857235bb0951ab5e2efacadaa5381184d0a03eaf9be1bb86f8c7a15f078f0be01ac7adb3b1c455e76d1dd3767592ea6cb12986c48aaa4c20a00c8d11bfa44606f5d8475cc6dab844940f88831955d3686e3d0a659abe6482d560aa2c721525e66baa84ebe53aece8e36252b8d2458b955f55eb3706047683130aee910ff235fe48d2e44c868afaa3fc4641948d5dfbecf3ad74f7acc4457207f7e292ff1355af9fa109c498e2613f13071b229a4ebdc69caf29872b6c98cbd17b60fc797214bad78c987451e46418735bed33551e997e6bc8093941ae3d4a6d6a01c786f689e121e02827fc0303852bdf72f44330ca69ce6cc498cdb68823de53768741dea09be1bd98cceeb7f89cf473ccef1f3e672d32188cc599f37ce5255edc6148e7e2e3428d74f112916709609911f6b7f3569c50b9ae727f3365e1f14238184e9c67d2149c2ac408c6f7d7eae8b3fa763706dbaf0271402d92c639810f59698dc9117ad42e1c19701c1d32f069875838b2d83e5a8c8a064ec82dcd1ed3526e01bc511c41fc09d53856dab28f60107769eb259658d84c50e6739edef6f4df380a74c17db01dd0ac1f5465b3eefcd046a1e52bb54c98e52a22af4497c5b59d667b54d7f11969a547555d573df24946d51887f45fce145982b4f2632007f25f280dd87aec910932fba1f742218895412136ef7041f3d00e88efd80260597434a0fef735d07a3f57939821f13dec8de69fc4bb98f5ea8317ff7f89bf7af215c7875142e6c894c596a24acbb703fd5a4705d37ead919326ad55d19775b5765a7cd60314cb453a96bd8c64f51f19f9144f3f88072260d1a27d758fa670d63cca7b5d1ac750b591f0227fbc250f139e663f42b0e8318ee709f3e2e04015ed16918c57bf108f7a8fa0901c99161734db72e530c4e2f41860b0fd703913b4e1993", "a0fe32e26c2b93fd195aada3b88ae1bb5f40ec7e07bd6bfe95fa1e3cb060a3dab1ca52d87fc955956a25543af410888972e7984eaf94e80faa1b254569c95b0d52badeefd14e4cc14c42ae12adaac72c9eea48cff90ec96d85b37e0225ff9bc82cfea6499ec29d56a61bec24284e885e0021163b14649a050de5a90b5b941aa0ec0891e7d7052d045ef1ca93c47921019b3140b075eb6d99ff5c327f964b5ccb4d3fd4e9985606fa1f2850d1fa5fb1e902049c015d13b128f322fa47ba2552fdc2cabddcc3161b34ae0541945429d7607627b45bd7a808997dc1d5fff59ff3962a300da1dd37296d1cb39425e5fabae502da8d740bdea15101e63b97d896229910241dc438b0937b66a0df0730a966a00df510a54ddf1fbec550093591f891b2cb17934f0380094e096d0448c91bc7d28a5719ec9a8a2f6df5b593a15597a7fc6989eacbb343c928d7fc5e9051299b02b42db3cf3723e92250bb84fda24f61bd5a86e2696f5aa07dd1108fd5862ea54ea307f5a54e7a192f9ed2b214ef65924eed31e07dc3b7ba9a4195b53d446104060f29b26acbd1e36ffae1c0f96d2310ecc1d9ca125f3dc682678a47993bedb9cd91133740d17eca07bc0eb3d8ba18a3eb52f3d6779298045766f33f813212e766f76e48a4b0416b5ee646969659b490da413df61fc3d961b87793676a877123ae7038b3d10fda9fdb2a990097262004b63ae4d992270d53ceb9572f87655f0dc91b78bb4a8ba6047a16ec25fab31c06ac7a2dca432d4b7ae82b1acfa3ee0910af0f7717ea57f98d3330bbbfd0ce475815e85340be8f3d1d713b0d7c437cd5a04c5e511c6d55314d61274e8354c37b8c54b3cc613e9bc97ce393fb2f55873105ba127fca0716bdd399905948fe42b76e7ce9a3f6e91abeb51c346952241edd6edb9c6873f8ed5ac470ec6f69e75d42b88a643b9e10c7515b93cd66cf65a636f5f6157001c4082d53c5876ace30248dd982f035e6c4122a7a5d9d299c7774e55449af162b7a7a33394742817ffd6c4b5aad1e62c7319c1e6724d6fd0c8c2cecbacd2a7eefe17c1cb0b87945f3a19a3cda8cad0935fe7cf6211bd71b54463ce9e5a9616a5ec60bc5c85060ec0a6e63d0c5750d2bd36f6042db66accf596724bbff5d200e3286ca26b744aaad6288cde5540c8d2e99e6b682d19baf0bd70582c572d0271f259b6260ceb5bb831207992c5b20c8bd37067e48062c309236bc08cae43ccb0fe28dd0e1d05a910c5bdf7e255e056b06cf36d9e384e76c8cc42827083a300be06d63e2f17dc39415597fa647c502fe45cdecea40cdf6a5a133ebc8beb2303bd6a628f6c796d71ba2a5aaa4f0105\nresult = valid\nsalt = 90983ed74912c6173d0f7cf8164b525361b89bda04d085341a057bde9083b5af\nsize = 8160\n\n# tcId = 94\n# invalid output size\nikm = 2b1017f28a19841832f576bfb3108db78a1e6f2009d49d25aade75d403ded34f\ninfo = e4978d1c18687176\nokm = \nresult = invalid\nsalt = 41535a35ec11384df15a0a24a65f067591b446ac4514f7d981724db4900a6106\nsize = 8161\nflags = SizeTooLarge\n\n# tcId = 95\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 2d0d642aea95ee9892fb87ac392b06aeaead1735c3468fff85c4d65fa62d4a06\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 96\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 2d0d642aea95ee9892fb87ac392b06aeaead1735c3468fff85c4d65fa62d4a06\nresult = valid\nsalt = 0000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 97\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 99dfa94cc0a5e1c313ffc5b3e664149bfe9c85afa7f4d8cff61b7b4fe4b9515a\nresult = valid\nsalt = 0102c651e047fed9c217bcf915520532d44999534c1e7e7c87311093d7a3681aff3e2d335b3c6139b9fc66dcfe35573b36a329a550c4cd20bfe2a90dfea50167ff\nsize = 32\n\n# tcId = 98\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 99dfa94cc0a5e1c313ffc5b3e664149bfe9c85afa7f4d8cff61b7b4fe4b9515a\nresult = valid\nsalt = 4031634ed8a9a6152058b921eee93908e7277f79263e73976967278317c2b885\nsize = 32\n\n# tcId = 99\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed66\nsize = 32\n\n# tcId = 100\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000\nsize = 32\n\n# tcId = 101\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000\nsize = 32\n\n# tcId = 102\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 103\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 104\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 105\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 64f72009dd00e4ca7a63f4b9f92dddf6dd074b5cb3e0fa753d47748dc42f0824\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n", }; -static const size_t kLen126 = 104065; +static const size_t kLen180 = 104065; -static const char *kData126[] = { +static const char *kData180[] = { "# Imported from Wycheproof's hkdf_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HKDF-SHA-384\n# Generator version: 0.8rc17\n\n[keySize = 128]\n\n# tcId = 1\nikm = 60ab7f45b0ad534683b3a6c020d4f775\ninfo = \nokm = 3f8b0e4a7b2bff01a26a18f1e07c0218897a324e\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 2\nikm = e3db76e02278cbd2adbcb4555803da11\ninfo = \nokm = 54d872ee6079718738b96cad7573bdd667aef80a43344ccdd2488eb2e1d3c33b9e291faf89609af32365\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 3\nikm = d4dcb92a769f57c8bab8a420ee0aa351\ninfo = \nokm = 8998abf032b4fbb29e431f0bf1544e19590ef4fc99e013db8d6ce0dc085660dd3f2432b5f9cdcc44cb6ce0053e7eb43c0375ac7efba148ece8688e637a5759f6\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 4\nikm = 2d43e54bf0c94c9cbff4300f4aa69ab8\ninfo = d674da3bb47d5c7e38b501e5251d9348af601c44\nokm = 658e6132e5279439568a617274fc788dccc2bacf\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 5\nikm = 4055536896c406d5fe14a6cd6b999bff\ninfo = 2094768a8816f7df070d6e08b7ad93755dc9024b\nokm = 14a650a903d54e0de9962f5462deb135071cd1e3051ecacd65d378b6181b41e1e1ab3b5d2143b710c728\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 6\nikm = 5b01b2da3166f217cdd68de8af60078f\ninfo = 6884cfa7ffe8f27bf4ebc6e46a7e01488c79243a\nokm = 7bf6c7c72fa9bf184f9a2e13077a0e1afb9d976a5574fb7ec819d8bafb9b10f962e6fa8bc6a844ee0b609eee34aaaa025065a7e3a7fe4678a005640f7dc286c2\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 7\nikm = 467403c2ec02a235bf730ff37e8d8ff3\ninfo = \nokm = 55169d60bedd7ab2399d830b1da06f69f94e4b0c\nresult = valid\nsalt = 41f0f173d307d40436c25856cf559f96\nsize = 20\n\n# tcId = 8\nikm = 3352f942aa93071da6d39cc5ed8dc460\ninfo = \nokm = 260a775477eb6b32fbeb4e6825464a47ac8484a92296a3a3d51b0821b346deadf57f9c82e589ee369fe6\nresult = valid\nsalt = 57a0db708b25a51afc4271803aa35204\nsize = 42\n\n# tcId = 9\nikm = 08867e76311126089356623ba5381e73\ninfo = \nokm = 59debea3637c46394e2fb2790ebf8760de4986f36a6b142305bb62d1466dd56fa201c96814a2e5846acdf141733ccc54df9e6ccbaebf84c4f40e21201e180b12\nresult = valid\nsalt = 0c164c443edcdfaedb1ab150f047951f\nsize = 64\n\n# tcId = 10\nikm = c55c41d69d2424a520414e3662aa7303\ninfo = 3fdf20538063b76901d61bbf9b72b0c18749e00e\nokm = 25ffbc81bc7b1c2dc1cf98020f55d256a31ce89f\nresult = valid\nsalt = fea9bfc92b74337e43a201a2dc199e27\nsize = 20\n\n# tcId = 11\nikm = 5d3db20e8238a90b62a600fa57fdb318\ninfo = 2bc5f39032b6fc87da69ba8711ce735b169646fd\nokm = 6724e716f6a953aab112b61e29d921fec0f8e806841d5ccd3aa567574b502904d04ae707d244187fec52\nresult = valid\nsalt = 1d6f3b38a1e607b5e6bcd4af1800a9d3\nsize = 42\n\n# tcId = 12\nikm = 8677dc79233ef3480777c4c601ef4f0b\ninfo = a38f634d947819a9bfa792174b42baa20c9fce15\nokm = 758546362a070c0f13cbfbf1756e8f29b7819fb903c7ed4f97a56be3c8f81e8c37aef5c0f8e5d2b17eb1aa02ec04c33f546cb2f3d193e930a9f89ec9ce3a82b5\nresult = valid\nsalt = ad88db718244e2cb60e35f874d7ad81f\nsize = 64\n\n# tcId = 13\nikm = 0f602703d37943e0253bed3da331aff4\ninfo = \nokm = 25b54be713ec3eabde9f8d25745672d1e6386c07\nresult = valid\nsalt = ebdc8510499f69b2e188daab77cd819cccb95f276f46e6b2be11cbe72700\nsize = 20\n\n# tcId = 14\nikm = 9fe65737574c5c7aa67646adf8230ba8\ninfo = \nokm = 24e3486d28a6574270b32541651cccbb93f0418905e628ec1274263681b943114f742b9b81db0f86385d\nresult = valid\nsalt = 73a34648c152443586236abcb46a090ce55ef6c7f282ffce6342d694650a\nsize = 42\n\n# tcId = 15\nikm = e8f2b1c3e6a6c3d5ee0a20dd47aafa78\ninfo = \nokm = 167928954f92eed2e1c82496e57cf091d9c96aa6d4c01ea0b4275f9f17ceed820d90287cea90ac8297f892c219885243a67429829bfc86ca8eabda4295236252\nresult = valid\nsalt = 3f5e162de91e0782cd189f3b7778cdc2ce6bfe9d3fe841cd3c70475d7b3c\nsize = 64\n\n# tcId = 16\nikm = a679521cdb56aafc5a4b76db0431a4dd\ninfo = 44ec41ab4f4e64f4a36e5e30c9f0dc1d77ae4974\nokm = 72f15cece4bc7704a841eb5047f04756f86ec549\nresult = valid\nsalt = 123033b1ddaead83a4b9cfef8a660bd8e00fde01e67c35656c6d7607d456\nsize = 20\n\n# tcId = 17\nikm = 49bf155ca102026f2a217ea1bc9843ac\ninfo = 851bda4faa8f7add2a3cbf0acf9c2786f8f955b2\nokm = f693a3253389435899adac72d3ff59c240c65bf282f373cea7a9ee00864d5b4f39b2000f7eb49af16fda\nresult = valid\nsalt = 76776e3b4d75f8f43dce4bded71f3b1ae6bcb012d9c0d59f78248b9427b8\nsize = 42\n\n# tcId = 18\nikm = 6cf725e939e8824d4392233eeac75d30\ninfo = 495425d9727fee2e2b7e78899868c1c3e7735e1d\nokm = e13a7490f842b6e5be206e6d5ce69b2a8e2cba5525715283f22b021d2fbc2aec59d0144088581058f0fb2f551c6d62bfbd8a15d2706e23e10f3bf7277fff337f\nresult = valid\nsalt = 1e72f24b05a91a0093f34306ffced79e7003055b0833c6d0f27a4f33a1bd\nsize = 64\n\n# tcId = 19\nikm = a319ff7b5ba9b14ac72b681cecf0f742\ninfo = \nokm = 83b3d9f22cb5765c16dcca24e6ce6875b180ec9253bb3950666c52e3711f3b9200d2a995aa548bc6bba2\nresult = valid\nsalt = d7e3bc6daed343ce77ef793e15a8246e4bfcbaf83d2ac956d0661d1df7262b2e7311623dfe4152caddbfda8fa8ed7a82656ec00b72c5adf7c9d388e5b3bc8d24\nsize = 42\n\n# tcId = 20\nikm = 34bae5a158c1678aa76a744417a70d7a\ninfo = 87ec30aa53acfc3d09ccc1d57d654fdbce403cd4\nokm = 9413c6e1b27f829fb82252b5ac5e14a54503e5f433fc8182a6b556bd7b8e04ac34b0d6006950d5917132\nresult = valid\nsalt = 1532075f363e061133780ac959bf653c7687d181b9431215d6f62dd2f1ec3019d61c50fa82c70ae25e624c849a276b0c57d7c02a4d753fe84a1a6621e9a5ef01\nsize = 42\n\n# tcId = 21\n# maximal output size\nikm = b8a3fec3c020e028a2a9512ad3acb688\ninfo = 006a7b5529648b31\nokm = d21bf9e7a8685d4c052b391b472767d436a0335ce2315a9e44d5b183da2f06fb0ac31733fe0cb0c1b47f1652d16b4ca84a5c05e4fc9432a840426d146cdf17924c62d3e1901cd3f5cbb0aaa55d46e0d3d23fd86f82a2bcf3181a548cef4d848960ec65518ae2230474d6177a29381e6537eedc2b2728db2573ee182afc5d72cd65ba04ed613f245f3ac401de5e4b30018040b8b1f253eb57a2128c2c0e99ab68dab4583f5a1ee7d0a1d16e9f00afb5f63a1e98268f8c66db5d49ddff7528dfe71f792a93623e355d0860d65344eee9eba04e739627874829c2cc469f27d467822a72a5dafbea14fea2aca2c521aa17985c07a8457b18a1965ce824bc886525c439bf48c36e957e567edd26ee015c01e01cf3ae463f8efdf12dd0d102d95310da2849b8b0bb0849e8b1b41c515708299c7fb645c8f5c86e165e14ccdd9f3ac4766e8ca74eec97f7632a75543d4a93818fcd2b3201feddc19eafe19ed596b76aa3a8492edc52e990549f91967aad94536e8234afb862a60c92267e029bf90e07315db87e56ce4fe7a857edd4869c44b4f410f62b7ddcd31bdad3c1d6016edff774ea7e17c1cb3b39ba918ef0d961725ebe407b6c89b06a9f012d8fa55abb1b84e277991d8b2089a7e228d326eb0c24632e4e35289a14cf7fa1f036de44ee56c0444bbe7d84873597fd82dd6b717488ba3086d57c76783e88cb0992944c66f8b87132eb9908c5dfcf30600feca06ac52d28af218bc5df00fdf4b8fe3fc3947e3ee24a68d8f7c96517337df46283adbad468daaefd334ee2b101692651cf5c8c1c60c2b204a111707afa2ff0520727ac222807629e65f8425c925eddd4a301ad247499f6640f9ae9818644cc94ce4b088e37ce728c48e42f82201b9b27c7b0e918c09b3dcf6484d6794ba27f10374f618c4ec49791a3918977a13099e53bb8fe4fdee599016e7fc91f849692ba97e722c90fa6b4fe54e2bdf4699857fafef364fda90767692818a40cd83cfa42e5c12b56f7d83c4a8653434ec7e5e9a13cb46019bdd215c106425ad51418a6258014a62a449287edbd879063d8db019de0980d0ee30c9463c50860c7a2c390974c09c74e634b0543212e99f6db9bc104e14fb7eb52c4d98c5df24808c59baeaa01bcec03dd110d0ca6529e437e2994dadd8a48af91734b638acfe6c8d216b5d1ee48143a0b24c51f4e24ab2687be88233d10bb974906d46ac8e08dee1191fe7455075c167a743290c261362051c28fc441737d92de5ebc763cb52bd905cd3cf115dfd3ee89f0051e31159965e285887fee7fbc529ece2d350985d13bd16abe379ac5f9a89a99b768d4f0353e2d52bc8636c1dcb05bed53e958937de69636e34d5f46ca5371bb0f38e2fd718a6bec6784076efefeb08c3184bc92e18a9fb7042910d1305b560b9c59223db160e2959f061cb0c9a0acb11f479d4e77c6d98d5ca73149bd19875daaf06341b86227a93e09765877c0d7d0e74337f9cce38d59f0c4c9fa202d1c48e9c398064d5f9fe802f634b094f47dc44cd041086b728ef57103162df6d62208c3b60f750a4bcc2ab461424fc88107cfd545518aab77b42fccbebc7bf3da92e4a8c2a1eeca8d7052ce8c94ba6393f66be9b758cacf37b7c87ae41e48f9d2016fcac2305d6e15256d4bf7d19d6129582eaf7237af07463aceb51edd7c56bbaae7a54af6678256bbd5ad3bbb328d0506e451855281c5b380f63c1bce87b370132570ca98e4e330c1ad12831771ecfeb6773eaa44880bc5dc633452160ac8388b9eddbd02fbad325e0dbd66cf20298cba81f3263a402c5e6d5d57d4ee5fe391de78d2103067fd889d870a36e7df6441e466262b759d3e2c051f7c850e8484b6fb837239e8d11570d095a76241817fbd518ac44bf1bdeea004f8496a252726de49f36b0dc69c0a5d01daf2723140922ddec55519d49391f9a34b7c1a5e00d094c0ba8af27bd3b2ae1de2d6ae15b23e49bf65483104ac62172c8f2e9ca109c59649d0318e5c38cdd659779c598c23620151783d521f7ca021cb910f195", "e36d55bd963c25167cdb3bffe3642bde8e184eff7905affe418f80379393cd7ca78586764a80be777dc9d9cbe0840a4219c83459745f9cae786d26c1edc74f5fad27113fb84e8854c76e1fb02b1998253d365cb7aa682104765ea1f020b0aef0d3cd2378c037e5d64ab2dafd8a23beb5ac5fae3341be1c6a9c6053a3d857a2d74d56a7bafe341bd5bf7779bd7bbd1991a949850fc25ef0f2e012772ea0d2cb7e9292fe2658c6424ce786d7b7aaafe415adaf9ed7ac5e5ac8e24218bf9e629dc93d22d398a7872b9a0477ae98df9fb22e042d475f96d349029dbe108632d4d3b56dd89f352dfc703e2f25fba97da49a079133f1e0c0c729bf80b02edad76bb036a9ce1c841e5202d59cf63149cb3b81a68df64589fba8b1dc7f4fdab3cc8c4b5ac9712d7c9c41a6d5e0efebc2a9ad6310d30087395dd74b61aef03cb4facfd59d5d50d8c04c5e79518823f9824a94e0ec06b7157e48916d551bb5a6831ec44cae0cc8dabba3ae1b6c03391f3b5ce45861902a8e777fea9a5729cd16eefff724636284dea34605f53d98010fd888f469475a6a98b20c8ad8fc07466276e461b9821ea55cf3c42e208fc56c610f70368ff331e3dfdffbecc26e489f70b0a3e995fbdeec6b8fc87e19d3ac6f9036dddab7e8ffc38f58446f75fcb2cc4f7e90a721533de151a61c67346dcc63e15fe1a4ef1a98d1cbb25cd7b24703045fdfcffbb1249ebd3c1e52399d6c24838d7bd5b668807a4310b447c167cd3d3c13697f35225bb284339149bdd4618656b2a09712a812b2586c3492bc07a4c2f8fbe39861cf8d36dad815edc9cdc97dc2fe4b24b0fb3c2513e3504bcdb1dacf2692c98a6f90ff77fc5348d4acc44ee4524506bc176257b434e8584a483c4c734cefbb7457b4761e1dd2dafa10eba4a031e1f0f644e210e5bcfb7a72e2e14577c972a78b1a275f338145e2b7d80851013b784811a91c19c71bbb9df88ccc2c1380699f0d88d203800574a0830632e4401880c547c6bab52d2235638a7222662e166307779d2528c3dc5436508e25544d1025ac3dfb627781e8fc7bfa67738b63a86bdd9f1f089f30a71cb7a79dda35340ac1a2dec129cab38dbde6cd5dcf9d2da3a88f9c2cf65b4a1aba02ca213ba596af1a2f323a47ab6a07f0e3057c6d635b2f5ed1bc2f4f6ece8eac348202cf1c6d9f9c8738044ca5166e371dac0f305fbf1b5ef2536cedda250a4f209ab01c714882244b3c1ab3c0a0e5c07d6b928dbc52c9b23362266ab8a25e2ade5e06c3d645dd557630fabe57733c7543f7453e002da4eb1844899740d95ebe604dbb03e883d9f668b4974282ed491ba183c5d8cb2867788f24eed7d67f4b6c235262cf71d52763fb7688d3d84d92424b0b23468908e95ae82de41a2615cb009aa7e5f18c889125f1167d60aa24c3fd9e2e087c6b99d29733abd06c81e5a728faa0a945a2ac8029d58d7782f03aea0e185dbcca12e0564fd163427ebc2bf46bc71fa3564bc9556546ca2cf1e8ac1720d8955caadd08a6530c98d7df7ac14b07f7959d0edc4ac31e6d58d793be3c6ceb370868cb1ee8b57b74860576398fa5c7bc8d23e673745e7ecb1754dc2c873d6ea61057adb9b91dc4ca1ae1fa69a93e8caebd8a647915a75db4935e040e609e3cbd1e382a433b7a990488094dc53a91104c9c28fac9c74568e5a9e4d37df0a44f750fba7dd45b17c142057f16361ac750fbccd56fe43ccc548c9c97ed9a190e14be1bc2a039a671175ae625bd4a0a7a9f6ff27d75a022a5a0e5bea17eb6976631117ad44beeff05360580b8aa87d8a6c65b7f4b51d53c20d9ccf9008eee95cddc90032325598f0c671810edc80c9de9a74cb32de95b940507773347a17fea02f85cd2461e2e76e0f58315a7393489b9d26440283d89ac0d4f8e853e35790aaabf8dc26981bccb4b85c36393db621c26c99d1ccb072c8f250924fd0411136c5e2f9e79ccf450e785de248b75427dc6f858975b0d3f11feb0f8745ef8e2873424d34f09d04bf01edc974865fb2223b9cf72aa4aa35a5b2c9c91f55f2e545ac403e66435c25fdcd6aff3466bc9b947bd1c811c65de058a92dd3d3668f2ea7c8fdfbc54188d8328e445676a3d115252022b2e828ffedad08c2b96b10b5ca3057083fcc313e3a6d1fffac12987b8d518cdb8b0447f6f23d5266d95e03d36a806dedcc5466ca408580d5c3872d7f6c96bc63fe3c0ffacdbac126ecfaa9426483bee96596d0ff88f8fac8b9c67de4d023b3f0b146d8ee27cad9ae019d8982c85e361cfb7495dfbcff0486448251e34a31f22c0beece7f01f8b81448d267397bfe55b4b384d6604606015a744ae36c92d593a1cf33d3b5562d98093313f3a2ebc7b8b7baaaa0535476b7399ef34521f06d459861985e81e2f1bee5b3544c09e5528bfd472e01383975dabd907be7e9628ba660a776a9ed3a815ffb1df09753e8dc45a0225ba98e197508e0a22560cc0d76fc1692749a16c91dbed55e385593331f3bef1666de4c2b8f29f5df2673ac331a337da8fc020d76f4e4b0933ed6df06b5199715416d6ce46b760205b7583973bdf3967fa546c9e367d6e60f4c9f8dd79fc73a0967a58deb4b779f9b5695a91db67fc2c0e55e7d74eff97bcc322a00c5a5c0fb9564d2c128f5ee3b3378416894ff25b8445e52d21bd35f1759171cb4e6e426c71bab9a6cda6049d8eea904a0c95ebacc98dbf5a5e98d835b6e216e6fc062e600ba74c321620f63e76995637fb506daaf7b7e0514563b536edbc11a35515a75c58cb7f56f3f5ca0e7dfa3ec715089bf6e5f26ad74c10e72ba5f603f3ee51c7bc9645f4194877d4f4645c8226b1d974fab69e62aa3527ad2fbd101eb6b752a739a191d431a87d5c739b7d7f7804430f41820cde5e5a717ed84d80ad154f816657561d58f379e4a2e7761cdb505b5da6f1008143cac623d11859b186c291a0b39267da29f64d5f5c3e0e5cf0f3dca3b78372593aecff71541dbe2d3f89d0febe753f9571684bf8c1b82826715d40cc0da84fc2cbeb3f46c1e53f522fe5f682479503bfa423a2fe10396a9330be5c484e21d60a26aa3f70b210d3ca96226972b7b03fcddfde1499fa81be22e82d851e609834ff9be6407e0bae00909f952798a559809bbe47ea0e4e626de0445b79758726a09e38e757c5645379223141ac21de8ee298542670f329d77ab498f73adfd2d269dcee504d8dd046f7b496fea449e2b265874af3419d43b58df44d9be3e414775c715d65a1d4107bafad16bc315610a36b5775b7fdba09511ce68d1fac79592e740535a27b47a24f07b98bc2548df11610860c5918173f04cf28890e9c038846ea4baaac30b22c552d5545c7dab8f4a034367352336e58409ed2907df1a2fdcb0c56994477c2c9075ce3b1876abda5da66b3768eb7eba609f83376aa5175e3d23a49e8a4327ca3687e401b9fc2f00fb41a13059dd57f9053d438fb66050c4022f9a2d740ca1be13830047d47e9d15184669640ae993fdcd2242977f479b80169ccc802baede5fb86fba380d3d6313bf2034f71f9bd7616c02225ae23b2a83158e31de5726b79564f16abde403a915c0e8d9110319dd91e8c32ba5546ae522ba3204b70d59731d9971157807b024306cbb720563671b282b6e89f82cf91d5686978de9af12e523beb1f2947a384dfe1a6b18989a0cf1c42803c8238eab525ed3a25dad792908db3478d14cb26abbf324d589eaf96204c837b32a4c4e6f9240103ffaa14c1edd6b7ee221ca2dc52dc553cd4eea179ca9a7c4481f17a3f4a9633d29987056afe59b8f51b8665837c62c72c0a3b5a4c5c597327414485c39f298b190da1d9effc1e103b0194f5dc634c6e12c7a22866ae23e64a86bca3629544be79f5b4e89592a69c46d92566c7939385870e3337174dde45ddbda3691ccd6573edb897a15d2d17f2599c523355137de6b987cc35df65d0bba0e06e64bd3059ff94e723ab11bb4f015d72b42e1762226f163b881bf82dcbfa1604fe33107c978181d850bbaec70b44d64fb27baaf7cddd33b1ebb0872115a4fbfaeb6ca5299a02aa07ebbb28574c430d02cedf0396b8e181ff3631a1fe938b0ef175ac9e7dd399b663ec6c6c9520e4a63c80584d8b845087f5419d8c815b1ad78e402a4db542b900c71a16ada2cff190d6fb38815c59238e96e6cde1dda63a89ba907db338e0db29d6151722e9120126d70c6d348b8d3b99084fd8b2bc068258d43a34dba7f639807eaf2176ca7eda0c0e2b4e168c1df200734b592416304e7fefe17f051640464164d643e7b66dce05264a24354651cb803c012af3aa6b61c7c2c5690979b1e1b5e05fc64cb6dbd4c95df382f7d5550e12d7bb9242ddc025f2af03a44f7974dcf5da038f23ad826e9177b23f6163b827a98f0cb065395235e7d3141f94e83e46e8fe71c9e2c43c77837c8616150250485db8a41f7dae069fba1e453cca231ac71454bcace3477af40485ff2f24474115a6029163ab3b7186af02de5c3361c3f26741b1d86334823120178f6d453057cd7b7df09c908ab114c0fda4767bcbc43d1262cb94f07c396ff51858ea2a55ee02873cf9fe2c456f8afb5a64671c05c020177891ba65fd8a3857359de1fb4fdd80d2f7bca6e369f8dca930bd1c977a141728afb66abbad60bbd3b5a08f32901354067f5442de768972a8ac3330f3b4324c16c1a5f4b321c68467404cfe642418620df5078d8525919eff62163c388ad4c2666bcd06330ce5737d438b59fe84f4089fcf35dcdb17ad93d3d40e32493a57ef97a6c0d45604623ecc80714b561e515c0169ccf488ece2672af491446a5d9ec8cd443d6bf95258d2bbbe220be1b56f1179231aca39ae84f5ed34ead9511a2e9af44bac69f4bf42b241696d4cdd5f260d28c22d26ebb580265c5046c81bc386c0bf698ca1d412e7cadcc247dc1c774877f5b9ff8193128934fbcdee8e0932e6658dcd30d07391f82f4d89a17e2b622a8b87997e1848490e26efbc6e79b9e1c40a414d9f84e22a0dec7e21321245c76e64921e3030a1076c9a87596d5aa97caa5c9c68b3280427668348985c7b7759db6fba4c1ce21ebc6b6889fd7d925215d56758131c515b544c56e75f95b90d15dda7f309b7740aa7989cf1a9e3ce217e0ca6e27f502731bb7821a3fdfa73f915ee49e0757a897972d58475e4b12ac735cd9e6b28b81a76d2ab0ff179fc1755a7d96cef5e8a68ac9256d8d8f17d9182daf1540d7af15aab8b1517f7b8656fd3e6708b99dca9a1fd598efeaaa60ebeab6adb5a76a0ab6cbb7dedbe3f0862ffb028ba4e942372344cfe84da9fdec4ec75fb290240828c4c31a1fac0d178f0dd2245f29d346c3a841f863130920bc97dc05c510020852f3c01bd783a8c6db64228b973b20d72c45bc5482517cff230f1a9bf1d8d0979f62049bbd5e8a3e1bc54f6a1c148289b2a66685ddfd0406bbab589abfd183c4299ed66283beb96556ff200497804dbabf9b6702a87692b4b5bb58e01d16ce069b6c3512332b394db1c91db0882a571ee41e458bc960e7535668e334152c9d46e9c155ad09617c348c3874e5db311601f25d5e1682cf69689c15c13dc5c8d836ff6e30b0b804e4810e280252f4bee9470964159f2b271c275c9615b341d20f292107a481955b0b986365c3d7f05de29a8955cccc5d42113c21fe60e2a4a51be45784fc304e8da0091398205a9afdad9b62361d6f8c42b16a7990d5fb50ebb90cd1e1052f62a966a9e8be73593b50be8398c5b3e8f7ced3af398d537bce72a", "b1d7b10b4f0aa77383560a79f4faf2f29992c1e2afda295d15a65e30e6f968d00d60e5f1dab5a847060e55ad9b64f0203b21bdb506319ad379302c24673a727acc17b59ba12f20c3ba472c0a5628d0b05213116e2dfbaf9e98628fac973046f60f930b7eaf0790ff010914c19e93f07b74ac3f7a6b6c3cf92adb49443194f9167f7dd553768841b34d461f7b854a40926b016d8a0123a1fae741e07662e125d42fdcfd765c52d518049ff16393422e6080b9fc69117e5f17f3764917eba5fff3f078727048f3e5bff1d9eefe8ebe2fb6db7c54cdc9b7678fd0d6551aee06b584dc4047beaa72c198bd96ae9eb9b151f29747af88b75399b21570ba6cf983637e6dd2b1d42d39d07108464ee22d81d640aa4cdbdbee7919de51d8f82710e32dc722a04a8ea96aa32a7a19c7048c1d76d2ae63ea288b1120d139bfd2e51f634c82f6f10a5bf18b02725bfed7a2913896b5f108fcebd949d04647467e9837256d9918c2185905e078a14d2945ae64d57eb7ebf9746f80ef939c3b1a307c6af627b91db34d59234d3b62279fec874720624278a51fa6d22886456135bc98b683eccbabcaacab2f013fcc884c554ddfc6f91950215c4f1f750cac338ef3e420a82c1ba15ef420798053483ced448b730e386f0788e1a3a747f8365385bd0e02cd42f1cb48a61ffeb2b2e6e3ad75363a118a27dcb86cf27400be97bc7d10bccdc03f6e19227ffd0e3881bd7c3126d682596abc15bcebe77854ce2844219b17f604aa2b4cc19971e8dc163ac654126bc39966d35737ae75a4852ea1c29183a3700e7cf609ca864285a8b92de0f32ae7c33b5ca11aaea05e10f87d892c5571e89dfe54091639bd87636245f06cfaf87fa3a7d6d657ab3aa89f5fa6b54eedec92186b2026954045a07822997051bf232e39dc1a36a50cbade8fe4dc6ceaaa29008c13fcd7ef96cafc7554b60d479132b2810ffa583aafd6c7e188293c4c35008d895fba6634eb20c92bc1fc2a93f7034694e6bae8d291c59caad61a723719298ae5d99fbb0485837a284f070fd293f74307fafbcd5b9b3a49c96d9b7dace812d6fc7a94aa381346e879601fc292e850d5a732bcec383ec59a1034a573793ee07b9c30e29c3f3cf0efb40693b8ee6df08cad92be3bc4666093daae5484fc02df28f3601861a2aa9ea96e68bbda698fbb032485a55c4baa03893813804f09a4d3e639f2d84c553f2e917b3d47f658820702a6cda2e06070d29c71640c677fd76c429f98ef0b65aed0d5c82d334a3e22b5e2d49a31518d61833ed8fcef352146e7a1ca1c9eac1d786487e357a108ba102415f9d87ef8b00d1fdadccaf3328d9376600ab0e4ee2400aced47774ef5374e62ceb9f19670e144e4590e80d33e0f5863be0e5c515656c7f0880bf57ad0b986affe07a1f66cc9b1763ae7646a8f28f6c804b6c8c260f5fa02af05cffc3a631377f0e4abe659e55655f691fd9572ad832f6485c06bc025d5300dca8aebf5ac0094e582c5ba28389d76fe6387f933db6d04b5da56b739824bd507a072f32b5e10be0516718d1c9031dc83aef222abe60c6ced982b4256a36beaa9d15e11fd3f3f600e28c2625ba2b7a9290fbe89a41465b075aa5f00b1bbcbbfdced6dbfc41e30d511b02c9711510087652b4c6637c44ebaabdd0d5527e5017dc4a339479c9be804bb5b606ea3e701e88bf02cb6c2b3e8c6f7e4bf730c8cc36748d38b96300ad92136c9ab8632c54da6d7307afc226eef8b3b9c849235347fdd953a194a90cc730edd043d44f4387858fb88daaf9a0b4f73abc949895ad4af054a8d31b69a2a98090940c24cf008fe675befaa7641a79c440e666905a055e4ede90f923d8bf16e2c451bbe8970e4c3c54ba5b1c3ddf66e8ee0cb3ea1d417cf82a72d244ccad0288c9231809302494235e905876cf8ae1f874b61d78c26b9e1645f68a0478767d049dee312f6ca578ef5630cf4bcb55967c960077503927f3562dab3e37bee4c96d18b66f969f04d592457d055302ac96fd47abd3582a5117fd62b09a1a8c74c379961fe68c9e1792a2097d29c1d837161edeee01a4b76158b0939af676edd2bcfd18bced7ebd0ea8464be04edfd2590004004b0b24af9c1c028fc2b7e756408854ad3d4f89f8d1d27f90db5844c1622b007c47882f316ddca82c7429c870b2455aebd0519bacda287f843419cd74bb07a40cc08d1fc812039254411266245f3b16dca3d88d305d7ffeaae1b45b1bf622945e3ce4e90ec153b9ef84741db9782f1b4518233ac86e10d5f212ae7dd3cbbb952336401a1831621aa7aaaf1f053efdf3938e73ec95d084cca4c2a266e7a1db5e58851fc291db9d0e7bc4447319feceb83767a5c226010db7c1068e8831d90c0051689a7d7a9dbf687d1f1ae43f62a33d3076784cb5d800c2e3e9007d9a50c1d218efc59bb6d5e61c12112b90f72deb9348e874f3292135d7ea9dd6061a6023cf8d9d8c3abc3a8f29a50f2a2be9ee11de0a910bd3763f0b90946ed1fa5a6494fc65f155bc0a1349f0c3626359746e020f8d3bd83ad591f6ad00921a13909d6df288f4174bdd2bd231d2c5352fa232687c5262432732b2837fc37874ba8ec887f17e41a0eff1b56a03d6d4cce12cd60b426a0ce2ca0a3af667874b2c43dab58e65f83c0afe85e36a754cf460fd66689746ecf640d5af440403d2339898647dd36e733b550f41882b6aebf31d886091d1f3a7044ac84014ffc793f34f6633e419599c792042282f37cade01ea1b307cff1f7ddfc340703166c24a63587324859d7190d540352bd31ecd34a2213978980a490c456dc55adda4f3c920aeaf16611ef0516180d05ccfb6c05a8df20792591a12df86a3450c0bcf0ee7ca2a861c9eab2de259e77391f4cbc3125e67d41553644b2a1a8268647237255bb08e884852fb050365574a5fd78999e23a6b0457b7007c0f31d1919680ba10e803bb52e8af42c4dd85638c87d5ea436be1c8102876cf7c38aef78864ad5ab556b7648806caf6fda6dc247f26754862b29fd0d8c89b5c70476132737eb9d6bbf044fb0eec96a961d4f9975d866a84df0a08cde0e9525b179b4b4f18ea67d035fcaa946e807bb22ae18c159241534ed15da394ed5f73b1d74c51db40283048dd8c0f8c5c807cc7c13129f10d957b698470c05caaf280b37f605ff4d855726869251fd4952cb35d6a873309a7166548cc3aac9008589a6d258d8b4b31835dc26504455bcaa25fc580f27b213d8af43897d59e89cca09472f57720146f4d0748040c2f21764b9b3faa75e5ff78d3eebba844feefe0ad9bc0493599bdf1de61b3d71446e6acaf3327dcf61635e51694d3713732804b43989a43d293f133ac21ead51d1f2b92b76b3c61f8de0aa8dd660effc9cb1bbab80f9d1915025cbf3f70198f979a5a1e15db18ec2b78da238cdab78dad028fd5aac7ac043acda7828234d93bf512e09deea886b6c9459962705f8cac432ca315c3b9449c68deb4b0e71b4d393b891bbf92c6ba9dcec3fece0dd91512f49af9806c6c05f950bf2af2842a85fe153153dd658719a2e1b1a2e989448fb0c9b456d81f4ca770140fe9e37e1ccbe61893c1886ba8805f08c9417c8a3998b5adaf96a37d71b953aeae5717258b9f11fbc891d2bec8ead8d355656a0d0fb783cdc1353af35d8cfce2ecc36124809a77cb6fdba75d0f1ab2c9f82de83e1d166a70edfb86129d9b4e362db8d4dfd6b37c6c85e0399bddc8d30ef6b24e1f0a49871511aa210027fb6dd37b979d3a79cd386d0aa3629a25df9e77c33f4eb822ea3daf6c29be1c2d88d3ae3be2321c8fea439c0da77cee72cce86673477cced34d4fd93aee2d2dde285eeac032a81d4df620603a141fdd1d62ee11d2a82e70c4134ce2a80071cd39cfca105bc669319fc85aae441754ef7a3ea83ccd1ccf3fc6c22b998107d1c747ad5dae0d304649f2bd9e21e3064be40ec7b570fe564fb71d95f9ddc94ca45b8768a0b96414dace446411a07fa0100835aa70b21526a1d6f59c167ae22e7e181a14cff96e1073f652cea4ff504180c74320633527430719178a4f75e65ae9464d7dff690bbed239e00e7d166c5b7f8b6f12d510c7d8e619976b359c3cf71b6ecca2984dbd080e631af5c0e5b4c5641aba47eeb4f3b0d942eff17da0f59ef22a12bf3c09f3c24b462743e396a0bdc21b728bb1a73c6d0038bdeb6c078efe49262c597c50cae204d7ee129f7189ec333b2099d5b8c30a5e651402dfcdd65aac3a30ce35e905b8480a45f3f339b81eecc19ed0b36f40fea6490f47ee1a3386678164e1f299abf45dbadd518f38c758bf4366f8e6a5774ce0ae4c4501f11b06fd72eb8ccc25e5bff4809ffbc78faf3b0055394348513fcc2053207008244ed0461660105fcdb9540cd7a026cd3485c5a06ed7907309c1666f9391eac01bf63d0c6d4818cfa4782e5350f14f0b61dfc566d2d6ae766ba4832a974e7524c351bdcf5279fc49f385894f64c56dafcea13762d9c1763515fe16207ce1873a183ecb0a7e557a2807289a868cc4194efa2b46e0cdfa8668eaf99e583888030891f9991f47cbd11e6594ddcaa87f1d8caf858fedb73269b5dc5749aaa794cd37241100ae2c6ab74f5e5d091cca278b3e2f16109d0fde76230e5b3c91c6b63dbf736fb2af20429af3975d589ccbf41515d492560e92c4f72ca6655c3faa78ea5f49487d2812c72b455b8be1c1b881d243e1bce03a6b171cbdba96e795eb0164cbdf40538e98efcde2843a8b1b12e66daccc68e2b4c169a7198090dcc60934783bab955259332dc3b2fd9f2ee83ab234184c22554325e0fb07c52cd3d1737f12911947312c46ee47ace07e8183dede9d52d1e4d9b8447ecc3f21d8ae22c4065d4a12ec8b0c317324595f5dcf17b14642d0e8b18c1a821723a9970281a593fd865fb6b9fe3c93e58767d3a60a55972e505cbfdafcd957752d2015af86b956972691ae027725c9bc6bd5ad63e8b41ccc5c6c0bce89441e1ecd86b20c73780b4e453a10cd3928c354bdb96fce9f09bfc0c0e34298604a0f2ab0e87d5ec6d3e20ca312695da3b65f8218f161a05fb224437c94c8a936b2f73f27f112df39ec596ec8248e228d379acedb3664a1a96825db7c770c43cf3fd1d8abff9fd68977a72d2cb6c3792c88588913e106a77749fbc9f8f5f0e3178475caf5b228327a7c1620c3b4e3a9e41f66456e40f484343dd3e14ce084e82a06d285379094d7d820b02673e16c79dc1a5e56c04d69a33b328a944d94e33c8009d7071d3dce25b74b1c7b7ff60cee8807c9dc1b8e854c79087e9ac00ec8216e01f1ecccab81432563d71e604af79bbb24761c6fbebb1b5420764624e0d6b08d7127661873b756cfbd99cdeb494228d03a619cda283e430da5cf2ea8854e3bb42b5af8dc957901e2442c89d189c7d0739eaa4c79aac9cc829bc70320c896d626b5cd2f862bae1294f3e2c83270e61c12d1db6064c4be559bbb03bca33d3129437a5f0f0696b9d36cd29b4f98561e4cf0e765258b324c50066db05ec4ed01caf9f6fec58dbd5818fad71b2ddf59c70506a2245e3a3a2753152d94b3b79a90ce2af0f6819bd9ccda102b73b81419c2a317c59d2baa3a963214050d15aa8fa85ea825a8e9852bbd3711ce45b495079b610c18789e0123c6d07178387bcd88fff0ac62437c5dbddcba1ea4af9ad0983f57381c438ff89700eede5047951aae1cd545597ef2f59b82ee173d1e06dbfd55f93b944ad68aafaab9eacbe1ee366e2e650881647d375abf478ea48cd", @@ -3462,9 +4100,9 @@ static const char *kData126[] = { "be95c376d9934950577b682d82985f0ffc2adeb9ac1d801cee6ddad69d342046487798373560db6331ac07287a9240fe1cffa3bcb14825ee235389e80ecfbbe138c349f6fb43574077213fa5a995ecc936eb12b011a7a1b3417b33f2adc3963a2b7abbd2314c4d32291cf24e9d0e896bd709c01e5a05acb60bb7713234b450557e460aa3ba916c5da158a88f37fab9c0a293565610ee33a42fe1b632c9c5ec0a70667d5fe236fd8405a80152bb91ccf336608dbc472602343579d0bca549d6d97155ff65e6d3cd2342ba931158a97613ea430b8fe663c28dac1cce08e8c28db4bae76758d3d186b6e34c631ad743a20ab81771879df17361e7d5db49fb0a88651d6d4b388b925714c19d790c50a76182f3d121dff6fae46fcd97e7eff2277bc8c6b87984c0fdb67cdec92b763d867ac3f54f30ea1c5e86be4484b8d52408dd9638f3d13d32e9fc43a7596c9748e0aaeabc83c08a7849c28df6262ffa83128341431cb97eb574990a2e2e92610035442bd7fa3520c4ad3f6a849297ff68650516fb80b786a3cd5a2699e37ab1f36d40c6b35843ba7cca1aa445af87711feea243c787165dc51975ae058f80cd70a272721e7d3be99db79e76c9cdbb476eea6b73e50968e9ff7515d78bf550e9b77fde7f686544e238483e7444faef2829a01651eb76aa767c03dbfd37c79ed8d77491cdc75798d230d9734052ab886075da01556263d09e82f2682bbad8c26d780ed6def00bbd3413a3b7d69d2eafc4ea0c42fa89114964aa4b775b5840ea4ea9f69b01d269ba4551f1aa7bff0dafd8e3ed13941abcd91fb3bef76a7b49340382eeca128b9ddd1bb253c1d082f02d20c37f0411a57ba5249b05b1ca2959aa140edfc4bbb474c9273909594b1d970124f86f861c0504bcb56d7ce395da042c175384e8e1c0b2be453df961e9fb0e8d60ad09ab6b8c8b09d8c7c3fa0c0376e70fe6487dab64d398257b8293c19bca53ec82479f7784f5359ef3577c7904acfd59ba3694283d7f0b63be70c5f7e55b45ae013ba5a8a77126a11154e91f8c3e9ed719e087c73e425c7425abda06860b898b1763dc030debaa9790ac22263a099573d6b4fa2ac17ffc9e7e0fa710a23326b965df9e2d2a69f07a249f7b2c931f2219a3f6281aa96937b1f88f952693519089b4504965e0408dc018f449c566f027866f891ca75832689995b72fd5f518e5a1e37f33c06775166822050932319f0d1e53bbccb9ae4d18c100086fae3311c69650d2317d83e4a164c4e67278dc1539dfaf2d9e02b52cd6885c9a66831cb81ce13422ccb069067ab6a6c4d3c89650677551c344918a5c24b0973ef5727f9593c59ba1026a82ca6e78033d6ba6a40488c5ec91708ec2479dc53d0ba7fe14bb238181f1c058e694898c914c2208dc01979119bfc0195e8ac0fcaca51d61fcfc5f72d92ba68a8d51394eea8d10b624dff051a9153b7d729f50f02d04547a6676add6ee0338b6d9ca9dee43260980291adaed18759bddd5311b7b46956cd113a076a3995b2e72cd1a5138dc31fcb5edfbc514bd2ee72fb53e0722367afc717b9ec401e4213a317583e6b3b19a75e1c63f1889f60dfb3059b0a64b85fb758651c713ac43345c8cd3c801da3f6ba8aceaba572f46100def2adcc135c4af0965f379a7a6c75d039a2cd40f2bb5919a3c8b74d58bc9d008b592f2ddb3acf4888e8b7873585f1f3d8581c743b324873fc23a345176635375b746575f79d361d186108eb5609dc78612b7bb530b6327bca6dfca45fb4f4f975afd1bf0f898dae164a19dee3f0feaaede1440cc7ff8fcb21145680e8a24e2eb5404697e25c2558ae9289f528a8faa572a354931a1cd4bc05bfb0116a0359a6b70aa79b145a88df482ed33354c260d1567e000b2d315e2808138638fd7bf7f4e88add370d24ceab5a999643741b13612ea85f67ecfc728e110aedeff58060a8aff0b7e1526f4aa60b9f9b558c2acf584a83b08d91901d6cff5ea2bcdd832303539703d30102ca067db40908dd8b555834a6060f3f6e7189612ed0d3b6c645db8b113909a38149072b3decb1f3a28be9223cfde40c2feea7e8c9d5bf37a2e55a60d8f89c391903e49bc644178531e6891653b1a4d73ee0870b18f8d53a089d5066dfadc3d92271232455637b20c298d640cb04b668d7080a510146b08031fcb84f41ca0cc85428f27ea9657de94073fec43d2c8c464723539276dbdcef593d716d02d172d30e76a9fc022d4952621d4c306278d3969592469d9a9ba62841dedd07e76a362b67ae5f925fae70f27c9cc870ba7b15d2d7d81b4e1d49f02fd963fa6f9ea5f4c901eade1114d92eabbde70cb0c6ba9136c68cbd25acb278e6cc73f9e625f1747e281d248739ecaaf403a21269758211121db85805ac522295ece97b8f90abb56e5a762bb7601b916befe8257e02a2b10c8384887de04b2d1c5afabe583367690c03d3ea6f7294f71b82ca80cd99951e5ccfe9ce7cbc5e04d1d60dcdd2ec88f9edb424bce5f04217be277700df4035443d18c14391bc9469f38f78f41f2d983bf761296161216e5719b37e3653de0d4a90a5171c2fdb9547a75be38910aa96c27ecc4e1fcf7a12d5254a8951a659df30db813ad7c75716ac050e61bd76ee5a4ec0bd7208a4c8cf4dfa0ac4438fc7f85e23db79d006e2acfb8d5a4229dbf0ee5ee26d064dc57a1dfb4374dc306158c1f8a9fe450a11e7ed21700ab2b817724a7139e2ac3df5f953ade220d996821ccef9e8f58a9c4996ed0bf6e70fc17237141d822f393cbc725b6813626cc63b88f5b893732969b47dc884c772e12c9099be0e519eccbc31d5b5886fbd737499a622058d6c13e200e7b201839c52634dd89e87a742cc99c5971e0b7cd976e8b1f5043a74fd6bd9d30eb8ab29c332057b2dac2f95739f34f1abe9e85b856f1d2df1d80915338cfc454b70ce41c2ce77da0f06f3b113d8ebc2ea441721a2f4d6e573eef2ce7e86c2c68a1060f6836526723e6726046c6efc68178798d967a88c17b4b4c59b96828d7497c7e40d6cb57e8f83c7164ad56c4e95cf551cbfe0314523fd7ca84bd0063ba241b591799b5422ba0cec9c2d5d5a3785bc510a4b12ece05c1081bd489edf428bba344eac60f1c9a59152fb8442c7b65987ac41b5ee2ff7ca6b8bbeded9e8b10ece0a3a792a508ac22497df9e66031edade139dffb19a3fc7d27b9bcd572d60b6a0f3482b8fb6ef495e2aaad99cdb89cf6171609096e4f2f03e21f01ad554c59d008ffce5f1ba874fc58638179ff01dd4fdfb01c4b60e08e315654fa5e211d0b75109439082a982ace4667ef510211b1c3ed116bbff57a3304161e1707f4f9c3b22365760b1de206a68c4eea017970e138a5e29fa3f5fb28f220d84596c0a7fa5e192e7aac83a1b83f65a5a61b2ce0586cf5c387ad24efacdec8f4c9e96334b94a9994fe3181a5e0ef82dd8e6a9ca79dcf9e5dec753a01f8d8c89e709a63a92638f0dbd4d083cd80ee7b4c82bb08bdb24d77ead9d20fa041b32386bb68d7e5255290ce65dd07d470b220e5298bf80a064c940378f06d35a3eec74dc60be0a9f46d29014210cb09374406a02e48342bc07db10811d314b0fd9be677909c91958ef5b3de9660d105058cb3a9bb859a355d502076938dc0f8feab32cc342f08e5392735263ab0e84eae11b39e993f0a6dfbbbc69dd01a7c23989f05acf42829f0fedc564e8ea633dbd4a1ae9318b8a7fe03efc535eb008cf30f8c9d38fa572e79a1b6c8bb02b87050dfd40f6d8a91a3b1bbc167247613000dd7fdcfa7e49000eb3604cbc7e790b1df640acb5a7dfb359d138b6fe3e12a8025b512f429d47ddd60c8c56c9084c509766d38ee652d49fa12aa3c2a26be8faafe589bfbae0815203101127aa23abae6b01b4fb82a2f7fee10cac9092d92e68b48bf26629524f2d8882dcd18965c2b7b6ecbab0204bd90e68ba89f1af5ab3992604bebfd482babe08ac40f86dc638c9440796bacc8bda1895d75fa30fcb0434aab12526de4c026d320587ebc36843a662d5c646eefc6524d6350ab11206530a7e48b53c8ef851e1d17d1a78a5f0a58023b9081357b033e2ece1dfc4cd68f99ae754195ba9453cc90f60371ebfb5086f60619f6b951f0708c1304875c618eb30ff4acf7b16a5f88564cebd3afa0c509516889e4a58354aed00433173830cc90c16ebd6b366e7d2b43da4f37ee4a05860e2d3267b4b61facdfed2ffb1960adce69914d4f36d13a5b7d6920524b364c87c2697000335cc5fecbc68c24acb6a6235a61fff788daad1294df9d2fd0d012b446b35e3bd4592f4f6418d7e676cf46bfdf1ede5c9f9c3fabbf3ea0b435555d253412deb4c66922f54a59cedef5dfd961795b0a8840a78266810d45da1e76f4ff7c8642e106852173bb7fb44394bf4b285d95d711651031d8f062ea62f2503c0047d808a131a44c0d67bbf1ae1ff58f9018bd92c63bab4761f572ec67da2538bae95fee458b1f298d27be26fbeb9c80361e30e0738e7da2d5b0dd21817832bd2af3f92f2e6d9a8c75f0bdb4c5f31811c4ba4af5312aa615e0e72a987724b56d78c8d598a59eee50978dd4ef4aa0fe958ce88f6ff8d3672a5d07a50a4c61af4b8121e6b5efdf7e39842d91004d2a78cda448ad233708a91d6a9b0e29e5c6ae3494b3e73f81c04e9df3d7cb5e4f8484bddcc228e87c3efeb39ee367cc3e9bd25521b493b168d15f5e15379177fe625e9a6052f8e3312ba0b85380ce40ec62afe4abb8d21ff9e420865874f16525fa38e3ea1aab965f548db6ba2bc21001a836b2598792e4dc27ac82b136ce604f554078d44b80424f449968cd3e7f07e73c1769fd6bbf2580421d4fa4e6bc2929da999f4ff8fb9f6170210e1d2be140f6fba282ec31c9d57a6d69e73502d194b611b1adbbc4c028bcea1d4003368cd564a59bd93966f2996fe7c6ef5b7ca578dac3b59989080b47024732adf735ffd721fdd88638217d44ac912893f031366150855028af0b12719460cfcb72378447f43fde09ae5fa6060e41372e40b89e088b00decd495dc7f37f9e8a4421f504108fc2f56eef0bc2eefe041dc52cde085622407d0da699cdc018a7844e8f8589e62cdd3359b08a6b90c75eb5b77421df5316c6dcb2e0672369f3feb5fc368d112a1d4d00abbae91f28e5fbecf772c8bfa84c222963934b206f8f77886bfc27e03b876d3c33e59d29901d41c7f3209d9562eee953eeb239a9c83f3c649a86c55d84a799145eac8f05303dfa6530cb693bfd5d1facb26753f76c50a3528003044e64359f22d8b31750782dd323b003c767ab6a8332994c51b57563cdc60c181400c46b5e7f928684e049a146ff614facfc17ad5f34e23f2a3bed5bb41cae4c65b9e6a6e62fa7dbf787543e5d8d2dcda4dad9773ba129e75b4dbf341cf6261c71441875a690ceb6b56b1f8a5c2504f17d521e1fb2b9e802db8a2e332c9ec91dfa044b0d948be844b6c67547efa07d74c9f9b1f44998888a62ce1b04a806923e3368fe4d9a1960191e022a1774589533b5c39090351ad793327dea2c54c6c03fe8afa5185e8579ef4f91a7b34d01b771bcb6cf1c9107bbb06045b4f689c034d4026a0540b44c24e9df543014a18\nresult = valid\nsalt = 8ed2f3533ae5da80bc34db49d9c3b3b0a7873baf9148772f286244b23ec6b3c1d9f235310c383c96bfe02a7e8be2c01c\nsize = 12240\n\n# tcId = 88\n# invalid output size\nikm = f39c81ba274637ba1460a7ecd776db66fa91ac12e1429be", "f84a9963b76c2c07f\ninfo = 516c2d910a221982\nokm = \nresult = invalid\nsalt = 408df96efb424324020d4836d100280b70f5d0e850e5460db77c543224ad5d2ba935060d1b5d63d80923fe922db1220a\nsize = 12241\nflags = SizeTooLarge\n\n# tcId = 89\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ef369d7b63f5509da56c5f6e446e2f03b700ca40c13e059ea0f43b08f5c29f15\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 90\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ef369d7b63f5509da56c5f6e446e2f03b700ca40c13e059ea0f43b08f5c29f15\nresult = valid\nsalt = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 91\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = b8365c28c10d6cd188f01efa320fa26713f7d87bf18f18529071607d1410b93c\nresult = valid\nsalt = 0102c651e047fed9c217bcf915520532d44999534c1e7e7c87311093d7a3681aff3e2d335b3c6139b9fc66dcfe35573b36a329a550c4cd20bfe2a90dfea50167ff\nsize = 32\n\n# tcId = 92\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = be14708389e4bf856681504fe3bd6a50eb33bf71a823337ada17316fc641344c\nresult = valid\nsalt = a0b5f9ccef84deab2a26b5d81f84e62b8800dbf270bad71f53d66881ccc543e33c20eb1b6526ffb53ab50399c5c96339\nsize = 32\n\n# tcId = 93\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed66\nsize = 32\n\n# tcId = 94\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000\nsize = 32\n\n# tcId = 95\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000\nsize = 32\n\n# tcId = 96\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 97\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 98\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 99\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = ab13dba7201b6df9182666cf7e658b2660de998ac8410745c2873aeb502fa371\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n[keySize = 384]\n\n# tcId = 100\nikm = baa311295125e326efd92676775b9aa20a0acd68fdd9b05795cf82e157c7dac61394fdc26cd7f8a9015e9587c5d0855d\ninfo = ac9954349e500c55\nokm = 5f027dcc4e32bc2f1c23de92b8b5fad67312fdeca2c09daa97bf0c81015bfe02ff2c17de1851336833666db3b29ceb16\nresult = valid\nsalt = 79f4669058de474f47efb74371ca5b6e3788a729abc31d47113ca0c2f972217ac9deb56b317f1e80fe42f5504c8690fa\nsize = 48\n\n# tcId = 101\nikm = a91adac5ab8bdd60fb350eb81d7243cf97740787877d41b40eee1c4c9a96f077e8bda335cb0e3b106454e85629bc5e63\ninfo = 3eb47169931585a5\nokm = fca326c96af6690eb9b61b4b2a23d78a05c90152667c87cf813c2c16f56047a63cc6103986d3c2bce48c5e4e031dde077fc153876bab3f57e12e871a506278f220d6180321ce84eb1ea45494d6b1c5bf44f60a397cf01d5a\nresult = valid\nsalt = 07e28c9f6efd74908c06435c95f3ab25f4d9a9e023f287e7298f9cde0cba29717baa1158e86fb70d5bd76d2549291923\nsize = 88\n\n# tcId = 102\nikm = e80e0fdb818f228c505ea15887a42abfd7b6479b589a76c33b0f63c00e7d188a20ef8e98534aa85df6e482750f85ad7f\ninfo = 31580276db515d6b\nokm = 941c9c841ecfd3b0d2c0488e0b327d151081d6f4d6b927c319df7ba4e3c9dd92ebe1c5b420af2f3b50b6991cc57a4f5a6aded05d5be9d699b4c70555e3dae218eb520158fd63e7be11bff5c5601ed9c6e616147aeb9878d01314ff519c4fe23bf29abe768df09bc485c175d9320e93aebce8336bd83c400b69d07fc19ff692bf05d299b25679cd038bffa43405057d22f014b9db5e5d94f09d3f6cea5d479d7e70f31dce39e2acd93f47f789ff094c0ae4c68b231d818548a81cd1373120b0f5\nresult = valid\nsalt = d1dd17d92c45854e1c617830ec2bd6ea613d8debe261ac30f0fdf9358a2be2dbb25f7ffaa9eee85f06df367b370804c8\nsize = 192\n\n", }; -static const size_t kLen127 = 129346; +static const size_t kLen181 = 129346; -static const char *kData127[] = { +static const char *kData181[] = { "# Imported from Wycheproof's hkdf_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HKDF-SHA-512\n# Generator version: 0.8rc17\n\n[keySize = 128]\n\n# tcId = 1\nikm = 60ab7f45b0ad534683b3a6c020d4f775\ninfo = \nokm = 2109bd244744acae2b8caa9e70f57596ad680212\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 2\nikm = e3db76e02278cbd2adbcb4555803da11\ninfo = \nokm = b28e3c338c70ede899f2a2654f2cd7e0d958d16eab2fa2a76035a2696054b68fa963c617b8fc2a826917\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 3\nikm = d4dcb92a769f57c8bab8a420ee0aa351\ninfo = \nokm = a8420281c08c5f087c9d54d5660847805b0fff2d6257f02bf849badfa8a29bee84ebe704a6eadc0beba0c33805d5843e167b1966aeba6a15b0f1f7b3db8c407a\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 4\nikm = 2d43e54bf0c94c9cbff4300f4aa69ab8\ninfo = d674da3bb47d5c7e38b501e5251d9348af601c44\nokm = ccd42097a730e47cd2908a834f9d81a3239f4b91\nresult = valid\nsalt = \nsize = 20\nflags = EmptySalt\n\n# tcId = 5\nikm = 4055536896c406d5fe14a6cd6b999bff\ninfo = 2094768a8816f7df070d6e08b7ad93755dc9024b\nokm = 0191ca548ab4c1f91eeaeaa2e561f954983885dd363c80079f7bbd053da4274b236f4ef0e4954b34a386\nresult = valid\nsalt = \nsize = 42\nflags = EmptySalt\n\n# tcId = 6\nikm = 5b01b2da3166f217cdd68de8af60078f\ninfo = 6884cfa7ffe8f27bf4ebc6e46a7e01488c79243a\nokm = 01e10d4c477c906d4f67105e4a8054bd2e9479d726166893fcf77b5df431ad007c0ae42847d3706a770a5e468783c9519804be63a404112dcd4ecea952952b73\nresult = valid\nsalt = \nsize = 64\nflags = EmptySalt\n\n# tcId = 7\nikm = 467403c2ec02a235bf730ff37e8d8ff3\ninfo = \nokm = 13abf6dd4468e2db7114437adc914cda3fab1c26\nresult = valid\nsalt = 41f0f173d307d40436c25856cf559f96\nsize = 20\n\n# tcId = 8\nikm = 3352f942aa93071da6d39cc5ed8dc460\ninfo = \nokm = 3cbd7242368ce2eecacd1839876cf2e8ee04d8c54848bf5515dfdd046fbe09483982d406345d1f71a4f9\nresult = valid\nsalt = 57a0db708b25a51afc4271803aa35204\nsize = 42\n\n# tcId = 9\nikm = 08867e76311126089356623ba5381e73\ninfo = \nokm = 098d9f9e0e0c609b94e8aa57b0449cdb3929605f821cda305e4d93746553a40a1e4c97565183e116511c3dc5d9d56561c698849a114692c8128b5d3c1cd728f7\nresult = valid\nsalt = 0c164c443edcdfaedb1ab150f047951f\nsize = 64\n\n# tcId = 10\nikm = c55c41d69d2424a520414e3662aa7303\ninfo = 3fdf20538063b76901d61bbf9b72b0c18749e00e\nokm = 19c2ea76fcf7ea72279de10e44533436300e250d\nresult = valid\nsalt = fea9bfc92b74337e43a201a2dc199e27\nsize = 20\n\n# tcId = 11\nikm = 5d3db20e8238a90b62a600fa57fdb318\ninfo = 2bc5f39032b6fc87da69ba8711ce735b169646fd\nokm = 8c3cf7122dcb5eb7efaf02718f1faf70bca20dcb75070e9d0871a413a6c05fc195a75aa9ffc349d70aae\nresult = valid\nsalt = 1d6f3b38a1e607b5e6bcd4af1800a9d3\nsize = 42\n\n# tcId = 12\nikm = 8677dc79233ef3480777c4c601ef4f0b\ninfo = a38f634d947819a9bfa792174b42baa20c9fce15\nokm = 918e9cda37bf7f52506111048a878e64a503f9869d0c2615047b995f1efedc4f713b4dbcc940838e68f6a2bf772ebefae9154e9075da80ea1fd68b9df580ad76\nresult = valid\nsalt = ad88db718244e2cb60e35f874d7ad81f\nsize = 64\n\n# tcId = 13\nikm = 0f602703d37943e0253bed3da331aff4\ninfo = \nokm = 60738c594db9638656cc8493db969736e743e152\nresult = valid\nsalt = ebdc8510499f69b2e188daab77cd819cccb95f276f46e6b2be11cbe72700\nsize = 20\n\n# tcId = 14\nikm = 9fe65737574c5c7aa67646adf8230ba8\ninfo = \nokm = d02f9f8a507d3cb0bc047b0d979b50f94dd9f3d805a5d7f5cd372ca14479cb698e17a95c737849aa7881\nresult = valid\nsalt = 73a34648c152443586236abcb46a090ce55ef6c7f282ffce6342d694650a\nsize = 42\n\n# tcId = 15\nikm = e8f2b1c3e6a6c3d5ee0a20dd47aafa78\ninfo = \nokm = 34718d60d8eba9f7ad6d111ef14160652381239551aca21bfc1f250f8d04c64cb6cd503c7f5fb3ff6b73ce234cf6bf91056228a8a51599a39c402e32d47618cb\nresult = valid\nsalt = 3f5e162de91e0782cd189f3b7778cdc2ce6bfe9d3fe841cd3c70475d7b3c\nsize = 64\n\n# tcId = 16\nikm = a679521cdb56aafc5a4b76db0431a4dd\ninfo = 44ec41ab4f4e64f4a36e5e30c9f0dc1d77ae4974\nokm = cb914a0b318cd57eda5b9575dd511313b60cb7ef\nresult = valid\nsalt = 123033b1ddaead83a4b9cfef8a660bd8e00fde01e67c35656c6d7607d456\nsize = 20\n\n# tcId = 17\nikm = 49bf155ca102026f2a217ea1bc9843ac\ninfo = 851bda4faa8f7add2a3cbf0acf9c2786f8f955b2\nokm = 4a540a643b1597bfbd4cb38953f31b677c02c40cdcbdb6c48984aa8ff3e5dc17caf09d0a6f67afe92cb0\nresult = valid\nsalt = 76776e3b4d75f8f43dce4bded71f3b1ae6bcb012d9c0d59f78248b9427b8\nsize = 42\n\n# tcId = 18\nikm = 6cf725e939e8824d4392233eeac75d30\ninfo = 495425d9727fee2e2b7e78899868c1c3e7735e1d\nokm = 379e6d4fc3c9b344754a1094eac60b71e47e281695515987abbc3b22c1e267d95b101592896e08c869557ea82ba075d9c9524d3cb79d7d8cabb33364f5252968\nresult = valid\nsalt = 1e72f24b05a91a0093f34306ffced79e7003055b0833c6d0f27a4f33a1bd\nsize = 64\n\n# tcId = 19\nikm = a319ff7b5ba9b14ac72b681cecf0f742\ninfo = \nokm = ca31c0e0f5ddaa7fded85be96d6311d8b935307b08127f690f15f5ce3ed5a44d1c226e354e8d7e5069ef\nresult = valid\nsalt = d7e3bc6daed343ce77ef793e15a8246e4bfcbaf83d2ac956d0661d1df7262b2e7311623dfe4152caddbfda8fa8ed7a82656ec00b72c5adf7c9d388e5b3bc8d24\nsize = 42\n\n# tcId = 20\nikm = 34bae5a158c1678aa76a744417a70d7a\ninfo = 87ec30aa53acfc3d09ccc1d57d654fdbce403cd4\nokm = 65f5385dab06d375033a6a25926ef4bf5dc660737ab8ccef370af10cc9dcd7743cf273fd048f64b7301e\nresult = valid\nsalt = 1532075f363e061133780ac959bf653c7687d181b9431215d6f62dd2f1ec3019d61c50fa82c70ae25e624c849a276b0c57d7c02a4d753fe84a1a6621e9a5ef01\nsize = 42\n\n# tcId = 21\n# maximal output size\nikm = dfc7c0159b921546a4ccb3067cafdd6c\ninfo = 7fa60cc2c830aba2\nokm = b52c51a447b923e2e6acfc05cd6fb0fb65d8f67f7facce95d3fd4b0dc0dc41d7a92bd06c1fa156d7756d603f8c26a5023cb842c7a133850e842aceea3779417d29a517452fac99855a2ec52503e725975b1d1142fe20608ca753d39301d37d99ff5956b45a7b587e3ad485e135c0002dc9918ec49a985d494795b7cfd53641ea9ceec7834d33d060bdb2eb158d10caccf74f87465052f71c43e67567e62975f02cc79349ed381720965533fa5eaa172d8c7c017036a0b4076d5b76ca16f69586aecc94d2e93585c4c90834ba697d0ecdf04b322c4a6f1b468a7c89bda5ea1307cd99060427fb6c2daeb2f25ad3572b9df69a5bb783d0e91f5f72f95e3aea3575de29e0d91aa8011c85dc918481155dac096260475076e1b5b2cf8061e888de70697899771eb8eaa9c899de2a5fcacb78ecec49a1b8d72df2e208eec858e2af089003c34079a24c15cac878d5339933b91497fe6732bd2d0f77cfb4a5adac9d59a778e38a65c986fd4cbe5f3661ff6e4aec2cb1f103660708a06b9dda3eb50e76629375c4bfc4027f563ffffb0a6b17e80fb1c8705fd28cdace78666dcb64e009ebbd67d77b8fd18c1cac8f7e114c18b4215f4678d719672f7c3307eafeb91b1ac44675654b26c49ec71144fee1fdd0c238be154768be9e851187d41dd1e8842fb4c7de48061cb1a2568a8682aea5cd457453f281541ec0544da726c0fa38b76672867763c1937fde3c9c3f8b58e4120a1ee1704a3dc472da40ac9326aa417b49e3a9603cad661bf1c61f92dff92c553a8368ec0c3b5b105e4c3a4bd1b02a7fe12e93b6674a2b45396206a113d28bc77fa6135d1a3c5d4c876a8c17b6f4611483ed080642677255f7d0219c9e6e7e661ddf05fd7ba333194efa079121091d9b117d9f0281c2a0d51bdafc8a7e391ee607176b1ccbae5b0df7a936f9611753cd5bd815a9fab6bcb2a95343dd7781484afbcdf55d260335cfce70f07b8f4737c49c7a9d93335fbf5bd2595c77e5fb088f81c033ccf08673b446da6edd68cb0e1cb2b93c793dbbd3f845d76bc90728149d6f5bcf3360a5601d42e6befa0574d89ef6f3d749538f7fac02e4b122ab93cee09cd710b0aea2570d761164f6bf37b43f2a252fb5d17a737b83ff36cc07ed550f5cc6d32679691d9cdd72c91f9fd3229c8492c02710a3b380b8ff95d2ed3779cab4abe7e1d16d21b0572a0cff15488721e447efbab8db70c2a79d36e80b6e7da11101e06b560bf6c3dd0e3fe7decbab8c3a023597d07f2ae5af73bac662508f4a86db8e71b9e02545a970f614f66c18fc69e569ff96fc32c05f1b3e87d3376131d69ac2f0aa9e50f4c02806f164a29f32852f64291862609f423be3627ca2a0b76e09f1080c3b602396fc043c7bb77722c08574385685f711446600a98718e78f49ce1ca2d522061bee0dc45a5b899769d098282d1bfde4f35c9a60101dae768e91f59d69e6b9d6f5c08c067044c7efa01790ad94b8e3c562ea8501f67b43933e76a7e416bdacf52f7ced3f5f01af4e317b5e537cb6d1b96960832066d8ccc74ca06664a8416a390ca7d0f31aee6973ea9c4d08d7a14b6dcba15203cada6baf08934cd211b6ec988cf1ae8b23ec9da4f78c5a73313fe294fe2d19c5dd7e5086efaf5956d8653362f03d70a7c4a348ebbab64831a12ba64081e8e4b9233fa75096ac0f0d225f2ca3d4944aaaa7da6dc1bec11a9aecb14e21181bbcd0f5b466d40bdbcd69bbddd51a85e2e9cb8becd5da2c7fcaf20283a35f6408061f9cc0bf68088c68df7e257492f2b1a77db3f6e3884689b09ebe0af6d8bea07eb4ec4f78aa4f61f94533311ce24c8e3bbca0e57d96834e2ab1fe9b80f8ccab305e47e63145244f340480513ea6089fdeab01a69f4401d2da6aed99176d5603cedfad1a9ba79b277c35611801c03534b1de4784e5def8f2e1d81aa68207968e1e9baf3405cd5fffe6a0acab1a18e01540821cdc1b69d344111c6043ea8dd9196a3eb2ea9c2b1f6a1c77564c0eb144e376b9cfe74ba734eddec86ba19e2c57677547ff6", "5dce2091d57fe59b7515941acddacbe757029babde6d8363e9c87ea40973f121463e706514a6b93cacc4375b0a4b640731d39bad93aa5d81d0024406b9412b951158a4a91a40c39dbe50295b01281f78c65430e6ba97ad3106a672721c80909d5d0d3e95b5e81308fe7e9b7cd6145dae402c32967ff73b04a163405e8d104ce751203d2c354622370b9a54601c1b1c9d484d3827d2137faab9fbd6fdae854add24a933b1b32f33985cf3bc1132ee2f6b0399101801754e34ef0d15bd95a40e9d8b3241008e39082a518a3882e30ffa1b4073cc637b2412667d4b51993135746b748fd88ed5da3e83948d278426262368f57cf5179ffe02c35952539c1f61591825c63e8178f45b6eb515e4f02547f7118b39646b8840694ceeb28ad96b4a1f63941fe68cba5eda641538906fb6b930a9e4fca5b02b2ea1e155093dc56bdc8c88780ba1ac9402fd0674ade1621e0aae1936fdca343e6a05e791147150e06c9a5720c76cd7f1b6ea0e02472deed435d69081c57b88c33618bfc31938fb11e5d1e731e1ac83b24c15a32e3c4becdfb839c5e737d21e3321bfd607300b606ec2c73544741536cdb72b0853da920453443d6efd99694124b61d312e11a8bfad436df14d04f9f9fab14ec474c5df8f81f4dd1de24ca5a4a74880ef61106f1218b55df34ed85ff1a6139330c8df45b047fa3acc4f3b1c896cea3a979e8dc5f58ee34c44a82dcdfbbdb6a42e1332579399651cec217355acb55e45f8206bee4e53e6afc6811704e3119e191e3be8182219e8543095cbc639f1b66b4cfbf96fd3b7d02ef6f781b18882e8dc5ccd684d330141029a9d8c8ebebc3a9e49a7a0f21facc94ebe64cc538d328679f38b06f31b3c5996729ffd9d1cd95e7ad33e7c5dfc147c3e75cd9dc417a08c910fdc3041accbe5b669c649502e16c02b78729784d08e81e0bc40b4590836cd877f80217e23bbde955d56176372221ccf1f18b1bac1f5c150b0b4bd764206b7cfe43716f4bbdf7a44b4407278bd849479865a581812221fa56ec34c30a08fff4045853251a12f48e9bc4fbf58fb1cca7aa68b5703ab6f6be834923c933b2b467013a0e6c156f417e14ae817f20a18898db4806465980eda6f166dcd8d8e36f8a138a96d65aa739a4c3ffc5777d1303f4a3c44751b12ebf293df5fa49beaf657ea5e10c06c5160635b5ffb0b252c32a2f0cf448bfb934d099fb450de717981befb8fdf24fa711eea66e3f670124b68eee9c7861e3cdd3e3d1366d981a6362563dd7cd1c3f87faff083c39be3cf2f39101012bd105715f36c34ec8d6a4bfd35ee74a813e4fa0c98c077f6c9f2ebe1decc3b2455f6b2e99121f6b1478ca45d6b2ad2903ecf2294741f80d09076c447bed7da37e3445fea133a4cab5de5c4f7b46abb84756925f3e1e1a6adcad8cf667e6521aaea32d8fd5f423b9ad7fbd6003ca6d15d6457f31720d5ec7833e58866465d89d807b9bf71be745241e6dd2a179f5d2b6ebc9b92ad0a86a7c64d6fb15ddfaba5b030ed94a0cde4ff8f67282b572fcfa85072a3f1102fa710e60e4f59e906fa190ead2056a35efcee0d74d7d6f3bc05fefda6a43362eb966944c23c99810f0ad6998427f33c0e94388ed7e677dee402c48fe08409bb8e7a2109c230f1f0bbeacf57910d5beb58d1d83c10e55454cee4de633b63fba04904b9f796fd0d8428522536c50ba8ba2997b43198ccc4e3009eecbe43ff652e3e17e6cf0e9774b4b8616cc9bc30740c85fd04bdeb181aa281a3fee92bab269fe0999d85d89e8cd1a4d1682ee873de633eff0f51473e0e29d625c2582c2d67d941d6a80aa9eae47bd8b1c147601eaafda28e721082edc8724e3a6ca944f2b96286035fe8017a9dbfdac05d0602037bb330ad2e05aa6ac6b771a836334a7a8eae30f8a0caf757b74e63c995fdbebb159152c7ca7105245597035258bd9b031bfe1951c688cc224fb3ba8da6063f244cad38b8fb5db148dcb838eabdc402572bb30cd8ab5ecf9a220c513f6d45ae3472e04779776b014acd812f48b1356d2c8429213b0204734338d386e29ea394fd856533c1fa81483a3acf32cb33025373debc7d00c8d5a153dd3e56f5069c44a8ac745cb6d1cd6d0a37ddf4816bb64667da38ad6c75e246ed358e539febd606bd66d12153ec3d223a5ff15f74d7a46319c73962aaeaa8cd470a861782ec3de3ca235688a99bdd8b234e61f6a1264fb93292ea2826e3695ee16b6c57e4287220429d2d1a28c6dc8b5a0b50117d23b0b5f4df498d3ad61ac6fc58e398a9f4093b5aa92e23a1a4b5a34ef93b9662e60baccf9bdcce4c058b80469c01975c6f0742e7cab07c14f975072533081a312d30a251867341f0e904391252bb5cf03e9cbc9318e2aac65b0a69c506b7f9e8ad7b9d19ebde74801e0526a2bc03b4821f8cec964bf1763ba94930135d589dbbc63a048c42d79ead50613135278685f99a38070696a4c8e88985a9a4c7fea3e23bae77d287db1281bdfd00e60a5a5cffcf7c29962604df3017c8b4f4fffaf1a27f2d353fca7c40784219c8e31c06ac628257dbc3cecd1341cab153109fc5e0df5e89c0996525ae5d2f949876a85e6f5671e9043c28920f46f5c778490cd1ee733ca3eddb8003abd82fd6973a45e338b9091f472ac877ebf57161b9afc4ec5721a03f17729c95af786d27f02da6c53f43d339e313bc11aa483a354fef6e36d17508bc8f22a98f13508af80a5f136248cecd3c34da11b2ebec4b2f135b66f3188803b840eca048a559b33b842d340e489df31644ec53cac0d10646d6100f76e3c6e074a13e4194796113a770331bb84bd00fdea57433ed74849d90410e2a2913a79d642103a3b732725d6e7a7c02c4fa844fa4866aca3af7c257cc94720fc032eb482d75a27ffd5491b28144bc2191b2db5d4e515ab4c79c55af44000a821f02c31621b0efeef6a4ef945c59ea4b32a6b95b73bf9a2687a3d059c9cb7ea1472271066892c4ab14198897ae910311f0f353ddf4f9e8177f8bb10dc0a64e0c9be776c07d94fa788718973226077dffca41bcbd57c0cdb2cef9b95ddf7beffa76ea663b28225b382c11a8f1a9a7fb3d1ba4448c36aeb55e7a49adba4992d057dbf4dde3f24d208e0611ee7e15fa715046eb32fede6193f64356da54799599a582a499ed2c48182d9a4f208931b64105ed27385ac1727122cabec3580897762509a7a5e5fe4c3bf921bbf2f0308905895c298633dca6450cd9334708b3c0342c73e32674530d6588a7528cf2fef4077597d18e2342b692581d6ddd977ef3a7bff43dc0c5078f38985896f6e6dc753bc5d2b02d8152097f62fb92508bc80bc556e5295329a0b1502b4fccce062bf1166e21da5b1253c0165fda2d31e6d80b7e68e4687ba90acbdad5a8af67b06bdaefdfead0deed71d318805adea6f641fb35b300b9f79a8ef3822463258684e0ee033b5c304db81f3c104fcadc7aaeefd80b8184e2d016440463948d35058ba6be3dae282d096beb6cda140c3663bce15aeb07fae784de1372f766c0ffb2748fb1210f5eede51c67527dcaf5621d225586c17554bc78d367d70413e2a1e0cc06bebfa1fef2b7a971e08e50087d0266a4da1505dfbe5f639d29421bb7045712a603aa65d54e9070e4d71fdd4a14ba92681a8aaa0254b198dd5095780dab36afe8e6e85289c67740cbbca6723ee55173b1c36759edf969af04cd52c05480573f60ce7c97dd97b64e3da1b9889bde260d1dac867c75d365476678c33a4cc2adf218a1d469af05e821cea216bccbff7ed7ce7af028816181e01eee51a9f72c4520abb40a82bdbb8b7b69e97b92c0805555a9052f17a123ff4a1c797be25a661cfc8c3096dddfb987022bfaebf169bb7f3d83b9e66d1999bc8f75df07be79b3be2f1b69d8a5d3c4b9e3b8388ee06bb5891374c922a99f597729066efca97d709c55b9dcb49384a2e49c63e4c83c3378b8cb6147405d2998d113bc29909ebb2fe97fbcdeedfc89d686763bb9a43476a2690600a3cb83858f9198c1b8d5969dd534e609cbf3da0d311c70896772531a53f4e8329b2d8fea575831bfb77283bd688dd6a3004438cc10f0dbc4f5b982fd25325e16b530b6f3fd015036b92e166b5c38238211b81e8f7b92aa492027bd91fe3f8d879dd4b3220c4738fdae0ebd462f554eb1a51987988a130e78c40e0e03c7df1f7527d87899a1fed1ce4155992c753f7b5a8e554b99d14cbe36ab012687e89fe01a87e250bef650611d2be15071119f9649691eef5a147c253eb77eaaeb53d44b1e354e0b5c00eaeba91dc4c5eef389fe861a38f1f9dd4262cc2f85351b7dc1b8dd740f43040c85c5fcf4b3316738c1bf0d31960416a6cab54112987262ea54c06ead156de660559805558ab110145b2df2a601266991f00c9e4dc7567d33834a13a156419eb1cd213629b3ddebe5dce71212c4c08fcadc22ee78687d465b6908cd578729ba23f326c7f02f68a7e567a5c07effefaff4bdf726dc90d37e1f3b72e8332d3ef5016fabf5c73c384816e18d175d718c6fb5f702d39063ae9b92e05e1674cac86a7c34db1f11eb9dcc0898143d8a66e8ca343e4a3f20e593ecb311ac06a36c4e84068de483794bb0fcf516bfb291befb6ff7af518219d6bff8eab670b42e824610522e805aac17808ffeb87ff7bc135de4eee0fd200c4344fb88e4c178fbe517c9f2a4919dc2a3f3c68e849e255106cd5216235fc8d6a0ec04d9f4765c7c9f58a71d2ea63b4446b5ed4cdee274a224d3c4ee5d5edb1b0a7d4fcf7234e612652e06c88f670eccf15086f1da39dcb273e1c0e7365b7fd506b14944f2a387294a3221993e60f0a10a50b662b886e199d3421d0710bf08ebb40a876de217eab4222db41590f13e7660939173606158d050d3d3e5e902b497bea23c38b0715033e0aa117fc2ac13c8f467a9e2547d58e60a68f478b78e6ab7bf8c963a0e708a60cfd9cb5d9e3782bf3cf2449d0df555bbe8fed61c7b55e56b056ae1220e94e13ae292ae2aeb6fac9ab5c5b920889dc0c83d2852ecd25ee82227d112a1ccd356aba1087f72f3885d302b7d302dc44b61483e0d1a692bcf68d96574a462fe217f323c5d88e76cf792fa81e6956800b6c0b5ef54f596dec633ba322dcdb6affe30af64f39bc4907ad4ed4f74e1a067fa82f76fab1d05f0804124e65e2afb43cf97c3c335fa71b7efe743955a5b5910c297799a57fd46828969f8c9690d4e2f102aefb6ea3acd049d811d977827b88ae5c01319beb85ca0a9f3cb835733b8945ba5fe50c23a84864800c87e9e26e3271612006e057a3fc38fbbe52bf7db6bac81d1c1b6c1ec9d12d09a27ef91546cf9f2ac6354e2118bfedd3fcceb77c6aeef1abc9fb985770980d65dbd1b25651268ec9826f979d10d2c9f7b267349c2a2afe2d3a799472a1f555f38c8ec67cd153b3ba55cbc3864fe8bf4e8624d9051fc4270abdf759e1cb1ca09374a747e806002039acea004ba5cc557d04701871c4ca0c5814c1a5912c5ba11dd66a36ca49b098f0d16a1a067f3e5df1c49a6a1ce5a82851a518986d12e0e207eb73c94648ff95437de11e49fe8f1f99f2858356472fdffe262a384e42443cc535767ee5aa223664cd20254e8a26121329fe22b0f64cd59a4b4558d21568e8cfe22272163e3d2af3805703153fa7b252ecc87e2ed1f807d2c8f1f52bd46bab665c207fe031f943a2e48e688c96417496a553eef8ac31d2a284f579464ec7e1e863a603fcae6bda14452a6ff6ea9efd2b83036848905df1382", "32bd8f68ec7f69078469111304bcf83519431481bec07ac9baaafe37dd63dca2aa6a07918d6da72305a3104819759dd829ec38ef1f4f2d96325a1ef4080075dad795c9b99bc0170f3d9868d11edc63e47e3c5bea097abf2817bb5c0e1d682370a22d70310d73280d5b50cd197492ae15176e292ae2fe2e00edb69c55817d5b6fd6eb349c028d35478edcb877d5316cf53d91a91e381bad7c07f015bb7b5f5bbd5047e51207ab93564b2120d34c524aaad5ed7d6334d22971eedc4ace2e319421644ff8f0b072f083e7440dbf8b97dcaa32702e364e481cc7c6fed8b50bddf67165224516ca8043dff05c6a9ffdbfed302ec8587866937ccde5633787e4e2755a81562acef00e150975568ed07a35182c06c79ed2db3c738f4a14d0281a1e649dae9d6b9c13faf164c4eb24a639fbb382776bf5fc01a4ff8273bc8e2229fa421a530f4f625e6ad2ca3b3309ce6eb1b090796771606b41d7a875d62c895937a6f5b8a202a4a215a72977a5ef7a90d63c6be8c4acf2f468a2f67ce26cc13f2d1d39788660eddbea5dd1ccc07578fab26c0d15f64294f8e51aadc1face02f3b990cb49b5898388664dfd0d20aa9f93d0a8a606cded780841bfd8aee52a4c9f701c8461627f94cf4e501ddb23033cf514839a23206306c5158cbbc993614bea44e00b8c927cafd1df01381884bcf35827ec7903f6b6e9eb1c6f6e7e163b5aafd77088d59379437babf32201c99583e65888a06197863fbd2cd814126905e6c4df6a4a4217b7d31535448cc9cc82dc5c3b2d9e939c3b4b6edb4cd2548fc94a2b94cf5c3bf992e5c4b911308df9fb02a4f3bd2565b06486538ffa08adb77fc650b51a3c5d1437a09f8ef2ad418241e9d22e1054133565d13eed0095cfd57364ce634060519d52865344cdac47c5c5c91c3ac77ae18d392146f300fcbd35f61126868b13763eb3978d318f53ca31de3c94449bde5eef91690e1a69d6fb44ad56edef2f8659123fb7022346472a6e218ca641aea266e6e5d582147a2f8e40d0689abfd150c9228cdf6d994ea3d211260a8c6e7ed60b6710babef11ffbd7c0c7bfd6c23f8030164341158ea10697c02855b827561023c20df47c529aa71fbd242425ec2c0fe1d506a0b72bb3b37564390180e0c2597b91c4ab07e02f5e95d71279cb44c01bcc95a2f2cfd095d48e6501ebef72e0696702b1d86506be3e53ac548fe2f567606f0b8d6b9dd0e4cc0fb24d78c6f5c3e9bc59ad74ba7d0dc92646de38bd6f9329cfaf83babd3f94752c44e2e1a20a7c8735d1adf9876360e5916b16761a2e1eb6359870e521099da05eb535b008fbc519aa03b030835033e4d529cc93038eb836c85ca1d61bc454843f0b32992c4f155c18a5cfe15ff5a07eef8e64f741288e8ced16b372d41f82cd13f285a51209a80d7612ea7ed2f11d5bebc20fae499612a9f92e203e49de1fe3a5a8caa9b27f49de9c73e4b7206f87142edfc179cefdc06ba50b8aabeb06f20e6023ce71dc996b53119e6252709b0d42d4abfac576ac907d31403dc260d76d7ab2c6e3dc25a079878e543abb7238f5e0c178388075d1a0abe378dd46e3f28ee782ca60459ba930c5e4083c4d91f4e7538b85e71bb5997c748719ba412ca291e9b9e93e3792dfa471652b710e86bbd38d4c147de34fd1ab283b6b3d8b7eb886b7306137e8c94ed0b18bf7cad1e829186ca25d91bb60af412b37080728f94f8893e6956f99e48cf032eb1604c6ef2021ecea58b87b2673a3f7982ecf16b372d6315f0613dd8b964f5c11218853f0db2f4c12d990386fedd53a848270f9d16c197f48ea850ece23c9b892bfaba8aeefa9d8bda3e801b186ebd7588469028406e0e2605bd66ec849c3269b6e6356ba367e8915d9baa88fdf5d8e039990b858b956daa61faf19856721bc4780662f698cd0ed03ca4f4468115c2c1431bfa187c7edaad651d6f4b361939235622650c1287aaf97dffe04458ef2d10070293cad2ee1b42e405bf3f8a18158d89e58309c37fe6616bca374f89a7566d914cb5ebc32c29141d38cceceaa28bbb02e13d5e8ce5626e6742c54ad953ec5f34eb15e1fb92746cbfdbba531e5e2d3ac6725a02d17007d31d1c7ff2df57af6430559eefd0e814e40553244b8a4a4e31dcce5f5688a7407d262dcf5369a50c964b56b49389d7aa15c3cd40191b21a1faba10db56cf83b2b47aef0944ba252ceb790f52a2537b6d9935029dd9c78631c999ed03c06e9bc608d4a87aec4671fb361bd631699270af5c6304e0fbc309a4d46175ecd1ba5fdfe9bc08dc3745b27af2cc22d67043a8c9d2e616286042cd0286b66de058bf1bc424f035a07804364dd03f85e3353e218c871f9faab4e276a676d0bbc1ae56750a56901b46a65b8d0fe096e571e70b9007d6f2a3c138b49d1883f0d32ac3956b94db4955f638f99c131b7ba291075e7f14692769ea03d8a05a64f68dd34ec9e39b7685192715b3b79463ade1c16dbe3522447078684a50264b26f79f9c6bdf1e8373a3d161f91962f5a850524bff5437bc9b9eecb657141f91aeec634db228a5246a9e2a2f96c005fedcea91bf8c4623894cfdddfe606c7f81cec461678b72cb4542715a72e5790be4f0bd62f36d6d2a1182c19f7832d9dab663c75e89f2f84603e9a172db7d89271ae0cbc7186c17a71204394f63294b540ef407d4b7b83d087026976b3e4b2d3e3252a6e9c281704bbc21333bc15c5f0fd67ecde2a13b763dddc1b6770c28641bafeca1bf333b09d5735b117bd3b93d404afdea4a35b05e910985225472d6363b481adb11672b6cf1ac2e8a6b50b04b355ff9f15fd661b36b8f00a9af9775c7c6fe44fcfc33bb73f702ea96d647cc6758edf04c77e209baec6c2c99bbaf14b43f100e920afcb470bfa5d638e8938908131cebd588f4591f846591b5ac53c32ae5809a807d57b74f08d949eb55f8e21b4b0b6007600a541e0aedbd027727592b6720f4275e832da4a488efba1ca4e94ed3702a2c978c656984960c0893b911aa7ed49cd70d543894eac675b2d9a37659cb89aba129a285323f92918801987f2d87b8c328005ae3fd99c48c1677f057f3b4eb9ed4375ff2cc0b34049276a9007388e0eaff0b20a7d209ce1186707e7773bc95fe97fefc2ba6a06680dd37608d1f76e91fe0a5fcf49577058e4ee270e6966c71f482456b31ca90bd7b43c3781a48eca3eb0689c3a93e9b258d25e49861e6a37e4de6491f6e4924a9fbc6e712fd4aeccdadf5ebf6dcfdc862e11bc52ee047460ed3d0bf6d472500b03762ee040ea403540ef4ce2495e50b64c0b541f7f27d14a6e6e20a3089ef309ce106504788a40fc4ab08a31608ec5237409fe59978339c672ebd22da9af5e791cb41dafad39e6217bee14f7367618e6183ff7280fc9b960871418b2d249b14879dce08f4bf1c1a1150672b5ab73002064d9d2b39941244c3d892d9d901bb9903aa66f224c2944b185c4a4f457d07f9587e850c4a0357bb6d64f0d3ad5f77edad72538dfa9df8569ec6094b24e36fb7a73938a13dac36aaf5813bfd5106e8d4064b9d82b45e3ec7caaa743e393c5de2145f711a6f653ad8de4cca55d9a8c4e90af42aaab37957dd4c9e7bca090dc713820e2395cf884b00e898f5196a8ee68ac822fcbc1a02ad92804d6e01bad3c337e3cdf3050da13a4cc0e5e677d2c225f6a297b4f077a90f52869e548b939a5fdfca735c2d0a58f279e624be63b6ae8ea3e5fc992f821ca38a5f67a05e721c90e79a5192bd6758d3d126ba9646c571b1a9678ac57975894f96f0ae17f0e2ad8cec39e8bc7de599e46bc05811360150acbff1d114cffe1edfba639fb63a1896cda03d42e6cf8fce4473426d92377e23454e8f289c01882305ea571138ae226d7c2951dee3b41f82e00c2425fc7c0b0bf925fdadc8e9abea6464ff49393539495e8b2b2b60a46a256b07b99a961bd11acafdb4235eb1a9d428296f068495861b824bf3be80a7e58dd09062d8141dba93f4b969a3a056cf78c3b91f6987262798045d5e72494bf3954bb56b6f9576ebeb2a4085aca829def1fdcf8a34140e859586819f7c50ef6aa4910c868de43f1c510fd6c049ddedd62dde4f6efbb83959d0a9157bee03c782b0b6e9e965bb0628e0600531372cdf27f510f47f4ec377dda208d43c5da5a0690498ed64dc9efb560295afdd09fe1fad5b1867a44cbde8faad2da662336183620eb7cec6d9bb09e60dcf67d332f28b4b07da39e25ab94fe074bd4919673625de5565a83ec7e42dcdcebe3ee5bcb1d52e7db91e1ac1f76359114080bb4e268d243906cbe5cbab8fef482732b971c4052e746c7136edba055dc6527e0516f5999c05654d28f4e23b56fe7da84d690ebc208193c6859c302346555c76f1e5f92cb4bc8f95abb2522d25a9b31387f3b3002d4c9f6b40d36d19b31fcf7715d9868513eef8de50afbd4f10caef4edebff586250b9965f8414ccf493a5f4c81032a0972c7ee33986cb278f6ff999e8f7be77795241a0c801966071c8f12aba59d9011f46acc1524b9683eef30700f8bab89a9c3d981e61be6d2e7b5227539d0c0227d8d1583e454404283517c2f4915c3612dba632ff9ada1aeb3ae94e9ba31a5c6a9fc555a8b1772fd2f2c7664b50a021f3e7174a65c386278ca670b398afc43c5bc79e6df61766780b73e0bba811fcf7c11541802953d01289f315fc4d1689f27e34ed4179ece68e550357a0ead1c34b7bd7b36d4fd5c812539877255ce67c1f561d58d9389eeda415d939bc3ab34a80e21fe9c6838b751130ceddbd412f8faa61b369670917b4778b0c0244619a6d483466a5ef85ec76a8514fdb1ac5cc429d6c6d6e5904776fced03bb677d9c3929fce21e0cd0f161d6d2e6149f6653f97cf62e802212ad1c6207866ad0fe6261428957f9aa0606262db22ca6490ed5930db5ce49a016265f12ea5262620acf93dc0a22fbb8147d92a11e6ca3999e0cf6d7b2770124db73949f84556ddc3008a0e27c686c40b8f3eac972a4c75a84e76dce3f917f2abe9de474cce9e6fa11711411d471971d74ee7474bf8e612ee769ba9878384f0b61a98c6c62f27dcd96398fc04883cde133d86e396b28c08443217a14efa2fc801cda336afa7481ddb71489df94bb8b432240ed0186511e55d8c03397306d8b67c2fa79da7380a866d40a5af26d5fdaaac09f98eebc69b1b4c0d339115a25c6435c7e6f8905406f0c6dba03d54f32e20333c5c2273613a764a7d594f967f9471a206380ed6f38997a55b7a4287d4f2b1cfd6c15c188b55696b90d5625ed0f33a9dc3ebb89e085bb7e295236b2be0872ec037b43a64b0896d2daaff9058d028298b7aca6a1053cc500885314cd0a304fa04e95a6ee95f859823c1a17808903cdc093c039b11c78108ec49a1af11a3188d61c9517f781745e32a02153a1f9af4fa8d7db0b3d34268c129a2c5f7b72f07342d1f3221037704da06235a6c55c3bec83b705087ca5293765ef24603f36b9280efa3c4683fd25190ccf2342034ac0fe5813ef2aac89c06a0ed565d2f9d590824a09ae785e581628ab9b0de009a736a3939bbe79c62111cf6a16fccdd4f1266017f7e68cfe71898b4ddfcfc58869de822590b124ce4c188eca36087b5f848fa8dc1b8178b943d8096fe3a94e24745026ce50f62632610540fcd8c2db5b9cf714002f8db11807f008e719304f269d1fc41473d14d97f85bcfe4c797bd0529fa8450286284fc57e63f4952e73f96268e7a413754182d5ccfb1fdf5c05a0c016696dae8516e8", @@ -3482,35 +4120,35 @@ static const char *kData127[] = { "b8069b185e8ca97f1772204e5a84ceadc892f8d3dcd2e3314d0d52894beea8ce9a536a88231f4d4386da6cae92841b9b90f78efa335ebca2464dd7017346fb53240150b5effbe0ef6b2d22398879ad07f981a2f079f28e29b73e67b58fa3163bb9411a5be962fdcf419ed7f5e67edb9c325aa6f1440d04a5111dc190e085e7c0f68365ab086f83ea68b4607f7219a4719e5c8288a0bc08889bfbe0dfc469cd9a90d440826ffa49296cd8b157a14f4383d47470bc139e2d38e0656b56f9958b5e08ac1802bffc142f9fed8df02e04ff976ead2817af9cc173aa9328fd73416fd105cd6d5742f509f7ea8864e13d4030555142c5507f1c2c74aa273cb9823e12c54d28842756504b966e2c157a46b20f57154ed063db1d2c31e55642edeaf53c3d078c255f168e5905689c30e94c8ef657e3990e3d32f09d41fbf6c4a360e3cf7957cff3888343f1b24d277d4dd8e70a3defe4cb5247b9f6c24f7469bf5d9270e9a1edd5e764ccd8b5e08927c066e08a792166b7907ef572dc9218600b18ca4c0de84870580871201db507af257d516c40c01902ac4be0a8190fbef31e71cf812dd3fd0d01cc6f4e5abec3bd68cefc1c97aef46e84923c08997c6ad565edbb70b0cd65856fb253cb35f9e10b485713cfcd5dd870ed6ea4d6490ef08323757b067abe2a1ddeb4e4e5b2471eba838682e0c611894bbfc1fbc831d2e6969798016462299a89f2a60860a5ed5fdc5854b2fb6c5b7f7e1b0efd261f70624c290c9207e903900faad06a7690b924edfda733a6e1b9541b556ff4c5585c3530349060eaa8576cc0e56ee3687fd087e26d933e4d0c5cbbd887302c3622a1a747096dedb5fc9cbc86b084df79d205cdfe29bb6e53b8f34d67111dd8218af04142332ddecb12e66d59307633b51d33e465b00b8126d2708d6caf45aa045a800b2860da7ed2b0af0f949a6fb164a9d5c837de7ccb4931c45b6b0c857c52f9030a377a75e5b27623e5d63badbd3d4d15dd9c36dd518f54a7f9f3271686fe5e606e608aacc9114e3ec0f6cc90ac163dd2ffde0fe8f2012477bc3a7a90b9df4233648634ec312a46994d4399ee5b5446c47c4d51658d88d2584bf7fedb329557ff80fcf1a94b03515561539b20e90e4da5c0626b51efeba29496fbc3091b70a73d9fbdb8739606dc5ee6d564d0f54d7febceb590be1e0f2b78fa7b21d5e181c6ba899c40d234e438bccfe37ba779cd8e1194a496e459c9e76fb9d8494a1182623ee747a3349b75bcd90dfc760f6fc72c174b5809789301ccfe6685c69968d1400ea9ecaa2441b8d772ecbbc8b8bbf0cde4887a9729298cbeeb2f9f5c8a823b0634818f78d0d4a79b2252fb5aeaa6c2b89b8818c18a21930e5b740cd842d049e02690fe0c10ff9b962068454d63f4a1bf7f6c5b7bec88db6810bfebfa38071ced9253e21f4be3790c5d96c6e99347b02d1fc6786aa7266bdc6f5c0e39891e772773ff348bf7e54bf21870692d07f2ba6558a20012d80351a9fe55ebbaeee155ffd13f59bab4917f75b1b8a0288340df5e06eee792497cded2f92016c00e44107b3eda12a007e84f9b81b09b21c22760e5d143c7acf0e057817149f07c055e049d96e0490f9b860bb80473a597fa2a842e0d20e7f2dce2eb2c5c68dab59d5205a5c9eeb3087b7cc798b02bd1bd84ac7d6973624fec2443fbbcd67cda5742651a441c0aaeaec96fb1186f66bc33f488c6f243ab16a07227e6796ab2124b62f6cb47255f2cab97c44dc94a090b366aeeee5efbf3846a47a886ff23b29dbec2a3df3b6295127d9b7fa6de46a69c7c195845e996a4384c07d1282dc7cd461fcf7eed91348d7481a4de5b3dae00f7326364c77f746e0271981779dc832edc3665628b504d657103f303443c653c1a1e898f99c794180bdfc2075787c0a6392e57b8afd6a517367cf614474ad2af4c221b448a23c0083daac98f16c9031504e778daf072db58eebf0485fd739e8431b88684f8cb3ca585577e8795415a16f19a11b5a60ae17bd244d12339bf1f5e9610cd19f1b020421c6b5cf6fd3442883cf10dd8ab6ccec576c81ee4cd404e89510b4035947a370442ef46a71ea93703505c240d8430c35d42078f45ff49b2fd382379643b36318efbcaef2d063e5f0306551454752b86adf5e406a9f190a0ac2fd3e8a17f1b02168e1a1a97b909e79c5e820376e6832bc3be73bace1dd05ec791590daf112a232a460a133e0d222d11d6faad404924c8591bd5900b34c829f6ab52fac5ff158b40089324d8e2ffdd53d0dd85b43995f7df351ec38825ea4deb1359e7fbfc8eff2135241fbfd484e1e832b3a680c8e228e5d5e5356818bf93d2b97bb68c6d6e528fcd6bc0fbc3ebb28ad842d94e750072d3a635e69969b778c8f14a97a2d28042a4071753fab49db785b5c41f7761ef49280a1a689642d6e47eb6e03cfcc18313729895c6bdc6bee62a970bcb247099c27c29733de0ed2de83674756ef4c84c41ffb7d47d67aeb8737ba082a33aea742601158d4843e55ee641a0fdc956a3bf2fba5f391b73036f1b4150f2908be5138cc0ee92953e2ef7de0455af425e8c5dcaac16b5e640892c56bf161ff1b94c16ff80bb0c3d6a876d072aeed92e4d4b1becfbee8b5c452d796b92ec452af4f8bc838e7b84dfdd80343983526d315622afdea80ab1ba296617556a993c9169f778c9d9e9256f4585e843fe550d1148d4d1a4891aa0fdff51a8f8914092a162f7959aa899fc3a0d105915bd88c05412fccff60504a0cafae00bb4880b6bd169316f9eb52835267f95c448cfd00dd1e409acc0cf2d7f5f6fdd1325f38adea4fd6f55af71c739ecdafe366dec44f3b544ae5c77c339e8fd5c7e06d28fa7207dd61518b3f327b35c6ab2b6e245fc4560770ddb18820826d95c743ffdce1b1a3af8a71c22beb5b5ef571ecab56373d182c20ccdcda91fc9a1b3bee03ee89cc38bf109cb0070c20d515f0b5339cc9060aabd23c2715f82a44bb10f2d956dd51f9c1d48dcd887b79723f9e7c61c87d61f1414d1ee1945f8defabccc0a4eddc2b5b02e2190d4510ec2b7ad404eeb28ad5a0c5eb838a35f39bf7fa91fc999445ccfa59391363ea6cd7ec389694eb4ecae97ca31524582f207dd120eecb0c6145885eee6bd39c8627c33916379a9d614c929adb64dd3fdb28c12b24d31b66919c4730cafd23fbd0266d471a2bd72b01cbe1649b56b4203c903b7c1e27fd00bdb8146632c2a5916ac678cae648192464082c747da12caf955033f4d942da3bd16690ced4653280abdcbe6ae6780a5512930d8adc6f7badde45a3426b78271bada4c28cbd4c5e5bb5ac958615ef129970ac13c376c7929d60ad1c629f8bab3c610649007dcfbfe6abfb66f4c4585082b1d9167a705cfc685f5fe5b17350e48b405e03a3d3d07f0ab0cedc961137e009b4ecdb9969f6ddbb92fc05bed560080d8450f7235b43ff79c9b460c29b2ffd0b67f4c437cbd8cc3badfe5a9feb3315c0aa6c9bfcb81c87547625038c804061e98346ff3633746cc571c3853ceff7a1842e0d2ddaeafd01f15758954ffac64ba46725acc1e30f6a5872fc090e47640cb4c804a59c55a5ed0316297a72f2bd4154f0452eeb785136f5d9befc4534b2ec2afd932c235c0c58f932aab15aa16f2cf7372633656c8623fab7291525e946550efe47eab479a1fc6c51132856ce09eecf36091892bb06f0f8ccc87f260c858873a4174ba1a64e1060a111efe1224c0b3d2c05e7d1282660b52e35c8f1a68a52cee6516e94b9746917d224c28f68ab4bb4a75a8b47ff343ea1056cf3116ac0660815bf0f6be1a6b98d713647d439c7e2511824026118a96b06c006d27454c3050f8bfbda087b3c7a8397383d652cc3b579fbeb309947773d6fbfdeda2940b7a0bbc2569b31dcac7dbfb8843b5a7bee26e63f734db3eb0773460d040238dbe757db9efb4ef872f781be75f357336b17bd84e2717db6fc23ab1a5c635a2dac389b3b6ff5bbad55711e807fcf207c80183f32efb5d47943bbccd96f5761c3861eb1ad3dc874cbfc5c25435c1a283c662cc13cd65ad6a807020dca215132f6a453ccf26ad4e8bf94dd0f6f8024c17729843d9f359609dd9b25e2a9b3c87622a751ace3ae47ac5675a3011c86d0ba3356ab8f9827bc726c956d11b4617010bdf90ddde46ab21423eb8ffe23da3cf551b23be964f9dbeb79297416ec4b3ac8e3dc7881aebed2a8c168e2c34316fcfff83602ff57cb99c18a71372d9f019fcea16abe0b6b7a27b02d99e2d67564986f122cae4205c0937bdd89a1de0cdb4fb71a4bcacc2a592b02be16e5d32ef4cddc4a52889c793dfe401135ca3baac0e1610f3bef47c89d411a53de275cb290b0715ed885bffe333a2df6bcd681ff0b47760306c0e379b07503e556a0f5313f7314c0d20f53cc41a75f07ef86720a42c88781ac6a968245fba509b43b67a42df8200981bcbee163c88d28b8dd1b70c61f0d558e0c5f827920d0b677e48915b99361dbb017e7df4cb5e2285557751b5dc2427cb7ff490b3f4566b3130b3c373fc877877149c8182c6e8c609eeb46bbc9e353d87cb8dd2fd59112b778881c30a87ee32618501767587e3bf64fbc7b8d801738bc9fb703fb8adeaa7699d4b227a588a4820dd4d07ecbead8910578c190465c14d7a1383b6ff1910017c3cf624b7a02dab9b2713084f45a7bac3d75012c3ea47cb39defc2009ea9fd083dd8b521e7df4c903bd39207ed5fa56c5dc594483e1531190bac65f348baa2159249546cebcf65155cc70b76013883af3df8ed1d8ae43da4cb26eab8d7e13a9ccbc1a8da5cd1026ef1bb5804169bcb25d6724775309414c7fd55d2fa219998a69a911a7e77e447fb12e3a2efea3265c728a0b14139436b50455669838f83463adb4ff0876285c5ce221ff704682f68949b2cce4749a6d442c6fe3a1fcf84e6714a764e19c383174b20f054c7f9488474ad2f8e572c566c1a33457f3ad24347e9f2517769c0a0842e3299b4b693492d5ac595654ced83e3b478676ea56dfc6a0430f356b6a5de1b473d5f9a6aaee5e4d31d1933340f42e09f245ac543fb2e2331f2c30847af524456563c0d9bc4190ab02ff510fcbcf5d8efb0f668587ef0023b0f4bdb193c4c73f7dbf1c7d662bb8e98fafb96bd9015c2b16b8fec91f764add9a57a5a5b25b4c9a836f95043b5fda20dff16e139c35922ce381d246f430036c79b32904979ed54ec4e08fc3fb006a62f90464b7fbbc18624e377710ba748782fc2ab80bb5133311d98a9d234601337b680073800c4408f44040629a3a0d2c6610a28367dd7ab59e43270ff10c3d29d945b01798d01169b13c061b4b60978df83702d7061bfefa1378b2ad3dda42a60179a5e3f080a3e1b8e36d9a689b1f41e039e39c500934d260bc1a51e0f6a87d5b65f65d2bc0bee3cb85adeffff9b0ae52a1bb80e1328a738964d91764fe1416a199b41603aa97fc63489238c6cd17c0d70a16c70118321cd1d3cd2536e40b782b40dc3c6f02d994a9a7270dad180345a48050119d96707c31159e12430a79b15330315c707e2d6843fef43e4454b1e033dd54ba498fe3dab1614aee2e290d971d4cf9d2043102231edeb6b703b4af5a23dc1dfd3f796c4916041aea90dff64d5c9cc9f6181ecd0843d6cc3d1767ee1d660929b953f8b4a51c9f10e90e1fb7dc1130877c46dc26b897e7c2b31cb868e38f9358d7997fc52335f530e41e33c\nresult = valid\nsalt = a1f3edc92da6733ed0c662ac5b9564525810e6", "4d87a2b317749f9eb4068f4df93b5e9bf1f5f2033b8e4cde8782738fb46c37aa1023399f29562033cb35b65ea2\nsize = 16320\n\n# tcId = 88\n# invalid output size\nikm = 38ec0b50e79a870ca225d1e78fdfb74b7fbde0891a16ed1b6e7ce8889d441fdd\ninfo = 9a6c71fc1588b2d2\nokm = \nresult = invalid\nsalt = 78865524949fc5a008997d85b1ce5d33054ea061d6ff5d7bf74c9d36b3502f0b6fc163101376b241024ee063e82d5826ff5395124a18504256544f922b7c1761\nsize = 16321\nflags = SizeTooLarge\n\n# tcId = 89\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 084332b8a0ab8635227a3b9ee0737072f021c21fbf0b087940939f34f685c0a0\nresult = valid\nsalt = \nsize = 32\nflags = EmptySalt\n\n# tcId = 90\n# output collision for different salts\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = 084332b8a0ab8635227a3b9ee0737072f021c21fbf0b087940939f34f685c0a0\nresult = valid\nsalt = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 91\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = d41d1d366b10f6dd7e886e5030ccd01ed14ed918407c84f12f8b9a2ed3a5841c\nresult = valid\nsalt = 0102c651e047fed9c217bcf915520532d44999534c1e7e7c87311093d7a3681aff3e2d335b3c6139b9fc66dcfe35573b36a329a550c4cd20bfe2a90dfea50167ff\nsize = 32\n\n# tcId = 92\n# a salt longer than the block size of the hash is equivalent to the hash of the\n# salt\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = dbbe9ebd37e2545d08d715013b50f31fd1f7089ebc2866191e49e774c537b17d\nresult = valid\nsalt = 1a57a60677a3c97fea6d4d6eabe0201452130c58eef435bb9cbc21eb65f1cf2c879639d10b9a580b1eda822aa5f406b939cea2ff9be10c56f0856709abf33a08\nsize = 32\n\n# tcId = 93\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed66\nsize = 32\n\n# tcId = 94\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000\nsize = 32\n\n# tcId = 95\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000\nsize = 32\n\n# tcId = 96\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 97\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed660000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 98\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed6600000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n# tcId = 99\n# a salt shorter than the block size is padded with zeros.\nikm = 2b54cba29681b6ff2feaa9202b87322d861aff8a8260e1bda68d61979e605b2d\ninfo = 1301b63168af5451377717f7f5ed52de36a197ff\nokm = f05091c6083c24742adbe5fbdf10a941783517d568e96dcc8cb55db90756d8c2\nresult = valid\nsalt = cd920e8dbf19ed66000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nsize = 32\n\n[keySize = 512]\n\n# tcId = 100\nikm = a75ce5b072311acdf290ceb4c6fd25eb6c52ecabc8ed1ffc698d7556d1132180e2888bbe6a798d891e0c8c5e0f79cabf3d27df56d472be152aae155b52d9a9f9\ninfo = 69d2aa66efec2cca\nokm = 8b025c9925f105898fe8f75da1839b683beb73e349dd08b79a3d80a7b29e7d9c1eebb5cf4c902371b31376e44d49ea39725ac912d5055c8638ce0771a8edc999\nresult = valid\nsalt = 8df18f4f797c4be88ca6b2935441a1100db080759c042a6d2c37d2e6fea9fd6fb066805c467b7557c78d078ae44dcb886e5e3d5f74a96bf6394aad36847ed8b7\nsize = 64\n\n# tcId = 101\nikm = 5be4b9756eff71ebe87fdb5933e5d88d51bcaf384cc289c16ec642d67f2e9236c04106e01ebe7956bac010e4107b6b788ed8b3916a39b59c7c01161cbc2671a7\ninfo = e496bea60a731eb7\nokm = 02487460b110121d3df3746d7860332b6d67d746f96ff8e7bcb2d62481b653dcf67903b25aabaf9031b370959105c9136536b52dab810cf041862e73d3352f77747814aee2d74cfa29840dbfbca242f38b95ea26d4a540edbdab3fbeced1c767d35a73b4c2ff180eee75b4ada9739b7bd8c75c3bb03589ab\nresult = valid\nsalt = 336a871d315b7d2ae0a0d24febebf0702d9f039ca97146cc0aa2341728824e83553e6eb166e954dac33e4d6a2437309d0980e26d1c7665ddc79b2e9ba3354262\nsize = 120\n\n# tcId = 102\nikm = 45102dd5f609c2f9352b91d8b492d83b5ab34976372b4ac814bf82cf0dc4f3875cd31dfd5897022458fc7bb8e5d2930a620909b7385ba4e48c8395b50d7d07fb\ninfo = cf6db9210ef18e3d\nokm = 146e59745a9d65fa6c98308b6f162566045d2f459a09eeb7ef7cf15e076fe8093fa202d15b12063e55d4b5ab4e80d58140b2664d944e33d8b2a72a3ac307ca51c23976adb1ff9ff04fd0fcbd21edea49890c12698b0600b3b70a61dd228542d47e69797122f0734c08d53f51afeccea785af1028b35e6ee911fa0d98f76e2aedc517f35d719c199b6a73aa867ad31253fc1c1d612ecc913b70c2f6b983fd50eccd8a20172052c8726ac6ecad97b8bc8770ba5fd59eec423160828fd8b1936a5ac5bbccfb6398cf46dc3e19df40d315091f2ae3df875334030418143e7b791cd1f732935482fdd585fba2f495973436138c7fc106058f9538b92f055ea3bbfec1\nresult = valid\nsalt = 76d1494d3631034558ac7108a69b79f7e38a45aa50783af41bf8c19531fdb30782e7689a50a4eb1391415ab2e6085b1e246ce0e6c35a5e02910c072a241cd8a0\nsize = 256\n\n", }; -static const size_t kLen128 = 30701; +static const size_t kLen182 = 30701; -static const char *kData128[] = { +static const char *kData182[] = { "# Imported from Wycheproof's hmac_sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HMACSHA1\n# Generator version: 0.8rc21\n\n[keySize = 160]\n[tagSize = 160]\n\n# tcId = 1\n# empty message\nkey = 06c0dcdc16ff81dce92807fa2c82b44d28ac178a\nmsg = \nresult = valid\ntag = 7d91d1b4748077b28911b4509762b6df24365810\n\n# tcId = 2\n# short message\nkey = 4cd64efdb76df5a85dce3d347012cad06b0c3db4\nmsg = 6c\nresult = valid\ntag = 6d3d37af55c75d872d2da07b9b907ba22ad487d4\n\n# tcId = 3\n# short message\nkey = 52e1995025297fe7b793dc8e1e4f7d312fee2700\nmsg = 29df\nresult = valid\ntag = 82cb24bfa38fbdc91d1eea2d2dc1ce6e60ff881e\n\n# tcId = 4\n# short message\nkey = f3edfa003d89c4e2a6422e77a01b8adbd7ac26e4\nmsg = b015b7\nresult = valid\ntag = cb244ca6ad233947378436076fbfd20c9c8b842b\n\n# tcId = 5\n# short message\nkey = 4b07ed4e0c8ddaa1f76cf0010728679c8857e18b\nmsg = 3b2c1afe\nresult = valid\ntag = 924125532e6b625e7c5a8dcd1614e04334c067cd\n\n# tcId = 6\n# short message\nkey = 7f532c8ec83cb21dc98af7734c64f5fd9167ec30\nmsg = a33c6f9826\nresult = valid\ntag = 0d25bc40f60fbed36d8d7a1045ffa60d88484d56\n\n# tcId = 7\n# short message\nkey = 99e60c1fc0cb3e6ed836619775e37bf15b2cb93f\nmsg = b129bb88ceaa\nresult = valid\ntag = 6924d833a3e74b48f991e6c44173565fdf8c7470\n\n# tcId = 8\n# short message\nkey = 53845f10344b7f39eddbd3e44231fa802d7e1aca\nmsg = c6f5b1cee31033\nresult = valid\ntag = fd4b28273d3ee8cc24de2d8dad23ad4f355240c7\n\n# tcId = 9\n# short message\nkey = e3220700ce24a010cf623f60891e4f298ff26b11\nmsg = c97afb5063a9dd0d\nresult = valid\ntag = 383b103ce9054cb74a0431d16da99d8233e94fc2\n\n# tcId = 10\n# short message\nkey = 466c061ddcf3d9b285a2900f8725971b733f850f\nmsg = 89024ceda7de3c114e\nresult = valid\ntag = 1b81f1127635233383b6ea5ba8fd68eb5112ef0a\n\n# tcId = 11\n# short message\nkey = a81f9f51b041ff29b8d705bb408f854ccbd7e5ab\nmsg = 032d866a270762cbae24\nresult = valid\ntag = b72ba0c89d010215a8f280616acbd8640fe86cec\n\n# tcId = 12\n# short message\nkey = e60d0b14886fe6fa2c839329204d84d81026b7ab\nmsg = fda7f48c11101255e02c8d\nresult = valid\ntag = 2be7bb541cede978f541e2cac0ab6451060e3e83\n\n# tcId = 13\n# short message\nkey = c090ef122a29348740ccd571d98407764b2adaac\nmsg = d1fe3dfa80ade7087efabb52\nresult = valid\ntag = e6c1e0c3ebb7750d66a50b6abccfdef9c2599008\n\n# tcId = 14\n# short message\nkey = 564a56290e1aea0522f19088a88ab4dce4c7cdf2\nmsg = 4213bd3cdaebbb1ec1cc81866a\nresult = valid\ntag = 6d1d5808c085ad512487debb57fb93514b205075\n\n# tcId = 15\n# short message\nkey = f898459d272fd5e43b062156f44958d85d97ea3f\nmsg = 5e86b05522eb65a4fb7b932cecd5\nresult = valid\ntag = b778f421c2d1e2701e75da6bd1bc65379b80e879\n\n# tcId = 16\n# short message\nkey = 7d5cc53f464e759438ee90b47f2fe67aa83d6b52\nmsg = 9f38ea80122b40f742a00c2e83e085\nresult = valid\ntag = c80ce6d33fe868432c262766fd23bf431e313882\n\n# tcId = 17\nkey = 33e9140175519b2f1619b44848331763c756fad4\nmsg = 7de0fccc83b51c29e5eb1b658c102438\nresult = valid\ntag = 34de6b8f479523870b8f905684672617669b0607\n\n# tcId = 18\nkey = 0ef29e7c961da37afaea8182f28738d22c340232\nmsg = 165bb8e5c6f0a3ae40946dc807aee84645\nresult = valid\ntag = 78e6fa53ec213e9019d47ee7529d963a8a252942\n\n# tcId = 19\nkey = 203cfad921e605c80d7aa8b64d3bf18328b7a7a0\nmsg = d289c7cd10d996d5daca1410c37815b237f74929588c5ae4\nresult = valid\ntag = 27d96da41895bf53d150ac15e7c31853f56ae363\n\n# tcId = 20\nkey = 8eb7416efd0c73c86b91df0d58891fdb738f40df\nmsg = b415cb7cd384a1035d2bac1f7b96ae858dfd44c467030f304e817d11b9f9c606\nresult = valid\ntag = 24cb16323b7ec47e3add8f55cb9920aa7c1655de\n\n# tcId = 21\n# long message\nkey = 6fbb3c55e935e0a002c170a9122f1f7037bc0c59\nmsg = 36ac9a8cf0223ccf5d9048be9a65df4a1f40aaa857ce13d621f601bdee1fbe803171002d1fa634a1977dc23d9aa8fd\nresult = valid\ntag = e2fe8b343cef4b9754308408930526159537ecc8\n\n# tcId = 22\n# long message\nkey = e40f6206105f7800a1f190602bb6dde8057c3a87\nmsg = 10463b771fa586c5ed5c1f6488d793299db40fdd4f3e53334ae3ff8e09e5a879da06eb46d210ee0af0c8251e6c07aa1d\nresult = valid\ntag = b5dfce5998d2e321800e0e42762e62ec7a81448f\n\n# tcId = 23\n# long message\nkey = f04cc641ff67aba4ac2d17e6a042b6ccf86ae1d2\nmsg = 73c179acc26ffd0710b6cb3f73570702c9c059bf685614bb0ba7973ab875ff882d9aeecea4ef452c8893224472cfa5b61c\nresult = valid\ntag = b7d1e63fae54638082a9cb58c69fac9efcbee174\n\n# tcId = 24\n# long message\nkey = f61c1a878550d27aa459b3016b31731b89630d36\nmsg = 82b378d40ca04ad478a980d7b46e56c9967bc4e110a7add8bcbda411c12de384f41324e9df888d81702ff2b9e8752986ba081363eacc2e396f6b5fb01bf842358f0145d569d34fb3b4e24ee9dc9103284d743c52ea8661504b2db42f221b6d49b605fde34aa555e33ab0a140f61f3cda\nresult = valid\ntag = e688199489c9d3938f2e33d7cb3fc81bad4ffb8c\n\n# tcId = 25\n# long message\nkey = 8c29eb661fb633087f2452d057f98d553d2846f1\nmsg = 021b968c4ce337595154d90e44229980f0e2b64776f562ea25b24881637b44375bde65e5f9418bf163e2aacd37bd10319729ac596615a35cb632e0ffc316936a68acf4c7ae3ad36026124cee6d204f10432f08157cc32c5f4bcadaee67bd42bbeb826a9e9c8af9f554f7419fb265338d22bae2190bb644b32fe9bb6a2287aa\nresult = valid\ntag = f940df33b09965a3118c847c2ae1591690d0405f\n\n# tcId = 26\n# long message\nkey = 6316298f3aadadc664eda2cedf17669bc80d44ae\nmsg = bab807df54c009610a5c3f1e81605f6bf7d76b299d7ebdefa70f5e2e0b979011d191ead39c3bbe5dd2658347eb172950a1e03a01552bb38add33bac832b7177a77b08eb11cc1afe3ae84daffe4c4e88bc441e54e4dcbae3e0d5639f635228d811f0a043b13d5c91899c26bce2da2ddabd21b2ee668a21b454928915d6585408d\nresult = valid\ntag = 23b9a6d6a9c7cef6dce537722f4557b65dcdde99\n\n# tcId = 27\n# long message\nkey = f291696bf4f9655a00c9a2382bd1487342358714\nmsg = 32a650b5307d94b23139be64d470ef1492d57ca7af98205bf9bce8854ba8f5204880b2e9d58ddbe2e7bb21e6e0673f5e1a39f505909227475e41c1d59c73a933b13f4b07a75cb9f3279cc3bf61a6c09e3b9f755907491b9e745bfda58ad4e2304ff7525b41507a51a2fd664a2ee98cea00148a3663d77c47beb055bd45e7df48f6a0ce66c0a2d9a848761a4575d195d74eef5bb78c0993557a25ad7ca32e0a96b2518d9d8a180f357402a44217f1e36a9138c0909faffd0e9a907048584bb03a4e06fc69c463f39542dd2c7c81467d3728481bbf6bb60259604aa33a2d4c6195012fdc7aec99e2175aeb2d0c1f680964d63ee11418cd4d26e77ec131108417\nresult = valid\ntag = 3346bf23e52231a4aed773fd73e58d918580ede5\n\n# tcId = 28\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e8ad50fc1035823661d979e2968968cecd03d9\n\n# tcId = 29\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5641600cedd7e12063deaea0788785f56113520\n\n# tcId = 30\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 04e8ad50fc1035823661d979e2968968cecd03d9\n\n# tcId = 31\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e6641600cedd7e12063deaea0788785f56113520\n\n# tcId = 32\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 86e8ad50fc1035823661d979e2968968cecd03d9\n\n# tcId = 33\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 64641600cedd7e12063deaea0788785f56113520\n\n# tcId = 34\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e9ad50fc1035823661d979e2968968cecd03d9\n\n# tcId = 35\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4651600cedd7e12063deaea0788785f56113520\n\n# tcId = 36\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8add0fc1035823661d979e2968968cecd03d9\n\n# tcId = 37\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641680cedd7e12063deaea0788785f56113520\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fd1035823661d979e2968968cecd03d9\n\n# tcId = 39\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cfdd7e12063deaea0788785f56113520\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fe1035823661d979e2968968cecd03d9\n", "\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600ccdd7e12063deaea0788785f56113520\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035023661d979e2968968cecd03d9\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e92063deaea0788785f56113520\n\n# tcId = 44\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823761d979e2968968cecd03d9\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12073deaea0788785f56113520\n\n# tcId = 46\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc103582b661d979e2968968cecd03d9\n\n# tcId = 47\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12863deaea0788785f56113520\n\n# tcId = 48\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823641d979e2968968cecd03d9\n\n# tcId = 49\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12061deaea0788785f56113520\n\n# tcId = 50\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d879e2968968cecd03d9\n\n# tcId = 51\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063debea0788785f56113520\n\n# tcId = 52\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e3968968cecd03d9\n\n# tcId = 53\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0688785f56113520\n\n# tcId = 54\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e0968968cecd03d9\n\n# tcId = 55\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0588785f56113520\n\n# tcId = 56\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d97962968968cecd03d9\n\n# tcId = 57\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea8788785f56113520\n\n# tcId = 58\n# Flipped bit 152 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e2968968cecd03d8\n\n# tcId = 59\n# Flipped bit 152 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0788785f56113521\n\n# tcId = 60\n# Flipped bit 153 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e2968968cecd03db\n\n# tcId = 61\n# Flipped bit 153 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0788785f56113522\n\n# tcId = 62\n# Flipped bit 158 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e2968968cecd0399\n\n# tcId = 63\n# Flipped bit 158 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0788785f56113560\n\n# tcId = 64\n# Flipped bit 159 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823661d979e2968968cecd0359\n\n# tcId = 65\n# Flipped bit 159 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063deaea0788785f561135a0\n\n# tcId = 66\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e8ad50fc1035823761d979e2968968cecd03d9\n\n# tcId = 67\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5641600cedd7e12073deaea0788785f56113520\n\n# tcId = 68\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8add0fc1035023661d979e2968968cecd03d9\n\n# tcId = 69\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641680cedd7e92063deaea0788785f56113520\n\n# tcId = 70\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035023661d979e29689e8cecd03d9\n\n# tcId = 71\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e92063deaea078878df56113520\n\n# tcId = 72\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = f91752af03efca7dc99e26861d6976973132fc26\n\n# tcId = 73\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 1b9be9ff312281edf9c21515f87787a0a9eecadf\n\n# tcId = 74\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 0000000000000000000000000000000000000000\n\n# tcId = 75\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0000000000000000000000000000000000000000\n\n# tcId = 76\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 77\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 78\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 86682dd07c90b502b6e159f9621609e84e4d8359\n\n# tcId = 79\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 64e496804e5dfe9286bd6a6a8708f8dfd691b5a0\n\n# tcId = 80\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e9ac51fd1134833760d878e3978869cfcc02d8\n\n# tcId = 81\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5651701cfdc7f13073cebeb0689795e57103421\n\n[keySize = 160]\n[tagSize = 80]\n\n# tcId = 82\n# empty message\nkey = 5ece0769742feabb6644469c9b264326b3deb126\nmsg = \nresult = valid\ntag = 344f8351f1d2773cae9e\n\n# tcId = 83\n# short message\nkey = 4ee9f9a93b2ddfe551281b397ccef844fc21af3a\nmsg = 2d\nresult = valid\ntag = 3aab1a2c9a2f2b8ac840\n\n# tcId = 84\n# short message\nkey = dfeebe9a5c181afc605ff63b22bf349ebdb6c7fb\nmsg = a5f3\nresult = valid\ntag = c3b7152230dacae4ef48\n\n# tcId = 85\n# short message\nkey = c5147ecd59b7d42315d5e3a55ec8b3a320c8d615\nmsg = 371777\nresult = valid\ntag = 0abb78a2c67c565f89b1\n\n# tcId = 86\n# short message\nkey = db0da5659ba69ce195a69524508e437c688f7147\nmsg = 4ef4ec44\nresult = valid\ntag = 4062faeb0b406698b740\n\n# tcId = 87\n# short message\nkey = 495d6c1191852ecaf0573e6a77610c32acf5a117\nmsg = 1566ae63ce\nresult = valid\ntag = 45cbefcd9c7eeee37ae5\n\n# tcId = 88\n# short message\nkey = e5cfe7dc67514c4c75d28bb805d0700bdea0d669\nmsg = af1a6b15b622\nresult = valid\ntag = e867269d506a37e8a62d\n\n# tcId = 89\n# short message\nkey = cf1b8b902512186e38c38165d6e587bceecae87f\nmsg = a59512152c7221\nresult = valid\ntag = 1a125b21412cdc596894\n\n# tcId = 90\n# short ", "message\nkey = d0157fb40c7739ae506aad7de60f32ccc3325583\nmsg = 1292df8d53d16f3c\nresult = valid\ntag = 9224f11bff0e49b9aa95\n\n# tcId = 91\n# short message\nkey = fd55b81edd55a15bff409129e9930f1ba1763c33\nmsg = 05220a6997533c699b\nresult = valid\ntag = 3b2d07dc8ca206ba16c4\n\n# tcId = 92\n# short message\nkey = 079937cf3bd42864d5b15c62bdd92f275597316d\nmsg = 5ac13ce1b1f77724e281\nresult = valid\ntag = 0c24afcdadd8538977b1\n\n# tcId = 93\n# short message\nkey = 545b13e1f39f0b7ca9252bc596277278166ad410\nmsg = 08a7bc90732d54381b6e30\nresult = valid\ntag = 9bf7f121365a82c2ac69\n\n# tcId = 94\n# short message\nkey = 25385e9f89b66098ee8162aeca03bb45b313561f\nmsg = bff236aad71fb5daf7fc43b8\nresult = valid\ntag = 44db86e7a1476226dd86\n\n# tcId = 95\n# short message\nkey = 9b68139d93a88fe34cf9f83006c03b3164b60468\nmsg = ad672b9719c10863fd6fa8db88\nresult = valid\ntag = 2d17a88d87aae7dbaced\n\n# tcId = 96\n# short message\nkey = c3b785915e137544dac542cb4bdb16d53036fb11\nmsg = f8c1edb469b93c073b6f6bf74cca\nresult = valid\ntag = 16713d61fbb4149f500b\n\n# tcId = 97\n# short message\nkey = da67475185b3615055f971819db27871b23c75d0\nmsg = a176533319bee5e43d8f0eafb77bb3\nresult = valid\ntag = fceece892852d4a26070\n\n# tcId = 98\nkey = 0cf146ca7a254db1e001a29ad03c5e6dcbe7140a\nmsg = a83df5d099854eb6ead7031c51460357\nresult = valid\ntag = 9bcf7513206e27a4697d\n\n# tcId = 99\nkey = e038dff028227dc4b4d7453db3070108465dd5b2\nmsg = 7ae4e30834db449e4244a9fc0322193e7a\nresult = valid\ntag = 9aa8544a9afdd920c0f2\n\n# tcId = 100\nkey = b399fcfd1ad32140879aa0556ac34d8b5ac267f2\nmsg = 0e3f0fc5cb1456fede99f86a056f640b8f5e5e1b612f25f6\nresult = valid\ntag = fa095c6faed0f086b215\n\n# tcId = 101\nkey = 2bf7d201ef44241a22ae4b81aab910d22c2db918\nmsg = aa0afaf3af36548227349adcfcb6bf998a7fa78d29b87a0f50609c42edcdb3dd\nresult = valid\ntag = 708ec45d410b1fe075c8\n\n# tcId = 102\n# long message\nkey = 48ccc3907c3612a18294fddf2660e33d9cb787fc\nmsg = edbb680243a825068eefe5ba184e5eed4b7f85ca3b511a42d655be3e05d8ff124541b3d56a10a35cff8da8b6229ac1\nresult = valid\ntag = 3cb7fce20df8385cf6bb\n\n# tcId = 103\n# long message\nkey = 227d796b7867409db3de1ffa3cfe376704044f01\nmsg = b6393ab18376c025e2d8e00ca774a51aec19dc4a89cf6a9f8fc4aba81d73b3907efef1a0d018a53cb8b8ca1032e31583\nresult = valid\ntag = 525387c81c2ab67aca74\n\n# tcId = 104\n# long message\nkey = 5718e700c48a7971350d8a11b37754ae55a9aad2\nmsg = cc95286e9b3ca936191aff8731e6a17806a0958b0b1a39977c46395240641e97d5395a9c8a9d36281eba825a94e8b1ad79\nresult = valid\ntag = e54782110d40efb54343\n\n# tcId = 105\n# long message\nkey = f56aa792795eb03ae0990440714ab16cc4ad18c3\nmsg = 7a024d995addd38d967bc3b41641738b69897d8c52b7aff961a700cb68fa7481da0a3690a151ce09c95b4da60f7cf28990017292893bbb2f81a4dda45fe8639877ac5abaebbe00c1fd179eaaf7dfb4d50929371b9ab8b7d3531a63ab188d7b99160060475c33e83351f65d5e329ee8bf\nresult = valid\ntag = 1e2205d17ad4de3f1ec1\n\n# tcId = 106\n# long message\nkey = 00be0034d32699b1335d8d4e506235ee4f07bef6\nmsg = 639e828d88bf0642be0a541b1c3fca07609eb98d23a8b2cd4e60e139515e4ff440dfda1bc19392feffed74164d6a9d8f5bafe53fd397cb5ee1dcdf9bfc86169f1bc38ba57f88d7e8c6728c35fc07128ab6c396bb3ef3c14d13a05f8c3453353e850dc1b291ac7061ab52f121663f18b024e5cc0068328c88f52c20cd21793a\nresult = valid\ntag = 6e98973d3a775ac508e7\n\n# tcId = 107\n# long message\nkey = c5baa750a8424450f1b4d453c58e29c462e52639\nmsg = 137c7227a192bed26d08da886430f010094243b5c4686e6831e48db450045aa1d7e3aecf193eaaa1a73905f5f1190659a43ed4d10bfca5668ebeb343b21ff71d0737f81f67392b6459aa95f9441f699bf45fee24867a98a8a6c57f972abe3e400fd64ce3e5b48622a0e99e08d424250fa00ed0dfa1193f936c78af276a4b442b\nresult = valid\ntag = 490dfd2d5e6ea130f6a1\n\n# tcId = 108\n# long message\nkey = 6bd486ce934c2f5fe38a19423d257bc5d808e367\nmsg = b8a684ada0a01405614b1fa66ebab8b0356e33b889b81b3eb68d13b05c4e60c724785e634c4ec0081cc6bbdf213db7254f92c0a858bfcc3d63a4e4dfd9e75bd4839ac05751c23cb59945f4c3660d2b3009f5b08a596bdc33070244bceea11180ac0906404518b09d5d8612e0d8e69f4b9e55bbc053b56574711b02956db3f3bd8f6c42065871255854a161e57100adb82cba79893aad715dc3df1488b3edb56e58b89c0be3cfab09a3df40524d2d3251b0fcf7faabfc75f50026795060c1d62872574a769e3da0e19af1b5e25514ae17a160c8d1eb253c9f66ec3df789ec0c6c704a9e2fe8ef7e9bf8e8164f86d09d2a23698733a8e40a279cd5fe02c295ff\nresult = valid\ntag = a594d26d98b53b4063b2\n\n# tcId = 109\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e8ad50fc1035823661\n\n# tcId = 110\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5641600cedd7e12063d\n\n# tcId = 111\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 04e8ad50fc1035823661\n\n# tcId = 112\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e6641600cedd7e12063d\n\n# tcId = 113\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 86e8ad50fc1035823661\n\n# tcId = 114\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 64641600cedd7e12063d\n\n# tcId = 115\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e9ad50fc1035823661\n\n# tcId = 116\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4651600cedd7e12063d\n\n# tcId = 117\n# Flipped bit 16 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ac50fc1035823661\n\n# tcId = 118\n# Flipped bit 16 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641700cedd7e12063d\n\n# tcId = 119\n# Flipped bit 17 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8af50fc1035823661\n\n# tcId = 120\n# Flipped bit 17 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641400cedd7e12063d\n\n# tcId = 121\n# Flipped bit 23 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e82d50fc1035823661\n\n# tcId = 122\n# Flipped bit 23 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4649600cedd7e12063d\n\n# tcId = 123\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8add0fc1035823661\n\n# tcId = 124\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641680cedd7e12063d\n\n# tcId = 125\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fd1035823661\n\n# tcId = 126\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cfdd7e12063d\n\n# tcId = 127\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fe1035823661\n\n# tcId = 128\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600ccdd7e12063d\n\n# tcId = 129\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035023661\n\n# tcId = 130\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e92063d\n\n# tcId = 131\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823761\n\n# tcId = 132\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12073d\n\n# tcId = 133\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc103582b661\n\n# tcId = 134\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12863d\n\n# tcId = 135\n# Flipped bit 72 in tag\nkey = 000102030405060708", "090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823660\n\n# tcId = 136\n# Flipped bit 72 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063c\n\n# tcId = 137\n# Flipped bit 73 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823663\n\n# tcId = 138\n# Flipped bit 73 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12063f\n\n# tcId = 139\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823641\n\n# tcId = 140\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12061d\n\n# tcId = 141\n# Flipped bit 78 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc1035823621\n\n# tcId = 142\n# Flipped bit 78 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e12067d\n\n# tcId = 143\n# Flipped bit 79 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8ad50fc10358236e1\n\n# tcId = 144\n# Flipped bit 79 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641600cedd7e1206bd\n\n# tcId = 145\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e8ad50fc1035823761\n\n# tcId = 146\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5641600cedd7e12073d\n\n# tcId = 147\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 06e8add0fc1035023661\n\n# tcId = 148\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e4641680cedd7e92063d\n\n# tcId = 149\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = f91752af03efca7dc99e\n\n# tcId = 150\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 1b9be9ff312281edf9c2\n\n# tcId = 151\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 00000000000000000000\n\n# tcId = 152\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 00000000000000000000\n\n# tcId = 153\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = ffffffffffffffffffff\n\n# tcId = 154\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffff\n\n# tcId = 155\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 86682dd07c90b502b6e1\n\n# tcId = 156\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 64e496804e5dfe9286bd\n\n# tcId = 157\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = \nresult = invalid\ntag = 07e9ac51fd1134833760\n\n# tcId = 158\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = e5651701cfdc7f13073c\n\n[keySize = 80]\n[tagSize = 160]\n\n# tcId = 159\n# short key\nkey = 1d9535a0daea9dfe443a\nmsg = \nresult = valid\ntag = 7436089fede3291c0c421c9ad13c357ec8660bae\n\n# tcId = 160\n# short key\nkey = f5c2c420c6f056467fca\nmsg = bc8a29f52e57581cb89a86e5d644a14d\nresult = valid\ntag = 1eb76df7235c52371d86113f5423628b2eb7c3d5\n\n# tcId = 161\n# short key\nkey = e59b0276e27a0abc75f1\nmsg = 061ca1a1af51c5133728c414f9646b3f50223e9b2055707032e754dc1d31964b\nresult = valid\ntag = 2081260f65316df2956aac723a9bd7d2225a8669\n\n[keySize = 80]\n[tagSize = 80]\n\n# tcId = 162\n# short key\nkey = b18aba1171cc2ffc7d58\nmsg = \nresult = valid\ntag = deeb3d6d81e33d1cad21\n\n# tcId = 163\n# short key\nkey = 23082066e8c45da82fc6\nmsg = 06c19c6ee4d2f015769f6d46eb46d6b4\nresult = valid\ntag = 747cd928e8831917c855\n\n# tcId = 164\n# short key\nkey = a6fa1e04df38a78667eb\nmsg = 51a4ea38e5566d6fd803aec5e073e087e9ae00d37d4a98d559074ebffc7658b7\nresult = valid\ntag = ec8c200c1ddad6d3aad0\n\n[keySize = 520]\n[tagSize = 160]\n\n# tcId = 165\n# long key\nkey = ab92e2cd40e00b40c4442dd7671c067c7792af28e60f2585e87f163bf3bdfca7f553cec71b0065025500c48e2070984ad9e24e733107ebfde27164a4828981ac20\nmsg = \nresult = valid\ntag = 7a29b47ff6ae90c99573d8c922a23e83a62b66bc\n\n# tcId = 166\n# long key\nkey = 3b47a5d5b72babe116e61919600cb980c904c298ab91fae3db9c82b0f38a18888bc05a418d65d68f8850937559bb37325bce04d0e5d175a24fea309895f5705ad7\nmsg = d71862028fcaf13422bf32ac0c5f079b\nresult = valid\ntag = 8019231e77aca645182670cadf887afd4b4115a7\n\n# tcId = 167\n# long key\nkey = 6e6c43df9bb6c6b8fe414a183e738508f0aca41d5beef6df1b260c39e1979b54683622a4d53354231bef6c35e129f85f822ba09198aa30c65ee60e4202de8cd102\nmsg = 98f0a4b9a36e173d89730a3b370777c499b4cff2846f50bfb88fbbbc547cbae4\nresult = valid\ntag = d1653c90fc591e3a3c285a3be8b12ca9b2121e88\n\n[keySize = 520]\n[tagSize = 80]\n\n# tcId = 168\n# long key\nkey = 4f00fd17ae82a6252ada98280bbd895d743fc4c20bc9e615d8a786c79e454c2b1341e24254fa0371fac86e7c0ef1a7df5c16f3b3569fda112cca8685faecbb8923\nmsg = \nresult = valid\ntag = 6802ca52be056d66b9a0\n\n# tcId = 169\n# long key\nkey = d22ec568909990c213679f7072eaf19763508ebde6962c75e7429c5f2454d4b5472811eea8e02fdc89ec386bc6f41d2ad8a91d116b2cbc52b80d357127d1555a66\nmsg = f71b43e0cc64b5409e6501ca55a8d450\nresult = valid\ntag = d492a296860cc5a89c5f\n\n# tcId = 170\n# long key\nkey = bcf6ad6e5c7e2200299ea8602efb42b409292346f78a0e57a789ba17b17ed608e88497e2bb4ebbbb3ce7750d222b3bdf848d4dc8d49b5b60378fb93ce3f66ab4eb\nmsg = 586f5ddbc372c0711b77e4b87d345d62b6de55a1ce6fa18de3346c86be5cec6e\nresult = valid\ntag = 1de9aefcc53130245a6e\n\n", }; -static const size_t kLen129 = 35704; +static const size_t kLen183 = 35704; -static const char *kData129[] = { +static const char *kData183[] = { "# Imported from Wycheproof's hmac_sha224_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HMACSHA224\n# Generator version: 0.8rc21\n\n[keySize = 224]\n[tagSize = 224]\n\n# tcId = 1\n# empty message\nkey = 7eef1e40253350eb9307cc6bd8ab8df434bc2faf7095e45b50ffdd64\nmsg = \nresult = valid\ntag = 45b466021214d19245506900532f5272f44b5ad9b3d829f0f5c2108c\n\n# tcId = 2\n# short message\nkey = 8648ee936c6ebc5ae4bb48c1139a54e3ac5d897beec492dc4d740752\nmsg = 2e\nresult = valid\ntag = 5b72e3208679e63f929e6ee19a257d0555f21484c7caac7c9861be43\n\n# tcId = 3\n# short message\nkey = 2297d78cc45faf9b885b36ac80205cc08e1b730f264f23f4edbbb406\nmsg = 329f\nresult = valid\ntag = 2e7a81c4e29a435d91e95f37fb0a62fbe9a69e061f416c1ad17a7fca\n\n# tcId = 4\n# short message\nkey = 0361a904f7cbd107a617614ab69d11208ee6d423b3ae90e2bb6d7e54\nmsg = e6e765\nresult = valid\ntag = bbfa7ff960931e2f5ed8c925cd74272990e755f31422e5c858995b73\n\n# tcId = 5\n# short message\nkey = 264a8d2128e8fd0972d9acc66dc275b1286beeb0aff7ce8e97c7b96c\nmsg = 25838e50\nresult = valid\ntag = b25c33bba1a91024f42cfb93232ad685d54be2ca310b0ff9ba5107b8\n\n# tcId = 6\n# short message\nkey = 6dde8828f09b7aa981082aa116fca3b7341721c0440803f52cc9732e\nmsg = be81602da7\nresult = valid\ntag = e510fbf14bd7301f751cc0ae89f8725a7654ebbba6bb2f741626471d\n\n# tcId = 7\n# short message\nkey = 3ba156ffdc55d155bd085105aca64d13044db60c82cf2cd9d61d098f\nmsg = 69c76c8937a0\nresult = valid\ntag = a9d38740245038d9c23cbb59ba6513f7034d8047a07a904a2a23d2fc\n\n# tcId = 8\n# short message\nkey = 9c2739bae2a863fb0236466ba3408f4eec8d43206d56bb7aa2f8f75e\nmsg = aaf4c9146db948\nresult = valid\ntag = 2110393c6ba01f53be203533fbc5471fc8f04940fe912411564ba36e\n\n# tcId = 9\n# short message\nkey = 31d9cae2c3df064018209b121f9e883976ea757942ecda9d92fdadfd\nmsg = b844289529206f5a\nresult = valid\ntag = 1f1ddb8680b0d99893c498a772a7bea63c2e08c0257a7f31e3db2b88\n\n# tcId = 10\n# short message\nkey = 89a1b9e9004444c1d4e967570c21a05512d3f618ec168fc3e13ea5a2\nmsg = 6b42eb6d84e90c70c2\nresult = valid\ntag = 3b6f3b09e03424c8adc267fccefaf614db6d74977754fcad8a8d1a9b\n\n# tcId = 11\n# short message\nkey = 4398731752fd7af1db86ebccbee0ad65eb5faf00ace6c9aa35441faa\nmsg = 1ae2e7d917c48026570d\nresult = valid\ntag = 5f1948336953337c381d449c17ab5c327c86121a8b1e0db19f624e3f\n\n# tcId = 12\n# short message\nkey = 339460d6bb26ca60ebcef10c38587b9e575c398491782ccf9e8f6803\nmsg = ca03eb4f37536b2377738e\nresult = valid\ntag = 51c5661c31fc7edd09de60c91957036824a19761bcc54f1e93c43c3c\n\n# tcId = 13\n# short message\nkey = 025f8380d10b8207b3623e4a90f79c3e753b1be6a35b88b68330a40c\nmsg = e57daef9ede4e915c3a9eece\nresult = valid\ntag = 8afdb371714e9d6063ec9e43c8cd55e1c032b2fda57f91e9ec0f6601\n\n# tcId = 14\n# short message\nkey = 0bdc5f51f8a1a35d75554be70efbcdf51e54f30fa4696f727431941f\nmsg = cc3dd1eb0690f7af09ad408f9c\nresult = valid\ntag = c0918951c3422b48502635b6e58c5dcee9fea51c9dce5c7c215c9b93\n\n# tcId = 15\n# short message\nkey = 5ada97d90a74a7d4a68c5464fff25a9b7fa2e75d6acf0a59f143a2e9\nmsg = 3fe4ede158af108e09f543e14ab7\nresult = valid\ntag = 180a6b8814ae34228ae9ac76da8379376aae6f1aa0102e8f06b022dc\n\n# tcId = 16\n# short message\nkey = 007afe6b7c0701c30cb76b431afa3510c8b31d21cfe0bbaa5289cd08\nmsg = c2cf80005c591c1f737369fcc212f0\nresult = valid\ntag = fbfdb450a42f9a4154146f73c590a0ee9187af8505d60790a9615447\n\n# tcId = 17\nkey = 26491168a32ce8cbc4c0cd64107e4fcc432f07d59c992862e1e55b1e\nmsg = 15e51091b4f424ba1fdecb5e2fba11f6\nresult = valid\ntag = 3fa99ee160328fddc47a7c5043e9ef645b8b07462b71cad58a024517\n\n# tcId = 18\nkey = 6978b6c134dd6949832d65e4cb9c1e1dc36beae4a134907c80da0f44\nmsg = 6641d834b3fbfdb5d178007801f7b4e7b1\nresult = valid\ntag = 61387230446f31fde8552f22ec52a7fef82e16d0ad399de939d8229b\n\n# tcId = 19\nkey = 9f9fb280adf12e739548b1d676cb794d685b9104e63b619b055cb60f\nmsg = 91513dd6de40a1c23f8d1eb0ab8f5ea6f6835506ec750894\nresult = valid\ntag = e6b92f9c030270897c5d27162a5d40f6d373ff136105d1a90e0f9a60\n\n# tcId = 20\nkey = 3b1b16e6dd2e69559dbeb964e10fc94c068471b2374d3a2d24d2d466\nmsg = 8ecd55b56c668dcb8e8b1efd699c0e4a464204d29af140f87d3f5075495378a3\nresult = valid\ntag = 175856b8f56a8c6fbebc36541771545046bb416254f01ff11a218d2e\n\n# tcId = 21\n# long message\nkey = fc296398845063e661bdf36ff3615926eaccbf06947cd31e6677f710\nmsg = 62bd0ad75d64c554cb2cc109c6e4019fc601c61cabdf99f8de871edc17a301b4c1f55a15ed66f91eb4666dd08bc59c\nresult = valid\ntag = b7cf741cf96d6bf57d216c43611c20869ca0d008a4542f5c850605bc\n\n# tcId = 22\n# long message\nkey = 6c98d1feafff9861351966bc6ed19ed467f9dc767fa0df6b56955554\nmsg = e99d51a1d9a25c5842501a5383133578c8debe501581b1610f7575519bbd26f01ab7cbe069bfd5df3699a2fea5b461a3\nresult = valid\ntag = 0fe64fdd912966a6542069a22bfd084b484c015cf434d86bca15cdb6\n\n# tcId = 23\n# long message\nkey = 42a164f94e33d574118e0f8c938bbc2874bab219ee7a179f21e13b02\nmsg = e895639631f8b5d48e3ce00eb310bf129976ffced96a6f30a09d6ac1c291f73e93690526d86cc4d1a8e21c11f5a8979308\nresult = valid\ntag = 1ea982226e8d4cb7b07922158e535af2233b4c4d39d26b062d6d2aae\n\n# tcId = 24\n# long message\nkey = c1b5b91210667e72aa510346e1811358815a3330c5ed27a695c39451\nmsg = bf1086c3ea8b8840418c690c92152c73a6730bd1a0210c8b1d25c43a2193e739684f04a25a52cc305599f22ba6f70c8ed00d10b914a9522a25e06c471ebca2ff1bb4fa6799b85122020978dfa66ef12ed26ad38331b26eaf591afceac96d8c771eae50fb7f46242337dd0029f4813b53\nresult = valid\ntag = 4f355edbe6a3c93fa7add384be899bb4fb55385a78812a26cb64e44f\n\n# tcId = 25\n# long message\nkey = 4f09d14d40e475b68288c080668ebb1bc8c6be3191f6664d91a23fcd\nmsg = ae8b6ecc219b368d22fb596e42652d0bffee0b20d69cfd089ce3dc9303ba2f054ccaf5f5147c7968a028b140f5e3c9274eae2afc61c3bb6298dc598df77dec1cd2dd84212693b082b8132ad0f0b19f66db69fa7f6bf352b4feac724ce048440d2a42b44d53bb62fe2ab25f7f54bedf9ce7ddafd8e09330dacc6d52ee9b65f5\nresult = valid\ntag = 29ba268103019e158a35614c80780fda3f5ec3fc32c80aaa27b4025d\n\n# tcId = 26\n# long message\nkey = 613f414cd94130bb8a6243e12eccd90836808428b4a7177867934da0\nmsg = f696b9063b64816a45064f48ca05ffe4d5cc3d0b3beb0dd4057b6ada994969bf039bfbb72ce197101cc4e4b3959b3702f045afb7fb3113c997606dcaf2aaab31e02ac6ee597dfc0f9143d0effedc9ae7ea10e7ddb1db860a91afec62c48ed9c0a6c10b4da1de748caf7f7a5e01799ac57090daf4e3352fe859c5131c205d262d\nresult = valid\ntag = 8129e2093070168a20899793a04447a7ef01ae723419256a8cb42f6d\n\n# tcId = 27\n# long message\nkey = 5b88275307aaf691a0cf0c51f50553dda972d14f8afff98e62c2d972\nmsg = 57e4efbde1ce9fee2e29db19dfc6ba3bcb17f33765af7f20133bbd1910d542145c7def187a304517b8d8954454a90a717f67f9c8cc587965fd9b43f41ecc50b3458d8ce9f66b475f1eaef4a29ba89a3d58e5011c92acd1536fcd18abec29411b389b64f7f344777ed6deae32127abaa69a50ba22a11d6e59354f2ff0e3c3e3293cdc335411cf55b180bab59da36903a6fba91df34d2aadf7017ff49a4fbd73c9c74469f225dafc0a0c7048c2b824cc0cba8cad8aced11b8cdac3243cdb5b654f7a15ce2014e92ee287d06904d778512a1b1f5ec0c9b090b9ab439c44266b6be3d6a98947d26d079e4f7e849f3c6d93de98624e6c5f53ec02dbd368bc24a300\nresult = valid\ntag = 657dd04b970219edd63abf9d4aa108474aa316b6bb66bca76ed806c6\n\n# tcId = 28\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6f99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 29\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 30\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6c99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 31\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0f216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 32\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ee99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 33\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 8d216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 34\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = inva", "lid\ntag = 6e98e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 35\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d206faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 36\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e8e2e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 37\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216f2edf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e432e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 39\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faede3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e732e8936d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedd3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8136d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf30534d51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 44\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936c78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd50fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 46\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e893ed78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 47\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cdd1fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 48\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d58b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 49\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51dcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 50\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b4f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 51\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcae417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 52\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02809b130ab09806b2af02f7cb9d39d12\n\n# tcId = 53\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417322c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 54\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02b09b130ab09806b2af02f7cb9d39d12\n\n# tcId = 55\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417022c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 56\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f0a909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 57\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf41f222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 58\n# Flipped bit 216 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d13\n\n# tcId = 59\n# Flipped bit 216 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d88b\n\n# tcId = 60\n# Flipped bit 217 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d10\n\n# tcId = 61\n# Flipped bit 217 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d888\n\n# tcId = 62\n# Flipped bit 222 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d52\n\n# tcId = 63\n# Flipped bit 222 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d8ca\n\n# tcId = 64\n# Flipped bit 223 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02909b130ab09806b2af02f7cb9d39d92\n\n# tcId = 65\n# Flipped bit 223 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417222c8f144abd5f2f7fa00ab4667d80a\n\n# tcId = 66\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6f99e862e532e8936c78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 67\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c216faedf3053cd50fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 68\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e8e2e532e8136d78b5f02909b130ab09806b2af02f7cb9d39d12\n\n# tcId = 69\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216f2edf30534d51fcaf417222c8f144abd5f2f7fa00ab4667d88a\n\n# tcId = 70\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8136d78b5f02909b1b0ab09806b2af02f7cb9d39d12\n\n# tcId = 71\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf30534d51fcaf417222c87144abd5f2f7fa00ab4667d88a\n\n# tcId = 72\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 9166179d1acd176c92874a0fd6f64ecf54f67f94d50fd083462c62ed\n\n# tcId = 73\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f2de905120cfac32ae0350be8ddd370ebb542a0d0805ff54b9982775\n\n# tcId = 74\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag =", " 00000000000000000000000000000000000000000000000000000000\n\n# tcId = 75\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 00000000000000000000000000000000000000000000000000000000\n\n# tcId = 76\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 77\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 78\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ee1968e265b26813edf83570a98931b02b8900ebaa70affc39531d92\n\n# tcId = 79\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 8da1ef2e5fb0d34dd17c2fc1f2a24871c42b5572777a802bc6e7580a\n\n# tcId = 80\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6f98e963e433e9926c79b4f12808b031aa08816a2bf12e7db8d29c13\n\n# tcId = 81\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c206eafde3152cc50fdae407323c9f045aad4f3f6fb01aa4766d98b\n\n[keySize = 224]\n[tagSize = 112]\n\n# tcId = 82\n# empty message\nkey = 26f314170b054daef5349804da18f969c94174baca2beeb009d47a23\nmsg = \nresult = valid\ntag = 816d7af2475e94713f2dc3aa3069\n\n# tcId = 83\n# short message\nkey = 17429a622dc18d38715b31f8f2b963108e952a6708f3e52d5b25848a\nmsg = da\nresult = valid\ntag = 26630777d85f777187630bb94674\n\n# tcId = 84\n# short message\nkey = 0acfe12d89acd7d9ca49bae6318f35b2fbbfc84e5d2c9d4954beded7\nmsg = 03a8\nresult = valid\ntag = aa4c4bb63cad66ac675150f718b2\n\n# tcId = 85\n# short message\nkey = 5a0680f112354bd467865b19ae956b2719e21ecee1a913bdca294339\nmsg = a0fb73\nresult = valid\ntag = 36c7cd3f290d1d7d332b951aa471\n\n# tcId = 86\n# short message\nkey = 46fa59aa524fe30a0f4e39561b5666854440dbd970bb59925ce0ae1a\nmsg = c8b2f557\nresult = valid\ntag = c1a8a7d43df34d917f0cb512c57d\n\n# tcId = 87\n# short message\nkey = 29efc5ab5d30e535357603f2711b6e0aa6cf4613546c23144436d213\nmsg = c8d9f5b373\nresult = valid\ntag = a8cc7bebef4cfcd5ac2f401a372d\n\n# tcId = 88\n# short message\nkey = fe60e0322035538f2b1de9de380cde35f291deeb6e027b5d829ecd1e\nmsg = 185e4cada4f4\nresult = valid\ntag = 32faa154396b0b62436e6bf937ee\n\n# tcId = 89\n# short message\nkey = 1bf7fcdf3742fa77991528cc1c678b98be9876a8c8c5b809beab7d9c\nmsg = 9c0f34a5654279\nresult = valid\ntag = 086170c46d2b0a76c61527c2d052\n\n# tcId = 90\n# short message\nkey = 32533c16f792ed0acf8e9e60f54aa173937c7194b882ecc3e671009f\nmsg = f968dc7a19afe339\nresult = valid\ntag = 3fb4eb4450ac4b26a714bcfb224c\n\n# tcId = 91\n# short message\nkey = 3cf28a476ce7eaecfc3fbf1b0859a042a568740a584c77cb8f9603ac\nmsg = dbca9e4bdd84b38934\nresult = valid\ntag = 2cf14eb8f4c7537e9831983bb5af\n\n# tcId = 92\n# short message\nkey = a2a8090aef69277f92830ec7404c032f8fdebfbceabb9e590968a77f\nmsg = 6b790a946a83364c79d7\nresult = valid\ntag = d467209f63a9bd3d2c5398c305da\n\n# tcId = 93\n# short message\nkey = 6f999929e91672bac35ea70f8ff8b9aeefa5489493c99b0d27797207\nmsg = b7dabb237aeae2be8b5e19\nresult = valid\ntag = 09b2bb6eaeda5f0229b8c35a2f54\n\n# tcId = 94\n# short message\nkey = 4525b96c263e4d2dab2890aa55f3cc503dc1206d9f1915a6fba5ae61\nmsg = ef858f496fcb7c3fabbfb52e\nresult = valid\ntag = 6f5ca7efcb9a70d0abf8425f42ca\n\n# tcId = 95\n# short message\nkey = f89401acb0a60d07fd733ed563f2ee241f4ecfea8114587a44dfdb0c\nmsg = 7d3c0918085984df95097afa81\nresult = valid\ntag = fc227f29b51f9c855343dcd0ea11\n\n# tcId = 96\n# short message\nkey = 58bce8c0d17fc7131d2fa2262409bb14663a6e68019f88299987893e\nmsg = 1ca50cd6c3f1225eb6c4ec4d6a90\nresult = valid\ntag = 53e103bbded7b825affa240f8578\n\n# tcId = 97\n# short message\nkey = 658e510fba4e2208afac98333f9e242bc118f6e79ef0661d619dd32b\nmsg = 32c385b75ae84558ca302881c51639\nresult = valid\ntag = 485f351e2a9a82910c3c949e32b8\n\n# tcId = 98\nkey = 6a41cc3ca7142ae14e6d979a3f890a331597e592dd74520ce4ea660f\nmsg = 78e3a770a8aaaf039fd4c9b6a1780411\nresult = valid\ntag = 331a58ed96fc8b9e684ab05f636c\n\n# tcId = 99\nkey = b8972b93b68302cbaa08d32904eae6375a66f3508ece3c9b22382c7e\nmsg = 3687e6287d73c9e3f679a50e7671247127\nresult = valid\ntag = 27d8113955026d4d318070fbfd8f\n\n# tcId = 100\nkey = bc570932abfa11050ad4fc80a6d5afe3271d86aa29dc62738b207d14\nmsg = d53202acd2ec74d746531bd9ad3016d0980e0166fb427a08\nresult = valid\ntag = 020e3e0c2940ce15eeb67392570f\n\n# tcId = 101\nkey = c92a0665c12e87026e1b344f971fdb0e474d450cba834aae40e2d21e\nmsg = 4a3a85ac09f5190ab94f73fd91d98f056015263c89ed5da223fc4675cab25cdd\nresult = valid\ntag = 922853f159c42b9e274fcef7bdf3\n\n# tcId = 102\n# long message\nkey = 6fbef67cfbacc98c63252b1ca009a60e8e3479769a2d449fb4639064\nmsg = 006e179eacfa9e1e628bb7823ee9609ae7968b6df90e176f772a79088d37e9b15cab312922aaf8fc6583a341002bda\nresult = valid\ntag = 0a27a12afbb9c3136202e02ae3b2\n\n# tcId = 103\n# long message\nkey = 700b09908174f1072e31ae8ccbda1c4460fcf21fdf146a11482b210d\nmsg = f772564ecb109e80eefb1d5a7f1c95e203ba4c980233dd8d13de3046079a6b2ca26dc3521e5e0c807eae7a79877c73e9\nresult = valid\ntag = 04c718a4cd8b583d5ffb8170276c\n\n# tcId = 104\n# long message\nkey = e18a20246ebe1b5796dbfe35110efc7637d74a355f0a6758d4a00b7d\nmsg = 77720dde530e6eeaa0e9af3311f7e99189d6c4f7d71d0a4207d62c766bee32020c92f5d5d28d5de4d0d9c94b57ec05f0c3\nresult = valid\ntag = 25ebc8611f4b636d892f11df2b29\n\n# tcId = 105\n# long message\nkey = 3c4585a775bec76c7d8b27b87e70a5863a85e6111f3161b3815f59b4\nmsg = 628c0ff8c432d74f4cfb77ba46b7cef67a48ac053cf0c18be41648736abcc8c6fbe4981529babd4b27866e34ced16d8b0bec456e14653a1422f5a62556d20b0fe4e03749d5f6e986375062dbdd82f6e9e1d4ad547c31530c2a31383c25ff57e879eae99d9b3a0da1f3c1dacb975067ac\nresult = valid\ntag = deb94b2d43e98926af51fc0c88dc\n\n# tcId = 106\n# long message\nkey = acaf94cb1a8ff4677fc586d2bdf981ac3a656b208215e0a7647b420f\nmsg = 314c2c25465de3427279dbc89436505fee6d37d56fbda0e5e2a49449d9dbf003027f2e4ef5c52f7af93fd80155a66a1cd6b9885b56d828058a0de7d247e19580b2e8dcbdef2ae46840565fd8b276569c19d7e185116ea11ad67d5fc27f4a6816ba45be5d14f3ba4315c74d1edb20f217b116be852b62a7f4e32b3e708ff9f7\nresult = valid\ntag = 5b0d7aec7fbd196ee69ed373e131\n\n# tcId = 107\n# long message\nkey = e490348ad78fd2cd5b51f2795b79e5805ce1d9baf1151dbdf995e1b0\nmsg = f6ff1845842b9e46f79adb1079aff47397391dc269bc0c899ba4087b58a676f5408c3f7637ffc4772af3e41b5cea51058bc528ea09bb4bd797594c798b0f0ff881695e98c08bbb040c12c5cbdb228d61cc99e332e963128d06e97ed2eefded2e1b5a035f3bea68273efac03a894dcf2fcc79a5696218595404b2758deb9a80ee\nresult = valid\ntag = 590727f344d8a540e5c5e0f4dae9\n\n# tcId = 108\n# long message\nkey = c8e099dbb60a8f19d8b86856b21c55f3437ae27f77dff9808f12a1b5\nmsg = edbc109bf28c8ab32b1238eff1cd14308cdd845fa919bfd8a00c991cf9a8d6b05dd8cc7d2393782949c899de79e771ef7d8567f32287623963048e6c80d91f0778dd63311106e9d0913c08b7a0b7253fa3ce307ac40ec55a4c445f5455a570fec090e251e8646bada1a486d41c3794bce5639732f2c6cfd58081c479a68c515f5d47bc5b2f1622a08d38a596a817f3d4efef8003ae430e6ae93b0a3ae8fa95a2ace3d24d90a9ef861dc04c13e38f6e524b3abdf9cce4fa490707c80c16e254b7a71af00a12dbf473b50b9fe4097ec00ab27e66b6f3022b0f101ee1a9f7fa8652e9f095ca240a446067446867f78e8352c4110794c2e3383dfedfb35e74a33e\nresult = valid\ntag = 33e7dcb0fde3b1c5b92506e635eb\n\n# tcId = 109\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6f99e862e532e8936d78b5f02909\n\n# tcId = 110\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c216faedf3053cd51fcaf417222\n\n# tcId = 111\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6c99e862e532e8936d78b5f02909\n\n# tcId = 112\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0f216faedf3053cd51fcaf417222\n\n# tcId = 113\n# Flipped bit 7 in tag\nkey = 000102030405060708", "090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ee99e862e532e8936d78b5f02909\n\n# tcId = 114\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 8d216faedf3053cd51fcaf417222\n\n# tcId = 115\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e98e862e532e8936d78b5f02909\n\n# tcId = 116\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d206faedf3053cd51fcaf417222\n\n# tcId = 117\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e8e2e532e8936d78b5f02909\n\n# tcId = 118\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216f2edf3053cd51fcaf417222\n\n# tcId = 119\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e432e8936d78b5f02909\n\n# tcId = 120\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faede3053cd51fcaf417222\n\n# tcId = 121\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e732e8936d78b5f02909\n\n# tcId = 122\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedd3053cd51fcaf417222\n\n# tcId = 123\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8136d78b5f02909\n\n# tcId = 124\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf30534d51fcaf417222\n\n# tcId = 125\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936c78b5f02909\n\n# tcId = 126\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd50fcaf417222\n\n# tcId = 127\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e893ed78b5f02909\n\n# tcId = 128\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cdd1fcaf417222\n\n# tcId = 129\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d58b5f02909\n\n# tcId = 130\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51dcaf417222\n\n# tcId = 131\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b4f02909\n\n# tcId = 132\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcae417222\n\n# tcId = 133\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02809\n\n# tcId = 134\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417322\n\n# tcId = 135\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02b09\n\n# tcId = 136\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417022\n\n# tcId = 137\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f0a909\n\n# tcId = 138\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf41f222\n\n# tcId = 139\n# Flipped bit 104 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02908\n\n# tcId = 140\n# Flipped bit 104 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417223\n\n# tcId = 141\n# Flipped bit 105 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f0290b\n\n# tcId = 142\n# Flipped bit 105 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417220\n\n# tcId = 143\n# Flipped bit 110 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02949\n\n# tcId = 144\n# Flipped bit 110 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf417262\n\n# tcId = 145\n# Flipped bit 111 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e862e532e8936d78b5f02989\n\n# tcId = 146\n# Flipped bit 111 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216faedf3053cd51fcaf4172a2\n\n# tcId = 147\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6f99e862e532e8936c78b5f02909\n\n# tcId = 148\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c216faedf3053cd50fcaf417222\n\n# tcId = 149\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 6e99e8e2e532e8136d78b5f02909\n\n# tcId = 150\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0d216f2edf30534d51fcaf417222\n\n# tcId = 151\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 9166179d1acd176c92874a0fd6f6\n\n# tcId = 152\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = f2de905120cfac32ae0350be8ddd\n\n# tcId = 153\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = 0000000000000000000000000000\n\n# tcId = 154\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0000000000000000000000000000\n\n# tcId = 155\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffff\n\n# tcId = 156\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffff\n\n# tcId = 157\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = invalid\ntag = ee1968e265b26813edf83570a989\n\n# tcId = 158\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 8da1ef2e5fb0d34dd17c2fc1f2a2\n\n# tcId = 159\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = \nresult = inva", "lid\ntag = 6f98e963e433e9926c79b4f12808\n\n# tcId = 160\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0c206eafde3152cc50fdae407323\n\n[keySize = 112]\n[tagSize = 224]\n\n# tcId = 161\n# short key\nkey = 77b0de54e893642caeac34bfd1ab\nmsg = \nresult = valid\ntag = 2014a9f272378fa1c9f6744d4db4861b52e61a19eb28320ebee2d174\n\n# tcId = 162\n# short key\nkey = 7346c7e4b118b24e51f4512f906a\nmsg = 506d4faf624f92965aa6b5c01e0c80a8\nresult = valid\ntag = c4e0ad2f62279898a7ede0f709a1ccb8c1004941f3c5074392e79533\n\n# tcId = 163\n# short key\nkey = caa864179f66e826a0ef3b5edbe3\nmsg = 73f64253706ce6b5094c24ee012ece9ac2495283dcd8c7f1114e81e4587d8ea4\nresult = valid\ntag = a1220745bb03d982763bfa7ce352b8bc87576a0ad5d46a0da08ff2d6\n\n[keySize = 112]\n[tagSize = 112]\n\n# tcId = 164\n# short key\nkey = 663a97d6b5493dbfa60c8dd087ed\nmsg = \nresult = valid\ntag = 0c6e21a85e3cd2cd413f36507d6e\n\n# tcId = 165\n# short key\nkey = b08c345a7c7166fdd33ce768c1dc\nmsg = 9964d80ee2338cffe28483aa446a6f76\nresult = valid\ntag = aa003015309f2ed6fd7752e49c31\n\n# tcId = 166\n# short key\nkey = fc9d2883c67534fefbd6ed4a9798\nmsg = a49820c194a43deef11f3a0f4eaa80425439fca9d9f1d7c8e665d6b130e4e908\nresult = valid\ntag = 1c2b96623c91ca9c5027f8f81ede\n\n[keySize = 520]\n[tagSize = 224]\n\n# tcId = 167\n# long key\nkey = cfa639656cd49f8d70f0b1a5a056ab4fc0aeeebc91338d067f36c47b6012dc8d856b8abcc4e1abffc910aeaee21b4d366e907488ffd0ca55b36a621aee0b2e9f0c\nmsg = \nresult = valid\ntag = 0ef4fedaeaab4ad52c843657047b19788a9fa91061b7a14adda8c490\n\n# tcId = 168\n# long key\nkey = b36d3d47a4585b401fc64c98eff56243d4da78863063d814e88f370b92576406d447fcf3d129a1ede57ddc56ea3a0a1f100105a95e83138cdf45ecf2a5992acf90\nmsg = 15c75a64b04d097af2371af380079eb8\nresult = valid\ntag = 4ecb2daa5fb08dbd836e92a51e200bb230f54ac2c9778f5226b3abc9\n\n# tcId = 169\n# long key\nkey = cf78b991382db5e8666ccb2333fb672179b10a75cf9e5a7699ae640005e19772ef6499a3bc97f12e58e835bb0017bb3b2e64c6ab44a0d619dfa0363484d1c991e2\nmsg = f661e598f180f25dc6dd76db8a9e0e4c9c272b9665a6b1756560c723b8e08595\nresult = valid\ntag = cd55cdb0c4f02b9f6148392993b18b4ff00a5e73b6f3fbf83a854aeb\n\n[keySize = 520]\n[tagSize = 112]\n\n# tcId = 170\n# long key\nkey = 3772ff6bb4e5b2811cfd4d6a3d34dc74bca3dbf89a5817b79d8472a1383b8c9afb27b3006196ce9966829eae6a313c2d724d995f4def17117c09edcfc8c0cbbc93\nmsg = \nresult = valid\ntag = 40beb1d3aaab25a403224e577770\n\n# tcId = 171\n# long key\nkey = 2ba910bc0bca90644cb21e96063e2cd85f5dd02fda75d353c9b51eaf45eee94c165ca6592d6cfdd987bfdc1cba66363d535a14b2f7ead841b17c4d76a5049105f9\nmsg = 7ba461040de9ea3cefd4809124f78b39\nresult = valid\ntag = 4d28a926df1b188e85d092bacf11\n\n# tcId = 172\n# long key\nkey = 7fcf3cb1b1c5b537492aede4689284b5881935e3537bb7307198d6518e7a6aabf70b50b44e4a8dfee35e9f5cbada7447e511a37209390fcd171c62075c6a8bf1eb\nmsg = 83d29c1c4d059ddb0d2aca787e5b701bac3953fb9bc72dc87b1ef92a582e9748\nresult = valid\ntag = 392ce38f7838b2f87163eea00b86\n\n", }; -static const size_t kLen130 = 38438; +static const size_t kLen184 = 38438; -static const char *kData130[] = { +static const char *kData184[] = { "# Imported from Wycheproof's hmac_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HMACSHA256\n# Generator version: 0.8rc21\n\n[keySize = 256]\n[tagSize = 256]\n\n# tcId = 1\n# empty message\nkey = 1e225cafb90339bba1b24076d4206c3e79c355805d851682bc818baa4f5a7779\nmsg = \nresult = valid\ntag = b175b57d89ea6cb606fb3363f2538abd73a4c00b4a1386905bac809004cf1933\n\n# tcId = 2\n# short message\nkey = 8159fd15133cd964c9a6964c94f0ea269a806fd9f43f0da58b6cd1b33d189b2a\nmsg = 77\nresult = valid\ntag = dfc5105d5eecf7ae7b8b8de3930e7659e84c4172f2555142f1e568fc1872ad93\n\n# tcId = 3\n# short message\nkey = 85a7cbaae825bb82c9b6f6c5c2af5ac03d1f6daa63d2a93c189948ec41b9ded9\nmsg = a59b\nresult = valid\ntag = 0fe2f13bba2198f6dda1a084be928e304e9cb16a56bc0b7b939a073280244373\n\n# tcId = 4\n# short message\nkey = 48f3029334e55cfbd574ccc765fb2c3685aab1f4837d23370874a3e634c3a76d\nmsg = c7b8b2\nresult = valid\ntag = 6c13f79bb2d5b6f9a315fe8fd6cbb5cb817a660687009deccd88c377429e596d\n\n# tcId = 5\n# short message\nkey = de8b5b5b2f09645be47ecb6407a4e1d9c6b33ae3c2d22517d3357da0357a3139\nmsg = cc021d65\nresult = valid\ntag = e87538eb167e62d7cb236690ff3f034a9c12d417aa8dfa694d7405f9e1f85fe8\n\n# tcId = 6\n# short message\nkey = b7938910f518f13205ca1492c669001a14ff913c8ab4a0dc3564e7418e91297c\nmsg = a4a6ef6ebd\nresult = valid\ntag = 01a93f4ed216d0b280896301e366aa67b25e6b6a5a6e84f291a13391c6e496c5\n\n# tcId = 7\n# short message\nkey = 1bb997ff4de8a5a391de5c08a33bc2c7c2891e47ad5b9c63110192f78b98fe78\nmsg = 667e015df7fc\nresult = valid\ntag = 06b5d8c5392323a802bc5cdd0b3c527454a873d9651c368836eaa4ad982ba546\n\n# tcId = 8\n# short message\nkey = 32fdeda39f98b4f4426c2d2ac00ab5dd4bfabb68f311447256ed6d3d3a51b154\nmsg = 4163a9f77e41f5\nresult = valid\ntag = 1b0103729f48c2772bb132aef9ebd6dd6aafc9145df6d5c514b233ee92ef4a00\n\n# tcId = 9\n# short message\nkey = 233e4fdee70bcc20235b6977ddfc05b0df66f5635d827c66e5a63cdb16a24938\nmsg = fdb2ee4b6d1a0ac2\nresult = valid\ntag = 120b26ee1355c134c262513c7922deb6c4fd90303de4cd61b9f9cd08f22d6e18\n\n# tcId = 10\n# short message\nkey = b984c6734e0bd12b1737b2fc7a1b3803b4dfec402140a57b9eccc35414ae661b\nmsg = dea584d0e2a14ad5fd\nresult = valid\ntag = 88bc2282e5fce47ec6d9895395cd47fff91a0cdc589a8fd56d8d344616533a3d\n\n# tcId = 11\n# short message\nkey = d0caf1456ac5e255fa6afd61a79dc8c716f5358a298a508271363fe1ff983561\nmsg = 18261dc806913c534666\nresult = valid\ntag = f678f081d83cf126ad6bd52c2dffd786214f519c47452b85a97458d0c10c3ee5\n\n# tcId = 12\n# short message\nkey = 835bc8241ed817735ec9d3d0e2df4c173ee4dded4a8ef0c04a96c48f11820463\nmsg = 26f8083e944bacf04e9a4d\nresult = valid\ntag = e0e46cd7d1a75b3d102893da64def46e455308761f1d908786628ca7ee22a0eb\n\n# tcId = 13\n# short message\nkey = 055f95c9461b0809575eccdfa5cdd06275f25d30915c4eb8db40e1acd3ab7591\nmsg = bfb7d6a08dbaa5225f320887\nresult = valid\ntag = e76d5c8c070a6b3c4824e9f342dc3056e63819509e1def98b585aeba0d638a00\n\n# tcId = 14\n# short message\nkey = e40f7a3eb88ddec4c6347ea4d67610756c82c8ebcc237629bf873ccabc32984a\nmsg = 7fe43febc78474649e45bf99b2\nresult = valid\ntag = aa57d020aa24ad823472c2b80ff2d0cf475f7de0068f9a59e8112fede53a3581\n\n# tcId = 15\n# short message\nkey = b020ad1de1c141f7ec615ee5701521773f9b232e4d06376c382894ce51a61f48\nmsg = 81c7581a194b5e71b41146a582c1\nresult = valid\ntag = f45c72603cc160c0762f703407844a7781dfe0f1ddf0aaf4ccd8205e94469aed\n\n# tcId = 16\n# short message\nkey = 9f3fd61a105202648ecff6074c95e502c1c51acd32ec538a5cce89ef841f7989\nmsg = 2a76f2acdace42e3b779724946912c\nresult = valid\ntag = 0226ee13cc05e2340135b3f4b27a9da1a160f6170fe805dadd98a3711ec9c421\n\n# tcId = 17\nkey = 6fa353868c82e5deeedac7f09471a61bf749ab5498239e947e012eee3c82d7c4\nmsg = aeed3e4d4cb9bbb60d482e98c126c0f5\nresult = valid\ntag = 9ed7f0e73812a27a87a3808ee0c89a6456499e835974ba57c5aab2a0d8c69e93\n\n# tcId = 18\nkey = 5300489494ca86221c91d6d953952ae1a5e097139dc9cf1179c2f56433753824\nmsg = 90fea6cf2bd811b449f333ee9233e57697\nresult = valid\ntag = 5b692cba13b54fffc3adcbb0e015cc011fbfd61235303ff0ad2a49775083bf22\n\n# tcId = 19\nkey = 383e7c5c13476a62268423ef0500479f9e86e236c5a081c6449189e6afdf2af5\nmsg = 3202705af89f9555c540b0e1276911d01971abb2c35c78b2\nresult = valid\ntag = 4e4901592ba46476408d758435c7d1b489d2689afd84ceaaee78bfb91fd9391d\n\n# tcId = 20\nkey = 186e248ad824e1eb93329a7fdcd565b6cb4eaf3f85b90b910777128d8c538d27\nmsg = 92ef9ff52f46eccc7e38b9ee19fd2de3b37726c8e6ce9e1b96db5dda4c317902\nresult = valid\ntag = 3fc1d73dd4a8858c1fc3d8c4a3f33ed5ad0c70210038394a5902cb26fe287348\n\n# tcId = 21\n# long message\nkey = 28855c7efc8532d92567300933cc1ca2d0586f55dcc9f054fcca2f05254fbf7f\nmsg = 9c09207ff0e6e582cb3747dca954c94d45c05e93f1e6f21179cf0e25b4cede74b5479d32f5166935c86f0441905865\nresult = valid\ntag = 788c0589000fb7f0b5d51f1596472bc9ec413421a43df96ee32b02b5d275ffe3\n\n# tcId = 22\n# long message\nkey = 8e540cb30c94836ae2a5950f355d482a7002e255207e94fda3f7ef1a099013a0\nmsg = d6500f95e11262e308bf3df4df4b855f33e857563d4543f195639a0a17b442eb9fdcc1367d2eee75c8f805730b89290f\nresult = valid\ntag = 39697e70ce741feb33dedc069f00b5627fd9b837d10cbdd5b6d19cfbd511dd2c\n\n# tcId = 23\n# long message\nkey = 69c50d5274358188cff4c0fae742243d4e8a5e5ba55d94ff40edd90f6a43dd10\nmsg = 1ac5255aff052828d8ea21b376f1ebdd4bb879949913900405aebce83e48feb6813b5e9c89f94501a8ade41b26b815c521\nresult = valid\ntag = 4b0b4d0416fa2e11586fbfa7fb11261e69991dfa34019b9893d69a2be8c1fc80\n\n# tcId = 24\n# long message\nkey = 23209b7c5aadcbd13f7279af1a86d3c7ae8f179d1bcaaad0dff9a15302e78dbf\nmsg = 84bdac37e1af35d9356404e2787d47ece58348dea76a4a46e8aade3463d4db8c94a051be3733b38d756984865d56c60e8025f15e3f968f093e7fb7ebc7e31189c5692d15ed4256737b9b1894e5809503aaa1c9983fb096aa21916361eeb6ef455b129723a1a1ddf9deddea208529a648\nresult = valid\ntag = 4a85c479d1650dbd73bc5248074a55ff50218bddaa8d1fddaaf44946dc19aefb\n\n# tcId = 25\n# long message\nkey = 7c9cc667cae175f448faa96647319633b2d48531373ae7d316c44ddd8b9f69cf\nmsg = 9233c1d73b498c5106ff88951e07b9652cb0ddae740737ec205c9876d094978bfc947f7dc937119fd6a93915b19b625958a7a22363aa2ac33fb869ed16b303336ab740a0498a2df66a6599da710094481a7b544bd955b6f97135ba4673401db2db144a6e287041e47a51ed9b6ba956c13508c1c0c25310105239ab73629e30\nresult = valid\ntag = ca1b80441d333909c2bb30769650055051ed20f17de8ee953cb9070af56c704f\n\n# tcId = 26\n# long message\nkey = 82314540564ea3ce30591e97f68b2602de40fa29f773c2508327471b8348e8c4\nmsg = 6a6d2f45cebf2757ae16ea33c68617671d77f8fdf80bed8fc5cdc5c8b7086bd28e7eb3eecc7163491104e5309455e67f836579b82a1da3bf5991a8e2b2f189a49e05700e46c409ed5de77780a5f389e3f13dad406c9d55675329c5c921f07034180937c0f6ef34a2308b6ff3e1a0e9dc1ea65f5632730e8744d1db2c40a6595b\nresult = valid\ntag = 0900b3e6535d34f90e2c335775e86bf38ee7e3d26fb60cd9cdf639eb3496b94c\n\n# tcId = 27\n# long message\nkey = d115acc9a636915241795f48852052e07b51273ae2448251ec1d0d0f9807f3db\nmsg = 696d2456de853fa028f486fef437b6b6d1b530a8475e299db3a9005ae9cef8401985b7d31e172e8f439ccd1ad1ec44c9b86b78f3f243c1305b53bc21abad7a8fc5256311bfd34c98e37dfdc649e7ae4bda08cf2994b063c0c7106ed0b02a1f48af9191cbfb0d6a953b7e04327dfe8c93779cb574ba9cba575d01674e83621aa0c5f400d6e6cd24b301e33c9f3303e73bf357408c1be86c2489c09de998ff2ef32df554f1247d9313ce1a7160115d06f4c18d6556ff7986ef8a55e2adcfa27e4c69c71cc2ff01639e9d49bd9ed0687f530ffeb0890132457df2088081bc4a2f7f0a9f4dcea2c80d991db7f3747a1803d7619aaf3dd382c69536a0bcdb931cbe\nresult = valid\ntag = 82f92977f0b605eaada510ffceb53ad75fde16a8029f1b75b406a84270dbb8b7\n\n# tcId = 28\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 29\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 30\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d18b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 31\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = dab99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 32\n# Flipped bit ", "7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 538b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 33\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 34\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38a42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 35\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b89f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 36\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42896d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 37\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99fa709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096c80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 39\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2708a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096f80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f270ba3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f4df826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3caf4172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 44\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f836b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74162cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 46\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f026b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 47\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74972cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 48\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f824b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 49\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74170cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 50\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b45a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 51\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbf93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 52\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d4607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 53\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93834c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 54\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d7607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 55\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93804c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 56\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a955607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 57\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93024c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 58\n# Flipped bit 248 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1ca\n\n# tcId = 59\n# Flipped bit 248 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14f\n\n# tcId = 60\n# Flipped bit 249 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1c9\n\n# tcId = 61\n# Flipped bit 249 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14c\n\n# tcId = 62\n# Flipped bit 254 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc18b\n\n# tcId = 63\n# Flipped bit 254 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef10e\n\n# tcId = 64\n# Flipped bit 255 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc14b\n\n# tcId = 65\n# Flipped bit 255 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef1ce\n\n# tcId = 66\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28b42096d80f45f836b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 67\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b99f2709a3ca74162cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 68\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42896d80f4df826b44a9d5607de72496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 69\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191", "a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99fa709a3caf4172cbe93824c1f29b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 70\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f4df826b44a9d5607d672496a415d3f4a1a8c88e3bb9da8dc1cb\n\n# tcId = 71\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3caf4172cbe93824c1fa9b23a0c1e9c21bd851ff2d2c39dbef14e\n\n# tcId = 72\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 2c74bdf6927f0ba07d94bb562a9f8218db695bea2c0b5e573771c44625723e34\n\n# tcId = 73\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 274660d8f65c358be8d3416c7db3e0d64dc5f3e163de427ae00d2d3c62410eb1\n\n# tcId = 74\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 75\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 76\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 77\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 78\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 530bc289ed0074df02ebc42955e0fd67a416249553742128480ebb395a0d414b\n\n# tcId = 79\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58391fa789234af497ac3e1302cc9fa932ba8c9e1ca13d059f7252431d3e71ce\n\n# tcId = 80\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28a43086c81f55e836a45a8d4617ce62597a514d2f5a0a9c98f3ab8db8cc0ca\n\n# tcId = 81\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b89e2608a2cb75162dbf92834d1e28b33b0d1f9d20bc841ef3d3c29cbff04f\n\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 82\n# empty message\nkey = 7bf9e536b66a215c22233fe2daaa743a898b9acb9f7802de70b40e3d6e43ef97\nmsg = \nresult = valid\ntag = f4605585949747de26f3ee98a738b172\n\n# tcId = 83\n# short message\nkey = e754076ceab3fdaf4f9bcab7d4f0df0cbbafbc87731b8f9b7cd2166472e8eebc\nmsg = 40\nresult = valid\ntag = 0dc00d7217bbafe8d78bf961189b8fd2\n\n# tcId = 84\n# short message\nkey = ea3b016bdd387dd64d837c71683808f335dbdc53598a4ea8c5f952473fafaf5f\nmsg = 6601\nresult = valid\ntag = ff296b368d3bf059cc48682f6949ccaa\n\n# tcId = 85\n# short message\nkey = 73d4709637857dafab6ad8b2b0a51b06524717fedf100296644f7cfdaae1805b\nmsg = f1d300\nresult = valid\ntag = 2d02bd1c25b1fe52b1ead07374d6e883\n\n# tcId = 86\n# short message\nkey = d5c81b399d4c0d1583a13da56de6d2dc45a66e7b47c24ab1192e246dc961dd77\nmsg = 2ae63cbf\nresult = valid\ntag = 4d9e8bddf9b7a1218309d5988aa1b0d9\n\n# tcId = 87\n# short message\nkey = 2521203fa0dddf59d837b2830f87b1aa61f958155df3ca4d1df2457cb4284dc8\nmsg = af3a015ea1\nresult = valid\ntag = cb8a4b413350b42f4ac3533cc7f47864\n\n# tcId = 88\n# short message\nkey = 665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c\nmsg = 3f56935def3f\nresult = valid\ntag = 1cfce745db1ca7de9a1d4420e612ca55\n\n# tcId = 89\n# short message\nkey = facd75b22221380047305bc981f570e2a1af38928ea7e2059e3af5fc6b82b493\nmsg = 57bb86beed156f\nresult = valid\ntag = 0bde0d0c756df09d4f6da81b299a3adf\n\n# tcId = 90\n# short message\nkey = 505aa98819809ef63b9a368a1e8bc2e922da45b03ce02d9a7966b15006dba2d5\nmsg = 2e4e7ef728fe11af\nresult = valid\ntag = 406a5c2bd3e6a9595f9b7dff608d59a7\n\n# tcId = 91\n# short message\nkey = f942093842808ba47f64e427f7351dde6b9546e66de4e7d60aa6f328182712cf\nmsg = 852a21d92848e627c7\nresult = valid\ntag = 0b1bf9e98d0a794fa55c09b63e25799f\n\n# tcId = 92\n# short message\nkey = 64be162b39c6e5f1fed9c32d9f674d9a8cde6eaa2443214d86bd4a1fb53b81b4\nmsg = 195a3b292f93baff0a2c\nresult = valid\ntag = 71f33f6021d90858cadb1353d7fbe8d7\n\n# tcId = 93\n# short message\nkey = b259a555d44b8a20c5489e2f38392ddaa6be9e35b9833b67e1b5fdf6cb3e4c6c\nmsg = afd73117330c6e8528a6e4\nresult = valid\ntag = 4b8d76372ebe5e5caa56ca4e5c59cdd3\n\n# tcId = 94\n# short message\nkey = 2c6fc62daa77ba8c6881b3dd6989898fef646663cc7b0a3db8228a707b85f2dc\nmsg = 0ff54d6b6759120c2e8a51e3\nresult = valid\ntag = c580c542846a96e84ea77701778455bf\n\n# tcId = 95\n# short message\nkey = abab815d51df29f740e4e2079fb798e0152836e6ab57d1536ae8929e52c06eb8\nmsg = f0058d412a104e53d820b95a7f\nresult = valid\ntag = 13cdb005059338f0f28e2d8ce1af5d0a\n\n# tcId = 96\n# short message\nkey = 3d5da1af83f7287458bff7a7651ea5d8db72259401333f6b82096996dd7eaf19\nmsg = aacc36972f183057919ff57b49e1\nresult = valid\ntag = bd993e4428cbc0e275e4d80b6f520363\n\n# tcId = 97\n# short message\nkey = c19bdf314c6cf64381425467f42aefa17c1cc9358be16ce31b1d214859ce86aa\nmsg = 5d066a92c300e9b6ddd63a7c13ae33\nresult = valid\ntag = 86c9f4dde0b257a7053a7b03c7504409\n\n# tcId = 98\nkey = 612e837843ceae7f61d49625faa7e7494f9253e20cb3adcea686512b043936cd\nmsg = cc37fae15f745a2f40e2c8b192f2b38d\nresult = valid\ntag = b96bcacafac30094f18ac5039e7b3656\n\n# tcId = 99\nkey = 73216fafd0022d0d6ee27198b2272578fa8f04dd9f44467fbb6437aa45641bf7\nmsg = d5247b8f6c3edcbfb1d591d13ece23d2f5\nresult = valid\ntag = 6e597c4c3861a380c06854b446fc2a87\n\n# tcId = 100\nkey = 0427a70e257528f3ab70640bba1a5de12cf3885dd4c8e284fbbb55feb35294a5\nmsg = 13937f8544f44270d01175a011f7670e93fa6ba7ef02336e\nresult = valid\ntag = f731aaf2f04023d621f10495344679a0\n\n# tcId = 101\nkey = 96e1e4896fb2cd05f133a6a100bc5609a7ac3ca6d81721e922dadd69ad07a892\nmsg = 91a17e4dfcc3166a1add26ff0e7c12056e8a654f28a6de24f4ba739ceb5b5b18\nresult = valid\ntag = 95243eb1a9d448174ae4fccf4a53ebfe\n\n# tcId = 102\n# long message\nkey = 41201567be4e6ea06de2295fd0e6e8a7d862bb57311894f525d8adeabba4a3e4\nmsg = 58c8c73bdd3f350c97477816eae4d0789c9369c0e99c248902c700bc29ed986425985eb3fa55709b73bf620cd9b1cb\nresult = valid\ntag = 343367207f71425d8f81f3110b0405f6\n\n# tcId = 103\n# long message\nkey = 649e373e681ef52e3c10ac265484750932a9918f28fb824f7cb50adab39781fe\nmsg = 39b447bd3a01983c1cb761b456d69000948ceb870562a536126a0d18a8e7e49b16de8fe672f13d0808d8b7d957899917\nresult = valid\ntag = 151618eec4f503f3b63b539de0a58966\n\n# tcId = 104\n# long message\nkey = 7b0d237f7b536e2c6950990e61b361b384333dda690045c591321a4e3f79747f\nmsg = 3d6283d11c0219b525620e9bf5b9fd887d3f0f707acb1fbdffab0d97a5c6d07fc547762e0e7dd7c43ad35fab1c790f8047\nresult = valid\ntag = ce201c0dcfdc3f2bef360609a31fb19e\n\n# tcId = 105\n# long message\nkey = 17c92663741f012e5bb6714e614c2d155948617f10936269d954c58aba2ae62d\nmsg = 7fdd6a15c861d0313f6635d77dc55e115ff18c8ab063b5d03eab472eeca87a378188f25813515cf90b6cffa94a8ff36b29d65603eab3fbd2aa9500b261e184049893dc6ca2010becac163053f211070bdda621b8bd8af77e450268603b52db34c90be836dfebddef42303f724e63bf0f\nresult = valid\ntag = 76e8dfd94db4af9d79d9718eec46cb2d\n\n# tcId = 106\n# long message\nkey = 424c6b22606fcc094ae82fc5d3cbe484174c2211b3ec778091cac34a8e38a152\nmsg = d96ff062e2490e8e0c54c5a8b89e85b25a66d93d7c2b93bdfef846b70d38672746a4b988d08f15a5c527ca4f2c80e53f7c6ac0521bc57ebe38209180cbf934e0bbeb58cfb63d75da64af41d09ce174af1896f42522910fced35ea000402e95fd3ac7aa6d5e0a6b533b0879bc466019b3a5e6b16e4bd1ea6cdfc9ccc1d6f0f0\nresult = valid\ntag = eda709c7009714c372d0d6a63dfde469\n\n# tcId = 107\n# long message\nkey = 15d553c8da433d53cdc7f15087a70349caab57b379a4078928ce9b99302e31a6\nmsg = d6c0c53b73f74fb426adfdc143d70db7f7a8f8ed32a2faef263cf9ab117537b6b9d1728bd1000c1f28906c6ce6ad21862bfa4d689c1a8ebe3868b992098", "b7f981b2af5189a6adedff53a6c70c83693f5c8d6385a9a8a4dca017c5716ac4d5b9765c5ca2ab5f9867e02795198c0b9527e07d08af52dbcb91ceb3d8b412a2b2402\nresult = valid\ntag = 8ca1402bf8fc23442ac2067be925b828\n\n# tcId = 108\n# long message\nkey = ffe559468a1031dfb3ced2e381e74b5821a36d9abf5f2e59895a7fdca0fa56a0\nmsg = 238899a84a3cf15202a1fbef4741e133fb24c009a0cd83854c6d1d7c9266d4c3eafe6d1dfc18f13845ccdad7fe277627b5fd5ff2555ce6dfde1ee078540a0a3590c6d9bf2fb63ba9afbe9380e797be7cd017645c5a3613eef38ef89e3b7461e6e700ff2b4deef5636c9d2198b143f797ca1820a3dcc5d462ebf4a8c4c09eb202a23592eb9524082c79adda8fcd56d256041a26bf8f523962ba911ce5a5786570d65be3c4df722ed8830302065febdf944715298a1fbb7d10b68d7da2bf889324314ce51e815c7fbf03aa0a8358aff3a86eb7a33f9a4923660db3047e793bebb0c6918f4395d400381723fdae2832c36efc8e368a68f30f6351c3bc942cd560\nresult = valid\ntag = a830b313f4936dea56a3aefd6a3ebe7d\n\n# tcId = 109\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28b42096d80f45f826b44a9d5607de7\n\n# tcId = 110\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b99f2709a3ca74172cbe93824c1f29\n\n# tcId = 111\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d18b42096d80f45f826b44a9d5607de7\n\n# tcId = 112\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = dab99f2709a3ca74172cbe93824c1f29\n\n# tcId = 113\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 538b42096d80f45f826b44a9d5607de7\n\n# tcId = 114\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58b99f2709a3ca74172cbe93824c1f29\n\n# tcId = 115\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38a42096d80f45f826b44a9d5607de7\n\n# tcId = 116\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b89f2709a3ca74172cbe93824c1f29\n\n# tcId = 117\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42896d80f45f826b44a9d5607de7\n\n# tcId = 118\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99fa709a3ca74172cbe93824c1f29\n\n# tcId = 119\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096c80f45f826b44a9d5607de7\n\n# tcId = 120\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2708a3ca74172cbe93824c1f29\n\n# tcId = 121\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096f80f45f826b44a9d5607de7\n\n# tcId = 122\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f270ba3ca74172cbe93824c1f29\n\n# tcId = 123\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f4df826b44a9d5607de7\n\n# tcId = 124\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3caf4172cbe93824c1f29\n\n# tcId = 125\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f836b44a9d5607de7\n\n# tcId = 126\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74162cbe93824c1f29\n\n# tcId = 127\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f026b44a9d5607de7\n\n# tcId = 128\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74972cbe93824c1f29\n\n# tcId = 129\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f824b44a9d5607de7\n\n# tcId = 130\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74170cbe93824c1f29\n\n# tcId = 131\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b45a9d5607de7\n\n# tcId = 132\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbf93824c1f29\n\n# tcId = 133\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d4607de7\n\n# tcId = 134\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93834c1f29\n\n# tcId = 135\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d7607de7\n\n# tcId = 136\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93804c1f29\n\n# tcId = 137\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a955607de7\n\n# tcId = 138\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93024c1f29\n\n# tcId = 139\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de6\n\n# tcId = 140\n# Flipped bit 120 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f28\n\n# tcId = 141\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607de5\n\n# tcId = 142\n# Flipped bit 121 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f2b\n\n# tcId = 143\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607da7\n\n# tcId = 144\n# Flipped bit 126 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1f69\n\n# tcId = 145\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f45f826b44a9d5607d67\n\n# tcId = 146\n# Flipped bit 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3ca74172cbe93824c1fa9\n\n# tcId = 147\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28b42096d80f45f836b44a9d5607de7\n\n# tcId ", "= 148\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b99f2709a3ca74162cbe93824c1f29\n\n# tcId = 149\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42896d80f4df826b44a9d5607de7\n\n# tcId = 150\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99fa709a3caf4172cbe93824c1f29\n\n# tcId = 151\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d38b42096d80f4df826b44a9d5607d67\n\n# tcId = 152\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d8b99f2709a3caf4172cbe93824c1fa9\n\n# tcId = 153\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 2c74bdf6927f0ba07d94bb562a9f8218\n\n# tcId = 154\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 274660d8f65c358be8d3416c7db3e0d6\n\n# tcId = 155\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 156\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 00000000000000000000000000000000\n\n# tcId = 157\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 158\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffff\n\n# tcId = 159\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = 530bc289ed0074df02ebc42955e0fd67\n\n# tcId = 160\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 58391fa789234af497ac3e1302cc9fa9\n\n# tcId = 161\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = \nresult = invalid\ntag = d28a43086c81f55e836a45a8d4617ce6\n\n# tcId = 162\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = d9b89e2608a2cb75162dbf92834d1e28\n\n[keySize = 128]\n[tagSize = 256]\n\n# tcId = 163\n# short key\nkey = a349ac0a9f9f74e48e099cc3dbf9a9c9\nmsg = \nresult = valid\ntag = 3a8437b877b75cc08a4d8d7559a8fc6869a58c713da63d1d4b350d59b597e30c\n\n# tcId = 164\n# short key\nkey = ac686ba0f1a51b4ec4f0b30492b7f556\nmsg = 2fa43a14ae500507deb95ab5bd32b0fe\nresult = valid\ntag = 008532a53d0c0ab22027ae249023375374e2239b959609e8339b05a15742a675\n\n# tcId = 165\n# short key\nkey = 73ef9ef1a4225e51e3c1db3ace1fa24f\nmsg = ffad380d9aabb0acede5c1bf112925cdfc3d379fc2376a4fe2644490d0430ac3\nresult = valid\ntag = 9c7cb9f7c207ec46d1e3c55764731c4ab5ddbae4e1401e52a895df0cff4787c9\n\n[keySize = 128]\n[tagSize = 128]\n\n# tcId = 166\n# short key\nkey = e34f15c7bd819930fe9d66e0c166e61c\nmsg = \nresult = valid\ntag = 1d765ab9e29892f7bfec2975ad4bc2dc\n\n# tcId = 167\n# short key\nkey = e09eaa5a3f5e56d279d5e7a03373f6ea\nmsg = ef4eab37181f98423e53e947e7050fd0\nresult = valid\ntag = cfc19ec07902ec8be489606d8f40d172\n\n# tcId = 168\n# short key\nkey = 9bd3902ed0996c869b572272e76f3889\nmsg = a7ba19d49ee1ea02f098aa8e30c740d893a4456ccc294040484ed8a00a55f93e\nresult = valid\ntag = ac50adad9785a89c7282d8ab881dc615\n\n[keySize = 520]\n[tagSize = 256]\n\n# tcId = 169\n# long key\nkey = 8a0c46eb8a2959e39865330079763341e7439dab149694ee57e0d61ec73d947e1d5301cd974e18a5e0d1cf0d2c37e8aadd9fd589d57ef32e47024a99bc3f70c077\nmsg = \nresult = valid\ntag = f5bfb940561fb4db73ebba49bf2e4893bb0cca618a71b7ecf6aca38231e167ea\n\n# tcId = 170\n# long key\nkey = 2877ebb81f80334fd00516337446c5cf5ad4a3a2e197269e5b0ad1889dfe2b4b0aaa676fac55b36ce3affc7f1092ab89c53273a837bd5bc94d1a9d9e5b02e9856f\nmsg = ba448db88f154f775028fdecf9e6752d\nresult = valid\ntag = 1690ed4180642899e0deb9ec2270374e8b0a484217f5a682c524316eca219b64\n\n# tcId = 171\n# long key\nkey = 21178e26bc28ffc27c06f762ba190a627075856d7ca6feab79ac63149b17126e34fd9e5590e0e90aac801df09505d8af2dd0a2703b352c573ac9d2cb063927f2af\nmsg = 7d5f1d6b993452b1b53a4375760d10a20d46a0ab9ec3943fc4b07a2ce735e731\nresult = valid\ntag = e542ac8ac8f364bae4b7da8b7a0777df350f001de4e8cfa2d9ef0b15019496ec\n\n[keySize = 520]\n[tagSize = 128]\n\n# tcId = 172\n# long key\nkey = 813e0c078c221375e80590ace6774eafd2d2c242350988d02efa550e05aecbe100c1b8bf154c932cf9e57177015c816c42bc7fbc71ceaa5328c7316b7f0f30330f\nmsg = \nresult = valid\ntag = bb6ab66f51e53fa086c9c61a26ca27e0\n\n# tcId = 173\n# long key\nkey = 5713343096b0aaf0562a6b92c1a15535924160475a4e4233589159728c562e3b2ad96f740c6a4da2bc3f768ce98c9bd66bac28d1646ff592028c940d455f35eeb4\nmsg = 71712de2fac1fb855673bff72af64257\nresult = valid\ntag = c18165b8b97db1ca5e2486a32b39731e\n\n# tcId = 174\n# long key\nkey = 7208afbecf5f1f34828f98b719414e280716de64f5edd1ae1c774153cd2022337bb20fade1b7856f1dbfd40e2b4307f1293ceff1692ee90d8c90b5fdf953ab01a5\nmsg = 43b53302b604d613e62db002044a4782d572ac8fbd3cd0ece91b43bc52e18e98\nresult = valid\ntag = 2fecfe45d79339c57dddba68ab34f5f1\n\n", }; -static const size_t kLen131 = 47894; +static const size_t kLen185 = 47894; -static const char *kData131[] = { +static const char *kData185[] = { "# Imported from Wycheproof's hmac_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HMACSHA384\n# Generator version: 0.8rc21\n\n[keySize = 384]\n[tagSize = 384]\n\n# tcId = 1\n# empty message\nkey = ee8df067857df2300fa71a10c30997178bb3796127b5ece5f2ccc170932be0e78ea9b0a5936c09157e671ce7ec9fc510\nmsg = \nresult = valid\ntag = a655184daf3346ffc6629d493c8442644e4996a2799e42e3306fa6f5b0967b6cf3a6f819bab89bce297d1d1a5907b2d0\n\n# tcId = 2\n# short message\nkey = 976696c0dc97182ca771975c3928ff9168ef89cd740cd2292858fd916068a702bc1df7c6cd8ee1f0d25e61d4c514cc5d\nmsg = 2b\nresult = valid\ntag = 363e8973fedcf7892013dfae0b7065d61d80b98c635bc09ed860a01473b9bcd0dc550dbf66cf0d601fe9cbf3ae59620d\n\n# tcId = 3\n# short message\nkey = c55ea4c64a0a63e2d14ad42559ba7c816b8824d263c2cc6a015761b53f681e514369f0dfba5cde165320ee10a96eb1fc\nmsg = 5abd\nresult = valid\ntag = ccc2925f164a7d9662f1e76bcaf6345492bb091d4d2d775af2178a4bcc1ca21dcf8b3bf8f056823770782f25a419bb3e\n\n# tcId = 4\n# short message\nkey = 2928d465d92fa40072ca9d67761be66e491755e43499003c1057d3bec870f255126c3658d0d8a0c7d207df8710037ca7\nmsg = c405ae\nresult = valid\ntag = d9e19c672a466e4c83a849905728c4be1db99bdd260946d9ff52939779002dcc460c576f02b40dda0717182be96b5411\n\n# tcId = 5\n# short message\nkey = 686a3730085cc944fceb141628419818e662fe21e52bea2748f3b704f80ce801086db1e3068917b242e62b4d6e6ed685\nmsg = 6601c683\nresult = valid\ntag = 10dc39103983b3a6be376a8eda7b6f363cb91efe11b027a62440ae136bd66f98b0a1d8b8f2399099492021076afa14a0\n\n# tcId = 6\n# short message\nkey = f22d867b972b232e3f444a488dd794d170807c70eb650f952b6177596f76c558a5d860d6f7be0be9e666f9bd53732f8d\nmsg = 15b29377e0\nresult = valid\ntag = e02e4e20b5f1e5f06913bc9745c9069c09ec1369f1a296ad1d07c04cc4f9cb4741248d7ba097cd3ba0e75d2409d6a01b\n\n# tcId = 7\n# short message\nkey = 3ac9abd53dbd0fbb891f9b5e16dd45df994e5283527832707138fc2712bad9e34761e7d9c6d05d46f2c8323ddb0efe99\nmsg = 5a34155b1115\nresult = valid\ntag = 78c53dd1a2431174628f5f4867fa777afa6df1b36269bba114d016d1065fcb021170baad09b4a528f40573903a65f540\n\n# tcId = 8\n# short message\nkey = ae3aa94fdd35e2bef40472d29bdad3a409840ea441c3d7025cd72f3e81ff56da602161d84b23d1634061385be30c5bbd\nmsg = 8a140d781e7191\nresult = valid\ntag = fd22ba896cb1147bb86f8ad51c253b792657c0becc913e90104da0f139f9b08c9169706f1531a2c6c03d6bd72a77eff2\n\n# tcId = 9\n# short message\nkey = 44b79852cabcf3fe93d2fff55d2afe6a46c35b7ad1954ce0888de7b459b982722faf8b490e6b00e7bcabbd36f18443f5\nmsg = 9398cd251deafe8b\nresult = valid\ntag = 56128fb438a93f6f48f47c0f4c7549f8008a8e69bbdbf0886ec40f86e7870034ef9090d2b04057391f1def5b25e8f0ad\n\n# tcId = 10\n# short message\nkey = 03fed2f579a3ebdececfb184ebe2984876113399c4a593d98b5f5e606dd330fb394c285d9ead601748259b493335f8e5\nmsg = 18d879b1f63df3ac7a\nresult = valid\ntag = a0e3b5660eeb5fc4a5dd48e725b09a0e282b22bbe2693d8b893ddf0f2116450e0875925407e909fde0f1f728f608fba9\n\n# tcId = 11\n# short message\nkey = f4ef48bf4056d39dbba4154018c63bdf29420b9991ea594ff05e3cc1cb02e176d54ba038a6b78692519d6788e495bbab\nmsg = 0a5de13cd9ba31c94486\nresult = valid\ntag = e9a1219e86983d69e336068b280309f974ab61f25968fc6352324ba49c36ce42c578676a3a31ef11e960d6771386650e\n\n# tcId = 12\n# short message\nkey = fc771f7ccd499a1ed633d86876d707b5f1d53c6bcdf21aa2907766ab3ca7fa6cdd6a9b981b1a84a528e81444303f1057\nmsg = 03ba11f3f3173b85226b25\nresult = valid\ntag = cfb4971d5449db364e2c8d0d429a0767050d480a5397f0dcc74294f52ea96260a57fe6cad14409ad67da6fbebf2da0d8\n\n# tcId = 13\n# short message\nkey = b3999de680b11550e18631c8199f7eb8a74e21bdc9d97f781245c2af19f85497d9f38b250a564e48650fd00be365f155\nmsg = 9c658cb5e601d85dc3857863\nresult = valid\ntag = d547e4cbd56e82b47d2ec93eeb6b34924ebda461fb60e475bf328d2368618f55fbf7b0e2eb1ff542c4eb7eefbfc8bd2b\n\n# tcId = 14\n# short message\nkey = 88005a62864ea699e1509616ec48033e84d2e2a13b8bc2e8a76f2eccbdb207a95ac8e2f5b5a703b22a0b571e8acc599a\nmsg = 5a94f84541a794bf23d72db16d\nresult = valid\ntag = d6b73ee67e88a20fceb5520be92594daf1b3786c7187535ccb1f0b926dae11adde6e8697ba803b159019849df3c9d2c7\n\n# tcId = 15\n# short message\nkey = b1cbda2c9a12f92315a5101aef311e99d6db002b0e04fb53c50106aa4d28e9a346697ba97084572eea56ccfc4ad7e572\nmsg = ce12c0c78e3f6b276ac56ed7435e\nresult = valid\ntag = 5c0802cd0ed82380e4c2a61d146ed72762613de89eb4ab9fe71da9ad3d79e1d2321cae186292f7c52ab639d3ba6aa85a\n\n# tcId = 16\n# short message\nkey = 08517e8014e00db5c37f2a20f987ea2ec52e7938de018ad6be256ba2236804144ad2a1bcc242738862b40647007e0a2c\nmsg = 21e2a0a167789a6b722d1737d92f8b\nresult = valid\ntag = 2264d3c9b835aedf699d5fbfc05d46f085591441df75aa2b2873f6c8a11a0856a2b79ae11ea0a91609dbd564a0bed456\n\n# tcId = 17\nkey = 503d7478a773b694d6e552c9703cc8bc56fd49fafc9a17cab8b0332dca8d49336fa7e9ec2bcb56253fe5bb504e3e7f7f\nmsg = d96e6fed893addfd9237c81c4f4e341b\nresult = valid\ntag = 19389766789912260f3f9757df3651663829c358bb48b22c1c63132070df318905beffd45f51e4dfcb3e785f44cf9106\n\n# tcId = 18\nkey = 41341bab902e767d4d1964c0acfecf46eff1b02b6455bcb2097de9c154be1f667f21be076de18cd2c15c005896fca87f\nmsg = 4c43ac7de3631cc86f4da72fe6b6a552f1\nresult = valid\ntag = 3c3104f24b7070cc3277d9ae640d416298fc917a0c1cdc3c2e7b6da75706fd2ae234efd551af12ae29144704793e2f6a\n\n# tcId = 19\nkey = c2f83be1acce7b89a5f9e9ea7e4c4f8b0f4319986fbe479fa3b4a3c298168362393b56ea03b5cef77f48e5a72abe6d08\nmsg = 8dd0cd786cd800ffebec098728923d69249d3223c4c595cb\nresult = valid\ntag = 751c6c7d00fef5e4edc993915fba694943a7ee3a2c8e5b700d0ee536bf85fb117a9cd6c456485cd670f7a0b490c83e61\n\n# tcId = 20\nkey = 6bd2aee9dd98d6b6609fce82181b10c20bba861da68a1590586fab08c5e9e90ff584047db4760828643fea38087160e4\nmsg = 33236a9de603c1e4f5e11164224740627d10f6008eb73ec2642321bf0b82d579\nresult = valid\ntag = e4cd8b8868bb078ed5d6938e40d9ff4bf61a4994be40a5f2b5446463e5db90516bccdd19f16c92e3f839b9d6de68b2a9\n\n# tcId = 21\n# long message\nkey = 2f98ba2ceaadc5ba08880a35cb0080dc870a5734a782ebe31c4bab100ff8786dcc3be6de18482ea5d1b3bf14aeabb470\nmsg = 2d74a66dacf12edb85ef3073feafd122889cb634add00ff0395d224b4ff8b5d5d67ca6419b6826abffdb41bab427d5\nresult = valid\ntag = a8ea72100859f4b7b6f2fe596248f1729bcdf0606c900ab52e51eab548d26e1eb634a42e5fc7ccc18356c0d283597ee2\n\n# tcId = 22\n# long message\nkey = 5e5f60e40d84c7ca2608af3bcc6e04abc5f8b7ca730a78af7f6f032e5a1501695bd91f3bebb28590af1db90d8390ca58\nmsg = 2efe6a14ea8d679e62dbcedf35e61852278c83c54adbe1f1c72cb1a746b11cff8cb4fc3a2c3acd44255d51c020ca6d47\nresult = valid\ntag = 6e8c95a4097ea13d064ed10809a33b569a6a84205158bd692ff82bc4b70b47a60ed332f2f5bca5211a1cc89c06f9c595\n\n# tcId = 23\n# long message\nkey = bc310bc3913d9fe59e2012a058c9e150534d25611e36206cf07ccaefe153f38eb0eaad9941b6883dfbce01bcb5196041\nmsg = 9f0747d7396bfbe01cf3e85361e50085e0a91a7490b994031d81851b725065993f45dad0d60d794aedec7ba5d9d6dbbee4\nresult = valid\ntag = 3a86498f78c3fb7eb3b7b3d82f677d2dfe01166fe76e232083334d74f11588fd089637c94761e9cfe836436005deaef7\n\n# tcId = 24\n# long message\nkey = dc770c64d00d156e43cb74970e3a1a2ad28b6d9ec6b2b6e5ac3e356a99f879cb620f00340c044cc1f31bdccfa0dbd177\nmsg = 403fd8e3ef51b6539db658a894be85b58fbc84881e61c5e0cb13ae421a09d31d780603256d390edd056d190856be00ad20a7048f0c67416fe8e02884086155f4263262e8c1275504d4f91f2751d3c3dccd4409ff2b45e41de93f7b104d58f6e15bacb62ace9700615ecc1b30a0cc1b35\nresult = valid\ntag = 1c4f6474f39e6eabbe7a99faa234f49833444130acf01dae68d68251a930419960b0fb5f48360149e05d1209941cc9ec\n\n# tcId = 25\n# long message\nkey = cca9299c7bdc26a4b595055c99ca23bec8ed11b5deeda91f83e2365e7340395ceef4e86e5cd91f2593bcfec498a67fc9\nmsg = a05b40b8d3a7bc7b75b0e97309c9bd1c9d8755c1ff5245ef6308a6a5cad3ecfbcb6364b41ca6f3d24bbee844d6204d1026abe345af7bdec114a373b109aa5724b738d50ab7a826c268e873709f8b35135a870045d5fb9daa82d3c245b5338917354e72b3058c9a4b807117465217d7d14f36f8a8d4e97bc3b93587c92641e7\nresult = valid\ntag = 1b6b5ba848bc13dd46c35177ae9ff9bd2d6ca5f4c9373964d3182483d980b4654527f36d7cc51b9e2efe7ed97a82e3be\n\n# tcId = 26\n# long message\nkey = c728e65e08d9296fe3cdf2dedb49c81a30b603a62569eece4ee5d01e9a32ae3bcb4ec163e455e452582454ceefefc046\nmsg = e6c6bac87c17e269a471434ca9568401451d78c2444a9d6edcda3cdab51c5bed1c19eaf34326580fd85ae5236ad51bc5dae386b36101f54695c595eeedcdd0182a4a117f8093f4f4812e03db396ede9849d193e7722081aeec4be6c4caf6c979d36ead56634a21be21162ea232dec9cffdbd2474245878dca369e814fd028303\nresult = valid\ntag = 533920a013cf006aa29b26f74b6dd29363", "4293089986aa249271c426b942dc6bae32b2641616672f3d75968866e182e5\n\n# tcId = 27\n# long message\nkey = 90c4215dc3f237435047fefdd8638d339a3fc66fca06c5063eacbda002ab335e621605f672f3da9f641fae110afc3e7b\nmsg = 1ebc22c3031b64615eb6f1a0696e33b7df139a4b891d3e6721cc26c05d55de790dca623668c10308485d38e95ec4769fa4430ca3ebc25da9f5d31c972674517d9a2222e6b97d8def6512af096c6d1480d83a229c84b7f28c80184b6bebf3f4eff5fc4e5c6cfea4f8eba9a957f7913b20a88ad1734f7c38547e934d1dbf2d73dbd61e31fb1583c7b6577a171e7d02f19045126ac2973d855bc18d34d32326d1e216da58366a60033450091128ae26a479069bba7b91b2ab7f3c5fbcde391de3ca114b951d6852f92795f8023d7a29a7f4ce61e9241b4f235d21e899087167ab3f3a0e9321c7942b165178788df48d3b106b203ec1e01d29bda41a99ac0d2c00\nresult = valid\ntag = c52b91daed6ee46416f2db78978251cb334e5d8e00b32ae06e365f455d28de406a9cce2f9f29378f229822dbf26bfdad\n\n# tcId = 28\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 45be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 29\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a84d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 30\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 46be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 31\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ab4d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 32\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = c4be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 33\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 294d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 34\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44bf81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 35\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94c07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 36\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be814415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 37\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d077f90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c414d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 39\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff91b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c417d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff92b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d2832b7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b3386064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 44\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7b62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e065b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 46\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283abfa62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 47\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e0e4b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 48\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a42a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 49\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064903603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 50\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a55188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 51\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03703d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 52\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45189e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 53\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d66bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 54\n", "# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a4518ae5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 55\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d56bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 56\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45108e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 57\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603576bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 58\n# Flipped bit 376 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c67\n\n# tcId = 59\n# Flipped bit 376 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d217\n\n# tcId = 60\n# Flipped bit 377 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c64\n\n# tcId = 61\n# Flipped bit 377 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d214\n\n# tcId = 62\n# Flipped bit 382 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c26\n\n# tcId = 63\n# Flipped bit 382 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d256\n\n# tcId = 64\n# Flipped bit 383 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310ce6\n\n# tcId = 65\n# Flipped bit 383 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d296\n\n# tcId = 66\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 45be81c415d283ab7b62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 67\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a84d07ff90b338e065b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 68\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be814415d2832b7a62a45188e5dafbcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 69\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d077f90b3386064b03603d76bcf0214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 70\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d2832b7a62a45188e5da7bcb97da606bd5b16c92c1fc36f198c0b3a714921848d5e03df1c4849bb8310c66\n\n# tcId = 71\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b3386064b03603d76bcf8214b1fb88c66b9415dde76674896400f97b8408bfefa6ee86c716bfa4a460d216\n\n# tcId = 72\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = bb417e3bea2d7c54859d5bae771a25043468259f942a4e936d3e03c90e673f4c58eb6de7b72a1fc20e3b7b6447cef399\n\n# tcId = 73\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 56b2f8006f4cc71f9b4fc9fc289430fdeb4e047739946bea2218998b769bff06847bf7401059117938e9405b5b9f2de9\n\n# tcId = 74\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 75\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 76\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 77\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 78\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = c43e01449552032bfae224d108655a7b4b175ae0eb5531ec12417cb67118403327941298c85560bd7144041b38b18ce6\n\n# tcId = 79\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 29cd877f1033b860e430b68357eb4f8294317b0846eb14955d67e6f409e48079fb04883f6f266e0647963f2424e05296\n\n# tcId = 80\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 45bf80c514d382aa7b63a55089e4dbfaca96db616ad4b06d93c0fd37f099c1b2a615931949d4e13cf0c5859ab9300d67\n\n# tcId = 81\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a84c06fe91b239e165b13702d66ace0315b0fa89c76a9514dce66775886501f87a8509beeea7ef87c617bea5a561d317\n\n[keySize = 384]\n[tagSize = 192]\n\n# tcId = 82\n# empty message\nkey = 1c678267be13acb464939c2896c9e9ce1deb5b30833bdd9ca00370889b84410782ad52afe25dc10ab7ec5cf5f34793b7\nmsg = \nresult = valid\ntag = 6dd566be678c1e6359ab31b635cc1601", @@ -3518,9 +4156,9 @@ static const char *kData131[] = { "090a0b0c0d0e0f\nresult = invalid\ntag = ab4d07ff90b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 113\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = c4be81c415d283ab7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 114\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 294d07ff90b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 115\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44bf81c415d283ab7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 116\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94c07ff90b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 117\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be814415d283ab7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 118\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d077f90b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 119\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c414d283ab7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 120\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff91b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 121\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c417d283ab7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 122\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff92b338e064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 123\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d2832b7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 124\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b3386064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 125\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7b62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 126\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e065b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 127\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283abfa62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 128\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e0e4b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 129\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a42a45188e5dafbcb97da606bd5b16c\n\n# tcId = 130\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064903603d76bcf0214b1fb88c66b9415\n\n# tcId = 131\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a55188e5dafbcb97da606bd5b16c\n\n# tcId = 132\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03703d76bcf0214b1fb88c66b9415\n\n# tcId = 133\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45189e5dafbcb97da606bd5b16c\n\n# tcId = 134\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d66bcf0214b1fb88c66b9415\n\n# tcId = 135\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a4518ae5dafbcb97da606bd5b16c\n\n# tcId = 136\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d56bcf0214b1fb88c66b9415\n\n# tcId = 137\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45108e5dafbcb97da606bd5b16c\n\n# tcId = 138\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603576bcf0214b1fb88c66b9415\n\n# tcId = 139\n# Flipped bit 184 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16d\n\n# tcId = 140\n# Flipped bit 184 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9414\n\n# tcId = 141\n# Flipped bit 185 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b16e\n\n# tcId = 142\n# Flipped bit 185 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9417\n\n# tcId = 143\n# Flipped bit 190 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b12c\n\n# tcId = 144\n# Flipped bit 190 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9455\n\n# tcId = 145\n# Flipped bit 191 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d283ab7a62a45188e5dafbcb97da606bd5b1ec\n\n# tcId = 146\n# Flipped bit 191 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b338e064b03603d76bcf0214b1fb88c66b9495\n\n# tcId = 147\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b", "0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 45be81c415d283ab7b62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 148\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a84d07ff90b338e065b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 149\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be814415d2832b7a62a45188e5dafbcb97da606bd5b16c\n\n# tcId = 150\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d077f90b3386064b03603d76bcf0214b1fb88c66b9415\n\n# tcId = 151\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 44be81c415d2832b7a62a45188e5da7bcb97da606bd5b16c\n\n# tcId = 152\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a94d07ff90b3386064b03603d76bcf8214b1fb88c66b9415\n\n# tcId = 153\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = bb417e3bea2d7c54859d5bae771a25043468259f942a4e93\n\n# tcId = 154\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 56b2f8006f4cc71f9b4fc9fc289430fdeb4e047739946bea\n\n# tcId = 155\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 000000000000000000000000000000000000000000000000\n\n# tcId = 156\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 000000000000000000000000000000000000000000000000\n\n# tcId = 157\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 158\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 159\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = c43e01449552032bfae224d108655a7b4b175ae0eb5531ec\n\n# tcId = 160\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 29cd877f1033b860e430b68357eb4f8294317b0846eb1495\n\n# tcId = 161\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = \nresult = invalid\ntag = 45bf80c514d382aa7b63a55089e4dbfaca96db616ad4b06d\n\n# tcId = 162\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = a84c06fe91b239e165b13702d66ace0315b0fa89c76a9514\n\n[keySize = 192]\n[tagSize = 384]\n\n# tcId = 163\n# short key\nkey = 08476e9d49499c5f52e37f80ece6f5a45459948806b48241\nmsg = \nresult = valid\ntag = 1b6cfc8709aab8075465f32e13b0b0f796cc34d93d7bed090f297dcf9fb75e0d8e285b1500b732d554ac97ba45f33e47\n\n# tcId = 164\n# short key\nkey = 213b44d8e1fabaff837ef30ee2542f9ab82ed70411dae78f\nmsg = ee0bf48585c186ff991b4d8607817c9c\nresult = valid\ntag = 54f4010d50f80bcdb4b84d56bc4ef30e4c68f75128214cf446b5145f6fff1326a209945fc21ab5e1f5d917559ea9b800\n\n# tcId = 165\n# short key\nkey = b4afa9daaa8c944d73a3881f3221e42b34ef4e35f184e878\nmsg = cf607f6a0eb44ecbca81b6d1fdb595cee35f2353da02e82e28e133b9decd8fbb\nresult = valid\ntag = d064a51fb109c3b1d443f13f41e90e14198f846080464547806d46a8151c4e3855a81f4af40915609095dd72f869aa1b\n\n[keySize = 192]\n[tagSize = 192]\n\n# tcId = 166\n# short key\nkey = 89e46b66209548c80b0c830662223b49b0e3b895eb30e2fc\nmsg = \nresult = valid\ntag = 4b012c0c0da44ede2a427e85ace8ecc54b379e9e24f08d41\n\n# tcId = 167\n# short key\nkey = f2c10ce8cb1cf3b363354473b027c1e53deccef03233be0c\nmsg = e1fa10b8e301e0348405770bc3fafcb1\nresult = valid\ntag = 2d088af29cc744e347124fbe4100cbcdebbae037ed9bf69d\n\n# tcId = 168\n# short key\nkey = 92e074442cc4c59e72260808d80d8e7b85c6335068917b83\nmsg = 34eae27425ace17771e164cbb634306f352edc9c37bf608be8a755fb94148183\nresult = valid\ntag = b7e6b7bb29c02e4635dbdc50d8be71e2ddf0a544471de285\n\n[keySize = 520]\n[tagSize = 384]\n\n# tcId = 169\n# long key\nkey = db6f9956c3f4ca6e41f1f7f14629d44c79e0353edbf3e310e6858bbc45a7cd57778a9053ba22a141bf58bfd434ad08648c7041a224b97a0d17e0edf94fd40b410a\nmsg = \nresult = valid\ntag = 0cb1b296255bb259f3b601b49b35524a5eca6c52360754d3d96dd521c905b1c1821d74965967d8e86d50de950fe4d635\n\n# tcId = 170\n# long key\nkey = f03404bdb3e08f530d4c3a5f165d236012a4c45cd063e3e4483da088ec0afdb24e9639fccabb91f98a49dc2972e2981426573ecfe69c00c43a2d99a3107cef3a70\nmsg = 73ed9fa2acf49d6c98bfc7d6c5ad9c56\nresult = valid\ntag = b6132e5216f711eeeb44da3d92983fe5b6de5cd9410be71db8d3b07228341686aa60e7081e95f2e4b69bb7cd9648bc0b\n\n# tcId = 171\n# long key\nkey = ee799e25edb1b18452e5ed174bc6b2185a6754417d6cc05d736d2ba9efc8367e4b05ba0a2ee525ceeab74f9804a8479130c328d671e34070cf174a003a1dfb5994\nmsg = ac3e7da7e578b9b4dc2424030446c7f6aebcc471445a9e0e6e65099caeec5b2f\nresult = valid\ntag = c8607fca1888418166c550dd58d7a3976a6ecd0e4ca99b02fb187800a9c9ef909a6c1497c0652d4dca82405ab07f5eed\n\n[keySize = 520]\n[tagSize = 192]\n\n# tcId = 172\n# long key\nkey = 063d6e12e670098adabe68192023b637bb6d8d713fc8436188c4ec06fdd084ce6d193f26c86a9560e1abc27d813fce2b3eac0170fd1cb72e1930a2776bc84d6c11\nmsg = \nresult = valid\ntag = 9dc2acbfa28a7ac5f2a5bdd4b1b2dbc806c48f96ce950eb5\n\n# tcId = 173\n# long key\nkey = 359318e6c6279ba9ebcb1675f5a98195bbf5d895da9c17b8329038be857dc395b12ae91a55598876593c1c20bc0172cf15126b7a6bf0a238eda3325d6dd60600ef\nmsg = 7ad0c9098ea10e615bb672b52c96542d\nresult = valid\ntag = 4163737c219f7c5e743843dc3d36019c6585ea5d4e7cf24f\n\n# tcId = 174\n# long key\nkey = d01cd898089d8a1eeb0035b0d332da80fbd3571b9192db10fa6f55f665ab192d7050cab643996e99254d9573e0cf4eeaa63afccdefd81614fe7b83dfe30e3ba19f\nmsg = d67c77cdd0af5d10e8cae887e5a609bb76a9e5597653773c303b82b918fdc59f\nresult = valid\ntag = e7df527a988080749ee215ba0f8207838df38a37707a6330\n\n", }; -static const size_t kLen132 = 57350; +static const size_t kLen186 = 57350; -static const char *kData132[] = { +static const char *kData186[] = { "# Imported from Wycheproof's hmac_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: HMACSHA512\n# Generator version: 0.8rc21\n\n[keySize = 512]\n[tagSize = 512]\n\n# tcId = 1\n# empty message\nkey = 5365244bb43f23f18dfc86c09d62db4741138bec1fbddc282d295e0a098eb5c3e37bd6f4cc16d5ce7d77b1d474a1eb4db313cc0c24e48992ac125196549df9a8\nmsg = \nresult = valid\ntag = d0a556bd1afa8df1ebf9e3ee683a8a2450a7c83eba2daf2e2ff2f953f0cd64da216e67134cf55578b205c8a1e241ba1369516a5ef4298b9c1d31e9d59fc04fe4\n\n# tcId = 2\n# short message\nkey = 00698977f7102c67b594166919aa99dc3e58c7b6697a6422e238d04d2f57b2c74e4e84f5c4c6b792952df72f1c09244802f0bcf8752efb90e836110703bfa21c\nmsg = 01\nresult = valid\ntag = 4d1609cc2c2f1ab5ddc35815ae1b5dc046f226bde17ec37a4c89ec46fbd31af2aeb810b196dffdd11924d3772bef26a7a542e0a1673b76b915d41cbd3df0f6a6\n\n# tcId = 3\n# short message\nkey = ed6dc65dbeaadbdaab530a0d35f19f78a7bd93e698546c82751bf650c2a44fc8529033d088febeed288fb4c8132a59df0207687640c76dcdb270ac3af5f042f1\nmsg = a78f\nresult = valid\ntag = 0757b27e120559d64cd3d6e3cb40d497845375815181bd9b4e74f2189d09d01a1b3ead53701380d988958ed22bc379ace9d47cbcac1d49bfa7e14f1f44804c30\n\n# tcId = 4\n# short message\nkey = 463c5e696da0ec0d784388be775d1d91d94746aa8d3d2c209f56ac95ea54e7288329f9fb40be4eef35547e64c61dc51a4a1f3380a2b96420f088655ea9d85b97\nmsg = e956c1\nresult = valid\ntag = ac4b1509391814ae5cb5a123e7a060601575c11d81b563bdc52febe6bb2c747b85eeddcb6748c98147a46a1cc9be6776d1a8e82ae4896b9c18da2ff351c56795\n\n# tcId = 5\n# short message\nkey = 4bc0d32e945cfdafd20d39be3820f9649727cbda5ab5859953a322cbde1ab7a514d7dcd14ba90905e70919bb86b85cfeaa375ee2ce2703711b938c8f4ab5f178\nmsg = b2aa48b3\nresult = valid\ntag = c4ecdbd2efb17640ce6707e2e9d0ee5bfb98b91584bc86ab386437eaa37b0f2eb70500361105416c0dcecff389dc94c723fcff18cb801740962312007a195a23\n\n# tcId = 6\n# short message\nkey = aca47f6350941a0efd8c3bac9064a554be337cde7d192f6fbf86d1b4db09b36531165cbae0a634206f71fa400df33352fff60e1fba4009ac6671cd37312bdd98\nmsg = bc993b1db0\nresult = valid\ntag = 89af2f5746cab89fda6993e00f1bf0cc70a77188945bb7b5409b536aec5533ad501db6ecfa3e516b580b7df9c8eadb3cf556ccc01668be984335bd5a6255d566\n\n# tcId = 7\n# short message\nkey = b3ecae6f25c2f699f158b3ffcd0a7a575583e4c9cb56b5c22ef4273cde6c6734e84d7400749c17e47e8cfccafaf8b50c65eb47dfeb273d5d30a1181e37b27ad0\nmsg = f0361d58291e\nresult = valid\ntag = 4037a57aa279b5a07abe9389dcf508be9495a8257dcb3feba3f0801cd57574c30bfddc6df5df6567cd572c4e82735fd4e67b65e85b030f183a7f4457fb7d2c3d\n\n# tcId = 8\n# short message\nkey = 70ff24a252d65183bdc6b7c88751f850821141a61246727c3240b4f96088ae3278767a822b65735a28ccebe4c874bcb2c942882cb23f9dd87fe08fbaad5ae72f\nmsg = e18da3ebf0ffa4\nresult = valid\ntag = 878d488754bc796c70e11d5db77acda2e1796d86146e27d862586740c4d488ed12239e6fb4ab2925afc88168609edc048f8572536fae96e149d73d230b18db66\n\n# tcId = 9\n# short message\nkey = dd4e05933d09711ee88cb4c1ceb3600b2b33808bc08d499387b331d9c7af49bc65b55172cf8083385a940e4b864b7b4b73ddf3bd513a6cbcac73878a879b4d06\nmsg = 66948029351432c3\nresult = valid\ntag = 9968a16eff2b4eeecb2f9d11fcb105e8d8ca59ed4e69131c9de599cd8155fa4f33def1195a6b452263aad9265e16d4951841d7cd33c74c475da04497c02922ea\n\n# tcId = 10\n# short message\nkey = fbd32caf8984fc4376d10daa7288db8e6e74464bdd94b448adab4497b319e9a6dcce542f82a7ff2e775d12477c880e460a9eab8efc49fcfc8c5476cb4b08954a\nmsg = 38a2586a2883953cc4\nresult = valid\ntag = e0c69bd034cdec5b48150fdf3a4383456a7626d4405df52dc6c2bc8fe93bd87e369e06a781ed80ba8b1fe1146c4df82b6a514412358b31b77b9b79c7a91ec9e4\n\n# tcId = 11\n# short message\nkey = fd4c3f6b2137513616c28ed4d8638f867ad0b97188b73fc9b36f3d52b82d72a49b9dc1b8b25397eb448054a8d38d838e7a88b4df9c263aea1b968771d5ac5756\nmsg = 86b4e61b3b7d650044ad\nresult = valid\ntag = 29345d7da44e2f228e8d502e29fb655da3676a481f9947c8482502ce070b3da5065589d84c02a05cd774b4bd5a15b668c59bafc192695aec43e5df3a82301745\n\n# tcId = 12\n# short message\nkey = f95baea535f477d22b405c67d927f59a9e042c46297a1681bcc16fdbe1b2cd59675a221351a78075981e7eb4998066768801cbd7a85231114d7f27f9bdf24899\nmsg = 5a34dee4e0982d458efffb\nresult = valid\ntag = 63867bb3e82bd4a5f715b3dd67ba3625666e458c5e3d75804709f80b6dde6f774ea223ba9e2536c60ab636dd12d07b217234a490ea9cae4fe673215d33f8c57a\n\n# tcId = 13\n# short message\nkey = 4d76ae95a123207e01c6d22d8b587e63ba682963e50961afff531160a9b9aac6c772c5e8bf918ddecbeb56455ea64710e51ac21e3bb9af4b24eaa8535b3c2924\nmsg = 2c31f2d986f68a6d6a96c4b0\nresult = valid\ntag = 9d4f9549ac134a6f60f17fd0fbc80f55426afa73cdaf84a806d98dfffc94263178116f76aadca95a9243a9128f5f66d3e7f33e72603d4b35ab90ab7d1e870ad7\n\n# tcId = 14\n# short message\nkey = 0da7fa1f5d217951e3e343cda81f232deb71764eb49e8510bc28dba8eb62afa2a98b6f0536adb10250c74878fe649f47bbafdf3f722fa150f66e83f65f606ab0\nmsg = 83511de190663c9c4229ace901\nresult = valid\ntag = 11bd76ba2fd5684e3faadd44abc05d32661472ae4c75fd69e62e47a2d462e483ab5fd374070e648017250934d486fed55e68f4338547fb5dc54d4bed894c1c2f\n\n# tcId = 15\n# short message\nkey = cec9e9f25ed9a017004a7882b1e44e8bd8fa3203c50cb6058455ed4f2a036788d46fcd328327d0d86b1abae69f7bbb96e3d66373ec8bd45075890879a83f4d33\nmsg = 80dcd8ba66f98b51094144e9b8bd\nresult = valid\ntag = c69f1787bf7804bfffd9da7e62f58c1c9f599ccae2ed4fc6abda1be48620afc797d59d4adb396e1fa5d18b8c1aa1c7c15218a9f9e3aab226119adad742641089\n\n# tcId = 16\n# short message\nkey = bbe25649ecdf54ae0028fb923cc8c28ec00e10e2d44214590781238a143b75d54efb037eb9f53082a8ab3d8876daf4dbdc2483c4ba222797fe20da3b7730368b\nmsg = 33f630088c0d24cda98caff1a3afc7\nresult = valid\ntag = c803ca833e851418a3d9ed764f8c83f481060141eb1b2bf64d7ee7991b041c48bfc747bce13d69722f63944085cef8e7a166270530fe31a2a525a99b8a75f1b1\n\n# tcId = 17\nkey = f5e2b9e2313f4f807cb3a924a7d4943fc3fb475d8f1a1b40ce09a37770f621af8977729cadf986c98c75f08a4fab4280538e09e7e51e87a8d62c03411bdb8d24\nmsg = 74ef623c83275ae99745bff7e6142afa\nresult = valid\ntag = 471055f7a2d44758e7d7837db85c33626b8306760eb45e18d4ba8dfbcd0d4279fcf8b539ef7b165eeabf5457ee2c41e52d07e9121da02c988f08162f86bdf208\n\n# tcId = 18\nkey = 8e323d5fb4752d92a6d905c512b287d07b21ae50002d026ff0388e1593bde9998dd02321e200d148f5fa2e824b37e9f5a77441794b840bedd552d1051c1ddd8c\nmsg = 4daa229b009b8984354c2ec3e7973e0042\nresult = valid\ntag = 93a2137cc84e2fa1439d7c239767b3ce653d634c58a4590eb61af9d3ef986445220aff3554de45a1b0933fa06d3d64460418910977d8d9ddb2eb04963c816841\n\n# tcId = 19\nkey = 465bc1ab2125cca29729d01df044e393b0677defdd939280a3aa141224efa06457e623056d02f6c36eca3dfc4a7476dd36b97d0c2d60c7672129189e73b6af8f\nmsg = dd84599b47ba9ae9f2ad0c8eac678485433eb6b1dfb7c998\nresult = valid\ntag = 9fff43a83c71833211f9d60eeef4166965c41a37c76634b1bdf9c5291df75dc877668f2287bcf8108ea9e03d061a708db2db08687eda61fa97b1ca92dcf22b92\n\n# tcId = 20\nkey = b90226798dff2ffb91d1ee4103f26397d0bf84c13c1ec717392c5fe1d4d0f4dc790236d759fa1be852e305da585a3dbde0d3912bea60d6b140c25645eb00943f\nmsg = aa29c372f136993c65ace5e1d62078806eb787913bb35af33371056359d354b2\nresult = valid\ntag = 493a727536b07d434a7fc8df6b70989148a8d94cadb9761ad845ac5fde2068f9565e68607b531b0f307d7c17ce0a2ba69fb1ac1b0c716f93904eec75669e70b7\n\n# tcId = 21\n# long message\nkey = af1bb91775cb40c73983f119c927a2ce8f7b954a6274ecc1cd96019e5c417af4b094376194eae71c7f68f3345654d5d9f8198a697b41ae251e82308accd935bd\nmsg = 75ededdfa7f1df1dc144fb195b27e454640e3f897cb564222f05e8aab0c6024f90472afea6e7254ed25134ea43452a\nresult = valid\ntag = b53d564086a745b10d88a48b50ed8b53f4c83fd12bf56a75108074de9b343cdf0668ce8b6a3d884ba2da5f4c957f1319e26c0813c99a4269c171ad80981013a2\n\n# tcId = 22\n# long message\nkey = 513e0e7622eabcb6bfc81669dac903df46daea1240f32248bbf4fc61f1f9b13b2c3fe1bcc97540d30065be9eee41e51748bc42c16a8c8269fbe2b6f625c19228\nmsg = 81d8650937f50871a66af71605ea4fa9d6c5d7a375774c2280eb34aefcee8c0ef83345bc547e4de7cbea482369b25a93\nresult = valid\ntag = 9d942e4585742ba118bda6e132510af3b9297047d364f76b2a0d1fc803849b06ccac0eaa427934055c9d2e5a5da19cf17299ffdab65089580d10ff7207c9ed03\n\n# tcId = 23\n# long message\nkey = 627c9a72247d07b0cec8346277468311c7401fc4cecaea8e22e13ece4b352c8f7a7eb1ba81ce348a08670438c97b8d9e883614d550f1ff16d636975c59988c2d\nmsg = 118e0468cbb52f93a3396ebfaa114881a98a4101f4ff912ced47ecfc73b27f52205b7a5d4f3899506f9e34ebf99460da7a\nresult = valid\ntag = a186e08c7731d4bbb1d5342a105ef48f5353c5c542277de607831fcbbc8d0b9fd509c74bf9e352ee739792ee3cd6382f", "96e70adb589fdf1fb031d43eef1a595f\n\n# tcId = 24\n# long message\nkey = 1e981d0cbbad5bea9480d836b4704bf3147663b6ea59e1e0a280fb45d9b85d445dc972159dde301c6f1e66681f95642dbb9a9218c00d0cd724cb02f3bcaea2ea\nmsg = 440dff390688c9fde31c17fdb61c1d13899f9544a986324c34d5eb07bef9a4436297f4a7fe16de5dd7b24e0c7c129051efe6f2dd0a21aec05c3e3c8f6fa30d9c0cbd60d840d14f0b2a928bc7189b9de4a6a731151d6b31e6a0ecae75095434737be8c3db11a6a697d0616c78b97041de\nresult = valid\ntag = c52eb5d18e90687248342a84dc0241c680e992b88b1409275df7e347c99169a50cd780eb4726ad759e2a027fb091354e3d7c7aba8a21f8acd1d0e21236af5f98\n\n# tcId = 25\n# long message\nkey = ee8aea2a52eb7e0c1120ab736b1a825b12610063de9642c594766c020cb87314d8ac94b13072bfbf3c019b4aacb1d2695cdd7563a26f574e12559906784d853c\nmsg = a3951f1d18135602fdadceeef5741c24ad22756160d0c55e51b788af952adaeb13e18c24c6b09672f405d7ec3d49b0bd86c7f8691b6f69af49175423215cf57d7c08a54ab0b0293e685c9aa250f1599d78193a00af822dec4b56fdb41f0343ab2cf85ea27bb2e650930f5e8ca836833903b053b3e06899b4012a6532978d90\nresult = valid\ntag = d3678ca7c5c1aa21f12eccc21a1add0b3eb12ccd134033570468191e51b058c61f2a7d88f2ca6c652c29c65c491bf1f0252bc157bdd77436ff55204eac6dfb0d\n\n# tcId = 26\n# long message\nkey = ecd1861a12eaee48aef1d7ed278223b50d3416dbff81e976c56ecd4b1a1bc8892b584cbcc72370ff5e976a6af1790caa32f9ea912855914c0315979578fbf165\nmsg = 5779c56373a8e5db43bd65c0453ce23144230d43666d717a3b59d2e90f0e10732376831d7281cb23dd5566e5f8c627d00d39650139ceb87cd47e921d65d6c1cc7712ac4bd75bda8828e68abc968f4160ed91b28946c9d706b0360bbbdd65f47ef9983c50f2d09d05c3674c0943ea4af54c381089f9b846dd69ce908e0f6eaaaf\nresult = valid\ntag = d377e4efc39f25ca751452e79dcb5661f8adcc06570bd3f710e03854e032286ca477e6a620647958fd31706463b542ddf617757875f349c61109358d04f6dc58\n\n# tcId = 27\n# long message\nkey = 71aadbf330ea133b46c939d12e603896902e8df638597c98872dfb5aecd5161bc84095221de3222367012f45c6d70701e862ab000e782e91b505b21b4e212c38\nmsg = e6d7b0280d2f7df83fd26562fcdea2597cf687a9c9fa194f655c44d3271b881f28adc436db8e0437ff4dc5d38356271c338829c3e2d9ba4ac1777c94886983d4b72c275bc00e4f7b06c5ce38a2fe549fe53761857f236da705fd03790b41cc6f759f41aa206feca7ba5486f4fc9d09f35c8e0887241291882010414ae41b8b384a715a409be13da17bfd60d3fbd4b8cb3cc7c26043807264a20b9a5c02725e742fff03e1806b38af357ebf8c79fc4c38b007bf0613286cf063e45482375475e6c426d4f70057cd92efcb2dfe86e45bdea399273a5e0f142221fae206800555c01b18533295f577e23a9a7a0aa072823002b9096501174d3bc4aac33e0dc600\nresult = valid\ntag = 0c1cbb2f196d3d1af5f982a330bf1d9accaada72cf6c254658cb32bfd8705481abd2e163a73338700f0d961ca02a31b600df04faf311cd06498557831102f80f\n\n# tcId = 28\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d39b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 29\n# Flipped bit 0 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = be301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 30\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d09b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 31\n# Flipped bit 1 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bd301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 32\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = 529b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 33\n# Flipped bit 7 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 3f301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 34\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29a9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 35\n# Flipped bit 8 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf311cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 36\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9ebf87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 37\n# Flipped bit 31 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301c3fb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 38\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f86809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 39\n# Flipped bit 32 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb466720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 40\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f85809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 41\n# Flipped bit 33 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb766720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 42\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809606f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 43\n# Flipped bit 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566728e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 44\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617", "18191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f24109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 45\n# Flipped bit 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e22f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 46\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686734109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 47\n# Flipped bit 71 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720ea3f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 48\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f36109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 49\n# Flipped bit 77 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23d166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 50\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34108fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 51\n# Flipped bit 80 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f167e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 52\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc618d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 53\n# Flipped bit 96 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24965c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 54\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc518d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 55\n# Flipped bit 97 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24a65c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 56\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fb4718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 57\n# Flipped bit 103 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e2c865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca52\n\n# tcId = 58\n# Flipped bit 504 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388d\n\n# tcId = 59\n# Flipped bit 504 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca53\n\n# tcId = 60\n# Flipped bit 505 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388e\n\n# tcId = 61\n# Flipped bit 505 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca50\n\n# tcId = 62\n# Flipped bit 510 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb038cc\n\n# tcId = 63\n# Flipped bit 510 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8ca12\n\n# tcId = 64\n# Flipped bit 511 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809686f34109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0380c\n\n# tcId = 65\n# Flipped bit 511 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566720e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3e7e2dca7b011bf4cec4c7e7d6cc41bc10c3be36e8320c50aaf6c35f04ac8cad2\n\n# tcId = 66\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d39b9e3f87809686f24109fbc718d6abbb09c278cf05a206adf21463e1170362122e58272a31679720b254cbd63a7c6d696bf9283f9c6897e7d792483bb0388c\n\n# tcId = 67\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = be301cbfb566720e22f166e24865c396f21619c7c15033cc6e8ebbcc8c5c", @@ -3530,9 +4168,9 @@ static const char *kData132[] = { "c396f21619c7c15033cc6e8ebbcc8c5c5b23\n\n# tcId = 147\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d39b9e3f87809686f24109fbc718d6abbb09c278cf05a206adf21463e1170362\n\n# tcId = 148\n# Flipped bits 0 and 64 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = be301cbfb566720e22f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3\n\n# tcId = 149\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9ebf87809606f34109fbc718d6abbb09c278cf05a206adf21463e1170362\n\n# tcId = 150\n# Flipped bits 31 and 63 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301c3fb566728e23f166e24865c396f21619c7c15033cc6e8ebbcc8c5c5ba3\n\n# tcId = 151\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d29b9e3f87809606f34109fbc718d62bbb09c278cf05a206adf21463e1170362\n\n# tcId = 152\n# Flipped bits 63 and 127 in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = bf301cbfb566728e23f166e24865c316f21619c7c15033cc6e8ebbcc8c5c5ba3\n\n# tcId = 153\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = 2d6461c0787f69790cbef60438e7295444f63d8730fa5df9520deb9c1ee8fc9d\n\n# tcId = 154\n# all bits of tag flipped\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 40cfe3404a998df1dc0e991db79a3c690de9e6383eafcc339171443373a3a45c\n\n# tcId = 155\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = 0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 156\n# Tag changed to all zero\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 0000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 157\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 158\n# tag changed to all 1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 159\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = 521b1ebf0700160673c1897b4798562b3b8942f84f8522862d7294e3619783e2\n\n# tcId = 160\n# msbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = 3fb09c3f35e6f28ea371e662c8e543167296994741d0b34cee0e3b4c0cdcdb23\n\n# tcId = 161\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = \nresult = invalid\ntag = d39a9f3e86819787f24008fac619d7aaba08c379ce04a307acf31562e0160263\n\n# tcId = 162\n# lsbs changed in tag\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\ntag = be311dbeb467730f22f067e34964c297f31718c6c05132cd6f8fbacd8d5d5aa2\n\n[keySize = 256]\n[tagSize = 512]\n\n# tcId = 163\n# short key\nkey = 14d93759fc28f3319ab74b8167c974e800f032344dc2747ec0f4945061a47827\nmsg = \nresult = valid\ntag = 68934dbe948d9a77a5e0a92ed98254fa3b6c93c8bf5eeaa912b7dfdf762b37192c5d8523bcab9ad71b09bf96d8454188d001c7f2077eb641199f5731b9f94669\n\n# tcId = 164\n# short key\nkey = 9fa371f36fb273d514fd628cb938067a4bae32a19a1e045a7d6d7f6de3751cbf\nmsg = 311bbf722d322cd7a0710f480fc66518\nresult = valid\ntag = 16345f6a6ca6e78d4ccac30b48d76691d6442420efa113c15ef127b538b5b024018b7d2db4bc3ed3424251ab6b8b6c3cb108b0beda842dc3e68e63400287e5cd\n\n# tcId = 165\n# short key\nkey = 6313f1526bc220f20dde1e64ced8597279586d1e15aad05ad591d841b369284f\nmsg = f744fa3933e16d8bf524afaeb34c715653a9cfb01fa45fe1fb68e701fe1487ca\nresult = valid\ntag = b88d1ba03e2799200a447550d18e310697a57974f513df77eb07bbe315ba5fef397eeb81ad9071680bcc6c70f6b252ade35b4a4040279ec01b86e40b98770e39\n\n[keySize = 256]\n[tagSize = 256]\n\n# tcId = 166\n# short key\nkey = 1e225cafb90339bba1b24076d4206c3e79c355805d851682bc818baa4f5a7779\nmsg = \nresult = valid\ntag = 23d482a05c907eeb346ba98f83db0f63c2adfbd5b2940f33c7964c7f1799f180\n\n# tcId = 167\n# short key\nkey = 6fa353868c82e5deeedac7f09471a61bf749ab5498239e947e012eee3c82d7c4\nmsg = aeed3e4d4cb9bbb60d482e98c126c0f5\nresult = valid\ntag = 1cf9d2c9c1b55a45190b5beb590cd4cc95e3853df8aaf9f4fef9bbbbd72435ff\n\n# tcId = 168\n# short key\nkey = 186e248ad824e1eb93329a7fdcd565b6cb4eaf3f85b90b910777128d8c538d27\nmsg = 92ef9ff52f46eccc7e38b9ee19fd2de3b37726c8e6ce9e1b96db5dda4c317902\nresult = valid\ntag = d127b7385badf0c76f2b3d8aa9c722333592e01f462fedd35ec664a6f6d52d74\n\n[keySize = 520]\n[tagSize = 512]\n\n# tcId = 169\n# long key\nkey = dd1e0bdbb6b60862176484f3669da531455f1cd714f999c29f08b851055fee8d72186d376c236f4e16cba7a25cba879fb2753deca4459aaebc6f6de625d99af330\nmsg = \nresult = valid\ntag = 7e4f7d844b3ba0e025b66de7cc6227bc50d4e174930251bfff3df36c3900b5b76b00095a896d0f96842e37b6134df40760307699534d6670f138974ee1c58d94\n\n# tcId = 170\n# long key\nkey = 432b311ebcfd46ecfcd3cc706ebd05c787dfbe1855fdcfce8d50c9a00f72b65a8d42acec335b4e07d544c92fd7b1d38543ac6e0fc04c26d88de8dd974af69e24d7\nmsg = 36b1fbe8f1335e7c0399c24730906420\nresult = valid\ntag = 2cfb688f30b10534da9377a4b3fbee1dec161cb288ac8b758793838b45ab953979dadf27817f477c9ebf23cfdcbacb60b81038e08bc4fc3180bd2a1ee805976a\n\n# tcId = 171\n# long key\nkey = 17f720f09df5972af9b9c63e10043284608900d50b7955db3b4e2679cb4120be2c9b9e2aa1a5743eb519792822c326b4d890b5554d1cb0eb71081b7569a2f04df7\nmsg = 57167c2524a55289687b83a40d3a69bc90adc53ad247020b88897f9b95d1516d\nresult = valid\ntag = 4f70267b98fceb4f662901bd18fb4c81ac164281dd0ece43028a3c2a65ca213aedf1bd207f0939bd879bbe20fd09cdeb20246e6539766add08b3adc5143d2bd9\n\n[keySize = 520]\n[tagSize = 256]\n\n# tcId = 172\n# long key\nkey = 8a0c46eb8a2959e39865330079763341e7439dab149694ee57e0d61ec73d947e1d5301cd974e18a5e0d1cf0d2c37e8aadd9fd589d57ef32e47024a99bc3f70c077\nmsg = \nresult = valid\ntag = e1657f44bf84895e6db0810a2cca61a6e105e12ec006f0b5961020301b57744e\n\n# tcId = 173\n# long key\nkey = 2877ebb81f80334fd00516337446c5cf5ad4a3a2e197269e5b0ad1889dfe2b4b0aaa676fac55b36ce3affc7f1092ab89c53273a837bd5bc94d1a9d9e5b02e9856f\nmsg = ba448db88f154f775028fdecf9e6752d\nresult = valid\ntag = 33d5a2d1998a586849eebf8134728485fcfc71248f4a98e622f83b967844c40e\n\n# tcId = 174\n# long key\nkey = 21178e26bc28ffc27c06f762ba190a627075856d7ca6feab79ac63149b17126e34fd9e5590e0e90aac801df09505d8af2dd0a2703b352c573ac9d2cb063927f2af\nmsg = 7d5f1d6b993452b1b53a4375760d10a20d46a0ab9ec3943fc4b07a2ce735e731\nresult = valid\ntag = 88d579c2801905b818070ccebd2c7192f97bb3e7acdcaf613cecc74d0e41", "1232\n\n", }; -static const size_t kLen133 = 55755; +static const size_t kLen187 = 55755; -static const char *kData133[] = { +static const char *kData187[] = { "# Imported from Wycheproof's kwp_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: KWP\n# Generator version: 0.8r12\n\n[keySize = 128]\n\n# tcId = 1\nct = 8cd63fa6788aa5edfa753fc87d645a672b14107c3b4519e7\nkey = 6f67486d1e914419cb43c28509c7c1ea\nmsg = 8dc0632d92ee0be4f740028410b08270\nresult = valid\n\n# tcId = 2\nct = e8bac475d1429034b32f9bdeec09a37f9b3704028f1e0270\nkey = a0b17172bb296db7f5c869e9a36b5ce3\nmsg = 615dd022d607c910f20178cbdf42060f\nresult = valid\n\n# tcId = 3\nct = 4c8bcd601b508ef399f71b841294497a4493c4a0014c0103\nkey = 0e49d571c19b5250effd41d94bde39d6\nmsg = f25e4de8caca363fd5f29442eb147b55\nresult = valid\n\n# tcId = 4\n# wrapped key is longer than wrapping key\nct = 9e4510cc84c4bd7abab0a8a5d7f1e6ff3e6777ca2dff9be7e223652239fe57d8\nkey = e0e12959109103e30ae8b5684a22e662\nmsg = dbb0f2bb2be912a20430972d9842ce3fd3b928e573e1ac8e\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 5\n# wrapped key is longer than wrapping key\nct = 8fbf39ae583bd4efa7a3e8f7b86870b34766ae7d8923a8e97b0cd289ad98cacb\nkey = dd583d9f1059861430ec8b5d8a180e9b\nmsg = f2e34f356362a31b51d6e02bcd333c9e6170494ca5ff5487\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 6\n# wrapped key is longer than wrapping key\nct = df2fbe5fa86418edc7b5b04a4aea724aca17e88cedc84ca8b0b0f048e64590cb\nkey = faf5ccfae42b43cee2c5f0f3177a7c5d\nmsg = 4e02084833660c463830483b36dab866c64c8cf7429cac3d\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 7\n# wrapped key is longer than wrapping key\nct = 67f8edf57f84ea0a35b35511d67d3f299c9984b2c07d3809c3d7f5f45091f1a8fbb937ed447677f6\nkey = c2b9d23f2831ddcdeb456853d4014db9\nmsg = f4cfea98e58b939cc859554385cf3a6c7f8217f728efb431c964786de8274907\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 8\n# wrapped key is longer than wrapping key\nct = 60d55a22ba7dbd7d8f317388e01e6be561d15d29f85c566f1259aa7e7dc3d5d30e0ef5f4c6267553\nkey = 620a08f320cdedbf7ae551add348d95e\nmsg = cec34eaf8e67e1ce619ddfc309531c42f16033a7e2cbc4f5eb3a548164e9b291\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 9\n# wrapped key is longer than wrapping key\nct = d78a8291108f0f2d8be0ec10ec08240bf4d3021f0a5ed7faba0748db73762f34a0504bd373212df2\nkey = ed089ac274f8c7cea2415671a94b5e53\nmsg = 6065e41df14daeeefacac5daeb7674cdc9c1f686013b797153e80ef215893299\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 10\n# Round counter overflows 256\nct = 9341221aca1c647e2afc2bdd9cf4ed6e60058eb0a84cb3fc2daf3a87d9fad0a1f8268b27aaf7201d705e72f7e2240309ad98742094e3f1c99b7faa9ae181b441f5004b8bc93cdd4160d403d0884749a3c379d47c112a45788c05c2106c98f59758d393e04c880691b0e8683a12df7f876e1e1f68b4acbae9cc8310b34d59ccf4617cee72e845df1e0e32e5b4938f2923d55f1bb5156dd8c787401e6ef241ea4073d0a59ddfcd7a53db5d89b480b030cfb9084ea8479b964f090bb612d5251eee9ef8870a45f1e76fd24abdd9b350fe148b15a4cfeb032d57b5743b3548a7ce9eec8e21a31ce832530edfd1cffd9bb37369e6463c6b373ab60d80b0a2677e92e658f7daf2a5234b7312bf2d967cd0bc809e9be2f706ae63bd632fd611f161e48ee19677f3243aa0e91f6651a1cef62feff7a72eedf830bae1dc6d89e55ccb5e6f97889c6266f7d3f2eb0aea6c8c42200febccc5916825368adc87e04e835de06fd7bc2805c219e7f0b6252563f29969b1f30cfa1a8da4b90ae7534fb849d068a7e77de7360f8af173\nkey = b6121acad51038e11873aaa7e6c7be06\nmsg = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 11\n# wrapping small key\nct = a65959a600000000\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = \nresult = acceptable\nflags = SmallKey\n\n# tcId = 12\n# wrapping small key\nct = 09bcbab50b8dd45ad83412e2919030d3\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 4c\nresult = acceptable\nflags = SmallKey\n\n# tcId = 13\n# wrapping small key\nct = 0cbe852cdce4f0b5333366f446b2b1c5\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = be52\nresult = acceptable\nflags = SmallKey\n\n# tcId = 14\n# wrapping small key\nct = a9dc66e03435ab3d4f97ff66f2c911a3\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 2d5244\nresult = acceptable\nflags = SmallKey\n\n# tcId = 15\n# wrapping small key\nct = 1b970c8ecb4187447e60e6083da03086\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 6c3d3b4c\nresult = acceptable\nflags = SmallKey\n\n# tcId = 16\n# wrapping small key\nct = 0344f7b34ab8ef28aaa843f276b0b3d5\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 0412ab3ec6\nresult = acceptable\nflags = SmallKey\n\n# tcId = 17\n# wrapping small key\nct = 17356c7148334ca1a24aab7e82a66e18\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 8ae08938929c\nresult = acceptable\nflags = SmallKey\n\n# tcId = 18\n# wrapping small key\nct = 1db7510a55591a455d9f8167e6db3c88\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 7c8dfbb68d72af\nresult = acceptable\nflags = SmallKey\n\n# tcId = 19\n# wrapping small key\nct = 936fe58b629ea6ec158145218f2361c7\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 536f8f83b64771c1\nresult = acceptable\nflags = SmallKey\n\n# tcId = 20\n# wrapping small key\nct = 6787816804b3127d0ca4073f1dba5c4d3db1ec9c227e6556\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 8571f282b18b64ec5e\nresult = acceptable\nflags = SmallKey\n\n# tcId = 21\n# wrapping small key\nct = 34131c3bfcc48af15eea8672e52927b462f81d5ba0e6260f\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 8ada889862813e364c4d\nresult = acceptable\nflags = SmallKey\n\n# tcId = 22\n# wrapping small key\nct = 4d1ec9287cd4dd378b9aefee79d4ed35bcb98ad9fa9fe529\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = f9c56e8058758a5c7c2baa\nresult = acceptable\nflags = SmallKey\n\n# tcId = 23\n# wrapping small key\nct = 7209f5b6bd5d4916f4995d280e9aa89edd5e96e3c9283ad2\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 7c7dbc83fa62206a521ed4ad\nresult = acceptable\nflags = SmallKey\n\n# tcId = 24\n# wrapping small key\nct = d85a1efc6ab3a40948f723d9810a5deb019b3ce0208a0d94\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = a6614daf00df6d14f50388bad5\nresult = acceptable\nflags = SmallKey\n\n# tcId = 25\n# wrapping small key\nct = 43509b5df3688b6e44c1a994592f4c03da34712f886e63d5\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 450580a47d7008321496bfb82f48\nresult = acceptable\nflags = SmallKey\n\n# tcId = 26\n# wrapping small key\nct = 16e369351c40f220d3fb1197f35da652a3a40ca3b1e99bfb\nkey = 1abf4b7fa2bb62a78f09ddab04625dca\nmsg = 9efd21e13855eea8907afdcd8935f4\nresult = acceptable\nflags = SmallKey\n\n# tcId = 27\n# Modified IV\nct = 4cdd2962f23ec897d41d14c3f818516c055799185f459e2d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 28\n# Modified IV\nct = de895192c35ec58ee6e5614fd2b20a85f8e9c8234cdc5319\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 29\n# Modified IV\nct = 4a24069a050af7bbcf6c2160d54525e017e3ac1b3a2e71f0\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 30\n# Modified IV\nct = 6252ab0e688d0638df7d87ec5be3b2f9c0c245c0f0794012\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 31\n# Modified IV\nct = a2ed5982a604512d85d87630cd50705b1a70189b81575e3f\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 32\n# Modified IV\nct = fed7d02db4081728c55cc17f45f267117347e526f4231651\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 33\n# Modified IV\nct = ed37722b94b08b6a6f7663fe90acd81dc25f85abd2f65c06\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 34\n# Modified IV\nct = 0adb0f47b890efed426e7cf5dbd67d5cd3d9d4807c34bc7d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 35\n# Modified IV\nct = a0c51e687c46f342c78e3c59eee076a85312206a37213ac3\nkey ", "= 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 36\n# Modified IV\nct = 8ac142d100eab0808b5f34ed29650163db77ab281e6f1e58\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 37\n# Modified IV\nct = db345851a09bf92c35855c367c8787e5ab3ff16e9d8b0f3b\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 38\n# Modified IV\nct = a90cb672f232eb693a290523a10d8f988a18829a11cabd96\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 39\n# Modified IV\nct = c9b3a55603e490c450b49c8b79c9a169030e6985b6e95b54\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 40\n# Modified IV\nct = 1c90d7613c7e81e66d9374d72a8a6a0c40163fc69bccafb1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 41\n# Modified IV\nct = e381bb56d1354e40c01cb414118b9518934c9ad92663f5e8\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 42\n# Modified IV\nct = f2a87686a3baa37810eea23232e9b784f628b1c0b4a557a1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 43\n# Modified IV\nct = 36ef8fc13d0f1f5745e3939877b62b8ecba2f5f0b19f9e90\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 44\n# Modified IV\nct = 7255c4eacb4105a68095e9e5b5a4bd8f9623a0da5c6fc230\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 45\n# Modified IV\nct = ea26eec89a46ff1a628834c7247a8e4e45d8a8d3229e26cc\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 46\n# Modified IV\nct = 508593fa85a8effd27c8a225981978fcec6e992eb488c9c2\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 47\n# Modified IV\nct = b8a4cb22f15529864d4ced8e8abae69752a9045a084dfc3f\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 48\n# Modified IV\nct = a0a6bf5e47e89706932b1057b680c3c81dc4d9d0b4f9153b\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 49\n# Modified IV\nct = 11f3af4ed30e77520517c880f1d0c272a89a968dc697cb5a\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 50\n# Modified IV\nct = 6fc912a0bda73bacfa93db4002f18f349fa30f22f7a95ab9\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 51\n# Modified Padding\nct = 96518bcf3d24b1c6c3c6ed642a3336531563abaa9bc19873\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 52\n# Modified Padding\nct = eceb8904c71372a974dcf65e2ee2e8eac035953cf41bf31e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 53\n# Modified Padding\nct = e8e1f4d621dc0d10786823eefd73e1d98873900fff79cdcf\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 54\n# Modified Padding\nct = 5aae3ef6d59abbd1acfba77d5e660a176b45683165398912\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 55\n# Modified Padding\nct = fdf11a815beb61c33f293801c33e681e296782967ff6c56b\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 56\n# Modified Padding\nct = 62cd9fd59aa08666b6d0e5fb0ed60b3692e87e680ea1d3ea\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 57\n# Modified Padding\nct = 31a9c782cc94c6fcd26e0aa6ee327fd01c5b1997ec70e22c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 58\n# Modified Padding\nct = ab29c3f5a4822bd572e43fdf2c59c2dab20327b9a25dcb87\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 59\n# Modified Padding\nct = 078070742b07caa793dfcab4d1c09f8df6a99f494ed00ea4\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 60\n# RFC 3349 padding\nct = 3731038571c35f7dcc55e48892de353e54c079b89774bbfd\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\n\n# tcId = 61\n# Invalid encryption\nct = d85c6bfd092df1aeae5a548e47aa7681\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 62\n# padding too long\nct = 7a92427387f5587ee825d1ffa011c40286844ecdadce31cd9678338694ea2682\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 000000000000000000000000000000000000000000000000\nresult = invalid\n\n# tcId = 63\n# padding too long\nct = a437d354606ae752894feb62c8def7d17046d8e47f9aed755fba48b3a3009e3ff67d34e26a779064\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0000000000000000000000000000000000000000000000000000000000000000\nresult = invalid\n\n# tcId = 64\n# incorrectly encoded length\nct = e8d240d64f16d1522ae2ded42ced257dfec158ff2fe1467d\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 65\n# length = 2**32-1\nct = 6d1bfda356b7b954e7aaccc6df953322f75be95947b02b30\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 66\n# length = 2**32-1\nct = 17dbf878ef4076cfcaba5f81d7b123d7\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 67\n# length = 2**31-1\nct = 75c23e253478037802fae0f86af9c78d4e4d9be0c3bff89f\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 68\n# length = 2**31 + 16\nct = 55717658c6a35e15ee36c66cce91083b63091f51525c0b51\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 69\n# data is incorrectly padded\nct = 8ede88a52ccb8a6d617456955a9f04c94d87696125ded87eebe3e97e185496d9\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = ffffffffffffffffffffffffffffffffffffffffffffffff\nresult = invalid\n\n# tcId = 70\n# data is incorrectly padded\nct = 5b4a8f1abffa51676ac8b5ddf9366c12\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 71\n# length = 0\nct = 205cc6dd9592da0ebff6b4b48a0c450eeaeb11a60d33f387\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 72\n# RFC 3349 padding with incorrect size\nct = 908a68b0d2054e199220d37c34a2e136\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 73\n# length = 9\nct = f84bdb15045cee3a8a0f3ed2f07c1771\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 74\n# length = 16\nct = 7592b1ee6ee92c9467db366adcfa65bb\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 75\n# length = 2**31 + 8\nct = db93a1db3b5babc80a304d527682c1ef\nkey = 48a53c11ef2d727db7eb9a834b134ea9\nmsg = 0000000000000000\nresult = invalid\n\n[keySize = 192]\n\n# tcId = 76\nct = 5c117a678223cfe5ee691503061e7ab1e5f720e005171b32\nkey = f75a2f49a630c7dc91626b00ce029f0bd2981d7c74a93ebe\nmsg = 9adbc00c710b1101bdf6a4ed65b32d72\nresult = valid\n\n# tcId = 77\nct = 6a7f9e03b6f379c56da3a56d8f32eba515454a91fd417449\nkey = b713f6b7814f98894d7b153974684359f1460213eb74be68\nmsg = 78585f0c49922e82caf17ebc3721b4db\nresult = valid\n\n# tcId = 78\nct = 764097f5ee8236bc0d93bbcea139a652f4b211cc33a61ac9\nkey = 13ecf423211caa334ba6db37259a535c20de8ad10fc8c432\nmsg = 4fc75d0f221e22408a37e11265d49a05\nresult = valid\n\n# tcId = 79\nct = 04b83ec803a75bbcb2f87fc6f488a4ccc1827b412483070eed195b6f0048ccbe\nkey = 4417fbbea51bdd91818d74051957dd70e135c5cf3732bdf1\nmsg = f5357da9f8fd4a1190f36e9fa09a90fcf14d87d62332f1a5\nresult = valid\n\n# tcId = 80\nct = 46ab71f032cb1ccbcc7447a5183574268c0167a26a93fe8422bf284417aa93ea\nkey = b3f26d8a22fdd61f709841231fbde695b3f28dddced6d41e\nmsg = 0d0af955d2e3829cc3d643219b301e64e0510dfbc428119a\nresult = valid\n\n# tcId = 81\nct = 47ca298ee47b1b755a499129347e11e7a25754ccb6c2689e8eff270e98c81d18\nkey = f70cfb262c729a18206c8afd74356ec7e049d10b44a6e000", "\nmsg = 241cedfa64c4e7bec541a2eb4c368269e0f0ddebc58267ea\nresult = valid\n\n# tcId = 82\n# wrapped key is longer than wrapping key\nct = ecac4c91758e1ae7bb010c34f4c5f99a3d728b9fa92cb778d3fe80d777a20d3de85ef46e7a0c6a6a\nkey = 1639f9f81e53e2eeb677a249e5eced3af108971301601a7b\nmsg = ec3c6a1f1a9585327fe658490c74635e5300876da5846a629398984fb551d691\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 83\n# wrapped key is longer than wrapping key\nct = 39b7326a44eaed08bffbd4aeaf3e2c3f899c1fd049384ed7b3eb92b788c6449acd6385f0bb18cf28\nkey = 1f22d5658aa685b8ba8659dc342880d5b2399e6a815005b0\nmsg = 50be4c1b2f29a63f44d7fc63737f600f0194ea3fb36e173d2ddd19f218656380\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 84\n# wrapped key is longer than wrapping key\nct = 3d2e9f39c7b13e9585227c4344fbe596f92b002456616f137deacc6a8c941649ce294bb2695c1807\nkey = 3a2f4aa50441954bba5a1836294ce071f9296b23dbed6771\nmsg = 65da02ff21b483a1e39575490b4319e84ae0299f1f00b3859fbe2e74b3ec2aaf\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 85\n# Round counter overflows 256\nct = d6aacfb52c26baae78c2f54259a4e4168f817064344e2ba8fbfa7fae9f1fd69bd5bc5c1e20a6101b4a7119cbce028e25a9e93d29ee260c4e609baedee788411c2afe60218ce1b0d28b9c29b941251fdcbac3009d59040a0337b8b4a3a020c6d8f310cba63db046d8f36b64c9092e75cee463fc7692ef56bed395c4579da0ecb02129e45ad8a7f116aac6170204888e40693f017a6a0a7dd3962004e60db3a9b6c8b7614a467ccb799bce1ba83f5c0921f1e52bb3909bc0486ec0eaea736498f3ba520a519c3ddf491307958620b737613417b15b438b80b43189baa455031f5771502002ea170c767b33d247feebce62e606f2262537f85f18d1951cc75cedef291c6a501cb1778586249b58156eb8d7283a3f508ee8bcc1206d77bbd6892fe74b865bfc02a8f07223087a6c1e50a41b7cf5f6ee04bd07766b2e5b34c4a7666b0ce06f670e6434a59fb74e0df36c91d94e5e8b721e53e09b6f6504c5d515492a373fcc348a63122cc6e4716e0e1a543d038c6f7731199f691780a8a655cca6718e3dc56e815b3669\nkey = b6121acad51038e11873aaa7e6c7be06f93826b74fec0ea1\nmsg = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nflags = WeakWrapping\n\n# tcId = 86\n# wrapping small key\nct = a65959a600000000\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = \nresult = acceptable\nflags = SmallKey\n\n# tcId = 87\n# wrapping small key\nct = 52c7f388d0d4237afaa29f2b94723475\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = a3\nresult = acceptable\nflags = SmallKey\n\n# tcId = 88\n# wrapping small key\nct = 833431ce8799be69b36aafe3f38d9dac\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 594b\nresult = acceptable\nflags = SmallKey\n\n# tcId = 89\n# wrapping small key\nct = 31674f46b989f6ead582c70dedc8c6b9\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 72ab34\nresult = acceptable\nflags = SmallKey\n\n# tcId = 90\n# wrapping small key\nct = 80535172d2a498aa31601d70fdca9dea\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = d4d9460f\nresult = acceptable\nflags = SmallKey\n\n# tcId = 91\n# wrapping small key\nct = 56232300dd7b2a71d2328b6df47af8e3\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 643972e552\nresult = acceptable\nflags = SmallKey\n\n# tcId = 92\n# wrapping small key\nct = e27e08efe39adbbad8d300b87be2c258\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = f3cdb73d2561\nresult = acceptable\nflags = SmallKey\n\n# tcId = 93\n# wrapping small key\nct = 8f90942cdab33e58b24a23ad7efb7538\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 7b0b53b6429e14\nresult = acceptable\nflags = SmallKey\n\n# tcId = 94\n# wrapping small key\nct = 0ebaf23c858015d3bda5b8d908db6049\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 6b2393773e6d1378\nresult = acceptable\nflags = SmallKey\n\n# tcId = 95\n# wrapping small key\nct = d56f89977b8eff511158edad6b993007189e5a4b8c0e2faf\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 2c52d6639e769960e8\nresult = acceptable\nflags = SmallKey\n\n# tcId = 96\n# wrapping small key\nct = dd889475a76733849f59bed49a15d4315bdb5ba00dc63470\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 707c9356216d69c69048\nresult = acceptable\nflags = SmallKey\n\n# tcId = 97\n# wrapping small key\nct = 1a9b3369239b0f40a8dc5bd8d965caf7431445799337b99b\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 615f6fa79e1847e7359a8a\nresult = acceptable\nflags = SmallKey\n\n# tcId = 98\n# wrapping small key\nct = 5232f8f6679a17d3303b0bd72b06b56b5089e80372dc295b\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 7f5e999168ec60624426cbb1\nresult = acceptable\nflags = SmallKey\n\n# tcId = 99\n# wrapping small key\nct = e5544361c60980f3d38f2d8820a150f48f49ef3f9184b29f\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 3f93aaf4463775baf6c0c975ae\nresult = acceptable\nflags = SmallKey\n\n# tcId = 100\n# wrapping small key\nct = 55396065905915ec914b8d1efbf471e37d283fc2c1496b49\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = fefcf10c976309b2beb085771e50\nresult = acceptable\nflags = SmallKey\n\n# tcId = 101\n# wrapping small key\nct = d90376be302a24c541bd6d96094f0025e3d73888391b4306\nkey = 1abf4b7fa2bb62a78f09ddab04625dcacdd9e551d1a69b6b\nmsg = 6854354d0099f7eff740b0587140b3\nresult = acceptable\nflags = SmallKey\n\n# tcId = 102\n# Modified IV\nct = 24f5b27f9e4d7b645331719ea8f2b63841b2324e61ce13df\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 103\n# Modified IV\nct = 5b5221464c7e960b31c3d6e5784e66c69fa0fba8ae315d4e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 104\n# Modified IV\nct = d17e8392b0d7e064f22770b7f38ffcdc572cf7694da9648c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 105\n# Modified IV\nct = 2f9ba2d81292a2494845ac8589f1a44affdd3d09044fc81c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 106\n# Modified IV\nct = 9258882e1812b1793c0cc08d6adc9fe9597d9270b1f0c3ef\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 107\n# Modified IV\nct = 8bdfb51ff4664220de3d87e06882c748490af56c0c5ef789\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 108\n# Modified IV\nct = 20a5b0fc789e8422e09a3128a10b6b0bca6aba2bde496aa6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 109\n# Modified IV\nct = fdfde90ee4681372c85fc5875dd482cef85bf69dfe57e71c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 110\n# Modified IV\nct = 5f2ba1d716b8fdee03f3fc5cc4c7ea35836bb3c073f02dc9\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 111\n# Modified IV\nct = f241ce804660d60397789d4c67f4e252b55838144b199355\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 112\n# Modified IV\nct = a4f5b4f3ef5a6939949fe6dfd755f327ffa604dc417ea495\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 113\n# Modified IV\nct = 4e23f48297480d1a4afc85fc97d6d69f861f518bc00fe7c3\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 114\n# Modified IV\nct = d9f0de809d4f6ef5815a3e6bfb09b11f0b51b6180caac98c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 115\n# Modified IV\nct =", @@ -3541,18 +4179,18 @@ static const char *kData133[] = { "\nct = 60107f4c60c04c987c7c5810130303bd83fbc35d924f4482\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 189\n# Modified IV\nct = 38e8d42ffc1a26278c6fad73bd699f207251f6e1b622bf92\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 190\n# Modified IV\nct = c23f1fdbe6c021a04bfc386b55c8fe911481f82edf308d79\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 191\n# Modified IV\nct = 7cc6af073f8d21e26713222ba609c91b69fc5faee9870eb7\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 192\n# Modified IV\nct = e7e5d96c0bc89dc23bff610db5ccfb5de8f97b74100b3492\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 193\n# Modified IV\nct = 18e77b855e322457a4942209f97acaed1fe6af0aea80c454\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 194\n# Modified IV\nct = 0fcc89e543fae40b914510c9064307b70ef12de4c8750874\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 195\n# Modified IV\nct = f795cf444efd94bd6a561d8cb0703ee0e979c073aa66fdaa\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 196\n# Modified IV\nct = bb5d2e4082140258d6cb26a74af7c10f985e4a84dcd5d8d6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 197\n# Modified IV\nct = 47819be55567934b165a6e93ca25d3900103bedb86eab148\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 198\n# Modified IV\nct = 41b70a974d3fce94feb94b7b01d959541cd120f879cf60e1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 199\n# Modified IV\nct = 86b9f13e871ecb5aa009c80a31693336e59ae1ed3c8d7aaf\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 200\n# Modified IV\nct = b17c3957d85127aae1ae0a04096b19eb2e0f67583772182b\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 201\n# Modified IV\nct = 2ca5c335226e3e171fde0f3401ba6835fa389f30f5288699\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 202\n# Modified IV\nct = 5b8ba944f4a961d6e4c5121279ea4d3fcd555b05e75da4ff\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 203\n# Modified IV\nct = 7fd3ad3aee0545da1ed3a54d5a198a2c76cf8290c011c042\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 204\n# Modified IV\nct = a24e94c12b2e6b776c8febe9179521beae0cfbd507d358b4\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 205\n# Modified IV\nct = 9395b071fa3d9908b2e1b349bf7cd6a1cfc86b979c8c73cd\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 206\n# Modified IV\nct = 1eb452770bc0f26a3576b604bf5ac72f714fc468c357eba7\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 207\n# Modified IV\nct = b42bcb4161f40b30f3d2f740f43e441d3c9a39613914f1c6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 208\n# Modified IV\nct = f3d76dd320e5f1b3f85b8f73a9ebcfabfb8346daafaf36e6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 209\n# Modified IV\nct = b8e26164496942f44f16751096fb47952ec478bb288e72a1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 210\n# Modified IV\nct = fa783b3aca0ec1e677378f23ebe937776fa590ecc6b01392\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 211\n# Modified IV\nct = 8b011408049eab81cc185796b9636982c1ad28e940e5c35ab1219434c23e8c59\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 212\n# Modified IV\nct = 08db2f06aa2400d4cc1113b1c9e3ba1b39e3e26a84918f9266796c426c166428\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 213\n# Modified IV\nct = 3114404be000ee167b65dd3cfae3b10c50dffe1df864b5e52a2805f0c80021c0\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 214\n# Modified IV\nct = 405ae5bdeff8b05d28ea55900b8e81dc789d532ec3fc457730819e762172f751\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 215\n# Modified IV\nct = 7c19e66d21c0f1409ee6f03a36ab6ba532349e2567200b95d7f5012b2b7e5d33\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 216\n# Modified IV\nct = 955ac67d6e496b9b93a4dda8f6e65e668f1326b256ee146a7647ba18deee7986\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 217\n# Modified IV\nct = c8600aa18be27279493fd68c84130c8bc328b0f6821e01e892b6c2dc1c005270\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 218\n# Modified IV\nct = 492566e0dc539e234b08b95fb23594a6d14f59fa4367799495c2e7f2993135ec\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 219\n# Modified IV\nct = 0b0aa97121bb8e367b8e80e6518a786ab686f4d6b8a075c3abe534698ec462e09fba981615d43ebd\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 220\n# Modified IV\nct = aa6eaa5b94f39247b9581c4d3120ed71e6a427eb51b2439f245d1762041dcf50741fc53fa7a95579\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 221\n# Modified IV\nct = 5cef33853f321f523951a27e41a68dfca418d5b8560484d3f233c5a45e7b69e7a6e4893e690cde6e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 222\n# Modified IV\nct = 62e120f39799ab7633fde15836b89b28a8ced5ecdc421939d8657e41fa1ea49a54da75b51b8dd3d8\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 223\n# Modified IV\nct = 9dc7bc15dfbc7da1a6f74bc4dfbc70091f2a180dbb76f9a6e9e18bcc3c11d2b56bed36c58c7dbc65\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 224\n# Modified IV\nct = e7ee36c6321ba0a30906b25e087fb0cabd74fbb0905b015ccc246cc90e5684605898a5a77983e897\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce", "3497352690\nresult = invalid\n\n# tcId = 225\n# Modified IV\nct = 75c636384c4210ea46422f31a5622d001e8978c2b0fbbb79ce3d7c4b46bb3c7c2c9d4182571ae515\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 226\n# Modified IV\nct = b0116ad877c745d609f7df14b9225a2d69ab56f2e74077e34607b4e75a2883442864f17ca19af259\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 227\n# Modified Padding\nct = 64956d333265a8f2547756feab37b81f97786a4ebf491f13\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 228\n# Modified Padding\nct = 6ee239e916d27f8a8931740fda92657f98dfc68e5e3984da\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 229\n# Modified Padding\nct = 40c990f89aa7c76400655fd4167b04cbe24145c8c800dc35\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 230\n# Modified Padding\nct = f2a900684f167b9246b1345b8a94e711d9b6ac439f3ef3e8\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 231\n# Modified Padding\nct = cd7053a854fcc2f476c20539360ce47e767563723c11d211\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 232\n# Modified Padding\nct = ffa557ea4960669ccbcf59007a24de06755475c1cfef56da\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae37\nresult = invalid\n\n# tcId = 233\n# Modified Padding\nct = 8672fdfb252c0dc9e3bc39b0fe76b9b08cf87b65c0f28ee3\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 234\n# Modified Padding\nct = fcc2c7a6d2944e7d02ca08e49a7ceb77ee3f5966509b528e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 235\n# Modified Padding\nct = 57bc3a4c7544fe76b92740608a1023bb70227856cbdb8ada\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070\nresult = invalid\n\n# tcId = 236\n# Modified Padding\nct = 9220a6eb9c77a3d6374647afa7a3effb99be7e1f7bafeca8a1bbd93e8adcca6e570484008ee674ca\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 237\n# Modified Padding\nct = 94654a58be6bb6b946ef40ac7b8f1d19e2edff7c2c8c54eb7b2cbb3227c4f9df2cb317795beea413\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 238\n# Modified Padding\nct = 1ae49d65e69886f0f47cbbeb50f07ab5163983916a738a0d8f538c59c8a6e1e9ad229b27418259a7\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce3497352690\nresult = invalid\n\n# tcId = 239\n# RFC 3349 padding\nct = ac1a774a5de27e4f9c356e4f62deaf8b7eeee6bcafafd895\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\n\n# tcId = 240\n# Invalid encryption\nct = b3941437f55e7cbc3f88050aff703967\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 241\n# padding too long\nct = 86175acf19ad0b7ac60d1fe4bb7850635e7ec6f8a314f85b6dd3d8f9349ea38d\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 000000000000000000000000000000000000000000000000\nresult = invalid\n\n# tcId = 242\n# padding too long\nct = 791f088847a76731e0d56b9b2dcb28bf9f091a9725790e0a64fc8e7cb3ad50f380297a98e3b1c33e\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0000000000000000000000000000000000000000000000000000000000000000\nresult = invalid\n\n# tcId = 243\n# incorrectly encoded length\nct = 868c34495bd3d7b4e2c1861e7fcbbdb372099488dd96c9ea\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 244\n# length = 2**32-1\nct = 4a8b4aeaa713469bfd9bf88d4072379fc858e40b24b0bebe\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 245\n# length = 2**32-1\nct = c210aa3b5fbf5eac97e68d98d7727f38\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 246\n# length = 2**31-1\nct = e0ebd376e050cc9027b76dfc38ee2c6ae2808cecf480a560\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 247\n# length = 2**31 + 16\nct = 23a693e211c08ab9b222c2ede2db18f437e22917fdff8032\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 248\n# data is incorrectly padded\nct = 003f2916fea6827e01199028d3dc4e03889113f97b1860cc242e5a0f28a0f159\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = ffffffffffffffffffffffffffffffffffffffffffffffff\nresult = invalid\n\n# tcId = 249\n# data is incorrectly padded\nct = 5c25a170d5225a6d66e117c691b37383\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 250\n# length = 0\nct = df9ef924eb59634be5b27cabd33d72bd6be6e01e4672ab05\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 00000000000000000000000000000000\nresult = invalid\n\n# tcId = 251\n# RFC 3349 padding with incorrect size\nct = e6e66fad359a7b63a977788acd297121\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 252\n# length = 9\nct = 76b88ecda760b1af80703036185fc476\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 253\n# length = 16\nct = fd101943f4ab7c38ec68c75d4b3193dc\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0000000000000000\nresult = invalid\n\n# tcId = 254\n# length = 2**31 + 8\nct = 1793a3a9bd146726edbcb9589f20e849\nkey = 48a53c11ef2d727db7eb9a834b134ea9602273aca929702eb2c31d96a58c9be2\nmsg = 0000000000000000\nresult = invalid\n\n", }; -static const size_t kLen134 = 36748; +static const size_t kLen188 = 36748; -static const char *kData134[] = { +static const char *kData188[] = { "# Imported from Wycheproof's kw_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: KW\n# Generator version: 0.8r12\n\n[keySize = 128]\n\n# tcId = 1\nct = 9de453ced5d4ab46a5601708eeefefb5e593e6ae8e86b26b\nkey = 6f67486d1e914419cb43c28509c7c1ea\nmsg = 8dc0632d92ee0be4f740028410b08270\nresult = valid\n\n# tcId = 2\nct = 8c3aba85cc0ae1ae10b36658b068f595baf8caafb745ef3c\nkey = a0b17172bb296db7f5c869e9a36b5ce3\nmsg = 615dd022d607c910f20178cbdf42060f\nresult = valid\n\n# tcId = 3\nct = 1de093654826f18fcd0f3fd499416ff22ed75ee12fe0b624\nkey = 0e49d571c19b5250effd41d94bde39d6\nmsg = f25e4de8caca363fd5f29442eb147b55\nresult = valid\n\n# tcId = 4\n# wrapped key is longer than wrapping key\nct = 9c3ddc23827b7b3c13105f9e8b11523baccdfb6c8b7e7825496e7a840bd32aec\nkey = e0e12959109103e30ae8b5684a22e662\nmsg = dbb0f2bb2be912a20430972d9842ce3fd3b928e573e1ac8e\nresult = valid\n\n# tcId = 5\n# wrapped key is longer than wrapping key\nct = afb744aaf746dcc0b57f8b378c404cbe877f44cf3d45140d60814eda3f541f01\nkey = dd583d9f1059861430ec8b5d8a180e9b\nmsg = f2e34f356362a31b51d6e02bcd333c9e6170494ca5ff5487\nresult = valid\n\n# tcId = 6\n# wrapped key is longer than wrapping key\nct = cff98cd64cb51ab99b81aee82cee4274d0df3e1b6a4943d39236ea989846d0cc\nkey = faf5ccfae42b43cee2c5f0f3177a7c5d\nmsg = 4e02084833660c463830483b36dab866c64c8cf7429cac3d\nresult = valid\n\n# tcId = 7\n# wrapped key is longer than wrapping key\nct = 58dcfb0e7ec4d3bc8003418d865fbd520c6b24b2bde35b1be5b1c5ff32a130f33d035e5932616083\nkey = c2b9d23f2831ddcdeb456853d4014db9\nmsg = f4cfea98e58b939cc859554385cf3a6c7f8217f728efb431c964786de8274907\nresult = valid\n\n# tcId = 8\n# wrapped key is longer than wrapping key\nct = 4ee47bd68d418586c447a39111e2ec1502ff0f1726ea91c5d97370409d89b8e66e889b638ac40ced\nkey = 620a08f320cdedbf7ae551add348d95e\nmsg = cec34eaf8e67e1ce619ddfc309531c42f16033a7e2cbc4f5eb3a548164e9b291\nresult = valid\n\n# tcId = 9\n# wrapped key is longer than wrapping key\nct = d3b093fd822ce454ebc251c6f21fa71c3858ee7e623ecbfbbf887398a30b40c55d0565c7a15e4015\nkey = ed089ac274f8c7cea2415671a94b5e53\nmsg = 6065e41df14daeeefacac5daeb7674cdc9c1f686013b797153e80ef215893299\nresult = valid\n\n# tcId = 10\n# Round counter overflows 256\nct = 222deadde6efb760cae42fa188310e0c07e7d557529766444a9efb330907d42f0dd8f3d17b3a38bf40d68c095a9cce19daf907bf2c92f1e59b18b277ff0397fc50f45f582db936aa8afb943de01b58abfdc81daef4e038c99e4c1eb3ee447464bb8f89a4ea81e56556cc26c72883c06a7fe850d04347d68bbadc4a06775030676db8cc34aeb07e39c7f059c2bff76a7f2baf076749004ef7189f887f89029f88c5c1d0f5ee62320b423048e2ad8186e63be23c553f5576a40d967e8b527ccd783c41abc64bea1aec8a76deb3e9c9a6656756e1dac38bd25ff008888a5591af763fd73f5addd749794817070990484654a46ef442adaeacab14d12daaf87bcb91661a21593717d9b93529d813ea5fc812d708c0d8e9b68122d9f5e6267cde363780a45d07e4caa5bf14f2334f25b9d177632bb80a82894aa47b6f360b2da1138dedd4331f077c900554c7a68b5d154980bb3517ac20a78a51f6f21e42b2c4c960d31cbd22bd610819182c5e456ba7d7e903f5e60f6e0c4cc014feb4f81973ce48ad6f4dab8da51eb7\nkey = 31cacbb17d6dbbecae40727c5048fe0c\nmsg = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 11\n# empty keys cannot be wrapped\nct = a6a6a6a6a6a6a6a6\nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = \nresult = invalid\n\n# tcId = 12\n# keys of size 8 byte cannot be wrapped\nct = dc26fb6911d71971df0356d6bb9ed6e6\nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 13\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 00\nresult = invalid\n\n# tcId = 14\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 0001\nresult = invalid\n\n# tcId = 15\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 000102\nresult = invalid\n\n# tcId = 16\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 00010203\nresult = invalid\n\n# tcId = 17\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 0001020304\nresult = invalid\n\n# tcId = 18\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 000102030405\nresult = invalid\n\n# tcId = 19\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 00010203040506\nresult = invalid\n\n# tcId = 20\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495\nmsg = 000102030405060708090a0b0c0d0e0f10111213\nresult = invalid\n\n# tcId = 21\n# invalid size of wrapped key\nct = \nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 22\n# invalid size of wrapped key\nct = 9f\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 23\n# invalid size of wrapped key\nct = dc9e9580\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 24\n# invalid size of wrapped key\nct = b9b282d138693000\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 25\n# invalid size of wrapped key\nct = 0efc635b2d61e244056b9d4591ca6b\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 26\n# invalid size of wrapped key\nct = 4a305dae087b0d24d62af41831338f33ae\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 27\n# invalid size of wrapped key\nct = 82cb927097cf31ea4affea440b0d8ca6a240b900\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = \nresult = invalid\n\n# tcId = 28\n# bytes appended to wrapped key\nct = 9790ab51fbcb850df6764e011ae97c85785bed2633aea66500\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\n\n# tcId = 29\n# Incorrect IV\nct = 0aac329ccd513edbdd6367df67999eaac9e7b51984c4d38d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 30\n# Incorrect IV\nct = 5a55dc429749ca49bb4ab01d966b19ea9a9e1402e6ab2962\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 31\n# Incorrect IV\nct = 45f533f6072f640eb7e1e512d56072085567f4ad6012a97a\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 32\n# Incorrect IV\nct = 84f284565df47c409107f7a0a71bc370a8ed4489d414b9e9\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 33\n# Incorrect IV\nct = 3941c366554fc896e9fe52f02493ca03d439eb17c236146d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 34\n# Incorrect IV\nct = 45c9d42363d981d086a972728e130a42f5dd90bda562a85a\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 35\n# Incorrect IV\nct = 037d17859519d6c0728a9eb6e64113e86919decabd3bbb88\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 36\n# Incorrect IV\nct = 1ad10af7f6c042b267a0c7bc4d25d27c003deb50e2cc566a\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 37\n# Incorrect IV\nct = 630c571b7fb8647ac5360a255f9f5d3645795ac45285cbaa\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 38\n# Incorrect IV\nct = 16db553e467d4029d0fea62b2c440e5df6c6591f0497a99d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 39\n# Incorrect IV\nct = 097991090a156047d4784b757f262e12ce57e13a3d5d286c\nkey = 4f710eb6b5e28703becfc3dc52", "fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 40\n# Incorrect IV\nct = 3957c338b750a3285eb7b65c9cfe77053dd7d8149f42caa1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 41\n# RFC 3394\nct = 1fa68b0a8112b447aef34bd8fb5a7b829d3e862371d2cfe5\nkey = 000102030405060708090a0b0c0d0e0f\nmsg = 00112233445566778899aabbccddeeff\nresult = valid\n\n[keySize = 192]\n\n# tcId = 42\nct = 00be1caddfd5ad7697877017795f9cee4bce5a61687a6126\nkey = f75a2f49a630c7dc91626b00ce029f0bd2981d7c74a93ebe\nmsg = 9adbc00c710b1101bdf6a4ed65b32d72\nresult = valid\n\n# tcId = 43\nct = 54e7f278b5a1fb4c31a0d79ac1f615edd910bf22015a0668\nkey = b713f6b7814f98894d7b153974684359f1460213eb74be68\nmsg = 78585f0c49922e82caf17ebc3721b4db\nresult = valid\n\n# tcId = 44\nct = 510455bd9c078ac1f07bb3752cbd04e421b0dd635190fa62\nkey = 13ecf423211caa334ba6db37259a535c20de8ad10fc8c432\nmsg = 4fc75d0f221e22408a37e11265d49a05\nresult = valid\n\n# tcId = 45\nct = 880da5b410f913ad72cc93f46344f1152165bdea14664fd2d3afbd87b8cc5cfd\nkey = 4417fbbea51bdd91818d74051957dd70e135c5cf3732bdf1\nmsg = f5357da9f8fd4a1190f36e9fa09a90fcf14d87d62332f1a5\nresult = valid\n\n# tcId = 46\nct = 27654cf6a63d6004ae83da54c2e5d7b5fad20878f350087ddd17ac44a2be868f\nkey = b3f26d8a22fdd61f709841231fbde695b3f28dddced6d41e\nmsg = 0d0af955d2e3829cc3d643219b301e64e0510dfbc428119a\nresult = valid\n\n# tcId = 47\nct = ad7ca66ad4664f43e4dd09296a6e6f02d5af4408f225c0abeb0d9b76c8d1e982\nkey = f70cfb262c729a18206c8afd74356ec7e049d10b44a6e000\nmsg = 241cedfa64c4e7bec541a2eb4c368269e0f0ddebc58267ea\nresult = valid\n\n# tcId = 48\n# wrapped key is longer than wrapping key\nct = e245c90a6b46caece94f47117d608331958c8f75f531ebcdc902c0213d9105f2155af07daa62d132\nkey = 1639f9f81e53e2eeb677a249e5eced3af108971301601a7b\nmsg = ec3c6a1f1a9585327fe658490c74635e5300876da5846a629398984fb551d691\nresult = valid\n\n# tcId = 49\n# wrapped key is longer than wrapping key\nct = 8a32b9f207ae5aaedb7e8a0d945107412c1bd06999bc5ac83c1f958dfb77ebdcf9d98c60dbd4650a\nkey = 1f22d5658aa685b8ba8659dc342880d5b2399e6a815005b0\nmsg = 50be4c1b2f29a63f44d7fc63737f600f0194ea3fb36e173d2ddd19f218656380\nresult = valid\n\n# tcId = 50\n# wrapped key is longer than wrapping key\nct = 4a5842b10d2db96ea1039ef4785ce722555b3751a9b6dd39126ad363378c72320d83ea7adb81615a\nkey = 3a2f4aa50441954bba5a1836294ce071f9296b23dbed6771\nmsg = 65da02ff21b483a1e39575490b4319e84ae0299f1f00b3859fbe2e74b3ec2aaf\nresult = valid\n\n# tcId = 51\n# Round counter overflows 256\nct = e2192598e6124f2791b2751f930958435bb1d02e98aa1e09781bba0b159435db659fa73fa310111704692c68e16ddf4be06022c52fe9dba6279aad1aeb814125d0ddf33f31e58e625af32305050cfea390d8782d32caac558889ca8e641908208da6976542b40dbd090178e2a6812a436c18a5e891ac8083176ace1ddfee4d382856a59c80c643ecd5c1ab68c66b2b8984ce6e0e386f6554a9cb91d363bb4accf028878ec20b8b2e37214f7b12dbcd78fb38f711a90fe262c78491b9058354e27b34fc92ef0d7028594cb08259f86b54cb1d317ec55f2ef2ab7e8b141671f8bcb1a90bb7d82bc8cb4fb02c9ce430ef4ae0dc847e91e7d4fb463eb9dd87fc9dc9568f3a4ef504d74c134dcb60ca01b36ce10cb467268ea297c0518a50d12cc025cfeea1381ddd7dd63e4ac94890a0eae9dbd8db244625a3c8af2e1aff6a8112c4d3d98e8263588ee1dd9063b709b8ec00474c4ea413a802b8cde814e7b3731410809ed000060fb7b9b0bf8509ef17515f333e868b188ea16445f380b3a7d42774f6456cdf724246fa\nkey = 31cacbb17d6dbbecae40727c5048fe0c01bc53b23ab63502\nmsg = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 52\n# empty keys cannot be wrapped\nct = a6a6a6a6a6a6a6a6\nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = \nresult = invalid\n\n# tcId = 53\n# keys of size 8 byte cannot be wrapped\nct = 38d8238cdb0d9a2da28d6d56194f2e78\nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 0001020304050607\nresult = invalid\n\n# tcId = 54\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 00\nresult = invalid\n\n# tcId = 55\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 0001\nresult = invalid\n\n# tcId = 56\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 000102\nresult = invalid\n\n# tcId = 57\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 00010203\nresult = invalid\n\n# tcId = 58\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 0001020304\nresult = invalid\n\n# tcId = 59\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 000102030405\nresult = invalid\n\n# tcId = 60\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 00010203040506\nresult = invalid\n\n# tcId = 61\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76\nmsg = 000102030405060708090a0b0c0d0e0f10111213\nresult = invalid\n\n# tcId = 62\n# invalid size of wrapped key\nct = \nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 63\n# invalid size of wrapped key\nct = 9f\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 64\n# invalid size of wrapped key\nct = dc9e9580\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 65\n# invalid size of wrapped key\nct = b9b282d138693000\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 66\n# invalid size of wrapped key\nct = 0efc635b2d61e244056b9d4591ca6b\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 67\n# invalid size of wrapped key\nct = 4a305dae087b0d24d62af41831338f33ae\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 68\n# invalid size of wrapped key\nct = 82cb927097cf31ea4affea440b0d8ca6a240b900\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = \nresult = invalid\n\n# tcId = 69\n# bytes appended to wrapped key\nct = 55dfb2f7e0c1ea04fead897c451c0505921dc47f308c491700\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd97\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\n\n# tcId = 70\n# Incorrect IV\nct = 9b1593fd7d4fe25a660bbc1976ea4ab68bcc53f848a8eb9d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 71\n# Incorrect IV\nct = e7edb847fa91e2deded726edf3ab93da91151697425fee28\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 72\n# Incorrect IV\nct = 1b51a7c033c1efb5ee2994259c40f03bb57d8cc09e507e6e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 73\n# Incorrect IV\nct = c40b614a5062f5fd049c5379b3e8141614c2da97893589fb\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 74\n# Incorrect IV\nct = d7575ef02df54b3086eb49035eeafbce0e08336e89b35ab0\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 75\n# Incorrect IV\nct = 0d617f1c12485a35917d2a941e949d2fdbf03a346889b850\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 76\n# Incorrect IV\nct = c7df34729174db2e83ee16c6de74d5eb9766715fad049b40\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a8", "28cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 77\n# Incorrect IV\nct = c3ed38d6f9ccb9bf3c56bb3176f00d3ce9887521f8d4c70b\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 78\n# Incorrect IV\nct = 6582b5f4652744b0537e97e7cdae0f443130140dbaea604c\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 79\n# Incorrect IV\nct = fc9b9bdf25f2b48ad79934c8d34897cdbf4c846f8cb4b11d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 80\n# Incorrect IV\nct = fc23c7f4fe20aa81105efc1a7105a5316b23399ac792c824\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 81\n# Incorrect IV\nct = 37b4a261b96bcec9cc93eef5b2fbbbe84634f978c5893dda\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 82\n# Incorrect IV\nct = 1831109847d17d010bfcd93fb46f3150cdafd52733db74c221b034fe8e1552c0\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 83\n# Incorrect IV\nct = 2b2b89c3c6b2db4903877ad4622ca33f3a3cb7e6701d1340e6afc0fdab7dbd72\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 84\n# Incorrect IV\nct = 3c6903f37da57161af6706050a2ed747cd55344d869189fd49d2536ff948129d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 85\n# Incorrect IV\nct = 8a8dc8b131c6b968b60c1dd819a655392d1a96d6cafa48e30fb1146f096229c6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 86\n# Incorrect IV\nct = 303e0b3602d514a7d52edba3306d7383e8999e7c652a510335a8949efb42eb66\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 87\n# Incorrect IV\nct = 319befbf2ddbb475723fb2fa30f2ae7fc1ceb1e6f361715eca7209608873c7fc\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 88\n# Incorrect IV\nct = 9b3e440341c5da131559959db6b3553a534691162f4f009327bf2c21d6fe5ada\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 89\n# Incorrect IV\nct = eba6cc0959e6a56339b141629840add80f4565656dc687a3b996960c994dfd26\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 90\n# Incorrect IV\nct = b703b6cf4587709353c7e4004d3da61ce5f5deaf7163ca9d6158dde919e0ac34\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 91\n# Incorrect IV\nct = 72549d52d6f4ff912d833c74136d90634ce8afa4f84412bbee8074084d4cecff\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 92\n# Incorrect IV\nct = 1337c8bd6c8a5dd43aba8d298864ffe76ad6ea909f3488157a15e6c46acf2214\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 93\n# Incorrect IV\nct = 4aaffaca5fe85814d040aa2a306ba4d1d44746cfe46c978aa057b53fd25316c1\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 94\n# RFC 3394\nct = 96778b25ae6ca435f92b5b97c050aed2468ab8a17ad84e5d\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 00112233445566778899aabbccddeeff\nresult = valid\n\n# tcId = 95\n# RFC 3394\nct = 031d33264e15d33268f24ec260743edce1c6c7ddee725a936ba814915c6762d2\nkey = 000102030405060708090a0b0c0d0e0f1011121314151617\nmsg = 00112233445566778899aabbccddeeff0001020304050607\nresult = valid\n\n[keySize = 256]\n\n# tcId = 96\nct = 940b1c580e0c7233a791b0f192438d2eace14214cee455b7\nkey = fce0429c610658ef8e7cfb0154c51de2239a8a317f5af5b6714f985fb5c4d75c\nmsg = 287326b5ed0078e7ca0164d748f667e7\nresult = valid\n\n# tcId = 97\nct = 939b3389336fea4a9751bf014ef18011323090e8a0500bc4\nkey = 0dda6da5123e2c37c6fa16ba0d334cd01acd652f8994211751dfab4faac2fc22\nmsg = b40b6828729b456322a8d065abc0d081\nresult = valid\n\n# tcId = 98\nct = 59ee8e5198861237f682edec6ba906526c016d4d935942bd\nkey = d6925914cd06308f81ad91e23073593d99d4e50351b20eb2a8d1a1ac4ced6588\nmsg = 037b27b3dc95b19d15bd4091e320bfe1\nresult = valid\n\n# tcId = 99\nct = 1ab53a065d8f776a08b33e51383071b6f154612116655137bd3b7ec29b70fd56\nkey = 07518a82cbc8da1dcec55f3763a206d277487abd03cedd0b8bef9ee2fb157121\nmsg = faa4664d79fce3c7d2fdd462f6c1c423c2f8e6b69be2e071\nresult = valid\n\n# tcId = 100\nct = a1bf8e73e3fa1db759f0ab2ab0b1ca6f2c85b63d83e25f7a0b5293d0a216a2b7\nkey = ea46991d4e71f53dd624e7fe7fde11944a7c5942d232369b8065d42b8cd2dde1\nmsg = dffc5cf1dd5411d015d84601fa38df5effe885c7f26a4825\nresult = valid\n\n# tcId = 101\nct = 27308a0e1a6c0a1d15d6174ab7d68675207b615df16fcf7a3c69b25f551cca9f\nkey = fdcfa902c6f222f527af84da533b14b52e2615da3a89d1d35708b0cd49f60d87\nmsg = 966b07047354966a703e79607b556032f4f596b7f9206f05\nresult = valid\n\n# tcId = 102\nct = 7155ee932b0358d98182a23f7f427c774ab340a4757d0b6a63facd3de90578438cf03201c3f88057\nkey = 38e1b1d075d9d852b9a6c01c8ff6965af01bac457a4e339ae3e1d7b2ffacc0cd\nmsg = 80ad6820f1c90981e2ca42b817a345c1179d0a11d8e23a8adc0505e13d87295a\nresult = valid\n\n# tcId = 103\nct = f20b9b553bc0847529f8d4379fa909211e68249bd429f436c615c4c4a5d9f1a1968f0b89c5237b30\nkey = c641f1689d81caa8ba37d895272240664054ed974cfffc40e6c5c0cad1b916c7\nmsg = 3fd0ba19955e46749f54d88e99d080b7339d588fe612ec0f4021ca3ca2104270\nresult = valid\n\n# tcId = 104\nct = 2811716854a214aecdd318c6670b9b2a7511713c9a0c0fa805230ff05cf84af795dd72f6c1a44512\nkey = aa0ab9d68ed4a04e723f81b44c0c88d0bcde7a80cfd476eb4b8836d9aa01ec4c\nmsg = 57faa8766f6d6a0aa1cf643f857c150df5b31303b50af480e21c4b5e8c8a15d5\nresult = valid\n\n# tcId = 105\n# Round counter overflows 256\nct = 5322bc62bd8379abbb75f69688b8f00e31962b8f9ae1e89771952d8a2a749e1352ec33b5435a674271b314760ab9f753b16726185ec7d319ac60531355344c1d53c7903000a8039eb40f70564a0ad3f41b2355ea5dfa6a1d46392f1d106a5da569bfb0493bf7c12dff04bafeae377df4bb47cd440b6f60fbab2a54a98551b76273e02cac8d7be9f2343d3abb2a23af1c91a7011c67a7907260116b67d510aabe5c7ca46c1c20f77106c45966583b3e4ed799a47ee19bb4223209265c2b1ac8183a678ff43bc9a3470a50b9ee4d10f60674268d72c68be003a0d9dd6849aba836fe8a1792b81c90e12945bfe1f27a9c6b2af66a063cdb7721a7f23fb30afdbd8b18db377dd1697f157be81c1578d08b066c71b0c5ca7feecac1cdd938cf9ad525f74844660908194b28e54eddb158f6e4c921b811d90db71a92ff872db2250dcc3f847fc752b66d77e33c85084d3fa53b4f30503d2a06e6cabb9033d59fc1dc15e32f19846a039b91597b0ba3141a7d9717630062170117b2131dab77406e9ed7d66b2c754d849c60\nkey = 31cacbb17d6dbbecae40727c5048fe0c01bc53b23ab635025cbac1ecf52ca495\nmsg = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 106\n# empty keys cannot be wrapped\nct = a6a6a6a6a6a6a6a6\nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = \nresult = invalid\n\n# tcId = 107\n# keys of size 8 byte cannot be wrapped\nct = 181ba6a3a4392469e3de98ddbbdd2432\nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 000102030", "4050607\nresult = invalid\n\n# tcId = 108\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 00\nresult = invalid\n\n# tcId = 109\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 0001\nresult = invalid\n\n# tcId = 110\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 000102\nresult = invalid\n\n# tcId = 111\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 00010203\nresult = invalid\n\n# tcId = 112\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 0001020304\nresult = invalid\n\n# tcId = 113\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 000102030405\nresult = invalid\n\n# tcId = 114\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 00010203040506\nresult = invalid\n\n# tcId = 115\n# wrapped key size must be divisible by 8\nct = \nkey = 574957151fc2afe0fa3dc7a9a7da6495398f18ea0d8eed76a51aac96038ad692\nmsg = 000102030405060708090a0b0c0d0e0f10111213\nresult = invalid\n\n# tcId = 116\n# invalid size of wrapped key\nct = \nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 117\n# invalid size of wrapped key\nct = 9f\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 118\n# invalid size of wrapped key\nct = dc9e9580\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 119\n# invalid size of wrapped key\nct = b9b282d138693000\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 120\n# invalid size of wrapped key\nct = 0efc635b2d61e244056b9d4591ca6b\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 121\n# invalid size of wrapped key\nct = 4a305dae087b0d24d62af41831338f33ae\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 122\n# invalid size of wrapped key\nct = 82cb927097cf31ea4affea440b0d8ca6a240b900\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = \nresult = invalid\n\n# tcId = 123\n# bytes appended to wrapped key\nct = 7dfbd7cf6158d75bb5900b3bf1e3871003402a6508b1912800\nkey = fe60fc8df7d9f4ebb5416ca4e82182f7e9923a746110fd978e3bd2defc1c10d7\nmsg = 000102030405060708090a0b0c0d0e0f\nresult = invalid\n\n# tcId = 124\n# Incorrect IV\nct = a417671bc62a23c7a65543092124024df72c048d8db330c7\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 125\n# Incorrect IV\nct = 9518d0f99d7a73ed4a502b449c14c285971b0e6177ce0eca\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 126\n# Incorrect IV\nct = f3511f0491bd74ae1defb5307f0e18db864b57b5c404d428\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 127\n# Incorrect IV\nct = 6c03ce779259661c43d41d5d0e45687f874353bba516c73e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 128\n# Incorrect IV\nct = 8df01969a11c87026535bfccf72b1d064c86ecc7e5227157\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 129\n# Incorrect IV\nct = 8ed1cde228d9c8d046dca65c7a27aef2edf8ae90c705d1e9\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 130\n# Incorrect IV\nct = d69b3e34e9de38d44de1998992362a6fa1f696b5acab3f10\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 131\n# Incorrect IV\nct = 67865122af3294b8da0588775125cbd6dc19d5e5cab97b6d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 132\n# Incorrect IV\nct = 9f0fa52363dd55df472d867e6faf5da8eb204a1d6d497030\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 133\n# Incorrect IV\nct = c399f999c96a4204325e7f08d6a4de256faf21ec2c007ddf\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 134\n# Incorrect IV\nct = 282082264a87dc35ce1cc5b9931b77d80d82fcacc0927f85\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 135\n# Incorrect IV\nct = c192c90b83003ca96744498014b6ad6bedda837955269819\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5\nresult = invalid\n\n# tcId = 136\n# Incorrect IV\nct = 30a983cd9e69d561acc95c42b252aba4185f8392f2e6c935c8eb105af8082e34\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 137\n# Incorrect IV\nct = 4de9a639b799630b45b49e28dbfc44dabb9843ee588a8cff286b8d5fbd7b32ee\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 138\n# Incorrect IV\nct = d915b2cdfb769d9d82259dc3d124646bbf972b83efd4c2eae9b9f751073f78d6\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 139\n# Incorrect IV\nct = 117d653f480b69fce564f1fe99572492945189ed5af789ce05a2651baf90bb5e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 140\n# Incorrect IV\nct = 8226d07a2f919e24ada1081c69a75520be895e3a2bda9b805d9747773ddeaa38\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 141\n# Incorrect IV\nct = b0a74345bedf8865348daf45d054b99ce515ea8be136270d1cf71e1cfa7aa4a2\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 142\n# Incorrect IV\nct = a261db77f17f7ec736d1a8be16e5f9ae432fe2a17012e5a6f07c5426a9f0ca59\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 143\n# Incorrect IV\nct = c53acb5e096b54548e1385b2ff18eaef68d235c95b0194e74a2383d3a7a530dc\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 144\n# Incorrect IV\nct = faef482d99ebb180e5bc5e3cf775ba292c2a3b6c44aa4a21ad400906f11af392\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 145\n# Incorrect IV\nct = 73a450b63b07b3aece9d1ae5bf097a3dd3fcf73e3ec2f1bd8fc3b5586cb9bd73\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 146\n# Incorrect IV\nct = d34b6ee184d387c9aa4b2d180ae0a89498014e55fe8e416be4f826fcf7d56522\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 147\n# Incorrect IV\nct = 2af823d1602803740bfa9040c2c4e769a5b6de919d403cfba9ad360f63af1113\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1\nresult = invalid\n\n# tcId = 148\n# I", "ncorrect IV\nct = dd78ebd3091c55a5da5b24504200f7fadd1b3ac6ad35f814f733e603c13936245d69d83f262f6b1e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 149\n# Incorrect IV\nct = 3d8338eae7de322399e1d1b4a3df54326b242b563612ea4b27da22a041d3c80966911bc009911761\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 150\n# Incorrect IV\nct = d04bf75cadd3b5f099c34b27a91e64a8f2dbcf08e8c5c1c9f07a777eeb805d5d0e8c5c01afc43944\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 151\n# Incorrect IV\nct = be0c5d193b61c5137a8fd8a6d7d1ed8f0fa28cec516f544697c12add4f8f4d5cfca65edeb1019974\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 152\n# Incorrect IV\nct = a83ebcbeb2be9d6807b5cfc31c89849d1343dd4eb22e5bfe9e2b2b3790ad8900601f1f5d54fd472f\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 153\n# Incorrect IV\nct = 416221485a6cb98ad1342ea9a12926a9a133ead8bd919323fe789bb8f89a4fcaf81e1be54f9d358e\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 154\n# Incorrect IV\nct = bf6a53286fac48e7f25d89b7056b27aa917d5b54c0d3171dff369f7249153bf09da5891eb4dc2d88\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 155\n# Incorrect IV\nct = 99d517a1321bb633b0d5f3afda2372d3abf68b41d13cbfdffc78f173b88bc4b97efcab2b2904788d\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 156\n# Incorrect IV\nct = d92456bc77a268ef71cba76064a1b772d1fee2ae4f0ee3bb932a2adb2b031796b9eadb51753f2868\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 157\n# Incorrect IV\nct = 5bb54630ab8d73a040f0f87e70e263d1aeb2358bcdc0dce6994d0d874452bbd8741b7ec1d59d8298\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 158\n# Incorrect IV\nct = 4581d6536039db1b23da50c648777e90c82d6128bb92e28b2974bae1141543a19a1592fda1fbd61f\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 159\n# Incorrect IV\nct = d35bc67e62064c34f48150999ba30ded475d8c75978f45737320f23edaaa7a40d7803fc61add34a4\nkey = 4f710eb6b5e28703becfc3dc52fa8bc1dd44a4a6d38a84b4f94e89ac32d987e7\nmsg = a828cbda9b5ff0ae374f84fa01d070a5f0a17a0c462be4f1acce34973526908c\nresult = invalid\n\n# tcId = 160\n# RFC 3394\nct = 64e8c3f9ce0f5ba263e9777905818a2a93c8191e7d6e8ae7\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 00112233445566778899aabbccddeeff\nresult = valid\n\n# tcId = 161\n# RFC 3394\nct = a8f9bc1612c68b3ff6e6f4fbe30e71e4769c8b80a32cb8958cd5d17d6b254da1\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 00112233445566778899aabbccddeeff0001020304050607\nresult = valid\n\n# tcId = 162\n# RFC 3394\nct = 28c9f404c4b810f4cbccb35cfb87f8263f5786e2d80ed326cbc7f0e71a99f43bfb988b9b7a02dd21\nkey = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 00112233445566778899aabbccddeeff000102030405060708090a0b0c0d0e0f\nresult = valid\n\n", }; -static const size_t kLen135 = 94020; +static const size_t kLen189 = 94020; -static const char *kData135[] = { +static const char *kData189[] = { "# Imported from Wycheproof's primality_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: PrimalityTest\n# Generator version: 0.8rc17\n\n\n# tcId = 1\n# small non prime integer\nresult = invalid\nvalue = ff\n\n# tcId = 2\n# small non prime integer\nresult = invalid\nvalue = 00\n\n# tcId = 3\n# small non prime integer\nresult = invalid\nvalue = 01\n\n# tcId = 4\n# Non-prime Mersenne number that is pseudoprime to base 2\nresult = invalid\nvalue = 07ffffffffffffffff\n\n# tcId = 5\n# Non-prime Mersenne number that is pseudoprime to base 2\nresult = invalid\nvalue = 7fffffffffffffffff\n\n# tcId = 6\n# Non-prime Fermat number\nresult = invalid\nvalue = 0100000000000000000000000000000001\n\n# tcId = 7\n# Non-prime Fermat number\nresult = invalid\nvalue = 010000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 8\n# Non-prime Fermat number\nresult = invalid\nvalue = 0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 9\n# pseudoprime square derived from Wiefrich prime\nresult = invalid\nvalue = 123a99\n\n# tcId = 10\n# pseudoprime square derived from Wiefrich prime\nresult = invalid\nvalue = 00bc18d1\n\n# tcId = 11\n# square\nresult = invalid\nvalue = 04\n\n# tcId = 12\n# square\nresult = invalid\nvalue = 09\n\n# tcId = 13\n# square\nresult = invalid\nvalue = 010201\n\n# tcId = 14\n# square\nresult = invalid\nvalue = 0f2ad9\n\n# tcId = 15\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 01f51f3fee3b\n\n# tcId = 16\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 032907381cdf\n\n# tcId = 17\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 0136a352b2c8c1\n\n# tcId = 18\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 023c3db80e80e53bd1\n\n# tcId = 19\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 0504e8e504fd585e79193ca1\n\n# tcId = 20\n# G. Jaeschke: \"On strong pseudoprimes to several bases\", Math o. comp. v.61, p\n# 915-926\nresult = invalid\nvalue = 00b7d84161830e3f6f2231a7a1\n\n# tcId = 21\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 4c6092d9a7a5462b34e5\n\n# tcId = 22\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 22c9a603ee84bb9c4cad\n\n# tcId = 23\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 437ae92817f9fc85b7e5\n\n# tcId = 24\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 0190e262098f0d746505\n\n# tcId = 25\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 027a5f7ca7b29ee74d5525\n\n# tcId = 26\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 008d60a89f3f36cb1fd495\n\n# tcId = 27\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 02be6951adc5b22410a5fd\n\n# tcId = 28\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 0292a0068ebb0ed3251f55\n\n# tcId = 29\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 750b703e68cb957ab415\n\n# tcId = 30\n# A strong pseudoprimes to 12 or more bases from\n# https://arxiv.org/pdf/1509.00864v1.pdf\nresult = invalid\nvalue = 02d0facc78aeeb89f5b299\n\n# tcId = 31\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Maple\nresult = invalid\nvalue = 09bdc1c98b9b\n\n# tcId = 32\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Maple\nresult = invalid\nvalue = 0ffb48c934842b\n\n# tcId = 33\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Maple\nresult = invalid\nvalue = 18444fdb12afb7\n\n# tcId = 34\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Mathematica 2.0\nresult = invalid\nvalue = 08e4f37e51\n\n# tcId = 35\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Mathematica 2.0\nresult = invalid\nvalue = 179d55b600e7f1\n\n# tcId = 36\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Axioms primality test\nresult = invalid\nvalue = 085270bd76a142abc3037d1aab3b\n\n# tcId = 37\n# Richard G.E. Pinch, \"Some primality testing algorithms\" a counter example for\n# Axioms primality test\nresult = invalid\nvalue = 02cb78fe3f36c4f5f05dbe92b82798d5fc18f2bfaaa388ef\n\n# tcId = 38\n# A composite q that was acceptied by Gnu Crypto.\n# http://www.iacr.org/archive/pkc2005/33860010/33860010.pdf\nresult = invalid\nvalue = 4682f52f0b54308d315b2fbec25065506c77be95912b137bc6eecffad8a299b631c55ce068702b1b3e4ce50958994c289b148fb298a8c603a0959cb0ba5ad4bcba278cf4c87e0ff85a62a25c40849662c53d0f81cf9e4431d8c391586629260e558db473997db20108278b1ae374089140d93bc2c5a808ad3aaf212f60bfc93cc0c788149dcd82f7ab\n\n# tcId = 39\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00f67307e54779cfe9120bf862afc5466c5d6d0783d12df5215c0c981c51e4bfc098e9afd574f51b18c820259b692ec0bf7c9d6e56e9bb99fbd3b7ecc4082146a9d7a5b7bc6519d476c4a9975d9c3e3b12bee45b7accb07a6a68ea583ac2523ef32ee6d01bc766b59c43031f9c6980c9b4317da6825be9f7c5db03283d04c13323\nflags = WorstCaseMillerRabin\n\n# tcId = 40\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00c1d00b32d63e3ea4fb69ab6b9dee40a17fada46c122e52a53fecd3fe613303f51c07871dc0b5d8d8c1705b484de6bdb7f442efecd7d9f59dc36e495f72905c7619bc4d3706283774e704a3adad7d6c1be42ddeffc2ca5b1c0e31b58ed606f16dc14676e60ecff42ae33e503621e232ba449e91e3a9909e80a8318610aea3b7cf\nflags = WorstCaseMillerRabin\n\n# tcId = 41\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01c2faadef91d43c9ab1320020e08e2ec3c34012bd0db94a1175170dc5aec26897e867d0b7a7273119fbe1115f02875b522566016f69f319ad5485e7458fcf50205d22ba765cc586a6037be987b6832c46227df19cd8ce0641794b60b73fbdd3c104870ae9bdf0194e772c985536e860b90b7fa3eb205af6b224413f5813836abb\nflags = WorstCaseMillerRabin\n\n# tcId = 42\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0109fddd44575367466c67aaa921047b367515c9aa579eb60728034ad2d56f10eb01cfadb3ba0abde99f348bc3c70559bc24551b85937ca4c886abc0826cc1c310f14393652c1b4994953881bd2d81de0f2a280839829543f429bc41bf3c6db120bb150173e2707f36d1f76318249851f4fedc39e36aaaca48686de03e6d256973\nflags = WorstCaseMillerRabin\n\n# tcId = 43\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00ffd0847cdda5a4fdfd2345bc731f1bc77843478950d33b2830ef0caf8deffdbe6309fe61fb67dded6659e433f30363339dbcc7c0832593f33c24a8b8f0e28038cb6edeed58ae765e6884ac0b66b5218cc758e6247269d24be9f91865d33c105219ffbce00c6c2d6391448643bcf5138268f510258f638b90a6c8b53bfc121759\nflags = WorstCaseMillerRabin\n\n# tcId = 44\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0118d077827c6db85bc61d53063edf5676d6ac65b611d836eed07ee7e1d15c02d999a3eb78ce662edaf457f0f7d9c0a0305acc1faec4170400f0610a797de50ebfb08fd0a5da77144a1e0236e2bc6d8d2a6a719e59df071367cd61275f372e23b1c0187d87d15bda5f71f4705b1c3aaaa8ad951d20cee93274b151f3f9a55bd693\nflags = WorstCaseMillerRabin\n\n# tcId = 45\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01c09377e15f53b1329b6e8a08bf0f94da27dd29c89be74544d705173a0bdd410935e186dd95ac113732674fe08585690ebe9f749a116a8c64e1b4a281ef0cb28bc70b1639bc1352ff5777783bd72e3b8495c1494ae11fb32bdaba8c80870a3de71c0c27f07983e97500c0ec0321b86c679c53ae7f8c76ddbf6a9cc3ff63e45023\nflags = WorstCaseMillerRabin\n\n# tcId = 46\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00f35cac3bb3c7cf5e4e50162f4ca889ac7b875f4aac08c5a2433600e9bc64db6c9895aaccf3ee98783ee2cfd8a5e448b265bbc4cda6cb80d487c7967d5a6724fae1ffd27c70f579e62b49f29819c6221d7659fa9364e8e37795d88611506b552a20533f1f6446a35b41a986d304fdd7a39f484331b4fbf242f95b80788cff39cd\nflags = WorstCaseMiller", "Rabin\n\n# tcId = 47\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01e9df6f069f5984c080087127f90437f2d38f19385b3592d17a5f23603ec6315c36a88d2012e85eca62a983de7ef27673c605155b5647311840cf8887be8267fbc01cec3f7e0467d5e9a812e5dca577cc8ac93971c84f8cea94637c60c0bfe5d7f4b4f950e60ad077941190afaa905d6d5d570c9b4dab98c32c7abc42346f894d\nflags = WorstCaseMillerRabin\n\n# tcId = 48\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00c5286502dda772fc22d43b0a2f46823777a91f580f3a1261c47be8e2010a5ad9395e2c036b32813dcdaad33c8f2f4a522593e31ae55ef05c8df8ed58636ac1b9db2b205797d39343e0868ff02bef46d18736bedc6f527730da8594d45d0447e7c7f0e8ca12b285b88aea5e343264874ac22038f5821bd96519d49caf45184f97\nflags = WorstCaseMillerRabin\n\n# tcId = 49\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01c29fe8b7e63795218563774685b9fe85eada73691a6420c38f0e9f2f802e89c77ae78716924e4efb5e4c639ca98ddb0c9e35cbc6313196b3327672527404b6da8ff7813915702fb7fa254c1cdc167a34170da57606ccff876ca0ce5e920f443e389fc9d0c071b908c6675b6a9f5903d6d22ad490e6476a7e13adcaf988663b3b\nflags = WorstCaseMillerRabin\n\n# tcId = 50\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01e8648f8abce82efb0afa9861c96c428f690c5fe33b9c9d47f97198542c982e607fd9700f876159ea404983f4eecbaf2a73b262085da4b7b5de8f6e8ca0b712f5e89c0e8f024033879f858f814275a3ea5543fd539e74f5e099769d0d726ebd8bc74bda6e2f8ffabbb7d043f7818cd8d531180a827731fac59f45b2af35d273f9\nflags = WorstCaseMillerRabin\n\n# tcId = 51\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00cedc5db464312d6f1ecf53a40bde07ae0d5540ef75a4802ff469142270049dbba2b74e4ece7340d8eb99bac1a3d6f0b52ebb41794d3cd4e4a588431879ff81818abc50bca5e686a06d48461b425be62d3c064321429e346960163f897d21b362dc72f306a6865cfb9c8c5682cc7fcd7dc6ac4202e8d070729ef9e3b526236c71\nflags = WorstCaseMillerRabin\n\n# tcId = 52\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0093ec9e6681f1bc1d6534add99d97e0d907828996bb3d7b481f3ceaefbe8f3fdf15698302ce26feb84c08994079c9f368af8171faf76801fe6dfdaecd587fa0edc751d64ff7e9aa73fb7aa51a8469379bac38e9d7941e0bbdcf658633daea40738e81f5605198b04fe8fd49646da4e98c2282a8041c25bb9894252412472294f9\nflags = WorstCaseMillerRabin\n\n# tcId = 53\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0129fffd0bf1827f2847f45bd490d5423f67d87eb8254535d57078707e19f2ca5ca10602c5eca552fbdc77e30592b7498254f901cad02e0bf59802f5582cbb3059a1979a5e5311855807b1cbeff86a651dbf3818c3b6cf50092c9b744c4831873d1d0d8c23f23b39517ce435a257e5026cfa0be280672e1bba3074b2cdc6474a37\nflags = WorstCaseMillerRabin\n\n# tcId = 54\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 017232b942eedc8a0df14f5c1ad4e099f192b242b7d3dff09c50cecfe636c72c6c8ba1c65dde4396282e1a1c823b6d5d9c0c9068b39e202dcba26a9d35a00b7bb6bede272820fbbba503bc1866c6ae183d8b50e28555a921121929862ce87ea4ddde8f9d6ff2e17a8ee7cf9d306faa0815a4d46e8dfd4b7ea538b7399cc1c06c1f\nflags = WorstCaseMillerRabin\n\n# tcId = 55\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00d3768b43c242fa7ac1de856dc7bd413b79d544bb8d38677bc9f44aa116ac5525c3e7fcf2fb2c1d3de61844931f47646b4c5f7de226031c925acbe57f1cd292fec7e7d4fd25afa128704ffd8da910ef18961e081e88d40bc37582b087f1b1f39fe4d23a03ec6b869c76fa3aed7a3606c469069c4fa1d4ff1c6112da16ba9dcf97\nflags = WorstCaseMillerRabin\n\n# tcId = 56\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 011b5119e5c68a710158c36d414597b4e1ccff332d1b437a4d2da2d2269ad2b626fde79e3ba7ed92128e5feaa87556f18ca6937b5a88f4738608d6bb6aacaf4fb719d67561d66dba9690009bcdbea2db4ee48d575722cbafbf1e487bab1c62ba0cde30a34620c7733b3e13d8b27fa035115680fb81016d1ca777b8a2bb7c399a47\nflags = WorstCaseMillerRabin\n\n# tcId = 57\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 008e9ee596ea83d06e1a9a4c3b75fc67f3c01de737be4dcdc18f1d10e322df48e455546ac8ac810129dbcb0fbf568987033cadef9d051f6032c8dca2804fc8d8d6e79f5d767963e4b6d72ac29d98d2520c29c8e69ffa59164d6a1e4cb55b7fcc60c7cb274da264203839873ec2f85f4ae377eeb6189e031b17e8603a01ef877b3f\nflags = WorstCaseMillerRabin\n\n# tcId = 58\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00879d1e0bc0538cd9025110cec61a034305c8fdea2b9709ba80b0c45891e7ffc69c05285f4680b95b5882ad04210342314d3ab465ee1209d0690613a09bf7df0d48de18a7200e09e8b7944e748413ad64057fee2daacd099dcbb19920429cf9776d939c27c74c3adc8c41f1001f98d5293e018b1dde228abc6e79092331804bdb\nflags = WorstCaseMillerRabin\n\n# tcId = 59\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00a14d02b57eb643499b92b797687a69aa809fc6c5b56be581de2f8668d38936c9921a16c921a18ae91bff15ab595897416ebbbde977244dbab4779d47bccfec14b1bdb255597bb9bb70e9372fc9afe475b2f73754daf575ef2dd565dfb4216208141fa99df428417d84fff2c54b1fba037a4237bb17b07ddac0f39209f83f8541\nflags = WorstCaseMillerRabin\n\n# tcId = 60\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00d11e471371b5ce0473a80367ce1b0baeb21d8f8ddfebf1116f3b3721247ec85f6e2786467b63743af0885e69c59d674d2b1a4b655ab15d8003be755fabd56f60ad3a7d2a5edbe942663b882e8c1d9aab7250a45b93feae3f092e8819d5cc2c0eee2cee0c6a098a40331aa12a0efc384e518036d382e4e231de3cf644e8aa8b97\nflags = WorstCaseMillerRabin\n\n# tcId = 61\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01fe65939e5a1c520be98522b1ebbd40e4c030adf0677c1878b1b0a58b72873eff6f58712e377457ef467bdbb4666e2f8a4733a13a065aa01e3f5f0cc0fbff0e8a2eb2d8d43b9f2a4931d107315943fa7e1d304f98838903897cd42ab948f7c5ce31a9323a35bdc0cae10eebccb5f318a1239f9b9609d45387805524d67e216477\nflags = WorstCaseMillerRabin\n\n# tcId = 62\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00c24248b5f6e52e0ce8c9068ba2b5839489d1a4849feb751b627e12d13722fd5a00cf4597e63c9bfd1a275b68489539f2b0bef36a09504d7539d0e1a346bc0dc5fa2c65c4c23b771a9946ef5bda403dcd27f496dc02233c05d7d7dc73f6438169a0bdc510bad2ca105d84c2c8bbf2a44c4d7d4d0ead980c13bda71a945d1f3f01\nflags = WorstCaseMillerRabin\n\n# tcId = 63\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 00ab0ef4c1c3be6b7bb39ab0c8a1ffb2c12f8a2fb6c85ea1a8893f452dae161a8decbbc6a84ddc2068bf9df927c0f68a95fff1af8aa9eddd80b0c373b7ea750def2f6df54c0a7e50c16bded071b8d1df6687264e496316be5fcf5f9ab73f5c39b61a876441fb3f467205c92a864d97205032660d6eb2cee3ebfca9649295f6fc95\nflags = WorstCaseMillerRabin\n\n# tcId = 64\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01878ec4f236498bbf2320c89679639394b03dda157a9901f2e07486e64f1bb52f6b4823db13786296a71d6e65ad6a17308e46ddbb2608774eab3df41221eec799fc13ec95b567450abfbae8aa04f3c6361df3a1c01028b83560018b729b5924ee5f03f1306267eea55ab65a95591b105810a50111c9041d20b3ddd389e8ded20f\nflags = WorstCaseMillerRabin\n\n# tcId = 65\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01602a125e7578a82e23051dd12ce12be44f2becfccbd13c2ee18ae1e391356786315832fe9fa6dd5488c83b4f560a5a4b9d9daae4faf0b9b21075fa1b470c7d984b2b43cfca22bc36ec305e52fb4b897445024f2ee536164a5a9a4201db4d9247d4e28e193ad3c62657a91b23727804e8f4bca40691eb41f17c68ab65bb8dd2a5\nflags = WorstCaseMillerRabin\n\n# tcId = 66\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0109a25eac262687f28e560e73bd95be9894bf2a0006dc217e97547064d29be5fae521312fcbdd2949520961abd90b5a2ebcf55780f0d14ebda3c17825089183fee844a3ba0d132cf3db13ebb8f42905bf24374ac29a7b68f93f76dbce3942d4b1dbd91c611d24251b374bd29ae153cb9e23177115dc7003894269328d960cbbc9\nflags = WorstCaseMillerRabin\n\n# tcId = 67\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01962b71c4824f2072f59c73cedfa26a49bd976bba7014005b6feecfc61c90caeeaa05ca8954219165f073bcdb73770846c97383ad1d47f0cf656830388fa5847ab9f542e26226d3e9c2a90bdc23819333bd13803f7520272e4cfb80b5c54c92dbc2936ac75f426babec5b49db6a64cd6eee14ecff0402506eabffc8bb11ec6c93\nflags = WorstCaseMillerRabin\n\n# tcId = 68\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 0102134c13210c561b22c8f2549e0a1786fb85900e3c69c20905cb46a3f633b7128656ba1644cb6bbfa1b5b0c5a5bed69a7802a543cefceb2132e0db7c596e51b88e62185f3815fdd40e7db9d1aed0b0f135b09c4d90e81fcd4ea7a8e7c150147bb2f0fab2d8a0128f25e1e498813f6dc26722a73a441d6e9ba4f488d96ee6d399\nflags = WorstCaseMillerRabin\n\n# tcId = 69\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 01ecee4b07f4311afce14524ab060a72a7198499342f099f681dd6b8a366bc9550a7ddd3288273ef59f62c5daa55c9c4726c78f08c20e0d9a74208db52f732377bbd8ca8f8f1d336bda6bb2defab66506c0db04bf0d", "d6f7179f52cfe9c5c91179de1c03eab017d7ff867478e45386955c7a5a744e7f8dacf738c80352a99226777\nflags = WorstCaseMillerRabin\n\n# tcId = 70\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 019fd1a5266cb6e8dfcff2b755624ec26413d25cf53a9d4341ff5c7b0b4e06e8246e6e1063e185b05d90f38637ca69c298d6a834e9aeb06e02afd001897c1fb097c905445b2e6d27750cef01f40d6030f0328eee55241137afead4f8d358d0be0655782a60265f0b9aa30b275a32b60bdb252c95d8d69b68e8a1e07c2374029bcd\nflags = WorstCaseMillerRabin\n\n# tcId = 71\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 32fa78d5eb67eb14a53de388e9d03ae6ebeb7ae017dbae8f594b95f82f6ec380d5162f6f498d0cb61bb14d7ae54fa1b427c2a1d819133161576864a86d039200cb22c5d68716fd0e2b8f021cf25e08506d4ce285536bc6a074edb6d9b4a9dc01fd79eda19efd3b168eac045b6a4edc4c880de430dadc5dd3f32886b88d320505f5f0b064e46be0f1e31c57dd160e89738a4f6897975875564f20f82ecd4cc0db\nflags = WorstCaseMillerRabin\n\n# tcId = 72\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 5954649e58b4eea73bf1738957727ed4f356fd14891d95b81c7cd40a9ae4b9f1a807fc859d4d419e9a2178a369ae734cebf3b6b9b7069570515a94b5609585625a7aab4e2ff05566be39860b1c2e41910a07b46a555299a573c50b82572a8e40d70cd5949c0c5488582cc2ca544265e1e48ec5501fe611ee65de54946f4543ddd94f5d2c100fad681b6390924e3dbee62bf78133bb2ae6d1592fa5c4b0873635\nflags = WorstCaseMillerRabin\n\n# tcId = 73\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 282ca88061946bcd2fa15fecd98e61505b4c98079e5ffd08e9797059673150435ed47f6d94311c9df4ceadce2e13679b4eb1e7120f9f19d7ac393cc090d1885c88136ec24d085ace42e92ab049d8cdf963d8ba7b93b25e3c720367fa9d7d3905eb460c6922f53866fe439bb96f6d5213e66ede6239512bf0c2253ae23c3ff9915dbee4eaa576395e2d6986d40151cd8fe4c9b4d990ba17ec4bcdf6660459858d\nflags = WorstCaseMillerRabin\n\n# tcId = 74\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 2161895b72aff5d2a865dac7e95cabaf7a28010da0dfb075f9b25c189821c99c1bb599d47d6a688254401511cfad26f1d93f254a3be2752a70f7859acad5e6f741848bfefe449072365616be7251781063e8f8934b59f1826341ebd0839dcf72b1735e21f35301313c683d28fb637f6f93453f575330f74e2a0d661ed5fe54816f8cd38b162d5e769c0bf94dfe83e25b6c05b7705a477ebf52ff4deb6bec6aad\nflags = WorstCaseMillerRabin\n\n# tcId = 75\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 71f7dff1a6a0fd66d5228398a7ff1707ed9f83b9b8c660ae57ee4dd40de7493cec1540e50b4586fdda98ee538e6264fb72f51682bb7bb5305285c287f4577023b8350a84fb088005e36121d9d137b16c4528b4a8a3934db88fd27128733b5f9ea78bbaf239c93bd9b6b4b1fb683e2e2ea911eb4da824b5650f186a7304031b62fc145a9a20a269079ba598dbd183f29a2f35a46eb05276b8ac99a8dc72d76151\nflags = WorstCaseMillerRabin\n\n# tcId = 76\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 55654725a248e323f3d4050b87acae89736b85dc8dd45a9c143b001685c72a70996f3ce99f40be4cdb83b7b420b520e7fa001eecd49cd43c31500c7c502e8c31e309026c07fcba386f0905da79d34b855861018af444fbd519736483fa79ab2d02182a9f0c0e514528f38cae7ef7668829b25d58b569027e4f286a71c1da3d9257a72a234ccde58d1604954d99115db265ae13c012125b5f317ab3297e5ca3e7\nflags = WorstCaseMillerRabin\n\n# tcId = 77\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 6af6ed1adb0d772536d2e80f9f048b9a94cea70f6e15f37a6b5cac22794826089a11c8fb421b3bf8c108bd41a3cd7f34d09466aadc8b043a51b0b3e9c18e0c96e4c703343fcf68d45d5f023bf781de530a1d7946f4d2bcde9d7ef44374a2ba94ad56777aa113abb19b57d4802c18bedb58157dcd52eeca7a3837e65aa97d95f3b757e7eec27a5f890f41399aa5c2831f13a724d798aeabfb642a011c52a7c70d\nflags = WorstCaseMillerRabin\n\n# tcId = 78\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 344b4e93ddadf36e039a4e97783a18c3a84f3d725d5f496f0b3632fd15b1a0c2ddf8f97a0f47401d0bef33c32ef36b2819f5d0f72046ab8bdd68fac28397d1906a1923f5ad96483048254e931a6acb5a3d31d4953212aa58c2f96e94dd5393f1e830e76264af68abfed551f3ff4e8d3bfbc6e6cb296befe2b9d694db4d4dd186cfcd6d697c7aadd92277f9ab85e000dfef3085cd52418d0f9b11605a64719003\nflags = WorstCaseMillerRabin\n\n# tcId = 79\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 2947f606c39ded9591b3314918b7fc0586888d42eb0a8d68bfa0890292f83f948280dc92e897c59de2477340c9fb288241737213d63d006a64b5d9c36b010164953fc68b3e4c7d70e4837b707a2b4b3608d878c7e5c122665299c012e2d5b3630b6862b87e4c680cedf13a6fbcc6eea8ce2d1fc394aa2327d6e0f41c4259b00fb8d8922b4a81432a30f7adf6477b5c436102c83bd1896718d8e795cbd5c30b65\nflags = WorstCaseMillerRabin\n\n# tcId = 80\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 2d586d8d3e1a38f532ed17011ff9d397084633faf6690129eac51e092c67217fb23e6d08f9cddbc38f7b3fafc308f23375df556f68f8dce22247da756e8aded669cb841b6be2fe5a22da4c0d06dcc6d6fd899d294ad0f62de03a7057e56ea6836ce8967d929f4144c9955460bb924fc32f5210919c79e9566e0552caaa130b6ab2e9be086fc97659bb2097adb0ddf82cca17b472ca511735499c448a8301f379\nflags = WorstCaseMillerRabin\n\n# tcId = 81\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 4ae1078c81d196eea211f9c4f762a350b4c060b4d3630bf7fb7dddd2739986b9de2422c9902e5870b3760be7b7926d6aaae633cf0ca9c0e78a2ee03fe193675524e0042073d3be737efe994b7bd93382bf8426f454e4a221fc899764f1059fa30b48ba6db9be33c92e312e449d190b3fa2f1c731277286fa363ac8420668239e0bfc26387ba329720bc4ed0217a772ab214a60d8d2d0889d887960383c420595\nflags = WorstCaseMillerRabin\n\n# tcId = 82\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 4acba34e2619592d5cfdbbe195d2aa9eed8762ac0a8336d947c846fc97d1d934c1ff42f1254de674990f76e514be53b2755cfb4ac52edec66a8127685c8e77e84b06bcfeda0684fcbfb20e2ee05c1202f3cb897bfb1c44bcb6301a9843f8e8eed031a1b4eb913bea04f13390ebd2a033ed151ef8b49b511da558e56cf1e3ac89545219ec026b3938ba9732792a1c89ca6d38c3c5e0e400af528ee477ffcf2ad9\nflags = WorstCaseMillerRabin\n\n# tcId = 83\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 3d809b8c90e877efa20e031ec99d825afc1c1920d8b94e460848b80c3fa0a093ddff5c608963ab74f505a6da96b8068c2c2b3bc1676170dd0c2e65adcaf7cfd0c6b0309634961ad0c9b7f75e2f721f1f57fa9cf5d4f41f60b2ad3fc1d213b8e75fedb69ad157e24ad67f2ecc4099943e19ecfa7e1a34abb9f4bb02cf205906dc159c258973267731ce59d16552d372b9b47f0e630ec677711bc13995e00a41c9\nflags = WorstCaseMillerRabin\n\n# tcId = 84\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 3de7d0bda6eae8145cc70591c4b78b1dd8d9ecc4a3d7edc1bbb75bf0e98fd3fb8d5cd4e94e4cd3ee246617b22426ceec6981681af9f7e6af08bc02bde7cbfa13301f7b88f607e1751285c4a861af2ac69f20d2d600e27b0de873b9ec7bf2cd0725b31032932f0f817084b347852613af9977931e2b3132a523dcd87f545805730b34db29c8c8dac9df8a50f5aa1e36a056ae41b01d04cd9574acaa98203d84a7\nflags = WorstCaseMillerRabin\n\n# tcId = 85\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 5e2a15c7d9bee2668dfd689d027bcc37743259309457147ee7785bb3960dae3c8126655cff9e1302086adb3d1c962c3390f50ca3bf5f666e8a004930536c0bedeef4e8bc3f4dedafc3168692109a239a7d4fbd3aef9e6e0c8665c6379caa6ccb05a6f941782379fb13990f2bc104dc7e0007702c7eea3bb7ee42ffb5d570570b2f5409ebe76d7244b1e8392ccabbfda22515beb0bfad6c006c2a02a5e8526763\nflags = WorstCaseMillerRabin\n\n# tcId = 86\n# Worst case for Miller-Rabin test\nresult = invalid\nvalue = 550fda19f97cdfbd13930911ef6e9e1cb2b7b5215a35c215d51ebffeb435642174cbe998f4451bde2d4bd2ce92ab5b9493b657f1d77d9ad4d348550247b903906109c608ecba7f88c239c76f0afc231e7f1ac1cee87b4c34448a16f7979ff4c18e65e05d5a86909615fe56587576962a2cb3ba467d9806445a0f039907601af77ba7d07578eff612364fbcac11d35e243734aa6d9a6cdcf912a2dd0a12ba7e87\nflags = WorstCaseMillerRabin\n\n# tcId = 87\n# A strong pseudoprime for the first 46 primes. F. Arnault, \"Rabin-Miller\n# primality test: composite numbers which pass it\", Math. comp. v.64, n.209, p\n# 355-361.\nresult = invalid\nvalue = 00907b5573c3d72ca5afda9df723d24066410e3d2b61f89c5c600f90732d0ad7db06a02e209f6792b609fee2ac6f3d73a5805f2b30642d1e2654f7ffd155153e5fbdcb17c76c27fbcc15010ccbfa7a1737cdf032edd5da7edebc9703e51572ce452c2319f1d91bee276d3e1121f9563b1700448ff37346b5a88098c9a682a59ccab86401aeeb74c8ce45dbf8b5\n\n# tcId = 88\n# Richard G.E. Pinch, \"Absolute quadratic pseudorprimes\"\n# http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.210.6783&rep=rep1&type=pdf\nresult = invalid\nvalue = 19bc037ff6b1\n\n# tcId = 89\n# Richard G.E. Pinch, \"Absolute quadratic pseudorprimes\"\n# http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.210.6783&rep=rep1&type=pdf\nresult = invalid\nvalue = 01933ecb87a0c1\n\n# tcId = 90\n# Richard G.E. Pinch, \"Absolute quadratic pseudorprimes\"\n#", @@ -3566,118 +4204,118 @@ static const char *kData135[] = { "b96229e4dd12baecae8680aa038c104df148191a40e5f0cca2b25b456957bd8f2145529e71d25762fedbb3b6cf3023dfacf47200b91b6a4bacbfaa92ffaf4a760ec132868b9e7e3f3d0f7cf77a1426645ad54a2e057fc01e223682e7c56afeec356d4f53a08528e5d2684b8be5eab78a3d9b46cf331\nflags = CarmichaelNumber\n\n# tcId = 192\n# S. Mueller, \"Strong Dickson Pseudoprimes which are not Fermat Carmichael\n# Numbers\"\nresult = invalid\nvalue = 00f4e8aaa62114c404219ed23f\n\n# tcId = 193\n# bound for deterministic tests\nresult = invalid\nvalue = 07ff\n\n# tcId = 194\n# bound for deterministic tests\nresult = invalid\nvalue = 05361b\n\n# tcId = 195\n# bound for deterministic tests\nresult = invalid\nvalue = 14f5d5\n\n# tcId = 196\n# bound for deterministic tests\nresult = invalid\nvalue = 008a8d7f\n\n# tcId = 197\n# bound for deterministic tests\nresult = invalid\nvalue = 018271b1\n\n# tcId = 198\n# bound for deterministic tests\nresult = invalid\nvalue = 3e9de64d\n\n# tcId = 199\n# bound for deterministic tests\nresult = invalid\nvalue = 00bfa17dc7\n\n# tcId = 200\n# bound for deterministic tests\nresult = invalid\nvalue = 011baa74c5\n\n# tcId = 201\n# bound for deterministic tests\nresult = invalid\nvalue = 518dafbfd1\n\n# tcId = 202\n# bound for deterministic tests\nresult = invalid\nvalue = 01053cb094c1\n\n# tcId = 203\n# bound for deterministic tests\nresult = invalid\nvalue = 323ee0e55e6b\n\n# tcId = 204\n# bound for deterministic tests\nresult = invalid\nvalue = 1c6b470864f683\n\n# tcId = 205\n# bound for deterministic tests\nresult = invalid\nvalue = 081f23f390affe89\n\n# tcId = 206\n# bound for deterministic tests\nresult = invalid\nvalue = 00ffffffffffffffff\n\n# tcId = 207\n# small prime\nresult = valid\nvalue = 02\n\n# tcId = 208\n# small prime\nresult = valid\nvalue = 03\n\n# tcId = 209\n# small prime\nresult = valid\nvalue = 05\n\n# tcId = 210\n# small prime\nresult = valid\nvalue = 61\n\n# tcId = 211\n# small prime\nresult = valid\nvalue = 65\n\n# tcId = 212\n# small prime\nresult = valid\nvalue = 00fb\n\n# tcId = 213\n# small prime\nresult = valid\nvalue = 0101\n\n# tcId = 214\n# Mersenne prime\nresult = valid\nvalue = 7fffffffffffffffffffffffffffffff\n\n# tcId = 215\n# Mersenne prime\nresult = valid\nvalue = 01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 216\n# Mersenne prime\nresult = valid\nvalue = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 217\n# Mersenne prime\nresult = valid\nvalue = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 218\n# Mersenne prime\nresult = valid\nvalue = 07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 219\n# Factorial prime\nresult = valid\nvalue = 02611501\n\n# tcId = 220\n# Factorial prime\nresult = valid\nvalue = 00f17a60a5d627ded85b6a9a397c2ba63bb27910ccf7e3135d4d1ae8c9f5cc1e4bf01ea704abb2000000000000000001\n\n# tcId = 221\n# Factorial prime\nresult = valid\nvalue = 01e764f3171d1e44a5f0c50c6537730168041cd93fa34898140da93d3df2939adecf61802daa63eaf08428d72148d63f267f22bd24cd411b7f25984b057bda5c11510000000000000000000000000001\n\n# tcId = 222\n# Factorial prime\nresult = valid\nvalue = 3a7c596683f12898e64bf1355bb9bc85f01d91307e568d01afdc9cf0b3fa9e464b140d899d9bf62a0c61c2bf0a8bca1de36f6d36a5be4aa212681896def96f583c8a7cfe362b4e823bd244f813e575391a029df7012e738d3e2e8e0181ea40000000000000000000000000000000000001\n\n# tcId = 223\n# Factorial prime\nresult = valid\nvalue = 72b20ce22e5616f923901a946b02b2ad0417882d9172d88c1940fec763b0cdf02ca5862cfa70e47fb8fd10615bf61187cd564a017355802212a526453e1fb9791014f070d77f8ff4dd54a6d1d58969293734e0b6bc22f3ceea788aa33be35eed4bdc1c8ceb94084399d98e13e69a2b9fa6c5583836a15798ba1a10edd81160a15662cdf587df6b816c570f9b11a466d1b4c328180f614e964f3a5ec61c3f2b759b21687a122f9faefc86fe69a3efd14829639596eb7f2de6eab6b444d06233d34d0651e6fed17db4d0025e58db7cad8824c3e93ed24df588a0a4530be2676e995f870172b9e765ec2886bce140000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 224\n# Factorial prime\nresult = valid\nvalue = 2c47a7947e4ef970e990c8b4a793b5f7d49b9af95a12b9f08475e1cf58f31046fd224c3ef20a736d7cae39a2f989d934c2aa644483aa6e348bd41c34a6819d7c08fdbd93a7f7c24a4756bb7dd97516287e161af87e56735c06d61918cb2fd4ae9dc1c7f2cbb5749934626af5f4db5bde6b748072c004110d45f6db0fe51c4889ff053bb2a24f83bbb80798b94e5d7a189599d85792807626de78a61a7468eab70a2c4dda6200e0c8328408e0327897220bbe009cf8bbbb23fa1cb5fbd3713f7172f8186d059d0b97c2ef5b096c558ec61f66e81116be44f2940f4c93b67d7cd3564c266540fbf0bb95cc3c52c9dbc71aa6a424457131aec3285e6ba46e828e635f3455e30b6db3e4680ba04c580fb569145f6371a0d352f40321751cd26623e92a6c5c9e83eb655338c9077826148e23c3705b8f11b15a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 225\n# Factorial prime\nresult = valid\nvalue = 1774015499125eee9c3c5e4275fe37ffffffff\n\n# tcId = 226\n# Factorial prime\nresult = valid\nvalue = 22d4fb39eb23880b4674bcffd06a18547ee73e7e77f1fb29c0dbfa66ed52cb8b22bbe0ed9b2a2b779c9037d7b412a389bec5ffffffffffffffffffffff\n\n# tcId = 227\n# Factorial prime\nresult = valid\nvalue = 371196ced90a51b120fd9171fa388fe8c2e634f9ee10f4bcddddfd269ebda2f3eed661eaab3cfbe6914395a73735701d7d65e278f76842b02d1f8f5d941d652067ead60bf9bb537ae7e13404711ee80b35bbf5936641be34d53d4b3bbd025bed4be7fa44113cfea3ffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 228\n# Factorial prime\nresult = valid\nvalue = 0120dd73742e20e30f56d82ace2d9ff917e66b2c92024a1444490511d41a39685a9901187f206b5a248b9e52d82f15820801be21beb73ff9e0c8150c69334f02fe9593493b55d48229601857a3ca4449a444d2c0566936deadacd46310d04480265834fe9b5e733357b0c73a0d1e23d85e401e8c3b60571045a6bfb1a19f4940140736098dac2d705dc1339370f1ac19252b931c450bb260800bb40aa404dc54199b7251abcb50d26fc9de82de037c3b9926a2958bd6a1d8690805c0681f5cb5d90b1447cb7e5d81c436b913d743372be382e3bb2d1cd7185948136957af2496888060c7b7ea519b173d5f190c27c70f3dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 229\n# Factor of Mersenne number\nresult = valid\nvalue = 07c97d9108c2ad4329db02eb8f166349\n\n# tcId = 230\n# Factor of Mersenne number\nresult = valid\nvalue = 010001\n\n# tcId = 231\n# Factor of Mersenne number\nresult = valid\nvalue = 663d81\n\n# tcId = 232\n# Factor of Mersenne number\nresult = valid\nvalue = 00b161194487\n\n# tcId = 233\n# Factor of Mersenne number\nresult = valid\nvalue = 08112264cd9bb77f\n\n# tcId = 234\n# Factor of Mersenne number\nresult = valid\nvalue = 0b73493decfd9b68318ef9\n\n# tcId = 235\n# Factor of Mersenne number\nresult = valid\nvalue = 3d30f19cd101\n\n# tcId = 236\n# Factor of Mersenne number\nresult = valid\nvalue = 126cf51772d253cba3f5a7cf\n\n# tcId = 237\n# Factor of Mersenne number\nresult = valid\nvalue = 00d3eafc3af14601\n\n# tcId = 238\n# Factor of Mersenne number\nresult = valid\nvalue = 013540775b48cc32ba01\n\n# tcId = 239\n# Factor of Mersenne number\nresult = valid\nvalue = 3a294c585a8f5c7073e36ee3637cab2586d049baa0ba2c911801\n\n# tcId = 240\n# Factor of Mersenne number\nresult = valid\nvalue = 03f1cb0fdf0fbef0f3747f239f5a8983e72b455488b792c8e29308f8c78e7f\n\n# tcId = 241\n# Factor of Mersenne number\nresult = valid\nvalue = 37a5f7f30fd2d1f46cd794e8337106ccebced1189c1f5b6b3c525b64b6c36768785f7912013f\n\n# tcId = 242\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00c4ec4ec5\n\n# tcId = 243\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00c18f9c19\n\n# tcId = 244\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00a08ad8f3\n\n# tcId = 245\n# edge ca", "se for Montgomery reduction\nresult = valid\nvalue = 00fcfcfcfd\n\n# tcId = 246\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00c71c71c7\n\n# tcId = 247\n# edge case for Montgomery reduction\nresult = valid\nvalue = 3d70a3d7\n\n# tcId = 248\n# edge case for Montgomery reduction\nresult = valid\nvalue = 3ef368eb\n\n# tcId = 249\n# edge case for Montgomery reduction\nresult = valid\nvalue = 69d0369d\n\n# tcId = 250\n# edge case for Montgomery reduction\nresult = valid\nvalue = 51b3bea3677d46cf\n\n# tcId = 251\n# edge case for Montgomery reduction\nresult = valid\nvalue = 7e3f1f8fc7e3f1f9\n\n# tcId = 252\n# edge case for Montgomery reduction\nresult = valid\nvalue = 43fa36f5e02e4851\n\n# tcId = 253\n# edge case for Montgomery reduction\nresult = valid\nvalue = 3454dca410f8ed9d\n\n# tcId = 254\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00c5b3f5dc83cd4e93\n\n# tcId = 255\n# edge case for Montgomery reduction\nresult = valid\nvalue = 593f69b02593f69b\n\n# tcId = 256\n# edge case for Montgomery reduction\nresult = valid\nvalue = 008f6ec07432d63dbb\n\n# tcId = 257\n# edge case for Montgomery reduction\nresult = valid\nvalue = 101767dce434a9b1\n\n# tcId = 258\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00fafafafafafafafafafafafafafafafb\n\n# tcId = 259\n# edge case for Montgomery reduction\nresult = valid\nvalue = 0c934ff1a0c934ff1a0c934ff1a0c935\n\n# tcId = 260\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00d2f87ebfcaa1c5a0f02806abc74be1fb\n\n# tcId = 261\n# edge case for Montgomery reduction\nresult = valid\nvalue = 7880d53da3d15a842a343316c494d305\n\n# tcId = 262\n# edge case for Montgomery reduction\nresult = valid\nvalue = 6a850096a850096a850096a850096a85\n\n# tcId = 263\n# edge case for Montgomery reduction\nresult = valid\nvalue = 0098dbdea62334302c77d10fbfc4b593eb\n\n# tcId = 264\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00df0041ff7c0107fdf0041ff7c0107fdf\n\n# tcId = 265\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8af8b\n\n# tcId = 266\n# edge case for Montgomery reduction\nresult = valid\nvalue = 7f26fe4dfc9bf937f26fe4dfc9bf937f26fe4dfc9bf937f26fe4dfc9bf937f27\n\n# tcId = 267\n# edge case for Montgomery reduction\nresult = valid\nvalue = 009b8f4f9e02732385830fec66e3d3e7809cc8e160c3fb19b8f4f9e02732385831\n\n# tcId = 268\n# edge case for Montgomery reduction\nresult = valid\nvalue = 64a9a50bc0a383524478973fdf4c22bf1b14f339bd92a6942f028e0d4911e25d\n\n# tcId = 269\n# edge case for Montgomery reduction\nresult = valid\nvalue = 7f95438b41e0500d578e97c3f5fe550e2d078140355e3a5f0fd7f95438b41e05\n\n# tcId = 270\n# edge case for Montgomery reduction\nresult = valid\nvalue = 5f1bbd6c9500cae5d85f1bbd6c9500cae5d85f1bbd6c9500cae5d85f1bbd6c95\n\n# tcId = 271\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00967300c9a633fcd967300c9a633fcd967300c9a633fcd967300c9a633fcd9673\n\n# tcId = 272\n# edge case for Montgomery reduction\nresult = valid\nvalue = 00a305942530f7f11f9cd2c027abb32354eb8b77a1c8368c165094c3dfc47e734b\n\n# tcId = 273\n# negative of a prime\nresult = acceptable\nvalue = feff\nflags = NegativeOfPrime\n\n# tcId = 274\n# negative of a prime\nresult = acceptable\nvalue = ff3b13b13b\nflags = NegativeOfPrime\n\n# tcId = 275\n# negative of a prime\nresult = acceptable\nvalue = ff38e38e39\nflags = NegativeOfPrime\n\n# tcId = 276\n# negative of a prime\nresult = acceptable\nvalue = ae4c415c9882b931\nflags = NegativeOfPrime\n\n# tcId = 277\n# negative of a prime\nresult = acceptable\nvalue = a6c0964fda6c0965\nflags = NegativeOfPrime\n\n# tcId = 278\n# negative of a prime\nresult = acceptable\nvalue = ff05050505050505050505050505050505\nflags = NegativeOfPrime\n\n# tcId = 279\n# negative of a prime\nresult = acceptable\nvalue = ff20ffbe0083fef8020ffbe0083fef8021\nflags = NegativeOfPrime\n\n# tcId = 280\n# negative of a prime\nresult = acceptable\nvalue = ff5075075075075075075075075075075075075075075075075075075075075075\nflags = NegativeOfPrime\n\n", }; -static const size_t kLen136 = 26217; +static const size_t kLen190 = 26217; -static const char *kData136[] = { +static const char *kData190[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha1_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 0747d520ca9b2dfc0335cf94301140b8102fb838c92ea99917e354e25709602dc0cdef231ff26ad2dfabbc391e723072a4ef52929f3f1cf0216e44c0093030f8ac29096faef28933bc9b924287014e2e935e2145be4752ccb82cb7646271936979cab73f521eeb27855ac2a410834ae5082eb62ef6f9899ee5cbb624a8d8c04ab7edcf78fe135d0f808f63b5de6e071779bf1d9eaaf8d3ef965486f2c52625e6e57a651c7bbd0197c99c057b3860a3260c864a11b3cf22ba44de3a3b3f3117e64ebf9a91f626ebb3f3c26d1b0bb80753468d4bf6a997b28335f20ed8c384d7558360a9ae9755661fa3749846b174e6bf330e52d09941f6ccd7de5004779f9bb9]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e5]\n[privateKeyPkcs8 = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e50203010001028201000747d520ca9b2dfc0335cf94301140b8102fb838c92ea99917e354e25709602dc0cdef231ff26ad2dfabbc391e723072a4ef52929f3f1cf0216e44c0093030f8ac29096faef28933bc9b924287014e2e935e2145be4752ccb82cb7646271936979cab73f521eeb27855ac2a410834ae5082eb62ef6f9899ee5cbb624a8d8c04ab7edcf78fe135d0f808f63b5de6e071779bf1d9eaaf8d3ef965486f2c52625e6e57a651c7bbd0197c99c057b3860a3260c864a11b3cf22ba44de3a3b3f3117e64ebf9a91f626ebb3f3c26d1b0bb80753468d4bf6a997b28335f20ed8c384d7558360a9ae9755661fa3749846b174e6bf330e52d09941f6ccd7de5004779f9bb902818100fe3d238d376a3856d9592fd4961c17a7fb0fa39d442e9df22e7eda115c648c5cb738df89ea92d8378558d0d9c1cf3d8bff740d3743a0140a6a7523e9176c2953b2c11d7f44691cf8bec2b34fb59c649535983319488118c03118ae7445e70df466ce98671260f05d5068ce777da97e2ba84779490500ceb4ff7f62ceca9a147f02818100be814af26bf3c27115bc7595d0d12a1af7713feca877ae6e6d858825eda3d192704774f42e1ae1b67f1739e8c45a0476388070fa545b7cc96b8a44003bc8d07fde73f5bcdd18268395dcc2842b5023ff14b352382607b7179a5ea330840fc45045d86e0acc4feb135f0ab9b7ce6b8eb5f5a575f2a2a8de299c0d3f506df4879b02818061bb4cf4572e0cf44ddefc0503a34ef0b31142fb0c9fc2f5bb2be656302732d1dd590e8d6cd0002fefa1c1bf43c28fcd4668ed3fa64e5e05d700aaca4ac7b867455af924d83e73f5a7171f68efce6bd7f3df4b1d5802d069e935acb263c0bb5b8d3db3d64379624cecc12d453fd82cf9495a18649a78c1fd500e3f04715ba3af0281806649dbe920a7a8ceb982108cd9ab857527498aae52a2b86918ab6b381a4a2cbbf94794f78b4de9c5e8a59af56d807c06d23dbcebdca1a6f62ba4f8f03b298f32294a9036d16c2739de1cc3e0ddb4d12f2479487b57882afa246c0e297daf4d94607c5e51b3f4715f5c57d0f26d867901209db02010d0a541284640a9b9f0636302818039ec606f5c9f1f33d964606e128e9e90cff932772c5715aa759816d504efe2c46206f3379aa61d31f88e726b50dd80b8ce8558a0d7408525f58c3399ce32e239d70941f12d21e7761c043e0b02220d25ffd03571c7ae5bbd59c31f48120676f9d7c370a749d8491bdfcea01662a136c85d349b6c710fc6f6ebf8a7a79b62adc3]\n[sha = SHA-1]\n\n# tcId = 1\nct = ba366806e4ad50f76c0d8f63a84cc8c1045fbb2f9bef31da89214b2c8553e2d0126fb91e8ad9c78d1515c1593fcd589278369f83d8da3508beed573b2e8a2e61e09d9923476cf2d1cade862344a87c8e50d6600754089992851f44998be57109fe4f9a787fc13cba351f335df5f4cd656858a9d9b547438db4e0e81640618104fac10c0227733f85e041a322459c13ebcf4855fa69519ab94301561146830680e1616fcf4652d30dc6d0cd0aba397560d2a5b9556b42d42ee2088ef8793469d1142331a0b3018feb153999a2439349a709eecbf09568643f8e5d3389073eafd93d37544057e567c3a553269ea1b15a49388127532ab967860c0406a4b0cb3adc\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 8773fdde3f148ec33d4facdfba812e44001d90861c047a9eefe6c6540212795b50dd186bb7712b8448830fc1799e0543b7093e4770f301e9216922e80280e9b50582c669e3a9a4feb08ec6f5b2428dc7efbcf6fe49feb61fd2795af1c8b23acb605812c9d7586e4f48e4d758f0695b688d1b4b563067852b1ce9db5dc82aba29ab416178f616426e5d0caf3f9903de2a5beeb970af7281e7cdacaaa00662ae36fb0365c20c653b670b3e7be4b0680932f3254d48ec3505ca1547d1be27d2414a3539f405df91057f4f97aa7796d7ccb69ed553447131fbe79611756b7e564bba7d76ce9256168446b34498a2e91d9a955a8aa98a71a43d65ee60fcea39d811fe\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 504b4e0d94d800a9da92be8fa84fc345f7ab4921ec53c073c79592b347a692cce2450135e998e07bb75ed7ee44f047f75a07e37b9c912d3d529b62bef144952d5b202246ad32c5d34ec8559c4163e2145fa5fd4d56de28cbfe7e537d5732305945c9370bbc6dcd72b3296fd54a2660365715f7d911099c96dfe6d114eec7b4425cb65701aa9e08d99c7ac20179656bb678554d74baca4501b5d0b366c97224bf0c8734e00ff2af8b916aef8b83142d5ec142493e0cc4c57326515a50a31ec2c6703512034642e5789649773d2f8312561bf2f2f6000cebdbf7c7a95fbfd0f721c31ba392acea37568a24f176767f71b31f407573deef95c305e0e063db0e9168\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 25a918a0c7985a72f18f6b6216d0e2d19a9b42a4d5b680e995c3c5c584966e29c6179877cfd0317f9e4dcdc87f76714994e4407cd868842350e28f328b3f33746a897ea9995575f328be7f9912369482ae1a66ff5b7a1c8ac8fd4e5771e58077b54a55db6c6849ff288d50de0ee1e45bfdf81ffaed16971f19abae660338a3a9240a0b732984fadcd28a85c680f0dac8b73306481a096f700706e91f7c100ce64e1c6bbabd419807dc167f1f924edc6f44a69b75a7c72989b25ce35480433bc456c6afa93a0e9b4156d75863f9440ae442eefd213b8a3f53a065daa8cd0206886d1544c3bfecaf62659cfa591da5e920d7d4370a9aabf7f9983fade101da2dba\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = a2550a9850903f3142bc1b1b54e45d7754e75ff0d39a8ae813b51eb8165be08a4c0366b93c803ef161650f8cb966f7dd4648f40363dd0cc37595e43756078955ef02e415b3e0efd5f9744d564eae763e307e893002dd1a9d0ba2997fe6658f3689fef4f4f21e7a972c0dc642993ff6612c6e6b43f9ce53674919abbc13e42772beb8c3f3f655df9dc9839e075e01beb9b93d8e016f57afc9a0207d9189b4bcb14ba6459ff5fdd5f2fed5260ac9a7a092feca20af0f23a00d8b990c074ca23d964e19e49c17c970bc972b70fda2b6c6e99e4e7ff11902ea7126257fd1964e7da07fbf413c8becb48729fbd861ddcc3fa6c3df2355759ef1338d02551b7fc80a88\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 6f35b56ebd7e12d58cf2239b3c926d21d54222da0d1943bcd0c0e446bc9213526c63ce0736b11340754460036eeac885dacac617499a58c56a6df5de1e91db4e1befba0237f696d1b6a8447163b839ddf082a1c5f8c1315f7fbab45b2bd8011accd5b2b1e3d4f35315e998eef82f368a72728817f7369648b9b1959781449707a5a668a6f8eefe5624135ff8edcdf9594eb4db32f27b2a6f5f7c6406c2f2c7b818f859d9e379a76c17b4d1535db7404e77d611f6cf5b4d0205f885883186d603c7a9920934fb5886406a38013f7a1864d5074f89ddc164c9e13f5aa5e4eb13dfc3a53b153c56d9f6403bf2ac5dde9c42227201fe314984752b5b41ef0064acb0\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 3530605f43b5539c80398f856eea8d88984af4a6a08db3b9d4093cc80d1a313c0ebe727eb2c45cec2025eee60f385822c09f82e3bcedf66b79c2b34a4f41aa8885eca5b9891798d47914f947c76881dbfc3f21ec27a11dc926c647b6b2a7f3292ec4aa32e969bab49afe203ffd79b0c1ab5777a041fbe4e9e1a679fe2d82e9c267ee7fbe54e9e0def68d8bbacb1e53da99aec8ba9255d2ff6676dbcc58498a386dd8a6b3cf0222a9e14fd03313303bec9d0439ff0e8a5a09ce2926ebe86cafd00cd8ca761b88df9cf84f7b8e07cc5f655199ea81ea6407ec264b5971738967a2e977132dc589c72f8bb639a9429feb512d8d32c441f7e1ce6c6befa08140a090\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 4d0cb9e23ea2f25cd93f6a4a5b9189156178572214c2bbc773158ed82b83cdfe7ac1e96d662afd46a9225b9e8d1ded274e00048c058d4cb66cccf4eb6c4ebaf30b97e3ff17a21223cded8708524bf75e3dec075833dc953dfd9a1341072f1485c60018f92bd41cedd0510085d818a5cb4df32c447294f4245385e1e5c4627c41450c1dfd22f34f96514aed1565976735e321c266300de6b93dd93e4db4e521b1a269947cb79bccd472cd40e3fd", "430726723cb97bca50e610bd81daed31fc164c18ef378f68e405ee6d978f97cc042dd266c90b909ba52128824fea7f4496ad56e03fa4aeb528d2fd3d9bfae8295e1a5306b389654b1d7058890b5dbd6770ff5b\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 873c4ecb4858c60218b4ff5fe75ec216502367e0a8446fef2302da892816f127a8bedf7e2fff349be493857c4e363493b28f90365eae44323a933eae25701d84024c84e09b9163de0dc7ba2d44f97c29af5b9422c417bb241a2fd326efd9aed2dcd7cea55bb16b9571647eaece0a0ca71f7da7decfbc588cafa8beacf0b286e143ff77f05407388b72c89c6a4be35d074083e2a128fda53ba7d3363c0d261430667770fd7b42032a4d9764fa86dd4834eba3864acf3e0c230fd03581292562151faa1ed3f8433bc63472c425c382d7425b11c97969b1fd0fa0b014d47d87af919de6df72ba52be888e44de4fa63c215ea80fc61072a320a24e99c6a247880c9a\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 91de22e76714eff612a41318303dc5aaf154dc5e4b79df8495b5acba18a27be6dd454f2c39494aa18d1911aabf38bbad0460922404c6e2c08ac3abfdcdb963623f1c1c07eb2096dff7064d3c55c6221773e4b2a80adaeb210532ec76a3c92832b0aaf7da03cfb60303e0116cb6cdead2b7371cbfaebbf3e511503b9b8bcd54c13c035a44368fba19dfb8735c6117a3edcbe9939afabd7204b6542c77d31a6a244b10481211ec99e45231203720043fe89a57c7a612b3588b12166c55edec13b8265a2c091dd859d4f34eb66ead8b583fd1f0f0ec739b92e7618c1abe1e3e9219fc43f628fe89ccdf2cabc07ffcc5c485c4cadbbbeb02efd8394f4db0b72d81d8\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 8654643090ce426118dcce2bb0fca3b2a4ed45589d73ae2f5683334f17ca5b9f41eb97ff566cbbc0171d8962fcca465f66f4cf14d0114d7768bbac1dfb726d91331670e0e88ce7286e1f0ee7acd5cd75e0d325adc9f47ff02820544770ecf46f381ff330a5c75978e8d248cc12f0752cc7c452265ae919f5a4dd7c20023fbf51d0b413afe09f746114d16d1be499c98d270e9213a37a2a745a3bb216bd30a07d110558090f4fe73debea009e18eb3770eeddd7150b4c7231539f7232d837836490c9547e27dac00efb5a8ccdf9a7c3c1d29c035170a517db899ee61925cc7a2cd278cf576ebe8281bd3a4f2665f15dd0b2e61bcd65172c2fff50a86a2adbf2f1\nlabel = \nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 7866ab0f81437de93442325f02f86a305c4a4a0871207ff3203746c26a43fff5979e68c74264c34dad13955a32785ec1523fccb264957ed6f6b822b5c052b9161d6b75adde451c6f8d637a75dffc9b9a9103934e777cef41b7966bf730a648e5b96aa587936d460124dcec515b55473a009844f19cb2794bd739557d25417e2c036762a921481d728b4d32a8015b17539b7cc2a16a2b33e43b85561a2119fb6c9d8ed42d6bec324281be79e2f79426c653f8445a20cce87a2c263e7933b8ef3fa0b9f9f38fd115fde459e5d32eee2412c0af06d2f6454e04ba060ea87c5aa0d4b365f24b4f05bb27c4aa42061a45cdcef1a39118018b875dfb9f904fda4d80fb\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 55fe2f0fdbe16bc284545cf2be83d2a92a526f52e33e7b116b265859f14433fdf3ae92e10b3a906ac95a4541c42eb80b3aa963e5d9dc4d3414bb5f378cfb3d50af10e9e84fe0e31c98e091643ee99fda65a2a8802f9fba68492beab9e606501b8e82a3d830175137617ae0352bc790b4ecfb76fc126c34fc600f5f09b58f3915155d3ae4820d91904cb92b61fe9193d150d4f0b6bbbaba2692eaff15d2a0f01d0bfb81228462954f404ae06350a24469381047a62e281d2bfa798a3fe19ab0c808de18ebaea11941e6325c04927e0af3499043a42705cfece04a60b6ed8c280869787a4f3d484218f09f0b266efc3a5b442098c82cdf809820cf3b8e7f6ebb8c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 930eeedfc0e94791a2118b228c4e1522ab52f5fbe53373d9c11b4d1b2595b121780f4312a4f834614df0c31425483dd845279b08fc0f1081dafcf51f32958505960e2eb9b9672c9a72a12fb45a25df678009542a171ef8d7f07b11fbe52db47957ce38d9242852a228a4ea864c36d14d58bf41d2a1151b8c18cad777c9a6f8542b2f3c9c84990a461df613f36a0461658b98ba193e6e6b14765021d0272536c044d8820bc3a5da2404f11a35c632b8c0f9ee8f5f3cf6c77934a7b03750031d6d7cd99623c484c5c244ddc07559ea756886d235844d9c6ba4aa24fab14e9c4ed01bac85d332869a8ba8c05ca7a074409e8231ae38c0e1bb98412fdf124f3ffa9f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = bbf27bdc6311952dcf7bb31459ad6f97e09d5948c7d21226c656121aaaf3ac28118efc49e379eabad3ab4b576b494cf438d0e210b8cbe6067a07ca78af7df1547ef9accb15c5c2601c2a020780cb14757201bfab58bb85ef5642d9b5b97ab768f285eb2012f1ed8f7bbd2bc4ac2b9eddbd656dc7477e800e95924827ba6d4f5bfae058e34150dc676e91cec780528d6bdb9d39c4af4005035ef45afeced57ca8f2817b5fcec969a6afa2e0df7cfe5b818bbdda76d7b760454f682d553f6976562f7f529ed8319cbc98bcc759db0c5f3c7c47557092bb3e0d3b208ab6fdfe75dd5c081ff4fcdb08556e78877623fdc4be029933bb659fd3677d62bcb5d8d37818\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 0fe6fcde58648f13ebd5f0ccbd68458da8ae18dfbe82238d2fb90eb42b743dcbe7b12b33f77e31ca85eaf694dcc1159c2fd4778fce93ceca25f5123aa63ad8ddbf776400d489d8d3d46665c9d22b4382d468881b7aa30c97cc6068a9031a100cd4b035426932c488a6396de7bf42bdfc8da04af6ceaa7836752feccfbe5295a757dfcc25c8e8c5cfe122bcb764f0660528e162c3205e0a6b9f8d399f50529005467f56ea70c0182c9d679d13dbb0e1ea24b84709c1681418cd174f4467f943cd5a1802bd0ac666dabac72bb3be4d3ab9874b23c4c394f3287075c60454daad062f2e5b81bfb14222c97caef742482c6729c9b44de880e07668b59a93d8e27d17\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 0a182cc23064e7b1d11ff906ed40842213938431906395ac4995b9e8e56fa3835e9fc4c4ca81d5cd0e14814bf16de6e07ddd949b43522387e8f543672dc965976229da3e791efccf4a4d28c3d5cc8c32f7216e89400794c495a54d2b38f72e30570b43b58c657471fb9b6be7a999807976263cc259c06df51e632beecd7372e2d0ffa17f79d029dba8cf00611caa9e05bdc0ef87d9a2f5f02e4732aac5bdbf1d754e2263a209a9b211a1a8712a2b9a8dbf676fb7bf130c505ec1972e4c5c4baef2e33c955e63d55cecb818f9c85dfb1fa54207a406f153ce77d946c60c4faa289d955d73a8c64f5d4dbc2fac3b4741eff3b3fc205e1bdaf7fabd738d01eaa404\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = affb9604fa25ac904e054b0401d51c566c7556c965088e81bb0181dc16532b5c5800117eaee491c1dcfebb184ca00ccfb3a934a4e3efd42a2249ef6d4a1df93af90db0d135a000c97fc1092e85cca90770e4b3583baa654cd127b5ef7549d7d7a4dab1ccb16b7fb0b0eaa6ae401e023efa97ef61a136554d013c61934cb9996db2cbac0a4b68651285ef3421ae2276c7e65dc81d8e3089c15e36e2bcd8f42926daa907f56e5fa4d6a8f3891e71b4f80a15798a94bb64aa68e295bb0d1f6669ea761de0792fee6e0bff465e53b1447eff610b33d38eca86d9c66b542f579338fd944f6a116333dec3684e4c78aba1b1ec12e8e6712206f81701d30a3b43688d0b\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = a455a8536e5295ac29243e3f7bfd2f6ebf1aa7e3d1333c1bd9fe05b6ade3aa913b859dbd45ba093ae9b034f619f99a69eaa680ffb7be3ab38784648f6f31f858200992f95740ff2edb835f8fc03bb6785278ab9eae742d5966519fa9f584f0c3044136d04fe12104ec8a8bd07950334db8df8a83af843347a10974245c723fc85686240eefd0cce09d81a63c6f6a4d2b83d29ff9ad060129e5521da5e635dc05796ba540f1dad25b9423bda365202709e5e287a2b0d7b09a2ab6031447e1a2ae8efd9e980a29dff1458327edc0ad162670f80343d8490118856f396c72058227f57b9b0ba66b13c4e7117538bcda3e937dfe05d10a764c0ba1f5626478d4fc72\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 96982e222302818f506285642768615f426bdf9f3b4daf80ec5e3ea26cbbe7f5ab48cbdaca4ab0538bfdd91f7678101b61181806f48b2d6fe778d899804a888716a0c2c3a7078513b1cbaf1d096e6fdc83abc2fe40b6742709a2e51afd8e767aa4a72bb4554286140533e4bd5432010d6016d308d475eb2a40165d46dba630c11a183532f658bd538096c1877fc4d843d9d2d8cee570dadc9895cfe2372df9601fcd74399006466fb9ed923b7d9abbad9bc7de963e0eeac7bbd56f20e1c254ef722d523fa8f3bdb0b91b37202e11b4578a3252673e69ec05a05ea60913ea1b9e6228d9fa0c85ac6d794dfeccdf7595828b06df2bdc89fd8d22629fdfee205be7\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = ae11f45e24cffa8e4f37be34ec87852db77c2501", "c1274e23477c50d62313480ba2ac9de76b790a355b50c2f2ed2dd061cd860ff7932cadaa0e1565e43d4177ac98e26d964e81cfb7c20fba7e2b0853fdcc7deab75b62ef5f231ea29f10c83c2f27c9215b7d10d85443d967ce7fcd41b0de999d9f98a072dc80fb5857d47e4373c736bae728932733d0a071164b6d6dea3205e267bebc287d9b5035a76978dcc2f38946dddca48a6a6035557dd9e1aaec4344dbb457612eb27b9302e02ea0c9456984e70faf235aecd20cb32f3da016c9a8a8b23e07a06dfa57f5a25853944cbf538c864169566797a4346e52fcd2ea1489799109820cca4b6249502270dfb1f6\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 8ba65949d2a53d5a933abbdff1efb4b6861484dc230bca0c363a66202691bd39d94798664763d72f55edb37e8cc791b3904c42c4e1b75e4aaad312f5dc53a246f211d19e311a974c92ff8af0573dc831c51194e59c920ec3d6325f06b9c4bceaa6e55696b185163e73aac401fc1925cffcc7b80985bab727288d258a3c60f7d3d2d8ec80dcfe7547229183a19247e3ea10afcb0fb0c8e7c4c57bd5cfd5529abbd407f959f4b9c492411691da445fc5ff3ffdd11fcd20c2a2936d1373b55c2ee41a7b43c049b40cc55f7bc85e46b0d8464a3add0bf28a0d3ee46c12e6fd600f840ed65f11d590381fb9c6a80a46d64570eb4f6930ed24087e47aa12eca2a1329a\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = e2dae040ee2a2d4c4a0e620b5dd05b56df67f079884f0bbfb64a3eeff08fdaafdccc458b014d53f0574f9ec5514ef21524373c0408b2d67c11fdc812762812db75786693b66313ec08cd001d90787a1b4cee69d3a9f2cf9ab81503be8f205c701da8a39d70b1e8cc40f132b3bed46ed8f466cdee0d032955dacc5c373789f5d58886a3a5cff7c841a5b34789a3091a0f1903a2227ac24ccf0a2fc3739c92210afdf726d53e07692f3fb82f431f2779768766608111f6f4f9cfdf256d79c5ab13cf68e9d494b2c60fd5eeabdaf4b0c896fdc190db93c78c85671ed3ab6b48b7bef639dd19b4f224d0667f1fffc200019773ad09be3f58b1eb5a7cec3289ff8f9f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 000025a918a0c7985a72f18f6b6216d0e2d19a9b42a4d5b680e995c3c5c584966e29c6179877cfd0317f9e4dcdc87f76714994e4407cd868842350e28f328b3f33746a897ea9995575f328be7f9912369482ae1a66ff5b7a1c8ac8fd4e5771e58077b54a55db6c6849ff288d50de0ee1e45bfdf81ffaed16971f19abae660338a3a9240a0b732984fadcd28a85c680f0dac8b73306481a096f700706e91f7c100ce64e1c6bbabd419807dc167f1f924edc6f44a69b75a7c72989b25ce35480433bc456c6afa93a0e9b4156d75863f9440ae442eefd213b8a3f53a065daa8cd0206886d1544c3bfecaf62659cfa591da5e920d7d4370a9aabf7f9983fade101da2dba\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 25a918a0c7985a72f18f6b6216d0e2d19a9b42a4d5b680e995c3c5c584966e29c6179877cfd0317f9e4dcdc87f76714994e4407cd868842350e28f328b3f33746a897ea9995575f328be7f9912369482ae1a66ff5b7a1c8ac8fd4e5771e58077b54a55db6c6849ff288d50de0ee1e45bfdf81ffaed16971f19abae660338a3a9240a0b732984fadcd28a85c680f0dac8b73306481a096f700706e91f7c100ce64e1c6bbabd419807dc167f1f924edc6f44a69b75a7c72989b25ce35480433bc456c6afa93a0e9b4156d75863f9440ae442eefd213b8a3f53a065daa8cd0206886d1544c3bfecaf62659cfa591da5e920d7d4370a9aabf7f9983fade101da2dba0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = a918a0c7985a72f18f6b6216d0e2d19a9b42a4d5b680e995c3c5c584966e29c6179877cfd0317f9e4dcdc87f76714994e4407cd868842350e28f328b3f33746a897ea9995575f328be7f9912369482ae1a66ff5b7a1c8ac8fd4e5771e58077b54a55db6c6849ff288d50de0ee1e45bfdf81ffaed16971f19abae660338a3a9240a0b732984fadcd28a85c680f0dac8b73306481a096f700706e91f7c100ce64e1c6bbabd419807dc167f1f924edc6f44a69b75a7c72989b25ce35480433bc456c6afa93a0e9b4156d75863f9440ae442eefd213b8a3f53a065daa8cd0206886d1544c3bfecaf62659cfa591da5e920d7d4370a9aabf7f9983fade101da2dba\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 31\n# em represents a small integer\nct = 092d5b4bea487029a4c06c97f727f6ad4531f7f646c95cd269e1e606a7e047c19a6a9eca8fa5abcbbca415477420ba422a7d5ba41ac79ba7548aa6f4b44aa65ad915ec11d7f50cd2ad7eac86869bf88bd7cbd11439aec354a25be71d36541e7ef211ae010d8259ac7b5af49e38e14d87b62a3e7840316799b548f14339cf7b46ccffd66e596b0879782f8638b975a89edc2b2355f05c53845078502d046b7f4371bdf911e30302fa980fefb439737333fa9c179c33a98e1b052da7da2436e8b862ee5f7c63c88ab751a244705c8bd1f32c277e0a7c80ef302bd01c9fd50c9b7b6395044c72461dc69aea549e37858b8b53b2792238f59445684e551e52e08750\nlabel = 610c549ce717749d3143cbd96c51c1c75885a5d200000000\nmsg = 32fdd5b5319188914afbe21b1fa91bc4e484ecd1f9968231879e372570c43a27f720e6773e1d905b70f85a312347f7e9752a8c4f5b9f27bd01530b6efeb221dddc723cd51b4bc4814992268c403ed4fdddd526efa87d835069246f25e8098dd5ae3e463fd639b36a4c139476b3d29ae0c9b6c163d81e7719cc85e65289bdde2f82b69bb4aa9c5a5dcd513421a54e5d4638d8c23567c12978c3aa806ba7964a547a689360105fc1b2468fa1480204d468ba2fe41ce9302328d4279e00a9af1c7cdd9f16d572e70b06f1f40acfd50c8865ef37d888b2fb\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em has a large hamming weight\nct = 58a4e190a7306bcb33ea5f1ad83b74da56e3debd2b2fb4499ea9339379b0f08117c77b4d5ca6dd1ad51a4cea4b818c270344980077674c8bf6e8a5ce5ab6212ddcabcd53be82672f19d535debf66bf853538d163b6128468fa21bd4464e84fbfa92501ad51bb1bf7e14ff522ecfd65a29e08ef23aae01218d7635915f8372055e0c6a2ed1de61511484bd6c32286a23a9eb2f1999708e8ed5e28516874241eb778713a845241151a946c509c07e4d27c167b7b5ef6f7a4f1fadf9049996eab17d97ef4d22550649060692af63fd06d05c76f3191689158323605582696729db7d94f730e5107d0d585cea56160968a887ab42bee7fd4f9ffd1449f021a3d41ab\nlabel = a0a0b480327073f080fc1efd8cf5be9bfcefd3a000000000\nmsg = f032ef2759de946b6ccf829695a9438e5f986fdbbf333262a795ff9ede842bb7b153c526abd1ea498f56e992bd21558c7c3b6434e4c667ccd16687eddc199bbaa59547e065a8a3814cd5ea46d7437c1d6bdd8f1a72ee5e945a2b1f11da2049a685ddb525da742260a20ce52f95755b8d7b5d29dfe7f55395c6203c518d5f45ae7435fbc19efb7fa9d2e1626cd655d409e35fdc4e8b5773965d9db726afa40a73cb212b60678bbc7a0417b94d97e03c273c8ee2ec49f23f57576ab3bce568fa2a1080f0f036e6971eba8a773b405ba2c5ba6564a4289a\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em has a large hamming weight\nct = 526352ba3b50ba160f05b9b7604abd508e744e176f99f5ed5fa47869dbf220f32fa43f7942a8951a75505a5800f8f49233d57778ea9dd5220bbecef15d38dd7400ba81ff4cd5085d2d20af7ce79f097ec08ce2a8dbab4482675ff08bda80c74078a44cd89af547a356cd21bb4be52a0cc5dad5bc779b54fbad60d15f10ca79d25e82f19d9dbfff7ecc1cccd8374582bef1d4bc3fa745259dcaecc56b8f162f7d4063aa2c99ed8f418f2aa5658df7d1f36041883b4484ac6766b059948960fa2e40363c6c56242396809f4b036fd91d46de8eb053c8cb0297784120264c6ac7e359f4ad5ec65a002644c03cfc166a8e5a019b8236c7", "d7145df247cd123a09c8c2\nlabel = bba0b480327073f080fc1efd8cf5be9bfcefd3a000000000\nmsg = a472bbae5a81e6500afc183d8bd1ceec795f4907c496830bff4a9f3b15f1768724cec8d288d1d11f47529538cdf93f769917afd65d033d4f563cc14f6dd39a8e7e03afde9eb374b9177f5bed74ebcbf771f630a1b3075d0a308ce65424386304396e824528deed8a2ac7a387f7a3eec3b633882c92e9c33eba9a91f9297dd6aeef37a5d475d10fe69e0b1264fc2ea1cb45ab4f1c6908cedac276183adee1f60da7cc1a105ed5ef187c2b11748e98c8a93af9683d441a3088cb0aa669b06db151e7151371d0273e2ecb161c8fa69d4e56666681c6439b\nresult = valid\nflags = Constructed\n\n# tcId = 34\n# em has a large hamming weight\nct = 6ab92b1c57f99c17ae4ca5f7d4c0149eb24cb18aaf36163859e1186dcbafeeda4d77fd059b0f938e92b8d413b771852fb019a66d76009444605edd5fb48e6eebbd9d01827be732292cb07cde541dce138990d46599b5a196525af199ad4adf7c259109e715e563d8974cbbeae62a53c8137076f10731a964f2ce37305a175d35eb7c8e6e72c9792631d35133dcd49f1a1da677ab3ac074172778402a4176c036cd8ac5674770f171d9134585a115f6a0983d606b748e0e47be040acda88cc5b8c7eadd33162117bb61f49cace91260c5e2c8ef4dbcec7f156a18894a2bed9956520b2b681b2fa31347df7ea98062d97f2972280be22e507249b2436a9ab91689\nlabel = 7fa0b480327073f080fc1efd8cf5be9bfcefd3a000000000\nmsg = 6d5c2cb5790875728fb21e987278fdd1d881cf4953e62866f8d53ebb067cf9a4ef53218030e3eca6732a6b1f789cdf3cc711b6063a01f424b388905549663769dcdcbdd82deb6bc23f66c1c04d30c6d91fd6116bdf8802c150fed396562edd21ca606528cd40b569e895c8ad5bd1bd5848a215501537dccbd0fcd70cf3b2d0df58a072e07f60ff764c4688c37240863242f6eafe36601dfcda41eb863f4db701de54781a6d53a97932d32aae0e6a526048f766902128b4842068fad9ab10811ce93339ad42f2e13c4cec324a8cf7035705b8a36fd8a7\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen137 = 21242; +static const size_t kLen191 = 21242; -static const char *kData137[] = { +static const char *kData191[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha224_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 56d0756ceddf7b1e5b258f783b99e036e25675eca054ae9b6ed7552776c69b2728f76e08973556b0a35ddbade9d462ed12bfc46fd254a07ef4ee043ab24d1ef00f8d214cd1d906911e92c4a212d9a981da74b8d18208153d583035d6642b87a23371787867efd02c336eab01486266c853a052490deaea430c6043a6b240b6e9d71e16f29255f2ceeb35d1a4ae25ae0dc9a436fb5dc30381cce982acc824961976df683173a02a540c403f3c8560243ceb5b798abcdc20f3c85d9532b0f0b0826f1b6352c5adac757fe3224b822455cc529fcdc8a220b0469f321f56bd1853d8a70b893f404cc06317e084173770c7d4c836281ac251353fcee4ac393838a1a1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f5]\n[privateKeyPkcs8 = 308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f502030100010282010056d0756ceddf7b1e5b258f783b99e036e25675eca054ae9b6ed7552776c69b2728f76e08973556b0a35ddbade9d462ed12bfc46fd254a07ef4ee043ab24d1ef00f8d214cd1d906911e92c4a212d9a981da74b8d18208153d583035d6642b87a23371787867efd02c336eab01486266c853a052490deaea430c6043a6b240b6e9d71e16f29255f2ceeb35d1a4ae25ae0dc9a436fb5dc30381cce982acc824961976df683173a02a540c403f3c8560243ceb5b798abcdc20f3c85d9532b0f0b0826f1b6352c5adac757fe3224b822455cc529fcdc8a220b0469f321f56bd1853d8a70b893f404cc06317e084173770c7d4c836281ac251353fcee4ac393838a1a102818100ea6010a0017d4073198610d0e761f286e3a1133eeed71b4fd4dfb0d8b52e1e1d8ffc58d9c10396629952eb002369b22bb9c3313c80330c1f3ab7a3fcf8d0fbf5a1c0fb7936ef20d51373b21bea72fcb7f70275ac41d97b566b71f727a32f0006de15e7f9bccfcc3224106f6b1ae62d59380065a48ef7bd015ee6dabae0f9d78902818100d52ed808d74a79b3ab515b4f2fe7b41027472c3785eb25587ae31d3500bf3c6ef20c427e223efa4f2911cd38cfc4479f28ae495fe3e88e94c236c0bc1323d71027aba290669ffbd7e0fbb6f615df1c9e4fe5abb5a90d4d0b6d1dea0ae2b249e6a5102092c998b60dd920d09a2e6ecf2a611793016bc0c92de3b9d92744bc070d02818100cb64f6c884c257ae0b56673d83af62b360d3a64a1527a3d211e0d62e1a7d9d30f6857dedeb2cdbd3514fbe14eea689329d1121a76971e3712e99b3bc9389793edf5304695b1d0697233c62330bb12253dc0ecc63e2f983a9a9b0cb5620ad670e8ea8e019c09b6c8f8ef09c608c85789156a231932f671b251760ac2d45944c5102818100b616befc3e3824dfac535f74b1ec6d46e6e5ca04dae4510fd4572d595a7bfdf89dd28ef101fb5cfe448c2a087e9e9eb6799ef4996d27f4b1677a3101f42f46c14bc134a7b6a0ac1266df5a15b3f4d0930097a22516727ffe64838aa7259f37b44405146d8cb85db8525fcf0e02df2f2079b21324c18ef7c7b49dc7b7dce3e5f902818040fbda2e571060971cc6aea0c1cc82beab4fa0361de43a55bd2b399f25ed89e33c48983f409d9f27292770d5c0ac1b31adf766045e60d67b89957c81c0f3b7706c3e1418926bfecba0242ba54ed95ae1bc73b67ddb1e3f4161380cbbf1db7d3dbef852ebb38063bc2544c9c29f47f416f14eb1ea3cf2bab933d21c2c091293ce]\n[sha = SHA-224]\n\n# tcId = 1\nct = 03aea385d1f1321eeac78684a79ea101f54adae40474a54c8e574e1ae3871634050e5b596461730c345cfc93224deb7a26ae40f30a0497d7c6f0e141e9657b84bf9e20606fa7fe6e1c921d8de5032ad8ecc37b7c3247a56b3992c7c63dfc3fe2f22d7c4904fbddc371f560fef052f3ed89202bcc5f92f5a7fced461f984406554eadb85ab7d2bd7fc576d333b8876f82860c94aabb705e34e5f385cc2d7acfc5463a0135a15ed3c417789e0b8873d5fa0241c9a0d9894f617cf55c11fc45a47b3fcc04fa5b57e9e188addcf259a0f8051f254b6a57c2af22cbd4eb2c411e229045efbb577da4f480989d173a2fa367af721088547a8a219ff2466561eaa877e1\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 5d19107e5f9422dd3d9e2207ca637f7347454c338c3191ef2eb5687a49f6570f723aab7ebbd78abba840942e74aea052dc24792c9eef1d72c148733c19776216431f917b81a9a80ff4b1883daba20dc6c368c525a2105550715a374583b56f9030df876d67b229fba732369113585166e41f8b5bb7735afc50970396f47921cb2d6c8bdedd5ff1f0411c804e412c2523da5354a0232a46bf9268402fb952f0ca00d04bfc4504c2ecd9772001b2d77be4731e131f90b46e0d0f51a6f7d787d95f01ce64f78b0c4759db1e4546857658b4bb899cb2e024d15b8bd14d0f2fd02a4001be3b6ab35ac589a83234d8d906750dec3e509332ca081969b26a1dd0ac7614\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 00d7ab45e49e37e0d73d9ec5d477985b51d9e1b7b9eb67a8e0224f49d8a3432c0dd8df02b5dbe8962b8a3d749d71e56c7871c0b4137d98de5b77d5f94bb448e124b57b2af9c24004bb693baf2d9f54fefe770f6f320cbe73c0405276b09b1d0627b3018787a3b27e09aa0b3ce50a79f946fc45746de72a93554b993936d3a41bf90bd9f2913f5580c8c1c1b853271286dacf275280faa981c78dfefcd4dd09b6f09bd5dde3ec11b02eb4538e43fbae835e40f903c81744797f04f5a38409a502f3a7eb9447a342dccd82fb192601d40f57192255f751f102e14fedc7e7aa81c770c6b72dcb853366b7a18fb11b8e3b3ee218e59f2dd74feba1bb6e06a87405d7\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 942fc136ac976cfc686ed13a38314c9c8b570a4afa2b18ae0a3cc39173a1430c1cab8893d530d4bfbf98251035d1fc18d18d905ac86792a1f597c08de11d9e2487dd78900a0bf79239f75e155eb0fc6d151cd7acd4664ac606c396494969422c6a321e12fe747a3b0601afaa43a0d9c08c776a7bacd68ca04b3b5dd9e8c9dee6773cfe652b923ff9d4e82d353113fd7e0264189556b1f28011dabf2fed6beb47498af5a6a8b0b1ac9640e5acb53ebb90bf29b7783a01ad6b4f4595e067711a49f8f1cf00443292251d2c0551f89e4271140b03681e8f4fdfe62e588f565c2e5288b3b14a488f14751b5a493290dd9365a48ea33011ffadbd2b898bec921bb1ba\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 36deb3f715d91d4f2c5a21a028f87b227dafedb7c0e064712dad36c276fc15bea7d0d3671b115323849ecf52e6326e5f2b205033177410eddd8e29fb06a1b93e99ff62ac8f7dbb973345947de615e9a8da910b5c810732985c3020d93e7485c69801b7ed49433ad66a0708f26d51c0fbd1c73cafc4c89f50a20a09369db4d065e9cd7845be623e86f497a0c3e9485701f18006b8130210cf09c69dcab7ec0e3c166fbbc5cc78c89dbd0cdaf7219b03dc580b4b8f7497c1f9f36d1c61e1609be1f67b892871ded426121c5f83e38d39127c7b574157e2f4ca589efe094c3472348bad8ec5b07b4a2f3f68d4176b6f381930ef377c640ae8491b5bc3249a5296fb\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 39f8f5ee290e93d4a36b96aa94a3bb7edb33c0fb6565ca6a99fe2434222be6b6846af4daa933bc6ecb62e963d2e107f51bba8a92ea5a4e6490402102dd378a55c0ee2224e77395e27bf28a216c6f929db2c2c95721d1448160e888aa93251c966858535146a70188d87443416101e530cef68a1781f10368ceb43c287c73cd8c44592c56bd8f2bd501284c3118fa0f0402b42ca7c4ea3a917afe71ea82df1655a39c650ea6adc9d73e789970d9b3bbe3f34d0fc4dc5fd51529cd328a62dee0c30eafbaf7dd51de3c31090833024124741966bc8722a157a8e71ed60bb3ef4704ebfabeba4ef67edfc5a120a0ee3316797e0e6a9ddb4d3bc7dcc9f4c262fe022d\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = b798998999f0e4318470e72841a57733c842f174121247fbf3e59e7724bfd9501425234f8616d288f0dc8206c727aba50c13016d4be6f3bb64bed9dc5122b94522b8987a9db93403975302ef6fd585cad02556a735ffc5332d362272a07c1ddde4484639ab767e39881fa1c0077aed9e8ea4f6349f59940953c956f52065fde0a97624d0840fa610a46dcbdd12b8ea3c56c5873e9fb3f58e43ac719d50c75b434b01fd7f65c7eabd5a71f305561088ffd2fa7bb8698d16455a81d233a4dcc4c1f12280bae89741ac47885552d21b37523ffa8901a2256b3f7fd410b6d842a786ce2cd6ab81a7596ce5479eee98aa3836a22ee8307888d9365a962f2746b01430\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 2860d0785fcecef5d43ea029d6ef89b978b25b091a2bb64ee1b95da7dd257ed644a5e4ae1437bb20840715895adc9b2dfaaa1a427ab35d6380c0a6840c022a2fa1eff9b6de19568cf8276ce549365c768a0ee6d84c4c4f4c582ed93c297e83507c8495b3951279b274215cbae88de81447ff5d5d9421fb025a821a934d0103b9efa6d36067cfd394751251ccf4418e32c283ace982f8ee86635b9489aa2e756ccf6d2773a4c8613b89", "9b7764c319153762a9ad14352538507d36f70f56e47c74e2786b8197ad42e2380324ba8cfc80d354eb4487e3642dba175cdcd8382f074e170e326f2cdce0cbdc3831aae1e1abb87756e503520b87a18eff17fca24fe20c\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = a13447bed3796370d356bca37fe2ce27d19022301007dcaafa7162de0897698bf706c3c4594107e9a3585091178a25f458aed6e63eda039b1ab89704757d80a94751ee21c1fb672ca1a8f448fe8d959ec226867bb13dedd1b870986a9e7fec6893fd2d8d533ff13e60b7d61303e123d1f50b7301ac9dbce4480cb3d334b72e048f8740a5b9739bd07beef64265dcd6576dbbc956095aa586a1f22962dc96a00baf953faf836dce03568f3bea85696b074c9e1180dc2f801efe48a47e0735195944891a866d3e2cd1edb8333bf5164b94e618b1204af410644d966fab0e49b23efb23ee2038dfa88bf231ed1deab19346c4833f17ead5f1a2f15d695eef4e14df\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 19dc98b0bd6a47a1d0cf9c9584bae53837bc666029ba6478152d23cfd36e72f1c686543a5836a6420c5f2c984c6c025cd26ec5c6a74ca4e0eb87ea26ad2ee94365c3a6ad0928f9bc9f560bef8b2830374707f7dbba0a938b230f8a42de6645fe765422810eceaa713e8f78e0fbe48b70bc636e21030a89b80118fd4bc066e4d5400529e9c2f8984bbd5800168d72329bfe0d86ac71d3b3d7aa749b1d860afc9b49dac1ee8fd12b73ffa7c095c610df9d502e80c8108b6c944eddca8162666b7955d061231a95698c4c8470217ef9c47ad1003c80f032d95b7a29f459d7ddff205a9b02513f977fdb72b148869527539c0f21a4d749a0301a2fc686e12a2aa6cc\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 94ad881563060d9ac62c32f57f9cf08c57ec10bcf77b35a67ce89da68cf8569e2e6891ed966ab988e68a0e6e44b389a57e2ceccf4e7e32d6bb73be98db72bf363d0da8a20d063e9be5d9f4c62e718004132c9cf876ef58b07c122f02691896df3deac296dbf3e1f6841d02572b6e297d2f0c8a54cc4088fc9bbc0f67f9de75dbdf81cd48e2f45b3b9ff2bdd3ac749d4f43866ecea7483e810cd3c332f055cea1525f263c54e5ca3e1e049af11850bc836e6064cda5cf9204e9cba0857b1fcd65654e30b062e980150d541027a212ecda6985f7e93a0f799679a7c36918aa39de158e0fd52c5cdde046fe6e4ee67f20ccdec1c4d328098c09e6b2fe4251586b67\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = bdcbfb51335812a53e7db2c1b73ed5585fd7899936adb790f4b10327ee075714e21e7df55bddc6888adce032ffe1935d37178adb4dbff608eb5f4cf9e29bc32554358a829ad0b84b1cde5da1018440fa31f60ca72407f5604ea216a139c34034705d295bad65cb9fade9951e17d1ee85f4a46dd4ce81bc878daeddd800d0296eaa90345dcfd83f6dff5cb3ed87c7a8b5985b2ccd7f925b67d39920438b66c1ae1c1321fea7a8a90023f57cd97a50081c42d012de9ba5b98a1aec7da9929cf783def9efdafeaa8d9302da9fd44ec252cb5a97d5dd4fc6f68daddaa9d0f431b7968386df1a514f407f1342e33b996ee9c4b5af934f1aa2fe1e1ad485438d497afd\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 61b8f5873124a6ec36f1ae35081f79e17516362e8e7c5ddf3f44af7070808411db7182a3c82b70cb4c0510aac537a817c6087b907627cdccfcec4cd4b0a901f8aa2ef75e797457cc6f5a0effaaa9b6c542726eb45e9b27e3040d9dd283cb92f1514d93f00f9ea8f40170fb26129d82f169d5e3d9e4d57a38eac39a5aa5dc7fbece162c2f0f13fc095894f323cef093eaa2f000507fbe9d2fa22078bf824b9df7b894ec9705c16e9dd43d2c98f11594e04cf120666c72c8192658e94b02ac89876d51173bfe282c90ff93a5a68d1136e2ebc98fbaf956f28c71df44975fc6376003e713dc5d89ef08658a4d3686a198a4d140259e213f9fbcf5471afb3e0bdfae\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 4fd0d013bedc7ec38e1cb2bb2c234bec4a91733c1363f1dcb7ca47b6d4c8cbd56d7d75255efb3d5fee9f0c1bc5f00560f14ec1947274287153f8db015df8f4f4db9e9d0d9cef10302cac8cfeb72e04feb612ddb2bf4d58a50e19d77027457cbcc158dbcc845ad48b13d710ba1156a9d8f50a27da1e09f0c449e4571a359b4bd9555dad9f5b9354d6ebcf31171704315f6daff2a50b9807dfbfd94264680f44e146039216d83821e27c7933cfe13efb6b0f3912c51dad42bf433d89ccf52a7de04b59931665ed7ca91c7b9b9ce9da70c47c5e91f55cfc6f97c88ce230dadc2222e25f8d25f6f669762bc05e3888b9a05bfc03ea32cc43df08c84219d5c75d7283\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = bd6952203734e2d690c1468c7707b6976f802e82d79a786b40e64275d563b36f1e91bc99853eb3c194d265509b8011ca2d553f6fbbe7a0d6cbb1de6a61dc2b4f6f89344b3033f41e0b302eb626f800c4cf316dbed56580210f951535656605ff142fb8f4e116663b17e0cf8725de29c385737660b4e04c0b710726a70c39d5c417c12a653c3be05031958b1a14befdf95c582e677daa8364fb5ab08cc7d9aa59e02792c44867f68daef5eac69d81200d8dc12dc34be80bece0b80cb16b40a6317ce24ee21e8c082af1598bc4f590459cbf469ddfa4130118fd4686ebb636de9fa41216c24885726d53ebfe50bdb41fd93ae97b079fae913694543339e5cb3ec7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 916331689c162246baef783597f0448e34dc5d358b7f00fa47d5549f4fb52c7607c3a3d571b0930705ea61da60d59e96f9b4cb9fa6aac7fc737cbf6615c98b4f8ecd4a0c27878f469edba1bfc1108b104f73d90f089621ba85a938714818efa68c0483359e014c69c84209e1560b8692b8ac90e6164796cd1bc0578805d9e7318bbf08345835c67397eddc2d326468f594b2d4ddaaf8c67f5dfd998eab7c2fecb6a9ce63bde38cf23e0b0f252dbe964647da61dd054d10c5ea82abf730b0ef1722f98aeb15dda842a099501246700dc37d696177f52345c7a8be7bf55d0fb0f134731fc138ece8feee540bfc0da05edb375a1c0035e6fb0168a6424cf25bec5f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 7d9133d56002b70d758be84c5765c01ada73449ad76776d0dd6995062b5707c6033cc93a3d3056d5cb576d5c8ef6e65f8f3aa2555a454a953c405e5163bf2b0e7f6fbbc9dcd210430862ad22628dc2529179eaaa047f2f87a5f5831a36b604a117908a2170497c218db30110812da89559c5ebaea9281429172088558b7754624f1dd71cff3eacaac9e71df7e4404129cc1b7a1d77c5d34167a3ac4214a74e11d154e1ad42c4d12e9ea32c40bf3d92b356ca5cff7ca65c5cab2298b2899c00fe15bc31996038b577f50204d0def12c900bbdbff4f7ddca011437e01ec923ef76144f097c6951c0606c18bb200c700f451529594512d4ec4c55980c7c0aade461\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 8dabf24844e59cba5ce1ab2a32862c6357c465475b98cfd54c5dbd07017e0ba9215aeddd2dde36d2db9891661e6a8a9ca5bf9676ed193047dbd140875f312fee28db4ffc433dd8edec1fd8c342faaf36ee398f8aed0108a3ce98f145883ad126eb025a011c64ea51e2008a14fde229622275c8fda70f3bb83d92597a110c655cf6303a96bed0ac6955501f14b663255ed5cefa0d7a14ff79a993c4f42db39e67530d0263b55832678bf1502d2defc59bf6848d2929ff8959cdf4d7e44c2721786b2306a8e6eebb4ba8d470d15bd8e608652c5d3922aedac36727ff02b55f3e4eebc38924392d28306f8e364f61d8f7cf4749165790cfaff47c3ba7c81ec5430c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 4ea21ab2ff547aa2e8edb93ce6e041b654793095327f4fa21f5bb5a06d84c40cdb428e99a4fee6e90697cc8e79f5a1919b47d057b79bf4be5baff430c28896a336705c57da70586cceaba902aa3740be61b41403d7bba0bf939ed2faad83206e0a41536247fc8b8e4e58686d0d19b8cf3aeabe578f4af256100a79472c4d501dc32bd30d7a921574b1e0d4f4ed2151350d246ceff46abd7b588d66c519d7191231461aab4009c03c3995b9e3b7296eddc6db550d8e6f57d1496fcf2d1c18b993557f11a7df438d4a9c73b680fe653297af059964a691bfdb378497528c1ede29bda74389bc462f6729d4ee3303e6e4ea17ece5e270e2dd2bd5ac6f415f972a9f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 8d15a2f44d4b458af3d83dc082cd75e1fb78f6d8016a22458afaa019bcee0fb298d2990941c1bc9c0594fdbe4d292183b7b3c7d3a747117cab05a1312c34ae5ab16f25f7f002b8ff9cc905d2372601103f12c6c69d91ef320d0f31775fe72f8d7db1e8e0b7a6f45fdccf017b74d4e6a3af16099be38d605921652dde236101c16ed6310e126e36b74936a04ca0fb0c26b0d4b28b1aa2ad42cbee98747b7c43ed3ad7a5388cab80b25b5ef5be9fac24f6d0b373919493f928df49bb415f7842b47c13e44f45c042da263ea3b5b989312bd6284fd049a59ffc5eab219440874d173bd11744419aff23450f86d7c7bea2a341361a306b299a8513a94b9c034bfed5\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 4f802efe0073cf430f7af010f23dffdca40a4a53db96a5cb00431170c6ea57d3", "bd6d50cfb0cacf6772017adc41810de36f020efb1e00e500a3ca6329ff3d88d86322c0764d4b11f75746b78dfb0838a848d24e0c471d58743a296f10b3fbf44375b289f87ad7ffcbafcaa46a2a0301270b48d123d61ea6f21dc4666df0ea2078140b742ae75c1887d29742dcd7b92b4cbda27b98d8e16b43ced64d5e2a207778d6f022f3228c0b7edeff81437d3669c418186e651b7ed2df8963c5a71726d1f507c8fb694a9a94ef7ff17dca9e1bd79c9686097e7286665a454a9b68acc4334349d99b9d5ab7093fc36c0c0c11d41ac6de2e4c3935bd0ec2eaba1502d22ba0d3\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 91a3872121d32ba547703f8a0b9c9aca280f099b9c559998fb39d8841f7ab6a1fdf05a81f246c324ce435d7d9ea135fbc989e15a56df082b5e1c47b3b40f86cd5db01304ffdd328ae99d205d4185bbdf506acba181cdcd2d1d48be3b860d96e0c6ca54ce626372a2a749121af68523decff2c4f02d9d6bfb3d3b9a175e9ce1f03e4616230d32d691a4a8455ec09995962d651cb6f85d2cad6b09e35274368f2eee8ae5c7aa123a16407bcdb200bb351ede750f4798b083ce82f2800e04b66fd2be942b4a64d56dd582de56e3da7facc71157ddaa124502cdae10591eac676df0c94224649cd109027af09cb147dbfd9938488e7be36cb1146753e7656421e90c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 0000942fc136ac976cfc686ed13a38314c9c8b570a4afa2b18ae0a3cc39173a1430c1cab8893d530d4bfbf98251035d1fc18d18d905ac86792a1f597c08de11d9e2487dd78900a0bf79239f75e155eb0fc6d151cd7acd4664ac606c396494969422c6a321e12fe747a3b0601afaa43a0d9c08c776a7bacd68ca04b3b5dd9e8c9dee6773cfe652b923ff9d4e82d353113fd7e0264189556b1f28011dabf2fed6beb47498af5a6a8b0b1ac9640e5acb53ebb90bf29b7783a01ad6b4f4595e067711a49f8f1cf00443292251d2c0551f89e4271140b03681e8f4fdfe62e588f565c2e5288b3b14a488f14751b5a493290dd9365a48ea33011ffadbd2b898bec921bb1ba\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 942fc136ac976cfc686ed13a38314c9c8b570a4afa2b18ae0a3cc39173a1430c1cab8893d530d4bfbf98251035d1fc18d18d905ac86792a1f597c08de11d9e2487dd78900a0bf79239f75e155eb0fc6d151cd7acd4664ac606c396494969422c6a321e12fe747a3b0601afaa43a0d9c08c776a7bacd68ca04b3b5dd9e8c9dee6773cfe652b923ff9d4e82d353113fd7e0264189556b1f28011dabf2fed6beb47498af5a6a8b0b1ac9640e5acb53ebb90bf29b7783a01ad6b4f4595e067711a49f8f1cf00443292251d2c0551f89e4271140b03681e8f4fdfe62e588f565c2e5288b3b14a488f14751b5a493290dd9365a48ea33011ffadbd2b898bec921bb1ba0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 2fc136ac976cfc686ed13a38314c9c8b570a4afa2b18ae0a3cc39173a1430c1cab8893d530d4bfbf98251035d1fc18d18d905ac86792a1f597c08de11d9e2487dd78900a0bf79239f75e155eb0fc6d151cd7acd4664ac606c396494969422c6a321e12fe747a3b0601afaa43a0d9c08c776a7bacd68ca04b3b5dd9e8c9dee6773cfe652b923ff9d4e82d353113fd7e0264189556b1f28011dabf2fed6beb47498af5a6a8b0b1ac9640e5acb53ebb90bf29b7783a01ad6b4f4595e067711a49f8f1cf00443292251d2c0551f89e4271140b03681e8f4fdfe62e588f565c2e5288b3b14a488f14751b5a493290dd9365a48ea33011ffadbd2b898bec921bb1ba\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen138 = 25538; +static const size_t kLen192 = 25538; -static const char *kData138[] = { +static const char *kData192[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha224_mgf1sha224_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 56d0756ceddf7b1e5b258f783b99e036e25675eca054ae9b6ed7552776c69b2728f76e08973556b0a35ddbade9d462ed12bfc46fd254a07ef4ee043ab24d1ef00f8d214cd1d906911e92c4a212d9a981da74b8d18208153d583035d6642b87a23371787867efd02c336eab01486266c853a052490deaea430c6043a6b240b6e9d71e16f29255f2ceeb35d1a4ae25ae0dc9a436fb5dc30381cce982acc824961976df683173a02a540c403f3c8560243ceb5b798abcdc20f3c85d9532b0f0b0826f1b6352c5adac757fe3224b822455cc529fcdc8a220b0469f321f56bd1853d8a70b893f404cc06317e084173770c7d4c836281ac251353fcee4ac393838a1a1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f5]\n[privateKeyPkcs8 = 308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f502030100010282010056d0756ceddf7b1e5b258f783b99e036e25675eca054ae9b6ed7552776c69b2728f76e08973556b0a35ddbade9d462ed12bfc46fd254a07ef4ee043ab24d1ef00f8d214cd1d906911e92c4a212d9a981da74b8d18208153d583035d6642b87a23371787867efd02c336eab01486266c853a052490deaea430c6043a6b240b6e9d71e16f29255f2ceeb35d1a4ae25ae0dc9a436fb5dc30381cce982acc824961976df683173a02a540c403f3c8560243ceb5b798abcdc20f3c85d9532b0f0b0826f1b6352c5adac757fe3224b822455cc529fcdc8a220b0469f321f56bd1853d8a70b893f404cc06317e084173770c7d4c836281ac251353fcee4ac393838a1a102818100ea6010a0017d4073198610d0e761f286e3a1133eeed71b4fd4dfb0d8b52e1e1d8ffc58d9c10396629952eb002369b22bb9c3313c80330c1f3ab7a3fcf8d0fbf5a1c0fb7936ef20d51373b21bea72fcb7f70275ac41d97b566b71f727a32f0006de15e7f9bccfcc3224106f6b1ae62d59380065a48ef7bd015ee6dabae0f9d78902818100d52ed808d74a79b3ab515b4f2fe7b41027472c3785eb25587ae31d3500bf3c6ef20c427e223efa4f2911cd38cfc4479f28ae495fe3e88e94c236c0bc1323d71027aba290669ffbd7e0fbb6f615df1c9e4fe5abb5a90d4d0b6d1dea0ae2b249e6a5102092c998b60dd920d09a2e6ecf2a611793016bc0c92de3b9d92744bc070d02818100cb64f6c884c257ae0b56673d83af62b360d3a64a1527a3d211e0d62e1a7d9d30f6857dedeb2cdbd3514fbe14eea689329d1121a76971e3712e99b3bc9389793edf5304695b1d0697233c62330bb12253dc0ecc63e2f983a9a9b0cb5620ad670e8ea8e019c09b6c8f8ef09c608c85789156a231932f671b251760ac2d45944c5102818100b616befc3e3824dfac535f74b1ec6d46e6e5ca04dae4510fd4572d595a7bfdf89dd28ef101fb5cfe448c2a087e9e9eb6799ef4996d27f4b1677a3101f42f46c14bc134a7b6a0ac1266df5a15b3f4d0930097a22516727ffe64838aa7259f37b44405146d8cb85db8525fcf0e02df2f2079b21324c18ef7c7b49dc7b7dce3e5f902818040fbda2e571060971cc6aea0c1cc82beab4fa0361de43a55bd2b399f25ed89e33c48983f409d9f27292770d5c0ac1b31adf766045e60d67b89957c81c0f3b7706c3e1418926bfecba0242ba54ed95ae1bc73b67ddb1e3f4161380cbbf1db7d3dbef852ebb38063bc2544c9c29f47f416f14eb1ea3cf2bab933d21c2c091293ce]\n[sha = SHA-224]\n\n# tcId = 1\nct = 5b467ce0a97ef94c7956b5f2ce08f88acabc4e9d6e7b83e6521e73c03abe9fda31c4c2c61ea1dcf5a4bea5f68cd1c17198c9c9f22cf9bcb6797629b9db4d96341503d7bc1286c0c47faca078594ab01530f88dae2fae71e5601c8a79040c81afda8f60fc1853df885885d8d2cc6bcb905f105f448d984e4a2374e78e4c357ef5674fe9917e30196d33fd97c4d67cb98c2a0c3f30c410453679ae748fb922a91da74359ad8dd9b00865517e7f225a8c999bf7c93bfa83bd687404425321e73f9e1fb97c11562f0622b217b09ac3542e0ac650a451011431a870c2ad77b9be4c72068e25dcaed1f2f9cf9a2a8336b407711c3fe16f2bc2c12e5454275ef783c732\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 9dd1ed2ae7257d576d793a110e0b39d85fe2b312ede286f0c1bec4fd975f10f9f51d9cb1b467de234697c428094a87879434f21f91e39fbd2e1d4b877313af6d9c92f4a7a16ba148fc5bd48c5405e27a9bfd6f2832f0f40fdb32ed3067fe2952060e5726a9a97d55e055b623cc42ed6a4db870f246ece6e89ce346060a4a5cca214a35e868231528c0c184a167f1d7c331cb0c1af95d6abd6dda250262aa54f2f6016d12d3b530dfe09d31eb182ea3718d8241bfa3e60137db838043ef4cce8ba28fd32b94198501d8d3d81dc9cf7eb5163c41753abee2ccbcbd368b8383b39bfe0739fe84f3e2b32612d01b324e4408b727318356ee38c200d5148b6e246bd3\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = a042226c1eac49482797ac7065940a268bc9d7b71a84ec7ab43f2fec5af2e39521780c7410cfd7538acb5d17d213d4e9ee1ae14e44db6e2249f97ef1ee97983e2bab3d2ea4775c4c8cb79f252cc7875dfca5214835dacb1bab7da6bc7781c15b56546f9273f79025fb8cfd90e632da174311aaad6cc5affbee024ff1099395f5cd9f314ec3cfecf089c6703296caa433d6c3c5779645ccd5c2702dd916aa74963c1c11d30af3348ffcd6ab28ea6b8076a8a82df890186c1821c1aa18766d8024885083b1ac5ade07aaa0bc7c5d38acd6fe392f70378e2a64403c39fd4dff70af9ea96b25d2dcd4ea4f9334cc24a888d1cda58af7eb85bf04752c379491c9d8be\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 54a3149fd9a580492b16ab91406c69164f8091ce0f5f57e9c2c798fb1cd985cea1cb7c3d39e2ed35fd5443140b7f2868e3090cb90a4e1f4f9efb8eafbe93e6ba65e2670778f0e82c403921d29d55f3ba5a965ed2bb623f6bd39078b859948a7f0dd929210c192ef7fd28d9ce9d04ac56f785ecdf5b7c98cc2735f0af1474125fefc2c063893868eaffc6bc61c80551093926f2b79c3d207ce310c3cd11063a274760e17ffedb5cfa640080a7c233ba38b95c3976a0a284ec904eb3ac75fd2156763a3968d01aa22886b3eef912e3a0fed03e2652eb18ecf0824e2879d70a586d92ccab823d16fe430fe5b5a4115f079b591c33d31970fa8081972d3f1c6fdbd5\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = bb49b660fb692e67ef888b55dc4944726ff955229f20593757eb616a796035bc3ee9d461d37dd6c5a5cb34303eb739b938dd53454675f872db127ca7cc6b77c6ec7188a436c09310004777409a7e680b8631cb420f7e69f04bd8fc3d1f735754a297a05b58ee52188b8fd00c7f1059932b8fbdc5db8321db0599dbae89f62d7a05015ccaff40a0505baaf4bf96a62e0f3656e84fe1b5e14117755d3c2d4395b9039fec8db8d02afc90cc4589d232f501c184753b6c1c9d687a77e6a40acbbdd97be6b43deb327c4a75f3e09b638df85eeb73cf8e6234122f04814c412407003d703d8192e02016d33638765f5aaf83699287095b47eba7d48db65541e4d8f6da\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 9f0a968b8aed115482ee51eb63b25ff07c3294eb3f8faea6af968408f4bb7fec7b456e2459626d5b8bf10ca8e953b0606627607ac227155b7accfa1ec90bd94ed216b7a7bc8ffcdec6f4ad0441dd24f1227a2f2a61e0645fa9a4d325f5861479a51af341bcfa8f699c64c02b5d2979cf7fa6ff2316aa3546e31bf0e17b0974252019c61783594adad3f8ba9b81780e17a646528e111994aac91fb056a57c19fedb948bcf1270573ab35cf903e1ec1ac33ce8359c3dc4210467a1620b1d3928782ad079ba9bb1f2040e157c7e5963594a7bc855b9a476adcaaa3be95f28ec49c934bd2a2440e6110ded6f02ed569206cc986a40f60ea4a97b30f5dfe8f38a6e30\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 3a2f3740f3df888485a993c169874d624097050697b21f5d3b6d19bcd373a6005f633931446147e8a4ee53fe11c305d397670019cc03fe83eb15431de666c1b7164184c33ce2508bb0c0e0c79639e6be07b7f5435d37e5f1279bf033ace5fa259c83b19a62f8f9df45cf0fa8a2b1b0b3725926c40a7fb2463da7e80e4dddfb260b3129d4dcd8f05e728f5cb6cd484b2328b8d8c5e421c9a7227daaa09cd0e7425886a9912a38d5e6cb716f0d148e17ea1ffe520a94d8b6235b5c82579734c642717cdac41d65aabea49e05cbf41ad2554ffd97fdf73d14d783e80f08eadf7fd522961ab00d89fd964b6f72039a5f1c76cf029f2177a80bec3cc89475ea3c9010\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = bffe021eb677345763b20dda24b4f482d02b9c42a3948fe4e90391f079f527471795b8ae9c8bb1b5437f56b8a6f60e5623433b02851a387761e27426fea806ad68ae140cd104b0fda542b1f00130bf89fd565c13cbdc28a27c980a0707d1d5a1fe275aa2acec5290c2892a0a28f6b7e546a89706965d3be0ea55a664471b03017a3c4414c1c694484b58a38eda72091cbdb2160f699f5bd1f53549f4e03de3d7fffb080bc57bb2", "835fa1bad1c19eee3d330f3e8eaff8110f226ea824842ca9996632b832a4509333ccff3ada3c6b9431273479ea1d0e541fe6494c9f053ad07d6bf9a4ca17d64fe50546428ab72fac1602637c7eb7ddf6ad081f6c9d767b4177\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 100de36f08403f5f8d3a42342c9471b3a59f412d641d402971d0208fcdc7f28cc5517e2d6aafc79d59a49c654ed10285e75f8b600f5ac4906d3716dabfd42785b6698147dbcca09eef28ee96c78699b688428e2de34341ee0c81febc6ed43512cfeb9304e2e40738a20d7b4847742f9fad3824f0cf06e437b3ec1061ce8aad0892689c3388ab6087adae203e23019875768bd53a4568986f9cc91a65a5e5e50c0ffbe07bad0f002a03dbb3b3c61647c35e23d8658879956fc23d5591a6142421490cfbe8e12f0673e2e456afd44b6f463ef3d2d5b51755305ad83181bca08f14b2a702e4ef2cc0786b69d9188714e9a4e9a1853011c515a22bb1789c47da7331\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = bb47d730bdcc0fbefa8cecebd029150fe5d3c967a429c40f16b48c8d07848699a3ab5d68ddb32f76e0e74e897bac9405a1620dbe9ffc2e0d653924bf5da381a903a278ed7489a62ca5b94c7f963a2604d5cca61a637d43dd78ab44314b4eb3547e2e4a72afbabed8cc8d48e23faeb5eb036c42d542578c68d72134feff3cbfc561348a2db48032e08f98765e87dc76600504cb7217fec04ee9050bd3766657719757f389c0b4f0bdb2fdeb8e5757a3a9b2391ee6eb2e6fcfe95764706c0778e4f0f3c7fc024f356f999e5f50c637ca9be7ff20f65edd5c9f6ec869c29657b1792225d8a16574c183dd5f15f084e97a9337e53b56f5d7bc54bf5e031922959f48\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = c2edf03b946ce57141fafbc89189daa734d0f388c211a322ad4ad9423ba5f31699abe68d5c03c0ccd56b1a39abd3145f4c0d59955e6cb502d6720c1af31ec511fed541e1a66761a20422f5490d3dadd815390a01da616ce4d7934c68e7b1c53d947803268d81d26429df505c22578f55ae0788cc619567f02237368258d2f591b51d61f088d972c40e4fbd4f50f72a674d25a1cff3b49edc9019ac9945cf2b828d4345398b3aefb63c9f0497ace4b7f9cf6c087efc93802e1c19326585788df3aeef36300f78f7ad016cd4ba6c55eb49d36e0d49f97e1bb8ae12e9d9ba66d18aa76812008eff83e0d7d45212ee972957c355307823fb692bb2041e6acc81902d\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = a7bf9e3d83a704bc5d3c672912a883d379f18ad0a8480c8b062b05def52191ecc81b2c6a8f5783ca3b401cec23f981f35246e3d45272ec73ed416713a4afb104f344dc9e73c4af29948dfca67f245815bdccf4491c5ee7ca2827934db728e08778eea48cc82da3ffc7b94434d2ce301e801feebcc39a57bc7450ea29d1013c31f716809af36189c3cdca42e78e31408f32b98dc79619628ca348ddbef3f18a942387b9479dec0af05e382ea15bf0280a9027f7f24a3150da0497a13a8f394070515c9be5fa0c705c012415dd7b4201f2ee28af50178f59e5064685d75fa54c187a22f2854051d6084894fd902e43b20f18d14091cb14804fd9e51dc681d1d9f6\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 794bccc669c6a853722db8e7100d5a76bdddd5997be5ee52bb6b30751672566da38fcc38fcee38be9ef3b9fee98eba9818277fab9367e3f024cb17babf71a71b4c03619de6bf25772b64e670102d5eac40c61250ee174aa802277a48a7488ce9582dedbfa941e7ffc6791515787652964bfbee021da63879251de9c89b9d9b63c547253c1b539d0ddec1074ff864ae6360db0c60492c5a992124593a797e7c4c85ed6bb873d5718a24df180f0739495562c8a522243bfb8c6dcef4bb099b7fb42ba01486e48b6841cadf7f8a8294c0234b779a8618945d7d557238fb7153f9f3fbaa89027eccaa49c75c583fb5b2309650bd4fdcfd3d77b9a181915fbe009507\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 3155ac16ff4b2c2e256d01ab5adb8eb7127076c92fb72d9dc30f217edbd10183a15dd8fb41ea074dcc27bacdaff2a5c58193fb25a18f15a98bea320cb52be2031f18b247815599f43f640121f91873d8a61cfaea011eedb77474bbbf9b15481ece1b0db5b56049294539168d6000c36dd0c35d11921cf5df1a0eff4cad1a32678700a4433e5fc90a7cd14a1fbc4f819e8ef74db8474d3c1c1aeda496226e8b7e1a184277a064be61e932dcebe94f366831f54088aef277819cbe29bfce1332e4d2cda509550711a9edffa9fa36c1dfaaaccf0d8a67419ad9cf1a5421a2da4cb2a96b94c0aebff1a64e4a932f6361b50685e07e9ecd23634d64a7610def333a40\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 2df84b7d330dbc93c4804b6112d997d012d1bd3bc0047630c9c7a97b494e295e25b63d5ec98a62878213bf0d523f7b8f29c5aab3fb6ff08d336cb078ac9ce0c3be123eddcd83ae7b8189409f4db89ed764c8dfa4557f95630065e74073bc92e6a725550f19957da5cec59402f82622b86f01f92e896247e80a2cb876014a6decc3cea0e3ca9290eec17f3ed80fd54e2a0410daae5d9705dba809ef3f2068038db7e74d0b1cbe8e1b3634fae69166e0348c9b1fecaf9915e9dd09cc8017b66a2f3d4faa8b51099e69e4f68728c223f79b32bd1bbbb01b9ac4ef18e226b9934290dc8e88369041624396f4dd27f6f570e18d790d29a894c14c1ab62c59b81d16b5\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 6995411d2531e2142f0d8bd65d41d2bf17c3f8b74626ae10c84ae86ffd0e53943af5155944da2d9eefe255f92aa8c4b29aedb9851202d93b36df48cc0fa6b70c79b8c3d5bd42f5ffcd1ab9a223b1126c2018c0628651f6c23d5d676365e3a5858cabd99eae861a3e91c0d8136d9e6dac7e95e4e1c6201132f764922b2beb9a47fbe9d5ed12107aa113b50cdbfbeca7ccfe9ae5abbfbbb28804c1f7b155b726294e6b0d77b1e845ac80c1b8e7936cce6229c7202d9be49b90c1816b179012263a64fced7858f52d80b8565ff2b0d7beedfb6c6bdaead108c19b2007b6872e83870133f52fa0caab1842e72be8f9a3d66d9e34cc16a650c69041bbdce7ad707878\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 5abda3c551401f34bbbbd1d4fc754b3bef1278a4c7a349e297c89ff1d98005c2c230312b998e000926e11132895d2c92b9d91cdefbad259528e1b95e5692b5ad2a60b304434c75ee9ca52a2135ea626b3d0415495062b5433522d802a370aac20123f8060e258d6540debfc200247bc61dbd72bc00517eed3d6ae66c064e7c5bcae2187b152024e8d092664bf1883d9fb64d39d33b350656236b92611a2fded06cf27149d479196a94981264a3fb4763e34afd94550d73615257cbd75ffa421aac56d79c76a63231daf70775cb510892ef88f2472ddf66ee7127112d2cca7006b3cce968538f95250aba7a914f1f3074433be80ec762ae2b35b463babe9d52cd\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 1aae5728fbc6acb37194eab4cf6de62c0d8229094f0c559c285c86d9cc2387c16639a8f567ddf7ea388f6e3785dfce3edf8b3dacc6f6b47ca90328648141623acaacbc02b2440cd5f3d5c41f7537736d9cd5c7a297bd8f773ffc2f616282084e3384c445fa3328ae6448232673e1c1fab93cc441ba6817099c64e22744e23c877720ae09f1405ab3c05837a80bb8f8c9f03476195d1c8fbb8202ef359b4b33911088fe4fbf601044702df98d395b4f2c19d7cecbcb8a544a8e50fb38135d272ed2b8d9a41432301d15822232b361f077336675c36e157d992d2f0a2a467f7a40a1b899ffbc1a310c92ecfa631d03f21a459310c05cf84a0a2bf58c93178e2a72\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 67bc8ecfbd98ec151cf04de90f1ecc3da09b7f94dc7f8ada3750c49de7a98173a59b908a09df6877b3787f1b74a5b456f92cddda3f1f14ea05d4531725627a8003773d0f6f14b4dbf5a06690f9d8b966e473741cb695e287c1f3c60aaeb01ca74e673f080928793ac06e609f54e4214ff53107cbeb73f32073ad771566fcefda28ffbad80a765eb52e2e6065227f21f60e06dac7fa34384968aa2d355184fa8202762bff510315ca73a93daf910686d36b77f0a4a9175874eda4ad07023cff631450b2d2aaaf99be755c36ac2bebefca2e402a8e4994220ebffbe080e84582c3f9ca283546ba8b9fba3b7aaeca60d8b9d61daa87940b9e500fbb47f0d6bde479\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 2aba9ba6b55fcba1efd92069966c95ed8b567213bef9fd6bba37a7b7c502f7fed38c9cdee9fc1c221bd651f1df6f1a938a01ef80a746ca9478ae00b7ab697e2ac311425a38e4384002dea66d9824c79b56f05b00bba5b26f852a7fe27a869ef101ca73c1bf8951edfe60da5b5ca9650a2bb04640026720b8c8e94e941b1f6cfa3e9475c2ade8597515ca64077c34e896817fee30d8c80e9b4802b5c8605f7597e7f49025237989bb253e06ce5673481d36ae7f70103a4457624dfecdc953207102cdc2efd5d682907fc4812a31fcb55324b6ba2ef697b3c31cbf82a5113e1ae8fbc2afc8d63a1ac9c3a54a25cbd3db54e934402b1c5b07ea445e4d21f38ff790\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 8941c4670d7798f1a935da39de654e7763329afed53c9ad2c2c6f7e8214c", "19e8fb27ecc137be1e54b1d51f6ece4e951fa2e7f4e39a3124d9298beae8d2ae35243b83d216301c34010df33faa631b50f87fde7e4f7c34436f62df2330fee4366da95ac2bf891a9fd4fa850f7e15430b8c966ea5bdd78f5172a27df1b56716e1260f71dbc42fd4fd0b92b90e9de67f8b4ff47f20365153799ba212ffd601f0f7e674dc532ccea5619e039068990beae5f10d39e5d1f860018d25a784665d6ad50e06e59386e13b6da201980fa5aa3b642527aba012269691c773484ff2fee7a1b0a1fe6db4f1ffb1a7da8464320ebb93557c5750bef6794696b3022ea92d01bd52\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 956180f6a240d45f212d6eecc906477151f0af704e743ed7789c06baf8cb4c3ab00d30cd0e13a77f1905ef37e55bbaad3c7e80abb5e64f4ca1aba2861d98f504e3cf834a2c669535001b0ba494e6684dbfc2c7f43dc14a80ad73c79856d18c26f5c635015e282bfb4344229d9f7719c743baddb89a2f64bae603c8f3da5e07d09a363a86d3f71b7c038b939516e3930a181f6b00d6e8171add3f68d83c3d82a34e56868c84105afbbeb473a38934af4a9264dab2f8b3495e7594a25df693e71a5806163f1c44f8040aaea20586edce9050e1cbd7f8a2c30e40db9508b66c42f21a9cbb54a4b228455b05aea9486dc81233679ff3bb13a463debd8ccf55660b02\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 000054a3149fd9a580492b16ab91406c69164f8091ce0f5f57e9c2c798fb1cd985cea1cb7c3d39e2ed35fd5443140b7f2868e3090cb90a4e1f4f9efb8eafbe93e6ba65e2670778f0e82c403921d29d55f3ba5a965ed2bb623f6bd39078b859948a7f0dd929210c192ef7fd28d9ce9d04ac56f785ecdf5b7c98cc2735f0af1474125fefc2c063893868eaffc6bc61c80551093926f2b79c3d207ce310c3cd11063a274760e17ffedb5cfa640080a7c233ba38b95c3976a0a284ec904eb3ac75fd2156763a3968d01aa22886b3eef912e3a0fed03e2652eb18ecf0824e2879d70a586d92ccab823d16fe430fe5b5a4115f079b591c33d31970fa8081972d3f1c6fdbd5\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 54a3149fd9a580492b16ab91406c69164f8091ce0f5f57e9c2c798fb1cd985cea1cb7c3d39e2ed35fd5443140b7f2868e3090cb90a4e1f4f9efb8eafbe93e6ba65e2670778f0e82c403921d29d55f3ba5a965ed2bb623f6bd39078b859948a7f0dd929210c192ef7fd28d9ce9d04ac56f785ecdf5b7c98cc2735f0af1474125fefc2c063893868eaffc6bc61c80551093926f2b79c3d207ce310c3cd11063a274760e17ffedb5cfa640080a7c233ba38b95c3976a0a284ec904eb3ac75fd2156763a3968d01aa22886b3eef912e3a0fed03e2652eb18ecf0824e2879d70a586d92ccab823d16fe430fe5b5a4115f079b591c33d31970fa8081972d3f1c6fdbd50000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = a3149fd9a580492b16ab91406c69164f8091ce0f5f57e9c2c798fb1cd985cea1cb7c3d39e2ed35fd5443140b7f2868e3090cb90a4e1f4f9efb8eafbe93e6ba65e2670778f0e82c403921d29d55f3ba5a965ed2bb623f6bd39078b859948a7f0dd929210c192ef7fd28d9ce9d04ac56f785ecdf5b7c98cc2735f0af1474125fefc2c063893868eaffc6bc61c80551093926f2b79c3d207ce310c3cd11063a274760e17ffedb5cfa640080a7c233ba38b95c3976a0a284ec904eb3ac75fd2156763a3968d01aa22886b3eef912e3a0fed03e2652eb18ecf0824e2879d70a586d92ccab823d16fe430fe5b5a4115f079b591c33d31970fa8081972d3f1c6fdbd5\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# em represents a small integer\nct = b2ed7a397f2245207dd9db69744a196ee5cad1df24e980196f3e9cdb69bc3db3bfdd4ec01780f7a063e1daa0b670f0185ab9c19f37462a1fa76b50a580f9c919be1502d3cbca99c24827c738178da543e0c2b7a8714471528fc54db03921fc9558017e01a2397d9c31136000c17b558b72584a1b25d6ee85340e99ec4ee7163e6f205cf0c8f3077050efe8a244bba2ef0dd2c1d71c1ff6aa76c34ed678d343a644d6b03dcbb0b1e176c18aa952ee1a95592e9880d82a1fd4ae689a9045d90ddb95ebeaf30e35f7afeafb7a127695bde67a5e0a79277db6769022d13e2008e2a1205d67f8776f0f99571ddf73bbc611e3e189223f1e62daedfa12f4a2b0cbf58a\nlabel = ec04b8614d294a9aa508cf5e5f0f29ba3547a24e4c6bf37feea8d68e00000000\nmsg = fdf36d511ab761a3424c296760f4c8124a75896cd8723dac73d3684ec27193a22113fb6e6df10b5d34b906fa8b1503b672a0ee0498a0c6c022c7d4a82a2c7eaee28f7a38c9b53e60b9473ba26c3db70480ff58291ca5bd5ca3ed660337e5b08698937ef2a3008735c097e79815ee74634bc13d152974b54cd3326355cda4a97d1e6aae770028678d51f0bf04ac5765ebe78719a5632f58f5adb235889cf900a7cb6d1ebdfa41af651ce05cd16e08fb62fbf95746a3ccb13edef8391ef9f6c996939418289d27\nresult = valid\nflags = Constructed\n\n# tcId = 31\n# em has low hamming weight\nct = 975e78a8894d8f0bf47eb4b6baad70b000512823ad93b370c01f1959aaf252471951b0bb941dc89e6d552ffdac77eb6af19b407dfd767f4f608a82d0f8f03d25276bc2dfa69b39e2151eea0fd6505a997439dfc73fe9ae5d1c95835483ec4a41a1d7cd5c9446beb7d418302405ef80324fea76ac32bfe1a06db9ad6d651fbb821a025b82f78197d7aa3185b785139649479e896ad382be558dffa756c7b09b28925f2c25897f00bc4be23f907a5ada5868929dd72a1fdaae110c293ed039bf6bf75065c42870f9227a914e4c00a14b58f0dbcd0f5fd6c94596ad69a89d28a8e318050222fe1c288e5d9ff624e97cea755a733ca76d4564875f09fb2d4a4b0a19\nlabel = 8c9ddb95c6f32d5665a1d95cd8c6fb17668ba638c482e0d539c28bf800000000\nmsg = eb6b68854f2011f6a2fa9d614c12f76f5cee4b203fde576dbb232d69f7b9301154d7af5c8c9d320a7456f93a84dceb152759d3c505cfc95204a618bcc5bfb367f056b0fb95c8334dc354c82036e3b551309b5124f4ca4696d481cda583085708796059853abb72f63e59a64dc28f194356fc9ce90bf90aaa50846c50c14a4ddc6b8a71a97de2b8fb16a1521d9ff6a612b27cace9431d59038669ce497219e934defc48a24b7916b75e18e8dbde1a110b5a4d3100a2935b073ec3cca440f5d369572581894d06\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em has a large hamming weight\nct = 16e4df71edb9cce0e20f9bc613de0958325747cf1e90d4b1aaeccb1cb9c586a9896b04e18bdeda54f82fa113e54e05e10bd39792ce5d3601473602b0174ef3d81040b9ba9a237de71d255882422b1a7e13ae5d7d50ad14c2054b0734bda9f2c42ca169e89fbb1072f4819c6a13e7d9ed6adce1cf565ddb5885c17ce7200c795f73b8a0f6b1d76b7f7bdf03291fce95b4ecc8f56178f86cf30e71f692c53cec7c091cc619a5bbbb2ea063bf1328a3abc56fc61dcb5ea4aa78ee1075038c2ae17fffef8a487b94efa62a26c01c05de83e965dfd19842fb586b4a8dcac7afc952d231be7ac0ba96a7d63c942cea6736ac7f2682023c9efbb312157e57ef082cb9c1\nlabel = b42f55b1895be2324ceb2fd6f40f469df1f5f3db556d84846989c81300000000\nmsg = dda76849a089db6948515c7a512b285ee8fc97c5b41ff7f7d1acfcd1fbabb4163916e63656f85bb9e285727e22f03d15e93e0895dd10bcf276fb8fcb21ccd0bc8ef2a8f29b87780a43622ffa7d92f5ee6dea280644027661d96d9ac818e91454f68994b11ee4fd0e64d3be8d3c14653813a704f0c7410ac1368ff6bd921ce2c4de86ccac17ad58dc2495129c8e3d36f141c634d232f2587dd102c609b57f0ea3c821e620e5f6437b1bfc1d99f5176a79a9f7cc7ed90f6012e54ce1cd873f2aba6dbbdb2252b9\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em has a large hamming weight\nct = 7b5e8addb0384e472da0c2465cb1e03bd4fd865c148850710b5cde1892c0834", "458ab2429e93ba375ebe1fe26cc81b8f991f0d21e6372fb34660ca513650fcfee3114aeb10855b9b3e7713b779687d0bab738dd24792b6261182670bd09cacbc7a26655ef299bc715a51403744282d0614c9182030b51c3000ab17f98e604eca3f7edd824ae52607bbed63f14717f771374ded2b5a0440d1a2edf74115df754a5c7e1368326f90e245ddf73916b6277f73d0866fc4657a1b4470cddaf91d3d297bfbb04e03cbab5d180a1e3c63d88453844c30d91db2f458e54dcc7bee78ded8ff29dce2d07fb8b5256531fa21a95524f5f8467b5ee2a2d4061676eb8fb899891\nlabel = 842f55b1895be2324ceb2fd6f40f469df1f5f3db556d84846989c81300000000\nmsg = 07f559e91dcb945125f58eed3cce2d841ae22af2cab3b8181eb33682c8b712922a911f397cb92e66b536246c3cd17f27605526c5eb17d4e77bf7509dfdde05fb598e3b037e613804220ac88b84bb39fc8f885bcdfd9734d64fac27e32bef6696c09fdf8bd5117f1a71f5b792065d2a466d9e33a36c84b0bc3ea2a99e2a4abd23c50bf71f8dd61f8e848abf5932c63136d82c6957b6cd80e14a54d43c96f670266df22733de9e8ce1f399f0a123d7e643cf4e4b7aaa832a94aeb9d723b7a4f8639535cf4da088\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen139 = 21224; +static const size_t kLen193 = 21224; -static const char *kData139[] = { +static const char *kData193[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha256_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 7627eef3567b2a27268e52053ecd31c3a7172ccb9ddcee819b306a5b3c66b7573ca4fa88efc6f3c4a00bfa0ae7139f64543a4dac3d05823f6ff477cfcec84fe2ac7a68b17204b390232e110310c4e899c4e7c10967db4acde042dbbf19dbe00b4b4741de1020aaaaffb5054c797c9f136f7d93ac3fc8caff6654242d7821ebee517bf537f44366a0fdd45ae05b9909c2e6cc1ed9281eff4399f76c96b96233ec29ae0bbf0d752b234fc197389f51050aa1acd01c074c3ac8fbdb9ea8b651a95995e8db4ad5c43b6c8673e5a126e7ee94b8dff4c5afc01259bc8da76950bae6f8bae715f50985b0d6f66d04c6fef3b700720eecdcdf171bb7b1ecbe7289c467c1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001028201007627eef3567b2a27268e52053ecd31c3a7172ccb9ddcee819b306a5b3c66b7573ca4fa88efc6f3c4a00bfa0ae7139f64543a4dac3d05823f6ff477cfcec84fe2ac7a68b17204b390232e110310c4e899c4e7c10967db4acde042dbbf19dbe00b4b4741de1020aaaaffb5054c797c9f136f7d93ac3fc8caff6654242d7821ebee517bf537f44366a0fdd45ae05b9909c2e6cc1ed9281eff4399f76c96b96233ec29ae0bbf0d752b234fc197389f51050aa1acd01c074c3ac8fbdb9ea8b651a95995e8db4ad5c43b6c8673e5a126e7ee94b8dff4c5afc01259bc8da76950bae6f8bae715f50985b0d6f66d04c6fef3b700720eecdcdf171bb7b1ecbe7289c467c102818100dc431050f782e894fb5248247d98cb7d58b8d1e24f3b55d041c56e4de086b0d5bb028bda42eeb5d234d5681e5809d415e6a289ad4cfbf78f978f6c35814f50eebff1c5b80a69f788e81e6bab5ddaa78369d659d143ec6f17e79813a575cfad9c569156b90113e2e9110ad9e7b48a1c9348a6e653321191290ea36cfb3a5b18f102818100bd1a81e7977f9898122273ae3222b598ea5fb19eb4eabc38308a5e32196603b2e500ffb79f5b886816611debc472fac45544070beb057c941378a6868af3b7a03d3f9880ec47d5e089b94fbde542aba9ae8d72c57088d7abf5b131f39098f7bc160f90536abc9492fd4e06f3ed7299d4b97bb03677207d95669f140cfbc20f2502818100a94b528b28f291599121d91952ffd1c7f21d7c1479d99d478885fb161870ee1218bf08472612dbe5497e8d9c650688e09c786961ae3e2c354dc48ae34514759c4c23c4588488961dc06b414e61c0e1e7fbbd2923d31532fe289f96da220711e58c14019808e00414276933bb07e4efb9b4a9b37656917205209f33f09515d7c10281803af0e72a933aef09ff2503df78bafed531c02ff1a2bc437c540cdcbd4ad35435cf511763596543480629b114ca7f780ff7efa32ea0cb6e000d6d9ea1f2ef71fd9cf9948422a165557e37e755edfe70d90b920502eb478bc98a63f788ce3a0f856d6ede7251a383bfa8fa480a81a925af7b3cc538c4bab8c9f7597ffb68011d8d0281802640fbfbcfefb163ee7a87b6483a66ee41f956d90fa8a7939bfc042ee0924b1b7993d0445f758d51933e85179c0320b0c968b48a91c38b5be923e1097c0c562f88d42294b6a2759bafa5428a74f1270874e45f6fcc60f21602de5eccd143cf31241f5921b5ad3983fb54ef17be3b285367e50c999c67247b552fe4bfce945f7b]\n[sha = SHA-256]\n\n# tcId = 1\nct = 8e6f127b86ed4ce03bea0242759dec562f3c0e475d70c950bb9865c5a00c19186487f6dad25e6ed4600510e067a8679cdd63f7718af92e5cc297d74d5ce72472c404083b156924c39852b03fad90becc3da0cbb1e80556b4010e9569c61e3b188b9dbbf58f779d3be5a9a7d000ab596d69c9aa48fa6c1f1fbc5be79ec39e27b7a76191b681a02d61cbc5924651198bdf9bb7749ab4a515d1ea1d9d32dad38dc703228985985043c152e2d8e918b652d67a40c2be1e2c6cc2fce11f6c923714b11732d8fdb1613c46bfcecafd64f9536fb7b41816736e3e4b62a1dd6e4c26e8a8f66d99cced308127a39ea1f21a6d7886e22aabf3ca6d6464278d930bf60f277f\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 7a896725e0944db789d4caa96bd8701fdc100a26ca12e45d7d9a5f5599fdec0a8ca5ba9e2e0a5c743d2e82a0006b915e6572e066c30bd794e98fe0959519f418d5587a5012ff9b0c545930e3065cf8deac440ef60715ecb8de63f2bea7fb80bc81cefd2f5b979bf0d32e07e615db6a363f0447bec068db90a9e86bb4703098b3ddf1bc34b2803930b56fbb8e026b8691248d8e471ed6dc0a90905f96412470f1002ab2a754cda6dead97c5a05fbcec5d0398c1561876bac021ec4cdc6915d929ebb6fa5ffa1d6e37db99951fa19670ae0f8bbe18bacab54bebeb5ec2dfb4a0cf69dd7077b3229fd0cd8580fb56fa13c399364e2bdecc1a0bfc6eb67f01a17fcc\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 835a8d5ab336e2133ade3b3537dbcd908a49d3933d0747e6c567e6e4938346b40a208321669f82ac6fe7055b4c435c455772ad9b3809ac65b5223c04329f232aaed6412bc6f024575fa9eee9d5f813e384a07289b9b203cf8cd7e2bfadf949aedfac4e08705a17e4db719ece091d46b264eb40befa199cb27de1a744c96182483ce84808686afc56e414ccbc2f219057af1d7e23549f44f7bae74f135254cc965227aca4ecd7b4571cd05cb2c99b6fa55cf7ec9c4cc085cd0ad0ce90e3e7f68af2ea3e2a6097b81a5c5091c31026261a479d46f05c45ae016e86029dae86c67afba8b8b6e8e646a94d07d07f3eaf8ca177c6c0ed05896971c0a911c846ffbdac\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 822e8870c00908cbf5032226547d38e423deb912c49c9fcbee66920cd2e9e3197b3fd7428cbbc5e90e660545720f180ac0ce06205cef8735446de30df32c8797380ccce9c0512eb285b7bffd883ef00fe118f027bdc75700e511226ec4da35f406e460fb88f9af2e9c4ec219387676ae21cadfad0fb1d704be69d0ebcdda90dff7e172612c972c6a974b828acee6ca186c71b50376d1ed5eb6c107408065473d53a2ebedc833f07f60f909a6c42464d79d76f94531a0d386213fce5efc2e66f311e73b06142f8245b063b9e395722dbea029dabe5ed1c12788b890974ba1d28492cce2c90e0a3026c282964763a030a7f7f3f76a72843a97d9eee17cdbbb00f4\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 94712359a945bb4711cabb40b95020092c43428748b10e0f11189172d7052b28401d96ffba516a9d491895e9e95308562cdf17953a4e05bbae8c8cf391e7c363506ac86d46932b373963e9e661e9de2df322719e6369f3ba68f42bba78ac932f7d2333759a53d4d18f5990b18a6d4d0af96d9a9451b2d5a8c3f427f607380997b5b2029f58f04301b52c18cf57c2a763b546a21b8da9627070a1cc30bee0c75863b196128988ffea683a4da5203924db470a53dac36a3fbec3dbd9710f85ff6b0728a692d640ed7ba67b7e493a7b95864a2191f617968ee1efdcdb5b015e45da55086b2b382a380cf66bc61521b2327a6bbf247ab7635da9a48acc119e867467\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 610aa2973bb0d67efc725204a0af7db852bcdd8227e309e6a523ef627555b7aeb783dee396934b61141590952801c027a559a3b7380abb6724224cf825a9c74dccfae278719551bbf0e6a8125d64bb437ef78c24cc00a52fd9a716ac20102b5a1d8fbd445d9a2d4ce2c55a2f549c2fed8e5932cbdfc8deb907d973834c2963720557668d61e3f2e53564d6db7b41899873e3ca66a1b5186a8a545d27915aa466df12ca7163a7d8137eea71ef80690d229deb089510567f24756f0f70a1dac609a57a11ddc400af943126e5c5b118b76b769dfc1a7a6ec748b5b906baa0f0e188b1c6fdbd6bc307af0fd9b4602ea62513430b3208e3d690707fc2d28ebc432388\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 76f7b6e1cf45b005ad58b5354cfc5799f74edfb27f27b414b4d25500a1ec4bcd46c6b65603b204f69a2a71b8d1099ce96c8ee52e119ed9b080d86d82789e3e5777cc5f920b147126ec8612b206bc5734e828ac819f90ea7191832d570d376df2c4e3eb5070fd8382f8c0a9b89da928bfbdd24bf1d17ebc83f9237a51352ff04b6bb3848cb6a9c195e5369f4b6ed9b4cc166377f88c7e6db6ef78c0e1bfbac5a3825867af9b22689b627dcd8d1441b515b15b78688b52b04df4157a888aabdb9e792c65fcbdcd03743fe45e637afa7e422782e6da58b95163acd59353e634337abb1c15b831a9dec79c517a5be0b4ee43f7544a2e9bf6af2bc53b080c60dc2bc6\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 338514dc5a9ce8f20a5040f26a830018314c569249d540e2dec247f4ae925f6cda2d7a535e4e20e5348bf14f6c87861b37fbe4901758dd38da7cc7cc050edd1e208acaf6ab2d332a6482c4e5af4cd4c4f1f9950610ff56ef910b2831e3f23b2b6d3325e8a9f4fc50e0057a50af5db51ec2a1f78d0465e5f54053113df300584f458a1ebf6e5b1358f2454cef3b3e4aec9bcdfdcdf5d88206bed1e9a4e7c7c8dc5f087d66103bcd28e94c", "2c233eac1706261aa6aa67f044bb06532954d91653aedcd58e8231a81c52aea96bb4ad1adc5e3c2183ea99247a4af8011b415d618c67c94f0b276bdafcddc8b646182989c1db26da677bfba285c0ab76c82b80a638a2\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 31478424e4255ab21a4d9a8c5a3daa8f0dd5416f79c2baab2fbeef406f76c493cb436acd030e0bc4d09432d9983860c01b1c559ce095b7d91761ac2e4bc5513c68ae6bdf747d556a84ac07133233368fc92d4f32f9bc9fc415c3d0dfa87f84853a828fdd103b8ade889a020f965304cae5324f78e36c72cf5d8b94496a6f48b03a9ee3f32fb435d48d31002ace7d212a108fef640f55e715a148335b396e900ca3fe96a0854764b54c3187e37d9eb5a65b54ce6676d3747bfda91ed2f536d79a6976fcfbbd683ecee32c5a8dc29622f789579a370eb7d66a1404a376a43ef584a0e2eddea06fe60c28ae08b7d1a8af26b20e50e9a8b3f8654e183219af3dd508\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 90689b191d041a9bc69ea93b26d04236edee88b8af6c0b29e9b438270b242dca467ee4874acf7f9b6b244c3843674962c9d0d67fdb7021aba63fcaec2eac3b6b5114ca4b242b08a1ddc1dc671b403bbd5ccb57c7f6c87cf0dc995b38aba6fe635f4a727f6b164bd36a5ff5e7b91e42bbe50835638cf9e3c7a5397f5f095784c3dc5c493ee1a22a9e2b3f28c71dddda2553e269d6e818aaad196b22e670eec5832a84a0f89cb9bf5d8f69e35f34ccbef4037e9a4b6bf2d8d3197bd02acb344cbe27006efb73db0b9d5493dcd14b95b934afc2768af27d1b3b24de694fc0f00f757488d231e3e2cc5be77530f512014445889600bd1a265a4bf188f617b9751783\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 9edf0e6ae25a3e7b6f31fa13a7a31db0e6ce2faa624c2ebcba9669bf5f205758e1e904a9a738bdf430072b0563d1a87f16522811d645cd9f85f13359d2961bbc583a3b15c66ab5a0d1373c2949261e3f44c2a1a88e25190efd30aa9fc410d2d23148c16daa90457bf1ee77c2d344525036e037ed473275bd535fa961a66e47072b586915d85d3d7edaae7945b5e7f08fa15a4d08cc669b3846b1ea02cdc3eb9bc5a54aba227f9434f19d28d06add791fce9efe2171e2c676bc1b09bc163798a1a74b7fdedad993dc47c8323cbe3aead96d0d4e7e494ac390200e6a79f96d88844d59a3d78626b0797b902220874e6957e6c214f3ab7574c6e476cc4262beda98\nlabel = \nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 9a4a3467718bbd455baf312dcfc65eeb570d286bc88ffbe19d2f8e032308a50acba1f7951f507f502de91c0ae3fa4708f47ba2459c5c62ca667fde3131ec16f65a221a63d1d27314c54589db50a1fdfe44fc7c789c041ca0398a0e648b1251fd3ea559eff450ba92d133233cc1779a2094e23a6b88f0ad8ef1e0c6ff42d9be754e2c9d904dfc75124b3f34b00e56087e672f5eacb98f27b5f0fda7f67e71c2e3e2d98ce379872d8120aeac24bc5edb3919a196f2790830b615806fc0b5bf03e6b60fbb36c9b202a9972dfb71d28d168f00f698960b2e1cf6a6528060ff7fff91afa0082bb9a618c5a05206de8bdd0759cefbe16b300a1b51ee12809551009bf0\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 008e70553d2ab7d1724c2e422ba525ebed71739bd8eb968c65d8667704383fec6432f0e071cd0ad71809a3fde92233bf7ef0144dabc688dc1beabcc829c76b3e418b6a994c94209e872bf7e7dc64e6ee8cac7a5a6ca3d40a2280f875d88fbbd59a2f5afd245a5b12c3fda1263c97bd1c5536245d0891ebc220757f6a95151cf06af744840cf2ee8610150427ffdcc619de7e0b0c8519c2eece9c45882dcec3bc4822057e5be017d17cf3b1df53c00414fc19fe478e67abec5b1b8e0462ec9e8606994f60433fe15ba3652719047d54089c9193218077f743b71d04990705c663817918b803ef8f362ee17522c3080b97a1db100291a70fabd925de209496209d\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 45a7b98944f429526c32ffd6770d2cfa275eb81a8163d0662e1e418d9a093736ad0aef2ec70013f15b5f240336a0c2c3c673ba265125ff6a3897a91a749a2894187bf7ade153ba1491c66c52b5dc67b3b163725dff9c49e4f36d901e1e9d964b285586777455438f8c001caf53e013720ecb14e1e28aedae25beddc5f42580b9f72bccef986ae0ed3daf0435838b4c2d55bdcef2341f8a08f6ef5c2bc4194eed1c1b2c741c7c9041fae5c8a48e90a469807750bea3a50fb7c848199ed62a6d0b09ea8bebe4ea6d433a73d6a34e31cd9fdd21622814cab547f01d4f6a626aa180e982b2a89977140762567f391ec069d85977a9469513ee60e7a9abb54e07b3a4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 2f782d8e57831158d10ef1fcfa7c1fff1aed675d34bc49656a11d97e1927503e189f76bf4e335b1ea0f53b1e909fdd5fdff67d7e034b518da036c00dba897006031af4830863fd11d6fecec254646d00a2bfc2db8cde7b303922c703885372cdac94d19a296761850dd582c42ba5c96905ebcef582442643ff8baa83911817a4f00ad7f644acd3fef86d43c20c8f81580f044546e606c87a5b073ac860462f11a004ac2fa00f775cebb98e20d07bdb3bfc407f2711267889b0fc365762272276d509f4a9fa94b63c407c0ab98b601837f6f5d0e5171ad86b5b66af9eb94509950c42f5fd7cdb0cc9cd3d95a96f852b5941eb73db45843ae062518044ce18d200\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 3a88faf7dc8658070703eedbaf36302db8e43aec4f1cab99a39637cf2221f5feb0f716d4fce38903532055f8fb6f9036a2e0be53417736bd3746a04bcfe47954a61402fccf19851a2299a54d3c63485d69dbc52095bec0838ba87eec636251a2483d320569d7e62da616dafe0b5f0ab8aae2b2f943d6583dbe35e2047d50eb9b3ae9eeea5cabb580bc34628fe5d00e6f5e5e9a1b5db85d446c276749fe47ad1c495428677e33698ebdc4da12972bcdec64318bc7814e8578851f1905a6ac0874af691da2518daa47b9da4c9f94e832d9d932b5285ee4eb5e50072590f9d3075e76f1e3d691269d76dad090d98a6c32aed8567b74f4dc343bec1cd5a538ca796e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 36b2dd6aae05f5cc143d28532d5e9c2107cd30cdfa69c670004d61657877cbc80e619d2673ca3de8313942f1fbc2151e7b2cd2ab86e91f99a39af44864999bf1037504fdf0561875e7b713e497da2000220ce615d933ad78f04d5ccdbf050affa72953cebe1b52fc2f2745da7e918a235d5e0a55bbbb8fff755704adf305ffdba10fa536361ce984126f0f8b72731218cfa4ad4c6c007a2d3b9329916393a9133b80c951a5731f62b1e8eff8c2c66865260e18040fc603b2479aee5ea762070c09af9149300c12c9bca17f3605703b40bb914e8da315d6db1062f5766cd03d9bafc0cbab492df3f2c74f59a65e4d3b3eb26519b6cf775239d370174032e2c0ed\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 7c440d6013a18f8fe017be3f55384c3b98e08a0df1d71b68e21c8ae75774a80584f9708c21c56f78d0d9bfeb0bf72318abb61c8c89df56db67261930900a1e6353b7ab4615bb4c5fe524b591e6383dd54ed7740f0e0a5f64ecb497c3d503d4d7fcb20441ea1bf678a2edb792dcd4c5a6c0ef570f11212edf698b242c43ebb3081ab17f6271f28c45e300bd367295195db3f2f160f7d6793192dcdf15049e89113bdb4fb526833db559e42f939229c2de0f1d86f0c1b59f6cc27f44744e227b373673c19d0c20c5298fdcad478d2bf4be5514015e5840a5a207f2c61188511d4513a874cd9836282984615369ef4d0d172b6d50a39fd12846f0c0cdba4f8a6c59\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 540c7f1adc69c34a2c230cf1a22a81f8a04bde9da4f844008074f3f68856e2f09fea0ad1ae62df08afbb99b659db9fffd04f940d4f764829a055908a13b59263264a854fbe97eaa251ee5073682fbd7f2316e9ec34a403b05d285e2852a574a25a29d1a1ac4a6d85b74f833160aa292aae2c90f169a83349d58232590be84533448d63f7565d1b3530b295913d7107217d6e98dbc18435da1be650ab747c5fc80bd3b6b3e685bcded82b901b8b58dab7d3ea18096535a9c77c3144e93a8191e0eb2d0f991af331a03c6323c59a45efd1c87a73dec29f9f091b7f7da23f4d7db399ceda5061445e1374eb75653d8422d32c4f36557ec66128ad1511a9c37a132b\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 610b4b5d2a85de6825ab293619162335cf8bb7b234e2b7e3bc898d7123b30f0abe764a0a5c9ee849cc107c6e9dab86cce426b42010719a05096e3cc7e0ac1f0133035756c1380ace2afee84ea82de9b8f612b7d292598d8533a8ce2848ed6d539b2519018806a11318317a864bfa2f2d55db110d7477d4f4f71ab9261477c7d8485beb1c5eba81c52529f98a5430d3eb2f540c7a66ecdebeb1d75391cf1f2d99be18967fc32fb02b515d10f60c20ef63ef6da45f78ec1692b131b2dc8c1b337e78cf81976d8e8908b4f62c0767be8b3a4cd8b3cd2f7ef8b9454eff54795a3edfbfe21cde680dae88544d88624ea27efdf72cd4bebe4a86951e5afaf6170a2398\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 6bfe4b01a7747e8f92a4d9138a2ef034b0127215095145b36e2668e10275c4ee9bd79e397f28bc9422", "75c9f401e81a3d7f0b6e3e191026be641171ee916af6bb4ddaaa20fbe55be2e251e2aa4f07b1291c955af87823e2134fef3e843c8af3bbd168344176d9fbc8d11ec8d8b410fa224530c98b84a01da048b7618c944d8cc7b18ab17bd405d262a1870552e827dee9d1a8196ddd93975d4c487e819e4b2e0cf5dc39eee5670e249437c5460dc4684794760e26244e83e0017e3cb37a1b5947709f9059d245c5e3ff23fcfe3b101e496e7a222bf9883f2f12e22b0a31da932f6ec8003f13a70050e2dda32c01ec3fb80908593bfeb2c9b06e0868738d545475\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 989d2556e8fe1a5bb102c28190c8ee1abf3ce700857a0fe25e648998daf337bc5cd835799d86a3b3c93c7ba7fa9d7feada59bfe62a6f76c694d37aa6e741c1a6a0f55c8202b3649d9f134c3f711b9dc907b5b8ff932379c3b24da57c4684c99cd94b5f0dd363108c06f5b6a7b6f7743f46f726d064a4cf2dd63fe0c26e02b2950db03903f14b7b1a22e1a68620384cced1e54efd29b977cbd58186f10d46d54964ec04f29b8ab3c6b58cbde5630465ba3410c814b9da9903f8549c8455d3f9050d905ba75c8f7feb55a20dc996d040184dcdc3019f841dabd657b07cc0da579f88eaa0298507ae6b2e5b8b0ecfabc254679900366ee747831760ff1667ac9625\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 0000822e8870c00908cbf5032226547d38e423deb912c49c9fcbee66920cd2e9e3197b3fd7428cbbc5e90e660545720f180ac0ce06205cef8735446de30df32c8797380ccce9c0512eb285b7bffd883ef00fe118f027bdc75700e511226ec4da35f406e460fb88f9af2e9c4ec219387676ae21cadfad0fb1d704be69d0ebcdda90dff7e172612c972c6a974b828acee6ca186c71b50376d1ed5eb6c107408065473d53a2ebedc833f07f60f909a6c42464d79d76f94531a0d386213fce5efc2e66f311e73b06142f8245b063b9e395722dbea029dabe5ed1c12788b890974ba1d28492cce2c90e0a3026c282964763a030a7f7f3f76a72843a97d9eee17cdbbb00f4\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 822e8870c00908cbf5032226547d38e423deb912c49c9fcbee66920cd2e9e3197b3fd7428cbbc5e90e660545720f180ac0ce06205cef8735446de30df32c8797380ccce9c0512eb285b7bffd883ef00fe118f027bdc75700e511226ec4da35f406e460fb88f9af2e9c4ec219387676ae21cadfad0fb1d704be69d0ebcdda90dff7e172612c972c6a974b828acee6ca186c71b50376d1ed5eb6c107408065473d53a2ebedc833f07f60f909a6c42464d79d76f94531a0d386213fce5efc2e66f311e73b06142f8245b063b9e395722dbea029dabe5ed1c12788b890974ba1d28492cce2c90e0a3026c282964763a030a7f7f3f76a72843a97d9eee17cdbbb00f40000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 2e8870c00908cbf5032226547d38e423deb912c49c9fcbee66920cd2e9e3197b3fd7428cbbc5e90e660545720f180ac0ce06205cef8735446de30df32c8797380ccce9c0512eb285b7bffd883ef00fe118f027bdc75700e511226ec4da35f406e460fb88f9af2e9c4ec219387676ae21cadfad0fb1d704be69d0ebcdda90dff7e172612c972c6a974b828acee6ca186c71b50376d1ed5eb6c107408065473d53a2ebedc833f07f60f909a6c42464d79d76f94531a0d386213fce5efc2e66f311e73b06142f8245b063b9e395722dbea029dabe5ed1c12788b890974ba1d28492cce2c90e0a3026c282964763a030a7f7f3f76a72843a97d9eee17cdbbb00f4\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen140 = 27137; +static const size_t kLen194 = 27137; -static const char *kData140[] = { +static const char *kData194[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha256_mgf1sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 7627eef3567b2a27268e52053ecd31c3a7172ccb9ddcee819b306a5b3c66b7573ca4fa88efc6f3c4a00bfa0ae7139f64543a4dac3d05823f6ff477cfcec84fe2ac7a68b17204b390232e110310c4e899c4e7c10967db4acde042dbbf19dbe00b4b4741de1020aaaaffb5054c797c9f136f7d93ac3fc8caff6654242d7821ebee517bf537f44366a0fdd45ae05b9909c2e6cc1ed9281eff4399f76c96b96233ec29ae0bbf0d752b234fc197389f51050aa1acd01c074c3ac8fbdb9ea8b651a95995e8db4ad5c43b6c8673e5a126e7ee94b8dff4c5afc01259bc8da76950bae6f8bae715f50985b0d6f66d04c6fef3b700720eecdcdf171bb7b1ecbe7289c467c1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001028201007627eef3567b2a27268e52053ecd31c3a7172ccb9ddcee819b306a5b3c66b7573ca4fa88efc6f3c4a00bfa0ae7139f64543a4dac3d05823f6ff477cfcec84fe2ac7a68b17204b390232e110310c4e899c4e7c10967db4acde042dbbf19dbe00b4b4741de1020aaaaffb5054c797c9f136f7d93ac3fc8caff6654242d7821ebee517bf537f44366a0fdd45ae05b9909c2e6cc1ed9281eff4399f76c96b96233ec29ae0bbf0d752b234fc197389f51050aa1acd01c074c3ac8fbdb9ea8b651a95995e8db4ad5c43b6c8673e5a126e7ee94b8dff4c5afc01259bc8da76950bae6f8bae715f50985b0d6f66d04c6fef3b700720eecdcdf171bb7b1ecbe7289c467c102818100dc431050f782e894fb5248247d98cb7d58b8d1e24f3b55d041c56e4de086b0d5bb028bda42eeb5d234d5681e5809d415e6a289ad4cfbf78f978f6c35814f50eebff1c5b80a69f788e81e6bab5ddaa78369d659d143ec6f17e79813a575cfad9c569156b90113e2e9110ad9e7b48a1c9348a6e653321191290ea36cfb3a5b18f102818100bd1a81e7977f9898122273ae3222b598ea5fb19eb4eabc38308a5e32196603b2e500ffb79f5b886816611debc472fac45544070beb057c941378a6868af3b7a03d3f9880ec47d5e089b94fbde542aba9ae8d72c57088d7abf5b131f39098f7bc160f90536abc9492fd4e06f3ed7299d4b97bb03677207d95669f140cfbc20f2502818100a94b528b28f291599121d91952ffd1c7f21d7c1479d99d478885fb161870ee1218bf08472612dbe5497e8d9c650688e09c786961ae3e2c354dc48ae34514759c4c23c4588488961dc06b414e61c0e1e7fbbd2923d31532fe289f96da220711e58c14019808e00414276933bb07e4efb9b4a9b37656917205209f33f09515d7c10281803af0e72a933aef09ff2503df78bafed531c02ff1a2bc437c540cdcbd4ad35435cf511763596543480629b114ca7f780ff7efa32ea0cb6e000d6d9ea1f2ef71fd9cf9948422a165557e37e755edfe70d90b920502eb478bc98a63f788ce3a0f856d6ede7251a383bfa8fa480a81a925af7b3cc538c4bab8c9f7597ffb68011d8d0281802640fbfbcfefb163ee7a87b6483a66ee41f956d90fa8a7939bfc042ee0924b1b7993d0445f758d51933e85179c0320b0c968b48a91c38b5be923e1097c0c562f88d42294b6a2759bafa5428a74f1270874e45f6fcc60f21602de5eccd143cf31241f5921b5ad3983fb54ef17be3b285367e50c999c67247b552fe4bfce945f7b]\n[sha = SHA-256]\n\n# tcId = 1\nct = 6e62bf24d95aff6868afec2a92a445b6458f16f688c19fe1212f66a63137831653cedd359d8cff4dd485d77dfd55812c181373201f54aafd65730d2a304e623455d51125d891e65d97fce52341cae45fb64c38a384a1c621e2713ee6794633f029a9fd4d774f56551eac2176162e162640f25eab873a3451c475570f19228bcede4c67c370a75ed7fabccd538c9819eff182481b10d42f1a9f6a05373b8cf9b71818d467bd3b8ebacb619e8ad42916e600c043effceb3855bc48a629e60ae886f51b2a7876b0e623fb2ce68af4b039242f963adb0e4240aed0ed07f65f1ee7c0cc77d210d0c2d1dc10c81b881aa0c9c9e9499665cf2970d2ccfeeb3191531765\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 207180c340658b5154ae45d2e4e7326a0997c683a26b595e536a29333c4b66149af85e029d5419a39e3a147b221516ffd86b6b4b66c3e0c4c49fe8c57a2f5c37b8704b9b592b80db9cd788a4ed51ab4f0a1cbed63bd18d1f06a22f225866b0c2c417cb23473b7ba4250b1353bd2e5b4f0f937cd2efe5fa38db3c295f7748b970088657db4aa9a76e1ee6fbff166ec1861d00d085326c7384bdd1bc2f400d4f74dbdfadaf3fdc46073e668573e02030b9eb5af58eb540c66677a771194479ec0098d858a2ea45d0ba1e6b32440dfbac745000554d51a17684ca964b02a74d479f1d432ef763ef4059715a4348cfe36a215359712f25b6977903be4adb92febbf6\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 5eab3f0741e63986ed647d53e1cd71df041986900803d0f99c68355d249a15a47dc5b4f70a191477654299e5a2731f3b4eec76dea18262fc696ac794e5f66cbfcddac4472c578e246c26707598055584540b839836b1404c5611ae558a984cee8fd036cea924e0be2474a940f61e0acc14fcae95ebdc59942a9ce9af9a9c81999f7f6815f057ffdc2533cb15d6391d1e2d95f16f9c04209c889a4c359c7d2926d28a66e2b030a416b928d2825627998e5191fb4983a6e65024262d94fc09187a2d78162122433251d1bfcc8e507d06eba2d229c10031261da32ab8ccd15f1c5f9fbf07ed158483d736a110af4b44d6a4da60d6cb519b4454213cf9f0dc560f2b\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 0da290b0bf71a1141b2adc62b5b42b07fc52520cb05d1f39ccca7b7c22d379a6c2f2d93143d057050140527a1e5638243938b531ec3de7014b0151301e49b9fa433482a02abdfd94193dc9c70157e557776a69ded01ecbeac405133595c61165a428b6284729a4746b47d2bbaca9d7432c3b5693591cfee488eb3c68ddb6cde0dd61cfc6952423f994abecee34f5683732b29934a2c498ad48cdd30c149177189f48eefd9cc7232df18be11ff5f7e3af7319e3115997c599e2d8f7f4f663dcc40032d403436d3058a5ea66473660f0e195281ec6eba997d2a951ca6ca5f3c112715c89da1d3dfb20a21940594ed10ade90ed7452b753757d7241cb8a803c373a\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 121196e51a3f4476bfb6adddfdeb3a25dad72d1ea315d652f331a43631ad36724b3d14532110dc44e407b1184618f115677b33751fb0e8786ba220cfa7fc3fce22822eabdd4fc2761c7f34a04e8f13c1021c31adc123a32d871f0da6cdacab9c020222da52afd5c307a6e55e4566944403fda426ee2c6c973ccaaafe2d081ed8c5b1dc00662424e395faed86c9ae19a3a95950c83d2a9ad5c7e7f670faeb123acef07fe7795ad298aafe543504d7811336b3e2ecb1622bc90599a185b34700f8f4c52a651d73ea57e8cfa80e61d9da61f36951c7194ae4dee3c6e67b5757a39685dd3fe01cb87620a54666ff8132e93d7081d38ddc9f079431075e96cca78f59\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 7ae8e4f5494393be144d81517f11baf4b634bb68b2f0ea9b30731035e8cbf4283c0ca99120f60b75ef685e989fecd7a5dc524cb66292a0ab87ebc61e67baca1a8aed99350edee045dfdd029406acb707d85dec9555169cf7ec5118d8f29d182f205e2859a8dcc5122bed640ad0ef128deb21785efaa20f92067dc216cf40c15bd7130e2c094131917950a816da814c5990fa6beed709a0218f4ddca2473796e1b44cff6d7ed601c574a784d0865d3afe5fec023ebe71bca881da5637e3d1d17238c20a5bd0075bac018f07898f74b9e6dc0fa3d5f8d0b274dfef3e6720d8396b34a81ac2e64da5b3e5d7666323ed7c56e8bdd179f3c6b2cf05bcac402513dd87\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 096958786ee7972050d67a9e4b69d6c6af7db7cc674386df725770dd29129b826e39552330104c8d71e6cc3a3014dd2f61b54153af51b0438d447ee939f9e3c13bb8b00a37dea6a068f6c9d27e848b1be7a1eeeb3ee50b78036fba95ae46948ca5b13f356ea24db10f60dc09e4b8bad8f766b668ef72524432080a0ce00ed676d6d5e354984b1078520412525848156d06f0652469f95791baa3d9a798ae537094f76f976faecd5c9ce0c930a75910c63dacf63485cb4b5e7bdbcf4d80e74037eaa1a8fe4b52930bec6be99cf6ac88cf5878dbf6859d456a95dbc34654eec425de84ca2a535d517403a9aada827e7d0093ecfc97ed056a7652825e9a45cb2dcb\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 6583e2f176aa7e7f655d2c53497349c156c8851fb23325589e85fb83bfa857346caba222cdaa3234e71564154298c24dbb85e18822a1d5e7faa47863a64d76874a3cbc70f4d9f137426a344c473fac1dd7008a9973765e9f66c5b492535a647c273c4f78ceb5aa7ba963a2142f2ce4a81f804c002b9b2eabb3c75e80a3c6ceafe5384a544c672a5d28d32bb87115f43eb79775fd9b3f4a2f6e6a89368bdd95ef1d014877b60afdb1", "234acd57653a65459f01b2fbe381f22a739504b4897a7e6c33b6349b276db6083abad9c169405859b800c812237634b503de6ada43013c1d86697a135be78a9784576d796d62aa7819e2ea0e2d902ffdd9cfdd1ae66212ee\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = a0443ba434156d0b503ec662f5eb5b10e20ad0cb8233720ee187ba986e4811dd312844d3edb26bfaf51b4b9268dc3c76072dd47c199d713c91824da23ff00481ee69e9d4cc543120fc33b7244bf0c1ad5fdd1ae9cbada7fe9a70ad0afaaaad8361e8dc4b3198ae661a84e275b60bf2ebb85e512da785d2fc3482294fa11967681d7bceffc08ce0e36f0a8af7fcfb1337186863c2c1c1b94c9ec9785cd3d94d15437c23b775677f3d29a4c9e52f13398fd14661160e5868bca97625aa6c7ecb07bbb479644def353f1f01a4c4100f9adb82c4f6a265a5ee962da58c3c042aa549c9d2de3008e7448e0c4b9b4ac8f5e4d8629873909bb995ccc0825fe87d81d596\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 26aa8e7931ed624bfd4077e3b83ec08de080483a61641e877f493fb7d0ae4dfebd4f05612a2e4869d20d440a64e928b13daa3b79da2ed674b99421df7e7f625a22b1c71136da27db699d3dd96e3364ee0cd2123ab6808930c6bc28a5dc307880d1ab4b03bcd6178a81b8ad52aafffbab387d40352dfea526abedca016c87e9e56ccc4c88e80f579da015b979bcdd88618b2a32ce072918b2e223535359f1ce4eaba5e692e6296b2140dc2304092ebd6f136a48092b3849082b57e70c93b54db55045dd6094ef3d2cfa8bc9e2fd2b1bbe0c7c603ad38d3f40c9eac8ae5e28cbbb031c38d93d3b2541d94eab3a1e8992a444ee4ce7b8d08c0b9a4f623d32fcba14\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 7efb69f1137d6a6e813b7ab75bf0400b3d07a442b88ab048675dc06b0215fc1a2e033263ec31a6c1d2eac56cb0470d69022a48131d1f000bbed70586b80cf6356465c8834daced7ea2a5ff8ef9c44d5ab828ffbf0556a6394752a4a28a70cae20084e1236f042f6c29de5cb34ef73acba5abcc7ccb3a26342701df3b9daa945d9fa5bf0b9b10306655e56370183f50fb8321f8f0cd1c72114791fca5df2166296b509b01a0b291c46110787cebe69d41b3b1e89590bc2f5e5d49ea24ae0f1207eef1aee54b9760553e80c5506a8a8a75732e92875025f0bfd5ead71e4340c8a9fa16dcd5a7dc96d8c4a7dc4e91f47a69366445c4695c8bad578ffe52bb672f65\nlabel = \nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 287d7108a1c6e7a18acb0045b20c57cdf2ac03456b44942764a7a9e9fdf3db481d7e202e4c8d733b56b9c1e93d71e791af8325c9363df789b252a5ed0eddc79e76fa41c2cb0a35618398217a390a5e6d99eed905d5554d19c1cf4e30bdf1c2fcc5148b641d71b3f1977b63d232648ddd935ec9499a53ac2fbcac55f462e91065adaa018a39c453ba759bd68b454074153421e2ce75cf149f748b5b84758df8a423d1c50c880af863f2a6df3cd465ca36aa2152b5771f3d507f4a4dd9f8006d80eca23537092287976f218a90df1e16d889fe31e79f7309f3224f613e9b52479fe73b7aad915319a3b62a5936649f7d015d7b09f7fa9f454f78a7c3dd4bf791e0\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 8b65065af82770625d24917d13fd97ae13247cad97910a2651f95800165b76cc34bfe06cbf8c31a7d7ab4f41e05c45a25b90c606378c8e49c95a15ca11ae37e797a00f1b2680a6958c54396be4e1ceedcabc58d9f136b36867a2fefe648a9758f49634bfbcaa48717a116cba58c27539be10c56911aabe013e0329645e8308423c3aa42e0c9b1f4b5f546ddd9f90bf4d007dab52ac3879db755e4f2b96db5cf01950f39076f261f50b1bae137be500b03ceff6ea1bbd80b33424f7faba5cc6b86670fcb7db1a9b3c58bdfd7b75ba9f3ebd34ae32d320c757020a7324df7d3985bccfe0e81bb7f61bd98cb37219312299b4f274b2c90c52a8e1790f52e8fdd768\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 356e91db9bd932c7b5726da288e2620cd79667c2e1d7aca562331ceaa6e4ab47665213ed75579abb147728bcff60787c95107f5be787c42e714d51627fcc8b4ea71c232c0c80ce6163cd0fbfa9dd7e8c1990176abc2705f4ffcf1d5c62393eab1c0ec8a653a90f27a968df8f4af622e96f663fceead8b0bf5dff65cd657a72b9c33265c5c2a8f7f9c614b9c2f8a95246970e6a778aca4b12552da47c274282ad9205ecd2264ae3c649597beaa35c141910e84233776d419448f55019a84e199a4867d68bf213f47b0316d50079dab77299fbbe7fe8929906461c1103a97c2b3f1633c8ef03e820ec675e331cd1fda8ebfedf541d0f2b571f4eaf292ce0ab14c1\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 5a6efdd2d211d50366885e177190ce1621ba110ee46530bd083ba76ed48992d85efd8f9ba964eb33e596e0c0bcb545f89e2c9592ed18495e8e5df1866fe30b27522a3ad9cf7124c4aa23f7c925900613c50b7c18872b4537a750419ae128e913e9a2d87c219e2cd01132972298028e54fe394ef9779d04543c72eec4c5732cadff0b954964706bc4085722b0c595162d11793ab29754837bf5d324e21814ea24b12fed441f20d22148ba5a987b6aa7c7d4ab5a33af8e6c9096c29777cb0d5cfe938a6ed5d30936a5a8f5fc435df14d1c439d1b9d274254e7b248bd20d21dc4652c1605d5a2929db018bd45794a523b217fe0a9a6b0704197ba8126fc8311556f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 52582e10264630e1584155f5e970b8eda9108a87370861cda12ee773411cf556db328c8a2a165d10f6f969ac61b170a75975fbdf9319d13c9535f30d621db19e41da3a04fe40874caf779c8f03bd5d1892e52925b183c118446ed9a335e9c1dc4519fb1253215e5f8d8ee6d49c0167af9d5ca5b1ace067af573e0be9a61beeccdac37b0e54f6b0f70576cb8a400d01136357a8576e81c119d3dd91c7b5cb343692a810362e1e6dc06c1746e071a903a2856b4446f10f78c670d617e5e24dc5c0e45caafbf8ffc4af6b3ef998fe1bfb59aacb16d98d7e389679939861a6722c4e29af731da99d17058d7a12ead0d3d576de796ad2ad596feada4c091f10748536\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 3f5e00347c36ceb79f400effcae92d331aa9f52539041c50dbbc6fd071912912692a16353378276a2c1596358c46f6232434a95a99c573d0b83e4a6e970a73e99ca13d734506e2a2a56744b1872bffd501a80ba7cf5494df6ff9b421cb10247e11d19ac9e60afe0dda87cb351c21ba554ea50b70f6eee4ffa949ae38694ef831020d4e599c6ff4493d07c7b6be06453b84143813a68dfe0fada2317a9f4040a3cf6308090b6bfaca36067312f41bc0c4c01ac00fdb5aee4395b04cdff82cb433b01cd3e70daafc7807b2f770226699e7535124a453f7ad2653bfb7cfe71e120dc37ba88a5be347ad134351c11ff1019b7e42d24b7a3890a8424fae53a10c0e11\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = a166bf7b5c2cf1896c0b924a69233a0a585bd47ed7f2330654aa68806deb0ff68c6475050ab45c691bbbcc58dbc2f5c817729e8e195ebd39d48bd5e14977abae0829636831655917fb5a758fb43a8e505d6ce595f625970685f7ec81cb5592210f5d68c6e2e1ef26b4ef8c92bf44f077e1d5099f379cb8120ad185bf07877979ca81f251fb81be0ad3c14f4d7885fcec496f80033fd4279b6830a20cbdead27c0967e28d1e06ef4bd7ba89210ec0d696274a187dc2f13212f5adf06e9450eca398325cfda73431036ac21b087d373c9f575c941f8cb078961176e31859a61c49baf8ff4f817a11010448d6a0e40dcede1a5ac3befa4c6e9d9d67d8e8fd8b6de3\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 75829ac4d97848dfba21c1688e936cfc736f53fde5b91d5330b63a9968dd4f51c2f529fd8d8f84e4a908196fcc5deba21b5c7300d7381e07c4e0ea2184965169cc9464933ef5a840d86b1dbcc945c7547d9eab245ba64d24946a75961161c2b8f417daf11b163b1e5a5b02d45341384f37755248fa871e6a82f948ad6292f11445bf30596dcccec73a441cea5e5dc470016309a83b6c8f158536687ad2734d3ea1562d46e23bfe8cab498d19b0b104d97182aacf852b6db3c4670109b81af1bd99b483d92b3e4bd813edfa4d0513214dcc5bb4da768e86007c22f11e5fe6f4cb60b909958fb94dea660d3fff0b99db15c2d2e6c8df7478330dade8c517b90975\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 8e5f01ff0c1775870715fd0366a8748531f8b00803df35e0e2308db63bbec4eca4e093351876b794213b904e5dde284a82d74abfcbfff94bc9a8300bea99edd07fe97d6e0b11219f85ac15acc404d37d3da16819a14a438f3f72f8178b312526232386e918a8a7e11fc38f4668c499a00480cf9d2d75aabc0198d3ba9ba345fba9105c6564df5f6ce796f14100d186abffe4d83d57969c1caddc7c7aa340b4d1bab23d9b3982278328ddebe648f5c52588738f3c56a88b3f34c890c03fafc27f485a17677a53e974dc1dd86f463a927f4328ac51bbc61705ae8abd7f45628957489e2defd8e043b955b118fb2a1c407d45893004aae0f945f06add1e45b41a03\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 50c23e2ad6e3f3b10a5716cbf60efcc9f66d2c6f17bf050ba0153b877ba2755e8a0d5406003456", "2266155744ef80547b8af777b0ff764fbb12baae49d02b4f6d65b6cd8f0a397839101d32ae163ff2e6072748d6b8017e5e73e332d53f4e91fe6233a82dbf54f3146b489803575c5ea37ab55a9ea7eae47ad4f1727d45822b569cd6e5d4b6ab759850948186616b5da2a9a316f57d899f91934bbb27edcdfa19532ba1c01f3724738daffdd88c9a18562ebcbc49185b0a817407903476d442c424c81b63aeb8f9d1b184756e0cc0a381eaba45a85c8bbc6770fd047ff1a6404a384599fbbd6a40b212a066e23f6a15cf13e42c0ea88c710e4d70c612074968e5\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 3f92a694661cae336cac7a3c5a6f67e0655d10218a64459739ab9664f2cec58978939512df621e6b92fe3429bb22c08b5103da648a7719e7e95a04e6b61601546955825d60f4c517619f851780ad17f1b8a955cf8c7f1a5e26ca4a0cc19cca751d0790d56e1140a4705e19274f638b7c16d9d3e423a7f787d02699235e3e9e4d543a954f9b1bce5411c8ebdcae86a4bb86c66818a0bab51a2b00383b318e53d95508bab1b19e388cd5a03cdceba0f7176c1782e19ef62cff69352d444b1ce0e1f339e96d8a65c07aa37f5f2cf33867f6c496e0da6cd79b3e2183b57064ce21a1b92072702e555a82cad75107fdfd8bd5e7ea5f119cfbbc1770e962fd0b781aff\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = b056e2513c7c470d897032d406e97b5946dcad52df1c1650d61a1d7b0af59e8cfaec4d9e834d06d819b92a7d440d277e5039ab8aeff25043e98b281ae6ce0a91f8dfbbd1b4998fe5481671381b6a3952448b617ae606f06a0143561a040edaf3c972e611bd7cb814aa4761d38e4a007ca65af8fde6eb25d919d8bd9273cca7622984aa27994d049612424547775c5df75483962143522d075b8c55ea61b04583eb4c0358f9fbb902dedff30b7d8592b57094df4f6345668af53d1aea86fb36dd69b4434bacf8fc12c13802f5b03551ba8f207d4060a9f56e6b7e18c766eb82b6ce6ee0747fbe785c3c1c25fe7fb87de50032b172129fa41a69c3ce0e777ef10f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 00000da290b0bf71a1141b2adc62b5b42b07fc52520cb05d1f39ccca7b7c22d379a6c2f2d93143d057050140527a1e5638243938b531ec3de7014b0151301e49b9fa433482a02abdfd94193dc9c70157e557776a69ded01ecbeac405133595c61165a428b6284729a4746b47d2bbaca9d7432c3b5693591cfee488eb3c68ddb6cde0dd61cfc6952423f994abecee34f5683732b29934a2c498ad48cdd30c149177189f48eefd9cc7232df18be11ff5f7e3af7319e3115997c599e2d8f7f4f663dcc40032d403436d3058a5ea66473660f0e195281ec6eba997d2a951ca6ca5f3c112715c89da1d3dfb20a21940594ed10ade90ed7452b753757d7241cb8a803c373a\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 0da290b0bf71a1141b2adc62b5b42b07fc52520cb05d1f39ccca7b7c22d379a6c2f2d93143d057050140527a1e5638243938b531ec3de7014b0151301e49b9fa433482a02abdfd94193dc9c70157e557776a69ded01ecbeac405133595c61165a428b6284729a4746b47d2bbaca9d7432c3b5693591cfee488eb3c68ddb6cde0dd61cfc6952423f994abecee34f5683732b29934a2c498ad48cdd30c149177189f48eefd9cc7232df18be11ff5f7e3af7319e3115997c599e2d8f7f4f663dcc40032d403436d3058a5ea66473660f0e195281ec6eba997d2a951ca6ca5f3c112715c89da1d3dfb20a21940594ed10ade90ed7452b753757d7241cb8a803c373a0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = a290b0bf71a1141b2adc62b5b42b07fc52520cb05d1f39ccca7b7c22d379a6c2f2d93143d057050140527a1e5638243938b531ec3de7014b0151301e49b9fa433482a02abdfd94193dc9c70157e557776a69ded01ecbeac405133595c61165a428b6284729a4746b47d2bbaca9d7432c3b5693591cfee488eb3c68ddb6cde0dd61cfc6952423f994abecee34f5683732b29934a2c498ad48cdd30c149177189f48eefd9cc7232df18be11ff5f7e3af7319e3115997c599e2d8f7f4f663dcc40032d403436d3058a5ea66473660f0e195281ec6eba997d2a951ca6ca5f3c112715c89da1d3dfb20a21940594ed10ade90ed7452b753757d7241cb8a803c373a\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 31\n# em represents a small integer\nct = 18416ff48c3a78bc85e1f483d546052d84deac02ce86fcd197215f227b6dad58bc19394f46551111f858b08879bc37c620b1e81ebac4c75fdd71713ce75c24293fa39caf46294d28bf87a46da9a769a304157ea1fc71afc3bfb790da32e84d812a8946d1b3d211fb6972b3fe6674496b2d8056c1503d02fd4c2e607bfb1e6b26b35636b8b823757ee9ba3795d3af2dd8710b0a6da4dbb430bc69dc089f1563d34f0d79431d63e7b8d94c8234649b64223d1e0be17463401184a096feb9c81e226eec26c7e9f3f4357536633029ebc0349bc136d1206c6064fc51b6d2e79578f2b26439c5b3f6ffe1b515740b3c4b94a49430631292968eb50983251bbc7f0f89\nlabel = 5a3564e9482a072bd99d0306d69a7f4595c49fb9c06b72250eed2b50ceddcc4700000000\nmsg = c4fc4b065f4595751c7ff8bb99681d505b7d0f1730d404617940f4b5c3b01979ffcffd19e86f69450e5fc14d9bc27a1f39734fd5f8f663d2d87c444e3e15da8764709909679aaa553d98ddbb1ad7dcc8be04bb8751570b4e6cdc7a8f56b09a4af43053a393bd8f947d7625137e6d84f9b9c727475a98ea22efcf679ee0aa5258da88a08afc53bd8bfa19b0131d6f676fe198a9c6a1f84174fc69ccf8e34e3617f8ff6c4192075cd6668392523fbecedb27578e591dead78c80a89be589a1\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em has low hamming weight\nct = 23ee3b4df8ac632078167f2f97a736469c6e6b39ced4ddc552d31f0fbc7ccb478adabe56cac20cbec1a0084125aefde0bdb575d68bd74cfbdf5f3bfb4401fa573645c223568918aa911c1f5a01b3b0903e91d82e8c04194df4bdc5facb6959b4df23593c7925a827f029064c75a4bc3d2899649025670e70f3e01336fe961664563a3bb0c7bca66d7eed48326746a060c5d3f18a160abce399917ab2e2386d0f1c2d7c9105d16befc1b0bfd72606ec300a777ac550b1b0b807b7e46467db5bfe0eac8bcbebb2df47bc65fe42174368595b72650b770f47157d2d14c71cebcaaa5cf567ab803e2bcff5f4298c06b1983757abe02faf4c7c5f9141aface72ab98c\nlabel = b503d03521b4ffc4b855c94e911a6117f04c76c6fe8000f8031e705486ae641900000000\nmsg = 03fd61590ddd05555a6d46d1e8925293fe46fa168cb06135c2e7c8d36551187e62016f40f3eb31751f3690f5da1aaba5c16ffa650b2e6c25f3763fe324929c4becc7fb28a383d66c31973c72eb13ff8c87a92b495f6f0619290f8675e9889f49d30d5e77b2115e8805eeeb1aa9324843a75e0bbe70538eefb7978a0ea7beb211e67bb075981673517518586eca5b04ef3ad6a3a978605fbc0e67af7fe412acfcb550d20c9900f4d71d7829a107cc51d663db54c57116959998f3946b4d43\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em has low hamming weight\nct = 94f4edda147a95cf29bb0402d0413e5421b5ae347c31b2ec3239bd808c4e5b609d0ce9d9c3a12e47eae6c5fe319288553ba25e8932d644a6387087b4e495ad4bc124596d9440ddd5376f2c1844e61a7c51bef528ad20065574198ace92d3402dcf4df8ff5d68c06dafe9302da4e075ab0e011bfc1bbaa55b4cc1bc30dc9b104539c21d60b6fc7044e0242591360751fbeb2883099602a900cb5320195cb7071819dbce2667a7532aacb2c9b96f3e726267b709c5c0877280f5d4efeb5d4155bf8751f9560db4bfaf8150a8f27b366c3935860aeb106bd88914b6bccf35bb6eaf9217254e6dacd88f0f1182d6cbe25635d4d9ad76a06687d2527ed7d9cbf50803\nlabel = 3bd80a6378115c0c946b4e3af28c6c96d1110621e21e8633416e9c8ef0a73d4", "000000000\nmsg = 90fd851c721e936df0134ce13f2b7f4469d58f69f85f4bebe2726123cc742c1c43293f85f50b5c6d220f40c387a1f2bb2704a16508e267c6c4324a82191170e67cbf57f56dc02a706e3373e9dca1ca0f7703804c0093e9f8a2ae5502d2ccbf26dff3cd179b5b8f97959d5d2a9400b31b01ee09caa6013d198beb7e0979aed5263974591cca36ceceb252110e61bebdf0272386f9571be79fe3afc8478eb9e7155759ed20e2a2e537d98aeda18c374ed9b48be8624984ba4b15bfffff6cc9\nresult = valid\nflags = Constructed\n\n# tcId = 34\n# em has low hamming weight\nct = 68825b60b53cc0bbc92e4ce994b0dd270bad0eb657e41acf26a9e3161c5254e4bd38b03e90d7453424e605a372bc185f3ae6ba9ff58fab0cc4c1cc158d7a1e8f1f0b30ac08789f7576fab2dae7e86dae60d9af793dc1b400c2d25a9d3357ba0d27361d74a1b4e1445147a45875901d70f3190a0b34defbdbec1cb9ed3014f15a1a0f9000d9b224fba944e791d303d816bafeb8e65dfc6d740d04719c4ab36c4bbf4ebea5fc45ead338825fc5a71dd6c25f8d8891a4f8d6e0b35483c75c1bd645c3cbe9dcf5a17ae5cd2abdfb132b2b37102122a9bfc42ceb3eac98f2af39905b9cece5d122b70c95239062ceeab798691dd2b88028047924d5ae814df78d555b\nlabel = 48915cebf2a2ef9e5d5b92cce033b60456d72af1ba54f88f5074a36a643a317800000000\nmsg = 0cf83d297f20f527983f3111716a68d0d33d97ee4f5d1822c9e5382398542bd532316db29d8a8f92bacae063aca1c1cd9bc272fec688b3f67956c662a5b2f895509fe6f2406f0674afb0f0472aa205a7d55a092a5ced1b1c1b92a7b93f9c695440a3257e007949d27098410454d4e39612c7dcabc85e19f3421734bb2717de00c041f569e8d43006005960af8f573e13867911989a4c678da8f15ca0278ebbb21742fe33b3613f22afca45ac09f815b50155ecab6eb07806bdfef37b5dd5\nresult = valid\nflags = Constructed\n\n# tcId = 35\n# em has a large hamming weight\nct = 0ed3b1f6a9b200147e535042353768280244b3c831215928a2b2103df02b3613f43ecfdecc6a8f61ce0183b8c60980f82c3dde3a731ea25a0ca9b89e5f68a7cd6cf6c6475f591f24b7a89a885a46edb0ade49e37665219a6da9afbbf655943912636af85e0bc859f43d3c48b4e77c9d1c0d641a21fecf4957185b805aeb908c6387c9d1c8ad85a166c075942f0cf68ca70f8174a9d2a4e5589c7005e2c423ff97c97a208da51d9adc0cb4588a257c0a1d0feb02eb050f9980309abd09258570ab2c8186cc357a9f693107c84855ff6ee7936b71980de42883e3ee7c1c6ddbe03d16a1f1c5bc5f987e6de9cab329ed7a31b59cac467d7b6432cb40f616ac9d4a8\nlabel = 02be339a2b399ffeaec99acfd80f50ebdfc8fe3021a9a432ddd4134b3466b4a800000000\nmsg = 2124d6fdfbbf77ac89f50a235b0af69edbdbe9ef3fcde36441d7022afdc8434431b893eba822cb82585384e36298df45b4b4415a3bdc494604305272f5e988f2cc14a56043421557d5e5dc958fd771e4d509126656d21222cb8e2e1052ba38286c5e3d0be0f4b1c978a61bd1e3652ccb63fea82ec46d6b64863c00b93a3243e2328f70f692aa65f73976335eec5b29a9542befa03d5e82aba9dc285af0913382d67aacd513bbf6f5095e4d5f9b5ebfb5ddc25cafd888addf9ffa068bd4eb\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen141 = 21160; +static const size_t kLen195 = 21160; -static const char *kData141[] = { +static const char *kData195[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha384_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 5a3dc962dafca26cb3640e73bea7439a9f1874bc23e04226ccd89e7ba5c3b938a1a293b70dbab0f9f0f57f66951447dc33e730fd7e2c2a164d47ac502b07dd24cd3c142c2a79e4ceab5cfabff4478754b25a8c02c1a47d80d9f37abe442ca9a78b23f631b6ff3e15a4956d7f18590cdeb206d5e2b698bd084f260e82ef28ff9ec6dbc85a895ec8a3865750f501b96125db1bbdd99a4ae4688adb304aabdfc4e0cfb9fe6b6bc0db74c88af8217eed738a0d04fe8d32c1d110370ce1c1b2f630657350694942730878e6fff77ada7e9a317df8bc059ea7081325306b8eb2fa0d3a3d89fae476d9344892bcd5a42cf83b7bcf3e0e51b4c78e72b3207a60a701adb1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f0203010001028201005a3dc962dafca26cb3640e73bea7439a9f1874bc23e04226ccd89e7ba5c3b938a1a293b70dbab0f9f0f57f66951447dc33e730fd7e2c2a164d47ac502b07dd24cd3c142c2a79e4ceab5cfabff4478754b25a8c02c1a47d80d9f37abe442ca9a78b23f631b6ff3e15a4956d7f18590cdeb206d5e2b698bd084f260e82ef28ff9ec6dbc85a895ec8a3865750f501b96125db1bbdd99a4ae4688adb304aabdfc4e0cfb9fe6b6bc0db74c88af8217eed738a0d04fe8d32c1d110370ce1c1b2f630657350694942730878e6fff77ada7e9a317df8bc059ea7081325306b8eb2fa0d3a3d89fae476d9344892bcd5a42cf83b7bcf3e0e51b4c78e72b3207a60a701adb102818100ef885b87e25c29d1ee431d1f4ace787c4f882e92d12c4b2766c84f89263106ef0be0ddc4de3bf061a2ba46ffe7c132ae67d337f04dc66daeb9de553791f4989f50b224c981812b5388d1c2b5d53349a61393bf6611995b6988f143c278ccc260cfe82a6ac4a6409807eab32664b7ee3f1c41dfe567e097fd7afe8520871a1c5302818100dbca582288c81a30d6581f272050a5fea773d711301bdd6ecac7214e00c0fcb9498f1e585086b14463cc89a02c2e77a89271c058c6f69f3cd13553994d8a76cf62ad9e275217720d62eb6e888ec4509cea474b53f37b458fc956dd31df3bb6ec7de659e88e7e709fe3be6a8d37264c3d20e7d088276ce7651a403c68d6c47ea5028181009d7e87c851d28d80c5eb84f375494ab959c5cdf1a4ed3dc0fb78cbaafedc8f958fb6dbba3cf1263ddc3424c8d0461c9fc60e802255d1197f20210ae10debc88a4011d1d4587d68d2750c8ebce620e1d4fbdc52a5b6fea1b7435e7752200169f123e2a0393171aad90ba38b05bc859f76098b5abec8cd48c2572390bef175fe970281800eed602d00432edc30428de31763c2d257c71b4d348a3ff0bd5ee6d9285df30c167ddcdebca1593abed86e646d7bbe6eb97b7647d14380af1dba54722dfd0072b74df956cc5181527d6c65f66a53d4f1c34b9247225b35ef3d0a643d75ded55e9c725f9ad6caa995825f35575fee7ef10be2129c9ca8ddd2550515d53cf8dd6d028180101d1f49afb04d065bd8c29001d212e737bba696108574a330a9cbacc51bf6c96594f37fba9c8de156c226371d49902191e1f69d84a1352193bff29e318eb36ede6ffbab93b6555ecf6addca9e134c20220a2d24b03a6d23ef8c608a5186769f66fe2f6b21bc39f6277ad706038b907872c4716609c223762130ef03616482f2]\n[sha = SHA-384]\n\n# tcId = 1\nct = 8402dbdca0d3e9ce70cacfdfe3b2ef26ed92a6b8dc3c70640e06d0900213824a79d0cce6d0d781306eb236384d69f3ed9d921db8203e82a0cab04a51c12eb0a3fe668ab0ecfc419d3529f9970d45d9bac4373ec312b2a24f0c829aa0c0051e44a25e6da5bcccf9edc6f1d87f152b4770aedb8a36993d5768cd97c302abbcfe9360baacf437d68f59048280b560f5265e7f08769103468338bc9332568c20c7efbeddca8350662d64964ae5338138ce13c0cd0c9eb6f0b2516ef227bdbbe55d208f470ec5976116865f42897e63294d4fdbf36f6f4fc43dcb79d2c84d30c5f69ace97abe77a1d82d3fd815253d5b573dde8eb01f96416085538e94b8a0d95de57\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 858406b01fa56d4f216e36fe4fb2ba991130cd5ef56542ff60bc5ac95eccdaffc40bedb373babf08a79620f838d874e574935604cc15b2dc0220f84ece76b43d5239c3012f0cc6a446dece3616606e36026fb1544b26ffb2d0dcbb954eb812e96abdf245dfba3ea30aa5d5e7b81973f5c00a9e18a5337bdcf046c55d7e5a6028b093e6fe5e825807376a27134974bed314226cd65e17077d721cb52bb083e5e379d2cbe8594617908d9b90e0851203ce7d9dd8df667e86c3857c2bf9dbbac70f939d822c188de67c60f3bfaaed36ad4932c2e28bf9a5460bf51f2ad381e96391c4024643c19165e63db29de6232c7bbf951d04d6fd67df6d0dd08c4d164386d0\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = c5390503bcc08959ab92c92ec9e07a59cddd2ca4929bdaec89efde9c4da1011c1be7484eb76b649769f3d258219a2503464c284a1d3bf12af8e584c45b717db7bebe3255a1b8aff1f19bc2ae26672d2bb1cc3d05ca6f4af9bca6967f22593e54d7c42b10e19735d483862850b7f184fcd38a3f895cecce365b68f922083c4737c16d152d70aeee8edff5d3a3c0153b33529b8faa73bccc4e2342b23acc227064d09fa7b66583068d9ae9978c14f96998362dd9ed0f67290b8eb220557e257daef38f118873094b8733c6d72a1aad6e40601cbec847690842a38de4f85e04e9d0edb39834571adb0da4dd158f8e22a6678db45ac86ce797d8b86d4d6de844c0dd\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 5814d6f2f3b23545e005a4f72eb0ef659fc07a8374780f8eb9223dad417bff6c96a91c6071abd678a8c9cbf0b4735e4c225e984669224e88655dd4f05adf1cb1ae96f7dc7932a0b387158a915f7563085f44c72a41f331e0e17e6895e442f7492151397159637968b15888f851323107bfdc1cd419d6ade56b974aff865d5823daad3d0cd8b1a94ee1767b70fe477c64a5bfa593783aa90868d4456f098630eb32ae71ad4914c142c805a69d2fd0e93563feca567ed922514c0c8867332c053d4912cd17d238eb46245fbeb03439c6e6adc1cac06d1eb41d9a185057431b25d4600684e057e571dfd1a573dc60395e7c2e3d612f9f66472f4dff284f4cad4e6a\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 8472105e089af324cfcbad5eb2ce2f85185f2e2f5a9e5e302022eaae5e40b1507dfd4801ac5d4743b18b87d916b2bb55bba812735831296dfcdf4087ba4a4dbf852f0274c7e37dcf2682c3aac50a70b6d08835b0c59e90fe3ce2f3b6100863936a67af141236daf5f588f2eaa09c391f5728dac6a007a02dde61bc69c65d4885149a344046d66f1b91711eecf5196006fb916ec209e5bd251ccb97b08c31aa1ebb25b44028047ae4f61adaea5215e0324af6d0509da3a3843eed6ae53fed3a1e459c7aac4d94f8c85611354e0e24f7630a42b184805f67aa7ed0bfb57e6136c43261f81940338fb4aeb662d29301ff3a0a5a01aa20e53f4041c20f14207ebe96\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 3645e92f0c46b7d6f6765575fa9aabde09512564a2d2ac80aa8b43710f34c4aff72d2df02446cc548acf30e34994020ed7301bba6b69bb4e9abcc766e3c9284abf824ae8389fba58bd2633b01edc3ab648788d31bc7b404f6e079a650dd8224b0642fd589b3f84cc393d18bf8b3a1f65fbe6684f6a76b3e767d5f2953db53e61dbfd69371b69b7112284f256ff11beeded9f4deea47350c283d825387981c1d51d62ca032485a1a6f8582148e7b80d2c55daae467576ef45be6f00e676eb5a40da88c18573ff012267859030cc614135dca8694dc0a0ef0d00e62761999d93c3e8651a11fb43a028370b481ddaf6cd8c4a086aea2e658d44556a6eedd64da5d4\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 4dcaf6ae82481350b49b344e2ff3348d0064b63d4a686283cfe7ca8ded4d73c55c9cd3dfc6656e3fd18e45dc69dddcc82a33b46531f3b5b7682ef1fa0068ec42583a2021e7dae3908d924a6bac3bcaa123c88afcf1dc6e22ac6be966723223f5f7aa46e2205c6e6cc594cdc5cbf9315c641a84665d66408a7b4f38ba6672fe3c77c53ed13ff5ca5e3d78ab51fd19186802709a0f98d7de5efc10ec7aa4448c0e89d506168acda5c85a12badb8b4104c6b6d48ad4cfaa4e055484a8c4009bd579e89b81d7121d4bb40e94a31f35ccab0e71cf767158139e7b413912efc9716d8de8f088467cb77f8e0649aaed9ef9f48df64cddd9b75ca5f077a08468a768cdcb\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 8d31b6a86582c2b35e86fba1af4d02484ea81326f9728c22761cfe337b7d0adff787e2cd68c3b71f22cf9d0c141e273ba9c61cd6c6cb18050391279456c3c930cd6cb2df70b295e3c062c93d60d8884a2cff2839364086208f1be9007247233a04805151b46854f9da2b9a9e0803200afb3166db9907c9406b002013d5a566e4ce83b0572694bea9d3cbedc796fc4538f0315eb920bed4267b12b9127c683e83069e8baeaaa911c8f08d", "2457539c731c6a90c62768fcc7169088b98c13a291bc70bf6d10372494f072d017cab2f2ab8ed682b4514f576af2f81b90cdc13a266efea3f98fecb4a2ac1062aba39e47e8b3bc487156bf7f41cb7872e402d514df86\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = a78eefe103fdfad9987535d10be6543a0092d1b49aef20a8c40df71b6470b560c64d1cda67b47338a572d695b314d4ba50f836deb746cc5a862e50c76fac689736c7912d5324db072f029fba10c9cb879973473e66f4a617d6aca9405f2556d44bf1d6fc3ede6a60a52334cb09cb0637f8f247200fc0063a0e8cc34ef01a6657a41444a942a8c72248f9dc2d15a26e822e0ef73ea5d9ec03060f906790510d88f46c38def40397a2aff2b77540dee5963a0ea5049904235b5e74da536c7a3f353d9cec5c50a5bcbfa07b9476aabb8de297653680823265d7afd8815267a79953301d7040e08d5981c1bb8958ad5bb3bb420b02449a25e8fff1d216fdc1f3cc2c\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = bd682ddc5226f61206b2464973df9155f6c3474412943f51dd8c8e1fd00a31b6ee2cca899db0aba83a918bda521014808790a0455a32cc765c19f088a0e1773364e25745eaf015b185ce69c7886efc16b3d95fb1668038eb9ee812985f965e3bd9bb84b8da9f1bfa324d050af36d93bc793fe58d6762d927340136dfac3ba149bbc38b4d3e4177ab95fc6fd53acaa925180b88b71f607620243d45d3bad1e96297fdd339a5a25a37436320e549742a5b1266d0946e056916cce24e002f7ce5ae412046bd0c519efc417352bd6d0e95920712d11a7afe3190afdd3b5ce510c0df7ff16c2e80869f69a2cb735f34f9c260b472ed20c3e8e61b2c38f564dff60ff2\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 672d24c076429291e410245c34e35eda0356fb22076601d55bea1bf309a8734062f44ee6615df4fa0067d43e86cca0a823bc4089cd50517fb3b921585ba0d1fbdb131a24685c02cfb25ab56ade1de0f6e705519bd5ae7e4eb2cf2a63ba9537ca850008712825cb2a2873dc76715c9922fcfb3a3acca0a4f15abfaf49fc298b5788bc912266900cb82700404c502ed66c83b6a4e93830bf9ff8e547a6c623ee99927dca03447fa1af896d76e59ecf3ab73e0453fd0d768f5ea1f4c8252f6a01849f8098461147c8e137533a89807968520c1d18b2cf62677ecdbbad1f09615c6ecb4939c7cdc17a53dc46f8143c36e3ebc99a21ef9320e770867d90fa3f083f9b\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 17652dc5457163c0a622e1a52d149770af1b5399b75cc7797aec3238bf8d9a67061e1d735e67f76f4f6f697c5c4f5eaece14eee288609ba0433fb17d0f7c54c9f5593b0059aab6e8fa94235174fadf7e601ea9968257bd9d9ee85631e3b1ce0d7a66294bfa68dd265f921dc7806babc31d404c35e51f4ae61c4b7b9e4d44f8c8decc0bf99b4a4367b53e3a61f85683ddc9c0f7f1d2186727517d1f9cf206e1004b0f57a19cf978456d669d9ee1339ae3329ecbacf717f13c51387b1ba0ae81718eeaba3e6227301ba8ff149a1c6d286e1fb016919fa4c8c7b78acebacb47606713b58205d15baa11755e7646b20dab4646a02d374346ffc09f6beda72a7f6734\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 02776046b529db8ff90a316f91eee580346bc626a688c0978fe5d66c14aa9ad9fcd2a887f98b77c8f3037126d32382dbf6a8109f8c0120e964a7519fe5bb9d1f4bcb3cdf761a19587b4914cde8d43f6bf31ab3d71ffe29ed293ea2202e5d383075cce7f9b83e3366563c148c72648a0ade863be3613d715dc9649a442cd2544762f3d2f0c0faaf9384f3f5b021200a062ee74d8b809cd9d8bfbe989499d9872402a0a490b654c1f856526334dfb84e73ec37cd75f63151dbfdf78d5e062977ba707c504dca2509fabdc85480fa2bead84f14c1a7197e2f41a6940ab4768fdcd6c72439be6f25bc600e0fc882348b73582adc13c674080d9c921367226230665f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 3102a70e601b928a6b350337b6e424d3ce2850bbccc6de821d677f2c406686c24ef6f3dc6fc450f873a7dc4ccc8a16ecd1c35b9374ee480465b7b312149538fe2e1d3a2a8b017fc916d3316eac606bd65b9af6d6179fecbd8ac2ef0f6f59082612dcf24786b4688a6a8659a46e5a8f941ad7c11a2e2e7275b900f0b8b0f6ca4c21878d96e876b05b3b1bc8e0d5548d433ee56f37722258d988624f0cca3cb0976c31c395f06931da563c3f2e134e636d5c50b4f4c32eb3a596b360ba0dc5f7fa2beb8f8342787d9f9e55ec018556edb4ce0f9d26b0f410ac877073ca8d40eefa2a500bf4489bad4fc60c373c576ab0135a612e2711c6fe04a07566f4c17d021d\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 2393ef64f33218e38ac80c309344fe33a1deba9f63aab29e06529f5fe5736721abbb792e787f2df1ec8db8513869c1fc1f0a78648f5613f70e0b522cd5cd78c01e121d3e527a49c248861c47f7b108228a6c4481451e2ac834029a48403598105fe99b3f060296043fb609277fff1746325763a5fde8d65e6f43791abd7b113fd7a8281d2629caf7f7615876dbc702aee7f2f01829b506dc336e9ebbc6147d94d853ead79693c3c6f956a18ec825be43084e23a3e15d31a888a885152bd7cff34cf3de284805e8358c7ffdaeb56b2257e3c7c1fe8c2ced183ee27fdc99e4f74758cd68d1442e1dcd05b62ce431c26c0c76852750791375345eedf9c9848eb272\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 6115fe66f94af6dc4f2cc46e552710603c271eb211261f415bea922adb0dc26085fc650758b79403dd76e035031e5d7d177abb752f4b1feb0bc44e13cf4b17b9b95b553c3eeeff2278f827345fdf3308b8d534a1e4a07be9ebd60c96fa45a2a04d6c91292f13223950466e441550c8903677be93f0c40562d8c51f9d772b7e2f721624342d6ba28d29b628ce8cccdfa07e50cb379063861abdb0d6876433243bcebe75a3424322255b5cbb44f2dfefaa9a9383296ebc44c6552f87e703368fbb33cc83de4f9027c588ae3d9e567ba28bd8efc5a4b173accdd0d0793abae5d2fb933055553be82eedbb6711e2ad648b04098a17e82a2a0ef4c6745c15639b7c85\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 4054692a9438bb2156dff805a60dde5ef1812df0eb8f7b4eb2aef74951bc2ad44850b830f558407cf5bec5cac20a26ba54112871a24e138ea43e499a7ff60e612124d06e0cd88533dd7b64ea20277fdba3c2522bdac6f79d9884ca1f971f1db54698e4cd149cca7674210f3beb08e1ba5bd1647417b5eb25116b94b165b80bf69cfad68457cf79dd3bdab1ec01b757d5f1a0286d53d8340ad5d53b0531a94e91e1a7f0fc864d7db4f9f0cc9ee0f9a6eb03305d7ebec3fc997923e7ca879d6f458ddc4618d2d8b7baa058f25c6dc092d6360b7f2708a0f28ed44c722f39f1e42b6aba4e4df8e51545df6cba4ed7b4fe8d65a6c1ad09fffde83e962d728de73fa4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 14c56a1f064ef78ee6a263c6b551d355fbf6beb7bdf6769999b86182f836a63f1f53c629243ab3dad581e221e8b51cae706698970d205f4bfb3858d265d05e0d5c9ad973e0a30f8fa6b249d1271ae931132ddb7d0b5a665c4a4f178aaf036a25ffcd5225c6edec847f9ecf949a93dbdb30cdcda198c95353033d87b3cc16fcbdd928dd131f4874dd4b50a8a617d049b475308d649c84444cb44e8544077166636ae6b64c4600029243f0acca7182a32e5504d98fdd8ab9cc3136aa0601ee63ee4022ea40cc6525bfeaaf3afcf66b0087885badcbefcfa31a0262840f098800dbe26ba91138600978ee739054ebae9fd9ce8566aa2a24989688b4f3245c7be832\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 81ea170e37cf844e0e3569cd9a1c88fb35d894c820fa46ea6de145613e51a6444404b18313bb47fc27ce81b953416bf40d9c86062f50cb7d547f0cae0682408fb6d1ca311ad617435229c6c1cd118476a12cf1fc96130208abdffe50101cf07ad3a318a8312c6c23fe9545a21274a169b1d7d4dbf198a1a06197c4d77c91bbc6b8591f66a3673d1eae4fdb0839b5925868ab8cd41ef670bbfaa77d12a9347658a969b7d0e4f51a1efaeb3339c761b8087f865d580263306417a275aa2a69a5b7db581b09b636f2dde022a7f9d2b2d88d64c02bdc3ca912ae89f10a0db867e61e7946057162259f9105cc13ba8d5125bcb3c49ddced4ffa833414b5f21d1e8446\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 8d86dc4148c4cdb2fc0fa7a92f48a1efd33897a2306f002aa39ba338cd20c44bee1dfe7db050145d9deebacf296cfa651f5e2e0f1a2b9e09df5d11dd564e2895f64c359c590ce0f400dd774f67c2e1ee178c0e5127ec30a2154f74b4b75b7f3788e51bfc6a54397f28e88587ffea825efd6cd1e5b6aa1464cbd5ee1aad24cfb86446687e58a2e9604f05a40c237bb94300677cb65a70505581af2fe51e0d7d82a08629db0499fb1d360f1f1a9affbd75579b98d6d976ebe2e407da9121cfb3a8b88472fb868d82881be87cee4d23c58a27b3707f2771dda0800ff269968bf5393a5d8c83d5d4235cc1eaa8c9db342b2929ad0ed8638044915efcecc507f66350\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 3e970ded411dc9ed2a18ceadbbd9d5470209c1dfba22e7cc3287ddcf10ca0c28fec6cad62227a156a5ee2066a995ab28a121ca7599992abfb75dbe987a4c190b1c58af8b13b11ed247", "24ba41e4a484fb35a38941c6838e4045fa8a048ea3efb460b01fb2d11aabcedf4ff2db5e889145bb2d729c8456e51f29608eb5aa65a1908fb94beb6c2a89778a1f2389821f15f818865e38568eea9aeeba0366198379b13723c6c37745b7ff7e4f7164afa5394083592e7d102ffa72a5ae6b3da8d92b5977fdef3a6449696c9e5cd2024a9f795e81633c243db6e74e566cc68ec4043a89cf69e020ed10b6590082e1a2015369029aaa673a92f44d6e62604672559fd933\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 731eaff9f54ce72b0572eb6cf3d586b898dd9d96ba82202c77a63f1d98642920790e092ed5a38abff54b6d12d7985efde0ec8b6321a5b8183a80adf3c68972e90f0027654e2c585eeb99e5edd7a9b56b652acc0051b95507b3daedbc6b00203f50553f432e612afa74056d0fae7021159ed95477fdc5719627c77af1ef2b2ee3b8048da4ef6ddb1662e35aa560cac6cb0beaa7d811eab49939b6dcd3cdbd1f00beb875bb60fcdf2a006eded6f449bae338908a0fe181035f14e6fec4f162743438ae2d9bdcdcc49c7cd778e762458bf2669b35ed3d498ada6041342d12627f14cebbab2c55daf2b9e4e645641ce07961b39061f432b6ab787a175f8e68f2c98b\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 00005814d6f2f3b23545e005a4f72eb0ef659fc07a8374780f8eb9223dad417bff6c96a91c6071abd678a8c9cbf0b4735e4c225e984669224e88655dd4f05adf1cb1ae96f7dc7932a0b387158a915f7563085f44c72a41f331e0e17e6895e442f7492151397159637968b15888f851323107bfdc1cd419d6ade56b974aff865d5823daad3d0cd8b1a94ee1767b70fe477c64a5bfa593783aa90868d4456f098630eb32ae71ad4914c142c805a69d2fd0e93563feca567ed922514c0c8867332c053d4912cd17d238eb46245fbeb03439c6e6adc1cac06d1eb41d9a185057431b25d4600684e057e571dfd1a573dc60395e7c2e3d612f9f66472f4dff284f4cad4e6a\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 5814d6f2f3b23545e005a4f72eb0ef659fc07a8374780f8eb9223dad417bff6c96a91c6071abd678a8c9cbf0b4735e4c225e984669224e88655dd4f05adf1cb1ae96f7dc7932a0b387158a915f7563085f44c72a41f331e0e17e6895e442f7492151397159637968b15888f851323107bfdc1cd419d6ade56b974aff865d5823daad3d0cd8b1a94ee1767b70fe477c64a5bfa593783aa90868d4456f098630eb32ae71ad4914c142c805a69d2fd0e93563feca567ed922514c0c8867332c053d4912cd17d238eb46245fbeb03439c6e6adc1cac06d1eb41d9a185057431b25d4600684e057e571dfd1a573dc60395e7c2e3d612f9f66472f4dff284f4cad4e6a0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 14d6f2f3b23545e005a4f72eb0ef659fc07a8374780f8eb9223dad417bff6c96a91c6071abd678a8c9cbf0b4735e4c225e984669224e88655dd4f05adf1cb1ae96f7dc7932a0b387158a915f7563085f44c72a41f331e0e17e6895e442f7492151397159637968b15888f851323107bfdc1cd419d6ade56b974aff865d5823daad3d0cd8b1a94ee1767b70fe477c64a5bfa593783aa90868d4456f098630eb32ae71ad4914c142c805a69d2fd0e93563feca567ed922514c0c8867332c053d4912cd17d238eb46245fbeb03439c6e6adc1cac06d1eb41d9a185057431b25d4600684e057e571dfd1a573dc60395e7c2e3d612f9f66472f4dff284f4cad4e6a\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen142 = 24258; +static const size_t kLen196 = 24258; -static const char *kData142[] = { +static const char *kData196[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha384_mgf1sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 5a3dc962dafca26cb3640e73bea7439a9f1874bc23e04226ccd89e7ba5c3b938a1a293b70dbab0f9f0f57f66951447dc33e730fd7e2c2a164d47ac502b07dd24cd3c142c2a79e4ceab5cfabff4478754b25a8c02c1a47d80d9f37abe442ca9a78b23f631b6ff3e15a4956d7f18590cdeb206d5e2b698bd084f260e82ef28ff9ec6dbc85a895ec8a3865750f501b96125db1bbdd99a4ae4688adb304aabdfc4e0cfb9fe6b6bc0db74c88af8217eed738a0d04fe8d32c1d110370ce1c1b2f630657350694942730878e6fff77ada7e9a317df8bc059ea7081325306b8eb2fa0d3a3d89fae476d9344892bcd5a42cf83b7bcf3e0e51b4c78e72b3207a60a701adb1]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-384]\n[n = 00cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f0203010001028201005a3dc962dafca26cb3640e73bea7439a9f1874bc23e04226ccd89e7ba5c3b938a1a293b70dbab0f9f0f57f66951447dc33e730fd7e2c2a164d47ac502b07dd24cd3c142c2a79e4ceab5cfabff4478754b25a8c02c1a47d80d9f37abe442ca9a78b23f631b6ff3e15a4956d7f18590cdeb206d5e2b698bd084f260e82ef28ff9ec6dbc85a895ec8a3865750f501b96125db1bbdd99a4ae4688adb304aabdfc4e0cfb9fe6b6bc0db74c88af8217eed738a0d04fe8d32c1d110370ce1c1b2f630657350694942730878e6fff77ada7e9a317df8bc059ea7081325306b8eb2fa0d3a3d89fae476d9344892bcd5a42cf83b7bcf3e0e51b4c78e72b3207a60a701adb102818100ef885b87e25c29d1ee431d1f4ace787c4f882e92d12c4b2766c84f89263106ef0be0ddc4de3bf061a2ba46ffe7c132ae67d337f04dc66daeb9de553791f4989f50b224c981812b5388d1c2b5d53349a61393bf6611995b6988f143c278ccc260cfe82a6ac4a6409807eab32664b7ee3f1c41dfe567e097fd7afe8520871a1c5302818100dbca582288c81a30d6581f272050a5fea773d711301bdd6ecac7214e00c0fcb9498f1e585086b14463cc89a02c2e77a89271c058c6f69f3cd13553994d8a76cf62ad9e275217720d62eb6e888ec4509cea474b53f37b458fc956dd31df3bb6ec7de659e88e7e709fe3be6a8d37264c3d20e7d088276ce7651a403c68d6c47ea5028181009d7e87c851d28d80c5eb84f375494ab959c5cdf1a4ed3dc0fb78cbaafedc8f958fb6dbba3cf1263ddc3424c8d0461c9fc60e802255d1197f20210ae10debc88a4011d1d4587d68d2750c8ebce620e1d4fbdc52a5b6fea1b7435e7752200169f123e2a0393171aad90ba38b05bc859f76098b5abec8cd48c2572390bef175fe970281800eed602d00432edc30428de31763c2d257c71b4d348a3ff0bd5ee6d9285df30c167ddcdebca1593abed86e646d7bbe6eb97b7647d14380af1dba54722dfd0072b74df956cc5181527d6c65f66a53d4f1c34b9247225b35ef3d0a643d75ded55e9c725f9ad6caa995825f35575fee7ef10be2129c9ca8ddd2550515d53cf8dd6d028180101d1f49afb04d065bd8c29001d212e737bba696108574a330a9cbacc51bf6c96594f37fba9c8de156c226371d49902191e1f69d84a1352193bff29e318eb36ede6ffbab93b6555ecf6addca9e134c20220a2d24b03a6d23ef8c608a5186769f66fe2f6b21bc39f6277ad706038b907872c4716609c223762130ef03616482f2]\n[sha = SHA-384]\n\n# tcId = 1\nct = bf20e0e04ddbf103a5133227fbc2696a0acc72f76f869240b06aee89c25128386d0e0c16927f98c1ff3b22b4fb61b508f383f7ea764396b2201e800c793c81a4d38e20b03ead703f0b164d7e7bf4708ce970c5907b139bdab8e2a1922989f97cc2cce656fe37630919626d966222c462af0e72ea36f3d81678bfd1928caf9111079edf93796d2713deee2b85cb04fa63d9fa41d212345507c90d04f4c6c80a114b36416cc55d78eb969d904269a69bf2e839075543955616071a45bc1678c64304ff5f4c22b207c27703f70061d1471b4704357c13dc44e1b3eed0842f578e3e84e28184f84ef6f80ac806c3ccc0afdeb17a74b42693f6e4b2a6c76161363f3d\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 0051190f85cf3bd0e9bdf5c937593d2219db50ba7d0512d38807b31eaa9310f0120320f7fad7c6b135f29cb17ffa5b135c0ebb1c4c8112a66912aa92bbb3191d5a284884f19460dfb9bf232f0db6c207ff21d53712e1c8d90bec036426cef56a017e6175bf8bf238c32050188869301ef78d3984762038bb72a982d5c9c9501820196d68c798ea29d0d60f7628625ffe975ee0757c6b70bf87b8219ddf9e6ad324ec9751fd3664887336bcaa7af71c93083dd96702e6089e2b67abb763193f95d4222b9177c17b4726998240ce74205f18cb4b17bbfc73185176ad761c1d48e633a4ac7adc2f61dc95798e530d20817b721311be824dfcf7629fbc533543280c\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 0a5067a97a17114be5a71697f15694d98cdd6e79dcba1726a38ca660ae4fd9a1336df2de79718cea176a365c46a24d0468c2a719cc1835e5b60aa64424a8dea0921fb641458c279c74a7ac74474126becc25c84cb8e411cc7a119c78298a2f45658c7590c3b40dbceb7c41c67e73d41b46ac55cbea541c64a91c521e377890cc031a4933a237609dce1d9f76684641417a44759662e166d837e77e9b8b3fd3343cad26de86db4f914ae83893fe9658654d0932b6a98ca5735669d667186d894b5d472a1efef4b2e06035189feaf960ca1242b620264e71c47307a8a38bbae9bc3d1bd5508ac37f1ba770bfc36a50a543ee204e5eff5310fe3bf430dc6908eb9e\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 767bcf450f416e428980a488bc8307674976253008d81340a2f519a1f4b936abf02028c2e7614f4aa31a8b3e17c96b4922340a6a9696fd4ff358c1a84c347b405033459f9192e9f7d611ca2da6a669a895d491a3c1908cb598730b596d66b1d4b7617f33766af385c333f037e7341c9680f9854f6ab4f2c986462d874f4dc66c6fa4f49fd3ef33d7c8cd81d7608411aa610e5e9101dbdba522f75cd12c575b42d082811227ba10319f6ea0c9a2eb6a3e63cfe0c1bab18f29091fc5d6372785208a830f732f8a0635f5ee7b0b9d2d62ff9f1a6cb88da253ad5f0d56e572548a350a7e12ff846d09ad5352fa45de484386b529e6f14a1e8055145394f8d4f91b80\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = c2a9b96b17314bfcc82d0653e14aaa7024b31451a842f7174a8a708dd80c94212af670806f96e7c08e2413198bc32d99a2e67d32c6fe772735ced16ae8b903d340b61585eb4b2ae7e0f51caafea691dabe31ddff90b114a13f05072fd8a8a9bc16fdcf32d199daa0de8ef34fd790f113505eab2b049c515a13a7d56f452f748ab76a07476d609f9e8db48d97f74f8e8bcdea62f495f573bfd2a171224bce7e2389811c01eec70ddffedd6bd2b7a3896a81a383e686dd80863f86a2290db0961ad1b2c6399a12fc725a33a182dfffd5ebc099612b9cd996a1c44037d2396ff657d22a50d94204e4428fe3d62b629c8319677654efb1bb0fceac9ae8d1eb3d2f07\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = c67d74acd68029ef1783f6412a2ff097bc4c588f4125dc9af871ff6cbc18caf2fdbd5f92235211bb460d7c32bad3d768a7893ad5b1e920ec9bde3cf9577f66a16d5a3e5a4feb40f0413ad47613929b44d40185cd4507515e73e9144a626c6e2461876789c8128eb6438879cc6b2a971dbcafa9e9f40b0120fa38f48023805011d89d48cb093bbafd221aca8b62311a6a2a29a92e13302c6da0f9190aceb9c36c970d731425ec079bbc6295aac01d9cce136f9e2d55e8516d007413f1d44bfaf63e257767dc0620a8902fb449f9d62a25630087b613784af81f1a588da7b0fc2ed2138e58eacc746cc2417b0088a1bc945552afb7536847baed72c16484ee7ddb\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = c1fb0843b4e3c77e622d1197ee897b8251971172ddd2a1bb94142173451d1748b468a450b15bc062adc94311fbd43a807391721bc05a4949b39af2ceafb1bbbe6e157237c6a7cb33fb971cef3c7bb172ca76f27e5a70b4ab501b8c4f695145da34f00a54deb47baf1f4722c313a1822b8746109c471f4fd8e6941cefe545804fad30e789e419aa32f16958fa667ed42912d6dfb5cc6d7635e2867253bfeb5ae946283f4fbc001fe8f578ca00c735f6cb02f65efaff2401f9da630ac2ed9ca7d44e4de8ae1ff6425560d54d75a934937021589418b91573b4eeb4f698383009c3074939d83c90d463a2c799c16e06c6467641d335b001ef89c9412f7478d5afb9\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = a59ed1881782b3a151254fd0102d0c78269ce015a542767763d786bbb88d7c764e6a2449f49bb8313430ed480ce6d65583502f647f439ffb578cba6267ddb492dc74ffab44cebbc11df44fa6e83899719c7432e509ae3a58717f452bdb531f01b70f9541cadb504b942f82b1032a5daa27179d83dc63e0f342d5f769fafc07506874704fab17d61cbda698a201fa42738fb21e9ef8828cfa0e0b4a5ee86e639d69642748cc764a4f", "a27fdb18c422f1257b9a7caaf2430e6a347bbaa170b77fc7f2aab7ad2673324c17acff7f67cc00525483c5a390c084eceb0ddea637f09cc1158638eedead7b38a14e9939c555cfb1881dae08479d838c1dc1af3b81348305\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 5490da684778d73666ab3cddb145bf50c914ed7fc5ccca7fa5aec07e45d925fd404e34c899b3620ee010cbdf02f190bf23f47c07f995142bfa0b1bdd988872671aa4ccaba8fcc668cf413a627bdf27f8b680f1b9d633cf3e2a3c0b83a9ebec591c9fd9f1a4bc997ad836bf5db9a8015c34bef11392ef8bfa4b278b9ba8f315e256908299812245dc534deacb9b97b7645162ab669721268177404799173f4f9a1e90abaf04cf78a1ea8a95e86c343553153562e3175ea135998e20cb51386e934ee28676e10a5a73b59fa1ca3b5c96ae43323883ab5a9a9214baa461046e3f600eaced75ccfb887fdb11d5d202347918cb42276370ef6fb42330d3922771e7b5\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = aaec366e45e9cbee804f4beab0c7d4a802731ae1e22d93e3dc0fa4868dd849c0cdfc52066051cf12887ccc09257301026be0e4ebe2d60dbec6de547d1dd4f778682fa9d88dccb0eab5e6cb07fe7c3a3664b5f31bd68cdbe9b88fec684b9e4a023f0e782e5e9a328628db6c3d94a1082bd0d3e453ce2628c1f17a767c017d725084dd0b7d715241b808b2537464dcc6eeb5af4c4c18702bcdc733c53f35d805f813e772ac32bcaffe025ef0fa8931849febf99c9e73cf5e4730a14924d9f074063b4d80faf3e8bce1930daa241ecee3b684d6674dc41b8ce53aa8c0002b0200fa393720ed967822eb2edd74a195423eba5dd6fe39150dcb697cc1f3553f84b9fe\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 348f6680d25d93e7f8f17f2410dd4bdc8a2ba5c9d29b17f3dc1e308d868ef3e1121982635c60fd386f77566370f5bc0d34e9596637c59b00a6eb665bf57071260483f72a5cf0bd6ad806a049aa670ffac206672fad6e206d9e13f82d89cd3675a888873cfdd1ea20feec04ac9e1d4daebc58ae9ebb84459a3481d268468f6e97bbad0011247576cdcea319b68b19ce7f2573cb3d711e078b9e206fea729e5b61d67f400a335aedb48f673af1a81c2998d80ba34ac18530ccef71838658e8937c127f5d5ce93a525a2ec60c98569d785592490fcf3c72d53791f8e81244292f1824264518bb827adf1205e6a2e1ca7d01195dd4c3616acb7580c0c9c572024a4f\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = a642bede4d119d37ba3c6f729ab8ef09055a41c5cc650a954bd0a2aa248172f3e332d3caf27f6652202287705d58b3ec31a5925083486c50c31ea5b27a693b2b93c6a4be3c5938a478148ed6600042970d71e2ae81e21a2f60ea683c4a11be85d2a00cd39edb6f05f8e93c2d760e68ba74a42dcecb6a890536c7bb093146a8161e8847b18ddf18e13eb04fcd841260016084b23efad5f36c3c5374a850b26f97e8076f9e288c9e904845c46df4fd8af41031dc6a9dc41c35c1ac73fb9586e308ecb8260d85d730ffe78bcc0439e4845bc9f6197956b2e4dfa4c5e6367b203c1a450a081e3edf6b50aa85303bbb547efbab5009fa80839d78a7d3c8514815a993\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 4d805a7ce650739a4e4f334de9e57fc134604c9e5198aab2bd2044b11afbc45741814b2c6b796411710445ad3f73b5a11d2066ab73d4ed636997c6542ec18e8af4f1ca0019865156cf9ee86315adb75db3640953d1f1268537d308256f712d0a3b3a4b2b88322056ae9c06458fc36eeed60359d091090a9a3d6c3646fcf54e0f98008a6440f5077ece467e10b9eeffc671309306eea60b912dcb872b48428450041f553412b0f7a370fc1f2ecfbe1711658de4991fedc33413f8faf69c3f8cf97e9003b2b039bff237681339875a85d2132bda1a029a2e79f0e37f90f50358216399b599d17e7760336fa447e6599cee60ca384f829df0fe49e6fddfce91a74f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 552edaec51577daf5a3a41f5122d8e14a0f210f4a691c22b624550d953c2e0c93fef2fb883d766a4996424377c384f41624c3d65728aa1a953e3283bba9ff5d020acc1f870e495c539f9857d32b42e9a7f821e2187e997c409ef85f0013c434918d7e085566607c2cf279d6d7a1f51ba51672d74491d1ad797461b555199ff3bcbd26f3d87781f09dee6cef446053685eeb60f0a81d57cf73b3d674cfff6060f53b0fa8f224e43ab4a88f0ce37d2ab9b4c257df77e7519f211dbaf6b9837992d9f6cd4e5fabba4ab0b405b49c8ef0cc172bc5889ac9beecef9abd48b46b134c3f0a8522cdfa0a07fd1c91788ac81c06b2cabd16117fe55d7892e4dba41188dc9\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 5de9c4fffaad1023d578673bda5f05d62dc73b5972b5addd16c453cb0d5aa9beb4cd7b51ef91a49f58c4eacba817b298b3f0d5053c37cfcc03770c0f84e77688bf35904033a4b002fab9065805e698f6f3082c4afd05d18e7b066a45a8c400a25d935455d3b575ee28da69e833163f8014f50cc3abda567b07f5b5fce34522f6825cfb6432ee17fb9ed6de30b7cd610960cf39f19844b09a61b00a957706227b2fa4e88081ca030a264dc1314bebc9a760dff72ded1f8d51706349db4cc95f0d7e6f331535075be4e95c12389759c26717cdd933157117a3b03f1c6f73826ab837a57405b0cdabb22e7f6ee468f46d93549067daaa6e735ef478fb2f6809b116\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = aea235313fd3bc3be95b1db39e4bf2ae67b8e70555d6dbb3de2c079c19fbb1dc4a9a6b4e8ce3d8dfc6d085b76a0559240bb90dab223dddf650da78301c255085982a7b8ecf11bc824586de0524cbcfea2a83ba11f619c8c87ae91d64aae92743b6e2719cc3d7a670a77614e086e4e3137cb1ca0c4867689b3c3aeccc5f31528801d1e22e864c031f58ced9d73f619bd5efa8f28f224587768c309e5086703ab9d6acacaaa1ee2681417b647c92db0640446840866b50de5d357da3ca259bd9e0b072bbc3ddba819a90ded0b4df6045ee3af3a0f013228fc454263f92a249eded9c73f7612f2f3303cc2b3463dd9c7a0fc2e474f899e9a27f83ea7fa5f11e0995\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = acb7bccf7e2cad69572f61c98565957f0e30931cc5980c4ee4540844e08d37066280b3d8d0f15090faeca12ab22b0a3f70b2d3b68ebc6d4b3f1998277d93256836a1f65879c8f48ea22b13b80fb0738cd44fb540507fb9f44577623a1af15384196afc9d5a6882c245938fc1b53c600fd0dd9f07a574e167041b53f414c7db6c252e875443b0006358382f5c83735e971337077249f7e9386ed0e915ceab283c0474308bba05e7410c91959648d1768d2e51e599d479a5578c6e7a0fc61fc8e18c017f4e2576087be8a8fdc7ada5b708bb07d6b0579c9baecab7e38794698c6d91390fef554c53b97561034db14b16dde648c9d5ffe61ef8debab95c57b22565\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = aa5b36de5f95c3c3b355a7968d39de17299bdb01870f07b3600714d5999dceee36451047e7eb1942bf25828a7368d219710ee27cbb8f58d9f64d9cc165865fbabdc52594a95049f21b65fbee38116a8032d37eb53dbe05b7ce5476e694cc0ea4ff981fb269d93cb634061c8355ef8e29d35ae3c251d24d894fbdbcd151da914a2a1c057a22afe8e13a596829cff32da6a8f7200cec826833bccb20bce20f96dd04066ea0728149dfd469ad2057ab3d6517c85d8817365258bec18a3fc67f314470b75f00c57cbbd04c51bd04971603acdbbdcdb36ff8b315baf4939d0b9ad5fa52093c8dcd701fe20fd67d8c3a1238f60141cb45e6b4ce0d504f03028091447c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = a79aaccb72907b41123e3efdb57be0c5ab48dc09ac22fddcda6bc497cbaa95b588ed3c70dc3e394e96e8c8cc07d1b49a6ad958a9cff9422be78aa2be641f38dc1609e076c41b79d874b8dfc0d601fcd065c4a24b9762170fdd20985a283f493d6772ac5b87f28ddc3fb67a941b7de48c6a8a8769b30d8e1cf020e649d11922d46933ffe809a68597744d9fc54ee47edcca190ab7d95f66067657703a61d53a0a6fa28113e1d4912f3ef0a8d2b5d0aadcf607f2f42a4ff52e2a9962d119fcf8d65c6474a91d62fc3e7fba867d06a07a03d2fa4969195879a692389134a5f414632de3dc6928744909452f7c6318ffd0df0ce3d9e10a8cae53d806b555a462178e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 07bd2fbe880a85da97962b4e806e3f380bba3dc80f631d9b4a9a64ab51179c5ea7f58789d8e5894b1fc7df15b34d09f5592fc600bf1edd118538a614ce3144165bf0578652686ce7df720c2660543d836746675a41cc929b198647c52ffb8b4afc74cba7de456d2298a1aa40c25247b4c1304f41bf4e137b98245ab8edea6f62077a8eadc6bc903722d0c7253b3d2b0acdc1f961157f14404dbdf50f294fd7fed64fab3a0c3cf46e683f41b89c0db6112395ff8af6348924823a43855a0cceb4bb00bb2564e40de0db8ccd803af1c4ce7873aa2fa156d09a4274b47c5888553cd09c32456da49411061e900188225eb181cf57cd8bbadf055f9f4df6f6389acd\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 79cb7928bcca16d8b74a0900d8de2b4e7f962e6073d74f3dff11c5a7d3e407ca962fd7eae0d3dc1ede81ea7cd4059fd1e304bf297cf30207b0abc8aa31189403d52a38811b6f11", "bfb930c15ec7b0e2e903623ae1d81083a5e0a7331c620d3d5b289adcbb74246d9c59336d165c0176e3c1b922d381ae8da731a933279fef6d185a689e039970135ac3c4d1d87d858e65f409341c593dd199e2dc60c16033023ad2665615877b41348721fdf3569bd03aff206a00a9705c25b3e33ff3b700ced05a6e72f3c5581eb3090c1c238ff5fcb26a286bd4c231f4eba81c5daee3c3c2dc9ac3cf2e73bcc15eef091cef335b8b89963a0d5983e1754e423d3b70c039b2c7\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = c295f57de51d491eff362ae8459c8be0224f27393a6d135bc8656b4f4a801f50e1c4c48b9eb52dda12c397416a89f709813fc500804e0cb458ce64d7c2c96f3f1f89ce70eb79b1f3c2efbdc46e1bf5dc8deeec5a34ab252568aaf8b6d832f677c04aac913901cd37c6914fc3517e53de1d75060c6c2d766625b5b8163ba556414cd114f45403f73d2676b7fcf9208d4f299d492f146f3e3da32ebfbde77a4f91574abe2195af5ba3b91bc4fe441e15e01da0fcd6d9e374aac38e622697b9385edb493bba4a486d35e8700c5009ec9cb82cac71a88c854edc6f1ceef96e759c64b08350f8073fff929468ef5aa83a86bffd9750dc43ea99927e93b4b3f84819c8\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 0000767bcf450f416e428980a488bc8307674976253008d81340a2f519a1f4b936abf02028c2e7614f4aa31a8b3e17c96b4922340a6a9696fd4ff358c1a84c347b405033459f9192e9f7d611ca2da6a669a895d491a3c1908cb598730b596d66b1d4b7617f33766af385c333f037e7341c9680f9854f6ab4f2c986462d874f4dc66c6fa4f49fd3ef33d7c8cd81d7608411aa610e5e9101dbdba522f75cd12c575b42d082811227ba10319f6ea0c9a2eb6a3e63cfe0c1bab18f29091fc5d6372785208a830f732f8a0635f5ee7b0b9d2d62ff9f1a6cb88da253ad5f0d56e572548a350a7e12ff846d09ad5352fa45de484386b529e6f14a1e8055145394f8d4f91b80\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 767bcf450f416e428980a488bc8307674976253008d81340a2f519a1f4b936abf02028c2e7614f4aa31a8b3e17c96b4922340a6a9696fd4ff358c1a84c347b405033459f9192e9f7d611ca2da6a669a895d491a3c1908cb598730b596d66b1d4b7617f33766af385c333f037e7341c9680f9854f6ab4f2c986462d874f4dc66c6fa4f49fd3ef33d7c8cd81d7608411aa610e5e9101dbdba522f75cd12c575b42d082811227ba10319f6ea0c9a2eb6a3e63cfe0c1bab18f29091fc5d6372785208a830f732f8a0635f5ee7b0b9d2d62ff9f1a6cb88da253ad5f0d56e572548a350a7e12ff846d09ad5352fa45de484386b529e6f14a1e8055145394f8d4f91b800000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 7bcf450f416e428980a488bc8307674976253008d81340a2f519a1f4b936abf02028c2e7614f4aa31a8b3e17c96b4922340a6a9696fd4ff358c1a84c347b405033459f9192e9f7d611ca2da6a669a895d491a3c1908cb598730b596d66b1d4b7617f33766af385c333f037e7341c9680f9854f6ab4f2c986462d874f4dc66c6fa4f49fd3ef33d7c8cd81d7608411aa610e5e9101dbdba522f75cd12c575b42d082811227ba10319f6ea0c9a2eb6a3e63cfe0c1bab18f29091fc5d6372785208a830f732f8a0635f5ee7b0b9d2d62ff9f1a6cb88da253ad5f0d56e572548a350a7e12ff846d09ad5352fa45de484386b529e6f14a1e8055145394f8d4f91b80\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# em has low hamming weight\nct = cd72b9c7697a399323bb3df69256ef3d7896c4b7c35a4932d56321e2bce7d590399041672d8a7694ba945d065469d9f527416cc771d6bec69db4d3653ab84ef6a1e1ab13cfcd5a23b49fe970f218016bcc674a655a10426cac75580065df467e2b3ca95e4a92f0c58b5fd9e6606cc44496a42207da4b5bc46ea6d389c35b3095db2c7ed756182408ac5c99aeeaa7098b1f4a91c5b6ade587633d66c9bc3357b11f3ecf019b1c53858d451d9f00a23318338255d48921971e86adb89a5c5742c6d7da82c7b9eb71679d2dc54911d9a427246be058f54ff269108c47a4bd568c3953a9365f641588f95c3c51311b3fe2f7c4e9b94f8db3410e738157d57e559898\nlabel = 027f3eb14d2f370b118a0b95acb6ce9849b6394de05269f339cbc505fc1b45f3f6a25b824cf997a6406ab2f496e145bf00000000\nmsg = c8556ddde4086f39f881c459e790ab6d3e6ac862be3b0f7ccdb6b1859eb160793cc16538744dd2d7b8f5d0a431b2e7fb21dc47977b40cd1381fcc5f3e8577331c14584ab3e5ed92a979a5bebe4b48c21a8b4f71d6a496d526907f7b6e5791328aefb2591e7994564c996826798bf62fa86d4b1e2f57e5df1fab316a928a007174698d32d15cc5a7e15acf53c31b30dfc18aab2aa9ddb0edabe65e153edb6\nresult = valid\nflags = Constructed\n\n# tcId = 31\n# em has low hamming weight\nct = 4112dc2f415f5ca05e1a9372660096836f4e47649ef22f31f3d2b2765cccedf922bbd9417f3863ee6be8f99a748f6b2d8bc0b286abd20849548b0173e385fa906d2e6d50ac3c8beecbea78d90aa7c630f4cd126b84e34b6acba9dd545a8673c4e00de4f6bca436f626bd7b8c1ff3c7cb3da7176ec11a0fd596078905a57e91387ce470f73c239227b6a9906c3aa8ccc214f323ca467a359fd0d1ae6c3a560d0f1285589b3e8b2e2acbc3ca606fe23298739cc194d97448a57206595189bbc9ac039aecbb77a3874aeed61ddf8fe718a873560c52f7cfa22d054d370aff20a48fc31850a19d7c4173d120a4fb108051bc68b8ebd40da335f620cce53cd07ea9dc\nlabel = d14bd61a246e92ee2be39c6066d25d2b2bb3bc95cfb16ca34700048ecdcfe85685d5aab6bf71d5d83bd6faccb81d1c0b00000000\nmsg = 5a1eba083b903ae2ef8bcc91ee0ce44249903d72e0dfecdb2e44e196f7b1febe5090b58e40b6e70004cf163b9a59bc02908aaa3eb52063d0b9ae6817a7eae8533a13437c0eafe1b5c359b5dfbc8821e213c41befd4b4548dd3e37f01d6b461d12cc4031d50c933514f004dce0e62a4e970b6a7b3bf06819dcb2a33351d7e8c0d130b0bbf3a67e2b75fb0059fb6ea8364678e90f86f9ebf2e9e4c5299d389\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em has a large hamming weight\nct = 204f1dfe1caf7952af8d4745071f4176edab7c4670db83502a450f6b52a6d90aef179eb4869b371d6a3ee2f0225494bdade6bd38b04a8ccbb00493e7c4b60c0c5be671808ca91f93aea17496b47cf9c6ca83e5f6cbdc41860b840f2c7bd19c2236aa1caf92f7b7f151305abb173d1ccbc97a3dabf50c24ae5d5bb719595cc2d1bea29185c55d7e1e873ff504b8e3008ec3bd8c702e792b6f6b7b24daf71b12168fb5cd586ac9313bce2fda37cfd0d68e401444920ea125fd9e7c8f424f4c5e0a068e7b95948289d71472b75d429021acf73249651deb09cee062de574e5ec18102852d1946050c84b3da9e63756f964cba0e4c68e8c8ef2cbbf6cd325a11853b\nlabel = d13595cf0b4193b80f34d3ed3f8a4cc3a3ff5d42f6a21d7f1493e744c3bb5819c53a9f16c9ec3b62dece167bd674a2f800000000\nmsg = 068a7d6662c9e1f96cb4c32cde0ba6da2aaf25501dc5f3b0cff0c74b6adc1cacf81c5b546505f360a4edc91f7f54cdac99458bdb01a5eee04947e2c725044da507c560a8b9856a5374fd75c02e6b8d1f915e291c6d8352eb89cef2f9297cc4d9b8ca118d1ebfac47aa64992a7e077e4ba35ca181eb3f0bda0330720f3f702a33878d3035e15e6376d528fadeaf29db79f4b6943417bc741c2a2f1d1eb598\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen143 = 21094; +static const size_t kLen197 = 21094; -static const char *kData143[] = { +static const char *kData197[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha512_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 0a5c2790a591c3ecf4f6281c17e1038845e540a95f21294a7ceecd75b18c54c50c02e789311c1b0091526f87ab3cc8d48188e980ce0e0377bec00e9f7d9793583cb66a1f281e31d20b594b5c66a2d9efcc36d979a92bb877a9678f991ff60b77e28fac55d64f21c064552a4319eb0a9a1870a76ade3c3a3534ab8353c3e57b2708363859ad3a6337fc15ffb90980d93743f972d743c3dc6fddb44279079a809abec8113a6f987f71748c036a4daf353b27a81e6983d56a2d65b71b93128d5569499d10ad1396f094eed77c044e3ce9ef82f0014c25ba693928c00b5043b641b016e3569b4bd84d683372538671307321c25e590f14bef241e6d8edf24ff39859]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba749]\n[privateKeyPkcs8 = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba7490203010001028201000a5c2790a591c3ecf4f6281c17e1038845e540a95f21294a7ceecd75b18c54c50c02e789311c1b0091526f87ab3cc8d48188e980ce0e0377bec00e9f7d9793583cb66a1f281e31d20b594b5c66a2d9efcc36d979a92bb877a9678f991ff60b77e28fac55d64f21c064552a4319eb0a9a1870a76ade3c3a3534ab8353c3e57b2708363859ad3a6337fc15ffb90980d93743f972d743c3dc6fddb44279079a809abec8113a6f987f71748c036a4daf353b27a81e6983d56a2d65b71b93128d5569499d10ad1396f094eed77c044e3ce9ef82f0014c25ba693928c00b5043b641b016e3569b4bd84d683372538671307321c25e590f14bef241e6d8edf24ff3985902818100e74a124759a174de33185996b3b437c24ed248203d674a87bcc2e76a667be3f54ac15e8f04e4c5e540f4e19f402a71d37d39756dcefbfaefb380095b6cfbdf4d78dd20cf085a1f127610e3b7102ca6bde1825941ab602e9b72c08e4533ac50317138e10bf7edfea30f52ee91ea6628c2cc65e76bafc02eb9d21ab66ad374ef2702818100d793b4f5514921bfbc47a1e45faa043eea03f052bce600ec4f5c62b014a7c45aeb3f4bc02160e7b12dee135e44b227a31854ca833ac706d14670ab5932a269c9b6f9188acb93e698b4a7dff65bb9c963c2e02b2cea3f2d5cb254e07b616792896e37550cb38171c4c32e0a6543bbe6acd4e99abeaba1340a961017412b57bc0f0281804dd402049a679730f2169e86f49f8f27c6684236ff1293e4cb22f6c63a083474251c9e9a17b677d5261f81109a81eddd91c4d4fc076b894c41a5b3005dd2ff984d3473c6d6f3a4830cd1b01eb8c59db245811c51d9be3ad0ba338b6c43f016e81c465c8c2f789977fb3f17e267f2ca828a4f3c29637193079a68bcbb83be547f028180767a352fc5d6bd7794d08186f3948af4d0c40d664b6ed4ff0ab6a97e403bdbcc6411cb5df27a419bbcb4656c9fb091dc2ed91adb78883d94f273a598461dc0aa1da754f7a2decc130ce65e4e15274c2949c6cdb3c7a1a51a96dfd2e7bc26a20069d47b2799d80060b52c2e866ced6ddf7abc50518e1df06e08ff1ae8b41b69bd0281805479dda30fc06b63cb5f77e20bb29db7eec7a6b37a5007f9651a46ffb66c90160be5700145c6a08d9737a98c5f7ba0dcef39352cc5d8612d94fd02383b8e093115376b154fa1cebdf915ddc051a7017d67a238fb4376749ced94712b117a1d0ca31cd653a1955dd547346d03b21eb0ad3c123fb85e92c8af50a985db10eba79b]\n[sha = SHA-512]\n\n# tcId = 1\nct = 409225dd2229d11accb99804e4da69fbcb862d3a74a1dceb8f1186d8d13b1569aa4fce51aff273aceb1f0c875d87a979f9915fd400a2eb1713b5a1ed129e6b0c7ca14a61a0939a87ae88c53e91ffdd635f7ddde6185dfe9b5b7bd739b53c4c198dc8333a36461c4d750773df1c84f024e18dc78d09fbbcdc4d12bb29854b2ae04c1b8b141eba753eed9cd90a5b66fea37612aca4c55f65a8381c4eff13c37ae1f9ed0688514788babc8ee27f8e76296495df254145331a49d11e7bee5a83a3713d4bbd5a805fdd8e84ba6ab869002b26e40b36d1d6c1189b8ca1c6fe19497a8059414abdc88ca71252fa86705ec96a7899296925f885fe55c9c6d2cbe7ca8578\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 7ab35168dc51cb7b3d8e5e3f9568e588c27dc395e825f909f3ef2a88c5ef8e1ee4918dcce7aa0c3ab6860f69de90e36d19284a15954a3bce2c95bb52b1a5cc752e35a7e08fc327f2a95ba05c474c4a5e625b5c0b780b3bed961e69bdfe073bc324a8dfeb3782413109fce1d795ef01a8eb0608ea42866ca997b8cd3c7b849190e42e84c3d60f935886df8d3dff5cca4157152e9ec9f954a7ea7b1ec4b0e1fbc14cef0f3ed16f1b013cef8753e1f5493ef7d0f753ed0a18ae5275459d15b86da95445dd65580a789354616e9a8a56720394a22ff30a01f38b173259a9829b8a4d14747326597ec332e1d402915c7f46a96c20bcd25a82ca3084660b4171cc31a3\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 930b4f613da112cd29f8fbb235ce0715eef85bd5a34fdf3a67b4af55015269ce99ac8112ee81b576b31f083160c5890dc2db204d581aba976974056a8bad367ff05984974c10f71f5b03482c7f7dd86aeabf5c9060b54b0487f40d30627e0a46fd7e801e5f1b2b813c4385f870258bc2cc186599e124b9ebca2a29a43dbc06bbd39faf7f305a902e7ffa403abc3bcedf29ee11361ba0a0b34f3bf9a9285660f66b4b75cf75e0eed8f463e204d93654a9c85b9788bf8e32890b658ea732efe3a56a4ddd2e7a426fec6486a0f591a8a1d4f089eb9c95a6332e7e0db103dc3daf8cebf35554d18cb6da33dfe6dfbe0c8cf04a4f6305693e94e87f68539f67892976\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 91d3f1fd66163ef8a8fe02f98802219f370938f21baaab871d6ed20de4449d5c615f395f89b5e455d301088285cf7ac42b51eeacc1c7d4220cf4c456178b9a2d6ba93b0b1c334b6aa6f19cb75f374d88d9d284feda4eea32c5a4d9baa0e12fec0f72308322eeeac9b0769f161491ddbea08983ea565058d98838b86df181088dc9048091450bedf4a671fe0a57f9d4ed67cc41ca6eb6a8324ce14d6202de07d55e80d56660ccc358b1cf6ed56061a2efdde8075553c326e9a15d441432c52c7209a6ea6cb6ae8fb1fb128d8aa31cea24e5648baa087eff8376bc01b6084e0476d3d5c5533d9c2c36803e939b8f525c2ed770ba08e221cb946d21d611c0fcfc15\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 41c04aefc703aaa71f40ce9f4f56a7719126ca192d2e9c33dfc6a8c176e8c1c22d9d7a83f39955403a7798d161e4ad17b1575c35cd8f2abab639307222395348b67ae8b7edc41eb0b9a38ac508f1c08489ebc21e5db909d98d69a74b210de76a924787b2fe1913c96ea934ef88be13969cb26fbbf007fff7f639760ca7de9041ddfe79b3be7710cbbf559db44d2db8aa32f88be33463b366924b845d07e2c00bf07fb3625a600b4f84041c73d777c0822bd896aee8b08c4f6e30dd4569208fc8caec74580a43acaf7fcb2b6daad569f4a58e281298caf9b6f155cf30e94ff671de9bb0cbabd184b854ef1d2b7cae33e7dc6072230ebe4bcd4d49253aef563e92\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 32af08d0e192b87a392e69c0e4f1faf525f9705af04301bcf4773caada60baf8c9e3ef5b23f22e38f9966849f55e075aab69f1bb76d2c9e443f34dcc1a9ed8d32a7ed3f9ecfc05cb154235e2e532af1b6f1fcc392676a500b5539f6a86be792de013a4d614129852ab57e030521e1a776d17a9c54061b7457e0517f260826640d24e604a08849f9c14a8b9b6126a394d1451649326b15a440f52da5fa917b15189a73f0ca93c6f1ca65a8b00f96516b9f87519e6ac96af33df112eb8cc669117821d7f318eb7f09ae74fe283ff4ded8a2e6b363543833a311c2b7be7b6f07798ba355a716707b06c4d50792c888424a5a049b1b0a33c881059dc8178119676a2\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 602a88779ae26e4aea37700b4ed513abed889d15de24523aebf34c9027fbd62747fadbdf46449ab8cf1bf5f2c4c942423e0c22df00e2b513aaa7a9502ee330be441274a09ac0b872150d73e52f34763879c56d09c400521aff0c7a8ddbbae280289113bd4f5cb1780eb16040974f41b6ec4e0b060209e7743df321a597a8a0fe00df285780073a03600c16ef62496e7e06335b7311d16a8cd376784f27289d02aadd1be5390e6e618cf8271dbd9ca7f8338392076ca53fee750f30c95aebfb26c8cee568a2253f2075eff7941b455317728bb1ad0442d691167f6472883b6e8b07e7f6c5bf10e4def8f271e622dabe23d6d3e8c0a1e277781e5888237e83bffd\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 738a92656e1e759bbf4515a13598efa7c7c3b3759ca87ee1974e7ff8f379953b7cb107fd421225d4c92c59e459e33290e6b73f8896f5f064be8de43c67c68bf6da3c7e4639268e5f204a7a9832fc1b1b5c4756c2e5b49c0912bb0dbdc049949090344301c42619143eb8024cd633a5a8429c9c717431f9dae72ce8f848ced228b72562517006f5ca77ef356af98f1d2828a59dc75fffb52437ef822a151bc696917a4cd0e688beaa6ca9e7", "ff15007c5ca12ff4da95e5780b8f7288fe9812df205a1a25baed9359ac87511bc8d4f0287de59940f0cd45e2f8ceb7ccb12b763b243adcec6da3d3def4e7856df4e4a4cd75fa03e14d5a63a5808bcad798ee2d2c8d\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 57c821093f340232c5df14fe7f6561c063d64e5660a353e6741774842e0fa0b4cd637ece4e935f7d948fa875b5978886b868195f5598a86e83f8d25bfaf445bf453c0a7ba4088e38eb6fb123788ad1dba2a3098e33cc7f354bd9622795720d3f3148db484fb982d5b0855e58ef8d74d12fe93e891f8987cf47d74024d1a2824b3d6a955670552d00055ec3bb0f6b4cfb87202cd66c36d831a62471c59c7d2ccd4302865496904bfce0a41ac3db7ac152fdfcec6bd984c9f63bda06d4b467ef1748f3a0c7f1e5a8ee5efd56aaae8981fb15329c44ba92d15edd20c982e555096b93921b081e68bd1e36b1dbe36fb3bdb69bddc8e9d9f6f1ca317ba16f664034a2\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 3d7787e441ea11708527a37464a529449650265f04b55294a71f3452586f55c1304fac48a46faa7082cf1b5d1d728fe337056551486d892eec1403550dd851ed6997e41f70acf7f401d1ac92c5e416e73f1f1a024e542ee279484db770c9a6c91c14d487bff37960db7a11064dcbbe07272cc036a1e0946d71f1fe97dcbdcab911b14d6e4dab44a07d8cd5bc3c0f008d9929f2d60b4c6ead2e84dcb86002adba056b3559fe40afd027cb05d41ea7f967e2cb4345c14ee37c25aef415ec932776de1ab992458203eb58a5eb1a21c3a619bf06aa0d6d74b5ea6decb25602139733c01e131c64b7de3465db2716940d00ecb5db6ba7c541543da53ba6119e7c117b\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 76a390230603a834305783f493b721b4f317f3d4b6e1bc26d1983ff1f49448babbeba061e94ef6b483579564496ea89f9e2e784e8e8db83cd0d2a6081048e4bece721197e66a54178acc6976089a4f6f268f8a54a2a9a3e90f583171401173f7f646d8cb422e4ee14fe057686b0072281e066a28cc0133c6b707781b718f535fa3a9c99a65360540d3182672acb1db4689c5d6d33159f37aa7e16d988d49f73b5e603f8116e1b5053ca45e6c04743cae29faa04ed939196b15faae2fe4303d7feab202d8809a7a2ad30deeec880990334f0da9c7faaebc1f7f64f0c8c20270c44b7046ee309d4bee151a504bdae896e856e202c8c5d8dc5d6f66c99961b6168b\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 60a639b945483083eb99c1c158f2cfd68ba8da37615b6f14f4a999b75da7fada3fb5b0716168f5342063306d8845ab565be176f457b6d26f2df5195356af72be2eab1185240d2b27d023141c060c37e46fc139d5df47667adb1e2acc5bf0b9d3adb7de087eafde53a157669b5e07507432fb366f4336f0231a04a3ff916ebc5f3a679239b39f952efe24aa5f053dcea10010986495bd2e1b6cad627f6c788b4adc6ebe482df63c13fca3b0371096ed74c079d8fa8fc3ab748b2e1935209a8934d4d4cd3baad94a6bf5be7c8517dfd55f76c25929cf3c14b64fed9c35101e3bbaa8c71ee816098741007496f20161aac16f1b4bc54b6a004d1e63beafc7bbd1f2\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = aece8a87a0c25ac33fe3225e262e5d2676ca68fe153b84c26b65e86f4dce6585f801e0b1d748ae6f3bcfcba4c5b95ab78f614499b547118d1eed2f6ede6e4a5966ae86c697577ce3d4f02cafacb76e2d90dc18222eadea2668717600e5eee93f3a20d583955ebdf9a66d5f957e42222a90f9de7232ef1d8eedbf884efe5e4fc0cca53fe4d7f60275c816f4f725b2d7539ce38ad3e643b7e4b4432842288e03734ae9dcb3d26f5e76ae227e7050ea7e0e5e2a755fd481a57d65cbc036aa9cb4062b5cee0d07e9dbae45b9a113575be96e9add1570ddf6b4849917e04bd9636f173cd5f79d3d05b1a0344cc62dbb523dd29c8cb770839525b9e6f7bbaf17385e2a\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = b05ad1bc0a5c6437aac33f123c62b94db24eb98d88808ebb1617b2866cc851c3818dd9c18e68c01416b1d593cabac1c364f89b1817bc58d021d9806f27d4ab4ec812d2a964dd70295ce9524cbc92b754e4057b2974b3648fec4a61c23548c7919ad4b97bc05639e6f727df472486c9f50265e227d648c56c13eb1ff4e5d743cd0a522f5b01f8efea61b934ed1f04fa0effc0b7a5a48b2662826ce72abaa3746e1718e73d06e3fa973f3117a45b578d759f89196b708e8685a314b8dc9387b4e82dbbad897708eaf10c285b9471468e2e464e57705e894018d2a02ea2059ccc7c7a921687ed9e358af5bc13c1d06d42afc5cec33e3497ad3c20b620f80eeee56e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 96a6cd6656b99ec45dae887958148f6748cf84dba950d7351033e98aae440c6f3603ed65bec311a55c6ec2bbc892442cb12730957b797ea8e3010efb8599891a3e8d209ea0eb6b32448e57f4003d2ac3dcf8c29a44454d0be799a5a772344282737e42f785ee3abd3ef80d5d4653931828d5f064354aee256b6271817e3807e15c805afae2877c8531cdccd2f8d66f3cd66d3866b5565d99154f1eb5a4f032596244dff79593980d07e6e06de0960c1df2c3f84de224c113494ade9d03f554871a0ef5c287fd0af2babd16fbf2983c758c792b489156e3a0db060a64d717e0d149c343c40015ccaff45bd4e3b155b9c4563d5b8c3d5caa97d7d46d4c5a2d2077\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 031efe798531e2ce640d492b623c630190a8da56e0fa3e2981680b20f14db024abb3bbfa08bdda51aa9d2fec81d23401a007326aa5849b24b099ce957c7e2b8352f97210a1e7ff68398aa3884a027f53f27e3c4ff65ee81af6afd4bc539e2f93282ed2a2274093305516b9800c547e4a8933db99b802b0ed67503fa58bd1ec8f086f1d646fb4fb3e468c75835efad1a17c5c1c7963cd74efc0c15d979a686ffc72f65b164dbfeb29930925ee5b2bd506378fefc797d96bcb1b55dbd4c58f0dd683c51c6d11c9427b4b452dcd7cc4344f21ba88dab082fa699acce7f0cb3e677d2d8ae803e0f1bafb0d2bc54d4ef88ddb91630fa6aa141b854b475ac190b696d7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = bc296554a73f000dc5b04a4dd96d91a82792cca120e52c7b9328a5b7518f4b8044e3bcebe8430badc933a8513641d68127d93a9137a96c81c67c4ad59048067990d14a208fd6b0d44d068c6bba72b28368c5781298d7be36cd3d462fdcf4f3c09fc0bedf8341b23f6722db3f0c96d7013603cbc35394ddb1f9edb8ac550c25d4ca6fe0062cb75ff3aced20040dbf752783a970783e78ac9f1c572c85973b254434cb7ceab15aeaa965878d1bc4be560838b821c35c218c06c5f6d690b86bd387e6511294cf9723d38226d95e3ad5d36ceae48889b7428d1f4188206cbe7673cfa2c28f51c4e451c5e2ad92c988038048c6c03b372f04eb2463512f5e85867504\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 6b36862a424ede6c744f0949dd9a3091d850ee1694deca2f844d864698eac29b2f1125ab310608067c37943bd386732b903e258865e0ae33eb38a8c35a84b3864b717ba29aecd5d5ef53f0def257b2951ee14bc95070356a9e9bf2f36232966c501710d08281c9b5944c5c923d65376f0cf592d3750603a758c16d30b9c307e32543a311bff7d47938f31f3547cc0ffc71441a1391f303970d975001d2df0033170cc00f26ae118bacb31707fde93c24abbbb8304b558c1bd52e9e6dabae23b789fb799f4f8667f6b7b724321d455ff4f391e8f1989f271204aa81ebb9491241871472ca1ebc38a05b93d557c4000e2cef7c5c9c0a85f8a63049170c90b2d901\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 8cd7fcfdeb18140c470d230b89444a63763c1025f69409757be574bf71fe7d899467cfe1a65d23d2401b7209e86be5a47753ad295c7203d2c935bd9de14556486908a7bf83dd9aee74b6e57204f9eb04cca15e2d50b22c5f45c7f362f23ed948195392a15b96a238b4e03daae8b7258ae607a9d5da0dba5629575edb56b444817824b8493b125d5da63dd81eba51dcc11f7979b16ca0314f02af4212a5ea840daf215e9fa082a7089550e5dd0c0d0f264d230a6249b45926fd360a4a56ac05910a15201292d5dc3d92308f98175c0fb4f9034ec8fc8d5b584e95ebb942fd16d04cd6867fbb2aa53377dca93e5ca2380de64e59ab41f71e449be3eafad63b4158\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = a83a07c4b0e408dd205adbed9d929d418e19e6cb0c2d486bf716ab66c21d1bdb341636ec9b5734ab9778ce1e28f882fa98582313d9840c05cb453973dc1384e73e2586b5e7539a3367f9ec788644f881be29c991b0e23de4e9e299dded39e349807318c5bed4d32b52d040ef5e99f06b1c14244347f50e57a8cb264638db98b3cfd467c2fb621366f83cbc68a27b0d3567e5741d1ccae568eaca51ac93f4c5febca4e23cc73fbf506ea337b0dfb47afdb351ac03e7bb81f1f6e867e4428d9b262d006976fb39901e84a2331b65b59fb96704f08bd77cbb7e0a39f357bc1100a70342e5f47c092a817374ac5ed1f66a4beb6f3a4820b6109b075cd80e0fbd840e\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 66e2bd9cb74a6abea34c2285165902c9a5aa5e11208f38a161ec72b0ba11e4006a9ff8b118de42bc45297a538e6aff1f4b56519e6d31d7ff9e5ff32e2ff05db68d023efb5fc10f5b57d4a3b216b63048c4aebd88ba409ec87e95bc239317c2320a06bad2da6cf7dc8867", "1c76859e4750eb39d09fbc2e27fef6e6247b23981a506e8ba9e8ee29709e0a846a617649083ef5ee383209036ba666f1240389328aabf61996563f65fceda07a24052e68896c65aceaa8d4e543ad4a2858a37369ae622924af975bc6924fd5eef327a01baf0b864c557ce86bfc2e84c1900d201e5f66786b499741e0f3504286ca6adad82d379394d4b8ab6f3a4ec3b16eee5506d98e\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 2d18a31f2e8762317ad943db09655b96ae7dd2b7c4754af2e852bd0fa877c58b160d62ab9378c06c0956d56b96d63d5693ed28b5d57a635432fbcdc2911c9843c68094301c6eb1ec02ff41400b9d9806673a0c07310a0a0e91973761a2cba91e38140217590cc2634c85247886f6364d5e5499c6e99f43822241d4e8ce6906b4d9b66ce4407c6e8fcda8f18aae2831c382afc9a8d273f17e2d44cfde2f463ea47a3292a74f743b1a99bb9adda4b65c8415040834f31e0f4392572d3a1237d8227adc380f794919e16144590fde3ffb92fae4353fab405fc09b25282450f66433d25a3178655545dda9da0a4759c8510e6e8f3f85799226715e7b2be7867d1fa3\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba748\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 000091d3f1fd66163ef8a8fe02f98802219f370938f21baaab871d6ed20de4449d5c615f395f89b5e455d301088285cf7ac42b51eeacc1c7d4220cf4c456178b9a2d6ba93b0b1c334b6aa6f19cb75f374d88d9d284feda4eea32c5a4d9baa0e12fec0f72308322eeeac9b0769f161491ddbea08983ea565058d98838b86df181088dc9048091450bedf4a671fe0a57f9d4ed67cc41ca6eb6a8324ce14d6202de07d55e80d56660ccc358b1cf6ed56061a2efdde8075553c326e9a15d441432c52c7209a6ea6cb6ae8fb1fb128d8aa31cea24e5648baa087eff8376bc01b6084e0476d3d5c5533d9c2c36803e939b8f525c2ed770ba08e221cb946d21d611c0fcfc15\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 91d3f1fd66163ef8a8fe02f98802219f370938f21baaab871d6ed20de4449d5c615f395f89b5e455d301088285cf7ac42b51eeacc1c7d4220cf4c456178b9a2d6ba93b0b1c334b6aa6f19cb75f374d88d9d284feda4eea32c5a4d9baa0e12fec0f72308322eeeac9b0769f161491ddbea08983ea565058d98838b86df181088dc9048091450bedf4a671fe0a57f9d4ed67cc41ca6eb6a8324ce14d6202de07d55e80d56660ccc358b1cf6ed56061a2efdde8075553c326e9a15d441432c52c7209a6ea6cb6ae8fb1fb128d8aa31cea24e5648baa087eff8376bc01b6084e0476d3d5c5533d9c2c36803e939b8f525c2ed770ba08e221cb946d21d611c0fcfc150000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = d3f1fd66163ef8a8fe02f98802219f370938f21baaab871d6ed20de4449d5c615f395f89b5e455d301088285cf7ac42b51eeacc1c7d4220cf4c456178b9a2d6ba93b0b1c334b6aa6f19cb75f374d88d9d284feda4eea32c5a4d9baa0e12fec0f72308322eeeac9b0769f161491ddbea08983ea565058d98838b86df181088dc9048091450bedf4a671fe0a57f9d4ed67cc41ca6eb6a8324ce14d6202de07d55e80d56660ccc358b1cf6ed56061a2efdde8075553c326e9a15d441432c52c7209a6ea6cb6ae8fb1fb128d8aa31cea24e5648baa087eff8376bc01b6084e0476d3d5c5533d9c2c36803e939b8f525c2ed770ba08e221cb946d21d611c0fcfc15\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen144 = 22691; +static const size_t kLen198 = 22691; -static const char *kData144[] = { +static const char *kData198[] = { "# Imported from Wycheproof's rsa_oaep_2048_sha512_mgf1sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 0a5c2790a591c3ecf4f6281c17e1038845e540a95f21294a7ceecd75b18c54c50c02e789311c1b0091526f87ab3cc8d48188e980ce0e0377bec00e9f7d9793583cb66a1f281e31d20b594b5c66a2d9efcc36d979a92bb877a9678f991ff60b77e28fac55d64f21c064552a4319eb0a9a1870a76ade3c3a3534ab8353c3e57b2708363859ad3a6337fc15ffb90980d93743f972d743c3dc6fddb44279079a809abec8113a6f987f71748c036a4daf353b27a81e6983d56a2d65b71b93128d5569499d10ad1396f094eed77c044e3ce9ef82f0014c25ba693928c00b5043b641b016e3569b4bd84d683372538671307321c25e590f14bef241e6d8edf24ff39859]\n[e = 010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba749]\n[privateKeyPkcs8 = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba7490203010001028201000a5c2790a591c3ecf4f6281c17e1038845e540a95f21294a7ceecd75b18c54c50c02e789311c1b0091526f87ab3cc8d48188e980ce0e0377bec00e9f7d9793583cb66a1f281e31d20b594b5c66a2d9efcc36d979a92bb877a9678f991ff60b77e28fac55d64f21c064552a4319eb0a9a1870a76ade3c3a3534ab8353c3e57b2708363859ad3a6337fc15ffb90980d93743f972d743c3dc6fddb44279079a809abec8113a6f987f71748c036a4daf353b27a81e6983d56a2d65b71b93128d5569499d10ad1396f094eed77c044e3ce9ef82f0014c25ba693928c00b5043b641b016e3569b4bd84d683372538671307321c25e590f14bef241e6d8edf24ff3985902818100e74a124759a174de33185996b3b437c24ed248203d674a87bcc2e76a667be3f54ac15e8f04e4c5e540f4e19f402a71d37d39756dcefbfaefb380095b6cfbdf4d78dd20cf085a1f127610e3b7102ca6bde1825941ab602e9b72c08e4533ac50317138e10bf7edfea30f52ee91ea6628c2cc65e76bafc02eb9d21ab66ad374ef2702818100d793b4f5514921bfbc47a1e45faa043eea03f052bce600ec4f5c62b014a7c45aeb3f4bc02160e7b12dee135e44b227a31854ca833ac706d14670ab5932a269c9b6f9188acb93e698b4a7dff65bb9c963c2e02b2cea3f2d5cb254e07b616792896e37550cb38171c4c32e0a6543bbe6acd4e99abeaba1340a961017412b57bc0f0281804dd402049a679730f2169e86f49f8f27c6684236ff1293e4cb22f6c63a083474251c9e9a17b677d5261f81109a81eddd91c4d4fc076b894c41a5b3005dd2ff984d3473c6d6f3a4830cd1b01eb8c59db245811c51d9be3ad0ba338b6c43f016e81c465c8c2f789977fb3f17e267f2ca828a4f3c29637193079a68bcbb83be547f028180767a352fc5d6bd7794d08186f3948af4d0c40d664b6ed4ff0ab6a97e403bdbcc6411cb5df27a419bbcb4656c9fb091dc2ed91adb78883d94f273a598461dc0aa1da754f7a2decc130ce65e4e15274c2949c6cdb3c7a1a51a96dfd2e7bc26a20069d47b2799d80060b52c2e866ced6ddf7abc50518e1df06e08ff1ae8b41b69bd0281805479dda30fc06b63cb5f77e20bb29db7eec7a6b37a5007f9651a46ffb66c90160be5700145c6a08d9737a98c5f7ba0dcef39352cc5d8612d94fd02383b8e093115376b154fa1cebdf915ddc051a7017d67a238fb4376749ced94712b117a1d0ca31cd653a1955dd547346d03b21eb0ad3c123fb85e92c8af50a985db10eba79b]\n[sha = SHA-512]\n\n# tcId = 1\nct = 101f82bcb8157966c8f50531f294510416393943fa9dd5dc05f85bb82f0492502274e07ca7dbda2a7e16187981c923d60cb6b427693c6d7b107ebadbb6fc400492fb795cebcc804d498a7d3a077cf39cd030e941308dc87000af5380b3ca5e8728313e35e31b78ede9e5f07cdec8e3569afe3d13466d06d4b77030d146b32cdd7da566d96753fa44d64791e687dcb324f52371c0191bc9f1a5bc7b7736a5bf00d3fd518b70ed6f4ae0fcb20bc92ff3eb048a6f767596263127ccd66e474e8c27521fe2eb21b8abb2c23b91bb16264e058265a567492bc51c4cd033b1d8a5d7b5798360f4c3716ddb43622ea5dc9fcd36819e05a989252dcce826506711a20fdb\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 35aee1c56044da3b866bfed989690dbaf57ac10211ca4c364c4f4127fed0a55b581217c7e854d11fd1a1f9d5431c2c309e62a6f7c3c59676182b288edccfa961c78c1baa53f2db1b1b9a4dd05015f41872cf22acfe3a071d6ac1e82ba6c31f5c2d9325247d6f2c9b03ce00c94f02fe33c5678a4149cf2fb70bbbd995af1465e3819c83c9ab8b55088fd5d75036613b04df302113948700d7876b7cec9d7337bf5773343d51a4298e717a4fae09e573fea412d88b836ecd4f74c7cc7500609723b3f3a2a00d85ee7ccbd92bf6c065833027c5e50310c6cf8fe8d13e2d8218e785333a2e65b547e5eda2f8f2f9608f366d7e43636fca4f46450c76f06dd08b00db\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 58878dc8b9527a416ec9bfbe0f07fdee8dc5bac8e31ca545ae7c6ef4a68f2c6b2b73366518edf85f1143c27fba00a5d9a9b02843ad8951631ddf01ef1238853b4593abf9701c621941b4f05931eaf307c06faa7fb818db8f859c96dbfc43268965303b44fcc69a0e3ce619624907bce074205f113715e5e820bc8c6dda65066453215702416db9320f54e67fc91e9d37a8522d701aa22976966a99cbc8fec0e12f2eb9b5705b4dc77caff82a36485550752a3a5ebd47fc67d66b68024a2c5db809d08be9090bb96e18807925b18a753ece05f1624fb19537abe7fd662830d56647a416df7ddb3e6a073150d5112f60538b685243f1e4fde2a5951c9e9499ecc4\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 2800f421c1c078b8bee9c4a4f355e1ea834c5bca442e9986792a50e66e68c0b8122cb81bb59e0070ca044c1c5b190f9098dbdaa977a441a8a4c62897edb9484935007aadb6732c1b2b2171aea3ab1513f225ebe7830fb823ec3f5433bd8f3c3e52775bb45fa91aa0ad3b7c1bc647b775e4de8e1b22eb971041267878421cf43a5e2a2675b2c940daa55f12a7c79d87d45e08c5592362f5e0d7ea668af99eecd2f60d7fc3791e4f53aed79931bd0ba90f701de836d8c8c9be7f7f4aedcbe5c92383932f762bec65fa298eb644877de26eec995146af551ad77ecfd06a3670721ab4c7577e61c048c5dd01b282cfc0fc963b92c78eabd13fba64195d74de4829bb\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 65a7286d77963a2d168ddb4c0e854baf8898d1d22c9de5d4968e8b326f92ede2f18fd29964708211ef6328e4ef16ec36a775b36b4531c52e01c7cc0058064af954790160012517134f17d92a05000ebba84f515f90258278208cb0a5db11d4b1dc26d2042218d2fd62aaaf53633ff0f632431a010b7e14971a41791644ebc170792a61b5548569f1b0268c890074a4b07d8e62d4857f9e720cb7307713424c701f6f666981ac8e96ab066f303fe89a138abd57b24f03d9136ef468cd8519235cef7bab01717898357c0e4ff4d3685706beb5d680da2885556e84663772d6c299fbda67df2cd325cbfd62932836920e0751b0d8095b914c18fbe5e348bcf4d85c\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 7fcda819b841cf7c668f9ec9e7e115146f990cc420efefafe239637076bf9ef1c49ea69474f63495d90cd3859e335d323ab9a967c65fceb0b33a760142b00894d1ac25ee7c2833bf2dcd086a0cad64433aa606f4747f14500ed2779470b4339f580e2fa0a14d870d6738e726a34dda3fb7b82509edb6d6b9bcaefeca077b2dc582982ee6e28fbf167a92b0ff1141d10fc3dfc49adcfaf32115f900b20c812094bca91bb10301616af5030e0a600c993a24d96764986782da083e327569103f7b358a6a91d05fcf89a9290ff989ac8c0acdae03438a44b16c7a3e06a1591869874f29460b0ce09bd022fc3c606d785ecfe4f4a120298408cb425e9abc7171e4d3\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = a5053d46939bd6c90f2a67f6613070ba40a831428884fbbb09d4923b978f17bf538a5963a0416875300f1b51d56880ecefbe58ff6ec7b3740a649f36db16ba6cab9b0e4e7a1ec658fa0fec781361a547a718ef5d9f7d03892bc1b18602436fbe5ff5cc6c3cfe8f2e9df960ed89800da546630251d292b00a60d102211db28ad184919709d8d4a1ab89d65ab2fdbcb66e1492c4525417eed89a0be2c67a79c5f89494ee7ef9d3d0d7db2de34ec6be5863993e8f64e4601b7945b2ea271efc941c4253b09dd3a3fdec6b45038887018a5018771fe60eb67a68bf977e9d3c6b032fa28868df58386902065ba3ac7f028600c5dd5c180552a25d741db12763dc3b89\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 38ead5cec1622d62e9f27eb7bb9d369fc13cf7d21256c5df8958dffa1df2dfbae006c80ac45ebc3044a20f8ba024b73c2e03185a9e4d975fe3075e6e11787116d1ddabf2af65904ec9a5b145dbf167872d066ef490c4b9a724000c44425cd33448288e883fd01ad915b8a4d9d3c65fc0c12d5c5bcb78b323db20ba07e57a18820e1154e9460d71b92f85aed92c2128c83e598564138a97e0379966459364be6aa166a8b62cf7c5b806", "2d99e98fad155c9f0f1c8629e43a45674563f0d142c309605ba2dcb048a9d5c58feba16b5b2c988d93741e84ec47f1cbfeee540f10dac120734143c80e98725c609ac249558f8ac58cb21769941102af34aaf02d538c55\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = a4582c4dbd1e60062e517331f4d49a67491c975bbeeb58c53c21c1aa350c63d74940ebb3e6d8062cefb2f0cc645b07e77e6bd350baab08862665b80fcbb5c386bfe330eae7c43a451d68e75da6a0230a5ffc45c9706cb5bff4952aba08230a626929726ceea068d52c18c525dec9d94884cd93a5b39acbcf31a0a3c1d28bc2ff352ff4097224664102015a14d6d9663d91489f9ca4e5e240a4d9c93707e015f07dd6398b306959d6a545616a3124b3a87c8a17293ba36f3c8af4be8bfccbcc0fda06881e05046b8088fa09c542f6bc7a397ab82f47e05d517e79b462fa77be7fa1af05a09baa17ebffe73e38c3107f4600d75f9becaa8af68e37a4deedfd9f10\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 1bb7a6d1dbab994619f25bd1659c215dfc12ccde9f91ecdbcebebd9c9d1399ab8296035f43f0ac65c56f56707aa4a301939b745a0d0000652072aba5c514ca331c9dd06a2f1c0122b1ba6f9389c6ea6904f36cac5788d339691feabd34b65bfa4505c60e439713591a8ddc6ebe85131bcfb37f7476120d587f127cc52f8914f0c78a2edddd1c6c5280b745de595bc6be424d01d99e58a8834742cd2f085b334966b692c3bd372b94c846581548ed2280c64b320ec1341ab54a702ef7040ff67094d540dcb080fdeeb2050fff66eaabfd5b66c99ab49db5e6c72cb2d530d503a87d691dcdbff85c5e8c9fe28a1f32fc4a22a2a67ae9584a4411f8dc03d3e76b55\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 89bc06f1f12c0b688352d31ddbe22de92b3e8ce8e0f7d34e5663cef1b473408c932aade4f06b056a52a48a0b7c80c763ccd3155f9f4282aa350e9c494dcd99dc2f4c17d53abbf24a37194db5f987aaa176028b2570c8e74aab356e233e406812a17fac0b92d27f503e6dcba5578755ad33a105ccd91204c8ed22e923492ff07d5aa702394b5b8cc417e8e390fc8268cab2468a4285a4fc327a83038e59114654df7d4dd32910f0fc2e900177d46aea50a61fb0e2066947fc648ef40e22c2156464fad8bfab19d8dd9a4aaa8804024693fd2cd45c233c59ec67be03a8b23fd859003b2d01540214b3c06633ce273a9a992d11befc23ef6be34798522c074f4ffd\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = ae26c94476747f8a7454a80c05405bf35799ca1070341b73208de24e7787af7846de55ab36c2d0feacc1653197d42cfd02aabdd57633a69f7fe09bdc72c8ed28c4b1736ca7b285cc685886a5ec535da9db91965b291c53bf92b1ae159974ee795ad0fdb8b422c06aeb78923b27ce67a766f142d10f960448679e5fd1176124593d32b9b7653862147637a76a87332acc5be2a955e4bd2de8b63d873ff449715f6f1f7c76e4083151dc6d58a3e3144c694a4ec85523fe71b298dca5f0716619ea3e1182a94c5a9f6e602844df92d1d2850fb64bd1f28da347b44e0af2017bad6b61a7190dcfded0df48840d3a7bcad796744c7ba5b214002f930b28f958cc5f0e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 1773e5b493ec17b56e250885eb5fbc3db160e2f6ae55bcd6a43abf01aa61a4b0b7b2dd0d522428af6730ff374c40779ca0c2bd8008e266ed234c6133ad4ce13f78468a0f828ad86a8dd7866fbfac741f66d909ea1f415a7337fd449f5b2ec62c5bec328d18f9dae193eb1645e1fb26be42bc6eb980ce5679a88144a2dd1df32d8fc48fd9b3c70e95561f50da328161d2ff658196f7f98da563af6e4c1ed2dbe992ef0df66932a45812234211131b43f618b277c553fbc408ca2369f33e080d9b1188210434c2d90c3f8d03d892eadd70af1c43a8586a4f523c60fbba5cb98e2b0855db413c2e99ea4863a1c2db014b6a31aee56448bc00a58717f03859dd6552\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 6cffa2bacf010449460c15f4e4d5bafd23be3d7ba4ac69368ac0dbba1268df39b96a863e759eb31a3f9eac5494e29f710afeec490ec82d582654e782c06cb0613d9b15d8c06417e36f686b71540494f51e993bc2eb44629fd3299429068ea84309504899c5b1bcd7a49599938f5bea8d308113d84c38acf7eb901cf3274dbfd71b98f420a83372613b4f43189308aa76c9ba15f9769cf4bc5def8ae02449c3b1ee74f0032bf1a8356797aae23f5a598c3f336df8d195cf31f9dbb60ff4a9e5c1398ba07662f31246170ffa3bd38ab0b42dbbb555affdd4928a4b478f9d5ca9a8f9719b0b2a0d3ddfbf708368970bcf027e48ea2d0ad10949a238c218ac7101e7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 9256e2341234a867ea476be7848b35aad5e2d2cd9170768af4f14fc1b30be151ceeb2768767e090913e0e05844088fa15b7a1a99777b614a89e99de472047decd6e9214e6c025385fbc467c5331febae8e2307bbb0f015228024445e142e79d91cb7a00cce07ebd36474d6bb2194a39cad1c110492ac0e0637fdfcc5453b0313065475a563a8257aa1ea467c58cdeea0e139132a97af3fc90b3bd70f03c337dbe73ee8c992a71d847bf9f559e666592a7f1d3876cd1625ebd4056c6de6077229cc2dd230cbc51ae7a28105be3dc32f795ecc11b45ed1074154f1d24b11ab5596d3f8829a5be976b2db2dda1e2fc2174384e6332a63a19a734c50b1a34e201ca0\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 6808813038a51bbaa5f4054f9fb7906c30736fcd150a1c70b3541d3707263057142503bf285bda1debd1d6c5491269627245cd649a027d0edcb4358ff9fad83c0644ebd8c3dee5be6fdfc1eef443bcd9cd5530b088f9f970623b380bbeb0b945c74737177c6b1485c5de2a0aad576ca79d05b41ec7c52975503f3af2cbc772116a27731687aadf16fa4704cfe56223336c64e2d8daa6a5fb75e47c0fde2bef7c48beb46317b3e637c5bfce3ff4fd5654b24ac6401ab346fcf7e214c674e099eb9d933cd1484e70fcefaff0498c8fd8672e35312d0bff87e244df3bb4a3c3f64d73fb0606ab46b8848e140a91fa3da08ec104bcee483360048cb1596a25b56106\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 7696edf1c06a6b772a95964665cbeb28f92fdde12ab092d7cf18816ef5209503d6416c9f4b24a5e4e1f828bd93634594b6a597a86005900d47e6b467337ce96023392958e30e4af43e7adf2a61b523517e299dd10092398d1b13c227b846a9ff8c792b0b1dc413459d9ba4543c81db4609dc6e17e5b99f04154444ef3b235e517e2b493f7fa1cf6e7271aa16961077f6843a3170aa61a0c4d57c0411a518cd35c0eb63e50b9479e7b6d41ea793a6aceee1cd892004dd35934ea383799eaf12347aa184c9be87ef1c244407acfef24f973a7127e614c57cc11a8161b92d57ecb67740fc29164c53413a9a9e216a5b3a290d585a5c0d9a26bfeb6b045b6bcf5c4f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = a7b27e1bb007bef734447c7e9a2b37e06a1721aecf7452f73da74ff381762b1489c6eba62e348ef4c4c6227a910025e8970729023cdc628d97f9d67e81a36e05d83ff625daaee05183042d5f1490c6d5ab6347e94f33a88ff692cc1388ac01fd1d7fd5ca5a026af5fe75551a76a8bf51b5a88e6d7f9e9977a91c535450f27914556a9bda1497dc58dd74b6f27b8a33d8eb157e03c3c5d874232f1b2e7c13138756c81e4de00d53629d6cbe7c7ee9b30ff55b5f31475e2ef3e96aa01f604bb382f5ecb0615d195c011d405e72fd5510adad469e88e42a5c61415c6147e2e471f28ac71c97044fb5df892cdc482caac4c2350033e00b43a1221d0008c63fb8f0b7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = a0c8b1ed6dfbaa3e738a3f6382a9d010f7281d9f0ee9de03436db92cb51738aa315bca194a9bd908340b0c3e1fc8523ce5711ab0f9b3f9e009ec09e1252805809eacfc2059579d45be3d4e26ba9c6be2f35c2ca3f00876a097d0ba9719ac9798c205fd8b44fd239f5bd21f7b264d883a1aa760c60a226c9b9c43090e6d91335a1f0ea04e5151631807a2f1e13fcbb5da9d98867ce9fd448ef1a116f779933dae65e5284053dbd2d004cdabf7c3bf5eb2cab25b0e646b25d34d277a4b20696f2e6cf735ad8acf6a999858d808627a049fc4acf5a507477620468ddfa11b56d28b63e46ba88ee90133990e0f4bcc2ee53acc150ab3f0c6ffa1015bcbd29f9d2d69\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = acaf316a29cbd805132b0c43a4589761a54aef928e4036b15b389a9c17a04c86ee6d595c064cdabe383414e41420be7e70163d89822774374ea85befbd3f3fc7dddc3de1f1ffa2bd595dbc678a03c0ed643ab4ee540c8e3ffaf86fca0f39eb4f795e9c387045ab2f378f246a2ff746dc3cc1df8f6158f16581231514fb22f6e169b13199c4239c1827767aec256d84f729739916f7d43a015a331c56099e8d33d66df6352a459356d9d981bf467dd88fc115eb88b4b22bfcb333facc97d295d72cb06984cd12b670a539400a719d11809a73f8c4406a677eb6285da557f8f69bd006da2c286a64cbbcaf2f2a083a8e5baf560c9d6fd703ad1544413eb0c3fce7\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 0e5569756d22d82b912ac15e90209006c52f6a48a499e242c6603eecfc2087c3175c4d18f42bf6bb6b201b9cebdd8a97a7b32e4e7e75e034ecb96bf0013b2f52ba036ab2929c163962f08cfd96ce780912bbebcab7798b5cb3eab91b82b01dd1983c1bee76334a71", "fa93ad2468a799afed4caa1284fc01225cf225bc0ceff35a6569b76b5cb57be214da94872eba8a73cd51acf917a627ef17547af38bcb805485262063f80c0daab609a40467f73fdede744db116842cfcbe4b1ea7468fcfc258e2069afaf2c552b3be864517a7b0c71d46765e9573f0643cc762ad21826920de1ab3d116496b71366b2f6eb487d8b4cf8b1d6d673da1b38fbbf1e11615b108\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 27f08c9efb8bae2841e67397d0bbb2e852c6d844b0b83eb0d3124ce3159020ac4bc750377f11630cda6956954cc9dd8ac5fe586e73c045ec8af96ebbc2bb6c0a3bb70c8d67cac5e972b38b20901339ce118e268a8a59675a6dd3db05f0f9c4890061d040a8734fd456176d1f4ef81129c7b3daf2eddb2f4c72251fa52550118496230461b583122df9f112599cee7372629b1704030385c988c372e4892007777098d3bb278578e306e5a37b89b7665321635b24564055f9f4ade4e2c7007014db3add8093659c285338ff370ff7e644ced701a7f8c131073f8651994758d0394224cd2271275443c079a3121df825024afec839406cd410f20fc829aa542702\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba748\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = eac59c81e52db549558a3b7bada6e9cb7b09ddabfec008f9ee9c9cb91f1976f168adef3158e37b210f8fbe1790bd6ab892cb556d5d1e204d02c2259f6f581f00371b1fe122cb7045d8fade589248475b30c37e5fd93b053411ca329e568a58bb503b0f25ce9ef9663a32b75165804d0f99941475bb4ee8aef1283b9c7a9a9b8fa337d9b6e35ca1be25db180d80804c241b6733e62832fcb8c660f2197dd4f4fd87078e46f85143b43682e33f58ee33b74a357d0588dff43dd06c6be4ab49e81f4f905a22b563c2704401c64dc3e4ff066c3adc541d5715fd7674031e62d5a7b2398de09eb8da0a954b3c185db29b3fe26e00a61067413fb640103bd0f503d104\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 00002800f421c1c078b8bee9c4a4f355e1ea834c5bca442e9986792a50e66e68c0b8122cb81bb59e0070ca044c1c5b190f9098dbdaa977a441a8a4c62897edb9484935007aadb6732c1b2b2171aea3ab1513f225ebe7830fb823ec3f5433bd8f3c3e52775bb45fa91aa0ad3b7c1bc647b775e4de8e1b22eb971041267878421cf43a5e2a2675b2c940daa55f12a7c79d87d45e08c5592362f5e0d7ea668af99eecd2f60d7fc3791e4f53aed79931bd0ba90f701de836d8c8c9be7f7f4aedcbe5c92383932f762bec65fa298eb644877de26eec995146af551ad77ecfd06a3670721ab4c7577e61c048c5dd01b282cfc0fc963b92c78eabd13fba64195d74de4829bb\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 2800f421c1c078b8bee9c4a4f355e1ea834c5bca442e9986792a50e66e68c0b8122cb81bb59e0070ca044c1c5b190f9098dbdaa977a441a8a4c62897edb9484935007aadb6732c1b2b2171aea3ab1513f225ebe7830fb823ec3f5433bd8f3c3e52775bb45fa91aa0ad3b7c1bc647b775e4de8e1b22eb971041267878421cf43a5e2a2675b2c940daa55f12a7c79d87d45e08c5592362f5e0d7ea668af99eecd2f60d7fc3791e4f53aed79931bd0ba90f701de836d8c8c9be7f7f4aedcbe5c92383932f762bec65fa298eb644877de26eec995146af551ad77ecfd06a3670721ab4c7577e61c048c5dd01b282cfc0fc963b92c78eabd13fba64195d74de4829bb0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = 00f421c1c078b8bee9c4a4f355e1ea834c5bca442e9986792a50e66e68c0b8122cb81bb59e0070ca044c1c5b190f9098dbdaa977a441a8a4c62897edb9484935007aadb6732c1b2b2171aea3ab1513f225ebe7830fb823ec3f5433bd8f3c3e52775bb45fa91aa0ad3b7c1bc647b775e4de8e1b22eb971041267878421cf43a5e2a2675b2c940daa55f12a7c79d87d45e08c5592362f5e0d7ea668af99eecd2f60d7fc3791e4f53aed79931bd0ba90f701de836d8c8c9be7f7f4aedcbe5c92383932f762bec65fa298eb644877de26eec995146af551ad77ecfd06a3670721ab4c7577e61c048c5dd01b282cfc0fc963b92c78eabd13fba64195d74de4829bb\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 31\n# em has a large hamming weight\nct = bbd79dc8eaa9101aa641ce152235ba3d804b48ec5e3dfe69842f125d815d6a56bdb774857c0bc0966aeab1d9c774e921852ff2b84d0a44016382d0e091c3534f0d38f4d5c0ea27744fe320bb0847521ab5474f22d4538562730909fa4496a0c262fdd9b62b422ed4ca9aa30f9cd7cbffe22b3747b0f2eafe1aecbf0f7506016afc9cb3414710fa3f46dd779b21622579b78aa7b580e5960d6c21da81b21b112ee7e2d33f3d67dceee1f07cb3bce8d7bcf8678a07e55498018470a714e00ce9ab796ebcd335240c202c82ac18c4c8c47b2fffba6974322e0e55624a2f0b7e8f3dff1ab4e73bcc65158f6e3d06f7e37535b413a7467979cb5a748b91313e3b7bf7\nlabel = 83f0db4e0dae6949337373a0d78c4b20c15a13cbd4e2adb885c33e0ef4c9764667a8706d059d1d891523d052e0edc1d8b5c959eebc340ce5d41559a89a1aeb5600000000\nmsg = 6b2e7b3152a8eb663899ce78d5c196462d5399720e85cb69fd2714b09842db9dad683ecb27f77938182f14168e76ab7dc039c224ff26c4631344442d81afef7a776101af2d19c45bc7609582eedaa9c1c1a1d364194186b767e6329f7c3daf2ca26348d9f6d2a80b0d018417606cf2256d28b782ace17b8463eb773cfac1\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen145 = 31155; +static const size_t kLen199 = 31155; -static const char *kData145[] = { +static const char *kData199[] = { "# Imported from Wycheproof's rsa_oaep_3072_sha256_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 72ac6bb6d9a5726e454b5430c71125c6e9ad5fd42e1c5a18a8343e9d83d72214386b2308c0b8ec5ec6759dcfcd6a21f88b8ceaf46403923eb86ac3d14a8592e95de0462e14085c3f17db005dc4fac87b4a2d1ede5cf851d5745c8651a4438c0a4d746ad72e419207964728c301bf379a01c094e9693376f721137d3dc76ee47c9790fbd590b7d6a8d626e21b277ef17a4e4f7e0171c1146e1ec324fa97f30d3a1bae08f8d5f6e92cfc121665239c429167359e9650434b29d2015190356adfee12f25b341b08f12b7fec6379598af7d5cc24fe7f00de1d47133ce3ad8b6be1c9a854e33fb952e164ac6dd2a9052186ee144ee7dd986a8f03891d0da21ed78516dcdc2ac89cdddc8b544731d66f9d89bf17a50c6d987a598b02c938dc36521b881ea994e4c8fb2ba8fd001f73335d4dd1bdbe177d3093cf3883657c9ff944e8f5c9cde548b7c1b0741929b0d74977ecda694d940aefd9d2fc75323e0b3a114b99feaf3e2518f5158d1fd9d953aa20af158e67d27e2ce2f18d97fd02f369981979]\n[e = 010001]\n[keysize = 3072]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1203]\n[privateKeyPkcs8 = 308206fb020100300d06092a864886f70d0101010500048206e5308206e10201000282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b120302030100010282018072ac6bb6d9a5726e454b5430c71125c6e9ad5fd42e1c5a18a8343e9d83d72214386b2308c0b8ec5ec6759dcfcd6a21f88b8ceaf46403923eb86ac3d14a8592e95de0462e14085c3f17db005dc4fac87b4a2d1ede5cf851d5745c8651a4438c0a4d746ad72e419207964728c301bf379a01c094e9693376f721137d3dc76ee47c9790fbd590b7d6a8d626e21b277ef17a4e4f7e0171c1146e1ec324fa97f30d3a1bae08f8d5f6e92cfc121665239c429167359e9650434b29d2015190356adfee12f25b341b08f12b7fec6379598af7d5cc24fe7f00de1d47133ce3ad8b6be1c9a854e33fb952e164ac6dd2a9052186ee144ee7dd986a8f03891d0da21ed78516dcdc2ac89cdddc8b544731d66f9d89bf17a50c6d987a598b02c938dc36521b881ea994e4c8fb2ba8fd001f73335d4dd1bdbe177d3093cf3883657c9ff944e8f5c9cde548b7c1b0741929b0d74977ecda694d940aefd9d2fc75323e0b3a114b99feaf3e2518f5158d1fd9d953aa20af158e67d27e2ce2f18d97fd02f3699819790281c100f5eca16e0e83696b0ed9ac8a812545daba55f20a964c4e6343604a7f2be2860fce9fa16a1cc92120939deb88dff68550383ead851fac07ad1b2e8a9b2bb69525d96ceabb7ee83ce50f08d649107f449a14521a6893f3f3c5c5a703b2fc28bfcfe261a4f7f450558080deaeaab651c7a9ae586c1e7f5c52cda93e40aac908e4e3357984fc116af9cbe9539bc7a8d3b351a73ea5c2413d1da2e0b448b454670aca89ffe73b1401e9b8554fc3f23d6c904623251a1d29962ca9b26d973345bc4c5f0281c100cf25446f59cf512919ddbfcfa2d9670495ad92b6f295d61032057f9da6dbefc4510a623c2b47a5220082a3bc42af1a144f98c9ee4fdae41be0ec501ccc94b2b0640191099b355611160deb327e8ace018b898025ef470e4373ec1d97f669e298e1d845c6553c0a546ccb168d5b510dbe6018fd4ed9a3545f9bdb81968f4a6d7c790e5c34729a8efb496086fa1300249ab8b28f38951d7bee1c127ac3c4d0bd596edee1e9d17781dbb8227d7b5d76ce8b8bce03c5d339b9757981610848c55cdd0281c06357a59679d26801514c6940c20eb67b370e84e9f5f0f9316c0437d3cb7c843f5a6e6d9c19e8bdb3152e93f904cfe6e692f1eed27a0ada46f95601b3d122be793dad9bdd05d4f6d469105ecfc11448381dc154ddadf6bc20c649435b483585d68a527b7b967be52e35e0be9a437021c1cfa5f4771567cc233c1ce3ae99eb37daf8bd10156b4bd580a3ce9c7d391bdbb23e67363a947405c6c812cbd3dccc8b356a2dafd0d3b23a21b684b458e4ab3854bcd9be04cdc9d65ceeb10a8531c470ed0281bf04dadabfc15b1a8bdc0f566f876191088a7986f6c2b8c04ba0e0801d31cbf5d2a4139a39cec9df14ecee22e846a7d3f4a5e8eed2a70c7a4c2cf95ce74fe42c4bf60c135a264919bb4cc906ba283d1896f0ae48529b490f0c85ab03068cbfee8fa6bb6ae73b182d25cd66f5205b038b4eeaf1aafe2e1ba5de97c88d40fa1ac47626602fc90ae694734f44f3e4e88d184e8805a755ac2904be8fe9def6b7a62cc9ebcf4d7c2d6c9f9e86b2483e9bf22ce51861bbb4e73e731a4dbeba87772d290281c0214a1f73130e48b336fe01b950885ecdb3443d93e7e8ca62fb0da96bd423759d8be552c8be44f139fbee6ec24b75fbf0744fac4daabf5488fe6c3600d9b8e9a922481fc74a7a3d622662db8c85318de48ee8b716f19429fb594990da705ebdf7ef6613dd6bf885c16ad65e9fe6c280386bee976c25dbaff8fbf69baed9510be5eded3f90e0ba4a97e5c81a2189f114670745ab95edda215bd05fdc78929fa0cfe8b01c83f2aec93e3ad1a334fd85aa8794eacf955ae5dacd45b268741fca195c]\n[sha = SHA-256]\n\n# tcId = 1\nct = 5817f7d276493c294359e776931f0c4922207b6a06b43b5b03e3ec6cea095fa6acb8313b61d4a60e293eb8f99372b9cd210818a54e796bf09c70e21eec280fddd784c56d63091bfca32ea28846219f1e39d262ea475e5ef0e0802e80d36479ab81f6250d3b590de65e870bc9a1e71da1bb32154c9af2d049b539c183c0b5d6225c7ebc81b29cd0ad8caee728c57b8a9aa81e02e0e4e2ae2653d8e9045a2f267b844244eb84f93fc5dd37fd956ac933ae1a65643bd910bfed21dea885581b6717cf9cfff50fac0cd7ab5d13884401f3fb65a280a209e6ead340dab05177724f6ce72109a78c433c936e88d746c244d6ffc9ae76d16cc5a2d55fe1ecece194bc1c1a7d589376b16efe8ab4198997476c3c47ee232107af8fd1285f27bb3b455990649c14ef7ae1e81775042d6905c37a0afdcaeb6ce8c303d8fac88d9515ce50e6df603129aeb112fb3742ed607a6f095b1de291fc9f1d808a9c17c78a314bf0d1317cb4d2498b1ceadf919b4aa0978b929fb1b25e2f310daa3e707a7e3816e2a1\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 9c3c92244619c8e02a3a5c444ed621ca2dff15ca12def6a375b96548ae86a1c27056903fe1ba70d376f8f7949adff43d946430cc6692b03151f4baed3f395c496ce2416d8fd91578c607832c3d02005a88631b741414fcbd517f7d4774a818566e2a8eb15e5737110a3515cd43140083d6c8f8e059a1ee0e30145bb10ae2170c0fb782296d646e50066bc92825f1f3ded41d694c6f0c5dc5b17b1dfc84d6be72ac705b41f82157593996f7b95b6362e7227f1a4b1213e473c1f6eb3014f2c79f255a00b3ff7d9aad362a88eb5aaed14b9a620ffd3abb2301feac7cbeb7728b261ee6e877da45d28e6554f736273879833b0d8f11ff04b44753130bf7e5e340303a20d5c21c5659f48e3c3d1c566eccc2b5c57cc7d215ecb8adc6cbaad1eb2dedce4dfa5cf2888cd307718b9980ea17b6b3c559b955b19534207a2ef5ec1ee270a69e417e5d6bece4a62f594e94ceae0ed182833cb7d58633d24d676d1c009be9f52d655c656ea5bd938f1459d9b8405aeb0317d6d4d14cf2c7de2146696a64bf\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 606657c39ae419347af5117fee8d9b8f28866aa59e0dd7d6c2c07a24db6f500272a7766cd45e809055b4ad8a650647076034035a055e0b492a2ffeac0395ccf0a1f79b8344f6e5fb30ede7a0c75ca443b9e999aab43f902c8f85b1c3295296a599b16d5dbdb8f0b65a541d40c4fdb7a800406b56d3b01466b7097a5ef5140e283bfcd16ab7a9101a71700b490eca0a5f12b465be16e46997d03f119b25c98a3898417a433139043d11149f07e829fb7a274f8b6ad7191060dbf740806326fc62921dce846871c2800f4b3ed6936b63ef829a6509d17dd5ab71093f75afca0b32f2b81b697213a1076757fc7e2d264597bf2670b61c2fa2376f21a32aaac2dfd0ed728bfdf865762e07303c860cef78fbb4a32bbac94320bf3246eb7a9e19db4a219b88c41e86aaac68ee52a9700e734887ca4547cc5b6b2725bcd47cfce7d74eb37e7a67ef1cc2adcdd5137201a43af8c5da372c80946d8aac2bd920283bbc0cf4afe2e20572e8100134a0ce1db5422e8a2f52e0f46be3de9dc134e2a0fae6a8\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 3302b97f67d2cd9fb0298f15a375a21defb6c9b52cdbd78838d4561f0650cbe2563cb5e5ea797ca7703f551980307429bd786c5f5d15090701f1d130366cb0a93219f0396c9bf9c7bf2aceee5053553f147c15d02a0b5f00b597d01acda7a396d4f7c250cf61342a48e1bbd07b3bd3c2d47fa2da326e1c757816e47c", "7cd81de6e0e7ae36c99ae2fcc56bb47570a68f5507468dd40bedf2ab43eabf6fd00fb43a0e711477db4ee323300897cf11e4fbba49836f55197b9673a2433a1756fbcfc2497a4adc620e65428e29a18c80c9a86710d1634b56c296238efae7cc0ff177052ac7b2159d2c21e587752ca16ea50c3a3e50b12709535b7eac02c4f8fbb6a95d8455e472f41765a2eddc24008e74b79baa11c7073168c7b54d3168cb41353bf8011e33d02d4753bfb28c762b7c459912da6d441f4942c64fb5f6e82c351d8942c69299b07ad25b6011a7a280471bb90113bda8e450a1098c6944d048c371351b0f1fbc254f9334a6c7b26f5a1888f0c558727ad05da09539ec9966b5adb1f6dc\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 22609a0bccdaf1e08cef04569a12655f58a9d5a43f83cf9f979e3a358c67a1e444d104a656aaebf8f7627870799435c292ac4655edcdc427a0b618781268a9664fac3a2ea481d3b62b3fcc37f0a473ce47090bc6f3fb2a3d80db8883b99f26c3da4a9e9b1902b2d0dc4643c8d9f47c105f8efa57bf8aaafbc96ab3094d49792d0edd751bf028611c1a5fa38319514bd34fbd19a837cd328f0a77b39e7f56f1c76d1e2ad9594251ad8c7741e958371a5737aa272d0dcb6674ea36440c807e57f95edbb182236bb5af45cf17d8649e33cec6e594b5d0e609fd7fd74c53358f9aa320df99c2fa38f69caa1fc333e4cc5d0bcf8a4c4b6d2ed237748eb1886e5a9f155aac9e86dcf798caecaf3d8e83fcdcf1dad4c2e304e288aa925ed68a3ed672c78fe3477f2f59510ced468965d90c88b1d7eeda4d7a6c5f6cfb418231343d2838d96f6152f9963ecc68684d5e5572cdc3b7cd237c3307b7ab72c810a5832ed907e275fe67b267d022c4dde029aa840bea6870f3ad29524a097f9060cfea3a73fc\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = a79686ec88818d6266f1fb06991ade5719ac10a7b0ecce5694dd76aea13fdcf32d620c290350839782f8083af7e73eb65a41d7a908644c6a28d6b9ffadc9545127eb1827468aa6f39a2f04308099480f79c37282e9d7f0545f6214bce22534cdf131c5bfc148562e45545beacab5568d3ce1615ad3ba0c48a93a3ccc72ec11ed32b770a3d435e5ecaa6f013cace1e04b8167dde67b97dfcf4c6434fc50bc53494d6252b70de6d48370aa80b8efd667993cc559791c0f60dd8e324a578a50507a2b36255c47871659e1c96148b17d9d2dfc453db34277a9ff395b828d627bd80083d44b594257a1b7741bd0b0865cbb0b6073d2b7e2a1158db00a20d652786937ed861e6775b551ff3ea78419ff4287a1d680981962f34d2c57a7ff0b8bfcbfe10e5c1a42e58e624971a53d59e1985b215a48a36ca8b4f2977b713baf9066ac3a98fef9775c97e248c53c3f425552050c29fe1eb05e31132806b7b7660da08ed9833ee43e7fe8f8d50325cfc1f6e54bc34b9b5994548516a980df38b9f61747fb\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 5a4eaf5cc897db7ed7dbd6a57519a06247b0c9c229f7bb1c6c6561858bca7552d56590821e22591218ca5edce82972f58cecd65804e048bbfe48df1934501d4ae5bcb8d50a0a12778540cd5354cbba91875ea70dd0f5057d808528f8c5600ee33c38ea7910f881e45ddd4db2ea933547db764769ca54bab59f3f9559b4d4e2d439462762fad169bf0e04cfc377b3f144924514c32d82e0a53e870ee0855d4ec96393c0eba5fa5fc5debe3d384debd1b61b33509f17da3bd95baeb0c43940924a11124d95d274e67df9e697c2b8133231f2f33aa5d6cc6f41b2962292c97465926bc8569a907c28b54fa6b6d2fd89c409da1b11d23a5f6c53ed82043fdaac6c0e4098daf8a27569d58b87b4597a25134ae45a8e1e6f1871d3310e56eca5894fcaa946e9a5844813e2ef31931dd105a3696bf04e4defef88c5c5a1cbe6bda766804a8e99c82474bdbc2ec344bc2de0575ff90a50d39f6446b99092cde226a81ac82f3688ecdbd527f37cb48490614022e2e961dc1ecbbac819cdcd1ed836a3a344\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 4b5ee510deba57cbbf954949f999d27fc760ad542eb46689672abbc8a9f56b3d2ed8d175a341686671ab4946655b7231fd2ecc8166781329f1f427dd2f937cadcb752bcc459fd51cf6d50721736a18d19387f0beb3b1c07f24bcc162b89803f58ebbebc35485505e834d9f5b69ebdc3428fd64aa70ac45d13765a89594f36498b5092fa8b8f5f0c359c2128af55530746375745966081040842f51894aec7f54a500b4e16525c264f587a3db0c2567fb431cc6d4efeeaf64df4328055c7b5d689f656bbbc221ee003a47ad35dc16655763c90633394ab8b584cfac31f81c90ac72e19dc800f2a5ae2fdbc2f839e56aa60558aba3868f835967d2610ba6214acc3f9d256bea014cbdc8c45a83d37fff6fcd59a7b561782123bcf2d41e15b7e08e7c247053d6114e951b5a50fc6e0b6281aa366f919cc36068fda6f9b228ae866cdd62a108ed151c42fd209bc4088cb6c03767bae21f310c37065fa66f0dffe8f4a8ca90b0d936888fc5e0401072780f54505f20e927be377a709ad13ed6d3fcc0\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 991e95287bb7b68da9337b8d5d615a7d18315a8b2a1023deeffa4f54728a1a0e86f4f70ffc2ec884eea8a7e6438656b96b6f60b5cbe724ccd58c7f94037bd458a24ced5ee99b57fa1df9fe91082dba94121e6bf34c5440e5b286af25ea23aa5295da4a4edd441d8898eea42606aee4f646980c3fa4b99da3cfd1383188fa3e5db7e464360d57ba32f94583f317bdc7c8679b793009f25063a948366be29e04e2a5e4e18384bab0c3c5dd25a9c015c5946b606b8e8934a831c674cc228b9cde32d090bd575ab306c7f88ac0ab610a4e4b81db9b54e9000bae8b8cc411297d7902bf219d3c5137a6c402a7723863bd3347293369db5916ee72250e8f699e0bf2717fc07c9550e875fa125ab902fc8d8df07df501a35e7146676480677587049090739721b9a655bed7737ff664def6cb4eed10466a264a83f3504e8ca057e98e9013837b221970549f40e48fe5c2637c4c5463d7a29371c5283111f1583c3639eaeac24b66aedddfca15404f71309f441196373dc4ab6419b9858131842950ad08\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 9a8b5757e7be4efb98d03e5a6d7e8cae4a3764168bb2e0854b1c95b4c0946318ab46fcafaef9f1859efe369c7bd3ea1bdb7bd3e119425ce9de08f5c2c2c2c036b1e01632d6582f86bba5b0aacb210c99aba26c96f1f3d5897617b5a5865e9999f6375bc8436073d631801a76881a6af0348759be5bbe2efcfc31416cc51ffdcecd0dc40f41247911f0b6b98a580792c68120bc3a662f0268dd84e8e7feee9634b590257020b8d1698510cac27c586a2ec72ea743fb2951ed79ae3e0a801a4a35361a37fcd1f8c4be9e06ee6e70481adad57d9fcf2baeb8820acba99b09549a3c44d78e17849a57c8ce356c823deff5597c8b6098b610f7c323693920fa088ca307ef3fb23b4730508bed46f575c83b2e7ed70ee9bf29c90ab7dd123a359280245dd7930363a0c2ea0ac1eab83225ba1cabaf5f57ba9c0a26a86242b3c09cc71533317dc5f1b4a410a9af00c14af4103ec6eb61ced21f3b115eb40c0b7a4a2d4667451cbd76074671e1c8ac3797ecddb82c55ea1c2309db5c4c9cc6ce6aa59fe3\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 0392ad8b60f892220f5ebd2ac686ba3bc49840dc8e54fcf21f8e8a656ca0c53ed0020c9d512d5aba3f3b8df0ea3c65ac066deeac64111af27d7f7759900280f3cd554ac91016f341bc089ca022bd1d772a1dc99ef9130cdd0bdead74f65d08cb1097c9b5745bf28141cfb6dd17c3587c549e06fe37325a51df08a15c1bf817760f6b4d6c3bf6d49b949e97272de6700e3a82a856ed06cdb3d0eaf6e74d6c9a5e6b2da5bb6b3b162baf291a78e0ce082b58057fe92de538672ae21c19e215e337d4ba7e6b878f269be166e6834d8670fcdbffe7676bca15ea3bdea2ce9286d87ec21d3c538f17c17e41f653257e967c8859bf9cca349d5450af6b48355b49dd58c189816bc4da34f907df6a178768c511e645b8a6069dee23854144693045814471cbcb45e607dbc82a501d97ca7e0c0f641da3f83d69f9561731ce59cf2020002e3ceffe8371422f1318194b862617d78c79f89215733c2aab34c3dd4f1eac7815d88cf18ac9424dfaeeaa3d4262a2e1f4871704e4453d65fb9cdb82700295a7\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = b6633093d61ed6dca2c22a5d7b8e94b34249d45c6b52b8b01473b8e2b7642ef1ea0b468a6ff1299b8b09c52bd3cbc63a157af1f85b78ee2f9ec7ca2ffdb19810dc6af4c5aa062f5ca321ec5ab600eaeab6bb087307ab0f8f0da27b8e0056d5db61852634033671983ae8d3455a468100cb1e5383ff42dca3a40a9cab167c33d118f67a3ffb4fa9eba472d0b0479eee9931383b3e93ebf3cb3500ad790bc9339b1c0bf4fdc1caa43f988e31587031fde728abae75749c2341e1df58bea94a8283537e3c77192f4b280a0021fae6fbdf9c456c9b34a5103e34829a8ad337d8020c77f244db22d05814877a3009e9a1e6f8be764b9d85cdcf129611c636eec65e6a968ca1f1335d320297d9f3c948846a8ef6545abd5badfd309acb083d7c163d712ac922de783b48812669e0d062d56e9e39c411b16fff13d48e0635ffb1ed8b7a43b2431e2d059a6c3b4a73dabb1bc0d09c3937dcc0fdc32b524d6ebc5d23db7d53a33943d8b0c034ac1c5cba115dc4e27eb04a26877806a61886f33ad3032f9e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 3f25923327bf6f3a1302697fda7f9024a1a4f649675fe8d5d09d889649499baebd", "6ba47b49782b04284d7cd00a863e6c10cee1268854bc884bc1061a8d8214f1326f95019026a6dcb6592b9bca412ef144252a66665f137bdb5fa5a39d13de8808afc9dfd8fd7591d180d436bf8d5f0642715b78e39eeb022cbd0d74669a755119984e255b8ea3223bfda0bb53c74c3e074f373a7c819cb0dc1b7835d27b94b240407dd5420e53fa72a4987a565880a83d242b8aa72cc902e89d7a47d9d2d74d3d3e0c4c5e1c798217fd1cb56999034773424f7a1e04547f463eb522d546a71bddf0c27229f82036391edcfaa85b32ebea83b0bc99b63eb5eea1dc614b6aec31ebc824ac6d59ab00538b919e9855e51378a82333817d20afb8128855ddee447c4653efb484524e2ef813c8ba23e3bda9824731553faa3289cbade67528884650f0c9c604129ecdd19668dacb79fcfbc4341f871845317194b0a147c86ec1225d0053209b5d4d2ee2607665c7ab28bbb156908f2f8c1f883264da65bc678669b0\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 1ca152106ad2592fa9a59024cfa7b33ef0fc9b52f1bf824f783c63ac1ef2e7accab17e5097103c4998589449398ae84a2e3368832cf7ed0647ba3d0f6ee5b8d947dad4a160e36fdab3f050371c4b332f0b4e4bc9cd7367ebc86a5fe51a8c925da97a01db87bf9d4a27992d97d2b7562d38a1fb1ba9c58dc5c423883a22190063ad60ff05c3c101485adfd95cd521e077f8b65cdbbfea945a5b212d32d0182bb1af5667adb413739e7c5582bc92845cbc17284f37b723bb8d6a77509376c492d58ed32683553bda2b7ebd24e5f83813f67b12f506e187b2db116e067d49eb1cc5e8dcd51a0da2822d2fbdea212fb631d264f255e0611c09fa43588cf92e1a3980a772560c8530f53de1c6b37cf5bf8325a915a9dea8ff1f580a657e795485d983a998e31fced4e23e92bc0974f58306eb2524cf3c8c3e592b2156e826e1fb88658eb65a947a5b2149941265faecde18bb1a2bdf7f03bb87a522278766016eb9b64dadf50d1f19c5c10632ca1f107d03b421abc217d3a07ddeb3b941eba59d37d5\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 819801441de0c512f558942ffb97c590b1fea96059f83f626fdc0ffbbecd334da7b9acfdb8ce52829cf05f046f57a083de44312d83eb46c93e971909ff553ab9be3c42f23ca15d7b7e14ca08fe874b0db6083700577c69a5e8a3bcf6f7c36240ab92ed3deb516b1aba0533a727eb75969ace40a304e0cf2982d696c4e95e30090b14a55e078426061c5d160f5456d6e6443f730341ddaf0acf4ad0e73b60e4bfe5e2305770dd65728ce2424d79115efd8de9cc2cc79bbe1789331b9a36100e1acd528a6fb25f6f093e4a9d4d187d767370f52c2deeef9448a6c016369e9fbdeb0c85b75d44a9afee56ccf8fdee0785e3e709bb36d125aafbfa9e80e38e01cd6604c5b29351fcfbc3bc31023aeb841f5926a37f728d3d345d48e2545d5412b738050964d374e493b3634758a39a73a29f5fe41185b60fff764008efb9257dcfd84a13ac79754875834d598c9cc4bade1c0927a274fb4bcd43d8d8a6dbf2b6f386022bfc68b79a13ecd608645a4d5dd5489935e221dbb767e760fda20b0c74aec6\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = bd60d3822203c14ba38ab4a83f40cae9dea49fc813a2922110244644eec6cbf63a293b5b7cd907705082c9349cd862f6f417d8d401d9c84c1dd39091c8288212c7b9b6ede28fd84fac25afc707ede9ddf3f7275b75ba946d2c9d75a2e26c712b20f704f3369b6c21d9c2a4ff3d691970055fd4b9d42f53c8040ff307aeab32c957973857843cc7ef2a3a2c86fada1ffedffa21dca1a343abc4f66c5944087096e3e4b6ce3adf9094c62d7dba4c615d7f60b13cbf445210186295fd55929ca296af79208f6f3e95945507e094ea927aa5c24316d8049f960cde93f221a018e42f772b765146f436aaaf003a0a4404b65861b86f299cc1d3b85dfdd19512632e513f282e06ad0c0e063950f1e34d612f8671a67724012597d080211cb310b162370026016db8f3ed378214ea76694c335723348f045b953467d86a13a26abe92194894f32b440bd247d81fbca4b1eb88e6175527f7cf454f7065ae5a0c5360d5f709969deeea42b2de830c2d346192d38589aba7c493e8329077deb6a2ea55f714\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 59ce93a93ff164f56ac01663ac9489ca65b071391a24fa7c70d4434d5a8be4a815ae3c84b6112429f69809f0895a3a35546630a74ba8a9c293900cb9e55e6d7ecae3a5c67471efe91e13246a04ae6b41886b338451f681597574bb3ed36a732655e8c32c819a82fcab17ab919a57a5d0f670c164bb02718017f99b5a6f45b5c0babdcd2b5d5fcf39f763f87fff70dc8cae554d1eb91cd9aed7b54f70e44e2d045602855e1a8b98f48b93da66e60c20084eeffe77a4fb5426b382505f8af60d97b7baa46921127dfd413b44bd26bf6453e10a849341677d809a831a68e24235af3a28481224fd114afc88ea74266671295e0e8d132f83f2a9f534b704418997fd51ae3f8eb0bd1353b1e396cbacd5b028d0323ef115c6c35af47c138f1e2d87ee03e418a9d02b95647e551037f263779322f1e9ed29f66432f3e71b1010b07951e0f155ccc4c3553602ab28551b6887530b7a066baeddb111f90fab9ff18eacd2f48127b1ffda4130f66f15c69593552fd6c8e2c0add716bcd8f4c23caa9341b5\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 5f2eb84a45b5c17a89eb1337b0ca5d7f13314a850e5607e1348b1bf1afad9e278454ac3bd3367c36c8ab22d1b3d8e16c364e0ab79c9ca91383c3ff68b8601faaf797f3721551a5f422594a8e96069ee1b7a698a86898cdd5e1b33d3fd108c74bab7c1e08a17a47d7f2195bdf1644ce12d6c5d4157a03be9019e439da230deea8972e360fcb3ba2b59c6e9fa514a26c00791af0dd5401cb01169a333ecc2216d2e0b603a52cb1fa09fe530324bd3e19f868c8c5b4cec1a07877543ee1b68bcdca734a6cf8f28bd57cf41f306f55fc759c193a6225893b3df93cf909de46a9a0eb80c58f80a74e11e78217489409579ab2a53ac7e0f615bd2e3f875e9abd2fc9046db342415b452ef112b7367c301f3bfe7ed537b5659302dc49fd22a8b0ddd8246fd5259b1f98bc857e4d4bc489db04d41379d82f81ceb2e3ef0a24defbbf027be3ece8af03e4e1b0323dccff2633183397289545988b0524b30ee637bc2fcfacb7cf97e57dcc78fc507d02cfdb4e3e1306888d1adc4d5a7d2c12d12c3e2f0d69\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 4da5ce126030a6df46e78cdf2c25b9e81c394b2ab1eb72128ba36e1ce978738830dea1af9cb743d037c0391feb51e3562a117b5bee96335495fed5e0969f26a25580a549e1299baf27f44253aad62b532524aeae684b0f989a0c5997ad35e66b8f4ec2501869b8c7a4161a126fb2594c728c96b97f0f52d29d1c50bee8db7358d5aed88117d262cc790e912403a332c5585195d815a84c8fef117f16c101fd12f51dba843c2e28b758e05b1fe47d738299a120b179703bb8116c50a9caa38799ab377307ed51c185d0ff54206e8b45215a5670d3a408dfdcfef08de0282d59fc33ac76c733d2e00c3a205b571dbf62c1e330d0948397a6a4f7cfea31ef6a297e7308a56bb48260cfbdc497d30956c976deae81604ecaf9ceacf056fccdc9e5d0c8ca1a0de2e7faa24aa0ddc97ca75d5e19e07a614e404ed0ea318bd04ce8866ab6db1f7ea6e65316582e3f8f23e9d9f258104da3cb9c3e8b2424642fea70b5de0b372e1b1ad15c1c97b67be227788bd1484d624d652a665cfbbac148ac4eb1c4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = c43f9e1991771364c2ae0e3fe7f0c5a30e39e998a7e1b293209a2bdd14dd1cfa14356288bf9f71056a0cf724b8e9242b6ad5f6947437051b9e09afb610b5a785f872f40d0ecf76417c38c2957e92d0ab43f77da2cd548e324ef96d87b78952e490e3d44f32125e62482eecdaf448a7a0a70df5b275b086dae02925d64216b25861017c73ffad338647133784b3629519245e830b11d2a9dc50385167b9cc698fa52ad02c5ed1d876f96cc1e425cd0d1f428c78227db88cdb0a9031dc555130a464d224e23ce8a53f41d3834bd414bf98657bd310e411a464875fb7cb12927cd30d2471171fe843c7f2d34160997dac0b91e9a3204b2d46909beaf50482d17758e088b392b1354e26a3ce8fd30afd35327056c432af2f4d0806b47c57183fe6172f9e2af390b2dd02e63d99a920c676c8e9b053e9544f3f01f75f0fa47646887ebdf8b677cb9855e49fd41587907accfbfc76712627af36d53253c3cf396e8ca0c756deafc025267e602af5648f068441e31b77773a0eb6b0be51b162941372d0\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 953969d3123d65c166431050330fbbb6927723a3315f714b6ed05c26b733b88c5ee3ca8d03515a7f3c7a6db910647b0243084bdcc3606799c7844b59faba014e8715b766dba6ba11cbe86eb7dea482af06558a87e51a9e4bd753bdbd01205bee4d3ba127063c0396477b600e44fb290a22241a4e1ff0091af1e93841ea3cf175b09aff11b81d9decfa5259165f4b7417067fc491fe816c700f3205eecd8b296f0d4047df2744843a1d8ebf774226a74e33b29c6a95750cd532b868713c1df0096bc9daaa57f21a7879d0f007c247c516de49fe3890934b71c2400646a983c688f1ad176891a79a87ec4955ef3e22c089c14e5b014f90de8f2ea1244effbe28fe001d6f80d09d2643f19e3bd09a8723267dee93ccb37ec58e10ae4725bd87b85a6268df03e98c5ab3227ed0009bbd4b9c338cc7089cb66228f626e2e12de47391ce49620c50fef3cdf1bf6bc0c068d81c3c776fa4b69b422b2fd5775535bbbb82c652519266fe45252f7ccb75f820690c91c1fb7430b8086aa10268fe226c9c79\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 5dc333cac75cf3da3e0a3bc580d5305ab08b11b10b8a4ddc4df54a6c08dcd21bea3c83178db7c3a9f1581a6db19972c2924ed07705045f0dc72bf60304e0f9f140986ad024aa4791f6b4e903a3c1f8e33f61268feea185a1b0f7690b80924ea06362ff9821ef7e39447bae69fda7671d11171dbbc6cb60d0e95bada53bd7a81e8a9188b4eb63d573bec3973d286777278fc4a4c7aea62267ea0c268a5498d2e989de4e4472c46a2d5961fd4a9a75d81e23e73770014b01721a09c05b39a1bcc1913a9a", "aa0c1f7e54859a86ed3f1dbcb5e4371658c640961927c2719109a964bea77b037d82a08ce241938ce0ca349590b9a5644c3c8f22b250bbff4aaa5731fec8ec554af2c3ea743effe2b42e30ff4ff181f8e6552c11b87090356b8d7597ba0d97059dfd77c300db534d6f660f6ae9163ea6d24a1543f5dcb691ef1fb9b917b7980660e223524ead8ea1d7b4dc29f1e542122361b4688c93f15434e52b791059650c99d97e09a3cf15e7dccadc95224478ea4c90615d654e51ca9433357835\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1202\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = fa00dcf88d38cfdbd67c16db4fe513720bc05e8649e1766e790ddd0ea86cf0977215d36e4d735c2115227dfd62acf808e3839209114929b6fe36864ec3e1d66024b62763acecfe3adf322168b340d839dbbb5e62d2196868dfd975a7a0eea51610df9a5202b0c7037afc6ba5b68d93bd9446f5a9ff1c27945852bf7c1b1aaaa8a1ff9fe3604fe120be2df2d8f1bef9bc049fb667459c487000c59b6f54bb8edf409521c5f87795f3782645a2c42b5136f281875e4193097edc2a284ee6f8981d637a276dcca9fe5cf990763648845e5cf874d56c57d6c49dd003a929672c8c2dc8cf96844bcc9d284a20f8449f8ea18ef2b6128cc49f6931623bff00e85c1f229ee9a9544ff2751766e5687ecd72ec6226ba5c5284771e57574cd65015940db4d4c88cbc3438d8ae0ae420d3962765bc7cdc92481ffc3e22ef0dc3c4cbefdc147639fc93029d68985e6efe7e9b10a223e3eb7988d2614c6f3c4b84fc84fa6c39667ae2054fed4af3be503ff186d64ca9cef2e9771c011a21074e5c6209cd08df\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 00003302b97f67d2cd9fb0298f15a375a21defb6c9b52cdbd78838d4561f0650cbe2563cb5e5ea797ca7703f551980307429bd786c5f5d15090701f1d130366cb0a93219f0396c9bf9c7bf2aceee5053553f147c15d02a0b5f00b597d01acda7a396d4f7c250cf61342a48e1bbd07b3bd3c2d47fa2da326e1c757816e47c7cd81de6e0e7ae36c99ae2fcc56bb47570a68f5507468dd40bedf2ab43eabf6fd00fb43a0e711477db4ee323300897cf11e4fbba49836f55197b9673a2433a1756fbcfc2497a4adc620e65428e29a18c80c9a86710d1634b56c296238efae7cc0ff177052ac7b2159d2c21e587752ca16ea50c3a3e50b12709535b7eac02c4f8fbb6a95d8455e472f41765a2eddc24008e74b79baa11c7073168c7b54d3168cb41353bf8011e33d02d4753bfb28c762b7c459912da6d441f4942c64fb5f6e82c351d8942c69299b07ad25b6011a7a280471bb90113bda8e450a1098c6944d048c371351b0f1fbc254f9334a6c7b26f5a1888f0c558727ad05da09539ec9966b5adb1f6dc\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 3302b97f67d2cd9fb0298f15a375a21defb6c9b52cdbd78838d4561f0650cbe2563cb5e5ea797ca7703f551980307429bd786c5f5d15090701f1d130366cb0a93219f0396c9bf9c7bf2aceee5053553f147c15d02a0b5f00b597d01acda7a396d4f7c250cf61342a48e1bbd07b3bd3c2d47fa2da326e1c757816e47c7cd81de6e0e7ae36c99ae2fcc56bb47570a68f5507468dd40bedf2ab43eabf6fd00fb43a0e711477db4ee323300897cf11e4fbba49836f55197b9673a2433a1756fbcfc2497a4adc620e65428e29a18c80c9a86710d1634b56c296238efae7cc0ff177052ac7b2159d2c21e587752ca16ea50c3a3e50b12709535b7eac02c4f8fbb6a95d8455e472f41765a2eddc24008e74b79baa11c7073168c7b54d3168cb41353bf8011e33d02d4753bfb28c762b7c459912da6d441f4942c64fb5f6e82c351d8942c69299b07ad25b6011a7a280471bb90113bda8e450a1098c6944d048c371351b0f1fbc254f9334a6c7b26f5a1888f0c558727ad05da09539ec9966b5adb1f6dc0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = 02b97f67d2cd9fb0298f15a375a21defb6c9b52cdbd78838d4561f0650cbe2563cb5e5ea797ca7703f551980307429bd786c5f5d15090701f1d130366cb0a93219f0396c9bf9c7bf2aceee5053553f147c15d02a0b5f00b597d01acda7a396d4f7c250cf61342a48e1bbd07b3bd3c2d47fa2da326e1c757816e47c7cd81de6e0e7ae36c99ae2fcc56bb47570a68f5507468dd40bedf2ab43eabf6fd00fb43a0e711477db4ee323300897cf11e4fbba49836f55197b9673a2433a1756fbcfc2497a4adc620e65428e29a18c80c9a86710d1634b56c296238efae7cc0ff177052ac7b2159d2c21e587752ca16ea50c3a3e50b12709535b7eac02c4f8fbb6a95d8455e472f41765a2eddc24008e74b79baa11c7073168c7b54d3168cb41353bf8011e33d02d4753bfb28c762b7c459912da6d441f4942c64fb5f6e82c351d8942c69299b07ad25b6011a7a280471bb90113bda8e450a1098c6944d048c371351b0f1fbc254f9334a6c7b26f5a1888f0c558727ad05da09539ec9966b5adb1f6dc\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen146 = 39041; +static const size_t kLen200 = 39041; -static const char *kData146[] = { +static const char *kData200[] = { "# Imported from Wycheproof's rsa_oaep_3072_sha256_mgf1sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 72ac6bb6d9a5726e454b5430c71125c6e9ad5fd42e1c5a18a8343e9d83d72214386b2308c0b8ec5ec6759dcfcd6a21f88b8ceaf46403923eb86ac3d14a8592e95de0462e14085c3f17db005dc4fac87b4a2d1ede5cf851d5745c8651a4438c0a4d746ad72e419207964728c301bf379a01c094e9693376f721137d3dc76ee47c9790fbd590b7d6a8d626e21b277ef17a4e4f7e0171c1146e1ec324fa97f30d3a1bae08f8d5f6e92cfc121665239c429167359e9650434b29d2015190356adfee12f25b341b08f12b7fec6379598af7d5cc24fe7f00de1d47133ce3ad8b6be1c9a854e33fb952e164ac6dd2a9052186ee144ee7dd986a8f03891d0da21ed78516dcdc2ac89cdddc8b544731d66f9d89bf17a50c6d987a598b02c938dc36521b881ea994e4c8fb2ba8fd001f73335d4dd1bdbe177d3093cf3883657c9ff944e8f5c9cde548b7c1b0741929b0d74977ecda694d940aefd9d2fc75323e0b3a114b99feaf3e2518f5158d1fd9d953aa20af158e67d27e2ce2f18d97fd02f369981979]\n[e = 010001]\n[keysize = 3072]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1203]\n[privateKeyPkcs8 = 308206fb020100300d06092a864886f70d0101010500048206e5308206e10201000282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b120302030100010282018072ac6bb6d9a5726e454b5430c71125c6e9ad5fd42e1c5a18a8343e9d83d72214386b2308c0b8ec5ec6759dcfcd6a21f88b8ceaf46403923eb86ac3d14a8592e95de0462e14085c3f17db005dc4fac87b4a2d1ede5cf851d5745c8651a4438c0a4d746ad72e419207964728c301bf379a01c094e9693376f721137d3dc76ee47c9790fbd590b7d6a8d626e21b277ef17a4e4f7e0171c1146e1ec324fa97f30d3a1bae08f8d5f6e92cfc121665239c429167359e9650434b29d2015190356adfee12f25b341b08f12b7fec6379598af7d5cc24fe7f00de1d47133ce3ad8b6be1c9a854e33fb952e164ac6dd2a9052186ee144ee7dd986a8f03891d0da21ed78516dcdc2ac89cdddc8b544731d66f9d89bf17a50c6d987a598b02c938dc36521b881ea994e4c8fb2ba8fd001f73335d4dd1bdbe177d3093cf3883657c9ff944e8f5c9cde548b7c1b0741929b0d74977ecda694d940aefd9d2fc75323e0b3a114b99feaf3e2518f5158d1fd9d953aa20af158e67d27e2ce2f18d97fd02f3699819790281c100f5eca16e0e83696b0ed9ac8a812545daba55f20a964c4e6343604a7f2be2860fce9fa16a1cc92120939deb88dff68550383ead851fac07ad1b2e8a9b2bb69525d96ceabb7ee83ce50f08d649107f449a14521a6893f3f3c5c5a703b2fc28bfcfe261a4f7f450558080deaeaab651c7a9ae586c1e7f5c52cda93e40aac908e4e3357984fc116af9cbe9539bc7a8d3b351a73ea5c2413d1da2e0b448b454670aca89ffe73b1401e9b8554fc3f23d6c904623251a1d29962ca9b26d973345bc4c5f0281c100cf25446f59cf512919ddbfcfa2d9670495ad92b6f295d61032057f9da6dbefc4510a623c2b47a5220082a3bc42af1a144f98c9ee4fdae41be0ec501ccc94b2b0640191099b355611160deb327e8ace018b898025ef470e4373ec1d97f669e298e1d845c6553c0a546ccb168d5b510dbe6018fd4ed9a3545f9bdb81968f4a6d7c790e5c34729a8efb496086fa1300249ab8b28f38951d7bee1c127ac3c4d0bd596edee1e9d17781dbb8227d7b5d76ce8b8bce03c5d339b9757981610848c55cdd0281c06357a59679d26801514c6940c20eb67b370e84e9f5f0f9316c0437d3cb7c843f5a6e6d9c19e8bdb3152e93f904cfe6e692f1eed27a0ada46f95601b3d122be793dad9bdd05d4f6d469105ecfc11448381dc154ddadf6bc20c649435b483585d68a527b7b967be52e35e0be9a437021c1cfa5f4771567cc233c1ce3ae99eb37daf8bd10156b4bd580a3ce9c7d391bdbb23e67363a947405c6c812cbd3dccc8b356a2dafd0d3b23a21b684b458e4ab3854bcd9be04cdc9d65ceeb10a8531c470ed0281bf04dadabfc15b1a8bdc0f566f876191088a7986f6c2b8c04ba0e0801d31cbf5d2a4139a39cec9df14ecee22e846a7d3f4a5e8eed2a70c7a4c2cf95ce74fe42c4bf60c135a264919bb4cc906ba283d1896f0ae48529b490f0c85ab03068cbfee8fa6bb6ae73b182d25cd66f5205b038b4eeaf1aafe2e1ba5de97c88d40fa1ac47626602fc90ae694734f44f3e4e88d184e8805a755ac2904be8fe9def6b7a62cc9ebcf4d7c2d6c9f9e86b2483e9bf22ce51861bbb4e73e731a4dbeba87772d290281c0214a1f73130e48b336fe01b950885ecdb3443d93e7e8ca62fb0da96bd423759d8be552c8be44f139fbee6ec24b75fbf0744fac4daabf5488fe6c3600d9b8e9a922481fc74a7a3d622662db8c85318de48ee8b716f19429fb594990da705ebdf7ef6613dd6bf885c16ad65e9fe6c280386bee976c25dbaff8fbf69baed9510be5eded3f90e0ba4a97e5c81a2189f114670745ab95edda215bd05fdc78929fa0cfe8b01c83f2aec93e3ad1a334fd85aa8794eacf955ae5dacd45b268741fca195c]\n[sha = SHA-256]\n\n# tcId = 1\nct = b47525feffb063be5201aaa1d6846f9f397589b988fa26848afb9bbd9d6b0d0c92cec327332f02bd072d53e479726faff5fb89677c4947d60d5f1d7f3bbf211755975e1851f17f0d88eb970bd14719a9e5b257cde71071915774578e0bead5f7ccd7b476732a47e0d54ef214488d733c689238f6cccd6c8be7145e0dee871fcbb504c93e1efd842b228d67fa3e303a1081e26052c6c11ca85355a2de7f717dc432a90092ff9d3d75301e7f092b3b425354939c43f0879768342242836030822c9bbbbe09d5e938fd070aac9f974c35dd46599766ac6f0f87a036a36e3650f7244a336bee4a9ed1280b8adf57d702844c739354eae88ceabd8e66338e59262ecf51b28f4dfe7bea8449383c27580f81ea06bb4bd031826e6f6ddd0c6a3c7eae23d3d6acd5f6388fd9fa70e66c86d178394953ba4e391629a9a588797e25acf8c130859cb7c9504998cce6dd9e032b1a09aba8b215b03b4343a5c0f2a8253b5543d301bd883e941786371bdad14117fa273296b153bca8ce4581df09fee1bd5e15\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 4aae8595883dedea13a1fd656405ae1a94785eb86318e181b747331019087686cb81b259f864c6a524137a316f744c0d092348fe0428e1d9551bd402404342e1df33f7491c381a4f32ae5687bfae07e1c408c3e65720f54c5a168a29df6b7fbc1835fa49ed5a8b42f2acbbdefb3cf58fb6876c2a0a710bdc5c9032018c6b326389b3c32efbd7aefa8dfde0ae7bbd829e6160cef2c8632335006baad32fa7af1fc9fc3ec5ac9c4f7af226e7561cb44338d428d97886d29009989e1d875650c9f3fa8af2a0924f93d00d2cfcaae67e8a89ef34d96afba478a250b7995e7882873bec869541c02ed46b410ab75a214f0ff08ceaed4444080a4ade6baf39aaa9d9ba52487dca33759153345538143d11af5f0ca335a2a3b94e1045da7ff690a4bd454fb788bd7c73b0b16e35ec2766024fd0b7fa44e0ca01fc61e331b1fc8b09f549a946101e2b60c339304a48d044fe231288129d2b70d6b08592288d175183e442b9aa4f5ec6eac0148b6be1f989263d3cf34a7ff265539b8e34c2117b7a1c7616\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 8f71391b8e3a079a51d015e86e0572aca134e5af782000545da1cbbb4cdfaf836542cad19bbc6aca73367dff9cd1e33631260d390b6d83882f82606e28abd2d8aa229ec1d93b4cf16599dfadd2178029360ef5a3bea6a136cd437f59289d334f20e7bae91ecca18b7e4fa5e3613e489ec806a52bc4727333bd7ebd5bcc7568f697d4013d0f6f54caf1baf36791fd21f8ce84643031ffe474901920eb4f592ffa306a979edfd6c287ee5b1fb0005a21d840372c60a649a1702fbc46489211700e8262bb1a2f54fd38da6a07e15850405a277705a66e7088b98bfaee8b2b51992797d5e5712147b756367170b6fde26c3fb5988ee07f916d189a3a18cdc0f3b1affe63538cbc187d4bfdcf5149b4d26bb207a1495d51a2ee1c2415f4a0d6434d50953ff2fe8480d276491ca1468e86c2318e94087e984444b04e7b804cb1f62c66573e82fa6800ac3a42ce0d8e5909f3dfba024a40c51b21b5455836a9244eeba25157e24676e1a317d1af9bf4773913ec3ba6ed1df50d3810eb98bcd290757daa\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 157562f61b512b11b02d1f8299e62f55ffb9c1cb5facb33c75fee79ea8bfb68314d48a7868c05b8c97de4af54e4960868a694a3c302c73195a8acfdc78137231dc960dab44bad191c4bb2b9f8b162a73799ba2083d93c55b425f5857c925f2aea6af19514825fb18724555a5b11ef553889af38c7585c35033d1", "eb9b71e56ec0a1a1185e4e6e5b7aab351404f0d4a4416023449d84f3bebdf57d5666ffaea80be1958be5d7da7ad2c081aa338203516aba1e11642192aa4024e5fed6119aad7456bf13c2dd561c4ac9ac887eeaf4b53bf15e007b043de9abd6619a6fad5df35a336f744d5034af72a6ceecb9305da973c50615c29b98a8d0afa8c54f5cfe80f8efba51b08cf921cf55c69314523619e753f3056ee704a947c24d12e8817d5312ea5f6d8444da4061d26f18ab660f0eb88019506eda480195395e6e948d42e96c3ac8723f5514d87da3bc47432ab60e93efd8e6100589318f1b85d1c4bd04820be2892a8acca1e3633950b111859c6ee2063cc061a44a737ffaa2c158da806864\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 7c741c6f511fb2eeef9ce3dd89269e991cec00f0ceab514a1780c0ea2e06261259652bbc5e46871780d0c03f933d2a3e4a482ad95bf346f7402509a3234617ff36bd50070e2278e77728ebb27eec2b1573c76ec52a25d921b1a6372ee6200dec65575324588203fc3635948e856cd47a857cbfa8d2fbbd046df850ecb1582d7ecf531f4f6f390b725703a58e82947141179811651588d6b13ea9fa09d138d71afac2b24b82c48ebf0e5dfdfc2a700d93d396c8ed4f78846797dff44535b39d176ec2d0124dd61b29d36a314631aa2a7d25015a06c0e30e2dbb011045115d6d705f06b593a22f3f6921806acb1c8a4460cad9104a78ce9c18e940fdaba39a6451a10a54aedc3cf31ad505fa889ccced290dfae89743722527324ef6131b7ff0880d90ebbf803fd798567ba0e07ecaec6c6ab2b3257688d2c374cc3e48137ff81a66c504a8aed98ff76ff057ae39ac67485b17abe4e16d6fb5b64a5d7c3303137ee286cb6ec53a86511cb224eaf47a59045529ed6049e3bdedf619007eefe4094c\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 76efadf7cc972062cddb8c0eb6789d1422632751dbfd514d3e8a4cfaeb17e07d78244aba11bd078fa4fe3da077f1b6b2a6bb161dffc4d96245b6d24acbddb56a2245146699ef629a069d73ea233dc3994f93bdbc208f6f53d4d74e47cc0ac167ca7912c915842d9113e75da6b2492608412e7fc2a577fd3621a1107c1d1c5e74d3a0aac4cfbf389c88474aa37be31d18fcad2f750c1b176f2c1ff544f5d23fd3e1a3c4507e62d5a2c2e0fb1bb426f860f84c4de0a2ac63f90e3a6e266504389e96b37a16ac03fff70f3bc4488b3ef783bea505911512b7d04abee4ce52b0100727e563f8416e9c6f889e5436b27388cd6d7c4e2ffda6896688f8ce15167e8baff14ce9ab95caee52a5fdc51515fca66b646af8aee83e0aed730bbf2af2a966f330818dc33d4662e4dffd50025cbf77efe6ffb3c6cfa24420f55a418d08b675dd85f7aba3da35cbadd290482af1e7a0c2b7034a41bc28a5e3dc2c47e78fb46ef14dc4674c65f5cacd17e4f542a9b98ec268bc977eb97045f50c714ad7a49c0e84\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 0351794ac968e26863bfa67aa4d602c725b79ca9a4cd907a9e03c7575b975bfd99fa491b5bc3f93e1eac5b48d95090e10a29d9e4edce709c74886ee2d5067bcabab044e239cb4c23e1ffa8a8666fbdc706ecf49225697fb6f1a095e20dcca49090548d9fd0b8533b090823a76ce6c8c8a139a20b3e930a8d2ef8d868fd92c086c06a86c172e40e76f9920a6de6ab2fbff2cbe029b685dbc20da94e84442050b0128200446bf227eca935e1bfa8c89ec3454ea3a82cc792a2512d8513f2ddaf172e35e735ad69a5f892ad0c216e84ea9e92129d8272db269173cbc525e61fdfa5533e2e69a4670ed95f4958c684476c208002667fc7f687260eb54d9cea88bbfeb7b6d7aa640cf0ad0af22ecae17034c762bf832a9e8ef090926c5ad4fe6a15b6e5ef69da001bb7fbc608bc024bcf38e157dbb57974169bdf302ec177e48d15a1d0c919d9b8862cd91d454a96df1c720561928e282b9e922d0d8218d65b74bb740cb7cf7455e97a5e6bba07424382c31c37549d7f29bf7e2e23093ee861dce0ef\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 7a9f4a75375002889bb9c4cafe5f044e2f28997474465251246788e51b0cd5c52c809a69f1ccef4c11723af030fb698a641b98b88b39c152e741b8ee29b13857ec144f200c669010a657441701e929ed7df195669197f46909acc69388128bb75645f270f20df256f0d0c0ed488efcf26c44e4d4e54a8757f6c5bc7008c68b7fec43778743a76a890d383e2983a754095224c56862b4b62e20f112d1bd96f30a3e66a20b01069c0ed9730f9f7de6cb13e2272640ca5cf807e64f44297e3e58ee9331e1f04610694a0d5be7006f96747cf730ff3fc4bf8884b3f9f0cba9c4a8f38a01b225b083d77516d46ade258242b0ea4f367bcdff490e2f127f013808cfeed451aa7c0f64b3156fc968507ec7c80572693d154b924fe18dfea946d52da81a5ad0bfb5fac7010ed5b4f18a0bd1ef400a2804b9ca2b2dd0bb8b8b402952949bba935b674c4863ea4a9e38dd701d23c71e29b4a7c695856db5978b7e3c964ad8fd4decb1cb5eb3f83e8ef0be4e5fefd27f8604b1d6fa06dd4f97110317bb19d9\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 1f1ef3e2956c31f6b98fb4141a42fb2b1a14331b5591f40b5f34fb3cff536753eed85f9c54f24c76b29cf7010875b17e2bdadddffe230d411c87718a5f0cdbe6c120ade66b2171949bcf7df65e6c687249c0dedcd358c38aa1b61867e2435c478f46be8853906cc08741a1c092c2fc577a0b8a32c818434575b54bd58e17fcd1a6f910b185df53449fa88a777f1f795a89eee2586c1cacd4d1277333ca2ebbe0430190289665c3efea05871227670fd07250652a1dd2afa6ed9c295ebc68b15a254725dd6006d28aec6b1acdafba69247790ceacedf5eff437d569a71e5564d6ec6c90d295e225fbf525e76b2e466985482927345737eabfa34046ef618494af1c847b1d819f2f99b15c13b8e817d437db38a574f66da845f54895710f1b685cbdd83fbff9835a26de074c5b1712d98d4e036c9720d921739b8f3dc320f1d266ae5b367b92f5e33ae28a7a06f727f2df5437e55c325cb233c801ddf6b12240ccd0b8db8c31a5ca652cd0e33bc1087f4bbd70a0142617903956443f4ccea5cd93\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 85186e5bd121796c604ceeaebe2f12fe87f41f502c2622f0ac8599428f556f7ddba82355e65dde44fe1691b7901fcf6ed83fb837c1f7ca549b2565da1a249dc717c245a9c6362c8e831ee4156dfdec6d9e19ee500243edf4419d152c643360e35935d88a0364b28038cbab30d23f6571053be99e0e405538c54a71c4483caa328a8a49b1e9a5ab0172d429b5635fa7cc11f5703bb95536d218bdb4ed555a2b1b71c717bd65e3607dfd7e7cfc1fa7f42e72a5daae3e6bd694a4a6194bce970cf102bafc5573b8de18544080db3e89a753b9245ed9cf7a17282017c8276bfbe737bf0d802a7d2e9a9fb5f373f9760708211f9b7a99d3dce0becfa77c96b1f5fe1c4ae8cb2b4f7c741e90e4bd2fd1b93648252e4576b5670d51e86068497ddf162a80dbc2a16b73e16e3661f31a8f2fdbb66764a70a1cec5e0e247e38f3fe95949a5742b1987280ba9d4afe69cd00fe10feee87b9d0b40a2e94fc042a4a51474d7e162a1e7261b2791f8af2af6978bb87ea1059553af71777fd04fb92c4fecab972\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 6aa169ad089b2cd0c5c0d0742e452c4f1bfe9aa04f4df93eeb38ad6de8cc93da66af9ba589352446b8c3a5797cb0fb8b0b6d6b6fca1f9ae4d508951bf0b526a9433a9b26b5cee4aa943f0d2c0d94c479ef8f99e2bb680aa4bddef38ef607ce2770f4d60629ebfabdd9fc20c6b88c8a02179dce5e9ad9beb90cf75baf5980edbd5b92794bdf9bc58dcc44a13b181179e92fa394152506845188b80aedc2fe559a3bbc289b933fa2cddefe080817f6fb3f1e8f585389ebbef06c3376caa975c07efe683a32e64917566645330dca75480e7ad2eae5b4505b6ad5233e7cf4c3d8677e0350b8e1db4cbfd73344e14f458f49849cd991d3b4fd19061bf25784e17b04230b9a1db1637a7b8c0f4e3bfe00952201c039483551931f84980bf8a633a1bbf4b609ad64ac6d26514c869c1d7b915b223356fbb07fad300cc9a8e6c768927a857c7e9a58b0d784a04e24082a393e65f098ff211dcde8a5155550c18bb22d64d324224d77e150bf424262f17827f13920ec7df259ccfba158766b0b52bf25b9\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 5e6a85d2e4ebae323cdf919e12ac8e5028e0bd12501c5c81f2a30daa39a0ce15ed25e705c59edab7e53895e9a4b60b0a0c75f11d984a5cdc45d8f300398868c76c973e5d47f50831cbe994c5c76633574bde9f274bde95f5f4c7a05c7c74f59718e152c182b4dc9f86ec3a677d824ac63d33aa5dfd7d695bc409a3f22d84b4d75effa7c80b64647b1344e948087aecbbfbc607b667611fd7c3f847ce223d0ce6ee131f75eee01cad17131b5de821fa7d6b458cf989e3005ecf6fcd1f6cd022162c2963e05893912cdfa9b06634ae0e040a73284414a9a6d8f8ac2e23b51ddcb108586216bcee3f07c7b1abc84c41b98cede33d5c4ab8f8259aa0c52a4b6cbb754aa21c2b2ebe83962039651c9159ec65da43458f6ff397d9503d41ee102d0456ec58b1b8e28febdba82dc92e5e6941a097c8e406559f8410974fafbb77a9f72b0566bde813306b1a7df7603f731e8982f1730b95f9e541b29eed40fa85978044067650c55ead01240e58c456d9416145b0124170f10675e22d32920e91c11784\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 61a595dcd055dedd65419ed49aa559d1bab787f1d38ff2b2ca65baae8439bf", "2a6afa3cd590f450b42962d84919d29f3d9c11a2586be563163b0a16a4f182029568939068003b3cfabe21ff2c6b7864fc2f6dfbe31bcfd32a1cbf3f0333477401f2d469b6ba8a7509d7e832df96bc0dd71e3c0d2979ec479609db9c19d8cbc99682d5ba09a8dab54c1ef4f3257919c3912aee52376bf3dc4ba4de5d9362b6c197779308ecde992bfcdc6ac658aeb01d5112fe592ca8665641d1e09dfef06ceba48ce18cf6b8ca0edb966246f04705574bc72c163ff7b28c149376bf6302acd2dc687667a9df54b4796941ec1aa9ee96e484e34429ee3a48e8a8a0a912569490190656207dd2a933ce212e229314fd51ba3fe505db2d10a0d29b5f54af042b4aaaaf3b548f38837b95d61739a895fdab837efe422db7fc71ae4652ba5319ba383fc459c7d0115c32b1c99df909cc3722e549e3119e0b47061eb96e714522b8b64cd5841967d43cc5f700a197ef0ad5c7c2e064fee98c461690b0fade7ff42e3f11\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 5c7b1e592ecfb9b230ab893e72c80dd0f762e62227686a1978cfabb3b961c490ee18a68174ef713f4dacddfc392fa0862e55e48cd084199f702507cb1ff8352ad67fa9c128a5d2738382973a65a6302b169a94d977b242ae57edf951c3ec1a368ed5a580ce6755709e722f5a8bc0c6844c53e8f72748f5123ad8773485eaa9a52446bafeb59193b1a95fbe6a8fe876abe6d26c161d8d3b56d5f47cd3b9912e9e3d283ff8d459f99348fd5d81a20bcb4792717b48af6a455333b99aa6b34e9e2f8252be8d51256a30af1209d7c33b55238c72b92fb08f216eb598a99fdc4d660307770a19045fc5e21e2b6e67df5cb3e8a2aa7b7997cf0eeb5324e86a952704beda65502e29b423222bc68184e4e18e3bd1efc4cd0d371eee26f2472184edf302701c0dc869cfd10937ec9d720f0b09c9e663d4e528ed257bf03a6bb7edacf03ea5796c5fccfe6f99cf8ad9b487db1bb228130afbb468d289230366e3890ae1b9561ee44d8fe019eff7ab5a6b2179e142616f9e2dc0c753e570185264253f180c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 2595c4281b17918f228519968ca6882fd7abc6de23a3beb223391548f6c856e99d497778dfdd24f4a91a63564e0e059056977ec4f621994ed67135ae72392e35a3b80b21ef4ce5ef01cb72faf38159b78a7e395eef3525872d6fcb7b97124be06ebd9c78110227ba0108e5d681d9415801b70384822cc24f0cae597da0f161077940fdfee3978a420907b0fd66dd64a8f4231cd963a1a36331dba563922675280457ad17d8a9a051f0852f2d0a69044fd501f1e29c4fdf9ad5957e249ef72963d678ebca418f08a73b8c16ce683b146ee731da35a48057ce41b309ef6ed90865e59e3477e23d7bbc8e5da47ca9c890772f7a5523ef181af764a4d05781db1e8a856b09478acd29c273f3bb7b52a7926bfcf43326a6bea8678151ee6235cf8e94696e174552ba644867824d9bdbaffdfe6e82ae8dce01674ac44d636f6ce97e926f1da2fb4bc941fea2592cbcae57769cfebc519c77c1fa9559f3c13fea9a3fc985ccdd02aef5d977b7aee39ee424c8cf4e0f522d5f50e9981e3b58f33713bca6\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 2db9c10038f4912d0d2011c0a684a3b918eda30b238660865c3047285390cbf019eb7bb0eb17c1c94f956eae46ec8f6f86b4a800ad7dbbeba616e392ddc7e5cc1bdac3433b57e73b48a27e62c59de1da90a8960f3d7010792af056407060ac39d6c200c89e9e0f10668962bcd13506b58b0447424c0e50b27b3a5e501dd35470681dd6f88a05903f4a9f42e9e4440a998a9ec6c575b0472452fc2f7816fedfbe7b9335cb3d9dc84bf54ed5e8bc89a69aba9ce9507e388fa8ff2ff2af86c6ef6f385c7ca2a18714a3652721c00768d8024207d8ef89b4cbe181e645ae1fc906620a7a9890ccedf3b70a08bd90c4acd3b2213e75ad7a6725eadcb6b7a57bdb5cad2ad599991800ab4f7e8e875a2c722bacb09346853dfcb293f213e4d5612458441fb923615b5bd9ca7b38a1bf2578657858ccf0ab002de62f04c195f3588db29c6ecd74815a48c0d7ba9808750dc2569621878f5cdab99c8ae361fceb0f0440ee4c896cddf709dbe0b3d3a6a643cf98b31e40296174ebe7f9fc25805bd6fe8328\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 5552caabf0e33c74402cb8d9cc43fbee119055f8e5a9169d8fa3eb5bd2fdf2f9fb72a9d190ba067eb625da0415b9e2127a85aefd9ff61dfdc42a6d252101aaaa3c11703115298c8893737ab8123c675a65f7db661273b936ffd0f3a5cf5dad3d732b749c83705a90d03e1eb1845c4a37fefa7d1c10da277de8437d44d9c448ab38433985a1b9a24697bbae2dfa875cb033e57527fedb17dca5102683c907b82a4aad66345da3031167fcf6a333a9bc4006934409c7141c70ba0bc3915b2a5579a351a8a6d7613fffeb014fecc6dc9937b1311970e71f45968c890521fdc2167b80155619b575019b563601d8fd6c14c261f64b9d5056ab189a9730dc157f69ac75ffcb8cf2fafa06db43ec91f583ec085c6dda8b0dbd48df33e2aa84eb5bbd77b39334d3dae4dc4b63da5132d69c0879639db22f84b29fe9e03b0102c95c339bf85cecbc564091d9168d93e92f1930617687adf56988cb89b69c367632cca798372b89002bec586e92609c021273a1cc4bd596342d6fd7fcf4911b3ccafee359\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 11e958a24a754abf620bfb2c265c568e41ed4e601bd64e1918a4759a84d6cada1c3b704c9b5c24a3be37aeba85e539b33c05ebc685e81be333d599f3fbea364eb63cabf71b57d9cb38ee4bf01ecfe7a0df7f79d390981a7d56ae6be07c5789e42ce50a9bb84e388301e007ff823f95b677d8cc0c0ba7d320f94032369eabd8500acbfbf2040dd68cf6ad2abce9ad3f8e54033c81e3e2e9ed966b56554d4f0a8134e3fd18facd3dd4e0d3e5fe7be2e1121e926f6f7ce9727475c0478a73bd2256d5d0d90c4ea144b5ed91e3984febb2469a858020294c7c561ae2ead0a05f422fa01e7d91f9ddb1e50a4bd6619f841349f5c998554f023b19abb2c5e77cb0bb14c2630158e37b83ffc5a7653d97a42c7d670feb8d19ad2a3a5be3a3911024fc7d797c3f27b84923e6837eb6a24ef4c9a95f437a17d0faee59dc181771cdfc6c989f7cf9004a353e4ba84fdef74871024ebe667e4cff2959830cea4f2ccfe9a83f58388e56090ff9ba7278759508b65d39c4d4e977f0d0ec1280b7317e42b8f05a\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 7a6ffb72a3d0219ad9e99ec707c39c37d4aa072c47553c307270b9901c1587669de22819c1116d67f4689fef5453007800c29eeae66a1ba58ef4d08a77f2fc7fe9d6bb3f4105adace30eacd883ff86c0c64c422b9101a997a1497ff145d63f7f129a11237d7189361af0da522ec7ea7ddda2732bee2f2870a590c362063ddd5c4ee4476272abe76ff2c761fa7818d951abd8841d516c816b0c7ba93967f95401359db08c8d5aa4edbf5d535ea42c1ebe316de34ba0e392683ca5c5e6767c186a1e0ba04b7ed39ecccf96ddcec921c192c5545881ab2a84c326304e2ed70d29315746cb8b31bb7d036023684f6fa2cf33d558d194389029329da0802c377675a0f3ea28e497c712c5cb0b754af92060ae722563facc3a40794489765d23c9925302c8c5bb9ab8ef5c05c8a9d8a0907858f51e276671a9c96484165b2463e8bba99b3ab7ba5bf88a787800682b98d204f78dc0e137e1aca622d8a2e2f268e2a23309ba8085536cd0630b561211d6c844ea29224e7cd8f598df9bd91a961ee33544\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 4f2f2db05cb302c4fb4b2eb83bd00e6fe362d4b7fae313de90374190931919727876280139e8d52efceb10003b9b367e13195d83354a30df2e3a06a743671df8761f25620790d1ab32c6ea65b74317e4cedebb725e8558d89ff6d70da36663cb34d8b0183caf9a6766b8436d2d9b0e7bb92c40483cd7cd30a681940699c8d167a4b1a0b2ba2670afeae543d34c60cd758ad7a53b8053be8bcfa471635389503b1146d051e978cd4befec148417f3b4b3cfed96ed78048452bfe88ba9b7ac4cc09ea8be3fbcfef9a818235c98a43e160f25427a5636994066ec1ac19be9fad308eb71015f417c15330083d6726977714841383bab6f44f94ef2b7313f513d3589d67d96f1b4d0887f79e414e77b77c39d5764bd7e5156193821fb80d11f7a0847d68d62e1e092d09fa4f2bb1bb65bcf407ee2d9352b3a84dffa4ec241a850466864a38518e2d5f3b51627dce6e6cf666f5f80b476ed84f96b023a63cd92229feeabdb855de9ad90cbe085190f20e6039b01a41b36f111e8faa8e0ac4578cb4fbc\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 1afed89bb5df115fb1cf52de68fd4b1c895c86a6852a06002519a69c6a983e54d19351f930c227b46a6f3481b09a121bb19aeba02f2abca4b0c5aef15861f0f1d25ee3f6c0cf56eb6b3d10ec5b7640ef409d9897b32c3d3e98da2ac0089968c352838d0bc6a594786ab813c212cb72a1238014d421642839c3634ab14f61d0c775f03d875490354dd902b23752fa3bd39cda588aaedaf31b69d29895cca2bac9db554708224b753eb36c7bf11031fe9ad0462f5054750e7b5616cdfff13467b20025a71bcf4c5e6b31dea741ce589c1cfbf76cd858ee480a69dac7a306308c5d3ec8108a7efb2fae18504e72e263c0a1366103abb70cb1f7a7f01074bdca763c17d7edcbf8d64c9b0a74ef11855abbc4188451183904ef1e9647e512b302ef263123b0e4af885187d8e1eb2f6a1c65daf7b2779be15337c3386a284801cc40358c19a4d9e487896c0bbfc1e56913247e97876487d875d6bd487553552b4faf8eb4b17ddfb55a87f46b202bda0e64e480ef03e057b410b5823216f87e4709bd64\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 3dc25636b9915a15c0b5bc467c0f3834e40ea9df315ad7e60a0f515408382a40f900e8ca2279cc2de6c94500db484692f92a0a62ad1a91be01e55e82ede69c5c188bd624cade6a359524023b3654c4dc6fa2e95a5062a1f4ea04f26343280871eca16ad398ab356784775159cb6d94f45838ec75c810de14ffaddfcc76d5cda931f6bb0285f812d5bdc15c77af50ae6b10438019e0207a4e8f95982651de5b251702f3778f4c92da002250cbf9e9f6cf57b8736b3b5596e6afc06076460e948f87", "b64b008545a1a8f71f6918b4d944b6c9a777a1119eb1ff63cace54492b7fc7c57e55d7306d06df5056275fd1c61845cc2981cdf71a8f6ac8bf58036845a6100b3db63d6453b22f44e9dbd85a417e10a8c033cea38f7f3d1f0fae1af30f609d97d8379542dd1a3ad593c2dd00b79badcc9824f2a0946991b01382b205050f68926efef723a10acec37788969ed56ad9c2113a4167b69defe05f02ca56bf93fccf8278dcf160b8e01bdcb4460013bae15219e16c64464cb15e2b94e32c909cb8\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1202\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = dc73866f40b72d4dd67fa7484655a0aa1bc3569c7cb25222b6386e8e4adbdb3830ada800cbba3b063cc173d930c5e465b0746fe5e46093c956cf84fb058897e8cf3244d5850bd604e4c27e19ee03ad6e40daea9ae5a1cec36ca0fde49c6cf42de296f1527b758df1a460057aec70b54e4862465c4233ce6f140dc69b1027fb8262b90a0ae523599ea3f7526871ed0ea85d7c6d30bea21482b2583266845a82b113b99933f5032da3089f58073449a6e7631c296d49aa1d4b5ecced0da19775cf70bef05447f1b56535135d28b2af6b31d901729c05521826176a5bcd04990882d17758bbfed52ab5697ab85c61473ec8796b772856e4b68365e1ff5749a3f6be0a4e1691e8d43143cecfd79291344eadd09b9aba3a12ffe9cc68806d55dc24cfbe09c6704bcbc5502ac6c3537ff0db6222889e97b101796872754a2d24153c3dea6fd521dcdfe5b5f083a3417eaaf7b6c006b6b487497471ee8c86787e8db92a39e4506accfbf9b02fee81a8f3e9cac67cbd2f0862aaf8671557b705369b7a67\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 0000157562f61b512b11b02d1f8299e62f55ffb9c1cb5facb33c75fee79ea8bfb68314d48a7868c05b8c97de4af54e4960868a694a3c302c73195a8acfdc78137231dc960dab44bad191c4bb2b9f8b162a73799ba2083d93c55b425f5857c925f2aea6af19514825fb18724555a5b11ef553889af38c7585c35033d1eb9b71e56ec0a1a1185e4e6e5b7aab351404f0d4a4416023449d84f3bebdf57d5666ffaea80be1958be5d7da7ad2c081aa338203516aba1e11642192aa4024e5fed6119aad7456bf13c2dd561c4ac9ac887eeaf4b53bf15e007b043de9abd6619a6fad5df35a336f744d5034af72a6ceecb9305da973c50615c29b98a8d0afa8c54f5cfe80f8efba51b08cf921cf55c69314523619e753f3056ee704a947c24d12e8817d5312ea5f6d8444da4061d26f18ab660f0eb88019506eda480195395e6e948d42e96c3ac8723f5514d87da3bc47432ab60e93efd8e6100589318f1b85d1c4bd04820be2892a8acca1e3633950b111859c6ee2063cc061a44a737ffaa2c158da806864\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 157562f61b512b11b02d1f8299e62f55ffb9c1cb5facb33c75fee79ea8bfb68314d48a7868c05b8c97de4af54e4960868a694a3c302c73195a8acfdc78137231dc960dab44bad191c4bb2b9f8b162a73799ba2083d93c55b425f5857c925f2aea6af19514825fb18724555a5b11ef553889af38c7585c35033d1eb9b71e56ec0a1a1185e4e6e5b7aab351404f0d4a4416023449d84f3bebdf57d5666ffaea80be1958be5d7da7ad2c081aa338203516aba1e11642192aa4024e5fed6119aad7456bf13c2dd561c4ac9ac887eeaf4b53bf15e007b043de9abd6619a6fad5df35a336f744d5034af72a6ceecb9305da973c50615c29b98a8d0afa8c54f5cfe80f8efba51b08cf921cf55c69314523619e753f3056ee704a947c24d12e8817d5312ea5f6d8444da4061d26f18ab660f0eb88019506eda480195395e6e948d42e96c3ac8723f5514d87da3bc47432ab60e93efd8e6100589318f1b85d1c4bd04820be2892a8acca1e3633950b111859c6ee2063cc061a44a737ffaa2c158da8068640000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = 7562f61b512b11b02d1f8299e62f55ffb9c1cb5facb33c75fee79ea8bfb68314d48a7868c05b8c97de4af54e4960868a694a3c302c73195a8acfdc78137231dc960dab44bad191c4bb2b9f8b162a73799ba2083d93c55b425f5857c925f2aea6af19514825fb18724555a5b11ef553889af38c7585c35033d1eb9b71e56ec0a1a1185e4e6e5b7aab351404f0d4a4416023449d84f3bebdf57d5666ffaea80be1958be5d7da7ad2c081aa338203516aba1e11642192aa4024e5fed6119aad7456bf13c2dd561c4ac9ac887eeaf4b53bf15e007b043de9abd6619a6fad5df35a336f744d5034af72a6ceecb9305da973c50615c29b98a8d0afa8c54f5cfe80f8efba51b08cf921cf55c69314523619e753f3056ee704a947c24d12e8817d5312ea5f6d8444da4061d26f18ab660f0eb88019506eda480195395e6e948d42e96c3ac8723f5514d87da3bc47432ab60e93efd8e6100589318f1b85d1c4bd04820be2892a8acca1e3633950b111859c6ee2063cc061a44a737ffaa2c158da806864\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 31\n# em represents a small integer\nct = 8390361b70122cf45d2cdd8c575a7e81a81ef3cc4b54f591ecb3d817212701a0b53df39301b88b041a317e6c01d58085a7a52a7f5e6c18975918b5a9b6166baa57ec8be83cc19f8c40c087d2d7128f9f45643be5e1fcdeb7d733bf3bd1b6e850b676f32cc804534e29b2c1f1fd50eb94d3ca585d584f854e2dbad003aba313c12aa86105a9e53ba2da03e8df687f3f1932554175756a48f2f13f3fa63e255bd0f86b2e9d3bf680017ffda3b94ac1ae12dbb5b7e03e0f022f53ce1fe8e6708ad61b30bb9513b76224b9ee689c69636224e613aec7dd6386fb8fc7772e336ce101360764dfb8f762b86719976571e560521ca776efa90282705129e3d30cb0f4f04ccb3bdfd1dacce9813d1a589da6ac9a39099495853e346f5733b830a72a1dec9f74214b5ff93f7a8e68874fe90f7c7e02dfa2afb96dfe5018fb6d6c3a4705be77f901282ae50d911e381213495f44fff40a823e618ae7d248039b6ec7e13c78819c3222a2fef30fc389ea017f4e98f0783722ef626ad4c876af3a45f5f8fd2f\nlabel = 904f95a1a204aee8987400c5d30ca79d72fbe988321fcf55dfcd0f07e763a9d400000000\nmsg = 119f6f2b7ee1c7fe0d5c2eb8d68566d8cfcfa3e9bcb1351737f23ae3472fe909dac0d4cd2b34ca643e3eda5343b07d47138a25489169897ba8772a74cbdcbca5dc4c7ffb707d57e86db83dbea8bff77172aafd113d5445618e36f7b9e50a1e9e0eb1f0809528323b45195b16666f5c22e8365945918e81e29aec72811adfe006c45e968e96c605e247163ea93dd434017b482b88187e06d021b1fdf4c985142f471e08d8a2398d54a6ddc6ceca63c430d3f67e825e61cd841b9a5d157b265ec2e5b789ba4b3844bb4ca168ec70fc2afafd9dac34d967400e982ab175d0d82a5007905a83115a181d4ee569c223bb9c2f9e1499f2798658aa8ee0488046b6915db383b001dc693da904cc4e330a9937914a8e0c2309b07be783d0e56a045a195b124f54016ba1c3ae760c2606a90f32760e303343c1b0729da9d1ed18fb16\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em represents a s", "mall integer\nct = a5adc9089becdf7dfdc75a59cda6125b66cd9680c5689e6266887a4a73880b492e9fa277f1839994438962e946cac0da338b98a8affce9765feaf004bbce10a3c85faaf2a0a1daf931d273590c896dc847ecab8b923005e89613784536ff40fd58e193d1a4a179383e4fde0b914b1537bbffb23f311f7abf9c0de7ebf412451b7e8683389bf9f80bf6f3f564ed44682d5712d434f5a8623ea6918af69748b5d5d26d2c1b89dc6ec5262cfc327ab7f3cc1524c36991e28bddc59adcdcc69fcbf32d19db045753ed85ea0700afe3915bd95467456c967a1b1bed39d7b3cda9f103794eb26479894a83066ecb00e23ba424897132407b50f3d25fb2e9649f1afe244c5d4fabcbb53c2d214febc978a3495e0cce53fc9fb61aed4f7f6e42152a6cce5ff9d5984e4de9c7b757c6f9ef5edd7f5a20450bfef586996b009cd07f8377b240ae859b1e4518413d9a79b6111000ecd1312157f4ad3a35a0386eb1f9bd15193ad9e00cb0d63bbc5e279add877eeda0ad66ce845d8acbf33f69b5d8b16ba8f0\nlabel = aa66934039f2adcbc6de2b9cc1b00b11bf33a72ca8dbae5e7a8af45446ec682900000000\nmsg = 2a0e8d66a82662bc1db11a99703df46431f00f815f55520c16be0efcc67e8757ffd4596e232ea9a09a9c96c66b73ccc94da587d0eba7bbd35834c6ba2803a21b5e9a70aa8c37e391f6bed5ffa250276c19719dfc01d8f693d5760ad1af4eed07387a5e6cbdc69584f6058c04bbf0f3f32ebbeccc2d2bd395e4debc53f44a7eb184111fe6ca944865c9978f969712e1f777c3c2fd4286b705e40d56f7b424c315fb5b181bfb14b53dff5687e9c122fee7b3569444f76dd158cf3925b6a3640f5e573c0e5b420287396d85db8b3eb4e42336eeb55bb04e0972d6fa2172391bd954069c8aefce760813961d360f1a34d052e90f9b2b8f71e8c63b7a1fd2add9b04046148d2d8308f8517ed8010f8b23a56982a77ac8cc7f68da4c8e3617933bcad802044e176612450f2c2f5e399275e3877102deb58418e2b51dd2cb0da857\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em represents a small integer\nct = 8da7f29a7b3fefb253514a166eae3b4a8cf5a1eb746e9c6e3c0bb84c81047546a77815a6d527c3ec81c23761be29ce1e44df62dd3e6f5f04b91541d6f4b3591d9b8d9d701d92c6080842305e73c7be4ce52f3462c3676aba2b88d70cb82cb28a9052f0315449a7dfce72089e5a2508d99c54346bd2289a54517136239152bddec1181dd09406f5bc2b1fd9f637d3fdd8b2efee4136b1e8b8ac2aa5883343f56d74280a0458258a7fd7ffc3277c79adbbd96a928664853c2b3964b139071dcd56ad6bb3cb4921a3fbb2b90aacfd932b5d5c5521088dc02a453c719a22a0cf7e925264e8d3252d4c05f326f9bff175937ff2c3b5f3ba29d18a37e9d962274a99bbb5afb7431f68f50771d099288f3c4fff9b07dfa656bd8bd1d309ffcb8f1541e747ce920ca2d6b7582aa81838b379f4dc4ee23ea768e16d42784f97f0f670cb1424195ad8bb382faea3e5017ed8643065d6bbaf54999b08734097e7e34b3203d2c7ddc42073e15ed178e7893198028a58695f9c58f74a7def45eba8bf7ede23f6\nlabel = d586a88b3b492bfc530bd701d28172d67359ccda042cedca29f17a6152f01d4300000000\nmsg = 8d708fb7bb840034728ef72ec2bd7f10b95e37c272a385129d58f003364fcf454528e290bcb872d51306812bca9ae146edd97f2d56c4483bf39b073b43b44e38b55b35c7c35946c59ad9d513af40dc6d65e0edc2017091d4b762d7698c5b632708028d4b94b2e59489bdd2140aa173aa8529134e4ca51f7b3a038521ce76eaba81dff111922fdcfd13b75dc6a8aba0c56867c4621c740fe412f5a4146076e2c1c3132012e7fb48559ed4f39874e6d00479e5a19b20f8f3e247b91c083a2ea603b2a75ab0564d62c2568de416082d9a0c1384742839baef2401f63dde8e0169446cde0beaa9fc0f92ad4d8816fa0b9b06a3e394d9a0466b9bbd13b3c9b832b18df1537f3a79c941ecd567880d99ca9031690e619674e8cf67dbff8ff7d650c03f49f8f0fb2fba43b76e6116fa9ad33abf71a232614cfe1a2e99d2fc6d9311\nresult = valid\nflags = Constructed\n\n# tcId = 34\n# em has low hamming weight\nct = a42d715c584bcc5589631f73e7ba3e0ee68d590626f76526b15c0e6defbd3a0c0e0504dc90157ece3c12317cf898a3d753787807892d2d67476ca7400022f0b3fb923b0add8a519027875778cea6537ba5a1c6ec5ee73d60e6fe998b97c18333ba711776d617198f38d97e7b56e260637efef5b68432394ba6e4520a33ebd7785fb05b212973664492a271ea666e76e5e15c9304a291b2a3800a2e0918a293aaf69cd280db9333493a261386a8fd602cd072bd9a16d242da982c33b6f70d475ffe8702ab82471831496584a4a3b6710aad7e4019dfebc6ec2f3e3128ee19325de5522d64000816e98be981ec2755be99c4d340413a08f2f8c888452887ab8e9e293297391fc9473c216d4a48256c3c1b8c7a142be547fd383de8ab7c2ce4fa5d4a0c034e1098ec5fc4066ae6b70fb24538432f67b8b188be691d94541522e78fc6cf46e3480ea6188598f8e73d08593d8b17e4fa28f470f72a1ca8ed92c7a9fe7abe2d02d7c13917c93a37dfb2d631942ab003c84c2216135bf8e2c014e96d48\nlabel = 01ca475244e50d16a353682007326d0ef4568cdb1e388a8d164ac114e459ae3000000000\nmsg = e00ac921d4554304c4d4c75a656ec3ec388c3c22e9837409cdba079cdd80fa3d215a6ee2db42947c7c4cec3d31f3f80bb64662df47bb9640eadf73d64054e3808b7c847e551fd91bf8d15baa9e33e37b688d48432deaf1855821721d903f8c69d7f6735d6d57d98eb8510cf6ee31801946f6aeffbc37d545028c0d5bbac890e91142f630a634c8b54ecb1eb9639c9e69d5c8a6a8c320b762e341948cf4e8cb9ff0da3024368e4ca87b838ee293fa8e209f8b993fd6a1048db31d149f47b150a1484c14f3c218baa1fe9a17fe74acb1f00050fa7642bc6ddc6574004dbf83001140cff15b3fb32d221c8bb21d9352e3356780e87b0df0b03b1cbb6b257150c70f19e43ab09c5a511c3b3a7c4ce192e718faac1bc6bcd6c6d5958b129076e1e0b3aaef5b38a1f82ccc0b8479aa41ab316d0b3c22de19004e06ea50413b0582\nresult = valid\nflags = Constructed\n\n# tcId = 35\n# em has low hamming weight\nct = 51ac53ba60a571b3257507f19d07646d340d8ed75ddac57f0633ce8f2ff5e3d86d94ede08c2e18a5070f954709ccc044625592249fd797f98a62190a6a65e0c6f8621c89af542ef7bea7c4efc0495abcc4554a22a77c9df7d6173fda1f25d3e33cf0f4d64989e9536570514040611dd78a07bf98f76a642d7bb359b151e99a5b0bf5f245ba896602f01550818215f48d020b8d521d63b611201492b22d6a212ca5bbccf3e475f045e3afb0f976fef14bb91b45e2e2927dbbf2bfd1fb94ff7fb165d5c000eaf09421df56691ba70bbeb98d660c7598cc58206c57a37bd9e8e111582f5274dfce29c934d156656e15ed0fbb61c0b4a733324cb3e6abc95d75b0bdbef8b617e0eb18350549dedd8692f18fe6e2196af679d4ddf4b040efb92d2fd0ccd60db025c402616e0f3ec8259e7b1667501dda86a41e15fb3bc259d6aad4553923bf563933940f1679106b9bde4b73a86a502f1e5afb6a8190dd4b03cad65690dd51afe3e4cf11deca11bd2f28a759c94624ed6b26fe3d89da93eba095b56d\nlabel = 9bb39276df720a4c92ca64f2e89a3c144fb2dcb3f8b13d74df5f24a76945812f00000000\nmsg = debedafca5e356c5375f0abf71f8c6ceb3879a1d9a0a5d5a750f2310e899a70f1cc833bad9e4204d883ac3c6238939f044a3df5641bc1ea2db48995850ac642ff1735062f441dde9376e61a3c7d2ad1eacf4af26c25e29bf3c1c27d3ee76bf992cde316973f88ee7c940beff156794d0729561a24e35e144f7da7a87664e423d6f040f915d996323d091901968e910ae6e206b586f084b5da695c1a1aa0784a7efaf92ce453d3c57f05c8fdb1ca7b2fdc0c4dbf463d5d8f4f62f19281221eb386ad292d26deb871d968d0b42073e1687cb3413f07702b47307a7c83df1a6654b0d92f55aad337d5e7cd58a7c7645df931ade6aea398e91f148392eb6032827cc2543847140b19bcdaeeaeabdf7ff22079aa822948088e7cec45c953ef1e13139f3652464cedcb9127b38b600f3e50b914c2661cb3c7196cbb9b7a4fa17a5\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen147 = 30190; +static const size_t kLen201 = 30190; -static const char *kData147[] = { +static const char *kData201[] = { "# Imported from Wycheproof's rsa_oaep_3072_sha512_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 009a389207c44f45ecd4b2ac716d728ef622e8e237171bc3e12f848e1743b73159a7731fc73bc8011bd8bb24855acda63ae8327dd60043e6ca86d3ea10f2dcb863f1fe20ba98246f324885198d642cab314c087b26fb115c0ba7dfffb222c3894f6577fb60bd07384dd4e71fee050408c9120a884f63ccb0901ea3e2ebd9da67c7cf54e7aa1adba1b146a9372f426e4d0f2fa4bbe070bcccc28a498fc711af83996362703b0433851ca516316da0758fbdac209eb63eddd91f6b3a24e87fbfa1d2ab8f8a95d1c143bb643d9ed2cad7778ed1bb41277f07a2ae4d5e01b263f905a1457fd1f7689c85694bc8a7f2181752a606b4e3ea5b59e1f85e993c8f8c528cdd0f9f09c65a53edfee6354be565d594060cbe594faf46d82a17056c8eaa59ccb0f0bb33114b9c2c029a6e0e7ee9325f03592ac0067feb660d99f8bdb6d25ba1ebc480ce770c367949668bdd2e3032d04968b5293c080dc41f2b69607c157e71c62570481a93e340a7a5be1629d91334533e41eae79befa422cd5ff4d838ec2181]\n[e = 010001]\n[keysize = 3072]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5245]\n[privateKeyPkcs8 = 308206ff020100300d06092a864886f70d0101010500048206e9308206e50201000282018100fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5245020301000102820181009a389207c44f45ecd4b2ac716d728ef622e8e237171bc3e12f848e1743b73159a7731fc73bc8011bd8bb24855acda63ae8327dd60043e6ca86d3ea10f2dcb863f1fe20ba98246f324885198d642cab314c087b26fb115c0ba7dfffb222c3894f6577fb60bd07384dd4e71fee050408c9120a884f63ccb0901ea3e2ebd9da67c7cf54e7aa1adba1b146a9372f426e4d0f2fa4bbe070bcccc28a498fc711af83996362703b0433851ca516316da0758fbdac209eb63eddd91f6b3a24e87fbfa1d2ab8f8a95d1c143bb643d9ed2cad7778ed1bb41277f07a2ae4d5e01b263f905a1457fd1f7689c85694bc8a7f2181752a606b4e3ea5b59e1f85e993c8f8c528cdd0f9f09c65a53edfee6354be565d594060cbe594faf46d82a17056c8eaa59ccb0f0bb33114b9c2c029a6e0e7ee9325f03592ac0067feb660d99f8bdb6d25ba1ebc480ce770c367949668bdd2e3032d04968b5293c080dc41f2b69607c157e71c62570481a93e340a7a5be1629d91334533e41eae79befa422cd5ff4d838ec21810281c100fd9e30b6bcb1674ead266332e2af25c56b2869b4d822d247e6f5b35cb0f3c573b5efc39e4b5de760489b82536d6cf3eda1bf60e5e43f69f26ac8e45b056d702f0361dbb4a73f42ae5889a849657a841d866b8b4417286ca9b39f854c4d95e3719b6cf367fc7128088a365f3e322c1fff16bc68bbfeb69c5b2a9a677dca6d494de44ad057135e65ae5a5f83c59a0d1477e5175acf716cdcb2966fb75145dad1554a112c466d249ba894caae5e182c65f1753fe5bb583ef962d1574d9be20bf6a10281c100fd3c5d0967b74bc6fb54ef961a6aeea76a59cad1600e3c73f834e5f5b7b5096f7779c62b07f783739341ad5de095e0209f2f2f30b8dd503da8a271f4b35d93cbda013b515f573501ab80dbc7d9fa9dc98da4451e00e0032f53583c818c2645cab8f35619e7c27928648cbcc3af39f30e0a61259ba2499ba96b2ed7b9edb881d442466c07f362ad11a2a9bb3f67548a5e24c246fc6c438d32de9ecfd18b609ce12fccca90bfa4c3ef63cfe3a349611e590e44a53242dbdbbe0937f2ecd81c8d250281c100a975dfbada4df7673c8edfcd8a65d96915f6c4dacf6844f5423f7dff3b4546f3cfe74ae0241fb4904333955b454c7d98947119bfc24914f3a3a263e2e5b7803409a0837b2c1d3ae2dfc9eb264fa6134cdf1a50cdc8637c67cfdb90e7b117ac07a7009f8b25c43e29a6a039f786f2b0d6734ca4f6a8753ff83279451969fea7f261ce13737b3fa1d564115a2cd88850dae3ba3d354ae6a078bbc81dc73253c977a1abe3d792e9d910458b40032347d73e054812aaa186428062bc60e0fda35cc10281c0098b4ade5de054a4cd38284779fb69bf398ce4cdfb56ce0478e8557a6b501168f811c8dc3a52a3cba953225b956950a72a18b72898ef0e652483ead3942704b8fc206bc1e75bfc0d720f4b393f07e9067da6214cbe2fb32f076f1de8ac058d3fd4b4a71c16d60786f43331b2165a92c486b39e9d3d0295314f6ed68695650ccf9927da4e7a67cfaa087d69273c97bd174b3f5f3988430b814d4ea2fa7ccc495d5b55d6949a0475b6020705c753aeab5c23e3866e5c82b8c772c57f0c5a20c9590281c100a2775a3e38c279cc6633f91e528ba76d14750e36b7d43883b1c8bc89eaaf2878c3b6ea9b87140d6938eaf938d1f010656899717be3e0de04437e1da539c6acf3db3956bd49ad71b747778217e2dc67ca0800726a7ab9624e41f10e578719850ed7684db03b7010e86c197eb79f7f68c3022403fcce14d8cf9df186b0a2b97cc120e2b4a729aa5877089240a18fab397962198fc846cf9a10eedcdb7cced6091c61e8b1c621df270cab19e5795485a4b74cdc3e24028bfbbf0eb1fa2ed4531cd0]\n[sha = SHA-512]\n\n# tcId = 1\nct = f9798ff0c606b0ff80a1042cd429d55bcad69856a0361640456261d29a98d2e42cc9618a08044fa29eb116d16f67212cafea3410c7c839a67519cfb5ca1def83ad3fdcc5488984ccbdfb2726371e1c2ca157357b881d873a7489004698ba21d697349968968a0189bd56ba4761b0e6feb4feeafcf4ebb5dd95fec7cb0a3cd23214356fbfdf93f17668196c354f7331a27bf12e8e9193e5c6c79e445160e0f28304be532b3157b50eac999cd162791c7bf446aff800686ca5d14a272a01dbfc6511472c18aa62d22b6af90a6335fec530aeaee8403cc8a07d9c2df2e9ea0e8c0cf83b82cde0488eabb8e7c8d18fcdcd62e680c6835955fdd7fa30c689b6b39805f317bb00e8dbe21907ee92f784c930acff37d70f8a7a838c7230e77d24ca45a5650726c2d1e3e7470d4247ee9f0a1bb8895dc2359cbde3b52785e4c05536759ae0c83555ef30f97482fe18f00527c7f0b37289c31c5621e3c7895abcb455277293e277c450bbb972fd63c533741d9a931be06163e166a4c6b139260e5909f01f\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = 93c78c91f4245a3475669a0683430aa59900c789474ec8f95321c46252e440209469e541778dc362b2ce9d5a6c822892b5e3754fe40038d5523d76e13ee07d3ae941963ba947b2fbb07c687a18521181f857d134a3286c073abd024691a0b7b85460a1872b5e33cb297e6630af2acc82c8fc61b96b8e7795f7e6bc8581d196dff9e3752fa88b08cba6bd67ca563043bc5296b6c26d526e34b0683b921739dabed3986c9b36b354ea17dfda86b78cbe5f0d4646cf102fea80da86c45b5dcbea40b44807935620e382aa17c6ea148d9b5e655793f7e6b6088ce719b08ccc6b5dde7bc3424f1c4d61f3a282bfee3d6f30480ec23a0b6c0712e9fb2ff799fc79459d1e2dfe8e7e87404894bb0a31260c1086c577cbe703a54eb9e750488529076c2dbd6f6b34dcf39e843f0ff279d0beab2e6709148b8562ae172bcbe0e562125cd6ed7f5d3a055c320bbc3c8b4bd28f7f9ce1fb402ff265e6d311e82adea22332d1b6d2b920313882ce3ba836d17e1176bf001afdceb1ca006c8a18f574bdc635c0\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 2679e7a6a3aa29ea006f84456c5cb6b33dfc0a7d1a86cf711f001b442fdcd788b01cdfee7d6e3d63ff3c30b2a67515e7d1d609e6ed4e22087d5857d7fca0d0b8f5dc41790d2913033971f85ee7d789de23ccee294493dd4484eb79e400799b24d6830ae8290343ed50d123ae840c6e4aa819badbbcd513341fd19654391085b0682d8f32c9706eaf8e2a0fa09420e861dcf8ca0867ae2f4b333031cf8fea956e3d67b67c40d97847cff086033cb83b95f33267c69d771407ecf5caa28fadb976db3855f39ba0710498271c86649604db35b141c8b9ae343bc4bc62b43d5c662b424a8e766eafdc22b41686d96d26d65cc28a221e15f53a1ce82ce664a2d5dc602bf0c9e488781fbc0ed679c9b225258a5582f15be48ba4a7a3d541a7433af5f40de0f04c04544962ba318179d2ecc8f4965d306bc56e2b6ee7f9705ad1501c218c31bc2f277c62029626fbf631f46964403d8037f4f6c8349ee8d9906274ede7d6b78ba30a3e0473a2621bc86dc31ba89561d82c5559982ff188ffcde9f81729\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 5120b9815296215e7ee89f5a20a46dee6f255f7d96d399c8cbf5721f9f9c4d89a8ee37e2a6bbd6acd4878404856143960be4a77bd8f6afe6b255f15bb8bcdbe3395f800df64c2d2b55aa7cc3c15c3d753562359a14433abd29106a0d1416cac5fea97732828a198c04d09ed6b47c12365de2a98eeddac3", "46fe879d39a1a28bc19e2ec570b94681f7bed871311edda5c8fd76cc14b15983046da8cdf1e15c465e4a9df0fda11ded950ffe5e67a3d07e56f902c7535331c08720493d6ef4b1760c6489e0af7d1b97229c4380167fd68f6ee30de2d61859ec55b5f0106ea0f675fed7c9f660520981dc201cf16a6fa87379d2c667f9c8fae97fa337c34d591f18b092f534be25db157e6696b1c85fbd896971f2c045d08be1470b403f2effe6d82fcd1b9baa9ba2c0ab0d25ca9cb2aa26f2c4d5ca3699cae3b61ee6eaf98d44610c8204e4298a01886e9cd21030058b29462f3d73018043466fe45307d2382b8b828fbad34f77c1915514a9ca9e0bcfefd3c0c7daaf02db684454c18b109a7a056f\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 290186a1a87bdde5c2ce70e17605b39b4fa2a286fd85c299a303d56207ddd0557ad5513a7f92ce1a39d8cd571c9c638c279d722583e17ae488d9d3ddad55d837a43845a84f3e774d8679d09b13bf218d11d8a2173cad0c5fc7b86e477dc372f215bc5641a13e931170c6401447836530b065f574f3376b99d4e0200053b92b1fe1c8f513d2d8ddc3ed210062e601d4750c5bb9a63e051098f159ecf8c40f90e6f0265b357585aaf35c32dde08e565bc6687319bd7c637b7e1a012408224865b9334083460aa39c12565c5bbf03a316a6ca5c174d6edee3391bab9773190bccc4bf737ad0f350e629d2eff4cd1611d510a7cf9c11dca1c86b8dcedc8f9b80fcff7a828c9b415f4699b2a1de2bebbb804e0203a1a04ddb95afdc4bcc6d98d240ba71ca2918f21696ec92abea1a9e16607e86f40f7de08c9013485d9f8121d9f9c0675980275519dcd2e705dad4d87009f0fb8f6c413b97c131766620ab583c82dc1ac489bade156b8e502335365bc4a8d7d8adebcc32bad71e6b949a48118dcdea\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 13ad5b087b5a11595dcf44902ca1011fffd32efe6b77be307b3dddd1b528f33e7ea3f36e09873da3909c7f44fe9ecd17adae5b40cddf0efe84fd401df7fed988963d555c24bc5a55e8bc40deb8061fcb59183836c1b1342d66cfc74f6404b67a4f50d9dab04223c18805c0a577b964997e5aca7016daf2c4273ca773bcde39470fe7eb5ec4541650c7687a378d00008bfe8a3a4627cf1efe29e7c81b8a12cc8afb745a86567f5141d16d1b848514acbbb52ced7ceb7381e7cf0261991761d411e6b16f2606050b24ee918cbd17f6c3ff949ed2dc7fa6e99b21436d35729b241f4a346c9c92a60d57c40f39fd299b2bff2f97e196aead3f954135b473267b27ff76bdb451c23b49d9477aeeadfe45a08852caf353d92f0e47feb7cbed5e49a89f42e2a755db0d5efe9dc330c3a71f331110db4a9fa3db914535050a96b0671c2a15b2e9a3ff3f1212526e2391e3edb1bbded4de0c3cc677263f2ded3a9506bdbbbd5fb3f15efda88d954063fd70f6642a5a28295fbf96a4e0cddbeef97a2b841e\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = f4b9ec8148f2d6757e6a6c9c32d5928e0efd5ba4d9635d60d9b481ee84631c6b019b4a04d1e15d5b3911aa5c5e9c46d564e707e64149cea901a88781512ba96a3a53694d5ed7ed7f8fc7885e384daa32dcd4c5228ea33e6266bec630ddda028c013288ff16671dbc5147b28e26b73585beda7e572bae5e30a2a9b123fb12b711a4f64f4aab9b6531fe691098d38c27389a8e99b44ff5d39b0ebeee5930313422c918681be11fb722230759c5b69f03c6a07956bf406d53f8d55729373931dfb19e01dea1b9e5203955712ec5463772b38097c075d8887bcf437c44b1f3041f2e84a60387e5565feadf19b528e77fd009bd13d248a0354e701a09a63bad83b30b4c64fbeaabfe23edc45e8405ee8a9496cb863e0b12a21848023ab41bf5d24f39b35fefdd1c27702dc3fd3ec31a3643ff7cf03cd429ff5b14735c8b9c8fcc7683d599ed14200e472a030cf3b40dabf7c22ec7645c735800cd1c72cd50beef8439f5a7406a932bcc1f0ddff90c95fe554da7c1efb79364cc53a773a35a2ef89bb2\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 20ae63774da080fc14e32bd56d9cbb3610aa0208185afbd8f612ad4edc3d9fda4746957c1891098ba091c3d0d3e337a218aaba1911eaa73b78c5f16e54c31cfd460098b33b160ea3c274d8e09703339b3b1cee7ce11299b1e7f4fddb75f19f546844b211764c6c171d2dfe820ac2e3a8656b90c7e4e19f81cbf80fd85e2f81c350c49462b45501487df08c2188f87383bc2382a32d60ac965aa4dbe5c1cf28619901ed6b42f2254e066af44a20eb6a9d4348c3a4169a209263f939ab49dfb989358c6cd89682df00fcbbc2208bd992e06f75c64f3e8a434dd7d1a4200fd197d0ee2b7f851d04dd4448544ab22c16bab499719bc43c9b07007a124b5b1e18b613e401340b637a31860d86cb4798c27afdfd885427f6f8b267d767ba290113eced53c9a3a0e7143b00c14beb395f2ba5bff839dc2c53a44eabc269e4860ef9d4c42e9e8c1623ef77613278b399f344a89fb1a107f08b5c265bf5809f89785ec7f24ffcb884897b891358ff48196142f57290b1a02a31d6bf5288893a1fb615fe0c\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 7a90b7e694903463592d5bfff2e00189459a41261d0d3b1c7c10b2a578c792b8abdf57f52d7d26a26ef2ab75a7ac39c28334f8a05fc14775ff1d63dbefb688e654a595ba49687d0b711ff21643a2467ff587aeadabd0966f1e5f34519e5b36ad9005a05b7093d5053f6463734c314e654340180ef8a18ed259790e3058b1d5ec18842e9b054853d8219e18131f51aceb01736666e60dd293e8ac47d4966ed68ba39194b766029f4bfd344ba2b07d9f89238804f0685706ac9c16462e69506f18dc3ae39e0509d67acbc603fc21b900712c4386c01a48877b9935355adbd009fcb41e5fcf1d39fc4dc7d26e72f0db741e2dcc17ddf79db46ef3ef3b2ee3c6ef5c689e139442c24c2cbec5eee51f03b0f38f19f67ca802e899be6597feaf3f0fbfc52af1960c1374f6114ac9b1e82670568c8c78e00474a1ec3de11e4f510982d8e9fda89e537733583ef6792ec3bc77955f4389b5b44965644c20f23a09363ac346e15e1f0821cf0488498824200191971257392490946d660819e6dbf310ae57\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = d88801d500a78a626043e14bd52e01f068eb5381c434bb3af50c9367a2ac5ca1fee8a9d248be2b7de7a5f52c1e716d110113b72bc6e2d08766607ee20e262275f7dbb669d47d8710a753ed8b0d99aa86c7b4cf0e342800c2185f00c38190bcfe3b40758035390fe649b2b0936433cd218450e3b762d10e7eb95d85fd52e5759d0d5a0ae49c897a059f7b1628efe8fe06e04d294548a07f73c74e6e6d515e311e7ae846b0c7f5aa56c61f3373e1a99f2b610785df6cba710fda15c24f56c37bf66e05de18f8417c5215ac4401a6f638a8d8b9fe2f77d247d0ea0d190b8c604bc702c91a84a4352ad0c8ee44d8fd1731a01d91503de39f8b19a7693f8aa6efdff15bd1169a0b79272ae03cb20b3ba573b24be410a8eeaa6ad6de87734f1e299c7dd95afdfdf56d41cf33ff61a7ce0af5eb99826473647fc79e884a75541ea7ab9963f154efca34741cf5b343c86be001c6dbbbf6b2cd8197ab5d377b8f0d2761f42f058ba8406f768ba8061576ff516f45faa42048b2ed3851dc7466c425433f6e\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = c609ea7cedd8b6d56fa625b11123b898819558797be9cdb61f0354efa52ffe6c379c4314fddd546020ce9f0fd5b907e6e7b416b46ce8bb3c6129ec39295077fbd3b6c24aef4a9163f5d7d80dfd47f44ebce3b5127bdecb5cbe49d1e125e20479d226ae2852d79047b5f0d535b48e8bfe6118c1d7c37e8c70ae84d1e262977e550f5da03bd087012a934f46c01e121e8b3106e50b4bac05632e9aed32996f09ee8c524ae104911cadcac120a45c44992fbe6f3af37b04e8754dbd674d1fcabc9f5c8649e0228f5f87cadd6d6620f8a9d27928e5249c08eee52372cdf67a4ac0fd8dee2b9e57699d7e28f17a7c76bb3565b6896c83ad14157908aa765c7a51493f2d3de7d735f3adf9f911a6ffd0b7cdddf610bce09e6d929675631381777a9fd486a7915890c0b8b3c119e50330579a4961db1c498955f0889dfaf3dcae46f319c722f7279102467b1109ba6191e30159ca53c9398e6de412afd21cf25ee131840d742562388acfbc528672d3dc38ce758895ddd5db82c875f12de940503617dc\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 2fdc9577156255b3b2f1073c76aed1dea93f18758096085e69b2a8593bd9dec848ae70a250d893d73c6b4ee109c967f896361d8d57883db63549cd9b3b61cbe50d2d944fe88524124c168a322175ee87b571569b567310b4367af407a9ef2657f693a33b536fa7804f066103fc012414c932c83aa1eeb9169f2ca10992b48910f0b2fa4409d992bd4218954078dcc78da6436b809a83391bb8cdd75c602f2b41a1b836a62e4bc04add443e90f58038b99b177a9fdce99813cb7cf42854520916b9ed0bfa4326c3aaf45ef8915c50a8c159d4c8ca6dcb06d35c15c5e8869d3b278e3f2e9fdb0811c6be2afd4959d082b4ee2f57be078d149a673fea7252b085e04b5c91d93bf6ff343e374ad5454a89c2bb77e040df555185539f0ae81808e20edc9d7c94e06498aad532b1de2eaed00d0f3419adb91893941688baa57269c9d1de160d9b505d55c7c58a6fdf95facbfc2551150825f42c1df3dc8f3bddffb80a0f424386a04ee423b72d5fc6161054ac43edad4e1f0a0d2cb96727de0dc6487f\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 12a86b617c77976f1647c75333a0e938a926d6ce39ae90208c63d1f0dd8420552946dcd8c929c08e6fdd8d03f8a1b8e8c3f1247a49bbbc010e8583bf4907405f62c95cc18d337bba3d54075dabc18c2845534dbee7df792262b49f3d", "7a71910181d6217f0f22f9839b7cd3990f2da4d959196ff448342b9a9dacb984a84969d62ae400a3116dbb8aa7b1ce61f82361cc5cf994f2b65639a772c731bcbfa1df069f6726ef3de4cd2840e7c6b91f3e032eb826b5b4abf2de20d4e8d667e6b275e72c202e4acf65459c91466dce7b81a811711d3fd4130b83cc8d33a6f736f91bdb911bba9c894f6a3497be6381a2dc4349c85fc07bf48b47fb2291717724d8fdc53c9b8ce15f3a536bdccafd36ebd5e4693420271c9a6c77cdde48f851279748a0acd9e29048174644c503c047d75be164bbef65c7a1c2f6db94298e7bbd74679e5b0d7799980173b89358371609b256adc28b8a7f67cae1bfbbd83b4497ee13646be77e17edabb75b33e382fd21cb8085ad958c38505ead775bb784d608a123a9\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 4187354a63cece7c984286cdd0eb98909757a41fb2e5cf45982676ca14e89fdbe5a570eb2d9475a5b9bd13a58b225f3154d538195a67f3813c6d70cfc8a282231aa41d3d3ce79aaeb9876af8b9cdcf68e529734d7ca576a8458837a6cb3ae65d8b706d54160f438ba1cb1eca3f6a557f2d2c66476e2d64a1b0b3dbd9ab0cb01d46900234aa22ce906e2acbba4cb1761ce412316deadc060269c74a81827b3180d94c69b5e30d2d45d51ec49b350ee0e672a0ea247a49601604c853c47170c4adf4a9e4a1066da59050f9edb6a21e922714706012443ba153959c8c11b9023f153d62d2a23f271e2b81ea0cb73dc15756ff7319f5ec3fab7e10fbb60b8a996fce23bf7de9fa17c11175f2cf604e32064b2ce3486221314bbb7a8d01987a57882f904d020761a53da20029d9b3a5355ce00520e61041b5a00d98a921300d3e30fc9a7dfcc00186e503bbf0fbf6ee00ca7eab439263d6d1257ce1dafafc1a0c3c684703ec18b3b12ecdf9a3f680b320a09865e70db3a6dce20a868a61ce187e5a56\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 4b845fca1d048ccf7e5a9cfe00c182238a2b69e02bb0b798863246e24c26856953d269d4de46e93caa7f383f241a963411b455e7a2547a9018b2f7676246324db9ebea25603d9b7f7792cf29ce26bb64cb6f3e703e359fe53ff4e2734371219307709d8a43959e61c5e76146b67b53cc2f669527594188b502bd92d811c9c44fdd7c7b69468f314ac30860bf51b26fbc8b6bf985df2cfb215fbd5f53ce0a6c00781f4d987f99fb420a8e34fa7544f87a7dc67f94418659c747bb984124086253eb86e0efc15214550429a7f4d13d8ab4bfe908794e0ceb41c5753b19792e8ad4f108f26eb990baea0d88e930c3bb245371905354c2a192bb21483c2f5033c05073e2bfaa65c8e7c0eee1d22f7363b363cd698b781cd7241db25eb2fe43f480ea8363a3c680869ca143f531d83cee2b4b6e9a56196358a4db22839aa7332c9be2acfbb5f0e710cf3c8b7eb30a16bc126d1a3dc2e29bdc54c830b070acddf2bbb2932a571125f12a5fe70282f21772bfa1a05967a04db4a17009ceab8b4ee7075c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 4e6394953d0761d4db461cdc976124f729800f191c1b308f663344db610b8e790521758688bff16f1f631d0f3023e5aec3d750db63fd4bbccb2798d1050beb31c16151253dbdcd7363a2c2c11398134965831cb076c0dda88d3898714969b0a55f944956d8f792a0d7074fcd6899675843e91cc6ea2f1372e3aecba67a4b598c4aa7092496070c94a0a1a289fcb6a0f19ae54ee2d634014064d76f44d092b2dc6da115b21b811faba0168722a5be99965527ac6c5992d2f8428319f72fed15451b89fc5b06710baf912bbdd0cee7e2f0f2818599bc99dc8df17cd5c410911d0277aa956f330f3cf062c8388e3d35136049fc9ea624286e5febc37ec9802aef1ab20b28da9602b88eac75b6d055dbc4363fd4d937e69a87931ba728101f70c8ce12ef9e1c1cd47ccaed88db0a95b40d8c1da61cacd0b31f723a57d908b8577259924ce2c457db888c302cfc9f2867dfa6b86dcc9250e69e3b392cf3057c06e0090d511ece16e3194abaf26a2ac9660ff6e0237d8ed4479b0740f77864138673aa\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 81b9ea5c0cbcc4b7f183deae85cf3d04d8c9a35cca7b9502238d1d94c05563bcfc6e3cd27320bccf3fabe737195bebf4d8770ddb232aa0e25fe41bb055d36dc328b2876e4b7842ad4499f0e735ebb283e7779f6b7c66cc71b62811f5c88ea3408939706ab48ba6fdd4359f18e8a6e0485de9bcbcda3654e7964cd8f243d3afd3cda79b498e6a10fda660029207f4b185f8ca73b1ae46c3dd3edd2097ddb6ca0396f94ce626448ee9325c91fab3e550bcc72c7a36cd4161cdfa65b9fba398e153ef1b75e06a2929a86a6e87f266b50d8f513699dc8663a7c6b1c4c9872a63fc3218cec37029c07a9b701d615bf8ef0da3361af097184c5f1a3feb4ca3785e235b83c0b494ac1e36b514fe5c343561136d14bd110117604fe8a99f210325afb5a406a10c99e6347b29dc6ea5b1902b7cca6fe6715f3b291e07850a12327d985565715266f723249cb595941f43b946ce7822edd05797eb1bccb9ade43248f22df4e38107ce9d92718cb795e93db7d1bf3203c8f64c804669159b58ecece44c6f2e\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 5a49100a3e147a880407ba68183f96a904529cf14377eef22775c95ae7d3166b73c3fd5dc259256858424ee97812b1dfa159c25b6de84831d8227b153c4624904ddd8c84bb1fcfde36bd61319120a7cb0c916dc22369b2243505d5fcb2d466462dabee4b8495ac8c186a38bb4065fab4e483c947cf72c27ad542ce7d32f689c34f6d0873aeff48a87eb89efddbcc1a5f51264ba246f10dceb2091823d3215f4928a8b7f3ce462e227cc5726834b6e86a503506497cbe8d6bf04a5b4085ddeb04816654829ff24cb8978551e92ebf588f3e60006b444d7b39efc6d18e42be234c37fc25ee2a1c02e1efaab917de7c6d12b05bd599adc92af582e7fb522c884d0cece7f912d2e69812e52aadf0748a98aeab06f391381f4518f20d029360b764faaa3aa1e69a9c05cc59e29cc663119ce74e74ce1efdfa565cd0a67751a070b4a0def04f79c7da5a7340123d00de354bffac3cbcf85e7309336977c2c4f84d528a123bf1ce7fcafc49020a8d51c48ded174b9eb468928f5fe94ea6dbbc83c68d40\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = b4a8e5d8f2cab3e3b659b1964fb9f634ff7ea5de5a447fc7c6ceeeba8af5efd0f136fb79e09b734a3978b655e74a0156a3bece09c00b578d894b81331770a3e95691335656eaf1c260e4e9dc67367265d6e870b37d0685b16762062166e10f0c0ec9fa34935d0943b0f5d4c5b1d88422e21f9e3846f854a2e725f22b53a778e65fdaf32ad88943b2baae31209552085f82f27a01caea2fdf471c08643d806463c61ffce92d0c1458518fc100fda777f769b33750aa84d1d4e206282f8ca944f151ef9a5061561e96453d7bcc9927eabc21a04c84ce1e0e6a88113132eee3a7d7baaaf33db8d1818e520e202275c5df2d3e749c3acc43326964a6663eb4ff856bf2291194e584919e872a31e1f040a59dcdfc88300a816a0ba27616919df4fc97d16de1fb0c6150cda6c329f643b036d99736b0424b6676ce0cc4d971aa6c5ad91a421cd369b35c95a38623fd99dbad13beaca3bfae5f9315a8a788f111608b5b856f4313ca6d19cc3172bffc6cccc28682a09d0ff74fd16a58234151c0224da9\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = a985e8779a4a34ab75873210d0c8897af9381c83887cff7fad9fe60f601801620747ec0a2c1f5acf6560a751216d204acdbcfe2d5bc235b84c17e903ffc96897d5df86031aeb1e40320502be3e18daf723c2577331e03c216e1febd35b30be8a419d5ac4e78674c93bf244e2cd8e57a4774d0b8763b9de21aa1e74b0afc3b423be7c52f32595934c993c88c32c2b0a66e5180c96ef478ea2be4262c840d3e2dfaf86b9684e7bdbf3b31b0513e3e48322dfed125f2d0ce186e58a321cec902cf01a7253b77069576594488b665facb1ba33671ce26cab40dd679f3817607719fa0669c6a593f30de1fafe264156cf48dcbfb8a5581f6a9a8401a749983b43cd90bcea0f6b690b46b2a00505e112d0bc0fd080c453085319b5d31dbbf46a234ac0f0eefa947f002daf872681ce731b27714e37fa3ca743cfd3060935affb356be4ce827e27ad36df8ff4b4fd72bbc0076d2277fd643ca0a39233a16fa545a4d84f1217ecf07a2ee57298cdb6de88f797116f80de8f446930045119e52fbc7840c0\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 3a567bb387312c94a0b8637807f86728e6e54ff473ee541ffdb4131cb5c55a60c6044a53a813672e4e5f90d5779dc21f824587a3618d4996449b2949720a93afb50520947d3b4a7391e2928acadf5fbb0bf87e48798e018f133b12276891e49007ebb27e49c858818e242dfea715f575da026a4f039840ddcba0bb330fe916739d095ecb76829091ad29e33a0b58e23f3e1c80a9aa4be2bc6e21eb1e7dd3061a737d3b460a5c4cbe6264b506d4f424bd0906a3977e3ebea5549825c889dcbb601c111f392f690b8bcf4b9935895e23c0e39672391f5e12e873d393ba19b00922d7f188def9a193789a80514abff02565376577c073a3ebaaf216d535f50f6a602ce038216ce7f1d1f7e9964570d8cd2b3821b11339446ebac43ec87bfb712a634089daf4db979d50d1a93e8badc40395fd8e8d680206606b8a1e78fa238f09ab3eed6ba87ee54ddd3a3bbdfc5c036fc9aedb207c6ab9e9ee594ca06da39297d8528fbdadaf80005162964bd4e0168d5c92d8ae5b05398d66c032ab5ae0eaebd7\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = a0f2388c5bc52093c31189674c410b4eabbe1ffd0e0a902dfe0b4fc7daecf29148703ca5906bd860065da69e5e7dead22fe28bbb7f3bf71d696174a900c115ab7a98848a08467643aca3a056ff58ef4b4515761b0e9452a587c4e7a0330faf97f657cf925e5bb0a395f7a798a715f41b70aa2d3dbe411de02c6ba40831f0b636e030a51e66cf7237030ae9569bab4cd8759baf22325f88c11cbac0b0e7b87dbe01669fdb5862101679e28774aa415df8a92e45b1ab74e1d85a95125163aa74c91da4a774ba539c7e1ac945c20df5ae3e31ec55609883f83a75fd3bf70bc4e4dc18b0a6e77d678d19c82400c698a0c34e3e77e86de8f51daf306f102a22cb", "a918b6ac435a045e89df00a9c84689e29b1eb466ad2c96c7326073afe08d47490230150c9b5d8ec84b352c6a33a896a26bc0f91e49fda6412bdd8a0e7c9b7f8beead5070a494af8b5b4a449b976b7f07c1b5648ac303e7b60adf3e53bd98642642f1041694986f214882a06f48db4d118f2b91c05578c0e7665c128cc6b4685b7faf\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5244\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 00005120b9815296215e7ee89f5a20a46dee6f255f7d96d399c8cbf5721f9f9c4d89a8ee37e2a6bbd6acd4878404856143960be4a77bd8f6afe6b255f15bb8bcdbe3395f800df64c2d2b55aa7cc3c15c3d753562359a14433abd29106a0d1416cac5fea97732828a198c04d09ed6b47c12365de2a98eeddac346fe879d39a1a28bc19e2ec570b94681f7bed871311edda5c8fd76cc14b15983046da8cdf1e15c465e4a9df0fda11ded950ffe5e67a3d07e56f902c7535331c08720493d6ef4b1760c6489e0af7d1b97229c4380167fd68f6ee30de2d61859ec55b5f0106ea0f675fed7c9f660520981dc201cf16a6fa87379d2c667f9c8fae97fa337c34d591f18b092f534be25db157e6696b1c85fbd896971f2c045d08be1470b403f2effe6d82fcd1b9baa9ba2c0ab0d25ca9cb2aa26f2c4d5ca3699cae3b61ee6eaf98d44610c8204e4298a01886e9cd21030058b29462f3d73018043466fe45307d2382b8b828fbad34f77c1915514a9ca9e0bcfefd3c0c7daaf02db684454c18b109a7a056f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 5120b9815296215e7ee89f5a20a46dee6f255f7d96d399c8cbf5721f9f9c4d89a8ee37e2a6bbd6acd4878404856143960be4a77bd8f6afe6b255f15bb8bcdbe3395f800df64c2d2b55aa7cc3c15c3d753562359a14433abd29106a0d1416cac5fea97732828a198c04d09ed6b47c12365de2a98eeddac346fe879d39a1a28bc19e2ec570b94681f7bed871311edda5c8fd76cc14b15983046da8cdf1e15c465e4a9df0fda11ded950ffe5e67a3d07e56f902c7535331c08720493d6ef4b1760c6489e0af7d1b97229c4380167fd68f6ee30de2d61859ec55b5f0106ea0f675fed7c9f660520981dc201cf16a6fa87379d2c667f9c8fae97fa337c34d591f18b092f534be25db157e6696b1c85fbd896971f2c045d08be1470b403f2effe6d82fcd1b9baa9ba2c0ab0d25ca9cb2aa26f2c4d5ca3699cae3b61ee6eaf98d44610c8204e4298a01886e9cd21030058b29462f3d73018043466fe45307d2382b8b828fbad34f77c1915514a9ca9e0bcfefd3c0c7daaf02db684454c18b109a7a056f0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 20b9815296215e7ee89f5a20a46dee6f255f7d96d399c8cbf5721f9f9c4d89a8ee37e2a6bbd6acd4878404856143960be4a77bd8f6afe6b255f15bb8bcdbe3395f800df64c2d2b55aa7cc3c15c3d753562359a14433abd29106a0d1416cac5fea97732828a198c04d09ed6b47c12365de2a98eeddac346fe879d39a1a28bc19e2ec570b94681f7bed871311edda5c8fd76cc14b15983046da8cdf1e15c465e4a9df0fda11ded950ffe5e67a3d07e56f902c7535331c08720493d6ef4b1760c6489e0af7d1b97229c4380167fd68f6ee30de2d61859ec55b5f0106ea0f675fed7c9f660520981dc201cf16a6fa87379d2c667f9c8fae97fa337c34d591f18b092f534be25db157e6696b1c85fbd896971f2c045d08be1470b403f2effe6d82fcd1b9baa9ba2c0ab0d25ca9cb2aa26f2c4d5ca3699cae3b61ee6eaf98d44610c8204e4298a01886e9cd21030058b29462f3d73018043466fe45307d2382b8b828fbad34f77c1915514a9ca9e0bcfefd3c0c7daaf02db684454c18b109a7a056f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen148 = 33222; +static const size_t kLen202 = 33222; -static const char *kData148[] = { +static const char *kData202[] = { "# Imported from Wycheproof's rsa_oaep_3072_sha512_mgf1sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 009a389207c44f45ecd4b2ac716d728ef622e8e237171bc3e12f848e1743b73159a7731fc73bc8011bd8bb24855acda63ae8327dd60043e6ca86d3ea10f2dcb863f1fe20ba98246f324885198d642cab314c087b26fb115c0ba7dfffb222c3894f6577fb60bd07384dd4e71fee050408c9120a884f63ccb0901ea3e2ebd9da67c7cf54e7aa1adba1b146a9372f426e4d0f2fa4bbe070bcccc28a498fc711af83996362703b0433851ca516316da0758fbdac209eb63eddd91f6b3a24e87fbfa1d2ab8f8a95d1c143bb643d9ed2cad7778ed1bb41277f07a2ae4d5e01b263f905a1457fd1f7689c85694bc8a7f2181752a606b4e3ea5b59e1f85e993c8f8c528cdd0f9f09c65a53edfee6354be565d594060cbe594faf46d82a17056c8eaa59ccb0f0bb33114b9c2c029a6e0e7ee9325f03592ac0067feb660d99f8bdb6d25ba1ebc480ce770c367949668bdd2e3032d04968b5293c080dc41f2b69607c157e71c62570481a93e340a7a5be1629d91334533e41eae79befa422cd5ff4d838ec2181]\n[e = 010001]\n[keysize = 3072]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5245]\n[privateKeyPkcs8 = 308206ff020100300d06092a864886f70d0101010500048206e9308206e50201000282018100fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5245020301000102820181009a389207c44f45ecd4b2ac716d728ef622e8e237171bc3e12f848e1743b73159a7731fc73bc8011bd8bb24855acda63ae8327dd60043e6ca86d3ea10f2dcb863f1fe20ba98246f324885198d642cab314c087b26fb115c0ba7dfffb222c3894f6577fb60bd07384dd4e71fee050408c9120a884f63ccb0901ea3e2ebd9da67c7cf54e7aa1adba1b146a9372f426e4d0f2fa4bbe070bcccc28a498fc711af83996362703b0433851ca516316da0758fbdac209eb63eddd91f6b3a24e87fbfa1d2ab8f8a95d1c143bb643d9ed2cad7778ed1bb41277f07a2ae4d5e01b263f905a1457fd1f7689c85694bc8a7f2181752a606b4e3ea5b59e1f85e993c8f8c528cdd0f9f09c65a53edfee6354be565d594060cbe594faf46d82a17056c8eaa59ccb0f0bb33114b9c2c029a6e0e7ee9325f03592ac0067feb660d99f8bdb6d25ba1ebc480ce770c367949668bdd2e3032d04968b5293c080dc41f2b69607c157e71c62570481a93e340a7a5be1629d91334533e41eae79befa422cd5ff4d838ec21810281c100fd9e30b6bcb1674ead266332e2af25c56b2869b4d822d247e6f5b35cb0f3c573b5efc39e4b5de760489b82536d6cf3eda1bf60e5e43f69f26ac8e45b056d702f0361dbb4a73f42ae5889a849657a841d866b8b4417286ca9b39f854c4d95e3719b6cf367fc7128088a365f3e322c1fff16bc68bbfeb69c5b2a9a677dca6d494de44ad057135e65ae5a5f83c59a0d1477e5175acf716cdcb2966fb75145dad1554a112c466d249ba894caae5e182c65f1753fe5bb583ef962d1574d9be20bf6a10281c100fd3c5d0967b74bc6fb54ef961a6aeea76a59cad1600e3c73f834e5f5b7b5096f7779c62b07f783739341ad5de095e0209f2f2f30b8dd503da8a271f4b35d93cbda013b515f573501ab80dbc7d9fa9dc98da4451e00e0032f53583c818c2645cab8f35619e7c27928648cbcc3af39f30e0a61259ba2499ba96b2ed7b9edb881d442466c07f362ad11a2a9bb3f67548a5e24c246fc6c438d32de9ecfd18b609ce12fccca90bfa4c3ef63cfe3a349611e590e44a53242dbdbbe0937f2ecd81c8d250281c100a975dfbada4df7673c8edfcd8a65d96915f6c4dacf6844f5423f7dff3b4546f3cfe74ae0241fb4904333955b454c7d98947119bfc24914f3a3a263e2e5b7803409a0837b2c1d3ae2dfc9eb264fa6134cdf1a50cdc8637c67cfdb90e7b117ac07a7009f8b25c43e29a6a039f786f2b0d6734ca4f6a8753ff83279451969fea7f261ce13737b3fa1d564115a2cd88850dae3ba3d354ae6a078bbc81dc73253c977a1abe3d792e9d910458b40032347d73e054812aaa186428062bc60e0fda35cc10281c0098b4ade5de054a4cd38284779fb69bf398ce4cdfb56ce0478e8557a6b501168f811c8dc3a52a3cba953225b956950a72a18b72898ef0e652483ead3942704b8fc206bc1e75bfc0d720f4b393f07e9067da6214cbe2fb32f076f1de8ac058d3fd4b4a71c16d60786f43331b2165a92c486b39e9d3d0295314f6ed68695650ccf9927da4e7a67cfaa087d69273c97bd174b3f5f3988430b814d4ea2fa7ccc495d5b55d6949a0475b6020705c753aeab5c23e3866e5c82b8c772c57f0c5a20c9590281c100a2775a3e38c279cc6633f91e528ba76d14750e36b7d43883b1c8bc89eaaf2878c3b6ea9b87140d6938eaf938d1f010656899717be3e0de04437e1da539c6acf3db3956bd49ad71b747778217e2dc67ca0800726a7ab9624e41f10e578719850ed7684db03b7010e86c197eb79f7f68c3022403fcce14d8cf9df186b0a2b97cc120e2b4a729aa5877089240a18fab397962198fc846cf9a10eedcdb7cced6091c61e8b1c621df270cab19e5795485a4b74cdc3e24028bfbbf0eb1fa2ed4531cd0]\n[sha = SHA-512]\n\n# tcId = 1\nct = cb9ba45404396101c1211be70415603708e1051b0debfa045b75ab936fe7c5d4e8c67704fd2ee046af8679e0bcf3d266ce67b801c90b581a3f6909f56c6fef023f0e2c4428227a51362d3f50ca65a79edb3faf899cf71bf99e244dc817fb4c2bce848216f0de57a1747fb1d4f0310e59f7ae0a656376690125dd10657357de11b5e7e5588af7083abc6018013ddc43d21c2af42c9c302f008064630a27ab014d6dbf48350c8758d821e74c45efd168ac37f366b413024ebbb0c9624e6a93d4c02d1f2b050f75de4b6a74c701386a6c330767af6bf03e8ccd69ce6540b471c01e6fe20852a10f198e4e0d29469b1b01d5ebff85ece159355083829e4c2935f16cd2f409199f799f250c8f1306da1614d0aa15578a58f399a17223c7618242cab31fe32a2317cf7babbb30b3885d5c07c4b89e91ddcb37f449cb3e2faca585d04beba9dce34face1167f5e4aaaa0509867716e3da0ff81b8a481b3f9cda725f01441d7d3d7ae24a5bcb373ff85e608ee7a49750a0d7d185a61082924b2343e18cd\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nct = ad215dc277e269310c54925f735d9bd6e68b828c8a9adcad792a567fa89f75bfd9512c69caab0539f3a2d4ad7caa73e6c1166d94645308d09f98166547beffa48940bba67d08391d8ce831ab3e819b1113eff18d02a83d7f07f1db2ad63cc53dccf2c9a8d8cd42f3054cbe1d223029364877c61d2a58d4c16929eb2c8b21fa1d09797a558d61f00f6b2a4b67eb794dc9730421bf52e073cca7bd083b35562d21b6527a525662defa0db2c9fb0fb3d8122a85128839e68fab7224756fe7cfde6d86cc7bc3c6665d3ecc52ad0ee25767d5f1f1815e56c79e1ae089a4278bd8c34fb397c1029b4315573391064c02f139e6a672b8a9f50678419ab6d9fc42fbcb69b71dd644ceb7968d6b0edea5f72d9d05da3d7b36cac7de135d45edf45834b47f7b2b91fe89ec6c3f2863f7454017091cf6622b02447a0f8ea6a8668c61a55f8654c4c8f60ca13639f125f2a3a46bd82d2bb6bc66511ab7050433cee0d6fa98946d18947d5649b380f795fdc8f0f13b663f518fad69c65601a51d170f7013204b\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 487ea78c9548871a93a0b856306f349ab51bbd30b3e6db0c47cfc965774cb0532575333f8584dddcb13f24ce98ff4a33d63b5b1898b3a8d9babc0ea906cf7d9ae047284f7a36dbc350d7affd57030196afdd419750f1c5f2fc55622e442e6203d58a725c7b6e59205baad02c86e44447caea8e88d38963389541a86933cc64c1d8a3b70c4870b0f75146de372de834988a5f852235926d7f3893c83dfbb78a1a8cb4d9a4d516de110d315ada9be71431d3e6b03681d4d7f665987000a72a1b138476579aae7058f7d4151f058410d93bdc197009b839906ea6254e90c1a49327ebf818dab3517edc39761d3f84be8f8bdc8b35541c6b6b30bf8cfd20fbd9a09713c470c9ebe0622ddd8b2471f9b0298cc77b51e56ac2dbf9209fc5a95c066092deebeb7ebec0bda02f89904ccad29ecdc1d263a29930947b90a6ab83dfaa657871be533d55231224ba4e866ee9a3e352f501372d75090b5236d39b62ee6c84c792dbb253dd1f9fceb868d460fd76847d9c450b1ee5f280fdb0da832bc5627957\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = cc6b45a4202ea5a1fc930a5008136091f48831e3dce258955f0a2fa95427a18ce12bc6d95424b983e2e75152b654a0c481014c6bc538354ff720b043f57c238c42ef536dccde3637babe7feab03e2fea7ddbdfcf1b689cea466c07b1aef757a7120141a2720cffda1ad422eae68d751425f879eb8e", "c65a1d0d24e1529a91f0643fac68e71da9f4d0eb56aae99bc03b600daaa127221dc20a5f5060820ba6cb1625382a4adc47185c0ea77d650cb517761a085a55e1a306c6136ba6a03d254079464ee8022a7e0189ef458fb4587b53fdec7864c90872bcfc5476bac7a7af7b104cec4cea576ded30bf4e24f80513ffef05b31e5031a2dcdcd2cba7784869c211c2ce0a3a65814fec0f153de0b8e327ecd2b0ce80a9bf691c1c08f5920547a2a08d749e229a6eaa4b770db54345c18ec3365f68fab045111d0928bb2cef7380dbbe07f6bc4fa3bf340e8fdefb1438188a474b206b430f988fde41f96b0642484d02adb39aa8624d908e52cc7fd3d39d74e002ea04a756b61be3f279ccc7206ee0\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 2034cef8731f5ddf7533380860b7426ba0a7ba97199ba332efb7422578d346ede8a41c8c4488d52cf2559706f1a677edbaa50c5783c00301cd41815e46c588e2e8657ced9a91f1b2e61d51d5e2384b59b90c78c8d5607076130926bf198e0968b239fd8d4451dad125467ab895eb3ed450e6abb61d6217c65ba2cd2176e2532594b5a09bba689ea1562d04527de919d47c3af5c2c24698e572f3ea289f5691afa164970daed05e83c051e39a99240a4fbd9c2046ae742cd1035aaf0d0c20b5ce1d42a08f9175d5ca30b6f4a7345b4820784c148a68f92be82f6e38638c1f8ecf8f07df3827f9fdc8469049d157202f31d98f06563f737ea3df3764f4644d9f9185cb2739c8aaac86e9b39fead8e03818550a25997c31674d5e14cc4c13790e409e278d778171c5462f689b0ec344f9a920a312ae9351c7d51ac7ca7783038b3d5e59d79c4d89ed4d36152d2a1baff8be23ae1eeebf6af20eaf093604cbe79fb93b61478d3a1bea20e1c6c60d63cd3e09920f521e3eb3e40fc21fe46103f3194d\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 7929db7a0ef0e385abca461e86013785f72d60fa4cf1c97b1a16e7b501235701aff06e71d981ff75392a27a266afcc5bebef5b1dc09ce60ad97b1722baf70b7be33b09de2f203f92a527a123e929b038428de471fb0edcb8e64741a1484ad5d2d5497f91aec6d87e5ca95fdea8962b61362bca2d0a4742f8666f1b067da8db4fa24cd721440d6582750498c9fd319d5ae5c27c9b70f1811d90b673d0529706d085fc78d73f933845278e36e96c48194f1494a1b4d891f249e8633c03d9c564534952e98c059dbe01294506d9238816215028d6414b954467650820e5db42b7701adb0d694bf2c00b42e89b80839b9f35b4e23ea70e55e514c50e9ec197423ad28a5dd4ece946345bd6ba154c122ba356320c2c1cf0ab4e0c713db0c8296ff900a078ed5f0ed1802d7f1f92c9305c245471d66820d4230aac6cf9a4311f7293e1d93a5dfd529dadc6699aef4c2ed53bcdbcbe8deafe5f9b035a6aaaf9b2d8eb23dac290f828bf1886136c79fdc915e21e06133f24e63876514abc29d25c146fff\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 5ed5766e97ba0017cc6ef508702d74049112f588e8930c3954b43c7398650fb1bfb94cdf75ddcfad8b50c59ed05bf8c32291e8b804f49fd5faef0e39b922e14ab4186c575cbee9cd2677b58cd890df072669c3c26845d7c89420cbea27d8c1ea43c2041a95852c85056e1d22c0cc9ec563d937fcb1d6d024f3a1a2943f77354885b3fdcdf8945f7b41e1f5a3c7cace9bfd2bb845f6cfee05f8f4680d1bf2b9d6510a6d2093a12214396ff02bdfeaee4b21af5d52244a3cf6eeffba75e946b83b5784b3bd98e5e585032fc88a1abdb12cd30c7f412c72d2e4957681f77e4157760c067a9312df871c972de688a839bb155c9de29eacd38ebea064f53f2599d08d6014c0f77f3ae121a4508c30eb0c8dd49c4c0ef31cacc3b1dcb2240050db157299260e9fc52dbfb530af6f759dba3764e4eeaed032e564141fc102399433456b91a3df2186ae9032957276e691c095ddaeef7142cfaf5bc86915c27461c136c1381a800bc3322c2dbdbfa83374922d607720272c8f955a9a10814c4bb9587e5a\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = c3aca8106f74c7733cd1bfa74419a2cf802f12293693c1a207158d52bfb728bebdea14a885fd52ea5600f82020fef8fa23f9078fb9ee34d82eed4c76b1312e7f50d0165792a938d264331da446b09533a0084e7398718c9575b66a07b7cdc85293695f291fc1ecbba9e0147320a557fd015a1339ee323d6706af18a08654564c49d2150f5d182a44f12e5d02b1839771b2048dd04c116f961e4af1632043bbade7e993b416c45c61e4a742bada5ad14dadc263431bd542050f40f4db8a95dfd24db22e049477f4ca93375e1d19513d64ecda0e9da1166da426a0c8614524471d72d413f2f6822843154959239b134033c876b0b68cec3a5eac05d5f179f70305f1f2ec7ef9ed17e79598b3d2fc148f9aea95774918aa6be14aad89ff5d612b13fedc0937bd1ab01f05d43b5f7c131086c63f5430742a347cdcecb435912d226ddde31250c3c0ed6d3ac9920873c1e73970a9d44061dcf6e0acf1a2935bcc48e2fb76ef74bb5101d0bb1a02fbf9a55ec75e122fa4dbe210836873099a1f91af20\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 4ee617bce690f21a6cd1760d8e7c41ec1c4bf0de2bfc4aa85002c278eeb63b568118e4ea28cf795a673965cbaecf1af5e4943b95c0fd20604911477492950fb99fbda4d5c0ecb11d954c2bc0d8522f5ee7365427d59143b261d6138aa2f27ee1a60d64f1f491b9ba1adec8d09f242ee0116e201a54ba968ffdf39edc3b314e8139ea8efca06185840ae9a3996ff5ff3c41add6c4dd6ecc3943aa60254859db786a0f0500f644e3d43e348b993439cd021ff0b92d05f327d6bc3c11ebb2f8c1812dc460d4ecebb358eee01fde79aef408a6b51694a2a2f7baf69589f4ed152026303290d9178c9d580421996c89e94e14ce91de0686d70a37241e48e439bad3371aa900d0d6142867ec2177ac21d912eacc5e2413b78b0adad7bdd0f72a5715c69f6223ac7ce99fdc20fbc7c603371c328eaee80f94f079b935713d38d83f18dc810dfdef5f1221ff8a24abd4a0de3e5d3f993bd5992280b06bab17ec6e36b27b7b08522f8bea3390590832da475e85ad4b898045930855be48bf2d56603b7485\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 5e8f89e2720d8edfa1a943223d6445bef51e330036fe6efb07289dc1388098aade647cdc9b363b4108a900611a1abdbe53415599192cdd5c39b4e467073183f4732e06a58fd43dd48d378495b2b4109d62042edecdcc0a93df468a0f2f96a4957fc744cdcb891484d7a1db15a6e2da980a91942814c5a9910dca32fbd27e2fcf862756a50658c8531d12ae652d088b15b674dd4bd895e8cad8d81b29c78eb7cdcd29737c8e532fc0c8128222120dd0a4da19d00b603f6cad9d6dd559230e237197269aa75f4ca4f361e418493aabbcb0e55bb3aa114c5777de94e53abedd9e358b2bad3fab666693ad525b1970b97944578ea65a15e31bb1721776bd9b91ac9f558de32ea498948d75d7a7a9ea610bced38be4dad797dd5651eab3b972915ce41aefcd28b641a4563b71b491c2322af7b06dc3f6b6e70ee40f25b6731a5f34ef7726cbf19c65b26d3c4f0a673753c6bc538841b6bd6efb89fe76793ef7859f6866e264baad2a7e1b1c3905c04e1ea8632aefe5c158cb560eba262aa7a3a6b143\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 4d0da40b2f6c6ec3b8de97593a591681c69853847f9deaba86baaa69b42bfc3d8fdac5fbb3faaa7a5edef6e7ca0f25ae169c6545f26c908a1e3bfe8f0a385c584cf3da930acea13076d475e9b428ef9758113d3d8a0e23eb2dcbccbb1ca0c9b384aa760d17a5764a7c4c709cbfa9cef0ba5672cba0deb198577e3abafb2176781956d0c4d39632fd30f778b8da3da16eabf3caece2a325926dcd25abb0bf743b9ee06a3b4496d82489613b0a720353b017e72c3c43eda97c6444d8f2edee7a444916187129bc0e9bc20e457c0946c767d3b32866655742e891490ee996a3b2106cc024c5da94ac89dac17fbf0c97a95541f8283510411868863e68d9efb7ae4493246b409441656ad0eecd3f0d84c7fb16a593cf0e3b5ce01c142da30d50e42f58c7bdede2dc350313c480a644802fa10fe117c98a92f5f8ce6c9c4cf3ac0b01ffa629dda82c217171a4723db2ce751d4a359dc53dd4b398e7882a8c88c9b591856189a9f9afa349f02573a9f07c6cb96eb41cbaebe69dd82ea7d9b860b841b5\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = a5f338d231cde9f20f87f69ab54147107fab298cd79df6635d3ab882e8682d0ce5bdad698bcdf0260b11ba11e5db3e857490f9ffcfe8fc98b8c89f09903f984eebea2ed74c73ac578bff3af99d4fbc33587d91518a948549739b0ffab4ea6a3fef5726eaf3ce77cefbe4fb001386101027d78b04ee5f23b6a7b0b5ffa9b473e7a86d076223fbaefd1f5ec030b5fb36aab0453a3b51440dd7709b78c0395e3b43ea873afa61e2e391abf0ff567d934c61d87f15095143bf660b73e2df1be6734064445154593fbd304f80a9ff730a66f54078142ad5c49e77b55ad5de5d974ae09d73f4fb506099ff06a226de67d55665115eee485372c19e599197aa561909804462dc0ee6d233da9c30fa7687d4f0a0f764646697bb93d2cd8cb6cd86cb3143b043f54448e032e8790e856604977e23088b69a57d4677e073fac808c8f65240f7628d09e0bc74bf7d6fe0ab2f7378808f082219edbdc1c1d456e4bc7dbd8508415917ec0d5f5ea10242368b8fb75cfb28975110208788b5696e34589c8a48d4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 715a8b585a2759b9fbebcb1683dd7d1fe956abce7255358e05cb19547a92083c2b5abe5c429c2a5527bd8193a4d05a0a8d161fe71ba612cc8aa3270a5b8186ca3f02ad716d78b7702c20f7bd17ba01748d1b51e52b6cb6561c13", "e84ccb9aad4f4c241a951f999d4b7b60c14021619951204e046d663a011eb9cd9bdf96bb2c43d6f8bc97bba1b63845db59268a3ec918e198448050332a540fa49e39796220fe2a97999160f564baecd0ebc4be5030a2016961f9f352d7fb04ae9d3218261a510614bcdcf33ec274b31cfd2d4c9462803c825e7dbb1a3b2618fd5067bf676c5fbb2f6dfee7068e84d4de68f840f97faaf880b8596d8847141ebd59eb9810d18cd95ab6a8b3bc87ba2e6bb2ae178a0e5043497b5cbce86508d96991c5f3d78ea3cd3a77be12bff0a0ebd7a3cd03b9bcbf7faecdad6a375e55569ac9ec02c9a319078d79ed2ec273078ef328b54579c0661ed64dd94883eede29818455b37b271c67b7bb303e743d6a080076bc712a2f22b36bf85ea242f2b8697b0b265102c557\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = b65f42ecb2fdbb8c231e201751bcef6779d0d7c755c19d5c82824ba34a5657a6187dea33ed2a7cb91fc1e5a3e417d806be4e626c555750bca3b45d0441865f0be6a52f5754fa871ffd1fd58b00f74e89eb60518330b21b78ed6c79fe38b8ff4d0f7ac49a152d1c54189e2eed31eb6211601b8b41b9a90e5e3d34e537b0af684133780bbaa4ae97c6dea9a75ec01cd00d2c43ac2c7d8deef21cd6c6382e2935ea1a0e350156dca5e78ba10e88891a5c0978859ac2645f90d5ac32eaf791b34a0c7bde0ce53572d2258ab7e5a9058624892d5e680eff78aa4232b579f94acad6081a7fa8330e8d3339afc4c57a48bd39279a54900e755f741aba2d5663e5efb738b38c72af33c13be9e996aa8c6df839f08af6a4961bcded7eed2b5a67a81c112095f1da9a3e6aa6e149715bb69a265dfb1fba8ea52bf7c8309f613cc183cf53890fc51e4c5f3d01336d67ebb66a9cb0231bdb1f99b033e9dd361262aa6c1dddcaccaaaa7b6a3e94c2b893304404c6be98cf20ef488f64b7540e4232d05b2ebe0c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = a0119ccf48d11ea14d4dd8a57d954cccb913fabc353727e883b53d6fed8dcc48ed7cbf98e3703c740df9bbecd0168b42e699c48841c0a964b40630f28076069a3363bb14c38e830712376d9beeb719d2620eab87e99ca2897ae1fbd4251f828db85c0c76a4554a39b2e14150b1d3020850dce02ba6e7619daa5e95598d50d9fb9bbb7ad57d60a4811d50f432845df09da1f01744138d10ebafe8951e111aa93b24588c803b37b12b2e572c2b46d13e654954828585672706a001dc4777c9b4b937d92a761ea3fce68c14379af6a8a2700cc20f25e47a0e4bfa85e2082dbb569522853a5498d539faabb90c479fc95fecf1ffcd3d03f9283b806bc6ab6b7310e72be66959082d631d138221c4cd81c46162649b25e46f9fe864b4394f8afede0bb4c1e148ffd62202141640555283eb683a3d3b1fa0a62d8380fdecf44d9050e06bac6a24fcfef1e2b04d952726ac9cfbd67ae3090ae90e16379a96bc7731a38401ea68365ea413ac757de058730259473fe79fe30e1b50e4ae66730e489a61e7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 21f59c055849cccb6dd90d2aacac59f987c1dd44f560c7137cc762f975a7161edc11503a838e4ed98cd8c630b20a4c43bf191e26d4d4f19b4e714d92cc45303c14209989cf10f9782d96f31ed8d7bab24ba02fc114d8dbd4324bd5b198565bab012bb7fdbe6754ce6b54666484aeb42952b055fa69601a16cb86a20652bd091859904bee412c53759137e811dce8eba60390b011b123ae6c1d6d76c33acd26b54eea627662cf1c6887f8c5b62121064097bcd69eac2b2e669fe8e018ec3fff888396075059ebc0289c8925538861246b2606e878b4d93c4c33c3bbbe21cf5c861f5bdcc9121cec2d0c4dbe3a95976a658c8bd8ed7579c1c6eec248317ae3d3c73e5104d377ed5634c16bf49e65879db350bcf5988b99ca124c3f5c4ef52b7f170f5c48f139151adf8d39dc1013d9a152321fc5784e1e81d3ef1cdab8fcd83623453fe4ef7b825b1baecc5817a13b56197e0c0c35463f8f8d8bf2a1068b8555aeb0e099ff5c9b86aeb6c495f6ebe6d0d6d44ace2ef80ec9fb647954a9137b9cc6\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 100e00b23d1058916a2d99f5a1285efad8c62b8ce779a558d9256ac36757a024bc6f72aeb307db6923d7407ccb91d1388a525354373619139eab0cdb413ebcf50b82f19184b2187eddc19b2c0db25f4145b35111111b98b109939155f008552ac863a7bfe1dca6bed2c47cebf48e29328c475c9c34499b770ff42f94878cbfb29e6254f89a4d49f5b886d355834c3eab27d65013a5928e6099fe125e61b8300e68fcad66e8413404d6e0eca34a8701c2575089955cc13fe0c0b3e7fd6a4bd296c88fcbc71c07bf7278a410b90fb113bdb26db1738b06b5d0b559cbab838d4567754a7154e17eb7cc4506d47ec99640c51f1d0134da884335a3d982078a5aea7543ad3a8db51db9bf771656105982e0a85b30ff080ad7153656d52ab2a738b5e8beace9a74d9492cdbf079a8293b52c8284acb1eca6ae8e0b47b2d699d069536b62312ede061a8dcf651d3eb4286ed22c6da22418a5856cded4866f74589b88ff9a3afa0479ad7964cd567953510df300cf3a3443e04495cc0fb02a8ed9c352e5\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 8778373fedd6de294c9f7dd84acf66211883066ecd53d860d53031dc51e303841f14dceb8999be392a6ccd19b899dca89764db04c2308f241090b0e09bbfb60c82e460757f6da6aacdda90f1a853bac858100d701fdf37997605324cdd7cda6260dbc2fc40ffb17973d1d82715d59055f8d55c74c93c9d7dcab167e25d8d26e0d98b6a02e5087faf20b50e429fa134aaddd0213e938f6f6c03ee89c413991163746a7df66212ff7b03de95c7be90a0888f8791e3b72c8f11e310c291c3f316425ac2d418baf46aa79a1ecca245e0fdb92a0f4e99eaa8992bb0f5973f080f2c72b7919055e88026012d86e2faa008e24545c38470b24dffe84f12577a14311306a9293ff98e3c6c42cac10b913d912e5060651cc73dcc015707c429c7bc669204d78335babfcfc614d4019fb45be0aaf7ba50b7947bba652a2b1984d876ecdad54fea8ce3d1524e812fb2519c17db82f300cc3d7c163c8653b46ef233c1678dc19dd75e93d0db22648147fe17ffd841f38177033b0183ec70d3a060ae69a71f81\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 66f53d3aed293fc5a20d24b3a7a2774e12b69115e277894670046e3fe076d7ac74b830765d3d8b12b3979ead0d87ad3a0a8b3e677688f7b8cbf5e7ef7ed5a336ea144667a507be46cd3d9145c5ac552ebae558ee95d4e17c6e9e5d49105777dc1ddac7969318d03678e2afae41e265c61704b7f61cc3306b0ead4d0d9e36ffd08164f93422a1e51769b0c8478c9975e1b2244544252eec743da10d8eca2cf901a3052904e898d5018c0ea9923bb6fb8a405cecadd81a3f858e34c87c069897729186710de5bac42a6c7a19a3f7b310ea5dea8bba7c594ddd2cb5309703baf64cda2295157f8530dc5a46de57d3ea7461df8af53474b15b54644d6e724cf6684b72dbabd5cea129c80a1dd67f7b636b55ba6980fc123859e9a702df29b2fc3959ecdf9269246c4cdc05bd06dbb9bcdff693ca4d04170118e7fdf43b163831f0f6bb9828faa316eaf92a4428efed7b2f22efd93761593be714e9a85aa7b690472525bb0b2a28712f5f524ec56e1d0515ec7cc190662ed2be402c824396f7de194c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 6ff0c91199b45d05ff630f4b8bb84ec1eb03dc229b51ac817c210f6034e8f27e8623bfc1f8cb5e597fe687d075f289ad76cb2d1e6ccbd7aaf7812e49e2408c74b4b8869d4bc86db5c2d6f62d2b6c1aaffa76d3059809ef3945e7fad49dd198e132f2681c4148eadc808231b6dbb7a9a8e5b5361f23d602c0873ef6751cd353f10d1f922a20982d60d29bb7eb57c86d3337bc8f2bafc28f830e16b4684f7b6f51e0efc3cfbabdf76b08cb8b5770e9f709331053794e35e159ecfe46455bb0994b38994fe6f405b6a88b7f5912c409f9781767871b2ba18f5e542c964450a5dac4c82212945e968878e43f4698500dd10621f31eaf5ccb04551d6ed36752f110fd5cf3ef72b2c3369db93f6480b3cb01bef799007820b1f4aa34354ffeb4f7c8ffdc90e6d19d1744f27516d67d1eac69f139b5b753497a599e977f459081460a35c75d986383ee486810f1c6eab1836f7ab4b6cbd427fcb206c05d6e46c84fed94d065c22ca732eb88c02550dd72259aaf4afcf8da2eb419e81d4f8a8e914e903d\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 5a8eb1da635aaf6e94012e3d61f9c7d016c657b812d9d95c50f4ec073c662392c4ba98b5d9c93bf5fab48d724ea9a147b5b84ad6e169033f32318c6fef89b2733c9040aab0862fb4b049f560fe1b448b987d203a40f3f46cceeab0ed9589df97e6cd928fffc5d20d64a10b31f54bcb269f1522f04762b4935feb0b02ce5d9a8a0f99910a4fe237b00b3f48e44e04ee9f7fcc06252b7c08dfbab4fd27e47604f4022d3ca0aba753b9ba9b9defd3496cb0c752a2a4cd619755fd7693ee7116341f8b9575d13b4f821759055225d0fe338659c02eae9c528cfa937a1d58efd0463773a29e9b34ad3647487267df59b324f6b8e73ce0be930c5f163d43df88fdb54e761bcfc12100362a17c507adef60e2be506df242e81161144be1e4a29a3426436c0a7d0e574f9468acc5af42981d5cdf5775e2b7d4e02121398b6dcb2d590417c06f6daee42199ffb4a51b0de715676d3f9779f1ec051219057c75208ddaf3b4530fc0360d389d7f95fceebb0123e0fa25c5c7c7f4f8ff9d88a928d6904ef4b1\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 9fa960f4d424a2fd23f7cd07dc40f43fc0490862ae8fbe2399a96ac7f9931e2f30421692afeddbf00fa86731e6e6724f428a479b49af5af07119856a913fc9211c722a6d25791111650b71997c40a7c8b74b4d0efef376806099b634388b93da0cc5e3b2678c5037d399fb7770546ce572852b1f4461ea415c7dd846b5611fbff3a492203d16b18b476f48b4ec0c3d900054607843bc23dd2d8e4889ae2871774fd520c510b48fb25dd15ca9f09c4cad7adf5614813506511473110780457194d41357e2ebcff9e3f4819e70fb9ba71d9eba053946beb75147f47e5d6fb1ff8c560010c32fd708025f5ac3f201d9853184f7997ebe8ae6526f7c7f7d", "abbbf94ceec56e61528b321e5b9d6255b90f205d9ee6a1f86d52b97cef1764fdc42ed14c22675111650e2237be27ec2d1e9ff2a70ac5832ac5a6db325f3fda757dcdec0fc662803cc76b18537c03465fa51cc15c395369001bbc615334f3aa161304b6ec18cdc2fcc44873e22bd833fafcbfac7a74f30c44aae4a176f48f8686002a6d10\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5244\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 0000cc6b45a4202ea5a1fc930a5008136091f48831e3dce258955f0a2fa95427a18ce12bc6d95424b983e2e75152b654a0c481014c6bc538354ff720b043f57c238c42ef536dccde3637babe7feab03e2fea7ddbdfcf1b689cea466c07b1aef757a7120141a2720cffda1ad422eae68d751425f879eb8ec65a1d0d24e1529a91f0643fac68e71da9f4d0eb56aae99bc03b600daaa127221dc20a5f5060820ba6cb1625382a4adc47185c0ea77d650cb517761a085a55e1a306c6136ba6a03d254079464ee8022a7e0189ef458fb4587b53fdec7864c90872bcfc5476bac7a7af7b104cec4cea576ded30bf4e24f80513ffef05b31e5031a2dcdcd2cba7784869c211c2ce0a3a65814fec0f153de0b8e327ecd2b0ce80a9bf691c1c08f5920547a2a08d749e229a6eaa4b770db54345c18ec3365f68fab045111d0928bb2cef7380dbbe07f6bc4fa3bf340e8fdefb1438188a474b206b430f988fde41f96b0642484d02adb39aa8624d908e52cc7fd3d39d74e002ea04a756b61be3f279ccc7206ee0\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = cc6b45a4202ea5a1fc930a5008136091f48831e3dce258955f0a2fa95427a18ce12bc6d95424b983e2e75152b654a0c481014c6bc538354ff720b043f57c238c42ef536dccde3637babe7feab03e2fea7ddbdfcf1b689cea466c07b1aef757a7120141a2720cffda1ad422eae68d751425f879eb8ec65a1d0d24e1529a91f0643fac68e71da9f4d0eb56aae99bc03b600daaa127221dc20a5f5060820ba6cb1625382a4adc47185c0ea77d650cb517761a085a55e1a306c6136ba6a03d254079464ee8022a7e0189ef458fb4587b53fdec7864c90872bcfc5476bac7a7af7b104cec4cea576ded30bf4e24f80513ffef05b31e5031a2dcdcd2cba7784869c211c2ce0a3a65814fec0f153de0b8e327ecd2b0ce80a9bf691c1c08f5920547a2a08d749e229a6eaa4b770db54345c18ec3365f68fab045111d0928bb2cef7380dbbe07f6bc4fa3bf340e8fdefb1438188a474b206b430f988fde41f96b0642484d02adb39aa8624d908e52cc7fd3d39d74e002ea04a756b61be3f279ccc7206ee00000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 6b45a4202ea5a1fc930a5008136091f48831e3dce258955f0a2fa95427a18ce12bc6d95424b983e2e75152b654a0c481014c6bc538354ff720b043f57c238c42ef536dccde3637babe7feab03e2fea7ddbdfcf1b689cea466c07b1aef757a7120141a2720cffda1ad422eae68d751425f879eb8ec65a1d0d24e1529a91f0643fac68e71da9f4d0eb56aae99bc03b600daaa127221dc20a5f5060820ba6cb1625382a4adc47185c0ea77d650cb517761a085a55e1a306c6136ba6a03d254079464ee8022a7e0189ef458fb4587b53fdec7864c90872bcfc5476bac7a7af7b104cec4cea576ded30bf4e24f80513ffef05b31e5031a2dcdcd2cba7784869c211c2ce0a3a65814fec0f153de0b8e327ecd2b0ce80a9bf691c1c08f5920547a2a08d749e229a6eaa4b770db54345c18ec3365f68fab045111d0928bb2cef7380dbbe07f6bc4fa3bf340e8fdefb1438188a474b206b430f988fde41f96b0642484d02adb39aa8624d908e52cc7fd3d39d74e002ea04a756b61be3f279ccc7206ee0\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# em represents a small integer\nct = 26a03bdf11a01ee4ba476d721c110840d093f38ed49f406c38f1c46fc4735a29bc7deaa3336aea98f6cfde4ec8ed305b91a194a23fe73112768080aba2c9e152f6ad8fbb8401546fac21ff696fb1f52268957cfd591fab64bc48c3c87ae5b3eb871beb669e15e881c0a9920ee5f401910d3415850fe2267f5ed141ea6e69d01cde65fb0a8cc063c33c0d333b6c90e7838f97cafb7a8aacb14b499c534a6af12934ee0c7585bef97a1ebf74aff278664aad35138fca85f360ba259d47542be5f97733b8f5e7a39bee1772cb8038d08acf56d3e8f613ee48ef147d6f0c1f57b3c08cc68b1c8f106402baa6834d460efdb8cc1dcb54f79f2928f4509e81de32d9839f9a022f47a83d8616f482c31eaeab84318f898763de7048f507a517900666549cc093b3c8f4d68c84fb33190e2b413134061e20ff51b8da5545aa991f89a0f612b5b2e74b7ad7facc491c7bbce41799ab70be4bf96a0ec76017399662ef8a6d8b3d8569ca86b2952ca3572777efe99724f85fa0375b29bbfff7380c36e4c533\nlabel = 55aa28091a62698acb80855f292ce725f088dc8fe0045e9e49375aa663055d72353a67087466c68306ab0135004b7cec41661da3db65188b9af52b255bcc888300000000\nmsg = 354f2c7d123c5bd8675e6f05c7a2d2a68f9002439be237430993ea325858e6a3690cc9345014539db4dffbe387995de694ff13c942a4d2634caa52b8451d2b04815d9a764cd9c7576943b559b7639ed8c0b604c2e59e65af105988c71dc91c6a0970c8917b0e00d3029bebf66129d4dc60b03a846decc6bb2cba9c45f6b2eefab79a9df5bfc01d93d5aa6bfef888d7334fcd0d2cd41f7b3e1c564dcdd2eefcb8819a66fd703cbbe9a4d7fdede75fc8578b94f8ae0009bd188f8c7469d6588ef8f240fabc1ddb0174783967106d2b6aaedbc15c4ece1cf7e12ba1d14415d7261d6d56efe0bc93f6838569504a131a4e126124d933bb63f6df189145caadf7\nresult = valid\nflags = Constructed\n\n# tcId = 31\n# em has a large hamming weight\nct = c63dfab03faf7d5933506b3a7ead6c6cb9bebf25ff4afc5693428e988bef9fb508e9d50f58f8e76f26121eb98f036c15d2538f6c8d7e707aff411d24b9ec3fc5ebe0fe04de2f13c212f674585dd157f5609b9ec156a04642e1b087b6b3d2a7015324c5c3986fb8a32482ca52821c033fe499e41aad19a55d934d2b179f6c89bf3b34b20f2fb616356b13b4aa8041089d9ba831f0868a66175609f4e3cf067289ca512b0444ee3a5761b5b95ee79151eb429e9fe2cf946c8dd86d5862ddc33997eefea8e7912a340f3d1e2d5a69eb32ec2bc82f74c4e68ba8c565dad2e9c71b81325d76a3fa600120cfe96613ae89a4251200df79ab92b1f04d9ec34f61f4bc71f05fe27b972c91be268d1e52dc46d85911212b9ecf42177f3be164fc99d11b878f1b85a508f13f583b4a0b7cfae186c421b34a997e31c594b7370503830ef7fdd8b50198def928a1075594a6e0b418e5361cb186fc3bd4ba01720081e21c9646aeecc0882c847871c894562508ce3320aec2f9b04c5b25975c9cf5af7364a3e7\nlabel = 5360d4b1eaf5a46e6f6a6ed03c0d405e7ed7fc2cecac86bf3cb27348f9d66a7bdca863e055ec1b6a5b20c351d63dfbc7eb599589d69a46ed7eafcd2ec117547b00000000\nmsg = 5265a56c99e71128fdcde31cd5918fd7e964b9f1d216bc9c4c10d6ddd3f63b65f0d3041f061c6eaa6f60407788d", "77e12b4e7b3b2e3751d2f1774d626e83d195c5b4d23e3fcb5f50eaf4252d720737b2af5a4e1928dcb7fc383193dfb13ffc6cafb3b609ebf0395508fa5124ed27207bef82e59dde2251dbbbd44405f69d771ffe54d269d417c42979dc014c1579ee58895475eb014ebfda48971ef3a08a3dc4f97b9b996ccf293d7b8f40055ed842eaece6d7fc4c76cb342914fe6bf89beef8ef463a048ec18695578ba514e5f6dd5813c58c7acc6f6eb02258dc3adcded16bc7cd3307e73445dad5f36e7e230dace3d4bf568daf408b6e07fdb365db5ad\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen149 = 40513; +static const size_t kLen203 = 40513; -static const char *kData149[] = { +static const char *kData203[] = { "# Imported from Wycheproof's rsa_oaep_4096_sha256_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 097a59d2c4f70377793937bbbd95d19b5d01edfb1eb3b073e27e4cfed416820d4af4e04cc3f53d272ae43551ad0cd09b89cacb21a595f9f8423b3b0148d2ad46cf818fd9e7cbba18f4f84a1dc18f69ed5a764c6fa191a3664fa94a39bafb1a29431e6fedf61eb9164dd7684f0cb506248121fa948a32c8733f3d9453dae61c8708b2500582f32d91128775265f18bcab6eb170145e33dc40f1bab451194cf8c38f9fa91806bd225fa4b54ca50813b9d7a54f61e0000e5e0769cb2a3eb99b1ae9c3c5416dac83a6f91248c734d7e63291ce12de4d780703614128f878f29015801c7a5ec7670e531e1573ebc8ce63d640b01b9aea48b43d1eea8ad85b55423d4e142bcf73315f3e9e978b65f0556246066596013fad97b83ba552140c6957ef443ccec4051b2a8c9cd9f25c4cf6bdc2e904f46063e319643283462a4047d49c38bdbb0ee3d87980ec08410d5d2dee8e5349958e4178aba065a55d79d89080570fd4af5678b1573e42f2e0f863b31bb4e19ba232c02ae5b8f948d1ce8145c4968d24b56ac930b4f67047257f3c0b86bce7a77b8d0d87124c4a4141409ac11377fb9fc805d60012386becc2ba8478e663becc3d73239ce3036c2d2fc9e6e2e370c2c78053ee1bcef7a87872ef92b784638b84713a5d78ba8c3a868e3466f2275b252e19766d2104ec60537bc1589b1558b76643751f6a60fd8a5102b6c788e0f049]\n[e = 010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed]\n[privateKeyPkcs8 = 30820942020100300d06092a864886f70d01010105000482092c308209280201000282020100956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed020301000102820200097a59d2c4f70377793937bbbd95d19b5d01edfb1eb3b073e27e4cfed416820d4af4e04cc3f53d272ae43551ad0cd09b89cacb21a595f9f8423b3b0148d2ad46cf818fd9e7cbba18f4f84a1dc18f69ed5a764c6fa191a3664fa94a39bafb1a29431e6fedf61eb9164dd7684f0cb506248121fa948a32c8733f3d9453dae61c8708b2500582f32d91128775265f18bcab6eb170145e33dc40f1bab451194cf8c38f9fa91806bd225fa4b54ca50813b9d7a54f61e0000e5e0769cb2a3eb99b1ae9c3c5416dac83a6f91248c734d7e63291ce12de4d780703614128f878f29015801c7a5ec7670e531e1573ebc8ce63d640b01b9aea48b43d1eea8ad85b55423d4e142bcf73315f3e9e978b65f0556246066596013fad97b83ba552140c6957ef443ccec4051b2a8c9cd9f25c4cf6bdc2e904f46063e319643283462a4047d49c38bdbb0ee3d87980ec08410d5d2dee8e5349958e4178aba065a55d79d89080570fd4af5678b1573e42f2e0f863b31bb4e19ba232c02ae5b8f948d1ce8145c4968d24b56ac930b4f67047257f3c0b86bce7a77b8d0d87124c4a4141409ac11377fb9fc805d60012386becc2ba8478e663becc3d73239ce3036c2d2fc9e6e2e370c2c78053ee1bcef7a87872ef92b784638b84713a5d78ba8c3a868e3466f2275b252e19766d2104ec60537bc1589b1558b76643751f6a60fd8a5102b6c788e0f0490282010100c3c677495c2bd56619e44e26140d2ede0037409b81f3a5b3886a0904eb486140f43b8626af13d14a33918eb72b786b3c9114f39017871528953c09104e1fd2d36b725388f54ffea30373077895a6934ab174e55ca6a12c21923a7b775b5ffaffbd813f9fb752805b016a5735b883c639fedd55ba2e233a6dc1673063d8487390d1676123544d3def177a91caeef98b13f38860474e44993d4c6060926d878a2059855d0de1c794ac8dbdad655fbbad20f152f15c73b95ac544cbb87b8bec8fd3c007ad09d76ae22a5e993302aa72f11deb265a7f28b88976af5d0c912d97b7284b1783c5bc91a6dcb7a9b97fe53713965857742b7e4032dc5141acd4afd4771f0282010100c357cf685f9b8d4e59e96686f7b8752f0a982efbe6658e6bcdb615d921f5e7056882825347455782d7bc78d637e17e0e6810c2136ad81b16cc1c81750785924616f2bdf5964b26c7fc50fa98fb67b746b50812705b379f5deadbd11dcd2fec7b724d042aef25cea2eb37f85b7554d7ad49fe5f47737ff436bded418507f2f175c695e324fbb11beb0544a7a7cb3f07924e291b5c8ddaa6a7dbb07e23bce1960cb52b9000d3a7aab1f58e3c750b6d978adf3d085ae7693b7e6a46cf6dbb6d2ad981f4bca5d15e0962c39066a9fc27985b9ba1f51132355792796a5dd847400804f98671ee4899050bdc2e7872ce6fb2b78b1050436d882425ee0745546a6a1c730282010100a6bbb5460638d2b2f5242aa6657760cdf3731b1415d5f2ee77248f6fe00e31bdc70396da054ba47844791809c9fcf19f90943e671e928e23950d9f4e82aab9bc138b37b7b1ed2219a54b67367c8574762db237d0f39cda5ff110dbac286712f69167ad4f122b3263cf4dc8de58b9e9ade4f08e1d5543ed74223e06c9521f4a45310291892c37e8a262e5a19b2a71decfec1dde997c00125e5158d7867dbfec9466899d59c04b60c4a0a6c5314c1a2375a5f194dbbf37422635d426d719b12c41140fb5806735814ec268493861002977e8982e8493a2ae78251be32315a85b75f6961d44dfb7505c34135987a2288907074fdc015ab1c45f3cd8e91fee6bcdd302820100178cd58f72bf5118da141e6d351e42da69ff90e2839348c94c62a05dae0f744b9d9ee6515ded4930980bbbd1afa8fac687db455a8bee03ce0acb80fbf7ed2d864fabf224d27abaf12f45200123860c7d74c3c55d5051f35fa239e00b24ba9b5b029bb05df0b8f12189141558095c32284d1c62a63d917682c700fc7e2a482abe1533eacf819c878e1cf37af6eab4ed97c0de89d2edb327966310f31421e85c6ba9c7d7b391d0cbee6a793c66abfb09630fa8cf020e960c3b205aeb15029c95a6e558f90950a572a23a8b852507264ae2f86f5d1936a161ae61fee5d3763b8cfbf48d35dd1159895735b350881ec52e999c255a57d6b3ac0ffa935bd36284ea6b02820100484ad86e79415ea3c78af5f6c807cc99decfb14ca1e80c8e6a1ef00ee582d3d180774236a54ec9dc8dbcca51f4da4379cf634f3a07cea4b7748d7b5d94cacd4d474111f92d19f3ab5eb4def8dba57b990844efd28d85344666e283f5d5fb0e6e8d96f07411c882bf280446e49b3b9b15218fc24da34ce8f01e02735920ef48a343b4de11f99b26547a251afa7aaa69083c421e2447b1a989d50712bf8fc35882b63517c7c39843cf67b92645b68c6d8f90331600142e6cb97032a5af6ef7c20f87630c6b25dddeb57f2cc0cd8c8a0661b5f40ed6632989f5d40f33bbfd9be09374483606c2cd7ed8b5fcb8bf3df1f9368a13922b1240c0d25792505b857d3e8d]\n[sha = SHA-256]\n\n# tcId = 1\nct = 864915b51654401f018ee23280252369c2a4655156b167747c886796da7fd08af0e5ea3e5e477ef31498be2547e78de91aab3283aaaead23013a01cb14cbc5ccafb27b345af079fe4520c6fc4f4395abe18f8ff3525b7f9bcc1876693800de79ea33fc5c3aaeafc9e4c97535033708b77516a891fbecf160fa3f98ea6b0b7fcf69ef44c470df232a35c48e758dc4b70965d2c2256753afde954b642fe83d181759949a901558dd0c88cd20291e236581199cdca2b5436a102fab4c6c58d5c8f2e867a046114e0c3662bf115126aae27a66ce932b4d9603e14fb3769a2b712e5b332ffc1b615bf9116455cb802f907a0600d9ac9d292a4582d356b6f8c06d54f252ff17d1d4d07ae25ba1fccf3ae9b372e2b8420de1b9258217c15c80bf88afbdb5a879fe31fcd7c7a275f4b7432921b8de5bcaf43ec8db6ea38a962b79d810904406573cf3c40fc416dc5f8d2d8feca1285748cab7d5335cd4c253b656b52e9ed1b8f8dbc4cd93962028f0ac1feb7d4f754c0aeb1c31e961f25965ec2328ca7049661e8528603c117f9ed93b74bca5954936546bf729e4572682bcdae42f0e693fb3d05de3fb7f8728825675268438339debeded1c2d50bd89128b41cd40cbb6bd68564494b06c9bb43e3ba7edde3f89933165eff31ff255e1174d51b885b6b61d4d3712625d78423640fe911e761fb05bc702da7bb7a6819727dcd892f7462c\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2\nc", "t = 0d9e70cb448371ac08d862e2ce2cec00ec8cadcd05aab58ce26c5c098cb8aa64ee561c446392253b3b6349c286f1222a3650d2393aeffa1eac0832552a43d11f7780f6f219c8ff1d1c98bb085092751f479aad553b0243537a23e53a9c9779e15bc3c8d8a176693c3261b4c0520d634dc5b3d618565c1428cf9d616c6bff17a4d0dceb97339f5556f0d96f28b187309a48174651383989854585ae85d30874894e6d54a3a65e16917c751f3edf1d1653f22ff5d3f1eea35b390c1df1912469db041559b9ccf8148deb9d4caf8cb587191049bc575cb20495a9b0837035d2b8c47a74190829e13973b5b72eda42ae1a7cf0022cca75f86f039c64e16797836c83bcc7c638d22fe1357444bb4e42bb1410d7b63a8c122006f45dbb942a802aa4a964c6b17f21634e0e029a9a6510158f88dc05f9c6f4ae024c6f13d32a4d412ba0dd0b9f7382a1771a61a35fad4e310becb6a5a59dffec526a9e06d9feb696804aba676d0d9bc043f07068c7882b1f8cc19033b78416d64d5c6f4b2d121d170e4924cdb9a7179ae3a93121b814fcb74cc25eed8ab26b12890f9392debfa3c1b9382d41f8bf0d1b8cd40a724478ee753c70d3f3820f48b6f8d71ac6d62d4e319659b188a24b586521986fa3ff61b376e6a78a8988441da519c6f986f10c32bce6ce156ab0e2e1d4cd1f2765d0cfbd8157104b64709c4f8380181f8021f9fb153b15\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 40d37ad25e0f854b3f3431c1bf0e24dfdacddd8985895dd95f95d5b664e03e9f3d6c006973be95f2b17621615b8fed29aae91454a4108997a7dde9f279a93909782bfa6ebf7eb69c198d656752b980d6424f054b3458c8b772f509981209e8514f5c366d7a5272ba91072339cdcd81810eb2c27f47da51e13225e564ec772a0cb40c95a295eddef2f5dc6fddbedc8f7c2b141049979b7373049cf5b8f91b093fa2cb1220e145e5fa8bd1581dbb7ff6f1e28f51f15e67350f145ba336d4a894a1156ca2cf35cd8a29318d084e28d4402529551e8fde5a30c8005b983705cc67a7cff211e2a23065ef9342d4d065405818997126e14834b4f3073a6845add06853121bda9df7fc68e2516e72515d43ace942ba26c0bd36f58e93fa586183533b82cce7c8610b15ebd305d0be2ec52636377cdddeacd4eaaf84fa64e7bd17dc2acf0cd54f75181a7e237a6b1cba8514dac2c0301fc7b28ca07dab48894ed25f0d2c4f755cb6b83eeef73107338cc9bb21bb16bf8069f41d5a86b37f2c4e9f793d5226a5723c5c95da151f663e8c96f0dab2af01ece8ca1280fce698ba99d033817f79190c7e387c71ec8c70d04ddf965afb5e0c106e1ad913882bf6295b8b45d6859b25125e0af2514fe66c40381987ee925e6619c9cdff3ec71534ea1cec815bd3ae8a4f66ecea466d9100dc1c94c64be432d8fc9973426dc2041583a96e68312b\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 3d8628a19ba75e418329363a074d5992a80446e9791583095c23ed66de5dd41c94db742324edfa2a8807b6e115460e48a30898c1cf94d88edd54e400e448025e44d35e27b89509e4bb5e73b5dcfddd38939180b69ee551aa3eb74cb3b4320127cbd77fd51b28da7c74871e20e5067ac610053fefed9cd4599971e219849142dcae66ce97d13c937f8812d619b6fe0df57abcec358341f82ffe13827fe7e8e26c1030f821cb1d43a8787ee48033f4f11c901adb48e7c85a950b3502fff2f12695df04d55e1c816464a636981de537d1b3e66598759c8b38e1d87b9cf69c752982b6b54f2398f7658ab446c12585975bd3154386accbc9b796abf8a1c4cf6ef291e9cc519bfe2e09084a20a88d1f2243ed8d21d199f983df56d8a176603a9036a44c175f1417b7d34ea95c32993c0cb6a029edd753c10d77944b666f3fbfd743adb9e6b60c06e83cb51ddae3f37e3632e4c2b547580dc1ab3c7c94c6f09226dca4884affa94a0e119dfbbabb42a85a516375f767dedc7d1e0cffbfb44ffbfc7534cf619d1f926b0f61ddf2dbb8921e9b27fdf9cf52776e0b2adb781a5b110849c4600399850bdbb155c2523862f61fa84bfa9362cddac0a49e276c01d31ff4ee6646d914819ed75e7395e04cc741a0d7f61503d940d0ebce7888ded00facab381e912fa737c5d628f820650cb9b867cdf17ff60f145fb2c107203fca793503dc22\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 64d5b5a72e27de69cd016f58fc0f7b1a4608376f0c9c51c7c89ac24487b6a542e414606aac2f00892e8a72307c9167d48d555d3c46f924e95b2f7ea6451fdd6eb7bf14c5543ee45ef6c30d39c9c31d93fc807d9b1ee85405c38a5952d1387e393ca9e357d819470f43cb202dc1275b91d0a5dec0b7b3c547994024200275bbfa9acee80b6adbd742563088bda0f2fb6989e78e2464f0b7a7dc96701792c365f9ad1d8efd0b3842bd407774c4138810bc0c7f5900e50cfa5c24eef43d52be497b7c8094413d543fa3474a04580448d8203661d3ad87e997777c112161af200af2442f591c8bb41f337c1ec11821166cbc3d2f264f27eeb2ebe05f68f610aacd58aab3722eb38ba798e9a9c083dd335be40dd65978cf0a67d0e78a5b9c77034dd7dee2ff87172f98b61899d76b384920570ed063670b5dea2e644e538e7124a4b8c9ba5da4afc1e1196ec194a797bb2c3ff90d8957ae7bb8ebe99b69b90fefcb876752cbeeaf4f921060e8cf420463152b32ca55e39e61cef5ad4ba4b0ee4a2eba2d784b27ded395bf85db2bc85eef5e0cfb8fd0ab3198ba5aea550fdc866b828b3095b2a8d4b71a6e20ee3d572b94cb4f6753ddfbb144b11266a1efac7808931bf3763a4a80d0bbf475e5a3d237eacdc58351c1400d5bcfe9006e6483cb664d0274c5cf12d2a18038b6e5643244e0ff07072e38eec29eab5090946e73b01474c4\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 286d5dd2d8141c8f28ad5834c57b729f39bf5f90a087ee09eba1013208793361cb39d338b4acdad72ef3143f45c6092cd790abddb45d1150abbda9c70f4d42abcdf71648f63172062ea5b64629430b5e3b88021cf5fbb63dcaaded696e3d6ecce60a1346d75a972dc6eb6f50b5ffb7da7a5b7b7f8a5454f9dde9fc21ec497b2223b24e3dd579e3c0518feccecd2b3dd91ed6a26318dea80b1eabd165a87bac00040c29f3335a7e474cd01cb8cf2f1a56e27d5377d17da3ca581e84149852b63868a9de2ba8846142b07d14ced219ee0fc318b826a35f7806fad240685ba4067949a79b9fa3252495f14f49db5b4a31710d4c1d04d8a2f6e7121762cb4873d1d5ddd05c2be9f8c09ce5e22e15342ae22f227d940c8ce9ca62f4fdb080b85a447d2af34acd4e77d126792a69892f63356061221c0c7105dd5e044bdaf073db841f0f25f957cbe259a2474b7cb6421225add558838757ccb028ad426ac1b75029aa08746f9a47df7df604cdefbcf4abfa92e114da11686a6b2fbdcfb9a6bb3e676a7bb288b88a9c9546eaad05a84e1cbfb22503e326c63c15c2c634085d2ad2d5220b9c6a7a51548adf4474145cf3045aff023c27f92c098d77f065ba59a530ff15f1f0cc634432a3b3fcf0c5d5cc58fe071deb4268fbf16917bdec618250dbf4d41efb3d13d0be332848a0512c5e8e6b4a6fd06ab4094550cf69d51e5321627dbd\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 815f21b2970412f0d01a6f7eb209b214b80a944718895712c0b17b86ae408b01d38636b0b10a0d50a761359b770aac9074d0a89a22431f031063d9fbf174a767720807d02dbf70f9c561214c8ea73bdb37b0ddc8ff2e72e744cfe48de0e2188f2c034d6a779434a7e32ff44f5a9016cdca2e8ead252ae8fa7b5137c033013dc1a74b5bdf048bf81ca66a424feb93d2579c63f2aebac51db1535217341b501557c7e034a5276c8279d46e8724cf0c184025f8862c22a64d9142472c098b8974c61b5c8c998f0e9c8eb5525dd520a190768faa9d3fa58ee6d93f2fc775edd368ae734f6b359469f4d3211895f35dcf1610a4a6981cd135709b91f2f7667b7288db3337bd46d6f15c0eb26385078f3943ba1e67df9ef34f7e52630d5a4862dccb0477a3988f25d970ee69cf860eb4b56a85665fc47995befe817a4e3fd2b4f112ef60a52180adee5a11edb9ac1458c1c6ec41e3b9bd40eeb906e206b447b7538be7fc0170915b047c998b8baba8430aeff4ee8c48c763be4a49a8d0b8b7b45a2f0e0403e18aa2bc30e754982d6d1872434fdaf22ba6ab298ebe29a739788e377c51a140e6ba07545e97eb9b2b12454c720653504686225a4c7966a13cf0dcbe8e1a852a2d0b828b9e708c1012ccf401e7ac94c9fa0ab5c4a19f087761b3d1129317571621593629f9459c94b92c62dd5d6827cf1c5187e98a9c20d27c0cf4e4b18a\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 91d2e4d3a0be29f0dde7d2033e960301ff15e0fa649865781d97876e1a566b19e1bdb2f7f458a524d6d86e0d6f5e72f0bfbe5d23139987cf1d8cf778fabbcf3b5c10092fcab71b296b12bd56eb87093e90747d28a2a85bb1e62b6fc841f0da507978c7aa9039c5d7bfb8dc20008153bf81e94222fbafbbad6289c4fde8da4ccfe8142f11a922317673f94aee392b3d34dae9cda01d4fc3dd1136b7341f45af106ccfc8f71aede870522664494dafd9c740e7d864453ca9874b909bb08ad74c673e97ee78e816db3757f80d3c1edbad9133361160296a304420841c37b0de7c73fb6d3dc1c98d9c637a57d145008048e02235c51c141fc0d38e0815ceb54847a381f02c556d1ec28f823fb3ffdc98e38e9de7d52096e7c4901ecb03ca1725d2f386296ef307b2f4a0471ae3e8eabffc1581ac2e1a00e70a3cbc584f7efe6bedc8d437a412035e527aae977647eb7b8271cf9dcf361750720289218c4372448a24b1fa8558cb8bbe928ab734d66b210489bab3292c2745a050ebd6a88d38359ca463ee4aa29bf84cc09e69ad4116765ca079d5a1023796342d7c306fc0fe8f2ccff4c2b1b855077f752fae6232761d40fa9abe063125cc56e4efd234fe6623325417506fb6d4be187fcab7471c16e607abda762423bf4dbac021cb2700019a1862e32253c0a8fd3c443d381555a799f4e2df7d6d0a92fbe889426c9dc8b6801635\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 5399224a31e400c2e26dcb43e4bcc394b22b87ad7694e59fde38d7f16e3abf190c877f79a262b6e9e172659acfb37cd3879dc2d4d86b0f7672f297a569650a37b3392602b147b1b1110431a4615389ff759e6ab16371a514259f1131a96952af64515d93eda9541791429cd14d3a2ca29c279088607ebc57b887cbafcc88f3e7eb65067e952fae40301e9b784f0c7c9f3251287d279634aa92573fa33b7845471f96c915352618618d733706d2d9d661afbb04b87927a2589f46d13d8adb749d14eba316c9cdfa066623c9882894345033e1414a3f3430b551f7de8d387662f75589b7f55c9ec5293c1de87f7e3b0589ce9b8e2924cf7b87232f0da39c0eb", "0f89489d73ed6f7e73730d39823495cca741a19179093f15d6cb1518650c74138c1c1c7e4e65fa277757f17be457607c51d310dc10150e7b381eba75c607417449b7d1bfcd7223ea1d373826b623c7d1580d1e989060791f027adcb36e4bae8a7b09799ecdc0927256a218e24d1e4c51ef7d5f201f4a167d4ec77f0a77521c1747a67d413742f15b1393519758f9c98f3b621c361bb5eb9e7a5b904a324d98873d54944a18a87930a79d53332a9b8ab093afa12029406a078815b13872033145a421ad3b1cb9e7fda09679e7e75ceed95f934720e32fa3fafcbfbbeb028a62aeb8855569d7efebd70dc3f078686b54d26088c2870d698e42956e65312a57563a2b8\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 043e5e7106d5e9755860328c3c135bbd898ee93b09f329aff989c41a271d88239c9f079ebfc17c352124fd5a9d31265dd912ac24b2c506ad33ed33b5109e5f42a7e01cf4851c1246719eb1c75267edb673fcaddb07f0fd8ebfedaf7df9331f95bcbd21a766418badb064e6b0c436c6e21c74eee42e45e5d04d3ce219d089905eb700542144a045e0f7a94a38b0e20858ad94098e82a0197e077136352f26725e50d7ddc4771f52ebe4f486e1fe72dbb94f69968aff98fa9f5b820b368c60d82e89fc27f0aeff824b59a6e64a5f604df475c9e91d18911f5e0a20b8bba06d842d6a55378f382c0705b75a308b08a86bb37e4601903e18740d041c987dce213071ad7edbcfdc327b8dd6e8bf1d21c74f8bb0ef233340ee193ad2728bb511e7b7616d5c1ac6708ca3127b00a8e743b73ece1b007a09c74f60cefc924a0e04d967640ced76c5025246e888168dac8b3a9e4f16c0d44c8935fb401d3b171abd18b7c79d2f445cd22467c77d34dcdba4c01c5418def4c170189b396e4ce9216edceeee101c6b6df834ca29c9f2767ba5a1b14ec157c09217c28dc4db95490ee3c8d0059e9fb8314b4c89123be5e1f2c4bcfd732975550f5755a845bbee0c65aab017c25c306ebb43bbd14406be70e046a7589ca3235f529fbfa8ec9d9208a95f39cadf8b091857cbdcc6e9ef11439ba752b8d24d4c401f1e0862f71d07262f007e562b\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 0e617b28ed72162e19b7a80a8b57b9ea9c826d0ac8b230bcf449f027978034e1bdcfd55b89393643d97b082d7c1e7eb4f901241955ead53e18ea50e07d8818d01286e6c7f6a0b1edd82c40a18cd934fe4b117f3711f762dfff24668c511524bedbbf9248590b708c36ab59ea8449c9468ddeb978614c930d7cbc45e01115f5ec5bc8e024e6d4ba38cb8a3c80fa85142de7dda62ec3089c56a3a2a067b09a230890842e6844b20cd1e5143f4d149a99b86c162b3be1d98ea2850f0c336a9a0e1f350e4435b7d0ea8cf479f4c07b3ed800c51ee78cea37c628ad0f8d9d9df93c94a7b40c828927dcb7f53f705f9145bab0191ca8279957674707cc442482754603dce5fe9dcba2b0a545f8a3be70e108e4c7c9ec55f58c43cd654fcb7f0fe85dc2cc02fbeda0171dc5c2344bfd908692aab69fa50fc0d06bc7b9791dd1cd02f23e52fb26c7d017372dcd84f966b49ed939eb92b51d8d25cea6b25ba6593900075f0ca7fe54a43faf9686e35eb42658d2af3c62ec9b68abc449462342c1e1e4f5891d8a2b7b60446da02600bc65e9e48efb38b5ec69103a8447e5df840a266776eeda1864013fb966360ab45ba9410a2721850cd0e2672840c6efcce5d468a35f9bf0ec25046e47d0dfa4ee6241db8ea32125cf8a7ffaa9941e00b49a1cf68928d493fd1a16602dab0db580001bfece99fca4f90aa823717921e836b12ad2827e06\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 01cc477af0a4ef90faf0020641b6140a27ab93f44cc33a26bbf0a8bf451443db7a3b4625689cb4ae03fe2aa97efd4518d49148260e72120657b158a6070f400cc5c904b24c4ef187dc6c5deeab86130eb9eed59d75bf962ec900cb0b2df2a0086ea5a1ba9d85c9f71a5df2f61a4dcf73d40a1d6c25e5503316bfe9a2c58c3d6012367f51720baa470248a8d54c1e8cb5f8b1efe93f2bb7bb4e7f000e4c06df92986ee7743b9088571fe8b3cc5b16f35d98e633ea3b623d9c83e2095ae81b2877c36898c983ec58d74cca9026d3649a12248b09f04c49e3878715eadfd966af34531699ad173cb01f8d73f585dc00b8b3d72b32cd40903148c0b6167e4e80e2f3d29e5285486ce51dd8ad1cd195809a4ce6710776c19d9bffcc915da723493837d6f99a215ebe502da8cb4444b0421626b2eadf61ef05210547940210bc4e647193e0a7cf00a99cb51533f74fc29ce5fd4632862b8efc542a9ca0e2da81b50d1c72da1dee2bd9af43ffd5264c92e5c00e9cafcff11e5b4f9b6e047e5a19e7e599a736e15463b363f250a2e1616162dcbebf4791adfa8b51e80eda02a8440132a80fc0f0a2939f176fed967240ff457676c6deaf5bd76a3c826445ce807ccf4135c7c4f37b112ad2f6a10f213e4fa70ef872eec4a7371daf30ab6ec5a47bf8f1a9f6f7b3798e3d5bcc0d313eee136cd9c0d831af2ba21dfbfef9fb6142bc36f586\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 1c95586fb690af2cceacd7c9232c70a8a52fb37a7ce391e9da23cf087e3b4c609081977a713a032c4dbc263a369c9b57f7036f6218b9ba5f522cd965a34d8cecdaa0a79c97a962dd5641cb6b68dbc77018238489ca1d64b9d3a3beb33eccccf81de113073030fa54305d959180340c54c9ae4f3e5a3c308c150f0498cdbf23555ee5377805d2cd58e72d6109030837740131a6a7e5c894ce498eb4eeef7aa8099c727946ba78f684103a1bd386840932ae99cac1ceec176823bd4c2c5b7c7786e2f071add8a940edc4695d0e031c1466906b4e6e974f04e80d21177a21f4caf5e2d542d7574df82470308ab1215a83b9380c6fbbd34059a2896f156a076f13e95501784ffbeb42002c2659b88540848cc06da46d99dcb7ac4f6294bda2e0dfa699b1d852eb946ed4538b4b743fca2f1384cdd3aad9e863874448eec50d7581c96fbdde8af1d6496386cf49161df95c1fab9bb4f905f3dad3dc67bc70e21629e19bc60a2a9300b246964e5d7a5a56942eee8ac4676556283af90d27274bb9f460b3f5374deae951140d616c34905310a36b2c52ea789610288e60bad45c26e2df328161c54bdba8c7b25b077b2ca5ece64e59d0e35a052839bd762522b4a6e2ea4ea98426f7b50b90ee1c39b2ff1ccd1789188cc547645e96857f9eabdbe1ee17d4e040f2f34eb826c9a2f5a4712806efbaba70b3272797a26852704e9a14c50a\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 6937187451f030bb4e8da158c24989f1466afe60449e8f720abeb3ce766b5e1fad5ce87b6902b67daad9f6deeddedcca13be3a888cbc0333a205bbd292e0daa9367ad5901547b70de0174f644c3d824df3861a1bb6a14cac290e70b06935c39d9bbca33932f5a4cc18f96561a328f390f6e6b81aad21c090c2f0a654b18674448a9a858b6b2d0e9b2bd2782516e4a7b401e04845a24882190361278557785f7ec9bf9eee62162543341a8068018a92600a5ab037b9a646a294492e6b8776c2f3613ddea88ca7e840d89ffc3a3a112fc104d52a01a5493446c524a5c02f5f8aa393c3f46cbf05530bd70747ff7dc95f021dab34c617f550f40ccce73e92d7a351a67f4c531eb3e786f6b92632444f36a8b7a554be5bfa9f8f3c0eb18dd96da5eb9fbf3d39f79495da701a549f5a4a0dcbcf147d9f992ab83ecac1504b2dd11ce7a1ca3bc084a2c611c68cfa89aca69626d80cf2a016cda8f47f6536f085bfef6a18ee2c84e0cc32e9dbc08981b6b54110ac7a8146627283e5bb30f47869d09987da689cf5b6f3aff6893dabe94d1c2fcdbe789d29430a3913e4a20aa6569c26d88d6e15030eeefe1fd1ef7ba865e52a9407fbe4578685672a4603d41c09a9aa99ae0033c5265117d8438f64a3daaa862ba2931fb86e429870f51f77697ef8e0f4b11dc6b70c9a1cc47fd2cce484f7d088d1d3a0fed120555d56d1e7304a656513\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 35826bea475a851d9f7c2b94b28922aa417b7cde808fb6cea5a243a3f414bb2c5c6dc76c00dd6fdc692b085334c38ffbb4619198bf1c9f4cde1056f796f47adfef03207a911d7529bc6ed81f32b632d0c2d127556b9ef010d68a2f45071dba2f128052b3e34588c8edaa552f7e060156dd683dae4dea4bc0ace1e17681ff4d826816dcf00dad4dd17df81aea72ae1e436f42c4c9f0ebbcbfa801d94db1bf0f80f51cd82b25aab6b9afd42a4c22ac9c04dfb0faa1b6954941d8684ff721cdd485f81abd6a59793f681f371d2e2187e7f7c034f5f5d63560284d2e0de7aa27b61a3863722b3898769eeae9dcf124f6314a13328459c4093105481f7cc0bbfdb872f3f304892eaea2971420eeb0b86c5839be6afd4c719a50ded51fb8d1fb08568a7d12ee7614b6e8be6f21baaca84c166a69eb773dc69fdf855d02548a188402616794437a2a9aaf50ab6a14f0f172af0af4a89c057e857ba40333a8ed3f61c6e08a6c98679f55da53c76c1c1349791ccbc7cbb3c189a52b2ed23c6fe86f00a2394fd664bb7a8296fb32868901dae475bfdf0b66cfeb7661e5b734aa5b8689fdf54299a393cd85921e21d35bff5de824a9434378106c3d21f2716be4f8a60a37b64a429a570c1e19c7a5d2e9db9f110e7c0727a711d845a1d8ff3a8778852eabfb793d5a0054", "b6ce2e38f4d085b44603b812611bda8754025e89e65cecfe99c11b\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 16\n# first byte of ps modified\nct = 29d887eba4aa52b73b5bb2308c0fe6fa78e6bd682ac7278fbe85cc8a9f9d009b2ebbe241ece0dfe5b6002921e555771ac5e5edebb8894be534e00135ed6660bc43e32fd3c20e8147f1d998d5291e877e075889a114b87a0051771a8c8034d4317e12f66d40955dd6d2e97eb2b0877ae0ceedfbe345cc10b5e6e3f41cf875f2600480c513672c8c0193d8f141feddc8ad82ff0fc3bf69663d386c968d53a4cc2fb82cbf8584d3c4d64280925737e1b6b27e60a443fbcb38ab7c4d14c81c98ff0018572054746a0ce3c6a004ec5ff3a827a140aeed96cfc0c2480fbaed571718b30ffde4c1de43667125ff7f68a5352ad76aa828abbb4e70dbaf02fccf4656382d4b7c261c0f858be7c59497823c892c52e9b2b8d57c70e82c8059345f12bf2a0fc4a214000e79a4f04ab7016c7ca1184a32b81243e44dae41d045933b9dae873d6b836d0b9c911616993eae95830ba8c5698d3ea722c370f47cade258cbdb67f1eb167e51c6f4b12ce7adce403a001e78092efc30a214939e3b86655bcc37d8b485d53b6e2ae42c18b03bd87299de70bf553a112e9e6bdbc2e2441c5072ecd2c74c25bfd94d7f5545c29c7a304be24be5ef61aec5ee4b119e971784e0189903240d2bec19ef9b39b528c65221649e72dfa36f7d04aa0becb4d147a33480764208623d0be7eaf7b466be492223d12c0fe756e23fc3b1212b4c3d257d50712c0385\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = 7e977901be2cb2d4f55451fbeeee9f081b945a7bfdccd3e16d502a15b2e05b0e31390d996a74de4521104bf642f5c1f4b28775ee21dce345273b595a6ff7578635c888f9d3615f9852a0530b65ee49695e1d88fa542e3852b545d361bd8ba4f9d66aed3a7d59101dc971aeb3f47a3c4f7cab15319981bfda2c68a491ff3de9b8975c8963b692061c8a8bf3b5dd062d42e8a2efd1aad46f46be4e31e3cc397ede8203a3750d05537992f310c936d7559de5745cbbacbaa0cc8bfc549b5299662dfaf3cfb8a85c5c40e30d12f10b8cac0022b3bc4405644b328ae4b38e077cdf263ff9e2fe9ae44127dc71f6cff5487e76c51ff94cf6c28dea5771fee269d5c47a9bfe519ef6ca253677fb1a8deee6b51b9d6152b53405958e724281d374228c4e501937e5b7cc745b6aaca552b8fe6db2c346b7514831f4f0fdf724bba6b462ffac33f9a2b353ee8429307ce9e10b2f2e3af326bc79bda4a4a93d9d0560699b91a5afef136e1ae2af5d3c5f483af0578b032f62a5c65bba35c47ec5f0c662fee407c775ec8718b5ce7e696fa2f5cf2d7d553a7e1aefa31c7716762e4b2765e6b58f268576cee7143caf67cfd32e6759891d1f823fed71339efdd7ee8b3f7e3cc8c5655a86a6823114c14643c2ceff08b1cb448d8b0814205d2b565841899ed28f1a5240f914186caacffc0ee03a7dff8df4cbf4b7f587c19bafa9f33ef132d808\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 310d8328fe04b15b0f7e92ceb3aadeb1785e71cf8a2081386e2938a95f4fb2a7732d8c347ea1159e9d7588d97496cf8f2c89285e7f226e7572055dbaebb4f4fc4bde689bdf6e6c9a0ecf6b3f8a98be9459d6d8b86dd184061d822545703e2fb958345bdb03465422909aad9f52d45eae132c5e6776ee9b37dd5eadc8531b69839ae6cfa8e03b35003cba6f1df317b522eb2a62dc4ce5ab7193693aa3352110d7fca5a8d74515a01ad236a515bd61bf74f768b8b26cd61d03a3a9b3e635677d8edb4264860173a1fb650ca4cc4fadc3545f84d1b85fdbf883addfc6607c898765f9ad4c3a6e64ac02058be83c8fc006a2ab52b3945fb0291509691adbc95c67548feae0d40f72e71eb9318d7a17a64dc65260ebdd69f97b608dfdaccd8bf1d371084421ae3b475babbd4dcf6367e3bac835190f2a9b21258329dfb8930793f76fd981c7ffe8eca6244e6a546ea4b076fe2f99a47c8dd4241a14959f9ee3aeb07061178d00cea20d9caa337464fb104087c6a9aeb1ec2a78c9c3fdb0c764c5128f7e2bef352dfa523fbefbc4d897a86f3a3fff8d1c24f8b9c8199ca7ace330f26c883d7dbca66825d8b001023438204c5b80f62c6456f7f3a383c27eceb2c3da0f78c4a9a04f12117658cc8bca5fa240874732e08e3df609e63f82f899aae27f08860d4a02afa12b495cabfe12fc3540c200e4ebbcd328f05ac68356b36c4c41ee\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 132666be585f41004622ccfbe802a61bde0f8a0459044a658e98e8ad9adbbd3b83c63144153da14dea424b7adc4294fe52961e94703eb7945ded497de3e26d682d745c7a37c88d88d0240ae3f334dcc23e2a6e3eb18888b7f5bc2c17f54d167f1704cf1f0b726a5301e1b94707f8c982cadb9b9aa8a559bf2dc2730b17b425ab0c26e4816a7d30d040a4aa995981db947765e097b5e424e8805a78980e709e3026ce5373ce1bbbdfcda646df70e8f8f8536a83f0284d685e99bfc5d0b98efcec6246241ed9dd3a1b01ffeef06b647be2cceeb122fbdd140999b7cb00a96c039bfabd7225db666a10478b83495c1c9636391daf162feb08bd7b4a1a69e9b0d2f846e9608ab327dfdefbd89abcd763077996dbb0a974472a17a843348d67b9fa1f630c3dba8aa8edc0c6b56cd7f05445133eeeb27377b4442a2c1dbb1d7027ed3f3d2a335b78a1a138b423f05cb16db5ae8e609d2f1c249668f5e47bcd9e405d4a369299c17f5e1d24472b112300c296ed49b0c094e93f0fd3ab10ca2269ed94ebd31c65b64c6988b8e0eef4f0bf7fac04758798fe736d85eb2025a82ebc064f39e529860a05ec50a86d16100059da2596f7d16861c88be135d85bc586cf40425ff0e2bccd7993e9e0fc0fac29465db116f79c0708497456a5cfd8ef12a50cf1c5183e05fa04ef7a6c1283b2aa140d8de9b8f5652ef08df0499b3ab4781c0619e7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 28c4f829d3446be96b30b681e6de5c390996a47e1a3d8ab42a4d7cb12eb7ed14d2f30a66e53e526b0345fba4f6f7ffb2434dd204dca8277c906b4d3d96862697467e33eca8ccd99f6e4ad1224a068d5bb405c4dd3cb3a18af3bb52b0ee49a359e47a84c5d8f5bd9c0ccf5bf0fa147af08ba92d625da26361ec5322e7aa2bd8f2c015efc99142858cbc77053be48a76de6cd665936efa7ad555860d8a6ca836a8d82aa179e97d5eeafd63e00a79ec614087a601d31a41dd151884d02c9ed14b93330d3f9026162b5593ffaae8ecc31c398b23167720e34558702d0e64adab0486a0ddf92e33c8553cb7ef0aefcd27f85c1fed5f9541f060c0b5d8ef2bfaa8537cc5b892aaa9c10237e9c3de2a57ce3722d36c8451efbe7a6f13e03e3fd87fa549d001aba5ce8cebfd5e171fc73243a7d6093980535351436175ebca6ccbb69f77d902bbe1a7a42d7d73685bc085bfe6baad593b92def6d419b500a864a7840f980ac3826f275c269f2ebc1186de6031b54f094f318b4835f6de0b460fa87ecfbcc7a1ff512db05c4db55b58a9f19f7e9e1e44508b2facee44c80911467ba8e561ffe7ba0600665bb2f957f80462f5490ea6b2645b27fc035215a3ca465c0616108b5e9ef246633ff8195c2b43c9f2a0d5a4feb1d5fb918e761d175fb6fd826874dfcedf8b4a13b85e4eedba6f12b7dd670b47b3f0893686880b4ca58ee05c1d24\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 401be864d1a7b598cce9822ca99a41c4c8c3ee4421c6ce8f617fdddc4525b8b92551073d24b40f107d52bb3e6d4f9ccc9f857a49e3ee5389fd7f2140fff2181773f8badcdcdbf004b0ebd00b8732c118bc1552c14ad305eb5d02e0c75ead4ac514ef866f68814b131d94d7f4dafefab4f9751c00864f09e840e1b1f6b96f8b7bcb8b2285bb959355d8f1843f82166db5986be2c6d82bbdeebc45bf944b47ff35f7f6b97fbb9bde65d138fb7bf1e93cb635a8b9b2ee8b77117225a193c0b7317a4d28f9e1bd925c43df48629674f37161f7ee36ac41324ed0b070da7159b19046c21d6f2e850dcf024ce3c5149e4ce4decb467433f32cc5bcb32e48b2f5bbf3cbffbe002eaa347b68d5017c8d0d4bb0be96b4607ad1877e7fca38d52e5b88eea511911d9ea1cb4fe1c89d7d786b0acc3a21f344b146c8da86af77ba17526d5a00fd43c7994179841088587d184b6663b89702f7c54f453a698efb1089562994a6908c41e261daf831d3deb5994ea78aa415648c9148cc0490b5cd756dfdc205399d7d111688f501834e8bc51cc92859f0bab7fa86a111c78766a0388cd009ff8591b3b81304eb0222bb3362b921c1df0cfffa44027d444ab1d8c3c993841abc6ed49c96f341c2951a3c23c8250addaed803239bb494f8263ad311a1214ebe36a0e1b51eb85b9a425fcb6b8f178e02690446290af6fe01c09d5f4f9b36eb40d65b\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 7f535a238cb7c5b93031a9397f139bfb2f373248f05c67528e2ab5db915a413b99734f6131452d43c82b82289565a6b9a601f5e3719e0fa0d44add201b5b2dcbec7925a4ed7dedf4d3886883db6b6d9b56d3391d9753af4872c3214cfe1055968d88940a3c3549ab27b22f7e56e7812e1ac1963f263e6a574d5f95296bfc1f34ff9cce1a7ea7f71d1832be55a18a78629f15ac9970797be6505dcb6f2a07f67acad1c058be5ec7accf2daa109605c83a5c928423af2bb802e787cc7b35717ea5ad221bdd0866c3e166f258976a660fcd923da605b11eb416b2ac80a42fb12d8fdc8a2152aa145035760c2abc4a88b3f0d96e14be3b01a2a7572095fb1d0f0df7b725a7247fda5afe22e29c0bf543b3a396531dee98c852c578e16049d01663fb57b42636305283a5f184ac11a0d4e912bb3da0913a27a515078de839c8665d9331b737e5b86e4cd7a103a40b73c9b64e0fd3d0d30b75bd6de1f6fcd05df200d059a19ecceccab7836970536942e0f7b7445dee987b47c34f89cc4de829109bd3df8f695a83714ea81b7f98f38006c13f7345b3cf1b1bdd70462613844b3e751cf4adceb98a6d95c63b2f245e5721c1d5f5099bfddf28ad796382c325cfd08235040572734dfe3312ec5d5a1aea0665859d00ec81638b60780d40b6fb93daedba0ef0bb8854f6d71261c6271b9c6e6c44689818e805d9bdc24a693ca1d83c6981\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = 956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ec\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = d2e97c8e52fd77875f7e7b1e6771bf9a3498396e8085a306960696e81ae89c90a3464a3fba4b4278d942f4afba6dee4a432186edf010f09586bc4728e67ecf9ac6e15da13c11a555581328d8b0db99ca25b5a31063213908e0fc203083daa5ef1bfc22a497f04900a32dbae8af18a2066b0c4037261724c27e09506513673c878be21c47f6384c57459cda2746641eb741a80980e3aff548204952b5f06912b96aa5fe257a2985f4050d523c46b85a99bd7b77e03c46d1e3396b31a96007b7727336e68a6fd3bd188162e4509288df1fee129ffdd203bc68777728592f0d9bcafe47ac17c42b9df69b47b14e8972b4253caf74d03c5dd6d027d4dacab27857329fb3879e6e61499e565f7e94a185f9ff7eb966f9e6522af10b85b3320d761f209902c501e03d0dcd8c795b7aaa67969bb4b58eb4bd09db6a3cdb6410533ba5896b134c567255a9a3930943bd98eadce1e6431b4093cbc8b2b9b4e0ea79e07b7beeb84dacd11f0aabfc4e779911e228237f26bef2536423c042901b154a6a9aad61dd2fe182fd9d462c8d49d7dbd7a2eea8492fb14131a400397036c248434d90e113afb4bff3aac595733ce93dff73ff8cd8b3e3a851d3465abd87118a0d40eaab61572f6aa9bcdaad2a885afa4724d8e3a1ba29286759deb5c1fe3512235e846e688cf325a278d94ea82d946fdf0945d9ffd5e7fd507bdb7a31e9b79752c30f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 00003d8628a19ba75e418329363a074d5992a80446e9791583095c23ed66de5dd41c94db742324edfa2a8807b6e115460e48a30898c1cf94d88edd54e400e448025e44d35e27b89509e4bb5e73b5dcfddd38939180b69ee551aa3eb74cb3b4320127cbd77fd51b28da7c74871e20e5067ac610053fefed9cd4599971e219849142dcae66ce97d13c937f8812d619b6fe0df57abcec358341f82ffe13827fe7e8e26c1030f821cb1d43a8787ee48033f4f11c901adb48e7c85a950b3502fff2f12695df04d55e1c816464a636981de537d1b3e66598759c8b38e1d87b9cf69c752982b6b54f2398f7658ab446c12585975bd3154386accbc9b796abf8a1c4cf6ef291e9cc519bfe2e09084a20a88d1f2243ed8d21d199f983df56d8a176603a9036a44c175f1417b7d34ea95c32993c0cb6a029edd753c10d77944b666f3fbfd743adb9e6b60c06e83cb51ddae3f37e3632e4c2b547580dc1ab3c7c94c6f09226dca4884affa94a0e119dfbbabb42a85a516375f767dedc7d1e0cffbfb44ffbfc7534cf619d1f926b0f61ddf2dbb8921e9b27fdf9cf52776e0b2adb781a5b110849c4600399850bdbb155c2523862f61fa84bfa9362cddac0a49e276c01d31ff4ee6646d914819ed75e7395e04cc741a0d7f61503d940d0ebce7888ded00facab381e912fa737c5d628f820650cb9b867cdf17ff60f145fb2c107203fca793503dc22\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 3d8628a19ba75e418329363a074d5992a80446e9791583095c23ed66de5dd41c94db742324edfa2a8807b6e115460e48a30898c1cf94d88edd54e400e448025e44d35e27b89509e4bb5e73b5dcfddd38939180b69ee551aa3eb74cb3b4320127cbd77fd51b28da7c74871e20e5067ac610053fefed9cd4599971e219849142dcae66ce97d13c937f8812d619b6fe0df57abcec358341f82ffe13827fe7e8e26c1030f821cb1d43a8787ee48033f4f11c901adb48e7c85a950b3502fff2f12695df04d55e1c816464a636981de537d1b3e66598759c8b38e1d87b9cf69c752982b6b54f2398f7658ab446c12585975bd3154386accbc9b796abf8a1c4cf6ef291e9cc519bfe2e09084a20a88d1f2243ed8d21d199f983df56d8a176603a9036a44c175f1417b7d34ea95c32993c0cb6a029edd753c10d77944b666f3fbfd743adb9e6b60c06e83cb51ddae3f37e3632e4c2b547580dc1ab3c7c94c6f09226dca4884affa94a0e119dfbbabb42a85a516375f767dedc7d1e0cffbfb44ffbfc7534cf619d1f926b0f61ddf2dbb8921e9b27fdf9cf52776e0b2adb781a5b110849c4600399850bdbb155c2523862f61fa84bfa9362cddac0a49e276c01d31ff4ee6646d914819ed75e7395e04cc741a0d7f61503d940d0ebce7888ded00facab381e912fa737c5d628f820650cb9b867cdf17ff60f145fb2c107203fca793503dc220000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = 8628a19ba75e418329363a074d5992a80446e9791583095c23ed66de5dd41c94db742324edfa2a8807b6e115460e48a30898c1cf94d88edd54e400e448025e44d35e27b89509e4bb5e73b5dcfddd38939180b69ee551aa3eb74cb3b4320127cbd77fd51b28da7c74871e20e5067ac610053fefed9cd4599971e219849142dcae66ce97d13c937f8812d619b6fe0df57abcec358341f82ffe13827fe7e8e26c1030f821cb1d43a8787ee48033f4f11c901adb48e7c85a950b3502fff2f12695df04d55e1c816464a636981de537d1b3e66598759c8b38e1d87b9cf69c752982b6b54f2398f7658ab446c12585975bd3154386accbc9b796abf8a1c4cf6ef291e9cc519bfe2e09084a20a88d1f2243ed8d21d199f983df56d8a176603a9036a44c175f1417b7d34ea95c32993c0cb6a029edd753c10d77944b666f3fbfd743adb9e6b60c06e83cb51ddae3f37e3632e4c2b547580dc1ab3c7c94c6f09226dca4884affa94a0e119dfbbabb42a85a516375f767dedc7d1e0cffbfb44ffbfc7534cf619d1f926b0f61ddf2dbb8921e9b27fdf9cf52776e0b2adb781a5b110849c4600399850bdbb155c2523862f61fa84bfa9362cddac0a49e276c01d31ff4ee6646d914819ed75e7395e04cc741a0d7f61503d940d0ebce7888ded00facab381e912fa737c5d628f820650cb9b867cdf17ff60f145fb2c107203fca793503dc22\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen150 = 50963; +static const size_t kLen204 = 50963; -static const char *kData150[] = { +static const char *kData204[] = { "# Imported from Wycheproof's rsa_oaep_4096_sha256_mgf1sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 097a59d2c4f70377793937bbbd95d19b5d01edfb1eb3b073e27e4cfed416820d4af4e04cc3f53d272ae43551ad0cd09b89cacb21a595f9f8423b3b0148d2ad46cf818fd9e7cbba18f4f84a1dc18f69ed5a764c6fa191a3664fa94a39bafb1a29431e6fedf61eb9164dd7684f0cb506248121fa948a32c8733f3d9453dae61c8708b2500582f32d91128775265f18bcab6eb170145e33dc40f1bab451194cf8c38f9fa91806bd225fa4b54ca50813b9d7a54f61e0000e5e0769cb2a3eb99b1ae9c3c5416dac83a6f91248c734d7e63291ce12de4d780703614128f878f29015801c7a5ec7670e531e1573ebc8ce63d640b01b9aea48b43d1eea8ad85b55423d4e142bcf73315f3e9e978b65f0556246066596013fad97b83ba552140c6957ef443ccec4051b2a8c9cd9f25c4cf6bdc2e904f46063e319643283462a4047d49c38bdbb0ee3d87980ec08410d5d2dee8e5349958e4178aba065a55d79d89080570fd4af5678b1573e42f2e0f863b31bb4e19ba232c02ae5b8f948d1ce8145c4968d24b56ac930b4f67047257f3c0b86bce7a77b8d0d87124c4a4141409ac11377fb9fc805d60012386becc2ba8478e663becc3d73239ce3036c2d2fc9e6e2e370c2c78053ee1bcef7a87872ef92b784638b84713a5d78ba8c3a868e3466f2275b252e19766d2104ec60537bc1589b1558b76643751f6a60fd8a5102b6c788e0f049]\n[e = 010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed]\n[privateKeyPkcs8 = 30820942020100300d06092a864886f70d01010105000482092c308209280201000282020100956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed020301000102820200097a59d2c4f70377793937bbbd95d19b5d01edfb1eb3b073e27e4cfed416820d4af4e04cc3f53d272ae43551ad0cd09b89cacb21a595f9f8423b3b0148d2ad46cf818fd9e7cbba18f4f84a1dc18f69ed5a764c6fa191a3664fa94a39bafb1a29431e6fedf61eb9164dd7684f0cb506248121fa948a32c8733f3d9453dae61c8708b2500582f32d91128775265f18bcab6eb170145e33dc40f1bab451194cf8c38f9fa91806bd225fa4b54ca50813b9d7a54f61e0000e5e0769cb2a3eb99b1ae9c3c5416dac83a6f91248c734d7e63291ce12de4d780703614128f878f29015801c7a5ec7670e531e1573ebc8ce63d640b01b9aea48b43d1eea8ad85b55423d4e142bcf73315f3e9e978b65f0556246066596013fad97b83ba552140c6957ef443ccec4051b2a8c9cd9f25c4cf6bdc2e904f46063e319643283462a4047d49c38bdbb0ee3d87980ec08410d5d2dee8e5349958e4178aba065a55d79d89080570fd4af5678b1573e42f2e0f863b31bb4e19ba232c02ae5b8f948d1ce8145c4968d24b56ac930b4f67047257f3c0b86bce7a77b8d0d87124c4a4141409ac11377fb9fc805d60012386becc2ba8478e663becc3d73239ce3036c2d2fc9e6e2e370c2c78053ee1bcef7a87872ef92b784638b84713a5d78ba8c3a868e3466f2275b252e19766d2104ec60537bc1589b1558b76643751f6a60fd8a5102b6c788e0f0490282010100c3c677495c2bd56619e44e26140d2ede0037409b81f3a5b3886a0904eb486140f43b8626af13d14a33918eb72b786b3c9114f39017871528953c09104e1fd2d36b725388f54ffea30373077895a6934ab174e55ca6a12c21923a7b775b5ffaffbd813f9fb752805b016a5735b883c639fedd55ba2e233a6dc1673063d8487390d1676123544d3def177a91caeef98b13f38860474e44993d4c6060926d878a2059855d0de1c794ac8dbdad655fbbad20f152f15c73b95ac544cbb87b8bec8fd3c007ad09d76ae22a5e993302aa72f11deb265a7f28b88976af5d0c912d97b7284b1783c5bc91a6dcb7a9b97fe53713965857742b7e4032dc5141acd4afd4771f0282010100c357cf685f9b8d4e59e96686f7b8752f0a982efbe6658e6bcdb615d921f5e7056882825347455782d7bc78d637e17e0e6810c2136ad81b16cc1c81750785924616f2bdf5964b26c7fc50fa98fb67b746b50812705b379f5deadbd11dcd2fec7b724d042aef25cea2eb37f85b7554d7ad49fe5f47737ff436bded418507f2f175c695e324fbb11beb0544a7a7cb3f07924e291b5c8ddaa6a7dbb07e23bce1960cb52b9000d3a7aab1f58e3c750b6d978adf3d085ae7693b7e6a46cf6dbb6d2ad981f4bca5d15e0962c39066a9fc27985b9ba1f51132355792796a5dd847400804f98671ee4899050bdc2e7872ce6fb2b78b1050436d882425ee0745546a6a1c730282010100a6bbb5460638d2b2f5242aa6657760cdf3731b1415d5f2ee77248f6fe00e31bdc70396da054ba47844791809c9fcf19f90943e671e928e23950d9f4e82aab9bc138b37b7b1ed2219a54b67367c8574762db237d0f39cda5ff110dbac286712f69167ad4f122b3263cf4dc8de58b9e9ade4f08e1d5543ed74223e06c9521f4a45310291892c37e8a262e5a19b2a71decfec1dde997c00125e5158d7867dbfec9466899d59c04b60c4a0a6c5314c1a2375a5f194dbbf37422635d426d719b12c41140fb5806735814ec268493861002977e8982e8493a2ae78251be32315a85b75f6961d44dfb7505c34135987a2288907074fdc015ab1c45f3cd8e91fee6bcdd302820100178cd58f72bf5118da141e6d351e42da69ff90e2839348c94c62a05dae0f744b9d9ee6515ded4930980bbbd1afa8fac687db455a8bee03ce0acb80fbf7ed2d864fabf224d27abaf12f45200123860c7d74c3c55d5051f35fa239e00b24ba9b5b029bb05df0b8f12189141558095c32284d1c62a63d917682c700fc7e2a482abe1533eacf819c878e1cf37af6eab4ed97c0de89d2edb327966310f31421e85c6ba9c7d7b391d0cbee6a793c66abfb09630fa8cf020e960c3b205aeb15029c95a6e558f90950a572a23a8b852507264ae2f86f5d1936a161ae61fee5d3763b8cfbf48d35dd1159895735b350881ec52e999c255a57d6b3ac0ffa935bd36284ea6b02820100484ad86e79415ea3c78af5f6c807cc99decfb14ca1e80c8e6a1ef00ee582d3d180774236a54ec9dc8dbcca51f4da4379cf634f3a07cea4b7748d7b5d94cacd4d474111f92d19f3ab5eb4def8dba57b990844efd28d85344666e283f5d5fb0e6e8d96f07411c882bf280446e49b3b9b15218fc24da34ce8f01e02735920ef48a343b4de11f99b26547a251afa7aaa69083c421e2447b1a989d50712bf8fc35882b63517c7c39843cf67b92645b68c6d8f90331600142e6cb97032a5af6ef7c20f87630c6b25dddeb57f2cc0cd8c8a0661b5f40ed6632989f5d40f33bbfd9be09374483606c2cd7ed8b5fcb8bf3df1f9368a13922b1240c0d25792505b857d3e8d]\n[sha = SHA-256]\n\n# tcId = 1\nct = 48b29ff276452ebcaa7f74bbfefcaa0cbba598beca99a178594baba98b126b2679e7d64876c8fe07e39f1f3fdd5c4f664a1ab314bcb75f1e906643fc4c786d66e90cac12b8c23aef35c4727451cb033d889e2a30eecd2f8d5091a6d52170ac6ce579c9c49701461185196aec6a380e2504833609b359d33a436f2c63bfea9a70e803f06644a0ca725a4c5b9b01cec93c01cbb79f9a17c401728325e17bfc9750dd19cfc127b9dcff8951a78023b9e30ef7ab628084d04f64a4be3b6d7d3da9d0a94d692a4cb275a7f509aac8dd2db4f797a374aa880c2d646d23760c51f3e0c00601b4c05f6e618372edb7d3a6f5cc9a26b5095adbff2134450b1ba238dbb9b3952f4d055f6d486e27e8cf6ff773896a0fc2991fc5ee046f6e81cf948afb12d669cc020b3aa3f14a18cd63830964c9662fcd3860fc461694ab3c6dc4f85fb4fa527f77e944e7c13b94c23fd0fd517a30dc00212d15bb25c00d48a36db8bdbdcc398fd6b1d229c762f7bf6e99d5452f69b91b073d866884a6e34c4608ee1df0733e592e339eedd59554e85be57c0a9689b69fac6e010d35c9c823a37f6f854c5247db77d54fd784ba82ea4e3bf776413376b4bae99c02a0226abef411f1d56ba7da24b72a1a5f74ab9d7431af7fc940d2319ce81dbc51390096d42a3072291ccb44f3db326cffac084c6a73c0b92919d6039e0ddaa9fe8ab1d65aff8b22cec120\nlabel = \nmsg = \nresult = valid\n\n# tcId =", " 2\nct = 0788a1201bac2e27ee3c704ab8172cd45416bc353eddb23477841fd6e13d87b9926231315d26ccb3694064ed9c52ecf401c9be16f4e70e3d7c4eea6a2b20f32b53e94c9d26d10e60a3fc37983c4f63b46be3c04f66305c4aa23d409c9875ebf238a1d999114c9ce8644e7a93a8caf0cd006be19164508142b36000a3e3a3b8bcd445f9193ce9bc2100b4364d4c88cb5001b8fc6314cc782f469061cfa7cef3c3450121c8de529bb8d41b1cb6975698b138cf9e0460b15f10baf335cb8d680146f801de67dac74b0311059252960d59b734295f33c9f8506b6940698fb0467e746240366a49da355582831cd2d99be95057e9560c95f86931843633119218bfd2f353ffcd64983a5bcd4802acc68a0064f9da51d585c1e38310957db7373b76a3e376846614bc9271d2045fea65a6eec059cc7647c94318166fe53dd19b6e8994caf8fb0ba888f0b9b89071649299f95512c3b459ff6e3b1636c51213108c3140ce88ff377b3f36da31e85c46d5a479ddecc07899a5c175818881ea30d9a5a21b3abbbc1dfdfbd40cd6849c1312c4a89360ecbd5c1fd90c759563b0700a945bdc03a0b7888b893ed8c50149983a7e18668dcf61effd03ac8cd9d730ee55a0adfbfaad873b4b7e1923bf839a5e3df9bc634b15076379de0705150f03897142daac961c8f99a5dcbea953f2e29681546361fefa495afdb116f789ebf9815f271c55\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 3ee1f8fe284d3b84ecaa5f48ce36661a7842cab4f4aac4019e0e7e4506f1baa27539e468877d1e41bee136782ccd335c23640316a24fdd13e9257062fb40f102e0b482a4b589537d0e417f3db7df51c7f8a5094888981132fbc8236b79f2463b969e12c621121e697445cc80f7d0abbb31548e0b732b014b9c40b4481896c47d4d6194346f49fb8ab3c69e3a9e282a5ddab98140a798f4811b1dc4f5903f44cfe029b7038ba28d806bbd42213d5235180f33161efdc80bdd1424fee3e475dcb353f79a1fd23097f20b54afeca8d2123830e9a706bd6d827be20089a464d2df133a631db522dbc7ebddb06125c112644cc41dfc1ba6a924f7b32fc9a315626f6157aa9fdfa9979a73db2f8ee054e534b4f00235daf2fb967189720f8196986697609a45e1586fc6321a2ccaf745bcd99d69135edb45734fcd27698a87b8b3d95f426f63c5addec03201fa33ac224deb25c1cb5e1e32c7c0b895166ae10cc1b9c270a075619364650d78a2119816b17d808d44d2169022cbc5cc64f80b042ef6def97eaccac3a45c497bf2e43d823c1468167d3dc824fce8740e811c21d3e7b2289bf5c09d722edb94bcd7ac47427ce90c944279d898cd7d975d6a200ebd00104238be33bb85730c0edbd41ad4106855567be674a73b325e508483cb897cdc25aa678f0379fe121795cb858527e72c8a62dba7612104dd796d538d4d9ba80277a4\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 0122a411f6c18869d9d071d89fec1f8d91a658d644a5da66453ad0f0fef2d07146e6a96c87dc4bc5e2d5c65cbf493289d4c9dbb3ee79dba765c71d74d8f0f0e9342f39e8621d791c813e004383fa970001c72a859ee9d01ff9920a650cdb08c11e95df70fcd3bff1f21bb4838a9534f815085238a9f860c27ad6e3075ece222d7d035732c4ed6d4d4fbc64d153da106eb58676f527e7867a7c46dd86c0f55451cfd22b07897f84621765215dd8e2814ff9d9a9cbf828d594c16ac10074689ee3472280fbc14c5f723286f2ca0f15f4b91e25559e77c244be757c18ce7743fbd0151419a1317b82407ee16e2a5b970a660706d0b4de8368ea542ea576d1c0dbcf03e07f646b42a78e430a39eaf5e48ead2d6d0cb360dbd6188d364e4a8e2b0094c698adf864724dc7098b4dda564d16edf775060eb7d26c15692878b93af87c3cf79027ebad55a08ff9f04e863d3d56dc9534d48edac17888342ab8c1bb28d8681bfae21bee0139c16ec1f6a60f2fc4927556a56c036a13e27eed7b056d5e92e296a5b7993a83f788ab0f943b56ab2622b732d717b2a6a46ceb5b9361430c8e8cc05dfdb2af949702d03a1a2b438e1612293a05ded6733e95fa17f24a06e573dd722175195e21f1f5a408ad2d72c8cc788de6d7d02da851f64a59bc64fee89eb1ffb06addb5459871a4614d6652374ed29811d3ecbb04a6646dc261e8aac5f109\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 01f290bc344f5b28bbee4f37d113bb1eb5c9ab3a6e735b9ac13ee65aa42a18ac22b51c684a34b969de549af295d48235bc0c46bad9e5ceb6a0ddfabac4dee6cdaffedda65556e951ecca0dcd8d1ab708176c1d665436ee2e3e9810dd2ecc508b232b3345708d3f2acd95727a2a1f8a612da88865c39652c8de64ac37236fbd0bf6aef4519821363e0be2391b7b0279605d193e4ac96caf52fdf1b71807cd37458f28bd4557f8c9b6db47c72b468f8bd643b8176bced97db6657a59c146b78389ee5d7fa3a463cf2d207b0cb68fe760b83a62462b42398ce7109b3d00b991f5ea915501b6c31d1d7a388b14a995f9c415a108542d375015bad8950f0be42f64c09eb54e39fdcea2efe61e2fdcffa740a71ecc94051c073c66e38e47f9f3161bc6b325123fe3c02ecfcd1d4b811569d95f1eebc7135fd7118cdda6bc24546b5d84622b796c289d7cfddf7d0f34705666b9263e6b9b8c070b28b6853c06fad4b8e538de222799b65f4efedd7d7435d3eb6aa30bc3827247374447ac92dcc59825b5b1e7c636f77db09411ca764366bf3db3bf39d1803034cf76cf59202e664f0cc0bfe03e67c83334196efc95d1f57385150212613147d149d4e6f4f994a544abd82f7eca54c8f8bce8bdff122079196014832547d1f50a9123ea130bc93a4c5ac43edcbfc4fa0f2804a31fb2061868f401e98f2b92a0d9cd2e260ac119fa06664b\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 185bdb913b9dee3ba4d6b27a945258beb43ae70909b6f5a2011256c1a743a6e2e14dad48a92ef6cbe1452306c5dbc77266590476febcce9eb6f64ec7e8d0f233749770275271e79c1980a247c0571dabf207b9d9afe8b6c3ad6f6c5b77c83f445cadbd77c043d5428acd6a55f6104c102240bfb9bd9e82d6db53547abc11537188ffce7d688b116527992f2501ae917f7aebbce1c402693c32ec29611afe7b6709667a65a6b38a6029a6ea884a7659353c29f49398de3c16e6d06e33dd186b14e7e04660c7d864954efe5c9157f178b4b9af46f12bf5fb083bbefeab1fc97114d45f08ff8389e93945afdb56a13eb3a86c64a8b33ee46349289cae37cb4f0b9ddbc306464b7574dfcea969398e6d8720125aa72fa7513ce8cf11502444594012024345e3bc716639cc1814ed18d14eee2251d20464a43bd018a9243dfc8e1d122f1d84664bf1d7e2b63236c3991929fe20d44030d17be9990e11cebfd07836e7ba4e7fa960d88cbbd23859135d2e7359a85e99e1fbb8e97ec736bb9ededf2eaa94c3165c46cdb5e289fe4b243e8e25f3969a39b307840990eef3d8b0db5d515e65833fdd59cf83c152e06f9a066623cba2fbbe233541121295566c0f2ac6150fc0efd89e2cdf7b0972a5efb7302b078816279069ad2e89016cc82add02f9aaacbc26af2cb8494d333c6e33f29a9e237df6dfb5c8e5bd8868c3a66a02bce69e9b\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 7aa5fee8dd85b6fc0c75c86d72fe6c742ecb062a036bbd3796af044378669c2162f6f9c9470e1dc8edad8a41de37411b21c865c0d04a2a4a8cbae941258aecc1bc436e96ab7d66aa1b866e9b3018a56366eaefaf92a1af51d5a901900739eecf07f05748b76565e386efcc8a717f39cf0a163dbfd7b1b02d78f96c4688143a80ea589df83c78440f5c53a1a79fa7265f5e1c15cf8348b8b7abbfc1739a9fdc8a30e25c2081b44437935fdcd19682cff42627b223d796d1cd3437fb12aeb990bf5dee03ec6fe8f0634dc0545d0390facc7fea02b5609f0b37e4bc5f2a5e26868ac3042fac5589457b482bf1c144c239e2a96bd80a813e67d36b4e43cb89450289ab3fd7d377cdcaf9b40811ecc5aa3704086dce9a893d1b19d9f957dcfc283d0ff1a4bdd7f3351314bd5e10a22b2a469615feab35e9966e758c5c2742c35d42659533fbf50693dd1efccaf1787de3c7f66b8c0df90754ca851caf2341b9a7004a7eb8e34cf232a6bc0e993db274107d4d734bb996803a4b335e1ce32d0453450a6fa871430827fd49123849993f421084c60880e3b6e4d33771a1bb255535616544cf4c016c416cd8b9b92c3ed61214972e86a901560c1721fef866ea7044a2c89cc2cba85fb25df521daa90680fb52c2a0baeac9d5942c851fbf5f1e88d522e759aa342d15be1b72f9815c0debd081e9881fba247dd6858890fdedc8838e9448\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 339772930c065104ed237b979efdd87be944739273a3d76e38e2a9dab4a089307f236ad0477a324c0d5f065f6eaa3f50e73104e4e44d25fd5b999948ca61c72ee440e4b75ea2909617c41833d0f67c28de6ed499f3df084310babacb41dd8dc94b66622e7b9d1fd0f81328cdc451c86bb891efcb31c020b191598b36120a40942d35761113680911756c72b859bddc17993acf696a4360dbeb63534f4b8edbb8a633d1d649370ad4c46c51893071712d3ab165421f8f0fda893e4c988ebbfe22d2ff6cd0f289f3cb333ccbe06291fdbeabf19f77c4ead63bc8f316e95d1bf9f743fd5ffec9513c0a1b2b89211426d7e7fc386affb340a8a7caa6f17a9879fd9582a5a01fcd3a2c399967feeea1333f01072ff1ba1785d27cfc48e04b05bfefe22870d82369338b6146d72761318ec977e3193a5fa325bdcc4ef2bac547de3fd099ef4e83461b9cd4cf9c1d586160c52d9770060258792ade9ab50568281f1c71d7a886db372e0afe0a6a03b3d3bd24b9ebf1cc5495570b3304a39b2d57f94f282e7698bfa71904a087d57f20cb67a859a888a2828df1ad1a424f02b272fa7467555512050c3ef8eaf9169ed20d7143cda6fd86a110a3b4102ed8a74d176bf625e488dd209dbdb81b78d5d32509af825405fb87d5400201176c36c19a1d8b93b020400bfbd5ad7dcb2c0dcce99ee05ef2b48e191439fe990d0576d0d98c5c9602\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 84f103bc40d2535d3ba06070b9e5739dea918968e524cf431e4a8a18036d5c43c40fdda432b5ac9134a54ebc6914d6f54895aa24a0420175f348ac41d13069bdb443ad3dfd8c15c283ca76bd557060876b5e686e6ed9e090b8be9701dd6afbd650eb9032f5a331fd91ce85f784e20b4a20c998b94bb9e79ff8bfe56f67786ed76dcee79002cc5586d04b2e1d82b7bbb1998ae596d09aa3cc8c7293bf8c6a89c22d7220fc97f426d0738de5c06d41e9cf13db801180f3407448ac2bf55d20ecdec273f41dfabdad0104f07d7902905ec1d4979fe36d5e0f8940255817fe8f911cf3dc295df6f17de9874b7f754f08a50209b63e8c87302d78d5ea909b0", "ed81f07965e30cd58e877984067defb9599541a7770787fb738bcb34b31adb2099b19ec15e5f585c52d64ac0d3778ed8bd415fb08303ad9492fe1ece5cc3cf824465856c179c304211c7121e226c859b7b4951a833eadf6a6f29e3bd3c26156f5af69f61ba6b8dd42747f33056fc1c0ea9f941c397f0d57d67e7255fcad2b97db22be83f2661122afb59dd2e18b38019f1ae40d48e6482aaffad2fdee1b971f75a93a9b14062d62bc8639bf866cd70c4963bef4303da8d1708f4ed489ec91b0593ce8f83cf3609cc51fa8c0ba0a43f96004818668f403bf97cb37a86b247580a33595957cbe39c8766199e186725afba94491a5cc7b618e1ac76436322823bc3f0b44a7\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 0b3d6f1a7949a05d472e0909c4667374a87e291ca8065786829b26702f2b979ed440a037abd310da6c0eacf0c01f5b2b082d00ea043e9bd403af238a0909ad8302deb3514cf7710d6a7777838675fd61e698ff09d03821046caa15848cf3c8b1e70fc497e2c8d3639dfaae1bebc52b68c24b54f3f1c4dbd8691d05867a818b0364512d6096ee6a49de7aa7f17148de1f5036af74213df39be1639a1b22640a693163af2e061073e28e1b20f32ce15cabd1005ed66d4d4ccfb50f94c6a34357989c1e13350fb25eb75e5004dfc311babf755d0c007fddf9398aa9c2761b5415c3a1c25e1d0c883187ee41c669337f3b69e131f87c68360ebcf4ac53cdd7101c71fcb1aeead812b06efaa514fecc8ebbc4b339a3f8e9fecd720c2d9019885346d4b483418ddde6f99c6cfe67500ac3ef5c064ab2fd96bf3372ece582c02e3dccefe5ea8cd82a79e7922075db696c5aa712243566fb820bec894ff96d3e844aeef4416b08e023fe48570f05203cf48054601a227ed3fc81fab7e54090864c110d7c0333299839675ce029436cf78266441fb910ef46101c3378cf7d322b696beed85d68a74fc5ad8bf65d212996774a80a68c7d017bdcffbb3f6194c2625e5937d3a004684d3a30b4c31c7fe4c05718182bde18a444dc2467d87bfa9fd64fbf5d31919d4f33f6f5721bea0afde9f47170fc8a2f45e17f4711971572873344a14372\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 2049694bab04b950f76d997385c150446040ae3373d4f868e852cbc4047ddf2648523a963df01a9a383e8a8a47a6abaf900de879414fe360d8eeb36e805ba2821d64a536c7e9f3c013d72cfef75038007cf546bc418d5e612d2ec9a41d9ff6807f8a2def511b09743b28514ec61139abe25a6087348d66f18b0a80a58f7fd91d019117c3b223057b8229f07d22c3af1f37b92c1c7fe8f27ed23729926bcd1f8470eb84da9b8991ed03ed9420b029eac8fdb6c76142150d1216a9d0622bea7d168c8019cedb9db6b984232a97385fbbba76ee260b8712f805f8e1e6fc966c9edbb4836137cf8519961f2ae1134867928ab4a517f6c4148500492e5a70cdc756df38f55b6b93ab81651e6edbd434cbd7f41245cddfa884b5e6ccae02cd19e1714ac3537966a113ea8cdf31b73ab55935af37a27420a6b0c8aaf225ed93e4250392b67cfe09300596836050ca95f16f1e2913eb3118faae6026571bba1803c0b133c5c39b6d8e9db60470b193760efb1d229ed1b5f867636f890c96dd16e454ff3bf75c54a1ace011d8c5d85a0ea3723bb3461369ceae212f0632b50f0dc0feedacfe701beea123f7c2ce22173a1fca90c2a861769ff9bc7bffc4d04d5e8107dcb4a1a49d9fb5dc3d806a0aefc1622935230a617009831f58adfdd08426ac70c688297b89452581b094a21beafbe33547f68812433b41227b87855b205aac11c970\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 741d6aa34179e67d3a1174ac4682ed88991e043dbc2634ddbcbe2b36136b99a279116b713e8484a4d4bc12b53ace3d70c5c352a07a7fbcdca7158abf5def14eafcc6919288f84b315dadf12a105e306b8d452f78d5ff6d4a95705c66186eb3b3a112bb26c266d3b8262c00d7a97da919ca37bbab032a60a55a1fd8e1a2cf908fbe918fbbcd5065dc210e4020deb415ba02e112f098aff54824f7fbfb959fa23b411fdb711cce0e0925e8ce526052ac76769394fa9a57ae4eddd30e4c28d87473054af6f6173292e4047d668c3c7c6c0d1f1e5e5ae3dee7e85da43b0478d0d0a46a759a23e1e5e68f80562ef52b76d85f664868e8866d8d728793e0d4f20b5673dd32eceedb4fe982036ed1c7c930c8f711888c8bddb33e385033043c812d6f678dacb3efab547176eabb08abafbb521111a6d5bcde133fcb7a4f3ba2316d2f7bbeb4aff80949e759da76dc238e64fbe7d27f4501eba60eb1e4ea0bcf9bd21c23f4c2385ec0a8cc078f8e67ad9ccd605086477ba2a9cc7148213827f63173641b78d47c920f73b72d2ac17f7103aa8c8b3dd050b260a17ac760a3463fb7dd19703d6eba6cf5b1a0467b2691b46ead45cbd6ed0492528819b50c922ed25f2b7f4a7322bdf24194f1cab6507b11f2211090f27bf3a6321a7d2de90690968a0401c117e8165c08431a1dca9999d8167cde6d53d41d3dd8700892941c9a36aa4d72dd\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 0e1551fd4bced67cdf4a57e4bf864bfa05990c52542f86d76714e74606c4f034d8e79cebc72af64e9f38bad64a2ee9f9ad8e6b1674fbc8c0a8dad71b55d59a52689bf8dc4fa8912ec0ba8c8300089e7fd689afff6f33fd13d0da443be82080af45276f790d551b162dd1e2592a53578af985307251a07aa46470932fe1ac6fe031daed53fcf0cd8b542f24f6dc3f58b28488c80231e087d6b7f48d8b0629e450b75648c065b603290971708a831d42837bf8eef88e5233228af52766675a046af5524d3b79831933e96be6c737f958aedffeee151f0eccfad3e95ad7bc3102ebd4887a340471e9115c4a6186b1021c724c00322e79c2dbb77e29157b72418757eb07371634d436133517b20d54de645b49ed5cef79d7fd88cca5ae8eeacf2d086f33e9e08ab575c1b1d090b64145cd6b57793a182e519743c4a69c1369be0494c253de25618cb488cec77ba585e7a2d5b387fd3f76aef6f6f7811848610098b916d77efb486f42f85e011c962c521891e35877c392d190bb2a9ccbd60a8536c29a07033531b74f586add9eda8bba422f6d1d343d6577d9f75906169d15045cd012e1b9267aafa15f39df23f55f931d9d8793a9b5c3e93e077992cf32ad57ac46048b19e0576f4bed86c502ce1af168efc236c49fed9aaa9614bceadfd3cac500628a8be815f074618d7e96c5d9b23e4139ad155ce9db36885f72b9ee1249e069\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 0cd65cb5fbf66fd36a61d7c3577eaad17191db8ed11ad0075fc3661120df2accbf0ae26da7e52e6aef362c2ba11d0743c4672a96f5e67b2adab40902216f433bd70601099563d3e168ee93d75f3db88806cf3d59017f5d2c6da4218dd9c8fe0be177ac0093e0909c34245b86cc1b791787e9544b9a874eca413895d81710df277837f4a598ea9f57ab8ce38f6a960646abe9f4ff2748d994ecd6ece82788ff368ce6d3989a820bc2d51c43cb88b3f9106b9ffb01da520514e7a03c605b4bd10d706eb322b67ed75072423505118efe727496516397a3f5ef9c77515d391e45c7d589a1fa1eeeeca8e9511890ad1a5d86046ddc72af6f6f6e08f87668567cc67e50b20d47f30e41665f192efb99824b603012d24d8c9e14f3f9facb12baf09b7004d558c39674c7e76f26bbb33945f73264a712e09277ae0e8ba9f208971a207dfacc8c5743411a591e4000b25b263ba78e7305a74afbe58673f26b8ed7b8377f7ca627839017b64d20c3940670330f6b45938e382d6d1099301a4b0017cabcb04d2358eb62634f121ff426e39c512bbc6539316f1d16da7b4ea3e203c2cd5c599080d1b3b3eda0fddababa6b402ae8ab932185a78dbd47a69ba9eee993646670d07bacd79caab4f50371f0b28e23045fed617c632dfa694c4028b8724733f30606d57502934000a6b95068805f70d44576a039fa70db1de3d1a001c6030913b7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 16bee7581623613fa6bc708e804b11954ee5578e6f6f6747eccc52b5bc47c0039569ad2ff4c9fd98cdc54404c50d404987cbb74716d769d70045361ddbd27f2c0e744681a2177f4ececedf39d90e23461dce3353999c90bce6b6b75f2c73cb2c2bc6220cc652196e8555495379bffefee61caea6eb850c0132e084897d9bdee7aff74da1be6f7ef2b86bc6f57494565ea93c6f3ad1853a5706acecce1190bc97bde071559d89f65c2717c31740e176c2db442d48c1780f65230eed8b498da2000a1a12ce4247221e68231e27d8b60dcadb2f50e0a9ee346e2be5083d964a5195d80d9b898e18ae88ffa73f690f2598b45327875278135b4f5e7ecfbc273848e1f1fe5504cca4a2c4a7fa353a301c2b6ccf0f2df7d0ab439d1e8629304f63fbdab4f6d28a84c1d581d3d43ba64408c286dbb452d34a48644271f23841868bd3462df5e4c0f1cded8e868c96cce995b13308339c49a0eb16bf5ce9493812ee205dc8b3fc3b8330895de3389895f162079c72019cb2c936cdfef9cd9f413514947e0abbf440db492f8b8b8aa66522975d674b0f663b0e24bf826c8799b850cf6a80221414eb8ddd2c83f824ee4d4db6565d07b46d8ef26123148c77c693f3c16d007b7103230e378a428dbd16eebcdbcbde38910984b10df5a3f6f9e6204d462e5c304cf5", @@ -3686,18 +4324,18 @@ static const char *kData150[] = { "3f4dd2f0c772cfe0ede15065b351c3e0892dd065a0fbfc35e6cfe47ffd90dbdd465bd7ea500b73f4981f3edd968cb5f9d2d1fd5abc1c9575ee16c263ba85d349f23de634801c2b64769b375e7bf0d098890269762840fa2f6084af3d9276a030b975a42c484d2be534264562b4a3a96d8fc7ba0b333d5af7b7a218fae0f23d21567293132ba3380de85689a1e913021a8df624e80c09d9c0e039544dcf6233c76071028ebc67c9de3ee674bc6837af70fa12d22c6f0d04f3060e2acb6700c3cff134ab90c2e3b1d7526b2fd34f8d8197a2c9e2727615732b14bf4cca0d38ed1dbbc357e7e2cd994d8deaeac9e6f44f63cd0fe509180540b5f5e85431d78a2e1703737ee082e0e709d55b27a0734584ae1adfbdff977e7019978abc30e0a9736b6b3aeb8a9f7fe1843c1611a8c77f4b92620b8167335ca222b44f3b\nlabel = 8b64ae26615eda5dc0a47b20b4f2a398844e7b97a06abd28b8db929ae347a11800000000\nmsg = 0cb3e2a241c8977bce02b885deb4bd3e707e1e950bd20d6573ef1cb28e558aec1c4064a18a0d656c7649d5412c422663784f9d24f4ef4ce744446a8e22634a4da006497c93df79b1a1b35d3461ce7ca8008dc4e2b23ca9fb63f0e1819e978ab95a173127e3c347ba33ee597b269c39983a018b9b79e596296582fae18da8c38090f1f775cb3b12f45fc33dfbafbc262b2579d93370542c2e67fccc40872dca0e2c177a349278d9a04453603c7c94a818541a586470c53302a4e0541081d11de7205c3bd97987db419aa7443bc7256213a8e046d1160ca9b77e1f10d134d43ad288367dadeeb55633221876e5783214b7c454e9ab79741b8d47e2d2f8c8ef01fc3ce7cf4b3f18068cdb386ec0a5734614ffab0dbc2ee1cc35a2cfd2e84426131c78630b4c8965796691e84f276ad55c41ac6d9d66b320580465b9d8d5c956cd4b144874c3430b4bb9e3f9408b420f0dd6c86918f85197e53538dd5e7ccda27d0cc62d939f394f7b6acb0044674ab549f087b33eddae5e49688e02e1ba0abb60e28926692de9c31667c147a8058b6db9ca87b217048d621b8685a645ed87a5d1edf0027a4eb07bcfc874987f43691f3e82ff028f7052b66610ba4a02d25c49\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em represents a small integer\nct = 93ebead3c8001ed15efe1648c9615db880d29fc29efb069671fcc0d5888f6ba3e2784639e6e3b9028614603d2f5180680aca911f23c5cb3028ff616920026d65afba45ce6e8c708e166e11ba2d837e4b120563ac783ef6aac5baafbabd26dff137ec98971ae892040f9795f63ce03f8df39ed75ca38999476088a21a7e32bae2f446e8a7ff5d6cfa78fb3635e9e301068d0bf53a36d66f0837f69de0da108f5c43caedb8136bcb9716014f09a7eb76f28761ed675447fdc46bc7ed2993a408e047839ba94a7698361b102c5e22b091ba5973b82d4a2040cfc5bdcc767faf5479a5da031d1be8242f6b1ff9859cea44db3074f021a6894fec3b637e320fdd4a03bf1b58fe91d5f8fa36f41a1c989e52e5c7b2dfbdce9a6dfe75d95977fbe533a753ac972e92388351080eb1d564fea5f3eca118bdb6004c0f16ec0b41acb7dde8708f65a8cf3af10ef8d3e9afdd314fecd3d7d4d480edf892f5117a6344cb12a2d39637d4d74597c129d7713dd878eb34f6f7dab71e71efce02d17eb008d370b809b31202cdbcc15f437cd362e7d41a1aa2425ee578ff8c19e6941a79d7bafc87201e819e1fbe5db1e7148628806b4ffcbf0e0de6f4632452d606122899452282ccb9b84ac11c70943386b6dd0ab1a5707bcbcc1799708ac8b05e0006aae87dff7c5c9b167f50c0fb6cba16c7a6e3882c32771059591abfc5a7cd53224b120ad1\nlabel = 2750512215b61f8e6623523475aa61c48ecec1b5ca09ea23bfaef162984dfce100000000\nmsg = 88ee82a2ed9e2db05df7d835b69113bf60ff23efe64e0bd14bb064e197c03e75f9730421be7b35770bc6dfc660b477276ff0ec936a3d3cd416f69ce8d10e4a4c6dc855b7a9e2bec17e3443ecd35a567fd0a1ab0fe027757a4b8c90c35d3aa26e337b99d6a1e0333d57e997a16a65d75ebbc8a06eef396d316ff45d066d6f46d18e68a423b8056ebc97cd8dca44036864f73584872405f8935e33a1247f20957f470445c36617087ad5260395f5f2763dcf4027dac0f95f0b378c9a1eea7ab02092ed8b893257615aec24a7ea9ce8edffd082972517246dbd9fcaff3fcff191cf23be27ce41c97b77b0e6d0add28848d0453acd8fa996b46edd975934d449d40203bd2bda89dbf80c12859c00087d77f58172226c065c8a7a3ee9ffdb688b8134a06216335b1d5ae67b5ed44c48c01c7fa54732478a2789be70e8082707395fdad5bf7cbc111cec0fa6141d8107e962e4c22c4cdba303dd692d6ecd71b1fbfc33487b33be2fc6e261914e407c155e2af7a459c10a1356d679a5a338528a283a47163656fbcdb748f5f7e244291f6699b0355f0d3d4931bf6c258f29ecfe69d2d01cb1610ddc40751b17fb275c68c899782c43d1a15950b53dc42c556b0c61\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em represents a small integer\nct = 054309a578d6ebc75b500308a2dc17b0f4cd5f9c1b3776bdd084f629eb6cb96d419a9cfcaab5e82908aab40bd28f1c622ce7b5ae40487aed8b56a71be56a91b6c3a7059b5cdbe81e5c7d19e2b63fe3c55833cfdf176eb5d46b0b4237c4af14eacea75a53dbe3770d934d5f8fab4f3ac1222264768e12f4fa4e4d23b3b2cf5fa4e315fb3da46fbb821456e17873e7ff06c247be7feb91ea4d1f7fdc07d351f423a4d133ad4ba543c9eba67b06b9c023b06c12e64b3d9ced33192945f630509f38053601a70e9a1781ae3688db6926a65697f41b5c51e2d97cbe293d39f270bafc0ef97920d83ca6a8bdacbd4ad1f5ff7e6643be13f2b6a7826bb03c87c99608a3ba5088c5703148928b30fdd459d902af837a8a51141a10b7eaaaa47a5458e28c10c8c92522efccecf7961f9345b4f9e00fe08c1cb01d0780199ce25edac27918db9d31adc7bafe055d4b76bb6f6b92cfcd8a51fb57718413e6ec3b7b2fe695baec3c0b15f63c91cf1f2d5a471e83e8a6ef73db86dd44c8284e0f6beedfac5d50bc2a8985383610e388d4902fe179cc3eddff4e24e2d4585af1dd5027fef0f6544780d1b43e3f23c04db2b00f3078986124369b8e7db5295588d3ec5340806229069c50e91c1e5a63446ab7c5f7245df2e3995ff5e39d4f5c4c734fe01ef23371e79420c43efaa0683ea212580d7e4d2ab5f3cd988a26ef9b3bad91571df86a97\nlabel = 0e5192d581dd952ec3aff44952004636d015ecd7faed33c005928a26bc0d30e000000000\nmsg = 0d9c1280709b3d2fa20196594cf21174401bd42de9f550466a506bf1f088ae58de149971a848fc31a4471bc8500921a2dd2c5a642ba523c264e5a1e0571e960df2c7d3848705791fdd05d6518e92034740719e5a25806a19c9fdc454076b150538dc7e949f3c997c17c1d3beb28393b00e4778c4d373e8b7e4acedce664f9196a6ce3e1e2274d793f58b34a50379bbba57b221f961c0b10dc5af3fe6d55e368d91357095c0ede3cab024f4d6e38884616f9e9b8ed2b185036d44b54e3e26d2d84b0f8b82f401a3bab3a8e2fb63a1a7a29e10f821762ba1bc904a619c4c82ddcb34c2091b8326fa83246ade38d516a3c04a31c9a934015ba0dbe6cf992477c52e7d13bdb9fef43230fc19fab553c04337ca331860a1b1d6af4d99ecef5bcf2e28f67a4b0182156da9e5e7b9eac9e8caf6fd5a7463e31403d1ca14195a25e697e0b8b3038b2ae86cc6bc2a3aef690853778984ade5bb45239982aa99c961936b64c8e89bd2f35f8853fd1df173d1afafb939bc4171550ded9ec0a8e6abb02656e45adfab051cc64040a736882206eb723b5f36def6acfc31a51bb6524dde33205ed599e38d7976af79c6986fed1f6e7c064ccb6d57599d23bf9a1c96167c49\nresult = valid\nflags = Constructed\n\n# tcId = 34\n# em has low hamming weight\nct = 904f9e8ae7e411ed6172cc00bbbd2ad1149573d177a9a2eafb9c0a6df18aec5bd83c1e4e865b35425e562780e57e6d83e1b5258978a444a1f91fe68be1bc0c529d64702d3a0f7142a0f0ebf9a5fa6df32d2fabe3d2bc7aa0b0f82a903c8448e0037a8e204336396d5ad28fd8483159e45102360791d7c343e973b38943b0851d339f868715d6ac4e5ab615f9d430d666032712e2937cf325977db79cce435d8e2c6d75b306b668f72dc7cf2ba2f8eecbd23b54878d1624ec6d7fb72ba26e5ce30603b66edbe87d4402e989fc75352698bf7fb03d1b5694eda874b99e7be2fac348f1736a351207f1cad43da26dce1470a55a795f3d11fa4d6302f68b88d976b2989dec0e669388c62cb555b929bcd6b5e4e2e42b06bf23672f8b1ab3ab2078b64a598be8d3ea6540027f736ed1d75531c0ecd52be66328c4eede803f70e8cdab6524f226d035926603b27376fbdd28564d8361f7584426188ef5318ea7332619bcfb2eb02424e1737ee0719562cc9975e4a0cccbd6e41d9a133384a62dbd2fbc36c928827c56f275731f4b197374e99c572d190a18b35f19bd9f5d7048cc9b9e034aefd724638b37a973348a1b5e8211c24fc16795779885acf915a7f2baa7087ee16c125a417d7a180a8c969b0d958f3429e12bed1a8d24b1b1f3d315145169176d69707d60e34ea54b7af983722ad91a05ab44f8450a55fc2e6017d0604aab\nlabel = bb9da557e9104db1e8ccfef13fff9a409a7d459e1d4bfee04ded3f75aaa0f23300000000\nmsg = c41f3759e1d39fc1a701e34b0876440172eee941bd9a5bda66ce86ba942527eacd2a8089adb0d9112c57437818d1cd9d0ad82977a20a88f8599e23b123ffe00fe0b9dd3544fee275d1e48f072bd4eca1e3a3a40afb914f22d3cb06803575442d04a2dda5bb93453372244d63b23e9d8a250c54f27657ee68024abe1ceb69bc3a4f5933def93f4b1084b30e2577d6eb2e21e5febda06eec675093c2aa117b7024c82b2ffa9ef5d6bcec8481c5345843504ece69e52a8a57285f048f69b1afeb735aceee081655b8381f632966f3e34eda7c8b6a7bbf4b4c7af65b2d9393cb4424c94930cf941d15675c6b12e33f892e93cc11271affc6036434e9514c0edb18846c0962ec369f4834d0ecdf799f0b36f11837533d3b2b71c9a819008a14408f0e360d44034e14bdad6dee228e37ec34bac910970e718ca4467a71393b59135e19f2dde5b693383e9db1f8f890b5ae64a779c6ab4bc9b48185d1d03d69037dd03ff1fc4aa7368282ec50040a28b160fb406b0a573d0e10e1906e0665722a07743f34c8779f3d6ad56f4cc3e53d3e2ab666684bfe67cc631e1705a47df516cc440d8ce171be464a68cb9a2cd43d1b92414bc3620f2c1adb8e53130306750414\nresult = valid\nflags = Constructed\n\n# tcId = 35\n# em has a large hamming weight\nct = 47b177a8fea05a0c3f6668bad507fbd3f0278faad6938c69b45826043cd24505022c2ba5fe8da4f4f4eccda8e86f4b4eb290b5b53952a803326a60888c07e41b74496bf4f5df9aa6fc884eecaac5dd52252d4631ac09c3df407a28b0c10de2794222b4a5379468a407805f25bf6077f8ff834f", "c49a01d6b12d2cf133fd37f648da7a24dc19035d8df2ff9da5135387fffc1abaab10028bc3cabd79ddb8901a81940ed80d304252b38d7e62ed0bed5061010737d88d9482e99e6dd71c1db75922cb2304c6ff0b594372dc7d73000a80a0dade307bc7cac2a9e634c32573ba9197b6bf554ca549227815325399560c8aab7d29224d99572c91b9148b167d987c19c8e33e7afeae675d5b4ec8dc013d439cb96c9e61ffb67937172b7ebac9decf7407c2cad48448cc5ac696ae4b53454f75aceef6e7a9fe7f04657bc0b08f3b0373324a12f4e0a04ae842483abf2aa9f11f236cd512cf70859d1be27b58f7cad0778a34708770fd295295e89c6ed6d055563ad5e7b30b64042860d2d4a17d7d53ba648ee27639ec91a9cb4dfa9a640f18dac43a47717bf1bb0f6371b44efc63b970324a8e25da6e0e83eea6f835aaabb815eac784aa023866438c2763599e078242e9a9aed6895715fbb033362fb2f1b543d9be3190dfbc2420b57c16816813ec78be3faa05604379ae168ccb0d6ab9509d0a84f667331e158c1644522c7b0ca862\nlabel = adc385a5ed585a2afe16f5f539620a47cc3352cb31c836bb72e39dc7a23b84c600000000\nmsg = 12087af4d447159fa47d932be56c419788668b8da88954239531178a718810e3a6eab3a08caf92b39bf1500d64eb0f9076100fe45b8bcc1b04cb6df9cdf05cfa1f806361f6c72f2c7d3afa9340d3b5dd1e2381193ce01a150701dbf4dfd99b8fa8bbccb7d0336b2d5b7df7a7d60a2c199ca037c6125a20c115df340e417f6ea87e7bfc53b19108dc404e3caaba3338e4edbe2e66aab7fca73fcd855fb95557041c59256e35306c102ba3043624c4b01378a0dbb3fcccd81e9907bbe9f17d44d0ab1efd0cf45d8742afa55ab4efb08a84e1579cb57d8c233c0021b1d22c32b6f6dc903d63f12df51959b06b7070077ab9672bad56608c22e54dd5cb4969c9798bbbffde18cad39c18d8f392df84fa68142b383d4848ec907c251af6aa3b8529b84100b981bac087ddc9e1df72a30f0e861dd4cbff9b1583229ef9610217ff4592955db67837842394f4a7789e8d99255b999f61af7244d23e66805f368340c7662fd398172d326076936fd1e5752cc9b176b30cface1bd386209c50fef70e95f6d7ab854ff75368109c277fc169615803dea8df39fb4953f78c48a42ab137b0e6ef3fb7a7a45e5790773e8465d014e18d9d51feecab8f2f3e168ea78d410b\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen151 = 39284; +static const size_t kLen205 = 39284; -static const char *kData151[] = { +static const char *kData205[] = { "# Imported from Wycheproof's rsa_oaep_4096_sha512_mgf1sha1_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 7bb0b14b4fa435505b69876e65a3a3f8892d61dda53709f4257aed4c8aa91f2351cca74cda1989c898c88e4a4dc60c583fe2e5f73852933bb13942bef04b4af985f8e56fec2d282ed9ce56f27e452bfdc4ff6e7295d95251c264a36743c14fce78a2f4ac6bf8ba0a8ac5f88c82524a1610abe7548b7f6a97bc744473ded26370bff86f966885ea31787b058197ab58830ea477fb600bcab4e2f133a613f9f125319d272ea5ea323fbea830ee146725a86133c4167c63ef899edebd2f91769329181325b5748a1146407901a8d8bf66da94dea20e64dd3c12ad7251df719dddf3fe882b6a22a30ad1061853f748dd83a72839adbd885710cff95d554c1bcf043dbb3feef19d498e7d8db5caed36bd0d44470fe7d7d1a1b0eb4c391a0736bbfe04846ac98d6243a4e3e58b57549ff7f54c92f103b33c9db04fbc6b36fdf5191567a79bb35a0be94a45480cfc28d377be27da9c2c3cc0bb2a4e910ae44233305af6a87387aab762c63d969714be53c0b8a26bd20cd63761b373b815330eb92a1fa7e6ab827276335dfec94146548d073ec828f3793a84cafa12126196a33f5fa2f4f2f6470093e99b2b2d91f2ff9240580965480d56c74be39bf42408a0e41ef60dc080898ce3eb530d87b4da4673977055e83d6504a89d60fb2f49703936a2fb391fdc39d59608d500870511b458c9e45e53398db152d3871f18d61b9afa4435c9]\n[e = 010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3]\n[privateKeyPkcs8 = 30820943020100300d06092a864886f70d01010105000482092d308209290201000282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001028202007bb0b14b4fa435505b69876e65a3a3f8892d61dda53709f4257aed4c8aa91f2351cca74cda1989c898c88e4a4dc60c583fe2e5f73852933bb13942bef04b4af985f8e56fec2d282ed9ce56f27e452bfdc4ff6e7295d95251c264a36743c14fce78a2f4ac6bf8ba0a8ac5f88c82524a1610abe7548b7f6a97bc744473ded26370bff86f966885ea31787b058197ab58830ea477fb600bcab4e2f133a613f9f125319d272ea5ea323fbea830ee146725a86133c4167c63ef899edebd2f91769329181325b5748a1146407901a8d8bf66da94dea20e64dd3c12ad7251df719dddf3fe882b6a22a30ad1061853f748dd83a72839adbd885710cff95d554c1bcf043dbb3feef19d498e7d8db5caed36bd0d44470fe7d7d1a1b0eb4c391a0736bbfe04846ac98d6243a4e3e58b57549ff7f54c92f103b33c9db04fbc6b36fdf5191567a79bb35a0be94a45480cfc28d377be27da9c2c3cc0bb2a4e910ae44233305af6a87387aab762c63d969714be53c0b8a26bd20cd63761b373b815330eb92a1fa7e6ab827276335dfec94146548d073ec828f3793a84cafa12126196a33f5fa2f4f2f6470093e99b2b2d91f2ff9240580965480d56c74be39bf42408a0e41ef60dc080898ce3eb530d87b4da4673977055e83d6504a89d60fb2f49703936a2fb391fdc39d59608d500870511b458c9e45e53398db152d3871f18d61b9afa4435c90282010100e97acd5f64c460b2cd51cbd70af5b4caa2882bf6033a92a23ed80f039e8a32c8a4c483f94ee1bb89c1dc1f6d04360a1c3f654251ad72eb39cccbfc38b072054bb0f21b9d516ef272e7cf86f8a8f838eba829e7fe9d803d469a1810fc5b37476333ddfc0cb6f00e9967970b4e474e04373f8dc92df50fa155e3139bfebf4e1cd274705551f2e9022029bea4b86664633d13fd90ebdd0b72d95a6508b6b4354e64b187fd81d21a0b1e4a853c27df11d7fe6c8953cff6344f50ebaed2513dc03761e8877c71ffa8005331043027b8dfdba97cae037fd5d1fda1f145a200c0d20f8dccd62e5c489eea8ae827910d3f48bddf0b18dc3089069f96d800de47036859550282010100dd1abc951ff1474ebfb70807b160b110b1eccef429c8fc8535ab0aa98376a82d3d33af906fb0395750b9aaccd8723cf73a8c3a6ad5c3a0929178ac55e1bd1ba1bf5da4f7698dbf09e87c84c45ecbbe8f12d3ed1091bc470eb2c733c31f8d27eba9718ee78db887385bff6b67950b79524482c50daead4db0f5676e4b92875b5be383ab1cd75e1cadb59cfb5794c17220154aca808f733a636d28c016d9843940bf44bb15ed191f53449b1651b79554c23e006a56dc0232cca209bf2d3c12cbbc0ed8b3110aabd365b603ea8cdf15e8b9ac781155f92f39dbf9749f70df003195a6bb169ea0e0d69eb3a18ce8fbcac9be3c710e797acb5c05a399c2f102947c870282010062f25622fd53741f927ffdc10eb5fe7e79cef7c274afd800c65d4e4f9c5ab916eb2d15390cc301756a20dd7897f646e69dbf4e11cb4e0e7e1a5ac0734de3a476e570555fa069427a8bdf19363c75a5b9c934a94af078ae7f4342bbc016f02062dc5251451a2a3625b10f040d928e6f9ef262264641baf406b00b596ae6ac35eec2c5f082a04d3b476229972946cb787b2403abed296a76abc2715af602fd2c51e422dbbeaec9b6b889a0595414673d806782f37008c9366bf6d5c9f000197bdf146a86c4d131e3a15dfe8661ef297fb01e54a8cafe54d6065177cf263e91476232d2fa26c5e80342070ced9e0d99c84dc4282ef8aab991dc9d8210b14bb267590282010100b83b9f0763265894758abd562ba6b5e3835e1ed3b43d94ac2a9beab674a45a5dd7b14988c087c63fcb33e9ede62cca3ff6b901b4238a6e31b2a52a742534bde178e33ea22981c2bd2ecb1295cda757913fcef6a9e7c54a302527772a0f103f434e5d21063040a1eb843cbff1ff6f20183c9dfa33fc68cb63b81806ff518917c6e93cbd47baece0589e0bc022aa00c66795564c85f301c095384fcc3f3ddfbf15044af0d8c4473aa2d777a29154b74978d0d0e7ca9867fc8c263898e3c83aa12881f66ebeb4759820181a0b46765c7b1ebb67108ae2a7473ed40d290d93c3458dbcf00759061452c0ca4cc26d1fe149590a63e9fbaf25e3f78eea8054f22167e10282010100c301f6bbe5fb5693f665b26d1a61e1de87e38950a5825270ee68ea5a5667e11a3aed28b2266768d1a3db3437dbda681ac8294dd50ad0b4bc5cee5694831b8df7354695335740b9b7dae5f7881536da6a6b2ac4308a0420ad6e99cb779a6338f5012986b1c1c889444d90585fb0dac995ad6e93af7eac717c643c4b8e7023cf57cfe284ca911d6dc3132b08e17f4e8759af42b43ac929c0259c3a1d5e5f7c4b247e2f6461aeff8577aedc710d6d2d56d943c211e47467421539dfc2700663c4068031b695e487ae6910ecb9c547cbfe12cc6f45b658e2c6f9f8fbe805304194a9d1d9c6d599c5ac5c9ee5fa78c8a4583218f7dc8f4c8d3adf275eec0e0941fa69]\n[sha = SHA-512]\n\n# tcId = 1\nct = b9fce8bcad33219375323a2e641de7650c1163d9aaf5f2f0c5b96230e788a9cb970fd4cfdf9df98060267e302b133e4974c0cd529ca1c900dfea65b46078fdffd9d589319087bafdbdbb8467013e48262bcda8554b225dc3567887da78976d5d9ae23ca9914248debc2383634f71d171ad375dccad198eabf391f4bcea22473c925e18d5210b02c555561592411d3fa6d2e425415a83fedd651718a8a7d1db2d81f64685c8da9a05e7201593374e30173ef04b42b1f16f0b8a8cff6c3ccc6b251fb61957df57176102a8a03d9718d95f3bf637b1fe1feefed9d50ebf9ee93a99c60d2e404bb78f9a4292ae280206782564cea8e2ae831f9b5d629b88af7c610cf28f9c6ec56534d16b70ebee0df20f8ffb40afdebec977d16f84c3e583a1229f0d2a01e0959b1cbf37448ab947da05e7cde1358c9bdfe298f2da27d65beef13aa13cc51f04c18560c054dd8f85d34ec759691b3d8c72138df12e6e442992a2466e3a6db6bd322d04c069741e0accc5f291a6520fb42fa001764c441c37456f9d91ab31c94283bd4a299fe4fda6fbd132e04d8d92157bf9aedc80c66cf7046a33bfa308ea7f5f56963edf4d804483e631acd033f2d9ec190c6d04c55540908e76f9b3749b8aef86287818358e4470cacc6d45fee370bf836d2b9277d044487aeec4064c74814d2c57839f6bffacdabe1f2ccaee4492b2a5b1ab7f3055d2569c58\nlabel = \nmsg = \nresult = valid\n\n# tcId = 2", "\nct = bbb5c693aeb28296b4559a792e489c74bf21c3739153be06dfd336f397f16969fb1ea0523f0adc7e206d908ea2a8eae1011217a54af3beeb6558bd80f2c111dbe51a0e25f3ac65578d4e7f6b41bede65813bb551c97cd70485b81d70934e86e6fa349287bcaf977e666bf9526db02e76f82b3ec2941c2c7355133adf80e16fd8c4d01a62f63d1e0e6d67a247fa2084409df92f8f528ddee355bcd9cda753010bae377bfd6e1a29a4021b239f98cecb5b8932c268393dd5ebe58d42f7eb59fd389491cdf05d29e7cf8c148caf71232853203dd76bf0ef8ce7be145196b7bfa83eca9761669fdc281ecd66ac37d45732c510b8d1f520f8be259a2de0220068a5c741358d4c34d72ab820e7791764efad86c4113988cb71ca323f31683105e273c037c02b4d4b56e7a2a341f9348180cbd671f73adc9767e050b58b99269b5fd696b071473e9d767918d99ef0e5e69859bc0a3133be92bf38edae5d8060cd5c13f2aa522d0389c3a5af934f81c46f83492c1ac6e856b2b1e3b17ea83a7dffbda5e8f4ce57e5c106c5c337ad286858af9ccf44417f2e0cfea2f196d89e078d9884fc176b02673d3295fc3849fbaf4829d7f310ca53a3861e8704765e8654e2b0274d6bf43152d13ddca60014067eb1d5589045ceed16df90a718260db6ee83662542c8c6fe47962d18758824b7f276dc3d94b6b8bc85bff1babe91b13604b8696078\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 3fe06a589140e2e037ca786111219bb545a189b506c2cb52376b6fee3d8c216b33578a92623f4852d2c82ff02db90b9266e5fd0301c8e156a44093206a8bf93c48022738a35b834dc025db456dfe003026aee1e7144f95db86d357dbc93d11ae9568ebd700fb577e9ffaff19f324cdc30332c0a680c47476564de727eccb1a974826bdb384a517d489901cc5f0afda3be84fad6a95435aa8cbd91b0cc5d707cb4656303541b69e70f9327c2ee061d96a223bb6e29b5851bcc345ad6e47feb0b86565706fa575fbf7aa4728d997023de295f669b34ef205feb24ebe07074b2ccd0fbfed7c3b543ba56875cf0addd47b8bf0375a5706684763dd7f7f0702d43934726a1d2600a668b6c4b170c85d0a4841661bd946b0c1ecfe801d1e366bf4432e756ecda05afecf29338edfa80677e3f21e54213f77c673786ba5cfee8ee800d651414d055d51edbbd2108afa1ee8f354ea7427ef772b31d12950c1359e9c6b65a1e2a2636efdc0cc6da8956ff84977c25cd67e31c88d27ba681626f25acff63b056f402f8f83090c5be0d51b6b9ebee8ba48ba88917b02058f4efdedd354c63063ca470036e3ef13da38c9462da836826d9472be5a6133c137f496b2337c9d470478800f67045cf9b1f5cb072847da6981f77d4e16f71181e90748c40c79df936e36ba4d4810cc81023591a82465f59e0b98f8dba0b0503b8bb9ec28919f0d89\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 8889564896395f4392a9ff76ebd1e0f5b3c5254c83fa7fd7bf614aeac559db65999171139bcd3c0fd6adcbbe7adfff9d8254ce2300d4ffc48ed00131243811677e8916cae0ff5752d75135fda0acd167b0e383f48e2cee184917d5f860c0bfc88a59d54587825f75db894de2e9f40bb3b168db171e8844d64add489ad839f47a63edd6382972d133d1d8887cf120a1dbf4cc3ebc0845ae85d6abc4ca82be90648ff4905e11e9a37137cff9400a0080e2d13babefbcd787a86b75772dd8461d5cd8a8f3c3f14b7b305ba6e51c765302981f0c3632a2860fcf61735396fa39bd407100cc1e8dfdfddfc0b87735b0ddefe96f2a2de97f168e41f2383c345ff93007f6fd505874f2c6cf2ed6f30ab6a2c8bffbbf6d3cf32ee716c85697db87f2f2b0b9cf65a48cc15187f5febd3b015b3339815beb3b02f418bbd3e7c6e9fec74374a1fb7ce9acef3b75292a3659b04f44062dae0980f6426dfb1ebe6d67c6cfb887f5fa3f9027ecf4936f3c0995acc540a4691cdd28909b3df8c48a4a27c9772763f98e7dc7d8a5497142aabf2c4c472ca397edf2fd1a74af576fbe1db292fdbd140d64a3c65173c0656619f5e5b3db0596a955bf017db34d849f29902f8a08544eb8aed66579084ba3aae9646d170bb76eeaaafa95f34295f2ce86b8bfff613644cf1ea061f7af8ee42df5d97a83a094d07219901d2e1ef26517364a03f031a3ad\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 81935470cfa189178b215635b35436bab84d880c42127d5bea48563d6d1e52cc4116d8ecb9dc9d30b82756eaf8981ccde25d4b3555e1e26691d92cec29103f7a514036ebb1d850b795ad662c9bd6c63b2dba32ef4889419b740d4cb38283feefd285041ea880319eea371a15e99dcd02761029b5709232f5df156594259cf6f63f882c22a3c427592ef86b0e4a7d0b13f772234fd2889c13b157c2da6a94c3e3807771059c970a3aa786b05d79c92a36607fda0c7c3b7279402543debcbf3639b3bae654f48b80f65eb9fcf5d4960d88b8906ebb84aca936b7a06e4db3be1bdef0fd16af1a3d0fe03203492a0357bc7e76eccfef7a2fc1edfc50aacd0d46bc7a28428b92f46e3d3a58af3a7f9e0d4c70c3ac240eedb878891a8f148b1e729604d943af03ed079787a7f67f830e9a77e7fa6e39fab006398e09483e6e848d14a95e902f2cb60252059d1cabf319bc463719132bec91c6e7bed2341455c16502d2bbd0851301f86e0674c9c62f54e6cc9bebc268a4a714320ba2d30e0dd7996720466a976d3c9e8a11e38f32050ed5e079875160e2c1b0f8d4a29a5e3f6d04db8f501b205e56f3375dbadbc77c4a48117532917f09575ebd5ac491eb1bacf1d157dce7465eccb7568b2d51a87ebd493fbc9275d5b253b05d7744921cdf5c274906137b3076002a2c10cd52cee21a17feb9e35c5ab3af3e0427207c206fe6a068ab\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 8eae919086dc6c634f495a45d86023caf497163b2f4b63ab9dbee8cc8c139e41d83c5cbd2c54b032f79f3bc37e93ed2c7a4b652014b1fe4b607bca3529aa160c84ec89910bae46ae4d6e8bdd384ae8a5a18a48721e0f59aa9b8394ff821dccb8e222e7e7a2a33e3f02a320301e2e7a7c315fa0bf9f9c676e6a4535c34b621ff8345ed2b7d5d35014610040a9b3f81340f4911e230f356b469c9c6035de42048a68d5f04681d85eb9c2891c6a57a29e8e64cae0b0404d4e374f3188caa210c4d1378f0012805d7b91972d085956f067791529fc0357dc30aeed5fd3bc5efad687e5e9ec50957ac809d683b02e5764a5d8434e5e12764672807e18198c225d346b406b4dc06b9164ba5f3ae719bd376643727d9061745a2e587718206d66b1648bb52090b224c175688ea8d50b43a1d08ffbb4248ea7f351799c7e50f2d490e466722ece2c4f88f89d2f96fb9aa9ba610ddfd6cfa7b7a9c375e95575ae51c5d6de43086fd0c0663ff88035c3adafb82469a77556a91d32a421e33338bb16195d19010b58d720688d172ea7d64fa50caa902bfdc7b78c7bec427031ae9e3f691edd91a90c86e2e86d00dcdde12076308e1fc4c910814b00d751fe2e44baf232c4934b58624c1da5bb51b0e8acfb454aeaae2f04be02e4e121cec2b980ad7c23d13698a88d1d545521c0624261fb0e97422bcf76f47d7c33ad63a8eb4e497502569a\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 9284f12053cab1f558770b0da4ac1122dac9f3ccc92992cdcf186b62557b265a72234cd443e39d5d2e1e88d4c2b3bf569ba8feeacb53d7f4100a505de9118cbd22d159ac00d2702fc37350780cf78a101d7447d82b6e0ccf9d901c58734cf9ce7b182c05315b31756a30c5e563da32224272523bf01291732ef390e90d0b16de359a944c8fc92ed9949e9bab4059424aef42a5ca7c28040f3c473c952c52827159eb125e2234fdd251c898746ff9bed99fa7cbb2894cedbcb3218526ea286da4e1420af5c9fe91fd4d557f81b69d36964121e5202599cddd4993cd8dfb82a48265771b3f940a82ff572e514f5eee9bb98f848a31e2d3f7271ac9b298ffcfd03857cd562e8a36daa26cac1f1dd173dbc4e4d5dda6f3c28e3aa8c8d54dca67091d304bbd3217e2c42bf13ae02867ab9da1d3d01bf196ec8be97da126cde6a0244673477e4f0c98651592e25ce1266995c7a41d41fca2e2213806394df9a7aef43a1d90609cae8511514702d890fb3230b8c22a34720435a547edee50bc5f78da62224ecc3335e900d8803aeac4296fc4a41d59806c811924bc2d4a6067dcf71ae24a6d7cea82597bd14a3149fdf718aad5f5a6b6f126436c0621fdac4297d646ad0e6f70d524a48e58988066694f3618e013825d03c19c75b9c9d9aca436424a3a9a58bdb92003749241661527a6878601970abc94767cbaf82ff3ddfec7478638\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 4db93239d2b04e8d6247a970797e21cda029a6986a4e62991fc489bb1036ad5ac9f5cacd7bb84584f0371c2781f81b64b8289c8c0bb1f00c42513bca88417ac838ec7dff9b6bdc59a4e3598454fce85bb1bde30db75ea83352358326386214dc1f0d584939cda6019ed6e4433bd6a45e3a7a27a15bf08b69b70346819fa1fad4ae11b1ac7d06834c70b1d25b0cd2f7815a0a00c692cb7d0fa1f4cb53448834fa26b344fe6e38560f48f6ac1cc170822b599dfeda6f3709a8d9ce62aa21d5e37f8348808d3b50159acf7e3cab7efb6a437001a596c17d31be3fc0f896b41091541f705d64541e84871d0136e251f8d31d24fdd101672940efe26b433ca084ee48a7d60c5f4afc1bc60b02d0fd1ea25a77e976b691578012f251f542e60b784afb61f3fc988fce74b9ca5be9cbd9657a7d88d68aa9544ffa2198bf5fea0ecaabd8752afe5c51819dadc5c728c2ab1f6f24d474bfdbbd252856c4b7588cca27801c61df0afef9b892acb53842b0656c91f4445e50f395d4bbcfaba3146fd6631b668f4f5c1897bd0a12f45f3d03aed84a26f44ce2ad7facc05c7035e675b0411a7ccc6450bcac760def267f79bf65b033f6b807ba0153398b5cd5833688ca57ec08b48fddfb6cbe4ba4ab293865c67bab953a4b9883f8b03a5441efa492b4d8f2b7d1a216d057feda7a9f388d3bcb0a28a6fb082ec632bf88cb411da33898aa9b9a\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 29583aac29536dd4b6a21da5a44e1e2b6e755a45c67f828156e1af72c7b7138374e5110ec7e3d7385f3791c5198d16cb5c78fc6f0291716ed818ec6b6d0a8cd4a95e3712449f0e6b6aee58b75413aa6cb09659378fe2a43ec789310182cd7eba7be97bf2b38386508116c8d693ad3f49a825e1cc0f9f692e1c9e955a92d4988408b2e940ea4539a3579c55a1cfe91d1019c996cad449ee8d95cef7d84ea27fd992532db562cb5d3dc30509c9ad0ffc624aa8ead95ce75d914ddb89f5a6ad950323fcf94830744e9af3681eed79a3b1d88252b46ad3ebe55263c003f4efcb25e17b97dc7a3c2d5dd9c1b1b8352dd3ac3665172fad40d9a7e9a9a5b185d2c", "b383cbbfb0bbae7c65e186479da5f850f466391ead2670c7512c3a24a35998283520827122e3577f3b3e8fccddfac3cb30f56e1f69f9e3c8fd503cd3daa2492b1d6adec372e11346ac8e6c7470dc31336cc9fa256634e927448a8eb7b36c49486d2f24123be03d021bd6058a0b891c06a50dbde6d8106de893c046a98d8ebc3ff0dfab1cbad8188c0e411b619bb1d4bac1da82093804e81621306cc06b34ddab2a944e1ca809a63c5ebef662ba409d20f1c980a311ef4d46a0d28921faa54d1d48a6f47b06292ccb4deb9dca5af89d789101caed8b7745c5439812c980c03a8a103fecb3be579c450ff6dd5920ee4fb7144f243aec7192c4d4a623730b01cd323a381\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = a0eef89abaf87828a4359fdaf9ad21419045568dde6cb1c4975fa744cbec96a60e2752acd8b05785f34b9ea28f825959422f50e2326234ff6df151617f00274446ceb3eba0ad79476ab70b1efb932bad03236af106d7c5011cfb4fd9b19ea26393651eef432422ac892f6905f4e1ef1f6c8da0c57289e93f580ece8bbbad8ed8892a5481685a8ceedabe4944bb8bf3022cdf1d004be65ab2bb24e4b2b1495abf0f0b162cf02b949d431fe6f629c9a80388876012e1fde67fdd454b306c42899b92665c7ce20c3c005a0bdc49eb32a482b410fb4d10918d7c4bd2ec7118980d88d567883117313a7b2c49d482686d8f02659a2801c4cc237dd1a792f2b70407859cac860263f05854d96fd588f0d8e66bfe4b04309b8869693e95f08ce4cf3662fb03b172661c56d8033563a883a0933fab91ad2a833590aefe1f0152472582c54a533d77c232155a70b628dedc6898675e368b84aa1b757c40baa07ab95c4a450b7097205fe751e415ab68e5e579a0e5de2bb9eea9fadf5a7b53e969ba85b023d8f0c6d749571baa2c531ed105531078de99aa935266d04eb82699958047ec946c63384d431076556a7e6714a039306420c483ef52f0ac7609b2a2754b31e96c9d2cf72357b8ca5c7a683b95ff221892058b1809df67ad955ae0852460374176f4a042b31545146685339e928136ce173aefd8d6f5066b3777ccaa5e5fe312d7\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 5061876f8bdda06553a4f653c4f0a96a96d8f823c9484a6c0c21ca0344c6f9d15086265fda4f6f14573127dc073631fb91ffe0082f926d696f974b22f4f9c899dbf16feb967ab9c66556a4e4aacde7df73d4c789ef2eeafc23dd06d363ce3f70da60283510512eabbd43cd89b7c014240c35266b87d860466358840f85ae91ff3ae033c7456c74f5f425c4371ca76bca86e2a9639f9901780b1ce20f652644cc504c2497204fa6b51759eb932f4e7099701718476a8d2cfcbf95d70845d7c0ab4a264cd023bd5fafd5d3d0c5500b17a38d0a85593e042685b6074f4737ca181ce3f58f81d2b29e934d44c665713733740832079c3888cee12a5435372a32df434be0c03698d2e2503adc889be76619f4076e02b3517e75a94b7bfb58faa31e660682e8964aec6abad3aade06f376a9ac9d3266ef1e4e51078c446ab6c1e1904e5a1c5b121da4767d53e60f9cc1ad40822ec20c19cb3cffc61fa8f211a58c57b2f79f4131289f0354eddab2bbaa01962a25fa19338b2e546ec96054013cc3c2688464ac77d89fd3106621080266357eeff963c2b0244599d4a594b69c3eb4458187a869544522031235c6a8f3ddaad154c15df7380b8da5ba06afbe9d5c4fc1fdee76b0e90483899d564eaf23c5df73764d4af52e10aa7891d82f26285ef441a785ba0915feb6df082044bfa6fb6fcb2a3a9bb053afea9c015b9188a4123f1038\nlabel = \nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 370fb94a46f8feaf018d0f2b9690189bdb29942522166645d0bb7921bc837daac9cd1bfd6ec6f67e4e88a7ff996932c9456314f2aefd01d81c9246696a74f0818a1f05b656ed5804bd99f2a9149277f8e5246e0f9724ccd5f1a0dc637687389bf5540d4873b535c2cf6e9c491b5caa3bbb2da4e71f1c27b7681a1f03b8639139ced480875abdaebf627989ecbcda9373d71c431513b8e937c4bb259db0e5bc64bd42da435ee9cf5f700f9587f32796e97eb5f60969c443efbd3c92f310a0005eadf2301bbf6d5411f7800603b53b6f7bab1072f9e6af0a01e44fb8c9677ff655de1a020b8a9854084c185179b49695f7ada1ca5300f1c8c61cf616ad7c8ef8b8f0250411cefbffad9fddec87dcc9e991ca5ce1f16049327704a73e2d46e6703b40c70e569ef52f0841e89d28da9c743a71fc17e3c23cd720ab7ef22a25d068e0f205a708fafee581787156f6804076ce20546c3dbf2609c9a70f7ea85915a8d0b7103daece1017fae3eb397e7f8b4c9d2ed708c97c9d7e34de437ddf5db42854ccbeff8be2557548bb1e6b1c443fd2a726e36d7ecad07d7ffa4f304dd374180a7456f2947212cb8a767a9241c537211982a9d42c67c5f9717eb6c05951f09a5c40c9d4d4bf6675ba071652912dca387602006b99455aa66dc45a170954700604296cc45204f89d5f875f54751f48b7b10984ac60cc5a46b55aac7443e91bc3dc\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = 48a28128571fee7bd47d4e6645181e9bd4fda711b9a85e22ea31ee3668c2c4dd7f8f2e62bc155f642fc37c0f4d8327d06190242d9b10cfdfe70896e948a0272dc93c48a9ac7ea5211f6938e8c969c88ae3564f27a190b8fd230ec39ccb3f0a8aab83af20906b39a93bdc8d39cb09edc2f393cc3bf761ccb6a742b9cf6e7586a22f885ce9a9d673dfedbe4e54ea710c446a5489d5cee956b781013c83dfdd92d7af84b909b7bd4fb92e32d374398b7bc9f7fe145e3930bce6f600546b7e645b085a213200bfb1ddfb1d52a3abadaff9565416e526a2e065f8de084e2b729db9da4b413894a7bf36a50418872b64c65fcf92e83537f101bf9190b21bb5f16f65bfb50004139d36b78814adcf269cdb2c2b7dd19e2b380ea83b2af202cd2245f857abb0ac9208c009554772ba5bdb1b2ef2a3889c077e3c5641b223a04cdeec295ce6e065478a9f26ced392fe29b971b15ce35389e68fe5ac48c00750bb26d3f79bd7cf24273c5c232e7e3569f6a315b5a570cf6265946b6a006e4045b97da36792ead0677dc864c71903234ac1471ec2bb3faed265e2cf6159822b7cddeab67897bc723d6db29210e46b4da283d6f66330c035b67eb21f179f1828272b2a114bd72d7a5039eb63b9865c983f700070a8753766041489b36d6c66ff3f552f0f766bbcdcb9f58a4eeba194ef89e0ec68f47b93de49bc3006196faa6298cc7c7f1099\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = 5c8b5881da1aca7e3842d9bc22c5af2dffd0d357380d7e95695af13a2521084f373dc2827b999094fa8dbaa85276b97cc95be2d0923503072533914032c696ab44172520a7f0ef999a7c9140da1facb71b44ff0b09c9e64fa3eb584aea20f1df0d1ea8f816b0bc4be4d59c12f586fe4811d84f9c3f0509d6c729e8718e23f261cc35ed38387e5ded781635738149b237f3c7e736a365d656175806cef25f50cb61271b4a0627e5c42c46398aa146e29cc27961851543196416766dcbadb41ff39c0205dcc43679391c699ad8f1b7202a17c7c6ab98a5edd3b04012546919d924f8081d2ae6b259a17e0a2f50cad28d3e4eed4a0d7f922cc5792a26ef2987ed8ad6a8b6dc3c5d05626854ff47ee4ee013ac85cf817833b43e1a856b8c3974766702c14e99e4e4b34e4babc99744c0a621820c234e2f6a3693feeab4c7db39744a2f039bb7e6269315861644474fb7586515bf340c764af09a408618bdfd79a944f14496b0d306f72e9540d650ac72079be5a90ba9ff80df176e8f762847be5cbeb391b7234eb1c37426ee6288d584af02b1529cd2cdff838523c9dcacfd7dd0941abe5b9f3868491d6159b426631bba86846321133bbefdd1c720a5f250c18678bed4cc4b1304b37abe5e0c7ebc79e85f615818cb2014945c519b9291331dc11cfed6a40258c8d547c0442a69d6dffc75b529e5fdad3aaccd820e89db767f91b9\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 256e3457626f1b5bb2cc1f82d7abcf966f487ea2227d164f5d9d60c688dae539988cc75a0f670e8c66abd77ea06101a9d78fabff1c5023114eb3832d561b48e99c977f351a4125af9d0b5210ed1473f07eddd6edd8905dc21189e23a1502cbefdf184534d64c257b896c631d6b3e17672170278af5850663207ac60f4da2151cc13939c126801477b181131d6857be3c31721ba2da42e7146ba1c2f3033072935546a6ffd833c4e8d5a733c1b1cf5854ade160c697e8f8d794bd6330af3a2268e31e432841910bfceac4d7c2300d942739c03a1234ce2195c28d4f6ec3b01c4ded49f811aad03021a7a7fcec212d150ed25cca815c461acc520bdc60d22df38f23a4e7fe25572ef55b1fb8a61ca50dd80a16e9ed0faaa74e7b502c81eb5e84e35f30e1b286e957195ea8c5b0326e5c45849ebe4a920dfa623a0295248d5338e888b7a47eb9730224c1f86663ba3bbef1aba30e9ed91a49d6abda5e0c1c5235767efef235585d81c789f7d83f3c42bbff9f327fecccabb5e35a070a6deba53bff749450c5883ccb2cb5a5545163df34badfe0ccba4b962ddaaa282d83f755f5b1492dedfb8c85c87e387e2855ac2ac6e669c981845f6feb77e986bc84bc16405a44fe810d9e2eae4af98352f93039a1495e4cc85522016337f75ddc3af6a2a4a5c89c8978c4d1d7c21bf16d4631c6406bb317160306aaaddcffca48adff7afbe4\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding", "\n\n# tcId = 16\n# first byte of ps modified\nct = 8324d6f1ee40adbb9d76a16187d9d28aa2bb90202d7ef7bd7ba2d01cab0915fe4789aaba1aec37fac4dc16d4b7dae25650daea9d26cb1bfb2a34b622943f6e3fd01cf3479718b906afc21801acaf43d8bd91b7c2bf688923609ffddc7043677e906675fa06701e0ce610041a687aa5f001a212896607d19574280acec0780c76a8d5e9ec1b327c9190527a5f1c13a0326c138e0c7079a83bfecf601aef604e606b70cef7bdf1782c0dda68c917095c1a027694c5448c6653c1074ac923eed2f06fc96810b353925f33c48e509aafad75195f06332c8a0c4d05010d2a14a1b00b3f474a35897fb12f61d4caf772076db8a8f4fee8205f7b6f0ce12200ccd45ef177481def6f74d4c4e744812eb2e4240dbe0095c8a95f060ddbbd69f6a1b376558081c24f647cdeaf242a153b5e5ea36efd7dd42a6280f1811035a02aebe53b95f847ade834fffd070294cd8ba8d7cd753e0506d900ea1e76279ff293f1ebd5d973fa9da26090aaba7117237c33b08b9ed345672bd0147f78e2c9ec9b14e4825cce84dc2f39284e25f85b11939ef7f0ebb50c058597d054fdbffd8128f8f5822652b1c75e38d32f35d699b21d5a73f9ec5e887e139b061f24052974f08f36213c5c6250aded6afa138ca53c0328b0692403cbe3ed569304a891268123660cac7080d92fcf4b2965159c8de01cca170ecea328326c393bf2d118efbc50f7bd227c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 17\n# ps terminated by 0xff\nct = b91a1ef2ec1a83116dfaee41a62d3813d42ad5e092e3d68b6b790a6213b322b08f7672e85698de1e9d650399ec6cf9161fb3c57d63c623426ed663f2add206630f5fcbdbc3111078b804b84bbb7c9da6c1e90edd8a879f675ae49d7cbe4d31c4b5c1b8918693844b85f45a981f980c8e15c407dadf7ebe288f6487b6a85cfb5a4699ac0295a003fd58f06d428b56b430496e6e738c18578b846cd957f592f2b55230a27faa2c3d43dbd9ebc41a97f1120bd0e0a7e71ceae24770933a5cee41dcb424756c9934f0f873bacaeba7f5096087a1fa9b320facd6df2d390bd7f5a1c8ef3b92ab179738023590fd962278905e54028a04f4c6537e4cced2c9f6ff8bce8cd8ba1b2ed7f317b2eb9b6abe079750ec65e10579fd2db0e8405d5dd1dc597eb19888de90efb0b982ea435db8697fccd7b77a2090b1f4db9116c59f3ce1b59309b22493c79d48df153cab3a7164ed686812ae714c2ba5faadf874748928b036967310ab1d3b17aa4bea2d663cb7325dd3c877886aa2136271d3fe514d78629cd12f294095a768dddbdbfe241ed8d1e32e7c2b1c1dfd061ad38a84708e4fac5611a973a66f0e3354cc73117217ff4263abcebf7c7465fa1f74e2ef7d850ca3d3e9893e46741a7e46da50c9c93f258f9c62ff71b83b03ca1a6e98934519e2fb6023241f8d09b8d78708462ff61f43bed939554fdc306a81051aecf7990bb9b5a7\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 18\n# ps is all zero\nct = 1d604ba6149ecca0f7e06492035e54d8b4b89419b39ae9aa2560d00c46de8a25daf8dcee5fb9f5aa6b00d36f080904bb41c72be319b3007d05d1a2fd97519e3acc0cd8d6f492991b6a2deceb16839f2c541255d026ed575f4cbc2bd83ee3c16d7746996c887e8c456242ffc0a8e4730778590711a998c081f2321c03593e85933127012d86dd0e5bf30d8433057e4880da06de4cee2cef6b3f8a7d93703cc0fbb6591464a0bac813c2a91c64c5508a1d7716ddf2b75575446ea87f8b94a8db97c95b8b977cdec73ac3ac3f9fc2be746a0b3ec323fc241ac2e22e9f5a52b62efe8a96de6b18c28df18013c091207c1029195b4137940a38aab6d59bf53dea5de16c977fe96d4ac615dcc87e86c044ce97a40324e325ac7660fae8614c56f86ba270bcdb766f5598771aa4fd149259353d752dca72afda5c86b72e2ce2f98a5478c800ae5a21e0d84cc1b1ad15355ad0be194c19181d984768738c3c7872ff33e2ae6f57b282ee6f9987cad599b0c510cced1a31793916a26e354079ba5bf9077720ba336bd98a275844136a433ba7e039c960abcef4b13c322695182002c1a39b4ab04b1994c7257e90fce4dd4681dea84044f6ab11df936ac8af219b72f17588abbe9080d67a0568e4b41d6869f8a1368188ebdf8d4c95300de029b3caa43ac7a08b2dda8a9aa3e6ad3b35a8b8aff9ff4c47b28dc35d06919a9be45833c107fd\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 19\n# ps replaced by 0xff's\nct = 96104d3365a60a8b4e6884fb18755e6d74fb4c114dd3847681d61303ef4deab05d2e34c44ebc6463ca72d641d9783cc4c5bfd79063f7dcfa75531e6c238b1ea1a85482eae2a8db6c7d25963e3bfacea905ffb37a9837707d5820eaead9b6958ac017d2e8ba7e0b1419780caa8bcd341ba025285798d2bc389ce095978243d48f94a2985966a940028d71083d75ff3c1509ea04af0f58d55b45982e70389aeb26ec44c9008df049ddf184bf0130e5671ede3b36836763eecb90eb544f6268c0dd87ed68f421210ae4efbc8c9601533f18cef68da370c1b0960a95d054cb4cab186595d20c18a409403f20ec25df0f928b737e369656fb683eea7a87e54c46fcf1a06ea3f2df95570b95ac39194c9f7d51ae98b295546f7b18f8234b95c99a6e9f37f99c638971e868b389660e95c12ead98f8526e2190fa132f7ddfa58b987ae9f8150d83477bb40d96f959483aee8f8b5d51b9f1df3e4e309db43c83795bf8a08db5d3ae0dea4370f5dfebebc5952eb6d4aacb4fbd3629cce8adb205225aa1cc7c8934e119f1b338151e545722c27adc368880936c56eff68c14ccea07f5c328d5a22e298a3a681c84d7ed4b7c5f78609b63822a327ad68922d0885810f797b27fee06205450b897fdb36c9c6b1c6a8f095b6ad15118c6424581918f3050f86a329821dcdd1c144cbaba537a25ee0fc4ffd90205e223eb7030c6d55e9ecfab73\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 20\n# seed is all 0\nct = 9e3b1e800104dfd28dcd147101435ea933562abff19d63aafc2bfc854596809842a68cb42f1110626176ab91a03bffd82b2290d05ff163bceb387601be00f5899a165f697b152b2812774910a5e07269c3266e5ad61957ff8e56cbf7fd896a0fcf14e154e50e3f795e081d11ddf10d8edd6263eb3e0f15fa54b0f16a77da6ab159b6ee22d74177d8ae5b05215c9544269d0f7a8013baab60516f2c7fdf631db996b5f48797015db8f2141a7f10beb71e68708e964e3457a48d6da6bded0525e6bbe10507aa87bf486199ffb52c67df477f9d86d307d8dad384b854939928e2d962f7c7cd6d309027a3d3689c26b7da4a648fbf3854f05fcc4658ffb3d9c35ded1169165bbd750c230a494f602b2a271425989f2a7d175bb24c0095f17b0de0d9e7ca854c80aa870edc6a02e17b1cd5a31a3bf3c74c2c18513bbe7ca1f6888754f35e2108ee1a2751d88dbc17dc1f4856eb8998151da990960f932f37c0d77aa44c25b5fe6f92c288f68ec83b2e8a453d608b2aab73224bdcdc3a4c46303c42106fbf5054c4f201cb96052c919e1c0eba7b7a88acdf38d35c6a998cd6d81d04665416959591662927bdf801f0de837ec3f9ea86d2ce82b07310bd4c326d757e1a56476f2ca7f5fad65a91f2b309ac1bb39c44737deca8203feb6fb18ae93ae546d7a23f6c908cb0ea4ba0183a25120f44659a112939745352e9ed922f478aa6a4\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 21\n# seed is all 1\nct = 576983b7901bd02be7e1ae3261de56e187b6acb5c3b891797fdfe324bdb249e1960d27b5498ed2ef4039391a2678306c8245b3fb59c3d9a55e62ec37f83df7cfa13a29cdeb4a5f9a03673eddc3d0faba2ee005b04679b7b476b1f7f9f841948a7983c977eb5319e6e667215b70ea465c5cf4d53ab87a3784bc30cde5b84cfc5f483d13eb3747364847668cf566a1992dac542f451274e31b00f21255e750022051d39983d77ea0b08e599e24caad762fce8f4244baa51dbc8b61c2d81ac1909fbc6144576efe1a60ea7176bf45f4091e32b37607477b20b721ee8e4492360164c98cd3b671dbed37e8c6692af81c566dc6e7d614932bf91758affa7e71fb8d5cebd71ee0165c0cf5a62a672670963a0afe16b726b4618d7ae0287a31c442edcb5e3920d363b230a027a0479578fa36c7481b901fba6087f89e6d5b18f8b80f503db8da0c67f71b7882c92da575d640a04a87d418d19857f4073429649f149a87406048a181c9d0e29a63b207e0a14cf6e40b9735e5e71522a779d27e767ace40ba92921e1b20cef245dfd04600a9d7ce98c00577dbb3afc36d0f6be77e493cab881a74522e2899f97777c943255852e3a61bcd69e375ac0939c37d38a4c5be0ed2ba60a5fb715e56c953865c17085925389dc7eda944d8eca151607ff7da2187a299d8bb5a52741593c451696ce684e066eb91137f6d2432db760fc2ee11306c\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 22\n# First byte is 1\nct = 9de5d8e7e5d4ca1a214e903fda56a012e739d704e4b910681d6f347198b1af54555fb28f1e4e071154f75374e09e4184f503d31b45358d72c4f1404501f87fcc4d124eb4573e52c30140e49aa6219e74f3aacf4ffb2e739bb96ec12e492e2a5bf490697b7a3b9f7fd3daf2f3bbdcc5c032441ff1cff63c70c3c27a7162afff864dc8ad1404ceb6fdc058222db8b69b1e4481f0044353d73b8e017a6a103030ac8d1ea2d0ec43c650be4fb8a410c4bc7ae813a06f6e3a393e5eb7272c52d1dac55a1834e1f3f6299573abd8dfda92c65071fe11be6edc0ce2561dbac5da100c4edfac2ebe9ea8756762d479a55132b0a922d7d405a301d31ec971581ae5358c435804f95ebec6286e7f7972a7e082f7172f66e5c118073a719e1a872665ea898a0a50c3d0bdf81b6cb1e890da4fbd8a9e45d78194dc687a5a91664003727689f7fb080d872580c6228601f61cbbff236caf521b76e527f5bd180bddc13a823a0ce7c5972466523de8cb6626761453d218170a37976e68113ad6294dc19ff06210118210c75d4cf2657f04ea9d79177474651044795bdfdf3c6959d9fc5c11d569f978679b7b81f9fedbf012dbf7b9b0652cee90c9059c98d7b24286304f7f41be1ab2a26931715c150de73775de58c2f12fa2fa353210ee1d8cb0f8dea22e9ed1d19df5f8dd349c181ad9bf5b9ffa5938f4b0f810feee4cd34356fc7251f5fea3\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 23\n# m is 0\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d2\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# prepended bytes to ciphertext\nct = 00008889564896395f4392a9ff76ebd1e0f5b3c5254c83fa7fd7bf614aeac559db65999171139bcd3c0fd6adcbbe7adfff9d8254ce2300d4ffc48ed00131243811677e8916cae0ff5752d75135fda0acd167b0e383f48e2cee184917d5f860c0bfc88a59d54587825f75db894de2e9f40bb3b168db171e8844d64add489ad839f47a63edd6382972d133d1d8887cf120a1dbf4cc3ebc0845ae85d6abc4ca82be90648ff4905e11e9a37137cff9400a0080e2d13babefbcd787a86b75772dd8461d5cd8a8f3c3f14b7b305ba6e51c765302981f0c3632a2860fcf61735396fa39bd407100cc1e8dfdfddfc0b87735b0ddefe96f2a2de97f168e41f2383c345ff93007f6fd505874f2c6cf2ed6f30ab6a2c8bffbbf6d3cf32ee716c85697db87f2f2b0b9cf65a48cc15187f5febd3b015b3339815beb3b02f418bbd3e7c6e9fec74374a1fb7ce9acef3b75292a3659b04f44062dae0980f6426dfb1ebe6d67c6cfb887f5fa3f9027ecf4936f3c0995acc540a4691cdd28909b3df8c48a4a27c9772763f98e7dc7d8a5497142aabf2c4c472ca397edf2fd1a74af576fbe1db292fdbd140d64a3c65173c0656619f5e5b3db0596a955bf017db34d849f29902f8a08544eb8aed66579084ba3aae9646d170bb76eeaaafa95f34295f2ce86b8bfff613644cf1ea061f7af8ee42df5d97a83a094d07219901d2e1ef26517364a03f031a3ad\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# appended bytes to ciphertext\nct = 8889564896395f4392a9ff76ebd1e0f5b3c5254c83fa7fd7bf614aeac559db65999171139bcd3c0fd6adcbbe7adfff9d8254ce2300d4ffc48ed00131243811677e8916cae0ff5752d75135fda0acd167b0e383f48e2cee184917d5f860c0bfc88a59d54587825f75db894de2e9f40bb3b168db171e8844d64add489ad839f47a63edd6382972d133d1d8887cf120a1dbf4cc3ebc0845ae85d6abc4ca82be90648ff4905e11e9a37137cff9400a0080e2d13babefbcd787a86b75772dd8461d5cd8a8f3c3f14b7b305ba6e51c765302981f0c3632a2860fcf61735396fa39bd407100cc1e8dfdfddfc0b87735b0ddefe96f2a2de97f168e41f2383c345ff93007f6fd505874f2c6cf2ed6f30ab6a2c8bffbbf6d3cf32ee716c85697db87f2f2b0b9cf65a48cc15187f5febd3b015b3339815beb3b02f418bbd3e7c6e9fec74374a1fb7ce9acef3b75292a3659b04f44062dae0980f6426dfb1ebe6d67c6cfb887f5fa3f9027ecf4936f3c0995acc540a4691cdd28909b3df8c48a4a27c9772763f98e7dc7d8a5497142aabf2c4c472ca397edf2fd1a74af576fbe1db292fdbd140d64a3c65173c0656619f5e5b3db0596a955bf017db34d849f29902f8a08544eb8aed66579084ba3aae9646d170bb76eeaaafa95f34295f2ce86b8bfff613644cf1ea061f7af8ee42df5d97a83a094d07219901d2e1ef26517364a03f031a3ad0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# truncated ciphertext\nct = 89564896395f4392a9ff76ebd1e0f5b3c5254c83fa7fd7bf614aeac559db65999171139bcd3c0fd6adcbbe7adfff9d8254ce2300d4ffc48ed00131243811677e8916cae0ff5752d75135fda0acd167b0e383f48e2cee184917d5f860c0bfc88a59d54587825f75db894de2e9f40bb3b168db171e8844d64add489ad839f47a63edd6382972d133d1d8887cf120a1dbf4cc3ebc0845ae85d6abc4ca82be90648ff4905e11e9a37137cff9400a0080e2d13babefbcd787a86b75772dd8461d5cd8a8f3c3f14b7b305ba6e51c765302981f0c3632a2860fcf61735396fa39bd407100cc1e8dfdfddfc0b87735b0ddefe96f2a2de97f168e41f2383c345ff93007f6fd505874f2c6cf2ed6f30ab6a2c8bffbbf6d3cf32ee716c85697db87f2f2b0b9cf65a48cc15187f5febd3b015b3339815beb3b02f418bbd3e7c6e9fec74374a1fb7ce9acef3b75292a3659b04f44062dae0980f6426dfb1ebe6d67c6cfb887f5fa3f9027ecf4936f3c0995acc540a4691cdd28909b3df8c48a4a27c9772763f98e7dc7d8a5497142aabf2c4c472ca397edf2fd1a74af576fbe1db292fdbd140d64a3c65173c0656619f5e5b3db0596a955bf017db34d849f29902f8a08544eb8aed66579084ba3aae9646d170bb76eeaaafa95f34295f2ce86b8bfff613644cf1ea061f7af8ee42df5d97a83a094d07219901d2e1ef26517364a03f031a3ad\nlabel = \nmsg = 313233343030\nresult = invalid\n\n", }; -static const size_t kLen152 = 48491; +static const size_t kLen206 = 48491; -static const char *kData152[] = { +static const char *kData206[] = { "# Imported from Wycheproof's rsa_oaep_4096_sha512_mgf1sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 7bb0b14b4fa435505b69876e65a3a3f8892d61dda53709f4257aed4c8aa91f2351cca74cda1989c898c88e4a4dc60c583fe2e5f73852933bb13942bef04b4af985f8e56fec2d282ed9ce56f27e452bfdc4ff6e7295d95251c264a36743c14fce78a2f4ac6bf8ba0a8ac5f88c82524a1610abe7548b7f6a97bc744473ded26370bff86f966885ea31787b058197ab58830ea477fb600bcab4e2f133a613f9f125319d272ea5ea323fbea830ee146725a86133c4167c63ef899edebd2f91769329181325b5748a1146407901a8d8bf66da94dea20e64dd3c12ad7251df719dddf3fe882b6a22a30ad1061853f748dd83a72839adbd885710cff95d554c1bcf043dbb3feef19d498e7d8db5caed36bd0d44470fe7d7d1a1b0eb4c391a0736bbfe04846ac98d6243a4e3e58b57549ff7f54c92f103b33c9db04fbc6b36fdf5191567a79bb35a0be94a45480cfc28d377be27da9c2c3cc0bb2a4e910ae44233305af6a87387aab762c63d969714be53c0b8a26bd20cd63761b373b815330eb92a1fa7e6ab827276335dfec94146548d073ec828f3793a84cafa12126196a33f5fa2f4f2f6470093e99b2b2d91f2ff9240580965480d56c74be39bf42408a0e41ef60dc080898ce3eb530d87b4da4673977055e83d6504a89d60fb2f49703936a2fb391fdc39d59608d500870511b458c9e45e53398db152d3871f18d61b9afa4435c9]\n[e = 010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3]\n[privateKeyPkcs8 = 30820943020100300d06092a864886f70d01010105000482092d308209290201000282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001028202007bb0b14b4fa435505b69876e65a3a3f8892d61dda53709f4257aed4c8aa91f2351cca74cda1989c898c88e4a4dc60c583fe2e5f73852933bb13942bef04b4af985f8e56fec2d282ed9ce56f27e452bfdc4ff6e7295d95251c264a36743c14fce78a2f4ac6bf8ba0a8ac5f88c82524a1610abe7548b7f6a97bc744473ded26370bff86f966885ea31787b058197ab58830ea477fb600bcab4e2f133a613f9f125319d272ea5ea323fbea830ee146725a86133c4167c63ef899edebd2f91769329181325b5748a1146407901a8d8bf66da94dea20e64dd3c12ad7251df719dddf3fe882b6a22a30ad1061853f748dd83a72839adbd885710cff95d554c1bcf043dbb3feef19d498e7d8db5caed36bd0d44470fe7d7d1a1b0eb4c391a0736bbfe04846ac98d6243a4e3e58b57549ff7f54c92f103b33c9db04fbc6b36fdf5191567a79bb35a0be94a45480cfc28d377be27da9c2c3cc0bb2a4e910ae44233305af6a87387aab762c63d969714be53c0b8a26bd20cd63761b373b815330eb92a1fa7e6ab827276335dfec94146548d073ec828f3793a84cafa12126196a33f5fa2f4f2f6470093e99b2b2d91f2ff9240580965480d56c74be39bf42408a0e41ef60dc080898ce3eb530d87b4da4673977055e83d6504a89d60fb2f49703936a2fb391fdc39d59608d500870511b458c9e45e53398db152d3871f18d61b9afa4435c90282010100e97acd5f64c460b2cd51cbd70af5b4caa2882bf6033a92a23ed80f039e8a32c8a4c483f94ee1bb89c1dc1f6d04360a1c3f654251ad72eb39cccbfc38b072054bb0f21b9d516ef272e7cf86f8a8f838eba829e7fe9d803d469a1810fc5b37476333ddfc0cb6f00e9967970b4e474e04373f8dc92df50fa155e3139bfebf4e1cd274705551f2e9022029bea4b86664633d13fd90ebdd0b72d95a6508b6b4354e64b187fd81d21a0b1e4a853c27df11d7fe6c8953cff6344f50ebaed2513dc03761e8877c71ffa8005331043027b8dfdba97cae037fd5d1fda1f145a200c0d20f8dccd62e5c489eea8ae827910d3f48bddf0b18dc3089069f96d800de47036859550282010100dd1abc951ff1474ebfb70807b160b110b1eccef429c8fc8535ab0aa98376a82d3d33af906fb0395750b9aaccd8723cf73a8c3a6ad5c3a0929178ac55e1bd1ba1bf5da4f7698dbf09e87c84c45ecbbe8f12d3ed1091bc470eb2c733c31f8d27eba9718ee78db887385bff6b67950b79524482c50daead4db0f5676e4b92875b5be383ab1cd75e1cadb59cfb5794c17220154aca808f733a636d28c016d9843940bf44bb15ed191f53449b1651b79554c23e006a56dc0232cca209bf2d3c12cbbc0ed8b3110aabd365b603ea8cdf15e8b9ac781155f92f39dbf9749f70df003195a6bb169ea0e0d69eb3a18ce8fbcac9be3c710e797acb5c05a399c2f102947c870282010062f25622fd53741f927ffdc10eb5fe7e79cef7c274afd800c65d4e4f9c5ab916eb2d15390cc301756a20dd7897f646e69dbf4e11cb4e0e7e1a5ac0734de3a476e570555fa069427a8bdf19363c75a5b9c934a94af078ae7f4342bbc016f02062dc5251451a2a3625b10f040d928e6f9ef262264641baf406b00b596ae6ac35eec2c5f082a04d3b476229972946cb787b2403abed296a76abc2715af602fd2c51e422dbbeaec9b6b889a0595414673d806782f37008c9366bf6d5c9f000197bdf146a86c4d131e3a15dfe8661ef297fb01e54a8cafe54d6065177cf263e91476232d2fa26c5e80342070ced9e0d99c84dc4282ef8aab991dc9d8210b14bb267590282010100b83b9f0763265894758abd562ba6b5e3835e1ed3b43d94ac2a9beab674a45a5dd7b14988c087c63fcb33e9ede62cca3ff6b901b4238a6e31b2a52a742534bde178e33ea22981c2bd2ecb1295cda757913fcef6a9e7c54a302527772a0f103f434e5d21063040a1eb843cbff1ff6f20183c9dfa33fc68cb63b81806ff518917c6e93cbd47baece0589e0bc022aa00c66795564c85f301c095384fcc3f3ddfbf15044af0d8c4473aa2d777a29154b74978d0d0e7ca9867fc8c263898e3c83aa12881f66ebeb4759820181a0b46765c7b1ebb67108ae2a7473ed40d290d93c3458dbcf00759061452c0ca4cc26d1fe149590a63e9fbaf25e3f78eea8054f22167e10282010100c301f6bbe5fb5693f665b26d1a61e1de87e38950a5825270ee68ea5a5667e11a3aed28b2266768d1a3db3437dbda681ac8294dd50ad0b4bc5cee5694831b8df7354695335740b9b7dae5f7881536da6a6b2ac4308a0420ad6e99cb779a6338f5012986b1c1c889444d90585fb0dac995ad6e93af7eac717c643c4b8e7023cf57cfe284ca911d6dc3132b08e17f4e8759af42b43ac929c0259c3a1d5e5f7c4b247e2f6461aeff8577aedc710d6d2d56d943c211e47467421539dfc2700663c4068031b695e487ae6910ecb9c547cbfe12cc6f45b658e2c6f9f8fbe805304194a9d1d9c6d599c5ac5c9ee5fa78c8a4583218f7dc8f4c8d3adf275eec0e0941fa69]\n[sha = SHA-512]\n\n# tcId = 1\nct = 8e615a3b27fae31bbcb6abbd713e54498b38143c5a740eb326cce75e2b9df42b6454dcb465873b831d3c18c4a0e4d941ebc49722402aa05498b34a7fa56a74774adada8c9c3af19386da29c191816117488a37b9899d135da5e8afa8e2b76a87caed1b050b8289d110922ca9b19ed932be12c92b36d36ee77ae9803fa8bea86cf8287954fb0fd69a0cf9809b686bac0c0035d8ed0bd80dc2c5020b6c6afeae2d7998373d551ae3a868a06854eec8fe07c8dc61408676ab2c21c251c5877bc31cb570724bdda76cfe2b055d5a27d1b3961518ac88afd3a041e2d21542ca027d6cf8c71c078016f1b23f73aeec8b7f5b77bbf003ab4233d0c56ea42337f5ce83d82b5e05497f0f8e3b4f23b78f71be7691f5bd66544a60f2ee685c9c70b17c5933e864d66f1ae50976629c7b76e91e17c1bc3099f5fcd191fe6419097088fed1b7d875f9a39dded5ca6c7c1ac36edf1ef3dfe9cf707de34c21962bbe9e8d0a92a7bbc0eda639d813254f44c47983db3d35c662096dcb61324e97d68320624f97eae0fe0400a7b618039d97bed9034c29846278a030d3c2e0932bab62a9ab325bc07cec7094fa427a37a937dab17357ede8d08d3b3f76e95f1f470af327f2a98ee1f56a5c69d1eeda8f0262fc36e04c78b051f4657c94cbdfa3218385d4e3422f5c4cf7d6c869113e0307a3c16f41db561c4a7d43e1ecd8ea7ffa6a6a548606ba96\nlabel = \nmsg = \nresult = valid\n\n# tcId", " = 2\nct = 77c634e7ac8dc0d271f8d970c3d59ecdc19a09ad5076f586942116e7125b6df207f8aa21217c47862419cfd64f8cf83302660cae993c45bded252c6e618ff225d251b0057099b3bba4fbf9480b536e5eb6f39f64f2c9b32c7d07edbedc4a642a7d69d263d88a62475769b653e550dbabc1d2fc0d14e27bec772b2643f46bc6c8950415977fe21b2f33a432617134bc208a613c3ecfcd531950d7ed44b925b3f16caa870419de62053c44984fede89b8503212531c13345868265d1fb139d2272a9f659e6a988b9f54155251601259b2c0159b3dda4910b5190694d98ae847b05b152fb63c1fefa31abaee992a46fa7407499ba1f59b6dc69c348502fcddc58fb2c60fbe30f7471821b75572f149138841972d08515d85ecf0390ade20b1630c9f7cff16bb1c0c0c566fd0e55c1090dd28f18b5019347461e4e533a1d97e553583af0beec3f1dc3a595f855baa75834eeda16f6adbb435be7044050f164b6ba4ee420ba9186027b166b50534d5607f2635c3317ca87acb9fa9d08272fc1b69eafe2d0b17b81def08851e9f623e14674016ddad14a86125f629d3642f5549c1bc69845fb7fe01b9be3c77051781635f438c6846a17a1c15669f0a161edef0c13d01ee2f53902585dd02d2f139bb91702ad29f93b6275de15bc7e537a1d2a4f8df47fd7751a4f9ac25dcbc9b2e43d21accacc6c3f7155845435faf50c275c3d4572\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 1dda78168838f43a71aa61151bb8bb953c204d0af526231cb804952d4e958ed47d2b51aad7c3ddf0cf5af70b87b5a5c80d9963e261309692a822294b40ee3ad67af64408508bbb18dd2b61090882869a5207197ffe0df39f278c2f3a710e0f8ea451b655fcd8542e07606af88a44a7bdecf5a523c312ff73942ef4e8105a5cc69fc1bb315f77f36b87477ff693289963d72f2ff0b6ded18a0d56d79787928ccd72b7d5d7acd61d37d632cbdce66e2cbfe990cb6ee250b8261248e81013df77448dfe1cdc5b812c8380aaa0c19e6cb11781c0e3080017ee254b89fab5d534cc4192946217718d3161c87231d955d4fbecaa817fa92800104fbd0bdff088fd65e9ad9f8513c88fa613d952634ee8306166225a2f37eb7ed779fd6a799f0e5600ef915867d88e99645bd797e261cfc9e462773fb52eb5398e4e6efc189759c2405f9506ed48e6123379ba477bbd029e8bbd11ba86239e138487ba48882b0c3ef356cc1b3cb2cffb0d2d0c9161f8dbab0a91276a242762d18ba36b2daad8527c781a2343a110c4acce2f2a4c294057765d82e86abe6ff036d9331f1986115b8a22d7e425b81f7c0f0e32fb57b2971e8a7032d155fcf61d0df5e9415344519891a712907727bff0b31cf652357e7755c68d35e22dabdee83f8b46ef4f4cba34f180b957d52488c033f4f2fe413bbd6d83e70c52783d78bd98689bd6d822618fbd464c\nlabel = \nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 2013a5504dd553e9ff2d0c42eefb6f6978cdfee946ebacb69aa0071640f42b1c6d019ab2c50362c7e271382d546a9ab53aed7cb625fdc692a60b4112df16d85db4a748935df606e4805419d4cd4a595285f369e20c7b474a2f71a6c40642c4e84f6ff870cd4546a4bb2b9f92a77d69bfa85724caa7c3724aeea131d9e2f61b5c24ab19a3ff46ef9b25e8951a165b2a795e8d734c996f0d3cdfc97995952195b60c65979f154ff185e880be3948eb95e449f5427fc3cebb805bc971dd32f57798e11d4411c7f2cae6ba40c711a5748c68d37fc7f493e5d389666159a55c57b1edb99fa9c30bc7eed5619177a90175cd0cb290b93b75a4725867baac40edc7033acb3b31e89063546d9c5b0a5d4c4f9062295269c51e7230b35fb2003c2e913f4c234ac9da3c467e6d522872fef1d28493e469b8e9efc1f6c389e69941b51977c4f4bb21c02a66926662899bf3dd638de31d47f8ffa9d8ee3404d8fa102985d2f8ec1e684acd5ca046e8b96d122630b3a7059ef8e7dc930c81c97bd81a3e3b9e984602d71cdf9985778f5f3b04d3f30faf4bd8a323ce6aadcedc43e3027abad83e92667afe962b07edfb218267f515c44be8509f1e26558220207468a318fe23e07fe2fda04114db17e754d9775d2c4951dc1c7f8d1b4476aa13ef50da043815a2a1c6453546067eb463db0877f717ec70c176e3fd73c8377ac3a8fd19dd2bb80f\nlabel = \nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 0f0b837a5f4f036f5a1b38669a4768571e1ac523e89f082361530f1288a55cda8c6cb5f4b7632d4624a9ef1507546ff1416f5baf2c6b53f1bcb9aecb305b6bf57b204282c74827ee71d23398509537bc7dfda5a4810b0c4b6af3af45e838e1586b9728509124d8b49d0a2adc8d383962fe70e4524e2fea9bcbe5c71ab05ec65b5e4822a6b765de292861c86a7605e3c20d1e3f8e8268a21a326f51cb66ab0490673f036ebe3d8fe5fa39e195fd703c1c93b49f3697d9f73f683b6f70d5bf585d72324d34efc79985463ce1df5c6112720e9bedf876e1b80f36614d719743e4420a62200dced4d457ba2bde819fa7ea2643eb1a4672e6827c915920fcb94f3ea9c1b0eefdbd7e5e07d1a2d6738a60ac7f81be705645f2b33af5d5a20b09ea4c3922169bcdf0d376fdc80b355740686e77049028f2f0dcbc7c910b8c15cca7461ca5a411a9b6d750a315a250f0da703459a2147aa3633c5711d3938f863e35713b802788e2d20b0de356fdbec6d187580b75d97cdbe7f07ffba0c14bb88f32e30613a1c911eb82ed72b4bdcc232b46684c581440df157f780fa9ce534ae18d20d50187aa905611b2b045d8b1c2061b0eb9fabae940de151348d10f0f24f753cf6f667bf2689a73bbf3089bd26dd74b803ca47d9da8f9ca538f4c7a62aba73def2a08f92eba90bd6d482ade0b6b724bb100c9231a31a7a0973af2de4fd5aa752450\nlabel = \nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = c40804f6c7fc5ba3c30f051a719c08823b6591f45a899fc9839d8dd77157761ce610d4a138c10bc231e53f9cf87d5fa26aac8f167deb1b6522a4b365a136849d0124b09a03c4d5f5c26ea90f7a0fcb4518625c3ae3908910085be3757143e1fe1fbd23bf0942174491cf8f7c2a1b697efcff99822ae13e2f4527c1b8e5d50c320971dfc3bf8761fd08ea49f60f78c80e65edb08aa916a5cb9355e9201c867fe17ccf4bb36d69dca6789906dd27515b1dd99285f483f8fadef217c80e0a430926bdad691118a33577689ec1815565f51dea4130533aca7a57a7bd706427ce2022000421a26a5d1fadbb834e6d78fe4dba457c70820c1c0f3f1efafa8a27ba302b1cafcb9b96f41a4f34633a28e87a6202f13fb0e41df3ff644a91106925c5c3b875c313aed8a04930011dd866c7d52ed018a6233f0125f4ceae5df8ef8890997868cdd3756e42775bce57327cff10e4daf568322f1021b140262f94f4c061c31475de1807313f1621fbfb24f4d779d99c917fa5104f93324ae675621df90b02446d40ab2f319c32d363b265ac32a7ffc6d262e7903d8c05dafeba307cadd25927a034cfcfc784ef45136c950682d313d35c20cfb918490c86eb342dce1c2b68967f3f10d439849a4b6db8430702615f36af9839391b1316c0505ee18b8a35806a94b73d00bd5e8bd2b79d383b89ce7bb046e5ef957d502fcd9e0290fe70886991\nlabel = \nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 9e053f731455e4fccecfdd3260ac0056a291fb4a37e297899e812777054f13c9e836f27de12cb2549d6aab0ed553544464119c495067e90699caed744e61ee17295673d2c868b41cc23f9e594a002a7eda75f1bd7e0b211c3c2e8122fc2568131b354b722bc1a29ec52e718e471c212cef4242270a4f9a765f6d077e37a01091bb13ffd9ef02c70462aecff739a2624a5d8d8f5cb8f8cd3c6eaabb683a10bd131afc6197a8d21d6cb066c610277eea1221d55c9c0d26f553ff7c22bba1a883d22f153c18ad617b506ad55e4fa04fbfa7cbc7fd310b49809c80513322b9ab296aa4a033ad3bf785c1bc5ff0c928777de67a71b393b213227e102c145e9b40357f251c19bf572a48c2e3f5f0bc12604c8475aed9baed2155028feecfdbb328b488bd5bdc031213b0b122bdb9cd44097d1813a759d13122530587be372a779e1aaa08d18a84d26213f936885b73835c27939e9c5d284076a09ecca3e6dc6e5be5c36666ac1ca1d8796502e0d5359cd6fa43edec58bc3d2b39938e69cd46e2a62ac4f6760d8c0c84765a6f5f6b66411dd3e217d690452745808a2c0f0fc504e6e56989a72bd1a59774abf529067cce618d2c39c05f0b400e644f7ede106e6eb1d0635f7f32ec04f86cd3628dba1f967b3109bf0052613fa84012da70ab4ea84e5d5942d42a0b9e3d0c80b0343fa9486c5a077fca77ffd30256cd4f8138dad30d6b5c\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\nct = 63a3fabc60b94267d318b377327ee6548f594777842681fe21baaa2e9278f001a575ba38a207a3deeeb2258de8f6bf11276090f869efe817fec6299247c09550bafe7bad02d0d7e0be51f8134bab130d4a9c593e3fbab7b276034f22ba071792a4031e591ebf2d67048ef07c6a017d2f71c72f8db0d32acc16788976f02fcaad2097aa83843773e59ef4c04f383f013f86e2334f215cfbfe64257f60d0797e5a56bea35b5dff983414ac686d0d80d5ae14572869d02d442b6a7b88954a9c0bd56a872fed20dc45fc0ca511db195232021fca52ab997191a08d1c02d0ed41de86b49d05715974776d8b0fcfc5a78432f122482e28812a0608ad1570de40c55397abd5c2a58046519a052cd3e2f03cd9e91f4888bda964e7e52d1296ce1b41b312d20f640276b91a737e9db0bf4fd449ddec6da642559b92d0a60405e868793681a2366904e8fa4eeee0368a2d0a606173c9470e26bfd462d97a8e40d06c31a4330a9ec02de58920c6ac90dcd20debe6fc14357842640b44b8d0be5bf03d737c4fc08fd37ed249017682b62735964a24681332b210fa8825bc60ed85e857828004b6cc42e8cf8b7d08308280b0f6daba6ec96cb5a300dbf3ed260984066478b5b93274e1b627d6a2a126d9e8d2db8b886686cccf6361487f5a0d62aa0027f1608e1da7f5b909f247ac42375551af7c3fa53673470c1c156bd953cf188f62bc696a\nlabel = 0000000000000000\nmsg = 313233343030\nresult = valid\n\n# tcId = 9\nct = 21f1f6cc2dddc3f1d41d482a0e1161769b8468f2340e32187349d80955e7003c57386a85b297aae086ac1550f90f8a5ba73192818c68f0cdc9f1a69ca518d1bb84c34538d9b0fdcfaf2ab859bd24748b326c8f8e1f0bdfe2d32fa7a5a6e56dbf69b07c41eb81ec699c79be15f34cefeaac0531923556296b7f9c29b06c2f8c4c36f5adee505c95db1496bcf923b27d4af4e083e986b0bd04cda37312a99bc091a81485bd335fa7e63772d8512b4fba1df03cda8cdbfafb26479518a75618068579bec06809c3107cdea7fa5a264c9dc0f43ea9db33b32d4637b65b7fcbde0d0c959b2c5bea8518f24f7f600d33d89ed286044d4594a446aea113f86", "b19764f68eda9ce15504f779316529bef78d1a83aadaab26e8aac19947b85d949d253713036d7c04f405051fd33dd8cca36bb657b3519f4e4a1722476b02577db945b86c39f8614df5782fa3e1cc7074cc5b5b71c9cb1077d8e88ed3aaa9be3745859c4649dd2845b4c6606c8f689cc5299cce15721eb0a66e7b6f9a9105191bf17867eca2a2668ea0e9598454dce6a10846f49e680c4bed4a9db06c5b92f92735b4dcfd63506ffeac5b354a09d16adbfe6375f9b6ac88fbd5402199f68d31254cad765a554d65757f4ecaeaa55b0d3a4934e24bb12f8fea46b18291e9aa7daec97ae675707a3913cb08b306876ce15a025e386cb03b1638ae4d4ccc76b8ebed23b92a004\nlabel = 000102030405060708090a0b0c0d0e0f10111213\nmsg = 313233343030\nresult = valid\n\n# tcId = 10\nct = 5559053e2566127dd1aa6ee3eecfdee11fa81f6896569d8a4f85c350c4f258126894f6826ae466ad939314b2674397f4aae2bb6a6d53ff89f5806cc29ee6c390434a4eec144547603742bbeff4584b884888b9af8988ec8fa2567cb6749b636b4a2a6196d2751840aeb64dee7dbd25c32b42776d04a2797bacf5e274895771f43b519a89669f56233c0b9a34c8a8e87b70ecbd5aa79337bae44364af6638e3d57b86946e3d26794434f8816b533aed1be591087448a13a1b247a64bbdfa989b1cac0047c966af74d0c9093a410cfbfdd828385597006b556276e6a466f9f3cfd38ccaea36d0a3bcc5acc63ed8f65ae5c3aec3091dcda791e7931221c09399ca56bfc3c2710c0211e9766dfa6f65cfbc6141479414a63a62d7c72830ff955b1cd86b38802d7935b430e7a802614d68f5015ef90adeeaf15f95bcd770fb7efe4d9e6a0ef8f23ec0743b3f71a9520e20fb60567998e58658abf6ecb98935fbcd343a949f952baec6ff5de23552ca435866b98e36288693b508bba177c09dfb27e13d70c741712d663f3525a7bbf929162d6f45031ead380ad869f40e230f78d9cc8a8918964ca0d8499e4bc355b3851a1fd1f03953d65935f613483058f6f250924db780733239b24dc454f9881df7648e2d19b416c2f8af53948cd7ea06e9b3baacd7fbd35e50a245c8c7d2113d9cac43880515d3a0fd6f3d76e5aec0d38f02e63\nlabel = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\nmsg = 313233343030\nresult = valid\n\n# tcId = 11\n# Longest valid message size\nct = 592e487960f3169443c5d6f87166bef2ffd52931518f3b0e5d977f3a2101814e749fff5fe8eba424a3d439609857940f5e23dcedbb45cde57c21c28bf729e396530d21fbcb96c97a148c5708801467b15be1eb0d35206105f543d21022fd023ac89b616ec790a9182aa053ee4aa7962f33f4b413a48ee3d53b2d247988683d4db30bf4ff6d80b6d0ce82e314ed6dd7607df577f1ec956acce51f744f89e7c6a770ceaf90b20665df2ca8050ac25ed29ca80a0351ad790c3b8fd00527195f427410dca6bbba37a441cb82e44383bb4e077fca32b27626051c13886392c10a305890454588f508ef8d9d0aeadd8bc78991fac96c5ffec892381b03580e28926d8b3a51da862951a05f48ef809b9ce11f23323ed10fd597d0449acabba954079164d775abba56da956c513b601d1846c867c6bbdbadf195db11857d4135c30c2b5898782ac9346f7fea4e2ec80b39b0ed962e0c1b34494af4441e5dad6d05fa7a47763368f850e3b81451b47ec12886fb317f5f5ca688275ff1d97410f8eeff8e210680c799f45dbc47744166d5b470c35a9df574dbf1b255931ec98e82e10985ea23daf960862882eb3ed17a99fef36af01b6168b22ae7ae0c91045f79da51fd62317630e123e322dc692c386bb9e30013525da3289321f311b8cd4e90175573debf08f772ce6d9257a6593557f9edd956c827a285f7bc620e262a7d64b8c56478\nlabel = \nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 12\n# first byte of l_hash modified\nct = 8bef4f3022bf5b4897cb318c5a2bbacab6b5a31d84553837feb0ee90f0e26e9c5fa0b963e13fa3f4867f60fca67c9de0ea48cd495df7083c269cd3d7da9942847623ccf81deb85240edf5ce1ed623f5edf0f8cbac61182538be43a32710d62881a973c12fd20012209ed24a8fcc64ba98cfc15029231ba9bf8c6171fce1cc365d7d49c169371e68191d9ed06a2f2b0b9dd8f21750e50c897f808e696730353a620656ab4449918b552628445f37e168b9d8e812bd6bc6ee3df375fccc531546479cbe773a839ae3523b7ba697ea0ca9cbcfe995f9f3e22680a787f3a43206571c556e6caadb9c6ea8f51da21f00820a2b5a3189fe1b3ba748408d93502cbff30e5204df86076a6612513db0067b2011927349066ba94b393a7dc23934904e6190a28c48d0913ba65f51e180b5458e1f0dbf0feb055bdc2f1002d2d4a1e506af1367d234dd0751cb2870fc9f4b84c05839366a2120503e8cff9f648c1f0b630619d5e020ea4ef7066df63053257d303bbe3717591e769fae87a9f92b1b04f9c0d879391fc063c8e5534f7b2eee96385fdd188b3ba26d6913ad9a767334dcd8d9b5b596a808301518de9f12f12b48b99f192670865abff0ce432ffffddfe5c311c3e321db48e79399c1fb530cf127936267dc18b05ea7e5594e77c63231d6a79f261854c856a4507d09ba5796995e1410135e05f16c7c5dde89973d35b0ff9b5f2\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 13\n# last byte of l_hash modified\nct = ab1f96560081e6aa20dcf6eefe00040bed6e0810076e5ab0457e276c06aea748946ff1f44c4884fc0509b79498709880b9be9a10accb2dad7a1195f6dafd668bd6d7b7225f1cea79f8c0dee13d125a0a1ba905f498ace6396e51f61f263af74304273220aeb8967b5a7f90fafb8226a1d3dac4f9bb626a513e4c7d352b31e25bd1eee15259fc3a4dba78641363e261242e18f860ad5f7ba35e60cc6c04c0709442048fe5b34ff9c567cfcba5a146df9f0c5fd9c1ba61d99595712e98a88c8c8d4b643925f0801b59cce4c1933d864b46c038400450bbb5da930612153116722050e8f8b377da4114052ab47ac3757aafbd6b7efcf006541681db2262478d3d125945901c2418fb3f013c5a9ecf3165de6e64b64a45e5bdc35ba38b6337b5da3cd9ffbd2a92f94565935f9505b1abd2f9c22705b5677b5e1e1290054d5dcae14f9314219287a4a618e2671930e6500acbba9417ec71e23b64d1cb5326f2fc531c5602e4b2fe45bcaa892dfdd8b05def3909b583d40e97a50ff7c38d29f7da72c92d7517e795ce7474f1ddfbc0cae588bdafa42188cb85204dbe88d742bbf7f71f7410e49b9215d9cf14a47d8b5bee0bc7947bab919462dc2c5549181ecf6ff07093fdc028251b8edaf2861a76465b9e22dd37940012d78182955e25a2a21ce157c6a93de447125184be3ad362f86b0299a74478f46061091a48704285fbd3a668\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 14\n# l_hash changed to all 0\nct = bc4463414999b839a31fd9e688d87f659a154a3025c0bc4bbb7ddee3c343b3b0d302def1195d56e39168b39dd48ec9ba5b16f8f52969e151ca122b06990d424b84884dea7a27d65b009af3125c2dc57aaa19bddb4ec284e008fe3c611883d60311c7cb4275588813e96090601c5c208f1d106145d02a7cc06659bbca484e1c898eb03fce81aaac560aad4b1e0dc4c92fafa0d4e232bbcfabb2e8c714c821a5673201df7b163f27d398451c4af2bbcd1448f83a4a8b238351b0561ad32dfd856b9a44516b3b6c20f5dee820aeb8e953d72f8d7e1f742d729bb1511d85400866e0f604e22f98e2f48033539756e86ab74939fec4568f37530678667e18bccece1abe6d3d934efb95ec85e1be5f0c2c4a3152cf5724a98a6f092de8ab70664e5a0725c8e5ed218540acd30ece6bc1279f1b8241660288b09300062e5d419525a9a7d6a04f24c2538189c9aba60730cbf6f6e208654077ee8e00a1e4b46ec3fbc37163572f0ed22b187970fed4e05a3331252263337e1d99f9d8e8fa5e42d5c4eb0b8cd9f4580b5c0c23667ac95004644eb125a6bc89b056d29aa9ba0757dd1bb7087102ef146b0bcf4f49d8898045ae7345ff58e4f804de5ec45ca10364bfa5594ff22049fc70801c1533a7946ac8eb445a14bb2159ff2c6f500fd67278b853d8b124dfe0ff022d0839533e4c17823639c6fc2fd0472649483db41ce72164970122\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 15\n# l_hash changed to all 1\nct = 17a8c7f746c34ddeb535edc9196c8a8f921dff923eb8ba3be9fd7079733982a147ef9aa5e9b32ff0c54968cccab1ba030dc623204693c18acffd0bdf46730a04befd55035b969d829cf539168ecd100d24cc7b8db4651054b5e63def4d6b183236cefb3ad9ae7c8eece2fef6f5c3355af267a7ee614050bae80eceef92dfb3b994a37724d46dea998894bc68e37252dfcf5c0a43bd3ebbde0d5a99fd8ad03a42f5d18b464b1f0a46a80242d7533ffc26c012b03626a0339ce0649b1264e9b5ff0654a52ab981783ef6c1b0b53a4be1bcea6f0367e4a1f9be96091038279d6bd15ef2f87e0619915d999cb30044f1abd24e019fab6dc7a1c413fef5dbbcd29d268e72fff5da72de0f4c0813615b27e74776af8b7a58f4f29a233103487f20d09750bfa9c272d0d57bee59b1e50577a04fbb46523ce1a3434f72fd69eeff3ab5df6c9d5e6832ba2601c0876f9c67b5854ea9a046b2ca9b0d57700728e19204eae99e1797637d510b54a2057d0f772ceb31c84d5625fd3c458bed65501a38ad0287df1348290c8b296fec11e7b3e36969bb8ce32ab7ab19bce268abf0a5c183f9db1afe56f47aaf73a1dfa499b8669a50191d80635c908f4b46183a33f025e0d1c6d7a85e3617967a421d998ea2a7461a3ddf3a19740273fefaf7cf9e64057042adeaf6b765e514071b92aaa44078cca712063c1415395f2bdcf86108d77e0f2a9c\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPad", @@ -3705,9 +4343,9 @@ static const char *kData152[] = { "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 24\n# m is 1\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 25\n# m is n-1\nct = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d2\nlabel = \nmsg = 313233343030\nresult = invalid\nflags = InvalidOaepPadding\n\n# tcId = 26\n# added n to c\nct = e9bb0b12b3f09a5ecf2054518959b594497b2eb3035b6bacc2e7ba277e14c43bd23b0249e12b87ef366733da226bc6dfc5a30f477324658da07d90b79837bb9e47b35902d92cfe816c450003562b3dc90e8208f02e93b217e635f8fe296e2a9d4e9cba9e9194d0fa50537730245546b31f8937c2635e137eb1b297a6492cac1b36e88d363bca78c4f2988373ed2233d4ebd7e8078c40a00684b1f5e3a7ddedb73cde4a298cd9d9b487b29c589655c08b31fb753e521a9aa69a56bb8dc70c72b2a5a6048ca0a23d1171d249c3d59d3386d9dcca35be84bf4dd3dee8f3602f44269260750da3718ff5704ce66f41b8b8f97d6a0fb09c93616b29384101f2638bd43bf4a07d5c9885e03ec3aef9aadb7e75eaada3a3e2c15d2d7a557ab63a00b1752e15a40cee1f2d8d1604fd883a4e2ca72c35a3fd405453f4830a2ec2bbce111ebd2d0982060bf006d9b7d220d5c5ab5b7e5061b83eba5c9203a26284d2c01fec65d2e6c8fee9835bef26de005f68c7b165b388082d18db7a70ebe4be0378f13dbb6d3ad091089aa7f2154d677a77a5d0586488130dfad798eae4c6b61b90af10b95436f2e3da96f258e40946c8dab0999f04f2652df4b60b1a02a538cdb4325a6f2d2e3440012f4eea97051ea73dce639e35bae219cfd9e27adc7d4a6103dc8a7b99aa9d4ff2bbe7bac248828d60d8a811c725e156e3293af298e63e839bffe2\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 27\n# ciphertext is empty\nct = \nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 28\n# prepended bytes to ciphertext\nct = 00002013a5504dd553e9ff2d0c42eefb6f6978cdfee946ebacb69aa0071640f42b1c6d019ab2c50362c7e271382d546a9ab53aed7cb625fdc692a60b4112df16d85db4a748935df606e4805419d4cd4a595285f369e20c7b474a2f71a6c40642c4e84f6ff870cd4546a4bb2b9f92a77d69bfa85724caa7c3724aeea131d9e2f61b5c24ab19a3ff46ef9b25e8951a165b2a795e8d734c996f0d3cdfc97995952195b60c65979f154ff185e880be3948eb95e449f5427fc3cebb805bc971dd32f57798e11d4411c7f2cae6ba40c711a5748c68d37fc7f493e5d389666159a55c57b1edb99fa9c30bc7eed5619177a90175cd0cb290b93b75a4725867baac40edc7033acb3b31e89063546d9c5b0a5d4c4f9062295269c51e7230b35fb2003c2e913f4c234ac9da3c467e6d522872fef1d28493e469b8e9efc1f6c389e69941b51977c4f4bb21c02a66926662899bf3dd638de31d47f8ffa9d8ee3404d8fa102985d2f8ec1e684acd5ca046e8b96d122630b3a7059ef8e7dc930c81c97bd81a3e3b9e984602d71cdf9985778f5f3b04d3f30faf4bd8a323ce6aadcedc43e3027abad83e92667afe962b07edfb218267f515c44be8509f1e26558220207468a318fe23e07fe2fda04114db17e754d9775d2c4951dc1c7f8d1b4476aa13ef50da043815a2a1c6453546067eb463db0877f717ec70c176e3fd73c8377ac3a8fd19dd2bb80f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 29\n# appended bytes to ciphertext\nct = 2013a5504dd553e9ff2d0c42eefb6f6978cdfee946ebacb69aa0071640f42b1c6d019ab2c50362c7e271382d546a9ab53aed7cb625fdc692a60b4112df16d85db4a748935df606e4805419d4cd4a595285f369e20c7b474a2f71a6c40642c4e84f6ff870cd4546a4bb2b9f92a77d69bfa85724caa7c3724aeea131d9e2f61b5c24ab19a3ff46ef9b25e8951a165b2a795e8d734c996f0d3cdfc97995952195b60c65979f154ff185e880be3948eb95e449f5427fc3cebb805bc971dd32f57798e11d4411c7f2cae6ba40c711a5748c68d37fc7f493e5d389666159a55c57b1edb99fa9c30bc7eed5619177a90175cd0cb290b93b75a4725867baac40edc7033acb3b31e89063546d9c5b0a5d4c4f9062295269c51e7230b35fb2003c2e913f4c234ac9da3c467e6d522872fef1d28493e469b8e9efc1f6c389e69941b51977c4f4bb21c02a66926662899bf3dd638de31d47f8ffa9d8ee3404d8fa102985d2f8ec1e684acd5ca046e8b96d122630b3a7059ef8e7dc930c81c97bd81a3e3b9e984602d71cdf9985778f5f3b04d3f30faf4bd8a323ce6aadcedc43e3027abad83e92667afe962b07edfb218267f515c44be8509f1e26558220207468a318fe23e07fe2fda04114db17e754d9775d2c4951dc1c7f8d1b4476aa13ef50da043815a2a1c6453546067eb463db0877f717ec70c176e3fd73c8377ac3a8fd19dd2bb80f0000\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 30\n# truncated ciphertext\nct = 13a5504dd553e9ff2d0c42eefb6f6978cdfee946ebacb69aa0071640f42b1c6d019ab2c50362c7e271382d546a9ab53aed7cb625fdc692a60b4112df16d85db4a748935df606e4805419d4cd4a595285f369e20c7b474a2f71a6c40642c4e84f6ff870cd4546a4bb2b9f92a77d69bfa85724caa7c3724aeea131d9e2f61b5c24ab19a3ff46ef9b25e8951a165b2a795e8d734c996f0d3cdfc97995952195b60c65979f154ff185e880be3948eb95e449f5427fc3cebb805bc971dd32f57798e11d4411c7f2cae6ba40c711a5748c68d37fc7f493e5d389666159a55c57b1edb99fa9c30bc7eed5619177a90175cd0cb290b93b75a4725867baac40edc7033acb3b31e89063546d9c5b0a5d4c4f9062295269c51e7230b35fb2003c2e913f4c234ac9da3c467e6d522872fef1d28493e469b8e9efc1f6c389e69941b51977c4f4bb21c02a66926662899bf3dd638de31d47f8ffa9d8ee3404d8fa102985d2f8ec1e684acd5ca046e8b96d122630b3a7059ef8e7dc930c81c97bd81a3e3b9e984602d71cdf9985778f5f3b04d3f30faf4bd8a323ce6aadcedc43e3027abad83e92667afe962b07edfb218267f515c44be8509f1e26558220207468a318fe23e07fe2fda04114db17e754d9775d2c4951dc1c7f8d1b4476aa13ef50da043815a2a1c6453546067eb463db0877f717ec70c176e3fd73c8377ac3a8fd19dd2bb80f\nlabel = \nmsg = 313233343030\nresult = invalid\n\n# tcId = 31\n# em has low hamming weight\nct = 125414a4d9a1c6dfb02822a23a43a54f9a43b4695f7e563da34da5c1706cf07baf3c7c58cb37da1ea56305d9bde03f0559205e05dad61beb195f5aef8a6e6b0a921b3d3913b5bc7c87e3fff274afe789c715b96cf2fc43e8372b68d10cafc7362095410c3c4d33580884a0f215572fb05c19fde4744f90a0ac23980d6b579ead8d68bc782ae2cd5e70064478011ceb82ac9df20d2f64550b37def09050c319134383a88c9673f6349c446b178f2d02b2abe7c61f9a1a1193ed6869cf1a985ece2b921a1234ca29298974ef9b3b42b5984c44576725aea8d3da89a5703081c6cf915be00750ff13260950b24f46f4551b069e7eefd531e71f7b7f7afc717c1e41d7781f01d6f0", "9cdc49b966d4f5455694379f4f0e31d3923db4776ad7fa2210f41b0e7fc6191ea18cf536de4e56d1865fd58f0dcbd71a0780e505f3d971fcd44e11db1945116fc8ed7bb7fbf3afce6db6454d9842f6c75b9c37503aeeadc6ad57e515c32bbcd5d81da7d178fd818d9bc8aaee2480754bea86bd507e74c33995458113f481ca8ef4de38f11dd0f0b7e6c05419c3c15b08adc2d4cea1558d8b430d2ecc1dd4bbce534b9627292869357b461fbc1087e435636534021ad02964121c474948a618c92dc5b7e8cfbbe1f3a5333c3d643f6ac0ec753540ccf3557762040a4754d7bc61d02aa51c7d7cb10e53c01b667af539a6b45c60b3bc1624073644\nlabel = 34c9c04473bd8a4da755a88a04a9ccab0bae8fdc51332dcba4aad045ae8305491fbdfab41821f6b838729d1e09fcf99513db3817c94c5be96a41bb23c8d0b0da00000000\nmsg = df487116341e4900036f3e9c31d809d20d17baa32348aea3f66babb8b082fe9fd496aea62e54c7529e0ff4c30690ce047caa15cb2a1824f0a4b7d56914272e8845d85fc8b5af454a5012355b5e862b283c59dbbd146cc6fa2a8aafe3889e10c8affee1782529b9756b45692bf369febd0639dd46029ad55111492ec2707939e62d645b4f4aea52573b3fbef8b4148ea2a539530f6841d8396c279ec66a503d8420c580a1ab55f571eb0ca931a2cd27b08986a7906d1f48ba68721967f2aded2d43cbb1f7356d62a169e3a376bb8f6b9e5b9e2541222d43832fd541acbd23a2044f04012179f654b70514bc38743bdbc8d8ad78b7392860c4dcc7173f180a25e6fbcf18dbd7440dee9e8ed9dd4dcfbc6a49e08c8ab08bca2ce4c774dd10e0126424948876f2a922d074df12d549328fa802275211d8b108880d90f4e1728f82453ba6bd5dda5a903a39f4e2da981e93522d7894a2ede6d1cd7f294ebcbb3a153803590097030b4d280e148a4016e454bf6b8b2b12b8c107b00826c5da2903\nresult = valid\nflags = Constructed\n\n# tcId = 32\n# em has a large hamming weight\nct = 429b721c92718aab272499bb59c79c051e89a93c091925faa209521649f090ff304342e04f258863a9da36b906384afb760d40bf553aa3b83e5ebc6f6246b0628836e59c56daa726c02e68552f79f8cbdd1cc349b7f988263680b7519861f8fab9ddd10a8392e6814d6e300a4b6447b0a1860bb8af7bc18e818ca2659c0c462c70ca929e2d0a67d81f557da8b1b63031835c362527289dfcd9b18f5644d1fbe54fd67c3b51fe84d3e44f3efaf280fa7cdcd72bbac2fa6731dae2be296992d6a08e8b8ad9fbfcfc086669ad34e4de07238791db1540c2fc91ba513fba4a692fbccdc717392bdb91995daef21430eba513bb80fcfc450f7af98a49fd254267f8f424ed516825cad9bf036794b9042ab7cfdd16bdc3398b8235a225aaac21672098f9fd799164f02d367ccbed67df1d16ab7e6948057efad3ebf9320ab3c74599a28636bf039ed4d1e023ce92732d1bc04cc2f71dda0093027e1e84666da7b6797e1b64e66d79dc088f0f8f91a806efe3c17c563fc2d6f3cd662fbb5bdc94a6b8a24c968e99a72b1a0ae5e621891d0a81d3b266da316c55284d65e20827d25a9a7abc5cd394b5cf313c5f0fc78fd4d2d8646c910ebb04f96e5be89d794bdd65b12bdafffa37dc5dc9c11b3cd664408e0954ce302a6e846b86b182f04e4ae30122d2b87dfab07e68d8466ebb235f606cc5d0989b1b2dc222e4a6c48a98f785a07c5d\nlabel = 2aef95ffcec9fb31cd3a17df07044ff10e054c4ff56d7f31b8ec1e24cbebf6979ff21d71ce627f7d4d7630e65fd07df472b39f2c7ba2f3af7aa645ac7aeb68da00000000\nmsg = 1348c2870b2c2aa0b686a87d4e51b8c9155e89f3e33ae3f7eb5a1c09c3469d3049bcb8a76f98c27e034b223a6c0195d29de1d4fde6748b2bcecf39457b292114fefc237e5d5e67893b1fd93385f9ca739f2487b79754c5bed364bd846a7afaa88ea1477e97949b770d6775830e932ffe327031d11a19db2d38d8a1897f2207a29d24ad47db096857838faf4512990ac167e5838f4001b62d6a7240b20cdcc159135bbb0939d67ce2c35f50267d2c4d702afcd907d6e43332eec8f52d71445a709fd365adaac1ef0f6ef72e7f7d976acc64e2d7e8e574918ed845fc4468727267d6e365bfe4fe3230645432cb5dedd284bbd28eefd53476d4a046dd30411cc8841017d1f0939db10a5c028140351147949d03d3aa0d512f03b42ac61403ac3c0fd240d9b69598803ef2e934c8b7d2923acd94672d570b44e60ded2df818181613e1dac6d19780fa2974a3226335c7c136ad643a17739b5b252c2aa82ca6ed8040c7230b86de80ffe9d81a22853124ce391dd3093076c0a93188554d202c53\nresult = valid\nflags = Constructed\n\n# tcId = 33\n# em has a large hamming weight\nct = 4556d44840f6c838427c8c477bdd8efc88cdf57d419d128f208a9e44674119dc71352004f1b149f2beedec7f3ac44d93e7fb9bb10bee7b675d62dbd9bd28dfa42dd6173ff17968e8578f0629486f99d40473d3ccd8e0fd3747a6daa2323c61a88e1f168a073197686668a8931ac03ba05cee8db7a5863532e798da7b0c371d03bee6cd2ca532c448187d16f424e4c22dc0aa86f5bb8358d0a593c9796cb5130cd6610a3a4b9afaf4da87c0eaf4aa015fdd5899b749af62e85e955de5a315fa971c35e900e410017f6860dbcfa347206a7e33277efcd3a17715a8f1527456d16e2addd711d7bda3be776afde4adb2a8834d98e4a2682e9b742a8798f4a5496138472bd889eaf0b03316180ddbf750ea5607f37a199e54c0812c5d59bba22dc1c18bdd8e0f8c4eb61a3701de06a710d142a2f5c864dd05a40c7c3fc4d4ae02078abc9559017f3c6588e670854ad81896b213a769bdfa6e221b5f8dd7ada50424deee1b1f138c738ad938b64f5228880214bf4166580b11e1afafe2b89819e720a7e08f773109dbecf40851e839b4a512b5fdeb3309b8e2fff237f8207df0af5d33a6b42da14f44dd49b716a7dba83989094b217d4b448353e250b9ce5f5536a471f2e1058e421f9c5c166b58db8e6516fe57db729b4c6ed31f014510976779beb555e30f1ad0de2c2922d9dbbf8bffadb189b7a5506545d3ce0b0f5891cde090cc\nlabel = daef95ffcec9fb31cd3a17df07044ff10e054c4ff56d7f31b8ec1e24cbebf6979ff21d71ce627f7d4d7630e65fd07df472b39f2c7ba2f3af7aa645ac7aeb68da00000000\nmsg = 01bb3b045ddec9528281814d028d1d6e78be895499b7f975e181c80e60627453016f4d2a767ee0ac090290243a9af67a6952a9591e3f242e80a7a19f177bb1c130849b9d74929ee5b048974b2d74dacecd05a32216976c9f605d1ab338de1bf245f5ba8c6822623458be9be96cfac7dfc65146dee746b67b128b68b36d03104e31ad9318c2d6eccd622bdcd07880ba1764a80b5ff9a367cd8366d82c1bcc65c9784c7842ecad63080230c1d6a5cade3fab837afe5785a8972172b9d9d0d7d4558ac162ae80991ca40b520979b24f64435b68c226828eb95e30be152bbbd509f010d5123ab65f31f389136a53b91b89a8b4c4ceef30ddbf0f3ff6237386f9aa9e2e57445d2a100b8eae294b08d6b86945abc3314af6982e5513eff8f8d987705a43de929382267523434fe4bca190b6c725faeb377f9581c49c45ae50e311dcf29cf3489ca8d1ee5cdfcfd5eccecfe9bf7910aebf141b6099f26135cc20538145ae8e0406ff3eac640c7bcc2f266a033212848d4a25b51dea318a97d38399\nresult = valid\nflags = Constructed\n\n# tcId = 34\n# em has a large hamming weight\nct = 29171896b305db27c0c404b65571df5125fac9ea2d8faedc5805fa35dbc2c335286694fe96bf415f4f2e579bd6b559c2569e886ca2e507881c1d80fec2ec6a83c3cf176b697cfd88f098c4105aabf25e2d322cb6a933c0b825d76a45deceecec9c5809a11acfded98eee74597c0e6963ea1d4fd2718152c9be554d511e380f5ef59ebfedb279c60fc622c3ec2f89fb89f82104567eed8b0d1e5548330fd434f3d83adb81b919e308c90108fd10261ececaa4249359250aa1f58a373c351f0d0ab51e344fd76cf0e688b39cd2a14569aaf49fc9f2f4d31d3e7120a2bd1dabe14f22022dc4d9a24cdd78ab85bfe34e048d57d3d465b616a835c33ae1ac2e337cf19d14e362e2f79b4e0feb51387a2b12a971ca1da3b2c7b03520cc6778249ce57540d7e60717864f4fecfbeb1a2e1c5a26487f4efe315fad65cd6c3c9929cdb2be9dde2d7def70709d5d87b7df54b0f7d2db610098a5da516f69cf4375af1c51c5c58bf8183a39ff3476f3472892625357eccf2c71b98f09922a560248d9b1c638a2fe635c7d3c06bbaedf44c5643c3dad43aa66efe6ebf7afc7b19e2b89db235b085f5aab01fe49c5dffae0dea31a4af25b8a65fcb68dd13a166b9b6fbe539eb79d610d2333b77e08a21ba8530133e24b7da38dc86bc1e56c5c869df6f5693e4b1e870d0c8884292edcd5fc6fe0d726803055d1a64d28a19ebfc4b027a1a340c7\nlabel = 81ef95ffcec9fb31cd3a17df07044ff10e054c4ff56d7f31b8ec1e24cbebf6979ff21d71ce627f7d4d7630e65fd07df472b39f2c7ba2f3af7aa645ac7aeb68da00000000\nmsg = 204020bb5dd616c0697e2f261d547f9e1082f60a8691c73b8f3d78ad19e772d67ff85453cce82d39d052f76c2743445d7be719c7d1a8a0f437669c40430ea1c8af4fbeb7d70606e67341925e63768085c94685aa28d9d55ac67e9196712360f477df744ce770c1d8858f33a2dd2a6926945f3632b3391487a2124c4c8c071af265dfc365901ed8046e9e5857c53332906a703bd0afe663ac7143cf4900405ddaec708d18159fdd7919bd6684c02a48edb54223e12c8c5d154627eaae83b3cc1bd4f2e6dcd62d41b519fe2b01199abe2f4dc57d7cc2c360f8c4e72f28d826a8a849d41a86c5b6676f7204a8c236883ab504681fe7a83ef0f12201691252a589cc985001cc7462eff1151fcaa25741620e914aaf6a1699c77a09375d1005e7dc3755e795086a32bf86cb71e93093315233fcc8a86b4fb72f8ca5d320e5ac19c142fa7a0d2400979863489ecadbde99e15e3fc0277498fe871719d2955f229804c2a85594232e3e29ccda494c5e340e7ca9c720f93a1e39f906522bdb8f4f08\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen153 = 931551; +static const size_t kLen207 = 931551; -static const char *kData153[] = { +static const char *kData207[] = { "# Imported from Wycheproof's rsa_oaep_misc_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-OAEP\n# Generator version: 0.8r12\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keysize = 1024]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad60d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 1\nct = 673779703fccab3ee7735e97e7be7fe3d1b39fa902ee35a858fabab8b2cd6b76b3a68f5971b42e28e8ceff7942cc4f3a0f2eeb4b998315961b06fac4b946d0c9f586fdab0c22b1252eae47d3c9d4fcde44dbf622b33b130adab572ca18a29016a35577c8518d24fc6659851b434b0025aa7da027d7ed77bfcbfc51c991daea7a\nlabel = \nmsg = \nresult = acceptable\nflags = SmallModulus\n\n# tcId = 2\nct = bb7914975c8a7817a50e7b3af7d79a93b4de5f9b3ce8a9a15300da83c75af932833d5f662ed58de5d195b4b03b4f70c6d7741bec915bf8077e31238c4d51c6e3c49d1a89211d3e14a3d29ca5e3ac4f9e1d13e22cde950fe979834f12f6ff93247e10da5cfab6b265bc87c8f2a63253ddbafb8ca0c16b07d2b230a78c04747089\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 3\nct = 615a6e86e3d447a655ee83eba8d92e29e08812c5de4816649765457c9b3241498f6308b3b5b1ee54f70642b35b85ff229af8b1e81a48e6e3359a5dd67c34e5d02b58caa36e3be7350481d0f7c5a0af1eaa8eb93e9768e7e1e0eb5c5d75de77c220f41bd03732d4c3a56f6d29cded37752047b5f79f11fd4c4eca39b34ea792cb\nlabel = \nmsg = 54657374\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 4\nct = c3e50252a748d77060deb817e617367fa93ae234e535c7c3155c65e0131c1c249fc7ee8e6b8f58bb085a6a455b63efb336cb6fbc9ff82204ec500026a7ae09c7cd8d361cecaf6fba5fdb265d64f90cecd32b0b3fbd93e29725058e1f689f030373fe0c9133660ec88e1b027bf7ddb5abf3aae80f86c0af411496acdcd89908a5\nlabel = \nmsg = 313233343030\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 5\nct = 6aacaa5bf3d71e04bad9ce95861983d5fa561c1bd4439aa47953d144fc880e82c1540487ab4586e24dc0749cb5d4f9a54854e6f90d03e288c23e5faa4a7a7f9ae09e36dce48428a8a9485123f1bb6d5b7a9bd339e8e799429da33668733dc8b323a29b8014a8eed800b36a783249842b7135e33b1708d4fcb5762a5845b16cf6\nlabel = \nmsg = 4d657373616765\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 6\nct = 0c0166f8e2d95d40d1343c4afe4ac038fbe7654fe7c96abf312e385626830eba877197b931039bd4270147d3480a99ee9b124667dd8a89e3e253234c669d9cb45e35a3465252251ab265a3812923dff495c91c5c50f4bda0b3ba9f9b14565ce78583ae7995813ae9a795c4f7d43ced1cb60e2cf8c1341798f8f72ac397f0bd36\nlabel = \nmsg = 61\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 7\nct = be7e293ee24ecfa696de652c0ece7b95c8cb70b4eca65077616021f7ab5e2e3e6e1115283757d9fae9ddde688e69ad470481459a7db49eab7ba3b77015a5be9e294a2fd5372810d1da1fb6ead5949d44c20be3159e56a9400a685128091bae955c4838312b4da54a30f26481092abe3b7d89ebc249694a09f2a029b333cb1126\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 8\n# Longest valid message size\nct = 163a77d9bf01658d6c74efdf3615a6a44d3d06415a9b6aa7a43d0c8f3907d51a66d51d6ce250431dbf91c22dffb39b6b51f9dc40d9f45a23943ffaf3904e7193816a5a521096c135c6fe6f59982b0c7425bb7a653c9ca33dba69871f29a129be856488c39f19420a4f3a9fd9b6f49ecf9e9cfeb2de7ef3eb57dba9cc19efe0b9\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = acceptable\nflags = SmallModulus\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keysize = 1024]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad60d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 9\nct = 43292f009868017ff514f9c3c04c2bcbe7d39e33b2b39d163812815e7294a87eeae5e8503ec8bd57d1f5bd02795ea3923c396ebffde08f70e9fcab64ab22b70d19cdd34653a265f13a36f832bd2e34f5a0211ffadb4dd353aa0bcdeea19c75290f0f948b61eeb5f41f86b42ed3222be38e2a30b8e568712d786b57173b3e4090\nlabel = \nmsg = \nresult = acceptable\nflags = SmallModulus\n\n# tcId = 10\nct = 583c33c713bf7f920f63add1f9da9051ef3716581c117b4fa41c82e59a45dc4539569ccfb8a86dde1ef4fad8bacfb8be0f73a9e3dbc2c682d1463f8f72304aa181f1c3bf829121d5809cf3f57ad295710728cc44aa6ed74e46b0975ef5510e89ff129dd20dbb66ae948b4f633d6fc0e886f8e944df9a2dcb43f48a6b3327ead7\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 11\nct = 342f6040b7f229009a429a9079950154588ac7689aa226b363b75ff03afe2f69a2eb8e2261c6870f1aae8a0885ad5fa612cac2cb63f92ddeac9a721b06bfa7a343670a44afda70bd8e64971699f1136eb95c0e06bf684b850853f073719275accd66f0e1ccc50c6f163b13d4cb5d273792343ef69f547a3477ae5d7985ca5240\nlabel = \nmsg = 54657374\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 12\nct = 75a608f2a58538978fbb1b5b761bee895c10d3ce99a0a5e791d65937098b9ea30586ed1bde62a2cb3e0b4332c5d993e35b52ed28402404521f5b579a5e257b76c2e70d67b6e1459b790fe32eee1c64a5d9d78e98d7a8", "513d5dbec7b1c958b0f6fda4b322194d68818747f9a75afcaaf07f8def984aa09373997900b69775db86\nlabel = \nmsg = 313233343030\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 13\nct = a12a689e17089bcb36b9487ba3b0ca55781ebcd5c68bf4a8dda58126a7ffb184633f97790e84905c2e9e2feb8d7fbf6cacdc35869aea943727ee3fbb494ba7657eb1cafb0c6e39ff159f41308d758f07afcd48808280f1269910b0aa51da3027788842df88ad5a299a014a040b4a9c9b54b382d349589ecf24f4acd82698ebea\nlabel = \nmsg = 4d657373616765\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 14\nct = c019f80847bbe0b299b256fcdb1e71b035345fad162969d202c20bda4c7398d14a1a6a8ebe75ce61b718425a72cdf0e1cf7accf1b692a175c146e87e0eac2bf7920c8b218640f8223e536dbd24f93b8455bf6a45f6b200b38b11457491a1bfffb4abcae258e2590bfdf585264f31bed39a0039cd23969ccaaa5da66307a6caad\nlabel = \nmsg = 61\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 15\nct = cafb437c778965cf82ba9e33cfd390917c7fcfd4090e56c70c2e9ffe5863736ef3c8e62a00e61a11c86a100c56c49f8f39fd9d04616d95e2467dcb2c61ca6323c887d78ebf3ff71eb67ccb9cae039de696a47c1c3bea01caac297e3ff14cd6642353d68e3bce9bd702d225959e894a2f996c7e0064ee1a340ddb6071634d0982\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 16\n# Longest valid message size\nct = 59f72eaaffe725a5808f31ab0372afdc2e87f4ee8ba12792560c1e014374c82432128380adf701f4a4f814a8329583abc22dc9e76af568d3aa1539ff41034e17c89450c9efb17ec61b89c2a47744f43e675e870a9fb901ab596a8bf5bf8603833bc12f49d52923f32e4d0af4c908ef75a4b9ec2a6b5475ef30d31944dc2534d5\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = acceptable\nflags = SmallModulus\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keysize = 1024]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad60d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 17\nct = 683504d9d84b2f9eeebda7748ecb59a8ea8a72a283983113deac27e65e268be105019dfc6608b6adb4c68e5a8b945481d797efe72bdfa554eafba55b5d4f2236777465eeeca0364e72f0e0ad96b09e1ccef8e7eb6bc1c58ed90a838f7c9b81517080b6978c1dff0038c6ff944bd084954b6b3b0c3184ecdfd08120455b5a24f4\nlabel = \nmsg = \nresult = acceptable\nflags = SmallModulus\n\n# tcId = 18\nct = 0673ac76c5cd297a6605ea6fa07ab36179ce8d7ac2291ff1ca43078d542b928aa53ed48a9389203be4313a15c4dd476a6d97a67aef5b2765e460108312bf28c8b85433968c82a3127e22a6fb6088c088c0aa428a495ba25fe6c570516457ec68da37db32160266d5cff2b8e0cff69c8ff722cd71c44f80a6085005eb48ad2c02\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 19\nct = 196a786011bdf22c7ef74f04b9104314086a25219803c319ee8d2d1e0669505f61122c13f4414c23da0ba6fabefc94635ec5534eea50d60cbf094ef254622005da9b64ecdd529280e32ef32a1210c827e25e9f851c235a7d1681cd0156bc7714b22819a8ab99cc647ba310998dd3ba11a2d694376e111101e781cff6fb0ee52e\nlabel = \nmsg = 54657374\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 20\nct = 73cbf741e6ea2ff7d90da94f6b2b0193948f3bca2fd46b6d3d1419a70628523b78325e3eb1db07f504e0463612ca04a10badca665cf032332e0cdde7577e1f54710588db2707c1606abf8e84f2d8141e4f09e63e198827824bcbc82673fe2186b8489b4e9b52c30e536705cefe652954b97fbe7e0bfa0bfc3f8b51a762806232\nlabel = \nmsg = 313233343030\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 21\nct = 9a05e365b558644187da88d6d54ce54ace67beed3b727dbb59bd3ed1f72ae4b8456c85254416efe608e2073ab3010fc7c2d27f157e9234e4d5c7f49bb89750819887d784c6ccb51c7f59cac5e04375dbe42b18f187be137befa13ba80c89605a18b8d838ce7a899e4a3145107d23cc55860e5d32187e0c6dcc946d11578c6c9f\nlabel = \nmsg = 4d657373616765\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 22\nct = 84084b95130f1d91ba7444c045898f8bee7917d9dad6b59b9bdcb204e5ee8a142bd94b405ab42d859bd6d9e8338a202b67c2551a539201d6657eea79cdc629125515560ae5061477e5c7efe0c4aacd36da41ad126aa630795f9e105ee70fb77fea7a2b371907afd415697fbd570bc3f414f4b88e271f41be1223c29e3d72b21b\nlabel = \nmsg = 61\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 23\nct = 52ab5613c4ca5fd259398258edd48186c9007cb99b11915c85060e84975e4de2365723315ff4269ddc37acce4e809598b7adcef464c0973e8ad12037b186c74b2e1e76212421b127c2c1d56c6e69d353a7ce52531c7a1d375cb6a0e358c86de3798378a09c4ffc38a4d27adcdbfac6211366890a75692fd2dab14360717fa415\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 24\n# Longest valid message size\nct = 1d79894e48cfc27e8fafec2f2f59fea5890569201172ffe68ea13fc3918ea0eb0e5ec1c3265a39acd5e1d210883359ee35c33d18206aa8d59c1a0459de1282fbfcdcf09a2c0d3a849c048875240b9ff1452f57a9d45148f838dc0b47dff2b52e0d93760d7b4e1f0e389abe425c9c167dfbaa3ca0196e660814986572d1878cb5\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = acceptable\nflags = SmallModulus\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keysize = 1024]\n[mgf = MGF1]\n[mgfSha = SHA-384]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad6", "0d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 25\nct = 54b9f6b31d9a10c7534d156f6f07dba7310a714a4b3b1c7b7d325825cf30ff36a2dbfca7c740ea03304e0a1e270e320f2440504499c312b4f4fd46d8dba78211b5b1938e43dfe386605d09c8c1c90fe2cf0f8ff7f7be04550914217312fa4105f13709167cae9a0f4076b1d07316f7347bb01e33d71bb0b7ed1cd673433a1ed6\nlabel = \nmsg = \nresult = acceptable\nflags = SmallModulus\n\n# tcId = 26\nct = a7f2cc65230e26da285af8905677315578b2d4eed37c8eff3c649f5f099c28d5184509b6ea5515bc1b15f7c0baed4323dd600f13d3831613b923b598c6446050a13fef00530f475bed55ec8de81e7badc5a078a2989e4b66ee1909793de82fe3bfab63263c7aa8bb74dc4afa23723982e65a0d6ebb2f54a53bf2bdd2c7c410c1\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 27\nct = 4f23774e0e834c3c94702652a3be92b3007b830b8650f517a5d2c690161c0a802f49fa9f896ee4de4c02370e84f66b8289d69eb828eae7ae2aad814770817b31a022fefd33e18197dd4f8991eae93292d9236858266944b86fdd9dc33170bd8a5f9c473afbffc88c51870d2ae39deb343da25afc2569bfede7177c92e80821c8\nlabel = \nmsg = 54657374\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 28\nct = 110f46bd1e27da8af2ce52d4c41171cdfc0c6a69f0709826b5c2de86e716ad41401d75442f849a06522ef7ddc0d67a99c06d5b6bbb8fe00a7bf5b470793bb65e3ddd761b7db657ee2e0fbddd1bf9e2441515e11717507eaa4a868378b888eb17ff4f02221c84650c2c41ce89d95e399f055ac70e3698f6836c655c44435090b4\nlabel = \nmsg = 313233343030\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 29\nct = c55786f3ebec1657da50ebd20d4a984ef54d89de99defea0de73db7e348dcb505945fe5af43a319f38d47c9fd1fed3c6b5e91961d1cd8185b6021293f208499848e5ae2bc7b24274fdbfa2d67dce5f2fe986d4e4ac7067979b51bc220441d2da2c9123c5526200d57d81d993480d6ae622f2a1434b8387c4e641cb632673be9f\nlabel = \nmsg = 4d657373616765\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 30\nct = 8637f6b594861442f04a9422df3ebff415fbca162712c1d69e83f6b05f8ac8214893e815fbe46b29ceb901830aa1b5397de66c0fa9607ea758849f5cd67571e3acfb0c614cc59512192012f18cc7a8dadd153cd7838572f921907b11b4ccc8e67614490a3e4769321f1e6330470bb206e81107c012d151512f8650b60c61381b\nlabel = \nmsg = 61\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 31\nct = 91a7ccc9d2fdac9e8b9697e0efb4f67cc1c1f5083201057e7405c0a82a5a91e3c6edec26a406367721c98be3baa7cccb5fd2a08bafc4f035e7e4c664e544611e0e44daf2667b26a1aaf84006c47661cc483d4ee031b35cf33c5205f26aeaae9606345d51b742aa5a09bc1a51b739a71aac058f9e69c4ead478f47597fb6a45bd\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 32\n# Longest valid message size\nct = bb0ff1cd0900a210d44649909b503a58e88073c3f1707d3be68f3b8148229b789c4870f5353a38f0550842cbebb7a596e6c458809d94626c3d2b457709990ed366fa1f66a0eb0c144b311a873080974f9e5a681abfa2afcefe43f59115fd3fb9fc2d2e685f3ee2ac686460bd79a88d90d2e5abc6853ffff19bbfd70333bd008e\nlabel = \nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = acceptable\nflags = SmallModulus\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keysize = 1024]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad60d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 33\nct = 2599294707d4888914f7f4b9634dbe1e471b10e3e8d43a988e853dc9943bcdca9cbfd9d44a780d6ab9df0617795585ab91d4c2d1a0f0e2bec78ac137902a2e1a88b165396d02a24beddb3905a6b3f031a2fef0d803266b170e435769f248c3e6c122f404f32ff3c450b38c608f12ff70ed46657d2ceb1a277b8ce418a7d9ba73\nlabel = \nmsg = \nresult = acceptable\nflags = SmallModulus\n\n# tcId = 34\nct = 0daa2be79921c08cddd40e536bc38da267157f22cacde4e9ad36730d616b86c734a7751afa3d7678cc7e173bdd3b9afc19c2f4cb4cae58fe1d623685026468673b36d268f170ab500d974b57536bbe44f544b002101b7ed1b4d342c18c2ac169bcda4219490bad3e645cf5ba69dad96860cecf559307ff0d293ab30dd330f8fc\nlabel = \nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 35\nct = 82c311c219ed2bd02be97da106d14f01e3292595f16afc6e61cf6d55202e7cff585fdccb56eebd86d03a04dc76069d1f06d3f72b59ebfd9be08ed664045377434311f83811163891704ed2fe0d25fc813b2df2718c4e32cd74fff8bec4d554ff72ff5c6420b2b76c03286dcfb2a662c8c66a86b04e61863d2ed379baede9c918\nlabel = \nmsg = 54657374\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 36\nct = 09cb258d6a5090a2638d2217f3c6535def5a2a05f97a2606f608d3ee10f7a6077f44bb63eb8008fd6d797937edc31dd0d5526cf24eda0191c4f48fdee02bcb731e4ecf09388df1d979c11fb841a0ac0d017334f6ec9f8a9c4de822c232faea803eff6225769a39d68206eead6414af996b1969f2f8d6bc1c3400f6fc31bfa8f9\nlabel = \nmsg = 313233343030\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 37\nct = 6daf23cdb83c5d16be94c4d9646081be49dc1db87287bdc534052d6848c5cf47584ebe6ddba5767f445c11010e019352472aff14343df44232784dc2adb135455ca28a03bb69e865762afa850f907d89e14e08d9a81e92b0852e99d360804cb0857e47b4bd2608838d6f81826d74d17984f805d7de29fb475ab71e5bdd057612\nlabel = \nmsg = 4d657373616765\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 38\nct = 6a397116dfd443619d3acb576c282eb0ee28b2ba901694c5459817909167fe1c9fffdce119316fda91e0f5c65ea4eecc595a18bec9a718cce8281fc4ab63d56dd82bd835b86a8b91229178d52ba4467f74a161314abaf533443efbe08270c1581caa5876eade4d34f48f1c9411aa089bb4a3370b92c30cd918bcfda92108e083\nlabel = \nmsg = 61\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 39\nct = b399d03b2fa231e85308c6c45fbad1aa03d7f328bae29e94a1c4e6975238d1883a343ac5c49f503ff35472a27c843d56cdc7c962c8753ce2229b2ca37dd9e24e3fa3f528787eed3c8980e9c1b888b093079af2ca69eb39859cffc31d66d0dc245d1213c7f54edb769bcbf0f10c6833967a7d13099ed99ed84154d505d51de912\nlabel = \nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nflags = SmallModulus\n\n# tcId = 40\n# Longest valid message size\nct = 149bd74986f0b9a4910723216817870a910c157d65df96d991f5dbf144f9911ceaafd2fa799b58d7e56971d6db66d3b23d1232ea0fa5be2467eab1c9142a898f0ea53f2c40702c42b2a7c0d987c50a6d4dd54ef27238f5d708e77954170631a9d52a2f54c79a4bc3edc8858da72752ad472e869782783f3e91ae36c176890190\nlabel = \nmsg = 787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878", @@ -3823,9 +4461,9 @@ static const char *kData153[] = { "e33a4e0d8d02d15628a0a3420429cbefeb8d4128cff26cd051b7b4c4bb0ab6aed614352cf66da8d7a7b00e46ac9ff86251f7b85c044082971c22e343b401ab57c978250597e27fab6ffc7f1d18cff956eaaf9c317cb82b32f342099582e6c4ec53d7d31fb4fe7b5394221b00e2fa6cb5a1218fe0db3f3fb5570d2601507a7b5bf75dc6f262222e755bf22b02391f0361a189138af6f8c68117bea1035f384452841b7d91137a970d9dfba0e194c8fda769c05ee3f82da90ed2fc9d2edc8953db5b293b3e55065f5e6ae1998f2\nresult = valid\nflags = Constructed\n\n# tcId = 771\n# em has low hamming weight\nct = 85e36c189212207dd67264ad00a49e5eead977895d106b9551af968480f5e64226cccd03ddc2714a6b85421c6b8ed498073aed03131b9f61416e50f94fc2a0b115b70218b10980cf3f84d3963332d7728b566ff6e6c58f505793d380c9b33420912c8341e55ea0b4c141f1bd28d97de1a8a651b55388ac26d0359d6aafade11be18e1a9b090cbe11032025c18cdcfc67b209f543f7d7b5d5fb92ebd1c989ca78c4b285ecdc1311bf2ffddda98449c0b13de1ecd80c120ce982a9b5b85cbf8e93eb8bb17821d69811faefb6c9f4992885e8fdb2375f68bb4bd3d183e2966e5fbe425a582c13a143622c043027e2d35f6574d58cb80b2f006fb94163bce16ec2e540024ee8da188547bcaa8d579642d20c9e06f7eb29745f99c4ff0a5ca6a815de406a64887603b4f2c65672dc279d987aba84b3c7f37a9bdb9b0742d1f62a50ec92b8fea87c5ca84aff9943fa6a34d656820e1bfcc5895389870cca6f49c2e3b16862b3fd8f12973ab778a10659ecefd945f1b13d9c8bd5be10a8817819f5dea3e91dbd19032bf339a325e18727beae8a3a1fcc07691931e274ffafd4ce98e1f4ef3778f7254ef748b87237bd54082d2340c3ef3b628fe9fac36ee4d883aa6876a0151704eea3a678fe74c23860bfe610f15207bddcd681c65efeaf7dca35005962b57d0e463b77e430ec9620c9aa16fe67d1357bf23be23d\nlabel = 798250bc59a7dd01906d16cc87b8741d16a7a2168648d6a7d51e0af8346347d700000000\nmsg = 38854b2bb70035c630eb18f92cdb1333a14781df75d9a6fa5df90a9f307ebc1cffbf3575bc023a390aa5b33488592d80753b0707bd600f089522189fe3129834480d5f9147bc33e5afb7ffc5bbfc1f6d7b87954382cb8af5b56baa01898d06130b5f25ff96ab9636b27cc4ec040c5c7c962933fefb64aa53799a81300a71bbcb5d45a29ec4f4c4f20d16aab39cbca96f786797bc871efdfa61e36ff896599417d33c0794e550da399e38e183115aa9169008be498dcbe8d13ce1ab10e0a4868e86f4c68fa377a119679740ff2fe1633fed84b8e2a59f33ef3a2f13cc2f904b0a0c2801a10c7d16b818c0a0b15dc9b66588991144e8ebd1c308bceba8cc36b7b417f0ec2d6c12aaa91970802aeeb2f83e67ea7f85ac3257087f19b0cd37dfccd7ebb0f40c86ca954588a92b44626d3281ba5af5c4d999981fd48ceb634757a338f969d5ce09f18dc24f7cba6de30e47aa5e8eadd957f3c121c73f32918d2a0e61f2469a9de31363f28ca0cc85ada3301dd9f4de8cb3551fc19c82aea08fe37c80fca221e54b58db3f4ddca8e89cdd30490d092f8c270bc54c23c7a1095a390c3ef45b50e59328e28877f81bb05c2bb97c2f33ceed6c83\nresult = valid\nflags = Constructed\n\n[d = 0082a411c8b1fcc0e52f27dda23b1004f1f68f4ca36b3d4d077bd6105d63c4f42c676d8fc08e031c9297617a2c53c602a207046f4b5de2f1f78f2054466d42fee730b0b95557d9965ee3a96d870b0cd882786d8287d650cb5f6b1bdeaf03c9c4bf1aaadffd747d725cf58ea9d184cc0cf4475064df227a57d8a9493f9b1eeb60dda43c3e89a57097f5a28e1ae2fb63c62b389d216dd055aa82655b01b2a0fca375aaf5dfcb179e9141c88aa3f5aa4323f3779101612505f06c60ef5077b2a46d5db7555ac0eec10f4c91af2cd605e34bdbac1548424c878a91dae7ea391c95a85ed55318fa5e9dcd464a11fc5425df5da1d1d33fbe659dc98138bcb73f2f85f1416dbf30dd4336733c04534da98aa1b333fa0444a4b337ca5368467dfe256d04d08aead94e39131110db422603fe85812cd15453ed02197f7c3ea38a84bf2eb21d8390acd3f2e955d7ec84286987b28ec5aef7929701dd466c7c1bab412e1550c118696bf47b3ca98435e5374852505188b8d70e46cd1b60553a5f56d2c6c47179009dcc01]\n[e = 010001]\n[keysize = 3104]\n[mgf = MGF1]\n[mgfSha = SHA-384]\n[n = 009ce4a11414e91683314b711e299ef58d817c68ece20f52902009d096bc7903250dacac14afd27d454d4bd21c4257f85820448ec74b5d5458246716f04252114873e3b19c867b00ac4e3b1ac1797c5fc0948a4095a1e87c8f5f6daeb754f2324d6ddc935c09a3cb86dfde5efa44002d563106891ea4e67eed97b4cbbf462fba0355fbb9adea1589f40ca565c04bb0ba23bb3ac683b9db0e7b591d5de431b42f174fee1c8e06adb78609f4e2654ac433fd721d3621b8c65de636e9ba769dab70079a5aafcbc12257381f14443892fda063ec252fe3934841c766208945e310693e735ee817e8639a8a9eade2f2e0112a845c83470349c32983e8b31407aada9e451f6973d47e39428da5c820681b8faec473e971eadeff14efe56e30060fead78f9155f5b9fb0807c0b800123f03c6ac5803334f6f8887304913198d98b2a97f0876ff24c3dc11644f6a7bf0e4e3a2aaad04ceca84bbc22823fb6559e914bfa9e1617f89dda2e90780ac15f12431406551b1f46e9995bb47eef70f6dc1d0e9929a22e5be91]\n[privateKeyPkcs8 = 30820710020100300d06092a864886f70d0101010500048206fa308206f602010002820185009ce4a11414e91683314b711e299ef58d817c68ece20f52902009d096bc7903250dacac14afd27d454d4bd21c4257f85820448ec74b5d5458246716f04252114873e3b19c867b00ac4e3b1ac1797c5fc0948a4095a1e87c8f5f6daeb754f2324d6ddc935c09a3cb86dfde5efa44002d563106891ea4e67eed97b4cbbf462fba0355fbb9adea1589f40ca565c04bb0ba23bb3ac683b9db0e7b591d5de431b42f174fee1c8e06adb78609f4e2654ac433fd721d3621b8c65de636e9ba769dab70079a5aafcbc12257381f14443892fda063ec252fe3934841c766208945e310693e735ee817e8639a8a9eade2f2e0112a845c83470349c32983e8b31407aada9e451f6973d47e39428da5c820681b8faec473e971eadeff14efe56e30060fead78f9155f5b9fb0807c0b800123f03c6ac5803334f6f8887304913198d98b2a97f0876ff24c3dc11644f6a7bf0e4e3a2aaad04ceca84bbc22823fb6559e914bfa9e1617f89dda2e90780ac15f12431406551b1f46e9995bb47eef70f6dc1d0e9929a22e5be910203010001028201850082a411c8b1fcc0e52f27dda23b1004f1f68f4ca36b3d4d077bd6105d63c4f42c676d8fc08e031c9297617a2c53c602a207046f4b5de2f1f78f2054466d42fee730b0b95557d9965ee3a96d870b0cd882786d8287d650cb5f6b1bdeaf03c9c4bf1aaadffd747d725cf58ea9d184cc0cf4475064df227a57d8a9493f9b1eeb60dda43c3e89a57097f5a28e1ae2fb63c62b389d216dd055aa82655b01b2a0fca375aaf5dfcb179e9141c88aa3f5aa4323f3779101612505f06c60ef5077b2a46d5db7555ac0eec10f4c91af2cd605e34bdbac1548424c878a91dae7ea391c95a85ed55318fa5e9dcd464a11fc5425df5da1d1d33fbe659dc98138bcb73f2f85f1416dbf30dd4336733c04534da98aa1b333fa0444a4b337ca5368467dfe256d04d08aead94e39131110db422603fe85812cd15453ed02197f7c3ea38a84bf2eb21d8390acd3f2e955d7ec84286987b28ec5aef7929701dd466c7c1bab412e1550c118696bf47b3ca98435e5374852505188b8d70e46cd1b60553a5f56d2c6c47179009dcc010281c300dd60b390ed7e73bc47d85692928b6a7669b75ac07b0d2d5e2aabbc97dd4f26f4504ccbac15fc18c8681e24241af32fea58e247ef47ff841fd88cd482685b24de080a373a7b2fb48300b997e911569f64129dc02092b51b0093addae3296c47a5388dd6f8cdc258c7bfa1cde81e97d01f198e6d05312ca8b9c58c2a11df5ed9e6ff75cd6925c52738278b7283ec198ff2c50e793e8e6842c23121dd5a702d312f6a0bdf29dcc932f5f58882953423176aadbf02dba57915fcbc2356d7b6d0e7a4ed410281c300b56e27f9764f02ffafd4689a3d1d1fc4ffc5c0d9d1b052394c72840963ee5eff90310b07cd6b45b0022439755aceaea774ba8aa99cfbfb9dadf8e007faa89329c347181236496485359d0d6eddc3c8e9f9ac3119f02b91e2e94cb63f1fa6bd4c02843714a74d5ae775d6d4422f7c4e99e5b3980bb3bc2ab9ceecc0a503f67720c8f294d15362e36b781c186a3c97c6076bce45d5853e57eb61dfed7e5db0094a28fee6df90a4406a9e3480adb2a972ddbf61a737dbd6f0afe961cdb8982f48326d510281c255e3d5e76ded78d3dd00179ea892c4cc8a79a41137ecc5e45a23e578fa596260b9e301c693850acc7e70eb4ec2d2058e23cc2f62ac097be6ab2b00ac53f6c0d810407e6b072e5c17d3a92e423402eab675ee94834ec84b60aeeb6e186292eb3d3432fbebee50f00717d79c3ee9d7b6dcca1a933bc7776f431c5d245968d3b131497e18232a8f52871bf8a386818ced67a082dc11a448d955e4a021f49bbf3ced0b74edb19d42c6addd0488bd80cbf8a2e02452e48b4fee72ef3fbacad8d83677abc10281c30089a28076d1d68ccad56388db0163b7b725e5aa3053cfb400bdcaddf995b2bea497896cf9c54f0cb5c25a22b0b16bbbb95367344c09c86b102a6b73e0f9b9aab272eedb06ede1ed7cd4b848f98308c4c122e40af7c767f62b329b3c6254ab944d365780c58d49b49d849aadb96bf69c5649985dcefad1d383d3c36d3d81ed16606bb1034e6d38c697bfad68a42745683837036b9cd890fbf797ef5d6690c23bb9e3b1c40973dbf6f62b005f61e5f8802852c84d27a601bfe363640bc16ec9e7b641910281c23c1346eae095cae1ef1feacd06a4c4d2f1ee4b135c2b7f3d22dfc10de6f4f67899cee2504252b572009a8fb80e807fbcd958f45a5237cf066f20788d8abfb76022032b6ad878160d6274c654681b9e399441fb0853c92f403cff13ad21d3ce998026e21bdbe3d98033fd1582169915b67c491388d41cef393ca2f2f583aae732d5d87a4561cfe160fd49a205531a03caa174ac48ba94d18e1b618c4935ecf562736897f2f813a344154387c4cd524115d352f8dfa10883532db127d4dd99258dc2d4]\n[sha = SHA-384]\n\n# tcId = 772\n# em represents a small integer\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nlabel = e3ed53a6f0f18a3e6a90044cfe6bf4efd1d3132cc274e37a1d65f5d86b7f0f44f3c924f714cb548c3e0a776a56c5ebaf00000000\nmsg = 6ce8486057bf0af47682d34def751d65a7cdf2edc2e1518cf96c95d125f17618b9a3fbeefe4b1c29ec258cfe3169aa771b3772c4997e472d65da3736e64120c1cc68110e5491fefde206b71a14cc4e96f826c1af4dea1369d6f29a32c9fb867c8910ffa786e47729ca862fb0e1b3b48700299d591a8cebdf0d8a2c622253dfdbc51fd554dd08d1bc4043b65aacd335b48490779be1b2499a9478415615ef70961421a4bed7be61a42825073054af2962e67d71201c094bb0ba924cf97e6e81dc4ebd9a8ee33030e2356b8e808a87b0cff1e91897aa241e7d1211ef464cfdb18a8881b59e346702e320abcaefe4e9f156fb589d54c340d15970729f64029341f2ba1b2ae0dae77be3a55122c85fa86945d41b1f4ab8411426ffed8fa632e75f609859\nresult = valid\nflags = Constructed\n\n# tcId = 773\n# em represents a small integer\nct = 1a93aa7065475280bff152e46394d26f07621a1e52972f0ee81c4f02985d276904c372f385c0f895c0f719ede146e397ad8e6c0c270d9da4f906c256c618d10cc581f4fde6f44263968f2eeb1b8c9d9240ea0976b8f4dbb8957a39cc598f3b31a69ff5cdd21b11dae9e0dd7929adbd6bcf5a34de85c99f2810960625d8ccb179b379296a26acc62c052f586ff31cead363a717c5726486fc1696a0c2f9d6740709a66f51043c318997911a87770afdf578c8d0c453028f2e597a3c5fdfcf7d039619736de870d84ddba29dad9f590483aebf4b84bc8b717ea498981c279c919c3ef70aecf7bef0fcd9536d340f43be884b3b5ad0b3482718e2132916cd068571b14694c4f6ee8433eaad6a13f3c4ed896ab0fce11b1b9d50c6347acd8ed088ff67aefdb19cba937e07d0705a6c8ffcd011629b33ad514510d5a3a31f53cc5f90817d5420472d554981b0bb9a45673e6fa956937f9f9ada017bc0000e5b6f5c578bc945402b216301afe6b25a1a961efadc4cd3aaf8bd3d4ec77fe13a554be5d73a4b2227\nlabel = f8343ff86e5650448a1a2c372b1bda8bf512701713017b61daa782751d0e3768e87e7b728abd485d2055e2bae4ad37cf00000000\nmsg = eb910d54e051c09090181c1bae07917b6b3b3f57a6a923307cb23f4d5a6e6f4ed2977762ddccefe94f439e9f44435e53180045f45de15320a30ce0139460d62603f53d66d59aae95b7000f0fb3c5d621d3583b023b69873a27fe52aef03ce6afc9b97588161d8a7c0a8fd4ed55174db1aae9e33649c5eab7d930b51f8c713e26c5bcf394a34ff1b893a409bf17437e0330cf4361cffa0e01aa3db7440b7c8c21d9c25e861eb8dad94f11e615efc251b37c63aca012fe778bd14e15a641075c8cbe4e497b4dbec93f63f8bf0e88a3e8e7f7a7aee334332db62eeef019f1ed55158ada3f79a32bc5e48f22b2856805a382b82edc3ef3cc492dad3519657b188e23a1b56155a3789dd2335759757412f4fee48f0aa4dbbda3914fe48c38ea08e835544b\nresult = valid\nflags = Constructed\n\n# tcId = 774\n# em represents a small integer\nct = 317931fe3f6a8b1f899371b89ac3d2497b91536b82f75179c593d8f5d4ec36284caf5587e49a9d1a4ac89ae6cbe6f2da24eb7a0fad03fcc277e0827a3c534fbc16f173cfd3d31279d229e50ed64e5ee7dc0baa5e46a3e9d4e79905cf87d85c2fbab5dda6afa8b9a08e3908e208231b5d5d56fade069077313c6f9494879b59092697c4f974377483ed66fee87431aef2b900896345c7072d705903497575fc22aaa3511a446ba3bc0f8118e3b74adf25c72a56495a5df1c96a6fff13410e7178fb32e5907afe85976b9764dedcea2d4f79fd3570a71844dff060084d8637d63577310d33741265e18641590c0a0a2909f8744aeb99cf97f819d614c751cb2c9158cfe0e3ef4843ffb7ba93958fe8e4cbe807274cb9c6d6b17d12200bb83b64f3a516eca3cbaadd70e4c55c4bb20346fb4f89f18ed70a829518f1b8864e1a83c5db09ffc880667b1ae30f936a30fa40afeb7f9471c4c7199ad7546de568c207de8dfe2bad374d7d4c5bfd7dce4398b4c971ca5700b13683d24e1c0a6d4f487e1f2cc86108\nlabel = f690520506e109069b536e670dec5d61bfb9f180291116fb2af2cd5f27bc523d9e820b145c1c03bbc9926a0629c09d8d00000000\nmsg = 0dae1d5855fa986c2b65cfcb24c2e3e6f84f8ecf91770c501ddb00b7e274389f5e7969dd2a1453e5bd1050f1c7961d35863bcefbffed80f16b2e5e282a0b67012a8ae741efbaddd1e062ac88bea714efd456d9a681c3baff87cb274d07ee5b9f75961b8d45bc2e3a69df97e477178e6e83c2c56e234336f3a219cfb77f32673129d1c3417e20ce9cdcefba9fb83375e0741bb66cd1c66fe62ae1be792a8a76e07e182ce6bf0116ff011810799412cafc477c99976222425a8843a457a3bf80c201bbc3976f13ee9a9b7fe378561b07602b3a2279af35ab5052b4dd71956a19656394bb2f89c7788cd642e3162a330c2231169691b4eeeafdcb63dd7c031f41b236ef579dfb688b0e6a4a0f7aa0c749196f154bdc8256e035e6ec5baeb3ab401872d0\nresult = valid\nflags = Constructed\n\n# tcId = 775\n# em represents a small integer\nct = 84484fe5185d8a4175d1501e8337df7680a210288677d116daf6828c7ac54fb635d29eeb745c517ce98ba08e1613073b1ba012605710cfe22b44d91fb95a07c261eb26afcca8385b0538e76dc4f0838478f0a1538c2cd12b53caa64b3c461f7abc5c01a2760f668db4a92451529c8c3fd63f4e3d15c47e7bf321fd1b90cfd1fa304ad289f36c5700f5289dc20c617e3447e59a6f590ddbacd194a42d44be825ae0558e0e0426b1ea46f86bcb746c643fbe87ce6d7b794fa3e575cf4692a457fb151fd1851f6268705cac43ffc2dca0d50fc1b1fee634478e7bdc5f64f00e53ea9dfe6fe13ae631530b87bdee1c33854e5091b84bafa460617c080bdd06ebbdeed51e9d91739ae2499fac61f980bfeaba7f190eda34acc3b60054afd731d51aeaca0dcba0de614119d4d30a7c6672f92752d0328dd926a05bd46640b98857c82388b4ee20450db739659997aed252d843c6ba8ee9f0616703dd8b33fd4c346593f325051c347fa4302534bee5dd669ab0ce33d210d0d72470e41403f05c812920ee0f603c\nlabel = b60b80e37f381cf571ed38a78823b59f0490163dbe7982f1369e986af48c8638c7937bd7302dd0304aa280e33c2bd03500000000\nmsg = a8ca5ddc13bcfba53524e57c821f4d1a979488b090c1bd30fc08ccb1e9c75b6e9011e7870ed5097b15ba4b0cb7762a52aaf7e68846216572ae70bc2057669d1b3e28deae3086c2309ef24b6d1338364c42c6bf2a5e504e2f1eee10ef2bcdd86054f38f04565fd1279b1a64fd84614b50f0ab724279398b100f10e1d64b6f83773e1be8877f1bb177a3dc0819d2440fc18e0fa600bbdbd6969213ac4502cea518b585dd53d2cf4775d96badc30c6cdd8df13407f5ccd6263b5d5e97a810cf14ab7330f744ba9789d89b56fe4a1d9808c5f65b5ae7c6adc55efd5626506f36ba3410d7ec8d33e69a8740563b57f5f1d612d0e4676d03fa2e0a3b87cf03893a3637b44cf05fa1b2bda733e15b633ed0c8d2e8049a49793ccb77c04874c9c992021ced72\nresult = valid\nflags = Constructed\n\n", }; -static const size_t kLen154 = 164058; +static const size_t kLen208 = 164058; -static const char *kData154[] = { +static const char *kData208[] = { "# Imported from Wycheproof's rsa_pkcs1_2048_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[d = 1a502d0eea6c7b69e21d5839101f705456ed0ef852fb47fe21071f54c5f33c8ceb066c62d727e32d26c58137329f89d3195325b795264c195d85472f7507dbd0961d2951f935a26b34f0ac24d15490e1128a9b7138915bc7dbfa8fe396357131c543ae9c98507368d9ceb08c1c6198a3eda7aea185a0e976cd42c22d00f003d9f19d96ea4c9afcbfe1441ccc802cfb0689f59d804c6a4e4f404c15174745ed6cb8bc88ef0b33ba0d2a80e35e43bc90f350052e72016e75b00d357a381c9c0d467069ca660887c987766349fcc43460b4aa516bce079edd87ba164307b752c277ed9528ad3ba0bf1877349ed3b7966a6c240110409bf4d0fade0c68fdadd847fd]\n[e = 010001]\n[keysize = 2048]\n[n = 00b3510a2bcd4ce644c5b594ae5059e12b2f054b658d5da5959a2fdf1871b808bc3df3e628d2792e51aad5c124b43bda453dca5cde4bcf28e7bd4effba0cb4b742bbb6d5a013cb63d1aa3a89e02627ef5398b52c0cfd97d208abeb8d7c9bce0bbeb019a86ddb589beb29a5b74bf861075c677c81d430f030c265247af9d3c9140ccb65309d07e0adc1efd15cf17e7b055d7da3868e4648cc3a180f0ee7f8e1e7b18098a3391b4ce7161e98d57af8a947e201a463e2d6bbca8059e5706e9dfed8f4856465ffa712ed1aa18e888d12dc6aa09ce95ecfca83cc5b0b15db09c8647f5d524c0f2e7620a3416b9623cadc0f097af573261c98c8400aa12af38e43cad84d]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100b3510a2bcd4ce644c5b594ae5059e12b2f054b658d5da5959a2fdf1871b808bc3df3e628d2792e51aad5c124b43bda453dca5cde4bcf28e7bd4effba0cb4b742bbb6d5a013cb63d1aa3a89e02627ef5398b52c0cfd97d208abeb8d7c9bce0bbeb019a86ddb589beb29a5b74bf861075c677c81d430f030c265247af9d3c9140ccb65309d07e0adc1efd15cf17e7b055d7da3868e4648cc3a180f0ee7f8e1e7b18098a3391b4ce7161e98d57af8a947e201a463e2d6bbca8059e5706e9dfed8f4856465ffa712ed1aa18e888d12dc6aa09ce95ecfca83cc5b0b15db09c8647f5d524c0f2e7620a3416b9623cadc0f097af573261c98c8400aa12af38e43cad84d0203010001028201001a502d0eea6c7b69e21d5839101f705456ed0ef852fb47fe21071f54c5f33c8ceb066c62d727e32d26c58137329f89d3195325b795264c195d85472f7507dbd0961d2951f935a26b34f0ac24d15490e1128a9b7138915bc7dbfa8fe396357131c543ae9c98507368d9ceb08c1c6198a3eda7aea185a0e976cd42c22d00f003d9f19d96ea4c9afcbfe1441ccc802cfb0689f59d804c6a4e4f404c15174745ed6cb8bc88ef0b33ba0d2a80e35e43bc90f350052e72016e75b00d357a381c9c0d467069ca660887c987766349fcc43460b4aa516bce079edd87ba164307b752c277ed9528ad3ba0bf1877349ed3b7966a6c240110409bf4d0fade0c68fdadd847fd02818100ec125cf37e310a2ff46263b9b2e0629d6390005ec88913d4fb71bd4dd856124498aaeba983d7ba2bd942e64d223feb7a23af4d605efeea6bd70d39afe99d35a3aa15e74a1768778093be0edd4a8d09b2def6dc9b67ff85764625c2e19236db4c401ce30a2572d3ecb4f969b7ad19c522c02d774465676e1a3776c54d6248348b02818100c2742abcd9897bd4b0b671f973fc82a8f84abf5705ff88dd41948623afe9dca60dc6543390767feaebeb539576ee8bfa61b5fcbca94a7cef75a09150c540fa9694dd8004ad23718c889049219369c99f4458d4afc148f6f07df87324a96d9cf7b385dd8622414a1832f9f29446f050c2d5a6407649dc41ab70e23b3dcc22c9870281810096a9798d250263400bb6277342881627e07cecdf91187b01b89ff47314188a7c20fb24800156d2c85d5666e8df6ceff9f9804ddfad80ff5767de56ecc029c72bf6c717df9f64daafc29acf9dc7908f9a0ad67e20e8949936ccba18d021a2c4febb04349a2b2047c4901385b6e5d0c691d118b33f81802b32ac272ef09e42fad50281800554f41b0b87f68a45722b3be0cf4ab1e165034c1a91002ab8f29e9ef9e2dab6fee7b2455bafb42037e9d2f7e533f348a147412fd72080be7c2633f5d802c91c39e6bcece3e675e59995033c55737020dad9e8b30d04b828adfb9304ad54a11a35a4f50709876ac5b118236ba76a4d7c9a291dd9607b169de1d182385691999f0281801c640189d9bfe8c623833210a76c420c6f44e5d760e259916cec2ae2b156456960fd95e2747660c389562250f055049cfab7e5c3039549384a7a2aaeb1c824d3af709482a8cf9b587022a00b1f0722db50f33cb26dc20dd2245d5265df61ee2983c938c2167dcee121fc4b4479c237e728cf633ab60a8c0ecd04fce7e3baa559]\n\n# tcId = 1\nct = 5999ccb0cfdd584a3fd9daf247b9cd7314323f8bba4864258f98c6bafc068fe672641bab25ef5b1a7a2b88f67f12af3ca4fe3c493b2062bbb11ad3b1ba0640025c814326ff50ed52b176bd7f606ea9e209bcdcc67c0a0c4b8ed30b9959c57e90fd1efdf99895e2608095f92caff9070dec900fb96d5ce5efd2b2e66b80cff27d482d242b307cb813e7dc818fce31b67ac9a94501b5bc4621b547ba9d81808dd297d600dfc1a7deeb061570cde8894e398453328740adfd77cf76075a109d41ad296651ac817382424a4907d5a342d06cf19c09d5b37a147dd69045bf7d378e19dbbbbfb25282e3d9a4dc9793c8c32ab5a45c0b43dba4daca367b6eb5f4432a62\nmsg = \nresult = valid\n\n# tcId = 2\nct = a9acec7e58761d9191249ff7ea5db499cadccc51d29f8e7fd0aa2cb9962095626f1cadae29666f04ce2afd4b650be59d071d06446d59107eb508cc60545727b0567dfb4f2f94ca60b939c60be111172f367dfd235516e4a60061648c67f5536650821ac2a60744be3cf6befa8f66e76a3e7c5fbc6dfa4dda55ecbdbffdc98d610de5667a4f485f6168b52bbe470e6014253874ce7b78e509937e0bc5f02857e1ad3cf55139bbe6dc7ac4b1ed5097bf781b7671ca9bb58187aa6c71c58ac0561c5aacf96c35deb24e395b6823de7fc96b8031b5906a34c4dc57e4f1226157b9abd849e1367dda014fbf9ed4ca515a7a04cf87787945007e4f63c0366a5bbc3489\nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 4501b4d669e01b9ef2dc800aa1b06d49196f5a09fe8fbcd037323c60eaf027bfb98432be4e4a26c567ffec718bcbea977dd26812fa071c33808b4d5ebb742d9879806094b6fbeea63d25ea3141733b60e31c6912106e1b758a7fe0014f075193faa8b4622bfd5d3013f0a32190a95de61a3604711bc62945f95a6522bd4dfed0a994ef185b28c281f7b5e4c8ed41176d12d9fc1b837e6a0111d0132d08a6d6f0580de0c9eed8ed105531799482d1e466c68c23b0c222af7fc12ac279bc4ff57e7b4586d209371b38c4c1035edd418dc5f960441cb21ea2bedbfea86de0d7861e81021b650a1de51002c315f1e7c12debe4dcebf790caaa54a2f26b149cf9e77d\nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 455fe8c7c59d08c068b5ff739d8dab912b639c8e9eade5d0519d58f4ead7208d5a753b4a88fe771475adc82d10ab29ded28caf03f9034d3a111b520440c02276e1b6417c42eec0257f1f05482868987f2f75bd33d1ec3dbc799d7b5bf25c4a0543793a4d3ce305cc43646bc450344e624fd381e24d8e57ef2840dd9d576da554ba408ee6580159e6d88438a28d66250b3b3fe3bc6624406022a9e4ee2778c38230674f635f56b9d6adcf2be6bfab34a8a431169d769876422f7077ded31fa6f29993dd1972b2d2d24b0513a7a193f6a88d53c49cde2c030f85e3ddfbc9f99b4a667fd9c652382238166f3d39eb2b78de53ad24c97699fe5738a7a705a2ab141b\nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 1cf861ef8b6c29474666605d3ddb663a259a9ae838417abcc7f7dd42d471d5f3812cdf90e3041c4c5bfd38ac1e4d95fd71661bddac45f5f8e3e89629a335bbf2eff116030f1c5ace8336cf7e94c2e8bf5a1d6116e54ec42b9da5fc651a41ac8fd38194e5029489cfde1f7fc850c0dfb3dc00021f74ae3847327c69afdb1355c7587bb93d5f4d2cfb35a7f70bcabd43eb32300585b6ee32f14a68c2a08434e923adb76dfcdf3ea5133edffa5ca20425083b28ecb045e69562b44286d320d87285e7a2e3bedded083c010401ae22c8f278b080112c4264a3cad3ed9fa31cf19e052aabbda9f8ecef1d64786258202bb61128b3140a355d65b982b0239764d77d24\nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 8122b33665648346f6cf728f285667cff7f3c20907e76438e64db81a6a5e74c34c5694fb5b4c826067bae94c5176e152eb16884d9c2b63d2ff41d06140c9c39469a4ae05cda86c81ccb208894266f6b24a0f79132f71521e10683faa05c8e68b77dd6c0c04cbfef55a9d1b68291c286e08907c3df029c52e15539027f534c7df8da5637db99355b24576b873c119ff1d74b3c913b70c48f366887ccbe6d206c11657401f41baad9290fe6ae01855a99891700d71775fb36237bd3597ad240fff4c03d1fe599cdec65baef11fbc4889575a55f255b51ec8298595dbcc89659382d35c2b85a941c33746a7937f3d18e27079fc3d2252904aa533fbfd2ebed2e059\nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 18e280e8b03d8588b923842d15fddb0493285ecd7ad2d9a9878045ce615ba07cb811fd4a0737e91ece5a63b70b1edc23e0da939ec654333eb77e956108b040bd6b92927e25a6922d1b92302036985915fedf9fb38431bbce1feee3ec42ff15bc4a4b6d10b3da41ec96667b81163b30b46eef4f46fb22f187da8fd536461e5594bf557a6dfc2337883bee8d6187192a3b4bea70398b01f3ea8c1547f6c57248243365b3c46b117924d8bb6845ea382c389c648d3e65ff0b8711bbe1a6fd3bea028f5808725f198cda0407a0ff46b5af261a37184547250f496800e697290e39d46d6bce67b767d73a63bd98f699c1828180abfd51a3048d050d496236edf1e99d\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\n# Longest valid message size\nct = 7e151b7b34e3b4abe045cf708640e61501c50fdca629aeca10259d45d15eeec6a2008b6336f57021ac6fdad9a6b29d65f098abff76f93722a8e23fb5e153db075005575dad6adccb7c020cd741c3419946b82d369a07fad5b0d55d51774f8991bd65e9e828d8f5a989c866a024a4a78434e9affd0af2c72f9185d450b627008a8a0968fc6373ca340410306a58921cce1207bb6f6c14e3d1f214304f9f6bb9199909e1610322e834b0ce9f55b1835d7623b82ef548545f984ea51466250159344dde902a0f021ba4baf26b16d8c6a42003f4d5dcae531", "187dc7e3f87c9e04470599eb623e04fca266e86f98cabb6866004e7fc80b36c3977456e51eb64f4b65f\nmsg = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 9\n# ps is all 0\nct = 6e0d507f66e16d4b7373a504c6d48692aaa541fdd59eeb5d4a2cd91f6000ce9b5734a232d6541a78729ac82152d3a30b51950a24ae379a108ed20fa4ec7542fe2281c2dd5de685564d15182f3c73e9c0135ebc993f5acd240a343d3257997582328c31be215c7349375406aa78a3ac35327226839bee2f1a4a0f8e6e06986cb33806c93e0b0c1d6cfd23f4a68c1f2a38c74b8df70f280984a840c710c52279034d04f61e313d4bcd8b3b5c58468a44565a1acb2eefc6d49044be7163e64ed84b5e7991ecba274a3a7ee4defb842a86ac4cbf2d3bfc9cf870ae025a3e2fbc775916a59579763c06eb84ad8edd1d03787e609ad446de43ebed16330ab06716fa73\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 10\n# ps is all 1\nct = 633546723d13ef2712561abfa5b477a36ce7c8dc5a9f43589ea289a15f749c89e4e3ba3ca6a615333e9bb5ff3efb62b32e7f11870c8bbeffe884a5ef2b1006045bd97bb29699084dac4212c217e10113232683445091fa7224abc02ad37feaf10d5b4af6f288fa01d85bcd944bf411ac56c0b7bf1037452f540f286114b14b2208fb4282b6829c594aa27ad5ef1dc67b5696ed2a4b9a4ee2354cc05315fff5e8a4e0e75675c1eed34d46effa73ea96e748340771dfec01dae937edd8924ece8470542a8251c31e9130e2c5f80152b4c66111df52f7e5f9b40835b44bf8e8e273b075dc04f758a30c24dc2c2abeaf639f4fca4dacd509250378ad0e5276374b99\nmsg = 54657374\nresult = valid\n\n# tcId = 11\n# rsa_sslv23_padding\nct = 94a6ecdadcc3a9c5645d0410929ba8f01c89b8426b889d3064cf1811f2caaa1e1a55a29a1869a7d719226bcea637407bb80383e76b5966e2ea4d56fbb2fb325da12546071b65898b12e36d0ea0e47245930eb051cecc4b8dede18adb4f1ca318cf0e36820f1cfd4911f076e0f3fbf9c197a0ed32063f72405477888f13cbab4649e3c8df4f022a4109ecb91fbeedbc4df4d89ad9cacbbd7e8e27a2f1fe1813d3f1b537ecf41878f05918171504bf800631781a7c36451abbc32dda5b55f05f4ba7b5414089d9d679248cf042756a4f06c37c8b5a18a6ba8f97853cc6763235ee841d96e61f2d75c188ca53d222d3d925a3d701551758feb79ccf8709cb61b793\nmsg = 54657374\nresult = valid\n\n# tcId = 12\n# byte 0 of ps is 0\nct = 6a8b8c01247d9d4d1c3bbaac58e077e37926854dc8bdb58fb7b98979ba9102934469836480a0b96a5b452e54dff55e77b52dc1cb93656f6802b7fbe06ca0923e38e549dabcdbce909fdd10d677d896384af75e7146794bfa009ebbb2d6890b1cfcad4698d297c759b0a01151bdfe1d48cf92e80896be923d02371930cafb155e543d9a21e52faf2395234e65d575fa9f5276c80ae4cd6ec18ac6d954ad043d2a46932763ca44476180b397215d95651fba63220998e06ab2dcc4935dadaae8660ac8c6356b871e0b1397af20d6fe937c3211e21559a3d0eb39c2949a96611b13740ae0c26ce67c373a9225a3c1773ec662ca20dee620c0acef1475b362ee9b9f\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 13\n# byte 1 of ps is 0\nct = 84c149c378f3f12ce202bb561456257057709114ecbaa4c3a7dbfbcbfaf2fe9a19cebabd72e39474b6bd7871c3dae41a9c87c5cb2fafc2d06d49c60ac401ed1e125522d0854fe8fb8611f8efb90d2b89a14eaeb6e991f19329dd7d183ef72cf0543dabedcdecc9977cc9395e2629a1dc8d359b2bc0fea6ef250c4cfa2ac8ad22a6a587e32859a8c99e4f7cdf938527e9e0bb597721517067d83fab31457e52e7a11b0393135d30e619d7cc47caf970facdd8dc4bd613b151f93cc53c1307cef68feb5a67d32337cf2ff954be7a553d3f07c9f657aebd9e8d4ee99e8736c152804295f366a4ffaf2a72e29c2f87b03b28b99da1f6a7ee0d9364ef711eda4f0793\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 14\n# byte 7 of ps is 0\nct = 3307264f64d4ca8b62c4e7da4cac117262e5d3a3dbc19a529ac5167c1987bce56e358726d0ecfc6cb591a12bd5f7531cd2249439254c366ad3cb7a608f845e1eca931018295208ba5c6198027b22191224c4568856ab331e2acf530fc434870865d3321ac90327a8c61f27cac9859dac8e3c38d8453349d2ef8e4a7e8011f6badd1530eae710e0c60d35905f20d7a2d118e7ce18ebb220f04b4089778cbf091bcb3e02aca83b4b9ba5319c3069188c7b00c7d32ebe1dd6e6535b5f667ce972f00ba773d4cf6a556ccf65bacc1eca2312881caf6a89ff5d83960846a5d9dd31477dcc9ee4ae50ab0cb2e574a685bd9d7b7a74c7ca9876f08fd64d1d5f196786be\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 15\n# ps truncated\nct = 16d56b7a9e672e387016e8b1c9cff474d560faa8ca14a565fba086015c5f9d53b205c4ccfe77ed5f3d10a04a23bc031d9c7fc809668ceb5c4e31ba8760475de713413b1ae5666e93087e146a2607c00d6492ed095973c7ccd79996aa26023a2c6623f382e94a4c595fbb596be074f87559267186cc475175152277cccaf9513dcb95a1f6540bb633a9a65182f2a53838b85329c9544c24740b24b27ce5d760f051c47e6cc107c264bc1a87ba7bd2bf27675547bda28b3d2a7281d6732f9dbc3c20eecb280f2ba6f25cd49c930dcc3a413987ab4de0fe9314a61e092b3708c75c9bf96831df05e4dbe31f75b2ddaf3bde7f01c7940ec62758006a652871d72b75\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 16\n# ps missing\nct = 25f67bc6c1320a13fa91a23d4d1801cc73594161a7f344ffa195d6dd1894c1e39d6cd81866462d05e0e16c02459a3f1dc5f0ecc52657f70385fd0b33de214216a2298b4814550af1ecd929170bc69b74e08299bea50de33021468f4fe2a2e4a43233d6872d15379ccea03450145d909c5eb11ca5f524e17b2065768b9bb06438e81b0b8ca816bfcc7eddcffba59b33e2a0b4ad8df215c2eafa240e553f1526dad66038e54f305a6d3fd6460e781239c9dc424ab6df7f75bb4327d873d0e8d7ecab1b09b8779cb841e002ee45f8dbebd2d483de2d7136ae7e350580dc8a48bcd6359a677bccd689bbdf879f2520d8976fc2b92e64dda8e7399719a13b8182c739\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 17\n# Block type = 0\nct = 371e281730bbc289cd77a64ab49b370ed7900c48f5625615ff28beeeeabc860b4673ab16003fd5e13c89c8b6a0e5c9b732044981ddf2bc45d4613bf409cb2e98123ceb661c1093773d71c67fd198288d6e9b832596894834c3955799ea20e242b632335baf8e8787c104499fb5d0eaa331f05a8b46383dd13cc05f0518d05d9b03bdfdc2dbc9299a04210c33f5dbed3779fb1548ead0022622234a6a2ffe5ca42a43db40f272d6633c7151360b5b90e135283a6aaf69b0491edda637dea0989e3a5dd0c3aac267074662443c37ce1b3fd4b2e9743fb0d00dc136d8df10b6fd0b60d30c1399ab52d75e2db559d8faefc45008c2d9100ed08caa88bdc11aea04df\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 18\n# Block type = 1\nct = 92210e5bbf24d2cd9527f6e24ffafafdfee242b146539f3731715fff42092cc8f5a1a4919417c9df9a5a32e61201f4354a87ab06e97f827f69e6cc13e7b9c79515145f210713523e6f64def697406a4929b2e09c31890b695b7b8bb851a22c7b541c5dc53cc75954c0246eae5a12af304133f4dcdb90f8c6f54847165612f7ef70f51dd493899d6e09ae9fed16fb1f1225d09750177893c5e5482e3cd427931ffd3fef3e901d51f39aa17e34443a34754533a887474e19213a5e24298071495d18c6ac77dece094c56bb34ed8274f5d75f99162a58dfc4240f5393baae58f484ef0a0259b56ad647ad81fe88c91b75a36b1acc67a56ec379bba03a8be91dc0cd\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 19\n# Block type = 0xff\nct = 6dbc27d33371f8cb3c3a54185a687a66eea8114f26cd234617b2f567d6013e222f33d7fe05298b73f8bf20266483571a52b1da2c0b1a431c257c62ed441215f57cd2a4af4628eeb21a9cd66a350a161cce446f25224a9acbdcdd709b14b810fafb02f3879605402e3fa6404e6e9a13b3f4fd3bd0e6c32f188a367a94aea813aebf4bd31635e5843a27bf7300419365d00ab97cb535866ba521dd0a8460fbc368ab9337caeee54f719f8998b126a111ffc6cff6d3c43ced45e8dce6565c00bf0be00694c339f7fdbe064c60e040a95b5d5b4af15fb7f14e00da6a591f187277e0c453eef7ffcef2a4efab93afdaa58e0bc1bb25286d9ce202176f395e29f92136\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 20\n# First byte is not zero\nct = 794ab724aeb176c4415a597e9d69cb567cece4479e6e4c9c19530b0877b53719d7f6318be8e970874c4be19984c632825dee7a38561a6904e23c776ccce71128847c24d5609e6790e3c9112393660ffd208771916d2e80d2c2fb35ff7936bab6c03e07646f15d09a88fd2ff8e70b624c66da4eb7dae241907ef328697c219d1ff347ada945e24ab526b6cea4e6b7f386560ab56f16751f6e2de0f7922a8946ae9afb9ce95369418f540163827f452f5d2a5029a1ce417453324eb015fd83ca2147331c02c762c457fc52ca5f097610c60430b69b6b0fc1c0877513bdb51923bca03e9af9174d3094530a007253958bfed03606e6f75cb5854443eaa363614116\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 21\n# First byte is not zero\nct = 8c7b80188818f63e6a0110cf94a169c78a0db75917caaf47405e8384b79a8f40de94f28f749186c4f16aeffb66168ac7c319d47de699ccae0edcb51a6822f88e27e99a1a0bb39d292e7d6e0922c1d2fd649376d81160d15cce10fc7082b88e8cd80dff13a33b54b8c00178a35fbbca633f4987f117aa9ec8e5f123dadcf29700ed5dbdad05bcd8e990985d950b210edae1ca1f6ecabf50a27e", "4bb23d4e80bf3955852e2ca18fd3e3c2f570fbeece943ef5c10ed1265049eac0d5b549713368703ad02311193ba0d3dac6073eb799139229a4aa0bfbc25bd5e886ad213dc321131ed12cf1008ee8af3a1588d06c75d7cf7375998e5a03af0ec8aa92276bd51b21\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 22\n# signature padding\nct = 34bc8b1a4646f2db8b10fdae22d6b5cb300229114015f25293d4b28e8f58783e1c5e6894da18dea527e4d843b51cf984170d56853e45f6ac77b1179eb0aa74fc556cbd632d576524b820a2c74a4c8159885fa08937e9c73ca0385c7a19676f2789b62f7a8b359a29132d74bc2b850e2335b5c7da8bf52d8d6fadd83ff9db32239bb737e890a32d561b10e9163c2fe4d35624e3e5faf664374c972a8d2e5b873c9a465e108bbdff1296c5557f314026558441a055d4b9cbb54179356787bd4bd02015cb3bbe02633711f266e915a0b4591415983610a2714adce1b0716675b95877bcef618784f2b3cd23fcdd0636e5856edb96852a32c9632c2e6e4b9a6f881e\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 23\n# no zero after padding\nct = 4629027bfdd6c33abda030f0cb3ac1b55bddddd11292520f142248bbd1efad14adcb7ec50d278471f4a98dc9a674c202d823677d2606cd639fda443d7c14f0aa35f472189abe1b639f0856743212aab46ae35160ab4e6c08a20e5b82210b07b6eed11a315ef1b1f831b52bfd3abc06382b51c41a665ca6428e4bb6bd0df7895d056b8c17093e73c8129916e3abab3f61ce9a94c9d2fd30902076104b0e7fbde8da601f6c1bcc56a0100104848da6e9fbb28d893274b40885b3003ec7781aa710c83fbf4d4bc197630b1455853c4d6d6050011a7f7377e9034d29e4396f52b24ee6875feef883274cb0842b4b177d3fa3b416095c6ff96f6de0d9123dd9ce6d31\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 24\n# no padding\nct = 910ad40ae0d8af151f512354e1cf12af7c4851cff0b659026e90a9ec4dea6c1e4b2b33cbe8260501493df2e7fa2cd77f020a7cfac1ca379eed3fe6d003335653a5f022f6bf5010e5f58c41fc91253d75eac2072479d4bb3509e1351a66f700ff4ac470115490021734bb8099e66c35f904f09d167303e26163393ed556cdccdfae95f239ebf0bd361a8adad927fb9544ca30132195735cb026dd0dc66c6efa0db41b73fc1c917be384a430e0788f5f872785cd709f70793204753d7b207fbce2d0bfbab11d3d614b99bf87bcc9a34db639fd203c9c081ddeecb9c85221e03cb9171685dafcfeaba470c5f1921a6fe016ba4b816a2328eee9853fa6994ec313d8\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 25\n# m = 2\nct = 6294ddf0fcd137390cb2193e050b5f61bf0183972912dca88ddcef7d54388665a7ff9be1f074b5e33b55dbf7c4212554a4e6243d3974aef4d95794dc72261883a45842da69497a36ed22c3590b0110e857bd0fc729663df53c831836f890b2b2012c9f56fc6dff36daada1a1e1cb2d654fee868c7c6fd58435dc8edb95dfe0271787074c2be9aace1f33ebd07ee6112cfb62f52487934af0c22ac93dafccfb01c561b370f05f3e604e92e5380103ba91113d007ab97b21ff3feb22f37c1a358215467d0a0223d43792f4947aa30c38f14246d1db9918c94600e7d0a393079dec2d9ad368ef378b2fff72cdd7c572f11074caca0995ca3e576428f651e1cf3764\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 26\n# m = n-2\nct = 50bc2c3ad07baf0bb9037b704b4e81c97003c7ce644ac8ed0c52ef9b1d7f825695f44a46e204786e6f7fe52cf01ab4f098e438a1125a79f2e3f76add9a8e9ebf175e92c5aa81e99abd17c6871b26de6b40f81c45d43194136f687545a33d590caeed0916deea9cb44ef815aa1695d9f7178dfb47b4805b3e2f47ec1e3de933e5b3de2950dbf702f3d09d7120ff94f43082409169beb5814955e445aa4914ecafbb36efc82aeda8b5d005f042f7a58d50f06763681d40a88119fa4d7b21e4a372701de8f5a4ef18e30e99f4126fd031af5aa28cf4316b03150a2e0a66355ce17124b13bc586e918116c2355f3169c186a80a85c1302fe01b33d01fd3c61fba0e9\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 27\n# c = 0\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 28\n# c = 1\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 29\n# c = n-1\nct = b3510a2bcd4ce644c5b594ae5059e12b2f054b658d5da5959a2fdf1871b808bc3df3e628d2792e51aad5c124b43bda453dca5cde4bcf28e7bd4effba0cb4b742bbb6d5a013cb63d1aa3a89e02627ef5398b52c0cfd97d208abeb8d7c9bce0bbeb019a86ddb589beb29a5b74bf861075c677c81d430f030c265247af9d3c9140ccb65309d07e0adc1efd15cf17e7b055d7da3868e4648cc3a180f0ee7f8e1e7b18098a3391b4ce7161e98d57af8a947e201a463e2d6bbca8059e5706e9dfed8f4856465ffa712ed1aa18e888d12dc6aa09ce95ecfca83cc5b0b15db09c8647f5d524c0f2e7620a3416b9623cadc0f097af573261c98c8400aa12af38e43cad84c\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 30\n# ciphertext is empty\nct = \nmsg = 54657374\nresult = invalid\n\n# tcId = 31\n# prepended bytes to ciphertext\nct = 00004501b4d669e01b9ef2dc800aa1b06d49196f5a09fe8fbcd037323c60eaf027bfb98432be4e4a26c567ffec718bcbea977dd26812fa071c33808b4d5ebb742d9879806094b6fbeea63d25ea3141733b60e31c6912106e1b758a7fe0014f075193faa8b4622bfd5d3013f0a32190a95de61a3604711bc62945f95a6522bd4dfed0a994ef185b28c281f7b5e4c8ed41176d12d9fc1b837e6a0111d0132d08a6d6f0580de0c9eed8ed105531799482d1e466c68c23b0c222af7fc12ac279bc4ff57e7b4586d209371b38c4c1035edd418dc5f960441cb21ea2bedbfea86de0d7861e81021b650a1de51002c315f1e7c12debe4dcebf790caaa54a2f26b149cf9e77d\nmsg = 54657374\nresult = invalid\n\n# tcId = 32\n# appended bytes to ciphertext\nct = 4501b4d669e01b9ef2dc800aa1b06d49196f5a09fe8fbcd037323c60eaf027bfb98432be4e4a26c567ffec718bcbea977dd26812fa071c33808b4d5ebb742d9879806094b6fbeea63d25ea3141733b60e31c6912106e1b758a7fe0014f075193faa8b4622bfd5d3013f0a32190a95de61a3604711bc62945f95a6522bd4dfed0a994ef185b28c281f7b5e4c8ed41176d12d9fc1b837e6a0111d0132d08a6d6f0580de0c9eed8ed105531799482d1e466c68c23b0c222af7fc12ac279bc4ff57e7b4586d209371b38c4c1035edd418dc5f960441cb21ea2bedbfea86de0d7861e81021b650a1de51002c315f1e7c12debe4dcebf790caaa54a2f26b149cf9e77d0000\nmsg = 54657374\nresult = invalid\n\n# tcId = 33\n# truncated ciphertext\nct = 01b4d669e01b9ef2dc800aa1b06d49196f5a09fe8fbcd037323c60eaf027bfb98432be4e4a26c567ffec718bcbea977dd26812fa071c33808b4d5ebb742d9879806094b6fbeea63d25ea3141733b60e31c6912106e1b758a7fe0014f075193faa8b4622bfd5d3013f0a32190a95de61a3604711bc62945f95a6522bd4dfed0a994ef185b28c281f7b5e4c8ed41176d12d9fc1b837e6a0111d0132d08a6d6f0580de0c9eed8ed105531799482d1e466c68c23b0c222af7fc12ac279bc4ff57e7b4586d209371b38c4c1035edd418dc5f960441cb21ea2bedbfea86de0d7861e81021b650a1de51002c315f1e7c12debe4dcebf790caaa54a2f26b149cf9e77d\nmsg = 54657374\nresult = invalid\n\n[d = 2bd68add0171ed921c0924dc0a40427fd4a4fc67821c6e7d50d0e8c730c665e2a843b1eb243e763a740d3c666b1bb1d4f9466b32b2b2e09a9e26e8777595da48a13ba9f9c45f6d2c214b9e5e504bfb3fafbce6adb31e8c15bde1968899efee1a5dcdff0d2a8bf2e27301eaa07882494610a23dd3644d0eb0a6086450e3a7bd4b5c446c01814be16c208619f8a5b7463fca583d936864bf74d96788aae8e5bae3c052a2b409df9a08eb9be76b3dbaba28863d5c56ee42eecdb85075e04de90b6dd3bd9408d7fa5694697c185162329ab9b57f21a84cab007c1c10d975f5491977fecf6c949f3a566d84be477ddaab02c0762d1b232f8a61910715a0ffa438a461]\n[e = 010001]\n[keysize = 2048]\n[n = 00dd904590397808c4314329623d9013453843251b13b8b3c4fef54598112af3eb31c71103c6259951674e53bd93a7e36d19472e474ebe8028686d9529484d8bafea4a04ba19555667616c8478670594009c9bc6a3efe52274cba64c724747d7edc194e4fedde32a3289d94c31936e7e7a15d756f548492f5b345b927e8c618bdd550acb21a17ae148304383db9b3c7baa3e4c8bd8e844a884daa3e18d56998cb32f9bae4d41d56a18ddd4313c8089b75e9dbb9128470bac9b087fb61928ab0f8c4c89360b020899008d08e8bd31f907a807e8056ad6800dffdf9ed9d964a939e7e48114b84978551acb85c9df9196f3eff55286d6cd4b39a822a8a7763a18208f]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100dd904590397808c4314329623d9013453843251b13b8b3c4fef54598112af3eb31c71103c625", @@ -3848,9 +4486,9 @@ static const char *kData154[] = { "fca291fa2ebd0d9ffe3e8cf5071a524f863df26369c22b38eacecdc784dd65e20d356a6e20de033c481ebe1c5cd42366ac83c26caf73875e628875c925de9c3939bd7f912bfded876393b1f6a314447a96bbc4cfe3c01443a2a9de7121023ee025194f5a20cb768591a01]\n[e = 010001]\n[keysize = 2048]\n[n = 00cc890f82986e18c35e18a2ea354bd2c7e88dca9f0e1981497b31342b893992a49f36380fbe9829995e9aec1b3ec88dfbcbfb11bd2a00140f8f6647c5e3bdda527799ef0571f45427f10d2463ee096fda48c41085d3a90bf7072d06fb7a3d2286cd10255a82a52452ea3e61e2d8e35eff9f6b831b48f09b522df104f48ac58f76cd241b9fddc042e7683774117808681693536600e1cd3035dcf6ec30a6bdf659b15e0417c3bfc4c9a591f2f858081df1243477d41812a6ac74bc4fbb6485b18aaf6a00c32593751a527723b4802d318038698de9063818044cca1b035b8800193fed71d3c38ed3296fddb336552b68d380d1214b13a1c86e6f687bd37e5fd22b]\n[privateKeyPkcs8 = 308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100cc890f82986e18c35e18a2ea354bd2c7e88dca9f0e1981497b31342b893992a49f36380fbe9829995e9aec1b3ec88dfbcbfb11bd2a00140f8f6647c5e3bdda527799ef0571f45427f10d2463ee096fda48c41085d3a90bf7072d06fb7a3d2286cd10255a82a52452ea3e61e2d8e35eff9f6b831b48f09b522df104f48ac58f76cd241b9fddc042e7683774117808681693536600e1cd3035dcf6ec30a6bdf659b15e0417c3bfc4c9a591f2f858081df1243477d41812a6ac74bc4fbb6485b18aaf6a00c32593751a527723b4802d318038698de9063818044cca1b035b8800193fed71d3c38ed3296fddb336552b68d380d1214b13a1c86e6f687bd37e5fd22b02030100010282010100877c32fdfb22d2dc7734329699ff43fc901b7ca0a7a25575eb58c88a1e3838df3b679af332f97074dbaa1bc4606e513efdfbade07435e113fd956eedb2d24c105c9167376028cca63892d00c31dda66e1dcd627483a472fc8b905413b9014e21a52c90d1c7c0c4b2f7dfa2cfb583c7a5e4603f548f98720a99cc11d03b2c6abec41d4ab1a6e4f73f394ef46213fcade3131ef85b004fca291fa2ebd0d9ffe3e8cf5071a524f863df26369c22b38eacecdc784dd65e20d356a6e20de033c481ebe1c5cd42366ac83c26caf73875e628875c925de9c3939bd7f912bfded876393b1f6a314447a96bbc4cfe3c01443a2a9de7121023ee025194f5a20cb768591a0102818100ea90923ad1a16d8f5704bdfd34a7f059941112c391f656b750f6c9ca1d916397ebcc33f48c300a9d001071caf00d33f80cf0ae3efd899c6443e6cdb9214d9dfb209e088163e75dd7582d3639df75d9cf113eb42bc61f7e90ebd9a619deb41c76d5728f3134d4564142e166f46313f1a7492f23d207fc2d8fa15cc7a01f24214102818100df39faf40d3cbaf2aed2d0f69c67b2bbb19e7c81bc90306918471d1e406cac8ed9969e8bdc80be72502176d68ea1f6016ecaf4d3b4ce24ea76762325fd1680345e5c5b77ba4888b9d7d4fd85af16e20cc922b8bd2bbb49f6373236ddc939063ae276d2fb4a3812de74047a1d9259fd877e2329920f4424585bb27afdc61eec6b02818100cc97db2438b2d00825c37a1fbfecf7a47a94c5c415ad4307d433dde05017ff4184a7716dcd551dfcc11096e086af4d73ff7d72ce7880ae0b7a7a775811e74c73bd887a2cb9c215c4fe21395a13420d0022af89a160c719b33834783fba53693c7182e1c8eea682b19baf5508b6deaf79d548abbac7c23acf3bd4dc3e1acb7dc102818054bbe08bb55ea1242fc26c79c02308d0807ac58e45b281fdd2ae63da30e04f9c25f22b9ab187d942f131d2b75d0b13a3b597aad995df4e5a05bf9056023d014b5faa353a3c66fe27754b2f3508a26a0a2a6b58aece23d8ce7263483a66009461d3c7010d4c3dfec39c4c7ac230e4a1fd459f394f6d261399caacf44cd260b8a30281804f8c1d61e059c9920e68544adc7e028f8f05933b4f49cec1614999d120450198bef26bdde1099bffc5316baef331c2b3d854e42a2f18858735641952104847cbbce742c8a6b9238143af4b27cb8ca4ef931f5509f2bca875397edfabdd2263e0867303dbdfbfac683a10c42d76184f320c469ab0f680a83797684b61026b93df]\n\n# tcId = 64\n# edge case for montgomery reduction with special primes\nct = cc890f82986e18c35e18a2ea354bd2c7e88dca9f0e1981497b31342b893992a49f36380fbe9829995e9aec1b3ec88dfbcbfb11bd2a00140f8f6647c5e3bdda527799ef0571f45427f10d2463ee096fda48c41085d3a90bf7072d06fb7a3d2286cd10255a82a52452ea3e61e2d8e35eff9f6b831b48f09b522df104f48ac58f76cc241b9fddc042e7683774117808681693536600e1cd3035dcf6ec30a6bdf659b15e0417c3bfc4c9a591f2f858081df1243477d41812a6ac74bc4fbb6485b18aaf6a00c32593751a527723b4802d318038698de9063818044cca1b035b8800193fed71d3c38ed3296fddb336552b68d380d1214b13a1c86e6f687bd37e5fd22c\nmsg = 841ee52c94cac3dda367429494b2a07274e19f7f9567bceae1a940df892b8e44c7c86bdcc6ea7232774ee2195b19bfe932a88c12401c06fe0b865583d989ed3236fdb18264499a36b6ae6ba1bfc68b8220a0e3fa2f8221bb3e72e267115469c8648b5ec81d04393f8357daea9b849b95d2707a3b13e4e27a5be8e75e803f41b081c7accae863211f5357a4c81c\nresult = valid\n\n[d = 355d71fce2f312b7c53d7911d7fbdcd976ddb3d5809691d3031e2d4656b7b48545bd7b265aca5f9779e2c332e70d592904b9e0caf2a8c8aa87b9dd8d88ac9ec370a637399688c62bf63ae41d87e493820cfe30144b7f8f7f6cb3c88b00a907be37190398927353a005a1a821edc644ecbd9ebe67c2993d9575d88c45ead2251e270a28bf017051d8a4248d76172b65c51728c23b56a8eb3e8c24dfc35b05675314f4a6e808411ec2564969d7e1a23b10277937f3e4cb06a338691d26677927f6a67e5334bccabd309fabc851b5c55999c160300ee10511656561fa98c0ec5b2dec78491319862664bed347bef461b5fa7c5e53859bc36c440a47f39a63203d01]\n[e = 010001]\n[keysize = 2048]\n[n = 00b519563f7b707c6e9b89342aa5314536c521dd78877a3307b372f617622cb06c84626ca4e09e92cb869acaa07b04e18ae51a2935eb0d4cd29ddb96e5fea661c6f038859e31a96bcebefa32cd77dcbb2817c20774ce6badb1795c8b1e73a555921e6cf2726663576d9075af06dd89795bdf10b3f1973cdfbe81fd0f09d9b7aca821e3f403bbf517982d39f1a3411814a24f72d02f96a545cd0e0297ed88f3603cecc340adb01e2b35f9b7d8c2e4fa04e22122e5931cec5a12a3e0b93ca623a7d1a337c2bf6faf6ac17c0480a2b7e922dd99ee44297c5c085f044a92865429696387768e1ac55b0acd5bf312fe10279d3e7277f11c46ebf161feba67aeb49b103f]\n[privateKeyPkcs8 = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100b519563f7b707c6e9b89342aa5314536c521dd78877a3307b372f617622cb06c84626ca4e09e92cb869acaa07b04e18ae51a2935eb0d4cd29ddb96e5fea661c6f038859e31a96bcebefa32cd77dcbb2817c20774ce6badb1795c8b1e73a555921e6cf2726663576d9075af06dd89795bdf10b3f1973cdfbe81fd0f09d9b7aca821e3f403bbf517982d39f1a3411814a24f72d02f96a545cd0e0297ed88f3603cecc340adb01e2b35f9b7d8c2e4fa04e22122e5931cec5a12a3e0b93ca623a7d1a337c2bf6faf6ac17c0480a2b7e922dd99ee44297c5c085f044a92865429696387768e1ac55b0acd5bf312fe10279d3e7277f11c46ebf161feba67aeb49b103f020301000102820100355d71fce2f312b7c53d7911d7fbdcd976ddb3d5809691d3031e2d4656b7b48545bd7b265aca5f9779e2c332e70d592904b9e0caf2a8c8aa87b9dd8d88ac9ec370a637399688c62bf63ae41d87e493820cfe30144b7f8f7f6cb3c88b00a907be37190398927353a005a1a821edc644ecbd9ebe67c2993d9575d88c45ead2251e270a28bf017051d8a4248d76172b65c51728c23b56a8eb3e8c24dfc35b05675314f4a6e808411ec2564969d7e1a23b10277937f3e4cb06a338691d26677927f6a67e5334bccabd309fabc851b5c55999c160300ee10511656561fa98c0ec5b2dec78491319862664bed347bef461b5fa7c5e53859bc36c440a47f39a63203d0102818100e9cffe9f3b702d03ee7c25703f1314b2647963de2da16f2c7966d3ebc18fea929f28cb7a55f576d9c3a5a2513087a439d74cae037a965a31832b87188d3ce71a2000f54b983956c8e6827e854d21b4c37eb3948f6801895319b1cf51e020dbb7883bf15164f1499696feda88eb0b6d75877deec33da2390e9976d698a6d9b0c902818100c648c5f9422c0127928e7a9cfe9b345185d53e06d8bbb35201cae7bdfa2ceb7a6b31bcb88f4617c995feb2b71ec8f4e1854fc17639c970bcdf37fc46654305a690b8e6a6bea726e8b7ea40edb886532d7944a2ad2763cbe612cc170d7ca95fb90ba90a806190252dcac94a3e79ba45e4abde0391769c1e750834f5cd00e384c702818100cb766a369a7ca54f948a87f1c391912323f7d68612e33661574bba02a02fe28ab0e1c91fae09aae11935dba81739121a1b56e8deb220806031ab0126c65147321ec376b1cfc7a5d3b173c131b2cb3008270b92adb06e15d830b5e09979165edcb93aa0669a16b658cb10ff8ec22af197a2ce5da59ccebc240e3bb1c6a8fb2ab102818051a7f48792bda678127dc476d4cf3bbb7adef75d40720405f8a103d093af5e061b10ef841dd4a2c52c95282a0b6e7c924721322daadc8f25e8d3187c310569d54f7225e2734f48d1bbb3a7ab7e3b2b13e605e2ec65f54e29e081d5d8830709599e38ae0f729e370165aa817dbb097ff10cea3013fe818a756dbcc9a0f405be4f0281806011e90bcbdc97ec1d0d43992f8830d4bda5922997eec843a9ed14f80f83d0a0afad3cc320108cae02e4010403b31650c26af431563f0821858c5da0095a9813c45c11bbf2a43bfc36ebd036cd4548f406a933235a5ea71aabe29ca536c5d8a37fd1310b43f0e1bcec13bba1d6a9968c718bf974f5b73ccbd808d1248c8f5cae]\n\n# tcId = 65\n# edge case for montgomery reduction with special primes\nct = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000\nmsg = a3b94a63d4937de4bf024bce52957cd9af5efb3b0defef908d5f2ce35941b10168128951a1c5093dcdcebaa0622fdfc1e481daac4ce5675ed6690cec5f8ef20305185ed5b61db798e7a13626831fa9\nresult = valid\n\n", }; -static const size_t kLen155 = 242948; +static const size_t kLen209 = 242948; -static const char *kData155[] = { +static const char *kData209[] = { "# Imported from Wycheproof's rsa_pkcs1_3072_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[d = 0501205bd17b88d0d6626dd0fec898a0fd7f68f8dddcc314f74d167c40495b958a87e4ed63202e6ac68f4f4f4b88e3ec7a07d85757a7458468b766aad9a40f77337855408b28d140e75c2e6b3604ea8907bbd7f8e9578c2400ae645d28e2deef8bf718e29cf12fccb92fef9869f43aee5bd6adc223848d169cd6c27c2766652766ff81993b3e015a553decee0ffdc1624f39f8d96b6ed5d95047c1570b59fa2eb3d688dd5e14acc9407b8094f18b4694244eb1adcd655d873f57ff9af6e4fec470be236baf3b20c2040ab360d759c8b4e618bf8bd4e0ec6698f1b72c7160ed0521c82b5176b60fb63503d0ae23f6e2fb7a609305b0af62150b921ac53f4de899666cb01db0c9d8b650753015c1b6e682e6bf38204e59f7409c3808c0e53f254935540a381a963c2c1a77c6f987f06a07a0572686ed22882dbc82e7823cec080a58d72b09d00cc1d245cf158ff49cc40599d3af719dc301b4aa7f5b03629ae853e9daabe284db86d5c41d0401143df2b4593ef4e3747209c523f5a7f80f02d011]\n[e = 010001]\n[keysize = 3072]\n[n = 00dc8f7880672f0cf9d63617a8a58bdd271a109badda0fa826f94b8a795526b6a49a80564ccaba8a9491a935a53edeae1d9a7b5463d9e2ef3ee0ce7bff5d4b6c8147b5c073c2f220515d531d55a36687a6de3c34775c2f15191ac0a742d7342228c8d910fe6bbca439539c485debcbd0ee0e4bae317503b83cee8100ac7bb4587467cbc4373c4bda2eedf7c41631e50922b580f5bce81d24b208cabcd2d75fcfe99f75b493dffc5c9bd990f7fc3bf2efe392fecae36f3e4ef4456c1b5de99cc7451733a910b6834b61ec29274d986be3752c350b13a327dabc08dfcf6565499ad26e853446633eadb2970ca95bcf6bf05ffdbc2a804378d76985a71f06f90979f9fef716c36aa625a45b5eedf50825a53e9d9435b23caab9e5c64d38fd3a767e185ad7727d6e15f9e9bab2f4184d6487695db9a2698c672b2e823410dbef1d93fe40c9d357ee9fc77f849de11363f583af8ccf5181ca1aeb944c422516cb401e950923e4bd881439fa1093c77582bfe1ac5993674700b6434339e0245315d86fcb]\n[privateKeyPkcs8 = 308206fd020100300d06092a864886f70d0101010500048206e7308206e30201000282018100dc8f7880672f0cf9d63617a8a58bdd271a109badda0fa826f94b8a795526b6a49a80564ccaba8a9491a935a53edeae1d9a7b5463d9e2ef3ee0ce7bff5d4b6c8147b5c073c2f220515d531d55a36687a6de3c34775c2f15191ac0a742d7342228c8d910fe6bbca439539c485debcbd0ee0e4bae317503b83cee8100ac7bb4587467cbc4373c4bda2eedf7c41631e50922b580f5bce81d24b208cabcd2d75fcfe99f75b493dffc5c9bd990f7fc3bf2efe392fecae36f3e4ef4456c1b5de99cc7451733a910b6834b61ec29274d986be3752c350b13a327dabc08dfcf6565499ad26e853446633eadb2970ca95bcf6bf05ffdbc2a804378d76985a71f06f90979f9fef716c36aa625a45b5eedf50825a53e9d9435b23caab9e5c64d38fd3a767e185ad7727d6e15f9e9bab2f4184d6487695db9a2698c672b2e823410dbef1d93fe40c9d357ee9fc77f849de11363f583af8ccf5181ca1aeb944c422516cb401e950923e4bd881439fa1093c77582bfe1ac5993674700b6434339e0245315d86fcb0203010001028201800501205bd17b88d0d6626dd0fec898a0fd7f68f8dddcc314f74d167c40495b958a87e4ed63202e6ac68f4f4f4b88e3ec7a07d85757a7458468b766aad9a40f77337855408b28d140e75c2e6b3604ea8907bbd7f8e9578c2400ae645d28e2deef8bf718e29cf12fccb92fef9869f43aee5bd6adc223848d169cd6c27c2766652766ff81993b3e015a553decee0ffdc1624f39f8d96b6ed5d95047c1570b59fa2eb3d688dd5e14acc9407b8094f18b4694244eb1adcd655d873f57ff9af6e4fec470be236baf3b20c2040ab360d759c8b4e618bf8bd4e0ec6698f1b72c7160ed0521c82b5176b60fb63503d0ae23f6e2fb7a609305b0af62150b921ac53f4de899666cb01db0c9d8b650753015c1b6e682e6bf38204e59f7409c3808c0e53f254935540a381a963c2c1a77c6f987f06a07a0572686ed22882dbc82e7823cec080a58d72b09d00cc1d245cf158ff49cc40599d3af719dc301b4aa7f5b03629ae853e9daabe284db86d5c41d0401143df2b4593ef4e3747209c523f5a7f80f02d0110281c100fec6a10bfc49b58a2c850eafebdb997649a95575a0c17631b011cb20d7a320232a815b9af6040d7bf23d267e5e06304c33e04c85e6d481442f010a9758ba08364a70035ef99e9c98eeb431505b2afb6779d1c91d0ea2fb0a65dc391e79ecda7d52fd7dd69923b25dfae448cace829ebaca6b3c8a3cb64a81800614434895778c20d629b125b69f42945f66b644f3840bcfa6fce361074256c50863ecca2ce756b4a9fb7e993d0f1fa48b2cc485b7eaa61405fbef150e7563c2150811767de0f90281c100dd9ec1cee6d8a971b166902c44a4f02ef37a62053b41288a1d873d399cbc9e7bd306ed906487da2f49bc1c1809c0d4d88106d6879518ed925feb66aad5ff3c2b83466c554ed97b96abef55b3b02314f50d0385a0a1d8a46ae03e8fce91b412120f0a10dc681570fa564b6873bacd997b616b2bd7733fb723ade23bc1089da32e509583436f1e3448b579fb21b240620d20458d08f0f995abacc0a398f0ab6a67c9f5bcf7e032fb1d668fe698d80327599ae3fdf3aaaab19baf17639443194be30281c100f1bfb40cd56573971acb5eb65b0cd2bf4502228f2ceca5a45c37661151cbfdb0a0a28233b600fe727fd6ba71e9f1e15e4d53260960907fe01ce1d614ea220bacc8512541b786637d51f3355fd44222af7b0e2ed11d9454b4f7165234b2e8a62188dff3c9ef21ca1c16f70a833615075ca2b9c28641398fd4f58fcf2650f752aa6a760cb584dd969cec80e1cb4dfdeb6bf1abb80661892bcf7dc28a5ea3309c8acf7f039e8af53f267d517a3737d2de1a9ca158fef171f8bda1e9a6f03b0912b10281c03e3c2ae8d362dc9294e2dc71d2050f7ddfd9ea54d5c3028366af67be1a09cde7afe72e277253c42dab632bf0842ca698f602d993d186e2904c676ab966c6fa3aadeec4d560032af5b0ead10258e0412e5fad31855e6ddc1e3742da57840b3157e8e946bade6fc6fe45e57f3ba0a5c40825df56bc761cda6d2693757c4bd318d414c527cb7414e351d7c49d8564ed379bc0084806cec50806e1c86728b7cd2b606212a43267bf694d6453dcc9e73f5b798a49a4331d263a2222154b5d834a43490281c018cc971e9186f86c144d140ceabbc9ae22c94e8d8575356fb6a4a033991ef210bafa39a4cd1abfa99b332fde9e56955af179459a7236a700b7fd1d88093906f6130ae7ca9742d9ed0d5c63e6a9e9b43df4d8b261c12d2c2f9148bc0669f165b8b881879c3ed58d4a6cd5a3f1193e9abd2784609c01fb9094c7c822532ad7aec2a08aee9e263095ad0426455cb59258c7fd3731ca89dee31800d191ed7249721c25266650c46dcbfbae3070604d2e009914a2e269a01bafa5bdf8bba31c4f3b60]\n\n# tcId = 1\nct = 142b27c795e6d7451db575c90a38488757a5c07760ce10e23a1eeeaa20a08ef14cc07e3ee757c45e309075f7261ee35af580a72c06dc6b0446233687592e838b1220816fc578bf0ccae6977aeddb03fb2c0b5112334acae93f64026afa503d8707faa9989c2176c59a1ec2ff6b6308593c85c11d94a9da2fad66c860fc248f066574fee8b0d82fdc684d8eabbeeffc55c3897099415d99c5d1598cc3ff335bf494c8fd36f234a20566c0d35e3bac56082fc6a81b8cba2c99c47d1d372481ec23f35b62a6469cc42f4d349eea52f7f08a63898da4207e3104efcf81de2ab1e33cd243769bec34df4a4e7cac1c4be4073694bd56170dde8c4e12f85d2f02df12e9936d2990d4a6c490ae0cf6c3bad313f3a477db67332319eeb5932e9d1e1321dff28a866e939fe50626342e141854081981f388489a962f38220ff14a686fa111a5b236eaa4eaf6d3fbd54f93fe744e2767a815adb0c43e947360a149fbf75469957dc3ab8dac091f6339402620424b9cff8324e2a35a5a2b765897ed6e8b2542\nmsg = \nresult = valid\n\n# tcId = 2\nct = b5d5116431fc78c12ee663635c9e9c32ceb91a18a9af36ea63e7e6b647e17a981741279957fe4f0bf08288082fd4c1b6b09a805ebfd229396eab3689b5bb2b686ea39637ec69c1b8142c7033c271c9cae9abfc14f8107a8a2d57984ff2a45c70b276167ac8c92a070c718bca9a1a274258fc385a62faa02e8f15167f9e825c6ad7e2358566f79f6641c6e959e3b898ac780e369f43739321906cae687a9d229f9c86fdb01cbf061dd3c53f8d0c950d4226e7c58a66b310e197e757db3516db2388fbee4e4cf16d12bb2786607617e6f6c4b86b26d36efac63fad1dc561b91b66122d9600124e03b18ca58da78f30ab0c31c5c7f4bc059ce65dba182afdaa788cbbdc3bf8d48b7972c5400f14d3d460d329e0ac60ccf96b3c1d5e4ea9f763565322a110de5569fb74b6cd44de2a5777e23c681f3f769afa961c42782dd2e56e22b4af1c777b87a15df1f6cb48b6a39f7396068fe40168c4dcbd3cce69daaed21554a3b15a2ee62974b112733ecd4f78ac4a05c63eb759842f4503a950bc7654df\nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 63b63f6eb3fd2322a6c85ed16318932e83f32535b3ec2527fb41dcc865bc44690554467655034ad33aa0fa993788e80654ab0e0174f8dd238ad68c3bc194f390dd38d26408778774848c49a6a606e7fb1b3bfbf5f19db4d4d1ba2db43fefb9a9bac311f2e1fc1ab4f5ddc00a009b9dc435448f250a648b206fe764505805c9bed1729d5bfeaa4fddafc115d281703fab0e79726d5546fa698a45ca6e5e561b8c2964b2da01914f808a498ab77672eda3432ed9974f0a06d320ff87a4222899f893a6cb6abf13d7e56cce2ee7eae67fc26f2274b63ce8301c721d7195158b6c966b8d36e3cff0aec6f218b0fa6d8490493471ee0f08b840b6cdcbb73a164246864de0f35565bbebe51585819e42a425090479537ed67f98236415e6ad3ca81116beb91db802dfb3f9da733f86cb6fa90904c8a382afcbf6162f0d89ee04973f2d26659325f7f00a4ae9e800de6aa27b6c94b9d57791658eb0714b7cba5466ecfe44bd5803647c3825b58c37187311a8b11399f53a877c265da82493a90869e376\nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = 072c9fb5c97732ddebad895eea7af5ae193a6cebe74a46cc2f911ddf31ea5a90fe7052861a520c8d8a2680b942eadf644933ac12d3f4e13390d0905808e2d4e7f29b3138ef7f50b360266833fb3ebbf3db0dfd33642b710899472500528a49b3d8d036671038820ede3a46709f7c64114e74c50f81f52ce4eeed74403ec9ed4fef6fb7cd788f8793b9951c1be5e075dfc1c53172dce2ec8c6ebebc3cae300beff7b551", "df0a11913f0a3aaedd59ed70d3308a3a04cb1f656edf2829c8c3d1de7530ce5db7ca1bc5d0e7d3830c77871b6af589b5db87d3d6e8f02c0954a14cb1ad4a79481ab124674acac340e0fb20dc6682c3db4039d2e15371807686b260cb093354e9e1b1793b86aa087455b54ad5ddbc9fc6a5b2b8f786fbd70c7998f55114adf9908a3259f51f31f228741ae5e7ed598000d8171f9c3fc1f24cdae7c6947c8d612d3918f4c7b01682e33633cab0875a83a779bc211d0c8c6c189af12c93716003a86ff7c5ce00a6d43cb37d9f467dff17156039f50c5a3c811f0f0b8be025\nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 0dfa0e455f2b30f23b868ebe95dc8008664d18f0a00da3612c045138c4ca44ae8d8bfc050f377f1995ce2084e7320bb75c763d95219f4fc11d9a3af128e9c369cec5ed19d52af27fd8e4a462b39c645c4b7b8534bdf7e2d5e2e7cb99a4bbd5713c3401fb1dc3dbe2f851a5fb655e3289d0592367c0518ad0dec38eb84c3a7f2400d3b53d9439b7fdfb42a8320a5617ad83366787cacb3644294a1a98deb09cf2dfc626889f5824b71d20b1a95b7b984760cd1f382a472d6025644770176390b8f38bebce8f28b68944eda8e5c6e99c694055456448f0df0136e7e4e881f1a6b73c642047327a6ce3966cc7d3124434191b09a0f6636e2346e234943cabefd18418a60da871c77a858551699583ec8c30516a28ce4f62a779d0f468f2efdb5fa60a4c647e62f045bd56f6df1564c5c2f112ad050a5bfd411396cfff1bd9618529efd92a62735e01c324da2ba4be1d3f450c2d37b7913bb809874bdbc0081397dd55f93716606a00001b25563f413d0c4b9c2b81efe320d9478bdb65fb3be9d268\nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 740486caac4d0038274e7627da5325320682e610bd678923158c7e23ce3d430e6bb0fc1063fcd84cbcb2415ac32128a0e506b2f95899dfc67c2955514d8e0b0e4d84077b869b5f4d13eaf96242a0925692ff69c752190082b813bb9dda83907e1d6c4733af31e00847e856c8d68445fd2021d982a0ed9165db69933f50acae667a5121672294ce4c534479590a9f4425a8fc7c0cdb8abfdbb290c71b4379cf7e7cd959f4557b2aa61e185e95699345aa4010d67efe3891094d5c0ad2310f1884111f4aa0d33cc1a4fa494c5a744c10c307069377c848e7042ec1581f0dce3fb7febd7d347c5abbce2ed3d2ec085644fb661d15ad8aa041a375ccc77c9e01dd47e300324738db555201506ff60fbf6c12a82f6acdf7396fe38e4692d1fbc9d86887709f81697676b0f45d57379dab3409b173827a6619572dd8e168b991d6f9f6b996453544032e097c28c320ee2072d5aa9582cdba70f40ee2aa58b0933896e6c27b0933268cc577ff5f6e9e6a7591b73dea4c6ee24fcc365bb7688eb786fd3d\nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 7f56c9312bee49fb2d93924c4be0ddc552ba918b292938136752bdced1074ce61b0af9f1cdea7dc572ceab2ae61510304ec9674175bf1f5fcbb78d466d1b8454f02c54d11e93153b9871842378a584722a5e85aa229a4c7a4399eb598f11bb931ea97d385a75627dd6698dd9255e77bd09d49b0453f2b2f7850dfea6f48ad7dbd64f046d656b0414da4e840059dbbebd27fb71c819a953440bd4bd7668953274cbedddf83dac7dea1422a6065cf4933beee13b7bf20c95ac07525f94ee38ead3809fc9eb8e4ae71ad57f72f7e8d6969aafbf8700c99f6363362dbeb0fd864c554f9a1d3cfeed9e8a94cad44a88427f856707c9f674aa2e2d29b075e246207bd692ef638c556ce50673823f5e0947845cee31ef97c1c92111d3121c7565cee925182c32ae3082ec1b0de1d6d85b61773f1b4a61a41f356f972e1358c71ea7bf9d984f603d3b69bfe0f0e995e38ef5f81f10c9e7d759eac65b7349a91b67105e30193c9491b137186bb834b8cd34171dd2b1cc4c5e923d9b29ef011937b9c59c8d\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\n# Longest valid message size\nct = 74b3f849a2957b53827ae1eadedf9fa29dd46c3705340afae5b18a4154efc6f2ec1705029383be4af5ce9140fdc315e8ac5d50e6537a470c0cdf0be4a66be30adef9c32e2caf8351b695c2e51ba0b1ef2dc466d0cee3c79bd95a8513f2241b3d82b8e0638d88f4b370ef17e0ac2fce14a626a34ce60b3e3f26ca01d26264ad1d577ea960c3eb57aa2f5cfe3a49f21fc081cf980fa5f433366a7fea9fc9aeff4441a86db59c8694b253d0bc35cd21332698a9358739b6a7524ee7228d89dfb0dbacc1e237b50bacf8c1d3f10586b68dd79303a37e2d0b6164f22a8f67cf0a39c4f66a4548df06353c4d2117691b1a2cff393a0ac9783d2370f52d7e6e8bd25bec8c193d1b4984bebfa72ba46c11d999094d0a5ab0a78196a6742c560291b79af6cb29a8e2504b5114411b8d83161c522c4a584b43603e47afb09500e82ed6d6a746e529742e50095ca9a8344572002881819b2cb50fa301f3b4d0a2b98c8f4e817d53dbbda8ef8487bdac3eb46ac4dda2eb7d1e9d08e782075669436bf5c094c7\nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 9\n# ps is all 0\nct = 88a6584754ad31f28a05575dd809be25231d078d1c1e46b7240c1c402645b710eb2d2bc189dbc16d82d9ad7bc5cc1df3318fc31bae54d88b25819f2b417f4da85dd11330cb8ba58bbf766bfe421af84f2b55a298ca0873fbc72317748c0437cf1416fae4bfb73a6ff973f62115d3cdc71d81a4cfb73afda00fcede7b586599efdc3aeb5e9ad6e816c0a39440629b8547163ac01340381607cbadbc93fd3e24a627a7b88d9d09dff135d22ec923af52d0dbdbe37f57956719b552ebd15803525b0d6509841fc3b35e8c564945f6ebffcbd96b4f34bcf4ff9120fce1c363dad2cefc2a83d427f47bf29968260380e47ff34e87ef9e2d9004a68641fa0ef26ae3a66a423097b16d4b82e8614cded1ebc68e7629c11eff3c9331d22adfe184bf4881691fa80d32790669d832c858c97149c47124c8ffc7fb55376546b7d9f173c51b899a156c7d4d5d8d0aa8d3b5ce2624cd24fe34fed4bd57b08a4c464f719bf67327fae5805d719276d3671b0cfdf7f05bf0772dfe1c830ff8f091ed49e73f60c8\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 10\n# ps is all 1\nct = c2459fbb04d640477c76958c8d5cb949ac552d188502553f01e6b3ec654bc70c55045b0184006936a69fc7dfd6684422c54463c8ded5be163f3392302834954c91852525e1beb096059465e6c261de5afca752cada74922debfc771bd0b99a5770f9a80d4b76e8558ea8ec6c8aa5cc28fdc3f049f5e38d99f2899d59d9b5ed6ead7581e991c56f8f6f1edf16881dcb7b29fb00a8566f0dcff5a1fa99ea2f6e4264545ec11da7762117ab938e3d906ee20c114cc35778753d96a89ca3e025efcb20215b6e983b9446e559831c4b5c06791e282d03bb303b9956bf3d90cf717e2117a45718edd2591d67dccc8405a3484c1633f0c7281d8c2605d9d2da7ccbe0d992c12c8bc54f30aadcc65ebb4fbbb27ac39571bde40631f8abd579c2c2a444b088a0bd112fb6b9ce010489e8561f6d411adb9cf2758b8874adfd0bc90eff1652f7ef9c6b810dd90a1ab591275605f9b658273d2edd513bffb5be5fd681a2b1f50d6dddc9b9b3f39d59d407d0710a712b3e6f3ac2a74c310caac45827c7ae241e\nmsg = 54657374\nresult = valid\n\n# tcId = 11\n# rsa_sslv23_padding\nct = 389edb8f7af2a7234657b851306c9f2443b9302403fea9ca9ce8b4e7a246dd2bafd4d669f34d409d04677dc5a64c42aeb834a324c9acb7f13604959422703274a686f8f39825f220173135cf4b6f32a97077f037cc7667ea02455f56891f98845be33b2e1a08062faed9ade751f5fa1b4a0d387fdf6be0db76f6525f924fec655cf8db49ff7e49a10f0facb52909bfc467b3ef4dda4ee287f681fb4678bf7f77545b7e8e168dd8202b464ffad10efe93350b6b125bd9153d9610dd3e7d9856392a9cd93ed9f77c6531e445383d0269bbff5a28524d29513f21ed2eb452456723606014c031722ec8a4768e2c17c609a337b0b9e992bdc43e6c49a20b834f8c93d7806949c32f281293393163a7ea5f83437c647dd29ef663b1c748304bdb663923b1cbc1c50ed4c1f5cef5c2f9b97d735500772dee60b5dcc2bcf925b2b815571dda26024d835dd99813ff469e5defc2a5f86da2049924ada57d2d811acdba5f8c0f7513b9fae73a5856de97fe8cc2471a06284075dcf00d3fb57a938c7dccbb\nmsg = 54657374\nresult = valid\n\n# tcId = 12\n# byte 0 of ps is 0\nct = d723aaad7aed7fe22277d057c70113531122781e8e46cecd035a9d26e980a771653d780cbb21d70db01aadc4a8b13b51380cc015326f5655e4acd5fb8e6175999efea729f0e1ddeb0369aace87d73d2d6c97edf3e65ac51a4b0edd0ff0bf10215cbf084ee7b463042f440b164e1e0d725651c2d79ae8e853bda5a0c656fb6999560b0734ad2f831d35b864e9ceda47dec6f6a675d33bf9412fde2432fa3aaf4a3278005f70838e7ea045097eee942e93c23f1bcc67bf383d47b8c98c7f7fbad6472745245266657de351cbf7b268e093bfd3eaf75c00da99873884f5c048a50348f99554c6a4c2f5e87f4c791764a09aa7e87a8f6e706cd18a6435b756f448fd903990e3b8edfd88a511eae5facdbf0db75ff279bb648b21517de4d306131552011c218ad28eb8e650424582b4ff49b47545f95101f6e0c100c795ebafac15a386a40200433f023d633b45c5b16a0727bf56488934a6328a352793a39d3b1d77b1a670ef6d02c76cd16e056740be323de03dd09d2ba30c913f289d312dd5925e\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 13\n# byte 1 of ps is 0\nct = 5b68c3c463fd8ffeda06c09fddccbc5284017f753ff81e1db255ecc8c32b7c11e7f92ddc170fd578f6d0e8218acd1b04bbf5bf540c1167984dc63abbc5799284a7c28a20ce4f6b95e142571f57198a6b0bb9488f455fbea076e520853b92e848bd", "1d29bb0581b6b5eb56ce839fc1c1afde7815d075f5da520443fe6d5d4d03ffaa029736d703457cb73e3769f6d9b70bb22d340886e088ae8356501b58ae6b6167bb0a29b9065305ac7228a07279a2f9787742991cb9c136ba53c569615a74f323526165ba73c340b041b97bb13c129bfeae795cca3dac7a1dcb30874c1b298056bf231f5bdb6419f5eb436ffc1f3101dae12428ee5ed02a4e72a4e7db60caf26b7fa4dcd4e8d0e663ce66569364d058db26c29588011543fc8c72995d325235eb4d3a6f85e1d74ab16cb3166409d3aca165c81746d4c956ebf8fb5b7b31bc31c8a0509cf068794ab0bd687dc1ed84ea6b17e7f98d235e7541bfa6e64916cb02f6c2892c56787c1ba490bcdfd7000f529c48608c2efd6240ed7e84fc1b04f0cc\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 14\n# byte 7 of ps is 0\nct = 01af89a4d37a04280b78628261964cd3fe67d062b74c35e851f68b9f8faf7454a22df1c84c64f625515b16b90d298d1123c3010d845b86c7bbe516e4434f1feaf3d83829d6658d5128069bf4a3fd5e0870903ac313f743b9c7a8f3a7ea4e9f72f5b8774046980bdc1a1af025337567bddf436ed9b739a7305dcbf76ed4d7085183a84bb298a262241ca5811113b60e211626adb2c20fdfd80d1bf76e763fb3eb7f2a0eebc565218808fe0f8b0351516773f4ef822693169a3f1c31c12ffbf53d583b1598125707ced9b6636acd2a66651eb3e94bd21055b13d4d6509bbfb01f9cf449f84397b448a7a761a878195a4a96f6ae1043b947e224325b5262145abf8b2daa65544ea8d56bf33cf9af7be8e0c8f20eac6dda208f45d068d4ffff279bb0f87ce8ed1562fdad32e89819f6d86bbdd46c175214514b2801ffae449029ab0987dd2ae49a619e6717abbc2395cbd02b2b0ee4023dc858e10fb08af579720a51b7aa51e5b366b5503563c271c485056153efc362515929ed6173a4fdcfcb0fd\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 15\n# ps truncated\nct = 700d40cfb0981f7b86260e36712a463d2d2faf1f9da3bf762c3f993371b441d9e3747f126dfe2ca3b6d538a2c53147e7bae60b6405238f0d76cff5f420f8b641ccbbe9db0f0b2eaac87335ce99ce8a2eec1bec4d569fe81cd580f6490e3ae27209c1d022de5fdd02eac36f674d664c75bbfab5020afc8fce701b6769de63eeb7c72ac0e428a3d88f071e68f377c79d5624481213ed8bf42d5f56a3a00b170c63f064cc61d8966ccf2ca5983d7d1b56f4e81e379e57aa8aaf59a05946c1c24aebef5eee5a97b4d6ce8796b2e731e9b31d3633524cd526c30fc921cf927ec392f95116c121c4599a9e180a9bc963d01cb3977e2d5f72747e5c1d839a515802a7c26529fa487ca5954bf137fecd5e46f301c54e8227c89f4ab766eb9b5f9d9a1d96a0a482c2415ec9bbcb5613a1d239add7fb99f24a4867a85a8e29ba668c7c1b5948d79b2f412998422bc35457bd05a4e5373ec671a88bc15eb7a4fab7394e38541fe8d4d2dbc7094be069933added250dafd8091dcc53ba08301e64d49a4960c9\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 16\n# ps missing\nct = 5a76259027089edb019b04788cb702e5e06b13b9826d57351694d20f5984badd4960bdc49b900c903255ffc689676044ce0990447fa4c674e780b24c142e39d157bd649995c23209b697f444a8d14f96033707c636c312b019783b1985dbae4b1558a9ce257fcc6a197edb6624c309bd3b2bc41898f370a0f94cd9531bf15f635d1ff5895654358db4e56c211a732a237cf9792b84096d747f41159ef8529324f5901d28549c726cdd12b9f60fd110a18b2ee2007abf99e0d126b57e8d92371091ea3fe289831097ee0b97b11edd36a5e382d3360ba33059375248e6e8a873b5e7d1382c430dd8ab68d93ba151680ff08c23159c7375bb455a9f73cbfec427305b378c4ba45f2080803a83d00aa058994b6cd3429653a3bdfade0b58221f94bf4c132888a595cc73ab6a705299e10f65297dc6e70f8c7623312f7205cfaba759a9663954ca3cd4390e7be33e0ecb9d3a5493c0329e6c07d048c93ff285d28e338db5595c5dfd6d31e920e49427c0623c01d498bec7ea2f1977a3d6a1ed7943f0\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 17\n# Block type = 0\nct = 0946361acb9a12452e370d04abbb2f64de0651ce5d6e813b4d256476003cfb170048284425c150dd9430dd53a2ca6fb8e86f1375ebabe86603af28b3561fc7df1cfa22fdd5d92018dcc4e208ec75723d55706351d00c8ab8017d703a0ed1eb5ad4772ce0abfe976d5c8c1e2b238ac50e9c7bf7871bab2362543312f24141ce3e0ff5fe2cdbcd8d36596189a504e16e09e617ecfe3d553ab36d529d885608cb4c3648b763b173a9f3b003e8a97bb9e8a0a19c5edff9f0cf585c0abb60af2545444df8789a747da21def80f287a3d54c0c5b50e114e2b1c17206011fc5fe9ad783b375044c442daef1b7c789cbe846809cd8eca17c1576060c1ff702e8b3d908e57be8c23a1a0984cc512937c3e3709f2f4ee82401db017d2a362af38f4e6629b70cba25cae45ef4f7a3d1c66c3ac7ceaf95b54638f8823b6ec510293f1d7221c2524f3b9011be4fc017ce600f6d0f77b271bfbd2325ed58e5975c41dbbcdf752e8c1bc40a096af1ccf5016b77229a4b081fa771f249695da0bf14e7be770ee010\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 18\n# Block type = 1\nct = 849eb249b9b5904f726cb7db324f5579d331895bd3ce5138edaa2d283360feda0bd3ebd97468ba98f3a5060ebfee43e495bf75db592f816bb9297fd1bd260d6f8ff79ddaee1100e013f13e4812caa3a8db290b4ae7dcb34701a2decf9834c53a0f6a5faee7cacfb11d017516aba150619021621d6aacd2612577802a52c88c119363358fe96c67ac5b3fc25c6ba28d8e6efe5f2b3305d686c58dfa3417a40134327885a302f59e9d81b5ec46127c391b5fb1a12d9776ee2190cc20248a4beae4c46e4b58130fbc3b805935a00df588845eee7956990d163c91b384d0db2bb66fed9eae58f15d3f39588e75ef79c8dbc60a87e4470ed2f48a48d62e2030ccbdadea0dc5cf75b21a8163dc2391bdc7d0b7999263b70346b02152020ca6160297797393be3a51944dc2666d829302eb9e1829fbaafefbec28710d58a0eab63ee49a5d1f0c2ea49b73f331ab27170fec368dc2473d1dc0ba7bf7b70b7ecae315e67b323ce267d5fa6b9fc83b20783ae20d755127b5654272b76c88fa362960f66466\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 19\n# Block type = 0xff\nct = 99aea15afde0b40c12960cce598c11d618b3e4a0502eb9764cc114eed704113f0d13d9c1181324c18669f6385b5f6b1e0eff715769e5b3236a53d7638b1b27fe1b6bf2089e97e0bf6b587ff2ee42c708ac45ebfea88d057b6fddb6af2f8ba0d0ee5da9366961ac098c0b8349683aaa5dbc789ef0a49737b059bdc1936ebbc03a00330b84606dd9e0aed5e2c51f9e336ae9f19c225477f1edf87e463e4d0d80cf6c85f8142cf6e9b33b83b9f4d0e62540ba4b3f73a8b3b6b9ed0728ffd97e2332131c6625578eced873f96e1a84e1f22c1ada6d8bae41e0f63f284d28e9198b4f047f9664f33db978e5d7843b2891fc5006b25a17cb8418c7cb17abc7c8235b9fc5c2acbe17febd87e3b758b1e0fa783117e738219bee41b29c2b64ec23c413f00cce03bb23652a7174fd299dcd68e3b5521a0b22f89cbbbd021fbb8723f5020e2e7205bb071dd792c6c5ab293f8ce1c5b837b6a8966a9560a38d52dd6518e636b69ffbb43035eba80531cd1077d7d1646cd1a458cbd4e88a42ea2ab62906f2dd\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 20\n# First byte is not zero\nct = a225db92d6853b708dd72cbfd081c06ce3d6c4579def7e6bd8b45090cc0b9f51d4217d3275402d5ec90be82e920cef6f9bfaeae58ac461a61b3cf568186c6fa2f3a14db4d349e55cdfe5633a530bb6178ab1c7d126686d3297c4871f19e065f1fec05b85b72b675d58836dd2f741c593719d8bd65d74b9c61ab771464766324338e9b3bd3c05fde9027f2f2746d806c3f8e3b41b93a2e45f276af2df8886948d9b4f1a4f7e67f2ad7ca03ccb2275850982e7723017639d51c0f09138f19449ff344c1caaeb72ca8607f6012b8fa6f7924ef0b6e516a79b02cd2219b03421ba25e7af6272f57d118e165da759af7b64b18e60b9597d1ca41a49da64caf8f9788dfbd67b5b68fca5fbb3d42e045328739d079596cf63ebe83c39041490d7961ebbd2c4729059b4e01d180e4b34d69fab70832dcf698225887377c615affc0df708dea84511b44905711e68a1dd3c0c6247f35c998299b82f1511168a79f40f50f7576eb4c963e00576cec70dc0c3016793c44aa9c8d9f7c9d34907523613d4bd84\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 21\n# First byte is not zero\nct = 85421977730b0f2ca7ac9e69328c09853d07e68f0c12396011a88e1b3d0d8675c723c3c7818b1b3ba6e46d1902eddcf05eab8f2f964e5b17e9bf0235c118336a25dc99469b6be3b939090279f0435f28e7b813444b1eb63a67aca79153c67addb59e1329c1faa7bf9c92870169afad12198dd0954fe581749137e63dceaa0151a4ca2e4157248458ac4d999dea03deffb079f01b7bb64d5e3f0f7e53817fd5af4d11c4768ee2a5b184925d0924ce5b8143d902768478439627e13ff2ef8554c322961b0d3070abda2b0821b53053228f63f81a634fc32cb909b7cd14cefa5208348c0044262ee4157d330cdfa1391471853554ebebeecd74a58c51d8d4dd433327a2b8bb6e2a29f986c6ec0b6cbe86706f8aa7f89b6287d818ef770f69e48d0266abde3f94fad09cc6f7bac45740247a03b7dd7aa6cc2b710e1fbf74d7d914c9588877e8e52ecc3eb8e5cd5b9c772a1aa3acbd2ce86168451dea1f539fb740fa4fd966bc7d124b098ee4dbcb86ec326a54665752a9050f80b90ac34dd51f1f11\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 22\n# signature padding\nct = 509c69e802c2ab812fea8c77f89dd321c0edfd279b200e93aaf46591886148722b06584fc8745e938d069cd4c100f07c48c2f81b7f94d47f835244bdf9c9eb08af688ff6908ea2b6b938b9265fbee0f421a35086223380a9925b3570b3c0eaebc37b9bc18db3271e7dc62850ef17cce8ce17d68dd81dbee566f4a585da87d4f02158f80b7ecebd0687acd6dc52a334ecaacd67895720766ce54ca6a3872ebf90f3c9b894a0f44c0e1a83d226807faf67144fa59b3a21cc33339d2bf9249ca5018b96ef837c3fad08e325c7d31c9ea2fa1fe4b7dcd36b1fe7c95530787423708a80044a745dca51ef448fa953e27353308a10d431c01b688cc2002614fdf60efc7f8e969b3b84caa04ac8305ce87586b0d1a01f016ab6eb5a970766201166d16b42d0829e811d258", @@ -3882,9 +4520,9 @@ static const char *kData155[] = { "9cb188a8308215dc910c83c3499870989ed340d3e90575ad9632f5ecd11bc041f4c5651993d5a0efe54af8b6ae87a2699a1fa34333ebcd069264d230219af3638c42fbb6aea60090832117dcae0d7795b13fbf2b0126f0a2a85868aee3ba033d64cad48b1e9a7bcea144f059333278d38e1767c6ef682d9d40f6ac9ebbb8\nmsg = deb2027b4c88c9d2efae9fc1aa883f016f01f7e8802aec6cf3f637e669b7e595e8d97d299bbb88\nresult = valid\n\n[d = 76557e33fa3349551c2c557d2b7c948c11b736f52766df40a37da1a0d263ce2798d529efa34e4b5fa79307c0345cb9acc995dadae0d7a7d1d7237a53f7b68ea0b73f70fc003450830b57dbc5b37ba185e01500771d7111e10b2495945f81bd854676cd22b3f3206b0be61931bd4e6b34d9d30384dab033104ed8a3ff4416cf02f60939fefabcc9a5ba2442e9bef333ff52488a0e841d9ef7ec83e1a476c447b94d4c8239d5f64346a9fef1de49bdff5db251d96d4823621146141d46aa601040139009c37c551455567562831847b6c43636aac85abd279b24390806cb9b555b05e0d26a2457801ad8f5724452695be0147c36e9a0cc332d2adf77628aa43253e4ef5f337484deca700db2962d4dc28421843880e3821e535dd94ea72662c4f3a5492e824d98c63e182c107a87941c7834c0af66c57ca1cdba550049c3bb3531d5d7bb07ee93bc84644ea60521f1511093b5b4d0b5a19518f6f48f377050b57a5919aaf958fd33b071109ed65741bff06f920401d5ab4d3e36c59d29bbf2f29d]\n[e = 010001]\n[keysize = 3072]\n[n = 00a9bd730ba3d04dc5f2f9ac15d00ef8bf6462ffd41000aa326e9b501f0a90bb299ea7f0bddcc46ff03cfa0d23fd45598a578be2434aa1738fa40ca05b8b2da67df4fc353facb7a0f7c4ab11a16780975641eb764c83f15c63e01807b7193b3c724220d21a2c2c83594c61dbd07474a8ce5b518ca7635d9c0e04b91eb2e84e0eadc7c790d5ee3129eb6f793d7b9bf4d52daf0313f841ea6688bf10891ef87aad500ea53b94662dbd4b7110103608bb31cde255ab82f852667bff55dd273114e5c1b2471f86fd41425067eafec25f8fdbbdb08490def14bb2d847b2eecc51cc4ef94e5a9f415d59ea8549b232cd8b6bb621d655989864d85de41d542f16eec86bc5f5d5465aa2e3eba1d1b82ddde61dddac0b62d660101032ba3f8fdd69a31c1ea2fa1966784802d3dbd848c479c93e12bec95a7ff15ea6bee5fbbea15ac31cc9e3e8196b8946aa322abfa29b044cdc5008313883885843728e9cd9a7cf1679fe374b06e1cf5ecfc51af75193797258c51309d96e7a71113ec0896b9261cd6cd2bd]\n[privateKeyPkcs8 = 308206fc020100300d06092a864886f70d0101010500048206e6308206e20201000282018100a9bd730ba3d04dc5f2f9ac15d00ef8bf6462ffd41000aa326e9b501f0a90bb299ea7f0bddcc46ff03cfa0d23fd45598a578be2434aa1738fa40ca05b8b2da67df4fc353facb7a0f7c4ab11a16780975641eb764c83f15c63e01807b7193b3c724220d21a2c2c83594c61dbd07474a8ce5b518ca7635d9c0e04b91eb2e84e0eadc7c790d5ee3129eb6f793d7b9bf4d52daf0313f841ea6688bf10891ef87aad500ea53b94662dbd4b7110103608bb31cde255ab82f852667bff55dd273114e5c1b2471f86fd41425067eafec25f8fdbbdb08490def14bb2d847b2eecc51cc4ef94e5a9f415d59ea8549b232cd8b6bb621d655989864d85de41d542f16eec86bc5f5d5465aa2e3eba1d1b82ddde61dddac0b62d660101032ba3f8fdd69a31c1ea2fa1966784802d3dbd848c479c93e12bec95a7ff15ea6bee5fbbea15ac31cc9e3e8196b8946aa322abfa29b044cdc5008313883885843728e9cd9a7cf1679fe374b06e1cf5ecfc51af75193797258c51309d96e7a71113ec0896b9261cd6cd2bd02030100010282018076557e33fa3349551c2c557d2b7c948c11b736f52766df40a37da1a0d263ce2798d529efa34e4b5fa79307c0345cb9acc995dadae0d7a7d1d7237a53f7b68ea0b73f70fc003450830b57dbc5b37ba185e01500771d7111e10b2495945f81bd854676cd22b3f3206b0be61931bd4e6b34d9d30384dab033104ed8a3ff4416cf02f60939fefabcc9a5ba2442e9bef333ff52488a0e841d9ef7ec83e1a476c447b94d4c8239d5f64346a9fef1de49bdff5db251d96d4823621146141d46aa601040139009c37c551455567562831847b6c43636aac85abd279b24390806cb9b555b05e0d26a2457801ad8f5724452695be0147c36e9a0cc332d2adf77628aa43253e4ef5f337484deca700db2962d4dc28421843880e3821e535dd94ea72662c4f3a5492e824d98c63e182c107a87941c7834c0af66c57ca1cdba550049c3bb3531d5d7bb07ee93bc84644ea60521f1511093b5b4d0b5a19518f6f48f377050b57a5919aaf958fd33b071109ed65741bff06f920401d5ab4d3e36c59d29bbf2f29d0281c100d42b178b5a12579410b0b3c5bdf6a93f15bdab87be1d964aec425ea611ec88b6f3bf924def484e9dcb2abd1fab2b2c3cee7f1ab3079d2d4bd7b48afafa6b2c903e112a7fe1dc997554054b3077e585d63ecc4ae058436adc56f417bdbaa3f346786aee58a26bd6c5e1d7e3965bfc0c7ce5e5d71ec1470d2a9358cfe7a3d06cefac24b0bcf692a8bfbdf38073f690535650f5620a6cc664d24b23134396397b79d2eeec9b97a290c282d3385767a96cfcb900c8220e76bd8dd717374085a019030281c100ccce75c5d321a523245787b19880044387fefb9fc06465e524539f265e85b8be15fad29e03173fb29e113d16d5c53f171fc9ebfb1df64428a59148d2ce5217607c1d2cc6dec49d46a88a10340e8c2a9e66b198b8babc64811d5e7cfdbc4b8710a0c908e081424549be828929b634e845fe8c1b89baf1d80867a32120884fcdc71e2aaec0d9e29d6fe907b706a700585f92c7eebb2755640dcc961361ddf239b1336088cb1cc2c6811e3d3703ff5522127f4b1f9bbde92f137cbca148d227393f0281c0789388cce4427a4d267315a7b27ec4ce9a4f7175328164116e5585aec18ef85f69051d63773253a36f7bf9814ee8b93a639c0e9362275c3fb6f5deea2578d519a07c66f7c867733aefa61686140d77d33b5b24ce7cbacbb72f1f878286d878003b9d219973acefa103e98a68c01bed08ea2a85e7ef95ae90dcae63715472b6063b819a83b969bdc7426f6937fe0f259d6f6314f5b1bdca3c8d010108af0e39f3110241ab6730b72e23e56026a43df0376bf85ac4a80da94a3bcbf0d5955b57fb0281c057e12b45e44f66858abd883b1b3dab16b30f25372a1daa5f455420511d73f18e96edd65bf8e58bee7fc6d3d8ad878287d09b1b07d896682eacc48763f525e264033d9d8e03de87c1dee5c7081f49e3abae52fc3e1fda60a1ca5155fea6421e4573486fe7ad6f1b3e06620aaafc44fd79b33cb94043182ce3865cc80526985faad5f5e8a0559dd88241928ee56ad94a1250703baed0b4e246cd8783ef9585af5daab6fc5b730edc9060c2518e048caa1f17c1cb614f7ef4353f6bcd24eb0feb8f0281c05a753898792e9799b9a6e5b244bc184c0cd8a06180b1bc3628fcdefe815675744c53e1c1881df87c00e0b104739754dcae0ee9bb9e7634c6d0e4530eb84836dc108bb38708935677fbd517902d757d0f5407ac78b9c939757a8c471c14222024591bf16784825190ae6e802258921a715d9a18a46994cb83ee87f5ddc13c69edbed56a8030f9f2d79292902727696d07013b12fdcdc5ae905be88a18fe318be5215fcc72ff82ceccfa6ebd9564ee779660cd31fe5f5e61b8f92bad3a8f7f26a4]\n\n# tcId = 64\n# edge case for montgomery reduction with special primes\nct = a9bd730ba3d04dc5f2f9ac15d00ef8bf6462ffd41000aa326e9b501f0a90bb299ea7f0bddcc46ff03cfa0d23fd45598a578be2434aa1738fa40ca05b8b2da67df4fc353facb7a0f7c4ab11a16780975641eb764c83f15c63e01807b7193b3c724220d21a2c2c83594c61dbd07474a8ce5b518ca7635d9c0e04b91eb2e84e0eadc7c790d5ee3129eb6f793d7b9bf4d52daf0313f841ea6688bf10891ef87aad500ea53b94662dbd4b7110103608bb31cde255ab82f852667bff55dd273114e5c1b1471f86fd41425067eafec25f8fdbbdb08490def14bb2d847b2eecc51cc4ef94e5a9f415d59ea8549b232cd8b6bb621d655989864d85de41d542f16eec86bc5f5d5465aa2e3eba1d1b82ddde61dddac0b62d660101032ba3f8fdd69a31c1ea2fa1966784802d3dbd848c479c93e12bec95a7ff15ea6bee5fbbea15ac31cc9e3e8196b8946aa322abfa29b044cdc5008313883885843728e9cd9a7cf1679fe374b06e1cf5ecfc51af75193797258c51309d96e7a71113ec0896b9261cd6cd2be\nmsg = 63461cd56eba70d756be706bd754d8e26d16629a685e3d6159e5e8684752574d6fe36a66755e327905f327c75de1158c34a22a99ce4306675bd876997225d3f508a2300a5029e7860d8eee842e28a4f3709dff9dd84365127e6d7b9d8d59d095894aaebc737dfebc5cdec19318b26245f2b77dd1c507cbc53dedc14f4a881fa4b41d3fb2b3b7569b36bb11bd79b562d464815ae4fd2742f03d78c50cfb22a2e56fa5754793390fba75ab1d068deead4156abd95566c051c3692f8e53bc4fd4e5a605b4adb29a78cda0170dd0b83546c951929adcc42bb4a2ac25439a55f0d193683aa521319eda1d6e0fc61ab084aa52909fdc220bffd22f2c691c579248b1928b08f791a3b64e81f587e58baa7a68e5c0b2ebbbb95418e3b2e0f210d53c33abca5076ebd4e0f5f7fd8117c3ba5404ddcea670da37c868e81a23e1d0f85f878917ef825d5a6bb5d257589ecb77c87a2cfdd6df915d343c38cef865ad4d0126c86a668cd64d6561c374c08680\nresult = valid\n\n[d = 33136923b595040cca19c000d9e6a1e3216b18c9e46f18b5b1e67f4e52a748127a9159484d5fd58d5ee237d363810c02db71937477e79085213e3575033cb57e2cd9a87c4a04f852d6b486580d410e57426d7529a16050cd30b280ddfe7f7ff35dc57caaf74152195da8d3b32fdee1cf1d4cfa2f615415f7ddcabf94a53e7af181b968041650665b517b45dc98556596e7116e247485b450e8937dbfcea703deb93be440bdc88ea6fb131ce97b7cc27e22720ec34222563ea0ff369f3ee4ca6113a2e77442cb9a7e616fa335b90380bcd954d71b62c201f1b3af478f814f08d2c78c982f9cacf8c9f63a06132b8164b69bee8b987094db722d99022efbe67853a0a6006a66a0e2d16b2d78d8c7eb1a568b647c5bfd81cb9da9afa3dab576a2b1569729aa492cc73214f473d4dd78a186d77b39a1f2ac5dd8b8b1f9c3aa662245774af9e2d135c7c267d4d4ca4d0d3173631fe19016e01dca4682de5d5c6849835487521c28a559a5faa8aeae2269cdf5d722c26fadcf3f759c4fbc23156990a1]\n[e = 010001]\n[keysize = 3072]\n[n = 00cd558670bb52e8c170723ac5b4edbfc4c1509816d2212f17808d7a17b637e281402984987e01fe42970fe736ab5d4d9b0c79b78b57f8d8883591fdda2242c87c68c5927b78370feba2050aa7f59717f7f8c9a0b23e87e6d5c7e6e618cd3cefdecc593c16cce7ae42039d671c2a5e8fe053dbcf9362e4920aed0a", "2a840c7c80444a2aada474069b25a79919882f44877ecd181bbb12582448f1066984633a6cf28b2cc751e917d84b475bcd91c45c8e822a874221ff254949c379d28f9e12ad06f28f0dfad56de8dded0a10888c5d18c163b7a9e826408dd8a27859e33874dc409fcac674eb8b5da86afebdaed4e83456df003b41f0a145f5cbc2b95455807080e2fcd049a6a49ee421b8e146fb9fc31f43bc7591ec25a970aef4752af01175b9370c20b49ce1bdac45ade8ae27f27e62f7716cbd5d49e7cbdf1e6952bb2403a01fc1d8b147dba49584931d7e0066544223a614d157beacd2f1bf36b4ad926c3073d9ba13a55df83a99017c500585320efdaedbd3ca91c227eb1f92753e3bed23]\n[privateKeyPkcs8 = 308206ff020100300d06092a864886f70d0101010500048206e9308206e50201000282018100cd558670bb52e8c170723ac5b4edbfc4c1509816d2212f17808d7a17b637e281402984987e01fe42970fe736ab5d4d9b0c79b78b57f8d8883591fdda2242c87c68c5927b78370feba2050aa7f59717f7f8c9a0b23e87e6d5c7e6e618cd3cefdecc593c16cce7ae42039d671c2a5e8fe053dbcf9362e4920aed0a2a840c7c80444a2aada474069b25a79919882f44877ecd181bbb12582448f1066984633a6cf28b2cc751e917d84b475bcd91c45c8e822a874221ff254949c379d28f9e12ad06f28f0dfad56de8dded0a10888c5d18c163b7a9e826408dd8a27859e33874dc409fcac674eb8b5da86afebdaed4e83456df003b41f0a145f5cbc2b95455807080e2fcd049a6a49ee421b8e146fb9fc31f43bc7591ec25a970aef4752af01175b9370c20b49ce1bdac45ade8ae27f27e62f7716cbd5d49e7cbdf1e6952bb2403a01fc1d8b147dba49584931d7e0066544223a614d157beacd2f1bf36b4ad926c3073d9ba13a55df83a99017c500585320efdaedbd3ca91c227eb1f92753e3bed2302030100010282018033136923b595040cca19c000d9e6a1e3216b18c9e46f18b5b1e67f4e52a748127a9159484d5fd58d5ee237d363810c02db71937477e79085213e3575033cb57e2cd9a87c4a04f852d6b486580d410e57426d7529a16050cd30b280ddfe7f7ff35dc57caaf74152195da8d3b32fdee1cf1d4cfa2f615415f7ddcabf94a53e7af181b968041650665b517b45dc98556596e7116e247485b450e8937dbfcea703deb93be440bdc88ea6fb131ce97b7cc27e22720ec34222563ea0ff369f3ee4ca6113a2e77442cb9a7e616fa335b90380bcd954d71b62c201f1b3af478f814f08d2c78c982f9cacf8c9f63a06132b8164b69bee8b987094db722d99022efbe67853a0a6006a66a0e2d16b2d78d8c7eb1a568b647c5bfd81cb9da9afa3dab576a2b1569729aa492cc73214f473d4dd78a186d77b39a1f2ac5dd8b8b1f9c3aa662245774af9e2d135c7c267d4d4ca4d0d3173631fe19016e01dca4682de5d5c6849835487521c28a559a5faa8aeae2269cdf5d722c26fadcf3f759c4fbc23156990a10281c100f793a0a9963aabba0dcd9a4f18a08e62f6b194dc64022af47c6d473f2a0d38ef862fd20f361a96c334f9457861bc8c09ffde66c5e29565a57b864911920113b5f0d269968e6177ddd89da7d77263dd9cc99108f3a7063b58216850eb84446971a6d3726aa91f4727f99302ce5ba63295c559b3c94f8c93efb8443f7e97b4ac489854e9062d199d17ee00910b3213639759dd9a5e1b8bd1b6d9a306b33fd6326268be6ad24ea0927454fcdb091541fe3c90f6f2a9534339b6f83da27c86fd30fb0281c100d451f7d6105fc90f350a536765b5aa8e42083e0f67747d67478a105e012c870da1abcb07e1c73fd46c7343ae5e7eea192a4d865c044a300a526271d4ce475c21b56e1123dc9185a64e261f4d09f94f2b43814397cd5edade156d06378c717e59d27b92f928e245ca6d5b5d53936d72489c2f62d0ff99f475913fb21424c9e0a911a441d534506200d0579e755a38346740f41794ad4aef4c64c9db039d72c400a3c44d38d0cbbefb3eab213fa287da49206bc14da3634dfa9c2d76f260ed8bf90281c100beb436c3aaf6d2a4e4510595fbd0611d960d402f6bd1c7a8bfd7a553e05e8306ee0413f8a7a25f934a50e0d453e4dab23127ed5e6ca4cbc1669f0fd5baf39d6d3e6db5ebc50d0b3a15cb8b2807f32917c6a433930b8b5f570994c31047b832c8daca718dfb6c1e718a6b55740360c8025a1c38c2cec5e88675180d18c45ee57e9de879fec9eabaf95dd98de063d84f949c2278f018a3e10cca242bdb13473954587ea4e60eaedd6142bdeb32d9ef15992dc92b2e86f677949b2f4ee4414ef2d50281c100ab451bc900186455f2114c4a420f936f81f0a82f40e3052dc4d5a8724c3c210d6bf6eaa687087582e3a0ef5dbf385d9ac3371a452be8b46bff1d0e79fd942ecbba50f95e9654851d2c393052b2d2fb7c08ce433a371e672b72d92984b1b3f39a7d61d5a34bc98b46c98443fa61188e71e81b8978d256dc8de207219d82379f1482f89f6a5ef2e0bb8b54c2ac2384e730cb829b6b01874b15b2cfe9ee369a1765f4b52b1dc3c03764f09e970980105a9356a5d59ecd4813e52f0ab5c2bb51a3f10281c100ca356699c6f5b223bdaa954d5a6b95c4d0b0b90d679f302e3f3d6a2e6fdb5b8c2d34a2362b72fef0cff0c7e08bb63b88d82bdf424384975477943e464a6282a3c301b8da1e77fcd5a4f28d2906886876c3094224d6b0f482fa388585c0b859d79b0d76badf107072971cbfc6057890c50c5de1e7582d45dbee868fedb52b4de3b2779650ffc977663dc7fcbf0da60eff97bdb3257d0739b22738a68e31a819f090a96d3a79e9ebfedd99b677e93bccfd4112e4f40843324703eeae57b3f5089d]\n\n# tcId = 65\n# edge case for montgomery reduction with special primes\nct = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nmsg = 2d6385fce580f795102dff20c7917588dfe5304746e5635dccc732d3a58def00efc60fe4af7805f09bfca49aad1ca464b6658daa7f133c12718ac8a6f60702eeb031d49ae35b99ec56d0c7a0a33108ca98b55ed68d27c4c81c38c02e82bb90060c5c2fd9d411dff55509b1e97908d152a4b3c93528013cef644dd70c3e99b647b403e49d0175c818de9f1289eb312cc44ed3a408b4f7f6ea03e44f9f1dc07ddfe02f2729feeb2174c032be05e9eb9243697264016cb0deb113266c3b\nresult = valid\n\n", }; -static const size_t kLen156 = 319528; +static const size_t kLen210 = 319528; -static const char *kData156[] = { +static const char *kData210[] = { "# Imported from Wycheproof's rsa_pkcs1_4096_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSAES-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[d = 00d3519bd86edf5dbe9c64a3781713dd049b747f5651fd918cce8a9b80b6d6a2fb6aab334ab569a89b58982e0aae373090299fa227f9652b802d23ee5ca6824c433d01d40bb0473b16190a8bfb137c0a704b4f49b45015bfbee1f670446f07595259d70c7d79ae95f9b2543b0162ebb763ebb81c4b6edff9d197dede1dbe57e40466d156d4dfd5d7634c45534fb2bbbd1bf257817a173c0795fdbcc533976f4a0d04160f299af5dc272a814b36d5bae5116b9542178f1d554cab7a6453035482b981add4bd8ffd5d500839b23e30ebd3f3868f07584cbd12ba089325982860f69f2bdc7077b6c60f58a2272823379e1023704165f7c14f64a18fd5b245a18149b7eda3385a56ba9e79502a27bf13865cde35be15de03d06aa6f08b172b7eeb4b73cbc157019c5d933584a8d1add61b7dbca3b253ca0cf93dc9a8a3aac2f50227022e692f7b4767556620cc928d63e31078c360e2ab4b71a917e19e7eb09380482e5b4ea88202871c2a29ca6f66b2fe304af609520e4f81d64c26768bb812a86679366611f4cf6e89e2bd1d9d7e28729c7f0e4e3152d7ad7f186fa32f01e169ff06a12001bc179dfd0dc942cbabc555f67f5fd043e0a3354340fa490d2f123367be926eb3e1dffe70c3151c87450f3217dc2aa0b5a7069c5a17d55614c9994139f7b37b49e9fe780af65a0e89e2e58feaaffe163bc9d19eafd9cd29b0ef3cef3d01]\n[e = 010001]\n[keysize = 4096]\n[n = 00f601be0dccd04aa40b12f3f191ae17c1f9c8c0b68e7a77e14be25c3c7907cb1d33a6ef418ef41852f32c98392bc5c9aed91c1a1501c503eab89b3ee6f4f8eb2e0fcfc41bd03609cf6a8eb3aa6f0fbe23187b33db4d34b66d128a8aba0a2abf40bb9d13d8e2554569a57ab1d8c61b8cad2dc88599ae0da5346e15dace1bac7bf69737c22f083be9b46bb8b1eab5957b2da740275e96c87195b96fe11452159dafcfd916cee5d749a77bc3905a5ebd387ae445e8fe70f16e9a086639779ceffbfd41557bd99aea6a371a6b4b160615a1a12bc6958d34bce0c85adcbd8392fa10ceca52209d56196ba3d273ce228f1f111192aa92de2a039798a17bcecb4dc6100e6f8ae8c2643f2ae768b2255f082c978e95ca551555f10608231cf8003bbf807969fff1e51914b9a8c9b8f4564645b9e5d705ffad29663f5dae3d76652b422e43f13e6c1491090805c2d1268a74a251177427e33a9a91175c3670b91746008bce1fd231e6e4f2ad70cb43aca5f07600a6d31dd02915243dfdd943a02165da367a6b7e4dae1dd2e8b836903080795d2585076cc1c15dd9e8d2e5e047526569b1bfd395d957eb9fde325d342d14426e71efdc1887515e53cdea5834921f928629e748eed097ac4024e2bf255d70411f87373948cf8e8aa7effa2b0ab47d5166091e1aedec60568b155bd9c27bc55f3ece35f83d636dbcd5abf4853a051db94d5045]\n[privateKeyPkcs8 = 30820944020100300d06092a864886f70d01010105000482092e3082092a0201000282020100f601be0dccd04aa40b12f3f191ae17c1f9c8c0b68e7a77e14be25c3c7907cb1d33a6ef418ef41852f32c98392bc5c9aed91c1a1501c503eab89b3ee6f4f8eb2e0fcfc41bd03609cf6a8eb3aa6f0fbe23187b33db4d34b66d128a8aba0a2abf40bb9d13d8e2554569a57ab1d8c61b8cad2dc88599ae0da5346e15dace1bac7bf69737c22f083be9b46bb8b1eab5957b2da740275e96c87195b96fe11452159dafcfd916cee5d749a77bc3905a5ebd387ae445e8fe70f16e9a086639779ceffbfd41557bd99aea6a371a6b4b160615a1a12bc6958d34bce0c85adcbd8392fa10ceca52209d56196ba3d273ce228f1f111192aa92de2a039798a17bcecb4dc6100e6f8ae8c2643f2ae768b2255f082c978e95ca551555f10608231cf8003bbf807969fff1e51914b9a8c9b8f4564645b9e5d705ffad29663f5dae3d76652b422e43f13e6c1491090805c2d1268a74a251177427e33a9a91175c3670b91746008bce1fd231e6e4f2ad70cb43aca5f07600a6d31dd02915243dfdd943a02165da367a6b7e4dae1dd2e8b836903080795d2585076cc1c15dd9e8d2e5e047526569b1bfd395d957eb9fde325d342d14426e71efdc1887515e53cdea5834921f928629e748eed097ac4024e2bf255d70411f87373948cf8e8aa7effa2b0ab47d5166091e1aedec60568b155bd9c27bc55f3ece35f83d636dbcd5abf4853a051db94d504502030100010282020100d3519bd86edf5dbe9c64a3781713dd049b747f5651fd918cce8a9b80b6d6a2fb6aab334ab569a89b58982e0aae373090299fa227f9652b802d23ee5ca6824c433d01d40bb0473b16190a8bfb137c0a704b4f49b45015bfbee1f670446f07595259d70c7d79ae95f9b2543b0162ebb763ebb81c4b6edff9d197dede1dbe57e40466d156d4dfd5d7634c45534fb2bbbd1bf257817a173c0795fdbcc533976f4a0d04160f299af5dc272a814b36d5bae5116b9542178f1d554cab7a6453035482b981add4bd8ffd5d500839b23e30ebd3f3868f07584cbd12ba089325982860f69f2bdc7077b6c60f58a2272823379e1023704165f7c14f64a18fd5b245a18149b7eda3385a56ba9e79502a27bf13865cde35be15de03d06aa6f08b172b7eeb4b73cbc157019c5d933584a8d1add61b7dbca3b253ca0cf93dc9a8a3aac2f50227022e692f7b4767556620cc928d63e31078c360e2ab4b71a917e19e7eb09380482e5b4ea88202871c2a29ca6f66b2fe304af609520e4f81d64c26768bb812a86679366611f4cf6e89e2bd1d9d7e28729c7f0e4e3152d7ad7f186fa32f01e169ff06a12001bc179dfd0dc942cbabc555f67f5fd043e0a3354340fa490d2f123367be926eb3e1dffe70c3151c87450f3217dc2aa0b5a7069c5a17d55614c9994139f7b37b49e9fe780af65a0e89e2e58feaaffe163bc9d19eafd9cd29b0ef3cef3d010282010100fc21b855c5ad4ca2b6970516406f71c6e79efc4126e6598772db1e082de6b0dddaaa2a2951f04148e86e0bde28213b7f600f987308301eacea134062bb0c3ddf628da9abf93ef1ce3e75b0953a484dbd3554bd5c0649933dd77e527563e90f05a8013fddac958c329378e94303b304be5f9df1fe5b043a7fdd94700a3f0b1cbbd0516b7cd94c57ca96d9fd2a8ca973991218cba33a1c23d810f7519d1f7702ab72affdb3f84a1b2a88116e4033bc4d0cfc7989c657e0fe94e964476ae58bae6b7876f36c09d32b1a63f8c47c94a74c92eedf75fc27cffe0f8452363e4bc8f7653f3cb55eaf693cec70d13c875de935a8b20439ab7e93f76981c5957fc5bb44d90282010100f9c7f748a505d23ecef9a85f8097c8cf7d7028ef6c90e22a336511582d2cc3636e34ead37204dbd22f142a3fb1d5f857b0310c7a433f51ae14d4608b01b43aa8c7ae67835f7fbe0b9d97948b39e9ba2d3a1687edb8b56ee70ff0536dab4d0551f71ed0daee9e412449f5f099bcc15e4ef0554dc79f87fec5a0dea717c7054392bf444613937401bbef3c22fbf7e738c58779b981609a1f9c11dd6f0bbe9996e2773459e4cef247b02a9fc21296ac57a5b10561824310cfbdecc90e06598370e3698713fdbe2528ec4ef3dccaae701eedc3e54ad6e7af4e68e3b39bd2e97ac9119936c647a503511cb283df984cfd7c07f0f56aa8ae3166948ef3f41b0859934d0282010100815486aab0a0896bf97f13e3eb1f7f5c49195b49cc3b6277412a3688798b18f46422df479cb941b3b54e25964a3d69b897bcc8355160e58b4af29f1745dd2cabb670f634b9c058e6b3514947f2c27de5ed424f73b1e1f1be4a188911a0333f3a6688658b3ee8e3265a512e4deacadc470ee304ebb5224123afb461984fe8524fe0b6b30d32a59f6ed2dc74a96bc7cbfd1bb44e58a7092235c5d6272e12a2c862cb8c8cf5d109aa4fb1c6472875a14460c1ed5207c4b22bc494c7947eb7ca63a8cafd31361d000ddf16a2d79f13dd9140d979149b488cbf44945a5b6aaf13221bf4491ebbb7fca27ca20e221f49c3c37b89fcf2dc0e2cb63f8f8a9b7a142250590282010100b61d84ff934a4e437b16ee1b4b9fdf4ae13370b5385bde7a5464a123c0343df575f9e128ef9df944230d39cc9cf5dc0edb28b7e740b69ef024c1bfee39fcd5340ffaea0010160c535dc0920e7cd81be533d00fa554a1fc4d3e02c461569f5e7ca787f1515edf45b196b759884de652c38d5934cf92524e807b4d3b590bc39bc417ee4885a761d28ddadce6c8fdb3b961d3e7fd48064df9340a967f8b79997438841f48579a476ddb55088c308f68f2b29d01c6597a5a7c8d066284f63e37a68c3879c32aa3836675fd0eb2719883a91944561e9dd7e8aa6bb17157f08c48f8e6fae5c3e5a2bb6b5d580eec6c97ddcd9be0a49ef283a7031ad7aba8d438df4e950282010022fb8e5fcd9b767104e71244db53058c18061e1b0d1f63b73e2d59a95e2a10cd87426a33da13c287cdef8136e5e47e93fb9b30ad92628a7b543f48eb011a86356ab3cb480f27e391b018ca187d97af3d82e31861ecafa663db78aa89c3bd468e6aadefb3a43f78bc00b8014c95db54e9d21a017e8f21f671545edde9a965ea32dfff45cda37fca1aa5132f6c8eed222bd01fed5a6e7d639580c5955777a86544c2c4c939bdb8b4c486dda53072861a0334359bdb3758475e49d90d0539944e78cfcfd8fff55bb31a1cebc65b28f51e790701b2f7912188984f034e6e96e1c5251e33fe38fb221bce7a90a86857c5f56b6ca77307c45d5290b1f088ade082b349]\n\n# tcId = 1\nct = 591be9c4c087764d1c3f38b2948c896bdca19616e70ce1ea20c3c1361d51635345bb8db8f559be2a08dfa6c8e0a717e9c6974762b73927213682e730cd4697d377f8c36ceab1b52fa4e67f7f230a1e3a551a51b6e355f3d40042d3508a0898b061bda6b6cfd1a13753f3379a1ba33f9e303317cdf768ddb009d84a357231d04aa159d88756f8037bf1da996720dc0360998f2055c1fa37473047bcad28b5c4ff5540769d6f23815cc0078821c1976249926310f0fa4013e1dd0bc7294f4e50eaaa2f5ae3cf936dea032b42e5889d0f7fb8f139ecede958ff2756be876fea0b426c902682523fda747ef8aee0b72e0a76659a689b989685de912a10cd2c7e095b147294e8cdfc9e272a7dcda458c61a6f94cbd1d54d9cec61f95d7b4698761a3930715b53715ec6183cec159f4b1e532073b7cbb9224e5c0d5f8e36041d5be8f8de2203c66cdef24a278027e5a2212bb5ada33520b304f186b5973b00c5d2ad7d73e404ca1e930828f08c85b62001f589a73ef0d1e8c2367ab6f1a3bc29d9645597cf7c0a85bbf5bcee4c12fc89af545922132759f83fddb369b55fe68f2c93a7d2459b04f52bfc2fc9ec237c14f651b41e9fe813205c345d1c36a838785a2465619fa0d4370088cf2b4083c972b17e4e0e207e142a765529b325ac91e16eaabed7d010e1735525d166cd310caab5b27e56bff36c478868233a38228e0177cec9\nmsg = \nresult = valid\n\n# tcId = 2\nct = ae1edfea692eca58775d3c35999e5738886a47884814994b29dcc9", "7b99e79d9f35ac1de680ca6ac6638fe73771ade65e74d13f8de01ee5cdf5c4c4ed2b86261218ec529437606353a80fe45be9fc7f9f27850a70653ad31f490c1075429ad5263c46992a1265871a5ecfc7390c86d72ead118028a3fb3b9fc81ad055c137e34c6d56769cc8cc6e9edaa31958d0b2ac87751870f8c955ed2a0999d5638c8a42864174a0c8045a6fa810b6e0204f15800dfea5688d98156b1589d4c51032c7761bb02fb90fc15643db17f398b30f79906c739dc10751011032bc75828322de3d1e98de6f1bf644619e91cdd875f18b08c5876a485d8d46e5cde5435e26eadcac8dc48ead9f9fb747220fcdb09d2dfb1d1197b591b1aa3003c61dd880fc4e0b7da59146e04eb0d12715f6f44704bf0a9a0fd77bc7b74d3b61157ff5b0221c782fc886b9cfdefcaa2cd737178c683c84055beeccdd1d402d538e0b72485f3be93d8041a145ab0d42855706d61056a1d49a656cd67486682349ed0a6f8ff52ff05ef800a969b978f93d441f896302029ce5e8e800f3b5c2bb9c92c93cda18145fcaeb8f8942787074b02b434b4e52b6ddd918c4ad0ea22575fda6b108b6e0b8c7f681767c553f5b6b2ab56bc657f7017d1deff8f1f55906767bd039038373416eb1198e0195112df8c87c52840e32e4d616963b2e9cc7524c21487d7e81696125ca63\nmsg = 0000000000000000000000000000000000000000\nresult = valid\n\n# tcId = 3\nct = 04327a40b02bf671557124f963a57b3860e92cff62c439c0425b48b4346fc60c0ebf7a7584f94d34450d20cbd877c8d5dca12f517b486c2cccb8e1f467276ac03aadc94a97fcd224994d81672eb577cf0bbd6aa948d3dc4d7f06456f6650e5620435c078787db0f36124b292349ebe011ce54b3e932fac6525a37c793846a4f08ac3694d649f4a04e24e1f5e50f11a0492a68a509cf30e565ceb9931565b4aa5c3514b2ba87c4c0937ebcd6bb2b8248abb0970d30480059daea4c6ae556f6e91b25ffa5a4f723a9bf98a0bff668a1f0c799d3b0c85b19190dbfb5d894f84fa5d72d261dd2c09013dc0981cd0c46d7a08710801590aac8ff17b237387427ab3c6d6f2a59434b37f123bc7fc0a83d5ca5793540cba582e41b262859d36eabd0aa8203ca05d4c16aaf2a7b2bc7f251497d4c8f8654deae3cfffc5d3599ab4779585bf1673196782075a91ee7c3296a2edc6ee6c30344dd0c0a82274ae17982eeb23eca5c39c7d11a2dd171c70108b0a33164fc175425586f714deb5552e90e561f7882211d3f01c07867256d0cca511e61b0cb51189d8e5124e8cacdab6042bd421447ffa7fe6cad8e7f17dd3e599bae061f85bb5181726d1c0c5bbf2c2a5c1e60f486a81782e58d90ccd5a769f98361765441de142bb0a7f7bd406a537d5be0c2773e847b1df1d49ac1daa963feec84954b72a695b74281159647a62a3c19acdda\nmsg = 54657374\nresult = valid\n\n# tcId = 4\nct = c550c1db08ba647b812973ac38784a62e707840367a725e60489a0995a789463d05a3a6ef7cf06a8fa7304cf28e8b11d1b684ba87e3be712b2c086e2acc7c8d46ea84175bee9e4d25c4a24967296374811d4afc6675223e624b7f2c59f8a02a875b1ca75de2f5fde43b85b7aefcda3beae7cfde9ea0215c48d65a8b4014aca446b780c785a49fdc8481e3c342c82a66d1103bc48a4bef5702e6b9157ed367e20605d4645084950abf36ee49d76d25bc2639130e01fd9592ef399aa670c3cc549787466bf7fb5fa5be203cf86759419812af003850ffd3bf9c7170919ca68c224cd4fe9a3566bdc17793a69688313d71aded8b64e3be8c47f81103ab35ad6090d98d7d00952aabd1c67ece3e2ee12717f4fc1e849ce2b8130ac5873ccfb99cf683756641d11747276cbee0a9e75a7851012517bd4c197cc843c9f26c6f2f357323918600db96dd4388202afe276edcb9b73b2d7d43126c3a92f7354dba6e67a1bda30612897392116d33e53005e4eea4dda087e5eee5a30739076c1ba838670f0315ceb7cdc9b7aaf5aadb049345c81fcd972431f80ae8722a3f4a58b68c42f3206f8cf434205700a27742cfe25a0786e5f0bf4dbf9b150a52807be2db31b3258b87f3f5e617fb3b1839d4353951e7f556ad3689f0d9418e4311d99b790f39ae05cb28fdba711d33e28bfe87421fef67d98038873a6bc8a103ed14dfa87249332\nmsg = 313233343030\nresult = valid\n\n# tcId = 5\nct = 06c23a6999c870c68707f2c2d85c11c35fb77ef6cd263393a1a6a8363298f4b8937a8d176fc268a9a1d4f3bea51623f7ff7c76c4e4c8b12408471a460d9d1f226e41d17da80b03efd27ba00bcb7067dd9e02c26a3ae9f8b082f6cdcf1fcf76dd2ff774307b7810a4128eb2090880c967845ef02a6da6344749fcba456bacf43d915bd394eb9babdd19140287e44bdf1951eb4c058b489c7f3984dc5763f64b918f35393c4f6e86c457133a101b60cda0f9d0c93c90dcbae3345cdb894947d8bf1371694c0c21d009d4173bc849ea7d00f0d2c77e4683b403c32ded38f38afb61ef1348e889b3d8e0f787bf85b6b93ddee2c97805734d20006111b26ad1ede2d16d3f0238369d5008d255f1e1c518e68f82d0a09eee6ca803ebcf11b95cd20e195cd3f0d8221a78bad42820f2a5a7184b461a7002d06b003183aa66a313d91164a7d6d09aa567aff83e3cd512368893156337a741b388d1f18b10de386a28993117679deabd6b00d7f8c641d6f201ee8fe4b9934c9bdc48a70f21450c6f23b21e655f8818bad28f0755c856e3ee926b021f2c3d5336bf1752d6b54388b745b6e109d4c6885608a61ea8a5d511eb7836025cd1503bb3d25ac20819b7d9a1257a8d68b0bc51e7b085de69c267c0590fad3e003ca8018835b2c7cb32a25bdff2bea8111bc1656da3b8cf4ce3ce1a5b2c6838d9c276a6c1a4b58b07e17aad2c645736\nmsg = 4d657373616765\nresult = valid\n\n# tcId = 6\nct = 2d452fce3031f644f4a22e0d7b2df7296edb3aacefab84e7c57107021c61acbef498a914b9a70d3e33f97f66767eed7a14c16da88ec156e436245b5d9d7bd1023c997155e2e64d6801b535c3c861b19598807387c0ee366d024950b996cb206155493f0f320cbdf58f59c5911e10db3f8034b89a81878dee5a73dfde620ed224181364e7c7ea5812c874b252ededbe4c8644fdd3d312c7bb4785fff4b23a3ab00a2e5fdb3192404d8f1af8668d89e7b4aaf70634b98d98b2c244c336e57b3cf8411294f1a614f55b06a78e56eea98c6f59b2813643515a919f7be4ed59dabf69d68f43376964f0243ec6dd19a0a3609f8ce3e722ea3375a6b5f7ab24eafeabd58f81a2b3d2bd3aea2e6cfe396542961c1fa9d806037945ab866a0af6b2ff9f517d8beb5cf0c8679ec75324fd82c03e217572bdc12f374a445ce528b4ee5d8c93d3b8f254d372cabcec7ca69c4c539c0e1d02de02a0a337bdaa9910ef9402f449219b2e7376637dccdb01693e50196b7691cd8f6557e42afa7b9b7a7c925e6587613ccf007bbdf5457e67a2c2afcebd609ad8d04903cd2f748e1fd3eec0f7f812257da9d99207788e9770d12eee0240f9ae93ad9ac9b4fb63d4bf35f0c0a363bcf19eb0cf7085ead9244d4623a15deb7b9c02698d38ee78713fb67ce662ad0c76130b0b541a5120405b8683af5ec83bd8fedf72bb60491f829448cf76a73e534b\nmsg = 61\nresult = valid\n\n# tcId = 7\nct = 3ed60cd73681d506ccfea349e5fb086eab2b679ecb796532af888088cc84d8692c6326cca3745d20a94e710335e105d2b71f6834f7cd16a1a2193a3ed88aa01b31cc5a8734178f6d9256a9a660e967ee58ba4ad63cc33ec6a08aa1c324a88f55aa700b4d5eadf46cbf7a3c5304bf883b233d5a3a2f9ae8f858959c7f832e793b5dd68f196b83702d929857a39d74a4e386f7f6636f7c03b96ffeac87625088b07a1fbeeb44fc03cb312b8f3b4308846b0566208b516687c5a786ee443ab399ea598a2631d40a7ec8671e49b6f8be46a337d9fd80c56308857247cd714205d647fdcf8019608f20bbd7816f427eb4e4384f8c10c57fb0a7a3557bd80a6744b3ce3f53ed8e32b2e384665bd274b9fd747c646111ccea90eb809e690bba31d190c6a2e2a895fcc71f521fa9c0481645348b718aaafa968bc18cc20065f25924b8f0565d1e93875fc6ec0249e5be0b1bb9d8ae054dff2a368ff4b11a3724fb8c56033ebda05246024ee0be0126217b6988242a17430284d2e9b204b9296ae22740a2e847948c60085464d8158d9ba7db29f4594dbc85482304e466936689599505576e92c6441653c2744a37b5bca6fd88c3cbf990433bd3d2f9977e474b4d09f3d489e78700df6ad9dd2b8170652d7df55557d86055b803ffca1a8c3f214369bfad683f77a4e134fcc4dba92134117323893a83c5a76c081d7f8198c2040d3fc308\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\n\n# tcId = 8\n# Longest valid message size\nct = 3f1eeaa59c4b466f1cd4cc42345749746e18c80805c885df89ce608031692414ff9d7164d06a3cfcb16d20b439e65c44ec534016e9d9a173ca5652a707841e877c1bb3ee6e7440580e1edba79c7ce517bbc32f127fe0a5ea6d2715a1742adb5ab5538665620da3028cd1a50601942c0d255dad1c2b3fd7789318c0257c1ac140c0d3cb0766a7b51bedd5f1e1a65e533422158929824b7a8189f1c3aa0bc51586a82fa130bb465aa140def445a86b6d6331d6d98547d8da1a1c989b3d5e6b1f4b8278de9863cf8cfc30c776daad90dd4b9214295c9510d37a035c3c104c16d57b65ec0a816173ccb580e16b537948b3b21aa5fc56e78663b1b01c6623a977eb4aecde5d6aab6320be170f9cd5cbc6a520f32f23dd000116200faec4f04e7883abe9ccc482951384e7149cae39c6385ca17593a9cb2428fcb94eb6986b1a49b60f5fe43121423510d98bec37f700abe8adef9fd7e13321dcad201ae5a6033b59806f795bc0248e4c039e2f770635e1ceab3cfcee3f4c7ca68603b410cd9629d2391f38ec8576cee684aaf7e617d8da424c323124b28638b78e941933c7ebff9ab2d4a27069b83d82bdd694715be0a9145e30b9438d0e1b9fbae8ddf215f010ffff55926828d6a8f4c64c38370e5c3edc7385fef5acdbc4cbccb34352c8083b6a6d86246b940e7d19e98ee44c5b8d867d5b746061ba71d50c2d7ab4af66db6afcb1\nmsg = 78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878", "7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878\nresult = valid\n\n# tcId = 9\n# ps is all 0\nct = 556ea7b7b4ca2cee4cb4a386744b99cc7fea3ad359cac1f08fac0417e051ac35a704c051a14eb3031bfb25bed2c51e1967068b1927d595d40c6f9d5ee029db187993bffacd772075e9b16f8bfc0dbd5a18ff065cb6f99ed759d219f3e03baf53c6270c5ae1e66ecd4ca71e44bc8efa0292987c8caef2b464cf3a2fbadd12613ea60e0a5b5e0fd207388374d20f2be36e8332ba8b37e20b8f461b87afa253a34cd7eb3314de4c3a6427acb27429cb1536f3171224c84e05f81537a75e6ec28a82ac6fe21af38c26831a9e7cde61dc7f3e0992170284e99518a3048ce6c4d687a3ecbaa8ed0244371343bd935a05be103d255a2162c7b914b99731f8b2fe088994e6c616611b12cf5f5f6077e3d18bd435aaf0aaa53ed40c023b8d2d13fb190fdc2022049c6fe4b6eb66f0bf6a36e81c8a920c53bfa9c93b51f8b2659051e445c9b816c02e2072024227470f10da398e35679e114795053d2f96c3fb033cbdbb0b2e31447584c35abd60875ffcc1bfb24f892ef213f507b8eb63460df382c6c507c6ed17ebbe049501ba62f53b499ff31d2c04a242f7e16e312439baca228130c3874e36c84c5872ebe774e3dd25dbe6b5aff945cb0399f742d200be7057375538701c3d5101feee7b02159ded185eeeaaedb72ca1d4189ad165b290b6b3261b0cbf74a87e1796c1b128a7d8bde89e189917215cc013add1c07f8eb1de069ce048\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 10\n# ps is all 1\nct = 2e6309334d66e15e8cbe39a9cd2c3c6d8f19d49f017d87abb99dd4b32135968586766bea12529f6eb01da0a1902793ab8fb656e7df70b5de12548670583a75d68eb6bd36357fd326d07aa4f1c690af4a4b6189cc2de456d163eccee06ecedf4f41a0288eec24c2e3abfbae9ffa349d578594bef818268925dcb294ee9066355b061513defe161749a2469abf3ffaa28d537d55a71a7910e4b29836298f9ea464bd327d33d33967029b1731c742cfb8d4a6fde07bf28789e2a2590d084f7330b52c9ed8870922dec327237b1ee9178dc611bff14380b330ef94e677a40c81c61368b1eeef2ca753b90861bb4421f7da836516378eaad2ab7f80e2642b84f66fb0acd62807f9673b8d975db172958d54528c915116257a5ee2fce3160253190511bcecd7262435fed8ad1a11ddc8bf0ece11333b01a3087f40beb1c4d112c2eeaa46f3c7cc843526ac0abf0104c94c8be9e54ec285ad5703ef1514fd210cfdaa6b2cd2e9d39bacfc338739ada8982b5b6af683ec8c2bc902bc9bc4c9d5ca6199fed502481d86f2a6f9dd23f3f8eeda71cbaf90b51a50f5c6280aec08469fb45447ab4878cfca86ef78daa0b618b9af3c16fc9e4402520b7fb3abbf3086a2ecefe84a10406b879e410fd46c518760059e37f56befef10590593cb4707a0605c056051956fcb9d95f36d4f3852cb15aae172578f73522f966d077a9d8d98d316b664\nmsg = 54657374\nresult = valid\n\n# tcId = 11\n# rsa_sslv23_padding\nct = 80e0480b11f19fbef3551fb123a4fd968d5e5ff64c88c1c2b70546570eb585d5b119f9d511fb15ab3e25b1dcee9fd3f337f949377af431df9ea9b60c07225da87ba0d61c0f7a99aeb130b09c294e0d49caf3854a65fa98be5644457cba4e5591b0f0434932b787e0573354932a6a9f0e3355524121b04fbb8fb5e4a787fa509a7fa946aaa34e91c16827a65639b06737bb1a9fd5b85c85c58b116cdb2a900142ff1886292de9d4d944edcaf4e98aa28560bd6d35b4d64f0c7e72c1b572883581ec8e479a836bc2fc55c49f8ae50a9118a81597ac5e0b31035aeb0cef1e5327df6ec7179ff461b6f157c690bdcdb9937fee7e8355384667cc7a69856f6e86457eab8d87ea8be33e5f684184001319fdacafdd20b90e2e03863bda108c349de950377fc11f20ee32f481d74fb656449c309459a0d296124f726519a73c2a5b41bff6779d91ae9b47c6091e695ee7bfc59ecfe123e4d0327a3cb5b04cf0a998487afc20a3d0aacde87a080481ae0455796c5273815cd2b2d76edc7c9558be1ea2840a17584941b3c86acd32967a64bd1295a94d3ab34cfc67b2cd27900898bf461453a8716c8820ac8e6e9880a3eee38b196d9af46a3ff7abd2354e1a5f654a1dc1ce45cb4902988e3e14d78d78f96f59ca20eb5cfccb2767e937a55acb7dec407f96f6e5f6345daaca1e8b11a72a599515e08a96dcdfe2a8b8dabc0a4dcac4cabd\nmsg = 54657374\nresult = valid\n\n# tcId = 12\n# byte 0 of ps is 0\nct = 4a7a03202b982309bcf2f99d30cd0bebe24b43800e3bef58abbc11e865ec2bceed4d25ae1aa95750d267233c5db0860e48228a4fd8c2953fca6bc7aef959729a7d35c9af4868fe63303ba4f00a8fef777eecab7baeb5d9db61c4a7581eb0c12c887ab6ee59f6d0d8ad044c64c39e344db3f2fb7906af25dbc1263d9ee3baee8ff46a49fec4d893425bb22ccfdf7bd86adb23b3171ee653bd129c042c60d049730a28cd9ca83ccc8d8838341701f545503f3e356bbd4ce269f455c9800a1e03228880edb0590136ec3982b33a4f561607d00eaf9ddf68b67f18808c485f7d2001712ca5e62ada62d3bb575e612cd2e94bd88e831026eb7a23cff7f3be1bb320d853202039b0f59dde8211f9c65494335e99b9049b5ca356dde17f3be1688e6cfd232271474065124a8b55186500bc42ba4d6dfab381d5dab6d7ee1e7305e9ee93f1202a9b8dc6a9b7f69034d9de54d112891a053223b8489ee5b24238629ddf6b5d78ec366fd0b00dc612c5751248108106a80676a3137cfe96008342696ae59c369c7364fb070fb0a5af3ff548f119c88f2a7059ef880d0d135b085918d48a377027f78c72ac6b4eacb869c8bf86135d459cd07202945b97873228fb280ef770fd317ad5b2d36925826d786bdc9fbb760d3907d3ef826a6ea47b0eac1ef709b7efacd40acf51339ebe4b99702e084bb6a15f070d409df7e7fc802e0e6a988a05\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 13\n# byte 1 of ps is 0\nct = 05256ddf55991cf3e74b8fb8b3172db6e327f15c2cf13830fd169716f7e5e717147f91602814e4e7b38ec9bb7fb5b5b60895a89a949d835398ee6798857e05857438ec27dcc897a777b85d420146e5a0f0ff64b23979b9626bf6a34a8e01658fc143eb9d6fdfe1dc878363b038e7f2d91a7f50854684f7bf2ccbf042477b9c6c50b8146f594800a5b907f04fcd03220bc25260748b24f6281d3fd939b51d2d694fa76941b8873c0c70311fec77bff5b0752dcaf86a8a041a29c5ed35b0a96bfe6f82754cd2d173763f9753dcda7f5651ec40e1da282c01bb0be7b5faa390fd134b05af61b3fbd83b0ddf0060015843aed03bb79a11ec906766a6fc82fc28016165b7e5f9c9b913d52eb0e1862209b9cc6950b5d47c21c3fd0673d0d7aa281ca5ec3a36cd9a4570419a29820c75307bdaf0012b68579a6ae9e832825f47ead6b6af0a1724ba7679a88233082b65862bf1fb76656b0ed76dd758470b00c147965b4ee233275476e9030ed301dcd19cbf7ddfeaecad3d17d7129c4e9b4352422a3d2b812d09e829d5d8c2e41f6aa10664824cf0d3b4597aa2cc137f05df672f17f0a345739c93f2cd583bc4ed5dc2bc7295d89c0d986eb88ecf5732a87fb8a10fb449fb3f5da74952511bf2ce03bd74db026b76df93b816a64b4372b33e873226681204022fc945d9c2909982e6517ec2157f57f4a36cbfadab9ba6c8589eb03310\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 14\n# byte 7 of ps is 0\nct = 9ea6991124c047788b4ce768614edc52cb1bf88865f80a7b7bbbc435c1389625a085a5030338856527d86f0fa9363101a7800d7e61dbc081d5839bc679728403bf028a22cebbfd2c9984d581ca79cbdd2e9962fae64a5bd3b2a8d419cb39fbbe2df7b8a9b4e7c603ae1cd923cea1da1561beeefa680d5bb36fe9822ce12e1c88498c2273b76646918353c663f91a2f54432cb3fdbc5c7191ec5b8412da54ea45616c4125775dba29930c36a12522ff3af5eb628d2fcef30b887114ab5908fba3ace7b7c71b101ab1fe311653997a50de08b7a3e92d50eeba2064e9162c13eee23b9fad9ec00bd62e62835745547afeb8fc1fa5af5a8be060bab8e4e2fa2664f62c8956ad4d20dd27932e57aa44eac7a86b867c4ff6e049981109c84585bdb50c31e6064dc4c592cb1796ab059849db5698e1956c38f0e07257fbadda137b57f03b8dbd3d6d5e4c06474bde194cfb7d671ca3d2f99b827af954cbf0c0dfff8cd63af75f7e01b6630798a00cc01676b0cdaff74cb270c216282906931a7daf29a4ef8034407e186f2f9dbeac1f712e8bb7b1a4b121e045e9547d15ef1ba1d8015f1d19a3be353f7a82a88c130352b8cfeaaaab871902fa5f68c852931b4a014e4fe3644861f276a6c17adbaffaa7cd23c223c4e54e2b85b46204b66a3c447b4db722e6a9dc0c61ce29407a4d246a2fe8386cdfe99732316026a2c632afe5084297\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 15\n# ps truncated\nct = 1427b2364dedf9b33b1cf70f8823b60a2686520f904e89247bc6b5b682170fd152554f862ca64234345bb83b118539eaa4c0b7fc46e21d2fbc7eb5bb26ade5464a7723f8d44c8d0a88e1d1d7fca1717adca7207b55c5b52457c8aa2c6d9a19e07e04ca09ac39301512aa66d61c5363898138d1f390af651cf230fdd8cc691d3c69dece67e4d9301b74b1cf6fe7aebe6626d49f47ea33e5861ba4c5bc0a24f506b4afc959e33733fef1ef7a207c29c610ceb9ae53f7080a84491bd12d609ed216445ee54315915b892561efdb1781150fe9c243af8800c7edb8466da8e4d0240c0f627ec2106326805cbdd845b30ac35dd46692ec964f6696adedf72948474255d50505acfc1f4be6f9b300708861f2b9f9796b0d488ffabd14f6750e67477c59a0abf21f066388b0cd1133c90dec0bfccf45f34f777748ca8687f3268c9b32d0552588df9fc496f29d7a9152d23b8b51203cf151c612fe183432ace03fba2fe5068d749463e50bfc09912220a618f650afe592e3bc4c7314e6d9a12aea44ac0b50d79c8b9393b0df70150af7da499a9c2d1ea3dce363305c21f3ece8f3880919bb57e764760ff7863c184c043be1c8de30b177e1bcd5cecb5e804d1ee96fc823f7cf2bc3159381c78a49879407191998ca759cf30eb503783f88ea157970ddc6ba7569e1362cbb99eb45b6578f142df5f1cbbcf2a713729c2a0117781f8509df\nmsg = 54657374\nresult = invalid\nflags = InvalidPkcs1Padding\n\n# tcId = 16\n# ps missing\nct = a4dfae8779a11c4254a59", @@ -3926,9 +4564,9 @@ static const char *kData156[] = { "59cd5cb75cbbc743f89b535898898ad298571\nresult = valid\n\n[d = 008777a7f9e0311bd8a049b874396230be6d1fc90ff4985e251641991f019ceb1914c2d911cc1b71f5f302cc3a4d094db7e9c1a544a07643d718c333434b76c0dd90069a90e7f8a6aae688c8d3d909b0c92a025669f07b55c99cd07757b58bce335fc9799f581eae4acf614fb15f07ce51c1b7fbe74e280238ca9a84cbe292534d10fb64421996652f7300c872f00f7ccbade7b6afba2e833be20b55759b112fde52452c481597cdd9681e9fbed850b16fda2cc86bdb0028150e10688cc8383ff58c072e02a86553ba2bfc07092d1d53c7d10100bba00464b776a07367b8a5f2754d3eb5236e811fd8100f6a9e14fc07bb0154de227216f22c434b07c179d69c754a87505ed6cdd1cb043f21629204fe4671248c4e70d28dd7a5e62fe9cfd08b15a0bf5754158c55bf271bec4963923c06964868c00b70f7f87ea54e2b188d3605477ccfa2f658a6298d627f56ae95131fa0e12c536b8afe962f8daf4b9e66bdab867e3809d80c5334421d14305e3fba5710beebd3f21012dfeb946644b1af604aeecb93efe288f047c076acf57981e0b0e873fbfdfb4a49579a7c1a8b2c945341e876027e93c213f37b6c09e1252488d31436dc62a9924c4d92fccb1f51296907e2faba674dd7ab7e3d73761a7c622bdbdabd45f02cdc66f0d6400c6b45875ac720fe045ac86a8e8324770aba7b9d7bbe49b98a819925ab8d200285ef0e927d55]\n[e = 010001]\n[keysize = 4096]\n[n = 00b9343dd96ed558cd9a99740fb5de19a5ca4c740e108bcdae2d6afd8d5091c09eed87021fa1bd291f6c23fd6657fefd470fa672ab568e41f5e37bf1b38241ad62f77630b644cd77be7db87d49ae13a151fe992198fa98d790099fabf71e50853482f321c833e5c7f76679faa9ce2e4ed7acdeef98944976b9b5a06fcc00c7e36a4d1047556587243903b678a3085eded3a17e7a7e691966a0a236ccc929af83ee37a78372d52cd9be2f79cea18bb20fccb59335b09b7d4e65b93f8f06ac983e521a341f38019f960b80661f9c4eaa7aac7c90019aff2c1ed85571ecfa86c4618831739d78af3af432e7548674daf1a781601ec1ecefa91fecf98fa5113de67f029e01fce0870fae71cbde1aa2b25cb958ef78ada540e054551be75c9659834d2fb458b20be0c4dfcfd02f5c69ade32a6301656d83f7ec8b88a610a9a4f5ab2c1e60fc8a096848658a1cab992cdc9954e29341cdbd4184909e6079d322b8a76eda67d6b5ca878d850d6c3ea2fff7119c1aa313d03797494f11b54cd36e4a8b22572b0088251f9fb3ed1531a4e70549054373bd4e0a17a0230d104c3f666ebf2d14d2060405b846202d2e4a44adc708b18749b75235d91ef786ef9b861ac1262dad728a397cb9e299bb64733d43aa2d21477c726bfd5993804578ac0533467af9a8ee31d402bcac633484e5445ed3b1a74d2a95feca1c4767d4cc7c150765558481]\n[privateKeyPkcs8 = 30820942020100300d06092a864886f70d01010105000482092c308209280201000282020100b9343dd96ed558cd9a99740fb5de19a5ca4c740e108bcdae2d6afd8d5091c09eed87021fa1bd291f6c23fd6657fefd470fa672ab568e41f5e37bf1b38241ad62f77630b644cd77be7db87d49ae13a151fe992198fa98d790099fabf71e50853482f321c833e5c7f76679faa9ce2e4ed7acdeef98944976b9b5a06fcc00c7e36a4d1047556587243903b678a3085eded3a17e7a7e691966a0a236ccc929af83ee37a78372d52cd9be2f79cea18bb20fccb59335b09b7d4e65b93f8f06ac983e521a341f38019f960b80661f9c4eaa7aac7c90019aff2c1ed85571ecfa86c4618831739d78af3af432e7548674daf1a781601ec1ecefa91fecf98fa5113de67f029e01fce0870fae71cbde1aa2b25cb958ef78ada540e054551be75c9659834d2fb458b20be0c4dfcfd02f5c69ade32a6301656d83f7ec8b88a610a9a4f5ab2c1e60fc8a096848658a1cab992cdc9954e29341cdbd4184909e6079d322b8a76eda67d6b5ca878d850d6c3ea2fff7119c1aa313d03797494f11b54cd36e4a8b22572b0088251f9fb3ed1531a4e70549054373bd4e0a17a0230d104c3f666ebf2d14d2060405b846202d2e4a44adc708b18749b75235d91ef786ef9b861ac1262dad728a397cb9e299bb64733d43aa2d21477c726bfd5993804578ac0533467af9a8ee31d402bcac633484e5445ed3b1a74d2a95feca1c4767d4cc7c150765558481020301000102820201008777a7f9e0311bd8a049b874396230be6d1fc90ff4985e251641991f019ceb1914c2d911cc1b71f5f302cc3a4d094db7e9c1a544a07643d718c333434b76c0dd90069a90e7f8a6aae688c8d3d909b0c92a025669f07b55c99cd07757b58bce335fc9799f581eae4acf614fb15f07ce51c1b7fbe74e280238ca9a84cbe292534d10fb64421996652f7300c872f00f7ccbade7b6afba2e833be20b55759b112fde52452c481597cdd9681e9fbed850b16fda2cc86bdb0028150e10688cc8383ff58c072e02a86553ba2bfc07092d1d53c7d10100bba00464b776a07367b8a5f2754d3eb5236e811fd8100f6a9e14fc07bb0154de227216f22c434b07c179d69c754a87505ed6cdd1cb043f21629204fe4671248c4e70d28dd7a5e62fe9cfd08b15a0bf5754158c55bf271bec4963923c06964868c00b70f7f87ea54e2b188d3605477ccfa2f658a6298d627f56ae95131fa0e12c536b8afe962f8daf4b9e66bdab867e3809d80c5334421d14305e3fba5710beebd3f21012dfeb946644b1af604aeecb93efe288f047c076acf57981e0b0e873fbfdfb4a49579a7c1a8b2c945341e876027e93c213f37b6c09e1252488d31436dc62a9924c4d92fccb1f51296907e2faba674dd7ab7e3d73761a7c622bdbdabd45f02cdc66f0d6400c6b45875ac720fe045ac86a8e8324770aba7b9d7bbe49b98a819925ab8d200285ef0e927d550282010100fcccd1ad86a93b05a2cba0cb9ce824924f596306841af3405169ef836d6bd96c57dd26ce2d01e46ef190871346e1486cdb3c11dc05b56e85c2a8fc5e1ff15ac223e033ff80aa03a3c0464636796e76865f1f3e4d255d7cf8d2e130da412a6508053a4a4b46bc091084cff4fa5ee007d9e48efcba6c4ddc4525f5f4a93e5771bf1a55699eb3c41eff562e529cd481aca601b7d4b4a7708869b7c3cbf79aeb2499a7845e0805d6f39e594f68fbc69f1e92f7488e57a8075a8f38c64db3fbe642bd8cdc48ba23ce019858adedd8c3fe56cc81e1b233e8f48a02175fa2919d4c16bc9003a3aece7f3b482745b6f767f137acf1bb6c673430440a3d17237768f235830282010100bb8c61e648015d9d08f8786e9236a5cb110048766ee1d43a8599b4457853bd67d168d8d2c076ce441343dfe0af9b219bd22457e0c431304dafeb78e00788992114be182aac566de4a788be21a91c78fc6cb214b6b464960bd4a257ed8873e94d94a81f83acae7f96eaf5e3ea0937569411b1dbb1421859c7933021d54f2b6001af99821a9e5f7bde3d396ed12e652021a0f80a66242ce8bdbd1d558c00475241b754eafd8d2d3217c7179d44071f1fdf3fb198a6addbdf14edfdc7960c0aef6668f6912c52df53f250ce93fe4209db1813e8f07160f5c117ee162110ff21f35227f2cec2c7f586a6e352b58a0900ec91daa3f05ab1ebff2dd00ff945534042ab0282010076bbc85b851ce4e0cfc66e1e53f2e0826b8c632b434ed9234359cb29e271be2bd9d4c00e242b785bf74f5771e15f9c41ac72b93caaddbd2c4bf24c9df4c8ca44d6cecdfd5a340003a022218622609480a61aa98b585a618108a2c5ec2ca139d49b87f62f06e8f824ef0c31568acb1444edc98ec00c70415da4e7b162f029e7fdc6e388f9061bbe275515eaad484e2385d0d6c3ab99dd0be5036f8dd41cca0665b8bd3de0ecc539a50cf3742e94ea5554d79a1768ea3d91f624c756e58b116a15571c7b7819aaff2acbb3dd3b6b4a81000a9cb3b317de0b17d25c93a16accbafd1372f224ff4dd8cd19ccef93a219347a210b536de1a02dc4d54e91d4dad0affb028201004ca5375123f622eacd42b5fd0216013576d235cae8cfb3aae2f488bea74919abb6e1f15257c375d24e493bd21811feef2e371a0eca3f0bed83ca6890ada37e690d900e524a31dc2148f2523971622873887c5288c43a2333dc872805f3f0e2d488bf1879f8752bc1626e70e131390351e9d554e2210fd0890636f26cb93911b83eaa2e887056b749809ddb12f3b1f22aac1d122ae1f7d479ce3291c6704ab56c13df4955ab7f5fec65b9d9d476509af6e291d2bfb3679ac873e675cd754876c3d47b87a2a48f8e40061416591f65e5baf650090b5cc3b250f444e8e8884bb8a3c79dac2fe006102c5dd46c4a68198f949fd4c5a25afa064413b6a37958677797028201007e3bc25b06f642f98a9eee091de958de87ac8252fec117dd7c6e873cfeffbb012320dded22e3640689346997a13b8fb96da25bd890af6e651f4884d9051e24c9ead42f096329b2692acd42374d8225a7b61159310a77dcbdc4ad809143e6d684890965cf485d0e805286408bbdd353790161472c7b0d2c309e897785c26662e27ec620ac7a496424410049c0848a2af34c44a22f986ae8a98891dde90219a4bbb79766be3101ffdde6c36a13dad1355dc41de41bcd282b29a171bac3196df7f18522d7776a947ac21658fcac2d91363ace9681184b2db52841c7b1cb12261997fc198914ed73a726fadf94faaa5b91a8cc1fb30dc0dc023769df5e76eddbbdd6]\n\n# tcId = 65\n# edge case for montgomery reduction with special primes\nct = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nmsg = 229f09dfdf4edef7a8cfa04fbb1437e22b814eea8bb7b7e81094c94ffa8aac13d2a9cd1b51c0dee1bea82d037034bc03105041e86eec10abe3b74313cec27c1e046a5d0bc57bce9a5171bd9bfe3217ca5995eb0", "825295da331ebdc096c0b73\nresult = valid\n\n", }; -static const size_t kLen157 = 50963; +static const size_t kLen211 = 50963; -static const char *kData157[] = { +static const char *kData211[] = { "# Imported from Wycheproof's rsa_pss_2048_sha1_mgf1_20_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e50203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e50203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e5]\n[sLen = 20]\n[sha = SHA-1]\n\n# tcId = 1\nmsg = \nresult = acceptable\nsig = 1d5a9bb49cb1f5c2862f36e451dce7fc607f3d302eb9a9fbea5b673a29fa9023308381262c538cb53910b5773a7a44ff465828bdfccf8a7a4ef902e945dd5f6226ffb7d5b05f2335e5762c5aceff71c8408150959c1780cc9c22fccebd3405e81f1bc16d276c07e4a545ddb1aadeb751b571d22f3e4bc4e02020eec5901a1ebc04415e9ddfe967fbe4ec7166923aa095b9fc7a81fc21ba37b5220a973fc5f32fdb8e0841ed321450248402a159d2c08e4a72b780310d420a6e499c2b34b0bd6fe0d1d0e1a7810563324ad8e778720755eb00ac6e28b204ff5fbb01fcfc91e8f1d2f113a5f32843119f5e06beec0fe94e5bfd0ccdd7f322bdab7b05c4f83c0504\nflags = WeakHash\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nsig = 01e9b1d4f36d040a553ee12afb76a36d04c6c5a0f3df84ae22422e8157e57b1c43a7bdaade30ae73073632a4679973ec10bcbb3016f6e20c9cad29a14f96052507819e90cf56ba50c97df5e5001c7f94817ed29f7500f839eb415ef3182aedb2484bace43cd2fcaaa6f5dbc4b6491791592f084b2a14ab303e89deb28a68c72b0b630ae85becb67f2b722f23a0f321f3a7496b251895111640452932579aa53ffb8f8fb4ffd331fa48c6f1e8e152ce7e04cfec941cd96dcf7a885a3022e426d87e8111336f1166878dcf8d190ffb16a574fea9eb6d7e270e025c6d98817e75c968f78c4750be018f74968d7f3e5cb9d6f47d5aafc99c85c83af7175c73091ae8\nflags = WeakHash\n\n# tcId = 3\nmsg = 54657374\nresult = acceptable\nsig = ac3c332b52f06ba2190c6ee312c32321ac377019c35453537a393bcf0c1e6f3697f770ccec092740100a7009cba20f86304108165d5de572df89c42423eabaf910619d555f7b27f7aca31861db0bca8357956466d3792fb6669c77b98bed3c721f71321548f8b4313e535eab5638b9e341f4bac6c9ca02bd07111da4e39f2cb8ed8ea5daced3ada8376ec8db27f6d619ad92e01fb49bb3e53ec3b84ca67b18c268db08ec28752b0c13f269a39fa700dac163b5b9439cd7a9883673335f2b7ecc0728ab38df178ce14479bf6a8aa1e24a433e41f9f217be5c0181245135d1e265e1ca1aa06dd6e853f5d1f144878e2f64461599cf88490285b52a79b744f25ec5\nflags = WeakHash\n\n# tcId = 4\nmsg = 313233343030\nresult = acceptable\nsig = 0bb9473d3a8cc4abd63c6f2ac13e278a9cd1dda844fdbd13e9b77cdd52c1b05ac59126e45d276777e8b1bc423cb261d29675988954c9ddc38bb9a67bec5e03e1e780915333dfe494dd8a4f0bfa0d748805885c389d6f7fb6f786c58d21a468b3589346d70e1153e29dcdb91dec8ac185501efea247bac7c63e3c546ed635e647097bae3b8ccb992701a75d209c439c5dbe8122da616a4e230bce08f541abff854fb93c87fdde0fb457c44b2783568bcbbfbba611d8e984410d360c4ec3732cb69426a94191d5a0cb33149b518ded86864706c723b27228d74836513191cebc790793e5809287b0279e7bc82f266d437d192e98975960d0014dd02e172b7fe251\nflags = WeakHash\n\n# tcId = 5\nmsg = 4d657373616765\nresult = acceptable\nsig = 1b92015bd34fcce819bcf75a6c38a05ae2b425f4b21802306c1af645d1197d2c84b84b24d453eccc44f578465b8100ad9d60ac4912c7aa4d5745a1acead176d8758f6abb532d874ba5407d9e3e399f2cd6166b9d3ad1745cd20ddbb584891879ebe71bfd4275d4c176c9da1e13903e42be68ff2a78d2da9324a8cfc7a8e2fd08307c0ee14288087196c840a0e2b3811d9e9bda6ec24bc86e7ca5e34b57969e3aac31388fd2e696528f7d5136bd44c122156a5147f05bc9b118d3a33ee6d7faecbb048290bb0d4719c25ba71741d7434d66fc4baba9b995dfbc56e3507cfc97aa2d67acfa1083e0ef58e6db6975b3bd6b10ddf1c13087d2bf546a931f0baa0cc6\nflags = WeakHash\n\n# tcId = 6\nmsg = 61\nresult = acceptable\nsig = ab8c1e95acc36ad6218e48f033835d15ec6bc7181552feb6dd6e128546917bac892f5b349a234d051a83ea6469e27189f2995302388337c2ffb3a746db17b157923bcf6e985ebd203a4e9a23697cf2925912ecadc3d3f68252e5e01e112db1829658b16ffe7188228921829ee59d575c6ad8299d76c7f5d6cb204b769854de0204087560465904c73ec3bbc1b47bbc98586f0ba17b99c43234d262b7f1e19fb2cdd20b92c322d6e498835b3ce8480eda172921b5a4707d5ccb662e1ee4b3b4c36b5b485a10aecf1b12449732018e594a734b68c8fad4a730b469d097c89c4121d4f6dce34be78f65591b673b1d0ee170cb3c1852ca22bd53b9b26b2fa19ff275\nflags = WeakHash\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nsig = 264dc979cdb293d180f15ef3183334d4940410c9639712910006c68e3766c3aba1dd95510d71e7d91d93e61128da456cb0d84c44552f33504bd2dae30699d372e394912a66c334e888873a949d58a3b7d7d43e76391ab0cc490e7c3afee6a5f3262b7d298919d64c5e7bb81cd7bf8e612b9f6e266eb28316a7fd01e44b62100f4b462ba5b238115081536ad1f6a068d656d00000431afd1b6a5b57f43f27ca778c08a4f86f62ef84c73aa72b0c361c68345c10599ed731d6423c750462acfb469910a50aa2fcad3ef8c908633bd3fb0b2e7e8988f9be2ebd715333381c6506e0cdaba7691109cceb8ad5364fbc035c309a50912dbb670a8c255c287a9ba992f0\nflags = WeakHash\n\n# tcId = 8\nmsg = 383633323732373830\nresult = acceptable\nsig = 91d5f67dd4f93a6093adb8a7686be7e458f66c23e32464942f46193055c61c29db94eb12f96c918e1cbfcbcd2ed6f4ef6d271cb6def90375b1c07bb2d5e7c1c92425b16b2d8acfb87b8aececb874b7bc2ec9b2865f8882e0807db9ed481ed5fed0f3dca5b643686e70b4940af6d086ed7fb91fc30b322ce9fda13ab70a7206feab152991415d50ae586e8a9229a5d2ebdd1cfe56c131fb832f1dc39bd9fce7b73b190832b4052f5dd34cffcb39f5b0d527db2322d292427bba611ccaf8afd7cef8878337f1a8b2bc0f5ac08497eecc95b23ba171707795fdf5397f94ead6b8569b4871aeef1052fb4e895bad9f17462c1dfd712950631f625503d1336e850e6f\nflags = WeakHash\n\n# tcId = 9\nmsg = 36313639333935313337\nresult = acceptable\nsig = 500ba4952945df532e565c9803ee08eae2b7b69e02199cdc510184fab3f22613f4a005fb425bcff96e25ba4f66a849abbd299f2ea7d530b263bab4899ee3b6121b88b1f2ba0186867fcacf686a71fdba46c2e5379167603bd88a9e1a20f5211420a1737a77c40fce3a7722115682882ba04fb521088750178f3b665921011209f4046b9981b79696cb4193fe56783ea96ffea62fd3f5945e4790ed1a1059b5f81124e52dfdae58e6814a1ea91851c045d71960600a2a94db05f40fdcc61b90e846e563122e6fff4ad1ba74394af7fc13ec46fd7befe8825abb40b365e8ecec7131769ae3871e806eff4f6092802a8edaa8cc47ac8053c8fefca21648abcab60f\nflags = WeakHash\n\n# tcId = 10\nmsg = 333036353331303631\nresult = acceptable\nsig = 3296d2cbabc9257d91b75b51b994dfb8f777fd2630801414c33d405860e3f75b8b08540952e4defba250d3946537774f93a8c88607c8d673a0a1c7161ea14c56b8d3e2d17862e932146f29937b0084295f16bda9f6c555af0e26f7ddd223af6118c795463ac9b5be70bd413bbeda91539f05da157275c24269f039be88b3c3589e4cbc99746f3acf186b79bf27882ef2ef3edc0dc717ed2b94ed55177f99537a3261cf509852115652376261b090ef766cc68a99ec4ec7aa8ec6cab724b4eccae9805f300c48a076f0dd345b6018941bbe4fdbf94e548bdd6bdb6c62a358407ed3c84ff587ebb36ca82818fd82618c94bd355944547b09af94a03e68a3f07f94\nflags = WeakHash\n\n# tcId = 11\nmsg = 38353939363734353639\nresult = acceptable\nsig = 97e5859c080f776faa13039db19d49eaf2a16b048246c939ef875fdb4e28eb2bf4ee3c114b2d99b20753d1082061fc4935429a92aad3d486718657a8ca2141873e69668edd749f99f1cd757dfe7cc2db297cf1bcaa1f82c3cd92482f4dca6ca66b0c28276c32c4c2864c8e87e8c42b4008a", "87a4100523130c8e4bb35b7fa7d1af7ea6097da7f7ae8372d5aeda20b4a4ba3a6c93e1b77b17a08328a27d975ccfa6d1b9010b34ccc12ebc0c3d4e6bb14c1b655a15b7f68604068c9c493f561017a1aaec7c84d1a24d9ef97aa683a240abd141a55daa3c210174e731daff63eb39ac3aab1a79b9a0f9178a7c374f0bd0148e4ffd8c9e17f2dc7ef8fb20e3f5f1043\nflags = WeakHash\n\n# tcId = 12\nmsg = 3135393637383036353431\nresult = acceptable\nsig = 8357bf730c668cf632cf2b1b5f9f9f3837061a1de0b86906debecd43077bd132b6c6a078b35b6878a07a8d0a84ceb45c93cf8e56e21e7cfc095107412672b58faeea7cdba71765101890b12a92af31d12f6370529215c299469ebfdcaa2055d2c2261bfce7329977f13fceb51d445b56a57a4e34e7c6abcbd7ecd13af0d92a6300ccaf70e3ae8a827380c58bfe4f381ab085784545d6b23ebf896ea8c453af1b498784025c9e9eb01e10e9d1e22eaf2c77902b64435be4c54b9f3d74b63482e69cf751f522f5a3ff59a35ccec8e612321495a727fdabe0891265cb45a18c99846aec27bcebdd79195f65e05a4d5799a333219589c61e1aaa93547974138746fa\nflags = WeakHash\n\n# tcId = 13\nmsg = 333237303833383939\nresult = acceptable\nsig = 46f2507d0817c14753ed5d4a9fa6c98cbcf7483f237ecf5d26d76e6522e940215841da07f3f20d4af6d8a35e182617150115063c1e1dc897b67ade6b6263700f5420a7f6595ce620f90ce6b8393ff006fe4f0825dee82ddca8457ef74d78e3352f05ecce196a1bf4d45f018317a6a42c59a2f2876f95e405d65c4bc5f0380d0e0956766f89b15850fbf736cb042921e4589721b5ad9abb6213bfecf8eab2ed077c6cf33be26e8b9fc5f95adc045efff8658231e28fd595701531e8bc3c74b42f12271f077e08cf9386d5b611bd88218e42ae757eab5c0c9b974c2bc17da12c8babad3eefda8a16a56ce3431da35460b1ad1df2b2e172cdfc006512e1a4ac866f\nflags = WeakHash\n\n# tcId = 14\nmsg = 34363035383435363034\nresult = acceptable\nsig = 0c3b3f5120fb9c7dc3a715498786aae8e2dfe5d63f54cf805d02bafd36c806c83d0a93af5d1eda293f4ffe6d0ab218648a82ad12dd328a60f6c632dbf9f6e5e504fd08b8b84d8d58000a2d2a9f9a966ee898d9cb75a69c930b260f6dba3a0301ae876e212d4fb971d819c20cb07aaf0fcdbc152765398173dc0d7229ebcd8a9aaddff45d118bf63ab397adb39af91203e8fa5a7d28f2937ff7cf31ae90dd9efc9f2549bf6cbcc3c65aaf78a93c76007bee2720930e2a5331335983943a6d93570b11615165196f9d7ddadf805d443021580514d921f439891446c1fb1dd740794bbd6decb017acc238a81ceab36071be58551557b09643cd2bd7be6e69b77aa8\nflags = WeakHash\n\n# tcId = 15\nmsg = 3131313738363634323032\nresult = acceptable\nsig = 94b777215d1ae19f959d046fc02fde3e113e15bdadb1d792c744f217200e275d3954b798b43e5ee382877420144087be340e11d2879c10af6376437b5a8f62634fa19b9338360a318c95c9421d90f60337634f3a03a2260796d8928e056aa7759cb13f3bbc72954f9c9da7eab1d3564050e4267ced557e3684e5090cef96f585153db8c732b78b4f7df59db219d7aeac42d4f20b1dc9825171bbebc2712e722ed6fed12dfc72dccb1e9a2c6d93e4c86641e1dfe16d6d43629dee7d80eba8e9639ea594ffa206cf3f0e561b2953a290d8cd70bd0ccbef64b32bd66b294f1fb1ec97bad0e096e5e200e5812fe025333cedd7d1ec8c111b28beb4a402f5cabf2f99\nflags = WeakHash\n\n# tcId = 16\nmsg = 383035343535343634\nresult = acceptable\nsig = 819f624b0dfe6822d3923ac1e5c75f79e1da3dfbc13b332874d4052eebb30f9b2a09ecf75f1122990c37367d75e4ec510f4645b9f41fe4f2f9805a981ea81ce932127613126caf8e04b9d194a927b720b24cd9f1721e33d121c59930ec48a5f5574f9aa8c6bafb5c8ccf9dddb2dbb418d9884ecb4a931a9265360dac7475de7e4cc795ce7a586c7d476ba470dda7c03b3f1ab69d9372d7cff3422306edd8fe8f6dd745596f1fcacfb99914470c13e752bfaadce632fe4124d6ccd80eebf87a6982a998aa4a0892c270ae6de0b9bcbfbc9cbd96dff2e2f93f80d9370fa2a015e13d0376b4d9dcbdedea29ba9b616a83261ccf6ec56079ff2ec93d72989cf93454\nflags = WeakHash\n\n# tcId = 17\nmsg = 32373335323330353531\nresult = acceptable\nsig = 118d4dcfebd82ea74b28041bd8bf5f969d04e160e2b8ab2fbbe1c2a1673cdd4fa7d801aa4bc23f9898bc0dcb240e8a3ede076f911ffeb2749c03d21923055f8878aeed88563dbbc45422b658f8647dc868885c92015df4d5925f3e6d75e85754b7f002374d4583ed310bc991cad2812fd29d0906c4dea5c52921fe2184880c5e8ca51b06bc5654edd5e0e72e20922a9c9b2fcd068c700ec82878b6ac04a56becd76fbbe9fd4abfa9348756f983bfa92539424d972d764e7813bbbd34bb369ec147fcb1a94e8602e359f1ef312725f2bb81c04932c1c4ebebfa09e3165d0287a85a22f0898d6385538066246ade07cb51580db1fcca86afad06fe2f9695c2f8fd\nflags = WeakHash\n\n# tcId = 18\nmsg = 31323238343430383037\nresult = acceptable\nsig = 53711344088547e405b1e3f7605e44f9b7b6735d5d3c32ee0e408fe7ec9ccf58998487443f66d4edc0020dba88efdef9ead403a2874b2892054e391f61c1b36e490a8623868ea3e3eeb07eb6a2de96503b93f4fb534225072c6bf90837c029a1f5c2a5d8194df2e203fb0c2aaeea506767952897d900d9fb20c8cf4f7b68a97a5278d7aaa6e383f0cc8d2b53bb748ab6b0dc5fb1ce82b08aa986449b3c3137a5965985d0cd62b7a1a11b31a498669a0b3072692eed9a1393e42d7e61b90226acc62b284ec550c0813c4afa25a1b6fc103cb80cf429944b557e1334e81c1173df4a86ab107cd8ec6c75392cc7cb11c9212f15ee7e18aa0d27006af5c5ede7b0e6\nflags = WeakHash\n\n# tcId = 19\nmsg = 353131363538393837\nresult = acceptable\nsig = 972ab5dfd3aa92ef9ff40026764716784c87154f12967ed3f02adee5f73fe9a0594b22599e829bcdaeb00217a12218dadf06c9940aaf9c02c75cb149a89e258a548894bf4762100ba17bc8bc60a7a0d05307b7133678dba4babf660d12418659cea25c9f982bdb9b1d2300fdd9d144a25d4f150e54ca7ca344dde9e9e1ba5783c2cb606bbc86341ab9344a0840dc515dd1d589bede2e3f483b20180f08695cca0e9e1cefc68b6bfc3527e48ff0260a3f696c0680364bd4b6830d675ec4986638e976b83cb1f56ad5fe705d5dee0c0c5eb29bd15a24f265965000ebcee5a8551ad8ef74b40592477255169bda56dc8f35fafaf796fbfa44d366033e15acfe048b\nflags = WeakHash\n\n# tcId = 20\nmsg = 36383435383536373234\nresult = acceptable\nsig = 7a7cdead06ba212e8dd6b446f911cf37b40c5ac7f9c817125c0d5ee3cde49ef336b87eb94f7d8a93e1d9fd0efeb77e724769b27d6f63ba91f7219f23e085a3433e4d69ca8f8e420534f554c69a7221d70e57f8a8246b24b5986716c50da4942a1720e51b3ab87efdad42e02cac254be2673d5bfa4669e764defb401121a25055993dc5ebba22176834b4a2f9a8a3a34d35ae2c344e9a84675d94ef8f56b16d848d15851c058ae64df8a404eee09b63bb64fe017c206a94dbd7b274440f04fe07d22d079c2d2a8686f247eb983a0ee625b2d4b9fdd4d9ade53712f0d13cf1ff1aac03d09f80335bf9364327a89171a8a51f4219f86646be96f0d96c6cb27f43d3\nflags = WeakHash\n\n# tcId = 21\nmsg = 32373736323939313435\nresult = acceptable\nsig = bb15915502ad77b3a080eed70b444b753496450a4114d435d2aee9fbf1b345074fe85c23ad4ef52603b3a8a077d5024e3d56dd620169b6dc0ff7437fe1a520c293d78faa77258e8c8632100e0644f469f0a3250a53483e9a2f8dab0bdaead5df41dd1bba91dd01d79eda1df838dd4567d04526b0e1fcb5d07cc628f4ff62fecb65d2386af638ba6d0e594518699c5685033635af6cb302d07bf39a1dc5b50ede06baacafad9a2ee9ac48bf88c11329d2be62d565b0312813fc81c9e3cd243aacaa6c11dccbb6941e2aba6f93524b0140f30987168036b13810c10f65f0acc443f7df7009c238a8d5bfab00116f1adcb4cbf55c484239689404788bd29eb787f8\nflags = WeakHash\n\n# tcId = 22\nmsg = 32383739323832383334\nresult = acceptable\nsig = 4fe965e8b685d1eff38f26261f5c168b77560de5f2d7243a33c3c1c7f267d7b60e9a61444b6cf0a71caa18ca81f38960f45ef29586910c240c93820551f3da5e15180684807faa5d9fd361325b9d39c7b8e805abd75b69af4d020345bcda266a15540b32ccd28e57f7063edc228fbc815f1ab965fa542ed679c43f7b4949f7448e6882bc36a8f10412dc0e828b33ad4e09a5c72d3730143520e4eb625356615bf49e51ccebe904af7c6397785de0f20371689f2975666524103bdbb4bf27f1e202018aca8003de615f073773cca7e647e71ee51d97cc30356a17b50aa3c47a74e133aabba4ae41750786a9b1e584e319836c3c7e7c8c2eb2ce6604323856b399\nflags = WeakHash\n\n# tcId = 23\nmsg = 363635373637393733\nresult = acceptable\nsig = 9e12dc1ec88182f9462a795d710dd07447e79a4e035b97c16e351c4b5d4e98459b8e5a52e2f51dcc1edc4c8943863fa9abc8fbd75ee2f47691a58428034021c6d3323191a5a5fdb2da2ac1b2a149b8d1025576309e21410c9400cbd3b67d2ac4d4af6f57c6380fda2817c263984795934b48844f5ea4761402354112a2a8e2c06dccea0e535a06b6b1274a42f218b1d442c2c8347e7fd168100ef658c63c790e6bdfad3f4e57a536e2ce181a976dee1d605cee947bf5b228f7c540c2c9c9f2caa0461bf737e32f5454f52cf5300b23e8a9921d5e4a380eb836b645515c0c71ea803b730d0667dba49be3825c7a5f49afb7e989c85246ceec236c3a0eb43ed8be\nflags = WeakHash\n\n# tcId = 24\nmsg = 373436353535373037\nresult = acceptable\nsig = 3f55470e612c832eea00cd738b6152bd03d88c3abda95ccc2ed6eb6aa5c0e4d858982a548d25914eac7649c53d2169da5ad4f09bb64d6290c913d346424d189bc2414ed50dd2bdcfe3e9e80a992c6611ec86b537a8b5cd92985cb6226a0367c2ff20d2859c21882fafb2b9c47f48fd19cfa14f793e0fff45d06a2e886253a209ed95030da05a1c6ea35d2993c600491b493ded76e952acb0442c52760fbb1f735957a1ab30fefea6e7b596a7aa4ea479ba6a6aeb866ce6caf38cb7c6338b2993213c39c98b0cdd6e46c9702069b85a8c7e050c1079b11fd209fde0cc58d37beec46db4c8c95b402c45b2f5b7906f1ef19f2a84dbb8e54bd5d5dd39a532ed6e37\nflags = WeakHash\n\n# tcId = 25\nmsg = 39383734313231353838\nresult = acceptable\nsig = 08823a3eefc4d13f801419b374a5d8cd51f9281e124deb0415250e9e353e3a2f974a83347ca09d3b5", "ec24ec94048b096a4b11dfac52f2480b522f70eb4eeeed6f84941bc37d1dd1d82d7b9883beef1a6cdcdc5b3f6024d9299b10d7697c0325e2c75764f225cdf5fed483ac300a489b69536acc9fc90d581dfa10d67056b3ef9b05e09aa8dfd3d688ec4d63f483c301a44934bba1841860948c130d6353e7d74c9ca9e764c44e3b6fb1665afd38b6a7df8892d90a0d5483dfaec6270084ad76aa50f38e34389f891fa6455ed9f3cbacc422266f6ca2b10aea5c3caf83035c06833cd7bbbba83dadfb28807f7b3d7f4ac6e9025a47217c3dd1dfe9426aae6175f\nflags = WeakHash\n\n# tcId = 26\nmsg = 32363032333032333730\nresult = acceptable\nsig = bb6c055b3f55671f0ce85c5641b970b5ca0dd1f1b8978b915c8e36390700f6bfc765dc6b1694625672f70c0bdc97517d81cca9190ac4bc9eb5105df3457f48144ab9dcc049ae54f28123af0204176685ef6c2d71b0e618389400e18e90fd1dfe65cde88b628fdc410631ecae8d64b86da329228ce4c99fcf572e77e3ea366ce6d33d1401e250c75a329c71c7f5363a95cfde27bc8cf010bef57aacbd44c60a4d5b7aea41df9b9d59efa0cb6cd343b3c95c7acbd84d77873a5775c8757c585d665cfae9bf10095fe4f979b5866b6fb393b09890e118a35ae8a17f7eb8f60dd6e4954010ba903e69f4cdc63880bb24c3019acc596e6028b5f1aa86cc16d6f9720b\nflags = WeakHash\n\n# tcId = 27\nmsg = 33373236363131363038\nresult = acceptable\nsig = 80ac097d00555c8f6ac34f3ea96570432283b373bfbfc327e5e1f88b9b25d8dccd61d1064a944a10418ffb863ca2eee28182d046ea819b776e00a6fd62836aa3f334aaf7d14897971782a8e557c53314a3da16f3bf09959c139abf42c95a943e8f736fe6ac47aac2c4453d2a7091214e9d6c81098f39907d001b4cdaef6a66b426b571105a94331349d0c4d456263e090c0ed01ad2195ca0e7affd36d0f559cdf12c8c8128c7cf1a8aebaef6154b4bf8e3bd8db789eab080b14b45b10527e800452fbe2f20345cb41afae4f35530936c1b99137a3370f4f1c9eccfa81bfa3749fec4b1b0672b50e970c621ba0a66d1e775bb4df0674f587c938a29176c603318\nflags = WeakHash\n\n# tcId = 28\nmsg = 37333434363334343235\nresult = acceptable\nsig = 669f3256203b4ffe73ec01c2d7d120ab9c02bab82ac75495dcfa24db2f8e79970673d4790da772f4b16b14f81047086034b3ad927196a48390774aefe0d277ff466798d3497c0e108d51476945e4c324d32145af5d8cafe88bfd6a4b52c8e033ab4b95bc5b5c3451808f019b39285efd4feb6c21708b00aa5bc781afa87fd7475cad673833617159e75051646064d81ed42044791c27e37eec421893fd371d7cd96b462c158560545df3f5862fe97958c9974c9332b46d894486e97c84528a1f55a3d9add429cd7c1a05fb582affc12fa3aeee980a93b8168f284d7f95faa2ddf137e445d2c5658b89a2a230a9a640bbee40665c2bede3f16b986c72ad15b4f2\nflags = WeakHash\n\n# tcId = 29\nmsg = 39313032343039313337\nresult = acceptable\nsig = 50191cd6481555054231eb25b7d44f374052a228036f1e796c2d923c9df9bfd2f881620870ee4d7dffa4637e570d6055345c87b61a2c8f4f3b536d89cb0379883c99fa246e3ae9c6a157770767bb018d702382840e5125ea59bb6367f98c070327d30bc4e17c40b465fb5314e59692527d792c9155f5f1c2d9f4061a3b784741788d92d761e1a3c553320b4165c864e874f24664de3dc6b572dbbd4fdc495431de288389c2690bcf56482632ee34b638aa902f5ea808933aeace4eefbd2b6ef54b47cf2afe586c20bf015e782d5ab952bf7696268467a6beb2f2506cbcbec919674fc785474ee0608c43980f64987ec0b75e8041871ed9a2f99bf4623504a9d5\nflags = WeakHash\n\n# tcId = 30\nmsg = 33383239383138363835\nresult = acceptable\nsig = 55a3be3e5c6c1bb472feb54e2154aef10c8880195183860a3c19dc2f0d9f2e7473b90bb2a9ecdb1a8b144ee27c60ed7ea25838bf6ecd60c2c5dae9213439a9ee8a7a49e970eef3cdbd86f0b259d7ad598230f43e2a5ac0a0f68f947cbded0d20e7a768fca530f3dac41515ec9ca79167de3d800c8bf547163b035a0f3f45c371d53969ebb6d14e5850bab303dbfcf86092b47d41582ede460bf9920c8eee792187d1da134945046d28af67c433fb802f09a6bfa946a8aadba2ae9f89afb530540cbd22960126e6e858be58e6372903698c644253cb5ff72c493b35caa4407d381f96b304b0993ce08b7b0c692c0bb7936f743666db5aebe2afc2c67e3b256fec\nflags = WeakHash\n\n# tcId = 31\nmsg = 31333332313433383039\nresult = acceptable\nsig = b6fd6d2d4ebe5860470aec5e25bbbb02d67d46d960008311d1dbfff3b85048cef40642362104e8e544b914b9974eb53ff1cc12cb8b0fd5b8a924e96ad982ccafc1a80092586adbd2905250452e38b342f7921cfc82623ed499742b2fb0b90d1b5285bad2fa03ab82468488356605b5b7693335e8dcf983f639d82c3168020e27a7e0d06b2af184eb96618ce942c99b49bfcc27a4b6b47c5c07865c5b2eafe30c6bba2d9a97818aa0eb5d2288018103668f892e8bf5ef1837521cd2bd41b5b8f6a954f5c4a50de874b8e00784a5546cc9b7ce8de2ff776749b0027b37158cd5b11b440a52a1820b7950fa685bb43505e1d35312a6fdcbecdbe947672dc2be74a1\nflags = WeakHash\n\n# tcId = 32\nmsg = 34343435383035313539\nresult = acceptable\nsig = 7fc54d8108368eef19f5877275d07e871a3251cca71c63cafb46808748cce240b8eb95a1f218b77954edd2ab8768e3fcaa8c8d3e9b7d678c0d44f9731d5a58f6ac5f3643187bf88ba6023301200936d9414517f1b13ac2afc01d8cb8e011631109f2e8eb66b61b7110c273e26c2066e9384732b5d978c0b2d6a9f0227533e092373fe9d8c2dc33f8253c13aa5730b3f792dd66c6b6b2be2dc5723a470d8da15c79286d1842c5cea67eaa47b906c4f034d1587610d9fa02cb7241364f8862458feb6d8fff98255b4c81b69c248d5f5dd721ee477b1f7341c73808b880a88f8425dff9c27c2bd0140a61b8c64d8dae15c4359a918de42c8a778b8b8e352b624291\nflags = WeakHash\n\n# tcId = 33\nmsg = 39373637303232323239\nresult = acceptable\nsig = 039ca79f8bcf17374bde9dca5b7615b809ac8d49241a48b118c18cbdd4e3fc43c2e3792b73d403062ce800f26955125b7b15beb60a6447710082c6c6bf80d24dbb417a58ab934160b18883ba64f29b461f6f76f833ebd16c38f7664976aaec1521ab6a567b34283a98b8556b4fd346b050ed4b1756c1228f891172a634444779e26798476d481e416e1180aa1709f885fe5c6f091466aba6287f727f26d086618ebbcc2c020a001ad8b24d2ad0dac784456e162d06030567187c25f2e2a023e30decc076eaca92d2c82042dd077abfb788fa03a0daab9714db415822501d99f89600f8d677faa726aa43d2314645b2320588b4cad7208b2fd12d7f99fc37d809\nflags = WeakHash\n\n# tcId = 34\nmsg = 3130373838393031373235\nresult = acceptable\nsig = 907f826f39412c22974469bbb28f049d8404b9397bbb86322c742872d8dc008bd199ec7e891c1a799da60ef20c9dd7573ba969761f5d812f72e889af855b833b5aa1cac338cf2a42d4e0a9d14cbc6fb004866aba01341e9dee8e2896df163996d78c4d30d8c68770e7c72eaf689cc49713c3eb479be8452c935aa44c48aecbb0d3f0646614d36750ef126036828be76be580879961932a74f34bac9983fba0b970ac740f584152c5cbb4d6e3815e87701ada8d30a501abdb62ab173aa1a7a3199ca27cfb179895132089c038e40a273be45b471a1a1f70e7d176b7424e852b3f8c608193a7126588c5065cfc5a7117beb72f73ea8a836c8a15f12eca67f84051\nflags = WeakHash\n\n# tcId = 35\nmsg = 38323137333338363331\nresult = acceptable\nsig = 7b786c0a1baaf52fb84459e92afaf038bfe997c9a4d910303633fe2750b97448a15bb057b505683bc53ca4b18fff1dd90d1416bb8c0fb2c29550d7dda9c9a7f087386776fe65b1288c1f5508ba9468ed9328c9d6620e6882fc818c4ebe832df36dcb5d92837a711ea6f0d20b784235933d0c571e2d6061445ef5d1bc22d43378d2593b2a762114f687bcf59cadb4ecabf258d3e14a4bdea0b215828b2e7462439fcd4cb99518bb5d5dd9266d6dcd459bf36cf32cb8683067918a225c1685db5e52f9a5305cbe60a38df2babe901367eca57f9cfeee2955549ad9b99318b015ae19402a4dad7752e15b94b25b3414cc9be0c13421f31a41d0b1a3e43ce2c1d309\nflags = WeakHash\n\n# tcId = 36\nmsg = 31313438363037323135\nresult = acceptable\nsig = 642e3b94f8c5a0897b5787805c99b04af6c7a2ef47eae10ddcbf58e0f9411373920d1e4d769619f97182db36a9c38b6cd695a1d96daaa9c9288ddd4774f9e085dcb4829f1cd852239016dd23ceb1a493a1294e3d35104f48384acebfa0cbecdc114f445c63d8a1524e608d3f75172782b1c3169d5317902a6796688dd6b0112d0822a5c65a9ab31be84c939cecc4190dfc766cfd29b965ca02baccf2e3a68f13fa304b469c60d7eb49049d78dc1e0ed94daa273dfbde714024e62ba97cfc7b3d32fff034986518e0486124a6d6d33f40474182b2c235306c7d0d5088e7e733b0a895745a4bf4c187d2cdc9d6a8df7153b41f16305a15da7807c6bc69c313b4ca\nflags = WeakHash\n\n# tcId = 37\nmsg = 38303433333530303635\nresult = acceptable\nsig = 5ace1b9ce1f57901e8b8a90f033750f807e52361779bfd97c60f029cff8a70774c06781a2ec5d16116e0ea5170b99d0486eefafcff11f2780d7d04139e28e408a358b48ad55c0d62a357323d3ec759205df77c73f89e991f849114d8bfcfe4b6a4eafd86a9cf43500775b1cf4b4980c4f6eee17aef782eb7f94144ab1e7a0ab9c83ef2860c1429d4ac9174295f5aeeb6a3d5fd430807b9c2ec20e0e2cd1242e496e5470b733db52c857be5a65c604779d9e1bfa5a7bacbf2979f1e533278076f102b14efc321e905ae5285e50e3c9998036718b34cff35ea0c082735ea576acc2f18065c7e05df03d3fee209f1a8df7da5a07af3a4ab86e54edf85fe61343fef\nflags = WeakHash\n\n# tcId = 38\nmsg = 36363939343437303335\nresult = acceptable\nsig = 30a1a557fc9651e08c004b23a5fc256b13f9f9221082f867643dd707fd5513de72b52d13bd1b1b6fd090fd816beb486813419bd9f426f9d4e8ec7e5c86d4228e3bfb899287b2354d5b720db60b68982e76ba2b14ed22b8bf849244c9ae6b55071bcefd4f7063d15ba43e0a5f747bef7373cb2dcbff6d511b030d3e13f628896406955a77573570305073d92c5cfb2a9c4d92f867c1801e63c8addba43ce3d7faf91af464f941faa48f28f549d897f93c074394137203a19176cbdb41bcff260b7b0053508956970e31f65807b40c3b7905da151b5520931ec5c470f020acb306fc6e969a89966fef4ab1c2a17fd5a112e0a841b853dd1449be32a3b52d2f6e89\nflags = We", @@ -3937,9 +4575,9 @@ static const char *kData157[] = { "e93c01a0f4605c7256de93ce1e1cc8f5175838999c734809bdaf8b95edfac0d5f98c3de33ad6399e8207a8015373e1f5ed76e304b5e2ac260bbed23c662c38b6f29dcb01faa4894\nflags = WeakHash\n\n# tcId = 66\n# ps followed by 0xff\nmsg = 313233343030\nresult = invalid\nsig = 5a7e549f99c138d3fa7ede3ad655473f78c3a8de650bf8db6a5116f0807e5df84445ed72ea6a82a8150db352b85210e120818da13d9800d15823f5780b6051e51bf4488654e6a93c95d19b45378744483b43b37200d933775d2f84a7719cdff6dae2e15716c86a9c5a0042a5268cdc7b5e1860c150d85253573787b2839fedf64df3d54c977f63e7bfaf3168f0153e2ef019244e5cdd9be69b421607fef727bd5442ada4bab802ac9fc0c0044eb5b435a9caf217732b6740571bf9f7b1b3fd83da8d4c806a7e2241e37cd0d06abae28ac5a83ae3b2f81f3374dbea97e46c66e821226fc7cf0b0af2dcbdb7c5cff641775c81fea4c8cb9309e989bca04a4a5d3d\nflags = WeakHash\n\n# tcId = 67\n# shifted salt\nmsg = 313233343030\nresult = invalid\nsig = 4975c3fd6358989938633d07cf7bf0121c8a8c987fde1cac405924ab88c5a3175d27207ebbfe42b24404227e388b11d92bbbacbbcf152d3fac0166acb868f908515903e37da98e96aea367c179530a43f78d877cf0838333fcea303cf6710f046513f01d586bc54b42bfcf5dd47b1a01ea8b95aafb4b9406888b3266445f749b1c56459ce4e10a57edc59f610b8b74edf9987c9888460108a11525d0e7228ba5eb9472a0fada1d056c8b0d08efee2761107595c6b221716b6782c27bd7755f1a23aef6cb966a31471921594a1de17ebc7e5b52b933ae52a0794bf4bcd1a792e78a47f019698a37d0d389ca2040c0d3758eedf0fa810041574b32938d290cfb45\nflags = WeakHash\n\n# tcId = 68\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 881dc4bf8b2c6c17e10bef3dab327b4cbb76413a7e5afbd24f198fa461bce9392d31f0a11d69bd67b75fa30ff2100dcd52b8e0c24c91b0196d172ae3fc1d40fb167b2abdce4b83fed365b9d5946a333d0f669d99edf7b8a3a1c8ddf2397cb77bcb62aecf818807d696af4f186bf2e0628ddb1b9d45dcd6eb965dd1b5eb2bade60fbf5b2ae816f45f9e0ad024039bf64c081e37630d6db51a368e92256268178aebd32963a07693f828d01eebaad0fa04e0ff29d8c7ae681be4ec16d2a6bafc1573e38f58c6c2c36a5d5a2ae7718adb1390770d9a3882f895b3f0fee16a2bdc743b0906567b6938d73a666cc33d85142359d40eabbc1da65ae616c7818f86fe1a\nflags = WeakHash\n\n# tcId = 69\n# bit 7 of masked_db not cleared\nmsg = 313233343030\nresult = invalid\nsig = 15872263f8270e7ae9d3127a9b677828cae2077e534ea349070289394d13599392b5f803f8dbfe40a5487223dda2a3c6f30ddc92c4e6d9d22e7d0d2b60197e032f188da35457273ce5518b426196c952d0219ff6190fce905d856d491b00999821ce8d1ea4b18f3423ebad242bc846e0af408f21cddbf44e9e5f5d300d71a3b104eaa2230ee633d2ea44016af735cd5ed9c7b421f322781547bcbb0cd95e4780412f734bf681bb47abd46b158d251ec92056553ac06a59c4ba7fd20bfe50cc58386832b52e548df345b086b5757c4c9f2e133131becc90a72ec6c313e7664dbc922c87a90364bfc746a425df77c9b97dc2afecb2cc36fec415a4e1c6a957b4b3\nflags = WeakHash\n\n# tcId = 70\n# first byte of masked_db changed to 0\nmsg = 313233343030\nresult = invalid\nsig = 6de50a9911893547ab56065d2953038768cd0689a63b0703c0dc99e7cda412ff49eca503671f068635f69b38c0627427f02785b3870c6791add37d436a81538e6fe3dd0eafdb50a18d2f2d97e3cba062fc8343a6dfd448c11997d1c5bf6e1895e09ab435ebb16052c20347f4d077c6c7779297a29e76e49cdf0d10713fce20ab51d273febaffd0679a1ed56da5c0430a90a5fca1ec2010293b2eb8fe34a732ef4679318fc5682cd8796d57be09904043961d5171fa3230674501544e3d5482f510afeb0ee4ba9fd1cfe5ba5527c9c32ff09df579884d4a5b0351cefa07baf40961412348b6846fce5bd6d65a5438821218d677e774828108ad805f574ce7b597\nflags = WeakHash\n\n# tcId = 71\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 1f47ac7fd4585ea42ab08e1002f547dc78dbacda00eb2b3e74d0e46d45ffa8fa7b35d7afdf605b2da772bf54843f15297bcc6f52eeecaefe1c26108c35f9059c8223767c19597f4470de5028b6c522aefc5b61d545ebd6d3312cc092d1fc2a70c524fe0256029d3d357975215b2bb62336c4f4923eaa0cc422a3a088b86f4e0d81b6b4e04c21808a19ac229f2657edd42a6c41e883e69a916717b59fc6980d79884eae5ea918022da28ce2f8e52a2e5dd50d2d2969748c2d97525e672c12113f605b8c4bfcbfdca05bd85285d8fe6d22b73d3b04fafd453cfa7267cefdb5281900389ff53bb4dc3bf0dc366d86912d822410e8f77f33392c0c27fed3659da463\nflags = WeakHash\n\n# tcId = 72\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 7922bfdd4da222918c573184b1d81a14fe87eca0a30c55f9167ad8144ea06a9d22b108a41437b42aa08afac44e7661f7b4c6293897426cb2e960aff163613349b3581cbd3a884ff9898c45c5c213d996cdc1cc119dbcd7e0e99ed08f99f8b69f8aa079cc6d15006697d4a7fc5bcfd349fcf26f43b6f5074db8e448bc92ab8442b27e82643a11842a0dc70b822cf7ae26e90791f67d25a321aec24ccd7553e631bce74888c43d9ecd18e77fc24615ec445b7d7ee83aaf63c0733da25ecd512f7dc7eec6e3fb499d7eee6165c78a4275a9e6fdcb1b962f38c8139da5089565b39c6d73739f84c70ed60e2c83bb4f351d4c87cba2cf6c68b9879e283b9c5e3de1c8\nflags = WeakHash\n\n# tcId = 73\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 8a7e600a6675a06e677ff1344fd53a8dd2b99fcca40c2ab799636663594ac3fe2a510bf1e3ec4ca9dd28cced48b4e8457ed74f4ec2adf31b77ff1bfabd0f80c9ab4688f15630406d8ca31edaa3a3cc7980ba1b760cfbd3ff9016e1f3fa0c34cb59378b0f3745b451fd3e053c8711ecc41feaaf350980532a7db67afc35f00da1f191ff4f66b8e7e27368bc26160f540af784e8ecb38e2dadf4be82e4b761626c5c06efe0dada642eb26f12d1ee96684a5ef8e5feeeb0da9ef432647336e4ec715cfa260a8727aec4a080738086ad26b51355b8bfaf1b135e97d108b36c73b436cc5cb59593a7ce0f0e7483152319fceb37479451eeea098a8eeb0dee19756e03\nflags = WeakHash\n\n# tcId = 74\n# signature is 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nflags = WeakHash\n\n# tcId = 75\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\nflags = WeakHash\n\n# tcId = 76\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e4\nflags = WeakHash\n\n# tcId = 77\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = bd31c7a02691d2d9587ef6a946ff788544ccadd4b2988ad62086792a6bf96c8616b4ad13317d2270b901d0fcd1d880cb8f52fb87304a5258c11b38dfeae8df670aeee7ea1d0d9df8e00e80847e41e5989ed402d44e78b30fef17b5671d3adbf8685e4dc204499ecd1863e1d5aff28a7cf66eadf31fec9236c120add13451522c647c9832a672cd64d328c1c322183f4661d09bda60b8dd5f0328da5420821424afdabb1a80c5d12763a1b0238cd89d0742bfc50b6a2fcb701d824218f9826f4f78a23a2b5aa42ace7f175376fb6cbdb2bad293ba583d4d31c6b8f9029e46b13689249855f505756e00e225a6a45a18769bd8d2b3a4acb9f1c23d3e51882561e5\nflags = WeakHash\n\n# tcId = 78\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 00000bb9473d3a8cc4abd63c6f2ac13e278a9cd1dda844fdbd13e9b77cdd52c1b05ac59126e45d276777e8b1bc423cb261d29675988954c9ddc38bb9a67bec5e03e1e780915333dfe494dd8a4f0bfa0d748805885c389d6f7fb6f786c58d21a468b3589346d70e1153e29dcdb91dec8ac185501efea247bac7c63e3c546ed635e647097bae3b8ccb992701a75d209c439c5dbe8122da616a4e230bce08f541abff854fb93c87fdde0fb457c44b2783568bcbbfbba611d8e984410d360c4ec3732cb69426a94191d5a0cb33149b518ded86864706c723b27228d74836513191cebc790793e5809287b0279e7bc82f266d437d192e98975960d0014dd02e172b7fe251\nflags = WeakHash\n\n# tcId = 79\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 0bb9473d3a8cc4abd63c6f2ac13e", "278a9cd1dda844fdbd13e9b77cdd52c1b05ac59126e45d276777e8b1bc423cb261d29675988954c9ddc38bb9a67bec5e03e1e780915333dfe494dd8a4f0bfa0d748805885c389d6f7fb6f786c58d21a468b3589346d70e1153e29dcdb91dec8ac185501efea247bac7c63e3c546ed635e647097bae3b8ccb992701a75d209c439c5dbe8122da616a4e230bce08f541abff854fb93c87fdde0fb457c44b2783568bcbbfbba611d8e984410d360c4ec3732cb69426a94191d5a0cb33149b518ded86864706c723b27228d74836513191cebc790793e5809287b0279e7bc82f266d437d192e98975960d0014dd02e172b7fe2510000\nflags = WeakHash\n\n# tcId = 80\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 0bb9473d3a8cc4abd63c6f2ac13e278a9cd1dda844fdbd13e9b77cdd52c1b05ac59126e45d276777e8b1bc423cb261d29675988954c9ddc38bb9a67bec5e03e1e780915333dfe494dd8a4f0bfa0d748805885c389d6f7fb6f786c58d21a468b3589346d70e1153e29dcdb91dec8ac185501efea247bac7c63e3c546ed635e647097bae3b8ccb992701a75d209c439c5dbe8122da616a4e230bce08f541abff854fb93c87fdde0fb457c44b2783568bcbbfbba611d8e984410d360c4ec3732cb69426a94191d5a0cb33149b518ded86864706c723b27228d74836513191cebc790793e5809287b0279e7bc82f266d437d192e98975960d0014dd02e172b7f\nflags = WeakHash\n\n# tcId = 81\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \nflags = WeakHash\n\n# tcId = 82\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 3598f87916b45e657df63a839c7e544953c0039477b396a276d8df752b0a98192a10fdf431033353f8565c6de1b268f4ccb44c00ce760c67e97409271c55055b3ea885d742def2c6cd32f5fed077193d12bd48d78130353ad4aca34d9148bfe80d8ea455c3ce4b24f70131908e1947feae311e29e0ae9d1074ba73124568468e34c8b073283d16359c530ea613adb4de2ba94ebc470a57055571ef9f575c068e00de09b6d1af2051b93079ddc683090d4427847b4b9ed63a34a01d9aeeef00524278ff54b7d2955ccae5ca1001ee7588f5a21166dde7b2941a6136b38d374aac73752bcfd3e700066b2972c66cef76a48d81811e26fc7646974a149708ae2d21\nflags = WeakHash\n\n", }; -static const size_t kLen158 = 59654; +static const size_t kLen212 = 59654; -static const char *kData158[] = { +static const char *kData212[] = { "# Imported from Wycheproof's rsa_pss_2048_sha256_mgf1_0_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5]\n[sLen = 0]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 20081f8894a1330c4d503f642880e3c30e398fc6235c24f1be752e2d49cd9493ac0cf999e275c4f89ff08f0d9ba4e264a332525a616d336bd9e822f41ab3f4fae2f48ec66c2e52642ed93b7cb944396fbaa727cbfdfc1f20aace99a6f2a74475c338f8d9f22a38cb5bc51752076503b3aef1e65e5a8f8583d9ae7378ded038cf516898ad06beb90a42b85764526fcea44f74258fa4efb1da253d337f65619181ceb832dfe285ce78ae6b15f204e23bab274e87445d9f5df97f41dc8e3a97736b62591d075744b2552f90bcf1b1393e1e7627ef1f985f2bbabd52e43a35d0ddf4c67126e391f922ef7b1bb1911cd6e1b303cb2910dd70672bbfb62ea4eaad725c\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 4bf16f098701d340c438368e658ed8904d3a21f7714c02440d7476ead132766b3d578b325ae752f906873af1b795585a2a0d0e6788fe903321b2080bd0dfb9de42c3be41aeff37e32defdc0a75f12adb5b9de4d067a920a720cb16cfaf56d7c09d8ef384a8aa106545229b540c52b49ecc9d6d14ea70480642b9cd0330efc005502e4c38b96a36456447ce2133df78854307010ec221305dc90570252321e06c1bb01d75100e85e68326fe92488c0c5e58524b10f8ec7458d887cec254d39b0bef921ba31fd5a117977f1945fc04837727456949ffdc9886f21071186bf32dfbd9c3cd6a2a00a1cdd5fc3c22f4bbaab92aa85116711f1c53754bdd2bc384f2a8\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 2b3155b14971f79c9e3294723c7e41ded41af709f6edb2c19f3526584aaa1ef2de2e7a8dcaf5d7c3239f604c421656dc58e8b0852f7a65cd557724a9b2a17cac38d8020e939bfefec5dce0d8993e75615b974944e4c4a811e40db63f13d2b626bf26257a706a7bedc863d0100b676ab70d4a4f6eaf4692e0b69ee4426cfe7cfc3e92d93bb804569883cf31fb282efa5a81ce9f6d9f0ed79251ef2a0b596f80e0eb96ede67e30457a07655d777928b898ed1679046673e489d9c6305dee05abfdeba7357099f9cffd00735165ddc39aa7355b10a8b8612dfa2f836fb9f5f89f1407365d6b39a39e89c6647ff9da5fc6f960306686a8ed8e2ce12cc7fd9870d576\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 5e91b5dcbf02d6f19621d41a83dc8f15ea83c0edb83765ef029b0acac2e1ec8918b1d2afe1fadf11c48d27594cb9c01fed79d90e5d5a8085c438450111aa7d9fa39c2345b14fc3c2cb34128f86db5eb00bdf8dfe38d61f29a41fe31342e7aaefcb4b122eb5d63c2f5c263c8df8450e9428ffef974d535818d51dc03a7d60c8b2d16c999ae46d73ab40515fe601d9b89b1d09c6d60cd51639a97c1d211e097609ba5e8c319c6fbd21b34a634ec8fb8971c5aae21c70b847a4539cc10dc314ddd8a9629e8a0e51c66c0cb61fd1f7228c01c6769190abe9bac9a3897800050014358594e0fb20dbb458b12aa1346826cc9f7e9c5352b073d62853dafe77c848cb1f\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 501c8119a0f8aa2139ef5e05adc65384fa389b9023532171d514651ff48677aad546326a2e3c02b39ed84e5b7e4630604f2979c1fd7bf37da8e0cedcaecfbea6f9c715141a1d052529d0d0fcd71eb70867e2704377801a0ec721fc59fca9d8b1b08cd9ae3ab094f5bbe2faaf3171dcf1712c534bbc7ea802a2a72d8cebefeeff1530e4081b85a42ae38f630f38c1121199f2156e267ce2467f9b4853dbd29dd999aebfc402f2a0c33b8c1b8022941e754b7a187df4c59633dc6e76cb3200e34acfde53a386647833dc2accf244726fdbf440cd32503188a291e5b0678aa729b539c1f5f97e7b788c0c20b88d90c90a3bf33300d181b9ae797cbc76049b43be3d\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = a17d67937354c7fcba18dd5383edbf2f0868ccbe0a316876fb1c4fb14e7f4c048ef5ded5d01d02556cff0c8bf081bd09c46ce4da156e9810df195c5b65ddbc3025b84f91047049f205341ca8dc55e440bf8d9a3e98c231bb74e71be019cdf451e962d8b7e8e6d766d3be430c7596ffcafbb785e5fe8987ce721ae228832c8b4fe0b0071b0e5c652856f785695f70cbb3c62394a8291ba5f587d4fd7bb448649a72261447aae6a2b750824d400ca402543c8bdbbb8e7c3b44cb7085a83392346abe999ea2a5ea15e9eef6bf08a88096ee4e532369f0059285298b387a428e5e34ed7296e0b53d34c5e23f0d3c12e8a2d3132672a655c7048bdc0c69b36cae602f\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 64c26d43b028f284e9667d5951e70c75e611ae2ab876f66ccfaf09bd54a26dd17983d993bd4f5270537f4c4b2e48695eda28c8c365486b5fc3bde4049dcf6fd722e634fdf5571d29b1e156a48b0c706d96155d86c20dbbb1a47c7e54efa15b25d76f502b3069e2514f89d9bdfda9bcda02301c58e2173cf4f3dd49d8415802c11aed78f031e8e2e50197443e5fe9ab55afd8deeb7b5db8ba7a7b9fce6b7d9eeab9ef25035742d076935c059d076b4714127d408c9428a90cb9891a151eee8de7d0cea32b0ad2d8ca4abeb0521b296b5ac08f7c53d5c85e47ed828e0c11468d6cb50bea89e4b455936376bde9f22eb98b3e2395eedd05d1def38fd5e082ade3b0\n\n# tcId = 8\nmsg = 343236343739373234\nresult = valid\nsig = 08a900c5c0cf38963b8d47682cc7dae9d3f0a78e571ee5bce658154248b0084ab96a7ab0ca8c6ad8d6fc105040c9de8f8df61c1b6be59a5b899df586026e4b3ac1531ab09b5fb5026cbd252c6a548fae9ee881fa382d98499fb88c2b061f560e1daf98145705054fd0ce66d8fb2f64ab160f4bf1ed1a54cf69382afb75c71cf4c38bfc1603653af35a7ab1ab7268cfbed88bd4e779a8811acc947a21b059ea43c19786f370076360f4620a486d6e0572e5c6c796604736acc5b41c6da7ab2a40630bb8bf572ae96c9bf293580021d5a0b42a196c74b80b55225839756380305203b2bfd7525618b402d5288da288bb3d78deaeb26fdd432b2aac746c4fea8b0f\n\n# tcId = 9\nmsg = 37313338363834383931\nresult = valid\nsig = 29b1c67e4be642cd69e7f38115db51d963a54260a877781ddeba5fa6ff2fc0da182f8923bb9257e92989438392f047943f5769ee057c7162c71cf2c0147ead670ab9ae2c1fdab604601a2dba88483b2d3b1dd530aaa17f7a056f1dee49e0b967984506bd39f2df29a06d58f159465973a0fcf1eb5890464863aee92a4f3938742c876164ef95cf34753e9926ef87004d207b9e496922bd00dfbaffd9ddfa216a4b7bffad0d9608e0a2e8d22e41a514494683831e25c24f032d1bfac19d193c4b343815747a254f026313a6b554085921c6a8d0b362a7e75f6419215a5b9d4b7b872cd952f830426462a547a475ed3696bb977223c1fb5aefccaceef99689788f\n\n# tcId = 10\nmsg = 3130333539333331363638\nresult = valid\nsig = 12a1cb80d9ca2b229f85c7aa1705abaa6152b3fe1c6ddeadde2de56f49cb5d5176c91bf9a12a12372753d0b657fced52a8c6ae88cf6e84a358b996fd06ed0846dd685b800232177f17d72da5e817caba8ec9a1f08ec7e015aa2821a1f9777ba6a7d0950449254e5bc5a0bc63f7a6c797fa5b2d30e81704735f8dbbe1a6c7c8db18c142b0861f8525b66e4c55090377b08350001b18cd27f6e1be8d43b936883f7e057016b78f6f810cfbc19d394909040844c9cdc9ff5c8b37327feced820f3dabbc1f597b2ed353e7bbd3d315e9e02124f98b014be827c635e13f284c1dd5f5457129d2ef249ad12659cfca95646314abbbe090e12ff4480a50e393a47a19be\n\n# tcId = 11\nmsg = 33393439343031323135\nresult = valid\nsig = 7bed5bb43826841053d23cb2f574c687be827e9968b37af248db451efcb818d0bb8975ddf7407496603281c5719aab83afb418f496d8cf26e91c56974e65b382f96a206995dff1b57839f7208e338e86358cccaa30cff9677ac0a7afa48e8ae3e3942e36fa3fdfb47db4295027e0cc4e2b98ef1db49519b316ff4bfaac246391691c7705acb89923d39981388286c5969bc42851788872659019a3bb05a72fe815ee17dd0bace92a934683e019049669ef285625b0bdf9935befca3a0bf6b4154d65b62a83597abfdb0ec335c2cebfa627918ee28d64ef0debeab27e9efe", "dfcc557789f44d1e57127b066a221e11f4c0b146293d78d72a5f899f954b5dd37c1e\n\n# tcId = 12\nmsg = 31333434323933303739\nresult = valid\nsig = 38b09eb6acd2d2f0e083f0bf84523a475fb5519ebcb8a5fc2007cec2ca6f01b14e4332acd935b070140cb241b4255fa097db2781b572866b55aab5684d73181b4c911ec6e72b3c267c09469737ea36eb2aeba743c29fc4ff0c82b3002ed8daeac313d2ec4f7d9e707ec334f0228852eae8d58c27e1fdd1dbf8d15b8a7b0f824eb4f2c0191924749e2af4adc0a0ed41978bbf390e31860068aa8db5d5c7c7e86b0cbc9239fea65bf0d9b0a4d7a7058ce6e423858d3a0956c3ac3af7f408c7926ebf86d47cd49de364f90671afb52bd7d17aad00833ec79e43401ea2437d0ef7a89ad35dcf884121bf91ac17df17163ae19f084398ca3abee47db7c111c81bdad9\n\n# tcId = 13\nmsg = 33373036323131373132\nresult = valid\nsig = 495254a0e2eb9ca9f0fa281cc7ee5031ccadd0ff52a1c77dc7fd027f54319258dc0a4e4bf98d13711a4d9ab0c1ac8d67f98c04747ae6b9ef95e67c8671d7d9a2a2bc5e58b1b863525bc10c6fe65388590b96f246c58d118f03bc673b87715db69385907b5ed7ad576b452361ac8164f9eadd250eb445d697ce7c0bb4360c65868a8fe06101b56f4f7cf82a9bc78254eff974366f2ca2f7a17096b05b9bae47ee572eb60cceeaf1e7b484e90b5b0a8ee6f1517d1e694d23a2f9d33ff47a3acb7c9e93a6fb9ed2e994773caf5a8ed3453554807124fc4a4a19fad88c70d5d5d90969e19acd4c1f10b87629dcf5de6a7441f47ea4cc4b84ca6ff43e0905a73083fa\n\n# tcId = 14\nmsg = 333433363838373132\nresult = valid\nsig = 7d0aee24ec62cd2c6238e49dd589ddcc804b5122f57ca8c2d3f7ddcdf1503c3eae8ae192a0057fca6ebfb3231cb9aaa380bf4509df5c83204cc61b4870e4233616ee7097507222c22010c3f34b6c75e4a341920dce40e4cfb72206f00dad39cd0786427575cab19832b64ce9dd45bf8c0023b5b007544c4048eb06b0a73e1583db64b9ae70ca88a7a169953cb207acca099876841c6f0ae9a4cecdee900d2ef1e5559f8b496467733e44bdc6ce8f222fce5e99ae3bf2ee9f6821dee0f1a1fdb072e92404e325e06f813d70df6525e76f0ea5934e53ca6aa12160f6a92dd9d1f5a4a61e47f3f01f297f0470c343df4167588b81c5223908b68c4e2380d95fadb6\n\n# tcId = 15\nmsg = 31333531353330333730\nresult = valid\nsig = 5d822177791faa3beb1493af760b50f62e78f14b3eb278679d59dbb8ff0eca8b4f4f90124b830c8d635e90b86de97d92212b1e42aae57cead0650e7e9204d3d204b43d2e6376092d2b280acd18398295650dc94f74b7fa7198c0868890078422e2ce12d375986ef387a82b188a231784c86e85ab0c630f7876c652e4f4ba9a4d4dc3ca70316bbae3399f82c3e4e24983143baaf4e176c7c0ec1cf908eff9c15b3468fc7a44f6bc077cc3467e4ec3a50ba51858ac9cf3cff0c99ce5c963ebe5341752db2cb6ed5980544056d308c7c74fd14985a414ee61669bf4abf48767071cfd0c1a1df84b8dd4dfca74b342ec820aeb73a5eba0df78b85a568dc36ceea5b8\n\n# tcId = 16\nmsg = 36353533323033313236\nresult = valid\nsig = 978c8852ab3a09c6e28f627cd917927353874cb7b2d6647f3f5889ff81b048f4a4c6073ae6d99bc7354d9e45c805febe5be5dd3f95ad14513119169a6ac7a6a5b88ead2171d999f199b324251566066f8d9a3bb51a5b59c799858d459136341ab774480f059fee153bc03e37cf676b1db4abb2f7979554fb635200ce1c53448e5dc397be13c4d8f8bc2cf2117a0c4ddcb08926fd5a1addd193d0c1f2167731c73affba2c7437443d8bce828540a3d42f03b590dded0958aa4fe48d66d3dedb0697f366b3c7ef9bea8c2b5670a31c41df21828a3a481d9e42c93ef0b5cf43330e6356021893078179fd857a14c437d8b8c66d4e4efce1369f6945c6bf878508a0\n\n# tcId = 17\nmsg = 31353634333436363033\nresult = valid\nsig = 132228bc781249b547b2543f004b5807c05f6530eb685a0a3c6b7ebe5c38ef39eddedc5cf3f98f452ffb202e30dccb8f14c252e673473ec7bfeb0d9cb16c2d88ea166fbb69eca16f7e0305e054f158ed24c74d02328730488179254ebd63972f2a51c45f274939d89bcbad5df3d3961115392aa483beba4f00e55531550f6e167da38519273b3d16555dbc286979b40cee6e5e5559cdfbe6bc208b53e6337400821c43646f940fe624466834b335b3bad27b8f298dfb4a1d3e6308a5fea77fd5347abbd2ee8e708ca2f8719cee6ffe9aa91443fc8ea50417d5f546c223fd07a587ac547a2e4b3f686b7034c06453db15fde31bd1b1c76448a3bab5d14c7ff94d\n\n# tcId = 18\nmsg = 34343239353339313137\nresult = valid\nsig = a04a78f92d6693c9470e7e88690e40a4ae8aefd0af1845450690337321ce5b5e125f981b768e9e0a8a4a37e687a038da1d2c21462b962b3cbbdeb170227fd92f8e22e99e6a183ac68c0c42708e369559cfe7a1bc5fd64ac71e8ed34ce70e86336503028e6174b3ff2b9076f4b6b84f050fe36ac45a0f1de677b78f42908de140d1f2a6ec887a4fbc795f761f2f9b71d45de9e6ce7820bd6fd1a53f0c1516e3df5b31486518b767ab554814ede6270b417d53480d82c415d86d40355b405341034da2949cdd7598195975236e264b098822aa8844488f16fcbce076baff03a9aef6a2aba155ca14fa30e0efff4c968eac265760dfff2056f6b1079dc29316b629\n\n# tcId = 19\nmsg = 3130393533323631333531\nresult = valid\nsig = 221efc61ab6dd3044cf77780d379c01af65312951e5ea5bd5ecfafa5ef55c5a54e8bcdba38a7b12753bf049e5aef8f2b71796429ca9350ce820a10c7042dea4beef196ed5ec3a34cfa534e711ae8009631a6a3c6d87b25af090cabb2c80e14321763fe1545bfca78267415fc89878e968283b216af23a9a5e675028e62e1e2df117737c773d832c705d3ed36e680f1e3b2ecf06aeff69e0072f951a34449b4134e9e139ffddce8c38b2ff0d20a314b45a9345e3ae6e312a94673605e5ed8693002d60629c60fa54469148d5c50d80ed8a1a0d22e4672f9f3a2eb85d298928e4fc333fd1e0ad5909e65b8fb82917415473f28a17a618c07903e8acbf8015e1c81\n\n# tcId = 20\nmsg = 35393837333530303431\nresult = valid\nsig = 55b67374c9ef2ae609f70bd1c805f5c092278e8a2e45f049b949bd57d4bed44dd9880cd59896de266e3a5294f29023a7fe376bfdc35bb92d542f28f7efaa37d4f32c297cef38c723b27cd1fc0e45f6babb61a27547b37a186866a9c725a0d4253e35befebf4f47aef7cb1c4b35419b6e024e0151d47c0c49fc3bbeabeb75f2dd596fef0f8c9c275f6058b9130c58e0266ef12e0233c6d16f78ec5ccc1e8c7e03e3bcf12be33317dfb660cf6d3851bb2aeff5693fe1a6e4b644e0fc860a3d6c2100009f29c632fd9a579a6bece04ed27baad3c5d62b12ba30372e5d7bed23702c146f4a644a6ca1bc9b23f29cfec3b47f7c92e9fef471b9e2555700ac3c2960b1\n\n# tcId = 21\nmsg = 33343633303036383738\nresult = valid\nsig = 74af7b301b5b480ab70b7af2decd155d7c6a280ca77663c276cdbb702f7843fc3b0e3d54669fa9b99093f323533f3ee584483c83fd2f20d2d291ab8482435fb53dfa19a898fce36f470951b4808ee4cdeed273546db4e6db79cb2a429c04c6e0e7661f6ee84eea57981797a298ee37ad2661b002345afc0fe97c6b2b955efe1d753f3e26533b43c0ee4881e6e7bb36bd56f061bce340a9af0a679bb29f10c3c140ab6a5d3fee7f5ee90201d335a09cd99d71c3fc4a890723f1992f18ea3fe672ab6556140fe4ca5b16b168736d58ca8b0e2be364931a1c2d63ebad5fa3a075a889ee1c56d5c128b151ba55a0db4139973143182b6521962ec36a81975b0e4a7b\n\n# tcId = 22\nmsg = 39383137333230323837\nresult = valid\nsig = 3ed6a556e0d26350f61ecc896550888481a0e4fddc0a8db85ce3547bef67d5a4dc8ec653123b8fef836e6d16187c746042d8eb68310545578e7aa69d676e2fecbec00567e67d9f90bad6ffad56f2ceb90d06cacf8e7360439542a6773e0b25b15f385f356f6303348177e662b6ed30854dfd40b649e98eb9289e964e15bdfad7a5596435a2c2e5f849431cf14d2b3549691e642d5dbadb128f663fb06f84ae233d8bd81fc7571970de9c5a14854ec03b3b424aa5091c0da9a25020d83ee439e84898411e977db53a9bcae55985c218c1b3d08a964593774f9120aea723683f8ebc9f095598a1312259bf1e20ab6a79928fb22858572bb11a77354383713232db\n\n# tcId = 23\nmsg = 33323232303431303436\nresult = valid\nsig = 05d975ccb92859e4322c7712119877401618268ba486a05a525ce5fa879c5b8cb2e38171f1b8c5badfd2d32b276767389b011148e994c400b8dcd2e44919b20fdac75ea3c5bd2e1b488d285e974569932c418741da41ab229dd65ca09cf281f42e231c8657623dbaaf7b5d875aeb7dd4aea1fd15fe6a0b7effff66e9bf979e70b0ec28dab260ec68d679b13e76dc1f0a82a0c598b3412cf6a2f306e8e5107698d3c54a7ede188ff396ecf7e153cbbe322e48de7fb4c8eee3cde0cd35615779ce24f85f550a35d3d31a6ada6175dce6346f2b4c7ab0d60d4a95500bc54eb5a1da6028192d5a5372f48dbf704784db5616fc1e690f7ab3be167b5328d487893c3a\n\n# tcId = 24\nmsg = 36363636333037313034\nresult = valid\nsig = 40f9b74051d6a95fdaa25b05598b422eef97852dda217d51b591a36937af45ddf5e06f3eabfaf17610e55490ed3e00d11c8561f7cffa25600fb9ef7a5114399415a933eb6811ae2142351cc0621a5d39ff452875b1a669c666c606e4b817975b966635811694c8a920a5cbe8300df00c0ae0faa1a7812912daa081c7204af6eb7f7152ec82b45b504dc3214eb9ec5b322c58771410dad121f5cd887bff9976c38c3cc9b1a44d3683e95c76e6a83af6c650cf6091b68e6ea2e6f28b11e0c664ad132ff098d0cee65c8f0b436328332ca0bd1048af8de618fdb494148af8d2d98ef4819fede564476a52fa2b7d176e57f0fd9e499a215de6b7737278d7e6d95a2b\n\n# tcId = 25\nmsg = 31303335393531383938\nresult = valid\nsig = 94cd1d5b54a88649f920e1decf750e04c8630e32d71810016b98818bfd0d978bab2725466c1a826bdf4ef42b115b904e328ff1c012c704865640af61aff3f7bb6a3fd667ed2c91ebb93a0232655360807002c2f05fb64c90f842b7bec11dd1960bf85f2167b397e0852b790c7f193d6e7f264b2a5024807dd5d76d9487ab0e422c9216c693aa1709e56b3b61719c9d6b35f510a721d9471f83ca1a6e46f7c14ad0e4ab4f2513a389e70977b3d7d9917a13c25c1a439a75185e9aab64ee7576db623e514283b2d94e105f8c39acdfd853817275e90541c67812e40a79fcda5a2d32d2c400d1193f1b756c98e8d3212575dece26c44792fe3fbce5dc56d0248c5e\n\n# tcId = 26\nmsg = 31383436353937313935\nresult = valid\nsig = 17da6446874a87e7a7ae4fb637", "c191db1d13c20befdc726c8af26a63b78bf0c998b82c25a125674a50717a849ddf004ba0f1400921c08a37a0c56a728322a2069dca4121c0c47c437e7a16cc3592ad5441a157028d8cb6cf7ce5b8582fd525a1c5face82204e01fabca60243022ea4d58126fa33170a6053ce2fd53b46b165d105151d5a3ea7b0f2f019784ae87fed529d771ba5a6a6ab60934a8aef5d4a4f25e5ac91b64e47aee095352ac6a9f68f5eead836730c08a35395e0a2cc1aab29b7e1d5ef238e939e9847b90d7228b1239749e79c07394acf13aa32e349c23731838b241c20f7ebfa627f96dcdf395b4f773c74347ccb966ff8a3122f6d6f1192eb\n\n# tcId = 27\nmsg = 33313336303436313839\nresult = valid\nsig = 0169a22f82d7c1fc21caf6131d6a4002578212f3beeb185a832408833bbc246f05222959e90849bd41207d6d74a48e084b6eaafaec78c9c0aad7a9b24624e8c4c66bec56fc86d2ec31762a7498dd48207a16b315c68aac94662013940307e6f6dc1d2d512885198f288adbd73b3109300b1f03e137b904f743ccc7b90db246c7ee7b18c1b6b2ad5f061496f8cac534b58f161e2778e8f73db6f455aad62f599cffc8ef16a462bf380e0d09ad8295e7e9a7bafa1b7fd84166dad936373b323b525a111d3b34e5f918358cec48144a99f2c614ffb23f9a3c8f9a491f8a7fb0825dcde62b40b9b56fbc816e21425fa4b0621d215fa019d293107a547d55a1f552b9\n\n# tcId = 28\nmsg = 32363633373834323534\nresult = valid\nsig = 78b2098126eb13ca306f31cb64ba1afc17e053580b68184a029d5ad47ec8029474a64dccea67ef1d01b4f95f1c2b416d312437139ed1977ec80a9339bf925cd2f2c157dd3accb47d1b85eaa43a7f2f6083e85084b05d80336b2d0435315d0124ed155be0100a98f75b9d7596f3799cfb3a1b7e2a8ac3c805da8da5844a27b04486f80f1ddfd463ba9d01a850096a600346772d8bbfc73c9932522687b296ddcf2892f37b2a9b90be7dcd9081df2a48014f5bdd08c114989a4920ead57563c4615874f3b7707607d6257614847bd99429642a58a305383c835a1bbc2ea8b443a2aaefa5c8cde459904016ddf381c591dc238e10a8249c7e1caad96b42ea415f7d\n\n# tcId = 29\nmsg = 31363532313030353234\nresult = valid\nsig = 37ac7d0088f21118f5f9f834063d56966456a9ba840089a1b1805fcfc808ff22cc9d7b3b3a361cbf1c2f96c62f694b47a6e9a19f2adace721200a52110f34b9c95f45fb4af9c250d0472018069d493847fafd468e8f50b4d2f1ad97e10015862ec02822b1e17dce3da1715f6f09fb89b4f7d0c35b8509445f770ea6ec325e933c651dd4d75f5702080ec3b03c48b380b1f202112eac8686d3e6e37f2685a6be8b078584533ae66855cfd6f6b758e4487bab19a65a12245a6f177fbfd861c94c5d30b6fbf750d66b682f98e34facf4aadd67b4db4463cb08328d8d59357895da55f1736c91c62b2634a66ace8b2ea44a86e5dbc09aad6998524077a68b9c1f33c\n\n# tcId = 30\nmsg = 35373438303831363936\nresult = valid\nsig = 6d250a920de5965ec36ab916ad585ef21252355f0629b084a119f7e9b73d3de14256f612fa92e3d658efb3e53343c0edb8b7e55a704dce2af2f7d861a404d1554fe19aa9a6b9aa8a13897247a37a2d973cee58c3608c94789fb8ac1ce05d6f0c2c1c7b8baa7baa1cc8d77d4b7e911db371038117af95b1e240ab317031bba83686b8ab99d75baabed4873fc72884794b3a3da905da016ac292622b8f73e446f46a992cad8d2b9c9b4d50381f58de58da58a25ae341b11d302e11db18d2bafe673dea1093d67f7d1e4919abbd43c0c0008b8eab089ec6bbcf126fb9998fa8697ab48cfa5d90ae76eafdecf18037fc3c8c5fba02e37ae79b29665c051e271f269a\n\n# tcId = 31\nmsg = 36333433393133343638\nresult = valid\nsig = 97a3e342aa73973a4b993873d1741dc9ad916f5de63d78f8c6a7f7b2247e2ed62a76510d0e25e6a27ea0e2ea8a5d8e38381528f913458bf6caeccb73fe2e2ae3830d0c3f463859bfd55fc26e5bb16f95a1517f445979265fd09b17033297aa6d5336206182d5030396176ed04b0f6b86a9ad9d180c17f7afc6aacba9416f0a67d5f7b8d93c994b719fac075389f83eefd9c9f3ade146632917c26f622a1313ef470f257f67f9fbfe67245ec253959751a84ae84c7a0c06129337645dfa36c65ceee8fd1ccbd021a51781f4ab8398af3344b0a3b9036ed4b9d17f7c572903391a64a8c45c1fe5ef9da607a0a7ced1f97a8651b44ba4f037484626bf770d1765e1\n\n# tcId = 32\nmsg = 31353431313033353938\nresult = valid\nsig = 6fe1f5e3f11dbac400043505b0b331c32c28c37b4d3cfd9bbf959b301b3bbc752248e052b5fc3fd6c80b2a8175440105bf84904d2fa9ea763a31ba532f7c528e15967f4858c0a67fb9b91b0ed43926f3bbb90d970e8d81a3d2380556e63efe0b49ff702db5c1835adbad43830a983fa891529732104e60941c03fc8e267c0a889ca7d29d615811d05e964faa99f81c2bac929b26b0825c35abd7d3a36c09568141a53853760d632446d4088d032b348ef0942b91ebf1c68bafc91bc54863452245af96c00250302a05b24723f7327ef420fcb4427f40d5e33ef4c4820e0a7df57c24814b6ed8bd61de28c65976356a3279d52134753e008f02cd9d27bcb6330f\n\n# tcId = 33\nmsg = 3130343738353830313238\nresult = valid\nsig = 9ae78de184d5b7207e99087c84dacd1d5d510119a25b43155050154c1539a7b44146de65c835426365c6d8778c29e6e7639765da4184dbe09e8f5946eb2d632caba6e31eb2edfc30016ffc4e3b7eed4d2d95cc563c2794d70f8ef60ff3f77f876d82cd075bb2fb6ab0d027ce9dc5f3b26a3e93c8a2c2e8bceb14f9eb45ba4e1095a19f441fee145c60df21adf2068fe566dd7926dade24b31b71f5db3d4ddaf6c4e44bee59e0d3302dca6d75fcc87952cb58555c7dfbec53975c7e1cda803c2007ec1e53fffa363e69613d17f870c2674442840d1005039ecd2106921ab6ebd9d96e21307a80e994ff85eae5349f4b426d458aeb22cae533e46724cfa5f2b442\n\n# tcId = 34\nmsg = 3130353336323835353638\nresult = valid\nsig = a288dab1bdd7f4676d1bcc84291a7784be62f001c5c1a83ad575b15cf56a868600badc95f22954f9f474340d874d3d56fd23a8a85ee3f052c7be5ca653cc2fd2c1ea62f02c0c5b653fc201272d432671059ee279398e5ad0c45e735eb5c03a2ff9c82ab53d1ac9225589ecee80fde90a036e079e45b33b0b4f0e6afc317ad3744dd65d22607cf31dbabeb38b0eb935ede4420a1d8246b80da217dbed5d1cf6a4cf88ac03a3eca307bc7af4cdea63894f676ef253f7c8e1e7ac1f67fb45abd2aeac3ac8899a73867af86688b67b3ecdf9e6380a84b99b98d2dc4e65682558d28711dbb1288a0351cef187f1edda14ab57a8fbc71fb60375e682a53566eba5ff0b\n\n# tcId = 35\nmsg = 393533393034313035\nresult = valid\nsig = 0a5339301400f505424bbd72a88355759ce2b8e43c97c7dc6fc90dc4bd339dd397bcdcd706ae49df8d5f535f37c4275e894419345bc01a15a11251ac2b01bea9edcf093239b6bd15196974ed38ebddaedd60e6ba3ee67ae005c73850ca8a13a1ec693433bba8eb40dcb23f33a1a6fac64d634c9363f276c119d8e7e7649e15fee7c0a039dd41ffd5871592b7bcd7c3052b3daff5c998442f788f4af43ad032f257dd4fa0c7c67f078d6b0608df1a1d3b4948327eded47f9f4ed16601a6e7fe86ecaf9721a4391b01051c00576627d44f66ca5657236e1f5260a31f017c6dae68d17e984997e1892626dd97f41429a914a7669e650182845b2614c77f39267187\n\n# tcId = 36\nmsg = 393738383438303339\nresult = valid\nsig = 8383a989de89656ec90337181cc615385f691622af128860328520625bfaa1ffd2792fcd8395cb8f4ab3986c00e9d43a0db678cf1cd3f130e95669ee3160da36b99eae9388a24079326e0c3e87eeb7fed2ad444e1b66d3072f057167ee967e9dd08dec183c4bd55b07280f74be43445a19aa0659f78fabcf56e4bbcf3927e308ef773ea6324e5b23fdb46b08057a1a63272b9c29a0d0ed59d4778ad7cf2ba576ec19d3d81c869cf762d04260ef805a35055d9013b327013da7a898b6684275dbe5057b833d738cda3f018c100d63848959e15492fade26378f4b39bed4bd56259ea8df023f2c63014fad634806f6a650b5e68fb35f6caf198ed09dedcfba9da4\n\n# tcId = 37\nmsg = 33363130363732343432\nresult = valid\nsig = 23b5e6dc26e10e99bf0405b84347e1cbbb6af4a8d0025d0313561c726de0268ffe4ff7b2e20a96e4bd699583281aaeb10b592e207e1cc5d8fb7d5c2c1d8f034467ca090ec4885e0a1b09dea61a129c967450cdb5984ac5dbc852893afdf333b5227df2f023f37f310f13dd73ecb9c864ccba1c93f6b7c4934fd817e26fc2cd607dfcc6618b41cc571603aa26dd4fc180d5b3ae915418d35d6476dd34d4612f50cca249ff661fc5a2bcd09a806da0ff0463489fc0fac10cdd41d4243766584ae38e99c68e9abffe362894cf5ab10100dd3171c6cf63d93da5f8f6f7d3877cebe64f3afa8bfe78f4436b83f8b845ffd94f9980d58a743856b6efddbbebabd31d9e\n\n# tcId = 38\nmsg = 31303534323430373035\nresult = valid\nsig = 9f8a9abd119e44261097a7fb120fa7edfb77418aa3a5498abeaf17e2453e8be26a814e7cc1a276a351ae002ac8746f630f7da9459d3fa4178f8ec9756fa6debdf4d55814bce8f84eab38dfa0c98f81448800755d08c3b9691e837a2aa052b5ca412e2bb8156e4a3aca3d35c9bd447d6b5b532905c60e70dd65f6c79a28f236e3a0cbe4f734b2a3b22fb733e45038820e087bdd429b5b54b84a6d1210788bb558f0325ecf8ab7f4641bff09564f06af6d792df988699550d35f2197b4bd7cb7eaea64341ce82391ab8798c1ef6be8a7ed8f2e1dcaa331da2844c06e3e056ad0ba22c4724ea7929f57274fe5a2c462780b190d5404c68c823ba233ae35026a6e72\n\n# tcId = 39\nmsg = 35313734343438313937\nresult = valid\nsig = 227fb42cb5c3d88b8b71d1a6522bc5f824b2507d2998a94b9b972cabe4ab46eb47cd106f79c17d4a0c59c7b74b5b3d03180ce155a8bb0920e987fd2bbdd64d91ff3f57b5dfbe57f3989ce4aa9d9e3efafc501c4437a0b14e2983262a61b15a1000888ee1482bee4a1e6afc92bed17f35a32df67fad28979775cf0c1edde006919566cfdc3657c9ad2a82d2e68a11e23f01f4d8faff873f5bd1609e3b901ae13f8a599d42d2fb5ac9f9707d730921c5981cafaaed86d370bdc7585bae3ea4002c50c96b195283592c5d577c53627d946afa48d10e8c89432f50210f8e0c99a23eb089559390dfeb472db740e27ca255f0764c7a575d3909c24308f187bde90fea\n\n# tcId = 40\nmsg = 31393637353631323531\nresult = valid\nsig = 49b8d35ac6093bd9d53d5acf6af1a2f294c13b0072564931b8e69e11d7fbcc7ccea44f5e52f28b63b09dedddd5766515eed3ed3d595424e70846ba96b9bd12781715ac7c405acf97a8a735c8a9d274b66a54f2a24138fd9006b2b5", @@ -3949,9 +4587,9 @@ static const char *kData158[] = { "8f5f616b3fd413b310fe8f50ef4f721fc026a6222f0d9113624cf7d481e79e788587ee659e81296eaa438ff13454e36ea50e9f038ed2a7548a8d169635c3e15bc20cd83c8279d16e6b0edcac2e9c72b9048dd7fd1d298e414c3832236d612af3841e426c74f20484ef408b19f22449e701460633fbc5155851e812e886cbfd6218bb27388e20547fb4a48d2e0f9a284f9bc1e9391b28ab7f3f45ff5aeb6af12faae437361877d04e2df1a1057ac3a680e5123ef\n\n# tcId = 83\n# all bytes of ps changed to 0x80\nmsg = 313233343030\nresult = invalid\nsig = 4bb8fd79da58fd3217661938c90772eebde7bfe5d49fa597cf448019a56d710ea126e8b94aacb45bed81df07ed4c89a9889bac0ad2abd506374d5ebed14777673fb1c51a3f844e9619bf707c9866b21721a75458c100d57b9ebf6ca58aaff1d47cb2d0f26074dc15d0900a11d681bcd76b111140500a51cf8c1b5ff4771176f1dc0884d42b36a15690b991c77f9605ee9c4329fead40364f2b6372812319c0ed4a6a15c0716da9426ddbbee79938bbf8dc3b459bad11ce79c0bae6080a06b6c8c1c051fc37e0bf0546c7b55b2cb6d90bbf4961ccd1adc623c9b9b51912d6b78843932ce04323f8a9159d10ac94c2d980e9b48fc143299d4c830050ace61f7238\n\n# tcId = 84\n# ps followed by 0\nmsg = 313233343030\nresult = invalid\nsig = 9aca5b5fe1369dc46eff908e690ba88744db0c86f7da7e644eac314493ba6a7d003dc5400e1c521c373ede410afcaae8a4ea8e14d1e6c2ac3f39c0bf8bfeb688962260f91058ef9c1a0ba39689736d039ff86524a97d8eaaf248601793023ce6569c3cf15dff30f41e384690ab40812cb1e4414a0370fc39f526abab87bb9a405fd44869069f343f28bab50a1e582d4bced25d41f9fdd2e958177a3625bb59c4677f7f749321023fc9b9b724e8172a4a512743a1c78c3c8b1f0556fede02e9f6f2f851fd31e21f0886a35d12a0e04f041251524bd7838d91657026540e133a2ac1ade52f03efb509c30578bfde272f0d9fc2e515e541259dfc249bf1762b17b5\n\n# tcId = 85\n# ps followed by 0xff\nmsg = 313233343030\nresult = invalid\nsig = 9211ea6374362d77f491d9dca7e8e8d2b672bd565dda1566814670d22e3f211b38246529a5f01333ced70323e6cc4de58e9dee11a90f345fc53c1cb0f0c2287230d1cfc83d33c6158a8730853b5163c825ec05084cf0816325e21ba87f1685197c9891ca3b89d8d8bbad395f7f71b91ef937a1d81bf7497356928b77b10fe270500a731d498beb85490c1d3c4145336d2a8ce8430354b3afcbf0c923b0b0e824adb36d7be69a8e951f64a5b1d648dfd9fea49b59c99efcf015c6b3937d8986100f48022346136eb56f9538b115284ead85196385d91dd414ee22a3c7f40f632cbe565c8d0a325404d0d4905282cf7acc6210a6eaa26f3c3961660a944771b342\n\n# tcId = 86\n# shifted salt\nmsg = 313233343030\nresult = invalid\nsig = 39112e1c8251d5ffe1373e70fac946358b00bae6a461a1af561a82d81ec4acdc63eecb3b98f5f070929dec66a758d4a12cec2600208d7597320ba5db412006ebe76ed593d8b1090e93be21b1c00700e393ddb4b7d7a8bbdaab603087abd2b90a0408a775a4469d4f2f6b34d228da55bb4872ef6dde5282f5bbcdd6a8cefc71c4caf00453e6d6c59321b738d3b21a3d8f0da4afde30c16bc5722ac30ad6bb1f9fe0451ad150fb3d67a805993e506a80b2dea3801bbedb8ff7b676f50ca3fa5b9bd744c00822c975e2ab8cc6a917436279a9e85aea62477ef84270f6efe495ed503623108ca39d5c47bafa3505f04995ec9c2a0e411fed9179c9a9e94fcecda5ad\n\n# tcId = 87\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 1baab34d753d4c169107ff7dba46ec1a4203cb1654489d6fc20d206bb21fab483872c44ae8017b7c07aadb8e8489a2b41b89f9331fef63317408105eae19900377ce150ec89a37b26bfb169a89aa1c71a83cba6858d5b47353e82017f19a6688927768bfd0e75bfcd71a5e1948543907d65bc8fc813436a15949fbaf0a7f95ddf010f298df9314203838a60b39c5bcbc7a438500649950bf28e78f94155cc664ad5ff996e51789fb13038e1757dc19b6572f028fdd8be318ab933adced2e87b569544503916030b4060e231b0265372805cb53214c6f21e13c632ce08031ee368bcdf3eacb3b87269e8a8684703a348524020e820de93f1f334b59cddff51a12\n\n# tcId = 88\n# first byte of masked_db changed to 0\nmsg = 313233343030\nresult = invalid\nsig = 7f04560acea95c8b3df67a74fb2b32d904e5c59b43b10b11519e796efa77c0c9b14beaf1ba1308a65fee50e7862289d46a3cfe79f423e7d9201dfc7428bec7f304228508b7e8e5af4dbabbb3958d1f48dae4016cf699421b7a9a0b1dc1c806a7b19cf65fb7d4465a031bd8c24071b397dc1f6987cddc8b69f5f3dde25fa36c2ad6e030c64413bf3eb39176bc003c909e37d28d5a040c15bb4a73c74c39c4d132d09fd565abd7b63d81115ecc8a151786f6ea50882e50db362cced39702ae1ecc176cece9509ff071b87f142547ca3aab04bec1a7d0c6ff35060420b99e285515eec016ec419caf75cf11af56a395187fe6575786998b6b4348561a0dd68878cf\n\n# tcId = 89\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 1c029185061385643943dca8adefc5666ca039765d29f8baa20dc3cc43981ebe1e6d1f09a617559955437323e50f6464a69950baf23c7463b1b1c6761b50bba89c81299d4543f76e3e4ca4e30ce710a20707b18dee5d2ac9e0d9330148526f193439cb33238ef9d82424fc1287097e7626bae0130b735a22cb6ef08ba4d840b370c9e8658f83267e52b8d56ae0ada9dc5114920f97884d6bf529bbd7c81b2f9a700e4df4c71a8ce3141f9f4be31c9d639619b20f725f55475b38ce36faee929864a5c7793ec26dd6d1c4b75f111feba3765d0d35a272fc52fdb85f2c0bd1bd22cfb47bd0ba58d00af119759e1f4d5763f15cba4e788fc6f8a221dbdeb32c484a\n\n# tcId = 90\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 0594a2a0f3d10857e8e2a89d72df80c8b37977bf2c390087d1df7672fca50d21b7a3b24453b55afee4c6fb2adf83e6b3e6a63db31b685ca956bda1f3074eb53364d9bbb9ad16883b56ceb66cae51712d592e10f851c4431a4f7b3625c774808bf7c694c582f1f20c2f51ca9f781c6172d05201e1e0ad96f7231c2786e039cdafcc4045bb078c2f432d3409dcaf25d8c0549de03d7964606aa0fbda333a0eac26e5f3ba13b1d6dc710c01a17e1a24241bd741d51db4cafbaca518fe32feb0ed5cb916c8c094c41f092cecb7a9cc0818351b5c8b6563bba32fb8e86b4c81f4f57c24a880e91daf31cd1911aa6690c8e45f00dd62986369bfa5824b785c1c56fdbb\n\n# tcId = 91\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 10bc1d1d1fdd4a8f74b17f2c8258078ef5c4f5fb973a2505060b126504c9366a4578e2a333b1a9c580239ee959d17017664631982cb8554fae8cedae07eb7e2fb69cb702db93d948d0d0e4654d9eb49192ef87e92f4d229ba56f165a8ad4769d0c707111b9be90c6cc29cb3389a9ae4d5045d8a69234cd5e57fabb76e5d1869d83cd2f3ea8f0419194cc54c398a288aaa35f765ca8e0e264865b709d5a21c9d807c4c0751f9e4e68c9cdc61d93113e5bb811c2e217f31eb14f010aad77abed3e4305e7bdb1066879237849883c3ef099b85c78352b32374dd244e173edc3824924098cfce9d729166ccfccadae8871266927763ae6a5e750f49b837b60682aa9\n\n# tcId = 92\n# signature is 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 93\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 94\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d4\n\n# tcId = 95\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5\n\n# tcId = 96\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 00005e91b5dcbf02d6f19621d41a83dc8f15ea83c0edb83765ef029b0acac2e", "1ec8918b1d2afe1fadf11c48d27594cb9c01fed79d90e5d5a8085c438450111aa7d9fa39c2345b14fc3c2cb34128f86db5eb00bdf8dfe38d61f29a41fe31342e7aaefcb4b122eb5d63c2f5c263c8df8450e9428ffef974d535818d51dc03a7d60c8b2d16c999ae46d73ab40515fe601d9b89b1d09c6d60cd51639a97c1d211e097609ba5e8c319c6fbd21b34a634ec8fb8971c5aae21c70b847a4539cc10dc314ddd8a9629e8a0e51c66c0cb61fd1f7228c01c6769190abe9bac9a3897800050014358594e0fb20dbb458b12aa1346826cc9f7e9c5352b073d62853dafe77c848cb1f\n\n# tcId = 97\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 5e91b5dcbf02d6f19621d41a83dc8f15ea83c0edb83765ef029b0acac2e1ec8918b1d2afe1fadf11c48d27594cb9c01fed79d90e5d5a8085c438450111aa7d9fa39c2345b14fc3c2cb34128f86db5eb00bdf8dfe38d61f29a41fe31342e7aaefcb4b122eb5d63c2f5c263c8df8450e9428ffef974d535818d51dc03a7d60c8b2d16c999ae46d73ab40515fe601d9b89b1d09c6d60cd51639a97c1d211e097609ba5e8c319c6fbd21b34a634ec8fb8971c5aae21c70b847a4539cc10dc314ddd8a9629e8a0e51c66c0cb61fd1f7228c01c6769190abe9bac9a3897800050014358594e0fb20dbb458b12aa1346826cc9f7e9c5352b073d62853dafe77c848cb1f0000\n\n# tcId = 98\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 5e91b5dcbf02d6f19621d41a83dc8f15ea83c0edb83765ef029b0acac2e1ec8918b1d2afe1fadf11c48d27594cb9c01fed79d90e5d5a8085c438450111aa7d9fa39c2345b14fc3c2cb34128f86db5eb00bdf8dfe38d61f29a41fe31342e7aaefcb4b122eb5d63c2f5c263c8df8450e9428ffef974d535818d51dc03a7d60c8b2d16c999ae46d73ab40515fe601d9b89b1d09c6d60cd51639a97c1d211e097609ba5e8c319c6fbd21b34a634ec8fb8971c5aae21c70b847a4539cc10dc314ddd8a9629e8a0e51c66c0cb61fd1f7228c01c6769190abe9bac9a3897800050014358594e0fb20dbb458b12aa1346826cc9f7e9c5352b073d62853dafe77c848\n\n# tcId = 99\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 100\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 1758eb94588e6fc4f50c1be1afcaa41027869f304cad513b1fb12c2f446d63cdc05c4830a7e3e630da7b2da4f7867cc173bf6420f9732277282596de41ded32e21d0cc31441174da8765f57419c7764ea758f55bc17646eb100c435d1ac0eed6fc7ba6de5f832094ee2f479979765e05ac9976788db3c241a9e32a0da864f0019a87646ba623d63f4411af5dee1be9ec488c7e3e1b231479de70b9ac5f78a17b1f4120aece45f26c07e7bb345fdfeb05e14bcaacc614672a465fc523624cb19f66f9c6c3f642b832ca44cb25176d679f0e05606c3fed022cac24c2bf960a406d48818e3eb7ed53b0446032469047dfed95fc18088c92d91d93722c47f88163a8\n\n", }; -static const size_t kLen159 = 61423; +static const size_t kLen213 = 61423; -static const char *kData159[] = { +static const char *kData213[] = { "# Imported from Wycheproof's rsa_pss_2048_sha256_mgf1_32_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5]\n[sLen = 32]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 4f01e0c12b08625ecac89a69231906edf826380f37c959a96690d046316d68ffce9d5c471694fcebfc6b45534864689256e4fc81c78e583f675d0c94b449647451e81beff01a11a516d5e5ce3f1a910437cb8a3a5096b19fb15f4524a35b23d89cdba12cf5b71aac1047b28c562df7c5542c34ce23a182cf7e0e231934b17294799d44877a1d68ef1b8f073619b7618e6b7c22db20030d98cf591ffc3d4da5f58613ecd5ecfc3b40a1d02f40891ca43695cd4c088b05a8054c89c595a47e274816f35384226f74459ee63e25a1bfc03c360490552ec38343f8ace502f065303b00bc0ec320711b211fde92e57feb9013c3609342495ec0d7cabdec21e54acc38\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 0658c68fe0895646056d9bca422a64fe48813b4e14f0c8c4122e56d345b6813dc6286ffde014617e351c7af0a0d2c0f285def79cb734e1e055a25fa6fddc1c07da17b4b235c637413b1849c24311fa72331f4c0458c364a4916de8619b884d7e37288fad12926fc091f4851686a04fd0a504dbce3db370663a6ea6128fea86c2ca94c63e0d34d7f2c845b5d71d9a5e544451f524a451acb85c49bba7864e0a34a48613a819caf3dfd0d510c940f1df21c3373915be1f3509a557fa4d5a4e9f273e85467961133e2482c0907386454228fb0246638616fc31bbb6fa7c2361b8035994eec69a923f4c0bb0ba8696dfe8b1400c2398d7b343fdf498b1116c8de602\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 401eb03cdb47ca88033e3030f6bdecbac8f5c8fc1dd6a13d23d379ed9a2b309891d13d74fea9d21d159b9e6d8f37efa2489962e24555f56dd434ff1d31ce4f9f5abd3f22cbea8b691d6a11e44efb83e2bca155e6a164325e0fde2a8865afd5c9f51161a9d615f62af7ec2e31b3e5ab649c164490d31d88cfae35b84aea7925690f929a144b6d2f48e8fb894a52deecd1b9a6496990c4ecf1588699a42cacd10c53af350514e4291ea9a058e77f101e32c1c0cefa61d945f7bc931f8bd19e7ba3169358a60e5a8b0123bc3199b9fdcafe8e519c41ba675491a27b85e44ef2d77277c10fe107293c8290186913bc9a99b640d8da041b64f31eab1d35920985f4a5\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 68caf07e71ee654ffabf07d342fc4059deb4f7e5970746c423b1e8f668d5332275cc35eb61270aebd27855b1e80d59def47fe8882867fd33c2308c91976baa0b1df952caa78db4828ab81e79949bf145cbdfd1c4987ed036f81e8442081016f20fa4b587574884ca6f6045959ce3501ae7c02b1902ec1d241ef28dee356c0d30d28a950f1fbc683ee7d9aad26b048c13426fe3975d5638afeb5b9c1a99d162d3a5810e8b074d7a2eae2be52b577151f76e1f734b0a956ef4f22be64dc20a81ad1316e4f79dff5fc41fc08a20bc612283a88415d41595bfea66d59de7ac12e230f72244ad9905aef0ead3fa41ed70bf4218863d5f041292f2d14ce0a7271c6d36\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 599724adc1bae31e84eb6e1399cd90cd67f48b432c63719b600402384aaea9b21ee864cdcf259029180877c847a223912b0647f066a59a65df6c2d3a6675b1450f0b05185cee486bfac56cfded182babcefe60568a6954f026cb2f59002a2f755e9bce49793f280d89822c9bd3a06a7ad2209c3d6cab7c1f74c8bbf4bf374e7ae8a539fccb83a78cff96a4f538adeba0869659d0e9647d98f96cb55d9cb7e58440c4c9d85b8e9dc602e909e29e45f2b82ded44f40e9ceb1292da20063967e3a116f4aeb202863cea523f215b8ec7fc4f6a22cd8652ed661e33803f3fa1be966fa8754cc7b0fa894cee0f045efba14c4f4a1d7cb837cea69e30522526b8a5878f\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 4e68a8375e086990bde05fc4bbde2d368f8d96a5bbcf16d9239fcdd45942d764fc2317d90f4f62ec80059490240be8f32dfc32414a427c7e34be25ed0dcaee6927881e797db97a0341fdde459b9cc915d0a348e15dcbfe1b0780472f52a887faffc988a9ceb677e1cf5638e44a9d6f2532417ed0bde5d67f5dc9229ef1f3cfd9cb46c695738fd006cc62d02f5df76996270223060f72505ccfbdf4e88d961e2e7763705480335148ecdd23d1202c26a963860dc769a43e44c72285092ba7f24d81844e612bf03f9c2ddd4e5960622f71672f4e42b8a8f36c6847a05f70400207471c575d6a960fac1de809118efb52903ca37f12d40f6de74decb9a5b8a415d4\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 8bdd6db90323f3bf26a36a4ab5b92180c96881bd32b66317c4b48c2ba1421f8434000c06adde4264c6ea2d5346468c6d5e97cb13d3cb932e523ac57b59c814fa0397ca6dcc9bec4be1147d77abcd318a6aba1af46ede2f5640da06511a006fd1bd5fb8e04be22789956adc47bbec7988be477150f9b24a07dff51530e8f0c14cfef7d25ca141f512939987b7eb0825633d41a48742bd7f56d4db9733d92ac0f36b4041f51332695f551ec91076da2301120c438eb9ec197cbe318d4571b6b79098d17eded0ca47747a143e34f882ad6e3f490f3a710ff7ec1bffce022027165d96281e593180c67f44aeda9ce6605e6b8e5eac1347695dab211a965bb3d3f928\n\n# tcId = 8\nmsg = 343236343739373234\nresult = valid\nsig = 3a52bec84b5b41e09358a7fe24bb7ae0cb39364374c911e0d3f011f2c4c79667f43eb700fcb33e44533654b3efdb37e627eaf1352d21a187a70a86b79b2c34ae3eef944e3e61d361c3baa446dd465f2ddc0b2ae7bc8beec1761922fb5d7aa6cc4fab9d1a0835f15cd71ccb3fcb57c578a46a7197dab478b7d1ed7c6235dea3b117472c334c3a18fb8a574922f511d7ebf030201dd7457a3860a6af6252ddaf90d07d90aca03f7037223400c066db1d7feb91d84815af2430190a2170ac7eeff898ebd5c4c7e9bed19aa86293aa257a9ad0a5146be80e7ce6081c8906d269d06bf037e34ee18aba113dcfc98eca70abed7249dc9a49f971648e58d7db2282ed6a\n\n# tcId = 9\nmsg = 37313338363834383931\nresult = valid\nsig = 0b47d3bfedac89323cef0d273035674b937f4106355c0baabf6664a57b3064a789592ec5ec4a63997b6f3dd81b0514a78b8824edb2b0ffaf45f8ae6432ce3521bf77e01912df0da5d6fad9f554a3d69b402866526e6914b5c78af847233d3482598143dd6fc65a81df92cfe119f38b0d4f9d1a51a99aa569e42cdec9b42a0598f5f0bbaa1bcd44c19c7614202e0aebaaefff7f3d197635e490bba81927ce491a5810952593f8fd57a80f60bc3c0b2a7b10a0f9dd4930db8172bcb1642f6d03332a7d90ce1edc1f8054b5bd4f4760996bcd565bddd2c6dc8f54fc6da5e6fe80a2248f920216b1bb836d7885a023d92edad5d20b0e47cf5beb2cbb1393c624eb3a\n\n# tcId = 10\nmsg = 3130333539333331363638\nresult = valid\nsig = 20c9d447ee65a4cf7883ab724df0c454814029c8178ddd25eaafab34344d6e06877d5a7121af22c7e5333e2d4f2bdf42450b7b735c335ebdfb461f7b20dbb77c68c449b7826ad14668e2103b636b300a675a9b3b1aca936420cf3fd8deb2ac8aec6528409f6419d8d5ac9ec2757ad4781e9cbda98912f4304710d3a89053ebfa7a84353c86b0c48eea5a541af4644ffa21b766e738f0d94cc796004b625f244f63c41666b2213317f778f0d9d7d09a1003cbe1b2bfef585f1580f941398059a09ec07ae35bb690728ce85c2e192d423a71b513008c29582b37df1f83e40a699c88048aadd81211322b3c9bb449addb037c553551d7835e90d53f1a1883766d5b\n\n# tcId = 11\nmsg = 33393439343031323135\nresult = valid\nsig = 7c5e135d7670a57d8fd7a1c9c7b33a6e07a57d957f7a5d9594200eaa9647a1d460bbebc40e0036a7d7665ebaca9ffe3a166fa1411c704049975a5e46b4d4fa03adbf69d1a18adf59505e6d2cfbb82d5d32b7e3dceb8542e9ed8c7ac248f9f7a84abf3f16e862726a4dd189c61d6979d85ba982db3a5b2903f38d2558cc115d6481952506182a09e04ec257b19235f6c6e2c6587bedb90709298c142fa31742f401f22e2b4b446f9642b598cf43d4d29bd0934f4853ef70ec72b97f6bfb084f45ea439c4dd8242d059bc3c1a851c67d94357f93587014b2860d7f195f7b", "6bfb39afa712338c684f68501c5fb9a67dbb36544e6bae5f72dcc85815c2d4d70b5baa\n\n# tcId = 12\nmsg = 31333434323933303739\nresult = valid\nsig = 80ff5c8258bc0c74993dbdc0ba644e050cf47213a6a19bc83d5e4b2080adcca763a55918a7e19d85a0da38c5cc4c0b958884fc79578d4c91bc403756c6dc353740df2d0330f32e1ca91136933f2491c6e7e9a01ea7bcc87088d7863e048fe9796d955ec7cf1d166ac36a431e4f858d93d8caebc6ff60a678d38ffc0c88e8ee0ea655d4c1a46345556e4633ffdce68914c75a55f071d4e59a2eb0d6fb6fe4f28b63adfc590a4f5fc72812dacc547fa0c4985620d4019083eef115dbddd673847b79540a4bee6dc4ee8de267057e321c44aae047d7bef2302369cff291f6efa90dde97672ec3cdf4953f27f26ce62e77251fbf5077fa986dab5213f1f94b19e127\n\n# tcId = 13\nmsg = 33373036323131373132\nresult = valid\nsig = 70eddb0b9cdacf82add0c58a154ff2c0ca5cbe2877dbac3e5596de69c686ac2710a78caaf6492af18b42956c450dc4eb1a3e6fd669100d55e06b3428c6285254291fab9c80634c6f9c874db77c2107db37720b43982d9763cf34f79283265dd70f03e444158e82709555db72fd7d13a004290140c80511985fc5ad275a72abfa7ab878cf043e6694340ec6b3cbef5728f2c3c63747ff75906673be53800a7eac17a47debac1c5a9dd36eebba9c23575ffe1ed4ccd2fd3a4b9902f563b17f2bd9638d2348af175e1cb918a0681691a84444751750463325ebef2c40493f049c655077a70bf420b50917906315657178e7cfe607e9c22a23e67fb88590b753411c\n\n# tcId = 14\nmsg = 333433363838373132\nresult = valid\nsig = 0ff6e37a9aa03391e6ec8270b926c123c7e6853e01e4530382ae1e9067c2c447f2d21ea4f6b8cffea5cdead0e7bbf4c26c07418397f7dd85f4bbac0376aa099574dbd3142081428762e0092388142b351483b67fd8abfb5b73f10383d33fc21aeedc6a0e6f8a3d47f11c8b319425f9768cbbf498adee29e7d52611feff8596b1ef21ebd203397d5842cacf570d79cf0b4308a32d0951a7fbf794b84e540cb52bb076972f003ad59a35deb7af887bedfd26cc7b2bf334e242518978ff2e48224f89c7894737bb835bc353f4c0139553d3aa4722d0cb15c5e0aca5f5eb91dc9f4639aa81314038367c2779ba5521b250b5ada48ea3d2bc41a1680900bcf3cf66bb\n\n# tcId = 15\nmsg = 31333531353330333730\nresult = valid\nsig = 22bee45100f26f64d7d994187841d9eed5ae1af0601604b72ea005fae6e28cf0ac2ddd9761046eda1ee55949820c5545a0af3fced402bdd463f43070da8a4dff41531a0ce09b2eaa14bbd3713b79bdf00a144167cd2142df7aa8c5a24be69c4c1a728cd04421183658726c5765b36701f0d61d26d062baec16eb59b1594a185363d8eff993ab9c6d5a5899199169ada44b77eba624c53bd7b745b053c55355da88e6b83e74069d7d7e51964a0ad666ff027ec4792c6f139f1baaee769debc55abdcbfd22fe84d6d6c70a1cd14597e7e3c218b36f35f57d4b4dae3f1c1dee433259e961cf69c3e019438ab60dbdbae050519fc3620ff677d5ce9ed6fc43868e1b\n\n# tcId = 16\nmsg = 36353533323033313236\nresult = valid\nsig = 1b41b1021b3bd5fc186eed5c1d2a69f7e648d75a03b0fbd62104442c55a707812ef635c7269cfcb124f464d6532f28880b26f91b4f3f826207c0b25401ba1eed2b4895737080085ade80f13620c20bce004a157e708f450bc615fd35c1d248ed0f9cbfdc77222d847fa8143e85f3eddcddbb137bc7bdb2ceabadbff8aadee86aaaa217a3533939fef1d6f5f3b5277d7f8ef1ca07194730edee92cc3fc9ade2faa603117e5ab812ad5a375429ebb913fb370eeeff362727c9bf2901cdf34c6d3f03ca5adc849759ec2c8dd64fa24716af610749ce462f189a5c3c947e4cc65d66983ea9efa2927dd4d9054c2e0b969428b18aab616d3f95d24d8a725d2686d10c\n\n# tcId = 17\nmsg = 31353634333436363033\nresult = valid\nsig = 52449f163676b9a8249b63d0340d82305cf36a920f173389f304044503b3f5dbb503b8c09cae20a24cb6253a16d2e63559e0746f05c6ddd8fd657c34c2de6fee62cfd2d4c6c4258b138b7e827326110812b1a04573989b969c769d29c888e1e64546419d17a16ce9abebc2bc00f8822401ee1ecfb9aae39f35792338f607791acd3d7dfd3e6b584dc9382f558990607d26f1f461c5b57879d2b0d1b6f50d8ba23b37015da559c41fad4ba3607b5cb40d18c2131091102a4295555ea37e9ce92cc7dd2f41bb5eb30d02c305116c0f65464e8e9584d1757f4be2aa2814ce6b387cdd7ae78aa0032ad5935d74d4d56659e804342aea3a785d6bfb70c0cb44897903\n\n# tcId = 18\nmsg = 34343239353339313137\nresult = valid\nsig = 33c76df07a9ae7335f5e31b3d14d7412cc79c8761ffc7fb5528ade2e5088d3be3e269962088f356830f6dbb460c73a526057d57648cbc709c14c23d85f85c11ad5c6cc7e3ceb5238be9e8380bd789106cd10e034036873ba7b8ac9470a01cf4048b488782587e2e5d7b4d2116e34b94f9c3d22983115c0fe96b42063b4f6fef5943fbc891a320f09e62f36cb1a6d83752a1c4fa6b62899afff5118af7102e123fe9c7b2a51cf3056670848240be93aaa0385ed093da763c91726debaf1bb9a48df4be342a3cb9c335d2b3ef999da4eab94d15ba37b07d049f885572f47e7dc33b5d481b5ce1a3f8b3a4237befbf04f015a97217dae6b16e7d855b9413d7c2271\n\n# tcId = 19\nmsg = 3130393533323631333531\nresult = valid\nsig = 2daebad5dc34fd919164e3ef95bbad50efca0ef2364b6db55dddc8fd703cd046e12d2d2181002d3e6c79a3671e2c7ce180176c3482baacc90076da7727c9b0c958ac40f547376b44e4f266df35419779a4fd30603c0042fc473d4a37ca3f069a915d2d0ab95b81bee5366c053b99d156cc31b2f3d68b0ea5f98da4848eb8a4dfce8ba1e167cba0ae2584757e5c1e46398d4695dd7a96412e2e1c7e62b3475a6689c5a80cc6b7c4be01a3cce6045a43aab732530898e60f55aff427afb201e85694b61e81ee86e58959a174ea87dd7f244d29c616b85cb426e7473bf568a2649f1efc40592b700499314bc809d4d9668946d60e27af852c02f6c7210dbf96ac82\n\n# tcId = 20\nmsg = 35393837333530303431\nresult = valid\nsig = 5c4799e86c698d3e09d8c806104ca3e7cb604d922d4373d7119324e95befda0669732294666e9009f9c7711b130ce531b1cd16ca5a147490a39f8726b3482cb3f2683a8a14d04ed59012005df79d2500730360dfd40f6d7f90ec71c101a686f02cf38c598efc33a60bd5d9c6d4b2c084258f865b8e77e802dc85fa8c2f59d4530fbd1e2aee005c3d446ff8f59c807f0664e5e62f38eee7be9b2eea3f8f98eb2b44a0848a7076271ca986de8599830a59a1289734774118a967e70f63df1bb82374a1a08fd91222ec77117f2af9706abb91230b06d5022e2a8784919344647a3b2660cb5a689f062ac84c3613278043be9204a4239169fd14fa05c34d8a6a6e64\n\n# tcId = 21\nmsg = 33343633303036383738\nresult = valid\nsig = 32753c1f0fff11b1aae620f21f4b25ee32eb5319413c201a71da0503d32077c911e40fae8a14d944bc57b36b05d85a9b4e2d92f260f6cde67739b6d252e4800c8e5c9499f603eced7f97651e1ee878654c0bb205ba39b59285a695619963f7f36dfdb7a2040552bba7ff13d047d273f0fc1ca3892e7692609d43adc0de6e3191f2ee58f3069531509a94de113fc10c3e5d4c886108394a55dbc2fa4baab0623db347cd0f6e6306af8973f0f166558c31901c9458ef274332c15ed9c4a6ff8df090becb7841ce5cdc40705b799277825f029582eb21890e23712837088826c108341028c96b4c6a0dd7b37defcd82622bde64a2d54e4749b065db7da5a515eff6\n\n# tcId = 22\nmsg = 39383137333230323837\nresult = valid\nsig = a2226016f848d96442f82bbc33bfbf098c4cad85b07915dcbc323baad479bd971f81faa49b063776147c448210d4adef7f06fef44baddc672501e0444fe8a28f871f49f6ec634bf4f49d13e4f73c832c978bd227bc1e85804122157885c8744d31f777168a8cdbe7a4742366cdcf0bce50a0f550cc1729f2089c927990d94f73cc962af25d70a1fc4da6df8457ddb5a4969bfca4d2b1964bae88226ab11047da7b6e7adf8f96dbd772747f29bd9b9361244a04b7558df62d84828f7aad2e562f2306a96973a068b176008b0c7534eebf0ae9f7979a0902212d4e20dcf162ab51cd55944d9bc07692348f8306ca90a80306d404d21724a28efbdd228e2080dc89\n\n# tcId = 23\nmsg = 33323232303431303436\nresult = valid\nsig = 6b9a45ec517bf838a535ed93fb36bb027471b11d20d0bf6b1edaaeefa25bccdf5881f34409a042dadbe4a7b3c41bf24abe66c1f7f37b92b9658f59c55fa88aa1632465ba8245c5f0c98d082fcabb5e9fb834d727a354f8f8a7fcdb8d3230725472a6a4ecb6f3d97540773e53eb45383acbe4bc81168e244fe769b1a7d5220dbcaf831e46c93f6ea7ca2ee30ce9281dd9674fccdc796fd6147be4bd99c53a12eacfd4b9b00972b0539e3d94b85911694ea98f27496b567a29fd3087842ba01402901d1bb1ba6b3c7931f1329ff5644989bdc1f7025059d0d069517fbb682c0be049ec7e38b614af1cf9cc37eab74e20e6bca468f93d3f13749557b70129ef95e5\n\n# tcId = 24\nmsg = 36363636333037313034\nresult = valid\nsig = 01926cbf92190fe7ccd7f858c260036a7a9d554bf636a82d43edd3d2cf0f5f7006c2e0d6dc43c7c427e49940cdc5c397df66841897d3e118cfa86f5188c54409ffc169e8f192c3a84896931d98ae8a9e83075e6dabe4d28a56f0a9282432511ab09a1a0ed420be665521936a1c9834a456997c0e5e2c1fc56ab45927b6042d3571163ba59d994b902aa5ed416ceff4313fb1c67334ed7be715d2e96c045d6c0bfd20f2f5040e09fbb077a01f982384ccd883cfa2fa25d35320746728ae530bb796f5ae6ec2c36aad3344ce69045b793052cf3a569293a2d232eab378853dc4030b91e1f08c31348224b774e8b71a7e23e77403cb26d1f2b1bb800c772860451d\n\n# tcId = 25\nmsg = 31303335393531383938\nresult = valid\nsig = 363ca23ec7d980a83a5f367cba3e9a2225b3a3ecaf6434b5a347e3baa5ce5ea27824fec727ec7b3ba2d41cdc9723f5cff3e75dc7f7b9200baaa2c02b4d8399b1760a1011231e2b26bad9326204c5079ac1c1303ac08fbae42f6a4032407e87915fa3759c43b29ca07a1a3259fbee4274b63a52860c6351246f8c1c84538e5e6f6add7ff6152acca4dedddab146a25bbdf0076e2879ecf93baf9d647b32cf32a9e62718eec599cd7b51510a70fd989a77426049092621c2386a82771b06a4c5b86bc28fdd630e76fe43f21c5d22fa63001da300ef9777c9dc4121158840bd084394d600a6db284b1e771112b56b63364f007cd71666902cac56323c6e5494d50c\n\n# tcId = 26\nmsg = 31383436353937313935\nresult = valid\nsig = 4a2dc205db899d51447b689d", "3ad601003eafb70a51051ae4e570c5125afae66427056fc2c9f71bc42610ef85ba0f49a2721247d4a77c6dc9f01429c2d9b909fc84dfb049bd351872301a7736195596a1c49ccb1b367544a190d188e4e66749731a760d76aa116fa4a189665a98975b7ec803e2695fef42eae7c7f8e274e4fb1c99ab0eebc76ad6bc8d768d2dfd5969181e78b3ee72fa900c31510f071a1da8b7589e49e254de8850db02b1be841af478045a847f2db9126a4281887e02beb58f1f0bbe67c9c7acfb49b5e4ec4fc76ef30654b5d3ffcfcdf7cc912c5e1f2b20d91bdd6114d25405ab65215c05c4ad2b6fae6662ae5130d17652ce42c0ce86c153\n\n# tcId = 27\nmsg = 33313336303436313839\nresult = valid\nsig = 45a2550893820ad511eabae35039a13457350df7ec21cedc1484530dc37ad332a170af8bb305e4bd6da78cfa4382045ddfbe2499a19d51838b3a553d7a849c49e284093e1f2fe4b269295a75f12dcd0e727a79c1f0e9cd2a89e295a355a52da7ee1dc2547fa43d96abef1a3b5121bca67cf450cd087c9d904cf797834057334f788c96763a4ff0a899068363621d90136eb530c32041ef3ede97a44be137d08c2a7019f31f8e27e156e509227860c723e3aef19685a5e3a10b78df66b38f299d60b2338bc6a943bc1b2f9261977ef4e08d1b6b42de17c4c652099d377a7ab983ff983c3bbbca99f79c8148f2afa9b0f1bee51e322ffc05b051e17d132a6e90c4\n\n# tcId = 28\nmsg = 32363633373834323534\nresult = valid\nsig = 258d169322a9546caa2b68089b481bd38348159fa9ed192d2eb60839029552a420d5b24644c3381a5ffbf2ed46072974918d777f1c53ad51f9ce8a91aff95dbcd817f50ef13ebfc9efb6c36987dfaaa96e37aa89dd7a32348906bcc22f4d0b5104c42181f76974651e3ced20d5412f70467d834cb49b1b7e1532ff417f91dcf653f18c43a6ad9ff4469600890f836c553963bc2379d5bd79ad338035f7f4aa6a27fbd924b5bc8d8b5373de7f4cdac75cbe0b8abd3961db17b819d46ccb4cceddcdb3636309d6754c6d82a61f5d9b9bfabd0c948777264c1138c6fb6064fdd5a797e551c1d0e545d1d32d63e1ebdfcb78275692cb50717910312da9917052cf53\n\n# tcId = 29\nmsg = 31363532313030353234\nresult = valid\nsig = 824d0372c40297e3a0059236a93f60db3d2514defe409bfaa2890f4d04cb21043ba1871b8374fa51f1c4d7392d0e244222b1eccd118009e46bbfd2a84bac9e84ddc5102eb4508f5b9d77450f7aed31cbf5b6a4032bb44fd808bad403e8b78af3756f472563e050526527debc1ec49ecf5d5c10f279d06a5dbb7cca188ba212be9fd36c7eef8b187405da50dfea140c4b604dc313f28941f2c4447143a1420b31cd23663252ec0426c8465ade55cecbb9b9cf4f88e2b4b7c86cc5e2c6a4fb25c55835a2eca1780fbdbb8b354ba512d412e84e73764e055514e10d7ea32ad7e1a3c20dfc53732d85fae40ca951b5fc18f9ab21c9001dae67c6200b9cfc6d142565\n\n# tcId = 30\nmsg = 35373438303831363936\nresult = valid\nsig = 8367893d5ad77be24a739cffdaa7bd414d66442357db9bb339a7ce862b400363d9e7014aa1ced3a8c31d65f247e96ba5649df636fb759df04b7a62da27a64025bbb9719c7ab1d74d63d2ad5a324db8718742e5438b780ae630499bea065e2215df9313fd45a57941e9632ce66fe13a5359900a0ad5de9261aef6a11c3b98be765c94a6d24fb7c88fdec9d6fa52ffe975917d3b3d68794c6fc899b0f6901173fa91345df15f1d08dbaa0ed77e692f9de80d6670a95bce1b014beeba77543baf4092f4b2158a1f27b62cedb0bd3f2cdd381d9a46bae1aa34c2b8c36a65d4e44fa5aab1cd188d4202227d6fd537776980ebe636dd81d3bc0775bab23ccd9623d423\n\n# tcId = 31\nmsg = 36333433393133343638\nresult = valid\nsig = 99f149e9940d2a6eb2e824b48838d56f383e4503cea71e9ececaf2a6e9d616c1e941fc0f8994a0373ca6325f6de2b76be043e4812d361d89cce166e7c0f4ae8e0c2c8aa053ebe4568e0c5434acb6535902dd13901446a38d7905eefa51a22bb5b2a05b242b061643a8b1538c342255438d46824c43c5df1fb84631147b9cc689d7b828f2bd5abfb48bd40a1b0ff6866eadfd9588a0361d9bc6a076b978b9f855a36732207816c8b3c426914c73c9613ca53ef8261fc30dc7a15cf7c858609265946626000a1465d41b076ac9ded93b86e95de58c1a4d2b5cfed5d311b6f24cbf257fb03c47e443cabaf1e766167f524e6fb665e42ee046144f25544d46d34efa\n\n# tcId = 32\nmsg = 31353431313033353938\nresult = valid\nsig = 20d044f045bdddb0bfe994a34b5437e61446f9568f3c7d09137430cfa17e3929ab8b849ec7cd632079a88f994c0f4a0ce23f2976595df198b4f1431205c29b3fa1d37980855446d25327ee669324c3666022c0100cf1bf855c8774f3aa4898dace7a16693c614eac00cb337f05ec2588f670370c3ee40f29e8e900da16d1dd28aaeb098f8f3b918c562f8c2512af238ed4ecb3be4ae39374eb638b021419a3e00890a4eff70876fabd74eea1bd56de05dca208928d434e7342e9179471e958e235a298f35edcf9ad77411f824d5c53b4308cd08b0443b58fc5a868399538e5294dcbd2e94d02c719aa91ac12c3839bea47cec649620b73235f368fd5d977e033\n\n# tcId = 33\nmsg = 3130343738353830313238\nresult = valid\nsig = 4c8d64aeabd2e12c8f2e3d31ac3f4b861723ab8f9a52cb8910b298fa3a735bf91284e9ad92bef3995a1058fdb0f696143d92a99c69c233f60f64873882c1c9ca8e54cd03350804aac319747c5cb8ec6e42f6100474158111b30548519e02ae9ab39507efe50b8b212caa82305d9f2d2c43b2f75c5538b0ffe9423e1044b5fa05bd675e1afbe6d22e73ced8dddb3a00ef37211136838bfcd37655203bf2c830a62f2c707030e2b964443df1ea24ab1271fd06b3d6c1ab78b13374c086edab36267ac065bf5ad799d2f27a6f4bae708be1103841aaf21ff547474634e94c7ffec8b4bdf81cd00cf0f0e6f234cf2d208e2af2e2fec001944e9444b005c8ed919903\n\n# tcId = 34\nmsg = 3130353336323835353638\nresult = valid\nsig = 0e97e294583f528af631e44c02563344657ed47783c119a9d28d6c0f39b6ebea40e1847b9f2fe2708bedf44d2037ef4ba7464c630b8ea5bfe1c66d4b8729b20ffd22fb5721199e884b3b314ed1a6b8abf11c72314dce375aca1d02aab773d88830d1b56e86f45b1862482242d9ff57a1473876c476c33fb8228420f3a6a31f85b77aec3a8d60b383eed4f07dbade1020f5afcc08132d0423319e85f51235b4aa5e16c0b183e0fd653e594c6b17f25d055b410b78c890f29c7966a8096cc248906084176e090af500c9c5d9235a2d35f231bae74deb9b860a541d2bb933ff0a200ccff8ea3642e3350562cf29dc2c1100401a9ae0c0f5e1e6420b219e34416254\n\n# tcId = 35\nmsg = 393533393034313035\nresult = valid\nsig = 80aa94e49ee824191050c8bbaa73b352fea2311893d8b8e00e61a2d14701783d364e15fc09035482747711fa1fa72629460fafdb23474564527447e0c05be2ba895e2dd1853b9e6079afc1464f7c8689b2ad74f8cd2bbbc7690c91bfe2671bf3fdb1a43927c5e73123f4dcddb8dff9f06bf254ca2cda0a039939ceaf2e196f2cb268eea37c515d0082e5e9b4a82719c6f5ddd6e6a779054325c1ac45d6c2599f2c83def50881cd9d3a8508749646c9296ae2429a96f580d7cfc54b2f08726ed3caf7c3e5ab37d32aff309b1f34c1b8d77e2da69b619e3804ae6ce439e796f86340dd0bbbe7ea823857d9e4eb1aeb7604fa16f4b0683f78a8253d00fedb5b6024\n\n# tcId = 36\nmsg = 393738383438303339\nresult = valid\nsig = 1e10e4135796443ff3a815be4c873f9f61675c85137ff4397f600f4f5ff79634aa4ffde2195419fc78ac82eb7be206f91443b12d743457cf7fdbfac6d7f66fabe26fba464d7f984c6a502b19c8d4b634cded91d4289bd84ea7b2fdf2e6229bf47b40feb368692f60277eef9c0228bd315a3237458107c8fbfde830f8c32acc4d172e8eeccfac19e99021cf8122487f93175981bf9b797ff869153b8addaaed1f184a677fd694d88ee0eda3959bb3a0d8f66c361658359eb117eaa91f02c6c0889f69f9a14fad91d2fa443d2bb17f3aaa41928546e163ec2d09ec5cc9758c7cda12fb29692f09abb987a135892f17afac78014624298b1af79a523fc0cbdeb120\n\n# tcId = 37\nmsg = 33363130363732343432\nresult = valid\nsig = 73e39468a5640718bb56f26939ca18406995013cd10a7a72e65d2e6b1df2e841c1a7394135ce0e5da4a830bdfaac5bc5b2d8ddbe6b5098a3d9de96cc639823f7a1b23f769ba18d0d4772c1e989891a4d60a95bcd42160a78931361522da1ce1f10204f57c519a10c2cc9ee3145a0a2ac31c37b3b5e5572aaffda559f05a684402bb5c3b28c6a2ae263214073999508d96a96c30bf02fde3de162d937c4f2b31ffdebc42f9267e621855fd18eb97c0cfa4977c1a3765b4ebce955a9c87130baef1853497407b1922be2f43b6deaf7910d6f8fbfa97d870f16e17a3b9c133be1391e847e103096fee4905f246facbbe8c95f62d15f302cb27e8d4b69ec249af4bd\n\n# tcId = 38\nmsg = 31303534323430373035\nresult = valid\nsig = 40e3504284c59620caf145dd9f2425c39c66bb4e0d7abddd694b810be4a9e2f728d706531019e7e07293066de0dd6c7c68ccf32ff2d91dea74c592c504916148551c99ddd5e4ea0a906500341b1f7f6a03c4901827fabddffaf1f028139db5292554186b867a012520d554bbc42b1d73d52b397a7c310e7d195037f15fb1fe729f577d1847894436b9828eca4fe881945c1a38a40805365dddf6cf7708cba2948a15b756757d6246dad90985222e4baecc7823e4e7e99d568a9da144a5b556220aae30b8a8d916a050a869c70368607dd0092ca9b5a00865d3bc1ee0ec06df53f9828327127f33a97796f6b0b255f1cee34328cfd2ca1ea3e692d0a94e457ecd\n\n# tcId = 39\nmsg = 35313734343438313937\nresult = valid\nsig = 72f7f4bf01a6784face7d31b19c19ba1c75b16eff419f81b39c1c17cd489ecafffdb2dfeb33045cf679a455336bd6869ae61109043687293bf98ef7ad03afe6e71ce4d43319743c07c313b12a728c8a98256bd1fd735152d1d2c83de2b8b57cf9bed4691ade15eabd261377c8e26bab03d0da055086dc4ca5870bdcd9ef3e7e0973be871738a3e389d774d5d04d71ae0a3be03746aa4b7f20afbb3a44d9163cbf4e675e36d01f016087d4e7c68b2e3020f6fad363948804b0494d7b38d2ad4ee1288bfc5166b59ae3db2c2c03971fd42d04e6fecbd36cba6390fdd878b67a2c6565a7826671144712108e37adbe8198a2bb3a371c90d8c6880dbcc948cb4f775\n\n# tcId = 40\nmsg = 31393637353631323531\nresult = valid\nsig = 084cf6628f8f96ad842105198bc30a72bc3ea4aa4bb01176780f384f9f4ef2dc9b591d042c56c898e48d468226a9a361a9c8e0b27986fe6499112d9f425e08c778d01d3b221dc110411006373ff903d78678b5b04319b5f96ad1", @@ -3961,9 +4599,9 @@ static const char *kData159[] = { "79d321ff88830d47d4842c0b032c27a181ac06a42cd0bfedaf75f2daa53f64eacb5986545bcf150b8d433e66b698f2553f9da259bec319d8c0cec05d9c320e7300463d41eb077028c1e0a7d6d87d4dddf54c5b78d6a15e4527e37110b9b9ad2f3b2dd0db591227d41cc9f26f2349581dd89e0ba639d0cf9f8c86fe819dbadc688522b58d7284caabf843e7143395255e9a0d710ffbef6ad13f6a9361e20d2f6f5a414f5\n\n# tcId = 83\n# last byte of ps modified\nmsg = 313233343030\nresult = invalid\nsig = 5798785187910703680cb2109f492c3f0a91b4a8f11d3da775aba891eedec3d76fd30a939f5d7a2baf7290c573e886cec8ecec0b1598f2cd169d53b4abf8accc09709187f32a12c80fdb42ed98d9e98b0923828f0e38acc338234f7b7a0ee377644a655f48816ea4a5bff0f6d63c3945dc3aaf921e9404864594bc323c1f3ef42f9361ed6cb8fcff2994293e17865e2fad2d885277251fa24d7e7aacebc48d61c3b48047dd7c99826b3105d2f820cd62404cad5d758da461af67677e39e55086d8fa52ea0334bc3b77f95191ffacd28ead07a34e4672577c4c65b5bb9d5f9cab6e1f1242216291b69a0c98714452f01f37722ff26589734cf6020c5ac9196374\n\n# tcId = 84\n# all bytes of ps changed to 0xff\nmsg = 313233343030\nresult = invalid\nsig = 3747c7c116cf30567e24fd4213c126ec84366a26eb304a65d144dd9b453054df4e5036c861b5807137934b1cef351411e40654bae5df6fbe3c42d763407f273d3dbe059fc6412a366775603e064b1561a58e70860edf954dbe666f8fe44f44f87df3b0e3f3e19c904966ada52f00806f975f256d4a855cee973e20f33c31f9f2b3792fcf326f075f86f275d8ef8df2dd0abac83d491d485fc167cd40f3802f66036df4fd64fc441ac8a25b405d5ef960127623c269ca836671a66a6bf2f39c0792dade17564d31863c7e0161ee0bb88522ac0c9054bebcedb603a2d18ddb0f64a91ca5a2f0086afd0d8c07cb0c1e7f24d12f866cdcde46d663c1d4dc7f7c6f62\n\n# tcId = 85\n# all bytes of ps changed to 0x80\nmsg = 313233343030\nresult = invalid\nsig = 1377d4997c03d885e4b95f0350b1c8091a4d9beef9533dc6abd194a1439c383622b9dca5a49da247cd55c02186829f695ebb007ef0535c4757baad057d7bf76dcfe37cb9181b0c290db16d0abc51ff32d03b6a8e56ecd270dac231c81e50c7e0203d22b991291fec650b9904b2539a8a330172843bcff0cf46f06e32f55bec1f5a734e70ec8e4e8883e3c22eab7561d9c76737025352b5c9fa9c76eaacb909d23d0d7d7b6f1094ccec8ba94f149f81946faedb39ac557cc28817c9114a89a6f720d849f90cb23ad202ed4682036b3cb70b6fd5df0225900eaec7a21e39fd433d3200aed4bb4abc3b531393fa462fbc920c918f1938d33ca86e7ca3bbf1d34d74\n\n# tcId = 86\n# ps followed by 0\nmsg = 313233343030\nresult = invalid\nsig = 7d0f3cebb4372569e8f02df9f42222151cc31659df8d5078e9ee8e91030735d27e66da8c87039a27ac28588e8431d7ad1583534e8570318cbb2554c07016bfb02fe59af00576b7908286f4b27e36f768a118c3f3a1ceaeffee03a1b67270c3e489cce5c5f1171e0a8734553403047faff680dbcd70bf0fc1f0f4461bd4e68c6c0978da3490a137ddd8f62bd79c6a1daf70f7a9a3e90056ccd41c62f04915bf128f74dabcc47cba85b0fae47a04da32e17799ca150814d27793816e6a198390c35d1f35abf6816761a5ff0c28b1e60eeed244b1f24934174a1d2c469475f3eb8842eb9f5c6224386994aff9579f26ea7d73c668a113ef7dee8b2bda576135d452\n\n# tcId = 87\n# ps followed by 0xff\nmsg = 313233343030\nresult = invalid\nsig = 53f2db262358c21792eca635806ea1c1ad041d9334e977a25c1de0fc8233ec6f01737adcf1fb4dbedbd0078406ecad921e37c77d4585b5eb5ecc74c07ada1864a3c13acaba9372f852aef55ff2dc42c0aaef74bb656b8e0beccb7b9eae587fdf3b52eb678af1032e60ad12321c9c10c445448df523856ad262208a06b8817ee229df825f080a72d5e1a43f222215824a8ea6d455c80b2563c65be1eaa0455714ae576ae67e46d006934cf0c137b8c9900af9ed716391ce96ec43296e83a5a10390ed91f2e6753ed0254f0290ad899462b3b7af42c3c5f0893863a3b5e6052d3a6dee554746960a07fb6ecdf781e47b96023ba01cfde4c7214611a1be5735e2fd\n\n# tcId = 88\n# shifted salt\nmsg = 313233343030\nresult = invalid\nsig = 11e8938238a20f0e6947015987380dfd88a1661606bd05bbe4298f4746e81e3bbf34aeceba5360f1839ee0d7d7fe3e578cacc2d24b15eefe2064edb1fd04ff9a44c0a600ebf00f64fbb1ead4246e5ffbad0c22441ed073462f26e30b61a0a9142b4f993d1b26fa32e11382da33b9eb5855cef6736bec2f4f5bc6bf82fdf7da62346a4d9696c53e1cfa789667b721f32f7779daf7df85474096a9e9a7291afc76df3a66c7a0b997b41bfb71fedbdb4e65095efe1a81d35b66be55432e0a6e33905475b46a94e05bce7fee84645f500d8ebd7c0282c35f22774e7089262210f83ed485cd2b045acd5d62b4bb53dcbeb2588dc6535518189cb0220a7c9406e454d6\n\n# tcId = 89\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = 39a8e947c919ecfad7ee28bb708c1f9e825036374ea0f610bf5531d89b813d506fd00bdc15850b250ac50fc556a676c894fb641dc650999eb6239b91e2c755126bbb9fef5783a5ab834e0ad91c60e720e80e096c091167a2a1dae838a16fe0ebaa8efb3573c89ac5d8e0584b5ec4e2168ef097f937ef0f0d2a2f964a8e6a810dd15b9c27b234d788af3c4f54dc97035657ff19f2835555dbafd02c4ed3c76654fa868babb71534bfe84674eeddbfc2b27a517f666bd03a27d8173bb92826a231cd9a241c171445b416934ebec5f7eea4fb41a61937d9a98f61b2fd1ca8e2be125e85cc8d16d553b114ab72395e86fea52f54edd853e9c5156557e38f621b975a\n\n# tcId = 90\n# bit 7 of masked_db not cleared\nmsg = 313233343030\nresult = invalid\nsig = 9c13d877ac2bd8c02c11e29ffcc0c1046dbc9870177e843c30b499c2bf7fd09daa43469caf2b8c3e955ded95e4d62209f7571bb45593f4cd8b0c7bc9470a8a693837248b5a7854dc8e37e752d949479272642994182061d7af80b0ac6f6e984874c8cdc6a5d7d17dc9e9de5ad12120cdb9f6c0d09c0e11b87b3423e37ba9437a4f76cc1e6124579e5f79832b89710de1968ce46e3e69fa185c0a924e8cb5f996ee5963f6826dd37714de264d75545e8509caf8735330cde7ed4228e5779471827b83757c466022117c45d598f5a4a7fed7be4e1b4d320f894879061a75d1a41efd8dcaf3c61733ed8ca2cc2f83714f8fdbc7a97cd6d6b97ea3d36ebd69890633\n\n# tcId = 91\n# first byte of masked_db changed to 0\nmsg = 313233343030\nresult = invalid\nsig = 00566c95524ad0995eda7d668fa08e8f75bea868b60972d6488cbe8939bbde68fa5206e671f35555f628fa707ce7ba0f468cfa8b9737e0ef64e0e23c901e4965ccaaeefa9b84363a3037cf5f9e044e295fe57f32c1125ca70c639b22732aa4c4b3e5562690bc1d7e7e74dd01c674212dcb63c58fa23333d45e1e4ccffa5d186443cc785c5ece3f2d7a8995e25de6a171cbc960c272c2899f6f87ceadb72eea1be085245669ac08993591e72bb9aff8bc29388b35c99f1ba7477af9d16754894a50d4caea4bc80e2aef2ced27f4a1c88be284bbb40cb8ae279b4e38a4cd8a51a92a279a799b3316c2938e1386043ae7ab1d8605cd310d7239c805a07a19c7b17d\n\n# tcId = 92\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 2b46a0aab5f573e32ffbcb411cd99d2f90aa9b1abbc600b0cda0d824f79020aab47a2494caea20fc93017e77b99eb73a1f8a550b611e2747ad29207772629c2ec40918c07adef1c90c99a15cddb9eac88955b4093a9e743d2420b4647e167bff8ddb07ce197db89d8a7d3f327058a41cc459ed4f6d5d23dfc015479d95e195da37f5b1fc318a3f74a0ac5fe2b9569c7fd99b8eb3ed3967a5eda1d246a3b225548f67ff860202033e7164d4b99dcf95f4232d18a7913f7258a33179133a6fb4ab5a4937b642eacb92908cf79495745abc583524cb0236fbfadd2c7e8b0a6597017912b4737fc01432625a508355869670bef25d32afe6753c38cfd96ec38953fb\n\n# tcId = 93\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 3b65975357ab2a410c2fae7f2f0381e6c40951260451f2eff05f0dc707abd013a996fc10658a6963f462877a808f61ad0362b9f640750b19debf3d59692134e357a49ed3693f50924b7c8a1824ccafcb4b93f7679dd892823cd479895d41fd1c40fb89fb1da19bc1fdc72eb038782f24ba3326428cfb166a475a9fd27f94d1a0ca6fa0e6a0d2c2883db3eeb2c0a59474da36211695fb811b9e8bc7f05ccb1f50d26d71a2dd209b0d269a736610c7dc1f7343a4736fa2b8c27827dfcad49bc4a86822cde1579dfbd646474f11e1a60f5e4ac2f2a3a5421a7baa9dea5d24be03cb6fee771dd808b67f886b37be5a300f6551d7e7636e9997b3255ceed5187ebcc0\n\n# tcId = 94\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 4516c8a39b8544d1c65d96472fea0b2753060330e76e6f90f41ab349953d26ab1b95fd87484535b68c0afcf1542a9b966a9bf98b89a53bb28877b34d168a4ba8201215c55f9e86d30b7159093517682e6e956078947e54e3f3a779da032af7dc6bcab1c0b2a6693fe0eeb9de0d158bcc125293a6f10ccaf1499b6ad912ed5912537e3c3c5f18eb0ab8e701056d7b973b8b61af918858b87152b6c40671bf96735ab1a112972346e771e7cd9482f6f59d320b8798a271cf21779747f964281afa1303142eb3e1841772de825b4b5e68024dea014193c4e1c206bdc6121a8f2d41837be3d13833ed615d5b9df4ac4c86cd25344fe1022df0adabfe2d46f7d9f0d0\n\n# tcId = 95\n# signature is 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 96\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 97\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d4\n\n# tcId = 98\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5\n\n# tcId = 99\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 000068caf07e71ee654ffabf07d342fc4059deb4f7e5970746c423b1e8f668d5332275cc35eb61270aebd27855b1e80d59def47fe8882867fd33c2308c91976baa0b1df952caa78db4828ab81e79949bf145cbdfd1c4987ed036f81e8442081016f20fa4b587574884ca6f6045959ce3501ae7c02b1902ec1d241ef28dee356c0d30d28a950f1fbc683ee7d9aad26b048c13426fe3975d5638afeb5b9c1a99d162d3a5810e8b074d7a2eae2be52b577151f76e1f734b0a956ef4f22be64dc20a81ad1316e4f79dff5fc41fc08a20bc612283a88415d41595bfea66d59de7ac12e230f72244ad9905aef0ead3fa41ed70bf4218863d5f041292f2d14ce0a7271c6d36\n\n# tcId = 100\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 68caf07e71ee654ffabf07d342fc4059deb4f7e5970746c423b1e8f668d5332275cc35eb61270aebd27855b1e80d59def47fe8882867fd33c2308c91976baa0b1df952caa78db4828ab81e79949bf145cbdfd1c4987ed036f81e8442081016f20fa4b587574884ca6f6045959ce3501ae7c02b1902ec1d241ef28dee356c0d30d28a950f1fbc683ee7d9aad26b048c13426fe3975d5638afeb5b9c1a99d162d3a5810e8b074d7a2eae2be52b577151f76e1f734b0a956ef4f22be64dc20a81ad1316e4f79dff5fc41fc08a20bc612283a88415d41595bfea66d59de7ac12e230f72244ad9905aef0ead3fa41ed70bf4218863d5f041292f2d14ce0a7271c6d360000\n\n# tcId = 101\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 68caf07e71ee654ffabf07d342fc4059deb4f7e5970746c423b1e8f668d5332275cc35eb61270aebd27855b1e80d59def47fe8882867fd33c2308c91976baa0b1df952caa78db4828ab81e79949bf145cbdfd1c4987ed036f81e8442081016f20fa4b587574884ca6f6045959ce3501ae7c02b1902ec1d241ef28dee356c0d30d28a950f1fbc683ee7d9aad26b048c13426fe3975d5638afeb5b9c1a99d162d3a5810e8b074d7a2eae2be52b577151f76e1f734b0a956ef4f22be64dc20a81ad1316e4f79dff5fc41fc08a20bc612283a88415d41595bfea66d59de7ac12e230f72244ad9905aef0ead3fa41ed70bf4218863d5f041292f2d14ce0a7271c\n\n# tcId = 102\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 103\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 1758eb94588e6fc4f50c1be1afcaa41027869f304cad513b1fb12c2f446d63cdc05c4830a7e3e630da7b2da4f7867cc173bf6420f9732277282596de41ded32e21d0cc31441174da8765f57419c7764ea758f55bc17646eb100c435d1ac0eed6fc7ba6de5f832094ee2f479979765e05ac9976788db3c241a9e32a0da864f0019a87646ba623d63f4411af5dee1be9ec488c7e3e1b231479de70b9ac5f78a17b1f4120aece45f26c07e7bb345fdfeb05e14bcaacc614672a465fc523624cb19f66f9c6c3f642b832ca44cb25176d679f0e05606c3fed022cac24c2bf960a406d48818e3eb7ed53b0446032469047dfed95fc18088c92d91d93722c47f88163a8\n\n", }; -static const size_t kLen160 = 88303; +static const size_t kLen214 = 88303; -static const char *kData160[] = { +static const char *kData214[] = { "# Imported from Wycheproof's rsa_pss_3072_sha256_mgf1_32_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082018a0282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b12030203010001]\n[keyDer = 308201a2300d06092a864886f70d01010105000382018f003082018a0282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b12030203010001]\n[keysize = 3072]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1203]\n[sLen = 32]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = b520065682633ba54c9b713b2ef19cdc1fcf275ba1744c2350da7307a20971cc30eefa37d1667d23d20001a674f0e00df4f9b9e1d5fe7eb85cc45cab5dd625759de83017995c93d48b126df03aa74ef87daea0c1652dd370ad5d663598a383cac217a208b22c7cf0e448cc7ae0555f892ccb8ded6894cfb0c328cb542be0485d860ca77203081f3b04c6f55c5689b1a66b1c24819a4a7ea55f32e00f61accf4b411bb320a96c990173b63ccd74e7da7df5ceaf33a39a8acb89a845a594b164ec6e22cce940eb06f2d487a8bc4574451878c2bbf57d241f76586e0703bf5f86bee832d05b75fabaed6accadfc1ec2cd6e619dbb29b65d6e6f5e118ad52d82a955d21005ecd63fb382f32bb8e2e1e57220b345cd6422bdd84a91495d0ab5775b08139edee960dab1b4ffd9ea5b27398b58e6e35211c3581501e99bf5e3f17fd79381528d28a4927e28082f45bfa9519f98ea663dc84c50317adf0bd5da98b01459011cec61800534dd5afc5a567c19e4a400f06dee74112083b5322615c144ce3b\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 8e10f23f49011d761946b283d7152e851ee76e5caa1741b0901eea317d8945f2a0368551b3f2b3a6a0d6a939aebded8fea0a96dd1d037be33b1c35ce78dc89693918a99d547a1d892f4047c09fff7a6523acb0cb0cddebcd4a6fdcc309a466ca9580fedf032bf56154f8d79d5c4686abfd2c7abd342b37e5373b59a07fa865b118c44f2c44b851306dc97eaeeb638f14bafbb09c81996beabaaec28c19f06ffd59dbe3080e0124e2386418052735f541d496322c03ebee6e4dcaba24dde9772a9f079973df26e854c255eb48df50c01d49831e54b64d0ff862d03fb4d82ff204d303b537176c50ea56761a83d0aed8ed2deecbbba981c8aacd1300051a864d1efdc897f31383ccd6f181bf976a75e7a7613b60b3cb2a6f7ab8636f672990c13017f2981c11ba36096cbea898f016c581ee859e950bec195cc4e376e134341b2fd3e3d6181ba4d377b2aab6a148c6ea8cca9ee3478297e901856ab18f61c0233c899841e5da125516cf5274dc1b22e2a51c922daeeccfad0f2a8bf84e531bc4f8\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 22915cfa1d7dd30f50b4c0e4cee42c5f0aa1b7a6644f8a11e611b2db042b122af8211ffc1dc220b435d8919cf64d715b54ff8a762f702b365cbdab455509b97d9b310011467d4186647b957e2efa404aed3b84840529bdef7746348385a1c6a2ecdb88d1cc2b40b36c346386739c39d2815938e463a35348426f17d32d633b873d6124d8b49a726743af7c0e56d63394155b63089c63ed8897f8af2a2260d33499afab11c911faa754ced5acdac2de571f39c2768716e4308244a99d1e65da7061d2feb8ec8b4e517bd5e19cac626698479ab2019257cf83ad7b641db2345b38006d63f84b41772b90037778389cc30ed6aba6af212d9326792af746d7bca9211fa344fdc2798a490aed3a2840620c2a85e3d9b9c38f2330072663e16dd26bc414c7d68f6b11d2cd3e0387c1834c5e2262a9e2dc1bf7c0108b4e2052566c7a941ef6b38c8687fd7abe6add2b745c2c2d680ae3e5646ce2e717ef9899c7f3fb1e3088e8c0587d86546f752771819595a7a3d422820ceaa12e3ee671a456dac673\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 8f9ac1354af4161d0e55b5674821d02823b3a6b3f79cefb98cbc77f9ac2d91cc6345f989a7828132f73f3630a247a936b6a057b3e5a2fda0c5999ea7721ee8880960c24cd2377e869cca1799747142d57ad6a8d83ec9254d89f591add11a758e1ea1e29bd08f624d0e28cea52ed5eed7c0f5f49d3533eb1cdbb2af837dc42942f9a86b5f4e2d5ce506697ef067a344949bdd89afcc25978af4d50c300bcd0ffc9d93cc559e3ae1a13215a1d3f6030827340c6591061a5ab7e65153b1df8b25e1421f924d39c7e6f76243c1bb9ae4063d9a475cd2ece45f4e288fe0720074e87868d70a5584a9ac2b47a56417cc76f15154315545a3ed6704b365f15d34320804469c3b09ed211cbc9e9e767b6f21fa16f8641d8b78b8dff8062a25b5bd3b6a38cb4706c42c1fbbe66db1c05cb57531132eb94fe1569735c33ec491c318a686c837ac810be4afff605f92bb390e7ab3cd24c0cd997cf13f112e5aa01746f43902432639e1eefcbd37b413c586f057bcba40a8f1251251e84cb7c87c53c1d1d558\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 6e471c9342aaa27bddf64b02e8805611a13770b22cc3d24cdfa9a2fc14865f59344c288cf15d4c8785089968a12e9d3e63b8179489568743448f698f316640146322ef3b611fc98396cf4a4757e48ce6701f123fc0bb8df80b63cd2371522f8ed929f7bdb709d424af6eab2eab212b43afe537fec7bbb9dd02e64f116e02ad1214ae931a6fe28a5982029088a27bb95ef2ee46ad212083719327acab5ee51c82d94d5b14f6dffd2242ddf9fbbb2d03f945796a3e35346f2334ca6b4ec5d9ed6f1584688e661951e948cb95fc5cc04e90cad98c861ddff514c60275650ae3003185efe0c04356b07f361f7dc7e17c5de479cbf119c2910aaffa032aaa81ec9eb9f7e1ad21a410ffce2502e4829404d01ae090ef289bc28c9c3f37d3fcae33e1523b3c9b81e301f51d046196fc15c90d58bd35a1fb11fa04621b32cb61e718a434a0aaefcb676cbca888554d1e84d43b108fc1cb123cd2d300da630fb77a3ce29a0f53af32a5ce81c5ad772a199d1180a9e2f090847cd87ddf7b39aeec89a6b492\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 39f7dc9010bf3c200df551499404ca40346e58ce0c56271e2eb7835187ae57a7b9a0688c9b088ad85e128f56c0299c437a1a9a9104f3f51aab7043d5714963e46ace5d8e435fd3e416dd61474e9dcac3ffa6c3f0ebc4ada987c4313ec36f2c43d2dc749e496fbfad639dc811304388990b98cf10ff616a866bf5d98cd5199bb74704ae4ef365424130738b9d81f893a5e2316ee6daea185c170f69ebd2ad455b56676ebda9d0bb0bf4d3357475ed8166a3d2dfe6e093c3a4bc5bc2fc2275e6779d809107b621138fc629a6767d5809c85bf88b46b14a8e4ee9e310db746f4c0a79a3d36f6e305125642dbf823474fb913a9967a6d120e82a79ace48c501fed8dd6edb9634df909fe6775f8f6fc5b79f5881e1f13b7cde37c7c3f97319cd612f8ad2b1ac921079f18213e5facba0b83c17887e69501a6d2eb37661f03590af1a15646165eb785f467cad0c625947e8a8a4a68f8938077d5ef7f1b8b4da0d09ad5874bcb22ccc4ee36b9341b974a51a1d6ca009ded4ace9faa99d924a23421aabb\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = ae8472e987806e5110beae330056ff974abfce7ea9927979cdd14346747414cdce06a9c78eb1846c75dc288d7da531531da49ba7651d3a1f79e3297fe37aa73e075cfe5ac004b166526cba55f914e0d2fb1f12a60a3222dac434fa378c2e7b0ea9c2cb5e22cc343ea624ad6cf5545a61364cd67d6dc23d22e4888a253e940ff0e0ce0207c1feedccdfa10f50d2363bdbdf10893e3967d7555fba157f9a450d6bbe63ff31777bdfd402afa72c3a2181e5cc025443cec30d253653db7e82eb7dd488e6491fd25001723eae2e3106c7b50c2b73c142a4a31ec4", "3edc9ec9011383c99a095b36258a0a77aac2af19b26af8a166b130f7f57f03a0e8007d5ac0eea9ecbe14fb7885538a22c13de5771bfdf523fef9c9b5f52ebc2af7902a0baf2a33923b0d0622b8fd5c938214aea4b9e7f0a647c5520c3a94a29737b95cc623f20bba8eaa3e9db60116fe1760d9b7ac1841e7586aec9708212a5bef2ff67c74462883062e052ab9fd90ffca0f0a6166b71a93bd289a1d4acd2d6ce72ae0b91cdde72e\n\n# tcId = 8\nmsg = 343236343739373234\nresult = valid\nsig = 5ce99063bb6c6bf8e46772e8701b63abb2feb5f88c5b76b76c00c719402ccb399d6c6d8c67ed5b6fb0f1dfeb8f8dcc5bae03ad57c1b0f53033dd2503b9604fdc40eba51e4b03c91a8d12b1a3b929b1ff1e8e79cb58d788114d53f7e07d87a885f6dd4d26560583986f7a84dc466ba981db06beddb1fa80b0a444b9a56c82f98a927977da9fa1ca83aebaf2c43692cef61b12995d8dd0f3bd6bf061025ddd34af3e0257203390a80765ef706acf7df6f43210a7928673d260f2f3c30a9bba9b08735dd9aa3ff2fc27a2ee9e130c88ba367c3d1428f173ea08e273886bc153c11e24b05cdbf9b00573b013170417fd96b0106f72c073f1216ba872eccc9f56ff9e3e08bfde64041d996b117a114b723cd97f70e07068ece643f58d5ee5cadca7e24a18b0a66ab724fb653a01c5749d51d4bf5408d2d2008b30eb3dc20b0e14510c06402f789276b6237802d608ab49378001ed6f3604abca038e3c7e057d95e85c9e668f397bcce18765132142d6b0f118c511e57defcb316fe41dec06b988d911\n\n# tcId = 9\nmsg = 37313338363834383931\nresult = valid\nsig = a7e0ad7ec64a600e37b70dcaba9036bb3ea95508c961668c4e051c8f3faa454496ce6c009ae9cfeaa2c194c5c9278e46b75bab40c52f077a4fea175b2679121d30b706139cde7ab571c89f4d19abe07c67c70afd3e4c2c05d60c92bb2a639ba389826088899605f1707ecacd88e42491debc78295b44f4e09791f9d541823ad5c48952bd3151ef98ace7e251d12ebcc9370bc205a1688c9a5e9190cd082da1ae94f22eb2b0b46b2a5eb2273b0b324215de187d685471a07f673d43e58f36c1e0f074765dc59c1ebce449229361d07522c7f03f27eda57ab8bc89ac683d27ff4f95a328892507952f14d9e3d8643d805c327eef8bdf13ab7e6634a103fe92cbe9e7b00f9bdf8efa740866c044735799d59245aafb8d04e8bd55b66fea31c9fce4cedd4abe68444fc8a6dd550c3c8f1d6597bde001fb977b7802e0263b7319ad7a6c1c4a6c558774641b204b6d3eb2a2aeedbf4a38de6584031102a1958fab6fbea9976793bd1ea6c9aeaafe81515b954c7615f8c45538f40a22adf0ce6f2c977d\n\n# tcId = 10\nmsg = 3130333539333331363638\nresult = valid\nsig = 6c60107dd182d5cbf4550e7a6e3a652f731503d8fafba3a7aa52e7ac93d4de4e03d911e058ade448285bb9c3452b60897c099fd4ba22ff4194eef1a3fcc3250cb9ae270c33ee767b2b4f18852612e27c4ab31d8ea6ccbf122a357a6d6e527191a36e0aa2aa925f68e158c8d5decfbf8484d16c2ce906826dc4773d59fd1a4032c2f576a1ae8374a13cc24abe15ac1403452ac7cd8a643dfe18c911ae34f773520fa94472c596dbd6f5b93227951ebbcbacf60b18e5a60330eba9bce0d8a732cfc27c7c0b9e22070670a165846d9d7e9b24dc6ee9759347f5c6320b63789d5ccbe9566d9f3c534e152f2686631a41aa85801a31a7f31cabf959cdc93755a3acdfcf0ddbbc5298e91fbbb2675565912e5fd95cd59b5744833222247aaaa5a5868da4d1d1af590b8633dfe6105e0a6abded2497ac7e46650432cbf0b784b9447770b20f75b2618fb7e6cc6fc5cadb022980f78943fa9f784e5f0c8fb5192239dbd3293a38e6dade27a07e08b54597029f92a8b29b700f842fda55aeb3e0dda79405\n\n# tcId = 11\nmsg = 33393439343031323135\nresult = valid\nsig = 2264d276cce22aec8d109ced7a048ea44d627aee577f1117998316af911e98139085bc92f120827b304c4ca519743a33f7be05d8a49a28cd716ca65f6b976513b33a440b6e8ec5daeb85d6a5926dc5015a2d24d94ff1f87a073867bea137a7217254b9bd040273664c58d61e618ace6bc942c446401c721565f74fad5bf31475093752e3a67fb32231ec8d26649594f32c5d453f0baae51b20dcc24f0e5e82eee71d85aa77f33ab01cb588420cf672461c490db52dc2fdcc7a22ccb2b92fe8de0e3f8110c93e5890076db8292b76f6fe80ecf3120b4f3824f77e538551ecd435922c7d433f0467b445026d0371a49a73fb2ee900c094fcb8ecc4c01b330dde0561fcde6bf2dfb6d26f3c3d9b897342d8079e29226828a39d8fec96b53e060a771fee75b482b2e0e262069316bd50e8e210078ce56476f70f149bfb356fe1e490ea642ce85a8664e50d0b3f350806d9de3926c8b2d417facd926741022fafa2f7b10781397cf012697442ea742c11f23a5b5ef5fd10369207cca693fc8af57d22\n\n# tcId = 12\nmsg = 31333434323933303739\nresult = valid\nsig = 677dd6918bf4c96934e329a114002460d67d1e8f729eea9d2e8bae78f4442f1a480ff1e5d20c1bd81e61e5f92e5e42881cb1fc22bb7da3a4d21060bb23bb17c234a85c76f7591fb54ce0ef70ee7556905eb670830b9d10905d100f0c255b944689f23e1313b0448777c52ba80b767e07108818aa5131f8b75c84fd2d7b4035e0df9a213afa8cb913482ae0af76a997aaa0c8cb63975bf9c006d89fe4ea6ef035cdb4137103585b9d05150b086d7f329b70efcb428ddf76ca36d44af742326aa05039382af67216c12f7eb2dcf01595f3b78235341be0bf7ea30f6294239c7a4b1ead8f98bac805e88caeb482b13c5bc552329a47f1e26233cd24a3b4bfb6be6d9e3ae8e58f06c95b513ccd5c61685ad0aef627bebab0b72bca3bc374f49645e403bbeaa255b501dce3f1f46f9d74d1aac2f6ec5eedc5440e3dd9f264bcb1d98b855d1cc788d796919d014ae215dfe2361a1d13aa55a7163f4164cff38c5f62c00f59eb20efec26e0fcf66d37f12c7a9d23dde68f25620df1a4d5e5e55ca94634\n\n# tcId = 13\nmsg = 33373036323131373132\nresult = valid\nsig = ad825df96215ebac22f37e5948fdb2281bb7ca69fbd9ed6d3f4d2fb21cc6f9d07cf7779a264dd427a863f0cc36a812f125d6ed9bccf6c233ae8958299cfe645b17331131c32459377524326f2e9eb43124e2e2fb7a025e0ec3de6551b7ec0aff5d1b4c4c03e454efcd250a7c9711f21e71f6e347b5e7400cef50eed93426b43cd11cf55c34a9d6d1d54314b1f0869febf3b92b8db421c4fa000e98ab0f891120d7c0a91bf50e307fb2cafa596c800a05e6f42c577a02aa2169cdbebca14c41d10ee1bd415785d7594347f46e700f62bcaa5cd728025247f39c40edc0977015604e196fa30b1a49d84132469d1a870a57d272c98ed93d8645a7bb92a4476057bf2b134ca20e45da22cca2961fd52d65f840b07a87aa4ad104af67d7bbc53ea95016883e3ee087f39582b13e274df32aa419eabe12a9eeb08868425c0a1ad06798d0f7da987340313cd4254a4140a62f3bb1b76bf57a2c0712ef2105f4de0819f6c724e0a2d92f87683a2734bedb4fcecc75ff26291ad862fc3397a9f02e6eddf4\n\n# tcId = 14\nmsg = 333433363838373132\nresult = valid\nsig = b3c301918f5d1becd6c88ef04f908509e9b62acd207cb0c03e968b56d4237b4a23cead6fa5a72ea6472af47ef3854766376bedaf67c14a7913d48a74aa6521f8ac814f01e3bcb073e3b85f315bf51468c28444231402a77cbebd0cbfc98b06fe925f5d59b4353c21abb324696bd5d402e7cc5435bccd8eec3eeb8e7e4b5d4f8f719adc00eae9180cb3cce9dd89231b637651a76d87c0311d0f9de0f7c9bd7f6485d7d600bbf105e1fc6d3744e83528fe761c2ab0fa0cd5c386d2ee44b0967ce2dac3abf1c723868569f43ae09f1a5ee32245b11569fb2dfff08f6f40c0cf45d2bc7fc524a82779328f850ffaedcd9de27db5e1bd372a76fb60fbbcf88a14a2d820647f660a894f5420c7246d9d9401ad56d577b56907d9fd3b69e35faa40000207d704087e3a7011cc343cc94f99ba653da6451485a9fc17bbad2688b511ee68cd90288e4f5e83ab742a54be006b51fd75e9ea3ad09ef7112f793b61d5470aa16255db34a8abd5963b53a940c890ce89f27b8f7e535489e965f33a4b9798c301\n\n# tcId = 15\nmsg = 31333531353330333730\nresult = valid\nsig = 602883fa2f9a6ca35437d377fffa5cf5a5643898763960c7722d5a5b808fdfb4a09a0cd3bbc8c5d2fc8a603229a5de18866aa0c5d88c2272784784c883918fcbf47ac62f5e7523d65d6ab486c68ca245199e1acad7f087b4e822669105f4f45a50c1a43722fbac7a9b88ef7bcbe5796ac9601a09d3fd6201c77ee09f591a9d37f48b3e93fb6ee5d9683d3ef4d581fb2ad9e5cb2896bacbd078952f9dd04540fbeeecf6d8d9fa45e791ccf3027130d1f1ec551fb35ebba6ff329c7d31c5bedd65303d56b58f826f38917b3f79d82b442f4668ad479b7e108e2e59d88640c1da8ecdf719156ddcad93d568d9593dfc7bf0bda2519454cd2b1dafefd556091a2a13ff80c75bbe9ddb04b1e55f7edccb8a0832ef03079564cc367cf5b696be4e193001d8c3bc5124227359c7616381a473b07f31d6494c062b2a9151420b828b830f250e66ec570e38bc44e26bb83d45c7f794a9460b4b6d746c888d084a754ac7d75ab1bff232be49dd1fb73efd76fbda26e6411b3b1de8671518f937b8ce3ba8c0\n\n# tcId = 16\nmsg = 36353533323033313236\nresult = valid\nsig = b259676e6b9b49edc04cf3f6b06267a6af924d278c21f5994c2190d0cb667d641291361a8bfaee8236360a4dffbd5ec4f1f8d9f85b54c1bbe3c9dc35332443c2509f0ad7d5ec42571d755af814cc0ef48e514dc5342ca7653d535789c8c21fee5e547ac3c247c9be6b792199db48a17299b5f9d3bb9881ca95751132fac76d776ad02872279bd77dcb43b0cae7673e40907c1bc321e14637f224481f58b90f875cdc08c49515b4be482147fcf2e62126fe4c0310c0677eb7eccd9352a9cc0902b54e4b3454f3ffd69666d16469be958a54aad1d2a58eb561b4b222a4ca5edcb5612d03b8bd2f7f26302b51567b83fe1d59eeed36bd2ef128cf476ccbabe4eb55d8c4ec91a0bda8445972fb3d74a4bcee2ecf5e90f5bc19d4e9908e7aa284cdbc37d22ff4ea70479e8e2a9d2bf0a6f02b3a2d2643a34d7d4f93782df0607c806177f61963b60c08e4154a074e92b26c4f2c678c9da7cd9d16307c7309559a3935a8eff9593b5454a1cd60c388c995df971075c5397feb77f36ed8b9987b8ef3db\n\n# tcId = 17\nmsg = 31353634333436363033\nresult = valid\nsig = 57765fb30e12f08143d72d7a4232c91583d60afbd8dfe01c3b50d861140d3c5bd0a17c3a51dfad96d8ce0716348dc6f62c12c16bab5401a1fa90950e96801064dab2537a4cd0b5227708618ed2e34e2eab8a557a316a5a7c42b6b297cfa646cf8a90af59730fe5d34df9a2d4a9bb0d8bb1d8e5decffdda6f50863bde347c17ed88e232c4d3235b00ce5db088e514f3490f8d459eba993d31f99bb24a097c0e322454e6c6", "8e6c9cb0042a8fe1a5897458d097ee68e5c79163f05ee0817499a98f2af038aaf02c488fad86ee0c157fbd1cfb91a17bc00971326d15e1c02ab440c46b07c807dad0822e2dce9505ea75dcea6ba134b58ee9eb79bb70c2045c1a4e6206ee9e12909b1c3a7a386cde5fb1965101159dd34c586170491b3b8cca3a9b4f1d0b7438aede0efb1cdc9e7712abe0675ea9ee87e2cd8200cb08bbb85a3f87695c3147092e153c292e5a32475bc4800fa2e3d037070bc6f130e5234f5cd74c9109d2cca14eb83bf61747712b4b9c90933d2c25d876ba1bf7a8e601b472c154c5\n\n# tcId = 18\nmsg = 34343239353339313137\nresult = valid\nsig = 27c677b2b0b546f23d5c3ceaed4007cfff9fc1e0843de43e7ddee8ba32274954d79d9fad43c10e890266123f247abd2ca351a15b196a340b7753d4cd3756a091271a25fbf7834b05ee9c5db4a8a355d5746ff9b0ff61061ac4670bfc9468a4101917ca61bf6da1b029872bc3fe14a306d4d43794deb2a1ae0a4aa5f432e9f33e536f39c249fc3ffc294a466e7bd7b3d35e7ce5f15a3564df9351770fe66b1312e69437a028d07fe31ab3644fa6d16d9e377fc3b8820f79d220b03012add369c630c7c01c123dfe1be97d8d71d491dc38e7781635139636213eda7655eb2ab9bf8c44af43d3c098667c6887be8e7f29cc72dbbbfd5c43ece1a0bdfbd01aaaad107700ed7d9468138638afe7c7ec64e66738e188400e8a71f89526f8170fb56a200f69dc9e4664fc24f40c80e117f3666f91ccbaf8dfae5fa145c9a94ad64219643a66c93a682a365bf082661a00bc8b0a663a6f2efbdae29744c735937c0f0d7f6faf7eacd068cd02c016cd16741d49170bc40e2fe3565cf3866db6fc1d528959\n\n# tcId = 19\nmsg = 3130393533323631333531\nresult = valid\nsig = 9849c3250c03095ecc9ad404f9ee412c4ee797ef0a0f0e806247225fe03b3ca5381157476b44bb8909d1cfb24504010873333dc969f035e08d552c2b9e2da82159619a75aaee04f20c5359450b6d85dbdc98e3174010395bba07cf3e64cd1ee44f81754a64cab4efe7c019e05ba8b3577333fa692858c3dadcb0f7047cdb1d2bf75b34493988ad84794517f18c934d95a7ed5ffe75aa5b3b5608462f18bf5c656e6f1e626d0e2ae4ab7c69da07a2616c515b88fe33feba7cab21eb9869ffa01cde1cf3b318e4b7c7089ec2d3748f93ce3ebcad0d75bc2e5f9bd20f10d6d946ee112be25dd97793f7295cf6862ec116f306d5328759c304329178a50a01ee76b5c5352ae160e0e7116f6e9640d7be77287c3910c929bc3a2a5ce1cbe08e48d5a27a11062d74442c5ec8a92be9bd8aa82db17bec86b2e141500fc5edaad589bcc0a0bc152a69857420bd5f6483aa3db9d1fa4ce7f6a1e20964b1620e8a3a13839311a61031e31bdbbd3e1350d1773ed132355eaa3adc8a292437293c26fc428844\n\n# tcId = 20\nmsg = 35393837333530303431\nresult = valid\nsig = 9d81ba9fff8a9e27c1af56efb4b48088785b9677397843f335f038b46e863045c5c48fc689ec046f87d7c2a1e22308558181a1dd95711088ba84db74ebe33398f77b760c693371a403d8988e3e90d025aede1e7b9d428ee4ce4502a307bd151cdec1ae148c6e0d36d50d3c19eb1266714b0111ace612dd8abdaef969c32cf3bae1bdd4b14cd53b3ffbe59ca75d279be3a933eb3496e0cc5d9b639a5899accc4c91f820cfcc4609630cd47f0f321a349f049cfeb5a74dd1dca0f898a36491cc3752c2a8c30d39c24f9cbfa21cfca15600e4ae161a9834f839878bbe66e201b8c8aa8a430913e157c3c7d74bcd901de43108d6049805bc85ac0b29869184fd587fe46d47eb740a86009940240480d3ba700a7130207637a438746084011f9039e52c1f6aa5c99d7093d14e3b4da4148f825a222fb8b1c35e5946d02ced55443cf0736f72011b129a40632caaefb78c44fcfc31fb2449f2d46c7aa53966b7966eba8d143b3220045991f66b1efe10f696d5d568ea87598ab5fd6655db506bee18be\n\n# tcId = 21\nmsg = 33343633303036383738\nresult = valid\nsig = 8f0c4086ce839242b6696e7e0fe63be07b1da1b77447520172fcccb41f341ba944927acc17cf1ca0686692130be5bfde236385628b0e99bd0b3ac5fcf2b64bb6fd0c8ca734febbd00dcc9b99887dbd4a8c5f7bc97031a7e18f6143d561b29ef3e25449559c5563a9169592efa534fb9b75cacb7ca67b3a8ff76f5642dfbffa93e4ba7e51e8a5919afdbb1c3ec91c9cba076902383614b2b1906e6192b451239870afb863e158f8ec61127f8a7a9442610c1ca47e5a9c8a0f460548320727ef1633cf9092cee65e373ef16322faddcdb4f671d91305ae8b3e4dc9ec65f5069667d462f429b025ee6f05cc38f8ea53f4cf0d81b4ea90f7e078e3b8c804ad2cc7525253fa81ebf50e8e62bd6841f28727214d183665a108bcf8e6f99b284a86b3f6adb5f5df71acda60cb6864970cc22769c1b1ec94abd1fbdd1c21edf2c375bb167ef66538dedde6b6b3c7f8634443ff163482250f1c8e97748cbe8ba0370662b1a10fb58b1ab595e228af813d3fbb852e9b8014a98afd6d96b2e27c0eb7688595\n\n# tcId = 22\nmsg = 39383137333230323837\nresult = valid\nsig = 2b1f093b09ddb27d5c25518781409db471c83e84e50332c47a183a657ce60fd44ad9a786b4d6ae9506e591a449dc0c46f65d9de5165079bf5bb776b70eeb826e3c58dd7a916e37d83b7ea6aef7a12f1aae1462844b0bab4acd4a5c9cffeec5c52b0a6d36ebb34facdef9c3dfc46d8a115d3835cea32775434e78dcdbc3e5444c82c0fa23f52fcaab3b8dec372ef7b19a0b391ffa8110e77fbfb6fea8a8def46a5f6ce20566af9e0918404df4446d6a69300eeadac1b0f5b81625f44cb9abb1876572815c2363e5d36691e070c19baf8c654e6440572739c468ab7589d262d3992fcdb2947d6f18e4be55572437e955d7f8b60ff4b1f1dc9d0c5e6bdedf913225fc65b0acbe8b6baede362cb615e86fa2335eb818878d3dd7bf689dd448205cdf14f69ca5925df66cf421da220035bebe9a78ec5fda4c0e4f49a456f9fefc791fa9109eaacb521e27aee95c120f4f9cde093b7a802dac80810b9d4d5793416672b58ca19273284a581ade84fd6d9bfa31a3b5254bece875a56fb3ad6451b1a661\n\n# tcId = 23\nmsg = 33323232303431303436\nresult = valid\nsig = 2b04d224788e2e94204486c111c0b07540b8e7324a8d57257841ecdb77d6ac906ac795dda72d51b054b5ce6c5232e061a18d67d64c7c1b1ef1b601cce28b84ed3645afc616eed7d1ed7c21fa348a418fc7417449bd997340e99c672a5b83dc43003fff82771a30b7b666fee40e078dfbc7af969d1aadec237ccde38959a0b5852ba0aeb15d8864ac41dacad460e9e69cea0374cb90fe2df0468011409cbbec5085f31684142100c13521742a47af6962e7a38d682f591c8b63fe3f629618afa3902590904f3c99bbd3f2681f42196714cb6e59a6422262b5d6c8220f6564cf35b3873e356015ae3dc6fbd243c29a8b4043a367a49a0dd44b921d98005a7bb0478371710c4a867a0022742449d594a321727776d906e636c4f1c798a65df8184d7c8261413b16a4544c37a8bfd4a3fcc4dd0cca3c3049c0446dc0e27e334c70f66787d8bfce5bd9dc2cc5811ad92518e679e8d219926321b0e7c77d4743db318ac1e47f6a5dbf3f6c53831a2ec8829a07125f5afca4f9f27a968fe5d269d5d427\n\n# tcId = 24\nmsg = 36363636333037313034\nresult = valid\nsig = 3ed79e7805fd64fffe1863e6e9233a502bdf1e35622799a3fd4da76a23a80e3e6fcab61e5c3f621474e91b90a43b36ede27a8627460d04a74677ae0994e949b7b93e01868c5413af61dcb5a9290f921fdc24073e5c7a85ce910016c2872ea410c239af0a33730ed89579f8d1f0743ebec1e55600fea2a3a98e49ac1c5ae12e3c27c32df9ea5fefeb5c4d004cedbcdd30cbfc00fc21b4aa5b172e87d34920c6dd31d9c80db40cadcac6341634ecf8c28fdb3cbae6c236a71322b81abb9137baaa83f65826f1d66e511f727935e01f16cc70c5ab78451f2fc199c02051789c3683bc573190adecfc041405c9a3aa8a6e36b5b4f016589d214da8bbb2e7456b50599ece0d8b61f106955cdd38eb737db4fd52783d60676af30c0d58bcb44655210d2d53f1d7001c925f74754041e94b9251d950784bbde135ef9108ffaf59170fe76d072011ad7fd1cf1ae2763140376be701a5210b29faef9e2501cb3e2769955230bceff7ca53afce8109b7cdd3812f412482f8157d55acdeadea7d9a3b314365\n\n# tcId = 25\nmsg = 31303335393531383938\nresult = valid\nsig = 072389935994033eb7a1bd07c3ddeb07f64589180bb5a0445f7c36412de2021cf7715254528c7ba95605045d2195499e095beea826d0f86da9386078b83a64c4e3dabd43415f68a1b4f08381ed290182727102e875bdc2854a28a725a8b9934dea06a8799c46463a21a9949f8bc19f87b5c0eabebd25200c1aea8eb8ae35be9b153ae54e11f348be421127b4bfa8982cb7db0a122a7b68c0f4496766c9250252c75ffc317e6c2a819edf70609a8a5935fc8e06554b84f31a5a2e1ca855f96c86acc12459cfe92b613573af365502365a3a3f7cd047ff3a227fc09c5494036d39c7887bf1f11dae79f83c0d4fe7cfa02c8e11561f351f86b691a14af945353284f9c7c0ea73d5389049ca0195cb103fa81f45ca01a17c7a857a142223f67c8551303478cf791f0f638e02e60c7f9452f848ebf0b6d6d8d0059bf8a2d513221c385ce075e8abe3ae0a7df9e65090ca2785286b245cf5ce734e4dd2a25774583a4aec4fc1ced402f25c2353bde80c2ef3eedcb5b761a7f2b87c201f3d5f9c08d3a5\n\n# tcId = 26\nmsg = 31383436353937313935\nresult = valid\nsig = 9c43688f7ccc4286e104c653c87979abfb36869a82ff4bc2c6cbeb4ddcd4c51b833367ac00098a84ceef062af0a0c0dec46b54d726f37df117762f83872611aa495a88e69fe0e31e58cee91e3b70987ff17f703a39a7af95ee4121b5bc092bb4a1306435d094a93153ee22dc50d4d4845c60aa065aa03ca6f327ddb3c870ac693b5679ab3390e6782dac49b76f71a0dd6354240184f8dd9400dd84bc2959234a3c9aea08b4ce781d38405eead754b8f3cf4c5bdd0cbf3a15017ef4bb5813bc9bd557fe288cbe32e6f6659ddcb01ee10a48a9f9d33cb5e57164fa77784c89b6e9a55ba65999f7cd61170d826f89e3cbae123ddebe1d2bcf2dac72a798ee9d2a47e80f1e73ad28c6516b271012733e3d8c3db695429d0d67302e5333f1afabe6c36cabac97c4f302e28b3a0821db915b10c1e5bedb64bc5b88d99b7fbd32d3af00b06201c64fa66f38fcf41903a7ef1df4265c0e120d1accb631c43b7b8fd49f8f77e228b550656ff7caeb79378dc3b868ba63d8e97b832ba18224d08cc87e67cf\n\n# tcId = 27\nmsg = 33313336303436313839\nresult = valid\nsig = 807f9a9f0fe0f04c59cdb1f87be60f510dfef3afbf5fc8d13aa735778a4c8823e82804650a837afac849e78c8d1fd81b364e98589da3f2092bae5f7c041ec0c399b994cfa89bc3c301ec3980f7bfc789a7838d212866a500763b5d29094f112ad572b2a825f19510869c5c6e67", @@ -3976,9 +4614,9 @@ static const char *kData160[] = { "714c5d78ca53d36728919a7c4e7069ce97bf215da1d02cf14068c16100f8f78baba2d19abd306e\n\n# tcId = 86\n# ps followed by 0\nmsg = 313233343030\nresult = invalid\nsig = 8574a80f36973bf6b986c7b81bc6d289b118caafffc31d2c99d2dccc1e6611d598dda3fd7c22cf10c7729fa84a87e3f19ff4bf11a96018694b7d829bc003009eb104e8955e8a8717f2fa89220281fed0878b9febf77e5b81e93515a8541d7a4b8a4c008a298d317e7b82c826b5d67bf04d459a5d5fd7f69389dfbb25146c4805cab1aadd009d7b00956ba93f6d02f5266d8b06e28b346b06f1c3501cef04a1c607d7f85ee037178e6f2b0dde307eb6f5f88229541cb3d37e495cb5997264a0c1342713e8548e318681a783381dec9d6524f5c80c437b997f2fb95c80ca7158d0ebd531b4c9bafb19ad9ea0542217c1ad965ee6f1afa5a48becbf65b380f1946dcc85fbcd82fb90011e650dd1e507dd19037ec1f2ac98a87c25a6f588aa6b6f93d35b83c1e8e09152470dae2af8afc1fb2146cd426fe8d3cae5a80c1a63c7fc42825226bec26d57fb62bd048fcd921b8be7aa8d024926fe3cf5c5e3e7f5b2f50b33dea547389e40fd67a8523cd5facb29e97583f26a34f1ed880869800a4b35d6\n\n# tcId = 87\n# ps followed by 0xff\nmsg = 313233343030\nresult = invalid\nsig = 7857b1fe06fcc417c07766a9892ae30eaca65df7474575a70d8e286fc22e3092dcd23446b101cf27951eeb2cf879d320b2bd12f45b79c10018178532d8fc4d708583adb4d7d7469cd5362c074c519106c761228557d4280dadd907b27675e318033ad32ea71e001c3e7f68f6dc07509396a61db29a9ad376f406ff35aeaebf8c6fd0bf7df4bb721c91dfdffa933f37db0bee5d4f7d34f3df2a3a0f383e443647838d7c02ca87d9d79814ee9d5b2860fdfea5577702dbc829610ee1eb13f6e6f0636f39c5ec537c0695bca4971dcab6907e907650b92b96d5d64c6de52c4d986d458f0195345b1e84fbeaa483e3c926167a0d1a977024aef2474c31752515b55021048d2fc23ecc5ec5126c57b18a1656ed49aa90e0cb51e77e56507d7fc60b1f761354423b110d44c67664781e5caecb5da5475b01ab2356993378491c2ce4fbc41badf110c33bd0b78cd19540d8aaf27bc9f3450ce7579c87ee40a454133093ad89b29b99b4b15c21f072bd2f5c991e6a98a23fefc06121ba81540cad7e2a34\n\n# tcId = 88\n# shifted salt\nmsg = 313233343030\nresult = invalid\nsig = 9393a9989ba865a8be0fee265ee6b5b3cb9380019e3c4377521a729a968dee0374b547e94e6b12d860bdfd5197787d35208ae3e8d6a689d031072f6b993b7a8900a278fbf1c07dadcba6b4074375c666e035c2f12d158f626277d7d4b781c8b6bd71a97f575f08c4520b2d66588756b9fc8603a346cec73eba4e8350d7570e923cf84c1b33ad7bdd507d87c3ddf01084703f47d423a5abacb7a6caf5bf7ac4c61cfc91ba9483e7b3cbf9a094aae25b17468fb3a3b6a42d23225bd4859d2279037de2ff446eb441de7060a675b61b3e591a4f854265ffe937bcf575ea85b84046af568a298902774ad9a888847f3d20496d8c570da907686e3441998857e3927feebbf5540d734fc7093263b0efdc33f32f93b936d8f81b920745c2c854266059c92120435b3f41d7a3a5a7d2c3571a15db2136362f736e099e893785876f0ff0b51d3006417235129ba4480c4164329f1f9c6aaf48c93411e388f00cd8b6b125f4f1d3fbf21ee7ad4355a416101cd857f6ae91958aa88b31134a7b6906aa184d\n\n# tcId = 89\n# including garbage\nmsg = 313233343030\nresult = invalid\nsig = b77b9c5862c9fd0f4e4d72fb7bcb23b2a5d2124f13aa7001275451a10148993a3e846e0b29157aa3a1a8ae643e2ee84a459b033201692697eff53b3606e85c6649d76c8288899499f2751918879a034d616543c0b7cfb215744b8dd03e50ce4eeda2891ddb8ca9c568ccf98b3128be25e191a4462f6458c718b33e5f519e3de152b0ec691f2f5b8f3cc150ce37814095001cd60b3dc6e694a3df5aab7a0c1b2dc152c26901294b01cba43b74e4e28d14a9a614d0198c30fe578831c8d1b51b1db0dc34f6c47de0d38d20efd1afc8d385e6bffeae43280f62a5f2715af79af64f04d126e1dd36067bb44d01ebc78769766bd4332a43dba1b124a4cbed381ccb43952ee4cc19201f05558c11f51ab5e76b76b01fcd036a949ec9e4d7153fb25a1aafdc8e0f1754bb59ffecb9a6fd9cb05d527661bc013cb73cec4ad1ab046e1e94b6d518604c7ce7bae1dd1319b612cde529a6ae588c4c6a6a7669e82e141ba6352e4552fdf05d9d1e3fa217ac5b38629d81ed749629ec53f3b30f29df883fa68e\n\n# tcId = 90\n# bit 7 of masked_db not cleared\nmsg = 313233343030\nresult = invalid\nsig = 6ae7425610f6d9b6cf5a358bdff3bdd00802d55cdaba2201794738b900489dfeb11d921d87449ef9d1e5b0deae4bdb26cc13c9916a767cde8e0ef67de6f8042e1d5f600bf707f65380f971222d37088edaafa4909ed566694601e25bec8c3128dd61e664688b5ce2ed2f626a5b618bb10d12cc78ebbb0f3cd6883b6476fe4f89008d9e8feb7e835fa873f2d6d9973412abcf12d2646723b1a5ab4e3b206d49ab6f47789010cf902adf720a02c7677847925487634f81e163819f286da4d42437e66ead9278a088d9a2628aec137be60eac2eb30306e598b9459f0ee1c79dc132248f013f15fb80ba713703b66848612d8f4e5d6bc444e166998f3107b459efc73ebe1bdc0b98e4d57bb960d6db0540f68b96212da6ffb05bac7ace76db7b3bb69188715c091f14354fbb8a02cf2b2d77e7f2e8db505e93603bbfff2f33ba54be38630dba291befeca45c76c67f344b9daf7a7b0712b5a49e7b6af29734516570cac32d02074a74cc0e49797508e1aff2af9f20a7163440fd962bbcc5269d8f13\n\n# tcId = 91\n# first byte of masked_db changed to 0\nmsg = 313233343030\nresult = invalid\nsig = b9bde8fc005ab0b6b0317aadbef7d6e8abb69391bd7ea43fba5a49ffec02979f89d0a9efeacfccabae271c998ad7fbff4442367c07e49a892b9632bf4f30de3e95583875f3069fd3299a30bc21e74526cc51cb10dafe22b06d3a412a6509daa83d337e18c5dee6591a11262e008c3b562a18a9ada3169267eaa849b16a377b195ca6f83df0d2c2945a3d3fc2b872bc2ba965ef4186ad1e7ea5b56fb689fada3f377e0897e5cf86906dd2d894848a6f3d64d96a5523fd74d2e8418809fcefe5b9bf12f5ae7189e2aad268e835b5a701073e26be131c9dac06203142d93c95af3d00acec603aae2a24bff3d5481c7e71be5f63a1c47eef680a00991008ca0047c7bef7812c9b823a64e6cb40d0fb4472b702bf4f1c9483f835812eb3f70808e3dec7ab2ce2d8cf1c0dede8521780513140f10d84727d4f14ae06f65276feba1857a7e879e9c4f59c80760b117e1c4083e342018da1c42adc6c5255404adaf8460d122d3c670aa29b58c087d118643eace86667e6bad6c07f078f9cdb8618b48e92\n\n# tcId = 92\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 872f410815926494669ff81dc7114e096f007790f6a4ae3a946b64984eb28bf28351616cc82ed34172f1d1d0a8918f87d64258328db63b72127fbd26320a21c114a7f0b6c88ef717d949f57a28e66244b1fbaaa942d3ab2245ac76f0cc4bafcc119a64f7d167e3e2a64dc9a004464b28bfdcac00a24ed7e3689ca1ed23480c1a0625601c4e7f1e374b54c1c1fbed91e0967b40a3920210b84619c23217c2a6a39734320607abee432c7ad2bb0a8b735400bf775256a61324d4c4ee743ffe99a7bcd13a27b0fa33c0dfbe0cf9663116997573a59204c62aa497e98a698b5dd19314de9ef95cb8bdad0e07b722eb6795f6ea8098b7b092f7bdf73aa459dd85843b310d71e0400470ac14db383940519c060d111f0b80896083b6fb305ee6d9d7879d177f7cfd85c913d226fd6c75f38519d7e8f6d32bce50e85901fe6bdfc74997862a3b809e5ed5793013cd19af9efca616a9ac3e346136142374f58ca823b6a6b2870bfec41207b0a8f58d72c119e319a3934cbd40451f0a1e26b447a5687b9a\n\n# tcId = 93\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 5e0a2f627d11c2f5c2a61cec6b9ab6ea6f2620085e52ab1d162365a2c7040178b3e6222503efdbc66eff0cb892be95abee6ae02af0a29436de4ecd2ff63eb7e082d51ab31d358309747ce61e30df4ab3382341b88eb2da84406ae20fb3bf9a968cf5ccc871be02f6cd9f2a89ffc6f3a69a589526e8a4f1a8c049286ffca8359e81cb3173a2d2e2cc76a4829edebdd3dbda327a92dd35202b597bdf077d7ac2924f8cfb29a85dc25dfd2ab6e770cc80120a7bd594e020392e58acca9d7356773e58aacfabd66c2d9a888379b73868d07e3d14af1dadc1843f2a6c8e14c93b3b29134169c5ae3b293ee6f6a475f20c7c159258a8cf1a1cede602afa9fe7c61a3218c34024a87bdf4a64ef12c78a11a50bc1521836bc4d84eba90ab1db1b17ef0e6e95d7c9de5d6b84e11dd5422a869ecc7f90f952794f6093df89fb664aae86669c63bd46de5972388d81908fe56c6bd029e393047c52924a97aa55c07d482f98b784e6d39cbc280330a34ac4a8a72733235e66234903a4505228a3fc8e1146034\n\n# tcId = 94\n# last byte in em modified\nmsg = 313233343030\nresult = invalid\nsig = 07f0772411cdb1e02802f8ca699bf55bebadd254c9aadc16e1d6d4af3e12670bfd2adc2dbe80195f065d75fa4a25ef757766fffa4d902b386a9c7f247206f60c744938f50d6f840170ae94c6792299c386a1d6d7aeb73fecd5b72a28249a2ad771a5518fb694f54924e15cecb2d755da44b54535dc6f8fce0e91ea160ea942c9e34eef5d7367c9065f5ac270ef11a35bcedf663183f74cd2d504410b97b4034a59d201333f235f59924aad30fa877a31e0c1573f62e7be41f961e9c31ec334153d83adb0ef38963f0f5e20c90b67ae5c5e2ef8520587587c22e869881abc6bfcecd62a1f878115e6cbca7259e8b9e116fdeed841f1d698e85f65c7ae07421cf3096f6b31a07e251944bd7e2cf50ccf69a18de7c17700b25786d29ed74fe8d5757d4dabe2d6fbffc2227448ee8d5559f992a3b635cd74a68c329f1785e743ce9d3bee57b997f9ae2deb531f8994ada98d9a3536b074814c2d5003d6a3d50a9e56287f3aee8ed87104c19656a6057515fe17bb2a72a53a7c19b7a814252c8bee61\n\n# tcId = 95\n# signature is 0\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 96\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 97\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1202\n\n# tcId = 98\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1203\n\n# tcId = 99\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 00008f9ac1354af4161d0e55b5674821d02823b3a6b3f79cefb98cbc77f9ac2d91cc6345f989a7828132f73f3630a247a936b6a057b3e5a2fda0c5999ea7721ee8880960c24cd2377e869cca1799747142d57ad6a8d83ec9254d89f591add11a758e1ea1e29bd08f624d0e28cea52ed5eed7c0f5f49d3533eb1cdbb2af837dc42942f9a86b5f4e2d5ce506697ef067a344949bdd89afcc25978af4d50c300bcd0ffc9d93cc559e3ae1a13215a1d3f6030827340c6591061a5ab7e65153b1df8b25e1421f924d39c7e6f76243c1bb9ae4063d9a475cd2ece45f4e288fe0720074e87868d70a5584a9ac2b47a56417cc76f15154315545a3ed6704b365f15d34320804469c3b09ed211cbc9e9e767b6f21fa16f8641d8b78b8dff8062a25b5bd3b6a38cb4706c42c1fbbe66db1c05cb57531132eb94fe1569735c33ec491c318a686c837ac810be4afff605f92bb390e7ab3cd24c0cd997cf13f112e5aa01746f43902432639e1eefcbd37b413c586f057bcba40a8f1251251e84cb7c87c53c1d1d558\n\n# tcId = 100\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 8f9ac1354af4161d0e55b5674821d02823b3a6b3f79cefb98cbc77f9ac2d91cc6345f989a7828132f73f3630a247a936b6a057b3e5a2fda0c5999ea7721ee8880960c24cd2377e869cca1799747142d57ad6a8d83ec9254d89f591add11a758e1ea1e29bd08f624d0e28cea52ed5eed7c0f5f49d3533eb1cdbb2af837dc42942f9a86b5f4e2d5ce506697ef067a344949bdd89afcc25978af4d50c300bcd0ffc9d93cc559e3ae1a13215a1d3f6030827340c6591061a5ab7e65153b1df8b25e1421f924d39c7e6f76243c1bb9ae4063d9a475cd2ece45f4e288fe0720074e87868d70a5584a9ac2b47a56417cc76f15154315545a3ed6704b365f15d34320804469c3b09ed211cbc9e9e767b6f21fa16f8641d8b78b8dff8062a25b5bd3b6a38cb4706c42c1fbbe66db1c05cb57531132eb94fe1569735c33ec491c318a686c837ac810be4afff605f92bb390e7ab3cd24c0cd997cf13f112e5aa01746f43902432639e1eefcbd37b413c586f057bcba40a8f1251251e84cb7c87c53c1d1d5580000\n\n# tcId = 101\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 8f9ac1354af4161d0e55b5674821d02823b3a6b3f79cefb98cbc77f9ac2d91cc6345f989a7828132f73f3630a247a936b6a057b3e5a2fda0c5999ea7721ee8880960c24cd2377e869cca1799747142d57ad6a8d83ec9254d89f591add11a758e1ea1e29bd08f624d0e28cea52ed5eed7c0f5f49d3533eb1cdbb2af837dc42942f9a86b5f4e2d5ce506697ef067a344949bdd89afcc25978af4d50c300bcd0ffc9d93cc559e3ae1a13215a1d3f6030827340c6591061a5ab7e65153b1df8b25e1421f924d39c7e6f76243c1bb9ae4063d9a475cd2ece45f4e288fe0720074e87868d70a5584a9ac2b47a56417cc76f15154315545a3ed6704b365f15d34320804469c3b09ed211cbc9e9e767b6f21fa16f8641d8b78b8dff8062a25b5bd3b6a38cb4706c42c1fbbe66db1c05cb57531132eb94fe1569735c33ec491c318a686c837ac810be4afff605f92bb390e7ab3cd24c0cd997cf13f112e5aa01746f43902432639e1eefcbd37b413c586f057bcba40a8f1251251e84cb7c87c53c1d1\n\n# tcId = 102\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 103\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 636d31d8d5dfe0fc6ab01ef2ccd4602dfea62d386b002c429e7e846e7a98d0cb1d448d25be039d5158887ab46a9dd49c41537a89036a065fc10329df051e5f2e5c1d4436e84790ff6db4d3f31575e5f0fbdfcaee625722c5492fceaa3fb29d0a865200dec06e117b04753ca9450a7ca7f7d1a1176cc38ecab721864413a0d7a22d8fc1595b6cd0032fbf154fbbb31b56d3bf963761ce8ec9fb38bba3419716d0d39e976857e79b1faefd5f5a2ce0ebd94968da1ec3a387804694d90f37b34033c7f70ccfb26beffaafb7bf56c1b8385d489217458e0a68b5d680f9fa45382fd1c227ff3c11e3ec82426ec648a564f0e886e5b12e695dd2fc8465bd9d08731fb140084c79be64d915bcb4ba10f1edb4c37e35231753be2d9f339d37d7b5f22c91584a68a973f9cc469a23d3b5800157dbd72a8405fef4e444ff01f7fd23efa143c1887504e81773743843d8a73209a1deb66c5f305df539bc30e871332e82330e5b66fa6ea253b2b64b4c9781011d20e80ddd8cb83916834eb8fa696b0a4b6bcd\n\n", }; -static const size_t kLen161 = 115183; +static const size_t kLen215 = 115183; -static const char *kData161[] = { +static const char *kData215[] = { "# Imported from Wycheproof's rsa_pss_4096_sha256_mgf1_32_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082020a0282020100956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed0203010001]\n[keyDer = 30820222300d06092a864886f70d01010105000382020f003082020a0282020100956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed0203010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-256]\n[n = 00956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed]\n[sLen = 32]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 492e60b828a9847501c7ff46a4a304ee7bf61ae87dd88cd5598c76289a70ab3afb7fa9efa3228a1e826241c13c2e120d22cd3a38a9b9ec5826a9711bdb119748e0f7080ccf917e8cb53f6f21ed19f4ffad9efd94c66e329226a811eef928816b5edb3b10d1f483b64bcad9b055dc78e99491560f59a598001e76a0bff0ddad4ebfd565495e2b523b02dc80050b64db4a200b5ca9efd8a1339d6cdff6a82dcbf769d3b0ed7ae53ea8f1788eb025e186a5eac02e3e1fb1f0aeec29b2929c7a718c32159609f973109d4a876bcecdeee6c6418df27fa46eb5cd238e274f94ab571c968b2c4a838cd812aa90e4657b95c0ccd68d60bd7d33b6e291a6a13f68e046cd41ecfc2bbe35fa9b4a0c17d89a708f89f975bf5a5eb9abc812b0c498d93d2d161f5c7969afbcf798029f3c14efc3f7c265b93fda572d265e9e116ffa9416e111aad32072f61943e9f0754f6e116ab5119ed09bbe245022b6e8bfe35dcee4a53ed375f5451c43f38f6eb55b48e386030cfb76c408c81f606886c81aacc76a999735682413069cc016f6e390ea2df7e8e74d088fb0643aebf4899ee8177a4a5faea3889181612ffdffcdb3fc699d578eba383e23e1beb68824c0bc7f920afbbea8ce7bf2b7c3bb40f33c6b7c8fb6cf73e6e2f3679669f235ddfebeeafa872918581d99c84d6dc37ff85949449d3994982d332cb9f9b8aca691651c4b63e58f6b38\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 3731df2cf46de010d06775044db5ad8c98fcb8bf2be357fd39af55a864395bd24fe7cf104374159cfff1b537bb26ecd67a0488ba7a124d8273ee0b3cee00bf94c5d34900c4ccd6e200cac6e90d97d8b4197ea78ad36be7a4fea6e1b43b1ed954c737bd6ec6960945f24308b085e255c1142c61af876995bb5736ae19ca0e1cd9b319634ff7103a4dc89eaa41c00cd173236c275c463a1cbb67f65e45b1bcc4e10c7f3456911e4f9ac4cee8b43651980dc2e8c332e5452e35f256463b96bb21799e22f4349846e8a2583763226b3278134b9313757163ce6ce0628376001fca63c535d384a6aa7cfecc29ebbb5cf6be9d2b211464e02a09c089fa63cdd9571f3fc559bd2b92b7a5a724d3b88fb4e42079add87ae188a983c11fb769d3ce65fc5aa27dc17b6914283971278a749101e38d3b92ed2817ce2b37d4dbdec14f44f2b015433cd6e5a5de6d803e95b8b8196bcc4a77ff6a8419f5c78b4dcfdae0f9f98e8ab792cdc18645a14604a604a417abcee8051aff0eab887f235b1c6143327a0db2e00a63e4c6b8e002f21c86163de68e49c766fa91ad956c12d36856cf58324d417b4898aaa6db3eac372f06ef21d7a7e86b540972dd4e3f7afae7caec8a692f31386e7b3e8b934499a945cdf556eae3010cb1ece6a08d0dea9500157e78117d0f4cdff096fba973f7c04f79bf42a54e4a82e5456f065bbe9382605c444d21cf\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 2b981b661e1e244b67e1892bdab545edc9ef68b50b4572a536dd4a40f31195648b8180454faa8765ba19b7ac6a59176c1a2c621e6f4131af96beb4ea47252d7617b9d8b432b5cd900f7b328b0013364a520ce46ae66a63b7181ab60b514839ec8f6bb63ec2f83a2a142d8ce532f63ebdd3f29ce26797f46f68481818ff1e00c47df1e7e8d809737307a63902c94d9c2ee5c69f1fa0602eeedab4d7f6d0032de1a8294c117ad2aa34f1175544f2bc1d466c5965ae5796bae216cee8bf7b91f9746a97749cce0388f8f443d14317e825cba2ea278045826835dfab50091cc988fc12d4913920cd625ac321df4d89175ba3f49f89d372318bc222643ab888246f8e5ad64f227be043bec3828cea0bc0229be6e71a035dca97bfe0c2f34ce03c1ee9d084d19a6d6c301168129a6589cee1119cee84e35b561d1f658b2e4f16c2b4ac2ded8ed5757ebec2d5ed59c66f7bd932d64c58af7fc16af4d3f6bc42897114c9ec537f8b7ea86752a2a26133a7b8085f4d438ba643f7a389a1c6811c2ee4eda48060d27e6299b44c8d504d280ca56ca49c246b5c4c897d3e1d352e047f735cb7e30ce87061ef267bd9c50e7de77032a162ac9a026e684bb4d0e8131a90240494418fbe471c9900a6b322306e47915f83cdd8e525566e8a71dfc869ee5c7e74d33ac8646d7c170ff82f2f3e5d319dc61cad06235145c031d03cd420fc370adb3e\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 75fbc044fe19c72f459b5a1fc4793f7893ffcc95bab8609900b3c3d3be6643a42987c167e7feb63ec2a57f961c1b9c35b11b34044e065d7d3df0b49496dd80f7cd1eb2e8c0d0b726f37e701ba62a3003a17657af55adcb0b6e86f95198ed435207663d616d516bf7222db241094849fb232bf6fbeeed7b5879a6b6c8aebc57646117220bf55403d0ff078e219ff119bd2e52e767b708b91afe30e9be348766e7537e1128087b4c9aca0281415e550965a395ab20d423330939b4e37551a7735c6df2b0395dd032266ec7dd4afaa3c477c64e3f95ee4945960b7a0c43b7a9622448eba4149e30ccaa0c234be7b06f4ebe8ef43063c62282e0643c6e483feb1942e3310bad0c05bb2f87674825fed098d5c787b69c5ba6a1f716dfa62ede3b8a01c076598b15ffa2e2be82fd1d8025f8ded14cd8fc8753ef76419e1dd561bc0310b2c7845e2744c9621735758645af0252315b6a05894c264c4587c8870e02e94813fc3a797d590a9645d92845b614b0d89cfffc0b80c5b48186ae350d877f0bc06e561770736342f00d56b2ae785891afe39cc0412337e4f5d29ff06d727f6fee8f0966d52ac146ba82a753751ad786c9d70ccd3005b11fc4f6b81517433a052c2351390332bf7fcb4326a19930b512631317c0354a81ec7c529ccd1bb2ef206d697999950a539808958d6c2be64220123f12e7aad168be35de70103090937f44\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 66381e10ca91edb043adc721883b8c005eaac4daf040379f4d69a2bd7ded69cc6e85d80a6f3ce8aad523a5d185cbb2fcebece5210feb0318065ced244ff73830cbc628d79572f7f0961c111883b9c40336d110cdd4dc4b9a04ae4a0380e8b17f0667b71b2c5bdd1c9b48c4e83694820d4cf4200051bf3101559625c0d06fd0996b759e9f4c689610e41655b262957457a4d8341c65bd89dd438025699dda37aa2d05", "1cd3c974103aafb092e865b1397661be3eee3f95d7a75d9a2ebd74e6d2cfa54ff0d8753130eca1555eac4bea45e90a6a37d7d057ccde4c32e43c7499d5c38754ce950308fcff69d42aa4a4fa85e6d92bd20d605823e198e94af5ad65ca4c2fb919391f919aa5fe048ff51a506f63063cc5f777fa70b20cf759a0b812b2527265fc7f32a40cc275ef94ebb4a0410280ad658e67c34d581b5e7a17c5629be34ceb70ca68f40aedaa3c9b7dbcf34f30f12789909a3540512044bd812760c3f76dbc644b89760b54d9e090dd9cbab935597c55fdc6793f8ef007f732732e3d1fcc3e3ed253689aa29acfcf85847acb74a722533b0b5debfbcd0b5388f6b19e8b9ac47753f8a616ed9a7e4163ce8669437c62271bad3497edf3b655e4d1523cd8f3448c5d07c48dcfaf1e1f8310baf3d3707ea23288911fdf91d7379738ba8fee9ce525ca0b9c4c03bf1bbcd7d1369c0d2f5e0127ce2d1f95322c94d4c309f2e8\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 134d55894c80eefab7744abbc9fc5cbc087072da8243236fda9df5ddedd81d23f0998061ceec59d1bd4fa2f404547056f9616f77843330bc65a2d2386574ec9198b2abcadee4139074c3208e2f09eec1e527e26b78b8773121f852bb8480e22b34c0e1cafe9bb224ce6243c46c03cfbd0fdaf28041dba177ced1a2ad70ca2f1e7dddd6cd137732f4a774e47eb59d8225d4c6a507f8f273b600a5b6449d63924b3a0cefe987cb5998dffef835dfe3a675442c90d02067c9b3ff0e3f1d84ce8801bf366e040710ad2c08c9f379bd07797ed954d3e15ef1350ffef88e9bce7174466358effd2494d7e174ae88b04e17c5ffa7b63bb6cf194d007b3ac22113fe3a1dc0c97d3853aa67c892d7d6bc5b0be6681e18004640416587452c856644ae6c07d135afae80fb80132c1faf56c5b224923cef5abe9969b807023fb84146a62e19bb6d8e5af0475e07f48b469ba3178c99741af6e57aefcb766ead4ea6cb3d172532704818fd82e12132b6329dbdc62e4c9da1fee2cb19e4f60ebfebc681a5b892afb812e82029123a7414f56f57e09731fe107f682f10a5c31fdec1d60118cc3646b0284e1948b2bd37c280135ab587960fd0769629860d17c4349271267a89c26c5f5debfdf40d843428af1010f87ab73648ac1c698898717889c38be7a06b7dfe9f63a9c7a19a77d61e3235ceaccad99cce004d6a870b27cd13414383ef4aff\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 7a7848548b15bf23e4dc1908e5b3aa8989936c498e77d587e64ebc9b335ce6f400a3965c027c6c248afcda5c80efe8d1f1bd9e71a5c459aa428a4ae1d1cef91ae48788f361dd440fb3cf745c9935664e43b81e9f860985418b61c3afe63b85cbd07e7dd3601c8ef8b7467694e3221ba4ace737c3134a8bd7f7ecd84d1382a93e5c9a6b69c9a8f12cbd612e48e5145972a1ad4f92cb0a57f44e0fde4548d231a5ee0efa8698154c66ddfd8fdbdd41d1476bb5d8852663e4b7891755ef9fa7b5d508b190d59270d32a0a7f32b1a28570a7e52592324fc461a32bde7e2cd14b04129a400274e4183cbe44aa4bea3b4680061b119a97da65c6ed4bff5f2f59193ccdfa8d021816a2b5d32ac52414d1c51f8c198f4c03e0993f8e47c268598d665c2b624cb66ff02219a9100adb3ca9674ca1b63d77d6156307efe953a489529a1701ceac83ef1134e7cc7aaa578fa4909e9c4c0220a5c882433dd3f0af1d87bede7ad979ecc9999cccaec3c4d39265efad3c39809ad3f24fed3982dc74c57ff8cf1578d940f9c6d351aff9cdaa2481d0f355054389ab2a6edb6b5455677d828453cd6aa21000adda95644125cdc6b4a4f95cb69a1abd23b46603485e696dc419cbeba767b2fa7081e1641c4b2daa44f5fb2b9a6513dd12d6f12f0f1cf7da5a74223da8dc390468e46af16583faacb7fc0ef4c095c641af4d76be03e880d4f4e2c8a3\n\n# tcId = 8\nmsg = 343236343739373234\nresult = valid\nsig = 303afbfa17c9c8d18b64867e7293f22c8a139a6b106ac86e9a59b590f085d572a0b1bc177a35e3ba74d66e3c6d9f7b5daef34e03080d13951fc2e73cd1c7cef4a815071a089964c35afca9745ae54c1dc2443c79ddb9f111182c501177fd6351dfa8a980f1ba2c99b489b78c3e31002007b00850c52e5db7f6cfab31ac0a6c8f6d0516e19304e8376088aae408ba6f69b2f70ebecd64a53e3da851ec36cccdb7e317a4f4a337781a7e9b0c168af765431e7342f53164c50c12d1e33b5f026a6cf1925b76869252d290ed048ad6c88b0010ab293f6d15d05c884f5c830fd09d107bced6a0697215afd121bc137438ebffda18b1a6f607625813ca9a93b54d8ad6be5ad5aab808d5fb5293ccf6bd18dc920fd72c258572b660fc2072251488c8623e3d2bf988a72fb289be8046975828e210217fd04d82c5694031be9a9f2932aba449da9d21738705a513a5dda2f277ba9a017c6363da9042838aff0c9ae4b5655580e74a95459666108fd5d870486b7ce4187f057fca8fbb0c877e1fb3ffacc26732c26a50c581537adfd596baf30563d7d23af2d68395f774f52abc238738a2fd15d1ff2046e07c382d176d6fca5348c1a44b44bf89883ca569b7cb9d7b8550e65229c4fb21e3dedb80ed3ec51b378c77750617741976d5b2f764c7db5e103651782df4841789b6993c5b73840038cad16b03a368dd6684b7a90ede21a2ed2b\n\n# tcId = 9\nmsg = 37313338363834383931\nresult = valid\nsig = 245258fbe3957df086cf99d113f5297d5287f6809236e97e398a4a66d43236dc93c5ff7b089260ceeb8312ed7c7fc2a0faa6b5933adb453e0619ef06601d5b2e2ba8b43c76704c29f45416d0085d209911db798c0aaaee221d795fac94d66d9bc01eb43fd9caa23b5e34d33cecb735319133696aadaf316424a9bd445a6b8bd779791edb302f352b1460a69a25fd14432cf043fcc4f1ae1b7bcfe6955da3a89d6abbfa08e703372b977c57a84ba81f7cb51bd58a9929a8b8dff805aec99b03a46ce82a16d25f6f30e501a9bd0fb8a47105893c2b361f80f2ae872e5358290770198cd2b5139c234e70b80aa18cea9d9b94e2b3c46e9311b2fc513e28a5dc83a4b1603d59ba12f695656fc40bc6f890731e9d990242fb79f5fd2111ed7b7019c0f22c1b84e382fff744e9f0476e4eef7259730ace36cd7b1747856fde8d1c6883df62b20eaa58d18febd316091acbd323903a9351016d089ba51df67f5cd14114b8530049478883d53f0376ccdc8ec472af2907a5463c320c066ecd8aa6ee8cfac58f67bc051685f0d38bd2649442aadfd87749e22acabb6c396e018d623540edd2977842ebc518e3b2954a8555de5d4b675027488b52f8ce32ae864b9e965163b0780b53e8e227e914c139f91afb662b9c4fbf21bcb7b43040113155b97571806c112aae1e9da34743df2ceea812f3b931f33bb103d9c5239c92c701c0565fb0\n\n# tcId = 10\nmsg = 3130333539333331363638\nresult = valid\nsig = 3f4d6ad95e3b937372ffe704d32b54c879f04e85dda332b360b2106942c45c7bcd2c7ace3c7cd0b585182a83e89a34809fcd72687c007c9a2ae07359449ff983bb1b5c3a0fb44cc694eee28b87d961847fd9a3067697c3283d4e8b79fc086ce77eccbde90a7960d9112ac4e9f0ce5ba897bc564b3bb6fe023dc369c01724455eb40170d92071b3cb08de7cb55300b244992e80c2e181d854c9974fb76bcffd3b9389f37f39dc0c0df15584fb6ca4c29b1fe1dabb1570a235f5b17a283969958cc7eed4a1d15eacf84f8cd7214b063b79c976887039adb9a1456f022c11c4966c32dd4c7782a187eeff40865ac926cfe97a8640ecae28c5448e8dcbb50279232f0dc597b58dfc4ce53d9530584a808cc7a20dcdc90024931732b92ad17bee31b60e7e3d6667d809e4bb02caa28d3676a7eb5fccc841385a010597b02fdc728715fda89cfca37c72cec44b6befa8093b99a4cf0a81a23e484a671b589437b4e6a953e27e7339e00cf0762b9ba9aad64170b8f07c76f2729771b8d406936fb219d3decb9fa075f51ca804f7ea59dae8f663e49f6b007a0300a28bb54707cd891439207104463907bdb7f7ce2c7861888ced5527f91e6f52003fce1090d9231a07303a416138118be8c49fc919450247a9004164030bbc69534dc7f61867f494682884314dd0fd6573af2cdc3e86ce5c9dd6af71dee512c78f8cd5eb4cce3967e349\n\n# tcId = 11\nmsg = 33393439343031323135\nresult = valid\nsig = 8732ca98efa135da433f00d9f4f5d76ab711876cdcd965598e243a7e68565eba7d60a95a5838dab1a3e35051cdc1ad7be6a6a872ec631c8f23c84ff831a25a01f3f8a49547ed98ecd7672ff561c438aa86c5a8a7fbc07ca1f6437d6e30b695ed81111365f721fffc36979ca2d1a55818f5a0fcc922dde87ed5b76fc47d5f4ef219f05668feb398b77573f9b1232f090647a2632dbfa3ee02c585660d76f2e3504a682382606a766e214c51a2813b730a93013ddf4a7ef08028c8e444da2b8d1f583780bba7148a010314f2588310da17845a0ee37dd6308d1f8d9b87a88df57cb1d530441c6a2c7a18fd47b4b7f89353d3108e91bb584c2c98a74e413e8e3be7c8273d0822dbabf96970c61b104ceed8306038a215c61f15bb4743dcbd80de6ef1458923213f7b27abff0614b6e1c3b02c4011ba2a6590fc9577687a2bc5267762367d7b62b03110bfe5b8023ff6a7c46e46a5deb7a5fb5f7b50207760e449655bb7ad84638091119729758e11c30c7dac2f0bac200f0d62e0c603a9a6a4110dfc70ba838bc76aed762cc9a7c3830428f0c8c68f7972a3ed68f9895ed0fdb7a7d6f206e8cf44100bdceb126ff8a5bf21b1e6dce17c3bd3b8908a8f4aa1d7f16800185d96332be6d5c3c5dbe0324d1cc809ce72f1cb1696c5574b13430687b2ddf1970c5b45fa3c4df55b46c88603677f29fddc4eb302e2490fa09af3b14d8f9e\n\n# tcId = 12\nmsg = 31333434323933303739\nresult = valid\nsig = 4e3b548219cbdba85f3ca9e739a153e8fc69a4974648806eb92cf2484b00dc272b4ae4b88db9b38a5e4320332c2ea62448c08e44968fc1ea1390f66469ba52d4633ea98bd3b6204e813bfa3353dbbee7c0c659279d7bc78770290c444ad6105ea2634fcb66ae0535900ef9cc458ff9da86e40dfd4e51f6bdc7b221641f6783d14213b6507ffddcda844ae38b323c6f22415dced537575e175633997557af0990589f019ab5ae99e32557f82b1b9c1c54e9ce289cbc98fafacda9ebbddf5fb3d99fb73e4ccb3d2f2ba889bc47207887f646d529bd1cf78ec915efb3086d6d4d664e8b07d094bc88d8e9fbf6b2ef22e56dcc7ea634aa021efaa4b85aa517b748322a8e0ee3c53324865a8bbc545008a5b855e9813418db9f74b178c1aad20e52bd7679d2a651760c6c195de92bfc27fec2405bb4b267152cbde712ce658a58700eafd2b0d3f06ead2cca73ec56cf4e55b5cb112263bdd8636b51779fa27847b2b658b39cc023df2d67143922dbcbbd07796d7702aeb831bcac758fa50d578996b5da3ecdf9799bf27989e5895bc1d86e99cc8ee5629479e99f2c0a038d0531aa2fd6cffc52bafa4406df74e0f33ed33fde3b4f4caccd06b68febad7f59e7e9", "51c95c24a588ce25d5e92b9b411d8b25af54e87553264faa6c5773d6d59a01252bcc05a40f3bbcb995615cb85dd1771cf05b75305b5dbc9ccc8571c0290905c22bf0\n\n# tcId = 13\nmsg = 33373036323131373132\nresult = valid\nsig = 456c58e80907cd7723f351425750bfbb8fbcd7a42794063f9c3093180a79c9b289b0c2e7db35cf0e90af75f3d830cf27ab4fd739e1db1e51d32baf5c2c219e2db5b856b5f0fc49fe33b32cb53f6201b47b320bac4f8e26d461ac6bb4c54a8cb3666717f9fdfcf148410ee6e2468394ebaa58a23fa3c7349ede819045d13a082d0304e5d0dfcef237c661884663dc956be112d47bbe627a1e66deaea251aac624ff45b15a6cd49c50445fc6f3e8a15caf4f9d082fac7b788695e3401b5b80fade651c1fc2404f5ad45ed632bddd1d02acaa6467f0da107202ab964844dbf00a48716e28d84176aa98ecb76ab52c631ddb9e1f06e6655cfb9fa1bccf05e9ea3aa773e540d0e7937f78e754a8ae4b57b0ea7d3e7cf42686f229e425f00cacf766d0c56de3151a151e12204c04d97a1470903e78cbaa74ab12955e1b2cb162acb07aca887507a661987e83fa9b0606f2b0d1303a709f407cb6866a560fad21f60a65bc4db2440b1a0b349cc29668a9f32a6d6e4ca7ff2bee3d670402fcfc05a51b988deaef45b6504689fbed8793f5061e50b803ba73843f3d8ba4ef097ff361a7cb58e95bc740d93a8420f81c13ea40f2f4ec44a0195d010577fdc42fdcc9b17a0c273dc79b48bd417c980258689026d292508c0c21346b6d9959f900cb3d7edc5acb5ef2e1f75eb3560c82a20e7bfe4c151792b3531c708744149faaea51a9e8bc\n\n# tcId = 14\nmsg = 333433363838373132\nresult = valid\nsig = 70aeb4087275eb488c13af70b3bd01ed728cbaa7e9d23227b4852d07bdbddbccd7e7e45cbf67a3609cc5d916f090bcc003ca86943a56b99482cba553f54a6c30f9cd09832caae0eebc61ac2824d1adaa448e3ceb6678da38629b2e3dbed14937881cd9887b23b0971b9ad2b30d63f553bd6d8235185b43f7a1db62952c4d0aaab7b598777a3c6406c5fdde2664f0112269f8a02dbaac936674f08330dd7ad49d7aa7a43926f9a40824a386ef0002963b2697e23db3bc227d12730271e2842ade151db6db670cf849ed14279b1378291d32fcc4b76d918ee5a0b64f6b5bd43d84fd5258f53d908f9bfee9b9de510f6e94ab4209ead7d48d4b1bdfc13afbded36d85de2adaae2e72beebd2b83208b7171d1618a66016e3c5f89364c9c4b8e5c33129f85fafe0e48080b6b78ac0f898f73f9635d8e72939a039d56e59b359f5f7e891f81c59369dc97da667b8e2a2d86f84ac9dbe98eed74c4f3d73809037ba17467825fa21aaffd18daf6bce69b8a7b88974565012f9ec01a51646884c1e64346012448940c4b3af1c9f86bcf656ba5efb0b1e65e8f9bafe42295bca712030ef6cef2d8dbb300ee57af3cc40e19dc1ee4138e78cfbf6f98bb8ef278dfda3b2464bb0bb6c9cdfd19e1b70004c994d4ea2962c4cb66e4fde4ce9c62b05cea744414da3cdf41e6285c1134ca53dc8581c6090f2f4b649455cab26912571dd03fc4ba4\n\n# tcId = 15\nmsg = 31333531353330333730\nresult = valid\nsig = 27b2c163e957b544022b487423bafdcd96b0d6b8b91f3df95e1b57679a5ab1c046de6dfa0f6a898a6aa1b5a81dc8eeb113fc992f4c64486e29b733fb4bf040afbf2a033eebf837d0823c46a70806de28a2a2ff3e39116e726afc7d400864bdefab2edde98662e1b6b036266fefcbc6040f95ed6c316c0969bdd3aa93db59d9e51a5172adf71f1af70daf873485523d9235c217407240938d5746dcee5b978aab3213b66fb75fb685d99f99160f23290baf90e9de690e1baefe716f119163653d35d7d638af70712fc97def6fe88ce8520e695f8a7b28a1ce73f0b9d6ce433ac0ed5446656a9b31dec1712d3c0fb6dab5f8cfb7fa3858bccb01033d9ec092a2f7f0caf68867f90a0318dbee1d40edc4c8ec0fea960ba04262dd7b2e48a3200285705ab150988f0b4fce4fd313d45f109d1f4a7c1c184d9123e896981b81afd280106917dec36f5b0ef5d3a71bb37a0e9c42491cc28bb82c70256775a5f2cc5bafcc15a8852b41ac59b1c7f654ca8d80375bc49e2e6b415458628d965d4ef4a751701abd20cc9f45e3cea908ad75e3bc258b36f584e60502e7cd02d2d4f8976bcc52695adf1bd6325e06ffe0ca161be992b4fce04d2440d6035164b09a8b955673e201f473c0f759b27e892c7fa61483743e25af670833f6fd49bd606aa04369295355a93163faaaec789400ce03067bae206dc58c8c7b4157251e63d683257c27\n\n# tcId = 16\nmsg = 36353533323033313236\nresult = valid\nsig = 675b9dfbd81c45913b46533153fa93161adc71cebdcd218b534c43f24b59df6fe8311da886898300e818ccfb8911d740cf619edb42643938185db0e2749e1bf4d6ae5a5c2d7c4139c339ca64e8dab0bbaf762c5a6cf9b6e04c86e476a6aec56c110a94c9ba0545f6f7fdfd08510f555cd67a9a8fe12f8d04bc00634bb3f84fc92587a3d4a9bb121762d8bd21c85462ab0f33de235498516ca63e0c4e157fd3031d78da7117f46256fd99cdd5cb18ac82d85c4ee1fa954e603dc09367a979d452450a63995eb83bae1d371b33cac539083eb52894f534d06d3e091e8e6a1dc8dfbafd4abd4df3fd5aaf8b93bbd1ff1d26ba7d1aae04e25a1fffb6aa7c02a4e75dc099d0e3d8381d7df70bd2558113c52ca8f839487ff5571c2a12c4c8596b023a0f9cf90958b69e513e59ebb5bb892b9b48c8e79887551e9df73f8f1357947f9cb43583c0b775ab9ec0d89a700cbbf935ab3ec00061b8d462b83c496a4b8abfb0dee0c11b4d5e3b6912a33599b014b7c381c2d8e82d06197cf2c40698730881de5df4e7202fcad15bce63c6d08573cd7712551404cf830967976e258f903aa518d7ee967d1c7c319bbca1a24420ed6beac83719c43214b9617144c1daf762b66f22bc34b8667dccb5b3bc980090ea22fa61c68e9119fd5f3d88c84e2ea9f83f0dd7dfc76b7535205fe0c4f7798e14f5559263dfc3666e9536e8c79445674dccf1\n\n# tcId = 17\nmsg = 31353634333436363033\nresult = valid\nsig = 1d1824029de39c7907288499362efe10d06179a8211e200f73889c1b9b68f7bf0ceb17ff58dfe494654e108864a2859075adf2ad2bb2e66a061ac9330ca9fddc525b3be8761f01a9c3eb7c9286215612962882b42ef74a2328e8e4511d3a589653bf0e46f299a52bd72a697fc6f09c4ee62c2d34d5487ad8c723faf42669583f2c7418c5c3f4897a193a19511c19840eb5c2c71b81023c0df8b1c6d3f27a880547dac9b12e094dc90904d47473dba66cf61207c709cc57791b0786148f62c591f72e46754e3d6e6f838c97397c5bc90e6079bed3dee5cfaf3520f50e127be6ba35cd9783b46424ad907a5c04edec02560c3d72179a6ee5cbbc9cc2331ef0fb157ed60ba4effbaa9a208ef03e1a4659d2d9a77f36fa783aa9e6dfa72015f6d6a586223a4640e04fe01b003aa395297c8d9579cd3b8e0134a06ac361819ea8499e010615478cf3d883b8f6a1ed2cd83cda71c7a595b3582ace4cab76a387f9f1f30aba9f5fc6ead0ad95343156a734645abf5b2771299dbe5daf2e2be5d4f1e6db93e92ee5202b7419b47ed5539d14d30d099d39f504a4162bf8a16a986c5cbec2a7d56ae06d815c4b91301d235a3d7e5536086699b44e5b92fd723804caf6acefa2fd58a9dde0c0524cb8d5a6288b05490b1153792bad9fd99ee696aa3b83d8f04f965242e98b1e6a96cc13f5de46a2fcbce6bdf33022f7860faaaf6d1ff0a5cb\n\n# tcId = 18\nmsg = 34343239353339313137\nresult = valid\nsig = 7eba46db8935bb9f29f3e5009b8ea19022f177fbdff7b5c11ac0fe7fc31ed63cd12685096956be4cea1ca37f738104144ae4a62591a467cfaa68b7e45c76bff4719026f4a5b1ad2e1a587bff308a27647c93cd869445d23043f87fb1bf0730e6f620864a61a097bc494eff10ae87fa270180ad0642ba638bcd53d753d2b8ecd1f70dee4eb0c90d1108677ef19a13c5bbfa2b1a4fecccdd54e15909fc73e2947677bbb4cfd097b3933facbb3d4b608e600d06d5ad53ce537efae69a5c6ac257c850eaf211aa58a3836368a21498bc63aa271ad5e8bf169ee149eb7f761393061ecf567856c64ef7575a9785d2c482cbd9a2999cc6499cd39103ec8d91ad3cb8cac0b4588ea1cbb8a61cf622bb638db4f0ad7ca8b1eaf9d7c60f9c7427e08cccc25057f497bd444aa11da061daaae0e5cea7e6aca793a51010be4b4c500af433abdb21dab5f79a84c302d290aa296f03fc1a4ede683762b72bfd2694beb537d06c750fddc312eb9ffcffd25558d88ddcd2509ff2f2615c5f9e29e6d1bab5145c6dadf490aa978530eb2358bca9759434f765c07130749d3b14ef7c2c5e45547d6a458fd3c1f80ae725a24b72f896f55d40da4a21b3612849d18119d52b962302eacc6620f3951e2d41f544801d4f1007479f89521e023989e9eb9865989fbc18234a0d07a89c9f9b8d051ff1eb5d41d394ea8045f94980020cd1c1992cdeaf5a27\n\n# tcId = 19\nmsg = 3130393533323631333531\nresult = valid\nsig = 90462930f56f9abaa7d7cd95bb07bcd9108fb5eb9c0595e5a370507c457e188d2b6d4fea1f6d6ab5e3b96c1fa140ef5ecb43cd48f942387fa155d2a73a19f759c681858150a1379cbeed487e39bc74a72d48d8a8ae1b40e894c6dff19f4e2e5116b3cdf078eb2e30393e3580bce971ba0187c4d90203de37a1c13c3ea40cddcada0b15ab8c963c95a8ee80ff1fe44fae72d18ad0f3af1567e5ce04b4722f93b581fa42731215b515f572cb98446a53614c93afd5f8d6742e0b1d7f449dd39ef1734cf8e04e61fdf0b7b2a4ad44615f88f7e1d4fe105fccf397f9531f3833f0ed49679b91b067b4f9ca35d53c4e6930b75bdd03f3cbfcdcabe7f688f69e88a76b31bcc3e200cb5ece2a90d77b97f4f1b192694d92904def232ce4d7775b94956c75ce8820dced0786c820c2324b400c951561970e769b616e605eb9b5f873a71c168e38285ddb572200903c24f8dcca7a6deca91c27d053d87d3405dc5f7169cd7b54c935f8c90b3cec4046077d1d84d8acdf05d7a0cdd92ef6ee59edfd067cf00e7bf4e911b877f60b957b88f0e71665727944ff95748c47ebcafe04009a3f356c3edbc423c7a31a9e8345dd9041926d388dc0436b6d514d10a3dd13bc0321f1e6f56297294d4e7e2d77ecbbed84dda2d03eb9a846b3ab9402711d72af55face368da74ecb263ea9522d9a7ebbad4063a3030c3bcd4b7c9eccd8eceb34af0047\n\n# tcId = 20\nmsg = 35393837333530303431\nresult = valid\nsig = 6a411380c1d5066a8555fddf5d4827fcfb0db89b1c60e071e24bb86773f951b5300fe423238ab7df1c109d854f6804aba4901ab6701ea545a8469500dcf95e7fc9e1bf9fa79b5031f130f583d91ead61ad11fa2c5a97d990909eb337fd48eb3bba09c761f0dcbd48cbb2bb6c778131c3c6e73403ac7c0006139fabaec0d91c4eb1adc39e6b0504a77140e685f60f5ceda237f47a5ee4ab5383f9d579ddde74886a0daf3c8efbdb7666532a44b7856d13a5f75d1656e5c6a9167d26a110c902e9b3c8274e01f0", @@ -3995,9 +4633,9 @@ static const char *kData161[] = { "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 96\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 97\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = 956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ec\n\n# tcId = 98\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = 956353ecb7561945dc5544e4602466078c93f28507701ffd39e2a9813c8ac8740e6ad61c955d484e513b3dcea527e001a018ee2c207c1806a96763280236cd3c820dff79837c9b709cb4b522d3ddbc9192242259c43be75ea244d37ccfa8a4c75024a2cf7cc76e842ea69cc7ca1227405b070047387a5068e4976e4b8ed5f9aadd7b4db024fbb8d7bd8a040d8f6610c1c6eb1d4b606dfd182235d0360880304d5a750603af0c424b8c8e6dbc12c3697d2d609c97547e774e2e362ea96d1690dc9432112c535258b3db2c4c32ad510d6c07ad0788357883869efb8b629298724847925cf42b34386be700f02903db5852276bee2370941f397bdc3905e30964a0b5e73602703340960c3ed6078263b611f197955fecce4b9a32e43cd1d2e5e87c4ceb65edc8853a7ee31d28e16e5adffb8ac7b760fbfc63d5f174f4d0936461dbb12c964a6b6d6cee752e5fca1ab4a9fd238dd3e8860a1d763d2019f9e7b99ed7666d4e038710f90e0093bc566987d6c0092f571376e705b342d066c54e6e2578927b92c1f0928de44e9a6e1f49b907c6aa4f605ec9c398d55df81c67373b03cc8110162fb417f96fd321048647dfcbb392455115cd912ea83351853e6a185284648842adcbd25e67174a3b93b8a64ce2ce9de0e8577b8b662ce32e2565782665dd38e5bb5fcc4fe12e4320dab7773b545a09c6d39d9dbad459f21f3e624ee6ed\n\n# tcId = 99\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 000075fbc044fe19c72f459b5a1fc4793f7893ffcc95bab8609900b3c3d3be6643a42987c167e7feb63ec2a57f961c1b9c35b11b34044e065d7d3df0b49496dd80f7cd1eb2e8c0d0b726f37e701ba62a3003a17657af55adcb0b6e86f95198ed435207663d616d516bf7222db241094849fb232bf6fbeeed7b5879a6b6c8aebc57646117220bf55403d0ff078e219ff119bd2e52e767b708b91afe30e9be348766e7537e1128087b4c9aca0281415e550965a395ab20d423330939b4e37551a7735c6df2b0395dd032266ec7dd4afaa3c477c64e3f95ee4945960b7a0c43b7a9622448eba4149e30ccaa0c234be7b06f4ebe8ef43063c62282e0643c6e483feb1942e3310bad0c05bb2f87674825fed098d5c787b69c5ba6a1f716dfa62ede3b8a01c076598b15ffa2e2be82fd1d8025f8ded14cd8fc8753ef76419e1dd561bc0310b2c7845e2744c9621735758645af0252315b6a05894c264c4587c8870e02e94813fc3a797d590a9645d92845b614b0d89cfffc0b80c5b48186ae350d877f0bc06e561770736342f00d56b2ae785891afe39cc0412337e4f5d29ff06d727f6fee8f0966d52ac146ba82a753751ad786c9d70ccd3005b11fc4f6b81517433a052c2351390332bf7fcb4326a19930b512631317c0354a81ec7c529ccd1bb2ef206d697999950a539808958d6c2be64220123f12e7aad168be35de70103090937f44\n\n# tcId = 100\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 75fbc044fe19c72f459b5a1fc4793f7893ffcc95bab8609900b3c3d3be6643a42987c167e7feb63ec2a57f961c1b9c35b11b34044e065d7d3df0b49496dd80f7cd1eb2e8c0d0b726f37e701ba62a3003a17657af55adcb0b6e86f95198ed435207663d616d516bf7222db241094849fb232bf6fbeeed7b5879a6b6c8aebc57646117220bf55403d0ff078e219ff119bd2e52e767b708b91afe30e9be348766e7537e1128087b4c9aca0281415e550965a395ab20d423330939b4e37551a7735c6df2b0395dd032266ec7dd4afaa3c477c64e3f95ee4945960b7a0c43b7a9622448eba4149e30ccaa0c234be7b06f4ebe8ef43063c62282e0643c6e483feb1942e3310bad0c05bb2f87674825fed098d5c787b69c5ba6a1f716dfa62ede3b8a01c076598b15ffa2e2be82fd1d8025f8ded14cd8fc8753ef76419e1dd561bc0310b2c7845e2744c9621735758645af0252315b6a05894c264c4587c8870e02e94813fc3a797d590a9645d92845b614b0d89cfffc0b80c5b48186ae350d877f0bc06e561770736342f00d56b2ae785891afe39cc0412337e4f5d29ff06d727f6fee8f0966d52ac146ba82a753751ad786c9d70ccd3005b11fc4f6b81517433a052c2351390332bf7fcb4326a19930b512631317c0354a81ec7c529ccd1bb2ef206d697999950a539808958d6c2be64220123f12e7aad168be35de70103090937f440000\n\n# tcId = 101\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 75fbc044fe19c72f459b5a1fc4793f7893ffcc95bab8609900b3c3d3be6643a42987c167e7feb63ec2a57f961c1b9c35b11b34044e065d7d3df0b49496dd80f7cd1eb2e8c0d0b726f37e701ba62a3003a17657af55adcb0b6e86f95198ed435207663d616d516bf7222db241094849fb232bf6fbeeed7b5879a6b6c8aebc57646117220bf55403d0ff078e219ff119bd2e52e767b708b91afe30e9be348766e7537e1128087b4c9aca0281415e550965a395ab20d423330939b4e37551a7735c6df2b0395dd032266ec7dd4afaa3c477c64e3f95ee4945960b7a0c43b7a9622448eba4149e30ccaa0c234be7b06f4ebe8ef43063c62282e0643c6e483feb1942e3310bad0c05bb2f87674825fed098d5c787b69c5ba6a1f716dfa62ede3b8a01c076598b15ffa2e2be82fd1d8025f8ded14cd8fc8753ef76419e1dd561bc0310b2c7845e2744c9621735758645af0252315b6a05894c264c4587c8870e02e94813fc3a797d590a9645d92845b614b0d89cfffc0b80c5b48186ae350d877f0bc06e561770736342f00d56b2ae785891afe39cc0412337e4f5d29ff06d727f6fee8f0966d52ac146ba82a753751ad786c9d70ccd3005b11fc4f6b81517433a052c2351390332bf7fcb4326a19930b512631317c0354a81ec7c529ccd1bb2ef206d697999950a539808958d6c2be64220123f12e7aad168be35de7010309093\n\n# tcId = 102\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 103\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 0e207de1295caadb15098f51f5db90f9f000776055b107be58bd24d52a01d4171cb9e47a40790254f86a8a56c8ae38252f909aa3b9bbe7b7e1fed008105690d9afa647067ac122a272d30ac28213d2cd37b45cf81dc48d59e87d9ffaef6e1c9cf6ddf4ea5ff6123523c9cc885344b7e1ef4c8096bb542bc0fa5c47abaabca9a58ca85bcf092924741503a0f3c54c725c48855dc434b09d761f729051fb15af5612bdd387b4cd5019577327bb2e64edb065f713d50ff4285f1d184fe709207f809b9c38d064722897a868f8a09bfe1d33c80be0693e98d7e85600befb643e9f713584c716306731d7f8087dff66be1c4f6dddbc51b6ffe6034845cf0f88749e039ec314887c94648154f", "7c97235323bf78041ec2c8ee98ea7c553ecfec1f9fe89279c9c91ac6acd12ebe969da4c67fa6534ef9ace4b629c7b1de8c4ce1dc2b0f5bd7d416db6eb512a4dc8eda0322138cb7c65b9a58d712284e4aaf059db80af5785af4d83d391b7d8bdc4071636712410d1dde662478eada1a2f1f35786b78eec77b2788536108e7463d676814a91f81fd5e2084a8c1b1cc33988e73184110c6e6b0ef1de874104602eb33b5276ebbac95d91b943e25de6dfc66b31d8091961c78dcddd358de7f25584d9f74dc6271ff31294bee2cc9b2f97a2583c9b33243600500bc723b05d65839de7442895bd57a1dd508651a20e20f264d8dcb59d485247\n\n", }; -static const size_t kLen162 = 189086; +static const size_t kLen216 = 189086; -static const char *kData162[] = { +static const char *kData216[] = { "# Imported from Wycheproof's rsa_pss_4096_sha512_mgf1_32_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082020a0282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001]\n[keyDer = 30820222300d06092a864886f70d01010105000382020f003082020a0282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001]\n[keysize = 4096]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3]\n[sLen = 32]\n[sha = SHA-512]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 8d4444ab233739c9d1441e99cb4f71581ed78fb996ba1257fffcd9e3c74ff60d6be352f002f959ff66bc6ed0c987a070097e5d57d8bd89b4452a9d2ca121eb6a283e8d0ef6f5f67875b6cbb8f04e6d242900d73d5bd7b59de4b9466ccbe53874ed422610e411fe3e026f47e47b8686b9c891c7226b4ca560a840e1734eb4f6fe877e559c9a9299dbbcaeebaf7eecfce6fe43ffbc483514fa3aabd6959e5aaa3977e23a9f97edf406d396e96c3c830164b10abc680bbaa6d99d19765d7c7e77946ef6ae240b5fef0249e7062792b15c8f9157da95971afb315c9c015c74a2e79ea2d0cc46992704872c340781f052b4b2cb5ded8f5cadd9b5e3edce128ef2354bd0411074d6515251f5231453bd530222f730ec736a86f721744267ba52652289ff6a207a5a7c45c20ec451948d6bd7b10f1af7282afed9f5df43e4a0d0f2e8fc6d3dd3130d4ff6fbc11f0ea460089856df29d1b7b111095754a7de9bc03029c6c397b6994674775fd29cd22ffb03dcd90c51096b18a6c174f2b48d50e94856f5a22adae64915d69c5528dac0345017c24e8aba401c6e9a0a268057a0fea237dbf0c88906796eea0d1bc3c2347cfcd812217e26015825e9f0fac404c22c26272443ccaf30b294c7c467497ee561a2a5f6d219973cffde9aed8e4486faa3de3d17405445e2f78a768dcac1efd01596486c2495f5bb1f830a4984041e03a7bcd77a\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 3a58fc64a234dbd7be958d7c34abcba7d780ca636c4f2b2bb7fd3d4e4faaea0e17226c85debf8dc9b1a79e152a3bd83b13f43b1e92be81b37e908d04b717251e32a2d49e2cb5f2e7dc18e74cf9fcf0c0e246d473f76c79c3d50e878a2f89bc4eb6ecdda96c166d6a825a1df569d11384a78d7052782ace5878c41361f148c54528288088716f935d3e5b5d556a0fc9b62c0de31d9ddf4893f82365111043ad7fca010d1fe9187bde48f78cf465657e184857451d64564a16a166743870033e64125ca3f20ba80c065b259666871fcfcf71e711aa34cb70ad9a2ac6051fc02c96149d4e3c1741c4d44663ee0b49e1ba60a80b4c2d389ce3ba953d68bec835432bfe170429951f82ff51f408aff052c934d51526117b3d57ed1f2a912b37cacdb5a980d30d223d79faee7948c5f4986c1df5ed42923a3f4342da02a41872db49aa09d2d48c3b3e1cca7114a9a34e76b747ae6c99141c9f856e41d98456b3fde7d26bf842d6a421b3d4cceda4da1aa4d1298b624159a1c83b6fe5cb89982eba5e7d6005489d39233f156817c00c04511b98463696f8b6b3962ca3f4ef76b37300dda1d368c237250baa057e38658882f482d024c26163dc1fdac29904bc6424130837b8928f764bc939f006913ab1e968c85016dd812dba264520e6380872587265d827557eeac6498db8137dd2ae029fd83250ab7dcd764d018ca05ac9db8f95e2\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 7c838ba65f923660aa4ac47465eb1df4df51d6fa2be26389757de8c6dfc7746aa5164d909b69b7c04758d256e13e3520e77e75b4094d8b0d60da0030b9c991969f6e892ff03ffba9b9f95ca991a279e7cded611a2879e6e6602f411a122c8d11cd333de5d2f7f367e38ee0491380e8796e113487ec7bc05ec1b1261aff871ef82cdd12f4e3d8f239cd49b2f53d57255dfe6ef29038831cdebe9cb1a76dc9ed79578e129b063724ccb3c7b3269f5dd3d9669a405582255cb56b1efe6d61a376df3a141014c3d660b66f9d1b266b5fd3c5472534df778e6e022a8f5a6cab501dde611e07c0c8eb5718962692e8e3773bfd25f1d3b63a20a251ef0c296f01f4a17814e18dfc029f2ed0ce073e83777cff44471f9348434fcc12b0420bf2de1c9018f0282ee21f09302b178f8c772c8f8962f6a29291c63532e1ae9301e7ac55781876965f425619a92559f33737d5e11b282f9434e27d9b27eb2fb0fce4e3e90ca9eaafef170644b00e512537bd779fd2207ee73020aaec07e6cd44103a14940c9499b013c42440d2f27a3def34f3509cd8631db1cc8633ac15180272c824369e1d3c8a6cdca511748361cb60e022173f95ad06e7c79d59e03934854a9f9827f3593d87c34d3fc44beec58e107d454ce04b55c96effce612aef0e5d55c31e367c9fc0166f2c9d450e86d79323d4da8fb409f97adc7af2ec6772ab290f622fe1fa61\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 4a80cafbe2a6095f8e8663f6289878514d7ee7daba0c1b0a077cefb333cacdf7c116ab89b0a01cab3161c68cac92a08aae7d117c9a3416d67365621da3380a85ff34a7a3b512846048acd1ec5957af942721c241a180a5dc5d8f6f6fe54d4d9fcb3709cde37081e2233b4fffa201d2029241932da170a5bad0d927a803a7f6289fc9f7b1d41cc1a6c94cbf588d5492b363920d0c98404f5da9eb9457648e2a4e9a034b2e2328c7f8c0e794771641a981df765887b5ba19b769156b375535911e1a2da68bb6a37eaa0ef8dded4ce3eac5caff4e8dc357703f0409d00baeedf3fbcbd6895dd3938e1f03dd9f131f9c979e22e4fcbea0c58721bc72d1f4976e93fc1a7649a23745c0310181031ac34b2200dfb4e8fe9bd4cdb52a23c31416745521aa4861eaea7dec4ea2c18ae9f75fa9d36c9b61bdc4185e434f8cb091cd731607b749a3990585cbbea2b1c0e0fff4f589a547d320bc7923b8a6b594c5866095df9c914cca80cd6c0e9aa3d691e2607f9de64322031ccfed04d9c805226cb476d3246d6caa1b04c63372a77668d5edf06365827b80391a6abd66010e8e1b873bd83db4dcc99444e109efa2414c6e5319f30a718eb43a1256b2142afa2382316e37aebde32da5bfec93e89d2adc39f62aca25a2289933a7cd8234d72a9b3c6a001d27560f8c8a2d9a233bac0b519b34f4f79288ea2cb08a87242953ac24ea144143\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 3d90ff4e36188b451116227e189a71734571b72cc6fe53dec4eec59e67e98111e96fcd906509fade9922f2de6a13a4faa23c7efaadde6dfd0acf150541eca973c7e38a49c597d741e99ef7575b6e2c8de0974bc868a5567f0890052c4df54d12198ea09a12bdb2b6ffc14a1d874e165ed12caab58b28aee171fa7f1839e36e23ecdee2633616791179084eaf98cc23d2f6ff479df0ba46ed933beedf07cc0cad4dea", "0f0b48f4a063488ac67519e1fb83c7b7e86e3644b0846383ecbb1b1189743036b271fbf121e2199601a3ffa8e8cab00a6b9b5527d62dc2a398e4a42c1e5a62f8aae35b629755119c54cba5e860b421845f9b4422f20d896abfa962ece5d116f7d4170db8dd0784b7625ab2a384c7d424c69901f59d03b144241f8f6556da8e3bfe07c17eae91c50ef2c53e71072c3ff16e642cf126feab904e09a2febebd282a2540389bb60b145cb332658d6a69e03a0a8419eec0f204d6e592e04df01b92f58236989b6b92eb0344255914c25dcd0a611c9fb77e435e2ef9bbe3c74efe144171ca95d1bb7de814f76be54cdd8c11db8af8d20af4451a4dd3b62387bac37cb79755afe91d0d9a2163d299ff61ee4fc4d5267eb8c5252371b0a83dea738f6383e085e992b3567ae170780f3b83e15d895ad4ea668a6304f10f0914ca3b2900fab1364c8b352dfa8d5a3993d5628f4d2264c412210798c18aa2ed6aee516c\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 07440a61252a8906a9264ff58cebad6217ad710833105369b7a858216f1d5a5f5dedbe3eb8128b34dc0f0243faacb64034d21b656a278abb26ced174f76a22637b755b768564db6ed4e4fba0d5784a22be30d088fa965307430982f84476907d55435ca3d4abdbf689e76f2d4b78d99bcc742e0b757b897c4fdb13d15c5057e6816e32c3e294a947374c998550173cc657ce33f9fcc18b2d14e1b448acaaef683ff84b086f545a05414589b1c23210290ed5ebbc25af614129212d3853ff728ec01128d37c4268975ef870a1e4fa00c3c98b39c3110c2c11af10333e25db027448fa8f219a7dca7c8bfb490912bd5040f1f348b2fb437a8a9f407ab7e8af1c6e29594f557f2e03fe74e4fbfd2f935e68ed824a510fc39bb4be0a2e091feb265fd2d7a33d2f238e70b153700f5bd5046aad7a6fc02a5e23dc36f67278fdb904d05f2efd0cabe9e4baf4e16af0f7ba9edad706d67c67221ca0630238d6f688174d66c1b152f8f921e2c6c08a19e870eab76a77371b42458dff1c36b0ae97b811e900f6c09e792c89644448f1d0b97b53b9818d1d8f3d7a37bcb1bd3e3a5bc022039f00a0ef7de19657c4c9e06daa2ecec2de30db3b7b84107bb74e164956eb26edc9bcc57e5e1c4ed875b02f0545383602faf9525f094c72f682995d4e2d71d03e11134495f637a3b1b022153689751b63521b1a16b3c3e269a2499a4be1aff9b8\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 2686029fb11cd033724e57dc1835da4f9321eef330747c3500a4893586429ebf02cb4424ee5a0b91a70eb35cb05ef60cf6b3635d4f2ef5eb647f398fd44f67fcd2969b629a7c54f1094f9827f9f27457509730f50c9ecd2dc83bd13f1268d93f0f61c29c5c27eb821c68edcdf1b01f79d1f261dd7f2f283db197ab56cae0ea3b3c1cfaf3fbd4c1ed1f6d313f0b919e5fddcb97b23f0bf64e36bdb6f7cce8ad9cf362953e66c644f8b8b64bddff1e850298f5531f121e6821a393f9658237280c2a53c7c658319bc7d38f93f2d7723ef6728008843f89f61f7ecf5949a2cce6a9fd9dbbc501ef25a53ca02486b61a5de0130149d9d246925f26e1a9a74287439592a4554a872ceca53e54d1c1f4c4e18a4977939a6c37eeaab5c8d0cb5686b44d84c86d736ee8e0d97421f4c8935e926419dd68fd4e5fe9999eef75d0d0f9494cbb0297fa066b3aaca55cc229a36659be310c1e328d0b52f7747c62b1102a2d0a4acbadf0acf621a45e5695ce1393b3eb05a69ca5318e6f6b7ae5c4ed3f6072f8ae99db9af66da6a98d675a35acfe0a7612e9d5f29690870d81114279010bf7bb3d458f630f10f81a785f671e6735d7bdddf4da375d2e6d48ceecaee741a33ec1e8f9e0ce0755bec28315c6f9df363c800ee147bd412c5ea7aeb89e7a354fcd3a2c8474aed04f9a2a5fd2983380f3c00a4558c46ca472a4c15887c07d4bc8a698\n\n# tcId = 8\nmsg = 33393439313934313732\nresult = valid\nsig = 69b292ceb8e8eb52e374140501389ae251d8451b64b9efbeeaa16ab24126f38f2a7d4e21981aee6b672df3afec1a9e167686b6238b2d3617c659ca1331470e95234e2c04c308cd6bdcef7631b74c36a752eb4187bee2dd33c59f3fed55bee29ebef7ea61d26e6c052a2b519702282de7652a500fc50956091b35f9ef03fc9bfcc72f02dd55b25f88b60bf22aa785f674791e4dc02f9f2f7f04a577f860ea1761d0d8d3a0082350551786c62789b48fb21e85ab6b05f56ba504f7f0ecf8625aedee4de0c95c4f97fda57929c399b6d4865b78eb2d1da433f2488b4134fa043aa26386b47f551d7778bba8b6f379cad3b4894e106fae90a2b391e859fe8bef5e545ca3d0d908133285273fec3616798b83a6f7136faed77ac31e13a3745de44bab641f559ef5487890261ea80cd9bc67c58c7e14e9821867ecfb473b47e95bdb0003cce856f9192e39b86f551b0e3b7342598cb34d8905e117cf85b828ce0aeeb55407785e27a9687b59b8c5fe011c95638c8f1549e95658de4ec73199e3bce9a14860a0ac64ebf20ce5f0083594f40d6c2a12a07a512a191072487d8741766af953365f240335db17d4fc57390ee0562e4f8dad03dabb113a665b5b9174c1c128190c335cb748469ba2bfcaee5bcd25c845bdec81508fbc519a8837c059427cb3e0d1ba0bbb6e79849fb6a2e7f29c7d778f957a7e26fb28534ddd85ae59498996\n\n# tcId = 9\nmsg = 35333637363431383737\nresult = valid\nsig = 28dea73d9efb0b7893b1493264c30a72708c1a28f10fa9b8c7af7e0f52fc5f533012c7b87c7005857f9c55386e81ec54a94f71364798a5d31297a13dfadab5b032052ed34124191d2a94023e27a7e6cd948e21ccd33bedd37769024e97ff90db92225b6b5c0643357d80ca155a69b3173755b88fa83a4367355f1921474f97fd2e1337ae93e2f535d81423177725404acb230144a9d86b74ba3c1a6e724a5420a12f2a19b4ad6984c043ff63eb14a0cd494c0072c40f54f4d931804fe63d9bfb97ee7de83e943e12693bdda14325de9d7ad605e7efa7f42b14657fdc2a2e8fa3de31bfe2560a034aaa6de4b4ba00b056ee9d060982ff77b5e2acabbee33f3df9e58b2782e2f99a6d8f1c6b827862b5b04a02641bd1331c73804e1322dd2edb621508aed4f997458a3f52380d2ef83e8c289a996dc2407f16f6c848074d12bcda0b5050140051301371b51e808f374685f728e24ae3e937ca9d5ef890e0727375e4832c8c07cfadc05b098fd50014d6be7a0aa2a35ac990026f5550427db3b2345866d72d3085594e2161871a4ece9c55bbfbccf854a7bae0631ff101d887681006388a37228dab83350e5a15c96f7d0397cc62c388e8ce6e13b6ac727df4b1dba0691b7b96574d0d024cdb0e329e94a128924772ebed4eedb41138e7dd99d347ba50b83d1547d80b85f98ea544aa63dd725f4ec61b1b3b522409a1369b5a9d4b\n\n# tcId = 10\nmsg = 35363731343831303935\nresult = valid\nsig = 19085093b94a6bbc8f27edfc375a736a9e086f98b1d6e4280e6a6f6e8dce1f878b4007ef9c55d3e4bbfce9a6fde2c6e07ba94c55bbe8053a3a3c08c5fb981960e82221fb66a95553448a4d2f8a1cc588bd1e9c4064e9b6346bf48b153262035db57ee6cc5453483501af3668a645a930332738782f55f4524b1de5787b4cf94c2042b43f47989295c8dc1e0bb9df8a28fa321c16637e20fb409f55a21ea3e29e515f833e18485b501442269ce5426a20b77bc3a797a8fe461b1e02ab4d2fdeccc84ab2b9a2f0f5fc68218dcaf140dfacc70a990b2157f71815049d86e43c094b956e6a1915ddcd3023e6805f9267e96318c466985fcc3eb84db972dca08c84a347aba687053871956edc2bee98207fa1e984b1bd05ff115e24bbfc706ca9fbc916565a3984533a281e665dfb6c8ef40852059993aa6d87d5d1faabab4e0143f1080a4ae9c8afd4886aa21ab3a487e316fa95dbcb0b67ad4dc8992c2beaa48cd274f3506b863b33d761d8369ee1e1ca85f5c86adc826d9adca6ac77fb586423eba20ccae5976f9feea127c720ecd881bdfec17ab1c6f539195838ea99d4b8e612933cbf8c7daf928e99c603e0f633e5d89bec797eb33d782769e03c75d04c6f64f90ae54a47f9fd3835a263ebe8c61df8987443ad8ad327aa2b9facf647409828fc9716da00f9ac1d932555c9138b6b9d23d9c6d1726d63c1e42527bfae0354bb\n\n# tcId = 11\nmsg = 3131323037313732393039\nresult = valid\nsig = 882a00befcdf655539171cfc51083a011e676653b03498c5f05a4894cc3ee7963997cb440e279acc5ba37f0f675b7de685d3f29aafa58fddd4feca007c1e96d0891f9e7407030fe288ea91d579d3d6e5062f9ce14aaf9b507b7405000a0a4ae6f207f756677276ab25352699fc3beb4892ee2c4fd416e59379732e1fc2af9e37bb6c49d4a9538f9cecbddb571a5e3f28d266a1a2eb3d477bb3f13ccf776101a5bb37ce0dab135f4a5976647ee50fb8c8fd829812c5f686012a48a6ef6af6a88c5e805cc95b5d0c90ce568b596b2ae2e5934d1c2dfd7b2966e52fa145ecc3d94cb7cfe3dfa4cd8b3b42b780a212678299a2ad2c920f386fee15085cfe225798f9ea233b5528915d8a4d530f80dfe6b20fd4fae2a80ad0ac3c3f45d99313801c1a06cfcd311fff3cc409ef375f0c2486cb5331a6f56f693f48596edaac25c10fd3f985b565e657570cac4ab291cc963ed196455f7285368f6877cf8c74ee7fb784ff192638415e4519abf74d82daf72cd6794b9e82258bc1b73f08c01941bf304385a3a80085898b0ef5ec929da0cb2f27fc75153c11d0699bad1fe8b1d357ee601d5de2489166447ece43d84212a88ee665c0890347e361f362f68a195184b224f3c2f0228350e326216b043a56efb4779aece7d5bb512e3113d611db9767639934778e442f838e9bcf2455f3aa66f5c038ba28a3a8838d2302384ffff1cb6131\n\n# tcId = 12\nmsg = 3131323938303334323336\nresult = valid\nsig = ba12cba0e650918ffed25cfa35075c29f2704a11d2698311965905bafa47ac53f0cd688647e298e3bd3cd380558b6d42e1ec16dc58f6175ad2341f93700703f9dc8617e321e5246c15d371845d4e67cf04f7e51b5328ed5a86464ab669330eb97749a10ed6ca4e052a21fda6ef70de6b49fccd8d6db530beb55588d85fa05f1643a79d5ad09003ae2e5413a06a189df2633b742bf43a8ab4a473bced22e6ff46a687b5a43d6d1e1d1b2d1fd96cc99e967b83c9841f4e2934a7e044606a73f8217455beef7926f0c65714cf50d2b5e06f59abbb95a489e8dd1725b9ba6d5b6092fd660091eb0c4f47e8a9844dec0e10cc1a61d50792e1f931071188af1e800784d202f99edf2b7fbe28a120b692ba476aa431765208cf493253d73763d36c795359c7146b2c82b635b4d6ca0c1a007cddc0385ede1c589cef90f02178e302bd731b37f66fde283777b7e02b77803edf808af7c1c71d0a321b7d090e299917aa21be4a9a82ece8bca006917fc0d126cea0e7e64f6073e10c589aaf3ea25211417f2c3d12d7066aefe4c2675d8022fac6506d12e8eb19af5a2c82829bf64abc4b52846191cd6dc555585c17aee1d50d82ab3a580d616d988de71bc7ed96", "5a6cb90702ee4ea29af392e4dcabb97f7dd7148b811a93724b40bf40a40ecd3729b99af580484958e1884e4947cfeddd5b3df5b810f65dff9d460ce273987f58ca57a03a\n\n# tcId = 13\nmsg = 39383736303239363833\nresult = valid\nsig = 39de8c150be0071d220697d5ec83166e42d608d83841cd01eecb5b63ef1a6638befb87269077ac7ebbedd0e368e3e3a87c63163ff84ba38e51cd346a4d0617704c1ce5780e1e1ca4d2fbe72b82429ba00f9311d2ee26075e8c045ba3f4f4e11c5454819353b951e684c829756be54da216d8d0585d23573720516ae900a197ba2ddd95c76a660726780213060c0a527e4e1e70eb4a377f7766237925fff87ce798349b4ba0fd3a0c89a7403b9e8ad657078166aa427ca530afae4b66233b1c601bf043c1358a73bb85fb5b4b7f2fe24fe532400a99f778f27a81352ae27d2ca9f3af99da7c9156871b7b4f0f649a3bbec0156e638f270af6e2e3730fee4500be694b0eb4e3066d2b5fe29fd91f1bf55747e6ef9cf106eb3bbc3772a8b181d6a4878531586022415f6be2541cba38f7b950f805b4b8d673355797ef0b5e58cb9e3dcb97d6cfc182ab493c5e04f239caf2c925ec2391700d501e5d4a7a7ea08b6fc9ed56c27460e7d717aa9f8100d76b57b4fe485fddbf8e81dee4b1616e0e0ce2eae4134ac6a96c1853cd3975f770f05f077eb4781ca935e58f7dfb618d855010cfccb3a5f3243853ee413ab695753329948e772aab3c1799b8ade5f9f4b0d041815842f7745d71d6ead2c83bdd2e654f445b469e5fee1f091e708cc50e8441eb38e0a035d58aa4bb9310468b38a8342d9ba9a346d64b25b4fb6143bb72155ff3\n\n# tcId = 14\nmsg = 3230323034323936353139\nresult = valid\nsig = 67f05d7cfb5ebb3fa6f34a32e859395de916efc318bb58cee0d5dee9457e458cfbb97fbda6909ebf85394095732353b221a1bcf502b9b2cfabb4d67eac73a6720733d5d76224fc6835fcd8937c259d7ed7bb1ebcc7517c3b6b0fb67a4998838f529b8be2abcc8c2cf10b60a19b9fd4139756b766827bc3cae375709ebd821abcd97bb4d2e5f42f56888d67cc159b9d54910316042a4acdda5c507c66a055f55281f1eb4b0a1fced99560878109be3c04eb62633bf069d86f1a7496b5008e7009eeb225d1d4d0b377ccd4029717fc7e55a26575059e4b90fc735f8dcc45fce928ebd5c116afdb631f6c302a213a71aa75d427cc805ef5c9cfed95a1e3470dfc1897860e459f50f98958bc4ba630aa855dbf5799dd564c7dc8c67797dc1eaf51396e4984e345b847bde407541c68c13fd29af83eb6e15bfd092641c46da3dc7537d07d83c343cc8bc8c6064f8e4f61915c555bb86b37ba73dece8f9a0203da68ca9ce7c874c2c1fe516952acf953b61b70c5424b17123020fcc64bbfd7b5ed9c4740971fefc1743beab357e466a35a14bc5b928a625c607799206c76a0aec7df6d9988f2dd266d41cfcc654fa23343d39196b3a10f651d8f9cbbdb410a629fa10efd840b85da03839d96e5744a0ba785d5f90e0e797a053b8762dd7ecf805abc99d648e97d603fc4890119942d3b9b9ad4e9391fe453002ea2059dd01ad7edbb73\n\n# tcId = 15\nmsg = 31343531363639313830\nresult = valid\nsig = 5b382b1f8b912347b40629ee86f870ef85da6ba37f8fe661b6a6af3e4ce714e2be967f149e1bd52224315c87e184a62537ba262072879a4c8f13c8534aefd892c074bd214c7b915e87fdba67287bc0e3737a13f69ea9c18fb9329ae08fd35b692eb7721d2816568f5fbeed25da9df0ccc0ed69a9cf2e299245b4be49ef11c956f182587062c75cc87a3befb1882386ed503b658756300adce5268270959fb270add0a61421c066aa8ffaef45428885176a466792ccd4af9b4ac03381b4e368eebb4a75ba4507e61137dabe41aab8239cdd9759766db0ba6420c967f008dccfd4537528c51dd7b9e95135fce34664ca0556a30e9bbb531f39bae4f6e15ae266efb39dbd7d9894c3022e8e5cec3808d8f465115f85b411f0b6e276dc5c6f2b676d6ffe8427112b3af2cd99137d25b109839c7661d8376e3252e1f8bf9c5baa524c1bd82eabe0228b2c8f2b186898a151d25192fa6266bbaeece357117b46dbbcbf4818de758c5892ac548a47c8631d4754d4ff1d13cfa3a707edb5dd8fc405545a84f2a860f4f59d587658dd5ef20681fd590c91245740d575d127a1173ca8969c4f69ab10bc67cdc3ef5718fc317cc7915bda8e97a5d674ae63da735abf9e119869fd76e816b2d9eb868cbcdcecfb7d3a22db60e686033227483de816fb80dbc3d0abeda3d3169f298aa72fc20e305d2c6df1092c8b406e48143a3a6211020bc6\n\n# tcId = 16\nmsg = 31303933363835393531\nresult = valid\nsig = 3d85ed8630bf31cdadca8fa4ec06e69ca8e9edca84ef2b5a9d689fc77ac3819fe5f1ce370a060e294425ac97c4ee2abd4c45e8566d5467ad19c2eae4ec85f3e25d0888ca4f739ab93cfe16c034295e075083702baa6f283428deca6d24c8083935c80c08e68a1c622697ac1989a6bdb26bf88403ec06685eee11976108c3abfa602b64e6dc62d53241600b71c85c0c9d5f30a1379b312c2cdd6051febe6e343ca99fccfdb53f0852730d2bb5585d3c344d9091cbffdc529f780ee7aa8d807e54c0a49fdfce3b2cf659c6cc214e2f3a8329bcc4156408db4a49071bc36a4e018872c6d8f138da58e0877307fde9650a94b98882e5686fcea8524ea07d9d67ccc6f17d914da6ce80f0ca32757cd5cb4357f419a1726006a2b8e5a3a5a2d93e3af8a8af38d12e409ed8cc118ddbf7028a4baaca589a5b937997097189160f36b9e38bc29723d2f8f3844963de7f0742dc6c7f3a183d0729efc785d280cde8c1879eb75a53556f2c064eb114a24bd36e498216e43f60f16dc231130f5a393ee13048c1e7830e2c9453381c238b730db88b186447174bccd5f297bd2b3343309df6ad047e6734980aac77ee15122e887d4109735a932401a9be4b02423171f26cc3c0c59ae1870a5d3561df937e344dce45ff2c03bd8ed634e61cb0a6655d8e5945d77e119f955103c7b121105e993389f44ae306d901ad9a568a90eaf0b6eb503fc8\n\n# tcId = 17\nmsg = 36323139353630323031\nresult = valid\nsig = 3ebc127c8ce530268e26be059e0db2f580109f0179c7694d384ad01f257effa13dd90dd760e011546e8f8185fa754d7f8f89718675c818d8b22d94f4410ba577778ff90207602e19dd66f7296548600ed4fd03ca80e706624b715c52dda105df29661759c39c3844a469f52cb187a4f51640c2feedeb9411d96bc9f79700fa5ffbdcb87183d5652718a7dc63f0fa5885f2b2a95e0a79294289caf3b998a747590bfd2f0054e844f79c57807cad58bc664d6c4daa96a6262f4d110e3bc456948ac157f067f7a999d789e1462af0c59bff7e6fd128ad3b04d3bc0863e7343ecd43c01b16e549a4d684f1ae5c069f5f48eb63d64b8c4e53decf1caeb545a7e3f7b62de1ea5cde0c77bfd03ed690c15b9ea122255d34252b5a59a3464d5c4e4187caa9143506088b62778d614a01cfeb6ae07cbb91ac1ce5e63769afd6d3746ca90bf387d86780e1bf86c6653112a0dd193ec8bfe26a2824694f28dab211e28262a45c54ba8e1e94e21e61cc282a3b9131709e0fe5132e27f3d8bb20e69ea99c972bc780da5c58448844635090da5aecef1683a663a7d8c3f65ed98568dcb3c5199c5a10ab41ae60a5ae31968f5ffddbdc30a475b02f18d97b0d0ea03ece8c9f06be97b3b76418cb57427b988cbc2f8c13607c8fb97f30f209683c2b25b1582b7fa99619fd62f36481147f4b1296b1e19c4e867d2f240671475d730c7c6e19b5b5a9\n\n# tcId = 18\nmsg = 35363832343734333033\nresult = valid\nsig = 2484f823b830036277b6c888a551a134afc4456e0f11c90c7de87443f115615a2c3b5cadfab075aeb8d5b044420b8b2a98a58b1601d4a179bdd2c28299386bfa8bfa23db3c0a32214a8f99d2d2bbd202ebd5d6a7ef645fb823ea7e07f1f0f8123099386a011d78b8f7d74391cc4c1e82d5f5e448e44b62d091d0c923aeaeb3dc0ebfacfab71956d6d05ebfb6b384a5ca850b4efbed24bc02410b68f72218bb57ef7d3831c777cf48e5ae455bd0fbff0533399708c02a3813413e877bd0d1f0ffc21489800bfc70f6d3f8e77dd2f3bed5d298a1677e75bcd2886e84b5eb2884642a560826269e0445c80d695ff1ff72496dbb5853f72affad202a780978d5bc18f87bf2562021016f6d6a6b94dc7161ba220088f1e9a6000b2424716ca33d3e0e68e332778e19297934634803cfd5ec4aec3de2f6c8606b217717cfc296bea23fdd61827508643cb5fe505ea14c2e6a61544362d4d541fc41912ba7dce58ddd928ce8b8ce465cfffb97904a3e961711a24a019d25f2bba8d65413b3de82cbb04f2975b87a95502c76921b550f545e6a659afc83c1731dd8bda533b154129883d9aea6af532adf3625712aa44ded67ffe6d90bc95357d446a673cb32487195ad20ae184250abdc7d3a08d3051044fd9eb1049272b89a2e98f1a35b2e0505793a8fcb7448c03c8f46aeec03d1cbc3eca5a27880c8b43a2d255132703c40413b2446\n\n# tcId = 19\nmsg = 33373336353331373836\nresult = valid\nsig = 76d929733914162395018b1641129388337fe075f1ef22857bf1fca62902ded0a7f6ea25a0b33196b1a51145dcafd1545c09daf6d4d453660c79b61993df7b3c3207b828920ee1fd030a29233e35fda6d8f96990acf3cb5715b769b4f8d1bcbe3d686527fed6ad66343012e8c9ca8217c7c3dd8a8efdd052652f7c9a89090e598a6a60753b2c8d9ab67eedb3b3ccf8fd755d116eb1b089b108f85ce2b3be6ce8b11340e57dbd8c9b3acdceddfb53e6ec145f7622e184dbfb35ae46d75ff43a197703b183196d8778bd06d5d245e79f6c2e0afaf9771babb9a88ff06d0300be38a6f4dd00a627df186147c91be1d2ee4dd1096985e37cd2754002c776223ec0aadb08a3279b0839c67e9e2053344bd45d487f65ddc1a526900e909cf1ab63908375a5e0811a084e481c1f149e58078a3fe8abc9ca195587bad6bfbda20beea9c87b122b55cac6f6f65635e655cc0187d63aff5a026915232490b43f35ae2b96d7a73747d958aead23b60784eacc6a7e6bc471f850adecf8e2b53f5f93c4b8a40a27420466abbcf5e554a35d40a2f0ce4447c23580193df8aba421fdafbea91a92f74f2f9d8a565251dccbf07133225b40ae28c33ecf8cf6ebd2703a135cc6420628304d13e5b65bfbf7aacec056664694126dbcfb2ec2334f04bf4e4d9227444b07737a4d7d7ef4762b53973b900320e589a08d0e6563086534b6fc6d939e0dfa\n\n# tcId = 20\nmsg = 34373935393033373932\nresult = valid\nsig = 757959f7d8edcc8d2b843027b0e7be51ef30769b79e7393a550ce13ff36088c49e062c19646b68a82fbff82d8f54efdef5e4a412faa075936fe83bab9d5ba4c16be9b50a45a8196769c899a4fda1351e0bfbc0d3778ba2f3cad6853e9b59fe1d5c2b6ccd3ea320300e55337991ecea2623f2fd2088c1a152acc9930b57aded1bcbc7d615e43b3f03f2568248b11fd0a7c8706acda54ed825a8a26dc5b745f26dcf0f6c6f6185170c7bcc94e0917160346a54b6f16596bc5b53d19824b77440ffeff031", @@ -4023,9 +4661,9 @@ static const char *kData162[] = { "3343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 164\n# signature is 1\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 165\n# signature is n-1\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d2\n\n# tcId = 166\n# signature is n\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3\n\n# tcId = 167\n# prepending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 00004a80cafbe2a6095f8e8663f6289878514d7ee7daba0c1b0a077cefb333cacdf7c116ab89b0a01cab3161c68cac92a08aae7d117c9a3416d67365621da3380a85ff34a7a3b512846048acd1ec5957af942721c241a180a5dc5d8f6f6fe54d4d9fcb3709cde37081e2233b4fffa201d2029241932da170a5bad0d927a803a7f6289fc9f7b1d41cc1a6c94cbf588d5492b363920d0c98404f5da9eb9457648e2a4e9a034b2e2328c7f8c0e794771641a981df765887b5ba19b769156b375535911e1a2da68bb6a37eaa0ef8dded4ce3eac5caff4e8dc357703f0409d00baeedf3fbcbd6895dd3938e1f03dd9f131f9c979e22e4fcbea0c58721bc72d1f4976e93fc1a7649a23745c0310181031ac34b2200dfb4e8fe9bd4cdb52a23c31416745521aa4861eaea7dec4ea2c18ae9f75fa9d36c9b61bdc4185e434f8cb091cd731607b749a3990585cbbea2b1c0e0fff4f589a547d320bc7923b8a6b594c5866095df9c914cca80cd6c0e9aa3d691e2607f9de64322031ccfed04d9c805226cb476d3246d6caa1b04c63372a77668d5edf06365827b80391a6abd66010e8e1b873bd83db4dcc99444e109efa2414c6e5319f30a718eb43a1256b2142afa2382316e37aebde32da5bfec93e89d2adc39f62aca25a2289933a7cd8234d72a9b3c6a001d27560f8c8a2d9a233bac0b519b34f4f79288ea2cb08a87242953ac24ea144143\n\n# tcId = 168\n# appending 0's to signature\nmsg = 313233343030\nresult = invalid\nsig = 4a80cafbe2a6095f8e8663f6289878514d7ee7daba0c1b0a077cefb333cacdf7c116ab89b0a01cab3161c68cac92a08aae7d117c9a3416d67365621da3380a85ff34a7a3b512846048acd1ec5957af942721c241a180a5dc5d8f6f6fe54d4d9fcb3709cde37081e2233b4fffa201d2029241932da170a5bad0d927a803a7f6289fc9f7b1d41cc1a6c94cbf588d5492b363920d0c98404f5da9eb9457648e2a4e9a034b2e2328c7f8c0e794771641a981df765887b5ba19b769156b375535911e1a2da68bb6a37eaa0ef8dded4ce3eac5caff4e8dc357703f0409d00baeedf3fbcbd6895dd3938e1f03dd9f131f9c979e22e4fcbea0c58721bc72d1f4976e93fc1a7649a23745c0310181031ac34b2200dfb4e8fe9bd4cdb52a23c31416745521aa4861eaea7dec4ea2c18ae9f75fa9d36c9b61bdc4185e434f8cb091cd731607b749a3990585cbbea2b1c0e0fff4f589a547d320bc7923b8a6b594c5866095df9c914cca80cd6c0e9aa3d691e2607f9de64322031ccfed04d9c805226cb476d3246d6caa1b04c63372a77668d5edf06365827b80391a6abd66010e8e1b873bd83db4dcc99444e109efa2414c6e5319f30a718eb43a1256b2142afa2382316e37aebde32da5bfec93e89d2adc39f62aca25a2289933a7cd8234d72a9b3c6a001d27560f8c8a2d9a233bac0b519b34f4f79288ea2cb08a87242953ac24ea1441430000\n\n# tcId = 169\n# truncated signature\nmsg = 313233343030\nresult = invalid\nsig = 4a80cafbe2a6095f8e8663f6289878514d7ee7daba0c1b0a077cefb333cacdf7c116ab89b0a01cab3161c68cac92a08aae7d117c9a3416d67365621da3380a85ff34a7a3b512846048acd1ec5957af942721c241a180a5dc5d8f6f6fe54d4d9fcb3709cde37081e2233b4fffa201d2029241932da170a5bad0d927a803a7f6289fc9f7b1d41cc1a6c94cbf588d5492b363920d0c98404f5da9eb9457648e2a4e9a034b2e2328c7f8c0e794771641a981df765887b5ba19b769156b375535911e1a2da68bb6a37eaa0ef8dded4ce3eac5caff4e8dc357703f0409d00baeedf3fbcbd6895dd3938e1f03dd9f131f9c979e22e4fcbea0c58721bc72d1f4976e93fc1a7649a23745c0310181031ac34b2200dfb4e8fe9bd4cdb52a23c31416745521aa4861eaea7dec4ea2c18ae9f75fa9d36c9b61bdc4185e434f8cb091cd731607b749a3990585cbbea2b1c0e0fff4f589a547d320bc7923b8a6b594c5866095df9c914cca80cd6c0e9aa3d691e2607f9de64322031ccfed04d9c805226cb476d3246d6caa1b04c63372a77668d5edf06365827b80391a6abd66010e8e1b873bd83db4dcc99444e109efa2414c6e5319f30a718eb43a1256b2142afa2382316e37aebde32da5bfec93e89d2adc39f62aca25a2289933a7cd8234d72a9b3c6a001d27560f8c8a2d9a233bac0b519b34f4f79288ea2cb08a87242953ac24ea14\n\n# tcId = 170\n# empty signature\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 171\n# PKCS #1 v1.5 signature\nmsg = 313233343030\nresult = invalid\nsig = 12813153b37fa6c0fd755a1c7c409bb8169c5a39d045dff2da02b2f8e8897b0cdc6c2d40e6945b97006f18e1b26983f77b70bf2961b5e5f2759241daee8c56fca7c53c81f69d3a0341720d9761a4f7be8c068464e881c85a2c39e0ac6f74f6f5cb42df8c3713f66a282d7fba85b7a09a6af83a068b78bfe83ab25841e4bc67c9e40cf2a0974f8875fb81cc6a115b91f922419c44ea82b33187521a7e1f46c0ab9459b4e97a3f4a1d9e92403a37168826fa0e", "e914232afb6c4d7dd082d0c58885e356d0efb8aa9ae33d045f24b4b3182d5c54556f5838c449d31a49a3ac4ba568c248ed72c111b5ffabd991ebf5c48efbca33cb38996d584992c4abdcc7b93700ca03619412a355b41b000a32f6cc4935f942209b56a23cfb7b788dceb692343995f77daffa25e44d672f8bc451f776560b415d0d1bfe9925af1c2567a8e9bd15b8554d93377c62b0addabd27e8d9e0859f498ba8e03094e1d86d41e69f7606d9f1fac04744c3b7b8fc4942a846e2a3649bd9416d500b9895455fb6741ed8ed4f426f20ab40d8ab2e6cf6c63f5c290fc011768b317bde49753efbdfd12583f1ca79287225f9c3d3ed0c4530815e4f5e7ed78d14aec0d04142d0ac0fa3bb5d73b4bfda2fe7103a2ab40672abf08ef4d9e537b9f856d32450e2e41d9277be62ad0675d1a530709f2747f51f17aba10381fdc70c626bab45d51166b6f6ad978d2dee\n\n", }; -static const size_t kLen163 = 350237; +static const size_t kLen217 = 350237; -static const char *kData163[] = { +static const char *kData217[] = { "# Imported from Wycheproof's rsa_pss_misc_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PSS\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 0]\n[sha = SHA-1]\n\n# tcId = 1\nmsg = 313233343030\nresult = acceptable\nsig = 88f4676b502e365dfd82805ac1db27d1107d1516431ab4f71107b62625b6275af4a5dbfd8314fae255820c0cb577ee2457f510851d2678e4ed3e6839848aca8b67c9ce52c5bf57a01b6683828d03470034b136e6ab1914adbb1d918fdc31f7cef6f44b0b0ba0dbd6c1d3c8d7699ce374dc86c28beb3bee8f81f41162344e688af0d91297da0dd5e8104a5440add89bdc6c05d20a164c0f079b78654f038d443743f94bc45762501034a32b5d05bb86e75dd9a171c81dbe43edf50b2e1fc24297375331d78a8f0399d4aebbeeed911f6d964049e67d89eec0e95443af2ceb37125ea8431cbad2d8416fc15fb9cbed9142fb8cb06dc7ceafac056cc1f6696e3d93\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 20]\n[sha = SHA-1]\n\n# tcId = 2\nmsg = 313233343030\nresult = acceptable\nsig = a85f06875b529ca61b60df404652e79a499f81a0591bafa3377b80d8e300cbae679a941832eb5569fb88c9f8629e3c2ebf5f32ffe43767d1eaf59016f5904de3f7d39cb470dfc5fb5678fcd7b55d1a30f716b7f04c2568f3c1a2bc780e974a363adc622e679902e966af183d874b35396423d1a263bb1c6e7330179671644c6953cd795a19e2fe4208e7da5244e4760dde142313a781a55b0baf866dc158812a723d74911c8717a512d722669193f8883b1cffac98de8473b7a77198e20560c0c21207e00fc7dd14385fabdd530d568d143ddbee8d1b502f7b194b9827eee9472f2be8b2a541124405582bff393412f6aba9c42e5824d7c24bdd4d82d925d066\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 28]\n[sha = SHA-1]\n\n# tcId = 3\nmsg = 313233343030\nresult = acceptable\nsig = 8189776015db3a51805f6bf71aa1214ee07f7e385510ea95a0d4c3d53bc0d59f07ca39af40fe8c3138cf6f4ba0f72a3397df6ffda9cf49e467a34d92ec772f6b6d51d52cef86d16f74bea798a85aac873cd4d5d3a0fbbb618998f4b2b691bc14fe1f235601c51a76c4eacd1a33975d9c3cdf1daf579fb943556f0febd948d1b1e15cc85edf486b00499fa9032b6b801b5ae4454c94d7f89dc1fa6dd6a927969b14a4bdf51caf7cc8a87ae05d41e1933849acc5fcb0f478f1e23a0f476372837ade82f8ed1809e2245062009b8e683f563029ddb9892a398dbc2df594c12fb4a0f0c551abdf2fee4cb325fe9800ea741f7b2f2b4db370939bc7e3ea95ab539b10\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b95489", "1cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 32]\n[sha = SHA-1]\n\n# tcId = 4\nmsg = 313233343030\nresult = acceptable\nsig = 49e060ccb577eb614274db1ad34249490d1cab2b8d3ae2b708b93c8a8ead302e6efb8d26644d5caa5f62b89f3949942d07470c37d8878eb5cc9c154701feea36ac66d0a9723fb316f7ad6226f634346c17ef47b3e19c7b9979d60118959a5b35cc188200c8f9b2723046f480d95a9a0af07e648225dc35114d8199a431ccf4f44fe8e8c9c0130aa819aeecb09f95eea8f6d89981c05cc82716fe7ea499c55460c95e99871aba1ad3ac3bdbc96850863b23e3e6659ca346ee0e186ad717a8ec9c7a548d8fed0e7b79f896722659ec7e1335de12f361d5e6c65c791441c3c0020de48e60f200c3ab79fe0179513b2c1592e2f0064ba4799f6a0eea199da77d174a\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 48]\n[sha = SHA-1]\n\n# tcId = 5\nmsg = 313233343030\nresult = acceptable\nsig = 2d4216f277e50736d41cda2191faa97fa99d9e325b34926a363f8dd73c901153f087ac206cf3cb25001dffbb6200b7b35565b466f46f23aafb872e5c39d26156d36d1bab19382e5f15873022e64b58c129d38eee8126130f6210fa5ffb697bb3dcddbd99a9b60b53b25d094f9ec9b7a1cdcd0cc74a3ac478c7a34cc22c7e30e952bfac85638678b8aa2341fb1f108114d43dc849d91a3b174b0dd62f6dfb96459d4c76ab5fb6479d68d690d4a5c120c42a4bf82a8a7e9e7aba127fd5fda3f4c6ffbf2e4eeb72ee695cfeb286ec99e7cee8cf300e4e149cf17e70cf9f2bdb6421087916e945bca42a70a88b1a87e7ca3ac0a1bf2ab1a65ebab7726994a6c9597e\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-1]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 64]\n[sha = SHA-1]\n\n# tcId = 6\nmsg = 313233343030\nresult = acceptable\nsig = b66294f7b1e1a673e566c59f9abf264860200763860cbd666e476dbbd61fc39136353ab74299cbfb64bff88ed51cf9a20694e832fd97235d31ec6aef386ad44487d3753cc1224dbd59a34babc3eb8b538c10705775a27fa88ae35c0f618e0b3c6b91d999fdec5b86f15d1e462feea3af6fa12a5234d526e82039e1df013ef1cc6056221b81d755a13b70c618cefc6dedcc3361b5a910fcd4a812ae48382fddd75d5b51ca3d243dac021aeeaf6e2bd4aed75d7ff6d81c9aaee2356e3d12192b5e75d006b124275b0daec06b5af29b0d3e85f057db59db4b887fdd2bd0a33865eb87e8f3e37b4d8621e2e41c760a973f1ba03722d42bf5b921380b71fea949cf0b\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 0]\n[sha = SHA-1]\n\n# tcId = 7\nmsg = 313233343030\nresult = acceptable\nsig = 513db066bc72893653d1f7fa3f19546281b6239bc8390c4984999121a1dd75aa94004c3874beb6327205f2ecf8f6eb93eab018de3a6c71ea8b2d3a628188d4aa2b1cd6bab169f3e78229e4383ab68aea4635935e0eabbe9dc1d671416945f1867782900da53451369ccbd548c8f756e7221ee7e1ff28dba099b8f28d1f3aad2ef8bd816a53dfa9bc88e4e3983b0de955e647caf71a607ffea2", "0a9677e687cdda29219c7daa839276de3fe436b96b2c68db64c170ab9e300ced00e72a9c0fdc321a517aa113cdec8e2713f8b54ee2d78820f6f86b2f6e6222493d15cbe8ee9815ef2e7ca9a6ceb55955049db35b1af188b99f2c4bce38f130a75780f41b852917\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 20]\n[sha = SHA-1]\n\n# tcId = 8\nmsg = 313233343030\nresult = acceptable\nsig = b3e943f3982a29d0c1e241890ebdd9e734baf85bd32de80c6240e34dd1f7f0ca4f37fff2c373f9718e7e900df224d155c4463c66badc8fc3563f36309568436bcbef1d83c63e393d9e1432d50541d45e54b7af1b18cc819d9eaaa65a4b1e4f37ae16ec75e9f44a07262cf3e2dab85a066d92b750ba1cd2a1d42493868123f18017bd9faf1de1a4f87a3f9cf744da1eafc761b7e24c9929d3dfd15d1b08db1e3fc64932816095cea495e0dbb82842b5f3ca90dc7b78895c1f12ba991f3bef6f16451a84880fa31cdfda6b9624a77a3a0489fcfdf6e07b89c0689b5b7b7052372a2b1e06a3457b027285c3b160c0de1dba4910c0162ae8e737a3d7dd1e05c77ace\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 28]\n[sha = SHA-1]\n\n# tcId = 9\nmsg = 313233343030\nresult = acceptable\nsig = a9b9eef8197c973d6a73bdc165f40f0f53b05848c93957aec2785fa92a9cc6397418a71870f1bbc21a39b244526b4a39a538d149cde62bf8f21f3eabca932751da83120136c48073792c55e2eff4e29e6973cd3f1090c5bf3ced02a1ba4c145addc674d33b0a285d73d14bcd6f374f60c95c4184e2d57388e9c73f697ac0af5116ddbf5081a8f99ace11027835cb3df8ae785491f42850de04b3e01b9317bd04ed488ad72e787c728b4516c7d839d388a2fd7b21994ff3f5b7f264413bedd3d8a5258d2b39e60411de1ee69fe05f4e76b23a9f50b49f7043f9812aeb81cd54cc1dd9ffdc6e73580e2cae821579ba3642ff7793a3995b136e057d2d2ca7aefae4\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-224]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 32]\n[sha = SHA-1]\n\n# tcId = 10\nmsg = 313233343030\nresult = acceptable\nsig = 899a49ab1511bef8727d1ed7093bf7e6a77fa8750d047b203740324d18fc45b587d3392bb7abbe7e6bed7bf2be2fa5e355f8ac5452e675027dbec1835555d059a4ec44120f499e4951cc3fab33d3e8154a4340d29c69fb50728c60eaa58d61b75cfe7efadbff55fc0edffb4af9719cd1a3b2a240936eb6c2ad70b10b72aab7e64d9fb17ba8fadb6f4f0036bc22d5779705b02d261b8c9be700b65c066c27be02db353f4ebcab1ccb41c4bbcfef39abfa8999196951209558463aab1c6d4917ae97006199daaf963666d85c133817035f36ea321714a6b20dadb355a226257fc0abff10c9afac551bb7c3ba9e44737f45ad4f9b7f2db002afb7ad61cda0d96538\nflags = WeakHash\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afa", @@ -4070,9 +4708,9 @@ static const char *kData163[] = { "b0976593ab6c6635d8258a7dae326dbe65d203951209f8ece46a4132efcb640bcbd7990a6f0c138b456688d268150396eed52b5553f091f4888642b18580977d80680bb9c1194968bed4b0198cf72d1ed4631a6c16f6ea562c6cf344b3f8d1c2fddbcede647c91d01312b3609345d3e32df899fb981f070ed1c0740d79eb19f6d54725c006c0cfd961a2943391baa2a32e4da6dff7ed0a2a61fded39a85ee642c1e219d9ccf93faf80e2c2135b0de494f8cbcec5bb77f75148e83ba408\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 0]\n[sha = SHA-512]\n\n# tcId = 145\nmsg = 313233343030\nresult = valid\nsig = a289625f9fe684d186604fa08140f7d522dbec8ae6266ce83fba2b6bc6305e2e27bbfb346165b4e110e1b3e9445ffa8933e5417dbd87e3084835b8677ae439609616f7b755bbbad33ed0257a170a3964b85b3cdfbce43ea3c550354a92ec8e75642b039e2b4d9bc77b84c6bc7f2f2a43a0a403a1992e008786b5e9e43fbe71bee787ecd99501f1204921f61ec0ca83f1a8fb7862efe69b104d822ff5170802d510fd55cba7dcc2b695db905bce4c07a702cdecf24381f49a9b95d4805f1eb51704ea198653f43c3f124a4347ea1becd138cc3fd43e813ed823c373a35eb9060bcbb8fefb1c453c72f1f6198747577aef14ad3fe144b7d8de1bd6a123bd9f3f96\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 20]\n[sha = SHA-512]\n\n# tcId = 146\nmsg = 313233343030\nresult = valid\nsig = 740cc94a43653655eabe5a2c9f883a3784cbc5b13161e05ac0849cee39b2e8a42a0f53d14b47ff61d143584797ad0889b26de17b0c27c79a69a356e2e3eaee2b8675b0aaf68dfe682df23463b9b780f5b4d6681c00b27277e4e7839a333b022a16e7b75418fae9d5f5b3b996427d518eb1a696ac83ce6c5107efae577859b814100f19c52708481ed03d038a4cf6039f91bf72f4788dba51179e3c95c750a9432af1044f7cc758572ff11c537add14a6618d0fc1064f762485a0ffebfb0cfaceff4602367a231cee6ea2c8407bcc88267f42189c02e3438e62e3825d8667d1ae221494d4e29626caea3a7f5d2284f18862512cdd4cd9cfe1d8d57cedc9960299\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 28]\n[sha = SHA-512]\n\n# tcId = 147\nmsg = 313233343030\nresult = valid\nsig = 9a8092d3e759eac9374356b3bda80d87c6cd1f1188dc894f48bfcc2d15e99c65ffb6353510998a360f28bd636c61edda93ebb903029feae9b2c3935b2870f9a3f29e044f3ccba9a08357226d48f760158cbe5bfc0d7c0a2eaca0b1b167745bf26ea1e008e7377a085f4bd685fd5ada6602758e27541e6f270adf6d5b1a2b6c65a3757c5b3c4c29284e7cadbd39f4cfcb4253e959945651c60eab57ac0170da7ccb0c8d72e760e603c755a1b1e1356e968989cec1b9e1273ec2c572ed7dd0d0d29c0ad1e77692b0d79ec60657fc21b746168dcdf0d05a3ef1f37a4ebfb199cc167d94cc2c9b75dddf113048326797a6cfd6c9a764a6c71131e5f5654a93fc83a7\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba78", "65dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 32]\n[sha = SHA-512]\n\n# tcId = 148\nmsg = 313233343030\nresult = valid\nsig = 3522943f158039aa68354e3c51eb6d9a496f5c7e7c33bfe9a20cf98caa710b88b18ecb6d73177787479d5064ce3deddc13f98998a7207118de77029e8fd5f012a9e056b972a974cb5b087b6564821af89ce3b64348095accdea8ad7d05cf3d21d6208365a1d2fcce7cd964295c963e5fd495448c0926de0950d12c42e056595295c4376484fd7d0dc6feef3dcb41ec5a0dd21eef375e65523bcf5af70a92331beb0c6b5ac445d6a06cbebeed0083b746b3d667aa366c647313389a2d9b61d41eaed8cf2db8b4938115700967432dcc4f383278b4a397afac04bdb7c2f5f6051854174d85fb96525c2ab7bb58c0ffb481efc29d08e4ad1a86ccfcbdcd98974862\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 48]\n[sha = SHA-512]\n\n# tcId = 149\nmsg = 313233343030\nresult = valid\nsig = 45d8ed4982ba484e0bcfca14537d607fb6c3f8f444425bca05cf29bd5f92945f0ac211ccbc78d934f6fd24131ae88483547aef01b4e70acd6f84eef74d4a2de40b4d15d38a0807087a54ece36f268a60b70c500b72fe0ff49920c63c0cbde6e0d9100f4e50ea3b5e11a595f3755878bb1e03c295d3e73f1ec32d24d629f2fb469cea48346c057abd64f6bae4cbd0fb89076a1e42bd5260cc5691fee46762136f936aed35cdb6e1579d586fc4e166fe252778a379c134562175e17eecf758c11eca66ad259aa9e51e504d0d317b1715bd224706d65418a4601612e482bf95c1e9e9278e5401bdf1ed24118b908a8e42c562a76896563fe4c04d62b8abdb61e4cb\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[mgf = MGF1]\n[mgfSha = SHA-512]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sLen = 64]\n[sha = SHA-512]\n\n# tcId = 150\nmsg = 313233343030\nresult = valid\nsig = 63942e89a56b634787dbf074e75b0525e8bd3b7b8172f2c27499272b939a812ce2f501eb95a64603f9bc7c2120ef2f7133c3b2a4bf6445e2257b59e57022c879f8d60667ab8e28dc972846670858fc0d5bdbfa71dff870aac96492214533383d8740d84ddf61d46f852c6bf0bfb2d10c2e4d41ce7eeaee028333dfe77650b53e66cd2c2991b80c32faa33aae27b1c30c0ae2abd759c59eb22e0d0597b6dd63491e0c95048c074b1d64d8f356e637669d90974f4eb29ca184468bc1e2d24cfcd36e395c41cf3703cdb1a5c206fbdd4763154e5569d04d75998e6f425bd42f80e0dcd8deeebc3322aa6f50aa873345d7c9a0522154b6de2387664ae33764ffb2a9\n\n", }; -static const size_t kLen164 = 236014; +static const size_t kLen218 = 236014; -static const char *kData164[] = { +static const char *kData218[] = { "# Imported from Wycheproof's rsa_sig_gen_misc_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[d = 5ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801]\n[e = 010001]\n[keyAsn = 30818902818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d90203010001]\n[keyDer = 30819f300d06092a864886f70d010101050003818d0030818902818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d90203010001]\n[keysize = 1024]\n[n = 00d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d9]\n[privateKeyPkcs8 = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818100d0941e63a980fa92fb25ed4c7b3307f827023034ae7f1a7491f0699ca7607285e62ad8e994bac21b8b6e305e334f4874067d28e304230dca7f0e85f7ce595770b6e054c9f844ba86c0696eeba0769d8d4a347e8fe85c724ac1c44994af18a39e719f721f1bc50c46a39e6c075fcd1649f01f22608ce7dc6955502258336987d902030100010281805ff4a47e690ea338573e3d8b3fea5c32378ff4296855a51017cba86a9f3de9b1dc0fbe36c76b9bbd1c4a170a5f448c2a8489b3f3ac858be4aacb3daaa14dccc183622eedd3ae6f0427a2a298b51b97818a5430f13705f42d8b25476f939c935e389e30d9ade5d0180920135f5aef0c5fecd15f00b83b51dab8ba930d88826801024100e882d12d5f0be26a80359f13c08210bdcbf759dfee695313efa8886919659b064e3c656a267af6275ed1af89a5dfe9e25b31a02bafbd59445b7507a22989a681024100e5a65cfa668bd857d59135a78c18c8adb7c222368e9d74abad8e83299f7ac3c2ad7aa44ddb05deea6d9b20dbaf09a8615284a17c72d3723240334685ea7e2559024100a327c8e8f19d4150428f5e055a3ceaca846a19e30d45534ad60d894b56caf9b1bf0c9a8d965b0a882dfd2e1485154ee5cbe052e8d4f525c2d5fa9554b1992a0102410091f17ceb411a247e056287f79787f498b9cc2d1400e43dce10b91dcfe8e30adf80820d42d12b54f4247dce8eee193421cd602e843930f944c81a0dfa730081d9024075915a454770b49082423761244ccec65a6e48ae9966344b675610facad9162fa5bd1cc5108c322c2fb3c144f807773a2c7d097f63e5c8d3bd8ce8efac2ade04]\n[sha = SHA-1]\n\n# tcId = 1\nmsg = \nresult = acceptable\nsig = 03e64d148e05201b021fb5d3d72ab6abd4294be6c1673277ba5822ad2fe7ce4bb29ac547b2fdf09c2894ea0e31e76f1b3e1937db91c389467e9a8ac7be0a4f674456f01c5b4fa4277a26028b49b16e25689827d0a4b9f1c25a63350dc15131da908a05c7cfa8c08a67ac9efe3b0cd04aba7db12064cbc36729eaaec540c4bc12\nflags = SmallModulus,WeakHash\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nsig = 1d19763e80121e228ac4dbb3be8448560aac613ec74b168efe1d8a8335b77e6d8c3cc0f641de8c8e26a2aff9d32a4ab77340912fec0e60e89257b5b6b19c8deb866c2d2349fe63a06ac6b72397b478cdd4198ead64f8d36b9df29651e95ac7b886978cffbb5f7498f136b1ded7580cbcbb31620415eb71cdb5bd615b47eff813\nflags = SmallModulus,WeakHash\n\n# tcId = 3\nmsg = 54657374\nresult = acceptable\nsig = 0891ef2061c4d3377744cd7243ccc444619df533f4eadee216f7ffb9244e86d3e0162fc82c0b9502dc7aeebaf7884067e5f18f21b395c43bbfce5559ae84157ffde2aa457b7f44675e706af443acd9e38070428dfc6471a24cdc0d44f9283ac158704ad114375f10c24e3adbd12c55dabb78b8c41d3938124acc74126c82bb0b\nflags = SmallModulus,WeakHash\n\n# tcId = 4\nmsg = 313233343030\nresult = acceptable\nsig = 8277e8984d536f81667feeee7e24068ca5bb8b815210b3e9fa82294e11cae92c45164c9dd5683be4650e4b7709eb8879f793ae804620750b26032894e53333158f6afa6b52318e6c730a4a55d5a0fca6d029744f2ecaa2e00d3d6dffa0716acefd5c91afeda74b7f1a1bd7e635283bfa2142ace513da24eb8f25f3578a401ba7\nflags = SmallModulus,WeakHash\n\n# tcId = 5\nmsg = 4d657373616765\nresult = acceptable\nsig = b41191a7a1d11e973600e9a28c8d6e6d1513f7d970cb05ad50c686bd6fc42b7848559b2b3073a8cc9839f464d82f8a7d864cbc9698cc1a4b5b8c8103d07e9d79e5d24e1b3ab69053461bd76ac3b62935c31ef9f0c44120bf5c0a012eeedbd2a39d347cf6676ee8c81a88eb87eef2708edd793ebb79d6fced626e6475681fe73d\nflags = SmallModulus,WeakHash\n\n# tcId = 6\nmsg = 61\nresult = acceptable\nsig = 29f69d320ea3221cd0704300f456295becf54e877c2b9b2704dc47ef992588c7dcc1648d17172d8c76362c488aadb3437be488fe667a192c5db1440f70d102361d7e85ffab370c7bdaceba0d15b1f32ba0801ccddc9fbaed1323834a60d19ff13ecd46a27f06e79cb0d3aefdefc0c69d8e85fbe8761d83f35e362355ba675933\nflags = SmallModulus,WeakHash\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nsig = 9aa3040e7df724bf506881f6a92a133ff76f6a168f0f3ced70b3363835ed6b655fae6f39416555af4071c16262da7556412d9905279d666f9e15fb8a813b313d00007cef3ed2be306b9e29e6b69c2c5bebe36aa057feba44ccb6c8619076a5b23f39729ef78bd6478249f34ee99f3abeef37c504410910d1ad3f1a712c8d697e\nflags = SmallModulus,WeakHash\n\n# tcId = 8\nmsg = 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f1011121314151617\nresult = acceptable\nsig = 1fd0610221104c3f1e7f49d4c77c48bc169e630d5471e41100ba58dbf0ee0d4731a3d5b3c8cf9b07ad116e6cf65787650fb90bc85a9c4fe9940f4754316772c4946022178a3becbaa3d9b6252ed1353f7de834e0ac6d95d5a1f81453e89650f5690dc078df80dfe8ab614ca4881e7b001f9a11a4464b1004bb537f2b99624deb\nflags = SmallModulus,WeakHash\n\n[d = 50f854da7dec301ab50d81761a575b0436ee7a6445ef359b7bf3ef374ab323883dfcd6e6c2c43fcc1d71d0d6408faf1f5992c69846911fd2a438068fba46fea5c108f95e307fdf3904c1cba6f014c6555a79679b843e5397e2dffc5e349d7b8666bc3c5e411f39f0f2585bc7bda70b84b8f5b08c9260b39d3e8603c88d128fc1]\n[e = 010001]\n[keyAsn = 30818902818100dfbe6f882c8b0c42c3229f29cd858bead25c213b5c0346c3052f844b045ac792c81c1df5ad6a66e9d4f3f7c11096f069f5fc0d1d7da555c6e685cf672ab2a6599f01605f50c93a91d6882f5884e4cf3e9c41a790b0c44247150777f95acf69312b0ed68f3c82693e6b67f0e1ea5927c0eeab3554c2c157181f4634e77bcb088b0203010001]\n[keyDer = 30819f300d06092a864886f70d010101050003818d0030818902818100dfbe6f882c8b0c42c3229f29cd858bead25c213b5c0346c3052f844b045ac792c81c1df5ad6a66e9d4f3f7c11096f069f5fc0d1d7da555c6e685cf672ab2a6599f01605f50c93a91d6882f5884e4cf3e9c41a790b0c44247150777f95acf69312b0ed68f3c82693e6b67f0e1ea5927c0eeab3554c2c157181f4634e77bcb088b0203010001]\n[keysize = 1024]\n[n = 00dfbe6f882c8b0c42c3229f29cd858bead25c213b5c0346c3052f844b045ac792c81c1df5ad6a66e9d4f3f7c11096f069f5fc0d1d7da555c6e685cf672ab2a6599f01605f50c93a91d6882f5884e4cf3e9c41a790b0c44247150777f95acf69312b0ed68f3c82693e6b67f0e1ea5927c0eeab3554c2c157181f4634e77bcb088b]\n[privateKeyPkcs8 = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100dfbe6f882c8b0c42c3229f29cd858bead25c213b5c0346c3052f844b045ac792c81c1df5ad6a66e9d4f3f7c11096f069f5fc0d1d7da555c6e685cf672ab2a6599f01605f50c93a91d6882f5884e4cf3e9c41a790b0c44247150777f95acf69312b0ed68f3c82693e6b67f0e1ea5927c0eeab3554c2c157181f4634e77bcb088b020301000102818050f854da7dec301ab50d81761a575b0436ee7a6445ef359b7bf3ef374ab323883dfcd6e6c2c43fcc1d71d0d6408faf1f5992c69846911fd2a438068fba46fea5c108f95e307fdf3904c1cba6f014c6555a79679b843e5397e2dffc5e349d7b8666bc3c5e411f39f0f2585bc7bda70b84b8f5b08c9260b39d3e8603c88d128fc1024100f002a2625626ade6f48c6f981017968124de0e2a8fa38d6bc4853e1bd0b48ac327610f5e566f017bd74bd5134cc9fedc2625f0f7370f42249663e31dd58c4ce1024100eea660e905c086faf3d3ea3a94f2f9716a0fa760c170edc81b64a05cd5289ba8def634500068682dde0600531b41cc3565e9d6ec3b4ca3f3385e85a843e936eb0240667ac979318ddc6d23f81ee20fe4f2777c1570790dd1e8dd9e10c27f3ff306d8e324975a518f", "9e53918f2890d015e3c37e6a6ee42fd74d07b04b403b89e619210240609d72f663a1c203aedac824d75056b417a026bf01115af27c448cb788845c204dc397021c68286509519ca8088ce6c36772f7d3c35e0fb1d3cc5088029653e9024100b1bde8f7c203566e12f11e23319aaf9cd671e25579a22d6d153eeec123b5ffbe7fd6ae6a0630ef956640805b9231d9b5da97a0d1d83b55374c22885ebff7229f]\n[sha = SHA-224]\n\n# tcId = 9\nmsg = \nresult = acceptable\nsig = 507e6233a3c80971daa07c13f34a532d53441e196d642fd6564b347fdceb865c55dd47330587622a30f8d4ee66bf8f163c626f8dd26b313bb4095ea1ae9d6a96a24365f4c20056998eb9d1e3f2e1c78257361e5c21e5ba76320997e8cb30021e8f11a580000891bca3537d7a2c0972e06844f1a01a1dbc9a3f8b8a2955f7005f\nflags = SmallModulus\n\n# tcId = 10\nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nsig = 414de39059daab523a725efe437d688824a43689766b33136aa3e6da0a2fcf1c2aeff952605c2f1a12a29e36f282e59631f442af96c7659e0717bb24807835aa06f034906670b042f8db1cdcbf3c54e25472383b6b9097a09bfbd73b2e7c10e18731c6bad47af591bdb2d376680f6cb62048a97c19f23a70e98ddedf02786efc\nflags = SmallModulus\n\n# tcId = 11\nmsg = 54657374\nresult = acceptable\nsig = aa5d174e95f9a1ff88c1ce60b3aed1d39e256e28b0512cc4b52be1d41b8ccfa2a739945aefb5b697886f4f08cef365d18bdd8151acc588fd4ebf2aede9bdd904aa3481822206f3fedc5889c9f9889a8dd4d160d65e587ee228f9ef155108cb283c4e2a697a1e739827cb4a9790f96023e6ad24cabe51741a7c7cea8c52f08cdc\nflags = SmallModulus\n\n# tcId = 12\nmsg = 313233343030\nresult = acceptable\nsig = 54a81c62bed2f716feb2939f504db144c1c3b70485a1f35b2871ede567ffcdeb8d2ed0c57c56f21b70388d631be05b4c738e67f160f34ec42f236cef92b03d3dc8e50145b33e634a6fad8e87f84624e96feefeeaa91ddbb003c3969017dd2d102da2e7d5de8ed298139d5e503e0aaab136fb583b99ece2e6b1681699a04b977e\nflags = SmallModulus\n\n# tcId = 13\nmsg = 4d657373616765\nresult = acceptable\nsig = 11890613a8ae298c21bda95fbe4059c37426f41ceccb7bd79598c72ab4662e012f08b7009c15155b5ae9d132b4ede565963e6014241305279d60662f57df7119e5d4088d32bfc7e0847036f41ca71f9a92660f90ec13ee9e19717d0b567ec5a6b5978a11337d5ee4e9147352fb954817be04fb767ef35c07babb03fd04a31338\nflags = SmallModulus\n\n# tcId = 14\nmsg = 61\nresult = acceptable\nsig = 0fd461012145fe0ae9362eef22ee35dac0d4751a037ce4cf0792012bb179d101f9a9752e5ebc5454b18684fa1b557f3136ae68edc087dbfa4bbfaa59be42d0daa84b574a9f23238d4d538ae3e6c32f8dbd98b1138b545badcc10b184428fe2707aec73206367f147196f7b83f358377562e8c7d9f1d396a1cd9aa74f8a78cb1d\nflags = SmallModulus\n\n# tcId = 15\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nsig = 307e421e06bdec1fc1750d53529f5f007eddcc991af8351477e1d67169409e3acc93367fadc412a4554854004c4a29c8af4af09793e55967ed439645034cc9e9ae565edfc861e04c763d058ff3aa29bef3942277b4c971d830be1259aa30c125a6ede65971b0120758c2a6eb21f238ff18228f344155ff9109a0f9656cae2351\nflags = SmallModulus\n\n# tcId = 16\nmsg = 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f1011121314151617\nresult = acceptable\nsig = 019682b9c934a37ec166efae16b5ec75671fbc6322cdc91bf56a6f557001b8914050852ed7f13e96cb47fc5932a311ee677ffc05c1cf6589201b1a806f2ead9ff3c7cf327c391044fee073527a791a451a0571e50bb1e4b4f7e40847dba751f2d73f2ab2f5ab11724be81c9fcfded5a2535b593287e120870138e5534292104a\nflags = SmallModulus\n\n[d = 008505d47c271560aaf6cf65da6d5594a69c86f01622ea194071606fde369b65f5a751bce06052409c3a04c6a8b2be935bc0d084829dea8ea0998398fd2a0b0719ac1a1ae2d133fcc72d9df27b377b9a0109ef1a564e92b66963356b8da48f88fcdbc20658f74b542582925ec5cd03fb5e9a527c670465f792a69c1f6c7c5e1841]\n[e = 010001]\n[keyAsn = 30818902818100ac9048a7a4f560af91b4fcaf62a14595cb9ca9ec12000fc845e48572113cab2890adb011a919575a40760d1f23fe92509c8a5810b6d05990b909dd0f4c6014f2b31b6abd805bace99816e2eda41fd7b95405db7c5c8f4cf6babb14f550d5d0dd5179b54951fff6aa9686f30f478db649b7c7044cc202dccad00343468eaacfbf0203010001]\n[keyDer = 30819f300d06092a864886f70d010101050003818d0030818902818100ac9048a7a4f560af91b4fcaf62a14595cb9ca9ec12000fc845e48572113cab2890adb011a919575a40760d1f23fe92509c8a5810b6d05990b909dd0f4c6014f2b31b6abd805bace99816e2eda41fd7b95405db7c5c8f4cf6babb14f550d5d0dd5179b54951fff6aa9686f30f478db649b7c7044cc202dccad00343468eaacfbf0203010001]\n[keysize = 1024]\n[n = 00ac9048a7a4f560af91b4fcaf62a14595cb9ca9ec12000fc845e48572113cab2890adb011a919575a40760d1f23fe92509c8a5810b6d05990b909dd0f4c6014f2b31b6abd805bace99816e2eda41fd7b95405db7c5c8f4cf6babb14f550d5d0dd5179b54951fff6aa9686f30f478db649b7c7044cc202dccad00343468eaacfbf]\n[privateKeyPkcs8 = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100ac9048a7a4f560af91b4fcaf62a14595cb9ca9ec12000fc845e48572113cab2890adb011a919575a40760d1f23fe92509c8a5810b6d05990b909dd0f4c6014f2b31b6abd805bace99816e2eda41fd7b95405db7c5c8f4cf6babb14f550d5d0dd5179b54951fff6aa9686f30f478db649b7c7044cc202dccad00343468eaacfbf0203010001028181008505d47c271560aaf6cf65da6d5594a69c86f01622ea194071606fde369b65f5a751bce06052409c3a04c6a8b2be935bc0d084829dea8ea0998398fd2a0b0719ac1a1ae2d133fcc72d9df27b377b9a0109ef1a564e92b66963356b8da48f88fcdbc20658f74b542582925ec5cd03fb5e9a527c670465f792a69c1f6c7c5e1841024100d397dcfab4919db23bb6b88c4511516f6135e1118277e496130f0cab3a75661010cc98ec8f40cdb0c1ab612c03bbe3b023d891f46185788fb114437c8a9ae71d024100d0c7805159509ddad70f35b9a76c7c2bd95a844d36b76d96138cfc7a2a55f88072e8b10ac37463caf9bf8d1014c93a001214d7ce230c8332fb58dadb05d52f8b0240762d3c4b7dac5292284dbe3701a051864e99e4117e77ede06fd698f1cd5da25a58b79cb58ab0dbf0dbca17249915486ea9269d260b8d9b2f4dec8e60b19d2075024062a4f06eff4944dc6262905ae0cd343a2f9f42058d85cb646e665de086e249e0beea4cc42e276f03374f9721f30044c445c6cd545b610d186883ca1c543c2f1302403cfcf044035c1854475e1dba480ac50d2a059f32d18e819c96a3199b1e3855a653ec0e5577e4d7677d6e0b7a55fc418b13202ee19430228c4bf9d28af8851c9b]\n[sha = SHA-256]\n\n# tcId = 17\nmsg = \nresult = acceptable\nsig = a0abd165a5ef8733ba111fa0fa092630222d809d8ae811f24f8bead4968b7533af31019663713ba134e7dd345c38e7166a037025eb34adcd6891c9ec941d2e3eb1e4bded1d269272b602cb9b53568b992ddb5103914e6424c75505701a37996c8318b0b6f8640cb6b6e770ac44314b866a7c683a6903f7bba07b6f197ec554fc\nflags = SmallModulus\n\n# tcId = 18\nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nsig = 41339884a9b3940e8488d666bb158063c6a2a2717cae7f564834a876fcbf7098ecf3acbfabf37d38a8e6127b1e313744f1f896e165efdaea0b2e7673867842b9e94db0868ed9a92bcdcb370a4e20ff275c82595e4400a8b9e9f12482f014846b48216f321266ae6ae6338dbcdc41b711e483e6e3e728772e7f9f5ef95c30196b\nflags = SmallModulus\n\n# tcId = 19\nmsg = 54657374\nresult = acceptable\nsig = 8883676becdc27878ccdff53dda011e5e2f886e31e1e88d520bb161cd63aa001fded9f0656109c1507bd1ba5d3bb3e725029a236b4c3c0420a1fcfffe348c5277d6aa51bf75d9af26fdc15fc49d637b078a8b0478b5b0a9c428756d260068e5e622f193b9f9a2c1d979e3322d7f3edc32053541c6efa2485e42e99a804f94388\nflags = SmallModulus\n\n# tcId = 20\nmsg = 313233343030\nresult = acceptable\nsig = 9f2e01b92bc9dd32dcf24aee91467797396649a3255bac943dd0e03c9ef416f349c0cbb728704730f3c7a7c244066a94b229a6e86bde7753c8940129626307b542cc7f596583932b4fe6ea9384d5353e08654e966a64b63bd6745503f7e4383dcef74ad4516ac25c8790db6702ac5b8b057a8fae75669b6a9e689e9211a337b9\nflags = SmallModulus\n\n# tcId = 21\nmsg = 4d657373616765\nresult = acceptable\nsig = 3cb9557d9fe49b889319e0d41efc00cba34277caeed2b2c54fc89772c669200dd63f02f340cb6ed579a379a3fd6a568ca9d4bce206655ae4586850638ee6bffaae2bed7c7afe7353d22418d7e4f6b15e198c85b649d3e5a67f00702dd9fefed7dc72136bb4440fac58e64453e4ee63a81de4270446571b192f414116e165efc0\nflags = SmallModulus\n\n# tcId = 22\nmsg = 61\nresult = acceptable\nsig = 06e6fb568e366fa20d48704be40e991a291d47a464296a49c37718c1153b0fea17ac18a01ff97b32a92d07635dfb9143d011d003c9153020f5ef7fd3ef258cfe92a7a2120718fcc85c73acd34cbd50670c2e044dc3b82fca29b1017912b65d8a844515655308367d8797ae5b7fb91042df573f32de69c1842a128ac88937c0e9\nflags = SmallModulus\n\n# tcId = 23\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0", "f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nsig = 327238fd701dc4a829827550aad98f9bcd75e9f3831c3679998c869c1dd8381bc6b74b721e9d3377034e059d6637690ba3a184ffd98af951d43a22105a51838f72cf592d658af01adeedf721cf2eb2bb2c90c68311cb267f0cfacca903c1a2a73f7228badb5d86976f5d3371fe9b00cca048a7a0b0fc4b03da11c5a098045e07\nflags = SmallModulus\n\n# tcId = 24\nmsg = 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f1011121314151617\nresult = acceptable\nsig = 65fd6547b4c27c06da21cfd067accbdede11ab8ddf16899d3acfd61134bbc4ed3269198733093062476906f36598a565ab32cb4b4f90e8c2acdab870bfd7f97726771050c4c67768d98514e51c28739067ca1a7890a846f6fb142d720df3c98ceb833a8cd8cc6129d22d0c5de9120c127e69e8d7b1548a474acf505897fd9f8d\nflags = SmallModulus\n\n[d = 5683206e498cd4867f94b062adaf2d3d7498150709d45ae03790731a58303b74a30d9b37b728f1c56fc34c2abf9c21e18adcf3952416d539934809cb1b516a62d80e1082b3e4d2ce749f58c7a1c0e5907fb7c6b9c9f971c80b890bfe101c5e8a83156bd4a55283a72d0634550a9bd674b771b9e1e00619eb43d6e35112e15031]\n[e = 010001]\n[keyAsn = 30818902818100a1d3912e65d994e0ba51135f78844d9a3ea5161e5450d16a8cf0173a0a309a1ee94e94385dffc5e27dea6692a1713516af86df2283c8e327e60ee26a7b7cfccb0af3f4b5efec358651996b97d5b25da933b063490cf7b67073d399b04ad55c0a89f8ec36d7f5cae757dbd3d6d0f5b77f7c94e28878397cb45cfd178f3f07ed010203010001]\n[keyDer = 30819f300d06092a864886f70d010101050003818d0030818902818100a1d3912e65d994e0ba51135f78844d9a3ea5161e5450d16a8cf0173a0a309a1ee94e94385dffc5e27dea6692a1713516af86df2283c8e327e60ee26a7b7cfccb0af3f4b5efec358651996b97d5b25da933b063490cf7b67073d399b04ad55c0a89f8ec36d7f5cae757dbd3d6d0f5b77f7c94e28878397cb45cfd178f3f07ed010203010001]\n[keysize = 1024]\n[n = 00a1d3912e65d994e0ba51135f78844d9a3ea5161e5450d16a8cf0173a0a309a1ee94e94385dffc5e27dea6692a1713516af86df2283c8e327e60ee26a7b7cfccb0af3f4b5efec358651996b97d5b25da933b063490cf7b67073d399b04ad55c0a89f8ec36d7f5cae757dbd3d6d0f5b77f7c94e28878397cb45cfd178f3f07ed01]\n[privateKeyPkcs8 = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a1d3912e65d994e0ba51135f78844d9a3ea5161e5450d16a8cf0173a0a309a1ee94e94385dffc5e27dea6692a1713516af86df2283c8e327e60ee26a7b7cfccb0af3f4b5efec358651996b97d5b25da933b063490cf7b67073d399b04ad55c0a89f8ec36d7f5cae757dbd3d6d0f5b77f7c94e28878397cb45cfd178f3f07ed0102030100010281805683206e498cd4867f94b062adaf2d3d7498150709d45ae03790731a58303b74a30d9b37b728f1c56fc34c2abf9c21e18adcf3952416d539934809cb1b516a62d80e1082b3e4d2ce749f58c7a1c0e5907fb7c6b9c9f971c80b890bfe101c5e8a83156bd4a55283a72d0634550a9bd674b771b9e1e00619eb43d6e35112e15031024100d55f5ac3627e7d4bb07c530cb26b3e0ec6cfc7753986e009c9f53d84b6940923d293f8c55b5e9820b56dc6eb008ee779a156a7c8a0b4fa5b6117a4f64233a38b024100c227f5cd75d8865f75ab467ef5f8d43ee0707250450d523230fa3786a6632dbb893ec9cf1039058521b4280529644315f9d37409915f6f5e86365ab82827d323024028403bb3fe01948b51b8b24603e65d2796739dd1cc4f5836208605dbe2415cd4082667d87b1b0621ad780efd47f6ad4df194924433a4d051aaa836334a5bc96f02402fec0d0f9976c833e7a74ecf2787335c11a9af8d807db93c0a3ab859d3d7c701f2ee3c818f4f83bd48845f1c670b0843f455ecde2fb38e999626f45d600bf46102402efab8b9b528803fe02e6dbad575d57824b794dbd9ae0b4d6b43acc1b22a42ce2ffc12ff9339af3da08387cbe73e1bd326725487eb97c71ba6f960e5dddf4207]\n[sha = SHA-384]\n\n# tcId = 25\nmsg = \nresult = acceptable\nsig = 8bda47e85848bb1d98eab90bd5f1880540204c8753a17b2552ee4778405e4c42cc3d25a4d869eb38f1e6fd122a2f52fa8685c3ef40400ade2017555ae88fa892a1ad2793f7c23762f0e54db0852cfdb2e52ebd02c8acf81b9a1e78accb5fbb57a29391cf4fa9aa298111c7b94fe240f0f576b1b52853853fce13da155f16e81d\nflags = SmallModulus\n\n# tcId = 26\nmsg = 0000000000000000000000000000000000000000\nresult = acceptable\nsig = 74b9a7b9548a281c5a258520c879e0e64d8a28812a7b6461c6e418e0502b61008a8e535a5b55fb64529a6a6df2f60ef33c1844b27f81532be2bc2992d0eb5e524112da90bf40adefcf206469639ff3895a9826674ee1acbdd623842ab0a9a36d48da13ba17c4ee069254da2ea418d5a8f135e2a414c0654a266d538621917545\nflags = SmallModulus\n\n# tcId = 27\nmsg = 54657374\nresult = acceptable\nsig = 10d9c8b0bf55586e985799be60a17979eb0461daca00ea6defcc62fe720ea502e7e486c02a48f5ca41ecd96c67b5c762a067c465c35a8e416748897ede3ee2cd3c3e1b1199da5c7f0dd0f036774a1730e63ba781d6ee43d78b067608e831a16dbec6075c8ec90e81a4d8e2ac2587b0ae43f7445478b03ab7eba2e63d4043c2e1\nflags = SmallModulus\n\n# tcId = 28\nmsg = 313233343030\nresult = acceptable\nsig = 2cb15eb09030fade89eabc41794d288275c456f12cb0d414311e5edb551a51c3e1354f134b27aecae50536379a871a4ce6ab2e1b999c0308f5fed2ec48d97d68885b37a1e3e26b841db103b64f720f9aef265632f4f4a207ddffe19092e8b16144b0a3443d779c0b648077d3b04b72dd4f4051ac232261ac9df65974764b97a9\nflags = SmallModulus\n\n# tcId = 29\nmsg = 4d657373616765\nresult = acceptable\nsig = 9c80154e3087b443fe6d9bc24faa7ea009330a210f2f1063ea1b61261507a5e3853079a0287d5b27983bd751ac782b1a5c31130978d3f2a8a95101c4ed87eacee964953ad32cd2cd4caeb7c37330d1650d7ca19dfa6e8f1c184d3dd9a3a759d6badc700b7063d2c579b336c5e141c200614ba613d9bb6493e87d26978b438573\nflags = SmallModulus\n\n# tcId = 30\nmsg = 61\nresult = acceptable\nsig = 99fc12c90f67dff9600c30c9f81bbf335492151345c809c05771d59ef73d438f88c5c43ba507a3cad6633641d70ec3f3c38f67cf7f2566489f59422a2dad1f647e790bbd28acc290ab392d48ce7a140184bb71023f8c9c5dcd9469ebe848063d96bad26fbd390974b38459d51727eb8c0a5b8a8ef1d3394b6f852dd2b22cd22c\nflags = SmallModulus\n\n# tcId = 31\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = acceptable\nsig = 869b42bb93624a139bb98c043cba8fe12d612aef040e3085994824a480274c0cca24d08d178321acb048055b777d897e267cd50809bc7e9f86c276beeb8a8d59d82aa2091c66c71e41ca59738b0e18f055f9c75a01e87aaad446e64ac0183c002ea2080415ebb4f85a590622bfa4e701a6e37d0b33bd78d5ff874d8d28fda263\nflags = SmallModulus\n\n# tcId = 32\nmsg = 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f1011121314151617\nresult = acceptable\nsig = 1d1d3424bfc646c0e3668ab4e9eddbf993c5efe63ee6ccc966dd467c466225bf587b9d7508a7dab8079c50cb3086b9f0fa3c6e77236744618fd651d39bed94bdf47a2a77897341f16da3db9557b2377f151375a74d9af8204e155abbb62dc7e2f6effee3ffe936b360e45ab750ce69e29f29e915baf8578017f66d85192ded04\nflags = SmallModulus\n\n[d = 00ad5144c6c266314d11dca0af34b8684a77cab12be2ffc8fd213e9289ff83eeadb70e4b6af5bdc7dd72659753ef1f84c2f8039fb13ced41f12af77bcb1cbb0333e26dcf0b27187216910d3de289487ddc843c8b66f1f662037e181dae36d6aaa3b509dd33892ed4851ddcaa4d02ec210262947517a38da2e9ed35e5801901bb6e82043bae88aa951f4a56cf454b4dcf2a9dc425525ee4b6e199320d1b080625fdc8af4e44592e87cab8753316fe933ccf044380880b1984f662c638ed8c3158f1]\n[e = 010001]\n[keyAsn = 3081c90281c100b8be129638e9c805359e6169b263265e2a8ec4b849101f2a321ce523665e399954ac3865ee8c85d14f3d3f24fbd583664bf09394cbc7f7ffc98aadc94eda35ca4b9614fd2d773c782086a1ea9ca23f357cb2cdc465fb85100172845d6b2906dc9315a542d204bcc4dce68d90484198e2350cd682eef9313a13df3607669aa4dd186f563ba0ae3ee054f857a92985f2694a54e1a87ed7327acbfda3e61ecbfecfdd1b7b2d08dd306122fd44268f08463306760f40dfb7634e71d7a72f1224e6110203010001]\n[keyDer = 3081df300d06092a864886f70d01010105000381cd003081c90281c100b8be129638e9c805359e6169b263265e2a8ec4b849101f2a321ce523665e399954ac3865ee8c85d14f3d3f24fbd583664bf09394cbc7f7ffc98aadc94eda35ca4b9614fd2d773c782086a1ea9ca23f357cb2cdc465fb85100172845d6b2906dc9315a542d204bcc4dce68d90484198e2350cd682eef9313a13df3607669aa4dd186f563ba0ae3ee054f857a92985f2694a54e1a87ed7", @@ -4103,9 +4741,9 @@ static const char *kData164[] = { "f875bf217a98fd573918edb2f8a19ba14637931e2041336f1221beb354d3032e5076d52037d18c03592ec334665a34152dab9f97836f72b808b444ca2fe5402a085782a1344ba6c96f1472896418e3383754ddedbf58d0308dd28dc18242c1cf34980107028201002cfe71b7d15c072e0ac71c7aef80e8e40823a92ffdcdba8977450a5e58b154b019c9d9e7a602015c41b7909389afe686a101e223da9e752638c244b31e298aa451e24857c97fc984998f276b6f4c69575f306376cd2870124488f518ede6ab3f43f0c68b133c5c278028d3d824163e22cc5a7f3fff478d502af055ecb5ab5039a94c9eea95db34ad163f1b0c4e5b66aa4fe75a4503df915c1431d6965e70c931fcd6e768b06e57653e7261f4b95ebe428ffd2bcf904f91fabe16c974b4f5ab10ebb66ee3e2a95b369946b2dc0a30f0e9653eaeb681fea81bc47adbe1f50d1e30c0bd85fd0a98fc4869dbd00f2d61571203411fa7f008c0e43cef14f6ed1ecc70]\n[sha = SHA-256]\n\n# tcId = 156\n# short signature\nmsg = 34333630\nresult = acceptable\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011a21abeac8409398319e65c8656f8f72e179dd1e99358c7531fddc037e47c1e688cd70eafd6eea01c823516bc79f89d7e52ee1eb4ffdeaad1d550dc0a47185bc9c42e47fce5503c3370a60510f834b4691152ef668deca633cf3873ce6613951784aa7dafde118f37f1cdf1a687ac236d5c956bced564b73cf202e3bace59667\nflags = SmallPublicKey\n\n[d = 5a227bd7284e2c0f51db10b911d24bd931add424b8cf6aad5f77f70bf94faebd2b6c8753ecb0bce16128569ead41ab428481b5748311fd02cc821a2379f3def60eadae0d46777eca8a98f50e653012867f0116768d9f04286b6921d77c812947fa838c22159a9743b030fefe695a25dc6e51a293700e545b52c01ccbd297d110a03719ee437ac4b220d7dbb058adef86b949ca4de07276101deb7b61b2e5e8fad8bc6bf2dacf8f90060aabf2696c7f1cafa101ec562ae5572fd592dd7cb1f5fec11473dd398f7effc7981ff96fea4269561f21fa87bb5c2ebbecb441a13098b6ff7b8aec3fb7f483f48f80bd8b531f4a99bb27cbdec584cd7c0114ec972380f333f1fe4849ba118e5c3895f9865b806733cb764b66e99703e35dd49bdc4372d8520f069237dfa06c72fe78ee267184cb3b14fbdeb1ebdadf31ba6bb57b469e6242bc0d1fa391e0e8edc94d01b5fdbb2010f7d8e4c5cdeab865b1a2f08643dd0ac0f7bc151b6ccb0c835202f07a9ee5b73db9c4ece4fe4cc2069379414ed6552b]\n[e = 03]\n[keyAsn = 3082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keyDer = 308201a0300d06092a864886f70d01010105000382018d003082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keysize = 3072]\n[n = 008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01]\n[privateKeyPkcs8 = 3082073d020100300d06092a864886f70d0101010500048207273082072302010002820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103028201805a227bd7284e2c0f51db10b911d24bd931add424b8cf6aad5f77f70bf94faebd2b6c8753ecb0bce16128569ead41ab428481b5748311fd02cc821a2379f3def60eadae0d46777eca8a98f50e653012867f0116768d9f04286b6921d77c812947fa838c22159a9743b030fefe695a25dc6e51a293700e545b52c01ccbd297d110a03719ee437ac4b220d7dbb058adef86b949ca4de07276101deb7b61b2e5e8fad8bc6bf2dacf8f90060aabf2696c7f1cafa101ec562ae5572fd592dd7cb1f5fec11473dd398f7effc7981ff96fea4269561f21fa87bb5c2ebbecb441a13098b6ff7b8aec3fb7f483f48f80bd8b531f4a99bb27cbdec584cd7c0114ec972380f333f1fe4849ba118e5c3895f9865b806733cb764b66e99703e35dd49bdc4372d8520f069237dfa06c72fe78ee267184cb3b14fbdeb1ebdadf31ba6bb57b469e6242bc0d1fa391e0e8edc94d01b5fdbb2010f7d8e4c5cdeab865b1a2f08643dd0ac0f7bc151b6ccb0c835202f07a9ee5b73db9c4ece4fe4cc2069379414ed6552b0282010044f592b4a5d5d2abfcbb235ed9c890ed4c393a58511d213477c92be7c44cc170a2476f6c9f836aea06b0d584c6b0d6eff344e20a58cd94b601b98ef3ec8ac8a7415430653450bde8b8e26ad2608814ee56bfe3ff1099d195c9c76edd82b1ffa50ed7b67f5cec464534ac99c8f043f57078a8752617abb04d4861031993efdcdda9df505b500c9dfda99f422ca3be309985b4a3ebe48cc37227e802298f9dfc937f3c419c156df8492b52cc24a1daeb355829836689fd0dd8c3057fc1d473942de38480e8ab6f16268cde71af49badce2cfd07524e8f90c301a6152129ad4d578f4cff93a042db9ffae0be5136c1ae5d8e49813d9dfc1703d14fc507846a8b45902818101f5ea5d7dd210be18585cc8f9118dcdd91e0587209ede4b419552064988741c3c76ff276ff952d104db1f6c0fec6c4a745e7340c2d000dde533258c29e5594566e240fe9a7981c5e7f6d6f42202590e759f34146e61de89f7370a15c0403ffd9469ca8e5b527b2d86cb52350e2e79dab865b9cb35fa88487d8190885a567d86e9028201002df90c786e8e8c72a87cc23f3bdb0b48dd7b7c3ae0be1622fa861d452d8880f5c184f4f315024746af208e588475e49ff783415c3b33b879567bb4a29db1db1a2b8d7598cd8b2945d096f1e195b00df439d542aa0b113663dbda49e901cbffc35f3a79aa3df2d98378731130a02d4e4afb1af8c40fc7cade3040acbbb7f53de91bea3592355dbea91bbf817317d42066592317f2985dd7a16ff001710a69530cff7d8112b8f3fadb723732c31691f223901bacef06a8b3e5d758ffd68da262c9425855f0724a0ec45de9a11f867c9341dfe04e189b50b2cabc40e161bc8de3a5f88aa626ad73d1551eb298b79d6743e5edbab7e6952ba028b8a835a58470783b028181014e9c3e53e1607ebae59330a60bb3de90beae5a15bf3edcd6638c043105a2bd7da4aa1a4aa63736033cbf9d5ff2f2dc4d944cd5d73555e943776e5d714390d8ef4180a9bc51012e9aa48f4d6c0190b44e6a22b84996945bfa24b163d5802aa90d9bdc5ee78c521e59dce178b41efbe7259926877951b03053abb5b03c39a9049b028201000a481e3baffb3d30fa9e49395e7fd986d58e804befc9bad0799b2e86389792a2e6e47449b23b9e15c9139dce384aae4f08bcffa353bea9ef2fe2639a35a1bc3f9ac38", "963f1b605d785bda5b7c5b17e66560d336cdec31b70709b43ce064d7e521df466c8015a1593453fb90f3d43713b5d5066f5c7a4abb817b874065a7a117be1df350320a5555fb39d78d178d17e37a288da8761853c40ee99590d87f21c133fe06d09f40f9c1765eddfa7e865b6a4b369470163aa681d85223f37a868e97e264f371dbcbd9cef8a17601f7b29b4e76f2ff77b538722695dd1fbf92e940b6e24c1f33b490b1aada82875596aacf074c36e1e8cac178e8690be9f54956bc1ac]\n[sha = SHA-512]\n\n# tcId = 157\n# short signature\nmsg = 36313237\nresult = acceptable\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bdd0c9e451b5b3e5513a94492dbee1ada9ea87e65a8cd95cceb4d304294ce34bf09a212f14908f5b865c7a34a72e68e389794a2d1c5767ba17829e2044108ac7842b6bfe0a5663b433d656f4e38522c5a5a23c460b898833828d257350e5814291b54cf13089080f84998edcacf0fe5fca0c1f8b176b172c5f9989491a039bef\nflags = SmallPublicKey\n\n[d = 61d4ba892aa781fc663a897a56f278364b09a89485a37255bdabc5e0f543fede724713cf3613d20c059983e7a38442c776c9accbe8ff714aa45d4d5cc35005adf8b8c76a91bd14fc975341a1689495fd85fae6f45ee5f010764c45a01d7fe521b0463c5838ced4fdf17f2df3056cc3f1d1f76753b563848ad5eac21b40e286e5e847932fdbe9a7a569c0542ca2e072763516ff44f67817739a3ee721dbc88f5d3d4ea704e53798eb8c0e7195070f313b800d65827a4057f62ceff11b160a8419054f99fe6b7cbdfa62a9f07ff7313b8cbc2b338bdf9517b1150de81212f9d6bde36a5b16eb82aabcd0157d2caaea6e0b02c784bbf9a00c7cd12e708723909f93]\n[e = 03]\n[keyAsn = 30820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d0030820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keysize = 2048]\n[n = 0092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d]\n[privateKeyPkcs8 = 308204e3020100300d06092a864886f70d0101010500048204cd308204c9020100028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d0201030282010061d4ba892aa781fc663a897a56f278364b09a89485a37255bdabc5e0f543fede724713cf3613d20c059983e7a38442c776c9accbe8ff714aa45d4d5cc35005adf8b8c76a91bd14fc975341a1689495fd85fae6f45ee5f010764c45a01d7fe521b0463c5838ced4fdf17f2df3056cc3f1d1f76753b563848ad5eac21b40e286e5e847932fdbe9a7a569c0542ca2e072763516ff44f67817739a3ee721dbc88f5d3d4ea704e53798eb8c0e7195070f313b800d65827a4057f62ceff11b160a8419054f99fe6b7cbdfa62a9f07ff7313b8cbc2b338bdf9517b1150de81212f9d6bde36a5b16eb82aabcd0157d2caaea6e0b02c784bbf9a00c7cd12e708723909f930281ab0c0f4f3c24bf8d0185bfe3f5be0fd9d94045abc59ed9082ebab4615c4fe5e74a26d2d3824276b90631aedbe4e2795873adaaf909fb454f7cc4eb6403c226a8d4fe96c429018c6500d227af70236f30ac3e299e502b0a9423ddccffb7e2987aa6889611896f3ca767a5d536f9815cd21fefa7f8f177ddb32b9a8c3599c3f37ef910e37e9048e61d0cf79dc14f14c242d0f0e350045ad6b54f278abca959b59c771e68c312aed3e33a71a73302560c2b1123368fcab3690929caa41f19b4e7e973c9696a6e1fd13e66b61ca9bb63cc30cbac1a8735206aa639fc8dbaca40f273e6b6320752fe2f0b4b5089d932ca0422ba3830eb74e462a7dad66f31491c321ad7f861df0281ab080a34d2c32a5e0103d542a3d40a913b802e7283bf3b5ac9d1cd963d8a9944dc19e1e256d6f9d0aecbc9e7edec50e5a273c750b1522e34fdd89ced57d6c4708dff0f2d70abb2ee008c1a74f56cf4cb1d7ec6698ac75c62c293ddffcfec65a719b0640bb0f4d31a451938cf5100e88c154a6ffb4ba53e7772670823bbd7f7a9fb6097a9b585eebe08a513d634b88181e0a0978aad91e478df6fb1d31b9123bda4bef0820c748d4226f66f770256081cb61779b531ccf0b0c6871814bbcdeff0f7db9b9c496a8b7eef24131bd242882087c811af78c047197bfdb3d1dc2b4c4d447976af8ca974b23235b13b7731581726d0209cf89841c53c8ef4cb8612cc11e550413f0281ab094cdf234ade11daf48b0df60628ad6846140b65d68783caf13171f4c2772e7a2f7576fc8ba0d5689074568ebfae719a4f2faee5159f17bbec294029f4b0d7ef85f5e7980a872ee5db8f6a39cf6871373abe90c894fc8cd96399a3a28f643752ea6bff28a919e88d85fe720ca359aa5d4c828f2530665ad9810d7dcecc0888bdce4d71e05c3a8579845fbe985ff6d0608fb2dfa1121c7b7e4ebd7209ce7fe2593ecfa2a061fb4e7b2773cf]\n[sha = SHA-256]\n\n# tcId = 158\n# signature is close to n\nmsg = 32353934\nresult = acceptable\nsig = 92bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240b8bf4bb1a6d0616fd5be2f081dc9ef741a9a4ae7274418b791432de470c4556463108388e8e8ed5dcebf3558e4650c2ac97c86fa682176f09b5dd8cfbf15d19c3fe4f961f4607c12cb3dfad9b6a0e59c92faa1fc8622\nflags = SmallPublicKey\n\n", }; -static const size_t kLen165 = 145457; +static const size_t kLen219 = 145457; -static const char *kData165[] = { +static const char *kData219[] = { "# Imported from Wycheproof's rsa_signature_2048_sha224_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f50203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f50203010001]\n[keysize = 2048]\n[n = 00c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f5]\n[sha = SHA-224]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 19c576f191c273306ec6ee9e26c673bdcf3f821adaf13a0759df7787511ddb096e964f5dc199ccc5cf131f855065d6ff0a6c720651477d9026bed82d201f6e84a23b37725fd24f5b75aedc2afa24524e7222c0dd7c6d2742430bab3ec46d12204a94a533e2a9147723d087d619e07873a4261c420226ec1869abd70117c787d4b1827fe98779287451086354292bbb90617ceb391122efe70887710c5cb4549d163d37e79b33c1b336826cb53b648689e6da54241d20df822cf7770d7beaef4bb00068252786580a88cd00e93f5ef42b69efa7c364b98749fe734ee7bd13d0aca585d84e4fe4b29478697170280a5921278997ef9856f7372b6995d7eb43ce0c\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = ab2e758c8de97282a7ede3401680ead187cc08658be0041f108851149a9b9d2588d5ca544039533eebd0305c07f394504d91a578f5764267149d4ef70b88a2a3f8cf0b1061d06882af53a88bef195aac87294dc833d80f42d942f3a59bb242b187e23bb89a068bb4c8a215247d04aec57f81f75c14e711b5878b04863e715d0f359ad13f008b79342b7a4ca095fd021f639e8f48860c1eafe6fa19162c2632a2d3a05330d149f3ea6c9aed9f89fa3f7bcb2cf2a3d1af0484178710c21c046a812f3b8d68027173ff5aeb1ad19ea6639e2d886eabf8149a8fb491d2c36ccfc4da2a9785a992046f24a93d2dd7765a171cd8ecb68b94ee70b0e5bf791967267251\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 61c702c72b0177ac857e52707c1a40b84a1859bf1d7d1cdbda643f924e8bab7c3d3eb2065aff837e92f93836fd54ea52e085e19cb0cb59fa58afad48480c2dac579315340883886e78456ce750fc55b6c188b716bda7957ff547222f0cc1462344de4bf078ec19f1ba5901a0e5f40d93dbae4aac407834b272a2be82c8da085a3e1e9e0a57d3f43d26462566f0aeade04ee8981fec8d7e34c916fe78c0c5c43781bab2fecab654fa55ac99182545d0ddf070d41f67efe0737d8ecab3411720c84862606c8e4b53e60faa1c9a98386e92b03d676b53e3fdbca3bdf0187ddc50086cf82ca6052be55fbb7f3bdb6c6c0432defa5634797c23b494c3880846169b67\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 965f82f0649a338ef14387a7f3335b9e2d5d3b4009eecfd26c0110344a30117bde6bad668cf083beb28242460fbb96adf9754b9a4d4505f6412e677bf3349868fd5b5268786308a5293f2cb2f7ffda76104351f10381e504e72d27435d5bea0517d20ebec0afa531e520e5fe484475a330a40ba1109c204fabc44ec099878a5e31342a650047c299a5f2322f057b9586cd9eebeed1f3d2d94aac24f9d7b2f05c6f28bc49cb2b00f5e56870fa099cfb2c3e276381adf5a030ab6ffd9cb96fe309061d44c2ca5ccdd76a69458be561e3f0ef603ebe9ecd533333584236970dc7414124ace98357c496369bf94123bf0d4e57b03aee567c2f83a9e6378e62a42fed\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 105c68d221aa579ab6206d23be01d0c91f98fb67ed8d2044b6278916223758aa346bd6d5c7282d23a2bf702e0facdfb884e0b389202a5073a715fa80158e31d1e3588af30d2fd8b61233499ab7952f0761c84912b700fec807937d00a021eaa84d96f59760cc7733236138cb4ff1fb04c7d4621331b5c729f9694555b6f9c324e74db4a7a8b72f2853dfd0b9fe63759b3468bc66017bd6c1aada2070dc8643b5e581f12cad170d9fe754c65dfd0a5925cfe846a8413d729103e9d7e8825affc20f477d5bd3860947c2665ca4170fc44f2670bc33b51d42e5df78134919bf4660cfbc092c1cdcc09c8fda1ec9383512abe253cd1a470271832e0c7de5a6d9a7c2\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 3662fc9bc91b00d457bce2fbc667dbb31ce7fa451acdbad95b4b418782b8af67d2fbaf1424be2c99e95e2637d8d39e751d757f89711ae165fe5bf142fd88b284df696e948ee714e3f2062c5d01d04bb6c0387aa5ff1511552dd066bda861e1c5cbfe73dd8c6bc3039b729c700c8f297f48ba2a36aecbb626b5c9f9b3c04102f55ee65ef5477d8d1d14d9b7b048cdac54d7239177e702d0629d3617de2a9fa556a6d4ec37fe38a46b768e39f1d8a380484ffe0cef59abb7e20ffdb7c11b14a42ee3cedda99ef9f71eae7cf760fd81172e03a3f2a9f7e42a813db3b089c11528350e93b131641b8d023d47447f58aeb9f3f38760df8a9b1ad4b8d43ba0c9018e02\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 8392c4d888e7c63ae2a3d53d560ccbc226dbb1d9f69100fd86a19ef30a83981371169deb4ef87aafcfb4186c5ebf8d83764470acc8c9cbe36a9b15037e25b1dfc63e929b0bb3891be2d1804b8c6a0bf65891943e4c0fd21e7df55c134dde69682244d22510dac2b304c10a2e31adc134ab27ed186568fa9091df16f1c9f4e7044ddef6675269de710774ed124b52fbac9bed285b4be5ef9f2fd50e1d95383e145553762fb87a1da173b8b89a7eb9e947d08b5303ef0992bf4e3783c30253a43b373d90a75bd52fc53ee4fb86bfa1bad035a8177f8c0a9f53a6214ec950c2a07cea7f908c55c24dc31799867f819af18fa30f304ea001ce9cc87eb703ab578f5b\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 00a3e40c77eae1f17fbf23c0218bb5baabb4adc424ec585b499a0e28ac21e664a0a8030026a161b1c3eb96cb5d0e498023561f11cb4ecdbca633f5d6087784106683a804301a16911bd7f8fd44c66a1c890c70fdaebb68267253329280f60fd617594194c96714126ad30547a813ce57f4fd14b1907172986c8a525abd130977a8e0a4af8007bb1e9b7cd83865b6f1b0e40b1709663a25bf118aeabb0af179cf61f034fe23d505c86f9f2be08b4dbd9e9c465c71edc0ee7f6236c1b52ec2e01904c14a3da0a426f39a8a5c462bcbf6edc04febbacde1dfe30495fc5c9726fb103f19d30d9d49d69ffe9190f5d448ac2d063ec4bdb8e07aceddb17202dbc25823\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 1da09f538311c3b591f0c28ff1ba3d0888fd583f78c1bbdb93cd44c17640ea658a62e41adcc74bf8d7509e7d46764b33fa02f74cab9db364101857870003caf2f6df6f4c366997d1d00e891a30275554db7690b267c56eda3a279a1c2d9271cace128f8f3449f2590e4f30befa9f374009c7d4d75dc9101e63c7a102fd7ef19c9d8cc8214c7d8960332be27270e913e2906e55d3e55085c792f2e34cfbc6e017fa7211d3d2aa0dbf9f664d7cd0252247f8d9859eb7d738985e2785d1ddc21a156824dc323b272c04ac36015061888de8cf026afd575257f4fb482d5807d5ca41ee8128b2c9bfb22900a6e60f03b3fa99621f2b7990421a070d89d0eb981de5c2\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 22b094143d7c0e14529739d6e712202114a04053f0ab81f2b9ff357e6866fc58ec238d225ad4dc6ec877db71152395ca3747f72c20de76aa4bc04b1a61babb5d3a08017978de1144c3810ab5e371e0236fe14fce95d79fedc74b3108c0713940d4be0da190a7e7b7b90440e91fa1770b56754b4e7a8024ca5918aba59afbc2fda4d60745665abbc2ce2d9ef7aa9a4894e14c150c98b7855f9c015b90a245b491f5c4f74900737692adb05900d590e617ba6ac8e951166f5c6ca69b1e627ac7cf09d73d84eac332cdb3b6372575a2db2531a4e1342f68b91bf6ab49523d5b29f99515fa6af1e2f5d02ed7a7ecf8aa3884a656dd026b29864762bb85e55e4a8e39\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 1addb77d2c6e825936e498fd1210c2b6fca811a99896ad40375567647012f3601f9657617876c62d1314731ea4609d03dc3681e6b53a93ec3ff0d49af491ed906692ac9278dcd0e0d051eacedaab7a038a6a8ec4d2de08103025a726568271ef9561db94f44ce4bda7210057f6d9d70ab71bef8599226349a88161de5e8035b671505b6b476f2cf39589030148c1bebffddff6d025870a4859866d63e8945a10c2cb2fe575f667", "6051c9f38140969c0162d87edcd0abd564e92e7389b223895ee92e35add16fb745ad493d269bb1c691cd1dfeebbde8e343da7051dd6d5afaf7aa4ee78200916ea2497043d07dfa25ffad324549902dbda79f4d9f02817a88ae\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = be516056260537514e69b25f482b4c22c1ff3ee12ca49b7f40e676a48cb424af3ca4bcb4d81b806c9c666ce066063efb1ba00f5b4dabae471e23e3eee7bbfb6ab5d505a725aadb6822a34d12ae00cb8e1a900a25cf236f3b1fe3b576162fcc8f33efd9bc6bc1c44d3c09e5e68c8aad9288a5a94cf86942231a413ced5bd61b4c6ebd83ccdbf52ab886f89d570d78c91d4b2afc3862569570e2d1b5469efb0be9b2c126c32dddac5c34d8f340b52cbcb38b1134c6b22109e7124411522b843c2bc3e575e60b35e7a440156770b85181c95488d82c0a725e02e90ca3dc4d41c8639d110d4bec80827140ffd1fe6e8d0c945de1e1b326a26e2998a2b03d86fbd7a2\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a9698fed4f4dd3d10ce7b039bd40b4a81bbd6a5eb82a71ba710094469479c14c1cb0cc13699fc8ccaf0c10382e1b03771a6d05670e22949c28965318acafde1331600f7337be8c19209b532958c5869c89b8384923a065df377de37b9e5cc7e5c8f6d0fd8664691dd9c97739194e5b2dd6d4330cef0aa0d873dce1405e7a435993fd84b339fb3574c78ed93fdc6fe604a3d9cf15c114e5fccbbbded2ae606fb9943a9a45461069e8b2dfdf882e9898a0eb59c4fadc3d86bf92b8dc537b1792be81b662b9c60db2938d513a7bb4878899df96a59334432d07a42b5de4a6d7c4b6449e3f469cd5f60857875bd1a617a2a8de8f9c0777fcf2e3e43499d90f3772a2\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 89d42ba026f51a31c27e079279cdded5cefe75069ce04bead266af39e266dfd8e9df16a3b9972e03f4afd3f561c931e815c66c2e81dafa56a8e6ff148f37e1ef4e98370c0a2b2e10ba47f7bdd4f433e8af206c107efdde39de9d8816bba196d52ace92335c34b15496c15f89bc087a16799059a556da9e96dafdb835b5553c5dc2c1b007a6ec1176e31a021da8c5106947e7a2316d3874a66b8a4ce2b237775365ec6f0842ade6f2a1b1e7d349189f6d2799c9dd40bd9d32056bfba10d14cd7d25fd260b1790f6ac6ff77631d4a5466c7c976c251f2d4b3fe943a344e75cfab3b8e30aff2ecb34014b906e1f1eb3f55dc8e4233a40cdd5364070ecb1f2b15682\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 712651f84c12fcbe98958b629326bb8aa9cf8e96cd8d06ebc68713e0241d2499b181b9216bb777e48d1191cae390d14dc63f0a09b5236fe6cb73f47d6043063ec1960e1fa5abb3631294e3c7fe3fa155864963a69ae9ad7f1b233a00e4b3b256fa0e28a431ff898155cbec008ec8367757b9290fc847bcad3a71d2026cd583b59401b7e66d552d9b59a010235785e6075cfa5f8a6588c957b66ce339882244311d9d0e33cf277134c0bf72c21683183ef12cff0ca9d3f517ee56acc4d89c74b0e81a7e1a26f14649766b0194b933649ec1fb72ebc78dd9645827e78843d31f503eebc40748a290b5fa5c1545d0801b63d753f0c0fb89e11e387d03c5dc465b2e\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = b23e98890d5806f743eed29a2f972bf2ef5e53bcd20e4e7f8beae79a4e7074ccc4ee9c38bd2122fc1ff4a94a22f25092024dd3aa598c70278c93d70e932402cc0bc7153d87c59c5fe15c50f13eaf4d0c468caba84e43c925c634a5c4518610e836da434a4743824139610d6ebacc07ef9438dbd860be879fa84f3cbc5ef4aaa140b581f7085cfbb343ea32dfd30546f559759df095853ab2d5dc9026f4f51f86a3621bd22b161215088a58233a42f64b1688244ce2a170b8c6656e33b697abf6a72d57662c5ba8e14cca9ac502392f4942f734670bd9addbc1033a33c1e7af3ec7dac7565a8fa50ddb8e220bc2426746bc0b05a9988aaf3b83103ef3a3902a74\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 98053fe9f2dfa6624379b11904fefed76adc19b8446cea727737fa452851deb44ea5a864300736b1c9a3ce27caed3fea4511e9bb9401d3a98b0892fb086a5dc04ae9e1d8ff6407914d0bb730507ceda69efb840219084c8ea2528b4146fc3420eaedaf45c0d8450192c7af36c3d6dc38f1604ea69fa9b2c38baf7e7cd4e0f5c151cc9db3590d505fd73e9c6363ac77aea87c7558582ff3a7b7ea08c4b4ef655984224c2bd9709d34d9b8662e48a2df5bbab3e9df9e5fb8db8411721c73ab50ac3d5a8b31bc64131415cc08daf6c34faae6abbf1b340dd4f3b1b0ab0d64cfa33b501bca552c950ddb7bb5f59562f73c51fd97f2d6d750b30ff19502516f5210f3\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a25aa3f523066ded870d269c7d26ef45ba35f386097015e0ef59a9de4710e88bffc62a16f8fb02eb18704c562bfb0ab9230d525e23b596a804707d98dce426d3e3a1278c29f342b9dc310b5c7da5aaa5584b84e922a385fedbe78ba432adee58f51b2570b7889fe854de8ba2654d52390217fc1f5f6f35f4a75cae85f388640db87e96908fe2a7b78c91f0fad3c118e75965ff2edc0cc9228cc81700069c6e71d4c7b527869e7a3dc63cf74c7f4aab9ecf0b2498d30765ed719ac0987cd5fa1058c81e57cacb3d489866f96d5962b1fba9f48ff298f89f8261e8fc4dacae06576c550421b419e5c5159a64b6b67eb7c709f145fd4ffbe4bf9d46b0b7d70d2e11\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3f0770de907f40310ecfa536486f77d721aa07371f7e3c77849fb84166389876f4bd2c1730ec69ea95951582f9f7fb9b7ca388689062f50ebf2202893842891edff2bf0449f9fd9d9b5b26a6c96033700230d740dc585e64e0365079df974d12fd96cacddf2f114caa5ded4181f63380f30a696b13000554fb963b6b073891ccedde00ca3701baae4818f5e74838f6824b7590263228e7b31d614432bf06e78247cc82f88c63ad0514868cde210e2625fe5b9162781b4ac32a53d52bd673a257863b0c137bccb2f86e481430d4ae570bca908f62c27746a1e8e1bd051fa2de935bc40278c00901e5974756f94b3824b40e695296dfa730c2493ce257fcd7f00a\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5e4895d00312302559c490c304dcd4fc4a10398cb8d545976d6b700edadac5605c44cb0c0c7c7738fcd77dd5830d0601d65f4b1211b365705f3d5fc36fd713ce5b75e18232557046efb632da5186399a1de3dfd0236e2a4244d72637ccfc39132a642e4d467b15140a32550ce67d602d06e40c4a39085f63b4e382d4ab9bd55e070eb498cf3dce7f315c28b7d83ed704dabcabe0159a7254295755c7cc0ef757614e4d04be52ac43f4586535373780cecc58d07511b310fdb3e858489269968751e25c0641519547127bd99233e0dbb82b0c1b984a7856fd28ade5eddb5df6ece6c252283d66c3477c2a5a631f0e032e5330ed8e097426426502bfdfe1434b29\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 1feb9e7455e16c9b7c572b6b0e095fae2a86e99fa92a8d65ed37f00450a20c3582dcb34c049d82c22200988da67eb45c2fe9d390161d50c3269250dd7e0f6f20a175fc4edaa6fc149a2fca18b3693b7779b686073e3c64f430c7578181389b813700da244d3725df2d63e0bff0b59d3894b646f94587e9431da3f508f23832b0eb69c825685bd1b9381d8127431d7efe2000bcfa5c507bba21b538780aabfe5aa9cbd8a075c91b487b29da70e18c48a9baa411f4f1d14ade15b09aafd0a3984013b376b2355ac9aac22b2695cd608cd9b9983821f1d570f523d3acbf119633af972fd5b311233fd0c7444c10d8b964b8372989640571ad80bf3f67dd1882d98f\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 43de19d59bba7bc49d2971d66a98e6eb34324705a3a860f74bff5edc1b41bb7b168cb7fe3639d7dd7766cfda9c8cb725c79c66cdf7b1fcfbf97e24ef45134b23e1028bdd8a3f6a50564970d9c8cdfa2e52defdc919a4c915104ec63b122323c9f37878017b5c2005af3249018417efdec9ac2cfe176a0f54b5b1b5cd949be1bf64e7e2b1d22e485bd215c61dc3b50af335e52ac5a9be0d5e3fdf6ead6e25146c429d7d4e0153a52e91504edf9e48ae8ebcbcbd753f06ebe111b72d7e24b80d5225daf8eec2bcc7d484a2fbb9d59c17cd5ab718557a452b848fc605b7f07a6a053049bc1221214932ac0892621b95dcabf0f9b2321a6af61fb4f47fa499d9f085\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 81d561d769770756f1120220a1b8abc6054560f2797778bd433e53e256419f4f58b0ad1356c2cfade14a7a081d1b93b37b5edf2cca3f51ca82c683781e25f2df36f20af9a67491b302cb12f8b96c49ded82557999ea30638fc5b3aaf546e7e81675c79299c1994ab1b3ebbe6adf6f91a4b5fe15af92f05c4f9a63339dd53675e843f50d5e74c47ef3a9f471a7b5966c7995e1dc9bbb3f14187636c8aa1e1d3bf70d24642396765333b72a2d450d839a6582c7a285db440734e2488baa416ddfdebd7b6dbab4b21146c9adde2a14f69cc69aca5bd0a80f285a4aba56b2f5abe0122edfea4b75404ff0eb6304e10886adaabee2b778e36527f38335ae0932f9d11\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 3b8ef79b1e78c674f827a66f305d67324d31847c0855cbc993fe9159f7a5e310ac2b30621646dacf58e57bc7b44a139c0834b3252f9c06ba6de582bd90de6e94211431820de2e00b9b0ab100239a5a75bbbcbb1761d85a3570dda4889bf37c8d3cc0faad74baa8c83124394cd10131351defb1673cbac952c4d968a4af71a28fc776f6f070b087f69a4d924dea561722f1029dd0c78bea40575b7faa5e8f96d3ac66acaa75aa5f74d11fed5070eaeb9f05892b7faabc4709ebc8b1748fc4d97e1452dc4dec40ab4789df166f68a4c8de218abbffba4b7b1733f81c47b3bf371a35114fff099b7db6fbbcaf37f7fe5d25a0399723a273e2c94f78cd21b4e534a7\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 89721e40d6e14639991bdefaab28735bdf50739f2583cb9ab34f4298ecf8070b5badd7d818fba03bace4d54fa050117cae3f5", "75a97cb31859473040360b994866918ff6b83356ccf53ef6ea900a1a8ee77f31cd5cf25245c9c543463d09c4ecdcd9886513f630c9bee91ae0fd054cce64199a3e43ec3ecccf68a155f2bf1086c59ca0a3be47cec1d8638b9120b67d7ba03ebdd066493092297a6bf597ba63062dfbbd428bcd9725afd10586f1d6320738362e551ccb8631d802541ae74348dfb02f8662ff237daa10ca4efbe33cefdacfae2e6d86d96d7d06503c06375ca1abd2196bfae5c2ba9a2f4b1cc2cdcd59ac24451742edb3152852a89e5386c16bf37\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 10264b9667483464d2bff8d643de5bbc3482da0563fe1e77f11977c6c0c0b9c8699ab5b0ea87d123f8a73f4aefaade654f550a0e5197468246e5f8fe96704172ab6e50da24f48793f1de62bebf8fc54a2ddbd11304678f75831da77f3177b458f3ef73852fceb0c25fb91c1b99e865dac0deb6bfec1d924ceab739da876e7641cc3e3faf530d4a47b283b7a6954e943d0ab1435e217687ce7c0d0664c08b307401f7473e732a5edb1e5b76960283a29df5e39abae0a4ac89247c82a828273415189858f280a98ac509303e2a94c01f5e28aa4f04468744c9279858de3d3e81e534816eadd8d2188624f83135529544205e03f9aa256ef31c00cb5bb4cb69607b\n\n# tcId = 27\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 6cc03e058bdf3761fa04a89069f97bb0654b41d00d825152cd00db635d7844d75596d33685fd02f4a1bf36040ad71d5c448d1e2a95d23dc150463d85394709f95d7e37aa44fe300e3cb6c59967cceb81e5741bdecfd1d877e5e02a543e4acac44c4563df5d5d2bcb20e68c26ba032928c5019b3030457f4a828b19d37c3bc5f341f00e15f14ac1184239ddfc66ad568682620ef099c08d088d5bd0a95935401fc1091bfa2a120e94d25a54cde34c455cadf6b5f784392e3d8a687a9c56f5348fe9e5082432b29f64ddcc292e445f51ee0af42a595e860b88eca2aa486e8c3998c00a3475ba04d740cb1cd3f8f436531271df58bd2f84c8dd20cf45ba4db256ab\n\n# tcId = 28\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 177e1f3535ebf19016eefcc188271b53387292eed25eab416ef324d58b7c26bccd05e5843e49b5ea573ec7557fa3662159318994595a878bf162f5206729bb960c502e248a1bc85bb60025ef41d9aaccc040d99d3b178b609a40c1581251cce8e6f410b082d5635f94dfbd06885f2935fcfbde23ae0ae509af1f39d77c2d94c0454cb173ea29381ebdedc4983e34efef635f954f6d911968c4f79b6487b28ef427805f4c3d14d2b8ab72f5d736cd48fae65ab3565d8d3b7af61b56f691c064146e424bd6db124ac9e5fb82e9a84e2d7da8ca953fb8db2a845640e6d48532adc426c4761315bbc2639bcde29f420cb553d6ebff0a496ede669b413c80aa63553b\n\n# tcId = 29\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2a0d24c903c732f2ad18dc96c7e58289a1ed5887006f1ff7eedcbeb28b517171a25e48bd161b33f8c620fc42f23cc0a4b3ec0c03e42748355650baafe1e03cb1e6dca25bed0afaf5a56f016372dae8b3d92e21e9a5dd7b56b26c9ada092805bdd6933cf2a9017bb258cc19cdb04b2ae507894527d93a1bc85ef0b8f3c2e6fb9671c75cba20986ecccae16470d2a0fd8534fd879d65e62233d0e6450e503912569db3ec382210f8173753b32c8302137f0b3a60faadbd5a2a5c7d117f248797ed44345ed43284adf7655e7f70a0d94c4b05f484553761ec8b7be2ab5bd66d3110b4fed00d83dde2f5e0c6e0dfad1f084a851b07fb097481517805affc7e5abb72\n\n# tcId = 30\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 28d582ef90052ede462304fb54653941f2b45d26998ae7af80f058646d2dd472d7ae738fe4ec226e2937366e759d2cf741b72cdc85f49004a143a68dd4c820985a5656b583e95dfdf48afe5895f6e02d8ad5131a522d8bb005303005ffe99fce9374cc538cc78d4f383dfe8b95cdee1938a91c847ad0c29345c99efb03424a4a04e52e5f955eac56fe5ddbb9c103223e0b3883ef4b1b787ccac10d9de11b85cfb8d3f675d18144ad64ebc59823653d54b85696bb6989c54dd368f0a130d8cdba7945216b7dc1da1f0a85e73f1458e009884d02106a2ed5b66d9871b5d1143d0ab5cf09b76e98d4f03675ff3e74af40e4fba4f9c0b87653455da30e4dd0897cb0\n\n# tcId = 31\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 2ea2f54a8bb688cfc16d6566f6b94d3170cdd93451316e89bef148e70cd85e185e5e19f23f4a8e7a5e65d938a43002ad4be43b3be2e409aca1b69292928d98830945784abd1ceb0cec45984a5496d0ccf9958efeac39842ba50a1cad7130ef5b227fe93040ab7f4226d5005647cc1b0259373e08ffcd242b77f9037797cfafc0254a96edfae31c4f7ee08833c0490082bd33ea25a2138593cc88fcfd7668a82f0cd26f4e1dc65c4e010c113bb2678c91254de5eeb689b582601b79ad08198072c51987602fc78bee6bb4754361bf5be123aa9c1f8c0d8b2a804102962c8da772529947bf2dd36456f6ff6132a0c6ee7347afc5680e705ad3b8e81c9a04f6a807\n\n# tcId = 32\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 0bc548744c7474e5d904c1a21dcf938ef8abc3fd1a0e20d94564432dae05550449d4b6ade94503073f6269bb71afd2b3207b809d39a2828a6f14774bfc04624255c1a2f28a722925e28115c98b20e98016fca0f8c4b3e2947e555113d7bc88d5586bd5a0c361d290b4dccbd1cce03a6df3dacc1baa516b1664608e6b9b097e64eaed352c8dc9b8864b0111581b97bd62a0f1b9396a385de650690e36818fc38d042574401c9dafb28b81ecd14d1b9e64ba867b4bf29f8e78fd919ba2b00f0896ab7d7df12fe4a8f525cb5b9a5b1c13ea609cc7d09b6ee57db3858e62270602662e8b160d7d4b76f2d128c901ecd74a0e2188aeea9c40325c18937e0ab67ea4ed\n\n# tcId = 33\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = bf13c64caf9726506b5cf9605c68252c38c9151064fc85666c7572145a72fa04dfe0fa5aa12f020f4581f1b199025e44aee682d65b1d6f78d52b03466fb52c6c8bc2adf65a0e20cf39f4e9d62cbb6746de236279dedb71e4c3b27fa7b4263911ef7ee2164384ea9b47ab8efe33c7c41a785b3b8c3aeb329248a3ad4fe443828b73b7da87475b1ac102b582ef16d45678000dc625fbcff5fc6509f3b42e0b097617af91c63bdb661a6b92f72cb1ea33a6ef2b6d23782bb87d069f9726c8c91a7b412461d59433a85f04f01a94b7db2e6b493505f6ab51dd2cf37c22cb5b3b9cff2316fc4a7433af2f6ad4946bd3faffaf03fafc1921ba7dc135f3d06f76ab31d1\n\n# tcId = 34\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 4789ffe0c9ae08e5b4a13e8e94fc0609c0485dd09c3d10621187aca1a503b0ad3e74ca519bc90f171f2de9246967b16ff69730a4fe9073685d35105633300f8af20b543f281fc7c2580a7d90e5977b13e20e3598daed7d1164f99999c49a90d50350e5e5e134c3692bdabb75fde51fe7f09bda5af6d98eadd4396bd90782579b02a0d60bcfab72ba3ff4414cd500360b21f9cfab420ccb67465967bf5a77efc2baf38b97759c28aa1df3443713c2967223e014182699c82169375388fb204b8bd609df94f5c14de98c4c4a97ef52bc4a26907e5610e249aeca9c951b5559ab1a63235cdd50ad991efeeb5cc87c2f270f3ef916c76beb90dd0fe380ef1d7f54ac\n\n# tcId = 35\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 3316b766710c2c54ce3c42fe05188c41bfd22cd91282464930c763ff3325bdf4cefe9328e6a6a9eaa0392422cc000a78903552649146773612a9becb4d7b4cdf2c6e468bf11b2ced75dcfb3f5811b596894c8dc7948d88093face5963356ef5dfe93a0839c0a3bde0ee33319fbf28949e9bf8710b988c6300beb0b04cbc841a9018a6a2fd6cad033fbb8e22c8cddf713fcbd096d5c498310a11863c276ba69d81a2327a0972bef0db5303e3d55dc4ccfdbac75885f337867e81994ce7e890dd52a0174639167b53718ad2dc59f75bb111461b713bedbb1fe00c790fed6984b630ead97647648bb09b65db20d2bdbf63b1101068d82a1ec3b2891f932ffa918cf\n\n# tcId = 36\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 4f3eb885b1033c3f5cdbf48b6fdcbd092972a466af821ebbd6f8b8a2508240ef14957e9cca82bcc1b3124828f9e2154353292ba3339f19e5e35bc6f6a678bb0296b2b5f54dcf9fb4b19fad1451c61539f5b2a3c0e94a738f25309ef87b273cfc3495c79a3937ea0cf56d3bce104b9b1ce30561dfa64867ff722c37973afefea4b5a79073f8ea6b0af36c9f49e61998381d0dbbdf9243838a987c7c446bfee0f18fd90ca023c03576c1ee24d8e2706d337f126775f6bd3ac3c5985592209b2d15f5ddb8dda0a432a5992d784dccb4d84f91e8edca9eabc4376411cde969c703eb1b61f0a8b82cce96dbf4bd97d574efb97e60c4a2b50808963c36c20baffb0ea5\n\n# tcId = 37\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 2d481e02fd9cb19356afe5a88342998ef96ef107f5b365c55e24073b815907f3ef9a628146f13101dc8305089ed0487576fa5b149ec6d80a0d1e6e8d874d1aa15f0261605105a63e41c05ba80aebb417a7fad72cbae383a26470e3ed867943a2a697b0e89ae5f2a9fa46edac74bbafec445a5d3f7ff8b010b6e0e0dd815f5a915d867c1345f39a3ff33e49e02c10dc0c87c1fbe3adfe8c21024573fe22e8f6700e9b577ba0c494eb96b55ac1fd6cc041f17f834c6b8b6ddc1c4087b6313012532365bf3771ef37bebc694fff80ae7682452d732da71a30cdee5af3f437451aae30d6b240752d87bfebf1141130d24a470fd991bd06bdc7fc1bc428380311dd86\n\n# tcId = 38\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 421326a7fb2b1c3ccef84998301905f4f7ea1c3b9a0edee378edf33a555bc379399ba64c970fd8c41a72f6d7f6149908d22700f3836fc0baa11f88a15ef9aba5337c3d5ba081715749b04c3a05d026f17ff8c781af9526add7d138e3899651e28544f21dac75fedb70d1a38f48eb711afb66dbd275ff82fa2cba43d265f07b2087821d63a5467c9ec363bef9a55b65537e15fa0b2015d8e3cebcf096c63733cb418336e8f04a86ef9f430d28b78352043151deacf135b27805fccd9ae4bd6e62b10c11173b22ab155555a88960f3d1cb8ec761c56d6d5aa63bad6b0cbb47a981e283f3c494411a4c3f27d26013e3d09bdb7efb", @@ -4125,9 +4763,9 @@ static const char *kData165[] = { "d145d522428c2e9e71be74af29f8e04d88ef46ac6b6dcddf2cb91156278f8b9151d7d5fec55224acc9b4a015762c9cc7327a16ed21a060b1f17b47d23ad66a2e5276524af9acc652e48d350409a119abdc73235d9de02a26964dff902aa1bcaefcb2b3e1a8394a50acf4c6fb503da872e9a65a220b7c1d31496ef10c2e27c00b7694648c60dfc5f238c7ca3063cd91d96d6617d76b0fed8da990838cb7a33561a7b61507deeebb95cb6a455b441305629ffde7979ac76c44601081f8cc425b346b08171752d4b3f711bf979a657e075e4924b73f011a0ba10d034934f8199c3c\n\n# tcId = 218\n# wrong hash in signature\nmsg = 313233343030\nresult = invalid\nsig = bac5e1663853e0a4088543eaf4cdf36e8b1ec7b52fef42081d31e3f294dffb31276834807c4719a1cfb8c7ff8db7020b72058d4dc481da66ab60f40db119cb57b66726329194f8a8e2a22499bb53c1346778b9a02f92e015b82b4ef432a13c51f93999fd3bba3723698bb0724b2cc5f91dcda79e29c5eddad80b7d4a08e3c549170952eeb03188dac1c81bf37dde0378f66fb81102aef841a9a69743f4c78a8e31556fadf5af56d81afa825d37d2f6d8516795abb7d5804ebeab2fe2fbafd5ae355dfb9864c996b147bb5f1d8c1b4ccc3040b42876a27c83df2068f1ae264ba557a6f1c5e0436c04fae398ad4200f5d1d5a872f771934d4a22a1c7785d4bf347\n\n# tcId = 219\n# wrong hash in signature\nmsg = 313233343030\nresult = invalid\nsig = 83a66a917fd062478353636c8a55eef1bbd99fe82af9305ef6e9049d8e96758d856191bc2fa3226166670502552d6a9e2a62a26d449b31f5905a34c1199b2de9fa37ba9970d1a00baf6b070b92a59054b12d83517d3fe5ea4b07f7e234b3cce16b2783771d9d6cca2b7c6477d695fbc2566e55feae9c6dfc183f99b7e27a964a6169e6a27b16c6e51e1e4e1becb49f48d3f225214db85f5b8f729f3811ff4497b517c4bc0111396692e4f438c9a8437e62ccc5fc44ba85d6315a63dce77d13e54832835281982e722d3eee4f4ccc4c4112e881df0900433ef46cc6134dfa75ce7da8c6f96729760172cc613cfcc89ae90edf1e8126f39ca5db76f45eab8c20c9\n\n# tcId = 220\n# wrong hash in signature\nmsg = 313233343030\nresult = invalid\nsig = 60ed20bd7d6f5a7e30cfce9c7cb5686507fcadec04b8c8aaae94353f83a5a857b305aa837eb818e11a350d1c1f1d3b40581118771f57e987f1b9fbfe5335a5dec435982fa37a7921af79cf52d638a79fa13fd6007deaaf9cfb5425b7bb99269d464e4a342abef1be23f5c6383750c6563caafa863e82ceb3aac7d66e38eba4811944dcaf6bc75e56bffaa2d1070202c898b381cdec53dce38601c196b40e1dcaa5ad76d7936be573fd2bedaa6ab98dd5cdb1428d36ff98e1784adaa39d3019ba7685c4ccecb18dcd7d120579b8c7dbfa3334a65d4fa7620c6d57ed256a6ef49dd5a317675c6fdf27d6e58000195c65f5b41ad81f866859e2c6adfe7a8b444865\n\n# tcId = 221\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = 5c206e08becf1abf756f632e5a19959a8f91a57bcf02a9f826555d924cc084efa07cb56d0ac67921f8d7c40155137685cdaf3fd92938866210ab9674cd451ab7ffe6c6e6c4c079cfb14df12a169540f3561a410a83f31eeccf0b2ffa5ad426c8218de9c11685a4352aaf076c815a8cb750e7dc3906eabac30e7179657054cb11f04a70e9c07ed8ec499a274001c9790ed86a3ee1060bafde5c2ecb6545d2e19dcb2eba4cb16e0ac45723849cc5ac4d5fbe9dafd47db853964b90b4f20ba2cd1786ece2e8a34da5d5d63cd5e535672b34158ba66adc480c5b78e70cfa9b05b506abb83e03c7f3efb25013aaa0c35beed9a020dac6e8bf79ca43adaa4eb482f0a1\n\n# tcId = 222\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = 6e838ff1c850eee3039e4ea545d9197b3f4bb810463d20759b7d5bf82bca07f8f82066aed8370c848ee55474fe61b8e0d83594d97a499123b468277c6b8eff5b9f124f43766e2314172a9c6864580fd24f4cac27d254c0638b15c0984008066340105d339418aba4c25e604992b70da5930533e830ba1a0cb9cb95505b25d4dce8b7e62975cb9f5a3a6bdebbe01a868048665ddf64262d55d21de69c6cff62aa7b316993876609eb1842f56279e88c238836ab6360520f1a81ac2642950293aafc945b2b9d967aa6e0ae09a0f9859a773b0f7ac0d74adcce5aff16b450317b2441a8b6cdc3c0c2c527ccca0f2a1e7870ec6e582f0b068e60a105f4c54f014433\n\n# tcId = 223\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 5f4e316d08081fb15f407f929883188cd7ed34b98fa2fcf2cd79ca01d83c86af4b122c300f4e4075cbe94c8b10b573e8f32f8dd24b5ba74f7ceb9583c562bd966d3071a56d4b815c285e16d15572f26ad3656bd86465cc2d1adcb4ffb0b323c1c77b3d4957523d76d82b25be35aa6a4c18e53ce056166aebc8ce5538f4e3ef33be60373f797fab945368e946fe6ac51516ce38ca46d86077c594e38f5a80e2475f3b929ed320ec43c12c12c297a6f15d90aa9d82321ca9a4ea7d147328ec2ab031ed9486dd889460f800a94a99ed2ee7a09c88f4dbafa1b462cdf42840db943b0b952f574a92c972af4ba04eb59540a2a02c538007f147769e238356a218ea09\n\n# tcId = 224\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 7cce1a56772b4dcaf1b2fc68dc8300b8ba9cab26f96841934b207590f868a2d5b0ab94d9e31e2edb1fa2b8785c5255d175f7c5eb3ad81d20bdf20bc6f8cc622529ab26688c74015d74257c76fbb3faf101db3823f6cd164bcf6ad60c3a80ab95dc400d275348d7d6a1f946c37b8b8f38c44ab05198c5e5ac32cee8b8e9b4efe4692ccbde4acfce1ab26cd1d8d10c31929d8ae3b0d24b91e2094ae967a42393ab198259230b07651476208350a0a83de06c588f77e4a6b401bed5339749ec26231e7fbbeb690d3d29b3aaea38214b3ebc3707dc1742fa373da53d98a47f3199d0e948f285edaa9d79fe819f8c37d51aa8a60a8059fce71e80f3b95364a0365823\n\n# tcId = 225\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 654fe698ff8d93bd6ef88c6aabe684521c451e4dafac0a762b4dcff7c159c410ce7f1ad7748b40ee4a97a72368edc33d94f024d83a2eb1188e48fd355dcb77dee4255c28a04e2b3c355e0032380336dc7e2de43ef670e578d1bf75cc25a3bbc169fe70b3d92d187d8eea1ad894ed1caef719353236e9a0813fdebef43f39fef0961d606106fcd476f0f51be3c202555bf96c4d32bdbf019e96b4935c03d0ccca0e62830bfa344339ebc679d90f9bad3eba617b60877acfd9563b413e4b7764ce9c746134c57cb40b7d4160fa26a5c8fa44f2f12d8a1c934ee6bd140bfcd61c560a3f8186da83d26f0d733028c6e4abcd8f223faf6ee371b97d765cb799e0c1ef\n\n# tcId = 226\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 61250794cd149921ecc1e182bac8a1c378462f8054be355d6bbd7159eee35718da038516172d30ea1806a674358a0474bfad792d1b99e014871f5d3ea1b818a1f42750aeac438b37e265119f9ec2ee6c6d26fdc17e080b2d7ad1ac5c0da61bc55ec89a2c78897ebfad49dbe9d6a0d6eea9acfc083551675b0468f78e5fe302298e97280995317a9ccfcd60fce9f6afd9e465b7934a2fbae4fc63cfcfce903e02f40b52978ed8ed01511576c54d9fa33efb708aae9854ef793a0abdf39a68f330423f79448de62ddba7bc8480186a2afea384d66b58c71b1c1b1aa905af314db3ac9f20b1449d2e5099c4a17ea0f131d3fb93fbfd79757025ed7c96d14ddbce12\n\n# tcId = 227\n# invalid PKCS#1 signature padding: 0001ff...ee00\nmsg = 313233343030\nresult = invalid\nsig = 1927a8ca62884d8515e9df565abc521a1c40ee409a7aaf19368bdc2c24f9e0cbd1f6a144109273acd712cb0e34d367d76800dc5f0ca9145feda1c518cdf7d07dbef73c189db35220e78c46339fbfdd63070d47e2bc1fd8dfa8b5bb08db1266960951da2ddd16a345c3d34f8bc59622e940a8317685a98f5883ce155471d6c96605b285b754032f998f2e6cd62139f75cd66b1822dce1a10b5af8c22d0931bab50ea1a47230a2dcdf77b720411bcc64c88efc0dacbe8610c359575a1dad37f923a6ff44b493a3b5ea1ddf22c205484cbe07ee665b04e26f9bd7ed62a66286b32a209fda6b5df0d7df048c400f27c493a2504bb1b10a20fc7a5566d2c0bbb3783b\n\n# tcId = 228\n# PKCS#1 padding too short: 000001ff...\nmsg = 313233343030\nresult = invalid\nsig = 89c981b36b3a8db41f0282f14fd9cad08d7c088b56aa16eeac5f643e83ff68d165ec6790a5c195bd37ca3e6d23f8da5187e866ef44c401b338337bd4f9312e8e87b019e89814fd5e24d322630555cdf628b56f93ef81c435be13cba6cf91db2c32eb6927c9db7f856a4f86dd127e9cac8159a990cc816edee7e8c39f06eff4c72c8128d2be37d2eb2247a9d709797af04bcd744d54741b14ec0a5b7b1583f9e12063521d1e7143690fbfda7cea18451599e76e7c2bea000ba9ffd5b8c547c4c23e8975bc6ae22eec79937929487e0d1166dc7ea9f6a1e71cef41e704e89f2d01b7a81baaeda1738756265573528a3a495919dc65abc36c9aa246691fe0aede70\n\n# tcId = 229\n# CVE-2017-11185: signature=n\nmsg = 313233343030\nresult = invalid\nsig = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f5\n\n# tcId = 230\n# the signature is 2 bytes too long\nmsg = 313233343030\nresult = invalid\nsig = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb0", "0b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f50000\n\n# tcId = 231\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 232\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 233\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 234\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 235\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f4\n\n# tcId = 236\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = c32cd0e1441fde8a2896ca3a133735be2d1010777cfc739afc77b6daa66f367d4876dccb3021fc22c25450a68d6cfb1191d485cbfba5ec45b49286d7cae2bdae553f47e10b94f867abcc6d0affc733bacc725e5ab4de1aba19a39d748b4c1355d5a6a710a52bd04c0c24e7bc3bdab8f3ce3ae86ecb31c4b45e10b40ddb5fdd40cb2411bcf5b1d392e1eef959cff2709a6e02b20ff3b4343641a6b78599586edc9b673d9f3f5e9d339ceebf96a1a31655876c39fcb00b1c3e571908c9b744765047abb5c23ecc42e551e13755e38cc9a13e1e02bcd5dcec9c301fab75be3e1a8ee9c42981607aba7855f4bbe76c8c160e80468b54bdf9f438b177c33dee30b0f6\n\n# tcId = 237\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 32f5b016f20c499f3cbe5d57253f464bed824eb521d191f3dc668eb9da87c8725a012e7969756a5ed530266f109a4666997fcc27419c208ab0b40cf42d5ae972f2dcb10fc3c8cb60f10ceb8f44394d8e66633f7846f1abb11c581a4827d5606558bbd7fcb6263b4c877e1682773fa94f1a1dba167befc444b89975daa7f8d30c6dfdfc397c21db569f887a9caf74bd8810c6bf8a80f38d2267295c3e05afc3699abe11cfa69dd385de7da73871e4c16abfd1ba60abedeb54eec3763cdaa533abe970f75d63d2e936e75bca2d1b467e42490065644843a509d2dd58d178e28a435ef4c48f2017c5f7244b4d8a74fe024b513cfb36dd2d2dada6fd5e8975da1595\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 3fa351c977a5fee02f875bb284a25bbde9175cddb79e53ad79b76b6e376a8967ac81e6ffe8b5091b4d4ffc3bb4394850eb912d2c98f60ab4fbd24e0b5b28b47e456d36aec7c11fedfb52ad0307ec24380ba1a2323e7f5786f655a6f6f6048a0bbf6e4257c22decd00d55556d06bcc138eecf2d51f2353df2c82c29227890f235cf84495febac0b074c35a072cd97ff206e3fb534de0315afcb4c36918ed8e39e84c6a1bed4941ea9ade58d45ea215174b0d45700918e9a3b44c1cb91bfa52d663ffd04dbd70889b126f030ce53e613d47f7cd3324856f1c41286d6ee16217b0fbbfc3ffa4ad4f2d323ab36fff4129cda11e42560791141ea22000ead1e2538cf\n\n# tcId = 240\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 199e5b886bbbac2fca6542b31726326be09fa9b865fdff482ef32ca5e91ab9b8a594ad1fca636c08d5ba242ee503d0500574fc07dfeaa2ccd6b0ce2cec51f3d97512e89494d6a33084095e1e3afcfd013f95952e3910b74f467d8d574917d5e0086973dacdd005d96e0cef0f6f518994335391238cadadb5871095cb399e2b5af51e06c00d2b78ac3b10d16e2a39628435e523f54873265b97874ea8f3c44c0bb331167b66ad055cbb6e236eed72a80081ace11bae8aaf39297587e5be4338f3baaa2a6623a9624162ab581371fe58f0ea58efd68465451502ae27596cd58fe40a841be295a81df636bfaee16afdafb01dcc717cd02b6065c1e99bc918f90786\n\n# tcId = 241\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 7e6af5ca287a5546bc76afcf42b1d5a8e4b3c3e276f6a56bb643cf3d84995437e830bca498c651b873b48c39493e71c6fd23eb76bd0d7523e092ea4c8f106a505f52605930b8ec244ac9b02dc14a089882462cd947d6e851d6c5999ab7b5325afb1e7c3a75f72064f6a66307dcfd98f86d8e705ac5d44d5a62023d97ebf9a759c6c657ea29039ee63370344610a2a072aa459b5309fa1ed4e1569ec40c57578166ad80a5da0f3b6d4f48a9c5cde4435d8edd5d909fa76228d8d7ae71ec5709ad08c24dd49280308e41339611df6f2e339215a70b901f189aa747be01867b8fdc08ba7fb0a867f3ff0e0aadb123747000db8d171b9864bb95885e912f76b3b21d\n\n", }; -static const size_t kLen166 = 148331; +static const size_t kLen220 = 148331; -static const char *kData166[] = { +static const char *kData220[] = { "# Imported from Wycheproof's rsa_signature_2048_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d50203010001]\n[keysize = 2048]\n[n = 00a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d5]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 840f5dac53106dd1f9c57219224cf51289290c42f20466875ba8e830ac5690e541536fcc8ab03b731f82bf66d83f194e7e180b3963ec7a2f3f7904a7ce49aed47da4d4b79421eaf937d301b3e696169297b797c32c076a12be4de0b58e003c5123051a84a10c62f8dac2f42a8640008eb3c7cccd6760ff5b51b689763922582845f048fb8150e5a7a6ca2eccc7bdc85349ad5b26c52137a79fa3fe5c29ab5cd7615013219c1941b6708e9c3c23feff5febaf0c8ebca5750b54e3e6e99a3e876b396f27860b7f3ec4e9191703c6332d944f6f69751167680c79c4f6b57f1cc8755d24b6ec158ccdbacdb23107a33cb6b332516c13274d1f9dccc21dced869e486\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 8a1b220cb2ab415dc760eb7f5bb10335a3cca269d7dbbf7d0962ba79f9cf7b43a5fc09c99a1584f07403473d6c189a836897a5b6f8ea9fa22d601e6ba5f7411fe27c638b81b1a22363583a80fce8c7df3e40fb51bd0e60d0a6653f79f3bcb7ec3e9dc14cfb5b31ab1735bca692d50ac03f979dda92747c6430f8045efa3513ba6e0ce3e9e35570e1c30c8ebe589b44192e1344ca83dfa576fc6fdc7bf1cd7cee875b001c8c02ce8d602769e4bd9d241c4857182a0089a8b67644e73eef105c550efa47a40874289395ac0c4e02fd4ba98e130a4c2d1b95521c6af4a002ac3bdc6e52122ae4c08cc3da1c896e059acbddec574ac0432f6103dd97273d8803c102\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 264491e844c119f14e425c03282139a558dcdaeb82a4628173cd407fd319f9076eaebc0dd87a1c22e4d17839096886d58a9d5b7f7aeb63efec56c45ac7bead4203b6886e1faa90e028ec0ae094d46bf3f97efdd19045cfbc25a1abda2432639f9876405c0d68f8edbf047c12a454f7681d5d5a2b54bd3723d193dbad4338baad753264006e2d08931c4b8bb79aa1c9cad10eb6605f87c5831f6e2b08e002f9c6f21141f5841d92727dd3e1d99c36bc560da3c9067df99fcaf818941f72588be33032bad22caf6704223bb114d575b6d02d9d222b580005d930e8f40cce9f672eebb634a20177d84351627964b83f2053d736a84ab1a005f63bd5ba943de6205c\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 1758eb94588e6fc4f50c1be1afcaa41027869f304cad513b1fb12c2f446d63cdc05c4830a7e3e630da7b2da4f7867cc173bf6420f9732277282596de41ded32e21d0cc31441174da8765f57419c7764ea758f55bc17646eb100c435d1ac0eed6fc7ba6de5f832094ee2f479979765e05ac9976788db3c241a9e32a0da864f0019a87646ba623d63f4411af5dee1be9ec488c7e3e1b231479de70b9ac5f78a17b1f4120aece45f26c07e7bb345fdfeb05e14bcaacc614672a465fc523624cb19f66f9c6c3f642b832ca44cb25176d679f0e05606c3fed022cac24c2bf960a406d48818e3eb7ed53b0446032469047dfed95fc18088c92d91d93722c47f88163a8\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 513a5abde16b5e0ecb8659d3ca0845800adf75cfc4437d42fa34e7aafbbe35fc5984d3560cba938f9a622e932bb6162b7fbb6cd8c1cf8815f28c495995ac18cdbe8fabfdce29c17aa021df192ac02d080d7c5eda6bd4c99154178a9d5e1cf3ff4177106315f4e6d74c991b601069acd60b55b3bb4dbf6316c35096a487d6756181d3394944f1c742a2f4d608ce4f6abbfb72347ad7d342ae15dd6d1049fbd0ff55f4d7c43ab805f81ff1fbe9256b5c78c2de6beb787f4b6d66d290a3d4c4857368aea5f7ebaa1296020c8f9e3670441a08038bb810e853a654e44316a4e52428745123ce2714020d00e55a9eb82f7fb41c73d852a82b003670246c6ca2045fc8\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 38c042a00d6f27742a46f1f963a7b2e04f0eac637849631a491b8e4e58fc721c6ce620d5e705dc8e73409c3909c1c68b6bdb2b30f882cf2797e65030b38c4e7daf6fef9d1f115c890086cf54ca3e7c2b21dcbfd1250ed1d925810970f17dbf482d1784f296adee9ace6979075c1e12f5580cfb322e8737db9d127d38e1b99ed87ec49448a18a6fee650d3c27e4a2a86a3d6e3ce4fe64120be60872fa07a3f78a112715c167fb6c900698ba1afd824087a4cf733335c4a6d5120e3b29bc42f3b3d5db79973e4e321e0910a288d18cdba172d060283c4f4c6656e9175a18b756b7d06251e9060bbfcab04978853eec6032850a0e757bc0c61ad38aa4eb6bb6d907\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 2ae8d95b19cbd64d0e343ff413fffb85d8e6713c06ac8a1ceba7f3924fa740f8d2b3e120fd71f22711e795cd6468c5e263b1a5ba6ac6b8fa9e23d2d6e7243f510592a61d134e68b8ead00612dbf38c5b7302abc3bf33f23e6d4816a6e3ddcea6482566e84f57464f7d56de4cef0b2256ef21874dda4c131a47292ff8ef853f93804483c8e6373d39ca3a22552e75427b812b861de6a310ff4c366f6f6604116efd9770170aa423554c4ebbd2b5c0698950e66bb5b7c5c346285d9f5c35146255736b6e818e8e77983c93b21e7f60b04a7a525598e7fd8049b181000bffc7f3753a504370f6bb70617ac8e914deb05a198a5758a459c9fcd2fce1aede48e8a852\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 095dad1fd82bcd36652a381b7f4dd656bd89b40aa58b56da4f6aa8247874b935e65d2b86752d537df7103884d39dd9ad3d65f87404526b09094c5615c6249979b0dc58d2199ae8696a5b76b4bb03eaf08c2ab6aec686c6b1b289c9b44f648bd30cb1ac6a64a73d68e59cd05e7aa1b780f4bfd7b83dfe3b884ec11821a93dc5bbb47a00eea4557b6b96b5656276001f1f295ddbbbc511a99b9a665b9c2674c8af0d812286d0be3ce74817ba2cad283757de35dfb149f2835f60cb03ff155524a57f78b148feceb84cd20b0ae22e3e48f433fbd9bfd60be8afec93165ee0310be961d3695f309d031320c830aa6ba08b5a51d943797097c57630be391bd23736cc\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 8a0e82d4f334aca72a718b6f8f643f69c6048d619d5eba71263a5d2d3ac7a7af133b780c7595ca2c982c006e861948f543cd0210c758691f9626842c25de2843ea314ca8eff285d47e0cffa54180af416004017034962a80a5959c3d3f1bfc154a4824462a93c014f6dfe920824f414a6e30e0e5944d480b99949ec7bf64c4a7461575933b17d7d6b0178b5192392ace3ed8469e8ac1dacae51ad5d3ad73dcb213e056d04596e64d8c0703def3110c7cecc93ba8ac8059f0f3d66b89d8712c62b41d407e4b4a104f4569558b0290c213cad6d0653898b9df8f4a453ab07d13bfb7598d505abbd0c4987e4f1ac66e1a523e113e370ab7cf990f0cc63f50f4f0a4\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3a380c29ce2f304f33a08aed4bd92cc6e8cf56596928fbde6b640cfdbe1dca564cb01421789c7fbb49856bbafb34da6e1c8351fb12f79a4614c33e50197939e237e0b987efdbc042bdd09073f02624c520f1e9524ec1cd10e917b9237166e3689afb710e6c4ef644e08ce866da6dc8849e0b2b4c6615b0aa803bf112e9a4883c8e60660935c43fbae9d939fdce49af603dceea05246b220a5cf99044f0c09dc98f3640eb23fa218d1421adea7898563144085f2c2d1c113e7046f80ff359b2f65742c58551ad62eb6dc6e7465553f7080fe100fcf1aad89fb079bfed32c8c4c15c84d2193de22385df91e9825717feb5209f1dbb47962df24f3b43c114417ae2\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 8d9c25235cdcdcc7ca2558c0be14f83afeb303f00c13106ac5affc952af527a0585cf4801104a7d019fa2e63fd0b923c061a24b8be7c3105443c8eedf4a033d3de802adfd80f872d3c505f41e3feb116f5d5f31f04df3e448bc7e7cbc2343f7dd4f4c3d2670ed3d3c66f91d626bb12a2001160a123d03b77d2a6ec53445db517147171e3ba3cd7dde902c486c74e8d8d33d4f7699791179d1df4fac78cda67da9138c18f2cc886", "3018e1739fb309408c62051b715096512602c5c4c7e7c394282593ec087832fd48b4f353d8046600e4152c2092632a79bf05497a13840e171047d79c23a76896235e9d5f0f56a78d3fe472fded2899e228f714690b40b66ee7\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 884b4b6838fb629fe42914cf15257111b502385d71dae543d03597a46cb10a6122f6d539ab411161ee278f16cd3b5f4bb7dfea0f907256d96cbdad1f1fb40093e9f5c97880814d86091bfa080bfaa5a955af9d15e9460610d4c859332c5beafc24fc9e02848e951eee2797246bef20dfb89e8e949ed52af39663f5f088690f1a24abf8a8e221582282127344bf740308d146d6d16b127d1639071037fdcfd630342ac134ec24791cb8905b77dccf45eb3ed7e9b2e72e60b5e19367fbb5d1c41853d79965530b3181e4cc7c24b198a61bcc2e63806cb6b3c76757737e35066b7f1bf0dd709216fcdab4f35d550b31ccfbda9eb8165aa78ba4b4e66e316ee07282\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 9947c137ebf7013ea9e41f1ce93fd29022e340e6ade56c1119cd826430acf9833bbc1ed05c1899757a79d3104c9b4133ff0aef7e1cbeaafc2ada2422bdf9e29926626527f947124d5549d9f4fddb809f84923aa335d331c392a5ae5e29cb0f503e230ce7bff114206d5dfd51b812f9ed5448d9100125a8cc2324e560c69f4a492988045c97ab90a2806df900c3b95ab95bd634dd0a50edc5312eeef6463bc4b62e54261cc67e9cb9caa9a0a7550183c9e03f26bd5c8718dd77f54290b3a27a054d7d3e39e8cb45529d585ac0e507b8688219d2b8032268020b68d2284f9f743debab5cd47fb3fbd77fdfe3a9d7984b11a37cce190ac89a472578a3332b150f5d\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 259cc7e43882850415f4d7f2321fde08212490f6e9929c37c6a60cf686eec1dee385fc513f5e4105f19f2d63565b2d3762080634306b4ca87f857912bc062f31de6cccae9b48213c1b661ec9874d426d74e4c23c0ca53abc8f7bfdfb9d32dc6b5559f6aec33a5b9445ec4490302af6893890f57969de00287203d8df9a511b678caee2a7d666d9fca912826216ae3c62a37f12dac1412100c966ec7c8ff347eb79566784ef86943e999d0d1aa46fc9e5b90e9b91f4d16bfc2d5b9ffd4515f1d23cd0ce9612d19c28079702e1bc96b98cd86a5708b9000a5d61777a92d7d033557492f9ab1a4aee6719dbb14e6c3b4998480a8d49013898a5418bc8c63c41c5f1\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 8965489287b5c6732e9269f3ea349830169f9ab644076423519bd18d744e9547dfa82d9bba9a8cf4e1ff5bcd79ce2c4168a8b6b1c7931bf4eff64dd18a1728715274a735b9f529a2fe7b02cdc2a8740c2f16bed7e0ef2ef003089a30937f04c2d0617f70db8d67ae9f6200b8279200a21a7862b7cdb406d4855d8fc950a10d5430424e4872714cbe07ea03f36689f756ae0bc09b08cf1f3343cac1e1ae6f943b5d0b2a3df116b0bbf2d433a8c03fe27c6cf2de2c0603b2fbe174a6a4d0009248c0a04ee4b6f393195955ba0818d5e3abea276d9eac469b5eccf6b37d42e38d840513d7130009bb93fc3d208b89429d053ec1fb5b635e6240b3f0021c7a243640\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2503d3586cf23777bcf02ac28f32daa1664ffd2e2bc3c34377d80718cd02195de3de6d10cbb057db69ca2bac07881497189bcd66b181972aa8def94a879dfcc1175aca14781a2abb39cd71569b721e69e9d9504b4ed54a58a4d8baa5f17bcaa8ca9524ed86cde37a86139bd62502afa770f4eef4293a0ba157968e42e77dd690a3920311d24013522295cb726e006a2e7f26dc287fd2754087f784151ac30188937c99cb20ae8d26db527d5dd3020742e8964f518bf13bf2cd36d99eacb1c81a6a9a46155894153d3c1a98e7671233febbf4f30bfad312e0dc4a9520a97098c634966c204aeffe7e55543a436ed003ce0772d9f57c8b0d3164ddb785639314a4\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 129990973396b70468d380897ccbe6930a485460bfc199c7c8efeedf81c7fc6a98f47c0afc29546c92d3ac2d93d8b1c6909642757fa52de1375867a197dac0ee58c5b62f12182a5b4e703ca981ad344411e2dc3aa6c456dc69651cde35bfe136ca323753137b4a28571eccf8d1f0cc4cb4977238dc33827f1bf670d938f5b902e6389c10b564608b396feb0cdca57f5bc3ad6bbb2cd324d531b0c5538de37482a09ce103ef6399cdfb404021c836151c81adf6f852f9a96919e4e78ce76aec77a48bc5eb224a3fc404373e28f07a1488ce2fb3181075b852a87941bd11735b3cd6f5bc0b660031fbf7671d3bb4f8c9f653b8c36e89320f7532ac0fab23dfadb0\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 2a004204ec4ec1515b855f1dd802299780835fbf7430f8f5861a4c6d86adaf38159858810d8645a3076fad16d6daac69b942890d6cadfbd12affcc3d3fad8f07e90c2b1e5aecfd9716ac9a12349e4a4b29eedd9bf59d875cbf028bc9a1a0cb4f5ea77b7ad026f09a208d3d39477a1ab59329cb64e9edb6e7e552b8875a73490551df742ab300f254b7805b4a9ad72b650ca944289a9c7c5223d760baad3dea1fc36d2b5961684840939fab0ffaf7fbb7e181ce3b92d9f7eb833235d97431b76891ef910827d110ca9fc88f7e4f98e84d00a98a1b5c6c70d86d89f56bb4f33cc88936db2b7f8127d11cf94d91f56a07aa7880f6a7c3c25b0df691d8657c330a5e\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 002faa1b204fd30ee0d3d6d79274f3b498f736bf6e6b34c0ec6eb418b7a4c105c1a75669c092f52fb1d39b2247a8d5692aaa44d4a4d70b8f9e636dfef370db9315fc1b35434af3ca21afd366c3295424bc1230a898186105a07788b92bd42c56d5b66a336fca64fbe58a843f391fcb58588466e0ba484502aa26c50ae35585eb95fe0ebf248b7a57782373cbac21a00928a091455347127910eb0b9ac35c1bac4a99eee0b718550ad282b4210eabe0602823209902b2bfac9283baac38940800515877366117a2d383e8f0cd09de7c946cff1eada4f1f97c44cbb3bf3562ce21af7f499af8ff40e13b907e5f4d1696dd52e3726570228095b89d4ed958e618a4\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 6d8de4a2cc01e33812da2d364cf3cb4fea7c6f37b4314c123eccbb2e4e9ec5d593934c60dadd5fef2a273d01447519573f701d398cfbb72b0c19937e9f7805fc4d354e292c5d0fc18bb872f6843a9211802f5980538ec6b100e3b2b744693a9b8d07654d2655414550a1645f047c865291ea8043137758a13dfb1652ef7dd42182603ba597eace857f39a0b7ea0c9a987326f55358910cb51e4141653e9f3c3d73f09686463433520ef0786163efc39bba3c62cd5c3599678a28b90470bb6f19fa1a56cf60e8c3465f8d7082728c20730227a2a3d2a6a4cc50fe0217f35a45459809de1f921ac5b6aa833a85bda15e288abe640829bc4a0af1aa9b3692a414a0\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 4c698321f4342f64a87fe6b199d5800af12d39725e449c79706e9af98b51a2d0d724663ab87618b06c49d3c1b98d97db35fbd8746c1d9a61f31ead8893ecc072057ad4004a53009703f66bc2b4fa7fa6826f54e8b873c79bc19ef71fe61a182a8be6cdb6dd35d87d1f46746022f98360f3870f49aceac4bb1a839977af2096539a2d182dfc4bd97af34ea075ba96c39c4a85b3ca83002f97e992c110d40cb6c668eb9fd022a4ef89988095e8c513153f99e37d9cce75a7ffa0a55af6b7d8314de4690934d55895b99cb0882adb346feb8af0480a4fc46251649d6cb2e4358dbadecf27ac713dfda9b8f40cfecb642b39bc1cca681d5628f4fd30e8788635e937\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 43fe92f5ab6b2583fbba40b493ce45f9eb5f9e0254c6e2547ed4b9543a2c3a927d5b9c1c12525f4f94fcddcc4c586f4e16626ef48fb0688e07eccf77dc65a26c28f374aa4bcca05c72555e7f54d896065f3d44a728bd2ef9c8adfa698b963c16b13c1d5346457beb6a66c964330e0945dafc5bf75f4ff26e84c0a8bbc854c6c877ffad409b11627ba951181939ba9a2e28764de34704a5575f43f70c3f4bc5d74f4d651e25f32fe238f193d4ca55c04463dafcc2bfe50e017fe9d3bd319311bd2d972f5e04d8324a4b26842fd66115ebd139440fe89bdd55d10e14aea5d9e3f6a5c5fac4acada9d9e2006e6a0c36f4b94956493c9a582eab35c69c9add972d40\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 64401a452e3b56bebb1d5f3cdcac3dbb0a6f6e81bf2fe938143b9df7e8f6380687249a0c30a2bc5ba0fdb1e4d0fdecfdfc74064d365fb8dbca0cefeec0ba6fb4f775b4650839f03dc681c1f78d298f6c789ef4734d0a3ceed09ba8850671911e5e68af41ba2f37f3e56f7864fe4775ccc6af928876290ffcd20b988540c0146db97e333da0eadd4772cf15cb494e366f1f3bae740dbc69cd339a5d1f8a5e608cd61eafed4e85886796520ec5ad7240d11f1ce25463b57d0723509fc368f8f81a6c63ed2c61a216629dcdb9fd226215f8b248e2dbab5cd4f62600fbf921f4fb666384333d92251578dbdc5dcecfacc2c4435a211cc984346bf254b7cd52aa2bf5\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 8998ed832b496be462a431b1b32c3696374d816bbdd2e348d98795a5ad27b02766aca9b161d8e8c94370fa38c56ab0ea9aeaa0bb37fee33a7bc27024024d321b25504874343cbd50dc31ef1429b16e2ecf53deeef15b4a8e5a447cc3f1b212179ccc5ae4a62e5af2127c02e53e8a23cec5f1863ed53e62f472ea65d599272a5e4c0a0802553f31dd22103b7fb7155fc8ef4a3a7061f78f6e72c265e561436159722da4b8850204a7d85f7d45c18f5ed4e452cb146c47963e38cd29f2dd3652720fd4206bf96ba2c7601895c8771d1b73f03fa88ecf81b8a8f2f290094d85521048ae0c097460cf8340ab32262115b5332abd75950d46ae77ff03cb618dd69e52\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 09634aaa108980fb190dbaa425d9908a4237a2531c6471ad47dced90ff65e217baa0d9a8b5167d1c07fb414c88214e6caeeb6", "a1809cbf28f9c6083bd54cb2fea79296ad2dc1e27de2e96c056842ad7694391b40c6b6a6693c64fc1e3dab13185f8c1406ad4d2c39a04c3f6437519489b3d6185d9415d97e9cc405dcafcd488cc4b93a9df5100c1fa8dd31c60575dc64067f2fcd26d1f5c44919a4e28ae00688487c279130d087161137d6fd480111d45b03057bfb7f79ae75362439775f28e84839156b9f1fd1aac698f1b1874ca19964d30a725e92d4ab784b8da18258291f86e0116c9d3d4be6931568c109068ec52af3a26aed5ec136abadab1688f06488a\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 4e63d527dd005236fbe35e838f51ffb09afd2669b684d9bf7488ba49730154be9147a63dd33473ebf547272cb6105b114f72f544e4568d45dc814a3c5250acbcbcab008dcaed3458e02159bf5be9e4b20420f9e4c075d27bb980748528327a1bbbc93f63db57ab03e7fd86c61db3ff8c39bf7d818a26d573fe57f5010718021e45299624e25a2f5acabcb3a1ca608fbde28d13cf74a3f58d283fa5a41e875854cc480c5948d2c0d57f2b857988a28e34a7dc5159c86ae1f970f3e318e9dc9d29641a521eabc66353ff0dbea4f237bce4ae546b8d05f6ad19a4ad8d4cd086b22458b311eb970ca33c484f0b9dc544ed4ddd88e7f70edc32702d66ba570b749428\n\n# tcId = 27\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 467e9fdad9a1f83ffaf7622a156384920eae46b89f63c3fa61c5066786c34108ff73213ffc7ee9102f367726854aebdd9eaed49b32c88517e136778dcdd7e231716bd618261615d029241a77f148c1e5e39777a9f85fc3d4e9320f2455cdfd3280184ae17e35bd9be0a0a0d1c2a2d321a3bc86588fce12d929de1a2f473026e0920b1cb8b6dbadbe3810af22a3e95dabc9553733afa026e0c7847493182aa1f3057a3b227775a3d7ba139c1724b3196f6300ca4ef457c2bb3f09bb2be6fb4e7caee6d4502c962291da0e499213209a28cbf2c4adf5d559e44075631c3035990aceca49bf6161203390509a80bcec1d274f1e9a1bf26c9f59244a695adb2c5fb0\n\n# tcId = 28\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 063b7dddb7483a77af978f1f09180b98557643574b40522da25e8636d5e5a71888c79ebc5de9ba6ac0e4c30c8dbcc4399661b117e4252d980822cee7cbd4d2aed3a10f91011d11ff92228d02393cadac68030123f52529d76ca2d41546cbfbfd28a43c5d52026ff582a6bcdd10a3dd944fd7232bb950ed162f8827a5625ff322bf98e079dedc770e4d586a7f28b4e19452a353eef2defdf56e0d07dc2fe5625d91651629c5b7bf6e180dd27a1cb51787ff264f0138b46bbbd32c5e1ea63722b4baa8e235f27e283ba6c46f1af28bd744e2db92e326ee7139b9e5370fa5b5e2c2bb79b60c9f9e305a8acaf29340edabf7531d17fffca6f43ff07ef5cccb50eb32\n\n# tcId = 29\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5afcf0d327a427f6d51b87aec24789fd7ebaca9c4eebcc307664aa6e92b6acc22b112faa3918ea3ef24552665965842639a532a09b914bcb3b953a0726d5f88eeac1bf65bbdec56d55bbdac534da0f83e182dc8cfd6e9a59095bc82b5f0f5f56a1163f716ce722d80394a712bf0d5d24cc13961079082e4598c8df5510e20febb3d1a778fc5876c65a3e1d3700ea537c8d67f7534780fa8d1cb0ef9c39e439dcb8a4c8b76a723ff8309e3f3cf39e6cdd6e52edca5308aa6be2628608d5206e82251f9f7cd711183f3604d83e1c23ba71041b92d33a695225b1a3f61fc742f969726d79504b224be259e9115f1988bca3c1e2b61541527227c3d629b22a95791a\n\n# tcId = 30\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 543ffa8db719767c9eaeacdee487311bd4c1d3b6bca2a07c6a3989eaad5f39042dae40b45a9b5aff326a2994f36f0a2a59ff3d46a3d4abc705d26afa3cd35a35bb662292c6ae3a47cea9b32de37cdadf797cf72c7c62f7c9b61024ad8c7c82f5efa27c8dfac28840677116183f1f0721fa36ccfc13ee5863589b0433b20b6e1c954cca97b3796232a3b0b2b6205382de80db8487bd00b620a4b423acfcaad649a683b915de7caa65a4efa6b0a1249a6d90348171b816deb0cf8c99013ffd84b8ebdc660866b56545de6dc4aa23156cd86c5bf3d5765ab48d8d601f43dc898ea6e05fc0460a28bfa2a776e8917c59f02f1c8e1cc454558658768acfd717718c6b\n\n# tcId = 31\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 5f912ddc495c20f1975219b0b5cdf0629585a98d5565e8ef2c98fd945cd851d703be32da38e6a376c1269734de5e72734cc685cded8a31d430f526dc3788dc2b54de838ce6514ef970afecb8bcc0b2cfe0c5e8de29d2a6c009813050114374e1db8d7f4cb714ab291a6095b7e2713a28b5dffdbe3ef127307e10155e0386e3af886cbc8e1b9b66086dc9c48d07e460fa4cf66197414a4e1a72f6bf09ca94964d668666ec1daeffc52a3384cb61abe1a4ee0c26674df776c7769fd0c89667a421855de0b060b169eeab02ce0005a1e7d7a126c8583da8a4900f14fbce7ec1b4120994ebebd3e97e0d9465bfb53f2ebef725a10fccd0359a2724a9ca18b2b7f715\n\n# tcId = 32\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 5dec8ec2a5ccc79cec9d4455a2479f562c049430d572b98e5bd44b83ccf6a08d94cffe4699dd29568dbecddbd28c92c771e37e2ce716ab7455e4a92ad87f9e5b76aa1ef1a08e3a77633bc71b3756e3ac956eb8d5974cb50b88a6f49f36d5d0e84bfc4d379621fde3bdfebfd9cd916e1294c854330218d50aef788aaff97e68f7cdb2e7a12e8350dedad00a0ede2d72fe294effd152ec33f95d66fdc648904c657eaf6fb0c322f5881bdc1f16305c3ef90c3df597a0e75222b82d79f5d6dfd913b2f9620092f418a3e67c48823b85e96b1fe85d306f3653a799811a1ed3dc612461383a6c1eeac737dbd2c6c20fbb56567bf544d199a474bdc38621c8b9bc7920\n\n# tcId = 33\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = a2ada8ff1c1821fadf49dfc156293dd59ac8f51367633f73d2200bbb65bd960f7b888d1a843920044ce98528773f3d3df57de92f129c03e1f6d425d39ac83978c7c8ed7cdcc8d47a778350f99f8fde4f6028d5ea77d46091f98f72279c59fb39ff8f73b35ab1c6748970d325c65ff49fdf833e8c2f40621bb770f2dcbdfc34fb22422f0105f5f582c90be73e664c215cc6d89419a8909f0d13f6535182aa567d4e16a2f7ce1e562a6cda4582304a5cef821c538de46c68509f3936166c109da8ef13f2000117644024ee1ec10e8ee4056879c07a6604956e1d03828dae5ae0eb60c322dbc6ff183a57b258c06a2b837021d4df94baab66be636b505a5a5b2697\n\n# tcId = 34\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 743209d44a3c907ca08c0b236b9cbabcaf210bf522de862005c977bf7099cb7a38eb9fb15b765a044703c9410082b6a35a7866821f33bc2e2a58ca8bde08b78ff6b3c53e771f8d7fb43503d8060a884ff6012101278564edd6d64fabb6add5f4d4c62707c2ffc45f904acb43ca2ab5609a23daf9cdc58aaaa638f6325a54a5e272b253bd57246d0935bcd19c7aa31f878c474c8298ec567b6a7e165c2e7eedcc80748953c90d20699ab8303062580d4693c058ac761678df6c875bd91d465430afc93cf0bce027ed00a35842ad560d79bb640cf3ea55d8ade362c258fa707397663fec6787d44ec075d857a6fc55c50f8df898da77252d8903220641005177e5\n\n# tcId = 35\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 098464aad869fbb37c36f56d750ba97ba6bbcf96c9e25d92fbd5778fcf214f6a24d1fa276a14b5945320eeb37dc9ce4cfdae21ba57185246052ae26718b549a59a81cf26387356b3d3fe39a45cf303741587e664244233fa2263cfc6f209f796112d61ca5e9f16e362765b0651e8e197920137a3842483772428b1088e7c1a7aec2152b62688c5655410ebc4907680753079706931359e893ac76ebce92a3572c7eb32c58b386d7ab0f3af24acc5047258b5b7c0db4c1ea4a4b64203d65aaf6c879ed89bf046ce5ffb1c647e95630ca485acc9fcd6beb6a5d17bd54fb518cbfa226d9738beb55325f1883ceebed860d54f5db3f1670ca910762d877f78af80d7\n\n# tcId = 36\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 498209f59a0679a1f926eccf3056da2cba553d7ab3064e7c41ad1d739f038249f02f5ad12ee246073d101bc3cdb563e8b6be61562056422b7e6c16ad53deb12af5de744197753a35859833f41bb59c6597f3980132b7478fd0b95fd27dfad64a20fd5c25312bbd41a85286cd2a83c8df5efa0779158d01b0747ff165b055eb2880ea27095700a295593196d8c5922cf6aa9d7e29b5056db5ded5eb20aeb31b8942e26b15a5188a4934cd7e39cfe379a197f49a204343a493452deebca436ee614f4daf989e355544489f7e69ffa8ccc6a1e81cf0ab33c3e6d7591091485a6a31bda3b33946490057b9a3003d3fd9daf7c4778b43fd46144d945d815f12628ff4\n\n# tcId = 37\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 4da37914ee4ecf0c0973cc89f9476e2d872eeb2fdb3eddf6fcbcad9b21b8eeff2dde26be6a26d5d5aae6300b4caf4f77f2ab7907af2434026c3369d76268c88b1a4c555c9d54723b17ac48ca1118d94e147a4c63c2c4baefd244235cde4f9c254bce8c8c21b45b7a2fd9d5971b21abad1bef74b9d5583d352ef67483ee611ff3f97198c023cfc56c667c81ef03bda4729b2eff85c24e75aafdaaa4c0f47419d8a63fb2ff72c074ffe985ec7f88bb0e93cfd375c656137722fc6aa45069771c6c66d4b109a5dfd8500331d8d840edf9a5c8024b2520daa56641ead240033b0aa300ff3f951009ac46a97ab9311f8af9467b8ecbde36c9744e44168314f092529d\n\n# tcId = 38\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 1aff9b9ad34e142421069661c71e35b98108a8f976191b45a97cf12e8ae8ebccd64c0fc6a795f4ed798fa4a2f79746c57a86f894110c1a5402dd72577c2bd9817a9e7a1b0b7e389527428140d53f4918b305e154f7c143011dc27ddb874c52b57758a3f4ee4395108897f0cf7b4fd7136ebf991dd9758bd2cb85cdc6f9d96a40f8e6a0c12970c18325d5742b80ae499da45655f972f33a80373a93572fe302dca03cf7e004690618c5b725e3b9be6e05dfd0ab8f28b8b994ea202875268837d3876681a63e88a410a0bf4a4c41f7336be2799c6e62514a5ee0422cb6d5c57c2e45e9f96d667f8629e0987421f01a9391a3334d", @@ -4148,9 +4786,9 @@ static const char *kData166[] = { "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d4\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = a2b451a07d0aa5f96e455671513550514a8a5b462ebef717094fa1fee82224e637f9746d3f7cafd31878d80325b6ef5a1700f65903b469429e89d6eac8845097b5ab393189db92512ed8a7711a1253facd20f79c15e8247f3d3e42e46e48c98e254a2fe9765313a03eff8f17e1a029397a1fa26a8dce26f490ed81299615d9814c22da610428e09c7d9658594266f5c021d0fceca08d945a12be82de4d1ece6b4c03145b5d3495d4ed5411eb878daf05fd7afc3e09ada0f1126422f590975a1969816f48698bcbba1b4d9cae79d460d8f9f85e7975005d9bc22c4e5ac0f7c1a45d12569a62807d3b9a02e5a530e773066f453d1f5b4c2e9cf7820283f742b9d6\n\n# tcId = 235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 5e91b5dcbf02d6f19621d41a83dc8f15ea83c0edb83765ef029b0acac2e1ec8918b1d2afe1fadf11c48d27594cb9c01fed79d90e5d5a8085c438450111aa7d9fa39c2345b14fc3c2cb34128f86db5eb00bdf8dfe38d61f29a41fe31342e7aaefcb4b122eb5d63c2f5c263c8df8450e9428ffef974d535818d51dc03a7d60c8b2d16c999ae46d73ab40515fe601d9b89b1d09c6d60cd51639a97c1d211e097609ba5e8c319c6fbd21b34a634ec8fb8971c5aae21c70b847a4539cc10dc314ddd8a9629e8a0e51c66c0cb61fd1f7228c01c6769190abe9bac9a3897800050014358594e0fb20dbb458b12aa1346826cc9f7e9c5352b073d62853dafe77c848cb1f\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 57e8cc1dc00c07383d89a79b5c8e4f5bde2a2ba55a3c7201b3291c4d805b1b2eb36f8f326b542342da180abe508669bb6cc2dd54e327bc70c1e317ba93a0fd21e7fce22a0c597c7420d1d5602ac43d9348ba3eba561f250e301ab955b0dc33e4abde32946b9b3e86c8bf07a44646ca595960bb988fef04b2824967e9da8b0264f1da0659373935313a574b5380f0b54ce1bc0dde423bd3a54f6ae5fafa772a55c1c44eb6edffecf13e6e5e1edaf87a79e338577304141fbc44f0e9eeb286f553f879addd6e12e436fa3af51ad53a72f2679f0ed102d504ee08706fe111eaee49d880d1a0b91924b3b79968ed0f9bff446dac199ee89b158c074927d27b864498\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 68caf07e71ee654ffabf07d342fc4059deb4f7e5970746c423b1e8f668d5332275cc35eb61270aebd27855b1e80d59def47fe8882867fd33c2308c91976baa0b1df952caa78db4828ab81e79949bf145cbdfd1c4987ed036f81e8442081016f20fa4b587574884ca6f6045959ce3501ae7c02b1902ec1d241ef28dee356c0d30d28a950f1fbc683ee7d9aad26b048c13426fe3975d5638afeb5b9c1a99d162d3a5810e8b074d7a2eae2be52b577151f76e1f734b0a956ef4f22be64dc20a81ad1316e4f79dff5fc41fc08a20bc612283a88415d41595bfea66d59de7ac12e230f72244ad9905aef0ead3fa41ed70bf4218863d5f041292f2d14ce0a7271c6d36\n\n[e = 03]\n[keyAsn = 30820108028201010090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d0030820108028201010090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1020103]\n[keysize = 2048]\n[n = 0090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1]\n[sha = SHA-256]\n\n# tcId = 239\n# short signature\nmsg = 33363730\nresult = acceptable\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000989e7ff72e67e680bd21d5f966e4ad8a48c3592dbacc4a2f035b4ef4d17a2f25f8a9fef7e78eb99d76d68629ed02d67c43c4b7ec8c3badc32e3d0a524c326537739b0fde156723b27c23ae2b09895e470c64d700f5c\nflags = SmallPublicKey\n\n[e = 03]\n[keyAsn = 30820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d0030820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keysize = 2048]\n[n = 0092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c26712", "89bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d]\n[sha = SHA-256]\n\n# tcId = 240\n# signature is close to n\nmsg = 32353934\nresult = acceptable\nsig = 92bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240b8bf4bb1a6d0616fd5be2f081dc9ef741a9a4ae7274418b791432de470c4556463108388e8e8ed5dcebf3558e4650c2ac97c86fa682176f09b5dd8cfbf15d19c3fe4f961f4607c12cb3dfad9b6a0e59c92faa1fc8622\nflags = SmallPublicKey\n\n", }; -static const size_t kLen167 = 152041; +static const size_t kLen221 = 152041; -static const char *kData167[] = { +static const char *kData221[] = { "# Imported from Wycheproof's rsa_signature_2048_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8rc16\n\n[e = 010001]\n[keyAsn = 3082010a0282010100cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f0203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f0203010001]\n[keysize = 2048]\n[n = 00cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f]\n[sha = SHA-384]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = c5b6f5fd8ea320880e9e27b0026b1d63bcd1152c72855853294b7683a759dee042be8bb0c350b0c31aea76e1ba2c6d79920c3e21b6e97b6cf46fabf92a701a7555540dd7c325e7c657fd9a079bc5a58923d2ccaef51014acd6fc6e5296960362a94688f2cb2675d5062c5101c3875399b95143511e6ea156ebbdd32c9ef8b061dc66e2c912bf2ae37e3ddcfd5f32a72412db8ba7a1ce3b44ea4c6e2a858b3f3cb198cf41914e4970b03edb1bf81f8abea6371b469d2e80883d7760c0707dac808fb55e588b285153b8ee5c32ffe90197991a567499d5ed62a6b810581901cf8abf086ddf84c10b03ad6845c977ec72d02028308cbd19daea2668865f00a23ab5\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 0e8742af2a1d82e99038a99a09bc182e21317b690004fcf8fac5a4b39c6c4c6f32ee0395a42b8aee31a7af7cc0b0205087b4cbe18e791c1d5454faa5dc220d3b21e44822d39beefa5e90654fae46205631c4691d3e78221f48edc14e342ad42dbeccfede07420b9352af9e0a009c49cac2b4564732d94495457dcbd2f67fb60fd77080631cf38b784a3373b66cc2d1ae971a7422562c2df5f2476983263f6559a8fed69c2c76806f8553b5f1f2239677f1a4a3f5f55a00f8391174fabd2852503c9dc130ba219d145709a4f045bf62b2278d1c9c5c2e7a81f47769b2a11b18bb8648a32eb984ff7aeed9c0ee1023886e6a402812ae6552b03419b4da25cbf3bb\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 943aaab06755ab012b4e062210ac3e2c1a455ca30f1c65beee0f7d54384e4e0d4e390208332690fef5ba0cfceffbfe28e6b05a1ecd8bca3a50f9542f17c39d28195a50203c7885195c7e84da26436bc9fe7fa98a5070e0a1b6f51d8ac7d2734fdb5e0b32da0df6c6c98311bc4d458b4e970412c67732effe67e083123bfc69ed164090be3d41a37bde52119da16a4fc7fba5d8d3ab905bca7b1bccf4699a8abea19d0ba0659fb6c94b4ec6d06fd086958f443a74a783b7440f6060f01cb9dee89f32c2f6fee61e3d61548fb6b3a0f6b649cd8bd5d5a5bbc016f4c737889c79d45c41b5406129066e259dfa06fa2ec05cf9330dec66ed4cf89b80b0f5dcd22c4f\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 682272b36ee1a6c7d4d73f0f3f153d8e84e2fa4ac812581fdda214a7b45d6ff7b7b3db0c89da96ce2e651fcfe25596761982799289b9fd2d69cf122e08404c9db0bdf6f8240b1545e76302a5a401ad56522e0a6158157dc1f9445f8cafc161b25423d35671d9ef714c5d33f7fc155424ab2ac34e0cc93bf2ce385721dacdc6251c7e3a5618bdffc8ef3f278477083a96de83303b9d286e64d8297ef0948b996616d34036bdee5538ca0c06fa08c72f03739fbc578814b402671f5d625dc9050d61b389d1f0a32011ac0dbb53b9c2980d315bc16e2272206a1a955ee870df725e78a7c6e9f793f5428af92c670df8e3bb0d567699714b04fede399f49fe19d0e7\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = c86aa0513ca2e6bb14892ae983212cb21cfaf702eafa5adcf17dfcb7ff53c1fc87d65001c639a20167ec97448463ada9b20d40d3e13db23d8048e38e5c05aa42ecb10d1683e3f64d42837274e1e021b3523cf763d32ee69f92180a9e3e6c6ff891b4c0f9f30a7840fe2524bdc0e82b0e19acd041554f4050f6d917a4677155c6e7841639cf86b8439a4a1edcb24ea272775dd9287291cbdaa79e97ecdbd97522e250db7c8d32658891a0dfe7fd079ca5a5284097ad505c83bbcfa82c0ba6cd91abfa0e21178981cd5c635433cffce413a3e03c7afcfc2fca37c7bd7a5287c13813afe3aa5d051d386e4250ef1617c0a58a24caa33e5855c32b457b1436d11d94\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 801ec289191d6f6e2ed3d7ba7d8cd78db3add3022c8387f592080705eaec1dca415a04e09d55aa6a8c90f11730e9eace7f0ef892f44377085fa8e72236b160382fb3bca71b71d775e4acd75c0ac133645c64517909530e0175a8f06236839de7f7704f39afdc4720a2d94c258188cf9f0794c279c777e5ef604a31412262cf871e3cff8a0fd7efec06eb1db05b50910733dc8d8783a24c07871908e711b27d0d1ebde4e418ce1216a5bc1c8c85d82fdd2b8bb9f0b047e8b38fcfb80771b019d154a510f2231c6c5becbff35f2c5b1f1a5d5280d0d8b0309db5294fd99b1afe576bbb85e980c4e9ea49327343084a6c29743d3e48316df0623776e98acbc84382\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 6ec812ff1115eb60ad2cc1f641479aca46c41da5d8f7b9e59b2dbdb8956f5c3ada3fe162c54bd5835f5e043ed3906a10a982e177f5f68c94ba367e4541b75117dbe18b7acabce6bf7bad0bddc4a1f98382272a655e0222ce4a87dac7f6a2099ad9996603479cf8454102e7ff703d11623cd59e3eb2df8a303732851a119d6c75f7503acc10c57f2cc418863e1b2a5305688c03fc9971334ba06541cb8b3cd192bbebfd5e9252517b17d2b8a3ddfa1533784d6f672e14737c4b6bfc38162ecfee2e97f0a29c98bc6709c922f42ed959bc3cf43764627a9beb32e53d2b35da63942006787476ce89abb7a82ee02e6c9c80ab777af86c1a99c65423ed75fe82acb1\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 127eca0852f26d216ffd2779159e3e3b742a830e3d4f29e9aebf4d8bbd45eda195002aac8ae5d10cebbf849b026caa37e988a7d5c6e3c0bf4f6da974b31a8139a85cbe62e0aed71b9c50a5e3bbfee50cc465d9a5173a33cc2952893e89815b3d68a2269c78dd91d3b8a9d9fb74bed451481267b797b28460358adaa90b82304a6182a5d79e113808adf31100d0bd943608a3a58c2561468aa379127cf8891ba61c2de46e66a9e4d86da3c007cebbc2ca0b8bb66f29b2205a3a45ca7303c0db32efc1e0e254e0735953a91f4927901cd78ab0ed2d047c822dafd5bdaf34cbbcc227e7711267785b68c2f9ba47ba108ff7633d6de61d453acf48fad092b28cb70e\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3c1d887865eccd6eb7d794756f93819c8126fb018d483b6cea67e10364d2455505e228c95106d493538c60d1203ca317aef7926e09e088a39e198915fcaaf316346db4ce62908464838efb7bca14041ce4477fd55422b94396dd79883f9024d46b8f9838ca7b5851e2d935329365c917ca03e1c44443a9602ae1cfb95ef89d9c7315f7e0b287a39d8133243c75ec0303339d88e937504b118ecedef756f746c6a8b244d86ad9e02d02b24ee5e616455deea86beb334af9e294289cee20a7a135448739dcd48400da80f15e060c312d4b981d63dba827ddb2751a89bc421ca600dbd5cc8915a1da43baa34d09e668d2cf5847cd55b705d5e7fb7d355c42c88d4a\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 47eb6558bc35fae214cf871eb167e0760a9b51309c805d7439bebca18ba163972f2fdecf5d1593933341553971b3f529e82850f519cd60597dad8a5920e567263995f7e7f348414920442fd9e4b0ec3b95fab248261913e773b05206e832ce35e5035d6f023a3d768e85b9588d9c5ac4c7beeb56ee14cea7744daa600064e9be391999bebc1786d3d2fd0a7d4ab0bb47ffcb0f3802503a0b3124797866c5d9c446025e21622f4d1cedfce4ad930aceff37e2e1f95dbeb1d4f162e542d1e6e47486766b8d6e0db3e336b8eba57a22f4e44a646ed6ff8bef24394c23059c8c6bd9ccc28a355d87d9a39270ca88834a8f0baa50af19a44aae9d5fe3961e25a9a070\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 4b09bdf2e03a21c695d457aaff214b4736034dca0fb9cf76763d623d16f49f2735fe831f9990f9b84171ebc39f5d533130a9b8b04adf332078b48a7aef60355683bafff862da9e30852e1e3a323bc09838679b687a6615df4b9a71dce533aec693345c1ceefdba7246eeb49b64848359b060fd08be04d4446241573d3445abd6bfdea24d490a14690e50920948998cfff43ba080dc20691841a739f6f134285eeb6c87f4e1b67", "0f2556b83b99ff76d873033fcc3953cdc9857a7352d3766217d987b03fa8fe6f90a4b7cf8bd55ab44d800a0c245ab25e91b54c0dcde0b3adf40e3f2bc8776f501fd419713a5445ddc0cd0e9c414ff30f8987071857050a12837\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 756305930024f3b1e17696ca04fdf72445291c2c4737277f9cbbd6c8e2036c3705e1630d47a6a4b5fe2cb1fd071303e4c70ec49378530cd811ee2dfb5f1da6aa66cb57d62e9a96d88c6628e23e1daf8ce536da9acca8d1068e1e430e43b469a55e311fe794767131f53e250ea99e5eb6a5f09e37a0d886ec92e0dd635ae4eb1bdecfc9a4b45b8fcc16245fbc5fee4e876944cf663a56bcc68f3e6cb79d96571eec6057922dd0841aaa126c6db7daf00c373ffe23d8dc7f14c2a294ff0704e5d7636c9108b05ebee13574b63362b547e4173ad37328241fa5cebb7ddb6a99dc52a4be44d3f2e0cbb823f02352fbbe31a3646e0b3988ef0f77445f4e5cea12434e\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 8f9c83a3a017383a5cab106589fe076c15802729be880120b956dd69d36b822022f58f6486cbc9009fceadb83b92883b281e3bd998115e522a1a3199b5773845aeb54331bed863baca87d6de45f387629bf6f328e8f3b0698fe2e96e4faa95d61d7afe105c15f6c3d11ab561bdefdeca453f87e75945ab1746fcc559fedad0be2a494b7b9b9c0089e131f86eb6a0a422da225390ada5559bc64d1990f94ffbe77d00aa19cf1a1676a2362596b32187229180e5e8944173606f54a627ae4457e748c481c3cbfa7416f381157684eabf87490ea96a8a032b1c0c316f99eb18b9c30192094fc8606bb86bf5445c10fc5e9025737fd52b779a008ae60e504b92c3c2\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3adba4b8e5c7ab81ff38544b299ee14cdbdc7d44aa4592fd32295a0e20ebf23d20cde4d26e752e3fc02a67bbd3b7fe927d2388d27f8d9d399ebdbceca97df4b5f1a4d5cc27fa5af84a8e39a32511f36707e8b23b6e38cec3526a15e557719aba13237620222b205992907f1e0b7a52cefcdd63d7f9d951ba528e707d179be671728708c1730096743494fb0bfe319fea4b8f02595c70dd831690c3e692c7b4f18f77e20e063d9d634b966cf14f4d110af8d7db642ad1f952c498d78f27838b84bfe0a9f89fea32cc243ac65e0cef7be743330a19c51a13a747e81d341d17a9204d167cb4006210cd8c7d6cb43d347cf80351041f98efe1379cfba9654d4a3e54\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = bdca4de4dd3bba08516ed45291cac24222f7978f0cad43c92cc3e11b3812ec5ccc196a59af3eea5217d66527776f630cc648d01803767bf1d97e341d6e89f2a4c0bb4ddf4bbec6e68b0e608119d3b41a2fd41da75e157bc3d7f76fbd29d9a6e60e1c383995dedecca3e5095d20978e7be11789137f940ddc8d3bf06eaa2013334530ed945cc3970e83d66f0f181e18c5bbe2440e0f04f472d1b259ad7af78ce7d670292a2894591d5055d5a0339e3321471f48043d92990fb6c3fbe41a3fe92597202e0ec85d0ecf6bfd88db54711cddee648540dc7f2cf1bfa9e0d96773c6c03884285d28fcba88e93e9238bbea7d07dcd36d251e39345c28bddfe365e04f12\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 648eed9f390fe7fc14589904bd72247c3a81dfbb0e84ca13796fbf4d248dd45763b2dbc687ae99a8594101260fd0b3a398ff2b6ec9bbd82099b5b44201a5bbbe8421a686bab7423663d45cea77321e16a155612af9443b94c7c287f73c6c5d3e0139823c081b91f4302da9a75f0e79633fca4175c2fe9f6d4657467ba38eefa1700b94f4f7882892e60954fada4483c99ae0b05d0ba46f774832a7e9fc8b35c81ef4a7fa073ad62fa2ea25143367c4d4df39090d34b40d48ec28f58073339b8677455bec559fc011320a53303c7484bdb3f7f2858262a6420412396f68c3a9f826d5e889d2c8599acbfa6705a7d22f1aef07560932e742a831a23f53d93d20bc\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 28a0905a6461f258c617cbd3cfa963ab3b137fc270296a7b5541c0e01aaa856a348383617dc987011ea42b58e19c49268b1f527ca54acce5e928ff5f122d0366f2e6f656765a73aa7ded1f2d0053015fc6e2d68155c6cd8819e7a6e51c485fc0a620f1c2c2973b21ad463603dee7954fb8fe83ad4ec7d4d860309d498e8d8c3f429df3defa7ec5ded39fee1d5a9aa75ae8ec9dd4b66e52f711e2bed712c43b5fd06e0fdbfbcfac5878d989102dae62307dabd0214f184fe768583e06311d8e8b30738703e11d52919fc72625e418749043df757d01b405cbb01eb2458c09d21b2c472015aec4fba7f88146cd72a2d0a3d80ae1adcb5c29416f538ead8249fb87\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 0167ceab6b14960f1160f13ecbdc8efa965049c1db8acfc8b487b363b7ae7a95b34c51bb54c69ff8a08f7b98fcf63eb200d2dceb5834487b843e9312e75940317d4b507501e46cb23000a12f7042548b8934315b247d4cb443485b39f208487110cf08a1f95a90869c63cc8c52fda64f86a37cd9c562be1e8a813906da82a5dfd72c96c8770b08959d5a7ce72bed149c2d74db3f57c3d67c1e2fc31cd2f2eba59348bca4111176ae050d8ba565a71ccc131d92f9ebe95a32a4f37512bc43edc02a9d65d45a59ae431163a5e4e2b237c0023ebf6aca27af938d3fe855543cf61c5e17e0bfff32c2da92b54a3ab8b196479a66a2962fba50cbb8365879b8618662\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 4b0a379baccf3147b547ffbb3c6023332620a2722e373b8261abbfa31165224fc85c1e41fc495e197f921a8db2d51282325bda21acd2b2fae56b4dd48da9dfe85b7c2f83e75972c22275f8af6c2c8edc544983cf5a783e74793978cb9717c39271613937505814f1862c4dbe2fb7ec577e4bd41e3fa6740319f15042eb4655aacf1b4a45473090910c179fa942e1a0876162f162f44b17bf554e65b291e7ef1eecc0377004c871f74628e2c069ef85d942da5cbe319a2489a5f6d16c421765451615c987f6d84acbd919013ded88bdf1408ed2c0ac1fd701fcc1df6da43a6a802368c11965c62aaa798efcdb699dc715e5f10bee9355d14afb732f270559fab5\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 6dbe87fa8707ec43fb4a4c51f6ca422ddd0051726dac648e1985b5146f54cffc78a2b0335b5d621f3a4f3eb5add994e1e68a4223e9e79616eb06eb421183729f4fedeab5fa291aaab3e83af7fa021b56aa02384752bfdb73ebcd540953695127d8adad2914426f5e9ac30ab4f5feb36e4ec9d7c7cf0a9f50c33979cdca2f7952ac8fccc4180c8beda3772250d6c5a5ef2ca99b9eeeb90a81e2346b465d24a8a8c47dad4a67d4e6a28a46a3ffe432af8c7ffc85c1eaaaa26f1ebf495474d96ec04b5fcdf09a25d8cdf45d8f348805b9558abe525f2c95d3cd97900e62aca25b744b779b14195f53d555808d3c15c0c3aabfdd50801356310deb29346a445d5a93\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 49b6dde9c7ccceaf49528a6f74c41d83fc3473ada4896eb0bc239c62efca50b33bea31e500b48ebabab16a35182651c38f72803654e1440e30215b0c54738772dad70b8883ebe60680103fb328d1a990547269cc470e9b06e208268220ab46c39411b7f2b5d3eb20ad723978d13d0970ea57a96237242e9892381c02674f349b0211b03bef1ab568abdb1fa28cd913fbda24d94af8ef79efb7d76bede1b43db2f45b9a522368cb9027a6d1f2c40581647b85a99334f05400e95e2ad4a414e032a560dd2321387f3f2deca9d3a4a34d40be2dad57650ae12390f28d2e4cb0ee8bad7ddcb9d7f8850c75c99c6cc4e154d4c8b741e972cedb373b9ca64eadc0e5db\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = befa74da01ad7d06b1464c2684576dffc25bdeaaa766683710934a8ac4aa2282320fcecb5f512e94dfc84289b2da3fc73afbe9239540f1066bec52bc8baafaa5830e85a5c8f31cf89a8e548604169d7e43d94fafb67b3d031b994af3f3741fb0aa02db1aa12e674e1e7fd0662fe06c8ee641029bf9fea3e997c15a7308fd65661a10be4ee1c8a4510b27794a3f5870bc83c6db63cefd008ccdf4206ad7ab6686c8047a52cf913adfe5d17b4d3b38a7e1e4f21bab174f2afa9268dfec1e6c9a611bba07273b4f65a33db419b18304f3ca920a4b1c655a76b5a5eb920b9123a1160b4855ce807a62c8bea9a9b8c38f592284afcfbb550d79ef085f1fc9edfacca1\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 814446f1d99803bae8290074bfa3b562eeb7fc2bdb5ae95524a8f31694e166163f89d2a22d37636b320867abb881467f0426fe948a774e349b72564a3215e117e7c14e54a7da4eaf67363723afa19886ba47998389f8069b3a752a2cb9e7e688ca273b260312562ffc124fb6529906dd397028762ca34a8313c99b648c25822191ca6ee3e956d98ab813ded5bc298ea65a9bf949f0a229fbe0000eadd2429ea40ff66238201a2f54e93b560e36e8a207a7f4624c782359437e5139d8ccd2a366a9d948780148daec600de8a0c516f0f93303067d12dcd8d5ba0b484d7c87cae1e63e4868c0c829cb4efa8650fba081c649014b3ada38dcc1c1471f93def8f7b4\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = c68048e66a376c5ac3c6a5eca4f1a73fef1cc0a1db91fa078d5334b80db31f339dd74ea3e975893c4dc26290bce8053a928321280ae60ffed3437072a562dd30442e5d3a5b046d1f4f3bce820604999b087d3d02130ec4bcf6cdc19df28ca9c61d44b9bf11b8d7d48b6d535dcdb52316da25dab87f747082a83118d7d1cb515641177f2453e2391345b893367f6bd8063a24d78d041e9eafd6543c9d4acc3f4e7ccd45bdada5b7b046a86b1bb0954397afd12650dc1d6bde119d7bc681c3c6cb1122cd2c523bf27f017faaaa1f5aee8f010f4c562f81d67a04e817d4fdd32bc032b8978864a9a6cde55958c0c6863690f2f3507aa53fcf7e3f932e460b09668b\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = bb7545df9dd8b0c768d7989248106c242e0e441dc1de681b22fd50b576a3afe9c6c19d52c77976343a529cd6bd95783a7c24", "4ff0d3fc701eb18297b52a3c0a6f7fdc3f991c1c2d47a413263ff67f83e042bc98991620ee16f08b9f9fbe47ce37a90062848a0d0ad96a54d4f8077e41d03953a10fbbe15a8366a88fc12f82f2cc1ed63fb5c295c4b0b3f7c87e95a2b76d649fe839979b1352fea3b0dc112d46c7fa72623932f1d3197b0da93d0b87f40a8ff1575dbf53dcc69c800d2f616cc7b80e942c6b3501858a6ebca6972fa3d4f3c16bbc165ac91f61b679fa33f2b2f909b63fa88bca231297145968bbf1c74814fd691249705140dd89dd32a49116aa9d\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = c5514a3811c53e0f8372a945ef0e3641acbb60f6321f67d9dbddb04e1287f1b42d97eaaeb7957e22de05abcd9f85d829b43ac766c9907271a1157c811d429d5c7c8cc36d19ac2dd24a036a16be2b6368da44cdc80bf21ffac73c0224b6f176218f70f0cb70e864224df7aea9724b61943dac5a0d0def579c342ff1fe0810b6edde9be8f9bf3d36cd75edad327d60c5dcdaa0f410ad7e74760bf56b93e0d5b9caac25ba319aefc510d26d44e57cd8e89a7355eb3c6d5ded4be863ab4c60e6c754fbcbd086fcb3ec64a1d4f40d3c1d00b65e93f2d09ed45eaa295a5c8b09268aa292096a5c41b86618e493d2f683682b10b25ac9032448e9e0b76bcb6f6664042c\n\n# tcId = 27\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 6acd858e30ee15fc5c1e8d73f0ef784690e047b0152938993e3e0db02c61f04f21ecbb7cd154b98aaccece5d4948e26260e0b19f759a5107cd4c365bb2ff6e5be93274ff6fafa1df4f26ca73d995f5604e847d635de7d6631e23397d95246310d884c7082893baacb46b6426f08884b0eb4b0bddcd01ee97b8182c55ab80b67f73ee0507206a5563f79167e9045a7ba9a8c9d6a1ebb85f53922d4a5514f4bb13a5f69154a2db4287e8aa95612fd7cb7addefc7516609c1b93844f254d630a2924cbd7b7ce0b623812fe4edc7edacaaa449ea949aefebb2e4b924b5ab893d5bcca76fd20dcfbdd04ebc6bdbb1d7407f710bcb2f23c7d50a4fd49eb6acc7d4ab97\n\n# tcId = 28\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 4df3f6eb5fb1049fd74877577a1ef69216df191af5858a661ff8edf68c8ffb5554d2c0e3b7adbc7d10da656c1c788e381d43e9eba5b0a84a92431df56eb81d7b19fe0e87404d16608f387e4b961dc13d336fab669195f357291e1287f9bff838f4b2c79b75536e6af0b5adbd750135ec166377c6c8ef6a9f80c575b1ae95da834a2d129313c096faafb641b46bd093cd1464c20821f4ced6b4dbf5922c44297fab04dcc286b68ab98bdf03de215c4b8ee1b46ea93d8f910e1c8976f3f040972f62901fa1fb24c59bebe201d3e5ac0615da8106c6b28310382fcb6c6acac7ca3255eb3d529863d939cd876d88741944ef06fd8ff9939184bc417200d361d1f1ee\n\n# tcId = 29\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 55e7afb895f743e418302ce73e8fd49aadbd0a4c27a9469406e0a801753d5a4cb96fffa47ce3af3a3f2dc0d816e6ec61a764455f2427cfcefbfb9452ed8401671607c8cea3bf105fda04abfbba07ebcccd141306c129b36f9014b4970f4e8ad6cf3f7b66c21ba1b56ec96ffc6b6500f8f38c00b7c4aaa0a0515272fdd0fffb43a4c4e8eecff7922b0891457df27029eba35c86191cd7d9775cc7223354d89118ce1b92490558b2f3a151fa1b8f9371db8f8fa0f156134f5d78d7897849d60414a7d0565535f271fc9172ed6c3eef2ff62e638da46ed4f507ae3c63a6d308a20ecad814232e39eeb7bdab898b18e37b57c10b19905c0d3d01fd8e7c390be1b218\n\n# tcId = 30\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 89c7b4912157be3be42558074cf23b8693d38dca6205289c9fd347369dd92534d2d2ec8e9d6fdb0a2ccb7e398c90deb5566763e4802e747e9dc593237d5a5e1d52bc3c43d89ac484445e3798a16a00bfd498f42d88a4110cb7e4745c5f1e6359ee8b6e81b42e85dea2e00e80f1c17dba13d586c6f6f9d3e24f5523bf9a0f21d82f150a227a718123c5f7c934c2040628e2660c6392fb4db3f7ce09e1c403d479e4858adaa6d798c34c4af771994129386594f0b9aa687706bd463a92d47ece2d4dea43192f8971ed7786ca2b6dbda7c449c2c2d428178d8de5c3a10bbc7533296ddf9fcae3019e85a22d9fe9fa23942912187bdb11365bd37114fafc9e88d4e1\n\n# tcId = 31\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 2f64360a55c3d64c3a5391d6c3ded718786ee654c97b6910f4741315fd7d9ab021999638b88b4751736a13faefa6a18339371e2f892f68913dbd426415cd34f499b755b10376fe11896694f1ed703d840a5e6faae1e6f75c7d6dbbfcd3dfd8e818499ad7d03878f8148d85e325e7d2aadd6f9ca675d7f0b8813112e83d3235bf5f9a33b14bccc774aef67517529593439397413e322d02ab7259b98ae549fee758b02adb6116e563d2fc8347dc5b5bb07d573d51024de583baaf8e982b3a8c742f03d7d739ae804e8de6198c75a556318fb372e2d1e6187bece98a5f39640ad28fe014e823a380c83fef85cee7bd788941bd04284d32961bf3582c4c3ae488cb\n\n# tcId = 32\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 325cb004062247e5f293ceede0066fdaa89f37f2b73464a14fdddc045f5395e7ab3710a9ad3eab03e9c2fb15818b551b1d8755f454dfb5fb6ddac75dad79563d9824a213ffd5865bcdb9e82a1bde2b94756a7877b91be30d58d48700dcdab15210fb17613bb9dc4f7cd95e1b33f4de328b4d166f78c992121e7e409acc1fc893771265ce9b01b5e21aba04278bab10be21dddf8a9375bf4ea0dd4a608a186f0889b9c0d132b022de4e903786789d0a5a960edd05b63ac4c08ffe57f6c5afab772bbc7e77f82ecb119022f96a6f42c5a5b958b88d0d6b17d3314adb050bf863a88782aa78a8efc50434c21e1077ccdca9b9c7676369bb8972f290bd5a7d85a635\n\n# tcId = 33\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 4b043dfcb768599364cd876ee5f6456b8a270dcafa679ae2199793578b26c42b30ef14fd8cc4ab045dabb55b938bb8c8af337386de8ea009a3a19ff74b6ab8ff038d6685b17e7dc5089ebd1c8565f48dc699770b48a6ab5d9353e26472b3a57dc74634435bb7b04681bb69dd3e7396adb569d6cc8ad07aae13387a17ff862b40af23be43bd74c9fa24f07d3c0afa47a063412eaa2016647b84a95b67f0d18efe75c2c9be7240d748c2bea9f25921233010079028e608a85362cccf7fe1bef5a71a5142f1dbc72224f5d983d7fb3b0d1a6303f017d9ab77b5d6ec4281a5df521d3528c6caf9508d65f07a6676d8d4cc9fc796efc6c5dc2aef6ff516ae55212671\n\n# tcId = 34\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 2f7659bd4b043c5e74d9e3a6bb3841351335881091ccc4d0e2de1efa168ba11ec04ccc71a0cdbf84d88a54a9b5e8e5e0ddac7fdc7c221e87bdf70969f98857ff91bd6d4c9f8afe28f5394660c959ebc8e4a09ec3e0d9ee0d6c9831dc0f31807bb8ebac2c9e74fbbd38d0dcdcdddca714b771aa73abf3d2c3174553ae3b30597604e4b33f8a6adcbc42c4e49e04a6bb0e6d5dd36b519d5de172c5513f8317c16cf39c89ceeb5cb698ff18cb8e149b8350815cd8c619aaff2ae5302cc683863e3c5e5588607237fac82a01c028e572fa77b30e60bb5a2874715065a2596af49cbad2926bdef2c81b5d031a46113a178a92f4d69c97f9ef311ecc7a2f058ec7be42\n\n# tcId = 35\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 241cebed86cc3a251f62e6dac6a4cdc7ade20ed6f879942e18185c85729f6874d4b0c0d8eabaaf1ba722891d35ebabf4b549278d14815db39f9e3c3dc7856ad29f60292318c808675079e2ec94984bdf0966a33590f47ed05058fdb91b6fe11456e592c9df76e4ff56df480a83fd2890b088e14dd59e7d6bd0fa1f009affdbc07161f091947b9b9b8342684a0bcc746d853cc52164740f08c364c2855455b82aaccbb80488143f59614be4b6a1c4f70cd1e006c775498df75cb0d700b8fdf164d0cf97e860bc8e153c85fdb6f5834b79efdd0902e02ddbde4b515afa360aa25632c19fe7349247bb528e617d34333120014eca9b549fcb1b541d3ef6fb5e1010\n\n# tcId = 36\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 8e694aaee29d01d26ca0fecbb8cb2bb49cc8ac8e1a01e327ca9dad1ed741032dad845602b2752f8637ca9152d36f120e81f37b6f4d6e5b5468158be2ca3acd469e3f532d9731eb6e7247f97d28366a652d747b21b732c875fe22867adeb88e42729eac1077fe7e6255cd643fd33050ed087b01e07df5efa7c182d266ae8b33a667fe88e5dc95e1751787de699be68857470cd4b0ab989ba7483f9ae375c693aca41ffa9faedbc669a9f4a0856a809d7406207f4ba4ecdf882993a2d774ae4f35a12d5f24c79aff5c00e89b7fe99a8d93fce6b1305e91a3d553ff0433f1bb989fe8923e1296f775118b17bbb3ac22d4744815e647547cfa03a515c20a33b431ce\n\n# tcId = 37\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 4abd84f5455855d18a88df8808a009b6a470964a82604d5e562200b4ee22a6537b31ed57bfc60151922715eac7804f1aa4501721e242bf553509eefd5e34fbb1f4b6fb6d6e3caad4c1b7d12db028e42f4a52efefc88bcda58c567c24fbafd2b3165d768947ed7fe69f0bc55b9add57638bdf7b44c0aef8bd104fdc80f32084466ff0dc97d37cde2499a498b77cedd01d389a5a4063d9efcf6a2ea6b4ec3d28768297865220dfdf379ecb3546949ccf7687beec862c72c3faf80a944d71f888821f079bde045fbf1f11e4e813bbf81b102cc5417af8dc93f24a7c3200395c824b9c4a2b643fbce4af95cf22afe146f8b66ce38d76bd8821a3aed81ed05039a097\n\n# tcId = 38\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = c9dc8b821879fbad44e3b5827c1d0f096dadd16908d3d7f3b6a63052f897e2728a855ebbc04d2af9c2cc1cf87f0d67f2599f134358626f52f2fe0dfca954c4e7445e604f347e3f5442e0ecff1e81f4593d2ce920c94bda5a3c75022c303df0930be672a7648f68294dd62d4299bf750eda9af0322a17f66de12ce87876e51b4c6141c2e09f7369b76c51ae9a200bcf110ccb938d789f3265f8766ec8c40f1fde02e64937724156d367b1a7761eff40f301d1b610f4f1720b38191ec71c8753064291cf3446723b8a7a9c0a188a7cc9e09538b8ac54a04b9082a299131e49ba733eea7f86eba7ca0ccdcd8edeb6575181b78fe", @@ -4171,9 +4809,9 @@ static const char *kData167[] = { "88df0548430ff4f0a8dcfbe466508fd93a138ddb9dee83b9cdafb794ded\n\n# tcId = 231\n# wrong hash in signature: SHA-512/224\nmsg = 313233343030\nresult = invalid\nsig = 1c153e1a94bd76b0c5d51d1c91d38afee4db20a10ccc44bd46bbc4a40974c02180ca0b3a53377d694de9c34d168a7466b0bf5954952a98031104934fb319936185dd8e795bed92ec7f8d1487dd9393ffe476c377e406fcbf65011c96a34ec627b7093cf6c0ad4576506d559c74cffdd73700c83ae8c4b6b8189b4b5d4119bc4b720bfb2a6acbd8a560c2642e25f6e8a4ab5ac6ff0ab19226fdfeb02e6f97943227df82b251e6826028460f33b7c6aad633d663fa06aa048b5e3c7226af2feac31d00bbde8965ceaa0d3ba2d268cb2d6c3fea67ab672c7f16f8775b3b41d573b8b99a71fe60331c6243dcee7438a30a8161099a7dcbd9933562eb40bd7d587383\n\n# tcId = 232\n# wrong hash in signature: SHA-512/256\nmsg = 313233343030\nresult = invalid\nsig = 34e2223e4f00809c5128c2dd2611956e8b3177859bd30ba86765df75b2aac2241c6e6fd836970fe68ed723f1399cf1c7a8f04560d776c572d2e53b2d0edb65fa5dd813915236b278c058f4fca84c6dc75de97fa7d32b30d6f54d6aa8318105e58391508dcdc1d15cf235d238a70b085c8007a65e0df54962dc31b098a9a7d06108f07ece64a70426d5d749c3e329d1779125a7c60207a1c99b892022703229cfe852b426a2a46d9407806f911cbacfd98168e8e4f1322b4572bd1f0634c8337b5160c2150dfc37d30f671bfdb2c3acd89646ac37a0ebfee5e1d2a078fa1b4c980a87f83a6b098bd09c865305bee5bbacd3865e38b4414daf5fcc3bbbb1655157\n\n# tcId = 233\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = 4a2bd5ed1e053d5421808f7d2636779c7c1e6e1d94c47ae2520332113333f0c3f229554db384561cc4be4615d2f9b36d7a1cfebb85333c0a070a8379293d5e46af0d5c34d71b4cecfee2a190a9bad3baac34aaa8881d048cd2e9b8a74c67a5be02fc27368e5417b4fb6d928254d645bdc95577fb1ba79bc169a9e24466427db64406a98a8589e3e164a5889d205ab861acd9ea5551cdc06515813e4455d202b08b829463dda47a55729961dfd2130ee03c4ca92a8579b30478c2b479646c242a7e9ff0547c7e774a29469eaa49157d53425e0afe0dca68c88cc71aad8a8a00bbfe8f39c36fa3ecc168f605d7333626b0afeaa7465d78862d4d44ad64a4f7a0cb\n\n# tcId = 234\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = 5e47e74f1eaa0c542173139c91fc3684c52a3e0624ebffab2ed2bc007a3c7fea826b4400a9145c7893573d73340789f32c3f6770e1b646e814846690a941846578afd0455e9f016631475149bab5a150469acadc1d0486da5fd766a75f2b6be6e7ee56bd350913acdc08e06806a3db60ecb9c1caf58db36b92f13b3ebad4c67f7be7f16156520691dcc37b10c9c3d0215f3e2c0558cfb8d4944e936816d38ea6e3829b736b68cc6156e86f505236f366b5928572826be1bf0b42885f1ea822ebcf79b7008d14b23a1f76a2730848c077fddc5b8982ceee4768ba7733864a4cc0525640f1fda07c6cfd92c7f32715a6edbfc4366e2b62673fea9116a18e600458\n\n# tcId = 235\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = c1d45424fc88ebc3de2cb0f6fef91042822f857835b014e6362b986496d1d0dbf3ef50d71ee2dff5567027dd00fad1e826216bb34c95954ba3a9ee3fe646f9f690484c2586b96946efff54d6591024d251cfed885d6e8d36baa14757d7621e75ad521adea55a217ba7e6ea0a8294651d688ed395920975d52f607d542126db2283f00d9ebf48e395bb83901350843cd7812072b67472d16cbdc2cef414ed57e33bc725d53c5d78bb3282116bd3ee672842191e9a5794d78d4f2bb9cf600d6ef8f3d538881c9efb80c7f4318f62c091b0a3d13f485923bd0561bacfd7e08f75c26a60c8116b37524f4e4b40cf488035a796bd19d3ae5cba8bcee923e021a78183\n\n# tcId = 236\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 20835e06ad227e3e7868ba812b0361062e5e7204e2a0febf12eb0efcc5cec87328a0c0c39539c177f3f81e50f8f731c6651c03d865cb1ae667c2083132841ea3bd9749a54fed4a9d04b9f4a36ecc11c31202b79f5c7e2bbe0499eadbbc7781e22c6b182d5eedca6591af8e4a7665883666e30a927959ce67a149a7d03c7a863c16eaa980e7ffacf844daf83b5958c50c502d742e638f97067be25eb0c0c1f26ae9da1e65924bbc3a963dfcaae959300bae2240881d9f528d14a9f025a7feeadde1301096479d8ef77bf722dda463ff63dbdb4d7e5fefb4a0428544e2a8e9b1622b9971f71671cf32b0c066a26372c46294a66796d80a498282f6da546ab095e6\n\n# tcId = 237\n# invalid PKCS#1 signature padding: 0001ff...ee00\nmsg = 313233343030\nresult = invalid\nsig = b386c91fe71bfe594a2de2b2a0db0eb097178076afca8fec5913337edee509eb6b470eab1e4553b3b346d85c8f2fb31b6afc301d4a545cd3fa2b7c4157d501207518728819579b51d15d59318e8eeac0b903cf3e770660dd7350336ea6431057ff68e47c9cd471d616f25043d099c8a1aa11a9588e5b9275e3b1b93c71746307c277b74dc429d9ca2ec87145636778a95707296d980cd8c430e5cf1faea6b62a66b2362c9aa74d6391ba7bfca88aac9747cb4b29df1ea6bb22e5cff500c746e26a95ba0b442b468d1663bbcbd9d0162aabe84c02d002e760e77f766938880776e903ab5e09844829296515d89bc68f8c3ccc748c35dd285676c13877f44f2ece\n\n# tcId = 238\n# PKCS#1 padding too short: 000001ff...\nmsg = 313233343030\nresult = invalid\nsig = bbde1e1373cb938add41e6ceeee683908f3c575c6a15e38481ce6e83a5d95fa3d2a4b0b6e95e1abf165cdfd5ba308497640f58cc4642298100e9ff639951446951e67aec55ab8e7b9f05abd8870ed3bba86ab875e03d935803d13236fd66887069a72d14375a4f17e9fc274cbeedfdfa7c8b77c0b62fc570dc5bd30dd6f9f23f309ca58e004495472f2c4e5095202c47f24ee8a10474144e1d101ae173c387dc92647a93618d779ff040ae424d75b22262146f457e704240cdad3bff67d086d82b4dba7f8308e1e392691065b28be33e52dcc20787997817104d2d23bb67469d21d5e3cb84c035a1d75e6b699cfe363db10d52b9c0b4c82573cb1de5a5cd6cfe\n\n# tcId = 239\n# empty padding: 000001ff...ff\nmsg = 313233343030\nresult = invalid\nsig = 27e5a5c4d9f86f7de7d7220a783c26afc2a6614bbe8e2685171481f928b230abcff5b37f3ef2e384db521187566c70b09d75399385bf2358204fd38c1dfa1fb84fa78c1d5d5e5a869063d544ea812a3f1db8a1f0224fe7e21c5ee25e75a0cf2ae5d6db16172455bad2418c81235bcfe2319def91de16a7e3de8dffd74122bed90dc53e7fef8f77e832f30b2a33efbb35522fb620ea326455339fe22a81fed5b58d9a5b103188bd530439c4855e2db8cd9f98a8129c76a335cd45923ab67100dc2b02f31e0e5282fe526f9cba163715026071b61a2aeb93a5a58b4a8499b3c078cfa303ef0a107bca6d2922ac8220fff175e2b4e87a7a9669a1560aafe3ae99b5\n\n# tcId = 240\n# CVE-2017-11185: signature=n\nmsg = 313233343030\nresult = invalid\nsig = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f\n\n# tcId = 241\n# the signature is 2 bytes too long\nmsg = 313233343030\nresult = invalid\nsig = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7f0000\n\n# tcId = 242\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 243\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 244\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 245\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 246\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b7e\n\n# tcId = 247\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = cda6fa5ca76bfe0492ec57e0a3bfff7272dc8d1e25ad1fb338aa050f02c104e63133d6b5b7c4985ebbae9ac036a5b9c03074d60aec8e25baf392a0c430ff05b88e948805d3dd74511d8885250a7b574215ada015c559076686e253ccc96c0815b1291ee787cc3363b4f77d930eb998d7c582b24cea9ce21de9722791989863a27ebc80a00de5bd2f9228775e5a4ceb054d58c9be36a054336971a13642dd9510dd696aa268db3aab2299d5d88f8e562434d1427094d3df8e72d1ef69b4ed34d12bac375223b2a25cf227f735f816e85e17239304769a6082154cd15899fc1eaefb69b748a3e5ed24d38372597de3e4e2a27b951d6ac7db182d6809d8ff511b80\n\n# tcId = 248\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 249\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 69a1af712699465ff84ed85dbb35323df339f7627310b2b3cf2b8b9fd4fa5cb0f536680d7bf905347a642c1960c3e17495770bf939b7b3d426ed2209b5e47a6029af076a8e95f9a7fc959041d2e221d433f3836e37b6075a8388a2a6aed1785528cc79348d4dead276988f7f49d827c0ebbbfe7aae9d946f16c7a3598da587710a8d9fc72ca537534959c76a35c91ea90989dd0fce6bbb0d0f8c439188e51e0c82debfab4ac1dd7df3c3e48627039a9d3829a7f08432da36b6ca6d9ba0f9a15f6a61afa09c1ad305c3182e0a88e128192d8d064af7037950574cfd21b1ddb5f562ceecefed4e62c6d12f82135aab2c0a6dba9a181945f56943b4a81faa42fff0\n\n# tcId = 250\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 8c8001352b612c2a8ce94e15aabcf7e077a4135a6cb9f128870ce3f7ed11b74df002a93e9c7929b504f9c33d6bb1c8193dfaab4a808057380c3a142cdad876290bd68472ab37133d50d3805b6037c855d145d75151c42b6fe5121ccb44c7a624e897b298694566698f49289ae0ea09795450ab9d17dd30170b27fa65d54ca4a07835b3d772dc27ca21e8049dc5751522530169aed63009013091fa7621583d6487029c45eaffcf0c9e7e9fea1cee27da0f623b3e4cb8f73db62ef1a818244a4d00165e4328cb2b1af117eb8daa5cd808fe06e6e2058b7db69569e7db51b072381fa6acb7683e4ad9164b2e29bb3c72e99e0f585787a77c69f8a58084eec664e9\n\n# tcId = 251\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 5bec85b7d892bd8bf5452d477c53eab4c930828493ee9092e4abf42f905580413a6ad458f82e78a839a47016b2c6131899abffa563f54d49b07c3f56ba5e4975d216be7a591c6466e472ae46edf2a15c72b649f7089f4f1147cdfbdd1334b07303320a95c6bf8426cb9e6452d3f8695b4e376058db6805a7ad304462ede8d89543a5360749e83ff7cdaa6379941d28a44a60bc36353cf8ed7cf1e3db091d136372d489602ebb1c4a41a6a15663a809e2fd3905a6e62f49a4df64594e0b13737de6c7e38bc16b349c9a71fa9d8c519b6aed9cbad2984e13a0d75a6d24854823e6c8d64d891cbd64cfbbbab9157f4a015bcf9b6bd1465e5badfc462e51fdaaf698\n\n# tcId = 252\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 9bc2fc58e6db83a04d327571189b835a63df65aa3a41918aebd7f97c069cd499978370e4a4e46b1c27165b51f703beb3beb1c0a3a83ed6613dc840b58612a996dee3a10e1907bbceb5960e4f7a0fa9cce69a3ac34cbbf10b404b685763ae3fbafb42f125a060626e1136742d4ccdb469b3a6b58fbb4cacd3f5fe88da8838e2d2645d11618067edc8eb6bf6f96e1055122cff85c423d113cb4e9e1303c268dd5ceca5a201bc17d582a84ffc14f7f5e654a25a89486d54991f85bd24a6112849f38ccff768d1ca3c44e3e6e6a23e177426d26bb1173cba60a7938bde64b02432db83fab73c3fd4f10578f826ac3cea04172aaf43d60455c2632ae06c7665ef4537\n\n", }; -static const size_t kLen168 = 146586; +static const size_t kLen222 = 146586; -static const char *kData168[] = { +static const char *kData222[] = { "# Imported from Wycheproof's rsa_signature_2048_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba7490203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba7490203010001]\n[keysize = 2048]\n[n = 00c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba749]\n[sha = SHA-512]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = b03dd72dc84b305ea811267a489aba10a1dc54b59f92e58546a2f0b6883f543512d621951352ef12abafe4bd6e10c2e5b0eabbbbf1d081b66e535fc9b8ad379040c3c71ec8f2b4f5d319f5d2a0240a767ddb4de1fbc878b2c5e8e1e260217bbd70971789fedb8c677fc8193f67e4637239607c7b9d3511868ccc0df372374abc685c9b4b74b2c5f11758f809b19bb3b5c464db870fea61ddfa5e18be2c4106f3e165fe85a7f8241db2806d0fc3c45d8a7f1eb4ca411a46ac411b81c04fd8c4ced5eff497da6bcb8e2fbe1f95cf4c3e761fc3037c82276f7ebfb7e6cc8534cb4fd34192074f580c6e31008df4f1404ae8dbcb111503d4bdfe6e7107a1ab5cd8c6\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 4de4dbf82607b36a5c6778ae6351d83b7ef5b4af64c3788889eb10ef1838822847ceb531914392360b92dee055796f73e3cdb8b3d50910a537dd2244fd7f922780356ea3f01e99e5bebcb1b6ef398d2399bd02472a871417daec3bbe6f89f45f1af0bf819a446dcbbb75c56958d34ba27c8120cee6ff97242921ccf58de9216995fa0c49cb3e6d60e46411b2df3b01b78fa81ca145ce8be594ee009031eda672eb097ba5ed6687a703b154ef616757f94237f4275f54738cb59d36b20a9c84ae133bd715747952f0222573a91faf740e4b7eb4e88abaa91004e72a1709b401616b2edb2784e491f671fcf5ebe326b669facaa5d8a0f6f8469ea995c4db772f06\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = a0f46582cde6be215351bb7b29e8ff24398816fad9e7e2ed6ccf1d0b5296bad827316c18b1565253291fa1c0baea9a735357cff8920e1024ae5707dd2f0cfcc9e6cc81402217d9b4f51e10def2bc2f4924e7d22c022fc87d6c3e772f4952050d027b003ab4267ff227a15cc7c884cdb46bbc7eb38852d0e6d8a12f485ccb0312157097687debb6feaf2b6dac998224c6047c1d5727195bb8ce05a59669034e88de0e4815af00c65def5b9748d017455056cc1ac6d3a77e31fcea4e726eda6be7bd33e509696e54d1d1858a1165fa9ece5d62e493c1a33ab3c94d294838a19f367fb799d6b69161bd9532a6ef317deb919923d78e33309f14a97b68023d600b4d\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 9922f7bd01d7ba6b2de255b91209631af92e5537a4554b3b7a50e39f2fe9b6085a7e418084213d445794ebc19be43782d9f80df1daa7498a1c67d935ec00dac6b7a194033a14431320acd1d7f3d4c2b7b5b1649dd93931c49f538c94e34f44fdcb8dac9d31539f87e6720dc887c6605284a6a0408e244325e35917b1e1ccdf5959ca87091827c8157bdaa31239e2103ca8a112cc76a8e7e90f352fb8cb3a3381e52cedf4d4188bf881054b80387605e7041ab149cccea1ac2bb6560b45000601c33ebc31cebdd499c0b8fdafa7c1691d6dcc48edc98519d55d126a757b2a753eda4f2bf35cb191face371c9c34b2ab57242053b9ecddc91e4b621e650432adc8\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 99996fc01a53bca03382b96e9ad83a3139bfacc5d37b180a099fb5d515a7b78a5c21a339ae6bd2bee8e0f503ba2bf892c1885ad5f4940a99d8d49df6f4623da16c337a011fb895c006100286aed82977be3fda054d1e935a872939b704750c3e2871c33768946e65a737184efa50060c6898247a6472854884fdbfc2533c936fe9c922d881bd5f093851b46693cf633e25f27efd6db65da3ad96f2e8154ac39f2a9859f15c919a92c8cd22285c1f9e87444e61769f6833bd0d56106f87825e472e59caaca1fedd8d4065fad9dbbc252a84c196bf5d6c40bd8660600bc6c825bc7470aaf4ad118c6c139a5c6fefd5223ef490d4afa6c06269ea8c0054aa1f368d\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 7930ceed4b191365ccac54cc8a5bd38498c0d0c1fa5a862b6c0744edf9bf1969ec4f3c7c42aec737438acc797b8301aa8b30be2a4a4c1323be0427411dc8be84881036e9062a55fa2334176049305a44b97f90ed0b3becf56f8c9f164ef0bb45729f9fab1d459f690c58f07ef5ef89f21b15da14a235f3012e6f83a7f226e118d3b7fdc9356c39667e1cea5c667b54ec5ca6a0d58ad933484f447c670e5bd3647361c81831dc710360a90692eb7e4a57ad225b2516d9c3bcc77323a9354d1b92d0b3f5ade911f5faac4e4bdbead32f3349840ee66f4010789a84f0934182c2b0cb7d6e72e2b2a6839d03d7c9f681bb7148449161ed50b4466d60002cdb7492fa\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 16b5ecefcd0167682fbb3601a016bfa8bce9dd5855bf305ff00b45d97e50fecd27716997c37ebf8efd8b269558385b3ecaf2b6e38313508a7a14546107b75afb450b1a0e39cd0760151b666451bab43d7fdbd93771e9d98152ac889bf1abbe1c3f62049c4735602ebd6a90a0361dfa08417ba03c55fc6b7bfabb136851ab01eacf528abb1129bef47f2b04e2aa24c0341720f728bc9fe12cfa5d4248976aaf7035d19c18302fb9ae2443286a71198b500034d48113b705c83e64561762c583dc013cc099c7e5bfecbfaa7b971c8f1a4d3868fe0a4ad518372ca68c65bdefbb726b1fd92ad92ab739d2bd1af97724dc076ba011a9f32db3979ca4cf94c5370b77\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = b73d6d97834d8d14bb4536b050dbe47db349dcf6847586f80624425065e10360f9ce491c38ae5e48f6640bd3a314eb097f08c859625d3b7e8198b0b9dda03920ce5fc4937adf8c16af3dea2cc3137c2c200cb8538baba5bf36c9913784e079d8cde826f615313cad093d53110ed616591e5c38f32e2873225634ab10fbc7393dcabe742ebae9ea3802031ffdd6356a30aee51d126064584db555657f11cf742b8ee1ee41119b5c2e65c740219bfc36e6f65fe8db8d16684ba4cd7a12b5bf22551192fa75362b142b95a0b0d786eb26c07547e73ee3f3a3f0b2f2f37ba562f61e86c4bb25e7e059ea504f0ea8f5883382d7b17c95c5297a934479b4d40b632e99\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 93611a697f527bb2d6e4193ea34e079e0b8ec8e4a516962a74cc91c157528bcf4654beb487f5eac5ed445f858fcf8461e63fc657a57bd8226d980b212fb5e61111e0c654e0a6aa0c959f20001f6345a60ab14b8ef5631a81cdc552a04ad3f17eef287b011ce401be17900e79b4b045c12a90412a852131a1b9ae7c31051e8fe6f066b4f7e1d8e9997aef10a8c516fa3d782c9aed73dcbaa1d9794de7300c607c17607740f091c2dde354b58c0ed9d4b8fdc43e249847b494821bc9560fbc3c57f363e5d2bfcc488c041f123fc379c7bc80a9ea6ae98b7fb76058f9260c0f5fa1000a7f865e5a63d1d279fc7f452775186608cae1f3b640594d4b3fd8af4a5a4c\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a98a9744f1f1893343ba5b702d7d431e40900a3e3948d3e6630fdc0a8f391eabe2f4b5521a2bb03a16053e87a15015d5bfbfb0e7ea4877a05f491bb8df5893c867070256e8bc348f896ca2c8ce4e0ab6a9adf10ab98412e4ab6a4fb8440243fd34749596855cc14745d7096842c48db0647fbd71361ebba7fc263a2d191d719d23e727b1ce36e543cccd521b540cc42e01120994a06a95f43cb83ea51f73dcdb9d5a90683f627a070ba8afe67f9e29b003800479b6b8ecaeb6f2e68bf19f1eb568b170e56d70a8ae41d2524a0e76bfd0f4d27ac8cde9b00900b49577c55384e948c6c6dce081d277c3623b1e749748488e648d9349b9f17cbf072d7083c377ed\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 1075928172057bdc681a626808436b13f556883057c93b452326c7f51316939cef89fe3072c6f1365120eceabaa0c12ce4ce05762843a09debccfa01ccb9a85f8b0f1f7f030ed2a0c1514ef1c25cce22557d30627cecbac23f9f1fb645776883fbdf502894cc373e18ac6bf47d655894b528369a341ec1e56c2801a30f4c93e5219a24f727b5d41c0789d01b868742dc9225f5bf3b588e5836aed54bb009e44b9598a96bb36df4", "bf3521cdfd792c2bf9647b01f77e80f8063299ee26a9a36aae9594536b7b3d3ab2fa8df3dfd7e4380eabec23ea09b046d9bd07a11f084107bb6caeaf32559685611791912513f50b0fca6bbc37f93b4c0048a41758228539e0\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 7a21f13f8af98f47bd62b03985a2e91ffb3c7c3a5af6ec75c2269e3ab11d859cd45a214b48310c7fd7983c8577d839cf63d3c3815302ea649a17f813d6cdc75803a6caf2195fe17a5e84d8a59eac0651232dc793d9b7554eb1123e3594e1f6a57a72e2bfa6b1ed9f1f9a6168aaa83ba2d8b408f3c709354a278b991751207075e7e5548f0c0f764d58775db3143191a210e702b69dfa8d8946b1a65d67b3da6f3451f70a65d29314ce5b7ff13b95cf7ae68854f586140d97a0e9de4ede07be81fe20a5b6330bd9c63f15a3d4904b3a4596951ef5c591007ee2f6ff94fa90abd1093d4dec45a9904eb656713a110faaeec429fea9d1b8c47133787ff6aad3f938\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a7db33f68fd972b3e122e2dc8c749561d14e513e7df9b03f285422015879de35021689bccca37b31aa7d156f39399063a06fc9590c58cee25d83e1debe90037a8713eb0c58194e7b54ddaa86baa0e9f83b604afb5585aa1e1a45fe24f38576e644eedbbb86f57031cb43f3ef1428a33998c1decf44011b63763e47d2b2fbdaa90deae270455607b928645b3f5ac39553feab8f5115c9e2f26497155076c13d76d95af3ef342bd1828e382949a63c54cd0d4c4c53cb00ff4b8e285034e78ee0f7dccf9017839c189ccb3bb8b92f515beb63345c9973e77dfb388b373b8076578e41aa3bf3e86bbd4e1875996ad19c8d618c8d69f4eb06b4103cceb2b8ccbd8a58\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 72eeb72c3c87040a35b98244d6d93cd309b65bcc793bf9b10d5f7501bcc4dd8030eea73c4670de7ed9605b3210dee4e53e758fe7741c6410dcdda4769df6351ee82380b5b2387c1cc8935a60d58408fa1a51b485949e0a4d4a82a27e8b2265ee634815b8fbe3778a00fcdef0201179bc4999ae16e1849027ecf92d53f53ae3e04c9d7a39e71f9be774036d40d38777fd6e115d0bb7d8b538e57cbf16bb4d5748ffac01e1b20347bd688b0b45448fb5028fdeaa190e3c288df6dae55ad078b50cd64adc36d471f0c31b574fe86680afac6a61ea7c2fa5942687e1a4027833655f88a123b50e7ccafb7cbb73c8ebcee7f915258b8ebc47a792832242176e2713ca\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = c280a6067d62ed84b0f9f44bfb322bad0ed92fd26f5c8ec7e91d9a115eec2dd6f5a589c124b50b732bc5f4e382ad344a3498ba280d70a8e7beb9759972fe31da8ba57b29a13c17004e4336207109385a5e27d53f12abd5bb6059fa917afbd45ca8a4322928cccc776cfbdefd7559eaa86326c21cdd6ae4c40c40b1659016520e5d34b1b63b7cf744a37bb795ffb86d853dec82a7c2c57ec5b14f68535c12279841fccacb94b35049a5feed59496db1ed372f968a4de1d70dd98c64e3e17e541d0fcc971a735cc610b9504680cb615301440cb211a73b6bb9355a677be77de6330dbdebcf6abf3ca83d457dbb951f3189d017022c354d08fd7a5d0f8f63aac308\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = bb7d11eff4ebfc47082969640c3883ae3b2a95efc08f0a4c4cd59c61fa5f15e1235a3e53a9653186f09c21e11757a016a671db51ab597959a437f26dd1f864ab7c67306fbc578dcf614c304f8ebf6b745967c71b8093485f74348f81865bcbadb39075497e1ed9de3f9e21209d21ce609d2d11c3fe837dc7381ef8aebf4680e680276cfcca5506d3c1eb5fce1655b566ed63cfa69e4e186140580ec9c7a51aab286a54fb674cbc1b527ef6d778ad228109a93ec4a7dd39c30c5879e2517a540ce7c0f4989b7a930899c1ff51143e7d2d3802c2328000331b9c6e9c887fe8242d2dfbff5f828f604050268c450d74779f8a512dd0632b90c9b5870c541b45d163\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 4988c316c1057404e4b0b1aa3d0aa039e0b4dee3917449c0cb816c7d738db50c5e62275770f2ac0372fa84e88a20a23b9c36970c6065c599ab4c23b5b28d260e95b7f020d760e7b7e00f0e7f7bba51ba104ef62205fafc6226c95c0f483486980eb163497d7c33aa1b856ff77bc1dcf94c57442edd91923417afa48fe718285f358a24bc7bba48707155e41145d16d9e37a12b8821ff29c581dbb2f3fb64172633c6d7c1ff6b78debd5fa8faa4623fa3fa93352834c7948f7b68311fd8f2189e54420d73dd5190ab34dc3a8efc9bb7787603f6030f0ea2eca2aa7e87c4373c9b0b3c8d9fe16afa3922639501b62459c34012313c160c8707f740330870ac2273\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 8f9a07ec03306424540f913dfd03eff0567cd419dbc5be4a28b3dfae5de126a01d1fe4c6147aa4f1a2f57fd50be2566ef8ef52ad8ff816abb114060d6efcfa64abb0864e613907ee142a4f96d965b3aeacc6c870bdfc316c72d43a5c9172fd2a5ba0de6c521fd82023c511c40700f7b7651e8e98a0a20d84f7be365ee540a403c9afc6087dd5ae8473006fe4203a790db4723520be38fa3b9247075c93e6b5499fe8ab997c7267e495d1a99d5865333acda265c02569040787d5aed0bd4e492e3f76605120bd41840473da0e4fe1a388cadca7b4d543f5beec4be9c3fbccd0442dd0b11f9d79c6e910177aa1c997028d675980c439e61571011ff9b26818a69c\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 22f3151da8a6c4d0b32ed9d6fc8fe090e218f18289b5a7d780b9cd78618f57415b49ed7a2ad1064cbeb8a20dcca021cff65e5d51a6d662f947dd2286e4734ea6923ff40acd41cbe4e6b33e4661966a8de0673e59958f71fdc191b24a9ca7b08a78bc318de1330ec7025f526cc6704faa7923c042e561f83719a7edcae9a3cc6ecd91d86a94416d2ef60ab3e74e1f587c0b5c26fbc4e2f67983d4845f907e58866936c80b3159d352383d1deffbb9bbd67a2eabdcc43450ebfda73495618c6b5b8093d49e1c0c32445f5e945227de1e8ce1cec611cbee43cd6956944d6554b5e120ff63899755836df131feba79d7fb06fc3a3b0feda121243ee00cf8965d4acf\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = ae0ea39ab7ce7af3075d67f8edd5862508eff6170b43c02e4f592c9101a7da1dd7ef2e4be53ba3449dd6c2a6c1837884f12fa29dbe8e9d40c677d1edb6122f61205b203ab0f342f21ef8cd45839b9fe9f61738e7ed0915ff398a679a983124009fd37fd5bc9891d33f4830aa6f89cf30b59dc3d84cf955ef960a0980f524c686cc8123dcff7bb9dc7e7e1bfb3585bec3aafacd5a0c7ba63f6af332dcd1b5215f95f06d2307cd75dbafff2ac5cdcf4587a68eab0d3d277ac6e999ede44a551a0d266f9358074715931a7787f4ca26a94ece1c963a96f6558a6c8611fef31a5d459635bc2781ecb35e75837829864001074dd585d70b7e5fa6abe2a6e28b67d48a\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = ae177278bf000f22063be4bbe62c28840bf0d293096cdbda95eb2794930c96544817c7af9e92f22dc81ef2b64f43fc50243ac91a99ff41d05a5e38005a32c519473de62f05a5250643412d6339b44fcc3ff2eb671da073ef72832cd9a4e892fa67c59f8dbdb1b5564f1c8b93ec9e9a1080670e649450b006afac18937a62142e2041cc5394f87325e723fee67bea8385eb8847058fc56bad33419314e4097852994286c2094e4d0360870aee0a6fa2a3823d27eb3650e727845df9dc1af0e475a8325cb9a39f0a9ebb2104a3b66214a7cc02b2ad3be12f91fa434553927dac42aec55b8fe2b5230b0951d738b42b73063b97eb6cf1fbebf76f5f7f5619c730c1\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 1037912266d26bbb66bc872403272075ebc3c0352ee5201b189db701f64ef193dc2facec45af460a38b8d2a71d1ccb17dd0f8532bd87e5d7f6b8e1414367b5128e3f6035b26054d3331ece1f926c2685f5c286ad0befce4be76df6c26bae8a6df520ad073a058eedaff3d5fc6906e8e1c864d5b989ce9319e87fb121623a27432e2c06e936d151b7657d6500a08e8a3c71a0b491cd3908811b18d00add825f848d6a0290f4c0ee2e289274cbac8c8ee00168631d43e7e637609444c18aa4cc0a887bc104d6ec9f699119840a99a9e6b7ee3dec0d0b4a1f6a1e022a44721066b0fbd6a7c6b4f51401036e755924845bc94de315f494c5c19901b23e62e9db6aef\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 47fc62936a9113548699f3133f7252e4d2b060969d2a992e4e83e2cc6330f4d3c9e5cc2005ab49f26cebe2834b7febf478cd01d0338a56f262955f61c70bf662a55ecb8848374f38bbb16b0b25bc012197e2b92d62b5c38bc7b2b570b376f6aaab95a134cf6d0805f3e5823bfbc5f57b69cd84fc103d7f3fd7f87186a08dade4522cd32a7cca292d25c02c90ea0a44f6c38c13eb58b71a54b58e42f17245f1881087d32df31be3e83a2716ff9487e3b389e2398d79ed80c0cb355322358bd908d397b7365185ec4f55a50a5879bfa87e248d31a6ff51617b282dd2c07e228510790babe57b466e5d7e7ea6491dd720e98c77124354b3e544d064895ac845c35f\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 389f60a3f7e33801cc6067cae353b16263aa75279d0cfed16c122b4ed81350538039fe7f43859a1f76bff62b613bc8abbac257ee6eb3e5088e6ec33815281d6f6702f05ff75f2c6260c8791e43dc168f69eedf1d33d42fa5da0ddc9d2f071ab3f9dc0654ff1a3db8c855cdd9941e6c6609aa29d69f6b1b1254c3437196fa871f443fed2b2beb113257da4bde8aa7bf232fd9c0ae7e7419bf977f14c4f2c4d128e5f79f6f5c63939e7fcec231ba64145f8fcf6f43b821b41776811a848d613b5da4cb8418a1a95402c3ee5bd7195666e8d5b13f12b08cbd730938c7ddea9d65ca45683e9de28d618af1b618aa0bc88e3d1db4521dd069be105b3145e54004eccc\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 7528546f84b9a056e49a848644d876452449b0e228681cf1a83c82aed6d1d68da0da6b880e31d71eeadd4ff2f59cd55340d63", "0c6c548b4b9c600de0cc4b18d0e6144a5a294216e4c9901250ec8a6897eb39517212fcb0ba823ed763427e477308194927c7ceef49c440c690f5ed33375cf29d697da0fec04e4bcb0d2bd0f52a3bcd209218605eec678ad665e8adc2ba55caf883d14fc6cedb87634a36b0fb6019849693fe47b0e5ab62bfee78b415397887cc3ab293b170b5cb4217f912e13ffaa27f8ae6bdd4210dffa0179d723a53ecf6d4996992ea0ac9ed6b10064bc793256bfb4ac5aab69858d9ec4cf9bcf13c1bca969831639fe8bc372ca67b7603fd4\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = a736d77611787cfc46ef5e49ca0d39f9a1249326fa77b50e024c657c791da09ea1d363657fb7b9d5978dd9b75a2b7593528e3c19e6e41abbe0e71273cda50382921ec6b366b07f0edc0aedb048484d51b603d062aaa18c404d6bdbd61a7bdbcb32e917a79bd95799cdf43a992ee3d93193f9a20fd113cbe168df7f884067825b79fa73c72b9168f7b83002096fdaf613919ecc40422317fd14b5ef8d2561639a3bcab462c3ef8e0f59929c43e23cf21911be969afe3548c1b449baeab90a8f6b52be5f6cfe47b941a625d4020785e8180eed315b7a6840986b33b6ad6d519c53179a2c3cb180583808dbd3ab5acd90e4ee01687d0946578ed9d7558ab8de8a8c\n\n# tcId = 27\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = bea793e3475943e123a0f811de9b3066d85d6cf394e1e8494741d8449ec11eed7b3d796ac69a5a3ee4279362f4a69decdcb1dbf397c7e0e46b9b855feb3b125f3ee8c735f79282a9efd6fb25bef533a9f3641f47d1ee3bd647e4b8e0c1bcb48ca35468302cbb32ece10135a63b4d4e14300d0a30b3eed9412b24139134c84cc2231dcaf505a15ebbb8cdffb96ba06b24f8e85e4274588f20454175752d94b0c71aa8d50a776ad13662c8badce5ba74f4d086aab60f12cfed831ee562d3b9d9bbf4cab8b53071dae0ce35644b425202595f155eed25a8d651349a2dc734130e0bff2f09b12750977fec65c79449b95957e3602104b4b0936d8e41d5fdfd1e2c72\n\n# tcId = 28\n# length of sequence = 2**64 - 1\nmsg = 313233343030\nresult = invalid\nsig = 9740ab49e35c355c40c6eb4839c47c85a27231b2b96133015267e10a7b0f786130308be8255c68584aa3f6d4c1ac2c304130b5bced81ce26cf6a0a0bac293f23b31e2f04f5f91d98ff17750b299dc521cfc946134cfc76ab629f9abf5275739befee3fcc9c217e6e7c81a71dae3cf3407e5362ca0c0db20386ea943466d59ffb9e512022df97d666cb15c35b0d1a0cc532e408727e8f76cf9955587bfc1e327dd5f58d1f7edab6fbc7232d1d2afb9616fb5a5de1795cf6e93896a55285f793edec78ded83560b34b4102f505c4f2ab8f15f603a7fc73b75cbbad2bff29c374fbbd9e1d1a6a1dc10a09140bf0cd5aad2ba8a0926b29b3d830959e6c45e8d8fe32\n\n# tcId = 29\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = b5f76f1fd7a6e786981f7a4fa8430dddd9a27ac86f683d4c7abc383932e57e5b15a30d6efc79cd266acac752fa73ff06e3f2169807133d3f9813932cdb7c83de7e57ee196f1785c12341142cc3af2048ea81b4b265ad16408a764b412b7ad96dd29fbf899d8343b01e74b63faba19c36ec825102941acfdb55f8388e7d429a89a5d10e96e2e612e231f8cd857127f6b19c7766e6d0f79d54e9ef54bcf5bcdb457509154eb5cb0640de286e2d4fcdc6941aa4d97f67fa99a1213deda89c78e5373e40a0fce38e71e57da2030575271012c4fe96eae29f65462ce293943952db34a93abb2719226592cd3c651d3d4ee6a36f8082a3f325290869bc3ca5f02de629\n\n# tcId = 30\n# incorrect length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 1c41cc918d7f45458e0bcf5a8e4ba5eecf39beffac05fc670adfca933f8e997061fb546a2faacf4cbc92f7b6da6b7ec97bc142b41f38476458836df716b9b7597072f11848bffaf7ade3871435f2b06fa0baeb08d3be31466d6c10409e3871c92df4a6a5346b5d7c3e82b90539033d170e4950320169c7d9db5159201bb5457e9b3c02c9aa6fbf2b5359f4b657702d37f34bb0ea2841e46c73f6d30ac546c1cc8a83c72319bcabf4ac741a542f2c45fbdbde6f4d8be88906a24efa7f62cd5e7697ef02a76c3fc827c1d2969d8c4ef05658ac4de9ea06dac8c6c0a65bc3d05ae3517428883a0c219084486c8793e2d546be6c8cffe00e07eb7b82a07449c726c4\n\n# tcId = 31\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 1b80690c323802241d2b9fd1b024571fce1ba770566018753d6434d0927336d9d4441a845d629ca275502d14bf818ae7a58ff7af427c3b8ec88997473537cc564267270bb2be0030e0cd934c417f814091831fcf776331daa9e73b7e426f73f0ca9c1733d015f37cce5893723f1ce9fb2fa0bfc3df6fe7ac28549983fed2f05b70eae4648011da36855f892dc65c06c909ffa179a8950501f4e650fc6a1b05ab988edd59aef685d5b05224445d9603d5b816f1ea3b3743fde547de72f15ca60c305c6f493310d22e84523b036bd71b1fc3e38164ef7b954b0bec028fba60c4720710356d080917c1c5abce6d27d3ff35d63baaf685db37dc76568e3b35147d54\n\n# tcId = 32\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 596d8e9730030342f72f0a850fa5ef746f63b89a1e0c48b67a817f775ac937454936cd8400653f4d1f82e315597b9e5146ff3fe4f9412f81cf6f8516d9d440c9c01c6a8e0a56838e2a206216b2f3e419e5fcfeaacc7c9be4fffc7586ec21d8bca6b49a2efe44d66266f298a3b70c4310eb22e64366bbd5f324a1c9c667cf0d970ecb37190bf7c98977f180100d3d6c63e3dbfe382e406128eadcbb99e45407a858dc6a443bdfef2c9531bd2461186ce21ed34cf5715b764c5bb4d4cca9fb59c7f90d9f71f43eafbb256906095edc27679b8c752b6232ad374c668d4ef2c55bc6fad362f8538b553ecea8658adf73fbee8c6c47289d9ac5c4471f74847697ed26\n\n# tcId = 33\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 766027246bf7d6eb5d4a137dfc5d537fe2446156834428d928f6c2c927f8e911fd57db474d55b4e8007a0cc65d40e7f3b13c16ab4c106550e5a89059862a86d95b2de4dae32d29f7fa0ab67bccdb74f90708153e5c726614ac33d61b3ff90c90a2c8b7277dc33e677647cfdd303462ed192c145264f253cfc403bd55a48855ea683b3e0d39b866c9408f149f76beee227a9b22720cb5eafe4ccab94dcda783ce5a15c29905c2d932b57eaf359e1e066ee4e41f97ee2338bd61f01bc0516463a6189cbddbd083e61f82e6ed918942242ca178de8ec45d9c3abbe0d6a621fd395114ec2f53683cfce25c5d5c5758f81bda5f2323c4f5897e7bdb5e0b1c9a2691cd\n\n# tcId = 34\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 7465093e55ef94f127a95582587d4096c69391e5fd935f9679cd2423d5e4e2edb53e1c6106f12e57fb372f0ad6f0795fc9619651568834be5f78d4614498b79615f894058d5e9be91138895fc5f38f4dea435ee9d8f9a43cf3bd98778b1c6d17ad4285338b26ac1288b97c4b2fd1ad27d02c152f38e2cab73677de734e56e6d48f1cb5c8bb5cdce8597952fb63ab5801d60acde502e5583825173646d4ad4a7f47dfe060eb7eaf34e44a45f621a57c6afe57a4fa2bf785b09f0ccaa2d6179f4169b65bd8d71b1ddb3ec92807708354cb10d10a4f198dcd1eaf8210079b12ec50a0b759e0f32103f46d256156e8635c99c973a03f70f31e32ed7c441dd4d7e36d\n\n# tcId = 35\n# indefinite length without termination\nmsg = 313233343030\nresult = invalid\nsig = 7925db05fc296b0d369a6695038c4196ef66d47f0a389ea05f0904eb9c048eeb464516de247437b2c8aba8fa6f95b563c982d21f5141505d2676b7691454a5f0c9c9d07d19b81c901b01f9c1cf5bd9b0d5e0b2e244b8475a1931efd5676bc18f84a8bf97031e2fadea1160ed8437c2dfd9a8f7fa918e93dc8803de821a067b0eeda6a6ba7c0a74f403b3fde78b182c7a22b6ca779513e0955a8fcc69d9a6d7d1e7960c032539f17322cc40e8698c146df8448ec2a430203dbe53421f2cf19158bfaba36840a5336a775200395dd1feb4363a4df2d115b6508fb2a52a7e1896a85fc778af2e014d485bd270de8727640d7e878fee0ca41b552241a83c1531fcff\n\n# tcId = 36\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 7255b2ff2dcd7241daf5c0973f37f460e2ac85bd20d4310c2797f2e263f4f8df1a70eed714bf5fb19ccecd66391abf0d3d6266313cf28b828694ceeb9846e9adaace75f691f9af5818e05fdccb2e2dc0c9cbef64aee2e058a0954ec3ac9d5146073796fee6f1fbaca676a5cb70b00bd0023b7d171e4f79d22d16fa3d6886f7695ebf19ef51d0d6e193ca73939c620c632881a26d61a354184e00e805e20326173fc14f1e0ad0e85c74272138f58345c365e4e46623c624995bda7eb6be14be0d276d6b6ab770b1d1e424aeba562e80bec509fe3c3646f455ad9f3ce1db8f8b923aed9ac89a72505e608f3ec9e58be7bd130e81c1e7d3b0bcfd20bdcda9e0945f\n\n# tcId = 37\n# removing sequence\nmsg = 313233343030\nresult = invalid\nsig = 9cfcb1b8abbfd5ca02379491ae39e3982ac9fe8bdf9577957ae39cc3b7c82815063a179822657aee3670e4b37436d47d7c24b79f5ac06d14a9ef51d5d48be524d09d1b8068b1af518ec4c80e2da596d9cc5f0fcd261a366ddfb191d0767e02371184ebe7b5999879ca805a79c428315ebc350ebe3d832fa0bca87248be57b1c1ce72df271cd7826888c43dbc4f187640ee5cde3ee3f004b530bfcddfc0eec7884998255351c7cfb7ae5d8356fbce910df9ec471ecfd15c3666b7943ddbbf3c688289ce3375bfa8a0fbf3f6078376c5f310690872c7e608b87b680be66d91630c8f3a71e44906c75560855ef3f341bd8cfcc1e49cbf77b58222ee1288b6979ad5\n\n# tcId = 38\n# lonely sequence tag\nmsg = 313233343030\nresult = invalid\nsig = 67c3f8293b514637ca21417422cad5f3c5f39fa97cffafd617ac72649a9026047e6d8ad968e48a9523d0883666dcf1d7745e2bca246f01dc285c34b87c10bae061e8e9e9b27c673e43c311bd23531443960f132d78e667ea8d22e118ada4efeb34a84d147b9206a5c462f89c49c34785416575e7ec1d61c0cddcb4aaca309b44cd5a5d0a0266e7dd71171e160b761dc3f12024b2508196caaba0102ae74c7dd1cf1c1f45127cf532f274489e9af63c02b2d5664375faaf1b7ba2b556d46b145c28a8d123b5c88c0151698f7771b790c00c17e75bd63d48406b4b245827364fcafd4fadf605bc5f68a78323d362189ce601a791", @@ -4193,9 +4831,9 @@ static const char *kData168[] = { "a5916a6c0ef2dccfd5ac7397e76a301096732584e8442f20ae80627588961cdf97e344e131d79e6894be6fd51b72122bc2654d00f943683a8db630d35c6874ea56f908eea64902f18c0a548905b3c13114e3526f3d6ed39061724c8e9df498545ac7f455c37d2e05beecd47c15181161873925049bfb4a671e4d1901a75099c7edd6499268229353073a598174fc937f856fe85f950e9059496348d0a1d9f98aa94208d66ff3f58792ab0afe27075b241a636f1b5835f4a4b330c6f9e032a736119a1d8feb99f6c22f3490a82a65710abc3767e81ad70a230ac4b1db9a327ede40\n\n# tcId = 218\n# wrong hash in signature\nmsg = 313233343030\nresult = invalid\nsig = 60899366735cff786b22572d67c50af5f644bcdfd50c559d989018efb91cc888398ce3b556d8ed134627827e7af0ffd5106795ddf96f988e581d8498ac2c2ac9ac5195d7c15bca548ccaa070924c6bc8de828fc08f5e74b8eb7cf94477310436b9d139e54e97a9764d0750182867e00f0f9e5b4b6122137bbb65271bda16add4bfb9bddb3d8ebc063296d9ca073c377e56993cd5f3f1bf229e0f40ad3efee00fde0a9ef1604f01a24c20d67fee04fe8848cd245a5b0e69d619dffea08fe1afb6cf075c2594d00cc6a21353656b1aed51af47159ef88b61891842a6eed6c3d294c1d226009d457e4c54108f8ebf4305d0dcacb07e60b51976c35d9dd5aa10b9a1\n\n# tcId = 219\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = bfa56d1f9db006144a2714fd66a633ac3d27e7033ad9d59967f816ee45277095689203f3b257c8fb64b3b1d16b6e424f1347076b6009ae56ae193075b82d5ece6e643f0e645b1675fa0b7998c6f5414511d2acedfcecd0324543f92a462b9f9f79223931e7ead2c2915a1dcccafaccbd374669caf1e2f50d45aa986e4511674fa9a5bebeac29760bb055acff67026ba83a977aee4d6bcc7b247a76bb77a345ceb97996750b77fcf979adcffb71e734c461adf3e23b708591f4987d59ca8983e0d10ff5a78199a02f02ee171c26b373160efbb51a23451bd326a7a6dcb66e4d9bd02ad30acb4719478b0908831d5cdf4012efe94aa8d87290f9e94d430e9095f0\n\n# tcId = 220\n# message not hashed\nmsg = 313233343030\nresult = invalid\nsig = 7859342f4b0977d970fd2c30ca94e898545f8dc398e37949a58146a203d191a6124cc2e0de5d3311587b4a54a83e5855486aeebe867584d7fe2d6b559f5bf2bdcf990062c2f04db9705f06fec4a3aa3db300cf080d1493a60c63df1ffb98e1c82440b8143b816244403c7d806bec0481264219fa263c62852ad9315db8f03b255e7e329caa6288beaf7a34ce3273ff39e8c8ba449a979253b60e48b66124cce678112cdb13d28d805c6b3a5fe55cab2df194287fc060442fade432473aaf96fa331fd16544c0fb801c30f63b0864ccf559432f98d1fe42215c050bc71616145b1fbb33a4842bd3222bad53bfba487101147c3119071513a49ba753c8b2307fd4\n\n# tcId = 221\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = a5521057430948701805207688507441e3ee85b3e8ef9334922c8ae9a9a8485f95f5747778b2f7db8ed3df6655e57b03022bc1244d04961d6ee57e62c762040b581bacefe7e5beee3fd1613a142baa6ad106e720206cb119c1884f41b90e3acca402b18deb5593c3f2d9d841e23b2f9443c13d450463b4e272a08fded7f00d26029f7c0478af557d41e7285c48d9a0ae3719a95a14bf8b9e25351c7513a5ddd86a2e6c124a54be07f29660bb09da8fa8e484c0c930833fd727b429ddd2b8a6e1626d05f6265bd88eb88e9783123a7720068f590d566d16bf19b474d58ab5ca9f718eb5d432d11f6c65e9325a2378c6588c5c6ee89edf7ac708c93bb9b04a1f80\n\n# tcId = 222\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 9c0eb700b26efe50ee6aafb76f0a996890ea71533c374286ded0c21a567afc5bb212e81cf80cfd6f2d26a3b27fd7f17a4c976f093b240fac274a2a22969d119ebcb26f81ae0bf5641dcef96510757de9b0e7b02db74efc1ae55c55e8135320156ee9152dd05c922066aa895319708bda1c7a9db1890ef7cdfe7de3925f4c9852a8679f4d71714cabf8fe834ff442794ba96c2f1df73641eef076b172ea846d7649e9a42bded0a7da4647e07ed4ad8c1f2d7858f416fdba4d63b7ad80241d8fd60012b3a77e7e0a759091274d350f688c8a73334a6c0f2cece789042cbc16585cc84150278bc3465b3df701533674d272c33d06ac852cc4ce6648e35cfe60da60\n\n# tcId = 223\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 4ca9a8f3f2a187234daaa149e463d1e27d78edb054e999ed19e63024e41e267a51bafc7c863b4f2802b09f1aa0dd3d6a42fb0306ac38fedfa3cc642eebb6f4748e55ab41d86e3fdc392b1a9f9b01c55215543b39e96d8603d80e223700521bf4b3030fe4f2a53dbace1d668d99cc4e57098732a05b99dfdd3326a218a11c195af7f09b829ef806ef71f3b139d1c2ab00d488cdc75576e7ccf75fad3ce9724495aca667dc41df1efa59974cb52b040fe7d578c7a4f2e71384ae347fd7dbc6f6076a86797198e989fc87878ce926fa39d23175de35b1d09862a62512fb58eacc669e11fee9aa0c08f351f4da30170a6e3bb47929edcb81ac0132bc6ca77b3f09f8\n\n# tcId = 224\n# using PKCS#1 encryption padding: 0002ff...00\nmsg = 313233343030\nresult = invalid\nsig = 89c5da365d5d2c22a961187ac62c26bd5b88cccebe46285c654dfc31f44b7268f38d9e2902424b09f35b7094a39ee937ab6140895acd30e63bb927f3a0e017e68a2fde529af3e1a2359ad2ca5df7c94e9e91843160922ecac8ba64d38ba0fbeed8e8fc7f2ff86888e0657805fdab834a6cef5920ff70929d66676eba288233427ab5ce9e44462e03f71225d9ba2e1b4898e56fb7949e6f788fc0b76c0b738366ebd32c58731e8d551f8f52b433bf45d6fd668548e59c41943684203697bfc0cf2c53274836aff5f346eb7ca753b3856ab4d9128efb0db77ca05274b393579ba78624fb356cb3360ea05bd5f9f9d642b74211f258fed6bb940577dddb2d807eee\n\n# tcId = 225\n# invalid PKCS#1 signature padding: 0001ff...ee00\nmsg = 313233343030\nresult = invalid\nsig = 084fc83861c80ca0f3c7d5f063916b2de3a1b3f93d11a5289ceb608ed3246bdf1fd79b7bbe22bf40ca7462d6689f1f50a53c0fff60b4899cbf86825f8e834171aad934a06687787c7c833cb4c6a2172002445389583edee72ba4d31a6c5cd09b1bcc18c3358faf548369af125a915d47affcfcd30f934b739a62ce37ee0060e568211ac255ed9481f6a3a871812ca2e86417b807e6d352b0aa0ca078c75319a64bdf4323a34f379dc2699201b1d6ab1599ad02c2e103499dd7cdfe0545716e73e400ea298005481288d384b76f1bff69dab1486921622fcabf0733c0bb392c3a9876d168e0a0ed453d0e020bcdc0432aa00ebcdab36538d616d93cd01ab3a63e\n\n# tcId = 226\n# PKCS#1 padding too short: 000001ff...\nmsg = 313233343030\nresult = invalid\nsig = 471eccd41ca3c301cc79447afec99925611ea09e5701fbba0ea0458be7d77b35e798452fd19865903b33e2121d4f21cbd0a2df7e2d10e8d20ddad3b9f0194cdac071a3c4f4f879ccd88fd03d761d4cf0770abeecc946a3dcac65e1f4152b833d4a43b65777bb146099800ae324479d98f623c5321cf9d0aca42ea93cd9df23f5bf27cc128f20ff41d9a5f4048357397ea45463f04ee665bf4e10630a006f57833ddae1b3704a6f50f5e2766b3f0c700c21160b24e0666c54eb3661f13cad3fac33b0d63860262e6759632204f0f87a3e1e039e38c15359c99cf89942cea589d78fd3710a83b5e9ab09f1630fd7f9d7a8857efd763d361e158bed5cc85b3776e6\n\n# tcId = 227\n# CVE-2017-11185: signature=n\nmsg = 313233343030\nresult = invalid\nsig = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba749\n\n# tcId = 228\n# the signature is 2 bytes too long\nmsg = 313233343030\nresult = invalid\nsig = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba7490000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba748\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = c2c4a860236d3c9096a076d6ba5107e0f7bd81e1ba916f7375724bd2b0b0b63956813715a3457ab0458b71fb35a45b27f9ef7ac3e579dea45dfbfd07819ed6b7021aa5336c58442aadd96ca9ee9d32473e9d9278562b4d10258ade6a98fb1c7cfdc3b3716ef5dec58cf73b359f389599b4b5865a9863519eb001c324387da755450db341309360e3807c0565b8e2c44fbd5e6e8d04d006d7ee768b8e8436082a90fa0e837f32f46087ab4a0d9be28aa7da1794ceb0172a7f50ed20f6df641efbcbfd2aac89775c761a7310093c671c977fa18b0d6e01fb25f7a432b42c65359784c689205719c1cf6e3a65dae2da434c326dde81bb6ffffbdbf6de5c16bba74a\n\n# tcId = 235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = b6e6752a6f99a6dbc43817850a139bf61d3b983821b022758da22187af9cc02a33cc4e7b59586fa829582374031a34d8d7f3ead4d9f7e42d3e50ffa74ea085b4cd884bf637039152d05de1fb6611c66b26bb4f4543eb4680dba24249aa0e31ba17b6fb4a26994b85bb1b79bd77c59ed18bcd4d4da04e45655c0d981af616a8ef5c193135a58c9a61857e1fd4c6afa60b23d214f58a968d31486c57d483dfcf7a59d49039bca4d0a7b3469eb47cb2db77dd9fcaec9d906bd206fad6533efe9b06a39e61dc1e901fe552fa086fde96f03e58cf3d6b65bf1c4eb9a8b48b218189ff4b0008c99aed899a787cc0d4ad447093db347161ce79d1de880d653b1380b4ff\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 58c3e57605deefef20c57f260b790664b8b215b3dc82d33177b8054e5a990df72fb27c3e7554f76ca5e42ee8b2eee410a6a6c8eea3634a527232d6c8098056bdbdf90feab1d123e22f8fea82f42f9b4c8d65f5febd38fb8357b295586d63c3fe689f89695638679ec3807c76e097a76be05720320a525c3911602704382854c0222e2a51384a08b98df7eed637a5dfcbb8c49156848cfa4b8b36f00562f4ceb5d7e7c6237d9d0c1dcffe3847605d1607c1665e956666b4a28df99fd7342336ba119556c6c7b162208f160ce950e7ff41c6452bedcfd5eede9bd34da77749b8df8c6925e24ebb04175611f0027253e7ceb028c6fcc82d87fbee1e2017ea43b6a3\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 8ddfa621e73504de33ee75ca1498cd7daa0fa625b7dea0756392f2421cc84ce10f0032632bd7d2b74c60d55fd2278bb86185af3c187953ebf6415f643974e53d34d8cfafecafd20dc4767001fccbd197a38222dcb1dba53ac8fea54427bbfc25a858e52b1b2f8a778b1034318c5f76d0f81b91267a4e37ee7014e50753956740c33796f8161fa72899c00643c010314440f026bed963bc3b5362124f2e31221151dd6273a28b21c3955ef6bfbe48eeca51f454173d01f7d4dded623fd2ee69442affbad43a648c82c99e8bd05affcd805814dc1e1f96f301421ed9ef6a3ec2c6bd6af61d5cdbae31acd48218badc1da7d14c07f018edaec3537d4462999550ef\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 53385d184121d3b7cb41d86ae31d9945bf8057e126c847b69d2799eaffc133877a51cf8196ed85e3d22e37c1f7df932f796753798abe3d3b08b03b5574ea201eb6caab2dd1a6e112fc75c92285243bc3ffc7bb20e8b1bd872c55c6f1e4935582b2653cfb7e1cd343429d693589b516c8381b324e27d16ea1569930295fbcd94c8a75f2d0d380006f0ba9702b2089394d678065540de715c7219dc16897201d61cc0ddeb2148ae691e92348c91e9c45118ce9a3d5d10edbc2081918e879c7234be129b480d5c46b5490eaef51d3e38403a36baa961d4d0e4dc9a045342488abaad93666a41bbf90039ab189b6b9cdabdd00e11fe0bdc9d52cfff469aba22080a7\n\n[e = 03]\n[keyAsn = 308201080282010100f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d00308201080282010100f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f020103]\n[keysize = 2048]\n[n = 00f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f]\n[sha = SHA-512]\n\n# tcId = 240\n# short signature\nmsg = 38343432\nresult = acceptable\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e7a1269086f0bbc0778ded8d7108ff4edcc2313425088117b2d5c53e9d9971950a5fe8b2b67d2bcd1be74f6b557a3f90650a96d7e4dbd63c05b94f73337eea682417c058d66ce523e4461065ac8ba990c4ecd04932\nflags = SmallPublicKey\n\n", }; -static const size_t kLen169 = 208470; +static const size_t kLen223 = 208470; -static const char *kData169[] = { +static const char *kData223[] = { "# Imported from Wycheproof's rsa_signature_3072_sha256_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082018a0282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b12030203010001]\n[keyDer = 308201a2300d06092a864886f70d01010105000382018f003082018a0282018100c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b12030203010001]\n[keysize = 3072]\n[n = 00c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1203]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 157ffb942b1363b5989ec4beb93fb0187ef016de4ce055620825d13c3dafd4fff621c71920e884ba28c5e98b328baac29ad4bfc4d2cae2f0ecb9d1b6c9fbdfc385aa565aaf6c5b3150e085e0316e21d7d440a873074e5d2700d961114ed420478647a4769d832691f7a004d934a89dc249c9343341902d5d0c3d1a623001265634216beacd5f756821f21c3b58111790657690918a2eafa9e85ab1ee44edd3d8bb89e892acf411ba9eaaeef88eca37dffbda72751c117364fd1b38c840d7b42318fcd011a4449aeffc2de32836d3a4f704d4c8ad4e078315d0d1758f098f2ea749ccce62aac592ac4041b5e733ba0431b88332a39a2af7f68f9bb1f469a793b280b964f285ce5cd1ff3adcd7dbd464a7c9414ed45791073f08415be2dd9f01dc2fec8c3a26fe97d9778e2b2fccf71a1ea5e9ce017d2d46778d7e37bb832ebd5825b3257a7852db5cb6c132bcf9ba3522a670b0e866585444ed3601fd32a922818ef6611626eee3ea99cfcfeeaa4c370567cc65e0479bd35e091b772d7445cade\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 631cb4bed6b79dcd3827879f6d64de3ae17e0fdb022be013e733bbfe0031cf204f0508ab87a2e2bbdfaa16cf24acc96b3fd2e72bc4a224428e515d6f1e0ea6927eba6ed7282a959e5df5e52eb3be9a39cfe139ea2fa45c21eb81b3197eff655b918f7c5fff6abab33945557a922063f9600a372ae7701db686f7e1fe4a6e804a0f624331fbb59536733bed3710dcacd22ec74b1a1386d045372853cac91130703ecafad7f6f42ec1aade5cb865339743c83e882f248b0db0855f487a6d3b55442f67773611a11813ff46a58c762b1bd70b5e870c3095507f23758e90b3c84526f47a825f0ae787acfd3ed349ca6786a2e84ec500c6042a9027a994c328c7a6868e6a81481b294383edda62773fd224af46e782ea3f00468515f6100486d94e818afca1bdb81851e62b3bf4f9236f061afafb3e399b93e6f6a295ae200c9bba5ff5aabcac8361c84f2e69aff8a8a21720b900d52ea4bddcfbaba3a231bb9b0dd48f0a4ef1cdd255b3524ca0633d04907ab672314c5e3173108313ff4a97df3772\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 5819a699691c01a7f35f0bb1831a1cb65631ef693f7c9ef89f1e8460ee2ec312f6fd38fe382b3bf4db8f5d208146c32c5ed2d3b13105743767a73529bfddb5753c8cc13148d41db97f69ea1dee0ef1e1de990ff565f633bd3cfd315a7dafc70aa7f27d4f6486a2f1e2711e7919c5c73c518069338c0ac984d75f58b00fb0eee0f7da6c9c84d97955137417df8f20c02b7893b5cd929ba37f6b3278a1bd35748e14086c5f7100abf2edebeab5f767bb83d999a61cc27531bb67e44a92004fba9944b9c5f770bc66671d2efc74e01fbbd2885c5175a1fd72b91937c324b8d99d3592bfb73efb9641b87949266de441b61d180e141de510ae0cdefc2160df918c08c53799f050ca4eeb3a8b6b5ed35b8b59d3acd13a600a8a137eb1b8c1abbf55f3e99cf52d7092d1e3acc08583b04aa25a052668bc982abf060ffb17c1782daf76fbd69e7fc9510c5c6a68bd525719be5b81d0f2a8b961f1aeac7dc13aeeeef9986c7a47b34f8b96167d79f7ec458fef7345c1c31bba599d09b3fe33e738bc7da1\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 636d31d8d5dfe0fc6ab01ef2ccd4602dfea62d386b002c429e7e846e7a98d0cb1d448d25be039d5158887ab46a9dd49c41537a89036a065fc10329df051e5f2e5c1d4436e84790ff6db4d3f31575e5f0fbdfcaee625722c5492fceaa3fb29d0a865200dec06e117b04753ca9450a7ca7f7d1a1176cc38ecab721864413a0d7a22d8fc1595b6cd0032fbf154fbbb31b56d3bf963761ce8ec9fb38bba3419716d0d39e976857e79b1faefd5f5a2ce0ebd94968da1ec3a387804694d90f37b34033c7f70ccfb26beffaafb7bf56c1b8385d489217458e0a68b5d680f9fa45382fd1c227ff3c11e3ec82426ec648a564f0e886e5b12e695dd2fc8465bd9d08731fb140084c79be64d915bcb4ba10f1edb4c37e35231753be2d9f339d37d7b5f22c91584a68a973f9cc469a23d3b5800157dbd72a8405fef4e444ff01f7fd23efa143c1887504e81773743843d8a73209a1deb66c5f305df539bc30e871332e82330e5b66fa6ea253b2b64b4c9781011d20e80ddd8cb83916834eb8fa696b0a4b6bcd\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 08e0ae3dc0d16c927c423f12a87313afd1d66fbd5d09f48a4dd1a8b52102bbdd208284cdd692932869803a5c7f041a4492ac2e664bb6dd981c370e0c79ee3f7c5c6dd37018986fc2cc618139fe3eb85c0616f0673403c4afe7cbca49c1eff27bbf6d7e541b285ffff20b80bf61dcebcc4250068e25ef5a8e7c3306e49fcc2a1ee0f500a3ec603b472082f12ce4a6a12a6ac66cd4da8b6efac0796e9dcdc66c095a6282ae9a32ad274efe63f43e725410e6ed4c480828ed876b76b71b1cb8c142d0c7a51dc202af796d7bb55cf544dbde2f564f31994911ec7307015b0da2c51abe265a04a74b9afd0791a68e725cd7d8b473296c5d948157c10bc4682f74d843ce72e9ee8719a7a49d9de2f982c5d4490451eaed62c305eae3d0f9cb3493bff056a0dbca8579b7b41dc8deb1becfd5abb455634569d58c5b5535ff1356ccfaddd14e0f9f7f69a7ae9cb9f4c0c9f661fde349facd21f0021423d3a9ee5031855dd242f27009090ff0c15d1655317383231799b18c01fad231385aa5020990f41e\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 9858e2557c6b99fbd84bc7eac3e31283a4efb351ff019343760a1e282368938e29ad902d3eb6cb29b35a036dfbcc7e06d2f1d15548df59ced35326295375bacd7a9d28a01b4e8acfb676d80b6295e19c6b7a259df56456e1df72f6a746e9cd31fed9b79b35d7a30a7aa257e9e8ac60ea886042b9194e7a383d1c9f71c84511faf6c96f7ae0e690112b26bb60cf7bb10f684e4fbe2a3a1b1c0caa9b1bdc79fde23fb758c2ba57880a4de461ecd2bc696689438183e2b9724fa68258f461bb4405425620a4d95c87ddd83e04be381bc743b05d26ede2ceff8a858636baadf56ef1dab54080da0f516307c579833717def053c8906d4f102448ab22693e7f52d5850193a40ccf0d68d1303953771a73924e4bcddd8486e1477d96250bf6b480a5f4b822822183694c52a2edacb331564444f0335d3b17d511ece59889b6d961767a3192d7f081caf7e671addb3757451776d4bd3b03f7b689843dcd59019ae4f292dba54738a88b86cc6ce3b123c61a446f4878b627a7f3585d8ab7bca9b258f10b\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 1294490626bdb36a31c93fa7853d93152d920b022f1b473bde3083a99e11aeba8c03218fa07d6c4a5f8b2504d2cb54505c40130fef5a2412f7a5ddfec5e2c8b5058f7cbde7ace0ac01c7ba8a1bd897e8974d991ad2b95c2f03100a34ff408a788c70ab5ec73b5356a4e3c7beb44fcb9e2f3f25d1c974ed962b148167684351dc2a223a174c9744b092071d58dfd39c38364f47d292651e7806ad7962bbedb64739d7ea298f0254244790e3971c15b861c95f00f65532aa1c77fba5c04ad078525128e92ed2b4f1269ae744547e3efd4ebb63e9df844df152a098c47fa492bfe0f1917ec973867c7491f64c1", "72cf3ea1bc3f97b42a397e6ad88d12e150d3dbe360071a3285d6a68ee6e736eb4d7d637c649c2f545259ecd430b25b38a1618d69a4602ca8a2a151066f12c3807f5dc7cbd06bf095711e4483cb0a89c26dd9e4b0b03e05beca349f601c894f9a245aca3204584a9bd844772dd87b83d481c8df18b615307eaf643cbe856488c160e077458e899755301749d2d27bc190d68a5da11\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 8b889902d581f3be759dab7e53cf3419d5dcfc825d203c736a374f37ac5570da2b87239c938bd299691a46387fb47ca656bb9ab639f6736207e19680ad1a0c7a7818f2498ec98e4693c51bfe414fcecff4bae7afc6db0d72cb9dc447e2ce4ce9ff435b9daa98cb125d77b7c7d2fe2e39ba15122da11bf19d341b9878de33d3cc134bcb77b9963d19a3037a67458b17eec462eb0d7eb7ce69b71f41287d3b104b45757c76440f370dedb720a0c721c08c055c5b815650737fa478898246d36f7722e913c0913612e753908400bf6b456f269538102b778257af0c7c14339d0ae1ddcbaa357369a065c0b3627cade311a627e1e3179514cd3761463eab7f9485f6651793cdff282daba9b16c2f79adbd24ba54ce4890a9685ca78d73e8785d722825c9fd22ff327b97f38d5e0b95f449928114ee9756aef5213eb95cc40774fa1733fd02bf37cf5243e7ca76f88e7e3fa8d28a754b5adaedf31a91e6911688a6149ecb52eab8024e72e1bc3a98579d9eb242e08fc42bd491e3b0924b03fb95bd1d\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 46da0267738cab66df530dbea6fbbebbe904ad3d6ea7e7a06e39a3b5f3e38bf5856624185080fc756941b226a52c8e6126d07714deb781f6f7944f47147c680aeb0dce310c7d6f429429ac73e562510678c23042b635116174a2c2f4e8e8becfee1e4ba3cfbf4e2ee541c7f7c27b1916a2aa165cdeeaafb9f81c84e9754d196c3a9bdc777fc55d86b6bbd16270bc4d3cc75c2960f2a7a661105184b436a31de2cefad722a14abc1cd2f2c75738b2c81580fecff78d7d385b20d1a03d4aa2c21a168e13da18fd628e34be16d821b48136b6dcf7594ab3e1243c0a2a9e785fe40436cc6fc460879b673b068cd35a9114b59c2dc61fb875310e103610b74aa5e3620c51a257dcc3b9b0adbe774426ede0f779ea9d370f18a19d8844ed9f5d90ebfc4e0607a467645711da2b500840d4851e3de63723283bda8d08acc51a012699df0e8f5aabe269206f93ba4ca6597e17cdc01d2ead46b5dd2433b82237da01518ee3168b133b6a42e9a73194fcf9162b71d08528254c34b20d692e141c657c969d\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 39c1fd7fd0bc4578c3370787ea5a133e8a34ec9702dc1456c1ca7f8c3cda7bdcb8beed72e4098de5ab3e467f325141a324ff55af1390ff6f3d0cdf680f4319378f099604c9044025e04ed1af1ba5c74805265d8963684c7555cb835e8b1bfc162812698679e47b96744809002c805b75bcc5233f378fdfdf3e56593bfd6b0228f416f58b4c32ec0c2d32fe113cf7f3c347425b69e8bda1a2c5bbc3cfd0c1bbc609086d91175fab0adf050a8b3e904fc4a700d747500433fb72c55cdc25bd283d1bfa1db93604f18b8960127e9b7080227235e6ce234880de8e3c49d5edfa205140b8ea383e546e0bbd4c5dc59d0c058670ed91a02a3bee241ccceac20d434a442bf35ec6d5922196d78b080b1c14aca63b827434679d7b6e666db10dd9a85b2da60c6b47fc97979974f11b6051fe9378d96c78328ccf4e5cf5c120c2641b3f6b7abdfd0832fbcf59fd3787100032ae65aef2b076631788e7be1019feed9b863f39759525be659f3ec50dd7e9724bf6d09d8b771bc60e8a8e788ced8d945c89ab\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 530bfb86fd2a4b31587767d5809e5ec2002cbdd9121e135391392c242354844a9b4c8993ae61bd85810a0ed240203cc4be48ded5997832570875a7b775206460067b30df7c3b7f7af9d98e436f0007ce0d6360de0c1a4e75912b885d1154ebc25df90465ecb5f07a6cc477e44d3579f3a629bb49b7a19a619f44e6b630b684f3ac4daee5eb386dea0386593be825a696656e130ec0e4a4bd5411c45ade6ddb4a6284f343b0a746bbaeaf03cef31120f19f2845dd9a7fb818406b0cba91598ece880836e0b17e6f375b8941381d0b301d0ed1bf746c992649b40899d2ed2b39d488981970cea6da2453b5fc85f23c8d671a3c7544f4a7133fb500f5448da44d4c405bb70e85aa3aa399204148c01d1a79de3f784dc5a9141dcb41872461e62deca48dc567b984ee80097a099290e413e575411faa54f7f3387cd7759f71b8013ddcf9ff2079503ef802c54fb731e3131316c93182dead523f41551bdd3a96a4261bf6c3dc72a952ed4b7cc95d116741c653494b5ba8ed9aa565ee57ad22a4dc83\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 94e0075930de07ea37f0eca5023be15c472a674513654d837befcf17765225c73d17e93ac4c69d855027747c7ab81c6bfb3080ccd5b6dbdd41e2ea4871fe30131bf2dbc143ddad0292dd4156c60cfe5172fd9703729daf99b2067334af23a2aaffd0f74d574955c406ef8ccb1796189c140d1a45701c993737b9de11e44112c4df9a5b2c7ac827c9329c5f63f4bd740f3f1baf69a8fb6b69ddf500272beccfc2f24902c592b91de99783242fbe9767f3809b38368f04b02d973c761fd999b0c69eab43a2187d6de4fe5455e070e20bec5bcb8ffa5e439b04e3883804a5dbeeae652260a405ef5e2e6b9b7bf7e8018065a900cd831b05674a093650644c42341c3f5429d59fa3aa93737a6b525a80e0748518cfe19e6a4de792d3bf842e2a864f04da31a8ecd0b191ea656f1c2987a1973ba1b10e16b09524a3cd07c96814b395b29ae1a434e76bde8e0b6e4e29ea3c6871ca447fddf077f53a4c2c3499c7e96dc6de112cf28ba83d8d274ec03fcd1d570b74e22ddddece554b7645380a2a7483\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3e65342b3d9322ee9b0473f54f0c3be5a17f56f2cfa5a8168bcf3001ca1256be867d3a575b07c3d7d020037590aa10d75dd764a1d57a123976116286ced29b68e3b625c3ce0c235a629e27e4f8011afe4b383117a8bfc927a7718bd81ec4a156ef6ec5cb206c2f23941b595ab3e8e4a3eed825c8e2af444cc7b0ae0e303c8f109cc149fed6e8a2679c55a2f483dc64642170d0f62f0f20a5387a80c5ee3e72d275a8c3e18c65de6f9af8a7ce886b83d84cd0270bddbca64db5d6de42619ab0f37ec18594a09a80c0183d44dd3ec6b46ca4846daab73effe1d5e2d8ce302db26708ae9223369ba5c488bd11ad27751abbf994e2bd18cc999dfff0f65e8c6d6d04e229252a5d6704483458d7d094dfdc96cd5a7b0573a2e0b50fc14a8d291fc856e63d82343534b75b25298c6ab7af401ce1215cebedf87635ec80d0cc228831d26c40efa5997105fe4b3786d0a44c17be443a67181d35a5ee56da18b7e97db573879686a406c3bf340851d12d8ed57c0530433d655aea85eb3211bb7f128c91c0\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a7ecbb2fac0916fc1bc793f4503d496cf2683d1529632eaeeee4fc89bb8174e7797a8d78faa95a52da0c4c887585d61c680fc4d1224e02d3a0dd2b33031120a14be8ad16e267656c683c179d261f6aa6089a14122168748a4bfccb59ecb086c0b7edd342bc61d2a9a2f5aab2f4558d458971ca04672e513d3db5784db83fdb93816bf8f1b443470973d96ed20a7d85adf93bcb497ae07022db0f939028b9387a1d448b3fab2408c2754478621640cae0ee6af76fb6e653e4d418e83d431f7967e435b748e8c7a26384addf77115e0dbbf7cb5be6ec0d11b183edd6def81d0554a2e7fffe692e3cdaa6c138cd73bff960f047c0226ff0ce1abf9d16ecca4c3b998ae8ab1fd1e35f80b04979ecf0338497d1df5cea3108bdcb1d0bbb6636ae234cd81e6f2df123d263ae38924783a2a11c85b7605808e84433dfd72d9ae5b9d82fc6a8cf385b0994d32afabf3ba62e8578ffac2073d81d69c808a2c9f46b1115ce7f26885d1be3052ca23e2cfd05e92469795bbb274c4cca1b992612d0610c27f0\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 7c2c6b135814accef0caafe8a22b8cbdb832a30c997edfd33e01a9578e309988322f08c64704080dbec0469274fcbfb131b4388cc1181ae2004a63cfec1080087dbd3b9e7409fc0f960ca721d456755f1bce99bc91ba36c65e747e4cb693ec4253f0ca37d8b9d64d5f7d0526ab809a4f476e6537263adc00f20d4261d78e5b6f22896706c665e885d5283716dd959400d2a7cb35974a3a3adb1a4bf3bf36e9773ca539787c0f6a05d17b75837452e247f065803513eb8c6c995e989a52a5d48bec77930a91cdfc1f373c58b344cb1700b7707a1801a758246267c8ce932035f8a93241f57e9ea8c4d2dab3ff4c5fe06caf37e5c996e60e7bcc4f3a6176a69e61df24f8cc080b7489bfd8395d30b6a4cde92ede49a26a0a03c766cef25ca6bf982fc3126ed7b1b1b2bf4a7ad9ddbe1a3a456a6720953460cebe6e1bd5c333b9ab2812f9b47452b2759436137424832753d8a97fd456603c5585620342fa1dd056be6247297d5758529c152d24fa2644e613244dbb66815278385be78cfa4224b5\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 27b9f6f0a34cfa0a71fe15c15c910b7c8f2096225213e7021649aa3689ccccd5e2041578ab5be9d110a05456fdc516c5675561dc82a23fca94cd66df6dbd4b0805ab85b57734f5dd2d6efcb1a0bd8c3da6f8ae7a68f54e015a324212b916a0eae4095975f76f509ea383edc4fd888217abb893693f821f4a3c72dff39dfb0fa7abace8c16151d01bb81be374122f0e479748df2c82ec87b443325ba908bd00b2cab985e64c7f6a1edc62787c64b84410d93ffaf6d9a33bf3164e4348d7e1afeb6cc7d3e8a51d723ba6ff27ff5ef1358001ffb8eaf651cf48ca5534bf5d86650e73b540226fc2a2c1a7c52e6003d89a108a65e1c9df183b47d1753ea697f05e77b3a13cbeba8daf25683a6bd423b2b7acefa66eb5e6d08ac1984007aedb7df5d4fa1da1aa3c6ea5f383571aebfa42ae1d42060d996cd9dcbcbfa605f002dd7ae653e7c295eb3c3d03c9f6c479068456a8b0087f0c61492ff7c125e3bffe30cc45a136d72c75b047b246dba18ebb41f3fb9ad0216a09d888885b4402200291e6f1\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 39c7a8c06ac4835655fa719be214556e0adc5a00ab466d88d33e694c30882e7c41", "d7fdefde724fb8255a44ec4bdbbd03d1ed528b4ea980bde20717349c0f2eb78141ed6f4490173e62cb2c48b76357c7816d1b0eb5f85391143d04cf6a100ed6917c46ec661a35860b3210ebf71bd7e6b8e4b8909914226ebe925c99a7a5a66f1d02c876f25d80ad4482899193d9a444a8a1d0ad8d5afa912b53995dc36ea89599f4f181241a6f4fbe698de8c7c794a82f1f576c255e701751d3815f5b6fe93efe9a678d2422ec9a4a5d090beef2e552db07a4d146f90bb4cdf1ea6fb844ffa1948542bdaaece102fa3359d2bd23c6447ddd64dfd7e4c94c801c2b6ae17b07b07a4dc79bd69ce5ec46aca637845a0185a372feb8adb7d60996133b9c37c32a9ad869ff5534f39aad8701e3487e1e6c8fb9ddaf71a1c34374a09ffb85fe44790ddea79439bae8eb51ce12e5abed6af335ad1ddbda07a8507b6df0d0f3ce80dec487968d29d92a139eb1d5ede5c28240320c5ad9cd0edefb69fd156f0626f6d45d\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 4c8a79462d5c62f418c83b35e67899db78b04883afddd506855ba23e7ef8c5336c1492faeaf1d57444d1049bd008c317fe7249d5decc09fb4f39d7858edd097c3949c53bca1a439674a61b355ff5a9388a60b7d5c7255961af7079e72c07fade552d0b77c36ea3d2f0c7c9985b8ce478df8658de208dbf4690299db7f1d32660585b918af94bbedbbde7ae9444972abcca2f6b3c4004e3c87940793f1a625d932ba14e715dc1b5f9231e0f34956b2920eaced888b3a320ec8376b059fd48ff369beb1ebfd32b9e9c9623d28b54856919b3af12239df425a055cf43e448541af94b88a223a90580977a72782b831ba0a88877cad65f8fb49c68d5e3b2f6224637e61f4b356fda8b8ab916cc31b18e6f92d33e0e27971a480491fde857715cc55388b281e7d313ebb0abe3337f7d4544ef9d144e402f49c2b71eed30f8ffe8e600c31de5960947bb07fcc4e15ac0d7bf00bee0920c9f092c8bed16ad9ab7d752433a96dbe49ac2cf33445257a51dd347dd77dd5ae0d08b223c457db3b57d727f52\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 93391857ce1fae6df31b1ad972189803a1fc3ae91b89a264ff86246d6efbdc599003bb7c35814a4215dfdd3932834d4064b497f464fa93054363f1fa5e365825d1b87881e125a50deaf22d75aae32fc0fe1e8f3115f7cab6af0c2aca54d6f21f5a72fa77a0731c9f8ea82ac2e31155fe56a7950f61fc1b22c274203ea91b28a4bba0a925ecaaa017b9258e1d0f492c24336334e328054a12df916e1e4108d0b7e5d8b2bdb3d4a10282cc1653b9df2a24a7ecbd753cc7677c88c2acb7f741e3d56d670c226a827fd6b19aefa445bd277eed60dd13619427a048616dd26770ce76a3031bf5856b50f0ceacc7bbef257d86f6e9fae62aa6af550c9d526a6076d1de77a9097acc15728cbab9fedd1428c33a89e07c0a49dc89822558da1da6db6f8f738ae309fec8f033ceda8773ed3eb5bf6203fed189c3b7a774cc5f44073dd0db9e4a614bf7c8005d5c6e022fda36b82dcfe66f4679eea23269ff39213851798e63e42c1ec5be20b3cb5e20787597b43248d4fadd1c10cc94d066639736b7781e\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 1d9a1575ce2cd06e5f160063d03199cac5e912cea51439f738d98ede05aaf7b821d8b26082ecaf4d12fd01d0f64be9ea2e1831388cdb5e7c7564b73146de8f9b5314ad6738d98e1053ad0d7d594425043ece575c75128888d0d7b090ba5d5e008be46abadbea23c9b7741a023151ef281d99fdfd684408992a8aa9f2c85376a40e53d9d223ef4ced563fca832ef03bef29a47bf381eb6728830ba37c69a99568494efc85370e8e9c3fcaace1a59d6c98afd03a0e8bd5da2f5c909df5710e385ceac35ab0fab92a6cd918ca8d32cd5d4bfee5dd644e0adb3d188a5d0e7a20a305bda34ec10bb65c922a0c074e8427cec78a590c095a0c670cea6d34bc7a88b2f1f06b00b368b8009cbfe6a14b18bdf2b01caab7041d46e6b76fbb1f63e9b309f60fdb4f1a6033a11dd7dc1eb15d7faf922b3fdde28796c44e226633813a969ae1fc54388525d0a125414060862718bd0ee1337de2133fc773d06bf83987a22e4d2e883765e3affe55ff8d92771da79ea0898258f0d7e858fa3937ff24f122669d\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = c0177318feee842e802480dbe0dcfc6215d75431a30bb8492cfb1cb84f7ebc73dc37f56cd0dbca1f6a6516c6eee3de3addbcbd569bbc79d533a4f5955d95babc717cd4c8f5039ce49ce7dd20aa44bdb96a394f8499172079f8ed20c4ed780ffbe11cb00d04aeab80c882eac517c153993892549f2d4203d8e3fdc719fd745b06103b49f54ad51b6dfd0f4c94b08b7059875073ac11701e16af0b73d7b305d9a420fcb560b490d01c4afcc52b9b21a467e95bce62da8f559527066116c602bbcc29a434ca04ea3227a25a07d733f1b867040ad1c85b001904c749505166635c217d8858e637cbd74ebd1b86a400961f2713cd00e64947c2b5d2b97a4ef795822eae56328bc4bf8e8c9c8bb8d759a3743cbe9d368d985299d8338796ad6e24df7eb7db18147450d2db91000c8667681b47aa9f0f2e08b48aebadaeeca32976dd03ba94ae72950803a07f566e091670c83c8ad01cf1a2a921467010c20975e1b9653a7b56d2137799eee863a576a2275c33320445307670bc62fa039c7cdc8094c1\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 5675e16b96e961dd428de891451ed0d23706165d65392d277eaf846e24f0c4388536b2b52e519c07d0e10686a164bed5a05314249a77f77d140dd16d42fba947bbed204ef4c8a958e49f3aa4e62438ee333812d6a9719ff166839e467080d8762a4268fb575a33070209013741ae8ea0c757bb44d12450579ac8e22870569c6892edf1fdd0bc12a7823b695c4c90e93c3cea57c2fa004eb3306d13ba60cfa7aa3f1465a232c3f4cbb765a82bd59551d0f130137829871bd35cea7c59cfa12f188c91dfc214d8102810a7deccce40f204562993633ba4669f4d7d02418d5a66db59af8ad001884969b8e00951492bd846ad7db619d623b3466cfa062ae9282a1cddf150e761c90a3413e92f2f1fb2b5b62d410cdaf6bd8885d635f05f20331416fc3808fccd342764b7c244c1aaf78fa7a1166b1b204058a16ab750ac3fafbafdb2610f52164f75e7cff8a4c3cb899ebd5fbe1834682ee94e6cd810a4015ed7f0fea7f1494c5a477b572d172056629320307e8ece3f72de5dc0652e688d79d154\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 562cb29e3b27d68a9f8741a57006296a943bee15c1e0cff97e8748ad822a321234a15fb3b89f4e07c1756d693507461172981189e9191e0175c71accbc258d3e79bbc627365c95f19fa416aaabf223bf22fbfd46cb8022a88600fdaf84aee70e9c8939e24de4e8a5fb2536c4fda5e3e3d71adc377708c1f4d7982c0c2267265d4f85d9e27f689de2c216a21239d6d4f95dd30ce102da43ec1b3e72ee5696db8c63cf06d94b8ccba75e197b2d26350d35336475f66de615daf8c1900ba37d7699ea881c0f7af84e936c402c08e15d3923733aad0894b4e78216225911ceae7f4c770a17d90fd7178a196050bef7218d7e0fe7fd22eb5c3854c806a5cd179e3a82b59d9b4e9e2dd1d4cd998ed32ffbf19a91cb19149c948b74861fd0e92174c2f35c82c9232a8413adeee723fe489dffc8aded50c7716403c02549802e083f16584b05e3f67a4e726dd8ec6d4adcfedc0695a47ab75e6d0b0486e946b6485f89162349eeeb88f20dc3095ec5f45bae1c2b7af4352138e864e6fec18b9bbe98fbf4\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 2302f69cbfe30dbdfb830918913fb556f2634e268210efcd0afff8bc527fe30ea1dc36833b01fc1b7b1d8781913a5004a24c2412b9e0713b84f228b6b08349eaec2ac6908861157576c89bcf472572be53c0075e48534d335b954f46aa456c90653912e07137a418f8eb59329996e86fbcab8e585d80b7a8f97e7aacad3d08d24dbe30a76ef8f47788d36926e74c0f24df942f73fbdfd649ffe9a952acddf3fd8ed9aad055c3a950e749dfce25d0c45114f40dae0a449f23d7915dea8ee1f6f163849affa4b7b8105badbbffc5690190fce192f4a647b81b14101b4fd9b1f0379b08379901f0908ccb48d5c88e8a3d0b6563bf01117ebcecbd84dd61e6bf05b77dd2a3c63d9c36a394843df28b8184de81cde4f381eea84822002008938d3549550cdeafe31606fcc282ef2c2a4ab90b437d0975a6d576fb705e26131bd07add5bcd34887496b653f3e9c2a7760eb367935cc8052ea896c6f2023f0d2a5bf3267835cb4adb079019b8974426953ef1447069a79cdb51fe8c32fff14a9bb8f78e\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 92218f94fc3552f215e98d21758992429cb17fc3313f780feea3f482d0e32cf97fc8832205e74286e69a1fa35062b984635687692d15e6050376afd8e8501b4a07e8c61006a2fa6eb27e2a4c310f54b907808027eaf9cb0530f8ade781c4fa9095a41bb6630c1e0973783eab65cb0849f9c8e89f3c997ea3ab930b4fc629028dda3d5e0e7dcd99b2951282c31b8e3739b6724a414dbc254802e63a1a6a268e7fc6a91934cbb27d9cf0ec994fd02334a7451c3658e7ab13aa5dd27e81736c9cb316679eb9a3d3f87c3739ca07a7be08a0402ab2883d860867a4eccd2476c8d9e37e2ec214d6895664bdda7ce7344c95622791cdfaca32508c8b7388391846b720659de2aea7bbb84520fae9edea66638270e735677f175f115c582f8d76185e8edb3d105e3d6c0f490ec486f7ba41f750add6d50997ec85ed351a2b14a4c328a41faf70ff3e50fd4ddfae6f9c74fd72a7c1bc0df045e31fd72f04b6a797e0cced07bf2fce788d75ef6d783cd6e4eff98c49e99487c76ccd4e08ea26d36c29aae1\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 55a36002b43d9b5a2f99ba0acf767cb04b54b7849fc2443d123bae5b6c6b6fb666d7ffb96e09580462df5fc560cbe9744c166f8f43be98b7b61ab71b86323d771eb6aed87ca4261b4e4d76af84813173c01cd82a87fda653c47f3700fc2110a852def8c785da96dbc779615335ec871a31ac3590562e8f50972b5e217d45089a217e8b0b1905693e7dcd121542d11c0083b967b04a8927211ce89262329ba2f7875412b8785ebe47693b8f3b76f98192bdadd3f4359999d48d751290e87264a5f2e53ef5814225931b253b451a3246f22ee3fc7295806ead7992bee92e74b19dba84b1228a8fcec6fc0729f4840d2b467956f86a916129c57025c7465fbfd760e0ddfb480f74", @@ -4223,9 +4861,9 @@ static const char *kData169[] = { "fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b12030000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1202\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = c6fe23792566023c265287c5ac6f71541c0994d11d059ee6403986efa21c24b51bd91d8862f9df79a4e328e3e27c83df260b25a9b43420affc44b51e8d7525b6f29c372a405104732007527a62ed82fac73f4892a80e09682a41a58cd347017f3be7d801334f92d9321aafd53b51bffabfc752cfccae0b1ee03bdaff9e428cc1c117f1ac96b4fe23f8c23e6381186a66fd59289339ae55c4bcdadbff84abdaa532240d4e1d28b2d0481dadd3b246557ca8fe18092817730b39e6ee378ffcc85b19ffdc916a9b991a6b66d4a9c7bab5f5e7a3722101142e7a4108c15d573b15289e07e46eaea07b42c2abcba330e99554b4656165bb4c0db2b6393a07eca575c51a93c4e15bdb0f747909447e3efe34c67ca8954b530e56a20a1b6d84d45ed1bcd3aa58ec06f184ee5857aaa819e1cca9a26f4e28d6b977d33916db9896d252d1afa762e287cb0d384cc75bfe53f4e922d02dd0a481c042e2d306b4b3c189371e575b25e0005a164cf69dd0976e4d5be476806ea6be6084e71ab4f5ac5c1b1204\n\n# tcId = 235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 4e28f546283f9ac74cc99c6bca79bc208e47220cfb0717aabc521ac55119ec6bbcac880bed0007c04eef92a24b091d9a09ee5d3b5be790abdb2c98a07313d505fc876adcbb1089026940e03dfc10fb46a0c2a764ebe86e51ecc2ab489f56daf38764fc0a36a9cb4529367c9880bfd7631c340fb7fbac0edd2e1def00d65bd52e597e2eba1be1e41bd89a00f5c66fbc18b93e9cc1b5be962780f6d7a9c6d375a28556114f37a8a3606dcd68c8128bf7a7e5f1205778bcf3048bd4f7c10cbdb4ae759954c4e4db0a9fe4df270c41bb86885dbdd8cb7e72a33322238a2d29615a2f01e9fc59c230c2cce58ad096c2de5071e020f76c8c39874f1de677dd5d2f96ab4dc145098d25b740b5279f05713daff54ba695f950039882059cfc2f86c35a0501b8d0914aa59a806e8d1403fb2eef163ba1d6e3d1e18dc99c622f8c2d360bfab2c9e8fd9d74a027e466fbcf4fa56777ee0fea7e04ae1901e65b5361f97146d7f4a550adf77539fabb7135967dc16f8ca99e8283dd69627cf27cb9d2df20bbbb\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 78d3509284dc06b54583e11ddf2507d9e50bdbf079fc319d107bc2527c1b742f4c759320fa22435d74e94253feb4a379128e7f33c5f3462fbfb92ff40c10b23f8bdc5890114757364207768014380fc16ebeaf22a7b1a9366f3fbbbb912347f1ef595d742a976b69377533e7b61d3237c3693cf43b34f92773497b8df7ac0660f67439aaa66fe179b34d9dd4d013e8fab958fbe2a27ce84b6d1c3c2998a50d41b6b38000191673c23792db2fe47e4ddd3b5396c65dc44812e55298b8b50b5a2a01d508b9d215986113b099717c3a4ee930f479308c20c26630aa5419c2589c8cbbafa7eaebd71fca9e751793629d767be8709fef9177d6631a48731f5e59fc7e98cd466375e8775ba935f12b45575819ecef4d78d85b6e984d90d41c93bb03c832fe415fb567a1d951f7dbdf407beef8caa3a741ca7c7729c8d8ba98896dbe52d9785feb49332e646771e7d84b75476aafa0a54512806339cb54ec1c70943beb508966741eba4d39c2fe535aa82a9cb92eec99d38540efa3e39fbc02d757ad74\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 8f9ac1354af4161d0e55b5674821d02823b3a6b3f79cefb98cbc77f9ac2d91cc6345f989a7828132f73f3630a247a936b6a057b3e5a2fda0c5999ea7721ee8880960c24cd2377e869cca1799747142d57ad6a8d83ec9254d89f591add11a758e1ea1e29bd08f624d0e28cea52ed5eed7c0f5f49d3533eb1cdbb2af837dc42942f9a86b5f4e2d5ce506697ef067a344949bdd89afcc25978af4d50c300bcd0ffc9d93cc559e3ae1a13215a1d3f6030827340c6591061a5ab7e65153b1df8b25e1421f924d39c7e6f76243c1bb9ae4063d9a475cd2ece45f4e288fe0720", "074e87868d70a5584a9ac2b47a56417cc76f15154315545a3ed6704b365f15d34320804469c3b09ed211cbc9e9e767b6f21fa16f8641d8b78b8dff8062a25b5bd3b6a38cb4706c42c1fbbe66db1c05cb57531132eb94fe1569735c33ec491c318a686c837ac810be4afff605f92bb390e7ab3cd24c0cd997cf13f112e5aa01746f43902432639e1eefcbd37b413c586f057bcba40a8f1251251e84cb7c87c53c1d1d558\n\n[e = 03]\n[keyAsn = 308201880282018100ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83020103]\n[keyDer = 308201a0300d06092a864886f70d01010105000382018d00308201880282018100ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83020103]\n[keysize = 3072]\n[n = 00ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83]\n[sha = SHA-256]\n\n# tcId = 239\n# short signature\nmsg = 34333630\nresult = acceptable\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011a21abeac8409398319e65c8656f8f72e179dd1e99358c7531fddc037e47c1e688cd70eafd6eea01c823516bc79f89d7e52ee1eb4ffdeaad1d550dc0a47185bc9c42e47fce5503c3370a60510f834b4691152ef668deca633cf3873ce6613951784aa7dafde118f37f1cdf1a687ac236d5c956bced564b73cf202e3bace59667\nflags = SmallPublicKey\n\n", }; -static const size_t kLen170 = 205965; +static const size_t kLen224 = 205965; -static const char *kData170[] = { +static const char *kData224[] = { "# Imported from Wycheproof's rsa_signature_3072_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082018a0282018100a07887f373378196b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d17690203010001]\n[keyDer = 308201a2300d06092a864886f70d01010105000382018f003082018a0282018100a07887f373378196b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d17690203010001]\n[keysize = 3072]\n[n = 00a07887f373378196b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d1769]\n[sha = SHA-384]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 473432cf11b6f96b1dd41e1742ace21cd10e8dad89a3e00ec68f3b45411059d0bbc6c8a3f077bfb4b12da60aca86dd856934061aa8e4c3221a019b7ed3d4e70ed8bf53fa140d3c31877a135a6ae140e021bea9408ee61fe7f32e60cd18932282b1aef1019f9a39789cb48991e535568b55eb26cf96e9bab35d03121f6be9f0d65079b064cff923edb5639cf08f48ecaec0670ab37b03e4cc2e604582e1cccef79f262c8b3d146887303c542ae7c455b0f68e882c5e2259ecd9f76cd3706e9894766089b267ed3bdec29df5b57e6a6f8deff21e093ce611724ba1012cf63aa2c62e7267af4b1df5ef030e6cba7b217d46fe43fab255f41ce086bec5e4f604718c95acdbd5c56bf8b68541ac0dde0a5e0f2336ea608864abdc5324b29b9f7bd35c514373efde38bb593b8d4b249535984662bf4b397b2a584ca15624416537320fdef81133d6038edd99ee19af9567c9fa536474effa925555c9c2fcea525fe2da935b791ec1d7d3bde33a58f80dd1e587e1c433239c65332e94d66d3c79bfd190\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 69d89aee9a1b9827228c40c3f3bdb9479ed36bedd2c77b3f5dca19917a5cde9636b9f6ede29718a391224ab58f464c9052b5e6786178194a90ec04d2d2b7513b19df2799b0e7a2d6d1ef2c49ec6870fb8cae45ee1103692da8d211bf61f656d304f69adf68c0227c7af5ceb8c2db4a3668bb6a1b8cc3a437b9df79bc0dd650d6e3a42295b4a6e23d40b3a9b7548f3760e0faf69200df230d2c143807b2f35fa449cfa73792844dff5d2ae50adc272c0dbacacd60eb0b7964012a5c1981cb2f358ff53509f90b0ec41259fef321e9a306a08363ed194e51ab6dbc00ceee576c048c02704a19f8f357250adc70cdd2819157d71af04ab0cc63ac9c6fa4b5799eae521e275f26ce53302017510826f96c4a2889deaef19fdedacc70a6598aa89e2bcf373239bed98d1f2267fa7c2436add13df68d9ea296fab52fed0f5ee46874f48735fe32c61ed2b1c977ff1862ccce093bdf7d84a6b03c3007c4c926d1e52d81dcc0bc2a553a12be363b764f6a322e41a8318ea7408c18e33c260aa05d039625\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 259332bd5a274bc347ffa3e8a31c8b27f216cc865d32c917a5d7e4c06abd44b6c024f44eba997862c812d8ebaf7caccbb234293178e44b2532478e8bebf6af5f83318ebe398e0850e929a89cda860cd18ec94554e4e0d45a9ec2d9acd83fbef2b5d31dd7b2f3c12e791afd3e39a9437fda7724c9426194bcfdc6bd52036f62aeea7853db2c8c498103eb60180281170aa0fae8139417974d917090dba8f9061665e92d953827dff4d450f5566d2c5b753b65c9b522a0c4da868629569a666b7c292b22060e92acf4ed65e51245403a4f162c8b504b85a810906ecaca2956d395c163a7f6f23573156968ecf62ef46b72b9ce39303681e354e91c5d7944cd3288b2a84a1ea28e7e6f260bc5f8d92be419ad649a8f55a2195ca46130922d82759f9bc030c8b122211d952c3ee7851f09f30c2fecd1070656c69c2598584b55cbe6567dd2719305dc52dfda03ea289a5db920fc2c777e7081cfd92864316d3fca9aaf8e2218ed8a5235e746e5cd9bcc856b0c615b901dc610f0193171869202e845\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 1f32b36eb43f87b18e569fcfe7021763bea0ca576cd273c0b20352906ed8484428d250241709c825704518ff9e97103bb70cd26f437f87754bd40407034a9653d00e868a759a190f3067ce5efce9ab17c8b46000d88e2d9e68b8dae0a0eaa4a31d3bb51c8c8d0fc839b0b273c83dad57016b1b5c1d8eccff1c753e5c6d189ed07b801f0a54a1144c142011fd3226451faea43d52597b003f9256cedb0d7d7f56d86dfeef50179a794f0b0de97da1926e9491f025bb3c3e8e031661e0ead860c8914f0b294bf8cfea2d5ccc726ad0743e192510732dc84301eee15eca3c6a5213ba66d0871789315f8537a44b727bd8a10d6e54636b345715fc0b6f5b5116f22557b0af9f948558b0ff4a3b0faf1de7da1965b977aaaf039c5b7b09b4f03efeeab3189d2a09fddc3983e4815df35ddd1c2198b695cffc35aa6662839f82468cb676b677d53ee4857ab9be7bd99e1749c811e2d6584427cbce14d2ca15df061165e85502420602666993463733b43c1c1ebae8d37780470b8cf5cae31cd7427799\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 7e3165358b5d09ab1ad1599935bbdab27abc32486910382a0ae630f725b5dca5ffaa9e606e2e555122c1e0f3409d7d915ea00d8784b814a6721d0dd117297c951c8d225a484a549e488fb80f996ad65490a09defb0b46f9cfca2e952b04dfd5418da920dfb2968e48dba8f0729b16fa32a832fd8b789bfebc63f01a1190813cfd55ace949d802afffbe9a1ec1e6a5df196e5ffb241c918d712e466f30c66c0bddd48b57ba4d0baa0c2ba9bcf519c3a26140df6aa5efbdd5ac9beff48613f92d247b35efbd6014f3d714705933e47d582f4a5da05b15a79bcacba1aa15a5fd6ddb228bbe4c5236f9ac607f41a492e6b1c92bd68ce30659eb5b27a5b2f76a5867dafbf85a9dfddfdd476c383fd03e38e81f2e1434553643e652cc006e5df7313272335f122a7fd9cae6f2f5a7da65865698d6d08d688000a730c90919e1826bfa1db85d5607ff9d76cb100ea1649442cefc4251a8cc1d823215e0ad1abfb2976bc4a6b2bbd793ebf9c7770957dba1e2a8583d9a82a072386d0957789b450993c77\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 8bc948c5c16603ab63e75e18bc7f062ea4c675ebf98dcacc1a9826b0eeab0004e2592b07525fca53bd288bb56b5961aea93b548771068f5b0cef467c387e2d62c91e045872922b516dd6c5b8ac3615c986a9c8b5211a05f63e82387175e8749709951273cd9d8b2eccf678284761c72285be5c189c4400629c26f87bf18ebfe5e56f2057fd91fc9209ec48a872d6d23bc330f1c81ede7fc5a0e2b09c3a4735eff9c8adf73152b3406a62656897c1eef075c4fb02244ecd93912dd36fbe0d358a71e02d2b302dbebd28ba50860e4a963071f0a890a2e400c18f530cf9440a897eb2781ceb17bbc58f61828a6456b93c86df972c42d082b913c4d8807b7563aafb7b330ec39dc988674a5c3b36f6bbdd096201f1c7c25ca9ea8f28e923ba46dbe93910268d6e35cfb605b92ecf98699ae9b09dd4634d1280586c5e6bb0b1a4b5e5e22b225453f5c66f9a7ed7fff83ecb201eb157c76c9beff95227b495c8516bbc7118f011cf9237b6e794bd7a9ba19e35d0a650dbf7c06a0c9ddc95f108a78246\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 09ee821221ce7bbeb4d66ea3ec88387bb5c5bfb055b8beb36ccba4c2ce9666b1a09935689db1cc2312d797ac8b6f62643de736f38269a81f969308eb616cf41960341fa8edd3501f4edf73736806b6fc1387df4ef3e1e26c03249f3db6471ed580699e8ac77d0fd9a78972347e8657b6cdfe172fda324eea00d60d38b47e066c4a6fc0e33f75d1d4ecdf46efd966ca9aef80d22e43dfc2cd0af37fa70d6df7c637c3c18a219bf58dc1e7bfc941a235bfe81ee7101530a2c264527608d7148dd91325b7895817ae50d774e8dcd2def8a476a9592d55be743c62c1192f0ad69981fdc8651c1db828097ff8088", "b720c637c60c771b5091f9d9e174bc823115a1f7dbf086f9ad36a403c2d710c47af4753fe6e43c675c30219abc2b8560bd18c25aac719546ce7a74080fcf22bd4e6cffc270e57baedcf2739c5cf4fc5fac18f5dd023301caac1b1faf4dcc65327255ccf54f5fbd3cf82801a8685c2eef3c5e7f608cf6f747b8307f617fce148347b76facf0e1f7895aeeb11e3225e3a6066a244ca\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 3b1a01f69afa77d96c1b7bfdff94d58e346746f3712b2bf2705d771b6ee082c7dd9d2c8a87de6a684177edd8038ea1b9bfdd6722a1453d68204e4d6effa584a1b9520561982f0181f102de2d62108418778b4976b4933a79c6a981bd48f84711a3f7cc26ddbf06c59aa669d56d60a741407f86e6a645dbdb1f7927dbc0acf996736899dd9aa367ec7bb157ed121da15f25bb21807293ccf6d3a66e18713d80763cd153cdef58b1e6e31b348cc514b8f2d357d14af7cbaae39993d7871bbd0cb9c136936b292dd368ef1d826000d3ca13ab48b659d231c95c02163d2e11e33152e69f6f3f08694918d89f9a04ad6a01c0887309654a4ea8a848422dc924f990cb65ba2550ce166b6a001cce4767a3f1cce74649876624d2a1111436a9a6b06dfdbafeaf329886d5e7482ce3e81a33b69a9fa7d82981aabd81c2650c3c2b34778f99efa2d3843b386c24377fe17483c490a63c6896212f8beeeee04a3959eeef47a00fec8061845d84fe7d7afa206074b41ff001be315a7e32c2cfabdc861eec45\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 7835e135188e97973f3cd0a05a102e888fa51ce232062c9856d134b30ff32b513093e07b7571b251f5b3618364b830b1af01169b0a19c203e079083c4ef85827f1a4095f0a6cfb9ea0c6ea4ad1bcbe27188f90b8c66a9ba0258d3baa49b97d0f8150370bbe9926e1471772f1f37dd85b37a5b9a4e15d32c02b427313407fa9ed693e0f444fc6f10dc1564072c360f9e5433fe985fa699860d6c9fc528aa82cd7b503854a975524b132eeed5f94015ed1b2d85d9dfc6b10b529e140bd611d316cb54f31f9d7d06b6deef9b63519c14ffe3d9694077bd0bbb3482b09a490b10ca2c6b510532f38dc2bfce51cfbf2ff8a43181fe2852e6876b760558129c3066a4f2f6e0f2f4e95c85f40ccdd81e795d5d2987c92013d542d99764bd0cac97024adacefc81ce89b36311ec4ee304b2307cf1e10d1f171f0ce7413cc03d5bd2c2233e0f80d98034e91d8b575e1ecab76d708c0899f27bfa1fee102e9a5f393ad18293d3ba93c7af3bb62e17311e79e02214dc9b62a85e6fe270be98a72391ba14e18\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 0e0e316e9d6d1e5f7333789d42f3761598bbb76da7847d5b75c376ad884ac2b61a0394bb2f65e1dbb986c26fa3837f905bda324dc65545fcc6d949ca4b8bd49f9ef7cc5b1c0c593bc34e02a56a0b2fcde4ced168a504ebd4ef1565cfb400cec0d86275af35afb01a5ed32263bc264a2c8a45a84f348c2ab7c7f74711e4e295323e2b9b76a7ba7475d8f8d72943b10ba64eb084c832ac9b2a984e1a2ce1bfb50b97f64bb754bf5d5832499479a198baef88d9dd21240cc95568c64664a704a359eb56534e241b106cd8d301b047448c9e83d0e3d9632da4641581ce53c8829e49701ed297d815c46f85528d2fc531a7813eeae45c0d249eea00dc69da92550ddd9e04787a1cbb76d7c6f4bf35b7d8582ce2f2e4c1184f79d3d7473d7637f42215ad4b9bebf143f958f3d0295b529d3b3db192dcdf4419d42ae219bd81a716f7d6472a6a86328e2728c5ed4c08cfc6f9c3277e42df22d15d7d46c442af610a45668de66d735e09abcbb638ac39cda905dab0cd802f5a542951df3233aa8732111d\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 02e31b3b6f1200f93fbe8426cf433575cf01030fa1284ab8bf74428acef25759df587be26a5260789cde2aae7b133d249783b1cae14796658d4b6a4aa24321f5afe684788efaae848b693846a457737694d1a7af6985890ffa7384769864064eca91ece6c03298f5ebfa7a18bf731ec9a7cb23025b7072ad4c06bbbfe33655654422cd4b97a9be3aff016000a6c7303ccfc73cbd908e82c930dd410c3ab2ace258bcd05e91e94e4a616a6ded7a4c64b00dc5cf202689a0ef3583a31e066337b1971cdd909c20a1ffc7c006944b81a89a5c96cf43a6def4d745134056becdb9c9275b2f2a97cfe0163bea5ac8dc32d0fa7b24dda4ec0c88f61cae77fac4c19a67c46fd26a03b990c5737ebeebde402879a02cde56728688394d577e5fc7c347a8cf66702b3b255084eb224436ca5c861b6886db60590a783c2d32beacbcecdfacfe6b6e520586856596b25cd918d586642db9acda72986078511bceddbea5239f229f1aee80cfb9d851ef9e84056141d026ff50abe0c83d2eba6288722457f916\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 0ea7aa33781b897d17e849f3967ff8f99b2f027a2f3d46bb979e5d4e58398f2b6798b6c6ff4e83df0a320cc964dfbd6542c0441668156e108d2eb5c7cd4947b4c310456fbe342a00ad7ec2be365d0e6c71abeba20f701b0b55c833e52e30ea9cde21bb1d23372b9ebf920e1c163703a484960872c2b5ec4e4840843447d108cc76a37474a9b7f2ba09e406ae26722b424f3de7a0c9b68ecd71fb1cbf3e87163dc780fbb8f0a16f06e05cd31a0b6de0c79912df07296bd059ff327fb5f860ddde50c3a28ccef959e89808120cb1298ca5f6f7bcb7366564981bf90161453df0bd8268e8cb34209c969bb5c7028476eb212baa30990526fd57b36c66b71c59180ccd26b02990906e0de5fb386bce5ac1b3d2d23e1893220f698b5d075ec0bd871843f473555df877bed9bb22cbe69cd7004d9eae7feec60808ec74db9f257ccdde2d20ff5eea9a4a8c3b89bd281286864d62e4997db92df8ae0d2a1fc3dfd9aebce9f7093c129c426b5b74e5dabb7fa2bbf8a59fa2e4b1aef9d69ff7ad653c2546\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 556a31f90b1879a1374cc4f2922dd41cb2313a61fc526e889fc9a20868458ad5cd26d6b3d3a0106193d44be3a22d1384084a949e5d1388f1e671f638da0dd1ab90d9d316ce66a25840a332bc2ca312dd9fde87ba57ca718f99f1851b36be9e023e24b9984062828211a581127b0d81e4b1bf5977f23d1c70da7887c09830c0e3c5a4cb66bc8035da055596ee7cbc1ed4ea76d7712708330385e5a9359fa8e3a0f6e63a569e5d2db4e867812b40da15d3015dcf31ffa887fa7faf478a0cfad3125fad16d38a57fac2262e01217d6d7adc50a3af804d8881e61dedb535001d999b82e2d9250ebaac07c4e695e946b5f42c86b546ff18f1a16a946963c9234d56d44a78c4b0ba0adea30b17528ae91fc326f1f976891de26e9320bdbca32f3709f731009da45b0b09ed5ee788278f18baa5a97d039448785a4751b77a7b061489adb289eb85459e663d85f3bb300be43a185283bbb94336c41e08f50ef7ba378e525e48a844e3a165bd484b882db08284e5a51b392727d54f913d4bb9b7c153b884\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3e5d3c3c140ee9a1443428aa0612506da862e56b1add3a86b13f4a014b65ab0be390c5b6be0aa14caa77c0e0a9116c543f3ae0ecb927924833838993d02cde56819fb5293b84b9a00ee84233c42cf993ca79a9af5dc7fb1d0074b9a9f895bf48f8d9f79f5d8535748196734790ded7f5e1cff092ba949bb70756835d1ff2472c82069aecb50ef4eb2078e59877ee8ebe42d90d8629580813f3ee4b9fe08960615c7b4c59acd071df543fdeb7440499ad473621dfcae3c14a2971f85e233925215ab08f7f2ee3cf70427e94be6c895cc11e2a3ba569d7a530d36e33f00cf76bb7f60b4fe7349cad86f09225a5ce0092b8fa2162b3ed556a7eba89e48461d32a241c4fc7016ed77a097ffb289ed34b88bc471d35a931a75b0309021dcfde235169d8b3f18de671444cc5a86acaccdaf62945fd39f71c833a58521f591c5ba04af3287444d6975d128f090c1030ae4de3100094c24e262481de1ff346da67ea73c410b80758273dcbd83e127524eb93a703bb982930644297545ea36000df500e7d\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 79184f204ed24bea8e2e768a55ced92dbc0b5d59ff9013db7d8b6828d9c631f47e1fea91d383b7c00a64a3a3e553e7953288cfdaa78affed5e7acd78f48878b507b02e85479c9fc529879e9c8c252a0e559543d78f0cde0e3b797d87fdfdbf960a8ec3bd49adf6ea370a10ee8caba7f8edaa44d36430163f1be74bb06a6e6b689aac34ec48c3dad3f95d21d5a453ea55d472331d56e2272765747a06909d8cba8d1543488cba40015af45608cd11dee21c22e76670693498ed7943732fc3bd4c3f5b78821f1d3481a1ecb73c878b190094b5b5094c54f68a017918768d9162c15e1e15e2623019e7773e6815bd6cfdc37560336619980829a61e950d34e87fcca3b5143ca26d55d6b9c896a28eaafd1d77320e18c46ea1933f681d32828486d2703903079633a61d2a828fadff6c617bcec466570da7d9d0a447e50d49beacb46a4488b65743fe8200cf6a0b44bc675ef6c6acb7c96fbaffb7b8ab0ffb6bee5d3d5bf94b6aaee4346307bc65be6e96de1fc84c52e8ccf2b81f65785f097f9bb9\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 11ad49205eb560672ca173d10d16e9f196ae3ae43350069549b74ff6c8c4aa71b31e017ba2abb0d8b6e8154652fe186a83fc34844beff934852a9c278286bf60166b6f99a30081a344e11c655a0fb51e1fc7a3ad700676ebaeb0557a2c8140686d5a803bc8e5ccc80f688bd0550bee603ea5f59705cf3add97712642f0b65e517a183b4637da5c7ac78665cc5ec07515fc4cd84c885ca673c35f33b01b9727342ddf269f4be73686b05d8fdbf83a149232f5c7e674d4079b8021dc314afcf3c5561915e03fef780f51eb5acb78ae14e84c82a1efe444330ac4638e3f9918ddc97b89ccfff94538d0031807ea147e068e5df45e7fa3592fec60fbb15a88094d491bf94394e0201a865b40516e1669695bc32813a443aa868de58f60b60617230f871f9923c2aabb9106c39b88650f150ac935485a246f559437a9f687104785630a6b18d5544a1eadeb259228e0a047ef829d9fc5c9ce907a344a89c5afc51408f8f23438be6885ac746a334e797213fb6f854e58dfb58baabaf05a4f2070244a\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 135943bd12689bfe04cc1c0a8860d7c18f13b4bf0a82c334b44ada2c5e82fc32b0", "ae99c048c94e3508f59855c53e6b42bcc041c219fd6465d21582f4f99cba4b88ec1844ae5a89f3215caf458547f0d147c0fa1db67453465e593ad2bfbac8ea9238d672368d32ccb681663fd8b023115c4f41345551d5f2bfd387117830323a4d061fcbb6aa13f2dc0c5a317e6b7339f6cce5c543291154ed7b118fb8c55e8942d0ee9acba4ec3c9106278c982a8cda67a2f3cf74eef8a37fef7a256e27ab43f5b6f6a5645544bc7d766e4aeb439d255d144330fea4c10438d2b801b477da861f6f13eeaf61bf5ad0b79669dd1c795e03bb826627fc3797846005aa975553343c91deac0c777ba9e253da8f3b925abf5cbb0c317fc2ea6f8d750bdce9cf149ebf623314de480daab1139f882af161750d3b74ca437df8bd7c9570c23d0d896d4a70aa4e464d0a836c7bbc22306aae10058d1dfd81303dfe07b9231c651fe30e0ceb328570802e30dfb5910cbb0739c6f74c6088b2ff20088b7b91fdbbe96068\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5513c16ec53402c0546785ed2febd651c1370352c121289d2a1fc9d4db74f99041af22d59c407d60769174e5976159ad64e84a3dd841c04a16b6f740067b50385cd31956d917372187d04bc169ac0d55555dda949bd422d39ca03e40817a3388a4ae03668af3148dd08e6faf1eaa170d4d8d9d1fd607ebc4f72c3eac163024dd2f86afdcd6b448c7c5d09f2594e95ef97b5fe6a38a265c06c12dda0665393ecbf64770be7cba42563293626c305eb840b54387d40fb371047014a058ed0082be31f59259971a27dc4de18a403bc26c7b4279e390844bfc13215365375fdec2f3c3873b1ff8f87f60506c55b7ccf03f3b3ca2534a4f686145536f65bd1f11bf7eca54f327c6bc120192fe4975657f54b962f0da0444c6650984213ea2b531b0b8432525a416e2de1790efb83a224d29d5d8153279d45f990e36c839ab7ef3cebab0dbae382b096a87075b5fe000a4369bae1335b22edccced1085f7c1fdc7f71c6ec16afc96df26df65bcab54321d91d59f7024ca5d65e4791f8a1589f094b797\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 62b1fd9511766e69a94d61d38e4b02f1c6b39a3c28e8e390175cd61df62001b189a0e44e7726cd8de44b0518dadd7aa360ebbffcf293c5ff749230066a63cc5e393ac443e73a345d79e4b54637ab3d1625a3d1e7d3d0c5bbcedb65be1c85317035cea9f73b282554f355350513a7f8564d5c2ebf93723f943d579878c89b63d25be92293538bb9d80793505b20c958da5ffde894c71c392453c506649b3891be55d69c607b6e4179d5a91a332f84a44ed32767bb189fdb7145bc13f128a0790b333be81288d4b52493cefb118d770aa5622a4318f5d37ba40cbea11d2433bf51d10d6f0d48f856ac1a87376c6a008ad9507d64103cf2e12d4f903f9dc7bd08c1c6e56a5710c01040a30575e755b8dabbdd83abbf53c9c0e53f184680a5d95526252f9ec04b03ba99731ff15e07d8566366ec78d3eea0f723c6df1cc32e0f906cf33b1967077f61ed045058f040746e4d414584d0c231cde7c28a108e15ccbf5e89744e3ba1f7bd3ec92934101be8af0bc0705690043261e98692ef737ed78e5b\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 1b035a14cae3a8c4311b879f4ed000debbe72f9847fa91cffe371d2cc3e5e5853542eeec362006e7bb8fe2528d325071a8d8564ec9d60eea7655ff33bcb698d65cc30753084f773ddc3347e934942afcff23da35628dcb2751337afddf1fd900e2d83f528a96d4a5ebd4636aa7ce0f20b181176973c440b014d203b24b03a92531a79c7fc802cd10b7f633fc238e9ff3e184bbae1db31a8e70a69dbbebf925467e5684218e5651fdcb9ab2379b2cbb398363c410192c1ff0397e9e23eddd8e3cb473ed39dd9ad142a7806c2e753310efb1254edb928d781e70211d0483bcef6b7c43b52d04b96ed56de631343e29c99f4c115d11c0b74880c4d6a1235c55d0601b07b23530c9f619ce12289bc1b3efd4f0a5d1d2f7f46f9d58f0b93f659420cea287532e0f3b6c92d65084c5e188c998857989d5a2056bb973a7cec9f8a25b260963bcc2d4f74f8701aeb9ca92fe7551c006b21dbca74f481b8ca1640e251b98ffa768ef2ec7924cd708931b15752858d6f7dc0890fae266181b52ccedc87446\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 0d6c8e033994b6ecedf22c5f544f2e3b688db8b2235a00dfc8f1b2bfd1391faf649be65815533d6ee94098a4382072beddc2a2f439837dc6df0c9826ec49c3c529b71e9cad2ce717fa047cebf81e0788ea71f8005a0c7ad1a8d59c27efc334c826b40c3f4ec0354633e7e6d71654509460e7d5eef7a44f4894f07e652d9d7860c78ba7facd161b65e5b8c47fd3df85816ee5af4ed35c03f9bf08c2d95d56bce82954f17da0195e95558dfc49d7d545ba004afc59e8f17236cb6f0d8d7d288f8bfc41122ac5e803ef855b3d02d11dd214a7f1e90617435b2840583acdee0feb145a37a8b8c9f5feef750d9a950a605b59841370a47f59a3aeaad2753f6b1ef1c4327133fd59895b627b7da0dcf5f9bb7660cb9002692ab94711db9c15d3bc5fb4cb0e62b36beff03bda7746a0161b4199366d3e2a3a9c7a762b6bf15ec1fa27585aa22d428e7c7ae7dfe8b8010a7df9f07a060d9115d235287ace863596e1e01fbf3551d9995e5442de650953cd2951c561317d331df010d1c6fcace9f8b05145\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = 7bbba09b554cdbeb72016995325649ab9c9d0a9bdecb5fc44ff0057bf619df2ca2bbd0c3b13dec3126a0545dc4936c043f200d7df11d87c390dfa1b0dd4e20c19877f283f62d6e20e0ff2f0d561589a683034bffb5fb2be9ce2be2a3f9f86667b53cb0901cdf40c23ee67746a49ba1ac576b2075bf1ff7f48941dd8bb9604d5369c9077d766776f265baa4db5dc3fe7a2643fc644a01f14c40a7a96d95713927b7cae6fd55faa5c802added32c5ff6f7026adef607a2f2abf59f2f0a8edd35547db4ace0b8d81961480412b02b5d51f1e7f0420086fb506b7d617605414a59db8d7f1374398efe6d38dfa39a0568a53fb58e1b71ced8e3c126db99b02c0a7b3e27a4d1493f2c077f51f5b9ae73bc89399b18c270e6e5766b69577283e084ce3b2522a77a994fe0e4a192eb997cb5b4bbd7592d24ec4fb1977809440c7e0dea07c384169e9cccb23c1fdca7773afee4ed804f63aa556492b7a4063a0699ddffe2b583230b826a320e1e26677adfc11d185a1992d38e4946631053330a542fe594\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 7e13964d767f2f286807be50118481f2651e9da08d93d850bba4297890e79673480d7dc10f5435b5e0e318adc9af3dd5d99e0339f9bbfe21891f2bee35b9462b442ddd764fc278f77e7c17d017779888fd552537f8d7a9bee63dbddc10903c665e975cbb01cc1ddd0349afa100f325e3dad303b707f22ad2c120083e4e304eb1d12abdcee41f6d1cb276f58eb09cba643444697e43a899c5bd3b1d10ac939e618db4bc12ce6d822a29c205ad748d3f632b147a7232f799c14678ebaa0124a9ec16168e32df41d21fc31a2d87c3b6008b2cd90f51230e1dec00311faff09c2fc07acd78b57e39271a8912a0c5b76e3cdfd5915c6362f1559c28c95479750b72c4f0b79ef5f9a25d9022051eb1d9de1ac764fe683958ca8a6980098939b473d2ba58a4041ba3db8b5a6cd19b4a2212744e1e2179d6c94ddcfb770d55abe3e5d7a81032809767dda95683f1ea60054d19b61779f17346b7642a92b57da96c5d5421bd77b49c0cc75e6294354e307453718335f5c1d87f5179c9fc74f0b10de00f9e\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 31140fb3b755d517fa660fdc5b940ba6c8fcb667ea633605c730fa47a3b52c0641829f275d2f8d9b8ccfa16e546146561d53a4d16a88bfc7ebf5fc3f81882e9e563346e19944727ccdf53b2f71c30a108ef2a43dba5be533fb0f05ba0ff302cf18e77d2df46d903476a9f7fabfb0a4e8a23e040359326612fdd9411910899900c3987a4b59d2e8ada6d6db45ef7f420b8e8faac28c6b9b55806dcf44f0b2137084035be8475ac6e5c6bbac67069530a36892e1d6bff9c594dad9b7e9bb604200c9320abffedc8ed3a568acb8e83411e6d28e0561848776c18f8822a150c68aa8279b90422f39432b44a9f843a843d4b970ca608b15f54c42057e17b406f939db847113fc6949090b203b35bfe53e3f414837dc0e2dcd58d5f7b829adfbbc60e41a8c9ed4a9fd15f31a7795c4fb93d88f640b20842281e966098060eef25b2ea3df4d8da8b8dbd9454022bed7f33539761303b46bf810b33253ef1a5887a9e4175cff852772101b27d1bc266e8b2924fb37917aaba4a1ffcc9fc444ccad469260\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 7b4bbdd6a446be7d5ff306171d91aad0f94e7996c01b12f2e402ef415b06ea2483a39fc4db755f3e7667f474bfa282dfb8af30c26a561f499b506a9ac15500d8b994e6ec5dd7c0b6963dea7f0bf1e5df5ede5740e41b8f71ba6ff56fea051e44b441df0264d730514e3cb74e8e0ac5d4e0be7e3621be53a41a12c12d0966ce64c524c16f4e1dd04dff3077b50ef54f2f4bb1da42fe79aa81d1604ef346e24321a7d9355c7e3e64d83aedfdcc02038ee483d6c46fc9a2290a8d75c87ac56e04da09e661df1f6adbb1ddc19087a3d7a96896cb803068c496ed93ab184d8377cb277032d627cb5f89aefc574d799445232292382d70e13234e4342825ce75dc08501878f4d3d219442cec45c5c6bcda2a70047d671aac7593c746850d8491a4fc9f17ff16fda341ed97ce8fc9d3d8cfd889dd752eef198914c4dbb78646674a5c88da0f6dbc3083dd5453a520a68ef79a97b580b87ddc7b7761277108eebab138b7eb73fb6d73e8827f0d7b7f4411136cae3ee2f172adad6b5f3fe3acb478cf7ec2\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = 56edf756f30417735f334309157c56b1918947f55978e684fc98f2b1a528e45f162ea4dc2463bc3dea7e31e0ae19a8114689ac76464efb2ff7e3a2258ed9dc074d5bfc47d6d0f95b71efbe8dbdfbb0cf6a9f3f96978597b6e2ed5c5cfd365ab5607419c529dd315302a753939c920351e2d1501f63ac2b8e1e3064eb7571cc4fd2d6af08c6a6e54eac092f80304ace2d717d9cc75efcdb714d7c86460f73f962ff221a76a9345aa92a17afb7faf5ee30a9351259a304f8430dc6c063de9547774f1df890756e4a797bbd1faae7f2145940ad316dfdeee42bdc5ffea9bcb19dd329b4f84c48318d63476f09f8de7b88db07634289ed42c546b2998b583e19912092b1895a086a", @@ -4253,9 +4891,9 @@ static const char *kData170[] = { "96b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d17690000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = a07887f373378196b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d1768\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = a07887f373378196b0b748cdf31c14735ccfa0f117acafdaa21fde4b6e7559390b834e7b92e9e1cc9d49fc0fe6cfb60429652b4bf9a7768f71fc4271ca6fef4e431192ebdc98630bfb94c5baf18b4cf7881d84483e4c44c22db15a9627705a0b42a26d6f3d6009aee0d2a71bedf4d4b0ee6b6fec2f16e1277ecaa3bdedba406473a476d1688df0fad1da795526c7e641981b4812b05b692d60c60b2bfa424c8b620f40dc9dba59e2c710e7ee750b3e134c1f71f43210688aff17aaa41cdb5668753f0006b1cf951bc5951f4d89a31196985ea55c0966c3662bcfe4e4cd34f12e4afd7e5c4a130739b1017d6a583882fd72db1a67418702c8b01353ccf75b7b93faec0e0be36211d5f2bd910e1552323711bbeb73858f899cc1ec063ef67d88e0c699d5a689c52106f06e960f09d2a3cf84f53bbea2a473edf2e6e0176801d3fa1c2d358e1e5a26f646ac93796ec1fadc6991c0ec19c9dd90b25a2dd3bf73d2cf1eea8867f96caa5a2df54973acb2a2da0a1367ec74afbb968f517765238d176a\n\n# tcId = 235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 627e76d9ab46ec144d942afcb5fe8f677eb9b1a51c047f7b8974f1a6697c5f4ed1c616ce304bef814ce307d4d6a8ad96a704e71c2bbe7fea47db502e59ec985a69405d9a606ca5ee7bc1e131783452cbd7afebebc6cc4ecdaf119ff16986f561ee4405a0bba05707da66de70f25c1b6e7bdde656eafb70d3ecbe2ff3bee66e3f0663a55feed8c501827a34f5916d0dff22fd7baccb87db47a472a21625c1af097264b5964d05368a19004ac9c5e11bd3129327f476b66abbe5b59e7df1cdad9660c52bd13c86b5a721de476f6662cbcc64db4c6e93c8ad7561326947192501050d4cf6e62adc42e5f3c0c605e3a1b1a1cb8486dbbb6fb070426013e9e1a5a2d1d8b0481ffcc9235a99d154e1991e8f15cd453e609be6bd008187b1f3066fb8d5348f08b2784f8fff31306dbfca2c59e1f48d40d70f7db16b89cc8506cf0137e2a617e27d529450f25ad8a7c502d197cf146e85fcbdf6e57e4703408754817a06fc8a60008560890d1e72a6751a43903c0f00a47ad383a28ec7bb469b178d5ecc\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 4b417241f14720559c1e8cfcadb9e0d6b7de849b16c80dfdbc867fc33e4b81d56915190fcaaecbb8f6481c177cc68e26813d8a93ff45ccc41b795714c7d486ff3b929800f88063cdac7b7100d917c2288094cecbe5d6f2ee20edf36dc646464958cb1cfcdabed57f329561ec6a8a00ea2011d2f9215f65ff6afa8ac692aba8328a04c9f9fc59c8d8f22e309d403fe04acf5a31de007a5f0f402efdb2c83c0c5aa57379163b14429146f9521ace54189c5445f80076b2d43214035c2b0e175ae0c463253796ec66477e1571bb6ac57722105b58fb507922974ed770eb898bd584d00a2267d8bcfc66055e7cd7eb7e7497149076e1d287b31671298076f1aa6d3f1ae1e3fd62eb8714f9fc38bc6413b2a15064da7b6b589ca5ca539d0d01a58f999935f1a8e6a0d89d440a510ba9cb71a87be0cb81cb1e05b73f8402d684c768ad86c98cd3bc904a59ec88c385835fb46b4ab46e3e026eae14e54a00f0e55b5cc26920682f9713d48c7946e1b0ab22a6fd6cd3e833666cdda12e31c05240a94c80\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 338c3b8b3ca15e0fd12433c5b18347d79d344871aeca17dc93389f3c5fc123ac9f9fe95c97dca7583e3fe3c2a319d0cb409367aa7573c7ad75b118ede506631f52aa861c2b0e31a9d8c435416e8e67059dfb4ceff533c214c4243f5451f449ba7b75667acdbeae22afe959287fd9f0ad3e4e7709de5c90a6e23996a7ad643ef0c3aae54934c31d79619c04b4cb85fa5069fc9b90231debe3e59da0ffa2873dcf9e53b8481e215b585b1115c02f63bfa6143e2b900a0ac71773a0439bb5d86a78b4ddaa5e2b9e44f7192d9451a6bb8e4635948212b17173b0695d4f518189714dc0b51", "ace3b9068f5fedda3b4ba4e24baf901b313366f64cd54fc2fa3db8bb8f1e81e06effd580fc4974a3cdae688297b4ac423d81dbd342b3067e6b4d7558ac8f4fd1c1d8f5fc94854adfb0ef8a69ec43b375ea724932b391ca5c04e7e75fdb952d671c315a7f86a28ba954db126cda3a39ef213b5f9531a8a159dd9e5698ac7ec8fe7df2a2316798742b2fb5271fabad932542bc98af6e99d231a1b5fbb09eb\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 7bf4d4739c1ce0e13aabe610a110ffe79dc689db3f9fdcbe29b56212f7ec0b3cdb96ea7052a277327107a992d40c5c5d03ee11476f328a83d2c3a1bcad5c9d9ea2928fda571850a2a9988a0078429631f6097b2fa9a85aaa1ed9ac0934a5b9d00fe6fc106342e2b03d4123e09e2ac61c1343f88047daff5f511c8fa3d66f76406b79b8f4f0475ab14313968e56ca9d2e8672d3bec27a5d536cef54220cf44a4a698fb7cbb8035eb5516ae4b44aec19da40fc788f2546d5da54b7e1110d13d3e3ae97671cdba93a6f5946b2cee22c4318b7343a0c6b0a32000c6ecd08c6913901b79dc2bf38707fdf14261581b656af1fc4e1d5d6234f9a5578869cc8b920d7020fffeb95977bc3d154b1127f454bae63f7b1ca377c3ef42b0ceb75c96b3f54ab8a5831d59ee8ebf4457f540550a6113584ca4782a53d7b62bd5c5decf44e005d2c46cf3e0691963730708ccd6bdfb29e7c099f1e91494a14a938b3f5fb08ac40bf93a10cbcef007fb6a99b432472ce3bc883714eecc76e002bace4b0394041e7\n\n", }; -static const size_t kLen171 = 209306; +static const size_t kLen225 = 209306; -static const char *kData171[] = { +static const char *kData225[] = { "# Imported from Wycheproof's rsa_signature_3072_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082018a0282018100fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d52450203010001]\n[keyDer = 308201a2300d06092a864886f70d01010105000382018f003082018a0282018100fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d52450203010001]\n[keysize = 3072]\n[n = 00fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5245]\n[sha = SHA-512]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = ebf3c64e4c19fcb0fd920e65554a552cc1e652312c2e0e51cdb3b92c94b2b41ee201f61f434a6aa4703e87416388f4661c04fdc2e459e199af3ea208c61b99d746f4b00d82105caf4f0196f1305e806bc13b4c6e6bf581962862dcb0eb15a0ffcb0fe6b36502320011b540799e1432baf2a56a428fad64811afb57d210d859a1201ec057dd8d2a68784b48dd07357162f21e4c82f8d5e385b1f72834dd4c0d85ffd333410f08ff28fdb7365e408a60af177c80298726940bf4c40efcddceee3945b1d921b9d04080dfb12d3ae61863ad2e3e302370f5a8858a1213dfcd500269ebef76f4ebf0982a751d8ade1aeed95f41d4560084711362774b11b6240c0ba6ee4ca634ba8298f6e63ef560a39047481b9eaa546178e69e4daf5651c66c6235ba97c231241c63ad16efe59b7b5505d9c3f1818368b9462cda71849e431648be9757620c15f99ca78f4e250afc41ffdcdc52693a1fd43506274c431caf34a4d37321f5ccf04971a25c5010b9ada07596bf9a20bf307db9d5e86146226081b25f\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = b9bb1751f2336ef5126508541b949d40f1719bd23c2f0fed64a7b73ebe1819377e6e4262f8440a3a3cd456f5eec0b1c0956bf6989add2c3d1c7ba4acf7a617d198179dd974051fa7a14ecd8093ad572d7e233daa2a9a46fe59bcf7e01c6ad8d68c0afa89a58247ce257566edcedd799173e2babadac15405e2812ad12ad900ad997035966a05a02988e11133c21e111a8e06d7ce509de1e0c11de55379482cfa072348fb41c05083529c2db86aebee92095e7450a75d97fce7b3103ef1f8598459651dcb9b6e90f299c9efc95d7ced2f6e91526ab3788238e2b5e109d3ea984189ea13939d58fd4ab896c76bca4f6a92fd3bc124dddfabef1f286583a1415d1fdb8c80de8e7583fd6d52836a22c3926f69723301904532b9fac2a37d0cedccd4b3d0ddf3550377191f813d4f92a5c126ae91e03fbffbcf59637ebbf1f30acba1dfcb0f93285381cec6da60bbcc62074075c71300f8424e0f964422dfac19d205251f227614bc13568f408284b6b53bebd7dc4adfb7e242953564763292d9c01a\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 1cc02717a3321a83da62deb3ed0b9706cf7ca9fdf3674617fcdc3364a697825b910d54b891b5f8eba197049047cf0048ffba6425d47374ec24a84f1f7f04716b7ec54daccd04aff858e2e7c8830e4420b5f99df756018083abe46d3fbce2da6e8ce6c893fc11ce5967a5f367159f9ad38d957078dbfbd32e818a26b49ae00151350044d22b58a4a61a35fadef67e3f8247f407f026eb17b8dd4ab29d388bfb271a1ec606e141cef3fe57e2e55ae8b40fb076a06f5898362b695545124e9c185c50647cc5b83f09f406e780f626ec60462fb50caf8560aa72fbe174111142029b19f2d681f771a774afedfe2500fd8b1bdd437fc41709253ffdedc302f47afa774f5ad23777a57fe44067182f4b35a28923edc82255cce11d2fbe91acbce29289b4e0e8f5e99e906e6607637b05eab4028d85e91d060fc1fee052a09baeea759917b34855e09b8e5b67ad60f45851e991cf01dd528b100327961eefd0c29f1d1d8771bbf3bb1e7f048d9c2e1dc5e652e6ac4f6a2aef86245b83f611700bedd07a\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = a0de9c2df76523499c6c344173d944b8e02ee1520f90759fa3c27ce284091f80215a9a26c9fcebc125171da556bb732a0645cd64b05c7cbcd8c187d3995e3c86cd59468118e9278ecdb8e791badca8785e56f33478ba03eca721591930db01bc1a5da5e193b2dc9022e98948644a406138a4c7971ad8ade585a3d72e6c9de50320b9fca1ac0e054835005cd39c96400c491e1b706eca22ae2e9f1b844284226fdcdab1f2cc942a8280f7786e0f2cd069b9ae99f04aae424a6d24eb023e064513931b2e4f7629151af6bf83f4c5c58616960f080c6f96eeab07a87b6d7cef3fe6b071e49ed340b48867a5bea30dee332cb89e1a54d9e3a9a8bbb87179c6ad206fd48dab07104b1f887a02160b59f9ddac6d1f8801c1a8df507ec199e970e02058c749475b7636ba2def322160b11b21773fdf904cc665eb5eda887ecb6d9be245d3dbd85cde107d082cc6d8492a087166e23835a379ac69f5a996ad9032cc41e205078c5ec9c50f85c396822c057b25595a35471a2fc3bdd3f75eb8ecf2d1189d\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = ddad8eeace34f1eb1b0dd28db89ba710ee68aabb54b0a826c2d69355f63acf0f2f2e0dcb96f388d44d0940774d7d55fe81ba6a8a880aeee8ce842101c7e8837fbf2704971341d38bf3289dfc61a6b3b557588db93eef2789d3735000c8e2d830a32070626d079e710c943082a8bd1c0cfb64b2dd911eea76001f8e08cdc01cb072f027fbd9c72331b857d07c1c2f3090eca53accef8b3b015438942e8d2fd3406cbc54c7ec3797a163b13878881f7b4ef5ca45056e16e0c2a76c3d5108c6f0f48803d27eb4b0d55e90b19b6fe372dceaa61270b9efe2800bb259dbead955635ca44ff979bb054b5cdf86d4914ee553d7d5b1a49fb8e49f3f761224802858458f702aa4428964a32a45bed5738224517489f2be075f9ec7234a019005be922b8265bd78abdeb1d1633fe7e5aeb37b61d36b1a03a06847a812e50ed551853d3cdebffaba8b056b788a1bc452ebdb5a3f043a116e5a3d262c745fc15897ad4ad955595292a79eb85373d552d6079ad77e469f7d3a60330702125127b1ee770225cd\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 2ecc537edc397ae5c3c789638204ba3393bff5cd9c1f0552db515a8258a311b6bdc88325f9072d2ae67bcf132a92c0b4d01ef0f2916349adc6d8f1b415c86bce6b5afcf4cf2d3137897d0f8a33063a0ff69965a5d2ef00dc3e010094ec8214c95c064313c8e90bd84e34c86b2e19b056539bdb3c83eec23722b3e380a53826bbb31cc97ebb8ca77cfd96d3e6a2da59baaace3883c652a92e79653941c5615bd30c77aa38ad74c49d36ceb9f76544835d57f0cd14999c2c0cf3debbee17a8aba6d777ebd9ffd44b09e093f1a894a8aee80301c3a5a59626a79e445254cb1df1174450bee22a7518afeeb15495d663af289dbb09216543bccd136abf2646bac573551cfd04e6a35b5cdf9729c8b14d34c06660a42b3ab365a42ffe470b69062d0f305c733c43844565b0b94d49d2019933de9686088d219d57b256170c137a21475d03f2a7e0783af11426fc6e64895fb92da117702e4487558e8bd21db82f263c4bdc64065c4f66d87c87889ec5aa9cee02c95d001b08636dc3420f817c228dc7\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = b9b492d4796fa2cb7066069a00e36aab8b8755f9dc8294401137efb3e2681c9b57930c0ba87b45c9d70e214979cca91a06562f710a2427660547006ead7b3e619cf4652131fd84999c5ff1c9a1cf057363b8ac62501bbfb1fae840cc963a95169c658add96c6c969d415c10bec5e2457a5c3fa4fe81e7de1afdec6f4e59e3fea185c7cd1bee4b8a42d2f22c7bad7d4933621a0cfacf0136abffc3ac54ea37c63af719425084cade944999aca3f43c7625d22af10149f39acef32ed7c92f781809aaa945b2f446a03e66150a524c7d88b7bec587ba7d6fe2db4ebb7a8c3bd46e7fa1cae291ff502acf33f003", "dfd1417fc60674501728e52490476d813f0079f56a9456909ccee3b76b30aca26fd4487527f4ee6283bdb2e72393d661ec0c35b2d1675f679f823fd28e044fed090721ba4c6be46da3eab26e5eb356d17d04fc3ac31425a6f6a50474e2725bd4dc30da74fd3767a122ced21671e47b1fb33bb7018349f7cbc916c6c7f4ca7334735a0e0ec18e01735107bd2ff02cd9508fa5832dd\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 7d550b35998d60a62393379e47dc02b1a4530bf60c892c4e559acf9b9a61208dd9ec054c865018aa2fcd11a88493b54935039d0fdf5371436da96ccc342bc1440afdc46eb7bfb6595303b013037537e695787324cf9593dc156881bd0dffe8d2d22d4e90c1bcc801c9bcf12cba9efb7979a293dc2ed17ef787515e2bac8011286c939c418234df353ff9a5e0617615acfd7bccf9aa31c6681950947df67690e36369c3c3bf6c466e9748da0582acc76bf15760e8ceead43b5c2e98d87eb502d5a823ca69702b6936cbe36295b5714fed51b35fad66c819cf1191b3708f398fbe8274f1ce219e8cc77690f30bb7643f9ea472811e6216253c58fbba5d19ab738d6fecad309999a4d814c19620c4ae998a5f0061fa616ec0ab96e3760dc5d3450ec376a1a0292899212828768bbec07a0e1ffdaf4d6e5fd1ef5a2e0567341b2fc0a4944fe8bca36369fdc0177885d5169747103418e2af807c4715d94c2bef45f5eefabe8980f90a11acc01ffe0453e1fed8a7986b07d8f6daae2fdf0cd266c587\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a31ac04a54a8b6ff7e56a0fd57b356d1f854de8e0f9001cb216b859819279bd80d8584bf603999215ba8debd1e9e93fba985427be8e2169924a3954a43b58521e0c79e7a858a77081439beda623bb7b96ea46176fdd040682da77916fbeb77290e7c93b2e8a1d3722587a70ba56b8de3b2e9599bea708568ed88d2f09d7b9d0ebf9be2345b81d9b343c7392701d35d1f3400f343763af8d9233e40228aaff22ace45920af56956e07cd010af64e01e1f8f63a9dcc3b7b205de730199fad3e3b2f139c556748d704876af986b98785fa5686d5d2410cdd95f1c80a8ab8e24c23f06d5c40ea5f2be6f980db62b6d9b22cf7aed0ec00125e1900e50db95269148f6165f563b8ccc0d35c9867412c21f627ed436769842662c856392d3d0daef99bc47ba8f2738b4ea9d068b20c249d43dc01a067aaa8c249d43e110ce40de060c7c68866639bdd3c6d7b7b635b7ba71b44b71e7f68651b203ee07b914d65a2165791cf2f6d5dcbeddef7bdd7f786f812d9c5515f846eed933248b4f40a00b7735fb\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 693fb14d0d6089db3aae22e292e43627af0cbd67234983ddc1b077b4baaadc45bcf0ea0f36ffdaf970f99ec5ed8ae8a58b7e94db9028963e14c2f624bed16bf24bbc5aafd472915d643e690f6e981287ee7856fd0f14ace63a790676457ac09692bafca0014b2866c870227a976fff547812641a70993da32acb962a3ea050845dc533390175900c668a5f36ffd495ab7917b768c68407f4cfe1d20bedfaca38f9f609e74d9e432829da2487f957069dcc290da513d8a453cca27c8253bebba2653f82f676e663db0248af2a310b254b00219c5969f05d04fbdb9ea0cfbd746050ab25cd10de42a02a0ddf223d40e233c6a6597992576f2d105b72cfd77b2f319fe3525da8a8f084c305b14e090e3bea5c5eedac3360d366c47fe9cd60c6bdeba472d408a79031343bce42bb1ef5d6f4e0e63cb7ad0cd22e4270392ce711d7c8efbf0feb888c74793f2dd903e3ce894ec758d69644f654c5a75378b0e5c63a5f9ae05e0f4818e2aea7286416aff545c1048eb4d359ce1bcd0b26a28f55695b56\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 0783d81e403f352d1140b99d6cbdf63f413a55ef9a64fe1fe019adfe807b5fa59a18e63d455e0f8fd61edbeccd392a01e09dedfe28600d1c7507b1d81bc814d1e835a95219cefaf7525fc0d03bf211bc99397bc8fcce685445263a3db61184a8e44edfe7ee48e2a7a5e3c8c7f28158a308db3fc35d822ef6cc00e8df43ab1b0a7ec2c92e3fb7fccf8f8b35e68ff6d31657aafd756782996785bee97d3ca5c37d22b44f8a1a44ed6afe5b80b9659336f3a39870b5de2385630f3fe7ce3c91bb269ecef7b3fa999a79518aa3a06fb626a5a1e48db98199c1c4d7a139497ed8e9682cdcf343dd03b4a5a056edda9e7101d2da5ed8d5b953e765bd6585cab5a27030a8c909ef69e61c0ffe9cefd2ffbc6f7cb26f64de674ec5f4395f7627adc72203fd6362c17bb1f262c430e502a258edf86076336499fa89efe7e1298c7c932b0893088430a30d7309282cc4a58c5ff05fa3f1dd664b00139c309831b8084e9f3065816844fc3074d7e8bbaa638dfc2fc0aaa74380a1282e65c7934be1cb7cdffe\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 162e2eb2457e28016b961ece8cd8aa9d4d2f4b06a9ab069cb79238f5870075de2a9755fadc5c78c28c82441c474718ee905a8d7700ff2601d7c56d7eb5a9d7019e92db6897c823925cfa75b5608c7a79e24af37abc09c89008be7b2ceb70170c6d1404a892d0804cf9abde53f9aedd13815459c3c6a1b37f7dbfee6e4b9e25143d9c64a6a817550337d0c74bb5cb6c7b5db2bbb770c67037729341cf25aa880b14d39d71e66cba9b62e1ff89c348eaf4efc79c0de4734171406295e346e9ce7562be7a5462834f1a00da1d4d54d7fd7fb12430b4096610fc96ff1bdfb88609d6a961338bae78991b05f2c80d2a131de5eb3477946d0d6f5f500a0fd93d57e0be3518b60e5688d8ba5b25c2343e894326129173b86dc315fa183a0d96845464f24cc020dfbc341f4623d6732ef699b3af9274fb504422bdbcb491c8cfc63f6cf6adbafd4f2bb671b92b6f4316ea456d9d87b8f3b2228e37b0f34f2d1ff70cfb0ed16d14ad3ab5e89985d4e30e51e4eafe69c0cf6ee5cd1ddae25b5585622a8b45\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = b17c7e6b49469e75e489f9647112354316bf3ce3a58aa9ae41544f73c8e1e56c284667381eda58b3466d3ef16962a2619d718f93edab9aa12e5be05f73cbfd4d8e546bc936ff9043d5c048f93794d68c9f8d99805f85665797a27b84a3e97883e74ea14c180aa2e5c0785af69275d484e14dffb50a4ccee742e809a03da229e70ce529d0166439cad74ec6457016b92df8e53f8ed68cc71229a1e1732b15175aff54ee34de4e908e9b6f9e720417d1a619ba9c1ed70a55e4f5d9bd940532b2f58700f404cee86c8ad9c72ad7731b8c2a063efbdb96c7b35d641d5027d55e8cf6c317613373dc303cf84a469b54df3c2ecf5cc8d1bb3882dda48e41b9e5a3dae95ded93f230959c547ef59131fed18c269a0d5c2be16891071299cf1bf77573fde1535836cec1daaf7cbcc50c563d08a79725d66d3720ecbbe1db7edf85ed3c4a9160350fe94326e3f0440619df346e33aab6333c1e38b9f34139a26778d0b0e64b8c4746e5879fc56eaa4c4641171f79f4f3fa711b9b0548cffdbc39929b4ae3\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 38f8952c63cb832a35b8808ca9255ab12fb5c27573f29d585cc30b94b050fc9e179f87821a2cf8d23f10d3ed6f2a8f461bd098eb5f6ab98923647f87594e2cec18a776af433cdf2b77dce0cd853651b50700c9812d2fec7a9760388f4c26da6bee3b768574644c4069775ce21e81446a9e7aa2c97865f4b953daf7acfaac13e75e079800bc5ffc94090ed6842960e03e95753be39e94dafbeea1745fa7a4fefe777ff5d278a8444c07e3c8526e80960f6e2146900ea86720fe35c881a61e3f23a32a6bbfbddf049084d9a6d1b32b9c2492161d1aec9479a8891c7b651d13e34e784e5a8d3cb2f5412d322689591a98b41ef9b010190e732a5ed0d28b695f6ab06870ebd23fee44845cc64d4ba39017047c7eadbc16a1e35788a9d2c2ff02b48badb7bc4605225b7b631913b19683b6f90e634582ed64c25bb6157f28102c4560945b6baa91dcc551b4a6bf2b5cd2adb8a0aa87e29c502b5b70bc4cce2e197479f9923c3ca35e5437c849d5264dc18cdd3f6bc7b88fd9182bed11f0cba3cc68b5\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = b24733b208d83a92b4a7c6d64209fa2ac1dbf615954eb99704ba9b6eed2a545aad13253234d88e0afa81277321a8662a1c9c59a7ff932c6b2889e44ee47e25e730427665a98f02b8897b24ee3036febef294a8ba02ce60b9fcd6aeb592f32daa1a79afe2a48f5097971f3a72ed3680433d93da0e3f19aa7d37082880b0c3745b86be89d184162287bb6354158ced89bbef14faac68649d995a4ba8576266bf5464106a82cafc07e4ae4dfb4ff3f6f0e8c713d3fb73673e75deb3fd04098c7c939f91594e45323432f30029122afd4e812475f69ec05248d6e2deec18e7dd02c7e9cf89cfdfca8b3412410b1e271023725272ef0d9fc72f35a94a484bdb0c1167c282dfda53a86b72922506d51adfab81df9dd257787aa5fb6033bd7fe61a577a7abe5b48174a3b2f7bf276ad6a6735593440867739851c91bb30fb2f6d279f35aced179d231dd9c5267cffd6b184bcd710a365b29957eb98aa81f10db84deb3448e2bd8ab50dcab06fdb3a2b1290eac0e60dbc4114243540585ec78473fe9297\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a336c6c475b3ddb4f9e58bda547d867c25b155b19d14746f8fe9b22cafabc05aca001d019352e8e96cb0afbadb7bf16998e5052b834a0045e861f646fcfc07347079822e64dfd5e72c2f996f0d5ae5d31596b93c77fee310b046d9c461ae9637ca21020e48c6745feb9b7a8f7e98e47be68214405b55d81d190d0bcdce483b2915544108bc8daaac9563483399a69c19c644d4cc36be4333fa9e9221f17b0ebd2885e57e84d31bd615e438aaa7a1742f0d6f3779c55ea3dedce1940e819cc140cf887edde8506b4c919edf3fb6505293921889c3d6704ca6aef24e620d87d6073c0e9f8a8c43f98fbba9e84fc9c445bff081acf6f6559dc0a49c9acd49c1adeb11ac31e38fe8319389541144dabfff498addb55d974082988503adc422d78f3e6c1764baf174c451eccb13e0e2f9791512e9a949478109176671f56cb3b8b841fb55207bdb7dfee0b7d76ae95a76de6f6ba4e953ad0431bbd23311ef17da7f4272a7ec4a34c08501d01965c4ab325420f6464dfdf471fba6f59ee78bedc28524\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 84d3cf49f14eb7e6d625614743859b9c1ef5a79c23d3c16e25c492c85df8c3d8f5", "ed0a6e548c042a71135bfac1d209cf434700e8a6247f8d9bd3f1527ae63a5b797880edd6b3112928b9878a890cb1d0aec6e84cd5da2d3191d590a57a82577c8db2cc51e8eff17c64a6f445ba202c9f13af6b20d5974c88f88bcac534ee80eae451d72bac360511ed77d9a09952937129790dbaebcc92014bde155de59c13ce95784ccec3b4e9ff0a08281fd30f5180f62667f3a2575e67550281c2f3ee42af8b9cd94721713cc95841311f81cfd5d50883d063425b8a307f8bab6bc19441eb5eb256b6cee8126586707eec75465bf8fed4bf010f00633f2d2a216af178f3439fe0857921a92a642b83c7edf45b8b7f0e280cb362fef1e6b77144465aa06968971861a03c8f6e6b0cc77f713a1417ee76934d441784fe9df0e65aa5f439a0cf9889c9366a213fa2f9302d8a70b4d9cf7707687cd2214d720eddf7a61eb0edbe679df5fdef79f2a8df50e90f26be5e156ccad330a3f81b998df0b610383fce24\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = f3d8e162aa3662eb0648048acd70eada84b12a7d15476e58e47f7720bca89a0f467f7bc2c6cfb17273d0ee66c82c2e82c7cb184d073af6a601cfa7c8df3c7eff348fd32973f8b3502d5257639016ebb24cb6011deb8ed816ffc44f262f03799b122a0c3bd7d69df064a34b166d7f138982fcb4bc2332384207117986d92bae3a5afafb0836a892a6c9403cf7054bf02a82851b35768ea77498b4d12a6e85018aa59623644e18fd9ebb4cf3490e8577994836a84ce6bca85ed3fce977e0fdac1eedc81e4aef60b9de47900b9dfd1b67a0c89b0be88ae67a5307576ff84a7f99f3f030e2133a51bf7af75142f59330e2492973373e64f34a05ba7f2262ebb91f144a89cd82906358e5a8bfdb5e7da91c2ca95d0e45cd2bca9912b27af36f45d4cc5535b0aa95e75d330cb01bcb01e23438d0bcc4207a2a7fbed4d762d6a81822993bdb42baab84a3b9cdec3dec31729c831cc28dec111605924ae0ce6d6c16ea9a605171a82cb11102bcab108229271e2167ba6ae715500038d1186204ae2fe685\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = bbb3dba33bbc56a859bfe0cab3ef7ee4fd1b9b8196f5bf02f55c3fa70ab8eca32d5e2d95e3166d5137b7136d21ee17fe5d790b37f51b030521fba37b0e1aaaf5bffd62db0421bc82798e58f6b94046519adbe859675acdc9efd050792a3ececaccc3dbd774a9cf426c5e58527021cbe8212c9158baf67a8d3ca0361364d0fd486f0402e8b5a94894b3af023ecc6b9c0ec8c9b717736dab8ae1da1c1913df84b6a5b7e6019e3e53efba2bead981e49316f671816b7222deeb8f3f4875cca353351d810f271d3c2a6663e34a8ee083d80a861338e22ff97e542878760ec0fcb8dbb390834409754b95f902210be72d7104abbe1a87979c0460dcccd2cfa5a13470855ead59d0d7554eb6b5a12611c5c1ec9db3ec7d3dd795acce3a2c4c71bd55c15986562689e808683442ddbc8ccb048eb2b154a66e6e19af41c233d6196155912bb1a020fabd6e803f04fab88fc677162b0d98c42500977c002774341c3fa455b6092d8848958c94de4641a43a269cc6903e512ceea3512351a05c52bcc2ac18\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 4ff317feb7f29b39f43c6dfe386347e057a97c5063007322c8ccea1761e5285a14a25cc84af041407130fde5e7e94d5196cefefc485d1c793432e62a8063557a0764305b40a7619b8e9aa9b395acd64a1c1321fed36e2187ade19b9a25e52373666cea888f5c699da92a59f2b2db76fa29b8e9d9b78e6fe42fe9d722c524a59a3ac8d7551ad5c5838c4ea92685ec6dbb23b6b69eb07e8a187ab78af4ea81c2d14977be336faf8169cc189eaac340c9578dc6d98148a14844c220ac1085a80c5e3e4c6f04a472cf1a4b893aad0f3370d56468ee1cef675b5fb77da481f128ce8aea30c67fdaad92f26db2df4c45000ef581e1a0f323ffb69e45981a6c1c8e45ffde22b4cfc0045fcb60e127820f4f1b2568797dc34ae29e916030ddc55d78629534f926a230c4144543d383aba05fd3fd1787bd70bb9fb8046d26c4d7034546452a682de60bac900337e5a27978e5b709475f4e01a1d57a00190b5e829d81e82f38450d3a21b5b6eb83ec0c491cd17cc91b6c0553d857a55fac7e8dbe378c95e5\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = c3d7c56f39e387328b551f8e33f1a8f6ebcd8375bf8a4ab92df72c732e73919778388f0a3aceec9f6753133626887c3a5793cfa2e8340466e8c0d602663cfc169643a46eccd913085dd1dd1efff1046dd441b1dd071a558c629573ba36631105ad76d89561f284c6321c9f35b1c4d5e588cc93be7c62b2db5b8c52526c8815c9dc5b755431de7abf8b2ae5750dea20823de561f92ec3630f80606a0638a18a7aa71d24a6e19f6ac3fa16eb77f769da4b27ca1b2bde187d10e297f6c8ae8c5aebd84e75948942bb64504ca0230a6801e58b23a7aeb2ae1458b5750a894cf6c5dbf3c60b86ee988bcef8e30f21afa7197e4103fa6f4f1a87680eec6173f480c94e11f8db980597e38c71f36e3c68215d810504ead6ff1b1291ffa5d178708ed3b0e5b9f5651fd1df9c18b21deaf20b1a8bc6de73de6e7337315bfd428156fac738542b38d03bcf1403ec210f67753e5b73db07d363ee85a595c205bf25827231df2bd576167e84c659e9276c7611a92fcc1e06af925543c4b11bac35df7ad14f34\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 313233343030\nresult = invalid\nsig = b2b73525c8a556fac8a98c717231601636d1ef1f6d52265bdf3da2236b35d6e673277bfa2b2b1222d6a90b50a30877447573210c87fd85a48469185198af8bfef4393e0b46b416ac0cb7fff2be11860209c340e470bd59d84dfa598b3635a5bdefebeb35feb4251157ec940a0c0fc6fd5ab97493c3e9c663dc943bfee7854f2da6f9b91a9dfacfb88bd21c15a488bf2b08bd00e311de4bb2aff850de3dbd9be9e73b9ae4af9a2dd0a7a3cea94f1badd56ae6679f5cb87cd3eb7ee6ddf7ff426686e551d846eb8399124e23d6b87897bcbbc0242cfaf48f8e08e9d5957b30bbb4dc942bced416ef50388b25208c5f4824ca875c4ee75eb1a705c1b5b693dac65e447e06f41251b295e05d4c5137bb7c0f451a19adb61bcf1282ce729b3ad581596d99c5876db7cd4a614112bc9d5557187b824a266434276c3ba8bd30c7f1541844a262ae8d4c09419c6e21881a3f4b0a8c3d958abd7ac0a9d0e7f1770d229177ad8afba36e324d254d36119d13cf1a47c93f0bedfb7d1776acca7c9f14cd56e3\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = 32506bd08dd88da1d3a3172ed17a6d1393f40413bbf2a7fa4f9393314b7d158a905c1e528d4f0b0c47417d20234f55e58fb9fd87344773b311fe4a77137a829d3a80dc77dac5170e32be53c212404d2802e1cdf982cf57261ae64d402790a7ed8efa42d9d807698884d23187c3f239beb3007b014e324e9f5f070cc225ede15115d07da064665f8dcf5a439cd6ab2aaa86cb4b7bd0f8d97c1c9a1eb3b416702b534ffdad74f447428c04073335bfc96b6f0528b0ba541ddc7aca70e37ba0b9acdb8acc1410bf82d5e6a8effc291f5701565d468c1578025f529be0cc7a2ae473eba843dd72ea8a6f9b3022c79d05e52964287ec9c2156745d4a14b304ad7d52da8a45a854becb8095917a4c7196afb2d73d35a7ef65748138a46c69253f0f67970daa38e0d435fd8f8763e9eca8d3be5ac96618629e30d285db481f23906e8a145f70fc8eaa71e451421501c579446c9545a1d7d033bd9ddf62e587b97ad7925b60a5a69ef383405126e4e0061b0349f9cf292641bb2050a86fbb505a68d321e\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 313233343030\nresult = invalid\nsig = c0eb720b105f53c191b4e62f76d6e49a1c2319c89f4223f1849b0ce95872363e782531d8a1a5a45e4422ce872327a49651df41705ea48087d797e68c1fefe0b25cfc01b457361ac2f98f2b6d675c04a62aa32f18aef7c488205cd1d82c6bbd14708125d86fba57f2c54a667a31a32af54d8df6906c07595d2dd3147fe4ed42da82377c88f44b7d29c8c1daec6230fed36b4e57191d950ac98c78fcbc6e9405645b3c5fdd69111f9e3badb199888d0dfeb69ebef4a4a39465cf9fbc784c59c2fcee8e367387554148ee6318b8a23d3526266206de788c7ec4d93e60e537bc3a13a99add8087f5a33e6c8904050a9b9e2ed7efac91db3e4672a192b6d11f38ffa57f5420043da23c4c1fcaf46adf4f7ee4efaa5f72ab4560953a1e9435f93b00a8dd4b5865d714ce5d026a0ebe9dd56ba7d4b35f33fd764c04850c5dfa91fd6cad03d71d41845eda65f9c36c7117497e82988aa49f553a510e812ac475a0c510eb03e0d5d531edcee01c475b7cfe94a77bf45a22e06307a9f6c6953d0117e3892d\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = a90662e02c0b8f5452f56d7343ba207ac0a8141977c46b74923a68f9dc155abd0230dadf771262b1c02db06de7bf78dc40904834e01b7b8bd07d48cb1f0dc9adc5dd140234b7ea8eb51ae64b84ce799b3948a8c7e3601328c3ff520b712fbe037d4ca78353d8b518660a0c0f61d3141f7b6a010e2f7b644665a2038a63174156d67f00fcddff3315d76dba6daee07d8315e518a376b3d4f695576670546656e538d7eb8851497c6e8428dfa0a5a10e3e7834a23968021c7cf17d2610254d411d2a9996fc8052c38c322004fb359bec00b4a781e4dfb66eb842054fa7ada84797010f1dff65a0729554266086e4767dbe7c174b8540f5da25578a3865caea12915e4cacf0284495c208dcc5096f861997d45ed89e534207c79737bf420dd5c9d6a6e81a5064c72c3cfcdd25d8a3dcaf2a9968aa97f8189a37db4a228ac26894f3218c1466343ad41d6b292621e795289bbcb5e80740ff91283012a7f747e0220ab94a8ce96fb54c417e0ff6fb1795f078ef6039939c24b9dd32d31c4b68069537\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 313233343030\nresult = invalid\nsig = d8436c155e096de5d22e627bff7f42869fb228581273e9eadc0c3f35be02077b3d37c8c6e4fb39300a1093af1fe0cb42440caa0564f7a78295bd1f8946a218051f7257323aeb227d80f3430576da12a54687c96dda4c2ef7e359d5fd17b7d77a2fffb09480d17a60c80f30c4e06724783706b210212ec11cdaaf91cb1a7648b3d197a4c2f4b79380f356a06f026358a5381a4c975eefab6e9546619cf4df87ec106066448644a415820af3136deb86d34b61337b4b0e3a53ec136ce8b26f949a6741bf067ad69da068af1291451b0b882544ba72b74248f6f7df5186ac7da1946c4faf1e1e0f08ccafa7bae6c9224d1ccb6a5fdb778ac4e55ae414be393de1da87424b59de23", @@ -4283,9 +4921,9 @@ static const char *kData171[] = { "66de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d52450000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5244\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = fae12363cc51e266de7d74b989085f10fc08f44363fab4ea7fcc56101d116616c43de313b70569cb27de134ecf35fcbcc448a81082678ee1ae427c48f459ab2c42c9085911a3d81c914f047ba46ef1a52a4983eba1113bdf0ee95e85cd23224cf832fe3e916d3bffa6ddcfee0926938b2c51c8904bec4739afc4f07979cbeabd514be5a2b87abec71c7a2b39c736d776442ea9e95e97ddfcad4c4c3b41fe856f81cce539b5057abfc6fb1aa153316ea4f8e76b8dc8804ee10303fc2dc182f7ce5d907e78729679333b3b012574b4c7c613c020ce1388ad37ffc0f6b2330cc5edf7ce9ba80eb984b6da2ac59aabaa3a29172ed2937920f47c17447e6185119b9b38a9935658997b487735a8184caff10a8f555d034552fd57471b293f813f19aa6c2139877992436fd1949ebe2259528c91716414aa72ff90bb5142d2fd5e7ba12d8df1ac995408e7fb645a9ab7b6f695e4050500a9042253833b055182657915246589f8362203b5517b2f7117d2aca015fce3cc41c6b1bcb2e672db142d5246\n\n# tcId = 235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 78caf448aa52e0fe470ef9082842a2f99079164744e63b4d3637e5ff0760088ff4f3f0e047475bfd023ad8b50f0f3d83d0fafbbb5db1e5edabbbd72253e2b696cb35705567079eadfb5ee3b442a7d13ffd92976c7bbc64e91d924c87e409e8dbe460e0808a5f31737c4a379b27b42c01e2b85fb703cb326e4b7a76d9446a17c406ecb2bffb48a501bc9e98646e94394edf7ac02a4c141c76bdef99cf52d4680e0c23296684ee7d0e935fbdfdac76299afb3f7a221fe45a07be79396631b8db97e358a0f4c4b29163d19f76c771d9fc7ebb68547e40f95f10f93ed199da7cc776f23c29b44a749bf6bcc8d4e3d50ac3aa6a9d13064caf8d81a526055faa2926324f46eb1ea5d1aca239f2d41523292bfeba89db64bb20e3681820f03b5b0f7c4ae5ebf7657c626debe58a8615b95a873c7bf306ad6e9ad18b6337f0f24d89384556eaf59c1eaab679c7299fcd80edb656cb3bbcee67e43e230f30f704f4a3e25aff07bb636865ab9fdfd830df834609d07719cff33ea0528497947ccf398b4a09\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = f2e40f94959e63e5cf5722139fc63dbac2712e0485718b153041e8c24af9ff96025b7da26810c78c4601fe6d3576ea33f3c041c911e8c7384ac86f062b0c77ddd03cf5cf91b35448326e04d65ab01102dff37c5a2158c5390febb0338c1c4ccdbd2510243f2f4ed3b762cc6f1430b7e0edf7da7b582bd963daf4d11416756309fba9ebca7eed8def4c538e081c966b11d1f2a3a7c52a9b134e92622397549e53a882f4e641071683633217cf7b0bbd4305559c40a3c5f3785c555705e6b67acbf7887d919c69b165b56e301367825e8394a54520a99c7742356ffb2fec914f968cf9c80af3beb72263f843aaeb5b32f476915ca6369984246ea453fa0d57c3dfffc76f8a072404b9aa5de9f8a5a60389f539d3de4c9e095f7fa97c1ba4253b7a3f0e61715774df20a73dd5acf30abccc2a05b3e418caf1b96baab1234a187c5c80ddd0ca0e35ae4f5afb7f9c56c7bbef028c79158d0d57c1dde1fd4c8e0252c372f684aa438a33669f4e18d087ac0fb36c780404ad22153d6de4f46f9081cecb\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 7acc8cc66f2c221df076ca4fa898f98c46bb0809a612920c0a7b9e2beee738e4403ffd34b35911ff20a9a23def8d0067b34177d1ebf02486dc699133e4fdd0a58b7bb29a971cda32617b4b234a10ffeb5e154adbcd83c478a00b9fa657b264dcc998d01abac58829c208120aa5f78beb0594ec507b9f7ac5657ca6596662b018cbb582277af76b9630b30e6fcffffb32ada6d256bba86077802db41f2424421b18bb906c18fc081ec6066dcbfc5805a729994d839601741e7ccb7a5b6564be1033824fdd5172aa4621c6cce3af870ab7ea9d538f5ec3f7f2adf54d1f56468be03689c", "715cfcbd8457f3b477490a55733d582ac7df3f087461112bd91c859d327f0cbbda4ba399fc7fcba66fc99f58e01fc6fdc7e77f6b10b7a624155b24fe2e1d9679400217ec9092ff6a037b1de3aabf66d3c997e46eb062fe64ab88433bcc3b471df2fe600e48b3056bdcd61be1ec01385402b33ae9ac55d8108b4b9ee1b15eae4f9f6471079d34daa33c24fabc5dafd18b86ce365003dad36c043bb56d5a7\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = dcd190da293f545fb08432ae90fd77e4974e5817ba8e7e858d95df30f90296bcd3e4ba1ba7a8e5b2fda5613b22cbf03681753eddb9dc975971ebf211c46196630501c5ef582a0cdbb58b8091ef5c4af1df4df49942d1077dfba75c73f4920231507b1b55ec73d1f1cb87accb52e46a0842199234f66b6489f050bd5b0a4da862801446242697802f23a221f352908e4a1d400f7f066f4560c8201c8854bc0ddaee5b45a1f1165dc8053e2527623c9321a412dab7c9e2f35db2b7f3a8f59f7bd4818e03598625be2033ddc81835308005f64d240d7253c1eea264426e49d4170acfbbd95abc48174d6c13959e3d8fea723eaf0623e4785ef6cf7621a4c65865605f1cab622a1a1add8d7f11266a7084f24c9fa1073b5607b90df4b786a9279eae72e300d1eeeb72700de66765d81f997d3635cc031eb8a962355efdc3937fd7fe3349994c5ed289d3656d50dd3844b24c3787785bd06527bc0d958850aa86c2a3a16eb41bb7de9ac214fe351f9424e3aaab67f5fd680622e690bb25ba967b311d\n\n[e = 03]\n[keyAsn = 3082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keyDer = 308201a0300d06092a864886f70d01010105000382018d003082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keysize = 3072]\n[n = 008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01]\n[sha = SHA-512]\n\n# tcId = 240\n# short signature\nmsg = 36313237\nresult = acceptable\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bdd0c9e451b5b3e5513a94492dbee1ada9ea87e65a8cd95cceb4d304294ce34bf09a212f14908f5b865c7a34a72e68e389794a2d1c5767ba17829e2044108ac7842b6bfe0a5663b433d656f4e38522c5a5a23c460b898833828d257350e5814291b54cf13089080f84998edcacf0fe5fca0c1f8b176b172c5f9989491a039bef\nflags = SmallPublicKey\n\n", }; -static const size_t kLen172 = 267661; +static const size_t kLen226 = 267661; -static const char *kData172[] = { +static const char *kData226[] = { "# Imported from Wycheproof's rsa_signature_4096_sha384_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082020a0282020100e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed10203010001]\n[keyDer = 30820222300d06092a864886f70d01010105000382020f003082020a0282020100e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed10203010001]\n[keysize = 4096]\n[n = 00e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed1]\n[sha = SHA-384]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = a454390b04bfdd69c4be2ad1bad96ec901639f0bb60df268415b4a93b4cd53510fe64f394b319e66ca8605d7d5f7a05dae5eff827060013503d857a977c09ef742525e43b7e69d3802a58206e696848a87ee17b2b9de6829044349036554c659c8f8866c401fe85869c0a5ea90739c4983a1561a84e4f0bceb00015a671f5283f41f0bb8599774829b6a2de24f14d83351c96e35ae1475c8b4bcd2cf66889237a206d147b0e949f2b2028ead379c74203017904ac09a5561a8ec343be22cf46c3bc2a87b12cf9cf6e8fb22de884bdd9677626b757a005d3745f387d296347d3852ddc2c4258cf572dc40df3ff6a8a5f9d8b1b410c54739b9ae182611ec01805c80b445d058ce2afc4bd58d87c03fc9500fba237bcbedb0960a1a02efef52b97cddac63b5eb0481c0c0991375735338ac84c0505415ad2bf8e7a819ad269460668ba8f8c879f521ec9dc709e406de023fc0f9129a3a94eb1f3af08d33eed6273e5166f31110097f5558d8d9028ff558e627c9c0db2454b134a82a9dacca5b4032bc0e27c4d41cf55e9d89cf51528bb4f08c6ee5ce651af3772f008a44863c851933a57cac8e29a84756c9fa7f80435b3b78486f9908512902d5461964918239c76b6790b780e09d2f1d3db1c59b275d20bb24fa4f518b25af3254b61d34ed8b444d3ca736ceffdddaf767bdc92b4543f68b25421cb8c1328f2f253e446be46d10\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 909c1f13b544933ccf3bc73ff5053a8a65a8f01b447d4b40f109cbde29d866368aaebf46c19051092063993862b32fd166006bdd4d988794d4e9a77821fc9e684fab1366a2d988eaca60e4fa8ea947dbc4b8438a9fc036691107d3d0be52c46c61342ef8fb7e08032921c1b455c55de28d58c77c1eaea03f13c26c4cea73d14acfa8ac2907f6a775273e7686ecf4b882b88a42cba11cd1efa5b985cf5a227654e54cdc9e2d283b80d250cce553fda636279336ba13f7f3659d70b5b2995a2ac7b60f329c62790d8eed1c3dacccd0df468a91e767c190be41a028d4efc1c5ed5e6f3a77930f50217fde9ce9ccb66b75731957959834839fa3bdc1a769fabebab03d3f0e605a12aa9fccb2a9421591a7427d82068623582de592935904b59a42e59b50419cd12d71da871862149a6500ec6870d989423346879551e506fada7c0c01b328244ac5f2e2c5bcbf4b5b09a4512a0edc90fee4d4dd9eb88582bfe37b49b8d8189051b32cccbc4d300284f9e523674a601b1a725722695d5ef438b770b575b6d0955edc761250bcc6a30e8d5c7287093236f223c2da8d9ab7d6b58e5d0e9167f2e8c58255ed16b63789ea16046bd0f987b156e9898076d444cc7a4aadc76699a2e3a442d63ca4c3f92da9f3b2c4ae13edf9d4e28ad206ed0cbd2df2a46920e298abd1904877b75c1a9ff80c5bf05bc5d1ab94d379d064fad894918ce326\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 65956121a818b842d861d0dbcbdef22aa05c7e94ce5d748308663e142881feadb85dc4421d9d01833b8b4c2713842c77949cee8b853286107c655de7778a5acca11afbf1d9dad429eb6a281c1e8ae1cfd37cdf530fd4f2b765c352bcea26ce44e2165c36553318d89b1e06ffd8a210cb988cbfc916a9401fbdaa56a1a2a4cb66ef00a3176182d33dec5f3625b760c37c82cf618cd2875079a36015af21d060dffeb5c9e1f4255d7fea64386d8d860c6868cd79ef6d7a87927753a78bdb63c4845306de1d73c5d7dccbb6cca9b65aef19a7b9e53d9c02a4a2bd6910e076959f9f40c30eaa0a6ef783c0b73f05566e4492e16b832729e03fc939e54bf0336d376a3b4cda534bee446dad3fe51d20bb8a135103e7e12220484bbe02e99c5803282ab90d11063e5243297f80d3f24ab08fe8f2fb62702b0543f0203972d35287ba64facbc635cb438a888c83c7028a325555f07521c3095bc4e38bd0f60eb90828319777fea2276e0bc76f2c13ebf92f802a08844209ccddd2aac1f2700e8a5107e86426e6ab76288fa01de18b8a63551fbe8705824d16e5190c559c7bbe8a17031e7d352a681b0418cb36423632ec48a8d3861136b250ad2fc72388e771b41849893cdbffe04aac4037209944ff3174f86f7a88414b1666727c960b1e54a2cdb82e39cf9f2661f4ad6e22f330b350eae7f588a623524617b1846486fe9f04abbf5e\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 3b35a042a4791dc1ac1561ad1038750bb9a575a7ff72db2ee60ba027f8994bcbabe41fed36417bd139a286ed0aa6c3ef2868a7251442d060c1cc67d4470c3ab7c307acb0c0641218a45b9cdde05546653850c2168a59f1788cd55dacd40afe38eb941ff08ffa8bbe609f2aa795c73c0368f482d53d691980891ba43b69f5791c2e6f70e17a996a299e60ce1c9d44ebb9f29e700e9ae216df749149f6c222d1e1733953553a792745c382d44f52ff404ed5ee04c41ac8acc97c250f9a5e3cc6d70902d51e8ac000d05e36279d83491dfe6a40f222bc1dfcfa7fa5e0197cf47528f77719e007b65ca39dae17bd0f323b00ee63b66401e2ec5f8917ef600a41c3a61571a4d922c0b0ad0a290ee054ad15e63f1a0cafb749f80cae6cbeb06be62e1608b502182d247bc6a37abe5fd750ead8b7216a35e74b969005309b14be36a31c5e6c2266701d5afdb5ca2314e2f32ae17387d8284ad2c7225fa63ed47e7245a65b74f53a5bd22654b3878ed09b1e5e070bc20eefac6c95b006b8f3e613b19f518c48ee6781a12bd08ad36ba384d03d3ea3c4e0b1facc39741f9ec73d0335d2ee735355955ed12cf8b999d155d389b1a3caebdfbba32c883ef7d0e112d86e6149a3328b63b9385c68fe8a7b679e8436aef7466067a8e8bb49e31675729b3f448e7dd3c048973d2a5f8f7173c4428f3982a99361fa691d1588e39cd4485c450158\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 09d8512c4667994623530a2317bbda738eb8917bc80c84b64793351463da171bccc88b95049a57ccd917a4687da3be63db21b0ad0972ed9ed182f4ecc8e06647675340192a57e6591eacbf15d2f5fbdcab568b16ed86e668144d9e676e55ec4df1dce61f672de9f53d1743b72993a5d21ffeb7ab58e0f83e297cccbf25ed68c70dd8441c119afb6c07fb1d83edd9bc1ac34046733c8b827d002c3b6072d74a6c2cf7f1d968e9f7b0873de8ee5adf902dc68fbc93171", "f763c425964ea6e3af6691f1a303ff7837adb07a09f728de3377fff74adb34c959d363db650fa5c3035febfe8c62a0cde3d006a9d34d51c5b2c4a1dd4f2423c532c6b5fddf03e0a05fdf8d857f98787d6f55f0ce1d0ca95a37177657035ee48bd4f39f7d520ccc48ee999777868b4c3876e2242f59b725798bca28ae66c267c507cd65fde612c1fdc9362994ee31134d5561ad7c3f523858f43611c249cca3c134d00ed966a82b800da11add213731b58caf232fb2094e9dd42ceaffc7002f1592e79b85eb6e39ed5de8484f5509e0f54166426095e8522f88363fd0dd7bf64414011a710c7834958c0aa308189819cd4488588b84729dafe163e79856b913ef55afed55e83ee5b812579b87cdb80d5bc9ffa02ec32a0d97b0a56bfaead58a438cee53d40dd197fa2eeef4aff98eb5590163e68b5f3de443909769080c8a6bf87e3808bf265a41a3b79f8\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 798f597e9ad4ba8b3d00a9527f4e785af5c55994e2953046a1b9062945e8dfa35eedb1e31af3daf1955d7b0afe74fbc53739b1aa02fa2dba629c31b211cd513e2248ed847dd579406ab603d3369de3bb07143a581734fd8b1ca0358c4fda639045be1f192b233efb8848bb2c544e4e188e0c7ce311bb4841077d15051c6f6b31998ddd8a7bd30d75b7b3c824358bccb35f8ffa8c0fc5ac37ed71cdd48ed3c0269a638317756bdc9287043be1b4f3c6ef6423f1d0d38857c195e7be81c3778648ab889474109ff3c7be0fec790d3f5f50b966e3df40c566f572f8f252d09e97d4c90442badf820c7db74d6fbb004bd7eb53c0b1a871bb9f480821bbb48b363c85c9866bf8a86de9c6732a3136f2c80e88a29540a9036b72fb8f4c898e7b487c41d0f693c91309bb3bc06f1e3b2fa9918c31ba2a4b82a37a927784a7c7d2aadc3301524ce2708774c3e2189ca188b3d85a33348d28ed6f080a06452bf8316d483e6a5e28b831797f85a8ca5ca922bcd94b9045f588ea9e15f2a20dd26817eeb80b3421c5de72db98843dc719cfb1aff1f927ee1df1bb718732159bec70d5b6d0f98a3fd5d42c31ecf4124cb1759f183838d676eca2cadb4d57f2d6a52cd0115ffec0fd79c99aa78df8c6b54797a590bfefd4c34e4c3f39750ba47f4d8002a131b870ff8e65c6c37b75e5c54c8a2bc2fdacedb41f30ed8bc9029819b7064b6514a1\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 41fa907da9f78e107b58ff6c4ac0e92a9bbc7f5b510260572fce4ef047c73cab3fb0d00b353b4cb9256dddad432c5815652bd83c78e657075781140de56189ecfbe1601f24bdce05c63f511a3d04673d24c4e943695d7812aad66f374a74a906177dc729090070cb5d6d518e7045f4cdece06ce2ae42e1177c46856a8425e60bb06040400c8ba0efb8d4f395a4377d4c2c128c68e6b30e358a73d9904d7aa1e517ef396526cb64d39b3b36ed7204b3bab1d91b23ca95b2ca1da3eee91c7d27b4e4e658fbf5060a79cce69be1d95252b0d7d7220797a53982dc371372969d4e06556507e7e7870a9efd9e03766702f217be1c8f7f80006c08d13e175040cf28b215deac6a1ebf3520a3ad9e91f9072dfe50c69d1aa5a0df73ad63f72831b055f2367ea35cfe676a4f7970bc85e2b58917d1bd449ed3d274ac40f7a515e261df3d067a277ae610e4ee4cf68b3a947ae8c8339c818ed10e73b6480577b2a13722023cbb09d3b378cfb71f6c86bd481ee09a1fcbb807338e968aa5af993697eab562aa4975562eea6b1169e86c75ef13e877cfcd4608994eadedea3eba55af19a7a55b19e92b974450a593cde717bf0d7ddbf0bbe8fef90816fecf86ec522a2d06a04ebbc50a1eafd67aa461a8a9cd705ece0bbb46cf773689cc19cd69607594fd2ebde06aaa1e34ebec001edf318fa22245876461fc46126172db41ae9ecd74700e\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 174f3644f5380c9d804287d8b58435cf141283eebfeb4e376493b401b812b525dca70833fdf626b043e70a71a9a54974be4b77b8fac0c8cd8b5141eb4c8a906cb16584b385124f2d339035906572e446d230cb60a0604e53454d8d0cfc588c0491190e2c26f46234bce081aab2c2cf15cd1d764baf46fd8b154e75e8be85d54c0b9062ee266e2ec781f7dbbe8764eccd13da5c107b46829590f6f28f595ef4de3744050fa2f721c3fbe1afe8250069d815c63273cfceb77505fec5844c21ad8e60a73149e5d7c3018895967abe471d7cc0800030c70760bd0d3d48d61e7eb12a0a27a91677216d0095a2a95a37f3c86942c1981dde4f7897a4190a270e962e2ba427b4e630e3187ab42cbb3f9aacc9c0f2eac9a8c44f6d73f96eab34b74dbba066c9dd56d32ba7df087dba9e479582bf73d5941cc107cad55c6596d4e25e39a7ee3704228ef978307605f2872eae23d8f2fc5d8c088b482e15adeda22a7cab9d00578d143d53af27b04416a1c3841aa88de6dc4f16b8dd320897d1498e4effb58a6d87b8ddcdcfaeee75ecb9ef64e3db62c232965f556ee3f74d73d2b19993e9a9b8d6ba56cc87fbbe3b7fb7ddcb35184ee2b881d55e55a7803ab2dcddcd3572cb8921bedf958185ee7046b12ef4e6190a314012006f8003aca93f430d121df1ada316ffe0b1ef85706e36ad2164cd1e40389b2f36cf10735e68e15022097884\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 34e01ccf88b7b25ed56f5fafc89ddcb9b6fade81ed2446b0c133f6949e73a1d68134973f59a551582bb3c28651b34fff77f97e91d947a96f269baef355697e15f4999d3b8b173c66c86eaa546b44f1aa42251df45584a938b40c6f1b5e1f8c58ff74f96257a044b10a70bc5075f9769c3c949dcde889e3b9c6d32d4eee6e312dfa2c74318954770556677d1937265e896bf044b3c0a03ac6ef1d82888a5a010787dc4a65a855368532b092a5f6c985dd720966fcd407d465b33426cd6e56ac30feff073bd4c55115bdbaef71c14f180fb559fa4860d7bc94b52aac8d121d0c0ae4c2a64ee32d1a1086efdb4264f4f93f4e8db096724f52d608bc686eb55f3e2820abc4384af6e4e4a8f9eca4cb3e52c43a67e673f2610ded69df520fec76d3aa50b9a6556fcec204cb959a0ebfa6dfb868068f583338e57cdcc2d2603acedc48c59500453522bfa8165c8e2c63e4ac97b3d4d70075c857beffb5db8df58247ec4842fda08a093df5ddae1cad03e374a350a87961408bf4fa99e5511ba42a9059a0ed73c1c9618ae0a300399347ee194003fb81f6e905f0286e1467fc0eef2c5691c0d05a480e52ec578f77d2616503061530de1346d1a424facd2cbb9a7c8da38d870e5f4b8cd406d41421c959101c6eeee60e092b2a5dc717f2caf292c8622d903856a266e31c7c342bbf09f8bc37f67f576a3e8b963b88ebda9aa31d093fd9\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5da09302fd2e6eb0695f2d027893f42d71476bd0ad8e1783f3015fda3d1b5d4fac1b56fbf133144bf82f874160a3a248e2c6a4da691a7db2110e4bd095d536e72fbde3b47ce0bdcca2fc9050aaaf2395686f98b8da83a7ad152b2f517125843b8306828a0d5ef8d4b3abb874373644e81755e7a929a33e98069c4d4d0a732b65c5b836c2b7ffc6a914ce02c2ac0d4bd5e67f7a395da04d8f24031d1bdad73eed9d08982216aac5a067d90311bffc2b109f9dc3ab4ee2c051e23880a675fab15a3ceebf15f114d79523ea5780d62a0785caddd3d345697b8a1a785b1488eaecbb863f8ba22a307bc835f3c832ce37de47a416136b8c2e559b38fe8d2b94c4cd376fbe209130206b53271f69789bd0f2596b85d9ccb000a15e3f2e7c50e8820dabdb36b1dfac83cf0a307ee46eca142eb747dd72972f0e824e9107f318036e83274ade55d53fb47069cc49cc51460f982cb712074082559bef436c501c968e1b73fae4adae5f2d7111a1741d1299869b5f5d6c831c69c4ab323c4e04227e435cf3cbfba1a3a9e6e6a64368027d5c385acbab0012f385ffa331db5decd358d44afe4d7d047ca4ec9b8f888930c1c6ca1a01106c8f7482ed80cecf0e244ee76e28527d8464f41395e949eda74e233282f50b6fcceddd3478be8b7825ac05f0f1f09617f31f79eacf10d90be50711b8d2c0a4e1f2062a3d6d4ab9ed05c0f6678f94e7\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 10877ae7a63a66b8249e34557c24145c4a5bbce1b2d7191ed8a6b194b5a14c6f0c75e157772c90553632c4a58636aec356e50bb15035b7409084ba68e91d09cfa3d090e1b4e17c08c56a3d20fbebd483df984b5f800c7724c52c19339db62ff9b13b2cb38b1187c5927ffe5728b8c7a66d3f209db3e2a490b115e6e854bb8b5fb6e390aedb5ac7fc93921399824120a24c6dfe8b084845e4921c5bdc04f0d3f9dcd7896632252b69727996b325e99a07fddaf055328685035b629c001078c8182e4bc79155405aac2324790497ca082e0d9e6b2707a011a9530fed0fb0e2568a05ab26e3cd1e613d6cf4f10ee619f97bebff59df634427584e26fa81cf8efe07c40eb910a7cbe463eb568cbc0cb1992146fbd7280064a8189d22ee23283f661b9e980d2403e70753c1bca7505ec92c1d688200fe001d597874968d14a8f3d8edbe436a6f7328218b69957b1526d22eea70992ed14526a0415e12534af443a1d8100578be888bad5e2fa18638d77dc5eb177fbb12045d6bb2fc70bd4ac3d9f3a202503611ef6b55b005f6a39cf45e3a896c5a726f8eec1ad5b68624347be0b4561df68afcbbd665935b4b5219d75af0252849ae4bdc9ae89636f7d0bd9533b0a18f94fa2ec5b4c4fcb63a0880619a887b710cb92b3376a407fbc6fbc43d5794dd243c7d235a14e8cc3e4f786c3bd57f391393d05c283bd9c62104fe04cef29c75\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = bd9586f52f2e14b0694a447fc111086141f8864f0d2464ed83adeeb0b702cc0dc501b899f0c1ba5acb0c0163191dc8f46e26631fa236289902949c087ef4968585a9daddac00fdf4430561fd81605f7f3568222da3c4cdddb9047dd529527a5d370c343dd2058d3dd3885157e4594d7af160e2443297a3c87c4214ae3ae2fb3c13a8ff39e1e804fbb39f3097b097a7d2dd568d885a5abdc3d1bb012349758e96b608050285ad3c80132390ae5fc9eddac40ca98d6db6463b8f10f79e4c4a98d2aa91b7d8d6b9c2536d8131a3d447a9622467e7170c66c72495df3f8cec11951db3cc6407ce75ef398581677753773bceb6aece44f40292d8de15e020523644acf0afc79e1381875b6a67168bf566665c4a4aab1a8c6a2a384437f4cd2b242acc8d8385cb39764dab2c73e2476200c2136e4904f8ba0479e5a6ece38ac8b4e99b6be4a2f12310b265a8470628f9d198d897cace6efd9cc2b8bd299696654ae205e1470521ec7ec74d2cfffd058a1bd1f84d72a5e13d2bf4", "4aa8306d78319569635d492c639397d886222d5de46f82dcc5bd9736d401ba2920577bc71e7cee77b9395732317b849d22ea98bd5c6ee461d8275df4fa8a9acaadc3db528d7c53e8b7e797e6647ddf9e2259af83b4c56d63bca901e1f0ce5414b5609fc1edcd2a6a7121b41a2f3082a7ba6fcc630fbc7fff4bc2535920d6e8345e0aa8d6240a5f04f1\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 23da245bc1defff09dc4a0adc58347ce419109e3002fd1300331a8dfbde68f4b17d7e65b8ecaaa69abc14134422b76036f4917b7d991e0f51d168074722a2f1ccd1b30bbd6f3139f147d29ef11a0da1204d4ad115df67a66d4d10509abeafd2502a6b671a40746861751e7e5912e23db05d0b3ebfa95f0f3fff8876b6f01af3dc3d5e94ccc7582536def9d40facb2c6d91e0eaef3ef7753fa8830c71e6e583fa21d423cdac47189337f8cca61044e492b073caee975cd3cd33ebd548eee68d7220fce78ba2db17ef8ae487d2ff06e94d3d4ae67e3ff9d3d78256403744dfc18c5649d529f3283b51edd7817cc3ee9a3d417d4e2e583f13a36bddc93f078cdfbdfba1c8cc486b50e8104f4dc862d4cfffc7c9209143d43fd7d55918d326f022db836d6d3ae155897aa4a12af78846c94e1bb42025a796d594920011945aa7d7f41eac8c0a42252286267433c0409371d20e312423062dea435283d3857a56d1b47248190b73b358ecbc998e7dfaa4f4b89acd10b05b58a172fa58fd37f07b707a978aa4e26d471726240edce522d4083477db37e4e230031cf06096d373d65e4e7fda47d421e4d000b722da6326d9e8fa5f09f2685f6af3a51f5649e99a67010bfb695f3f5bd8a6027ab1eb759ef0a022f5bd6775e5fe96aa22d9d76b375377e2b556199c940f0567f09899874e02e8b972940fc7d7fd632efa97a617c1d4767e\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = bec4ecc1e9935d26a8a448266a6d450ef1926d3e0353bb61f7d84934d7c66d66b4441d21b54abaf9200257fca89ad352fb0247b5b65fc952f4d75fdfd2c04a8b440817cf351c4c09493191ede4d73ca55d4142f1c8abd1982278c60c2f9f5f2adf4a0d1e0ad8ea2e3aa1778a846a91bcf4ba4b9637e4a2ae49ed91379c2127dce0fe03048e78dc9c37b700089ab84b84cff7872fe08d0d773818e158b896bbd6075af6df1a751909dd1e5dad968ecc91bc6219c613a4ab902de6b0acc46748a30fef9fb33a335820d737fdb353f9e8e5378e9ceced5b8809906ddb710038c6f2c4e3c80158f5ea4ab1e2357bee7f01e2dd2dc81e9912d8b260ef4ad38e181d7f2d5b07287659e03351e4cee0f0cd4e4ca477415504a8e59168937958e3eadda0a9e366fc370c308ad78505a8faca416e94b7f27f60f40709959fe26c1c6ab985a1141537d1fa110cce115ae45a10a3498591800e81102097ff514551819abfab67d876df37e1d04557ca98ac6d9c14cde0bd2e0f9ccfd6e2571750b3a69519ff2630c5f1a08f22767e9500727433126a7da85d992cd14d4d946aafeb596f7aa8ea2239d1d5fc0556584669a8fe968c7d1ec9f35a601afc7d8c5e2620af5bb95fd922dfb3b8d013f5b87c3cb1da4b3349ab13135a13d45de49b4991eefe8c6f6b1bd409b2f827288986e986cf08c643420b160a642dc47afb7af321d9eee89af7\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 6e5a44b4fe52c8104eb60e7d96e697c2fb0c7610fe17fe8c6d10fabc509cd3cb16bb4428935ec58fac84db83542ba166991f923a9889ee78088f0886deee107c1d0852ebcb295561c3977b2d69aa069e1c15e41d5ac47050b2221962413f9b5111a536a0a6c1762d04dd8ad96318964e34b8230564509e62d63b4bfd0dccafefc31bc44a0086daae5da89baf990e454f390343f1755f7db2bceaef0a310d07b7817a29371485d5abce1cb9b1e556b830e15b35de0b0aa977aeb1b6a54117bd787f7f9a64452123a3f29fc2e87256395102b6ac86bfde21c05a5aebd4862008be79eae34faaf324db09b5bc57e7e2650ba2d5a11851ef8c864dc5c04c58b132c208b7c579673b7419557d4bbdb47b2281129c72072d906e0e63f4e6dd55f3d3b2fc386a81a7b746a991a751d49d91a76fa4876b3c93c4b8e6bd9326957994354ce4d93dc93df5c5a8d115897d263857c702f2a95ff4a714d402c88b07caa43d4876ae5c37780a7a22a01e8f5a89ee1b50185a27318120a6d3dad156811ee818fa2d7b051d57c5a4f9b93a99dbe9630b3e301e94b04ff6bfd4361abcd95d86fc89046f66da80e29073365fcbbef0e7f29ea799e33302ee3a29792742f4a078f6cf86494c97e8b1dc2018d4a65ffaca21af43675a6461a4a8519e95f4320e2ce904f88ee8bfcc5d10a980684a2038b3dc8b34b5131995c684c89d01095b41b713be\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 856accc6420e940cb6ae49009afc46bc43ce4853098a25631d172c30b2d94b71268949c8ecb721a24f1d9b1dd0448f2825268c3f62c39a97d40bbb36cc93f36f9e78c1e87ae7e217a3f0f3b96c20b99c96d10d8a06b40dab75e7045f484bd6537610f423345df4b9235be70874c3754dc9131ad5041da7ce7c61ede789d87adac85dc9318b82985c83143ea1194c07386ecf2e3af4c1a72722c19649875378b43e85b8251e769e42405f70ae26d94e7b7492dc761accf9d793f5b9e3619a8192d8166ecc53679dc2bd1b8ff609d698bf92c75ac92895653c650ab205a9233237c5ef111d71cd13ae2cabe6c71f5164e896e9659afe547ed1321a6cf84734bccc19b9b93d796b54ee6f3f5355bf1a8f681854ada63ca8beaf9695c5da9adb1705ef06b3bfcf2d35be7793c48c8d8d32a1e2273714c314670447c51065619558c8ae80ef286048ced7e53d3c7b5293d1145b337a0ec34b21dbd3e2bac4897bc657737044c9ebf8c9d8ce82a33a56785a2f21c296b18435895005d1a5bef8c496a36c4608b9f7dff13bc7a741217b54b8293e8b754e1f1d98f9ad74bd3334f381726f405130509b815bcb09f34b3c34b3340870e7702b54dfab81fe68c20e1d6ec9f64ddbb73ef0768f3ed80babbfca7eafe69ccbe1bc8db50ed35614f1b883e702c04612af87fe3cf48063068abc42f3dfbe6499b8faa57ab75384bbc47c0a83bb\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 7658eabf44cbf5777f121c459c87744aee55b520f3163f9753d7c21d6487dabccbdd6a54bd8186cc5cd68fde76e6eaba46443ec0a750a1824e7f8e7581f7b57949cc6c44b5a6bc08d61178617c4ee99ec700053562efee3d8c7d532082cea526f6e0949b686399f15658771949cf6ea8eb455587fd328de1315180df149bf764ce52536c82b2d1e924e7b7cdc09d11f7e8e8e1279cfebd39b8dd64902206e3fe437697b0cde2620da6f3252d09e2ceb52a6bb1a63b407d3ef1a0ec2d6dfe7a413dd8e899b8da238032241514b44add07e2a3cf37cee9cbd50bbdecd386226b08020652bb651e292fb4ddf6a0cf8c3acf9ba13ad90e74055418d6cf0ec2dee44fba207a2052474c6e397a7eb30a021d2e44b343624657d4753706df893b031395d0cfd831eae47775b2a4ee21bb36f294f26a1ba1011d16d5a889edfdf0f69e3bcc10d85dd89f54318aa6403ffa0dd3711516a0d13771f04a23c7679a2fead20c57f067e9feb5f43729bf6351ee3bda720d5f01d56688ec2bd5f760977beab14b22bb72885e2b7f43572c0bfda433eb65e8f8c7da81414f96454fde33ceb6775ae73ee119e25a8f54a9cf33922fb06def12c6c6e3cdf01134a62a81412acb67b7e63778d675d110d8fbeef33db054737c9c99b86041e96a13bf064264d3abbde65af598cd60aa827f4f7416d3f3b0c622c038c7fb63ea7c10691e4900f0505a05\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5bdf25b34b0452928d5616140daed62cb7916283165722a98f344e2fb86028f4a5a6459227502f558ab0e6d0591f28bbafc7fbab5a5411167acd7183936d072c3192d73aaf5f02ad4d31d0afec686a6c6c73cb0426c4320b57b73cf6dccc2a376d0cdaa2b0f86f9aac6bdc3700e5df7a75fe69881e3e0573167f3b8faba3d7be21635e7dd10ce82c7cb74e97611415f7e283bdac4b186f7b0c4e9e803a9f19220f686657300e4ec312229ff8cf69fb780964d14c3654df79903fae9969058533a7d0fc29f417f98c1c62aee7eb260a318404e64164699d18a16bdb934e5beaad513d6bb7bdf1f30c89eebc2cc02e623aa7f52532f2e89122f50ad8be9cd3d6476d815e721b789f148be254731e4d5236a678a5894b939de88067a8f70c3ff5355b7a10c2a624d09fadffe29c97e6c2b655b22cbc8f99a1912539d034537f29c343e94d762496ed93072940bc2d56bc419dc584e0f984bcdb4681920d650eac7bac0cf2ad14457566dcb2c4165813aee4d2891adf8979bf38e6d7a3b80073ba04c35b2d161575edba17520fa709e2f1ad8ee43ff5327fb8f40935b7563c0a1487701e964b282c3e5e294b5d5cb570d18108c2d8fb9f9e2419bc154e1f865b2512bcff2424a690afb6d0f582f4b84a41e4a211fe57ac406db5908ac95a5a26d7de6c3d7b4b27d4a7919c8362293e8c8dfe21675e800794d31cb96d9a400c15df4b\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 20dc09d6978139edbfb570a17a39704a662b77fe4047037275064346e761f2e198046a42ba19087fbf5f44977615a8c3d26950acb99ef1aabb32a99a5a069ba7008a0f8594c4fbd7010ddcdd71c2f5bd2ac972d4f2434cc662443e280f2e241f0c36ed47c276563763d09591c80d1c77fb1fd2ca278448f3d183fdc16f1d9acdbdf94c7a2408ebb7bd3883767ffd5f7a392ba1945c2ab9b03da850e745432f0a09c7c02e7065c8b55c3ff86b171b78b13c3ab933ea1a76c332a2690c852f4bc39e7e8cbff8d71f1d2e614c611e4ac5b9f6340fad1db3a3484fb7a295f9e7673bbaa8ed675da4915eaaf0b3cb882e9b9055ae4bb8ca513762c73a78f12f42bf3cc42c8e37eec06f7caf1da5cad92cda284d07de75aae9681cc4cc9974e2683d4a56a6af6c792f26a281e72df45ee3b2beeb7667e2b254405c3af92889e6add37aacd2e6f1ddb106d1e7de901f285ec7097b15898443d8f368a0756c2c937ef1ec177736e94043689d6ab04abcd7829d58e888335fc64d19783ef08544fae0ef5cda771e481217c09ebbc12e41981f56b68c4c9078172f575928c7003606f69c3d75ef2b397dddb856ad5625035c274b5bfdd6ee91045eb8aef15004160b98846c817cbbe8e608fb1426daff941e9f0d358abef9d8b52b59d3d25ff41a44cd1168e6ac32f09e86569adf3dd11c632ad14c43a4545575f4461bcc29122cbfaf5440\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 380c5334185962bef9ee8ad0672b4b997f", @@ -4320,9 +4958,9 @@ static const char *kData172[] = { "935914f2a6d79090a79465c69239eef14adf66a32117709528fec892619c26f59e234b5755530d1c10c59973b40a55c289b85f5e5f34c5e147af44c84460e2ee834f0a4798f49aa61a16148c8a36fad5fc255bd02621b5f51212908d73089b10936d778b6882c031eda9e26c7fc8bdbbc4eb808e318090e89cd6daabb75c1d55d638d603b60d51d3f3a82ac56663a0e4df5d9cbf323e1ee7b1531e97a2129f\n\n# tcId = 227\n# CVE-2017-11185: signature=n\nmsg = 313233343030\nresult = invalid\nsig = e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed1\n\n# tcId = 228\n# the signature is 2 bytes too long\nmsg = 313233343030\nresult = invalid\nsig = e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed10000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed0\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = e3ae7de5bf44de7d357e238c8dff063ca713470777ab786b495884e7a9ba1dde65de7d2b5be3f2b7d1830cf6ca8ed5c05d3f094aaaeb1dd2e4b2ede08613109a9ba34c7e2bf8450225974374459f16da2c14192c637985febebbef01f0381e78d0fd63b76038f5e3d35dc7d2243963366af5d7685f1bcfc99dcb91e94c93019068353122edd03cc3e615e17c1bf1dd7c43dae86f47a40238fb594041cebdba25f3fe9593a6c329b7f7c476eab7625d17ba7be7886936b733f8dce6e6c937f588da1315c1117abd29c83895d95988d17f9fd7623960d8e433d7c6841507ff2faac36e0e19a41eb2cccdb2a2c0fae966719a99d203c924349bc0eea1374efd3e23099b2d187922016fd014087520a67363687322b90d7a890d8f4464a8c794d2a3f2070ccd3b0ebbca2b42bbf8eba6f2c0bf8008b5616ee7b81629ebff97a93a5b861989daa10da7c8e3bc7b0cdb095f6ce1185cf8fd3dca035eb3e505cbe022d81d93945a144806b9fe0ba07f3ab9c70e72b5fb77ac6e4c7e03aa2dce7c5ef227aba1acd48c1d93e0e26f01e8f1e43aa97880d15d6c924b060d1face21d03a796c86301f4a74339e472b2f96cd0755741cb9df3535077381ada84d1bc0846a6c44c8a8d3cfe1b7a9913d1f3d7af2c5ea4e67ce0a7ed3c0058206fd13ad9ccad5a8212f3ecd788368a6b6148178c7c5ea8d6d385227f2c76a047216e5e206b1ed2\n\n# tcId = ", "235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 556bb026d73b4d8949c94db2740b6cfbb17137b69cf269ba5f1be736ab6eb0746cb7ffbc5d7d11995b2053227013d5102b9484c59f521853d99f961e46611974f47f3932a8e1f82a3f5eb047cf7c7bfc63b5dcf86effae34ba216287fa23d5d79e7ea2439aad07fd751e190111308d9b49a524db7c3b0c939d9012f9c2f3edd9534176ab2096d4e3d1195566d072e3deef214539bd70223f712ec45f8a28060604e29ccf6e5031432c9623190dd194a79bea16a1b51745f2fc33f2d4229cd543a1d197813525c655b34def9990fcf75deabf65b325815f80d544528a0639383cbad12d18d4103abfb634a7b9dd68d416600aa4bee19bbedff26f81ed91e119bdcde3ca52792e2a5eb20a4c927f96b238bb478ab31230901eb99f856d0c92915fba339393d1acd7f29270b728d3f26614c6c894c11693d2d52a89da376530f3356cda798f1ff98277e8f469895e66fdcd8e685d663e9a4b9b25874626ccec38e1acdf1762e20852727854cdfda4682951000c6b412a1d0344aa4f7a13ac1a6af8d34bd7881c8449e645940df870292dc70493149f609db2624ad3ec293d8666bd8e6d8deb62b16fb88e662ca32f99ab3a7a99247f9baf9ebaa3cb2dd05b110d5288550042ddacf603388efca1493da1c9bb92cac856f5eacb8c7fb5650e9288635b6c44a47b5d6fd36c41637a6de1eceb135871e747318c27fd341fd5d3ebab70\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = af875eda2f4243accd942bf9abf7eb89260c365d64e610997961b3278914c330e607ca8342847b02c9ca916b1f51c2afdd95229c9c3e1d33dcdba370f472060a3f7ee1d74c8667bb8945b6f10bdecec96a9699895f2fc58f21e235d54f2988cf78d27b65037b7b46552412d30ea2b4e1d96167b9f720f4704bff09e3bf6e2ba899445debdb09cc9e06078f4dbf1794813662d522c25c0e3346132c53e31b02723cd0252ac0932e0171ecf11cef73ecf8eee9ce23f3ce66fa6301050c8e8ea96ad136968926753fbd09a4da0176e8e3d9f572d4857962d04aaf33145fd4613329fc4b3b50c28f4d43d54317752f983dea5432ca88efd035ce839d09867e0d84ed57e331eb7ed2de74ddcd625d13f3bb586bb4dbdbfba34eb0d72130a62ac10079807cdafb40c6383f08af4109472d2ee6430c3c301bd6bc1a983ddced8618b08db2fd4ddca07c9f48b668c9d6f2cb2755a29e19ca0c8d037d3db7919450900d217fe426f054443aaad6be22285faa923cf719350cdaedc8733ece6d62264bf4a0dc1bb88646f157686a4053111aafdefd412d3d7f59a2544829ed429038f1452ff36d4e8b297d0b43148090a995944b4225bdf519a6315d62df555d2337f7ef07975f0fddecef82ef0ca5bb41444d89860405fc06a8dc6c93bd23663a977c68ff8890bcd20988efc44df6891b9daea3af083137a21f3776f2e85443b359ed13e7\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = cfbad304e05807af505f5590a49eca630fc43df9950e5f43b2128a45d7271f2ddc86d8374af08bb478bc2ee3873f883ca0dd41f5aa853bc442dcf5b6fb1fed395d8d7d71f19a47e27cdc790e63f4bb6d17faad0f58efff1a36044448db8883325b290308caf5272255be1d15276fba4039206762ffa3b63cfd07c82ecbe0f8b68345f748c42729ef05ee87d7d5d83bf6f708658d7c45a7f457c3187f76e2e2e69bc74e60bb729acbd1bfac5b79ecd895ada4b2c9ba433ee513b651168fc23709bc75f27ac8f79336543d44af3910ccf66fff78113b103de9d3d0665157ebc14355e9048e04cba51882db9d70f41505e5343dd82894ff277417fc6b9524904b32655ff0dbd8899671b64b8f4e6b3878553d21da3ab842c12c0cc4cd88bc131bee41896d0337ea887dc729874922f4cf5b242296787db9709b237cf0b9a7712ca722ecc6842c11612dd79dba6b3fda11597baacd44a00519bf864fbdd3b4eebb923b7eee29aaa968d074cb45efb3304cb923b247867f819bb6145186cbf779b5c4d8b95add1b649b38ce306479e8684beda55cf68b2aa23359a9034c6b37e54262bf54e6cc3c959f3c7b8906ea15864c488e33bbec8b5d465054602798359eedb80c9dff2463fb16d153b0200aa01222fb3b2dd844f915efb05612a8f1f0371b2d668a68768a168d507af7765ae805ba3edc1f81e0dfc495d824212d1cb00012a7\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 92528f459c1bd0775d8c4655fb2fd5e8040f3265bb57fe1ee553c48f34738f3d5ad2ae40d6037f02a23989669e0ee9835f3fc7444213558f2eda9bb9485c3b81d99fe1ae4e26b22cd5ea7268d489d291d4f5e47f5cac8fad31027cc56138d5b55b3e45b05cc858afd6ed92bec181e1176b84ec33f134801aba8620b294b2238165b8182dd30c1831307ec35944e1611469a458ed3eeec14805562f88eba7e952beb9c19a8ec9c6a0c7e2418d0ade519c1675ee3b029bfad20c434ecf2b1105e76592bfb0341380adc413d566e62c9308f59d6ee717d25c5a2887af1c8341127b690156186a7d265fecb99a08421c89c8da829c6e242f561876919b229e73cea2f0694d8bff282231ad9b010e4d1c65483c2acfe70e0d840ab25e5d181ed7ff884f45d48c45934a60ffa6cbeefcff85d4bb3b6187a7d1454a2c08c5fa222715bbfbf707a492ac8fa2a709686acf466966823473d82a7d7366e253a41372fa2200cd4f3cc4d78a4bc2c425a53d1580f0e3ecc17b48bc55a8185688f3362a5ef7cb547ef4524606ad3e317f0d1027059bea88a0ed7fdf44515838e3a03fe059a804534b482801e5b1cc35ee6bbdcd4c6af53899cc97457224b8470cb72c4c41cb180ca639e18d45a9cdb38d27d9a82c04157c70d5ac18b623e79eeb9ff747289b8580257356e7a2488f0811509190aff1c7dfe3e28019f5f861543af0004f897ee7\n\n", }; -static const size_t kLen173 = 267661; +static const size_t kLen227 = 267661; -static const char *kData173[] = { +static const char *kData227[] = { "# Imported from Wycheproof's rsa_signature_4096_sha512_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082020a0282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001]\n[keyDer = 30820222300d06092a864886f70d01010105000382020f003082020a0282020100c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30203010001]\n[keysize = 4096]\n[n = 00c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3]\n[sha = SHA-512]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 9cd28bf41b99fa4df2852d86536257fe111f63f01815146c057dc3bda9b6633e49495d38822392b6b901e6ac69c4f09623a524e49246c3710c85a1957943d89c8399b0c2a649938bb07340f14c6981a0da0fd35163bc7eedac80ad1cbf06a4c32a4a08523554256eb221395c76e1f79a5e3c5b9636673db3ba27eebf8315468888671f8441324e092124df31d396ad8367eb7c9d0afa44dae85d56208ba21ec7c1f0ed6a3678f5d97ba7089422c662d86cd514fe853f38481632197c1ba07e4d92735eef3b75afc25ffa900769c74ba34f2d157e74bbab64cf413bc858cf6c393e8afe24f9e71168e97db96717d0081d88a27257d8c692dd0e001f3fdc2090512550ad38725c10a201fc50f8dc89ecf363b4d21a7d815eb78557d42e657cb44bfc785203e8de00f9e18af1c8e12953a33b0717af215d9b04b71fc320bdf4d558faf55d03d30844237551e35ed6606bc706ca43a47e6c493e14719049065eb8e00760283ee72c1ae3ce019ce3263a90b8340d1a47b49b78d5cae9602539b379186e5c1e847b69c75152036c8d9ef3c77ecd151bdae7ff36a459d0bbc1dfa33ce3dcd94ee2cf6ee08a77485746306ed987eebaae2baa544b543b5afe143e4122ade5adfa4fd463a246f29482dce7a51573aa18fce87f7edde842e7f21ff9e40c4101b922616ee4c14ea1af3c4d417fe8876af381027d837fc40dc684e81b9eecd4\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = 659ffcbf6b22f5d201fa4114077aa7df32b513a1fa5948ee01f6e21c1862a2b91863f7aa53d1aadcab9347955210a91829a5f7c86b3e2850bd1f76b3c4f4333615ceb22830a7a9d7a13436683a48995bfd62f528ef4959d30b6ddcc8ed2a431c06c337250f8274417f6369b7a08b927885df52bd7370d3675094bf1bd32a7f5b0ca9a399a59f868cfb78f87b8647ab37d0d7a58d6f4a58f3e3df7ae88ddfa6470050229754f4ccfa265cec0635f0360c485d8f81974c6b8a11adce3775dd01936b82db37641ecf5f43cb8538055a053d4085c38a8a1c4e0c8af961448a779288c5efaab1eb4401c8f388c0b729e42243d935df1ad3705c1c5a7ffb6ea8ce77a69481a3b930f95ff118cd0fdb17393a37139b3b5a9c275c6bbbc819e18f49c369153bf1f7807b450e54fc28065a6ab6d5b0ee91d0a9302ebc0bccd35c2fb2fefc341a954b67e91f6d8f3f7b62c5fbe504508594f357b1ed951fcac7043a082b9bbf41ccf609881861e2de15ee99d373c0e99027ff240c0b6fa52be2e199967860baffbe25b3254fcd375da7152bb94ce8dd01465290fbcdea0838a69576e97e63cb636db79c2799a26f94a9fb044e3bf66c520895b4683bd799e6b04ab62f621dc00f20a4adb131606f127b84025269466c760181d7dd9ffd0aa5381180b541e5e933e1841d6386ec55a63bd9d8674a775526d30dbe34e4db87067a9326c6dba0\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 46eaa4624a4d2c1f1043eb3d17b48d977819a8796f48f20174c50da624c657e64d3154dcfa2a5b1d8c6d2ed07cf1f1c19aaa611d6466f7e7ec73df5ee786573adc5a9e3c1d0a25559dad282db26e889807764115a05a23959acf48d23b3b33a93d8b6c7de3ee446f113eef96055d285fdfd27888e569c50f022d5e8abafc874dd5a61df6258e85268bff66cc5643107f7d9097496caedc185b37311ab6979f273e5670f143146b68e44b49389554772c1ca7bb7a12fcf67d67a1fd0c245bb4cbb924276ae756098599392cde076a1c0edc8096d9125e5a5d30c2a93d00fe2e0362e98592c8fd31ab5b4c3b34e65d38ca0c25874eb394e04969982b70932616b75ee2912c6a07f20ec70e52be630ebe024c0622aed125e00bc84980416b80cba7752eb90af2b8215c4b559880d2e1c577b7374531038083725d23d02d4fa5d8b5a4c68e9ea5e11fe2d9e03c1b8a4db0b053097b5a175b1131e8beef5d559bcc3f17ed2e6f6304c0e4650a2bb675aa8de44af8a2e301734584eea145c4b389f6180e6395412ae70e57f488ed15d45895be580bd87cd916b8f20e46ad2fff0367dda54266778bb444c6e4fdd45fa62cae3aeb54b6a7a6b4d8068e3a4d0730f0260340a6c32c3c5d33f514612c941bb63d730df5584933e12546500495b5ed3ba3631a3db871d17353d4c16676a0332ba4c4c4c68cdb6ff21ff737ee249be153c1d9\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 12813153b37fa6c0fd755a1c7c409bb8169c5a39d045dff2da02b2f8e8897b0cdc6c2d40e6945b97006f18e1b26983f77b70bf2961b5e5f2759241daee8c56fca7c53c81f69d3a0341720d9761a4f7be8c068464e881c85a2c39e0ac6f74f6f5cb42df8c3713f66a282d7fba85b7a09a6af83a068b78bfe83ab25841e4bc67c9e40cf2a0974f8875fb81cc6a115b91f922419c44ea82b33187521a7e1f46c0ab9459b4e97a3f4a1d9e92403a37168826fa0ee914232afb6c4d7dd082d0c58885e356d0efb8aa9ae33d045f24b4b3182d5c54556f5838c449d31a49a3ac4ba568c248ed72c111b5ffabd991ebf5c48efbca33cb38996d584992c4abdcc7b93700ca03619412a355b41b000a32f6cc4935f942209b56a23cfb7b788dceb692343995f77daffa25e44d672f8bc451f776560b415d0d1bfe9925af1c2567a8e9bd15b8554d93377c62b0addabd27e8d9e0859f498ba8e03094e1d86d41e69f7606d9f1fac04744c3b7b8fc4942a846e2a3649bd9416d500b9895455fb6741ed8ed4f426f20ab40d8ab2e6cf6c63f5c290fc011768b317bde49753efbdfd12583f1ca79287225f9c3d3ed0c4530815e4f5e7ed78d14aec0d04142d0ac0fa3bb5d73b4bfda2fe7103a2ab40672abf08ef4d9e537b9f856d32450e2e41d9277be62ad0675d1a530709f2747f51f17aba10381fdc70c626bab45d51166b6f6ad978d2dee\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 27a042625f50673fe9edab9aa2fb4c60dcae0be2e8b75662bdddec7b1d698065510a193e17981bb0b1c32e46d237e15915afe2e2d4890c09907e1866095c19763524b6c8d2dbb7814ac5047f0a082f7fed4109741f4719e12ebb91f27a3cda71e80ec8a7f6c882ea5b3de3c9f156cff033a0d3cf787f9a8a833a29d0c96f0b68ccf55ffc62098e21f0df1832b70878dc94ef1a3260ec2fa56dd3c4fece5d855644d26012f56d2af85a0771d61367b7e266577e44c44", "4347970908ab6cfae42069e2ceedf63679c2bd03697957e287d156b2717a416f0e4ad96868e1c7b80eb84e99778f670ca39c15e1f901def1efd824ea5f7bbe127dce8c8f53d849fe1172a1254caec13b10b0612e72d3f8e7206eee2620e8e3c0ea176deb4b1fdf5d8d37b57af553cf7628ead74443f98655b5166cdc08190d7e3b134d71c21bfacde3e4673529e6d8a9c7a8b419451e7ecc6c16a44b8e1b3f2c9d1c822df8f2b51d8fd027074ab2d1c52d16aab0a266c7d9ec03df7e631052e67a28963bf8560e89326168bb7c8f5a152f7ac54a46e88190c62a938628950df881a4be4136a55bad4f608d39ff37907a6f99bdee065e5ccd2921f8f1a2ebafcb336fc6ca96a207a5a0a7873420a2ea383a5f1c604c93b6c0ac69244f05d54cab184c6592e9bc4069df60d3cbcbf16729dc2f3f3540474890abef29e1b21dee8af0386ab61784d7af8d79c\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 2e642b8a5208890b52187729c43a1a308cf6b846ba1c2fff152ff4a1b051753f14ab035c2f3f732d5a9df7c2cb732d09f8147509bf02df8ad26924eeb04dded8467b66c5e3eae384568f624e55c81cfd8e3204422677ab62d919a176471b1fa8bae44bcc8d4d116a6afe5ea2773ac52a24186d6a4374171ce0516bba8733c59f38d622b7b6b7ca7ed2123f7f46b6c06b02f4c7506c46327d7cd908ddd503fd42be3cc896008eb9202bbd7af08b9908121a8b27fa44747217ef72a8c549444232e9209ca1345ee017010409527faf0722e3f13641ede5730639bf560c8a655e2f96cbba7b2811da8a1fc3e5125c92754ea7b823f394998b8890602b1713c2a4d352066e01f55ea86fe3da71f9119300d84874b667a6538a90ab24aec2bdfd9ba9a5f0c3072d549653b16f4a4319ca398147e6753f9a048b5b250c64d599115bb717ce85c8370df62c93da7e10fe705a12482e6f25e6ef1f4851a305aa4dc21b08791885867fc10c5503a769a6d6794ab5a9cc5da68cfc3546b0e848ed8629ecded620ee3fa6dc1236b59874916c45f9c409c9889bb85d7b289ee5f45f6d33262dea83b32c071417d3759cf650b9d43468ff0c2e922632e8d73feb4c55fe4233dc1f0cc6f6e522fbc9e9362f1d69441d56ee5f3252dc0559339335901f539ba274cc3640ec776a12c5c7e5c1cfeddedccce36884ea01071c2bcfae7ebfb5b874e6\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 811dec041124d3ed9d5eaa9c760ca5756e42525687d4af701231671e8f7f4448ea9b9eaacbd9c99659ee3c175277d30cdede73e1b332ffe41b8b737150ce1f1c67aa6b22ff801077c4241a6ff4af8f4db9462c70c13e1da86edec4042a70be9d08384d932681dae48fdb83149170472564a5bc68cbe952c76e476b99c8a5a1ecaae809690a014b28224ddb9c9dce0d4f6a77fa2888a71f3aa9b5deda0af40ad0464d9adbd26fde242523c096106124048bafe824f733b0af480056de2314f5e27db5aa3fd15705777e14efd2ac43beb12f8f496d09103ab377971cdd45e9afee8baa874c23d3942ee3a505bbc3901dd4cf55ea8a30fac0cb754793fb2d8f4edc29afd51b99140a8d03aa0614169428205fcd66c1047d3366fb32f1c2b1bcfed8ae23580ed254c3dcb127daf16aec1892714ee05a1ceb4e561a1e9c8fd4118ef8cc9e063bd86c55d28b8acc9d5b4c589583e7c6b78fd518d8ca85b88517f10c27aca2f0bcfa54ba5bb94ed5b005e3d871b68b86e96adf12588037adc97cbef59c05f0d2162db2e4cce41227df11eab5449d612be56ef6fc522452573340d4d68af0178d4f19db6a0ded521f1a982bc5567dbde2036f74d6d67b806ccc7c7f70d3092c22c9c1acf307b751d994fa5259a5046668a047afe4c3302e908bf70bc6b55c39726bf24ceca809357c623b89fbf0eaf8b5d18823337e7e0245d865574cb9\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 313233343030\nresult = acceptable\nsig = 47dd8953f9fef033d428958a32a4b30983d7eb9950c3d9acd167d50d9445cafe2bd02f44db5f7c5f6f999d3e1cae5b7458cd3220034132a3195481fbe5ba6b878d85c6f8ec53769f28245dacf66b562bec12399919265b3ce99c5f2217c3f5b33228a7300a0e87174675b379ffcd8a048467f04df2b5b7a7b8e3b8ffeb2dcd408a9363891518988a2a09453e98f7cd73aee8be03acb0bc8d67f7f944b62a717a7a5dc9869ac3d30e7fdf68cef439eabb8220c6923016f00b353ce5209ace5d387a7f50dbe09a7d2e521f1ce57251c48883229dfcea220e31810aff68da93744715f0720d49d8a5f3df2ce56d8fa42c02300729e8099df6e8d39bcfed502a5ef910b024e09031e141266e5493e64202a77c661da8c363f713b78247d8962b271e6ce968810775b6e76b577f01c24daeb7f765e9aa0118168103a51870dacbb4144389cb0e221e6529f9692005a2828e68936c339c96f7bcb4ae61494d03a3ff46adde34aec671b5aaff2fb61dc6011f53f9dd9a19bb6f0180ed90a4ed44ec0ecf97fc50c15607d1c6e42d35e36526f3a39278a7afa2601ba7610292bd6f04bff85f8c4f32f32b42379085b461eaee65de85ef2fbdce1d0dc39120f5670ee2ba5b12902878d2eae39290909dc55d64d1d6b03cfb4b144dab9e7bd8cbfe8500576e1a9f300818abce002ffedb4e8f2f0f58eab36f5c81929b50578d4ca3626b87fe\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 17ac14ac21d38aaa857542a9d871f7d81a829c39aa26cbe7db722f68e4397a7c758b11a0154edd42e1cc6b64047238ce4177558a0caac2a6c66136c8347ba058d6aadfa3630b4c44fa7205e0b8a9582eb5d904cdc7d25e5b9fc83bb4fc5723b3171834c07d59876f9ac771ee66ee17dae152dcfd86095fcd908697008ec1776536724d9e4322b6f7cfa59949a0b9be7990ada56722e6536b8e1442e0f0d8799ebb36e7881ccd52ddcd8a8033cfaf6d3e2a5f2d5aaa04291ab11e48e745c4de3fcad3120261d01eca03f502b69ea1d5d6f5556e9a198d663b05b7d631dc975cb7368b8f34fac47c621e60163914144b2e98e2f993606f1961d2f176a1b1eb17e119d48fd2249889a89be68ac78a415a8752f0425f1baa1cc5de9a4e0b51bed081ebdb538a70be96cf7519eeda55bccfa7ec5fc82acf88036af913cd8b30f182646d9f7f02daa27306f0ea2fdf436a40bace578ec2166a4080c7cef4a862804820020d9bdccfb2289c99ae61ee3fb3b3a9d3f6df672c4690e8c943f2fe23b5718a199439c5b2dc65b63d37e00440fbba51660242550484c94c8b6f504b0bb4e2579f1f560042b721db7d2ec2ea175401c14899062f9022fc0d8e4775c8d10c63cef61e9c649f771351b94620a3305f2d4b681c11089b5fddfbbdd291ccf9e1a997c1b2e6ab3cb1e1bdb428590ced534cd4da5a9548f3d8a6edc20139115d459853\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 15850012d1a5af88b5d1105aa0aacf404c2417de3dec04484cac687f6bec531cd569074e5c44ba15b27ebd131d018c2a4b463ae029bef8295e89c594c23ac9878e6d7a03276cb7c0b5231e887fa7e0fc3529c11e2580e329e65c669c346998d687fbf7e76b3539605753c3cd708dc19a072331d77290d810311b23a76137ddb50737436fa31f078852bc0d546364a28456c4048bae337ccc0fd8713c02713a987f89f9868cb64658ab1b8298846bd36b8efbbca088b6489d69a674aef11191c3409ea5b6428c2d847833db1563c77727706d2657ae8f249a75e23a1782024f23383330d11f1b91ca7b0ebfbe3f4a5fc6b2d37210b16049a2aa61030ed1c15b5d2ebd1a0ece36de2f53b36323a0eb25d4f77ea3582591e13f00e836a87a1fd2fd432f074fdca1a27e97dfb62f1666277bef1404958601d4e6b8b24125b4a86c9dfb260c3eb84750ba00930a1f7772510fdc0b265efeafb5de8c2525f5706fdf52a6e813bdd18cf683dbe94a6df2464366707bec34cfebb097b2f025011a0c4b5f263d30fc0c67c6e5a65f2281b463988ceb9b072718802a0a80a52f90af1aeadc8fb290bcdfea333a90b55c1a73839665df30f5b42f3e795ff1f57cdd7edfdee1dcbc81155bc3be1e264084ee3d7af4fe8d9a5be9cb2692674f1f608139b9707dc4c4b5b6968d4081236946f4c6ed2c8836769a03f9e87efd1c555f4ac1013882\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = b053f20b91837472425746c5cb3c26f4aa24bb58482556b418aad3aa6df71b9f67fb66855b83ee57e7a62aba93167d9a0aadb514c7d9f4c6e0000fea8525aee39ebcd59017fe5e58ba751c89daa976c158d9de60192230c0ce85f832882fb3db671ae091c886559dce66ad1d6ac0a5d1b2ebf2e1c30d88c46d43f9ffce192ad1cef57a7f0c437f6d25db071b74b49faee3b9732e9e0c7fef58e5b9971277411fff636aa2393ddc82202319f2aa5b2d14024609310f9c4fb6b8641504151f07ec1db8f729ecbbadd5a1d21969cdca6d4c9e7995de673ef79e95384f83900303c157ac79bcb681d2601e9b2f97a9438cef3a8ccb72a740750a2cdecd1b1b0df4a313e912701e82d76d4af9c8e18ad175345ef59968ea8c5dc62a8afb39f52515d6e8527902a03dab09419208636a3b0eeda8148d2ddce169ad3389776e10ac3a88b1e57f0f5da8e12bb1339f1cbfd367b221fc2754c185fd52897deacfadfa401eba9d55521592311ca3441c4228896a09c080443f78144e3e5d8068a946fa0d30b2187cea28085913ac86051e77f84873ff2b150455fc2486edad521ccd0b58a9055b049664d1156f4eb4ed393bf73a5d3d09cf7d163b4ef5df618dc6a57d2983024b779eb6a3331cbca72094052a8621d24d76db741a9f57dc42f41712b474cd8ad90fb348a2646f456c6ffd8a30657e344e57bcf890bd0a2d199bec9e2d5be5\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 313233343030\nresult = invalid\nsig = 4d8feae269696ba5aa750a49b64e7346de9e11ce331a3c7bf917c5467bb077099150b760541fce35521073fc68a5c638a5884fff577e97f0d78faab8161ca4c766ee4cd89e26d8b747671d84bba1865fd133e51a7e81e8986f0c95400ecb58c8b0af8aabc9ab352a675041e7bccd972c2be01080ad175c76e431ff670780e4b63d34aa69e3227696d8736a6d6fc2e20015180a680117a6f04f8f56836d907fd9efe10a7fb5a0f57f6461fb527494e9678568e168a83ad61b8c5cc9872f27a80e159f8547849186ebc43a54c41bd49c0dbc48fa2ce3781cec1d6623017035cf7425d7fd8a8562d3ab36c9e605738f82b5a77fc65afd217963e710a1e3a4e30862c8a8f18c97b095f68ae0878ce3cf1d062dd440764e19868c5b98f08575d65e0b944ce83b35028da466051d082ba66c2650eaca9ea9d83804f41437a3ea43932ddc217fee2c59765b5e862e85bed19e9ba0de41d64e518dd1c7c2f2f0b4bf44b40b26eeae0911d0c63b1b2cbbf3cb8e24a1ec6ddd70b9d4", "42313e47fd36d1f1624d071de53d76384aeeedde697c206dd27cb1d54e513621351444a4d139cee2fd04ff760d08d6aa949fe9f2c2ebcecda4f8478900503eaf172a63d4d6deeac67b3b880cf20f8472394451caad83af1e8de2e29c0bf904f288d74b73fb330fb3a50b63ecafee8ad9701361db09a1026146bbd0ffc4f0375488e5a178af304b6301\n\n# tcId = 13\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 5113288772030fec77b5bcea9a599a9502d8dc6b2b13832ae23c34e4be89eeefc4cdce3311fc6520ef8164ac409e9c2a8f6b3f7ae54788bd652f73cb8902be3f0f95c64b7135a231d8b0ac9dbb82441408eae432106aecd8167e0d3ff56fedfdd0facdaf1478183fc35a522e34933ec07844f21dcf76ed0eef71559769ee6b5a6bfb14f654528e6e24cd3f331634e88862f2b37e25cd61549a7ce207aabf6550292c21b187a30707eb0a463be2bc8ca7532f1b00f7bf3e7b561f685c91f6492c5b728ff2fa26865e6f1bc85ad84d44728fb549fc9d1ef6cc0fce603c3fd94ba8bf795fdf1b347a9f5ac58f1d922bc7cc3754cf427287a8458d075a148f6a336a0fde617f771789cdaf7223a2dab71448cfe2c2ffabd43eb839c5eca84538785e3c6f1cb0a19e532b5efebbdab5b98260f26190a359c378983548497cd746d4ee0021f148a6c7b5ae97e96d72565521b9d9ea066a3bbfba1427d40099ca367e378b227616d3d679ab5832b2dc93d2eb4993ade501059cfa8b916158aa8238bd5e1cd83e4a2ee676dfcb85051906f94a8861f5e2679912df5b48ba309b90fb383e213a70ebba0964b00f7df451c6d60ec38350e260861f5b5e86af8fadfd09d66d8d1c4955fc8dabba82b937ddea4003f9c39d4e7b152c4d13fd2e54fc95cd3c3e1bf20a065fb6a78d161e80bc4bc00c5bd93acfac027c94d21accbc423c2932db\n\n# tcId = 14\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 78e1817f4671f8c737dd45ca7d069a572d73010927e5957dd6f05ecede34487e8b4168e666305a80ead3f6f5701d350397ee730ffb6a320161c9743db09cdfa272683383271287908eb5a61b0e72cb783b4b0f341f042973247e525330201eed0b0ad881582de9ca70aa66e5171fc08ae22a89a6d5bf61f056ec02fb5207a82ca0270da42d44afb79f299782da7fc8156320e837269c9170dec5a767451edf0543361c5e5ef4f6a165cde8b0f6c6b6c62ceddd73bbab815d08340046579482e39a216d2dc8069fea722937ba5333cd47905497e512b904db8731a88006aa6b650841f636cb75c1b6d0be32b955389eb1f6ab5df19bdeb9ec19f090d7a46b1d45063126037b9f8f025816bc79d33b983cb576392ae135bcef786665522b65a6afcae3e345c06d551d5a122b305b413144cda4a58012d539bc7f9326f1a80ff70b5cde353622577dd23d10f75d206839274c771f2c6e4da1eb7b93c3c0640ebf7d3d8010e22a2d58281b8f811cf8f99725542fc9059228fd7e01113b9c3c8956badeb798d89606f481e99c222ea1918a26aca49a9ce98bd4fd658ded3c5a2c946643ff312d418b7b0da0e8d96ce91da8cc037c16280632083ee0032ef65532ecdc45589dddac1fab52f8ed55e35c261425701d9778ae53caf595d7b32510f7dfa8a7c86af4e358fe08b8efc19835e0e9c40dda2f1ac05613a26520f0ca5a126e95\n\n# tcId = 15\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 246873df5e978483ab6bde2bf90219bfce3d2b6dd6db3a32d5f3da3808e5ad945f1dcdf1186f066ef8860c8854cc80ea794758a84dcf399c9ecfc54f184de1397d48b2a15432422c60d50ae42ca8203be687f4a51fb27f46ae5c8ffe354b708d9e7007af22b42a2662a61ce1001761f3935cd6649efcf5049e4ecc0dadf8424dc3be83a299902ec387e42a79207170bea5db24c729d811b6ae9480065809aa0956760d40fe0759024af27620c12a9ce2f842b429d005848857a904ed62cca6752cb5be1935c6562c3319d42efddd490705eaff46c822f81a28c6dc44dc9e08893ffda5e044217a6e01fcb0f6e55ef1a6393ced7049657d4c37b3dca55f5ed8ca383a4a72c3a6ea6f096d1cdb63c767d0c5f4900006ced15e0d39a1a6c2d36f69af25b2a324fe6568e4665b4ca9730f50aea9ac98bb2a8aca25132e614a70c20533cc0b78c1092988482dd42cd13e4a3adabf45f811d638915214b184692ea09b83975a5e0c3384c9b37db667cf321f3d297c0f4fea1c80ed2fdc218c0b7db9cf8da370cec25549f2a0e5be001df317f0d1f6f36b4dbbe4a499e5e5c004a51bc88435872e4c4e34115619659b94bacada61e7d3283bf5a23e6c548bd089a6553524e430285e2ee278768242952b041732fc7091260537b0801d50e01891cdadab05c671a39dd46db4d9988e03593f7b4002b3ed4b0ce1b0e6d5253c423f59bf6e\n\n# tcId = 16\n# wrong length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 0d93eb247bbcf1003b3360fd8ab063378baf9ca43df1ed46aac03429ad1d817071522cc56dfe61e96db6ee747a5ebfcbe2ae6ca7571b17b9e8e2a3f5fd8879f167d3f9c20fed72058c00801a4058446122ef04d8685a16804ff91c0073efa697ba4d6639fd789a3fef6a53fa5eb062c82c974bf8206dcd5617ed1851f537643ae16b58e368456636b56f4fcda9c81041def1cfc854203af0a5ad581ea126bee84a4452c58602a2eed0ee082ef19f4ac75f8a7ba52d927f35a3bdcfc64183238adf1174dddc29c49ae4e1e3388fb08d28d9cbb379dd6c83903f096f395ad3bef4fa245e6aa7af5533ab6bedff2775649e5cbe89513a18b00ba726954ef0ed94865a7d9aad1e845415cbc19e039b3f7a7e4fb8a0b47edffd9c6eb2834331f0b636fb5eca42925b5dab4ba08078a71a6e44896abd06276f6f2e41f122848b94e2a22baf2d262a06498e0084f700ed1d23faa7b2ba9f7a71673f4f8c2a9a00e611f53c2095c43d9e78c1a9dd73cdcf0b74aadb47127a990ce7dc335ee26f4c13fee45a1eb44b99b2325fdc30e33fd675fb991d487efd478ac79c8d7a57dd210c5cb9c6fcc7be1a7e4a86f2ddde1ec8e4ac687b61231646d9457b4bac5dd5eba2eecfadcc5852dd2f1f7b9a14a0d346c6effce2549c9fe552bf1f21b99e5a013d41b5693059fb905bc30eb40b075ea8da092fab2024e6c03c4630f53e31b8e78be253\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 3fe3db1dfbb41a675e4768562c60dc2c2ed3c43022b54f4c9fa8e99de6a93ce650984c6c27b7bc5524c0b032c9115fae2cd23ac7b03e496c6f4785e7045b24d226b2ac535b7eb605cf8b56906ab95ab0e2e6cb3e2b3df71b714c66685a2433244ed153a8f526bad60a530c97ea9a238fca6fc5aac295a257b32fa6fdc68f9216d8118907f282df1fb2085644cd8c51d1be9f6dfa9f3eaaa57acc75d1bd29c3a59f167215c90603e790c5658b2d7887254ff80630122ab5578083556351edf1cffb7e42775a5ef79b2ff6cad7a1b8f32a7704bdaad7d63844b7cb7a295155fd8643044c3a83f867d427511e352079f578f00fa55575445e4af5c6e42500d0e4ffeb718e13076d9531195bcc36333960060830496256702c20df4759c74cba389ad73001f166a3b6c2d9e69d2b3bf86a5f929c79d17483164d76cb43f8723cda7648cd37e5d9d3aaa5cf9d077a6f3a1135e3e62feac9d0a0d8c15d6cade7ed6d2b568f89f74d6892d645c89bbf1429cce33e525c4d151a0a4e9192fb6737f151d5b460c4915ba57e3fec3b537aed97ca425f58a81beb3144b5898e27905ae56539c97b9994cffdb9e4bd91a600dd02c2ab3c9d8c668ee077a2f1f58c8ab7d0db0333190c59d37ad615dc3029faed93f31a4334a1ea29bf7b53f3d9415b8b760891a4a649a92781eb0568d5442b65e574193f040af56e5d33d2e6a47da09b7bb8c2\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 34e1788aadfc237f7896f530426725bf06a553fad96003cf7f6dc90dc6ecf745ea1c6ed5facf0fed6a0b88f9eaea6895b6bdd4a6e79f114a75a01be620eb5eb782431bb58feef95956cfea2b5fbfcbca452f65ea049663639e996e35ef37c27987015ed3af600598543f1faef183199ceaecf01ef86b026e974721a94a549aff6545f42197df772729797f4b6c6dc7f500106a793993216d5a356104a72c880f8e55343bc4593f13f988834c03c45101a4c1b27ef8ade0b56c4df4592654c32289a706d7afd7095e7f8a7846d2607d12a409c67fff8a3997e4d6963abb979d51dba6c5be5e58b105738744acbffb6ebf7428ae4599318948767b40c831ea810f5d11cd3de09a066093205e852ebc663b0b970497c64081d1ac6a418289f7ac2eb755cad07390c553bdd82ff5dacd2937bedec7d84f820e054a3ec16ba447a8c25325c0f1cf1b8df93443c56947f5c9c8ba2eed73d379583fd6c57ecf4f70e1b899cdbff6c6d80834e8e88440cc8bb2596cb26df266544326c5a15b4e6fcd6f3296994ff3887898d95a0d32f92d179c3d1dedac8e2eab8e097770a0b35e886c2fe65fbf9766e397b746a2819d1e1d4f8eec4f7354e504310241bf6becf0b84d21a2b41ac6fa5ada51cde86b8151c409d642bde0307fc732de16476995628f79bf02295929e220e2a16dc17c6b271be629cbdd43823e0ac5a25c4596400b0b2f2a\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = a79151876e4e870920cd837bdf756398cf9929bc47dd5d082916cb622c05b52f2d02406960c2eccbd387b722303d5de1edb4f0a2ec2ac82fe2842dc6b321bb1ac772270997594460bb14d9ac27c3fa7c17ffc987035a30784e0817b4a90fdbcbecddfcbdda814b2296b2fa976199c2cfe8e2567a56b100aeadc571b8172f05eabfe8e10b302fb3dca6079c387914430e64f32c5267dd41782fda4e134e691eb4455656f740048640e3bb1226d47f04c973236a2c0a864cb1bf0dd354f47df45486c60ee8fd931328d8298aa77dc561c394dc337b418d4c41040fc3f15fe72d3b6ef9d3c582c939b6a33692b8032ef32e025683b015c276161e526c19c3e4223e71460918c03c31496e8eae68fa97850b051208e2a989a8e53beff882484992fe9b5c47a4f72849aa8d7896adf4592736e31940c714f8198101d123b72c2715a18e8d58d2c3d7d0d3a36c303f62ffa1abb5f8ca057aa5c4030af66b931fc6bf80389d84dfc1af44dd69e73bfe22f76ae6c0da7f936f06f652a9432697a94bdc2f869f8ce2338cc938cbc2c7809a4000666002bc351ffbce64a860d7e00bfb1083c47a2cde7ba67ba5829769b0bd63d0f2277f000faec93e225234e3cdf1a3c41c8a327f67d41eacea3a7ba3dac55072429f47226d95c235857739027b85a9462e7a9906d8908e5c7f25f0efe596ee4c05a22b611a33580054686f6dc17e930a41\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 313233343030\nresult = invalid\nsig = 18318a9ed077357126cea3c22f6dddd974", @@ -4357,9 +4995,9 @@ static const char *kData173[] = { "53c9c132c0ff27435a6baf40d77b7a52ad8e8ee7ed6f0d6524cdf060e3e843b538e586facd8a5f5f3dd97712ef426f229d803ac6d6ee6567ebd0ccc467b2301f567c92e1c4731a4134c18edc00c55779d7a34a6c155823320914157fe9d7226907a7750bb78f7b6b61b134c18133de7dd4357a7763f88fd3886d95d47449a6385243cde3bfb975738e96078cf8759d516b31268c0052045635ce50f8805ff0\n\n# tcId = 227\n# CVE-2017-11185: signature=n\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d3\n\n# tcId = 228\n# the signature is 2 bytes too long\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d30000\n\n# tcId = 229\n# the signature is empty\nmsg = 313233343030\nresult = invalid\nsig = \n\n# tcId = 230\n# the signature has value 0\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n# tcId = 231\n# the signature has value 1\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n\n# tcId = 232\n# the signature has value 2\nmsg = 313233343030\nresult = invalid\nsig = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002\n\n# tcId = 233\n# the signature has value n-1\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d2\n\n# tcId = 234\n# the signature has value n+1\nmsg = 313233343030\nresult = invalid\nsig = c9a765c2661b4674cff3480e9a5e462ad0ad2fc9bc6fbef62847b3113d20991f653967971c28252753f5fbacce012c2a8ab592914d269efafa724fa4b920e340930c106f7b36f79cebf0e62e88e0e476888e9f0e22186acdb6c4523a232b65b4ff2cc22dc44f8a559527d79d7cd7dcf3773212f7bb9aa133c31165cc663690bf123d73923c838929ccafee59d6c7095b8d4a74baf2d192c9a4e87c4e12bc58013078b28a7789e82e9f31de1f4d6a2aa6e80632be8e4bdf263e8d49b09416fb19c488c07ad8af722ab79182b23028a71e065d02412a9eebc46d7d8f4e03d79238d8c0cb4a97a9a1200ebb6ec64042ebeccad9567526eeef12c17d94c1049c889970b96e94cc353172a268a49c5e8bee13c15b39dec44f2c7a1aa37a7a0b6f72290acada32b1d8af1fc3dc8a89487ba81347cbeb1350925d30f923958106b49959c871e7c1dba55da0772e362cf8621d78610868b894e16e5dfec96874a93a4cf379b47e7e318ce315066d70ee3938140a60148f205085cef8a7700ca3c53d52a5756a63b3b16f153062b61262a68496210c8be4ef3f9029ca0ea0e3b3a0d5d6d226edbbf44daf8f045dc286ded3c4ec4db6b45347079f33eaf98e3c95b4b60e79ef4a3093feec543703422ba74a118511c2193b54fe8b633866ed2c705ccbc6e7d9d3656809ec3d3356e7400a9648ec37505041e3e31af1c02eefe924a67047d4\n\n# tcId = ", "235\n# the signature has value -1\nmsg = 313233343030\nresult = invalid\nsig = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n\n# tcId = 236\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 9e591980e9ec3d62e2edc3163ac8206fc09fe026a2f7e622dc5a6d02976d30ecf141295335008d91a223ee98a143541494ccf7cb06a1aa61de524fb5bb4b379a67ed2ced447c7b395c57a625f835dec6844c3b67a85aaae10e273d3902f5f30539711f98d73f86beccd798b98541a84a03ccb3379e8eff88c19c88aac7b7ea99758194ffa6660153d4f22c1252dd1b7b574e19b3492f28cc097d3ee3f30f6b88576bc6299512f9f8749e0b297295bc275ca59f8056decfca9f3980e6f8d6e07b73e1a8ae8b3847556cd67ab77b96618979ed37744be2d6bc9f2b671615f1d4c4c1b419f05036148182ad4c6375f9e3c7cb37bb75d16c4486e97c0ac5685995cd8e5d76452934b26105be9074b2f8daeb1add13c9b127dca2858e5c80e686791a6f98cd98e540bdf27d21b2dc9fc84e09561df968d73c190b3081293d666be7d991761f4722450ac249a6eb4bcdf190c214630c85243a6c5970184e257c00c5a2a18bcd20195fd041887f001e06d4a6049e210cce62356f99853f3da2522d3d63739fbb2ff315e68ab4a05ba1e29e5b93808df51aeaced52539d7b956db2f229999ac09a6d4c2ef8714ef9d4783f538559f29af9d850bf71b001f231270874fb8dc60f1d1554f60fa69cd657112530e22563fcde26c3c86137e476a2fc1d8ba4a15dda42d4d8a20fbbad7586f472b716d6ea2ee30f1c111bdbb3db8e5e2d933a8\n\n# tcId = 237\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 23e198d582d048874ce4e6e69f5a81234ca08be1fc9cf0f7be05454997fad87da8f05c2faf7285a7a9ca7aa50f772b8175479b7bec85919162b8a7eb7cd4c1b8f0aaa64a8f371e23ec2c3428d7d83411f24bbd4b80762a75fa0e5de468a71dbe9bac382b4072241e3c7085ed2b9e72ec3779c1f70bbd0f246834f3e81ebffee13312d133e1ddaeb58b84d1ac1b441f311ee1e2c9693e300862cdf5b4a5d820dfde870da22746be0b12dfb943780c0ba928c657c54bea0d84db37fe50f0965ceab905f2ec3ff177421b11c30e846ad93212485e7f6e52d7d51af1c96f31fef174ab38cfb1b1fb5961cfadac518a6a4991ff2d561a7d8dadc5ad430c94b40c04a297012f81e6e84ca02879fd82b73744c4372ec02f141ae6c4ce75595559f3f4cc9e4b7a7a6d93636487e34938082b3fd5f09366a062484d1820586a720a9618ec18d980c969a28d74c81fe4fe7bb61986769a89716c965a7f056aff60e9175527778210eae23e53e244b973b2452f40ab375222621a89e1f5f2abfe5039708f2a659553582f760f0d264f854840d069e8c4db0246738af1697b05980c1f53a1ba4eef8e08583781c13a93d03eb19db75e71bdd0602b91908a885b41f0b8d9588d6e05796c8a6f8d220922ef9bcdb026af9bb328ac7d96d4078205ba1abf00eea45b9c260e3b55da036864bf5bc0cc2d3944fdbcc7e64539a45238bb2061210514\n\n# tcId = 238\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 4a80cafbe2a6095f8e8663f6289878514d7ee7daba0c1b0a077cefb333cacdf7c116ab89b0a01cab3161c68cac92a08aae7d117c9a3416d67365621da3380a85ff34a7a3b512846048acd1ec5957af942721c241a180a5dc5d8f6f6fe54d4d9fcb3709cde37081e2233b4fffa201d2029241932da170a5bad0d927a803a7f6289fc9f7b1d41cc1a6c94cbf588d5492b363920d0c98404f5da9eb9457648e2a4e9a034b2e2328c7f8c0e794771641a981df765887b5ba19b769156b375535911e1a2da68bb6a37eaa0ef8dded4ce3eac5caff4e8dc357703f0409d00baeedf3fbcbd6895dd3938e1f03dd9f131f9c979e22e4fcbea0c58721bc72d1f4976e93fc1a7649a23745c0310181031ac34b2200dfb4e8fe9bd4cdb52a23c31416745521aa4861eaea7dec4ea2c18ae9f75fa9d36c9b61bdc4185e434f8cb091cd731607b749a3990585cbbea2b1c0e0fff4f589a547d320bc7923b8a6b594c5866095df9c914cca80cd6c0e9aa3d691e2607f9de64322031ccfed04d9c805226cb476d3246d6caa1b04c63372a77668d5edf06365827b80391a6abd66010e8e1b873bd83db4dcc99444e109efa2414c6e5319f30a718eb43a1256b2142afa2382316e37aebde32da5bfec93e89d2adc39f62aca25a2289933a7cd8234d72a9b3c6a001d27560f8c8a2d9a233bac0b519b34f4f79288ea2cb08a87242953ac24ea144143\n\n# tcId = 239\n# RSASSA-PSS signature\nmsg = 313233343030\nresult = invalid\nsig = 727f107d20a02c2a2e530a78fdcc8ee88816badea1204d4c6a3b116776217f86f6fce6612cacb44aa288991146675cc0907094b5f90a06f0e940c886c07b5157605102c670aa9927fd0f2222b737890d1cb905f0fe4b47e67d254e6fef0f2004be64c94ba630839199b3656abe2c6eb59e84584bb652a181a64895d52d46aaebcb46bdd5eca4655eee4c340649a49a5eed60a2d3c95762bf825f622bc48d05fd6813393d39021c0db5b2104186f5cd00b203b43ca839c192755b40a8d946d1db6b0d2d7df6ec6929e5655396d935ce9d45bd7364b1e8e2bbc316918d33caf6a08ff1c8404fb66cc679f03f9ed6c5997f72e52da5df41af58893129bccf2fe3f2ab7173fa227f24c30438e064c0c1e99d3ab9bcc929391893187b9683cc1026546b6d21c02fed28fe1c43bf1eb679faa560375d445af434fdc2794ea44fea6445a8e89ed6c14379f756070227b20cc2c0add3a6709be39680eee5efac9697f45d2122a51ee64f9ae310c6a9b85d0b300528b858581d59e59c7755a0764c59cb81d355396042cf8150c91376660bc737d33144fa7b6d7231fbd43c16a79d06de0fd18a53415acb352065cf169e82abf94a3337e6b525ddc3d25eb6516208e9f832168faf3c3a224612c9791369ba2ab85a701e8332b738bf2942cd20975d2edac2ece8568d101ab8602d58fbdf652580b5008b499aa06062bb99697c41ce8e34bb\n\n", }; -static const size_t kLen174 = 275879; +static const size_t kLen228 = 275879; -static const char *kData174[] = { +static const char *kData228[] = { "# Imported from Wycheproof's rsa_signature_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: RSASSA-PKCS1-v1_5\n# Generator version: 0.8r12\n\n[e = 010001]\n[keyAsn = 3082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keyDer = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a70203010001]\n[keysize = 2048]\n[n = 00bb0d4124c20130688b8419fabecc427d946c5096dcf69ecb0eb69fcf5aed15d7e1e5fe4e34fbe26f8b244aa3f088d546a00a531464ba4b8980bcc4d5e54bcc20e1a51afa9044f7fdecbc6edb751b5a5fa7ab403a04e5f77ba7865dd6d211da0afa71262a77a63d9c06e8b00b616ca15f11ea5b4948973864183f570347570553e3878376ca4f7536ad5afac10c0a7b34a5c11f8cf16115fbaeb4b323b1ad6f75c7ec3b954891cab2611cf1768cec983c1717c57f67676d721a955bdbbc216a3345bb31d7d63e06bdac96a6b991ba1e0113d01e48c77ab327d36b426c2f8fe4825a37877425885c927e92423b6977fc304122a2c397cb74845fe9961dba22c1a7]\n[sha = SHA-256]\n\n# tcId = 1\nmsg = \nresult = valid\nsig = 9f420516e9d063e5e2961accd80e3eb0198b10f4d64e749b5bd39a80f7356d2ca0fdbbfe5f5b2bba92da7616a83912b449e69f8ce6e35a27e9e553279d6a9317a1d07d897dddd9a8291321359c6a8a31a4ad7dbb54432bebaffbe8940e40cc875d941ecaa10196e1aa68b83e0db67e34f3937dc1dd11cc0e5b40cdb0b90ecdcad793d7279dc5b5f6cb356b805e6357baa1b3659dbbdfc9a0f042131760fe1b78202f289699e04b5c55f3ec26fa25460ce3de5aeff0b1f5c435e022e1168f9fb86147e7a8b0f11cd988d59c81c3fe74116b350e0396b1cdb2b4e0326b5c90dc384529c7f794c4c2f40958f97ea203d76a75076d5360228e7ddf166842b9165e8e\n\n# tcId = 2\nmsg = 0000000000000000000000000000000000000000\nresult = valid\nsig = b4e0a273bbf6e942cb22ae5ccbfd9d843400ba451c5e086fce9b3b1f90bd892fadc54ac45b61f3b3b37aca67d835fda1b37d5bec427382be2348062716d4592c7eb5c9107cf391e1cec01c74d64dfa5cb7052f2f8e442a09d21c22ef5484cb045c25a05b3057b266335f619ea8dc43b72e9abf38c19b5d71c21b9bf2eb8b63f2fe0fa868f7dbc9deae9745adb1fc26027bf5e2770b2d250c7507faf2fa63fabc67eeada9f2ed8f724dbd99d43294e5ec11d1575101d32af1a308abb56f7f15f544204b533fbd96fd3fe9174db3bc2af67c35401cc4003bbce360a7898dc831011ff0582c0658663a8c2e7c0e7a0df7f3c8ef95175bc136c3b49eb7a65023b08f\n\n# tcId = 3\nmsg = 54657374\nresult = valid\nsig = 9f74957ef2ec67062c5064143d096610d04af16f23189bf010f560d49bd793d619f70125dbef4edb4d4c923f8447e48a744428d8b463745d84a718d3c5592cdf6f611a735c7e04fe3f89920cc61e0113df20b93c719df7cf62013a2db3b497c033704352519dd51975eb156ee733d7bb342093bf494e6d7c8e92537adaf8b9170c0a2f0d76af847f716ecc87e8cd3545151387cafe062d5a2db83c5463b84d13b1ede8656efb3ae9509b449f4676084042b7c9091fb75476c8a866bbdbe57e125d7c64f2f7f1d4f732666bc7ac09c8e767d145f22243dd1f10943aa61b75e85256c52c522426c1dafde98af977c8538f7441ccdbb4eabff1990304c087070b12\n\n# tcId = 4\nmsg = 313233343030\nresult = valid\nsig = 257d5214d02f48bf63a6a1f2604824bef64108af97a6032d9eab48b7964642e104f13c462289fa889109274360dfedaec2ace0f5f190d2e9ba0d2d522dc763dd60fcee52d513bf9ca7c0b29de279ca8b401bc2016c10d837cca56498dd644e4d350315819767e2908c1c33b71acecd0143e2913f9eec1978a900a3326bd8bb7574521c39efa2e987327c9343b9da06b304d1e4688ef80e6c285a6dfb64b57ffbfc786f69a2a1c0948ee6781dae288089a5dcb7fcb1e53a74b828b34867b8d7fb5a0151e43076772bd53a537937f8ad6e44adcf96a18181b460b63e530edc56a773fa3adb252cfc8bb664ca560a054f374c2a03d7532ac8986377b76ad0a4f1d6\n\n# tcId = 5\nmsg = 4d657373616765\nresult = valid\nsig = 339b527aeec23ed9319d5c5ee671e8e92fde09932648734b1ded4eeae420e113a7ff1119686aef90c0bea5248ee1d50f5081515fba7a68a7ac8e2ba9828ebd58237d211c8212267f2a82363ffe790e3ad5282bef3842ead902cd98194d440cd1a53cc34121862034670dffd82aff9bda7f867a3893c2ba2d60cd3d5a3ae1c446c718e99bda195e8b19af734786c62908e1e18b155dbf791283c1bf3e02ce009e08415444d56f5defe78200557d513c8d93414228c4b746a10262cc4dc573da6801f624c5d99c200bd5731142e49d69f9cc9d6d914be18d09bcff4411f62bf028223ea559a41c71a970f5e0010ae487db94461a662d56e124d7b275e8266e55f0\n\n# tcId = 6\nmsg = 61\nresult = valid\nsig = 6ea7297a28c575e4348878b928d6e938a2e3d77dc46a785611a64817fa0e9c8ec71728bc7e8f9eb3268aae0f3bfa23dcb73d503e0147432b4003400167ddf2f9fc8d09464e0b91a44de12c1efc8c38732e1ed87f91cebae036610c43a3b8bcd5bb4beac4f9fb5e39f193cfd4bc00d4c7a3a98d00c4efcd1bd64f260a2a957fc730df6dba68d622441901c51f5788d6c3636299ed3eaf0bc23000650ca97ed62d367a844f23649bdc23efd0349dc8d58cdbcf655aad1f9d3a21afa02930d68a2c2db68e364b0966b005c460b682717035fd43f0cb0e7008a3d841a90c0449de8d154082703313cd9abdcc836e6c1ae5b1887f75d2e4b6387e7971128790a62c00\n\n# tcId = 7\nmsg = e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\nresult = valid\nsig = 5a7186589cda0f9fb081dad864032ffd26a775fb33c7dae0ac080aebdd4ab53bc3ed37cc09f0a1b1edee78f0790ce0d1b656e4a788172db08900bb1474159937ad29a7899d6bbc87c743945c798307e61141ac21542af06bc2f435a47b505b2aad2619800a97396392f141772cfa97d762c42ee8afdef27617dc8056fe75b23ede6c8f4e9abe31c8344edd2c73e5304621283021ae7003cd760c3e34caec5b4b5cc6d291cff1ea80e5b9b68c5b7b045c04714d3dc73e150eb770d3d3ed788a4ed039117881ed5cd03eb3db6e4084679e09078110630aa6895029e7a6dd19d5b77952bbb06de26c2179fb06c64d184caee0079287c7b18f5ae7843e3cd01eae28\n\n# tcId = 8\n# Legacy:missing NULL\nmsg = 54657374\nresult = acceptable\nsig = 38e80b028443d96685ed76d4574b36c43cf9722e5fbcf08bc974385454316dee326a308c935a6e612ed26ef4e470e5f3f19a223e2866a2f1c805f74c804e2184f5620c1e84f894b890be7d46420178a2a5ad97b4bd3d31db24828281587207041a96792d8ee57889c666719c769f759c2175361434b18f188de387c8c13f6fb3a7e96f1abbb6124e94fbb4c6bc1d88caf54136b8f01c9eedfd614bc35375f33277d2e71a4dc5f65254179bbe75634e9dfe05aff9e1f1d792f4e6caf88e4299ed90d212d3d7ac9bfc71a8ac85ffbf2f49f77b41d36a64bccd3fe8948054cbad480451b0ca5f7fe35b0f6c772d64b70346f469808dc0057ba1c25c6ae7ac8450e9\nflags = MissingNull\n\n# tcId = 9\n# long form encoding of length of sequence\nmsg = 54657374\nresult = invalid\nsig = 33a82ebc17f79f56f79073afbe0ff3f984f868684c529ecfffb3bfffaf52a99bfc057b196c3faeae3cf722c386c224ac235f781d9025ff8c9dcf10c4cc7f93c1f1aa5e1db9b166a71ac7350134ae1a1e5537a67f846f8c6970c269c4b91bc59ec783b7710afbd763ae42b1125eb9d0fc28b4045071c72320448a474006eefb256bb403b30a67c253028a2a0af7e4e36e85aa70ea73541ee2694d2bbe1415b37d2210def5ec77ba23c6f5cbe31ee21e072b49313e6e18bc6d6f2ffbd6b28267a5cdda24a62edd2151bff87ea6858db5b863c13a8e2a6445d8d31fd6b3ce8fa5a31060f97545f1e04df6819648a1933b1bcfa2470bb14844963f53175f1b26b612\n\n# tcId = 10\n# long form encoding of length of sequence\nmsg = 54657374\nresult = invalid\nsig = 37c62aaa10e8cb4bcce5fe466ac8688431e8ad2105dc12c6b7a0dfe8657ef3dbd027d04847c7d708c2099d7d38ca2b21aa5146ec0ffc7fd1a44c91c24689fa37475013e5b30c92c3565e3d53afa73fcf269dcf3b2bfc48a2ff026130bc008a724cd29ffc546d1aea5aeefc8cd13779b3b821d78bc7b7664fc7a89ce0273a8eed1e4a683c739005640c2edb756ea95f48d9c91d1ae9f57f24f6ce3193cedbcc52d05eb0dc8a9634a0ca8e12a446e9ac3378cfabc37b498aa4a1a9d1d3a6fb308411566f9c68063c0bc8e78621fed3a22073260aa87c76c5768c3db7f674f84d8826381fc3491f46d417a73ab88587d905d1c090e37913c99cfe29dae491841d31\n\n# tcId = 11\n# length of sequence contains leading 0\nmsg = 54657374\nresult = invalid\nsig = ac3c440334308e0eef1b3c3afb42dd050c77f1bfe9f3c3c83d466a46bf708502f1866f423d52866147554a5c9f86f10c079d2bd47192dce0968e8aefd5f43a2892ad21b0bdb92be45bc380c11565ac7c01be00cb1e294048a1efb4cbb19be44fa4b542e0bbf9a47549d09e456f58ff377adafbd68ef8d86dc2d7d56c5d3be08ec6cf12c0d04bb7c64c13f08f75377ba896bece7f409d50809521b7f6496c992c90ce15a70a8f8096f8f2cbd3e575acb618c87f5632", "4885cea1a6ded33d2f09d684f8d5a98c78f94853d74b9e6ab503918fea323e5534d3e45d51b3097e082c5da614d03a5ac422e5dcc3b764bbc02aa633a517bbe391d2662d71ab851e4eb3f5\n\n# tcId = 12\n# length of sequence contains leading 0\nmsg = 54657374\nresult = invalid\nsig = 65fa4957fe03c0eb8a6680ede12f009178d3ce357927c8586ae056f209e0ab0c110871fdf0b95a2ff684748beb4e5a6a73ca3c657b23bfa06d362a300f260f4d60d459a066c9f5311d634bf96ac7ee4c80ffec2fca27eca7dbd37025bae76122a1fed1914da70f2bfb6bf2e1bf3a624acf2a6377606fbf06044a21a39ccd55b2cc1f0ff184d9df95bd73942a190f30028e770139d38ef3156f64fc3eec68ed5170c41f09f110f5a0fd195cd42c4dd8e394f32d195c159c7c2b69943ea966039b20c7ca17cec610be60aaf7ecdf3511590a662b74a181fb89135604d84cf9c4d6cb6cc0b4c24f4b5e7e9e9cd969855cdb92e3b399f32cb31319ac81701d056e84\n\n# tcId = 13\n# wrong length of sequence\nmsg = 54657374\nresult = invalid\nsig = 36f62f546a36d5215548e6a770a14fc6edd4a9353ff8ed6231369cbb6598d25d86018b8cea9f1a87c150fda18c7e89b2c907f0ce485c8c321be467a97febc05dce335db88cabdb99ebc4c187a04fdc8e879487f03c2aeccb6ddaf006f0613d32b197c79b2a8cfae015909e02746fecb9ae9da3f07ee91ba70c0356984dd15d078cd0b93dd9e3c1cc03d6f255c1383e6e949e529ca4408f0f453e7e94c17e9b47f841f73dd62e5be047c44e1d9d7eee0d9f2a56bab13d4397494812793a49e8dc0d237242bf134aaead8f303226e532afd0c2e9748be08d7b7fd74f6f1806cfc4092af39d6eada4e0b6d7aa6f06592f6cd7dd26c1fcc84fdff1bf3086e8e2c81b\n\n# tcId = 14\n# wrong length of sequence\nmsg = 54657374\nresult = invalid\nsig = 6e18d86059eb2f05c0c1277abcd8d2380ea39ea0c4587ae140d2f709363eaa2b0b7f801a75fbe15aa329129c4abe43ec0fd84f552a3aff7e4de40a5943ef13cc3b2d02a1ad90309e8091d5c2c6fe3b6dc2472c94116cd9adf367e575720906a9fe41068a86c15214e3dae39ac41b84f5fb824dbf5c911c8c640254cd19910e15a6488c2a59179f271dbde468d540cb33dd5add9a864780e27a3e55c87402d9e2c0e12d70c9a41681bda6f9f337e7a26dd2ec06580e6fd9cd4db40a62002feaf5a4c93dfe05dc392b63809d4caebdcdac74a7a240260a6eb8db8dcbf25527d4297e4c6145decb0a888817b4f949fb66ee63e5cb2c2477a9373d1e30b4d71cd7c1\n\n# tcId = 15\n# wrong length of sequence\nmsg = 54657374\nresult = invalid\nsig = 61a6e5ea6b3c5241d75dbf0cb397da7cd9d5b2c23ffefa183ddd1d34b6cf116b127045f4681877fd58907c1209528a6b45266cfd5bf4e95361b9036c77fd6cc7891cb2417d081ed897ab97588dfcf975992ac9c0239aa9fc19dcf6d6d0f3e4bf72da5ab09cdd4b205b41a27e6b36dff608a638925d13e3ad7143b1ea9a2758c787a2f33790ad423749c1b79b3239d1f96fc4690b19a0b8edbeff446b148fbf39a890ed8e4a18ea09d5e50c25855e1a4a4c28c5437c906d1a9c371569936c858c29bd16e98af749edf2f048933d706068928e81ac7e219fc923f6dee8a411f40ede593468ada31e5c647d4a576ddb68a335bd50cdf7446dc722ee711b5c71ae93\n\n# tcId = 16\n# wrong length of sequence\nmsg = 54657374\nresult = invalid\nsig = 6494a47f97d18199ce0948b2ddf81e408e2d4acd58705059454b728b1be79842ca8b9e197a29347bfc02a6830aa7189ccd84469e696daed24fd3e45a403af6d38a2bf3e5e8005b9535a00a5b1520a9665676aa51a1b274a3c0270a20b86a5168e08000fc4cc60673604564f8620e9a2a2374ae148ec6fdbf7e880fb8be7bd85131a3b2cc08e85ff3270a4b433a6f58583a16e5b18eb2a093e6249e0e5e27c13e1cfc3fb8e078ede70034f52f4540f5fc69dc9124671200c5dc6961aee740d39bb5b6ea9f9325f2dc9eb85be46b998b29ed3dd9c7169d58e33efc212c9cc0b09e356e65463b9becc52e7654cb22a374832ad6d4e219e0fc5eddec8debf779031f\n\n# tcId = 17\n# uint32 overflow in length of sequence\nmsg = 54657374\nresult = invalid\nsig = 55d1cee3129381d3c8526661a5f2c9b59bef9972a8d3ecbddd3cd859db06be0971a181d9deb7a7333b3f40eab2e93a67342da7880961fa3b931b3ee94cfa5eb7cc76ca8f6f013bda5b1dff7a7d8ec7afa76fc6acb7809b411e8d77e97fd11f4d13af1033a04b949ce35efdc52e125394759df4f7658fb4c807823f80c01b74c5424744a39193c901a8b7238f77c330f0c37877cdfb493228a600dbb5694ccaf9521b0e2921cf84fb0a778d6616ea76f79d89ddb344834bb34a033f2399289c35ba4b5b70b1aa6d504db3f15cd1be6215678f01f3df03a3a38cd2f6e9d18755c484b4b4ee514c976a7a3edb9d93f475c4fcfa6fec43e6f815095d4dda75a5ec81\n\n# tcId = 18\n# uint32 overflow in length of sequence\nmsg = 54657374\nresult = invalid\nsig = 759135e8b8f94d853d92e75bed21033eaa80c88e1cfa202aeaeee96fc9dd8f5430da9baa436062c843e2a6d06801e4397c93a7643b52e4e33c298638f546be9f8b2961c0da08a172ab2a9185eec9b9b859a8b46cb240317e66469882269a53b34c9db60ba080e1831942db3ad65d3779c7205aaa366c00b6372496d71fd5cebc14b885303fb7c9e968f7d4f9f0511bac5f273608c8803db4ce582eddb0c672d579b4d1d67cb5aaa4fcaa14d744acb8124f3715bb82417ca020cb1b2a597f149364f859d5f1dc17dde4181628b96438df017e9b96b87f45d40383badf6b6a89620adf601c9c4fee15b1a868f8bf7ed6f59d1f9a960fcc1d961c8d010002e238f3\n\n# tcId = 19\n# uint64 overflow in length of sequence\nmsg = 54657374\nresult = invalid\nsig = 8fcf0a72c6fd0f9b505effcd2c074051f1d25840f8803a68f1c149dc43af6b94a114efa7ce2b399a91aba823470b9f32a70fb6631dfef593dd312801062c7f64d7c7b8724bcd36b05df16838f9e2ef209c2dfa180717d9d1bb59c10d30bdf6a0c0041ff395d4eee8a1c60af17b8152906a58786ab39840909508f7a8f3a05096e92eb57b31c07e79500091f119698bf31bd14399e122e16c3f0083d0a9a6f6413a8427dd27dd5473a9060450349f51ac265030778dbb04d4a35aa98dd72ea38a548be905717b46a1e31cc0b2c9247b7a64d26c027b7d09fdc5f2c6f3f625ecc3a5e07e37d2623b099aa776c48c66d62764def44896651c6b0ab10f1db7105f8c\n\n# tcId = 20\n# uint64 overflow in length of sequence\nmsg = 54657374\nresult = invalid\nsig = a34534b9e1b82be8c7a70d643c85664cb3919ced9c6b6cbf470f4aa8c62194d3e287077d3dc03e9e49d9069b69a4fc2caa5c9fc0ff1f08cb9b8370d044baa4be1b5918174997d74579c791a4c9d53f0348d33b6dd9151ec11823fa765a04cf03791f9d8f89048bd702f03247e3d9ea4e9882d9c768166e60b2db47a1bd76dd8cde45933dd1e4c3fd2bd46bbb8b2fbd6a2630f9db7e09dc342a3e279927a68f3da34192d0a283e2df7530b06a42ad1680b4a33c8b4bed2a8e799ff39ce4c5853a2f9d016610e58ce819771cd0ca5cc286134fafdcf36eb6c0f198e312e0e2cf722c47487a43cf4630c0703e65f5cc23972d5c16012b0e338aa6bbaa9a6110bb7b\n\n# tcId = 21\n# length of sequence = 2**31 - 1\nmsg = 54657374\nresult = invalid\nsig = 87bff62986cb2cd250de8d56fb4674c65cafd441da9dd4e42b1e7e14231519b63fa59608cd70d3ad761fdba810993ab3da3ba5d182dabefdce2c383e153df2b21c4cd4b58ea94e353d8c02bcfef4d565cda92975610207c9c30754cbe22bfe0f7cebaad0b6fe1d470d9119090adde8587d15cf27965f525d92ccb2c8778261f9d126ffdd8b90bd00acbe648979567a3ecb1fb5ceae06bbfb1df595e2155889ce62b3b47bce372a7527fd59ab5dca37378d0a90f4487690385acadea3766fa407d277ce4e76416daaeeba1591aa31dc601efd0d9e29b50ccc68d1511581b00f75de4c05d145b7ce0f74ccc509748fb1f8c636e1a56c9c412142d5c9a95efd0b8d\n\n# tcId = 22\n# length of sequence = 2**31 - 1\nmsg = 54657374\nresult = invalid\nsig = 2fadb8a429803ec2956ae6012289f15f7ed8d535c07412994204ade72d2e7a5548024390e1356d432b7e68c1a8738382f5aef3cc7739f926b44f9b9905222323a97fe7b303c130eb4147a5a4c69a031bd0c459779f7c3bc00bd5ad616421d14aa90ff3f5f4f700efd19826d89c80c6c4ab4ec81ec05498bb543be74acb3f61e6e1bef48e61646ab962da08502fb092961c5fb324026a52abfd1c47b9ea76187f5134916c5dbfc18668933c2a562a02c102b6efb9ca2df40869e920e84f8e73668a73c1cea83bc8600f7dbadeb5babfa74b99a3d02794b924b01dbf087da3d8d579514647633d8d6922a59a3f5625687a4b1c3b5cc67858e9b78ebbc7adc20aa7\n\n# tcId = 23\n# length of sequence = 2**32 - 1\nmsg = 54657374\nresult = invalid\nsig = 85ec33234ac05061985a24bd9e5e13de3fc8e8c246f75d85abf8021cd993f97c38ec6b73d713c6417effc7a751530feff849a5591ca0c4e6dc5bf6bf97c34bace7faa2e448bbc81e3d8551d4f82f7ed095ecdb19e91498e357909f090fd8c215f830b2741a4a4af518341c312bd6f7fef9c1b563cd4284f785430c538234f6bd3fceb2b49ab872cb481447b2d45a37d45dafad4d6de26246634b99b926e37832a8302d24b35e315f0b971cf52c60ac486460d7678152beff5369441c84ed54f16177f5ae560eacac13d7f94f14764ecd42adeaa0599a1a47e7f500e6b14e0a3b198aaa18fdc6d9141932bb28b20e71f69c173c2b841fa042a3fa0a388e164fd3\n\n# tcId = 24\n# length of sequence = 2**32 - 1\nmsg = 54657374\nresult = invalid\nsig = 4d28f0c7915b1eb63badbd931675ecf29f8d69b4b2e1b1fad776fa5adbccdc17bde98029059d46b197de49e061ec57cce2cb77a63deec3c75c2cc14fc9bb4a2ac29d5f4a05e6b4ff97ecbcc26a0dce39760423740141e675b52878a83aa044f68e84d9abd0ea6bfc5e6fc3acd971af258b7b9a01079010e68e70bd7bd31a9f9bdbb70598758ba274fb8feeb8ff46a4b2331a4da03330cf55910e6ce940c1a95b6bee9adec351354774139e3b213627a6d7e8381656362b4c6f83e97f93630939d22763f0850f1b4d38a8e3ed213d2febeeb125ec03854a4b276fb59087904ffabe83cfa66c1af413af6ecde5efcbc5241d5b958425b66ccd31500ceb9b80d793\n\n# tcId = 25\n# length of sequence = 2**40 - 1\nmsg = 54657374\nresult = invalid\nsig = 02d431509bae6e097fffb5e719b16a296b81fcfc9fc6a64b85b337c88049fed54971ef61e635388c2653554685e652059c769c5947af49858439d9c388a40703a016f73cf231726853f498f94a0a9a98e14e0cf8f0c8284b4d992f00c", "bb8dde41b07679c7bb7a2b4b7b307f2edda65fe3e002c7235eb85dd2ba41483b26131c997793ed64fe92a9fa9198eead1e8506385db0c3c4dfb93b87e2cfc09d9d3b00937cfc0a35bc211cc8efa4de83745c5eb0bb28ae52a22ae4ec8712be72bcf420476fdada50b618f0e9576e3e7ad8df5a0ebab78b1bfcdcef594cb7ff56a895b5ab5e0a30f82453880d394bad6ddb92231e44aa275f945ba6220d9f226da4d0aaf\n\n# tcId = 26\n# length of sequence = 2**40 - 1\nmsg = 54657374\nresult = invalid\nsig = 665e80a08c78f4c8a2768d1ba374bdd5e5101e61a594300a18a071d7c98c68cdb73acf32831ea077734e2486f1b13f76cd779a80fedbd76716fd022006a6faee19cb9789359e5b7013a59cd671a2a91c8328f4a1697e14a085c897eb45692d0bec074b400ded2820c6a5dbee2feac84cb6a37baece0ce763dfa7ca3b3fd4a82863a0eb35fcff709ca401c0bbb73f27f251b627cc442dd43eea634942bcd8bd72f1e8f192ae8dec1b7275c7739db254ced8b57332407f8a85285a190c94ea7f1c9318b7fcf67369ed23243c2454dd2ffa153ef12074a842878b38695336e8acfebf2d56d3560e43cdb039c27b207ae35f7a527b05baffc73fe76e57813b484f00\n\n# tcId = 27\n# length of sequence = 2**64 - 1\nmsg = 54657374\nresult = invalid\nsig = 58bb9a11f29ec8bc8ec7bba4c056e09087fcc881d8fe8e5dc58fa74d979676a20e00468e16238d8e2a53e40b4952ae47cc857807558b12224b3ab06ae355fbbd35180e555d7d468c23c6466ae74c8003d2b1591fbd529cc479e7469f5645787b8d7baaedb089efacf7f4395cc1382a3068770530ae97729089100960f22a13d73883a3a5ce6867c77a9e833d60f8f3c79fc2f36e63cbde5a02cdb7e226f387588456b9161814abb84c638aafb44f293e19f1bd5093e36d68386e365a5ab076b64275880823bb77502924d26bf443e94e45921866c68edaf5e66b24df38155b6faa25e531eb1af900780413cf5d5d903146a9cfe9350a3a1509beb679d7b75cd6\n\n# tcId = 28\n# length of sequence = 2**64 - 1\nmsg = 54657374\nresult = invalid\nsig = ab35fb3939affc42b2ac00248105dbd3da37b59db5d489d1ab1962418e6bec3b6fb4dbc03fb47c2a64cd09fee70acd723a50402b47cc2a3411c716a1f380138511d693751e37a0bf23751488293a68382a909202b7d18dc3721521f9c8fa3554dac15b20ce5ff9638edeba6ae89afaa100cfc92f51326b82e8fea27ca216b8b953afe00d0a02c0df5ec76ac494c1ed3398144a2654570d8daebfb27dc698bb5fc3a69e7b3759c1f1c7d5e807f509185a17b642f8b24934b5efef55287dff737fe633f19e0d1af46a0b4675b300583f96a3670b1e50f1c27441b5e601b8c4cee015854d680ab544900e65f4e205e2666ac0087586012d8ae52711a9cda02ee520\n\n# tcId = 29\n# incorrect length of sequence\nmsg = 54657374\nresult = invalid\nsig = 3f9ed26d39ea6b13377ba941923d1c55544c4ef8c9187dc6430eb1e7c8b86292e528fbc74b7876016ff3cf8014da3d85f37e975810c0a7a8996c91533567e40b0c8464de887b18c9adf84571f7703147cee96c81e5eaa61cb3c40840d21cc0a280991173d5fb1cce01514003bec10e28420ba01819ff003d9ca8658f41a6e02c3295a53613adac27ddbe959d90faa58e33c3326c4b5b6a5a015955541531fc62ea216a4dc54878b65e6a12e0fd548046e103d8dd4516bcebf008ae4d5b971e9e2eecc8379356ebf76b69943b6f0d87ccdc19036007f7c79f363ace8e85bb97c40f7b59bbeacba0325decf642cc8cb8e51efb55a7296bb23bb12a3a1b334f5ca8\n\n# tcId = 30\n# incorrect length of sequence\nmsg = 54657374\nresult = invalid\nsig = 748e7f86340f83dfe05a19e73449b7814398c6951a649029509c3072b6ce053e6176453d9046677e4996ea9a490fd602d8a735042b29d2a17f997817c6d9600bea2d5f7d7129a361bac6b7f76df520f4971790d250fbf89df5c22bb9e7a510bb6fcbd18251fcc5b77d61128f27adb3784c9c363eedd2c0acf9fbff65c9b4c67d631c98ec6ad6ce56389420a9f7e78973e3b55c90b3c3a6b37ffaa74ced4889cf306eb75e87d4b34519a349d1b7842f81eb588c3137e80895fbb98d67fda3621c7510815a5d5ae512e6566088dc333107a3a6f4309d6dda5417bfa795c72d4e70253775afeda3940d4bedb9a094502e1bd90084cae6f66c5f0369d3ca6a00d4f0\n\n# tcId = 31\n# indefinite length without termination\nmsg = 54657374\nresult = invalid\nsig = 672bf0ea5541b809287c9e2b6a584da21271f24d58eb68cf2dca42f604bf3d62fa9d5a52ea20e234002ceda5bd919ee8ff344c8f84e2cf4d8efc511560e03f930b6533cce2ebaf14203401317fa8b0fd17807389b3c5449ba24a8a1f16d143ad06c1dc62c5c40facabe64faf0a9816d51a831b648ae9c99b465535b342085ebb1aa44ad23c08bf4dd9e0838209d4805f48cb16d9bca302d161ec3f6e66ac734f001e232c3133558c4b89c00eba40bd53c37c5b03ff6fb3f323d0b79510592141946a7a7b16abfa78ab81d886d7c4d4090bdcb782efbf0c4a76b47abb18e1fc9259cee098929a1843a04ba52704bc9be25a2b96779a2b647d3ba7c11e2a8dfe48\n\n# tcId = 32\n# indefinite length without termination\nmsg = 54657374\nresult = invalid\nsig = 94818574cddac115d352d1740c4e5581ce36f1eac658a7cc9c0fa26a1d6f5f43279c9f2af313b3e0df805ac1e24976d58aee16e2a4616cbe421e46f5263ce46e301d8c295cb8a807a9c65610b176c61ae03229fc6601cfcffcf90d53edcfe869a1bc692dcdf88ce84f23b34733f9c8046d1cb7df77f1eb29cddcd4b420dcc8761169f3c7dab4f04e2eccbc046b0b26007406dec7505a38273e3bab522a81a054241afea6b6576cb1fdab2569cfa605c0cfcea0f4665f489273b92d2fcaae21be8f2d37dc40a38d847c56c3df5a2d5cab476753c91bb4e2dfbf2bd9ded2010e202976055c78de4fb2ec3f2a6a44d6816c7cbb829c83646156941418b4f060e196\n\n# tcId = 33\n# indefinite length without termination\nmsg = 54657374\nresult = invalid\nsig = 5c54c39c0a079e7a842c8b7f5c6bc63f4b90873e1379132fc1a52fb78fe6eb46aece7f5ebeeaf2df8862622442f0a470d2a8ae252c5c5d71702033c6b5e6e983cf44ac0e818d9453b86b91b5d99a1af0fa5ed8aff718d49864c093e4cd5be4db1fd44b6ed38e58df96e70cab32fae1889e091be25eb9f15c07ad2c304e0ccb881cdbb1e45ba993b95e169358a169c70e7d0915ba34955bf20fe1df2c7aae78fb78c893d184c85a56524643dfdfc41e62539da005751409a18fb4e59d2877c6cc45a4b832fbfa8ad2880775d9fe92b6516f8458bb52cd5820710bc16ca32cd7bb3998af0299778a2dab50d62d73415294a857d92bc5bad97248e70cdacd50dd5d\n\n# tcId = 34\n# indefinite length without termination\nmsg = 54657374\nresult = invalid\nsig = 9b91890eb53272fe7542c2067a4e9295b8c7b8ddf1c9ece6a75fcde79c9af2cbcbcef38d342032b85ccff9d6c82d3cfd68a7b27a38eaa45c78a17741c230391b3df0bd79dcc3447c8717b7207fa1fd04e917b5282e3a7dad48e8f2f6d1360f6c720f9eaf1d1d59f061d71daac1548538c0a06fa65b2ac87abc9e6fed3a6e15f48422bd9c4c681fa98a27c873d7efc5c100e708d58141b60e5a691747df4036162456bb11f92f2a391170233ca1c03e1786a32fe9ab8a94246dc643a884ad59edc40e2eb873713e84816e4a7f7857126da3f063cb9a3dda0547207c426f7cc985b5a3b6374cfff51d0d542ce9f82ffc07ad24c106363ffaed12c97526394a84ff\n\n# tcId = 35\n# indefinite length without termination\nmsg = 54657374\nresult = invalid\nsig = 0f07dc8786a46a7ae2fe2bd534715044f46ad17b836b00370996258aa90bddf563b5f3e7eb1500ed0604f9380491a5a6c6c004b560b0f280a2de30d191928bf5aa0378fd6beda830beb1db8b6b1c8846079b6013cf586e384be0e1163c62b526fbf8e26992afba6ef5e5f15755ec7b5287a149b19e577e79bff6526d72616e28d921661752e8cd0e4b950d7ee9f2414e45b3069a80a2e089e46d0b3da5cc0352c07305f8dfef2e1e928e85bb76c5a0f1516383143184f66f31c69adc0b8219f11809501927744fa37d1c8cc1e2a6712d54ed66dd177714b7cbd005e6a6f83db92041b595dd934b0b19fce5db369e504fb45c9df1e645e81bef62cd4da3497e9d\n\n# tcId = 36\n# removing sequence\nmsg = 54657374\nresult = invalid\nsig = 70f9515388762b320cf84e90eb571b27eee58a43ebd4773573bffbce8b162bf17e6c0317636b211b2bc56aafa99b968ec950466ae5cd7b10d94c993dabace14b94bed501dacc0b40feb8a89586eb1a792e92115ba5430ce1183ffc6f538ca657fed3ea684a1b9d998c0d9ff004e150a0a32d20455176e8db3d96b5063a60106a7bf6c9d0baa8879ddb77d9a3037400348ed1ee4b88f8256e8e632b15b0dc2611da3a9faab929a0bd4881418d7fd8fc7760c523e1ca4cd3f25c8243b8bcdcd51e96a3840de589744bb8d655851b9cdbd8b7f2d47a57144d9c2a7ea07d49c0d141cf918a4eb1507f8a7b11cbaa28c1a35745209a5fad2bd1e66f7929fe0223d505\n\n# tcId = 37\n# removing sequence\nmsg = 54657374\nresult = invalid\nsig = 8804d661bb17ffa73e371d134984ee95e426d7c12af978d9ad00ce746db4a3bad36546709f029d2c9ed13e6d27123cb7a1954f1f65f3fa46eeb56f449ba6b5e0736e5dd2586d642711d98aa19595d9da1c4ec20953009e2711738263170b487072566558de1301e0d0253f8fc14d12c8cfb4644b50aeb3d3a9fe1a26fd3bccd72986cbaff34fc4fa38ce52e65821f169d54b78037b8ddcba141ffc72797023c802564989a20b07b9a2ba6a256647e937b1c16df2081cb61bc6e6a2ec6ca9939db91ec2ae62c4b2d0d7f61a0bf0c693165175c91b100c195f3611c3ecb797c531439655ace9aae18e53a69e66698fb593f48084117ba288a134fd0389ee0f7544\n\n# tcId = 38\n# lonely sequence tag\nmsg = 54657374\nresult = invalid\nsig = 47004cf187bd2a34c6ed89f6f8eb9f67a401a40d66a95c8cddd98fa0faa829bbfc9e62a854788e4d23015a68f098a77cc5daac7e23c6ba56167518753187a8ead68edc686c393940f77255fc8092c4c65a01aa6901c0af96830c05747791e511c8c01da4358feb38bf5507543184fe887c5821c4af048c5082bed56c7934985d86de2402b37e16a6f3e23d5a1e838992bef2a46d4fa87971f0cb01a470e185654a6b174d9bba81117e8df24b19a7be0d1f8e3906d3029b5ad4f0d8c152375dfc4fa490f9fa3a5b52fb929a7d41a84d61bbf60d80162b16334b4958ec879bbc0098962d5d3220169c8ccb338d31c664c23144cc85bc371b2d9da61a69f0b4b658\n\n# tcId = 39\n# lonely sequence tag\nmsg = 54657374\nresult = invalid\nsig = 24bc364503e9aa28177f9fe7ebda884cbe94", @@ -4395,9 +5033,9 @@ static const char *kData174[] = { "1ed9064323c12b6ebde15ae8c05a0e5205c91f57f5753815ff39c918\nflags = SmallModulus,SmallPublicKey\n\n[e = 03]\n[keyAsn = 30820108028201010090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d0030820108028201010090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1020103]\n[keysize = 2048]\n[n = 0090a5d7aba2c8dc828e616fc1fc45c7c52130c8589dcbe2913da187572f6c23217b89a5186b6f90cbe053abfb0885a91f141dbe106ce6ad303904a5941df26ced10478cb56a7bd6cf1313c4966d9cf7c4509d9dc63566aa323e110af219f3398c04e79bb486de8703793473136f5c9051af24bd2c0208ea1bf9321a3e8f24af00aaca1216842eab248d58cf46ac786c49fd3ca8557e9b53993a4b9718cdc5c474bf1cfe58c07ad97b2c5acb7d86accc0fc7bed147adb2e77b8697d80150948117714b806ff76f9d88147d84e93987b724bf4870429e85a7a7b51486a78d8a88f1688f60e215d43d06221e2b993b5c12a607b80e9e0122472b29945f76b55737c1]\n[sha = SHA-256]\n\n# tcId = 373\n# short signature\nmsg = 33363730\nresult = acceptable\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000989e7ff72e67e680bd21d5f966e4ad8a48c3592dbacc4a2f035b4ef4d17a2f25f8a9fef7e78eb99d76d68629ed02d67c43c4b7ec8c3badc32e3d0a524c326537739b0fde156723b27c23ae2b09895e470c64d700f5c\nflags = SmallPublicKey\n\n[e = 03]\n[keyAsn = 308201080282010100f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d00308201080282010100f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f020103]\n[keysize = 2048]\n[n = 00f2ed0e93228f37c2ce1c215e00cce4ef00e2c08a004a39c4170dc73e5fbd9b91e7c55e596579ec9c60b9bd341e83029b1934e6493eb60099b6cfbb9804d4179c983099e19102bba49eaa28fa505efacc5a9d5374499c0c5775778317ed370de1919f38aff22d5aee8c8af36a86d036029e761f243dff3c205a11e9bce9ac1d6baf81e79ad4146b119abb13903f8562e8f3e6a918f48223465bc93d5e7d5abe3d08503ec42998fe087a1f935d1b8673c495f005dfa7453daf977e1608a8c276da2a4cd0567e4af4d18cba05fdbedcde74493ccabd9060c27d35a02f35c760b12a4deae1359f649f273fa408626fb789c916434a642d528f41db868ff93b7f889f]\n[sha = SHA-512]\n\n# tcId = 374\n# short signature\nmsg = 38343432\nresult = acceptable\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e7a1269086f0bbc0778ded8d7108ff4edcc2313425088117b2d5c53e9d9971950a5fe8b2b67d2bcd1be74f6b557a3f90650a96d7e4dbd63c05b94f73337eea682417c058d66ce523e4461065ac8ba990c4ecd04932\nflags = SmallPublicKey\n\n[e = 03]\n[keyAsn = 308201880282018100ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83020103]\n[keyDer = 308201a0300d06092a864886f70d01010105000382018d00308201880282018100ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83020103]\n[keysize = 3072]\n[n = 00ab54a4f2560b9f65faa2f83bcf77d41803c080e4e5c3eab3534210982bba8a5d7e513ba50ba1ece33555c5457c41ba58f3f605a04369408f586c26dfda464c7b300a01f1616893264c7606daad4ced14df9a894a1f34586181294297e3ceb9580b0c785c056d5c566467f6f227f3084918d1cd17ed156e7f9fcce4757c5794f92770771ea5cf3101ca0425c846775f56938c1d1cad4401f4df2f5e0d3a3b2770f99e3c1cb4d9d4896c7ca89287b45831218b099add4bdf1dab6e2fb55d2775429386c85dff32c07a6dda504a9627529dd82c943554aaf23c5a5f6cea9c301b4b1f066b86bbef2e4bae9dc5b5e82e1fa03c29ff8bf38556729b356d5ba41d37a069fcc8fc23ac715bbea04c1972a2d50c57cc0159a46b5919fb670fb2a502d5ab66f0aa99e51016b83a406943ce9bdf0ab9b9e946574a5b32ce95d97ac8b1fbb48f0bf7e3c0d4b7a00d131966d009997a166a6630dee4a74c141cde0114aa423351b1dfdd3893a856fc632b6d90dbc79c8a61a9f9e31702ba69fb222860e60a83]\n[sha = SHA-256]\n\n# tcId = 375\n# short signature\nmsg = 34333630\nresult = acceptable\nsig = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011a21abeac8409398319e65c8656f8f72e179dd1e99358c7531fddc037e47c1e688cd70eafd6eea01c823516bc79f89d7e52ee1eb4ffdeaad1d550dc0a47185bc9c42e47fce5503c3370a60510f834b4691152ef668deca633cf3873ce6613951784aa7dafde118f37f1cdf1a687ac236d5c956bced564b73cf202e3bace59667\nflags = SmallPublicKey\n\n[e = 03]\n[keyAsn = 3082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81", "ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keyDer = 308201a0300d06092a864886f70d01010105000382018d003082018802820181008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01020103]\n[keysize = 3072]\n[n = 008733b9c2bc754216fac899159abb71c5ca84be37153720040f33f291f5f7861bc122cafde3091b5211bc81ee03e280e3c6c2902ec49afb8432c3273536edce7116048513e9b33e2fcfe56f9597c81bc9be81a1b1d46e863ca11db2c33ac1bdebf7c552332067e2e588497e7d9e0738caa57a73dd28157e88fc202b31bbe3b9993548399a0b0df9b72dfeece75ecd78376227e9cd21c8d24ca4aa64fa50a59ee8e7621158e7bac2420fc0d77064d3959afab664ecda0decb8c979eb402795b9a562f2de310aa7fc6864469ac88867788c57ee96f6dc32dbdbe3aa7d3ff47ae4b78e1106e1bc80350b2383dae54140a4605f4130d7e5d3f7818262a27c76a51e4c6db4ab4590b4766b8c50ec1bfed53f0d716b5c7d9dc971399246c75ce27745147151f2e7629039f0b2efed99c7f17cda8f3c3df764dfb40cc0c2ad7bf2b6c72829df93329a4bad6be8635953dd10840888784eea738c763be9f5dc3ba47a9e9d800e21b4ffcc18193e591e8a5283192426e8867331c72bdda06a0eb49367bb01]\n[sha = SHA-512]\n\n# tcId = 376\n# short signature\nmsg = 36313237\nresult = acceptable\nsig = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bdd0c9e451b5b3e5513a94492dbee1ada9ea87e65a8cd95cceb4d304294ce34bf09a212f14908f5b865c7a34a72e68e389794a2d1c5767ba17829e2044108ac7842b6bfe0a5663b433d656f4e38522c5a5a23c460b898833828d257350e5814291b54cf13089080f84998edcacf0fe5fca0c1f8b176b172c5f9989491a039bef\nflags = SmallPublicKey\n\n[e = 03]\n[keyAsn = 30820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keyDer = 30820120300d06092a864886f70d01010105000382010d0030820108028201010092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d020103]\n[keysize = 2048]\n[n = 0092bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240c11ebf97cd68c2aa19c787b3be21e68c0e397c7f04c6ef98950e27e0e19a40da92a3ea10800fe9252b77026d14c2fa1eb4ac102491e5773279f07d856d446f45169b09bf60b8a2695f5e4864eaaf9590aec8c7c2f86d]\n[sha = SHA-256]\n\n# tcId = 377\n# signature is close to n\nmsg = 32353934\nresult = acceptable\nsig = 92bf17cdbffb42fa9957ce37826bb451708e7cdec8752b809c81a8d16fe5fe4dab6a9db6d11dbb12086645db7546642b322e8331dd7f29eff68bf40b24f80884f5152b1fda9b9f7ae2fce2721cdee0fc48f85a6e8e64f767ed9727fd2dc597967e276a5e2e768528afdd9df4b6ddda4c174300e4da3c19a3c32299e1e7857934c14dd6203d8c2671289bc392711597155364a59046b2b9f1905fe717ca7efebb4c1969b804118effa240b8bf4bb1a6d0616fd5be2f081dc9ef741a9a4ae7274418b791432de470c4556463108388e8e8ed5dcebf3558e4650c2ac97c86fa682176f09b5dd8cfbf15d19c3fe4f961f4607c12cb3dfad9b6a0e59c92faa1fc8622\nflags = SmallPublicKey\n\n", }; -static const size_t kLen175 = 157296; +static const size_t kLen229 = 157296; -static const char *kData175[] = { +static const char *kData229[] = { "# Imported from Wycheproof's x25519_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: XDH\n# Generator version: 0.8r12\n\n[curve = curve25519]\n\n# tcId = 1\n# normal case\nprivate = c8a9d5a91091ad851c668b0736c1c9a02936c0d3ad62670858088047ba057475\npublic = 504a36999f489cd2fdbc08baff3d88fa00569ba986cba22548ffde80f9806829\nresult = valid\nshared = 436a2c040cf45fea9b29a0cb81b1f41458f863d0d61b453d0a982720d6d61320\n\n# tcId = 2\n# public key on twist\nprivate = d85d8c061a50804ac488ad774ac716c3f5ba714b2712e048491379a500211958\npublic = 63aa40c6e38346c5caf23a6df0a5e6c80889a08647e551b3563449befcfc9733\nresult = acceptable\nshared = 279df67a7c4611db4708a0e8282b195e5ac0ed6f4b2f292c6fbd0acac30d1332\nflags = Twist\n\n# tcId = 3\n# public key on twist\nprivate = c8b45bfd32e55325d9fd648cb302848039000b390e44d521e58aab3b29a6964b\npublic = 0f83c36fded9d32fadf4efa3ae93a90bb5cfa66893bc412c43fa7287dbb99779\nresult = acceptable\nshared = 4bc7e01e7d83d6cf67632bf90033487a5fc29eba5328890ea7b1026d23b9a45f\nflags = Twist\n\n# tcId = 4\n# public key on twist\nprivate = f876e34bcbe1f47fbc0fddfd7c1e1aa53d57bfe0f66d243067b424bb6210be51\npublic = 0b8211a2b6049097f6871c6c052d3c5fc1ba17da9e32ae458403b05bb283092a\nresult = acceptable\nshared = 119d37ed4b109cbd6418b1f28dea83c836c844715cdf98a3a8c362191debd514\nflags = Twist\n\n# tcId = 5\n# public key on twist\nprivate = 006ac1f3a653a4cdb1d37bba94738f8b957a57beb24d646e994dc29a276aad45\npublic = 343ac20a3b9c6a27b1008176509ad30735856ec1c8d8fcae13912d08d152f46c\nresult = acceptable\nshared = cc4873aed3fcee4b3aaea7f0d20716b4276359081f634b7bea4b705bfc8a4d3e\nflags = Twist\n\n# tcId = 6\n# public key on twist\nprivate = 08da77b26d06dff9d9f7fd4c5b3769f8cdd5b30516a5ab806be324ff3eb69e60\npublic = fa695fc7be8d1be5bf704898f388c452bafdd3b8eae805f8681a8d15c2d4e142\nresult = acceptable\nshared = b6f8e2fcb1affc79e2ff798319b2701139b95ad6dd07f05cbac78bd83edfd92e\nflags = Twist\n\n# tcId = 7\n# public key on twist\nprivate = d03edde9f3e7b799045f9ac3793d4a9277dadeadc41bec0290f81f744f73775f\npublic = 0200000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = b87a1722cc6c1e2feecb54e97abd5a22acc27616f78f6e315fd2b73d9f221e57\nflags = Twist\n\n# tcId = 8\n# public key on twist\nprivate = e09d57a914e3c29036fd9a442ba526b5cdcdf28216153e636c10677acab6bd6a\npublic = 0300000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = a29d8dad28d590cd3017aa97a4761f851bf1d3672b042a4256a45881e2ad9035\nflags = Twist\n\n# tcId = 9\n# public key on twist\nprivate = e0ed78e6ee02f08bec1c15d66fbbe5b83ffc37ea14e1512cc1bd4b2ea6d8066f\npublic = ff00000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = e703bc8aa94b7d87ba34e2678353d12cdaaa1a97b5ca3e1b8c060c4636087f07\nflags = Twist\n\n# tcId = 10\n# public key on twist\nprivate = a8a1a2ec9fa9915ae7aace6a37c68591d39e15995c4ef5ebd3561c02f72dda41\npublic = ffff000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = ff5cf041e924dbe1a64ac9bdba96bdcdfaf7d59d91c7e33e76ed0e4c8c836446\nflags = Twist\n\n# tcId = 11\n# public key on twist\nprivate = a8c9df5820eb399d471dfa3215d96055b3c7d0f4ea49f8ab028d6a6e3194517b\npublic = 0000010000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = a92a96fa029960f9530e6fe37e2429cd113be4d8f3f4431f8546e6c76351475d\nflags = Twist\n\n# tcId = 12\n# public key on twist\nprivate = d0d31c491cbd39271859b4a63a316826507b1db8c701709fd0ffe3eb21c4467c\npublic = ffffff0f00000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 9f8954868158ec62b6b586b8cae1d67d1b9f4c03d5b3ca0393cee71accc9ab65\nflags = Twist\n\n# tcId = 13\n# public key on twist\nprivate = d053e7bf1902619cd61c9c739e09d54c4147f46d190720966f7de1d9cffbbd4e\npublic = ffffffff00000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 6cbf1dc9af97bc148513a18be4a257de1a3b065584df94e8b43c1ab89720b110\nflags = Twist\n\n# tcId = 14\n# public key on twist\nprivate = a021d75009a4596e5a33f12921c10f3670933bc80dde3bba22881b6120582144\npublic = 0000000000001000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 38284b7086095a9406028c1f800c071ea106039ad7a1d7f82fe00906fd90594b\nflags = Twist\n\n# tcId = 15\n# public key on twist\nprivate = a89c6687f99bd569a01fd8bd438236160d15ce2c57c1d71ebaa3f2da88233863\npublic = 0000000000000001000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = c721041df0244071794a8db06b9f7eaeec690c257265343666f4416f4166840f\nflags = Twist\n\n# tcId = 16\n# public key on twist\nprivate = 68964bca51465bf0f5ba524b1482ceff0e960a1ed9f48dcc30f1608d0e501a50\npublic = ffffffffffffffff000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 25ff9a6631b143dbdbdc207b38e38f832ae079a52a618c534322e77345fd9049\nflags = Twist\n\n# tcId = 17\n# public key on twist\nprivate = a8e56bb13a9f2b33b8e6750b4a6e6621dc26ae8c5c624a0992c8f0d5b910f170\npublic = 0000000000000000000000000000000000000000000000000100000000000000\nresult = acceptable\nshared = f294e7922c6cea587aefe72911630d50f2456a2ba7f21207d57f1ecce04f6213\nflags = Twist\n\n# tcId = 18\n# public key on twist\nprivate = e045f55c159451e97814d747050fd7769bd478434a01876a56e553f66384a74c\npublic = ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000\nresult = acceptable\nshared = ff4715bd8cf847b77c244ce2d9b008b19efaa8e845feb85ce4889b5b2c6a4b4d\nflags = Twist\n\n# tcId = 19\n# public key on twist\nprivate = 105d621e1ef339c3d99245cfb77cd3a5bd0c4427a0e4d8752c3b51f045889b4f\npublic = ffffff030000f8ffff1f0000c0ffffff000000feffff070000f0ffff3f000000\nresult = acceptable\nshared = 61eace52da5f5ecefafa4f199b077ff64f2e3d2a6ece6f8ec0497826b212ef5f\nflags = Twist\n\n# tcId = 20\n# public key on twist\nprivate = d88a441e706f606ae7f630f8b21f3c2554739e3e549f804118c03771f608017b\npublic = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000\nresult = acceptable\nshared = ff1b509a0a1a54726086f1e1c0acf040ab463a2a542e5d54e92c6df8126cf636\nflags = Twist\n\n# tcId = 21\n# public key on twist\nprivate = 80bbad168222276200aafd36f7f25fdc025632d8bf9f6354bb762e06fb63e250\npublic = 0000000000000000000000000000000000000000000000000000000000800000\nresult = acceptable\nshared = f134e6267bf93903085117b99932cc0c7ba26f25fca12102a26d7533d9c4272a\nflags = Twist\n\n# tcId = 22\n# public key on twist\nprivate = 68e134092e94e622c8a0cd18aff55be23dabd994ebdee982d90601f6f0f4b369\npublic = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f\nresult = acceptable\nshared = 74bfc15e5597e9f5193f941e10a5c008fc89f051392723886a4a8fe5093a7354\nflags = Twist\n\n# tcId = 23\n# public key on twist\nprivate = e8e43fc1ebac0bbc9b99c8035ee1ac59b90f19a16c42c0b90f96adfcc5fdee78\npublic = 0000000000000000000000000000000000000000000000000000000000000020\nresult = acceptable\nshared = 0d41a5b3af770bf2fcd34ff7972243a0e2cf4d34f2046a144581ae1ec68df03b\nflags = Twist\n\n# tcId = 24\n# public key on twist\nprivate = 18bffb16f92680a9e267473e43c464476d5372ddd1f664f3d0678efe7c98bc79\npublic = 000000fcffff070000e0ffff3f000000ffffff010000f8ffff0f0000c0ffff7f\nresult = acceptable\nshared = 5894e0963583ae14a0b80420894167f4b759c8d2eb9b69cb675543f66510f646\nflags = Twist\n\n# tcId = 25\n# public key on twist\nprivate = 300305eb002bf86c71fe9c0b311993727b9dc618d0ce7251d0dfd8552d17905d\npublic = ffffffffffffff00000000000000ffffffffffffff00000000000000ffffff7f\nresult = acceptable\nshared = f8624d6e35e6c548ac47832f2e5d151a8e53b9290363b28d2ab8d84ab7cb6a72\nflags = Twist\n\n# tcId = 26\n# public key on twist\nprivate = 80da9f02842247d4ade5ddbac51dbce55ea7dca2844e7f97ab8987ce7fd8bc71\npublic = 00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffff7f\nresult = acceptable\nshared = bfe183ba3d4157a7b53ef178613db619e27800f85359c0b39a9fd6e32152c208\nflags = Twist\n\n# tcId = 27\n# public key on twist\nprivate = 806e7f26ca3246de8182946cbed09f52b95da626c823c7b50450001a47b7b252\npublic = edfffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = bca4a0724f5c1feb184078448c898c8620e7caf81f64cca746f557dff2498859\nflags = Twist\n\n# tcId = 28\n# public key on twist\nprivate = 58354fd64bc022cba3a71b2ae64281e4ea7bf6d65fdbaead1440eeb18604fe62\npublic = edfffffffffffffefffffffffffffffffffff", "fffffffffffffffffffffffff7f\nresult = acceptable\nshared = b3418a52464c15ab0cacbbd43887a1199206d59229ced49202300638d7a40f04\nflags = Twist\n\n# tcId = 29\n# public key on twist\nprivate = f0019cf05159794cc8052b00c2e75b7f46fb6693c4b38c02b12a4fe272e8556a\npublic = edffffffffffefffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = fcde6e0a3d5fd5b63f10c2d3aad4efa05196f26bc0cb26fd6d9d3bd015eaa74f\nflags = Twist\n\n# tcId = 30\n# public key on twist\nprivate = d0fca64cc5f3a0c8e75c824e8b09d1615aa79aeba139bb7302e2bb2fcbe54b40\npublic = edfeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 7d62f189444c6231a48afab10a0af2eee4a52e431ea05ff781d616af2114672f\nflags = Twist\n\n# tcId = 31\n# public key on twist\nprivate = d02456e456911d3c6cd054933199807732dfdc958642ad1aebe900c793bef24a\npublic = eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 07ba5fcbda21a9a17845c401492b10e6de0a168d5c94b606694c11bac39bea41\nflags = Twist\n\n# tcId = 32\n# public key = 0\nprivate = 88227494038f2bb811d47805bcdf04a2ac585ada7f2f23389bfd4658f9ddd45e\npublic = 0000000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = SmallPublicKey,LowOrderPublic,ZeroSharedSecret\n\n# tcId = 33\n# public key = 1\nprivate = 48232e8972b61c7e61930eb9450b5070eae1c670475685541f0476217e48184f\npublic = 0100000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = SmallPublicKey,LowOrderPublic,ZeroSharedSecret\n\n# tcId = 34\n# edge case public key\nprivate = a8386f7f16c50731d64f82e6a170b142a4e34f31fd7768fcb8902925e7d1e25a\npublic = 0400000000000000000000000000000000000000000000000000000000000000\nresult = valid\nshared = 34b7e4fa53264420d9f943d15513902342b386b172a0b0b7c8b8f2dd3d669f59\n\n# tcId = 35\n# edge case public key\nprivate = d05abd08bf5e62538cb9a5ed105dbedd6de38d07940085072b4311c2678ed77d\npublic = 0001000000000000000000000000000000000000000000000000000000000000\nresult = valid\nshared = 3aa227a30781ed746bd4b3365e5f61461b844d09410c70570abd0d75574dfc77\n\n# tcId = 36\n# edge case public key\nprivate = f0b8b0998c8394364d7dcb25a3885e571374f91615275440db0645ee7c0a6f6b\npublic = 0000001000000000000000000000000000000000000000000000000000000000\nresult = valid\nshared = 97755e7e775789184e176847ffbc2f8ef98799d46a709c6a1c0ffd29081d7039\n\n# tcId = 37\n# edge case public key\nprivate = d00c35dc17460f360bfae7b94647bc4e9a7ad9ce82abeadb50a2f1a0736e2175\npublic = 0000000001000000000000000000000000000000000000000000000000000000\nresult = valid\nshared = c212bfceb91f8588d46cd94684c2c9ee0734087796dc0a9f3404ff534012123d\n\n# tcId = 38\n# edge case public key\nprivate = 385fc8058900a85021dd92425d2fb39a62d4e23aef1d5104c4c2d88712d39e4d\npublic = ffffffffffff0f00000000000000000000000000000000000000000000000000\nresult = valid\nshared = 388faffb4a85d06702ba3e479c6b216a8f33efce0542979bf129d860f93b9f02\n\n# tcId = 39\n# edge case public key\nprivate = e0614b0c408af24d9d24c0a72f9137fbd6b16f02ccc94797ea3971ab16073a7f\npublic = ffffffffffffff00000000000000000000000000000000000000000000000000\nresult = valid\nshared = 877fec0669d8c1a5c866641420eea9f6bd1dfd38d36a5d55a8c0ab2bf3105c68\n\n# tcId = 40\n# edge case public key\nprivate = f004b8fd05d9fffd853cdc6d2266389b737e8dfc296ad00b5a69b2a9dcf72956\npublic = 0000000000000000010000000000000000000000000000000000000000000000\nresult = valid\nshared = 180373ea0f23ea73447e5a90398a97d490b541c69320719d7dd733fb80d5480f\n\n# tcId = 41\n# edge case public key\nprivate = e80bf0e609bf3b035b552f9db7e9ecbc44a04b7910b1493661a524f46c3c2277\npublic = ffffffffffffffffffffffffffff000000000000000000000000000000000000\nresult = valid\nshared = 208142350af938aba52a156dce19d3c27ab1628729683cf4ef2667c3dc60cf38\n\n# tcId = 42\n# edge case public key\nprivate = 48890e95d1b03e603bcb51fdf6f296f1f1d10f5df10e00b8a25c9809f9aa1a54\npublic = 0000000000000000000000000000010000000000000000000000000000000000\nresult = valid\nshared = 1c3263890f7a081cefe50cb92abd496582d90dcc2b9cb858bd286854aa6b0a7e\n\n# tcId = 43\n# edge case public key\nprivate = a806f1e39b742615a7dde3b29415ed827c68f07d4a47a4d9595c40c7fccb9263\npublic = ffffffffffffffffffffffffffffffff00000000000000000000000000000000\nresult = valid\nshared = 56128e78d7c66f48e863e7e6f2caa9c0988fd439deac11d4aac9664083087f7a\n\n# tcId = 44\n# edge case public key\nprivate = 9899d5e265e1fc7c32345227d6699a6d6b5517cf33b43ab156ee20df4878794e\npublic = 0000000000000000000000000000000001000000000000000000000000000000\nresult = valid\nshared = 30eca56f1f1c2e8ff780134e0e9382c5927d305d86b53477e9aeca79fc9ced05\n\n# tcId = 45\n# edge case public key\nprivate = d842316e5476aeaee838204258a06f15de011ba40b9962705e7f6e889fe71f40\npublic = ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000\nresult = valid\nshared = cb21b7aa3f992ecfc92954849154b3af6b96a01f17bf21c612da748db38eb364\n\n# tcId = 46\n# edge case public key\nprivate = a0933ee30512b25ee4e900aaa07f73e507a8ec53b53a44626e0f589af4e0356c\npublic = ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000\nresult = valid\nshared = c5caf8cabc36f086deaf1ab226434098c222abdf8acd3ce75c75e9debb271524\n\n# tcId = 47\n# edge case public key\nprivate = 38d6403e1377734cdce98285e820f256ad6b769d6b5612bcf42cf2b97945c073\npublic = 0000000000000000000000000000000000000000000000000000000001000000\nresult = valid\nshared = 4d46052c7eabba215df8d91327e0c4610421d2d9129b1486d914c766cf104c27\n\n# tcId = 48\n# edge case public key\nprivate = 182191b7052e9cd630ef08007fc6b43bc7652913be6774e2fd271b71b962a641\npublic = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03\nresult = valid\nshared = a0e0315175788362d4ebe05e6ac76d52d40187bd687492af05abc7ba7c70197d\n\n# tcId = 49\n# edge case public key\nprivate = 106221fe5694a710d6e147696c5d5b93d6887d584f24f228182ebe1b1d2db85d\npublic = ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f\nresult = valid\nshared = 5e64924b91873b499a5402fa64337c65d4b2ed54beeb3fa5d7347809e43aef1c\n\n# tcId = 50\n# edge case public key\nprivate = d035de9456080d85a912083b2e3c7ddd7971f786f25a96c5e782cf6f4376e362\npublic = 000000fcffff030000e0ffff1f000000ffffff000000f8ffff070000c0ffff3f\nresult = valid\nshared = c052466f9712d9ec4ef40f276bb7e6441c5434a83efd8e41d20ce83f2dbf5952\n\n# tcId = 51\n# edge case public key\nprivate = a8f37318a4c760f3cb2d894822918735683cb1edacf3e666e15694154978fd6d\npublic = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f\nresult = valid\nshared = d151b97cba9c25d48e6d576338b97d53dd8b25e84f65f7a2091a17016317c553\n\n# tcId = 52\n# edge case public key\nprivate = 20d4d624cf732f826f09e8088017742f13f2da98f4dcf4b40519adb790cebf64\npublic = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f\nresult = valid\nshared = 5716296baf2b1a6b9cd15b23ba86829743d60b0396569be1d5b40014c06b477d\n\n# tcId = 53\n# edge case public key\nprivate = d806a735d138efb3b404683c9d84485ab4af540d0af253b574323d8913003c66\npublic = edffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fff7f\nresult = valid\nshared = ddbd56d0454b794c1d1d4923f023a51f6f34ef3f4868e3d6659307c683c74126\n\n# tcId = 54\n# edge case public key\nprivate = 184198c6228177f3ef41dc9a341258f8181ae365fe9ec98d93639b0bbee1467d\npublic = fffffffffeffff7ffffffffffeffff7ffffffffffeffff7ffffffffffeffff7f\nresult = valid\nshared = 8039eebed1a4f3b811ea92102a6267d4da412370f3f0d6b70f1faaa2e8d5236d\n\n# tcId = 55\n# edge case public key\nprivate = f0a46a7f4b989fe515edc441109346ba746ec1516896ec5b7e4f4d903064b463\npublic = edfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff7f\nresult = valid\nshared = b69524e3955da23df6ad1a7cd38540047f50860f1c8fded9b1fdfcc9e812a035\n\n# tcId = 56\n# edge case public key\nprivate = 881874fda3a99c0f0216e1172fbd07ab1c7df78602cc6b11264e57aab5f23a49\npublic = edfffffffffffffffffffffffffffffffffffffffffffffffeffffffffffff7f\nresult = valid\nshared = e417bb8854f3b4f70ecea557454c5c4e5f3804ae537960a8097b9f338410d757\n\n# tcId = 57\n# edge case public key\nprivate = b8d0f1ae05a5072831443150e202ac6db00322cdf341f467e9f296588b04db72\npublic = edfffffffffffffffffffffffffffffffeffffffffffffffffffffffffffff7f\nresult = valid\nshared = afca72bb8ef72", "7b60c530c937a2f7d06bb39c39b903a7f4435b3f5d8fc1ca810\n\n# tcId = 58\n# edge case public key\nprivate = c8619ba988859db7d6f20fbf3ffb8b113418cc278065b4e8bb6d4e5b3e7cb569\npublic = edfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffff7f\nresult = valid\nshared = 7e41c2886fed4af04c1641a59af93802f25af0f9cba7a29ae72e2a92f35a1e5a\n\n# tcId = 59\n# edge case public key\nprivate = f8d4ca1f37a30ec9acd6dbe5a6e150e5bc447d22b355d80ba002c5b05c26935d\npublic = edfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = valid\nshared = dd3abd4746bf4f2a0d93c02a7d19f76d921c090d07e6ea5abae7f28848355947\n\n# tcId = 60\n# edge case public key\nprivate = 88037ac8e33c72c2c51037c7c8c5288bba9265c82fd8c31796dd7ea5df9aaa4a\npublic = edffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = valid\nshared = 8c27b3bff8d3c1f6daf2d3b7b3479cf9ad2056e2002be247992a3b29de13a625\n\n# tcId = 61\n# edge case public key\nprivate = 5034ee7bf83a13d9167df86b0640294f3620f4f4d9030e5e293f9190824ae562\npublic = edfffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = valid\nshared = 8e1d2207b47432f881677448b9d426a30de1a1f3fd38cad6f4b23dbdfe8a2901\n\n# tcId = 62\n# edge case public key\nprivate = 40bd4e1caf39d9def7663823502dad3e7d30eb6eb01e9b89516d4f2f45b7cd7f\npublic = ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = valid\nshared = 2cf6974b0c070e3707bf92e721d3ea9de3db6f61ed810e0a23d72d433365f631\n\n# tcId = 63\n# public key with low order\nprivate = e0f978dfcd3a8f1a5093418de54136a584c20b7b349afdf6c0520886f95b1272\npublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 64\n# public key with low order\nprivate = 387355d995616090503aafad49da01fb3dc3eda962704eaee6b86f9e20c92579\npublic = 5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 65\n# public key with low order\nprivate = c8fe0df92ae68a03023fc0c9adb9557d31be7feed0d3ab36c558143daf4dbb40\npublic = ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,Twist,ZeroSharedSecret\n\n# tcId = 66\n# public key with low order\nprivate = c8d74acde5934e64b9895d5ff7afbffd7f704f7dfccff7ac28fa62a1e6410347\npublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,NonCanonicalPublic,Twist,ZeroSharedSecret\n\n# tcId = 67\n# public key with low order\nprivate = b85649d5120e01e8ccaf7b2fb8d81b62e8ad6f3d5c0553fdde1906cb9d79c050\npublic = 5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,NonCanonicalPublic,Twist,ZeroSharedSecret\n\n# tcId = 68\n# public key with low order\nprivate = 2064b2f4c9dc97ec7cf58932fdfa3265ba6ea4d11f0259b8efc8afb35db88c48\npublic = ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,NonCanonicalPublic,ZeroSharedSecret\n\n# tcId = 69\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 0000000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 70\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 0100000000000000000000000000000000000000000000000000000000000000\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 71\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 72\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 73\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 74\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 75\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 76\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 0000000000000000000000000000000000000000000000000000000000000080\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 77\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 0100000000000000000000000000000000000000000000000000000000000080\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 78\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 79\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = 5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 80\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 81\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 82\n# public key with low order\nprivate = 786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55\npublic = eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nresult = acceptable\nshared = 0000000000000000000000000000000000000000000000000000000000000000\nflags = LowOrderPublic,ZeroSharedSecret\n\n# tcId = 83\n# public key =\n# 57896044618658097711785492504343953926634992332820282019728792003956564819949\nprivate = 40ff586e73d61f0960dc2d763ac19e98225f1194f6fe43d5dd97ad55b3d35961\npublic = edfffffffffffffffffffff", @@ -4419,9 +5057,9 @@ static const char *kData175[] = { "n multiplication by 8\nprivate = a898af8138e11ae45bbcefa737182a571885f92d515c32056c7cb0d7deac4741\npublic = 0cad7545ade2fd93fcae007c97648348f26d85829bdb7223a63eccb84e56d475\nresult = valid\nshared = c8085877800c175e949cdd88e196eb9c4841da2ac446dfed9085bda5bbec265d\n\n# tcId = 487\n# special case for AA in multiplication by 9\nprivate = b0bfef6ec095b5a1f93917d32f16a21d0462c1fde17446f5a590232d9c895f4a\npublic = 60f27ed0a27804ced237cf3c1cc776650fb320bae6d5acb564e97b56cba25210\nresult = valid\nshared = 4c300895827382a9d1079028bd6f694a7a12ddac9c76abac6fdf5d29457a3310\n\n# tcId = 488\n# special case for AA in multiplication by 9\nprivate = 60497d4464ed8823c50fbc6b68620826c4f629c1d9193058df6bf857c6aecc4b\npublic = f93a73270ac19194b8e4ffd02be4b1438525f84a76224688ea89a9dd6a1bd623\nresult = acceptable\nshared = 7285fbb3f76340a979ab6e288727a2113332cf933809b018b8739a796a09d00b\nflags = Twist\n\n# tcId = 489\n# special case for AA in multiplication by 9\nprivate = 08c6cbe03792a3829f06e8ad54c55db113236ac0dcc9ab6a9a6b10eed1041b48\npublic = cf80c30fcbfd535666ca1da499e2e99cc537063e2de19458fcf92f5ee34acf47\nresult = acceptable\nshared = dabc3bd49f19cf7071802e43c863ed0b1d93a841588098b98a0c581bf4fe0a11\nflags = Twist\n\n# tcId = 490\n# special case for AA in multiplication by 9\nprivate = 50044da3315dd082e9dfb6a1994aabb331f53e0d1c12633383b2a3c8678cfe4c\npublic = 698effe0ad42e15ee1f46fde6fc5074ffda183bcf1b2db8647f561ddd191dd60\nresult = valid\nshared = a61a3b150b4770532373676298c9a5da28adcc4365b06fe07c959ca80e477a57\n\n# tcId = 491\n# special case for AA in multiplication by 9\nprivate = 285640da7a48252e35ddce60c14addb73097fbc9ac2f87c8d2772ce89aa6be4d\npublic = bd1565b4a3f8515dff577be6dcb414511d3d4ec2de15e0bd45b28e9cc4caef60\nresult = valid\nshared = 916ab4f3bfc8321e1087d9c5444f8f7a43e9ca6d29e7ba98a19dc05fff34ed4c\n\n# tcId = 492\n# special case for AA in multiplication by 9\nprivate = 783271c21199ba2e94ead92cd9dd79f70aab378b59497455d327a5907dafcb4a\npublic = b8649e13843f80cf5702398e4a9a8c378f29da96dfd6579f1eb4f7ea34df6765\nresult = acceptable\nshared = 844a5dd5139554ca7b41cbe6a4796193912e7aa4e201cc68944ce2a55774a10f\nflags = Twist\n\n# tcId = 493\n# special case for AA in multiplication by 9\nprivate = d0676a0b9a046c62d5b2e740d9cc43fa37965dea93c23254f7bf569f2bebaa4a\npublic = c396938737abdf791e09a97eba577c437d9b67c2dae94e13eab7296ec0fc737e\nresult = valid\nshared = 10780333b2a6170136265bb5ebc6c818817f2e48ae372528c8f34433fdd6215a\n\n# tcId = 494\n# special case for DA - CB in multiplication by 9\nprivate = 608c84d2b76fccda579e974db3d3b2ce39a6bc0dad440599db22411b60467849\npublic = 557b825012d98f065bb95a2ab9b2d2d8b83fd2037912508c263f86d7e36c4f24\nresult = acceptable\nshared = 5ce84842dbae8b795b3d545343558045508f271383bfb3dd3943f4101398c864\nflags = Twist\n\n# tcId = 495\n# special case for z_2 in multiplication by 9\nprivate = 80f233936a8821936d39114c84d929e79760b27680779e5009e1709410dd8e4f\npublic = ae98296d4a2fbcbb40b472f4063231608bb1465c226c8a4a2dff29afd915882a\nresult = valid\nshared = 4f11aa0c313195f96f25cadcbf49f06a932d8b051879ea537d1c6dfee7f36d35\n\n# tcId = 496\n# special case for z_2 in multiplication by 9\nprivate = c8d80b1a34f21194f047a6f0328bb947e2e7aff6a043553aa07f2abf99aaf048\npublic = 8b9d249829fbe81333d85050da88998f63fac665679e27dbbe21b745dd14e145\nresult = valid\nshared = 1d619070bf5626064be10025e74e336c81ef3166b743f99c751fb90587c31d7e\n\n# tcId = 497\n# special case for z_2 in multiplication by 9\nprivate = 9021477b452361580059364c6f94f4981ee94ea3f9b7d37439bc82ae45816f4d\npublic = 61896093e2697c78230afdda12639cbe4342827b8d2b093281f148eb60b9034b\nresult = valid\nshared = 532e797861db56b9d5db8825fb72f8629c2422f8abea721ad2d7b9e77a95b576\n\n# tcId = 498\n# special case for z_2 in multiplication by 9\nprivate = 6079dae04c40a59ea4e0c8c17092e4c85ea9133d143307363487836df4e30349\npublic = ccc1dc186229dba9a9360a0f7ff00247a3732625acaacd18ea13a9a8b40fac4f\nresult = acceptable\nshared = 4f678b64fd1f85cbbd5f7e7f3c8ac95ec7500e102e9006d6d42f48fb2473ab02\nflags = Twist\n\n# tcId = 499\n# special case for z_2 in multiplication by 9\nprivate = 281db6a5ac9a47d4a7b2b91a87f6536ce62d4e5129b8d647b97f9c504014894c\npublic = 69e368c0b7e78eb9f3a53bf458f6e79dc4883bf9458f04a8c12c4ddd94d62151\nresult = valid\nshared = e069fd06702f10f33adb8cf0766880634865b510e2da409241fb5f178050514a\n\n# tcId = 500\n# special case for z_2 in multiplication by 9\nprivate = d830f3c4785829a0f945857e0e85e0ae723702b57783b933cd2a2ad05484fe49\npublic = f21f9badd98dd8a103cc2ab5484fac6c2bfdd2671ee6e674134a86b89cee9160\nresult = valid\nshared = fee218eb1f92864486e83c1731f04bb8c7e6d7143e3915bcbf80fe03ff69dc77\n\n# tcId = 501\n# special case for E in multiplication by 9\nprivate = 10230bd0721f4c8c4b921881dd88c603af501ee80e2102f8acc30cf8b2acd349\npublic = e853062b2d6f38d021d645163ea208d0e193a479f11f99971b98e21188fd0b2c\nresult = acceptable\nshared = 64bdfa0207a174ca17eeba8df74d79b25f54510e6174923034a4d6ee0c167e7b\nflags = Twist\n\n# tcId = 502\n# special case for E in multiplication by 9\nprivate = f0a34d6d76896e17cb8f66feda23115ffb96f246b823bb63dec08335787de74c\npublic = 362eb92dab9fb29f7ed0e03843dcc15797928c2b4e51ec260204179c1c12945f\nresult = valid\nshared = d7f4583ee4fe86af3a3f1dfcb295ba3a3e37bced7b9c6f000a95336530318902\n\n# tcId = 503\n# special case for E in multiplication by 9\nprivate = 9073c1d0a173c7ff02dc966a165993d9c4c9357514f7a6bb7aaa4b0827718948\npublic = ff543f1e81996e88631f030ceba7e603b13033efd205e68bd36b28468134aa73\nresult = acceptable\nshared = c1b5e5f4401c98fa14eba8aafae30a641bfd8fb132be03413f3bf29290d49e0b\nflags = Twist\n\n# tcId = 504\n# special case for x_2 in multiplication by 9\nprivate = b0c1822566e016c12ae35ec035edd09af3cb7a48f55c9028e05e1178a8c3824e\npublic = 90ef70844ead1613f69df7d78c057813f866c0d95e6d22caee4a012b9c1c4b33\nresult = valid\nshared = 9369ebb3d2b744341cba77302719a4b2d63aff612872f86d9877a76bc919ca1c\n\n# tcId = 505\n# special case for x_2 in multiplication by 9\nprivate = e06fe64e2117796f997bbcd3bcad3067cf1291640a3a643fb359809a4016834d\npublic = 88c1ae575ad073dda66c6eacb7b7f436e1f8ad72a0db5c04e5660b7b719e4c4b\nresult = acceptable\nshared = 335394be9c154901c0b4063300001804b1cd01b27fa562e44f3302168837166e\nflags = Twist\n\n# tcId = 506\n# special case for x_2 in multiplication by 9\nprivate = 707ee81f113a244c9d87608b12158c50f9ac1f2c8948d170ad16ab0ad866d74b\npublic = dcffc4c1e1fba5fda9d5c98421d99c257afa90921bc212a046d90f6683e8a467\nresult = acceptable\nshared = 7ecdd54c5e15f7b4061be2c30b5a4884a0256581f87df60d579a3345653eb641\nflags = Twist\n\n# tcId = 507\n# special case for BB in multiplication by 9\nprivate = 7089654baacbb65bd00cd8cb9de4680e748075e8842ca69d448fb50fea85e74e\npublic = 6c0044cd10578c5aff1ff4917b041b76c9a9ae23664eb8cf978bd7aa192cf249\nresult = valid\nshared = 0d8c21fa800ee63ce5e473d4c2975495062d8afa655091122cb41799d374594f\n\n# tcId = 508\n# special case for BB in multiplication by 9\nprivate = 8089784c52cd67e4536e568218c7b7033b28413f942fca24ed69e43496efa14b\npublic = d9089de902e143dcd9107e5a3393a3f7fe05d926c357b47e307a236cb590fd64\nresult = valid\nshared = db6fec44bf118316a6bdfbae9af447baede4d82daa16bed596ea6f05d4a51400\n\n# tcId = 509\n# special case for BB in multiplication by 9\nprivate = 00e73e4e013148b9f05273bad626bb126a40ec4558f5425096b48947e0a9de4a\npublic = 8c4a26aa319c2cc4a4158c2bc69a0d5b340b60628a14cf31bb0ae5ddc38ae866\nresult = valid\nshared = ecc1204bc753c4cec4c9059fd7b504944ebf995ab1b1d49f0b3b325353be3a15\n\n# tcId = 510\n# special case for BB in multiplication by 9\nprivate = 78ed4c9bf9f44db8d93388985191ecf59226b9c1205fe7e762c327581c75884e\npublic = ce7295d1227c9062aab9cf02fc5671fb81632e725367f131d4122824a6132d68\nresult = valid\nshared = 3740de297ff0122067951e8985247123440e0f27171da99e263d5b4450f59f3d\n\n# tcId = 511\n# private key == -1 (mod order)\nprivate = a023cdd083ef5bb82f10d62e59e15a6800000000000000000000000000000050\npublic = 6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376\nresult = valid\nshared = 6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376\n\n# tcId = 512\n# private key == 1 (mod order) on twist\nprivate = 58083dd261ad91eff952322ec824c682ffffffffffffffffffffffffffffff5f\npublic = 2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035\nresult = acceptable\nshared = 2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035\nflags = Twist\n\n# tcId = 513\n# special cas", "e private key\nprivate = 4855555555555555555555555555555555555555555555555555555555555555\npublic = 3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666\nresult = valid\nshared = 63ef7d1c586476ec78bb7f747e321e01102166bf967a9ea9ba9741f49d439510\n\n# tcId = 514\n# special case private key\nprivate = 4855555555555555555555555555555555555555555555555555555555555555\npublic = 9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a\nresult = valid\nshared = 8b98ef4d6bf30df7f88e58d51505d37ed6845a969fe598747c033dcd08014065\n\n# tcId = 515\n# special case private key\nprivate = 4855555555555555555555555555555555555555555555555555555555555555\npublic = be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308\nresult = valid\nshared = cfa83e098829fe82fd4c14355f70829015219942c01e2b85bdd9ac4889ec2921\n\n# tcId = 516\n# special case private key\nprivate = b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a\npublic = 3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666\nresult = valid\nshared = 4782036d6b136ca44a2fd7674d8afb0169943230ac8eab5160a212376c06d778\n\n# tcId = 517\n# special case private key\nprivate = b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a\npublic = 9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a\nresult = valid\nshared = 65fc1e7453a3f8c7ebcd577ade4b8efe1035efc181ab3bdb2fcc7484cbcf1e4e\n\n# tcId = 518\n# special case private key\nprivate = b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a\npublic = be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308\nresult = valid\nshared = e3c649beae7cc4a0698d519a0a61932ee5493cbb590dbe14db0274cc8611f914\n\n", }; -static const size_t kLen176 = 129059; +static const size_t kLen230 = 129059; -static const char *kData176[] = { +static const char *kData230[] = { "# Imported from Wycheproof's xchacha20_poly1305_test.json.\n# This file is generated by convert_wycheproof.go. Do not edit by hand.\n#\n# Algorithm: XCHACHA20-POLY1305\n# Generator version: 0.8r12\n\n[ivSize = 192]\n[keySize = 256]\n[tagSize = 128]\n\n# tcId = 1\n# draft-arciszewski-xchacha-02\naad = 50515253c0c1c2c3c4c5c6c7\nct = bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e\niv = 404142434445464748494a4b4c4d4e4f5051525354555657\nkey = 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f\nmsg = 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e\nresult = valid\ntag = c0875924c1c7987947deafd8780acf49\n\n# tcId = 2\naad = \nct = \niv = 6a5e0c4617e07091b605a4de2c02dde117de2ebd53b23497\nkey = ab1562faea9f47af3ae1c3d6d030e3af230255dff3df583ced6fbbcbf9d606a9\nmsg = \nresult = valid\ntag = e2697ea6877aba39d9555a00e14db041\n\n# tcId = 3\naad = 8780fb400f94c55d\nct = \niv = 3ec3f7c45e687d75a895bf5e71809e7cdac32158bb48ec0d\nkey = d821dce9b890ea37ae1c89e7cb6aeae9371b8179add0d08f5494718322ae0071\nmsg = \nresult = valid\ntag = 966c22d655b9e56326024f028cf887ad\n\n# tcId = 4\naad = \nct = 45\niv = 05188738844ab90a8b11beef38eaec3e100d8f4f85ae7a41\nkey = 303ccb2e1567c3d9f629a5c632dbc62a9a82c525674f67988b31bd1dee990538\nmsg = 62\nresult = valid\ntag = d15734f984d749fa3f0550a70c43dddf\n\n# tcId = 5\naad = 6384f4714ff18c18\nct = b0\niv = cd78f4533c94648feacd5aef0291b00b454ee3dcdb76dcc8\nkey = 697c197c9e0023c8eee42ddf08c12c46718a436561b0c66d998c81879f7cb74c\nmsg = e1\nresult = valid\ntag = e5e35f5332f91bdd2d28e59d68a0b141\n\n# tcId = 6\naad = \nct = 5e03\niv = b60ca1ab736deebe4d9da78bc7cbbab91be14a2f884240b7\nkey = c11213bcff39a88b0e3ecc47b23acf6c3014e4708d80dcca162da7377b316ab3\nmsg = 57f9\nresult = valid\ntag = eed21c2cd3f395538d677602964ed578\n\n# tcId = 7\naad = 322f82a87ee82997\nct = b56a\niv = 4fd76cbf27cb387502a706461564e5a5c14e027d40bc6eef\nkey = b0f51b8227013464943370e926b6ed1c9fb45b5994af829ff3a9f998b77d822c\nmsg = ab8c\nresult = valid\ntag = edcafa2c9032aff695e427fc2a344767\n\n# tcId = 8\naad = \nct = 31a461\niv = 737e3e7699f788c4136938c0f65310684eacbb5f96ecd98d\nkey = 17afb080753f2aa0af0a7f4821f6ab2709a6b2b5b9f2f262910e3b27b82c6c1c\nmsg = 2af96a\nresult = valid\ntag = 2b745098b154bb90903b0240c3bc95e9\n\n# tcId = 9\naad = 9d53316bd2aa3e3d\nct = d41c02\niv = 1436f36466fce5db337a73ec18e269e6e985d91035128183\nkey = b720aea3df85fb3fb00583eddbebc5c545bcdcb7f6f2a94c1087950e16d68278\nmsg = 4799c4\nresult = valid\ntag = 8faa889d7f189cd9473e19200ef03920\n\n# tcId = 10\naad = \nct = a3b405bb\niv = 7c39999d498286d974d266b2f027a26d7fbcd330869d9f93\nkey = d7704e505826124ab02935e7349a4e13391e6dc020fee95cd30654cdc5d5f393\nmsg = c44efab6\nresult = valid\ntag = c50e2ddb97df1ee58561c97a7b746c24\n\n# tcId = 11\naad = 8e0ac97934605052\nct = 9406a621\niv = eb4e36c637d1908db2c2ae9c72cfbae50655cb5f6504c4b6\nkey = c70ef9ee59259019960c918bfc91237ed6786c73f2b62427e4cbd4d8096a1f03\nmsg = 2738c9d0\nresult = valid\ntag = 916b78ee04b20b8cd90f00b81bb8091c\n\n# tcId = 12\naad = \nct = 2a01d08fe2\niv = 49875536d4946af49288f36684e25ff35998d50be6bcfcc2\nkey = 7fac2a879ffddf5e36e04e3edcb8aa6be18a8326b28f76b15623307badc1ece2\nmsg = 2c4c38f435\nresult = valid\ntag = 9cbe5f3e782f57a33a45b1f4aeeeea6e\n\n# tcId = 13\naad = 5cbdd482f3429a27\nct = fb5daf8c6e\niv = 88ccb58d435ea760f19e1fa6172139a071c0c5143959a56c\nkey = 48f1389d9222a80898ca26b5cfef5dc82dfc0af7cf66ea1e01bc5279e7414247\nmsg = 945a1fd040\nresult = valid\ntag = ec1682b61957493c2eb758d7a2b7a179\n\n# tcId = 14\naad = \nct = 856c300cfceb\niv = 89c9806ad153b805f1bf5b50738319011d5fc070bb551ee1\nkey = 737cdaa2ce1e4740e75af4aaf68c0296c1607bde871d2452e628f1456239c753\nmsg = fae858dd3150\nresult = valid\ntag = aaa9875ebd42a11d12cf0aca26021f4a\n\n# tcId = 15\naad = 71b29930f84a572d\nct = 6438fc8f8788\niv = 5cbdc34772b54fb4fba9eca1e2745e0e3704d9d7b5c78fb4\nkey = 9f7cd632bd5eb5f017b898590d645571ef56e521024eda36eff893a6ad04b935\nmsg = 53abb8943ada\nresult = valid\ntag = af05a4def2ad39a195a7b8c222050111\n\n# tcId = 16\naad = \nct = 843f1039531fe1\niv = a020b016d952a5948a3d226bb1b73efc39d46845f3bf0ca5\nkey = ecf60cd2af8c7155c0be848ecdaa5baddad6bd5f254a2d98f47bef83999f60ee\nmsg = ea30907da57d78\nresult = valid\ntag = efd99acdab540690ec91a7ad5697cb33\n\n# tcId = 17\naad = 0c87cc97c49e166a\nct = f99f3fb49ec920\niv = b1f05bb66d29bcddf7412f6a556ff7540aac452457dd69e6\nkey = a9376583c47176728d7b2ed1039f0b12b2c7a97563937f7fe976ce4548f7cb00\nmsg = 4a3d9926dc9757\nresult = valid\ntag = 91c3356ee6601ae7073673d2ef30293b\n\n# tcId = 18\naad = \nct = 5b596bab0890286e\niv = f4f3484cacdce37cf5134a12f57903096acd3553607eb682\nkey = bf9ae8ceceb8d3001da7652c4cec02adda8696294a4ab542b41b5ba86c096a75\nmsg = 6eb5e11b358c0ab1\nresult = valid\ntag = d4474d9520f7178e9811f624209721ea\n\n# tcId = 19\naad = 06947c3afa797e99\nct = 80c8e9ac2cec97ce\niv = cc4781134455e89c836f7433bd0426776f945d82f6358276\nkey = d447796ed4ceb2e43942700e7759e335f67afa8653748db95f924c94488195db\nmsg = 77c46ada19c81849\nresult = valid\ntag = 9b62dcc8076098affcb6e7995aaa99a6\n\n# tcId = 20\naad = \nct = 37d696264f781338c9\niv = 200a30270bc911dd3b8a8ea2a6e6ce75be9cfb0f5431db3d\nkey = 08eb57d7bc113f7fbdda1b32237cdd06cccd52ef4a89a831c5e0564370c885ad\nmsg = 704df23a31893799ee\nresult = valid\ntag = 5fddaf74438159acc3c5667b5e84af13\n\n# tcId = 21\naad = 00fc4f61d9777504\nct = a55cbb308f81e449e9\niv = a613e0b17fafb47c79614d39959b986ba2c97b0215676d41\nkey = 9f093b6bb75f1609ab1e00a4bf4667961d885f01deb6520c5bb16ec21e033766\nmsg = 472578ece9fe828dc6\nresult = valid\ntag = 8174bd595da1be72cc226e74c46a4af5\n\n# tcId = 22\naad = \nct = 8bd51b64fcd244f0b3aa\niv = 21b40036745f64b2aab3e89665cf4dab2b690d88721fe9a3\nkey = e421bb3269130c731d1947e7b5d233c11d195ceed1d08634743db9c252bfefa5\nmsg = 1155c7f0ee3e1faa641e\nresult = valid\ntag = dbdd1558934b83ae4393ade73e9edadb\n\n# tcId = 23\naad = e7c9d1dda90b699e\nct = e5aad5c055dc6df73cf0\niv = 33dfa71a0cb2aca008e4c8e8a72dbda4c407bbadd5d7e1a5\nkey = 8a275c90eb8688c5d9e82b74331cf104a2c8757d6257079b1d8035bb40d6a8d9\nmsg = 3c2da491f244acfbd1dc\nresult = valid\ntag = 96fc30292cc8381c345d5f2964ba5626\n\n# tcId = 24\naad = \nct = 2a41cc14a6a65bbb153758\niv = 5a44801d2baabfe8cbee6da52bb51b5297856065fbf33944\nkey = 2d97a35e4b6617e5f4a0f50dcda7622f321cad936a246d9beada9d75e142ef3d\nmsg = b94df0d444dac848ffcad4\nresult = valid\ntag = 1044cd75f2e61cbecbf3a7a77c13ef01\n\n# tcId = 25\naad = d78dcb5431ef5669\nct = 5b3193405830b6840a4474\niv = 07590877a1e1df3a78fe4d04dd64b6cb79f1df45de17685b\nkey = 70d11ca92903865c6a6d8ba497f5a2d65f23b72198d7fc7fdaeda6c2632f7e46\nmsg = f61bb0dd66e5905f1a7ea1\nresult = valid\ntag = 4b10bef8e8a3c2e6ae87fb8fb2a8bdd5\n\n# tcId = 26\naad = \nct = 528dfb79ea182945f13bafb7\niv = 94f86b0fd8a6ed90d3780eca23a82f4387da82b0894ae317\nkey = 05c7317f07a0e89ce1b5ac41df8064faa9fd569ee1c357cd01a2872076477ac5\nmsg = b63e50c9bcd01406b6f78f86\nresult = valid\ntag = 4fc22f4491449bb4ffe6a1eb266e2a91\n\n# tcId = 27\naad = a67a57310055b193\nct = 2345bfc502f9c62d64ad87f9\niv = 829cb09e40c2cc5f7648adc177e56ef53a58bfa16a859338\nkey = 924aafdb5b8a206b3e49aefe8944918cdcc8ccb5bb4b8c4ee81b847aa6fa52a0\nmsg = 68576b935acaab8b33ab62e3\nresult = valid\ntag = 6736f095a28b887238f80dc562eaa25c\n\n# tcId = 28\naad = \nct = d1f725ace69f7899ef51c11dd3\niv = 016dac89c624a9d425ae377132421c37c4486895bef270f0\nkey = 332b7ec9bf4a983eb02af7efee8ffaf5627b66f29e3e4728f50894fe176788d8\nmsg = 8289397a58921bb3201b29c505\nresult = valid\ntag = 0d2858cc30497107a035929fdf2eb6af\n\n# tcId = 29\naad = 4dc711c827a6f626\nct = 6c0e9d31b8e45591726f4cfc63\niv = e8252b018f9e0c3fbd4a6ad0d06346302b8ed7dcb206c3ad\nkey = b75fd9dd7ecca4f3eab36c36a176530dd3ffc825c202613740311d11cd501804\nmsg = 9800f8b835c4ff490ebd764914\nresult = valid\ntag = 2ce700f1f3dc7d3f60607058ac3b817e\n\n# tcId = 30\naad = \nct = 23a49dbe4b699d481621d9fc2db6\niv = e698d39b3cec2634dbe035a55b8fce3b0041aabe4156f713\nkey = 2bddfb332f74ac31fcf91d652c7b41fbcb26a10f2792ecf8075478e645042f87\nmsg = 813974b924c7618c63070d0247f0\nresult = valid\ntag = ef2cfb8423ae6f9faaec81025e6e274b\n\n# tcId = 31\naad = 0b9df4ffd1c9ccbe\nct = 0596f5709407a62fffce84240346\niv = d025b0", "188edc9c40a8d6fc807cead97749016c9016d62ea5\nkey = ea029c829c13a580b66aca21133a16933235c11c42905a640104a2ae9bb5cf82\nmsg = a67e672df18cfbe125b212d63ec8\nresult = valid\ntag = 893772def69053b0aaf3bf1c21144ebf\n\n# tcId = 32\naad = \nct = c5aa0caf82b963f1e9b84a789a77d3\niv = 9ce202557c11a57cb14e7e4bd7986f1cf6232196672d25ea\nkey = 1c838d9f68e687fbdddc6dff7f2e44b277bfeb316ae5d11b3e935889b48539d8\nmsg = 37905d98be9839e02923d119a88d56\nresult = valid\ntag = 59c3e2e43cc098ed413ece9d9a6fd47a\n\n# tcId = 33\naad = a2e44e165e7ca5f7\nct = f91d01453f568774115f75b5dad642\niv = ffdca5c51a0852ab18dd484af6664b63ab4097d303450837\nkey = 51a99f0646767fbc01d7736df0340191acfbb5ae0288ed6fff2d34f0ea31470f\nmsg = 93553954f0be4e24185601ce5c3c34\nresult = valid\ntag = 8fc36af6ae5ee3e05b38ed43598bbfcd\n\n# tcId = 34\naad = \nct = 732715c60018fb0ed55c14c1fa9a5273\niv = 25dc279923c1bcdaa7a36e7b884b51f62343abad71986037\nkey = 6a1f808358461e75072a054e2fc4e4c3e7f882c57920dda3278d0c860ca704e3\nmsg = f242209c67698ea32c2152f8785b7d82\nresult = valid\ntag = afe3c4f050bf001e1dfcb2313dd8edd2\n\n# tcId = 35\naad = 8981c7260d514ab6\nct = a7eb11bfaa0d1c2ce457598049399575\niv = c02c8c595064ac303b1be5df6ab43048856e97ae9962fb8f\nkey = 7fb18b56f3f5122585754a3b6c6a4e523036e66793db569c3e8e28032e916eb6\nmsg = 6e8c0bb3361908f5b33e059408651ae3\nresult = valid\ntag = 485a94f61aa5f47a3036e85a57effd2f\n\n# tcId = 36\naad = \nct = 0fd7386b41396e0558495c45cdba029062\niv = 9a61cf35aecbd40a65b35a64b516896f3de7f977b5c9901d\nkey = 3b11469dc670f5dfbe0aad7d15ee4862c92cb07842e5dcc48fa8e5fc817f1749\nmsg = 540731e4ba3e4e2fd623a1a13233736ee7\nresult = valid\ntag = 29f601a11f6a1072342c60b631de6085\n\n# tcId = 37\naad = 23230be73ba2a6fb\nct = 86d0fd1a325d501fe9efe83d3a3f62e346\niv = 6570889af7acab7f555337bdce05499e8eb0d8d3d1a77660\nkey = e6d9fc8a9e3fa6ecadd9faffbb6ff387aa96502e60adadab029a9146ee39de28\nmsg = deec95974eeef6e2b99739bed2f4a74771\nresult = valid\ntag = 1ed9a79616c787a8de2ff5cdac6af0c9\n\n# tcId = 38\naad = \nct = daea40da316b8e78254a737c57063c4ad8b7\niv = f3d84207ab5574e4bc74ae61b17ccaccc7c46eb3471e0e53\nkey = cbaa654cd4ad70ae96d3412680e60522807e9b887ec6dbfcd6e71e917e29ce62\nmsg = f55aaf5a55432c20fb782c552e5ae096eb23\nresult = valid\ntag = e13ff7a7e2c85b1abb5350134dfa7f9b\n\n# tcId = 39\naad = b6bea5c60f288109\nct = eef62d53545698255648a483708c9cc93937\niv = de1e034363b0daec9828159e7996faff33a5f63eb552eb5f\nkey = 5b51ea4943ce173baa53f84a6ef59cb1e25b794768508b8dd8dcbfbc1744c18a\nmsg = 953939dd7601f17071b2bf776e4b1ed629ce\nresult = valid\ntag = 182529b1d07dbcb4bd89b3c5e4c8fac9\n\n# tcId = 40\naad = \nct = 03dfbb3407a55ab0dbc451d0289de44acb5f33\niv = 74533cbe3ff9ec5a66604c88f5dae4d7efe4f604111f79fc\nkey = c5d3917ffb42b0508296cb245d468b04bbaa2c8c8c32e845415a911ea85f95f1\nmsg = 0afab6dbab51f929332d743ccfbb9f34877bc9\nresult = valid\ntag = a050def2e06a9ed3d10be180bafa636d\n\n# tcId = 41\naad = 880ac1004984fb3e\nct = 95a9bd7bf7e9836e5f8a75393c70da0d9b1d97\niv = 562f3b788783bbb72e465c9d04eb555f366c66de32356e7b\nkey = 77cbd62759966c03b4487ce7cb3fca652c30198cdc0de5d447256e979e041c87\nmsg = 0e677082f7dd9c56bd365310c15a18de78df6d\nresult = valid\ntag = f028003066f8902c5d74ca6bc526e346\n\n# tcId = 42\naad = \nct = 4ad85a75f1a975bbf3ee5302b71949036e3a2198\niv = 5fb9a00843c4b192bf6c3bc29451c237f30a607d3c637b85\nkey = 40e231268005ff28c36bd00167ea39131d262f3a591b0d1508c11b00ed04a0b6\nmsg = d34b950a1c4f2ae5c94a1fddd6574c5d9c0ab18f\nresult = valid\ntag = b82c05b09328949aa70bb537e871cd70\n\n# tcId = 43\naad = 043cd9069dbd8cb5\nct = dfca9d845c21093f43348a4f6e72e324e9673129\niv = 7ade1bc01148ac071bfbe9870fe2023a7769b92312f45e0a\nkey = d66e92c86712132b1e3f5ba3a4cd006b9de1fa444246d99ef02e5b190a73089d\nmsg = 1cf9f2a93cb056fa4222c5850872d9989bc8c185\nresult = valid\ntag = 9defc3de90d493be2a1945d11c569095\n\n# tcId = 44\naad = \nct = 74634f111539fac80bb29d76ba656e5af90fd37f8e\niv = 45ccb4a19073c79a4ac1e052d4664d0dd1c730a6a2e87fe8\nkey = 841404f7e07cdebeb48efd25a75444b6de170995cd460e38ff5930dc9cf5eba2\nmsg = 5d583f68421d00cd8d95896a091b9bb10b744c61c4\nresult = valid\ntag = c04ce25d27416ae5f181238acf9508bc\n\n# tcId = 45\naad = 91b46ee1f7a9361b\nct = 0c1afa5419abb32e479b181a6e51cd99eb041bc37d\niv = 89248df60acfa757945d12647a14cc5bc6508bb2b9e4999c\nkey = 77a812cdbce2b7327dbbaecf6f81340b0ac97589676939d1ff0e69c3373326a3\nmsg = 2573f8f0276ce3b2b38fb727575f376a2eeb305758\nresult = valid\ntag = 6c0b51ea2fc63841893216b03eb47be0\n\n# tcId = 46\naad = \nct = 59d9c3f18cbc59a3c04cdc6904cb860aae69a5485147\niv = ec272b052c33c84a611512a483c3fcec40501240eb7a42ee\nkey = f2f9bdba59206e8c31a3338213d6a46a40aee237f631906aff076fe2d29d3b85\nmsg = 408c4cac91b4bd3ce25c8971b1ed8adb20ed667f8393\nresult = valid\ntag = 63e55e220873e295a5b86543334b1715\n\n# tcId = 47\naad = 1bc37fc6729b401d\nct = d5a1f87dae98ab385d5d34626c295cca0ed6931635f4\niv = a131b4b0582be36dcce56beb036ec4fc31147efed7ff4718\nkey = d9aa0213bfac5ee89f9ef2c6f616d8f71c3725dafe7926504e18b141192c33b0\nmsg = 081280932efbce0a5500d76d41c7dd2ddbc3311dc0cd\nresult = valid\ntag = 25f2fa45c86c4cb0f02f99050e9d5ab7\n\n# tcId = 48\naad = \nct = 93034cdc9298d0086b8e8bbf3aea637484454015cf544d\niv = df72b7fe00eb070276ba1b0de6b17a6100fe0d660bf3c6c7\nkey = d7b0b278c5ede48da2db2f6ec6f8b23282d3c940bd1eb59f7102bf69c683298d\nmsg = 0f44c184d297c0a66467d54ac982f922b119d5b4c8b238\nresult = valid\ntag = b1e1dcf03663a995c6c14991b5558159\n\n# tcId = 49\naad = 04e0e991fb5a465e\nct = 83a8bbe26ad18129459f66f6dc771c653a3dbb88a00b11\niv = 0378f12d4891c68477d90f16f2ff59287c81922b73cec608\nkey = bd5040047cd7bd0bd1ca22164058a2901feb383c1ccba5c71c853f186d4e2b9e\nmsg = 29b7080f92c860ca4dd501f18b041c5cbc5c131783a720\nresult = valid\ntag = 791971c0f5ba2c8b7635924267c68f32\n\n# tcId = 50\naad = \nct = 1a0bc208b17fb629200e805da495db70c599ecb3c3b9cc94\niv = c9f5d4dfd5dd2276d68b25c6178d9ef2f38756df4be9d4b3\nkey = 3b96dbe28ee07208cdf703f1488f478134147363da1502249e025e0efe5cb663\nmsg = 8f37fd7e3e2f6563a9883d4adb92b5c37242a56b73a6fb7e\nresult = valid\ntag = 08b9477bc98543019ddaa7ae380f83dd\n\n# tcId = 51\naad = e1b2f309ce5fabe8\nct = e9dd13d48dd7258682311bfec967e1a1ebc562855f224f41\niv = 90b932e3464c8b66d3d2fec2bc9097289f147e05f18a9867\nkey = 53fc679ebe23b70714ab4ce6c8b0de5df656dca27177512654da31f6848dbe6b\nmsg = 8b0b4038c0eebea97fa1f93b7c2f3576898e7cdc9fd702d0\nresult = valid\ntag = d9038207dbfc82a9a9d507fe254d57c2\n\n# tcId = 52\naad = \nct = 666f807a6e5d0253fe1967d45efea42cf1f421789b7f48e0dc\niv = d758776af8d089ef14a075ddf683e6669ed8109fe5681833\nkey = 275ac60ffa734bf86601c951d0bd263b9651181c32f41fce90d59cb8d59da081\nmsg = 1fa3b565515a429f78fb36e93e048425ffb64bc9e9e68336b3\nresult = valid\ntag = 5d423636988dd257e5cbd40ee28ae94e\n\n# tcId = 53\naad = bbcbfa1779f4122c\nct = 369a80f75ad28fd05cb3c944e0a8c8b37ce65bbd1f6d4b355a\niv = 9628e46f25d08b206371449e7321d6bf5d811629e01ef32b\nkey = ec4d4b14860a36fe8afb2861c1376db8004cc2d37eb1ebb609343daf24bc39fb\nmsg = 201ec6c1d0675e818cb7a4e583ea1aa1afde1bbda1f0f549e1\nresult = valid\ntag = 3ca5005eda0b99d6566ac841340ad23a\n\n# tcId = 54\naad = \nct = b6faccf43dabd8965cb231fe96a2bdf2cb51e0b9afb6445c21eb\niv = ec3dae28ec71ceba5b97a933d30b9fb98a40d4c92e6f54ef\nkey = 53f9c2c335c1c5cde744e890f6bd291e4484925aaa036f1e74f0144603322648\nmsg = 00f4f6a8c09ecbff3e6e825ca676a5cb8373d4915ecaf5d317a1\nresult = valid\ntag = ee91b39d01a114f80a7c5e7e1a0b2868\n\n# tcId = 55\naad = a6d7d9034512781c\nct = c97a4ba644788bfdeeb0a5de228948902a57359879c82cf8ead9\niv = a7f4c26140ba7d8a884de794fb23a50c6647627fa85ef9f7\nkey = 9bb8bc991f01fb26df610032e1bf6ed0e2652629a6726aec9c23df4fefbdb594\nmsg = ebcb0777bd1c3385376270e543521e11f4bac00d0f9c0192581e\nresult = valid\ntag = bf51aa205497db895f008d828040150f\n\n# tcId = 56\naad = \nct = 28cf032caf586255ee3f3f70492d33458a7b42473b8e354d983dfd\niv = 7e4c8d0e24ab24f500053964774c92f808bafc42be0f6a34\nkey = 69b8b0846c47226dbb278f83082b75476e89a77444bfa06de69395f16c6eed01\nmsg = 3b406d4c07f2ef751ac701fe944b2392bd59fb0ee4b32e6cbf8958\nresult = valid\ntag = 58896a5d7618837701ed8dda9b18d82c\n\n# tcId = 57\naad = f5fa84749ff438f4\nct = be95d62d6acb3e5344f6b4ddbddfb45fa479c2d1577a42967dc0ad\niv = 26b2165f4b22415df4c052564b87d62c4c2c01df47c82cd8\nkey = aa6d2da8fe7ce3228f15e09ae8c7f3d1b0220679a3e0e13e7523060b5b8d09b6\nmsg = 92763e759a5c0b8c4d40d6398fa9e257900ff4b1f31000dbd9a15e\nresult = valid\ntag = 61ac094fefb1237c9d44ab7f4bbbf5f9\n\n# tcId = 58\naad = \nct = 2248e5332ed42c42fcb6a029e3d8f9f96cbc32d34fa5f302fabf1bf3\niv ", "= b595d9204461e311915cc17df51a3bbfa55c3a98aafbbaee\nkey = 31b9e848dfd3dd1ec05410975190109f550ee6e5235f040ce6faf6c380fba49d\nmsg = 95272cdea7a15889059b4e1de058c869e1776384159539470b542ed8\nresult = valid\ntag = b777e88479292944c5d6ace1ffd24ac2\n\n# tcId = 59\naad = 96fc6284d7eeb53c\nct = b10f9fbd87f51ebeae1942b9afb59749987b1575babd8008b281a662\niv = bc101b6d01bda7e13d402aa0023f0507ab02aa58758cb6aa\nkey = da132c34b2291a15777d3ebda2ed0078028c215038c2410d822578dcc869ea8d\nmsg = 331f3d53965bfee2edb463c5b21751eb445289287fada2aedae99258\nresult = valid\ntag = 54ad4e664b86333223fca6869c501dc2\n\n# tcId = 60\naad = \nct = ffb587ec97c7d11ca75629f066881f6b2c392fa71b73fc4cb4559a645d\niv = 4adcd5ecf1506fe7a38adf5634b454bf90278c9ebffbac87\nkey = d7e5e9c008af44266c876fa6b02a453854703c1a4fd221573c382c8d512a982d\nmsg = f8b3ae84d6502d353d57c970da5f9bc53de7a5c6262ba7a7b2220d0ee1\nresult = valid\ntag = ec9db510c3bb11831c20684d82e45053\n\n# tcId = 61\naad = cec8c976f2e25979\nct = 5d3ce03a6f43eab32a91b6eb87666af14e5e28d98d23c49c56557497d5\niv = 055776b422138960f6631e3c58f3ba0688082747de4ae5f6\nkey = 1e72be02d7ebf3c78b400efd005f5b6b983ede08443541475808d43e6d30eab8\nmsg = f2654733ca29af4bb29347f7a6508ed87913e0faa885505928ac1ee86e\nresult = valid\ntag = b324b10851d159bd3822705a9d638038\n\n# tcId = 62\naad = \nct = aa6edcb0f49535b2d2fa2e5f0b29343ba0c9c1667c401c78a3a8b8a61ad2\niv = cb52ad5674aff0762ef49fb3bed4722dcef2bcbc4f3c316a\nkey = 98362eff7af1e38d3d77d4a013bb6bf3fb3690568bf897651c578b21572fd37e\nmsg = a40610eaf3a823c06936293473ca36a2952d0eb5e5bbc18be123a07f8bc8\nresult = valid\ntag = 98d5e90a5a64e411c98d7c9e91557f5c\n\n# tcId = 63\naad = f5203e702570c4b1\nct = 3d1add00e51e60b16825272790ff47c0d533bfe65484d105ee7a69896c48\niv = f2f09c3469e2cf73b07620e461d7b1ad999c5f7d54867d21\nkey = 8f0e3dc43b86943ed4b0361fa5aa49999f24bc1e102bf3afb439e44f9ce43504\nmsg = dba4ed2a7938826c43548f6976d8f0ec1838fe71cc535b2a5d56e4d3d5ca\nresult = valid\ntag = a018e2629d5656920f1202e65624b056\n\n# tcId = 64\naad = \nct = 1ca6389e16c2f43e9e89447991d1472c8283a8dd94fdf61c4f5aee746cb537\niv = 17d6ff40ad135ac9df55fa5c0eaf03e5d91cdac63c684e8e\nkey = 16a376d68b3105262a07558e5e448ecdcbe075770cf60e7b7db1420f4fa4e36d\nmsg = bdb5500794edd38a398f18f83de03e16f135ea960d3b8c6578abc541aa1d03\nresult = valid\ntag = 33107bbbc06e563abf48979dbc7c66b6\n\n# tcId = 65\naad = 3fe9ad465d0aa3fa\nct = e8ae311bf2e80d696c543cd272d3e50dc968a0ab47259c461e0dec35f77530\niv = c306b69443bfdbedb5ce9f9bb6088132a88e8a175d3bd769\nkey = 8e1fb8cc57ca60ae091d27e292923272439c37f2dede36b2c2aaee96439d5a31\nmsg = 1d884a83a5f9b00b8951ef81778bd7c991cdc911127eee9dfeff82c48ca937\nresult = valid\ntag = 906de4c31eb2ce283eeb95388b0d83ce\n\n# tcId = 66\naad = \nct = d34c1778d105d0e80d429c86b879d52835cf8aebc5a04a9084cff1f9646e040a\niv = 0140f2791eb81fd4b69edf2d9ba4b2d62eab1d296741583f\nkey = 2ed460a56867ee1a2877a8f3d2d98fb886cfcc8913e31c3d08f42374ba37ebb1\nmsg = 318cc4bf151c3baaee5a783ec091ab618f2ecacf38c962ba9c32c323696cc94c\nresult = valid\ntag = ac8a68605a0567c559442342b764b964\n\n# tcId = 67\naad = 1264b91e71865033\nct = cc24cfa62063d11b2c31cf25ceb7308ca376feb1dd6bc102ed7db8ed46b06759\niv = 97438f178419732feaade58a5d5c21bed14d04c4add50465\nkey = b43328e39cc6f6e94ea601fbebadb4b41cfe6a52c3a4d5eeabaa9853db45ccb1\nmsg = 63cb5c20c9edf36757b795921437d3fd228af1fcdbb329505cbdde12afaf9f84\nresult = valid\ntag = dda7fc160e23f57e8392809f1e3b5ee8\n\n# tcId = 68\naad = \nct = 82be237be008228a8a9ff1a506d5b893cf9dcaa1dd33c0523b13582bcade4629ef\niv = daca1f50a4c0d9b77151c75f2e58ce404847d0aab493086d\nkey = 92b9b40c00480a50ee16a86349a46e37b02d5ba74d2e5a67eaf333e467fa0152\nmsg = c857f3c55da61d72563912a2534e01b6426ba41bf417c15b725086d31a1645c94d\nresult = valid\ntag = 723437af0b684b6e04024352206cbaf9\n\n# tcId = 69\naad = aaefd84240ade0ed\nct = ff98ead89d45d70f09b9e3f31f4ff56ae8b8cad1517294a8af3c962bad24a92efe\niv = ffcaddf85da09293c4352c81cbb5dd82e30b0f9e7623e92a\nkey = 5c271bac09a0454c83d158bcc9ec331ca92e62726903b7bb5799adff47d671ee\nmsg = 7c716a5b6cf0b8b0e1ff825ff9324bb5715b0d40af5338d5337f66de681932d423\nresult = valid\ntag = 4b8a06a1613737d0f8e3fb88184b23e4\n\n# tcId = 70\naad = \nct = d0e84c6450f348d887c49c4b44ac38721d4a1742e72095c330249c7348bade49dc776d449272e0f3dd5422c2a6ab18\niv = 64cc9f3cc334abce364cec9efe8ad54117ff0bbb03e3e8b9\nkey = c28403cce44ff256d055c2cbc84bb2d9773346e0d51bd38e80cebd861b03fa30\nmsg = f9e8f60b70044b03a189c26f1c8fd246239bc23f8adf0f88516f88d73d11c9290882bb6ad49d956b10c9f848180065\nresult = valid\ntag = 28c72dea441cffac2f7811286f8ea5dd\n\n# tcId = 71\naad = 7185f9cbf59d2095\nct = 4093dcbca1555835b78140fe7a3798a77bd97a01b0a7c1f7157fedb27c40d9d16cc3e935f649faf0dcf431636cd539\niv = 7b97c8b1c06b69b99220042ab2ac65b88d8b4294b76b4bd1\nkey = 7c72c748ea0010c90e1dfbde8e91edf6ead2474148cf234e0559dcd881cc3b2b\nmsg = 9a1f6c42a8a0f3032e8dfa36e0f5750479276866c920672a0454c41bfae5dd74fbf0fbcc8e6fbf4843f20d06440837\nresult = valid\ntag = c7c9133ff17a296c987d72885182874d\n\n# tcId = 72\naad = \nct = 764ab84b844b57b0564f63ec70ad12d81dc3a0e65233a9bf06d6b2c653787eb991bc37a885a04509690ab49fd8dedcabe3c346df9036d735de3bf73ab03f5ba7\niv = 8052acef0423bb07a6fbaf8f63039f1eaa2cdefc61b31b18\nkey = 7948151a374363d07dfb12869b7f90502f2de8117d3d72d5133b9b3e3dc78ef7\nmsg = 76e03034be5514561e99c32ab58901eabac0f67b40c366202ac8a08ee3f68c3b283c1adeefee6f5544330d4771e5148c5231ec27b3f3f9d81a3dca52e115e1b5\nresult = valid\ntag = 075248c91d1f246aebaa96c86627d18e\n\n# tcId = 73\naad = dc514d540551b9dc\nct = de03f775aee744e4148e008dfefa7156ce2a23a613d4d9cae99c3164f54a173f895a9466ef046c020179383d70c813e765f207860c79dcf627f17663ea76af20\niv = f357e3b3d3d5e4187e34da08afd4817635adde91b676da1d\nkey = 50a1b2b155150936609d45596e9175f3271be548574405f827593fc5a0578c3a\nmsg = e854b8531ace95c975a5b1497f3dec6d80b29ca673690411abe277bbfd29fa00133ee17570805c1c605452d648581be8db878e782f217b481b1268591593efc0\nresult = valid\ntag = b473a9f1d5312d556bd0b62d84bb0803\n\n# tcId = 74\naad = \nct = 98fc26e0cfd5a75b5bcd9e046e89c6e9dc5aaefdd5e8ea7e4d286dcdaca0fe6ae744d244678f91c9ccf6e294bd5586be671645ae87d3435836a5ab383b253602c25a6cc04353c076725b4fc4aff9b4dc9bd194fe92ef0a920f15d6b8fea9f19065\niv = 6d609141e3e4331f55344c1f5e6fad589b39ec1d12b9fbf0\nkey = 92570a01d2b6123b67055400c8a9b0cb948e32c9b8520758cd1abd73f83c8507\nmsg = e86fc97c194d37a5e1345d139fe82dd669b6350c435cb446fcbdcc90fe5859bb2ef1f69d930e29dc343b57dfd7ff3c382652939bbd1c978a790ed1dbe5ad1fcbe157925ab4335c649c2f80c19d541e9e7eb4feb64e596bc6d7df8aa3476e0a9f7e\nresult = valid\ntag = 03bb49593f116a30a8390f96380a9888\n\n# tcId = 75\naad = e40cb55a18f2885f\nct = 7042beb6e4f08e583752f23048e2f3433e0821423d72a7e531b86684b57b32c5bdcc11164db0b8516d7b463cf7f8b0e3ed8a7d584345934ef184e4f8fee31e126601f08558c725aaa23d38c8017b07adbf1e742128795b03458b581b8cd9100bd9\niv = 1a80def5bd8be8eef5f6643a5c1aed9947c3ee5ca0cb56df\nkey = 4a3bc8f5c4aab87c20772404a291c1d6d68eb12e5f3c82e582564d6300fc28c9\nmsg = 2b0815f7eb0a83b9617e4f0906e9179b600b0c822bfb56c5012103aecb4550a57099dcebae00b6c06f3537fb1550c78b249d00a4007d23b882cb5511fdd53482575554028e9db437b8224368ead730d157a64d5571c706cbd9c0d2b10b3b14c3e2\nresult = valid\ntag = b5e3df83f18cbc0bd99427b9a172bf1b\n\n# tcId = 76\naad = \nct = cf2e17f9d8c6562de6d3e8c8bc30ba2904cf5c3616d15ea77667186ee45f444ea264327dcf210b6735a39005b62529d557480ed0462e49d982cf5962e5ee6d8ccc388d5de102e676a55426ce5a873d2e84a2d841e7b30c7ab19035274886b3c5c979d065bdde9b0b9e466b22559e30a5a5abc4817312e15d2c0dcdd99d867361\niv = 3507ec4cd1a6c2eaf081ec32888e08839481f35b3b0f7872\nkey = 2e89767b15f18b855d04c0b6b47c1f8facc9a058e2194ad2ad901ef940ab54cb\nmsg = eff2e375228756f995b8ab52213177c4b7ca92bc81114f5c23aa64dd7eaff7b86ee2e674984c4b65bf4c5ff402e23902c005e05de25b3c6e8a64323aeafe04ec6cd1f6c851be39e55208d76476d3ed7100042eccb72cf1349ea101253b7a5a4a8677c1d6df5a54e9c24558e2d68c3f50acbd1ebbb4773884b0ff23d95a4ff60d\nresult = valid\ntag = c844d555bb43a83b4aa735b2aa1d566a\n\n# tcId = 77\naad = e2f0d2f16704527e\nct = 4f0e805a2b3f2e1bfe3c06c83f5c77b9c4e562514a78f9f2cbf3206f68f686923656885878087d17da261666e798649d74841753525875f425e82a4795fdf8dfb629a8b1d2faa5594557d62f421f4e6a5dbb9f8336875f2fe2e2a4a1d0084358d9583e6b6662895a07c924c0a7cdba07be8a020e1b8ef3a0b5d007ec47a8e8cf\niv = 0a5914f29abb1cb48dc686159f09480370477f6069018e18\nkey = 6357cd94e2d9503288eaf3abf9604b050d4a483350a828029baaa9cae184f075\nmsg = bb266ddea2f88c2f0fea7f0cf4a1a3336334", @@ -4467,522 +5105,684 @@ std::string GetTestData(const char *path) { if (strcmp(path, "crypto/cipher_extra/test/aes_128_ccm_bluetooth_8_tests.txt") == 0) { return AssembleString(kData4, kLen4); } - if (strcmp(path, "crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt") == 0) { return AssembleString(kData5, kLen5); } - if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_randnonce_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt") == 0) { return AssembleString(kData6, kLen6); } - if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_randnonce_tests.txt") == 0) { return AssembleString(kData7, kLen7); } - if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt") == 0) { return AssembleString(kData8, kLen8); } - if (strcmp(path, "crypto/cipher_extra/test/aes_192_gcm_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_128_gcm_tests.txt") == 0) { return AssembleString(kData9, kLen9); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_192_gcm_tests.txt") == 0) { return AssembleString(kData10, kLen10); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt") == 0) { return AssembleString(kData11, kLen11); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_ctr_hmac_sha256.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_cbc_sha1_tls_tests.txt") == 0) { return AssembleString(kData12, kLen12); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_randnonce_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_ctr_hmac_sha256.txt") == 0) { return AssembleString(kData13, kLen13); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_randnonce_tests.txt") == 0) { return AssembleString(kData14, kLen14); } - if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt") == 0) { return AssembleString(kData15, kLen15); } - if (strcmp(path, "crypto/cipher_extra/test/chacha20_poly1305_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/aes_256_gcm_tests.txt") == 0) { return AssembleString(kData16, kLen16); } - if (strcmp(path, "crypto/cipher_extra/test/xchacha20_poly1305_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/chacha20_poly1305_tests.txt") == 0) { return AssembleString(kData17, kLen17); } - if (strcmp(path, "crypto/cipher_extra/test/cipher_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/xchacha20_poly1305_tests.txt") == 0) { return AssembleString(kData18, kLen18); } - if (strcmp(path, "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/cipher_tests.txt") == 0) { return AssembleString(kData19, kLen19); } - if (strcmp(path, "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt") == 0) { return AssembleString(kData20, kLen20); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/des_ede3_cbc_sha1_tls_tests.txt") == 0) { return AssembleString(kData21, kLen21); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt") == 0) { return AssembleString(kData22, kLen22); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_gcm.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt") == 0) { return AssembleString(kData23, kLen23); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_128_gcm.txt") == 0) { return AssembleString(kData24, kLen24); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt") == 0) { return AssembleString(kData25, kLen25); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt") == 0) { return AssembleString(kData26, kLen26); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt") == 0) { return AssembleString(kData27, kLen27); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_gcm.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt") == 0) { return AssembleString(kData28, kLen28); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/aes_256_gcm.txt") == 0) { return AssembleString(kData29, kLen29); } - if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt") == 0) { return AssembleString(kData30, kLen30); } - if (strcmp(path, "crypto/curve25519/ed25519_tests.txt") == 0) { + if (strcmp(path, "crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt") == 0) { return AssembleString(kData31, kLen31); } - if (strcmp(path, "crypto/cmac/cavp_3des_cmac_tests.txt") == 0) { + if (strcmp(path, "crypto/curve25519/ed25519_tests.txt") == 0) { return AssembleString(kData32, kLen32); } - if (strcmp(path, "crypto/cmac/cavp_aes128_cmac_tests.txt") == 0) { + if (strcmp(path, "crypto/ecdh_extra/ecdh_tests.txt") == 0) { return AssembleString(kData33, kLen33); } - if (strcmp(path, "crypto/cmac/cavp_aes192_cmac_tests.txt") == 0) { + if (strcmp(path, "crypto/evp/evp_tests.txt") == 0) { return AssembleString(kData34, kLen34); } - if (strcmp(path, "crypto/cmac/cavp_aes256_cmac_tests.txt") == 0) { + if (strcmp(path, "crypto/evp/scrypt_tests.txt") == 0) { return AssembleString(kData35, kLen35); } - if (strcmp(path, "crypto/ecdh_extra/ecdh_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/aes/aes_tests.txt") == 0) { return AssembleString(kData36, kLen36); } - if (strcmp(path, "crypto/evp/evp_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/exp_tests.txt") == 0) { return AssembleString(kData37, kLen37); } - if (strcmp(path, "crypto/evp/scrypt_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/gcd_tests.txt") == 0) { return AssembleString(kData38, kLen38); } - if (strcmp(path, "crypto/fipsmodule/aes/aes_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/miller_rabin_tests.txt") == 0) { return AssembleString(kData39, kLen39); } - if (strcmp(path, "crypto/fipsmodule/bn/bn_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/mod_exp_tests.txt") == 0) { return AssembleString(kData40, kLen40); } - if (strcmp(path, "crypto/fipsmodule/bn/miller_rabin_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/mod_inv_tests.txt") == 0) { return AssembleString(kData41, kLen41); } - if (strcmp(path, "crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/mod_mul_tests.txt") == 0) { return AssembleString(kData42, kLen42); } - if (strcmp(path, "crypto/fipsmodule/ec/p256-x86_64_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/mod_sqrt_tests.txt") == 0) { return AssembleString(kData43, kLen43); } - if (strcmp(path, "crypto/fipsmodule/ecdsa/ecdsa_sign_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/product_tests.txt") == 0) { return AssembleString(kData44, kLen44); } - if (strcmp(path, "crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/quotient_tests.txt") == 0) { return AssembleString(kData45, kLen45); } - if (strcmp(path, "crypto/fipsmodule/modes/gcm_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/shift_tests.txt") == 0) { return AssembleString(kData46, kLen46); } - if (strcmp(path, "crypto/fipsmodule/rand/ctrdrbg_vectors.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/bn/test/sum_tests.txt") == 0) { return AssembleString(kData47, kLen47); } - if (strcmp(path, "crypto/hmac_extra/hmac_tests.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt") == 0) { return AssembleString(kData48, kLen48); } - if (strcmp(path, "crypto/hpke/hpke_test_vectors.txt") == 0) { + if (strcmp(path, "crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt") == 0) { return AssembleString(kData49, kLen49); } - if (strcmp(path, "crypto/pkcs8/test/empty_password.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt") == 0) { return AssembleString(kData50, kLen50); } - if (strcmp(path, "crypto/pkcs8/test/no_encryption.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt") == 0) { return AssembleString(kData51, kLen51); } - if (strcmp(path, "crypto/pkcs8/test/nss.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt") == 0) { return AssembleString(kData52, kLen52); } - if (strcmp(path, "crypto/pkcs8/test/null_password.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/ec/p256-nistz_tests.txt") == 0) { return AssembleString(kData53, kLen53); } - if (strcmp(path, "crypto/pkcs8/test/openssl.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/ecdsa/ecdsa_sign_tests.txt") == 0) { return AssembleString(kData54, kLen54); } - if (strcmp(path, "crypto/pkcs8/test/pbes2_sha1.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt") == 0) { return AssembleString(kData55, kLen55); } - if (strcmp(path, "crypto/pkcs8/test/pbes2_sha256.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/modes/gcm_tests.txt") == 0) { return AssembleString(kData56, kLen56); } - if (strcmp(path, "crypto/pkcs8/test/unicode_password.p12") == 0) { + if (strcmp(path, "crypto/fipsmodule/rand/ctrdrbg_vectors.txt") == 0) { return AssembleString(kData57, kLen57); } - if (strcmp(path, "crypto/pkcs8/test/windows.p12") == 0) { + if (strcmp(path, "crypto/hmac_extra/hmac_tests.txt") == 0) { return AssembleString(kData58, kLen58); } - if (strcmp(path, "crypto/poly1305/poly1305_tests.txt") == 0) { + if (strcmp(path, "crypto/hpke/hpke_test_vectors.txt") == 0) { return AssembleString(kData59, kLen59); } - if (strcmp(path, "crypto/siphash/siphash_tests.txt") == 0) { + if (strcmp(path, "crypto/kyber/keccak_tests.txt") == 0) { return AssembleString(kData60, kLen60); } - if (strcmp(path, "crypto/x509/test/basic_constraints_ca.pem") == 0) { + if (strcmp(path, "crypto/kyber/kyber_tests.txt") == 0) { return AssembleString(kData61, kLen61); } - if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_0.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/empty_password.p12") == 0) { return AssembleString(kData62, kLen62); } - if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_1.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/no_encryption.p12") == 0) { return AssembleString(kData63, kLen63); } - if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_10.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/nss.p12") == 0) { return AssembleString(kData64, kLen64); } - if (strcmp(path, "crypto/x509/test/basic_constraints_leaf.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/null_password.p12") == 0) { return AssembleString(kData65, kLen65); } - if (strcmp(path, "crypto/x509/test/basic_constraints_none.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/openssl.p12") == 0) { return AssembleString(kData66, kLen66); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/pbes2_sha1.p12") == 0) { return AssembleString(kData67, kLen67); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_authority_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/pbes2_sha256.p12") == 0) { return AssembleString(kData68, kLen68); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_basic_constraints.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/unicode_password.p12") == 0) { return AssembleString(kData69, kLen69); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_ext_key_usage.pem") == 0) { + if (strcmp(path, "crypto/pkcs8/test/windows.p12") == 0) { return AssembleString(kData70, kLen70); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_key_usage.pem") == 0) { + if (strcmp(path, "crypto/poly1305/poly1305_tests.txt") == 0) { return AssembleString(kData71, kLen71); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_name_constraints.pem") == 0) { + if (strcmp(path, "crypto/siphash/siphash_tests.txt") == 0) { return AssembleString(kData72, kLen72); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_subject_alt_name.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_ca.pem") == 0) { return AssembleString(kData73, kLen73); } - if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_subject_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_0.pem") == 0) { return AssembleString(kData74, kLen74); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_1.pem") == 0) { return AssembleString(kData75, kLen75); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_authority_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_ca_pathlen_10.pem") == 0) { return AssembleString(kData76, kLen76); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_basic_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_leaf.pem") == 0) { return AssembleString(kData77, kLen77); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_ext_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/basic_constraints_none.pem") == 0) { return AssembleString(kData78, kLen78); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate.pem") == 0) { return AssembleString(kData79, kLen79); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_name_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_authority_key_identifier.pem") == 0) { return AssembleString(kData80, kLen80); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_subject_alt_name.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_basic_constraints.pem") == 0) { return AssembleString(kData81, kLen81); } - if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_subject_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_ext_key_usage.pem") == 0) { return AssembleString(kData82, kLen82); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_key_usage.pem") == 0) { return AssembleString(kData83, kLen83); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_authority_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_name_constraints.pem") == 0) { return AssembleString(kData84, kLen84); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_basic_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_subject_alt_name.pem") == 0) { return AssembleString(kData85, kLen85); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_ext_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_intermediate_subject_key_identifier.pem") == 0) { return AssembleString(kData86, kLen86); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf.pem") == 0) { return AssembleString(kData87, kLen87); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_name_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_authority_key_identifier.pem") == 0) { return AssembleString(kData88, kLen88); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_subject_alt_name.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_basic_constraints.pem") == 0) { return AssembleString(kData89, kLen89); } - if (strcmp(path, "crypto/x509/test/invalid_extension_root_subject_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_ext_key_usage.pem") == 0) { return AssembleString(kData90, kLen90); } - if (strcmp(path, "crypto/x509/test/many_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_key_usage.pem") == 0) { return AssembleString(kData91, kLen91); } - if (strcmp(path, "crypto/x509/test/many_names1.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_name_constraints.pem") == 0) { return AssembleString(kData92, kLen92); } - if (strcmp(path, "crypto/x509/test/many_names2.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_subject_alt_name.pem") == 0) { return AssembleString(kData93, kLen93); } - if (strcmp(path, "crypto/x509/test/many_names3.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_leaf_subject_key_identifier.pem") == 0) { return AssembleString(kData94, kLen94); } - if (strcmp(path, "crypto/x509/test/some_names1.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root.pem") == 0) { return AssembleString(kData95, kLen95); } - if (strcmp(path, "crypto/x509/test/some_names2.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_authority_key_identifier.pem") == 0) { return AssembleString(kData96, kLen96); } - if (strcmp(path, "crypto/x509/test/some_names3.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_basic_constraints.pem") == 0) { return AssembleString(kData97, kLen97); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_authority_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_ext_key_usage.pem") == 0) { return AssembleString(kData98, kLen98); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_basic_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_key_usage.pem") == 0) { return AssembleString(kData99, kLen99); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_ext_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_name_constraints.pem") == 0) { return AssembleString(kData100, kLen100); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_key_usage.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_subject_alt_name.pem") == 0) { return AssembleString(kData101, kLen101); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_name_constraints.pem") == 0) { + if (strcmp(path, "crypto/x509/test/invalid_extension_root_subject_key_identifier.pem") == 0) { return AssembleString(kData102, kLen102); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_subject_alt_name.pem") == 0) { + if (strcmp(path, "crypto/x509/test/many_constraints.pem") == 0) { return AssembleString(kData103, kLen103); } - if (strcmp(path, "crypto/x509/test/trailing_data_leaf_subject_key_identifier.pem") == 0) { + if (strcmp(path, "crypto/x509/test/many_names1.pem") == 0) { return AssembleString(kData104, kLen104); } - if (strcmp(path, "third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/many_names2.pem") == 0) { return AssembleString(kData105, kLen105); } - if (strcmp(path, "third_party/wycheproof_testvectors/aes_cmac_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/many_names3.pem") == 0) { return AssembleString(kData106, kLen106); } - if (strcmp(path, "third_party/wycheproof_testvectors/aes_gcm_siv_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_any.pem") == 0) { return AssembleString(kData107, kLen107); } - if (strcmp(path, "third_party/wycheproof_testvectors/aes_gcm_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_duplicate.pem") == 0) { return AssembleString(kData108, kLen108); } - if (strcmp(path, "third_party/wycheproof_testvectors/chacha20_poly1305_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_invalid.pem") == 0) { return AssembleString(kData109, kLen109); } - if (strcmp(path, "third_party/wycheproof_testvectors/dsa_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_mapped_any.pem") == 0) { return AssembleString(kData110, kLen110); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp224r1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_mapped_oid3.pem") == 0) { return AssembleString(kData111, kLen111); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp256r1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_mapped.pem") == 0) { return AssembleString(kData112, kLen112); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp384r1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_require_duplicate.pem") == 0) { return AssembleString(kData113, kLen113); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp521r1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_require_no_policies.pem") == 0) { return AssembleString(kData114, kLen114); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_require.pem") == 0) { return AssembleString(kData115, kLen115); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_require1.pem") == 0) { return AssembleString(kData116, kLen116); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate_require2.pem") == 0) { return AssembleString(kData117, kLen117); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_intermediate.pem") == 0) { return AssembleString(kData118, kLen118); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_any.pem") == 0) { return AssembleString(kData119, kLen119); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_duplicate.pem") == 0) { return AssembleString(kData120, kLen120); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_invalid.pem") == 0) { return AssembleString(kData121, kLen121); } - if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_none.pem") == 0) { return AssembleString(kData122, kLen122); } - if (strcmp(path, "third_party/wycheproof_testvectors/eddsa_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_oid1.pem") == 0) { return AssembleString(kData123, kLen123); } - if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_oid2.pem") == 0) { return AssembleString(kData124, kLen124); } - if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_oid3.pem") == 0) { return AssembleString(kData125, kLen125); } - if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha384_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_oid4.pem") == 0) { return AssembleString(kData126, kLen126); } - if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_oid5.pem") == 0) { return AssembleString(kData127, kLen127); } - if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_require.pem") == 0) { return AssembleString(kData128, kLen128); } - if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha224_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf_require1.pem") == 0) { return AssembleString(kData129, kLen129); } - if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_leaf.pem") == 0) { return AssembleString(kData130, kLen130); } - if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha384_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_root_cross_inhibit_mapping.pem") == 0) { return AssembleString(kData131, kLen131); } - if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_root.pem") == 0) { return AssembleString(kData132, kLen132); } - if (strcmp(path, "third_party/wycheproof_testvectors/kwp_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/policy_root2.pem") == 0) { return AssembleString(kData133, kLen133); } - if (strcmp(path, "third_party/wycheproof_testvectors/kw_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha1_explicit.pem") == 0) { return AssembleString(kData134, kLen134); } - if (strcmp(path, "third_party/wycheproof_testvectors/primality_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha1_mgf1_syntax_error.pem") == 0) { return AssembleString(kData135, kLen135); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha1_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha1.pem") == 0) { return AssembleString(kData136, kLen136); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha224_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha224.pem") == 0) { return AssembleString(kData137, kLen137); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha224_mgf1sha224_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_explicit_trailer.pem") == 0) { return AssembleString(kData138, kLen138); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha256_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_mgf1_sha384.pem") == 0) { return AssembleString(kData139, kLen139); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha256_mgf1sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_mgf1_syntax_error.pem") == 0) { return AssembleString(kData140, kLen140); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha384_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_omit_nulls.pem") == 0) { return AssembleString(kData141, kLen141); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha384_mgf1sha384_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_salt_overflow.pem") == 0) { return AssembleString(kData142, kLen142); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha512_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_salt31.pem") == 0) { return AssembleString(kData143, kLen143); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha512_mgf1sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_unknown_mgf.pem") == 0) { return AssembleString(kData144, kLen144); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha256_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256_wrong_trailer.pem") == 0) { return AssembleString(kData145, kLen145); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha256_mgf1sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha256.pem") == 0) { return AssembleString(kData146, kLen146); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha512_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha384.pem") == 0) { return AssembleString(kData147, kLen147); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha512_mgf1sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/pss_sha512.pem") == 0) { return AssembleString(kData148, kLen148); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha256_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/some_names1.pem") == 0) { return AssembleString(kData149, kLen149); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha256_mgf1sha256_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/some_names2.pem") == 0) { return AssembleString(kData150, kLen150); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha512_mgf1sha1_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/some_names3.pem") == 0) { return AssembleString(kData151, kLen151); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha512_mgf1sha512_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_authority_key_identifier.pem") == 0) { return AssembleString(kData152, kLen152); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_basic_constraints.pem") == 0) { return AssembleString(kData153, kLen153); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_ext_key_usage.pem") == 0) { return AssembleString(kData154, kLen154); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_key_usage.pem") == 0) { return AssembleString(kData155, kLen155); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_name_constraints.pem") == 0) { return AssembleString(kData156, kLen156); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_subject_alt_name.pem") == 0) { return AssembleString(kData157, kLen157); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt") == 0) { + if (strcmp(path, "crypto/x509/test/trailing_data_leaf_subject_key_identifier.pem") == 0) { return AssembleString(kData158, kLen158); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_32_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt") == 0) { return AssembleString(kData159, kLen159); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_3072_sha256_mgf1_32_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/aes_cmac_test.txt") == 0) { return AssembleString(kData160, kLen160); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_4096_sha256_mgf1_32_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/aes_gcm_siv_test.txt") == 0) { return AssembleString(kData161, kLen161); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_4096_sha512_mgf1_32_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/aes_gcm_test.txt") == 0) { return AssembleString(kData162, kLen162); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/chacha20_poly1305_test.txt") == 0) { return AssembleString(kData163, kLen163); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_sig_gen_misc_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/dsa_test.txt") == 0) { return AssembleString(kData164, kLen164); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp224r1_test.txt") == 0) { return AssembleString(kData165, kLen165); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp256r1_test.txt") == 0) { return AssembleString(kData166, kLen166); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp384r1_test.txt") == 0) { return AssembleString(kData167, kLen167); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdh_secp521r1_test.txt") == 0) { return AssembleString(kData168, kLen168); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha224_test.txt") == 0) { return AssembleString(kData169, kLen169); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha256_test.txt") == 0) { return AssembleString(kData170, kLen170); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp224r1_sha512_test.txt") == 0) { return AssembleString(kData171, kLen171); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha256_test.txt") == 0) { return AssembleString(kData172, kLen172); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp256r1_sha512_test.txt") == 0) { return AssembleString(kData173, kLen173); } - if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha384_test.txt") == 0) { return AssembleString(kData174, kLen174); } - if (strcmp(path, "third_party/wycheproof_testvectors/x25519_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp384r1_sha512_test.txt") == 0) { return AssembleString(kData175, kLen175); } - if (strcmp(path, "third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt") == 0) { + if (strcmp(path, "third_party/wycheproof_testvectors/ecdsa_secp521r1_sha512_test.txt") == 0) { return AssembleString(kData176, kLen176); } + if (strcmp(path, "third_party/wycheproof_testvectors/eddsa_test.txt") == 0) { + return AssembleString(kData177, kLen177); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha1_test.txt") == 0) { + return AssembleString(kData178, kLen178); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha256_test.txt") == 0) { + return AssembleString(kData179, kLen179); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha384_test.txt") == 0) { + return AssembleString(kData180, kLen180); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hkdf_sha512_test.txt") == 0) { + return AssembleString(kData181, kLen181); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha1_test.txt") == 0) { + return AssembleString(kData182, kLen182); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha224_test.txt") == 0) { + return AssembleString(kData183, kLen183); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha256_test.txt") == 0) { + return AssembleString(kData184, kLen184); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha384_test.txt") == 0) { + return AssembleString(kData185, kLen185); + } + if (strcmp(path, "third_party/wycheproof_testvectors/hmac_sha512_test.txt") == 0) { + return AssembleString(kData186, kLen186); + } + if (strcmp(path, "third_party/wycheproof_testvectors/kwp_test.txt") == 0) { + return AssembleString(kData187, kLen187); + } + if (strcmp(path, "third_party/wycheproof_testvectors/kw_test.txt") == 0) { + return AssembleString(kData188, kLen188); + } + if (strcmp(path, "third_party/wycheproof_testvectors/primality_test.txt") == 0) { + return AssembleString(kData189, kLen189); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha1_mgf1sha1_test.txt") == 0) { + return AssembleString(kData190, kLen190); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha224_mgf1sha1_test.txt") == 0) { + return AssembleString(kData191, kLen191); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha224_mgf1sha224_test.txt") == 0) { + return AssembleString(kData192, kLen192); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha256_mgf1sha1_test.txt") == 0) { + return AssembleString(kData193, kLen193); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha256_mgf1sha256_test.txt") == 0) { + return AssembleString(kData194, kLen194); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha384_mgf1sha1_test.txt") == 0) { + return AssembleString(kData195, kLen195); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha384_mgf1sha384_test.txt") == 0) { + return AssembleString(kData196, kLen196); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha512_mgf1sha1_test.txt") == 0) { + return AssembleString(kData197, kLen197); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_2048_sha512_mgf1sha512_test.txt") == 0) { + return AssembleString(kData198, kLen198); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha256_mgf1sha1_test.txt") == 0) { + return AssembleString(kData199, kLen199); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha256_mgf1sha256_test.txt") == 0) { + return AssembleString(kData200, kLen200); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha512_mgf1sha1_test.txt") == 0) { + return AssembleString(kData201, kLen201); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_3072_sha512_mgf1sha512_test.txt") == 0) { + return AssembleString(kData202, kLen202); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha256_mgf1sha1_test.txt") == 0) { + return AssembleString(kData203, kLen203); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha256_mgf1sha256_test.txt") == 0) { + return AssembleString(kData204, kLen204); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha512_mgf1sha1_test.txt") == 0) { + return AssembleString(kData205, kLen205); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_4096_sha512_mgf1sha512_test.txt") == 0) { + return AssembleString(kData206, kLen206); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_oaep_misc_test.txt") == 0) { + return AssembleString(kData207, kLen207); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_2048_test.txt") == 0) { + return AssembleString(kData208, kLen208); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_3072_test.txt") == 0) { + return AssembleString(kData209, kLen209); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pkcs1_4096_test.txt") == 0) { + return AssembleString(kData210, kLen210); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha1_mgf1_20_test.txt") == 0) { + return AssembleString(kData211, kLen211); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_0_test.txt") == 0) { + return AssembleString(kData212, kLen212); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_2048_sha256_mgf1_32_test.txt") == 0) { + return AssembleString(kData213, kLen213); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_3072_sha256_mgf1_32_test.txt") == 0) { + return AssembleString(kData214, kLen214); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_4096_sha256_mgf1_32_test.txt") == 0) { + return AssembleString(kData215, kLen215); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_4096_sha512_mgf1_32_test.txt") == 0) { + return AssembleString(kData216, kLen216); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_pss_misc_test.txt") == 0) { + return AssembleString(kData217, kLen217); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_sig_gen_misc_test.txt") == 0) { + return AssembleString(kData218, kLen218); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha224_test.txt") == 0) { + return AssembleString(kData219, kLen219); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha256_test.txt") == 0) { + return AssembleString(kData220, kLen220); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha384_test.txt") == 0) { + return AssembleString(kData221, kLen221); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_2048_sha512_test.txt") == 0) { + return AssembleString(kData222, kLen222); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha256_test.txt") == 0) { + return AssembleString(kData223, kLen223); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha384_test.txt") == 0) { + return AssembleString(kData224, kLen224); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_3072_sha512_test.txt") == 0) { + return AssembleString(kData225, kLen225); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_4096_sha384_test.txt") == 0) { + return AssembleString(kData226, kLen226); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_4096_sha512_test.txt") == 0) { + return AssembleString(kData227, kLen227); + } + if (strcmp(path, "third_party/wycheproof_testvectors/rsa_signature_test.txt") == 0) { + return AssembleString(kData228, kLen228); + } + if (strcmp(path, "third_party/wycheproof_testvectors/x25519_test.txt") == 0) { + return AssembleString(kData229, kLen229); + } + if (strcmp(path, "third_party/wycheproof_testvectors/xchacha20_poly1305_test.txt") == 0) { + return AssembleString(kData230, kLen230); + } fprintf(stderr, "File not embedded: %s.\n", path); abort(); } diff --git a/third_party/boringssl/kit/err_data.c b/third_party/boringssl/kit/err_data.c index 98bc22a4..0243a7e7 100644 --- a/third_party/boringssl/kit/err_data.c +++ b/third_party/boringssl/kit/err_data.c @@ -16,224 +16,229 @@ #include #include -#include +#include -OPENSSL_STATIC_ASSERT(ERR_LIB_NONE == 1, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_SYS == 2, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_BN == 3, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_RSA == 4, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_DH == 5, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_EVP == 6, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_BUF == 7, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_OBJ == 8, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_PEM == 9, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_DSA == 10, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_X509 == 11, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_ASN1 == 12, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_CONF == 13, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_CRYPTO == 14, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_EC == 15, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_SSL == 16, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_BIO == 17, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS7 == 18, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS8 == 19, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_X509V3 == 20, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_RAND == 21, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_ENGINE == 22, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_OCSP == 23, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_UI == 24, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_COMP == 25, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_ECDSA == 26, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_ECDH == 27, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_HMAC == 28, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_DIGEST == 29, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_CIPHER == 30, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_HKDF == 31, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_TRUST_TOKEN == 32, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_LIB_USER == 33, "library value changed"); -OPENSSL_STATIC_ASSERT(ERR_NUM_LIBS == 34, "number of libraries changed"); +static_assert(ERR_LIB_NONE == 1, "library value changed"); +static_assert(ERR_LIB_SYS == 2, "library value changed"); +static_assert(ERR_LIB_BN == 3, "library value changed"); +static_assert(ERR_LIB_RSA == 4, "library value changed"); +static_assert(ERR_LIB_DH == 5, "library value changed"); +static_assert(ERR_LIB_EVP == 6, "library value changed"); +static_assert(ERR_LIB_BUF == 7, "library value changed"); +static_assert(ERR_LIB_OBJ == 8, "library value changed"); +static_assert(ERR_LIB_PEM == 9, "library value changed"); +static_assert(ERR_LIB_DSA == 10, "library value changed"); +static_assert(ERR_LIB_X509 == 11, "library value changed"); +static_assert(ERR_LIB_ASN1 == 12, "library value changed"); +static_assert(ERR_LIB_CONF == 13, "library value changed"); +static_assert(ERR_LIB_CRYPTO == 14, "library value changed"); +static_assert(ERR_LIB_EC == 15, "library value changed"); +static_assert(ERR_LIB_SSL == 16, "library value changed"); +static_assert(ERR_LIB_BIO == 17, "library value changed"); +static_assert(ERR_LIB_PKCS7 == 18, "library value changed"); +static_assert(ERR_LIB_PKCS8 == 19, "library value changed"); +static_assert(ERR_LIB_X509V3 == 20, "library value changed"); +static_assert(ERR_LIB_RAND == 21, "library value changed"); +static_assert(ERR_LIB_ENGINE == 22, "library value changed"); +static_assert(ERR_LIB_OCSP == 23, "library value changed"); +static_assert(ERR_LIB_UI == 24, "library value changed"); +static_assert(ERR_LIB_COMP == 25, "library value changed"); +static_assert(ERR_LIB_ECDSA == 26, "library value changed"); +static_assert(ERR_LIB_ECDH == 27, "library value changed"); +static_assert(ERR_LIB_HMAC == 28, "library value changed"); +static_assert(ERR_LIB_DIGEST == 29, "library value changed"); +static_assert(ERR_LIB_CIPHER == 30, "library value changed"); +static_assert(ERR_LIB_HKDF == 31, "library value changed"); +static_assert(ERR_LIB_TRUST_TOKEN == 32, "library value changed"); +static_assert(ERR_LIB_USER == 33, "library value changed"); +static_assert(ERR_NUM_LIBS == 34, "number of libraries changed"); const uint32_t kOpenSSLReasonValues[] = { - 0xc320862, - 0xc32887c, - 0xc33088b, - 0xc33889b, - 0xc3408aa, - 0xc3488c3, - 0xc3508cf, - 0xc3588ec, - 0xc36090c, - 0xc36891a, - 0xc37092a, - 0xc378937, - 0xc380947, - 0xc388952, - 0xc390968, - 0xc398977, - 0xc3a098b, - 0xc3a886f, + 0xc320885, + 0xc32889f, + 0xc3308ae, + 0xc3388be, + 0xc3408cd, + 0xc3488e6, + 0xc3508f2, + 0xc35890f, + 0xc36092f, + 0xc36893d, + 0xc37094d, + 0xc37895a, + 0xc38096a, + 0xc388975, + 0xc39098b, + 0xc39899a, + 0xc3a09ae, + 0xc3a8892, 0xc3b00f7, - 0xc3b88fe, - 0x1032086f, - 0x103295e5, - 0x103315f1, - 0x1033960a, - 0x1034161d, - 0x10348f4f, - 0x10350c88, - 0x10359630, - 0x1036165a, - 0x1036966d, - 0x1037168c, - 0x103796a5, - 0x103816ba, - 0x103896d8, - 0x103916e7, - 0x10399703, - 0x103a171e, - 0x103a972d, - 0x103b1749, - 0x103b9764, - 0x103c178a, + 0xc3b8921, + 0x10320892, + 0x10329641, + 0x1033164d, + 0x10339666, + 0x10341679, + 0x10348f93, + 0x10350ccc, + 0x1035968c, + 0x103616b6, + 0x103696c9, + 0x103716e8, + 0x10379701, + 0x10381716, + 0x10389734, + 0x10391743, + 0x1039975f, + 0x103a177a, + 0x103a9789, + 0x103b17a5, + 0x103b97c0, + 0x103c17e6, 0x103c80f7, - 0x103d179b, - 0x103d97af, - 0x103e17ce, - 0x103e97dd, - 0x103f17f4, - 0x103f9807, - 0x10400c4c, - 0x1040981a, - 0x10411838, - 0x1041984b, - 0x10421865, - 0x10429875, - 0x10431889, - 0x1043989f, - 0x104418b7, - 0x104498cc, - 0x104518e0, - 0x104598f2, - 0x10460625, - 0x10468977, - 0x10471907, - 0x1047991e, - 0x10481933, - 0x10489941, - 0x10490e9b, - 0x1049977b, - 0x104a1645, - 0x14320c2f, - 0x14328c3d, - 0x14330c4c, - 0x14338c5e, + 0x103d17f7, + 0x103d980b, + 0x103e182a, + 0x103e9839, + 0x103f1850, + 0x103f9863, + 0x10400c90, + 0x10409876, + 0x10411894, + 0x104198a7, + 0x104218c1, + 0x104298d1, + 0x104318e5, + 0x104398fb, + 0x10441913, + 0x10449928, + 0x1045193c, + 0x1045994e, + 0x10460635, + 0x1046899a, + 0x10471963, + 0x1047997a, + 0x1048198f, + 0x1048999d, + 0x10490edf, + 0x104997d7, + 0x104a16a1, + 0x14320c73, + 0x14328c81, + 0x14330c90, + 0x14338ca2, 0x143400b9, 0x143480f7, 0x18320090, - 0x18328fa5, + 0x18328fe9, 0x183300b9, - 0x18338fbb, - 0x18340fcf, + 0x18338fff, + 0x18341013, 0x183480f7, - 0x18350fee, - 0x18359006, - 0x1836101b, - 0x1836902f, - 0x18371067, - 0x1837907d, - 0x18381091, - 0x183890a1, - 0x18390a9d, - 0x183990b1, - 0x183a10d7, - 0x183a90fd, - 0x183b0ca7, - 0x183b914c, - 0x183c115e, - 0x183c9169, - 0x183d1179, - 0x183d918a, - 0x183e119b, - 0x183e91ad, - 0x183f11d6, - 0x183f91ef, - 0x18401207, - 0x184086fd, - 0x18411120, - 0x184190eb, - 0x1842110a, - 0x18428c94, - 0x184310c6, - 0x18439132, - 0x18440fe4, - 0x18449053, - 0x20321241, - 0x2032922e, - 0x2432124d, - 0x243289bd, - 0x2433125f, - 0x2433926c, - 0x24341279, - 0x2434928b, - 0x2435129a, - 0x243592b7, - 0x243612c4, - 0x243692d2, - 0x243712e0, - 0x243792ee, - 0x243812f7, - 0x24389304, - 0x24391317, - 0x28320c7c, - 0x28328ca7, - 0x28330c4c, - 0x28338cba, - 0x28340c88, + 0x18351032, + 0x1835904a, + 0x1836105f, + 0x18369073, + 0x183710ab, + 0x183790c1, + 0x183810d5, + 0x183890e5, + 0x18390ac0, + 0x183990f5, + 0x183a111b, + 0x183a9141, + 0x183b0ceb, + 0x183b9190, + 0x183c11a2, + 0x183c91ad, + 0x183d11bd, + 0x183d91ce, + 0x183e11df, + 0x183e91f1, + 0x183f121a, + 0x183f9233, + 0x1840124b, + 0x1840870d, + 0x18411164, + 0x1841912f, + 0x1842114e, + 0x18428cd8, + 0x1843110a, + 0x18439176, + 0x18441028, + 0x18449097, + 0x20321285, + 0x20329272, + 0x24321291, + 0x243289e0, + 0x243312a3, + 0x243392b0, + 0x243412bd, + 0x243492cf, + 0x243512de, + 0x243592fb, + 0x24361308, + 0x24369316, + 0x24371324, + 0x24379332, + 0x2438133b, + 0x24389348, + 0x2439135b, + 0x28320cc0, + 0x28328ceb, + 0x28330c90, + 0x28338cfe, + 0x28340ccc, 0x283480b9, 0x283500f7, - 0x28358c94, - 0x2c323286, - 0x2c32932e, - 0x2c333294, - 0x2c33b2a6, - 0x2c3432ba, - 0x2c34b2cc, - 0x2c3532e7, - 0x2c35b2f9, - 0x2c363329, + 0x28358cd8, + 0x2836099a, + 0x2c3232e0, + 0x2c329372, + 0x2c3332ee, + 0x2c33b300, + 0x2c343314, + 0x2c34b326, + 0x2c353341, + 0x2c35b353, + 0x2c363383, 0x2c36833a, - 0x2c373336, - 0x2c37b362, - 0x2c383387, - 0x2c38b39e, - 0x2c3933bc, - 0x2c39b3cc, - 0x2c3a33de, - 0x2c3ab3f2, - 0x2c3b3403, - 0x2c3bb422, - 0x2c3c1340, - 0x2c3c9356, - 0x2c3d3436, - 0x2c3d936f, - 0x2c3e3453, - 0x2c3eb461, - 0x2c3f3479, - 0x2c3fb491, - 0x2c4034bb, - 0x2c409241, - 0x2c4134cc, - 0x2c41b4df, - 0x2c421207, - 0x2c42b4f0, - 0x2c43074a, - 0x2c43b414, - 0x2c443375, - 0x2c44b49e, - 0x2c45330c, - 0x2c45b348, - 0x2c4633ac, + 0x2c373390, + 0x2c37b3bc, + 0x2c3833fa, + 0x2c38b411, + 0x2c39342f, + 0x2c39b43f, + 0x2c3a3451, + 0x2c3ab465, + 0x2c3b3476, + 0x2c3bb495, + 0x2c3c1384, + 0x2c3c939a, + 0x2c3d34da, + 0x2c3d93b3, + 0x2c3e3504, + 0x2c3eb512, + 0x2c3f352a, + 0x2c3fb542, + 0x2c40356c, + 0x2c409285, + 0x2c41357d, + 0x2c41b590, + 0x2c42124b, + 0x2c42b5a1, + 0x2c43076d, + 0x2c43b487, + 0x2c4433cf, + 0x2c44b54f, + 0x2c453366, + 0x2c45b3a2, + 0x2c46341f, + 0x2c46b4a9, + 0x2c4734be, + 0x2c47b4f7, + 0x2c4833e1, 0x30320000, 0x30328015, 0x3033001f, @@ -278,528 +283,533 @@ const uint32_t kOpenSSLReasonValues[] = { 0x3046833a, 0x30470372, 0x30478384, - 0x30480392, - 0x304883a3, - 0x304903b2, - 0x304983ca, - 0x304a03dc, - 0x304a83f0, - 0x304b0408, - 0x304b841b, - 0x304c0426, - 0x304c8437, - 0x304d0443, - 0x304d8459, - 0x304e0467, - 0x304e847d, - 0x304f048f, - 0x304f84a1, - 0x305004c4, - 0x305084d7, - 0x305104e8, - 0x305184f8, - 0x30520510, - 0x30528525, - 0x3053053d, - 0x30538551, - 0x30540569, - 0x30548582, - 0x3055059b, - 0x305585b8, - 0x305605c3, - 0x305685db, - 0x305705eb, - 0x305785fc, - 0x3058060f, - 0x30588625, - 0x3059062e, - 0x30598643, - 0x305a0656, - 0x305a8665, - 0x305b0685, - 0x305b8694, - 0x305c06b5, - 0x305c86d1, - 0x305d06dd, - 0x305d86fd, - 0x305e0719, - 0x305e872a, - 0x305f0740, - 0x305f874a, - 0x306004b4, + 0x304803a2, + 0x304883b3, + 0x304903c2, + 0x304983da, + 0x304a03ec, + 0x304a8400, + 0x304b0418, + 0x304b842b, + 0x304c0436, + 0x304c8447, + 0x304d0453, + 0x304d8469, + 0x304e0477, + 0x304e848d, + 0x304f049f, + 0x304f84b1, + 0x305004d4, + 0x305084e7, + 0x305104f8, + 0x30518508, + 0x30520520, + 0x30528535, + 0x3053054d, + 0x30538561, + 0x30540579, + 0x30548592, + 0x305505ab, + 0x305585c8, + 0x305605d3, + 0x305685eb, + 0x305705fb, + 0x3057860c, + 0x3058061f, + 0x30588635, + 0x3059063e, + 0x30598653, + 0x305a0666, + 0x305a8675, + 0x305b0695, + 0x305b86a4, + 0x305c06c5, + 0x305c86e1, + 0x305d06ed, + 0x305d870d, + 0x305e0729, + 0x305e874d, + 0x305f0763, + 0x305f876d, + 0x306004c4, 0x3060804a, 0x30610357, - 0x34320b8d, - 0x34328ba1, - 0x34330bbe, - 0x34338bd1, - 0x34340be0, - 0x34348c19, - 0x34350bfd, + 0x3061873a, + 0x30620392, + 0x34320bb0, + 0x34328bc4, + 0x34330be1, + 0x34338bf4, + 0x34340c03, + 0x34348c5d, + 0x34350c41, + 0x34358c20, 0x3c320090, - 0x3c328ce4, - 0x3c330cfd, - 0x3c338d18, - 0x3c340d35, - 0x3c348d5f, - 0x3c350d7a, - 0x3c358da0, - 0x3c360db9, - 0x3c368dd1, - 0x3c370de2, - 0x3c378df0, - 0x3c380dfd, - 0x3c388e11, - 0x3c390ca7, - 0x3c398e34, - 0x3c3a0e48, - 0x3c3a8937, - 0x3c3b0e58, - 0x3c3b8e73, - 0x3c3c0e85, - 0x3c3c8eb8, - 0x3c3d0ec2, - 0x3c3d8ed6, - 0x3c3e0ee4, - 0x3c3e8f09, - 0x3c3f0cd0, - 0x3c3f8ef2, + 0x3c328d28, + 0x3c330d41, + 0x3c338d5c, + 0x3c340d79, + 0x3c348da3, + 0x3c350dbe, + 0x3c358de4, + 0x3c360dfd, + 0x3c368e15, + 0x3c370e26, + 0x3c378e34, + 0x3c380e41, + 0x3c388e55, + 0x3c390ceb, + 0x3c398e78, + 0x3c3a0e8c, + 0x3c3a895a, + 0x3c3b0e9c, + 0x3c3b8eb7, + 0x3c3c0ec9, + 0x3c3c8efc, + 0x3c3d0f06, + 0x3c3d8f1a, + 0x3c3e0f28, + 0x3c3e8f4d, + 0x3c3f0d14, + 0x3c3f8f36, 0x3c4000b9, 0x3c4080f7, - 0x3c410d50, - 0x3c418d8f, - 0x3c420e9b, - 0x3c428e25, - 0x403219d3, - 0x403299e9, - 0x40331a17, - 0x40339a21, - 0x40341a38, - 0x40349a56, - 0x40351a66, - 0x40359a78, - 0x40361a85, - 0x40369a91, - 0x40371aa6, - 0x40379ab8, - 0x40381ac3, - 0x40389ad5, - 0x40390f4f, - 0x40399ae5, - 0x403a1af8, - 0x403a9b19, - 0x403b1b2a, - 0x403b9b3a, + 0x3c410d94, + 0x3c418dd3, + 0x3c420edf, + 0x3c428e69, + 0x40321a2f, + 0x40329a45, + 0x40331a73, + 0x40339a7d, + 0x40341a94, + 0x40349ab2, + 0x40351ac2, + 0x40359ad4, + 0x40361ae1, + 0x40369aed, + 0x40371b02, + 0x40379b14, + 0x40381b1f, + 0x40389b31, + 0x40390f93, + 0x40399b41, + 0x403a1b54, + 0x403a9b75, + 0x403b1b86, + 0x403b9b96, 0x403c0071, 0x403c8090, - 0x403d1b9b, - 0x403d9bb1, - 0x403e1bc0, - 0x403e9bf8, - 0x403f1c12, - 0x403f9c3a, - 0x40401c4f, - 0x40409c63, - 0x40411c9e, - 0x40419cb9, - 0x40421cd2, - 0x40429ce5, - 0x40431cf9, - 0x40439d27, - 0x40441d3e, + 0x403d1bf7, + 0x403d9c0d, + 0x403e1c1c, + 0x403e9c54, + 0x403f1c6e, + 0x403f9c96, + 0x40401cab, + 0x40409cbf, + 0x40411cfa, + 0x40419d15, + 0x40421d2e, + 0x40429d41, + 0x40431d55, + 0x40439d83, + 0x40441d9a, 0x404480b9, - 0x40451d53, - 0x40459d65, - 0x40461d89, - 0x40469da9, - 0x40471db7, - 0x40479dde, - 0x40481e4f, - 0x40489f09, - 0x40491f20, - 0x40499f3a, - 0x404a1f51, - 0x404a9f6f, - 0x404b1f87, - 0x404b9fb4, - 0x404c1fca, - 0x404c9fdc, - 0x404d1ffd, - 0x404da036, - 0x404e204a, - 0x404ea057, - 0x404f20f1, - 0x404fa167, - 0x405021be, - 0x4050a1d2, - 0x40512205, - 0x40522215, - 0x4052a239, - 0x40532251, - 0x4053a264, - 0x40542279, - 0x4054a29c, - 0x405522c7, - 0x4055a304, - 0x40562329, - 0x4056a342, - 0x4057235a, - 0x4057a36d, - 0x40582382, - 0x4058a3a9, - 0x405923d8, - 0x4059a405, - 0x405a2419, - 0x405aa429, - 0x405b2441, - 0x405ba452, - 0x405c2465, - 0x405ca4a4, - 0x405d24b1, - 0x405da4d6, - 0x405e2514, - 0x405e8adb, - 0x405f254f, - 0x405fa55c, - 0x4060256a, - 0x4060a58c, - 0x406125ed, - 0x4061a625, - 0x4062263c, - 0x4062a64d, - 0x4063269a, - 0x4063a6af, - 0x406426c6, - 0x4064a6f2, - 0x4065270d, - 0x4065a724, - 0x4066273c, - 0x4066a766, - 0x40672791, - 0x4067a7d6, - 0x4068281e, - 0x4068a83f, - 0x40692871, - 0x4069a89f, - 0x406a28c0, - 0x406aa8e0, - 0x406b2a68, - 0x406baa8b, - 0x406c2aa1, - 0x406cadab, - 0x406d2dda, - 0x406dae02, - 0x406e2e30, - 0x406eae7d, - 0x406f2ed6, - 0x406faf0e, - 0x40702f21, - 0x4070af3e, - 0x4071082a, - 0x4071af50, - 0x40722f63, - 0x4072af99, - 0x40732fb1, - 0x40739540, - 0x40742fc5, - 0x4074afdf, - 0x40752ff0, - 0x4075b004, - 0x40763012, - 0x40769304, - 0x40773037, - 0x4077b077, - 0x40783092, - 0x4078b0cb, - 0x407930e2, - 0x4079b0f8, - 0x407a3124, - 0x407ab137, - 0x407b314c, - 0x407bb15e, - 0x407c318f, - 0x407cb198, - 0x407d285a, - 0x407da177, - 0x407e30a7, - 0x407ea3b9, - 0x407f1dcb, - 0x407f9f9e, - 0x40802101, - 0x40809df3, - 0x40812227, - 0x4081a0a5, - 0x40822e1b, - 0x40829b46, - 0x40832394, - 0x4083a6d7, - 0x40841e07, - 0x4084a3f1, - 0x40852476, - 0x4085a5b4, - 0x408624f6, - 0x4086a191, - 0x40872e61, - 0x4087a602, - 0x40881b84, - 0x4088a7e9, - 0x40891bd3, - 0x40899b60, - 0x408a2ad9, - 0x408a9958, - 0x408b3173, - 0x408baeeb, - 0x408c2486, - 0x408c9990, - 0x408d1eef, - 0x408d9e39, - 0x408e201f, - 0x408ea2e4, - 0x408f27fd, - 0x408fa5d0, - 0x409027b2, - 0x4090a4c8, - 0x40912ac1, - 0x409199b6, - 0x40921c20, - 0x4092ae9c, - 0x40932f7c, - 0x4093a1a2, - 0x40941e1b, - 0x4094aaf2, - 0x4095265e, - 0x4095b104, - 0x40962e48, - 0x4096a11a, - 0x409721ed, - 0x4097a06e, - 0x40981c80, - 0x4098a672, - 0x40992eb8, - 0x4099a311, - 0x409a22aa, - 0x409a9974, - 0x409b1e75, - 0x409b9ea0, - 0x409c3059, - 0x409c9ec8, - 0x409d20d6, - 0x409da0bb, - 0x409e1d11, - 0x409ea14f, - 0x409f2137, - 0x409f9e68, - 0x40a02535, - 0x40a0a088, - 0x41f42993, - 0x41f92a25, - 0x41fe2918, - 0x41feabce, - 0x41ff2cfc, - 0x420329ac, - 0x420829ce, - 0x4208aa0a, - 0x420928fc, - 0x4209aa44, - 0x420a2953, - 0x420aa933, - 0x420b2973, - 0x420ba9ec, - 0x420c2d18, - 0x420cab02, - 0x420d2bb5, - 0x420dabec, - 0x42122c1f, - 0x42172cdf, - 0x4217ac61, - 0x421c2c83, - 0x421f2c3e, - 0x42212d90, - 0x42262cc2, - 0x422b2d6e, - 0x422bab90, - 0x422c2d50, - 0x422cab43, - 0x422d2b1c, - 0x422dad2f, - 0x422e2b6f, - 0x42302c9e, - 0x4230ac06, - 0x44320755, - 0x44328764, - 0x44330770, - 0x4433877e, - 0x44340791, - 0x443487a2, - 0x443507a9, - 0x443587b3, - 0x443607c6, - 0x443687dc, - 0x443707ee, - 0x443787fb, - 0x4438080a, - 0x44388812, - 0x4439082a, - 0x44398838, - 0x443a084b, - 0x4832132e, - 0x48329340, - 0x48331356, - 0x4833936f, - 0x4c321394, - 0x4c3293a4, - 0x4c3313b7, - 0x4c3393d7, + 0x40451daf, + 0x40459dc1, + 0x40461de5, + 0x40469e05, + 0x40471e13, + 0x40479e3a, + 0x40481eab, + 0x40489f65, + 0x40491f7c, + 0x40499f96, + 0x404a1fad, + 0x404a9fcb, + 0x404b1fe3, + 0x404ba010, + 0x404c2026, + 0x404ca038, + 0x404d2059, + 0x404da092, + 0x404e20a6, + 0x404ea0b3, + 0x404f214d, + 0x404fa1c3, + 0x40502232, + 0x4050a246, + 0x40512279, + 0x40522289, + 0x4052a2ad, + 0x405322c5, + 0x4053a2d8, + 0x405422ed, + 0x4054a310, + 0x4055233b, + 0x4055a378, + 0x4056239d, + 0x4056a3b6, + 0x405723ce, + 0x4057a3e1, + 0x405823f6, + 0x4058a41d, + 0x4059244c, + 0x4059a479, + 0x405a248d, + 0x405aa49d, + 0x405b24b5, + 0x405ba4c6, + 0x405c24d9, + 0x405ca518, + 0x405d2525, + 0x405da54a, + 0x405e2588, + 0x405e8afe, + 0x405f25a9, + 0x405fa5b6, + 0x406025c4, + 0x4060a5e6, + 0x40612647, + 0x4061a67f, + 0x40622696, + 0x4062a6a7, + 0x406326f4, + 0x4063a709, + 0x40642720, + 0x4064a74c, + 0x40652767, + 0x4065a77e, + 0x40662796, + 0x4066a7c0, + 0x406727eb, + 0x4067a830, + 0x40682878, + 0x4068a899, + 0x406928cb, + 0x4069a8f9, + 0x406a291a, + 0x406aa93a, + 0x406b2ac2, + 0x406baae5, + 0x406c2afb, + 0x406cae05, + 0x406d2e34, + 0x406dae5c, + 0x406e2e8a, + 0x406eaed7, + 0x406f2f30, + 0x406faf68, + 0x40702f7b, + 0x4070af98, + 0x4071084d, + 0x4071afaa, + 0x40722fbd, + 0x4072aff3, + 0x4073300b, + 0x4073959c, + 0x4074301f, + 0x4074b039, + 0x4075304a, + 0x4075b05e, + 0x4076306c, + 0x40769348, + 0x40773091, + 0x4077b0d1, + 0x407830ec, + 0x4078b125, + 0x4079313c, + 0x4079b152, + 0x407a317e, + 0x407ab191, + 0x407b31a6, + 0x407bb1b8, + 0x407c31e9, + 0x407cb1f2, + 0x407d28b4, + 0x407da1eb, + 0x407e3101, + 0x407ea42d, + 0x407f1e27, + 0x407f9ffa, + 0x4080215d, + 0x40809e4f, + 0x4081229b, + 0x4081a101, + 0x40822e75, + 0x40829ba2, + 0x40832408, + 0x4083a731, + 0x40841e63, + 0x4084a465, + 0x408524ea, + 0x4085a60e, + 0x4086256a, + 0x4086a205, + 0x40872ebb, + 0x4087a65c, + 0x40881be0, + 0x4088a843, + 0x40891c2f, + 0x40899bbc, + 0x408a2b33, + 0x408a99b4, + 0x408b31cd, + 0x408baf45, + 0x408c24fa, + 0x408c99ec, + 0x408d1f4b, + 0x408d9e95, + 0x408e207b, + 0x408ea358, + 0x408f2857, + 0x408fa62a, + 0x4090280c, + 0x4090a53c, + 0x40912b1b, + 0x40919a12, + 0x40921c7c, + 0x4092aef6, + 0x40932fd6, + 0x4093a216, + 0x40941e77, + 0x4094ab4c, + 0x409526b8, + 0x4095b15e, + 0x40962ea2, + 0x4096a176, + 0x40972261, + 0x4097a0ca, + 0x40981cdc, + 0x4098a6cc, + 0x40992f12, + 0x4099a385, + 0x409a231e, + 0x409a99d0, + 0x409b1ed1, + 0x409b9efc, + 0x409c30b3, + 0x409c9f24, + 0x409d2132, + 0x409da117, + 0x409e1d6d, + 0x409ea1ab, + 0x409f2193, + 0x409f9ec4, + 0x40a021d3, + 0x40a0a0e4, + 0x41f429ed, + 0x41f92a7f, + 0x41fe2972, + 0x41feac28, + 0x41ff2d56, + 0x42032a06, + 0x42082a28, + 0x4208aa64, + 0x42092956, + 0x4209aa9e, + 0x420a29ad, + 0x420aa98d, + 0x420b29cd, + 0x420baa46, + 0x420c2d72, + 0x420cab5c, + 0x420d2c0f, + 0x420dac46, + 0x42122c79, + 0x42172d39, + 0x4217acbb, + 0x421c2cdd, + 0x421f2c98, + 0x42212dea, + 0x42262d1c, + 0x422b2dc8, + 0x422babea, + 0x422c2daa, + 0x422cab9d, + 0x422d2b76, + 0x422dad89, + 0x422e2bc9, + 0x42302cf8, + 0x4230ac60, + 0x44320778, + 0x44328787, + 0x44330793, + 0x443387a1, + 0x443407b4, + 0x443487c5, + 0x443507cc, + 0x443587d6, + 0x443607e9, + 0x443687ff, + 0x44370811, + 0x4437881e, + 0x4438082d, + 0x44388835, + 0x4439084d, + 0x4439885b, + 0x443a086e, + 0x48321372, + 0x48329384, + 0x4833139a, + 0x483393b3, + 0x4c3213f0, + 0x4c329400, + 0x4c331413, + 0x4c339433, 0x4c3400b9, 0x4c3480f7, - 0x4c3513e3, - 0x4c3593f1, - 0x4c36140d, - 0x4c369433, - 0x4c371442, - 0x4c379450, - 0x4c381465, - 0x4c389471, - 0x4c391491, - 0x4c3994bb, - 0x4c3a14d4, - 0x4c3a94ed, - 0x4c3b0625, - 0x4c3b9506, - 0x4c3c1518, - 0x4c3c9527, - 0x4c3d1540, - 0x4c3d8c6f, - 0x4c3e15ad, - 0x4c3e954f, - 0x4c3f15cf, - 0x4c3f9304, - 0x4c401565, - 0x4c409380, - 0x4c41159d, - 0x4c419420, - 0x4c421589, - 0x50323502, - 0x5032b511, - 0x5033351c, - 0x5033b52c, - 0x50343545, - 0x5034b55f, - 0x5035356d, - 0x5035b583, - 0x50363595, - 0x5036b5ab, - 0x503735c4, - 0x5037b5d7, - 0x503835ef, - 0x5038b600, - 0x50393615, - 0x5039b629, - 0x503a3649, - 0x503ab65f, - 0x503b3677, - 0x503bb689, - 0x503c36a5, - 0x503cb6bc, - 0x503d36d5, - 0x503db6eb, - 0x503e36f8, - 0x503eb70e, - 0x503f3720, - 0x503f83a3, - 0x50403733, - 0x5040b743, - 0x5041375d, - 0x5041b76c, - 0x50423786, - 0x5042b7a3, - 0x504337b3, - 0x5043b7c3, - 0x504437e0, - 0x50448459, - 0x504537f4, - 0x5045b812, - 0x50463825, - 0x5046b83b, - 0x5047384d, - 0x5047b862, - 0x50483888, - 0x5048b896, - 0x504938a9, - 0x5049b8be, - 0x504a38d4, - 0x504ab8e4, - 0x504b3904, - 0x504bb917, - 0x504c393a, - 0x504cb968, - 0x504d3995, - 0x504db9b2, - 0x504e39cd, - 0x504eb9e9, - 0x504f39fb, - 0x504fba12, - 0x50503a21, - 0x50508719, - 0x50513a34, - 0x5051b7d2, - 0x5052397a, - 0x58320f8d, - 0x68320f4f, - 0x68328ca7, - 0x68330cba, - 0x68338f5d, - 0x68340f6d, + 0x4c35143f, + 0x4c35944d, + 0x4c361469, + 0x4c36948f, + 0x4c37149e, + 0x4c3794ac, + 0x4c3814c1, + 0x4c3894cd, + 0x4c3914ed, + 0x4c399517, + 0x4c3a1530, + 0x4c3a9549, + 0x4c3b0635, + 0x4c3b9562, + 0x4c3c1574, + 0x4c3c9583, + 0x4c3d159c, + 0x4c3d8cb3, + 0x4c3e1609, + 0x4c3e95ab, + 0x4c3f162b, + 0x4c3f9348, + 0x4c4015c1, + 0x4c4093dc, + 0x4c4115f9, + 0x4c41947c, + 0x4c4215e5, + 0x4c4293c4, + 0x503235b3, + 0x5032b5c2, + 0x503335cd, + 0x5033b5dd, + 0x503435f6, + 0x5034b610, + 0x5035361e, + 0x5035b634, + 0x50363646, + 0x5036b65c, + 0x50373675, + 0x5037b688, + 0x503836a0, + 0x5038b6b1, + 0x503936c6, + 0x5039b6da, + 0x503a36fa, + 0x503ab710, + 0x503b3728, + 0x503bb73a, + 0x503c3756, + 0x503cb76d, + 0x503d3786, + 0x503db79c, + 0x503e37a9, + 0x503eb7bf, + 0x503f37d1, + 0x503f83b3, + 0x504037e4, + 0x5040b7f4, + 0x5041380e, + 0x5041b81d, + 0x50423837, + 0x5042b854, + 0x50433864, + 0x5043b874, + 0x50443891, + 0x50448469, + 0x504538a5, + 0x5045b8c3, + 0x504638d6, + 0x5046b8ec, + 0x504738fe, + 0x5047b913, + 0x50483939, + 0x5048b947, + 0x5049395a, + 0x5049b96f, + 0x504a3985, + 0x504ab995, + 0x504b39b5, + 0x504bb9c8, + 0x504c39eb, + 0x504cba19, + 0x504d3a46, + 0x504dba63, + 0x504e3a7e, + 0x504eba9a, + 0x504f3aac, + 0x504fbac3, + 0x50503ad2, + 0x50508729, + 0x50513ae5, + 0x5051b883, + 0x50523a2b, + 0x58320fd1, + 0x68320f93, + 0x68328ceb, + 0x68330cfe, + 0x68338fa1, + 0x68340fb1, 0x683480f7, - 0x6c320f15, - 0x6c328c5e, - 0x6c330f20, - 0x6c338f39, - 0x74320a43, + 0x6835099a, + 0x6c320f59, + 0x6c328ca2, + 0x6c330f64, + 0x6c338f7d, + 0x74320a66, 0x743280b9, - 0x74330c6f, - 0x783209a8, - 0x783289bd, - 0x783309c9, + 0x74330cb3, + 0x783209cb, + 0x783289e0, + 0x783309ec, 0x78338090, - 0x783409d8, - 0x783489ed, - 0x78350a0c, - 0x78358a2e, - 0x78360a43, - 0x78368a59, - 0x78370a69, - 0x78378a8a, - 0x78380a9d, - 0x78388aaf, - 0x78390abc, - 0x78398adb, - 0x783a0af0, - 0x783a8afe, - 0x783b0b08, - 0x783b8b1c, - 0x783c0b33, - 0x783c8b48, - 0x783d0b5f, - 0x783d8b74, - 0x783e0aca, - 0x783e8a7c, - 0x7c32121d, - 0x80321433, + 0x783409fb, + 0x78348a10, + 0x78350a2f, + 0x78358a51, + 0x78360a66, + 0x78368a7c, + 0x78370a8c, + 0x78378aad, + 0x78380ac0, + 0x78388ad2, + 0x78390adf, + 0x78398afe, + 0x783a0b13, + 0x783a8b21, + 0x783b0b2b, + 0x783b8b3f, + 0x783c0b56, + 0x783c8b6b, + 0x783d0b82, + 0x783d8b97, + 0x783e0aed, + 0x783e8a9f, + 0x7c321261, + 0x8032148f, 0x80328090, - 0x80333255, + 0x803332af, 0x803380b9, - 0x80343264, - 0x8034b1cc, - 0x803531ea, - 0x8035b278, - 0x8036322c, - 0x8036b1db, - 0x8037321e, - 0x8037b1b9, - 0x8038323f, - 0x8038b1fb, - 0x80393210, + 0x803432be, + 0x8034b226, + 0x80353244, + 0x8035b2d2, + 0x80363286, + 0x8036b235, + 0x80373278, + 0x8037b213, + 0x80383299, + 0x8038b255, + 0x8039326a, }; const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); @@ -851,6 +861,7 @@ const char kOpenSSLReasonStringData[] = "INVALID_BIT_STRING_PADDING\0" "INVALID_BMPSTRING\0" "INVALID_DIGIT\0" + "INVALID_INTEGER\0" "INVALID_MODIFIER\0" "INVALID_NUMBER\0" "INVALID_OBJECT_ENCODING\0" @@ -897,6 +908,7 @@ const char kOpenSSLReasonStringData[] = "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0" "UNSUPPORTED_PUBLIC_KEY_TYPE\0" "UNSUPPORTED_TYPE\0" + "WRONG_INTEGER_TYPE\0" "WRONG_PUBLIC_KEY_TYPE\0" "WRONG_TAG\0" "WRONG_TYPE\0" @@ -966,6 +978,7 @@ const char kOpenSSLReasonStringData[] = "MISSING_EQUAL_SIGN\0" "NO_CLOSE_BRACE\0" "UNABLE_TO_CREATE_NEW_SECTION\0" + "VARIABLE_EXPANSION_NOT_SUPPORTED\0" "VARIABLE_EXPANSION_TOO_LONG\0" "VARIABLE_HAS_NO_VALUE\0" "BAD_GENERATOR\0" @@ -1066,6 +1079,7 @@ const char kOpenSSLReasonStringData[] = "NOT_PKCS7_SIGNED_DATA\0" "NO_CERTIFICATES_INCLUDED\0" "NO_CRLS_INCLUDED\0" + "AMBIGUOUS_FRIENDLY_NAME\0" "BAD_ITERATION_COUNT\0" "BAD_PKCS12_DATA\0" "BAD_PKCS12_VERSION\0" @@ -1223,6 +1237,7 @@ const char kOpenSSLReasonStringData[] = "INVALID_ECH_CONFIG_LIST\0" "INVALID_ECH_PUBLIC_NAME\0" "INVALID_MESSAGE\0" + "INVALID_OUTER_EXTENSION\0" "INVALID_OUTER_RECORD_TYPE\0" "INVALID_SCT_LIST\0" "INVALID_SIGNATURE_ALGORITHM\0" @@ -1266,7 +1281,6 @@ const char kOpenSSLReasonStringData[] = "OLD_SESSION_CIPHER_NOT_RETURNED\0" "OLD_SESSION_PRF_HASH_MISMATCH\0" "OLD_SESSION_VERSION_NOT_RETURNED\0" - "OUTER_EXTENSION_NOT_FOUND\0" "PARSE_TLSEXT\0" "PATH_TOO_LONG\0" "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" @@ -1407,6 +1421,7 @@ const char kOpenSSLReasonStringData[] = "INVALID_FIELD_FOR_VERSION\0" "INVALID_FIELD_NAME\0" "INVALID_PARAMETER\0" + "INVALID_POLICY_EXTENSION\0" "INVALID_PSS_PARAMETERS\0" "INVALID_TRUST\0" "INVALID_VERSION\0" @@ -1417,7 +1432,10 @@ const char kOpenSSLReasonStringData[] = "LOADING_DEFAULTS\0" "NAME_TOO_LONG\0" "NEWER_CRL_NOT_NEWER\0" + "NO_CERTIFICATE_FOUND\0" + "NO_CERTIFICATE_OR_CRL_FOUND\0" "NO_CERT_SET_FOR_US_TO_VERIFY\0" + "NO_CRL_FOUND\0" "NO_CRL_NUMBER\0" "PUBLIC_KEY_DECODE_ERROR\0" "PUBLIC_KEY_ENCODE_ERROR\0" diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8-linux.S index e7f019ce..598cb2a8 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/chacha/chacha-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -66,7 +65,7 @@ ChaCha20_ctr32: ldp x24,x25,[x3] // load key ldp x26,x27,[x3,#16] ldp x28,x30,[x4] // load counter -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x24,x24,#32 ror x25,x25,#32 ror x26,x26,#32 @@ -227,7 +226,7 @@ ChaCha20_ctr32: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -284,7 +283,7 @@ ChaCha20_ctr32: add x15,x15,x16,lsl#32 add x17,x17,x19,lsl#32 add x20,x20,x21,lsl#32 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -350,7 +349,7 @@ ChaCha20_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -648,7 +647,7 @@ ChaCha20_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -728,7 +727,7 @@ ChaCha20_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -846,7 +845,7 @@ ChaCha20_512_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -1359,7 +1358,7 @@ ChaCha20_512_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1873,7 +1872,7 @@ ChaCha20_512_neon: add x1,x1,#64 add v21.4s,v21.4s,v25.4s -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1990,6 +1989,8 @@ ChaCha20_512_neon: AARCH64_VALIDATE_LINK_REGISTER ret .size ChaCha20_512_neon,.-ChaCha20_512_neon +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-linux.S b/third_party/boringssl/kit/linux-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-linux.S new file mode 100644 index 00000000..73a3d646 --- /dev/null +++ b/third_party/boringssl/kit/linux-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-linux.S @@ -0,0 +1,3021 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +.section .rodata + +.align 7 +.Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.Linc: +.long 1,2,3,4 +.Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC + +.text + +.type .Lpoly_hash_ad_internal,%function +.align 6 +.Lpoly_hash_ad_internal: +.cfi_startproc + cbnz x4, .Lpoly_hash_intro + ret + +.Lpoly_hash_intro: + cmp x4, #16 + b.lt .Lpoly_hash_ad_tail + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b .Lpoly_hash_ad_internal + +.Lpoly_hash_ad_tail: + cbz x4, .Lpoly_hash_ad_ret + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the AAD + sub x4, x4, #1 + +.Lpoly_hash_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, x4] + mov v20.b[0], w11 + subs x4, x4, #1 + b.ge .Lpoly_hash_tail_16_compose + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +.Lpoly_hash_ad_ret: + ret +.cfi_endproc +.size .Lpoly_hash_ad_internal, .-.Lpoly_hash_ad_internal + +///////////////////////////////// +// +// void chacha20_poly1305_seal(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *seal_data); +// +.globl chacha20_poly1305_seal +.hidden chacha20_poly1305_seal +.type chacha20_poly1305_seal,%function +.align 6 +chacha20_poly1305_seal: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, .Lchacha20_consts + add x11, x11, :lo12:.Lchacha20_consts + + ld1 {v24.16b - v27.16b}, [x11] // .Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + ldr x12, [x5, #56] // The total cipher text length includes extra_in_len + add x12, x12, x2 + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x12 + + cmp x2, #128 + b.le .Lseal_128 // Optimization for smaller buffers + + // Initially we prepare 5 ChaCha20 blocks. Four to encrypt up to 4 blocks (256 bytes) of plaintext, + // and one for the Poly1305 R and S keys. The first four blocks (A0-A3..D0-D3) are computed vertically, + // the fifth block (A4-D4) horizontally. + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + sub x5, x5, #32 + + mov x6, #10 + +.align 5 +.Lseal_init_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.hi .Lseal_init_rounds + + add v15.4s, v15.4s, v25.4s + mov x11, #4 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + and v4.16b, v4.16b, v27.16b + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + mov x16, v4.d[0] // Move the R key to GPRs + mov x17, v4.d[1] + mov v27.16b, v9.16b // Store the S key + + bl .Lpoly_hash_ad_internal + + mov x3, x0 + cmp x2, #256 + b.le .Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #256 + + mov x6, #4 // In the first run of the loop we need to hash 256 bytes, therefore we hash one block for the first 4 rounds + mov x7, #6 // and two blocks for the remaining 6, for a total of (1 * 4 + 2 * 6) * 16 = 256 + +.Lseal_main_loop: + adrp x11, .Lchacha20_consts + add x11, x11, :lo12:.Lchacha20_consts + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + sub x5, x5, #32 +.align 5 +.Lseal_main_loop_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.ge .Lseal_main_loop_rounds + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + subs x7, x7, #1 + b.gt .Lseal_main_loop_rounds + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + cmp x2, #320 + b.le .Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #320 + + mov x6, #0 + mov x7, #10 // For the remainder of the loop we always hash and encrypt 320 bytes per iteration + + b .Lseal_main_loop + +.Lseal_tail: + // This part of the function handles the storage and authentication of the last [0,320) bytes + // We assume A0-A4 ... D0-D4 hold at least inl (320 max) bytes of the stream data. + cmp x2, #64 + b.lt .Lseal_tail_64 + + // Store and authenticate 64B blocks per iteration + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + // Shift the state left by 64 bytes for the next iteration of the loop + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + + mov v1.16b, v2.16b + mov v6.16b, v7.16b + mov v11.16b, v12.16b + mov v16.16b, v17.16b + + mov v2.16b, v3.16b + mov v7.16b, v8.16b + mov v12.16b, v13.16b + mov v17.16b, v18.16b + + mov v3.16b, v4.16b + mov v8.16b, v9.16b + mov v13.16b, v14.16b + mov v18.16b, v19.16b + + b .Lseal_tail + +.Lseal_tail_64: + ldp x3, x4, [x5, #48] // extra_in_len and extra_in_ptr + + // Here we handle the last [0,64) bytes of plaintext + cmp x2, #16 + b.lt .Lseal_tail_16 + // Each iteration encrypt and authenticate a 16B block + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b}, [x0], #16 + + sub x2, x2, #16 + + // Shift the state left by 16 bytes for the next iteration of the loop + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + + b .Lseal_tail_64 + +.Lseal_tail_16: + // Here we handle the last [0,16) bytes of ciphertext that require a padded block + cbz x2, .Lseal_hash_extra + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the plaintext/extra in + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask that will only mask the ciphertext bytes + not v22.16b, v20.16b + + mov x6, x2 + add x1, x1, x2 + + cbz x4, .Lseal_tail_16_compose // No extra data to pad with, zero padding + + mov x7, #16 // We need to load some extra_in first for padding + sub x7, x7, x2 + cmp x4, x7 + csel x7, x4, x7, lt // .Load the minimum of extra_in_len and the amount needed to fill the register + mov x12, x7 + add x3, x3, x7 + sub x4, x4, x7 + +.Lseal_tail16_compose_extra_in: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x7, x7, #1 + b.gt .Lseal_tail16_compose_extra_in + + add x3, x3, x12 + +.Lseal_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x1, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt .Lseal_tail_16_compose + + and v0.16b, v0.16b, v21.16b + eor v20.16b, v20.16b, v0.16b + mov v21.16b, v20.16b + +.Lseal_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt .Lseal_tail_16_store + + // Hash in the final ct block concatenated with extra_in + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +.Lseal_hash_extra: + cbz x4, .Lseal_finalize + +.Lseal_hash_extra_loop: + cmp x4, #16 + b.lt .Lseal_hash_extra_tail + ld1 {v20.16b}, [x3], #16 + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b .Lseal_hash_extra_loop + +.Lseal_hash_extra_tail: + cbz x4, .Lseal_finalize + eor v20.16b, v20.16b, v20.16b // Use T0 to load the remaining extra ciphertext + add x3, x3, x4 + +.Lseal_hash_extra_load: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x4, x4, #1 + b.gt .Lseal_hash_extra_load + + // Hash in the final padded extra_in blcok + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +.Lseal_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.Lseal_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +.Lseal_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi .Lseal_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + // Only the first 32 bytes of the third block (counter = 0) are needed, + // so skip updating v12 and v17. + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl .Lpoly_hash_ad_internal + b .Lseal_tail +.cfi_endproc +.size chacha20_poly1305_seal,.-chacha20_poly1305_seal + +///////////////////////////////// +// +// void chacha20_poly1305_open(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *aead_data); +// +.globl chacha20_poly1305_open +.hidden chacha20_poly1305_open +.type chacha20_poly1305_open,%function +.align 6 +chacha20_poly1305_open: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, .Lchacha20_consts + add x11, x11, :lo12:.Lchacha20_consts + + ld1 {v24.16b - v27.16b}, [x11] // .Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x2 + + cmp x2, #128 + b.le .Lopen_128 // Optimization for smaller buffers + + // Initially we prepare a single ChaCha20 block for the Poly1305 R and S keys + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + + mov x6, #10 + +.align 5 +.Lopen_init_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.hi .Lopen_init_rounds + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + + and v0.16b, v0.16b, v27.16b + mov x16, v0.d[0] // Move the R key to GPRs + mov x17, v0.d[1] + mov v27.16b, v5.16b // Store the S key + + bl .Lpoly_hash_ad_internal + +.Lopen_ad_done: + mov x3, x1 + +// Each iteration of the loop hash 320 bytes, and prepare stream for 320 bytes +.Lopen_main_loop: + + cmp x2, #192 + b.lt .Lopen_tail + + adrp x11, .Lchacha20_consts + add x11, x11, :lo12:.Lchacha20_consts + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + sub x5, x5, #32 + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + lsr x4, x2, #4 // How many whole blocks we have to hash, will always be at least 12 + sub x4, x4, #10 + + mov x7, #10 + subs x6, x7, x4 + subs x6, x7, x4 // itr1 can be negative if we have more than 320 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are full + + cbz x7, .Lopen_main_loop_rounds_short + +.align 5 +.Lopen_main_loop_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +.Lopen_main_loop_rounds_short: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x7, x7, #1 + b.gt .Lopen_main_loop_rounds + subs x6, x6, #1 + b.ge .Lopen_main_loop_rounds_short + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + // We can always safely store 192 bytes + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #192 + + mov v0.16b, v3.16b + mov v5.16b, v8.16b + mov v10.16b, v13.16b + mov v15.16b, v18.16b + + cmp x2, #64 + b.lt .Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v4.16b + mov v5.16b, v9.16b + mov v10.16b, v14.16b + mov v15.16b, v19.16b + + cmp x2, #64 + b.lt .Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + b .Lopen_main_loop + +.Lopen_tail: + + cbz x2, .Lopen_finalize + + lsr x4, x2, #4 // How many whole blocks we have to hash + + cmp x2, #64 + b.le .Lopen_tail_64 + cmp x2, #128 + b.le .Lopen_tail_128 + +.Lopen_tail_192: + // We need three more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + mov v17.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v21.16b, v21.16b, v21.16b + ins v23.s[0], v25.s[0] + ins v21.d[0], x15 + + add v22.4s, v23.4s, v21.4s + add v21.4s, v22.4s, v21.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + mov x7, #10 + subs x6, x7, x4 // itr1 can be negative if we have more than 160 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are hashing + sub x4, x4, x7 + + cbz x7, .Lopen_tail_192_rounds_no_hash + +.Lopen_tail_192_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +.Lopen_tail_192_rounds_no_hash: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x7, x7, #1 + b.gt .Lopen_tail_192_rounds + subs x6, x6, #1 + b.ge .Lopen_tail_192_rounds_no_hash + + // We hashed 160 bytes at most, may still have 32 bytes left +.Lopen_tail_192_hash: + cbz x4, .Lopen_tail_192_hash_done + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b .Lopen_tail_192_hash + +.Lopen_tail_192_hash_done: + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v12.4s, v12.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v17.4s, v17.4s, v30.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #128 + b .Lopen_tail_64_store + +.Lopen_tail_128: + // We need two more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v22.16b, v22.16b, v22.16b + ins v23.s[0], v25.s[0] + ins v22.d[0], x15 + add v22.4s, v22.4s, v23.4s + + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +.Lopen_tail_128_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #4 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #12 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #4 + subs x6, x6, #1 + b.gt .Lopen_tail_128_rounds + cbz x4, .Lopen_tail_128_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b .Lopen_tail_128_rounds + +.Lopen_tail_128_rounds_done: + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + b .Lopen_tail_64_store + +.Lopen_tail_64: + // We just need a single block + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + ins v23.s[0], v25.s[0] + add v15.4s, v15.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +.Lopen_tail_64_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.gt .Lopen_tail_64_rounds + cbz x4, .Lopen_tail_64_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b .Lopen_tail_64_rounds + +.Lopen_tail_64_rounds_done: + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v15.4s, v15.4s, v23.4s + +.Lopen_tail_64_store: + cmp x2, #16 + b.lt .Lopen_tail_16 + + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + st1 {v20.16b}, [x0], #16 + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + sub x2, x2, #16 + b .Lopen_tail_64_store + +.Lopen_tail_16: + // Here we handle the last [0,16) bytes that require a padded block + cbz x2, .Lopen_finalize + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the ciphertext + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask + not v22.16b, v20.16b + + add x7, x1, x2 + mov x6, x2 + +.Lopen_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x7, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt .Lopen_tail_16_compose + + and v20.16b, v20.16b, v21.16b + // Hash in the final padded block + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + eor v20.16b, v20.16b, v0.16b + +.Lopen_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt .Lopen_tail_16_store + +.Lopen_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.Lopen_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +.Lopen_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi .Lopen_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl .Lpoly_hash_ad_internal + +.Lopen_128_store: + cmp x2, #64 + b.lt .Lopen_128_store_64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + +.Lopen_128_store_64: + + lsr x4, x2, #4 + mov x3, x1 + +.Lopen_128_hash_64: + cbz x4, .Lopen_tail_64_store + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b .Lopen_128_hash_64 +.cfi_endproc +.size chacha20_poly1305_open,.-chacha20_poly1305_open +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armv8-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armv8-linux.S index f8cd03df..fe13c64d 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -635,7 +634,7 @@ aes_hw_ctr32_encrypt_blocks: // // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8, w8 #endif add w10, w8, #1 @@ -797,6 +796,8 @@ aes_hw_ctr32_encrypt_blocks: ret .size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-linux.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-linux.S new file mode 100644 index 00000000..3e462d59 --- /dev/null +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-linux.S @@ -0,0 +1,1567 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +#if __ARM_MAX_ARCH__ >= 8 + +.arch armv8-a+crypto +.text +.globl aes_gcm_enc_kernel +.hidden aes_gcm_enc_kernel +.type aes_gcm_enc_kernel,%function +.align 4 +aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + add x4, x0, x1, lsr #3 // end_input_ptr + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 // byte_len - 1 + ldr q18, [x8, #0] // load rk0 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr q25, [x8, #112] // load rk7 + add x5, x5, x0 + lsr x12, x11, #32 + fmov d2, x10 // CTR block 2 + orr w11, w11, w11 + rev w12, w12 // rev_ctr32 + fmov d1, x10 // CTR block 1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + add w12, w12, #1 // increment rev_ctr32 + rev w9, w12 // CTR block 1 + fmov d3, x10 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 1 + add w12, w12, #1 // CTR block 1 + ldr q19, [x8, #16] // load rk1 + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + ldr q20, [x8, #32] // load rk2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + orr x9, x11, x9, lsl #32 // CTR block 3 + fmov v3.d[1], x9 // CTR block 3 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q21, [x8, #48] // load rk3 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q24, [x8, #96] // load rk6 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q23, [x8, #80] // load rk5 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q22, [x8, #64] // load rk4 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + ldr q29, [x8, #176] // load rk11 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + ldr q26, [x8, #128] // load rk8 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + add w12, w12, #1 // CTR block 3 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + ldr q27, [x8, #144] // load rk9 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + ldr q28, [x8, #160] // load rk10 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + b.lt .Lenc_finish_first_blocks // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + b.eq .Lenc_finish_first_blocks // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +.Lenc_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v2.16b, v31.16b // AES block 2 - round N-1 + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + aese v3.16b, v31.16b // AES block 3 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + b.ge .Lenc_tail // handle tail + + ldp x19, x20, [x0, #16] // AES block 1 - load plaintext + rev w9, w12 // CTR block 4 + ldp x6, x7, [x0, #0] // AES block 0 - load plaintext + ldp x23, x24, [x0, #48] // AES block 3 - load plaintext + ldp x21, x22, [x0, #32] // AES block 2 - load plaintext + add x0, x0, #64 // AES input_ptr update + eor x19, x19, x13 // AES block 1 - round N low + eor x20, x20, x14 // AES block 1 - round N high + fmov d5, x19 // AES block 1 - mov low + eor x6, x6, x13 // AES block 0 - round N low + eor x7, x7, x14 // AES block 0 - round N high + eor x24, x24, x14 // AES block 3 - round N high + fmov d4, x6 // AES block 0 - mov low + cmp x0, x5 // check if we have <= 8 blocks + fmov v4.d[1], x7 // AES block 0 - mov high + eor x23, x23, x13 // AES block 3 - round N low + eor x21, x21, x13 // AES block 2 - round N low + fmov v5.d[1], x20 // AES block 1 - mov high + fmov d6, x21 // AES block 2 - mov low + add w12, w12, #1 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov d7, x23 // AES block 3 - mov low + eor x22, x22, x14 // AES block 2 - round N high + fmov v6.d[1], x22 // AES block 2 - mov high + eor v4.16b, v4.16b, v0.16b // AES block 0 - result + fmov d0, x10 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + eor v5.16b, v5.16b, v1.16b // AES block 1 - result + fmov d1, x10 // CTR block 5 + orr x9, x11, x9, lsl #32 // CTR block 5 + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + st1 { v4.16b}, [x2], #16 // AES block 0 - store result + fmov v7.d[1], x24 // AES block 3 - mov high + orr x9, x11, x9, lsl #32 // CTR block 6 + eor v6.16b, v6.16b, v2.16b // AES block 2 - result + st1 { v5.16b}, [x2], #16 // AES block 1 - store result + add w12, w12, #1 // CTR block 6 + fmov d2, x10 // CTR block 6 + fmov v2.d[1], x9 // CTR block 6 + st1 { v6.16b}, [x2], #16 // AES block 2 - store result + rev w9, w12 // CTR block 7 + orr x9, x11, x9, lsl #32 // CTR block 7 + eor v7.16b, v7.16b, v3.16b // AES block 3 - result + st1 { v7.16b}, [x2], #16 // AES block 3 - store result + b.ge .Lenc_prepretail // do prepretail + +.Lenc_main_loop: // main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + fmov v3.d[1], x9 // CTR block 4k+3 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] // AES block 4k+7 - load plaintext + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] // AES block 4k+6 - load plaintext + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b // PRE 1 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x23, x23, x13 // AES block 4k+7 - round N low + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d10, v17.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + eor x22, x22, x14 // AES block 4k+6 - round N high + mov d8, v4.d[1] // GHASH block 4k - mid + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] // AES block 4k+5 - load plaintext + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor x19, x19, x13 // AES block 4k+5 - round N low + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + eor x21, x21, x13 // AES block 4k+6 - round N low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + movi v8.8b, #0xc2 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + fmov d5, x19 // AES block 4k+5 - mov low + ldp x6, x7, [x0, #0] // AES block 4k+4 - load plaintext + b.lt .Lenc_main_loop_continue // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq .Lenc_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Lenc_main_loop_continue: + shl d8, d8, #56 // mod_constant + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + add w12, w12, #1 // CTR block 4k+3 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + add x0, x0, #64 // AES input_ptr update + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + rev w9, w12 // CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor x6, x6, x13 // AES block 4k+4 - round N low + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + eor x7, x7, x14 // AES block 4k+4 - round N high + fmov d4, x6 // AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b // MODULO - fold into mid + eor x20, x20, x14 // AES block 4k+5 - round N high + eor x24, x24, x14 // AES block 4k+7 - round N high + add w12, w12, #1 // CTR block 4k+8 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + fmov d7, x23 // AES block 4k+7 - mov low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + fmov v5.d[1], x20 // AES block 4k+5 - mov high + fmov d6, x21 // AES block 4k+6 - mov low + cmp x0, x5 // .LOOP CONTROL + fmov v6.d[1], x22 // AES block 4k+6 - mov high + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b // AES block 4k+4 - result + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + rev w9, w12 // CTR block 4k+9 + add w12, w12, #1 // CTR block 4k+9 + eor v5.16b, v5.16b, v1.16b // AES block 4k+5 - result + fmov d1, x10 // CTR block 4k+9 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + fmov v1.d[1], x9 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + rev w9, w12 // CTR block 4k+10 + st1 { v4.16b}, [x2], #16 // AES block 4k+4 - store result + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + fmov v7.d[1], x24 // AES block 4k+7 - mov high + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 // AES block 4k+5 - store result + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + eor v6.16b, v6.16b, v2.16b // AES block 4k+6 - result + fmov d2, x10 // CTR block 4k+10 + st1 { v6.16b}, [x2], #16 // AES block 4k+6 - store result + fmov v2.d[1], x9 // CTR block 4k+10 + rev w9, w12 // CTR block 4k+11 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + orr x9, x11, x9, lsl #32 // CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b // AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 // AES block 4k+7 - store result + b.lt .Lenc_main_loop + +.Lenc_prepretail: // PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + fmov v3.d[1], x9 // CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + add w12, w12, #1 // CTR block 4k+3 + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v9.16b // karatsuba tidy up + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + eor v10.16b, v10.16b, v11.16b + b.lt .Lenc_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + b.eq .Lenc_finish_prepretail // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + +.Lenc_finish_prepretail: + eor v10.16b, v10.16b, v4.16b + eor v10.16b, v10.16b, v9.16b + pmull v4.1q, v10.1d, v8.1d + ext v10.16b, v10.16b, v10.16b, #8 + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + eor v11.16b, v11.16b, v4.16b + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b + +.Lenc_tail: // TAIL + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 // AES block 4k+4 - load plaintext + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + cmp x5, #48 + fmov d4, x6 // AES block 4k+4 - mov low + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v5.16b, v4.16b, v0.16b // AES block 4k+4 - result + b.gt .Lenc_blocks_more_than_3 + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + movi v9.8b, #0 + sub w12, w12, #1 + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt .Lenc_blocks_more_than_2 + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + b.gt .Lenc_blocks_more_than_1 + sub w12, w12, #1 + b .Lenc_blocks_less_than_1 +.Lenc_blocks_more_than_3: // blocks left > 3 + st1 { v5.16b}, [x2], #16 // AES final-3 block - store result + ldp x6, x7, [x0], #16 // AES final-2 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-3 block + eor x6, x6, x13 // AES final-2 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor x7, x7, x14 // AES final-2 block - round N high + mov d22, v4.d[1] // GHASH final-3 block - mid + fmov d5, x6 // AES final-2 block - mov low + fmov v5.d[1], x7 // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + mov d10, v17.d[1] // GHASH final-3 block - mid + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b // AES final-2 block - result +.Lenc_blocks_more_than_2: // blocks left > 2 + st1 { v5.16b}, [x2], #16 // AES final-2 block - store result + ldp x6, x7, [x0], #16 // AES final-1 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-2 block + eor x6, x6, x13 // AES final-1 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + fmov d5, x6 // AES final-1 block - mov low + eor x7, x7, x14 // AES final-1 block - round N high + fmov v5.d[1], x7 // AES final-1 block - mov high + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + eor v5.16b, v5.16b, v2.16b // AES final-1 block - result + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid +.Lenc_blocks_more_than_1: // blocks left > 1 + st1 { v5.16b}, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ldp x6, x7, [x0], #16 // AES final block - load input low & high + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + eor x6, x6, x13 // AES final block - round N low + mov d22, v4.d[1] // GHASH final-1 block - mid + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor x7, x7, x14 // AES final block - round N high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + fmov d5, x6 // AES final block - mov low + fmov v5.d[1], x7 // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + eor v5.16b, v5.16b, v3.16b // AES final block - result + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low +.Lenc_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] // load existing bytes where the possibly partial last block is to be stored + mvn x14, xzr // rkN_h = 0xffffffffffffffff + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + fmov d0, x6 // ctr0b is mask for last block + fmov v0.d[1], x7 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + bif v5.16b, v18.16b, v0.16b // insert existing bytes in top end of result before storing + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + mov d8, v4.d[1] // GHASH final block - mid + rev w9, w12 + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + str w9, [x16, #12] // store the updated counter + st1 { v5.16b}, [x2] // store all 16B + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_enc_kernel,.-aes_gcm_enc_kernel +.globl aes_gcm_dec_kernel +.hidden aes_gcm_dec_kernel +.type aes_gcm_dec_kernel,%function +.align 4 +aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ldr q26, [x8, #128] // load rk8 + sub x5, x5, #1 // byte_len - 1 + ldr q25, [x8, #112] // load rk7 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add x4, x0, x1, lsr #3 // end_input_ptr + ldr q24, [x8, #96] // load rk6 + lsr x12, x11, #32 + ldr q23, [x8, #80] // load rk5 + orr w11, w11, w11 + ldr q21, [x8, #48] // load rk3 + add x5, x5, x0 + rev w12, w12 // rev_ctr32 + add w12, w12, #1 // increment rev_ctr32 + fmov d3, x10 // CTR block 3 + rev w9, w12 // CTR block 1 + add w12, w12, #1 // CTR block 1 + fmov d1, x10 // CTR block 1 + orr x9, x11, x9, lsl #32 // CTR block 1 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + fmov d2, x10 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 3 + ldr q18, [x8, #0] // load rk0 + fmov v3.d[1], x9 // CTR block 3 + add w12, w12, #1 // CTR block 3 + ldr q22, [x8, #64] // load rk4 + ldr q19, [x8, #16] // load rk1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q20, [x8, #32] // load rk2 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q27, [x8, #144] // load rk9 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q28, [x8, #160] // load rk10 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + ldr q29, [x8, #176] // load rk11 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + b.lt .Ldec_finish_first_blocks // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + b.eq .Ldec_finish_first_blocks // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +.Ldec_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v2.16b, v31.16b // AES block 2 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + aese v3.16b, v31.16b // AES block 3 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + b.ge .Ldec_tail // handle tail + + ldr q4, [x0, #0] // AES block 0 - load ciphertext + ldr q5, [x0, #16] // AES block 1 - load ciphertext + rev w9, w12 // CTR block 4 + eor v0.16b, v4.16b, v0.16b // AES block 0 - result + eor v1.16b, v5.16b, v1.16b // AES block 1 - result + rev64 v5.16b, v5.16b // GHASH block 1 + ldr q7, [x0, #48] // AES block 3 - load ciphertext + mov x7, v0.d[1] // AES block 0 - mov high + mov x6, v0.d[0] // AES block 0 - mov low + rev64 v4.16b, v4.16b // GHASH block 0 + add w12, w12, #1 // CTR block 4 + fmov d0, x10 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + mov x19, v1.d[0] // AES block 1 - mov low + orr x9, x11, x9, lsl #32 // CTR block 5 + mov x20, v1.d[1] // AES block 1 - mov high + eor x7, x7, x14 // AES block 0 - round N high + eor x6, x6, x13 // AES block 0 - round N low + stp x6, x7, [x2], #16 // AES block 0 - store result + fmov d1, x10 // CTR block 5 + ldr q6, [x0, #32] // AES block 2 - load ciphertext + add x0, x0, #64 // AES input_ptr update + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + add w12, w12, #1 // CTR block 6 + eor x19, x19, x13 // AES block 1 - round N low + orr x9, x11, x9, lsl #32 // CTR block 6 + eor x20, x20, x14 // AES block 1 - round N high + stp x19, x20, [x2], #16 // AES block 1 - store result + eor v2.16b, v6.16b, v2.16b // AES block 2 - result + cmp x0, x5 // check if we have <= 8 blocks + b.ge .Ldec_prepretail // do prepretail + +.Ldec_main_loop: // main loop start + mov x21, v2.d[0] // AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev w9, w12 // CTR block 4k+7 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x23, v3.d[0] // AES block 4k+3 - mov low + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov v3.d[1], x9 // CTR block 4k+7 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor x22, x22, x14 // AES block 4k+2 - round N high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x21, x21, x13 // AES block 4k+2 - round N low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor x23, x23, x13 // AES block 4k+3 - round N low + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor x24, x24, x14 // AES block 4k+3 - round N high + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + add w12, w12, #1 // CTR block 4k+7 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + rev w9, w12 // CTR block 4k+8 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + add w12, w12, #1 // CTR block 4k+8 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + b.lt .Ldec_main_loop_continue // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq .Ldec_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Ldec_main_loop_continue: + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + ldr q4, [x0, #0] // AES block 4k+4 - load ciphertext + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + ldr q5, [x0, #16] // AES block 4k+5 - load ciphertext + eor v0.16b, v4.16b, v0.16b // AES block 4k+4 - result + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + ldr q7, [x0, #48] // AES block 4k+7 - load ciphertext + ldr q6, [x0, #32] // AES block 4k+6 - load ciphertext + mov x7, v0.d[1] // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + add x0, x0, #64 // AES input_ptr update + mov x6, v0.d[0] // AES block 4k+4 - mov low + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b // AES block 4k+5 - result + rev w9, w12 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + cmp x0, x5 // .LOOP CONTROL + add w12, w12, #1 // CTR block 4k+9 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + mov x20, v1.d[1] // AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b // AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + mov x19, v1.d[0] // AES block 4k+5 - mov low + fmov d1, x10 // CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + fmov v1.d[1], x9 // CTR block 4k+9 + rev w9, w12 // CTR block 4k+10 + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + rev64 v5.16b, v5.16b // GHASH block 4k+5 + eor x20, x20, x14 // AES block 4k+5 - round N high + stp x6, x7, [x2], #16 // AES block 4k+4 - store result + eor x19, x19, x13 // AES block 4k+5 - round N low + stp x19, x20, [x2], #16 // AES block 4k+5 - store result + rev64 v4.16b, v4.16b // GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + b.lt .Ldec_main_loop + +.Ldec_prepretail: // PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + mov x21, v2.d[0] // AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + rev w9, w12 // CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + mov x23, v3.d[0] // AES block 4k+3 - mov low + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + fmov v3.d[1], x9 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + b.lt .Ldec_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + b.eq .Ldec_finish_prepretail // branch if AES-192 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +.Ldec_finish_prepretail: + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor x22, x22, x14 // AES block 4k+2 - round N high + eor x23, x23, x13 // AES block 4k+3 - round N low + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + add w12, w12, #1 // CTR block 4k+7 + eor x21, x21, x13 // AES block 4k+2 - round N low + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor x24, x24, x14 // AES block 4k+3 - round N high + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + +.Ldec_tail: // TAIL + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 // AES block 4k+4 - load ciphertext + eor v0.16b, v5.16b, v0.16b // AES block 4k+4 - result + mov x6, v0.d[0] // AES block 4k+4 - mov low + mov x7, v0.d[1] // AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + cmp x5, #48 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + b.gt .Ldec_blocks_more_than_3 + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + movi v11.8b, #0 + cmp x5, #32 + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt .Ldec_blocks_more_than_2 + sub w12, w12, #1 + mov v3.16b, v1.16b + cmp x5, #16 + b.gt .Ldec_blocks_more_than_1 + sub w12, w12, #1 + b .Ldec_blocks_less_than_1 +.Ldec_blocks_more_than_3: // blocks left > 3 + rev64 v4.16b, v5.16b // GHASH final-3 block + ld1 { v5.16b}, [x0], #16 // AES final-2 block - load ciphertext + stp x6, x7, [x2], #16 // AES final-3 block - store result + mov d10, v17.d[1] // GHASH final-3 block - mid + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor v0.16b, v5.16b, v1.16b // AES final-2 block - result + mov d22, v4.d[1] // GHASH final-3 block - mid + mov x6, v0.d[0] // AES final-2 block - mov low + mov x7, v0.d[1] // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor x6, x6, x13 // AES final-2 block - round N low + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + eor x7, x7, x14 // AES final-2 block - round N high +.Ldec_blocks_more_than_2: // blocks left > 2 + rev64 v4.16b, v5.16b // GHASH final-2 block + ld1 { v5.16b}, [x0], #16 // AES final-1 block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + stp x6, x7, [x2], #16 // AES final-2 block - store result + eor v0.16b, v5.16b, v2.16b // AES final-1 block - result + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + mov x6, v0.d[0] // AES final-1 block - mov low + mov x7, v0.d[1] // AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + movi v8.8b, #0 // suppress further partial tag feed in + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + eor x6, x6, x13 // AES final-1 block - round N low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid + eor x7, x7, x14 // AES final-1 block - round N high +.Ldec_blocks_more_than_1: // blocks left > 1 + stp x6, x7, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ld1 { v5.16b}, [x0], #16 // AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + mov d22, v4.d[1] // GHASH final-1 block - mid + eor v0.16b, v5.16b, v3.16b // AES final block - result + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + mov x6, v0.d[0] // AES final block - mov low + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + mov x7, v0.d[1] // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + eor x6, x6, x13 // AES final block - round N low + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor x7, x7, x14 // AES final block - round N high +.Ldec_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x14, xzr // rkN_h = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + ldp x4, x5, [x2] // load existing bytes we need to not overwrite + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + fmov d0, x9 // ctr0b is mask for last block + and x6, x6, x9 + mov v0.d[1], x10 + bic x4, x4, x9 // mask out low existing bytes + rev w9, w12 + bic x5, x5, x10 // mask out high existing bytes + orr x6, x6, x4 + and x7, x7, x10 + orr x7, x7, x5 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + mov d8, v4.d[1] // GHASH final block - mid + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + stp x6, x7, [x2] + str w9, [x16, #12] // store the updated counter + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_dec_kernel,.-aes_gcm_dec_kernel +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont-linux.S index db89859a..8ba78192 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/armv8-mont-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1431,6 +1430,8 @@ __bn_mul4x_mont: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 4 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/bn-armv8-linux.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/bn-armv8-linux.S new file mode 100644 index 00000000..d18381e4 --- /dev/null +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/bn-armv8-linux.S @@ -0,0 +1,101 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_add_words, %function +.globl bn_add_words +.hidden bn_add_words +.align 4 +bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, .Ladd_tail +.Ladd_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + adcs x4, x4, x6 + adcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, .Ladd_loop + +.Ladd_tail: + cbz x3, .Ladd_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + adcs x4, x4, x6 + str x4, [x0], #8 + +.Ladd_exit: + cset x0, cs + ret +.size bn_add_words,.-bn_add_words + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_sub_words, %function +.globl bn_sub_words +.hidden bn_sub_words +.align 4 +bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, .Lsub_tail +.Lsub_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + sbcs x4, x4, x6 + sbcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, .Lsub_loop + +.Lsub_tail: + cbz x3, .Lsub_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + sbcs x4, x4, x6 + str x4, [x0], #8 + +.Lsub_exit: + cset x0, cc + ret +.size bn_sub_words,.-bn_sub_words +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8-linux.S index 098967b5..1f814980 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -341,6 +340,8 @@ gcm_ghash_neon: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armv8-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armv8-linux.S index 9480a38a..bfe17cb9 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/ghashv8-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -120,7 +119,7 @@ gcm_gmult_v8: movi v19.16b,#0xe1 ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... shl v19.2d,v19.2d,#57 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v3.16b,v17.16b,v17.16b,#8 @@ -145,7 +144,7 @@ gcm_gmult_v8: eor v18.16b,v18.16b,v2.16b eor v0.16b,v0.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -184,14 +183,14 @@ gcm_ghash_v8: ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi ld1 {v16.2d},[x2],#16 //load [rotated] I[0] shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b rev64 v0.16b,v0.16b #endif ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] b.lo .Lodd_tail_v8 //x3 was less than 32 ld1 {v17.2d},[x2],x12 //load [rotated] I[1] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v7.16b,v17.16b,v17.16b,#8 @@ -223,13 +222,13 @@ gcm_ghash_v8: eor v18.16b,v0.16b,v2.16b eor v1.16b,v1.16b,v17.16b ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b #endif eor v1.16b,v1.16b,v18.16b pmull v18.1q,v0.1d,v19.1d //1st phase of reduction -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ins v2.d[0],v1.d[1] @@ -279,7 +278,7 @@ gcm_ghash_v8: eor v0.16b,v0.16b,v18.16b .Ldone_v8: -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -298,7 +297,7 @@ gcm_ghash_v8_4x: shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b @@ -342,7 +341,7 @@ gcm_ghash_v8_4x: eor v16.16b,v4.16b,v0.16b ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 ext v3.16b,v16.16b,v16.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v7.16b,v7.16b @@ -425,7 +424,7 @@ gcm_ghash_v8_4x: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d,v6.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v4.16b,v4.16b @@ -477,7 +476,7 @@ gcm_ghash_v8_4x: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v4.16b,v4.16b #endif @@ -520,7 +519,7 @@ gcm_ghash_v8_4x: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v4.16b,v4.16b #endif @@ -560,7 +559,7 @@ gcm_ghash_v8_4x: eor v0.16b,v0.16b,v18.16b ext v0.16b,v0.16b,v0.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif st1 {v0.2d},[x0] //write out Xi @@ -571,6 +570,8 @@ gcm_ghash_v8_4x: .align 2 .align 2 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256-armv8-asm-linux.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256-armv8-asm-linux.S new file mode 100644 index 00000000..accc3755 --- /dev/null +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256-armv8-asm-linux.S @@ -0,0 +1,1738 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.section .rodata +.align 5 +.Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +.Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lone: +.quad 1,0,0,0 +.Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.text + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont +.hidden ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,%function +.align 4 +ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont +.hidden ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,%function +.align 4 +ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 +.hidden ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,%function +.align 4 +ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 +.hidden ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,%function +.align 4 +ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 +.hidden ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,%function +.align 4 +ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub +.hidden ecp_nistz256_sub +.type ecp_nistz256_sub,%function +.align 4 +ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sub,.-ecp_nistz256_sub + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg +.hidden ecp_nistz256_neg +.type ecp_nistz256_neg,%function +.align 4 +ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_neg,.-ecp_nistz256_neg + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 +.type __ecp_nistz256_mul_mont,%function +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 +.type __ecp_nistz256_sqr_mont,%function +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.type __ecp_nistz256_add_to,%function +.align 4 +__ecp_nistz256_add_to: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_add_to,.-__ecp_nistz256_add_to + +.type __ecp_nistz256_sub_from,%function +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from + +.type __ecp_nistz256_sub_morf,%function +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf + +.type __ecp_nistz256_div_by_2,%function +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret +.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 +.globl ecp_nistz256_point_double +.hidden ecp_nistz256_point_double +.type ecp_nistz256_point_double,%function +.align 5 +ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +.Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + mov x8,x14 + ldr x13,[x13,#24] + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +.globl ecp_nistz256_point_add +.hidden ecp_nistz256_point_add +.type ecp_nistz256_point_add,%function +.align 5 +ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +.Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b .Ldouble_shortcut + +.align 4 +.Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +.Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +.globl ecp_nistz256_point_add_affine +.hidden ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,%function +.align 5 +ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,.Lpoly + add x13,x13,:lo12:.Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adrp x23,.Lone_mont-64 + add x23,x23,:lo12:.Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont +.hidden ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,%function +.align 4 +ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,.Lord + add x23,x23,:lo12:.Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl ecp_nistz256_ord_sqr_mont +.hidden ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,%function +.align 4 +ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,.Lord + add x23,x23,:lo12:.Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b .Loop_ord_sqr + +.align 4 +.Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,.Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w5 +.hidden ecp_nistz256_select_w5 +.type ecp_nistz256_select_w5,%function +.align 4 +ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // x10 := x0 + // w9 := 0; loop counter and incremented internal index + mov x10, x0 + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + movi v20.16b, #0 + movi v21.16b, #0 + +.Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v27] := Load a (3*256-bit = 6*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // continue loading ... + ld1 {v26.2d, v27.2d}, [x1],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + bit v20.16b, v26.16b, v3.16b + bit v21.16b, v27.16b, v3.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz w9, #4, .Lselect_w5_loop + + // Write [v16-v21] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x10],#64 + st1 {v20.2d, v21.2d}, [x10] + + ret +.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5 + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w7 +.hidden ecp_nistz256_select_w7 +.type ecp_nistz256_select_w7,%function +.align 4 +ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // w9 := 0; loop counter and incremented internal index + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + +.Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v25] := Load a (2*256-bit = 4*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz w9, #6, .Lselect_w7_loop + + // Write [v16-v19] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x0] + + ret +.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-linux.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-linux.S new file mode 100644 index 00000000..0f8645f7 --- /dev/null +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-linux.S @@ -0,0 +1,321 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.text +.globl beeu_mod_inverse_vartime +.hidden beeu_mod_inverse_vartime +.type beeu_mod_inverse_vartime, %function +.align 4 +beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp x25,x26,[x1] + ldp x27,x28,[x1,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp x0,x1,[x2] + ldp x2,x30,[x2,#16] + + // A = a3..a0 := n + mov x21, x0 + mov x22, x1 + mov x23, x2 + mov x24, x30 + + // X = x4..x0 := 1 + mov x3, #1 + eor x4, x4, x4 + eor x5, x5, x5 + eor x6, x6, x6 + eor x7, x7, x7 + + // Y = y4..y0 := 0 + eor x8, x8, x8 + eor x9, x9, x9 + eor x10, x10, x10 + eor x11, x11, x11 + eor x12, x12, x12 + +.Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + orr x14, x25, x26 + orr x14, x14, x27 + + // reverse the bit order of x25. This is needed for clz after this macro + rbit x15, x25 + + orr x14, x14, x28 + cbz x14,.Lbeeu_loop_end + + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in x25 + // ( = number of leading 0s in x15; see the "rbit" instruction in TEST_B_ZERO) + clz x13, x15 + + // If there is no shift, goto shift_A_Y + cbz x13, .Lbeeu_shift_A_Y + + // Shift B right by "x13" bits + neg x14, x13 + lsr x25, x25, x13 + lsl x15, x26, x14 + + lsr x26, x26, x13 + lsl x19, x27, x14 + + orr x25, x25, x15 + + lsr x27, x27, x13 + lsl x20, x28, x14 + + orr x26, x26, x19 + + lsr x28, x28, x13 + + orr x27, x27, x20 + + + // Shift X right by "x13" bits, adding n whenever X becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +.Lbeeu_shift_loop_X: + tbz x3, #0, .Lshift1_0 + adds x3, x3, x0 + adcs x4, x4, x1 + adcs x5, x5, x2 + adcs x6, x6, x30 + adc x7, x7, x14 +.Lshift1_0: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x3, x4, x3, #1 + extr x4, x5, x4, #1 + extr x5, x6, x5, #1 + extr x6, x7, x6, #1 + lsr x7, x7, #1 + + subs x13, x13, #1 + bne .Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "x13" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and x13 is decreased while executing the X loop. + // - SHIFT256(B, x13) is performed before right-shifting X; they are independent + +.Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of x21 + // x13 := number of trailing 0s in x21 (= number of leading 0s in x15) + rbit x15, x21 + clz x13, x15 + + // If there is no shift, goto |B-A|, X+Y update + cbz x13, .Lbeeu_update_B_X_or_A_Y + + // Shift A right by "x13" bits + neg x14, x13 + lsr x21, x21, x13 + lsl x15, x22, x14 + + lsr x22, x22, x13 + lsl x19, x23, x14 + + orr x21, x21, x15 + + lsr x23, x23, x13 + lsl x20, x24, x14 + + orr x22, x22, x19 + + lsr x24, x24, x13 + + orr x23, x23, x20 + + + // Shift Y right by "x13" bits, adding n whenever Y becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +.Lbeeu_shift_loop_Y: + tbz x8, #0, .Lshift1_1 + adds x8, x8, x0 + adcs x9, x9, x1 + adcs x10, x10, x2 + adcs x11, x11, x30 + adc x12, x12, x14 +.Lshift1_1: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x8, x9, x8, #1 + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + subs x13, x13, #1 + bne .Lbeeu_shift_loop_Y + +.Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs x14, x25, x21 + sbcs x15, x26, x22 + sbcs x19, x27, x23 + sbcs x20, x28, x24 + bcs .Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs x21, x21, x25 + sbcs x22, x22, x26 + sbcs x23, x23, x27 + sbcs x24, x24, x28 + + adds x8, x8, x3 + adcs x9, x9, x4 + adcs x10, x10, x5 + adcs x11, x11, x6 + adc x12, x12, x7 + b .Lbeeu_loop + +.Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov x25, x14 + mov x26, x15 + mov x27, x19 + mov x28, x20 + + adds x3, x3, x8 + adcs x4, x4, x9 + adcs x5, x5, x10 + adcs x6, x6, x11 + adc x7, x7, x12 + b .Lbeeu_loop + +.Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub x14, x21, #1 + orr x14, x14, x22 + orr x14, x14, x23 + orr x14, x14, x24 + cbnz x14, .Lbeeu_err + + // If Y>n ==> Y:=Y-n +.Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // (x14 = 0 from above) + subs x3, x8, x0 + sbcs x4, x9, x1 + sbcs x5, x10, x2 + sbcs x6, x11, x30 + sbcs x7, x12, x14 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel x8, x3, x8, cs + csel x9, x4, x9, cs + csel x10, x5, x10, cs + csel x11, x6, x11, cs + csel x12, x7, x12, cs + bcs .Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs x8, x0, x8 + sbcs x9, x1, x9 + sbcs x10, x2, x10 + sbcs x11, x30, x11 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp x8, x9, [x3] + stp x10, x11, [x3,#16] + // return 1 (success) + mov x0, #1 + b .Lbeeu_finish + +.Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +.Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size beeu_mod_inverse_vartime,.-beeu_mod_inverse_vartime +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8-linux.S index 838ec329..079f2723 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha1-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -52,7 +51,7 @@ sha1_block_data_order: movz w28,#0x7999 sub x2,x2,#1 movk w28,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x3,x3,#32 #else rev32 x3,x3 @@ -70,7 +69,7 @@ sha1_block_data_order: ror w21,w21,#2 add w23,w23,w4 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x5,x5,#32 #else rev32 x5,x5 @@ -95,7 +94,7 @@ sha1_block_data_order: ror w24,w24,#2 add w21,w21,w6 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x7,x7,#32 #else rev32 x7,x7 @@ -120,7 +119,7 @@ sha1_block_data_order: ror w22,w22,#2 add w24,w24,w8 // future e+=X[i] add w20,w20,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x9,x9,#32 #else rev32 x9,x9 @@ -145,7 +144,7 @@ sha1_block_data_order: ror w20,w20,#2 add w22,w22,w10 // future e+=X[i] add w23,w23,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x11,x11,#32 #else rev32 x11,x11 @@ -170,7 +169,7 @@ sha1_block_data_order: ror w23,w23,#2 add w20,w20,w12 // future e+=X[i] add w21,w21,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x13,x13,#32 #else rev32 x13,x13 @@ -195,7 +194,7 @@ sha1_block_data_order: ror w21,w21,#2 add w23,w23,w14 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x15,x15,#32 #else rev32 x15,x15 @@ -220,7 +219,7 @@ sha1_block_data_order: ror w24,w24,#2 add w21,w21,w16 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x17,x17,#32 #else rev32 x17,x17 @@ -1233,6 +1232,8 @@ sha1_block_armv8: .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8-linux.S index a4f170ec..98a685f1 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha256-armv8-linux.S @@ -8,12 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -41,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -49,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -101,7 +101,7 @@ sha256_block_data_order: ldr w19,[x30],#4 // *K++ eor w28,w21,w22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w3,w3 // 0 #endif ror w16,w24,#6 @@ -124,7 +124,7 @@ sha256_block_data_order: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w4,w4 // 1 #endif ldp w5,w6,[x1],#2*4 @@ -149,7 +149,7 @@ sha256_block_data_order: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w5,w5 // 2 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -173,7 +173,7 @@ sha256_block_data_order: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w6,w6 // 3 #endif ldp w7,w8,[x1],#2*4 @@ -198,7 +198,7 @@ sha256_block_data_order: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w7,w7 // 4 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -222,7 +222,7 @@ sha256_block_data_order: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8,w8 // 5 #endif ldp w9,w10,[x1],#2*4 @@ -247,7 +247,7 @@ sha256_block_data_order: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w9,w9 // 6 #endif add w22,w22,w17 // h+=Sigma0(a) @@ -271,7 +271,7 @@ sha256_block_data_order: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w10,w10 // 7 #endif ldp w11,w12,[x1],#2*4 @@ -296,7 +296,7 @@ sha256_block_data_order: add w20,w20,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w20,w20,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w11,w11 // 8 #endif add w20,w20,w17 // h+=Sigma0(a) @@ -320,7 +320,7 @@ sha256_block_data_order: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w12,w12 // 9 #endif ldp w13,w14,[x1],#2*4 @@ -345,7 +345,7 @@ sha256_block_data_order: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w13,w13 // 10 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -369,7 +369,7 @@ sha256_block_data_order: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w14,w14 // 11 #endif ldp w15,w0,[x1],#2*4 @@ -395,7 +395,7 @@ sha256_block_data_order: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w15,w15 // 12 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -420,7 +420,7 @@ sha256_block_data_order: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w0,w0 // 13 #endif ldp w1,w2,[x1] @@ -446,7 +446,7 @@ sha256_block_data_order: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w1,w1 // 14 #endif ldr w6,[sp,#12] @@ -472,7 +472,7 @@ sha256_block_data_order: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w2,w2 // 15 #endif ldr w7,[sp,#0] @@ -1209,6 +1209,8 @@ sha256_block_armv8: ret .size sha256_block_armv8,.-sha256_block_armv8 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8-linux.S similarity index 60% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8-linux.S index 98b7a7e2..5e2f8857 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/sha512-armv8-linux.S @@ -8,12 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -41,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -49,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -65,6 +65,17 @@ .type sha512_block_data_order,%function .align 6 sha512_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x16,OPENSSL_armcap_P +#endif + ldr w16,[x16,:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA512 + b.ne .Lv8_entry +#endif AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -90,7 +101,7 @@ sha512_block_data_order: ldr x19,[x30],#8 // *K++ eor x28,x21,x22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x3,x3 // 0 #endif ror x16,x24,#14 @@ -113,7 +124,7 @@ sha512_block_data_order: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x4,x4 // 1 #endif ldp x5,x6,[x1],#2*8 @@ -138,7 +149,7 @@ sha512_block_data_order: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x5,x5 // 2 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -162,7 +173,7 @@ sha512_block_data_order: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x6,x6 // 3 #endif ldp x7,x8,[x1],#2*8 @@ -187,7 +198,7 @@ sha512_block_data_order: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x7,x7 // 4 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -211,7 +222,7 @@ sha512_block_data_order: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x8,x8 // 5 #endif ldp x9,x10,[x1],#2*8 @@ -236,7 +247,7 @@ sha512_block_data_order: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x9,x9 // 6 #endif add x22,x22,x17 // h+=Sigma0(a) @@ -260,7 +271,7 @@ sha512_block_data_order: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x10,x10 // 7 #endif ldp x11,x12,[x1],#2*8 @@ -285,7 +296,7 @@ sha512_block_data_order: add x20,x20,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x20,x20,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x11,x11 // 8 #endif add x20,x20,x17 // h+=Sigma0(a) @@ -309,7 +320,7 @@ sha512_block_data_order: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x12,x12 // 9 #endif ldp x13,x14,[x1],#2*8 @@ -334,7 +345,7 @@ sha512_block_data_order: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x13,x13 // 10 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -358,7 +369,7 @@ sha512_block_data_order: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x14,x14 // 11 #endif ldp x15,x0,[x1],#2*8 @@ -384,7 +395,7 @@ sha512_block_data_order: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x15,x15 // 12 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -409,7 +420,7 @@ sha512_block_data_order: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x0,x0 // 13 #endif ldp x1,x2,[x1] @@ -435,7 +446,7 @@ sha512_block_data_order: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x1,x1 // 14 #endif ldr x6,[sp,#24] @@ -461,7 +472,7 @@ sha512_block_data_order: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x2,x2 // 15 #endif ldr x7,[sp,#0] @@ -1079,6 +1090,529 @@ sha512_block_data_order: .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +.text +#ifndef __KERNEL__ +.type sha512_block_armv8,%function +.align 6 +sha512_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adrp x3,.LK512 + add x3,x3,:lo12:.LK512 + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b .Loop_hw + +.align 4 +.Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,.Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret +.size sha512_block_armv8,.-sha512_block_armv8 +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8-linux.S index 59b1d31d..a4c2f83f 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/fipsmodule/vpaes-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1230,6 +1229,8 @@ vpaes_ctr32_encrypt_blocks: AARCH64_VALIDATE_LINK_REGISTER ret .size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8.S b/third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8.S rename to third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8-linux.S index 8928d7f5..08e0bc35 100644 --- a/third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8.S +++ b/third_party/boringssl/kit/linux-aarch64/crypto/test/trampoline-armv8-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -756,6 +755,8 @@ abi_test_clobber_v15_upper: fmov v15.d[1], xzr ret .size abi_test_clobber_v15_upper,.-abi_test_clobber_v15_upper +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4.S b/third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4.S rename to third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4-linux.S index 363aeee5..8de81965 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4.S +++ b/third_party/boringssl/kit/linux-arm/crypto/chacha/chacha-armv4-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1488,6 +1487,8 @@ ChaCha20_neon: .size ChaCha20_neon,.-ChaCha20_neon .comm OPENSSL_armcap_P,4,4 #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armx32.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armv7-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armx32.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armv7-linux.S index 30c6525d..e44cb77c 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armx32.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/aesv8-armv7-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -795,6 +794,8 @@ aes_hw_ctr32_encrypt_blocks: ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,pc} .size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont-linux.S index 02968947..4cbd5fac 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/armv4-mont-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -972,6 +971,8 @@ bn_mul8x_mont_neon: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7-linux.S index 69a8fcac..45ae4b01 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/bsaes-armv7-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1524,6 +1523,8 @@ bsaes_ctr32_encrypt_blocks: @ out to retain a constant-time implementation. .size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4-linux.S index 0532695a..57ca0983 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghash-armv4-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -250,6 +249,8 @@ gcm_ghash_neon: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armx32.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armv7-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armx32.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armv7-linux.S index 096dfb74..46fa9181 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armx32.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/ghashv8-armv7-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -252,6 +251,8 @@ gcm_ghash_v8: .align 2 .align 2 #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large-linux.S index 61deddf8..4e7aa299 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha1-armv4-large-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1506,6 +1505,8 @@ sha1_block_data_order_armv8: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4-linux.S index aee04785..eaa5701e 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha256-armv4-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2834,6 +2833,8 @@ sha256_block_data_order_armv8: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4-linux.S index a06d41fe..02489b86 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/sha512-armv4-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1889,6 +1888,8 @@ sha512_block_data_order_neon: .comm OPENSSL_armcap_P,4,4 .hidden OPENSSL_armcap_P #endif +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7.S b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7.S rename to third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7-linux.S index e5ad6ed9..dd354ef4 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7.S +++ b/third_party/boringssl/kit/linux-arm/crypto/fipsmodule/vpaes-armv7-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1231,6 +1230,8 @@ vpaes_ctr32_encrypt_blocks: vldmia sp!, {d8,d9,d10,d11,d12,d13,d14,d15} ldmia sp!, {r7,r8,r9,r10,r11, pc} @ return .size vpaes_ctr32_encrypt_blocks,.-vpaes_ctr32_encrypt_blocks +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4.S b/third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4.S rename to third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4-linux.S index 9a73ba82..4649b043 100644 --- a/third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4.S +++ b/third_party/boringssl/kit/linux-arm/crypto/test/trampoline-armv4-linux.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__arm__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -374,6 +373,8 @@ abi_test_clobber_d15: vmov s31, r0 bx lr .size abi_test_clobber_d15,.-abi_test_clobber_d15 +#endif // !OPENSSL_NO_ASM && defined(__ARMEL__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM -.section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/aesp8-ppc.S b/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/aesp8-ppc.S deleted file mode 100644 index ea2a7f68..00000000 --- a/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/aesp8-ppc.S +++ /dev/null @@ -1,3670 +0,0 @@ -// This file is generated from a similarly-named Perl script in the BoringSSL -// source tree. Do not edit by hand. - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) -#define OPENSSL_NO_ASM -#endif -#endif - -#if !defined(OPENSSL_NO_ASM) && defined(__powerpc64__) -.machine "any" - -.abiversion 2 -.text - -.align 7 -.Lrcon: -.byte 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01 -.byte 0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x1b -.byte 0x0c,0x0f,0x0e,0x0d,0x0c,0x0f,0x0e,0x0d,0x0c,0x0f,0x0e,0x0d,0x0c,0x0f,0x0e,0x0d -.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -.Lconsts: - mflr 0 - bcl 20,31,$+4 - mflr 6 - addi 6,6,-0x48 - mtlr 0 - blr -.long 0 -.byte 0,12,0x14,0,0,0,0,0 -.byte 65,69,83,32,102,111,114,32,80,111,119,101,114,73,83,65,32,50,46,48,55,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 -.align 2 - -.globl aes_hw_set_encrypt_key -.type aes_hw_set_encrypt_key,@function -.align 5 -aes_hw_set_encrypt_key: -.localentry aes_hw_set_encrypt_key,0 - -.Lset_encrypt_key: - mflr 11 - std 11,16(1) - - li 6,-1 - cmpldi 3,0 - beq- .Lenc_key_abort - cmpldi 5,0 - beq- .Lenc_key_abort - li 6,-2 - cmpwi 4,128 - blt- .Lenc_key_abort - cmpwi 4,256 - bgt- .Lenc_key_abort - andi. 0,4,0x3f - bne- .Lenc_key_abort - - lis 0,0xfff0 - li 12,-1 - or 0,0,0 - - bl .Lconsts - mtlr 11 - - neg 9,3 - lvx 1,0,3 - addi 3,3,15 - lvsr 3,0,9 - li 8,0x20 - cmpwi 4,192 - lvx 2,0,3 - vspltisb 5,0x0f - lvx 4,0,6 - vxor 3,3,5 - lvx 5,8,6 - addi 6,6,0x10 - vperm 1,1,2,3 - li 7,8 - vxor 0,0,0 - mtctr 7 - - lvsl 8,0,5 - vspltisb 9,-1 - lvx 10,0,5 - vperm 9,9,0,8 - - blt .Loop128 - addi 3,3,8 - beq .L192 - addi 3,3,8 - b .L256 - -.align 4 -.Loop128: - vperm 3,1,1,5 - vsldoi 6,0,1,12 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - .long 0x10632509 - stvx 7,0,5 - addi 5,5,16 - - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vadduwm 4,4,4 - vxor 1,1,3 - bdnz .Loop128 - - lvx 4,0,6 - - vperm 3,1,1,5 - vsldoi 6,0,1,12 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - .long 0x10632509 - stvx 7,0,5 - addi 5,5,16 - - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vadduwm 4,4,4 - vxor 1,1,3 - - vperm 3,1,1,5 - vsldoi 6,0,1,12 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - .long 0x10632509 - stvx 7,0,5 - addi 5,5,16 - - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vxor 1,1,3 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - stvx 7,0,5 - - addi 3,5,15 - addi 5,5,0x50 - - li 8,10 - b .Ldone - -.align 4 -.L192: - lvx 6,0,3 - li 7,4 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - stvx 7,0,5 - addi 5,5,16 - vperm 2,2,6,3 - vspltisb 3,8 - mtctr 7 - vsububm 5,5,3 - -.Loop192: - vperm 3,2,2,5 - vsldoi 6,0,1,12 - .long 0x10632509 - - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - - vsldoi 7,0,2,8 - vspltw 6,1,3 - vxor 6,6,2 - vsldoi 2,0,2,12 - vadduwm 4,4,4 - vxor 2,2,6 - vxor 1,1,3 - vxor 2,2,3 - vsldoi 7,7,1,8 - - vperm 3,2,2,5 - vsldoi 6,0,1,12 - vperm 11,7,7,8 - vsel 7,10,11,9 - vor 10,11,11 - .long 0x10632509 - stvx 7,0,5 - addi 5,5,16 - - vsldoi 7,1,2,8 - vxor 1,1,6 - vsldoi 6,0,6,12 - vperm 11,7,7,8 - vsel 7,10,11,9 - vor 10,11,11 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - stvx 7,0,5 - addi 5,5,16 - - vspltw 6,1,3 - vxor 6,6,2 - vsldoi 2,0,2,12 - vadduwm 4,4,4 - vxor 2,2,6 - vxor 1,1,3 - vxor 2,2,3 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - stvx 7,0,5 - addi 3,5,15 - addi 5,5,16 - bdnz .Loop192 - - li 8,12 - addi 5,5,0x20 - b .Ldone - -.align 4 -.L256: - lvx 6,0,3 - li 7,7 - li 8,14 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - stvx 7,0,5 - addi 5,5,16 - vperm 2,2,6,3 - mtctr 7 - -.Loop256: - vperm 3,2,2,5 - vsldoi 6,0,1,12 - vperm 11,2,2,8 - vsel 7,10,11,9 - vor 10,11,11 - .long 0x10632509 - stvx 7,0,5 - addi 5,5,16 - - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vsldoi 6,0,6,12 - vxor 1,1,6 - vadduwm 4,4,4 - vxor 1,1,3 - vperm 11,1,1,8 - vsel 7,10,11,9 - vor 10,11,11 - stvx 7,0,5 - addi 3,5,15 - addi 5,5,16 - bdz .Ldone - - vspltw 3,1,3 - vsldoi 6,0,2,12 - .long 0x106305C8 - - vxor 2,2,6 - vsldoi 6,0,6,12 - vxor 2,2,6 - vsldoi 6,0,6,12 - vxor 2,2,6 - - vxor 2,2,3 - b .Loop256 - -.align 4 -.Ldone: - lvx 2,0,3 - vsel 2,10,2,9 - stvx 2,0,3 - li 6,0 - or 12,12,12 - stw 8,0(5) - -.Lenc_key_abort: - mr 3,6 - blr -.long 0 -.byte 0,12,0x14,1,0,0,3,0 -.long 0 -.size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key - -.globl aes_hw_set_decrypt_key -.type aes_hw_set_decrypt_key,@function -.align 5 -aes_hw_set_decrypt_key: -.localentry aes_hw_set_decrypt_key,0 - - stdu 1,-64(1) - mflr 10 - std 10,80(1) - bl .Lset_encrypt_key - mtlr 10 - - cmpwi 3,0 - bne- .Ldec_key_abort - - slwi 7,8,4 - subi 3,5,240 - srwi 8,8,1 - add 5,3,7 - mtctr 8 - -.Ldeckey: - lwz 0, 0(3) - lwz 6, 4(3) - lwz 7, 8(3) - lwz 8, 12(3) - addi 3,3,16 - lwz 9, 0(5) - lwz 10,4(5) - lwz 11,8(5) - lwz 12,12(5) - stw 0, 0(5) - stw 6, 4(5) - stw 7, 8(5) - stw 8, 12(5) - subi 5,5,16 - stw 9, -16(3) - stw 10,-12(3) - stw 11,-8(3) - stw 12,-4(3) - bdnz .Ldeckey - - xor 3,3,3 -.Ldec_key_abort: - addi 1,1,64 - blr -.long 0 -.byte 0,12,4,1,0x80,0,3,0 -.long 0 -.size aes_hw_set_decrypt_key,.-aes_hw_set_decrypt_key -.globl aes_hw_encrypt -.type aes_hw_encrypt,@function -.align 5 -aes_hw_encrypt: -.localentry aes_hw_encrypt,0 - - lwz 6,240(5) - lis 0,0xfc00 - li 12,-1 - li 7,15 - or 0,0,0 - - lvx 0,0,3 - neg 11,4 - lvx 1,7,3 - lvsl 2,0,3 - vspltisb 4,0x0f - lvsr 3,0,11 - vxor 2,2,4 - li 7,16 - vperm 0,0,1,2 - lvx 1,0,5 - lvsr 5,0,5 - srwi 6,6,1 - lvx 2,7,5 - addi 7,7,16 - subi 6,6,1 - vperm 1,2,1,5 - - vxor 0,0,1 - lvx 1,7,5 - addi 7,7,16 - mtctr 6 - -.Loop_enc: - vperm 2,1,2,5 - .long 0x10001508 - lvx 2,7,5 - addi 7,7,16 - vperm 1,2,1,5 - .long 0x10000D08 - lvx 1,7,5 - addi 7,7,16 - bdnz .Loop_enc - - vperm 2,1,2,5 - .long 0x10001508 - lvx 2,7,5 - vperm 1,2,1,5 - .long 0x10000D09 - - vspltisb 2,-1 - vxor 1,1,1 - li 7,15 - vperm 2,2,1,3 - vxor 3,3,4 - lvx 1,0,4 - vperm 0,0,0,3 - vsel 1,1,0,2 - lvx 4,7,4 - stvx 1,0,4 - vsel 0,0,4,2 - stvx 0,7,4 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,3,0 -.long 0 -.size aes_hw_encrypt,.-aes_hw_encrypt -.globl aes_hw_decrypt -.type aes_hw_decrypt,@function -.align 5 -aes_hw_decrypt: -.localentry aes_hw_decrypt,0 - - lwz 6,240(5) - lis 0,0xfc00 - li 12,-1 - li 7,15 - or 0,0,0 - - lvx 0,0,3 - neg 11,4 - lvx 1,7,3 - lvsl 2,0,3 - vspltisb 4,0x0f - lvsr 3,0,11 - vxor 2,2,4 - li 7,16 - vperm 0,0,1,2 - lvx 1,0,5 - lvsr 5,0,5 - srwi 6,6,1 - lvx 2,7,5 - addi 7,7,16 - subi 6,6,1 - vperm 1,2,1,5 - - vxor 0,0,1 - lvx 1,7,5 - addi 7,7,16 - mtctr 6 - -.Loop_dec: - vperm 2,1,2,5 - .long 0x10001548 - lvx 2,7,5 - addi 7,7,16 - vperm 1,2,1,5 - .long 0x10000D48 - lvx 1,7,5 - addi 7,7,16 - bdnz .Loop_dec - - vperm 2,1,2,5 - .long 0x10001548 - lvx 2,7,5 - vperm 1,2,1,5 - .long 0x10000D49 - - vspltisb 2,-1 - vxor 1,1,1 - li 7,15 - vperm 2,2,1,3 - vxor 3,3,4 - lvx 1,0,4 - vperm 0,0,0,3 - vsel 1,1,0,2 - lvx 4,7,4 - stvx 1,0,4 - vsel 0,0,4,2 - stvx 0,7,4 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,3,0 -.long 0 -.size aes_hw_decrypt,.-aes_hw_decrypt -.globl aes_hw_cbc_encrypt -.type aes_hw_cbc_encrypt,@function -.align 5 -aes_hw_cbc_encrypt: -.localentry aes_hw_cbc_encrypt,0 - - cmpldi 5,16 - .long 0x4dc00020 - - cmpwi 8,0 - lis 0,0xffe0 - li 12,-1 - or 0,0,0 - - li 10,15 - vxor 0,0,0 - vspltisb 3,0x0f - - lvx 4,0,7 - lvsl 6,0,7 - lvx 5,10,7 - vxor 6,6,3 - vperm 4,4,5,6 - - neg 11,3 - lvsr 10,0,6 - lwz 9,240(6) - - lvsr 6,0,11 - lvx 5,0,3 - addi 3,3,15 - vxor 6,6,3 - - lvsl 8,0,4 - vspltisb 9,-1 - lvx 7,0,4 - vperm 9,9,0,8 - vxor 8,8,3 - - srwi 9,9,1 - li 10,16 - subi 9,9,1 - beq .Lcbc_dec - -.Lcbc_enc: - vor 2,5,5 - lvx 5,0,3 - addi 3,3,16 - mtctr 9 - subi 5,5,16 - - lvx 0,0,6 - vperm 2,2,5,6 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - vxor 2,2,0 - lvx 0,10,6 - addi 10,10,16 - vxor 2,2,4 - -.Loop_cbc_enc: - vperm 1,0,1,10 - .long 0x10420D08 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - .long 0x10420508 - lvx 0,10,6 - addi 10,10,16 - bdnz .Loop_cbc_enc - - vperm 1,0,1,10 - .long 0x10420D08 - lvx 1,10,6 - li 10,16 - vperm 0,1,0,10 - .long 0x10820509 - cmpldi 5,16 - - vperm 3,4,4,8 - vsel 2,7,3,9 - vor 7,3,3 - stvx 2,0,4 - addi 4,4,16 - bge .Lcbc_enc - - b .Lcbc_done - -.align 4 -.Lcbc_dec: - cmpldi 5,128 - bge _aesp8_cbc_decrypt8x - vor 3,5,5 - lvx 5,0,3 - addi 3,3,16 - mtctr 9 - subi 5,5,16 - - lvx 0,0,6 - vperm 3,3,5,6 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - vxor 2,3,0 - lvx 0,10,6 - addi 10,10,16 - -.Loop_cbc_dec: - vperm 1,0,1,10 - .long 0x10420D48 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - .long 0x10420548 - lvx 0,10,6 - addi 10,10,16 - bdnz .Loop_cbc_dec - - vperm 1,0,1,10 - .long 0x10420D48 - lvx 1,10,6 - li 10,16 - vperm 0,1,0,10 - .long 0x10420549 - cmpldi 5,16 - - vxor 2,2,4 - vor 4,3,3 - vperm 3,2,2,8 - vsel 2,7,3,9 - vor 7,3,3 - stvx 2,0,4 - addi 4,4,16 - bge .Lcbc_dec - -.Lcbc_done: - addi 4,4,-1 - lvx 2,0,4 - vsel 2,7,2,9 - stvx 2,0,4 - - neg 8,7 - li 10,15 - vxor 0,0,0 - vspltisb 9,-1 - vspltisb 3,0x0f - lvsr 8,0,8 - vperm 9,9,0,8 - vxor 8,8,3 - lvx 7,0,7 - vperm 4,4,4,8 - vsel 2,7,4,9 - lvx 5,10,7 - stvx 2,0,7 - vsel 2,4,5,9 - stvx 2,10,7 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,6,0 -.long 0 -.align 5 -_aesp8_cbc_decrypt8x: - stdu 1,-448(1) - li 10,207 - li 11,223 - stvx 20,10,1 - addi 10,10,32 - stvx 21,11,1 - addi 11,11,32 - stvx 22,10,1 - addi 10,10,32 - stvx 23,11,1 - addi 11,11,32 - stvx 24,10,1 - addi 10,10,32 - stvx 25,11,1 - addi 11,11,32 - stvx 26,10,1 - addi 10,10,32 - stvx 27,11,1 - addi 11,11,32 - stvx 28,10,1 - addi 10,10,32 - stvx 29,11,1 - addi 11,11,32 - stvx 30,10,1 - stvx 31,11,1 - li 0,-1 - stw 12,396(1) - li 8,0x10 - std 26,400(1) - li 26,0x20 - std 27,408(1) - li 27,0x30 - std 28,416(1) - li 28,0x40 - std 29,424(1) - li 29,0x50 - std 30,432(1) - li 30,0x60 - std 31,440(1) - li 31,0x70 - or 0,0,0 - - subi 9,9,3 - subi 5,5,128 - - lvx 23,0,6 - lvx 30,8,6 - addi 6,6,0x20 - lvx 31,0,6 - vperm 23,30,23,10 - addi 11,1,79 - mtctr 9 - -.Load_cbc_dec_key: - vperm 24,31,30,10 - lvx 30,8,6 - addi 6,6,0x20 - stvx 24,0,11 - vperm 25,30,31,10 - lvx 31,0,6 - stvx 25,8,11 - addi 11,11,0x20 - bdnz .Load_cbc_dec_key - - lvx 26,8,6 - vperm 24,31,30,10 - lvx 27,26,6 - stvx 24,0,11 - vperm 25,26,31,10 - lvx 28,27,6 - stvx 25,8,11 - addi 11,1,79 - vperm 26,27,26,10 - lvx 29,28,6 - vperm 27,28,27,10 - lvx 30,29,6 - vperm 28,29,28,10 - lvx 31,30,6 - vperm 29,30,29,10 - lvx 14,31,6 - vperm 30,31,30,10 - lvx 24,0,11 - vperm 31,14,31,10 - lvx 25,8,11 - - - - subi 3,3,15 - - li 10,8 - .long 0x7C001E99 - lvsl 6,0,10 - vspltisb 3,0x0f - .long 0x7C281E99 - vxor 6,6,3 - .long 0x7C5A1E99 - vperm 0,0,0,6 - .long 0x7C7B1E99 - vperm 1,1,1,6 - .long 0x7D5C1E99 - vperm 2,2,2,6 - vxor 14,0,23 - .long 0x7D7D1E99 - vperm 3,3,3,6 - vxor 15,1,23 - .long 0x7D9E1E99 - vperm 10,10,10,6 - vxor 16,2,23 - .long 0x7DBF1E99 - addi 3,3,0x80 - vperm 11,11,11,6 - vxor 17,3,23 - vperm 12,12,12,6 - vxor 18,10,23 - vperm 13,13,13,6 - vxor 19,11,23 - vxor 20,12,23 - vxor 21,13,23 - - mtctr 9 - b .Loop_cbc_dec8x -.align 5 -.Loop_cbc_dec8x: - .long 0x11CEC548 - .long 0x11EFC548 - .long 0x1210C548 - .long 0x1231C548 - .long 0x1252C548 - .long 0x1273C548 - .long 0x1294C548 - .long 0x12B5C548 - lvx 24,26,11 - addi 11,11,0x20 - - .long 0x11CECD48 - .long 0x11EFCD48 - .long 0x1210CD48 - .long 0x1231CD48 - .long 0x1252CD48 - .long 0x1273CD48 - .long 0x1294CD48 - .long 0x12B5CD48 - lvx 25,8,11 - bdnz .Loop_cbc_dec8x - - subic 5,5,128 - .long 0x11CEC548 - .long 0x11EFC548 - .long 0x1210C548 - .long 0x1231C548 - .long 0x1252C548 - .long 0x1273C548 - .long 0x1294C548 - .long 0x12B5C548 - - subfe. 0,0,0 - .long 0x11CECD48 - .long 0x11EFCD48 - .long 0x1210CD48 - .long 0x1231CD48 - .long 0x1252CD48 - .long 0x1273CD48 - .long 0x1294CD48 - .long 0x12B5CD48 - - and 0,0,5 - .long 0x11CED548 - .long 0x11EFD548 - .long 0x1210D548 - .long 0x1231D548 - .long 0x1252D548 - .long 0x1273D548 - .long 0x1294D548 - .long 0x12B5D548 - - add 3,3,0 - - - - .long 0x11CEDD48 - .long 0x11EFDD48 - .long 0x1210DD48 - .long 0x1231DD48 - .long 0x1252DD48 - .long 0x1273DD48 - .long 0x1294DD48 - .long 0x12B5DD48 - - addi 11,1,79 - .long 0x11CEE548 - .long 0x11EFE548 - .long 0x1210E548 - .long 0x1231E548 - .long 0x1252E548 - .long 0x1273E548 - .long 0x1294E548 - .long 0x12B5E548 - lvx 24,0,11 - - .long 0x11CEED48 - .long 0x11EFED48 - .long 0x1210ED48 - .long 0x1231ED48 - .long 0x1252ED48 - .long 0x1273ED48 - .long 0x1294ED48 - .long 0x12B5ED48 - lvx 25,8,11 - - .long 0x11CEF548 - vxor 4,4,31 - .long 0x11EFF548 - vxor 0,0,31 - .long 0x1210F548 - vxor 1,1,31 - .long 0x1231F548 - vxor 2,2,31 - .long 0x1252F548 - vxor 3,3,31 - .long 0x1273F548 - vxor 10,10,31 - .long 0x1294F548 - vxor 11,11,31 - .long 0x12B5F548 - vxor 12,12,31 - - .long 0x11CE2549 - .long 0x11EF0549 - .long 0x7C001E99 - .long 0x12100D49 - .long 0x7C281E99 - .long 0x12311549 - vperm 0,0,0,6 - .long 0x7C5A1E99 - .long 0x12521D49 - vperm 1,1,1,6 - .long 0x7C7B1E99 - .long 0x12735549 - vperm 2,2,2,6 - .long 0x7D5C1E99 - .long 0x12945D49 - vperm 3,3,3,6 - .long 0x7D7D1E99 - .long 0x12B56549 - vperm 10,10,10,6 - .long 0x7D9E1E99 - vor 4,13,13 - vperm 11,11,11,6 - .long 0x7DBF1E99 - addi 3,3,0x80 - - vperm 14,14,14,6 - vperm 15,15,15,6 - .long 0x7DC02799 - vperm 12,12,12,6 - vxor 14,0,23 - vperm 16,16,16,6 - .long 0x7DE82799 - vperm 13,13,13,6 - vxor 15,1,23 - vperm 17,17,17,6 - .long 0x7E1A2799 - vxor 16,2,23 - vperm 18,18,18,6 - .long 0x7E3B2799 - vxor 17,3,23 - vperm 19,19,19,6 - .long 0x7E5C2799 - vxor 18,10,23 - vperm 20,20,20,6 - .long 0x7E7D2799 - vxor 19,11,23 - vperm 21,21,21,6 - .long 0x7E9E2799 - vxor 20,12,23 - .long 0x7EBF2799 - addi 4,4,0x80 - vxor 21,13,23 - - mtctr 9 - beq .Loop_cbc_dec8x - - addic. 5,5,128 - beq .Lcbc_dec8x_done - nop - nop - -.Loop_cbc_dec8x_tail: - .long 0x11EFC548 - .long 0x1210C548 - .long 0x1231C548 - .long 0x1252C548 - .long 0x1273C548 - .long 0x1294C548 - .long 0x12B5C548 - lvx 24,26,11 - addi 11,11,0x20 - - .long 0x11EFCD48 - .long 0x1210CD48 - .long 0x1231CD48 - .long 0x1252CD48 - .long 0x1273CD48 - .long 0x1294CD48 - .long 0x12B5CD48 - lvx 25,8,11 - bdnz .Loop_cbc_dec8x_tail - - .long 0x11EFC548 - .long 0x1210C548 - .long 0x1231C548 - .long 0x1252C548 - .long 0x1273C548 - .long 0x1294C548 - .long 0x12B5C548 - - .long 0x11EFCD48 - .long 0x1210CD48 - .long 0x1231CD48 - .long 0x1252CD48 - .long 0x1273CD48 - .long 0x1294CD48 - .long 0x12B5CD48 - - .long 0x11EFD548 - .long 0x1210D548 - .long 0x1231D548 - .long 0x1252D548 - .long 0x1273D548 - .long 0x1294D548 - .long 0x12B5D548 - - .long 0x11EFDD48 - .long 0x1210DD48 - .long 0x1231DD48 - .long 0x1252DD48 - .long 0x1273DD48 - .long 0x1294DD48 - .long 0x12B5DD48 - - .long 0x11EFE548 - .long 0x1210E548 - .long 0x1231E548 - .long 0x1252E548 - .long 0x1273E548 - .long 0x1294E548 - .long 0x12B5E548 - - .long 0x11EFED48 - .long 0x1210ED48 - .long 0x1231ED48 - .long 0x1252ED48 - .long 0x1273ED48 - .long 0x1294ED48 - .long 0x12B5ED48 - - .long 0x11EFF548 - vxor 4,4,31 - .long 0x1210F548 - vxor 1,1,31 - .long 0x1231F548 - vxor 2,2,31 - .long 0x1252F548 - vxor 3,3,31 - .long 0x1273F548 - vxor 10,10,31 - .long 0x1294F548 - vxor 11,11,31 - .long 0x12B5F548 - vxor 12,12,31 - - cmplwi 5,32 - blt .Lcbc_dec8x_one - nop - beq .Lcbc_dec8x_two - cmplwi 5,64 - blt .Lcbc_dec8x_three - nop - beq .Lcbc_dec8x_four - cmplwi 5,96 - blt .Lcbc_dec8x_five - nop - beq .Lcbc_dec8x_six - -.Lcbc_dec8x_seven: - .long 0x11EF2549 - .long 0x12100D49 - .long 0x12311549 - .long 0x12521D49 - .long 0x12735549 - .long 0x12945D49 - .long 0x12B56549 - vor 4,13,13 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - vperm 19,19,19,6 - .long 0x7E5B2799 - vperm 20,20,20,6 - .long 0x7E7C2799 - vperm 21,21,21,6 - .long 0x7E9D2799 - .long 0x7EBE2799 - addi 4,4,0x70 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_six: - .long 0x12102549 - .long 0x12311549 - .long 0x12521D49 - .long 0x12735549 - .long 0x12945D49 - .long 0x12B56549 - vor 4,13,13 - - vperm 16,16,16,6 - vperm 17,17,17,6 - .long 0x7E002799 - vperm 18,18,18,6 - .long 0x7E282799 - vperm 19,19,19,6 - .long 0x7E5A2799 - vperm 20,20,20,6 - .long 0x7E7B2799 - vperm 21,21,21,6 - .long 0x7E9C2799 - .long 0x7EBD2799 - addi 4,4,0x60 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_five: - .long 0x12312549 - .long 0x12521D49 - .long 0x12735549 - .long 0x12945D49 - .long 0x12B56549 - vor 4,13,13 - - vperm 17,17,17,6 - vperm 18,18,18,6 - .long 0x7E202799 - vperm 19,19,19,6 - .long 0x7E482799 - vperm 20,20,20,6 - .long 0x7E7A2799 - vperm 21,21,21,6 - .long 0x7E9B2799 - .long 0x7EBC2799 - addi 4,4,0x50 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_four: - .long 0x12522549 - .long 0x12735549 - .long 0x12945D49 - .long 0x12B56549 - vor 4,13,13 - - vperm 18,18,18,6 - vperm 19,19,19,6 - .long 0x7E402799 - vperm 20,20,20,6 - .long 0x7E682799 - vperm 21,21,21,6 - .long 0x7E9A2799 - .long 0x7EBB2799 - addi 4,4,0x40 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_three: - .long 0x12732549 - .long 0x12945D49 - .long 0x12B56549 - vor 4,13,13 - - vperm 19,19,19,6 - vperm 20,20,20,6 - .long 0x7E602799 - vperm 21,21,21,6 - .long 0x7E882799 - .long 0x7EBA2799 - addi 4,4,0x30 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_two: - .long 0x12942549 - .long 0x12B56549 - vor 4,13,13 - - vperm 20,20,20,6 - vperm 21,21,21,6 - .long 0x7E802799 - .long 0x7EA82799 - addi 4,4,0x20 - b .Lcbc_dec8x_done - -.align 5 -.Lcbc_dec8x_one: - .long 0x12B52549 - vor 4,13,13 - - vperm 21,21,21,6 - .long 0x7EA02799 - addi 4,4,0x10 - -.Lcbc_dec8x_done: - vperm 4,4,4,6 - .long 0x7C803F99 - - li 10,79 - li 11,95 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - - or 12,12,12 - lvx 20,10,1 - addi 10,10,32 - lvx 21,11,1 - addi 11,11,32 - lvx 22,10,1 - addi 10,10,32 - lvx 23,11,1 - addi 11,11,32 - lvx 24,10,1 - addi 10,10,32 - lvx 25,11,1 - addi 11,11,32 - lvx 26,10,1 - addi 10,10,32 - lvx 27,11,1 - addi 11,11,32 - lvx 28,10,1 - addi 10,10,32 - lvx 29,11,1 - addi 11,11,32 - lvx 30,10,1 - lvx 31,11,1 - ld 26,400(1) - ld 27,408(1) - ld 28,416(1) - ld 29,424(1) - ld 30,432(1) - ld 31,440(1) - addi 1,1,448 - blr -.long 0 -.byte 0,12,0x04,0,0x80,6,6,0 -.long 0 -.size aes_hw_cbc_encrypt,.-aes_hw_cbc_encrypt -.globl aes_hw_ctr32_encrypt_blocks -.type aes_hw_ctr32_encrypt_blocks,@function -.align 5 -aes_hw_ctr32_encrypt_blocks: -.localentry aes_hw_ctr32_encrypt_blocks,0 - - cmpldi 5,1 - .long 0x4dc00020 - - lis 0,0xfff0 - li 12,-1 - or 0,0,0 - - li 10,15 - vxor 0,0,0 - vspltisb 3,0x0f - - lvx 4,0,7 - lvsl 6,0,7 - lvx 5,10,7 - vspltisb 11,1 - vxor 6,6,3 - vperm 4,4,5,6 - vsldoi 11,0,11,1 - - neg 11,3 - lvsr 10,0,6 - lwz 9,240(6) - - lvsr 6,0,11 - lvx 5,0,3 - addi 3,3,15 - vxor 6,6,3 - - srwi 9,9,1 - li 10,16 - subi 9,9,1 - - cmpldi 5,8 - bge _aesp8_ctr32_encrypt8x - - lvsl 8,0,4 - vspltisb 9,-1 - lvx 7,0,4 - vperm 9,9,0,8 - vxor 8,8,3 - - lvx 0,0,6 - mtctr 9 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - vxor 2,4,0 - lvx 0,10,6 - addi 10,10,16 - b .Loop_ctr32_enc - -.align 5 -.Loop_ctr32_enc: - vperm 1,0,1,10 - .long 0x10420D08 - lvx 1,10,6 - addi 10,10,16 - vperm 0,1,0,10 - .long 0x10420508 - lvx 0,10,6 - addi 10,10,16 - bdnz .Loop_ctr32_enc - - vadduwm 4,4,11 - vor 3,5,5 - lvx 5,0,3 - addi 3,3,16 - subic. 5,5,1 - - vperm 1,0,1,10 - .long 0x10420D08 - lvx 1,10,6 - vperm 3,3,5,6 - li 10,16 - vperm 1,1,0,10 - lvx 0,0,6 - vxor 3,3,1 - .long 0x10421D09 - - lvx 1,10,6 - addi 10,10,16 - vperm 2,2,2,8 - vsel 3,7,2,9 - mtctr 9 - vperm 0,1,0,10 - vor 7,2,2 - vxor 2,4,0 - lvx 0,10,6 - addi 10,10,16 - stvx 3,0,4 - addi 4,4,16 - bne .Loop_ctr32_enc - - addi 4,4,-1 - lvx 2,0,4 - vsel 2,7,2,9 - stvx 2,0,4 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,6,0 -.long 0 -.align 5 -_aesp8_ctr32_encrypt8x: - stdu 1,-448(1) - li 10,207 - li 11,223 - stvx 20,10,1 - addi 10,10,32 - stvx 21,11,1 - addi 11,11,32 - stvx 22,10,1 - addi 10,10,32 - stvx 23,11,1 - addi 11,11,32 - stvx 24,10,1 - addi 10,10,32 - stvx 25,11,1 - addi 11,11,32 - stvx 26,10,1 - addi 10,10,32 - stvx 27,11,1 - addi 11,11,32 - stvx 28,10,1 - addi 10,10,32 - stvx 29,11,1 - addi 11,11,32 - stvx 30,10,1 - stvx 31,11,1 - li 0,-1 - stw 12,396(1) - li 8,0x10 - std 26,400(1) - li 26,0x20 - std 27,408(1) - li 27,0x30 - std 28,416(1) - li 28,0x40 - std 29,424(1) - li 29,0x50 - std 30,432(1) - li 30,0x60 - std 31,440(1) - li 31,0x70 - or 0,0,0 - - subi 9,9,3 - - lvx 23,0,6 - lvx 30,8,6 - addi 6,6,0x20 - lvx 31,0,6 - vperm 23,30,23,10 - addi 11,1,79 - mtctr 9 - -.Load_ctr32_enc_key: - vperm 24,31,30,10 - lvx 30,8,6 - addi 6,6,0x20 - stvx 24,0,11 - vperm 25,30,31,10 - lvx 31,0,6 - stvx 25,8,11 - addi 11,11,0x20 - bdnz .Load_ctr32_enc_key - - lvx 26,8,6 - vperm 24,31,30,10 - lvx 27,26,6 - stvx 24,0,11 - vperm 25,26,31,10 - lvx 28,27,6 - stvx 25,8,11 - addi 11,1,79 - vperm 26,27,26,10 - lvx 29,28,6 - vperm 27,28,27,10 - lvx 30,29,6 - vperm 28,29,28,10 - lvx 31,30,6 - vperm 29,30,29,10 - lvx 15,31,6 - vperm 30,31,30,10 - lvx 24,0,11 - vperm 31,15,31,10 - lvx 25,8,11 - - vadduwm 7,11,11 - subi 3,3,15 - sldi 5,5,4 - - vadduwm 16,4,11 - vadduwm 17,4,7 - vxor 15,4,23 - li 10,8 - vadduwm 18,16,7 - vxor 16,16,23 - lvsl 6,0,10 - vadduwm 19,17,7 - vxor 17,17,23 - vspltisb 3,0x0f - vadduwm 20,18,7 - vxor 18,18,23 - vxor 6,6,3 - vadduwm 21,19,7 - vxor 19,19,23 - vadduwm 22,20,7 - vxor 20,20,23 - vadduwm 4,21,7 - vxor 21,21,23 - vxor 22,22,23 - - mtctr 9 - b .Loop_ctr32_enc8x -.align 5 -.Loop_ctr32_enc8x: - .long 0x11EFC508 - .long 0x1210C508 - .long 0x1231C508 - .long 0x1252C508 - .long 0x1273C508 - .long 0x1294C508 - .long 0x12B5C508 - .long 0x12D6C508 -.Loop_ctr32_enc8x_middle: - lvx 24,26,11 - addi 11,11,0x20 - - .long 0x11EFCD08 - .long 0x1210CD08 - .long 0x1231CD08 - .long 0x1252CD08 - .long 0x1273CD08 - .long 0x1294CD08 - .long 0x12B5CD08 - .long 0x12D6CD08 - lvx 25,8,11 - bdnz .Loop_ctr32_enc8x - - subic 11,5,256 - .long 0x11EFC508 - .long 0x1210C508 - .long 0x1231C508 - .long 0x1252C508 - .long 0x1273C508 - .long 0x1294C508 - .long 0x12B5C508 - .long 0x12D6C508 - - subfe 0,0,0 - .long 0x11EFCD08 - .long 0x1210CD08 - .long 0x1231CD08 - .long 0x1252CD08 - .long 0x1273CD08 - .long 0x1294CD08 - .long 0x12B5CD08 - .long 0x12D6CD08 - - and 0,0,11 - addi 11,1,79 - .long 0x11EFD508 - .long 0x1210D508 - .long 0x1231D508 - .long 0x1252D508 - .long 0x1273D508 - .long 0x1294D508 - .long 0x12B5D508 - .long 0x12D6D508 - lvx 24,0,11 - - subic 5,5,129 - .long 0x11EFDD08 - addi 5,5,1 - .long 0x1210DD08 - .long 0x1231DD08 - .long 0x1252DD08 - .long 0x1273DD08 - .long 0x1294DD08 - .long 0x12B5DD08 - .long 0x12D6DD08 - lvx 25,8,11 - - .long 0x11EFE508 - .long 0x7C001E99 - .long 0x1210E508 - .long 0x7C281E99 - .long 0x1231E508 - .long 0x7C5A1E99 - .long 0x1252E508 - .long 0x7C7B1E99 - .long 0x1273E508 - .long 0x7D5C1E99 - .long 0x1294E508 - .long 0x7D9D1E99 - .long 0x12B5E508 - .long 0x7DBE1E99 - .long 0x12D6E508 - .long 0x7DDF1E99 - addi 3,3,0x80 - - .long 0x11EFED08 - vperm 0,0,0,6 - .long 0x1210ED08 - vperm 1,1,1,6 - .long 0x1231ED08 - vperm 2,2,2,6 - .long 0x1252ED08 - vperm 3,3,3,6 - .long 0x1273ED08 - vperm 10,10,10,6 - .long 0x1294ED08 - vperm 12,12,12,6 - .long 0x12B5ED08 - vperm 13,13,13,6 - .long 0x12D6ED08 - vperm 14,14,14,6 - - add 3,3,0 - - - - subfe. 0,0,0 - .long 0x11EFF508 - vxor 0,0,31 - .long 0x1210F508 - vxor 1,1,31 - .long 0x1231F508 - vxor 2,2,31 - .long 0x1252F508 - vxor 3,3,31 - .long 0x1273F508 - vxor 10,10,31 - .long 0x1294F508 - vxor 12,12,31 - .long 0x12B5F508 - vxor 13,13,31 - .long 0x12D6F508 - vxor 14,14,31 - - bne .Lctr32_enc8x_break - - .long 0x100F0509 - .long 0x10300D09 - vadduwm 16,4,11 - .long 0x10511509 - vadduwm 17,4,7 - vxor 15,4,23 - .long 0x10721D09 - vadduwm 18,16,7 - vxor 16,16,23 - .long 0x11535509 - vadduwm 19,17,7 - vxor 17,17,23 - .long 0x11946509 - vadduwm 20,18,7 - vxor 18,18,23 - .long 0x11B56D09 - vadduwm 21,19,7 - vxor 19,19,23 - .long 0x11D67509 - vadduwm 22,20,7 - vxor 20,20,23 - vperm 0,0,0,6 - vadduwm 4,21,7 - vxor 21,21,23 - vperm 1,1,1,6 - vxor 22,22,23 - mtctr 9 - - .long 0x11EFC508 - .long 0x7C002799 - vperm 2,2,2,6 - .long 0x1210C508 - .long 0x7C282799 - vperm 3,3,3,6 - .long 0x1231C508 - .long 0x7C5A2799 - vperm 10,10,10,6 - .long 0x1252C508 - .long 0x7C7B2799 - vperm 12,12,12,6 - .long 0x1273C508 - .long 0x7D5C2799 - vperm 13,13,13,6 - .long 0x1294C508 - .long 0x7D9D2799 - vperm 14,14,14,6 - .long 0x12B5C508 - .long 0x7DBE2799 - .long 0x12D6C508 - .long 0x7DDF2799 - addi 4,4,0x80 - - b .Loop_ctr32_enc8x_middle - -.align 5 -.Lctr32_enc8x_break: - cmpwi 5,-0x60 - blt .Lctr32_enc8x_one - nop - beq .Lctr32_enc8x_two - cmpwi 5,-0x40 - blt .Lctr32_enc8x_three - nop - beq .Lctr32_enc8x_four - cmpwi 5,-0x20 - blt .Lctr32_enc8x_five - nop - beq .Lctr32_enc8x_six - cmpwi 5,0x00 - blt .Lctr32_enc8x_seven - -.Lctr32_enc8x_eight: - .long 0x11EF0509 - .long 0x12100D09 - .long 0x12311509 - .long 0x12521D09 - .long 0x12735509 - .long 0x12946509 - .long 0x12B56D09 - .long 0x12D67509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - vperm 19,19,19,6 - .long 0x7E5B2799 - vperm 20,20,20,6 - .long 0x7E7C2799 - vperm 21,21,21,6 - .long 0x7E9D2799 - vperm 22,22,22,6 - .long 0x7EBE2799 - .long 0x7EDF2799 - addi 4,4,0x80 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_seven: - .long 0x11EF0D09 - .long 0x12101509 - .long 0x12311D09 - .long 0x12525509 - .long 0x12736509 - .long 0x12946D09 - .long 0x12B57509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - vperm 19,19,19,6 - .long 0x7E5B2799 - vperm 20,20,20,6 - .long 0x7E7C2799 - vperm 21,21,21,6 - .long 0x7E9D2799 - .long 0x7EBE2799 - addi 4,4,0x70 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_six: - .long 0x11EF1509 - .long 0x12101D09 - .long 0x12315509 - .long 0x12526509 - .long 0x12736D09 - .long 0x12947509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - vperm 19,19,19,6 - .long 0x7E5B2799 - vperm 20,20,20,6 - .long 0x7E7C2799 - .long 0x7E9D2799 - addi 4,4,0x60 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_five: - .long 0x11EF1D09 - .long 0x12105509 - .long 0x12316509 - .long 0x12526D09 - .long 0x12737509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - vperm 19,19,19,6 - .long 0x7E5B2799 - .long 0x7E7C2799 - addi 4,4,0x50 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_four: - .long 0x11EF5509 - .long 0x12106509 - .long 0x12316D09 - .long 0x12527509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - vperm 18,18,18,6 - .long 0x7E3A2799 - .long 0x7E5B2799 - addi 4,4,0x40 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_three: - .long 0x11EF6509 - .long 0x12106D09 - .long 0x12317509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - vperm 17,17,17,6 - .long 0x7E082799 - .long 0x7E3A2799 - addi 4,4,0x30 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_two: - .long 0x11EF6D09 - .long 0x12107509 - - vperm 15,15,15,6 - vperm 16,16,16,6 - .long 0x7DE02799 - .long 0x7E082799 - addi 4,4,0x20 - b .Lctr32_enc8x_done - -.align 5 -.Lctr32_enc8x_one: - .long 0x11EF7509 - - vperm 15,15,15,6 - .long 0x7DE02799 - addi 4,4,0x10 - -.Lctr32_enc8x_done: - li 10,79 - li 11,95 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - stvx 6,10,1 - addi 10,10,32 - stvx 6,11,1 - addi 11,11,32 - - or 12,12,12 - lvx 20,10,1 - addi 10,10,32 - lvx 21,11,1 - addi 11,11,32 - lvx 22,10,1 - addi 10,10,32 - lvx 23,11,1 - addi 11,11,32 - lvx 24,10,1 - addi 10,10,32 - lvx 25,11,1 - addi 11,11,32 - lvx 26,10,1 - addi 10,10,32 - lvx 27,11,1 - addi 11,11,32 - lvx 28,10,1 - addi 10,10,32 - lvx 29,11,1 - addi 11,11,32 - lvx 30,10,1 - lvx 31,11,1 - ld 26,400(1) - ld 27,408(1) - ld 28,416(1) - ld 29,424(1) - ld 30,432(1) - ld 31,440(1) - addi 1,1,448 - blr -.long 0 -.byte 0,12,0x04,0,0x80,6,6,0 -.long 0 -.size aes_hw_ctr32_encrypt_blocks,.-aes_hw_ctr32_encrypt_blocks -.globl aes_hw_xts_encrypt -.type aes_hw_xts_encrypt,@function -.align 5 -aes_hw_xts_encrypt: -.localentry aes_hw_xts_encrypt,0 - - mr 10,3 - li 3,-1 - cmpldi 5,16 - .long 0x4dc00020 - - lis 0,0xfff0 - li 12,-1 - li 11,0 - or 0,0,0 - - vspltisb 9,0x07 - lvsl 6,11,11 - vspltisb 11,0x0f - vxor 6,6,9 - - li 3,15 - lvx 8,0,8 - lvsl 5,0,8 - lvx 4,3,8 - vxor 5,5,11 - vperm 8,8,4,5 - - neg 11,10 - lvsr 5,0,11 - lvx 2,0,10 - addi 10,10,15 - vxor 5,5,11 - - cmpldi 7,0 - beq .Lxts_enc_no_key2 - - lvsr 7,0,7 - lwz 9,240(7) - srwi 9,9,1 - subi 9,9,1 - li 3,16 - - lvx 0,0,7 - lvx 1,3,7 - addi 3,3,16 - vperm 0,1,0,7 - vxor 8,8,0 - lvx 0,3,7 - addi 3,3,16 - mtctr 9 - -.Ltweak_xts_enc: - vperm 1,0,1,7 - .long 0x11080D08 - lvx 1,3,7 - addi 3,3,16 - vperm 0,1,0,7 - .long 0x11080508 - lvx 0,3,7 - addi 3,3,16 - bdnz .Ltweak_xts_enc - - vperm 1,0,1,7 - .long 0x11080D08 - lvx 1,3,7 - vperm 0,1,0,7 - .long 0x11080509 - - li 8,0 - b .Lxts_enc - -.Lxts_enc_no_key2: - li 3,-16 - and 5,5,3 - - -.Lxts_enc: - lvx 4,0,10 - addi 10,10,16 - - lvsr 7,0,6 - lwz 9,240(6) - srwi 9,9,1 - subi 9,9,1 - li 3,16 - - vslb 10,9,9 - vor 10,10,9 - vspltisb 11,1 - vsldoi 10,10,11,15 - - cmpldi 5,96 - bge _aesp8_xts_encrypt6x - - andi. 7,5,15 - subic 0,5,32 - subi 7,7,16 - subfe 0,0,0 - and 0,0,7 - add 10,10,0 - - lvx 0,0,6 - lvx 1,3,6 - addi 3,3,16 - vperm 2,2,4,5 - vperm 0,1,0,7 - vxor 2,2,8 - vxor 2,2,0 - lvx 0,3,6 - addi 3,3,16 - mtctr 9 - b .Loop_xts_enc - -.align 5 -.Loop_xts_enc: - vperm 1,0,1,7 - .long 0x10420D08 - lvx 1,3,6 - addi 3,3,16 - vperm 0,1,0,7 - .long 0x10420508 - lvx 0,3,6 - addi 3,3,16 - bdnz .Loop_xts_enc - - vperm 1,0,1,7 - .long 0x10420D08 - lvx 1,3,6 - li 3,16 - vperm 0,1,0,7 - vxor 0,0,8 - .long 0x10620509 - - vperm 11,3,3,6 - - .long 0x7D602799 - - addi 4,4,16 - - subic. 5,5,16 - beq .Lxts_enc_done - - vor 2,4,4 - lvx 4,0,10 - addi 10,10,16 - lvx 0,0,6 - lvx 1,3,6 - addi 3,3,16 - - subic 0,5,32 - subfe 0,0,0 - and 0,0,7 - add 10,10,0 - - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 8,8,11 - - vperm 2,2,4,5 - vperm 0,1,0,7 - vxor 2,2,8 - vxor 3,3,0 - vxor 2,2,0 - lvx 0,3,6 - addi 3,3,16 - - mtctr 9 - cmpldi 5,16 - bge .Loop_xts_enc - - vxor 3,3,8 - lvsr 5,0,5 - vxor 4,4,4 - vspltisb 11,-1 - vperm 4,4,11,5 - vsel 2,2,3,4 - - subi 11,4,17 - subi 4,4,16 - mtctr 5 - li 5,16 -.Loop_xts_enc_steal: - lbzu 0,1(11) - stb 0,16(11) - bdnz .Loop_xts_enc_steal - - mtctr 9 - b .Loop_xts_enc - -.Lxts_enc_done: - cmpldi 8,0 - beq .Lxts_enc_ret - - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 8,8,11 - - vperm 8,8,8,6 - .long 0x7D004799 - -.Lxts_enc_ret: - or 12,12,12 - li 3,0 - blr -.long 0 -.byte 0,12,0x04,0,0x80,6,6,0 -.long 0 -.size aes_hw_xts_encrypt,.-aes_hw_xts_encrypt - -.globl aes_hw_xts_decrypt -.type aes_hw_xts_decrypt,@function -.align 5 -aes_hw_xts_decrypt: -.localentry aes_hw_xts_decrypt,0 - - mr 10,3 - li 3,-1 - cmpldi 5,16 - .long 0x4dc00020 - - lis 0,0xfff8 - li 12,-1 - li 11,0 - or 0,0,0 - - andi. 0,5,15 - neg 0,0 - andi. 0,0,16 - sub 5,5,0 - - vspltisb 9,0x07 - lvsl 6,11,11 - vspltisb 11,0x0f - vxor 6,6,9 - - li 3,15 - lvx 8,0,8 - lvsl 5,0,8 - lvx 4,3,8 - vxor 5,5,11 - vperm 8,8,4,5 - - neg 11,10 - lvsr 5,0,11 - lvx 2,0,10 - addi 10,10,15 - vxor 5,5,11 - - cmpldi 7,0 - beq .Lxts_dec_no_key2 - - lvsr 7,0,7 - lwz 9,240(7) - srwi 9,9,1 - subi 9,9,1 - li 3,16 - - lvx 0,0,7 - lvx 1,3,7 - addi 3,3,16 - vperm 0,1,0,7 - vxor 8,8,0 - lvx 0,3,7 - addi 3,3,16 - mtctr 9 - -.Ltweak_xts_dec: - vperm 1,0,1,7 - .long 0x11080D08 - lvx 1,3,7 - addi 3,3,16 - vperm 0,1,0,7 - .long 0x11080508 - lvx 0,3,7 - addi 3,3,16 - bdnz .Ltweak_xts_dec - - vperm 1,0,1,7 - .long 0x11080D08 - lvx 1,3,7 - vperm 0,1,0,7 - .long 0x11080509 - - li 8,0 - b .Lxts_dec - -.Lxts_dec_no_key2: - neg 3,5 - andi. 3,3,15 - add 5,5,3 - - -.Lxts_dec: - lvx 4,0,10 - addi 10,10,16 - - lvsr 7,0,6 - lwz 9,240(6) - srwi 9,9,1 - subi 9,9,1 - li 3,16 - - vslb 10,9,9 - vor 10,10,9 - vspltisb 11,1 - vsldoi 10,10,11,15 - - cmpldi 5,96 - bge _aesp8_xts_decrypt6x - - lvx 0,0,6 - lvx 1,3,6 - addi 3,3,16 - vperm 2,2,4,5 - vperm 0,1,0,7 - vxor 2,2,8 - vxor 2,2,0 - lvx 0,3,6 - addi 3,3,16 - mtctr 9 - - cmpldi 5,16 - blt .Ltail_xts_dec - - -.align 5 -.Loop_xts_dec: - vperm 1,0,1,7 - .long 0x10420D48 - lvx 1,3,6 - addi 3,3,16 - vperm 0,1,0,7 - .long 0x10420548 - lvx 0,3,6 - addi 3,3,16 - bdnz .Loop_xts_dec - - vperm 1,0,1,7 - .long 0x10420D48 - lvx 1,3,6 - li 3,16 - vperm 0,1,0,7 - vxor 0,0,8 - .long 0x10620549 - - vperm 11,3,3,6 - - .long 0x7D602799 - - addi 4,4,16 - - subic. 5,5,16 - beq .Lxts_dec_done - - vor 2,4,4 - lvx 4,0,10 - addi 10,10,16 - lvx 0,0,6 - lvx 1,3,6 - addi 3,3,16 - - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 8,8,11 - - vperm 2,2,4,5 - vperm 0,1,0,7 - vxor 2,2,8 - vxor 2,2,0 - lvx 0,3,6 - addi 3,3,16 - - mtctr 9 - cmpldi 5,16 - bge .Loop_xts_dec - -.Ltail_xts_dec: - vsrab 11,8,9 - vaddubm 12,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 12,12,11 - - subi 10,10,16 - add 10,10,5 - - vxor 2,2,8 - vxor 2,2,12 - -.Loop_xts_dec_short: - vperm 1,0,1,7 - .long 0x10420D48 - lvx 1,3,6 - addi 3,3,16 - vperm 0,1,0,7 - .long 0x10420548 - lvx 0,3,6 - addi 3,3,16 - bdnz .Loop_xts_dec_short - - vperm 1,0,1,7 - .long 0x10420D48 - lvx 1,3,6 - li 3,16 - vperm 0,1,0,7 - vxor 0,0,12 - .long 0x10620549 - - vperm 11,3,3,6 - - .long 0x7D602799 - - - vor 2,4,4 - lvx 4,0,10 - - lvx 0,0,6 - lvx 1,3,6 - addi 3,3,16 - vperm 2,2,4,5 - vperm 0,1,0,7 - - lvsr 5,0,5 - vxor 4,4,4 - vspltisb 11,-1 - vperm 4,4,11,5 - vsel 2,2,3,4 - - vxor 0,0,8 - vxor 2,2,0 - lvx 0,3,6 - addi 3,3,16 - - subi 11,4,1 - mtctr 5 - li 5,16 -.Loop_xts_dec_steal: - lbzu 0,1(11) - stb 0,16(11) - bdnz .Loop_xts_dec_steal - - mtctr 9 - b .Loop_xts_dec - -.Lxts_dec_done: - cmpldi 8,0 - beq .Lxts_dec_ret - - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 8,8,11 - - vperm 8,8,8,6 - .long 0x7D004799 - -.Lxts_dec_ret: - or 12,12,12 - li 3,0 - blr -.long 0 -.byte 0,12,0x04,0,0x80,6,6,0 -.long 0 -.size aes_hw_xts_decrypt,.-aes_hw_xts_decrypt -.align 5 -_aesp8_xts_encrypt6x: - stdu 1,-448(1) - mflr 11 - li 7,207 - li 3,223 - std 11,464(1) - stvx 20,7,1 - addi 7,7,32 - stvx 21,3,1 - addi 3,3,32 - stvx 22,7,1 - addi 7,7,32 - stvx 23,3,1 - addi 3,3,32 - stvx 24,7,1 - addi 7,7,32 - stvx 25,3,1 - addi 3,3,32 - stvx 26,7,1 - addi 7,7,32 - stvx 27,3,1 - addi 3,3,32 - stvx 28,7,1 - addi 7,7,32 - stvx 29,3,1 - addi 3,3,32 - stvx 30,7,1 - stvx 31,3,1 - li 0,-1 - stw 12,396(1) - li 3,0x10 - std 26,400(1) - li 26,0x20 - std 27,408(1) - li 27,0x30 - std 28,416(1) - li 28,0x40 - std 29,424(1) - li 29,0x50 - std 30,432(1) - li 30,0x60 - std 31,440(1) - li 31,0x70 - or 0,0,0 - - subi 9,9,3 - - lvx 23,0,6 - lvx 30,3,6 - addi 6,6,0x20 - lvx 31,0,6 - vperm 23,30,23,7 - addi 7,1,79 - mtctr 9 - -.Load_xts_enc_key: - vperm 24,31,30,7 - lvx 30,3,6 - addi 6,6,0x20 - stvx 24,0,7 - vperm 25,30,31,7 - lvx 31,0,6 - stvx 25,3,7 - addi 7,7,0x20 - bdnz .Load_xts_enc_key - - lvx 26,3,6 - vperm 24,31,30,7 - lvx 27,26,6 - stvx 24,0,7 - vperm 25,26,31,7 - lvx 28,27,6 - stvx 25,3,7 - addi 7,1,79 - vperm 26,27,26,7 - lvx 29,28,6 - vperm 27,28,27,7 - lvx 30,29,6 - vperm 28,29,28,7 - lvx 31,30,6 - vperm 29,30,29,7 - lvx 22,31,6 - vperm 30,31,30,7 - lvx 24,0,7 - vperm 31,22,31,7 - lvx 25,3,7 - - vperm 0,2,4,5 - subi 10,10,31 - vxor 17,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 7,0,17 - vxor 8,8,11 - - .long 0x7C235699 - vxor 18,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 1,1,1,6 - vand 11,11,10 - vxor 12,1,18 - vxor 8,8,11 - - .long 0x7C5A5699 - andi. 31,5,15 - vxor 19,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 2,2,2,6 - vand 11,11,10 - vxor 13,2,19 - vxor 8,8,11 - - .long 0x7C7B5699 - sub 5,5,31 - vxor 20,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 3,3,3,6 - vand 11,11,10 - vxor 14,3,20 - vxor 8,8,11 - - .long 0x7C9C5699 - subi 5,5,0x60 - vxor 21,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 4,4,4,6 - vand 11,11,10 - vxor 15,4,21 - vxor 8,8,11 - - .long 0x7CBD5699 - addi 10,10,0x60 - vxor 22,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 5,5,5,6 - vand 11,11,10 - vxor 16,5,22 - vxor 8,8,11 - - vxor 31,31,23 - mtctr 9 - b .Loop_xts_enc6x - -.align 5 -.Loop_xts_enc6x: - .long 0x10E7C508 - .long 0x118CC508 - .long 0x11ADC508 - .long 0x11CEC508 - .long 0x11EFC508 - .long 0x1210C508 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD08 - .long 0x118CCD08 - .long 0x11ADCD08 - .long 0x11CECD08 - .long 0x11EFCD08 - .long 0x1210CD08 - lvx 25,3,7 - bdnz .Loop_xts_enc6x - - subic 5,5,96 - vxor 0,17,31 - .long 0x10E7C508 - .long 0x118CC508 - vsrab 11,8,9 - vxor 17,8,23 - vaddubm 8,8,8 - .long 0x11ADC508 - .long 0x11CEC508 - vsldoi 11,11,11,15 - .long 0x11EFC508 - .long 0x1210C508 - - subfe. 0,0,0 - vand 11,11,10 - .long 0x10E7CD08 - .long 0x118CCD08 - vxor 8,8,11 - .long 0x11ADCD08 - .long 0x11CECD08 - vxor 1,18,31 - vsrab 11,8,9 - vxor 18,8,23 - .long 0x11EFCD08 - .long 0x1210CD08 - - and 0,0,5 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x10E7D508 - .long 0x118CD508 - vand 11,11,10 - .long 0x11ADD508 - .long 0x11CED508 - vxor 8,8,11 - .long 0x11EFD508 - .long 0x1210D508 - - add 10,10,0 - - - - vxor 2,19,31 - vsrab 11,8,9 - vxor 19,8,23 - vaddubm 8,8,8 - .long 0x10E7DD08 - .long 0x118CDD08 - vsldoi 11,11,11,15 - .long 0x11ADDD08 - .long 0x11CEDD08 - vand 11,11,10 - .long 0x11EFDD08 - .long 0x1210DD08 - - addi 7,1,79 - vxor 8,8,11 - .long 0x10E7E508 - .long 0x118CE508 - vxor 3,20,31 - vsrab 11,8,9 - vxor 20,8,23 - .long 0x11ADE508 - .long 0x11CEE508 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x11EFE508 - .long 0x1210E508 - lvx 24,0,7 - vand 11,11,10 - - .long 0x10E7ED08 - .long 0x118CED08 - vxor 8,8,11 - .long 0x11ADED08 - .long 0x11CEED08 - vxor 4,21,31 - vsrab 11,8,9 - vxor 21,8,23 - .long 0x11EFED08 - .long 0x1210ED08 - lvx 25,3,7 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - - .long 0x10E7F508 - .long 0x118CF508 - vand 11,11,10 - .long 0x11ADF508 - .long 0x11CEF508 - vxor 8,8,11 - .long 0x11EFF508 - .long 0x1210F508 - vxor 5,22,31 - vsrab 11,8,9 - vxor 22,8,23 - - .long 0x10E70509 - .long 0x7C005699 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x118C0D09 - .long 0x7C235699 - .long 0x11AD1509 - vperm 0,0,0,6 - .long 0x7C5A5699 - vand 11,11,10 - .long 0x11CE1D09 - vperm 1,1,1,6 - .long 0x7C7B5699 - .long 0x11EF2509 - vperm 2,2,2,6 - .long 0x7C9C5699 - vxor 8,8,11 - .long 0x11702D09 - - vperm 3,3,3,6 - .long 0x7CBD5699 - addi 10,10,0x60 - vperm 4,4,4,6 - vperm 5,5,5,6 - - vperm 7,7,7,6 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,17 - vperm 13,13,13,6 - .long 0x7D832799 - vxor 12,1,18 - vperm 14,14,14,6 - .long 0x7DBA2799 - vxor 13,2,19 - vperm 15,15,15,6 - .long 0x7DDB2799 - vxor 14,3,20 - vperm 16,11,11,6 - .long 0x7DFC2799 - vxor 15,4,21 - .long 0x7E1D2799 - - vxor 16,5,22 - addi 4,4,0x60 - - mtctr 9 - beq .Loop_xts_enc6x - - addic. 5,5,0x60 - beq .Lxts_enc6x_zero - cmpwi 5,0x20 - blt .Lxts_enc6x_one - nop - beq .Lxts_enc6x_two - cmpwi 5,0x40 - blt .Lxts_enc6x_three - nop - beq .Lxts_enc6x_four - -.Lxts_enc6x_five: - vxor 7,1,17 - vxor 12,2,18 - vxor 13,3,19 - vxor 14,4,20 - vxor 15,5,21 - - bl _aesp8_xts_enc5x - - vperm 7,7,7,6 - vor 17,22,22 - vperm 12,12,12,6 - .long 0x7CE02799 - vperm 13,13,13,6 - .long 0x7D832799 - vperm 14,14,14,6 - .long 0x7DBA2799 - vxor 11,15,22 - vperm 15,15,15,6 - .long 0x7DDB2799 - .long 0x7DFC2799 - addi 4,4,0x50 - bne .Lxts_enc6x_steal - b .Lxts_enc6x_done - -.align 4 -.Lxts_enc6x_four: - vxor 7,2,17 - vxor 12,3,18 - vxor 13,4,19 - vxor 14,5,20 - vxor 15,15,15 - - bl _aesp8_xts_enc5x - - vperm 7,7,7,6 - vor 17,21,21 - vperm 12,12,12,6 - .long 0x7CE02799 - vperm 13,13,13,6 - .long 0x7D832799 - vxor 11,14,21 - vperm 14,14,14,6 - .long 0x7DBA2799 - .long 0x7DDB2799 - addi 4,4,0x40 - bne .Lxts_enc6x_steal - b .Lxts_enc6x_done - -.align 4 -.Lxts_enc6x_three: - vxor 7,3,17 - vxor 12,4,18 - vxor 13,5,19 - vxor 14,14,14 - vxor 15,15,15 - - bl _aesp8_xts_enc5x - - vperm 7,7,7,6 - vor 17,20,20 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 11,13,20 - vperm 13,13,13,6 - .long 0x7D832799 - .long 0x7DBA2799 - addi 4,4,0x30 - bne .Lxts_enc6x_steal - b .Lxts_enc6x_done - -.align 4 -.Lxts_enc6x_two: - vxor 7,4,17 - vxor 12,5,18 - vxor 13,13,13 - vxor 14,14,14 - vxor 15,15,15 - - bl _aesp8_xts_enc5x - - vperm 7,7,7,6 - vor 17,19,19 - vxor 11,12,19 - vperm 12,12,12,6 - .long 0x7CE02799 - .long 0x7D832799 - addi 4,4,0x20 - bne .Lxts_enc6x_steal - b .Lxts_enc6x_done - -.align 4 -.Lxts_enc6x_one: - vxor 7,5,17 - nop -.Loop_xts_enc1x: - .long 0x10E7C508 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD08 - lvx 25,3,7 - bdnz .Loop_xts_enc1x - - add 10,10,31 - cmpwi 31,0 - .long 0x10E7C508 - - subi 10,10,16 - .long 0x10E7CD08 - - lvsr 5,0,31 - .long 0x10E7D508 - - .long 0x7C005699 - .long 0x10E7DD08 - - addi 7,1,79 - .long 0x10E7E508 - lvx 24,0,7 - - .long 0x10E7ED08 - lvx 25,3,7 - vxor 17,17,31 - - vperm 0,0,0,6 - .long 0x10E7F508 - - vperm 0,0,0,5 - .long 0x10E78D09 - - vor 17,18,18 - vxor 11,7,18 - vperm 7,7,7,6 - .long 0x7CE02799 - addi 4,4,0x10 - bne .Lxts_enc6x_steal - b .Lxts_enc6x_done - -.align 4 -.Lxts_enc6x_zero: - cmpwi 31,0 - beq .Lxts_enc6x_done - - add 10,10,31 - subi 10,10,16 - .long 0x7C005699 - lvsr 5,0,31 - vperm 0,0,0,6 - vperm 0,0,0,5 - vxor 11,11,17 -.Lxts_enc6x_steal: - vxor 0,0,17 - vxor 7,7,7 - vspltisb 12,-1 - vperm 7,7,12,5 - vsel 7,0,11,7 - - subi 30,4,17 - subi 4,4,16 - mtctr 31 -.Loop_xts_enc6x_steal: - lbzu 0,1(30) - stb 0,16(30) - bdnz .Loop_xts_enc6x_steal - - li 31,0 - mtctr 9 - b .Loop_xts_enc1x - -.align 4 -.Lxts_enc6x_done: - cmpldi 8,0 - beq .Lxts_enc6x_ret - - vxor 8,17,23 - vperm 8,8,8,6 - .long 0x7D004799 - -.Lxts_enc6x_ret: - mtlr 11 - li 10,79 - li 11,95 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - - or 12,12,12 - lvx 20,10,1 - addi 10,10,32 - lvx 21,11,1 - addi 11,11,32 - lvx 22,10,1 - addi 10,10,32 - lvx 23,11,1 - addi 11,11,32 - lvx 24,10,1 - addi 10,10,32 - lvx 25,11,1 - addi 11,11,32 - lvx 26,10,1 - addi 10,10,32 - lvx 27,11,1 - addi 11,11,32 - lvx 28,10,1 - addi 10,10,32 - lvx 29,11,1 - addi 11,11,32 - lvx 30,10,1 - lvx 31,11,1 - ld 26,400(1) - ld 27,408(1) - ld 28,416(1) - ld 29,424(1) - ld 30,432(1) - ld 31,440(1) - addi 1,1,448 - blr -.long 0 -.byte 0,12,0x04,1,0x80,6,6,0 -.long 0 - -.align 5 -_aesp8_xts_enc5x: - .long 0x10E7C508 - .long 0x118CC508 - .long 0x11ADC508 - .long 0x11CEC508 - .long 0x11EFC508 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD08 - .long 0x118CCD08 - .long 0x11ADCD08 - .long 0x11CECD08 - .long 0x11EFCD08 - lvx 25,3,7 - bdnz _aesp8_xts_enc5x - - add 10,10,31 - cmpwi 31,0 - .long 0x10E7C508 - .long 0x118CC508 - .long 0x11ADC508 - .long 0x11CEC508 - .long 0x11EFC508 - - subi 10,10,16 - .long 0x10E7CD08 - .long 0x118CCD08 - .long 0x11ADCD08 - .long 0x11CECD08 - .long 0x11EFCD08 - vxor 17,17,31 - - .long 0x10E7D508 - lvsr 5,0,31 - .long 0x118CD508 - .long 0x11ADD508 - .long 0x11CED508 - .long 0x11EFD508 - vxor 1,18,31 - - .long 0x10E7DD08 - .long 0x7C005699 - .long 0x118CDD08 - .long 0x11ADDD08 - .long 0x11CEDD08 - .long 0x11EFDD08 - vxor 2,19,31 - - addi 7,1,79 - .long 0x10E7E508 - .long 0x118CE508 - .long 0x11ADE508 - .long 0x11CEE508 - .long 0x11EFE508 - lvx 24,0,7 - vxor 3,20,31 - - .long 0x10E7ED08 - vperm 0,0,0,6 - .long 0x118CED08 - .long 0x11ADED08 - .long 0x11CEED08 - .long 0x11EFED08 - lvx 25,3,7 - vxor 4,21,31 - - .long 0x10E7F508 - vperm 0,0,0,5 - .long 0x118CF508 - .long 0x11ADF508 - .long 0x11CEF508 - .long 0x11EFF508 - - .long 0x10E78D09 - .long 0x118C0D09 - .long 0x11AD1509 - .long 0x11CE1D09 - .long 0x11EF2509 - blr -.long 0 -.byte 0,12,0x14,0,0,0,0,0 - -.align 5 -_aesp8_xts_decrypt6x: - stdu 1,-448(1) - mflr 11 - li 7,207 - li 3,223 - std 11,464(1) - stvx 20,7,1 - addi 7,7,32 - stvx 21,3,1 - addi 3,3,32 - stvx 22,7,1 - addi 7,7,32 - stvx 23,3,1 - addi 3,3,32 - stvx 24,7,1 - addi 7,7,32 - stvx 25,3,1 - addi 3,3,32 - stvx 26,7,1 - addi 7,7,32 - stvx 27,3,1 - addi 3,3,32 - stvx 28,7,1 - addi 7,7,32 - stvx 29,3,1 - addi 3,3,32 - stvx 30,7,1 - stvx 31,3,1 - li 0,-1 - stw 12,396(1) - li 3,0x10 - std 26,400(1) - li 26,0x20 - std 27,408(1) - li 27,0x30 - std 28,416(1) - li 28,0x40 - std 29,424(1) - li 29,0x50 - std 30,432(1) - li 30,0x60 - std 31,440(1) - li 31,0x70 - or 0,0,0 - - subi 9,9,3 - - lvx 23,0,6 - lvx 30,3,6 - addi 6,6,0x20 - lvx 31,0,6 - vperm 23,30,23,7 - addi 7,1,79 - mtctr 9 - -.Load_xts_dec_key: - vperm 24,31,30,7 - lvx 30,3,6 - addi 6,6,0x20 - stvx 24,0,7 - vperm 25,30,31,7 - lvx 31,0,6 - stvx 25,3,7 - addi 7,7,0x20 - bdnz .Load_xts_dec_key - - lvx 26,3,6 - vperm 24,31,30,7 - lvx 27,26,6 - stvx 24,0,7 - vperm 25,26,31,7 - lvx 28,27,6 - stvx 25,3,7 - addi 7,1,79 - vperm 26,27,26,7 - lvx 29,28,6 - vperm 27,28,27,7 - lvx 30,29,6 - vperm 28,29,28,7 - lvx 31,30,6 - vperm 29,30,29,7 - lvx 22,31,6 - vperm 30,31,30,7 - lvx 24,0,7 - vperm 31,22,31,7 - lvx 25,3,7 - - vperm 0,2,4,5 - subi 10,10,31 - vxor 17,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vand 11,11,10 - vxor 7,0,17 - vxor 8,8,11 - - .long 0x7C235699 - vxor 18,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 1,1,1,6 - vand 11,11,10 - vxor 12,1,18 - vxor 8,8,11 - - .long 0x7C5A5699 - andi. 31,5,15 - vxor 19,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 2,2,2,6 - vand 11,11,10 - vxor 13,2,19 - vxor 8,8,11 - - .long 0x7C7B5699 - sub 5,5,31 - vxor 20,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 3,3,3,6 - vand 11,11,10 - vxor 14,3,20 - vxor 8,8,11 - - .long 0x7C9C5699 - subi 5,5,0x60 - vxor 21,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 4,4,4,6 - vand 11,11,10 - vxor 15,4,21 - vxor 8,8,11 - - .long 0x7CBD5699 - addi 10,10,0x60 - vxor 22,8,23 - vsrab 11,8,9 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - vperm 5,5,5,6 - vand 11,11,10 - vxor 16,5,22 - vxor 8,8,11 - - vxor 31,31,23 - mtctr 9 - b .Loop_xts_dec6x - -.align 5 -.Loop_xts_dec6x: - .long 0x10E7C548 - .long 0x118CC548 - .long 0x11ADC548 - .long 0x11CEC548 - .long 0x11EFC548 - .long 0x1210C548 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD48 - .long 0x118CCD48 - .long 0x11ADCD48 - .long 0x11CECD48 - .long 0x11EFCD48 - .long 0x1210CD48 - lvx 25,3,7 - bdnz .Loop_xts_dec6x - - subic 5,5,96 - vxor 0,17,31 - .long 0x10E7C548 - .long 0x118CC548 - vsrab 11,8,9 - vxor 17,8,23 - vaddubm 8,8,8 - .long 0x11ADC548 - .long 0x11CEC548 - vsldoi 11,11,11,15 - .long 0x11EFC548 - .long 0x1210C548 - - subfe. 0,0,0 - vand 11,11,10 - .long 0x10E7CD48 - .long 0x118CCD48 - vxor 8,8,11 - .long 0x11ADCD48 - .long 0x11CECD48 - vxor 1,18,31 - vsrab 11,8,9 - vxor 18,8,23 - .long 0x11EFCD48 - .long 0x1210CD48 - - and 0,0,5 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x10E7D548 - .long 0x118CD548 - vand 11,11,10 - .long 0x11ADD548 - .long 0x11CED548 - vxor 8,8,11 - .long 0x11EFD548 - .long 0x1210D548 - - add 10,10,0 - - - - vxor 2,19,31 - vsrab 11,8,9 - vxor 19,8,23 - vaddubm 8,8,8 - .long 0x10E7DD48 - .long 0x118CDD48 - vsldoi 11,11,11,15 - .long 0x11ADDD48 - .long 0x11CEDD48 - vand 11,11,10 - .long 0x11EFDD48 - .long 0x1210DD48 - - addi 7,1,79 - vxor 8,8,11 - .long 0x10E7E548 - .long 0x118CE548 - vxor 3,20,31 - vsrab 11,8,9 - vxor 20,8,23 - .long 0x11ADE548 - .long 0x11CEE548 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x11EFE548 - .long 0x1210E548 - lvx 24,0,7 - vand 11,11,10 - - .long 0x10E7ED48 - .long 0x118CED48 - vxor 8,8,11 - .long 0x11ADED48 - .long 0x11CEED48 - vxor 4,21,31 - vsrab 11,8,9 - vxor 21,8,23 - .long 0x11EFED48 - .long 0x1210ED48 - lvx 25,3,7 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - - .long 0x10E7F548 - .long 0x118CF548 - vand 11,11,10 - .long 0x11ADF548 - .long 0x11CEF548 - vxor 8,8,11 - .long 0x11EFF548 - .long 0x1210F548 - vxor 5,22,31 - vsrab 11,8,9 - vxor 22,8,23 - - .long 0x10E70549 - .long 0x7C005699 - vaddubm 8,8,8 - vsldoi 11,11,11,15 - .long 0x118C0D49 - .long 0x7C235699 - .long 0x11AD1549 - vperm 0,0,0,6 - .long 0x7C5A5699 - vand 11,11,10 - .long 0x11CE1D49 - vperm 1,1,1,6 - .long 0x7C7B5699 - .long 0x11EF2549 - vperm 2,2,2,6 - .long 0x7C9C5699 - vxor 8,8,11 - .long 0x12102D49 - vperm 3,3,3,6 - .long 0x7CBD5699 - addi 10,10,0x60 - vperm 4,4,4,6 - vperm 5,5,5,6 - - vperm 7,7,7,6 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,17 - vperm 13,13,13,6 - .long 0x7D832799 - vxor 12,1,18 - vperm 14,14,14,6 - .long 0x7DBA2799 - vxor 13,2,19 - vperm 15,15,15,6 - .long 0x7DDB2799 - vxor 14,3,20 - vperm 16,16,16,6 - .long 0x7DFC2799 - vxor 15,4,21 - .long 0x7E1D2799 - vxor 16,5,22 - addi 4,4,0x60 - - mtctr 9 - beq .Loop_xts_dec6x - - addic. 5,5,0x60 - beq .Lxts_dec6x_zero - cmpwi 5,0x20 - blt .Lxts_dec6x_one - nop - beq .Lxts_dec6x_two - cmpwi 5,0x40 - blt .Lxts_dec6x_three - nop - beq .Lxts_dec6x_four - -.Lxts_dec6x_five: - vxor 7,1,17 - vxor 12,2,18 - vxor 13,3,19 - vxor 14,4,20 - vxor 15,5,21 - - bl _aesp8_xts_dec5x - - vperm 7,7,7,6 - vor 17,22,22 - vxor 18,8,23 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,18 - vperm 13,13,13,6 - .long 0x7D832799 - vperm 14,14,14,6 - .long 0x7DBA2799 - vperm 15,15,15,6 - .long 0x7DDB2799 - .long 0x7DFC2799 - addi 4,4,0x50 - bne .Lxts_dec6x_steal - b .Lxts_dec6x_done - -.align 4 -.Lxts_dec6x_four: - vxor 7,2,17 - vxor 12,3,18 - vxor 13,4,19 - vxor 14,5,20 - vxor 15,15,15 - - bl _aesp8_xts_dec5x - - vperm 7,7,7,6 - vor 17,21,21 - vor 18,22,22 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,22 - vperm 13,13,13,6 - .long 0x7D832799 - vperm 14,14,14,6 - .long 0x7DBA2799 - .long 0x7DDB2799 - addi 4,4,0x40 - bne .Lxts_dec6x_steal - b .Lxts_dec6x_done - -.align 4 -.Lxts_dec6x_three: - vxor 7,3,17 - vxor 12,4,18 - vxor 13,5,19 - vxor 14,14,14 - vxor 15,15,15 - - bl _aesp8_xts_dec5x - - vperm 7,7,7,6 - vor 17,20,20 - vor 18,21,21 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,21 - vperm 13,13,13,6 - .long 0x7D832799 - .long 0x7DBA2799 - addi 4,4,0x30 - bne .Lxts_dec6x_steal - b .Lxts_dec6x_done - -.align 4 -.Lxts_dec6x_two: - vxor 7,4,17 - vxor 12,5,18 - vxor 13,13,13 - vxor 14,14,14 - vxor 15,15,15 - - bl _aesp8_xts_dec5x - - vperm 7,7,7,6 - vor 17,19,19 - vor 18,20,20 - vperm 12,12,12,6 - .long 0x7CE02799 - vxor 7,0,20 - .long 0x7D832799 - addi 4,4,0x20 - bne .Lxts_dec6x_steal - b .Lxts_dec6x_done - -.align 4 -.Lxts_dec6x_one: - vxor 7,5,17 - nop -.Loop_xts_dec1x: - .long 0x10E7C548 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD48 - lvx 25,3,7 - bdnz .Loop_xts_dec1x - - subi 0,31,1 - .long 0x10E7C548 - - andi. 0,0,16 - cmpwi 31,0 - .long 0x10E7CD48 - - sub 10,10,0 - .long 0x10E7D548 - - .long 0x7C005699 - .long 0x10E7DD48 - - addi 7,1,79 - .long 0x10E7E548 - lvx 24,0,7 - - .long 0x10E7ED48 - lvx 25,3,7 - vxor 17,17,31 - - vperm 0,0,0,6 - .long 0x10E7F548 - - mtctr 9 - .long 0x10E78D49 - - vor 17,18,18 - vor 18,19,19 - vperm 7,7,7,6 - .long 0x7CE02799 - addi 4,4,0x10 - vxor 7,0,19 - bne .Lxts_dec6x_steal - b .Lxts_dec6x_done - -.align 4 -.Lxts_dec6x_zero: - cmpwi 31,0 - beq .Lxts_dec6x_done - - .long 0x7C005699 - vperm 0,0,0,6 - vxor 7,0,18 -.Lxts_dec6x_steal: - .long 0x10E7C548 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD48 - lvx 25,3,7 - bdnz .Lxts_dec6x_steal - - add 10,10,31 - .long 0x10E7C548 - - cmpwi 31,0 - .long 0x10E7CD48 - - .long 0x7C005699 - .long 0x10E7D548 - - lvsr 5,0,31 - .long 0x10E7DD48 - - addi 7,1,79 - .long 0x10E7E548 - lvx 24,0,7 - - .long 0x10E7ED48 - lvx 25,3,7 - vxor 18,18,31 - - vperm 0,0,0,6 - .long 0x10E7F548 - - vperm 0,0,0,5 - .long 0x11679549 - - vperm 7,11,11,6 - .long 0x7CE02799 - - - vxor 7,7,7 - vspltisb 12,-1 - vperm 7,7,12,5 - vsel 7,0,11,7 - vxor 7,7,17 - - subi 30,4,1 - mtctr 31 -.Loop_xts_dec6x_steal: - lbzu 0,1(30) - stb 0,16(30) - bdnz .Loop_xts_dec6x_steal - - li 31,0 - mtctr 9 - b .Loop_xts_dec1x - -.align 4 -.Lxts_dec6x_done: - cmpldi 8,0 - beq .Lxts_dec6x_ret - - vxor 8,17,23 - vperm 8,8,8,6 - .long 0x7D004799 - -.Lxts_dec6x_ret: - mtlr 11 - li 10,79 - li 11,95 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - stvx 9,10,1 - addi 10,10,32 - stvx 9,11,1 - addi 11,11,32 - - or 12,12,12 - lvx 20,10,1 - addi 10,10,32 - lvx 21,11,1 - addi 11,11,32 - lvx 22,10,1 - addi 10,10,32 - lvx 23,11,1 - addi 11,11,32 - lvx 24,10,1 - addi 10,10,32 - lvx 25,11,1 - addi 11,11,32 - lvx 26,10,1 - addi 10,10,32 - lvx 27,11,1 - addi 11,11,32 - lvx 28,10,1 - addi 10,10,32 - lvx 29,11,1 - addi 11,11,32 - lvx 30,10,1 - lvx 31,11,1 - ld 26,400(1) - ld 27,408(1) - ld 28,416(1) - ld 29,424(1) - ld 30,432(1) - ld 31,440(1) - addi 1,1,448 - blr -.long 0 -.byte 0,12,0x04,1,0x80,6,6,0 -.long 0 - -.align 5 -_aesp8_xts_dec5x: - .long 0x10E7C548 - .long 0x118CC548 - .long 0x11ADC548 - .long 0x11CEC548 - .long 0x11EFC548 - lvx 24,26,7 - addi 7,7,0x20 - - .long 0x10E7CD48 - .long 0x118CCD48 - .long 0x11ADCD48 - .long 0x11CECD48 - .long 0x11EFCD48 - lvx 25,3,7 - bdnz _aesp8_xts_dec5x - - subi 0,31,1 - .long 0x10E7C548 - .long 0x118CC548 - .long 0x11ADC548 - .long 0x11CEC548 - .long 0x11EFC548 - - andi. 0,0,16 - cmpwi 31,0 - .long 0x10E7CD48 - .long 0x118CCD48 - .long 0x11ADCD48 - .long 0x11CECD48 - .long 0x11EFCD48 - vxor 17,17,31 - - sub 10,10,0 - .long 0x10E7D548 - .long 0x118CD548 - .long 0x11ADD548 - .long 0x11CED548 - .long 0x11EFD548 - vxor 1,18,31 - - .long 0x10E7DD48 - .long 0x7C005699 - .long 0x118CDD48 - .long 0x11ADDD48 - .long 0x11CEDD48 - .long 0x11EFDD48 - vxor 2,19,31 - - addi 7,1,79 - .long 0x10E7E548 - .long 0x118CE548 - .long 0x11ADE548 - .long 0x11CEE548 - .long 0x11EFE548 - lvx 24,0,7 - vxor 3,20,31 - - .long 0x10E7ED48 - vperm 0,0,0,6 - .long 0x118CED48 - .long 0x11ADED48 - .long 0x11CEED48 - .long 0x11EFED48 - lvx 25,3,7 - vxor 4,21,31 - - .long 0x10E7F548 - .long 0x118CF548 - .long 0x11ADF548 - .long 0x11CEF548 - .long 0x11EFF548 - - .long 0x10E78D49 - .long 0x118C0D49 - .long 0x11AD1549 - .long 0x11CE1D49 - .long 0x11EF2549 - mtctr 9 - blr -.long 0 -.byte 0,12,0x14,0,0,0,0,0 -#endif // !OPENSSL_NO_ASM && __powerpc64__ -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S b/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S deleted file mode 100644 index 76b4e739..00000000 --- a/third_party/boringssl/kit/linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S +++ /dev/null @@ -1,587 +0,0 @@ -// This file is generated from a similarly-named Perl script in the BoringSSL -// source tree. Do not edit by hand. - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) -#define OPENSSL_NO_ASM -#endif -#endif - -#if !defined(OPENSSL_NO_ASM) && defined(__powerpc64__) -.machine "any" - -.abiversion 2 -.text - -.globl gcm_init_p8 -.type gcm_init_p8,@function -.align 5 -gcm_init_p8: -.localentry gcm_init_p8,0 - - li 0,-4096 - li 8,0x10 - li 12,-1 - li 9,0x20 - or 0,0,0 - li 10,0x30 - .long 0x7D202699 - - vspltisb 8,-16 - vspltisb 5,1 - vaddubm 8,8,8 - vxor 4,4,4 - vor 8,8,5 - vsldoi 8,8,4,15 - vsldoi 6,4,5,1 - vaddubm 8,8,8 - vspltisb 7,7 - vor 8,8,6 - vspltb 6,9,0 - vsl 9,9,5 - vsrab 6,6,7 - vand 6,6,8 - vxor 3,9,6 - - vsldoi 9,3,3,8 - vsldoi 8,4,8,8 - vsldoi 11,4,9,8 - vsldoi 10,9,4,8 - - .long 0x7D001F99 - .long 0x7D681F99 - li 8,0x40 - .long 0x7D291F99 - li 9,0x50 - .long 0x7D4A1F99 - li 10,0x60 - - .long 0x10035CC8 - .long 0x10234CC8 - .long 0x104354C8 - - .long 0x10E044C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - - vsldoi 6,0,0,8 - .long 0x100044C8 - vxor 6,6,2 - vxor 16,0,6 - - vsldoi 17,16,16,8 - vsldoi 19,4,17,8 - vsldoi 18,17,4,8 - - .long 0x7E681F99 - li 8,0x70 - .long 0x7E291F99 - li 9,0x80 - .long 0x7E4A1F99 - li 10,0x90 - .long 0x10039CC8 - .long 0x11B09CC8 - .long 0x10238CC8 - .long 0x11D08CC8 - .long 0x104394C8 - .long 0x11F094C8 - - .long 0x10E044C8 - .long 0x114D44C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vsldoi 11,14,4,8 - vsldoi 9,4,14,8 - vxor 0,0,5 - vxor 2,2,6 - vxor 13,13,11 - vxor 15,15,9 - - vsldoi 0,0,0,8 - vsldoi 13,13,13,8 - vxor 0,0,7 - vxor 13,13,10 - - vsldoi 6,0,0,8 - vsldoi 9,13,13,8 - .long 0x100044C8 - .long 0x11AD44C8 - vxor 6,6,2 - vxor 9,9,15 - vxor 0,0,6 - vxor 13,13,9 - - vsldoi 9,0,0,8 - vsldoi 17,13,13,8 - vsldoi 11,4,9,8 - vsldoi 10,9,4,8 - vsldoi 19,4,17,8 - vsldoi 18,17,4,8 - - .long 0x7D681F99 - li 8,0xa0 - .long 0x7D291F99 - li 9,0xb0 - .long 0x7D4A1F99 - li 10,0xc0 - .long 0x7E681F99 - .long 0x7E291F99 - .long 0x7E4A1F99 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,2,0 -.long 0 -.size gcm_init_p8,.-gcm_init_p8 -.globl gcm_gmult_p8 -.type gcm_gmult_p8,@function -.align 5 -gcm_gmult_p8: -.localentry gcm_gmult_p8,0 - - lis 0,0xfff8 - li 8,0x10 - li 12,-1 - li 9,0x20 - or 0,0,0 - li 10,0x30 - .long 0x7C601E99 - - .long 0x7D682699 - lvsl 12,0,0 - .long 0x7D292699 - vspltisb 5,0x07 - .long 0x7D4A2699 - vxor 12,12,5 - .long 0x7D002699 - vperm 3,3,3,12 - vxor 4,4,4 - - .long 0x10035CC8 - .long 0x10234CC8 - .long 0x104354C8 - - .long 0x10E044C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - - vsldoi 6,0,0,8 - .long 0x100044C8 - vxor 6,6,2 - vxor 0,0,6 - - vperm 0,0,0,12 - .long 0x7C001F99 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,2,0 -.long 0 -.size gcm_gmult_p8,.-gcm_gmult_p8 - -.globl gcm_ghash_p8 -.type gcm_ghash_p8,@function -.align 5 -gcm_ghash_p8: -.localentry gcm_ghash_p8,0 - - li 0,-4096 - li 8,0x10 - li 12,-1 - li 9,0x20 - or 0,0,0 - li 10,0x30 - .long 0x7C001E99 - - .long 0x7D682699 - li 8,0x40 - lvsl 12,0,0 - .long 0x7D292699 - li 9,0x50 - vspltisb 5,0x07 - .long 0x7D4A2699 - li 10,0x60 - vxor 12,12,5 - .long 0x7D002699 - vperm 0,0,0,12 - vxor 4,4,4 - - cmpldi 6,64 - bge .Lgcm_ghash_p8_4x - - .long 0x7C602E99 - addi 5,5,16 - subic. 6,6,16 - vperm 3,3,3,12 - vxor 3,3,0 - beq .Lshort - - .long 0x7E682699 - li 8,16 - .long 0x7E292699 - add 9,5,6 - .long 0x7E4A2699 - - -.align 5 -.Loop_2x: - .long 0x7E002E99 - vperm 16,16,16,12 - - subic 6,6,32 - .long 0x10039CC8 - .long 0x11B05CC8 - subfe 0,0,0 - .long 0x10238CC8 - .long 0x11D04CC8 - and 0,0,6 - .long 0x104394C8 - .long 0x11F054C8 - add 5,5,0 - - vxor 0,0,13 - vxor 1,1,14 - - .long 0x10E044C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 2,2,15 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - .long 0x7C682E99 - addi 5,5,32 - - vsldoi 6,0,0,8 - .long 0x100044C8 - vperm 3,3,3,12 - vxor 6,6,2 - vxor 3,3,6 - vxor 3,3,0 - cmpld 9,5 - bgt .Loop_2x - - cmplwi 6,0 - bne .Leven - -.Lshort: - .long 0x10035CC8 - .long 0x10234CC8 - .long 0x104354C8 - - .long 0x10E044C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - - vsldoi 6,0,0,8 - .long 0x100044C8 - vxor 6,6,2 - -.Leven: - vxor 0,0,6 - vperm 0,0,0,12 - .long 0x7C001F99 - - or 12,12,12 - blr -.long 0 -.byte 0,12,0x14,0,0,0,4,0 -.long 0 -.align 5 -.gcm_ghash_p8_4x: -.Lgcm_ghash_p8_4x: - stdu 1,-256(1) - li 10,63 - li 11,79 - stvx 20,10,1 - addi 10,10,32 - stvx 21,11,1 - addi 11,11,32 - stvx 22,10,1 - addi 10,10,32 - stvx 23,11,1 - addi 11,11,32 - stvx 24,10,1 - addi 10,10,32 - stvx 25,11,1 - addi 11,11,32 - stvx 26,10,1 - addi 10,10,32 - stvx 27,11,1 - addi 11,11,32 - stvx 28,10,1 - addi 10,10,32 - stvx 29,11,1 - addi 11,11,32 - stvx 30,10,1 - li 10,0x60 - stvx 31,11,1 - li 0,-1 - stw 12,252(1) - or 0,0,0 - - lvsl 5,0,8 - - li 8,0x70 - .long 0x7E292699 - li 9,0x80 - vspltisb 6,8 - - li 10,0x90 - .long 0x7EE82699 - li 8,0xa0 - .long 0x7F092699 - li 9,0xb0 - .long 0x7F2A2699 - li 10,0xc0 - .long 0x7FA82699 - li 8,0x10 - .long 0x7FC92699 - li 9,0x20 - .long 0x7FEA2699 - li 10,0x30 - - vsldoi 7,4,6,8 - vaddubm 18,5,7 - vaddubm 19,6,18 - - srdi 6,6,4 - - .long 0x7C602E99 - .long 0x7E082E99 - subic. 6,6,8 - .long 0x7EC92E99 - .long 0x7F8A2E99 - addi 5,5,0x40 - vperm 3,3,3,12 - vperm 16,16,16,12 - vperm 22,22,22,12 - vperm 28,28,28,12 - - vxor 2,3,0 - - .long 0x11B0BCC8 - .long 0x11D0C4C8 - .long 0x11F0CCC8 - - vperm 11,17,9,18 - vperm 5,22,28,19 - vperm 10,17,9,19 - vperm 6,22,28,18 - .long 0x12B68CC8 - .long 0x12855CC8 - .long 0x137C4CC8 - .long 0x134654C8 - - vxor 21,21,14 - vxor 20,20,13 - vxor 27,27,21 - vxor 26,26,15 - - blt .Ltail_4x - -.Loop_4x: - .long 0x7C602E99 - .long 0x7E082E99 - subic. 6,6,4 - .long 0x7EC92E99 - .long 0x7F8A2E99 - addi 5,5,0x40 - vperm 16,16,16,12 - vperm 22,22,22,12 - vperm 28,28,28,12 - vperm 3,3,3,12 - - .long 0x1002ECC8 - .long 0x1022F4C8 - .long 0x1042FCC8 - .long 0x11B0BCC8 - .long 0x11D0C4C8 - .long 0x11F0CCC8 - - vxor 0,0,20 - vxor 1,1,27 - vxor 2,2,26 - vperm 5,22,28,19 - vperm 6,22,28,18 - - .long 0x10E044C8 - .long 0x12855CC8 - .long 0x134654C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - - vsldoi 6,0,0,8 - .long 0x12B68CC8 - .long 0x137C4CC8 - .long 0x100044C8 - - vxor 20,20,13 - vxor 26,26,15 - vxor 2,2,3 - vxor 21,21,14 - vxor 2,2,6 - vxor 27,27,21 - vxor 2,2,0 - bge .Loop_4x - -.Ltail_4x: - .long 0x1002ECC8 - .long 0x1022F4C8 - .long 0x1042FCC8 - - vxor 0,0,20 - vxor 1,1,27 - - .long 0x10E044C8 - - vsldoi 5,1,4,8 - vsldoi 6,4,1,8 - vxor 2,2,26 - vxor 0,0,5 - vxor 2,2,6 - - vsldoi 0,0,0,8 - vxor 0,0,7 - - vsldoi 6,0,0,8 - .long 0x100044C8 - vxor 6,6,2 - vxor 0,0,6 - - addic. 6,6,4 - beq .Ldone_4x - - .long 0x7C602E99 - cmpldi 6,2 - li 6,-4 - blt .Lone - .long 0x7E082E99 - beq .Ltwo - -.Lthree: - .long 0x7EC92E99 - vperm 3,3,3,12 - vperm 16,16,16,12 - vperm 22,22,22,12 - - vxor 2,3,0 - vor 29,23,23 - vor 30, 24, 24 - vor 31,25,25 - - vperm 5,16,22,19 - vperm 6,16,22,18 - .long 0x12B08CC8 - .long 0x13764CC8 - .long 0x12855CC8 - .long 0x134654C8 - - vxor 27,27,21 - b .Ltail_4x - -.align 4 -.Ltwo: - vperm 3,3,3,12 - vperm 16,16,16,12 - - vxor 2,3,0 - vperm 5,4,16,19 - vperm 6,4,16,18 - - vsldoi 29,4,17,8 - vor 30, 17, 17 - vsldoi 31,17,4,8 - - .long 0x12855CC8 - .long 0x13704CC8 - .long 0x134654C8 - - b .Ltail_4x - -.align 4 -.Lone: - vperm 3,3,3,12 - - vsldoi 29,4,9,8 - vor 30, 9, 9 - vsldoi 31,9,4,8 - - vxor 2,3,0 - vxor 20,20,20 - vxor 27,27,27 - vxor 26,26,26 - - b .Ltail_4x - -.Ldone_4x: - vperm 0,0,0,12 - .long 0x7C001F99 - - li 10,63 - li 11,79 - or 12,12,12 - lvx 20,10,1 - addi 10,10,32 - lvx 21,11,1 - addi 11,11,32 - lvx 22,10,1 - addi 10,10,32 - lvx 23,11,1 - addi 11,11,32 - lvx 24,10,1 - addi 10,10,32 - lvx 25,11,1 - addi 11,11,32 - lvx 26,10,1 - addi 10,10,32 - lvx 27,11,1 - addi 11,11,32 - lvx 28,10,1 - addi 10,10,32 - lvx 29,11,1 - addi 11,11,32 - lvx 30,10,1 - lvx 31,11,1 - addi 1,1,256 - blr -.long 0 -.byte 0,12,0x04,0,0x80,0,4,0 -.long 0 -.size gcm_ghash_p8,.-gcm_ghash_p8 - -.byte 71,72,65,83,72,32,102,111,114,32,80,111,119,101,114,73,83,65,32,50,46,48,55,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 -.align 2 -.align 2 -#endif // !OPENSSL_NO_ASM && __powerpc64__ -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-ppc64le/crypto/test/trampoline-ppc.S b/third_party/boringssl/kit/linux-ppc64le/crypto/test/trampoline-ppc.S deleted file mode 100644 index 8166d31a..00000000 --- a/third_party/boringssl/kit/linux-ppc64le/crypto/test/trampoline-ppc.S +++ /dev/null @@ -1,1410 +0,0 @@ -// This file is generated from a similarly-named Perl script in the BoringSSL -// source tree. Do not edit by hand. - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) -#define OPENSSL_NO_ASM -#endif -#endif - -#if !defined(OPENSSL_NO_ASM) && defined(__powerpc64__) -.machine "any" -.abiversion 2 -.text - - - - - - - -.globl abi_test_trampoline -.type abi_test_trampoline,@function -.align 5 -abi_test_trampoline: -.localentry abi_test_trampoline,0 - - - mflr 0 - std 0, 16(1) - - - - - - - - - - - - - - - - - - - - stdu 1, -528(1) - - mfcr 0 - std 0, 8(1) - std 2, 24(1) - std 4, 32(1) - li 11, 48 - stvx 20, 11, 1 - li 11, 64 - stvx 21, 11, 1 - li 11, 80 - stvx 22, 11, 1 - li 11, 96 - stvx 23, 11, 1 - li 11, 112 - stvx 24, 11, 1 - li 11, 128 - stvx 25, 11, 1 - li 11, 144 - stvx 26, 11, 1 - li 11, 160 - stvx 27, 11, 1 - li 11, 176 - stvx 28, 11, 1 - li 11, 192 - stvx 29, 11, 1 - li 11, 208 - stvx 30, 11, 1 - li 11, 224 - stvx 31, 11, 1 - std 14, 240(1) - std 15, 248(1) - std 16, 256(1) - std 17, 264(1) - std 18, 272(1) - std 19, 280(1) - std 20, 288(1) - std 21, 296(1) - std 22, 304(1) - std 23, 312(1) - std 24, 320(1) - std 25, 328(1) - std 26, 336(1) - std 27, 344(1) - std 28, 352(1) - std 29, 360(1) - std 30, 368(1) - std 31, 376(1) - stfd 14, 384(1) - stfd 15, 392(1) - stfd 16, 400(1) - stfd 17, 408(1) - stfd 18, 416(1) - stfd 19, 424(1) - stfd 20, 432(1) - stfd 21, 440(1) - stfd 22, 448(1) - stfd 23, 456(1) - stfd 24, 464(1) - stfd 25, 472(1) - stfd 26, 480(1) - stfd 27, 488(1) - stfd 28, 496(1) - stfd 29, 504(1) - stfd 30, 512(1) - stfd 31, 520(1) - li 11, 0 - lvx 20, 11, 4 - li 11, 16 - lvx 21, 11, 4 - li 11, 32 - lvx 22, 11, 4 - li 11, 48 - lvx 23, 11, 4 - li 11, 64 - lvx 24, 11, 4 - li 11, 80 - lvx 25, 11, 4 - li 11, 96 - lvx 26, 11, 4 - li 11, 112 - lvx 27, 11, 4 - li 11, 128 - lvx 28, 11, 4 - li 11, 144 - lvx 29, 11, 4 - li 11, 160 - lvx 30, 11, 4 - li 11, 176 - lvx 31, 11, 4 - ld 14, 192(4) - ld 15, 200(4) - ld 16, 208(4) - ld 17, 216(4) - ld 18, 224(4) - ld 19, 232(4) - ld 20, 240(4) - ld 21, 248(4) - ld 22, 256(4) - ld 23, 264(4) - ld 24, 272(4) - ld 25, 280(4) - ld 26, 288(4) - ld 27, 296(4) - ld 28, 304(4) - ld 29, 312(4) - ld 30, 320(4) - ld 31, 328(4) - lfd 14, 336(4) - lfd 15, 344(4) - lfd 16, 352(4) - lfd 17, 360(4) - lfd 18, 368(4) - lfd 19, 376(4) - lfd 20, 384(4) - lfd 21, 392(4) - lfd 22, 400(4) - lfd 23, 408(4) - lfd 24, 416(4) - lfd 25, 424(4) - lfd 26, 432(4) - lfd 27, 440(4) - lfd 28, 448(4) - lfd 29, 456(4) - lfd 30, 464(4) - lfd 31, 472(4) - - ld 0, 480(4) - mtcr 0 - - - addi 11, 5, -8 - mr 12, 3 - - - cmpdi 6, 0 - beq .Largs_done - mtctr 6 - ldu 3, 8(11) - bdz .Largs_done - ldu 4, 8(11) - bdz .Largs_done - ldu 5, 8(11) - bdz .Largs_done - ldu 6, 8(11) - bdz .Largs_done - ldu 7, 8(11) - bdz .Largs_done - ldu 8, 8(11) - bdz .Largs_done - ldu 9, 8(11) - bdz .Largs_done - ldu 10, 8(11) - -.Largs_done: - li 2, 0 - mtctr 12 - bctrl - ld 2, 24(1) - - ld 4, 32(1) - li 11, 0 - stvx 20, 11, 4 - li 11, 16 - stvx 21, 11, 4 - li 11, 32 - stvx 22, 11, 4 - li 11, 48 - stvx 23, 11, 4 - li 11, 64 - stvx 24, 11, 4 - li 11, 80 - stvx 25, 11, 4 - li 11, 96 - stvx 26, 11, 4 - li 11, 112 - stvx 27, 11, 4 - li 11, 128 - stvx 28, 11, 4 - li 11, 144 - stvx 29, 11, 4 - li 11, 160 - stvx 30, 11, 4 - li 11, 176 - stvx 31, 11, 4 - std 14, 192(4) - std 15, 200(4) - std 16, 208(4) - std 17, 216(4) - std 18, 224(4) - std 19, 232(4) - std 20, 240(4) - std 21, 248(4) - std 22, 256(4) - std 23, 264(4) - std 24, 272(4) - std 25, 280(4) - std 26, 288(4) - std 27, 296(4) - std 28, 304(4) - std 29, 312(4) - std 30, 320(4) - std 31, 328(4) - stfd 14, 336(4) - stfd 15, 344(4) - stfd 16, 352(4) - stfd 17, 360(4) - stfd 18, 368(4) - stfd 19, 376(4) - stfd 20, 384(4) - stfd 21, 392(4) - stfd 22, 400(4) - stfd 23, 408(4) - stfd 24, 416(4) - stfd 25, 424(4) - stfd 26, 432(4) - stfd 27, 440(4) - stfd 28, 448(4) - stfd 29, 456(4) - stfd 30, 464(4) - stfd 31, 472(4) - li 11, 48 - lvx 20, 11, 1 - li 11, 64 - lvx 21, 11, 1 - li 11, 80 - lvx 22, 11, 1 - li 11, 96 - lvx 23, 11, 1 - li 11, 112 - lvx 24, 11, 1 - li 11, 128 - lvx 25, 11, 1 - li 11, 144 - lvx 26, 11, 1 - li 11, 160 - lvx 27, 11, 1 - li 11, 176 - lvx 28, 11, 1 - li 11, 192 - lvx 29, 11, 1 - li 11, 208 - lvx 30, 11, 1 - li 11, 224 - lvx 31, 11, 1 - ld 14, 240(1) - ld 15, 248(1) - ld 16, 256(1) - ld 17, 264(1) - ld 18, 272(1) - ld 19, 280(1) - ld 20, 288(1) - ld 21, 296(1) - ld 22, 304(1) - ld 23, 312(1) - ld 24, 320(1) - ld 25, 328(1) - ld 26, 336(1) - ld 27, 344(1) - ld 28, 352(1) - ld 29, 360(1) - ld 30, 368(1) - ld 31, 376(1) - lfd 14, 384(1) - lfd 15, 392(1) - lfd 16, 400(1) - lfd 17, 408(1) - lfd 18, 416(1) - lfd 19, 424(1) - lfd 20, 432(1) - lfd 21, 440(1) - lfd 22, 448(1) - lfd 23, 456(1) - lfd 24, 464(1) - lfd 25, 472(1) - lfd 26, 480(1) - lfd 27, 488(1) - lfd 28, 496(1) - lfd 29, 504(1) - lfd 30, 512(1) - lfd 31, 520(1) - mfcr 0 - std 0, 480(4) - ld 0, 8(1) - mtcrf 0b00111000, 0 - addi 1, 1, 528 - ld 0, 16(1) - mtlr 0 - blr -.size abi_test_trampoline,.-abi_test_trampoline -.globl abi_test_clobber_r0 -.type abi_test_clobber_r0,@function -.align 5 -abi_test_clobber_r0: -.localentry abi_test_clobber_r0,0 - - li 0, 0 - blr -.size abi_test_clobber_r0,.-abi_test_clobber_r0 -.globl abi_test_clobber_r2 -.type abi_test_clobber_r2,@function -.align 5 -abi_test_clobber_r2: -.localentry abi_test_clobber_r2,0 - - li 2, 0 - blr -.size abi_test_clobber_r2,.-abi_test_clobber_r2 -.globl abi_test_clobber_r3 -.type abi_test_clobber_r3,@function -.align 5 -abi_test_clobber_r3: -.localentry abi_test_clobber_r3,0 - - li 3, 0 - blr -.size abi_test_clobber_r3,.-abi_test_clobber_r3 -.globl abi_test_clobber_r4 -.type abi_test_clobber_r4,@function -.align 5 -abi_test_clobber_r4: -.localentry abi_test_clobber_r4,0 - - li 4, 0 - blr -.size abi_test_clobber_r4,.-abi_test_clobber_r4 -.globl abi_test_clobber_r5 -.type abi_test_clobber_r5,@function -.align 5 -abi_test_clobber_r5: -.localentry abi_test_clobber_r5,0 - - li 5, 0 - blr -.size abi_test_clobber_r5,.-abi_test_clobber_r5 -.globl abi_test_clobber_r6 -.type abi_test_clobber_r6,@function -.align 5 -abi_test_clobber_r6: -.localentry abi_test_clobber_r6,0 - - li 6, 0 - blr -.size abi_test_clobber_r6,.-abi_test_clobber_r6 -.globl abi_test_clobber_r7 -.type abi_test_clobber_r7,@function -.align 5 -abi_test_clobber_r7: -.localentry abi_test_clobber_r7,0 - - li 7, 0 - blr -.size abi_test_clobber_r7,.-abi_test_clobber_r7 -.globl abi_test_clobber_r8 -.type abi_test_clobber_r8,@function -.align 5 -abi_test_clobber_r8: -.localentry abi_test_clobber_r8,0 - - li 8, 0 - blr -.size abi_test_clobber_r8,.-abi_test_clobber_r8 -.globl abi_test_clobber_r9 -.type abi_test_clobber_r9,@function -.align 5 -abi_test_clobber_r9: -.localentry abi_test_clobber_r9,0 - - li 9, 0 - blr -.size abi_test_clobber_r9,.-abi_test_clobber_r9 -.globl abi_test_clobber_r10 -.type abi_test_clobber_r10,@function -.align 5 -abi_test_clobber_r10: -.localentry abi_test_clobber_r10,0 - - li 10, 0 - blr -.size abi_test_clobber_r10,.-abi_test_clobber_r10 -.globl abi_test_clobber_r11 -.type abi_test_clobber_r11,@function -.align 5 -abi_test_clobber_r11: -.localentry abi_test_clobber_r11,0 - - li 11, 0 - blr -.size abi_test_clobber_r11,.-abi_test_clobber_r11 -.globl abi_test_clobber_r12 -.type abi_test_clobber_r12,@function -.align 5 -abi_test_clobber_r12: -.localentry abi_test_clobber_r12,0 - - li 12, 0 - blr -.size abi_test_clobber_r12,.-abi_test_clobber_r12 -.globl abi_test_clobber_r14 -.type abi_test_clobber_r14,@function -.align 5 -abi_test_clobber_r14: -.localentry abi_test_clobber_r14,0 - - li 14, 0 - blr -.size abi_test_clobber_r14,.-abi_test_clobber_r14 -.globl abi_test_clobber_r15 -.type abi_test_clobber_r15,@function -.align 5 -abi_test_clobber_r15: -.localentry abi_test_clobber_r15,0 - - li 15, 0 - blr -.size abi_test_clobber_r15,.-abi_test_clobber_r15 -.globl abi_test_clobber_r16 -.type abi_test_clobber_r16,@function -.align 5 -abi_test_clobber_r16: -.localentry abi_test_clobber_r16,0 - - li 16, 0 - blr -.size abi_test_clobber_r16,.-abi_test_clobber_r16 -.globl abi_test_clobber_r17 -.type abi_test_clobber_r17,@function -.align 5 -abi_test_clobber_r17: -.localentry abi_test_clobber_r17,0 - - li 17, 0 - blr -.size abi_test_clobber_r17,.-abi_test_clobber_r17 -.globl abi_test_clobber_r18 -.type abi_test_clobber_r18,@function -.align 5 -abi_test_clobber_r18: -.localentry abi_test_clobber_r18,0 - - li 18, 0 - blr -.size abi_test_clobber_r18,.-abi_test_clobber_r18 -.globl abi_test_clobber_r19 -.type abi_test_clobber_r19,@function -.align 5 -abi_test_clobber_r19: -.localentry abi_test_clobber_r19,0 - - li 19, 0 - blr -.size abi_test_clobber_r19,.-abi_test_clobber_r19 -.globl abi_test_clobber_r20 -.type abi_test_clobber_r20,@function -.align 5 -abi_test_clobber_r20: -.localentry abi_test_clobber_r20,0 - - li 20, 0 - blr -.size abi_test_clobber_r20,.-abi_test_clobber_r20 -.globl abi_test_clobber_r21 -.type abi_test_clobber_r21,@function -.align 5 -abi_test_clobber_r21: -.localentry abi_test_clobber_r21,0 - - li 21, 0 - blr -.size abi_test_clobber_r21,.-abi_test_clobber_r21 -.globl abi_test_clobber_r22 -.type abi_test_clobber_r22,@function -.align 5 -abi_test_clobber_r22: -.localentry abi_test_clobber_r22,0 - - li 22, 0 - blr -.size abi_test_clobber_r22,.-abi_test_clobber_r22 -.globl abi_test_clobber_r23 -.type abi_test_clobber_r23,@function -.align 5 -abi_test_clobber_r23: -.localentry abi_test_clobber_r23,0 - - li 23, 0 - blr -.size abi_test_clobber_r23,.-abi_test_clobber_r23 -.globl abi_test_clobber_r24 -.type abi_test_clobber_r24,@function -.align 5 -abi_test_clobber_r24: -.localentry abi_test_clobber_r24,0 - - li 24, 0 - blr -.size abi_test_clobber_r24,.-abi_test_clobber_r24 -.globl abi_test_clobber_r25 -.type abi_test_clobber_r25,@function -.align 5 -abi_test_clobber_r25: -.localentry abi_test_clobber_r25,0 - - li 25, 0 - blr -.size abi_test_clobber_r25,.-abi_test_clobber_r25 -.globl abi_test_clobber_r26 -.type abi_test_clobber_r26,@function -.align 5 -abi_test_clobber_r26: -.localentry abi_test_clobber_r26,0 - - li 26, 0 - blr -.size abi_test_clobber_r26,.-abi_test_clobber_r26 -.globl abi_test_clobber_r27 -.type abi_test_clobber_r27,@function -.align 5 -abi_test_clobber_r27: -.localentry abi_test_clobber_r27,0 - - li 27, 0 - blr -.size abi_test_clobber_r27,.-abi_test_clobber_r27 -.globl abi_test_clobber_r28 -.type abi_test_clobber_r28,@function -.align 5 -abi_test_clobber_r28: -.localentry abi_test_clobber_r28,0 - - li 28, 0 - blr -.size abi_test_clobber_r28,.-abi_test_clobber_r28 -.globl abi_test_clobber_r29 -.type abi_test_clobber_r29,@function -.align 5 -abi_test_clobber_r29: -.localentry abi_test_clobber_r29,0 - - li 29, 0 - blr -.size abi_test_clobber_r29,.-abi_test_clobber_r29 -.globl abi_test_clobber_r30 -.type abi_test_clobber_r30,@function -.align 5 -abi_test_clobber_r30: -.localentry abi_test_clobber_r30,0 - - li 30, 0 - blr -.size abi_test_clobber_r30,.-abi_test_clobber_r30 -.globl abi_test_clobber_r31 -.type abi_test_clobber_r31,@function -.align 5 -abi_test_clobber_r31: -.localentry abi_test_clobber_r31,0 - - li 31, 0 - blr -.size abi_test_clobber_r31,.-abi_test_clobber_r31 -.globl abi_test_clobber_f0 -.type abi_test_clobber_f0,@function -.align 4 -abi_test_clobber_f0: -.localentry abi_test_clobber_f0,0 - - li 0, 0 - - std 0, -8(1) - lfd 0, -8(1) - blr -.size abi_test_clobber_f0,.-abi_test_clobber_f0 -.globl abi_test_clobber_f1 -.type abi_test_clobber_f1,@function -.align 4 -abi_test_clobber_f1: -.localentry abi_test_clobber_f1,0 - - li 0, 0 - - std 0, -8(1) - lfd 1, -8(1) - blr -.size abi_test_clobber_f1,.-abi_test_clobber_f1 -.globl abi_test_clobber_f2 -.type abi_test_clobber_f2,@function -.align 4 -abi_test_clobber_f2: -.localentry abi_test_clobber_f2,0 - - li 0, 0 - - std 0, -8(1) - lfd 2, -8(1) - blr -.size abi_test_clobber_f2,.-abi_test_clobber_f2 -.globl abi_test_clobber_f3 -.type abi_test_clobber_f3,@function -.align 4 -abi_test_clobber_f3: -.localentry abi_test_clobber_f3,0 - - li 0, 0 - - std 0, -8(1) - lfd 3, -8(1) - blr -.size abi_test_clobber_f3,.-abi_test_clobber_f3 -.globl abi_test_clobber_f4 -.type abi_test_clobber_f4,@function -.align 4 -abi_test_clobber_f4: -.localentry abi_test_clobber_f4,0 - - li 0, 0 - - std 0, -8(1) - lfd 4, -8(1) - blr -.size abi_test_clobber_f4,.-abi_test_clobber_f4 -.globl abi_test_clobber_f5 -.type abi_test_clobber_f5,@function -.align 4 -abi_test_clobber_f5: -.localentry abi_test_clobber_f5,0 - - li 0, 0 - - std 0, -8(1) - lfd 5, -8(1) - blr -.size abi_test_clobber_f5,.-abi_test_clobber_f5 -.globl abi_test_clobber_f6 -.type abi_test_clobber_f6,@function -.align 4 -abi_test_clobber_f6: -.localentry abi_test_clobber_f6,0 - - li 0, 0 - - std 0, -8(1) - lfd 6, -8(1) - blr -.size abi_test_clobber_f6,.-abi_test_clobber_f6 -.globl abi_test_clobber_f7 -.type abi_test_clobber_f7,@function -.align 4 -abi_test_clobber_f7: -.localentry abi_test_clobber_f7,0 - - li 0, 0 - - std 0, -8(1) - lfd 7, -8(1) - blr -.size abi_test_clobber_f7,.-abi_test_clobber_f7 -.globl abi_test_clobber_f8 -.type abi_test_clobber_f8,@function -.align 4 -abi_test_clobber_f8: -.localentry abi_test_clobber_f8,0 - - li 0, 0 - - std 0, -8(1) - lfd 8, -8(1) - blr -.size abi_test_clobber_f8,.-abi_test_clobber_f8 -.globl abi_test_clobber_f9 -.type abi_test_clobber_f9,@function -.align 4 -abi_test_clobber_f9: -.localentry abi_test_clobber_f9,0 - - li 0, 0 - - std 0, -8(1) - lfd 9, -8(1) - blr -.size abi_test_clobber_f9,.-abi_test_clobber_f9 -.globl abi_test_clobber_f10 -.type abi_test_clobber_f10,@function -.align 4 -abi_test_clobber_f10: -.localentry abi_test_clobber_f10,0 - - li 0, 0 - - std 0, -8(1) - lfd 10, -8(1) - blr -.size abi_test_clobber_f10,.-abi_test_clobber_f10 -.globl abi_test_clobber_f11 -.type abi_test_clobber_f11,@function -.align 4 -abi_test_clobber_f11: -.localentry abi_test_clobber_f11,0 - - li 0, 0 - - std 0, -8(1) - lfd 11, -8(1) - blr -.size abi_test_clobber_f11,.-abi_test_clobber_f11 -.globl abi_test_clobber_f12 -.type abi_test_clobber_f12,@function -.align 4 -abi_test_clobber_f12: -.localentry abi_test_clobber_f12,0 - - li 0, 0 - - std 0, -8(1) - lfd 12, -8(1) - blr -.size abi_test_clobber_f12,.-abi_test_clobber_f12 -.globl abi_test_clobber_f13 -.type abi_test_clobber_f13,@function -.align 4 -abi_test_clobber_f13: -.localentry abi_test_clobber_f13,0 - - li 0, 0 - - std 0, -8(1) - lfd 13, -8(1) - blr -.size abi_test_clobber_f13,.-abi_test_clobber_f13 -.globl abi_test_clobber_f14 -.type abi_test_clobber_f14,@function -.align 4 -abi_test_clobber_f14: -.localentry abi_test_clobber_f14,0 - - li 0, 0 - - std 0, -8(1) - lfd 14, -8(1) - blr -.size abi_test_clobber_f14,.-abi_test_clobber_f14 -.globl abi_test_clobber_f15 -.type abi_test_clobber_f15,@function -.align 4 -abi_test_clobber_f15: -.localentry abi_test_clobber_f15,0 - - li 0, 0 - - std 0, -8(1) - lfd 15, -8(1) - blr -.size abi_test_clobber_f15,.-abi_test_clobber_f15 -.globl abi_test_clobber_f16 -.type abi_test_clobber_f16,@function -.align 4 -abi_test_clobber_f16: -.localentry abi_test_clobber_f16,0 - - li 0, 0 - - std 0, -8(1) - lfd 16, -8(1) - blr -.size abi_test_clobber_f16,.-abi_test_clobber_f16 -.globl abi_test_clobber_f17 -.type abi_test_clobber_f17,@function -.align 4 -abi_test_clobber_f17: -.localentry abi_test_clobber_f17,0 - - li 0, 0 - - std 0, -8(1) - lfd 17, -8(1) - blr -.size abi_test_clobber_f17,.-abi_test_clobber_f17 -.globl abi_test_clobber_f18 -.type abi_test_clobber_f18,@function -.align 4 -abi_test_clobber_f18: -.localentry abi_test_clobber_f18,0 - - li 0, 0 - - std 0, -8(1) - lfd 18, -8(1) - blr -.size abi_test_clobber_f18,.-abi_test_clobber_f18 -.globl abi_test_clobber_f19 -.type abi_test_clobber_f19,@function -.align 4 -abi_test_clobber_f19: -.localentry abi_test_clobber_f19,0 - - li 0, 0 - - std 0, -8(1) - lfd 19, -8(1) - blr -.size abi_test_clobber_f19,.-abi_test_clobber_f19 -.globl abi_test_clobber_f20 -.type abi_test_clobber_f20,@function -.align 4 -abi_test_clobber_f20: -.localentry abi_test_clobber_f20,0 - - li 0, 0 - - std 0, -8(1) - lfd 20, -8(1) - blr -.size abi_test_clobber_f20,.-abi_test_clobber_f20 -.globl abi_test_clobber_f21 -.type abi_test_clobber_f21,@function -.align 4 -abi_test_clobber_f21: -.localentry abi_test_clobber_f21,0 - - li 0, 0 - - std 0, -8(1) - lfd 21, -8(1) - blr -.size abi_test_clobber_f21,.-abi_test_clobber_f21 -.globl abi_test_clobber_f22 -.type abi_test_clobber_f22,@function -.align 4 -abi_test_clobber_f22: -.localentry abi_test_clobber_f22,0 - - li 0, 0 - - std 0, -8(1) - lfd 22, -8(1) - blr -.size abi_test_clobber_f22,.-abi_test_clobber_f22 -.globl abi_test_clobber_f23 -.type abi_test_clobber_f23,@function -.align 4 -abi_test_clobber_f23: -.localentry abi_test_clobber_f23,0 - - li 0, 0 - - std 0, -8(1) - lfd 23, -8(1) - blr -.size abi_test_clobber_f23,.-abi_test_clobber_f23 -.globl abi_test_clobber_f24 -.type abi_test_clobber_f24,@function -.align 4 -abi_test_clobber_f24: -.localentry abi_test_clobber_f24,0 - - li 0, 0 - - std 0, -8(1) - lfd 24, -8(1) - blr -.size abi_test_clobber_f24,.-abi_test_clobber_f24 -.globl abi_test_clobber_f25 -.type abi_test_clobber_f25,@function -.align 4 -abi_test_clobber_f25: -.localentry abi_test_clobber_f25,0 - - li 0, 0 - - std 0, -8(1) - lfd 25, -8(1) - blr -.size abi_test_clobber_f25,.-abi_test_clobber_f25 -.globl abi_test_clobber_f26 -.type abi_test_clobber_f26,@function -.align 4 -abi_test_clobber_f26: -.localentry abi_test_clobber_f26,0 - - li 0, 0 - - std 0, -8(1) - lfd 26, -8(1) - blr -.size abi_test_clobber_f26,.-abi_test_clobber_f26 -.globl abi_test_clobber_f27 -.type abi_test_clobber_f27,@function -.align 4 -abi_test_clobber_f27: -.localentry abi_test_clobber_f27,0 - - li 0, 0 - - std 0, -8(1) - lfd 27, -8(1) - blr -.size abi_test_clobber_f27,.-abi_test_clobber_f27 -.globl abi_test_clobber_f28 -.type abi_test_clobber_f28,@function -.align 4 -abi_test_clobber_f28: -.localentry abi_test_clobber_f28,0 - - li 0, 0 - - std 0, -8(1) - lfd 28, -8(1) - blr -.size abi_test_clobber_f28,.-abi_test_clobber_f28 -.globl abi_test_clobber_f29 -.type abi_test_clobber_f29,@function -.align 4 -abi_test_clobber_f29: -.localentry abi_test_clobber_f29,0 - - li 0, 0 - - std 0, -8(1) - lfd 29, -8(1) - blr -.size abi_test_clobber_f29,.-abi_test_clobber_f29 -.globl abi_test_clobber_f30 -.type abi_test_clobber_f30,@function -.align 4 -abi_test_clobber_f30: -.localentry abi_test_clobber_f30,0 - - li 0, 0 - - std 0, -8(1) - lfd 30, -8(1) - blr -.size abi_test_clobber_f30,.-abi_test_clobber_f30 -.globl abi_test_clobber_f31 -.type abi_test_clobber_f31,@function -.align 4 -abi_test_clobber_f31: -.localentry abi_test_clobber_f31,0 - - li 0, 0 - - std 0, -8(1) - lfd 31, -8(1) - blr -.size abi_test_clobber_f31,.-abi_test_clobber_f31 -.globl abi_test_clobber_v0 -.type abi_test_clobber_v0,@function -.align 4 -abi_test_clobber_v0: -.localentry abi_test_clobber_v0,0 - - vxor 0, 0, 0 - blr -.size abi_test_clobber_v0,.-abi_test_clobber_v0 -.globl abi_test_clobber_v1 -.type abi_test_clobber_v1,@function -.align 4 -abi_test_clobber_v1: -.localentry abi_test_clobber_v1,0 - - vxor 1, 1, 1 - blr -.size abi_test_clobber_v1,.-abi_test_clobber_v1 -.globl abi_test_clobber_v2 -.type abi_test_clobber_v2,@function -.align 4 -abi_test_clobber_v2: -.localentry abi_test_clobber_v2,0 - - vxor 2, 2, 2 - blr -.size abi_test_clobber_v2,.-abi_test_clobber_v2 -.globl abi_test_clobber_v3 -.type abi_test_clobber_v3,@function -.align 4 -abi_test_clobber_v3: -.localentry abi_test_clobber_v3,0 - - vxor 3, 3, 3 - blr -.size abi_test_clobber_v3,.-abi_test_clobber_v3 -.globl abi_test_clobber_v4 -.type abi_test_clobber_v4,@function -.align 4 -abi_test_clobber_v4: -.localentry abi_test_clobber_v4,0 - - vxor 4, 4, 4 - blr -.size abi_test_clobber_v4,.-abi_test_clobber_v4 -.globl abi_test_clobber_v5 -.type abi_test_clobber_v5,@function -.align 4 -abi_test_clobber_v5: -.localentry abi_test_clobber_v5,0 - - vxor 5, 5, 5 - blr -.size abi_test_clobber_v5,.-abi_test_clobber_v5 -.globl abi_test_clobber_v6 -.type abi_test_clobber_v6,@function -.align 4 -abi_test_clobber_v6: -.localentry abi_test_clobber_v6,0 - - vxor 6, 6, 6 - blr -.size abi_test_clobber_v6,.-abi_test_clobber_v6 -.globl abi_test_clobber_v7 -.type abi_test_clobber_v7,@function -.align 4 -abi_test_clobber_v7: -.localentry abi_test_clobber_v7,0 - - vxor 7, 7, 7 - blr -.size abi_test_clobber_v7,.-abi_test_clobber_v7 -.globl abi_test_clobber_v8 -.type abi_test_clobber_v8,@function -.align 4 -abi_test_clobber_v8: -.localentry abi_test_clobber_v8,0 - - vxor 8, 8, 8 - blr -.size abi_test_clobber_v8,.-abi_test_clobber_v8 -.globl abi_test_clobber_v9 -.type abi_test_clobber_v9,@function -.align 4 -abi_test_clobber_v9: -.localentry abi_test_clobber_v9,0 - - vxor 9, 9, 9 - blr -.size abi_test_clobber_v9,.-abi_test_clobber_v9 -.globl abi_test_clobber_v10 -.type abi_test_clobber_v10,@function -.align 4 -abi_test_clobber_v10: -.localentry abi_test_clobber_v10,0 - - vxor 10, 10, 10 - blr -.size abi_test_clobber_v10,.-abi_test_clobber_v10 -.globl abi_test_clobber_v11 -.type abi_test_clobber_v11,@function -.align 4 -abi_test_clobber_v11: -.localentry abi_test_clobber_v11,0 - - vxor 11, 11, 11 - blr -.size abi_test_clobber_v11,.-abi_test_clobber_v11 -.globl abi_test_clobber_v12 -.type abi_test_clobber_v12,@function -.align 4 -abi_test_clobber_v12: -.localentry abi_test_clobber_v12,0 - - vxor 12, 12, 12 - blr -.size abi_test_clobber_v12,.-abi_test_clobber_v12 -.globl abi_test_clobber_v13 -.type abi_test_clobber_v13,@function -.align 4 -abi_test_clobber_v13: -.localentry abi_test_clobber_v13,0 - - vxor 13, 13, 13 - blr -.size abi_test_clobber_v13,.-abi_test_clobber_v13 -.globl abi_test_clobber_v14 -.type abi_test_clobber_v14,@function -.align 4 -abi_test_clobber_v14: -.localentry abi_test_clobber_v14,0 - - vxor 14, 14, 14 - blr -.size abi_test_clobber_v14,.-abi_test_clobber_v14 -.globl abi_test_clobber_v15 -.type abi_test_clobber_v15,@function -.align 4 -abi_test_clobber_v15: -.localentry abi_test_clobber_v15,0 - - vxor 15, 15, 15 - blr -.size abi_test_clobber_v15,.-abi_test_clobber_v15 -.globl abi_test_clobber_v16 -.type abi_test_clobber_v16,@function -.align 4 -abi_test_clobber_v16: -.localentry abi_test_clobber_v16,0 - - vxor 16, 16, 16 - blr -.size abi_test_clobber_v16,.-abi_test_clobber_v16 -.globl abi_test_clobber_v17 -.type abi_test_clobber_v17,@function -.align 4 -abi_test_clobber_v17: -.localentry abi_test_clobber_v17,0 - - vxor 17, 17, 17 - blr -.size abi_test_clobber_v17,.-abi_test_clobber_v17 -.globl abi_test_clobber_v18 -.type abi_test_clobber_v18,@function -.align 4 -abi_test_clobber_v18: -.localentry abi_test_clobber_v18,0 - - vxor 18, 18, 18 - blr -.size abi_test_clobber_v18,.-abi_test_clobber_v18 -.globl abi_test_clobber_v19 -.type abi_test_clobber_v19,@function -.align 4 -abi_test_clobber_v19: -.localentry abi_test_clobber_v19,0 - - vxor 19, 19, 19 - blr -.size abi_test_clobber_v19,.-abi_test_clobber_v19 -.globl abi_test_clobber_v20 -.type abi_test_clobber_v20,@function -.align 4 -abi_test_clobber_v20: -.localentry abi_test_clobber_v20,0 - - vxor 20, 20, 20 - blr -.size abi_test_clobber_v20,.-abi_test_clobber_v20 -.globl abi_test_clobber_v21 -.type abi_test_clobber_v21,@function -.align 4 -abi_test_clobber_v21: -.localentry abi_test_clobber_v21,0 - - vxor 21, 21, 21 - blr -.size abi_test_clobber_v21,.-abi_test_clobber_v21 -.globl abi_test_clobber_v22 -.type abi_test_clobber_v22,@function -.align 4 -abi_test_clobber_v22: -.localentry abi_test_clobber_v22,0 - - vxor 22, 22, 22 - blr -.size abi_test_clobber_v22,.-abi_test_clobber_v22 -.globl abi_test_clobber_v23 -.type abi_test_clobber_v23,@function -.align 4 -abi_test_clobber_v23: -.localentry abi_test_clobber_v23,0 - - vxor 23, 23, 23 - blr -.size abi_test_clobber_v23,.-abi_test_clobber_v23 -.globl abi_test_clobber_v24 -.type abi_test_clobber_v24,@function -.align 4 -abi_test_clobber_v24: -.localentry abi_test_clobber_v24,0 - - vxor 24, 24, 24 - blr -.size abi_test_clobber_v24,.-abi_test_clobber_v24 -.globl abi_test_clobber_v25 -.type abi_test_clobber_v25,@function -.align 4 -abi_test_clobber_v25: -.localentry abi_test_clobber_v25,0 - - vxor 25, 25, 25 - blr -.size abi_test_clobber_v25,.-abi_test_clobber_v25 -.globl abi_test_clobber_v26 -.type abi_test_clobber_v26,@function -.align 4 -abi_test_clobber_v26: -.localentry abi_test_clobber_v26,0 - - vxor 26, 26, 26 - blr -.size abi_test_clobber_v26,.-abi_test_clobber_v26 -.globl abi_test_clobber_v27 -.type abi_test_clobber_v27,@function -.align 4 -abi_test_clobber_v27: -.localentry abi_test_clobber_v27,0 - - vxor 27, 27, 27 - blr -.size abi_test_clobber_v27,.-abi_test_clobber_v27 -.globl abi_test_clobber_v28 -.type abi_test_clobber_v28,@function -.align 4 -abi_test_clobber_v28: -.localentry abi_test_clobber_v28,0 - - vxor 28, 28, 28 - blr -.size abi_test_clobber_v28,.-abi_test_clobber_v28 -.globl abi_test_clobber_v29 -.type abi_test_clobber_v29,@function -.align 4 -abi_test_clobber_v29: -.localentry abi_test_clobber_v29,0 - - vxor 29, 29, 29 - blr -.size abi_test_clobber_v29,.-abi_test_clobber_v29 -.globl abi_test_clobber_v30 -.type abi_test_clobber_v30,@function -.align 4 -abi_test_clobber_v30: -.localentry abi_test_clobber_v30,0 - - vxor 30, 30, 30 - blr -.size abi_test_clobber_v30,.-abi_test_clobber_v30 -.globl abi_test_clobber_v31 -.type abi_test_clobber_v31,@function -.align 4 -abi_test_clobber_v31: -.localentry abi_test_clobber_v31,0 - - vxor 31, 31, 31 - blr -.size abi_test_clobber_v31,.-abi_test_clobber_v31 -.globl abi_test_clobber_cr0 -.type abi_test_clobber_cr0,@function -.align 4 -abi_test_clobber_cr0: -.localentry abi_test_clobber_cr0,0 - - - - mfcr 0 - not 0, 0 - mtcrf 128, 0 - blr -.size abi_test_clobber_cr0,.-abi_test_clobber_cr0 -.globl abi_test_clobber_cr1 -.type abi_test_clobber_cr1,@function -.align 4 -abi_test_clobber_cr1: -.localentry abi_test_clobber_cr1,0 - - - - mfcr 0 - not 0, 0 - mtcrf 64, 0 - blr -.size abi_test_clobber_cr1,.-abi_test_clobber_cr1 -.globl abi_test_clobber_cr2 -.type abi_test_clobber_cr2,@function -.align 4 -abi_test_clobber_cr2: -.localentry abi_test_clobber_cr2,0 - - - - mfcr 0 - not 0, 0 - mtcrf 32, 0 - blr -.size abi_test_clobber_cr2,.-abi_test_clobber_cr2 -.globl abi_test_clobber_cr3 -.type abi_test_clobber_cr3,@function -.align 4 -abi_test_clobber_cr3: -.localentry abi_test_clobber_cr3,0 - - - - mfcr 0 - not 0, 0 - mtcrf 16, 0 - blr -.size abi_test_clobber_cr3,.-abi_test_clobber_cr3 -.globl abi_test_clobber_cr4 -.type abi_test_clobber_cr4,@function -.align 4 -abi_test_clobber_cr4: -.localentry abi_test_clobber_cr4,0 - - - - mfcr 0 - not 0, 0 - mtcrf 8, 0 - blr -.size abi_test_clobber_cr4,.-abi_test_clobber_cr4 -.globl abi_test_clobber_cr5 -.type abi_test_clobber_cr5,@function -.align 4 -abi_test_clobber_cr5: -.localentry abi_test_clobber_cr5,0 - - - - mfcr 0 - not 0, 0 - mtcrf 4, 0 - blr -.size abi_test_clobber_cr5,.-abi_test_clobber_cr5 -.globl abi_test_clobber_cr6 -.type abi_test_clobber_cr6,@function -.align 4 -abi_test_clobber_cr6: -.localentry abi_test_clobber_cr6,0 - - - - mfcr 0 - not 0, 0 - mtcrf 2, 0 - blr -.size abi_test_clobber_cr6,.-abi_test_clobber_cr6 -.globl abi_test_clobber_cr7 -.type abi_test_clobber_cr7,@function -.align 4 -abi_test_clobber_cr7: -.localentry abi_test_clobber_cr7,0 - - - - mfcr 0 - not 0, 0 - mtcrf 1, 0 - blr -.size abi_test_clobber_cr7,.-abi_test_clobber_cr7 -.globl abi_test_clobber_ctr -.type abi_test_clobber_ctr,@function -.align 4 -abi_test_clobber_ctr: -.localentry abi_test_clobber_ctr,0 - - li 0, 0 - mtctr 0 - blr -.size abi_test_clobber_ctr,.-abi_test_clobber_ctr - -.globl abi_test_clobber_lr -.type abi_test_clobber_lr,@function -.align 4 -abi_test_clobber_lr: -.localentry abi_test_clobber_lr,0 - - mflr 0 - mtctr 0 - li 0, 0 - mtlr 0 - bctr -.size abi_test_clobber_lr,.-abi_test_clobber_lr - -#endif // !OPENSSL_NO_ASM && __powerpc64__ -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86.S b/third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86-linux.S index 0ae7a4bb..17d280d4 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/chacha/chacha-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -971,5 +977,8 @@ ChaCha20_ssse3: .byte 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 .byte 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 .byte 114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86-linux.S index 00a6ec21..34e1e432 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/aesni-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2509,5 +2515,8 @@ aes_hw_set_decrypt_key: .byte 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 .byte 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 .byte 115,108,46,111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586-linux.S index 638c0361..d3b83f89 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/bn-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -993,5 +999,8 @@ bn_sub_words: popl %ebp ret .size bn_sub_words,.-.L_bn_sub_words_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586-linux.S index f1e67caf..bb75ab4c 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/co-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1262,5 +1268,8 @@ bn_sqr_comba4: popl %esi ret .size bn_sqr_comba4,.-.L_bn_sqr_comba4_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86-linux.S similarity index 93% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86-linux.S index 840e4389..19fd370b 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-ssse3-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -290,5 +296,8 @@ gcm_ghash_ssse3: .align 16 .Llow4_mask: .long 252645135,252645135,252645135,252645135 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86-linux.S similarity index 94% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86-linux.S index 13b94457..e912e86d 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/ghash-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -326,5 +332,8 @@ gcm_ghash_clmul: .byte 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 .byte 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 .byte 0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586-linux.S index 58872344..d28e1f4e 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/md5-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -684,5 +690,8 @@ md5_block_asm_data_order: popl %esi ret .size md5_block_asm_data_order,.-.L_md5_block_asm_data_order_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586-linux.S index e224da4d..b63882db 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha1-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -3804,5 +3810,8 @@ _sha1_block_data_order_avx: .byte 102,111,114,109,32,102,111,114,32,120,56,54,44,32,67,82 .byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 .byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586-linux.S index dcaf8755..8eb929f4 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha256-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -5563,5 +5569,8 @@ sha256_block_data_order: popl %ebp ret .size sha256_block_data_order,.-.L_sha256_block_data_order_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586-linux.S index 282cddaa..eb0695ef 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/sha512-586-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -2833,5 +2839,8 @@ sha512_block_data_order: .byte 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97 .byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 .byte 62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86-linux.S similarity index 97% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86-linux.S index 66bd5f5e..efd56e38 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/vpaes-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -704,5 +710,8 @@ vpaes_cbc_encrypt: popl %ebp ret .size vpaes_cbc_encrypt,.-.L_vpaes_cbc_encrypt_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont.S b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont-linux.S similarity index 95% rename from third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont.S rename to third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont-linux.S index 5de32518..2085caf4 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont.S +++ b/third_party/boringssl/kit/linux-x86/crypto/fipsmodule/x86-mont-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -480,5 +486,8 @@ bn_mul_mont: .byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 .byte 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 .byte 111,114,103,62,0 +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86.S b/third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86-linux.S similarity index 93% rename from third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86.S rename to third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86-linux.S index e7162dfa..3d560af3 100644 --- a/third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86.S +++ b/third_party/boringssl/kit/linux-x86/crypto/test/trampoline-x86-linux.S @@ -1,7 +1,13 @@ // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -202,5 +208,8 @@ abi_test_clobber_xmm7: pxor %xmm7,%xmm7 ret .size abi_test_clobber_xmm7,.-.L_abi_test_clobber_xmm7_begin +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && defined(__ELF__) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64-linux.S index b862f4e9..57919a25 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/chacha/chacha-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -16,6 +16,7 @@ .extern OPENSSL_ia32cap_P .hidden OPENSSL_ia32cap_P +.section .rodata .align 64 .Lzero: .long 0,0,0,0 @@ -45,6 +46,7 @@ .Lsixteen: .long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .byte 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .globl ChaCha20_ctr32 .hidden ChaCha20_ctr32 .type ChaCha20_ctr32,@function @@ -1630,4 +1632,7 @@ ChaCha20_8x: .cfi_endproc .size ChaCha20_8x,.-ChaCha20_8x #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.S index 2e41e91f..dff6ddaa 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-linux.S @@ -7,11 +7,11 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif -.data +.section .rodata .align 16 one: @@ -3076,4 +3076,7 @@ aes256gcmsiv_kdf: .cfi_endproc .size aes256gcmsiv_kdf, .-aes256gcmsiv_kdf #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.S index 2f3f641a..cb4df762 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -17,6 +17,7 @@ chacha20_poly1305_constants: +.section .rodata .align 64 .Lchacha20_consts: .byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' @@ -54,6 +55,7 @@ chacha20_poly1305_constants: .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +.text .type poly_hash_ad_internal,@function .align 64 @@ -8919,4 +8921,7 @@ chacha20_poly1305_seal_avx2: .cfi_endproc .size chacha20_poly1305_seal_avx2, .-chacha20_poly1305_seal_avx2 #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-linux.S similarity index 92% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-linux.S index b28f7f80..340cc9e5 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -221,7 +221,7 @@ _aesni_ctr32_ghash_6x: movbeq 0(%r14),%r12 vaesenc %xmm1,%xmm14,%xmm14 vmovups 160-128(%rcx),%xmm1 - cmpl $11,%ebp + cmpl $11,%r10d jb .Lenc_tail vaesenc %xmm15,%xmm9,%xmm9 @@ -305,6 +305,9 @@ _aesni_ctr32_ghash_6x: vpaddb %xmm2,%xmm1,%xmm0 movq %r13,112+8(%rsp) leaq 96(%rdi),%rdi + + prefetcht0 512(%rdi) + prefetcht0 576(%rdi) vaesenclast %xmm5,%xmm11,%xmm11 vpaddb %xmm2,%xmm0,%xmm5 movq %r12,120+8(%rsp) @@ -317,7 +320,7 @@ _aesni_ctr32_ghash_6x: vaesenclast %xmm3,%xmm14,%xmm14 vpaddb %xmm2,%xmm7,%xmm3 - addq $0x60,%r10 + addq $0x60,%rax subq $0x6,%rdx jc .L6x_done @@ -349,41 +352,50 @@ _aesni_ctr32_ghash_6x: .align 32 aesni_gcm_decrypt: .cfi_startproc - xorq %r10,%r10 + + xorq %rax,%rax cmpq $0x60,%rdx jb .Lgcm_dec_abort - leaq (%rsp),%rax -.cfi_def_cfa_register %rax - pushq %rbx -.cfi_offset %rbx,-16 pushq %rbp -.cfi_offset %rbp,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + pushq %rbx +.cfi_offset %rbx,-24 + pushq %r12 .cfi_offset %r12,-32 + pushq %r13 .cfi_offset %r13,-40 + pushq %r14 .cfi_offset %r14,-48 + pushq %r15 .cfi_offset %r15,-56 + vzeroupper + movq 16(%rbp),%r12 vmovdqu (%r8),%xmm1 addq $-128,%rsp movl 12(%r8),%ebx leaq .Lbswap_mask(%rip),%r11 leaq -128(%rcx),%r14 movq $0xf80,%r15 - vmovdqu (%r9),%xmm8 + vmovdqu (%r12),%xmm8 andq $-128,%rsp vmovdqu (%r11),%xmm0 leaq 128(%rcx),%rcx - leaq 32+32(%r9),%r9 - movl 240-128(%rcx),%ebp + leaq 32(%r9),%r9 + movl 240-128(%rcx),%r10d vpshufb %xmm0,%xmm8,%xmm8 andq %r15,%r14 @@ -396,7 +408,7 @@ aesni_gcm_decrypt: .Ldec_no_key_aliasing: vmovdqu 80(%rdi),%xmm7 - leaq (%rdi),%r14 + movq %rdi,%r14 vmovdqu 64(%rdi),%xmm4 @@ -409,7 +421,7 @@ aesni_gcm_decrypt: vmovdqu 48(%rdi),%xmm5 shrq $4,%rdx - xorq %r10,%r10 + xorq %rax,%rax vmovdqu 32(%rdi),%xmm6 vpshufb %xmm0,%xmm7,%xmm7 vmovdqu 16(%rdi),%xmm2 @@ -427,6 +439,7 @@ aesni_gcm_decrypt: call _aesni_ctr32_ghash_6x + movq 16(%rbp),%r12 vmovups %xmm9,-96(%rsi) vmovups %xmm10,-80(%rsi) vmovups %xmm11,-64(%rsi) @@ -435,26 +448,32 @@ aesni_gcm_decrypt: vmovups %xmm14,-16(%rsi) vpshufb (%r11),%xmm8,%xmm8 - vmovdqu %xmm8,-64(%r9) + vmovdqu %xmm8,(%r12) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp +.cfi_def_cfa %rsp, 0x38 + popq %r15 +.cfi_adjust_cfa_offset -8 .cfi_restore %r15 - movq -40(%rax),%r14 + popq %r14 +.cfi_adjust_cfa_offset -8 .cfi_restore %r14 - movq -32(%rax),%r13 + popq %r13 +.cfi_adjust_cfa_offset -8 .cfi_restore %r13 - movq -24(%rax),%r12 + popq %r12 +.cfi_adjust_cfa_offset -8 .cfi_restore %r12 - movq -16(%rax),%rbp -.cfi_restore %rbp - movq -8(%rax),%rbx + popq %rbx +.cfi_adjust_cfa_offset -8 .cfi_restore %rbx - leaq (%rax),%rsp -.cfi_def_cfa_register %rsp + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp .Lgcm_dec_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .cfi_endproc .size aesni_gcm_decrypt,.-aesni_gcm_decrypt .type _aesni_ctr32_6x,@function @@ -463,7 +482,7 @@ _aesni_ctr32_6x: .cfi_startproc vmovdqu 0-128(%rcx),%xmm4 vmovdqu 32(%r11),%xmm2 - leaq -1(%rbp),%r13 + leaq -1(%r10),%r13 vmovups 16-128(%rcx),%xmm15 leaq 32-128(%rcx),%r12 vpxor %xmm4,%xmm1,%xmm9 @@ -556,12 +575,13 @@ _aesni_ctr32_6x: .align 32 aesni_gcm_encrypt: .cfi_startproc + #ifdef BORINGSSL_DISPATCH_TEST .extern BORINGSSL_function_hit .hidden BORINGSSL_function_hit movb $1,BORINGSSL_function_hit+2(%rip) #endif - xorq %r10,%r10 + xorq %rax,%rax @@ -569,20 +589,27 @@ aesni_gcm_encrypt: cmpq $288,%rdx jb .Lgcm_enc_abort - leaq (%rsp),%rax -.cfi_def_cfa_register %rax - pushq %rbx -.cfi_offset %rbx,-16 pushq %rbp -.cfi_offset %rbp,-24 +.cfi_adjust_cfa_offset 8 +.cfi_offset %rbp,-16 + + movq %rsp,%rbp +.cfi_def_cfa_register %rbp + pushq %rbx +.cfi_offset %rbx,-24 + pushq %r12 .cfi_offset %r12,-32 + pushq %r13 .cfi_offset %r13,-40 + pushq %r14 .cfi_offset %r14,-48 + pushq %r15 .cfi_offset %r15,-56 + vzeroupper vmovdqu (%r8),%xmm1 @@ -594,7 +621,7 @@ aesni_gcm_encrypt: leaq 128(%rcx),%rcx vmovdqu (%r11),%xmm0 andq $-128,%rsp - movl 240-128(%rcx),%ebp + movl 240-128(%rcx),%r10d andq %r15,%r14 andq %rsp,%r15 @@ -605,7 +632,7 @@ aesni_gcm_encrypt: subq %r15,%rsp .Lenc_no_key_aliasing: - leaq (%rsi),%r14 + movq %rsi,%r14 @@ -633,10 +660,11 @@ aesni_gcm_encrypt: call _aesni_ctr32_6x - vmovdqu (%r9),%xmm8 - leaq 32+32(%r9),%r9 + movq 16(%rbp),%r12 + leaq 32(%r9),%r9 + vmovdqu (%r12),%xmm8 subq $12,%rdx - movq $192,%r10 + movq $192,%rax vpshufb %xmm0,%xmm8,%xmm8 call _aesni_ctr32_ghash_6x @@ -812,29 +840,37 @@ aesni_gcm_encrypt: vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8 vpxor %xmm7,%xmm2,%xmm2 vpxor %xmm2,%xmm8,%xmm8 + movq 16(%rbp),%r12 vpshufb (%r11),%xmm8,%xmm8 - vmovdqu %xmm8,-64(%r9) + vmovdqu %xmm8,(%r12) vzeroupper - movq -48(%rax),%r15 + leaq -40(%rbp),%rsp +.cfi_def_cfa %rsp, 0x38 + popq %r15 +.cfi_adjust_cfa_offset -8 .cfi_restore %r15 - movq -40(%rax),%r14 + popq %r14 +.cfi_adjust_cfa_offset -8 .cfi_restore %r14 - movq -32(%rax),%r13 + popq %r13 +.cfi_adjust_cfa_offset -8 .cfi_restore %r13 - movq -24(%rax),%r12 + popq %r12 +.cfi_adjust_cfa_offset -8 .cfi_restore %r12 - movq -16(%rax),%rbp -.cfi_restore %rbp - movq -8(%rax),%rbx + popq %rbx +.cfi_adjust_cfa_offset -8 .cfi_restore %rbx - leaq (%rax),%rsp -.cfi_def_cfa_register %rsp + popq %rbp +.cfi_adjust_cfa_offset -8 +.cfi_restore %rbp .Lgcm_enc_abort: - movq %r10,%rax .byte 0xf3,0xc3 + .cfi_endproc -.size aesni_gcm_encrypt,.-aesni_gcm_encrypt +.size aesni_gcm_decrypt,.-aesni_gcm_decrypt +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -848,5 +884,9 @@ aesni_gcm_encrypt: .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64-linux.S index 2d4654f8..fd962c84 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/aesni-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1262,6 +1262,8 @@ aes_hw_ctr32_encrypt_blocks: pxor %xmm0,%xmm13 movdqu 80(%rdi),%xmm15 pxor %xmm0,%xmm14 + prefetcht0 448(%rdi) + prefetcht0 512(%rdi) pxor %xmm0,%xmm15 .byte 102,15,56,220,209 .byte 102,15,56,220,217 @@ -2480,6 +2482,7 @@ __aesni_set_encrypt_key: .byte 0xf3,0xc3 .size aes_hw_set_encrypt_key,.-aes_hw_set_encrypt_key .size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -2502,5 +2505,9 @@ __aesni_set_encrypt_key: .byte 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-linux.S index b5fbdc81..0754e9bd 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -23,7 +23,7 @@ .align 16 gcm_gmult_ssse3: .cfi_startproc -.Lgmult_seh_begin: + movdqu (%rdi),%xmm0 movdqa .Lreverse_bytes(%rip),%xmm10 movdqa .Llow4_mask(%rip),%xmm2 @@ -199,8 +199,8 @@ gcm_gmult_ssse3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -.Lgmult_seh_end: .cfi_endproc + .size gcm_gmult_ssse3,.-gcm_gmult_ssse3 @@ -212,8 +212,8 @@ gcm_gmult_ssse3: .hidden gcm_ghash_ssse3 .align 16 gcm_ghash_ssse3: -.Lghash_seh_begin: .cfi_startproc + movdqu (%rdi),%xmm0 movdqa .Lreverse_bytes(%rip),%xmm10 movdqa .Llow4_mask(%rip),%xmm11 @@ -411,10 +411,11 @@ gcm_ghash_ssse3: pxor %xmm5,%xmm5 pxor %xmm6,%xmm6 .byte 0xf3,0xc3 -.Lghash_seh_end: .cfi_endproc + .size gcm_ghash_ssse3,.-gcm_ghash_ssse3 +.section .rodata .align 16 @@ -423,5 +424,9 @@ gcm_ghash_ssse3: .Llow4_mask: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64-linux.S index 91cea671..e0cbc99a 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/ghash-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -20,6 +20,7 @@ .align 16 gcm_init_clmul: .cfi_startproc + .L_init_clmul: movdqu (%rsi),%xmm2 pshufd $78,%xmm2,%xmm2 @@ -172,6 +173,7 @@ gcm_init_clmul: movdqu %xmm4,80(%rdi) .byte 0xf3,0xc3 .cfi_endproc + .size gcm_init_clmul,.-gcm_init_clmul .globl gcm_gmult_clmul .hidden gcm_gmult_clmul @@ -233,6 +235,7 @@ gcm_gmult_clmul: .align 32 gcm_ghash_clmul: .cfi_startproc + .L_ghash_clmul: movdqa .Lbswap_mask(%rip),%xmm10 @@ -613,6 +616,7 @@ gcm_ghash_clmul: movdqu %xmm0,(%rdi) .byte 0xf3,0xc3 .cfi_endproc + .size gcm_ghash_clmul,.-gcm_ghash_clmul .globl gcm_init_avx .hidden gcm_init_avx @@ -722,6 +726,7 @@ gcm_init_avx: vzeroupper .byte 0xf3,0xc3 + .cfi_endproc .size gcm_init_avx,.-gcm_init_avx .globl gcm_gmult_avx @@ -1111,7 +1116,9 @@ gcm_ghash_avx: vzeroupper .byte 0xf3,0xc3 .cfi_endproc + .size gcm_ghash_avx,.-gcm_ghash_avx +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -1123,5 +1130,9 @@ gcm_ghash_avx: .byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64-linux.S index 4f082070..88ba8b29 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/md5-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -699,4 +699,7 @@ md5_block_asm_data_order: .cfi_endproc .size md5_block_asm_data_order,.-md5_block_asm_data_order #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm-linux.S index 655f1a2a..56a48ad7 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -16,6 +16,7 @@ .hidden OPENSSL_ia32cap_P +.section .rodata .align 64 .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 @@ -34,6 +35,7 @@ .quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 .LordK: .quad 0xccd1c8aaee00bc4f +.text @@ -4540,4 +4542,7 @@ ecp_nistz256_point_add_affinex: .cfi_endproc .size ecp_nistz256_point_add_affinex,.-ecp_nistz256_point_add_affinex #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.S similarity index 96% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.S index cf056e3e..5c0eaf7d 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -340,4 +340,7 @@ beeu_mod_inverse_vartime: .size beeu_mod_inverse_vartime, .-beeu_mod_inverse_vartime #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64-linux.S similarity index 85% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64-linux.S index b392637c..44eb652d 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rdrand-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -60,4 +60,7 @@ CRYPTO_rdrand_multiple8_buf: .cfi_endproc .size CRYPTO_rdrand_multiple8_buf,.-CRYPTO_rdrand_multiple8_buf #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2-linux.S index 0f8a978a..ccf5478d 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/rsaz-avx2-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1733,6 +1733,7 @@ rsaz_1024_gather5_avx2: .cfi_endproc .LSEH_end_rsaz_1024_gather5: .size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2 +.section .rodata .align 64 .Land_mask: .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1745,5 +1746,9 @@ rsaz_1024_gather5_avx2: .long 2,2,2,2, 3,3,3,3 .long 4,4,4,4, 4,4,4,4 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64-linux.S index cf2e7bc7..f9c7250d 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha1-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1299,6 +1299,7 @@ _shaext_shortcut: leaq 64(%rsi),%r8 paddd %xmm4,%xmm1 cmovneq %r8,%rsi + prefetcht0 512(%rsi) movdqa %xmm0,%xmm8 .byte 15,56,201,229 movdqa %xmm0,%xmm2 @@ -5449,6 +5450,7 @@ _avx2_shortcut: .byte 0xf3,0xc3 .cfi_endproc .size sha1_block_data_order_avx2,.-sha1_block_data_order_avx2 +.section .rodata .align 64 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -5464,5 +5466,9 @@ K_XX_XX: .byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 64 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64-linux.S similarity index 93% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64-linux.S index a09764ae..9472e2bd 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha256-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -25,6 +25,8 @@ sha256_block_data_order: movl 0(%r11),%r9d movl 4(%r11),%r10d movl 8(%r11),%r11d + testl $536870912,%r11d + jnz .Lshaext_shortcut andl $1073741824,%r9d andl $268435968,%r10d orl %r9d,%r10d @@ -1738,6 +1740,7 @@ sha256_block_data_order: .byte 0xf3,0xc3 .cfi_endproc .size sha256_block_data_order,.-sha256_block_data_order +.section .rodata .align 64 .type K256,@object K256: @@ -1781,6 +1784,216 @@ K256: .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text +.type sha256_block_data_order_shaext,@function +.align 64 +sha256_block_data_order_shaext: +.cfi_startproc +.Lshaext_shortcut: + leaq K256+128(%rip),%rcx + movdqu (%rdi),%xmm1 + movdqu 16(%rdi),%xmm2 + movdqa 512-128(%rcx),%xmm7 + + pshufd $0x1b,%xmm1,%xmm0 + pshufd $0xb1,%xmm1,%xmm1 + pshufd $0x1b,%xmm2,%xmm2 + movdqa %xmm7,%xmm8 +.byte 102,15,58,15,202,8 + punpcklqdq %xmm0,%xmm2 + jmp .Loop_shaext + +.align 16 +.Loop_shaext: + movdqu (%rsi),%xmm3 + movdqu 16(%rsi),%xmm4 + movdqu 32(%rsi),%xmm5 +.byte 102,15,56,0,223 + movdqu 48(%rsi),%xmm6 + + movdqa 0-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 102,15,56,0,231 + movdqa %xmm2,%xmm10 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + nop + movdqa %xmm1,%xmm9 +.byte 15,56,203,202 + + movdqa 32-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 102,15,56,0,239 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + leaq 64(%rsi),%rsi +.byte 15,56,204,220 +.byte 15,56,203,202 + + movdqa 64-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 102,15,56,0,247 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + + movdqa 96-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 128-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 160-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 192-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 224-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 256-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 288-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 + nop + paddd %xmm7,%xmm6 +.byte 15,56,204,220 +.byte 15,56,203,202 + movdqa 320-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,205,245 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm6,%xmm7 +.byte 102,15,58,15,253,4 + nop + paddd %xmm7,%xmm3 +.byte 15,56,204,229 +.byte 15,56,203,202 + movdqa 352-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 +.byte 15,56,205,222 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm3,%xmm7 +.byte 102,15,58,15,254,4 + nop + paddd %xmm7,%xmm4 +.byte 15,56,204,238 +.byte 15,56,203,202 + movdqa 384-128(%rcx),%xmm0 + paddd %xmm3,%xmm0 +.byte 15,56,205,227 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm4,%xmm7 +.byte 102,15,58,15,251,4 + nop + paddd %xmm7,%xmm5 +.byte 15,56,204,243 +.byte 15,56,203,202 + movdqa 416-128(%rcx),%xmm0 + paddd %xmm4,%xmm0 +.byte 15,56,205,236 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + movdqa %xmm5,%xmm7 +.byte 102,15,58,15,252,4 +.byte 15,56,203,202 + paddd %xmm7,%xmm6 + + movdqa 448-128(%rcx),%xmm0 + paddd %xmm5,%xmm0 +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 +.byte 15,56,205,245 + movdqa %xmm8,%xmm7 +.byte 15,56,203,202 + + movdqa 480-128(%rcx),%xmm0 + paddd %xmm6,%xmm0 + nop +.byte 15,56,203,209 + pshufd $0x0e,%xmm0,%xmm0 + decq %rdx + nop +.byte 15,56,203,202 + + paddd %xmm10,%xmm2 + paddd %xmm9,%xmm1 + jnz .Loop_shaext + + pshufd $0xb1,%xmm2,%xmm2 + pshufd $0x1b,%xmm1,%xmm7 + pshufd $0xb1,%xmm1,%xmm1 + punpckhqdq %xmm2,%xmm1 +.byte 102,15,58,15,215,8 + + movdqu %xmm1,(%rdi) + movdqu %xmm2,16(%rdi) + .byte 0xf3,0xc3 +.cfi_endproc +.size sha256_block_data_order_shaext,.-sha256_block_data_order_shaext .type sha256_block_data_order_ssse3,@function .align 64 sha256_block_data_order_ssse3: @@ -3970,4 +4183,7 @@ sha256_block_data_order_avx: .cfi_endproc .size sha256_block_data_order_avx,.-sha256_block_data_order_avx #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64-linux.S index 45a58a1d..d9fd3a40 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/sha512-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1736,6 +1736,7 @@ sha512_block_data_order: .byte 0xf3,0xc3 .cfi_endproc .size sha512_block_data_order,.-sha512_block_data_order +.section .rodata .align 64 .type K512,@object K512: @@ -1823,6 +1824,7 @@ K512: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text .type sha512_block_data_order_avx,@function .align 64 sha512_block_data_order_avx: @@ -2989,4 +2991,7 @@ sha512_block_data_order_avx: .cfi_endproc .size sha512_block_data_order_avx,.-sha512_block_data_order_avx #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64-linux.S similarity index 98% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64-linux.S index b651713f..f00ef0ed 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/vpaes-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1020,6 +1020,7 @@ _vpaes_preheat: .type _vpaes_consts,@object +.section .rodata .align 64 _vpaes_consts: .Lk_inv: @@ -1129,5 +1130,9 @@ _vpaes_consts: .byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0 .align 64 .size _vpaes_consts,.-_vpaes_consts +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont-linux.S similarity index 99% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont-linux.S index e39b5ca7..6dfb8853 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1257,4 +1257,7 @@ bn_mulx4x_mont: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 16 #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5-linux.S similarity index 94% rename from third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S rename to third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5-linux.S index 55cc7817..7e42e808 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/fipsmodule/x86_64-mont5-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -207,6 +207,7 @@ bn_mul_mont_gather5: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -330,6 +331,7 @@ bn_mul_mont_gather5: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -698,6 +700,7 @@ mul4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 por %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%r12),%r12 @@ -905,6 +908,7 @@ mul4x_internal: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%r12),%r12 @@ -2067,187 +2071,6 @@ __bn_post4x_internal: .byte 0xf3,0xc3 .cfi_endproc .size __bn_post4x_internal,.-__bn_post4x_internal -.globl bn_from_montgomery -.hidden bn_from_montgomery -.type bn_from_montgomery,@function -.align 32 -bn_from_montgomery: -.cfi_startproc - testl $7,%r9d - jz bn_from_mont8x - xorl %eax,%eax - .byte 0xf3,0xc3 -.cfi_endproc -.size bn_from_montgomery,.-bn_from_montgomery - -.type bn_from_mont8x,@function -.align 32 -bn_from_mont8x: -.cfi_startproc -.byte 0x67 - movq %rsp,%rax -.cfi_def_cfa_register %rax - pushq %rbx -.cfi_offset %rbx,-16 - pushq %rbp -.cfi_offset %rbp,-24 - pushq %r12 -.cfi_offset %r12,-32 - pushq %r13 -.cfi_offset %r13,-40 - pushq %r14 -.cfi_offset %r14,-48 - pushq %r15 -.cfi_offset %r15,-56 -.Lfrom_prologue: - - shll $3,%r9d - leaq (%r9,%r9,2),%r10 - negq %r9 - movq (%r8),%r8 - - - - - - - - - leaq -320(%rsp,%r9,2),%r11 - movq %rsp,%rbp - subq %rdi,%r11 - andq $4095,%r11 - cmpq %r11,%r10 - jb .Lfrom_sp_alt - subq %r11,%rbp - leaq -320(%rbp,%r9,2),%rbp - jmp .Lfrom_sp_done - -.align 32 -.Lfrom_sp_alt: - leaq 4096-320(,%r9,2),%r10 - leaq -320(%rbp,%r9,2),%rbp - subq %r10,%r11 - movq $0,%r10 - cmovcq %r10,%r11 - subq %r11,%rbp -.Lfrom_sp_done: - andq $-64,%rbp - movq %rsp,%r11 - subq %rbp,%r11 - andq $-4096,%r11 - leaq (%r11,%rbp,1),%rsp - movq (%rsp),%r10 - cmpq %rbp,%rsp - ja .Lfrom_page_walk - jmp .Lfrom_page_walk_done - -.Lfrom_page_walk: - leaq -4096(%rsp),%rsp - movq (%rsp),%r10 - cmpq %rbp,%rsp - ja .Lfrom_page_walk -.Lfrom_page_walk_done: - - movq %r9,%r10 - negq %r9 - - - - - - - - - - - movq %r8,32(%rsp) - movq %rax,40(%rsp) -.cfi_escape 0x0f,0x05,0x77,0x28,0x06,0x23,0x08 -.Lfrom_body: - movq %r9,%r11 - leaq 48(%rsp),%rax - pxor %xmm0,%xmm0 - jmp .Lmul_by_1 - -.align 32 -.Lmul_by_1: - movdqu (%rsi),%xmm1 - movdqu 16(%rsi),%xmm2 - movdqu 32(%rsi),%xmm3 - movdqa %xmm0,(%rax,%r9,1) - movdqu 48(%rsi),%xmm4 - movdqa %xmm0,16(%rax,%r9,1) -.byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 - movdqa %xmm1,(%rax) - movdqa %xmm0,32(%rax,%r9,1) - movdqa %xmm2,16(%rax) - movdqa %xmm0,48(%rax,%r9,1) - movdqa %xmm3,32(%rax) - movdqa %xmm4,48(%rax) - leaq 64(%rax),%rax - subq $64,%r11 - jnz .Lmul_by_1 - -.byte 102,72,15,110,207 -.byte 102,72,15,110,209 -.byte 0x67 - movq %rcx,%rbp -.byte 102,73,15,110,218 - leaq OPENSSL_ia32cap_P(%rip),%r11 - movl 8(%r11),%r11d - andl $0x80108,%r11d - cmpl $0x80108,%r11d - jne .Lfrom_mont_nox - - leaq (%rax,%r9,1),%rdi - call __bn_sqrx8x_reduction - call __bn_postx4x_internal - - pxor %xmm0,%xmm0 - leaq 48(%rsp),%rax - jmp .Lfrom_mont_zero - -.align 32 -.Lfrom_mont_nox: - call __bn_sqr8x_reduction - call __bn_post4x_internal - - pxor %xmm0,%xmm0 - leaq 48(%rsp),%rax - jmp .Lfrom_mont_zero - -.align 32 -.Lfrom_mont_zero: - movq 40(%rsp),%rsi -.cfi_def_cfa %rsi,8 - movdqa %xmm0,0(%rax) - movdqa %xmm0,16(%rax) - movdqa %xmm0,32(%rax) - movdqa %xmm0,48(%rax) - leaq 64(%rax),%rax - subq $32,%r9 - jnz .Lfrom_mont_zero - - movq $1,%rax - movq -48(%rsi),%r15 -.cfi_restore %r15 - movq -40(%rsi),%r14 -.cfi_restore %r14 - movq -32(%rsi),%r13 -.cfi_restore %r13 - movq -24(%rsi),%r12 -.cfi_restore %r12 - movq -16(%rsi),%rbp -.cfi_restore %rbp - movq -8(%rsi),%rbx -.cfi_restore %rbx - leaq (%rsi),%rsp -.cfi_def_cfa_register %rsp -.Lfrom_epilogue: - .byte 0xf3,0xc3 -.cfi_endproc -.size bn_from_mont8x,.-bn_from_mont8x .type bn_mulx4x_mont_gather5,@function .align 32 bn_mulx4x_mont_gather5: @@ -2502,6 +2325,7 @@ mulx4x_internal: por %xmm2,%xmm0 por %xmm3,%xmm1 pxor %xmm1,%xmm0 + pshufd $0x4e,%xmm0,%xmm1 por %xmm1,%xmm0 leaq 256(%rdi),%rdi @@ -2652,6 +2476,7 @@ mulx4x_internal: por %xmm2,%xmm4 por %xmm3,%xmm5 por %xmm5,%xmm4 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 leaq 256(%rdi),%rdi @@ -3600,6 +3425,15 @@ bn_scatter5: .cfi_startproc cmpl $0,%esi jz .Lscatter_epilogue + + + + + + + + + leaq (%rdx,%rcx,8),%rdx .Lscatter: movq (%rdi),%rax @@ -3768,6 +3602,7 @@ bn_gather5: por %xmm3,%xmm5 por %xmm5,%xmm4 leaq 256(%r11),%r11 + pshufd $0x4e,%xmm4,%xmm0 por %xmm4,%xmm0 movq %xmm0,(%rdi) @@ -3781,10 +3616,15 @@ bn_gather5: .LSEH_end_bn_gather5: .cfi_endproc .size bn_gather5,.-bn_gather5 +.section .rodata .align 64 .Linc: .long 0,0, 1,1 .long 2,2, 2,2 .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.text +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -.section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64.S b/third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64-linux.S similarity index 93% rename from third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64.S rename to third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64-linux.S index b7d6101b..aa269804 100644 --- a/third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64.S +++ b/third_party/boringssl/kit/linux-x86_64/crypto/test/trampoline-x86_64-linux.S @@ -7,7 +7,7 @@ #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include #endif @@ -25,7 +25,6 @@ .hidden abi_test_trampoline .align 16 abi_test_trampoline: -.Labi_test_trampoline_seh_begin: .cfi_startproc @@ -36,29 +35,29 @@ abi_test_trampoline: + subq $120,%rsp .cfi_adjust_cfa_offset 120 -.Labi_test_trampoline_seh_prolog_alloc: + movq %r8,48(%rsp) movq %rbx,64(%rsp) .cfi_offset rbx, -64 -.Labi_test_trampoline_seh_prolog_rbx: + movq %rbp,72(%rsp) .cfi_offset rbp, -56 -.Labi_test_trampoline_seh_prolog_rbp: + movq %r12,80(%rsp) .cfi_offset r12, -48 -.Labi_test_trampoline_seh_prolog_r12: + movq %r13,88(%rsp) .cfi_offset r13, -40 -.Labi_test_trampoline_seh_prolog_r13: + movq %r14,96(%rsp) .cfi_offset r14, -32 -.Labi_test_trampoline_seh_prolog_r14: + movq %r15,104(%rsp) .cfi_offset r15, -24 -.Labi_test_trampoline_seh_prolog_r15: -.Labi_test_trampoline_seh_prolog_end: + movq 0(%rsi),%rbx movq 8(%rsi),%rbp movq 16(%rsi),%r12 @@ -182,7 +181,7 @@ abi_test_unwind_stop: .byte 0xf3,0xc3 .cfi_endproc -.Labi_test_trampoline_seh_end: + .size abi_test_trampoline,.-abi_test_trampoline .type abi_test_clobber_rax, @function .globl abi_test_clobber_rax @@ -441,11 +440,11 @@ abi_test_clobber_xmm15: .align 16 abi_test_bad_unwind_wrong_register: .cfi_startproc -.Labi_test_bad_unwind_wrong_register_seh_begin: + pushq %r12 .cfi_adjust_cfa_offset 8 .cfi_offset %r13,-16 -.Labi_test_bad_unwind_wrong_register_seh_push_r13: + @@ -454,7 +453,7 @@ abi_test_bad_unwind_wrong_register: .cfi_adjust_cfa_offset -8 .cfi_restore %r12 .byte 0xf3,0xc3 -.Labi_test_bad_unwind_wrong_register_seh_end: + .cfi_endproc .size abi_test_bad_unwind_wrong_register,.-abi_test_bad_unwind_wrong_register @@ -467,11 +466,11 @@ abi_test_bad_unwind_wrong_register: .align 16 abi_test_bad_unwind_temporary: .cfi_startproc -.Labi_test_bad_unwind_temporary_seh_begin: + pushq %r12 .cfi_adjust_cfa_offset 8 .cfi_offset %r12,-16 -.Labi_test_bad_unwind_temporary_seh_push_r12: + movq %r12,%rax incq %rax @@ -486,8 +485,8 @@ abi_test_bad_unwind_temporary: .cfi_adjust_cfa_offset -8 .cfi_restore %r12 .byte 0xf3,0xc3 -.Labi_test_bad_unwind_temporary_seh_end: .cfi_endproc + .size abi_test_bad_unwind_temporary,.-abi_test_bad_unwind_temporary @@ -515,4 +514,7 @@ abi_test_set_direction_flag: .byte 0xf3,0xc3 .size abi_test_set_direction_flag,.-abi_test_set_direction_flag #endif -.section .note.GNU-stack,"",@progbits +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/src/.gitignore b/third_party/boringssl/kit/src/.gitignore index 08d99a1d..3e22141d 100644 --- a/third_party/boringssl/kit/src/.gitignore +++ b/third_party/boringssl/kit/src/.gitignore @@ -7,23 +7,24 @@ ssl/test/runner/runner *.swo doc/*.html doc/doc.css +rust/Cargo.lock +rust/bssl-crypto/Cargo.lock +rust/target util/bot/android_ndk util/bot/android_sdk/public -util/bot/cmake-linux64 -util/bot/cmake-mac -util/bot/cmake-win32 -util/bot/cmake-win32.zip +util/bot/cmake util/bot/golang util/bot/libFuzzer util/bot/libcxx util/bot/libcxxabi util/bot/llvm-build util/bot/nasm-win32.exe +util/bot/ninja util/bot/perl-win32 -util/bot/perl-win32.zip util/bot/sde-linux64 -util/bot/sde-linux64.tar.bz2 +util/bot/sde-linux64.tar.xz util/bot/sde-win32 -util/bot/sde-win32.tar.bz2 +util/bot/sde-win32.tar.xz util/bot/win_toolchain.json +target/ diff --git a/third_party/boringssl/kit/src/BUILDING.md b/third_party/boringssl/kit/src/BUILDING.md index 08f004c8..f915d856 100644 --- a/third_party/boringssl/kit/src/BUILDING.md +++ b/third_party/boringssl/kit/src/BUILDING.md @@ -10,7 +10,7 @@ Unless otherwise noted, build tools must at most five years old, matching [Abseil guidelines](https://abseil.io/about/compatibility). If in doubt, use the most recent stable version of each tool. - * [CMake](https://cmake.org/download/) 3.5 or later is required. + * [CMake](https://cmake.org/download/) 3.10 or later is required. * A recent version of Perl is required. On Windows, [Active State Perl](http://www.activestate.com/activeperl/) has been @@ -30,12 +30,11 @@ most recent stable version of each tool. by CMake, it may be configured explicitly by setting `CMAKE_ASM_NASM_COMPILER`. - * C and C++ compilers with C++11 support are required. On Windows, MSVC 14 - (Visual Studio 2015) or later with Platform SDK 8.1 or later are supported, - but newer versions are recommended. We will drop support for Visual Studio - 2015 in March 2022, five years after the release of Visual Studio 2017. - Recent versions of GCC (6.1+) and Clang should work on non-Windows - platforms, and maybe on Windows too. + * C and C++ compilers with C++14 support are required. If using a C compiler + other than MSVC, C11 support is also requried. On Windows, MSVC from + Visual Studio 2019 or later with Windows 10 SDK 2104 or later are supported, + but using the latest versions is recommended. Recent versions of GCC (6.1+) + and Clang should work on non-Windows platforms, and maybe on Windows too. * The most recent stable version of [Go](https://golang.org/dl/) is required. Note Go is exempt from the five year support window. If not found by CMake, @@ -49,17 +48,13 @@ most recent stable version of each tool. Using Ninja (note the 'N' is capitalized in the cmake invocation): - mkdir build - cd build - cmake -GNinja .. - ninja + cmake -GNinja -B build + ninja -C build Using Make (does not work on Windows): - mkdir build - cd build - cmake .. - make + cmake -B build + make -C build You usually don't need to run `cmake` again after changing `CMakeLists.txt` files because the build scripts will detect changes to them and rebuild @@ -70,10 +65,9 @@ debugging—optimisation isn't enabled. Pass `-DCMAKE_BUILD_TYPE=Release` to `cmake` to configure a release build. If you want to cross-compile then there is an example toolchain file for 32-bit -Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like -this: +Intel in `util/`. Wipe out the build directory, run `cmake` like this: - cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja .. + cmake -B build -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja If you want to build as a shared library, pass `-DBUILD_SHARED_LIBS=1`. On Windows, where functions need to be tagged with `dllimport` when coming from a @@ -94,12 +88,12 @@ versions of the NDK include a CMake toolchain file which works with CMake 3.6.0 or later. This has been tested with version r16b of the NDK. Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the -directory. Then make a build directory as above and run CMake like this: +directory. Then run CMake like this: cmake -DANDROID_ABI=armeabi-v7a \ + -DANDROID_PLATFORM=android-19 \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ - -DANDROID_NATIVE_API_LEVEL=16 \ - -GNinja .. + -GNinja -B build Once you've run that, Ninja should produce Android-compatible binaries. You can replace `armeabi-v7a` in the above with `arm64-v8a` and use API level 21 or @@ -141,7 +135,7 @@ In order to build with prefixed symbols, the `BORINGSSL_PREFIX` CMake variable should specify the prefix to add to all symbols, and the `BORINGSSL_PREFIX_SYMBOLS` CMake variable should specify the path to a file which contains a list of symbols which should be prefixed (one per line; -comments are supported with `#`). In other words, `cmake .. +comments are supported with `#`). In other words, `cmake -B build -DBORINGSSL_PREFIX=MY_CUSTOM_PREFIX -DBORINGSSL_PREFIX_SYMBOLS=/path/to/symbols.txt` will configure the build to add the prefix `MY_CUSTOM_PREFIX` to all of the symbols listed in @@ -163,22 +157,19 @@ BoringSSL maintainers if making use of it. don't have steps for assembling the assembly language source files, so they currently cannot be used to build BoringSSL. -## Embedded ARM +## ARM CPU Capabilities -ARM, unlike Intel, does not have an instruction that allows applications to -discover the capabilities of the processor. Instead, the capability information -has to be provided by the operating system somehow. +ARM, unlike Intel, does not have a userspace instruction that allows +applications to discover the capabilities of the processor. Instead, the +capability information has to be provided by a combination of compile-time +information and the operating system. -By default, on Linux-based systems, BoringSSL will try to use `getauxval` and -`/proc` to discover the capabilities. But some environments don't support that -sort of thing and, for them, it's possible to configure the CPU capabilities at -compile time. - -On iOS or builds which define `OPENSSL_STATIC_ARMCAP`, features will be -determined based on the `__ARM_NEON__` and `__ARM_FEATURE_CRYPTO` preprocessor -symbols reported by the compiler. These values are usually controlled by the -`-march` flag. You can also define any of the following to enable the -corresponding ARM feature. +BoringSSL determines capabilities at compile-time based on `__ARM_NEON`, +`__ARM_FEATURE_AES`, and other preprocessor symbols defined in +[Arm C Language Extensions (ACLE)](https://developer.arm.com/architectures/system-architectures/software-standards/acle). +These values are usually controlled by the `-march` flag. You can also define +any of the following to enable the corresponding ARM feature, but using the ACLE +symbols via `-march` is recommended. * `OPENSSL_STATIC_ARMCAP_NEON` * `OPENSSL_STATIC_ARMCAP_AES` @@ -186,8 +177,16 @@ corresponding ARM feature. * `OPENSSL_STATIC_ARMCAP_SHA256` * `OPENSSL_STATIC_ARMCAP_PMULL` -Note that if a feature is enabled in this way, but not actually supported at -run-time, BoringSSL will likely crash. +The resulting binary will assume all such features are always present. This can +reduce code size, by allowing the compiler to omit fallbacks. However, if the +feature is not actually supported at runtime, BoringSSL will likely crash. + +BoringSSL will additionally query the operating system at runtime for additional +features, e.g. with `getauxval` on Linux. This allows a single binary to use +newer instructions when present, but still function on CPUs without them. But +some environments don't support runtime queries. If building for those, define +`OPENSSL_STATIC_ARMCAP` to limit BoringSSL to compile-time capabilities. If not +defined, the target operating system must be known to BoringSSL. ## Binary Size diff --git a/third_party/boringssl/kit/src/CMakeLists.txt b/third_party/boringssl/kit/src/CMakeLists.txt index ce74106d..c939e424 100644 --- a/third_party/boringssl/kit/src/CMakeLists.txt +++ b/third_party/boringssl/kit/src/CMakeLists.txt @@ -1,8 +1,14 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.10) # Defer enabling C and CXX languages. project(BoringSSL NONE) +# Don't install BoringSSL to system directories by default; it has no stable +# ABI. Instead, default to an "install" directory under the source. +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install CACHE PATH "" FORCE) +endif() + if(WIN32) # On Windows, prefer cl over gcc if both are available. By default most of # the CMake generators prefer gcc, even on Windows. @@ -10,27 +16,41 @@ if(WIN32) endif() include(sources.cmake) +include(cmake/go.cmake) +include(cmake/paths.cmake) +include(cmake/perlasm.cmake) enable_language(C) enable_language(CXX) -# This is a dummy target which all other targets depend on (manually - see other -# CMakeLists.txt files). This gives us a hook to add any targets which need to -# run before all other targets. -add_custom_target(global_target) +include(GNUInstallDirs) + +# CMake versions before 3.14 do not have default destination values. Executable +# and library targets that use a default destination should include this +# variable. +if(CMAKE_VERSION VERSION_LESS "3.14") + set(INSTALL_DESTINATION_DEFAULT + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() + +# Wrap the CMake install function so we can disable it. +set(INSTALL_ENABLED 1) +function(install_if_enabled) + if(INSTALL_ENABLED) + install(${ARGV}) + endif() +endfunction() if(ANDROID) - # Android-NDK CMake files reconfigure the path and so Go and Perl won't be - # found. However, ninja will still find them in $PATH if we just name them. + # Android-NDK CMake files reconfigure the path and so Perl won't be found. + # However, ninja will still find them in $PATH if we just name them. if(NOT PERL_EXECUTABLE) set(PERL_EXECUTABLE "perl") endif() - if(NOT GO_EXECUTABLE) - set(GO_EXECUTABLE "go") - endif() else() find_package(Perl REQUIRED) - find_program(GO_EXECUTABLE go) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_CROSSCOMPILING) @@ -47,10 +67,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_CROSSCOMPILING) endif() endif() -if(NOT GO_EXECUTABLE) - message(FATAL_ERROR "Could not find Go") -endif() - if(USE_CUSTOM_LIBCXX) set(BORINGSSL_ALLOW_CXX_RUNTIME 1) endif() @@ -92,7 +108,7 @@ if(BORINGSSL_PREFIX AND BORINGSSL_PREFIX_SYMBOLS) COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/symbol_prefix_include COMMAND ${GO_EXECUTABLE} run ${CMAKE_CURRENT_SOURCE_DIR}/util/make_prefix_headers.go -out ${CMAKE_CURRENT_BINARY_DIR}/symbol_prefix_include ${BORINGSSL_PREFIX_SYMBOLS} DEPENDS util/make_prefix_headers.go - ${CMAKE_BINARY_DIR}/${BORINGSSL_PREFIX_SYMBOLS}) + ${BORINGSSL_PREFIX_SYMBOLS}) # add_dependencies needs a target, not a file, so we add an intermediate # target. @@ -101,9 +117,10 @@ if(BORINGSSL_PREFIX AND BORINGSSL_PREFIX_SYMBOLS) DEPENDS symbol_prefix_include/boringssl_prefix_symbols.h symbol_prefix_include/boringssl_prefix_symbols_asm.h symbol_prefix_include/boringssl_prefix_symbols_nasm.inc) - add_dependencies(global_target boringssl_prefix_symbols) elseif(BORINGSSL_PREFIX OR BORINGSSL_PREFIX_SYMBOLS) message(FATAL_ERROR "Must specify both or neither of BORINGSSL_PREFIX and BORINGSSL_PREFIX_SYMBOLS") +else() + add_custom_target(boringssl_prefix_symbols) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -114,18 +131,20 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") set(EMSCRIPTEN 1) endif() +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) # Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration # primarily on our normal Clang one. - set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -Wvla -Wshadow") + set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings -Wvla -Wshadow -Wtype-limits") if(MSVC) # clang-cl sets different default warnings than clang. It also treats -Wall # as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall. # See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116 set(C_CXX_FLAGS "${C_CXX_FLAGS} -W3 -Wno-unused-parameter -fmsc-version=1900") - # googletest suppresses warning C4996 via a pragma, but clang-cl does not - # honor it. Suppress it here to compensate. See https://crbug.com/772117. - set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-deprecated-declarations") else() if(EMSCRIPTEN) # emscripten's emcc/clang does not accept the "-ggdb" flag. @@ -145,21 +164,29 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-free-nonheap-object") endif() - if(CLANG OR NOT "7.0.0" VERSION_GREATER CMAKE_C_COMPILER_VERSION) + # -Wstring-concatenation was added in Clang 12.0.0, which corresponds to + # AppleClang 13.0.0 per the table in + # https://en.wikipedia.org/wiki/Xcode#Toolchain_versions + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0") OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0")) + set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wstring-concatenation") + endif() + + if(CLANG OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0") set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wimplicit-fallthrough") endif() + if(CMAKE_COMPILER_IS_GNUCXX) + set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wformat-signedness") + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} -Wmissing-declarations") - if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - endif() - if(NOT BORINGSSL_ALLOW_CXX_RUNTIME) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti") - endif() + if(NOT MSVC AND NOT BORINGSSL_ALLOW_CXX_RUNTIME) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti") endif() # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes @@ -174,67 +201,17 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) endif() elseif(MSVC) set(MSVC_DISABLED_WARNINGS_LIST - "C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not - # explicitly handled by a case label - # Disable this because it flags even when there is a default. "C4100" # 'exarg' : unreferenced formal parameter "C4127" # conditional expression is constant - "C4200" # nonstandard extension used : zero-sized array in - # struct/union. - "C4204" # nonstandard extension used: non-constant aggregate initializer - "C4221" # nonstandard extension used : 'identifier' : cannot be - # initialized using address of automatic variable - "C4242" # 'function' : conversion from 'int' to 'uint8_t', - # possible loss of data "C4244" # 'function' : conversion from 'int' to 'uint8_t', # possible loss of data "C4267" # conversion from 'size_t' to 'int', possible loss of data - "C4371" # layout of class may have changed from a previous version of the - # compiler due to better packing of member '...' - "C4388" # signed/unsigned mismatch - "C4296" # '>=' : expression is always true - "C4350" # behavior change: 'std::_Wrap_alloc...' - "C4365" # '=' : conversion from 'size_t' to 'int', - # signed/unsigned mismatch - "C4389" # '!=' : signed/unsigned mismatch - "C4464" # relative include path contains '..' - "C4510" # 'argument' : default constructor could not be generated - "C4512" # 'argument' : assignment operator could not be generated - "C4514" # 'function': unreferenced inline function has been removed - "C4548" # expression before comma has no effect; expected expression with - # side-effect" caused by FD_* macros. - "C4610" # struct 'argument' can never be instantiated - user defined - # constructor required. - "C4623" # default constructor was implicitly defined as deleted - "C4625" # copy constructor could not be generated because a base class - # copy constructor is inaccessible or deleted - "C4626" # assignment operator could not be generated because a base class - # assignment operator is inaccessible or deleted - "C4628" # digraphs not supported with -Ze - "C4668" # 'symbol' is not defined as a preprocessor macro, replacing with - # '0' for 'directives' - # Disable this because GTest uses it everywhere. "C4706" # assignment within conditional expression - "C4710" # 'function': function not inlined - "C4711" # function 'function' selected for inline expansion - "C4800" # 'int' : forcing value to bool 'true' or 'false' - # (performance warning) - "C4820" # 'bytes' bytes padding added after construct 'member_name' - "C5026" # move constructor was implicitly defined as deleted - "C5027" # move assignment operator was implicitly defined as deleted - "C5045" # Compiler will insert Spectre mitigation for memory load if - # /Qspectre switch specified - ) - set(MSVC_LEVEL4_WARNINGS_LIST - # See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header - "C4265" # class has virtual functions, but destructor is not virtual ) string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR ${MSVC_DISABLED_WARNINGS_LIST}) - string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR - ${MSVC_LEVEL4_WARNINGS_LIST}) - set(CMAKE_C_FLAGS "-utf-8 -Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}") - set(CMAKE_CXX_FLAGS "-utf-8 -Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}") + set(CMAKE_C_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") + set(CMAKE_CXX_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") endif() if(WIN32) @@ -243,18 +220,13 @@ if(WIN32) add_definitions(-DNOMINMAX) # Allow use of fopen. add_definitions(-D_CRT_SECURE_NO_WARNINGS) - # VS 2017 and higher supports STL-only warning suppressions. - # A bug in CMake < 3.13.0 may cause the space in this value to - # cause issues when building with NASM. In that case, update CMake. - add_definitions("-D_STL_EXTRA_DISABLED_WARNINGS=4774 4987") endif() -if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") -endif() - -# pthread_rwlock_t requires a feature flag. -if(NOT WIN32) +# pthread_rwlock_t on Linux requires a feature flag. We limit this to Linux +# because, on Apple platforms, it instead disables APIs we use. See compat(5) +# and sys/cdefs.h. Reportedly, FreeBSD also breaks when this is set. See +# https://crbug.com/boringssl/471. +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700") endif() @@ -392,112 +364,58 @@ if(CONSTANT_TIME_VALIDATION) add_definitions(-DNDEBUG) endif() -function(go_executable dest package) - set(godeps "${CMAKE_SOURCE_DIR}/util/godeps.go") - if(CMAKE_VERSION VERSION_LESS "3.7" OR NOT CMAKE_GENERATOR STREQUAL "Ninja") - # The DEPFILE parameter to add_custom_command is new as of CMake 3.7 and - # only works with Ninja. Query the sources at configure time. Additionally, - # everything depends on go.mod. That affects what external packages to use. - execute_process(COMMAND ${GO_EXECUTABLE} run ${godeps} -format cmake - -pkg ${package} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE sources - RESULT_VARIABLE godeps_result) - add_custom_command(OUTPUT ${dest} - COMMAND ${GO_EXECUTABLE} build - -o ${CMAKE_CURRENT_BINARY_DIR}/${dest} ${package} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${sources} ${CMAKE_SOURCE_DIR}/go.mod) +if(MALLOC_FAILURE_TESTING) + add_definitions(-DBORINGSSL_MALLOC_FAILURE_TESTING) +endif() + +if(OPENSSL_NO_ASM) + add_definitions(-DOPENSSL_NO_ASM) +endif() + +if(FIPS_DELOCATE OR NOT OPENSSL_NO_ASM) + # On x86 and x86_64 Windows, we use the NASM output. + if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64|amd64|x86|i[3-6]86") + enable_language(ASM_NASM) + set(OPENSSL_NASM TRUE) + set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") else() - # Ninja expects the target in the depfile to match the output. This is a - # relative path from the build directory. - string(LENGTH "${CMAKE_BINARY_DIR}" root_dir_length) - math(EXPR root_dir_length "${root_dir_length} + 1") - string(SUBSTRING "${CMAKE_CURRENT_BINARY_DIR}" ${root_dir_length} -1 target) - set(target "${target}/${dest}") - - set(depfile "${CMAKE_CURRENT_BINARY_DIR}/${dest}.d") - add_custom_command(OUTPUT ${dest} - COMMAND ${GO_EXECUTABLE} build - -o ${CMAKE_CURRENT_BINARY_DIR}/${dest} ${package} - COMMAND ${GO_EXECUTABLE} run ${godeps} -format depfile - -target ${target} -pkg ${package} -out ${depfile} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${godeps} ${CMAKE_SOURCE_DIR}/go.mod - DEPFILE ${depfile}) + enable_language(ASM) + set(OPENSSL_ASM TRUE) + # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/20771 in older + # CMake versions. + if(APPLE AND CMAKE_VERSION VERSION_LESS 3.19) + if(CMAKE_OSX_SYSROOT) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"") + endif() + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}") + endforeach() + endif() + if(NOT WIN32) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack") + endif() + # Clang's integerated assembler does not support debug symbols. + if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang") + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g") + endif() endif() -endfunction() - -# CMake's iOS support uses Apple's multiple-architecture toolchain. It takes an -# architecture list from CMAKE_OSX_ARCHITECTURES, leaves CMAKE_SYSTEM_PROCESSOR -# alone, and expects all architecture-specific logic to be conditioned within -# the source files rather than the build. This does not work for our assembly -# files, so we fix CMAKE_SYSTEM_PROCESSOR and only support single-architecture -# builds. -if(NOT OPENSSL_NO_ASM AND CMAKE_OSX_ARCHITECTURES) - list(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHES) - if(NOT NUM_ARCHES EQUAL 1) - message(FATAL_ERROR "Universal binaries not supported.") - endif() - list(GET CMAKE_OSX_ARCHITECTURES 0 CMAKE_SYSTEM_PROCESSOR) endif() if(OPENSSL_NO_SSE2_FOR_TESTING) add_definitions(-DOPENSSL_NO_SSE2_FOR_TESTING) endif() -if(OPENSSL_NO_ASM) - add_definitions(-DOPENSSL_NO_ASM) - set(ARCH "generic") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(ARCH "x86_64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") - set(ARCH "x86_64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") - # cmake reports AMD64 on Windows, but we might be building for 32-bit. - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH "x86_64") - else() - set(ARCH "x86") - endif() -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") - set(ARCH "aarch64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") - set(ARCH "aarch64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") - set(ARCH "aarch64") -# Apple A12 Bionic chipset which is added in iPhone XS/XS Max/XR uses arm64e architecture. -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64e") - set(ARCH "aarch64") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm*") - set(ARCH "arm") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "mips") - # Just to avoid the “unknown processor” error. - set(ARCH "generic") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le") - set(ARCH "ppc64le") -else() - message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR}) -endif() - -if(ANDROID AND NOT ANDROID_NDK_REVISION AND ARCH STREQUAL "arm") - # The third-party Android-NDK CMake files somehow fail to set the -march flag - # for assembly files. Without this flag, the compiler believes that it's - # building for ARMv5. - set(CMAKE_ASM_FLAGS "-march=${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_ASM_FLAGS}") -endif() - if(USE_CUSTOM_LIBCXX) if(NOT CLANG) message(FATAL_ERROR "USE_CUSTOM_LIBCXX only supported with Clang") endif() + # CMake does not allow installing a library without installing dependencies. + # If we installed libcrypto, we'd have to install our custom libc++, which + # does not make sense. As this is a test-only configuration, disable + # installing. + set(INSTALL_ENABLED 0) + # CMAKE_CXX_FLAGS ends up in the linker flags as well, so use # add_compile_options. There does not appear to be a way to set # language-specific compile-only flags. @@ -531,9 +449,6 @@ if(USE_CUSTOM_LIBCXX) libcxxabi PRIVATE -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS ) - set_target_properties(libcxxabi PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-implicit-fallthrough") - # libc++abi depends on libc++ internal headers. - set_property(TARGET libcxxabi APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/util/bot/libcxx/src") add_library(libcxx ${LIBCXX_SOURCES}) if(ASAN OR MSAN OR TSAN) @@ -548,15 +463,29 @@ if(USE_CUSTOM_LIBCXX) -D_LIBCPP_BUILDING_LIBRARY -DLIBCXX_BUILDING_LIBCXXABI ) + set_target_properties( + libcxx libcxxabi PROPERTIES + COMPILE_FLAGS "-Wno-missing-prototypes -Wno-implicit-fallthrough" + # libc++ and libc++abi must be built in C++20 mode. + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED TRUE + ) + # libc++abi depends on libc++ internal headers. + set_property(TARGET libcxx libcxxabi APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/util/bot/libcxx/src") target_link_libraries(libcxx libcxxabi) endif() # Add minimal googletest targets. The provided one has many side-effects, and # googletest has a very straightforward build. add_library(boringssl_gtest third_party/googletest/src/gtest-all.cc) -target_include_directories(boringssl_gtest PRIVATE third_party/googletest) - -include_directories(third_party/googletest/include) +if(USE_CUSTOM_LIBCXX) + target_link_libraries(boringssl_gtest libcxx) +endif() +target_include_directories( + boringssl_gtest + PUBLIC third_party/googletest/include + PRIVATE third_party/googletest +) # Declare a dummy target to build all unit tests. Test targets should inject # themselves as dependencies next to the target definition. @@ -586,7 +515,7 @@ add_subdirectory(crypto) add_subdirectory(ssl) add_subdirectory(ssl/test) add_subdirectory(tool) -add_subdirectory(util/fipstools/cavp) +add_subdirectory(util/fipstools) add_subdirectory(util/fipstools/acvp/modulewrapper) add_subdirectory(decrepit) @@ -602,23 +531,32 @@ if(FUZZ) add_subdirectory(fuzz) endif() -if(UNIX AND NOT APPLE AND NOT ANDROID) +if(RUST_BINDINGS) + find_program(BINDGEN_EXECUTABLE bindgen) + if(NOT BINDGEN_EXECUTABLE) + message(FATAL_ERROR "Could not find bindgen but was asked to generate Rust bindings.") + else() + add_subdirectory(rust) + endif() +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(HANDSHAKER_ARGS "-handshaker-path" $) endif() if(FIPS) add_custom_target( acvp_tests - COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_BINARY_DIR}/acvptool + COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/acvptool boringssl.googlesource.com/boringssl/util/fipstools/acvp/acvptool - COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_BINARY_DIR}/testmodulewrapper + COMMAND ${GO_EXECUTABLE} build -o ${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper boringssl.googlesource.com/boringssl/util/fipstools/acvp/acvptool/testmodulewrapper COMMAND cd util/fipstools/acvp/acvptool/test && ${GO_EXECUTABLE} run check_expected.go - -tool ${CMAKE_BINARY_DIR}/acvptool - -module-wrappers modulewrapper:$,testmodulewrapper:${CMAKE_BINARY_DIR}/testmodulewrapper + -tool ${CMAKE_CURRENT_BINARY_DIR}/acvptool + -module-wrappers modulewrapper:$,testmodulewrapper:${CMAKE_CURRENT_BINARY_DIR}/testmodulewrapper -tests tests.json - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS modulewrapper USES_TERMINAL) @@ -630,13 +568,30 @@ else() add_custom_target(fips_specific_tests_if_any) endif() +# Read util/go_tests.txt into a CMake variable. +file(READ util/go_tests.txt GO_TESTS) +string(REPLACE "\n" ";" GO_TESTS "${GO_TESTS}") +list(REMOVE_ITEM GO_TESTS "") +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + util/go_tests.txt) + add_custom_target( run_tests + COMMAND ${GO_EXECUTABLE} test ${GO_TESTS} COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir - ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR} COMMAND cd ssl/test/runner && ${GO_EXECUTABLE} test -shim-path $ ${HANDSHAKER_ARGS} ${RUNNER_ARGS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS all_tests bssl_shim handshaker fips_specific_tests_if_any USES_TERMINAL) + +install_if_enabled(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +install_if_enabled(EXPORT OpenSSLTargets + FILE OpenSSLTargets.cmake + NAMESPACE OpenSSL:: + DESTINATION lib/cmake/OpenSSL +) +install_if_enabled(FILES cmake/OpenSSLConfig.cmake DESTINATION lib/cmake/OpenSSL) diff --git a/third_party/boringssl/kit/src/CONTRIBUTING.md b/third_party/boringssl/kit/src/CONTRIBUTING.md index 8907cc98..69dbc20d 100644 --- a/third_party/boringssl/kit/src/CONTRIBUTING.md +++ b/third_party/boringssl/kit/src/CONTRIBUTING.md @@ -22,7 +22,10 @@ use [Gerrit](https://boringssl-review.googlesource.com) for this purpose. If you have not done so on this machine, you will need to set up a password for Gerrit. Sign in with a Google account, visit [this link](https://boringssl.googlesource.com/), and click the "Generate -Password" link in the top right. You will also need to prepare your checkout to +Password" link in the top right. You must also have a Gerrit account associated with +your Google account. To do this visit the [Gerrit review server](https://boringssl-review.googlesource.com) +and click "Sign in" (top right). +You will also need to prepare your checkout to [add Change-Ids](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html) on commit. Run: @@ -34,8 +37,8 @@ To upload a change, push it to the special `refs/for/master` target: git push origin HEAD:refs/for/master -The output will then give you a link to the change. Add `agl@google.com` and -`davidben@google.com` as reviewers. +The output will then give you a link to the change. Add `agl@google.com`, +`davidben@google.com`, and `bbe@google.com` as reviewers. Pushing a commit with the same Change-Id as an existing change will upload a new version of it. (Use the `git rebase` or `git commit --amend` commands.) diff --git a/third_party/boringssl/kit/src/FUZZING.md b/third_party/boringssl/kit/src/FUZZING.md index 5653acc1..89cf5e93 100644 --- a/third_party/boringssl/kit/src/FUZZING.md +++ b/third_party/boringssl/kit/src/FUZZING.md @@ -7,10 +7,8 @@ We use Clang's [libFuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz testing In order to build the fuzz tests you will need at least Clang 6.0. Pass `-DFUZZ=1` on the CMake command line to enable building BoringSSL with coverage and AddressSanitizer, and to build the fuzz test binaries. You'll probably need to set the `CC` and `CXX` environment variables too, like this: ``` -mkdir build -cd build -CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 .. -ninja +CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 -B build +ninja -C build ``` diff --git a/third_party/boringssl/kit/src/INCORPORATING.md b/third_party/boringssl/kit/src/INCORPORATING.md index 96bf9088..f793e88a 100644 --- a/third_party/boringssl/kit/src/INCORPORATING.md +++ b/third_party/boringssl/kit/src/INCORPORATING.md @@ -3,6 +3,22 @@ **Note**: if your target project is not a Google project then first read the [main README](/README.md) about the purpose of BoringSSL. +## Which branch to use + +BoringSSL usage typically follows a +["live at head"](https://abseil.io/about/philosophy#we-recommend-that-you-choose-to-live-at-head) +model. Projects pin to whatever the current latest of BoringSSL is at the time +of update, and regularly update it to pick up new changes. + +While the BoringSSL repository may contain project-specific branches, e.g. +`chromium-2214`, those are _not_ supported release branches and must not as +such. In rare cases, BoringSSL will temporarily maintain a short-lived branch on +behalf of a project. Most such branches are no longer updated, because the +corresponding project no longer needs them, and we do not create new ones to +replace the ones that are no longer updated. E.g., not every Chromium release +branch has a corresponding BoringSSL `chromium-*` branch. Even while active, the +branch may not contain all changes relevant to a general BoringSSL consumer. + ## Bazel If you are using [Bazel](https://bazel.build) then you can incorporate diff --git a/third_party/boringssl/kit/src/LICENSE b/third_party/boringssl/kit/src/LICENSE index 49c41fa7..fc1cebba 100644 --- a/third_party/boringssl/kit/src/LICENSE +++ b/third_party/boringssl/kit/src/LICENSE @@ -21,6 +21,7 @@ record keeping.) 27287199 27287880 27287883 + 263291445 OpenSSL License --------------- diff --git a/third_party/boringssl/kit/src/PORTING.md b/third_party/boringssl/kit/src/PORTING.md index 9adaf738..eb951f57 100644 --- a/third_party/boringssl/kit/src/PORTING.md +++ b/third_party/boringssl/kit/src/PORTING.md @@ -170,14 +170,13 @@ OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form: In addition to returning the result, OpenSSL places it in `*out` if `out` is not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not always) reuse that object rather than allocating a new one. In BoringSSL, these -functions are compatibility wrappers over a newer ASN.1 stack. Even if `*out` -is not `NULL`, these wrappers will always allocate a new object and free the -previous one. +functions will always allocate a new object and free the previous one. Ensure that callers do not rely on this object reuse behavior. It is recommended to avoid the `out` parameter completely and always pass in `NULL`. -Note that less error-prone APIs are available for BoringSSL-specific code (see -below). +In most cases, even in OpenSSL, relying on object reuse is not safe because, on +parse error, OpenSSL will free the reused object. Note that less error-prone +APIs are available for BoringSSL-specific code (see below). ### Memory allocation diff --git a/third_party/boringssl/kit/src/README.md b/third_party/boringssl/kit/src/README.md index 2a99b60b..d3d5e29d 100644 --- a/third_party/boringssl/kit/src/README.md +++ b/third_party/boringssl/kit/src/README.md @@ -30,13 +30,13 @@ Project links: There are other files in this directory which might be helpful: - * [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL. - * [BUILDING.md](/BUILDING.md): how to build BoringSSL - * [INCORPORATING.md](/INCORPORATING.md): how to incorporate BoringSSL into a project. - * [API-CONVENTIONS.md](/API-CONVENTIONS.md): general API conventions for BoringSSL consumers and developers. - * [STYLE.md](/STYLE.md): rules and guidelines for coding style. + * [PORTING.md](./PORTING.md): how to port OpenSSL-using code to BoringSSL. + * [BUILDING.md](./BUILDING.md): how to build BoringSSL + * [INCORPORATING.md](./INCORPORATING.md): how to incorporate BoringSSL into a project. + * [API-CONVENTIONS.md](./API-CONVENTIONS.md): general API conventions for BoringSSL consumers and developers. + * [STYLE.md](./STYLE.md): rules and guidelines for coding style. * include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). - * [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL. - * [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL. - * [BREAKING-CHANGES.md](/BREAKING-CHANGES.md): notes on potentially-breaking changes. - * [SANDBOXING.md](/SANDBOXING.md): notes on using BoringSSL in a sandboxed environment. + * [FUZZING.md](./FUZZING.md): information about fuzzing BoringSSL. + * [CONTRIBUTING.md](./CONTRIBUTING.md): how to contribute to BoringSSL. + * [BREAKING-CHANGES.md](./BREAKING-CHANGES.md): notes on potentially-breaking changes. + * [SANDBOXING.md](./SANDBOXING.md): notes on using BoringSSL in a sandboxed environment. diff --git a/third_party/boringssl/kit/src/SANDBOXING.md b/third_party/boringssl/kit/src/SANDBOXING.md index b1a32df5..cb17720b 100644 --- a/third_party/boringssl/kit/src/SANDBOXING.md +++ b/third_party/boringssl/kit/src/SANDBOXING.md @@ -90,8 +90,10 @@ addition to the operations above. On Linux ARM platforms, BoringSSL depends on OS APIs to query CPU capabilities. 32-bit and 64-bit ARM both depend on the `getauxval` function. 32-bit ARM, to -work around bugs in older Android devices, may additionally read `/proc/cpuinfo` -and `/proc/self/auxv`. +work around bugs in older Android devices, may additionally read +`/proc/cpuinfo`. + +On 64-bit Apple ARM platforms, BoringSSL needs to query `hw.optional.*` sysctls. If querying CPU capabilities fails, BoringSSL will still function, but may not perform as well. diff --git a/third_party/boringssl/kit/src/cmake/OpenSSLConfig.cmake b/third_party/boringssl/kit/src/cmake/OpenSSLConfig.cmake new file mode 100644 index 00000000..3ebaf19b --- /dev/null +++ b/third_party/boringssl/kit/src/cmake/OpenSSLConfig.cmake @@ -0,0 +1,32 @@ +include(${CMAKE_CURRENT_LIST_DIR}/OpenSSLTargets.cmake) + +# Recursively collect dependency locations for the imported targets. +macro(_openssl_config_libraries libraries target) + get_property(_DEPS TARGET ${target} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(_DEP ${_DEPS}) + if(TARGET ${_DEP}) + _openssl_config_libraries(${libraries} ${_DEP}) + else() + list(APPEND ${libraries} ${_DEP}) + endif() + endforeach() + get_property(_LOC TARGET ${target} PROPERTY LOCATION) + list(APPEND ${libraries} ${_LOC}) +endmacro() + +set(OPENSSL_FOUND YES) +get_property(OPENSSL_INCLUDE_DIR TARGET OpenSSL::SSL PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(OPENSSL_CRYPTO_LIBRARY TARGET OpenSSL::Crypto PROPERTY LOCATION) +_openssl_config_libraries(OPENSSL_CRYPTO_LIBRARIES OpenSSL::Crypto) +list(REMOVE_DUPLICATES OPENSSL_CRYPTO_LIBRARIES) + +get_property(OPENSSL_SSL_LIBRARY TARGET OpenSSL::Crypto PROPERTY LOCATION) +_openssl_config_libraries(OPENSSL_SSL_LIBRARIES OpenSSL::SSL) +list(REMOVE_DUPLICATES OPENSSL_SSL_LIBRARIES) + +set(OPENSSL_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}) +list(REMOVE_DUPLICATES OPENSSL_LIBRARIES) + +set(_DEP) +set(_DEPS) +set(_LOC) diff --git a/third_party/boringssl/kit/src/cmake/go.cmake b/third_party/boringssl/kit/src/cmake/go.cmake new file mode 100644 index 00000000..966ad32d --- /dev/null +++ b/third_party/boringssl/kit/src/cmake/go.cmake @@ -0,0 +1,50 @@ +if(ANDROID) + # Android-NDK CMake files reconfigure the path and so Go won't be found. + # However, ninja will still find them in $PATH if we just name them. + if(NOT GO_EXECUTABLE) + set(GO_EXECUTABLE "go") + endif() +else() + find_program(GO_EXECUTABLE go) +endif() + +if(NOT GO_EXECUTABLE) + message(FATAL_ERROR "Could not find Go") +endif() + +function(go_executable dest package) + set(godeps "${PROJECT_SOURCE_DIR}/util/godeps.go") + if(NOT CMAKE_GENERATOR STREQUAL "Ninja") + # The DEPFILE parameter to add_custom_command only works with Ninja. Query + # the sources at configure time. Additionally, everything depends on go.mod. + # That affects what external packages to use. + # + # TODO(davidben): Starting CMake 3.20, it also works with Make. Starting + # 3.21, it works with Visual Studio and Xcode too. + execute_process(COMMAND ${GO_EXECUTABLE} run ${godeps} -format cmake + -pkg ${package} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE sources + RESULT_VARIABLE godeps_result) + add_custom_command(OUTPUT ${dest} + COMMAND ${GO_EXECUTABLE} build + -o ${CMAKE_CURRENT_BINARY_DIR}/${dest} ${package} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${sources} ${PROJECT_SOURCE_DIR}/go.mod) + else() + # Ninja expects the target in the depfile to match the output. This is a + # relative path from the build directory. + binary_dir_relative_path(${dest} target) + + set(depfile "${CMAKE_CURRENT_BINARY_DIR}/${dest}.d") + add_custom_command(OUTPUT ${dest} + COMMAND ${GO_EXECUTABLE} build + -o ${CMAKE_CURRENT_BINARY_DIR}/${dest} ${package} + COMMAND ${GO_EXECUTABLE} run ${godeps} -format depfile + -target ${target} -pkg ${package} -out ${depfile} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${godeps} ${PROJECT_SOURCE_DIR}/go.mod + DEPFILE ${depfile}) + endif() +endfunction() + diff --git a/third_party/boringssl/kit/src/cmake/paths.cmake b/third_party/boringssl/kit/src/cmake/paths.cmake new file mode 100644 index 00000000..43ebc406 --- /dev/null +++ b/third_party/boringssl/kit/src/cmake/paths.cmake @@ -0,0 +1,11 @@ +# binary_dir_relative_path sets outvar to +# ${CMAKE_CURRENT_BINARY_DIR}/${cur_bin_dir_relative}, but expressed relative to +# ${CMAKE_BINARY_DIR}. +# +# TODO(davidben): When we require CMake 3.20 or later, this can be replaced with +# the built-in cmake_path(RELATIVE_PATH) function. +function(binary_dir_relative_path cur_bin_dir_relative outvar) + string(LENGTH "${CMAKE_BINARY_DIR}/" root_dir_length) + string(SUBSTRING "${CMAKE_CURRENT_BINARY_DIR}/${cur_bin_dir_relative}" ${root_dir_length} -1 result) + set(${outvar} ${result} PARENT_SCOPE) +endfunction() diff --git a/third_party/boringssl/kit/src/cmake/perlasm.cmake b/third_party/boringssl/kit/src/cmake/perlasm.cmake new file mode 100644 index 00000000..98287990 --- /dev/null +++ b/third_party/boringssl/kit/src/cmake/perlasm.cmake @@ -0,0 +1,58 @@ +macro(append_to_parent_scope var) + list(APPEND ${var} ${ARGN}) + set(${var} "${${var}}" PARENT_SCOPE) +endmacro() + +function(add_perlasm_target dest src) + get_filename_component(dir ${dest} DIRECTORY) + if(dir STREQUAL "") + set(dir ".") + endif() + + add_custom_command( + OUTPUT ${dest} + COMMAND ${CMAKE_COMMAND} -E make_directory ${dir} + COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${ARGN} + ${dest} + DEPENDS + ${src} + ${PROJECT_SOURCE_DIR}/crypto/perlasm/arm-xlate.pl + ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86_64-xlate.pl + ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86asm.pl + ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86gas.pl + ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86masm.pl + ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86nasm.pl + WORKING_DIRECTORY . + ) +endfunction() + +# perlasm generates perlasm output from a given file. arch specifies the +# architecture. dest specifies the basename of the output file. The list of +# generated files will be appended to ${var}_ASM and ${var}_NASM depending on +# the assembler used. +function(perlasm var arch dest src) + if(arch STREQUAL "aarch64") + add_perlasm_target("${dest}-apple.S" ${src} ios64) + add_perlasm_target("${dest}-linux.S" ${src} linux64) + add_perlasm_target("${dest}-win.S" ${src} win64) + append_to_parent_scope("${var}_ASM" "${dest}-apple.S" "${dest}-linux.S" "${dest}-win.S") + elseif(arch STREQUAL "arm") + add_perlasm_target("${dest}-apple.S" ${src} ios32) + add_perlasm_target("${dest}-linux.S" ${src} linux32) + append_to_parent_scope("${var}_ASM" "${dest}-apple.S" "${dest}-linux.S") + elseif(arch STREQUAL "x86") + add_perlasm_target("${dest}-apple.S" ${src} macosx -fPIC -DOPENSSL_IA32_SSE2) + add_perlasm_target("${dest}-linux.S" ${src} elf -fPIC -DOPENSSL_IA32_SSE2) + add_perlasm_target("${dest}-win.asm" ${src} win32n -DOPENSSL_IA32_SSE2) + append_to_parent_scope("${var}_ASM" "${dest}-apple.S" "${dest}-linux.S") + append_to_parent_scope("${var}_NASM" "${dest}-win.asm") + elseif(arch STREQUAL "x86_64") + add_perlasm_target("${dest}-apple.S" ${src} macosx) + add_perlasm_target("${dest}-linux.S" ${src} elf) + add_perlasm_target("${dest}-win.asm" ${src} nasm) + append_to_parent_scope("${var}_ASM" "${dest}-apple.S" "${dest}-linux.S") + append_to_parent_scope("${var}_NASM" "${dest}-win.asm") + else() + message(FATAL_ERROR "Unknown perlasm architecture: $arch") + endif() +endfunction() diff --git a/third_party/boringssl/kit/src/crypto/CMakeLists.txt b/third_party/boringssl/kit/src/crypto/CMakeLists.txt index 9c724b74..80fd919e 100644 --- a/third_party/boringssl/kit/src/crypto/CMakeLists.txt +++ b/third_party/boringssl/kit/src/crypto/CMakeLists.txt @@ -1,95 +1,3 @@ -include_directories(../include) - -if(NOT OPENSSL_NO_ASM) - if(UNIX) - if(ARCH STREQUAL "aarch64") - # The "armx" Perl scripts look for "64" in the style argument - # in order to decide whether to generate 32- or 64-bit asm. - if(APPLE) - set(PERLASM_STYLE ios64) - else() - set(PERLASM_STYLE linux64) - endif() - elseif(ARCH STREQUAL "arm") - if(APPLE) - set(PERLASM_STYLE ios32) - else() - set(PERLASM_STYLE linux32) - endif() - elseif(ARCH STREQUAL "ppc64le") - set(PERLASM_STYLE linux64le) - else() - if(ARCH STREQUAL "x86") - set(PERLASM_FLAGS "-fPIC -DOPENSSL_IA32_SSE2") - endif() - if(APPLE) - set(PERLASM_STYLE macosx) - else() - set(PERLASM_STYLE elf) - endif() - endif() - set(ASM_EXT S) - enable_language(ASM) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack") - - # Clang's integerated assembler does not support debug symbols. - if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang") - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g") - endif() - - # CMake does not add -isysroot and -arch flags to assembly. - if(APPLE) - if(CMAKE_OSX_SYSROOT) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"") - endif() - foreach(arch ${CMAKE_OSX_ARCHITECTURES}) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}") - endforeach() - endif() - else() - if(ARCH STREQUAL "aarch64") - set(PERLASM_STYLE win64) - set(ASM_EXT S) - enable_language(ASM) - else() - if(ARCH STREQUAL "x86_64") - set(PERLASM_STYLE nasm) - else() - set(PERLASM_STYLE win32n) - set(PERLASM_FLAGS "-DOPENSSL_IA32_SSE2") - endif() - set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") - - # On Windows, we use the NASM output. - set(ASM_EXT asm) - enable_language(ASM_NASM) - endif() - endif() -endif() - -function(perlasm dest src) - get_filename_component(dir ${dest} DIRECTORY) - if(dir STREQUAL "") - set(dir ".") - endif() - - add_custom_command( - OUTPUT ${dest} - COMMAND ${CMAKE_COMMAND} -E make_directory ${dir} - COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${PERLASM_STYLE} ${PERLASM_FLAGS} ${ARGN} ${dest} - DEPENDS - ${src} - ${PROJECT_SOURCE_DIR}/crypto/perlasm/arm-xlate.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/ppc-xlate.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86_64-xlate.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86asm.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86gas.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86masm.pl - ${PROJECT_SOURCE_DIR}/crypto/perlasm/x86nasm.pl - WORKING_DIRECTORY . - ) -endfunction() - add_subdirectory(fipsmodule) add_subdirectory(test) @@ -104,66 +12,25 @@ if(FIPS_DELOCATE OR FIPS_SHARED) ) endif() -if(ARCH STREQUAL "arm") - set( - CRYPTO_ARCH_SOURCES - - chacha/chacha-armv4.${ASM_EXT} - curve25519/asm/x25519-asm-arm.S - poly1305/poly1305_arm_asm.S - test/trampoline-armv4.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "aarch64") - set( - CRYPTO_ARCH_SOURCES - - chacha/chacha-armv8.${ASM_EXT} - test/trampoline-armv8.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "ppc64le") - set( - CRYPTO_ARCH_SOURCES - - test/trampoline-ppc.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "x86") - set( - CRYPTO_ARCH_SOURCES - - chacha/chacha-x86.${ASM_EXT} - test/trampoline-x86.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "x86_64") - set( - CRYPTO_ARCH_SOURCES - - chacha/chacha-x86_64.${ASM_EXT} - cipher_extra/aes128gcmsiv-x86_64.${ASM_EXT} - cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT} - hrss/asm/poly_rq_mul.S - test/trampoline-x86_64.${ASM_EXT} - ) -endif() - -perlasm(chacha/chacha-armv4.${ASM_EXT} chacha/asm/chacha-armv4.pl) -perlasm(chacha/chacha-armv8.${ASM_EXT} chacha/asm/chacha-armv8.pl) -perlasm(chacha/chacha-x86.${ASM_EXT} chacha/asm/chacha-x86.pl) -perlasm(chacha/chacha-x86_64.${ASM_EXT} chacha/asm/chacha-x86_64.pl) -perlasm(cipher_extra/aes128gcmsiv-x86_64.${ASM_EXT} cipher_extra/asm/aes128gcmsiv-x86_64.pl) -perlasm(cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT} cipher_extra/asm/chacha20_poly1305_x86_64.pl) -perlasm(test/trampoline-armv4.${ASM_EXT} test/asm/trampoline-armv4.pl) -perlasm(test/trampoline-armv8.${ASM_EXT} test/asm/trampoline-armv8.pl) -perlasm(test/trampoline-ppc.${ASM_EXT} test/asm/trampoline-ppc.pl) -perlasm(test/trampoline-x86.${ASM_EXT} test/asm/trampoline-x86.pl) -perlasm(test/trampoline-x86_64.${ASM_EXT} test/asm/trampoline-x86_64.pl) +set( + CRYPTO_SOURCES_ASM + curve25519/asm/x25519-asm-arm.S + hrss/asm/poly_rq_mul.S + poly1305/poly1305_arm_asm.S + ../third_party/fiat/asm/fiat_curve25519_adx_mul.S + ../third_party/fiat/asm/fiat_curve25519_adx_square.S +) +perlasm(CRYPTO_SOURCES aarch64 chacha/chacha-armv8 chacha/asm/chacha-armv8.pl) +perlasm(CRYPTO_SOURCES aarch64 cipher_extra/chacha20_poly1305_armv8 cipher_extra/asm/chacha20_poly1305_armv8.pl) +perlasm(CRYPTO_SOURCES aarch64 test/trampoline-armv8 test/asm/trampoline-armv8.pl) +perlasm(CRYPTO_SOURCES arm chacha/chacha-armv4 chacha/asm/chacha-armv4.pl) +perlasm(CRYPTO_SOURCES arm test/trampoline-armv4 test/asm/trampoline-armv4.pl) +perlasm(CRYPTO_SOURCES x86 chacha/chacha-x86 chacha/asm/chacha-x86.pl) +perlasm(CRYPTO_SOURCES x86 test/trampoline-x86 test/asm/trampoline-x86.pl) +perlasm(CRYPTO_SOURCES x86_64 chacha/chacha-x86_64 chacha/asm/chacha-x86_64.pl) +perlasm(CRYPTO_SOURCES x86_64 cipher_extra/aes128gcmsiv-x86_64 cipher_extra/asm/aes128gcmsiv-x86_64.pl) +perlasm(CRYPTO_SOURCES x86_64 cipher_extra/chacha20_poly1305_x86_64 cipher_extra/asm/chacha20_poly1305_x86_64.pl) +perlasm(CRYPTO_SOURCES x86_64 test/trampoline-x86_64 test/asm/trampoline-x86_64.pl) add_custom_command( OUTPUT err_data.c @@ -203,20 +70,17 @@ add_library( asn1/a_bool.c asn1/a_d2i_fp.c asn1/a_dup.c - asn1/a_enum.c asn1/a_gentm.c asn1/a_i2d_fp.c asn1/a_int.c asn1/a_mbstr.c asn1/a_object.c asn1/a_octet.c - asn1/a_print.c asn1/a_strex.c asn1/a_strnid.c asn1/a_time.c asn1/a_type.c asn1/a_utctm.c - asn1/a_utf8.c asn1/asn1_lib.c asn1/asn1_par.c asn1/asn_pack.c @@ -228,7 +92,7 @@ add_library( asn1/tasn_new.c asn1/tasn_typ.c asn1/tasn_utl.c - asn1/time_support.c + asn1/posix_time.c base64/base64.c bio/bio.c bio/bio_mem.c @@ -252,27 +116,32 @@ add_library( chacha/chacha.c cipher_extra/cipher_extra.c cipher_extra/derive_key.c - cipher_extra/e_aesccm.c cipher_extra/e_aesctrhmac.c cipher_extra/e_aesgcmsiv.c cipher_extra/e_chacha20poly1305.c + cipher_extra/e_des.c cipher_extra/e_null.c cipher_extra/e_rc2.c cipher_extra/e_rc4.c cipher_extra/e_tls.c cipher_extra/tls_cbc.c - cmac/cmac.c conf/conf.c - cpu-aarch64-fuchsia.c - cpu-aarch64-linux.c - cpu-aarch64-win.c - cpu-arm-linux.c - cpu-arm.c - cpu-intel.c - cpu-ppc64le.c + cpu_aarch64_apple.c + cpu_aarch64_freebsd.c + cpu_aarch64_openbsd.c + cpu_aarch64_fuchsia.c + cpu_aarch64_linux.c + cpu_aarch64_win.c + cpu_arm_freebsd.c + cpu_arm_openbsd.c + cpu_arm_linux.c + cpu_arm.c + cpu_intel.c crypto.c curve25519/curve25519.c + curve25519/curve25519_64_adx.c curve25519/spake25519.c + des/des.c dh_extra/params.c dh_extra/dh_asn1.c digest_extra/digest_extra.c @@ -286,7 +155,6 @@ add_library( err/err.c err_data.c engine/engine.c - evp/digestsign.c evp/evp.c evp/evp_asn1.c evp/evp_ctx.c @@ -295,6 +163,7 @@ add_library( evp/p_ec_asn1.c evp/p_ed25519.c evp/p_ed25519_asn1.c + evp/p_hkdf.c evp/p_rsa.c evp/p_rsa_asn1.c evp/p_x25519.c @@ -304,9 +173,10 @@ add_library( evp/scrypt.c evp/sign.c ex_data.c - hkdf/hkdf.c hpke/hpke.c hrss/hrss.c + kyber/keccak.c + kyber/kyber.c lhash/lhash.c mem.c obj/obj.c @@ -335,9 +205,9 @@ add_library( rand_extra/rand_extra.c rand_extra/windows.c rc4/rc4.c - refcount_c11.c - refcount_lock.c + refcount.c rsa_extra/rsa_asn1.c + rsa_extra/rsa_crypt.c rsa_extra/rsa_print.c stack/stack.c siphash/siphash.c @@ -357,6 +227,7 @@ add_library( x509/by_file.c x509/i2d_pr.c x509/name_print.c + x509/policy.c x509/rsa_pss.c x509/t_crl.c x509/t_req.c @@ -396,12 +267,6 @@ add_library( x509/x_val.c x509/x_x509.c x509/x_x509a.c - x509v3/pcy_cache.c - x509v3/pcy_data.c - x509v3/pcy_lib.c - x509v3/pcy_map.c - x509v3/pcy_node.c - x509v3/pcy_tree.c x509v3/v3_akey.c x509v3/v3_akeya.c x509v3/v3_alt.c @@ -419,8 +284,6 @@ add_library( x509v3/v3_lib.c x509v3/v3_ncons.c x509v3/v3_ocsp.c - x509v3/v3_pci.c - x509v3/v3_pcia.c x509v3/v3_pcons.c x509v3/v3_pmaps.c x509v3/v3_prn.c @@ -429,23 +292,29 @@ add_library( x509v3/v3_utl.c $ - - ${CRYPTO_ARCH_SOURCES} ${CRYPTO_FIPS_OBJECTS} ) +if(OPENSSL_ASM) + target_sources(crypto PRIVATE ${CRYPTO_SOURCES_ASM}) +endif() +if(OPENSSL_NASM) + target_sources(crypto PRIVATE ${CRYPTO_SOURCES_NASM}) +endif() +target_include_directories(crypto PUBLIC + $ + $ +) +install_if_enabled(TARGETS crypto EXPORT OpenSSLTargets ${INSTALL_DESTINATION_DEFAULT}) +set_property(TARGET crypto PROPERTY EXPORT_NAME Crypto) if(FIPS_SHARED) - set(EXTRA_INJECT_HASH_ARGS) - if(ANDROID) - set(EXTRA_INJECT_HASH_ARGS "-sha256") - endif() # Rewrite libcrypto.so to inject the correct module hash value. This assumes # UNIX-style library naming, but we only support FIPS mode on Linux anyway. add_custom_command( TARGET crypto POST_BUILD COMMAND ${GO_EXECUTABLE} run ${CMAKE_CURRENT_SOURCE_DIR}/../util/fipstools/inject_hash/inject_hash.go - -o libcrypto.so -in-object libcrypto.so ${EXTRA_INJECT_HASH_ARGS} + -o libcrypto.so -in-object libcrypto.so # The DEPENDS argument to a POST_BUILD rule appears to be ignored. Thus # go_executable isn't used (as it doesn't get built), but we list this # dependency anyway in case it starts working in some CMake version. @@ -454,16 +323,21 @@ if(FIPS_SHARED) ) endif() -add_dependencies(crypto global_target) +add_dependencies(crypto boringssl_prefix_symbols) if(FIPS_DELOCATE OR FIPS_SHARED) add_dependencies(crypto bcm_o_target) endif() -SET_TARGET_PROPERTIES(crypto PROPERTIES LINKER_LANGUAGE C) +set_target_properties(crypto PROPERTIES LINKER_LANGUAGE C) -if(NOT WIN32 AND NOT ANDROID) - target_link_libraries(crypto pthread) +if(WIN32) + target_link_libraries(crypto ws2_32) +endif() + +if(NOT ANDROID) + find_package(Threads REQUIRED) + target_link_libraries(crypto Threads::Threads) endif() # Every target depends on crypto, so we add libcxx as a dependency here to @@ -480,10 +354,7 @@ add_executable( fipsmodule/rand/urandom_test.cc ) - target_link_libraries(urandom_test test_support_lib boringssl_gtest crypto) - -add_dependencies(urandom_test global_target) add_dependencies(all_tests urandom_test) add_executable( @@ -499,11 +370,10 @@ add_executable( chacha/chacha_test.cc cipher_extra/aead_test.cc cipher_extra/cipher_test.cc - cmac/cmac_test.cc compiler_test.cc conf/conf_test.cc constant_time_test.cc - cpu-arm-linux_test.cc + cpu_arm_linux_test.cc crypto_test.cc curve25519/ed25519_test.cc curve25519/spake25519_test.cc @@ -519,19 +389,22 @@ add_executable( evp/scrypt_test.cc fipsmodule/aes/aes_test.cc fipsmodule/bn/bn_test.cc + fipsmodule/cmac/cmac_test.cc fipsmodule/ec/ec_test.cc - fipsmodule/ec/p256-x86_64_test.cc + fipsmodule/ec/p256-nistz_test.cc fipsmodule/ecdsa/ecdsa_test.cc + fipsmodule/hkdf/hkdf_test.cc fipsmodule/md5/md5_test.cc fipsmodule/modes/gcm_test.cc fipsmodule/rand/ctrdrbg_test.cc fipsmodule/rand/fork_detect_test.cc + fipsmodule/service_indicator/service_indicator_test.cc fipsmodule/sha/sha_test.cc - hkdf/hkdf_test.cc hpke/hpke_test.cc hmac_extra/hmac_test.cc hrss/hrss_test.cc impl_dispatch_test.cc + kyber/kyber_test.cc lhash/lhash_test.cc obj/obj_test.cc pem/pem_test.cc @@ -552,16 +425,8 @@ add_executable( x509/x509_test.cc x509/x509_time_test.cc x509v3/tab_test.cc - x509v3/v3name_test.cc $ - $ ) - -add_dependencies(crypto_test global_target) - -target_link_libraries(crypto_test test_support_lib boringssl_gtest crypto) -if(WIN32) - target_link_libraries(crypto_test ws2_32) -endif() +target_link_libraries(crypto_test test_support_lib boringssl_gtest_main crypto) add_dependencies(all_tests crypto_test) diff --git a/third_party/boringssl/kit/src/crypto/abi_self_test.cc b/third_party/boringssl/kit/src/crypto/abi_self_test.cc index c48818b6..a42bd1de 100644 --- a/third_party/boringssl/kit/src/crypto/abi_self_test.cc +++ b/third_party/boringssl/kit/src/crypto/abi_self_test.cc @@ -58,9 +58,10 @@ TEST(ABITest, SanityCheck) { #if defined(OPENSSL_WINDOWS) // The invalid epilog makes Windows believe the epilog starts later than it // actually does. As a result, immediately after the popq, it does not - // realize the stack has been unwound and repeats the work. - EXPECT_NONFATAL_FAILURE(CHECK_ABI_SEH(abi_test_bad_unwind_epilog), - "unwound past starting frame"); + // realize the stack has been unwound and repeats the popq. This will result + // in reading the wrong return address and fail to unwind. The exact failure + // may vary depending on what was on the stack before. + EXPECT_NONFATAL_FAILURE(CHECK_ABI_SEH(abi_test_bad_unwind_epilog), ""); CHECK_ABI_NO_UNWIND(abi_test_bad_unwind_epilog); #endif // OPENSSL_WINDOWS } @@ -520,289 +521,3 @@ TEST(ABITest, AArch64) { CHECK_ABI_NO_UNWIND(abi_test_clobber_v15_upper); } #endif // OPENSSL_AARCH64 && SUPPORTS_ABI_TEST - -#if defined(OPENSSL_PPC64LE) && defined(SUPPORTS_ABI_TEST) -extern "C" { -void abi_test_clobber_r0(void); -// r1 is the stack pointer. -void abi_test_clobber_r2(void); -void abi_test_clobber_r3(void); -void abi_test_clobber_r4(void); -void abi_test_clobber_r5(void); -void abi_test_clobber_r6(void); -void abi_test_clobber_r7(void); -void abi_test_clobber_r8(void); -void abi_test_clobber_r9(void); -void abi_test_clobber_r10(void); -void abi_test_clobber_r11(void); -void abi_test_clobber_r12(void); -// r13 is the thread pointer. -void abi_test_clobber_r14(void); -void abi_test_clobber_r15(void); -void abi_test_clobber_r16(void); -void abi_test_clobber_r17(void); -void abi_test_clobber_r18(void); -void abi_test_clobber_r19(void); -void abi_test_clobber_r20(void); -void abi_test_clobber_r21(void); -void abi_test_clobber_r22(void); -void abi_test_clobber_r23(void); -void abi_test_clobber_r24(void); -void abi_test_clobber_r25(void); -void abi_test_clobber_r26(void); -void abi_test_clobber_r27(void); -void abi_test_clobber_r28(void); -void abi_test_clobber_r29(void); -void abi_test_clobber_r30(void); -void abi_test_clobber_r31(void); - -void abi_test_clobber_f0(void); -void abi_test_clobber_f1(void); -void abi_test_clobber_f2(void); -void abi_test_clobber_f3(void); -void abi_test_clobber_f4(void); -void abi_test_clobber_f5(void); -void abi_test_clobber_f6(void); -void abi_test_clobber_f7(void); -void abi_test_clobber_f8(void); -void abi_test_clobber_f9(void); -void abi_test_clobber_f10(void); -void abi_test_clobber_f11(void); -void abi_test_clobber_f12(void); -void abi_test_clobber_f13(void); -void abi_test_clobber_f14(void); -void abi_test_clobber_f15(void); -void abi_test_clobber_f16(void); -void abi_test_clobber_f17(void); -void abi_test_clobber_f18(void); -void abi_test_clobber_f19(void); -void abi_test_clobber_f20(void); -void abi_test_clobber_f21(void); -void abi_test_clobber_f22(void); -void abi_test_clobber_f23(void); -void abi_test_clobber_f24(void); -void abi_test_clobber_f25(void); -void abi_test_clobber_f26(void); -void abi_test_clobber_f27(void); -void abi_test_clobber_f28(void); -void abi_test_clobber_f29(void); -void abi_test_clobber_f30(void); -void abi_test_clobber_f31(void); - -void abi_test_clobber_v0(void); -void abi_test_clobber_v1(void); -void abi_test_clobber_v2(void); -void abi_test_clobber_v3(void); -void abi_test_clobber_v4(void); -void abi_test_clobber_v5(void); -void abi_test_clobber_v6(void); -void abi_test_clobber_v7(void); -void abi_test_clobber_v8(void); -void abi_test_clobber_v9(void); -void abi_test_clobber_v10(void); -void abi_test_clobber_v11(void); -void abi_test_clobber_v12(void); -void abi_test_clobber_v13(void); -void abi_test_clobber_v14(void); -void abi_test_clobber_v15(void); -void abi_test_clobber_v16(void); -void abi_test_clobber_v17(void); -void abi_test_clobber_v18(void); -void abi_test_clobber_v19(void); -void abi_test_clobber_v20(void); -void abi_test_clobber_v21(void); -void abi_test_clobber_v22(void); -void abi_test_clobber_v23(void); -void abi_test_clobber_v24(void); -void abi_test_clobber_v25(void); -void abi_test_clobber_v26(void); -void abi_test_clobber_v27(void); -void abi_test_clobber_v28(void); -void abi_test_clobber_v29(void); -void abi_test_clobber_v30(void); -void abi_test_clobber_v31(void); - -void abi_test_clobber_cr0(void); -void abi_test_clobber_cr1(void); -void abi_test_clobber_cr2(void); -void abi_test_clobber_cr3(void); -void abi_test_clobber_cr4(void); -void abi_test_clobber_cr5(void); -void abi_test_clobber_cr6(void); -void abi_test_clobber_cr7(void); - -void abi_test_clobber_ctr(void); -void abi_test_clobber_lr(void); - -} // extern "C" - -TEST(ABITest, PPC64LE) { - // abi_test_trampoline hides unsaved registers from the caller, so we can - // safely call the abi_test_clobber_* functions below. - abi_test::internal::CallerState state; - RAND_bytes(reinterpret_cast(&state), sizeof(state)); - CHECK_ABI_NO_UNWIND(abi_test_trampoline, - reinterpret_cast(abi_test_clobber_r14), - &state, nullptr, 0, 0 /* no breakpoint */); - - CHECK_ABI_NO_UNWIND(abi_test_clobber_r0); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r2); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r3); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r4); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r5); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r6); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r7); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r8); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r9); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r10); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r11); - CHECK_ABI_NO_UNWIND(abi_test_clobber_r12); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r14), - "r14 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r15), - "r15 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r16), - "r16 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r17), - "r17 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r18), - "r18 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r19), - "r19 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r20), - "r20 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r21), - "r21 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r22), - "r22 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r23), - "r23 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r24), - "r24 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r25), - "r25 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r26), - "r26 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r27), - "r27 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r28), - "r28 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r29), - "r29 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r30), - "r30 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r31), - "r31 was not restored after return"); - - CHECK_ABI_NO_UNWIND(abi_test_clobber_f0); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f1); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f2); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f3); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f4); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f5); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f6); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f7); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f8); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f9); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f10); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f11); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f12); - CHECK_ABI_NO_UNWIND(abi_test_clobber_f13); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f14), - "f14 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f15), - "f15 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f16), - "f16 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f17), - "f17 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f18), - "f18 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f19), - "f19 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f20), - "f20 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f21), - "f21 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f22), - "f22 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f23), - "f23 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f24), - "f24 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f25), - "f25 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f26), - "f26 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f27), - "f27 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f28), - "f28 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f29), - "f29 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f30), - "f30 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_f31), - "f31 was not restored after return"); - - CHECK_ABI_NO_UNWIND(abi_test_clobber_v0); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v1); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v2); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v3); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v4); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v5); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v6); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v7); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v8); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v9); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v10); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v11); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v12); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v13); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v14); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v15); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v16); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v17); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v18); - CHECK_ABI_NO_UNWIND(abi_test_clobber_v19); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v20), - "v20 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v21), - "v21 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v22), - "v22 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v23), - "v23 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v24), - "v24 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v25), - "v25 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v26), - "v26 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v27), - "v27 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v28), - "v28 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v29), - "v29 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v30), - "v30 was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_v31), - "v31 was not restored after return"); - - CHECK_ABI_NO_UNWIND(abi_test_clobber_cr0); - CHECK_ABI_NO_UNWIND(abi_test_clobber_cr1); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr2), - "cr was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr3), - "cr was not restored after return"); - EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_cr4), - "cr was not restored after return"); - CHECK_ABI_NO_UNWIND(abi_test_clobber_cr5); - CHECK_ABI_NO_UNWIND(abi_test_clobber_cr6); - CHECK_ABI_NO_UNWIND(abi_test_clobber_cr7); - - CHECK_ABI_NO_UNWIND(abi_test_clobber_ctr); - CHECK_ABI_NO_UNWIND(abi_test_clobber_lr); -} -#endif // OPENSSL_PPC64LE && SUPPORTS_ABI_TEST diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_bitstr.c b/third_party/boringssl/kit/src/crypto/asn1/a_bitstr.c index 1bb58e2b..2be07a45 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_bitstr.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_bitstr.c @@ -66,219 +66,219 @@ #include "internal.h" -int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d, int len) -{ - return ASN1_STRING_set(x, d, len); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d, + ossl_ssize_t len) { + return ASN1_STRING_set(x, d, len); } int asn1_bit_string_length(const ASN1_BIT_STRING *str, uint8_t *out_padding_bits) { - int len = str->length; - if (str->flags & ASN1_STRING_FLAG_BITS_LEFT) { - // If the string is already empty, it cannot have padding bits. - *out_padding_bits = len == 0 ? 0 : str->flags & 0x07; - return len; - } - - // TODO(https://crbug.com/boringssl/447): If we move this logic to - // |ASN1_BIT_STRING_set_bit|, can we remove this representation? - while (len > 0 && str->data[len - 1] == 0) { - len--; - } - uint8_t padding_bits = 0; - if (len > 0) { - uint8_t last = str->data[len - 1]; - assert(last != 0); - for (; padding_bits < 7; padding_bits++) { - if (last & (1 << padding_bits)) { - break; - } - } - } - *out_padding_bits = padding_bits; + int len = str->length; + if (str->flags & ASN1_STRING_FLAG_BITS_LEFT) { + // If the string is already empty, it cannot have padding bits. + *out_padding_bits = len == 0 ? 0 : str->flags & 0x07; return len; + } + + // TODO(https://crbug.com/boringssl/447): If we move this logic to + // |ASN1_BIT_STRING_set_bit|, can we remove this representation? + while (len > 0 && str->data[len - 1] == 0) { + len--; + } + uint8_t padding_bits = 0; + if (len > 0) { + uint8_t last = str->data[len - 1]; + assert(last != 0); + for (; padding_bits < 7; padding_bits++) { + if (last & (1 << padding_bits)) { + break; + } + } + } + *out_padding_bits = padding_bits; + return len; } int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, size_t *out) { - uint8_t padding_bits; - int len = asn1_bit_string_length(str, &padding_bits); - if (padding_bits != 0) { - return 0; - } - *out = len; - return 1; + uint8_t padding_bits; + int len = asn1_bit_string_length(str, &padding_bits); + if (padding_bits != 0) { + return 0; + } + *out = len; + return 1; } -int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) -{ - if (a == NULL) { - return 0; - } +int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) { + if (a == NULL) { + return 0; + } - uint8_t bits; - int len = asn1_bit_string_length(a, &bits); - int ret = 1 + len; - if (pp == NULL) { - return ret; - } + uint8_t bits; + int len = asn1_bit_string_length(a, &bits); + if (len > INT_MAX - 1) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + int ret = 1 + len; + if (pp == NULL) { + return ret; + } - uint8_t *p = *pp; - *(p++) = bits; - OPENSSL_memcpy(p, a->data, len); - if (len > 0) { - p[len - 1] &= (0xff << bits); - } - p += len; - *pp = p; - return (ret); + uint8_t *p = *pp; + *(p++) = bits; + OPENSSL_memcpy(p, a->data, len); + if (len > 0) { + p[len - 1] &= (0xff << bits); + } + p += len; + *pp = p; + return ret; } ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long len) -{ - ASN1_BIT_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - int padding; + const unsigned char **pp, long len) { + ASN1_BIT_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + int padding; - if (len < 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); - goto err; + if (len < 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + goto err; + } + + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + goto err; + } + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_BIT_STRING_new()) == NULL) { + return NULL; } + } else { + ret = (*a); + } - if (len > INT_MAX) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + p = *pp; + padding = *(p++); + len--; + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + goto err; + } + + // Unused bits in a BIT STRING must be zero. + uint8_t padding_mask = (1 << padding) - 1; + if (padding != 0 && (len < 1 || (p[len - 1] & padding_mask) != 0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); + goto err; + } + + // We do this to preserve the settings. If we modify the settings, via + // the _set_bit function, we will recalculate on output + ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); // clear + ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); // set + + if (len > 0) { + s = OPENSSL_memdup(p, len); + if (s == NULL) { goto err; } + p += len; + } else { + s = NULL; + } - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_BIT_STRING_new()) == NULL) - return (NULL); - } else - ret = (*a); + ret->length = (int)len; + OPENSSL_free(ret->data); + ret->data = s; + ret->type = V_ASN1_BIT_STRING; + if (a != NULL) { + (*a) = ret; + } + *pp = p; + return ret; +err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) { + ASN1_BIT_STRING_free(ret); + } + return NULL; +} - p = *pp; - padding = *(p++); - len--; - if (padding > 7) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - goto err; +// These next 2 functions from Goetz Babin-Ebell +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) { + int w, v, iv; + unsigned char *c; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + iv = ~v; + if (!value) { + v = 0; + } + + if (a == NULL) { + return 0; + } + + a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); // clear, set on write + + if ((a->length < (w + 1)) || (a->data == NULL)) { + if (!value) { + return 1; // Don't need to set } - - /* Unused bits in a BIT STRING must be zero. */ - uint8_t padding_mask = (1 << padding) - 1; - if (padding != 0 && - (len < 1 || (p[len - 1] & padding_mask) != 0)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); - goto err; - } - - /* - * We do this to preserve the settings. If we modify the settings, via - * the _set_bit function, we will recalculate on output - */ - ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ - ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */ - - if (len > 0) { - s = OPENSSL_memdup(p, len); - if (s == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - p += len; + if (a->data == NULL) { + c = (unsigned char *)OPENSSL_malloc(w + 1); } else { - s = NULL; + c = (unsigned char *)OPENSSL_realloc(a->data, w + 1); } - - ret->length = (int)len; - OPENSSL_free(ret->data); - ret->data = s; - ret->type = V_ASN1_BIT_STRING; - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_BIT_STRING_free(ret); - return (NULL); -} - -/* - * These next 2 functions from Goetz Babin-Ebell - */ -int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) -{ - int w, v, iv; - unsigned char *c; - - w = n / 8; - v = 1 << (7 - (n & 0x07)); - iv = ~v; - if (!value) - v = 0; - - if (a == NULL) - return 0; - - a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ - - if ((a->length < (w + 1)) || (a->data == NULL)) { - if (!value) - return (1); /* Don't need to set */ - if (a->data == NULL) - c = (unsigned char *)OPENSSL_malloc(w + 1); - else - c = (unsigned char *)OPENSSL_realloc(a->data, w + 1); - if (c == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return 0; - } - if (w + 1 - a->length > 0) - OPENSSL_memset(c + a->length, 0, w + 1 - a->length); - a->data = c; - a->length = w + 1; + if (c == NULL) { + return 0; } - a->data[w] = ((a->data[w]) & iv) | v; - while ((a->length > 0) && (a->data[a->length - 1] == 0)) - a->length--; - return (1); -} - -int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) -{ - int w, v; - - w = n / 8; - v = 1 << (7 - (n & 0x07)); - if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) - return (0); - return ((a->data[w] & v) != 0); -} - -/* - * Checks if the given bit string contains only bits specified by - * the flags vector. Returns 0 if there is at least one bit set in 'a' - * which is not specified in 'flags', 1 otherwise. - * 'len' is the length of 'flags'. - */ -int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, - const unsigned char *flags, int flags_len) -{ - int i, ok; - /* Check if there is one bit set at all. */ - if (!a || !a->data) - return 1; - - /* - * Check each byte of the internal representation of the bit string. - */ - ok = 1; - for (i = 0; i < a->length && ok; ++i) { - unsigned char mask = i < flags_len ? ~flags[i] : 0xff; - /* We are done if there is an unneeded bit set. */ - ok = (a->data[i] & mask) == 0; + if (w + 1 - a->length > 0) { + OPENSSL_memset(c + a->length, 0, w + 1 - a->length); } - return ok; + a->data = c; + a->length = w + 1; + } + a->data[w] = ((a->data[w]) & iv) | v; + while ((a->length > 0) && (a->data[a->length - 1] == 0)) { + a->length--; + } + return 1; +} + +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) { + int w, v; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) { + return 0; + } + return ((a->data[w] & v) != 0); +} + +// Checks if the given bit string contains only bits specified by +// the flags vector. Returns 0 if there is at least one bit set in 'a' +// which is not specified in 'flags', 1 otherwise. +// 'len' is the length of 'flags'. +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags, + int flags_len) { + int i, ok; + // Check if there is one bit set at all. + if (!a || !a->data) { + return 1; + } + + // Check each byte of the internal representation of the bit string. + ok = 1; + for (i = 0; i < a->length && ok; ++i) { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + // We are done if there is an unneeded bit set. + ok = (a->data[i] & mask) == 0; + } + return ok; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_bool.c b/third_party/boringssl/kit/src/crypto/asn1/a_bool.c index 3f32e807..e227b7f7 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_bool.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_bool.c @@ -56,67 +56,40 @@ #include +#include #include -#include -int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **pp) -{ - int r; - unsigned char *p, *allocated = NULL; +#include "../bytestring/internal.h" - r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); - if (pp == NULL) - return (r); - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(r)) == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - } else { - p = *pp; - } - - ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); - *p = a ? 0xff : 0x00; - - /* - * If a new buffer was allocated, just return it back. - * If not, return the incremented buffer pointer. - */ - *pp = allocated != NULL ? allocated : p + 1; - return r; +int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp) { + CBB cbb; + if (!CBB_init(&cbb, 3) || // + !CBB_add_asn1_bool(&cbb, a != ASN1_BOOLEAN_FALSE)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); } -ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *a, const unsigned char **pp, - long length) { - const unsigned char *p = *pp; - long len; - int inf, tag, xclass; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); - return -1; - } +ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, + long len) { + if (len < 0) { + return ASN1_BOOLEAN_NONE; + } - if (inf & V_ASN1_CONSTRUCTED) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return -1; - } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + int val; + if (!CBS_get_asn1_bool(&cbs, &val)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return ASN1_BOOLEAN_NONE; + } - if (tag != V_ASN1_BOOLEAN || xclass != V_ASN1_UNIVERSAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_BOOLEAN); - return -1; - } - - if (len != 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - return -1; - } - ASN1_BOOLEAN ret = (ASN1_BOOLEAN)*(p++); - if (a != NULL) { - (*a) = ret; - } - *pp = p; - return ret; + ASN1_BOOLEAN ret = val ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE; + if (out != NULL) { + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_d2i_fp.c b/third_party/boringssl/kit/src/crypto/asn1/a_d2i_fp.c index d0d6d03a..36c9d699 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_d2i_fp.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_d2i_fp.c @@ -63,29 +63,27 @@ #include -void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) -{ - uint8_t *data; - size_t len; - // Historically, this function did not impose a limit in OpenSSL and is used - // to read CRLs, so we leave this without an external bound. - if (!BIO_read_asn1(in, &data, &len, INT_MAX)) { - return NULL; - } - const uint8_t *ptr = data; - void *ret = ASN1_item_d2i(x, &ptr, len, it); - OPENSSL_free(data); - return ret; +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) { + uint8_t *data; + size_t len; + // Historically, this function did not impose a limit in OpenSSL and is used + // to read CRLs, so we leave this without an external bound. + if (!BIO_read_asn1(in, &data, &len, INT_MAX)) { + return NULL; + } + const uint8_t *ptr = data; + void *ret = ASN1_item_d2i(x, &ptr, len, it); + OPENSSL_free(data); + return ret; } -void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) -{ - BIO *b = BIO_new_fp(in, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); - return NULL; - } - void *ret = ASN1_item_d2i_bio(it, b, x); - BIO_free(b); - return ret; +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) { + BIO *b = BIO_new_fp(in, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); + return NULL; + } + void *ret = ASN1_item_d2i_bio(it, b, x); + BIO_free(b); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_dup.c b/third_party/boringssl/kit/src/crypto/asn1/a_dup.c index 9ede8511..b37a5c61 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_dup.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_dup.c @@ -59,29 +59,26 @@ #include #include -/* - * ASN1_ITEM version of dup: this follows the model above except we don't - * need to allocate the buffer. At some point this could be rewritten to - * directly dup the underlying structure instead of doing and encode and - * decode. - */ -void *ASN1_item_dup(const ASN1_ITEM *it, void *x) -{ - unsigned char *b = NULL; - const unsigned char *p; - long i; - void *ret; +// ASN1_ITEM version of dup: this follows the model above except we don't +// need to allocate the buffer. At some point this could be rewritten to +// directly dup the underlying structure instead of doing and encode and +// decode. +void *ASN1_item_dup(const ASN1_ITEM *it, void *x) { + unsigned char *b = NULL; + const unsigned char *p; + long i; + void *ret; - if (x == NULL) - return (NULL); + if (x == NULL) { + return NULL; + } - i = ASN1_item_i2d(x, &b, it); - if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return (NULL); - } - p = b; - ret = ASN1_item_d2i(NULL, &p, i, it); - OPENSSL_free(b); - return (ret); + i = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + return NULL; + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_enum.c b/third_party/boringssl/kit/src/crypto/asn1/a_enum.c deleted file mode 100644 index d7a7357f..00000000 --- a/third_party/boringssl/kit/src/crypto/asn1/a_enum.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include -#include - -#include -#include - -#include "../internal.h" - - -/* - * Code for ENUMERATED type: identical to INTEGER apart from a different tag. - * for comments on encoding see a_int.c - */ - -int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) -{ - int j, k; - unsigned int i; - unsigned char buf[sizeof(long) + 1]; - long d; - - a->type = V_ASN1_ENUMERATED; - if (a->length < (int)(sizeof(long) + 1)) { - if (a->data != NULL) - OPENSSL_free(a->data); - if ((a->data = - (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) - OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1); - } - if (a->data == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return (0); - } - d = v; - if (d < 0) { - d = -d; - a->type = V_ASN1_NEG_ENUMERATED; - } - - for (i = 0; i < sizeof(long); i++) { - if (d == 0) - break; - buf[i] = (int)d & 0xff; - d >>= 8; - } - j = 0; - for (k = i - 1; k >= 0; k--) - a->data[j++] = buf[k]; - a->length = j; - return (1); -} - -long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) -{ - int neg = 0, i; - - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_ENUMERATED) - neg = 1; - else if (i != V_ASN1_ENUMERATED) - return -1; - - OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long), - "long larger than uint64_t"); - - if (a->length > (int)sizeof(uint64_t)) { - /* hmm... a bit ugly */ - return -1; - } - - uint64_t r64 = 0; - if (a->data != NULL) { - for (i = 0; i < a->length; i++) { - r64 <<= 8; - r64 |= (unsigned char)a->data[i]; - } - - if (r64 > LONG_MAX) { - return -1; - } - } - - long r = (long) r64; - if (neg) - r = -r; - - return r; -} - -ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) -{ - ASN1_ENUMERATED *ret; - int len, j; - - if (ai == NULL) - ret = ASN1_ENUMERATED_new(); - else - ret = ai; - if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } - if (BN_is_negative(bn)) - ret->type = V_ASN1_NEG_ENUMERATED; - else - ret->type = V_ASN1_ENUMERATED; - j = BN_num_bits(bn); - len = ((j == 0) ? 0 : ((j / 8) + 1)); - if (ret->length < len + 4) { - unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); - if (!new_data) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->data = new_data; - } - - ret->length = BN_bn2bin(bn, ret->data); - return (ret); - err: - if (ret != ai) - ASN1_ENUMERATED_free(ret); - return (NULL); -} - -BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) -{ - BIGNUM *ret; - - if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); - else if (ai->type == V_ASN1_NEG_ENUMERATED) - BN_set_negative(ret, 1); - return (ret); -} diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_gentm.c b/third_party/boringssl/kit/src/crypto/asn1/a_gentm.c index 3e6f14e3..ff1f97cb 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_gentm.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_gentm.c @@ -55,212 +55,93 @@ * [including the GNU Public Licence.] */ #include +#include +#include +#include +#include #include #include -#include -#include - #include "internal.h" -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) -{ - static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - if (d->type != V_ASN1_GENERALIZEDTIME) - return (0); - l = d->length; - a = (char *)d->data; - o = 0; - /* - * GENERALIZEDTIME is similar to UTCTIME except the year is represented - * as YYYY. This stuff treats everything as a two digit field so make - * first two fields 00 to 99 - */ - if (l < 13) - goto err; - for (i = 0; i < 7; i++) { - if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n * 100 - 1900; - break; - case 1: - tm->tm_year += n; - break; - case 2: - tm->tm_mon = n - 1; - break; - case 3: - tm->tm_mday = n; - break; - case 4: - tm->tm_hour = n; - break; - case 5: - tm->tm_min = n; - break; - case 6: - tm->tm_sec = n; - break; - } - } - } - /* - * Optional fractional seconds: decimal point followed by one or more - * digits. - */ - if (a[o] == '.') { - if (++o > l) - goto err; - i = o; - while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) - o++; - /* Must have at least one digit after decimal point */ - if (i == o) - goto err; - } - - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? 1 : -1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 7; i < 9; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 7) - offset = n * 3600; - else if (i == 8) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } else if (a[o]) { - /* Missing time zone information. */ - goto err; - } - return (o == l); - err: - return (0); +int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) { + if (d->type != V_ASN1_GENERALIZEDTIME) { + return 0; + } + CBS cbs; + CBS_init(&cbs, d->data, (size_t)d->length); + if (!CBS_parse_generalized_time(&cbs, tm, /*allow_timezone_offset=*/0)) { + return 0; + } + return 1; } -int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) -{ - return asn1_generalizedtime_to_tm(NULL, d); +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) { + return asn1_generalizedtime_to_tm(NULL, d); } -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) -{ - ASN1_GENERALIZEDTIME t; - - t.type = V_ASN1_GENERALIZEDTIME; - t.length = strlen(str); - t.data = (unsigned char *)str; - if (ASN1_GENERALIZEDTIME_check(&t)) { - if (s != NULL) { - if (!ASN1_STRING_set((ASN1_STRING *)s, - (unsigned char *)str, t.length)) - return 0; - s->type = V_ASN1_GENERALIZEDTIME; - } - return (1); - } else - return (0); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) { + size_t len = strlen(str); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)str, len); + if (!CBS_parse_generalized_time(&cbs, /*out_tm=*/NULL, + /*allow_timezone_offset=*/0)) { + return 0; + } + if (s != NULL) { + if (!ASN1_STRING_set(s, str, len)) { + return 0; + } + s->type = V_ASN1_GENERALIZEDTIME; + } + return 1; } ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, - time_t t) -{ - return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); + int64_t posix_time) { + return ASN1_GENERALIZEDTIME_adj(s, posix_time, 0, 0); } ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, - time_t t, int offset_day, - long offset_sec) -{ - char *p; - struct tm *ts; - struct tm data; - size_t len = 20; - ASN1_GENERALIZEDTIME *tmps = NULL; - - if (s == NULL) - tmps = ASN1_GENERALIZEDTIME_new(); - else - tmps = s; - if (tmps == NULL) - return NULL; - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) - goto err; - - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - goto err; - } - - if (ts->tm_year < 0 - 1900 || ts->tm_year > 9999 - 1900) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); - goto err; - } - - p = (char *)tmps->data; - if ((p == NULL) || ((size_t)tmps->length < len)) { - p = OPENSSL_malloc(len); - if (p == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_free(tmps->data); - tmps->data = (unsigned char *)p; - } - - BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, - ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, - ts->tm_sec); - tmps->length = strlen(p); - tmps->type = V_ASN1_GENERALIZEDTIME; - return tmps; - err: - if (s == NULL) - ASN1_GENERALIZEDTIME_free(tmps); + int64_t posix_time, int offset_day, + long offset_sec) { + struct tm data; + if (!OPENSSL_posix_to_tm(posix_time, &data)) { return NULL; + } + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(&data, offset_day, offset_sec)) { + return NULL; + } + } + + if (data.tm_year < 0 - 1900 || data.tm_year > 9999 - 1900) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); + return NULL; + } + + char buf[16]; + BIO_snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ", + data.tm_year + 1900, data.tm_mon + 1, data.tm_mday, data.tm_hour, + data.tm_min, data.tm_sec); + + int free_s = 0; + if (s == NULL) { + free_s = 1; + s = ASN1_UTCTIME_new(); + if (s == NULL) { + return NULL; + } + } + + if (!ASN1_STRING_set(s, buf, strlen(buf))) { + if (free_s) { + ASN1_UTCTIME_free(s); + } + return NULL; + } + s->type = V_ASN1_GENERALIZEDTIME; + return s; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_i2d_fp.c b/third_party/boringssl/kit/src/crypto/asn1/a_i2d_fp.c index db0d8122..e0713fae 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_i2d_fp.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_i2d_fp.c @@ -61,28 +61,25 @@ #include -int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) -{ - BIO *b = BIO_new_fp(out, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); - return 0; - } - int ret = ASN1_item_i2d_bio(it, b, x); - BIO_free(b); - return ret; +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) { + BIO *b = BIO_new_fp(out, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB); + return 0; + } + int ret = ASN1_item_i2d_bio(it, b, x); + BIO_free(b); + return ret; } -int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) -{ - unsigned char *b = NULL; - int n = ASN1_item_i2d(x, &b, it); - if (b == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return 0; - } +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) { + unsigned char *b = NULL; + int n = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + return 0; + } - int ret = BIO_write_all(out, b, n); - OPENSSL_free(b); - return ret; + int ret = BIO_write_all(out, b, n); + OPENSSL_free(b); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_int.c b/third_party/boringssl/kit/src/crypto/asn1/a_int.c index 1695fd07..27845c0b 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_int.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_int.c @@ -56,365 +56,410 @@ #include -#include +#include #include +#include +#include #include #include #include "../internal.h" -ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) -{ - return ASN1_STRING_dup(x); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) { + return ASN1_STRING_dup(x); } -int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) -{ - int neg, ret; - /* Compare signs */ - neg = x->type & V_ASN1_NEG; - if (neg != (y->type & V_ASN1_NEG)) { - if (neg) - return -1; - else - return 1; - } +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) { + // Compare signs. + int neg = x->type & V_ASN1_NEG; + if (neg != (y->type & V_ASN1_NEG)) { + return neg ? -1 : 1; + } - ret = ASN1_STRING_cmp(x, y); - - if (neg) - return -ret; - else - return ret; -} - -/* - * This converts an ASN1 INTEGER into its content encoding. - * The internal representation is an ASN1_STRING whose data is a big endian - * representation of the value, ignoring the sign. The sign is determined by - * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. - * - * Positive integers are no problem: they are almost the same as the DER - * encoding, except if the first byte is >= 0x80 we need to add a zero pad. - * - * Negative integers are a bit trickier... - * The DER representation of negative integers is in 2s complement form. - * The internal form is converted by complementing each octet and finally - * adding one to the result. This can be done less messily with a little trick. - * If the internal form has trailing zeroes then they will become FF by the - * complement and 0 by the add one (due to carry) so just copy as many trailing - * zeros to the destination as there are in the source. The carry will add one - * to the last none zero octet: so complement this octet and add one and finally - * complement any left over until you get to the start of the string. - * - * Padding is a little trickier too. If the first bytes is > 0x80 then we pad - * with 0xff. However if the first byte is 0x80 and one of the following bytes - * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 - * followed by optional zeros isn't padded. - */ - -int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp) -{ - int pad = 0, ret, i, neg; - unsigned char *p, *n, pb = 0; - - if (a == NULL) - return (0); - neg = a->type & V_ASN1_NEG; - if (a->length == 0) - ret = 1; - else { - ret = a->length; - i = a->data[0]; - if (ret == 1 && i == 0) - neg = 0; - if (!neg && (i > 127)) { - pad = 1; - pb = 0; - } else if (neg) { - if (i > 128) { - pad = 1; - pb = 0xFF; - } else if (i == 128) { - /* - * Special case: if any other bytes non zero we pad: - * otherwise we don't. - */ - for (i = 1; i < a->length; i++) - if (a->data[i]) { - pad = 1; - pb = 0xFF; - break; - } - } - } - ret += pad; - } - if (pp == NULL) - return (ret); - p = *pp; - - if (pad) - *(p++) = pb; - if (a->length == 0) - *(p++) = 0; - else if (!neg) - OPENSSL_memcpy(p, a->data, (unsigned int)a->length); - else { - /* Begin at the end of the encoding */ - n = a->data + a->length - 1; - p += a->length - 1; - i = a->length; - /* Copy zeros to destination as long as source is zero */ - while (!*n && i > 1) { - *(p--) = 0; - n--; - i--; - } - /* Complement and increment next octet */ - *(p--) = ((*(n--)) ^ 0xff) + 1; - i--; - /* Complement any octets left */ - for (; i > 0; i--) - *(p--) = *(n--) ^ 0xff; - } - - *pp += ret; - return (ret); -} - -/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ - -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long len) -{ - ASN1_INTEGER *ret = NULL; - const unsigned char *p, *pend; - unsigned char *to, *s; - int i; - - /* - * This function can handle lengths up to INT_MAX - 1, but the rest of the - * legacy ASN.1 code mixes integer types, so avoid exposing it to - * ASN1_INTEGERS with larger lengths. - */ - if (len < 0 || len > INT_MAX / 2) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); - return NULL; - } - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_INTEGER_new()) == NULL) - return (NULL); - ret->type = V_ASN1_INTEGER; - } else - ret = (*a); - - p = *pp; - pend = p + len; - - /* - * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies - * a missing NULL parameter. - */ - s = (unsigned char *)OPENSSL_malloc((int)len + 1); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - to = s; - if (!len) { - /* - * Strictly speaking this is an illegal INTEGER but we tolerate it. - */ - ret->type = V_ASN1_INTEGER; - } else if (*p & 0x80) { /* a negative number */ - ret->type = V_ASN1_NEG_INTEGER; - if ((*p == 0xff) && (len != 1)) { - p++; - len--; - } - i = len; - p += i - 1; - to += i - 1; - while ((!*p) && i) { - *(to--) = 0; - i--; - p--; - } - /* - * Special case: if all zeros then the number will be of the form FF - * followed by n zero bytes: this corresponds to 1 followed by n zero - * bytes. We've already written n zeros so we just append an extra - * one and set the first byte to a 1. This is treated separately - * because it is the only case where the number of bytes is larger - * than len. - */ - if (!i) { - *s = 1; - s[len] = 0; - len++; - } else { - *(to--) = (*(p--) ^ 0xff) + 1; - i--; - for (; i > 0; i--) - *(to--) = *(p--) ^ 0xff; - } + int ret = ASN1_STRING_cmp(x, y); + if (neg) { + // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from + // returning |INT_MIN|. + if (ret < 0) { + return 1; + } else if (ret > 0) { + return -1; } else { - ret->type = V_ASN1_INTEGER; - if ((*p == 0) && (len != 1)) { - p++; - len--; - } - OPENSSL_memcpy(s, p, (int)len); + return 0; } + } - if (ret->data != NULL) - OPENSSL_free(ret->data); - ret->data = s; - ret->length = (int)len; - if (a != NULL) - (*a) = ret; - *pp = pend; - return (ret); - err: - OPENSSL_PUT_ERROR(ASN1, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_INTEGER_free(ret); - return (NULL); + return ret; } -int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) -{ - if (v >= 0) { - return ASN1_INTEGER_set_uint64(a, (uint64_t) v); - } - - if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) { - return 0; - } - - a->type = V_ASN1_NEG_INTEGER; - return 1; +// negate_twos_complement negates |len| bytes from |buf| in-place, interpreted +// as a signed, big-endian two's complement value. +static void negate_twos_complement(uint8_t *buf, size_t len) { + uint8_t borrow = 0; + for (size_t i = len - 1; i < len; i--) { + uint8_t t = buf[i]; + buf[i] = 0u - borrow - t; + borrow |= t != 0; + } } -int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) -{ - uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t)); - if (newdata == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return 0; +static int is_all_zeros(const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; i++) { + if (in[i] != 0) { + return 0; } - - OPENSSL_free(out->data); - out->data = newdata; - v = CRYPTO_bswap8(v); - memcpy(out->data, &v, sizeof(v)); - - out->type = V_ASN1_INTEGER; - - size_t leading_zeros; - for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1; - leading_zeros++) { - if (out->data[leading_zeros] != 0) { - break; - } - } - - out->length = sizeof(uint64_t) - leading_zeros; - OPENSSL_memmove(out->data, out->data + leading_zeros, out->length); - - return 1; + } + return 1; } -long ASN1_INTEGER_get(const ASN1_INTEGER *a) -{ - int neg = 0, i; +int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { + if (in == NULL) { + return 0; + } - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_INTEGER) - neg = 1; - else if (i != V_ASN1_INTEGER) - return -1; + // |ASN1_INTEGER|s should be represented minimally, but it is possible to + // construct invalid ones. Skip leading zeros so this does not produce an + // invalid encoding or break invariants. + CBS cbs; + CBS_init(&cbs, in->data, in->length); + while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) { + CBS_skip(&cbs, 1); + } - OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long), - "long larger than uint64_t"); + int is_negative = (in->type & V_ASN1_NEG) != 0; + size_t pad; + CBS copy = cbs; + uint8_t msb; + if (!CBS_get_u8(©, &msb)) { + // Zero is represented as a single byte. + is_negative = 0; + pad = 1; + } else if (is_negative) { + // 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff + // through 0x00...01 and need an extra byte to be negative. + // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff + // through 0x80...00 and can be negated as-is. + pad = msb > 0x80 || + (msb == 0x80 && !is_all_zeros(CBS_data(©), CBS_len(©))); + } else { + // If the high bit is set, the signed representation needs an extra + // byte to be positive. + pad = (msb & 0x80) != 0; + } - if (a->length > (int)sizeof(uint64_t)) { - /* hmm... a bit ugly, return all ones */ - return -1; - } + if (CBS_len(&cbs) > INT_MAX - pad) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + int len = (int)(pad + CBS_len(&cbs)); + assert(len > 0); + if (outp == NULL) { + return len; + } - uint64_t r64 = 0; - if (a->data != NULL) { - for (i = 0; i < a->length; i++) { - r64 <<= 8; - r64 |= (unsigned char)a->data[i]; - } - - if (r64 > LONG_MAX) { - return -1; - } - } - - long r = (long) r64; - if (neg) - r = -r; - - return r; + if (pad) { + (*outp)[0] = 0; + } + OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs)); + if (is_negative) { + negate_twos_complement(*outp, len); + assert((*outp)[0] >= 0x80); + } else { + assert((*outp)[0] < 0x80); + } + *outp += len; + return len; } -ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) -{ - ASN1_INTEGER *ret; - int len, j; +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, + long len) { + // This function can handle lengths up to INT_MAX - 1, but the rest of the + // legacy ASN.1 code mixes integer types, so avoid exposing it to + // ASN1_INTEGERS with larger lengths. + if (len < 0 || len > INT_MAX / 2) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return NULL; + } - if (ai == NULL) - ret = ASN1_INTEGER_new(); - else - ret = ai; + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + int is_negative; + if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return NULL; + } + + ASN1_INTEGER *ret = NULL; + if (out == NULL || *out == NULL) { + ret = ASN1_INTEGER_new(); if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; + return NULL; } - if (BN_is_negative(bn) && !BN_is_zero(bn)) - ret->type = V_ASN1_NEG_INTEGER; - else - ret->type = V_ASN1_INTEGER; - j = BN_num_bits(bn); - len = ((j == 0) ? 0 : ((j / 8) + 1)); - if (ret->length < len + 4) { - unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); - if (!new_data) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->data = new_data; + } else { + ret = *out; + } + + // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First, + // determine the size needed for a minimal result. + if (is_negative) { + // 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff + // through 0x000100...001 and need one leading zero removed. 0x8000...00 + // through 0xff00...00 have a two's complement of 0x8000...00 through + // 0x0100...00 and will be minimally-encoded as-is. + if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff && + !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) { + CBS_skip(&cbs, 1); } - ret->length = BN_bn2bin(bn, ret->data); - /* Correct zero case */ - if (!ret->length) { - ret->data[0] = 0; - ret->length = 1; + } else { + // Remove the leading zero byte, if any. + if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) { + CBS_skip(&cbs, 1); } - return (ret); - err: - if (ret != ai) - ASN1_INTEGER_free(ret); - return (NULL); + } + + if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) { + goto err; + } + + if (is_negative) { + ret->type = V_ASN1_NEG_INTEGER; + negate_twos_complement(ret->data, ret->length); + } else { + ret->type = V_ASN1_INTEGER; + } + + // The value should be minimally-encoded. + assert(ret->length == 0 || ret->data[0] != 0); + // Zero is not negative. + assert(!is_negative || ret->length > 0); + + *inp += len; + if (out != NULL) { + *out = ret; + } + return ret; + +err: + if (ret != NULL && (out == NULL || *out != ret)) { + ASN1_INTEGER_free(ret); + } + return NULL; } -BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) -{ - BIGNUM *ret; +int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) { + if (v >= 0) { + return ASN1_INTEGER_set_uint64(a, (uint64_t)v); + } - if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); - else if (ai->type == V_ASN1_NEG_INTEGER) - BN_set_negative(ret, 1); - return (ret); + if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) { + return 0; + } + + a->type = V_ASN1_NEG_INTEGER; + return 1; +} + +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) { + if (v >= 0) { + return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v); + } + + if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) { + return 0; + } + + a->type = V_ASN1_NEG_ENUMERATED; + return 1; +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) { + static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t"); + return ASN1_INTEGER_set_int64(a, v); +} + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) { + static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t"); + return ASN1_ENUMERATED_set_int64(a, v); +} + +static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) { + uint8_t buf[sizeof(uint64_t)]; + CRYPTO_store_u64_be(buf, v); + size_t leading_zeros; + for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) { + if (buf[leading_zeros] != 0) { + break; + } + } + + if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) { + return 0; + } + out->type = type; + return 1; +} + +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) { + return asn1_string_set_uint64(out, v, V_ASN1_INTEGER); +} + +int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) { + return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED); +} + +static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a, + int type) { + if ((a->type & ~V_ASN1_NEG) != type) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE); + return 0; + } + uint8_t buf[sizeof(uint64_t)] = {0}; + if (a->length > (int)sizeof(buf)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return 0; + } + OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length); + *out = CRYPTO_load_u64_be(buf); + return 1; +} + +static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a, + int type) { + if (!asn1_string_get_abs_uint64(out, a, type)) { + return 0; + } + if (a->type & V_ASN1_NEG) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return 0; + } + return 1; +} + +int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) { + return asn1_string_get_uint64(out, a, V_ASN1_INTEGER); +} + +int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) { + return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED); +} + +static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) { + uint64_t v; + if (!asn1_string_get_abs_uint64(&v, a, type)) { + return 0; + } + int64_t i64; + int fits_in_i64; + // Check |v != 0| to handle manually-constructed negative zeros. + if ((a->type & V_ASN1_NEG) && v != 0) { + i64 = (int64_t)(0u - v); + fits_in_i64 = i64 < 0; + } else { + i64 = (int64_t)v; + fits_in_i64 = i64 >= 0; + } + if (!fits_in_i64) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); + return 0; + } + *out = i64; + return 1; +} + +int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) { + return asn1_string_get_int64(out, a, V_ASN1_INTEGER); +} + +int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) { + return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED); +} + +static long asn1_string_get_long(const ASN1_STRING *a, int type) { + if (a == NULL) { + return 0; + } + + int64_t v; + if (!asn1_string_get_int64(&v, a, type) || // + v < LONG_MIN || v > LONG_MAX) { + // This function's return value does not distinguish overflow from -1. + ERR_clear_error(); + return -1; + } + + return (long)v; +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) { + return asn1_string_get_long(a, V_ASN1_INTEGER); +} + +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) { + return asn1_string_get_long(a, V_ASN1_ENUMERATED); +} + +static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, + int type) { + ASN1_INTEGER *ret; + if (ai == NULL) { + ret = ASN1_STRING_type_new(type); + } else { + ret = ai; + } + if (ret == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + if (BN_is_negative(bn) && !BN_is_zero(bn)) { + ret->type = type | V_ASN1_NEG; + } else { + ret->type = type; + } + + int len = BN_num_bytes(bn); + if (!ASN1_STRING_set(ret, NULL, len) || + !BN_bn2bin_padded(ret->data, len, bn)) { + goto err; + } + return ret; + +err: + if (ret != ai) { + ASN1_STRING_free(ret); + } + return NULL; +} + +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) { + return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER); +} + +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) { + return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED); +} + +static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) { + if ((ai->type & ~V_ASN1_NEG) != type) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE); + return NULL; + } + + BIGNUM *ret; + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + } else if (ai->type & V_ASN1_NEG) { + BN_set_negative(ret, 1); + } + return ret; +} + +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) { + return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER); +} + +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) { + return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_mbstr.c b/third_party/boringssl/kit/src/crypto/asn1/a_mbstr.c index 5853b723..8fc82ab5 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_mbstr.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_mbstr.c @@ -63,236 +63,217 @@ #include #include -#include "internal.h" #include "../bytestring/internal.h" +#include "internal.h" -/* - * These functions take a string in UTF8, ASCII or multibyte form and a mask - * of permissible ASN1 string types. It then works out the minimal type - * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and - * creates a string of the correct type with the supplied data. Yes this is - * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum - * size limits too. - */ +// These functions take a string in UTF8, ASCII or multibyte form and a mask +// of permissible ASN1 string types. It then works out the minimal type +// (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and +// creates a string of the correct type with the supplied data. Yes this is +// horrible: it has to be :-( The 'ncopy' form checks minimum and maximum +// size limits too. -int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask) -{ - return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, + ossl_ssize_t len, int inform, unsigned long mask) { + return ASN1_mbstring_ncopy(out, in, len, inform, mask, /*minsize=*/0, + /*maxsize=*/0); } OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_BMPSTRING) OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UNIVERSALSTRING) OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UTF8STRING) -int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask, - long minsize, long maxsize) -{ - int str_type; - char free_out; - ASN1_STRING *dest; - size_t nchar = 0; - char strbuf[32]; - if (len == -1) - len = strlen((const char *)in); - if (!mask) - mask = DIRSTRING_TYPE; +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, + ossl_ssize_t len, int inform, unsigned long mask, + ossl_ssize_t minsize, ossl_ssize_t maxsize) { + if (len == -1) { + len = strlen((const char *)in); + } + if (!mask) { + mask = DIRSTRING_TYPE; + } - int (*decode_func)(CBS *, uint32_t*); - int error; - switch (inform) { + int (*decode_func)(CBS *, uint32_t *); + int error; + switch (inform) { case MBSTRING_BMP: - decode_func = cbs_get_ucs2_be; - error = ASN1_R_INVALID_BMPSTRING; - break; + decode_func = cbs_get_ucs2_be; + error = ASN1_R_INVALID_BMPSTRING; + break; case MBSTRING_UNIV: - decode_func = cbs_get_utf32_be; - error = ASN1_R_INVALID_UNIVERSALSTRING; - break; + decode_func = cbs_get_utf32_be; + error = ASN1_R_INVALID_UNIVERSALSTRING; + break; case MBSTRING_UTF8: - decode_func = cbs_get_utf8; - error = ASN1_R_INVALID_UTF8STRING; - break; + decode_func = cbs_get_utf8; + error = ASN1_R_INVALID_UTF8STRING; + break; case MBSTRING_ASC: - decode_func = cbs_get_latin1; - error = ERR_R_INTERNAL_ERROR; // Latin-1 inputs are never invalid. - break; + decode_func = cbs_get_latin1; + error = ERR_R_INTERNAL_ERROR; // Latin-1 inputs are never invalid. + break; default: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); - return -1; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + // Check |minsize| and |maxsize| and work out the minimal type, if any. + CBS cbs; + CBS_init(&cbs, in, len); + size_t utf8_len = 0, nchar = 0; + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!decode_func(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, error); + return -1; + } + if (nchar == 0 && (inform == MBSTRING_BMP || inform == MBSTRING_UNIV) && + c == 0xfeff) { + // Reject byte-order mark. We could drop it but that would mean + // adding ambiguity around whether a BOM was included or not when + // matching strings. + // + // For a little-endian UCS-2 string, the BOM will appear as 0xfffe + // and will be rejected as noncharacter, below. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; } - /* Check |minsize| and |maxsize| and work out the minimal type, if any. */ - CBS cbs; - CBS_init(&cbs, in, len); - size_t utf8_len = 0; - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!decode_func(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, error); - return -1; - } - if (nchar == 0 && - (inform == MBSTRING_BMP || inform == MBSTRING_UNIV) && - c == 0xfeff) { - /* Reject byte-order mark. We could drop it but that would mean - * adding ambiguity around whether a BOM was included or not when - * matching strings. - * - * For a little-endian UCS-2 string, the BOM will appear as 0xfffe - * and will be rejected as noncharacter, below. */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); - return -1; - } - - /* Update which output formats are still possible. */ - if ((mask & B_ASN1_PRINTABLESTRING) && !asn1_is_printable(c)) { - mask &= ~B_ASN1_PRINTABLESTRING; - } - if ((mask & B_ASN1_IA5STRING) && (c > 127)) { - mask &= ~B_ASN1_IA5STRING; - } - if ((mask & B_ASN1_T61STRING) && (c > 0xff)) { - mask &= ~B_ASN1_T61STRING; - } - if ((mask & B_ASN1_BMPSTRING) && (c > 0xffff)) { - mask &= ~B_ASN1_BMPSTRING; - } - if (!mask) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); - return -1; - } - - nchar++; - utf8_len += cbb_get_utf8_len(c); - } - - if (minsize > 0 && nchar < (size_t)minsize) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); - BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize); - ERR_add_error_data(2, "minsize=", strbuf); - return -1; + // Update which output formats are still possible. + if ((mask & B_ASN1_PRINTABLESTRING) && !asn1_is_printable(c)) { + mask &= ~B_ASN1_PRINTABLESTRING; + } + if ((mask & B_ASN1_IA5STRING) && (c > 127)) { + mask &= ~B_ASN1_IA5STRING; + } + if ((mask & B_ASN1_T61STRING) && (c > 0xff)) { + mask &= ~B_ASN1_T61STRING; + } + if ((mask & B_ASN1_BMPSTRING) && (c > 0xffff)) { + mask &= ~B_ASN1_BMPSTRING; + } + if (!mask) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; } + nchar++; + utf8_len += cbb_get_utf8_len(c); if (maxsize > 0 && nchar > (size_t)maxsize) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); - BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); - ERR_add_error_data(2, "maxsize=", strbuf); - return -1; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + ERR_add_error_dataf("maxsize=%zu", (size_t)maxsize); + return -1; } + } - /* Now work out output format and string type */ - int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1; - size_t size_estimate = nchar; - int outform = MBSTRING_ASC; - if (mask & B_ASN1_PRINTABLESTRING) { - str_type = V_ASN1_PRINTABLESTRING; - } else if (mask & B_ASN1_IA5STRING) { - str_type = V_ASN1_IA5STRING; - } else if (mask & B_ASN1_T61STRING) { - str_type = V_ASN1_T61STRING; - } else if (mask & B_ASN1_BMPSTRING) { - str_type = V_ASN1_BMPSTRING; - outform = MBSTRING_BMP; - encode_func = cbb_add_ucs2_be; - size_estimate = 2 * nchar; - } else if (mask & B_ASN1_UNIVERSALSTRING) { - str_type = V_ASN1_UNIVERSALSTRING; - encode_func = cbb_add_utf32_be; - size_estimate = 4 * nchar; - outform = MBSTRING_UNIV; - } else if (mask & B_ASN1_UTF8STRING) { - str_type = V_ASN1_UTF8STRING; - outform = MBSTRING_UTF8; - encode_func = cbb_add_utf8; - size_estimate = utf8_len; - } else { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); - return -1; - } - - if (!out) - return str_type; - if (*out) { - free_out = 0; - dest = *out; - if (dest->data) { - dest->length = 0; - OPENSSL_free(dest->data); - dest->data = NULL; - } - dest->type = str_type; - } else { - free_out = 1; - dest = ASN1_STRING_type_new(str_type); - if (!dest) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - *out = dest; - } - - /* If both the same type just copy across */ - if (inform == outform) { - if (!ASN1_STRING_set(dest, in, len)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - return str_type; - } - - CBB cbb; - if (!CBB_init(&cbb, size_estimate + 1)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - CBS_init(&cbs, in, len); - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!decode_func(&cbs, &c) || - !encode_func(&cbb, c)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); - goto err; - } - } - uint8_t *data = NULL; - size_t data_len; - if (/* OpenSSL historically NUL-terminated this value with a single byte, - * even for |MBSTRING_BMP| and |MBSTRING_UNIV|. */ - !CBB_add_u8(&cbb, 0) || - !CBB_finish(&cbb, &data, &data_len) || - data_len < 1 || - data_len > INT_MAX) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); - OPENSSL_free(data); - goto err; - } - dest->length = (int)(data_len - 1); - dest->data = data; - return str_type; - - err: - if (free_out) - ASN1_STRING_free(dest); - CBB_cleanup(&cbb); + if (minsize > 0 && nchar < (size_t)minsize) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + ERR_add_error_dataf("minsize=%zu", (size_t)minsize); return -1; + } + + // Now work out output format and string type + int str_type; + int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1; + size_t size_estimate = nchar; + int outform = MBSTRING_ASC; + if (mask & B_ASN1_PRINTABLESTRING) { + str_type = V_ASN1_PRINTABLESTRING; + } else if (mask & B_ASN1_IA5STRING) { + str_type = V_ASN1_IA5STRING; + } else if (mask & B_ASN1_T61STRING) { + str_type = V_ASN1_T61STRING; + } else if (mask & B_ASN1_BMPSTRING) { + str_type = V_ASN1_BMPSTRING; + outform = MBSTRING_BMP; + encode_func = cbb_add_ucs2_be; + size_estimate = 2 * nchar; + } else if (mask & B_ASN1_UNIVERSALSTRING) { + str_type = V_ASN1_UNIVERSALSTRING; + encode_func = cbb_add_utf32_be; + size_estimate = 4 * nchar; + outform = MBSTRING_UNIV; + } else if (mask & B_ASN1_UTF8STRING) { + str_type = V_ASN1_UTF8STRING; + outform = MBSTRING_UTF8; + encode_func = cbb_add_utf8; + size_estimate = utf8_len; + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + if (!out) { + return str_type; + } + + int free_dest = 0; + ASN1_STRING *dest; + if (*out) { + dest = *out; + } else { + free_dest = 1; + dest = ASN1_STRING_type_new(str_type); + if (!dest) { + return -1; + } + } + + CBB cbb; + CBB_zero(&cbb); + // If both the same type just copy across + if (inform == outform) { + if (!ASN1_STRING_set(dest, in, len)) { + goto err; + } + dest->type = str_type; + *out = dest; + return str_type; + } + if (!CBB_init(&cbb, size_estimate + 1)) { + goto err; + } + CBS_init(&cbs, in, len); + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!decode_func(&cbs, &c) || !encode_func(&cbb, c)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + goto err; + } + } + uint8_t *data = NULL; + size_t data_len; + if (// OpenSSL historically NUL-terminated this value with a single byte, + // even for |MBSTRING_BMP| and |MBSTRING_UNIV|. + !CBB_add_u8(&cbb, 0) || !CBB_finish(&cbb, &data, &data_len) || + data_len < 1 || data_len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + OPENSSL_free(data); + goto err; + } + dest->type = str_type; + ASN1_STRING_set0(dest, data, (int)data_len - 1); + *out = dest; + return str_type; + +err: + if (free_dest) { + ASN1_STRING_free(dest); + } + CBB_cleanup(&cbb); + return -1; } -int asn1_is_printable(uint32_t value) -{ - if (value > 0x7f) { - return 0; - } - /* Note we cannot use |isalnum| because it is locale-dependent. */ - return ('a' <= value && value <= 'z') || // - ('A' <= value && value <= 'Z') || // - ('0' <= value && value <= '9') || // - value == ' ' || value == '\'' || value == '(' || value == ')' || - value == '+' || value == ',' || value == '-' || value == '.' || - value == '/' || value == ':' || value == '=' || value == '?'; +int asn1_is_printable(uint32_t value) { + if (value > 0x7f) { + return 0; + } + return OPENSSL_isalnum(value) || // + value == ' ' || value == '\'' || value == '(' || value == ')' || + value == '+' || value == ',' || value == '-' || value == '.' || + value == '/' || value == ':' || value == '=' || value == '?'; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_object.c b/third_party/boringssl/kit/src/crypto/asn1/a_object.c index 30a656d3..e5019341 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_object.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_object.c @@ -59,241 +59,177 @@ #include #include +#include #include #include #include +#include "../bytestring/internal.h" #include "../internal.h" #include "internal.h" -int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) -{ - if (a == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } +int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { + if (in == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } - if (a->length == 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - return -1; - } + if (in->length <= 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + return -1; + } - int objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); - if (pp == NULL || objsize == -1) { - return objsize; - } + CBB cbb, child; + if (!CBB_init(&cbb, (size_t)in->length + 2) || + !CBB_add_asn1(&cbb, &child, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&child, in->data, in->length)) { + CBB_cleanup(&cbb); + return -1; + } - unsigned char *p, *allocated = NULL; - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - } else { - p = *pp; - } - - ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); - OPENSSL_memcpy(p, a->data, a->length); - - /* - * If a new buffer was allocated, just return it back. - * If not, return the incremented buffer pointer. - */ - *pp = allocated != NULL ? allocated : p + a->length; - return objsize; + return CBB_finish_i2d(&cbb, outp); } -int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) -{ - return OBJ_obj2txt(buf, buf_len, a, 0); +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) { + return OBJ_obj2txt(buf, buf_len, a, 0); } -static int write_str(BIO *bp, const char *str) -{ - int len = strlen(str); - return BIO_write(bp, str, len) == len ? len : -1; +static int write_str(BIO *bp, const char *str) { + size_t len = strlen(str); + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return -1; + } + return BIO_write(bp, str, (int)len) == (int)len ? (int)len : -1; } -int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) -{ - if (a == NULL || a->data == NULL) { - return write_str(bp, "NULL"); - } +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) { + if (a == NULL || a->data == NULL) { + return write_str(bp, "NULL"); + } - char buf[80], *allocated = NULL; - const char *str = buf; - int len = i2t_ASN1_OBJECT(buf, sizeof(buf), a); - if (len > (int)sizeof(buf) - 1) { - /* The input was truncated. Allocate a buffer that fits. */ - allocated = OPENSSL_malloc(len + 1); - if (allocated == NULL) { - return -1; - } - len = i2t_ASN1_OBJECT(allocated, len + 1, a); - str = allocated; - } - if (len <= 0) { - str = ""; + char buf[80], *allocated = NULL; + const char *str = buf; + int len = i2t_ASN1_OBJECT(buf, sizeof(buf), a); + if (len > (int)sizeof(buf) - 1) { + // The input was truncated. Allocate a buffer that fits. + allocated = OPENSSL_malloc(len + 1); + if (allocated == NULL) { + return -1; } + len = i2t_ASN1_OBJECT(allocated, len + 1, a); + str = allocated; + } + if (len <= 0) { + str = ""; + } - int ret = write_str(bp, str); - OPENSSL_free(allocated); - return ret; + int ret = write_str(bp, str); + OPENSSL_free(allocated); + return ret; } -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length) -{ - long len; - int tag, xclass; - const unsigned char *p = *pp; - int inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); - return NULL; - } +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, + long len) { + if (len < 0) { + return NULL; + } - if (inf & V_ASN1_CONSTRUCTED) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return NULL; - } + CBS cbs, child; + CBS_init(&cbs, *inp, (size_t)len); + if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return NULL; + } - if (tag != V_ASN1_OBJECT || xclass != V_ASN1_UNIVERSAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_AN_OBJECT); - return NULL; - } - ASN1_OBJECT *ret = c2i_ASN1_OBJECT(a, &p, len); - if (ret) { - *pp = p; - } - return ret; + const uint8_t *contents = CBS_data(&child); + ASN1_OBJECT *ret = c2i_ASN1_OBJECT(out, &contents, CBS_len(&child)); + if (ret != NULL) { + // |c2i_ASN1_OBJECT| should have consumed the entire input. + assert(CBS_data(&cbs) == contents); + *inp = CBS_data(&cbs); + } + return ret; } -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long len) -{ - ASN1_OBJECT *ret = NULL; - const unsigned char *p; - unsigned char *data; - int i, length; +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } - /* - * Sanity check OID encoding. Need at least one content octet. MSB must - * be clear in the last octet. can't have leading 0x80 in subidentifiers, - * see: X.690 8.19.2 - */ - if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || - p[len - 1] & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - /* Now 0 < len <= INT_MAX, so the cast is safe. */ - length = (int)len; - for (i = 0; i < length; i++, p++) { - if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + if (!CBS_is_valid_asn1_oid(&cbs)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } - if ((a == NULL) || ((*a) == NULL) || - !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { - if ((ret = ASN1_OBJECT_new()) == NULL) - return (NULL); - } else { - ret = (*a); - } + ASN1_OBJECT *ret = ASN1_OBJECT_create(NID_undef, *inp, (size_t)len, + /*sn=*/NULL, /*ln=*/NULL); + if (ret == NULL) { + return NULL; + } - p = *pp; - /* detach data from object */ - data = (unsigned char *)ret->data; - ret->data = NULL; - /* once detached we can change it */ - if ((data == NULL) || (ret->length < length)) { - ret->length = 0; - if (data != NULL) - OPENSSL_free(data); - data = (unsigned char *)OPENSSL_malloc(length); - if (data == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; - } - OPENSSL_memcpy(data, p, length); - /* If there are dynamic strings, free them here, and clear the flag */ - if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) { - OPENSSL_free((char *)ret->sn); - OPENSSL_free((char *)ret->ln); - ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS; - } - /* reattach data to object, after which it remains const */ - ret->data = data; - ret->length = length; - ret->sn = NULL; - ret->ln = NULL; - p += length; - - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - OPENSSL_PUT_ERROR(ASN1, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_OBJECT_free(ret); - return (NULL); + if (out != NULL) { + ASN1_OBJECT_free(*out); + *out = ret; + } + *inp += len; // All bytes were consumed. + return ret; } -ASN1_OBJECT *ASN1_OBJECT_new(void) -{ - ASN1_OBJECT *ret; +ASN1_OBJECT *ASN1_OBJECT_new(void) { + ASN1_OBJECT *ret; - ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); - if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->length = 0; - ret->data = NULL; - ret->nid = 0; - ret->sn = NULL; - ret->ln = NULL; - ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; - return (ret); + ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); + if (ret == NULL) { + return NULL; + } + ret->length = 0; + ret->data = NULL; + ret->nid = 0; + ret->sn = NULL; + ret->ln = NULL; + ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; + return ret; } -void ASN1_OBJECT_free(ASN1_OBJECT *a) -{ - if (a == NULL) - return; - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { - OPENSSL_free((void *)a->sn); - OPENSSL_free((void *)a->ln); - a->sn = a->ln = NULL; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - OPENSSL_free((void *)a->data); - a->data = NULL; - a->length = 0; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) - OPENSSL_free(a); +void ASN1_OBJECT_free(ASN1_OBJECT *a) { + if (a == NULL) { + return; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { + OPENSSL_free((void *)a->sn); + OPENSSL_free((void *)a->ln); + a->sn = a->ln = NULL; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { + OPENSSL_free((void *)a->data); + a->data = NULL; + a->length = 0; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) { + OPENSSL_free(a); + } } -ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, int len, - const char *sn, const char *ln) -{ - ASN1_OBJECT o; +ASN1_OBJECT *ASN1_OBJECT_create(int nid, const unsigned char *data, size_t len, + const char *sn, const char *ln) { + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); + return NULL; + } - o.sn = sn; - o.ln = ln; - o.data = data; - o.nid = nid; - o.length = len; - o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA; - return (OBJ_dup(&o)); + ASN1_OBJECT o; + o.sn = sn; + o.ln = ln; + o.data = data; + o.nid = nid; + o.length = (int)len; + o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; + return OBJ_dup(&o); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_octet.c b/third_party/boringssl/kit/src/crypto/asn1/a_octet.c index 312993b9..f9c33791 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_octet.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_octet.c @@ -59,19 +59,16 @@ #include #include -ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) -{ - return ASN1_STRING_dup(x); +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) { + return ASN1_STRING_dup(x); } int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, - const ASN1_OCTET_STRING *b) -{ - return ASN1_STRING_cmp(a, b); + const ASN1_OCTET_STRING *b) { + return ASN1_STRING_cmp(a, b); } int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, - int len) -{ - return ASN1_STRING_set(x, d, len); + int len) { + return ASN1_STRING_set(x, d, len); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_strex.c b/third_party/boringssl/kit/src/crypto/asn1/a_strex.c index 7829d671..f21d1465 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_strex.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_strex.c @@ -56,595 +56,415 @@ #include +#include #include #include +#include #include +#include #include +#include #include -#include "charmap.h" +#include "../bytestring/internal.h" #include "internal.h" -// These flags must be distinct from |ESC_FLAGS| and fit in a byte. +#define ESC_FLAGS \ + (ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_QUOTE | ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) -// Character is a valid PrintableString character -#define CHARTYPE_PRINTABLESTRING 0x10 -// Character needs escaping if it is the first character -#define CHARTYPE_FIRST_ESC_2253 0x20 -// Character needs escaping if it is the last character -#define CHARTYPE_LAST_ESC_2253 0x40 - -#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) - -#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB) - -static int maybe_write(BIO *out, const void *buf, int len) -{ - /* If |out| is NULL, ignore the output but report the length. */ - return out == NULL || BIO_write(out, buf, len) == len; +static int maybe_write(BIO *out, const void *buf, int len) { + // If |out| is NULL, ignore the output but report the length. + return out == NULL || BIO_write(out, buf, len) == len; } -/* - * This function handles display of strings, one character at a time. It is - * passed an unsigned long for each character because it could come from 2 or - * even 4 byte forms. - */ +static int is_control_character(unsigned char c) { return c < 32 || c == 127; } -#define HEX_SIZE(type) (sizeof(type)*2) - -static int do_esc_char(uint32_t c, unsigned char flags, char *do_quotes, - BIO *out) -{ - unsigned char chflgs, chtmp; - char tmphex[HEX_SIZE(uint32_t) + 3]; - - if (c > 0xffff) { - BIO_snprintf(tmphex, sizeof tmphex, "\\W%08" PRIX32, c); - if (!maybe_write(out, tmphex, 10)) - return -1; - return 10; - } - if (c > 0xff) { - BIO_snprintf(tmphex, sizeof tmphex, "\\U%04" PRIX32, c); - if (!maybe_write(out, tmphex, 6)) - return -1; - return 6; - } - chtmp = (unsigned char)c; - if (chtmp > 0x7f) - chflgs = flags & ASN1_STRFLGS_ESC_MSB; - else - chflgs = char_type[chtmp] & flags; - if (chflgs & CHARTYPE_BS_ESC) { - /* If we don't escape with quotes, signal we need quotes */ - if (chflgs & ASN1_STRFLGS_ESC_QUOTE) { - if (do_quotes) - *do_quotes = 1; - if (!maybe_write(out, &chtmp, 1)) - return -1; - return 1; +static int do_esc_char(uint32_t c, unsigned long flags, char *do_quotes, + BIO *out, int is_first, int is_last) { + // |c| is a |uint32_t| because, depending on |ASN1_STRFLGS_UTF8_CONVERT|, + // we may be escaping bytes or Unicode codepoints. + char buf[16]; // Large enough for "\\W01234567". + unsigned char u8 = (unsigned char)c; + if (c > 0xffff) { + BIO_snprintf(buf, sizeof(buf), "\\W%08" PRIX32, c); + } else if (c > 0xff) { + BIO_snprintf(buf, sizeof(buf), "\\U%04" PRIX32, c); + } else if ((flags & ASN1_STRFLGS_ESC_MSB) && c > 0x7f) { + BIO_snprintf(buf, sizeof(buf), "\\%02X", c); + } else if ((flags & ASN1_STRFLGS_ESC_CTRL) && is_control_character(c)) { + BIO_snprintf(buf, sizeof(buf), "\\%02X", c); + } else if (flags & ASN1_STRFLGS_ESC_2253) { + // See RFC 2253, sections 2.4 and 4. + if (c == '\\' || c == '"') { + // Quotes and backslashes are always escaped, quoted or not. + BIO_snprintf(buf, sizeof(buf), "\\%c", (int)c); + } else if (c == ',' || c == '+' || c == '<' || c == '>' || c == ';' || + (is_first && (c == ' ' || c == '#')) || + (is_last && (c == ' '))) { + if (flags & ASN1_STRFLGS_ESC_QUOTE) { + // No need to escape, just tell the caller to quote. + if (do_quotes != NULL) { + *do_quotes = 1; } - if (!maybe_write(out, "\\", 1)) - return -1; - if (!maybe_write(out, &chtmp, 1)) - return -1; - return 2; + return maybe_write(out, &u8, 1) ? 1 : -1; + } + BIO_snprintf(buf, sizeof(buf), "\\%c", (int)c); + } else { + return maybe_write(out, &u8, 1) ? 1 : -1; } - if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) { - BIO_snprintf(tmphex, 11, "\\%02X", chtmp); - if (!maybe_write(out, tmphex, 3)) - return -1; - return 3; - } - /* - * If we get this far and do any escaping at all must escape the escape - * character itself: backslash. - */ - if (chtmp == '\\' && flags & ESC_FLAGS) { - if (!maybe_write(out, "\\\\", 2)) - return -1; - return 2; - } - if (!maybe_write(out, &chtmp, 1)) - return -1; - return 1; + } else if ((flags & ESC_FLAGS) && c == '\\') { + // If any escape flags are set, also escape backslashes. + BIO_snprintf(buf, sizeof(buf), "\\%c", (int)c); + } else { + return maybe_write(out, &u8, 1) ? 1 : -1; + } + + static_assert(sizeof(buf) < INT_MAX, "len may not fit in int"); + int len = (int)strlen(buf); + return maybe_write(out, buf, len) ? len : -1; } -#define BUF_TYPE_WIDTH_MASK 0x7 -#define BUF_TYPE_CONVUTF8 0x8 +// This function sends each character in a buffer to do_esc_char(). It +// interprets the content formats and converts to or from UTF8 as +// appropriate. -/* - * This function sends each character in a buffer to do_esc_char(). It - * interprets the content formats and converts to or from UTF8 as - * appropriate. - */ +static int do_buf(const unsigned char *buf, int buflen, int encoding, + unsigned long flags, char *quotes, BIO *out) { + int (*get_char)(CBS *cbs, uint32_t *out); + int get_char_error; + switch (encoding) { + case MBSTRING_UNIV: + get_char = cbs_get_utf32_be; + get_char_error = ASN1_R_INVALID_UNIVERSALSTRING; + break; + case MBSTRING_BMP: + get_char = cbs_get_ucs2_be; + get_char_error = ASN1_R_INVALID_BMPSTRING; + break; + case MBSTRING_ASC: + get_char = cbs_get_latin1; + get_char_error = ERR_R_INTERNAL_ERROR; // Should not be possible. + break; + case MBSTRING_UTF8: + get_char = cbs_get_utf8; + get_char_error = ASN1_R_INVALID_UTF8STRING; + break; + default: + assert(0); + return -1; + } -static int do_buf(unsigned char *buf, int buflen, - int type, unsigned char flags, char *quotes, BIO *out) -{ - int i, outlen, len, charwidth; - unsigned char orflags, *p, *q; + CBS cbs; + CBS_init(&cbs, buf, buflen); + int outlen = 0; + while (CBS_len(&cbs) != 0) { + const int is_first = CBS_data(&cbs) == buf; uint32_t c; + if (!get_char(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, get_char_error); + return -1; + } + const int is_last = CBS_len(&cbs) == 0; + if (flags & ASN1_STRFLGS_UTF8_CONVERT) { + uint8_t utf8_buf[6]; + CBB utf8_cbb; + CBB_init_fixed(&utf8_cbb, utf8_buf, sizeof(utf8_buf)); + if (!cbb_add_utf8(&utf8_cbb, c)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return 1; + } + size_t utf8_len = CBB_len(&utf8_cbb); + for (size_t i = 0; i < utf8_len; i++) { + int len = do_esc_char(utf8_buf[i], flags, quotes, out, + is_first && i == 0, is_last && i == utf8_len - 1); + if (len < 0) { + return -1; + } + outlen += len; + } + } else { + int len = do_esc_char(c, flags, quotes, out, is_first, is_last); + if (len < 0) { + return -1; + } + outlen += len; + } + } + return outlen; +} + +// This function hex dumps a buffer of characters + +static int do_hex_dump(BIO *out, unsigned char *buf, int buflen) { + static const char hexdig[] = "0123456789ABCDEF"; + unsigned char *p, *q; + char hextmp[2]; + if (out) { p = buf; q = buf + buflen; - outlen = 0; - charwidth = type & BUF_TYPE_WIDTH_MASK; - - switch (charwidth) { - case 4: - if (buflen & 3) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); - return -1; - } - break; - case 2: - if (buflen & 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); - return -1; - } - break; - default: - break; - } - while (p != q) { - if (p == buf && flags & ASN1_STRFLGS_ESC_2253) - orflags = CHARTYPE_FIRST_ESC_2253; - else - orflags = 0; - /* TODO(davidben): Replace this with |cbs_get_ucs2_be|, etc., to check - * for invalid codepoints. */ - switch (charwidth) { - case 4: - c = ((uint32_t)*p++) << 24; - c |= ((uint32_t)*p++) << 16; - c |= ((uint32_t)*p++) << 8; - c |= *p++; - break; - - case 2: - c = ((uint32_t)*p++) << 8; - c |= *p++; - break; - - case 1: - c = *p++; - break; - - case 0: - i = UTF8_getc(p, buflen, &c); - if (i < 0) - return -1; /* Invalid UTF8String */ - buflen -= i; - p += i; - break; - default: - return -1; /* invalid width */ - } - if (p == q && flags & ASN1_STRFLGS_ESC_2253) - orflags = CHARTYPE_LAST_ESC_2253; - if (type & BUF_TYPE_CONVUTF8) { - unsigned char utfbuf[6]; - int utflen; - utflen = UTF8_putc(utfbuf, sizeof utfbuf, c); - for (i = 0; i < utflen; i++) { - /* - * We don't need to worry about setting orflags correctly - * because if utflen==1 its value will be correct anyway - * otherwise each character will be > 0x7f and so the - * character will never be escaped on first and last. - */ - len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), - quotes, out); - if (len < 0) - return -1; - outlen += len; - } - } else { - len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, out); - if (len < 0) - return -1; - outlen += len; - } + hextmp[0] = hexdig[*p >> 4]; + hextmp[1] = hexdig[*p & 0xf]; + if (!maybe_write(out, hextmp, 2)) { + return -1; + } + p++; } - return outlen; + } + return buflen << 1; } -/* This function hex dumps a buffer of characters */ +// "dump" a string. This is done when the type is unknown, or the flags +// request it. We can either dump the content octets or the entire DER +// encoding. This uses the RFC 2253 #01234 format. -static int do_hex_dump(BIO *out, unsigned char *buf, int buflen) -{ - static const char hexdig[] = "0123456789ABCDEF"; - unsigned char *p, *q; - char hextmp[2]; - if (out) { - p = buf; - q = buf + buflen; - while (p != q) { - hextmp[0] = hexdig[*p >> 4]; - hextmp[1] = hexdig[*p & 0xf]; - if (!maybe_write(out, hextmp, 2)) - return -1; - p++; - } - } - return buflen << 1; -} +static int do_dump(unsigned long flags, BIO *out, const ASN1_STRING *str) { + if (!maybe_write(out, "#", 1)) { + return -1; + } -/* - * "dump" a string. This is done when the type is unknown, or the flags - * request it. We can either dump the content octets or the entire DER - * encoding. This uses the RFC 2253 #01234 format. - */ - -static int do_dump(unsigned long lflags, BIO *out, const ASN1_STRING *str) -{ - if (!maybe_write(out, "#", 1)) { - return -1; - } - - /* If we don't dump DER encoding just dump content octets */ - if (!(lflags & ASN1_STRFLGS_DUMP_DER)) { - int outlen = do_hex_dump(out, str->data, str->length); - if (outlen < 0) { - return -1; - } - return outlen + 1; - } - - /* - * Placing the ASN1_STRING in a temporary ASN1_TYPE allows the DER encoding - * to readily obtained. - */ - ASN1_TYPE t; - t.type = str->type; - /* Negative INTEGER and ENUMERATED values are the only case where - * |ASN1_STRING| and |ASN1_TYPE| types do not match. - * - * TODO(davidben): There are also some type fields which, in |ASN1_TYPE|, do - * not correspond to |ASN1_STRING|. It is unclear whether those are allowed - * in |ASN1_STRING| at all, or what the space of allowed types is. - * |ASN1_item_ex_d2i| will never produce such a value so, for now, we say - * this is an invalid input. But this corner of the library in general - * should be more robust. */ - if (t.type == V_ASN1_NEG_INTEGER) { - t.type = V_ASN1_INTEGER; - } else if (t.type == V_ASN1_NEG_ENUMERATED) { - t.type = V_ASN1_ENUMERATED; - } - t.value.asn1_string = (ASN1_STRING *)str; - unsigned char *der_buf = NULL; - int der_len = i2d_ASN1_TYPE(&t, &der_buf); - if (der_len < 0) { - return -1; - } - int outlen = do_hex_dump(out, der_buf, der_len); - OPENSSL_free(der_buf); + // If we don't dump DER encoding just dump content octets + if (!(flags & ASN1_STRFLGS_DUMP_DER)) { + int outlen = do_hex_dump(out, str->data, str->length); if (outlen < 0) { - return -1; + return -1; } return outlen + 1; + } + + // Placing the ASN1_STRING in a temporary ASN1_TYPE allows the DER encoding + // to readily obtained. + ASN1_TYPE t; + t.type = str->type; + // Negative INTEGER and ENUMERATED values are the only case where + // |ASN1_STRING| and |ASN1_TYPE| types do not match. + // + // TODO(davidben): There are also some type fields which, in |ASN1_TYPE|, do + // not correspond to |ASN1_STRING|. It is unclear whether those are allowed + // in |ASN1_STRING| at all, or what the space of allowed types is. + // |ASN1_item_ex_d2i| will never produce such a value so, for now, we say + // this is an invalid input. But this corner of the library in general + // should be more robust. + if (t.type == V_ASN1_NEG_INTEGER) { + t.type = V_ASN1_INTEGER; + } else if (t.type == V_ASN1_NEG_ENUMERATED) { + t.type = V_ASN1_ENUMERATED; + } + t.value.asn1_string = (ASN1_STRING *)str; + unsigned char *der_buf = NULL; + int der_len = i2d_ASN1_TYPE(&t, &der_buf); + if (der_len < 0) { + return -1; + } + int outlen = do_hex_dump(out, der_buf, der_len); + OPENSSL_free(der_buf); + if (outlen < 0) { + return -1; + } + return outlen + 1; } -/* - * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is - * used for non string types otherwise it is the number of bytes per - * character - */ +// string_type_to_encoding returns the |MBSTRING_*| constant for the encoding +// used by the |ASN1_STRING| type |type|, or -1 if |tag| is not a string +// type. +static int string_type_to_encoding(int type) { + // This function is sometimes passed ASN.1 universal types and sometimes + // passed |ASN1_STRING| type values + switch (type) { + case V_ASN1_UTF8STRING: + return MBSTRING_UTF8; + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_ISO64STRING: + // |MBSTRING_ASC| refers to Latin-1, not ASCII. + return MBSTRING_ASC; + case V_ASN1_UNIVERSALSTRING: + return MBSTRING_UNIV; + case V_ASN1_BMPSTRING: + return MBSTRING_BMP; + } + return -1; +} -static const signed char tag2nbyte[] = { - -1, -1, -1, -1, -1, /* 0-4 */ - -1, -1, -1, -1, -1, /* 5-9 */ - -1, -1, 0, -1, /* 10-13 */ - -1, -1, -1, -1, /* 15-17 */ - 1, 1, 1, /* 18-20 */ - -1, 1, 1, 1, /* 21-24 */ - -1, 1, -1, /* 25-27 */ - 4, -1, 2 /* 28-30 */ -}; +// This is the main function, print out an ASN1_STRING taking note of various +// escape and display options. Returns number of characters written or -1 if +// an error occurred. -/* - * This is the main function, print out an ASN1_STRING taking note of various - * escape and display options. Returns number of characters written or -1 if - * an error occurred. - */ - -int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long lflags) -{ - int outlen, len; - int type; - char quotes; - unsigned char flags; - quotes = 0; - /* Keep a copy of escape flags */ - flags = (unsigned char)(lflags & ESC_FLAGS); - - type = str->type; - - outlen = 0; - - if (lflags & ASN1_STRFLGS_SHOW_TYPE) { - const char *tagname; - tagname = ASN1_tag2str(type); - outlen += strlen(tagname); - if (!maybe_write(out, tagname, outlen) || !maybe_write(out, ":", 1)) - return -1; - outlen++; +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, + unsigned long flags) { + int type = str->type; + int outlen = 0; + if (flags & ASN1_STRFLGS_SHOW_TYPE) { + const char *tagname = ASN1_tag2str(type); + outlen += strlen(tagname); + if (!maybe_write(out, tagname, outlen) || !maybe_write(out, ":", 1)) { + return -1; } + outlen++; + } - /* Decide what to do with type, either dump content or display it */ - - /* Dump everything */ - if (lflags & ASN1_STRFLGS_DUMP_ALL) - type = -1; - /* Ignore the string type */ - else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) - type = 1; - else { - /* Else determine width based on type */ - if ((type > 0) && (type < 31)) - type = tag2nbyte[type]; - else - type = -1; - if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) - type = 1; + // Decide what to do with |str|, either dump the contents or display it. + int encoding; + if (flags & ASN1_STRFLGS_DUMP_ALL) { + // Dump everything. + encoding = -1; + } else if (flags & ASN1_STRFLGS_IGNORE_TYPE) { + // Ignore the string type and interpret the contents as Latin-1. + encoding = MBSTRING_ASC; + } else { + encoding = string_type_to_encoding(type); + if (encoding == -1 && (flags & ASN1_STRFLGS_DUMP_UNKNOWN) == 0) { + encoding = MBSTRING_ASC; } + } - if (type == -1) { - len = do_dump(lflags, out, str); - if (len < 0) - return -1; - outlen += len; - return outlen; + if (encoding == -1) { + int len = do_dump(flags, out, str); + if (len < 0) { + return -1; } - - if (lflags & ASN1_STRFLGS_UTF8_CONVERT) { - /* - * Note: if string is UTF8 and we want to convert to UTF8 then we - * just interpret it as 1 byte per character to avoid converting - * twice. - */ - if (!type) - type = 1; - else - type |= BUF_TYPE_CONVUTF8; - } - - len = do_buf(str->data, str->length, type, flags, "es, NULL); - if (len < 0) - return -1; outlen += len; - if (quotes) - outlen += 2; - if (!out) - return outlen; - if (quotes && !maybe_write(out, "\"", 1)) - return -1; - if (do_buf(str->data, str->length, type, flags, NULL, out) < 0) - return -1; - if (quotes && !maybe_write(out, "\"", 1)) - return -1; return outlen; + } + + // Measure the length. + char quotes = 0; + int len = do_buf(str->data, str->length, encoding, flags, "es, NULL); + if (len < 0) { + return -1; + } + outlen += len; + if (quotes) { + outlen += 2; + } + if (!out) { + return outlen; + } + + // Encode the value. + if ((quotes && !maybe_write(out, "\"", 1)) || + do_buf(str->data, str->length, encoding, flags, NULL, out) < 0 || + (quotes && !maybe_write(out, "\"", 1))) { + return -1; + } + return outlen; } int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, - unsigned long flags) -{ - BIO *bio = NULL; - if (fp != NULL) { - /* If |fp| is NULL, this function returns the number of bytes without - * writing. */ - bio = BIO_new_fp(fp, BIO_NOCLOSE); - if (bio == NULL) { - return -1; - } + unsigned long flags) { + BIO *bio = NULL; + if (fp != NULL) { + // If |fp| is NULL, this function returns the number of bytes without + // writing. + bio = BIO_new_fp(fp, BIO_NOCLOSE); + if (bio == NULL) { + return -1; } - int ret = ASN1_STRING_print_ex(bio, str, flags); - BIO_free(bio); + } + int ret = ASN1_STRING_print_ex(bio, str, flags); + BIO_free(bio); + return ret; +} + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in) { + if (!in) { + return -1; + } + int mbflag = string_type_to_encoding(in->type); + if (mbflag == -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); + return -1; + } + ASN1_STRING stmp, *str = &stmp; + stmp.data = NULL; + stmp.length = 0; + stmp.flags = 0; + int ret = + ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); + if (ret < 0) { return ret; + } + *out = stmp.data; + return stmp.length; } -int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in) -{ - ASN1_STRING stmp, *str = &stmp; - int mbflag, type, ret; - if (!in) - return -1; - type = in->type; - if ((type < 0) || (type > 30)) - return -1; - mbflag = tag2nbyte[type]; - if (mbflag == -1) - return -1; - mbflag |= MBSTRING_FLAG; - stmp.data = NULL; - stmp.length = 0; - stmp.flags = 0; - ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, - B_ASN1_UTF8STRING); - if (ret < 0) - return ret; - *out = stmp.data; - return stmp.length; -} +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) { + int i, n; + char buf[80]; + const char *p; -int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) -{ - int i, n; - char buf[80]; - const char *p; - - if (v == NULL) - return (0); - n = 0; - p = (const char *)v->data; - for (i = 0; i < v->length; i++) { - if ((p[i] > '~') || ((p[i] < ' ') && - (p[i] != '\n') && (p[i] != '\r'))) - buf[n] = '.'; - else - buf[n] = p[i]; - n++; - if (n >= 80) { - if (BIO_write(bp, buf, n) <= 0) - return (0); - n = 0; - } - } - if (n > 0) - if (BIO_write(bp, buf, n) <= 0) - return (0); - return (1); -} - -int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) -{ - if (tm->type == V_ASN1_UTCTIME) - return ASN1_UTCTIME_print(bp, tm); - if (tm->type == V_ASN1_GENERALIZEDTIME) - return ASN1_GENERALIZEDTIME_print(bp, tm); - BIO_write(bp, "Bad time value", 14); - return (0); -} - -static const char *const mon[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) -{ - char *v; - int gmt = 0; - int i; - int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; - char *f = NULL; - int f_len = 0; - - i = tm->length; - v = (char *)tm->data; - - if (i < 12) - goto err; - if (v[i - 1] == 'Z') - gmt = 1; - for (i = 0; i < 12; i++) - if ((v[i] > '9') || (v[i] < '0')) - goto err; - y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] - - '0'); - M = (v[4] - '0') * 10 + (v[5] - '0'); - if ((M > 12) || (M < 1)) - goto err; - d = (v[6] - '0') * 10 + (v[7] - '0'); - h = (v[8] - '0') * 10 + (v[9] - '0'); - m = (v[10] - '0') * 10 + (v[11] - '0'); - if (tm->length >= 14 && - (v[12] >= '0') && (v[12] <= '9') && - (v[13] >= '0') && (v[13] <= '9')) { - s = (v[12] - '0') * 10 + (v[13] - '0'); - /* Check for fractions of seconds. */ - if (tm->length >= 15 && v[14] == '.') { - int l = tm->length; - f = &v[14]; /* The decimal point. */ - f_len = 1; - while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') - ++f_len; - } - } - - if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", - mon[M - 1], d, h, m, s, f_len, f, y, - (gmt) ? " GMT" : "") <= 0) - return (0); - else - return (1); - err: - BIO_write(bp, "Bad time value", 14); - return (0); -} - -// consume_two_digits is a helper function for ASN1_UTCTIME_print. If |*v|, -// assumed to be |*len| bytes long, has two leading digits, updates |*out| with -// their value, updates |v| and |len|, and returns one. Otherwise, returns -// zero. -static int consume_two_digits(int* out, const char **v, int *len) { - if (*len < 2|| !isdigit((*v)[0]) || !isdigit((*v)[1])) { + if (v == NULL) { return 0; } - *out = ((*v)[0] - '0') * 10 + ((*v)[1] - '0'); - *len -= 2; - *v += 2; + n = 0; + p = (const char *)v->data; + for (i = 0; i < v->length; i++) { + if ((p[i] > '~') || ((p[i] < ' ') && (p[i] != '\n') && (p[i] != '\r'))) { + buf[n] = '.'; + } else { + buf[n] = p[i]; + } + n++; + if (n >= 80) { + if (BIO_write(bp, buf, n) <= 0) { + return 0; + } + n = 0; + } + } + if (n > 0) { + if (BIO_write(bp, buf, n) <= 0) { + return 0; + } + } return 1; } -// consume_zulu_timezone is a helper function for ASN1_UTCTIME_print. If |*v|, -// assumed to be |*len| bytes long, starts with "Z" then it updates |*v| and -// |*len| and returns one. Otherwise returns zero. -static int consume_zulu_timezone(const char **v, int *len) { - if (*len == 0 || (*v)[0] != 'Z') { +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) { + if (tm->type == V_ASN1_UTCTIME) { + return ASN1_UTCTIME_print(bp, tm); + } + if (tm->type == V_ASN1_GENERALIZEDTIME) { + return ASN1_GENERALIZEDTIME_print(bp, tm); + } + BIO_puts(bp, "Bad time value"); + return 0; +} + +static const char *const mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) { + CBS cbs; + CBS_init(&cbs, tm->data, tm->length); + struct tm utc; + if (!CBS_parse_generalized_time(&cbs, &utc, /*allow_timezone_offset=*/0)) { + BIO_puts(bp, "Bad time value"); return 0; } - *len -= 1; - *v += 1; - return 1; + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d GMT", mon[utc.tm_mon], + utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec, + utc.tm_year + 1900) > 0; } int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) { - const char *v = (const char *)tm->data; - int len = tm->length; - int Y = 0, M = 0, D = 0, h = 0, m = 0, s = 0; - - // YYMMDDhhmm are required to be present. - if (!consume_two_digits(&Y, &v, &len) || - !consume_two_digits(&M, &v, &len) || - !consume_two_digits(&D, &v, &len) || - !consume_two_digits(&h, &v, &len) || - !consume_two_digits(&m, &v, &len)) { - goto err; - } - // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires seconds - // to be present, but historically this code has forgiven its absence. - consume_two_digits(&s, &v, &len); - - // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, specifies this - // interpretation of the year. - if (Y < 50) { - Y += 2000; - } else { - Y += 1900; - } - if (M > 12 || M == 0) { - goto err; - } - if (D > 31 || D == 0) { - goto err; - } - if (h > 23 || m > 59 || s > 60) { - goto err; + CBS cbs; + CBS_init(&cbs, tm->data, tm->length); + struct tm utc; + if (!CBS_parse_utc_time(&cbs, &utc, /*allow_timezone_offset=*/0)) { + BIO_puts(bp, "Bad time value"); + return 0; } - // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires the "Z" - // to be present, but historically this code has forgiven its absence. - const int is_gmt = consume_zulu_timezone(&v, &len); - - // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, does not permit - // the specification of timezones using the +hhmm / -hhmm syntax, which is - // the only other thing that might legitimately be found at the end. - if (len) { - goto err; - } - - return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", mon[M - 1], D, h, m, s, Y, - is_gmt ? " GMT" : "") > 0; - -err: - BIO_write(bp, "Bad time value", 14); - return 0; + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d GMT", mon[utc.tm_mon], + utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec, + utc.tm_year + 1900) > 0; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_strnid.c b/third_party/boringssl/kit/src/crypto/asn1/a_strnid.c index bc9226a3..db25b2a6 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_strnid.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_strnid.c @@ -72,70 +72,57 @@ DEFINE_LHASH_OF(ASN1_STRING_TABLE) static LHASH_OF(ASN1_STRING_TABLE) *string_tables = NULL; -static struct CRYPTO_STATIC_MUTEX string_tables_lock = CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX string_tables_lock = CRYPTO_MUTEX_INIT; -void ASN1_STRING_set_default_mask(unsigned long mask) -{ -} +void ASN1_STRING_set_default_mask(unsigned long mask) {} -unsigned long ASN1_STRING_get_default_mask(void) -{ - return B_ASN1_UTF8STRING; -} +unsigned long ASN1_STRING_get_default_mask(void) { return B_ASN1_UTF8STRING; } -int ASN1_STRING_set_default_mask_asc(const char *p) -{ - return 1; -} +int ASN1_STRING_set_default_mask_asc(const char *p) { return 1; } static const ASN1_STRING_TABLE *asn1_string_table_get(int nid); -/* - * The following function generates an ASN1_STRING based on limits in a - * table. Frequently the types and length of an ASN1_STRING are restricted by - * a corresponding OID. For example certificates and certificate requests. - */ +// The following function generates an ASN1_STRING based on limits in a +// table. Frequently the types and length of an ASN1_STRING are restricted by +// a corresponding OID. For example certificates and certificate requests. ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, - int len, int inform, int nid) -{ - ASN1_STRING *str = NULL; - int ret; - if (!out) { - out = &str; + ossl_ssize_t len, int inform, int nid) { + ASN1_STRING *str = NULL; + int ret; + if (!out) { + out = &str; + } + const ASN1_STRING_TABLE *tbl = asn1_string_table_get(nid); + if (tbl != NULL) { + unsigned long mask = tbl->mask; + if (!(tbl->flags & STABLE_NO_MASK)) { + mask &= B_ASN1_UTF8STRING; } - const ASN1_STRING_TABLE *tbl = asn1_string_table_get(nid); - if (tbl != NULL) { - unsigned long mask = tbl->mask; - if (!(tbl->flags & STABLE_NO_MASK)) { - mask &= B_ASN1_UTF8STRING; - } - ret = ASN1_mbstring_ncopy(out, in, len, inform, mask, tbl->minsize, - tbl->maxsize); - } else { - ret = ASN1_mbstring_copy(out, in, len, inform, B_ASN1_UTF8STRING); - } - if (ret <= 0) { - return NULL; - } - return *out; + ret = ASN1_mbstring_ncopy(out, in, len, inform, mask, tbl->minsize, + tbl->maxsize); + } else { + ret = ASN1_mbstring_copy(out, in, len, inform, B_ASN1_UTF8STRING); + } + if (ret <= 0) { + return NULL; + } + return *out; } -/* - * Now the tables and helper functions for the string table: - */ +// Now the tables and helper functions for the string table: -/* See RFC 5280. */ -#define ub_name 32768 -#define ub_common_name 64 -#define ub_locality_name 128 -#define ub_state_name 128 -#define ub_organization_name 64 -#define ub_organization_unit_name 64 -#define ub_email_address 128 -#define ub_serial_number 64 +// See RFC 5280. +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_email_address 128 +#define ub_serial_number 64 -/* This table must be kept in NID order */ +// This table must be kept in NID order static const ASN1_STRING_TABLE tbl_standard[] = { {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, @@ -159,108 +146,100 @@ static const ASN1_STRING_TABLE tbl_standard[] = { {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, - {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK} -}; + {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}}; -static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) -{ - if (a->nid < b->nid) { - return -1; - } - if (a->nid > b->nid) { - return 1; - } - return 0; +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) { + if (a->nid < b->nid) { + return -1; + } + if (a->nid > b->nid) { + return 1; + } + return 0; } -static int table_cmp_void(const void *a, const void *b) -{ - return table_cmp(a, b); +static int table_cmp_void(const void *a, const void *b) { + return table_cmp(a, b); } -static uint32_t table_hash(const ASN1_STRING_TABLE *tbl) -{ - return OPENSSL_hash32(&tbl->nid, sizeof(tbl->nid)); +static uint32_t table_hash(const ASN1_STRING_TABLE *tbl) { + return OPENSSL_hash32(&tbl->nid, sizeof(tbl->nid)); } -static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) -{ - ASN1_STRING_TABLE key; - key.nid = nid; - const ASN1_STRING_TABLE *tbl = - bsearch(&key, tbl_standard, OPENSSL_ARRAY_SIZE(tbl_standard), - sizeof(ASN1_STRING_TABLE), table_cmp_void); - if (tbl != NULL) { - return tbl; - } - - CRYPTO_STATIC_MUTEX_lock_read(&string_tables_lock); - if (string_tables != NULL) { - tbl = lh_ASN1_STRING_TABLE_retrieve(string_tables, &key); - } - CRYPTO_STATIC_MUTEX_unlock_read(&string_tables_lock); - /* Note returning |tbl| without the lock is only safe because - * |ASN1_STRING_TABLE_add| cannot modify or delete existing entries. If we - * wish to support that, this function must copy the result under a lock. */ +static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) { + ASN1_STRING_TABLE key; + key.nid = nid; + const ASN1_STRING_TABLE *tbl = + bsearch(&key, tbl_standard, OPENSSL_ARRAY_SIZE(tbl_standard), + sizeof(ASN1_STRING_TABLE), table_cmp_void); + if (tbl != NULL) { return tbl; + } + + CRYPTO_MUTEX_lock_read(&string_tables_lock); + if (string_tables != NULL) { + tbl = lh_ASN1_STRING_TABLE_retrieve(string_tables, &key); + } + CRYPTO_MUTEX_unlock_read(&string_tables_lock); + // Note returning |tbl| without the lock is only safe because + // |ASN1_STRING_TABLE_add| cannot modify or delete existing entries. If we + // wish to support that, this function must copy the result under a lock. + return tbl; } int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, - unsigned long mask, unsigned long flags) -{ - /* Existing entries cannot be overwritten. */ - if (asn1_string_table_get(nid) != NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } + unsigned long mask, unsigned long flags) { + // Existing entries cannot be overwritten. + if (asn1_string_table_get(nid) != NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } - int ret = 0; - CRYPTO_STATIC_MUTEX_lock_write(&string_tables_lock); + int ret = 0; + CRYPTO_MUTEX_lock_write(&string_tables_lock); + if (string_tables == NULL) { + string_tables = lh_ASN1_STRING_TABLE_new(table_hash, table_cmp); if (string_tables == NULL) { - string_tables = lh_ASN1_STRING_TABLE_new(table_hash, table_cmp); - if (string_tables == NULL) { - goto err; - } - } else { - /* Check again for an existing entry. One may have been added while - * unlocked. */ - ASN1_STRING_TABLE key; - key.nid = nid; - if (lh_ASN1_STRING_TABLE_retrieve(string_tables, &key) != NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - goto err; - } + goto err; } + } else { + // Check again for an existing entry. One may have been added while + // unlocked. + ASN1_STRING_TABLE key; + key.nid = nid; + if (lh_ASN1_STRING_TABLE_retrieve(string_tables, &key) != NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + goto err; + } + } - ASN1_STRING_TABLE *tbl = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); - if (tbl == NULL) { - goto err; - } - tbl->nid = nid; - tbl->flags = flags; - tbl->minsize = minsize; - tbl->maxsize = maxsize; - tbl->mask = mask; - ASN1_STRING_TABLE *old_tbl; - if (!lh_ASN1_STRING_TABLE_insert(string_tables, &old_tbl, tbl)) { - OPENSSL_free(tbl); - goto err; - } - assert(old_tbl == NULL); - ret = 1; + ASN1_STRING_TABLE *tbl = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (tbl == NULL) { + goto err; + } + tbl->nid = nid; + tbl->flags = flags; + tbl->minsize = minsize; + tbl->maxsize = maxsize; + tbl->mask = mask; + ASN1_STRING_TABLE *old_tbl; + if (!lh_ASN1_STRING_TABLE_insert(string_tables, &old_tbl, tbl)) { + OPENSSL_free(tbl); + goto err; + } + assert(old_tbl == NULL); + ret = 1; err: - CRYPTO_STATIC_MUTEX_unlock_write(&string_tables_lock); - return ret; + CRYPTO_MUTEX_unlock_write(&string_tables_lock); + return ret; } -void ASN1_STRING_TABLE_cleanup(void) -{ -} +void ASN1_STRING_TABLE_cleanup(void) {} void asn1_get_string_table_for_testing(const ASN1_STRING_TABLE **out_ptr, size_t *out_len) { - *out_ptr = tbl_standard; - *out_len = OPENSSL_ARRAY_SIZE(tbl_standard); + *out_ptr = tbl_standard; + *out_len = OPENSSL_ARRAY_SIZE(tbl_standard); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_time.c b/third_party/boringssl/kit/src/crypto/asn1/a_time.c index 1195569d..d8ec85f7 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_time.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_time.c @@ -55,158 +55,205 @@ * [including the GNU Public Licence.] */ #include +#include #include #include #include +#include #include #include #include "internal.h" -/* - * This is an implementation of the ASN1 Time structure which is: Time ::= - * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve - * Henson. - */ +// This is an implementation of the ASN1 Time structure which is: Time ::= +// CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve +// Henson. IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) IMPLEMENT_ASN1_FUNCTIONS_const(ASN1_TIME) -ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) -{ - return ASN1_TIME_adj(s, t, 0, 0); +ASN1_TIME *ASN1_TIME_set_posix(ASN1_TIME *s, int64_t posix_time) { + return ASN1_TIME_adj(s, posix_time, 0, 0); } -ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, - int offset_day, long offset_sec) -{ - struct tm *ts; - struct tm data; - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME); - return NULL; - } - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - return NULL; - } - if ((ts->tm_year >= 50) && (ts->tm_year < 150)) - return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); - return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t time) { + return ASN1_TIME_adj(s, time, 0, 0); } -int ASN1_TIME_check(const ASN1_TIME *t) -{ - if (t->type == V_ASN1_GENERALIZEDTIME) - return ASN1_GENERALIZEDTIME_check(t); - else if (t->type == V_ASN1_UTCTIME) - return ASN1_UTCTIME_check(t); - return 0; +static int fits_in_utc_time(const struct tm *tm) { + return 50 <= tm->tm_year && tm->tm_year < 150; } -/* Convert an ASN1_TIME structure to GeneralizedTime */ -ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, - ASN1_GENERALIZEDTIME **out) -{ - ASN1_GENERALIZEDTIME *ret = NULL; - char *str; - int newlen; +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day, + long offset_sec) { + struct tm tm; - if (!ASN1_TIME_check(t)) - return NULL; - - if (!out || !*out) { - if (!(ret = ASN1_GENERALIZEDTIME_new())) - goto err; - } else { - ret = *out; - } - - /* If already GeneralizedTime just copy across */ - if (t->type == V_ASN1_GENERALIZEDTIME) { - if (!ASN1_STRING_set(ret, t->data, t->length)) - goto err; - goto done; - } - - /* grow the string */ - if (!ASN1_STRING_set(ret, NULL, t->length + 2)) - goto err; - /* ASN1_STRING_set() allocated 'len + 1' bytes. */ - newlen = t->length + 2 + 1; - str = (char *)ret->data; - /* Work out the century and prepend */ - if (t->data[0] >= '5') - OPENSSL_strlcpy(str, "19", newlen); - else - OPENSSL_strlcpy(str, "20", newlen); - - OPENSSL_strlcat(str, (char *)t->data, newlen); - - done: - if (out != NULL && *out == NULL) - *out = ret; - return ret; - - err: - if (out == NULL || *out != ret) - ASN1_GENERALIZEDTIME_free(ret); + if (!OPENSSL_posix_to_tm(posix_time, &tm)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME); return NULL; + } + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec)) { + return NULL; + } + } + if (fits_in_utc_time(&tm)) { + return ASN1_UTCTIME_adj(s, posix_time, offset_day, offset_sec); + } + return ASN1_GENERALIZEDTIME_adj(s, posix_time, offset_day, offset_sec); } - -int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) -{ - ASN1_TIME t; - - t.length = strlen(str); - t.data = (unsigned char *)str; - t.flags = 0; - - t.type = V_ASN1_UTCTIME; - - if (!ASN1_TIME_check(&t)) { - t.type = V_ASN1_GENERALIZEDTIME; - if (!ASN1_TIME_check(&t)) - return 0; - } - - if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) - return 0; - - return 1; +int ASN1_TIME_check(const ASN1_TIME *t) { + if (t->type == V_ASN1_GENERALIZEDTIME) { + return ASN1_GENERALIZEDTIME_check(t); + } else if (t->type == V_ASN1_UTCTIME) { + return ASN1_UTCTIME_check(t); + } + return 0; } -static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t) -{ - if (t == NULL) { - time_t now_t; - time(&now_t); - if (OPENSSL_gmtime(&now_t, tm)) - return 1; - return 0; +// Convert an ASN1_TIME structure to GeneralizedTime +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out) { + ASN1_GENERALIZEDTIME *ret = NULL; + char *str; + int newlen; + + if (!ASN1_TIME_check(t)) { + return NULL; + } + + if (!out || !*out) { + if (!(ret = ASN1_GENERALIZEDTIME_new())) { + goto err; } + } else { + ret = *out; + } - if (t->type == V_ASN1_UTCTIME) - return asn1_utctime_to_tm(tm, t); - else if (t->type == V_ASN1_GENERALIZEDTIME) - return asn1_generalizedtime_to_tm(tm, t); + // If already GeneralizedTime just copy across + if (t->type == V_ASN1_GENERALIZEDTIME) { + if (!ASN1_STRING_set(ret, t->data, t->length)) { + goto err; + } + goto done; + } + // grow the string + if (!ASN1_STRING_set(ret, NULL, t->length + 2)) { + goto err; + } + // ASN1_STRING_set() allocated 'len + 1' bytes. + newlen = t->length + 2 + 1; + str = (char *)ret->data; + // Work out the century and prepend + if (t->data[0] >= '5') { + OPENSSL_strlcpy(str, "19", newlen); + } else { + OPENSSL_strlcpy(str, "20", newlen); + } + + OPENSSL_strlcat(str, (char *)t->data, newlen); + +done: + if (out != NULL && *out == NULL) { + *out = ret; + } + return ret; + +err: + if (out == NULL || *out != ret) { + ASN1_GENERALIZEDTIME_free(ret); + } + return NULL; +} + +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) { + return ASN1_UTCTIME_set_string(s, str) || + ASN1_GENERALIZEDTIME_set_string(s, str); +} + +int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str) { + CBS cbs; + CBS_init(&cbs, (const uint8_t*)str, strlen(str)); + int type; + struct tm tm; + if (CBS_parse_utc_time(&cbs, /*out_tm=*/NULL, + /*allow_timezone_offset=*/0)) { + type = V_ASN1_UTCTIME; + } else if (CBS_parse_generalized_time(&cbs, &tm, + /*allow_timezone_offset=*/0)) { + type = V_ASN1_GENERALIZEDTIME; + if (fits_in_utc_time(&tm)) { + type = V_ASN1_UTCTIME; + CBS_skip(&cbs, 2); + } + } else { return 0; + } + + if (s != NULL) { + if (!ASN1_STRING_set(s, CBS_data(&cbs), CBS_len(&cbs))) { + return 0; + } + s->type = type; + } + return 1; } -int ASN1_TIME_diff(int *out_days, int *out_seconds, - const ASN1_TIME *from, const ASN1_TIME *to) -{ - struct tm tm_from, tm_to; - if (!asn1_time_to_tm(&tm_from, from)) - return 0; - if (!asn1_time_to_tm(&tm_to, to)) - return 0; - return OPENSSL_gmtime_diff(out_days, out_seconds, &tm_from, &tm_to); +static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t, + int allow_timezone_offset) { + if (t == NULL) { + if (OPENSSL_posix_to_tm(time(NULL), tm)) { + return 1; + } + return 0; + } + + if (t->type == V_ASN1_UTCTIME) { + return asn1_utctime_to_tm(tm, t, allow_timezone_offset); + } else if (t->type == V_ASN1_GENERALIZEDTIME) { + return asn1_generalizedtime_to_tm(tm, t); + } + + return 0; +} + +int ASN1_TIME_diff(int *out_days, int *out_seconds, const ASN1_TIME *from, + const ASN1_TIME *to) { + struct tm tm_from, tm_to; + if (!asn1_time_to_tm(&tm_from, from, /*allow_timezone_offset=*/1)) { + return 0; + } + if (!asn1_time_to_tm(&tm_to, to, /*allow_timezone_offset=*/1)) { + return 0; + } + return OPENSSL_gmtime_diff(out_days, out_seconds, &tm_from, &tm_to); +} + +// The functions below do *not* permissively allow the use of four digit +// timezone offsets in UTC times, as is done elsewhere in the code. They are +// both new API, and used internally to X509_cmp_time. This is to discourage the +// use of nonstandard times in new code, and to ensure that this code behaves +// correctly in X509_cmp_time which historically did its own time validations +// slightly different than the many other copies of X.509 time validation +// sprinkled through the codebase. The custom checks in X509_cmp_time meant that +// it did not allow four digit timezone offsets in UTC times. +int ASN1_TIME_to_time_t(const ASN1_TIME *t, time_t *out_time) { + struct tm tm; + if (!asn1_time_to_tm(&tm, t, /*allow_timezone_offset=*/0)) { + return 0; + } + return OPENSSL_timegm(&tm, out_time); +} + +int ASN1_TIME_to_posix(const ASN1_TIME *t, int64_t *out_time) { + struct tm tm; + if (!asn1_time_to_tm(&tm, t, /*allow_timezone_offset=*/0)) { + return 0; + } + return OPENSSL_tm_to_posix(&tm, out_time); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_type.c b/third_party/boringssl/kit/src/crypto/asn1/a_type.c index c63030b9..0c2fd136 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_type.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_type.c @@ -64,76 +64,109 @@ #include "internal.h" -int ASN1_TYPE_get(const ASN1_TYPE *a) -{ - if (a->type == V_ASN1_BOOLEAN || a->type == V_ASN1_NULL || - a->value.ptr != NULL) { - return a->type; - } - return 0; -} - -const void *asn1_type_value_as_pointer(const ASN1_TYPE *a) -{ - if (a->type == V_ASN1_BOOLEAN) { - return a->value.boolean ? (void *)0xff : NULL; - } - if (a->type == V_ASN1_NULL) { - return NULL; - } - return a->value.ptr; -} - -void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) -{ - ASN1_TYPE **tmp_a = &a; - ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); - a->type = type; - if (type == V_ASN1_BOOLEAN) - a->value.boolean = value ? 0xff : 0; - else - a->value.ptr = value; -} - -int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) -{ - if (!value || (type == V_ASN1_BOOLEAN)) { - void *p = (void *)value; - ASN1_TYPE_set(a, type, p); - } else if (type == V_ASN1_OBJECT) { - ASN1_OBJECT *odup; - odup = OBJ_dup(value); - if (!odup) - return 0; - ASN1_TYPE_set(a, type, odup); - } else { - ASN1_STRING *sdup; - sdup = ASN1_STRING_dup(value); - if (!sdup) - return 0; - ASN1_TYPE_set(a, type, sdup); - } - return 1; -} - -/* Returns 0 if they are equal, != 0 otherwise. */ -int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) -{ - int result = -1; - - if (!a || !b || a->type != b->type) - return -1; - - switch (a->type) { - case V_ASN1_OBJECT: - result = OBJ_cmp(a->value.object, b->value.object); - break; +int ASN1_TYPE_get(const ASN1_TYPE *a) { + switch (a->type) { case V_ASN1_NULL: - result = 0; /* They do not have content. */ - break; case V_ASN1_BOOLEAN: - result = a->value.boolean - b->value.boolean; - break; + return a->type; + case V_ASN1_OBJECT: + return a->value.object != NULL ? a->type : 0; + default: + return a->value.asn1_string != NULL ? a->type : 0; + } +} + +const void *asn1_type_value_as_pointer(const ASN1_TYPE *a) { + switch (a->type) { + case V_ASN1_NULL: + return NULL; + case V_ASN1_BOOLEAN: + return a->value.boolean ? (void *)0xff : NULL; + case V_ASN1_OBJECT: + return a->value.object; + default: + return a->value.asn1_string; + } +} + +void asn1_type_cleanup(ASN1_TYPE *a) { + switch (a->type) { + case V_ASN1_NULL: + a->value.ptr = NULL; + break; + case V_ASN1_BOOLEAN: + a->value.boolean = ASN1_BOOLEAN_NONE; + break; + case V_ASN1_OBJECT: + ASN1_OBJECT_free(a->value.object); + a->value.object = NULL; + break; + default: + ASN1_STRING_free(a->value.asn1_string); + a->value.asn1_string = NULL; + break; + } +} + +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) { + asn1_type_cleanup(a); + a->type = type; + switch (type) { + case V_ASN1_NULL: + a->value.ptr = NULL; + break; + case V_ASN1_BOOLEAN: + a->value.boolean = value ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_FALSE; + break; + case V_ASN1_OBJECT: + a->value.object = value; + break; + default: + a->value.asn1_string = value; + break; + } +} + +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) { + if (!value || (type == V_ASN1_BOOLEAN)) { + void *p = (void *)value; + ASN1_TYPE_set(a, type, p); + } else if (type == V_ASN1_OBJECT) { + ASN1_OBJECT *odup; + odup = OBJ_dup(value); + if (!odup) { + return 0; + } + ASN1_TYPE_set(a, type, odup); + } else { + ASN1_STRING *sdup; + sdup = ASN1_STRING_dup(value); + if (!sdup) { + return 0; + } + ASN1_TYPE_set(a, type, sdup); + } + return 1; +} + +// Returns 0 if they are equal, != 0 otherwise. +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) { + int result = -1; + + if (!a || !b || a->type != b->type) { + return -1; + } + + switch (a->type) { + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; + case V_ASN1_NULL: + result = 0; // They do not have content. + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: case V_ASN1_BIT_STRING: @@ -155,9 +188,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) case V_ASN1_UTF8STRING: case V_ASN1_OTHER: default: - result = ASN1_STRING_cmp(a->value.asn1_string, b->value.asn1_string); - break; - } + result = ASN1_STRING_cmp(a->value.asn1_string, b->value.asn1_string); + break; + } - return result; + return result; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_utctm.c b/third_party/boringssl/kit/src/crypto/asn1/a_utctm.c index 21ea2cc3..82f2df63 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_utctm.c +++ b/third_party/boringssl/kit/src/crypto/asn1/a_utctm.c @@ -55,210 +55,125 @@ * [including the GNU Public Licence.] */ #include +#include +#include +#include +#include #include #include -#include -#include - #include "internal.h" - -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) -{ - static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - if (d->type != V_ASN1_UTCTIME) - return (0); - l = d->length; - a = (char *)d->data; - o = 0; - - if (l < 11) - goto err; - for (i = 0; i < 6; i++) { - if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n < 50 ? n + 100 : n; - break; - case 1: - tm->tm_mon = n - 1; - break; - case 2: - tm->tm_mday = n; - break; - case 3: - tm->tm_hour = n; - break; - case 4: - tm->tm_min = n; - break; - case 5: - tm->tm_sec = n; - break; - } - } - } - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? 1 : -1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 6; i < 8; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 6) - offset = n * 3600; - else if (i == 7) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } - return o == l; - err: +int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, + int allow_timezone_offset) { + if (d->type != V_ASN1_UTCTIME) { return 0; + } + CBS cbs; + CBS_init(&cbs, d->data, (size_t)d->length); + if (!CBS_parse_utc_time(&cbs, tm, allow_timezone_offset)) { + return 0; + } + return 1; } -int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) -{ - return asn1_utctime_to_tm(NULL, d); +int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) { + return asn1_utctime_to_tm(NULL, d, /*allow_timezone_offset=*/1); } -int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) -{ - ASN1_UTCTIME t; - - t.type = V_ASN1_UTCTIME; - t.length = strlen(str); - t.data = (unsigned char *)str; - if (ASN1_UTCTIME_check(&t)) { - if (s != NULL) { - if (!ASN1_STRING_set((ASN1_STRING *)s, - (unsigned char *)str, t.length)) - return 0; - s->type = V_ASN1_UTCTIME; - } - return (1); - } else - return (0); -} - -ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) -{ - return ASN1_UTCTIME_adj(s, t, 0, 0); -} - -ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, - int offset_day, long offset_sec) -{ - char *p; - struct tm *ts; - struct tm data; - size_t len = 20; - int free_s = 0; - - if (s == NULL) { - free_s = 1; - s = ASN1_UTCTIME_new(); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) { + // Although elsewhere we allow timezone offsets with UTCTime, to be compatible + // with some existing misissued certificates, this function is used to + // construct new certificates and can be stricter. + size_t len = strlen(str); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)str, len); + if (!CBS_parse_utc_time(&cbs, /*out_tm=*/NULL, + /*allow_timezone_offset=*/0)) { + return 0; + } + if (s != NULL) { + if (!ASN1_STRING_set(s, str, len)) { + return 0; } - if (s == NULL) - goto err; - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) - goto err; - - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - goto err; - } - - if ((ts->tm_year < 50) || (ts->tm_year >= 150)) - goto err; - - p = (char *)s->data; - if ((p == NULL) || ((size_t)s->length < len)) { - p = OPENSSL_malloc(len); - if (p == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - if (s->data != NULL) - OPENSSL_free(s->data); - s->data = (unsigned char *)p; - } - - BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, - ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, - ts->tm_sec); - s->length = strlen(p); s->type = V_ASN1_UTCTIME; - return (s); - err: - if (free_s && s) - ASN1_UTCTIME_free(s); + } + return 1; +} + +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, int64_t posix_time) { + return ASN1_UTCTIME_adj(s, posix_time, 0, 0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, int64_t posix_time, int offset_day, + long offset_sec) { + struct tm data; + if (!OPENSSL_posix_to_tm(posix_time, &data)) { return NULL; + } + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(&data, offset_day, offset_sec)) { + return NULL; + } + } + + if (data.tm_year < 50 || data.tm_year >= 150) { + return NULL; + } + + char buf[14]; + BIO_snprintf(buf, sizeof(buf), "%02d%02d%02d%02d%02d%02dZ", + data.tm_year % 100, data.tm_mon + 1, data.tm_mday, data.tm_hour, + data.tm_min, data.tm_sec); + + int free_s = 0; + if (s == NULL) { + free_s = 1; + s = ASN1_UTCTIME_new(); + if (s == NULL) { + return NULL; + } + } + + if (!ASN1_STRING_set(s, buf, strlen(buf))) { + if (free_s) { + ASN1_UTCTIME_free(s); + } + return NULL; + } + s->type = V_ASN1_UTCTIME; + return s; } -int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) -{ - struct tm stm, ttm; - int day, sec; +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) { + struct tm stm, ttm; + int day, sec; - if (!asn1_utctime_to_tm(&stm, s)) - return -2; + if (!asn1_utctime_to_tm(&stm, s, /*allow_timezone_offset=*/1)) { + return -2; + } - if (!OPENSSL_gmtime(&t, &ttm)) - return -2; + if (!OPENSSL_posix_to_tm(t, &ttm)) { + return -2; + } - if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) - return -2; + if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) { + return -2; + } - if (day > 0) - return 1; - if (day < 0) - return -1; - if (sec > 0) - return 1; - if (sec < 0) - return -1; - return 0; + if (day > 0) { + return 1; + } + if (day < 0) { + return -1; + } + if (sec > 0) { + return 1; + } + if (sec < 0) { + return -1; + } + return 0; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_utf8.c b/third_party/boringssl/kit/src/crypto/asn1/a_utf8.c deleted file mode 100644 index 922a7800..00000000 --- a/third_party/boringssl/kit/src/crypto/asn1/a_utf8.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include -#include - -#include "internal.h" - -/* UTF8 utilities */ - -/* - * This parses a UTF8 string one character at a time. It is passed a pointer - * to the string and the length of the string. It sets 'value' to the value - * of the current character. It returns the number of characters read or a - * negative error code: -1 = string too short -2 = illegal character -3 = - * subsequent characters not of the form 10xxxxxx -4 = character encoded - * incorrectly (not minimal length). - */ - -int UTF8_getc(const unsigned char *str, int len, uint32_t *val) -{ - const unsigned char *p; - uint32_t value; - int ret; - if (len <= 0) - return 0; - p = str; - - /* Check syntax and work out the encoded value (if correct) */ - if ((*p & 0x80) == 0) { - value = *p++ & 0x7f; - ret = 1; - } else if ((*p & 0xe0) == 0xc0) { - if (len < 2) - return -1; - if ((p[1] & 0xc0) != 0x80) - return -3; - value = (*p++ & 0x1f) << 6; - value |= *p++ & 0x3f; - if (value < 0x80) - return -4; - ret = 2; - } else if ((*p & 0xf0) == 0xe0) { - if (len < 3) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80)) - return -3; - value = (*p++ & 0xf) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x800) - return -4; - ret = 3; - } else if ((*p & 0xf8) == 0xf0) { - if (len < 4) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80)) - return -3; - value = ((uint32_t)(*p++ & 0x7)) << 18; - value |= (*p++ & 0x3f) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x10000) - return -4; - ret = 4; - } else if ((*p & 0xfc) == 0xf8) { - if (len < 5) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80)) - return -3; - value = ((uint32_t)(*p++ & 0x3)) << 24; - value |= ((uint32_t)(*p++ & 0x3f)) << 18; - value |= ((uint32_t)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x200000) - return -4; - ret = 5; - } else if ((*p & 0xfe) == 0xfc) { - if (len < 6) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80) - || ((p[5] & 0xc0) != 0x80)) - return -3; - value = ((uint32_t)(*p++ & 0x1)) << 30; - value |= ((uint32_t)(*p++ & 0x3f)) << 24; - value |= ((uint32_t)(*p++ & 0x3f)) << 18; - value |= ((uint32_t)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x4000000) - return -4; - ret = 6; - } else - return -2; - *val = value; - return ret; -} - -/* - * This takes a character 'value' and writes the UTF8 encoded value in 'str' - * where 'str' is a buffer containing 'len' characters. Returns the number of - * characters written or -1 if 'len' is too small. 'str' can be set to NULL - * in which case it just returns the number of characters. It will need at - * most 6 characters. - */ - -int UTF8_putc(unsigned char *str, int len, uint32_t value) -{ - if (!str) - len = 6; /* Maximum we will need */ - else if (len <= 0) - return -1; - if (value < 0x80) { - if (str) - *str = (unsigned char)value; - return 1; - } - if (value < 0x800) { - if (len < 2) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 2; - } - if (value < 0x10000) { - if (len < 3) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 3; - } - if (value < 0x200000) { - if (len < 4) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 4; - } - if (value < 0x4000000) { - if (len < 5) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 5; - } - if (len < 6) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); - *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 6; -} diff --git a/third_party/boringssl/kit/src/crypto/asn1/asn1_lib.c b/third_party/boringssl/kit/src/crypto/asn1/asn1_lib.c index fbf4d686..dd56c989 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/asn1_lib.c +++ b/third_party/boringssl/kit/src/crypto/asn1/asn1_lib.c @@ -59,7 +59,7 @@ #include #include -#include +#include #include #include @@ -67,19 +67,17 @@ #include "internal.h" -/* Cross-module errors from crypto/x509/i2d_pr.c. */ +// Cross-module errors from crypto/x509/i2d_pr.c. OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE) -/* Cross-module errors from crypto/x509/algorithm.c. */ +// Cross-module errors from crypto/x509/algorithm.c. OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED) OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED) OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM) OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM) OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE) -/* - * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove - * these once asn1_gen.c is gone. - */ +// Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove +// these once asn1_gen.c is gone. OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED) OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT) OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN) @@ -104,349 +102,288 @@ OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT) OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG) OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE) -static int asn1_get_length(const unsigned char **pp, long *rl, long max); static void asn1_put_length(unsigned char **pp, int length); -int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, - int *pclass, long omax) -{ - int i, ret; - long l; - const unsigned char *p = *pp; - int tag, xclass; - long max = omax; - - if (!max) - goto err; - ret = (*p & V_ASN1_CONSTRUCTED); - xclass = (*p & V_ASN1_PRIVATE); - i = *p & V_ASN1_PRIMITIVE_TAG; - if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ - p++; - if (--max == 0) - goto err; - l = 0; - while (*p & 0x80) { - l <<= 7L; - l |= *(p++) & 0x7f; - if (--max == 0) - goto err; - if (l > (INT_MAX >> 7L)) - goto err; - } - l <<= 7L; - l |= *(p++) & 0x7f; - tag = (int)l; - if (--max == 0) - goto err; - } else { - tag = i; - p++; - if (--max == 0) - goto err; - } - - /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */ - if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL) - goto err; - - *ptag = tag; - *pclass = xclass; - if (!asn1_get_length(&p, plength, max)) - goto err; - - if (*plength > (omax - (p - *pp))) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); - return 0x80; - } - *pp = p; - return ret; - err: +int ASN1_get_object(const unsigned char **inp, long *out_len, int *out_tag, + int *out_class, long in_len) { + if (in_len < 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); return 0x80; + } + + CBS_ASN1_TAG tag; + CBS cbs, body; + CBS_init(&cbs, *inp, (size_t)in_len); + if (!CBS_get_any_asn1(&cbs, &body, &tag) || + // Bound the length to comfortably fit in an int. Lengths in this + // module often switch between int and long without overflow checks. + CBS_len(&body) > INT_MAX / 2) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + return 0x80; + } + + // Convert between tag representations. + int tag_class = (tag & CBS_ASN1_CLASS_MASK) >> CBS_ASN1_TAG_SHIFT; + int constructed = (tag & CBS_ASN1_CONSTRUCTED) >> CBS_ASN1_TAG_SHIFT; + int tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + + // To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. + if (tag_class == V_ASN1_UNIVERSAL && tag_number > V_ASN1_MAX_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG); + return 0x80; + } + + *inp = CBS_data(&body); + *out_len = CBS_len(&body); + *out_tag = tag_number; + *out_class = tag_class; + return constructed; } -static int asn1_get_length(const unsigned char **pp, long *rl, long max) -{ - const unsigned char *p = *pp; - unsigned long ret = 0; - unsigned long i; - - if (max-- < 1) { - return 0; - } - if (*p == 0x80) { - /* We do not support BER indefinite-length encoding. */ - return 0; - } - i = *p & 0x7f; - if (*(p++) & 0x80) { - if (i > sizeof(ret) || max < (long)i) - return 0; - while (i-- > 0) { - ret <<= 8L; - ret |= *(p++); - } - } else { - ret = i; - } - /* - * Bound the length to comfortably fit in an int. Lengths in this module - * often switch between int and long without overflow checks. - */ - if (ret > INT_MAX / 2) - return 0; - *pp = p; - *rl = (long)ret; - return 1; -} - -/* - * class 0 is constructed constructed == 2 for indefinite length constructed - */ +// class 0 is constructed constructed == 2 for indefinite length constructed void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, - int xclass) -{ - unsigned char *p = *pp; - int i, ttag; + int xclass) { + unsigned char *p = *pp; + int i, ttag; - i = (constructed) ? V_ASN1_CONSTRUCTED : 0; - i |= (xclass & V_ASN1_PRIVATE); - if (tag < 31) - *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); - else { - *(p++) = i | V_ASN1_PRIMITIVE_TAG; - for (i = 0, ttag = tag; ttag > 0; i++) - ttag >>= 7; - ttag = i; - while (i-- > 0) { - p[i] = tag & 0x7f; - if (i != (ttag - 1)) - p[i] |= 0x80; - tag >>= 7; - } - p += ttag; + i = (constructed) ? V_ASN1_CONSTRUCTED : 0; + i |= (xclass & V_ASN1_PRIVATE); + if (tag < 31) { + *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); + } else { + *(p++) = i | V_ASN1_PRIMITIVE_TAG; + for (i = 0, ttag = tag; ttag > 0; i++) { + ttag >>= 7; } - if (constructed == 2) - *(p++) = 0x80; - else - asn1_put_length(&p, length); - *pp = p; + ttag = i; + while (i-- > 0) { + p[i] = tag & 0x7f; + if (i != (ttag - 1)) { + p[i] |= 0x80; + } + tag >>= 7; + } + p += ttag; + } + if (constructed == 2) { + *(p++) = 0x80; + } else { + asn1_put_length(&p, length); + } + *pp = p; } -int ASN1_put_eoc(unsigned char **pp) -{ - /* This function is no longer used in the library, but some external code - * uses it. */ - unsigned char *p = *pp; - *p++ = 0; - *p++ = 0; - *pp = p; - return 2; +int ASN1_put_eoc(unsigned char **pp) { + // This function is no longer used in the library, but some external code + // uses it. + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; } -static void asn1_put_length(unsigned char **pp, int length) -{ - unsigned char *p = *pp; - int i, l; - if (length <= 127) - *(p++) = (unsigned char)length; - else { - l = length; - for (i = 0; l > 0; i++) - l >>= 8; - *(p++) = i | 0x80; - l = i; - while (i-- > 0) { - p[i] = length & 0xff; - length >>= 8; - } - p += l; +static void asn1_put_length(unsigned char **pp, int length) { + unsigned char *p = *pp; + int i, l; + if (length <= 127) { + *(p++) = (unsigned char)length; + } else { + l = length; + for (i = 0; l > 0; i++) { + l >>= 8; } - *pp = p; + *(p++) = i | 0x80; + l = i; + while (i-- > 0) { + p[i] = length & 0xff; + length >>= 8; + } + p += l; + } + *pp = p; } -int ASN1_object_size(int constructed, int length, int tag) -{ - int ret = 1; - if (length < 0) - return -1; - if (tag >= 31) { - while (tag > 0) { - tag >>= 7; - ret++; - } +int ASN1_object_size(int constructed, int length, int tag) { + int ret = 1; + if (length < 0) { + return -1; + } + if (tag >= 31) { + while (tag > 0) { + tag >>= 7; + ret++; } - if (constructed == 2) { - ret += 3; - } else { + } + if (constructed == 2) { + ret += 3; + } else { + ret++; + if (length > 127) { + int tmplen = length; + while (tmplen > 0) { + tmplen >>= 8; ret++; - if (length > 127) { - int tmplen = length; - while (tmplen > 0) { - tmplen >>= 8; - ret++; - } - } + } } - if (ret >= INT_MAX - length) - return -1; - return ret + length; + } + if (ret >= INT_MAX - length) { + return -1; + } + return ret + length; } -int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) -{ - if (str == NULL) - return 0; - if (!ASN1_STRING_set(dst, str->data, str->length)) - return 0; - dst->type = str->type; - dst->flags = str->flags; - return 1; -} - -ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) -{ - ASN1_STRING *ret; - if (!str) - return NULL; - ret = ASN1_STRING_new(); - if (!ret) - return NULL; - if (!ASN1_STRING_copy(ret, str)) { - ASN1_STRING_free(ret); - return NULL; - } - return ret; -} - -int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) -{ - unsigned char *c; - const char *data = _data; - - if (len < 0) { - if (data == NULL) - return (0); - else - len = strlen(data); - } - if ((str->length <= len) || (str->data == NULL)) { - c = str->data; - if (c == NULL) - str->data = OPENSSL_malloc(len + 1); - else - str->data = OPENSSL_realloc(c, len + 1); - - if (str->data == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - str->data = c; - return (0); - } - } - str->length = len; - if (data != NULL) { - OPENSSL_memcpy(str->data, data, len); - /* an allowance for strings :-) */ - str->data[len] = '\0'; - } - return (1); -} - -void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) -{ - OPENSSL_free(str->data); - str->data = data; - str->length = len; -} - -ASN1_STRING *ASN1_STRING_new(void) -{ - return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); -} - -ASN1_STRING *ASN1_STRING_type_new(int type) -{ - ASN1_STRING *ret; - - ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); - if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->length = 0; - ret->type = type; - ret->data = NULL; - ret->flags = 0; - return (ret); -} - -void ASN1_STRING_free(ASN1_STRING *str) -{ - if (str == NULL) - return; - OPENSSL_free(str->data); - OPENSSL_free(str); -} - -int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) -{ - /* Capture padding bits and implicit truncation in BIT STRINGs. */ - int a_length = a->length, b_length = b->length; - uint8_t a_padding = 0, b_padding = 0; - if (a->type == V_ASN1_BIT_STRING) { - a_length = asn1_bit_string_length(a, &a_padding); - } - if (b->type == V_ASN1_BIT_STRING) { - b_length = asn1_bit_string_length(b, &b_padding); - } - - if (a_length < b_length) { - return -1; - } - if (a_length > b_length) { - return 1; - } - /* In a BIT STRING, the number of bits is 8 * length - padding. Invert this - * comparison so we compare by lengths. */ - if (a_padding > b_padding) { - return -1; - } - if (a_padding < b_padding) { - return 1; - } - - int ret = OPENSSL_memcmp(a->data, b->data, a_length); - if (ret != 0) { - return ret; - } - - /* Comparing the type first is more natural, but this matches OpenSSL. */ - if (a->type < b->type) { - return -1; - } - if (a->type > b->type) { - return 1; - } +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) { + if (str == NULL) { return 0; + } + if (!ASN1_STRING_set(dst, str->data, str->length)) { + return 0; + } + dst->type = str->type; + dst->flags = str->flags; + return 1; } -int ASN1_STRING_length(const ASN1_STRING *str) -{ - return str->length; +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) { + ASN1_STRING *ret; + if (!str) { + return NULL; + } + ret = ASN1_STRING_new(); + if (!ret) { + return NULL; + } + if (!ASN1_STRING_copy(ret, str)) { + ASN1_STRING_free(ret); + return NULL; + } + return ret; } -int ASN1_STRING_type(const ASN1_STRING *str) -{ - return str->type; +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, ossl_ssize_t len_s) { + const char *data = _data; + size_t len; + if (len_s < 0) { + if (data == NULL) { + return 0; + } + len = strlen(data); + } else { + len = (size_t)len_s; + } + + // |ASN1_STRING| cannot represent strings that exceed |int|, and we must + // reserve space for a trailing NUL below. + if (len > INT_MAX || len + 1 < len) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + + if (str->length <= (int)len || str->data == NULL) { + unsigned char *c = str->data; + if (c == NULL) { + str->data = OPENSSL_malloc(len + 1); + } else { + str->data = OPENSSL_realloc(c, len + 1); + } + + if (str->data == NULL) { + str->data = c; + return 0; + } + } + str->length = (int)len; + if (data != NULL) { + OPENSSL_memcpy(str->data, data, len); + // Historically, OpenSSL would NUL-terminate most (but not all) + // |ASN1_STRING|s, in case anyone accidentally passed |str->data| into a + // function expecting a C string. We retain this behavior for compatibility, + // but code must not rely on this. See CVE-2021-3712. + str->data[len] = '\0'; + } + return 1; } -unsigned char *ASN1_STRING_data(ASN1_STRING *str) -{ - return str->data; +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) { + OPENSSL_free(str->data); + str->data = data; + str->length = len; } -const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str) -{ - return str->data; +ASN1_STRING *ASN1_STRING_new(void) { + return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); +} + +ASN1_STRING *ASN1_STRING_type_new(int type) { + ASN1_STRING *ret; + + ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); + if (ret == NULL) { + return NULL; + } + ret->length = 0; + ret->type = type; + ret->data = NULL; + ret->flags = 0; + return ret; +} + +void ASN1_STRING_free(ASN1_STRING *str) { + if (str == NULL) { + return; + } + OPENSSL_free(str->data); + OPENSSL_free(str); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) { + // Capture padding bits and implicit truncation in BIT STRINGs. + int a_length = a->length, b_length = b->length; + uint8_t a_padding = 0, b_padding = 0; + if (a->type == V_ASN1_BIT_STRING) { + a_length = asn1_bit_string_length(a, &a_padding); + } + if (b->type == V_ASN1_BIT_STRING) { + b_length = asn1_bit_string_length(b, &b_padding); + } + + if (a_length < b_length) { + return -1; + } + if (a_length > b_length) { + return 1; + } + // In a BIT STRING, the number of bits is 8 * length - padding. Invert this + // comparison so we compare by lengths. + if (a_padding > b_padding) { + return -1; + } + if (a_padding < b_padding) { + return 1; + } + + int ret = OPENSSL_memcmp(a->data, b->data, a_length); + if (ret != 0) { + return ret; + } + + // Comparing the type first is more natural, but this matches OpenSSL. + if (a->type < b->type) { + return -1; + } + if (a->type > b->type) { + return 1; + } + return 0; +} + +int ASN1_STRING_length(const ASN1_STRING *str) { return str->length; } + +int ASN1_STRING_type(const ASN1_STRING *str) { return str->type; } + +unsigned char *ASN1_STRING_data(ASN1_STRING *str) { return str->data; } + +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str) { + return str->data; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/asn1_par.c b/third_party/boringssl/kit/src/crypto/asn1/asn1_par.c index 282ad235..d065e200 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/asn1_par.c +++ b/third_party/boringssl/kit/src/crypto/asn1/asn1_par.c @@ -57,24 +57,47 @@ #include -const char *ASN1_tag2str(int tag) -{ - static const char *const tag2str[] = { - "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ - "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ - "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ - "", "", "SEQUENCE", "SET", /* 15-17 */ - "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ - "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 - */ - "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ - "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ - }; +const char *ASN1_tag2str(int tag) { + static const char *const tag2str[] = { + "EOC", + "BOOLEAN", + "INTEGER", + "BIT STRING", + "OCTET STRING", + "NULL", + "OBJECT", + "OBJECT DESCRIPTOR", + "EXTERNAL", + "REAL", + "ENUMERATED", + "", + "UTF8STRING", + "", + "", + "", + "SEQUENCE", + "SET", + "NUMERICSTRING", + "PRINTABLESTRING", + "T61STRING", + "VIDEOTEXSTRING", + "IA5STRING", + "UTCTIME", + "GENERALIZEDTIME", + "GRAPHICSTRING", + "VISIBLESTRING", + "GENERALSTRING", + "UNIVERSALSTRING", + "", + "BMPSTRING", + }; - if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) - tag &= ~V_ASN1_NEG; + if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) { + tag &= ~V_ASN1_NEG; + } - if (tag < 0 || tag > 30) - return "(unknown)"; - return tag2str[tag]; + if (tag < 0 || tag > 30) { + return "(unknown)"; + } + return tag2str[tag]; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/asn1_test.cc b/third_party/boringssl/kit/src/crypto/asn1/asn1_test.cc index ab9cb017..94f22728 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/asn1_test.cc +++ b/third_party/boringssl/kit/src/crypto/asn1/asn1_test.cc @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -22,11 +23,15 @@ #include #include +#include #include #include #include #include +#include #include +#include +#include #include #include "../test/test_util.h" @@ -37,72 +42,6 @@ #endif -// kTag128 is an ASN.1 structure with a universal tag with number 128. -static const uint8_t kTag128[] = { - 0x1f, 0x81, 0x00, 0x01, 0x00, -}; - -// kTag258 is an ASN.1 structure with a universal tag with number 258. -static const uint8_t kTag258[] = { - 0x1f, 0x82, 0x02, 0x01, 0x00, -}; - -static_assert(V_ASN1_NEG_INTEGER == 258, - "V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it."); - -// kTagOverflow is an ASN.1 structure with a universal tag with number 2^35-1, -// which will not fit in an int. -static const uint8_t kTagOverflow[] = { - 0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01, 0x00, -}; - -TEST(ASN1Test, LargeTags) { - const uint8_t *p = kTag258; - bssl::UniquePtr obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258))); - EXPECT_FALSE(obj) << "Parsed value with illegal tag" << obj->type; - ERR_clear_error(); - - p = kTagOverflow; - obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow))); - EXPECT_FALSE(obj) << "Parsed value with tag overflow" << obj->type; - ERR_clear_error(); - - p = kTag128; - obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128))); - ASSERT_TRUE(obj); - EXPECT_EQ(128, obj->type); - const uint8_t kZero = 0; - EXPECT_EQ(Bytes(&kZero, 1), Bytes(obj->value.asn1_string->data, - obj->value.asn1_string->length)); -} - -TEST(ASN1Test, IntegerSetting) { - bssl::UniquePtr by_bn(ASN1_INTEGER_new()); - bssl::UniquePtr by_long(ASN1_INTEGER_new()); - bssl::UniquePtr by_uint64(ASN1_INTEGER_new()); - bssl::UniquePtr bn(BN_new()); - - const std::vector kValues = { - LONG_MIN, -2, -1, 0, 1, 2, 0xff, 0x100, 0xffff, 0x10000, LONG_MAX, - }; - for (const auto &i : kValues) { - SCOPED_TRACE(i); - - ASSERT_EQ(1, ASN1_INTEGER_set(by_long.get(), i)); - const uint64_t abs = i < 0 ? (0 - (uint64_t) i) : i; - ASSERT_TRUE(BN_set_u64(bn.get(), abs)); - BN_set_negative(bn.get(), i < 0); - ASSERT_TRUE(BN_to_ASN1_INTEGER(bn.get(), by_bn.get())); - - EXPECT_EQ(0, ASN1_INTEGER_cmp(by_bn.get(), by_long.get())); - - if (i >= 0) { - ASSERT_EQ(1, ASN1_INTEGER_set_uint64(by_uint64.get(), i)); - EXPECT_EQ(0, ASN1_INTEGER_cmp(by_bn.get(), by_uint64.get())); - } - } -} - // |obj| and |i2d_func| require different template parameters because C++ may // deduce, say, |ASN1_STRING*| via |obj| and |const ASN1_STRING*| via // |i2d_func|. Template argument deduction then fails. The language is not able @@ -131,6 +70,475 @@ void TestSerialize(T obj, int (*i2d_func)(U a, uint8_t **pp), EXPECT_EQ(Bytes(expected), Bytes(buf)); } +// Historically, unknown universal tags were represented in |ASN1_TYPE| as +// |ASN1_STRING|s with the type matching the tag number. This can collide with +// |V_ASN_NEG|, which was one of the causes of CVE-2016-2108. We now represent +// unsupported values with |V_ASN1_OTHER|, but retain the |V_ASN1_MAX_UNIVERSAL| +// limit. +TEST(ASN1Test, UnknownTags) { + // kTag258 is an ASN.1 structure with a universal tag with number 258. + static const uint8_t kTag258[] = {0x1f, 0x82, 0x02, 0x01, 0x00}; + static_assert( + V_ASN1_NEG_INTEGER == 258, + "V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it."); + const uint8_t *p = kTag258; + bssl::UniquePtr obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258))); + EXPECT_FALSE(obj) << "Parsed value with illegal tag" << obj->type; + ERR_clear_error(); + + // kTagOverflow is an ASN.1 structure with a universal tag with number 2^35-1, + // which will not fit in an int. + static const uint8_t kTagOverflow[] = {0x1f, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x01, 0x00}; + p = kTagOverflow; + obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow))); + EXPECT_FALSE(obj) << "Parsed value with tag overflow" << obj->type; + ERR_clear_error(); + + // kTag128 is an ASN.1 structure with a universal tag with number 128. It + // should be parsed as |V_ASN1_OTHER|. + static const uint8_t kTag128[] = {0x1f, 0x81, 0x00, 0x01, 0x00}; + p = kTag128; + obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128))); + ASSERT_TRUE(obj); + EXPECT_EQ(V_ASN1_OTHER, obj->type); + EXPECT_EQ(Bytes(kTag128), Bytes(obj->value.asn1_string->data, + obj->value.asn1_string->length)); + TestSerialize(obj.get(), i2d_ASN1_TYPE, kTag128); + + // The historical in-memory representation of |kTag128| was for both + // |obj->type| and |obj->value.asn1_string->type| to be 128. This is no + // longer used but is still accepted by the encoder. + // + // TODO(crbug.com/boringssl/412): The encoder should reject it. However, it is + // still needed to support some edge cases in |ASN1_PRINTABLE|. When that is + // fixed, test that we reject it. + obj.reset(ASN1_TYPE_new()); + ASSERT_TRUE(obj); + obj->type = 128; + obj->value.asn1_string = ASN1_STRING_type_new(128); + ASSERT_TRUE(obj->value.asn1_string); + const uint8_t zero = 0; + ASSERT_TRUE(ASN1_STRING_set(obj->value.asn1_string, &zero, sizeof(zero))); + TestSerialize(obj.get(), i2d_ASN1_TYPE, kTag128); + + // If a tag is known, but has the wrong constructed bit, it should be + // rejected, not placed in |V_ASN1_OTHER|. + static const uint8_t kConstructedOctetString[] = {0x24, 0x00}; + p = kConstructedOctetString; + obj.reset(d2i_ASN1_TYPE(nullptr, &p, sizeof(kConstructedOctetString))); + EXPECT_FALSE(obj); + + static const uint8_t kPrimitiveSequence[] = {0x10, 0x00}; + p = kPrimitiveSequence; + obj.reset(d2i_ASN1_TYPE(nullptr, &p, sizeof(kPrimitiveSequence))); + EXPECT_FALSE(obj); +} + +static bssl::UniquePtr BIGNUMPow2(unsigned bit) { + bssl::UniquePtr bn(BN_new()); + if (!bn || + !BN_set_bit(bn.get(), bit)) { + return nullptr; + } + return bn; +} + +TEST(ASN1Test, Integer) { + bssl::UniquePtr int64_min = BIGNUMPow2(63); + ASSERT_TRUE(int64_min); + BN_set_negative(int64_min.get(), 1); + + bssl::UniquePtr int64_max = BIGNUMPow2(63); + ASSERT_TRUE(int64_max); + ASSERT_TRUE(BN_sub_word(int64_max.get(), 1)); + + bssl::UniquePtr int32_min = BIGNUMPow2(31); + ASSERT_TRUE(int32_min); + BN_set_negative(int32_min.get(), 1); + + bssl::UniquePtr int32_max = BIGNUMPow2(31); + ASSERT_TRUE(int32_max); + ASSERT_TRUE(BN_sub_word(int32_max.get(), 1)); + + struct { + // der is the DER encoding of the INTEGER, including the tag and length. + std::vector der; + // type and data are the corresponding fields of the |ASN1_STRING| + // representation. + int type; + std::vector data; + // bn_asc is the |BIGNUM| representation, as parsed by the |BN_asc2bn| + // function. + const char *bn_asc; + } kTests[] = { + // -2^64 - 1 + {{0x02, 0x09, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_NEG_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + "-0x10000000000000001"}, + // -2^64 + {{0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_NEG_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "-0x10000000000000000"}, + // -2^64 + 1 + {{0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + V_ASN1_NEG_INTEGER, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "-0xffffffffffffffff"}, + // -2^63 - 1 + {{0x02, 0x09, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_NEG_INTEGER, + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + "-0x8000000000000001"}, + // -2^63 (INT64_MIN) + {{0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_NEG_INTEGER, + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "-0x8000000000000000"}, + // -2^63 + 1 + {{0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + V_ASN1_NEG_INTEGER, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "-0x7fffffffffffffff"}, + // -2^32 - 1 + {{0x02, 0x05, 0xfe, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_NEG_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x01}, + "-0x100000001"}, + // -2^32 + {{0x02, 0x05, 0xff, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_NEG_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00}, + "-0x100000000"}, + // -2^32 + 1 + {{0x02, 0x05, 0xff, 0x00, 0x00, 0x00, 0x01}, + V_ASN1_NEG_INTEGER, + {0xff, 0xff, 0xff, 0xff}, + "-0xffffffff"}, + // -2^31 - 1 + {{0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xff}, + V_ASN1_NEG_INTEGER, + {0x80, 0x00, 0x00, 0x01}, + "-0x80000001"}, + // -2^31 (INT32_MIN) + {{0x02, 0x04, 0x80, 0x00, 0x00, 0x00}, + V_ASN1_NEG_INTEGER, + {0x80, 0x00, 0x00, 0x00}, + "-0x80000000"}, + // -2^31 + 1 + {{0x02, 0x04, 0x80, 0x00, 0x00, 0x01}, + V_ASN1_NEG_INTEGER, + {0x7f, 0xff, 0xff, 0xff}, + "-0x7fffffff"}, + // -257 + {{0x02, 0x02, 0xfe, 0xff}, V_ASN1_NEG_INTEGER, {0x01, 0x01}, "-257"}, + // -256 + {{0x02, 0x02, 0xff, 0x00}, V_ASN1_NEG_INTEGER, {0x01, 0x00}, "-256"}, + // -255 + {{0x02, 0x02, 0xff, 0x01}, V_ASN1_NEG_INTEGER, {0xff}, "-255"}, + // -129 + {{0x02, 0x02, 0xff, 0x7f}, V_ASN1_NEG_INTEGER, {0x81}, "-129"}, + // -128 + {{0x02, 0x01, 0x80}, V_ASN1_NEG_INTEGER, {0x80}, "-128"}, + // -127 + {{0x02, 0x01, 0x81}, V_ASN1_NEG_INTEGER, {0x7f}, "-127"}, + // -1 + {{0x02, 0x01, 0xff}, V_ASN1_NEG_INTEGER, {0x01}, "-1"}, + // 0 + {{0x02, 0x01, 0x00}, V_ASN1_INTEGER, {}, "0"}, + // 1 + {{0x02, 0x01, 0x01}, V_ASN1_INTEGER, {0x01}, "1"}, + // 127 + {{0x02, 0x01, 0x7f}, V_ASN1_INTEGER, {0x7f}, "127"}, + // 128 + {{0x02, 0x02, 0x00, 0x80}, V_ASN1_INTEGER, {0x80}, "128"}, + // 129 + {{0x02, 0x02, 0x00, 0x81}, V_ASN1_INTEGER, {0x81}, "129"}, + // 255 + {{0x02, 0x02, 0x00, 0xff}, V_ASN1_INTEGER, {0xff}, "255"}, + // 256 + {{0x02, 0x02, 0x01, 0x00}, V_ASN1_INTEGER, {0x01, 0x00}, "256"}, + // 257 + {{0x02, 0x02, 0x01, 0x01}, V_ASN1_INTEGER, {0x01, 0x01}, "257"}, + // 2^31 - 2 + {{0x02, 0x04, 0x7f, 0xff, 0xff, 0xfe}, + V_ASN1_INTEGER, + {0x7f, 0xff, 0xff, 0xfe}, + "0x7ffffffe"}, + // 2^31 - 1 (INT32_MAX) + {{0x02, 0x04, 0x7f, 0xff, 0xff, 0xff}, + V_ASN1_INTEGER, + {0x7f, 0xff, 0xff, 0xff}, + "0x7fffffff"}, + // 2^31 + {{0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00}, + V_ASN1_INTEGER, + {0x80, 0x00, 0x00, 0x00}, + "0x80000000"}, + // 2^32 - 2 + {{0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xfe}, + V_ASN1_INTEGER, + {0xff, 0xff, 0xff, 0xfe}, + "0xfffffffe"}, + // 2^32 - 1 (UINT32_MAX) + {{0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_INTEGER, + {0xff, 0xff, 0xff, 0xff}, + "0xffffffff"}, + // 2^32 + {{0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00}, + "0x100000000"}, + // 2^63 - 2 + {{0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + V_ASN1_INTEGER, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + "0x7ffffffffffffffe"}, + // 2^63 - 1 (INT64_MAX) + {{0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_INTEGER, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "0x7fffffffffffffff"}, + // 2^63 + {{0x02, 0x09, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_INTEGER, + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "0x8000000000000000"}, + // 2^64 - 2 + {{0x02, 0x09, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + V_ASN1_INTEGER, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, + "0xfffffffffffffffe"}, + // 2^64 - 1 (UINT64_MAX) + {{0x02, 0x09, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + V_ASN1_INTEGER, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "0xffffffffffffffff"}, + // 2^64 + {{0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + V_ASN1_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "0x10000000000000000"}, + // 2^64 + 1 + {{0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + V_ASN1_INTEGER, + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + "0x10000000000000001"}, + }; + + for (const auto &t : kTests) { + SCOPED_TRACE(t.bn_asc); + // Collect a map of different ways to construct the integer. The key is the + // method used and is only retained to aid debugging. + std::map> objs; + + // Construct |ASN1_INTEGER| by setting the type and data manually. + bssl::UniquePtr by_data(ASN1_STRING_type_new(t.type)); + ASSERT_TRUE(by_data); + ASSERT_TRUE(ASN1_STRING_set(by_data.get(), t.data.data(), t.data.size())); + objs["data"] = std::move(by_data); + + // Construct |ASN1_INTEGER| from a |BIGNUM|. + BIGNUM *bn_raw = nullptr; + ASSERT_TRUE(BN_asc2bn(&bn_raw, t.bn_asc)); + bssl::UniquePtr bn(bn_raw); + bssl::UniquePtr by_bn(BN_to_ASN1_INTEGER(bn.get(), nullptr)); + ASSERT_TRUE(by_bn); + objs["bn"] = std::move(by_bn); + + // Construct |ASN1_INTEGER| from decoding. + const uint8_t *ptr = t.der.data(); + bssl::UniquePtr by_der( + d2i_ASN1_INTEGER(nullptr, &ptr, t.der.size())); + ASSERT_TRUE(by_der); + EXPECT_EQ(ptr, t.der.data() + t.der.size()); + objs["der"] = std::move(by_der); + + // Construct |ASN1_INTEGER| from various C types, if it fits. + bool fits_in_long = false, fits_in_i64 = false, fits_in_u64 = false; + uint64_t u64 = 0; + int64_t i64 = 0; + long l = 0; + uint64_t abs_u64; + if (BN_get_u64(bn.get(), &abs_u64)) { + fits_in_u64 = !BN_is_negative(bn.get()); + if (fits_in_u64) { + u64 = abs_u64; + bssl::UniquePtr by_u64(ASN1_INTEGER_new()); + ASSERT_TRUE(by_u64); + ASSERT_TRUE(ASN1_INTEGER_set_uint64(by_u64.get(), u64)); + objs["u64"] = std::move(by_u64); + } + + fits_in_i64 = BN_cmp(int64_min.get(), bn.get()) <= 0 && + BN_cmp(bn.get(), int64_max.get()) <= 0; + if (fits_in_i64) { + if (BN_is_negative(bn.get())) { + i64 = static_cast(0u - abs_u64); + } else { + i64 = static_cast(abs_u64); + } + bssl::UniquePtr by_i64(ASN1_INTEGER_new()); + ASSERT_TRUE(by_i64); + ASSERT_TRUE(ASN1_INTEGER_set_int64(by_i64.get(), i64)); + objs["i64"] = std::move(by_i64); + } + + if (sizeof(long) == 8) { + fits_in_long = fits_in_i64; + } else { + ASSERT_EQ(4u, sizeof(long)); + fits_in_long = BN_cmp(int32_min.get(), bn.get()) <= 0 && + BN_cmp(bn.get(), int32_max.get()) <= 0; + } + if (fits_in_long) { + l = static_cast(i64); + bssl::UniquePtr by_long(ASN1_INTEGER_new()); + ASSERT_TRUE(by_long); + ASSERT_TRUE(ASN1_INTEGER_set(by_long.get(), l)); + objs["long"] = std::move(by_long); + } + } + + // Default construction should return the zero |ASN1_INTEGER|. + if (BN_is_zero(bn.get())) { + bssl::UniquePtr by_default(ASN1_INTEGER_new()); + ASSERT_TRUE(by_default); + objs["default"] = std::move(by_default); + } + + // Test that every |ASN1_INTEGER| constructed behaves as expected. + for (const auto &pair : objs) { + // The fields should be as expected. + SCOPED_TRACE(pair.first); + const ASN1_INTEGER *obj = pair.second.get(); + EXPECT_EQ(t.type, ASN1_STRING_type(obj)); + EXPECT_EQ(Bytes(t.data), Bytes(ASN1_STRING_get0_data(obj), + ASN1_STRING_length(obj))); + + // The object should encode correctly. + TestSerialize(obj, i2d_ASN1_INTEGER, t.der); + + bssl::UniquePtr bn2(ASN1_INTEGER_to_BN(obj, nullptr)); + ASSERT_TRUE(bn2); + EXPECT_EQ(0, BN_cmp(bn.get(), bn2.get())); + + if (fits_in_u64) { + uint64_t v; + ASSERT_TRUE(ASN1_INTEGER_get_uint64(&v, obj)); + EXPECT_EQ(v, u64); + } else { + uint64_t v; + EXPECT_FALSE(ASN1_INTEGER_get_uint64(&v, obj)); + } + + if (fits_in_i64) { + int64_t v; + ASSERT_TRUE(ASN1_INTEGER_get_int64(&v, obj)); + EXPECT_EQ(v, i64); + } else { + int64_t v; + EXPECT_FALSE(ASN1_INTEGER_get_int64(&v, obj)); + } + + if (fits_in_long) { + EXPECT_EQ(l, ASN1_INTEGER_get(obj)); + } else { + EXPECT_EQ(-1, ASN1_INTEGER_get(obj)); + } + + // All variations of integers should compare as equal to each other, as + // strings or integers. (Functions like |ASN1_TYPE_cmp| rely on + // string-based comparison.) + for (const auto &pair2 : objs) { + SCOPED_TRACE(pair2.first); + EXPECT_EQ(0, ASN1_INTEGER_cmp(obj, pair2.second.get())); + EXPECT_EQ(0, ASN1_STRING_cmp(obj, pair2.second.get())); + } + } + + // Although our parsers will never output non-minimal |ASN1_INTEGER|s, it is + // possible to construct them manually. They should encode correctly. + std::vector data = t.data; + const int kMaxExtraBytes = 5; + for (int i = 0; i < kMaxExtraBytes; i++) { + data.insert(data.begin(), 0x00); + SCOPED_TRACE(Bytes(data)); + + bssl::UniquePtr non_minimal(ASN1_STRING_type_new(t.type)); + ASSERT_TRUE(non_minimal); + ASSERT_TRUE(ASN1_STRING_set(non_minimal.get(), data.data(), data.size())); + + TestSerialize(non_minimal.get(), i2d_ASN1_INTEGER, t.der); + } + } + + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) { + SCOPED_TRACE(Bytes(kTests[i].der)); + const uint8_t *ptr = kTests[i].der.data(); + bssl::UniquePtr a( + d2i_ASN1_INTEGER(nullptr, &ptr, kTests[i].der.size())); + ASSERT_TRUE(a); + for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(kTests); j++) { + SCOPED_TRACE(Bytes(kTests[j].der)); + ptr = kTests[j].der.data(); + bssl::UniquePtr b( + d2i_ASN1_INTEGER(nullptr, &ptr, kTests[j].der.size())); + ASSERT_TRUE(b); + + // |ASN1_INTEGER_cmp| should compare numerically. |ASN1_STRING_cmp| does + // not but should preserve equality. + if (i < j) { + EXPECT_LT(ASN1_INTEGER_cmp(a.get(), b.get()), 0); + EXPECT_NE(ASN1_STRING_cmp(a.get(), b.get()), 0); + } else if (i > j) { + EXPECT_GT(ASN1_INTEGER_cmp(a.get(), b.get()), 0); + EXPECT_NE(ASN1_STRING_cmp(a.get(), b.get()), 0); + } else { + EXPECT_EQ(ASN1_INTEGER_cmp(a.get(), b.get()), 0); + EXPECT_EQ(ASN1_STRING_cmp(a.get(), b.get()), 0); + } + } + } + + std::vector kInvalidTests[] = { + // The empty string is not an integer. + {0x02, 0x00}, + // Integers must be minimally-encoded. + {0x02, 0x02, 0x00, 0x00}, + {0x02, 0x02, 0x00, 0x7f}, + {0x02, 0x02, 0xff, 0xff}, + {0x02, 0x02, 0xff, 0x80}, + }; + for (const auto &invalid : kInvalidTests) { + SCOPED_TRACE(Bytes(invalid)); + + const uint8_t *ptr = invalid.data(); + bssl::UniquePtr integer( + d2i_ASN1_INTEGER(nullptr, &ptr, invalid.size())); + EXPECT_FALSE(integer); + } + + // Callers expect |ASN1_INTEGER_get| and |ASN1_ENUMERATED_get| to return zero + // given NULL. + EXPECT_EQ(0, ASN1_INTEGER_get(nullptr)); + EXPECT_EQ(0, ASN1_ENUMERATED_get(nullptr)); +} + +// Although invalid, a negative zero should encode correctly. +TEST(ASN1Test, NegativeZero) { + bssl::UniquePtr neg_zero( + ASN1_STRING_type_new(V_ASN1_NEG_INTEGER)); + ASSERT_TRUE(neg_zero); + EXPECT_EQ(0, ASN1_INTEGER_get(neg_zero.get())); + + static const uint8_t kDER[] = {0x02, 0x01, 0x00}; + TestSerialize(neg_zero.get(), i2d_ASN1_INTEGER, kDER); +} + TEST(ASN1Test, SerializeObject) { static const uint8_t kDER[] = {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}; @@ -172,8 +580,10 @@ TEST(ASN1Test, Boolean) { {0x81, 0x01, 0x00}, // Element is constructed. {0x21, 0x01, 0x00}, - // TODO(https://crbug.com/boringssl/354): Reject non-DER encodings of TRUE - // and test this. + // Not a DER encoding of TRUE. + {0x01, 0x01, 0x01}, + // Non-minimal tag length. + {0x01, 0x81, 0x01, 0xff}, }; for (const auto &invalid : kInvalidBooleans) { SCOPED_TRACE(Bytes(invalid)); @@ -310,6 +720,8 @@ TEST(ASN1Test, ParseASN1Object) { {0x86, 0x03, 0x2b, 0x65, 0x70}, // Element is constructed. {0x26, 0x03, 0x2b, 0x65, 0x70}, + // Non-minimal tag length. + {0x06, 0x81, 0x03, 0x2b, 0x65, 0x70}, }; for (const auto &invalid : kInvalidObjects) { SCOPED_TRACE(Bytes(invalid)); @@ -512,6 +924,8 @@ TEST(ASN1Test, StringToUTF8) { {{0, 0, 0xfd, 0xd5}, V_ASN1_UNIVERSALSTRING, nullptr}, // BMPString is UCS-2, not UTF-16, so surrogate pairs are invalid. {{0xd8, 0, 0xdc, 1}, V_ASN1_BMPSTRING, nullptr}, + // INTEGERs are stored as strings, but cannot be converted to UTF-8. + {{0x01}, V_ASN1_INTEGER, nullptr}, }; for (const auto &test : kTests) { @@ -540,44 +954,89 @@ static std::string ASN1StringToStdString(const ASN1_STRING *str) { ASN1_STRING_get0_data(str) + ASN1_STRING_length(str)); } +static bool ASN1Time_check_posix(const ASN1_TIME *s, int64_t t) { + struct tm stm, ttm; + int day, sec; + + switch (ASN1_STRING_type(s)) { + case V_ASN1_GENERALIZEDTIME: + if (!asn1_generalizedtime_to_tm(&stm, s)) { + return false; + } + break; + case V_ASN1_UTCTIME: + if (!asn1_utctime_to_tm(&stm, s, /*allow_timezone_offset=*/1)) { + return false; + } + break; + default: + return false; + } + if (!OPENSSL_posix_to_tm(t, &ttm) || + !OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) { + return false; + } + return day == 0 && sec ==0; +} + +static std::string PrintStringToBIO(const ASN1_STRING *str, + int (*print_func)(BIO *, + const ASN1_STRING *)) { + const uint8_t *data; + size_t len; + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + if (!bio || // + !print_func(bio.get(), str) || + !BIO_mem_contents(bio.get(), &data, &len)) { + ADD_FAILURE() << "Could not print to BIO"; + return ""; + } + return std::string(data, data + len); +} + TEST(ASN1Test, SetTime) { static const struct { - time_t time; + int64_t time; const char *generalized; const char *utc; + const char *printed; } kTests[] = { - {-631152001, "19491231235959Z", nullptr}, - {-631152000, "19500101000000Z", "500101000000Z"}, - {0, "19700101000000Z", "700101000000Z"}, - {981173106, "20010203040506Z", "010203040506Z"}, -#if defined(OPENSSL_64_BIT) - // TODO(https://crbug.com/boringssl/416): These cases overflow 32-bit - // |time_t| and do not consistently work on 32-bit platforms. For now, - // disable the tests on 32-bit. Re-enable them once the bug is fixed. - {2524607999, "20491231235959Z", "491231235959Z"}, - {2524608000, "20500101000000Z", nullptr}, - // Test boundary conditions. - {-62167219200, "00000101000000Z", nullptr}, - {-62167219201, nullptr, nullptr}, - {253402300799, "99991231235959Z", nullptr}, - {253402300800, nullptr, nullptr}, -#endif + {-631152001, "19491231235959Z", nullptr, "Dec 31 23:59:59 1949 GMT"}, + {-631152000, "19500101000000Z", "500101000000Z", + "Jan 1 00:00:00 1950 GMT"}, + {0, "19700101000000Z", "700101000000Z", "Jan 1 00:00:00 1970 GMT"}, + {981173106, "20010203040506Z", "010203040506Z", + "Feb 3 04:05:06 2001 GMT"}, + {951804000, "20000229060000Z", "000229060000Z", + "Feb 29 06:00:00 2000 GMT"}, + // NASA says this is the correct time for posterity. + {-16751025, "19690621025615Z", "690621025615Z", + "Jun 21 02:56:15 1969 GMT"}, + // -1 is sometimes used as an error value. Ensure we correctly handle it. + {-1, "19691231235959Z", "691231235959Z", "Dec 31 23:59:59 1969 GMT"}, + {2524607999, "20491231235959Z", "491231235959Z", + "Dec 31 23:59:59 2049 GMT"}, + {2524608000, "20500101000000Z", nullptr, "Jan 1 00:00:00 2050 GMT"}, + // Test boundary conditions. + {-62167219200, "00000101000000Z", nullptr, "Jan 1 00:00:00 0 GMT"}, + {-62167219201, nullptr, nullptr, nullptr}, + {253402300799, "99991231235959Z", nullptr, "Dec 31 23:59:59 9999 GMT"}, + {253402300800, nullptr, nullptr, nullptr}, }; for (const auto &t : kTests) { + int64_t tt; SCOPED_TRACE(t.time); -#if defined(OPENSSL_WINDOWS) - // Windows |time_t| functions can only handle 1970 through 3000. See - // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/gmtime-s-gmtime32-s-gmtime64-s?view=msvc-160 - if (t.time < 0 || int64_t{t.time} > 32535215999) { - continue; - } -#endif bssl::UniquePtr utc(ASN1_UTCTIME_set(nullptr, t.time)); if (t.utc) { ASSERT_TRUE(utc); EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(utc.get())); EXPECT_EQ(t.utc, ASN1StringToStdString(utc.get())); + EXPECT_TRUE(ASN1Time_check_posix(utc.get(), t.time)); + EXPECT_EQ(ASN1_TIME_to_posix(utc.get(), &tt), 1); + EXPECT_EQ(tt, t.time); + EXPECT_EQ(PrintStringToBIO(utc.get(), &ASN1_UTCTIME_print), t.printed); + EXPECT_EQ(PrintStringToBIO(utc.get(), &ASN1_TIME_print), t.printed); } else { EXPECT_FALSE(utc); } @@ -588,11 +1047,19 @@ TEST(ASN1Test, SetTime) { ASSERT_TRUE(generalized); EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(generalized.get())); EXPECT_EQ(t.generalized, ASN1StringToStdString(generalized.get())); + EXPECT_TRUE(ASN1Time_check_posix(generalized.get(), t.time)); + EXPECT_EQ(ASN1_TIME_to_posix(generalized.get(), &tt), 1); + EXPECT_EQ(tt, t.time); + EXPECT_EQ( + PrintStringToBIO(generalized.get(), &ASN1_GENERALIZEDTIME_print), + t.printed); + EXPECT_EQ(PrintStringToBIO(generalized.get(), &ASN1_TIME_print), + t.printed); } else { EXPECT_FALSE(generalized); } - bssl::UniquePtr choice(ASN1_TIME_set(nullptr, t.time)); + bssl::UniquePtr choice(ASN1_TIME_set_posix(nullptr, t.time)); if (t.generalized) { ASSERT_TRUE(choice); if (t.utc) { @@ -602,12 +1069,122 @@ TEST(ASN1Test, SetTime) { EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(choice.get())); EXPECT_EQ(t.generalized, ASN1StringToStdString(choice.get())); } + EXPECT_TRUE(ASN1Time_check_posix(choice.get(), t.time)); + EXPECT_EQ(ASN1_TIME_to_posix(choice.get(), &tt), 1); + EXPECT_EQ(tt, t.time); } else { EXPECT_FALSE(choice); } } } +TEST(ASN1Test, TimeSetString) { + bssl::UniquePtr s(ASN1_STRING_new()); + ASSERT_TRUE(s); + + ASSERT_TRUE(ASN1_UTCTIME_set_string(s.get(), "700101000000Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_GENERALIZEDTIME_set_string(s.get(), "19700101000000Z")); + EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("19700101000000Z", ASN1StringToStdString(s.get())); + + // |ASN1_TIME_set_string| accepts either format. It relies on there being no + // overlap between the two. + ASSERT_TRUE(ASN1_TIME_set_string(s.get(), "700101000000Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string(s.get(), "19700101000000Z")); + EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("19700101000000Z", ASN1StringToStdString(s.get())); + + // |ASN1_TIME_set_string_X509| behaves similarly except it additionally + // converts GeneralizedTime to UTCTime if it fits. + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "700101000000Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19700101000000Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19500101000000Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("500101000000Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19491231235959Z")); + EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("19491231235959Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "20491231235959Z")); + EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("491231235959Z", ASN1StringToStdString(s.get())); + + ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "20500101000000Z")); + EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get())); + EXPECT_EQ("20500101000000Z", ASN1StringToStdString(s.get())); + + // Invalid inputs are rejected. + EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "nope")); + EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "19700101000000Z")); + EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(s.get(), "nope")); + EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(s.get(), "700101000000Z")); + EXPECT_FALSE(ASN1_TIME_set_string(s.get(), "nope")); + + // If passed a null object, the functions validate the input without writing + // to anything. + EXPECT_TRUE(ASN1_UTCTIME_set_string(nullptr, "700101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "700101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "700101000000Z")); + EXPECT_TRUE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "19700101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "19700101000000Z")); + // Test an input |ASN1_TIME_set_string_X509| won't convert to UTCTime. + EXPECT_TRUE(ASN1_GENERALIZEDTIME_set_string(nullptr, "20500101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "20500101000000Z")); + EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "20500101000000Z")); + EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "nope")); + EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "nope")); + EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "nope")); + EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "nope")); + + // Timezone offsets are not allowed by DER. + EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "700101000000-0400")); + EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "700101000000-0400")); + EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "700101000000-0400")); + EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000-0400")); + EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "19700101000000-0400")); + EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "19700101000000-0400")); +} + +TEST(ASN1Test, AdjTime) { + struct tm tm1, tm2; + int days, secs; + + OPENSSL_posix_to_tm(0, &tm1); + OPENSSL_posix_to_tm(0, &tm2); + // Test values that are too large and should be rejected. + EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MIN, INT_MIN)); + EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MAX, INT_MAX)); + // Basic functionality. + EXPECT_TRUE(OPENSSL_gmtime_adj(&tm2, 1, 1)); + EXPECT_TRUE(OPENSSL_gmtime_diff(&days, &secs, &tm1, &tm2)); + EXPECT_EQ(days, 1); + EXPECT_EQ(secs, 1); + EXPECT_TRUE(OPENSSL_gmtime_diff(&days, &secs, &tm2, &tm1)); + EXPECT_EQ(days, -1); + EXPECT_EQ(secs, -1); + // Test a value of days that is very large, but valid. + EXPECT_TRUE(OPENSSL_gmtime_adj(&tm2, 2932800, 0)); + EXPECT_TRUE(OPENSSL_gmtime_diff(&days, &secs, &tm1, &tm2)); + EXPECT_EQ(days, 2932801); + EXPECT_EQ(secs, 1); + EXPECT_TRUE(OPENSSL_gmtime_diff(&days, &secs, &tm2, &tm1)); + EXPECT_EQ(days, -2932801); + EXPECT_EQ(secs, -1); +} static std::vector StringToVector(const std::string &str) { return std::vector(str.begin(), str.end()); } @@ -681,6 +1258,8 @@ TEST(ASN1Test, StringPrintEx) { // RFC 2253 only escapes spaces at the start and end of a string. {V_ASN1_T61STRING, StringToVector(" "), 0, ASN1_STRFLGS_ESC_2253, "\\ \\ "}, + {V_ASN1_T61STRING, StringToVector(" "), 0, + ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT, "\\ \\ "}, {V_ASN1_T61STRING, StringToVector(" "), 0, ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_QUOTE, "\" \""}, @@ -831,6 +1410,7 @@ TEST(ASN1Test, StringPrintEx) { SCOPED_TRACE(t.flags); bssl::UniquePtr str(ASN1_STRING_type_new(t.type)); + ASSERT_TRUE(str); ASSERT_TRUE(ASN1_STRING_set(str.get(), t.data.data(), t.data.size())); str->flags = t.str_flags; @@ -860,11 +1440,23 @@ TEST(ASN1Test, StringPrintEx) { int str_flags; unsigned long flags; } kUnprintableTests[] = { - // When decoding strings, invalid codepoints are errors. + // It is an error if the string cannot be decoded. {V_ASN1_UTF8STRING, {0xff}, 0, ASN1_STRFLGS_ESC_MSB}, {V_ASN1_BMPSTRING, {0xff}, 0, ASN1_STRFLGS_ESC_MSB}, {V_ASN1_BMPSTRING, {0xff}, 0, ASN1_STRFLGS_ESC_MSB}, {V_ASN1_UNIVERSALSTRING, {0xff}, 0, ASN1_STRFLGS_ESC_MSB}, + // Invalid codepoints are errors. + {V_ASN1_UTF8STRING, {0xed, 0xa0, 0x80}, 0, ASN1_STRFLGS_ESC_MSB}, + {V_ASN1_BMPSTRING, {0xd8, 0x00}, 0, ASN1_STRFLGS_ESC_MSB}, + {V_ASN1_UNIVERSALSTRING, + {0x00, 0x00, 0xd8, 0x00}, + 0, + ASN1_STRFLGS_ESC_MSB}, + // Even when re-encoding UTF-8 back into UTF-8, we should check validity. + {V_ASN1_UTF8STRING, + {0xff}, + 0, + ASN1_STRFLGS_ESC_MSB | ASN1_STRFLGS_UTF8_CONVERT}, }; for (const auto &t : kUnprintableTests) { SCOPED_TRACE(t.type); @@ -873,6 +1465,7 @@ TEST(ASN1Test, StringPrintEx) { SCOPED_TRACE(t.flags); bssl::UniquePtr str(ASN1_STRING_type_new(t.type)); + ASSERT_TRUE(str); ASSERT_TRUE(ASN1_STRING_set(str.get(), t.data.data(), t.data.size())); str->flags = t.str_flags; @@ -1334,27 +1927,6 @@ TEST(ASN1Test, NegativeEnumeratedMultistring) { TestSerialize(str.get(), i2d_ASN1_PRINTABLE, kMinusOne); } -TEST(ASN1Test, PrintableType) { - const struct { - std::vector in; - int result; - } kTests[] = { - {{}, V_ASN1_PRINTABLESTRING}, - {{'a', 'A', '0', '\'', '(', ')', '+', ',', '-', '.', '/', ':', '=', '?'}, - V_ASN1_PRINTABLESTRING}, - {{'*'}, V_ASN1_IA5STRING}, - {{'\0'}, V_ASN1_IA5STRING}, - {{'\0', 'a'}, V_ASN1_IA5STRING}, - {{0, 1, 2, 3, 125, 126, 127}, V_ASN1_IA5STRING}, - {{0, 1, 2, 3, 125, 126, 127, 128}, V_ASN1_T61STRING}, - {{128, 0, 1, 2, 3, 125, 126, 127}, V_ASN1_T61STRING}, - }; - for (const auto &t : kTests) { - SCOPED_TRACE(Bytes(t.in)); - EXPECT_EQ(t.result, ASN1_PRINTABLE_type(t.in.data(), t.in.size())); - } -} - // Encoding a CHOICE type with an invalid selector should fail. TEST(ASN1Test, InvalidChoice) { bssl::UniquePtr name(GENERAL_NAME_new()); @@ -1700,7 +2272,7 @@ TEST(ASN1Test, PrintASN1Object) { std::string(reinterpret_cast(bio_data), bio_len)); } -TEST(ASN1, GetObject) { +TEST(ASN1Test, GetObject) { // The header is valid, but there are not enough bytes for the length. static const uint8_t kTruncated[] = {0x30, 0x01}; const uint8_t *ptr = kTruncated; @@ -1710,10 +2282,181 @@ TEST(ASN1, GetObject) { EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class, sizeof(kTruncated))); + // Indefinite-length encoding is not allowed in DER. static const uint8_t kIndefinite[] = {0x30, 0x80, 0x00, 0x00}; ptr = kIndefinite; EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class, sizeof(kIndefinite))); + + // DER requires lengths be minimally-encoded. This should be {0x30, 0x00}. + static const uint8_t kNonMinimal[] = {0x30, 0x81, 0x00}; + ptr = kNonMinimal; + EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class, + sizeof(kNonMinimal))); + + // This should be {0x04, 0x81, 0x80, ...}. + std::vector non_minimal = {0x04, 0x82, 0x00, 0x80}; + non_minimal.resize(non_minimal.size() + 0x80); + ptr = non_minimal.data(); + EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class, + non_minimal.size())); +} + +template +void ExpectNoParse(T *(*d2i)(T **, const uint8_t **, long), + const std::vector &in) { + SCOPED_TRACE(Bytes(in)); + const uint8_t *ptr = in.data(); + bssl::UniquePtr obj(d2i(nullptr, &ptr, in.size())); + EXPECT_FALSE(obj); +} + +// The zero tag, constructed or primitive, is reserved and should rejected by +// the parser. +TEST(ASN1Test, ZeroTag) { + ExpectNoParse(d2i_ASN1_TYPE, {0x00, 0x00}); + ExpectNoParse(d2i_ASN1_TYPE, {0x00, 0x10, 0x00}); + ExpectNoParse(d2i_ASN1_TYPE, {0x20, 0x00}); + ExpectNoParse(d2i_ASN1_TYPE, {0x20, 0x00}); + ExpectNoParse(d2i_ASN1_SEQUENCE_ANY, {0x30, 0x02, 0x00, 0x00}); + ExpectNoParse(d2i_ASN1_SET_ANY, {0x31, 0x02, 0x00, 0x00}); + // SEQUENCE { + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.1 } + // [UNIVERSAL 0 PRIMITIVE] {} + // } + ExpectNoParse(d2i_X509_ALGOR, + {0x30, 0x10, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x01, 0x00, 0x00}); + // SEQUENCE { + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.1 } + // [UNIVERSAL 0 CONSTRUCTED] {} + // } + ExpectNoParse(d2i_X509_ALGOR, + {0x30, 0x10, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x01, 0x20, 0x00}); + // SEQUENCE { + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.1 } + // [UNIVERSAL 0 PRIMITIVE] { "a" } + // } + ExpectNoParse(d2i_X509_ALGOR, + {0x30, 0x11, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x01, 0x00, 0x01, 0x61}); +} + +TEST(ASN1Test, StringEncoding) { + const struct { + ASN1_STRING *(*d2i)(ASN1_STRING **out, const uint8_t **inp, long len); + std::vector in; + bool valid; + } kTests[] = { + // All OCTET STRINGs are valid. + {d2i_ASN1_OCTET_STRING, {0x04, 0x00}, true}, + {d2i_ASN1_OCTET_STRING, {0x04, 0x01, 0x00}, true}, + + // UTF8String must be valid UTF-8. + {d2i_ASN1_UTF8STRING, {0x0c, 0x00}, true}, + {d2i_ASN1_UTF8STRING, {0x0c, 0x01, 'a'}, true}, + {d2i_ASN1_UTF8STRING, {0x0c, 0x03, 0xe2, 0x98, 0x83}, true}, + // Non-minimal, two-byte UTF-8. + {d2i_ASN1_UTF8STRING, {0x0c, 0x02, 0xc0, 0x81}, false}, + // Truncated, four-byte UTF-8. + {d2i_ASN1_UTF8STRING, {0x0c, 0x03, 0xf0, 0x80, 0x80}, false}, + // Low-surrogate value. + {d2i_ASN1_UTF8STRING, {0x0c, 0x03, 0xed, 0xa0, 0x80}, false}, + // High-surrogate value. + {d2i_ASN1_UTF8STRING, {0x0c, 0x03, 0xed, 0xb0, 0x81}, false}, + + // BMPString must be valid UCS-2. + {d2i_ASN1_BMPSTRING, {0x1e, 0x00}, true}, + {d2i_ASN1_BMPSTRING, {0x1e, 0x02, 0x00, 'a'}, true}, + // Truncated code unit. + {d2i_ASN1_BMPSTRING, {0x1e, 0x01, 'a'}, false}, + // Lone surrogate. + {d2i_ASN1_BMPSTRING, {0x1e, 0x02, 0xd8, 0}, false}, + // BMPString is UCS-2, not UTF-16, so surrogate pairs are also invalid. + {d2i_ASN1_BMPSTRING, {0x1e, 0x04, 0xd8, 0, 0xdc, 1}, false}, + + // UniversalString must be valid UTF-32. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x00}, true}, + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x00, 0x00, 'a'}, true}, + // Maximum code point. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x10, 0xff, 0xfd}, true}, + // Reserved. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x10, 0xff, 0xfe}, false}, + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x10, 0xff, 0xff}, false}, + // Too high. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x11, 0x00, 0x00}, false}, + // Surrogates are not characters. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x04, 0x00, 0x00, 0xd8, 0}, false}, + // Truncated codepoint. + {d2i_ASN1_UNIVERSALSTRING, {0x1c, 0x03, 0x00, 0x00, 0x00}, false}, + + // We interpret T61String as Latin-1, so all inputs are valid. + {d2i_ASN1_T61STRING, {0x14, 0x00}, true}, + {d2i_ASN1_T61STRING, {0x14, 0x01, 0x00}, true}, + }; + for (const auto& t : kTests) { + SCOPED_TRACE(Bytes(t.in)); + const uint8_t *inp; + + if (t.d2i != nullptr) { + inp = t.in.data(); + bssl::UniquePtr str(t.d2i(nullptr, &inp, t.in.size())); + EXPECT_EQ(t.valid, str != nullptr); + } + + // Also test with the ANY parser. + inp = t.in.data(); + bssl::UniquePtr any(d2i_ASN1_TYPE(nullptr, &inp, t.in.size())); + EXPECT_EQ(t.valid, any != nullptr); + } +} + +// Exhaustively test POSIX time conversions for every day across the millenium. +TEST(ASN1Test, POSIXTime) { + const int kDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + // Test the epoch explicitly, to confirm our baseline is correct. + struct tm civil_time; + ASSERT_TRUE(OPENSSL_posix_to_tm(0, &civil_time)); + ASSERT_EQ(civil_time.tm_year + 1900, 1970); + ASSERT_EQ(civil_time.tm_mon + 1, 1); + ASSERT_EQ(civil_time.tm_mday, 1); + ASSERT_EQ(civil_time.tm_hour, 0); + ASSERT_EQ(civil_time.tm_min, 0); + ASSERT_EQ(civil_time.tm_sec, 0); + + int64_t posix_time = -11676096000; // Sat, 01 Jan 1600 00:00:00 +0000 + for (int year = 1600; year < 3000; year++) { + SCOPED_TRACE(year); + bool is_leap_year = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; + for (int month = 1; month <= 12; month++) { + SCOPED_TRACE(month); + int days = kDaysInMonth[month - 1]; + if (month == 2 && is_leap_year) { + days++; + } + for (int day = 1; day <= days; day++) { + SCOPED_TRACE(day); + SCOPED_TRACE(posix_time); + + ASSERT_TRUE(OPENSSL_posix_to_tm(posix_time, &civil_time)); + ASSERT_EQ(civil_time.tm_year + 1900, year); + ASSERT_EQ(civil_time.tm_mon + 1, month); + ASSERT_EQ(civil_time.tm_mday, day); + ASSERT_EQ(civil_time.tm_hour, 0); + ASSERT_EQ(civil_time.tm_min, 0); + ASSERT_EQ(civil_time.tm_sec, 0); + + int64_t posix_time_computed; + ASSERT_TRUE(OPENSSL_tm_to_posix(&civil_time, &posix_time_computed)); + ASSERT_EQ(posix_time_computed, posix_time); + + // Advance to the next day. + posix_time += 24 * 60 * 60; + } + } + } } // The ASN.1 macros do not work on Windows shared library builds, where usage of @@ -1870,4 +2613,286 @@ TEST(ASN1Test, MissingRequiredField) { } } +struct BOOLEANS { + ASN1_BOOLEAN required; + ASN1_BOOLEAN optional; + ASN1_BOOLEAN default_true; + ASN1_BOOLEAN default_false; +}; + +DECLARE_ASN1_FUNCTIONS(BOOLEANS) +ASN1_SEQUENCE(BOOLEANS) = { + ASN1_SIMPLE(BOOLEANS, required, ASN1_BOOLEAN), + ASN1_IMP_OPT(BOOLEANS, optional, ASN1_BOOLEAN, 1), + // Although not actually optional, |ASN1_TBOOLEAN| and |ASN1_FBOOLEAN| need + // to be marked optional in the template. + ASN1_IMP_OPT(BOOLEANS, default_true, ASN1_TBOOLEAN, 2), + ASN1_IMP_OPT(BOOLEANS, default_false, ASN1_FBOOLEAN, 3), +} ASN1_SEQUENCE_END(BOOLEANS) +IMPLEMENT_ASN1_FUNCTIONS(BOOLEANS) + +TEST(ASN1Test, OptionalAndDefaultBooleans) { + std::unique_ptr obj(nullptr, + BOOLEANS_free); + + // A default-constructed object should use, respectively, omitted, omitted, + // TRUE, FALSE. + // + // TODO(davidben): Is the first one a bug? It seems more consistent for a + // required BOOLEAN default to FALSE. |FOO_new| typically default-initializes + // fields valid states. (Though there are exceptions. CHOICE, ANY, and OBJECT + // IDENTIFIER are default-initialized to something invalid.) + obj.reset(BOOLEANS_new()); + ASSERT_TRUE(obj); + EXPECT_EQ(obj->required, ASN1_BOOLEAN_NONE); + EXPECT_EQ(obj->optional, ASN1_BOOLEAN_NONE); + EXPECT_EQ(obj->default_true, ASN1_BOOLEAN_TRUE); + EXPECT_EQ(obj->default_false, ASN1_BOOLEAN_FALSE); + + // Trying to serialize this should fail, because |obj->required| is omitted. + EXPECT_EQ(-1, i2d_BOOLEANS(obj.get(), nullptr)); + + // Otherwise, this object is serializable. Most fields are omitted, due to + // them being optional or defaulted. + static const uint8_t kFieldsOmitted[] = {0x30, 0x03, 0x01, 0x01, 0x00}; + obj->required = 0; + TestSerialize(obj.get(), i2d_BOOLEANS, kFieldsOmitted); + + const uint8_t *der = kFieldsOmitted; + obj.reset(d2i_BOOLEANS(nullptr, &der, sizeof(kFieldsOmitted))); + ASSERT_TRUE(obj); + EXPECT_EQ(obj->required, ASN1_BOOLEAN_FALSE); + EXPECT_EQ(obj->optional, ASN1_BOOLEAN_NONE); + EXPECT_EQ(obj->default_true, ASN1_BOOLEAN_TRUE); + EXPECT_EQ(obj->default_false, ASN1_BOOLEAN_FALSE); + + // Include the optinonal fields instead. + static const uint8_t kFieldsIncluded[] = {0x30, 0x0c, 0x01, 0x01, 0xff, + 0x81, 0x01, 0x00, 0x82, 0x01, + 0x00, 0x83, 0x01, 0xff}; + obj->required = ASN1_BOOLEAN_TRUE; + obj->optional = ASN1_BOOLEAN_FALSE; + obj->default_true = ASN1_BOOLEAN_FALSE; + obj->default_false = ASN1_BOOLEAN_TRUE; + TestSerialize(obj.get(), i2d_BOOLEANS, kFieldsIncluded); + + der = kFieldsIncluded; + obj.reset(d2i_BOOLEANS(nullptr, &der, sizeof(kFieldsIncluded))); + ASSERT_TRUE(obj); + EXPECT_EQ(obj->required, ASN1_BOOLEAN_TRUE); + EXPECT_EQ(obj->optional, ASN1_BOOLEAN_FALSE); + EXPECT_EQ(obj->default_true, ASN1_BOOLEAN_FALSE); + EXPECT_EQ(obj->default_false, ASN1_BOOLEAN_TRUE); + + // TODO(https://crbug.com/boringssl/354): Reject explicit DEFAULTs. +} + +// EXPLICIT_BOOLEAN is a [1] EXPLICIT BOOLEAN. +ASN1_ITEM_TEMPLATE(EXPLICIT_BOOLEAN) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPLICIT, + 1, + EXPLICIT_BOOLEAN, + ASN1_BOOLEAN) +ASN1_ITEM_TEMPLATE_END(EXPLICIT_BOOLEAN) + +// EXPLICIT_OCTET_STRING is a [2] EXPLICIT OCTET STRING. +ASN1_ITEM_TEMPLATE(EXPLICIT_OCTET_STRING) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_EXPLICIT, 2, EXPLICIT_OCTET_STRING, ASN1_OCTET_STRING) +ASN1_ITEM_TEMPLATE_END(EXPLICIT_OCTET_STRING) + +// DOUBLY_TAGGED is +// SEQUENCE { +// b [3] EXPLICIT [1] EXPLICIT BOOLEAN OPTIONAL, +// oct [4] EXPLICIT [2] EXPLICIT OCTET STRING OPTIONAL } +// with explicit tagging. +struct DOUBLY_TAGGED { + ASN1_BOOLEAN b; + ASN1_OCTET_STRING *oct; +}; + +DECLARE_ASN1_FUNCTIONS(DOUBLY_TAGGED) +ASN1_SEQUENCE(DOUBLY_TAGGED) = { + ASN1_EXP_OPT(DOUBLY_TAGGED, b, EXPLICIT_BOOLEAN, 3), + ASN1_EXP_OPT(DOUBLY_TAGGED, oct, EXPLICIT_OCTET_STRING, 4), +} ASN1_SEQUENCE_END(DOUBLY_TAGGED) +IMPLEMENT_ASN1_FUNCTIONS(DOUBLY_TAGGED) + +// Test that optional fields with two layers of explicit tagging are correctly +// handled. +TEST(ASN1Test, DoublyTagged) { + std::unique_ptr obj( + nullptr, DOUBLY_TAGGED_free); + + // Both fields missing. + static const uint8_t kOmitted[] = {0x30, 0x00}; + const uint8_t *inp = kOmitted; + obj.reset(d2i_DOUBLY_TAGGED(nullptr, &inp, sizeof(kOmitted))); + ASSERT_TRUE(obj); + EXPECT_EQ(obj->b, -1); + EXPECT_FALSE(obj->oct); + TestSerialize(obj.get(), i2d_DOUBLY_TAGGED, kOmitted); + + // Both fields present, true and the empty string. + static const uint8_t kTrueEmpty[] = {0x30, 0x0d, 0xa3, 0x05, 0xa1, + 0x03, 0x01, 0x01, 0xff, 0xa4, + 0x04, 0xa2, 0x02, 0x04, 0x00}; + inp = kTrueEmpty; + obj.reset(d2i_DOUBLY_TAGGED(nullptr, &inp, sizeof(kTrueEmpty))); + ASSERT_TRUE(obj); + EXPECT_EQ(obj->b, 0xff); + ASSERT_TRUE(obj->oct); + EXPECT_EQ(ASN1_STRING_length(obj->oct), 0); + TestSerialize(obj.get(), i2d_DOUBLY_TAGGED, kTrueEmpty); +} + +#define CHOICE_TYPE_OCT 0 +#define CHOICE_TYPE_BOOL 1 + +struct CHOICE_TYPE { + int type; + union { + ASN1_OCTET_STRING *oct; + ASN1_BOOLEAN b; + } value; +}; + +DECLARE_ASN1_FUNCTIONS(CHOICE_TYPE) +ASN1_CHOICE(CHOICE_TYPE) = { + ASN1_SIMPLE(CHOICE_TYPE, value.oct, ASN1_OCTET_STRING), + ASN1_SIMPLE(CHOICE_TYPE, value.b, ASN1_BOOLEAN), +} ASN1_CHOICE_END(CHOICE_TYPE) +IMPLEMENT_ASN1_FUNCTIONS(CHOICE_TYPE) + +struct OPTIONAL_CHOICE { + CHOICE_TYPE *choice; +}; + +DECLARE_ASN1_FUNCTIONS(OPTIONAL_CHOICE) +ASN1_SEQUENCE(OPTIONAL_CHOICE) = { + ASN1_OPT(OPTIONAL_CHOICE, choice, CHOICE_TYPE), +} ASN1_SEQUENCE_END(OPTIONAL_CHOICE) +IMPLEMENT_ASN1_FUNCTIONS(OPTIONAL_CHOICE) + +TEST(ASN1Test, OptionalChoice) { + std::unique_ptr obj( + nullptr, OPTIONAL_CHOICE_free); + + // Value omitted. + static const uint8_t kOmitted[] = {0x30, 0x00}; + const uint8_t *inp = kOmitted; + obj.reset(d2i_OPTIONAL_CHOICE(nullptr, &inp, sizeof(kOmitted))); + ASSERT_TRUE(obj); + EXPECT_FALSE(obj->choice); + TestSerialize(obj.get(), i2d_OPTIONAL_CHOICE, kOmitted); + + // Value is present as an OCTET STRING. + static const uint8_t kOct[] = {0x30, 0x02, 0x04, 0x00}; + inp = kOct; + obj.reset(d2i_OPTIONAL_CHOICE(nullptr, &inp, sizeof(kOct))); + ASSERT_TRUE(obj); + ASSERT_TRUE(obj->choice); + ASSERT_EQ(obj->choice->type, CHOICE_TYPE_OCT); + ASSERT_TRUE(obj->choice->value.oct); + EXPECT_EQ(ASN1_STRING_length(obj->choice->value.oct), 0); + TestSerialize(obj.get(), i2d_OPTIONAL_CHOICE, kOct); + + // Value is present as TRUE. + static const uint8_t kTrue[] = {0x30, 0x03, 0x01, 0x01, 0xff}; + inp = kTrue; + obj.reset(d2i_OPTIONAL_CHOICE(nullptr, &inp, sizeof(kTrue))); + ASSERT_TRUE(obj); + ASSERT_TRUE(obj->choice); + ASSERT_EQ(obj->choice->type, CHOICE_TYPE_BOOL); + EXPECT_EQ(obj->choice->value.b, ASN1_BOOLEAN_TRUE); + TestSerialize(obj.get(), i2d_OPTIONAL_CHOICE, kTrue); +} + +struct EMBED_X509 { + X509 *x509; + X509 *x509_opt; + STACK_OF(X509) *x509_seq; +}; + +DECLARE_ASN1_FUNCTIONS(EMBED_X509) +ASN1_SEQUENCE(EMBED_X509) = { + ASN1_SIMPLE(EMBED_X509, x509, X509), + ASN1_EXP_OPT(EMBED_X509, x509_opt, X509, 0), + ASN1_IMP_SEQUENCE_OF_OPT(EMBED_X509, x509_seq, X509, 1), +} ASN1_SEQUENCE_END(EMBED_X509) +IMPLEMENT_ASN1_FUNCTIONS(EMBED_X509) + +// Test that X.509 types defined in this library can be embedded into other +// types, as we rewrite them away from the templating system. +TEST(ASN1Test, EmbedX509) { + // Set up a test certificate. + static const char kTestCert[] = R"( +-----BEGIN CERTIFICATE----- +MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC +QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ +BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l +dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni +v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa +HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw +HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ +BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E +BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ= +-----END CERTIFICATE----- +)"; + bssl::UniquePtr bio(BIO_new_mem_buf(kTestCert, sizeof(kTestCert))); + ASSERT_TRUE(bio); + bssl::UniquePtr cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)); + ASSERT_TRUE(cert); + uint8_t *cert_der = nullptr; + int cert_len = i2d_X509(cert.get(), &cert_der); + ASSERT_GT(cert_len, 0); + bssl::UniquePtr free_cert_der(cert_der); + + std::unique_ptr obj(nullptr, + EMBED_X509_free); + + // Test only the first field present. + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 64)); + CBB seq; + ASSERT_TRUE(CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE)); + ASSERT_TRUE(CBB_add_bytes(&seq, cert_der, cert_len)); + ASSERT_TRUE(CBB_flush(cbb.get())); + const uint8_t *ptr = CBB_data(cbb.get()); + obj.reset(d2i_EMBED_X509(nullptr, &ptr, CBB_len(cbb.get()))); + ASSERT_TRUE(obj); + ASSERT_TRUE(obj->x509); + EXPECT_EQ(X509_cmp(obj->x509, cert.get()), 0); + EXPECT_FALSE(obj->x509_opt); + EXPECT_FALSE(obj->x509_seq); + TestSerialize(obj.get(), i2d_EMBED_X509, + {CBB_data(cbb.get()), CBB_len(cbb.get())}); + + // Test all fields present. + cbb.Reset(); + ASSERT_TRUE(CBB_init(cbb.get(), 64)); + ASSERT_TRUE(CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE)); + ASSERT_TRUE(CBB_add_bytes(&seq, cert_der, cert_len)); + CBB child; + ASSERT_TRUE(CBB_add_asn1( + &seq, &child, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)); + ASSERT_TRUE(CBB_add_bytes(&child, cert_der, cert_len)); + ASSERT_TRUE(CBB_add_asn1( + &seq, &child, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)); + ASSERT_TRUE(CBB_add_bytes(&child, cert_der, cert_len)); + ASSERT_TRUE(CBB_add_bytes(&child, cert_der, cert_len)); + ASSERT_TRUE(CBB_flush(cbb.get())); + ptr = CBB_data(cbb.get()); + obj.reset(d2i_EMBED_X509(nullptr, &ptr, CBB_len(cbb.get()))); + ASSERT_TRUE(obj); + ASSERT_TRUE(obj->x509); + EXPECT_EQ(X509_cmp(obj->x509, cert.get()), 0); + ASSERT_TRUE(obj->x509_opt); + EXPECT_EQ(X509_cmp(obj->x509_opt, cert.get()), 0); + ASSERT_EQ(sk_X509_num(obj->x509_seq), 2u); + EXPECT_EQ(X509_cmp(sk_X509_value(obj->x509_seq, 0), cert.get()), 0); + EXPECT_EQ(X509_cmp(sk_X509_value(obj->x509_seq, 1), cert.get()), 0); + TestSerialize(obj.get(), i2d_EMBED_X509, + {CBB_data(cbb.get()), CBB_len(cbb.get())}); +} + #endif // !WINDOWS || !SHARED_LIBRARY diff --git a/third_party/boringssl/kit/src/crypto/asn1/asn_pack.c b/third_party/boringssl/kit/src/crypto/asn1/asn_pack.c index 9124f23d..c42cc05e 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/asn_pack.c +++ b/third_party/boringssl/kit/src/crypto/asn1/asn_pack.c @@ -60,42 +60,39 @@ #include -ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **out) -{ - uint8_t *new_data = NULL; - int len = ASN1_item_i2d(obj, &new_data, it); - if (len <= 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR); - return NULL; - } +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **out) { + uint8_t *new_data = NULL; + int len = ASN1_item_i2d(obj, &new_data, it); + if (len <= 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR); + return NULL; + } - ASN1_STRING *ret = NULL; - if (out == NULL || *out == NULL) { - ret = ASN1_STRING_new(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - OPENSSL_free(new_data); - return NULL; - } - } else { - ret = *out; + ASN1_STRING *ret = NULL; + if (out == NULL || *out == NULL) { + ret = ASN1_STRING_new(); + if (ret == NULL) { + OPENSSL_free(new_data); + return NULL; } + } else { + ret = *out; + } - ASN1_STRING_set0(ret, new_data, len); - if (out != NULL) { - *out = ret; - } - return ret; + ASN1_STRING_set0(ret, new_data, len); + if (out != NULL) { + *out = ret; + } + return ret; } -void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) -{ - const unsigned char *p = oct->data; - void *ret = ASN1_item_d2i(NULL, &p, oct->length, it); - if (ret == NULL || p != oct->data + oct->length) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - ASN1_item_free(ret, it); - return NULL; - } - return ret; +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) { + const unsigned char *p = oct->data; + void *ret = ASN1_item_d2i(NULL, &p, oct->length, it); + if (ret == NULL || p != oct->data + oct->length) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + ASN1_item_free(ret, it); + return NULL; + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/charmap.h b/third_party/boringssl/kit/src/crypto/asn1/charmap.h deleted file mode 100644 index 3305ad14..00000000 --- a/third_party/boringssl/kit/src/crypto/asn1/charmap.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Auto generated with chartype.pl script. Mask of various character - * properties - */ - -static const unsigned char char_type[] = { - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2 -}; diff --git a/third_party/boringssl/kit/src/crypto/asn1/charmap.pl b/third_party/boringssl/kit/src/crypto/asn1/charmap.pl deleted file mode 100644 index 117ed32f..00000000 --- a/third_party/boringssl/kit/src/crypto/asn1/charmap.pl +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/local/bin/perl -w - -# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project -# 2000. -# -# ==================================================================== -# Copyright (c) 2000 The OpenSSL Project. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. All advertising materials mentioning features or use of this -# software must display the following acknowledgment: -# "This product includes software developed by the OpenSSL Project -# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" -# -# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to -# endorse or promote products derived from this software without -# prior written permission. For written permission, please contact -# licensing@OpenSSL.org. -# -# 5. Products derived from this software may not be called "OpenSSL" -# nor may "OpenSSL" appear in their names without prior written -# permission of the OpenSSL Project. -# -# 6. Redistributions of any form whatsoever must retain the following -# acknowledgment: -# "This product includes software developed by the OpenSSL Project -# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" -# -# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR -# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# ==================================================================== -# -# This product includes cryptographic software written by Eric Young -# (eay@cryptsoft.com). This product includes software written by Tim -# Hudson (tjh@cryptsoft.com). - -use strict; - -my ($i, @arr); - -# Set up an array with the type of ASCII characters -# Each set bit represents a character property. - -# RFC 2253 character properties -my $RFC2253_ESC = 1; # Character escaped with \ -my $ESC_CTRL = 2; # Escaped control character -# These are used with RFC 1779 quoting using " -my $NOESC_QUOTE = 8; # Not escaped if quoted -my $PSTRING_CHAR = 0x10; # Valid PrintableString character -my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character -my $RFC2253_LAST_ESC = 0x40; # Escaped with \ if last character - -for($i = 0; $i < 128; $i++) { - # Set the RFC 2253 escape characters (control) - $arr[$i] = 0; - if(($i < 32) || ($i > 126)) { - $arr[$i] |= $ESC_CTRL; - } - - # Some PrintableString characters - if( ( ( $i >= ord("a")) && ( $i <= ord("z")) ) - || ( ( $i >= ord("A")) && ( $i <= ord("Z")) ) - || ( ( $i >= ord("0")) && ( $i <= ord("9")) ) ) { - $arr[$i] |= $PSTRING_CHAR; - } -} - -# Now setup the rest - -# Remaining RFC 2253 escaped characters - -$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC; -$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC; - -$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC; -$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC; -$arr[ord("\"")] |= $RFC2253_ESC; -$arr[ord("\\")] |= $RFC2253_ESC; -$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC; -$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC; -$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC; - -# Remaining PrintableString characters - -$arr[ord(" ")] |= $PSTRING_CHAR; -$arr[ord("'")] |= $PSTRING_CHAR; -$arr[ord("(")] |= $PSTRING_CHAR; -$arr[ord(")")] |= $PSTRING_CHAR; -$arr[ord("+")] |= $PSTRING_CHAR; -$arr[ord(",")] |= $PSTRING_CHAR; -$arr[ord("-")] |= $PSTRING_CHAR; -$arr[ord(".")] |= $PSTRING_CHAR; -$arr[ord("/")] |= $PSTRING_CHAR; -$arr[ord(":")] |= $PSTRING_CHAR; -$arr[ord("=")] |= $PSTRING_CHAR; -$arr[ord("?")] |= $PSTRING_CHAR; - -# Now generate the C code - -print < -int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) -{ - int i, n = 0; - static const char *h = "0123456789ABCDEF"; - char buf[2]; +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) { + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; - if (a == NULL) - return (0); + if (a == NULL) { + return 0; + } - if (a->type & V_ASN1_NEG) { - if (BIO_write(bp, "-", 1) != 1) - goto err; - n = 1; + if (a->type & V_ASN1_NEG) { + if (BIO_write(bp, "-", 1) != 1) { + goto err; } + n = 1; + } - if (a->length == 0) { - if (BIO_write(bp, "00", 2) != 2) - goto err; - n += 2; - } else { - for (i = 0; i < a->length; i++) { - if ((i != 0) && (i % 35 == 0)) { - if (BIO_write(bp, "\\\n", 2) != 2) - goto err; - n += 2; - } - buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; - buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; - if (BIO_write(bp, buf, 2) != 2) - goto err; - n += 2; + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) { + goto err; + } + n += 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) { + goto err; } + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) { + goto err; + } + n += 2; } - return (n); - err: - return (-1); + } + return n; +err: + return -1; } -int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a) -{ - return i2a_ASN1_INTEGER(bp, a); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a) { + return i2a_ASN1_INTEGER(bp, a); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/f_string.c b/third_party/boringssl/kit/src/crypto/asn1/f_string.c index 01d9dec0..4bc81107 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/f_string.c +++ b/third_party/boringssl/kit/src/crypto/asn1/f_string.c @@ -58,34 +58,37 @@ #include -int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type) -{ - int i, n = 0; - static const char *h = "0123456789ABCDEF"; - char buf[2]; +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type) { + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; - if (a == NULL) - return (0); + if (a == NULL) { + return 0; + } - if (a->length == 0) { - if (BIO_write(bp, "0", 1) != 1) - goto err; - n = 1; - } else { - for (i = 0; i < a->length; i++) { - if ((i != 0) && (i % 35 == 0)) { - if (BIO_write(bp, "\\\n", 2) != 2) - goto err; - n += 2; - } - buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; - buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; - if (BIO_write(bp, buf, 2) != 2) - goto err; - n += 2; - } + if (a->length == 0) { + if (BIO_write(bp, "0", 1) != 1) { + goto err; } - return (n); - err: - return (-1); + n = 1; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) { + goto err; + } + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) { + goto err; + } + n += 2; + } + } + return n; +err: + return -1; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/internal.h b/third_party/boringssl/kit/src/crypto/asn1/internal.h index 5bdaac8f..5dca7280 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/internal.h +++ b/third_party/boringssl/kit/src/crypto/asn1/internal.h @@ -56,8 +56,8 @@ * */ -#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H -#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#ifndef OPENSSL_HEADER_ASN1_INTERNAL_H +#define OPENSSL_HEADER_ASN1_INTERNAL_H #include @@ -69,105 +69,118 @@ extern "C" { #endif -/* Wrapper functions for time functions. */ +// Wrapper functions for time functions. -/* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */ -struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); +// OPENSSL_gmtime converts a time_t value in |time| which must be in the range +// of year 0000 to 9999 to a broken out time value in |tm|. On success |tm| is +// returned. On failure NULL is returned. +OPENSSL_EXPORT struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); -/* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec| - * seconds. */ -int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +// OPENSSL_timegm converts a time value between the years 0 and 9999 in |tm| to +// a time_t value in |out|. One is returned on success, zero is returned on +// failure. It is a failure if the converted time can not be represented in a +// time_t, or if the tm contains out of range values. +OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out); -/* OPENSSL_gmtime_diff calculates the difference between |from| and |to| and - * outputs the difference as a number of days and seconds in |*out_days| and - * |*out_secs|. */ -int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, - const struct tm *to); +// OPENSSL_gmtime_adj returns one on success, and updates |tm| by adding +// |offset_day| days and |offset_sec| seconds. It returns zero on failure. |tm| +// must be in the range of year 0000 to 9999 both before and after the update or +// a failure will be returned. +OPENSSL_EXPORT int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, + long offset_sec); +// OPENSSL_gmtime_diff calculates the difference between |from| and |to|. It +// returns one, and outputs the difference as a number of days and seconds in +// |*out_days| and |*out_secs| on success. It returns zero on failure. Both +// |from| and |to| must be in the range of year 0000 to 9999 or a failure will +// be returned. +OPENSSL_EXPORT int OPENSSL_gmtime_diff(int *out_days, int *out_secs, + const struct tm *from, + const struct tm *to); -/* Internal ASN1 structures and functions: not for application use */ +// Internal ASN1 structures and functions: not for application use -/* These are used internally in the ASN1_OBJECT to keep track of - * whether the names and data need to be free()ed */ -#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ -#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */ -#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */ +// These are used internally in the ASN1_OBJECT to keep track of +// whether the names and data need to be free()ed +#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 // internal use +#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 // internal use +#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 // internal use -/* An asn1_object_st (aka |ASN1_OBJECT|) represents an ASN.1 OBJECT IDENTIFIER. - * Note: Mutating an |ASN1_OBJECT| is only permitted when initializing it. The - * library maintains a table of static |ASN1_OBJECT|s, which may be referenced - * by non-const |ASN1_OBJECT| pointers. Code which receives an |ASN1_OBJECT| - * pointer externally must assume it is immutable, even if the pointer is not - * const. */ +// An asn1_object_st (aka |ASN1_OBJECT|) represents an ASN.1 OBJECT IDENTIFIER. +// Note: Mutating an |ASN1_OBJECT| is only permitted when initializing it. The +// library maintains a table of static |ASN1_OBJECT|s, which may be referenced +// by non-const |ASN1_OBJECT| pointers. Code which receives an |ASN1_OBJECT| +// pointer externally must assume it is immutable, even if the pointer is not +// const. struct asn1_object_st { const char *sn, *ln; int nid; int length; - const unsigned char *data; /* data remains const after init */ - int flags; /* Should we free this one */ + const unsigned char *data; // data remains const after init + int flags; // Should we free this one }; ASN1_OBJECT *ASN1_OBJECT_new(void); -// ASN1_ENCODING structure: this is used to save the received -// encoding of an ASN1 type. This is useful to get round -// problems with invalid encodings which can break signatures. +// ASN1_ENCODING is used to save the received encoding of an ASN.1 type. This +// avoids problems with invalid encodings that break signatures. typedef struct ASN1_ENCODING_st { - unsigned char *enc; // DER encoding - long len; // Length of encoding - int modified; // set to 1 if 'enc' is invalid - // alias_only is zero if |enc| owns the buffer that it points to - // (although |enc| may still be NULL). If one, |enc| points into a - // buffer that is owned elsewhere. - unsigned alias_only : 1; - // alias_only_on_next_parse is one iff the next parsing operation - // should avoid taking a copy of the input and rather set - // |alias_only|. - unsigned alias_only_on_next_parse : 1; + // enc is the saved DER encoding. Its ownership is determined by |buf|. + uint8_t *enc; + // len is the length of |enc|. If zero, there is no saved encoding. + size_t len; + // buf, if non-NULL, is the |CRYPTO_BUFFER| that |enc| points into. If NULL, + // |enc| must be released with |OPENSSL_free|. + CRYPTO_BUFFER *buf; } ASN1_ENCODING; -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); - -void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); - -int UTF8_getc(const unsigned char *str, int len, uint32_t *val); -int UTF8_putc(unsigned char *str, int len, uint32_t value); +OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, + int allow_timezone_offset); +OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, + const ASN1_GENERALIZEDTIME *d); int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +// ASN1_item_ex_d2i parses |len| bytes from |*in| as a structure of type |it| +// and writes the result to |*pval|. If |tag| is non-negative, |it| is +// implicitly tagged with the tag specified by |tag| and |aclass|. If |opt| is +// non-zero, the value is optional. If |buf| is non-NULL, |*in| must point into +// |buf|. +// +// This function returns one and advances |*in| if an object was successfully +// parsed, -1 if an optional value was successfully skipped, and zero on error. int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, - ASN1_TLC *ctx); + CRYPTO_BUFFER *buf); -/* ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the - * i2d output convention. It returns a non-zero length on success and -1 on - * error. If |tag| is -1. the tag and class come from |it|. Otherwise, the tag - * number is |tag| and the class is |aclass|. This is used for implicit tagging. - * This function treats a missing value as an error, not an optional field. */ +// ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the +// i2d output convention. It returns a non-zero length on success and -1 on +// error. If |tag| is -1. the tag and class come from |it|. Otherwise, the tag +// number is |tag| and the class is |aclass|. This is used for implicit tagging. +// This function treats a missing value as an error, not an optional field. int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -/* asn1_get_choice_selector returns the CHOICE selector value for |*pval|, which - * must of type |it|. */ +// asn1_get_choice_selector returns the CHOICE selector value for |*pval|, which +// must of type |it|. int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); -/* asn1_get_field_ptr returns a pointer to the field in |*pval| corresponding to - * |tt|. */ +// asn1_get_field_ptr returns a pointer to the field in |*pval| corresponding to +// |tt|. ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -/* asn1_do_adb returns the |ASN1_TEMPLATE| for the ANY DEFINED BY field |tt|, - * based on the selector INTEGER or OID in |*pval|. If |tt| is not an ADB field, - * it returns |tt|. If the selector does not match any value, it returns NULL. - * If |nullerr| is non-zero, it will additionally push an error to the error - * queue when there is no match. */ +// asn1_do_adb returns the |ASN1_TEMPLATE| for the ANY DEFINED BY field |tt|, +// based on the selector INTEGER or OID in |*pval|. If |tt| is not an ADB field, +// it returns |tt|. If the selector does not match any value, it returns NULL. +// If |nullerr| is non-zero, it will additionally push an error to the error +// queue when there is no match. const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr); @@ -177,29 +190,39 @@ int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it); void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -/* asn1_enc_restore, if |*pval| has a saved encoding, writes it to |out| under - * the i2d output convention, sets |*len| to the length, and returns one. If it - * has no saved encoding, it returns zero. */ +// asn1_enc_restore, if |*pval| has a saved encoding, writes it to |out| under +// the i2d output convention, sets |*len| to the length, and returns one. If it +// has no saved encoding, it returns zero. int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it); +// asn1_enc_save saves |inlen| bytes from |in| as |*pval|'s saved encoding. It +// returns one on success and zero on error. If |buf| is non-NULL, |in| must +// point into |buf|. +int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t inlen, + const ASN1_ITEM *it, CRYPTO_BUFFER *buf); -/* asn1_type_value_as_pointer returns |a|'s value in pointer form. This is - * usually the value object but, for BOOLEAN values, is 0 or 0xff cast to - * a pointer. */ +// asn1_encoding_clear clears the cached encoding in |enc|. +void asn1_encoding_clear(ASN1_ENCODING *enc); + +// asn1_type_value_as_pointer returns |a|'s value in pointer form. This is +// usually the value object but, for BOOLEAN values, is 0 or 0xff cast to +// a pointer. const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); -/* asn1_is_printable returns one if |value| is a valid Unicode codepoint for an - * ASN.1 PrintableString, and zero otherwise. */ +// asn1_type_cleanup releases memory associated with |a|'s value, without +// freeing |a| itself. +void asn1_type_cleanup(ASN1_TYPE *a); + +// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an +// ASN.1 PrintableString, and zero otherwise. int asn1_is_printable(uint32_t value); -/* asn1_bit_string_length returns the number of bytes in |str| and sets - * |*out_padding_bits| to the number of padding bits. - * - * This function should be used instead of |ASN1_STRING_length| to correctly - * handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. */ +// asn1_bit_string_length returns the number of bytes in |str| and sets +// |*out_padding_bits| to the number of padding bits. +// +// This function should be used instead of |ASN1_STRING_length| to correctly +// handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. int asn1_bit_string_length(const ASN1_BIT_STRING *str, uint8_t *out_padding_bits); @@ -211,14 +234,36 @@ typedef struct { unsigned long flags; } ASN1_STRING_TABLE; -/* asn1_get_string_table_for_testing sets |*out_ptr| and |*out_len| to the table - * of built-in |ASN1_STRING_TABLE| values. It is exported for testing. */ +// asn1_get_string_table_for_testing sets |*out_ptr| and |*out_len| to the table +// of built-in |ASN1_STRING_TABLE| values. It is exported for testing. OPENSSL_EXPORT void asn1_get_string_table_for_testing( const ASN1_STRING_TABLE **out_ptr, size_t *out_len); +typedef ASN1_VALUE *ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, + long length); +typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int opt, ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef struct ASN1_EXTERN_FUNCS_st { + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; +} ASN1_EXTERN_FUNCS; + #if defined(__cplusplus) -} /* extern C */ +} // extern C #endif -#endif /* OPENSSL_HEADER_ASN1_ASN1_LOCL_H */ +#endif // OPENSSL_HEADER_ASN1_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/asn1/posix_time.c b/third_party/boringssl/kit/src/crypto/asn1/posix_time.c new file mode 100644 index 00000000..31d184c0 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/asn1/posix_time.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Time conversion to/from POSIX time_t and struct tm, with no support +// for time zones other than UTC + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" + +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (24 * SECS_PER_HOUR) + + +// Is a year/month/day combination valid, in the range from year 0000 +// to 9999? +static int is_valid_date(int year, int month, int day) { + if (day < 1 || month < 1 || year < 0 || year > 9999) { + return 0; + } + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return day > 0 && day <= 31; + case 4: + case 6: + case 9: + case 11: + return day > 0 && day <= 30; + case 2: + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { + return day > 0 && day <= 29; + } else { + return day > 0 && day <= 28; + } + default: + return 0; + } +} + +// Is a time valid? Leap seconds of 60 are not considered valid, as +// the POSIX time in seconds does not include them. +static int is_valid_time(int hours, int minutes, int seconds) { + if (hours < 0 || minutes < 0 || seconds < 0 || hours > 23 || minutes > 59 || + seconds > 59) { + return 0; + } + return 1; +} + +// Is a int64 time representing a time within our expected range? +static int is_valid_epoch_time(int64_t time) { + // 0000-01-01 00:00:00 UTC to 9999-12-31 23:59:59 UTC + return (int64_t)-62167219200 <= time && time <= (int64_t)253402300799; +} + +// Inspired by algorithms presented in +// https://howardhinnant.github.io/date_algorithms.html +// (Public Domain) +static int posix_time_from_utc(int year, int month, int day, int hours, + int minutes, int seconds, int64_t *out_time) { + if (!is_valid_date(year, month, day) || + !is_valid_time(hours, minutes, seconds)) { + return 0; + } + if (month <= 2) { + year--; // Start years on Mar 1, so leap days always finish a year. + } + // At this point year will be in the range -1 and 9999. + assert(-1 <= year && year <= 9999); + int64_t era = (year >= 0 ? year : year - 399) / 400; + int64_t year_of_era = year - era * 400; + int64_t day_of_year = + (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1; + int64_t day_of_era = + year_of_era * 365 + year_of_era / 4 - year_of_era / 100 + day_of_year; + int64_t posix_days = era * 146097 + day_of_era - 719468; + *out_time = posix_days * SECS_PER_DAY + hours * SECS_PER_HOUR + minutes * 60 + + seconds; + return 1; +} + +// Inspired by algorithms presented in +// https://howardhinnant.github.io/date_algorithms.html +// (Public Domain) +static int utc_from_posix_time(int64_t time, int *out_year, int *out_month, + int *out_day, int *out_hours, int *out_minutes, + int *out_seconds) { + if (!is_valid_epoch_time(time)) { + return 0; + } + int64_t days = time / SECS_PER_DAY; + int64_t leftover_seconds = time % SECS_PER_DAY; + if (leftover_seconds < 0) { + days--; + leftover_seconds += SECS_PER_DAY; + } + days += 719468; // Shift to starting epoch of Mar 1 0000. + // At this point, days will be in the range -61 and 3652364. + assert(-61 <= days && days <= 3652364); + int64_t era = (days > 0 ? days : days - 146096) / 146097; + int64_t day_of_era = days - era * 146097; + int64_t year_of_era = (day_of_era - day_of_era / 1460 + day_of_era / 36524 - + day_of_era / 146096) / + 365; + *out_year = (int)(year_of_era + era * 400); // Year starting on Mar 1. + int64_t day_of_year = + day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100); + int64_t month_of_year = (5 * day_of_year + 2) / 153; + *out_month = + (int)(month_of_year < 10 ? month_of_year + 3 : month_of_year - 9); + if (*out_month <= 2) { + (*out_year)++; // Adjust year back to Jan 1 start of year. + } + *out_day = (int)(day_of_year - (153 * month_of_year + 2) / 5 + 1); + *out_hours = (int)(leftover_seconds / SECS_PER_HOUR); + leftover_seconds %= SECS_PER_HOUR; + *out_minutes = (int)(leftover_seconds / 60); + *out_seconds = (int)(leftover_seconds % 60); + return 1; +} + +int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out) { + return posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, out); +} + +int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm) { + memset(out_tm, 0, sizeof(struct tm)); + if (!utc_from_posix_time(time, &out_tm->tm_year, &out_tm->tm_mon, + &out_tm->tm_mday, &out_tm->tm_hour, &out_tm->tm_min, + &out_tm->tm_sec)) { + return 0; + } + out_tm->tm_year -= 1900; + out_tm->tm_mon -= 1; + + return 1; +} + +int OPENSSL_timegm(const struct tm *tm, time_t *out) { + static_assert( + sizeof(time_t) == sizeof(int32_t) || sizeof(time_t) == sizeof(int64_t), + "time_t is broken"); + int64_t posix_time; + if (!OPENSSL_tm_to_posix(tm, &posix_time)) { + return 0; + } + if (sizeof(time_t) == sizeof(int32_t) && + (posix_time > INT32_MAX || posix_time < INT32_MIN)) { + return 0; + } + *out = (time_t)posix_time; + return 1; +} + +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *out_tm) { + static_assert( + sizeof(time_t) == sizeof(int32_t) || sizeof(time_t) == sizeof(int64_t), + "time_t is broken"); + int64_t posix_time = *time; + if (!OPENSSL_posix_to_tm(posix_time, out_tm)) { + return NULL; + } + return out_tm; +} + +int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { + int64_t posix_time; + if (!posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, &posix_time)) { + return 0; + } + if (!utc_from_posix_time( + posix_time + (int64_t)off_day * SECS_PER_DAY + offset_sec, + &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min, + &tm->tm_sec)) { + return 0; + } + tm->tm_year -= 1900; + tm->tm_mon -= 1; + + return 1; +} + +int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, + const struct tm *to) { + int64_t time_to; + if (!posix_time_from_utc(to->tm_year + 1900, to->tm_mon + 1, to->tm_mday, + to->tm_hour, to->tm_min, to->tm_sec, &time_to)) { + return 0; + } + int64_t time_from; + if (!posix_time_from_utc(from->tm_year + 1900, from->tm_mon + 1, + from->tm_mday, from->tm_hour, from->tm_min, + from->tm_sec, &time_from)) { + return 0; + } + int64_t timediff = time_to - time_from; + int64_t daydiff = timediff / SECS_PER_DAY; + timediff %= SECS_PER_DAY; + if (daydiff > INT_MAX || daydiff < INT_MIN) { + return 0; + } + *out_secs = (int)timediff; + *out_days = (int)daydiff; + return 1; +} diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_dec.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_dec.c index beb9a0b2..24ab04f2 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_dec.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_dec.c @@ -55,758 +55,771 @@ * [including the GNU Public Licence.] */ #include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include - +#include "../bytestring/internal.h" #include "../internal.h" #include "internal.h" -/* - * Constructed types with a recursive definition (such as can be found in PKCS7) - * could eventually exceed the stack given malicious input with excessive - * recursion. Therefore we limit the stack depth. This is the maximum number of - * recursive invocations of asn1_item_embed_d2i(). - */ +// Constructed types with a recursive definition (such as can be found in PKCS7) +// could eventually exceed the stack given malicious input with excessive +// recursion. Therefore we limit the stack depth. This is the maximum number of +// recursive invocations of asn1_item_embed_d2i(). #define ASN1_MAX_CONSTRUCTED_NEST 30 -static int asn1_check_eoc(const unsigned char **in, long len); - static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *cst, const unsigned char **in, long len, - int exptag, int expclass, char opt, ASN1_TLC *ctx); + int exptag, int expclass, char opt); -static int asn1_template_ex_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); -static int asn1_template_noexp_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, +static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_TEMPLATE *tt, char opt, + CRYPTO_BUFFER *buf, int depth); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_TEMPLATE *tt, char opt, + CRYPTO_BUFFER *buf, int depth); +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, int utype, const ASN1_ITEM *it); -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, - ASN1_TLC *ctx); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, + int aclass, char opt); +static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, int aclass, + char opt, CRYPTO_BUFFER *buf, int depth); -/* Table to convert tags to bit values, used for MSTRING type */ -static const unsigned long tag2bit[32] = { - 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ - B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */ - B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags - * 8-11 */ - B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags - * 12-15 - */ - B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags - * 16-19 - */ - B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */ - B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ - B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags - * 25-27 */ - B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags - * 28-31 - */ +// Table to convert tags to bit values, used for MSTRING type +static const unsigned long tag2bit[31] = { + 0, // (reserved) + 0, // BOOLEAN + 0, // INTEGER + B_ASN1_BIT_STRING, + B_ASN1_OCTET_STRING, + 0, // NULL + 0, // OBJECT IDENTIFIER + B_ASN1_UNKNOWN, // ObjectDescriptor + B_ASN1_UNKNOWN, // EXTERNAL + B_ASN1_UNKNOWN, // REAL + B_ASN1_UNKNOWN, // ENUMERATED + B_ASN1_UNKNOWN, // EMBEDDED PDV + B_ASN1_UTF8STRING, + B_ASN1_UNKNOWN, // RELATIVE-OID + B_ASN1_UNKNOWN, // TIME + B_ASN1_UNKNOWN, // (reserved) + B_ASN1_SEQUENCE, + 0, // SET + B_ASN1_NUMERICSTRING, + B_ASN1_PRINTABLESTRING, + B_ASN1_T61STRING, + B_ASN1_VIDEOTEXSTRING, + B_ASN1_IA5STRING, + B_ASN1_UTCTIME, + B_ASN1_GENERALIZEDTIME, + B_ASN1_GRAPHICSTRING, + B_ASN1_ISO64STRING, + B_ASN1_GENERALSTRING, + B_ASN1_UNIVERSALSTRING, + B_ASN1_UNKNOWN, // CHARACTER STRING + B_ASN1_BMPSTRING, }; -unsigned long ASN1_tag2bit(int tag) -{ - if ((tag < 0) || (tag > 30)) - return 0; - return tag2bit[tag]; +unsigned long ASN1_tag2bit(int tag) { + if (tag < 0 || tag > 30) { + return 0; + } + return tag2bit[tag]; } -/* Macro to initialize and invalidate the cache */ - -#define asn1_tlc_clear(c) if (c) (c)->valid = 0 -/* Version to avoid compiler warning about 'c' always non-NULL */ -#define asn1_tlc_clear_nc(c) (c)->valid = 0 - -/* - * Decode an ASN1 item, this currently behaves just like a standard 'd2i' - * function. 'in' points to a buffer to read the data from, in future we - * will have more advanced versions that can input data a piece at a time and - * this will simply be a special case. - */ - -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it) -{ - ASN1_TLC c; - ASN1_VALUE *ptmpval = NULL; - if (!pval) - pval = &ptmpval; - asn1_tlc_clear_nc(&c); - if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) - return *pval; - return NULL; +static int is_supported_universal_type(int tag, int aclass) { + if (aclass != V_ASN1_UNIVERSAL) { + return 0; + } + return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN || + tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER || + tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING || + tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING || + tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING || + tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME || + tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING || + tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING || + tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING || + tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET || + tag == V_ASN1_SEQUENCE; } -/* - * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and - * tag mismatch return -1 to handle OPTIONAL - */ +// Macro to initialize and invalidate the cache + +// Decode an ASN1 item, this currently behaves just like a standard 'd2i' +// function. 'in' points to a buffer to read the data from, in future we +// will have more advanced versions that can input data a piece at a time and +// this will simply be a special case. + +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it) { + ASN1_VALUE *ret = NULL; + if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0, + /*buf=*/NULL, /*depth=*/0) <= 0) { + // Clean up, in case the caller left a partial object. + // + // TODO(davidben): I don't think it can leave one, but the codepaths below + // are a bit inconsistent. Revisit this when rewriting this function. + ASN1_item_ex_free(&ret, it); + } + + // If the caller supplied an output pointer, free the old one and replace it + // with |ret|. This differs from OpenSSL slightly in that we don't support + // object reuse. We run this on both success and failure. On failure, even + // with object reuse, OpenSSL destroys the previous object. + if (pval != NULL) { + ASN1_item_ex_free(pval, it); + *pval = ret; + } + return ret; +} + +// Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and +// tag mismatch return -1 to handle OPTIONAL +// +// TODO(davidben): Historically, all functions in this file had to account for +// |*pval| containing an arbitrary existing value. This is no longer the case +// because |ASN1_item_d2i| now always starts from NULL. As part of rewriting +// this function, take the simplified assumptions into account. Though we must +// still account for the internal calls to |ASN1_item_ex_new|. static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, ASN1_TLC *ctx, int depth) -{ - const ASN1_TEMPLATE *tt, *errtt = NULL; - const ASN1_EXTERN_FUNCS *ef; - const unsigned char *p = NULL, *q; - unsigned char oclass; - char cst, isopt; - int i; - int otag; - int ret = 0; - ASN1_VALUE **pchptr; - int combine = aclass & ASN1_TFLG_COMBINE; - aclass &= ~ASN1_TFLG_COMBINE; - if (!pval) - return 0; + char opt, CRYPTO_BUFFER *buf, int depth) { + const ASN1_TEMPLATE *tt, *errtt = NULL; + const unsigned char *p = NULL, *q; + unsigned char oclass; + char cst, isopt; + int i; + int otag; + int ret = 0; + ASN1_VALUE **pchptr; + if (!pval) { + return 0; + } - /* - * Bound |len| to comfortably fit in an int. Lengths in this module often - * switch between int and long without overflow checks. - */ - if (len > INT_MAX/2) { - len = INT_MAX/2; - } + if (buf != NULL) { + assert(CRYPTO_BUFFER_data(buf) <= *in && + *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + } - if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP); - goto err; - } + // Bound |len| to comfortably fit in an int. Lengths in this module often + // switch between int and long without overflow checks. + if (len > INT_MAX / 2) { + len = INT_MAX / 2; + } - switch (it->itype) { + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP); + goto err; + } + + switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - /* - * tagging or OPTIONAL is currently illegal on an item template - * because the flags can't get passed down. In practice this - * isn't a problem: we include the relevant flags from the item - * template in the template itself. - */ - if ((tag != -1) || opt) { - OPENSSL_PUT_ERROR(ASN1, - ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); - goto err; - } - return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx, depth); + if (it->templates) { + // tagging or OPTIONAL is currently illegal on an item template + // because the flags can't get passed down. In practice this + // isn't a problem: we include the relevant flags from the item + // template in the template itself. + if ((tag != -1) || opt) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + goto err; } - return asn1_d2i_ex_primitive(pval, in, len, it, - tag, aclass, opt, ctx); - break; + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf, + depth); + } + return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt); + break; case ASN1_ITYPE_MSTRING: - /* - * It never makes sense for multi-strings to have implicit tagging, so - * if tag != -1, then this looks like an error in the template. - */ - if (tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - goto err; - } + // It never makes sense for multi-strings to have implicit tagging, so + // if tag != -1, then this looks like an error in the template. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } - p = *in; - /* Just read in tag and class */ - ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, - &p, len, -1, 0, 1, ctx); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } + p = *in; + // Just read in tag and class + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, &p, len, -1, 0, 1); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } - /* Must be UNIVERSAL class */ - if (oclass != V_ASN1_UNIVERSAL) { - /* If OPTIONAL, assume this is OK */ - if (opt) - return -1; - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL); - goto err; + // Must be UNIVERSAL class + if (oclass != V_ASN1_UNIVERSAL) { + // If OPTIONAL, assume this is OK + if (opt) { + return -1; } - /* Check tag matches bit map */ - if (!(ASN1_tag2bit(otag) & it->utype)) { - /* If OPTIONAL, assume this is OK */ - if (opt) - return -1; - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG); - goto err; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL); + goto err; + } + // Check tag matches bit map + if (!(ASN1_tag2bit(otag) & it->utype)) { + // If OPTIONAL, assume this is OK + if (opt) { + return -1; } - return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG); + goto err; + } + return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0); - case ASN1_ITYPE_EXTERN: - /* Use new style d2i */ - ef = it->funcs; - return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); + case ASN1_ITYPE_EXTERN: { + // We don't support implicit tagging with external types. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } + const ASN1_EXTERN_FUNCS *ef = it->funcs; + return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL); + } case ASN1_ITYPE_CHOICE: { - /* - * It never makes sense for CHOICE types to have implicit tagging, so if - * tag != -1, then this looks like an error in the template. - */ - if (tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - goto err; - } + // It never makes sense for CHOICE types to have implicit tagging, so if + // tag != -1, then this looks like an error in the template. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + goto err; + } - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) - goto auxerr; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) { + goto auxerr; + } - if (*pval) { - /* Free up and zero CHOICE value if initialised */ - i = asn1_get_choice_selector(pval, it); - if ((i >= 0) && (i < it->tcount)) { - tt = it->templates + i; - pchptr = asn1_get_field_ptr(pval, tt); - ASN1_template_free(pchptr, tt); - asn1_set_choice_selector(pval, -1, it); - } - } else if (!ASN1_item_ex_new(pval, it)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; + if (*pval) { + // Free up and zero CHOICE value if initialised + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + tt = it->templates + i; + pchptr = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchptr, tt); + asn1_set_choice_selector(pval, -1, it); } - /* CHOICE type, try each possibility in turn */ - p = *in; - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - pchptr = asn1_get_field_ptr(pval, tt); - /* - * We mark field as OPTIONAL so its absence can be recognised. - */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); - /* If field not present, try the next one */ - if (ret == -1) - continue; - /* If positive return, read OK, break loop */ - if (ret > 0) - break; - /* Otherwise must be an ASN1 parsing error */ - errtt = tt; - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; + } else if (!ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + // CHOICE type, try each possibility in turn + p = *in; + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + pchptr = asn1_get_field_ptr(pval, tt); + // We mark field as OPTIONAL so its absence can be recognised. + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth); + // If field not present, try the next one + if (ret == -1) { + continue; } + // If positive return, read OK, break loop + if (ret > 0) { + break; + } + // Otherwise must be an ASN1 parsing error + errtt = tt; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } - /* Did we fall off the end without reading anything? */ - if (i == it->tcount) { - /* If OPTIONAL, this is OK */ - if (opt) { - /* Free and zero it */ - ASN1_item_ex_free(pval, it); - return -1; - } - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); - goto err; + // Did we fall off the end without reading anything? + if (i == it->tcount) { + // If OPTIONAL, this is OK + if (opt) { + // Free and zero it + ASN1_item_ex_free(pval, it); + return -1; } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); + goto err; + } - asn1_set_choice_selector(pval, i, it); - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) - goto auxerr; - *in = p; - return 1; + asn1_set_choice_selector(pval, i, it); + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { + goto auxerr; + } + *in = p; + return 1; } case ASN1_ITYPE_SEQUENCE: { - p = *in; + p = *in; - /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if (tag == -1) { - tag = V_ASN1_SEQUENCE; - aclass = V_ASN1_UNIVERSAL; + // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + // Get SEQUENCE length and update len, p + ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, len, tag, aclass, opt); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) { + return -1; + } + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) { + goto auxerr; + } + + // Free up and zero any ADB found + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + if (tt->flags & ASN1_TFLG_ADB_MASK) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (seqtt == NULL) { + continue; + } + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); } - /* Get SEQUENCE length and update len, p */ - ret = asn1_check_tlen(&len, NULL, NULL, &cst, - &p, len, tag, aclass, opt, ctx); + } + + // Get each field entry + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) { + goto err; + } + pseqval = asn1_get_field_ptr(pval, seqtt); + // Have we ran out of data? + if (!len) { + break; + } + q = p; + // This determines the OPTIONAL flag value. The field cannot be + // omitted if it is the last of a SEQUENCE and there is still + // data to be read. This isn't strictly necessary but it + // increases efficiency in some cases. + if (i == (it->tcount - 1)) { + isopt = 0; + } else { + isopt = (seqtt->flags & ASN1_TFLG_OPTIONAL) != 0; + } + // attempt to read in field, allowing each to be OPTIONAL + + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth); if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - if (!cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); - goto err; + errtt = seqtt; + goto err; + } else if (ret == -1) { + // OPTIONAL component absent. Free and zero the field. + ASN1_template_free(pseqval, seqtt); + continue; } + // Update length + len -= p - q; + } - if (!*pval && !ASN1_item_ex_new(pval, it)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; + // Check all data read + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + goto err; + } + + // If we get here we've got no more data in the SEQUENCE, however we + // may not have read all fields so check all remaining are OPTIONAL + // and clear any that are. + for (; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) { + goto err; } - - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) - goto auxerr; - - /* Free up and zero any ADB found */ - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - if (tt->flags & ASN1_TFLG_ADB_MASK) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 0); - if (seqtt == NULL) - continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); - } + if (seqtt->flags & ASN1_TFLG_OPTIONAL) { + ASN1_VALUE **pseqval; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } else { + errtt = seqtt; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING); + goto err; } - - /* Get each field entry */ - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); - if (seqtt == NULL) - goto err; - pseqval = asn1_get_field_ptr(pval, seqtt); - /* Have we ran out of data? */ - if (!len) - break; - q = p; - /* TODO(https://crbug.com/boringssl/455): Although we've removed - * indefinite-length support, this check is not quite a no-op. - * Reject [UNIVERSAL 0] in the tag parsers themselves. */ - if (asn1_check_eoc(&p, len)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC); - goto err; - } - /* - * This determines the OPTIONAL flag value. The field cannot be - * omitted if it is the last of a SEQUENCE and there is still - * data to be read. This isn't strictly necessary but it - * increases efficiency in some cases. - */ - if (i == (it->tcount - 1)) - isopt = 0; - else - isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); - /* - * attempt to read in field, allowing each to be OPTIONAL - */ - - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, - depth); - if (!ret) { - errtt = seqtt; - goto err; - } else if (ret == -1) { - /* - * OPTIONAL component absent. Free and zero the field. - */ - ASN1_template_free(pseqval, seqtt); - continue; - } - /* Update length */ - len -= p - q; - } - - /* Check all data read */ - if (len) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH); - goto err; - } - - /* - * If we get here we've got no more data in the SEQUENCE, however we - * may not have read all fields so check all remaining are OPTIONAL - * and clear any that are. - */ - for (; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - seqtt = asn1_do_adb(pval, tt, 1); - if (seqtt == NULL) - goto err; - if (seqtt->flags & ASN1_TFLG_OPTIONAL) { - ASN1_VALUE **pseqval; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); - } else { - errtt = seqtt; - OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING); - goto err; - } - } - /* Save encoding */ - if (!asn1_enc_save(pval, *in, p - *in, it)) - goto auxerr; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) - goto auxerr; - *in = p; - return 1; + } + // Save encoding + if (!asn1_enc_save(pval, *in, p - *in, it, buf)) { + goto auxerr; + } + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { + goto auxerr; + } + *in = p; + return 1; } default: - return 0; - } - auxerr: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); - err: - if (combine == 0) - ASN1_item_ex_free(pval, it); - if (errtt) - ERR_add_error_data(4, "Field=", errtt->field_name, - ", Type=", it->sname); - else - ERR_add_error_data(2, "Type=", it->sname); - return 0; + return 0; + } +auxerr: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); +err: + ASN1_item_ex_free(pval, it); + if (errtt) { + ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); + } else { + ERR_add_error_data(2, "Type=", it->sname); + } + return 0; } int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ - return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); + const ASN1_ITEM *it, int tag, int aclass, char opt, + CRYPTO_BUFFER *buf) { + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf, + /*depth=*/0); } -/* - * Templates are handled with two separate functions. One handles any - * EXPLICIT tag and the other handles the rest. - */ +// Templates are handled with two separate functions. One handles any +// EXPLICIT tag and the other handles the rest. -static int asn1_template_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long inlen, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) -{ - int flags, aclass; - int ret; - long len; - const unsigned char *p, *q; - if (!val) - return 0; - flags = tt->flags; - aclass = flags & ASN1_TFLG_TAG_CLASS; - - p = *in; - - /* Check if EXPLICIT tag expected */ - if (flags & ASN1_TFLG_EXPTAG) { - char cst; - /* - * Need to work out amount of data available to the inner content and - * where it starts: so read in EXPLICIT header to get the info. - */ - ret = asn1_check_tlen(&len, NULL, NULL, &cst, - &p, inlen, tt->tag, aclass, opt, ctx); - q = p; - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - if (!cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); - return 0; - } - /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } - /* We read the field in OK so update length */ - len -= p - q; - /* Check for trailing data. */ - if (len) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH); - goto err; - } - } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); - - *in = p; - return 1; - - err: - ASN1_template_free(val, tt); +static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, + long inlen, const ASN1_TEMPLATE *tt, char opt, + CRYPTO_BUFFER *buf, int depth) { + int aclass; + int ret; + long len; + const unsigned char *p, *q; + if (!val) { return 0; -} + } + uint32_t flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; -static int asn1_template_noexp_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) -{ - int flags, aclass; - int ret; - const unsigned char *p; - if (!val) - return 0; - flags = tt->flags; - aclass = flags & ASN1_TFLG_TAG_CLASS; + p = *in; - p = *in; - - if (flags & ASN1_TFLG_SK_MASK) { - /* SET OF, SEQUENCE OF */ - int sktag, skaclass; - /* First work out expected inner tag value */ - if (flags & ASN1_TFLG_IMPTAG) { - sktag = tt->tag; - skaclass = aclass; - } else { - skaclass = V_ASN1_UNIVERSAL; - if (flags & ASN1_TFLG_SET_OF) - sktag = V_ASN1_SET; - else - sktag = V_ASN1_SEQUENCE; - } - /* Get the tag */ - ret = asn1_check_tlen(&len, NULL, NULL, NULL, - &p, len, sktag, skaclass, opt, ctx); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - if (!*val) - *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); - else { - /* - * We've got a valid STACK: free up any items present - */ - STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; - ASN1_VALUE *vtmp; - while (sk_ASN1_VALUE_num(sktmp) > 0) { - vtmp = sk_ASN1_VALUE_pop(sktmp); - ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); - } - } - - if (!*val) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Read as many items as we can */ - while (len > 0) { - ASN1_VALUE *skfield; - const unsigned char *q = p; - /* TODO(https://crbug.com/boringssl/455): Although we've removed - * indefinite-length support, this check is not quite a no-op. - * Reject [UNIVERSAL 0] in the tag parsers themselves. */ - if (asn1_check_eoc(&p, len)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC); - goto err; - } - skfield = NULL; - if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, 0, ctx, depth)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } - len -= p - q; - if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { - ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } else if (flags & ASN1_TFLG_IMPTAG) { - /* IMPLICIT tagging */ - ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, - aclass, opt, ctx, depth); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - } else { - /* Nothing special */ - ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, - depth); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - } - - *in = p; - return 1; - - err: - ASN1_template_free(val, tt); - return 0; -} - -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, - const unsigned char **in, long inlen, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ - int ret = 0, utype; - long plen; + // Check if EXPLICIT tag expected + if (flags & ASN1_TFLG_EXPTAG) { char cst; - const unsigned char *p; - const unsigned char *cont = NULL; - long len; - if (!pval) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); - return 0; /* Should never happen */ - } - - if (it->itype == ASN1_ITYPE_MSTRING) { - utype = tag; - tag = -1; - } else - utype = it->utype; - - if (utype == V_ASN1_ANY) { - /* If type is ANY need to figure out type from tag */ - unsigned char oclass; - if (tag >= 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); - return 0; - } - if (opt) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); - return 0; - } - p = *in; - ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, - &p, inlen, -1, 0, 0, ctx); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } - if (oclass != V_ASN1_UNIVERSAL) - utype = V_ASN1_OTHER; - } - if (tag == -1) { - tag = utype; - aclass = V_ASN1_UNIVERSAL; - } - p = *in; - /* Check header */ - ret = asn1_check_tlen(&plen, NULL, NULL, &cst, - &p, inlen, tag, aclass, opt, ctx); + // Need to work out amount of data available to the inner content and + // where it starts: so read in EXPLICIT header to get the info. + ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, inlen, tt->tag, aclass, + opt); + q = p; if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - ret = 0; - /* SEQUENCE, SET and "OTHER" are left in encoded form */ - if ((utype == V_ASN1_SEQUENCE) - || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { - /* - * Clear context cache for type OTHER because the auto clear when we - * have a exact match wont work - */ - if (utype == V_ASN1_OTHER) { - asn1_tlc_clear(ctx); - } - /* SEQUENCE and SET must be constructed */ - else if (!cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); - return 0; - } - - cont = *in; - len = p - cont + plen; - p += plen; - } else if (cst) { - /* This parser historically supported BER constructed strings. We no - * longer do and will gradually tighten this parser into a DER - * parser. BER types should use |CBS_asn1_ber_to_der|. */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } else { - cont = p; - len = plen; - p += plen; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) { + return -1; } + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + return 0; + } + // We've found the field so it can't be OPTIONAL now + ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + // We read the field in OK so update length + len -= p - q; + // Check for trailing data. + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH); + goto err; + } + } else { + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth); + } - /* We now have content length and type: translate into a structure */ - if (!asn1_ex_c2i(pval, cont, len, utype, it)) - goto err; + *in = p; + return 1; - *in = p; - ret = 1; - err: - return ret; +err: + ASN1_template_free(val, tt); + return 0; } -/* Translate ASN1 content octets into a structure */ +static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_TEMPLATE *tt, char opt, + CRYPTO_BUFFER *buf, int depth) { + int aclass; + int ret; + const unsigned char *p; + if (!val) { + return 0; + } + uint32_t flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, const ASN1_ITEM *it) -{ - ASN1_VALUE **opval = NULL; - ASN1_STRING *stmp; - ASN1_TYPE *typ = NULL; - int ret = 0; - ASN1_INTEGER **tint; + p = *in; - /* Historically, |it->funcs| for primitive types contained an - * |ASN1_PRIMITIVE_FUNCS| table of callbacks. */ - assert(it->funcs == NULL); - - /* If ANY type clear type and set pointer to internal value */ - if (it->utype == V_ASN1_ANY) { - if (!*pval) { - typ = ASN1_TYPE_new(); - if (typ == NULL) - goto err; - *pval = (ASN1_VALUE *)typ; - } else - typ = (ASN1_TYPE *)*pval; - - if (utype != typ->type) - ASN1_TYPE_set(typ, utype, NULL); - opval = pval; - pval = &typ->value.asn1_value; + if (flags & ASN1_TFLG_SK_MASK) { + // SET OF, SEQUENCE OF + int sktag, skaclass; + // First work out expected inner tag value + if (flags & ASN1_TFLG_IMPTAG) { + sktag = tt->tag; + skaclass = aclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (flags & ASN1_TFLG_SET_OF) { + sktag = V_ASN1_SET; + } else { + sktag = V_ASN1_SEQUENCE; + } } - switch (utype) { + // Get the tag + ret = + asn1_check_tlen(&len, NULL, NULL, NULL, &p, len, sktag, skaclass, opt); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) { + return -1; + } + if (!*val) { + *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); + } else { + // We've got a valid STACK: free up any items present + STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; + ASN1_VALUE *vtmp; + while (sk_ASN1_VALUE_num(sktmp) > 0) { + vtmp = sk_ASN1_VALUE_pop(sktmp); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + } + } + + if (!*val) { + goto err; + } + + // Read as many items as we can + while (len > 0) { + ASN1_VALUE *skfield; + const unsigned char *q = p; + skfield = NULL; + if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), + /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } + len -= p - q; + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); + goto err; + } + } + } else if (flags & ASN1_TFLG_IMPTAG) { + // IMPLICIT tagging + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, + aclass, opt, buf, depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) { + return -1; + } + } else { + // Nothing special + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1, + /*aclass=*/0, opt, buf, depth); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) { + return -1; + } + } + + *in = p; + return 1; + +err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, + long inlen, const ASN1_ITEM *it, int tag, + int aclass, char opt) { + int ret = 0, utype; + long plen; + char cst; + const unsigned char *p; + const unsigned char *cont = NULL; + long len; + if (!pval) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); + return 0; // Should never happen + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + utype = tag; + tag = -1; + } else { + utype = it->utype; + } + + if (utype == V_ASN1_ANY) { + // If type is ANY need to figure out type from tag + unsigned char oclass; + if (tag >= 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); + return 0; + } + p = *in; + ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, &p, inlen, -1, 0, 0); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + if (!is_supported_universal_type(utype, oclass)) { + utype = V_ASN1_OTHER; + } + } + if (tag == -1) { + tag = utype; + aclass = V_ASN1_UNIVERSAL; + } + p = *in; + // Check header + ret = asn1_check_tlen(&plen, NULL, NULL, &cst, &p, inlen, tag, aclass, opt); + if (!ret) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) { + return -1; + } + ret = 0; + // SEQUENCE, SET and "OTHER" are left in encoded form + if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || + (utype == V_ASN1_OTHER)) { + // SEQUENCE and SET must be constructed + if (utype != V_ASN1_OTHER && !cst) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + + cont = *in; + len = p - cont + plen; + p += plen; + } else if (cst) { + // This parser historically supported BER constructed strings. We no + // longer do and will gradually tighten this parser into a DER + // parser. BER types should use |CBS_asn1_ber_to_der|. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } else { + cont = p; + len = plen; + p += plen; + } + + // We now have content length and type: translate into a structure + if (!asn1_ex_c2i(pval, cont, len, utype, it)) { + goto err; + } + + *in = p; + ret = 1; +err: + return ret; +} + +// Translate ASN1 content octets into a structure + +static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, + int utype, const ASN1_ITEM *it) { + ASN1_VALUE **opval = NULL; + ASN1_STRING *stmp; + ASN1_TYPE *typ = NULL; + int ret = 0; + ASN1_INTEGER **tint; + + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of callbacks. + assert(it->funcs == NULL); + + // If ANY type clear type and set pointer to internal value + if (it->utype == V_ASN1_ANY) { + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) { + goto err; + } + *pval = (ASN1_VALUE *)typ; + } else { + typ = (ASN1_TYPE *)*pval; + } + + if (utype != typ->type) { + ASN1_TYPE_set(typ, utype, NULL); + } + opval = pval; + pval = &typ->value.asn1_value; + } + switch (utype) { case V_ASN1_OBJECT: - if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) - goto err; - break; + if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) { + goto err; + } + break; case V_ASN1_NULL: - if (len) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); - goto err; - } - *pval = (ASN1_VALUE *)1; - break; + if (len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; case V_ASN1_BOOLEAN: - if (len != 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - goto err; - } else { - ASN1_BOOLEAN *tbool; - tbool = (ASN1_BOOLEAN *)pval; - *tbool = *cont; - } - break; + if (len != 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + goto err; + } else { + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = *cont; + } + break; case V_ASN1_BIT_STRING: - if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) - goto err; - break; + if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) { + goto err; + } + break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: - tint = (ASN1_INTEGER **)pval; - if (!c2i_ASN1_INTEGER(tint, &cont, len)) - goto err; - /* Fixup type to match the expected form */ - (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); - break; + tint = (ASN1_INTEGER **)pval; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) { + goto err; + } + // Fixup type to match the expected form + (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); + break; case V_ASN1_OCTET_STRING: case V_ASN1_NUMERICSTRING: @@ -825,145 +838,136 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, case V_ASN1_OTHER: case V_ASN1_SET: case V_ASN1_SEQUENCE: - default: - if (utype == V_ASN1_BMPSTRING && (len & 1)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + // TODO(crbug.com/boringssl/412): This default case should be removed, now + // that we've resolved https://crbug.com/boringssl/561. However, it is still + // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE| + // broadly doesn't tolerate unrecognized universal tags, but except for + // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the + // X509Test.NameAttributeValues test. + default: { + CBS cbs; + CBS_init(&cbs, cont, (size_t)len); + if (utype == V_ASN1_BMPSTRING) { + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!cbs_get_ucs2_be(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); goto err; + } } - if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); + } + if (utype == V_ASN1_UNIVERSALSTRING) { + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!cbs_get_utf32_be(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); goto err; + } } - /* All based on ASN1_STRING and handled the same */ - if (!*pval) { - stmp = ASN1_STRING_type_new(utype); - if (!stmp) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; - } - *pval = (ASN1_VALUE *)stmp; - } else { - stmp = (ASN1_STRING *)*pval; - stmp->type = utype; - } - if (!ASN1_STRING_set(stmp, cont, len)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(stmp); - *pval = NULL; + } + if (utype == V_ASN1_UTF8STRING) { + while (CBS_len(&cbs) != 0) { + uint32_t c; + if (!cbs_get_utf8(&cbs, &c)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); goto err; + } } - break; - } - /* If ASN1_ANY and NULL type fix up value */ - if (typ && (utype == V_ASN1_NULL)) - typ->value.ptr = NULL; + } + if (utype == V_ASN1_UTCTIME) { + if (!CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + } + if (utype == V_ASN1_GENERALIZEDTIME) { + if (!CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + } + // TODO(https://crbug.com/boringssl/427): Check other string types. - ret = 1; - err: - if (!ret) { - ASN1_TYPE_free(typ); - if (opval) - *opval = NULL; + // All based on ASN1_STRING and handled the same + if (!*pval) { + stmp = ASN1_STRING_type_new(utype); + if (!stmp) { + goto err; + } + *pval = (ASN1_VALUE *)stmp; + } else { + stmp = (ASN1_STRING *)*pval; + stmp->type = utype; + } + if (!ASN1_STRING_set(stmp, cont, len)) { + ASN1_STRING_free(stmp); + *pval = NULL; + goto err; + } + break; } - return ret; + } + // If ASN1_ANY and NULL type fix up value + if (typ && (utype == V_ASN1_NULL)) { + typ->value.ptr = NULL; + } + + ret = 1; +err: + if (!ret) { + ASN1_TYPE_free(typ); + if (opval) { + *opval = NULL; + } + } + return ret; } -/* Check for ASN1 EOC and swallow it if found */ - -static int asn1_check_eoc(const unsigned char **in, long len) -{ - const unsigned char *p; - if (len < 2) - return 0; - p = *in; - if (!p[0] && !p[1]) { - *in += 2; - return 1; - } - return 0; -} - -/* - * Check an ASN1 tag and length: a bit like ASN1_get_object but it handles - * the ASN1_TLC cache and checks the expected tag. - */ +// Check an ASN1 tag and length: a bit like ASN1_get_object but it +// checks the expected tag. static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *cst, const unsigned char **in, long len, - int exptag, int expclass, char opt, ASN1_TLC *ctx) -{ - int i; - int ptag, pclass; - long plen; - const unsigned char *p, *q; - p = *in; - q = p; + int exptag, int expclass, char opt) { + int i; + int ptag, pclass; + long plen; + const unsigned char *p; + p = *in; - if (ctx && ctx->valid) { - i = ctx->ret; - plen = ctx->plen; - pclass = ctx->pclass; - ptag = ctx->ptag; - p += ctx->hdrlen; - } else { - i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); - if (ctx) { - ctx->ret = i; - ctx->plen = plen; - ctx->pclass = pclass; - ctx->ptag = ptag; - ctx->hdrlen = p - q; - ctx->valid = 1; - /* - * If no error, length + header can't exceed total amount of data - * available. - * - * TODO(davidben): Is this check necessary? |ASN1_get_object| - * should already guarantee this. - */ - if (!(i & 0x80) && ((plen + ctx->hdrlen) > len)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); - asn1_tlc_clear(ctx); - return 0; - } - } + i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); + if (i & 0x80) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); + return 0; + } + if (exptag >= 0) { + if ((exptag != ptag) || (expclass != pclass)) { + // If type is OPTIONAL, not an error: indicate missing type. + if (opt) { + return -1; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG); + return 0; } + } - if (i & 0x80) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); - asn1_tlc_clear(ctx); - return 0; - } - if (exptag >= 0) { - if ((exptag != ptag) || (expclass != pclass)) { - /* - * If type is OPTIONAL, not an error: indicate missing type. - */ - if (opt) - return -1; - asn1_tlc_clear(ctx); - OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG); - return 0; - } - /* - * We have a tag and class match: assume we are going to do something - * with it - */ - asn1_tlc_clear(ctx); - } + if (cst) { + *cst = i & V_ASN1_CONSTRUCTED; + } - if (cst) - *cst = i & V_ASN1_CONSTRUCTED; + if (olen) { + *olen = plen; + } - if (olen) - *olen = plen; + if (oclass) { + *oclass = pclass; + } - if (oclass) - *oclass = pclass; + if (otag) { + *otag = ptag; + } - if (otag) - *otag = ptag; - - *in = p; - return 1; + *in = p; + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_enc.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_enc.c index 0af9e9df..e85400b2 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_enc.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_enc.c @@ -78,605 +78,601 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit, static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort); static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt, int tag, int aclass); + const ASN1_TEMPLATE *tt, int tag, int aclass, + int optional); -/* - * Top level i2d equivalents - */ +// Top level i2d equivalents -int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) -{ - if (out && !*out) { - unsigned char *p, *buf; - int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0); - if (len <= 0) { - return len; - } - buf = OPENSSL_malloc(len); - if (!buf) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return -1; - } - p = buf; - int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0); - if (len2 <= 0) { - return len2; - } - assert(len == len2); - *out = buf; - return len; +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { + if (out && !*out) { + unsigned char *p, *buf; + int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0); + if (len <= 0) { + return len; } + buf = OPENSSL_malloc(len); + if (!buf) { + return -1; + } + p = buf; + int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0); + if (len2 <= 0) { + OPENSSL_free(buf); + return len2; + } + assert(len == len2); + *out = buf; + return len; + } - return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0); + return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0); } -/* - * Encode an item, taking care of IMPLICIT tagging (if any). This function - * performs the normal item handling: it can be used in external types. - */ +// Encode an item, taking care of IMPLICIT tagging (if any). This function +// performs the normal item handling: it can be used in external types. int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) -{ - int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0); - assert(ret != 0); - return ret; + const ASN1_ITEM *it, int tag, int aclass) { + int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0); + assert(ret != 0); + return ret; } -/* asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is - * non-zero and |*pval| is omitted, it returns zero and writes no bytes. */ +// asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is +// non-zero and |*pval| is omitted, it returns zero and writes no bytes. int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass, - int optional) -{ - const ASN1_TEMPLATE *tt = NULL; - int i, seqcontlen, seqlen; + int optional) { + const ASN1_TEMPLATE *tt = NULL; + int i, seqcontlen, seqlen; - /* Historically, |aclass| was repurposed to pass additional flags into the - * encoding process. */ - assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass); - /* If not overridding the tag, |aclass| is ignored and should be zero. */ - assert(tag != -1 || aclass == 0); + // Historically, |aclass| was repurposed to pass additional flags into the + // encoding process. + assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass); + // If not overridding the tag, |aclass| is ignored and should be zero. + assert(tag != -1 || aclass == 0); - /* All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s. - * Optional primitives are handled later. */ - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) { - if (optional) { - return 0; - } - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); - return -1; + // All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s. + // Optional primitives are handled later. + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) { + if (optional) { + return 0; } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } - switch (it->itype) { - + switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - if (it->templates->flags & ASN1_TFLG_OPTIONAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } - return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass); + if (it->templates) { + // This is an |ASN1_ITEM_TEMPLATE|. + if (it->templates->flags & ASN1_TFLG_OPTIONAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; } - return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional); + return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass, + optional); + } + return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional); case ASN1_ITYPE_MSTRING: - /* - * It never makes sense for multi-strings to have implicit tagging, so - * if tag != -1, then this looks like an error in the template. - */ - if (tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } - return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional); + // It never makes sense for multi-strings to have implicit tagging, so + // if tag != -1, then this looks like an error in the template. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional); case ASN1_ITYPE_CHOICE: { - /* - * It never makes sense for CHOICE types to have implicit tagging, so if - * tag != -1, then this looks like an error in the template. - */ - if (tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } - i = asn1_get_choice_selector(pval, it); - if (i < 0 || i >= it->tcount) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); - return -1; - } - const ASN1_TEMPLATE *chtt = it->templates + i; - if (chtt->flags & ASN1_TFLG_OPTIONAL) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } - ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt); - return asn1_template_ex_i2d(pchval, out, chtt, -1, 0); + // It never makes sense for CHOICE types to have implicit tagging, so if + // tag != -1, then this looks like an error in the template. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + i = asn1_get_choice_selector(pval, it); + if (i < 0 || i >= it->tcount) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); + return -1; + } + const ASN1_TEMPLATE *chtt = it->templates + i; + if (chtt->flags & ASN1_TFLG_OPTIONAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt); + return asn1_template_ex_i2d(pchval, out, chtt, -1, 0, /*optional=*/0); } case ASN1_ITYPE_EXTERN: { - /* If new style i2d it does all the work */ - const ASN1_EXTERN_FUNCS *ef = it->funcs; - int ret = ef->asn1_ex_i2d(pval, out, it, tag, aclass); - if (ret == 0) { - /* |asn1_ex_i2d| should never return zero. We have already checked - * for optional values generically, and |ASN1_ITYPE_EXTERN| fields - * must be pointers. */ - OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); - return -1; - } - return ret; + // We don't support implicit tagging with external types. + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + const ASN1_EXTERN_FUNCS *ef = it->funcs; + int ret = ef->asn1_ex_i2d(pval, out, it); + if (ret == 0) { + // |asn1_ex_i2d| should never return zero. We have already checked + // for optional values generically, and |ASN1_ITYPE_EXTERN| fields + // must be pointers. + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return -1; + } + return ret; } case ASN1_ITYPE_SEQUENCE: { - i = asn1_enc_restore(&seqcontlen, out, pval, it); - /* An error occurred */ - if (i < 0) - return -1; - /* We have a valid cached encoding... */ - if (i > 0) - return seqcontlen; - /* Otherwise carry on */ - seqcontlen = 0; - /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if (tag == -1) { - tag = V_ASN1_SEQUENCE; - aclass = V_ASN1_UNIVERSAL; + i = asn1_enc_restore(&seqcontlen, out, pval, it); + // An error occurred + if (i < 0) { + return -1; + } + // We have a valid cached encoding... + if (i > 0) { + return seqcontlen; + } + // Otherwise carry on + seqcontlen = 0; + // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + // First work out sequence content length + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + int tmplen; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) { + return -1; } - /* First work out sequence content length */ - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - int tmplen; - seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) - return -1; - pseqval = asn1_get_field_ptr(pval, seqtt); - tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0); - if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) - return -1; - seqcontlen += tmplen; + pseqval = asn1_get_field_ptr(pval, seqtt); + tmplen = + asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0, /*optional=*/0); + if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) { + return -1; } + seqcontlen += tmplen; + } - seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag); - if (!out || seqlen == -1) - return seqlen; - /* Output SEQUENCE header */ - ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass); - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) - return -1; - pseqval = asn1_get_field_ptr(pval, seqtt); - if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0) < 0) { - return -1; - } - } + seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag); + if (!out || seqlen == -1) { return seqlen; + } + // Output SEQUENCE header + ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) { + return -1; + } + pseqval = asn1_get_field_ptr(pval, seqtt); + if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0, /*optional=*/0) < + 0) { + return -1; + } + } + return seqlen; } default: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } } -/* asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an - * |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an - * |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. Instead of - * taking an |optional| parameter, it uses the |ASN1_TFLG_OPTIONAL| flag. */ +// asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an +// |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an +// |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt, int tag, int iclass) -{ - int i, ret, flags, ttag, tclass; - size_t j; - flags = tt->flags; + const ASN1_TEMPLATE *tt, int tag, int iclass, + int optional) { + int i, ret, ttag, tclass; + size_t j; + uint32_t flags = tt->flags; - /* Historically, |iclass| was repurposed to pass additional flags into the - * encoding process. */ - assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass); - /* If not overridding the tag, |iclass| is ignored and should be zero. */ - assert(tag != -1 || iclass == 0); + // Historically, |iclass| was repurposed to pass additional flags into the + // encoding process. + assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass); + // If not overridding the tag, |iclass| is ignored and should be zero. + assert(tag != -1 || iclass == 0); - /* - * Work out tag and class to use: tagging may come either from the - * template or the arguments, not both because this would create - * ambiguity. - */ - if (flags & ASN1_TFLG_TAG_MASK) { - /* Error if argument and template tagging */ - if (tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - return -1; - } - /* Get tagging from template */ - ttag = tt->tag; - tclass = flags & ASN1_TFLG_TAG_CLASS; - } else if (tag != -1) { - /* No template tagging, get from arguments */ - ttag = tag; - tclass = iclass & ASN1_TFLG_TAG_CLASS; + // Work out tag and class to use: tagging may come either from the + // template or the arguments, not both because this would create + // ambiguity. + if (flags & ASN1_TFLG_TAG_MASK) { + // Error if argument and template tagging + if (tag != -1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); + return -1; + } + // Get tagging from template + ttag = tt->tag; + tclass = flags & ASN1_TFLG_TAG_CLASS; + } else if (tag != -1) { + // No template tagging, get from arguments + ttag = tag; + tclass = iclass & ASN1_TFLG_TAG_CLASS; + } else { + ttag = -1; + tclass = 0; + } + + // The template may itself by marked as optional, or this may be the template + // of an |ASN1_ITEM_TEMPLATE| type which was contained inside an outer + // optional template. (They cannot both be true because the + // |ASN1_ITEM_TEMPLATE| codepath rejects optional templates.) + assert(!optional || (flags & ASN1_TFLG_OPTIONAL) == 0); + optional = optional || (flags & ASN1_TFLG_OPTIONAL) != 0; + + // At this point 'ttag' contains the outer tag to use, and 'tclass' is the + // class. + + if (flags & ASN1_TFLG_SK_MASK) { + // SET OF, SEQUENCE OF + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + int isset, sktag, skaclass; + int skcontlen, sklen; + ASN1_VALUE *skitem; + + if (!*pval) { + if (optional) { + return 0; + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + if (flags & ASN1_TFLG_SET_OF) { + isset = 1; + // Historically, types with both bits set were mutated when + // serialized to apply the sort. We no longer support this. + assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0); } else { - ttag = -1; - tclass = 0; + isset = 0; } - const int optional = (flags & ASN1_TFLG_OPTIONAL) != 0; - - /* - * At this point 'ttag' contains the outer tag to use, and 'tclass' is the - * class. - */ - - if (flags & ASN1_TFLG_SK_MASK) { - /* SET OF, SEQUENCE OF */ - STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; - int isset, sktag, skaclass; - int skcontlen, sklen; - ASN1_VALUE *skitem; - - if (!*pval) { - if (optional) { - return 0; - } - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); - return -1; - } - - if (flags & ASN1_TFLG_SET_OF) { - isset = 1; - /* Historically, types with both bits set were mutated when - * serialized to apply the sort. We no longer support this. */ - assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0); - } else { - isset = 0; - } - - /* - * Work out inner tag value: if EXPLICIT or no tagging use underlying - * type. - */ - if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { - sktag = ttag; - skaclass = tclass; - } else { - skaclass = V_ASN1_UNIVERSAL; - if (isset) - sktag = V_ASN1_SET; - else - sktag = V_ASN1_SEQUENCE; - } - - /* Determine total length of items */ - skcontlen = 0; - for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) { - int tmplen; - skitem = sk_ASN1_VALUE_value(sk, j); - tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), - -1, 0); - if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) - return -1; - skcontlen += tmplen; - } - sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag); - if (sklen == -1) - return -1; - /* If EXPLICIT need length of surrounding tag */ - if (flags & ASN1_TFLG_EXPTAG) - ret = ASN1_object_size(/*constructed=*/1, sklen, ttag); - else - ret = sklen; - - if (!out || ret == -1) - return ret; - - /* Now encode this lot... */ - /* EXPLICIT tag */ - if (flags & ASN1_TFLG_EXPTAG) - ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass); - /* SET or SEQUENCE and IMPLICIT tag */ - ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass); - /* And the stuff itself */ - if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), - isset)) { - return -1; - } - return ret; + // Work out inner tag value: if EXPLICIT or no tagging use underlying + // type. + if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { + sktag = ttag; + skaclass = tclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (isset) { + sktag = V_ASN1_SET; + } else { + sktag = V_ASN1_SEQUENCE; + } } + // Determine total length of items + skcontlen = 0; + for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) { + int tmplen; + skitem = sk_ASN1_VALUE_value(sk, j); + tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0); + if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) { + return -1; + } + skcontlen += tmplen; + } + sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag); + if (sklen == -1) { + return -1; + } + // If EXPLICIT need length of surrounding tag if (flags & ASN1_TFLG_EXPTAG) { - /* EXPLICIT tagging */ - /* Find length of tagged item */ - i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0, - optional); - if (i <= 0) - return i; - /* Find length of EXPLICIT tag */ - ret = ASN1_object_size(/*constructed=*/1, i, ttag); - if (out && ret != -1) { - /* Output tag and item */ - ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass); - if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, - 0) < 0) { - return -1; - } - } - return ret; + ret = ASN1_object_size(/*constructed=*/1, sklen, ttag); + } else { + ret = sklen; } - /* Either normal or IMPLICIT tagging */ - return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item), - ttag, tclass, optional); + if (!out || ret == -1) { + return ret; + } + // Now encode this lot... + // EXPLICIT tag + if (flags & ASN1_TFLG_EXPTAG) { + ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass); + } + // SET or SEQUENCE and IMPLICIT tag + ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass); + // And the stuff itself + if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset)) { + return -1; + } + return ret; + } + + if (flags & ASN1_TFLG_EXPTAG) { + // EXPLICIT tagging + // Find length of tagged item + i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0, + optional); + if (i <= 0) { + return i; + } + // Find length of EXPLICIT tag + ret = ASN1_object_size(/*constructed=*/1, i, ttag); + if (out && ret != -1) { + // Output tag and item + ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass); + if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0) < 0) { + return -1; + } + } + return ret; + } + + // Either normal or IMPLICIT tagging + return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item), ttag, tclass, + optional); } -/* Temporary structure used to hold DER encoding of items for SET OF */ +// Temporary structure used to hold DER encoding of items for SET OF typedef struct { - unsigned char *data; - int length; + unsigned char *data; + int length; } DER_ENC; -static int der_cmp(const void *a, const void *b) -{ - const DER_ENC *d1 = a, *d2 = b; - int cmplen, i; - cmplen = (d1->length < d2->length) ? d1->length : d2->length; - i = OPENSSL_memcmp(d1->data, d2->data, cmplen); - if (i) - return i; - return d1->length - d2->length; +static int der_cmp(const void *a, const void *b) { + const DER_ENC *d1 = a, *d2 = b; + int cmplen, i; + cmplen = (d1->length < d2->length) ? d1->length : d2->length; + i = OPENSSL_memcmp(d1->data, d2->data, cmplen); + if (i) { + return i; + } + return d1->length - d2->length; } -/* asn1_set_seq_out writes |sk| to |out| under the i2d output convention, - * excluding the tag and length. It returns one on success and zero on error. - * |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the - * elements are sorted for a SET OF type. Each element of |sk| has type - * |item|. */ +// asn1_set_seq_out writes |sk| to |out| under the i2d output convention, +// excluding the tag and length. It returns one on success and zero on error. +// |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the +// elements are sorted for a SET OF type. Each element of |sk| has type +// |item|. static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, - int skcontlen, const ASN1_ITEM *item, int do_sort) -{ - /* No need to sort if there are fewer than two items. */ - if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) { - for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); - if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) { - return 0; - } - } - return 1; - } - - if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + int skcontlen, const ASN1_ITEM *item, int do_sort) { + // No need to sort if there are fewer than two items. + if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) { + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); + if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) { return 0; + } } + return 1; + } - int ret = 0; - unsigned char *const buf = OPENSSL_malloc(skcontlen); - DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded)); - if (encoded == NULL || buf == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto err; + if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW); + return 0; + } + + int ret = 0; + unsigned char *const buf = OPENSSL_malloc(skcontlen); + DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded)); + if (encoded == NULL || buf == NULL) { + goto err; + } + + // Encode all the elements into |buf| and populate |encoded|. + unsigned char *p = buf; + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); + encoded[i].data = p; + encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0); + if (encoded[i].length < 0) { + goto err; } + assert(p - buf <= skcontlen); + } - /* Encode all the elements into |buf| and populate |encoded|. */ - unsigned char *p = buf; - for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i); - encoded[i].data = p; - encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0); - if (encoded[i].length < 0) { - goto err; - } - assert(p - buf <= skcontlen); - } + qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp); - qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp); + // Output the elements in sorted order. + p = *out; + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + OPENSSL_memcpy(p, encoded[i].data, encoded[i].length); + p += encoded[i].length; + } + *out = p; - /* Output the elements in sorted order. */ - p = *out; - for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - OPENSSL_memcpy(p, encoded[i].data, encoded[i].length); - p += encoded[i].length; - } - *out = p; - - ret = 1; + ret = 1; err: - OPENSSL_free(encoded); - OPENSSL_free(buf); - return ret; + OPENSSL_free(encoded); + OPENSSL_free(buf); + return ret; } -/* asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a - * a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|. */ +// asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a +// a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|. static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass, - int optional) -{ - /* Get length of content octets and maybe find out the underlying type. */ - int omit; - int utype = it->utype; - int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it); - if (len < 0) { - return -1; - } - if (omit) { - if (optional) { - return 0; - } - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); - return -1; + int optional) { + // Get length of content octets and maybe find out the underlying type. + int omit; + int utype = it->utype; + int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it); + if (len < 0) { + return -1; + } + if (omit) { + if (optional) { + return 0; } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } - /* - * If SEQUENCE, SET or OTHER then header is included in pseudo content - * octets so don't include tag+length. We need to check here because the - * call to asn1_ex_i2c() could change utype. - */ - int usetag = utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET && - utype != V_ASN1_OTHER; + // If SEQUENCE, SET or OTHER then header is included in pseudo content + // octets so don't include tag+length. We need to check here because the + // call to asn1_ex_i2c() could change utype. + int usetag = + utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET && utype != V_ASN1_OTHER; - /* If not implicitly tagged get tag from underlying type */ - if (tag == -1) - tag = utype; - - /* Output tag+length followed by content octets */ - if (out) { - if (usetag) { - ASN1_put_object(out, /*constructed=*/0, len, tag, aclass); - } - int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it); - if (len2 < 0) { - return -1; - } - assert(len == len2); - assert(!omit); - *out += len; - } + // If not implicitly tagged get tag from underlying type + if (tag == -1) { + tag = utype; + } + // Output tag+length followed by content octets + if (out) { if (usetag) { - return ASN1_object_size(/*constructed=*/0, len, tag); + ASN1_put_object(out, /*constructed=*/0, len, tag, aclass); } - return len; + int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it); + if (len2 < 0) { + return -1; + } + assert(len == len2); + assert(!omit); + *out += len; + } + + if (usetag) { + return ASN1_object_size(/*constructed=*/0, len, tag); + } + return len; } -/* asn1_ex_i2c writes the |*pval| to |cout| under the i2d output convention, - * excluding the tag and length. It returns the number of bytes written, - * possibly zero, on success or -1 on error. If |*pval| should be omitted, it - * returns zero and sets |*out_omit| to true. - * - * If |it| is an MSTRING or ANY type, it gets the underlying type from |*pval|, - * which must be an |ASN1_STRING| or |ASN1_TYPE|, respectively. It then updates - * |*putype| with the tag number of type used, or |V_ASN1_OTHER| if it was not a - * universal type. If |*putype| is set to |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or - * |V_ASN1_OTHER|, it additionally outputs the tag and length, so the caller - * must not do so. - * - * Otherwise, |*putype| must contain |it->utype|. - * - * WARNING: Unlike most functions in this file, |asn1_ex_i2c| can return zero - * without omitting the element. ASN.1 values may have empty contents. */ +// asn1_ex_i2c writes the |*pval| to |cout| under the i2d output convention, +// excluding the tag and length. It returns the number of bytes written, +// possibly zero, on success or -1 on error. If |*pval| should be omitted, it +// returns zero and sets |*out_omit| to true. +// +// If |it| is an MSTRING or ANY type, it gets the underlying type from |*pval|, +// which must be an |ASN1_STRING| or |ASN1_TYPE|, respectively. It then updates +// |*putype| with the tag number of type used, or |V_ASN1_OTHER| if it was not a +// universal type. If |*putype| is set to |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or +// |V_ASN1_OTHER|, it additionally outputs the tag and length, so the caller +// must not do so. +// +// Otherwise, |*putype| must contain |it->utype|. +// +// WARNING: Unlike most functions in this file, |asn1_ex_i2c| can return zero +// without omitting the element. ASN.1 values may have empty contents. static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit, - int *putype, const ASN1_ITEM *it) -{ - ASN1_BOOLEAN *tbool = NULL; - ASN1_STRING *strtmp; - ASN1_OBJECT *otmp; - int utype; - const unsigned char *cont; - unsigned char c; - int len; + int *putype, const ASN1_ITEM *it) { + ASN1_BOOLEAN *tbool = NULL; + ASN1_STRING *strtmp; + ASN1_OBJECT *otmp; + int utype; + const unsigned char *cont; + unsigned char c; + int len; - /* Historically, |it->funcs| for primitive types contained an - * |ASN1_PRIMITIVE_FUNCS| table of callbacks. */ - assert(it->funcs == NULL); + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of callbacks. + assert(it->funcs == NULL); - *out_omit = 0; + *out_omit = 0; - /* Should type be omitted? */ - if ((it->itype != ASN1_ITYPE_PRIMITIVE) - || (it->utype != V_ASN1_BOOLEAN)) { - if (!*pval) { - *out_omit = 1; - return 0; - } + // Should type be omitted? + if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { + if (!*pval) { + *out_omit = 1; + return 0; } + } - if (it->itype == ASN1_ITYPE_MSTRING) { - /* If MSTRING type set the underlying type */ - strtmp = (ASN1_STRING *)*pval; - utype = strtmp->type; - if (utype < 0 && utype != V_ASN1_OTHER) { - /* MSTRINGs can have type -1 when default-constructed. */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); - return -1; - } - /* Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values - * that do not match their corresponding utype values. INTEGERs cannot - * participate in MSTRING types, but ENUMERATEDs can. - * - * TODO(davidben): Is this a bug? Although arguably one of the MSTRING - * types should contain more values, rather than less. See - * https://crbug.com/boringssl/412. But it is not possible to fit all - * possible ANY values into an |ASN1_STRING|, so matching the spec here - * is somewhat hopeless. */ - if (utype == V_ASN1_NEG_INTEGER) { - utype = V_ASN1_INTEGER; - } else if (utype == V_ASN1_NEG_ENUMERATED) { - utype = V_ASN1_ENUMERATED; - } - *putype = utype; - } else if (it->utype == V_ASN1_ANY) { - /* If ANY set type and pointer to value */ - ASN1_TYPE *typ; - typ = (ASN1_TYPE *)*pval; - utype = typ->type; - if (utype < 0 && utype != V_ASN1_OTHER) { - /* |ASN1_TYPE|s can have type -1 when default-constructed. */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); - return -1; - } - *putype = utype; - pval = &typ->value.asn1_value; - } else - utype = *putype; + if (it->itype == ASN1_ITYPE_MSTRING) { + // If MSTRING type set the underlying type + strtmp = (ASN1_STRING *)*pval; + utype = strtmp->type; + if (utype < 0 && utype != V_ASN1_OTHER) { + // MSTRINGs can have type -1 when default-constructed. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return -1; + } + // Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values + // that do not match their corresponding utype values. INTEGERs cannot + // participate in MSTRING types, but ENUMERATEDs can. + // + // TODO(davidben): Is this a bug? Although arguably one of the MSTRING + // types should contain more values, rather than less. See + // https://crbug.com/boringssl/412. But it is not possible to fit all + // possible ANY values into an |ASN1_STRING|, so matching the spec here + // is somewhat hopeless. + if (utype == V_ASN1_NEG_INTEGER) { + utype = V_ASN1_INTEGER; + } else if (utype == V_ASN1_NEG_ENUMERATED) { + utype = V_ASN1_ENUMERATED; + } + *putype = utype; + } else if (it->utype == V_ASN1_ANY) { + // If ANY set type and pointer to value + ASN1_TYPE *typ; + typ = (ASN1_TYPE *)*pval; + utype = typ->type; + if (utype < 0 && utype != V_ASN1_OTHER) { + // |ASN1_TYPE|s can have type -1 when default-constructed. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return -1; + } + *putype = utype; + pval = &typ->value.asn1_value; + } else { + utype = *putype; + } - switch (utype) { + switch (utype) { case V_ASN1_OBJECT: - otmp = (ASN1_OBJECT *)*pval; - cont = otmp->data; - len = otmp->length; - if (len == 0) { - /* Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized. */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - return -1; - } - break; + otmp = (ASN1_OBJECT *)*pval; + cont = otmp->data; + len = otmp->length; + if (len == 0) { + // Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + return -1; + } + break; case V_ASN1_NULL: - cont = NULL; - len = 0; - break; + cont = NULL; + len = 0; + break; case V_ASN1_BOOLEAN: - tbool = (ASN1_BOOLEAN *)pval; - if (*tbool == -1) { - *out_omit = 1; - return 0; + tbool = (ASN1_BOOLEAN *)pval; + if (*tbool == ASN1_BOOLEAN_NONE) { + *out_omit = 1; + return 0; + } + if (it->utype != V_ASN1_ANY) { + // Default handling if value == size field then omit + if ((*tbool && (it->size > 0)) || (!*tbool && !it->size)) { + *out_omit = 1; + return 0; } - if (it->utype != V_ASN1_ANY) { - /* - * Default handling if value == size field then omit - */ - if ((*tbool && (it->size > 0)) || - (!*tbool && !it->size)) { - *out_omit = 1; - return 0; - } - } - c = *tbool ? 0xff : 0x00; - cont = &c; - len = 1; - break; + } + c = *tbool ? 0xff : 0x00; + cont = &c; + len = 1; + break; case V_ASN1_BIT_STRING: { - int ret = i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, - cout ? &cout : NULL); - /* |i2c_ASN1_BIT_STRING| returns zero on error instead of -1. */ - return ret <= 0 ? -1 : ret; + int ret = + i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); + // |i2c_ASN1_BIT_STRING| returns zero on error instead of -1. + return ret <= 0 ? -1 : ret; } case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: { - /* |i2c_ASN1_INTEGER| also handles ENUMERATED. */ - int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); - /* |i2c_ASN1_INTEGER| returns zero on error instead of -1. */ - return ret <= 0 ? -1 : ret; + // |i2c_ASN1_INTEGER| also handles ENUMERATED. + int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + // |i2c_ASN1_INTEGER| returns zero on error instead of -1. + return ret <= 0 ? -1 : ret; } case V_ASN1_OCTET_STRING: @@ -695,16 +691,23 @@ static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit, case V_ASN1_UTF8STRING: case V_ASN1_SEQUENCE: case V_ASN1_SET: + // This is not a valid |ASN1_ITEM| type, but it appears in |ASN1_TYPE|. + case V_ASN1_OTHER: + // TODO(crbug.com/boringssl/412): This default case should be removed, now + // that we've resolved https://crbug.com/boringssl/561. However, it is still + // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE| + // broadly doesn't tolerate unrecognized universal tags, but except for + // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the + // X509Test.NameAttributeValues test. default: - /* All based on ASN1_STRING and handled the same */ - strtmp = (ASN1_STRING *)*pval; - cont = strtmp->data; - len = strtmp->length; - - break; - - } - if (cout && len) - OPENSSL_memcpy(cout, cont, len); - return len; + // All based on ASN1_STRING and handled the same + strtmp = (ASN1_STRING *)*pval; + cont = strtmp->data; + len = strtmp->length; + break; + } + if (cout && len) { + OPENSSL_memcpy(cout, cont, len); + } + return len; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_fre.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_fre.c index b8479014..add46f53 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_fre.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_fre.c @@ -63,171 +63,150 @@ #include "internal.h" -/* Free up an ASN1 structure */ +// Free up an ASN1 structure -void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) -{ - asn1_item_combine_free(&val, it, 0); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) { + ASN1_item_ex_free(&val, it); } -void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - asn1_item_combine_free(pval, it, 0); -} - -void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) -{ - const ASN1_TEMPLATE *tt = NULL, *seqtt; - const ASN1_EXTERN_FUNCS *ef; - int i; - if (!pval) - return; - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) - return; - - switch (it->itype) { +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { + const ASN1_TEMPLATE *tt = NULL, *seqtt; + const ASN1_EXTERN_FUNCS *ef; + int i; + if (!pval) { + return; + } + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) { + return; + } + switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: - if (it->templates) - ASN1_template_free(pval, it->templates); - else - ASN1_primitive_free(pval, it); - break; + if (it->templates) { + ASN1_template_free(pval, it->templates); + } else { + ASN1_primitive_free(pval, it); + } + break; case ASN1_ITYPE_MSTRING: - ASN1_primitive_free(pval, it); - break; + ASN1_primitive_free(pval, it); + break; case ASN1_ITYPE_CHOICE: { - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); - if (i == 2) - return; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) { + return; } - i = asn1_get_choice_selector(pval, it); - if ((i >= 0) && (i < it->tcount)) { - ASN1_VALUE **pchval; - tt = it->templates + i; - pchval = asn1_get_field_ptr(pval, tt); - ASN1_template_free(pchval, tt); - } - if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } - break; + } + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + tt = it->templates + i; + pchval = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchval, tt); + } + if (asn1_cb) { + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + } + OPENSSL_free(*pval); + *pval = NULL; + break; } case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_free) - ef->asn1_ex_free(pval, it); - break; + ef = it->funcs; + if (ef && ef->asn1_ex_free) { + ef->asn1_ex_free(pval, it); + } + break; case ASN1_ITYPE_SEQUENCE: { - if (!asn1_refcount_dec_and_test_zero(pval, it)) - return; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); - if (i == 2) - return; + if (!asn1_refcount_dec_and_test_zero(pval, it)) { + return; + } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) { + return; } - asn1_enc_free(pval, it); - /* - * If we free up as normal we will invalidate any ANY DEFINED BY - * field and we wont be able to determine the type of the field it - * defines. So free up in reverse order. - */ - tt = it->templates + it->tcount - 1; - for (i = 0; i < it->tcount; tt--, i++) { - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 0); - if (!seqtt) - continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); + } + asn1_enc_free(pval, it); + // If we free up as normal we will invalidate any ANY DEFINED BY + // field and we wont be able to determine the type of the field it + // defines. So free up in reverse order. + tt = it->templates + it->tcount - 1; + for (i = 0; i < it->tcount; tt--, i++) { + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (!seqtt) { + continue; } - if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } - break; - } + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + if (asn1_cb) { + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + } + OPENSSL_free(*pval); + *pval = NULL; + break; } + } } -void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - size_t i; - if (tt->flags & ASN1_TFLG_SK_MASK) { - STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - ASN1_VALUE *vtmp; - vtmp = sk_ASN1_VALUE_value(sk, i); - asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); - } - sk_ASN1_VALUE_free(sk); - *pval = NULL; - } else - asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), - tt->flags & ASN1_TFLG_COMBINE); +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + } + sk_ASN1_VALUE_free(sk); + *pval = NULL; + } else { + ASN1_item_ex_free(pval, ASN1_ITEM_ptr(tt->item)); + } } -void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int utype; - /* Historically, |it->funcs| for primitive types contained an - * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ - assert(it == NULL || it->funcs == NULL); - /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ - if (!it) { - ASN1_TYPE *typ = (ASN1_TYPE *)*pval; - utype = typ->type; - pval = &typ->value.asn1_value; - if (utype != V_ASN1_BOOLEAN && !*pval) - return; - } else if (it->itype == ASN1_ITYPE_MSTRING) { - utype = -1; - if (!*pval) - return; - } else { - utype = it->utype; - if ((utype != V_ASN1_BOOLEAN) && !*pval) - return; - } +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of calbacks. + assert(it->funcs == NULL); - switch (utype) { + int utype = it->itype == ASN1_ITYPE_MSTRING ? -1 : it->utype; + switch (utype) { case V_ASN1_OBJECT: - ASN1_OBJECT_free((ASN1_OBJECT *)*pval); - break; + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + break; case V_ASN1_BOOLEAN: - if (it) - *(ASN1_BOOLEAN *)pval = it->size; - else - *(ASN1_BOOLEAN *)pval = -1; - return; + if (it) { + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; + } else { + *(ASN1_BOOLEAN *)pval = ASN1_BOOLEAN_NONE; + } + return; case V_ASN1_NULL: - break; + break; case V_ASN1_ANY: - ASN1_primitive_free(pval, NULL); + if (*pval != NULL) { + asn1_type_cleanup((ASN1_TYPE *)*pval); OPENSSL_free(*pval); - break; + } + break; default: - ASN1_STRING_free((ASN1_STRING *)*pval); - *pval = NULL; - break; - } - *pval = NULL; + ASN1_STRING_free((ASN1_STRING *)*pval); + *pval = NULL; + break; + } + *pval = NULL; } diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_new.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_new.c index eea219d6..8a90b436 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_new.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_new.c @@ -63,270 +63,264 @@ #include #include -#include "internal.h" #include "../internal.h" +#include "internal.h" -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); -ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) -{ - ASN1_VALUE *ret = NULL; - if (ASN1_item_ex_new(&ret, it) > 0) - return ret; - return NULL; +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) { + ASN1_VALUE *ret = NULL; + if (ASN1_item_ex_new(&ret, it) > 0) { + return ret; + } + return NULL; } -/* Allocate an ASN1 structure */ +// Allocate an ASN1 structure -int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - return asn1_item_ex_combine_new(pval, it, 0); -} - -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) -{ - const ASN1_TEMPLATE *tt = NULL; - const ASN1_EXTERN_FUNCS *ef; - ASN1_VALUE **pseqval; - int i; - - switch (it->itype) { +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { + const ASN1_TEMPLATE *tt = NULL; + const ASN1_EXTERN_FUNCS *ef; + ASN1_VALUE **pseqval; + int i; + switch (it->itype) { case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_new) { - if (!ef->asn1_ex_new(pval, it)) - goto memerr; + ef = it->funcs; + if (ef && ef->asn1_ex_new) { + if (!ef->asn1_ex_new(pval, it)) { + goto memerr; } - break; + } + break; case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - if (!ASN1_template_new(pval, it->templates)) - goto memerr; - } else if (!ASN1_primitive_new(pval, it)) - goto memerr; - break; + if (it->templates) { + if (!ASN1_template_new(pval, it->templates)) { + goto memerr; + } + } else if (!ASN1_primitive_new(pval, it)) { + goto memerr; + } + break; case ASN1_ITYPE_MSTRING: - if (!ASN1_primitive_new(pval, it)) - goto memerr; - break; + if (!ASN1_primitive_new(pval, it)) { + goto memerr; + } + break; case ASN1_ITYPE_CHOICE: { - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); - if (!i) - goto auxerr; - if (i == 2) { - return 1; - } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) { + goto auxerr; } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) - goto memerr; - OPENSSL_memset(*pval, 0, it->size); + if (i == 2) { + return 1; } - asn1_set_choice_selector(pval, -1, it); - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr2; - break; + } + *pval = OPENSSL_malloc(it->size); + if (!*pval) { + goto memerr; + } + OPENSSL_memset(*pval, 0, it->size); + asn1_set_choice_selector(pval, -1, it); + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) { + goto auxerr2; + } + break; } case ASN1_ITYPE_SEQUENCE: { - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; - if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); - if (!i) - goto auxerr; - if (i == 2) { - return 1; - } + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) { + goto auxerr; } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) - goto memerr; - OPENSSL_memset(*pval, 0, it->size); - asn1_refcount_set_one(pval, it); - asn1_enc_init(pval, it); + if (i == 2) { + return 1; } - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - pseqval = asn1_get_field_ptr(pval, tt); - if (!ASN1_template_new(pseqval, tt)) - goto memerr2; + } + *pval = OPENSSL_malloc(it->size); + if (!*pval) { + goto memerr; + } + OPENSSL_memset(*pval, 0, it->size); + asn1_refcount_set_one(pval, it); + asn1_enc_init(pval, it); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + pseqval = asn1_get_field_ptr(pval, tt); + if (!ASN1_template_new(pseqval, tt)) { + goto memerr2; } - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr2; - break; + } + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) { + goto auxerr2; + } + break; } - } - return 1; + } + return 1; - memerr2: - asn1_item_combine_free(pval, it, combine); - memerr: - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return 0; - - auxerr2: - asn1_item_combine_free(pval, it, combine); - auxerr: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); - return 0; +memerr2: + ASN1_item_ex_free(pval, it); +memerr: + return 0; +auxerr2: + ASN1_item_ex_free(pval, it); +auxerr: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); + return 0; } -static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - const ASN1_EXTERN_FUNCS *ef; - - switch (it->itype) { +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { + const ASN1_EXTERN_FUNCS *ef; + switch (it->itype) { case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_clear) - ef->asn1_ex_clear(pval, it); - else - *pval = NULL; - break; + ef = it->funcs; + if (ef && ef->asn1_ex_clear) { + ef->asn1_ex_clear(pval, it); + } else { + *pval = NULL; + } + break; case ASN1_ITYPE_PRIMITIVE: - if (it->templates) - asn1_template_clear(pval, it->templates); - else - asn1_primitive_clear(pval, it); - break; + if (it->templates) { + asn1_template_clear(pval, it->templates); + } else { + asn1_primitive_clear(pval, it); + } + break; case ASN1_ITYPE_MSTRING: - asn1_primitive_clear(pval, it); - break; + asn1_primitive_clear(pval, it); + break; case ASN1_ITYPE_CHOICE: case ASN1_ITYPE_SEQUENCE: - *pval = NULL; - break; - } + *pval = NULL; + break; + } } -static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); - int ret; - if (tt->flags & ASN1_TFLG_OPTIONAL) { - asn1_template_clear(pval, tt); - return 1; - } - /* If ANY DEFINED BY nothing to do */ +static int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { + const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); + int ret; + if (tt->flags & ASN1_TFLG_OPTIONAL) { + asn1_template_clear(pval, tt); + return 1; + } + // If ANY DEFINED BY nothing to do - if (tt->flags & ASN1_TFLG_ADB_MASK) { - *pval = NULL; - return 1; + if (tt->flags & ASN1_TFLG_ADB_MASK) { + *pval = NULL; + return 1; + } + // If SET OF or SEQUENCE OF, its a STACK + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *skval; + skval = sk_ASN1_VALUE_new_null(); + if (!skval) { + ret = 0; + goto done; } - /* If SET OF or SEQUENCE OF, its a STACK */ - if (tt->flags & ASN1_TFLG_SK_MASK) { - STACK_OF(ASN1_VALUE) *skval; - skval = sk_ASN1_VALUE_new_null(); - if (!skval) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - ret = 0; - goto done; - } - *pval = (ASN1_VALUE *)skval; - ret = 1; - goto done; - } - /* Otherwise pass it back to the item routine */ - ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); - done: - return ret; + *pval = (ASN1_VALUE *)skval; + ret = 1; + goto done; + } + // Otherwise pass it back to the item routine + ret = ASN1_item_ex_new(pval, it); +done: + return ret; } -static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - /* If ADB or STACK just NULL the field */ - if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) - *pval = NULL; - else - asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { + // If ADB or STACK just NULL the field + if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) { + *pval = NULL; + } else { + asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); + } } -/* - * NB: could probably combine most of the real XXX_new() behaviour and junk - * all the old functions. - */ +// NB: could probably combine most of the real XXX_new() behaviour and junk +// all the old functions. -static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - ASN1_TYPE *typ; - int utype; +static int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { + if (!it) { + return 0; + } - if (!it) - return 0; + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of calbacks. + assert(it->funcs == NULL); - /* Historically, |it->funcs| for primitive types contained an - * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ - assert(it->funcs == NULL); - - if (it->itype == ASN1_ITYPE_MSTRING) - utype = -1; - else - utype = it->utype; - switch (utype) { + int utype; + if (it->itype == ASN1_ITYPE_MSTRING) { + utype = -1; + } else { + utype = it->utype; + } + switch (utype) { case V_ASN1_OBJECT: - *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); - return 1; + *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); + return 1; case V_ASN1_BOOLEAN: - *(ASN1_BOOLEAN *)pval = it->size; - return 1; + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; + return 1; case V_ASN1_NULL: - *pval = (ASN1_VALUE *)1; - return 1; + *pval = (ASN1_VALUE *)1; + return 1; - case V_ASN1_ANY: - typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); - if (!typ) - return 0; - typ->value.ptr = NULL; - typ->type = -1; - *pval = (ASN1_VALUE *)typ; - break; + case V_ASN1_ANY: { + ASN1_TYPE *typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); + if (!typ) { + return 0; + } + typ->value.ptr = NULL; + typ->type = -1; + *pval = (ASN1_VALUE *)typ; + break; + } default: - *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); - break; - } - if (*pval) - return 1; - return 0; + *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); + break; + } + if (*pval) { + return 1; + } + return 0; } -static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int utype; - /* Historically, |it->funcs| for primitive types contained an - * |ASN1_PRIMITIVE_FUNCS| table of calbacks. */ - assert(it == NULL || it->funcs == NULL); - if (!it || (it->itype == ASN1_ITYPE_MSTRING)) - utype = -1; - else - utype = it->utype; - if (utype == V_ASN1_BOOLEAN) - *(ASN1_BOOLEAN *)pval = it->size; - else - *pval = NULL; +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) { + int utype; + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of calbacks. + assert(it == NULL || it->funcs == NULL); + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) { + utype = -1; + } else { + utype = it->utype; + } + if (utype == V_ASN1_BOOLEAN) { + *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size; + } else { + *pval = NULL; + } } diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_typ.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_typ.c index 5cfdd574..ebeda542 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_typ.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_typ.c @@ -58,19 +58,13 @@ #include -/* Declarations for string types */ +// Declarations for string types -#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ - IMPLEMENT_ASN1_TYPE(sname) \ - IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \ - sname *sname##_new(void) \ - { \ - return ASN1_STRING_type_new(V_##sname); \ - } \ - void sname##_free(sname *x) \ - { \ - ASN1_STRING_free(x); \ - } +#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ + IMPLEMENT_ASN1_TYPE(sname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \ + sname *sname##_new(void) { return ASN1_STRING_type_new(V_##sname); } \ + void sname##_free(sname *x) { ASN1_STRING_free(x); } IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING) IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER) @@ -94,12 +88,12 @@ IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) IMPLEMENT_ASN1_TYPE(ASN1_ANY) -/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ +// Just swallow an ASN1_SEQUENCE in an ASN1_STRING IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) -/* Multistring types */ +// Multistring types IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, ASN1_PRINTABLE, @@ -112,20 +106,21 @@ IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) IMPLEMENT_ASN1_FUNCTIONS_const_fname(ASN1_STRING, DIRECTORYSTRING, DIRECTORYSTRING) -/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ -IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) -IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) -IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) - -/* Special, OCTET STRING with indefinite length constructed support */ +// Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_NONE) +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_TRUE) +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, ASN1_BOOLEAN_FALSE) ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) -ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, + ASN1_SET_ANY, ASN1_ANY) ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, + ASN1_SEQUENCE_ANY, + ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, + ASN1_SET_ANY) diff --git a/third_party/boringssl/kit/src/crypto/asn1/tasn_utl.c b/third_party/boringssl/kit/src/crypto/asn1/tasn_utl.c index 9b1da0b7..488c206c 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/tasn_utl.c +++ b/third_party/boringssl/kit/src/crypto/asn1/tasn_utl.c @@ -60,27 +60,28 @@ #include #include +#include #include #include -#include +#include #include #include "../internal.h" #include "internal.h" -/* Utility functions for manipulating fields and offsets */ +// Utility functions for manipulating fields and offsets -/* Add 'offset' to 'addr' */ +// Add 'offset' to 'addr' #define offset2ptr(addr, offset) (void *)(((char *)(addr)) + (offset)) -/* Given an ASN1_ITEM CHOICE type return the selector value */ +// Given an ASN1_ITEM CHOICE type return the selector value int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) { int *sel = offset2ptr(*pval, it->utype); return *sel; } -/* Given an ASN1_ITEM CHOICE type set the selector value, return old value. */ +// Given an ASN1_ITEM CHOICE type set the selector value, return old value. int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it) { int *sel, ret; @@ -131,68 +132,62 @@ static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { } void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); if (enc) { enc->enc = NULL; enc->len = 0; - enc->alias_only = 0; - enc->alias_only_on_next_parse = 0; - enc->modified = 1; + enc->buf = NULL; } } void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); if (enc) { - if (enc->enc && !enc->alias_only) { - OPENSSL_free(enc->enc); - } - enc->enc = NULL; - enc->len = 0; - enc->alias_only = 0; - enc->alias_only_on_next_parse = 0; - enc->modified = 1; + asn1_encoding_clear(enc); } } -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it) { +int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, + const ASN1_ITEM *it, CRYPTO_BUFFER *buf) { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); if (!enc) { return 1; } - if (!enc->alias_only) { - OPENSSL_free(enc->enc); - } - - enc->alias_only = enc->alias_only_on_next_parse; - enc->alias_only_on_next_parse = 0; - - if (enc->alias_only) { - enc->enc = (uint8_t *) in; + asn1_encoding_clear(enc); + if (buf != NULL) { + assert(CRYPTO_BUFFER_data(buf) <= in && + in + in_len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + CRYPTO_BUFFER_up_ref(buf); + enc->buf = buf; + enc->enc = (uint8_t *)in; } else { - enc->enc = OPENSSL_malloc(inlen); + enc->enc = OPENSSL_memdup(in, in_len); if (!enc->enc) { return 0; } - OPENSSL_memcpy(enc->enc, in, inlen); } - enc->len = inlen; - enc->modified = 0; - + enc->len = in_len; return 1; } +void asn1_encoding_clear(ASN1_ENCODING *enc) { + if (enc->buf != NULL) { + CRYPTO_BUFFER_free(enc->buf); + } else { + OPENSSL_free(enc->enc); + } + enc->enc = NULL; + enc->len = 0; + enc->buf = NULL; +} + int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc || enc->modified) { + ASN1_ENCODING *enc = asn1_get_enc_ptr(pval, it); + if (!enc || enc->len == 0) { return 0; } if (out) { @@ -205,38 +200,33 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, return 1; } -/* Given an ASN1_TEMPLATE get a pointer to a field */ +// Given an ASN1_TEMPLATE get a pointer to a field ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) { - ASN1_VALUE **pvaltmp; - if (tt->flags & ASN1_TFLG_COMBINE) { - return pval; - } - pvaltmp = offset2ptr(*pval, tt->offset); - /* NOTE for BOOLEAN types the field is just a plain int so we can't return - * int **, so settle for (int *). */ + ASN1_VALUE **pvaltmp = offset2ptr(*pval, tt->offset); + // NOTE for BOOLEAN types the field is just a plain int so we can't return + // int **, so settle for (int *). return pvaltmp; } -/* Handle ANY DEFINED BY template, find the selector, look up the relevant - * ASN1_TEMPLATE in the table and return it. */ +// Handle ANY DEFINED BY template, find the selector, look up the relevant +// ASN1_TEMPLATE in the table and return it. const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr) { const ASN1_ADB *adb; const ASN1_ADB_TABLE *atbl; - long selector; ASN1_VALUE **sfld; int i; if (!(tt->flags & ASN1_TFLG_ADB_MASK)) { return tt; } - /* Else ANY DEFINED BY ... get the table */ + // Else ANY DEFINED BY ... get the table adb = ASN1_ADB_ptr(tt->item); - /* Get the selector field */ + // Get the selector field sfld = offset2ptr(*pval, adb->offset); - /* Check if NULL */ + // Check if NULL if (*sfld == NULL) { if (!adb->null_tt) { goto err; @@ -244,19 +234,16 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, return adb->null_tt; } - /* Convert type to a long: - * NB: don't check for NID_undef here because it - * might be a legitimate value in the table */ - if (tt->flags & ASN1_TFLG_ADB_OID) { - selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); - } else { - selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); - } + // Convert type to a NID: + // NB: don't check for NID_undef here because it + // might be a legitimate value in the table + assert(tt->flags & ASN1_TFLG_ADB_OID); + int selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); - /* Try to find matching entry in table Maybe should check application types - * first to allow application override? Might also be useful to have a flag - * which indicates table is sorted and we can do a binary search. For now - * stick to a linear search. */ + // Try to find matching entry in table Maybe should check application types + // first to allow application override? Might also be useful to have a flag + // which indicates table is sorted and we can do a binary search. For now + // stick to a linear search. for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) { if (atbl->value == selector) { @@ -264,16 +251,16 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, } } - /* FIXME: need to search application table too */ + // FIXME: need to search application table too - /* No match, return default type */ + // No match, return default type if (!adb->default_tt) { goto err; } return adb->default_tt; err: - /* FIXME: should log the value or OID of unsupported type */ + // FIXME: should log the value or OID of unsupported type if (nullerr) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); } diff --git a/third_party/boringssl/kit/src/crypto/asn1/time_support.c b/third_party/boringssl/kit/src/crypto/asn1/time_support.c deleted file mode 100644 index e748ad75..00000000 --- a/third_party/boringssl/kit/src/crypto/asn1/time_support.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL - * project 2001. - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 2008. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 201410L /* for gmtime_r */ -#endif - -#include "internal.h" - -#include - - -#define SECS_PER_DAY (24 * 60 * 60) - -struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result) { -#if defined(OPENSSL_WINDOWS) - if (gmtime_s(result, time)) { - return NULL; - } - return result; -#else - return gmtime_r(time, result); -#endif -} - -/* Convert date to and from julian day Uses Fliegel & Van Flandern algorithm */ -static long date_to_julian(int y, int m, int d) { - return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + - (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - - (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; -} - -static void julian_to_date(long jd, int *y, int *m, int *d) { - long L = jd + 68569; - long n = (4 * L) / 146097; - long i, j; - - L = L - (146097 * n + 3) / 4; - i = (4000 * (L + 1)) / 1461001; - L = L - (1461 * i) / 4 + 31; - j = (80 * L) / 2447; - *d = L - (2447 * j) / 80; - L = j / 11; - *m = j + 2 - (12 * L); - *y = 100 * (n - 49) + i + L; -} - -/* Convert tm structure and offset into julian day and seconds */ -static int julian_adj(const struct tm *tm, int off_day, long offset_sec, - long *pday, int *psec) { - int offset_hms, offset_day; - long time_jd; - int time_year, time_month, time_day; - /* split offset into days and day seconds */ - offset_day = offset_sec / SECS_PER_DAY; - /* Avoid sign issues with % operator */ - offset_hms = offset_sec - (offset_day * SECS_PER_DAY); - offset_day += off_day; - /* Add current time seconds to offset */ - offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; - /* Adjust day seconds if overflow */ - if (offset_hms >= SECS_PER_DAY) { - offset_day++; - offset_hms -= SECS_PER_DAY; - } else if (offset_hms < 0) { - offset_day--; - offset_hms += SECS_PER_DAY; - } - - /* Convert date of time structure into a Julian day number. */ - - time_year = tm->tm_year + 1900; - time_month = tm->tm_mon + 1; - time_day = tm->tm_mday; - - time_jd = date_to_julian(time_year, time_month, time_day); - - /* Work out Julian day of new date */ - time_jd += offset_day; - - if (time_jd < 0) { - return 0; - } - - *pday = time_jd; - *psec = offset_hms; - return 1; -} - -int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { - int time_sec, time_year, time_month, time_day; - long time_jd; - - /* Convert time and offset into julian day and seconds */ - if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec)) { - return 0; - } - - /* Convert Julian day back to date */ - - julian_to_date(time_jd, &time_year, &time_month, &time_day); - - if (time_year < 1900 || time_year > 9999) { - return 0; - } - - /* Update tm structure */ - - tm->tm_year = time_year - 1900; - tm->tm_mon = time_month - 1; - tm->tm_mday = time_day; - - tm->tm_hour = time_sec / 3600; - tm->tm_min = (time_sec / 60) % 60; - tm->tm_sec = time_sec % 60; - - return 1; -} - -int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, - const struct tm *to) { - int from_sec, to_sec, diff_sec; - long from_jd, to_jd, diff_day; - - if (!julian_adj(from, 0, 0, &from_jd, &from_sec)) { - return 0; - } - if (!julian_adj(to, 0, 0, &to_jd, &to_sec)) { - return 0; - } - - diff_day = to_jd - from_jd; - diff_sec = to_sec - from_sec; - /* Adjust differences so both positive or both negative */ - if (diff_day > 0 && diff_sec < 0) { - diff_day--; - diff_sec += SECS_PER_DAY; - } - if (diff_day < 0 && diff_sec > 0) { - diff_day++; - diff_sec -= SECS_PER_DAY; - } - - if (out_days) { - *out_days = (int)diff_day; - } - if (out_secs) { - *out_secs = diff_sec; - } - - return 1; -} diff --git a/third_party/boringssl/kit/src/crypto/base64/base64.c b/third_party/boringssl/kit/src/crypto/base64/base64.c index 6ce6007f..d2b1e584 100644 --- a/third_party/boringssl/kit/src/crypto/base64/base64.c +++ b/third_party/boringssl/kit/src/crypto/base64/base64.c @@ -60,8 +60,6 @@ #include #include -#include - #include "../internal.h" @@ -98,8 +96,8 @@ static uint8_t conv_bin2ascii(uint8_t a) { return ret; } -OPENSSL_STATIC_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0, - "data length must be a multiple of base64 chunk size"); +static_assert(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0, + "data length must be a multiple of base64 chunk size"); int EVP_EncodedLength(size_t *out_len, size_t len) { if (len + 2 < len) { diff --git a/third_party/boringssl/kit/src/crypto/bio/bio.c b/third_party/boringssl/kit/src/crypto/bio/bio.c index 3d36e28d..b2d95638 100644 --- a/third_party/boringssl/kit/src/crypto/bio/bio.c +++ b/third_party/boringssl/kit/src/crypto/bio/bio.c @@ -72,7 +72,6 @@ BIO *BIO_new(const BIO_METHOD *method) { BIO *ret = OPENSSL_malloc(sizeof(BIO)); if (ret == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -192,11 +191,17 @@ int BIO_write_all(BIO *bio, const void *data, size_t len) { } int BIO_puts(BIO *bio, const char *in) { - return BIO_write(bio, in, strlen(in)); + size_t len = strlen(in); + if (len > INT_MAX) { + // |BIO_write| and the return value both assume the string fits in |int|. + OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW); + return -1; + } + return BIO_write(bio, in, (int)len); } int BIO_flush(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); } long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) { @@ -229,11 +234,11 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { } int BIO_reset(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); } int BIO_eof(BIO *bio) { - return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); } void BIO_set_flags(BIO *bio, int flags) { @@ -333,7 +338,7 @@ size_t BIO_wpending(const BIO *bio) { } int BIO_set_close(BIO *bio, int close_flag) { - return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); + return (int)BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); } OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { @@ -418,7 +423,7 @@ int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) { } static int print_bio(const char *str, size_t len, void *bio) { - return BIO_write((BIO *)bio, str, len); + return BIO_write_all((BIO *)bio, str, len); } void ERR_print_errors(BIO *bio) { @@ -457,9 +462,11 @@ static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, OPENSSL_free(*out); return 0; } - const size_t todo = len - done; - assert(todo < INT_MAX); - const int n = BIO_read(bio, *out + done, todo); + size_t todo = len - done; + if (todo > INT_MAX) { + todo = INT_MAX; + } + const int n = BIO_read(bio, *out + done, (int)todo); if (n == 0) { *out_len = done; return 1; @@ -603,7 +610,6 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { *out = OPENSSL_malloc(len); if (*out == NULL) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memcpy(*out, header, header_len); @@ -622,14 +628,14 @@ void BIO_set_retry_special(BIO *bio) { int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; } -static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX g_index_lock = CRYPTO_MUTEX_INIT; static int g_index = BIO_TYPE_START; int BIO_get_new_index(void) { - CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock); + CRYPTO_MUTEX_lock_write(&g_index_lock); // If |g_index| exceeds 255, it will collide with the flags bits. int ret = g_index > 255 ? -1 : g_index++; - CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock); + CRYPTO_MUTEX_unlock_write(&g_index_lock); return ret; } diff --git a/third_party/boringssl/kit/src/crypto/bio/bio_mem.c b/third_party/boringssl/kit/src/crypto/bio/bio_mem.c index f40a9a79..5d7534c2 100644 --- a/third_party/boringssl/kit/src/crypto/bio/bio_mem.c +++ b/third_party/boringssl/kit/src/crypto/bio/bio_mem.c @@ -66,7 +66,7 @@ #include "../internal.h" -BIO *BIO_new_mem_buf(const void *buf, int len) { +BIO *BIO_new_mem_buf(const void *buf, ossl_ssize_t len) { BIO *ret; BUF_MEM *b; const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len; @@ -130,13 +130,15 @@ static int mem_free(BIO *bio) { } static int mem_read(BIO *bio, char *out, int outl) { - int ret; - BUF_MEM *b = (BUF_MEM*) bio->ptr; - BIO_clear_retry_flags(bio); - ret = outl; - if (b->length < INT_MAX && ret > (int)b->length) { - ret = b->length; + if (outl <= 0) { + return 0; + } + + BUF_MEM *b = bio->ptr; + int ret = outl; + if ((size_t)ret > b->length) { + ret = (int)b->length; } if (ret > 0) { @@ -157,70 +159,53 @@ static int mem_read(BIO *bio, char *out, int outl) { } static int mem_write(BIO *bio, const char *in, int inl) { - int ret = -1; - int blen; - BUF_MEM *b; - - b = (BUF_MEM *)bio->ptr; + BIO_clear_retry_flags(bio); + if (inl <= 0) { + return 0; // Successfully write zero bytes. + } if (bio->flags & BIO_FLAGS_MEM_RDONLY) { OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); - goto err; + return -1; } - BIO_clear_retry_flags(bio); - blen = b->length; - if (INT_MAX - blen < inl) { - goto err; + BUF_MEM *b = bio->ptr; + if (!BUF_MEM_append(b, in, inl)) { + return -1; } - if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) { - goto err; - } - OPENSSL_memcpy(&b->data[blen], in, inl); - ret = inl; -err: - return ret; + return inl; } static int mem_gets(BIO *bio, char *buf, int size) { - int i, j; - char *p; - BUF_MEM *b = (BUF_MEM *)bio->ptr; - BIO_clear_retry_flags(bio); - j = b->length; - if (size - 1 < j) { - j = size - 1; - } - if (j <= 0) { - if (size > 0) { - *buf = 0; - } + if (size <= 0) { return 0; } - p = b->data; - for (i = 0; i < j; i++) { - if (p[i] == '\n') { - i++; - break; - } + // The buffer size includes space for the trailing NUL, so we can read at most + // one fewer byte. + BUF_MEM *b = bio->ptr; + int ret = size - 1; + if ((size_t)ret > b->length) { + ret = (int)b->length; } - // i is now the max num of bytes to copy, either j or up to and including the - // first newline - - i = mem_read(bio, buf, i); - if (i > 0) { - buf[i] = '\0'; + // Stop at the first newline. + const char *newline = OPENSSL_memchr(b->data, '\n', ret); + if (newline != NULL) { + ret = (int)(newline - b->data + 1); } - return i; + + ret = mem_read(bio, buf, ret); + if (ret >= 0) { + buf[ret] = '\0'; + } + return ret; } static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { long ret = 1; - char **pptr; BUF_MEM *b = (BUF_MEM *)bio->ptr; @@ -246,8 +231,8 @@ static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { case BIO_CTRL_INFO: ret = (long)b->length; if (ptr != NULL) { - pptr = (char **)ptr; - *pptr = (char *)&b->data[0]; + char **pptr = ptr; + *pptr = b->data; } break; case BIO_C_SET_BUF_MEM: @@ -257,8 +242,8 @@ static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { break; case BIO_C_GET_BUF_MEM_PTR: if (ptr != NULL) { - pptr = (char **)ptr; - *pptr = (char *)b; + BUF_MEM **pptr = ptr; + *pptr = b; } break; case BIO_CTRL_GET_CLOSE: @@ -308,17 +293,17 @@ int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, } long BIO_get_mem_data(BIO *bio, char **contents) { - return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents); + return BIO_ctrl(bio, BIO_CTRL_INFO, 0, contents); } int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { - return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); + return (int)BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, out); } int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) { - return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); + return (int)BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, b); } int BIO_set_mem_eof_return(BIO *bio, int eof_value) { - return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); + return (int)BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); } diff --git a/third_party/boringssl/kit/src/crypto/bio/bio_test.cc b/third_party/boringssl/kit/src/crypto/bio/bio_test.cc index 765e9629..8827ce61 100644 --- a/third_party/boringssl/kit/src/crypto/bio/bio_test.cc +++ b/third_party/boringssl/kit/src/crypto/bio/bio_test.cc @@ -154,73 +154,336 @@ TEST(BIOTest, Printf) { } } -static const size_t kLargeASN1PayloadLen = 8000; +TEST(BIOTest, ReadASN1) { + static const size_t kLargeASN1PayloadLen = 8000; -struct ASN1TestParam { - bool should_succeed; - std::vector input; - // suffix_len is the number of zeros to append to |input|. - size_t suffix_len; - // expected_len, if |should_succeed| is true, is the expected length of the - // ASN.1 element. - size_t expected_len; - size_t max_len; -} kASN1TestParams[] = { - {true, {0x30, 2, 1, 2, 0, 0}, 0, 4, 100}, - {false /* truncated */, {0x30, 3, 1, 2}, 0, 0, 100}, - {false /* should be short len */, {0x30, 0x81, 1, 1}, 0, 0, 100}, - {false /* zero padded */, {0x30, 0x82, 0, 1, 1}, 0, 0, 100}, + struct ASN1Test { + bool should_succeed; + std::vector input; + // suffix_len is the number of zeros to append to |input|. + size_t suffix_len; + // expected_len, if |should_succeed| is true, is the expected length of the + // ASN.1 element. + size_t expected_len; + size_t max_len; + } kASN1Tests[] = { + {true, {0x30, 2, 1, 2, 0, 0}, 0, 4, 100}, + {false /* truncated */, {0x30, 3, 1, 2}, 0, 0, 100}, + {false /* should be short len */, {0x30, 0x81, 1, 1}, 0, 0, 100}, + {false /* zero padded */, {0x30, 0x82, 0, 1, 1}, 0, 0, 100}, - // Test a large payload. - {true, - {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff}, - kLargeASN1PayloadLen, - 4 + kLargeASN1PayloadLen, - kLargeASN1PayloadLen * 2}, - {false /* max_len too short */, - {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff}, - kLargeASN1PayloadLen, - 4 + kLargeASN1PayloadLen, - 3 + kLargeASN1PayloadLen}, + // Test a large payload. + {true, + {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff}, + kLargeASN1PayloadLen, + 4 + kLargeASN1PayloadLen, + kLargeASN1PayloadLen * 2}, + {false /* max_len too short */, + {0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff}, + kLargeASN1PayloadLen, + 4 + kLargeASN1PayloadLen, + 3 + kLargeASN1PayloadLen}, - // Test an indefinite-length input. - {true, - {0x30, 0x80}, - kLargeASN1PayloadLen + 2, - 2 + kLargeASN1PayloadLen + 2, - kLargeASN1PayloadLen * 2}, - {false /* max_len too short */, - {0x30, 0x80}, - kLargeASN1PayloadLen + 2, - 2 + kLargeASN1PayloadLen + 2, - 2 + kLargeASN1PayloadLen + 1}, -}; + // Test an indefinite-length input. + {true, + {0x30, 0x80}, + kLargeASN1PayloadLen + 2, + 2 + kLargeASN1PayloadLen + 2, + kLargeASN1PayloadLen * 2}, + {false /* max_len too short */, + {0x30, 0x80}, + kLargeASN1PayloadLen + 2, + 2 + kLargeASN1PayloadLen + 2, + 2 + kLargeASN1PayloadLen + 1}, + }; -class BIOASN1Test : public testing::TestWithParam {}; + for (const auto &t : kASN1Tests) { + std::vector input = t.input; + input.resize(input.size() + t.suffix_len, 0); -TEST_P(BIOASN1Test, ReadASN1) { - const ASN1TestParam& param = GetParam(); - std::vector input = param.input; - input.resize(input.size() + param.suffix_len, 0); + bssl::UniquePtr bio(BIO_new_mem_buf(input.data(), input.size())); + ASSERT_TRUE(bio); - bssl::UniquePtr bio(BIO_new_mem_buf(input.data(), input.size())); - ASSERT_TRUE(bio); + uint8_t *out; + size_t out_len; + int ok = BIO_read_asn1(bio.get(), &out, &out_len, t.max_len); + if (!ok) { + out = nullptr; + } + bssl::UniquePtr out_storage(out); - uint8_t *out; - size_t out_len; - int ok = BIO_read_asn1(bio.get(), &out, &out_len, param.max_len); - if (!ok) { - out = nullptr; - } - bssl::UniquePtr out_storage(out); - - ASSERT_EQ(param.should_succeed, (ok == 1)); - if (param.should_succeed) { - EXPECT_EQ(Bytes(input.data(), param.expected_len), Bytes(out, out_len)); + ASSERT_EQ(t.should_succeed, (ok == 1)); + if (t.should_succeed) { + EXPECT_EQ(Bytes(input.data(), t.expected_len), Bytes(out, out_len)); + } } } -INSTANTIATE_TEST_SUITE_P(All, BIOASN1Test, testing::ValuesIn(kASN1TestParams)); +TEST(BIOTest, MemReadOnly) { + // A memory BIO created from |BIO_new_mem_buf| is a read-only buffer. + static const char kData[] = "abcdefghijklmno"; + bssl::UniquePtr bio(BIO_new_mem_buf(kData, strlen(kData))); + ASSERT_TRUE(bio); + + // Writing to read-only buffers should fail. + EXPECT_EQ(BIO_write(bio.get(), kData, strlen(kData)), -1); + + const uint8_t *contents; + size_t len; + ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); + EXPECT_EQ(Bytes(contents, len), Bytes(kData)); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Read less than the whole buffer. + char buf[6]; + int ret = BIO_read(bio.get(), buf, sizeof(buf)); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("abcdef")); + + ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); + EXPECT_EQ(Bytes(contents, len), Bytes("ghijklmno")); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + ret = BIO_read(bio.get(), buf, sizeof(buf)); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("ghijkl")); + + ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); + EXPECT_EQ(Bytes(contents, len), Bytes("mno")); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Read the remainder of the buffer. + ret = BIO_read(bio.get(), buf, sizeof(buf)); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("mno")); + + ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); + EXPECT_EQ(Bytes(contents, len), Bytes("")); + EXPECT_EQ(BIO_eof(bio.get()), 1); + + // By default, reading from a consumed read-only buffer returns EOF. + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), 0); + EXPECT_FALSE(BIO_should_read(bio.get())); + + // A memory BIO can be configured to return an error instead of EOF. This is + // error is returned as retryable. (This is not especially useful here. It + // makes more sense for a writable BIO.) + EXPECT_EQ(BIO_set_mem_eof_return(bio.get(), -1), 1); + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), -1); + EXPECT_TRUE(BIO_should_read(bio.get())); + + // Read exactly the right number of bytes, to test the boundary condition is + // correct. + bio.reset(BIO_new_mem_buf("abc", 3)); + ASSERT_TRUE(bio); + ret = BIO_read(bio.get(), buf, 3); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("abc")); + EXPECT_EQ(BIO_eof(bio.get()), 1); +} + +TEST(BIOTest, MemWritable) { + // A memory BIO created from |BIO_new| is writable. + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio); + + auto check_bio_contents = [&](Bytes b) { + const uint8_t *contents; + size_t len; + ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); + EXPECT_EQ(Bytes(contents, len), b); + + char *contents_c; + long len_l = BIO_get_mem_data(bio.get(), &contents_c); + ASSERT_GE(len_l, 0); + EXPECT_EQ(Bytes(contents_c, len_l), b); + + BUF_MEM *buf; + ASSERT_EQ(BIO_get_mem_ptr(bio.get(), &buf), 1); + EXPECT_EQ(Bytes(buf->data, buf->length), b); + }; + + // It is initially empty. + check_bio_contents(Bytes("")); + EXPECT_EQ(BIO_eof(bio.get()), 1); + + // Reading from it should default to returning a retryable error. + char buf[32]; + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), -1); + EXPECT_TRUE(BIO_should_read(bio.get())); + + // This can be configured to return an EOF. + EXPECT_EQ(BIO_set_mem_eof_return(bio.get(), 0), 1); + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), 0); + EXPECT_FALSE(BIO_should_read(bio.get())); + + // Restore the default. A writable memory |BIO| is typically used in this mode + // so additional data can be written when exhausted. + EXPECT_EQ(BIO_set_mem_eof_return(bio.get(), -1), 1); + + // Writes append to the buffer. + ASSERT_EQ(BIO_write(bio.get(), "abcdef", 6), 6); + check_bio_contents(Bytes("abcdef")); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Writes can include embedded NULs. + ASSERT_EQ(BIO_write(bio.get(), "\0ghijk", 6), 6); + check_bio_contents(Bytes("abcdef\0ghijk", 12)); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Do a partial read. + int ret = BIO_read(bio.get(), buf, 4); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("abcd")); + check_bio_contents(Bytes("ef\0ghijk", 8)); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Reads and writes may alternate. + ASSERT_EQ(BIO_write(bio.get(), "lmnopq", 6), 6); + check_bio_contents(Bytes("ef\0ghijklmnopq", 14)); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // Reads may consume embedded NULs. + ret = BIO_read(bio.get(), buf, 4); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("ef\0g", 4)); + check_bio_contents(Bytes("hijklmnopq")); + EXPECT_EQ(BIO_eof(bio.get()), 0); + + // The read buffer exceeds the |BIO|, so we consume everything. + ret = BIO_read(bio.get(), buf, sizeof(buf)); + ASSERT_GT(ret, 0); + EXPECT_EQ(Bytes(buf, ret), Bytes("hijklmnopq")); + check_bio_contents(Bytes("")); + EXPECT_EQ(BIO_eof(bio.get()), 1); + + // The |BIO| is now empty. + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), -1); + EXPECT_TRUE(BIO_should_read(bio.get())); + + // Repeat the above, reading exactly the right number of bytes, to test the + // boundary condition is correct. + ASSERT_EQ(BIO_write(bio.get(), "abc", 3), 3); + ret = BIO_read(bio.get(), buf, 3); + EXPECT_EQ(Bytes(buf, ret), Bytes("abc")); + EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), -1); + EXPECT_TRUE(BIO_should_read(bio.get())); + EXPECT_EQ(BIO_eof(bio.get()), 1); +} + +TEST(BIOTest, Gets) { + const struct { + std::string bio; + int gets_len; + std::string gets_result; + } kGetsTests[] = { + // BIO_gets should stop at the first newline. If the buffer is too small, + // stop there instead. Note the buffer size + // includes a trailing NUL. + {"123456789\n123456789", 5, "1234"}, + {"123456789\n123456789", 9, "12345678"}, + {"123456789\n123456789", 10, "123456789"}, + {"123456789\n123456789", 11, "123456789\n"}, + {"123456789\n123456789", 12, "123456789\n"}, + {"123456789\n123456789", 256, "123456789\n"}, + + // If we run out of buffer, read the whole buffer. + {"12345", 5, "1234"}, + {"12345", 6, "12345"}, + {"12345", 10, "12345"}, + + // NUL bytes do not terminate gets. + {std::string("abc\0def\nghi", 11), 256, std::string("abc\0def\n", 8)}, + + // An output size of one means we cannot read any bytes. Only the trailing + // NUL is included. + {"12345", 1, ""}, + + // Empty line. + {"\nabcdef", 256, "\n"}, + // Empty BIO. + {"", 256, ""}, + }; + for (const auto& t : kGetsTests) { + SCOPED_TRACE(t.bio); + SCOPED_TRACE(t.gets_len); + + auto check_bio_gets = [&](BIO *bio) { + std::vector buf(t.gets_len, 'a'); + int ret = BIO_gets(bio, buf.data(), t.gets_len); + ASSERT_GE(ret, 0); + // |BIO_gets| should write a NUL terminator, not counted in the return + // value. + EXPECT_EQ(Bytes(buf.data(), ret + 1), + Bytes(t.gets_result.data(), t.gets_result.size() + 1)); + + // The remaining data should still be in the BIO. + buf.resize(t.bio.size() + 1); + ret = BIO_read(bio, buf.data(), static_cast(buf.size())); + ASSERT_GE(ret, 0); + EXPECT_EQ(Bytes(buf.data(), ret), + Bytes(t.bio.substr(t.gets_result.size()))); + }; + + { + SCOPED_TRACE("memory"); + bssl::UniquePtr bio(BIO_new_mem_buf(t.bio.data(), t.bio.size())); + ASSERT_TRUE(bio); + check_bio_gets(bio.get()); + } + + using ScopedFILE = std::unique_ptr; + ScopedFILE file(tmpfile(), fclose); +#if defined(OPENSSL_ANDROID) + // On Android, when running from an APK, |tmpfile| does not work. See + // b/36991167#comment8. + if (!file) { + fprintf(stderr, "tmpfile failed: %s (%d). Skipping file-based tests.\n", + strerror(errno), errno); + continue; + } +#else + ASSERT_TRUE(file); +#endif + + if (!t.bio.empty()) { + ASSERT_EQ(1u, + fwrite(t.bio.data(), t.bio.size(), /*nitems=*/1, file.get())); + ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); + } + + // TODO(crbug.com/boringssl/585): If the line has an embedded NUL, file + // BIOs do not currently report the answer correctly. + if (t.bio.find('\0') == std::string::npos) { + SCOPED_TRACE("file"); + bssl::UniquePtr bio(BIO_new_fp(file.get(), BIO_NOCLOSE)); + ASSERT_TRUE(bio); + check_bio_gets(bio.get()); + } + + ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); + + { + SCOPED_TRACE("fd"); +#if defined(OPENSSL_WINDOWS) + int fd = _fileno(file.get()); +#else + int fd = fileno(file.get()); +#endif + bssl::UniquePtr bio(BIO_new_fd(fd, BIO_NOCLOSE)); + ASSERT_TRUE(bio); + check_bio_gets(bio.get()); + } + } + + // Negative and zero lengths should not output anything, even a trailing NUL. + bssl::UniquePtr bio(BIO_new_mem_buf("12345", -1)); + ASSERT_TRUE(bio); + char c = 'a'; + EXPECT_EQ(0, BIO_gets(bio.get(), &c, -1)); + EXPECT_EQ(0, BIO_gets(bio.get(), &c, 0)); + EXPECT_EQ(c, 'a'); +} // Run through the tests twice, swapping |bio1| and |bio2|, for symmetry. class BIOPairTest : public testing::TestWithParam {}; diff --git a/third_party/boringssl/kit/src/crypto/bio/connect.c b/third_party/boringssl/kit/src/crypto/bio/connect.c index 3b65acfc..c19f1c4e 100644 --- a/third_party/boringssl/kit/src/crypto/bio/connect.c +++ b/third_party/boringssl/kit/src/crypto/bio/connect.c @@ -117,7 +117,8 @@ static int closesocket(int sock) { // split_host_and_port sets |*out_host| and |*out_port| to the host and port // parsed from |name|. It returns one on success or zero on error. Even when // successful, |*out_port| may be NULL on return if no port was specified. -static int split_host_and_port(char **out_host, char **out_port, const char *name) { +static int split_host_and_port(char **out_host, char **out_port, + const char *name) { const char *host, *port = NULL; size_t host_len = 0; @@ -362,7 +363,7 @@ static int conn_read(BIO *bio, char *out, int out_len) { } bio_clear_socket_error(); - ret = recv(bio->num, out, out_len, 0); + ret = (int)recv(bio->num, out, out_len, 0); BIO_clear_retry_flags(bio); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -386,7 +387,7 @@ static int conn_write(BIO *bio, const char *in, int in_len) { } bio_clear_socket_error(); - ret = send(bio->num, in, in_len, 0); + ret = (int)send(bio->num, in, in_len, 0); BIO_clear_retry_flags(bio); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -466,8 +467,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) { case BIO_CTRL_FLUSH: break; case BIO_CTRL_GET_CALLBACK: { - int (**fptr)(const BIO *bio, int state, int xret); - fptr = (int (**)(const BIO *bio, int state, int xret))ptr; + int (**fptr)(const BIO *bio, int state, int xret) = ptr; *fptr = data->info_callback; } break; default: @@ -485,7 +485,13 @@ static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { switch (cmd) { case BIO_CTRL_SET_CALLBACK: + // This is the actual type signature of |fp|. The caller is expected to + // cast it to |bio_info_cb| due to the |BIO_callback_ctrl| calling + // convention. + OPENSSL_MSVC_PRAGMA(warning(push)) + OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) data->info_callback = (int (*)(const struct bio_st *, int, int))fp; + OPENSSL_MSVC_PRAGMA(warning(pop)) break; default: ret = 0; @@ -517,11 +523,11 @@ static const BIO_METHOD methods_connectp = { const BIO_METHOD *BIO_s_connect(void) { return &methods_connectp; } int BIO_set_conn_hostname(BIO *bio, const char *name) { - return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); + return (int)BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); } int BIO_set_conn_port(BIO *bio, const char *port_str) { - return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); + return (int)BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); } int BIO_set_conn_int_port(BIO *bio, const int *port) { @@ -531,11 +537,11 @@ int BIO_set_conn_int_port(BIO *bio, const int *port) { } int BIO_set_nbio(BIO *bio, int on) { - return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); + return (int)BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); } int BIO_do_connect(BIO *bio) { - return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); + return (int)BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); } #endif // OPENSSL_TRUSTY diff --git a/third_party/boringssl/kit/src/crypto/bio/fd.c b/third_party/boringssl/kit/src/crypto/bio/fd.c index 349ee9dd..7775d7a7 100644 --- a/third_party/boringssl/kit/src/crypto/bio/fd.c +++ b/third_party/boringssl/kit/src/crypto/bio/fd.c @@ -158,7 +158,7 @@ static int fd_free(BIO *bio) { static int fd_read(BIO *b, char *out, int outl) { int ret = 0; - ret = BORINGSSL_READ(b->num, out, outl); + ret = (int)BORINGSSL_READ(b->num, out, outl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -170,7 +170,7 @@ static int fd_read(BIO *b, char *out, int outl) { } static int fd_write(BIO *b, const char *in, int inl) { - int ret = BORINGSSL_WRITE(b->num, in, inl); + int ret = (int)BORINGSSL_WRITE(b->num, in, inl); BIO_clear_retry_flags(b); if (ret <= 0) { if (bio_fd_should_retry(ret)) { @@ -241,20 +241,24 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) { } static int fd_gets(BIO *bp, char *buf, int size) { - char *ptr = buf; - char *end = buf + size - 1; - if (size <= 0) { return 0; } - while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') { + char *ptr = buf; + char *end = buf + size - 1; + while (ptr < end && fd_read(bp, ptr, 1) > 0) { + char c = ptr[0]; ptr++; + if (c == '\n') { + break; + } } ptr[0] = '\0'; - return ptr - buf; + // The output length is bounded by |size|. + return (int)(ptr - buf); } static const BIO_METHOD methods_fdp = { @@ -265,11 +269,11 @@ static const BIO_METHOD methods_fdp = { const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; } int BIO_set_fd(BIO *bio, int fd, int close_flag) { - return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); + return (int)BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); } int BIO_get_fd(BIO *bio, int *out_fd) { - return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); + return (int)BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); } #endif // OPENSSL_TRUSTY diff --git a/third_party/boringssl/kit/src/crypto/bio/file.c b/third_party/boringssl/kit/src/crypto/bio/file.c index 835d661b..8ba9c544 100644 --- a/third_party/boringssl/kit/src/crypto/bio/file.c +++ b/third_party/boringssl/kit/src/crypto/bio/file.c @@ -157,13 +157,11 @@ static int file_read(BIO *b, char *out, int outl) { } static int file_write(BIO *b, const char *in, int inl) { - int ret = 0; - if (!b->init) { return 0; } - ret = fwrite(in, inl, 1, (FILE *)b->ptr); + int ret = (int)fwrite(in, inl, 1, (FILE *)b->ptr); if (ret > 0) { ret = inl; } @@ -253,20 +251,18 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { } static int file_gets(BIO *bp, char *buf, int size) { - int ret = 0; - if (size == 0) { return 0; } if (!fgets(buf, size, (FILE *)bp->ptr)) { buf[0] = 0; - goto err; + // TODO(davidben): This doesn't distinguish error and EOF. This should check + // |ferror| as in |file_read|. + return 0; } - ret = strlen(buf); -err: - return ret; + return (int)strlen(buf); } static const BIO_METHOD methods_filep = { @@ -281,31 +277,38 @@ const BIO_METHOD *BIO_s_file(void) { return &methods_filep; } int BIO_get_fp(BIO *bio, FILE **out_file) { - return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file); + return (int)BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char *)out_file); } int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { - return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file); + return (int)BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *)file); } int BIO_read_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, + (char *)filename); } int BIO_write_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, + (char *)filename); } int BIO_append_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, - (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, + (char *)filename); } int BIO_rw_filename(BIO *bio, const char *filename) { - return BIO_ctrl(bio, BIO_C_SET_FILENAME, - BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); + return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, + (char *)filename); +} + +long BIO_tell(BIO *bio) { return BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL); } + +long BIO_seek(BIO *bio, long offset) { + return BIO_ctrl(bio, BIO_C_FILE_SEEK, offset, NULL); } #endif // OPENSSL_TRUSTY diff --git a/third_party/boringssl/kit/src/crypto/bio/pair.c b/third_party/boringssl/kit/src/crypto/bio/pair.c index a1a9c9c9..40711cdf 100644 --- a/third_party/boringssl/kit/src/crypto/bio/pair.c +++ b/third_party/boringssl/kit/src/crypto/bio/pair.c @@ -221,7 +221,8 @@ static int bio_read(BIO *bio, char *buf, int size_) { rest -= chunk; } while (rest); - return size; + // |size| is bounded by the buffer size, which fits in |int|. + return (int)size; } static int bio_write(BIO *bio, const char *buf, int num_) { @@ -293,7 +294,8 @@ static int bio_write(BIO *bio, const char *buf, int num_) { buf += chunk; } while (rest); - return num; + // |num| is bounded by the buffer size, which fits in |int|. + return (int)num; } static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, @@ -317,7 +319,6 @@ static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, } b1->buf = OPENSSL_malloc(b1->size); if (b1->buf == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return 0; } b1->len = 0; @@ -330,7 +331,6 @@ static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, } b2->buf = OPENSSL_malloc(b2->size); if (b2->buf == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return 0; } b2->len = 0; @@ -479,5 +479,5 @@ size_t BIO_ctrl_get_write_guarantee(BIO *bio) { } int BIO_shutdown_wr(BIO *bio) { - return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); + return (int)BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); } diff --git a/third_party/boringssl/kit/src/crypto/bio/printf.c b/third_party/boringssl/kit/src/crypto/bio/printf.c index 4f9d8a18..102256bc 100644 --- a/third_party/boringssl/kit/src/crypto/bio/printf.c +++ b/third_party/boringssl/kit/src/crypto/bio/printf.c @@ -71,18 +71,6 @@ int BIO_printf(BIO *bio, const char *format, ...) { va_start(args, format); out_len = vsnprintf(buf, sizeof(buf), format, args); va_end(args); - -#if defined(OPENSSL_WINDOWS) - // On Windows, vsnprintf returns -1 rather than the requested length on - // truncation - if (out_len < 0) { - va_start(args, format); - out_len = _vscprintf(format, args); - va_end(args); - assert(out_len >= (int)sizeof(buf)); - } -#endif - if (out_len < 0) { return -1; } @@ -95,7 +83,6 @@ int BIO_printf(BIO *bio, const char *format, ...) { out = OPENSSL_malloc(requested_len + 1); out_malloced = 1; if (out == NULL) { - OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); return -1; } va_start(args, format); diff --git a/third_party/boringssl/kit/src/crypto/bio/socket.c b/third_party/boringssl/kit/src/crypto/bio/socket.c index 679959eb..c5bf6094 100644 --- a/third_party/boringssl/kit/src/crypto/bio/socket.c +++ b/third_party/boringssl/kit/src/crypto/bio/socket.c @@ -1,4 +1,3 @@ -/* crypto/bio/bss_sock.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -101,7 +100,7 @@ static int sock_read(BIO *b, char *out, int outl) { #if defined(OPENSSL_WINDOWS) int ret = recv(b->num, out, outl, 0); #else - int ret = read(b->num, out, outl); + int ret = (int)read(b->num, out, outl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { @@ -113,13 +112,11 @@ static int sock_read(BIO *b, char *out, int outl) { } static int sock_write(BIO *b, const char *in, int inl) { - int ret; - bio_clear_socket_error(); #if defined(OPENSSL_WINDOWS) - ret = send(b->num, in, inl, 0); + int ret = send(b->num, in, inl, 0); #else - ret = write(b->num, in, inl); + int ret = (int)write(b->num, in, inl); #endif BIO_clear_retry_flags(b); if (ret <= 0) { diff --git a/third_party/boringssl/kit/src/crypto/bio/socket_helper.c b/third_party/boringssl/kit/src/crypto/bio/socket_helper.c index fc751fd4..4cd7825a 100644 --- a/third_party/boringssl/kit/src/crypto/bio/socket_helper.c +++ b/third_party/boringssl/kit/src/crypto/bio/socket_helper.c @@ -12,8 +12,10 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if defined(__linux__) #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L +#endif #include #include diff --git a/third_party/boringssl/kit/src/crypto/blake2/blake2.c b/third_party/boringssl/kit/src/crypto/blake2/blake2.c index 096d61db..14bbe5b2 100644 --- a/third_party/boringssl/kit/src/crypto/blake2/blake2.c +++ b/third_party/boringssl/kit/src/crypto/blake2/blake2.c @@ -14,7 +14,7 @@ #include -#include +#include #include "../internal.h" @@ -55,13 +55,16 @@ static void blake2b_mix(uint64_t v[16], int a, int b, int c, int d, uint64_t x, v[b] = CRYPTO_rotr_u64(v[b] ^ v[c], 63); } -static void blake2b_transform( - BLAKE2B_CTX *b2b, - const uint64_t block_words[BLAKE2B_CBLOCK / sizeof(uint64_t)], - size_t num_bytes, int is_final_block) { +static uint64_t blake2b_load(const uint8_t block[BLAKE2B_CBLOCK], size_t i) { + return CRYPTO_load_u64_le(block + 8 * i); +} + +static void blake2b_transform(BLAKE2B_CTX *b2b, + const uint8_t block[BLAKE2B_CBLOCK], + size_t num_bytes, int is_final_block) { // https://tools.ietf.org/html/rfc7693#section-3.2 uint64_t v[16]; - OPENSSL_STATIC_ASSERT(sizeof(v) == sizeof(b2b->h) + sizeof(kIV), ""); + static_assert(sizeof(v) == sizeof(b2b->h) + sizeof(kIV), ""); OPENSSL_memcpy(v, b2b->h, sizeof(b2b->h)); OPENSSL_memcpy(&v[8], kIV, sizeof(kIV)); @@ -78,14 +81,22 @@ static void blake2b_transform( for (int round = 0; round < 12; round++) { const uint8_t *const s = &kSigma[16 * (round % 10)]; - blake2b_mix(v, 0, 4, 8, 12, block_words[s[0]], block_words[s[1]]); - blake2b_mix(v, 1, 5, 9, 13, block_words[s[2]], block_words[s[3]]); - blake2b_mix(v, 2, 6, 10, 14, block_words[s[4]], block_words[s[5]]); - blake2b_mix(v, 3, 7, 11, 15, block_words[s[6]], block_words[s[7]]); - blake2b_mix(v, 0, 5, 10, 15, block_words[s[8]], block_words[s[9]]); - blake2b_mix(v, 1, 6, 11, 12, block_words[s[10]], block_words[s[11]]); - blake2b_mix(v, 2, 7, 8, 13, block_words[s[12]], block_words[s[13]]); - blake2b_mix(v, 3, 4, 9, 14, block_words[s[14]], block_words[s[15]]); + blake2b_mix(v, 0, 4, 8, 12, blake2b_load(block, s[0]), + blake2b_load(block, s[1])); + blake2b_mix(v, 1, 5, 9, 13, blake2b_load(block, s[2]), + blake2b_load(block, s[3])); + blake2b_mix(v, 2, 6, 10, 14, blake2b_load(block, s[4]), + blake2b_load(block, s[5])); + blake2b_mix(v, 3, 7, 11, 15, blake2b_load(block, s[6]), + blake2b_load(block, s[7])); + blake2b_mix(v, 0, 5, 10, 15, blake2b_load(block, s[8]), + blake2b_load(block, s[9])); + blake2b_mix(v, 1, 6, 11, 12, blake2b_load(block, s[10]), + blake2b_load(block, s[11])); + blake2b_mix(v, 2, 7, 8, 13, blake2b_load(block, s[12]), + blake2b_load(block, s[13])); + blake2b_mix(v, 3, 4, 9, 14, blake2b_load(block, s[14]), + blake2b_load(block, s[15])); } for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(b2b->h); i++) { @@ -97,7 +108,7 @@ static void blake2b_transform( void BLAKE2B256_Init(BLAKE2B_CTX *b2b) { OPENSSL_memset(b2b, 0, sizeof(BLAKE2B_CTX)); - OPENSSL_STATIC_ASSERT(sizeof(kIV) == sizeof(b2b->h), ""); + static_assert(sizeof(kIV) == sizeof(b2b->h), ""); OPENSSL_memcpy(&b2b->h, kIV, sizeof(kIV)); // https://tools.ietf.org/html/rfc7693#section-2.5 @@ -105,13 +116,17 @@ void BLAKE2B256_Init(BLAKE2B_CTX *b2b) { } void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) { - const uint8_t *data = (const uint8_t *)in_data; + if (len == 0) { + // Work around a C language bug. See https://crbug.com/1019588. + return; + } - size_t todo = sizeof(b2b->block.bytes) - b2b->block_used; + const uint8_t *data = in_data; + size_t todo = sizeof(b2b->block) - b2b->block_used; if (todo > len) { todo = len; } - OPENSSL_memcpy(&b2b->block.bytes[b2b->block_used], data, todo); + OPENSSL_memcpy(&b2b->block[b2b->block_used], data, todo); b2b->block_used += todo; data += todo; len -= todo; @@ -122,28 +137,26 @@ void BLAKE2B256_Update(BLAKE2B_CTX *b2b, const void *in_data, size_t len) { // More input remains therefore we must have filled |b2b->block|. assert(b2b->block_used == BLAKE2B_CBLOCK); - blake2b_transform(b2b, b2b->block.words, BLAKE2B_CBLOCK, + blake2b_transform(b2b, b2b->block, BLAKE2B_CBLOCK, /*is_final_block=*/0); b2b->block_used = 0; while (len > BLAKE2B_CBLOCK) { - uint64_t block_words[BLAKE2B_CBLOCK / sizeof(uint64_t)]; - OPENSSL_memcpy(block_words, data, sizeof(block_words)); - blake2b_transform(b2b, block_words, BLAKE2B_CBLOCK, /*is_final_block=*/0); + blake2b_transform(b2b, data, BLAKE2B_CBLOCK, /*is_final_block=*/0); data += BLAKE2B_CBLOCK; len -= BLAKE2B_CBLOCK; } - OPENSSL_memcpy(b2b->block.bytes, data, len); + OPENSSL_memcpy(b2b->block, data, len); b2b->block_used = len; } void BLAKE2B256_Final(uint8_t out[BLAKE2B256_DIGEST_LENGTH], BLAKE2B_CTX *b2b) { - OPENSSL_memset(&b2b->block.bytes[b2b->block_used], 0, - sizeof(b2b->block.bytes) - b2b->block_used); - blake2b_transform(b2b, b2b->block.words, b2b->block_used, + OPENSSL_memset(&b2b->block[b2b->block_used], 0, + sizeof(b2b->block) - b2b->block_used); + blake2b_transform(b2b, b2b->block, b2b->block_used, /*is_final_block=*/1); - OPENSSL_STATIC_ASSERT(BLAKE2B256_DIGEST_LENGTH <= sizeof(b2b->h), ""); + static_assert(BLAKE2B256_DIGEST_LENGTH <= sizeof(b2b->h), ""); memcpy(out, b2b->h, BLAKE2B256_DIGEST_LENGTH); } diff --git a/third_party/boringssl/kit/src/crypto/bn_extra/convert.c b/third_party/boringssl/kit/src/crypto/bn_extra/convert.c index 6e930fc6..29234eff 100644 --- a/third_party/boringssl/kit/src/crypto/bn_extra/convert.c +++ b/third_party/boringssl/kit/src/crypto/bn_extra/convert.c @@ -81,7 +81,6 @@ char *BN_bn2hex(const BIGNUM *bn) { char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ + width * BN_BYTES * 2 + 1 /* trailing NUL */); if (buf == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -133,18 +132,9 @@ static int decode_hex(BIGNUM *bn, const char *in, int in_len) { BN_ULONG word = 0; int j; for (j = todo; j > 0; j--) { - char c = in[in_len - j]; - - BN_ULONG hex; - if (c >= '0' && c <= '9') { - hex = c - '0'; - } else if (c >= 'a' && c <= 'f') { - hex = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - hex = c - 'A' + 10; - } else { - hex = 0; - // This shouldn't happen. The caller checks |isxdigit|. + uint8_t hex = 0; + if (!OPENSSL_fromxdigit(&hex, in[in_len - j])) { + // This shouldn't happen. The caller checks |OPENSSL_isxdigit|. assert(0); } word = (word << 4) | hex; @@ -240,7 +230,7 @@ err: } int BN_hex2bn(BIGNUM **outp, const char *in) { - return bn_x2bn(outp, in, decode_hex, isxdigit); + return bn_x2bn(outp, in, decode_hex, OPENSSL_isxdigit); } char *BN_bn2dec(const BIGNUM *a) { @@ -250,12 +240,12 @@ char *BN_bn2dec(const BIGNUM *a) { CBB cbb; if (!CBB_init(&cbb, 16) || !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { - goto cbb_err; + goto err; } if (BN_is_zero(a)) { if (!CBB_add_u8(&cbb, '0')) { - goto cbb_err; + goto err; } } else { copy = BN_dup(a); @@ -272,7 +262,7 @@ char *BN_bn2dec(const BIGNUM *a) { const int add_leading_zeros = !BN_is_zero(copy); for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { if (!CBB_add_u8(&cbb, '0' + word % 10)) { - goto cbb_err; + goto err; } word /= 10; } @@ -282,13 +272,13 @@ char *BN_bn2dec(const BIGNUM *a) { if (BN_is_negative(a) && !CBB_add_u8(&cbb, '-')) { - goto cbb_err; + goto err; } uint8_t *data; size_t len; if (!CBB_finish(&cbb, &data, &len)) { - goto cbb_err; + goto err; } // Reverse the buffer. @@ -301,8 +291,6 @@ char *BN_bn2dec(const BIGNUM *a) { BN_free(copy); return (char *)data; -cbb_err: - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); err: BN_free(copy); CBB_cleanup(&cbb); @@ -310,7 +298,7 @@ err: } int BN_dec2bn(BIGNUM **outp, const char *in) { - return bn_x2bn(outp, in, decode_dec, isdigit); + return bn_x2bn(outp, in, decode_dec, OPENSSL_isdigit); } int BN_asc2bn(BIGNUM **outp, const char *in) { @@ -436,7 +424,6 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) { if (out == NULL) { out = BN_new(); if (out == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } out_is_alloced = 1; diff --git a/third_party/boringssl/kit/src/crypto/buf/buf.c b/third_party/boringssl/kit/src/crypto/buf/buf.c index bd97dd34..57bf34d4 100644 --- a/third_party/boringssl/kit/src/crypto/buf/buf.c +++ b/third_party/boringssl/kit/src/crypto/buf/buf.c @@ -69,7 +69,6 @@ BUF_MEM *BUF_MEM_new(void) { ret = OPENSSL_malloc(sizeof(BUF_MEM)); if (ret == NULL) { - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return NULL; } @@ -93,21 +92,18 @@ int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) { size_t n = cap + 3; if (n < cap) { - // overflow - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); return 0; } n = n / 3; size_t alloc_size = n * 4; if (alloc_size / 4 != n) { - // overflow - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); return 0; } char *new_buf = OPENSSL_realloc(buf->data, alloc_size); if (new_buf == NULL) { - OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/bytestring/asn1_compat.c b/third_party/boringssl/kit/src/crypto/bytestring/asn1_compat.c index 50df9cce..a565c44b 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/asn1_compat.c +++ b/third_party/boringssl/kit/src/crypto/bytestring/asn1_compat.c @@ -26,7 +26,8 @@ int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { - assert(cbb->base->can_resize); + assert(!cbb->is_child); + assert(cbb->u.base.can_resize); uint8_t *der; size_t der_len; diff --git a/third_party/boringssl/kit/src/crypto/bytestring/ber.c b/third_party/boringssl/kit/src/crypto/bytestring/ber.c index e7f67ddf..5d43d0b7 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/ber.c +++ b/third_party/boringssl/kit/src/crypto/bytestring/ber.c @@ -24,11 +24,11 @@ // kMaxDepth is a just a sanity limit. The code should be such that the length // of the input being processes always decreases. None the less, a very large // input could otherwise cause the stack to overflow. -static const unsigned kMaxDepth = 2048; +static const uint32_t kMaxDepth = 2048; // is_string_type returns one if |tag| is a string type and zero otherwise. It // ignores the constructed bit. -static int is_string_type(unsigned tag) { +static int is_string_type(CBS_ASN1_TAG tag) { // While BER supports constructed BIT STRINGS, OpenSSL misparses them. To // avoid acting on an ambiguous input, we do not support constructed BIT // STRINGS. See https://github.com/openssl/openssl/issues/12810. @@ -55,7 +55,7 @@ static int is_string_type(unsigned tag) { // depending on whether an indefinite length element or constructed string was // found. The value of |orig_in| is not changed. It returns one on success (i.e. // |*ber_found| was set) and zero on error. -static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) { +static int cbs_find_ber(const CBS *orig_in, int *ber_found, uint32_t depth) { CBS in; if (depth > kMaxDepth) { @@ -67,11 +67,11 @@ static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) { while (CBS_len(&in) > 0) { CBS contents; - unsigned tag; + CBS_ASN1_TAG tag; size_t header_len; - + int indefinite; if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len, - ber_found)) { + ber_found, &indefinite)) { return 0; } if (*ber_found) { @@ -93,11 +93,14 @@ static int cbs_find_ber(const CBS *orig_in, int *ber_found, unsigned depth) { return 1; } -// is_eoc returns true if |header_len| and |contents|, as returned by -// |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. -static char is_eoc(size_t header_len, CBS *contents) { - return header_len == 2 && CBS_len(contents) == 2 && - OPENSSL_memcmp(CBS_data(contents), "\x00\x00", 2) == 0; +// cbs_get_eoc returns one if |cbs| begins with an "end of contents" (EOC) value +// and zero otherwise. If an EOC was found, it advances |cbs| past it. +static int cbs_get_eoc(CBS *cbs) { + if (CBS_len(cbs) >= 2 && + CBS_data(cbs)[0] == 0 && CBS_data(cbs)[1] == 0) { + return CBS_skip(cbs, 2); + } + return 0; } // cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If @@ -107,8 +110,8 @@ static char is_eoc(size_t header_len, CBS *contents) { // constructed string. If |looking_for_eoc| is set then any EOC elements found // will cause the function to return after consuming it. It returns one on // success and zero on error. -static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, - char looking_for_eoc, unsigned depth) { +static int cbs_convert_ber(CBS *in, CBB *out, CBS_ASN1_TAG string_tag, + int looking_for_eoc, uint32_t depth) { assert(!(string_tag & CBS_ASN1_CONSTRUCTED)); if (depth > kMaxDepth) { @@ -116,19 +119,18 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, } while (CBS_len(in) > 0) { - CBS contents; - unsigned tag, child_string_tag = string_tag; - size_t header_len; - int ber_found; - CBB *out_contents, out_contents_storage; - - if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len, - &ber_found)) { - return 0; + if (looking_for_eoc && cbs_get_eoc(in)) { + return 1; } - if (is_eoc(header_len, &contents)) { - return looking_for_eoc; + CBS contents; + CBS_ASN1_TAG tag, child_string_tag = string_tag; + size_t header_len; + int indefinite; + CBB *out_contents, out_contents_storage; + if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len, + /*out_ber_found=*/NULL, &indefinite)) { + return 0; } if (string_tag != 0) { @@ -140,7 +142,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, } out_contents = out; } else { - unsigned out_tag = tag; + CBS_ASN1_TAG out_tag = tag; if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) { // If a constructed string, clear the constructed bit and inform // children to concatenate bodies. @@ -153,11 +155,9 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, out_contents = &out_contents_storage; } - if (CBS_len(&contents) == header_len && header_len > 0 && - CBS_data(&contents)[header_len - 1] == 0x80) { - // This is an indefinite length element. + if (indefinite) { if (!cbs_convert_ber(in, out_contents, child_string_tag, - 1 /* looking for eoc */, depth + 1) || + /*looking_for_eoc=*/1, depth + 1) || !CBB_flush(out)) { return 0; } @@ -171,7 +171,7 @@ static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, if (tag & CBS_ASN1_CONSTRUCTED) { // Recurse into children. if (!cbs_convert_ber(&contents, out_contents, child_string_tag, - 0 /* not looking for eoc */, depth + 1)) { + /*looking_for_eoc=*/0, depth + 1)) { return 0; } } else { @@ -221,7 +221,8 @@ int CBS_asn1_ber_to_der(CBS *in, CBS *out, uint8_t **out_storage) { } int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, - unsigned outer_tag, unsigned inner_tag) { + CBS_ASN1_TAG outer_tag, + CBS_ASN1_TAG inner_tag) { assert(!(outer_tag & CBS_ASN1_CONSTRUCTED)); assert(!(inner_tag & CBS_ASN1_CONSTRUCTED)); assert(is_string_type(inner_tag)); diff --git a/third_party/boringssl/kit/src/crypto/bytestring/bytestring_test.cc b/third_party/boringssl/kit/src/crypto/bytestring/bytestring_test.cc index 985e38cc..10d34697 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/bytestring_test.cc +++ b/third_party/boringssl/kit/src/crypto/bytestring/bytestring_test.cc @@ -24,9 +24,9 @@ #include #include -#include "internal.h" #include "../internal.h" #include "../test/test_util.h" +#include "internal.h" TEST(CBSTest, Skip) { @@ -249,7 +249,7 @@ TEST(CBSTest, GetASN1) { EXPECT_FALSE(CBS_get_optional_asn1_uint64( &data, &value, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, 42)); - unsigned tag; + CBS_ASN1_TAG tag; CBS_init(&data, kData1, sizeof(kData1)); ASSERT_TRUE(CBS_get_any_asn1(&data, &contents, &tag)); EXPECT_EQ(CBS_ASN1_SEQUENCE, tag); @@ -267,7 +267,7 @@ TEST(CBSTest, GetASN1) { TEST(CBSTest, ParseASN1Tag) { const struct { bool ok; - unsigned tag; + CBS_ASN1_TAG tag; std::vector in; } kTests[] = { {true, CBS_ASN1_SEQUENCE, {0x30, 0}}, @@ -278,9 +278,9 @@ TEST(CBSTest, ParseASN1Tag) { {true, CBS_ASN1_PRIVATE | CBS_ASN1_CONSTRUCTED | 0x1fffffff, {0xff, 0x81, 0xff, 0xff, 0xff, 0x7f, 0}}, - // Tag number fits in unsigned but not |CBS_ASN1_TAG_NUMBER_MASK|. + // Tag number fits in |uint32_t| but not |CBS_ASN1_TAG_NUMBER_MASK|. {false, 0, {0xff, 0x82, 0xff, 0xff, 0xff, 0x7f, 0}}, - // Tag number does not fit in unsigned. + // Tag number does not fit in |uint32_t|. {false, 0, {0xff, 0x90, 0x80, 0x80, 0x80, 0, 0}}, // Tag number is not minimally-encoded {false, 0, {0x5f, 0x80, 0x1f, 0}}, @@ -289,7 +289,7 @@ TEST(CBSTest, ParseASN1Tag) { }; for (const auto &t : kTests) { SCOPED_TRACE(Bytes(t.in)); - unsigned tag; + CBS_ASN1_TAG tag; CBS cbs, child; CBS_init(&cbs, t.in.data(), t.in.size()); ASSERT_EQ(t.ok, !!CBS_get_any_asn1(&cbs, &child, &tag)); @@ -376,28 +376,36 @@ TEST(CBBTest, Basic) { } TEST(CBBTest, Fixed) { - bssl::ScopedCBB cbb; + CBB cbb; uint8_t buf[1]; uint8_t *out_buf; size_t out_size; - ASSERT_TRUE(CBB_init_fixed(cbb.get(), NULL, 0)); - ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size)); + ASSERT_TRUE(CBB_init_fixed(&cbb, NULL, 0)); + ASSERT_TRUE(CBB_finish(&cbb, &out_buf, &out_size)); EXPECT_EQ(NULL, out_buf); EXPECT_EQ(0u, out_size); - cbb.Reset(); - ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, 1)); - ASSERT_TRUE(CBB_add_u8(cbb.get(), 1)); - ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size)); + ASSERT_TRUE(CBB_init_fixed(&cbb, buf, 1)); + ASSERT_TRUE(CBB_add_u8(&cbb, 1)); + ASSERT_TRUE(CBB_finish(&cbb, &out_buf, &out_size)); EXPECT_EQ(buf, out_buf); EXPECT_EQ(1u, out_size); EXPECT_EQ(1u, buf[0]); - cbb.Reset(); - ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, 1)); - ASSERT_TRUE(CBB_add_u8(cbb.get(), 1)); - EXPECT_FALSE(CBB_add_u8(cbb.get(), 2)); + ASSERT_TRUE(CBB_init_fixed(&cbb, buf, 1)); + ASSERT_TRUE(CBB_add_u8(&cbb, 1)); + EXPECT_FALSE(CBB_add_u8(&cbb, 2)); + // We do not need |CBB_cleanup| or |bssl::ScopedCBB| here because a fixed + // |CBB| has no allocations. Leak-checking tools will confirm there was + // nothing to clean up. + + // However, it should be harmless to call |CBB_cleanup|. + CBB cbb2; + ASSERT_TRUE(CBB_init_fixed(&cbb2, buf, 1)); + ASSERT_TRUE(CBB_add_u8(&cbb2, 1)); + EXPECT_FALSE(CBB_add_u8(&cbb2, 2)); + CBB_cleanup(&cbb2); } // Test that calling CBB_finish on a child does nothing. @@ -693,29 +701,43 @@ struct BERTest { const char *in_hex; bool ok; bool ber_found; - unsigned tag; + bool indefinite; + CBS_ASN1_TAG tag; }; static const BERTest kBERTests[] = { - // Trivial cases, also valid DER. - {"0000", true, false, 0}, - {"0100", true, false, 1}, - {"020101", true, false, 2}, + // Trivial cases, also valid DER. + {"0100", true, false, false, 1}, + {"020101", true, false, false, 2}, - // Non-minimally encoded lengths. - {"02810101", true, true, 2}, - {"0282000101", true, true, 2}, - {"028300000101", true, true, 2}, - {"02840000000101", true, true, 2}, - // Technically valid BER, but not handled. - {"02850000000101", false, false, 0}, + // Non-minimally encoded lengths. + {"02810101", true, true, false, 2}, + {"0282000101", true, true, false, 2}, + {"028300000101", true, true, false, 2}, + {"02840000000101", true, true, false, 2}, + // Technically valid BER, but not handled. + {"02850000000101", false, false, false, 0}, - {"0280", false, false, 0}, // Indefinite length, but not constructed. - {"2280", true, true, CBS_ASN1_CONSTRUCTED | 2}, // Indefinite length. - {"3f0000", false, false, 0}, // Invalid extended tag zero (X.690 8.1.2.4.2.c) - {"1f0100", false, false, 0}, // Should be a low-number tag form, even in BER. - {"1f4000", true, false, 0x40}, - {"1f804000", false, false, 0}, // Non-minimal tags are invalid, even in BER. + // Indefinite length, but not constructed. + {"0280", false, false, false, 0}, + // Indefinite length. + {"2280", true, true, true, CBS_ASN1_CONSTRUCTED | 2}, + // Indefinite length with multi-byte tag. + {"bf1f80", true, true, true, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 31}, + // Invalid extended tag zero (X.690 8.1.2.4.2.c) + {"3f0000", false, false, false, 0}, + // Should be a low-number tag form, even in BER. + {"1f0100", false, false, false, 0}, + {"1f4000", true, false, false, 0x40}, + // Non-minimal tags are invalid, even in BER. + {"1f804000", false, false, false, 0}, + + // EOCs and other forms of tag [UNIVERSAL 0] are rejected as elements. + {"0000", false, false, false, 0}, + {"000100", false, false, false, 0}, + {"00800000", false, false, false, 0}, + {"2000", false, false, false, 0}, }; TEST(CBSTest, BERElementTest) { @@ -726,17 +748,19 @@ TEST(CBSTest, BERElementTest) { ASSERT_TRUE(DecodeHex(&in_bytes, test.in_hex)); CBS in(in_bytes); CBS out; - unsigned tag; + CBS_ASN1_TAG tag; size_t header_len; int ber_found; - int ok = - CBS_get_any_ber_asn1_element(&in, &out, &tag, &header_len, &ber_found); + int indefinite; + int ok = CBS_get_any_ber_asn1_element(&in, &out, &tag, &header_len, + &ber_found, &indefinite); ASSERT_TRUE((ok == 1) == test.ok); if (!test.ok) { continue; } - EXPECT_TRUE((ber_found == 1) == test.ber_found); + EXPECT_EQ(test.ber_found ? 1 : 0, ber_found); + EXPECT_EQ(test.indefinite ? 1 : 0, indefinite); EXPECT_LE(header_len, in_bytes.size()); EXPECT_EQ(CBS_len(&out), in_bytes.size()); EXPECT_EQ(CBS_len(&in), 0u); @@ -846,12 +870,28 @@ TEST(CBSTest, ASN1Uint64) { EXPECT_EQ(0, is_negative); EXPECT_TRUE(CBS_is_unsigned_asn1_integer(&child)); - bssl::ScopedCBB cbb; - ASSERT_TRUE(CBB_init(cbb.get(), 0)); - ASSERT_TRUE(CBB_add_asn1_uint64(cbb.get(), test.value)); - ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); - bssl::UniquePtr scoper(out); - EXPECT_EQ(Bytes(test.encoding, test.encoding_len), Bytes(out, len)); + { + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(CBB_add_asn1_uint64(cbb.get(), test.value)); + ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); + bssl::UniquePtr scoper(out); + EXPECT_EQ(Bytes(test.encoding, test.encoding_len), Bytes(out, len)); + } + + { + // Overwrite the tag. + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(CBB_add_asn1_uint64_with_tag(cbb.get(), test.value, + CBS_ASN1_CONTEXT_SPECIFIC | 1)); + ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); + bssl::UniquePtr scoper(out); + std::vector expected(test.encoding, + test.encoding + test.encoding_len); + expected[0] = 0x81; + EXPECT_EQ(Bytes(expected), Bytes(out, len)); + } } for (const ASN1InvalidUint64Test &test : kASN1InvalidUint64Tests) { @@ -936,12 +976,28 @@ TEST(CBSTest, ASN1Int64) { EXPECT_EQ(test.value < 0, !!is_negative); EXPECT_EQ(test.value >= 0, !!CBS_is_unsigned_asn1_integer(&child)); - bssl::ScopedCBB cbb; - ASSERT_TRUE(CBB_init(cbb.get(), 0)); - ASSERT_TRUE(CBB_add_asn1_int64(cbb.get(), test.value)); - ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); - bssl::UniquePtr scoper(out); - EXPECT_EQ(Bytes(test.encoding, test.encoding_len), Bytes(out, len)); + { + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(CBB_add_asn1_int64(cbb.get(), test.value)); + ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); + bssl::UniquePtr scoper(out); + EXPECT_EQ(Bytes(test.encoding, test.encoding_len), Bytes(out, len)); + } + + { + // Overwrite the tag. + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(CBB_add_asn1_int64_with_tag(cbb.get(), test.value, + CBS_ASN1_CONTEXT_SPECIFIC | 1)); + ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len)); + bssl::UniquePtr scoper(out); + std::vector expected(test.encoding, + test.encoding + test.encoding_len); + expected[0] = 0x81; + EXPECT_EQ(Bytes(expected), Bytes(out, len)); + } } for (const ASN1InvalidInt64Test &test : kASN1InvalidInt64Tests) { @@ -1143,16 +1199,23 @@ TEST(CBBTest, AddOIDFromText) { "2.18446744073709551536", }; - const std::vector kInvalidDER[] = { + const struct { + std::vector der; + // If true, |der| is valid but has a component that exceeds 2^64-1. + bool overflow; + } kInvalidDER[] = { // The empty string is not an OID. - {}, + {{}, false}, // Non-minimal representation. - {0x80, 0x01}, + {{0x80, 0x01}, false}, + // Unterminated integer. + {{0x01, 0x02, 0x83}, false}, // Overflow. This is the DER representation of // 1.2.840.113554.4.1.72585.18446744073709551616. (The final value is // 2^64.) - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, - 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}, + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}, + true}, }; for (const auto &t : kValidOIDs) { @@ -1172,6 +1235,8 @@ TEST(CBBTest, AddOIDFromText) { bssl::UniquePtr text(CBS_asn1_oid_to_text(&cbs)); ASSERT_TRUE(text.get()); EXPECT_STREQ(t.text, text.get()); + + EXPECT_TRUE(CBS_is_valid_asn1_oid(&cbs)); } for (const char *t : kInvalidTexts) { @@ -1182,11 +1247,12 @@ TEST(CBBTest, AddOIDFromText) { } for (const auto &t : kInvalidDER) { - SCOPED_TRACE(Bytes(t)); + SCOPED_TRACE(Bytes(t.der)); CBS cbs; - CBS_init(&cbs, t.data(), t.size()); + CBS_init(&cbs, t.der.data(), t.der.size()); bssl::UniquePtr text(CBS_asn1_oid_to_text(&cbs)); EXPECT_FALSE(text); + EXPECT_EQ(t.overflow ? 1 : 0, CBS_is_valid_asn1_oid(&cbs)); } } @@ -1477,3 +1543,177 @@ TEST(CBBTest, Unicode) { EXPECT_EQ(4u, cbb_get_utf8_len(0x10000)); EXPECT_EQ(4u, cbb_get_utf8_len(0x10ffff)); } + +TEST(CBSTest, BogusTime) { + static const struct { + const char *timestring; + } kBogusTimeTests[] = { + {""}, + {"invalidtimesZ"}, + {"Z"}, + {"0000"}, + {"9999Z"}, + {"00000000000000000000000000000Z"}, + {"19491231235959"}, + {"500101000000.001Z"}, + {"500101000000+6"}, + {"-1970010100000Z"}, + {"7a0101000000Z"}, + {"20500101000000-6"}, + {"20500101000000.001"}, + {"20500229000000Z"}, + {"220229000000Z"}, + {"20500132000000Z"}, + {"220132000000Z"}, + {"20500332000000Z"}, + {"220332000000Z"}, + {"20500532000000Z"}, + {"220532000000Z"}, + {"20500732000000Z"}, + {"220732000000Z"}, + {"20500832000000Z"}, + {"220832000000Z"}, + {"20501032000000Z"}, + {"221032000000Z"}, + {"20501232000000Z"}, + {"221232000000Z"}, + {"20500431000000Z"}, + {"220431000000Z"}, + {"20500631000000Z"}, + {"220631000000Z"}, + {"20500931000000Z"}, + {"220931000000Z"}, + {"20501131000000Z"}, + {"221131000000Z"}, + {"20501100000000Z"}, + {"221100000000Z"}, + {"19500101000000+0600"}, + }; + for (const auto &t : kBogusTimeTests) { + SCOPED_TRACE(t.timestring); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)t.timestring, strlen(t.timestring)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)); + } + static const struct { + const char *timestring; + } kUTCTZTests[] = { + {"480711220333-0700"}, + {"140704000000-0700"}, + {"480222202332-0500"}, + {"480726113216-0000"}, + {"480726113216-2359"}, + }; + for (const auto &t : kUTCTZTests) { + SCOPED_TRACE(t.timestring); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)t.timestring, strlen(t.timestring)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/1)); + EXPECT_TRUE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/0)); + } + static const struct { + const char *timestring; + } kBogusUTCTZTests[] = { + {"480711220333-0160"}, + {"140704000000-9999"}, + {"480222202332-2400"}, + }; + for (const auto &t : kBogusUTCTZTests) { + SCOPED_TRACE(t.timestring); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)t.timestring, strlen(t.timestring)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)); + } + static const struct { + const char *timestring; + } kGenTZTests[] = { + {"20480711220333-0000"}, + {"20140704000000-0100"}, + {"20460311174630-0300"}, + {"20140704000000-2359"}, + }; + for (const auto &t : kGenTZTests) { + SCOPED_TRACE(t.timestring); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)t.timestring, strlen(t.timestring)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)); + EXPECT_TRUE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/1)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/0)); + } + static const struct { + const char *timestring; + } kBogusGenTZTests[] = { + {"20480222202332-2400"}, + {"20140704000000-9999"}, + {"20480726113216-0160"}, + }; + for (const auto &t : kBogusGenTZTests) { + SCOPED_TRACE(t.timestring); + CBS cbs; + CBS_init(&cbs, (const uint8_t *)t.timestring, strlen(t.timestring)); + EXPECT_FALSE(CBS_parse_generalized_time(&cbs, NULL, + /*allow_timezone_offset=*/0)); + EXPECT_FALSE(CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)); + } +} + +TEST(CBSTest, GetU64Decimal) { + const struct { + uint64_t val; + const char *text; + } kTests[] = { + {0, "0"}, + {1, "1"}, + {123456, "123456"}, + // 2^64 - 1 + {UINT64_C(18446744073709551615), "18446744073709551615"}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.text); + CBS cbs; + CBS_init(&cbs, reinterpret_cast(t.text), strlen(t.text)); + uint64_t v; + ASSERT_TRUE(CBS_get_u64_decimal(&cbs, &v)); + EXPECT_EQ(v, t.val); + EXPECT_EQ(CBS_data(&cbs), + reinterpret_cast(t.text) + strlen(t.text)); + EXPECT_EQ(CBS_len(&cbs), 0u); + + std::string str(t.text); + str += "Z"; + CBS_init(&cbs, reinterpret_cast(str.data()), str.size()); + ASSERT_TRUE(CBS_get_u64_decimal(&cbs, &v)); + EXPECT_EQ(v, t.val); + EXPECT_EQ(CBS_data(&cbs), + reinterpret_cast(str.data()) + strlen(t.text)); + EXPECT_EQ(CBS_len(&cbs), 1u); + } + + static const char *kInvalidTests[] = { + "", + "nope", + "-1", + // 2^64 + "18446744073709551616", + // Overflows at multiplying by 10. + "18446744073709551620", + }; + for (const char *invalid : kInvalidTests) { + SCOPED_TRACE(invalid); + CBS cbs; + CBS_init(&cbs, reinterpret_cast(invalid), strlen(invalid)); + uint64_t v; + EXPECT_FALSE(CBS_get_u64_decimal(&cbs, &v)); + } +} diff --git a/third_party/boringssl/kit/src/crypto/bytestring/cbb.c b/third_party/boringssl/kit/src/crypto/bytestring/cbb.c index 12587cdf..5280dc8f 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/cbb.c +++ b/third_party/boringssl/kit/src/crypto/bytestring/cbb.c @@ -19,6 +19,7 @@ #include #include +#include #include "../internal.h" @@ -27,24 +28,14 @@ void CBB_zero(CBB *cbb) { OPENSSL_memset(cbb, 0, sizeof(CBB)); } -static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { - // This assumes that |cbb| has already been zeroed. - struct cbb_buffer_st *base; - - base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); - if (base == NULL) { - return 0; - } - - base->buf = buf; - base->len = 0; - base->cap = cap; - base->can_resize = 1; - base->error = 0; - - cbb->base = base; +static void cbb_init(CBB *cbb, uint8_t *buf, size_t cap, int can_resize) { cbb->is_child = 0; - return 1; + cbb->child = NULL; + cbb->u.base.buf = buf; + cbb->u.base.len = 0; + cbb->u.base.cap = cap; + cbb->u.base.can_resize = can_resize; + cbb->u.base.error = 0; } int CBB_init(CBB *cbb, size_t initial_capacity) { @@ -55,22 +46,13 @@ int CBB_init(CBB *cbb, size_t initial_capacity) { return 0; } - if (!cbb_init(cbb, buf, initial_capacity)) { - OPENSSL_free(buf); - return 0; - } - + cbb_init(cbb, buf, initial_capacity, /*can_resize=*/1); return 1; } int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { CBB_zero(cbb); - - if (!cbb_init(cbb, buf, len)) { - return 0; - } - - cbb->base->can_resize = 0; + cbb_init(cbb, buf, len, /*can_resize=*/0); return 1; } @@ -82,41 +64,35 @@ void CBB_cleanup(CBB *cbb) { return; } - if (cbb->base) { - if (cbb->base->can_resize) { - OPENSSL_free(cbb->base->buf); - } - OPENSSL_free(cbb->base); + if (cbb->u.base.can_resize) { + OPENSSL_free(cbb->u.base.buf); } - cbb->base = NULL; } static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, size_t len) { - size_t newlen; - if (base == NULL) { return 0; } - newlen = base->len + len; + size_t newlen = base->len + len; if (newlen < base->len) { // Overflow + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } if (newlen > base->cap) { - size_t newcap = base->cap * 2; - uint8_t *newbuf; - if (!base->can_resize) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } + size_t newcap = base->cap * 2; if (newcap < base->cap || newcap < newlen) { newcap = newlen; } - newbuf = OPENSSL_realloc(base->buf, newcap); + uint8_t *newbuf = OPENSSL_realloc(base->buf, newcap); if (newbuf == NULL) { goto err; } @@ -146,32 +122,9 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, return 1; } -static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint64_t v, - size_t len_len) { - if (len_len == 0) { - return 1; - } - - uint8_t *buf; - if (!cbb_buffer_add(base, &buf, len_len)) { - return 0; - } - - for (size_t i = len_len - 1; i < len_len; i--) { - buf[i] = v; - v >>= 8; - } - - if (v != 0) { - base->error = 1; - return 0; - } - - return 1; -} - int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { if (cbb->is_child) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -179,59 +132,70 @@ int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { return 0; } - if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { + if (cbb->u.base.can_resize && (out_data == NULL || out_len == NULL)) { // |out_data| and |out_len| can only be NULL if the CBB is fixed. return 0; } if (out_data != NULL) { - *out_data = cbb->base->buf; + *out_data = cbb->u.base.buf; } if (out_len != NULL) { - *out_len = cbb->base->len; + *out_len = cbb->u.base.len; } - cbb->base->buf = NULL; + cbb->u.base.buf = NULL; CBB_cleanup(cbb); return 1; } +static struct cbb_buffer_st *cbb_get_base(CBB *cbb) { + if (cbb->is_child) { + return cbb->u.child.base; + } + return &cbb->u.base; +} + // CBB_flush recurses and then writes out any pending length prefix. The // current length of the underlying base is taken to be the length of the // length-prefixed data. int CBB_flush(CBB *cbb) { - size_t child_start, i, len; - - // If |cbb->base| has hit an error, the buffer is in an undefined state, so + // If |base| has hit an error, the buffer is in an undefined state, so // fail all following calls. In particular, |cbb->child| may point to invalid // memory. - if (cbb->base == NULL || cbb->base->error) { + struct cbb_buffer_st *base = cbb_get_base(cbb); + if (base == NULL || base->error) { return 0; } - if (cbb->child == NULL || cbb->child->pending_len_len == 0) { + if (cbb->child == NULL) { + // Nothing to flush. return 1; } - child_start = cbb->child->offset + cbb->child->pending_len_len; + assert(cbb->child->is_child); + struct cbb_child_st *child = &cbb->child->u.child; + assert(child->base == base); + size_t child_start = child->offset + child->pending_len_len; if (!CBB_flush(cbb->child) || - child_start < cbb->child->offset || - cbb->base->len < child_start) { + child_start < child->offset || + base->len < child_start) { goto err; } - len = cbb->base->len - child_start; + size_t len = base->len - child_start; - if (cbb->child->pending_is_asn1) { + if (child->pending_is_asn1) { // For ASN.1 we assume that we'll only need a single byte for the length. // If that turned out to be incorrect, we have to move the contents along // in order to make space. uint8_t len_len; uint8_t initial_length_byte; - assert (cbb->child->pending_len_len == 1); + assert (child->pending_len_len == 1); if (len > 0xfffffffe) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); // Too large. goto err; } else if (len > 0xffffff) { @@ -255,70 +219,86 @@ int CBB_flush(CBB *cbb) { if (len_len != 1) { // We need to move the contents along in order to make space. size_t extra_bytes = len_len - 1; - if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { + if (!cbb_buffer_add(base, NULL, extra_bytes)) { goto err; } - OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes, - cbb->base->buf + child_start, len); + OPENSSL_memmove(base->buf + child_start + extra_bytes, + base->buf + child_start, len); } - cbb->base->buf[cbb->child->offset++] = initial_length_byte; - cbb->child->pending_len_len = len_len - 1; + base->buf[child->offset++] = initial_length_byte; + child->pending_len_len = len_len - 1; } - for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; - i--) { - cbb->base->buf[cbb->child->offset + i] = (uint8_t)len; + for (size_t i = child->pending_len_len - 1; i < child->pending_len_len; i--) { + base->buf[child->offset + i] = (uint8_t)len; len >>= 8; } if (len != 0) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); goto err; } - cbb->child->base = NULL; + child->base = NULL; cbb->child = NULL; return 1; err: - cbb->base->error = 1; + base->error = 1; return 0; } const uint8_t *CBB_data(const CBB *cbb) { assert(cbb->child == NULL); - return cbb->base->buf + cbb->offset + cbb->pending_len_len; + if (cbb->is_child) { + return cbb->u.child.base->buf + cbb->u.child.offset + + cbb->u.child.pending_len_len; + } + return cbb->u.base.buf; } size_t CBB_len(const CBB *cbb) { assert(cbb->child == NULL); - assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); + if (cbb->is_child) { + assert(cbb->u.child.offset + cbb->u.child.pending_len_len <= + cbb->u.child.base->len); + return cbb->u.child.base->len - cbb->u.child.offset - + cbb->u.child.pending_len_len; + } + return cbb->u.base.len; +} - return cbb->base->len - cbb->offset - cbb->pending_len_len; +static int cbb_add_child(CBB *cbb, CBB *out_child, uint8_t len_len, + int is_asn1) { + assert(cbb->child == NULL); + assert(!is_asn1 || len_len == 1); + struct cbb_buffer_st *base = cbb_get_base(cbb); + size_t offset = base->len; + + // Reserve space for the length prefix. + uint8_t *prefix_bytes; + if (!cbb_buffer_add(base, &prefix_bytes, len_len)) { + return 0; + } + OPENSSL_memset(prefix_bytes, 0, len_len); + + CBB_zero(out_child); + out_child->is_child = 1; + out_child->u.child.base = base; + out_child->u.child.offset = offset; + out_child->u.child.pending_len_len = len_len; + out_child->u.child.pending_is_asn1 = is_asn1; + cbb->child = out_child; + return 1; } static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, uint8_t len_len) { - uint8_t *prefix_bytes; - if (!CBB_flush(cbb)) { return 0; } - size_t offset = cbb->base->len; - if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { - return 0; - } - - OPENSSL_memset(prefix_bytes, 0, len_len); - OPENSSL_memset(out_contents, 0, sizeof(CBB)); - out_contents->base = cbb->base; - out_contents->is_child = 1; - cbb->child = out_contents; - cbb->child->offset = offset; - cbb->child->pending_len_len = len_len; - cbb->child->pending_is_asn1 = 0; - - return 1; + return cbb_add_child(cbb, out_contents, len_len, /*is_asn1=*/0); } int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { @@ -359,14 +339,14 @@ static int add_base128_integer(CBB *cbb, uint64_t v) { return 1; } -int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { +int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag) { if (!CBB_flush(cbb)) { return 0; } // Split the tag into leading bits and tag number. uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0; - unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + CBS_ASN1_TAG tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; if (tag_number >= 0x1f) { // Set all the bits in the tag number to signal high tag number form. if (!CBB_add_u8(cbb, tag_bits | 0x1f) || @@ -377,30 +357,16 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { return 0; } - size_t offset = cbb->base->len; - if (!CBB_add_u8(cbb, 0)) { - return 0; - } - - OPENSSL_memset(out_contents, 0, sizeof(CBB)); - out_contents->base = cbb->base; - out_contents->is_child = 1; - cbb->child = out_contents; - cbb->child->offset = offset; - cbb->child->pending_len_len = 1; - cbb->child->pending_is_asn1 = 1; - - return 1; + // Reserve one byte of length prefix. |CBB_flush| will finish it later. + return cbb_add_child(cbb, out_contents, /*len_len=*/1, /*is_asn1=*/1); } int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { - uint8_t *dest; - - if (!CBB_flush(cbb) || - !cbb_buffer_add(cbb->base, &dest, len)) { + uint8_t *out; + if (!CBB_add_space(cbb, &out, len)) { return 0; } - OPENSSL_memcpy(dest, data, len); + OPENSSL_memcpy(out, data, len); return 1; } @@ -415,7 +381,7 @@ int CBB_add_zeros(CBB *cbb, size_t len) { int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { if (!CBB_flush(cbb) || - !cbb_buffer_add(cbb->base, out_data, len)) { + !cbb_buffer_add(cbb_get_base(cbb), out_data, len)) { return 0; } return 1; @@ -423,37 +389,50 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { if (!CBB_flush(cbb) || - !cbb_buffer_reserve(cbb->base, out_data, len)) { + !cbb_buffer_reserve(cbb_get_base(cbb), out_data, len)) { return 0; } return 1; } int CBB_did_write(CBB *cbb, size_t len) { - size_t newlen = cbb->base->len + len; + struct cbb_buffer_st *base = cbb_get_base(cbb); + size_t newlen = base->len + len; if (cbb->child != NULL || - newlen < cbb->base->len || - newlen > cbb->base->cap) { + newlen < base->len || + newlen > base->cap) { return 0; } - cbb->base->len = newlen; + base->len = newlen; + return 1; +} + +static int cbb_add_u(CBB *cbb, uint64_t v, size_t len_len) { + uint8_t *buf; + if (!CBB_add_space(cbb, &buf, len_len)) { + return 0; + } + + for (size_t i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + + // |v| must fit in |len_len| bytes. + if (v != 0) { + cbb_get_base(cbb)->error = 1; + return 0; + } + return 1; } int CBB_add_u8(CBB *cbb, uint8_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 1); + return cbb_add_u(cbb, value, 1); } int CBB_add_u16(CBB *cbb, uint16_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 2); + return cbb_add_u(cbb, value, 2); } int CBB_add_u16le(CBB *cbb, uint16_t value) { @@ -461,19 +440,11 @@ int CBB_add_u16le(CBB *cbb, uint16_t value) { } int CBB_add_u24(CBB *cbb, uint32_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 3); + return cbb_add_u(cbb, value, 3); } int CBB_add_u32(CBB *cbb, uint32_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - - return cbb_buffer_add_u(cbb->base, value, 4); + return cbb_add_u(cbb, value, 4); } int CBB_add_u32le(CBB *cbb, uint32_t value) { @@ -481,10 +452,7 @@ int CBB_add_u32le(CBB *cbb, uint32_t value) { } int CBB_add_u64(CBB *cbb, uint64_t value) { - if (!CBB_flush(cbb)) { - return 0; - } - return cbb_buffer_add_u(cbb->base, value, 8); + return cbb_add_u(cbb, value, 8); } int CBB_add_u64le(CBB *cbb, uint64_t value) { @@ -496,20 +464,25 @@ void CBB_discard_child(CBB *cbb) { return; } - cbb->base->len = cbb->child->offset; + struct cbb_buffer_st *base = cbb_get_base(cbb); + assert(cbb->child->is_child); + base->len = cbb->child->u.child.offset; - cbb->child->base = NULL; + cbb->child->u.child.base = NULL; cbb->child = NULL; } int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { - CBB child; - int started = 0; + return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER); +} - if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { +int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, CBS_ASN1_TAG tag) { + CBB child; + if (!CBB_add_asn1(cbb, &child, tag)) { return 0; } + int started = 0; for (size_t i = 0; i < 8; i++) { uint8_t byte = (value >> 8*(7-i)) & 0xff; if (!started) { @@ -538,27 +511,28 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { } int CBB_add_asn1_int64(CBB *cbb, int64_t value) { + return CBB_add_asn1_int64_with_tag(cbb, value, CBS_ASN1_INTEGER); +} + +int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, CBS_ASN1_TAG tag) { if (value >= 0) { - return CBB_add_asn1_uint64(cbb, value); + return CBB_add_asn1_uint64_with_tag(cbb, (uint64_t)value, tag); } - union { - int64_t i; - uint8_t bytes[sizeof(int64_t)]; - } u; - u.i = value; + uint8_t bytes[sizeof(int64_t)]; + memcpy(bytes, &value, sizeof(value)); int start = 7; // Skip leading sign-extension bytes unless they are necessary. - while (start > 0 && (u.bytes[start] == 0xff && (u.bytes[start - 1] & 0x80))) { + while (start > 0 && (bytes[start] == 0xff && (bytes[start - 1] & 0x80))) { start--; } CBB child; - if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + if (!CBB_add_asn1(cbb, &child, tag)) { return 0; } for (int i = start; i >= 0; i--) { - if (!CBB_add_u8(&child, u.bytes[i])) { + if (!CBB_add_u8(&child, bytes[i])) { return 0; } } @@ -592,30 +566,15 @@ int CBB_add_asn1_bool(CBB *cbb, int value) { // component and the dot, so |cbs| may be passed into the function again for the // next value. static int parse_dotted_decimal(CBS *cbs, uint64_t *out) { - *out = 0; - int seen_digit = 0; - for (;;) { - // Valid terminators for a component are the end of the string or a - // non-terminal dot. If the string ends with a dot, this is not a valid OID - // string. - uint8_t u; - if (!CBS_get_u8(cbs, &u) || - (u == '.' && CBS_len(cbs) > 0)) { - break; - } - if (u < '0' || u > '9' || - // Forbid stray leading zeros. - (seen_digit && *out == 0) || - // Check for overflow. - *out > UINT64_MAX / 10 || - *out * 10 > UINT64_MAX - (u - '0')) { - return 0; - } - *out = *out * 10 + (u - '0'); - seen_digit = 1; + if (!CBS_get_u64_decimal(cbs, out)) { + return 0; } - // The empty string is not a legal OID component. - return seen_digit; + + // The integer must have either ended at the end of the string, or a + // non-terminal dot, which should be consumed. If the string ends with a dot, + // this is not a valid OID string. + uint8_t dot; + return !CBS_get_u8(cbs, &dot) || (dot == '.' && CBS_len(cbs) > 0); } int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) { @@ -681,6 +640,7 @@ int CBB_flush_asn1_set_of(CBB *cbb) { CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb)); while (CBS_len(&cbs) != 0) { if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } num_children++; @@ -710,14 +670,14 @@ int CBB_flush_asn1_set_of(CBB *cbb) { } qsort(children, num_children, sizeof(CBS), compare_set_of_element); - // Rewind |cbb| and write the contents back in the new order. - cbb->base->len = cbb->offset + cbb->pending_len_len; + // Write the contents back in the new order. + uint8_t *out = (uint8_t *)CBB_data(cbb); + size_t offset = 0; for (size_t i = 0; i < num_children; i++) { - if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) { - goto err; - } + OPENSSL_memcpy(out + offset, CBS_data(&children[i]), CBS_len(&children[i])); + offset += CBS_len(&children[i]); } - assert(CBB_len(cbb) == buf_len); + assert(offset == buf_len); ret = 1; diff --git a/third_party/boringssl/kit/src/crypto/bytestring/cbs.c b/third_party/boringssl/kit/src/crypto/bytestring/cbs.c index 803c97ae..eb7e4dc9 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/cbs.c +++ b/third_party/boringssl/kit/src/crypto/bytestring/cbs.c @@ -12,15 +12,18 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include #include +#include #include +#include #include #include -#include "internal.h" +#include "../asn1/internal.h" #include "../internal.h" +#include "internal.h" void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { @@ -133,7 +136,7 @@ int CBS_get_u24(CBS *cbs, uint32_t *out) { if (!cbs_get_u(cbs, &v, 3)) { return 0; } - *out = v; + *out = (uint32_t)v; return 1; } @@ -142,7 +145,7 @@ int CBS_get_u32(CBS *cbs, uint32_t *out) { if (!cbs_get_u(cbs, &v, 4)) { return 0; } - *out = v; + *out = (uint32_t)v; return 1; } @@ -224,6 +227,30 @@ int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c) { return CBS_get_bytes(cbs, out, split - CBS_data(cbs)); } +int CBS_get_u64_decimal(CBS *cbs, uint64_t *out) { + uint64_t v = 0; + int seen_digit = 0; + while (CBS_len(cbs) != 0) { + uint8_t c = CBS_data(cbs)[0]; + if (!OPENSSL_isdigit(c)) { + break; + } + CBS_skip(cbs, 1); + if (// Forbid stray leading zeros. + (v == 0 && seen_digit) || + // Check for overflow. + v > UINT64_MAX / 10 || // + v * 10 > UINT64_MAX - (c - '0')) { + return 0; + } + v = v * 10 + (c - '0'); + seen_digit = 1; + } + + *out = v; + return seen_digit; +} + // parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets // |*out| to the result. This is the encoding used in DER for both high tag // number form and OID components. @@ -251,7 +278,7 @@ static int parse_base128_integer(CBS *cbs, uint64_t *out) { return 1; } -static int parse_asn1_tag(CBS *cbs, unsigned *out) { +static int parse_asn1_tag(CBS *cbs, CBS_ASN1_TAG *out) { uint8_t tag_byte; if (!CBS_get_u8(cbs, &tag_byte)) { return 0; @@ -263,8 +290,8 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) { // If the number portion is 31 (0x1f, the largest value that fits in the // allotted bits), then the tag is more than one byte long and the // continuation bytes contain the tag number. - unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; - unsigned tag_number = tag_byte & 0x1f; + CBS_ASN1_TAG tag = ((CBS_ASN1_TAG)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; + CBS_ASN1_TAG tag_number = tag_byte & 0x1f; if (tag_number == 0x1f) { uint64_t v; if (!parse_base128_integer(cbs, &v) || @@ -274,18 +301,25 @@ static int parse_asn1_tag(CBS *cbs, unsigned *out) { v < 0x1f) { return 0; } - tag_number = (unsigned)v; + tag_number = (CBS_ASN1_TAG)v; } tag |= tag_number; + // Tag [UNIVERSAL 0] is reserved for use by the encoding. Reject it here to + // avoid some ambiguity around ANY values and BER indefinite-length EOCs. See + // https://crbug.com/boringssl/455. + if ((tag & ~CBS_ASN1_CONSTRUCTED) == 0) { + return 0; + } + *out = tag; return 1; } -static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, +static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, size_t *out_header_len, int *out_ber_found, - int ber_ok) { + int *out_indefinite, int ber_ok) { CBS header = *cbs; CBS throwaway; @@ -294,9 +328,13 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, } if (ber_ok) { *out_ber_found = 0; + *out_indefinite = 0; + } else { + assert(out_ber_found == NULL); + assert(out_indefinite == NULL); } - unsigned tag; + CBS_ASN1_TAG tag; if (!parse_asn1_tag(&header, &tag)) { return 0; } @@ -333,6 +371,7 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, *out_header_len = header_len; } *out_ber_found = 1; + *out_indefinite = 1; return CBS_get_bytes(cbs, out, header_len); } @@ -379,7 +418,7 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, return CBS_get_bytes(cbs, out, len); } -int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { +int CBS_get_any_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag) { size_t header_len; if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) { return 0; @@ -393,24 +432,26 @@ int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { return 1; } -int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, size_t *out_header_len) { - return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, - NULL, 0 /* DER only */); + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, NULL, NULL, + /*ber_ok=*/0); } -int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, - size_t *out_header_len, int *out_ber_found) { +int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG *out_tag, + size_t *out_header_len, int *out_ber_found, + int *out_indefinite) { int ber_found_temp; return cbs_get_any_asn1_element( cbs, out, out_tag, out_header_len, - out_ber_found ? out_ber_found : &ber_found_temp, 1 /* BER allowed */); + out_ber_found ? out_ber_found : &ber_found_temp, out_indefinite, + /*ber_ok=*/1); } -static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, +static int cbs_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value, int skip_header) { size_t header_len; - unsigned tag; + CBS_ASN1_TAG tag; CBS throwaway; if (out == NULL) { @@ -430,21 +471,17 @@ static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, return 1; } -int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { +int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) { return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); } -int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { +int CBS_get_asn1_element(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value) { return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); } -int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { - if (CBS_len(cbs) < 1) { - return 0; - } - +int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value) { CBS copy = *cbs; - unsigned actual_tag; + CBS_ASN1_TAG actual_tag; return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag; } @@ -482,15 +519,12 @@ int CBS_get_asn1_int64(CBS *cbs, int64_t *out) { if (len > sizeof(int64_t)) { return 0; } - union { - int64_t i; - uint8_t bytes[sizeof(int64_t)]; - } u; - memset(u.bytes, is_negative ? 0xff : 0, sizeof(u.bytes)); // Sign-extend. + uint8_t sign_extend[sizeof(int64_t)]; + memset(sign_extend, is_negative ? 0xff : 0, sizeof(sign_extend)); for (size_t i = 0; i < len; i++) { - u.bytes[i] = data[len - i - 1]; + sign_extend[i] = data[len - i - 1]; } - *out = u.i; + memcpy(out, sign_extend, sizeof(sign_extend)); return 1; } @@ -510,7 +544,7 @@ int CBS_get_asn1_bool(CBS *cbs, int *out) { return 1; } -int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, CBS_ASN1_TAG tag) { int present = 0; if (CBS_peek_asn1_tag(cbs, tag)) { @@ -528,7 +562,7 @@ int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { } int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, - unsigned tag) { + CBS_ASN1_TAG tag) { CBS child; int present; if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { @@ -549,7 +583,7 @@ int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, return 1; } -int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, CBS_ASN1_TAG tag, uint64_t default_value) { CBS child; int present; @@ -567,7 +601,7 @@ int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, return 1; } -int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, CBS_ASN1_TAG tag, int default_value) { CBS child, child2; int present; @@ -664,6 +698,29 @@ static int add_decimal(CBB *out, uint64_t v) { return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf)); } +int CBS_is_valid_asn1_oid(const CBS *cbs) { + if (CBS_len(cbs) == 0) { + return 0; // OID encodings cannot be empty. + } + + CBS copy = *cbs; + uint8_t v, prev = 0; + while (CBS_get_u8(©, &v)) { + // OID encodings are a sequence of minimally-encoded base-128 integers (see + // |parse_base128_integer|). If |prev|'s MSB was clear, it was the last byte + // of an integer (or |v| is the first byte). |v| is then the first byte of + // the next integer. If first byte of an integer is 0x80, it is not + // minimally-encoded. + if ((prev & 0x80) == 0 && v == 0x80) { + return 0; + } + prev = v; + } + + // The last byte should must end an integer encoding. + return (prev & 0x80) == 0; +} + char *CBS_asn1_oid_to_text(const CBS *cbs) { CBB cbb; if (!CBB_init(&cbb, 32)) { @@ -709,3 +766,161 @@ err: CBB_cleanup(&cbb); return NULL; } + +static int cbs_get_two_digits(CBS *cbs, int *out) { + uint8_t first_digit, second_digit; + if (!CBS_get_u8(cbs, &first_digit)) { + return 0; + } + if (!OPENSSL_isdigit(first_digit)) { + return 0; + } + if (!CBS_get_u8(cbs, &second_digit)) { + return 0; + } + if (!OPENSSL_isdigit(second_digit)) { + return 0; + } + *out = (first_digit - '0') * 10 + (second_digit - '0'); + return 1; +} + +static int is_valid_day(int year, int month, int day) { + if (day < 1) { + return 0; + } + switch (month) { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + return day <= 31; + case 4: + case 6: + case 9: + case 11: + return day <= 30; + case 2: + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { + return day <= 29; + } else { + return day <= 28; + } + default: + return 0; + } +} + +static int CBS_parse_rfc5280_time_internal(const CBS *cbs, int is_gentime, + int allow_timezone_offset, + struct tm *out_tm) { + int year, month, day, hour, min, sec, tmp; + CBS copy = *cbs; + uint8_t tz; + + if (is_gentime) { + if (!cbs_get_two_digits(©, &tmp)) { + return 0; + } + year = tmp * 100; + if (!cbs_get_two_digits(©, &tmp)) { + return 0; + } + year += tmp; + } else { + year = 1900; + if (!cbs_get_two_digits(©, &tmp)) { + return 0; + } + year += tmp; + if (year < 1950) { + year += 100; + } + if (year >= 2050) { + return 0; // A Generalized time must be used. + } + } + if (!cbs_get_two_digits(©, &month) || month < 1 || + month > 12 || // Reject invalid months. + !cbs_get_two_digits(©, &day) || + !is_valid_day(year, month, day) || // Reject invalid days. + !cbs_get_two_digits(©, &hour) || + hour > 23 || // Reject invalid hours. + !cbs_get_two_digits(©, &min) || + min > 59 || // Reject invalid minutes. + !cbs_get_two_digits(©, &sec) || sec > 59 || !CBS_get_u8(©, &tz)) { + return 0; + } + + int offset_sign = 0; + switch (tz) { + case 'Z': + break; // We correctly have 'Z' on the end as per spec. + case '+': + offset_sign = 1; + break; // Should not be allowed per RFC 5280. + case '-': + offset_sign = -1; + break; // Should not be allowed per RFC 5280. + default: + return 0; // Reject anything else after the time. + } + + // If allow_timezone_offset is non-zero, allow for a four digit timezone + // offset to be specified even though this is not allowed by RFC 5280. We are + // permissive of this for UTCTimes due to the unfortunate existence of + // artisinally rolled long lived certificates that were baked into places that + // are now difficult to change. These certificates were generated with the + // 'openssl' command that permissively allowed the creation of certificates + // with notBefore and notAfter times specified as strings for direct + // certificate inclusion on the command line. For context see cl/237068815. + // + // TODO(bbe): This has been expunged from public web-pki as the ecosystem has + // managed to encourage CA compliance with standards. We should find a way to + // get rid of this or make it off by default. + int offset_seconds = 0; + if (offset_sign != 0) { + if (!allow_timezone_offset) { + return 0; + } + int offset_hours, offset_minutes; + if (!cbs_get_two_digits(©, &offset_hours) || + offset_hours > 23 || // Reject invalid hours. + !cbs_get_two_digits(©, &offset_minutes) || + offset_minutes > 59) { // Reject invalid minutes. + return 0; + } + offset_seconds = offset_sign * (offset_hours * 3600 + offset_minutes * 60); + } + + if (CBS_len(©) != 0) { + return 0; // Reject invalid lengths. + } + + if (out_tm != NULL) { + // Fill in the tm fields corresponding to what we validated. + out_tm->tm_year = year - 1900; + out_tm->tm_mon = month - 1; + out_tm->tm_mday = day; + out_tm->tm_hour = hour; + out_tm->tm_min = min; + out_tm->tm_sec = sec; + if (offset_seconds && !OPENSSL_gmtime_adj(out_tm, 0, offset_seconds)) { + return 0; + } + } + return 1; +} + +int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm, + int allow_timezone_offset) { + return CBS_parse_rfc5280_time_internal(cbs, 1, allow_timezone_offset, out_tm); +} + +int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm, + int allow_timezone_offset) { + return CBS_parse_rfc5280_time_internal(cbs, 0, allow_timezone_offset, out_tm); +} diff --git a/third_party/boringssl/kit/src/crypto/bytestring/internal.h b/third_party/boringssl/kit/src/crypto/bytestring/internal.h index 7ef0e21c..ba23244f 100644 --- a/third_party/boringssl/kit/src/crypto/bytestring/internal.h +++ b/third_party/boringssl/kit/src/crypto/bytestring/internal.h @@ -54,8 +54,8 @@ OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, CBS *out, // It returns one on success and zero otherwise. OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, - unsigned outer_tag, - unsigned inner_tag); + CBS_ASN1_TAG outer_tag, + CBS_ASN1_TAG inner_tag); // CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized // with |CBB_init|. If |outp| is not NULL then the result is written to |*outp| diff --git a/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-armv8.pl b/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-armv8.pl index 608db667..c3a3653a 100755 --- a/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-armv8.pl +++ b/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-armv8.pl @@ -171,7 +171,7 @@ ChaCha20_ctr32: ldp @d[2],@d[3],[$key] // load key ldp @d[4],@d[5],[$key,#16] ldp @d[6],@d[7],[$ctr] // load counter -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 ror @d[4],@d[4],#32 @@ -240,7 +240,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -297,7 +297,7 @@ $code.=<<___; add @x[10],@x[10],@x[11],lsl#32 add @x[12],@x[12],@x[13],lsl#32 add @x[14],@x[14],@x[15],lsl#32 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -402,7 +402,7 @@ ChaCha20_neon: ldp @d[6],@d[7],[$ctr] // load counter ld1 {@K[3]},[$ctr] ld1 {$ONE},[@x[0]] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 @K[0],@K[0] ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 @@ -519,7 +519,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -599,7 +599,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -724,7 +724,7 @@ ChaCha20_512_neon: ldp @d[6],@d[7],[$ctr] // load counter ld1 {@K[3]},[$ctr] ld1 {$ONE},[@x[0]] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 @K[0],@K[0] ror @d[2],@d[2],#32 ror @d[3],@d[3],#32 @@ -866,7 +866,7 @@ $code.=<<___; add @x[14],@x[14],@x[15],lsl#32 ldp @x[13],@x[15],[$inp,#48] add $inp,$inp,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] @@ -1007,7 +1007,7 @@ $code.=<<___; add $inp,$inp,#64 add $B5,$B5,@K[1] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev @x[0],@x[0] rev @x[2],@x[2] rev @x[4],@x[4] diff --git a/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-x86_64.pl b/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-x86_64.pl index 8f3f4cee..31384def 100755 --- a/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/chacha/asm/chacha-x86_64.pl @@ -78,6 +78,7 @@ $code.=<<___; .extern OPENSSL_ia32cap_P +.section .rodata .align 64 .Lzero: .long 0,0,0,0 @@ -107,6 +108,7 @@ $code.=<<___; .Lsixteen: .long 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .asciz "ChaCha20 for x86_64, CRYPTOGAMS by " +.text ___ sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm diff --git a/third_party/boringssl/kit/src/crypto/chacha/chacha.c b/third_party/boringssl/kit/src/crypto/chacha/chacha.c index 64ca1c48..a4d88c0a 100644 --- a/third_party/boringssl/kit/src/crypto/chacha/chacha.c +++ b/third_party/boringssl/kit/src/crypto/chacha/chacha.c @@ -19,8 +19,6 @@ #include #include -#include - #include "../internal.h" #include "internal.h" @@ -93,7 +91,25 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, } #endif - ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce); + while (in_len > 0) { + // The assembly functions do not have defined overflow behavior. While + // overflow is almost always a bug in the caller, we prefer our functions to + // behave the same across platforms, so divide into multiple calls to avoid + // this case. + uint64_t todo = 64 * ((UINT64_C(1) << 32) - counter_nonce[0]); + if (todo > in_len) { + todo = in_len; + } + + ChaCha20_ctr32(out, in, (size_t)todo, key_ptr, counter_nonce); + in += todo; + out += todo; + in_len -= todo; + + // We're either done and will next break out of the loop, or we stopped at + // the wraparound point and the counter should continue at zero. + counter_nonce[0] = 0; + } } #else diff --git a/third_party/boringssl/kit/src/crypto/chacha/chacha_test.cc b/third_party/boringssl/kit/src/crypto/chacha/chacha_test.cc index 25313cad..00683ce5 100644 --- a/third_party/boringssl/kit/src/crypto/chacha/chacha_test.cc +++ b/third_party/boringssl/kit/src/crypto/chacha/chacha_test.cc @@ -218,8 +218,102 @@ static const uint8_t kOutput[] = { 0x8f, 0x40, 0xcf, 0x4a, }; +static uint32_t kOverflowCounter = 0xffffffff; + +static const uint8_t kOverflowOutput[] = { + 0x37, 0x64, 0x38, 0xcb, 0x25, 0x69, 0x2c, 0xf5, 0x88, 0x8a, 0xfe, 0x6d, + 0x3b, 0x10, 0x07, 0x3c, 0x77, 0xac, 0xcd, 0x1c, 0x0c, 0xa7, 0x17, 0x31, + 0x1d, 0xc3, 0x81, 0xd1, 0xa5, 0x20, 0x55, 0xea, 0xd3, 0x00, 0xc9, 0x84, + 0xde, 0xe2, 0xe5, 0x5e, 0x7b, 0x28, 0x28, 0x59, 0x73, 0x3a, 0x8e, 0x57, + 0x62, 0x18, 0x50, 0x55, 0x97, 0xca, 0x50, 0x3e, 0x8a, 0x84, 0x61, 0x28, + 0x4c, 0x22, 0x93, 0x50, 0x48, 0x7e, 0x65, 0x78, 0x06, 0x5a, 0xcd, 0x2b, + 0x11, 0xf7, 0x10, 0xfd, 0x6f, 0x41, 0x92, 0x82, 0x7c, 0x3a, 0x71, 0x07, + 0x67, 0xd0, 0x7e, 0xb7, 0xdf, 0xdc, 0xfc, 0xee, 0xe6, 0x55, 0xdd, 0x6f, + 0x79, 0x23, 0xf3, 0xae, 0xb1, 0x21, 0x96, 0xbe, 0xea, 0x0e, 0x1b, 0x58, + 0x0b, 0x3f, 0x63, 0x51, 0xd4, 0xce, 0x98, 0xfe, 0x1a, 0xc7, 0xa7, 0x43, + 0x7f, 0x0c, 0xe8, 0x62, 0xcf, 0x78, 0x3f, 0x4e, 0x31, 0xbf, 0x2b, 0x76, + 0x91, 0xcd, 0x19, 0x80, 0x0d, 0x7f, 0x11, 0x8b, 0x76, 0xef, 0x43, 0x3c, + 0x4f, 0x61, 0x86, 0xc5, 0x64, 0xa8, 0xc2, 0x73, 0xc2, 0x64, 0x39, 0xa0, + 0x8b, 0xe6, 0x7f, 0xf6, 0x26, 0xd4, 0x47, 0x4f, 0xe4, 0x46, 0xe2, 0xf5, + 0x9e, 0xe6, 0xc7, 0x76, 0x6c, 0xa9, 0x0f, 0x1d, 0x1b, 0x22, 0xa5, 0x62, + 0x0a, 0x88, 0x3e, 0x8c, 0xf0, 0xbc, 0x4c, 0x11, 0x3f, 0x0d, 0xf7, 0x85, + 0x67, 0x0b, 0x4c, 0xa3, 0x3f, 0xa8, 0xf1, 0x2a, 0x65, 0x2e, 0x00, 0x03, + 0xc9, 0x49, 0x91, 0x48, 0xb7, 0xc8, 0x29, 0x28, 0x2f, 0x46, 0x8e, 0x8b, + 0xd6, 0x73, 0x19, 0x06, 0x3e, 0x6f, 0x92, 0xc8, 0x3d, 0x3f, 0x4d, 0x68, + 0xbc, 0x02, 0xc0, 0x8f, 0x71, 0x46, 0x0d, 0x28, 0x63, 0xfe, 0xad, 0x14, + 0x81, 0x04, 0xb7, 0x23, 0xfd, 0x21, 0x0a, 0xf0, 0x6f, 0xcd, 0x47, 0x0b, + 0x0e, 0x93, 0xa3, 0xa8, 0x44, 0x15, 0xd6, 0xae, 0x06, 0x44, 0x6b, 0xbc, + 0xff, 0x8a, 0x56, 0x60, 0x3c, 0x38, 0xd6, 0xed, 0x03, 0x2d, 0x79, 0x2a, + 0xe9, 0x15, 0xef, 0xfc, 0x92, 0x1f, 0x83, 0xa4, 0x60, 0x8f, 0xc9, 0x29, + 0xb2, 0xb4, 0x9e, 0x3f, 0xa9, 0xe8, 0xfb, 0xa2, 0x62, 0x20, 0x2e, 0xc9, + 0x43, 0xb2, 0xd1, 0x36, 0x85, 0x1e, 0xa4, 0xb3, 0x4f, 0x8c, 0x9e, 0x81, + 0x75, 0x68, 0xbc, 0xf1, 0x52, 0xd5, 0x03, 0x22, 0xcf, 0xdf, 0x64, 0xb0, + 0x28, 0xd2, 0x45, 0x18, 0x38, 0x8c, 0xd0, 0xf6, 0x30, 0x3c, 0x04, 0xd9, + 0x8d, 0xb6, 0xb2, 0x57, 0x2a, 0xee, 0x28, 0xeb, 0x5f, 0x1a, 0x10, 0x6e, + 0x88, 0x79, 0x08, 0x23, 0x19, 0x84, 0xf8, 0x80, 0x1a, 0x7d, 0x6f, 0x8b, + 0xc1, 0x8e, 0x5f, 0x5f, 0x54, 0x14, 0x2a, 0xdc, 0x41, 0x5d, 0xeb, 0x00, + 0xf2, 0x50, 0xae, 0xd3, 0x55, 0x32, 0xf6, 0xd9, 0x34, 0xf4, 0xb2, 0xf2, + 0xf5, 0x90, 0x05, 0x8a, 0x9c, 0xc7, 0x94, 0x5d, 0x2d, 0x5a, 0x0f, 0xdd, + 0x03, 0xde, 0xbe, 0x18, 0xb3, 0xe3, 0x07, 0x6b, 0x57, 0xfa, 0x1b, 0x7b, + 0x75, 0xcb, 0xc2, 0x4d, 0xf7, 0x88, 0xfe, 0xf9, 0xc0, 0x6c, 0xdb, 0x5f, + 0xf6, 0x48, 0x00, 0x4a, 0x5d, 0x75, 0xfa, 0x6b, 0x45, 0x43, 0xc4, 0x7f, + 0x97, 0x31, 0x22, 0xb4, 0x9c, 0xa3, 0xee, 0x2f, 0x27, 0xa9, 0x9f, 0x0e, + 0xdc, 0x40, 0x67, 0x17, 0x2e, 0xcb, 0xfd, 0x9e, 0xe7, 0xb2, 0x85, 0xcd, + 0x49, 0x24, 0xc8, 0x8a, 0x59, 0x6b, 0x1f, 0xec, 0x72, 0x89, 0xf8, 0x30, + 0xdf, 0x82, 0x61, 0x3b, 0x8b, 0xc9, 0x80, 0xe4, 0x27, 0x0d, 0xfe, 0x42, + 0x27, 0x6c, 0xaf, 0x62, 0x3e, 0x2f, 0x1d, 0x38, 0xb6, 0x88, 0x8f, 0x71, + 0x5a, 0x54, 0x6c, 0x68, 0x57, 0x40, 0x49, 0x7a, 0xb2, 0xe8, 0xb6, 0x97, + 0xab, 0xd6, 0x3c, 0x35, 0xf3, 0x95, 0x12, 0xde, 0xa2, 0x39, 0x54, 0x52, + 0x8c, 0x38, 0x2a, 0x2b, 0xe7, 0x21, 0x38, 0x63, 0xb0, 0xd6, 0xad, 0x94, + 0x44, 0xaf, 0x49, 0x5d, 0xfc, 0x49, 0x6b, 0x30, 0xdf, 0xe9, 0x19, 0x1e, + 0xed, 0x98, 0x0d, 0x4a, 0x3d, 0x56, 0x5e, 0x74, 0xad, 0x13, 0x8b, 0x68, + 0x45, 0x08, 0xbe, 0x0e, 0x6c, 0xb4, 0x62, 0x93, 0x27, 0x8b, 0x4f, 0xab, + 0x3e, 0xba, 0xe1, 0xe5, 0xff, 0xa8, 0x5d, 0x33, 0x32, 0xff, 0x34, 0xf9, + 0x8d, 0x67, 0x24, 0x4a, 0xbb, 0x2c, 0x60, 0xb5, 0x88, 0x96, 0x1b, 0xcc, + 0x53, 0xfb, 0x2e, 0x05, 0x1d, 0x8b, 0xc2, 0xa0, 0xde, 0x21, 0x41, 0x5e, + 0x11, 0x1b, 0x96, 0xd9, 0xa6, 0xae, 0xbd, 0xf0, 0x91, 0xad, 0x69, 0x2b, + 0xd2, 0x3f, 0xe4, 0x3d, 0x16, 0x69, 0xa6, 0xb2, 0x9c, 0xbe, 0x59, 0x7b, + 0x87, 0x79, 0xf5, 0xc2, 0x5a, 0xcc, 0xdf, 0xfe, 0x7f, 0xf9, 0xa6, 0x52, + 0xde, 0x5f, 0x46, 0x91, 0x21, 0x2c, 0x2c, 0x49, 0x25, 0x00, 0xd5, 0xe4, + 0x81, 0x6b, 0x85, 0xad, 0x98, 0xaf, 0x06, 0x4a, 0x83, 0xb2, 0xe3, 0x42, + 0x39, 0x31, 0x50, 0xe1, 0x2d, 0x22, 0xe6, 0x07, 0x24, 0x65, 0x29, 0x3f, + 0x4c, 0xbd, 0x14, 0x8d, 0xfa, 0x31, 0xfa, 0xa4, 0xb5, 0x99, 0x04, 0xa2, + 0xa5, 0xcc, 0x3b, 0x12, 0xb1, 0xaa, 0x6a, 0x17, 0x78, 0x8b, 0xb3, 0xe4, + 0x3c, 0x4c, 0xc5, 0xaa, 0x79, 0x12, 0x17, 0xe0, 0x22, 0x4d, 0xf4, 0xa9, + 0xd5, 0xd0, 0xed, 0xf8, 0xfe, 0x0a, 0x45, 0x80, 0x9f, 0x3b, 0x74, 0xa0, + 0xb1, 0xda, 0x18, 0xfa, 0xc2, 0x7d, 0xf6, 0x18, 0x2e, 0xa9, 0x2b, 0x7e, + 0x69, 0x06, 0x43, 0x2d, 0x62, 0x09, 0x42, 0x10, 0x9f, 0x83, 0xad, 0xd9, + 0xdd, 0xcd, 0xcb, 0x1b, 0x33, 0x32, 0x3e, 0x1f, 0xf6, 0xac, 0x3b, 0xa3, + 0x29, 0xd7, 0xc0, 0x88, 0xf9, 0xb7, 0x4c, 0xcd, 0x0a, 0x1f, 0xb8, 0x0f, + 0xe6, 0xf7, 0xd7, 0x4d, 0x5f, 0x06, 0x12, 0x8a, 0x12, 0xa6, 0x2d, 0xbe, + 0x5c, 0x57, 0xf8, 0x7f, 0x54, 0x3f, 0x90, 0x83, 0x2c, 0x0a, 0xc5, 0x3d, + 0x03, 0x78, 0x8a, 0x68, 0xf0, 0xbd, 0xa5, 0x3e, 0xe7, 0x07, 0xab, 0xc8, + 0x58, 0x2f, 0x5c, 0xfd, 0xb5, 0x39, 0xe3, 0xc6, 0x1c, 0x27, 0xf9, 0x0b, + 0xc7, 0x4c, 0xcc, 0x67, 0x62, 0xe6, 0x79, 0xe8, 0xc1, 0x0a, 0x86, 0x8a, + 0xb2, 0x32, 0x7b, 0x90, 0x36, 0x50, 0x92, 0x1f, 0x3e, 0x68, 0x39, 0x1c, + 0x4d, 0x5d, 0xf8, 0x2b, 0xe8, 0x7d, 0xe2, 0x34, 0x61, 0x9e, 0xc3, 0x77, + 0xb9, 0x4c, 0x34, 0x08, 0xda, 0x31, 0xc9, 0x1d, 0xbd, 0x3b, 0x7b, 0xf1, + 0x14, 0xba, 0x3a, 0x34, 0x13, 0xaa, 0x5e, 0xa8, 0x36, 0xf6, 0xfe, 0xed, + 0x5b, 0xef, 0xaf, 0x24, 0x42, 0xba, 0xfc, 0xc9, 0x30, 0x84, 0xec, 0x49, + 0x14, 0xab, 0x58, 0x71, 0xfe, 0x4b, 0x6d, 0x7b, 0x9f, 0xbb, 0x3c, 0x83, + 0xdf, 0x3a, 0xfb, 0x54, 0xff, 0x36, 0xaa, 0x6c, 0x47, 0x94, 0xc0, 0xde, + 0x89, 0x2e, 0xac, 0x68, 0xee, 0xe8, 0xf4, 0xae, 0xa3, 0xe0, 0x91, 0x55, + 0x0b, 0x0c, 0xd7, 0xf4, 0x33, 0xb5, 0xf9, 0xf2, 0x9e, 0xda, 0x78, 0xe5, + 0x75, 0xec, 0xdb, 0xf6, 0xed, 0x27, 0x9f, 0x44, 0x19, 0x9f, 0xb7, 0xf0, + 0xac, 0x1b, 0x3a, 0xf5, 0x77, 0xc7, 0x76, 0x1e, 0x3f, 0x78, 0x12, 0x48, + 0x1d, 0xb8, 0xe0, 0x30, 0x29, 0x9a, 0x8c, 0x8f, 0x21, 0x44, 0x9c, 0x89, + 0xec, 0x8e, 0xd0, 0x81, 0xf5, 0x6a, 0xd0, 0xac, 0x5e, 0xf0, 0x0f, 0x88, + 0x86, 0x31, 0x2e, 0x15, 0x1e, 0x0d, 0x2d, 0xeb, 0x56, 0x30, 0x27, 0x02, + 0x93, 0xf4, 0x07, 0x07, 0xba, 0xf7, 0xbd, 0xe8, 0x27, 0x4f, 0xc6, 0xd9, + 0x57, 0x10, 0x3b, 0xf0, 0xff, 0x2f, 0x2d, 0x6b, 0xd0, 0x17, 0xb3, 0x49, + 0xeb, 0xc2, 0x49, 0xdb, +}; + + static_assert(sizeof(kInput) == sizeof(kOutput), "Input and output lengths don't match."); +static_assert(sizeof(kInput) == sizeof(kOverflowOutput), + "Input and output lengths don't match."); TEST(ChaChaTest, TestVector) { // Run the test with the test vector at all lengths. @@ -237,6 +331,22 @@ TEST(ChaChaTest, TestVector) { } } +TEST(ChaChaTest, CounterOverflow) { + // Run the test with the test vector at all lengths. + for (size_t len = 0; len <= sizeof(kInput); len++) { + SCOPED_TRACE(len); + + std::unique_ptr buf(new uint8_t[len]); + CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kOverflowCounter); + EXPECT_EQ(Bytes(kOverflowOutput, len), Bytes(buf.get(), len)); + + // Test the in-place version. + OPENSSL_memcpy(buf.get(), kInput, len); + CRYPTO_chacha_20(buf.get(), buf.get(), len, kKey, kNonce, kOverflowCounter); + EXPECT_EQ(Bytes(kOverflowOutput, len), Bytes(buf.get(), len)); + } +} + #if defined(CHACHA20_ASM) && defined(SUPPORTS_ABI_TEST) TEST(ChaChaTest, ABI) { uint32_t key[8]; diff --git a/third_party/boringssl/kit/src/crypto/chacha/internal.h b/third_party/boringssl/kit/src/crypto/chacha/internal.h index 1435e3b0..5f442ec4 100644 --- a/third_party/boringssl/kit/src/crypto/chacha/internal.h +++ b/third_party/boringssl/kit/src/crypto/chacha/internal.h @@ -32,7 +32,14 @@ void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32], defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) #define CHACHA20_ASM -// ChaCha20_ctr32 is defined in asm/chacha-*.pl. +// ChaCha20_ctr32 encrypts |in_len| bytes from |in| and writes the result to +// |out|. If |in| and |out| alias, they must be equal. +// +// |counter[0]| is the initial 32-bit block counter, and the remainder is the +// 96-bit nonce. If the counter overflows, the output is undefined. The function +// will produce output, but the output may vary by machine and may not be +// self-consistent. (On some architectures, the assembly implements a mix of +// 64-bit and 32-bit counters.) void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len, const uint32_t key[8], const uint32_t counter[4]); #endif diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/aead_test.cc b/third_party/boringssl/kit/src/crypto/cipher_extra/aead_test.cc index 9e5dceef..a8d2dbd8 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/aead_test.cc +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/aead_test.cc @@ -12,6 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include @@ -48,13 +49,8 @@ constexpr uint32_t kNondeterministic = 1 << 7; // RequiresADLength encodes an AD length requirement into flags. constexpr uint32_t RequiresADLength(size_t length) { - // If we had a more recent C++ version we could assert that the length is - // sufficiently small with: - // - // if (length >= 16) { - // __builtin_unreachable(); - // } - return (length & 0xf) << 3; + assert(length < 16); + return static_cast((length & 0xf) << 3); } // RequiredADLength returns the AD length requirement encoded in |flags|, or @@ -64,9 +60,8 @@ constexpr size_t RequiredADLength(uint32_t flags) { } constexpr uint32_t RequiresMinimumTagLength(size_t length) { - // See above for statically checking the size at compile time with future C++ - // versions. - return (length & 0xf) << 8; + assert(length < 16); + return static_cast((length & 0xf) << 8); } constexpr size_t MinimumTagLength(uint32_t flags) { @@ -154,6 +149,9 @@ static const struct KnownAEAD kAEADs[] = { {"AES_128_CCM_BLUETOOTH_8", EVP_aead_aes_128_ccm_bluetooth_8, "aes_128_ccm_bluetooth_8_tests.txt", 0}, + + {"AES_128_CCM_Matter", EVP_aead_aes_128_ccm_matter, + "aes_128_ccm_matter_tests.txt", 0}, }; class PerAEADTest : public testing::TestWithParam { @@ -1008,3 +1006,7 @@ TEST(AEADTest, WycheproofXChaCha20Poly1305) { RunWycheproofTestCase(t, EVP_aead_xchacha20_poly1305()); }); } + +TEST(AEADTest, FreeNull) { + EVP_AEAD_CTX_free(nullptr); +} diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl index aad31ab7..f7d419bb 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/aes128gcmsiv-x86_64.pl @@ -32,7 +32,7 @@ open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; *STDOUT=*OUT; $code.=<<___; -.data +.section .rodata .align 16 one: diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_armv8.pl b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_armv8.pl new file mode 100644 index 00000000..9bd7f49d --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_armv8.pl @@ -0,0 +1,1644 @@ +#!/usr/bin/env perl + +# Copyright (c) 2020, CloudFlare Ltd. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +############################################################################## +# # +# Author: Vlad Krasnov # +# # +############################################################################## + +$flavour = shift; +while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +my ($oup,$inp,$inl,$adp,$adl,$keyp,$itr1,$itr2) = ("x0","x1","x2","x3","x4","x5","x6","x7"); +my ($acc0,$acc1,$acc2) = map("x$_",(8..10)); +my ($t0,$t1,$t2,$t3) = map("x$_",(11..14)); +my ($one, $r0, $r1) = ("x15","x16","x17"); +my ($t0w) = $t0 =~ s/x/w/r; + +my ($A0,$A1,$A2,$A3,$A4,$B0,$B1,$B2,$B3,$B4,$C0,$C1,$C2,$C3,$C4,$D0,$D1,$D2,$D3,$D4) = map("v$_",(0..19)); +my ($T0,$T1,$T2,$T3) = map("v$_",(20..23)); + +my $CONSTS = "v24"; +my $INC = "v25"; +my $ROL8 = "v26"; +my $CLAMP = "v27"; + +my ($B_STORE, $C_STORE, $D_STORE) = map("v$_",(28..30)); + +my $S_STORE = $CLAMP; +my $LEN_STORE = "v31"; + +sub chacha_qr { +my ($a,$b,$c,$d,$t,$dir)=@_; +my ($shift_b,$shift_d) = $dir =~ /left/ ? ("#4","#12") : ("#12","#4"); +$code.=<<___; + add $a.4s, $a.4s, $b.4s + eor $d.16b, $d.16b, $a.16b + rev32 $d.8h, $d.8h + + add $c.4s, $c.4s, $d.4s + eor $b.16b, $b.16b, $c.16b + ushr $t.4s, $b.4s, #20 + sli $t.4s, $b.4s, #12 +___ + ($t,$b) = ($b,$t); +$code.=<<___; + add $a.4s, $a.4s, $b.4s + eor $d.16b, $d.16b, $a.16b + tbl $d.16b, {$d.16b}, $ROL8.16b + + add $c.4s, $c.4s, $d.4s + eor $b.16b, $b.16b, $c.16b + ushr $t.4s, $b.4s, #25 + sli $t.4s, $b.4s, #7 +___ + ($t,$b) = ($b,$t); +$code.=<<___; + ext $b.16b, $b.16b, $b.16b, $shift_b + ext $c.16b, $c.16b, $c.16b, #8 + ext $d.16b, $d.16b, $d.16b, $shift_d +___ +} + +sub poly_add { +my ($src)=@_; +$code.="ldp $t0, $t1, [$src], 16 + adds $acc0, $acc0, $t0 + adcs $acc1, $acc1, $t1 + adc $acc2, $acc2, $one\n"; +} + +sub poly_add_vec { +my ($src)=@_; +$code.="mov $t0, $src.d[0] + mov $t1, $src.d[1] + adds $acc0, $acc0, $t0 + adcs $acc1, $acc1, $t1 + adc $acc2, $acc2, $one\n"; +} + +sub poly_stage1 { +$code.="mul $t0, $acc0, $r0 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh $t1, $acc0, $r0 + mul $t2, $acc1, $r0 + umulh $t3, $acc1, $r0 + adds $t1, $t1, $t2 + mul $t2, $acc2, $r0 + adc $t2, $t2, $t3\n"; +} + +sub poly_stage2 { +$code.="mul $t3, $acc0, $r1 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh $acc0, $acc0, $r1 + adds $t1, $t1, $t3 + mul $t3, $acc1, $r1 + umulh $acc1, $acc1, $r1 + adcs $t3, $t3, $acc0 + mul $acc2, $acc2, $r1 + adc $acc2, $acc2, $acc1 + adds $t2, $t2, $t3 + adc $t3, $acc2, xzr\n"; +} + +# At the beginning of the reduce stage t = [t3:t2:t1:t0] is a product of +# r = [r1:r0] and acc = [acc2:acc1:acc0] +# r is 124 bits at most (due to clamping) and acc is 131 bits at most +# (acc2 is at most 4 before the addition and can be at most 6 when we add in +# the next block) therefore t is at most 255 bits big, and t3 is 63 bits. +sub poly_reduce_stage { +$code.="and $acc2, $t2, #3 // At this point acc2 is 2 bits at most (value of 3) + and $acc0, $t2, #-4 + extr $t2, $t3, $t2, #2 + adds $acc0, $acc0, $t0 + lsr $t0, $t3, #2 + adc $acc1, $t3, $t0 // No carry out since t0 is 61 bits and t3 is 63 bits + adds $acc0, $acc0, $t2 + adcs $acc1, $acc1, $t1 + adc $acc2, $acc2, xzr // At this point acc2 has the value of 4 at most \n"; +} + +sub poly_mul { + &poly_stage1(); + &poly_stage2(); + &poly_reduce_stage(); +} + +sub chacha_qr_x3 { +my ($dir)=@_; +my ($shift_b,$shift_d) = $dir =~ /left/ ? ("#4","#12") : ("#12","#4"); +$code.=<<___; + add $A0.4s, $A0.4s, $B0.4s + add $A1.4s, $A1.4s, $B1.4s + add $A2.4s, $A2.4s, $B2.4s + eor $D0.16b, $D0.16b, $A0.16b + eor $D1.16b, $D1.16b, $A1.16b + eor $D2.16b, $D2.16b, $A2.16b + rev32 $D0.8h, $D0.8h + rev32 $D1.8h, $D1.8h + rev32 $D2.8h, $D2.8h + + add $C0.4s, $C0.4s, $D0.4s + add $C1.4s, $C1.4s, $D1.4s + add $C2.4s, $C2.4s, $D2.4s + eor $B0.16b, $B0.16b, $C0.16b + eor $B1.16b, $B1.16b, $C1.16b + eor $B2.16b, $B2.16b, $C2.16b + ushr $T0.4s, $B0.4s, #20 + sli $T0.4s, $B0.4s, #12 + ushr $B0.4s, $B1.4s, #20 + sli $B0.4s, $B1.4s, #12 + ushr $B1.4s, $B2.4s, #20 + sli $B1.4s, $B2.4s, #12 + + add $A0.4s, $A0.4s, $T0.4s + add $A1.4s, $A1.4s, $B0.4s + add $A2.4s, $A2.4s, $B1.4s + eor $D0.16b, $D0.16b, $A0.16b + eor $D1.16b, $D1.16b, $A1.16b + eor $D2.16b, $D2.16b, $A2.16b + tbl $D0.16b, {$D0.16b}, $ROL8.16b + tbl $D1.16b, {$D1.16b}, $ROL8.16b + tbl $D2.16b, {$D2.16b}, $ROL8.16b + + add $C0.4s, $C0.4s, $D0.4s + add $C1.4s, $C1.4s, $D1.4s + add $C2.4s, $C2.4s, $D2.4s + eor $T0.16b, $T0.16b, $C0.16b + eor $B0.16b, $B0.16b, $C1.16b + eor $B1.16b, $B1.16b, $C2.16b + ushr $B2.4s, $B1.4s, #25 + sli $B2.4s, $B1.4s, #7 + ushr $B1.4s, $B0.4s, #25 + sli $B1.4s, $B0.4s, #7 + ushr $B0.4s, $T0.4s, #25 + sli $B0.4s, $T0.4s, #7 + + ext $B0.16b, $B0.16b, $B0.16b, $shift_b + ext $B1.16b, $B1.16b, $B1.16b, $shift_b + ext $B2.16b, $B2.16b, $B2.16b, $shift_b + + ext $C0.16b, $C0.16b, $C0.16b, #8 + ext $C1.16b, $C1.16b, $C1.16b, #8 + ext $C2.16b, $C2.16b, $C2.16b, #8 + + ext $D0.16b, $D0.16b, $D0.16b, $shift_d + ext $D1.16b, $D1.16b, $D1.16b, $shift_d + ext $D2.16b, $D2.16b, $D2.16b, $shift_d +___ +} + +# When preparing 5 ChaCha20 blocks in parallel, we operate on 4 blocks vertically as introduced by Andrew Moon +# the fifth block is done horizontally +sub chacha_qr_x5 { +my ($dir)=@_; +my ($a0,$a1,$a2,$a3) = $dir =~ /left/ ? ($A0,$A1,$A2,$A3) : ($A0,$A1,$A2,$A3); +my ($b0,$b1,$b2,$b3) = $dir =~ /left/ ? ($B0,$B1,$B2,$B3) : ($B1,$B2,$B3,$B0); +my ($c0,$c1,$c2,$c3) = $dir =~ /left/ ? ($C0,$C1,$C2,$C3) : ($C2,$C3,$C0,$C1); +my ($d0,$d1,$d2,$d3) = $dir =~ /left/ ? ($D0,$D1,$D2,$D3) : ($D3,$D0,$D1,$D2); +my ($shift_b,$shift_d) = $dir =~ /left/ ? ("#4","#12") : ("#12","#4"); +$code.=<<___; + add $a0.4s, $a0.4s, $b0.4s + add $a1.4s, $a1.4s, $b1.4s + add $a2.4s, $a2.4s, $b2.4s + add $a3.4s, $a3.4s, $b3.4s + add $A4.4s, $A4.4s, $B4.4s + + eor $d0.16b, $d0.16b, $a0.16b + eor $d1.16b, $d1.16b, $a1.16b + eor $d2.16b, $d2.16b, $a2.16b + eor $d3.16b, $d3.16b, $a3.16b + eor $D4.16b, $D4.16b, $A4.16b + + rev32 $d0.8h, $d0.8h + rev32 $d1.8h, $d1.8h + rev32 $d2.8h, $d2.8h + rev32 $d3.8h, $d3.8h + rev32 $D4.8h, $D4.8h + + add $c0.4s, $c0.4s, $d0.4s + add $c1.4s, $c1.4s, $d1.4s + add $c2.4s, $c2.4s, $d2.4s + add $c3.4s, $c3.4s, $d3.4s + add $C4.4s, $C4.4s, $D4.4s + + eor $b0.16b, $b0.16b, $c0.16b + eor $b1.16b, $b1.16b, $c1.16b + eor $b2.16b, $b2.16b, $c2.16b + eor $b3.16b, $b3.16b, $c3.16b + eor $B4.16b, $B4.16b, $C4.16b + + ushr $T0.4s, $b0.4s, #20 + sli $T0.4s, $b0.4s, #12 + ushr $b0.4s, $b1.4s, #20 + sli $b0.4s, $b1.4s, #12 + ushr $b1.4s, $b2.4s, #20 + sli $b1.4s, $b2.4s, #12 + ushr $b2.4s, $b3.4s, #20 + sli $b2.4s, $b3.4s, #12 + ushr $b3.4s, $B4.4s, #20 + sli $b3.4s, $B4.4s, #12 + + add $a0.4s, $a0.4s, $T0.4s + add $a1.4s, $a1.4s, $b0.4s + add $a2.4s, $a2.4s, $b1.4s + add $a3.4s, $a3.4s, $b2.4s + add $A4.4s, $A4.4s, $b3.4s + + eor $d0.16b, $d0.16b, $a0.16b + eor $d1.16b, $d1.16b, $a1.16b + eor $d2.16b, $d2.16b, $a2.16b + eor $d3.16b, $d3.16b, $a3.16b + eor $D4.16b, $D4.16b, $A4.16b + + tbl $d0.16b, {$d0.16b}, $ROL8.16b + tbl $d1.16b, {$d1.16b}, $ROL8.16b + tbl $d2.16b, {$d2.16b}, $ROL8.16b + tbl $d3.16b, {$d3.16b}, $ROL8.16b + tbl $D4.16b, {$D4.16b}, $ROL8.16b + + add $c0.4s, $c0.4s, $d0.4s + add $c1.4s, $c1.4s, $d1.4s + add $c2.4s, $c2.4s, $d2.4s + add $c3.4s, $c3.4s, $d3.4s + add $C4.4s, $C4.4s, $D4.4s + + eor $T0.16b, $T0.16b, $c0.16b + eor $b0.16b, $b0.16b, $c1.16b + eor $b1.16b, $b1.16b, $c2.16b + eor $b2.16b, $b2.16b, $c3.16b + eor $b3.16b, $b3.16b, $C4.16b + + ushr $B4.4s, $b3.4s, #25 + sli $B4.4s, $b3.4s, #7 + ushr $b3.4s, $b2.4s, #25 + sli $b3.4s, $b2.4s, #7 + ushr $b2.4s, $b1.4s, #25 + sli $b2.4s, $b1.4s, #7 + ushr $b1.4s, $b0.4s, #25 + sli $b1.4s, $b0.4s, #7 + ushr $b0.4s, $T0.4s, #25 + sli $b0.4s, $T0.4s, #7 + + ext $B4.16b, $B4.16b, $B4.16b, $shift_b + ext $C4.16b, $C4.16b, $C4.16b, #8 + ext $D4.16b, $D4.16b, $D4.16b, $shift_d +___ +} + +{ +$code.=<<___; +#include +.section .rodata + +.align 7 +.Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +.Linc: +.long 1,2,3,4 +.Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +.Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC + +.text + +.type .Lpoly_hash_ad_internal,%function +.align 6 +.Lpoly_hash_ad_internal: + .cfi_startproc + cbnz $adl, .Lpoly_hash_intro + ret + +.Lpoly_hash_intro: + cmp $adl, #16 + b.lt .Lpoly_hash_ad_tail +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + sub $adl, $adl, #16 + b .Lpoly_hash_ad_internal + +.Lpoly_hash_ad_tail: + cbz $adl, .Lpoly_hash_ad_ret + + eor $T0.16b, $T0.16b, $T0.16b // Use T0 to load the AAD + sub $adl, $adl, #1 + +.Lpoly_hash_tail_16_compose: + ext $T0.16b, $T0.16b, $T0.16b, #15 + ldrb $t0w, [$adp, $adl] + mov $T0.b[0], $t0w + subs $adl, $adl, #1 + b.ge .Lpoly_hash_tail_16_compose +___ + &poly_add_vec($T0); + &poly_mul(); +$code.=<<___; + +.Lpoly_hash_ad_ret: + ret + .cfi_endproc +.size .Lpoly_hash_ad_internal, .-.Lpoly_hash_ad_internal + +///////////////////////////////// +// +// void chacha20_poly1305_seal(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *seal_data); +// +.globl chacha20_poly1305_seal +.type chacha20_poly1305_seal,%function +.align 6 +chacha20_poly1305_seal: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp $t0, :pg_hi21:.Lchacha20_consts + add $t0, $t0, :lo12:.Lchacha20_consts + + ld1 {$CONSTS.16b - $CLAMP.16b}, [$t0] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {$B_STORE.16b - $D_STORE.16b}, [$keyp] + + mov $one, #1 // Prepare the Poly1305 state + mov $acc0, #0 + mov $acc1, #0 + mov $acc2, #0 + + ldr $t1, [$keyp, #56] // The total cipher text length includes extra_in_len + add $t1, $t1, $inl + mov $LEN_STORE.d[0], $adl // Store the input and aad lengths + mov $LEN_STORE.d[1], $t1 + + cmp $inl, #128 + b.le .Lseal_128 // Optimization for smaller buffers + + // Initially we prepare 5 ChaCha20 blocks. Four to encrypt up to 4 blocks (256 bytes) of plaintext, + // and one for the Poly1305 R and S keys. The first four blocks (A0-A3..D0-D3) are computed vertically, + // the fifth block (A4-D4) horizontally. + ld4r {$A0.4s-$A3.4s}, [$t0] + mov $A4.16b, $CONSTS.16b + + ld4r {$B0.4s-$B3.4s}, [$keyp], #16 + mov $B4.16b, $B_STORE.16b + + ld4r {$C0.4s-$C3.4s}, [$keyp], #16 + mov $C4.16b, $C_STORE.16b + + ld4r {$D0.4s-$D3.4s}, [$keyp] + add $D0.4s, $D0.4s, $INC.4s + mov $D4.16b, $D_STORE.16b + + sub $keyp, $keyp, #32 + + mov $itr1, #10 + +.align 5 +.Lseal_init_rounds: +___ + &chacha_qr_x5("left"); + &chacha_qr_x5("right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.hi .Lseal_init_rounds + + add $D0.4s, $D0.4s, $INC.4s + mov $t0, #4 + dup $T0.4s, $t0w + add $INC.4s, $INC.4s, $T0.4s + + zip1 $T0.4s, $A0.4s, $A1.4s + zip2 $T1.4s, $A0.4s, $A1.4s + zip1 $T2.4s, $A2.4s, $A3.4s + zip2 $T3.4s, $A2.4s, $A3.4s + + zip1 $A0.2d, $T0.2d, $T2.2d + zip2 $A1.2d, $T0.2d, $T2.2d + zip1 $A2.2d, $T1.2d, $T3.2d + zip2 $A3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $B0.4s, $B1.4s + zip2 $T1.4s, $B0.4s, $B1.4s + zip1 $T2.4s, $B2.4s, $B3.4s + zip2 $T3.4s, $B2.4s, $B3.4s + + zip1 $B0.2d, $T0.2d, $T2.2d + zip2 $B1.2d, $T0.2d, $T2.2d + zip1 $B2.2d, $T1.2d, $T3.2d + zip2 $B3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $C0.4s, $C1.4s + zip2 $T1.4s, $C0.4s, $C1.4s + zip1 $T2.4s, $C2.4s, $C3.4s + zip2 $T3.4s, $C2.4s, $C3.4s + + zip1 $C0.2d, $T0.2d, $T2.2d + zip2 $C1.2d, $T0.2d, $T2.2d + zip1 $C2.2d, $T1.2d, $T3.2d + zip2 $C3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $D0.4s, $D1.4s + zip2 $T1.4s, $D0.4s, $D1.4s + zip1 $T2.4s, $D2.4s, $D3.4s + zip2 $T3.4s, $D2.4s, $D3.4s + + zip1 $D0.2d, $T0.2d, $T2.2d + zip2 $D1.2d, $T0.2d, $T2.2d + zip1 $D2.2d, $T1.2d, $T3.2d + zip2 $D3.2d, $T1.2d, $T3.2d + + add $A4.4s, $A4.4s, $CONSTS.4s + add $B4.4s, $B4.4s, $B_STORE.4s + and $A4.16b, $A4.16b, $CLAMP.16b + + add $A0.4s, $A0.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + + add $A1.4s, $A1.4s, $CONSTS.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + add $D1.4s, $D1.4s, $D_STORE.4s + + add $A2.4s, $A2.4s, $CONSTS.4s + add $B2.4s, $B2.4s, $B_STORE.4s + add $C2.4s, $C2.4s, $C_STORE.4s + add $D2.4s, $D2.4s, $D_STORE.4s + + add $A3.4s, $A3.4s, $CONSTS.4s + add $B3.4s, $B3.4s, $B_STORE.4s + add $C3.4s, $C3.4s, $C_STORE.4s + add $D3.4s, $D3.4s, $D_STORE.4s + + mov $r0, $A4.d[0] // Move the R key to GPRs + mov $r1, $A4.d[1] + mov $S_STORE.16b, $B4.16b // Store the S key + + bl .Lpoly_hash_ad_internal + + mov $adp, $oup + cmp $inl, #256 + b.le .Lseal_tail + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A0.16b + eor $T1.16b, $T1.16b, $B0.16b + eor $T2.16b, $T2.16b, $C0.16b + eor $T3.16b, $T3.16b, $D0.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A1.16b + eor $T1.16b, $T1.16b, $B1.16b + eor $T2.16b, $T2.16b, $C1.16b + eor $T3.16b, $T3.16b, $D1.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A2.16b + eor $T1.16b, $T1.16b, $B2.16b + eor $T2.16b, $T2.16b, $C2.16b + eor $T3.16b, $T3.16b, $D2.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A3.16b + eor $T1.16b, $T1.16b, $B3.16b + eor $T2.16b, $T2.16b, $C3.16b + eor $T3.16b, $T3.16b, $D3.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #256 + + mov $itr1, #4 // In the first run of the loop we need to hash 256 bytes, therefore we hash one block for the first 4 rounds + mov $itr2, #6 // and two blocks for the remaining 6, for a total of (1 * 4 + 2 * 6) * 16 = 256 + +.Lseal_main_loop: + adrp $t0, :pg_hi21:.Lchacha20_consts + add $t0, $t0, :lo12:.Lchacha20_consts + + ld4r {$A0.4s-$A3.4s}, [$t0] + mov $A4.16b, $CONSTS.16b + + ld4r {$B0.4s-$B3.4s}, [$keyp], #16 + mov $B4.16b, $B_STORE.16b + + ld4r {$C0.4s-$C3.4s}, [$keyp], #16 + mov $C4.16b, $C_STORE.16b + + ld4r {$D0.4s-$D3.4s}, [$keyp] + add $D0.4s, $D0.4s, $INC.4s + mov $D4.16b, $D_STORE.16b + + eor $T0.16b, $T0.16b, $T0.16b //zero + not $T1.16b, $T0.16b // -1 + sub $T1.4s, $INC.4s, $T1.4s // Add +1 + ext $T0.16b, $T1.16b, $T0.16b, #12 // Get the last element (counter) + add $D4.4s, $D4.4s, $T0.4s + + sub $keyp, $keyp, #32 +.align 5 +.Lseal_main_loop_rounds: +___ + &chacha_qr_x5("left"); + &poly_add($adp); + &poly_mul(); + &chacha_qr_x5("right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.ge .Lseal_main_loop_rounds +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + subs $itr2, $itr2, #1 + b.gt .Lseal_main_loop_rounds + + eor $T0.16b, $T0.16b, $T0.16b //zero + not $T1.16b, $T0.16b // -1 + sub $T1.4s, $INC.4s, $T1.4s // Add +1 + ext $T0.16b, $T1.16b, $T0.16b, #12 // Get the last element (counter) + add $D4.4s, $D4.4s, $T0.4s + + add $D0.4s, $D0.4s, $INC.4s + mov $t0, #5 + dup $T0.4s, $t0w + add $INC.4s, $INC.4s, $T0.4s + + zip1 $T0.4s, $A0.4s, $A1.4s + zip2 $T1.4s, $A0.4s, $A1.4s + zip1 $T2.4s, $A2.4s, $A3.4s + zip2 $T3.4s, $A2.4s, $A3.4s + + zip1 $A0.2d, $T0.2d, $T2.2d + zip2 $A1.2d, $T0.2d, $T2.2d + zip1 $A2.2d, $T1.2d, $T3.2d + zip2 $A3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $B0.4s, $B1.4s + zip2 $T1.4s, $B0.4s, $B1.4s + zip1 $T2.4s, $B2.4s, $B3.4s + zip2 $T3.4s, $B2.4s, $B3.4s + + zip1 $B0.2d, $T0.2d, $T2.2d + zip2 $B1.2d, $T0.2d, $T2.2d + zip1 $B2.2d, $T1.2d, $T3.2d + zip2 $B3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $C0.4s, $C1.4s + zip2 $T1.4s, $C0.4s, $C1.4s + zip1 $T2.4s, $C2.4s, $C3.4s + zip2 $T3.4s, $C2.4s, $C3.4s + + zip1 $C0.2d, $T0.2d, $T2.2d + zip2 $C1.2d, $T0.2d, $T2.2d + zip1 $C2.2d, $T1.2d, $T3.2d + zip2 $C3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $D0.4s, $D1.4s + zip2 $T1.4s, $D0.4s, $D1.4s + zip1 $T2.4s, $D2.4s, $D3.4s + zip2 $T3.4s, $D2.4s, $D3.4s + + zip1 $D0.2d, $T0.2d, $T2.2d + zip2 $D1.2d, $T0.2d, $T2.2d + zip1 $D2.2d, $T1.2d, $T3.2d + zip2 $D3.2d, $T1.2d, $T3.2d + + add $A0.4s, $A0.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + + add $A1.4s, $A1.4s, $CONSTS.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + add $D1.4s, $D1.4s, $D_STORE.4s + + add $A2.4s, $A2.4s, $CONSTS.4s + add $B2.4s, $B2.4s, $B_STORE.4s + add $C2.4s, $C2.4s, $C_STORE.4s + add $D2.4s, $D2.4s, $D_STORE.4s + + add $A3.4s, $A3.4s, $CONSTS.4s + add $B3.4s, $B3.4s, $B_STORE.4s + add $C3.4s, $C3.4s, $C_STORE.4s + add $D3.4s, $D3.4s, $D_STORE.4s + + add $A4.4s, $A4.4s, $CONSTS.4s + add $B4.4s, $B4.4s, $B_STORE.4s + add $C4.4s, $C4.4s, $C_STORE.4s + add $D4.4s, $D4.4s, $D_STORE.4s + + cmp $inl, #320 + b.le .Lseal_tail + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A0.16b + eor $T1.16b, $T1.16b, $B0.16b + eor $T2.16b, $T2.16b, $C0.16b + eor $T3.16b, $T3.16b, $D0.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A1.16b + eor $T1.16b, $T1.16b, $B1.16b + eor $T2.16b, $T2.16b, $C1.16b + eor $T3.16b, $T3.16b, $D1.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A2.16b + eor $T1.16b, $T1.16b, $B2.16b + eor $T2.16b, $T2.16b, $C2.16b + eor $T3.16b, $T3.16b, $D2.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A3.16b + eor $T1.16b, $T1.16b, $B3.16b + eor $T2.16b, $T2.16b, $C3.16b + eor $T3.16b, $T3.16b, $D3.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A4.16b + eor $T1.16b, $T1.16b, $B4.16b + eor $T2.16b, $T2.16b, $C4.16b + eor $T3.16b, $T3.16b, $D4.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #320 + + mov $itr1, #0 + mov $itr2, #10 // For the remainder of the loop we always hash and encrypt 320 bytes per iteration + + b .Lseal_main_loop + +.Lseal_tail: + // This part of the function handles the storage and authentication of the last [0,320) bytes + // We assume A0-A4 ... D0-D4 hold at least inl (320 max) bytes of the stream data. + cmp $inl, #64 + b.lt .Lseal_tail_64 + + // Store and authenticate 64B blocks per iteration + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + + eor $T0.16b, $T0.16b, $A0.16b + eor $T1.16b, $T1.16b, $B0.16b + eor $T2.16b, $T2.16b, $C0.16b + eor $T3.16b, $T3.16b, $D0.16b +___ + &poly_add_vec($T0); + &poly_mul(); + &poly_add_vec($T1); + &poly_mul(); + &poly_add_vec($T2); + &poly_mul(); + &poly_add_vec($T3); + &poly_mul(); +$code.=<<___; + st1 {$T0.16b - $T3.16b}, [$oup], #64 + sub $inl, $inl, #64 + + // Shift the state left by 64 bytes for the next iteration of the loop + mov $A0.16b, $A1.16b + mov $B0.16b, $B1.16b + mov $C0.16b, $C1.16b + mov $D0.16b, $D1.16b + + mov $A1.16b, $A2.16b + mov $B1.16b, $B2.16b + mov $C1.16b, $C2.16b + mov $D1.16b, $D2.16b + + mov $A2.16b, $A3.16b + mov $B2.16b, $B3.16b + mov $C2.16b, $C3.16b + mov $D2.16b, $D3.16b + + mov $A3.16b, $A4.16b + mov $B3.16b, $B4.16b + mov $C3.16b, $C4.16b + mov $D3.16b, $D4.16b + + b .Lseal_tail + +.Lseal_tail_64: + ldp $adp, $adl, [$keyp, #48] // extra_in_len and extra_in_ptr + + // Here we handle the last [0,64) bytes of plaintext + cmp $inl, #16 + b.lt .Lseal_tail_16 + // Each iteration encrypt and authenticate a 16B block + ld1 {$T0.16b}, [$inp], #16 + eor $T0.16b, $T0.16b, $A0.16b +___ + &poly_add_vec($T0); + &poly_mul(); +$code.=<<___; + st1 {$T0.16b}, [$oup], #16 + + sub $inl, $inl, #16 + + // Shift the state left by 16 bytes for the next iteration of the loop + mov $A0.16b, $B0.16b + mov $B0.16b, $C0.16b + mov $C0.16b, $D0.16b + + b .Lseal_tail_64 + +.Lseal_tail_16: + // Here we handle the last [0,16) bytes of ciphertext that require a padded block + cbz $inl, .Lseal_hash_extra + + eor $T0.16b, $T0.16b, $T0.16b // Use T0 to load the plaintext/extra in + eor $T1.16b, $T1.16b, $T1.16b // Use T1 to generate an AND mask that will only mask the ciphertext bytes + not $T2.16b, $T0.16b + + mov $itr1, $inl + add $inp, $inp, $inl + + cbz $adl, .Lseal_tail_16_compose // No extra data to pad with, zero padding + + mov $itr2, #16 // We need to load some extra_in first for padding + sub $itr2, $itr2, $inl + cmp $adl, $itr2 + csel $itr2, $adl, $itr2, lt // Load the minimum of extra_in_len and the amount needed to fill the register + mov $t1, $itr2 + add $adp, $adp, $itr2 + sub $adl, $adl, $itr2 + +.Lseal_tail16_compose_extra_in: + ext $T0.16b, $T0.16b, $T0.16b, #15 + ldrb $t0w, [$adp, #-1]! + mov $T0.b[0], $t0w + subs $itr2, $itr2, #1 + b.gt .Lseal_tail16_compose_extra_in + + add $adp, $adp, $t1 + +.Lseal_tail_16_compose: + ext $T0.16b, $T0.16b, $T0.16b, #15 + ldrb $t0w, [$inp, #-1]! + mov $T0.b[0], $t0w + ext $T1.16b, $T2.16b, $T1.16b, #15 + subs $inl, $inl, #1 + b.gt .Lseal_tail_16_compose + + and $A0.16b, $A0.16b, $T1.16b + eor $T0.16b, $T0.16b, $A0.16b + mov $T1.16b, $T0.16b + +.Lseal_tail_16_store: + umov $t0w, $T0.b[0] + strb $t0w, [$oup], #1 + ext $T0.16b, $T0.16b, $T0.16b, #1 + subs $itr1, $itr1, #1 + b.gt .Lseal_tail_16_store + + // Hash in the final ct block concatenated with extra_in +___ + &poly_add_vec($T1); + &poly_mul(); +$code.=<<___; + +.Lseal_hash_extra: + cbz $adl, .Lseal_finalize + +.Lseal_hash_extra_loop: + cmp $adl, #16 + b.lt .Lseal_hash_extra_tail + ld1 {$T0.16b}, [$adp], #16 +___ + &poly_add_vec($T0); + &poly_mul(); +$code.=<<___; + sub $adl, $adl, #16 + b .Lseal_hash_extra_loop + +.Lseal_hash_extra_tail: + cbz $adl, .Lseal_finalize + eor $T0.16b, $T0.16b, $T0.16b // Use T0 to load the remaining extra ciphertext + add $adp, $adp, $adl + +.Lseal_hash_extra_load: + ext $T0.16b, $T0.16b, $T0.16b, #15 + ldrb $t0w, [$adp, #-1]! + mov $T0.b[0], $t0w + subs $adl, $adl, #1 + b.gt .Lseal_hash_extra_load + + // Hash in the final padded extra_in blcok +___ + &poly_add_vec($T0); + &poly_mul(); +$code.=<<___; + +.Lseal_finalize: +___ + &poly_add_vec($LEN_STORE); + &poly_mul(); +$code.=<<___; + // Final reduction step + sub $t1, xzr, $one + orr $t2, xzr, #3 + subs $t0, $acc0, #-5 + sbcs $t1, $acc1, $t1 + sbcs $t2, $acc2, $t2 + csel $acc0, $t0, $acc0, cs + csel $acc1, $t1, $acc1, cs + csel $acc2, $t2, $acc2, cs +___ + &poly_add_vec($S_STORE); +$code.=<<___; + + stp $acc0, $acc1, [$keyp] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.Lseal_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor $INC.16b, $INC.16b, $INC.16b + mov $t0, #1 + mov $INC.s[0], $t0w + mov $A0.16b, $CONSTS.16b + mov $A1.16b, $CONSTS.16b + mov $A2.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $B1.16b, $B_STORE.16b + mov $B2.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $C1.16b, $C_STORE.16b + mov $C2.16b, $C_STORE.16b + mov $D2.16b, $D_STORE.16b + add $D0.4s, $D2.4s, $INC.4s + add $D1.4s, $D0.4s, $INC.4s + + mov $itr1, #10 + +.Lseal_128_rounds: +___ + &chacha_qr_x3("left"); + &chacha_qr_x3("right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.hi .Lseal_128_rounds + + add $A0.4s, $A0.4s, $CONSTS.4s + add $A1.4s, $A1.4s, $CONSTS.4s + add $A2.4s, $A2.4s, $CONSTS.4s + + add $B0.4s, $B0.4s, $B_STORE.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $B2.4s, $B2.4s, $B_STORE.4s + + // Only the first 32 bytes of the third block (counter = 0) are needed, + // so skip updating $C2 and $D2. + add $C0.4s, $C0.4s, $C_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + + add $D_STORE.4s, $D_STORE.4s, $INC.4s + add $D0.4s, $D0.4s, $D_STORE.4s + add $D_STORE.4s, $D_STORE.4s, $INC.4s + add $D1.4s, $D1.4s, $D_STORE.4s + + and $A2.16b, $A2.16b, $CLAMP.16b + mov $r0, $A2.d[0] // Move the R key to GPRs + mov $r1, $A2.d[1] + mov $S_STORE.16b, $B2.16b // Store the S key + + bl .Lpoly_hash_ad_internal + b .Lseal_tail +.cfi_endproc +.size chacha20_poly1305_seal,.-chacha20_poly1305_seal + +///////////////////////////////// +// +// void chacha20_poly1305_open(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *aead_data); +// +.globl chacha20_poly1305_open +.type chacha20_poly1305_open,%function +.align 6 +chacha20_poly1305_open: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp $t0, :pg_hi21:.Lchacha20_consts + add $t0, $t0, :lo12:.Lchacha20_consts + + ld1 {$CONSTS.16b - $CLAMP.16b}, [$t0] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {$B_STORE.16b - $D_STORE.16b}, [$keyp] + + mov $one, #1 // Prepare the Poly1305 state + mov $acc0, #0 + mov $acc1, #0 + mov $acc2, #0 + + mov $LEN_STORE.d[0], $adl // Store the input and aad lengths + mov $LEN_STORE.d[1], $inl + + cmp $inl, #128 + b.le .Lopen_128 // Optimization for smaller buffers + + // Initially we prepare a single ChaCha20 block for the Poly1305 R and S keys + mov $A0.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $D0.16b, $D_STORE.16b + + mov $itr1, #10 + +.align 5 +.Lopen_init_rounds: +___ + &chacha_qr($A0, $B0, $C0, $D0, $T0, "left"); + &chacha_qr($A0, $B0, $C0, $D0, $T0, "right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.hi .Lopen_init_rounds + + add $A0.4s, $A0.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + + and $A0.16b, $A0.16b, $CLAMP.16b + mov $r0, $A0.d[0] // Move the R key to GPRs + mov $r1, $A0.d[1] + mov $S_STORE.16b, $B0.16b // Store the S key + + bl .Lpoly_hash_ad_internal + +.Lopen_ad_done: + mov $adp, $inp + +// Each iteration of the loop hash 320 bytes, and prepare stream for 320 bytes +.Lopen_main_loop: + + cmp $inl, #192 + b.lt .Lopen_tail + + adrp $t0, :pg_hi21:.Lchacha20_consts + add $t0, $t0, :lo12:.Lchacha20_consts + + ld4r {$A0.4s-$A3.4s}, [$t0] + mov $A4.16b, $CONSTS.16b + + ld4r {$B0.4s-$B3.4s}, [$keyp], #16 + mov $B4.16b, $B_STORE.16b + + ld4r {$C0.4s-$C3.4s}, [$keyp], #16 + mov $C4.16b, $C_STORE.16b + + ld4r {$D0.4s-$D3.4s}, [$keyp] + sub $keyp, $keyp, #32 + add $D0.4s, $D0.4s, $INC.4s + mov $D4.16b, $D_STORE.16b + + eor $T0.16b, $T0.16b, $T0.16b //zero + not $T1.16b, $T0.16b // -1 + sub $T1.4s, $INC.4s, $T1.4s // Add +1 + ext $T0.16b, $T1.16b, $T0.16b, #12 // Get the last element (counter) + add $D4.4s, $D4.4s, $T0.4s + + lsr $adl, $inl, #4 // How many whole blocks we have to hash, will always be at least 12 + sub $adl, $adl, #10 + + mov $itr2, #10 + subs $itr1, $itr2, $adl + subs $itr1, $itr2, $adl // itr1 can be negative if we have more than 320 bytes to hash + csel $itr2, $itr2, $adl, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are full + + cbz $itr2, .Lopen_main_loop_rounds_short + +.align 5 +.Lopen_main_loop_rounds: +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; +.Lopen_main_loop_rounds_short: +___ + &chacha_qr_x5("left"); + &poly_add($adp); + &poly_mul(); + &chacha_qr_x5("right"); +$code.=<<___; + subs $itr2, $itr2, #1 + b.gt .Lopen_main_loop_rounds + subs $itr1, $itr1, #1 + b.ge .Lopen_main_loop_rounds_short +___ +$code.=<<___; + + eor $T0.16b, $T0.16b, $T0.16b //zero + not $T1.16b, $T0.16b // -1 + sub $T1.4s, $INC.4s, $T1.4s // Add +1 + ext $T0.16b, $T1.16b, $T0.16b, #12 // Get the last element (counter) + add $D4.4s, $D4.4s, $T0.4s + + add $D0.4s, $D0.4s, $INC.4s + mov $t0, #5 + dup $T0.4s, $t0w + add $INC.4s, $INC.4s, $T0.4s + + zip1 $T0.4s, $A0.4s, $A1.4s + zip2 $T1.4s, $A0.4s, $A1.4s + zip1 $T2.4s, $A2.4s, $A3.4s + zip2 $T3.4s, $A2.4s, $A3.4s + + zip1 $A0.2d, $T0.2d, $T2.2d + zip2 $A1.2d, $T0.2d, $T2.2d + zip1 $A2.2d, $T1.2d, $T3.2d + zip2 $A3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $B0.4s, $B1.4s + zip2 $T1.4s, $B0.4s, $B1.4s + zip1 $T2.4s, $B2.4s, $B3.4s + zip2 $T3.4s, $B2.4s, $B3.4s + + zip1 $B0.2d, $T0.2d, $T2.2d + zip2 $B1.2d, $T0.2d, $T2.2d + zip1 $B2.2d, $T1.2d, $T3.2d + zip2 $B3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $C0.4s, $C1.4s + zip2 $T1.4s, $C0.4s, $C1.4s + zip1 $T2.4s, $C2.4s, $C3.4s + zip2 $T3.4s, $C2.4s, $C3.4s + + zip1 $C0.2d, $T0.2d, $T2.2d + zip2 $C1.2d, $T0.2d, $T2.2d + zip1 $C2.2d, $T1.2d, $T3.2d + zip2 $C3.2d, $T1.2d, $T3.2d + + zip1 $T0.4s, $D0.4s, $D1.4s + zip2 $T1.4s, $D0.4s, $D1.4s + zip1 $T2.4s, $D2.4s, $D3.4s + zip2 $T3.4s, $D2.4s, $D3.4s + + zip1 $D0.2d, $T0.2d, $T2.2d + zip2 $D1.2d, $T0.2d, $T2.2d + zip1 $D2.2d, $T1.2d, $T3.2d + zip2 $D3.2d, $T1.2d, $T3.2d + + add $A0.4s, $A0.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + + add $A1.4s, $A1.4s, $CONSTS.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + add $D1.4s, $D1.4s, $D_STORE.4s + + add $A2.4s, $A2.4s, $CONSTS.4s + add $B2.4s, $B2.4s, $B_STORE.4s + add $C2.4s, $C2.4s, $C_STORE.4s + add $D2.4s, $D2.4s, $D_STORE.4s + + add $A3.4s, $A3.4s, $CONSTS.4s + add $B3.4s, $B3.4s, $B_STORE.4s + add $C3.4s, $C3.4s, $C_STORE.4s + add $D3.4s, $D3.4s, $D_STORE.4s + + add $A4.4s, $A4.4s, $CONSTS.4s + add $B4.4s, $B4.4s, $B_STORE.4s + add $C4.4s, $C4.4s, $C_STORE.4s + add $D4.4s, $D4.4s, $D_STORE.4s + + // We can always safely store 192 bytes + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A0.16b + eor $T1.16b, $T1.16b, $B0.16b + eor $T2.16b, $T2.16b, $C0.16b + eor $T3.16b, $T3.16b, $D0.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A1.16b + eor $T1.16b, $T1.16b, $B1.16b + eor $T2.16b, $T2.16b, $C1.16b + eor $T3.16b, $T3.16b, $D1.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A2.16b + eor $T1.16b, $T1.16b, $B2.16b + eor $T2.16b, $T2.16b, $C2.16b + eor $T3.16b, $T3.16b, $D2.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #192 + + mov $A0.16b, $A3.16b + mov $B0.16b, $B3.16b + mov $C0.16b, $C3.16b + mov $D0.16b, $D3.16b + + cmp $inl, #64 + b.lt .Lopen_tail_64_store + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A3.16b + eor $T1.16b, $T1.16b, $B3.16b + eor $T2.16b, $T2.16b, $C3.16b + eor $T3.16b, $T3.16b, $D3.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #64 + + mov $A0.16b, $A4.16b + mov $B0.16b, $B4.16b + mov $C0.16b, $C4.16b + mov $D0.16b, $D4.16b + + cmp $inl, #64 + b.lt .Lopen_tail_64_store + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + eor $T0.16b, $T0.16b, $A4.16b + eor $T1.16b, $T1.16b, $B4.16b + eor $T2.16b, $T2.16b, $C4.16b + eor $T3.16b, $T3.16b, $D4.16b + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #64 + b .Lopen_main_loop + +.Lopen_tail: + + cbz $inl, .Lopen_finalize + + lsr $adl, $inl, #4 // How many whole blocks we have to hash + + cmp $inl, #64 + b.le .Lopen_tail_64 + cmp $inl, #128 + b.le .Lopen_tail_128 + +.Lopen_tail_192: + // We need three more blocks + mov $A0.16b, $CONSTS.16b + mov $A1.16b, $CONSTS.16b + mov $A2.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $B1.16b, $B_STORE.16b + mov $B2.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $C1.16b, $C_STORE.16b + mov $C2.16b, $C_STORE.16b + mov $D0.16b, $D_STORE.16b + mov $D1.16b, $D_STORE.16b + mov $D2.16b, $D_STORE.16b + eor $T3.16b, $T3.16b, $T3.16b + eor $T1.16b, $T1.16b, $T1.16b + ins $T3.s[0], $INC.s[0] + ins $T1.d[0], $one + + add $T2.4s, $T3.4s, $T1.4s + add $T1.4s, $T2.4s, $T1.4s + + add $D0.4s, $D0.4s, $T1.4s + add $D1.4s, $D1.4s, $T3.4s + add $D2.4s, $D2.4s, $T2.4s + + mov $itr2, #10 + subs $itr1, $itr2, $adl // itr1 can be negative if we have more than 160 bytes to hash + csel $itr2, $itr2, $adl, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are hashing + sub $adl, $adl, $itr2 + + cbz $itr2, .Lopen_tail_192_rounds_no_hash + +.Lopen_tail_192_rounds: +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; +.Lopen_tail_192_rounds_no_hash: +___ + &chacha_qr_x3("left"); + &chacha_qr_x3("right"); +$code.=<<___; + subs $itr2, $itr2, #1 + b.gt .Lopen_tail_192_rounds + subs $itr1, $itr1, #1 + b.ge .Lopen_tail_192_rounds_no_hash + + // We hashed 160 bytes at most, may still have 32 bytes left +.Lopen_tail_192_hash: + cbz $adl, .Lopen_tail_192_hash_done +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + sub $adl, $adl, #1 + b .Lopen_tail_192_hash + +.Lopen_tail_192_hash_done: + + add $A0.4s, $A0.4s, $CONSTS.4s + add $A1.4s, $A1.4s, $CONSTS.4s + add $A2.4s, $A2.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $B2.4s, $B2.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + add $C2.4s, $C2.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + add $D1.4s, $D1.4s, $D_STORE.4s + add $D2.4s, $D2.4s, $D_STORE.4s + + add $D0.4s, $D0.4s, $T1.4s + add $D1.4s, $D1.4s, $T3.4s + add $D2.4s, $D2.4s, $T2.4s + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + + eor $T0.16b, $T0.16b, $A1.16b + eor $T1.16b, $T1.16b, $B1.16b + eor $T2.16b, $T2.16b, $C1.16b + eor $T3.16b, $T3.16b, $D1.16b + + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + + eor $T0.16b, $T0.16b, $A2.16b + eor $T1.16b, $T1.16b, $B2.16b + eor $T2.16b, $T2.16b, $C2.16b + eor $T3.16b, $T3.16b, $D2.16b + + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #128 + b .Lopen_tail_64_store + +.Lopen_tail_128: + // We need two more blocks + mov $A0.16b, $CONSTS.16b + mov $A1.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $B1.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $C1.16b, $C_STORE.16b + mov $D0.16b, $D_STORE.16b + mov $D1.16b, $D_STORE.16b + eor $T3.16b, $T3.16b, $T3.16b + eor $T2.16b, $T2.16b, $T2.16b + ins $T3.s[0], $INC.s[0] + ins $T2.d[0], $one + add $T2.4s, $T2.4s, $T3.4s + + add $D0.4s, $D0.4s, $T2.4s + add $D1.4s, $D1.4s, $T3.4s + + mov $itr1, #10 + sub $itr1, $itr1, $adl + +.Lopen_tail_128_rounds: +___ + &chacha_qr($A0, $B0, $C0, $D0, $T0, "left"); + &chacha_qr($A1, $B1, $C1, $D1, $T0, "left"); + &chacha_qr($A0, $B0, $C0, $D0, $T0, "right"); + &chacha_qr($A1, $B1, $C1, $D1, $T0, "right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.gt .Lopen_tail_128_rounds + cbz $adl, .Lopen_tail_128_rounds_done + subs $adl, $adl, #1 +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + b .Lopen_tail_128_rounds + +.Lopen_tail_128_rounds_done: + add $A0.4s, $A0.4s, $CONSTS.4s + add $A1.4s, $A1.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + add $D1.4s, $D1.4s, $D_STORE.4s + add $D0.4s, $D0.4s, $T2.4s + add $D1.4s, $D1.4s, $T3.4s + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + + eor $T0.16b, $T0.16b, $A1.16b + eor $T1.16b, $T1.16b, $B1.16b + eor $T2.16b, $T2.16b, $C1.16b + eor $T3.16b, $T3.16b, $D1.16b + + st1 {$T0.16b - $T3.16b}, [$oup], #64 + sub $inl, $inl, #64 + + b .Lopen_tail_64_store + +.Lopen_tail_64: + // We just need a single block + mov $A0.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $D0.16b, $D_STORE.16b + eor $T3.16b, $T3.16b, $T3.16b + ins $T3.s[0], $INC.s[0] + add $D0.4s, $D0.4s, $T3.4s + + mov $itr1, #10 + sub $itr1, $itr1, $adl + +.Lopen_tail_64_rounds: +___ + &chacha_qr($A0, $B0, $C0, $D0, $T0, "left"); + &chacha_qr($A0, $B0, $C0, $D0, $T0, "right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.gt .Lopen_tail_64_rounds + cbz $adl, .Lopen_tail_64_rounds_done + subs $adl, $adl, #1 +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + b .Lopen_tail_64_rounds + +.Lopen_tail_64_rounds_done: + add $A0.4s, $A0.4s, $CONSTS.4s + add $B0.4s, $B0.4s, $B_STORE.4s + add $C0.4s, $C0.4s, $C_STORE.4s + add $D0.4s, $D0.4s, $D_STORE.4s + add $D0.4s, $D0.4s, $T3.4s + +.Lopen_tail_64_store: + cmp $inl, #16 + b.lt .Lopen_tail_16 + + ld1 {$T0.16b}, [$inp], #16 + eor $T0.16b, $T0.16b, $A0.16b + st1 {$T0.16b}, [$oup], #16 + mov $A0.16b, $B0.16b + mov $B0.16b, $C0.16b + mov $C0.16b, $D0.16b + sub $inl, $inl, #16 + b .Lopen_tail_64_store + +.Lopen_tail_16: + // Here we handle the last [0,16) bytes that require a padded block + cbz $inl, .Lopen_finalize + + eor $T0.16b, $T0.16b, $T0.16b // Use T0 to load the ciphertext + eor $T1.16b, $T1.16b, $T1.16b // Use T1 to generate an AND mask + not $T2.16b, $T0.16b + + add $itr2, $inp, $inl + mov $itr1, $inl + +.Lopen_tail_16_compose: + ext $T0.16b, $T0.16b, $T0.16b, #15 + ldrb $t0w, [$itr2, #-1]! + mov $T0.b[0], $t0w + ext $T1.16b, $T2.16b, $T1.16b, #15 + subs $inl, $inl, #1 + b.gt .Lopen_tail_16_compose + + and $T0.16b, $T0.16b, $T1.16b + // Hash in the final padded block +___ + &poly_add_vec($T0); + &poly_mul(); +$code.=<<___; + eor $T0.16b, $T0.16b, $A0.16b + +.Lopen_tail_16_store: + umov $t0w, $T0.b[0] + strb $t0w, [$oup], #1 + ext $T0.16b, $T0.16b, $T0.16b, #1 + subs $itr1, $itr1, #1 + b.gt .Lopen_tail_16_store + +.Lopen_finalize: +___ + &poly_add_vec($LEN_STORE); + &poly_mul(); +$code.=<<___; + // Final reduction step + sub $t1, xzr, $one + orr $t2, xzr, #3 + subs $t0, $acc0, #-5 + sbcs $t1, $acc1, $t1 + sbcs $t2, $acc2, $t2 + csel $acc0, $t0, $acc0, cs + csel $acc1, $t1, $acc1, cs + csel $acc2, $t2, $acc2, cs +___ + &poly_add_vec($S_STORE); +$code.=<<___; + + stp $acc0, $acc1, [$keyp] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.Lopen_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor $INC.16b, $INC.16b, $INC.16b + mov $t0, #1 + mov $INC.s[0], $t0w + mov $A0.16b, $CONSTS.16b + mov $A1.16b, $CONSTS.16b + mov $A2.16b, $CONSTS.16b + mov $B0.16b, $B_STORE.16b + mov $B1.16b, $B_STORE.16b + mov $B2.16b, $B_STORE.16b + mov $C0.16b, $C_STORE.16b + mov $C1.16b, $C_STORE.16b + mov $C2.16b, $C_STORE.16b + mov $D2.16b, $D_STORE.16b + add $D0.4s, $D2.4s, $INC.4s + add $D1.4s, $D0.4s, $INC.4s + + mov $itr1, #10 + +.Lopen_128_rounds: +___ + &chacha_qr_x3("left"); + &chacha_qr_x3("right"); +$code.=<<___; + subs $itr1, $itr1, #1 + b.hi .Lopen_128_rounds + + add $A0.4s, $A0.4s, $CONSTS.4s + add $A1.4s, $A1.4s, $CONSTS.4s + add $A2.4s, $A2.4s, $CONSTS.4s + + add $B0.4s, $B0.4s, $B_STORE.4s + add $B1.4s, $B1.4s, $B_STORE.4s + add $B2.4s, $B2.4s, $B_STORE.4s + + add $C0.4s, $C0.4s, $C_STORE.4s + add $C1.4s, $C1.4s, $C_STORE.4s + + add $D_STORE.4s, $D_STORE.4s, $INC.4s + add $D0.4s, $D0.4s, $D_STORE.4s + add $D_STORE.4s, $D_STORE.4s, $INC.4s + add $D1.4s, $D1.4s, $D_STORE.4s + + and $A2.16b, $A2.16b, $CLAMP.16b + mov $r0, $A2.d[0] // Move the R key to GPRs + mov $r1, $A2.d[1] + mov $S_STORE.16b, $B2.16b // Store the S key + + bl .Lpoly_hash_ad_internal + +.Lopen_128_store: + cmp $inl, #64 + b.lt .Lopen_128_store_64 + + ld1 {$T0.16b - $T3.16b}, [$inp], #64 + +___ + &poly_add_vec($T0); + &poly_mul(); + &poly_add_vec($T1); + &poly_mul(); + &poly_add_vec($T2); + &poly_mul(); + &poly_add_vec($T3); + &poly_mul(); +$code.=<<___; + + eor $T0.16b, $T0.16b, $A0.16b + eor $T1.16b, $T1.16b, $B0.16b + eor $T2.16b, $T2.16b, $C0.16b + eor $T3.16b, $T3.16b, $D0.16b + + st1 {$T0.16b - $T3.16b}, [$oup], #64 + + sub $inl, $inl, #64 + + mov $A0.16b, $A1.16b + mov $B0.16b, $B1.16b + mov $C0.16b, $C1.16b + mov $D0.16b, $D1.16b + +.Lopen_128_store_64: + + lsr $adl, $inl, #4 + mov $adp, $inp + +.Lopen_128_hash_64: + cbz $adl, .Lopen_tail_64_store +___ + &poly_add($adp); + &poly_mul(); +$code.=<<___; + sub $adl, $adl, #1 + b .Lopen_128_hash_64 +.cfi_endproc +.size chacha20_poly1305_open,.-chacha20_poly1305_open +___ +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + print $_,"\n"; +} +close STDOUT or die "error closing STDOUT"; diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl index b2067c78..f0430c3e 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl @@ -42,6 +42,7 @@ $code.=<<___; chacha20_poly1305_constants: +.section .rodata .align 64 .Lchacha20_consts: .byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' @@ -79,6 +80,7 @@ chacha20_poly1305_constants: .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +.text ___ my ($oup,$inp,$inl,$adp,$keyp,$itr1,$itr2,$adl)=("%rdi","%rsi","%rbx","%rcx","%r9","%rcx","%r8","%r8"); diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/cipher_test.cc b/third_party/boringssl/kit/src/crypto/cipher_extra/cipher_test.cc index ad939e24..6101ef96 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/cipher_test.cc +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/cipher_test.cc @@ -106,6 +106,8 @@ static const EVP_CIPHER *GetCipher(const std::string &name) { return EVP_aes_192_ctr(); } else if (name == "AES-192-ECB") { return EVP_aes_192_ecb(); + } else if (name == "AES-192-GCM") { + return EVP_aes_192_gcm(); } else if (name == "AES-192-OFB") { return EVP_aes_192_ofb(); } else if (name == "AES-256-CBC") { @@ -122,198 +124,341 @@ static const EVP_CIPHER *GetCipher(const std::string &name) { return nullptr; } -static bool DoCipher(EVP_CIPHER_CTX *ctx, std::vector *out, - bssl::Span in, size_t chunk, - bool in_place) { +enum class Operation { + // kBoth tests both encryption and decryption. + kBoth, + // kEncrypt tests encryption. The result of encryption should always + // successfully decrypt, so this should only be used if the test file has a + // matching decrypt-only vector. + kEncrypt, + // kDecrypt tests decryption. This should only be used if the test file has a + // matching encrypt-only input, or if multiple ciphertexts are valid for + // a given plaintext and this is a non-canonical ciphertext. + kDecrypt, + // kInvalidDecrypt tests decryption and expects it to fail, e.g. due to + // invalid tag or padding. + kInvalidDecrypt, +}; + +static const char *OperationToString(Operation op) { + switch (op) { + case Operation::kBoth: + return "Both"; + case Operation::kEncrypt: + return "Encrypt"; + case Operation::kDecrypt: + return "Decrypt"; + case Operation::kInvalidDecrypt: + return "InvalidDecrypt"; + } + abort(); +} + +// MaybeCopyCipherContext, if |copy| is true, replaces |*ctx| with a, hopefully +// equivalent, copy of it. +static bool MaybeCopyCipherContext(bool copy, + bssl::UniquePtr *ctx) { + if (!copy) { + return true; + } + bssl::UniquePtr ctx2(EVP_CIPHER_CTX_new()); + if (!ctx2 || !EVP_CIPHER_CTX_copy(ctx2.get(), ctx->get())) { + return false; + } + *ctx = std::move(ctx2); + return true; +} + +static void TestCipherAPI(const EVP_CIPHER *cipher, Operation op, bool padding, + bool copy, bool in_place, bool use_evp_cipher, + size_t chunk_size, bssl::Span key, + bssl::Span iv, + bssl::Span plaintext, + bssl::Span ciphertext, + bssl::Span aad, + bssl::Span tag) { + bool encrypt = op == Operation::kEncrypt; + bool is_custom_cipher = + EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER; + bssl::Span in = encrypt ? plaintext : ciphertext; + bssl::Span expected = encrypt ? ciphertext : plaintext; + bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE; + + // Some |EVP_CIPHER|s take a variable-length key, and need to first be + // configured with the key length, which requires configuring the cipher. + bssl::UniquePtr ctx(EVP_CIPHER_CTX_new()); + ASSERT_TRUE(ctx); + ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, /*engine=*/nullptr, + /*key=*/nullptr, /*iv=*/nullptr, + encrypt ? 1 : 0)); + ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size())); + if (!padding) { + ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0)); + } + + // Configure the key. + ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx)); + ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr, + /*engine=*/nullptr, key.data(), /*iv=*/nullptr, + /*enc=*/-1)); + + // Configure the IV to run the actual operation. Callers that wish to use a + // key for multiple, potentially concurrent, operations will likely copy at + // this point. The |EVP_CIPHER_CTX| API uses the same type to represent a + // pre-computed key schedule and a streaming operation. + ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx)); + if (is_aead) { + ASSERT_LE(iv.size(), size_t{INT_MAX}); + ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, + static_cast(iv.size()), 0)); + } else { + ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx.get())); + } + ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), /*cipher=*/nullptr, + /*engine=*/nullptr, + /*key=*/nullptr, iv.data(), /*enc=*/-1)); + + if (is_aead && !encrypt) { + ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_TAG, + tag.size(), + const_cast(tag.data()))); + } + + // Note: the deprecated |EVP_CIPHER|-based AEAD API is sensitive to whether + // parameters are NULL, so it is important to skip the |in| and |aad| + // |EVP_CipherUpdate| calls when empty. + while (!aad.empty()) { + size_t todo = + chunk_size == 0 ? aad.size() : std::min(aad.size(), chunk_size); + if (use_evp_cipher) { + // AEADs always use the "custom cipher" return value convention. Passing a + // null output pointer triggers the AAD logic. + ASSERT_TRUE(is_custom_cipher); + ASSERT_EQ(static_cast(todo), + EVP_Cipher(ctx.get(), nullptr, aad.data(), todo)); + } else { + int len; + ASSERT_TRUE(EVP_CipherUpdate(ctx.get(), nullptr, &len, aad.data(), todo)); + // Although it doesn't output anything, |EVP_CipherUpdate| should claim to + // output the input length. + EXPECT_EQ(len, static_cast(todo)); + } + aad = aad.subspan(todo); + } + + // Set up the output buffer. size_t max_out = in.size(); - if ((EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_NO_PADDING) == 0 && - EVP_CIPHER_CTX_encrypting(ctx)) { - unsigned block_size = EVP_CIPHER_CTX_block_size(ctx); + size_t block_size = EVP_CIPHER_CTX_block_size(ctx.get()); + if (block_size > 1 && + (EVP_CIPHER_CTX_flags(ctx.get()) & EVP_CIPH_NO_PADDING) == 0 && + EVP_CIPHER_CTX_encrypting(ctx.get())) { max_out += block_size - (max_out % block_size); } - out->resize(max_out); + std::vector result(max_out); if (in_place) { - std::copy(in.begin(), in.end(), out->begin()); - in = bssl::MakeConstSpan(out->data(), in.size()); + std::copy(in.begin(), in.end(), result.begin()); + in = bssl::MakeConstSpan(result).first(in.size()); } size_t total = 0; int len; while (!in.empty()) { - size_t todo = chunk == 0 ? in.size() : std::min(in.size(), chunk); + size_t todo = chunk_size == 0 ? in.size() : std::min(in.size(), chunk_size); EXPECT_LE(todo, static_cast(INT_MAX)); - if (!EVP_CipherUpdate(ctx, out->data() + total, &len, in.data(), - static_cast(todo))) { - return false; + ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx)); + if (use_evp_cipher) { + // |EVP_Cipher| sometimes returns the number of bytes written, or -1 on + // error, and sometimes 1 or 0, implicitly writing |in_len| bytes. + if (is_custom_cipher) { + len = EVP_Cipher(ctx.get(), result.data() + total, in.data(), todo); + } else { + ASSERT_EQ( + 1, EVP_Cipher(ctx.get(), result.data() + total, in.data(), todo)); + len = static_cast(todo); + } + } else { + ASSERT_TRUE(EVP_CipherUpdate(ctx.get(), result.data() + total, &len, + in.data(), static_cast(todo))); } - EXPECT_GE(len, 0); + ASSERT_GE(len, 0); total += static_cast(len); in = in.subspan(todo); } - if (!EVP_CipherFinal_ex(ctx, out->data() + total, &len)) { - return false; - } - EXPECT_GE(len, 0); - total += static_cast(len); - out->resize(total); - return true; -} - -static void TestOperation(FileTest *t, const EVP_CIPHER *cipher, bool encrypt, - bool copy, bool in_place, size_t chunk_size, - const std::vector &key, - const std::vector &iv, - const std::vector &plaintext, - const std::vector &ciphertext, - const std::vector &aad, - const std::vector &tag) { - const std::vector *in, *out; - if (encrypt) { - in = &plaintext; - out = &ciphertext; - } else { - in = &ciphertext; - out = &plaintext; - } - - bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE; - - bssl::ScopedEVP_CIPHER_CTX ctx1; - ASSERT_TRUE(EVP_CipherInit_ex(ctx1.get(), cipher, nullptr, nullptr, nullptr, - encrypt ? 1 : 0)); - if (t->HasAttribute("IV")) { - if (is_aead) { - ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx1.get(), EVP_CTRL_AEAD_SET_IVLEN, - iv.size(), 0)); + if (op == Operation::kInvalidDecrypt) { + if (use_evp_cipher) { + // Only the "custom cipher" return value convention can report failures. + // Passing all nulls should act like |EVP_CipherFinal_ex|. + ASSERT_TRUE(is_custom_cipher); + EXPECT_EQ(-1, EVP_Cipher(ctx.get(), nullptr, nullptr, 0)); } else { - ASSERT_EQ(iv.size(), EVP_CIPHER_CTX_iv_length(ctx1.get())); + // Invalid padding and invalid tags all appear as a failed + // |EVP_CipherFinal_ex|. + EXPECT_FALSE(EVP_CipherFinal_ex(ctx.get(), result.data() + total, &len)); + } + } else { + if (use_evp_cipher) { + if (is_custom_cipher) { + // Only the "custom cipher" convention has an |EVP_CipherFinal_ex| + // equivalent. + len = EVP_Cipher(ctx.get(), nullptr, nullptr, 0); + } else { + len = 0; + } + } else { + ASSERT_TRUE(EVP_CipherFinal_ex(ctx.get(), result.data() + total, &len)); + } + ASSERT_GE(len, 0); + total += static_cast(len); + result.resize(total); + EXPECT_EQ(Bytes(expected), Bytes(result)); + if (encrypt && is_aead) { + uint8_t rtag[16]; + ASSERT_LE(tag.size(), sizeof(rtag)); + ASSERT_TRUE(MaybeCopyCipherContext(copy, &ctx)); + ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG, + tag.size(), rtag)); + EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size())); } } +} - bssl::ScopedEVP_CIPHER_CTX ctx2; - EVP_CIPHER_CTX *ctx = ctx1.get(); - if (copy) { - ASSERT_TRUE(EVP_CIPHER_CTX_copy(ctx2.get(), ctx1.get())); - ctx = ctx2.get(); +static void TestLowLevelAPI( + const EVP_CIPHER *cipher, Operation op, bool in_place, size_t chunk_size, + bssl::Span key, bssl::Span iv, + bssl::Span plaintext, bssl::Span ciphertext) { + bool encrypt = op == Operation::kEncrypt; + bssl::Span in = encrypt ? plaintext : ciphertext; + bssl::Span expected = encrypt ? ciphertext : plaintext; + int nid = EVP_CIPHER_nid(cipher); + bool is_ctr = nid == NID_aes_128_ctr || nid == NID_aes_192_ctr || + nid == NID_aes_256_ctr; + bool is_cbc = nid == NID_aes_128_cbc || nid == NID_aes_192_cbc || + nid == NID_aes_256_cbc; + bool is_ofb = nid == NID_aes_128_ofb128 || nid == NID_aes_192_ofb128 || + nid == NID_aes_256_ofb128; + if (!is_ctr && !is_cbc && !is_ofb) { + return; } - if (is_aead && !encrypt) { - ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag.size(), - const_cast(tag.data()))); + // Invalid ciphertexts are not possible in any of the ciphers where this API + // applies. + ASSERT_NE(op, Operation::kInvalidDecrypt); + + AES_KEY aes; + if (encrypt || !is_cbc) { + ASSERT_EQ(0, AES_set_encrypt_key(key.data(), key.size() * 8, &aes)); + } else { + ASSERT_EQ(0, AES_set_decrypt_key(key.data(), key.size() * 8, &aes)); } - // The ciphers are run with no padding. For each of the ciphers we test, the - // output size matches the input size. - ASSERT_EQ(in->size(), out->size()); - ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx, key.size())); - ASSERT_TRUE( - EVP_CipherInit_ex(ctx, nullptr, nullptr, key.data(), iv.data(), -1)); - // Note: the deprecated |EVP_CIPHER|-based AEAD API is sensitive to whether - // parameters are NULL, so it is important to skip the |in| and |aad| - // |EVP_CipherUpdate| calls when empty. - if (!aad.empty()) { - int unused; - ASSERT_TRUE( - EVP_CipherUpdate(ctx, nullptr, &unused, aad.data(), aad.size())); - } - ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx, 0)); + std::vector result; - ASSERT_TRUE(DoCipher(ctx, &result, *in, chunk_size, in_place)); - EXPECT_EQ(Bytes(*out), Bytes(result)); - if (encrypt && is_aead) { - uint8_t rtag[16]; - ASSERT_LE(tag.size(), sizeof(rtag)); - ASSERT_TRUE( - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag.size(), rtag)); - EXPECT_EQ(Bytes(tag), Bytes(rtag, tag.size())); + if (in_place) { + result.assign(in.begin(), in.end()); + } else { + result.resize(expected.size()); } + bssl::Span out = bssl::MakeSpan(result); + // Input and output sizes for all the low-level APIs should match. + ASSERT_EQ(in.size(), out.size()); - // Additionally test low-level AES mode APIs. Skip runs where |copy| because - // it does not apply. - if (!copy) { - int nid = EVP_CIPHER_nid(cipher); - bool is_ctr = nid == NID_aes_128_ctr || nid == NID_aes_192_ctr || - nid == NID_aes_256_ctr; - bool is_cbc = nid == NID_aes_128_cbc || nid == NID_aes_192_cbc || - nid == NID_aes_256_cbc; - bool is_ofb = nid == NID_aes_128_ofb128 || nid == NID_aes_192_ofb128 || - nid == NID_aes_256_ofb128; - if (is_ctr || is_cbc || is_ofb) { - AES_KEY aes; - if (encrypt || !is_cbc) { - ASSERT_EQ(0, AES_set_encrypt_key(key.data(), key.size() * 8, &aes)); - } else { - ASSERT_EQ(0, AES_set_decrypt_key(key.data(), key.size() * 8, &aes)); + // The low-level APIs all use block-size IVs. + ASSERT_EQ(iv.size(), size_t{AES_BLOCK_SIZE}); + uint8_t ivec[AES_BLOCK_SIZE]; + OPENSSL_memcpy(ivec, iv.data(), iv.size()); + + if (is_ctr) { + unsigned num = 0; + uint8_t ecount_buf[AES_BLOCK_SIZE]; + if (chunk_size == 0) { + AES_ctr128_encrypt(in.data(), out.data(), in.size(), &aes, ivec, + ecount_buf, &num); + } else { + do { + size_t todo = std::min(in.size(), chunk_size); + AES_ctr128_encrypt(in.data(), out.data(), todo, &aes, ivec, ecount_buf, + &num); + in = in.subspan(todo); + out = out.subspan(todo); + } while (!in.empty()); + } + EXPECT_EQ(Bytes(expected), Bytes(result)); + } else if (is_cbc && chunk_size % AES_BLOCK_SIZE == 0) { + // Note |AES_cbc_encrypt| requires block-aligned chunks. + if (chunk_size == 0) { + AES_cbc_encrypt(in.data(), out.data(), in.size(), &aes, ivec, encrypt); + } else { + do { + size_t todo = std::min(in.size(), chunk_size); + AES_cbc_encrypt(in.data(), out.data(), todo, &aes, ivec, encrypt); + in = in.subspan(todo); + out = out.subspan(todo); + } while (!in.empty()); + } + EXPECT_EQ(Bytes(expected), Bytes(result)); + } else if (is_ofb) { + int num = 0; + if (chunk_size == 0) { + AES_ofb128_encrypt(in.data(), out.data(), in.size(), &aes, ivec, &num); + } else { + do { + size_t todo = std::min(in.size(), chunk_size); + AES_ofb128_encrypt(in.data(), out.data(), todo, &aes, ivec, &num); + in = in.subspan(todo); + out = out.subspan(todo); + } while (!in.empty()); + } + EXPECT_EQ(Bytes(expected), Bytes(result)); + } +} + +static void TestCipher(const EVP_CIPHER *cipher, Operation input_op, + bool padding, bssl::Span key, + bssl::Span iv, + bssl::Span plaintext, + bssl::Span ciphertext, + bssl::Span aad, + bssl::Span tag) { + size_t block_size = EVP_CIPHER_block_size(cipher); + std::vector ops; + if (input_op == Operation::kBoth) { + ops = {Operation::kEncrypt, Operation::kDecrypt}; + } else { + ops = {input_op}; + } + for (Operation op : ops) { + SCOPED_TRACE(OperationToString(op)); + // Zero indicates a single-shot API. + static const size_t kChunkSizes[] = {0, 1, 2, 5, 7, 8, 9, 15, 16, + 17, 31, 32, 33, 63, 64, 65, 512}; + for (size_t chunk_size : kChunkSizes) { + SCOPED_TRACE(chunk_size); + if (chunk_size > plaintext.size() && chunk_size > ciphertext.size() && + chunk_size > aad.size()) { + continue; } - - // The low-level APIs all work in-place. - bssl::Span input = *in; - result.clear(); - if (in_place) { - result = *in; - input = result; - } else { - result.resize(out->size()); - } - bssl::Span output = bssl::MakeSpan(result); - ASSERT_EQ(input.size(), output.size()); - - // The low-level APIs all use block-size IVs. - ASSERT_EQ(iv.size(), size_t{AES_BLOCK_SIZE}); - uint8_t ivec[AES_BLOCK_SIZE]; - OPENSSL_memcpy(ivec, iv.data(), iv.size()); - - if (is_ctr) { - unsigned num = 0; - uint8_t ecount_buf[AES_BLOCK_SIZE]; - if (chunk_size == 0) { - AES_ctr128_encrypt(input.data(), output.data(), input.size(), &aes, - ivec, ecount_buf, &num); - } else { - do { - size_t todo = std::min(input.size(), chunk_size); - AES_ctr128_encrypt(input.data(), output.data(), todo, &aes, ivec, - ecount_buf, &num); - input = input.subspan(todo); - output = output.subspan(todo); - } while (!input.empty()); + for (bool in_place : {false, true}) { + SCOPED_TRACE(in_place); + for (bool copy : {false, true}) { + SCOPED_TRACE(copy); + TestCipherAPI(cipher, op, padding, copy, in_place, + /*use_evp_cipher=*/false, chunk_size, key, iv, + plaintext, ciphertext, aad, tag); + if (!padding && chunk_size % block_size == 0) { + TestCipherAPI(cipher, op, padding, copy, in_place, + /*use_evp_cipher=*/true, chunk_size, key, iv, + plaintext, ciphertext, aad, tag); + } } - EXPECT_EQ(Bytes(*out), Bytes(result)); - } else if (is_cbc && chunk_size % AES_BLOCK_SIZE == 0) { - // Note |AES_cbc_encrypt| requires block-aligned chunks. - if (chunk_size == 0) { - AES_cbc_encrypt(input.data(), output.data(), input.size(), &aes, ivec, - encrypt); - } else { - do { - size_t todo = std::min(input.size(), chunk_size); - AES_cbc_encrypt(input.data(), output.data(), todo, &aes, ivec, - encrypt); - input = input.subspan(todo); - output = output.subspan(todo); - } while (!input.empty()); + if (!padding) { + TestLowLevelAPI(cipher, op, in_place, chunk_size, key, iv, plaintext, + ciphertext); } - EXPECT_EQ(Bytes(*out), Bytes(result)); - } else if (is_ofb) { - int num = 0; - if (chunk_size == 0) { - AES_ofb128_encrypt(input.data(), output.data(), input.size(), &aes, - ivec, &num); - } else { - do { - size_t todo = std::min(input.size(), chunk_size); - AES_ofb128_encrypt(input.data(), output.data(), todo, &aes, ivec, - &num); - input = input.subspan(todo); - output = output.subspan(todo); - } while (!input.empty()); - } - EXPECT_EQ(Bytes(*out), Bytes(result)); } } } } -static void TestCipher(FileTest *t) { +static void CipherFileTest(FileTest *t) { std::string cipher_str; ASSERT_TRUE(t->GetAttribute(&cipher_str, "Cipher")); const EVP_CIPHER *cipher = GetCipher(cipher_str); @@ -331,151 +476,104 @@ static void TestCipher(FileTest *t) { ASSERT_TRUE(t->GetBytes(&tag, "Tag")); } - enum { - kEncrypt, - kDecrypt, - kBoth, - } operation = kBoth; + Operation op = Operation::kBoth; if (t->HasAttribute("Operation")) { const std::string &str = t->GetAttributeOrDie("Operation"); - if (str == "ENCRYPT") { - operation = kEncrypt; - } else if (str == "DECRYPT") { - operation = kDecrypt; + if (str == "Encrypt" || str == "ENCRYPT") { + op = Operation::kEncrypt; + } else if (str == "Decrypt" || str == "DECRYPT") { + op = Operation::kDecrypt; + } else if (str == "InvalidDecrypt") { + op = Operation::kInvalidDecrypt; } else { FAIL() << "Unknown operation: " << str; } } - const std::vector chunk_sizes = {0, 1, 2, 5, 7, 8, 9, 15, 16, - 17, 31, 32, 33, 63, 64, 65, 512}; - - for (size_t chunk_size : chunk_sizes) { - SCOPED_TRACE(chunk_size); - for (bool copy : {false, true}) { - SCOPED_TRACE(copy); - for (bool in_place : {false, true}) { - SCOPED_TRACE(in_place); - // By default, both directions are run, unless overridden by the - // operation. - if (operation != kDecrypt) { - SCOPED_TRACE("encrypt"); - TestOperation(t, cipher, true /* encrypt */, copy, in_place, - chunk_size, key, iv, plaintext, ciphertext, aad, tag); - } - - if (operation != kEncrypt) { - SCOPED_TRACE("decrypt"); - TestOperation(t, cipher, false /* decrypt */, copy, in_place, - chunk_size, key, iv, plaintext, ciphertext, aad, tag); - } - } - } - } + TestCipher(cipher, op, /*padding=*/false, key, iv, plaintext, ciphertext, aad, + tag); } TEST(CipherTest, TestVectors) { - FileTestGTest("crypto/cipher_extra/test/cipher_tests.txt", TestCipher); + FileTestGTest("crypto/cipher_extra/test/cipher_tests.txt", CipherFileTest); } TEST(CipherTest, CAVP_AES_128_CBC) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_128_cbc.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_AES_128_CTR) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_128_ctr.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_AES_192_CBC) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_192_cbc.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_AES_192_CTR) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_192_ctr.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_AES_256_CBC) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_256_cbc.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_AES_256_CTR) { FileTestGTest("crypto/cipher_extra/test/nist_cavp/aes_256_ctr.txt", - TestCipher); + CipherFileTest); } TEST(CipherTest, CAVP_TDES_CBC) { - FileTestGTest("crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt", TestCipher); + FileTestGTest("crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt", + CipherFileTest); } TEST(CipherTest, CAVP_TDES_ECB) { - FileTestGTest("crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt", TestCipher); + FileTestGTest("crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt", + CipherFileTest); } TEST(CipherTest, WycheproofAESCBC) { - FileTestGTest( - "third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt", - [](FileTest *t) { - t->IgnoreInstruction("type"); - t->IgnoreInstruction("ivSize"); + FileTestGTest("third_party/wycheproof_testvectors/aes_cbc_pkcs5_test.txt", + [](FileTest *t) { + t->IgnoreInstruction("type"); + t->IgnoreInstruction("ivSize"); - std::string key_size; - ASSERT_TRUE(t->GetInstruction(&key_size, "keySize")); - const EVP_CIPHER *cipher; - switch (atoi(key_size.c_str())) { - case 128: - cipher = EVP_aes_128_cbc(); - break; - case 192: - cipher = EVP_aes_192_cbc(); - break; - case 256: - cipher = EVP_aes_256_cbc(); - break; - default: - FAIL() << "Unsupported key size: " << key_size; - } + std::string key_size; + ASSERT_TRUE(t->GetInstruction(&key_size, "keySize")); + const EVP_CIPHER *cipher; + switch (atoi(key_size.c_str())) { + case 128: + cipher = EVP_aes_128_cbc(); + break; + case 192: + cipher = EVP_aes_192_cbc(); + break; + case 256: + cipher = EVP_aes_256_cbc(); + break; + default: + FAIL() << "Unsupported key size: " << key_size; + } - std::vector key, iv, msg, ct; - ASSERT_TRUE(t->GetBytes(&key, "key")); - ASSERT_TRUE(t->GetBytes(&iv, "iv")); - ASSERT_TRUE(t->GetBytes(&msg, "msg")); - ASSERT_TRUE(t->GetBytes(&ct, "ct")); - ASSERT_EQ(EVP_CIPHER_key_length(cipher), key.size()); - ASSERT_EQ(EVP_CIPHER_iv_length(cipher), iv.size()); - WycheproofResult result; - ASSERT_TRUE(GetWycheproofResult(t, &result)); - - bssl::ScopedEVP_CIPHER_CTX ctx; - std::vector out; - const std::vector chunk_sizes = { - 0, 1, 2, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 512}; - for (size_t chunk : chunk_sizes) { - SCOPED_TRACE(chunk); - for (bool in_place : {false, true}) { - SCOPED_TRACE(in_place); - if (result.IsValid()) { - ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, - key.data(), iv.data())); - ASSERT_TRUE(DoCipher(ctx.get(), &out, ct, chunk, in_place)); - EXPECT_EQ(Bytes(msg), Bytes(out)); - - ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), cipher, nullptr, - key.data(), iv.data())); - ASSERT_TRUE(DoCipher(ctx.get(), &out, msg, chunk, in_place)); - EXPECT_EQ(Bytes(ct), Bytes(out)); - } else { - ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, - key.data(), iv.data())); - EXPECT_FALSE(DoCipher(ctx.get(), &out, ct, chunk, in_place)); - } - } - } - }); + std::vector key, iv, msg, ct; + ASSERT_TRUE(t->GetBytes(&key, "key")); + ASSERT_TRUE(t->GetBytes(&iv, "iv")); + ASSERT_TRUE(t->GetBytes(&msg, "msg")); + ASSERT_TRUE(t->GetBytes(&ct, "ct")); + WycheproofResult result; + ASSERT_TRUE(GetWycheproofResult(t, &result)); + TestCipher(cipher, + result.IsValid() ? Operation::kBoth + : Operation::kInvalidDecrypt, + /*padding=*/true, key, iv, msg, ct, /*aad=*/{}, + /*tag=*/{}); + }); } TEST(CipherTest, SHA1WithSecretSuffix) { @@ -525,6 +623,53 @@ TEST(CipherTest, SHA1WithSecretSuffix) { } } +TEST(CipherTest, SHA256WithSecretSuffix) { + uint8_t buf[SHA256_CBLOCK * 4]; + RAND_bytes(buf, sizeof(buf)); + // Hashing should run in time independent of the bytes. + CONSTTIME_SECRET(buf, sizeof(buf)); + + // Exhaustively testing interesting cases in this function is cubic in the + // block size, so we test in 3-byte increments. + constexpr size_t kSkip = 3; + // This value should be less than 8 to test the edge case when the 8-byte + // length wraps to the next block. + static_assert(kSkip < 8, "kSkip is too large"); + + // |EVP_sha256_final_with_secret_suffix| is sensitive to the public length of + // the partial block previously hashed. In TLS, this is the HMAC prefix, the + // header, and the public minimum padding length. + for (size_t prefix = 0; prefix < SHA256_CBLOCK; prefix += kSkip) { + SCOPED_TRACE(prefix); + // The first block is treated differently, so we run with up to three + // blocks of length variability. + for (size_t max_len = 0; max_len < 3 * SHA256_CBLOCK; max_len += kSkip) { + SCOPED_TRACE(max_len); + for (size_t len = 0; len <= max_len; len += kSkip) { + SCOPED_TRACE(len); + + uint8_t expected[SHA256_DIGEST_LENGTH]; + SHA256(buf, prefix + len, expected); + CONSTTIME_DECLASSIFY(expected, sizeof(expected)); + + // Make a copy of the secret length to avoid interfering with the loop. + size_t secret_len = len; + CONSTTIME_SECRET(&secret_len, sizeof(secret_len)); + + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, buf, prefix); + uint8_t computed[SHA256_DIGEST_LENGTH]; + ASSERT_TRUE(EVP_sha256_final_with_secret_suffix( + &ctx, computed, buf + prefix, secret_len, max_len)); + + CONSTTIME_DECLASSIFY(computed, sizeof(computed)); + EXPECT_EQ(Bytes(expected), Bytes(computed)); + } + } + } +} + TEST(CipherTest, GetCipher) { const EVP_CIPHER *cipher = EVP_get_cipherbynid(NID_aes_128_gcm); ASSERT_TRUE(cipher); diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/derive_key.c b/third_party/boringssl/kit/src/crypto/cipher_extra/derive_key.c index 45b49637..4b84c4eb 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/derive_key.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/derive_key.c @@ -69,12 +69,12 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, unsigned count, uint8_t *key, uint8_t *iv) { EVP_MD_CTX c; uint8_t md_buf[EVP_MAX_MD_SIZE]; - unsigned niv, nkey, addmd = 0; + unsigned addmd = 0; unsigned mds = 0, i; int rv = 0; - nkey = type->key_len; - niv = type->iv_len; + unsigned nkey = EVP_CIPHER_key_length(type); + unsigned niv = EVP_CIPHER_iv_length(type); assert(nkey <= EVP_MAX_KEY_LENGTH); assert(niv <= EVP_MAX_IV_LENGTH); @@ -143,7 +143,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, break; } } - rv = type->key_len; + rv = EVP_CIPHER_key_length(type); err: EVP_MD_CTX_cleanup(&c); diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesctrhmac.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesctrhmac.c index 8c45c811..32b42d2e 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesctrhmac.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesctrhmac.c @@ -13,6 +13,9 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include + +#include + #include #include #include @@ -35,14 +38,12 @@ struct aead_aes_ctr_hmac_sha256_ctx { SHA256_CTX outer_init_state; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_ctr_hmac_sha256_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_ctr_hmac_sha256_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_ctr_hmac_sha256_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_ctr_hmac_sha256_ctx), + "AEAD state has insufficient alignment"); static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer, const uint8_t hmac_key[32]) { diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesgcmsiv.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesgcmsiv.c index d7175723..15601e19 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesgcmsiv.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesgcmsiv.c @@ -17,11 +17,11 @@ #include #include -#include #include #include #include "../fipsmodule/cipher/internal.h" +#include "../internal.h" #define EVP_AEAD_AES_GCM_SIV_NONCE_LEN 12 @@ -42,13 +42,11 @@ struct aead_aes_gcm_siv_asm_ctx { // The assembly code assumes 8-byte alignment of the EVP_AEAD_CTX's state, and // aligns to 16 bytes itself. -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) + 8 >= - sizeof(struct aead_aes_gcm_siv_asm_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= 8, - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) + 8 >= + sizeof(struct aead_aes_gcm_siv_asm_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= 8, + "AEAD state has insufficient alignment"); // asm_ctx_from_ctx returns a 16-byte aligned context pointer from |ctx|. static struct aead_aes_gcm_siv_asm_ctx *asm_ctx_from_ctx( @@ -262,17 +260,10 @@ static void gcm_siv_asm_polyval(uint8_t out_tag[16], const uint8_t *in, aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); } - union { - uint8_t c[16]; - struct { - uint64_t ad; - uint64_t in; - } bitlens; - } length_block; - - length_block.bitlens.ad = ad_len * 8; - length_block.bitlens.in = in_len * 8; - aesgcmsiv_polyval_horner(out_tag, auth_key, length_block.c, 1); + uint8_t length_block[16]; + CRYPTO_store_u64_le(length_block, ad_len * 8); + CRYPTO_store_u64_le(length_block + 8, in_len * 8); + aesgcmsiv_polyval_horner(out_tag, auth_key, length_block, 1); for (size_t i = 0; i < 12; i++) { out_tag[i] ^= nonce[i]; @@ -289,18 +280,15 @@ static void aead_aes_gcm_siv_asm_crypt_last_block( int is_128_bit, uint8_t *out, const uint8_t *in, size_t in_len, const uint8_t tag[16], const struct aead_aes_gcm_siv_asm_ctx *enc_key_expanded) { - alignas(16) union { - uint8_t c[16]; - uint32_t u32[4]; - } counter; + alignas(16) uint8_t counter[16]; OPENSSL_memcpy(&counter, tag, sizeof(counter)); - counter.c[15] |= 0x80; - counter.u32[0] += in_len / 16; + counter[15] |= 0x80; + CRYPTO_store_u32_le(counter, CRYPTO_load_u32_le(counter) + in_len / 16); if (is_128_bit) { - aes128gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + aes128gcmsiv_ecb_enc_block(counter, counter, enc_key_expanded); } else { - aes256gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + aes256gcmsiv_ecb_enc_block(counter, counter, enc_key_expanded); } const size_t last_bytes_offset = in_len & ~15; @@ -308,7 +296,7 @@ static void aead_aes_gcm_siv_asm_crypt_last_block( uint8_t *last_bytes_out = &out[last_bytes_offset]; const uint8_t *last_bytes_in = &in[last_bytes_offset]; for (size_t i = 0; i < last_bytes_len; i++) { - last_bytes_out[i] = last_bytes_in[i] ^ counter.c[i]; + last_bytes_out[i] = last_bytes_in[i] ^ counter[i]; } } @@ -489,18 +477,11 @@ static int aead_aes_gcm_siv_asm_open(const EVP_AEAD_CTX *ctx, uint8_t *out, scratch, 1); } - union { - uint8_t c[16]; - struct { - uint64_t ad; - uint64_t in; - } bitlens; - } length_block; - - length_block.bitlens.ad = ad_len * 8; - length_block.bitlens.in = plaintext_len * 8; + uint8_t length_block[16]; + CRYPTO_store_u64_le(length_block, ad_len * 8); + CRYPTO_store_u64_le(length_block + 8, plaintext_len * 8); aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, - length_block.c, 1); + length_block, 1); for (size_t i = 0; i < 12; i++) { calculated_tag[i] ^= nonce[i]; @@ -569,14 +550,12 @@ struct aead_aes_gcm_siv_ctx { unsigned is_256:1; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_gcm_siv_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_gcm_siv_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_siv_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_siv_ctx), + "AEAD state has insufficient alignment"); static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len) { @@ -619,18 +598,15 @@ static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) {} static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len, const uint8_t initial_counter[AES_BLOCK_SIZE], block128_f enc_block, const AES_KEY *key) { - union { - uint32_t w[4]; - uint8_t c[16]; - } counter; + uint8_t counter[16]; - OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE); - counter.c[15] |= 0x80; + OPENSSL_memcpy(counter, initial_counter, AES_BLOCK_SIZE); + counter[15] |= 0x80; for (size_t done = 0; done < in_len;) { uint8_t keystream[AES_BLOCK_SIZE]; - enc_block(counter.c, keystream, key); - counter.w[0]++; + enc_block(counter, keystream, key); + CRYPTO_store_u32_le(counter, CRYPTO_load_u32_le(counter) + 1); size_t todo = AES_BLOCK_SIZE; if (in_len - done < todo) { @@ -670,17 +646,10 @@ static void gcm_siv_polyval( CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); } - union { - uint8_t c[16]; - struct { - uint64_t ad; - uint64_t in; - } bitlens; - } length_block; - - length_block.bitlens.ad = ad_len * 8; - length_block.bitlens.in = in_len * 8; - CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c, + uint8_t length_block[16]; + CRYPTO_store_u64_le(length_block, ad_len * 8); + CRYPTO_store_u64_le(length_block + 8, in_len * 8); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block, sizeof(length_block)); CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag); @@ -857,22 +826,15 @@ static const EVP_AEAD aead_aes_256_gcm_siv = { #if defined(AES_GCM_SIV_ASM) -static char avx_aesni_capable(void) { - const uint32_t ecx = OPENSSL_ia32cap_P[1]; - - return (ecx & (1 << (57 - 32))) != 0 /* AESNI */ && - (ecx & (1 << 28)) != 0 /* AVX */; -} - const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { - if (avx_aesni_capable()) { + if (CRYPTO_is_AVX_capable() && CRYPTO_is_AESNI_capable()) { return &aead_aes_128_gcm_siv_asm; } return &aead_aes_128_gcm_siv; } const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { - if (avx_aesni_capable()) { + if (CRYPTO_is_AVX_capable() && CRYPTO_is_AESNI_capable()) { return &aead_aes_256_gcm_siv_asm; } return &aead_aes_256_gcm_siv; diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_chacha20poly1305.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_chacha20poly1305.c index 16501889..6510ff48 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_chacha20poly1305.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_chacha20poly1305.c @@ -14,6 +14,7 @@ #include +#include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include "internal.h" #include "../chacha/internal.h" @@ -32,14 +32,12 @@ struct aead_chacha20_poly1305_ctx { uint8_t key[32]; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_chacha20_poly1305_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_chacha20_poly1305_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_chacha20_poly1305_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_chacha20_poly1305_ctx), + "AEAD state has insufficient alignment"); static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len) { @@ -147,7 +145,7 @@ static int chacha20_poly1305_seal_scatter( // encrypted byte-by-byte first. if (extra_in_len) { static const size_t kChaChaBlockSize = 64; - uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + uint32_t block_counter = (uint32_t)(1 + (in_len / kChaChaBlockSize)); size_t offset = in_len % kChaChaBlockSize; uint8_t block[64 /* kChaChaBlockSize */]; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_des.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_des.c similarity index 63% rename from third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_des.c rename to third_party/boringssl/kit/src/crypto/cipher_extra/e_des.c index e77363b5..300ec00e 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_des.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_des.c @@ -58,8 +58,8 @@ #include #include +#include "../fipsmodule/cipher/internal.h" #include "internal.h" -#include "../delocate.h" typedef struct { @@ -88,17 +88,21 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, return 1; } -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_cbc) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_cbc; - out->block_size = 8; - out->key_len = 8; - out->iv_len = 8; - out->ctx_size = sizeof(EVP_DES_KEY); - out->flags = EVP_CIPH_CBC_MODE; - out->init = des_init_key; - out->cipher = des_cbc_cipher; -} +static const EVP_CIPHER evp_des_cbc = { + /* nid = */ NID_des_cbc, + /* block_size = */ 8, + /* key_len = */ 8, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(EVP_DES_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_init_key, + /* cipher = */ des_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_cbc(void) { return &evp_des_cbc; } static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { @@ -107,25 +111,29 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } in_len -= ctx->cipher->block_size; - EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { - DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), &dat->ks.ks, ctx->encrypt); } return 1; } -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ecb) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_ecb; - out->block_size = 8; - out->key_len = 8; - out->iv_len = 0; - out->ctx_size = sizeof(EVP_DES_KEY); - out->flags = EVP_CIPH_ECB_MODE; - out->init = des_init_key; - out->cipher = des_ecb_cipher; -} +static const EVP_CIPHER evp_des_ecb = { + /* nid = */ NID_des_ecb, + /* block_size = */ 8, + /* key_len = */ 8, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(EVP_DES_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_init_key, + /* cipher = */ des_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ecb(void) { return &evp_des_ecb; } typedef struct { union { @@ -137,7 +145,7 @@ typedef struct { static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { DES_cblock *deskey = (DES_cblock *)key; - DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; DES_set_key(&deskey[0], &dat->ks.ks[0]); DES_set_key(&deskey[1], &dat->ks.ks[1]); @@ -147,8 +155,8 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, } static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, - const uint8_t *in, size_t in_len) { - DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + const uint8_t *in, size_t in_len) { + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); @@ -156,22 +164,26 @@ static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, return 1; } -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3_cbc) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_ede3_cbc; - out->block_size = 8; - out->key_len = 24; - out->iv_len = 8; - out->ctx_size = sizeof(DES_EDE_KEY); - out->flags = EVP_CIPH_CBC_MODE; - out->init = des_ede3_init_key; - out->cipher = des_ede3_cbc_cipher; -} +static const EVP_CIPHER evp_des_ede3_cbc = { + /* nid = */ NID_des_ede3_cbc, + /* block_size = */ 8, + /* key_len = */ 24, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_ede3_init_key, + /* cipher = */ des_ede3_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &evp_des_ede3_cbc; } static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, - const uint8_t *iv, int enc) { - DES_cblock *deskey = (DES_cblock *) key; - DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; DES_set_key(&deskey[0], &dat->ks.ks[0]); DES_set_key(&deskey[1], &dat->ks.ks[1]); @@ -180,17 +192,21 @@ static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, return 1; } -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede_cbc) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_ede_cbc; - out->block_size = 8; - out->key_len = 16; - out->iv_len = 8; - out->ctx_size = sizeof(DES_EDE_KEY); - out->flags = EVP_CIPH_CBC_MODE; - out->init = des_ede_init_key; - out->cipher = des_ede3_cbc_cipher; -} +static const EVP_CIPHER evp_des_ede_cbc = { + /* nid = */ NID_des_ede_cbc, + /* block_size = */ 8, + /* key_len = */ 16, + /* iv_len = */ 8, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_CBC_MODE, + /* app_data = */ NULL, + /* init = */ des_ede_init_key, + /* cipher = */ des_ede3_cbc_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede_cbc(void) { return &evp_des_ede_cbc; } static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { @@ -208,30 +224,36 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, return 1; } -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_ede_ecb; - out->block_size = 8; - out->key_len = 16; - out->iv_len = 0; - out->ctx_size = sizeof(DES_EDE_KEY); - out->flags = EVP_CIPH_ECB_MODE; - out->init = des_ede_init_key; - out->cipher = des_ede_ecb_cipher; -} +static const EVP_CIPHER evp_des_ede = { + /* nid = */ NID_des_ede_ecb, + /* block_size = */ 8, + /* key_len = */ 16, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_ede_init_key, + /* cipher = */ des_ede_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; -DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3) { - memset(out, 0, sizeof(EVP_CIPHER)); - out->nid = NID_des_ede3_ecb; - out->block_size = 8; - out->key_len = 24; - out->iv_len = 0; - out->ctx_size = sizeof(DES_EDE_KEY); - out->flags = EVP_CIPH_ECB_MODE; - out->init = des_ede3_init_key; - out->cipher = des_ede_ecb_cipher; -} +const EVP_CIPHER *EVP_des_ede(void) { return &evp_des_ede; } -const EVP_CIPHER* EVP_des_ede3_ecb(void) { - return EVP_des_ede3(); -} +static const EVP_CIPHER evp_des_ede3 = { + /* nid = */ NID_des_ede3_ecb, + /* block_size = */ 8, + /* key_len = */ 24, + /* iv_len = */ 0, + /* ctx_size = */ sizeof(DES_EDE_KEY), + /* flags = */ EVP_CIPH_ECB_MODE, + /* app_data = */ NULL, + /* init = */ des_ede3_init_key, + /* cipher = */ des_ede_ecb_cipher, + /* cleanup = */ NULL, + /* ctrl = */ NULL, +}; + +const EVP_CIPHER *EVP_des_ede3(void) { return &evp_des_ede3; } + +const EVP_CIPHER *EVP_des_ede3_ecb(void) { return EVP_des_ede3(); } diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_null.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_null.c index f5fe8fb7..e9ee8adc 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_null.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_null.c @@ -60,6 +60,7 @@ #include +#include "../fipsmodule/cipher/internal.h" #include "../internal.h" diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc2.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc2.c index 221a9c92..ffc5e6b1 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc2.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc2.c @@ -57,6 +57,7 @@ #include #include +#include "../fipsmodule/cipher/internal.h" #include "../internal.h" diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc4.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc4.c index e7c2ccaf..2f4f9bba 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc4.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_rc4.c @@ -61,6 +61,8 @@ #include #include +#include "../fipsmodule/cipher/internal.h" + static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_tls.c b/third_party/boringssl/kit/src/crypto/cipher_extra/e_tls.c index 6d84f7f0..c462a2b3 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_tls.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/e_tls.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "../fipsmodule/cipher/internal.h" #include "../internal.h" @@ -42,17 +41,12 @@ typedef struct { char implicit_iv; } AEAD_TLS_CTX; -OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, - "mac_key_len does not fit in uint8_t"); +static_assert(EVP_MAX_MD_SIZE < 256, "mac_key_len does not fit in uint8_t"); -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(AEAD_TLS_CTX), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(AEAD_TLS_CTX), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= sizeof(AEAD_TLS_CTX), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= alignof(AEAD_TLS_CTX), + "AEAD state has insufficient alignment"); static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; @@ -406,6 +400,14 @@ static int aead_aes_128_cbc_sha1_tls_implicit_iv_init( EVP_sha1(), 1); } +static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha256(), 0); +} + static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, enum evp_aead_direction_t dir) { @@ -448,13 +450,6 @@ static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, return 1; } -static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, - size_t key_len, size_t tag_len, - enum evp_aead_direction_t dir) { - return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), - EVP_sha1(), 1 /* implicit iv */); -} - static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { SHA_DIGEST_LENGTH + 16, // key len (SHA1 + AES128) 16, // nonce len (IV) @@ -489,6 +484,23 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = { aead_tls_tag_len, }; +static const EVP_AEAD aead_aes_128_cbc_sha256_tls = { + SHA256_DIGEST_LENGTH + 16, // key len (SHA256 + AES128) + 16, // nonce len (IV) + 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256) + SHA256_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha256_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + static const EVP_AEAD aead_aes_256_cbc_sha1_tls = { SHA_DIGEST_LENGTH + 32, // key len (SHA1 + AES256) 16, // nonce len (IV) @@ -557,23 +569,6 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = { aead_tls_tag_len, }; -static const EVP_AEAD aead_null_sha1_tls = { - SHA_DIGEST_LENGTH, // key len - 0, // nonce len - SHA_DIGEST_LENGTH, // overhead (SHA1) - SHA_DIGEST_LENGTH, // max tag length - 0, // seal_scatter_supports_extra_in - - NULL, // init - aead_null_sha1_tls_init, - aead_tls_cleanup, - aead_tls_open, - aead_tls_seal_scatter, - NULL, // open_gather - NULL, // get_iv - aead_tls_tag_len, -}; - const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) { return &aead_aes_128_cbc_sha1_tls; } @@ -582,6 +577,10 @@ const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) { return &aead_aes_128_cbc_sha1_tls_implicit_iv; } +const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) { + return &aead_aes_128_cbc_sha256_tls; +} + const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) { return &aead_aes_256_cbc_sha1_tls; } @@ -597,5 +596,3 @@ const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) { const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) { return &aead_des_ede3_cbc_sha1_tls_implicit_iv; } - -const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; } diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/internal.h b/third_party/boringssl/kit/src/crypto/cipher_extra/internal.h index a2ec30b0..39ab950f 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/internal.h +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/internal.h @@ -57,11 +57,10 @@ #ifndef OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H #define OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H +#include #include #include -#include -#include #include "../internal.h" @@ -110,6 +109,14 @@ OPENSSL_EXPORT int EVP_sha1_final_with_secret_suffix( SHA_CTX *ctx, uint8_t out[SHA_DIGEST_LENGTH], const uint8_t *in, size_t len, size_t max_len); +// EVP_sha256_final_with_secret_suffix acts like +// |EVP_sha1_final_with_secret_suffix|, but for SHA-256. +// +// This function is exported for unit tests. +OPENSSL_EXPORT int EVP_sha256_final_with_secret_suffix( + SHA256_CTX *ctx, uint8_t out[SHA256_DIGEST_LENGTH], const uint8_t *in, + size_t len, size_t max_len); + // EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS // record. // @@ -164,19 +171,23 @@ union chacha20_poly1305_seal_data { } out; }; -#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) +#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_NO_ASM) -OPENSSL_STATIC_ASSERT(sizeof(union chacha20_poly1305_open_data) == 48, - "wrong chacha20_poly1305_open_data size"); -OPENSSL_STATIC_ASSERT(sizeof(union chacha20_poly1305_seal_data) == 48 + 8 + 8, - "wrong chacha20_poly1305_seal_data size"); +static_assert(sizeof(union chacha20_poly1305_open_data) == 48, + "wrong chacha20_poly1305_open_data size"); +static_assert(sizeof(union chacha20_poly1305_seal_data) == 48 + 8 + 8, + "wrong chacha20_poly1305_seal_data size"); OPENSSL_INLINE int chacha20_poly1305_asm_capable(void) { - const int sse41_capable = (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0; - return sse41_capable; +#if defined(OPENSSL_X86_64) + return CRYPTO_is_SSE4_1_capable(); +#elif defined(OPENSSL_AARCH64) + return CRYPTO_is_NEON_capable(); +#endif } -// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It decrypts +// chacha20_poly1305_open is defined in chacha20_poly1305_*.pl. It decrypts // |plaintext_len| bytes from |ciphertext| and writes them to |out_plaintext|. // Additional input parameters are passed in |aead_data->in|. On exit, it will // write calculated tag value to |aead_data->out.tag|, which the caller must @@ -187,7 +198,7 @@ extern void chacha20_poly1305_open(uint8_t *out_plaintext, size_t ad_len, union chacha20_poly1305_open_data *data); -// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It encrypts +// chacha20_poly1305_open is defined in chacha20_poly1305_*.pl. It encrypts // |plaintext_len| bytes from |plaintext| and writes them to |out_ciphertext|. // Additional input parameters are passed in |aead_data->in|. The calculated tag // value is over the computed ciphertext concatenated with |extra_ciphertext| diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt new file mode 100644 index 00000000..7cff4fb0 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt @@ -0,0 +1,92 @@ +# These test vectors were derived from those found in +# the Bluetooth Mesh Profile Specification v1.0. That document doesn't use +# 16-byte tags, so the tags have been updated here. Note that the first four or +# eight bytes of the tag is not equal to the tag from those vectors because CCM +# authenticates the expected tag length. + +KEY: 0953fa93e7caac9638f58820220a398e +NONCE: 00800000011201000012345678 +IN: fffd034b50057e400000010000 +AD: +CT: b5e5bfdacbaf6cb7fb6bff871f +TAG: b0d6dd827d35bf372fa6425dcd17d356 + +# Section 8.3.2 +KEY: 0953fa93e7caac9638f58820220a398e +NONCE: 00800148202345000012345678 +IN: 120104320308ba072f +AD: +CT: 79d7dbc0c9b4d43eeb +TAG: 281508e50d58dbbd27c39597800f4733 + +# Section 8.3.3. +KEY: 0953fa93e7caac9638f58820220a398e +NONCE: 00802b38322fe3000012345678 +IN: 120104fa0205a6000a +AD: +CT: 53273086b8c5ee00bd +TAG: d52b87a8ce6290a772d472b8c62bdc13 + +# Section 8.3.4. +KEY: be635105434859f484fc798e043ce40e +NONCE: 00800000021201000012345678 +IN: 23450100 +AD: +CT: b0e5d0ad +TAG: 6078e0ddbb7cd43faea57c7051e5b4ae + +# Section 8.3.5. +KEY: be635105434859f484fc798e043ce40e +NONCE: 00800148342345000012345678 +IN: 120102001234567800 +AD: +CT: 5c39da1792b1fee9ec +TAG: a9233958aced64f2343b9d610e876440 + +# Section 8.3.7. +KEY: 0953fa93e7caac9638f58820220a398e +NONCE: 008b0148352345000012345678 +IN: 000300a6ac00000002 +AD: +CT: 0d0d730f94d7f3509d +TAG: dda1694adb791652fb6ae04682f19b29 + +# Section 8.3.9. +KEY: 0953fa93e7caac9638f58820220a398e +NONCE: 008b0148362345000012345678 +IN: 000300a6ac00000003 +AD: +CT: d85d806bbed248614f +TAG: ef7f4d55e47d21522ebe3d5bc735a5c5 + +# Section 8.3.10. +KEY: be635105434859f484fc798e043ce40e +NONCE: 00800000031201000012345678 +IN: 23450101 +AD: +CT: 7777ed35 +TAG: 35d84e18784c4bf3cb1b4c191dc555cc + +# Section 8.3.12. +KEY: be635105434859f484fc798e043ce40e +NONCE: 00800000041201000012345678 +IN: 23450101 +AD: +CT: ae214660 +TAG: d146b28beafe7f984f9430502d07aafe + +# Section 8.3.14. +KEY: be635105434859f484fc798e043ce40e +NONCE: 00800000051201000012345678 +IN: 23450100 +AD: +CT: 7d3ae62a +TAG: 52ee03ab84e1a33365e8a61275665f71 + +# Section 8.3.24. +KEY: 63964771734fbd76e3b40519d1d94a48 +NONCE: 010007080d1234973612345677 +IN: ea0a00576f726c64 +AD: f4a002c7fb1e4ca0a469a021de0db875 +CT: de1547118463123e +TAG: 14604c1ddb4f5987064b1736f3923962 diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt index 8587eea1..38655fdf 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt @@ -1,5 +1,5 @@ # This is the example from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#section-8 +# https://www.rfc-editor.org/rfc/rfc8452.html#section-8 KEY: ee8e1ed9ff2540ae8f2ba9f50bc2f27c NONCE: 752abad3e0afb5f434dc4310 @@ -9,7 +9,7 @@ CT: 5d349ead175ef6b1def6fd TAG: 4fbcdeb7e4793f4a1d7e4faa70100af1 # Test vectors from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C +# https://www.rfc-editor.org/rfc/rfc8452.html#appendix-C KEY: 01000000000000000000000000000000 NONCE: 030000000000000000000000 @@ -123,6 +123,62 @@ AD: 0100000000000000000000000000000002000000 CT: 44d0aaf6fb2f1f34add5e8064e83e12a2ada TAG: bff9b2ef00fb47920cc72a0c0f13b9fd +KEY: e66021d5eb8e4f4066d4adb9c33560e4 +NONCE: f46e44bb3da0015c94f70887 +IN: +AD: +CT: +TAG: a4194b79071b01a87d65f706e3949578 + +KEY: 36864200e0eaf5284d884a0e77d31646 +NONCE: bae8e37fc83441b16034566b +IN: 7a806c +AD: 46bb91c3c5 +CT: af60eb +TAG: 711bd85bc1e4d3e0a462e074eea428a8 + +KEY: aedb64a6c590bc84d1a5e269e4b47801 +NONCE: afc0577e34699b9e671fdd4f +IN: bdc66f146545 +AD: fc880c94a95198874296 +CT: bb93a3e34d3c +TAG: d6a9c45545cfc11f03ad743dba20f966 + +KEY: d5cc1fd161320b6920ce07787f86743b +NONCE: 275d1ab32f6d1f0434d8848c +IN: 1177441f195495860f +AD: 046787f3ea22c127aaf195d1894728 +CT: 4f37281f7ad12949d0 +TAG: 1d02fd0cd174c84fc5dae2f60f52fd2b + +KEY: b3fed1473c528b8426a582995929a149 +NONCE: 9e9ad8780c8d63d0ab4149c0 +IN: 9f572c614b4745914474e7c7 +AD: c9882e5386fd9f92ec489c8fde2be2cf97e74e93 +CT: f54673c5ddf710c745641c8b +TAG: c1dc2f871fb7561da1286e655e24b7b0 + +KEY: 2d4ed87da44102952ef94b02b805249b +NONCE: ac80e6f61455bfac8308a2d4 +IN: 0d8c8451178082355c9e940fea2f58 +AD: 2950a70d5a1db2316fd568378da107b52b0da55210cc1c1b0a +CT: c9ff545e07b88a015f05b274540aa1 +TAG: 83b3449b9f39552de99dc214a1190b0b + +KEY: bde3b2f204d1e9f8b06bc47f9745b3d1 +NONCE: ae06556fb6aa7890bebc18fe +IN: 6b3db4da3d57aa94842b9803a96e07fb6de7 +AD: 1860f762ebfbd08284e421702de0de18baa9c9596291b08466f37de21c7f +CT: 6298b296e24e8cc35dce0bed484b7f30d580 +TAG: 3e377094f04709f64d7b985310a4db84 + +KEY: f901cfe8a69615a93fdf7a98cad48179 +NONCE: 6245709fb18853f68d833640 +IN: e42a3c02c25b64869e146d7b233987bddfc240871d +AD: 7576f7028ec6eb5ea7e298342a94d4b202b370ef9768ec6561c4fe6b7e7296fa859c21 +CT: 391cc328d484a4f46406181bcd62efd9b3ee197d05 +TAG: 2d15506c84a9edd65e13e9d24a2a6e70 + # Random vectors generated by the reference code. KEY: e66021d5eb8e4f4066d4adb9c33560e4 diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt index 057b7587..f20188cc 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/test/aes_256_gcm_siv_tests.txt @@ -1,5 +1,5 @@ # Test vectors from -# https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04#appendix-C +# https://www.rfc-editor.org/rfc/rfc8452.html#appendix-C KEY: 0100000000000000000000000000000000000000000000000000000000000000 NONCE: 030000000000000000000000 @@ -113,6 +113,62 @@ AD: 0100000000000000000000000000000002000000 CT: 462401724b5ce6588d5a54aae5375513a075 TAG: cfcdf5042112aa29685c912fc2056543 +KEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200 +NONCE: e0eaf5284d884a0e77d31646 +IN: +AD: +CT: +TAG: 169fbb2fbf389a995f6390af22228a62 + +KEY: bae8e37fc83441b16034566b7a806c46bb91c3c5aedb64a6c590bc84d1a5e269 +NONCE: e4b47801afc0577e34699b9e +IN: 671fdd +AD: 4fbdc66f14 +CT: 0eaccb +TAG: 93da9bb81333aee0c785b240d319719d + +KEY: 6545fc880c94a95198874296d5cc1fd161320b6920ce07787f86743b275d1ab3 +NONCE: 2f6d1f0434d8848c1177441f +IN: 195495860f04 +AD: 6787f3ea22c127aaf195 +CT: a254dad4f3f9 +TAG: 6b62b84dc40c84636a5ec12020ec8c2c + +KEY: d1894728b3fed1473c528b8426a582995929a1499e9ad8780c8d63d0ab4149c0 +NONCE: 9f572c614b4745914474e7c7 +IN: c9882e5386fd9f92ec +AD: 489c8fde2be2cf97e74e932d4ed87d +CT: 0df9e308678244c44b +TAG: c0fd3dc6628dfe55ebb0b9fb2295c8c2 + +KEY: a44102952ef94b02b805249bac80e6f61455bfac8308a2d40d8c845117808235 +NONCE: 5c9e940fea2f582950a70d5a +IN: 1db2316fd568378da107b52b +AD: 0da55210cc1c1b0abde3b2f204d1e9f8b06bc47f +CT: 8dbeb9f7255bf5769dd56692 +TAG: 404099c2587f64979f21826706d497d5 + +KEY: 9745b3d1ae06556fb6aa7890bebc18fe6b3db4da3d57aa94842b9803a96e07fb +NONCE: 6de71860f762ebfbd08284e4 +IN: 21702de0de18baa9c9596291b08466 +AD: f37de21c7ff901cfe8a69615a93fdf7a98cad481796245709f +CT: 793576dfa5c0f88729a7ed3c2f1bff +TAG: b3080d28f6ebb5d3648ce97bd5ba67fd + +KEY: b18853f68d833640e42a3c02c25b64869e146d7b233987bddfc240871d7576f7 +NONCE: 028ec6eb5ea7e298342a94d4 +IN: b202b370ef9768ec6561c4fe6b7e7296fa85 +AD: 9c2159058b1f0fe91433a5bdc20e214eab7fecef4454a10ef0657df21ac7 +CT: 857e16a64915a787637687db4a9519635cdd +TAG: 454fc2a154fea91f8363a39fec7d0a49 + +KEY: 3c535de192eaed3822a2fbbe2ca9dfc88255e14a661b8aa82cc54236093bbc23 +NONCE: 688089e55540db1872504e1c +IN: ced532ce4159b035277d4dfbb7db62968b13cd4eec +AD: 734320ccc9d9bbbb19cb81b2af4ecbc3e72834321f7aa0f70b7282b4f33df23f167541 +CT: 626660c26ea6612fb17ad91e8e767639edd6c9faee +TAG: 9d6c7029675b89eaf4ba1ded1a286594 + # Random vectors generated by the reference code. KEY: e66021d5eb8e4f4066d4adb9c33560e4f46e44bb3da0015c94f7088736864200 diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/test/cipher_tests.txt b/third_party/boringssl/kit/src/crypto/cipher_extra/test/cipher_tests.txt index 782b08e7..1622a88d 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/test/cipher_tests.txt +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/test/cipher_tests.txt @@ -123,13 +123,11 @@ Ciphertext = # DES EDE tests Cipher = DES-EDE Key = 0123456789abcdeff1e0d3c2b5a49786 -IV = fedcba9876543210 Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000 Ciphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F Cipher = DES-EDE Key = 0123456789abcdeff1e0d3c2b5a49786 -IV = fedcba9876543210 Plaintext = Ciphertext = @@ -377,6 +375,15 @@ Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 Tag = 619cc5aefffe0bfa462af43c1699d050 +Cipher = AES-128-GCM +Key = feffe9928665731c6d6a8f9467308308 +IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5 +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = 619cc5aefffe0bfa462af43c1699d051 +Operation = InvalidDecrypt + Cipher = AES-128-GCM Key = 3de7b368783bd7287f2b9b731814c876 IV = 90dedcfff100eb1f1db9d935 @@ -385,6 +392,63 @@ Ciphertext = 66c03198b3422cf3fd8291080f6fb3ebd9ad863e41cdff169becde726946a342ffa AAD = 85ddde4720659e80e25168585a354eb1e021c0b5d2ee289f2314dd5aae52bdf1fd44755bb56a6e659111a1d4b4da73315bde01c7d2c15a4f7114aefd68c141049fac27acfdca24e65c51fb1c27d307cd948e13af2963166bbc9411401d124f1ddf20f890db5611385257f52aa05c09b467e3ae886decf5744ec3749e5879f2a60017f601bbee11a66604d5f3d521d2c48cea1794f77366f29c7bd12a8aa51d34a4f3fb52809561b527016bc6badf9d136156c330e1d69d1aab98c7caa9cb46e782a898b4c66e4ee3e2445fbfacaadf9a8f73c4cbcb2a1ceb604ba5637b51337fcbe0fc366da98e805ceeb29feaf05420113b16e1005079c0e88af33f5970b3d7a8b51d0d9f5120a0795063db508171b75ed07705ac6d6bfe4ecc59243091d48865536515e036860affa880bfc91aae2fd1700de15994792aefc4a176e5d49d0f9135c7d670f3cb8798bfbe83fe73de7427e0f3e6a2df561cfa15ffe6ae80d5016096c8875b0beac8cee8fb530fb421b9a8ada4d551a528d0a0b521086f5a2db371a3bf12a2ef861f831fcb44cb2baede907a9306d3e5a3af796e0a50ba2c8dd61fb03727df5f0654d837dabee2fd90eecb7b2e8f303b0d57f97dc6a52d8281574d8457c89c6a9f5d80e0bd86c90ed39b1db4253affee614e8cf1ff05166c66e7d2a2aa2fe8a81c4741339683debe189c126e7f553a5f2dc16fc16672f74aebf94c7e3041c758fbc6d0c7f71c192cfd0fb2ec52d0a0705b05815d567f3d19f9b5d553a2adce9a79159b0e38980851bf64e97f896c028a6df8363cf1f13f4654265a7b0c0b24198efcf4418c32772bafd3980dbc689fab12e85b3ef4a491e2e5ffaa2fadaaf3deb392105a42380797d3b41ef61303a6016b269ec9a9f6e3f26070ff33cb467435ecb325dc7e18728a5c2e882e720c8f876fef10f5bffd5a925cdc9689d934272019e90e3a3bbf63a295f207faa5c014e1517c7d5c18c3ed70e92304d51944dcd3604c999d4aa8d8dbf2a4c69cbbc08635c968a20dcb80f438d43c57851c4cafec0b9568dd6c19932fd3f1294afd16f019f20e40ec87f6f5dffc7717470614b2de6e9000969e6b7e561cf91c06dd379a09c6c25c7841330dc78fc5be1d9b86581a81f55c0289531128638441fc98a1ad9472d74e2be2f874aff2fcf9c941502f59f716185a4c39289ca368c6dbf5257b5dc5e57a420792c26e602e4ecbc4f17c8787004eb88ea091d6b6ddc3c85dc110b5d1f46f6e1d872723176f4c73664ecb4219258fedce19ae22360354fa4894fe51d69434c2e58e1ec665b5cc33bb295053c591b474b6ae178c8834667bef971604279440170ebf3e739a4ff19704e5886767f81edce95a3dd93d1147995e7eb6c794b7be136658ed23cec7c374705ec0d8479dfb44cc7213076668e5fbe6a508537a9157815c6e5187b89f Tag = 469e3ef168a64945f76d7a2013f27b68 +Cipher = AES-192-GCM +Key = 000000000000000000000000000000000000000000000000 +IV = 000000000000000000000000 +AAD = +Tag = cd33b28ac773f74ba00ed1f312572435 +Plaintext = +Ciphertext = + +Cipher = AES-192-GCM +Key = 000000000000000000000000000000000000000000000000 +IV = 000000000000000000000000 +AAD = +Tag = 2ff58d80033927ab8ef4d4587514f0fb +Plaintext = 00000000000000000000000000000000 +Ciphertext = 98e7247c07f0fe411c267e4384b0f600 + +Cipher = AES-192-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c +IV = cafebabefacedbaddecaf888 +AAD = +Tag = 9924a7c8587336bfb118024db8674a14 +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255 +Ciphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256 + +Cipher = AES-192-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c +IV = cafebabefacedbaddecaf888 +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = 2519498e80f1478f37ba55bd6d27618c +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = 3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710 + +Cipher = AES-192-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c +IV = cafebabefacedbad +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = 65dcc57fcf623a24094fcca40d3533f8 +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = 0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7 + +Cipher = AES-192-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c +IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = dcf566ff291c25bbb8568fc3d376a6d9 +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b + +Cipher = AES-192-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c +IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = dcf566ff291c25bbb8568fc3d376a6d8 +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b +Operation = InvalidDecrypt + Cipher = AES-256-GCM Key = 0000000000000000000000000000000000000000000000000000000000000000 IV = 000000000000000000000000 @@ -433,6 +497,15 @@ Ciphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a +Cipher = AES-256-GCM +Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308 +IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b +Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39 +Ciphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f +AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2 +Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19b +Operation = InvalidDecrypt + # local add-ons, primarily streaming ghash tests # 128 bytes aad Cipher = AES-128-GCM diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/tls_cbc.c b/third_party/boringssl/kit/src/crypto/cipher_extra/tls_cbc.c index e1e95d42..ac6ca43f 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/tls_cbc.c +++ b/third_party/boringssl/kit/src/crypto/cipher_extra/tls_cbc.c @@ -267,24 +267,115 @@ int EVP_sha1_final_with_secret_suffix(SHA_CTX *ctx, return 1; } -int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { - return EVP_MD_type(md) == NID_sha1; -} - -int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, - size_t *md_out_size, const uint8_t header[13], - const uint8_t *data, size_t data_size, - size_t data_plus_mac_plus_padding_size, - const uint8_t *mac_secret, - unsigned mac_secret_length) { - if (EVP_MD_type(md) != NID_sha1) { - // EVP_tls_cbc_record_digest_supported should have been called first to - // check that the hash function is supported. - assert(0); - *md_out_size = 0; - return 0; +int EVP_sha256_final_with_secret_suffix(SHA256_CTX *ctx, + uint8_t out[SHA256_DIGEST_LENGTH], + const uint8_t *in, size_t len, + size_t max_len) { + // Bound the input length so |total_bits| below fits in four bytes. This is + // redundant with TLS record size limits. This also ensures |input_idx| below + // does not overflow. + size_t max_len_bits = max_len << 3; + if (ctx->Nh != 0 || + (max_len_bits >> 3) != max_len || // Overflow + ctx->Nl + max_len_bits < max_len_bits || + ctx->Nl + max_len_bits > UINT32_MAX) { + return 0; } + // We need to hash the following into |ctx|: + // + // - ctx->data[:ctx->num] + // - in[:len] + // - A 0x80 byte + // - However many zero bytes are needed to pad up to a block. + // - Eight bytes of length. + size_t num_blocks = (ctx->num + len + 1 + 8 + SHA256_CBLOCK - 1) >> 6; + size_t last_block = num_blocks - 1; + size_t max_blocks = (ctx->num + max_len + 1 + 8 + SHA256_CBLOCK - 1) >> 6; + + // The bounds above imply |total_bits| fits in four bytes. + size_t total_bits = ctx->Nl + (len << 3); + uint8_t length_bytes[4]; + length_bytes[0] = (uint8_t)(total_bits >> 24); + length_bytes[1] = (uint8_t)(total_bits >> 16); + length_bytes[2] = (uint8_t)(total_bits >> 8); + length_bytes[3] = (uint8_t)total_bits; + + // We now construct and process each expected block in constant-time. + uint8_t block[SHA256_CBLOCK] = {0}; + uint32_t result[8] = {0}; + // input_idx is the index into |in| corresponding to the current block. + // However, we allow this index to overflow beyond |max_len|, to simplify the + // 0x80 byte. + size_t input_idx = 0; + for (size_t i = 0; i < max_blocks; i++) { + // Fill |block| with data from the partial block in |ctx| and |in|. We copy + // as if we were hashing up to |max_len| and then zero the excess later. + size_t block_start = 0; + if (i == 0) { + OPENSSL_memcpy(block, ctx->data, ctx->num); + block_start = ctx->num; + } + if (input_idx < max_len) { + size_t to_copy = SHA256_CBLOCK - block_start; + if (to_copy > max_len - input_idx) { + to_copy = max_len - input_idx; + } + OPENSSL_memcpy(block + block_start, in + input_idx, to_copy); + } + + // Zero any bytes beyond |len| and add the 0x80 byte. + for (size_t j = block_start; j < SHA256_CBLOCK; j++) { + // input[idx] corresponds to block[j]. + size_t idx = input_idx + j - block_start; + // The barriers on |len| are not strictly necessary. However, without + // them, GCC compiles this code by incorporating |len| into the loop + // counter and subtracting it out later. This is still constant-time, but + // it frustrates attempts to validate this. + uint8_t is_in_bounds = constant_time_lt_8(idx, value_barrier_w(len)); + uint8_t is_padding_byte = constant_time_eq_8(idx, value_barrier_w(len)); + block[j] &= is_in_bounds; + block[j] |= 0x80 & is_padding_byte; + } + + input_idx += SHA256_CBLOCK - block_start; + + // Fill in the length if this is the last block. + crypto_word_t is_last_block = constant_time_eq_w(i, last_block); + for (size_t j = 0; j < 4; j++) { + block[SHA256_CBLOCK - 4 + j] |= is_last_block & length_bytes[j]; + } + + // Process the block and save the hash state if it is the final value. + SHA256_Transform(ctx, block); + for (size_t j = 0; j < 8; j++) { + result[j] |= is_last_block & ctx->h[j]; + } + } + + // Write the output. + for (size_t i = 0; i < 8; i++) { + CRYPTO_store_u32_be(out + 4 * i, result[i]); + } + return 1; +} + +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { + switch (EVP_MD_type(md)) { + case NID_sha1: + case NID_sha256: + return 1; + default: + return 0; + } +} + +static int tls_cbc_digest_record_sha1(uint8_t *md_out, size_t *md_out_size, + const uint8_t header[13], + const uint8_t *data, size_t data_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { if (mac_secret_length > SHA_CBLOCK) { // HMAC pads small keys with zeros and hashes large keys down. This function // should never reach the large key case. @@ -336,3 +427,88 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, *md_out_size = SHA_DIGEST_LENGTH; return 1; } + +static int tls_cbc_digest_record_sha256(uint8_t *md_out, size_t *md_out_size, + const uint8_t header[13], + const uint8_t *data, size_t data_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { + if (mac_secret_length > SHA256_CBLOCK) { + // HMAC pads small keys with zeros and hashes large keys down. This function + // should never reach the large key case. + assert(0); + return 0; + } + + // Compute the initial HMAC block. + uint8_t hmac_pad[SHA256_CBLOCK]; + OPENSSL_memset(hmac_pad, 0, sizeof(hmac_pad)); + OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); + for (size_t i = 0; i < SHA256_CBLOCK; i++) { + hmac_pad[i] ^= 0x36; + } + + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, hmac_pad, SHA256_CBLOCK); + SHA256_Update(&ctx, header, 13); + + // There are at most 256 bytes of padding, so we can compute the public + // minimum length for |data_size|. + size_t min_data_size = 0; + if (data_plus_mac_plus_padding_size > SHA256_DIGEST_LENGTH + 256) { + min_data_size = + data_plus_mac_plus_padding_size - SHA256_DIGEST_LENGTH - 256; + } + + // Hash the public minimum length directly. This reduces the number of blocks + // that must be computed in constant-time. + SHA256_Update(&ctx, data, min_data_size); + + // Hash the remaining data without leaking |data_size|. + uint8_t mac_out[SHA256_DIGEST_LENGTH]; + if (!EVP_sha256_final_with_secret_suffix( + &ctx, mac_out, data + min_data_size, data_size - min_data_size, + data_plus_mac_plus_padding_size - min_data_size)) { + return 0; + } + + // Complete the HMAC in the standard manner. + SHA256_Init(&ctx); + for (size_t i = 0; i < SHA256_CBLOCK; i++) { + hmac_pad[i] ^= 0x6a; + } + + SHA256_Update(&ctx, hmac_pad, SHA256_CBLOCK); + SHA256_Update(&ctx, mac_out, SHA256_DIGEST_LENGTH); + SHA256_Final(md_out, &ctx); + *md_out_size = SHA256_DIGEST_LENGTH; + return 1; +} + +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { + switch (EVP_MD_type(md)) { + case NID_sha1: + return tls_cbc_digest_record_sha1( + md_out, md_out_size, header, data, data_size, + data_plus_mac_plus_padding_size, mac_secret, mac_secret_length); + + case NID_sha256: + return tls_cbc_digest_record_sha256( + md_out, md_out_size, header, data, data_size, + data_plus_mac_plus_padding_size, mac_secret, mac_secret_length); + + default: + // EVP_tls_cbc_record_digest_supported should have been called first to + // check that the hash function is supported. + assert(0); + *md_out_size = 0; + return 0; + } +} diff --git a/third_party/boringssl/kit/src/crypto/compiler_test.cc b/third_party/boringssl/kit/src/crypto/compiler_test.cc index 29375a57..91023375 100644 --- a/third_party/boringssl/kit/src/crypto/compiler_test.cc +++ b/third_party/boringssl/kit/src/crypto/compiler_test.cc @@ -57,27 +57,49 @@ static void CheckRepresentation(T value) { } TEST(CompilerTest, IntegerRepresentation) { - EXPECT_EQ(8, CHAR_BIT); - EXPECT_EQ(0xff, static_cast(UCHAR_MAX)); + static_assert(CHAR_BIT == 8, "BoringSSL only supports 8-bit chars"); + static_assert(UCHAR_MAX == 0xff, "BoringSSL only supports 8-bit chars"); - // uint8_t is assumed to be unsigned char. I.e., casting to uint8_t should be - // as good as unsigned char for strict aliasing purposes. + // Require that |unsigned char| and |uint8_t| be the same type. We require + // that type-punning through |uint8_t| is not a strict aliasing violation. In + // principle, type-punning should be done with |memcpy|, which would make this + // moot. + // + // However, C made too many historical mistakes with the types and signedness + // of character strings. As a result, aliasing between all variations on 8-bit + // chars are a practical necessity for all real C code. We do not support + // toolchains that break this assumption. + static_assert( + std::is_same::value, + "BoringSSL requires uint8_t and unsigned char be the same type"); uint8_t u8 = 0; unsigned char *ptr = &u8; (void)ptr; // Sized integers have the expected size. - EXPECT_EQ(1u, sizeof(uint8_t)); - EXPECT_EQ(2u, sizeof(uint16_t)); - EXPECT_EQ(4u, sizeof(uint32_t)); - EXPECT_EQ(8u, sizeof(uint64_t)); + static_assert(sizeof(uint8_t) == 1u, "uint8_t has the wrong size"); + static_assert(sizeof(uint16_t) == 2u, "uint16_t has the wrong size"); + static_assert(sizeof(uint32_t) == 4u, "uint32_t has the wrong size"); + static_assert(sizeof(uint64_t) == 8u, "uint64_t has the wrong size"); // size_t does not exceed uint64_t. - EXPECT_LE(sizeof(size_t), 8u); + static_assert(sizeof(size_t) <= 8u, "size_t must not exceed uint64_t"); - // int must be 32-bit or larger. - EXPECT_LE(0x7fffffff, INT_MAX); - EXPECT_LE(0xffffffffu, UINT_MAX); + // Require that |int| be exactly 32 bits. OpenSSL historically mixed up + // |unsigned| and |uint32_t|, so we require it be at least 32 bits. Requiring + // at most 32-bits is a bit more subtle. C promotes arithemetic operands to + // |int| when they fit. But this means, if |int| is 2N bits wide, multiplying + // two maximum-sized |uintN_t|s is undefined by integer overflow! + // + // We attempt to handle this for |uint16_t|, assuming a 32-bit |int|, but we + // make no attempts to correct for this with |uint32_t| for a 64-bit |int|. + // Thus BoringSSL does not support ILP64 platforms. + // + // This test is on |INT_MAX| and |INT32_MAX| rather than sizeof because it is + // theoretically allowed for sizeof(int) to be 4 but include padding bits. + static_assert(INT_MAX == INT32_MAX, "BoringSSL requires int be 32-bit"); + static_assert(UINT_MAX == UINT32_MAX, + "BoringSSL requires unsigned be 32-bit"); CheckRepresentation(static_cast(127)); CheckRepresentation(static_cast(1)); diff --git a/third_party/boringssl/kit/src/crypto/conf/conf.c b/third_party/boringssl/kit/src/crypto/conf/conf.c index c1e4e963..523de78f 100644 --- a/third_party/boringssl/kit/src/crypto/conf/conf.c +++ b/third_party/boringssl/kit/src/crypto/conf/conf.c @@ -68,21 +68,10 @@ #include "conf_def.h" #include "internal.h" #include "../internal.h" -#include "../lhash/internal.h" -DEFINE_LHASH_OF(CONF_VALUE) - -struct conf_st { - LHASH_OF(CONF_VALUE) *data; -}; - static const char kDefaultSectionName[] = "default"; -// The maximum length we can grow a value to after variable expansion. 64k -// should be more than enough for all reasonable uses. -#define MAX_CONF_VALUE_LENGTH 65536 - static uint32_t conf_value_hash(const CONF_VALUE *v) { const uint32_t section_hash = v->section ? OPENSSL_strhash(v->section) : 0; const uint32_t name_hash = v->name ? OPENSSL_strhash(v->name) : 0; @@ -132,7 +121,6 @@ CONF *NCONF_new(void *method) { CONF_VALUE *CONF_VALUE_new(void) { CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE)); if (!v) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(v, 0, sizeof(CONF_VALUE)); @@ -140,24 +128,23 @@ CONF_VALUE *CONF_VALUE_new(void) { } static void value_free_contents(CONF_VALUE *value) { - if (value->section) { - OPENSSL_free(value->section); - } + OPENSSL_free(value->section); if (value->name) { OPENSSL_free(value->name); - if (value->value) { - OPENSSL_free(value->value); - } + OPENSSL_free(value->value); } else { - if (value->value) { - sk_CONF_VALUE_free((STACK_OF(CONF_VALUE)*)value->value); - } + // TODO(davidben): When |value->name| is NULL, |CONF_VALUE| is actually an + // entirely different structure. This is fragile and confusing. Make a + // proper |CONF_SECTION| type that doesn't require this. + sk_CONF_VALUE_free((STACK_OF(CONF_VALUE) *)value->value); } } static void value_free(CONF_VALUE *value) { - value_free_contents(value); - OPENSSL_free(value); + if (value != NULL) { + value_free_contents(value); + OPENSSL_free(value); + } } static void value_free_arg(CONF_VALUE *value, void *arg) { value_free(value); } @@ -193,28 +180,21 @@ static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) { if (!lh_CONF_VALUE_insert(conf->data, &old_value, v)) { goto err; } - if (old_value) { - value_free(old_value); - } + value_free(old_value); ok = 1; err: if (!ok) { - if (sk != NULL) { - sk_CONF_VALUE_free(sk); - } - if (v != NULL) { - OPENSSL_free(v); - } + sk_CONF_VALUE_free(sk); + OPENSSL_free(v); v = NULL; } return v; } static int str_copy(CONF *conf, char *section, char **pto, char *from) { - int q, r, rr = 0, to = 0, len = 0; - char *s, *e, *rp, *rrp, *np, *cp, v; - const char *p; + int q, to = 0, len = 0; + char v; BUF_MEM *buf; buf = BUF_MEM_new(); @@ -243,22 +223,6 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) { if (*from == q) { from++; } - } else if (IS_DQUOTE(conf, *from)) { - q = *from; - from++; - while (!IS_EOF(conf, *from)) { - if (*from == q) { - if (*(from + 1) == q) { - from++; - } else { - break; - } - } - buf->data[to++] = *(from++); - } - if (*from == q) { - from++; - } } else if (IS_ESC(conf, *from)) { from++; v = *(from++); @@ -277,103 +241,23 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) { } else if (IS_EOF(conf, *from)) { break; } else if (*from == '$') { - // try to expand it - rrp = NULL; - s = &(from[1]); - if (*s == '{') { - q = '}'; - } else if (*s == '(') { - q = ')'; - } else { - q = 0; - } - - if (q) { - s++; - } - cp = section; - e = np = s; - while (IS_ALPHA_NUMERIC(conf, *e)) { - e++; - } - if (e[0] == ':' && e[1] == ':') { - cp = np; - rrp = e; - rr = *e; - *rrp = '\0'; - e += 2; - np = e; - while (IS_ALPHA_NUMERIC(conf, *e)) { - e++; - } - } - r = *e; - *e = '\0'; - rp = e; - if (q) { - if (r != q) { - OPENSSL_PUT_ERROR(CONF, CONF_R_NO_CLOSE_BRACE); - goto err; - } - e++; - } - // So at this point we have - // np which is the start of the name string which is - // '\0' terminated. - // cp which is the start of the section string which is - // '\0' terminated. - // e is the 'next point after'. - // r and rr are the chars replaced by the '\0' - // rp and rrp is where 'r' and 'rr' came from. - p = NCONF_get_string(conf, cp, np); - if (rrp != NULL) { - *rrp = rr; - } - *rp = r; - if (p == NULL) { - OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE); - goto err; - } - size_t newsize = strlen(p) + buf->length - (e - from); - if (newsize > MAX_CONF_VALUE_LENGTH) { - OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); - goto err; - } - if (!BUF_MEM_grow_clean(buf, newsize)) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); - goto err; - } - while (*p) { - buf->data[to++] = *(p++); - } - - /* Since we change the pointer 'from', we also have - to change the perceived length of the string it - points at. /RL */ - len -= e - from; - from = e; - - /* In case there were no braces or parenthesis around - the variable reference, we have to put back the - character that was replaced with a '\0'. /RL */ - *rp = r; + // Historically, $foo would expand to a previously-parsed value. This + // feature has been removed as it was unused and is a DoS vector. + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_NOT_SUPPORTED); + goto err; } else { buf->data[to++] = *(from++); } } buf->data[to] = '\0'; - if (*pto != NULL) { - OPENSSL_free(*pto); - } + OPENSSL_free(*pto); *pto = buf->data; OPENSSL_free(buf); return 1; err: - if (buf != NULL) { - BUF_MEM_free(buf); - } + BUF_MEM_free(buf); return 0; } @@ -385,8 +269,9 @@ static CONF_VALUE *get_section(const CONF *conf, const char *section) { return lh_CONF_VALUE_retrieve(conf->data, &template); } -STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { - CONF_VALUE *section_value = get_section(conf, section); +const STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section) { + const CONF_VALUE *section_value = get_section(conf, section); if (section_value == NULL) { return NULL; } @@ -473,33 +358,8 @@ static char *scan_quote(CONF *conf, char *p) { return p; } - -static char *scan_dquote(CONF *conf, char *p) { - int q = *p; - - p++; - while (!(IS_EOF(conf, *p))) { - if (*p == q) { - if (*(p + 1) == q) { - p++; - } else { - break; - } - } - p++; - } - if (*p == q) { - p++; - } - return p; -} - static void clear_comments(CONF *conf, char *p) { for (;;) { - if (IS_FCOMMENT(conf, *p)) { - *p = '\0'; - return; - } if (!IS_WS(conf, *p)) { break; } @@ -511,10 +371,6 @@ static void clear_comments(CONF *conf, char *p) { *p = '\0'; return; } - if (IS_DQUOTE(conf, *p)) { - p = scan_dquote(conf, p); - continue; - } if (IS_QUOTE(conf, *p)) { p = scan_quote(conf, p); continue; @@ -551,7 +407,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { section = OPENSSL_strdup(kDefaultSectionName); if (section == NULL) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } @@ -686,7 +541,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { } v->name = OPENSSL_strdup(pname); if (v->name == NULL) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } if (!str_copy(conf, psection, &(v->value), start)) { @@ -705,27 +559,18 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { tv = sv; } if (add_string(conf, tv, v) == 0) { - OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); goto err; } v = NULL; } } - if (buff != NULL) { - BUF_MEM_free(buff); - } - if (section != NULL) { - OPENSSL_free(section); - } + BUF_MEM_free(buff); + OPENSSL_free(section); return 1; err: - if (buff != NULL) { - BUF_MEM_free(buff); - } - if (section != NULL) { - OPENSSL_free(section); - } + BUF_MEM_free(buff); + OPENSSL_free(section); if (out_error_line != NULL) { *out_error_line = eline; } @@ -733,15 +578,9 @@ err: ERR_add_error_data(2, "line ", btmp); if (v != NULL) { - if (v->name != NULL) { - OPENSSL_free(v->name); - } - if (v->value != NULL) { - OPENSSL_free(v->value); - } - if (v != NULL) { - OPENSSL_free(v); - } + OPENSSL_free(v->name); + OPENSSL_free(v->value); + OPENSSL_free(v); } return 0; } @@ -766,7 +605,7 @@ int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) { } int CONF_parse_list(const char *list, char sep, int remove_whitespace, - int (*list_cb)(const char *elem, int len, void *usr), + int (*list_cb)(const char *elem, size_t len, void *usr), void *arg) { int ret; const char *lstart, *tmpend, *p; @@ -779,7 +618,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace, lstart = list; for (;;) { if (remove_whitespace) { - while (*lstart && isspace((unsigned char)*lstart)) { + while (*lstart && OPENSSL_isspace((unsigned char)*lstart)) { lstart++; } } @@ -793,7 +632,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace, tmpend = lstart + strlen(lstart) - 1; } if (remove_whitespace) { - while (isspace((unsigned char)*tmpend)) { + while (OPENSSL_isspace((unsigned char)*tmpend)) { tmpend--; } } diff --git a/third_party/boringssl/kit/src/crypto/conf/conf_def.h b/third_party/boringssl/kit/src/crypto/conf/conf_def.h index b1e6ba63..d2c285ae 100644 --- a/third_party/boringssl/kit/src/crypto/conf/conf_def.h +++ b/third_party/boringssl/kit/src/crypto/conf/conf_def.h @@ -1,4 +1,3 @@ -/* crypto/conf/conf_def.h */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,8 +55,9 @@ * [including the GNU Public Licence.] */ -/* THIS FILE WAS AUTOMAGICALLY GENERATED! - Please modify and use keysets.pl to regenerate it. */ +// This file was historically generated by keysets.pl in OpenSSL. +// +// TODO(davidben): Replace it with something more readable. #define CONF_NUMBER 1 #define CONF_UPPER 2 @@ -67,9 +67,7 @@ #define CONF_WS 16 #define CONF_ESC 32 #define CONF_QUOTE 64 -#define CONF_DQUOTE 1024 #define CONF_COMMENT 128 -#define CONF_FCOMMENT 2048 #define CONF_EOF 8 #define CONF_HIGHBIT 4096 #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) @@ -79,7 +77,6 @@ #define KEYTYPES(c) CONF_type_default #define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) -#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) #define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) #define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) #define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) @@ -88,8 +85,6 @@ #define IS_ALPHA_NUMERIC_PUNCT(c,a) \ (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) #define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) -#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) -#define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) static const unsigned short CONF_type_default[256]={ 0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, diff --git a/third_party/boringssl/kit/src/crypto/conf/conf_test.cc b/third_party/boringssl/kit/src/crypto/conf/conf_test.cc index 65938e1b..b243411d 100644 --- a/third_party/boringssl/kit/src/crypto/conf/conf_test.cc +++ b/third_party/boringssl/kit/src/crypto/conf/conf_test.cc @@ -12,33 +12,391 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include + #include #include #include +#include "internal.h" + + +// A |CONF| is an unordered list of sections, where each section contains an +// ordered list of (name, value) pairs. +using ConfModel = + std::map>>; + +static void ExpectConfEquals(const CONF *conf, const ConfModel &model) { + // There is always a default section, even if empty. This is an easy mistake + // to make in test data, so test for it. + EXPECT_NE(model.find("default"), model.end()) + << "Model does not have a default section"; + + size_t total_values = 0; + for (const auto &pair : model) { + const std::string §ion = pair.first; + SCOPED_TRACE(section); + + const STACK_OF(CONF_VALUE) *values = + NCONF_get_section(conf, section.c_str()); + ASSERT_TRUE(values); + total_values += pair.second.size(); + + EXPECT_EQ(sk_CONF_VALUE_num(values), pair.second.size()); + + // If the lengths do not match, still compare up to the smaller of the two, + // to aid debugging. + size_t min_len = std::min(sk_CONF_VALUE_num(values), pair.second.size()); + for (size_t i = 0; i < min_len; i++) { + SCOPED_TRACE(i); + const std::string &name = pair.second[i].first; + const std::string &value = pair.second[i].second; + + const CONF_VALUE *v = sk_CONF_VALUE_value(values, i); + EXPECT_EQ(v->section, section); + EXPECT_EQ(v->name, name); + EXPECT_EQ(v->value, value); + + const char *str = NCONF_get_string(conf, section.c_str(), name.c_str()); + ASSERT_NE(str, nullptr); + EXPECT_EQ(str, value); + + if (section == "default") { + // nullptr is interpreted as the default section. + str = NCONF_get_string(conf, nullptr, name.c_str()); + ASSERT_NE(str, nullptr); + EXPECT_EQ(str, value); + } + } + } + + // Unrecognized sections must return nullptr. + EXPECT_EQ(NCONF_get_section(conf, "must_not_appear_in_tests"), nullptr); + EXPECT_EQ(NCONF_get_string(conf, "must_not_appear_in_tests", + "must_not_appear_in_tests"), + nullptr); + if (!model.empty()) { + // Valid section, invalid name. + EXPECT_EQ(NCONF_get_string(conf, model.begin()->first.c_str(), + "must_not_appear_in_tests"), + nullptr); + if (!model.begin()->second.empty()) { + // Invalid section, valid name. + EXPECT_EQ(NCONF_get_string(conf, "must_not_appear_in_tests", + model.begin()->second.front().first.c_str()), + nullptr); + } + } + + // There should not be any other values in |conf|. |conf| currently stores + // both sections and values in the same map. + EXPECT_EQ(lh_CONF_VALUE_num_items(conf->data), total_values + model.size()); +} TEST(ConfTest, Parse) { - // Check that basic parsing works. (We strongly recommend that people don't - // use the [N]CONF functions.) - - static const char kConf[] = R"( -# Comment + const struct { + std::string in; + ConfModel model; + } kTests[] = { + // Test basic parsing. + { + R"(# Comment key=value [section_name] key=value2 -)"; +)", + { + {"default", {{"key", "value"}}}, + {"section_name", {{"key", "value2"}}}, + }, + }, - bssl::UniquePtr bio(BIO_new_mem_buf(kConf, sizeof(kConf) - 1)); - ASSERT_TRUE(bio); - bssl::UniquePtr conf(NCONF_new(nullptr)); - ASSERT_TRUE(conf); - ASSERT_TRUE(NCONF_load_bio(conf.get(), bio.get(), nullptr)); - EXPECT_TRUE(NCONF_get_section(conf.get(), "section_name")); - EXPECT_FALSE(NCONF_get_section(conf.get(), "other_section")); - EXPECT_STREQ(NCONF_get_string(conf.get(), nullptr, "key"), "value"); - EXPECT_STREQ(NCONF_get_string(conf.get(), "section_name", "key"), "value2"); - EXPECT_STREQ(NCONF_get_string(conf.get(), "other_section", "key"), nullptr); + // If a section is listed multiple times, keys add to the existing one. + { + R"(key1 = value1 + +[section1] +key2 = value2 + +[section2] +key3 = value3 + +[default] +key4 = value4 + +[section1] +key5 = value5 +)", + { + {"default", {{"key1", "value1"}, {"key4", "value4"}}}, + {"section1", {{"key2", "value2"}, {"key5", "value5"}}}, + {"section2", {{"key3", "value3"}}}, + }, + }, + + // Although the CONF parser internally uses a buffer size of 512 bytes to + // read one line, it detects truncation and is able to parse long lines. + { + std::string(1000, 'a') + " = " + std::string(1000, 'b') + "\n", + { + {"default", {{std::string(1000, 'a'), std::string(1000, 'b')}}}, + }, + }, + + // Trailing backslashes are line continations. + { + "key=\\\nvalue\nkey2=foo\\\nbar=baz", + { + {"default", {{"key", "value"}, {"key2", "foobar=baz"}}}, + }, + }, + + // To be a line continuation, it must be at the end of the line. + { + "key=\\\nvalue\nkey2=foo\\ \nbar=baz", + { + {"default", {{"key", "value"}, {"key2", "foo"}, {"bar", "baz"}}}, + }, + }, + + // A line continuation without any following line is ignored. + { + "key=value\\", + { + {"default", {{"key", "value"}}}, + }, + }, + + // Values may have embedded whitespace, but leading and trailing + // whitespace is dropped. + { + "key = \t foo \t\t\tbar \t ", + { + {"default", {{"key", "foo \t\t\tbar"}}}, + }, + }, + + // Empty sections still end up in the file. + { + "[section1]\n[section2]\n[section3]\n", + { + {"default", {}}, + {"section1", {}}, + {"section2", {}}, + {"section3", {}}, + }, + }, + + // Section names can contain spaces and punctuation. + { + "[This! Is. A? Section;]\nkey = value", + { + {"default", {}}, + {"This! Is. A? Section;", {{"key", "value"}}}, + }, + }, + + // Trailing data after a section line is ignored. + { + "[section] key = value\nkey2 = value2\n", + { + {"default", {}}, + {"section", {{"key2", "value2"}}}, + }, + }, + + // Comments may appear within a line. Escapes and quotes, however, + // suppress the comment character. + { + R"( +key1 = # comment +key2 = "# not a comment" +key3 = '# not a comment' +key4 = `# not a comment` +key5 = \# not a comment +)", + { + {"default", + { + {"key1", ""}, + {"key2", "# not a comment"}, + {"key3", "# not a comment"}, + {"key4", "# not a comment"}, + {"key5", "# not a comment"}, + }}, + }, + }, + + // Quotes may appear in the middle of a string. Inside quotes, escape + // sequences like \n are not evaluated. \X always evaluates to X. + { + R"( +key1 = mix "of" 'different' `quotes` +key2 = "`'" +key3 = "\r\n\b\t\"" +key4 = '\r\n\b\t\'' +key5 = `\r\n\b\t\`` +)", + { + {"default", + { + {"key1", "mix of different quotes"}, + {"key2", "`'"}, + {"key3", "rnbt\""}, + {"key4", "rnbt'"}, + {"key5", "rnbt`"}, + }}, + }, + }, + + // Outside quotes, escape sequences like \n are evaluated. Unknown escapes + // turn into the character. + { + R"( +key = \r\n\b\t\"\'\`\z +)", + { + {"default", + { + {"key", "\r\n\b\t\"'`z"}, + }}, + }, + }, + + // Escapes (but not quoting) work inside section names. + { + "[section\\ name]\nkey = value\n", + { + {"default", {}}, + {"section name", {{"key", "value"}}}, + }, + }, + + // Escapes (but not quoting) are skipped over in key names, but they are + // left unevaluated. This is probably a bug. + { + "key\\ name = value\n", + { + {"default", {{"key\\ name", "value"}}}, + }, + }, + + // Keys can specify sections explicitly with ::. + { + R"( +[section1] +default::key1 = value1 +section1::key2 = value2 +section2::key3 = value3 +section1::key4 = value4 +section2::key5 = value5 +default::key6 = value6 +key7 = value7 # section1 +)", + { + {"default", {{"key1", "value1"}, {"key6", "value6"}}}, + {"section1", + {{"key2", "value2"}, {"key4", "value4"}, {"key7", "value7"}}}, + {"section2", {{"key3", "value3"}, {"key5", "value5"}}}, + }, + }, + + // Punctuation is allowed in key names. + { + "key.1 = value\n", + { + {"default", {{"key.1", "value"}}}, + }, + }, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.in); + bssl::UniquePtr bio(BIO_new_mem_buf(t.in.data(), t.in.size())); + ASSERT_TRUE(bio); + bssl::UniquePtr conf(NCONF_new(nullptr)); + ASSERT_TRUE(conf); + ASSERT_TRUE(NCONF_load_bio(conf.get(), bio.get(), nullptr)); + + ExpectConfEquals(conf.get(), t.model); + } + + const char *kInvalidTests[] = { + // Missing equals sign. + "key", + // Unterminated section heading. + "[section", + // Section names can only contain alphanumeric characters, punctuation, + // and escapes. Quotes are not punctuation. + "[\"section\"]", + // Keys can only contain alphanumeric characters, punctuaion, and escapes. + "key name = value", + "\"key\" = value", + // Variable references have been removed. + "key1 = value1\nkey2 = $key1", + }; + for (const auto &t : kInvalidTests) { + SCOPED_TRACE(t); + bssl::UniquePtr bio(BIO_new_mem_buf(t, strlen(t))); + ASSERT_TRUE(bio); + bssl::UniquePtr conf(NCONF_new(nullptr)); + ASSERT_TRUE(conf); + EXPECT_FALSE(NCONF_load_bio(conf.get(), bio.get(), nullptr)); + } +} + +TEST(ConfTest, ParseList) { + const struct { + const char *list; + char sep; + bool remove_whitespace; + std::vector expected; + } kTests[] = { + {"", ',', /*remove_whitespace=*/0, {""}}, + {"", ',', /*remove_whitespace=*/1, {""}}, + + {" ", ',', /*remove_whitespace=*/0, {" "}}, + {" ", ',', /*remove_whitespace=*/1, {""}}, + + {"hello world", ',', /*remove_whitespace=*/0, {"hello world"}}, + {"hello world", ',', /*remove_whitespace=*/1, {"hello world"}}, + + {" hello world ", ',', /*remove_whitespace=*/0, {" hello world "}}, + {" hello world ", ',', /*remove_whitespace=*/1, {"hello world"}}, + + {"hello,world", ',', /*remove_whitespace=*/0, {"hello", "world"}}, + {"hello,world", ',', /*remove_whitespace=*/1, {"hello", "world"}}, + + {"hello,,world", ',', /*remove_whitespace=*/0, {"hello", "", "world"}}, + {"hello,,world", ',', /*remove_whitespace=*/1, {"hello", "", "world"}}, + + {"\tab cd , , ef gh ", + ',', + /*remove_whitespace=*/0, + {"\tab cd ", " ", " ef gh "}}, + {"\tab cd , , ef gh ", + ',', + /*remove_whitespace=*/1, + {"ab cd", "", "ef gh"}}, + }; + for (const auto& t : kTests) { + SCOPED_TRACE(t.list); + SCOPED_TRACE(t.sep); + SCOPED_TRACE(t.remove_whitespace); + + std::vector result; + auto append_to_vector = [](const char *elem, size_t len, void *arg) -> int { + auto *vec = static_cast *>(arg); + vec->push_back(std::string(elem, len)); + return 1; + }; + ASSERT_TRUE(CONF_parse_list(t.list, t.sep, t.remove_whitespace, + append_to_vector, &result)); + EXPECT_EQ(result, t.expected); + } } diff --git a/third_party/boringssl/kit/src/crypto/conf/internal.h b/third_party/boringssl/kit/src/crypto/conf/internal.h index 3e0e57df..04359ad2 100644 --- a/third_party/boringssl/kit/src/crypto/conf/internal.h +++ b/third_party/boringssl/kit/src/crypto/conf/internal.h @@ -15,14 +15,34 @@ #ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H +#include + +#include "../lhash/internal.h" + #if defined(__cplusplus) extern "C" { #endif +DEFINE_LHASH_OF(CONF_VALUE) + +struct conf_st { + LHASH_OF(CONF_VALUE) *data; +}; + // CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. CONF_VALUE *CONF_VALUE_new(void); +// CONF_parse_list takes a list separated by 'sep' and calls |list_cb| giving +// the start and length of each member, optionally stripping leading and +// trailing whitespace. This can be used to parse comma separated lists for +// example. If |list_cb| returns <= 0, then the iteration is halted and that +// value is returned immediately. Otherwise it returns one. Note that |list_cb| +// may be called on an empty member. +OPENSSL_EXPORT int CONF_parse_list( + const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, size_t len, void *usr), void *arg); + #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/crypto/constant_time_test.cc b/third_party/boringssl/kit/src/crypto/constant_time_test.cc index ae80003e..50389c60 100644 --- a/third_party/boringssl/kit/src/crypto/constant_time_test.cc +++ b/third_party/boringssl/kit/src/crypto/constant_time_test.cc @@ -52,6 +52,7 @@ #include #include +#include "test/test_util.h" #include #include @@ -169,3 +170,71 @@ TEST(ConstantTimeTest, ValueBarrier) { EXPECT_EQ(u64, value_barrier_u64(u64)); } } + +TEST(ConstantTimeTest, MemCmov) { + for (int i = 0; i < 100; i++) { + uint8_t out[256], in[256]; + RAND_bytes(out, sizeof(out)); + RAND_bytes(in, sizeof(in)); + + uint8_t b = 0; + RAND_bytes(&b, 1); + b = constant_time_is_zero_8(b & 0xf); + + uint8_t ref_in[256]; + OPENSSL_memcpy(ref_in, in, sizeof(in)); + + uint8_t ref_out[256]; + OPENSSL_memcpy(ref_out, out, sizeof(out)); + if (b) { + OPENSSL_memcpy(ref_out, in, sizeof(in)); + } + + CONSTTIME_SECRET(out, sizeof(out)); + CONSTTIME_SECRET(in, sizeof(in)); + CONSTTIME_SECRET(&b, 1); + + constant_time_conditional_memcpy(out, in, sizeof(out), b); + + CONSTTIME_DECLASSIFY(&in, sizeof(in)); + CONSTTIME_DECLASSIFY(&out, sizeof(out)); + + EXPECT_EQ(Bytes(in), Bytes(ref_in)); + EXPECT_EQ(Bytes(out), Bytes(ref_out)); + } +} + +TEST(ConstantTimeTest, MemCxor) { + for (int i = 0; i < 100; i++) { + uint8_t out[256], in[256]; + RAND_bytes(out, sizeof(out)); + RAND_bytes(in, sizeof(in)); + + uint8_t b = 0; + RAND_bytes(&b, 1); + b = constant_time_is_zero_8(b & 0xf); + + uint8_t ref_in[256]; + OPENSSL_memcpy(ref_in, in, sizeof(in)); + + uint8_t ref_out[256]; + OPENSSL_memcpy(ref_out, out, sizeof(out)); + if (b) { + for (size_t j = 0; j < sizeof(ref_out); ++j) { + ref_out[j] ^= in[j]; + } + } + + CONSTTIME_SECRET(out, sizeof(out)); + CONSTTIME_SECRET(in, sizeof(in)); + CONSTTIME_SECRET(&b, 1); + + constant_time_conditional_memxor(out, in, sizeof(out), b); + + CONSTTIME_DECLASSIFY(&in, sizeof(in)); + CONSTTIME_DECLASSIFY(&out, sizeof(out)); + + EXPECT_EQ(Bytes(in), Bytes(ref_in)); + EXPECT_EQ(Bytes(out), Bytes(ref_out)); + } +} diff --git a/third_party/boringssl/kit/src/crypto/cpu_aarch64_apple.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_apple.c new file mode 100644 index 00000000..de6a8bd0 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_apple.c @@ -0,0 +1,77 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_APPLE) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include + +#include + + +extern uint32_t OPENSSL_armcap_P; + +static int has_hw_feature(const char *name) { + int value; + size_t len = sizeof(value); + if (sysctlbyname(name, &value, &len, NULL, 0) != 0) { + return 0; + } + if (len != sizeof(int)) { + // This should not happen. All the values queried should be integer-valued. + assert(0); + return 0; + } + + // Per sys/sysctl.h: + // + // Selectors that return errors are not support on the system. Supported + // features will return 1 if they are recommended or 0 if they are supported + // but are not expected to help performance. Future versions of these + // selectors may return larger values as necessary so it is best to test for + // non zero. + return value != 0; +} + +void OPENSSL_cpuid_setup(void) { + // Apple ARM64 platforms have NEON and cryptography extensions available + // statically, so we do not need to query them. In particular, there sometimes + // are no sysctls corresponding to such features. See below. +#if !defined(__ARM_NEON) || !defined(__ARM_FEATURE_AES) || \ + !defined(__ARM_FEATURE_SHA2) +#error "NEON and crypto extensions should be statically available." +#endif + OPENSSL_armcap_P = + ARMV7_NEON | ARMV8_AES | ARMV8_PMULL | ARMV8_SHA1 | ARMV8_SHA256; + + // See Apple's documentation for sysctl names: + // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics + // + // The new feature names, e.g. "hw.optional.arm.FEAT_SHA512", are only + // available in macOS 12. For compatibility with macOS 11, we also support + // the old names. The old names don't have values for features like FEAT_AES, + // so instead we detect them statically above. + // + // If querying new sysctls, update the Chromium sandbox definition. See + // https://crrev.com/c/4415225. + if (has_hw_feature("hw.optional.arm.FEAT_SHA512") || + has_hw_feature("hw.optional.armv8_2_sha512")) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_APPLE && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu_aarch64_freebsd.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_freebsd.c new file mode 100644 index 00000000..42d8afa0 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_freebsd.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FREEBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include + +#include + +extern uint32_t OPENSSL_armcap_P; + +// ID_AA64ISAR0_*_VAL are defined starting FreeBSD 13.0. When FreeBSD +// 12.x is out of support, these compatibility macros can be removed. + +#ifndef ID_AA64ISAR0_AES_VAL +#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES +#endif +#ifndef ID_AA64ISAR0_SHA1_VAL +#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1 +#endif +#ifndef ID_AA64ISAR0_SHA2_VAL +#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2 +#endif + +void OPENSSL_cpuid_setup(void) { + uint64_t id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1); + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) >= ID_AA64ISAR0_AES_BASE) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) >= ID_AA64ISAR0_AES_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA1_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA2_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) >= ID_AA64ISAR0_SHA2_512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_FREEBSD && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-aarch64-fuchsia.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_fuchsia.c similarity index 81% rename from third_party/boringssl/kit/src/crypto/cpu-aarch64-fuchsia.c rename to third_party/boringssl/kit/src/crypto/cpu_aarch64_fuchsia.c index 98303a03..64bc4489 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-aarch64-fuchsia.c +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_fuchsia.c @@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "internal.h" #if defined(OPENSSL_AARCH64) && defined(OPENSSL_FUCHSIA) && \ !defined(OPENSSL_STATIC_ARMCAP) @@ -23,16 +23,14 @@ #include -#include "internal.h" - extern uint32_t OPENSSL_armcap_P; void OPENSSL_cpuid_setup(void) { uint32_t hwcap; zx_status_t rc = zx_system_get_features(ZX_FEATURE_KIND_CPU, &hwcap); if (rc != ZX_OK || (hwcap & ZX_ARM64_FEATURE_ISA_ASIMD) == 0) { - // Matching OpenSSL, if NEON/ASIMD is missing, don't report other features - // either. + // If NEON/ASIMD is missing, don't report other features either. This + // matches OpenSSL, and the other features depend on SIMD registers. return; } @@ -47,9 +45,12 @@ void OPENSSL_cpuid_setup(void) { if (hwcap & ZX_ARM64_FEATURE_ISA_SHA1) { OPENSSL_armcap_P |= ARMV8_SHA1; } - if (hwcap & ZX_ARM64_FEATURE_ISA_SHA2) { + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA256) { OPENSSL_armcap_P |= ARMV8_SHA256; } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } } -#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP +#endif // OPENSSL_AARCH64 && OPENSSL_FUCHSIA && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-aarch64-linux.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_linux.c similarity index 90% rename from third_party/boringssl/kit/src/crypto/cpu-aarch64-linux.c rename to third_party/boringssl/kit/src/crypto/cpu_aarch64_linux.c index 0184dd4f..42227115 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-aarch64-linux.c +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_linux.c @@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "internal.h" #if defined(OPENSSL_AARCH64) && defined(OPENSSL_LINUX) && \ !defined(OPENSSL_STATIC_ARMCAP) @@ -21,8 +21,6 @@ #include -#include "internal.h" - extern uint32_t OPENSSL_armcap_P; @@ -36,6 +34,7 @@ void OPENSSL_cpuid_setup(void) { static const unsigned long kPMULL = 1 << 4; static const unsigned long kSHA1 = 1 << 5; static const unsigned long kSHA256 = 1 << 6; + static const unsigned long kSHA512 = 1 << 21; if ((hwcap & kNEON) == 0) { // Matching OpenSSL, if NEON is missing, don't report other features @@ -57,6 +56,9 @@ void OPENSSL_cpuid_setup(void) { if (hwcap & kSHA256) { OPENSSL_armcap_P |= ARMV8_SHA256; } + if (hwcap & kSHA512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } } -#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP +#endif // OPENSSL_AARCH64 && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu_aarch64_openbsd.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_openbsd.c new file mode 100644 index 00000000..be271f26 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_openbsd.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2022, Robert Nagy + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_OPENBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include + +#include + +#include "internal.h" + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 }; + uint64_t cpu_id = 0; + size_t len = sizeof(cpu_id); + + if (sysctl(isar0_mib, 2, &cpu_id, &len, NULL, 0) < 0) { + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (ID_AA64ISAR0_AES(cpu_id) >= ID_AA64ISAR0_AES_BASE) { + OPENSSL_armcap_P |= ARMV8_AES; + } + + if (ID_AA64ISAR0_AES(cpu_id) >= ID_AA64ISAR0_AES_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + + if (ID_AA64ISAR0_SHA1(cpu_id) >= ID_AA64ISAR0_SHA1_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + + if (ID_AA64ISAR0_SHA2(cpu_id) >= ID_AA64ISAR0_SHA2_BASE) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + + if (ID_AA64ISAR0_SHA2(cpu_id) >= ID_AA64ISAR0_SHA2_512) { + OPENSSL_armcap_P |= ARMV8_SHA512; + } +} + +#endif // OPENSSL_AARCH64 && OPENSSL_OPENBSD && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-aarch64-win.c b/third_party/boringssl/kit/src/crypto/cpu_aarch64_win.c similarity index 88% rename from third_party/boringssl/kit/src/crypto/cpu-aarch64-win.c rename to third_party/boringssl/kit/src/crypto/cpu_aarch64_win.c index ee7f8e02..0630f96a 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-aarch64-win.c +++ b/third_party/boringssl/kit/src/crypto/cpu_aarch64_win.c @@ -13,7 +13,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "internal.h" #if defined(OPENSSL_AARCH64) && defined(OPENSSL_WINDOWS) && \ !defined(OPENSSL_STATIC_ARMCAP) @@ -22,8 +22,6 @@ #include -#include "internal.h" - extern uint32_t OPENSSL_armcap_P; void OPENSSL_cpuid_setup(void) { // We do not need to check for the presence of NEON, as Armv8-A always has it @@ -36,6 +34,8 @@ void OPENSSL_cpuid_setup(void) { OPENSSL_armcap_P |= ARMV8_SHA1; OPENSSL_armcap_P |= ARMV8_SHA256; } + // As of writing, Windows does not have a |PF_*| value for ARMv8.2 SHA-512 + // extensions. When it does, add it here. } -#endif +#endif // OPENSSL_AARCH64 && OPENSSL_WINDOWS && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-arm.c b/third_party/boringssl/kit/src/crypto/cpu_arm.c similarity index 98% rename from third_party/boringssl/kit/src/crypto/cpu-arm.c rename to third_party/boringssl/kit/src/crypto/cpu_arm.c index e8596ac2..33259084 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-arm.c +++ b/third_party/boringssl/kit/src/crypto/cpu_arm.c @@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "internal.h" #if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_STATIC_ARMCAP) diff --git a/third_party/boringssl/kit/src/crypto/cpu_arm_freebsd.c b/third_party/boringssl/kit/src/crypto/cpu_arm_freebsd.c new file mode 100644 index 00000000..dcc79205 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/cpu_arm_freebsd.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_ARM) && defined(OPENSSL_FREEBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) +#include +#include + +#include +#include + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = 0, hwcap2 = 0; + + // |elf_aux_info| may fail, in which case |hwcap| and |hwcap2| will be + // left at zero. The rest of this function will then gracefully report + // the features are absent. + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); + + // Matching OpenSSL, only report other features if NEON is present. + if (hwcap & HWCAP_NEON) { + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap2 & HWCAP2_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap2 & HWCAP2_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap2 & HWCAP2_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap2 & HWCAP2_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + } +} + +#endif // OPENSSL_ARM && OPENSSL_OPENBSD && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-arm-linux.c b/third_party/boringssl/kit/src/crypto/cpu_arm_linux.c similarity index 57% rename from third_party/boringssl/kit/src/crypto/cpu-arm-linux.c rename to third_party/boringssl/kit/src/crypto/cpu_arm_linux.c index 962a4a50..d13ac215 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-arm-linux.c +++ b/third_party/boringssl/kit/src/crypto/cpu_arm_linux.c @@ -12,25 +12,20 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "internal.h" -#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP) +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) #include #include +#include #include #include #include #include -#include "cpu-arm-linux.h" - -#define AT_HWCAP 16 -#define AT_HWCAP2 26 - -// |getauxval| is not available on Android until API level 20. Link it as a weak -// symbol and use other methods as fallback. -unsigned long getauxval(unsigned long type) __attribute__((weak)); +#include "cpu_arm_linux.h" static int open_eintr(const char *path, int flags) { int ret; @@ -48,21 +43,6 @@ static ssize_t read_eintr(int fd, void *out, size_t len) { return ret; } -// read_full reads exactly |len| bytes from |fd| to |out|. On error or end of -// file, it returns zero. -static int read_full(int fd, void *out, size_t len) { - char *outp = out; - while (len > 0) { - ssize_t ret = read_eintr(fd, outp, len); - if (ret <= 0) { - return 0; - } - outp += ret; - len -= ret; - } - return 1; -} - // read_file opens |path| and reads until end-of-file. On success, it returns // one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the // contents. Otherwise, it returns zero. @@ -115,41 +95,14 @@ err: return ret; } -// getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. -static unsigned long getauxval_proc(unsigned long type) { - int fd = open_eintr("/proc/self/auxv", O_RDONLY); - if (fd < 0) { - return 0; - } - - struct { - unsigned long tag; - unsigned long value; - } entry; - - for (;;) { - if (!read_full(fd, &entry, sizeof(entry)) || - (entry.tag == 0 && entry.value == 0)) { - break; - } - if (entry.tag == type) { - close(fd); - return entry.value; - } - } - close(fd); - return 0; -} - extern uint32_t OPENSSL_armcap_P; -static int g_has_broken_neon, g_needs_hwcap2_workaround; +static int g_needs_hwcap2_workaround; void OPENSSL_cpuid_setup(void) { // We ignore the return value of |read_file| and proceed with an empty // /proc/cpuinfo on error. If |getauxval| works, we will still detect - // capabilities. There may be a false positive due to - // |crypto_cpuinfo_has_broken_neon|, but this is now rare. + // capabilities. char *cpuinfo_data = NULL; size_t cpuinfo_len = 0; read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo"); @@ -157,37 +110,8 @@ void OPENSSL_cpuid_setup(void) { cpuinfo.data = cpuinfo_data; cpuinfo.len = cpuinfo_len; - // |getauxval| is not available on Android until API level 20. If it is - // unavailable, read from /proc/self/auxv as a fallback. This is unreadable - // on some versions of Android, so further fall back to /proc/cpuinfo. - // - // See - // https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2 - // and b/13679666 (Google-internal) for details. - unsigned long hwcap = 0; - if (getauxval != NULL) { - hwcap = getauxval(AT_HWCAP); - } - if (hwcap == 0) { - hwcap = getauxval_proc(AT_HWCAP); - } - if (hwcap == 0) { - hwcap = crypto_get_arm_hwcap_from_cpuinfo(&cpuinfo); - } - - // Clear NEON support if known broken. Note, if NEON is available statically, - // the non-NEON code is dropped and this workaround is a no-op. - // - // TODO(davidben): The Android NDK now builds with NEON statically available - // by default. Cronet still has some consumers that support NEON-less devices - // (b/150371744). Get metrics on whether they still see this CPU and, if not, - // remove this check entirely. - g_has_broken_neon = crypto_cpuinfo_has_broken_neon(&cpuinfo); - if (g_has_broken_neon) { - hwcap &= ~HWCAP_NEON; - } - // Matching OpenSSL, only report other features if NEON is present. + unsigned long hwcap = getauxval(AT_HWCAP); if (hwcap & HWCAP_NEON) { OPENSSL_armcap_P |= ARMV7_NEON; @@ -196,10 +120,7 @@ void OPENSSL_cpuid_setup(void) { // this is now rare (see Chrome's Net.NeedsHWCAP2Workaround metric), but AES // and PMULL extensions are very useful, so we still carry the workaround // for now. - unsigned long hwcap2 = 0; - if (getauxval != NULL) { - hwcap2 = getauxval(AT_HWCAP2); - } + unsigned long hwcap2 = getauxval(AT_HWCAP2); if (hwcap2 == 0) { hwcap2 = crypto_get_arm_hwcap2_from_cpuinfo(&cpuinfo); g_needs_hwcap2_workaround = hwcap2 != 0; @@ -222,8 +143,8 @@ void OPENSSL_cpuid_setup(void) { OPENSSL_free(cpuinfo_data); } -int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; } +int CRYPTO_has_broken_NEON(void) { return 0; } int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; } -#endif // OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP +#endif // OPENSSL_ARM && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-arm-linux.h b/third_party/boringssl/kit/src/crypto/cpu_arm_linux.h similarity index 76% rename from third_party/boringssl/kit/src/crypto/cpu-arm-linux.h rename to third_party/boringssl/kit/src/crypto/cpu_arm_linux.h index e326285f..89509978 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-arm-linux.h +++ b/third_party/boringssl/kit/src/crypto/cpu_arm_linux.h @@ -118,13 +118,6 @@ static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in, return 0; } -static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field, - const char *value) { - STRING_PIECE extracted; - return extract_cpuinfo_field(&extracted, cpuinfo, field) && - STRING_PIECE_equals(&extracted, value); -} - // has_list_item treats |list| as a space-separated list of items and returns // one if |item| is contained in |list| and zero otherwise. static int has_list_item(const STRING_PIECE *list, const char *item) { @@ -137,27 +130,6 @@ static int has_list_item(const STRING_PIECE *list, const char *item) { return 0; } -// crypto_get_arm_hwcap_from_cpuinfo returns an equivalent ARM |AT_HWCAP| value -// from |cpuinfo|. -static unsigned long crypto_get_arm_hwcap_from_cpuinfo( - const STRING_PIECE *cpuinfo) { - if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) { - // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always - // available on ARMv8. Linux omits required features, so reading the - // "Features" line does not work. (For simplicity, use strict equality. We - // assume everything running on future ARM architectures will have a - // working |getauxval|.) - return HWCAP_NEON; - } - - STRING_PIECE features; - if (extract_cpuinfo_field(&features, cpuinfo, "Features") && - has_list_item(&features, "neon")) { - return HWCAP_NEON; - } - return 0; -} - // crypto_get_arm_hwcap2_from_cpuinfo returns an equivalent ARM |AT_HWCAP2| // value from |cpuinfo|. static unsigned long crypto_get_arm_hwcap2_from_cpuinfo( @@ -183,16 +155,6 @@ static unsigned long crypto_get_arm_hwcap2_from_cpuinfo( return ret; } -// crypto_cpuinfo_has_broken_neon returns one if |cpuinfo| matches a CPU known -// to have broken NEON unit and zero otherwise. See https://crbug.com/341598. -static int crypto_cpuinfo_has_broken_neon(const STRING_PIECE *cpuinfo) { - return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") && - cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") && - cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") && - cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") && - cpuinfo_field_equals(cpuinfo, "CPU revision", "0"); -} - #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/crypto/cpu-arm-linux_test.cc b/third_party/boringssl/kit/src/crypto/cpu_arm_linux_test.cc similarity index 64% rename from third_party/boringssl/kit/src/crypto/cpu-arm-linux_test.cc rename to third_party/boringssl/kit/src/crypto/cpu_arm_linux_test.cc index 0472537f..0b6b02fb 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-arm-linux_test.cc +++ b/third_party/boringssl/kit/src/crypto/cpu_arm_linux_test.cc @@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "cpu-arm-linux.h" +#include "cpu_arm_linux.h" #include @@ -22,55 +22,8 @@ TEST(ARMLinuxTest, CPUInfo) { struct CPUInfoTest { const char *cpuinfo; - unsigned long hwcap; unsigned long hwcap2; - bool broken_neon; } kTests[] = { - // https://crbug.com/341598#c33 - { - "Processor: ARMv7 Processory rev 0 (v71)\n" - "processor: 0\n" - "BogoMIPS: 13.50\n" - "\n" - "Processor: 1\n" - "BogoMIPS: 13.50\n" - "\n" - "Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 " - "idiva idivt\n" - "CPU implementer : 0x51\n" - "CPU architecture: 7\n" - "CPU variant: 0x1\n" - "CPU part: 0x04d\n" - "CPU revision: 0\n" - "\n" - "Hardware: SAMSUNG M2\n" - "Revision: 0010\n" - "Serial: 00001e030000354e\n", - HWCAP_NEON, - 0, - true, - }, - // https://crbug.com/341598#c39 - { - "Processor : ARMv7 Processor rev 0 (v7l)\n" - "processor : 0\n" - "BogoMIPS : 13.53\n" - "\n" - "Features : swp half thumb fastmult vfp edsp neon vfpv3 tls " - "vfpv4\n" - "CPU implementer : 0x51\n" - "CPU architecture: 7\n" - "CPU variant : 0x1\n" - "CPU part : 0x04d\n" - "CPU revision : 0\n" - "\n" - "Hardware : SAMSUNG M2_ATT\n" - "Revision : 0010\n" - "Serial : 0000df0c00004d4c\n", - HWCAP_NEON, - 0, - true, - }, // Nexus 4 from https://crbug.com/341598#c43 { "Processor : ARMv7 Processor rev 2 (v7l)\n" @@ -97,30 +50,7 @@ TEST(ARMLinuxTest, CPUInfo) { "Hardware : QCT APQ8064 MAKO\n" "Revision : 000b\n" "Serial : 0000000000000000\n", - HWCAP_NEON, 0, - false, - }, - // Razr M from https://crbug.com/341598#c43 - { - "Processor : ARMv7 Processor rev 4 (v7l)\n" - "processor : 0\n" - "BogoMIPS : 13.53\n" - "\n" - "Features : swp half thumb fastmult vfp edsp neon vfpv3 tls " - "vfpv4\n" - "CPU implementer : 0x51\n" - "CPU architecture: 7\n" - "CPU variant : 0x1\n" - "CPU part : 0x04d\n" - "CPU revision : 4\n" - "\n" - "Hardware : msm8960dt\n" - "Revision : 82a0\n" - "Serial : 0001000201fe37a5\n", - HWCAP_NEON, - 0, - false, }, // Pixel 2 (truncated slightly) { @@ -163,77 +93,56 @@ TEST(ARMLinuxTest, CPUInfo) { // (Extra processors omitted.) "\n" "Hardware : Qualcomm Technologies, Inc MSM8998\n", - HWCAP_NEON, // CPU architecture 8 implies NEON. HWCAP2_AES | HWCAP2_PMULL | HWCAP2_SHA1 | HWCAP2_SHA2, - false, }, - // Nexus 4 from // Garbage should be tolerated. { "Blah blah blah this is definitely an ARM CPU", 0, - 0, - false, }, // A hypothetical ARMv8 CPU without crc32 (and thus no trailing space // after the last crypto entry). { "Features : aes pmull sha1 sha2\n" "CPU architecture: 8\n", - HWCAP_NEON, HWCAP2_AES | HWCAP2_PMULL | HWCAP2_SHA1 | HWCAP2_SHA2, - false, }, // Various combinations of ARMv8 flags. { "Features : aes sha1 sha2\n" "CPU architecture: 8\n", - HWCAP_NEON, HWCAP2_AES | HWCAP2_SHA1 | HWCAP2_SHA2, - false, }, { "Features : pmull sha2\n" "CPU architecture: 8\n", - HWCAP_NEON, HWCAP2_PMULL | HWCAP2_SHA2, - false, }, { "Features : aes aes aes not_aes aes aes \n" "CPU architecture: 8\n", - HWCAP_NEON, HWCAP2_AES, - false, }, { "Features : \n" "CPU architecture: 8\n", - HWCAP_NEON, 0, - false, }, { "Features : nothing\n" "CPU architecture: 8\n", - HWCAP_NEON, 0, - false, }, // If opening /proc/cpuinfo fails, we process the empty string. { "", 0, - 0, - false, }, }; for (const auto &t : kTests) { SCOPED_TRACE(t.cpuinfo); STRING_PIECE sp = {t.cpuinfo, strlen(t.cpuinfo)}; - EXPECT_EQ(t.hwcap, crypto_get_arm_hwcap_from_cpuinfo(&sp)); EXPECT_EQ(t.hwcap2, crypto_get_arm_hwcap2_from_cpuinfo(&sp)); - EXPECT_EQ(t.broken_neon ? 1 : 0, crypto_cpuinfo_has_broken_neon(&sp)); } } diff --git a/third_party/boringssl/kit/src/crypto/cpu-ppc64le.c b/third_party/boringssl/kit/src/crypto/cpu_arm_openbsd.c similarity index 61% rename from third_party/boringssl/kit/src/crypto/cpu-ppc64le.c rename to third_party/boringssl/kit/src/crypto/cpu_arm_openbsd.c index 6cc8aee5..c3463c72 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-ppc64le.c +++ b/third_party/boringssl/kit/src/crypto/cpu_arm_openbsd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, Google Inc. +/* Copyright (c) 2023, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -12,27 +12,20 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - -#if defined(OPENSSL_PPC64LE) - -#include - #include "internal.h" +#if defined(OPENSSL_ARM) && defined(OPENSSL_OPENBSD) && \ + !defined(OPENSSL_STATIC_ARMCAP) -#if !defined(PPC_FEATURE2_HAS_VCRYPTO) -// PPC_FEATURE2_HAS_VCRYPTO was taken from section 4.1.2.3 of the “OpenPOWER -// ABI for Linux Supplement”. -#define PPC_FEATURE2_HAS_VCRYPTO 0x02000000 -#endif +#include + +extern uint32_t OPENSSL_armcap_P; void OPENSSL_cpuid_setup(void) { - OPENSSL_ppc64le_hwcap2 = getauxval(AT_HWCAP2); + // OpenBSD does not support arm32 machines without NEON + OPENSSL_armcap_P |= ARMV7_NEON; + + // OpenBSD does not support v8 features on non aarch64 } -int CRYPTO_is_PPC64LE_vcrypto_capable(void) { - return (OPENSSL_ppc64le_hwcap2 & PPC_FEATURE2_HAS_VCRYPTO) != 0; -} - -#endif // OPENSSL_PPC64LE +#endif // OPENSSL_ARM && OPENSSL_OPENBSD && !OPENSSL_STATIC_ARMCAP diff --git a/third_party/boringssl/kit/src/crypto/cpu-intel.c b/third_party/boringssl/kit/src/crypto/cpu_intel.c similarity index 99% rename from third_party/boringssl/kit/src/crypto/cpu-intel.c rename to third_party/boringssl/kit/src/crypto/cpu_intel.c index 53ece950..fa96a7f6 100644 --- a/third_party/boringssl/kit/src/crypto/cpu-intel.c +++ b/third_party/boringssl/kit/src/crypto/cpu_intel.c @@ -54,8 +54,7 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include - +#include #if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) diff --git a/third_party/boringssl/kit/src/crypto/crypto.c b/third_party/boringssl/kit/src/crypto/crypto.c index 6886aa4e..beaae0f7 100644 --- a/third_party/boringssl/kit/src/crypto/crypto.c +++ b/third_party/boringssl/kit/src/crypto/crypto.c @@ -14,20 +14,21 @@ #include -#include +#include #include "fipsmodule/rand/fork_detect.h" #include "fipsmodule/rand/internal.h" #include "internal.h" +static_assert(sizeof(ossl_ssize_t) == sizeof(size_t), + "ossl_ssize_t should be the same size as size_t"); + #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \ - (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ - defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ - defined(OPENSSL_PPC64LE)) -// x86, x86_64, the ARMs and ppc64le need to record the result of a -// cpuid/getauxval call for the asm to work correctly, unless compiled without -// asm code. + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +// x86, x86_64, and the ARMs need to record the result of a cpuid/getauxval call +// for the asm to work correctly, unless compiled without asm code. #define NEED_CPUID #else @@ -38,8 +39,7 @@ #define BORINGSSL_NO_STATIC_INITIALIZER #endif -#endif // !NO_ASM && !STATIC_ARMCAP && - // (X86 || X86_64 || ARM || AARCH64 || PPC64LE) +#endif // !NO_ASM && !STATIC_ARMCAP && (X86 || X86_64 || ARM || AARCH64) // Our assembly does not use the GOT to reference symbols, which means @@ -78,32 +78,37 @@ HIDDEN uint8_t BORINGSSL_function_hit[7] = {0}; // This value must be explicitly initialized to zero. See similar comment above. HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0}; -#elif defined(OPENSSL_PPC64LE) - -HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0; - #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) #include #if defined(OPENSSL_STATIC_ARMCAP) +// See ARM ACLE for the definitions of these macros. Note |__ARM_FEATURE_AES| +// covers both AES and PMULL and |__ARM_FEATURE_SHA2| covers SHA-1 and SHA-256. +// https://developer.arm.com/architectures/system-architectures/software-standards/acle +// https://github.com/ARM-software/acle/issues/152 +// +// TODO(davidben): Do we still need |OPENSSL_STATIC_ARMCAP_*| or are the +// standard flags and -march sufficient? HIDDEN uint32_t OPENSSL_armcap_P = -#if defined(OPENSSL_STATIC_ARMCAP_NEON) || \ - (defined(__ARM_NEON__) || defined(__ARM_NEON)) +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON) ARMV7_NEON | #endif -#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_AES) ARMV8_AES | #endif -#if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_CRYPTO) +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_AES) + ARMV8_PMULL | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_SHA2) ARMV8_SHA1 | #endif -#if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_CRYPTO) +#if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_SHA2) ARMV8_SHA256 | #endif -#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) - ARMV8_PMULL | +#if defined(__ARM_FEATURE_SHA512) + ARMV8_SHA512 | #endif 0; diff --git a/third_party/boringssl/kit/src/crypto/crypto_test.cc b/third_party/boringssl/kit/src/crypto/crypto_test.cc index 7f15a232..4543d5c1 100644 --- a/third_party/boringssl/kit/src/crypto/crypto_test.cc +++ b/third_party/boringssl/kit/src/crypto/crypto_test.cc @@ -138,3 +138,32 @@ TEST(CryptoTest, FIPSCountersEVP_AEAD) { } #endif // BORINGSSL_FIPS_COUNTERS + +TEST(Crypto, QueryAlgorithmStatus) { +#if defined(BORINGSSL_FIPS) + const bool is_fips_build = true; +#else + const bool is_fips_build = false; +#endif + + EXPECT_EQ(FIPS_query_algorithm_status("AES-GCM"), is_fips_build); + EXPECT_EQ(FIPS_query_algorithm_status("AES-ECB"), is_fips_build); + + EXPECT_FALSE(FIPS_query_algorithm_status("FakeEncrypt")); + EXPECT_FALSE(FIPS_query_algorithm_status("")); +} + +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) +TEST(Crypto, OnDemandIntegrityTest) { + BORINGSSL_integrity_test(); +} +#endif + +OPENSSL_DEPRECATED static void DeprecatedFunction() {} + +OPENSSL_BEGIN_ALLOW_DEPRECATED +TEST(CryptoTest, DeprecatedFunction) { + // This is deprecated, but should not trigger any warnings. + DeprecatedFunction(); +} +OPENSSL_END_ALLOW_DEPRECATED diff --git a/third_party/boringssl/kit/src/crypto/curve25519/asm/x25519-asm-arm.S b/third_party/boringssl/kit/src/crypto/curve25519/asm/x25519-asm-arm.S index 41bc0c6e..ab84c104 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/asm/x25519-asm-arm.S +++ b/third_party/boringssl/kit/src/crypto/curve25519/asm/x25519-asm-arm.S @@ -23,7 +23,7 @@ #endif #endif -#if !defined(OPENSSL_NO_ASM) && defined(__arm__) && !defined(__APPLE__) +#if !defined(OPENSSL_NO_ASM) && defined(__ARMEL__) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include @@ -2129,7 +2129,7 @@ mov sp,r12 vpop {q4,q5,q6,q7} bx lr -#endif /* !OPENSSL_NO_ASM && __arm__ && !__APPLE__ */ +#endif /* !OPENSSL_NO_ASM && __ARMEL__ && __ELF__ */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/src/crypto/curve25519/curve25519.c b/third_party/boringssl/kit/src/crypto/curve25519/curve25519.c index ea48810d..d1677a69 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/curve25519.c +++ b/third_party/boringssl/kit/src/crypto/curve25519/curve25519.c @@ -19,29 +19,26 @@ // // The field functions are shared by Ed25519 and X25519 where possible. -#include - #include #include -#include #include #include #include -#include #include "internal.h" #include "../internal.h" - // Various pre-computed constants. #include "./curve25519_tables.h" -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(BORINGSSL_HAS_UINT128) #include "../../third_party/fiat/curve25519_64.h" +#elif defined(OPENSSL_64_BIT) +#include "../../third_party/fiat/curve25519_64_msvc.h" #else #include "../../third_party/fiat/curve25519_32.h" -#endif // BORINGSSL_CURVE25519_64BIT +#endif // Low-level intrinsic operations @@ -66,7 +63,7 @@ static uint64_t load_4(const uint8_t *in) { // Field operations. -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) typedef uint64_t fe_limb_t; #define FE_NUM_LIMBS 5 @@ -146,10 +143,10 @@ typedef uint32_t fe_limb_t; } \ } while (0) -#endif // BORINGSSL_CURVE25519_64BIT +#endif // OPENSSL_64_BIT -OPENSSL_STATIC_ASSERT(sizeof(fe) == sizeof(fe_limb_t) * FE_NUM_LIMBS, - "fe_limb_t[FE_NUM_LIMBS] is inconsistent with fe"); +static_assert(sizeof(fe) == sizeof(fe_limb_t) * FE_NUM_LIMBS, + "fe_limb_t[FE_NUM_LIMBS] is inconsistent with fe"); static void fe_frombytes_strict(fe *h, const uint8_t s[32]) { // |fiat_25519_from_bytes| requires the top-most bit be clear. @@ -312,15 +309,9 @@ static void fe_copy(fe *h, const fe *f) { } static void fe_copy_lt(fe_loose *h, const fe *f) { - OPENSSL_STATIC_ASSERT(sizeof(fe_loose) == sizeof(fe), - "fe and fe_loose mismatch"); + static_assert(sizeof(fe_loose) == sizeof(fe), "fe and fe_loose mismatch"); OPENSSL_memmove(h, f, sizeof(fe)); } -#if !defined(OPENSSL_SMALL) -static void fe_copy_ll(fe_loose *h, const fe_loose *f) { - OPENSSL_memmove(h, f, sizeof(fe_loose)); -} -#endif // !defined(OPENSSL_SMALL) static void fe_loose_invert(fe *out, const fe_loose *z) { fe t0; @@ -503,27 +494,21 @@ static void ge_p3_tobytes(uint8_t s[32], const ge_p3 *h) { int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t s[32]) { fe u; fe_loose v; - fe v3; + fe w; fe vxx; fe_loose check; fe_frombytes(&h->Y, s); fe_1(&h->Z); - fe_sq_tt(&v3, &h->Y); - fe_mul_ttt(&vxx, &v3, &d); - fe_sub(&v, &v3, &h->Z); // u = y^2-1 + fe_sq_tt(&w, &h->Y); + fe_mul_ttt(&vxx, &w, &d); + fe_sub(&v, &w, &h->Z); // u = y^2-1 fe_carry(&u, &v); fe_add(&v, &vxx, &h->Z); // v = dy^2+1 - fe_sq_tl(&v3, &v); - fe_mul_ttl(&v3, &v3, &v); // v3 = v^3 - fe_sq_tt(&h->X, &v3); - fe_mul_ttl(&h->X, &h->X, &v); - fe_mul_ttt(&h->X, &h->X, &u); // x = uv^7 - - fe_pow22523(&h->X, &h->X); // x = (uv^7)^((q-5)/8) - fe_mul_ttt(&h->X, &h->X, &v3); - fe_mul_ttt(&h->X, &h->X, &u); // x = uv^3(uv^7)^((q-5)/8) + fe_mul_ttl(&w, &u, &v); // w = u*v + fe_pow22523(&h->X, &w); // x = w^((q-5)/8) + fe_mul_ttt(&h->X, &h->X, &u); // x = u*w^((q-5)/8) fe_sq_tt(&vxx, &h->X); fe_mul_ttl(&vxx, &vxx, &v); @@ -705,16 +690,6 @@ void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { fe_add(&r->T, &trZ, &trT); } -static uint8_t equal(signed char b, signed char c) { - uint8_t ub = b; - uint8_t uc = c; - uint8_t x = ub ^ uc; // 0: yes; 1..255: no - uint32_t y = x; // 0: yes; 1..255: no - y -= 1; // 4294967295: yes; 0..254: no - y >>= 31; // 1: yes; 0: no - return y; -} - static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) { fe_cmov(&t->yplusx, &u->yplusx, b); fe_cmov(&t->yminusx, &u->yminusx, b); @@ -761,7 +736,7 @@ void x25519_ge_scalarmult_small_precomp( ge_precomp_0(&e); for (j = 1; j < 16; j++) { - cmov(&e, &multiples[j-1], equal(index, j)); + cmov(&e, &multiples[j-1], 1&constant_time_eq_w(index, j)); } ge_cached cached; @@ -783,35 +758,36 @@ void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { #else -static uint8_t negative(signed char b) { - uint32_t x = b; - x >>= 31; // 1: yes; 0: no - return x; -} +static void table_select(ge_precomp *t, const int pos, const signed char b) { + uint8_t bnegative = constant_time_msb_w(b); + uint8_t babs = b - ((bnegative & b) << 1); + + uint8_t t_bytes[3][32] = { + {constant_time_is_zero_w(b) & 1}, {constant_time_is_zero_w(b) & 1}, {0}}; +#if defined(__clang__) // materialize for vectorization, 6% speedup + __asm__("" : "+m" (t_bytes) : /*no inputs*/); +#endif + static_assert(sizeof(t_bytes) == sizeof(k25519Precomp[pos][0]), ""); + for (int i = 0; i < 8; i++) { + constant_time_conditional_memxor(t_bytes, k25519Precomp[pos][i], + sizeof(t_bytes), + constant_time_eq_w(babs, 1 + i)); + } + + fe yplusx, yminusx, xy2d; + fe_frombytes_strict(&yplusx, t_bytes[0]); + fe_frombytes_strict(&yminusx, t_bytes[1]); + fe_frombytes_strict(&xy2d, t_bytes[2]); + + fe_copy_lt(&t->yplusx, &yplusx); + fe_copy_lt(&t->yminusx, &yminusx); + fe_copy_lt(&t->xy2d, &xy2d); -static void table_select(ge_precomp *t, int pos, signed char b) { ge_precomp minust; - uint8_t bnegative = negative(b); - uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1); - - ge_precomp_0(t); - cmov(t, &k25519Precomp[pos][0], equal(babs, 1)); - cmov(t, &k25519Precomp[pos][1], equal(babs, 2)); - cmov(t, &k25519Precomp[pos][2], equal(babs, 3)); - cmov(t, &k25519Precomp[pos][3], equal(babs, 4)); - cmov(t, &k25519Precomp[pos][4], equal(babs, 5)); - cmov(t, &k25519Precomp[pos][5], equal(babs, 6)); - cmov(t, &k25519Precomp[pos][6], equal(babs, 7)); - cmov(t, &k25519Precomp[pos][7], equal(babs, 8)); - fe_copy_ll(&minust.yplusx, &t->yminusx); - fe_copy_ll(&minust.yminusx, &t->yplusx); - - // NOTE: the input table is canonical, but types don't encode it - fe tmp; - fe_carry(&tmp, &t->xy2d); - fe_neg(&minust.xy2d, &tmp); - - cmov(t, &minust, bnegative); + fe_copy_lt(&minust.yplusx, &yminusx); + fe_copy_lt(&minust.yminusx, &yplusx); + fe_neg(&minust.xy2d, &xy2d); + cmov(t, &minust, bnegative>>7); } // h = a * B @@ -821,6 +797,18 @@ static void table_select(ge_precomp *t, int pos, signed char b) { // Preconditions: // a[31] <= 127 void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { +#if defined(BORINGSSL_FE25519_ADX) + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + uint8_t t[4][32]; + x25519_ge_scalarmult_base_adx(t, a); + fiat_25519_from_bytes(h->X.v, t[0]); + fiat_25519_from_bytes(h->Y.v, t[1]); + fiat_25519_from_bytes(h->Z.v, t[2]); + fiat_25519_from_bytes(h->T.v, t[3]); + return; + } +#endif signed char e[64]; signed char carry; ge_p1p1 r; @@ -923,7 +911,7 @@ void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) { ge_cached selected; ge_cached_0(&selected); for (j = 0; j < 16; j++) { - cmov_cached(&selected, &Ai[j], equal(j, index)); + cmov_cached(&selected, &Ai[j], 1&constant_time_eq_w(index, j)); } x25519_ge_add(&t, &u, &selected); @@ -1939,11 +1927,8 @@ int ED25519_verify(const uint8_t *message, size_t message_len, OPENSSL_memcpy(pkcopy, public_key, 32); uint8_t rcopy[32]; OPENSSL_memcpy(rcopy, signature, 32); - union { - uint64_t u64[4]; - uint8_t u8[32]; - } scopy; - OPENSSL_memcpy(&scopy.u8[0], signature + 32, 32); + uint8_t scopy[32]; + OPENSSL_memcpy(scopy, signature + 32, 32); // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in // the range [0, order) in order to prevent signature malleability. @@ -1956,9 +1941,10 @@ int ED25519_verify(const uint8_t *message, size_t message_len, UINT64_C(0x1000000000000000), }; for (size_t i = 3;; i--) { - if (scopy.u64[i] > kOrder[i]) { + uint64_t word = CRYPTO_load_u64_le(scopy + i * 8); + if (word > kOrder[i]) { return 0; - } else if (scopy.u64[i] < kOrder[i]) { + } else if (word < kOrder[i]) { break; } else if (i == 0) { return 0; @@ -1976,7 +1962,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len, x25519_sc_reduce(h); ge_p2 R; - ge_double_scalarmult_vartime(&R, h, &A, scopy.u8); + ge_double_scalarmult_vartime(&R, h, &A, scopy); uint8_t rcheck[32]; x25519_ge_tobytes(rcheck, &R); @@ -2092,6 +2078,12 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], x25519_NEON(out, scalar, point); return; } +#elif defined(BORINGSSL_FE25519_ADX) + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + x25519_scalar_mult_adx(out, scalar, point); + return; + } #endif x25519_scalar_mult_generic(out, scalar, point); @@ -2125,7 +2117,8 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], static const uint8_t kZeros[32] = {0}; x25519_scalar_mult(out_shared_key, private_key, peer_public_value); // The all-zero output results when the input is a point of small order. - return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; + return constant_time_declassify_int( + CRYPTO_memcmp(kZeros, out_shared_key, 32)) != 0; } void X25519_public_from_private(uint8_t out_public_value[32], @@ -2156,4 +2149,5 @@ void X25519_public_from_private(uint8_t out_public_value[32], fe_loose_invert(&zminusy_inv, &zminusy); fe_mul_tlt(&zminusy_inv, &zplusy, &zminusy_inv); fe_tobytes(out_public_value, &zminusy_inv); + CONSTTIME_DECLASSIFY(out_public_value, 32); } diff --git a/third_party/boringssl/kit/src/crypto/curve25519/curve25519_64_adx.c b/third_party/boringssl/kit/src/crypto/curve25519/curve25519_64_adx.c new file mode 100644 index 00000000..27689896 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/curve25519/curve25519_64_adx.c @@ -0,0 +1,18 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" +#if defined(BORINGSSL_FE25519_ADX) +#include "../../third_party/fiat/curve25519_64_adx.h" +#endif diff --git a/third_party/boringssl/kit/src/crypto/curve25519/curve25519_tables.h b/third_party/boringssl/kit/src/crypto/curve25519/curve25519_tables.h index 310581cf..6636a36a 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/curve25519_tables.h +++ b/third_party/boringssl/kit/src/crypto/curve25519/curve25519_tables.h @@ -17,7 +17,7 @@ static const fe d = {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575 #else @@ -27,7 +27,7 @@ static const fe d = {{ }}; static const fe sqrtm1 = {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133 #else @@ -37,7 +37,7 @@ static const fe sqrtm1 = {{ }}; static const fe d2 = {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903 #else @@ -142,7493 +142,2885 @@ static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = { #else // k25519Precomp[i][j] = (j+1)*256^i*B -static const ge_precomp k25519Precomp[32][8] = { +const uint8_t k25519Precomp[32][8][3][32] = { { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1288382639258501, 245678601348599, 269427782077623, - 1462984067271730, 137412439391563 -#else - 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, - 27544626, 21800161, 61029707, 2047604 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 62697248952638, 204681361388450, 631292143396476, - 338455783676468, 1213667448819585 -#else - 54563134, 934261, 64385954, 3049989, 66381436, 9406985, - 12720692, 5043384, 19500929, 18085054 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 301289933810280, 1259582250014073, 1422107436869536, - 796239922652654, 1953934009299142 -#else - 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, - 29287918, 11864899, 42594502, 29115885 -#endif - }}, + {0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0xe, 0x8c, + 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, + 0xb, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x7}, + {0x3e, 0x91, 0x40, 0xd7, 0x5, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, + 0xd1, 0x5, 0x9f, 0x39, 0xfd, 0x9, 0x8a, 0x8f, 0x68, 0x34, 0x84, + 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44}, + {0x68, 0xaa, 0x7a, 0x87, 0x5, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, + 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, + 0x1b, 0x5a, 0xa8, 0x65, 0xc, 0x9f, 0x68, 0x7b, 0x11, 0x6f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1380971894829527, 790832306631236, 2067202295274102, - 1995808275510000, 1566530869037010 -#else - 54292951, 20578084, 45527620, 11784319, 41753206, 30803714, - 55390960, 29739860, 66750418, 23343128 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 463307831301544, 432984605774163, 1610641361907204, - 750899048855000, 1894842303421586 -#else - 45405608, 6903824, 27185491, 6451973, 37531140, 24000426, - 51492312, 11189267, 40279186, 28235350 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 748439484463711, 1033211726465151, 1396005112841647, - 1611506220286469, 1972177495910992 -#else - 26966623, 11152617, 32442495, 15396054, 14353839, 20802097, - 63980037, 24013313, 51636816, 29387734 -#endif - }}, + {0xd7, 0x71, 0x3c, 0x93, 0xfc, 0xe7, 0x24, 0x92, 0xb5, 0xf5, 0xf, + 0x7a, 0x96, 0x9d, 0x46, 0x9f, 0x2, 0x7, 0xd6, 0xe1, 0x65, 0x9a, + 0xa6, 0x5a, 0x2e, 0x2e, 0x7d, 0xa8, 0x3f, 0x6, 0xc, 0x59}, + {0xa8, 0xd5, 0xb4, 0x42, 0x60, 0xa5, 0x99, 0x8a, 0xf6, 0xac, 0x60, + 0x4e, 0xc, 0x81, 0x2b, 0x8f, 0xaa, 0x37, 0x6e, 0xb1, 0x6b, 0x23, + 0x9e, 0xe0, 0x55, 0x25, 0xc9, 0x69, 0xa6, 0x95, 0xb5, 0x6b}, + {0x5f, 0x7a, 0x9b, 0xa5, 0xb3, 0xa8, 0xfa, 0x43, 0x78, 0xcf, 0x9a, + 0x5d, 0xdd, 0x6b, 0xc1, 0x36, 0x31, 0x6a, 0x3d, 0xb, 0x84, 0xa0, + 0xf, 0x50, 0x73, 0xb, 0xa5, 0x3e, 0xb1, 0xf5, 0x1a, 0x70}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1601611775252272, 1720807796594148, 1132070835939856, - 1260455018889551, 2147779492816911 -#else - 15636272, 23865875, 24204772, 25642034, 616976, 16869170, - 27787599, 18782243, 28944399, 32004408 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 316559037616741, 2177824224946892, 1459442586438991, - 1461528397712656, 751590696113597 -#else - 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, - 16354576, 21778470, 7689661, 11199574 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1850748884277385, 1200145853858453, 1068094770532492, - 672251375690438, 1586055907191707 -#else - 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, - 7512774, 10017326, 49359771, 23634074 -#endif - }}, + {0x30, 0x97, 0xee, 0x4c, 0xa8, 0xb0, 0x25, 0xaf, 0x8a, 0x4b, 0x86, + 0xe8, 0x30, 0x84, 0x5a, 0x2, 0x32, 0x67, 0x1, 0x9f, 0x2, 0x50, + 0x1b, 0xc1, 0xf4, 0xf8, 0x80, 0x9a, 0x1b, 0x4e, 0x16, 0x7a}, + {0x65, 0xd2, 0xfc, 0xa4, 0xe8, 0x1f, 0x61, 0x56, 0x7d, 0xba, 0xc1, + 0xe5, 0xfd, 0x53, 0xd3, 0x3b, 0xbd, 0xd6, 0x4b, 0x21, 0x1a, 0xf3, + 0x31, 0x81, 0x62, 0xda, 0x5b, 0x55, 0x87, 0x15, 0xb9, 0x2a}, + {0x89, 0xd8, 0xd0, 0xd, 0x3f, 0x93, 0xae, 0x14, 0x62, 0xda, 0x35, + 0x1c, 0x22, 0x23, 0x94, 0x58, 0x4c, 0xdb, 0xf2, 0x8c, 0x45, 0xe5, + 0x70, 0xd1, 0xc6, 0xb4, 0xb9, 0x12, 0xaf, 0x26, 0x28, 0x5a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 934282339813791, 1846903124198670, 1172395437954843, - 1007037127761661, 1830588347719256 -#else - 50071967, 13921891, 10945806, 27521001, 27105051, 17470053, - 38182653, 15006022, 3284568, 27277892 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1694390458783935, 1735906047636159, 705069562067493, - 648033061693059, 696214010414170 -#else - 23599295, 25248385, 55915199, 25867015, 13236773, 10506355, - 7464579, 9656445, 13059162, 10374397 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1121406372216585, 192876649532226, 190294192191717, - 1994165897297032, 2245000007398739 -#else - 7798537, 16710257, 3033922, 2874086, 28997861, 2835604, - 32406664, 29715387, 66467155, 33453106 -#endif - }}, + {0x9f, 0x9, 0xfc, 0x8e, 0xb9, 0x51, 0x73, 0x28, 0x38, 0x25, 0xfd, + 0x7d, 0xf4, 0xc6, 0x65, 0x67, 0x65, 0x92, 0xa, 0xfb, 0x3d, 0x8d, + 0x34, 0xca, 0x27, 0x87, 0xe5, 0x21, 0x3, 0x91, 0xe, 0x68}, + {0xbf, 0x18, 0x68, 0x5, 0xa, 0x5, 0xfe, 0x95, 0xa9, 0xfa, 0x60, + 0x56, 0x71, 0x89, 0x7e, 0x32, 0x73, 0x50, 0xa0, 0x6, 0xcd, 0xe3, + 0xe8, 0xc3, 0x9a, 0xa4, 0x45, 0x74, 0x4c, 0x3f, 0x93, 0x27}, + {0x9, 0xff, 0x76, 0xc4, 0xe9, 0xfb, 0x13, 0x5a, 0x72, 0xc1, 0x5c, + 0x7b, 0x45, 0x39, 0x9e, 0x6e, 0x94, 0x44, 0x2b, 0x10, 0xf9, 0xdc, + 0xdb, 0x5d, 0x2b, 0x3e, 0x55, 0x63, 0xbf, 0xc, 0x9d, 0x7f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 769950342298419, 132954430919746, 844085933195555, - 974092374476333, 726076285546016 -#else - 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, - 32867885, 14515107, 51670560, 10819379 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 425251763115706, 608463272472562, 442562545713235, - 837766094556764, 374555092627893 -#else - 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, - 41455196, 12483687, 54440373, 5581305 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1086255230780037, 274979815921559, 1960002765731872, - 929474102396301, 1190409889297339 -#else - 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, - 28542349, 13850243, 43430843, 17738489 -#endif - }}, + {0x33, 0xbb, 0xa5, 0x8, 0x44, 0xbc, 0x12, 0xa2, 0x2, 0xed, 0x5e, + 0xc7, 0xc3, 0x48, 0x50, 0x8d, 0x44, 0xec, 0xbf, 0x5a, 0xc, 0xeb, + 0x1b, 0xdd, 0xeb, 0x6, 0xe2, 0x46, 0xf1, 0xcc, 0x45, 0x29}, + {0xba, 0xd6, 0x47, 0xa4, 0xc3, 0x82, 0x91, 0x7f, 0xb7, 0x29, 0x27, + 0x4b, 0xd1, 0x14, 0x0, 0xd5, 0x87, 0xa0, 0x64, 0xb8, 0x1c, 0xf1, + 0x3c, 0xe3, 0xf3, 0x55, 0x1b, 0xeb, 0x73, 0x7e, 0x4a, 0x15}, + {0x85, 0x82, 0x2a, 0x81, 0xf1, 0xdb, 0xbb, 0xbc, 0xfc, 0xd1, 0xbd, + 0xd0, 0x7, 0x8, 0xe, 0x27, 0x2d, 0xa7, 0xbd, 0x1b, 0xb, 0x67, + 0x1b, 0xb4, 0x9a, 0xb6, 0x3b, 0x6b, 0x69, 0xbe, 0xaa, 0x43}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1388594989461809, 316767091099457, 394298842192982, - 1230079486801005, 1440737038838979 -#else - 51736881, 20691677, 32573249, 4720197, 40672342, 5875510, - 47920237, 18329612, 57289923, 21468654 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 7380825640100, 146210432690483, 304903576448906, - 1198869323871120, 997689833219095 -#else - 58559652, 109982, 15149363, 2178705, 22900618, 4543417, 3044240, - 17864545, 1762327, 14866737 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1181317918772081, 114573476638901, 262805072233344, - 265712217171332, 294181933805782 -#else - 48909169, 17603008, 56635573, 1707277, 49922944, 3916100, - 38872452, 3959420, 27914454, 4383652 -#endif - }}, + {0x31, 0x71, 0x15, 0x77, 0xeb, 0xee, 0xc, 0x3a, 0x88, 0xaf, 0xc8, + 0x0, 0x89, 0x15, 0x27, 0x9b, 0x36, 0xa7, 0x59, 0xda, 0x68, 0xb6, + 0x65, 0x80, 0xbd, 0x38, 0xcc, 0xa2, 0xb6, 0x7b, 0xe5, 0x51}, + {0xa4, 0x8c, 0x7d, 0x7b, 0xb6, 0x6, 0x98, 0x49, 0x39, 0x27, 0xd2, + 0x27, 0x84, 0xe2, 0x5b, 0x57, 0xb9, 0x53, 0x45, 0x20, 0xe7, 0x5c, + 0x8, 0xbb, 0x84, 0x78, 0x41, 0xae, 0x41, 0x4c, 0xb6, 0x38}, + {0x71, 0x4b, 0xea, 0x2, 0x67, 0x32, 0xac, 0x85, 0x1, 0xbb, 0xa1, + 0x41, 0x3, 0xe0, 0x70, 0xbe, 0x44, 0xc1, 0x3b, 0x8, 0x4b, 0xa2, + 0xe4, 0x53, 0xe3, 0x61, 0xd, 0x9f, 0x1a, 0xe9, 0xb8, 0x10}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 665000864555967, 2065379846933859, 370231110385876, - 350988370788628, 1233371373142985 -#else - 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, - 19480852, 5230134, 43156425, 18378665 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2019367628972465, 676711900706637, 110710997811333, - 1108646842542025, 517791959672113 -#else - 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, - 20654025, 16520125, 30598449, 7715701 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 965130719900578, 247011430587952, 526356006571389, - 91986625355052, 2157223321444601 -#else - 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, - 35708204, 1370707, 29794553, 32145132 -#endif - }}, + {0xbf, 0xa3, 0x4e, 0x94, 0xd0, 0x5c, 0x1a, 0x6b, 0xd2, 0xc0, 0x9d, + 0xb3, 0x3a, 0x35, 0x70, 0x74, 0x49, 0x2e, 0x54, 0x28, 0x82, 0x52, + 0xb2, 0x71, 0x7e, 0x92, 0x3c, 0x28, 0x69, 0xea, 0x1b, 0x46}, + {0xb1, 0x21, 0x32, 0xaa, 0x9a, 0x2c, 0x6f, 0xba, 0xa7, 0x23, 0xba, + 0x3b, 0x53, 0x21, 0xa0, 0x6c, 0x3a, 0x2c, 0x19, 0x92, 0x4f, 0x76, + 0xea, 0x9d, 0xe0, 0x17, 0x53, 0x2e, 0x5d, 0xdd, 0x6e, 0x1d}, + {0xa2, 0xb3, 0xb8, 0x1, 0xc8, 0x6d, 0x83, 0xf1, 0x9a, 0xa4, 0x3e, + 0x5, 0x47, 0x5f, 0x3, 0xb3, 0xf3, 0xad, 0x77, 0x58, 0xba, 0x41, + 0x9c, 0x52, 0xa7, 0x90, 0xf, 0x6a, 0x1c, 0xbb, 0x9f, 0x7a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2068619540119183, 1966274918058806, 957728544705549, - 729906502578991, 159834893065166 -#else - 14499471, 30824833, 33917750, 29299779, 28494861, 14271267, - 30290735, 10876454, 33954766, 2381725 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2073601412052185, 31021124762708, 264500969797082, - 248034690651703, 1030252227928288 -#else - 59913433, 30899068, 52378708, 462250, 39384538, 3941371, - 60872247, 3696004, 34808032, 15351954 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 551790716293402, 1989538725166328, 801169423371717, - 2052451893578887, 678432056995012 -#else - 27431194, 8222322, 16448760, 29646437, 48401861, 11938354, - 34147463, 30583916, 29551812, 10109425 -#endif - }}, + {0x8f, 0x3e, 0xdd, 0x4, 0x66, 0x59, 0xb7, 0x59, 0x2c, 0x70, 0x88, + 0xe2, 0x77, 0x3, 0xb3, 0x6c, 0x23, 0xc3, 0xd9, 0x5e, 0x66, 0x9c, + 0x33, 0xb1, 0x2f, 0xe5, 0xbc, 0x61, 0x60, 0xe7, 0x15, 0x9}, + {0xd9, 0x34, 0x92, 0xf3, 0xed, 0x5d, 0xa7, 0xe2, 0xf9, 0x58, 0xb5, + 0xe1, 0x80, 0x76, 0x3d, 0x96, 0xfb, 0x23, 0x3c, 0x6e, 0xac, 0x41, + 0x27, 0x2c, 0xc3, 0x1, 0xe, 0x32, 0xa1, 0x24, 0x90, 0x3a}, + {0x1a, 0x91, 0xa2, 0xc9, 0xd9, 0xf5, 0xc1, 0xe7, 0xd7, 0xa7, 0xcc, + 0x8b, 0x78, 0x71, 0xa3, 0xb8, 0x32, 0x2a, 0xb6, 0xe, 0x19, 0x12, + 0x64, 0x63, 0x95, 0x4e, 0xcc, 0x2e, 0x5c, 0x7c, 0x90, 0x26}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1368953770187805, 790347636712921, 437508475667162, - 2142576377050580, 1932081720066286 -#else - 53451805, 20399000, 35825113, 11777097, 21447386, 6519384, - 64730580, 31926875, 10092782, 28790261 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 953638594433374, 1092333936795051, 1419774766716690, - 805677984380077, 859228993502513 -#else - 27939166, 14210322, 4677035, 16277044, 44144402, 21156292, - 34600109, 12005537, 49298737, 12803509 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1200766035879111, 20142053207432, 1465634435977050, - 1645256912097844, 295121984874596 -#else - 17228999, 17892808, 65875336, 300139, 65883994, 21839654, - 30364212, 24516238, 18016356, 4397660 -#endif - }}, + {0x1d, 0x9c, 0x2f, 0x63, 0xe, 0xdd, 0xcc, 0x2e, 0x15, 0x31, 0x89, + 0x76, 0x96, 0xb6, 0xd0, 0x51, 0x58, 0x7a, 0x63, 0xa8, 0x6b, 0xb7, + 0xdf, 0x52, 0x39, 0xef, 0xe, 0xa0, 0x49, 0x7d, 0xd3, 0x6d}, + {0x5e, 0x51, 0xaa, 0x49, 0x54, 0x63, 0x5b, 0xed, 0x3a, 0x82, 0xc6, + 0xb, 0x9f, 0xc4, 0x65, 0xa8, 0xc4, 0xd1, 0x42, 0x5b, 0xe9, 0x1f, + 0xc, 0x85, 0xb9, 0x15, 0xd3, 0x3, 0x6f, 0x6d, 0xd7, 0x30}, + {0xc7, 0xe4, 0x6, 0x21, 0x17, 0x44, 0x44, 0x6c, 0x69, 0x7f, 0x8d, + 0x92, 0x80, 0xd6, 0x53, 0xfb, 0x26, 0x3f, 0x4d, 0x69, 0xa4, 0x9e, + 0x73, 0xb4, 0xb0, 0x4b, 0x86, 0x2e, 0x11, 0x97, 0xc6, 0x10}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1735718747031557, 1248237894295956, 1204753118328107, - 976066523550493, 65943769534592 -#else - 56150021, 25864224, 4776340, 18600194, 27850027, 17952220, - 40489757, 14544524, 49631360, 982638 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1060098822528990, 1586825862073490, 212301317240126, - 1975302711403555, 666724059764335 -#else - 29253598, 15796703, 64244882, 23645547, 10057022, 3163536, - 7332899, 29434304, 46061167, 9934962 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1091990273418756, 1572899409348578, 80968014455247, - 306009358661350, 1520450739132526 -#else - 5793284, 16271923, 42977250, 23438027, 29188559, 1206517, - 52360934, 4559894, 36984942, 22656481 -#endif - }}, + {0x5, 0xc8, 0x58, 0x83, 0xa0, 0x2a, 0xa6, 0xc, 0x47, 0x42, 0x20, + 0x7a, 0xe3, 0x4a, 0x3d, 0x6a, 0xdc, 0xed, 0x11, 0x3b, 0xa6, 0xd3, + 0x64, 0x74, 0xef, 0x6, 0x8, 0x55, 0xaf, 0x9b, 0xbf, 0x3}, + {0xde, 0x5f, 0xbe, 0x7d, 0x27, 0xc4, 0x93, 0x64, 0xa2, 0x7e, 0xad, + 0x19, 0xad, 0x4f, 0x5d, 0x26, 0x90, 0x45, 0x30, 0x46, 0xc8, 0xdf, + 0x0, 0xe, 0x9, 0xfe, 0x66, 0xed, 0xab, 0x1c, 0xe6, 0x25}, + {0x4, 0x66, 0x58, 0xcc, 0x28, 0xe1, 0x13, 0x3f, 0x7e, 0x74, 0x59, + 0xb4, 0xec, 0x73, 0x58, 0x6f, 0xf5, 0x68, 0x12, 0xcc, 0xed, 0x3d, + 0xb6, 0xa0, 0x2c, 0xe2, 0x86, 0x45, 0x63, 0x78, 0x6d, 0x56}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1480517209436112, 1511153322193952, 1244343858991172, - 304788150493241, 369136856496443 -#else - 39464912, 22061425, 16282656, 22517939, 28414020, 18542168, - 24191033, 4541697, 53770555, 5500567 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2151330273626164, 762045184746182, 1688074332551515, - 823046109005759, 907602769079491 -#else - 12650548, 32057319, 9052870, 11355358, 49428827, 25154267, - 49678271, 12264342, 10874051, 13524335 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2047386910586836, 168470092900250, 1552838872594810, - 340951180073789, 360819374702533 -#else - 25556948, 30508442, 714650, 2510400, 23394682, 23139102, - 33119037, 5080568, 44580805, 5376627 -#endif - }}, + {0xd0, 0x2f, 0x5a, 0xc6, 0x85, 0x42, 0x5, 0xa1, 0xc3, 0x67, 0x16, + 0xf3, 0x2a, 0x11, 0x64, 0x6c, 0x58, 0xee, 0x1a, 0x73, 0x40, 0xe2, + 0xa, 0x68, 0x2a, 0xb2, 0x93, 0x47, 0xf3, 0xa5, 0xfb, 0x14}, + {0x34, 0x8, 0xc1, 0x9c, 0x9f, 0xa4, 0x37, 0x16, 0x51, 0xc4, 0x9b, + 0xa8, 0xd5, 0x56, 0x8e, 0xbc, 0xdb, 0xd2, 0x7f, 0x7f, 0xf, 0xec, + 0xb5, 0x1c, 0xd9, 0x35, 0xcc, 0x5e, 0xca, 0x5b, 0x97, 0x33}, + {0xd4, 0xf7, 0x85, 0x69, 0x16, 0x46, 0xd7, 0x3c, 0x57, 0x0, 0xc8, + 0xc9, 0x84, 0x5e, 0x3e, 0x59, 0x1e, 0x13, 0x61, 0x7b, 0xb6, 0xf2, + 0xc3, 0x2f, 0x6c, 0x52, 0xfc, 0x83, 0xea, 0x9c, 0x82, 0x14}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1982622644432056, 2014393600336956, 128909208804214, - 1617792623929191, 105294281913815 -#else - 41020600, 29543379, 50095164, 30016803, 60382070, 1920896, - 44787559, 24106988, 4535767, 1569007 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 980234343912898, 1712256739246056, 588935272190264, - 204298813091998, 841798321043288 -#else - 64853442, 14606629, 45416424, 25514613, 28430648, 8775819, - 36614302, 3044289, 31848280, 12543772 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 197561292938973, 454817274782871, 1963754960082318, - 2113372252160468, 971377527342673 -#else - 45080285, 2943892, 35251351, 6777305, 13784462, 29262229, - 39731668, 31491700, 7718481, 14474653 -#endif - }}, + {0xb8, 0xec, 0x71, 0x4e, 0x2f, 0xb, 0xe7, 0x21, 0xe3, 0x77, 0xa4, + 0x40, 0xb9, 0xdd, 0x56, 0xe6, 0x80, 0x4f, 0x1d, 0xce, 0xce, 0x56, + 0x65, 0xbf, 0x7e, 0x7b, 0x5d, 0x53, 0xc4, 0x3b, 0xfc, 0x5}, + {0xc2, 0x95, 0xdd, 0x97, 0x84, 0x7b, 0x43, 0xff, 0xa7, 0xb5, 0x4e, + 0xaa, 0x30, 0x4e, 0x74, 0x6c, 0x8b, 0xe8, 0x85, 0x3c, 0x61, 0x5d, + 0xc, 0x9e, 0x73, 0x81, 0x75, 0x5f, 0x1e, 0xc7, 0xd9, 0x2f}, + {0xdd, 0xde, 0xaf, 0x52, 0xae, 0xb3, 0xb8, 0x24, 0xcf, 0x30, 0x3b, + 0xed, 0x8c, 0x63, 0x95, 0x34, 0x95, 0x81, 0xbe, 0xa9, 0x83, 0xbc, + 0xa4, 0x33, 0x4, 0x1f, 0x65, 0x5c, 0x47, 0x67, 0x37, 0x37}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 164699448829328, 3127451757672, 1199504971548753, - 1766155447043652, 1899238924683527 -#else - 2385296, 2454213, 44477544, 46602, 62670929, 17874016, 656964, - 26317767, 24316167, 28300865 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 732262946680281, 1674412764227063, 2182456405662809, - 1350894754474250, 558458873295247 -#else - 13741529, 10911568, 33875447, 24950694, 46931033, 32521134, - 33040650, 20129900, 46379407, 8321685 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2103305098582922, 1960809151316468, 715134605001343, - 1454892949167181, 40827143824949 -#else - 21060490, 31341688, 15712756, 29218333, 1639039, 10656336, - 23845965, 21679594, 57124405, 608371 -#endif - }}, + {0x90, 0x65, 0x24, 0x14, 0xcb, 0x95, 0x40, 0x63, 0x35, 0x55, 0xc1, + 0x16, 0x40, 0x14, 0x12, 0xef, 0x60, 0xbc, 0x10, 0x89, 0xc, 0x14, + 0x38, 0x9e, 0x8c, 0x7c, 0x90, 0x30, 0x57, 0x90, 0xf5, 0x6b}, + {0xd9, 0xad, 0xd1, 0x40, 0xfd, 0x99, 0xba, 0x2f, 0x27, 0xd0, 0xf4, + 0x96, 0x6f, 0x16, 0x7, 0xb3, 0xae, 0x3b, 0xf0, 0x15, 0x52, 0xf0, + 0x63, 0x43, 0x99, 0xf9, 0x18, 0x3b, 0x6c, 0xa5, 0xbe, 0x1f}, + {0x8a, 0x5b, 0x41, 0xe1, 0xf1, 0x78, 0xa7, 0xf, 0x7e, 0xa7, 0xc3, + 0xba, 0xf7, 0x9f, 0x40, 0x6, 0x50, 0x9a, 0xa2, 0x9a, 0xb8, 0xd7, + 0x52, 0x6f, 0x56, 0x5a, 0x63, 0x7a, 0xf6, 0x1c, 0x52, 0x2}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1239289043050212, 1744654158124578, 758702410031698, - 1796762995074688, 1603056663766 -#else - 53436132, 18466845, 56219170, 25997372, 61071954, 11305546, - 1123968, 26773855, 27229398, 23887 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2232056027107988, 987343914584615, 2115594492994461, - 1819598072792159, 1119305654014850 -#else - 43864724, 33260226, 55364135, 14712570, 37643165, 31524814, - 12797023, 27114124, 65475458, 16678953 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 320153677847348, 939613871605645, 641883205761567, - 1930009789398224, 329165806634126 -#else - 37608244, 4770661, 51054477, 14001337, 7830047, 9564805, - 65600720, 28759386, 49939598, 4904952 -#endif - }}, + {0xe4, 0x5e, 0x2f, 0x77, 0x20, 0x67, 0x14, 0xb1, 0xce, 0x9a, 0x7, + 0x96, 0xb1, 0x94, 0xf8, 0xe8, 0x4a, 0x82, 0xac, 0x0, 0x4d, 0x22, + 0xf8, 0x4a, 0xc4, 0x6c, 0xcd, 0xf7, 0xd9, 0x53, 0x17, 0x0}, + {0x94, 0x52, 0x9d, 0xa, 0xb, 0xee, 0x3f, 0x51, 0x66, 0x5a, 0xdf, + 0xf, 0x5c, 0xe7, 0x98, 0x8f, 0xce, 0x7, 0xe1, 0xbf, 0x88, 0x86, + 0x61, 0xd4, 0xed, 0x2c, 0x38, 0x71, 0x7e, 0xa, 0xa0, 0x3f}, + {0x34, 0xdb, 0x3d, 0x96, 0x2d, 0x23, 0x69, 0x3c, 0x58, 0x38, 0x97, + 0xb4, 0xda, 0x87, 0xde, 0x1d, 0x85, 0xf2, 0x91, 0xa0, 0xf9, 0xd1, + 0xd7, 0xaa, 0xb6, 0xed, 0x48, 0xa0, 0x2f, 0xfe, 0xb5, 0x12}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 980930490474130, 1242488692177893, 1251446316964684, - 1086618677993530, 1961430968465772 -#else - 24059538, 14617003, 19037157, 18514524, 19766092, 18648003, - 5169210, 16191880, 2128236, 29227599 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 276821765317453, 1536835591188030, 1305212741412361, - 61473904210175, 2051377036983058 -#else - 50127693, 4124965, 58568254, 22900634, 30336521, 19449185, - 37302527, 916032, 60226322, 30567899 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 833449923882501, 1750270368490475, 1123347002068295, - 185477424765687, 278090826653186 -#else - 44477957, 12419371, 59974635, 26081060, 50629959, 16739174, - 285431, 2763829, 15736322, 4143876 -#endif - }}, + {0x92, 0x1e, 0x6f, 0xad, 0x26, 0x7c, 0x2b, 0xdf, 0x13, 0x89, 0x4b, + 0x50, 0x23, 0xd3, 0x66, 0x4b, 0xc3, 0x8b, 0x1c, 0x75, 0xc0, 0x9d, + 0x40, 0x8c, 0xb8, 0xc7, 0x96, 0x7, 0xc2, 0x93, 0x7e, 0x6f}, + {0x4d, 0xe3, 0xfc, 0x96, 0xc4, 0xfb, 0xf0, 0x71, 0xed, 0x5b, 0xf3, + 0xad, 0x6b, 0x82, 0xb9, 0x73, 0x61, 0xc5, 0x28, 0xff, 0x61, 0x72, + 0x4, 0xd2, 0x6f, 0x20, 0xb1, 0x6f, 0xf9, 0x76, 0x9b, 0x74}, + {0x5, 0xae, 0xa6, 0xae, 0x4, 0xf6, 0x5a, 0x1f, 0x99, 0x9c, 0xe4, + 0xbe, 0xf1, 0x51, 0x23, 0xc1, 0x66, 0x6b, 0xff, 0xee, 0xb5, 0x8, + 0xa8, 0x61, 0x51, 0x21, 0xe0, 0x1, 0xf, 0xc1, 0xce, 0xf}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 794524995833413, 1849907304548286, 53348672473145, - 1272368559505217, 1147304168324779 -#else - 2379333, 11839345, 62998462, 27565766, 11274297, 794957, 212801, - 18959769, 23527083, 17096164 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1504846112759364, 1203096289004681, 562139421471418, - 274333017451844, 1284344053775441 -#else - 33431108, 22423954, 49269897, 17927531, 8909498, 8376530, - 34483524, 4087880, 51919953, 19138217 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 483048732424432, 2116063063343382, 30120189902313, - 292451576741007, 1156379271702225 -#else - 1767664, 7197987, 53903638, 31531796, 54017513, 448825, 5799055, - 4357868, 62334673, 17231393 -#endif - }}, + {0x45, 0x4e, 0x24, 0xc4, 0x9d, 0xd2, 0xf2, 0x3d, 0xa, 0xde, 0xd8, + 0x93, 0x74, 0xe, 0x2, 0x2b, 0x4d, 0x21, 0xc, 0x82, 0x7e, 0x6, + 0xc8, 0x6c, 0xa, 0xb9, 0xea, 0x6f, 0x16, 0x79, 0x37, 0x41}, + {0x44, 0x1e, 0xfe, 0x49, 0xa6, 0x58, 0x4d, 0x64, 0x7e, 0x77, 0xad, + 0x31, 0xa2, 0xae, 0xfc, 0x21, 0xd2, 0xd0, 0x7f, 0x88, 0x5a, 0x1c, + 0x44, 0x2, 0xf3, 0x11, 0xc5, 0x83, 0x71, 0xaa, 0x1, 0x49}, + {0xf0, 0xf8, 0x1a, 0x8c, 0x54, 0xb7, 0xb1, 0x8, 0xb4, 0x99, 0x62, + 0x24, 0x7c, 0x7a, 0xf, 0xce, 0x39, 0xd9, 0x6, 0x1e, 0xf9, 0xb0, + 0x60, 0xf7, 0x13, 0x12, 0x6d, 0x72, 0x7b, 0x88, 0xbb, 0x41}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 928372153029038, 2147692869914564, 1455665844462196, - 1986737809425946, 185207050258089 -#else - 6721966, 13833823, 43585476, 32003117, 26354292, 21691111, - 23365146, 29604700, 7390889, 2759800 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 137732961814206, 706670923917341, 1387038086865771, - 1965643813686352, 1384777115696347 -#else - 4409022, 2052381, 23373853, 10530217, 7676779, 20668478, - 21302352, 29290375, 1244379, 20634787 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 481144981981577, 2053319313589856, 2065402289827512, - 617954271490316, 1106602634668125 -#else - 62687625, 7169618, 4982368, 30596842, 30256824, 30776892, - 14086412, 9208236, 15886429, 16489664 -#endif - }}, + {0xae, 0x91, 0x66, 0x7c, 0x59, 0x4c, 0x23, 0x7e, 0xc8, 0xb4, 0x85, + 0xa, 0x3d, 0x9d, 0x88, 0x64, 0xe7, 0xfa, 0x4a, 0x35, 0xc, 0xc9, + 0xe2, 0xda, 0x1d, 0x9e, 0x6a, 0xc, 0x7, 0x1e, 0x87, 0xa}, + {0xbe, 0x46, 0x43, 0x74, 0x44, 0x7d, 0xe8, 0x40, 0x25, 0x2b, 0xb5, + 0x15, 0xd4, 0xda, 0x48, 0x1d, 0x3e, 0x60, 0x3b, 0xa1, 0x18, 0x8a, + 0x3a, 0x7c, 0xf7, 0xbd, 0xcd, 0x2f, 0xc1, 0x28, 0xb7, 0x4e}, + {0x89, 0x89, 0xbc, 0x4b, 0x99, 0xb5, 0x1, 0x33, 0x60, 0x42, 0xdd, + 0x5b, 0x3a, 0xae, 0x6b, 0x73, 0x3c, 0x9e, 0xd5, 0x19, 0xe2, 0xad, + 0x61, 0xd, 0x64, 0xd4, 0x85, 0x26, 0xf, 0x30, 0xe7, 0x3e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 696298019648792, 893299659040895, 1148636718636009, - 26734077349617, 2203955659340681 -#else - 1996056, 10375649, 14346367, 13311202, 60234729, 17116020, - 53415665, 398368, 36502409, 32841498 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 657390353372855, 998499966885562, 991893336905797, - 810470207106761, 343139804608786 -#else - 41801399, 9795879, 64331450, 14878808, 33577029, 14780362, - 13348553, 12076947, 36272402, 5113181 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 791736669492960, 934767652997115, 824656780392914, - 1759463253018643, 361530362383518 -#else - 49338080, 11797795, 31950843, 13929123, 41220562, 12288343, - 36767763, 26218045, 13847710, 5387222 -#endif - }}, + {0x18, 0x75, 0x1e, 0x84, 0x47, 0x79, 0xfa, 0x43, 0xd7, 0x46, 0x9c, + 0x63, 0x59, 0xfa, 0xc6, 0xe5, 0x74, 0x2b, 0x5, 0xe3, 0x1d, 0x5e, + 0x6, 0xa1, 0x30, 0x90, 0xb8, 0xcf, 0xa2, 0xc6, 0x47, 0x7d}, + {0xb7, 0xd6, 0x7d, 0x9e, 0xe4, 0x55, 0xd2, 0xf5, 0xac, 0x1e, 0xb, + 0x61, 0x5c, 0x11, 0x16, 0x80, 0xca, 0x87, 0xe1, 0x92, 0x5d, 0x97, + 0x99, 0x3c, 0xc2, 0x25, 0x91, 0x97, 0x62, 0x57, 0x81, 0x13}, + {0xe0, 0xd6, 0xf0, 0x8e, 0x14, 0xd0, 0xda, 0x3f, 0x3c, 0x6f, 0x54, + 0x91, 0x9a, 0x74, 0x3e, 0x9d, 0x57, 0x81, 0xbb, 0x26, 0x10, 0x62, + 0xec, 0x71, 0x80, 0xec, 0xc9, 0x34, 0x8d, 0xf5, 0x8c, 0x14}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2022541353055597, 2094700262587466, 1551008075025686, - 242785517418164, 695985404963562 -#else - 48526701, 30138214, 17824842, 31213466, 22744342, 23111821, - 8763060, 3617786, 47508202, 10370990 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1287487199965223, 2215311941380308, 1552928390931986, - 1664859529680196, 1125004975265243 -#else - 20246567, 19185054, 22358228, 33010720, 18507282, 23140436, - 14554436, 24808340, 32232923, 16763880 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 677434665154918, 989582503122485, 1817429540898386, - 1052904935475344, 1143826298169798 -#else - 9648486, 10094563, 26416693, 14745928, 36734546, 27081810, - 11094160, 15689506, 3140038, 17044340 -#endif - }}, + {0x6d, 0x75, 0xe4, 0x9a, 0x7d, 0x2f, 0x57, 0xe2, 0x7f, 0x48, 0xf3, + 0x88, 0xbb, 0x45, 0xc3, 0x56, 0x8d, 0xa8, 0x60, 0x69, 0x6d, 0xb, + 0xd1, 0x9f, 0xb9, 0xa1, 0xae, 0x4e, 0xad, 0xeb, 0x8f, 0x27}, + {0x27, 0xf0, 0x34, 0x79, 0xf6, 0x92, 0xa4, 0x46, 0xa9, 0xa, 0x84, + 0xf6, 0xbe, 0x84, 0x99, 0x46, 0x54, 0x18, 0x61, 0x89, 0x2a, 0xbc, + 0xa1, 0x5c, 0xd4, 0xbb, 0x5d, 0xbd, 0x1e, 0xfa, 0xf2, 0x3f}, + {0x66, 0x39, 0x93, 0x8c, 0x1f, 0x68, 0xaa, 0xb1, 0x98, 0xc, 0x29, + 0x20, 0x9c, 0x94, 0x21, 0x8c, 0x52, 0x3c, 0x9d, 0x21, 0x91, 0x52, + 0x11, 0x39, 0x7b, 0x67, 0x9c, 0xfe, 0x2, 0xdd, 0x4, 0x41}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 367266328308408, 318431188922404, 695629353755355, - 634085657580832, 24581612564426 -#else - 50948792, 5472694, 31895588, 4744994, 8823515, 10365685, - 39884064, 9448612, 38334410, 366294 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 773360688841258, 1815381330538070, 363773437667376, - 539629987070205, 783280434248437 -#else - 19153450, 11523972, 56012374, 27051289, 42461232, 5420646, - 28344573, 8041113, 719605, 11671788 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 180820816194166, 168937968377394, 748416242794470, - 1227281252254508, 1567587861004268 -#else - 8678006, 2694440, 60300850, 2517371, 4964326, 11152271, - 51675948, 18287915, 27000812, 23358879 -#endif - }}, + {0xb8, 0x6a, 0x9, 0xdb, 0x6, 0x4e, 0x21, 0x81, 0x35, 0x4f, 0xe4, + 0xc, 0xc9, 0xb6, 0xa8, 0x21, 0xf5, 0x2a, 0x9e, 0x40, 0x2a, 0xc1, + 0x24, 0x65, 0x81, 0xa4, 0xfc, 0x8e, 0xa4, 0xb5, 0x65, 0x1}, + {0x2a, 0x42, 0x24, 0x11, 0x5e, 0xbf, 0xb2, 0x72, 0xb5, 0x3a, 0xa3, + 0x98, 0x33, 0xc, 0xfa, 0xa1, 0x66, 0xb6, 0x52, 0xfa, 0x1, 0x61, + 0xcb, 0x94, 0xd5, 0x53, 0xaf, 0xaf, 0x0, 0x3b, 0x86, 0x2c}, + {0x76, 0x6a, 0x84, 0xa0, 0x74, 0xa4, 0x90, 0xf1, 0xc0, 0x7c, 0x2f, + 0xcd, 0x84, 0xf9, 0xef, 0x12, 0x8f, 0x2b, 0xaa, 0x58, 0x6, 0x29, + 0x5e, 0x69, 0xb8, 0xc8, 0xfe, 0xbf, 0xd9, 0x67, 0x1b, 0x59}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 478775558583645, 2062896624554807, 699391259285399, - 358099408427873, 1277310261461761 -#else - 51950941, 7134311, 8639287, 30739555, 59873175, 10421741, - 564065, 5336097, 6750977, 19033406 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1984740906540026, 1079164179400229, 1056021349262661, - 1659958556483663, 1088529069025527 -#else - 11836410, 29574944, 26297893, 16080799, 23455045, 15735944, - 1695823, 24735310, 8169719, 16220347 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 580736401511151, 1842931091388998, 1177201471228238, - 2075460256527244, 1301133425678027 -#else - 48993007, 8653646, 17578566, 27461813, 59083086, 17541668, - 55964556, 30926767, 61118155, 19388398 -#endif - }}, + {0x5d, 0xb5, 0x18, 0x9f, 0x71, 0xb3, 0xb9, 0x99, 0x1e, 0x64, 0x8c, + 0xa1, 0xfa, 0xe5, 0x65, 0xe4, 0xed, 0x5, 0x9f, 0xc2, 0x36, 0x11, + 0x8, 0x61, 0x8b, 0x12, 0x30, 0x70, 0x86, 0x4f, 0x9b, 0x48}, + {0xfa, 0x9b, 0xb4, 0x80, 0x1c, 0xd, 0x2f, 0x31, 0x8a, 0xec, 0xf3, + 0xab, 0x5e, 0x51, 0x79, 0x59, 0x88, 0x1c, 0xf0, 0x9e, 0xc0, 0x33, + 0x70, 0x72, 0xcb, 0x7b, 0x8f, 0xca, 0xc7, 0x2e, 0xe0, 0x3d}, + {0xef, 0x92, 0xeb, 0x3a, 0x2d, 0x10, 0x32, 0xd2, 0x61, 0xa8, 0x16, + 0x61, 0xb4, 0x53, 0x62, 0xe1, 0x24, 0xaa, 0xb, 0x19, 0xe7, 0xab, + 0x7e, 0x3d, 0xbf, 0xbe, 0x6c, 0x49, 0xba, 0xfb, 0xf5, 0x49}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1515728832059182, 1575261009617579, 1510246567196186, - 191078022609704, 116661716289141 -#else - 43800366, 22586119, 15213227, 23473218, 36255258, 22504427, - 27884328, 2847284, 2655861, 1738395 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1295295738269652, 1714742313707026, 545583042462581, - 2034411676262552, 1513248090013606 -#else - 39571412, 19301410, 41772562, 25551651, 57738101, 8129820, - 21651608, 30315096, 48021414, 22549153 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 230710545179830, 30821514358353, 760704303452229, - 390668103790604, 573437871383156 -#else - 1533110, 3437855, 23735889, 459276, 29970501, 11335377, - 26030092, 5821408, 10478196, 8544890 -#endif - }}, + {0x2e, 0x57, 0x9c, 0x1e, 0x8c, 0x62, 0x5d, 0x15, 0x41, 0x47, 0x88, + 0xc5, 0xac, 0x86, 0x4d, 0x8a, 0xeb, 0x63, 0x57, 0x51, 0xf6, 0x52, + 0xa3, 0x91, 0x5b, 0x51, 0x67, 0x88, 0xc2, 0xa6, 0xa1, 0x6}, + {0xd4, 0xcf, 0x5b, 0x8a, 0x10, 0x9a, 0x94, 0x30, 0xeb, 0x73, 0x64, + 0xbc, 0x70, 0xdd, 0x40, 0xdc, 0x1c, 0xd, 0x7c, 0x30, 0xc1, 0x94, + 0xc2, 0x92, 0x74, 0x6e, 0xfa, 0xcb, 0x6d, 0xa8, 0x4, 0x56}, + {0xb6, 0x64, 0x17, 0x7c, 0xd4, 0xd1, 0x88, 0x72, 0x51, 0x8b, 0x41, + 0xe0, 0x40, 0x11, 0x54, 0x72, 0xd1, 0xf6, 0xac, 0x18, 0x60, 0x1a, + 0x3, 0x9f, 0xc6, 0x42, 0x27, 0xfe, 0x89, 0x9e, 0x98, 0x20}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1169380107545646, 263167233745614, 2022901299054448, - 819900753251120, 2023898464874585 -#else - 32173102, 17425121, 24896206, 3921497, 22579056, 30143578, - 19270448, 12217473, 17789017, 30158437 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2102254323485823, 1570832666216754, 34696906544624, - 1993213739807337, 70638552271463 -#else - 36555903, 31326030, 51530034, 23407230, 13243888, 517024, - 15479401, 29701199, 30460519, 1052596 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 894132856735058, 548675863558441, 845349339503395, - 1942269668326667, 1615682209874691 -#else - 55493970, 13323617, 32618793, 8175907, 51878691, 12596686, - 27491595, 28942073, 3179267, 24075541 -#endif - }}, + {0x2e, 0xec, 0xea, 0x85, 0x8b, 0x27, 0x74, 0x16, 0xdf, 0x2b, 0xcb, + 0x7a, 0x7, 0xdc, 0x21, 0x56, 0x5a, 0xf4, 0xcb, 0x61, 0x16, 0x4c, + 0xa, 0x64, 0xd3, 0x95, 0x5, 0xf7, 0x50, 0x99, 0xb, 0x73}, + {0x7f, 0xcc, 0x2d, 0x3a, 0xfd, 0x77, 0x97, 0x49, 0x92, 0xd8, 0x4f, + 0xa5, 0x2c, 0x7c, 0x85, 0x32, 0xa0, 0xe3, 0x7, 0xd2, 0x64, 0xd8, + 0x79, 0xa2, 0x29, 0x7e, 0xa6, 0xc, 0x1d, 0xed, 0x3, 0x4}, + {0x52, 0xc5, 0x4e, 0x87, 0x35, 0x2d, 0x4b, 0xc9, 0x8d, 0x6f, 0x24, + 0x98, 0xcf, 0xc8, 0xe6, 0xc5, 0xce, 0x35, 0xc0, 0x16, 0xfa, 0x46, + 0xcb, 0xf7, 0xcc, 0x3d, 0x30, 0x8, 0x43, 0x45, 0xd7, 0x5b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1287670217537834, 1222355136884920, 1846481788678694, - 1150426571265110, 1613523400722047 -#else - 31947050, 19187781, 62468280, 18214510, 51982886, 27514722, - 52352086, 17142691, 19072639, 24043372 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 793388516527298, 1315457083650035, 1972286999342417, - 1901825953052455, 338269477222410 -#else - 11685058, 11822410, 3158003, 19601838, 33402193, 29389366, - 5977895, 28339415, 473098, 5040608 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 550201530671806, 778605267108140, 2063911101902983, - 115500557286349, 2041641272971022 -#else - 46817982, 8198641, 39698732, 11602122, 1290375, 30754672, - 28326861, 1721092, 47550222, 30422825 -#endif - }}, + {0x2a, 0x79, 0xe7, 0x15, 0x21, 0x93, 0xc4, 0x85, 0xc9, 0xdd, 0xcd, + 0xbd, 0xa2, 0x89, 0x4c, 0xc6, 0x62, 0xd7, 0xa3, 0xad, 0xa8, 0x3d, + 0x1e, 0x9d, 0x2c, 0xf8, 0x67, 0x30, 0x12, 0xdb, 0xb7, 0x5b}, + {0xc2, 0x4c, 0xb2, 0x28, 0x95, 0xd1, 0x9a, 0x7f, 0x81, 0xc1, 0x35, + 0x63, 0x65, 0x54, 0x6b, 0x7f, 0x36, 0x72, 0xc0, 0x4f, 0x6e, 0xb6, + 0xb8, 0x66, 0x83, 0xad, 0x80, 0x73, 0x0, 0x78, 0x3a, 0x13}, + {0xbe, 0x62, 0xca, 0xc6, 0x67, 0xf4, 0x61, 0x9, 0xee, 0x52, 0x19, + 0x21, 0xd6, 0x21, 0xec, 0x4, 0x70, 0x47, 0xd5, 0x9b, 0x77, 0x60, + 0x23, 0x18, 0xd2, 0xe0, 0xf0, 0x58, 0x6d, 0xca, 0xd, 0x74}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 717255318455100, 519313764361315, 2080406977303708, - 541981206705521, 774328150311600 -#else - 7881532, 10687937, 7578723, 7738378, 48157852, 31000479, - 21820785, 8076149, 39240368, 11538388 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 261715221532238, 1795354330069993, 1496878026850283, - 499739720521052, 389031152673770 -#else - 47173198, 3899860, 18283497, 26752864, 51380203, 22305220, - 8754524, 7446702, 61432810, 5797015 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1997217696294013, 1717306351628065, 1684313917746180, - 1644426076011410, 1857378133465451 -#else - 55813245, 29760862, 51326753, 25589858, 12708868, 25098233, - 2014098, 24503858, 64739691, 27677090 -#endif - }}, + {0x3c, 0x43, 0x78, 0x4, 0x57, 0x8c, 0x1a, 0x23, 0x9d, 0x43, 0x81, + 0xc2, 0xe, 0x27, 0xb5, 0xb7, 0x9f, 0x7, 0xd9, 0xe3, 0xea, 0x99, + 0xaa, 0xdb, 0xd9, 0x3, 0x2b, 0x6c, 0x25, 0xf5, 0x3, 0x2c}, + {0x4e, 0xce, 0xcf, 0x52, 0x7, 0xee, 0x48, 0xdf, 0xb7, 0x8, 0xec, + 0x6, 0xf3, 0xfa, 0xff, 0xc3, 0xc4, 0x59, 0x54, 0xb9, 0x2a, 0xb, + 0x71, 0x5, 0x8d, 0xa3, 0x3e, 0x96, 0xfa, 0x25, 0x1d, 0x16}, + {0x7d, 0xa4, 0x53, 0x7b, 0x75, 0x18, 0xf, 0x79, 0x79, 0x58, 0xc, + 0xcf, 0x30, 0x1, 0x7b, 0x30, 0xf9, 0xf7, 0x7e, 0x25, 0x77, 0x3d, + 0x90, 0x31, 0xaf, 0xbb, 0x96, 0xbd, 0xbd, 0x68, 0x94, 0x69}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1475434724792648, 76931896285979, 1116729029771667, - 2002544139318042, 725547833803938 -#else - 44636488, 21985690, 39426843, 1146374, 18956691, 16640559, - 1192730, 29840233, 15123618, 10811505 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2022306639183567, 726296063571875, 315345054448644, - 1058733329149221, 1448201136060677 -#else - 14352079, 30134717, 48166819, 10822654, 32750596, 4699007, - 67038501, 15776355, 38222085, 21579878 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1710065158525665, 1895094923036397, 123988286168546, - 1145519900776355, 1607510767693874 -#else - 38867681, 25481956, 62129901, 28239114, 29416930, 1847569, - 46454691, 17069576, 4714546, 23953777 -#endif - }}, + {0x48, 0x19, 0xa9, 0x6a, 0xe6, 0x3d, 0xdd, 0xd8, 0xcc, 0xd2, 0xc0, + 0x2f, 0xc2, 0x64, 0x50, 0x48, 0x2f, 0xea, 0xfd, 0x34, 0x66, 0x24, + 0x48, 0x9b, 0x3a, 0x2e, 0x4a, 0x6c, 0x4e, 0x1c, 0x3e, 0x29}, + {0xcf, 0xfe, 0xda, 0xf4, 0x46, 0x2f, 0x1f, 0xbd, 0xf7, 0xd6, 0x7f, + 0xa4, 0x14, 0x1, 0xef, 0x7c, 0x7f, 0xb3, 0x47, 0x4a, 0xda, 0xfd, + 0x1f, 0xd3, 0x85, 0x57, 0x90, 0x73, 0xa4, 0x19, 0x52, 0x52}, + {0xe1, 0x12, 0x51, 0x92, 0x4b, 0x13, 0x6e, 0x37, 0xa0, 0x5d, 0xa1, + 0xdc, 0xb5, 0x78, 0x37, 0x70, 0x11, 0x31, 0x1c, 0x46, 0xaf, 0x89, + 0x45, 0xb0, 0x23, 0x28, 0x3, 0x7f, 0x44, 0x5c, 0x60, 0x5b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 561605375422540, 1071733543815037, 131496498800990, - 1946868434569999, 828138133964203 -#else - 15200332, 8368572, 19679101, 15970074, 35236190, 1959450, - 24611599, 29010600, 55362987, 12340219 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1548495173745801, 442310529226540, 998072547000384, - 553054358385281, 644824326376171 -#else - 12876937, 23074376, 33134380, 6590940, 60801088, 14872439, - 9613953, 8241152, 15370987, 9608631 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1445526537029440, 2225519789662536, 914628859347385, - 1064754194555068, 1660295614401091 -#else - 62965568, 21540023, 8446280, 33162829, 4407737, 13629032, - 59383996, 15866073, 38898243, 24740332 -#endif - }}, + {0x4c, 0xf0, 0xe7, 0xf0, 0xc6, 0xfe, 0xe9, 0x3b, 0x62, 0x49, 0xe3, + 0x75, 0x9e, 0x57, 0x6a, 0x86, 0x1a, 0xe6, 0x1d, 0x1e, 0x16, 0xef, + 0x42, 0x55, 0xd5, 0xbd, 0x5a, 0xcc, 0xf4, 0xfe, 0x12, 0x2f}, + {0x89, 0x7c, 0xc4, 0x20, 0x59, 0x80, 0x65, 0xb9, 0xcc, 0x8f, 0x3b, + 0x92, 0xc, 0x10, 0xf0, 0xe7, 0x77, 0xef, 0xe2, 0x2, 0x65, 0x25, + 0x1, 0x0, 0xee, 0xb3, 0xae, 0xa8, 0xce, 0x6d, 0xa7, 0x24}, + {0x40, 0xc7, 0xc0, 0xdf, 0xb2, 0x22, 0x45, 0xa, 0x7, 0xa4, 0xc9, + 0x40, 0x7f, 0x6e, 0xd0, 0x10, 0x68, 0xf6, 0xcf, 0x78, 0x41, 0x14, + 0xcf, 0xc6, 0x90, 0x37, 0xa4, 0x18, 0x25, 0x7b, 0x60, 0x5e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1199690223111956, 24028135822341, 66638289244341, - 57626156285975, 565093967979607 -#else - 26660628, 17876777, 8393733, 358047, 59707573, 992987, 43204631, - 858696, 20571223, 8420556 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 876926774220824, 554618976488214, 1012056309841565, - 839961821554611, 1414499340307677 -#else - 14620696, 13067227, 51661590, 8264466, 14106269, 15080814, - 33531827, 12516406, 45534429, 21077682 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 703047626104145, 1266841406201770, 165556500219173, - 486991595001879, 1011325891650656 -#else - 236881, 10476226, 57258, 18877408, 6472997, 2466984, 17258519, - 7256740, 8791136, 15069930 -#endif - }}, + {0x14, 0xcf, 0x96, 0xa5, 0x1c, 0x43, 0x2c, 0xa0, 0x0, 0xe4, 0xd3, + 0xae, 0x40, 0x2d, 0xc4, 0xe3, 0xdb, 0x26, 0xf, 0x2e, 0x80, 0x26, + 0x45, 0xd2, 0x68, 0x70, 0x45, 0x9e, 0x13, 0x33, 0x1f, 0x20}, + {0x18, 0x18, 0xdf, 0x6c, 0x8f, 0x1d, 0xb3, 0x58, 0xa2, 0x58, 0x62, + 0xc3, 0x4f, 0xa7, 0xcf, 0x35, 0x6e, 0x1d, 0xe6, 0x66, 0x4f, 0xff, + 0xb3, 0xe1, 0xf7, 0xd5, 0xcd, 0x6c, 0xab, 0xac, 0x67, 0x50}, + {0x51, 0x9d, 0x3, 0x8, 0x6b, 0x7f, 0x52, 0xfd, 0x6, 0x0, 0x7c, + 0x1, 0x64, 0x49, 0xb1, 0x18, 0xa8, 0xa4, 0x25, 0x2e, 0xb0, 0xe, + 0x22, 0xd5, 0x75, 0x3, 0x46, 0x62, 0x88, 0xba, 0x7c, 0x39}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1622861044480487, 1156394801573634, 1869132565415504, - 327103985777730, 2095342781472284 -#else - 1276391, 24182514, 22949634, 17231625, 43615824, 27852245, - 14711874, 4874229, 36445724, 31223040 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 334886927423922, 489511099221528, 129160865966726, - 1720809113143481, 619700195649254 -#else - 5855666, 4990204, 53397016, 7294283, 59304582, 1924646, - 65685689, 25642053, 34039526, 9234252 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1646545795166119, 1758370782583567, 714746174550637, - 1472693650165135, 898994790308209 -#else - 20590503, 24535444, 31529743, 26201766, 64402029, 10650547, - 31559055, 21944845, 18979185, 13396066 -#endif - }}, + {0xe7, 0x79, 0x13, 0xc8, 0xfb, 0xc3, 0x15, 0x78, 0xf1, 0x2a, 0xe1, + 0xdd, 0x20, 0x94, 0x61, 0xa6, 0xd5, 0xfd, 0xa8, 0x85, 0xf8, 0xc0, + 0xa9, 0xff, 0x52, 0xc2, 0xe1, 0xc1, 0x22, 0x40, 0x1b, 0x77}, + {0xb2, 0x59, 0x59, 0xf0, 0x93, 0x30, 0xc1, 0x30, 0x76, 0x79, 0xa9, + 0xe9, 0x8d, 0xa1, 0x3a, 0xe2, 0x26, 0x5e, 0x1d, 0x72, 0x91, 0xd4, + 0x2f, 0x22, 0x3a, 0x6c, 0x6e, 0x76, 0x20, 0xd3, 0x39, 0x23}, + {0xa7, 0x2f, 0x3a, 0x51, 0x86, 0xd9, 0x7d, 0xd8, 0x8, 0xcf, 0xd4, + 0xf9, 0x71, 0x9b, 0xac, 0xf5, 0xb3, 0x83, 0xa2, 0x1e, 0x1b, 0xc3, + 0x6b, 0xd0, 0x76, 0x1a, 0x97, 0x19, 0x92, 0x18, 0x1a, 0x33}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 333403773039279, 295772542452938, 1693106465353610, - 912330357530760, 471235657950362 -#else - 24474287, 4968103, 22267082, 4407354, 24063882, 25229252, - 48291976, 13594781, 33514650, 7021958 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1811196219982022, 1068969825533602, 289602974833439, - 1988956043611592, 863562343398367 -#else - 55541958, 26988926, 45743778, 15928891, 40950559, 4315420, - 41160136, 29637754, 45628383, 12868081 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 906282429780072, 2108672665779781, 432396390473936, - 150625823801893, 1708930497638539 -#else - 38473832, 13504660, 19988037, 31421671, 21078224, 6443208, - 45662757, 2244499, 54653067, 25465048 -#endif - }}, + {0xaf, 0x72, 0x75, 0x9d, 0x3a, 0x2f, 0x51, 0x26, 0x9e, 0x4a, 0x7, + 0x68, 0x88, 0xe2, 0xcb, 0x5b, 0xc4, 0xf7, 0x80, 0x11, 0xc1, 0xc1, + 0xed, 0x84, 0x7b, 0xa6, 0x49, 0xf6, 0x9f, 0x61, 0xc9, 0x1a}, + {0xc6, 0x80, 0x4f, 0xfb, 0x45, 0x6f, 0x16, 0xf5, 0xcf, 0x75, 0xc7, + 0x61, 0xde, 0xc7, 0x36, 0x9c, 0x1c, 0xd9, 0x41, 0x90, 0x1b, 0xe8, + 0xd4, 0xe3, 0x21, 0xfe, 0xbd, 0x83, 0x6b, 0x7c, 0x16, 0x31}, + {0x68, 0x10, 0x4b, 0x52, 0x42, 0x38, 0x2b, 0xf2, 0x87, 0xe9, 0x9c, + 0xee, 0x3b, 0x34, 0x68, 0x50, 0xc8, 0x50, 0x62, 0x4a, 0x84, 0x71, + 0x9d, 0xfc, 0x11, 0xb1, 0x8, 0x1f, 0x34, 0x36, 0x24, 0x61}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 925664675702328, 21416848568684, 1831436641861340, - 601157008940113, 371818055044496 -#else - 36513336, 13793478, 61256044, 319135, 41385692, 27290532, - 33086545, 8957937, 51875216, 5540520 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1479786007267725, 1738881859066675, 68646196476567, - 2146507056100328, 1247662817535471 -#else - 55478669, 22050529, 58989363, 25911358, 2620055, 1022908, - 43398120, 31985447, 50980335, 18591624 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 52035296774456, 939969390708103, 312023458773250, - 59873523517659, 1231345905848899 -#else - 23152952, 775386, 27395463, 14006635, 57407746, 4649511, - 1689819, 892185, 55595587, 18348483 -#endif - }}, + {0x38, 0x26, 0x2d, 0x1a, 0xe3, 0x49, 0x63, 0x8b, 0x35, 0xfd, 0xd3, + 0x9b, 0x0, 0xb7, 0xdf, 0x9d, 0xa4, 0x6b, 0xa0, 0xa3, 0xb8, 0xf1, + 0x8b, 0x7f, 0x45, 0x4, 0xd9, 0x78, 0x31, 0xaa, 0x22, 0x15}, + {0x8d, 0x89, 0x4e, 0x87, 0xdb, 0x41, 0x9d, 0xd9, 0x20, 0xdc, 0x7, + 0x6c, 0xf1, 0xa5, 0xfe, 0x9, 0xbc, 0x9b, 0xf, 0xd0, 0x67, 0x2c, + 0x3d, 0x79, 0x40, 0xff, 0x5e, 0x9e, 0x30, 0xe2, 0xeb, 0x46}, + {0x38, 0x49, 0x61, 0x69, 0x53, 0x2f, 0x38, 0x2c, 0x10, 0x6d, 0x2d, + 0xb7, 0x9a, 0x40, 0xfe, 0xda, 0x27, 0xf2, 0x46, 0xb6, 0x91, 0x33, + 0xc8, 0xe8, 0x6c, 0x30, 0x24, 0x5, 0xf5, 0x70, 0xfe, 0x45}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 643355106415761, 290186807495774, 2013561737429023, - 319648069511546, 393736678496162 -#else - 9770129, 9586738, 26496094, 4324120, 1556511, 30004408, - 27453818, 4763127, 47929250, 5867133 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 129358342392716, 1932811617704777, 1176749390799681, - 398040349861790, 1170779668090425 -#else - 34343820, 1927589, 31726409, 28801137, 23962433, 17534932, - 27846558, 5931263, 37359161, 17445976 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2051980782668029, 121859921510665, 2048329875753063, - 1235229850149665, 519062146124755 -#else - 27461885, 30576896, 22380809, 1815854, 44075111, 30522493, - 7283489, 18406359, 47582163, 7734628 -#endif - }}, + {0x91, 0x14, 0x95, 0xc8, 0x20, 0x49, 0xf2, 0x62, 0xa2, 0xc, 0x63, + 0x3f, 0xc8, 0x7, 0xf0, 0x5, 0xb8, 0xd4, 0xc9, 0xf5, 0xd2, 0x45, + 0xbb, 0x6f, 0x45, 0x22, 0x7a, 0xb5, 0x6d, 0x9f, 0x61, 0x16}, + {0x8c, 0xb, 0xc, 0x96, 0xa6, 0x75, 0x48, 0xda, 0x20, 0x2f, 0xe, + 0xef, 0x76, 0xd0, 0x68, 0x5b, 0xd4, 0x8f, 0xb, 0x3d, 0xcf, 0x51, + 0xfb, 0x7, 0xd4, 0x92, 0xe3, 0xa0, 0x23, 0x16, 0x8d, 0x42}, + {0xfd, 0x8, 0xa3, 0x1, 0x44, 0x4a, 0x4f, 0x8, 0xac, 0xca, 0xa5, + 0x76, 0xc3, 0x19, 0x22, 0xa8, 0x7d, 0xbc, 0xd1, 0x43, 0x46, 0xde, + 0xb8, 0xde, 0xc6, 0x38, 0xbd, 0x60, 0x2d, 0x59, 0x81, 0x1d}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1608170971973096, 415809060360428, 1350468408164766, - 2038620059057678, 1026904485989112 -#else - 59098600, 23963614, 55988460, 6196037, 29344158, 20123547, - 7585294, 30377806, 18549496, 15302069 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1837656083115103, 1510134048812070, 906263674192061, - 1821064197805734, 565375124676301 -#else - 34450527, 27383209, 59436070, 22502750, 6258877, 13504381, - 10458790, 27135971, 58236621, 8424745 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 578027192365650, 2034800251375322, 2128954087207123, - 478816193810521, 2196171989962750 -#else - 24687186, 8613276, 36441818, 30320886, 1863891, 31723888, - 19206233, 7134917, 55824382, 32725512 -#endif - }}, + {0xe8, 0xc5, 0x85, 0x7b, 0x9f, 0xb6, 0x65, 0x87, 0xb2, 0xba, 0x68, + 0xd1, 0x8b, 0x67, 0xf0, 0x6f, 0x9b, 0xf, 0x33, 0x1d, 0x7c, 0xe7, + 0x70, 0x3a, 0x7c, 0x8e, 0xaf, 0xb0, 0x51, 0x6d, 0x5f, 0x3a}, + {0x5f, 0xac, 0xd, 0xa6, 0x56, 0x87, 0x36, 0x61, 0x57, 0xdc, 0xab, + 0xeb, 0x6a, 0x2f, 0xe0, 0x17, 0x7d, 0xf, 0xce, 0x4c, 0x2d, 0x3f, + 0x19, 0x7f, 0xf0, 0xdc, 0xec, 0x89, 0x77, 0x4a, 0x23, 0x20}, + {0x52, 0xb2, 0x78, 0x71, 0xb6, 0xd, 0xd2, 0x76, 0x60, 0xd1, 0x1e, + 0xd5, 0xf9, 0x34, 0x1c, 0x7, 0x70, 0x11, 0xe4, 0xb3, 0x20, 0x4a, + 0x2a, 0xf6, 0x66, 0xe3, 0xff, 0x3c, 0x35, 0x82, 0xd6, 0x7c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1633188840273139, 852787172373708, 1548762607215796, - 1266275218902681, 1107218203325133 -#else - 11334899, 24336410, 8025292, 12707519, 17523892, 23078361, - 10243737, 18868971, 62042829, 16498836 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 462189358480054, 1784816734159228, 1611334301651368, - 1303938263943540, 707589560319424 -#else - 8911542, 6887158, 57524604, 26595841, 11145640, 24010752, - 17303924, 19430194, 6536640, 10543906 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1038829280972848, 38176604650029, 753193246598573, - 1136076426528122, 595709990562434 -#else - 38162480, 15479762, 49642029, 568875, 65611181, 11223453, - 64439674, 16928857, 39873154, 8876770 -#endif - }}, + {0xf3, 0xf4, 0xac, 0x68, 0x60, 0xcd, 0x65, 0xa6, 0xd3, 0xe3, 0xd7, + 0x3c, 0x18, 0x2d, 0xd9, 0x42, 0xd9, 0x25, 0x60, 0x33, 0x9d, 0x38, + 0x59, 0x57, 0xff, 0xd8, 0x2c, 0x2b, 0x3b, 0x25, 0xf0, 0x3e}, + {0xb6, 0xfa, 0x87, 0xd8, 0x5b, 0xa4, 0xe1, 0xb, 0x6e, 0x3b, 0x40, + 0xba, 0x32, 0x6a, 0x84, 0x2a, 0x0, 0x60, 0x6e, 0xe9, 0x12, 0x10, + 0x92, 0xd9, 0x43, 0x9, 0xdc, 0x3b, 0x86, 0xc8, 0x38, 0x28}, + {0x30, 0x50, 0x46, 0x4a, 0xcf, 0xb0, 0x6b, 0xd1, 0xab, 0x77, 0xc5, + 0x15, 0x41, 0x6b, 0x49, 0xfa, 0x9d, 0x41, 0xab, 0xf4, 0x8a, 0xae, + 0xcf, 0x82, 0x12, 0x28, 0xa8, 0x6, 0xa6, 0xb8, 0xdc, 0x21}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1408451820859834, 2194984964010833, 2198361797561729, - 1061962440055713, 1645147963442934 -#else - 41365946, 20987567, 51458897, 32707824, 34082177, 32758143, - 33627041, 15824473, 66504438, 24514614 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 4701053362120, 1647641066302348, 1047553002242085, - 1923635013395977, 206970314902065 -#else - 10330056, 70051, 7957388, 24551765, 9764901, 15609756, 27698697, - 28664395, 1657393, 3084098 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1750479161778571, 1362553355169293, 1891721260220598, - 966109370862782, 1024913988299801 -#else - 10477963, 26084172, 12119565, 20303627, 29016246, 28188843, - 31280318, 14396151, 36875289, 15272408 -#endif - }}, + {0xba, 0x31, 0x77, 0xbe, 0xfa, 0x0, 0x8d, 0x9a, 0x89, 0x18, 0x9e, + 0x62, 0x7e, 0x60, 0x3, 0x82, 0x7f, 0xd9, 0xf3, 0x43, 0x37, 0x2, + 0xcc, 0xb2, 0x8b, 0x67, 0x6f, 0x6c, 0xbf, 0xd, 0x84, 0x5d}, + {0xc8, 0x9f, 0x9d, 0x8c, 0x46, 0x4, 0x60, 0x5c, 0xcb, 0xa3, 0x2a, + 0xd4, 0x6e, 0x9, 0x40, 0x25, 0x9c, 0x2f, 0xee, 0x12, 0x4c, 0x4d, + 0x5b, 0x12, 0xab, 0x1d, 0xa3, 0x94, 0x81, 0xd0, 0xc3, 0xb}, + {0x8b, 0xe1, 0x9f, 0x30, 0xd, 0x38, 0x6e, 0x70, 0xc7, 0x65, 0xe1, + 0xb9, 0xa6, 0x2d, 0xb0, 0x6e, 0xab, 0x20, 0xae, 0x7d, 0x99, 0xba, + 0xbb, 0x57, 0xdd, 0x96, 0xc1, 0x2a, 0x23, 0x76, 0x42, 0x3a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 212699049131723, 1117950018299775, 1873945661751056, - 1403802921984058, 130896082652698 -#else - 54820555, 3169462, 28813183, 16658753, 25116432, 27923966, - 41934906, 20918293, 42094106, 1950503 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 636808533673210, 1262201711667560, 390951380330599, - 1663420692697294, 561951321757406 -#else - 40928506, 9489186, 11053416, 18808271, 36055143, 5825629, - 58724558, 24786899, 15341278, 8373727 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 520731594438141, 1446301499955692, 273753264629267, - 1565101517999256, 1019411827004672 -#else - 28685821, 7759505, 52730348, 21551571, 35137043, 4079241, - 298136, 23321830, 64230656, 15190419 -#endif - }}, + {0xcb, 0x7e, 0x44, 0xdb, 0x72, 0xc1, 0xf8, 0x3b, 0xbd, 0x2d, 0x28, + 0xc6, 0x1f, 0xc4, 0xcf, 0x5f, 0xfe, 0x15, 0xaa, 0x75, 0xc0, 0xff, + 0xac, 0x80, 0xf9, 0xa9, 0xe1, 0x24, 0xe8, 0xc9, 0x70, 0x7}, + {0xfa, 0x84, 0x70, 0x8a, 0x2c, 0x43, 0x42, 0x4b, 0x45, 0xe5, 0xb9, + 0xdf, 0xe3, 0x19, 0x8a, 0x89, 0x5d, 0xe4, 0x58, 0x9c, 0x21, 0x0, + 0x9f, 0xbe, 0xd1, 0xeb, 0x6d, 0xa1, 0xce, 0x77, 0xf1, 0x1f}, + {0xfd, 0xb5, 0xb5, 0x45, 0x9a, 0xd9, 0x61, 0xcf, 0x24, 0x79, 0x3a, + 0x1b, 0xe9, 0x84, 0x9, 0x86, 0x89, 0x3e, 0x3e, 0x30, 0x19, 0x9, + 0x30, 0xe7, 0x1e, 0xb, 0x50, 0x41, 0xfd, 0x64, 0xf2, 0x39}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 926527492029409, 1191853477411379, 734233225181171, - 184038887541270, 1790426146325343 -#else - 34175969, 13806335, 52771379, 17760000, 43104243, 10940927, - 8669718, 2742393, 41075551, 26679428 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1464651961852572, 1483737295721717, 1519450561335517, - 1161429831763785, 405914998179977 -#else - 65528476, 21825014, 41129205, 22109408, 49696989, 22641577, - 9291593, 17306653, 54954121, 6048604 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 996126634382301, 796204125879525, 127517800546509, - 344155944689303, 615279846169038 -#else - 36803549, 14843443, 1539301, 11864366, 20201677, 1900163, - 13934231, 5128323, 11213262, 9168384 -#endif - }}, + {0xe1, 0x7b, 0x9, 0xfe, 0xab, 0x4a, 0x9b, 0xd1, 0x29, 0x19, 0xe0, + 0xdf, 0xe1, 0xfc, 0x6d, 0xa4, 0xff, 0xf1, 0xa6, 0x2c, 0x94, 0x8, + 0xc9, 0xc3, 0x4e, 0xf1, 0x35, 0x2c, 0x27, 0x21, 0xc6, 0x65}, + {0x9c, 0xe2, 0xe7, 0xdb, 0x17, 0x34, 0xad, 0xa7, 0x9c, 0x13, 0x9c, + 0x2b, 0x6a, 0x37, 0x94, 0xbd, 0xa9, 0x7b, 0x59, 0x93, 0x8e, 0x1b, + 0xe9, 0xa0, 0x40, 0x98, 0x88, 0x68, 0x34, 0xd7, 0x12, 0x17}, + {0xdd, 0x93, 0x31, 0xce, 0xf8, 0x89, 0x2b, 0xe7, 0xbb, 0xc0, 0x25, + 0xa1, 0x56, 0x33, 0x10, 0x4d, 0x83, 0xfe, 0x1c, 0x2e, 0x3d, 0xa9, + 0x19, 0x4, 0x72, 0xe2, 0x9c, 0xb1, 0xa, 0x80, 0xf9, 0x22}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 738724080975276, 2188666632415296, 1961313708559162, - 1506545807547587, 1151301638969740 -#else - 40828332, 11007846, 19408960, 32613674, 48515898, 29225851, - 62020803, 22449281, 20470156, 17155731 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 622917337413835, 1218989177089035, 1284857712846592, - 970502061709359, 351025208117090 -#else - 43972811, 9282191, 14855179, 18164354, 59746048, 19145871, - 44324911, 14461607, 14042978, 5230683 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2067814584765580, 1677855129927492, 2086109782475197, - 235286517313238, 1416314046739645 -#else - 29969548, 30812838, 50396996, 25001989, 9175485, 31085458, - 21556950, 3506042, 61174973, 21104723 -#endif - }}, + {0xac, 0xfd, 0x6e, 0x9a, 0xdd, 0x9f, 0x2, 0x42, 0x41, 0x49, 0xa5, + 0x34, 0xbe, 0xce, 0x12, 0xb9, 0x7b, 0xf3, 0xbd, 0x87, 0xb9, 0x64, + 0xf, 0x64, 0xb4, 0xca, 0x98, 0x85, 0xd3, 0xa4, 0x71, 0x41}, + {0xcb, 0xf8, 0x9e, 0x3e, 0x8a, 0x36, 0x5a, 0x60, 0x15, 0x47, 0x50, + 0xa5, 0x22, 0xc0, 0xe9, 0xe3, 0x8f, 0x24, 0x24, 0x5f, 0xb0, 0x48, + 0x3d, 0x55, 0xe5, 0x26, 0x76, 0x64, 0xcd, 0x16, 0xf4, 0x13}, + {0x8c, 0x4c, 0xc9, 0x99, 0xaa, 0x58, 0x27, 0xfa, 0x7, 0xb8, 0x0, + 0xb0, 0x6f, 0x6f, 0x0, 0x23, 0x92, 0x53, 0xda, 0xad, 0xdd, 0x91, + 0xd2, 0xfb, 0xab, 0xd1, 0x4b, 0x57, 0xfa, 0x14, 0x82, 0x50}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 586844262630358, 307444381952195, 458399356043426, - 602068024507062, 1028548203415243 -#else - 63964118, 8744660, 19704003, 4581278, 46678178, 6830682, - 45824694, 8971512, 38569675, 15326562 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 678489922928203, 2016657584724032, 90977383049628, - 1026831907234582, 615271492942522 -#else - 47644235, 10110287, 49846336, 30050539, 43608476, 1355668, - 51585814, 15300987, 46594746, 9168259 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 301225714012278, 1094837270268560, 1202288391010439, - 644352775178361, 1647055902137983 -#else - 61755510, 4488612, 43305616, 16314346, 7780487, 17915493, - 38160505, 9601604, 33087103, 24543045 -#endif - }}, + {0xd6, 0x3, 0xd0, 0x53, 0xbb, 0x15, 0x1a, 0x46, 0x65, 0xc9, 0xf3, + 0xbc, 0x88, 0x28, 0x10, 0xb2, 0x5a, 0x3a, 0x68, 0x6c, 0x75, 0x76, + 0xc5, 0x27, 0x47, 0xb4, 0x6c, 0xc8, 0xa4, 0x58, 0x77, 0x3a}, + {0x4b, 0xfe, 0xd6, 0x3e, 0x15, 0x69, 0x2, 0xc2, 0xc4, 0x77, 0x1d, + 0x51, 0x39, 0x67, 0x5a, 0xa6, 0x94, 0xaf, 0x14, 0x2c, 0x46, 0x26, + 0xde, 0xcb, 0x4b, 0xa7, 0xab, 0x6f, 0xec, 0x60, 0xf9, 0x22}, + {0x76, 0x50, 0xae, 0x93, 0xf6, 0x11, 0x81, 0x54, 0xa6, 0x54, 0xfd, + 0x1d, 0xdf, 0x21, 0xae, 0x1d, 0x65, 0x5e, 0x11, 0xf3, 0x90, 0x8c, + 0x24, 0x12, 0x94, 0xf4, 0xe7, 0x8d, 0x5f, 0xd1, 0x9f, 0x5d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1210746697896478, 1416608304244708, 686487477217856, - 1245131191434135, 1051238336855737 -#else - 47665694, 18041531, 46311396, 21109108, 37284416, 10229460, - 39664535, 18553900, 61111993, 15664671 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1135604073198207, 1683322080485474, 769147804376683, - 2086688130589414, 900445683120379 -#else - 23294591, 16921819, 44458082, 25083453, 27844203, 11461195, - 13099750, 31094076, 18151675, 13417686 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1971518477615628, 401909519527336, 448627091057375, - 1409486868273821, 1214789035034363 -#else - 42385932, 29377914, 35958184, 5988918, 40250079, 6685064, - 1661597, 21002991, 15271675, 18101767 -#endif - }}, + {0x1e, 0x52, 0xd7, 0xee, 0x2a, 0x4d, 0x24, 0x3f, 0x15, 0x96, 0x2e, + 0x43, 0x28, 0x90, 0x3a, 0x8e, 0xd4, 0x16, 0x9c, 0x2e, 0x77, 0xba, + 0x64, 0xe1, 0xd8, 0x98, 0xeb, 0x47, 0xfa, 0x87, 0xc1, 0x3b}, + {0x7f, 0x72, 0x63, 0x6d, 0xd3, 0x8, 0x14, 0x3, 0x33, 0xb5, 0xc7, + 0xd7, 0xef, 0x9a, 0x37, 0x6a, 0x4b, 0xe2, 0xae, 0xcc, 0xc5, 0x8f, + 0xe1, 0xa9, 0xd3, 0xbe, 0x8f, 0x4f, 0x91, 0x35, 0x2f, 0x33}, + {0xc, 0xc2, 0x86, 0xea, 0x15, 0x1, 0x47, 0x6d, 0x25, 0xd1, 0x46, + 0x6c, 0xcb, 0xb7, 0x8a, 0x99, 0x88, 0x1, 0x66, 0x3a, 0xb5, 0x32, + 0x78, 0xd7, 0x3, 0xba, 0x6f, 0x90, 0xce, 0x81, 0xd, 0x45}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1364039144731711, 1897497433586190, 2203097701135459, - 145461396811251, 1349844460790699 -#else - 11433023, 20325767, 8239630, 28274915, 65123427, 32828713, - 48410099, 2167543, 60187563, 20114249 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1045230323257973, 818206601145807, 630513189076103, - 1672046528998132, 807204017562437 -#else - 35672693, 15575145, 30436815, 12192228, 44645511, 9395378, - 57191156, 24915434, 12215109, 12028277 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 439961968385997, 386362664488986, 1382706320807688, - 309894000125359, 2207801346498567 -#else - 14098381, 6555944, 23007258, 5757252, 51681032, 20603929, - 30123439, 4617780, 50208775, 32898803 -#endif - }}, + {0x3f, 0x74, 0xae, 0x1c, 0x96, 0xd8, 0x74, 0xd0, 0xed, 0x63, 0x1c, + 0xee, 0xf5, 0x18, 0x6d, 0xf8, 0x29, 0xed, 0xf4, 0xe7, 0x5b, 0xc5, + 0xbd, 0x97, 0x8, 0xb1, 0x3a, 0x66, 0x79, 0xd2, 0xba, 0x4c}, + {0x75, 0x52, 0x20, 0xa6, 0xa1, 0xb6, 0x7b, 0x6e, 0x83, 0x8e, 0x3c, + 0x41, 0xd7, 0x21, 0x4f, 0xaa, 0xb2, 0x5c, 0x8f, 0xe8, 0x55, 0xd1, + 0x56, 0x6f, 0xe1, 0x5b, 0x34, 0xa6, 0x4b, 0x5d, 0xe2, 0x2d}, + {0xcd, 0x1f, 0xd7, 0xa0, 0x24, 0x90, 0xd1, 0x80, 0xf8, 0x8a, 0x28, + 0xfb, 0xa, 0xc2, 0x25, 0xc5, 0x19, 0x64, 0x3a, 0x5f, 0x4b, 0x97, + 0xa3, 0xb1, 0x33, 0x72, 0x0, 0xe2, 0xef, 0xbc, 0x7f, 0x7d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1229004686397588, 920643968530863, 123975893911178, - 681423993215777, 1400559197080973 -#else - 63082644, 18313596, 11893167, 13718664, 52299402, 1847384, - 51288865, 10154008, 23973261, 20869958 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2003766096898049, 170074059235165, 1141124258967971, - 1485419893480973, 1573762821028725 -#else - 40577025, 29858441, 65199965, 2534300, 35238307, 17004076, - 18341389, 22134481, 32013173, 23450893 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 729905708611432, 1270323270673202, 123353058984288, - 426460209632942, 2195574535456672 -#else - 41629544, 10876442, 55337778, 18929291, 54739296, 1838103, - 21911214, 6354752, 4425632, 32716610 -#endif - }}, + {0x94, 0x90, 0xc2, 0xf3, 0xc5, 0x5d, 0x7c, 0xcd, 0xab, 0x5, 0x91, + 0x2a, 0x9a, 0xa2, 0x81, 0xc7, 0x58, 0x30, 0x1c, 0x42, 0x36, 0x1d, + 0xc6, 0x80, 0xd7, 0xd4, 0xd8, 0xdc, 0x96, 0xd1, 0x9c, 0x4f}, + {0x1, 0x28, 0x6b, 0x26, 0x6a, 0x1e, 0xef, 0xfa, 0x16, 0x9f, 0x73, + 0xd5, 0xc4, 0x68, 0x6c, 0x86, 0x2c, 0x76, 0x3, 0x1b, 0xbc, 0x2f, + 0x8a, 0xf6, 0x8d, 0x5a, 0xb7, 0x87, 0x5e, 0x43, 0x75, 0x59}, + {0x68, 0x37, 0x7b, 0x6a, 0xd8, 0x97, 0x92, 0x19, 0x63, 0x7a, 0xd1, + 0x1a, 0x24, 0x58, 0xd0, 0xd0, 0x17, 0xc, 0x1c, 0x5c, 0xad, 0x9c, + 0x2, 0xba, 0x7, 0x3, 0x7a, 0x38, 0x84, 0xd0, 0xcd, 0x7c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1271140255321235, 2044363183174497, 52125387634689, - 1445120246694705, 942541986339084 -#else - 56675475, 18941465, 22229857, 30463385, 53917697, 776728, - 49693489, 21533969, 4725004, 14044970 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1761608437466135, 583360847526804, 1586706389685493, - 2157056599579261, 1170692369685772 -#else - 19268631, 26250011, 1555348, 8692754, 45634805, 23643767, - 6347389, 32142648, 47586572, 17444675 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 871476219910823, 1878769545097794, 2241832391238412, - 548957640601001, 690047440233174 -#else - 42244775, 12986007, 56209986, 27995847, 55796492, 33405905, - 19541417, 8180106, 9282262, 10282508 -#endif - }}, + {0x93, 0xcc, 0x60, 0x67, 0x18, 0x84, 0xc, 0x9b, 0x99, 0x2a, 0xb3, + 0x1a, 0x7a, 0x0, 0xae, 0xcd, 0x18, 0xda, 0xb, 0x62, 0x86, 0xec, + 0x8d, 0xa8, 0x44, 0xca, 0x90, 0x81, 0x84, 0xca, 0x93, 0x35}, + {0x17, 0x4, 0x26, 0x6d, 0x2c, 0x42, 0xa6, 0xdc, 0xbd, 0x40, 0x82, + 0x94, 0x50, 0x3d, 0x15, 0xae, 0x77, 0xc6, 0x68, 0xfb, 0xb4, 0xc1, + 0xc0, 0xa9, 0x53, 0xcf, 0xd0, 0x61, 0xed, 0xd0, 0x8b, 0x42}, + {0xa7, 0x9a, 0x84, 0x5e, 0x9a, 0x18, 0x13, 0x92, 0xcd, 0xfa, 0xd8, + 0x65, 0x35, 0xc3, 0xd8, 0xd4, 0xd1, 0xbb, 0xfd, 0x53, 0x5b, 0x54, + 0x52, 0x8c, 0xe6, 0x63, 0x2d, 0xda, 0x8, 0x83, 0x39, 0x27}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 297194732135507, 1366347803776820, 1301185512245601, - 561849853336294, 1533554921345731 -#else - 40903763, 4428546, 58447668, 20360168, 4098401, 19389175, - 15522534, 8372215, 5542595, 22851749 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 999628998628371, 1132836708493400, 2084741674517453, - 469343353015612, 678782988708035 -#else - 56546323, 14895632, 26814552, 16880582, 49628109, 31065071, - 64326972, 6993760, 49014979, 10114654 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2189427607417022, 699801937082607, 412764402319267, - 1478091893643349, 2244675696854460 -#else - 47001790, 32625013, 31422703, 10427861, 59998115, 6150668, - 38017109, 22025285, 25953724, 33448274 -#endif - }}, + {0x53, 0x24, 0x70, 0xa, 0x4c, 0xe, 0xa1, 0xb9, 0xde, 0x1b, 0x7d, + 0xd5, 0x66, 0x58, 0xa2, 0xf, 0xf7, 0xda, 0x27, 0xcd, 0xb5, 0xd9, + 0xb9, 0xff, 0xfd, 0x33, 0x2c, 0x49, 0x45, 0x29, 0x2c, 0x57}, + {0x13, 0xd4, 0x5e, 0x43, 0x28, 0x8d, 0xc3, 0x42, 0xc9, 0xcc, 0x78, + 0x32, 0x60, 0xf3, 0x50, 0xbd, 0xef, 0x3, 0xda, 0x79, 0x1a, 0xab, + 0x7, 0xbb, 0x55, 0x33, 0x8c, 0xbe, 0xae, 0x97, 0x95, 0x26}, + {0xbe, 0x30, 0xcd, 0xd6, 0x45, 0xc7, 0x7f, 0xc7, 0xfb, 0xae, 0xba, + 0xe3, 0xd3, 0xe8, 0xdf, 0xe4, 0xc, 0xda, 0x5d, 0xaa, 0x30, 0x88, + 0x2c, 0xa2, 0x80, 0xca, 0x5b, 0xc0, 0x98, 0x54, 0x98, 0x7f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1712292055966563, 204413590624874, 1405738637332841, - 408981300829763, 861082219276721 -#else - 62874467, 25515139, 57989738, 3045999, 2101609, 20947138, - 19390019, 6094296, 63793585, 12831124 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 508561155940631, 966928475686665, 2236717801150132, - 424543858577297, 2089272956986143 -#else - 51110167, 7578151, 5310217, 14408357, 33560244, 33329692, - 31575953, 6326196, 7381791, 31132593 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 221245220129925, 1156020201681217, 491145634799213, - 542422431960839, 828100817819207 -#else - 46206085, 3296810, 24736065, 17226043, 18374253, 7318640, - 6295303, 8082724, 51746375, 12339663 -#endif - }}, + {0x63, 0x63, 0xbf, 0xf, 0x52, 0x15, 0x56, 0xd3, 0xa6, 0xfb, 0x4d, + 0xcf, 0x45, 0x5a, 0x4, 0x8, 0xc2, 0xa0, 0x3f, 0x87, 0xbc, 0x4f, + 0xc2, 0xee, 0xe7, 0x12, 0x9b, 0xd6, 0x3c, 0x65, 0xf2, 0x30}, + {0x17, 0xe1, 0xb, 0x9f, 0x88, 0xce, 0x49, 0x38, 0x88, 0xa2, 0x54, + 0x7b, 0x1b, 0xad, 0x5, 0x80, 0x1c, 0x92, 0xfc, 0x23, 0x9f, 0xc3, + 0xa3, 0x3d, 0x4, 0xf3, 0x31, 0xa, 0x47, 0xec, 0xc2, 0x76}, + {0x85, 0xc, 0xc1, 0xaa, 0x38, 0xc9, 0x8, 0x8a, 0xcb, 0x6b, 0x27, + 0xdb, 0x60, 0x9b, 0x17, 0x46, 0x70, 0xac, 0x6f, 0xe, 0x1e, 0xc0, + 0x20, 0xa9, 0xda, 0x73, 0x64, 0x59, 0xf1, 0x73, 0x12, 0x2f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 153756971240384, 1299874139923977, 393099165260502, - 1058234455773022, 996989038681183 -#else - 27724736, 2291157, 6088201, 19369634, 1792726, 5857634, - 13848414, 15768922, 25091167, 14856294 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 559086812798481, 573177704212711, 1629737083816402, - 1399819713462595, 1646954378266038 -#else - 48242193, 8331042, 24373479, 8541013, 66406866, 24284974, - 12927299, 20858939, 44926390, 24541532 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1887963056288059, 228507035730124, 1468368348640282, - 930557653420194, 613513962454686 -#else - 55685435, 28132841, 11632844, 3405020, 30536730, 21880393, - 39848098, 13866389, 30146206, 9142070 -#endif - }}, + {0xc0, 0xb, 0xa7, 0x55, 0xd7, 0x8b, 0x48, 0x30, 0xe7, 0x42, 0xd4, + 0xf1, 0xa4, 0xb5, 0xd6, 0x6, 0x62, 0x61, 0x59, 0xbc, 0x9e, 0xa6, + 0xd1, 0xea, 0x84, 0xf7, 0xc5, 0xed, 0x97, 0x19, 0xac, 0x38}, + {0x11, 0x1e, 0xe0, 0x8a, 0x7c, 0xfc, 0x39, 0x47, 0x9f, 0xab, 0x6a, + 0x4a, 0x90, 0x74, 0x52, 0xfd, 0x2e, 0x8f, 0x72, 0x87, 0x82, 0x8a, + 0xd9, 0x41, 0xf2, 0x69, 0x5b, 0xd8, 0x2a, 0x57, 0x9e, 0x5d}, + {0x3b, 0xb1, 0x51, 0xa7, 0x17, 0xb5, 0x66, 0x6, 0x8c, 0x85, 0x9b, + 0x7e, 0x86, 0x6, 0x7d, 0x74, 0x49, 0xde, 0x4d, 0x45, 0x11, 0xc0, + 0xac, 0xac, 0x9c, 0xe6, 0xe9, 0xbf, 0x9c, 0xcd, 0xdf, 0x22}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1224529808187553, 1577022856702685, 2206946542980843, - 625883007765001, 279930793512158 -#else - 3924129, 18246916, 53291741, 23499471, 12291819, 32886066, - 39406089, 9326383, 58871006, 4171293 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1076287717051609, 1114455570543035, 187297059715481, - 250446884292121, 1885187512550540 -#else - 51186905, 16037936, 6713787, 16606682, 45496729, 2790943, - 26396185, 3731949, 345228, 28091483 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 902497362940219, 76749815795675, 1657927525633846, - 1420238379745202, 1340321636548352 -#else - 45781307, 13448258, 25284571, 1143661, 20614966, 24705045, - 2031538, 21163201, 50855680, 19972348 -#endif - }}, + {0xa1, 0xe0, 0x3b, 0x10, 0xb4, 0x59, 0xec, 0x56, 0x69, 0xf9, 0x59, + 0xd2, 0xec, 0xba, 0xe3, 0x2e, 0x32, 0xcd, 0xf5, 0x13, 0x94, 0xb2, + 0x7c, 0x79, 0x72, 0xe4, 0xcd, 0x24, 0x78, 0x87, 0xe9, 0xf}, + {0xd9, 0xc, 0xd, 0xc3, 0xe0, 0xd2, 0xdb, 0x8d, 0x33, 0x43, 0xbb, + 0xac, 0x5f, 0x66, 0x8e, 0xad, 0x1f, 0x96, 0x2a, 0x32, 0x8c, 0x25, + 0x6b, 0x8f, 0xc7, 0xc1, 0x48, 0x54, 0xc0, 0x16, 0x29, 0x6b}, + {0x3b, 0x91, 0xba, 0xa, 0xd1, 0x34, 0xdb, 0x7e, 0xe, 0xac, 0x6d, + 0x2e, 0x82, 0xcd, 0xa3, 0x4e, 0x15, 0xf8, 0x78, 0x65, 0xff, 0x3d, + 0x8, 0x66, 0x17, 0xa, 0xf0, 0x7f, 0x30, 0x3f, 0x30, 0x4c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1129576631190784, 1281994010027327, 996844254743018, - 257876363489249, 1150850742055018 -#else - 31016192, 16832003, 26371391, 19103199, 62081514, 14854136, - 17477601, 3842657, 28012650, 17149012 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 628740660038789, 1943038498527841, 467786347793886, - 1093341428303375, 235413859513003 -#else - 62033029, 9368965, 58546785, 28953529, 51858910, 6970559, - 57918991, 16292056, 58241707, 3507939 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 237425418909360, 469614029179605, 1512389769174935, - 1241726368345357, 441602891065214 -#else - 29439664, 3537914, 23333589, 6997794, 49553303, 22536363, - 51899661, 18503164, 57943934, 6580395 -#endif - }}, + {0x0, 0x45, 0xd9, 0xd, 0x58, 0x3, 0xfc, 0x29, 0x93, 0xec, 0xbb, + 0x6f, 0xa4, 0x7a, 0xd2, 0xec, 0xf8, 0xa7, 0xe2, 0xc2, 0x5f, 0x15, + 0xa, 0x13, 0xd5, 0xa1, 0x6, 0xb7, 0x1a, 0x15, 0x6b, 0x41}, + {0x85, 0x8c, 0xb2, 0x17, 0xd6, 0x3b, 0xa, 0xd3, 0xea, 0x3b, 0x77, + 0x39, 0xb7, 0x77, 0xd3, 0xc5, 0xbf, 0x5c, 0x6a, 0x1e, 0x8c, 0xe7, + 0xc6, 0xc6, 0xc4, 0xb7, 0x2a, 0x8b, 0xf7, 0xb8, 0x61, 0xd}, + {0xb0, 0x36, 0xc1, 0xe9, 0xef, 0xd7, 0xa8, 0x56, 0x20, 0x4b, 0xe4, + 0x58, 0xcd, 0xe5, 0x7, 0xbd, 0xab, 0xe0, 0x57, 0x1b, 0xda, 0x2f, + 0xe6, 0xaf, 0xd2, 0xe8, 0x77, 0x42, 0xf7, 0x2a, 0x1a, 0x19}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1736417953058555, 726531315520508, 1833335034432527, - 1629442561574747, 624418919286085 -#else - 54923003, 25874643, 16438268, 10826160, 58412047, 27318820, - 17860443, 24280586, 65013061, 9304566 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1960754663920689, 497040957888962, 1909832851283095, - 1271432136996826, 2219780368020940 -#else - 20714545, 29217521, 29088194, 7406487, 11426967, 28458727, - 14792666, 18945815, 5289420, 33077305 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1537037379417136, 1358865369268262, 2130838645654099, - 828733687040705, 1999987652890901 -#else - 50443312, 22903641, 60948518, 20248671, 9192019, 31751970, - 17271489, 12349094, 26939669, 29802138 -#endif - }}, + {0xfb, 0xe, 0x46, 0x4f, 0x43, 0x2b, 0xe6, 0x9f, 0xd6, 0x7, 0x36, + 0xa6, 0xd4, 0x3, 0xd3, 0xde, 0x24, 0xda, 0xa0, 0xb7, 0xe, 0x21, + 0x52, 0xf0, 0x93, 0x5b, 0x54, 0x0, 0xbe, 0x7d, 0x7e, 0x23}, + {0x31, 0x14, 0x3c, 0xc5, 0x4b, 0xf7, 0x16, 0xce, 0xde, 0xed, 0x72, + 0x20, 0xce, 0x25, 0x97, 0x2b, 0xe7, 0x3e, 0xb2, 0xb5, 0x6f, 0xc3, + 0xb9, 0xb8, 0x8, 0xc9, 0x5c, 0xb, 0x45, 0xe, 0x2e, 0x7e}, + {0x30, 0xb4, 0x1, 0x67, 0xed, 0x75, 0x35, 0x1, 0x10, 0xfd, 0xb, + 0x9f, 0xe6, 0x94, 0x10, 0x23, 0x22, 0x7f, 0xe4, 0x83, 0x15, 0xf, + 0x32, 0x75, 0xe3, 0x55, 0x11, 0xb1, 0x99, 0xa6, 0xaf, 0x71}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 629042105241814, 1098854999137608, 887281544569320, - 1423102019874777, 7911258951561 -#else - 54218966, 9373457, 31595848, 16374215, 21471720, 13221525, - 39825369, 21205872, 63410057, 117886 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1811562332665373, 1501882019007673, 2213763501088999, - 359573079719636, 36370565049116 -#else - 22263325, 26994382, 3984569, 22379786, 51994855, 32987646, - 28311252, 5358056, 43789084, 541963 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 218907117361280, 1209298913016966, 1944312619096112, - 1130690631451061, 1342327389191701 -#else - 16259200, 3261970, 2309254, 18019958, 50223152, 28972515, - 24134069, 16848603, 53771797, 20002236 -#endif - }}, + {0xd6, 0x50, 0x3b, 0x47, 0x1c, 0x3c, 0x42, 0xea, 0x10, 0xef, 0x38, + 0x3b, 0x1f, 0x7a, 0xe8, 0x51, 0x95, 0xbe, 0xc9, 0xb2, 0x5f, 0xbf, + 0x84, 0x9b, 0x1c, 0x9a, 0xf8, 0x78, 0xbc, 0x1f, 0x73, 0x0}, + {0x1d, 0xb6, 0x53, 0x39, 0x9b, 0x6f, 0xce, 0x65, 0xe6, 0x41, 0xa1, + 0xaf, 0xea, 0x39, 0x58, 0xc6, 0xfe, 0x59, 0xf7, 0xa9, 0xfd, 0x5f, + 0x43, 0xf, 0x8e, 0xc2, 0xb1, 0xc2, 0xe9, 0x42, 0x11, 0x2}, + {0x80, 0x18, 0xf8, 0x48, 0x18, 0xc7, 0x30, 0xe4, 0x19, 0xc1, 0xce, + 0x5e, 0x22, 0xc, 0x96, 0xbf, 0xe3, 0x15, 0xba, 0x6b, 0x83, 0xe0, + 0xda, 0xb6, 0x8, 0x58, 0xe1, 0x47, 0x33, 0x6f, 0x4d, 0x4c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1369976867854704, 1396479602419169, 1765656654398856, - 2203659200586299, 998327836117241 -#else - 9378160, 20414246, 44262881, 20809167, 28198280, 26310334, - 64709179, 32837080, 690425, 14876244 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2230701885562825, 1348173180338974, 2172856128624598, - 1426538746123771, 444193481326151 -#else - 24977353, 33240048, 58884894, 20089345, 28432342, 32378079, - 54040059, 21257083, 44727879, 6618998 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 784210426627951, 918204562375674, 1284546780452985, - 1324534636134684, 1872449409642708 -#else - 65570671, 11685645, 12944378, 13682314, 42719353, 19141238, - 8044828, 19737104, 32239828, 27901670 -#endif - }}, + {0x70, 0x19, 0x8f, 0x98, 0xfc, 0xdd, 0xc, 0x2f, 0x1b, 0xf5, 0xb9, + 0xb0, 0x27, 0x62, 0x91, 0x6b, 0xbe, 0x76, 0x91, 0x77, 0xc4, 0xb6, + 0xc7, 0x6e, 0xa8, 0x9f, 0x8f, 0xa8, 0x0, 0x95, 0xbf, 0x38}, + {0xc9, 0x1f, 0x7d, 0xc1, 0xcf, 0xec, 0xf7, 0x18, 0x14, 0x3c, 0x40, + 0x51, 0xa6, 0xf5, 0x75, 0x6c, 0xdf, 0xc, 0xee, 0xf7, 0x2b, 0x71, + 0xde, 0xdb, 0x22, 0x7a, 0xe4, 0xa7, 0xaa, 0xdd, 0x3f, 0x19}, + {0x6f, 0x87, 0xe8, 0x37, 0x3c, 0xc9, 0xd2, 0x1f, 0x2c, 0x46, 0xd1, + 0x18, 0x5a, 0x1e, 0xf6, 0xa2, 0x76, 0x12, 0x24, 0x39, 0x82, 0xf5, + 0x80, 0x50, 0x69, 0x49, 0xd, 0xbf, 0x9e, 0xb9, 0x6f, 0x6a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 319638829540294, 596282656808406, 2037902696412608, - 1557219121643918, 341938082688094 -#else - 48505798, 4762989, 66182614, 8885303, 38696384, 30367116, - 9781646, 23204373, 32779358, 5095274 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1901860206695915, 2004489122065736, 1625847061568236, - 973529743399879, 2075287685312905 -#else - 34100715, 28339925, 34843976, 29869215, 9460460, 24227009, - 42507207, 14506723, 21639561, 30924196 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1371853944110545, 1042332820512553, 1949855697918254, - 1791195775521505, 37487364849293 -#else - 50707921, 20442216, 25239337, 15531969, 3987758, 29055114, - 65819361, 26690896, 17874573, 558605 -#endif - }}, + {0xc6, 0x23, 0xe4, 0xb6, 0xb5, 0x22, 0xb1, 0xee, 0x8e, 0xff, 0x86, + 0xf2, 0x10, 0x70, 0x9d, 0x93, 0x8c, 0x5d, 0xcf, 0x1d, 0x83, 0x2a, + 0xa9, 0x90, 0x10, 0xeb, 0xc5, 0x42, 0x9f, 0xda, 0x6f, 0x13}, + {0xeb, 0x55, 0x8, 0x56, 0xbb, 0xc1, 0x46, 0x6a, 0x9d, 0xf0, 0x93, + 0xf8, 0x38, 0xbb, 0x16, 0x24, 0xc1, 0xac, 0x71, 0x8f, 0x37, 0x11, + 0x1d, 0xd7, 0xea, 0x96, 0x18, 0xa3, 0x14, 0x69, 0xf7, 0x75}, + {0xd1, 0xbd, 0x5, 0xa3, 0xb1, 0xdf, 0x4c, 0xf9, 0x8, 0x2c, 0xf8, + 0x9f, 0x9d, 0x4b, 0x36, 0xf, 0x8a, 0x58, 0xbb, 0xc3, 0xa5, 0xd8, + 0x87, 0x2a, 0xba, 0xdc, 0xe8, 0xb, 0x51, 0x83, 0x21, 0x2}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 687200189577855, 1082536651125675, 644224940871546, - 340923196057951, 343581346747396 -#else - 53508735, 10240080, 9171883, 16131053, 46239610, 9599699, - 33499487, 5080151, 2085892, 5119761 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2082717129583892, 27829425539422, 145655066671970, - 1690527209845512, 1865260509673478 -#else - 44903700, 31034903, 50727262, 414690, 42089314, 2170429, - 30634760, 25190818, 35108870, 27794547 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1059729620568824, 2163709103470266, 1440302280256872, - 1769143160546397, 869830310425069 -#else - 60263160, 15791201, 8550074, 32241778, 29928808, 21462176, - 27534429, 26362287, 44757485, 12961481 -#endif - }}, + {0x7f, 0x7a, 0x30, 0x43, 0x1, 0x71, 0x5a, 0x9d, 0x5f, 0xa4, 0x7d, + 0xc4, 0x9e, 0xde, 0x63, 0xb0, 0xd3, 0x7a, 0x92, 0xbe, 0x52, 0xfe, + 0xbb, 0x22, 0x6c, 0x42, 0x40, 0xfd, 0x41, 0xc4, 0x87, 0x13}, + {0x14, 0x2d, 0xad, 0x5e, 0x38, 0x66, 0xf7, 0x4a, 0x30, 0x58, 0x7c, + 0xca, 0x80, 0xd8, 0x8e, 0xa0, 0x3d, 0x1e, 0x21, 0x10, 0xe6, 0xa6, + 0x13, 0xd, 0x3, 0x6c, 0x80, 0x7b, 0xe1, 0x1c, 0x7, 0x6a}, + {0xf8, 0x8a, 0x97, 0x87, 0xd1, 0xc3, 0xd3, 0xb5, 0x13, 0x44, 0xe, + 0x7f, 0x3d, 0x5a, 0x2b, 0x72, 0xa0, 0x7c, 0x47, 0xbb, 0x48, 0x48, + 0x7b, 0xd, 0x92, 0xdc, 0x1e, 0xaf, 0x6a, 0xb2, 0x71, 0x31}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1609516219779025, 777277757338817, 2101121130363987, - 550762194946473, 1905542338659364 -#else - 42616785, 23983660, 10368193, 11582341, 43711571, 31309144, - 16533929, 8206996, 36914212, 28394793 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2024821921041576, 426948675450149, 595133284085473, - 471860860885970, 600321679413000 -#else - 55987368, 30172197, 2307365, 6362031, 66973409, 8868176, - 50273234, 7031274, 7589640, 8945490 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 598474602406721, 1468128276358244, 1191923149557635, - 1501376424093216, 1281662691293476 -#else - 34956097, 8917966, 6661220, 21876816, 65916803, 17761038, - 7251488, 22372252, 24099108, 19098262 -#endif - }}, + {0xd1, 0x47, 0x8a, 0xb2, 0xd8, 0xb7, 0xd, 0xa6, 0xf1, 0xa4, 0x70, + 0x17, 0xd6, 0x14, 0xbf, 0xa6, 0x58, 0xbd, 0xdd, 0x53, 0x93, 0xf8, + 0xa1, 0xd4, 0xe9, 0x43, 0x42, 0x34, 0x63, 0x4a, 0x51, 0x6c}, + {0xa8, 0x4c, 0x56, 0x97, 0x90, 0x31, 0x2f, 0xa9, 0x19, 0xe1, 0x75, + 0x22, 0x4c, 0xb8, 0x7b, 0xff, 0x50, 0x51, 0x87, 0xa4, 0x37, 0xfe, + 0x55, 0x4f, 0x5a, 0x83, 0xf0, 0x3c, 0x87, 0xd4, 0x1f, 0x22}, + {0x41, 0x63, 0x15, 0x3a, 0x4f, 0x20, 0x22, 0x23, 0x2d, 0x3, 0xa, + 0xba, 0xe9, 0xe0, 0x73, 0xfb, 0xe, 0x3, 0xf, 0x41, 0x4c, 0xdd, + 0xe0, 0xfc, 0xaa, 0x4a, 0x92, 0xfb, 0x96, 0xa5, 0xda, 0x48}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1721138489890707, 1264336102277790, 433064545421287, - 1359988423149466, 1561871293409447 -#else - 5019539, 25646962, 4244126, 18840076, 40175591, 6453164, - 47990682, 20265406, 60876967, 23273695 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 719520245587143, 393380711632345, 132350400863381, - 1543271270810729, 1819543295798660 -#else - 10853575, 10721687, 26480089, 5861829, 44113045, 1972174, - 65242217, 22996533, 63745412, 27113307 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 396397949784152, 1811354474471839, 1362679985304303, - 2117033964846756, 498041172552279 -#else - 50106456, 5906789, 221599, 26991285, 7828207, 20305514, - 24362660, 31546264, 53242455, 7421391 -#endif - }}, + {0x93, 0x97, 0x4c, 0xc8, 0x5d, 0x1d, 0xf6, 0x14, 0x6, 0x82, 0x41, + 0xef, 0xe3, 0xf9, 0x41, 0x99, 0xac, 0x77, 0x62, 0x34, 0x8f, 0xb8, + 0xf5, 0xcd, 0xa9, 0x79, 0x8a, 0xe, 0xfa, 0x37, 0xc8, 0x58}, + {0xc7, 0x9c, 0xa5, 0x5c, 0x66, 0x8e, 0xca, 0x6e, 0xa0, 0xac, 0x38, + 0x2e, 0x4b, 0x25, 0x47, 0xa8, 0xce, 0x17, 0x1e, 0xd2, 0x8, 0xc7, + 0xaf, 0x31, 0xf7, 0x4a, 0xd8, 0xca, 0xfc, 0xd6, 0x6d, 0x67}, + {0x58, 0x90, 0xfc, 0x96, 0x85, 0x68, 0xf9, 0xc, 0x1b, 0xa0, 0x56, + 0x7b, 0xf3, 0xbb, 0xdc, 0x1d, 0x6a, 0xd6, 0x35, 0x49, 0x7d, 0xe7, + 0xc2, 0xdc, 0xa, 0x7f, 0xa5, 0xc6, 0xf2, 0x73, 0x4f, 0x1c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1812471844975748, 1856491995543149, 126579494584102, - 1036244859282620, 1975108050082550 -#else - 8139908, 27007935, 32257645, 27663886, 30375718, 1886181, - 45933756, 15441251, 28826358, 29431403 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 650623932407995, 1137551288410575, 2125223403615539, - 1725658013221271, 2134892965117796 -#else - 6267067, 9695052, 7709135, 16950835, 34239795, 31668296, - 14795159, 25714308, 13746020, 31812384 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 522584000310195, 1241762481390450, 1743702789495384, - 2227404127826575, 1686746002148897 -#else - 28584883, 7787108, 60375922, 18503702, 22846040, 25983196, - 63926927, 33190907, 4771361, 25134474 -#endif - }}, + {0x84, 0x34, 0x7c, 0xfc, 0x6e, 0x70, 0x6e, 0xb3, 0x61, 0xcf, 0xc1, + 0xc3, 0xb4, 0xc9, 0xdf, 0x73, 0xe5, 0xc7, 0x1c, 0x78, 0xc9, 0x79, + 0x1d, 0xeb, 0x5c, 0x67, 0xaf, 0x7d, 0xdb, 0x9a, 0x45, 0x70}, + {0xbb, 0xa0, 0x5f, 0x30, 0xbd, 0x4f, 0x7a, 0xe, 0xad, 0x63, 0xc6, + 0x54, 0xe0, 0x4c, 0x9d, 0x82, 0x48, 0x38, 0xe3, 0x2f, 0x83, 0xc3, + 0x21, 0xf4, 0x42, 0x4c, 0xf6, 0x1b, 0xd, 0xc8, 0x5a, 0x79}, + {0xb3, 0x2b, 0xb4, 0x91, 0x49, 0xdb, 0x91, 0x1b, 0xca, 0xdc, 0x2, + 0x4b, 0x23, 0x96, 0x26, 0x57, 0xdc, 0x78, 0x8c, 0x1f, 0xe5, 0x9e, + 0xdf, 0x9f, 0xd3, 0x1f, 0xe2, 0x8c, 0x84, 0x62, 0xe1, 0x5f}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 427904865186312, 1703211129693455, 1585368107547509, - 1436984488744336, 761188534613978 -#else - 24949256, 6376279, 39642383, 25379823, 48462709, 23623825, - 33543568, 21412737, 3569626, 11342593 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 318101947455002, 248138407995851, 1481904195303927, - 309278454311197, 1258516760217879 -#else - 26514970, 4740088, 27912651, 3697550, 19331575, 22082093, - 6809885, 4608608, 7325975, 18753361 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1275068538599310, 513726919533379, 349926553492294, - 688428871968420, 1702400196000666 -#else - 55490446, 19000001, 42787651, 7655127, 65739590, 5214311, - 39708324, 10258389, 49462170, 25367739 -#endif - }}, + {0x8, 0xb2, 0x7c, 0x5d, 0x2d, 0x85, 0x79, 0x28, 0xe7, 0xf2, 0x7d, + 0x68, 0x70, 0xdd, 0xde, 0xb8, 0x91, 0x78, 0x68, 0x21, 0xab, 0xff, + 0xb, 0xdc, 0x35, 0xaa, 0x7d, 0x67, 0x43, 0xc0, 0x44, 0x2b}, + {0x1a, 0x96, 0x94, 0xe1, 0x4f, 0x21, 0x59, 0x4e, 0x4f, 0xcd, 0x71, + 0xd, 0xc7, 0x7d, 0xbe, 0x49, 0x2d, 0xf2, 0x50, 0x3b, 0xd2, 0xcf, + 0x0, 0x93, 0x32, 0x72, 0x91, 0xfc, 0x46, 0xd4, 0x89, 0x47}, + {0x8e, 0xb7, 0x4e, 0x7, 0xab, 0x87, 0x1c, 0x1a, 0x67, 0xf4, 0xda, + 0x99, 0x8e, 0xd1, 0xc6, 0xfa, 0x67, 0x90, 0x4f, 0x48, 0xcd, 0xbb, + 0xac, 0x3e, 0xe4, 0xa4, 0xb9, 0x2b, 0xef, 0x2e, 0xc5, 0x60}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1061864036265233, 961611260325381, 321859632700838, - 1045600629959517, 1985130202504038 -#else - 11431185, 15823007, 26570245, 14329124, 18029990, 4796082, - 35662685, 15580663, 9280358, 29580745 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1558816436882417, 1962896332636523, 1337709822062152, - 1501413830776938, 294436165831932 -#else - 66948081, 23228174, 44253547, 29249434, 46247496, 19933429, - 34297962, 22372809, 51563772, 4387440 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 818359826554971, 1862173000996177, 626821592884859, - 573655738872376, 1749691246745455 -#else - 46309467, 12194511, 3937617, 27748540, 39954043, 9340369, - 42594872, 8548136, 20617071, 26072431 -#endif - }}, + {0x11, 0x6d, 0xae, 0x7c, 0xc2, 0xc5, 0x2b, 0x70, 0xab, 0x8c, 0xa4, + 0x54, 0x9b, 0x69, 0xc7, 0x44, 0xb2, 0x2e, 0x49, 0xba, 0x56, 0x40, + 0xbc, 0xef, 0x6d, 0x67, 0xb6, 0xd9, 0x48, 0x72, 0xd7, 0x70}, + {0xf1, 0x8b, 0xfd, 0x3b, 0xbc, 0x89, 0x5d, 0xb, 0x1a, 0x55, 0xf3, + 0xc9, 0x37, 0x92, 0x6b, 0xb0, 0xf5, 0x28, 0x30, 0xd5, 0xb0, 0x16, + 0x4c, 0xe, 0xab, 0xca, 0xcf, 0x2c, 0x31, 0x9c, 0xbc, 0x10}, + {0x5b, 0xa0, 0xc2, 0x3e, 0x4b, 0xe8, 0x8a, 0xaa, 0xe0, 0x81, 0x17, + 0xed, 0xf4, 0x9e, 0x69, 0x98, 0xd1, 0x85, 0x8e, 0x70, 0xe4, 0x13, + 0x45, 0x79, 0x13, 0xf4, 0x76, 0xa9, 0xd3, 0x5b, 0x75, 0x63}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1988022651432119, 1082111498586040, 1834020786104821, - 1454826876423687, 692929915223122 -#else - 66170039, 29623845, 58394552, 16124717, 24603125, 27329039, - 53333511, 21678609, 24345682, 10325460 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2146513703733331, 584788900394667, 464965657279958, - 2183973639356127, 238371159456790 -#else - 47253587, 31985546, 44906155, 8714033, 14007766, 6928528, - 16318175, 32543743, 4766742, 3552007 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1129007025494441, 2197883144413266, 265142755578169, - 971864464758890, 1983715884903702 -#else - 45357481, 16823515, 1351762, 32751011, 63099193, 3950934, - 3217514, 14481909, 10988822, 29559670 -#endif - }}, + {0xb7, 0xac, 0xf1, 0x97, 0x18, 0x10, 0xc7, 0x3d, 0xd8, 0xbb, 0x65, + 0xc1, 0x5e, 0x7d, 0xda, 0x5d, 0xf, 0x2, 0xa1, 0xf, 0x9c, 0x5b, + 0x8e, 0x50, 0x56, 0x2a, 0xc5, 0x37, 0x17, 0x75, 0x63, 0x27}, + {0x53, 0x8, 0xd1, 0x2a, 0x3e, 0xa0, 0x5f, 0xb5, 0x69, 0x35, 0xe6, + 0x9e, 0x90, 0x75, 0x6f, 0x35, 0x90, 0xb8, 0x69, 0xbe, 0xfd, 0xf1, + 0xf9, 0x9f, 0x84, 0x6f, 0xc1, 0x8b, 0xc4, 0xc1, 0x8c, 0xd}, + {0xa9, 0x19, 0xb4, 0x6e, 0xd3, 0x2, 0x94, 0x2, 0xa5, 0x60, 0xb4, + 0x77, 0x7e, 0x4e, 0xb4, 0xf0, 0x56, 0x49, 0x3c, 0xd4, 0x30, 0x62, + 0xa8, 0xcf, 0xe7, 0x66, 0xd1, 0x7a, 0x8a, 0xdd, 0xc2, 0x70}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1291366624493075, 381456718189114, 1711482489312444, - 1815233647702022, 892279782992467 -#else - 15564307, 19242862, 3101242, 5684148, 30446780, 25503076, - 12677126, 27049089, 58813011, 13296004 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 444548969917454, 1452286453853356, 2113731441506810, - 645188273895859, 810317625309512 -#else - 57666574, 6624295, 36809900, 21640754, 62437882, 31497052, - 31521203, 9614054, 37108040, 12074673 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2242724082797924, 1373354730327868, 1006520110883049, - 2147330369940688, 1151816104883620 -#else - 4771172, 33419193, 14290748, 20464580, 27992297, 14998318, - 65694928, 31997715, 29832612, 17163397 -#endif - }}, + {0x13, 0x7e, 0xed, 0xb8, 0x7d, 0x96, 0xd4, 0x91, 0x7a, 0x81, 0x76, + 0xd7, 0xa, 0x2f, 0x25, 0x74, 0x64, 0x25, 0x85, 0xd, 0xe0, 0x82, + 0x9, 0xe4, 0xe5, 0x3c, 0xa5, 0x16, 0x38, 0x61, 0xb8, 0x32}, + {0xe, 0xec, 0x6f, 0x9f, 0x50, 0x94, 0x61, 0x65, 0x8d, 0x51, 0xc6, + 0x46, 0xa9, 0x7e, 0x2e, 0xee, 0x5c, 0x9b, 0xe0, 0x67, 0xf3, 0xc1, + 0x33, 0x97, 0x95, 0x84, 0x94, 0x63, 0x63, 0xac, 0xf, 0x2e}, + {0x64, 0xcd, 0x48, 0xe4, 0xbe, 0xf7, 0xe7, 0x79, 0xd0, 0x86, 0x78, + 0x8, 0x67, 0x3a, 0xc8, 0x6a, 0x2e, 0xdb, 0xe4, 0xa0, 0xd9, 0xd4, + 0x9f, 0xf8, 0x41, 0x4f, 0x5a, 0x73, 0x5c, 0x21, 0x79, 0x41}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1745720200383796, 1911723143175317, 2056329390702074, - 355227174309849, 879232794371100 -#else - 7064884, 26013258, 47946901, 28486894, 48217594, 30641695, - 25825241, 5293297, 39986204, 13101589 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 163723479936298, 115424889803150, 1156016391581227, - 1894942220753364, 1970549419986329 -#else - 64810282, 2439669, 59642254, 1719964, 39841323, 17225986, - 32512468, 28236839, 36752793, 29363474 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 681981452362484, 267208874112496, 1374683991933094, - 638600984916117, 646178654558546 -#else - 37102324, 10162315, 33928688, 3981722, 50626726, 20484387, - 14413973, 9515896, 19568978, 9628812 -#endif - }}, + {0x34, 0xcd, 0x6b, 0x28, 0xb9, 0x33, 0xae, 0xe4, 0xdc, 0xd6, 0x9d, + 0x55, 0xb6, 0x7e, 0xef, 0xb7, 0x1f, 0x8e, 0xd3, 0xb3, 0x1f, 0x14, + 0x8b, 0x27, 0x86, 0xc2, 0x41, 0x22, 0x66, 0x85, 0xfa, 0x31}, + {0x2a, 0xed, 0xdc, 0xd7, 0xe7, 0x94, 0x70, 0x8c, 0x70, 0x9c, 0xd3, + 0x47, 0xc3, 0x8a, 0xfb, 0x97, 0x2, 0xd9, 0x6, 0xa9, 0x33, 0xe0, + 0x3b, 0xe1, 0x76, 0x9d, 0xd9, 0xc, 0xa3, 0x44, 0x3, 0x70}, + {0xf4, 0x22, 0x36, 0x2e, 0x42, 0x6c, 0x82, 0xaf, 0x2d, 0x50, 0x33, + 0x98, 0x87, 0x29, 0x20, 0xc1, 0x23, 0x91, 0x38, 0x2b, 0xe1, 0xb7, + 0xc1, 0x9b, 0x89, 0x24, 0x95, 0xa9, 0x12, 0x23, 0xbb, 0x24}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 13378654854251, 106237307029567, 1944412051589651, - 1841976767925457, 230702819835573 -#else - 33053803, 199357, 15894591, 1583059, 27380243, 28973997, - 49269969, 27447592, 60817077, 3437739 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 260683893467075, 854060306077237, 913639551980112, - 4704576840123, 280254810808712 -#else - 48129987, 3884492, 19469877, 12726490, 15913552, 13614290, - 44147131, 70103, 7463304, 4176122 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 715374893080287, 1173334812210491, 1806524662079626, - 1894596008000979, 398905715033393 -#else - 39984863, 10659916, 11482427, 17484051, 12771466, 26919315, - 34389459, 28231680, 24216881, 5944158 -#endif - }}, + {0x6b, 0x5c, 0xf8, 0xf5, 0x2a, 0xc, 0xf8, 0x41, 0x94, 0x67, 0xfa, + 0x4, 0xc3, 0x84, 0x72, 0x68, 0xad, 0x1b, 0xba, 0xa3, 0x99, 0xdf, + 0x45, 0x89, 0x16, 0x5d, 0xeb, 0xff, 0xf9, 0x2a, 0x1d, 0xd}, + {0xc3, 0x67, 0xde, 0x32, 0x17, 0xed, 0xa8, 0xb1, 0x48, 0x49, 0x1b, + 0x46, 0x18, 0x94, 0xb4, 0x3c, 0xd2, 0xbc, 0xcf, 0x76, 0x43, 0x43, + 0xbd, 0x8e, 0x8, 0x80, 0x18, 0x1e, 0x87, 0x3e, 0xee, 0xf}, + {0xdf, 0x1e, 0x62, 0x32, 0xa1, 0x8a, 0xda, 0xa9, 0x79, 0x65, 0x22, + 0x59, 0xa1, 0x22, 0xb8, 0x30, 0x93, 0xc1, 0x9a, 0xa7, 0x7b, 0x19, + 0x4, 0x40, 0x76, 0x1d, 0x53, 0x18, 0x97, 0xd7, 0xac, 0x16}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 500026409727661, 1596431288195371, 1420380351989370, - 985211561521489, 392444930785633 -#else - 8894125, 7450974, 64444715, 23788679, 39028346, 21165316, - 19345745, 14680796, 11632993, 5847885 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2096421546958141, 1922523000950363, 789831022876840, - 427295144688779, 320923973161730 -#else - 26942781, 31239115, 9129563, 28647825, 26024104, 11769399, - 55590027, 6367193, 57381634, 4782139 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1927770723575450, 1485792977512719, 1850996108474547, - 551696031508956, 2126047405475647 -#else - 19916442, 28726022, 44198159, 22140040, 25606323, 27581991, - 33253852, 8220911, 6358847, 31680575 -#endif - }}, + {0xad, 0xb6, 0x87, 0x78, 0xc5, 0xc6, 0x59, 0xc9, 0xba, 0xfe, 0x90, + 0x5f, 0xad, 0x9e, 0xe1, 0x94, 0x4, 0xf5, 0x42, 0xa3, 0x62, 0x4e, + 0xe2, 0x16, 0x0, 0x17, 0x16, 0x18, 0x4b, 0xd3, 0x4e, 0x16}, + {0x3d, 0x1d, 0x9b, 0x2d, 0xaf, 0x72, 0xdf, 0x72, 0x5a, 0x24, 0x32, + 0xa4, 0x36, 0x2a, 0x46, 0x63, 0x37, 0x96, 0xb3, 0x16, 0x79, 0xa0, + 0xce, 0x3e, 0x9, 0x23, 0x30, 0xb9, 0xf6, 0xe, 0x3e, 0x12}, + {0x9a, 0xe6, 0x2f, 0x19, 0x4c, 0xd9, 0x7e, 0x48, 0x13, 0x15, 0x91, + 0x3a, 0xea, 0x2c, 0xae, 0x61, 0x27, 0xde, 0xa4, 0xb9, 0xd3, 0xf6, + 0x7b, 0x87, 0xeb, 0xf3, 0x73, 0x10, 0xc6, 0xf, 0xda, 0x78}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2112099158080148, 742570803909715, 6484558077432, - 1951119898618916, 93090382703416 -#else - 801428, 31472730, 16569427, 11065167, 29875704, 96627, 7908388, - 29073952, 53570360, 1387154 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 383905201636970, 859946997631870, 855623867637644, - 1017125780577795, 794250831877809 -#else - 19646058, 5720633, 55692158, 12814208, 11607948, 12749789, - 14147075, 15156355, 45242033, 11835259 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 77571826285752, 999304298101753, 487841111777762, - 1038031143212339, 339066367948762 -#else - 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, - 26121523, 15467869, 40548314, 5052482 -#endif - }}, + {0x94, 0x3a, 0xc, 0x68, 0xf1, 0x80, 0x9f, 0xa2, 0xe6, 0xe7, 0xe9, + 0x1a, 0x15, 0x7e, 0xf7, 0x71, 0x73, 0x79, 0x1, 0x48, 0x58, 0xf1, + 0x0, 0x11, 0xdd, 0x8d, 0xb3, 0x16, 0xb3, 0xa4, 0x4a, 0x5}, + {0x6a, 0xc6, 0x2b, 0xe5, 0x28, 0x5d, 0xf1, 0x5b, 0x8e, 0x1a, 0xf0, + 0x70, 0x18, 0xe3, 0x47, 0x2c, 0xdd, 0x8b, 0xc2, 0x6, 0xbc, 0xaf, + 0x19, 0x24, 0x3a, 0x17, 0x6b, 0x25, 0xeb, 0xde, 0x25, 0x2d}, + {0xb8, 0x7c, 0x26, 0x19, 0x8d, 0x46, 0xc8, 0xdf, 0xaf, 0x4d, 0xe5, + 0x66, 0x9c, 0x78, 0x28, 0xb, 0x17, 0xec, 0x6e, 0x66, 0x2a, 0x1d, + 0xeb, 0x2a, 0x60, 0xa7, 0x7d, 0xab, 0xa6, 0x10, 0x46, 0x13}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 674994775520533, 266035846330789, 826951213393478, - 1405007746162285, 1781791018620876 -#else - 64091413, 10058205, 1980837, 3964243, 22160966, 12322533, - 60677741, 20936246, 12228556, 26550755 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1001412661522686, 348196197067298, 1666614366723946, - 888424995032760, 580747687801357 -#else - 32944382, 14922211, 44263970, 5188527, 21913450, 24834489, - 4001464, 13238564, 60994061, 8653814 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1939560076207777, 1409892634407635, 552574736069277, - 383854338280405, 190706709864139 -#else - 22865569, 28901697, 27603667, 21009037, 14348957, 8234005, - 24808405, 5719875, 28483275, 2841751 -#endif - }}, + {0x15, 0xf5, 0xd1, 0x77, 0xe7, 0x65, 0x2a, 0xcd, 0xf1, 0x60, 0xaa, + 0x8f, 0x87, 0x91, 0x89, 0x54, 0xe5, 0x6, 0xbc, 0xda, 0xbc, 0x3b, + 0xb7, 0xb1, 0xfb, 0xc9, 0x7c, 0xa9, 0xcb, 0x78, 0x48, 0x65}, + {0xfe, 0xb0, 0xf6, 0x8d, 0xc7, 0x8e, 0x13, 0x51, 0x1b, 0xf5, 0x75, + 0xe5, 0x89, 0xda, 0x97, 0x53, 0xb9, 0xf1, 0x7a, 0x71, 0x1d, 0x7a, + 0x20, 0x9, 0x50, 0xd6, 0x20, 0x2b, 0xba, 0xfd, 0x2, 0x21}, + {0xa1, 0xe6, 0x5c, 0x5, 0x5, 0xe4, 0x9e, 0x96, 0x29, 0xad, 0x51, + 0x12, 0x68, 0xa7, 0xbc, 0x36, 0x15, 0xa4, 0x7d, 0xaa, 0x17, 0xf5, + 0x1a, 0x3a, 0xba, 0xb2, 0xec, 0x29, 0xdb, 0x25, 0xd7, 0xa}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2177087163428741, 1439255351721944, 1208070840382793, - 2230616362004769, 1396886392021913 -#else - 50687877, 32441126, 66781144, 21446575, 21886281, 18001658, - 65220897, 33238773, 19932057, 20815229 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 676962063230039, 1880275537148808, 2046721011602706, - 888463247083003, 1318301552024067 -#else - 55452759, 10087520, 58243976, 28018288, 47830290, 30498519, - 3999227, 13239134, 62331395, 19644223 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1466980508178206, 617045217998949, 652303580573628, - 757303753529064, 207583137376902 -#else - 1382174, 21859713, 17266789, 9194690, 53784508, 9720080, - 20403944, 11284705, 53095046, 3093229 -#endif - }}, + {0x85, 0x6f, 0x5, 0x9b, 0xc, 0xbc, 0xc7, 0xfe, 0xd7, 0xff, 0xf5, + 0xe7, 0x68, 0x52, 0x7d, 0x53, 0xfa, 0xae, 0x12, 0x43, 0x62, 0xc6, + 0xaf, 0x77, 0xd9, 0x9f, 0x39, 0x2, 0x53, 0x5f, 0x67, 0x4f}, + {0x57, 0x24, 0x4e, 0x83, 0xb1, 0x67, 0x42, 0xdc, 0xc5, 0x1b, 0xce, + 0x70, 0xb5, 0x44, 0x75, 0xb6, 0xd7, 0x5e, 0xd1, 0xf7, 0xb, 0x7a, + 0xf0, 0x1a, 0x50, 0x36, 0xa0, 0x71, 0xfb, 0xcf, 0xef, 0x4a}, + {0x1e, 0x17, 0x15, 0x4, 0x36, 0x36, 0x2d, 0xc3, 0x3b, 0x48, 0x98, + 0x89, 0x11, 0xef, 0x2b, 0xcd, 0x10, 0x51, 0x94, 0xd0, 0xad, 0x6e, + 0xa, 0x87, 0x61, 0x65, 0xa8, 0xa2, 0x72, 0xbb, 0xcc, 0xb}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1511056752906902, 105403126891277, 493434892772846, - 1091943425335976, 1802717338077427 -#else - 16650902, 22516500, 66044685, 1570628, 58779118, 7352752, - 66806440, 16271224, 43059443, 26862581 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1853982405405128, 1878664056251147, 1528011020803992, - 1019626468153565, 1128438412189035 -#else - 45197768, 27626490, 62497547, 27994275, 35364760, 22769138, - 24123613, 15193618, 45456747, 16815042 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1963939888391106, 293456433791664, 697897559513649, - 985882796904380, 796244541237972 -#else - 57172930, 29264984, 41829040, 4372841, 2087473, 10399484, - 31870908, 14690798, 17361620, 11864968 -#endif - }}, + {0x96, 0x12, 0xfe, 0x50, 0x4c, 0x5e, 0x6d, 0x18, 0x7e, 0x9f, 0xe8, + 0xfe, 0x82, 0x7b, 0x39, 0xe0, 0xb0, 0x31, 0x70, 0x50, 0xc5, 0xf6, + 0xc7, 0x3b, 0xc2, 0x37, 0x8f, 0x10, 0x69, 0xfd, 0x78, 0x66}, + {0xc8, 0xa9, 0xb1, 0xea, 0x2f, 0x96, 0x5e, 0x18, 0xcd, 0x7d, 0x14, + 0x65, 0x35, 0xe6, 0xe7, 0x86, 0xf2, 0x6d, 0x5b, 0xbb, 0x31, 0xe0, + 0x92, 0xb0, 0x3e, 0xb7, 0xd6, 0x59, 0xab, 0xf0, 0x24, 0x40}, + {0xc2, 0x63, 0x68, 0x63, 0x31, 0xfa, 0x86, 0x15, 0xf2, 0x33, 0x2d, + 0x57, 0x48, 0x8c, 0xf6, 0x7, 0xfc, 0xae, 0x9e, 0x78, 0x9f, 0xcc, + 0x73, 0x4f, 0x1, 0x47, 0xad, 0x8e, 0x10, 0xe2, 0x42, 0x2d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 416770998629779, 389655552427054, 1314476859406756, - 1749382513022778, 1161905598739491 -#else - 55801235, 6210371, 13206574, 5806320, 38091172, 19587231, - 54777658, 26067830, 41530403, 17313742 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1428358296490651, 1027115282420478, 304840698058337, - 441410174026628, 1819358356278573 -#else - 14668443, 21284197, 26039038, 15305210, 25515617, 4542480, - 10453892, 6577524, 9145645, 27110552 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 204943430200135, 1554861433819175, 216426658514651, - 264149070665950, 2047097371738319 -#else - 5974855, 3053895, 57675815, 23169240, 35243739, 3225008, - 59136222, 3936127, 61456591, 30504127 -#endif - }}, + {0x93, 0x75, 0x53, 0xf, 0xd, 0x7b, 0x71, 0x21, 0x4c, 0x6, 0x1e, + 0x13, 0xb, 0x69, 0x4e, 0x91, 0x9f, 0xe0, 0x2a, 0x75, 0xae, 0x87, + 0xb6, 0x1b, 0x6e, 0x3c, 0x42, 0x9b, 0xa7, 0xf3, 0xb, 0x42}, + {0x9b, 0xd2, 0xdf, 0x94, 0x15, 0x13, 0xf5, 0x97, 0x6a, 0x4c, 0x3f, + 0x31, 0x5d, 0x98, 0x55, 0x61, 0x10, 0x50, 0x45, 0x8, 0x7, 0x3f, + 0xa1, 0xeb, 0x22, 0xd3, 0xd2, 0xb8, 0x8, 0x26, 0x6b, 0x67}, + {0x47, 0x2b, 0x5b, 0x1c, 0x65, 0xba, 0x38, 0x81, 0x80, 0x1b, 0x1b, + 0x31, 0xec, 0xb6, 0x71, 0x86, 0xb0, 0x35, 0x31, 0xbc, 0xb1, 0xc, + 0xff, 0x7b, 0xe0, 0xf1, 0xc, 0x9c, 0xfa, 0x2f, 0x5d, 0x74}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1934415182909034, 1393285083565062, 516409331772960, - 1157690734993892, 121039666594268 -#else - 30625386, 28825032, 41552902, 20761565, 46624288, 7695098, - 17097188, 17250936, 39109084, 1803631 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 662035583584445, 286736105093098, 1131773000510616, - 818494214211439, 472943792054479 -#else - 63555773, 9865098, 61880298, 4272700, 61435032, 16864731, - 14911343, 12196514, 45703375, 7047411 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 665784778135882, 1893179629898606, 808313193813106, - 276797254706413, 1563426179676396 -#else - 20093258, 9920966, 55970670, 28210574, 13161586, 12044805, - 34252013, 4124600, 34765036, 23296865 -#endif - }}, + {0x6a, 0x4e, 0xd3, 0x21, 0x57, 0xdf, 0x36, 0x60, 0xd0, 0xb3, 0x7b, + 0x99, 0x27, 0x88, 0xdb, 0xb1, 0xfa, 0x6a, 0x75, 0xc8, 0xc3, 0x9, + 0xc2, 0xd3, 0x39, 0xc8, 0x1d, 0x4c, 0xe5, 0x5b, 0xe1, 0x6}, + {0xbd, 0xc8, 0xc9, 0x2b, 0x1e, 0x5a, 0x52, 0xbf, 0x81, 0x9d, 0x47, + 0x26, 0x8, 0x26, 0x5b, 0xea, 0xdb, 0x55, 0x1, 0xdf, 0xe, 0xc7, + 0x11, 0xd5, 0xd0, 0xf5, 0xc, 0x96, 0xeb, 0x3c, 0xe2, 0x1a}, + {0x4a, 0x99, 0x32, 0x19, 0x87, 0x5d, 0x72, 0x5b, 0xb0, 0xda, 0xb1, + 0xce, 0xb5, 0x1c, 0x35, 0x32, 0x5, 0xca, 0xb7, 0xda, 0x49, 0x15, + 0xc4, 0x7d, 0xf7, 0xc1, 0x8e, 0x27, 0x61, 0xd8, 0xde, 0x58}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 945205108984232, 526277562959295, 1324180513733566, - 1666970227868664, 153547609289173 -#else - 46320040, 14084653, 53577151, 7842146, 19119038, 19731827, - 4752376, 24839792, 45429205, 2288037 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2031433403516252, 203996615228162, 170487168837083, - 981513604791390, 843573964916831 -#else - 40289628, 30270716, 29965058, 3039786, 52635099, 2540456, - 29457502, 14625692, 42289247, 12570231 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1476570093962618, 838514669399805, 1857930577281364, - 2017007352225784, 317085545220047 -#else - 66045306, 22002608, 16920317, 12494842, 1278292, 27685323, - 45948920, 30055751, 55134159, 4724942 -#endif - }}, + {0xa8, 0xc9, 0xc2, 0xb6, 0xa8, 0x5b, 0xfb, 0x2d, 0x8c, 0x59, 0x2c, + 0xf5, 0x8e, 0xef, 0xee, 0x48, 0x73, 0x15, 0x2d, 0xf1, 0x7, 0x91, + 0x80, 0x33, 0xd8, 0x5b, 0x1d, 0x53, 0x6b, 0x69, 0xba, 0x8}, + {0x5c, 0xc5, 0x66, 0xf2, 0x93, 0x37, 0x17, 0xd8, 0x49, 0x4e, 0x45, + 0xcc, 0xc5, 0x76, 0xc9, 0xc8, 0xa8, 0xc3, 0x26, 0xbc, 0xf8, 0x82, + 0xe3, 0x5c, 0xf9, 0xf6, 0x85, 0x54, 0xe8, 0x9d, 0xf3, 0x2f}, + {0x7a, 0xc5, 0xef, 0xc3, 0xee, 0x3e, 0xed, 0x77, 0x11, 0x48, 0xff, + 0xd4, 0x17, 0x55, 0xe0, 0x4, 0xcb, 0x71, 0xa6, 0xf1, 0x3f, 0x7a, + 0x3d, 0xea, 0x54, 0xfe, 0x7c, 0x94, 0xb4, 0x33, 0x6, 0x12}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1461557121912842, 1600674043318359, 2157134900399597, - 1670641601940616, 127765583803283 -#else - 17960970, 21778898, 62967895, 23851901, 58232301, 32143814, - 54201480, 24894499, 37532563, 1903855 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1293543509393474, 2143624609202546, 1058361566797508, - 214097127393994, 946888515472729 -#else - 23134274, 19275300, 56426866, 31942495, 20684484, 15770816, - 54119114, 3190295, 26955097, 14109738 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 357067959932916, 1290876214345711, 521245575443703, - 1494975468601005, 800942377643885 -#else - 15308788, 5320727, 36995055, 19235554, 22902007, 7767164, - 29425325, 22276870, 31960941, 11934971 -#endif - }}, + {0xa, 0x10, 0x12, 0x49, 0x47, 0x31, 0xbd, 0x82, 0x6, 0xbe, 0x6f, + 0x7e, 0x6d, 0x7b, 0x23, 0xde, 0xc6, 0x79, 0xea, 0x11, 0x19, 0x76, + 0x1e, 0xe1, 0xde, 0x3b, 0x39, 0xcb, 0xe3, 0x3b, 0x43, 0x7}, + {0x42, 0x0, 0x61, 0x91, 0x78, 0x98, 0x94, 0xb, 0xe8, 0xfa, 0xeb, + 0xec, 0x3c, 0xb1, 0xe7, 0x4e, 0xc0, 0xa4, 0xf0, 0x94, 0x95, 0x73, + 0xbe, 0x70, 0x85, 0x91, 0xd5, 0xb4, 0x99, 0xa, 0xd3, 0x35}, + {0xf4, 0x97, 0xe9, 0x5c, 0xc0, 0x44, 0x79, 0xff, 0xa3, 0x51, 0x5c, + 0xb0, 0xe4, 0x3d, 0x5d, 0x57, 0x7c, 0x84, 0x76, 0x5a, 0xfd, 0x81, + 0x33, 0x58, 0x9f, 0xda, 0xf6, 0x7a, 0xde, 0x3e, 0x87, 0x2d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 566116659100033, 820247422481740, 994464017954148, - 327157611686365, 92591318111744 -#else - 39713153, 8435795, 4109644, 12222639, 42480996, 14818668, - 20638173, 4875028, 10491392, 1379718 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 617256647603209, 1652107761099439, 1857213046645471, - 1085597175214970, 817432759830522 -#else - 53949449, 9197840, 3875503, 24618324, 65725151, 27674630, - 33518458, 16176658, 21432314, 12180697 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 771808161440705, 1323510426395069, 680497615846440, - 851580615547985, 1320806384849017 -#else - 55321537, 11500837, 13787581, 19721842, 44678184, 10140204, - 1465425, 12689540, 56807545, 19681548 -#endif - }}, + {0x81, 0xf9, 0x5d, 0x4e, 0xe1, 0x2, 0x62, 0xaa, 0xf5, 0xe1, 0x15, + 0x50, 0x17, 0x59, 0xd, 0xa2, 0x6c, 0x1d, 0xe2, 0xba, 0xd3, 0x75, + 0xa2, 0x18, 0x53, 0x2, 0x60, 0x1, 0x8a, 0x61, 0x43, 0x5}, + {0x9, 0x34, 0x37, 0x43, 0x64, 0x31, 0x7a, 0x15, 0xd9, 0x81, 0xaa, + 0xf4, 0xee, 0xb7, 0xb8, 0xfa, 0x6, 0x48, 0xa6, 0xf5, 0xe6, 0xfe, + 0x93, 0xb0, 0xb6, 0xa7, 0x7f, 0x70, 0x54, 0x36, 0x77, 0x2e}, + {0xc1, 0x23, 0x4c, 0x97, 0xf4, 0xbd, 0xea, 0xd, 0x93, 0x46, 0xce, + 0x9d, 0x25, 0xa, 0x6f, 0xaa, 0x2c, 0xba, 0x9a, 0xa2, 0xb8, 0x2c, + 0x20, 0x4, 0xd, 0x96, 0x7, 0x2d, 0x36, 0x43, 0x14, 0x4b}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1219260086131915, 647169006596815, 79601124759706, - 2161724213426748, 404861897060198 -#else - 5414091, 18168391, 46101199, 9643569, 12834970, 1186149, - 64485948, 32212200, 26128230, 6032912 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1327968293887866, 1335500852943256, 1401587164534264, - 558137311952440, 1551360549268902 -#else - 40771450, 19788269, 32496024, 19900513, 17847800, 20885276, - 3604024, 8316894, 41233830, 23117073 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 417621685193956, 1429953819744454, 396157358457099, - 1940470778873255, 214000046234152 -#else - 3296484, 6223048, 24680646, 21307972, 44056843, 5903204, - 58246567, 28915267, 12376616, 3188849 -#endif - }}, + {0xcb, 0x9c, 0x52, 0x1c, 0xe9, 0x54, 0x7c, 0x96, 0xfb, 0x35, 0xc6, + 0x64, 0x92, 0x26, 0xf6, 0x30, 0x65, 0x19, 0x12, 0x78, 0xf4, 0xaf, + 0x47, 0x27, 0x5c, 0x6f, 0xf6, 0xea, 0x18, 0x84, 0x3, 0x17}, + {0x7a, 0x1f, 0x6e, 0xb6, 0xc7, 0xb7, 0xc4, 0xcc, 0x7e, 0x2f, 0xc, + 0xf5, 0x25, 0x7e, 0x15, 0x44, 0x1c, 0xaf, 0x3e, 0x71, 0xfc, 0x6d, + 0xf0, 0x3e, 0xf7, 0x63, 0xda, 0x52, 0x67, 0x44, 0x2f, 0x58}, + {0xe4, 0x4c, 0x32, 0x20, 0xd3, 0x7b, 0x31, 0xc6, 0xc4, 0x8b, 0x48, + 0xa4, 0xe8, 0x42, 0x10, 0xa8, 0x64, 0x13, 0x5a, 0x4e, 0x8b, 0xf1, + 0x1e, 0xb2, 0xc9, 0x8d, 0xa2, 0xcd, 0x4b, 0x1c, 0x2a, 0xc}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1268047918491973, 2172375426948536, 1533916099229249, - 1761293575457130, 1590622667026765 -#else - 29190469, 18895386, 27549112, 32370916, 3520065, 22857131, - 32049514, 26245319, 50999629, 23702124 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1627072914981959, 2211603081280073, 1912369601616504, - 1191770436221309, 2187309757525860 -#else - 52364359, 24245275, 735817, 32955454, 46701176, 28496527, - 25246077, 17758763, 18640740, 32593455 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1149147819689533, 378692712667677, 828475842424202, - 2218619146419342, 70688125792186 -#else - 60180029, 17123636, 10361373, 5642961, 4910474, 12345252, - 35470478, 33060001, 10530746, 1053335 -#endif - }}, + {0x45, 0x69, 0xbd, 0x69, 0x48, 0x81, 0xc4, 0xed, 0x22, 0x8d, 0x1c, + 0xbe, 0x7d, 0x90, 0x6d, 0xd, 0xab, 0xc5, 0x5c, 0xd5, 0x12, 0xd2, + 0x3b, 0xc6, 0x83, 0xdc, 0x14, 0xa3, 0x30, 0x9b, 0x6a, 0x5a}, + {0x47, 0x4, 0x1f, 0x6f, 0xd0, 0xc7, 0x4d, 0xd2, 0x59, 0xc0, 0x87, + 0xdb, 0x3e, 0x9e, 0x26, 0xb2, 0x8f, 0xd2, 0xb2, 0xfb, 0x72, 0x2, + 0x5b, 0xd1, 0x77, 0x48, 0xf6, 0xc6, 0xd1, 0x8b, 0x55, 0x7c}, + {0x3d, 0x46, 0x96, 0xd3, 0x24, 0x15, 0xec, 0xd0, 0xf0, 0x24, 0x5a, + 0xc3, 0x8a, 0x62, 0xbb, 0x12, 0xa4, 0x5f, 0xbc, 0x1c, 0x79, 0x3a, + 0xc, 0xa5, 0xc3, 0xaf, 0xfb, 0xa, 0xca, 0xa5, 0x4, 0x4}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1299739417079761, 1438616663452759, 1536729078504412, - 2053896748919838, 1008421032591246 -#else - 37842897, 19367626, 53570647, 21437058, 47651804, 22899047, - 35646494, 30605446, 24018830, 15026644 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2040723824657366, 399555637875075, 632543375452995, - 872649937008051, 1235394727030233 -#else - 44516310, 30409154, 64819587, 5953842, 53668675, 9425630, - 25310643, 13003497, 64794073, 18408815 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2211311599327900, 2139787259888175, 938706616835350, - 12609661139114, 2081897930719789 -#else - 39688860, 32951110, 59064879, 31885314, 41016598, 13987818, - 39811242, 187898, 43942445, 31022696 -#endif - }}, + {0xd1, 0x6f, 0x41, 0x2a, 0x1b, 0x9e, 0xbc, 0x62, 0x8b, 0x59, 0x50, + 0xe3, 0x28, 0xf7, 0xc6, 0xb5, 0x67, 0x69, 0x5d, 0x3d, 0xd8, 0x3f, + 0x34, 0x4, 0x98, 0xee, 0xf8, 0xe7, 0x16, 0x75, 0x52, 0x39}, + {0xd6, 0x43, 0xa7, 0xa, 0x7, 0x40, 0x1f, 0x8c, 0xe8, 0x5e, 0x26, + 0x5b, 0xcb, 0xd0, 0xba, 0xcc, 0xde, 0xd2, 0x8f, 0x66, 0x6b, 0x4, + 0x4b, 0x57, 0x33, 0x96, 0xdd, 0xca, 0xfd, 0x5b, 0x39, 0x46}, + {0x9c, 0x9a, 0x5d, 0x1a, 0x2d, 0xdb, 0x7f, 0x11, 0x2a, 0x5c, 0x0, + 0xd1, 0xbc, 0x45, 0x77, 0x9c, 0xea, 0x6f, 0xd5, 0x54, 0xf1, 0xbe, + 0xd4, 0xef, 0x16, 0xd0, 0x22, 0xe8, 0x29, 0x9a, 0x57, 0x76}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1324994503390450, 336982330582631, 1183998925654177, - 1091654665913274, 48727673971319 -#else - 45364466, 19743956, 1844839, 5021428, 56674465, 17642958, - 9716666, 16266922, 62038647, 726098 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1845522914617879, 1222198248335542, 150841072760134, - 1927029069940982, 1189913404498011 -#else - 29370903, 27500434, 7334070, 18212173, 9385286, 2247707, - 53446902, 28714970, 30007387, 17731091 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1079559557592645, 2215338383666441, 1903569501302605, - 49033973033940, 305703433934152 -#else - 66172485, 16086690, 23751945, 33011114, 65941325, 28365395, - 9137108, 730663, 9835848, 4555336 -#endif - }}, + {0xf2, 0x34, 0xb4, 0x52, 0x13, 0xb5, 0x3c, 0x33, 0xe1, 0x80, 0xde, + 0x93, 0x49, 0x28, 0x32, 0xd8, 0xce, 0x35, 0xd, 0x75, 0x87, 0x28, + 0x51, 0xb5, 0xc1, 0x77, 0x27, 0x2a, 0xbb, 0x14, 0xc5, 0x2}, + {0x17, 0x2a, 0xc0, 0x49, 0x7e, 0x8e, 0xb6, 0x45, 0x7f, 0xa3, 0xa9, + 0xbc, 0xa2, 0x51, 0xcd, 0x23, 0x1b, 0x4c, 0x22, 0xec, 0x11, 0x5f, + 0xd6, 0x3e, 0xb1, 0xbd, 0x5, 0x9e, 0xdc, 0x84, 0xa3, 0x43}, + {0x45, 0xb6, 0xf1, 0x8b, 0xda, 0xd5, 0x4b, 0x68, 0x53, 0x4b, 0xb5, + 0xf6, 0x7e, 0xd3, 0x8b, 0xfb, 0x53, 0xd2, 0xb0, 0xa9, 0xd7, 0x16, + 0x39, 0x31, 0x59, 0x80, 0x54, 0x61, 0x9, 0x92, 0x60, 0x11}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 94653405416909, 1386121349852999, 1062130477891762, - 36553947479274, 833669648948846 -#else - 43732429, 1410445, 44855111, 20654817, 30867634, 15826977, - 17693930, 544696, 55123566, 12422645 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1432015813136298, 440364795295369, 1395647062821501, - 1976874522764578, 934452372723352 -#else - 31117226, 21338698, 53606025, 6561946, 57231997, 20796761, - 61990178, 29457725, 29120152, 13924425 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1296625309219774, 2068273464883862, 1858621048097805, - 1492281814208508, 2235868981918946 -#else - 49707966, 19321222, 19675798, 30819676, 56101901, 27695611, - 57724924, 22236731, 7240930, 33317044 -#endif - }}, + {0xcd, 0x4d, 0x9b, 0x36, 0x16, 0x56, 0x38, 0x7a, 0x63, 0x35, 0x5c, + 0x65, 0xa7, 0x2c, 0xc0, 0x75, 0x21, 0x80, 0xf1, 0xd4, 0xf9, 0x1b, + 0xc2, 0x7d, 0x42, 0xe0, 0xe6, 0x91, 0x74, 0x7d, 0x63, 0x2f}, + {0xaa, 0xcf, 0xda, 0x29, 0x69, 0x16, 0x4d, 0xb4, 0x8f, 0x59, 0x13, + 0x84, 0x4c, 0x9f, 0x52, 0xda, 0x59, 0x55, 0x3d, 0x45, 0xca, 0x63, + 0xef, 0xe9, 0xb, 0x8e, 0x69, 0xc5, 0x5b, 0x12, 0x1e, 0x35}, + {0xbe, 0x7b, 0xf6, 0x1a, 0x46, 0x9b, 0xb4, 0xd4, 0x61, 0x89, 0xab, + 0xc8, 0x7a, 0x3, 0x3, 0xd6, 0xfb, 0x99, 0xa6, 0xf9, 0x9f, 0xe1, + 0xde, 0x71, 0x9a, 0x2a, 0xce, 0xe7, 0x6, 0x2d, 0x18, 0x7f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1490330266465570, 1858795661361448, 1436241134969763, - 294573218899647, 1208140011028933 -#else - 35747106, 22207651, 52101416, 27698213, 44655523, 21401660, - 1222335, 4389483, 3293637, 18002689 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1282462923712748, 741885683986255, 2027754642827561, - 518989529541027, 1826610009555945 -#else - 50424044, 19110186, 11038543, 11054958, 53307689, 30215898, - 42789283, 7733546, 12796905, 27218610 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1525827120027511, 723686461809551, 1597702369236987, - 244802101764964, 1502833890372311 -#else - 58349431, 22736595, 41689999, 10783768, 36493307, 23807620, - 38855524, 3647835, 3222231, 22393970 -#endif - }}, + {0x22, 0x75, 0x21, 0x8e, 0x72, 0x4b, 0x45, 0x9, 0xd8, 0xb8, 0x84, + 0xd4, 0xf4, 0xe8, 0x58, 0xaa, 0x3c, 0x90, 0x46, 0x7f, 0x4d, 0x25, + 0x58, 0xd3, 0x17, 0x52, 0x1c, 0x24, 0x43, 0xc0, 0xac, 0x44}, + {0xec, 0x68, 0x1, 0xab, 0x64, 0x8e, 0x7c, 0x7a, 0x43, 0xc5, 0xed, + 0x15, 0x55, 0x4a, 0x5a, 0xcb, 0xda, 0xe, 0xcd, 0x47, 0xd3, 0x19, + 0x55, 0x9, 0xb0, 0x93, 0x3e, 0x34, 0x8c, 0xac, 0xd4, 0x67}, + {0x77, 0x57, 0x7a, 0x4f, 0xbb, 0x6b, 0x7d, 0x1c, 0xe1, 0x13, 0x83, + 0x91, 0xd4, 0xfe, 0x35, 0x8b, 0x84, 0x46, 0x6b, 0xc9, 0xc6, 0xa1, + 0xdc, 0x4a, 0xbd, 0x71, 0xad, 0x12, 0x83, 0x1c, 0x6d, 0x55}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 113622036244513, 1233740067745854, 674109952278496, - 2114345180342965, 166764512856263 -#else - 18606113, 1693100, 41660478, 18384159, 4112352, 10045021, - 23603893, 31506198, 59558087, 2484984 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2041668749310338, 2184405322203901, 1633400637611036, - 2110682505536899, 2048144390084644 -#else - 9255298, 30423235, 54952701, 32550175, 13098012, 24339566, - 16377219, 31451620, 47306788, 30519729 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 503058759232932, 760293024620937, 2027152777219493, - 666858468148475, 1539184379870952 -#else - 44379556, 7496159, 61366665, 11329248, 19991973, 30206930, - 35390715, 9936965, 37011176, 22935634 -#endif - }}, + {0x21, 0xe8, 0x1b, 0xb1, 0x56, 0x67, 0xf0, 0x81, 0xdd, 0xf3, 0xa3, + 0x10, 0x23, 0xf8, 0xaf, 0xf, 0x5d, 0x46, 0x99, 0x6a, 0x55, 0xd0, + 0xb2, 0xf8, 0x5, 0x7f, 0x8c, 0xcc, 0x38, 0xbe, 0x7a, 0x9}, + {0x82, 0x39, 0x8d, 0xc, 0xe3, 0x40, 0xef, 0x17, 0x34, 0xfa, 0xa3, + 0x15, 0x3e, 0x7, 0xf7, 0x31, 0x6e, 0x64, 0x73, 0x7, 0xcb, 0xf3, + 0x21, 0x4f, 0xff, 0x4e, 0x82, 0x1d, 0x6d, 0x6c, 0x6c, 0x74}, + {0xa4, 0x2d, 0xa5, 0x7e, 0x87, 0xc9, 0x49, 0xc, 0x43, 0x1d, 0xdc, + 0x9b, 0x55, 0x69, 0x43, 0x4c, 0xd2, 0xeb, 0xcc, 0xf7, 0x9, 0x38, + 0x2c, 0x2, 0xbd, 0x84, 0xee, 0x4b, 0xa3, 0x14, 0x7e, 0x57}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1916168475367211, 915626432541343, 883217071712575, - 363427871374304, 1976029821251593 -#else - 21878571, 28553135, 4338335, 13643897, 64071999, 13160959, - 19708896, 5415497, 59748361, 29445138 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 678039535434506, 570587290189340, 1605302676614120, - 2147762562875701, 1706063797091704 -#else - 27736842, 10103576, 12500508, 8502413, 63695848, 23920873, - 10436917, 32004156, 43449720, 25422331 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1439489648586438, 2194580753290951, 832380563557396, - 561521973970522, 584497280718389 -#else - 19492550, 21450067, 37426887, 32701801, 63900692, 12403436, - 30066266, 8367329, 13243957, 8709688 -#endif - }}, + {0x2b, 0xd7, 0x4d, 0xbd, 0xbe, 0xce, 0xfe, 0x94, 0x11, 0x22, 0xf, + 0x6, 0xda, 0x4f, 0x6a, 0xf4, 0xff, 0xd1, 0xc8, 0xc0, 0x77, 0x59, + 0x4a, 0x12, 0x95, 0x92, 0x0, 0xfb, 0xb8, 0x4, 0x53, 0x70}, + {0xa, 0x3b, 0xa7, 0x61, 0xac, 0x68, 0xe2, 0xf0, 0xf5, 0xa5, 0x91, + 0x37, 0x10, 0xfa, 0xfa, 0xf2, 0xe9, 0x0, 0x6d, 0x6b, 0x82, 0x3e, + 0xe1, 0xc1, 0x42, 0x8f, 0xd7, 0x6f, 0xe9, 0x7e, 0xfa, 0x60}, + {0xc6, 0x6e, 0x29, 0x4d, 0x35, 0x1d, 0x3d, 0xb6, 0xd8, 0x31, 0xad, + 0x5f, 0x3e, 0x5, 0xc3, 0xf3, 0xec, 0x42, 0xbd, 0xb4, 0x8c, 0x95, + 0xb, 0x67, 0xfd, 0x53, 0x63, 0xa1, 0xc, 0x8e, 0x39, 0x21}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 187989455492609, 681223515948275, 1933493571072456, - 1872921007304880, 488162364135671 -#else - 12015105, 2801261, 28198131, 10151021, 24818120, 28811299, - 55914672, 27908697, 5150967, 7274186 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1413466089534451, 410844090765630, 1397263346404072, - 408227143123410, 1594561803147811 -#else - 2831347, 21062286, 1478974, 6122054, 23825128, 20820846, - 31097298, 6083058, 31021603, 23760822 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2102170800973153, 719462588665004, 1479649438510153, - 1097529543970028, 1302363283777685 -#else - 64578913, 31324785, 445612, 10720828, 53259337, 22048494, - 43601132, 16354464, 15067285, 19406725 -#endif - }}, + {0x1, 0x56, 0xb7, 0xb4, 0xf9, 0xaa, 0x98, 0x27, 0x72, 0xad, 0x8d, + 0x5c, 0x13, 0x72, 0xac, 0x5e, 0x23, 0xa0, 0xb7, 0x61, 0x61, 0xaa, + 0xce, 0xd2, 0x4e, 0x7d, 0x8f, 0xe9, 0x84, 0xb2, 0xbf, 0x1b}, + {0xf3, 0x33, 0x2b, 0x38, 0x8a, 0x5, 0xf5, 0x89, 0xb4, 0xc0, 0x48, + 0xad, 0xb, 0xba, 0xe2, 0x5a, 0x6e, 0xb3, 0x3d, 0xa5, 0x3, 0xb5, + 0x93, 0x8f, 0xe6, 0x32, 0xa2, 0x95, 0x9d, 0xed, 0xa3, 0x5a}, + {0x61, 0x65, 0xd9, 0xc7, 0xe9, 0x77, 0x67, 0x65, 0x36, 0x80, 0xc7, + 0x72, 0x54, 0x12, 0x2b, 0xcb, 0xee, 0x6e, 0x50, 0xd9, 0x99, 0x32, + 0x5, 0x65, 0xcc, 0x57, 0x89, 0x5e, 0x4e, 0xe1, 0x7, 0x4a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 942065717847195, 1069313679352961, 2007341951411051, - 70973416446291, 1419433790163706 -#else - 7840923, 14037873, 33744001, 15934015, 66380651, 29911725, - 21403987, 1057586, 47729402, 21151211 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1146565545556377, 1661971299445212, 406681704748893, - 564452436406089, 1109109865829139 -#else - 915865, 17085158, 15608284, 24765302, 42751837, 6060029, - 49737545, 8410996, 59888403, 16527024 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2214421081775077, 1165671861210569, 1890453018796184, - 3556249878661, 442116172656317 -#else - 32922597, 32997445, 20336073, 17369864, 10903704, 28169945, - 16957573, 52992, 23834301, 6588044 -#endif - }}, + {0x9b, 0xa4, 0x77, 0xc4, 0xcd, 0x58, 0xb, 0x24, 0x17, 0xf0, 0x47, + 0x64, 0xde, 0xda, 0x38, 0xfd, 0xad, 0x6a, 0xc8, 0xa7, 0x32, 0x8d, + 0x92, 0x19, 0x81, 0xa0, 0xaf, 0x84, 0xed, 0x7a, 0xaf, 0x50}, + {0x99, 0xf9, 0xd, 0x98, 0xcb, 0x12, 0xe4, 0x4e, 0x71, 0xc7, 0x6e, + 0x3c, 0x6f, 0xd7, 0x15, 0xa3, 0xfd, 0x77, 0x5c, 0x92, 0xde, 0xed, + 0xa5, 0xbb, 0x2, 0x34, 0x31, 0x1d, 0x39, 0xac, 0xb, 0x3f}, + {0xe5, 0x5b, 0xf6, 0x15, 0x1, 0xde, 0x4f, 0x6e, 0xb2, 0x9, 0x61, + 0x21, 0x21, 0x26, 0x98, 0x29, 0xd9, 0xd6, 0xad, 0xb, 0x81, 0x5, + 0x2, 0x78, 0x6, 0xd0, 0xeb, 0xba, 0x16, 0xa3, 0x21, 0x19}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 753830546620811, 1666955059895019, 1530775289309243, - 1119987029104146, 2164156153857580 -#else - 32752011, 11232950, 3381995, 24839566, 22652987, 22810329, - 17159698, 16689107, 46794284, 32248439 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 615171919212796, 1523849404854568, 854560460547503, - 2067097370290715, 1765325848586042 -#else - 62419196, 9166775, 41398568, 22707125, 11576751, 12733943, - 7924251, 30802151, 1976122, 26305405 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1094538949313667, 1796592198908825, 870221004284388, - 2025558921863561, 1699010892802384 -#else - 21251203, 16309901, 64125849, 26771309, 30810596, 12967303, - 156041, 30183180, 12331344, 25317235 -#endif - }}, + {0x8b, 0xc1, 0xf3, 0xd9, 0x9a, 0xad, 0x5a, 0xd7, 0x9c, 0xc1, 0xb1, + 0x60, 0xef, 0xe, 0x6a, 0x56, 0xd9, 0xe, 0x5c, 0x25, 0xac, 0xb, + 0x9a, 0x3e, 0xf5, 0xc7, 0x62, 0xa0, 0xec, 0x9d, 0x4, 0x7b}, + {0xfc, 0x70, 0xb8, 0xdf, 0x7e, 0x2f, 0x42, 0x89, 0xbd, 0xb3, 0x76, + 0x4f, 0xeb, 0x6b, 0x29, 0x2c, 0xf7, 0x4d, 0xc2, 0x36, 0xd4, 0xf1, + 0x38, 0x7, 0xb0, 0xae, 0x73, 0xe2, 0x41, 0xdf, 0x58, 0x64}, + {0x83, 0x44, 0x44, 0x35, 0x7a, 0xe3, 0xcb, 0xdc, 0x93, 0xbe, 0xed, + 0xf, 0x33, 0x79, 0x88, 0x75, 0x87, 0xdd, 0xc5, 0x12, 0xc3, 0x4, + 0x60, 0x78, 0x64, 0xe, 0x95, 0xc2, 0xcb, 0xdc, 0x93, 0x60}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1951351290725195, 1916457206844795, 198025184438026, - 1909076887557595, 1938542290318919 -#else - 8651595, 29077400, 51023227, 28557437, 13002506, 2950805, - 29054427, 28447462, 10008135, 28886531 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1014323197538413, 869150639940606, 1756009942696599, - 1334952557375672, 1544945379082874 -#else - 31486061, 15114593, 52847614, 12951353, 14369431, 26166587, - 16347320, 19892343, 8684154, 23021480 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 764055910920305, 1603590757375439, 146805246592357, - 1843313433854297, 954279890114939 -#else - 19443825, 11385320, 24468943, 23895364, 43189605, 2187568, - 40845657, 27467510, 31316347, 14219878 -#endif - }}, + {0x4b, 0x3, 0x84, 0x60, 0xbe, 0xee, 0xde, 0x6b, 0x54, 0xb8, 0xf, + 0x78, 0xb6, 0xc2, 0x99, 0x31, 0x95, 0x6, 0x2d, 0xb6, 0xab, 0x76, + 0x33, 0x97, 0x90, 0x7d, 0x64, 0x8b, 0xc9, 0x80, 0x31, 0x6e}, + {0x6d, 0x70, 0xe0, 0x85, 0x85, 0x9a, 0xf3, 0x1f, 0x33, 0x39, 0xe7, + 0xb3, 0xd8, 0xa5, 0xd0, 0x36, 0x3b, 0x45, 0x8f, 0x71, 0xe1, 0xf2, + 0xb9, 0x43, 0x7c, 0xa9, 0x27, 0x48, 0x8, 0xea, 0xd1, 0x57}, + {0x71, 0xb0, 0x28, 0xa1, 0xe7, 0xb6, 0x7a, 0xee, 0xaa, 0x8b, 0xa8, + 0x93, 0x6d, 0x59, 0xc1, 0xa4, 0x30, 0x61, 0x21, 0xb2, 0x82, 0xde, + 0xb4, 0xf7, 0x18, 0xbd, 0x97, 0xdd, 0x9d, 0x99, 0x3e, 0x36}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 80113526615750, 764536758732259, 1055139345100233, - 469252651759390, 617897512431515 -#else - 38514374, 1193784, 32245219, 11392485, 31092169, 15722801, - 27146014, 6992409, 29126555, 9207390 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 74497112547268, 740094153192149, 1745254631717581, - 727713886503130, 1283034364416928 -#else - 32382916, 1110093, 18477781, 11028262, 39697101, 26006320, - 62128346, 10843781, 59151264, 19118701 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 525892105991110, 1723776830270342, 1476444848991936, - 573789489857760, 133864092632978 -#else - 2814918, 7836403, 27519878, 25686276, 46214848, 22000742, - 45614304, 8550129, 28346258, 1994730 -#endif - }}, + {0xc6, 0xae, 0x4b, 0xe2, 0xdc, 0x48, 0x18, 0x2f, 0x60, 0xaf, 0xbc, + 0xba, 0x55, 0x72, 0x9b, 0x76, 0x31, 0xe9, 0xef, 0x3c, 0x6e, 0x3c, + 0xcb, 0x90, 0x55, 0xb3, 0xf9, 0xc6, 0x9b, 0x97, 0x1f, 0x23}, + {0xc4, 0x1f, 0xee, 0x35, 0xc1, 0x43, 0xa8, 0x96, 0xcf, 0xc8, 0xe4, + 0x8, 0x55, 0xb3, 0x6e, 0x97, 0x30, 0xd3, 0x8c, 0xb5, 0x1, 0x68, + 0x2f, 0xb4, 0x2b, 0x5, 0x3a, 0x69, 0x78, 0x9b, 0xee, 0x48}, + {0xc6, 0xf3, 0x2a, 0xcc, 0x4b, 0xde, 0x31, 0x5c, 0x1f, 0x8d, 0x20, + 0xfe, 0x30, 0xb0, 0x4b, 0xb0, 0x66, 0xb4, 0x4f, 0xc1, 0x9, 0x70, + 0x8d, 0xb7, 0x13, 0x24, 0x79, 0x8, 0x9b, 0xfa, 0x9b, 0x7}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 542611720192581, 1986812262899321, 1162535242465837, - 481498966143464, 544600533583622 -#else - 47530565, 8085544, 53108345, 29605809, 2785837, 17323125, - 47591912, 7174893, 22628102, 8115180 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 64123227344372, 1239927720647794, 1360722983445904, - 222610813654661, 62429487187991 -#else - 36703732, 955510, 55975026, 18476362, 34661776, 20276352, - 41457285, 3317159, 57165847, 930271 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1793193323953132, 91096687857833, 70945970938921, - 2158587638946380, 1537042406482111 -#else - 51805164, 26720662, 28856489, 1357446, 23421993, 1057177, - 24091212, 32165462, 44343487, 22903716 -#endif - }}, + {0x45, 0x42, 0xd5, 0xa2, 0x80, 0xed, 0xc9, 0xf3, 0x52, 0x39, 0xf6, + 0x77, 0x78, 0x8b, 0xa0, 0xa, 0x75, 0x54, 0x8, 0xd1, 0x63, 0xac, + 0x6d, 0xd7, 0x6b, 0x63, 0x70, 0x94, 0x15, 0xfb, 0xf4, 0x1e}, + {0xf4, 0xd, 0x30, 0xda, 0x51, 0x3a, 0x90, 0xe3, 0xb0, 0x5a, 0xa9, + 0x3d, 0x23, 0x64, 0x39, 0x84, 0x80, 0x64, 0x35, 0xb, 0x2d, 0xf1, + 0x3c, 0xed, 0x94, 0x71, 0x81, 0x84, 0xf6, 0x77, 0x8c, 0x3}, + {0xec, 0x7b, 0x16, 0x5b, 0xe6, 0x5e, 0x4e, 0x85, 0xc2, 0xcd, 0xd0, + 0x96, 0x42, 0xa, 0x59, 0x59, 0x99, 0x21, 0x10, 0x98, 0x34, 0xdf, + 0xb2, 0x72, 0x56, 0xff, 0xb, 0x4a, 0x2a, 0xe9, 0x5e, 0x57}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1895854577604609, 1394895708949416, 1728548428495944, - 1140864900240149, 563645333603061 -#else - 44357633, 28250434, 54201256, 20785565, 51297352, 25757378, - 52269845, 17000211, 65241845, 8398969 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 141358280486863, 91435889572504, 1087208572552643, - 1829599652522921, 1193307020643647 -#else - 35139535, 2106402, 62372504, 1362500, 12813763, 16200670, - 22981545, 27263159, 18009407, 17781660 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1611230858525381, 950720175540785, 499589887488610, - 2001656988495019, 88977313255908 -#else - 49887941, 24009210, 39324209, 14166834, 29815394, 7444469, - 29551787, 29827013, 19288548, 1325865 -#endif - }}, + {0x1, 0xd8, 0xa4, 0xa, 0x45, 0xbc, 0x46, 0x5d, 0xd8, 0xb9, 0x33, + 0xa5, 0x27, 0x12, 0xaf, 0xc3, 0xc2, 0x6, 0x89, 0x2b, 0x26, 0x3b, + 0x9e, 0x38, 0x1b, 0x58, 0x2f, 0x38, 0x7e, 0x1e, 0xa, 0x20}, + {0xcf, 0x2f, 0x18, 0x8a, 0x90, 0x80, 0xc0, 0xd4, 0xbd, 0x9d, 0x48, + 0x99, 0xc2, 0x70, 0xe1, 0x30, 0xde, 0x33, 0xf7, 0x52, 0x57, 0xbd, + 0xba, 0x5, 0x0, 0xfd, 0xd3, 0x2c, 0x11, 0xe7, 0xd4, 0x43}, + {0xc5, 0x3a, 0xf9, 0xea, 0x67, 0xb9, 0x8d, 0x51, 0xc0, 0x52, 0x66, + 0x5, 0x9b, 0x98, 0xbc, 0x71, 0xf5, 0x97, 0x71, 0x56, 0xd9, 0x85, + 0x2b, 0xfe, 0x38, 0x4e, 0x1e, 0x65, 0x52, 0xca, 0xe, 0x5}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1189080501479658, 2184348804772597, 1040818725742319, - 2018318290311834, 1712060030915354 -#else - 15100138, 17718680, 43184885, 32549333, 40658671, 15509407, - 12376730, 30075286, 33166106, 25511682 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 873966876953756, 1090638350350440, 1708559325189137, - 672344594801910, 1320437969700239 -#else - 20909212, 13023121, 57899112, 16251777, 61330449, 25459517, - 12412150, 10018715, 2213263, 19676059 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1508590048271766, 1131769479776094, 101550868699323, - 428297785557897, 561791648661744 -#else - 32529814, 22479743, 30361438, 16864679, 57972923, 1513225, - 22922121, 6382134, 61341936, 8371347 -#endif - }}, + {0xea, 0x68, 0xe6, 0x60, 0x76, 0x39, 0xac, 0x97, 0x97, 0xb4, 0x3a, + 0x15, 0xfe, 0xbb, 0x19, 0x9b, 0x9f, 0xa7, 0xec, 0x34, 0xb5, 0x79, + 0xb1, 0x4c, 0x57, 0xae, 0x31, 0xa1, 0x9f, 0xc0, 0x51, 0x61}, + {0x9c, 0xc, 0x3f, 0x45, 0xde, 0x1a, 0x43, 0xc3, 0x9b, 0x3b, 0x70, + 0xff, 0x5e, 0x4, 0xf5, 0xe9, 0x3d, 0x7b, 0x84, 0xed, 0xc9, 0x7a, + 0xd9, 0xfc, 0xc6, 0xf4, 0x58, 0x1c, 0xc2, 0xe6, 0xe, 0x4b}, + {0x96, 0x5d, 0xf0, 0xfd, 0xd, 0x5c, 0xf5, 0x3a, 0x7a, 0xee, 0xb4, + 0x2a, 0xe0, 0x2e, 0x26, 0xdd, 0x9, 0x17, 0x17, 0x12, 0x87, 0xbb, + 0xb2, 0x11, 0xb, 0x3, 0xf, 0x80, 0xfa, 0x24, 0xef, 0x1f}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 756417570499462, 237882279232602, 2136263418594016, - 1701968045454886, 703713185137472 -#else - 9923462, 11271500, 12616794, 3544722, 37110496, 31832805, - 12891686, 25361300, 40665920, 10486143 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1781187809325462, 1697624151492346, 1381393690939988, - 175194132284669, 1483054666415238 -#else - 44511638, 26541766, 8587002, 25296571, 4084308, 20584370, - 361725, 2610596, 43187334, 22099236 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2175517777364616, 708781536456029, 955668231122942, - 1967557500069555, 2021208005604118 -#else - 5408392, 32417741, 62139741, 10561667, 24145918, 14240566, - 31319731, 29318891, 19985174, 30118346 -#endif - }}, + {0x86, 0x6b, 0x97, 0x30, 0xf5, 0xaf, 0xd2, 0x22, 0x4, 0x46, 0xd2, + 0xc2, 0x6, 0xb8, 0x90, 0x8d, 0xe5, 0xba, 0xe5, 0x4d, 0x6c, 0x89, + 0xa1, 0xdc, 0x17, 0xc, 0x34, 0xc8, 0xe6, 0x5f, 0x0, 0x28}, + {0x96, 0x31, 0xa7, 0x1a, 0xfb, 0x53, 0xd6, 0x37, 0x18, 0x64, 0xd7, + 0x3f, 0x30, 0x95, 0x94, 0xf, 0xb2, 0x17, 0x3a, 0xfb, 0x9, 0xb, + 0x20, 0xad, 0x3e, 0x61, 0xc8, 0x2f, 0x29, 0x49, 0x4d, 0x54}, + {0x88, 0x86, 0x52, 0x34, 0x9f, 0xba, 0xef, 0x6a, 0xa1, 0x7d, 0x10, + 0x25, 0x94, 0xff, 0x1b, 0x5c, 0x36, 0x4b, 0xd9, 0x66, 0xcd, 0xbb, + 0x5b, 0xf7, 0xfa, 0x6d, 0x31, 0xf, 0x93, 0x72, 0xe4, 0x72}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1115135966606887, 224217372950782, 915967306279222, - 593866251291540, 561747094208006 -#else - 53114407, 16616820, 14549246, 3341099, 32155958, 13648976, - 49531796, 8849296, 65030, 8370684 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1443163092879439, 391875531646162, 2180847134654632, - 464538543018753, 1594098196837178 -#else - 58787919, 21504805, 31204562, 5839400, 46481576, 32497154, - 47665921, 6922163, 12743482, 23753914 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 850858855888869, 319436476624586, 327807784938441, - 740785849558761, 17128415486016 -#else - 64747493, 12678784, 28815050, 4759974, 43215817, 4884716, - 23783145, 11038569, 18800704, 255233 -#endif - }}, + {0x27, 0x76, 0x2a, 0xd3, 0x35, 0xf6, 0xf3, 0x7, 0xf0, 0x66, 0x65, + 0x5f, 0x86, 0x4d, 0xaa, 0x7a, 0x50, 0x44, 0xd0, 0x28, 0x97, 0xe7, + 0x85, 0x3c, 0x38, 0x64, 0xe0, 0xf, 0x0, 0x7f, 0xee, 0x1f}, + {0x4f, 0x8, 0x81, 0x97, 0x8c, 0x20, 0x95, 0x26, 0xe1, 0xe, 0x45, + 0x23, 0xb, 0x2a, 0x50, 0xb1, 0x2, 0xde, 0xef, 0x3, 0xa6, 0xae, + 0x9d, 0xfd, 0x4c, 0xa3, 0x33, 0x27, 0x8c, 0x2e, 0x9d, 0x5a}, + {0xe5, 0xf7, 0xdb, 0x3, 0xda, 0x5, 0x53, 0x76, 0xbd, 0xcd, 0x34, + 0x14, 0x49, 0xf2, 0xda, 0xa4, 0xec, 0x88, 0x4a, 0xd2, 0xcd, 0xd5, + 0x4a, 0x7b, 0x43, 0x5, 0x4, 0xee, 0x51, 0x40, 0xf9, 0x0}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2132756334090067, 536247820155645, 48907151276867, - 608473197600695, 1261689545022784 -#else - 61839187, 31780545, 13957885, 7990715, 23132995, 728773, - 13393847, 9066957, 19258688, 18800639 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1525176236978354, 974205476721062, 293436255662638, - 148269621098039, 137961998433963 -#else - 64172210, 22726896, 56676774, 14516792, 63468078, 4372540, - 35173943, 2209389, 65584811, 2055793 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1121075518299410, 2071745529082111, 1265567917414828, - 1648196578317805, 496232102750820 -#else - 580882, 16705327, 5468415, 30871414, 36182444, 18858431, - 59905517, 24560042, 37087844, 7394434 -#endif - }}, + {0x53, 0x97, 0xaf, 0x7, 0xbb, 0x93, 0xef, 0xd7, 0xa7, 0x66, 0xb7, + 0x3d, 0xcf, 0xd0, 0x3e, 0x58, 0xc5, 0x1e, 0xb, 0x6e, 0xbf, 0x98, + 0x69, 0xce, 0x52, 0x4, 0xd4, 0x5d, 0xd2, 0xff, 0xb7, 0x47}, + {0xb2, 0x30, 0xd3, 0xc3, 0x23, 0x6b, 0x35, 0x8d, 0x6, 0x1b, 0x47, + 0xb0, 0x9b, 0x8b, 0x1c, 0xf2, 0x3c, 0xb8, 0x42, 0x6e, 0x6c, 0x31, + 0x6c, 0xb3, 0xd, 0xb1, 0xea, 0x8b, 0x7e, 0x9c, 0xd7, 0x7}, + {0x12, 0xdd, 0x8, 0xbc, 0x9c, 0xfb, 0xfb, 0x87, 0x9b, 0xc2, 0xee, + 0xe1, 0x3a, 0x6b, 0x6, 0x8a, 0xbf, 0xc1, 0x1f, 0xdb, 0x2b, 0x24, + 0x57, 0xd, 0xb6, 0x4b, 0xa6, 0x5e, 0xa3, 0x20, 0x35, 0x1c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 122321229299801, 1022922077493685, 2001275453369484, - 2017441881607947, 993205880778002 -#else - 23838809, 1822728, 51370421, 15242726, 8318092, 29821328, - 45436683, 30062226, 62287122, 14799920 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 654925550560074, 1168810995576858, 575655959430926, - 905758704861388, 496774564663534 -#else - 13345610, 9759151, 3371034, 17416641, 16353038, 8577942, - 31129804, 13496856, 58052846, 7402517 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1954109525779738, 2117022646152485, 338102630417180, - 1194140505732026, 107881734943492 -#else - 2286874, 29118501, 47066405, 31546095, 53412636, 5038121, - 11006906, 17794080, 8205060, 1607563 -#endif - }}, + {0x59, 0xc0, 0x6b, 0x21, 0x40, 0x6f, 0xa8, 0xcd, 0x7e, 0xd8, 0xbc, + 0x12, 0x1d, 0x23, 0xbb, 0x1f, 0x90, 0x9, 0xc7, 0x17, 0x9e, 0x6a, + 0x95, 0xb4, 0x55, 0x2e, 0xd1, 0x66, 0x3b, 0xc, 0x75, 0x38}, + {0x4a, 0xa3, 0xcb, 0xbc, 0xa6, 0x53, 0xd2, 0x80, 0x9b, 0x21, 0x38, + 0x38, 0xa1, 0xc3, 0x61, 0x3e, 0x96, 0xe3, 0x82, 0x98, 0x1, 0xb6, + 0xc3, 0x90, 0x6f, 0xe6, 0xe, 0x5d, 0x77, 0x5, 0x3d, 0x1c}, + {0x1a, 0xe5, 0x22, 0x94, 0x40, 0xf1, 0x2e, 0x69, 0x71, 0xf6, 0x5d, + 0x2b, 0x3c, 0xc7, 0xc0, 0xcb, 0x29, 0xe0, 0x4c, 0x74, 0xe7, 0x4f, + 0x1, 0x21, 0x7c, 0x48, 0x30, 0xd3, 0xc7, 0xe2, 0x21, 0x6}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1714785840001267, 2036500018681589, 1876380234251966, - 2056717182974196, 1645855254384642 -#else - 14414067, 25552300, 3331829, 30346215, 22249150, 27960244, - 18364660, 30647474, 30019586, 24525154 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 106431476499341, 62482972120563, 1513446655109411, - 807258751769522, 538491469114 -#else - 39420813, 1585952, 56333811, 931068, 37988643, 22552112, - 52698034, 12029092, 9944378, 8024 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2002850762893643, 1243624520538135, 1486040410574605, - 2184752338181213, 378495998083531 -#else - 4368715, 29844802, 29874199, 18531449, 46878477, 22143727, - 50994269, 32555346, 58966475, 5640029 -#endif - }}, + {0xf3, 0xf0, 0xdb, 0xb0, 0x96, 0x17, 0xae, 0xb7, 0x96, 0xe1, 0x7c, + 0xe1, 0xb9, 0xaf, 0xdf, 0x54, 0xb4, 0xa3, 0xaa, 0xe9, 0x71, 0x30, + 0x92, 0x25, 0x9d, 0x2e, 0x0, 0xa1, 0x9c, 0x58, 0x8e, 0x5d}, + {0x8d, 0x83, 0x59, 0x82, 0xcc, 0x60, 0x98, 0xaf, 0xdc, 0x9a, 0x9f, + 0xc6, 0xc1, 0x48, 0xea, 0x90, 0x30, 0x1e, 0x58, 0x65, 0x37, 0x48, + 0x26, 0x65, 0xbc, 0xa5, 0xd3, 0x7b, 0x9, 0xd6, 0x7, 0x0}, + {0x4b, 0xa9, 0x42, 0x8, 0x95, 0x1d, 0xbf, 0xc0, 0x3e, 0x2e, 0x8f, + 0x58, 0x63, 0xc3, 0xd3, 0xb2, 0xef, 0xe2, 0x51, 0xbb, 0x38, 0x14, + 0x96, 0xa, 0x86, 0xbf, 0x1c, 0x3c, 0x78, 0xd7, 0x83, 0x15}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 922510868424903, 1089502620807680, 402544072617374, - 1131446598479839, 1290278588136533 -#else - 10299591, 13746483, 11661824, 16234854, 7630238, 5998374, - 9809887, 16859868, 15219797, 19226649 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1867998812076769, 715425053580701, 39968586461416, - 2173068014586163, 653822651801304 -#else - 27425505, 27835351, 3055005, 10660664, 23458024, 595578, - 51710259, 32381236, 48766680, 9742716 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 162892278589453, 182585796682149, 75093073137630, - 497037941226502, 133871727117371 -#else - 6744077, 2427284, 26042789, 2720740, 66260958, 1118973, - 32324614, 7406442, 12420155, 1994844 -#endif - }}, + {0xc7, 0x28, 0x9d, 0xcc, 0x4, 0x47, 0x3, 0x90, 0x8f, 0xc5, 0x2c, + 0xf7, 0x9e, 0x67, 0x1b, 0x1d, 0x26, 0x87, 0x5b, 0xbe, 0x5f, 0x2b, + 0xe1, 0x16, 0xa, 0x58, 0xc5, 0x83, 0x4e, 0x6, 0x58, 0x49}, + {0xe1, 0x7a, 0xa2, 0x5d, 0xef, 0xa2, 0xee, 0xec, 0x74, 0x1, 0x67, + 0x55, 0x14, 0x3a, 0x7c, 0x59, 0x7a, 0x16, 0x9, 0x66, 0x12, 0x2a, + 0xa6, 0xc9, 0x70, 0x8f, 0xed, 0x81, 0x2e, 0x5f, 0x2a, 0x25}, + {0xd, 0xe8, 0x66, 0x50, 0x26, 0x94, 0x28, 0xd, 0x6b, 0x8c, 0x7c, + 0x30, 0x85, 0xf7, 0xc3, 0xfc, 0xfd, 0x12, 0x11, 0xc, 0x78, 0xda, + 0x53, 0x1b, 0x88, 0xb3, 0x43, 0xd8, 0xb, 0x17, 0x9c, 0x7}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1914596576579670, 1608999621851578, 1987629837704609, - 1519655314857977, 1819193753409464 -#else - 14012502, 28529712, 48724410, 23975962, 40623521, 29617992, - 54075385, 22644628, 24319928, 27108099 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1949315551096831, 1069003344994464, 1939165033499916, - 1548227205730856, 1933767655861407 -#else - 16412671, 29047065, 10772640, 15929391, 50040076, 28895810, - 10555944, 23070383, 37006495, 28815383 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1730519386931635, 1393284965610134, 1597143735726030, - 416032382447158, 1429665248828629 -#else - 22397363, 25786748, 57815702, 20761563, 17166286, 23799296, - 39775798, 6199365, 21880021, 21303672 -#endif - }}, + {0x56, 0xd0, 0xd5, 0xc0, 0x50, 0xcd, 0xd6, 0xcd, 0x3b, 0x57, 0x3, + 0xbb, 0x6d, 0x68, 0xf7, 0x9a, 0x48, 0xef, 0xc3, 0xf3, 0x3f, 0x72, + 0xa6, 0x3c, 0xcc, 0x8a, 0x7b, 0x31, 0xd7, 0xc0, 0x68, 0x67}, + {0xff, 0x6f, 0xfa, 0x64, 0xe4, 0xec, 0x6, 0x5, 0x23, 0xe5, 0x5, + 0x62, 0x1e, 0x43, 0xe3, 0xbe, 0x42, 0xea, 0xb8, 0x51, 0x24, 0x42, + 0x79, 0x35, 0x0, 0xfb, 0xc9, 0x4a, 0xe3, 0x5, 0xec, 0x6d}, + {0xb3, 0xc1, 0x55, 0xf1, 0xe5, 0x25, 0xb6, 0x94, 0x91, 0x7b, 0x7b, + 0x99, 0xa7, 0xf3, 0x7b, 0x41, 0x0, 0x26, 0x6b, 0x6d, 0xdc, 0xbd, + 0x2c, 0xc2, 0xf4, 0x52, 0xcd, 0xdd, 0x14, 0x5e, 0x44, 0x51}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 360275475604565, 547835731063078, 215360904187529, - 596646739879007, 332709650425085 -#else - 62825557, 5368522, 35991846, 8163388, 36785801, 3209127, - 16557151, 8890729, 8840445, 4957760 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 47602113726801, 1522314509708010, 437706261372925, - 814035330438027, 335930650933545 -#else - 51661137, 709326, 60189418, 22684253, 37330941, 6522331, - 45388683, 12130071, 52312361, 5005756 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1291597595523886, 1058020588994081, 402837842324045, - 1363323695882781, 2105763393033193 -#else - 64994094, 19246303, 23019041, 15765735, 41839181, 6002751, - 10183197, 20315106, 50713577, 31378319 -#endif - }}, + {0x55, 0xa4, 0xbe, 0x2b, 0xab, 0x47, 0x31, 0x89, 0x29, 0x91, 0x7, + 0x92, 0x4f, 0xa2, 0x53, 0x8c, 0xa7, 0xf7, 0x30, 0xbe, 0x48, 0xf9, + 0x49, 0x4b, 0x3d, 0xd4, 0x4f, 0x6e, 0x8, 0x90, 0xe9, 0x12}, + {0x51, 0x49, 0x14, 0x3b, 0x4b, 0x2b, 0x50, 0x57, 0xb3, 0xbc, 0x4b, + 0x44, 0x6b, 0xff, 0x67, 0x8e, 0xdb, 0x85, 0x63, 0x16, 0x27, 0x69, + 0xbd, 0xb8, 0xc8, 0x95, 0x92, 0xe3, 0x31, 0x6f, 0x18, 0x13}, + {0x2e, 0xbb, 0xdf, 0x7f, 0xb3, 0x96, 0xc, 0xf1, 0xf9, 0xea, 0x1c, + 0x12, 0x5e, 0x93, 0x9a, 0x9f, 0x3f, 0x98, 0x5b, 0x3a, 0xc4, 0x36, + 0x11, 0xdf, 0xaf, 0x99, 0x3e, 0x5d, 0xf0, 0xe3, 0xb2, 0x77}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 109521982566564, 1715257748585139, 1112231216891516, - 2046641005101484, 134249157157013 -#else - 48083108, 1632004, 13466291, 25559332, 43468412, 16573536, - 35094956, 30497327, 22208661, 2000468 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2156991030936798, 2227544497153325, 1869050094431622, - 754875860479115, 1754242344267058 -#else - 3065054, 32141671, 41510189, 33192999, 49425798, 27851016, - 58944651, 11248526, 63417650, 26140247 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1846089562873800, 98894784984326, 1412430299204844, - 171351226625762, 1100604760929008 -#else - 10379208, 27508878, 8877318, 1473647, 37817580, 21046851, - 16690914, 2553332, 63976176, 16400288 -#endif - }}, + {0xa4, 0xb0, 0xdd, 0x12, 0x9c, 0x63, 0x98, 0xd5, 0x6b, 0x86, 0x24, + 0xc0, 0x30, 0x9f, 0xd1, 0xa5, 0x60, 0xe4, 0xfc, 0x58, 0x3, 0x2f, + 0x7c, 0xd1, 0x8a, 0x5e, 0x9, 0x2e, 0x15, 0x95, 0xa1, 0x7}, + {0xde, 0xc4, 0x2e, 0x9c, 0xc5, 0xa9, 0x6f, 0x29, 0xcb, 0xf3, 0x84, + 0x4f, 0xbf, 0x61, 0x8b, 0xbc, 0x8, 0xf9, 0xa8, 0x17, 0xd9, 0x6, + 0x77, 0x1c, 0x5d, 0x25, 0xd3, 0x7a, 0xfc, 0x95, 0xb7, 0x63}, + {0xc8, 0x5f, 0x9e, 0x38, 0x2, 0x8f, 0x36, 0xa8, 0x3b, 0xe4, 0x8d, + 0xcf, 0x2, 0x3b, 0x43, 0x90, 0x43, 0x26, 0x41, 0xc5, 0x5d, 0xfd, + 0xa1, 0xaf, 0x37, 0x1, 0x2f, 0x3, 0x3d, 0xe8, 0x8f, 0x3e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 84172382130492, 499710970700046, 425749630620778, - 1762872794206857, 612842602127960 -#else - 15716668, 1254266, 48636174, 7446273, 58659946, 6344163, - 45011593, 26268851, 26894936, 9132066 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 868309334532756, 1703010512741873, 1952690008738057, - 4325269926064, 2071083554962116 -#else - 24158868, 12938817, 11085297, 25376834, 39045385, 29097348, - 36532400, 64451, 60291780, 30861549 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 523094549451158, 401938899487815, 1407690589076010, - 2022387426254453, 158660516411257 -#else - 13488534, 7794716, 22236231, 5989356, 25426474, 20976224, - 2350709, 30135921, 62420857, 2364225 -#endif - }}, + {0x3c, 0xd1, 0xef, 0xe8, 0x8d, 0x4c, 0x70, 0x8, 0x31, 0x37, 0xe0, + 0x33, 0x8e, 0x1a, 0xc5, 0xdf, 0xe3, 0xcd, 0x60, 0x12, 0xa5, 0x5d, + 0x9d, 0xa5, 0x86, 0x8c, 0x25, 0xa6, 0x99, 0x8, 0xd6, 0x22}, + {0x94, 0xa2, 0x70, 0x5, 0xb9, 0x15, 0x8b, 0x2f, 0x49, 0x45, 0x8, + 0x67, 0x70, 0x42, 0xf2, 0x94, 0x84, 0xfd, 0xbb, 0x61, 0xe1, 0x5a, + 0x1c, 0xde, 0x7, 0x40, 0xac, 0x7f, 0x79, 0x3b, 0xba, 0x75}, + {0x96, 0xd1, 0xcd, 0x70, 0xc0, 0xdb, 0x39, 0x62, 0x9a, 0x8a, 0x7d, + 0x6c, 0x8b, 0x8a, 0xfe, 0x60, 0x60, 0x12, 0x40, 0xeb, 0xbc, 0x47, + 0x88, 0xb3, 0x5e, 0x9e, 0x77, 0x87, 0x7b, 0xd0, 0x4, 0x9}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 612867287630009, 448212612103814, 571629077419196, - 1466796750919376, 1728478129663858 -#else - 16335033, 9132434, 25640582, 6678888, 1725628, 8517937, - 55301840, 21856974, 15445874, 25756331 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1723848973783452, 2208822520534681, 1718748322776940, - 1974268454121942, 1194212502258141 -#else - 29004188, 25687351, 28661401, 32914020, 54314860, 25611345, - 31863254, 29418892, 66830813, 17795152 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1254114807944608, 977770684047110, 2010756238954993, - 1783628927194099, 1525962994408256 -#else - 60986784, 18687766, 38493958, 14569918, 56250865, 29962602, - 10343411, 26578142, 37280576, 22738620 -#endif - }}, + {0xb9, 0x40, 0xf9, 0x48, 0x66, 0x2d, 0x32, 0xf4, 0x39, 0xc, 0x2d, + 0xbd, 0xc, 0x2f, 0x95, 0x6, 0x31, 0xf9, 0x81, 0xa0, 0xad, 0x97, + 0x76, 0x16, 0x6c, 0x2a, 0xf7, 0xba, 0xce, 0xaa, 0x40, 0x62}, + {0x9c, 0x91, 0xba, 0xdd, 0xd4, 0x1f, 0xce, 0xb4, 0xaa, 0x8d, 0x4c, + 0xc7, 0x3e, 0xdb, 0x31, 0xcf, 0x51, 0xcc, 0x86, 0xad, 0x63, 0xcc, + 0x63, 0x2c, 0x7, 0xde, 0x1d, 0xbc, 0x3f, 0x14, 0xe2, 0x43}, + {0xa0, 0x95, 0xa2, 0x5b, 0x9c, 0x74, 0x34, 0xf8, 0x5a, 0xd2, 0x37, + 0xca, 0x5b, 0x7c, 0x94, 0xd6, 0x6a, 0x31, 0xc9, 0xe7, 0xa7, 0x3b, + 0xf1, 0x66, 0xac, 0xc, 0xb4, 0x8d, 0x23, 0xaf, 0xbd, 0x56}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 232464058235826, 1948628555342434, 1835348780427694, - 1031609499437291, 64472106918373 -#else - 27081650, 3463984, 14099042, 29036828, 1616302, 27348828, - 29542635, 15372179, 17293797, 960709 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 767338676040683, 754089548318405, 1523192045639075, - 435746025122062, 512692508440385 -#else - 20263915, 11434237, 61343429, 11236809, 13505955, 22697330, - 50997518, 6493121, 47724353, 7639713 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1255955808701983, 1700487367990941, 1166401238800299, - 1175121994891534, 1190934801395380 -#else - 64278047, 18715199, 25403037, 25339236, 58791851, 17380732, - 18006286, 17510682, 29994676, 17746311 -#endif - }}, + {0xb2, 0x3b, 0x9d, 0xc1, 0x6c, 0xd3, 0x10, 0x13, 0xb9, 0x86, 0x23, + 0x62, 0xb7, 0x6b, 0x2a, 0x6, 0x5c, 0x4f, 0xa1, 0xd7, 0x91, 0x85, + 0x9b, 0x7c, 0x54, 0x57, 0x1e, 0x7e, 0x50, 0x31, 0xaa, 0x3}, + {0xeb, 0x33, 0x35, 0xf5, 0xe3, 0xb9, 0x2a, 0x36, 0x40, 0x3d, 0xb9, + 0x6e, 0xd5, 0x68, 0x85, 0x33, 0x72, 0x55, 0x5a, 0x1d, 0x52, 0x14, + 0xe, 0x9e, 0x18, 0x13, 0x74, 0x83, 0x6d, 0xa8, 0x24, 0x1d}, + {0x1f, 0xce, 0xd4, 0xff, 0x48, 0x76, 0xec, 0xf4, 0x1c, 0x8c, 0xac, + 0x54, 0xf0, 0xea, 0x45, 0xe0, 0x7c, 0x35, 0x9, 0x1d, 0x82, 0x25, + 0xd2, 0x88, 0x59, 0x48, 0xeb, 0x9a, 0xdc, 0x61, 0xb2, 0x43}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 349144008168292, 1337012557669162, 1475912332999108, - 1321618454900458, 47611291904320 -#else - 9769828, 5202651, 42951466, 19923039, 39057860, 21992807, - 42495722, 19693649, 35924288, 709463 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 877519947135419, 2172838026132651, 272304391224129, - 1655143327559984, 886229406429814 -#else - 12286395, 13076066, 45333675, 32377809, 42105665, 4057651, - 35090736, 24663557, 16102006, 13205847 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 375806028254706, 214463229793940, 572906353144089, - 572168269875638, 697556386112979 -#else - 13733362, 5599946, 10557076, 3195751, 61550873, 8536969, - 41568694, 8525971, 10151379, 10394400 -#endif - }}, + {0x64, 0x13, 0x95, 0x6c, 0x8b, 0x3d, 0x51, 0x19, 0x7b, 0xf4, 0xb, + 0x0, 0x26, 0x71, 0xfe, 0x94, 0x67, 0x95, 0x4f, 0xd5, 0xdd, 0x10, + 0x8d, 0x2, 0x64, 0x9, 0x94, 0x42, 0xe2, 0xd5, 0xb4, 0x2}, + {0xbb, 0x79, 0xbb, 0x88, 0x19, 0x1e, 0x5b, 0xe5, 0x9d, 0x35, 0x7a, + 0xc1, 0x7d, 0xd0, 0x9e, 0xa0, 0x33, 0xea, 0x3d, 0x60, 0xe2, 0x2e, + 0x2c, 0xb0, 0xc2, 0x6b, 0x27, 0x5b, 0xcf, 0x55, 0x60, 0x32}, + {0xf2, 0x8d, 0xd1, 0x28, 0xcb, 0x55, 0xa1, 0xb4, 0x8, 0xe5, 0x6c, + 0x18, 0x46, 0x46, 0xcc, 0xea, 0x89, 0x43, 0x82, 0x6c, 0x93, 0xf4, + 0x9c, 0xc4, 0x10, 0x34, 0x5d, 0xae, 0x9, 0xc8, 0xa6, 0x27}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1168827102357844, 823864273033637, 2071538752104697, - 788062026895924, 599578340743362 -#else - 4024660, 17416881, 22436261, 12276534, 58009849, 30868332, - 19698228, 11743039, 33806530, 8934413 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1948116082078088, 2054898304487796, 2204939184983900, - 210526805152138, 786593586607626 -#else - 51229064, 29029191, 58528116, 30620370, 14634844, 32856154, - 57659786, 3137093, 55571978, 11721157 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1915320147894736, 156481169009469, 655050471180417, - 592917090415421, 2165897438660879 -#else - 17555920, 28540494, 8268605, 2331751, 44370049, 9761012, - 9319229, 8835153, 57903375, 32274386 -#endif - }}, + {0x54, 0x69, 0x3d, 0xc4, 0xa, 0x27, 0x2c, 0xcd, 0xb2, 0xca, 0x66, + 0x6a, 0x57, 0x3e, 0x4a, 0xdd, 0x6c, 0x3, 0xd7, 0x69, 0x24, 0x59, + 0xfa, 0x79, 0x99, 0x25, 0x8c, 0x3d, 0x60, 0x3, 0x15, 0x22}, + {0x88, 0xb1, 0xd, 0x1f, 0xcd, 0xeb, 0xa6, 0x8b, 0xe8, 0x5b, 0x5a, + 0x67, 0x3a, 0xd7, 0xd3, 0x37, 0x5a, 0x58, 0xf5, 0x15, 0xa3, 0xdf, + 0x2e, 0xf2, 0x7e, 0xa1, 0x60, 0xff, 0x74, 0x71, 0xb6, 0x2c}, + {0xd0, 0xe1, 0xb, 0x39, 0xf9, 0xcd, 0xee, 0x59, 0xf1, 0xe3, 0x8c, + 0x72, 0x44, 0x20, 0x42, 0xa9, 0xf4, 0xf0, 0x94, 0x7a, 0x66, 0x1c, + 0x89, 0x82, 0x36, 0xf4, 0x90, 0x38, 0xb7, 0xf4, 0x1d, 0x7b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1726336468579724, 1119932070398949, 1929199510967666, - 33918788322959, 1836837863503150 -#else - 66647436, 25724417, 20614117, 16688288, 59594098, 28747312, - 22300303, 505429, 6108462, 27371017 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 829996854845988, 217061778005138, 1686565909803640, - 1346948817219846, 1723823550730181 -#else - 62038564, 12367916, 36445330, 3234472, 32617080, 25131790, - 29880582, 20071101, 40210373, 25686972 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 384301494966394, 687038900403062, 2211195391021739, - 254684538421383, 1245698430589680 -#else - 35133562, 5726538, 26934134, 10237677, 63935147, 32949378, - 24199303, 3795095, 7592688, 18562353 -#endif - }}, + {0x8c, 0xf5, 0xf8, 0x7, 0x18, 0x22, 0x2e, 0x5f, 0xd4, 0x9, 0x94, + 0xd4, 0x9f, 0x5c, 0x55, 0xe3, 0x30, 0xa6, 0xb6, 0x1f, 0x8d, 0xa8, + 0xaa, 0xb2, 0x3d, 0xe0, 0x52, 0xd3, 0x45, 0x82, 0x69, 0x68}, + {0x24, 0xa2, 0xb2, 0xb3, 0xe0, 0xf2, 0x92, 0xe4, 0x60, 0x11, 0x55, + 0x2b, 0x6, 0x9e, 0x6c, 0x7c, 0xe, 0x7b, 0x7f, 0xd, 0xe2, 0x8f, + 0xeb, 0x15, 0x92, 0x59, 0xfc, 0x58, 0x26, 0xef, 0xfc, 0x61}, + {0x7a, 0x18, 0x18, 0x2a, 0x85, 0x5d, 0xb1, 0xdb, 0xd7, 0xac, 0xdd, + 0x86, 0xd3, 0xaa, 0xe4, 0xf3, 0x82, 0xc4, 0xf6, 0xf, 0x81, 0xe2, + 0xba, 0x44, 0xcf, 0x1, 0xaf, 0x3d, 0x47, 0x4c, 0xcf, 0x46}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1247567493562688, 1978182094455847, 183871474792955, - 806570235643435, 288461518067916 -#else - 21594432, 18590204, 17466407, 29477210, 32537083, 2739898, - 6407723, 12018833, 38852812, 4298411 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1449077384734201, 38285445457996, 2136537659177832, - 2146493000841573, 725161151123125 -#else - 46458361, 21592935, 39872588, 570497, 3767144, 31836892, - 13891941, 31985238, 13717173, 10805743 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1201928866368855, 800415690605445, 1703146756828343, - 997278587541744, 1858284414104014 -#else - 52432215, 17910135, 15287173, 11927123, 24177847, 25378864, - 66312432, 14860608, 40169934, 27690595 -#endif - }}, + {0x40, 0x81, 0x49, 0xf1, 0xa7, 0x6e, 0x3c, 0x21, 0x54, 0x48, 0x2b, + 0x39, 0xf8, 0x7e, 0x1e, 0x7c, 0xba, 0xce, 0x29, 0x56, 0x8c, 0xc3, + 0x88, 0x24, 0xbb, 0xc5, 0x8c, 0xd, 0xe5, 0xaa, 0x65, 0x10}, + {0xf9, 0xe5, 0xc4, 0x9e, 0xed, 0x25, 0x65, 0x42, 0x3, 0x33, 0x90, + 0x16, 0x1, 0xda, 0x5e, 0xe, 0xdc, 0xca, 0xe5, 0xcb, 0xf2, 0xa7, + 0xb1, 0x72, 0x40, 0x5f, 0xeb, 0x14, 0xcd, 0x7b, 0x38, 0x29}, + {0x57, 0xd, 0x20, 0xdf, 0x25, 0x45, 0x2c, 0x1c, 0x4a, 0x67, 0xca, + 0xbf, 0xd6, 0x2d, 0x3b, 0x5c, 0x30, 0x40, 0x83, 0xe1, 0xb1, 0xe7, + 0x7, 0xa, 0x16, 0xe7, 0x1c, 0x4f, 0xe6, 0x98, 0xa1, 0x69}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 356468809648877, 782373916933152, 1718002439402870, - 1392222252219254, 663171266061951 -#else - 12962541, 5311799, 57048096, 11658279, 18855286, 25600231, - 13286262, 20745728, 62727807, 9882021 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 759628738230460, 1012693474275852, 353780233086498, - 246080061387552, 2030378857679162 -#else - 18512060, 11319350, 46985740, 15090308, 18818594, 5271736, - 44380960, 3666878, 43141434, 30255002 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2040672435071076, 888593182036908, 1298443657189359, - 1804780278521327, 354070726137060 -#else - 60319844, 30408388, 16192428, 13241070, 15898607, 19348318, - 57023983, 26893321, 64705764, 5276064 -#endif - }}, + {0xed, 0xca, 0xc5, 0xdc, 0x34, 0x44, 0x1, 0xe1, 0x33, 0xfb, 0x84, + 0x3c, 0x96, 0x5d, 0xed, 0x47, 0xe7, 0xa0, 0x86, 0xed, 0x76, 0x95, + 0x1, 0x70, 0xe4, 0xf9, 0x67, 0xd2, 0x7b, 0x69, 0xb2, 0x25}, + {0xbc, 0x78, 0x1a, 0xd9, 0xe0, 0xb2, 0x62, 0x90, 0x67, 0x96, 0x50, + 0xc8, 0x9c, 0x88, 0xc9, 0x47, 0xb8, 0x70, 0x50, 0x40, 0x66, 0x4a, + 0xf5, 0x9d, 0xbf, 0xa1, 0x93, 0x24, 0xa9, 0xe6, 0x69, 0x73}, + {0x64, 0x68, 0x98, 0x13, 0xfb, 0x3f, 0x67, 0x9d, 0xb8, 0xc7, 0x5d, + 0x41, 0xd9, 0xfb, 0xa5, 0x3c, 0x5e, 0x3b, 0x27, 0xdf, 0x3b, 0xcc, + 0x4e, 0xe0, 0xd2, 0x4c, 0x4e, 0xb5, 0x3d, 0x68, 0x20, 0x14}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1894938527423184, 1463213041477277, 474410505497651, - 247294963033299, 877975941029128 -#else - 30169808, 28236784, 26306205, 21803573, 27814963, 7069267, - 7152851, 3684982, 1449224, 13082861 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 207937160991127, 12966911039119, 820997788283092, - 1010440472205286, 1701372890140810 -#else - 10342807, 3098505, 2119311, 193222, 25702612, 12233820, - 23697382, 15056736, 46092426, 25352431 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 218882774543183, 533427444716285, 1233243976733245, - 435054256891319, 1509568989549904 -#else - 33958735, 3261607, 22745853, 7948688, 19370557, 18376767, - 40936887, 6482813, 56808784, 22494330 -#endif - }}, + {0xd0, 0x5a, 0xcc, 0xc1, 0x6f, 0xbb, 0xee, 0x34, 0x8b, 0xac, 0x46, + 0x96, 0xe9, 0xc, 0x1b, 0x6a, 0x53, 0xde, 0x6b, 0xa6, 0x49, 0xda, + 0xb0, 0xd3, 0xc1, 0x81, 0xd0, 0x61, 0x41, 0x3b, 0xe8, 0x31}, + {0x97, 0xd1, 0x9d, 0x24, 0x1e, 0xbd, 0x78, 0xb4, 0x2, 0xc1, 0x58, + 0x5e, 0x0, 0x35, 0xc, 0x62, 0x5c, 0xac, 0xba, 0xcc, 0x2f, 0xd3, + 0x2, 0xfb, 0x2d, 0xa7, 0x8, 0xf5, 0xeb, 0x3b, 0xb6, 0x60}, + {0x4f, 0x2b, 0x6, 0x9e, 0x12, 0xc7, 0xe8, 0x97, 0xd8, 0xa, 0x32, + 0x29, 0x4f, 0x8f, 0xe4, 0x49, 0x3f, 0x68, 0x18, 0x6f, 0x4b, 0xe1, + 0xec, 0x5b, 0x17, 0x3, 0x55, 0x2d, 0xb6, 0x1e, 0xcf, 0x55}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1888838535711826, 1052177758340622, 1213553803324135, - 169182009127332, 463374268115872 -#else - 32869458, 28145887, 25609742, 15678670, 56421095, 18083360, - 26112420, 2521008, 44444576, 6904814 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 299137589460312, 1594371588983567, 868058494039073, - 257771590636681, 1805012993142921 -#else - 29506904, 4457497, 3377935, 23757988, 36598817, 12935079, - 1561737, 3841096, 38105225, 26896789 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1806842755664364, 2098896946025095, 1356630998422878, - 1458279806348064, 347755825962072 -#else - 10340844, 26924055, 48452231, 31276001, 12621150, 20215377, - 30878496, 21730062, 41524312, 5181965 -#endif - }}, + {0x52, 0x8c, 0xf5, 0x7d, 0xe3, 0xb5, 0x76, 0x30, 0x36, 0xcc, 0x99, + 0xe7, 0xdd, 0xb9, 0x3a, 0xd7, 0x20, 0xee, 0x13, 0x49, 0xe3, 0x1c, + 0x83, 0xbd, 0x33, 0x1, 0xba, 0x62, 0xaa, 0xfb, 0x56, 0x1a}, + {0x58, 0x3d, 0xc2, 0x65, 0x10, 0x10, 0x79, 0x58, 0x9c, 0x81, 0x94, + 0x50, 0x6d, 0x8, 0x9d, 0x8b, 0xa7, 0x5f, 0xc5, 0x12, 0xa9, 0x2f, + 0x40, 0xe2, 0xd4, 0x91, 0x8, 0x57, 0x64, 0x65, 0x9a, 0x66}, + {0xec, 0xc9, 0x9d, 0x5c, 0x50, 0x6b, 0x3e, 0x94, 0x1a, 0x37, 0x7c, + 0xa7, 0xbb, 0x57, 0x25, 0x30, 0x51, 0x76, 0x34, 0x41, 0x56, 0xae, + 0x73, 0x98, 0x5c, 0x8a, 0xc5, 0x99, 0x67, 0x83, 0xc4, 0x13}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1402334161391744, 1560083671046299, 1008585416617747, - 1147797150908892, 1420416683642459 -#else - 25940096, 20896407, 17324187, 23247058, 58437395, 15029093, - 24396252, 17103510, 64786011, 21165857 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 665506704253369, 273770475169863, 799236974202630, - 848328990077558, 1811448782807931 -#else - 45343161, 9916822, 65808455, 4079497, 66080518, 11909558, - 1782390, 12641087, 20603771, 26992690 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1468412523962641, 771866649897997, 1931766110147832, - 799561180078482, 524837559150077 -#else - 48226577, 21881051, 24849421, 11501709, 13161720, 28785558, - 1925522, 11914390, 4662781, 7820689 -#endif - }}, + {0x80, 0xd0, 0x8b, 0x5d, 0x6a, 0xfb, 0xdc, 0xc4, 0x42, 0x48, 0x1a, + 0x57, 0xec, 0xc4, 0xeb, 0xde, 0x65, 0x53, 0xe5, 0xb8, 0x83, 0xe8, + 0xb2, 0xd4, 0x27, 0xb8, 0xe5, 0xc8, 0x7d, 0xc8, 0xbd, 0x50}, + {0xb9, 0xe1, 0xb3, 0x5a, 0x46, 0x5d, 0x3a, 0x42, 0x61, 0x3f, 0xf1, + 0xc7, 0x87, 0xc1, 0x13, 0xfc, 0xb6, 0xb9, 0xb5, 0xec, 0x64, 0x36, + 0xf8, 0x19, 0x7, 0xb6, 0x37, 0xa6, 0x93, 0xc, 0xf8, 0x66}, + {0x11, 0xe1, 0xdf, 0x6e, 0x83, 0x37, 0x6d, 0x60, 0xd9, 0xab, 0x11, + 0xf0, 0x15, 0x3e, 0x35, 0x32, 0x96, 0x3b, 0xb7, 0x25, 0xc3, 0x3a, + 0xb0, 0x64, 0xae, 0xd5, 0x5f, 0x72, 0x44, 0x64, 0xd5, 0x1d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2223212657821850, 630416247363666, 2144451165500328, - 816911130947791, 1024351058410032 -#else - 12241050, 33128450, 8132690, 9393934, 32846760, 31954812, - 29749455, 12172924, 16136752, 15264020 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1266603897524861, 156378408858100, 1275649024228779, - 447738405888420, 253186462063095 -#else - 56758909, 18873868, 58896884, 2330219, 49446315, 19008651, - 10658212, 6671822, 19012087, 3772772 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2022215964509735, 136144366993649, 1800716593296582, - 1193970603800203, 871675847064218 -#else - 3753511, 30133366, 10617073, 2028709, 14841030, 26832768, - 28718731, 17791548, 20527770, 12988982 -#endif - }}, + {0x9a, 0xc8, 0xba, 0x8, 0x0, 0xe6, 0x97, 0xc2, 0xe0, 0xc3, 0xe1, + 0xea, 0x11, 0xea, 0x4c, 0x7d, 0x7c, 0x97, 0xe7, 0x9f, 0xe1, 0x8b, + 0xe3, 0xf3, 0xcd, 0x5, 0xa3, 0x63, 0xf, 0x45, 0x3a, 0x3a}, + {0x7d, 0x12, 0x62, 0x33, 0xf8, 0x7f, 0xa4, 0x8f, 0x15, 0x7c, 0xcd, + 0x71, 0xc4, 0x6a, 0x9f, 0xbc, 0x8b, 0xc, 0x22, 0x49, 0x43, 0x45, + 0x71, 0x6e, 0x2e, 0x73, 0x9f, 0x21, 0x12, 0x59, 0x64, 0xe}, + {0x27, 0x46, 0x39, 0xd8, 0x31, 0x2f, 0x8f, 0x7, 0x10, 0xa5, 0x94, + 0xde, 0x83, 0x31, 0x9d, 0x38, 0x80, 0x6f, 0x99, 0x17, 0x6d, 0x6c, + 0xe3, 0xd1, 0x7b, 0xa8, 0xa9, 0x93, 0x93, 0x8d, 0x8c, 0x31}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1862751661970328, 851596246739884, 1519315554814041, - 1542798466547449, 1417975335901520 -#else - 52286360, 27757162, 63400876, 12689772, 66209881, 22639565, - 42925817, 22989488, 3299664, 21129479 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1228168094547481, 334133883362894, 587567568420081, - 433612590281181, 603390400373205 -#else - 50331161, 18301130, 57466446, 4978982, 3308785, 8755439, - 6943197, 6461331, 41525717, 8991217 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 121893973206505, 1843345804916664, 1703118377384911, - 497810164760654, 101150811654673 -#else - 49882601, 1816361, 65435576, 27467992, 31783887, 25378441, - 34160718, 7417949, 36866577, 1507264 -#endif - }}, + {0x98, 0xd3, 0x1d, 0xab, 0x29, 0x9e, 0x66, 0x5d, 0x3b, 0x9e, 0x2d, + 0x34, 0x58, 0x16, 0x92, 0xfc, 0xcd, 0x73, 0x59, 0xf3, 0xfd, 0x1d, + 0x85, 0x55, 0xf6, 0xa, 0x95, 0x25, 0xc3, 0x41, 0x9a, 0x50}, + {0x19, 0xfe, 0xff, 0x2a, 0x3, 0x5d, 0x74, 0xf2, 0x66, 0xdb, 0x24, + 0x7f, 0x49, 0x3c, 0x9f, 0xc, 0xef, 0x98, 0x85, 0xba, 0xe3, 0xd3, + 0x98, 0xbc, 0x14, 0x53, 0x1d, 0x9a, 0x67, 0x7c, 0x4c, 0x22}, + {0xe9, 0x25, 0xf9, 0xa6, 0xdc, 0x6e, 0xc0, 0xbd, 0x33, 0x1f, 0x1b, + 0x64, 0xf4, 0xf3, 0x3e, 0x79, 0x89, 0x3e, 0x83, 0x9d, 0x80, 0x12, + 0xec, 0x82, 0x89, 0x13, 0xa1, 0x28, 0x23, 0xf0, 0xbf, 0x5}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 458346255946468, 290909935619344, 1452768413850679, - 550922875254215, 1537286854336538 -#else - 29692644, 6829891, 56610064, 4334895, 20945975, 21647936, - 38221255, 8209390, 14606362, 22907359 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 584322311184395, 380661238802118, 114839394528060, - 655082270500073, 2111856026034852 -#else - 63627275, 8707080, 32188102, 5672294, 22096700, 1711240, - 34088169, 9761486, 4170404, 31469107 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 996965581008991, 2148998626477022, 1012273164934654, - 1073876063914522, 1688031788934939 -#else - 55521375, 14855944, 62981086, 32022574, 40459774, 15084045, - 22186522, 16002000, 52832027, 25153633 -#endif - }}, + {0xe4, 0x12, 0xc5, 0xd, 0xdd, 0xa0, 0x81, 0x68, 0xfe, 0xfa, 0xa5, + 0x44, 0xc8, 0xd, 0xe7, 0x4f, 0x40, 0x52, 0x4a, 0x8f, 0x6b, 0x8e, + 0x74, 0x1f, 0xea, 0xa3, 0x1, 0xee, 0xcd, 0x77, 0x62, 0x57}, + {0xb, 0xe0, 0xca, 0x23, 0x70, 0x13, 0x32, 0x36, 0x59, 0xcf, 0xac, + 0xd1, 0xa, 0xcf, 0x4a, 0x54, 0x88, 0x1c, 0x1a, 0xd2, 0x49, 0x10, + 0x74, 0x96, 0xa7, 0x44, 0x2a, 0xfa, 0xc3, 0x8c, 0xb, 0x78}, + {0x5f, 0x30, 0x4f, 0x23, 0xbc, 0x8a, 0xf3, 0x1e, 0x8, 0xde, 0x5, + 0x14, 0xbd, 0x7f, 0x57, 0x9a, 0xd, 0x2a, 0xe6, 0x34, 0x14, 0xa5, + 0x82, 0x5e, 0xa1, 0xb7, 0x71, 0x62, 0x72, 0x18, 0xf4, 0x5f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 923487018849600, 2085106799623355, 528082801620136, - 1606206360876188, 735907091712524 -#else - 62297408, 13761028, 35404987, 31070512, 63796392, 7869046, - 59995292, 23934339, 13240844, 10965870 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1697697887804317, 1335343703828273, 831288615207040, - 949416685250051, 288760277392022 -#else - 59366301, 25297669, 52340529, 19898171, 43876480, 12387165, - 4498947, 14147411, 29514390, 4302863 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1419122478109648, 1325574567803701, 602393874111094, - 2107893372601700, 1314159682671307 -#else - 53695440, 21146572, 20757301, 19752600, 14785142, 8976368, - 62047588, 31410058, 17846987, 19582505 -#endif - }}, + {0x40, 0x95, 0xb6, 0x13, 0xe8, 0x47, 0xdb, 0xe5, 0xe1, 0x10, 0x26, + 0x43, 0x3b, 0x2a, 0x5d, 0xf3, 0x76, 0x12, 0x78, 0x38, 0xe9, 0x26, + 0x1f, 0xac, 0x69, 0xcb, 0xa0, 0xa0, 0x8c, 0xdb, 0xd4, 0x29}, + {0x9d, 0xdb, 0x89, 0x17, 0xc, 0x8, 0x8e, 0x39, 0xf5, 0x78, 0xe7, + 0xf3, 0x25, 0x20, 0x60, 0xa7, 0x5d, 0x3, 0xbd, 0x6, 0x4c, 0x89, + 0x98, 0xfa, 0xbe, 0x66, 0xa9, 0x25, 0xdc, 0x3, 0x6a, 0x10}, + {0xd0, 0x53, 0x33, 0x33, 0xaf, 0xa, 0xad, 0xd9, 0xe5, 0x9, 0xd3, + 0xac, 0xa5, 0x9d, 0x66, 0x38, 0xf0, 0xf7, 0x88, 0xc8, 0x8a, 0x65, + 0x57, 0x3c, 0xfa, 0xbe, 0x2c, 0x5, 0x51, 0x8a, 0xb3, 0x4a}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2201150872731804, 2180241023425241, 97663456423163, - 1633405770247824, 848945042443986 -#else - 64864412, 32799703, 62511833, 32488122, 60861691, 1455298, - 45461136, 24339642, 61886162, 12650266 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1173339555550611, 818605084277583, 47521504364289, - 924108720564965, 735423405754506 -#else - 57202067, 17484121, 21134159, 12198166, 40044289, 708125, - 387813, 13770293, 47974538, 10958662 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 830104860549448, 1886653193241086, 1600929509383773, - 1475051275443631, 286679780900937 -#else - 22470984, 12369526, 23446014, 28113323, 45588061, 23855708, - 55336367, 21979976, 42025033, 4271861 -#endif - }}, + {0x9c, 0xc0, 0xdd, 0x5f, 0xef, 0xd1, 0xcf, 0xd6, 0xce, 0x5d, 0x57, + 0xf7, 0xfd, 0x3e, 0x2b, 0xe8, 0xc2, 0x34, 0x16, 0x20, 0x5d, 0x6b, + 0xd5, 0x25, 0x9b, 0x2b, 0xed, 0x4, 0xbb, 0xc6, 0x41, 0x30}, + {0x93, 0xd5, 0x68, 0x67, 0x25, 0x2b, 0x7c, 0xda, 0x13, 0xca, 0x22, + 0x44, 0x57, 0xc0, 0xc1, 0x98, 0x1d, 0xce, 0xa, 0xca, 0xd5, 0xb, + 0xa8, 0xf1, 0x90, 0xa6, 0x88, 0xc0, 0xad, 0xd1, 0xcd, 0x29}, + {0x48, 0xe1, 0x56, 0xd9, 0xf9, 0xf2, 0xf2, 0xf, 0x2e, 0x6b, 0x35, + 0x9f, 0x75, 0x97, 0xe7, 0xad, 0x5c, 0x2, 0x6c, 0x5f, 0xbb, 0x98, + 0x46, 0x1a, 0x7b, 0x9a, 0x4, 0x14, 0x68, 0xbd, 0x4b, 0x10}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1577111294832995, 1030899169768747, 144900916293530, - 1964672592979567, 568390100955250 -#else - 41939299, 23500789, 47199531, 15361594, 61124506, 2159191, - 75375, 29275903, 34582642, 8469672 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 278388655910247, 487143369099838, 927762205508727, - 181017540174210, 1616886700741287 -#else - 15854951, 4148314, 58214974, 7259001, 11666551, 13824734, - 36577666, 2697371, 24154791, 24093489 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1191033906638969, 940823957346562, 1606870843663445, - 861684761499847, 658674867251089 -#else - 15446137, 17747788, 29759746, 14019369, 30811221, 23944241, - 35526855, 12840103, 24913809, 9815020 -#endif - }}, + {0x63, 0xf1, 0x7f, 0xd6, 0x5f, 0x9a, 0x5d, 0xa9, 0x81, 0x56, 0xc7, + 0x4c, 0x9d, 0xe6, 0x2b, 0xe9, 0x57, 0xf2, 0x20, 0xde, 0x4c, 0x2, + 0xf8, 0xb7, 0xf5, 0x2d, 0x7, 0xfb, 0x20, 0x2a, 0x4f, 0x20}, + {0x67, 0xed, 0xf1, 0x68, 0x31, 0xfd, 0xf0, 0x51, 0xc2, 0x3b, 0x6f, + 0xd8, 0xcd, 0x1d, 0x81, 0x2c, 0xde, 0xf2, 0xd2, 0x4, 0x43, 0x5c, + 0xdc, 0x44, 0x49, 0x71, 0x2a, 0x9, 0x57, 0xcc, 0xe8, 0x5b}, + {0x79, 0xb0, 0xeb, 0x30, 0x3d, 0x3b, 0x14, 0xc8, 0x30, 0x2e, 0x65, + 0xbd, 0x5a, 0x15, 0x89, 0x75, 0x31, 0x5c, 0x6d, 0x8f, 0x31, 0x3c, + 0x3c, 0x65, 0x1f, 0x16, 0x79, 0xc2, 0x17, 0xfb, 0x70, 0x25}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1875032594195546, 1427106132796197, 724736390962158, - 901860512044740, 635268497268760 -#else - 62399578, 27940162, 35267365, 21265538, 52665326, 10799413, - 58005188, 13438768, 18735128, 9466238 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 622869792298357, 1903919278950367, 1922588621661629, - 1520574711600434, 1087100760174640 -#else - 11933045, 9281483, 5081055, 28370608, 64480701, 28648802, - 59381042, 22658328, 44380208, 16199063 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 25465949416618, 1693639527318811, 1526153382657203, - 125943137857169, 145276964043999 -#else - 14576810, 379472, 40322331, 25237195, 37682355, 22741457, - 67006097, 1876698, 30801119, 2164795 -#endif - }}, + {0x5a, 0x24, 0xb8, 0xb, 0x55, 0xa9, 0x2e, 0x19, 0xd1, 0x50, 0x90, + 0x8f, 0xa8, 0xfb, 0xe6, 0xc8, 0x35, 0xc9, 0xa4, 0x88, 0x2d, 0xea, + 0x86, 0x79, 0x68, 0x86, 0x1, 0xde, 0x91, 0x5f, 0x1c, 0x24}, + {0x75, 0x15, 0xb6, 0x2c, 0x7f, 0x36, 0xfa, 0x3e, 0x6c, 0x2, 0xd6, + 0x1c, 0x76, 0x6f, 0xf9, 0xf5, 0x62, 0x25, 0xb5, 0x65, 0x2a, 0x14, + 0xc7, 0xe8, 0xcd, 0xa, 0x3, 0x53, 0xea, 0x65, 0xcb, 0x3d}, + {0xaa, 0x6c, 0xde, 0x40, 0x29, 0x17, 0xd8, 0x28, 0x3a, 0x73, 0xd9, + 0x22, 0xf0, 0x2c, 0xbf, 0x8f, 0xd1, 0x1, 0x5b, 0x23, 0xdd, 0xfc, + 0xd7, 0x16, 0xe5, 0xf0, 0xcd, 0x5f, 0xdd, 0xe, 0x42, 0x8}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 214739857969358, 920212862967915, 1939901550972269, - 1211862791775221, 85097515720120 -#else - 15995086, 3199873, 13672555, 13712240, 47730029, 28906785, - 54027253, 18058162, 53616056, 1268051 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2006245852772938, 734762734836159, 254642929763427, - 1406213292755966, 239303749517686 -#else - 56818250, 29895392, 63822271, 10948817, 23037027, 3794475, - 63638526, 20954210, 50053494, 3565903 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1619678837192149, 1919424032779215, 1357391272956794, - 1525634040073113, 1310226789796241 -#else - 29210069, 24135095, 61189071, 28601646, 10834810, 20226706, - 50596761, 22733718, 39946641, 19523900 -#endif - }}, + {0xce, 0x10, 0xf4, 0x4, 0x4e, 0xc3, 0x58, 0x3, 0x85, 0x6, 0x6e, + 0x27, 0x5a, 0x5b, 0x13, 0xb6, 0x21, 0x15, 0xb9, 0xeb, 0xc7, 0x70, + 0x96, 0x5d, 0x9c, 0x88, 0xdb, 0x21, 0xf3, 0x54, 0xd6, 0x4}, + {0x4a, 0xfa, 0x62, 0x83, 0xab, 0x20, 0xff, 0xcd, 0x6e, 0x3e, 0x1a, + 0xe2, 0xd4, 0x18, 0xe1, 0x57, 0x2b, 0xe6, 0x39, 0xfc, 0x17, 0x96, + 0x17, 0xe3, 0xfd, 0x69, 0x17, 0xbc, 0xef, 0x53, 0x9a, 0xd}, + {0xd5, 0xb5, 0xbd, 0xdd, 0x16, 0xc1, 0x7d, 0x5e, 0x2d, 0xdd, 0xa5, + 0x8d, 0xb6, 0xde, 0x54, 0x29, 0x92, 0xa2, 0x34, 0x33, 0x17, 0x8, + 0xb6, 0x1c, 0xd7, 0x1a, 0x99, 0x18, 0x26, 0x4f, 0x7a, 0x4a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1040763709762123, 1704449869235352, 605263070456329, - 1998838089036355, 1312142911487502 -#else - 53946955, 15508587, 16663704, 25398282, 38758921, 9019122, - 37925443, 29785008, 2244110, 19552453 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1996723311435669, 1844342766567060, 985455700466044, - 1165924681400960, 311508689870129 -#else - 61955989, 29753495, 57802388, 27482848, 16243068, 14684434, - 41435776, 17373631, 13491505, 4641841 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 43173156290518, 2202883069785309, 1137787467085917, - 1733636061944606, 1394992037553852 -#else - 10813398, 643330, 47920349, 32825515, 30292061, 16954354, - 27548446, 25833190, 14476988, 20787001 -#endif - }}, + {0x4b, 0x2a, 0x37, 0xaf, 0x91, 0xb2, 0xc3, 0x24, 0xf2, 0x47, 0x81, + 0x71, 0x70, 0x82, 0xda, 0x93, 0xf2, 0x9e, 0x89, 0x86, 0x64, 0x85, + 0x84, 0xdd, 0x33, 0xee, 0xe0, 0x23, 0x42, 0x31, 0x96, 0x4a}, + {0x95, 0x5f, 0xb1, 0x5f, 0x2, 0x18, 0xa7, 0xf4, 0x8f, 0x1b, 0x5c, + 0x6b, 0x34, 0x5f, 0xf6, 0x3d, 0x12, 0x11, 0xe0, 0x0, 0x85, 0xf0, + 0xfc, 0xcd, 0x48, 0x18, 0xd3, 0xdd, 0x4c, 0xc, 0xb5, 0x11}, + {0xd6, 0xff, 0xa4, 0x8, 0x44, 0x27, 0xe8, 0xa6, 0xd9, 0x76, 0x15, + 0x9c, 0x7e, 0x17, 0x8e, 0x73, 0xf2, 0xb3, 0x2, 0x3d, 0xb6, 0x48, + 0x33, 0x77, 0x51, 0xcc, 0x6b, 0xce, 0x4d, 0xce, 0x4b, 0x4f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 670078326344559, 555655025059356, 471959386282438, - 2141455487356409, 849015953823125 -#else - 10292079, 9984945, 6481436, 8279905, 59857350, 7032742, - 27282937, 31910173, 39196053, 12651323 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2197214573372804, 794254097241315, 1030190060513737, - 267632515541902, 2040478049202624 -#else - 35923332, 32741048, 22271203, 11835308, 10201545, 15351028, - 17099662, 3988035, 21721536, 30405492 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1812516004670529, 1609256702920783, 1706897079364493, - 258549904773295, 996051247540686 -#else - 10202177, 27008593, 35735631, 23979793, 34958221, 25434748, - 54202543, 3852693, 13216206, 14842320 -#endif - }}, + {0x6f, 0xb, 0x9d, 0xc4, 0x6e, 0x61, 0xe2, 0x30, 0x17, 0x23, 0xec, + 0xca, 0x8f, 0x71, 0x56, 0xe4, 0xa6, 0x4f, 0x6b, 0xf2, 0x9b, 0x40, + 0xeb, 0x48, 0x37, 0x5f, 0x59, 0x61, 0xe5, 0xce, 0x42, 0x30}, + {0x84, 0x25, 0x24, 0xe2, 0x5a, 0xce, 0x1f, 0xa7, 0x9e, 0x8a, 0xf5, + 0x92, 0x56, 0x72, 0xea, 0x26, 0xf4, 0x3c, 0xea, 0x1c, 0xd7, 0x9, + 0x1a, 0xd2, 0xe6, 0x1, 0x1c, 0xb7, 0x14, 0xdd, 0xfc, 0x73}, + {0x41, 0xac, 0x9b, 0x44, 0x79, 0x70, 0x7e, 0x42, 0xa, 0x31, 0xe2, + 0xbc, 0x6d, 0xe3, 0x5a, 0x85, 0x7c, 0x1a, 0x84, 0x5f, 0x21, 0x76, + 0xae, 0x4c, 0xd6, 0xe1, 0x9c, 0x9a, 0xc, 0x74, 0x9e, 0x38}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1540374301420584, 1764656898914615, 1810104162020396, - 923808779163088, 664390074196579 -#else - 51293224, 22953365, 60569911, 26295436, 60124204, 26972653, - 35608016, 13765823, 39674467, 9900183 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1323460699404750, 1262690757880991, 871777133477900, - 1060078894988977, 1712236889662886 -#else - 14465486, 19721101, 34974879, 18815558, 39665676, 12990491, - 33046193, 15796406, 60056998, 25514317 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1696163952057966, 1391710137550823, 608793846867416, - 1034391509472039, 1780770894075012 -#else - 30924398, 25274812, 6359015, 20738097, 16508376, 9071735, - 41620263, 15413634, 9524356, 26535554 -#endif - }}, + {0x28, 0xac, 0xe, 0x57, 0xf6, 0x78, 0xbd, 0xc9, 0xe1, 0x9c, 0x91, + 0x27, 0x32, 0xb, 0x5b, 0xe5, 0xed, 0x91, 0x9b, 0xa1, 0xab, 0x3e, + 0xfc, 0x65, 0x90, 0x36, 0x26, 0xd6, 0xe5, 0x25, 0xc4, 0x25}, + {0xce, 0xb9, 0xdc, 0x34, 0xae, 0xb3, 0xfc, 0x64, 0xad, 0xd0, 0x48, + 0xe3, 0x23, 0x3, 0x50, 0x97, 0x1b, 0x38, 0xc6, 0x62, 0x7d, 0xf0, + 0xb3, 0x45, 0x88, 0x67, 0x5a, 0x46, 0x79, 0x53, 0x54, 0x61}, + {0x6e, 0xde, 0xd7, 0xf1, 0xa6, 0x6, 0x3e, 0x3f, 0x8, 0x23, 0x6, + 0x8e, 0x27, 0x76, 0xf9, 0x3e, 0x77, 0x6c, 0x8a, 0x4e, 0x26, 0xf6, + 0x14, 0x8c, 0x59, 0x47, 0x48, 0x15, 0x89, 0xa0, 0x39, 0x65}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1367603834210841, 2131988646583224, 890353773628144, - 1908908219165595, 270836895252891 -#else - 12274201, 20378885, 32627640, 31769106, 6736624, 13267305, - 5237659, 28444949, 15663515, 4035784 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 597536315471731, 40375058742586, 1942256403956049, - 1185484645495932, 312666282024145 -#else - 64157555, 8903984, 17349946, 601635, 50676049, 28941875, - 53376124, 17665097, 44850385, 4659090 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1919411405316294, 1234508526402192, 1066863051997083, - 1008444703737597, 1348810787701552 -#else - 50192582, 28601458, 36715152, 18395610, 20774811, 15897498, - 5736189, 15026997, 64930608, 20098846 -#endif - }}, + {0x19, 0x4a, 0xbb, 0x14, 0xd4, 0xdb, 0xc4, 0xdd, 0x8e, 0x4f, 0x42, + 0x98, 0x3c, 0xbc, 0xb2, 0x19, 0x69, 0x71, 0xca, 0x36, 0xd7, 0x9f, + 0xa8, 0x48, 0x90, 0xbd, 0x19, 0xf0, 0xe, 0x32, 0x65, 0xf}, + {0x73, 0xf7, 0xd2, 0xc3, 0x74, 0x1f, 0xd2, 0xe9, 0x45, 0x68, 0xc4, + 0x25, 0x41, 0x54, 0x50, 0xc1, 0x33, 0x9e, 0xb9, 0xf9, 0xe8, 0x5c, + 0x4e, 0x62, 0x6c, 0x18, 0xcd, 0xc5, 0xaa, 0xe4, 0xc5, 0x11}, + {0xc6, 0xe0, 0xfd, 0xca, 0xb1, 0xd1, 0x86, 0xd4, 0x81, 0x51, 0x3b, + 0x16, 0xe3, 0xe6, 0x3f, 0x4f, 0x9a, 0x93, 0xf2, 0xfa, 0xd, 0xaf, + 0xa8, 0x59, 0x2a, 0x7, 0x33, 0xec, 0xbd, 0xc7, 0xab, 0x4c}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2102881477513865, 1570274565945361, 1573617900503708, - 18662635732583, 2232324307922098 -#else - 58249865, 31335375, 28571665, 23398914, 66634396, 23448733, - 63307367, 278094, 23440562, 33264224 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1853931367696942, 8107973870707, 350214504129299, - 775206934582587, 1752317649166792 -#else - 10226222, 27625730, 15139955, 120818, 52241171, 5218602, - 32937275, 11551483, 50536904, 26111567 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1417148368003523, 721357181628282, 505725498207811, - 373232277872983, 261634707184480 -#else - 17932739, 21117156, 43069306, 10749059, 11316803, 7535897, - 22503767, 5561594, 63462240, 3898660 -#endif - }}, + {0x89, 0xd2, 0x78, 0x3f, 0x8f, 0x78, 0x8f, 0xc0, 0x9f, 0x4d, 0x40, + 0xa1, 0x2c, 0xa7, 0x30, 0xfe, 0x9d, 0xcc, 0x65, 0xcf, 0xfc, 0x8b, + 0x77, 0xf2, 0x21, 0x20, 0xcb, 0x5a, 0x16, 0x98, 0xe4, 0x7e}, + {0x2e, 0xa, 0x9c, 0x8, 0x24, 0x96, 0x9e, 0x23, 0x38, 0x47, 0xfe, + 0x3a, 0xc0, 0xc4, 0x48, 0xc7, 0x2a, 0xa1, 0x4f, 0x76, 0x2a, 0xed, + 0xdb, 0x17, 0x82, 0x85, 0x1c, 0x32, 0xf0, 0x93, 0x9b, 0x63}, + {0xc3, 0xa1, 0x11, 0x91, 0xe3, 0x8, 0xd5, 0x7b, 0x89, 0x74, 0x90, + 0x80, 0xd4, 0x90, 0x2b, 0x2b, 0x19, 0xfd, 0x72, 0xae, 0xc2, 0xae, + 0xd2, 0xe7, 0xa6, 0x2, 0xb6, 0x85, 0x3c, 0x49, 0xdf, 0xe}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2186733281493267, 2250694917008620, 1014829812957440, - 479998161452389, 83566193876474 -#else - 7749907, 32584865, 50769132, 33537967, 42090752, 15122142, - 65535333, 7152529, 21831162, 1245233 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1268116367301224, 560157088142809, 802626839600444, - 2210189936605713, 1129993785579988 -#else - 26958440, 18896406, 4314585, 8346991, 61431100, 11960071, - 34519569, 32934396, 36706772, 16838219 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 615183387352312, 917611676109240, 878893615973325, - 978940963313282, 938686890583575 -#else - 54942968, 9166946, 33491384, 13673479, 29787085, 13096535, - 6280834, 14587357, 44770839, 13987524 -#endif - }}, + {0x13, 0x41, 0x76, 0x84, 0xd2, 0xc4, 0x67, 0x67, 0x35, 0xf8, 0xf5, + 0xf7, 0x3f, 0x40, 0x90, 0xa0, 0xde, 0xbe, 0xe6, 0xca, 0xfa, 0xcf, + 0x8f, 0x1c, 0x69, 0xa3, 0xdf, 0xd1, 0x54, 0xc, 0xc0, 0x4}, + {0x68, 0x5a, 0x9b, 0x59, 0x58, 0x81, 0xcc, 0xae, 0xe, 0xe2, 0xad, + 0xeb, 0xf, 0x4f, 0x57, 0xea, 0x7, 0x7f, 0xb6, 0x22, 0x74, 0x1d, + 0xe4, 0x4f, 0xb4, 0x4f, 0x9d, 0x1, 0xe3, 0x92, 0x3b, 0x40}, + {0xf8, 0x5c, 0x46, 0x8b, 0x81, 0x2f, 0xc2, 0x4d, 0xf8, 0xef, 0x80, + 0x14, 0x5a, 0xf3, 0xa0, 0x71, 0x57, 0xd6, 0xc7, 0x4, 0xad, 0xbf, + 0xe8, 0xae, 0xf4, 0x76, 0x61, 0xb2, 0x2a, 0xb1, 0x5b, 0x35}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 522024729211672, 1045059315315808, 1892245413707790, - 1907891107684253, 2059998109500714 -#else - 42758936, 7778774, 21116000, 15572597, 62275598, 28196653, - 62807965, 28429792, 59639082, 30696363 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1799679152208884, 912132775900387, 25967768040979, - 432130448590461, 274568990261996 -#else - 9681908, 26817309, 35157219, 13591837, 60225043, 386949, - 31622781, 6439245, 52527852, 4091396 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 98698809797682, 2144627600856209, 1907959298569602, - 811491302610148, 1262481774981493 -#else - 58682418, 1470726, 38999185, 31957441, 3978626, 28430809, - 47486180, 12092162, 29077877, 18812444 -#endif - }}, + {0x18, 0x73, 0x8c, 0x5a, 0xc7, 0xda, 0x1, 0xa3, 0x11, 0xaa, 0xce, + 0xb3, 0x9d, 0x3, 0x90, 0xed, 0x2d, 0x3f, 0xae, 0x3b, 0xbf, 0x7c, + 0x7, 0x6f, 0x8e, 0xad, 0x52, 0xe0, 0xf8, 0xea, 0x18, 0x75}, + {0xf4, 0xbb, 0x93, 0x74, 0xcc, 0x64, 0x1e, 0xa7, 0xc3, 0xb0, 0xa3, + 0xec, 0xd9, 0x84, 0xbd, 0xe5, 0x85, 0xe7, 0x5, 0xfa, 0xc, 0xc5, + 0x6b, 0xa, 0x12, 0xc3, 0x2e, 0x18, 0x32, 0x81, 0x9b, 0xf}, + {0x32, 0x6c, 0x7f, 0x1b, 0xc4, 0x59, 0x88, 0xa4, 0x98, 0x32, 0x38, + 0xf4, 0xbc, 0x60, 0x2d, 0xf, 0xd9, 0xd1, 0xb1, 0xc9, 0x29, 0xa9, + 0x15, 0x18, 0xc4, 0x55, 0x17, 0xbb, 0x1b, 0x87, 0xc3, 0x47}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1791451399743152, 1713538728337276, 118349997257490, - 1882306388849954, 158235232210248 -#else - 5269168, 26694706, 53878652, 25533716, 25932562, 1763552, - 61502754, 28048550, 47091016, 2357888 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1217809823321928, 2173947284933160, 1986927836272325, - 1388114931125539, 12686131160169 -#else - 32264008, 18146780, 61721128, 32394338, 65017541, 29607531, - 23104803, 20684524, 5727337, 189038 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1650875518872272, 1136263858253897, 1732115601395988, - 734312880662190, 1252904681142109 -#else - 14609104, 24599962, 61108297, 16931650, 52531476, 25810533, - 40363694, 10942114, 41219933, 18669734 -#endif - }}, + {0xb0, 0x66, 0x50, 0xc8, 0x50, 0x5d, 0xe6, 0xfb, 0xb0, 0x99, 0xa2, + 0xb3, 0xb0, 0xc4, 0xec, 0x62, 0xe0, 0xe8, 0x1a, 0x44, 0xea, 0x54, + 0x37, 0xe5, 0x5f, 0x8d, 0xd4, 0xe8, 0x2c, 0xa0, 0xfe, 0x8}, + {0x48, 0x4f, 0xec, 0x71, 0x97, 0x53, 0x44, 0x51, 0x6e, 0x5d, 0x8c, + 0xc9, 0x7d, 0xb1, 0x5, 0xf8, 0x6b, 0xc6, 0xc3, 0x47, 0x1a, 0xc1, + 0x62, 0xf7, 0xdc, 0x99, 0x46, 0x76, 0x85, 0x9b, 0xb8, 0x0}, + {0xd0, 0xea, 0xde, 0x68, 0x76, 0xdd, 0x4d, 0x82, 0x23, 0x5d, 0x68, + 0x4b, 0x20, 0x45, 0x64, 0xc8, 0x65, 0xd6, 0x89, 0x5d, 0xcd, 0xcf, + 0x14, 0xb5, 0x37, 0xd5, 0x75, 0x4f, 0xa7, 0x29, 0x38, 0x47}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 372986456113865, 525430915458171, 2116279931702135, - 501422713587815, 1907002872974925 -#else - 20513481, 5557931, 51504251, 7829530, 26413943, 31535028, - 45729895, 7471780, 13913677, 28416557 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 803147181835288, 868941437997146, 316299302989663, - 943495589630550, 571224287904572 -#else - 41534488, 11967825, 29233242, 12948236, 60354399, 4713226, - 58167894, 14059179, 12878652, 8511905 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 227742695588364, 1776969298667369, 628602552821802, - 457210915378118, 2041906378111140 -#else - 41452044, 3393630, 64153449, 26478905, 64858154, 9366907, - 36885446, 6812973, 5568676, 30426776 -#endif - }}, + {0xc9, 0x2, 0x39, 0xad, 0x3a, 0x53, 0xd9, 0x23, 0x8f, 0x58, 0x3, + 0xef, 0xce, 0xdd, 0xc2, 0x64, 0xb4, 0x2f, 0xe1, 0xcf, 0x90, 0x73, + 0x25, 0x15, 0x90, 0xd3, 0xe4, 0x44, 0x4d, 0x8b, 0x66, 0x6c}, + {0x18, 0xc4, 0x79, 0x46, 0x75, 0xda, 0xd2, 0x82, 0xf0, 0x8d, 0x61, + 0xb2, 0xd8, 0xd7, 0x3b, 0xe6, 0xa, 0xeb, 0x47, 0xac, 0x24, 0xef, + 0x5e, 0x35, 0xb4, 0xc6, 0x33, 0x48, 0x4c, 0x68, 0x78, 0x20}, + {0xc, 0x82, 0x78, 0x7a, 0x21, 0xcf, 0x48, 0x3b, 0x97, 0x3e, 0x27, + 0x81, 0xb2, 0xa, 0x6a, 0xf7, 0x7b, 0xed, 0x8e, 0x8c, 0xa7, 0x65, + 0x6c, 0xa9, 0x3f, 0x43, 0x8a, 0x4f, 0x5, 0xa6, 0x11, 0x74}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 815000523470260, 913085688728307, 1052060118271173, - 1345536665214223, 541623413135555 -#else - 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, - 49700111, 20050058, 52713667, 8070817 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1580216071604333, 1877997504342444, 857147161260913, - 703522726778478, 2182763974211603 -#else - 27117677, 23547054, 35826092, 27984343, 1127281, 12772488, - 37262958, 10483305, 55556115, 32525717 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1870080310923419, 71988220958492, 1783225432016732, - 615915287105016, 1035570475990230 -#else - 10637467, 27866368, 5674780, 1072708, 40765276, 26572129, - 65424888, 9177852, 39615702, 15431202 -#endif - }}, + {0xb4, 0x75, 0xb1, 0x18, 0x3d, 0xe5, 0x9a, 0x57, 0x2, 0xa1, 0x92, + 0xf3, 0x59, 0x31, 0x71, 0x68, 0xf5, 0x35, 0xef, 0x1e, 0xba, 0xec, + 0x55, 0x84, 0x8f, 0x39, 0x8c, 0x45, 0x72, 0xa8, 0xc9, 0x1e}, + {0x6d, 0xc8, 0x9d, 0xb9, 0x32, 0x9d, 0x65, 0x4d, 0x15, 0xf1, 0x3a, + 0x60, 0x75, 0xdc, 0x4c, 0x4, 0x88, 0xe4, 0xc2, 0xdc, 0x2c, 0x71, + 0x4c, 0xb3, 0xff, 0x34, 0x81, 0xfb, 0x74, 0x65, 0x13, 0x7c}, + {0x9b, 0x50, 0xa2, 0x0, 0xd4, 0xa4, 0xe6, 0xb8, 0xb4, 0x82, 0xc8, + 0xb, 0x2, 0xd7, 0x81, 0x9b, 0x61, 0x75, 0x95, 0xf1, 0x9b, 0xcc, + 0xe7, 0x57, 0x60, 0x64, 0xcd, 0xc7, 0xa5, 0x88, 0xdd, 0x3a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 730987750830150, 857613889540280, 1083813157271766, - 1002817255970169, 1719228484436074 -#else - 20525126, 10892566, 54366392, 12779442, 37615830, 16150074, - 38868345, 14943141, 52052074, 25618500 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 377616581647602, 1581980403078513, 804044118130621, - 2034382823044191, 643844048472185 -#else - 37084402, 5626925, 66557297, 23573344, 753597, 11981191, - 25244767, 30314666, 63752313, 9594023 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 176957326463017, 1573744060478586, 528642225008045, - 1816109618372371, 1515140189765006 -#else - 43356201, 2636869, 61944954, 23450613, 585133, 7877383, - 11345683, 27062142, 13352334, 22577348 -#endif - }}, + {0x46, 0x30, 0x39, 0x59, 0xd4, 0x98, 0xc2, 0x85, 0xec, 0x59, 0xf6, + 0x5f, 0x98, 0x35, 0x7e, 0x8f, 0x3a, 0x6e, 0xf6, 0xf2, 0x2a, 0xa2, + 0x2c, 0x1d, 0x20, 0xa7, 0x6, 0xa4, 0x31, 0x11, 0xba, 0x61}, + {0xf2, 0xdc, 0x35, 0xb6, 0x70, 0x57, 0x89, 0xab, 0xbc, 0x1f, 0x6c, + 0xf6, 0x6c, 0xef, 0xdf, 0x2, 0x87, 0xd1, 0xb6, 0xbe, 0x68, 0x2, + 0x53, 0x85, 0x74, 0x9e, 0x87, 0xcc, 0xfc, 0x29, 0x99, 0x24}, + {0x29, 0x90, 0x95, 0x16, 0xf1, 0xa0, 0xd0, 0xa3, 0x89, 0xbd, 0x7e, + 0xba, 0x6c, 0x6b, 0x3b, 0x2, 0x7, 0x33, 0x78, 0x26, 0x3e, 0x5a, + 0xf1, 0x7b, 0xe7, 0xec, 0xd8, 0xbb, 0xc, 0x31, 0x20, 0x56}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1888911448245718, 1387110895611080, 1924503794066429, - 1731539523700949, 2230378382645454 -#else - 65177046, 28146973, 3304648, 20669563, 17015805, 28677341, - 37325013, 25801949, 53893326, 33235227 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 443392177002051, 233793396845137, 2199506622312416, - 1011858706515937, 974676837063129 -#else - 20239939, 6607058, 6203985, 3483793, 48721888, 32775202, - 46385121, 15077869, 44358105, 14523816 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1846351103143623, 1949984838808427, 671247021915253, - 1946756846184401, 1929296930380217 -#else - 27406023, 27512775, 27423595, 29057038, 4996213, 10002360, - 38266833, 29008937, 36936121, 28748764 -#endif - }}, + {0xd6, 0x85, 0xe2, 0x77, 0xf4, 0xb5, 0x46, 0x66, 0x93, 0x61, 0x8f, + 0x6c, 0x67, 0xff, 0xe8, 0x40, 0xdd, 0x94, 0xb5, 0xab, 0x11, 0x73, + 0xec, 0xa6, 0x4d, 0xec, 0x8c, 0x65, 0xf3, 0x46, 0xc8, 0x7e}, + {0x43, 0xd6, 0x34, 0x49, 0x43, 0x93, 0x89, 0x52, 0xf5, 0x22, 0x12, + 0xa5, 0x6, 0xf8, 0xdb, 0xb9, 0x22, 0x1c, 0xf4, 0xc3, 0x8f, 0x87, + 0x6d, 0x8f, 0x30, 0x97, 0x9d, 0x4d, 0x2a, 0x6a, 0x67, 0x37}, + {0xc7, 0x2e, 0xa2, 0x1d, 0x3f, 0x8f, 0x5e, 0x9b, 0x13, 0xcd, 0x1, + 0x6c, 0x77, 0x1d, 0xf, 0x13, 0xb8, 0x9f, 0x98, 0xa2, 0xcf, 0x8f, + 0x4c, 0x21, 0xd5, 0x9d, 0x9b, 0x39, 0x23, 0xf7, 0xaa, 0x6d}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 849646212452002, 1410198775302919, 73767886183695, - 1641663456615812, 762256272452411 -#else - 11374242, 12660715, 17861383, 21013599, 10935567, 1099227, - 53222788, 24462691, 39381819, 11358503 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 692017667358279, 723305578826727, 1638042139863265, - 748219305990306, 334589200523901 -#else - 54378055, 10311866, 1510375, 10778093, 64989409, 24408729, - 32676002, 11149336, 40985213, 4985767 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 22893968530686, 2235758574399251, 1661465835630252, - 925707319443452, 1203475116966621 -#else - 48012542, 341146, 60911379, 33315398, 15756972, 24757770, - 66125820, 13794113, 47694557, 17933176 -#endif - }}, + {0xa2, 0x8e, 0xad, 0xac, 0xbf, 0x4, 0x3b, 0x58, 0x84, 0xe8, 0x8b, + 0x14, 0xe8, 0x43, 0xb7, 0x29, 0xdb, 0xc5, 0x10, 0x8, 0x3b, 0x58, + 0x1e, 0x2b, 0xaa, 0xbb, 0xb3, 0x8e, 0xe5, 0x49, 0x54, 0x2b}, + {0x47, 0xbe, 0x3d, 0xeb, 0x62, 0x75, 0x3a, 0x5f, 0xb8, 0xa0, 0xbd, + 0x8e, 0x54, 0x38, 0xea, 0xf7, 0x99, 0x72, 0x74, 0x45, 0x31, 0xe5, + 0xc3, 0x0, 0x51, 0xd5, 0x27, 0x16, 0xe7, 0xe9, 0x4, 0x13}, + {0xfe, 0x9c, 0xdc, 0x6a, 0xd2, 0x14, 0x98, 0x78, 0xb, 0xdd, 0x48, + 0x8b, 0x3f, 0xab, 0x1b, 0x3c, 0xa, 0xc6, 0x79, 0xf9, 0xff, 0xe1, + 0xf, 0xda, 0x93, 0xd6, 0x2d, 0x7c, 0x2d, 0xde, 0x68, 0x44}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 801299035785166, 1733292596726131, 1664508947088596, - 467749120991922, 1647498584535623 -#else - 6490062, 11940286, 25495923, 25828072, 8668372, 24803116, - 3367602, 6970005, 65417799, 24549641 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 903105258014366, 427141894933047, 561187017169777, - 1884330244401954, 1914145708422219 -#else - 1656478, 13457317, 15370807, 6364910, 13605745, 8362338, - 47934242, 28078708, 50312267, 28522993 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1344191060517578, 1960935031767890, 1518838929955259, - 1781502350597190, 1564784025565682 -#else - 44835530, 20030007, 67044178, 29220208, 48503227, 22632463, - 46537798, 26546453, 67009010, 23317098 -#endif - }}, + {0xce, 0x7, 0x63, 0xf8, 0xc6, 0xd8, 0x9a, 0x4b, 0x28, 0xc, 0x5d, + 0x43, 0x31, 0x35, 0x11, 0x21, 0x2c, 0x77, 0x7a, 0x65, 0xc5, 0x66, + 0xa8, 0xd4, 0x52, 0x73, 0x24, 0x63, 0x7e, 0x42, 0xa6, 0x5d}, + {0x9e, 0x46, 0x19, 0x94, 0x5e, 0x35, 0xbb, 0x51, 0x54, 0xc7, 0xdd, + 0x23, 0x4c, 0xdc, 0xe6, 0x33, 0x62, 0x99, 0x7f, 0x44, 0xd6, 0xb6, + 0xa5, 0x93, 0x63, 0xbd, 0x44, 0xfb, 0x6f, 0x7c, 0xce, 0x6c}, + {0xca, 0x22, 0xac, 0xde, 0x88, 0xc6, 0x94, 0x1a, 0xf8, 0x1f, 0xae, + 0xbb, 0xf7, 0x6e, 0x6, 0xb9, 0xf, 0x58, 0x59, 0x8d, 0x38, 0x8c, + 0xad, 0x88, 0xa8, 0x2c, 0x9f, 0xe7, 0xbf, 0x9a, 0xf2, 0x58}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 673723351748086, 1979969272514923, 1175287312495508, - 1187589090978666, 1881897672213940 -#else - 17747446, 10039260, 19368299, 29503841, 46478228, 17513145, - 31992682, 17696456, 37848500, 28042460 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1917185587363432, 1098342571752737, 5935801044414, - 2000527662351839, 1538640296181569 -#else - 31932008, 28568291, 47496481, 16366579, 22023614, 88450, - 11371999, 29810185, 4882241, 22927527 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2495540013192, 678856913479236, 224998292422872, - 219635787698590, 1972465269000940 -#else - 29796488, 37186, 19818052, 10115756, 55279832, 3352735, - 18551198, 3272828, 61917932, 29392022 -#endif - }}, + {0xf6, 0xcd, 0xe, 0x71, 0xbf, 0x64, 0x5a, 0x4b, 0x3c, 0x29, 0x2c, + 0x46, 0x38, 0xe5, 0x4c, 0xb1, 0xb9, 0x3a, 0xb, 0xd5, 0x56, 0xd0, + 0x43, 0x36, 0x70, 0x48, 0x5b, 0x18, 0x24, 0x37, 0xf9, 0x6a}, + {0x68, 0x3e, 0xe7, 0x8d, 0xab, 0xcf, 0xe, 0xe9, 0xa5, 0x76, 0x7e, + 0x37, 0x9f, 0x6f, 0x3, 0x54, 0x82, 0x59, 0x1, 0xbe, 0xb, 0x5b, + 0x49, 0xf0, 0x36, 0x1e, 0xf4, 0xa7, 0xc4, 0x29, 0x76, 0x57}, + {0x88, 0xa8, 0xc6, 0x9, 0x45, 0x2, 0x20, 0x32, 0x73, 0x89, 0x55, + 0x4b, 0x13, 0x36, 0xe0, 0xd2, 0x9f, 0x28, 0x33, 0x3c, 0x23, 0x36, + 0xe2, 0x83, 0x8f, 0xc1, 0xae, 0xc, 0xbb, 0x25, 0x1f, 0x70}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 271413961212179, 1353052061471651, 344711291283483, - 2014925838520662, 2006221033113941 -#else - 12501267, 4044383, 58495907, 20162046, 34678811, 5136598, - 47878486, 30024734, 330069, 29895023 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 194583029968109, 514316781467765, 829677956235672, - 1676415686873082, 810104584395840 -#else - 6384877, 2899513, 17807477, 7663917, 64749976, 12363164, - 25366522, 24980540, 66837568, 12071498 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1980510813313589, 1948645276483975, 152063780665900, - 129968026417582, 256984195613935 -#else - 58743349, 29511910, 25133447, 29037077, 60897836, 2265926, - 34339246, 1936674, 61949167, 3829362 -#endif - }}, + {0x13, 0xc1, 0xbe, 0x7c, 0xd9, 0xf6, 0x18, 0x9d, 0xe4, 0xdb, 0xbf, + 0x74, 0xe6, 0x6, 0x4a, 0x84, 0xd6, 0x60, 0x4e, 0xac, 0x22, 0xb5, + 0xf5, 0x20, 0x51, 0x5e, 0x95, 0x50, 0xc0, 0x5b, 0xa, 0x72}, + {0xed, 0x6c, 0x61, 0xe4, 0xf8, 0xb0, 0xa8, 0xc3, 0x7d, 0xa8, 0x25, + 0x9e, 0xe, 0x66, 0x0, 0xf7, 0x9c, 0xa5, 0xbc, 0xf4, 0x1f, 0x6, + 0xe3, 0x61, 0xe9, 0xb, 0xc4, 0xbd, 0xbf, 0x92, 0xc, 0x2e}, + {0x35, 0x5a, 0x80, 0x9b, 0x43, 0x9, 0x3f, 0xc, 0xfc, 0xab, 0x42, + 0x62, 0x37, 0x8b, 0x4e, 0xe8, 0x46, 0x93, 0x22, 0x5c, 0xf3, 0x17, + 0x14, 0x69, 0xec, 0xf0, 0x4e, 0x14, 0xbb, 0x9c, 0x9b, 0xe}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1860190562533102, 1936576191345085, 461100292705964, - 1811043097042830, 957486749306835 -#else - 28425966, 27718999, 66531773, 28857233, 52891308, 6870929, - 7921550, 26986645, 26333139, 14267664 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 796664815624365, 1543160838872951, 1500897791837765, - 1667315977988401, 599303877030711 -#else - 56041645, 11871230, 27385719, 22994888, 62522949, 22365119, - 10004785, 24844944, 45347639, 8930323 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1151480509533204, 2136010406720455, 738796060240027, - 319298003765044, 1150614464349587 -#else - 45911060, 17158396, 25654215, 31829035, 12282011, 11008919, - 1541940, 4757911, 40617363, 17145491 -#endif - }}, + {0xee, 0xbe, 0xb1, 0x5d, 0xd5, 0x9b, 0xee, 0x8d, 0xb9, 0x3f, 0x72, + 0xa, 0x37, 0xab, 0xc3, 0xc9, 0x91, 0xd7, 0x68, 0x1c, 0xbf, 0xf1, + 0xa8, 0x44, 0xde, 0x3c, 0xfd, 0x1c, 0x19, 0x44, 0x6d, 0x36}, + {0xad, 0x20, 0x57, 0xfb, 0x8f, 0xd4, 0xba, 0xfb, 0xe, 0xd, 0xf9, + 0xdb, 0x6b, 0x91, 0x81, 0xee, 0xbf, 0x43, 0x55, 0x63, 0x52, 0x31, + 0x81, 0xd4, 0xd8, 0x7b, 0x33, 0x3f, 0xeb, 0x4, 0x11, 0x22}, + {0x14, 0x8c, 0xbc, 0xf2, 0x43, 0x17, 0x3c, 0x9e, 0x3b, 0x6c, 0x85, + 0xb5, 0xfc, 0x26, 0xda, 0x2e, 0x97, 0xfb, 0xa7, 0x68, 0xe, 0x2f, + 0xb8, 0xcc, 0x44, 0x32, 0x59, 0xbc, 0xe6, 0xa4, 0x67, 0x41}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1731069268103150, 735642447616087, 1364750481334268, - 417232839982871, 927108269127661 -#else - 13537262, 25794942, 46504023, 10961926, 61186044, 20336366, - 53952279, 6217253, 51165165, 13814989 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1017222050227968, 1987716148359, 2234319589635701, - 621282683093392, 2132553131763026 -#else - 49686272, 15157789, 18705543, 29619, 24409717, 33293956, - 27361680, 9257833, 65152338, 31777517 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1567828528453324, 1017807205202360, 565295260895298, - 829541698429100, 307243822276582 -#else - 42063564, 23362465, 15366584, 15166509, 54003778, 8423555, - 37937324, 12361134, 48422886, 4578289 -#endif - }}, + {0xee, 0x8f, 0xce, 0xf8, 0x65, 0x26, 0xbe, 0xc2, 0x2c, 0xd6, 0x80, + 0xe8, 0x14, 0xff, 0x67, 0xe9, 0xee, 0x4e, 0x36, 0x2f, 0x7e, 0x6e, + 0x2e, 0xf1, 0xf6, 0xd2, 0x7e, 0xcb, 0x70, 0x33, 0xb3, 0x34}, + {0x0, 0x27, 0xf6, 0x76, 0x28, 0x9d, 0x3b, 0x64, 0xeb, 0x68, 0x76, + 0xe, 0x40, 0x9d, 0x1d, 0x5d, 0x84, 0x6, 0xfc, 0x21, 0x3, 0x43, + 0x4b, 0x1b, 0x6a, 0x24, 0x55, 0x22, 0x7e, 0xbb, 0x38, 0x79}, + {0xcc, 0xd6, 0x81, 0x86, 0xee, 0x91, 0xc5, 0xcd, 0x53, 0xa7, 0x85, + 0xed, 0x9c, 0x10, 0x2, 0xce, 0x83, 0x88, 0x80, 0x58, 0xc1, 0x85, + 0x74, 0xed, 0xe4, 0x65, 0xfe, 0x2d, 0x6e, 0xfc, 0x76, 0x11}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 249079270936248, 1501514259790706, 947909724204848, - 944551802437487, 552658763982480 -#else - 24579768, 3711570, 1342322, 22374306, 40103728, 14124955, - 44564335, 14074918, 21964432, 8235257 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2089966982947227, 1854140343916181, 2151980759220007, - 2139781292261749, 158070445864917 -#else - 60580251, 31142934, 9442965, 27628844, 12025639, 32067012, - 64127349, 31885225, 13006805, 2355433 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1338766321464554, 1906702607371284, 1519569445519894, - 115384726262267, 1393058953390992 -#else - 50803946, 19949172, 60476436, 28412082, 16974358, 22643349, - 27202043, 1719366, 1141648, 20758196 -#endif - }}, + {0xb8, 0xe, 0x77, 0x49, 0x89, 0xe2, 0x90, 0xdb, 0xa3, 0x40, 0xf4, + 0xac, 0x2a, 0xcc, 0xfb, 0x98, 0x9b, 0x87, 0xd7, 0xde, 0xfe, 0x4f, + 0x35, 0x21, 0xb6, 0x6, 0x69, 0xf2, 0x54, 0x3e, 0x6a, 0x1f}, + {0x9b, 0x61, 0x9c, 0x5b, 0xd0, 0x6c, 0xaf, 0xb4, 0x80, 0x84, 0xa5, + 0xb2, 0xf4, 0xc9, 0xdf, 0x2d, 0xc4, 0x4d, 0xe9, 0xeb, 0x2, 0xa5, + 0x4f, 0x3d, 0x34, 0x5f, 0x7d, 0x67, 0x4c, 0x3a, 0xfc, 0x8}, + {0xea, 0x34, 0x7, 0xd3, 0x99, 0xc1, 0xa4, 0x60, 0xd6, 0x5c, 0x16, + 0x31, 0xb6, 0x85, 0xc0, 0x40, 0x95, 0x82, 0x59, 0xf7, 0x23, 0x3e, + 0x33, 0xe2, 0xd1, 0x0, 0xb9, 0x16, 0x1, 0xad, 0x2f, 0x4f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1364621558265400, 1512388234908357, 1926731583198686, - 2041482526432505, 920401122333774 -#else - 54244920, 20334445, 58790597, 22536340, 60298718, 28710537, - 13475065, 30420460, 32674894, 13715045 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1884844597333588, 601480070269079, 620203503079537, - 1079527400117915, 1202076693132015 -#else - 11423316, 28086373, 32344215, 8962751, 24989809, 9241752, - 53843611, 16086211, 38367983, 17912338 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 840922919763324, 727955812569642, 1303406629750194, - 522898432152867, 294161410441865 -#else - 65699196, 12530727, 60740138, 10847386, 19531186, 19422272, - 55399715, 7791793, 39862921, 4383346 -#endif - }}, + {0x38, 0xb6, 0x3b, 0xb7, 0x1d, 0xd9, 0x2c, 0x96, 0x8, 0x9c, 0x12, + 0xfc, 0xaa, 0x77, 0x5, 0xe6, 0x89, 0x16, 0xb6, 0xf3, 0x39, 0x9b, + 0x61, 0x6f, 0x81, 0xee, 0x44, 0x29, 0x5f, 0x99, 0x51, 0x34}, + {0x54, 0x4e, 0xae, 0x94, 0x41, 0xb2, 0xbe, 0x44, 0x6c, 0xef, 0x57, + 0x18, 0x51, 0x1c, 0x54, 0x5f, 0x98, 0x4, 0x8d, 0x36, 0x2d, 0x6b, + 0x1e, 0xa6, 0xab, 0xf7, 0x2e, 0x97, 0xa4, 0x84, 0x54, 0x44}, + {0x7c, 0x7d, 0xea, 0x9f, 0xd0, 0xfc, 0x52, 0x91, 0xf6, 0x5c, 0x93, + 0xb0, 0x94, 0x6c, 0x81, 0x4a, 0x40, 0x5c, 0x28, 0x47, 0xaa, 0x9a, + 0x8e, 0x25, 0xb7, 0x93, 0x28, 0x4, 0xa6, 0x9c, 0xb8, 0x10}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 353760790835310, 1598361541848743, 1122905698202299, - 1922533590158905, 419107700666580 -#else - 38137966, 5271446, 65842855, 23817442, 54653627, 16732598, - 62246457, 28647982, 27193556, 6245191 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 359856369838236, 180914355488683, 861726472646627, - 218807937262986, 575626773232501 -#else - 51914908, 5362277, 65324971, 2695833, 4960227, 12840725, - 23061898, 3260492, 22510453, 8577507 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 755467689082474, 909202735047934, 730078068932500, - 936309075711518, 2007798262842972 -#else - 54476394, 11257345, 34415870, 13548176, 66387860, 10879010, - 31168030, 13952092, 37537372, 29918525 -#endif - }}, + {0x6e, 0xf0, 0x45, 0x5a, 0xbe, 0x41, 0x39, 0x75, 0x65, 0x5f, 0x9c, + 0x6d, 0xed, 0xae, 0x7c, 0xd0, 0xb6, 0x51, 0xff, 0x72, 0x9c, 0x6b, + 0x77, 0x11, 0xa9, 0x4d, 0xd, 0xef, 0xd9, 0xd1, 0xd2, 0x17}, + {0x9c, 0x28, 0x18, 0x97, 0x49, 0x47, 0x59, 0x3d, 0x26, 0x3f, 0x53, + 0x24, 0xc5, 0xf8, 0xeb, 0x12, 0x15, 0xef, 0xc3, 0x14, 0xcb, 0xbf, + 0x62, 0x2, 0x8e, 0x51, 0xb7, 0x77, 0xd5, 0x78, 0xb8, 0x20}, + {0x6a, 0x3e, 0x3f, 0x7, 0x18, 0xaf, 0xf2, 0x27, 0x69, 0x10, 0x52, + 0xd7, 0x19, 0xe5, 0x3f, 0xfd, 0x22, 0x0, 0xa6, 0x3c, 0x2c, 0xb7, + 0xe3, 0x22, 0xa7, 0xc6, 0x65, 0xcc, 0x63, 0x4f, 0x21, 0x72}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1609384177904073, 362745185608627, 1335318541768201, - 800965770436248, 547877979267412 -#else - 3877321, 23981693, 32416691, 5405324, 56104457, 19897796, - 3759768, 11935320, 5611860, 8164018 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 984339177776787, 815727786505884, 1645154585713747, - 1659074964378553, 1686601651984156 -#else - 50833043, 14667796, 15906460, 12155291, 44997715, 24514713, - 32003001, 24722143, 5773084, 25132323 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1697863093781930, 599794399429786, 1104556219769607, - 830560774794755, 12812858601017 -#else - 43320746, 25300131, 1950874, 8937633, 18686727, 16459170, - 66203139, 12376319, 31632953, 190926 -#endif - }}, + {0xc9, 0x29, 0x3b, 0xf4, 0xb9, 0xb7, 0x9d, 0x1d, 0x75, 0x8f, 0x51, + 0x4f, 0x4a, 0x82, 0x5, 0xd6, 0xc4, 0x9d, 0x2f, 0x31, 0xbd, 0x72, + 0xc0, 0xf2, 0xb0, 0x45, 0x15, 0x5a, 0x85, 0xac, 0x24, 0x1f}, + {0x93, 0xa6, 0x7, 0x53, 0x40, 0x7f, 0xe3, 0xb4, 0x95, 0x67, 0x33, + 0x2f, 0xd7, 0x14, 0xa7, 0xab, 0x99, 0x10, 0x76, 0x73, 0xa7, 0xd0, + 0xfb, 0xd6, 0xc9, 0xcb, 0x71, 0x81, 0xc5, 0x48, 0xdf, 0x5f}, + {0xaa, 0x5, 0x95, 0x8e, 0x32, 0x8, 0xd6, 0x24, 0xee, 0x20, 0x14, + 0xc, 0xd1, 0xc1, 0x48, 0x47, 0xa2, 0x25, 0xfb, 0x6, 0x5c, 0xe4, + 0xff, 0xc7, 0xe6, 0x95, 0xe3, 0x2a, 0x9e, 0x73, 0xba, 0x0}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1168737550514982, 897832437380552, 463140296333799, - 302564600022547, 2008360505135501 -#else - 42515238, 17415546, 58684872, 13378745, 14162407, 6901328, - 58820115, 4508563, 41767309, 29926903 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1856930662813910, 678090852002597, 1920179140755167, - 1259527833759868, 55540971895511 -#else - 8884438, 27670423, 6023973, 10104341, 60227295, 28612898, - 18722940, 18768427, 65436375, 827624 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1158643631044921, 476554103621892, 178447851439725, - 1305025542653569, 103433927680625 -#else - 34388281, 17265135, 34605316, 7101209, 13354605, 2659080, - 65308289, 19446395, 42230385, 1541285 -#endif - }}, + {0x26, 0xbb, 0x88, 0xea, 0xf5, 0x26, 0x44, 0xae, 0xfb, 0x3b, 0x97, + 0x84, 0xd9, 0x79, 0x6, 0x36, 0x50, 0x4e, 0x69, 0x26, 0xc, 0x3, + 0x9f, 0x5c, 0x26, 0xd2, 0x18, 0xd5, 0xe7, 0x7d, 0x29, 0x72}, + {0xd6, 0x90, 0x87, 0x5c, 0xde, 0x98, 0x2e, 0x59, 0xdf, 0xa2, 0xc2, + 0x45, 0xd3, 0xb7, 0xbf, 0xe5, 0x22, 0x99, 0xb4, 0xf9, 0x60, 0x3b, + 0x5a, 0x11, 0xf3, 0x78, 0xad, 0x67, 0x3e, 0x3a, 0x28, 0x3}, + {0x39, 0xb9, 0xc, 0xbe, 0xc7, 0x1d, 0x24, 0x48, 0x80, 0x30, 0x63, + 0x8b, 0x4d, 0x9b, 0xf1, 0x32, 0x8, 0x93, 0x28, 0x2, 0xd, 0xc9, + 0xdf, 0xd3, 0x45, 0x19, 0x27, 0x46, 0x68, 0x29, 0xe1, 0x5}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2176793111709008, 1576725716350391, 2009350167273523, - 2012390194631546, 2125297410909580 -#else - 2901328, 32436745, 3880375, 23495044, 49487923, 29941650, - 45306746, 29986950, 20456844, 31669399 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 825403285195098, 2144208587560784, 1925552004644643, - 1915177840006985, 1015952128947864 -#else - 27019610, 12299467, 53450576, 31951197, 54247203, 28692960, - 47568713, 28538373, 29439640, 15138866 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1807108316634472, 1534392066433717, 347342975407218, - 1153820745616376, 7375003497471 -#else - 21536104, 26928012, 34661045, 22864223, 44700786, 5175813, - 61688824, 17193268, 7779327, 109896 -#endif - }}, + {0x50, 0x45, 0x2c, 0x24, 0xc8, 0xbb, 0xbf, 0xad, 0xd9, 0x81, 0x30, + 0xd0, 0xec, 0xc, 0xc8, 0xbc, 0x92, 0xdf, 0xc8, 0xf5, 0xa6, 0x66, + 0x35, 0x84, 0x4c, 0xce, 0x58, 0x82, 0xd3, 0x25, 0xcf, 0x78}, + {0x5a, 0x49, 0x9c, 0x2d, 0xb3, 0xee, 0x82, 0xba, 0x7c, 0xb9, 0x2b, + 0xf1, 0xfc, 0xc8, 0xef, 0xce, 0xe0, 0xd1, 0xb5, 0x93, 0xae, 0xab, + 0x2d, 0xb0, 0x9b, 0x8d, 0x69, 0x13, 0x9c, 0xc, 0xc0, 0x39}, + {0x68, 0x9d, 0x48, 0x31, 0x8e, 0x6b, 0xae, 0x15, 0x87, 0xf0, 0x2b, + 0x9c, 0xab, 0x1c, 0x85, 0xaa, 0x5, 0xfa, 0x4e, 0xf0, 0x97, 0x5a, + 0xa7, 0xc9, 0x32, 0xf8, 0x3f, 0x6b, 0x7, 0x52, 0x6b, 0x0}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 983061001799725, 431211889901241, 2201903782961093, - 817393911064341, 2214616493042167 -#else - 30279725, 14648750, 59063993, 6425557, 13639621, 32810923, - 28698389, 12180118, 23177719, 33000357 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 228567918409756, 865093958780220, 358083886450556, - 159617889659320, 1360637926292598 -#else - 26572828, 3405927, 35407164, 12890904, 47843196, 5335865, - 60615096, 2378491, 4439158, 20275085 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 234147501399755, 2229469128637390, 2175289352258889, - 1397401514549353, 1885288963089922 -#else - 44392139, 3489069, 57883598, 33221678, 18875721, 32414337, - 14819433, 20822905, 49391106, 28092994 -#endif - }}, + {0x2d, 0x8, 0xce, 0xb9, 0x16, 0x7e, 0xcb, 0xf5, 0x29, 0xbc, 0x7a, + 0x41, 0x4c, 0xf1, 0x7, 0x34, 0xab, 0xa7, 0xf4, 0x2b, 0xce, 0x6b, + 0xb3, 0xd4, 0xce, 0x75, 0x9f, 0x1a, 0x56, 0xe9, 0xe2, 0x7d}, + {0x1c, 0x78, 0x95, 0x9d, 0xe1, 0xcf, 0xe0, 0x29, 0xe2, 0x10, 0x63, + 0x96, 0x18, 0xdf, 0x81, 0xb6, 0x39, 0x6b, 0x51, 0x70, 0xd3, 0x39, + 0xdf, 0x57, 0x22, 0x61, 0xc7, 0x3b, 0x44, 0xe3, 0x57, 0x4d}, + {0xcb, 0x5e, 0xa5, 0xb6, 0xf4, 0xd4, 0x70, 0xde, 0x99, 0xdb, 0x85, + 0x5d, 0x7f, 0x52, 0x1, 0x48, 0x81, 0x9a, 0xee, 0xd3, 0x40, 0xc4, + 0xc9, 0xdb, 0xed, 0x29, 0x60, 0x1a, 0xaf, 0x90, 0x2a, 0x6b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1111762412951562, 252849572507389, 1048714233823341, - 146111095601446, 1237505378776770 -#else - 62052362, 16566550, 15953661, 3767752, 56672365, 15627059, - 66287910, 2177224, 8550082, 18440267 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1113790697840279, 1051167139966244, 1045930658550944, - 2011366241542643, 1686166824620755 -#else - 48635543, 16596774, 66727204, 15663610, 22860960, 15585581, - 39264755, 29971692, 43848403, 25125843 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1054097349305049, 1872495070333352, 182121071220717, - 1064378906787311, 100273572924182 -#else - 34628313, 15707274, 58902952, 27902350, 29464557, 2713815, - 44383727, 15860481, 45206294, 1494192 -#endif - }}, + {0xa, 0xd8, 0xb2, 0x5b, 0x24, 0xf3, 0xeb, 0x77, 0x9b, 0x7, 0xb9, + 0x2f, 0x47, 0x1b, 0x30, 0xd8, 0x33, 0x73, 0xee, 0x4c, 0xf2, 0xe6, + 0x47, 0xc6, 0x9, 0x21, 0x6c, 0x27, 0xc8, 0x12, 0x58, 0x46}, + {0x97, 0x1e, 0xe6, 0x9a, 0xfc, 0xf4, 0x23, 0x69, 0xd1, 0x5f, 0x3f, + 0xe0, 0x1d, 0x28, 0x35, 0x57, 0x2d, 0xd1, 0xed, 0xe6, 0x43, 0xae, + 0x64, 0xa7, 0x4a, 0x3e, 0x2d, 0xd1, 0xe9, 0xf4, 0xd8, 0x5f}, + {0xd9, 0x62, 0x10, 0x2a, 0xb2, 0xbe, 0x43, 0x4d, 0x16, 0xdc, 0x31, + 0x38, 0x75, 0xfb, 0x65, 0x70, 0xd7, 0x68, 0x29, 0xde, 0x7b, 0x4a, + 0xd, 0x18, 0x90, 0x67, 0xb1, 0x1c, 0x2b, 0x2c, 0xb3, 0x5}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1306410853171605, 1627717417672447, 50983221088417, - 1109249951172250, 870201789081392 -#else - 47546773, 19467038, 41524991, 24254879, 13127841, 759709, - 21923482, 16529112, 8742704, 12967017 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 104233794644221, 1548919791188248, 2224541913267306, - 2054909377116478, 1043803389015153 -#else - 38643965, 1553204, 32536856, 23080703, 42417258, 33148257, - 58194238, 30620535, 37205105, 15553882 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 216762189468802, 707284285441622, 190678557969733, - 973969342604308, 1403009538434867 -#else - 21877890, 3230008, 9881174, 10539357, 62311749, 2841331, - 11543572, 14513274, 19375923, 20906471 -#endif - }}, + {0x95, 0x81, 0xd5, 0x7a, 0x2c, 0xa4, 0xfc, 0xf7, 0xcc, 0xf3, 0x33, + 0x43, 0x6e, 0x28, 0x14, 0x32, 0x9d, 0x97, 0xb, 0x34, 0xd, 0x9d, + 0xc2, 0xb6, 0xe1, 0x7, 0x73, 0x56, 0x48, 0x1a, 0x77, 0x31}, + {0xfd, 0xa8, 0x4d, 0xd2, 0xcc, 0x5e, 0xc0, 0xc8, 0x83, 0xef, 0xdf, + 0x5, 0xac, 0x1a, 0xcf, 0xa1, 0x61, 0xcd, 0xf9, 0x7d, 0xf2, 0xef, + 0xbe, 0xdb, 0x99, 0x1e, 0x47, 0x7b, 0xa3, 0x56, 0x55, 0x3b}, + {0x82, 0xd4, 0x4d, 0xe1, 0x24, 0xc5, 0xb0, 0x32, 0xb6, 0xa4, 0x2b, + 0x1a, 0x54, 0x51, 0xb3, 0xed, 0xf3, 0x5a, 0x2b, 0x28, 0x48, 0x60, + 0xd1, 0xa3, 0xeb, 0x36, 0x73, 0x7a, 0xd2, 0x79, 0xc0, 0x4f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1279024291038477, 344776835218310, 273722096017199, - 1834200436811442, 634517197663804 -#else - 8832269, 19058947, 13253510, 5137575, 5037871, 4078777, - 24880818, 27331716, 2862652, 9455043 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 343805853118335, 1302216857414201, 566872543223541, - 2051138939539004, 321428858384280 -#else - 29306751, 5123106, 20245049, 19404543, 9592565, 8447059, - 65031740, 30564351, 15511448, 4789663 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 470067171324852, 1618629234173951, 2000092177515639, - 7307679772789, 1117521120249968 -#else - 46429108, 7004546, 8824831, 24119455, 63063159, 29803695, - 61354101, 108892, 23513200, 16652362 -#endif - }}, + {0xd, 0xc5, 0x86, 0xc, 0x44, 0x8b, 0x34, 0xdc, 0x51, 0xe6, 0x94, + 0xcc, 0xc9, 0xcb, 0x37, 0x13, 0xb9, 0x3c, 0x3e, 0x64, 0x4d, 0xf7, + 0x22, 0x64, 0x8, 0xcd, 0xe3, 0xba, 0xc2, 0x70, 0x11, 0x24}, + {0x7f, 0x2f, 0xbf, 0x89, 0xb0, 0x38, 0xc9, 0x51, 0xa7, 0xe9, 0xdf, + 0x2, 0x65, 0xbd, 0x97, 0x24, 0x53, 0xe4, 0x80, 0x78, 0x9c, 0xc0, + 0xff, 0xff, 0x92, 0x8e, 0xf9, 0xca, 0xce, 0x67, 0x45, 0x12}, + {0xb4, 0x73, 0xc4, 0xa, 0x86, 0xab, 0xf9, 0x3f, 0x35, 0xe4, 0x13, + 0x1, 0xee, 0x1d, 0x91, 0xf0, 0xaf, 0xc4, 0xc6, 0xeb, 0x60, 0x50, + 0xe7, 0x4a, 0xd, 0x0, 0x87, 0x6c, 0x96, 0x12, 0x86, 0x3f}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 278151578291475, 1810282338562947, 1771599529530998, - 1383659409671631, 685373414471841 -#else - 33852691, 4144781, 62632835, 26975308, 10770038, 26398890, - 60458447, 20618131, 48789665, 10212859 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 577009397403102, 1791440261786291, 2177643735971638, - 174546149911960, 1412505077782326 -#else - 2756062, 8598110, 7383731, 26694540, 22312758, 32449420, - 21179800, 2600940, 57120566, 21047965 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 893719721537457, 1201282458018197, 1522349501711173, - 58011597740583, 1130406465887139 -#else - 42463153, 13317461, 36659605, 17900503, 21365573, 22684775, - 11344423, 864440, 64609187, 16844368 -#endif - }}, + {0x13, 0x8d, 0x4, 0x36, 0xfa, 0xfc, 0x18, 0x9c, 0xdd, 0x9d, 0x89, + 0x73, 0xb3, 0x9d, 0x15, 0x29, 0xaa, 0xd0, 0x92, 0x9f, 0xb, 0x35, + 0x9f, 0xdc, 0xd4, 0x19, 0x8a, 0x87, 0xee, 0x7e, 0xf5, 0x26}, + {0xde, 0xd, 0x2a, 0x78, 0xc9, 0xc, 0x9a, 0x55, 0x85, 0x83, 0x71, + 0xea, 0xb2, 0xcd, 0x1d, 0x55, 0x8c, 0x23, 0xef, 0x31, 0x5b, 0x86, + 0x62, 0x7f, 0x3d, 0x61, 0x73, 0x79, 0x76, 0xa7, 0x4a, 0x50}, + {0xb1, 0xef, 0x87, 0x56, 0xd5, 0x2c, 0xab, 0xc, 0x7b, 0xf1, 0x7a, + 0x24, 0x62, 0xd1, 0x80, 0x51, 0x67, 0x24, 0x5a, 0x4f, 0x34, 0x5a, + 0xc1, 0x85, 0x69, 0x30, 0xba, 0x9d, 0x3d, 0x94, 0x41, 0x40}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 412607348255453, 1280455764199780, 2233277987330768, - 14180080401665, 331584698417165 -#else - 40676061, 6148328, 49924452, 19080277, 18782928, 33278435, - 44547329, 211299, 2719757, 4940997 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 262483770854550, 990511055108216, 526885552771698, - 571664396646158, 354086190278723 -#else - 65784982, 3911312, 60160120, 14759764, 37081714, 7851206, - 21690126, 8518463, 26699843, 5276295 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1820352417585487, 24495617171480, 1547899057533253, - 10041836186225, 480457105094042 -#else - 53958991, 27125364, 9396248, 365013, 24703301, 23065493, - 1321585, 149635, 51656090, 7159368 -#endif - }}, + {0xdd, 0xaa, 0x6c, 0xa2, 0x43, 0x77, 0x21, 0x4b, 0xce, 0xb7, 0x8a, + 0x64, 0x24, 0xb4, 0xa6, 0x47, 0xe3, 0xc9, 0xfb, 0x3, 0x7a, 0x4f, + 0x1d, 0xcb, 0x19, 0xd0, 0x0, 0x98, 0x42, 0x31, 0xd9, 0x12}, + {0x96, 0xcc, 0xeb, 0x43, 0xba, 0xee, 0xc0, 0xc3, 0xaf, 0x9c, 0xea, + 0x26, 0x9c, 0x9c, 0x74, 0x8d, 0xc6, 0xcc, 0x77, 0x1c, 0xee, 0x95, + 0xfa, 0xd9, 0xf, 0x34, 0x84, 0x76, 0xd9, 0xa1, 0x20, 0x14}, + {0x4f, 0x59, 0x37, 0xd3, 0x99, 0x77, 0xc6, 0x0, 0x7b, 0xa4, 0x3a, + 0xb2, 0x40, 0x51, 0x3c, 0x5e, 0x95, 0xf3, 0x5f, 0xe3, 0x54, 0x28, + 0x18, 0x44, 0x12, 0xa0, 0x59, 0x43, 0x31, 0x92, 0x4f, 0x1b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2023310314989233, 637905337525881, 2106474638900687, - 557820711084072, 1687858215057826 -#else - 9987761, 30149673, 17507961, 9505530, 9731535, 31388918, - 22356008, 8312176, 22477218, 25151047 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1144168702609745, 604444390410187, 1544541121756138, - 1925315550126027, 626401428894002 -#else - 18155857, 17049442, 19744715, 9006923, 15154154, 23015456, - 24256459, 28689437, 44560690, 9334108 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1922168257351784, 2018674099908659, 1776454117494445, - 956539191509034, 36031129147635 -#else - 2986088, 28642539, 10776627, 30080588, 10620589, 26471229, - 45695018, 14253544, 44521715, 536905 -#endif - }}, + {0xb1, 0x66, 0x98, 0xa4, 0x30, 0x30, 0xcf, 0x33, 0x59, 0x48, 0x5f, + 0x21, 0xd2, 0x73, 0x1f, 0x25, 0xf6, 0xf4, 0xde, 0x51, 0x40, 0xaa, + 0x82, 0xab, 0xf6, 0x23, 0x9a, 0x6f, 0xd5, 0x91, 0xf1, 0x5f}, + {0x51, 0x9, 0x15, 0x89, 0x9d, 0x10, 0x5c, 0x3e, 0x6a, 0x69, 0xe9, + 0x2d, 0x91, 0xfa, 0xce, 0x39, 0x20, 0x30, 0x5f, 0x97, 0x3f, 0xe4, + 0xea, 0x20, 0xae, 0x2d, 0x13, 0x7f, 0x2a, 0x57, 0x9b, 0x23}, + {0x68, 0x90, 0x2d, 0xac, 0x33, 0xd4, 0x9e, 0x81, 0x23, 0x85, 0xc9, + 0x5f, 0x79, 0xab, 0x83, 0x28, 0x3d, 0xeb, 0x93, 0x55, 0x80, 0x72, + 0x45, 0xef, 0xcb, 0x36, 0x8f, 0x75, 0x6a, 0x52, 0xc, 0x2}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 544644538748041, 1039872944430374, 876750409130610, - 710657711326551, 1216952687484972 -#else - 4377737, 8115836, 24567078, 15495314, 11625074, 13064599, - 7390551, 10589625, 10838060, 18134008 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 58242421545916, 2035812695641843, 2118491866122923, - 1191684463816273, 46921517454099 -#else - 47766460, 867879, 9277171, 30335973, 52677291, 31567988, - 19295825, 17757482, 6378259, 699185 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 272268252444639, 1374166457774292, 2230115177009552, - 1053149803909880, 1354288411641016 -#else - 7895007, 4057113, 60027092, 20476675, 49222032, 33231305, - 66392824, 15693154, 62063800, 20180469 -#endif - }}, + {0x89, 0xcc, 0x42, 0xf0, 0x59, 0xef, 0x31, 0xe9, 0xb6, 0x4b, 0x12, + 0x8e, 0x9d, 0x9c, 0x58, 0x2c, 0x97, 0x59, 0xc7, 0xae, 0x8a, 0xe1, + 0xc8, 0xad, 0xc, 0xc5, 0x2, 0x56, 0xa, 0xfe, 0x2c, 0x45}, + {0xbc, 0xdb, 0xd8, 0x9e, 0xf8, 0x34, 0x98, 0x77, 0x6c, 0xa4, 0x7c, + 0xdc, 0xf9, 0xaa, 0xf2, 0xc8, 0x74, 0xb0, 0xe1, 0xa3, 0xdc, 0x4c, + 0x52, 0xa9, 0x77, 0x38, 0x31, 0x15, 0x46, 0xcc, 0xaa, 0x2}, + {0xdf, 0x77, 0x78, 0x64, 0xa0, 0xf7, 0xa0, 0x86, 0x9f, 0x7c, 0x60, + 0xe, 0x27, 0x64, 0xc4, 0xbb, 0xc9, 0x11, 0xfb, 0xf1, 0x25, 0xea, + 0x17, 0xab, 0x7b, 0x87, 0x4b, 0x30, 0x7b, 0x7d, 0xfb, 0x4c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1857910905368338, 1754729879288912, 885945464109877, - 1516096106802166, 1602902393369811 -#else - 59371282, 27685029, 52542544, 26147512, 11385653, 13201616, - 31730678, 22591592, 63190227, 23885106 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1193437069800958, 901107149704790, 999672920611411, - 477584824802207, 364239578697845 -#else - 10188286, 17783598, 59772502, 13427542, 22223443, 14896287, - 30743455, 7116568, 45322357, 5427592 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 886299989548838, 1538292895758047, 1590564179491896, - 1944527126709657, 837344427345298 -#else - 696102, 13206899, 27047647, 22922350, 15285304, 23701253, - 10798489, 28975712, 19236242, 12477404 -#endif - }}, + {0x12, 0xef, 0x89, 0x97, 0xc2, 0x99, 0x86, 0xe2, 0xd, 0x19, 0x57, + 0xdf, 0x71, 0xcd, 0x6e, 0x2b, 0xd0, 0x70, 0xc9, 0xec, 0x57, 0xc8, + 0x43, 0xc3, 0xc5, 0x3a, 0x4d, 0x43, 0xbc, 0x4c, 0x1d, 0x5b}, + {0xfe, 0x75, 0x9b, 0xb8, 0x6c, 0x3d, 0xb4, 0x72, 0x80, 0xdc, 0x6a, + 0x9c, 0xd9, 0x94, 0xc6, 0x54, 0x9f, 0x4c, 0xe3, 0x3e, 0x37, 0xaa, + 0xc3, 0xb8, 0x64, 0x53, 0x7, 0x39, 0x2b, 0x62, 0xb4, 0x14}, + {0x26, 0x9f, 0xa, 0xcc, 0x15, 0x26, 0xfb, 0xb6, 0xe5, 0xcc, 0x8d, + 0xb8, 0x2b, 0xe, 0x4f, 0x3a, 0x5, 0xa7, 0x69, 0x33, 0x8b, 0x49, + 0x1, 0x13, 0xd1, 0x2d, 0x59, 0x58, 0x12, 0xf7, 0x98, 0x2f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 754558365378305, 1712186480903618, 1703656826337531, - 750310918489786, 518996040250900 -#else - 55879425, 11243795, 50054594, 25513566, 66320635, 25386464, - 63211194, 11180503, 43939348, 7733643 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1309847803895382, 1462151862813074, 211370866671570, - 1544595152703681, 1027691798954090 -#else - 17800790, 19518253, 40108434, 21787760, 23887826, 3149671, - 23466177, 23016261, 10322026, 15313801 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 803217563745370, 1884799722343599, 1357706345069218, - 2244955901722095, 730869460037413 -#else - 26246234, 11968874, 32263343, 28085704, 6830754, 20231401, - 51314159, 33452449, 42659621, 10890803 -#endif - }}, + {0x1, 0xa7, 0x54, 0x4f, 0x44, 0xae, 0x12, 0x2e, 0xde, 0xd7, 0xcb, + 0xa9, 0xf0, 0x3e, 0xfe, 0xfc, 0xe0, 0x5d, 0x83, 0x75, 0xd, 0x89, + 0xbf, 0xce, 0x54, 0x45, 0x61, 0xe7, 0xe9, 0x62, 0x80, 0x1d}, + {0x56, 0x9e, 0xf, 0xb5, 0x4c, 0xa7, 0x94, 0xc, 0x20, 0x13, 0x8e, + 0x8e, 0xa9, 0xf4, 0x1f, 0x5b, 0x67, 0xf, 0x30, 0x82, 0x21, 0xcc, + 0x2a, 0x9a, 0xf9, 0xaa, 0x6, 0xd8, 0x49, 0xe2, 0x6a, 0x3a}, + {0x5a, 0x7c, 0x90, 0xa9, 0x85, 0xda, 0x7a, 0x65, 0x62, 0xf, 0xb9, + 0x91, 0xb5, 0xa8, 0xe, 0x1a, 0xe9, 0xb4, 0x34, 0xdf, 0xfb, 0x1d, + 0xe, 0x8d, 0xf3, 0x5f, 0xf2, 0xae, 0xe8, 0x8c, 0x8b, 0x29}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 689299471295966, 1831210565161071, 1375187341585438, - 1106284977546171, 1893781834054269 -#else - 35743198, 10271362, 54448239, 27287163, 16690206, 20491888, - 52126651, 16484930, 25180797, 28219548 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 696351368613042, 1494385251239250, 738037133616932, - 636385507851544, 927483222611406 -#else - 66522290, 10376443, 34522450, 22268075, 19801892, 10997610, - 2276632, 9482883, 316878, 13820577 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1949114198209333, 1104419699537997, 783495707664463, - 1747473107602770, 2002634765788641 -#else - 57226037, 29044064, 64993357, 16457135, 56008783, 11674995, - 30756178, 26039378, 30696929, 29841583 -#endif - }}, + {0xde, 0x65, 0x21, 0xa, 0xea, 0x72, 0x7a, 0x83, 0xf6, 0x79, 0xcf, + 0xb, 0xb4, 0x7, 0xab, 0x3f, 0x70, 0xae, 0x38, 0x77, 0xc7, 0x36, + 0x16, 0x52, 0xdc, 0xd7, 0xa7, 0x3, 0x18, 0x27, 0xa6, 0x6b}, + {0xb2, 0xc, 0xf7, 0xef, 0x53, 0x79, 0x92, 0x2a, 0x76, 0x70, 0x15, + 0x79, 0x2a, 0xc9, 0x89, 0x4b, 0x6a, 0xcf, 0xa7, 0x30, 0x7a, 0x45, + 0x18, 0x94, 0x85, 0xe4, 0x5c, 0x4d, 0x40, 0xa8, 0xb8, 0x34}, + {0x35, 0x33, 0x69, 0x83, 0xb5, 0xec, 0x6e, 0xc2, 0xfd, 0xfe, 0xb5, + 0x63, 0xdf, 0x13, 0xa8, 0xd5, 0x73, 0x25, 0xb2, 0xa4, 0x9a, 0xaa, + 0x93, 0xa2, 0x6a, 0x1c, 0x5e, 0x46, 0xdd, 0x2b, 0xd6, 0x71}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1607325776830197, 530883941415333, 1451089452727895, - 1581691157083423, 496100432831154 -#else - 32988917, 23951020, 12499365, 7910787, 56491607, 21622917, - 59766047, 23569034, 34759346, 7392472 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1068900648804224, 2006891997072550, 1134049269345549, - 1638760646180091, 2055396084625778 -#else - 58253184, 15927860, 9866406, 29905021, 64711949, 16898650, - 36699387, 24419436, 25112946, 30627788 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2222475519314561, 1870703901472013, 1884051508440561, - 1344072275216753, 1318025677799069 -#else - 64604801, 33117465, 25621773, 27875660, 15085041, 28074555, - 42223985, 20028237, 5537437, 19640113 -#endif - }}, + {0xf5, 0x5e, 0xf7, 0xb1, 0xda, 0xb5, 0x2d, 0xcd, 0xf5, 0x65, 0xb0, + 0x16, 0xcf, 0x95, 0x7f, 0xd7, 0x85, 0xf0, 0x49, 0x3f, 0xea, 0x1f, + 0x57, 0x14, 0x3d, 0x2b, 0x2b, 0x26, 0x21, 0x36, 0x33, 0x1c}, + {0x80, 0xdf, 0x78, 0xd3, 0x28, 0xcc, 0x33, 0x65, 0xb4, 0xa4, 0xf, + 0xa, 0x79, 0x43, 0xdb, 0xf6, 0x5a, 0xda, 0x1, 0xf7, 0xf9, 0x5f, + 0x64, 0xe3, 0xa4, 0x2b, 0x17, 0xf3, 0x17, 0xf3, 0xd5, 0x74}, + {0x81, 0xca, 0xd9, 0x67, 0x54, 0xe5, 0x6f, 0xa8, 0x37, 0x8c, 0x29, + 0x2b, 0x75, 0x7c, 0x8b, 0x39, 0x3b, 0x62, 0xac, 0xe3, 0x92, 0x8, + 0x6d, 0xda, 0x8c, 0xd9, 0xe9, 0x47, 0x45, 0xcc, 0xeb, 0x4a}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 155711679280656, 681100400509288, 389811735211209, - 2135723811340709, 408733211204125 -#else - 55883280, 2320284, 57524584, 10149186, 33664201, 5808647, - 52232613, 31824764, 31234589, 6090599 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 7813206966729, 194444201427550, 2071405409526507, - 1065605076176312, 1645486789731291 -#else - 57475529, 116425, 26083934, 2897444, 60744427, 30866345, 609720, - 15878753, 60138459, 24519663 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 16625790644959, 1647648827778410, 1579910185572704, - 436452271048548, 121070048451050 -#else - 39351007, 247743, 51914090, 24551880, 23288160, 23542496, - 43239268, 6503645, 20650474, 1804084 -#endif - }}, + {0x10, 0xb6, 0x54, 0x73, 0x9e, 0x8d, 0x40, 0xb, 0x6e, 0x5b, 0xa8, + 0x5b, 0x53, 0x32, 0x6b, 0x80, 0x7, 0xa2, 0x58, 0x4a, 0x3, 0x3a, + 0xe6, 0xdb, 0x2c, 0xdf, 0xa1, 0xc9, 0xdd, 0xd9, 0x3b, 0x17}, + {0xc9, 0x1, 0x6d, 0x27, 0x1b, 0x7, 0xf0, 0x12, 0x70, 0x8c, 0xc4, + 0x86, 0xc5, 0xba, 0xb8, 0xe7, 0xa9, 0xfb, 0xd6, 0x71, 0x9b, 0x12, + 0x8, 0x53, 0x92, 0xb7, 0x3d, 0x5a, 0xf9, 0xfb, 0x88, 0x5d}, + {0xdf, 0x72, 0x58, 0xfe, 0x1e, 0xf, 0x50, 0x2b, 0xc1, 0x18, 0x39, + 0xd4, 0x2e, 0x58, 0xd6, 0x58, 0xe0, 0x3a, 0x67, 0xc9, 0x8e, 0x27, + 0xed, 0xe6, 0x19, 0xa3, 0x9e, 0xb1, 0x13, 0xcd, 0xe1, 0x6}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1037263028552531, 568385780377829, 297953104144430, - 1558584511931211, 2238221839292471 -#else - 39519059, 15456423, 8972517, 8469608, 15640622, 4439847, - 3121995, 23224719, 27842615, 33352104 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 190565267697443, 672855706028058, 338796554369226, - 337687268493904, 853246848691734 -#else - 51801891, 2839643, 22530074, 10026331, 4602058, 5048462, - 28248656, 5031932, 55733782, 12714368 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1763863028400139, 766498079432444, 1321118624818005, - 69494294452268, 858786744165651 -#else - 20807691, 26283607, 29286140, 11421711, 39232341, 19686201, - 45881388, 1035545, 47375635, 12796919 -#endif - }}, + {0x53, 0x3, 0x5b, 0x9e, 0x62, 0xaf, 0x2b, 0x47, 0x47, 0x4, 0x8d, + 0x27, 0x90, 0xb, 0xaa, 0x3b, 0x27, 0xbf, 0x43, 0x96, 0x46, 0x5f, + 0x78, 0xc, 0x13, 0x7b, 0x83, 0x8d, 0x1a, 0x6a, 0x3a, 0x7f}, + {0x23, 0x6f, 0x16, 0x6f, 0x51, 0xad, 0xd0, 0x40, 0xbe, 0x6a, 0xab, + 0x1f, 0x93, 0x32, 0x8e, 0x11, 0x8e, 0x8, 0x4d, 0xa0, 0x14, 0x5e, + 0xe3, 0x3f, 0x66, 0x62, 0xe1, 0x26, 0x35, 0x60, 0x80, 0x30}, + {0xb, 0x80, 0x3d, 0x5d, 0x39, 0x44, 0xe6, 0xf7, 0xf6, 0xed, 0x1, + 0xc9, 0x55, 0xd5, 0xa8, 0x95, 0x39, 0x63, 0x2c, 0x59, 0x30, 0x78, + 0xcd, 0x68, 0x7e, 0x30, 0x51, 0x2e, 0xed, 0xfd, 0xd0, 0x30}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1292056768563024, 1456632109855638, 1100631247050184, - 1386133165675321, 1232898350193752 -#else - 12076880, 19253146, 58323862, 21705509, 42096072, 16400683, - 49517369, 20654993, 3480664, 18371617 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 366253102478259, 525676242508811, 1449610995265438, - 1183300845322183, 185960306491545 -#else - 34747315, 5457596, 28548107, 7833186, 7303070, 21600887, - 42745799, 17632556, 33734809, 2771024 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 28315355815982, 460422265558930, 1799675876678724, - 1969256312504498, 1051823843138725 -#else - 45719598, 421931, 26597266, 6860826, 22486084, 26817260, - 49971378, 29344205, 42556581, 15673396 -#endif - }}, + {0x50, 0x47, 0xb8, 0x68, 0x1e, 0x97, 0xb4, 0x9c, 0xcf, 0xbb, 0x64, + 0x66, 0x29, 0x72, 0x95, 0xa0, 0x2b, 0x41, 0xfa, 0x72, 0x26, 0xe7, + 0x8d, 0x5c, 0xd9, 0x89, 0xc5, 0x51, 0x43, 0x8, 0x15, 0x46}, + {0xb3, 0x33, 0x12, 0xf2, 0x1a, 0x4d, 0x59, 0xe0, 0x9c, 0x4d, 0xcc, + 0xf0, 0x8e, 0xe7, 0xdb, 0x1b, 0x77, 0x9a, 0x49, 0x8f, 0x7f, 0x18, + 0x65, 0x69, 0x68, 0x98, 0x9, 0x2c, 0x20, 0x14, 0x92, 0xa}, + {0x2e, 0xa0, 0xb9, 0xae, 0xc0, 0x19, 0x90, 0xbc, 0xae, 0x4c, 0x3, + 0x16, 0xd, 0x11, 0xc7, 0x55, 0xec, 0x32, 0x99, 0x65, 0x1, 0xf5, + 0x6d, 0xe, 0xfe, 0x5d, 0xca, 0x95, 0x28, 0xd, 0xca, 0x3b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 156914999361983, 1606148405719949, 1665208410108430, - 317643278692271, 1383783705665320 -#else - 46924223, 2338215, 19788685, 23933476, 63107598, 24813538, - 46837679, 4733253, 3727144, 20619984 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 54684536365732, 2210010038536222, 1194984798155308, - 535239027773705, 1516355079301361 -#else - 6120100, 814863, 55314462, 32931715, 6812204, 17806661, 2019593, - 7975683, 31123697, 22595451 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1484387703771650, 198537510937949, 2186282186359116, - 617687444857508, 647477376402122 -#else - 30069250, 22119100, 30434653, 2958439, 18399564, 32578143, - 12296868, 9204260, 50676426, 9648164 -#endif - }}, + {0xbf, 0x1, 0xcc, 0x9e, 0xb6, 0x8e, 0x68, 0x9c, 0x6f, 0x89, 0x44, + 0xa6, 0xad, 0x83, 0xbc, 0xf0, 0xe2, 0x9f, 0x7a, 0x5f, 0x5f, 0x95, + 0x2d, 0xca, 0x41, 0x82, 0xf2, 0x8d, 0x3, 0xb4, 0xa8, 0x4e}, + {0xa4, 0x62, 0x5d, 0x3c, 0xbc, 0x31, 0xf0, 0x40, 0x60, 0x7a, 0xf0, + 0xcf, 0x3e, 0x8b, 0xfc, 0x19, 0x45, 0xb5, 0xf, 0x13, 0xa2, 0x3d, + 0x18, 0x98, 0xcd, 0x13, 0x8f, 0xae, 0xdd, 0xde, 0x31, 0x56}, + {0x2, 0xd2, 0xca, 0xf1, 0xa, 0x46, 0xed, 0x2a, 0x83, 0xee, 0x8c, + 0xa4, 0x5, 0x53, 0x30, 0x46, 0x5f, 0x1a, 0xf1, 0x49, 0x45, 0x77, + 0x21, 0x91, 0x63, 0xa4, 0x2c, 0x54, 0x30, 0x9, 0xce, 0x24}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2147715541830533, 500032538445817, 646380016884826, - 352227855331122, 1488268620408052 -#else - 32705413, 32003455, 30705657, 7451065, 55303258, 9631812, - 3305266, 5248604, 41100532, 22176930 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 159386186465542, 1877626593362941, 618737197060512, - 1026674284330807, 1158121760792685 -#else - 17219846, 2375039, 35537917, 27978816, 47649184, 9219902, - 294711, 15298639, 2662509, 17257359 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1744544377739822, 1964054180355661, 1685781755873170, - 2169740670377448, 1286112621104591 -#else - 65935918, 25995736, 62742093, 29266687, 45762450, 25120105, - 32087528, 32331655, 32247247, 19164571 -#endif - }}, + {0x85, 0xb, 0xf3, 0xfd, 0x55, 0xa1, 0xcf, 0x3f, 0xa4, 0x2e, 0x37, + 0x36, 0x8e, 0x16, 0xf7, 0xd2, 0x44, 0xf8, 0x92, 0x64, 0xde, 0x64, + 0xe0, 0xb2, 0x80, 0x42, 0x4f, 0x32, 0xa7, 0x28, 0x99, 0x54}, + {0x6, 0xc1, 0x6, 0xfd, 0xf5, 0x90, 0xe8, 0x1f, 0xf2, 0x10, 0x88, + 0x5d, 0x35, 0x68, 0xc4, 0xb5, 0x3e, 0xaf, 0x8c, 0x6e, 0xfe, 0x8, + 0x78, 0x82, 0x4b, 0xd7, 0x6, 0x8a, 0xc2, 0xe3, 0xd4, 0x41}, + {0x2e, 0x1a, 0xee, 0x63, 0xa7, 0x32, 0x6e, 0xf2, 0xea, 0xfd, 0x5f, + 0xd2, 0xb7, 0xe4, 0x91, 0xae, 0x69, 0x4d, 0x7f, 0xd1, 0x3b, 0xd3, + 0x3b, 0xbc, 0x6a, 0xff, 0xdc, 0xc0, 0xde, 0x66, 0x1b, 0x49}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 81977249784993, 1667943117713086, 1668983819634866, - 1605016835177615, 1353960708075544 -#else - 14312609, 1221556, 17395390, 24854289, 62163122, 24869796, - 38911119, 23916614, 51081240, 20175586 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1602253788689063, 439542044889886, 2220348297664483, - 657877410752869, 157451572512238 -#else - 65680039, 23875441, 57873182, 6549686, 59725795, 33085767, - 23046501, 9803137, 17597934, 2346211 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1029287186166717, 65860128430192, 525298368814832, - 1491902500801986, 1461064796385400 -#else - 18510781, 15337574, 26171504, 981392, 44867312, 7827555, - 43617730, 22231079, 3059832, 21771562 -#endif - }}, + {0xa1, 0x64, 0xda, 0xd0, 0x8e, 0x4a, 0xf0, 0x75, 0x4b, 0x28, 0xe2, + 0x67, 0xaf, 0x2c, 0x22, 0xed, 0xa4, 0x7b, 0x7b, 0x1f, 0x79, 0xa3, + 0x34, 0x82, 0x67, 0x8b, 0x1, 0xb7, 0xb0, 0xb8, 0xf6, 0x4c}, + {0xa7, 0x32, 0xea, 0xc7, 0x3d, 0xb1, 0xf5, 0x98, 0x98, 0xdb, 0x16, + 0x7e, 0xcc, 0xf8, 0xd5, 0xe3, 0x47, 0xd9, 0xf8, 0xcb, 0x52, 0xbf, + 0xa, 0xac, 0xac, 0xe4, 0x5e, 0xc8, 0xd0, 0x38, 0xf3, 0x8}, + {0xbd, 0x73, 0x1a, 0x99, 0x21, 0xa8, 0x83, 0xc3, 0x7a, 0xc, 0x32, + 0xdf, 0x1, 0xbc, 0x27, 0xab, 0x63, 0x70, 0x77, 0x84, 0x1b, 0x33, + 0x3d, 0xc1, 0x99, 0x8a, 0x7, 0xeb, 0x82, 0x4a, 0xd, 0x53}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 408216988729246, 2121095722306989, 913562102267595, - 1879708920318308, 241061448436731 -#else - 10141598, 6082907, 17829293, 31606789, 9830091, 13613136, - 41552228, 28009845, 33606651, 3592095 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1185483484383269, 1356339572588553, 584932367316448, - 102132779946470, 1792922621116791 -#else - 33114149, 17665080, 40583177, 20211034, 33076704, 8716171, - 1151462, 1521897, 66126199, 26716628 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1966196870701923, 2230044620318636, 1425982460745905, - 261167817826569, 46517743394330 -#else - 34169699, 29298616, 23947180, 33230254, 34035889, 21248794, - 50471177, 3891703, 26353178, 693168 -#endif - }}, + {0x9e, 0xbf, 0x9a, 0x6c, 0x45, 0x73, 0x69, 0x6d, 0x80, 0xa8, 0x0, + 0x49, 0xfc, 0xb2, 0x7f, 0x25, 0x50, 0xb8, 0xcf, 0xc8, 0x12, 0xf4, + 0xac, 0x2b, 0x5b, 0xbd, 0xbf, 0xc, 0xe0, 0xe7, 0xb3, 0xd}, + {0x25, 0x48, 0xf9, 0xe1, 0x30, 0x36, 0x4c, 0x0, 0x5a, 0x53, 0xab, + 0x8c, 0x26, 0x78, 0x2d, 0x7e, 0x8b, 0xff, 0x84, 0xcc, 0x23, 0x23, + 0x48, 0xc7, 0xb9, 0x70, 0x17, 0x10, 0x3f, 0x75, 0xea, 0x65}, + {0x63, 0x63, 0x9, 0xe2, 0x3e, 0xfc, 0x66, 0x3d, 0x6b, 0xcb, 0xb5, + 0x61, 0x7f, 0x2c, 0xd6, 0x81, 0x1a, 0x3b, 0x44, 0x13, 0x42, 0x4, + 0xbe, 0xf, 0xdb, 0xa1, 0xe1, 0x21, 0x19, 0xec, 0xa4, 0x2}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 107077591595359, 884959942172345, 27306869797400, - 2224911448949390, 964352058245223 -#else - 30374239, 1595580, 50224825, 13186930, 4600344, 406904, 9585294, - 33153764, 31375463, 14369965 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1730194207717538, 431790042319772, 1831515233279467, - 1372080552768581, 1074513929381760 -#else - 52738210, 25781902, 1510300, 6434173, 48324075, 27291703, - 32732229, 20445593, 17901440, 16011505 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1450880638731607, 1019861580989005, 1229729455116861, - 1174945729836143, 826083146840706 -#else - 18171223, 21619806, 54608461, 15197121, 56070717, 18324396, - 47936623, 17508055, 8764034, 12309598 -#endif - }}, + {0x5f, 0x79, 0xcf, 0xf1, 0x62, 0x61, 0xc8, 0xf5, 0xf2, 0x57, 0xee, + 0x26, 0x19, 0x86, 0x8c, 0x11, 0x78, 0x35, 0x6, 0x1c, 0x85, 0x24, + 0x21, 0x17, 0xcf, 0x7f, 0x6, 0xec, 0x5d, 0x2b, 0xd1, 0x36}, + {0xa2, 0xb8, 0x24, 0x3b, 0x9a, 0x25, 0xe6, 0x5c, 0xb8, 0xa0, 0xaf, + 0x45, 0xcc, 0x7a, 0x57, 0xb8, 0x37, 0x70, 0xa0, 0x8b, 0xe8, 0xe6, + 0xcb, 0xcc, 0xbf, 0x9, 0x78, 0x12, 0x51, 0x3c, 0x14, 0x3d}, + {0x57, 0x45, 0x15, 0x79, 0x91, 0x27, 0x6d, 0x12, 0xa, 0x3a, 0x78, + 0xfc, 0x5c, 0x8f, 0xe4, 0xd5, 0xac, 0x9b, 0x17, 0xdf, 0xe8, 0xb6, + 0xbd, 0x36, 0x59, 0x28, 0xa8, 0x5b, 0x88, 0x17, 0xf5, 0x2e}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1899935429242705, 1602068751520477, 940583196550370, - 82431069053859, 1540863155745696 -#else - 5975889, 28311244, 47649501, 23872684, 55567586, 14015781, - 43443107, 1228318, 17544096, 22960650 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2136688454840028, 2099509000964294, 1690800495246475, - 1217643678575476, 828720645084218 -#else - 5811932, 31839139, 3442886, 31285122, 48741515, 25194890, - 49064820, 18144304, 61543482, 12348899 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 765548025667841, 462473984016099, 998061409979798, - 546353034089527, 2212508972466858 -#else - 35709185, 11407554, 25755363, 6891399, 63851926, 14872273, - 42259511, 8141294, 56476330, 32968952 -#endif - }}, + {0x51, 0x2f, 0x5b, 0x30, 0xfb, 0xbf, 0xee, 0x96, 0xb8, 0x96, 0x95, + 0x88, 0xad, 0x38, 0xf9, 0xd3, 0x25, 0xdd, 0xd5, 0x46, 0xc7, 0x2d, + 0xf5, 0xf0, 0x95, 0x0, 0x3a, 0xbb, 0x90, 0x82, 0x96, 0x57}, + {0xdc, 0xae, 0x58, 0x8c, 0x4e, 0x97, 0x37, 0x46, 0xa4, 0x41, 0xf0, + 0xab, 0xfb, 0x22, 0xef, 0xb9, 0x8a, 0x71, 0x80, 0xe9, 0x56, 0xd9, + 0x85, 0xe1, 0xa6, 0xa8, 0x43, 0xb1, 0xfa, 0x78, 0x1b, 0x2f}, + {0x1, 0xe1, 0x20, 0xa, 0x43, 0xb8, 0x1a, 0xf7, 0x47, 0xec, 0xf0, + 0x24, 0x8d, 0x65, 0x93, 0xf3, 0xd1, 0xee, 0xe2, 0x6e, 0xa8, 0x9, + 0x75, 0xcf, 0xe1, 0xa3, 0x2a, 0xdc, 0x35, 0x3e, 0xc4, 0x7d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 46575283771160, 892570971573071, 1281983193144090, - 1491520128287375, 75847005908304 -#else - 54433560, 694025, 62032719, 13300343, 14015258, 19103038, - 57410191, 22225381, 30944592, 1130208 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1801436127943107, 1734436817907890, 1268728090345068, - 167003097070711, 2233597765834956 -#else - 8247747, 26843490, 40546482, 25845122, 52706924, 18905521, - 4652151, 2488540, 23550156, 33283200 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1997562060465113, 1048700225534011, 7615603985628, - 1855310849546841, 2242557647635213 -#else - 17294297, 29765994, 7026747, 15626851, 22990044, 113481, - 2267737, 27646286, 66700045, 33416712 -#endif - }}, + {0x18, 0x97, 0x3e, 0x27, 0x5c, 0x2a, 0x78, 0x5a, 0x94, 0xfd, 0x4e, + 0x5e, 0x99, 0xc6, 0x76, 0x35, 0x3e, 0x7d, 0x23, 0x1f, 0x5, 0xd8, + 0x2e, 0xf, 0x99, 0xa, 0xd5, 0x82, 0x1d, 0xb8, 0x4f, 0x4}, + {0xc3, 0xd9, 0x7d, 0x88, 0x65, 0x66, 0x96, 0x85, 0x55, 0x53, 0xb0, + 0x4b, 0x31, 0x9b, 0xf, 0xc9, 0xb1, 0x79, 0x20, 0xef, 0xf8, 0x8d, + 0xe0, 0xc6, 0x2f, 0xc1, 0x8c, 0x75, 0x16, 0x20, 0xf7, 0x7e}, + {0xd9, 0xe3, 0x7, 0xa9, 0xc5, 0x18, 0xdf, 0xc1, 0x59, 0x63, 0x4c, + 0xce, 0x1d, 0x37, 0xb3, 0x57, 0x49, 0xbb, 0x1, 0xb2, 0x34, 0x45, + 0x70, 0xca, 0x2e, 0xdd, 0x30, 0x9c, 0x3f, 0x82, 0x79, 0x7f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1161017320376250, 492624580169043, 2169815802355237, - 976496781732542, 1770879511019629 -#else - 16091066, 17300506, 18599251, 7340678, 2137637, 32332775, - 63744702, 14550935, 3260525, 26388161 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1357044908364776, 729130645262438, 1762469072918979, - 1365633616878458, 181282906404941 -#else - 62198760, 20221544, 18550886, 10864893, 50649539, 26262835, - 44079994, 20349526, 54360141, 2701325 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1080413443139865, 1155205815510486, 1848782073549786, - 622566975152580, 124965574467971 -#else - 58534169, 16099414, 4629974, 17213908, 46322650, 27548999, - 57090500, 9276970, 11329923, 1862132 -#endif - }}, + {0xba, 0x87, 0xf5, 0x68, 0xf0, 0x1f, 0x9c, 0x6a, 0xde, 0xc8, 0x50, + 0x0, 0x4e, 0x89, 0x27, 0x8, 0xe7, 0x5b, 0xed, 0x7d, 0x55, 0x99, + 0xbf, 0x3c, 0xf0, 0xd6, 0x6, 0x1c, 0x43, 0xb0, 0xa9, 0x64}, + {0xe8, 0x13, 0xb5, 0xa3, 0x39, 0xd2, 0x34, 0x83, 0xd8, 0xa8, 0x1f, + 0xb9, 0xd4, 0x70, 0x36, 0xc1, 0x33, 0xbd, 0x90, 0xf5, 0x36, 0x41, + 0xb5, 0x12, 0xb4, 0xd9, 0x84, 0xd7, 0x73, 0x3, 0x4e, 0xa}, + {0x19, 0x29, 0x7d, 0x5b, 0xa1, 0xd6, 0xb3, 0x2e, 0x35, 0x82, 0x3a, + 0xd5, 0xa0, 0xf6, 0xb4, 0xb0, 0x47, 0x5d, 0xa4, 0x89, 0x43, 0xce, + 0x56, 0x71, 0x6c, 0x34, 0x18, 0xce, 0xa, 0x7d, 0x1a, 0x7}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1184526762066993, 247622751762817, 692129017206356, - 820018689412496, 2188697339828085 -#else - 14763057, 17650824, 36190593, 3689866, 3511892, 10313526, - 45157776, 12219230, 58070901, 32614131 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2020536369003019, 202261491735136, 1053169669150884, - 2056531979272544, 778165514694311 -#else - 8894987, 30108338, 6150752, 3013931, 301220, 15693451, 35127648, - 30644714, 51670695, 11595569 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 237404399610207, 1308324858405118, 1229680749538400, - 720131409105291, 1958958863624906 -#else - 15214943, 3537601, 40870142, 19495559, 4418656, 18323671, - 13947275, 10730794, 53619402, 29190761 -#endif - }}, + {0x31, 0x44, 0xe1, 0x20, 0x52, 0x35, 0xc, 0xcc, 0x41, 0x51, 0xb1, + 0x9, 0x7, 0x95, 0x65, 0xd, 0x36, 0x5f, 0x9d, 0x20, 0x1b, 0x62, + 0xf5, 0x9a, 0xd3, 0x55, 0x77, 0x61, 0xf7, 0xbc, 0x69, 0x7c}, + {0xb, 0xba, 0x87, 0xc8, 0xaa, 0x2d, 0x7, 0xd3, 0xee, 0x62, 0xa5, + 0xbf, 0x5, 0x29, 0x26, 0x1, 0x8b, 0x76, 0xef, 0xc0, 0x2, 0x30, + 0x54, 0xcf, 0x9c, 0x7e, 0xea, 0x46, 0x71, 0xcc, 0x3b, 0x2c}, + {0x5f, 0x29, 0xe8, 0x4, 0xeb, 0xd7, 0xf0, 0x7, 0x7d, 0xf3, 0x50, + 0x2f, 0x25, 0x18, 0xdb, 0x10, 0xd7, 0x98, 0x17, 0x17, 0xa3, 0xa9, + 0x51, 0xe9, 0x1d, 0xa5, 0xac, 0x22, 0x73, 0x9a, 0x5a, 0x6f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 515583508038846, 17656978857189, 1717918437373989, - 1568052070792483, 46975803123923 -#else - 64570558, 7682792, 32759013, 263109, 37124133, 25598979, - 44776739, 23365796, 977107, 699994 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 281527309158085, 36970532401524, 866906920877543, - 2222282602952734, 1289598729589882 -#else - 54642373, 4195083, 57897332, 550903, 51543527, 12917919, - 19118110, 33114591, 36574330, 19216518 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1278207464902042, 494742455008756, 1262082121427081, - 1577236621659884, 1888786707293291 -#else - 31788442, 19046775, 4799988, 7372237, 8808585, 18806489, - 9408236, 23502657, 12493931, 28145115 -#endif - }}, + {0xbe, 0x44, 0xd9, 0xa3, 0xeb, 0xd4, 0x29, 0xe7, 0x9e, 0xaf, 0x78, + 0x80, 0x40, 0x9, 0x9e, 0x8d, 0x3, 0x9c, 0x86, 0x47, 0x7a, 0x56, + 0x25, 0x45, 0x24, 0x3b, 0x8d, 0xee, 0x80, 0x96, 0xab, 0x2}, + {0xc5, 0xc6, 0x41, 0x2f, 0xc, 0x0, 0xa1, 0x8b, 0x9b, 0xfb, 0xfe, + 0xc, 0xc1, 0x79, 0x9f, 0xc4, 0x9f, 0x1c, 0xc5, 0x3c, 0x70, 0x47, + 0xfa, 0x4e, 0xca, 0xaf, 0x47, 0xe1, 0xa2, 0x21, 0x4e, 0x49}, + {0x9a, 0xd, 0xe5, 0xdd, 0x85, 0x8a, 0xa4, 0xef, 0x49, 0xa2, 0xb9, + 0xf, 0x4e, 0x22, 0x9a, 0x21, 0xd9, 0xf6, 0x1e, 0xd9, 0x1d, 0x1f, + 0x9, 0xfa, 0x34, 0xbb, 0x46, 0xea, 0xcb, 0x76, 0x5d, 0x6b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 353042527954210, 1830056151907359, 1111731275799225, - 174960955838824, 404312815582675 -#else - 41428258, 5260743, 47873055, 27269961, 63412921, 16566086, - 27218280, 2607121, 29375955, 6024730 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2064251142068628, 1666421603389706, 1419271365315441, - 468767774902855, 191535130366583 -#else - 842132, 30759739, 62345482, 24831616, 26332017, 21148791, - 11831879, 6985184, 57168503, 2854095 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1716987058588002, 1859366439773457, 1767194234188234, - 64476199777924, 1117233614485261 -#else - 62261602, 25585100, 2516241, 27706719, 9695690, 26333246, - 16512644, 960770, 12121869, 16648078 -#endif - }}, + {0x22, 0x25, 0x78, 0x1e, 0x17, 0x41, 0xf9, 0xe0, 0xd3, 0x36, 0x69, + 0x3, 0x74, 0xae, 0xe6, 0xf1, 0x46, 0xc7, 0xfc, 0xd0, 0xa2, 0x3e, + 0x8b, 0x40, 0x3e, 0x31, 0xdd, 0x3, 0x9c, 0x86, 0xfb, 0x16}, + {0x94, 0xd9, 0xc, 0xec, 0x6c, 0x55, 0x57, 0x88, 0xba, 0x1d, 0xd0, + 0x5c, 0x6f, 0xdc, 0x72, 0x64, 0x77, 0xb4, 0x42, 0x8f, 0x14, 0x69, + 0x1, 0xaf, 0x54, 0x73, 0x27, 0x85, 0xf6, 0x33, 0xe3, 0xa}, + {0x62, 0x9, 0xb6, 0x33, 0x97, 0x19, 0x8e, 0x28, 0x33, 0xe1, 0xab, + 0xd8, 0xb4, 0x72, 0xfc, 0x24, 0x3e, 0xd0, 0x91, 0x9, 0xed, 0xf7, + 0x11, 0x48, 0x75, 0xd0, 0x70, 0x8f, 0x8b, 0xe3, 0x81, 0x3f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 984292135520292, 135138246951259, 2220652137473167, - 1722843421165029, 190482558012909 -#else - 51890212, 14667095, 53772635, 2013716, 30598287, 33090295, - 35603941, 25672367, 20237805, 2838411 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 298845952651262, 1166086588952562, 1179896526238434, - 1347812759398693, 1412945390096208 -#else - 47820798, 4453151, 15298546, 17376044, 22115042, 17581828, - 12544293, 20083975, 1068880, 21054527 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1143239552672925, 906436640714209, 2177000572812152, - 2075299936108548, 325186347798433 -#else - 57549981, 17035596, 33238497, 13506958, 30505848, 32439836, - 58621956, 30924378, 12521377, 4845654 -#endif - }}, + {0x24, 0xc8, 0x17, 0x5f, 0x35, 0x7f, 0xdb, 0xa, 0xa4, 0x99, 0x42, + 0xd7, 0xc3, 0x23, 0xb9, 0x74, 0xf7, 0xea, 0xf8, 0xcb, 0x8b, 0x3e, + 0x7c, 0xd5, 0x3d, 0xdc, 0xde, 0x4c, 0xd3, 0xe2, 0xd3, 0xa}, + {0xfe, 0xaf, 0xd9, 0x7e, 0xcc, 0xf, 0x91, 0x7f, 0x4b, 0x87, 0x65, + 0x24, 0xa1, 0xb8, 0x5c, 0x54, 0x4, 0x47, 0xc, 0x4b, 0xd2, 0x7e, + 0x39, 0xa8, 0x93, 0x9, 0xf5, 0x4, 0xc1, 0xf, 0x51, 0x50}, + {0x9d, 0x24, 0x6e, 0x33, 0xc5, 0xf, 0xc, 0x6f, 0xd9, 0xcf, 0x31, + 0xc3, 0x19, 0xde, 0x5e, 0x74, 0x1c, 0xfe, 0xee, 0x9, 0x0, 0xfd, + 0xd6, 0xf2, 0xbe, 0x1e, 0xfa, 0xf0, 0x8b, 0x15, 0x7c, 0x12}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 721024854374772, 684487861263316, 1373438744094159, - 2193186935276995, 1387043709851261 -#else - 38910324, 10744107, 64150484, 10199663, 7759311, 20465832, - 3409347, 32681032, 60626557, 20668561 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 418098668140962, 715065997721283, 1471916138376055, - 2168570337288357, 937812682637044 -#else - 43547042, 6230155, 46726851, 10655313, 43068279, 21933259, - 10477733, 32314216, 63995636, 13974497 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1043584187226485, 2143395746619356, 2209558562919611, - 482427979307092, 847556718384018 -#else - 12966261, 15550616, 35069916, 31939085, 21025979, 32924988, - 5642324, 7188737, 18895762, 12629579 -#endif - }}, + {0x74, 0xb9, 0x51, 0xae, 0xc4, 0x8f, 0xa2, 0xde, 0x96, 0xfe, 0x4d, + 0x74, 0xd3, 0x73, 0x99, 0x1d, 0xa8, 0x48, 0x38, 0x87, 0xb, 0x68, + 0x40, 0x62, 0x95, 0xdf, 0x67, 0xd1, 0x79, 0x24, 0xd8, 0x4e}, + {0xa2, 0x79, 0x98, 0x2e, 0x42, 0x7c, 0x19, 0xf6, 0x47, 0x36, 0xca, + 0x52, 0xd4, 0xdd, 0x4a, 0xa4, 0xcb, 0xac, 0x4e, 0x4b, 0xc1, 0x3f, + 0x41, 0x9b, 0x68, 0x4f, 0xef, 0x7, 0x7d, 0xf8, 0x4e, 0x35}, + {0x75, 0xd9, 0xc5, 0x60, 0x22, 0xb5, 0xe3, 0xfe, 0xb8, 0xb0, 0x41, + 0xeb, 0xfc, 0x2e, 0x35, 0x50, 0x3c, 0x65, 0xf6, 0xa9, 0x30, 0xac, + 0x8, 0x88, 0x6d, 0x23, 0x39, 0x5, 0xd2, 0x92, 0x2d, 0x30}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1248731221520759, 1465200936117687, 540803492710140, - 52978634680892, 261434490176109 -#else - 14741879, 18607545, 22177207, 21833195, 1279740, 8058600, - 11758140, 789443, 32195181, 3895677 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1057329623869501, 620334067429122, 461700859268034, - 2012481616501857, 297268569108938 -#else - 10758205, 15755439, 62598914, 9243697, 62229442, 6879878, - 64904289, 29988312, 58126794, 4429646 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1055352180870759, 1553151421852298, 1510903185371259, - 1470458349428097, 1226259419062731 -#else - 64654951, 15725972, 46672522, 23143759, 61304955, 22514211, - 59972993, 21911536, 18047435, 18272689 -#endif - }}, + {0x77, 0xf1, 0xe0, 0xe4, 0xb6, 0x6f, 0xbc, 0x2d, 0x93, 0x6a, 0xbd, + 0xa4, 0x29, 0xbf, 0xe1, 0x4, 0xe8, 0xf6, 0x7a, 0x78, 0xd4, 0x66, + 0x19, 0x5e, 0x60, 0xd0, 0x26, 0xb4, 0x5e, 0x5f, 0xdc, 0xe}, + {0x3d, 0x28, 0xa4, 0xbc, 0xa2, 0xc1, 0x13, 0x78, 0xd9, 0x3d, 0x86, + 0xa1, 0x91, 0xf0, 0x62, 0xed, 0x86, 0xfa, 0x68, 0xc2, 0xb8, 0xbc, + 0xc7, 0xae, 0x4c, 0xae, 0x1c, 0x6f, 0xb7, 0xd3, 0xe5, 0x10}, + {0x67, 0x8e, 0xda, 0x53, 0xd6, 0xbf, 0x53, 0x54, 0x41, 0xf6, 0xa9, + 0x24, 0xec, 0x1e, 0xdc, 0xe9, 0x23, 0x8a, 0x57, 0x3, 0x3b, 0x26, + 0x87, 0xbf, 0x72, 0xba, 0x1c, 0x36, 0x51, 0x6c, 0xb4, 0x45}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1492988790301668, 790326625573331, 1190107028409745, - 1389394752159193, 1620408196604194 -#else - 41935844, 22247266, 29759955, 11776784, 44846481, 17733976, - 10993113, 20703595, 49488162, 24145963 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 47000654413729, 1004754424173864, 1868044813557703, - 173236934059409, 588771199737015 -#else - 21987233, 700364, 42603816, 14972007, 59334599, 27836036, - 32155025, 2581431, 37149879, 8773374 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 30498470091663, 1082245510489825, 576771653181956, - 806509986132686, 1317634017056939 -#else - 41540495, 454462, 53896929, 16126714, 25240068, 8594567, - 20656846, 12017935, 59234475, 19634276 -#endif - }}, + {0xe4, 0xe3, 0x7f, 0x8a, 0xdd, 0x4d, 0x9d, 0xce, 0x30, 0xe, 0x62, + 0x76, 0x56, 0x64, 0x13, 0xab, 0x58, 0x99, 0xe, 0xb3, 0x7b, 0x4f, + 0x59, 0x4b, 0xdf, 0x29, 0x12, 0x32, 0xef, 0xa, 0x1c, 0x5c}, + {0xa1, 0x7f, 0x4f, 0x31, 0xbf, 0x2a, 0x40, 0xa9, 0x50, 0xf4, 0x8c, + 0x8e, 0xdc, 0xf1, 0x57, 0xe2, 0x84, 0xbe, 0xa8, 0x23, 0x4b, 0xd5, + 0xbb, 0x1d, 0x3b, 0x71, 0xcb, 0x6d, 0xa3, 0xbf, 0x77, 0x21}, + {0x8f, 0xdb, 0x79, 0xfa, 0xbc, 0x1b, 0x8, 0x37, 0xb3, 0x59, 0x5f, + 0xc2, 0x1e, 0x81, 0x48, 0x60, 0x87, 0x24, 0x83, 0x9c, 0x65, 0x76, + 0x7a, 0x8, 0xbb, 0xb5, 0x8a, 0x7d, 0x38, 0x19, 0xe6, 0x4a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 420308055751555, 1493354863316002, 165206721528088, - 1884845694919786, 2065456951573059 -#else - 6028163, 6263078, 36097058, 22252721, 66289944, 2461771, - 35267690, 28086389, 65387075, 30777706 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1115636332012334, 1854340990964155, 83792697369514, - 1972177451994021, 457455116057587 -#else - 54829870, 16624276, 987579, 27631834, 32908202, 1248608, - 7719845, 29387734, 28408819, 6816612 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1698968457310898, 1435137169051090, 1083661677032510, - 938363267483709, 340103887207182 -#else - 56750770, 25316602, 19549650, 21385210, 22082622, 16147817, - 20613181, 13982702, 56769294, 5067942 -#endif - }}, + {0x83, 0xfb, 0x5b, 0x98, 0x44, 0x7e, 0x11, 0x61, 0x36, 0x31, 0x96, + 0x71, 0x2a, 0x46, 0xe0, 0xfc, 0x4b, 0x90, 0x25, 0xd4, 0x48, 0x34, + 0xac, 0x83, 0x64, 0x3d, 0xa4, 0x5b, 0xbe, 0x5a, 0x68, 0x75}, + {0x2e, 0xa3, 0x44, 0x53, 0xaa, 0xf6, 0xdb, 0x8d, 0x78, 0x40, 0x1b, + 0xb4, 0xb4, 0xea, 0x88, 0x7d, 0x60, 0xd, 0x13, 0x4a, 0x97, 0xeb, + 0xb0, 0x5e, 0x3, 0x3e, 0xbf, 0x17, 0x1b, 0xd9, 0x0, 0x1a}, + {0xb2, 0xf2, 0x61, 0xeb, 0x33, 0x9, 0x96, 0x6e, 0x52, 0x49, 0xff, + 0xc9, 0xa8, 0xf, 0x3d, 0x54, 0x69, 0x65, 0xf6, 0x7a, 0x10, 0x75, + 0x72, 0xdf, 0xaa, 0xe6, 0xb0, 0x23, 0xb6, 0x29, 0x55, 0x13}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1995325341336574, 911500251774648, 164010755403692, - 855378419194762, 1573601397528842 -#else - 36602878, 29732664, 12074680, 13582412, 47230892, 2443950, - 47389578, 12746131, 5331210, 23448488 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 241719380661528, 310028521317150, 1215881323380194, - 1408214976493624, 2141142156467363 -#else - 30528792, 3601899, 65151774, 4619784, 39747042, 18118043, - 24180792, 20984038, 27679907, 31905504 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1315157046163473, 727368447885818, 1363466668108618, - 1668921439990361, 1398483384337907 -#else - 9402385, 19597367, 32834042, 10838634, 40528714, 20317236, - 26653273, 24868867, 22611443, 20839026 -#endif - }}, + {0xfe, 0x83, 0x2e, 0xe2, 0xbc, 0x16, 0xc7, 0xf5, 0xc1, 0x85, 0x9, + 0xe8, 0x19, 0xeb, 0x2b, 0xb4, 0xae, 0x4a, 0x25, 0x14, 0x37, 0xa6, + 0x9d, 0xec, 0x13, 0xa6, 0x90, 0x15, 0x5, 0xea, 0x72, 0x59}, + {0x18, 0xd5, 0xd1, 0xad, 0xd7, 0xdb, 0xf0, 0x18, 0x11, 0x1f, 0xc1, + 0xcf, 0x88, 0x78, 0x9f, 0x97, 0x9b, 0x75, 0x14, 0x71, 0xf0, 0xe1, + 0x32, 0x87, 0x1, 0x3a, 0xca, 0x65, 0x1a, 0xb8, 0xb5, 0x79}, + {0x11, 0x78, 0x8f, 0xdc, 0x20, 0xac, 0xd4, 0xf, 0xa8, 0x4f, 0x4d, + 0xac, 0x94, 0xd2, 0x9a, 0x9a, 0x34, 0x4, 0x36, 0xb3, 0x64, 0x2d, + 0x1b, 0xc0, 0xdb, 0x3b, 0x5f, 0x90, 0x95, 0x9c, 0x7e, 0x4f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 75029678299646, 1015388206460473, 1849729037055212, - 1939814616452984, 444404230394954 -#else - 22190590, 1118029, 22736441, 15130463, 36648172, 27563110, - 19189624, 28905490, 4854858, 6622139 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2053597130993710, 2024431685856332, 2233550957004860, - 2012407275509545, 872546993104440 -#else - 58798126, 30600981, 58846284, 30166382, 56707132, 33282502, - 13424425, 29987205, 26404408, 13001963 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1217269667678610, 599909351968693, 1390077048548598, - 1471879360694802, 739586172317596 -#else - 35867026, 18138731, 64114613, 8939345, 11562230, 20713762, - 41044498, 21932711, 51703708, 11020692 -#endif - }}, + {0xfe, 0x99, 0x52, 0x35, 0x3d, 0x44, 0xc8, 0x71, 0xd7, 0xea, 0xeb, + 0xdb, 0x1c, 0x3b, 0xcd, 0x8b, 0x66, 0x94, 0xa4, 0xf1, 0x9e, 0x49, + 0x92, 0x80, 0xc8, 0xad, 0x44, 0xa1, 0xc4, 0xee, 0x42, 0x19}, + {0x2e, 0x30, 0x81, 0x57, 0xbc, 0x4b, 0x67, 0x62, 0xf, 0xdc, 0xad, + 0x89, 0x39, 0xf, 0x52, 0xd8, 0xc6, 0xd9, 0xfb, 0x53, 0xae, 0x99, + 0x29, 0x8c, 0x4c, 0x8e, 0x63, 0x2e, 0xd9, 0x3a, 0x99, 0x31}, + {0x92, 0x49, 0x23, 0xae, 0x19, 0x53, 0xac, 0x7d, 0x92, 0x3e, 0xea, + 0xc, 0x91, 0x3d, 0x1b, 0x2c, 0x22, 0x11, 0x3c, 0x25, 0x94, 0xe4, + 0x3c, 0x55, 0x75, 0xca, 0xf9, 0x4e, 0x31, 0x65, 0xa, 0x2a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1718318639380794, 1560510726633958, 904462881159922, - 1418028351780052, 94404349451937 -#else - 1866042, 25604943, 59210214, 23253421, 12483314, 13477547, - 3175636, 21130269, 28761761, 1406734 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2132502667405250, 214379346175414, 1502748313768060, - 1960071701057800, 1353971822643138 -#else - 66660290, 31776765, 13018550, 3194501, 57528444, 22392694, - 24760584, 29207344, 25577410, 20175752 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 319394212043702, 2127459436033571, 717646691535162, - 663366796076914, 318459064945314 -#else - 42818486, 4759344, 66418211, 31701615, 2066746, 10693769, - 37513074, 9884935, 57739938, 4745409 -#endif - }}, + {0x3a, 0x79, 0x1c, 0x3c, 0xcd, 0x1a, 0x36, 0xcf, 0x3b, 0xbc, 0x35, + 0x5a, 0xac, 0xbc, 0x9e, 0x2f, 0xab, 0xa6, 0xcd, 0xa8, 0xe9, 0x60, + 0xe8, 0x60, 0x13, 0x1a, 0xea, 0x6d, 0x9b, 0xc3, 0x5d, 0x5}, + {0xc2, 0x27, 0xf9, 0xf7, 0x7f, 0x93, 0xb7, 0x2d, 0x35, 0xa6, 0xd0, + 0x17, 0x6, 0x1f, 0x74, 0xdb, 0x76, 0xaf, 0x55, 0x11, 0xa2, 0xf3, + 0x82, 0x59, 0xed, 0x2d, 0x7c, 0x64, 0x18, 0xe2, 0xf6, 0x4c}, + {0xb6, 0x5b, 0x8d, 0xc2, 0x7c, 0x22, 0x19, 0xb1, 0xab, 0xff, 0x4d, + 0x77, 0xbc, 0x4e, 0xe2, 0x7, 0x89, 0x2c, 0xa3, 0xe4, 0xce, 0x78, + 0x3c, 0xa8, 0xb6, 0x24, 0xaa, 0x10, 0x77, 0x30, 0x1a, 0x12}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 405989424923593, 1960452633787083, 667349034401665, - 1492674260767112, 1451061489880787 -#else - 57967561, 6049713, 47577803, 29213020, 35848065, 9944275, - 51646856, 22242579, 10931923, 21622501 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 947085906234007, 323284730494107, 1485778563977200, - 728576821512394, 901584347702286 -#else - 50547351, 14112679, 59096219, 4817317, 59068400, 22139825, - 44255434, 10856640, 46638094, 13434653 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1575783124125742, 2126210792434375, 1569430791264065, - 1402582372904727, 1891780248341114 -#else - 22759470, 23480998, 50342599, 31683009, 13637441, 23386341, - 1765143, 20900106, 28445306, 28189722 -#endif - }}, + {0xc9, 0x83, 0x74, 0xc7, 0x3e, 0x71, 0x59, 0xd6, 0xaf, 0x96, 0x2b, + 0xb8, 0x77, 0xe0, 0xbf, 0x88, 0xd3, 0xbc, 0x97, 0x10, 0x23, 0x28, + 0x9e, 0x28, 0x9b, 0x3a, 0xed, 0x6c, 0x4a, 0xb9, 0x7b, 0x52}, + {0x97, 0x4a, 0x3, 0x9f, 0x5e, 0x5d, 0xdb, 0xe4, 0x2d, 0xbc, 0x34, + 0x30, 0x9, 0xfc, 0x53, 0xe1, 0xb1, 0xd3, 0x51, 0x95, 0x91, 0x46, + 0x5, 0x46, 0x2d, 0xe5, 0x40, 0x7a, 0x6c, 0xc7, 0x3f, 0x33}, + {0x2e, 0x48, 0x5b, 0x99, 0x2a, 0x99, 0x3d, 0x56, 0x1, 0x38, 0x38, + 0x6e, 0x7c, 0xd0, 0x5, 0x34, 0xe5, 0xd8, 0x64, 0x2f, 0xde, 0x35, + 0x50, 0x48, 0xf7, 0xa9, 0xa7, 0x20, 0x9b, 0x6, 0x89, 0x6b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 838432205560695, 1997703511451664, 1018791879907867, - 1662001808174331, 78328132957753 -#else - 29875063, 12493613, 2795536, 29768102, 1710619, 15181182, - 56913147, 24765756, 9074233, 1167180 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 739152638255629, 2074935399403557, 505483666745895, - 1611883356514088, 628654635394878 -#else - 40903181, 11014232, 57266213, 30918946, 40200743, 7532293, - 48391976, 24018933, 3843902, 9367684 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1822054032121349, 643057948186973, 7306757352712, - 577249257962099, 284735863382083 -#else - 56139269, 27150720, 9591133, 9582310, 11349256, 108879, - 16235123, 8601684, 66969667, 4242894 -#endif - }}, + {0x77, 0xdb, 0xc7, 0xb5, 0x8c, 0xfa, 0x82, 0x40, 0x55, 0xc1, 0x34, + 0xc7, 0xf8, 0x86, 0x86, 0x6, 0x7e, 0xa5, 0xe7, 0xf6, 0xd9, 0xc8, + 0xe6, 0x29, 0xcf, 0x9b, 0x63, 0xa7, 0x8, 0xd3, 0x73, 0x4}, + {0xd, 0x22, 0x70, 0x62, 0x41, 0xa0, 0x2a, 0x81, 0x4e, 0x5b, 0x24, + 0xf9, 0xfa, 0x89, 0x5a, 0x99, 0x5, 0xef, 0x72, 0x50, 0xce, 0xc4, + 0xad, 0xff, 0x73, 0xeb, 0x73, 0xaa, 0x3, 0x21, 0xbc, 0x23}, + {0x5, 0x9e, 0x58, 0x3, 0x26, 0x79, 0xee, 0xca, 0x92, 0xc4, 0xdc, + 0x46, 0x12, 0x42, 0x4b, 0x2b, 0x4f, 0xa9, 0x1, 0xe6, 0x74, 0xef, + 0xa1, 0x2, 0x1a, 0x34, 0x4, 0xde, 0xbf, 0x73, 0x2f, 0x10}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1366558556363930, 1448606567552086, 1478881020944768, - 165803179355898, 1115718458123498 -#else - 22092954, 20363309, 65066070, 21585919, 32186752, 22037044, - 60534522, 2470659, 39691498, 16625500 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 204146226972102, 1630511199034723, 2215235214174763, - 174665910283542, 956127674017216 -#else - 56051142, 3042015, 13770083, 24296510, 584235, 33009577, - 59338006, 2602724, 39757248, 14247412 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1562934578796716, 1070893489712745, 11324610642270, - 958989751581897, 2172552325473805 -#else - 6314156, 23289540, 34336361, 15957556, 56951134, 168749, - 58490057, 14290060, 27108877, 32373552 -#endif - }}, + {0x9a, 0x1c, 0x51, 0xb5, 0xe0, 0xda, 0xb4, 0xa2, 0x6, 0xff, 0xff, + 0x2b, 0x29, 0x60, 0xc8, 0x7a, 0x34, 0x42, 0x50, 0xf5, 0x5d, 0x37, + 0x1f, 0x98, 0x2d, 0xa1, 0x4e, 0xda, 0x25, 0xd7, 0x6b, 0x3f}, + {0xc6, 0x45, 0x57, 0x7f, 0xab, 0xb9, 0x18, 0xeb, 0x90, 0xc6, 0x87, + 0x57, 0xee, 0x8a, 0x3a, 0x2, 0xa9, 0xaf, 0xf7, 0x2d, 0xda, 0x12, + 0x27, 0xb7, 0x3d, 0x1, 0x5c, 0xea, 0x25, 0x7d, 0x59, 0x36}, + {0xac, 0x58, 0x60, 0x10, 0x7b, 0x8d, 0x4d, 0x73, 0x5f, 0x90, 0xc6, + 0x6f, 0x9e, 0x57, 0x40, 0xd9, 0x2d, 0x93, 0x2, 0x92, 0xf9, 0xf8, + 0x66, 0x64, 0xd0, 0xd6, 0x60, 0xda, 0x19, 0xcc, 0x7e, 0x7b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1770564423056027, 735523631664565, 1326060113795289, - 1509650369341127, 65892421582684 -#else - 58522267, 26383465, 13241781, 10960156, 34117849, 19759835, - 33547975, 22495543, 39960412, 981873 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 623682558650637, 1337866509471512, 990313350206649, - 1314236615762469, 1164772974270275 -#else - 22833421, 9293594, 34459416, 19935764, 57971897, 14756818, - 44180005, 19583651, 56629059, 17356469 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 223256821462517, 723690150104139, 1000261663630601, - 933280913953265, 254872671543046 -#else - 59340277, 3326785, 38997067, 10783823, 19178761, 14905060, - 22680049, 13906969, 51175174, 3797898 -#endif - }}, + {0x9b, 0xfa, 0x7c, 0xa7, 0x51, 0x4a, 0xae, 0x6d, 0x50, 0x86, 0xa3, + 0xe7, 0x54, 0x36, 0x26, 0x82, 0xdb, 0x82, 0x2d, 0x8f, 0xcd, 0xff, + 0xbb, 0x9, 0xba, 0xca, 0xf5, 0x1b, 0x66, 0xdc, 0xbe, 0x3}, + {0xd, 0x69, 0x5c, 0x69, 0x3c, 0x37, 0xc2, 0x78, 0x6e, 0x90, 0x42, + 0x6, 0x66, 0x2e, 0x25, 0xdd, 0xd2, 0x2b, 0xe1, 0x4a, 0x44, 0x44, + 0x1d, 0x95, 0x56, 0x39, 0x74, 0x1, 0x76, 0xad, 0x35, 0x42}, + {0xf5, 0x75, 0x89, 0x7, 0xd, 0xcb, 0x58, 0x62, 0x98, 0xf2, 0x89, + 0x91, 0x54, 0x42, 0x29, 0x49, 0xe4, 0x6e, 0xe3, 0xe2, 0x23, 0xb4, + 0xca, 0xa0, 0xa1, 0x66, 0xf0, 0xcd, 0xb0, 0xe2, 0x7c, 0xe}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1969087237026041, 624795725447124, 1335555107635969, - 2069986355593023, 1712100149341902 -#else - 21721337, 29341686, 54902740, 9310181, 63226625, 19901321, - 23740223, 30845200, 20491982, 25512280 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1236103475266979, 1837885883267218, 1026072585230455, - 1025865513954973, 1801964901432134 -#else - 9209251, 18419377, 53852306, 27386633, 66377847, 15289672, - 25947805, 15286587, 30997318, 26851369 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1115241013365517, 1712251818829143, 2148864332502771, - 2096001471438138, 2235017246626125 -#else - 7392013, 16618386, 23946583, 25514540, 53843699, 32020573, - 52911418, 31232855, 17649997, 33304352 -#endif - }}, + {0xf9, 0x70, 0x4b, 0xd9, 0xdf, 0xfe, 0xa6, 0xfe, 0x2d, 0xba, 0xfc, + 0xc1, 0x51, 0xc0, 0x30, 0xf1, 0x89, 0xab, 0x2f, 0x7f, 0x7e, 0xd4, + 0x82, 0x48, 0xb5, 0xee, 0xec, 0x8a, 0x13, 0x56, 0x52, 0x61}, + {0xa3, 0x85, 0x8c, 0xc4, 0x3a, 0x64, 0x94, 0xc4, 0xad, 0x39, 0x61, + 0x3c, 0xf4, 0x1d, 0x36, 0xfd, 0x48, 0x4d, 0xe9, 0x3a, 0xdd, 0x17, + 0xdb, 0x9, 0x4a, 0x67, 0xb4, 0x8f, 0x5d, 0xa, 0x6e, 0x66}, + {0xd, 0xcb, 0x70, 0x48, 0x4e, 0xf6, 0xbb, 0x2a, 0x6b, 0x8b, 0x45, + 0xaa, 0xf0, 0xbc, 0x65, 0xcd, 0x5d, 0x98, 0xe8, 0x75, 0xba, 0x4e, + 0xbe, 0x9a, 0xe4, 0xde, 0x14, 0xd5, 0x10, 0xc8, 0xb, 0x7f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1299268198601632, 2047148477845621, 2165648650132450, - 1612539282026145, 514197911628890 -#else - 57807776, 19360604, 30609525, 30504889, 41933794, 32270679, - 51867297, 24028707, 64875610, 7662145 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 118352772338543, 1067608711804704, 1434796676193498, - 1683240170548391, 230866769907437 -#else - 49550191, 1763593, 33994528, 15908609, 37067994, 21380136, - 7335079, 25082233, 63934189, 3440182 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1850689576796636, 1601590730430274, 1139674615958142, - 1954384401440257, 76039205311 -#else - 47219164, 27577423, 42997570, 23865561, 10799742, 16982475, - 40449, 29122597, 4862399, 1133 -#endif - }}, + {0xa0, 0x13, 0x72, 0x73, 0xad, 0x9d, 0xac, 0x83, 0x98, 0x2e, 0xf7, + 0x2e, 0xba, 0xf8, 0xf6, 0x9f, 0x57, 0x69, 0xec, 0x43, 0xdd, 0x2e, + 0x1e, 0x31, 0x75, 0xab, 0xc5, 0xde, 0x7d, 0x90, 0x3a, 0x1d}, + {0x6f, 0x13, 0xf4, 0x26, 0xa4, 0x6b, 0x0, 0xb9, 0x35, 0x30, 0xe0, + 0x57, 0x9e, 0x36, 0x67, 0x8d, 0x28, 0x3c, 0x46, 0x4f, 0xd9, 0xdf, + 0xc8, 0xcb, 0xf5, 0xdb, 0xee, 0xf8, 0xbc, 0x8d, 0x1f, 0xd}, + {0xdc, 0x81, 0xd0, 0x3e, 0x31, 0x93, 0x16, 0xba, 0x80, 0x34, 0x1b, + 0x85, 0xad, 0x9f, 0x32, 0x29, 0xcb, 0x21, 0x3, 0x3, 0x3c, 0x1, + 0x28, 0x1, 0xe3, 0xfd, 0x1b, 0xa3, 0x44, 0x1b, 0x1, 0x0}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1723387471374172, 997301467038410, 533927635123657, - 20928644693965, 1756575222802513 -#else - 34252636, 25680474, 61686474, 14860949, 50789833, 7956141, - 7258061, 311861, 36513873, 26175010 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2146711623855116, 503278928021499, 625853062251406, - 1109121378393107, 1033853809911861 -#else - 63335436, 31988495, 28985339, 7499440, 24445838, 9325937, - 29727763, 16527196, 18278453, 15405622 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 571005965509422, 2005213373292546, 1016697270349626, - 56607856974274, 914438579435146 -#else - 62726958, 8508651, 47210498, 29880007, 61124410, 15149969, - 53795266, 843522, 45233802, 13626196 -#endif - }}, + {0x5c, 0xa7, 0xa, 0x6a, 0x69, 0x1f, 0x56, 0x16, 0x6a, 0xbd, 0x52, + 0x58, 0x5c, 0x72, 0xbf, 0xc1, 0xad, 0x66, 0x79, 0x9a, 0x7f, 0xdd, + 0xa8, 0x11, 0x26, 0x10, 0x85, 0xd2, 0xa2, 0x88, 0xd9, 0x63}, + {0xc, 0x6c, 0xc6, 0x3f, 0x6c, 0xa0, 0xdf, 0x3f, 0xd2, 0xd, 0xd6, + 0x4d, 0x8e, 0xe3, 0x40, 0x5d, 0x71, 0x4d, 0x8e, 0x26, 0x38, 0x8b, + 0xe3, 0x7a, 0xe1, 0x57, 0x83, 0x6e, 0x91, 0x8d, 0xc4, 0x3a}, + {0x2e, 0x23, 0xbd, 0xaf, 0x53, 0x7, 0x12, 0x0, 0x83, 0xf6, 0xd8, + 0xfd, 0xb8, 0xce, 0x2b, 0xe9, 0x91, 0x2b, 0xe7, 0x84, 0xb3, 0x69, + 0x16, 0xf8, 0x66, 0xa0, 0x68, 0x23, 0x2b, 0xd5, 0xfa, 0x33}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1346698876211176, 2076651707527589, 1084761571110205, - 265334478828406, 1068954492309671 -#else - 2281448, 20067377, 56193445, 30944521, 1879357, 16164207, - 56324982, 3953791, 13340839, 15928663 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1769967932677654, 1695893319756416, 1151863389675920, - 1781042784397689, 400287774418285 -#else - 31727126, 26374577, 48671360, 25270779, 2875792, 17164102, - 41838969, 26539605, 43656557, 5964752 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1851867764003121, 403841933237558, 820549523771987, - 761292590207581, 1743735048551143 -#else - 4100401, 27594980, 49929526, 6017713, 48403027, 12227140, - 40424029, 11344143, 2538215, 25983677 -#endif - }}, + {0xe8, 0xcf, 0x22, 0xc4, 0xd0, 0xc8, 0x2c, 0x8d, 0xcb, 0x3a, 0xa1, + 0x5, 0x7b, 0x4f, 0x2b, 0x7, 0x6f, 0xa5, 0xf6, 0xec, 0xe6, 0xb6, + 0xfe, 0xa3, 0xe2, 0x71, 0xa, 0xb9, 0xcc, 0x55, 0xc3, 0x3c}, + {0x16, 0x1e, 0xe4, 0xc5, 0xc6, 0x49, 0x6, 0x54, 0x35, 0x77, 0x3f, + 0x33, 0x30, 0x64, 0xf8, 0xa, 0x46, 0xe7, 0x5, 0xf3, 0xd2, 0xfc, + 0xac, 0xb2, 0xa7, 0xdc, 0x56, 0xa2, 0x29, 0xf4, 0xc0, 0x16}, + {0x31, 0x91, 0x3e, 0x90, 0x43, 0x94, 0xb6, 0xe9, 0xce, 0x37, 0x56, + 0x7a, 0xcb, 0x94, 0xa4, 0xb8, 0x44, 0x92, 0xba, 0xba, 0xa4, 0xd1, + 0x7c, 0xc8, 0x68, 0x75, 0xae, 0x6b, 0x42, 0xaf, 0x1e, 0x63}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 410915148140008, 2107072311871739, 1004367461876503, - 99684895396761, 1180818713503224 -#else - 57675240, 6123112, 11159803, 31397824, 30016279, 14966241, - 46633881, 1485420, 66479608, 17595569 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 285945406881439, 648174397347453, 1098403762631981, - 1366547441102991, 1505876883139217 -#else - 40304287, 4260918, 11851389, 9658551, 35091757, 16367491, - 46903439, 20363143, 11659921, 22439314 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 672095903120153, 1675918957959872, 636236529315028, - 1569297300327696, 2164144194785875 -#else - 26180377, 10015009, 36264640, 24973138, 5418196, 9480663, - 2231568, 23384352, 33100371, 32248261 -#endif - }}, + {0xe8, 0xd, 0x70, 0xa3, 0xb9, 0x75, 0xd9, 0x47, 0x52, 0x5, 0xf8, + 0xe2, 0xfb, 0xc5, 0x80, 0x72, 0xe1, 0x5d, 0xe4, 0x32, 0x27, 0x8f, + 0x65, 0x53, 0xb5, 0x80, 0x5f, 0x66, 0x7f, 0x2c, 0x1f, 0x43}, + {0x9f, 0xfe, 0x66, 0xda, 0x10, 0x4, 0xe9, 0xb3, 0xa6, 0xe5, 0x16, + 0x6c, 0x52, 0x4b, 0xdd, 0x85, 0x83, 0xbf, 0xf9, 0x1e, 0x61, 0x97, + 0x3d, 0xbc, 0xb5, 0x19, 0xa9, 0x1e, 0x8b, 0x64, 0x99, 0x55}, + {0x19, 0x7b, 0x8f, 0x85, 0x44, 0x63, 0x2, 0xd6, 0x4a, 0x51, 0xea, + 0xa1, 0x2f, 0x35, 0xab, 0x14, 0xd7, 0xa9, 0x90, 0x20, 0x1a, 0x44, + 0x0, 0x89, 0x26, 0x3b, 0x25, 0x91, 0x5f, 0x71, 0x4, 0x7b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1902708175321798, 1035343530915438, 1178560808893263, - 301095684058146, 1280977479761118 -#else - 15121094, 28352561, 56718958, 15427820, 39598927, 17561924, - 21670946, 4486675, 61177054, 19088051 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1615357281742403, 404257611616381, 2160201349780978, - 1160947379188955, 1578038619549541 -#else - 16166467, 24070699, 56004733, 6023907, 35182066, 32189508, - 2340059, 17299464, 56373093, 23514607 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2013087639791217, 822734930507457, 1785668418619014, - 1668650702946164, 389450875221715 -#else - 28042865, 29997343, 54982337, 12259705, 63391366, 26608532, - 6766452, 24864833, 18036435, 5803270 -#endif - }}, + {0xc6, 0xba, 0xe6, 0xc4, 0x80, 0xc2, 0x76, 0xb3, 0xb, 0x9b, 0x1d, + 0x6d, 0xdd, 0xd3, 0xe, 0x97, 0x44, 0xf9, 0xb, 0x45, 0x58, 0x95, + 0x9a, 0xb0, 0x23, 0xe2, 0xcd, 0x57, 0xfa, 0xac, 0xd0, 0x48}, + {0x43, 0xae, 0xf6, 0xac, 0x28, 0xbd, 0xed, 0x83, 0xb4, 0x7a, 0x5c, + 0x7d, 0x8b, 0x7c, 0x35, 0x86, 0x44, 0x2c, 0xeb, 0xb7, 0x69, 0x47, + 0x40, 0xc0, 0x3f, 0x58, 0xf6, 0xc2, 0xf5, 0x7b, 0xb3, 0x59}, + {0x71, 0xe6, 0xab, 0x7d, 0xe4, 0x26, 0xf, 0xb6, 0x37, 0x3a, 0x2f, + 0x62, 0x97, 0xa1, 0xd1, 0xf1, 0x94, 0x3, 0x96, 0xe9, 0x7e, 0xce, + 0x8, 0x42, 0xdb, 0x3b, 0x6d, 0x33, 0x91, 0x41, 0x23, 0x16}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 453918449698368, 106406819929001, 2072540975937135, - 308588860670238, 1304394580755385 -#else - 66291264, 6763911, 11803561, 1585585, 10958447, 30883267, - 23855390, 4598332, 60949433, 19436993 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1295082798350326, 2091844511495996, 1851348972587817, - 3375039684596, 789440738712837 -#else - 36077558, 19298237, 17332028, 31170912, 31312681, 27587249, - 696308, 50292, 47013125, 11763583 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2083069137186154, 848523102004566, 993982213589257, - 1405313299916317, 1532824818698468 -#else - 66514282, 31040148, 34874710, 12643979, 12650761, 14811489, - 665117, 20940800, 47335652, 22840869 -#endif - }}, + {0x40, 0x86, 0xf3, 0x1f, 0xd6, 0x9c, 0x49, 0xdd, 0xa0, 0x25, 0x36, + 0x6, 0xc3, 0x9b, 0xcd, 0x29, 0xc3, 0x3d, 0xd7, 0x3d, 0x2, 0xd8, + 0xe2, 0x51, 0x31, 0x92, 0x3b, 0x20, 0x7a, 0x70, 0x25, 0x4a}, + {0xf6, 0x7f, 0x26, 0xf6, 0xde, 0x99, 0xe4, 0xb9, 0x43, 0x8, 0x2c, + 0x74, 0x7b, 0xca, 0x72, 0x77, 0xb1, 0xf2, 0xa4, 0xe9, 0x3f, 0x15, + 0xa0, 0x23, 0x6, 0x50, 0xd0, 0xd5, 0xec, 0xdf, 0xdf, 0x2c}, + {0x6a, 0xed, 0xf6, 0x53, 0x8a, 0x66, 0xb7, 0x2a, 0xa1, 0x70, 0xd1, + 0x1d, 0x58, 0x42, 0x42, 0x30, 0x61, 0x1, 0xe2, 0x3a, 0x4c, 0x14, + 0x0, 0x40, 0xfc, 0x49, 0x8e, 0x24, 0x6d, 0x89, 0x21, 0x57}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1495961298852430, 1397203457344779, 1774950217066942, - 139302743555696, 66603584342787 -#else - 30464590, 22291560, 62981387, 20819953, 19835326, 26448819, - 42712688, 2075772, 50088707, 992470 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1782411379088302, 1096724939964781, 27593390721418, - 542241850291353, 1540337798439873 -#else - 18357166, 26559999, 7766381, 16342475, 37783946, 411173, - 14578841, 8080033, 55534529, 22952821 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 693543956581437, 171507720360750, 1557908942697227, - 1074697073443438, 1104093109037196 -#else - 19598397, 10334610, 12555054, 2555664, 18821899, 23214652, - 21873262, 16014234, 26224780, 16452269 -#endif - }}, + {0x4e, 0xda, 0xd0, 0xa1, 0x91, 0x50, 0x5d, 0x28, 0x8, 0x3e, 0xfe, + 0xb5, 0xa7, 0x6f, 0xaa, 0x4b, 0xb3, 0x93, 0x93, 0xe1, 0x7c, 0x17, + 0xe5, 0x63, 0xfd, 0x30, 0xb0, 0xc4, 0xaf, 0x35, 0xc9, 0x3}, + {0xae, 0x1b, 0x18, 0xfd, 0x17, 0x55, 0x6e, 0xb, 0xb4, 0x63, 0xb9, + 0x2b, 0x9f, 0x62, 0x22, 0x90, 0x25, 0x46, 0x6, 0x32, 0xe9, 0xbc, + 0x9, 0x55, 0xda, 0x13, 0x3c, 0xf6, 0x74, 0xdd, 0x8e, 0x57}, + {0x3d, 0xc, 0x2b, 0x49, 0xc6, 0x76, 0x72, 0x99, 0xfc, 0x5, 0xe2, + 0xdf, 0xc4, 0xc2, 0xcc, 0x47, 0x3c, 0x3a, 0x62, 0xdd, 0x84, 0x9b, + 0xd2, 0xdc, 0xa2, 0xc7, 0x88, 0x2, 0x59, 0xab, 0xc2, 0x3e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 345288228393419, 1099643569747172, 134881908403743, - 1740551994106740, 248212179299770 -#else - 36884939, 5145195, 5944548, 16385966, 3976735, 2009897, - 55731060, 25936245, 46575034, 3698649 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 231429562203065, 1526290236421172, 2021375064026423, - 1520954495658041, 806337791525116 -#else - 14187449, 3448569, 56472628, 22743496, 44444983, 30120835, - 7268409, 22663988, 27394300, 12015369 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1079623667189886, 872403650198613, 766894200588288, - 2163700860774109, 2023464507911816 -#else - 19695742, 16087646, 28032085, 12999827, 6817792, 11427614, - 20244189, 32241655, 53849736, 30151970 -#endif - }}, + {0xcb, 0xd1, 0x32, 0xae, 0x9, 0x3a, 0x21, 0xa7, 0xd5, 0xc2, 0xf5, + 0x40, 0xdf, 0x87, 0x2b, 0xf, 0x29, 0xab, 0x1e, 0xe8, 0xc6, 0xa4, + 0xae, 0xb, 0x5e, 0xac, 0xdb, 0x6a, 0x6c, 0xf6, 0x1b, 0xe}, + {0xb9, 0x7b, 0xd8, 0xe4, 0x7b, 0xd2, 0xa0, 0xa1, 0xed, 0x1a, 0x39, + 0x61, 0xeb, 0x4d, 0x8b, 0xa9, 0x83, 0x9b, 0xcb, 0x73, 0xd0, 0xdd, + 0xa0, 0x99, 0xce, 0xca, 0xf, 0x20, 0x5a, 0xc2, 0xd5, 0x2d}, + {0x7e, 0x88, 0x2c, 0x79, 0xe9, 0xd5, 0xab, 0xe2, 0x5d, 0x6d, 0x92, + 0xcb, 0x18, 0x0, 0x2, 0x1a, 0x1e, 0x5f, 0xae, 0xba, 0xcd, 0x69, + 0xba, 0xbf, 0x5f, 0x8f, 0xe8, 0x5a, 0xb3, 0x48, 0x5, 0x73}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 854645372543796, 1936406001954827, 151460662541253, - 825325739271555, 1554306377287556 -#else - 30860084, 12735208, 65220619, 28854697, 50133957, 2256939, - 58942851, 12298311, 58558340, 23160969 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1497138821904622, 1044820250515590, 1742593886423484, - 1237204112746837, 849047450816987 -#else - 61389038, 22309106, 65198214, 15569034, 26642876, 25966672, - 61319509, 18435777, 62132699, 12651792 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 667962773375330, 1897271816877105, 1399712621683474, - 1143302161683099, 2081798441209593 -#else - 64260450, 9953420, 11531313, 28271553, 26895122, 20857343, - 53990043, 17036529, 9768697, 31021214 -#endif - }}, + {0x34, 0xe3, 0xd6, 0xa1, 0x4b, 0x9, 0x5b, 0x80, 0x19, 0x3f, 0x35, + 0x9, 0x77, 0xf1, 0x3e, 0xbf, 0x2b, 0x70, 0x22, 0x6, 0xcb, 0x6, + 0x3f, 0x42, 0xdd, 0x45, 0x78, 0xd8, 0x77, 0x22, 0x5a, 0x58}, + {0xee, 0xb8, 0xa8, 0xcb, 0xa3, 0x51, 0x35, 0xc4, 0x16, 0x5f, 0x11, + 0xb2, 0x1d, 0x6f, 0xa2, 0x65, 0x50, 0x38, 0x8c, 0xab, 0x52, 0x4f, + 0xf, 0x76, 0xca, 0xb8, 0x1d, 0x41, 0x3b, 0x44, 0x43, 0x30}, + {0x62, 0x89, 0xd4, 0x33, 0x82, 0x5f, 0x8a, 0xa1, 0x7f, 0x25, 0x78, + 0xec, 0xb5, 0xc4, 0x98, 0x66, 0xff, 0x41, 0x3e, 0x37, 0xa5, 0x6f, + 0x8e, 0xa7, 0x1f, 0x98, 0xef, 0x50, 0x89, 0x27, 0x56, 0x76}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 127147851567005, 1936114012888110, 1704424366552046, - 856674880716312, 716603621335359 -#else - 42389405, 1894650, 66821166, 28850346, 15348718, 25397902, - 32767512, 12765450, 4940095, 10678226 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1072409664800960, 2146937497077528, 1508780108920651, - 935767602384853, 1112800433544068 -#else - 18860224, 15980149, 48121624, 31991861, 40875851, 22482575, - 59264981, 13944023, 42736516, 16582018 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 333549023751292, 280219272863308, 2104176666454852, - 1036466864875785, 536135186520207 -#else - 51604604, 4970267, 37215820, 4175592, 46115652, 31354675, - 55404809, 15444559, 56105103, 7989036 -#endif - }}, + {0x9d, 0xcf, 0x86, 0xea, 0xa3, 0x73, 0x70, 0xe1, 0xdc, 0x5f, 0x15, + 0x7, 0xb7, 0xfb, 0x8c, 0x3a, 0x8e, 0x8a, 0x83, 0x31, 0xfc, 0xe7, + 0x53, 0x48, 0x16, 0xf6, 0x13, 0xb6, 0x84, 0xf4, 0xbb, 0x28}, + {0xc0, 0xc8, 0x1f, 0xd5, 0x59, 0xcf, 0xc3, 0x38, 0xf2, 0xb6, 0x6, + 0x5, 0xfd, 0xd2, 0xed, 0x9b, 0x8f, 0xe, 0x57, 0xab, 0x9f, 0x10, + 0xbf, 0x26, 0xa6, 0x46, 0xb8, 0xc1, 0xa8, 0x60, 0x41, 0x3f}, + {0x7c, 0x6c, 0x13, 0x6f, 0x5c, 0x2f, 0x61, 0xf2, 0xbe, 0x11, 0xdd, + 0xf6, 0x7, 0xd1, 0xea, 0xaf, 0x33, 0x6f, 0xde, 0x13, 0xd2, 0x9a, + 0x7e, 0x52, 0x5d, 0xf7, 0x88, 0x81, 0x35, 0xcb, 0x79, 0x1e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 373666279883137, 146457241530109, 304116267127857, - 416088749147715, 1258577131183391 -#else - 31490433, 5568061, 64696061, 2182382, 34772017, 4531685, - 35030595, 6200205, 47422751, 18754260 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1186115062588401, 2251609796968486, 1098944457878953, - 1153112761201374, 1791625503417267 -#else - 49800177, 17674491, 35586086, 33551600, 34221481, 16375548, - 8680158, 17182719, 28550067, 26697300 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1870078460219737, 2129630962183380, 852283639691142, - 292865602592851, 401904317342226 -#else - 38981977, 27866340, 16837844, 31733974, 60258182, 12700015, - 37068883, 4364037, 1155602, 5988841 -#endif - }}, + {0x81, 0x81, 0xe0, 0xf5, 0xd8, 0x53, 0xe9, 0x77, 0xd9, 0xde, 0x9d, + 0x29, 0x44, 0xc, 0xa5, 0x84, 0xe5, 0x25, 0x45, 0x86, 0xc, 0x2d, + 0x6c, 0xdc, 0xf4, 0xf2, 0xd1, 0x39, 0x2d, 0xb5, 0x8a, 0x47}, + {0xf1, 0xe3, 0xf7, 0xee, 0xc3, 0x36, 0x34, 0x1, 0xf8, 0x10, 0x9e, + 0xfe, 0x7f, 0x6a, 0x8b, 0x82, 0xfc, 0xde, 0xf9, 0xbc, 0xe5, 0x8, + 0xf9, 0x7f, 0x31, 0x38, 0x3b, 0x3a, 0x1b, 0x95, 0xd7, 0x65}, + {0x59, 0xd1, 0x52, 0x92, 0xd3, 0xa4, 0xa6, 0x66, 0x7, 0xc8, 0x1a, + 0x87, 0xbc, 0xe1, 0xdd, 0xe5, 0x6f, 0xc9, 0xc1, 0xa6, 0x40, 0x6b, + 0x2c, 0xb8, 0x14, 0x22, 0x21, 0x1a, 0x41, 0x7a, 0xd8, 0x16}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1361070124828035, 815664541425524, 1026798897364671, - 1951790935390647, 555874891834790 -#else - 21890435, 20281525, 54484852, 12154348, 59276991, 15300495, - 23148983, 29083951, 24618406, 8283181 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1546301003424277, 459094500062839, 1097668518375311, - 1780297770129643, 720763293687608 -#else - 33972757, 23041680, 9975415, 6841041, 35549071, 16356535, - 3070187, 26528504, 1466168, 10740210 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1212405311403990, 1536693382542438, 61028431067459, - 1863929423417129, 1223219538638038 -#else - 65599446, 18066246, 53605478, 22898515, 32799043, 909394, - 53169961, 27774712, 34944214, 18227391 -#endif - }}, + {0x83, 0x5, 0x4e, 0xd5, 0xe2, 0xd5, 0xa4, 0xfb, 0xfa, 0x99, 0xbd, + 0x2e, 0xd7, 0xaf, 0x1f, 0xe2, 0x8f, 0x77, 0xe9, 0x6e, 0x73, 0xc2, + 0x7a, 0x49, 0xde, 0x6d, 0x5a, 0x7a, 0x57, 0xb, 0x99, 0x1f}, + {0x15, 0x62, 0x6, 0x42, 0x5a, 0x7e, 0xbd, 0xb3, 0xc1, 0x24, 0x5a, + 0xc, 0xcd, 0xe3, 0x9b, 0x87, 0xb7, 0x94, 0xf9, 0xd6, 0xb1, 0x5d, + 0xc0, 0x57, 0xa6, 0x8c, 0xf3, 0x65, 0x81, 0x7c, 0xf8, 0x28}, + {0xd6, 0xf7, 0xe8, 0x1b, 0xad, 0x4e, 0x34, 0xa3, 0x8f, 0x79, 0xea, + 0xac, 0xeb, 0x50, 0x1e, 0x7d, 0x52, 0xe0, 0xd, 0x52, 0x9e, 0x56, + 0xc6, 0x77, 0x3e, 0x6d, 0x4d, 0x53, 0xe1, 0x2f, 0x88, 0x45}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1294303766540260, 1183557465955093, 882271357233093, - 63854569425375, 2213283684565087 -#else - 3960804, 19286629, 39082773, 17636380, 47704005, 13146867, - 15567327, 951507, 63848543, 32980496 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 339050984211414, 601386726509773, 413735232134068, - 966191255137228, 1839475899458159 -#else - 24740822, 5052253, 37014733, 8961360, 25877428, 6165135, - 42740684, 14397371, 59728495, 27410326 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 235605972169408, 2174055643032978, 1538335001838863, - 1281866796917192, 1815940222628465 -#else - 38220480, 3510802, 39005586, 32395953, 55870735, 22922977, - 51667400, 19101303, 65483377, 27059617 -#endif - }}, + {0xe4, 0x6f, 0x3c, 0x94, 0x29, 0x99, 0xac, 0xd8, 0xa2, 0x92, 0x83, + 0xa3, 0x61, 0xf1, 0xf9, 0xb5, 0xf3, 0x9a, 0xc8, 0xbe, 0x13, 0xdb, + 0x99, 0x26, 0x74, 0xf0, 0x5, 0xe4, 0x3c, 0x84, 0xcf, 0x7d}, + {0xd6, 0x83, 0x79, 0x75, 0x5d, 0x34, 0x69, 0x66, 0xa6, 0x11, 0xaa, + 0x17, 0x11, 0xed, 0xb6, 0x62, 0x8f, 0x12, 0x5e, 0x98, 0x57, 0x18, + 0xdd, 0x7d, 0xdd, 0xf6, 0x26, 0xf6, 0xb8, 0xe5, 0x8f, 0x68}, + {0xc0, 0x32, 0x47, 0x4a, 0x48, 0xd6, 0x90, 0x6c, 0x99, 0x32, 0x56, + 0xca, 0xfd, 0x43, 0x21, 0xd5, 0xe1, 0xc6, 0x5d, 0x91, 0xc3, 0x28, + 0xbe, 0xb3, 0x1b, 0x19, 0x27, 0x73, 0x7e, 0x68, 0x39, 0x67}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1632352921721536, 1833328609514701, 2092779091951987, - 1923956201873226, 2210068022482919 -#else - 793280, 24323954, 8836301, 27318725, 39747955, 31184838, - 33152842, 28669181, 57202663, 32932579 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 35271216625062, 1712350667021807, 983664255668860, - 98571260373038, 1232645608559836 -#else - 5666214, 525582, 20782575, 25516013, 42570364, 14657739, - 16099374, 1468826, 60937436, 18367850 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1998172393429622, 1798947921427073, 784387737563581, - 1589352214827263, 1589861734168180 -#else - 62249590, 29775088, 64191105, 26806412, 7778749, 11688288, - 36704511, 23683193, 65549940, 23690785 -#endif - }}, + {0xc0, 0x1a, 0xc, 0xc8, 0x9d, 0xcc, 0x6d, 0xa6, 0x36, 0xa4, 0x38, + 0x1b, 0xf4, 0x5c, 0xa0, 0x97, 0xc6, 0xd7, 0xdb, 0x95, 0xbe, 0xf3, + 0xeb, 0xa7, 0xab, 0x7d, 0x7e, 0x8d, 0xf6, 0xb8, 0xa0, 0x7d}, + {0xa6, 0x75, 0x56, 0x38, 0x14, 0x20, 0x78, 0xef, 0xe8, 0xa9, 0xfd, + 0xaa, 0x30, 0x9f, 0x64, 0xa2, 0xcb, 0xa8, 0xdf, 0x5c, 0x50, 0xeb, + 0xd1, 0x4c, 0xb3, 0xc0, 0x4d, 0x1d, 0xba, 0x5a, 0x11, 0x46}, + {0x76, 0xda, 0xb5, 0xc3, 0x53, 0x19, 0xf, 0xd4, 0x9b, 0x9e, 0x11, + 0x21, 0x73, 0x6f, 0xac, 0x1d, 0x60, 0x59, 0xb2, 0xfe, 0x21, 0x60, + 0xcc, 0x3, 0x4b, 0x4b, 0x67, 0x83, 0x7e, 0x88, 0x5f, 0x5a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1733739258725305, 31715717059538, 201969945218860, - 992093044556990, 1194308773174556 -#else - 10896313, 25834728, 824274, 472601, 47648556, 3009586, 25248958, - 14783338, 36527388, 17796587 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 846415389605137, 746163495539180, 829658752826080, - 592067705956946, 957242537821393 -#else - 10566929, 12612572, 35164652, 11118702, 54475488, 12362878, - 21752402, 8822496, 24003793, 14264025 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1758148849754419, 619249044817679, 168089007997045, - 1371497636330523, 1867101418880350 -#else - 27713843, 26198459, 56100623, 9227529, 27050101, 2504721, - 23886875, 20436907, 13958494, 27821979 -#endif - }}, + {0xb9, 0x43, 0xa6, 0xa0, 0xd3, 0x28, 0x96, 0x9e, 0x64, 0x20, 0xc3, + 0xe6, 0x0, 0xcb, 0xc3, 0xb5, 0x32, 0xec, 0x2d, 0x7c, 0x89, 0x2, + 0x53, 0x9b, 0xc, 0xc7, 0xd1, 0xd5, 0xe2, 0x7a, 0xe3, 0x43}, + {0x11, 0x3d, 0xa1, 0x70, 0xcf, 0x1, 0x63, 0x8f, 0xc4, 0xd0, 0xd, + 0x35, 0x15, 0xb8, 0xce, 0xcf, 0x7e, 0xa4, 0xbc, 0xa4, 0xd4, 0x97, + 0x2, 0xf7, 0x34, 0x14, 0x4d, 0xe4, 0x56, 0xb6, 0x69, 0x36}, + {0x33, 0xe1, 0xa6, 0xed, 0x6, 0x3f, 0x7e, 0x38, 0xc0, 0x3a, 0xa1, + 0x99, 0x51, 0x1d, 0x30, 0x67, 0x11, 0x38, 0x26, 0x36, 0xf8, 0xd8, + 0x5a, 0xbd, 0xbe, 0xe9, 0xd5, 0x4f, 0xcd, 0xe6, 0x21, 0x6a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 326633984209635, 261759506071016, 1700682323676193, - 1577907266349064, 1217647663383016 -#else - 43627235, 4867225, 39861736, 3900520, 29838369, 25342141, - 35219464, 23512650, 7340520, 18144364 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1714182387328607, 1477856482074168, 574895689942184, - 2159118410227270, 1555532449716575 -#else - 4646495, 25543308, 44342840, 22021777, 23184552, 8566613, - 31366726, 32173371, 52042079, 23179239 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 853828206885131, 998498946036955, 1835887550391235, - 207627336608048, 258363815956050 -#else - 49838347, 12723031, 50115803, 14878793, 21619651, 27356856, - 27584816, 3093888, 58265170, 3849920 -#endif - }}, + {0xe3, 0xb2, 0x99, 0x66, 0x12, 0x29, 0x41, 0xef, 0x1, 0x13, 0x8d, + 0x70, 0x47, 0x8, 0xd3, 0x71, 0xbd, 0xb0, 0x82, 0x11, 0xd0, 0x32, + 0x54, 0x32, 0x36, 0x8b, 0x1e, 0x0, 0x7, 0x1b, 0x37, 0x45}, + {0x5f, 0xe6, 0x46, 0x30, 0xa, 0x17, 0xc6, 0xf1, 0x24, 0x35, 0xd2, + 0x0, 0x2a, 0x2a, 0x71, 0x58, 0x55, 0xb7, 0x82, 0x8c, 0x3c, 0xbd, + 0xdb, 0x69, 0x57, 0xff, 0x95, 0xa1, 0xf1, 0xf9, 0x6b, 0x58}, + {0xb, 0x79, 0xf8, 0x5e, 0x8d, 0x8, 0xdb, 0xa6, 0xe5, 0x37, 0x9, + 0x61, 0xdc, 0xf0, 0x78, 0x52, 0xb8, 0x6e, 0xa1, 0x61, 0xd2, 0x49, + 0x3, 0xac, 0x79, 0x21, 0xe5, 0x90, 0x37, 0xb0, 0xaf, 0xe}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 141141474651677, 1236728744905256, 643101419899887, - 1646615130509173, 1208239602291765 -#else - 58043933, 2103171, 25561640, 18428694, 61869039, 9582957, - 32477045, 24536477, 5002293, 18004173 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1501663228068911, 1354879465566912, 1444432675498247, - 897812463852601, 855062598754348 -#else - 55051311, 22376525, 21115584, 20189277, 8808711, 21523724, - 16489529, 13378448, 41263148, 12741425 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 714380763546606, 1032824444965790, 1774073483745338, - 1063840874947367, 1738680636537158 -#else - 61162478, 10645102, 36197278, 15390283, 63821882, 26435754, - 24306471, 15852464, 28834118, 25908360 -#endif - }}, + {0x1d, 0xae, 0x75, 0xf, 0x5e, 0x80, 0x40, 0x51, 0x30, 0xcc, 0x62, + 0x26, 0xe3, 0xfb, 0x2, 0xec, 0x6d, 0x39, 0x92, 0xea, 0x1e, 0xdf, + 0xeb, 0x2c, 0xb3, 0x5b, 0x43, 0xc5, 0x44, 0x33, 0xae, 0x44}, + {0x2f, 0x4, 0x48, 0x37, 0xc1, 0x55, 0x5, 0x96, 0x11, 0xaa, 0xb, + 0x82, 0xe6, 0x41, 0x9a, 0x21, 0xc, 0x6d, 0x48, 0x73, 0x38, 0xf7, + 0x81, 0x1c, 0x61, 0xc6, 0x2, 0x5a, 0x67, 0xcc, 0x9a, 0x30}, + {0xee, 0x43, 0xa5, 0xbb, 0xb9, 0x89, 0xf2, 0x9c, 0x42, 0x71, 0xc9, + 0x5a, 0x9d, 0xe, 0x76, 0xf3, 0xaa, 0x60, 0x93, 0x4f, 0xc6, 0xe5, + 0x82, 0x1d, 0x8f, 0x67, 0x94, 0x7f, 0x1b, 0x22, 0xd5, 0x62}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1640635546696252, 633168953192112, 2212651044092396, - 30590958583852, 368515260889378 -#else - 49773116, 24447374, 42577584, 9434952, 58636780, 32971069, - 54018092, 455840, 20461858, 5491305 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1171650314802029, 1567085444565577, 1453660792008405, - 757914533009261, 1619511342778196 -#else - 13669229, 17458950, 54626889, 23351392, 52539093, 21661233, - 42112877, 11293806, 38520660, 24132599 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 420958967093237, 971103481109486, 2169549185607107, - 1301191633558497, 1661514101014240 -#else - 28497909, 6272777, 34085870, 14470569, 8906179, 32328802, - 18504673, 19389266, 29867744, 24758489 -#endif - }}, + {0x3c, 0x7a, 0xf7, 0x3a, 0x26, 0xd4, 0x85, 0x75, 0x4d, 0x14, 0xe9, + 0xfe, 0x11, 0x7b, 0xae, 0xdf, 0x3d, 0x19, 0xf7, 0x59, 0x80, 0x70, + 0x6, 0xa5, 0x37, 0x20, 0x92, 0x83, 0x53, 0x9a, 0xf2, 0x14}, + {0x6d, 0x93, 0xd0, 0x18, 0x9c, 0x29, 0x4c, 0x52, 0xc, 0x1a, 0xc, + 0x8a, 0x6c, 0xb5, 0x6b, 0xc8, 0x31, 0x86, 0x4a, 0xdb, 0x2e, 0x5, + 0x75, 0xa3, 0x62, 0x45, 0x75, 0xbc, 0xe4, 0xfd, 0xe, 0x5c}, + {0xf5, 0xd7, 0xb2, 0x25, 0xdc, 0x7e, 0x71, 0xdf, 0x40, 0x30, 0xb5, + 0x99, 0xdb, 0x70, 0xf9, 0x21, 0x62, 0x4c, 0xed, 0xc3, 0xb7, 0x34, + 0x92, 0xda, 0x3e, 0x9, 0xee, 0x7b, 0x5c, 0x36, 0x72, 0x5e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 907123651818302, 1332556122804146, 1824055253424487, - 1367614217442959, 1982558335973172 -#else - 50901822, 13517195, 39309234, 19856633, 24009063, 27180541, - 60741263, 20379039, 22853428, 29542421 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1121533090144639, 1021251337022187, 110469995947421, - 1511059774758394, 2110035908131662 -#else - 24191359, 16712145, 53177067, 15217830, 14542237, 1646131, - 18603514, 22516545, 12876622, 31441985 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 303213233384524, 2061932261128138, 352862124777736, - 40828818670255, 249879468482660 -#else - 17902668, 4518229, 66697162, 30725184, 26878216, 5258055, - 54248111, 608396, 16031844, 3723494 -#endif - }}, + {0x3e, 0xb3, 0x8, 0x2f, 0x6, 0x39, 0x93, 0x7d, 0xbe, 0x32, 0x9f, + 0xdf, 0xe5, 0x59, 0x96, 0x5b, 0xfd, 0xbd, 0x9e, 0x1f, 0xad, 0x3d, + 0xff, 0xac, 0xb7, 0x49, 0x73, 0xcb, 0x55, 0x5, 0xb2, 0x70}, + {0x7f, 0x21, 0x71, 0x45, 0x7, 0xfc, 0x5b, 0x57, 0x5b, 0xd9, 0x94, + 0x6, 0x5d, 0x67, 0x79, 0x37, 0x33, 0x1e, 0x19, 0xf4, 0xbb, 0x37, + 0xa, 0x9a, 0xbc, 0xea, 0xb4, 0x47, 0x4c, 0x10, 0xf1, 0x77}, + {0x4c, 0x2c, 0x11, 0x55, 0xc5, 0x13, 0x51, 0xbe, 0xcd, 0x1f, 0x88, + 0x9a, 0x3a, 0x42, 0x88, 0x66, 0x47, 0x3b, 0x50, 0x5e, 0x85, 0x77, + 0x66, 0x44, 0x4a, 0x40, 0x6, 0x4a, 0x8f, 0x39, 0x34, 0xe}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 856559257852200, 508517664949010, 1378193767894916, - 1723459126947129, 1962275756614521 -#else - 38476072, 12763727, 46662418, 7577503, 33001348, 20536687, - 17558841, 25681542, 23896953, 29240187 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1445691340537320, 40614383122127, 402104303144865, - 485134269878232, 1659439323587426 -#else - 47103464, 21542479, 31520463, 605201, 2543521, 5991821, - 64163800, 7229063, 57189218, 24727572 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 20057458979482, 1183363722525800, 2140003847237215, - 2053873950687614, 2112017736174909 -#else - 28816026, 298879, 38943848, 17633493, 19000927, 31888542, - 54428030, 30605106, 49057085, 31471516 -#endif - }}, + {0x28, 0x19, 0x4b, 0x3e, 0x9, 0xb, 0x93, 0x18, 0x40, 0xf6, 0xf3, + 0x73, 0xe, 0xe1, 0xe3, 0x7d, 0x6f, 0x5d, 0x39, 0x73, 0xda, 0x17, + 0x32, 0xf4, 0x3e, 0x9c, 0x37, 0xca, 0xd6, 0xde, 0x8a, 0x6f}, + {0xe8, 0xbd, 0xce, 0x3e, 0xd9, 0x22, 0x7d, 0xb6, 0x7, 0x2f, 0x82, + 0x27, 0x41, 0xe8, 0xb3, 0x9, 0x8d, 0x6d, 0x5b, 0xb0, 0x1f, 0xa6, + 0x3f, 0x74, 0x72, 0x23, 0x36, 0x8a, 0x36, 0x5, 0x54, 0x5e}, + {0x9a, 0xb2, 0xb7, 0xfd, 0x3d, 0x12, 0x40, 0xe3, 0x91, 0xb2, 0x1a, + 0xa2, 0xe1, 0x97, 0x7b, 0x48, 0x9e, 0x94, 0xe6, 0xfd, 0x2, 0x7d, + 0x96, 0xf9, 0x97, 0xde, 0xd3, 0xc8, 0x2e, 0xe7, 0xd, 0x78}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2228654250927986, 1483591363415267, 1368661293910956, - 1076511285177291, 526650682059608 -#else - 16000882, 33209536, 3493091, 22107234, 37604268, 20394642, - 12577739, 16041268, 47393624, 7847706 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 709481497028540, 531682216165724, 316963769431931, - 1814315888453765, 258560242424104 -#else - 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, - 34252933, 27035413, 57088296, 3852847 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1053447823660455, 1955135194248683, 1010900954918985, - 1182614026976701, 1240051576966610 -#else - 55678375, 15697595, 45987307, 29133784, 5386313, 15063598, - 16514493, 17622322, 29330898, 18478208 -#endif - }}, + {0x72, 0x27, 0xf4, 0x0, 0xf3, 0xea, 0x1f, 0x67, 0xaa, 0x41, 0x8c, + 0x2a, 0x2a, 0xeb, 0x72, 0x8f, 0x92, 0x32, 0x37, 0x97, 0xd7, 0x7f, + 0xa1, 0x29, 0xa6, 0x87, 0xb5, 0x32, 0xad, 0xc6, 0xef, 0x1d}, + {0xbc, 0xe7, 0x9a, 0x8, 0x45, 0x85, 0xe2, 0xa, 0x6, 0x4d, 0x7f, + 0x1c, 0xcf, 0xde, 0x8d, 0x38, 0xb8, 0x11, 0x48, 0xa, 0x51, 0x15, + 0xac, 0x38, 0xe4, 0x8c, 0x92, 0x71, 0xf6, 0x8b, 0xb2, 0xe}, + {0xa7, 0x95, 0x51, 0xef, 0x1a, 0xbe, 0x5b, 0xaf, 0xed, 0x15, 0x7b, + 0x91, 0x77, 0x12, 0x8c, 0x14, 0x2e, 0xda, 0xe5, 0x7a, 0xfb, 0xf7, + 0x91, 0x29, 0x67, 0x28, 0xdd, 0xf8, 0x1b, 0x20, 0x7d, 0x46}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1957943897155497, 1788667368028035, 137692910029106, - 1039519607062, 826404763313028 -#else - 41609129, 29175637, 51885955, 26653220, 16615730, 2051784, - 3303702, 15490, 39560068, 12314390 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1848942433095597, 1582009882530495, 1849292741020143, - 1068498323302788, 2001402229799484 -#else - 15683501, 27551389, 18109119, 23573784, 15337967, 27556609, - 50391428, 15921865, 16103996, 29823217 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1528282417624269, 2142492439828191, 2179662545816034, - 362568973150328, 1591374675250271 -#else - 43939021, 22773182, 13588191, 31925625, 63310306, 32479502, - 47835256, 5402698, 37293151, 23713330 -#endif - }}, + {0xa9, 0xe7, 0x7a, 0x56, 0xbd, 0xf4, 0x1e, 0xbc, 0xbd, 0x98, 0x44, + 0xd6, 0xb2, 0x4c, 0x62, 0x3f, 0xc8, 0x4e, 0x1f, 0x2c, 0xd2, 0x64, + 0x10, 0xe4, 0x1, 0x40, 0x38, 0xba, 0xa5, 0xc5, 0xf9, 0x2e}, + {0xad, 0x4f, 0xef, 0x74, 0x9a, 0x91, 0xfe, 0x95, 0xa2, 0x8, 0xa3, + 0xf6, 0xec, 0x7b, 0x82, 0x3a, 0x1, 0x7b, 0xa4, 0x9, 0xd3, 0x1, + 0x4e, 0x96, 0x97, 0xc7, 0xa3, 0x5b, 0x4f, 0x3c, 0xc4, 0x71}, + {0xcd, 0x74, 0x9e, 0xfa, 0xf6, 0x6d, 0xfd, 0xb6, 0x7a, 0x26, 0xaf, + 0xe4, 0xbc, 0x78, 0x82, 0xf1, 0xe, 0x99, 0xef, 0xf1, 0xd0, 0xb3, + 0x55, 0x82, 0x93, 0xf2, 0xc5, 0x90, 0xa3, 0x8c, 0x75, 0x5a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 160026679434388, 232341189218716, 2149181472355545, - 598041771119831, 183859001910173 -#else - 23190676, 2384583, 34394524, 3462153, 37205209, 32025299, - 55842007, 8911516, 41903005, 2739712 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2013278155187349, 662660471354454, 793981225706267, - 411706605985744, 804490933124791 -#else - 21374101, 30000182, 33584214, 9874410, 15377179, 11831242, - 33578960, 6134906, 4931255, 11987849 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2051892037280204, 488391251096321, 2230187337030708, - 930221970662692, 679002758255210 -#else - 67101132, 30575573, 50885377, 7277596, 105524, 33232381, - 35628324, 13861387, 37032554, 10117929 -#endif - }}, + {0x94, 0xdc, 0x61, 0x1d, 0x8b, 0x91, 0xe0, 0x8c, 0x66, 0x30, 0x81, + 0x9a, 0x46, 0x36, 0xed, 0x8d, 0xd3, 0xaa, 0xe8, 0xaf, 0x29, 0xa8, + 0xe6, 0xd4, 0x3f, 0xd4, 0x39, 0xf6, 0x27, 0x80, 0x73, 0xa}, + {0x95, 0x24, 0x46, 0xd9, 0x10, 0x27, 0xb7, 0xa2, 0x3, 0x50, 0x7d, + 0xd5, 0xd2, 0xc6, 0xa8, 0x3a, 0xca, 0x87, 0xb4, 0xa0, 0xbf, 0x0, + 0xd4, 0xe3, 0xec, 0x72, 0xeb, 0xb3, 0x44, 0xe2, 0xba, 0x2d}, + {0xcc, 0xe1, 0xff, 0x57, 0x2f, 0x4a, 0xf, 0x98, 0x43, 0x98, 0x83, + 0xe1, 0xd, 0xd, 0x67, 0x0, 0xfd, 0x15, 0xfb, 0x49, 0x4a, 0x3f, + 0x5c, 0x10, 0x9c, 0xa6, 0x26, 0x51, 0x63, 0xca, 0x98, 0x26}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1530723630438670, 875873929577927, 341560134269988, - 449903119530753, 1055551308214179 -#else - 37607694, 22809559, 40945095, 13051538, 41483300, 5089642, - 60783361, 6704078, 12890019, 15728940 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1461835919309432, 1955256480136428, 180866187813063, - 1551979252664528, 557743861963950 -#else - 45136504, 21783052, 66157804, 29135591, 14704839, 2695116, - 903376, 23126293, 12885166, 8311031 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 359179641731115, 1324915145732949, 902828372691474, - 294254275669987, 1887036027752957 -#else - 49592363, 5352193, 10384213, 19742774, 7506450, 13453191, - 26423267, 4384730, 1888765, 28119028 -#endif - }}, + {0xe, 0xd9, 0x3d, 0x5e, 0x2f, 0x70, 0x3d, 0x2e, 0x86, 0x53, 0xd2, + 0xe4, 0x18, 0x9, 0x3f, 0x9e, 0x6a, 0xa9, 0x4d, 0x2, 0xf6, 0x3e, + 0x77, 0x5e, 0x32, 0x33, 0xfa, 0x4a, 0xc, 0x4b, 0x0, 0x3c}, + {0x78, 0xba, 0xb0, 0x32, 0x88, 0x31, 0x65, 0xe7, 0x8b, 0xff, 0x5c, + 0x92, 0xf7, 0x31, 0x18, 0x38, 0xcc, 0x1f, 0x29, 0xa0, 0x91, 0x1b, + 0xa8, 0x8, 0x7, 0xeb, 0xca, 0x49, 0xcc, 0x3d, 0xb4, 0x1f}, + {0x2b, 0xb8, 0xf4, 0x6, 0xac, 0x46, 0xa9, 0x9a, 0xf3, 0xc4, 0x6, + 0xa8, 0xa5, 0x84, 0xa2, 0x1c, 0x87, 0x47, 0xcd, 0xc6, 0x5f, 0x26, + 0xd3, 0x3e, 0x17, 0xd2, 0x1f, 0xcd, 0x1, 0xfd, 0x43, 0x6b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2043271609454323, 2038225437857464, 1317528426475850, - 1398989128982787, 2027639881006861 -#else - 41291507, 30447119, 53614264, 30371925, 30896458, 19632703, - 34857219, 20846562, 47644429, 30214188 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2072902725256516, 312132452743412, 309930885642209, - 996244312618453, 1590501300352303 -#else - 43500868, 30888657, 66582772, 4651135, 5765089, 4618330, - 6092245, 14845197, 17151279, 23700316 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1397254305160710, 695734355138021, 2233992044438756, - 1776180593969996, 1085588199351115 -#else - 42278406, 20820711, 51942885, 10367249, 37577956, 33289075, - 22825804, 26467153, 50242379, 16176524 -#endif - }}, + {0xf3, 0xe, 0x76, 0x3e, 0x58, 0x42, 0xc7, 0xb5, 0x90, 0xb9, 0xa, + 0xee, 0xb9, 0x52, 0xdc, 0x75, 0x3f, 0x92, 0x2b, 0x7, 0xc2, 0x27, + 0x14, 0xbf, 0xf0, 0xd9, 0xf0, 0x6f, 0x2d, 0xb, 0x42, 0x73}, + {0x44, 0xc5, 0x97, 0x46, 0x4b, 0x5d, 0xa7, 0xc7, 0xbf, 0xff, 0xf, + 0xdf, 0x48, 0xf8, 0xfd, 0x15, 0x5a, 0x78, 0x46, 0xaa, 0xeb, 0xb9, + 0x68, 0x28, 0x14, 0xf7, 0x52, 0x5b, 0x10, 0xd7, 0x68, 0x5a}, + {0x6, 0x1e, 0x85, 0x9e, 0xcb, 0xf6, 0x2c, 0xaf, 0xc4, 0x38, 0x22, + 0xc6, 0x13, 0x39, 0x59, 0x8f, 0x73, 0xf3, 0xfb, 0x99, 0x96, 0xb8, + 0x8a, 0xda, 0x9e, 0xbc, 0x34, 0xea, 0x2f, 0x63, 0xb5, 0x3d}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 440567051331029, 254894786356681, 493869224930222, - 1556322069683366, 1567456540319218 -#else - 43525589, 6564960, 20063689, 3798228, 62368686, 7359224, - 2006182, 23191006, 38362610, 23356922 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1950722461391320, 1907845598854797, 1822757481635527, - 2121567704750244, 73811931471221 -#else - 56482264, 29068029, 53788301, 28429114, 3432135, 27161203, - 23632036, 31613822, 32808309, 1099883 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 387139307395758, 2058036430315676, 1220915649965325, - 1794832055328951, 1230009312169328 -#else - 15030958, 5768825, 39657628, 30667132, 60681485, 18193060, - 51830967, 26745081, 2051440, 18328567 -#endif - }}, + {0xd5, 0x25, 0x98, 0x82, 0xb1, 0x90, 0x49, 0x2e, 0x91, 0x89, 0x9a, + 0x3e, 0x87, 0xeb, 0xea, 0xed, 0xf8, 0x4a, 0x70, 0x4c, 0x39, 0x3d, + 0xf0, 0xee, 0xe, 0x2b, 0xdf, 0x95, 0xa4, 0x7e, 0x19, 0x59}, + {0xd8, 0xd9, 0x5d, 0xf7, 0x2b, 0xee, 0x6e, 0xf4, 0xa5, 0x59, 0x67, + 0x39, 0xf6, 0xb1, 0x17, 0xd, 0x73, 0x72, 0x9e, 0x49, 0x31, 0xd1, + 0xf2, 0x1b, 0x13, 0x5f, 0xd7, 0x49, 0xdf, 0x1a, 0x32, 0x4}, + {0xae, 0x5a, 0xe5, 0xe4, 0x19, 0x60, 0xe1, 0x4, 0xe9, 0x92, 0x2f, + 0x7e, 0x7a, 0x43, 0x7b, 0xe7, 0xa4, 0x9a, 0x15, 0x6f, 0xc1, 0x2d, + 0xce, 0xc7, 0xc0, 0xc, 0xd7, 0xf4, 0xc1, 0xfd, 0xea, 0x45}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1765973779329517, 659344059446977, 19821901606666, - 1301928341311214, 1116266004075885 -#else - 63746541, 26315059, 7517889, 9824992, 23555850, 295369, 5148398, - 19400244, 44422509, 16633659 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1127572801181483, 1224743760571696, 1276219889847274, - 1529738721702581, 1589819666871853 -#else - 4577067, 16802144, 13249840, 18250104, 19958762, 19017158, - 18559669, 22794883, 8402477, 23690159 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2181229378964934, 2190885205260020, 1511536077659137, - 1246504208580490, 668883326494241 -#else - 38702534, 32502850, 40318708, 32646733, 49896449, 22523642, - 9453450, 18574360, 17983009, 9967138 -#endif - }}, + {0xed, 0xb1, 0xcc, 0xcf, 0x24, 0x46, 0xe, 0xb6, 0x95, 0x3, 0x5c, + 0xbd, 0x92, 0xc2, 0xdb, 0x59, 0xc9, 0x81, 0x4, 0xdc, 0x1d, 0x9d, + 0xa0, 0x31, 0x40, 0xd9, 0x56, 0x5d, 0xea, 0xce, 0x73, 0x3f}, + {0x2b, 0xd7, 0x45, 0x80, 0x85, 0x1, 0x84, 0x69, 0x51, 0x6, 0x2f, + 0xcf, 0xa2, 0xfa, 0x22, 0x4c, 0xc6, 0x2d, 0x22, 0x6b, 0x65, 0x36, + 0x1a, 0x94, 0xde, 0xda, 0x62, 0x3, 0xc8, 0xeb, 0x5e, 0x5a}, + {0xc6, 0x8d, 0x4e, 0xa, 0xd1, 0xbf, 0xa7, 0xb7, 0x39, 0xb3, 0xc9, + 0x44, 0x7e, 0x0, 0x57, 0xbe, 0xfa, 0xae, 0x57, 0x15, 0x7f, 0x20, + 0xc1, 0x60, 0xdb, 0x18, 0x62, 0x26, 0x91, 0x88, 0x5, 0x26}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 437866655573314, 669026411194768, 81896997980338, - 523874406393178, 245052060935236 -#else - 41346370, 6524721, 26585488, 9969270, 24709298, 1220360, - 65430874, 7806336, 17507396, 3651560 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1975438052228868, 1071801519999806, 594652299224319, - 1877697652668809, 1489635366987285 -#else - 56688388, 29436320, 14584638, 15971087, 51340543, 8861009, - 26556809, 27979875, 48555541, 22197296 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 958592545673770, 233048016518599, 851568750216589, - 567703851596087, 1740300006094761 -#else - 2839082, 14284142, 4029895, 3472686, 14402957, 12689363, - 40466743, 8459446, 61503401, 25932490 -#endif - }}, + {0x42, 0xe5, 0x76, 0xc6, 0x3c, 0x8e, 0x81, 0x4c, 0xad, 0xcc, 0xce, + 0x3, 0x93, 0x2c, 0x42, 0x5e, 0x8, 0x9f, 0x12, 0xb4, 0xca, 0xcc, + 0x7, 0xec, 0xb8, 0x43, 0x44, 0xb2, 0x10, 0xfa, 0xed, 0xd}, + {0x4, 0xff, 0x60, 0x83, 0xa6, 0x4, 0xf7, 0x59, 0xf4, 0xe6, 0x61, + 0x76, 0xde, 0x3f, 0xd9, 0xc3, 0x51, 0x35, 0x87, 0x12, 0x73, 0x2a, + 0x1b, 0x83, 0x57, 0x5d, 0x61, 0x4e, 0x2e, 0xc, 0xad, 0x54}, + {0x2a, 0x52, 0x2b, 0xb8, 0xd5, 0x67, 0x3b, 0xee, 0xeb, 0xc1, 0xa5, + 0x9f, 0x46, 0x63, 0xf1, 0x36, 0xd3, 0x9f, 0xc1, 0x6e, 0xf2, 0xd2, + 0xb4, 0xa5, 0x8, 0x94, 0x7a, 0xa7, 0xba, 0xb2, 0xec, 0x62}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2014540178270324, 192672779514432, 213877182641530, - 2194819933853411, 1716422829364835 -#else - 62269556, 30018987, 9744960, 2871048, 25113978, 3187018, - 41998051, 32705365, 17258083, 25576693 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1540769606609725, 2148289943846077, 1597804156127445, - 1230603716683868, 815423458809453 -#else - 18164541, 22959256, 49953981, 32012014, 19237077, 23809137, - 23357532, 18337424, 26908269, 12150756 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1738560251245018, 1779576754536888, 1783765347671392, - 1880170990446751, 1088225159617541 -#else - 36843994, 25906566, 5112248, 26517760, 65609056, 26580174, - 43167, 28016731, 34806789, 16215818 -#endif - }}, + {0x74, 0x28, 0xb6, 0xaf, 0x36, 0x28, 0x7, 0x92, 0xa5, 0x4, 0xe1, + 0x79, 0x85, 0x5e, 0xcd, 0x5f, 0x4a, 0xa1, 0x30, 0xc6, 0xad, 0x1, + 0xad, 0x5a, 0x98, 0x3f, 0x66, 0x75, 0x50, 0x3d, 0x91, 0x61}, + {0x3d, 0x2b, 0x15, 0x61, 0x52, 0x79, 0xed, 0xe5, 0xd1, 0xd7, 0xdd, + 0xe, 0x7d, 0x35, 0x62, 0x49, 0x71, 0x4c, 0x6b, 0xb9, 0xd0, 0xc8, + 0x82, 0x74, 0xbe, 0xd8, 0x66, 0xa9, 0x19, 0xf9, 0x59, 0x2e}, + {0xda, 0x31, 0x32, 0x1a, 0x36, 0x2d, 0xc6, 0xd, 0x70, 0x2, 0x20, + 0x94, 0x32, 0x58, 0x47, 0xfa, 0xce, 0x94, 0x95, 0x3f, 0x51, 0x1, + 0xd8, 0x2, 0x5c, 0x5d, 0xc0, 0x31, 0xa1, 0xc2, 0xdb, 0x3d}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 659303913929492, 1956447718227573, 1830568515922666, - 841069049744408, 1669607124206368 -#else - 60209940, 9824393, 54804085, 29153342, 35711722, 27277596, - 32574488, 12532905, 59605792, 24879084 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1143465490433355, 1532194726196059, 1093276745494697, - 481041706116088, 2121405433561163 -#else - 39765323, 17038963, 39957339, 22831480, 946345, 16291093, - 254968, 7168080, 21676107, 31611404 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1686424298744462, 1451806974487153, 266296068846582, - 1834686947542675, 1720762336132256 -#else - 21260942, 25129680, 50276977, 21633609, 43430902, 3968120, - 63456915, 27338965, 63552672, 25641356 -#endif - }}, + {0x14, 0xbb, 0x96, 0x27, 0xa2, 0x57, 0xaa, 0xf3, 0x21, 0xda, 0x7, + 0x9b, 0xb7, 0xba, 0x3a, 0x88, 0x1c, 0x39, 0xa0, 0x31, 0x18, 0xe2, + 0x4b, 0xe5, 0xf9, 0x5, 0x32, 0xd8, 0x38, 0xfb, 0xe7, 0x5e}, + {0x4b, 0xc5, 0x5e, 0xce, 0xf9, 0xf, 0xdc, 0x9a, 0xd, 0x13, 0x2f, + 0x8c, 0x6b, 0x2a, 0x9c, 0x3, 0x15, 0x95, 0xf8, 0xf0, 0xc7, 0x7, + 0x80, 0x2, 0x6b, 0xb3, 0x4, 0xac, 0x14, 0x83, 0x96, 0x78}, + {0x8e, 0x6a, 0x44, 0x41, 0xcb, 0xfd, 0x8d, 0x53, 0xf9, 0x37, 0x49, + 0x43, 0xa9, 0xfd, 0xac, 0xa5, 0x78, 0x8c, 0x3c, 0x26, 0x8d, 0x90, + 0xaf, 0x46, 0x9, 0xd, 0xca, 0x9b, 0x3c, 0x63, 0xd0, 0x61}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 889217026388959, 1043290623284660, 856125087551909, - 1669272323124636, 1603340330827879 -#else - 16544735, 13250366, 50304436, 15546241, 62525861, 12757257, - 64646556, 24874095, 48201831, 23891632 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1206396181488998, 333158148435054, 1402633492821422, - 1120091191722026, 1945474114550509 -#else - 64693606, 17976703, 18312302, 4964443, 51836334, 20900867, - 26820650, 16690659, 25459437, 28989823 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 766720088232571, 1512222781191002, 1189719893490790, - 2091302129467914, 2141418006894941 -#else - 41964155, 11425019, 28423002, 22533875, 60963942, 17728207, - 9142794, 31162830, 60676445, 31909614 -#endif - }}, + {0xdf, 0x73, 0xfc, 0xf8, 0xbc, 0x28, 0xa3, 0xad, 0xfc, 0x37, 0xf0, + 0xa6, 0x5d, 0x69, 0x84, 0xee, 0x9, 0xa9, 0xc2, 0x38, 0xdb, 0xb4, + 0x7f, 0x63, 0xdc, 0x7b, 0x6, 0xf8, 0x2d, 0xac, 0x23, 0x5b}, + {0x66, 0x25, 0xdb, 0xff, 0x35, 0x49, 0x74, 0x63, 0xbb, 0x68, 0xb, + 0x78, 0x89, 0x6b, 0xbd, 0xc5, 0x3, 0xec, 0x3e, 0x55, 0x80, 0x32, + 0x1b, 0x6f, 0xf5, 0xd7, 0xae, 0x47, 0xd8, 0x5f, 0x96, 0x6e}, + {0x7b, 0x52, 0x80, 0xee, 0x53, 0xb9, 0xd2, 0x9a, 0x8d, 0x6d, 0xde, + 0xfa, 0xaa, 0x19, 0x8f, 0xe8, 0xcf, 0x82, 0xe, 0x15, 0x4, 0x17, + 0x71, 0xe, 0xdc, 0xde, 0x95, 0xdd, 0xb9, 0xbb, 0xb9, 0x79}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 419663647306612, 1998875112167987, 1426599870253707, - 1154928355379510, 486538532138187 -#else - 44004212, 6253475, 16964147, 29785560, 41994891, 21257994, - 39651638, 17209773, 6335691, 7249989 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 938160078005954, 1421776319053174, 1941643234741774, - 180002183320818, 1414380336750546 -#else - 36775618, 13979674, 7503222, 21186118, 55152142, 28932738, - 36836594, 2682241, 25993170, 21075909 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 398001940109652, 1577721237663248, 1012748649830402, - 1540516006905144, 1011684812884559 -#else - 4364628, 5930691, 32304656, 23509878, 59054082, 15091130, - 22857016, 22955477, 31820367, 15075278 -#endif - }}, + {0x74, 0x73, 0x9f, 0x8e, 0xae, 0x7d, 0x99, 0xd1, 0x16, 0x8, 0xbb, + 0xcf, 0xf8, 0xa2, 0x32, 0xa0, 0xa, 0x5f, 0x44, 0x6d, 0x12, 0xba, + 0x6c, 0xcd, 0x34, 0xb8, 0xcc, 0xa, 0x46, 0x11, 0xa8, 0x1b}, + {0xc2, 0x26, 0x31, 0x6a, 0x40, 0x55, 0xb3, 0xeb, 0x93, 0xc3, 0xc8, + 0x68, 0xa8, 0x83, 0x63, 0xd2, 0x82, 0x7a, 0xb9, 0xe5, 0x29, 0x64, + 0xc, 0x6c, 0x47, 0x21, 0xfd, 0xc9, 0x58, 0xf1, 0x65, 0x50}, + {0x54, 0x99, 0x42, 0xc, 0xfb, 0x69, 0x81, 0x70, 0x67, 0xcf, 0x6e, + 0xd7, 0xac, 0x0, 0x46, 0xe1, 0xba, 0x45, 0xe6, 0x70, 0x8a, 0xb9, + 0xaa, 0x2e, 0xf2, 0xfa, 0xa4, 0x58, 0x9e, 0xf3, 0x81, 0x39}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1653276489969630, 6081825167624, 1921777941170836, - 1604139841794531, 861211053640641 -#else - 31879134, 24635739, 17258760, 90626, 59067028, 28636722, - 24162787, 23903546, 49138625, 12833044 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 996661541407379, 1455877387952927, 744312806857277, - 139213896196746, 1000282908547789 -#else - 19073683, 14851414, 42705695, 21694263, 7625277, 11091125, - 47489674, 2074448, 57694925, 14905376 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1450817495603008, 1476865707053229, 1030490562252053, - 620966950353376, 1744760161539058 -#else - 24483648, 21618865, 64589997, 22007013, 65555733, 15355505, - 41826784, 9253128, 27628530, 25998952 -#endif - }}, + {0xde, 0x6f, 0xe6, 0x6d, 0xa5, 0xdf, 0x45, 0xc8, 0x3a, 0x48, 0x40, + 0x2c, 0x0, 0xa5, 0x52, 0xe1, 0x32, 0xf6, 0xb4, 0xc7, 0x63, 0xe1, + 0xd2, 0xe9, 0x65, 0x1b, 0xbc, 0xdc, 0x2e, 0x45, 0xf4, 0x30}, + {0x93, 0xa, 0x23, 0x59, 0x75, 0x8a, 0xfb, 0x18, 0x5d, 0xf4, 0xe6, + 0x60, 0x69, 0x8f, 0x16, 0x1d, 0xb5, 0x3c, 0xa9, 0x14, 0x45, 0xa9, + 0x85, 0x3a, 0xfd, 0xd0, 0xac, 0x5, 0x37, 0x8, 0xdc, 0x38}, + {0x40, 0x97, 0x75, 0xc5, 0x82, 0x27, 0x6d, 0x85, 0xcc, 0xbe, 0x9c, + 0xf9, 0x69, 0x45, 0x13, 0xfa, 0x71, 0x4e, 0xea, 0xc0, 0x73, 0xfc, + 0x44, 0x88, 0x69, 0x24, 0x3f, 0x59, 0x1a, 0x9a, 0x2d, 0x63}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 559728410002599, 37056661641185, 2038622963352006, - 1637244893271723, 1026565352238948 -#else - 17597607, 8340603, 19355617, 552187, 26198470, 30377849, - 4593323, 24396850, 52997988, 15297015 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 962165956135846, 1116599660248791, 182090178006815, - 1455605467021751, 196053588803284 -#else - 510886, 14337390, 35323607, 16638631, 6328095, 2713355, - 46891447, 21690211, 8683220, 2921426 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 796863823080135, 1897365583584155, 420466939481601, - 2165972651724672, 932177357788289 -#else - 18606791, 11874196, 27155355, 28272950, 43077121, 6265445, - 41930624, 32275507, 4674689, 13890525 -#endif - }}, + {0xa7, 0x84, 0xc, 0xed, 0x11, 0xfd, 0x9, 0xbf, 0x3a, 0x69, 0x9f, + 0xd, 0x81, 0x71, 0xf0, 0x63, 0x79, 0x87, 0xcf, 0x57, 0x2d, 0x8c, + 0x90, 0x21, 0xa2, 0x4b, 0xf6, 0x8a, 0xf2, 0x7d, 0x5a, 0x3a}, + {0xa6, 0xcb, 0x7, 0xb8, 0x15, 0x6b, 0xbb, 0xf6, 0xd7, 0xf0, 0x54, + 0xbc, 0xdf, 0xc7, 0x23, 0x18, 0xb, 0x67, 0x29, 0x6e, 0x3, 0x97, + 0x1d, 0xbb, 0x57, 0x4a, 0xed, 0x47, 0x88, 0xf4, 0x24, 0xb}, + {0xc7, 0xea, 0x1b, 0x51, 0xbe, 0xd4, 0xda, 0xdc, 0xf2, 0xcc, 0x26, + 0xed, 0x75, 0x80, 0x53, 0xa4, 0x65, 0x9a, 0x5f, 0x0, 0x9f, 0xff, + 0x9c, 0xe1, 0x63, 0x1f, 0x48, 0x75, 0x44, 0xf7, 0xfc, 0x34}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 877047233620632, 1375632631944375, 643773611882121, - 660022738847877, 19353932331831 -#else - 13609624, 13069022, 39736503, 20498523, 24360585, 9592974, - 14977157, 9835105, 4389687, 288396 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2216943882299338, 394841323190322, 2222656898319671, - 558186553950529, 1077236877025190 -#else - 9922506, 33035038, 13613106, 5883594, 48350519, 33120168, - 54804801, 8317627, 23388070, 16052080 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 801118384953213, 1914330175515892, 574541023311511, - 1471123787903705, 1526158900256288 -#else - 12719997, 11937594, 35138804, 28525742, 26900119, 8561328, - 46953177, 21921452, 52354592, 22741539 -#endif - }}, + {0x98, 0xaa, 0xcf, 0x78, 0xab, 0x1d, 0xbb, 0xa5, 0xf2, 0x72, 0xb, + 0x19, 0x67, 0xa2, 0xed, 0x5c, 0x8e, 0x60, 0x92, 0xa, 0x11, 0xc9, + 0x9, 0x93, 0xb0, 0x74, 0xb3, 0x2f, 0x4, 0xa3, 0x19, 0x1}, + {0xca, 0x67, 0x97, 0x78, 0x4c, 0xe0, 0x97, 0xc1, 0x7d, 0x46, 0xd9, + 0x38, 0xcb, 0x4d, 0x71, 0xb8, 0xa8, 0x5f, 0xf9, 0x83, 0x82, 0x88, + 0xde, 0x55, 0xf7, 0x63, 0xfa, 0x4d, 0x16, 0xdc, 0x3b, 0x3d}, + {0x7d, 0x17, 0xc2, 0xe8, 0x9c, 0xd8, 0xa2, 0x67, 0xc1, 0xd0, 0x95, + 0x68, 0xf6, 0xa5, 0x9d, 0x66, 0xb0, 0xa2, 0x82, 0xb2, 0xe5, 0x98, + 0x65, 0xf5, 0x73, 0xa, 0xe2, 0xed, 0xf1, 0x88, 0xc0, 0x56}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 949617889087234, 2207116611267331, 912920039141287, - 501158539198789, 62362560771472 -#else - 15961858, 14150409, 26716931, 32888600, 44314535, 13603568, - 11829573, 7467844, 38286736, 929274 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1474518386765335, 1760793622169197, 1157399790472736, - 1622864308058898, 165428294422792 -#else - 11038231, 21972036, 39798381, 26237869, 56610336, 17246600, - 43629330, 24182562, 45715720, 2465073 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1961673048027128, 102619413083113, 1051982726768458, - 1603657989805485, 1941613251499678 -#else - 20017144, 29231206, 27915241, 1529148, 12396362, 15675764, - 13817261, 23896366, 2463390, 28932292 -#endif - }}, + {0x2, 0x8f, 0xf3, 0x24, 0xac, 0x5f, 0x1b, 0x58, 0xbd, 0xc, 0xe3, + 0xba, 0xfe, 0xe9, 0xb, 0xa9, 0xf0, 0x92, 0xcf, 0x8a, 0x2, 0x69, + 0x21, 0x9a, 0x8f, 0x3, 0x59, 0x83, 0xa4, 0x7e, 0x8b, 0x3}, + {0x17, 0x6e, 0xa8, 0x10, 0x11, 0x3d, 0x6d, 0x33, 0xfa, 0xb2, 0x75, + 0xb, 0x32, 0x88, 0xf3, 0xd7, 0x88, 0x29, 0x7, 0x25, 0x76, 0x33, + 0x15, 0xf9, 0x87, 0x8b, 0x10, 0x99, 0x6b, 0x4c, 0x67, 0x9}, + {0xf8, 0x6f, 0x31, 0x99, 0x21, 0xf8, 0x4e, 0x9f, 0x4f, 0x8d, 0xa7, + 0xea, 0x82, 0xd2, 0x49, 0x2f, 0x74, 0x31, 0xef, 0x5a, 0xab, 0xa5, + 0x71, 0x9, 0x65, 0xeb, 0x69, 0x59, 0x2, 0x31, 0x5e, 0x6e}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1401939116319266, 335306339903072, 72046196085786, - 862423201496006, 850518754531384 -#else - 50749986, 20890520, 55043680, 4996453, 65852442, 1073571, - 9583558, 12851107, 4003896, 12673717 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1234706593321979, 1083343891215917, 898273974314935, - 1640859118399498, 157578398571149 -#else - 65377275, 18398561, 63845933, 16143081, 19294135, 13385325, - 14741514, 24450706, 7903885, 2348101 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1143483057726416, 1992614991758919, 674268662140796, - 1773370048077526, 674318359920189 -#else - 24536016, 17039225, 12715591, 29692277, 1511292, 10047386, - 63266518, 26425272, 38731325, 10048126 -#endif - }}, + {0x22, 0x62, 0x6, 0x63, 0xe, 0xfb, 0x4, 0x33, 0x3f, 0xba, 0xac, + 0x87, 0x89, 0x6, 0x35, 0xfb, 0xa3, 0x61, 0x10, 0x8c, 0x77, 0x24, + 0x19, 0xbd, 0x20, 0x86, 0x83, 0xd1, 0x43, 0xad, 0x58, 0x30}, + {0xfb, 0x93, 0xe5, 0x87, 0xf5, 0x62, 0x6c, 0xb1, 0x71, 0x3e, 0x5d, + 0xca, 0xde, 0xed, 0x99, 0x49, 0x6d, 0x3e, 0xcc, 0x14, 0xe0, 0xc1, + 0x91, 0xb4, 0xa8, 0xdb, 0xa8, 0x89, 0x47, 0x11, 0xf5, 0x8}, + {0xd0, 0x63, 0x76, 0xe5, 0xfd, 0xf, 0x3c, 0x32, 0x10, 0xa6, 0x2e, + 0xa2, 0x38, 0xdf, 0xc3, 0x5, 0x9a, 0x4f, 0x99, 0xac, 0xbd, 0x8a, + 0xc7, 0xbd, 0x99, 0xdc, 0xe3, 0xef, 0xa4, 0x9f, 0x54, 0x26}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1835401379538542, 173900035308392, 818247630716732, - 1762100412152786, 1021506399448291 -#else - 54486638, 27349611, 30718824, 2591312, 56491836, 12192839, - 18873298, 26257342, 34811107, 15221631 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1506632088156630, 2127481795522179, 513812919490255, - 140643715928370, 442476620300318 -#else - 40630742, 22450567, 11546243, 31701949, 9180879, 7656409, - 45764914, 2095754, 29769758, 6593415 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2056683376856736, 219094741662735, 2193541883188309, - 1841182310235800, 556477468664293 -#else - 35114656, 30646970, 4176911, 3264766, 12538965, 32686321, - 26312344, 27435754, 30958053, 8292160 -#endif - }}, + {0x6e, 0x66, 0x3f, 0xaf, 0x49, 0x85, 0x46, 0xdb, 0xa5, 0xe, 0x4a, + 0xf1, 0x4, 0xcf, 0x7f, 0xd7, 0x47, 0xc, 0xba, 0xa4, 0xf7, 0x3f, + 0xf2, 0x3d, 0x85, 0x3c, 0xce, 0x32, 0xe1, 0xdf, 0x10, 0x3a}, + {0xd6, 0xf9, 0x6b, 0x1e, 0x46, 0x5a, 0x1d, 0x74, 0x81, 0xa5, 0x77, + 0x77, 0xfc, 0xb3, 0x5, 0x23, 0xd9, 0xd3, 0x74, 0x64, 0xa2, 0x74, + 0x55, 0xd4, 0xff, 0xe0, 0x1, 0x64, 0xdc, 0xe1, 0x26, 0x19}, + {0xa0, 0xce, 0x17, 0xea, 0x8a, 0x4e, 0x7f, 0xe0, 0xfd, 0xc1, 0x1f, + 0x3a, 0x46, 0x15, 0xd5, 0x2f, 0xf1, 0xc0, 0xf2, 0x31, 0xfd, 0x22, + 0x53, 0x17, 0x15, 0x5d, 0x1e, 0x86, 0x1d, 0xd0, 0xa1, 0x1f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1315019427910827, 1049075855992603, 2066573052986543, - 266904467185534, 2040482348591520 -#else - 31429803, 19595316, 29173531, 15632448, 12174511, 30794338, - 32808830, 3977186, 26143136, 30405556 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 94096246544434, 922482381166992, 24517828745563, - 2139430508542503, 2097139044231004 -#else - 22648882, 1402143, 44308880, 13746058, 7936347, 365344, - 58440231, 31879998, 63350620, 31249806 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 537697207950515, 1399352016347350, 1563663552106345, - 2148749520888918, 549922092988516 -#else - 51616947, 8012312, 64594134, 20851969, 43143017, 23300402, - 65496150, 32018862, 50444388, 8194477 -#endif - }}, + {0xab, 0x94, 0xdf, 0xd1, 0x0, 0xac, 0xdc, 0x38, 0xe9, 0xd, 0x8, + 0xd1, 0xdd, 0x2b, 0x71, 0x2e, 0x62, 0xe2, 0xd5, 0xfd, 0x3e, 0xe9, + 0x13, 0x7f, 0xe5, 0x1, 0x9a, 0xee, 0x18, 0xed, 0xfc, 0x73}, + {0x32, 0x98, 0x59, 0x7d, 0x94, 0x55, 0x80, 0xcc, 0x20, 0x55, 0xf1, + 0x37, 0xda, 0x56, 0x46, 0x1e, 0x20, 0x93, 0x5, 0x4e, 0x74, 0xf7, + 0xf6, 0x99, 0x33, 0xcf, 0x75, 0x6a, 0xbc, 0x63, 0x35, 0x77}, + {0xb3, 0x9c, 0x13, 0x63, 0x8, 0xe9, 0xb1, 0x6, 0xcd, 0x3e, 0xa0, + 0xc5, 0x67, 0xda, 0x93, 0xa4, 0x32, 0x89, 0x63, 0xad, 0xc8, 0xce, + 0x77, 0x8d, 0x44, 0x4f, 0x86, 0x1b, 0x70, 0x6b, 0x42, 0x1f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1747985413252434, 680511052635695, 1809559829982725, - 594274250930054, 201673170745982 -#else - 27338066, 26047012, 59694639, 10140404, 48082437, 26964542, - 27277190, 8855376, 28572286, 3005164 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 323583936109569, 1973572998577657, 1192219029966558, - 79354804385273, 1374043025560347 -#else - 26287105, 4821776, 25476601, 29408529, 63344350, 17765447, - 49100281, 1182478, 41014043, 20474836 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 213277331329947, 416202017849623, 1950535221091783, - 1313441578103244, 2171386783823658 -#else - 59937691, 3178079, 23970071, 6201893, 49913287, 29065239, - 45232588, 19571804, 32208682, 32356184 -#endif - }}, + {0x52, 0x25, 0xa1, 0x91, 0xc8, 0x35, 0x7e, 0xf1, 0x76, 0x9c, 0x5e, + 0x57, 0x53, 0x81, 0x6b, 0xb7, 0x3e, 0x72, 0x9b, 0xd, 0x6f, 0x40, + 0x83, 0xfa, 0x38, 0xe4, 0xa7, 0x3f, 0x1b, 0xbb, 0x76, 0xb}, + {0x1, 0x1c, 0x91, 0x41, 0x4c, 0x26, 0xc9, 0xef, 0x25, 0x2c, 0xa2, + 0x17, 0xb8, 0xb7, 0xa3, 0xf1, 0x47, 0x14, 0xf, 0xf3, 0x6b, 0xda, + 0x75, 0x58, 0x90, 0xb0, 0x31, 0x1d, 0x27, 0xf5, 0x1a, 0x4e}, + {0x9b, 0x93, 0x92, 0x7f, 0xf9, 0xc1, 0xb8, 0x8, 0x6e, 0xab, 0x44, + 0xd4, 0xcb, 0x71, 0x67, 0xbe, 0x17, 0x80, 0xbb, 0x99, 0x63, 0x64, + 0xe5, 0x22, 0x55, 0xa9, 0x72, 0xb7, 0x1e, 0xd6, 0x6d, 0x7b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 189088804229831, 993969372859110, 895870121536987, - 1547301535298256, 1477373024911350 -#else - 50451143, 2817642, 56822502, 14811297, 6024667, 13349505, - 39793360, 23056589, 39436278, 22014573 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1620578418245010, 541035331188469, 2235785724453865, - 2154865809088198, 1974627268751826 -#else - 15941010, 24148500, 45741813, 8062054, 31876073, 33315803, - 51830470, 32110002, 15397330, 29424239 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1346805451740245, 1350981335690626, 942744349501813, - 2155094562545502, 1012483751693409 -#else - 8934485, 20068965, 43822466, 20131190, 34662773, 14047985, - 31170398, 32113411, 39603297, 15087183 -#endif - }}, + {0xc7, 0xd2, 0x1, 0xab, 0xf9, 0xab, 0x30, 0x57, 0x18, 0x3b, 0x14, + 0x40, 0xdc, 0x76, 0xfb, 0x16, 0x81, 0xb2, 0xcb, 0xa0, 0x65, 0xbe, + 0x6c, 0x86, 0xfe, 0x6a, 0xff, 0x9b, 0x65, 0x9b, 0xfa, 0x53}, + {0x92, 0x3d, 0xf3, 0x50, 0xe8, 0xc1, 0xad, 0xb7, 0xcf, 0xd5, 0x8c, + 0x60, 0x4f, 0xfa, 0x98, 0x79, 0xdb, 0x5b, 0xfc, 0x8d, 0xbd, 0x2d, + 0x96, 0xad, 0x4f, 0x2f, 0x1d, 0xaf, 0xce, 0x9b, 0x3e, 0x70}, + {0x55, 0x54, 0x88, 0x94, 0xe9, 0xc8, 0x14, 0x6c, 0xe5, 0xd4, 0xae, + 0x65, 0x66, 0x5d, 0x3a, 0x84, 0xf1, 0x5a, 0xd6, 0xbc, 0x3e, 0xb7, + 0x1b, 0x18, 0x50, 0x1f, 0xc6, 0xc4, 0xe5, 0x93, 0x8d, 0x39}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2107080134091762, 1132567062788208, 1824935377687210, - 769194804343737, 1857941799971888 -#else - 48751602, 31397940, 24524912, 16876564, 15520426, 27193656, - 51606457, 11461895, 16788528, 27685490 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1074666112436467, 249279386739593, 1174337926625354, - 1559013532006480, 1472287775519121 -#else - 65161459, 16013772, 21750665, 3714552, 49707082, 17498998, - 63338576, 23231111, 31322513, 21938797 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1872620123779532, 1892932666768992, 1921559078394978, - 1270573311796160, 1438913646755037 -#else - 21426636, 27904214, 53460576, 28206894, 38296674, 28633461, - 48833472, 18933017, 13040861, 21441484 -#endif - }}, + {0xf2, 0xe3, 0xe7, 0xd2, 0x60, 0x7c, 0x87, 0xc3, 0xb1, 0x8b, 0x82, + 0x30, 0xa0, 0xaa, 0x34, 0x3b, 0x38, 0xf1, 0x9e, 0x73, 0xe7, 0x26, + 0x3e, 0x28, 0x77, 0x5, 0xc3, 0x2, 0x90, 0x9c, 0x9c, 0x69}, + {0xf3, 0x48, 0xe2, 0x33, 0x67, 0xd1, 0x4b, 0x1c, 0x5f, 0xa, 0xbf, + 0x15, 0x87, 0x12, 0x9e, 0xbd, 0x76, 0x3, 0xb, 0xa1, 0xf0, 0x8c, + 0x3f, 0xd4, 0x13, 0x1b, 0x19, 0xdf, 0x5d, 0x9b, 0xb0, 0x53}, + {0xcc, 0xf1, 0x46, 0x59, 0x23, 0xa7, 0x6, 0xf3, 0x7d, 0xd9, 0xe5, + 0xcc, 0xb5, 0x18, 0x17, 0x92, 0x75, 0xe9, 0xb4, 0x81, 0x47, 0xd2, + 0xcd, 0x28, 0x7, 0xd9, 0xcd, 0x6f, 0xc, 0xf3, 0xca, 0x51}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 837390187648199, 1012253300223599, 989780015893987, - 1351393287739814, 328627746545550 -#else - 11293895, 12478086, 39972463, 15083749, 37801443, 14748871, - 14555558, 20137329, 1613710, 4896935 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1028328827183114, 1711043289969857, 1350832470374933, - 1923164689604327, 1495656368846911 -#else - 41213962, 15323293, 58619073, 25496531, 25967125, 20128972, - 2825959, 28657387, 43137087, 22287016 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1900828492104143, 430212361082163, 687437570852799, - 832514536673512, 1685641495940794 -#else - 51184079, 28324551, 49665331, 6410663, 3622847, 10243618, - 20615400, 12405433, 43355834, 25118015 -#endif - }}, + {0xc7, 0x54, 0xac, 0x18, 0x9a, 0xf9, 0x7a, 0x73, 0xf, 0xb3, 0x1c, + 0xc5, 0xdc, 0x78, 0x33, 0x90, 0xc7, 0xc, 0xe1, 0x4c, 0x33, 0xbc, + 0x89, 0x2b, 0x9a, 0xe9, 0xf8, 0x89, 0xc1, 0x29, 0xae, 0x12}, + {0xa, 0xe0, 0x74, 0x76, 0x42, 0xa7, 0xb, 0xa6, 0xf3, 0x7b, 0x7a, + 0xa1, 0x70, 0x85, 0xe, 0x63, 0xcc, 0x24, 0x33, 0xcf, 0x3d, 0x56, + 0x58, 0x37, 0xaa, 0xfd, 0x83, 0x23, 0x29, 0xaa, 0x4, 0x55}, + {0xcf, 0x1, 0xd, 0x1f, 0xcb, 0xc0, 0x9e, 0xa9, 0xae, 0xf7, 0x34, + 0x3a, 0xcc, 0xef, 0xd1, 0xd, 0x22, 0x4e, 0x9c, 0xd0, 0x21, 0x75, + 0xca, 0x55, 0xea, 0xa5, 0xeb, 0x58, 0xe9, 0x4f, 0xd1, 0x5f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 842632847936398, 605670026766216, 290836444839585, - 163210774892356, 2213815011799645 -#else - 60017550, 12556207, 46917512, 9025186, 50036385, 4333800, - 4378436, 2432030, 23097949, 32988414 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1176336383453996, 1725477294339771, 12700622672454, - 678015708818208, 162724078519879 -#else - 4565804, 17528778, 20084411, 25711615, 1724998, 189254, - 24767264, 10103221, 48596551, 2424777 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1448049969043497, 1789411762943521, 385587766217753, - 90201620913498, 832999441066823 -#else - 366633, 21577626, 8173089, 26664313, 30788633, 5745705, - 59940186, 1344108, 63466311, 12412658 -#endif - }}, + {0x8e, 0xcb, 0x93, 0xbf, 0x5e, 0xfe, 0x42, 0x3c, 0x5f, 0x56, 0xd4, + 0x36, 0x51, 0xa8, 0xdf, 0xbe, 0xe8, 0x20, 0x42, 0x88, 0x9e, 0x85, + 0xf0, 0xe0, 0x28, 0xd1, 0x25, 0x7, 0x96, 0x3f, 0xd7, 0x7d}, + {0x2c, 0xab, 0x45, 0x28, 0xdf, 0x2d, 0xdc, 0xb5, 0x93, 0xe9, 0x7f, + 0xa, 0xb1, 0x91, 0x94, 0x6, 0x46, 0xe3, 0x2, 0x40, 0xd6, 0xf3, + 0xaa, 0x4d, 0xd1, 0x74, 0x64, 0x58, 0x6e, 0xf2, 0x3f, 0x9}, + {0x29, 0x98, 0x5, 0x68, 0xfe, 0x24, 0xd, 0xb1, 0xe5, 0x23, 0xaf, + 0xdb, 0x72, 0x6, 0x73, 0x75, 0x29, 0xac, 0x57, 0xb4, 0x3a, 0x25, + 0x67, 0x13, 0xa4, 0x70, 0xb4, 0x86, 0xbc, 0xbc, 0x59, 0x2f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 516086333293313, 2240508292484616, 1351669528166508, - 1223255565316488, 750235824427138 -#else - 43107073, 7690285, 14929416, 33386175, 34898028, 20141445, - 24162696, 18227928, 63967362, 11179384 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1263624896582495, 1102602401673328, 526302183714372, - 2152015839128799, 1483839308490010 -#else - 18289503, 18829478, 8056944, 16430056, 45379140, 7842513, - 61107423, 32067534, 48424218, 22110928 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 442991718646863, 1599275157036458, 1925389027579192, - 899514691371390, 350263251085160 -#else - 476239, 6601091, 60956074, 23831056, 17503544, 28690532, - 27672958, 13403813, 11052904, 5219329 -#endif - }}, + {0x1, 0xc3, 0x91, 0xb6, 0x60, 0xd5, 0x41, 0x70, 0x1e, 0xe7, 0xd7, + 0xad, 0x3f, 0x1b, 0x20, 0x85, 0x85, 0x55, 0x33, 0x11, 0x63, 0xe1, + 0xc2, 0x16, 0xb1, 0x28, 0x8, 0x1, 0x3d, 0x5e, 0xa5, 0x2a}, + {0x5f, 0x13, 0x17, 0x99, 0x42, 0x7d, 0x84, 0x83, 0xd7, 0x3, 0x7d, + 0x56, 0x1f, 0x91, 0x1b, 0xad, 0xd1, 0xaa, 0x77, 0xbe, 0xd9, 0x48, + 0x77, 0x7e, 0x4a, 0xaf, 0x51, 0x2e, 0x2e, 0xb4, 0x58, 0x54}, + {0x4f, 0x44, 0x7, 0xc, 0xe6, 0x92, 0x51, 0xed, 0x10, 0x1d, 0x42, + 0x74, 0x2d, 0x4e, 0xc5, 0x42, 0x64, 0xc8, 0xb5, 0xfd, 0x82, 0x4c, + 0x2b, 0x35, 0x64, 0x86, 0x76, 0x8a, 0x4a, 0x0, 0xe9, 0x13}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1689713572022143, 593854559254373, 978095044791970, - 1985127338729499, 1676069120347625 -#else - 20678527, 25178694, 34436965, 8849122, 62099106, 14574751, - 31186971, 29580702, 9014761, 24975376 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1557207018622683, 340631692799603, 1477725909476187, - 614735951619419, 2033237123746766 -#else - 53464795, 23204192, 51146355, 5075807, 65594203, 22019831, - 34006363, 9160279, 8473550, 30297594 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 968764929340557, 1225534776710944, 662967304013036, - 1155521416178595, 791142883466590 -#else - 24900749, 14435722, 17209120, 18261891, 44516588, 9878982, - 59419555, 17218610, 42540382, 11788947 -#endif - }}, + {0x7f, 0x87, 0x3b, 0x19, 0xc9, 0x0, 0x2e, 0xbb, 0x6b, 0x50, 0xdc, + 0xe0, 0x90, 0xa8, 0xe3, 0xec, 0x9f, 0x64, 0xde, 0x36, 0xc0, 0xb7, + 0xf3, 0xec, 0x1a, 0x9e, 0xde, 0x98, 0x8, 0x4, 0x46, 0x5f}, + {0xdb, 0xce, 0x2f, 0x83, 0x45, 0x88, 0x9d, 0x73, 0x63, 0xf8, 0x6b, + 0xae, 0xc9, 0xd6, 0x38, 0xfa, 0xf7, 0xfe, 0x4f, 0xb7, 0xca, 0xd, + 0xbc, 0x32, 0x5e, 0xe4, 0xbc, 0x14, 0x88, 0x7e, 0x93, 0x73}, + {0x8d, 0xf4, 0x7b, 0x29, 0x16, 0x71, 0x3, 0xb9, 0x34, 0x68, 0xf0, + 0xd4, 0x22, 0x3b, 0xd1, 0xa9, 0xc6, 0xbd, 0x96, 0x46, 0x57, 0x15, + 0x97, 0xe1, 0x35, 0xe8, 0xd5, 0x91, 0xe8, 0xa4, 0xf8, 0x2c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1487081286167458, 993039441814934, 1792378982844640, - 698652444999874, 2153908693179754 -#else - 63990690, 22159237, 53306774, 14797440, 9652448, 26708528, - 47071426, 10410732, 42540394, 32095740 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1123181311102823, 685575944875442, 507605465509927, - 1412590462117473, 568017325228626 -#else - 51449703, 16736705, 44641714, 10215877, 58011687, 7563910, - 11871841, 21049238, 48595538, 8464117 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 560258797465417, 2193971151466401, 1824086900849026, - 579056363542056, 1690063960036441 -#else - 43708233, 8348506, 52522913, 32692717, 63158658, 27181012, - 14325288, 8628612, 33313881, 25183915 -#endif - }}, + {0xa2, 0x6b, 0xd0, 0x17, 0x7e, 0x48, 0xb5, 0x2c, 0x6b, 0x19, 0x50, + 0x39, 0x1c, 0x38, 0xd2, 0x24, 0x30, 0x8a, 0x97, 0x85, 0x81, 0x9c, + 0x65, 0xd7, 0xf6, 0xa4, 0xd6, 0x91, 0x28, 0x7f, 0x6f, 0x7a}, + {0x67, 0xf, 0x11, 0x7, 0x87, 0xfd, 0x93, 0x6d, 0x49, 0xb5, 0x38, + 0x7c, 0xd3, 0x9, 0x4c, 0xdd, 0x86, 0x6a, 0x73, 0xc2, 0x4c, 0x6a, + 0xb1, 0x7c, 0x9, 0x2a, 0x25, 0x58, 0x6e, 0xbd, 0x49, 0x20}, + {0x49, 0xef, 0x9a, 0x6a, 0x8d, 0xfd, 0x9, 0x7d, 0xb, 0xb9, 0x3d, + 0x5b, 0xbe, 0x60, 0xee, 0xf0, 0xd4, 0xbf, 0x9e, 0x51, 0x2c, 0xb5, + 0x21, 0x4c, 0x1d, 0x94, 0x45, 0xc5, 0xdf, 0xaa, 0x11, 0x60}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1918407319222416, 353767553059963, 1930426334528099, - 1564816146005724, 1861342381708096 -#else - 46921872, 28586496, 22367355, 5271547, 66011747, 28765593, - 42303196, 23317577, 58168128, 27736162 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2131325168777276, 1176636658428908, 1756922641512981, - 1390243617176012, 1966325177038383 -#else - 60160060, 31759219, 34483180, 17533252, 32635413, 26180187, - 15989196, 20716244, 28358191, 29300528 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2063958120364491, 2140267332393533, 699896251574968, - 273268351312140, 375580724713232 -#else - 43547083, 30755372, 34757181, 31892468, 57961144, 10429266, - 50471180, 4072015, 61757200, 5596588 -#endif - }}, + {0x90, 0xf8, 0xcb, 0x2, 0xc8, 0xd0, 0xde, 0x63, 0xaa, 0x6a, 0xff, + 0xd, 0xca, 0x98, 0xd0, 0xfb, 0x99, 0xed, 0xb6, 0xb9, 0xfd, 0xa, + 0x4d, 0x62, 0x1e, 0xb, 0x34, 0x79, 0xb7, 0x18, 0xce, 0x69}, + {0x3c, 0xf8, 0x95, 0xcf, 0x6d, 0x92, 0x67, 0x5f, 0x71, 0x90, 0x28, + 0x71, 0x61, 0x85, 0x7e, 0x7c, 0x5b, 0x7a, 0x8f, 0x99, 0xf3, 0xe7, + 0xa1, 0xd6, 0xe0, 0xf9, 0x62, 0xb, 0x1b, 0xcc, 0xc5, 0x6f}, + {0xcb, 0x79, 0x98, 0xb2, 0x28, 0x55, 0xef, 0xd1, 0x92, 0x90, 0x7e, + 0xd4, 0x3c, 0xae, 0x1a, 0xdd, 0x52, 0x23, 0x9f, 0x18, 0x42, 0x4, + 0x7e, 0x12, 0xf1, 0x1, 0x71, 0xe5, 0x3a, 0x6b, 0x59, 0x15}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2024297515263178, 416959329722687, 1079014235017302, - 171612225573183, 1031677520051053 -#else - 38872266, 30164383, 12312895, 6213178, 3117142, 16078565, - 29266239, 2557221, 1768301, 15373193 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2033900009388450, 1744902869870788, 2190580087917640, - 1949474984254121, 231049754293748 -#else - 59865506, 30307471, 62515396, 26001078, 66980936, 32642186, - 66017961, 29049440, 42448372, 3442909 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 343868674606581, 550155864008088, 1450580864229630, - 481603765195050, 896972360018042 -#else - 36898293, 5124042, 14181784, 8197961, 18964734, 21615339, - 22597930, 7176455, 48523386, 13365929 -#endif - }}, + {0xca, 0x24, 0x51, 0x7e, 0x16, 0x31, 0xff, 0x9, 0xdf, 0x45, 0xc7, + 0xd9, 0x8b, 0x15, 0xe4, 0xb, 0xe5, 0x56, 0xf5, 0x7e, 0x22, 0x7d, + 0x2b, 0x29, 0x38, 0xd1, 0xb6, 0xaf, 0x41, 0xe2, 0xa4, 0x3a}, + {0xa2, 0x79, 0x91, 0x3f, 0xd2, 0x39, 0x27, 0x46, 0xcf, 0xdd, 0xd6, + 0x97, 0x31, 0x12, 0x83, 0xff, 0x8a, 0x14, 0xf2, 0x53, 0xb5, 0xde, + 0x7, 0x13, 0xda, 0x4d, 0x5f, 0x7b, 0x68, 0x37, 0x22, 0xd}, + {0xf5, 0x5, 0x33, 0x2a, 0xbf, 0x38, 0xc1, 0x2c, 0xc3, 0x26, 0xe9, + 0xa2, 0x8f, 0x3f, 0x58, 0x48, 0xeb, 0xd2, 0x49, 0x55, 0xa2, 0xb1, + 0x3a, 0x8, 0x6c, 0xa3, 0x87, 0x46, 0x6e, 0xaa, 0xfc, 0x32}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2151139328380127, 314745882084928, 59756825775204, - 1676664391494651, 2048348075599360 -#else - 59231455, 32054473, 8324672, 4690079, 6261860, 890446, 24538107, - 24984246, 57419264, 30522764 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1528930066340597, 1605003907059576, 1055061081337675, - 1458319101947665, 1234195845213142 -#else - 25008885, 22782833, 62803832, 23916421, 16265035, 15721635, - 683793, 21730648, 15723478, 18390951 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 830430507734812, 1780282976102377, 1425386760709037, - 362399353095425, 2168861579799910 -#else - 57448220, 12374378, 40101865, 26528283, 59384749, 21239917, - 11879681, 5400171, 519526, 32318556 -#endif - }}, + {0xdf, 0xcc, 0x87, 0x27, 0x73, 0xa4, 0x7, 0x32, 0xf8, 0xe3, 0x13, + 0xf2, 0x8, 0x19, 0xe3, 0x17, 0x4e, 0x96, 0xd, 0xf6, 0xd7, 0xec, + 0xb2, 0xd5, 0xe9, 0xb, 0x60, 0xc2, 0x36, 0x63, 0x6f, 0x74}, + {0xf5, 0x9a, 0x7d, 0xc5, 0x8d, 0x6e, 0xc5, 0x7b, 0xf2, 0xbd, 0xf0, + 0x9d, 0xed, 0xd2, 0xb, 0x3e, 0xa3, 0xe4, 0xef, 0x22, 0xde, 0x14, + 0xc0, 0xaa, 0x5c, 0x6a, 0xbd, 0xfe, 0xce, 0xe9, 0x27, 0x46}, + {0x1c, 0x97, 0x6c, 0xab, 0x45, 0xf3, 0x4a, 0x3f, 0x1f, 0x73, 0x43, + 0x99, 0x72, 0xeb, 0x88, 0xe2, 0x6d, 0x18, 0x44, 0x3, 0x8a, 0x6a, + 0x59, 0x33, 0x93, 0x62, 0xd6, 0x7e, 0x0, 0x17, 0x49, 0x7b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1155762232730333, 980662895504006, 2053766700883521, - 490966214077606, 510405877041357 -#else - 22258397, 17222199, 59239046, 14613015, 44588609, 30603508, - 46754982, 7315966, 16648397, 7605640 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1683750316716132, 652278688286128, 1221798761193539, - 1897360681476669, 319658166027343 -#else - 59027556, 25089834, 58885552, 9719709, 19259459, 18206220, - 23994941, 28272877, 57640015, 4763277 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 618808732869972, 72755186759744, 2060379135624181, - 1730731526741822, 48862757828238 -#else - 45409620, 9220968, 51378240, 1084136, 41632757, 30702041, - 31088446, 25789909, 55752334, 728111 -#endif - }}, + {0xdd, 0xa2, 0x53, 0xdd, 0x28, 0x1b, 0x34, 0x54, 0x3f, 0xfc, 0x42, + 0xdf, 0x5b, 0x90, 0x17, 0xaa, 0xf4, 0xf8, 0xd2, 0x4d, 0xd9, 0x92, + 0xf5, 0xf, 0x7d, 0xd3, 0x8c, 0xe0, 0xf, 0x62, 0x3, 0x1d}, + {0x64, 0xb0, 0x84, 0xab, 0x5c, 0xfb, 0x85, 0x2d, 0x14, 0xbc, 0xf3, + 0x89, 0xd2, 0x10, 0x78, 0x49, 0xc, 0xce, 0x15, 0x7b, 0x44, 0xdc, + 0x6a, 0x47, 0x7b, 0xfd, 0x44, 0xf8, 0x76, 0xa3, 0x2b, 0x12}, + {0x54, 0xe5, 0xb4, 0xa2, 0xcd, 0x32, 0x2, 0xc2, 0x7f, 0x18, 0x5d, + 0x11, 0x42, 0xfd, 0xd0, 0x9e, 0xd9, 0x79, 0xd4, 0x7d, 0xbe, 0xb4, + 0xab, 0x2e, 0x4c, 0xec, 0x68, 0x2b, 0xf5, 0xb, 0xc7, 0x2}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1463171970593505, 1143040711767452, 614590986558883, - 1409210575145591, 1882816996436803 -#else - 26047201, 21802961, 60208540, 17032633, 24092067, 9158119, - 62835319, 20998873, 37743427, 28056159 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2230133264691131, 563950955091024, 2042915975426398, - 827314356293472, 672028980152815 -#else - 17510331, 33231575, 5854288, 8403524, 17133918, 30441820, - 38997856, 12327944, 10750447, 10014012 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 264204366029760, 1654686424479449, 2185050199932931, - 2207056159091748, 506015669043634 -#else - 56796096, 3936951, 9156313, 24656749, 16498691, 32559785, - 39627812, 32887699, 3424690, 7540221 -#endif - }}, + {0xe1, 0x72, 0x8d, 0x45, 0xbf, 0x32, 0xe5, 0xac, 0xb5, 0x3c, 0xb7, + 0x7c, 0xe0, 0x68, 0xe7, 0x5b, 0xe7, 0xbd, 0x8b, 0xee, 0x94, 0x7d, + 0xcf, 0x56, 0x3, 0x3a, 0xb4, 0xfe, 0xe3, 0x97, 0x6, 0x6b}, + {0xbb, 0x2f, 0xb, 0x5d, 0x4b, 0xec, 0x87, 0xa2, 0xca, 0x82, 0x48, + 0x7, 0x90, 0x57, 0x5c, 0x41, 0x5c, 0x81, 0xd0, 0xc1, 0x1e, 0xa6, + 0x44, 0xe0, 0xe0, 0xf5, 0x9e, 0x40, 0xa, 0x4f, 0x33, 0x26}, + {0xc0, 0xa3, 0x62, 0xdf, 0x4a, 0xf0, 0xc8, 0xb6, 0x5d, 0xa4, 0x6d, + 0x7, 0xef, 0x0, 0xf0, 0x3e, 0xa9, 0xd2, 0xf0, 0x49, 0x58, 0xb9, + 0x9c, 0x9c, 0xae, 0x2f, 0x1b, 0x44, 0x43, 0x7f, 0xc3, 0x1c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1784446333136569, 1973746527984364, 334856327359575, - 1156769775884610, 1023950124675478 -#else - 30322361, 26590322, 11361004, 29411115, 7433303, 4989748, - 60037442, 17237212, 57864598, 15258045 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2065270940578383, 31477096270353, 306421879113491, - 181958643936686, 1907105536686083 -#else - 13054543, 30774935, 19155473, 469045, 54626067, 4566041, - 5631406, 2711395, 1062915, 28418087 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1496516440779464, 1748485652986458, 872778352227340, - 818358834654919, 97932669284220 -#else - 47868616, 22299832, 37599834, 26054466, 61273100, 13005410, - 61042375, 12194496, 32960380, 1459310 -#endif - }}, + {0xb9, 0xae, 0xce, 0xc9, 0xf1, 0x56, 0x66, 0xd7, 0x6a, 0x65, 0xe5, + 0x18, 0xf8, 0x15, 0x5b, 0x1c, 0x34, 0x23, 0x4c, 0x84, 0x32, 0x28, + 0xe7, 0x26, 0x38, 0x68, 0x19, 0x2f, 0x77, 0x6f, 0x34, 0x3a}, + {0x4f, 0x32, 0xc7, 0x5c, 0x5a, 0x56, 0x8f, 0x50, 0x22, 0xa9, 0x6, + 0xe5, 0xc0, 0xc4, 0x61, 0xd0, 0x19, 0xac, 0x45, 0x5c, 0xdb, 0xab, + 0x18, 0xfb, 0x4a, 0x31, 0x80, 0x3, 0xc1, 0x9, 0x68, 0x6c}, + {0xc8, 0x6a, 0xda, 0xe2, 0x12, 0x51, 0xd5, 0xd2, 0xed, 0x51, 0xe8, + 0xb1, 0x31, 0x3, 0xbd, 0xe9, 0x62, 0x72, 0xc6, 0x8e, 0xdd, 0x46, + 0x7, 0x96, 0xd0, 0xc5, 0xf7, 0x6e, 0x9f, 0x1b, 0x91, 0x5}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 471636015770351, 672455402793577, 1804995246884103, - 1842309243470804, 1501862504981682 -#else - 19852015, 7027924, 23669353, 10020366, 8586503, 26896525, - 394196, 27452547, 18638002, 22379495 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1013216974933691, 538921919682598, 1915776722521558, - 1742822441583877, 1886550687916656 -#else - 31395515, 15098109, 26581030, 8030562, 50580950, 28547297, - 9012485, 25970078, 60465776, 28111795 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2094270000643336, 303971879192276, 40801275554748, - 649448917027930, 1818544418535447 -#else - 57916680, 31207054, 65111764, 4529533, 25766844, 607986, - 67095642, 9677542, 34813975, 27098423 -#endif - }}, + {0xef, 0xea, 0x2e, 0x51, 0xf3, 0xac, 0x49, 0x53, 0x49, 0xcb, 0xc1, + 0x1c, 0xd3, 0x41, 0xc1, 0x20, 0x8d, 0x68, 0x9a, 0xa9, 0x7, 0xc, + 0x18, 0x24, 0x17, 0x2d, 0x4b, 0xc6, 0xd1, 0xf9, 0x5e, 0x55}, + {0xbb, 0xe, 0xdf, 0xf5, 0x83, 0x99, 0x33, 0xc1, 0xac, 0x4c, 0x2c, + 0x51, 0x8f, 0x75, 0xf3, 0xc0, 0xe1, 0x98, 0xb3, 0xb, 0xa, 0x13, + 0xf1, 0x2c, 0x62, 0xc, 0x27, 0xaa, 0xf9, 0xec, 0x3c, 0x6b}, + {0x8, 0xbd, 0x73, 0x3b, 0xba, 0x70, 0xa7, 0x36, 0xc, 0xbf, 0xaf, + 0xa3, 0x8, 0xef, 0x4a, 0x62, 0xf2, 0x46, 0x9, 0xb4, 0x98, 0xff, + 0x37, 0x57, 0x9d, 0x74, 0x81, 0x33, 0xe1, 0x4d, 0x5f, 0x67}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2241737709499165, 549397817447461, 838180519319392, - 1725686958520781, 1705639080897747 -#else - 64664349, 33404494, 29348901, 8186665, 1873760, 12489863, - 36174285, 25714739, 59256019, 25416002 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1216074541925116, 50120933933509, 1565829004133810, - 721728156134580, 349206064666188 -#else - 51872508, 18120922, 7766469, 746860, 26346930, 23332670, - 39775412, 10754587, 57677388, 5203575 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 948617110470858, 346222547451945, 1126511960599975, - 1759386906004538, 493053284802266 -#else - 31834314, 14135496, 66338857, 5159117, 20917671, 16786336, - 59640890, 26216907, 31809242, 7347066 -#endif - }}, + {0x1d, 0xb3, 0xda, 0x3b, 0xd9, 0xf6, 0x2f, 0xa1, 0xfe, 0x2d, 0x65, + 0x9d, 0xf, 0xd8, 0x25, 0x7, 0x87, 0x94, 0xbe, 0x9a, 0xf3, 0x4f, + 0x9c, 0x1, 0x43, 0x3c, 0xcd, 0x82, 0xb8, 0x50, 0xf4, 0x60}, + {0xfc, 0x82, 0x17, 0x6b, 0x3, 0x52, 0x2c, 0xe, 0xb4, 0x83, 0xad, + 0x6c, 0x81, 0x6c, 0x81, 0x64, 0x3e, 0x7, 0x64, 0x69, 0xd9, 0xbd, + 0xdc, 0xd0, 0x20, 0xc5, 0x64, 0x1, 0xf7, 0x9d, 0xd9, 0x13}, + {0xca, 0xc0, 0xe5, 0x21, 0xc3, 0x5e, 0x4b, 0x1, 0xa2, 0xbf, 0x19, + 0xd7, 0xc9, 0x69, 0xcb, 0x4f, 0xa0, 0x23, 0x0, 0x75, 0x18, 0x1c, + 0x5f, 0x4e, 0x80, 0xac, 0xed, 0x55, 0x9e, 0xde, 0x6, 0x1c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1454933046815146, 874696014266362, 1467170975468588, - 1432316382418897, 2111710746366763 -#else - 57502122, 21680191, 20414458, 13033986, 13716524, 21862551, - 19797969, 21343177, 15192875, 31466942 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2105387117364450, 1996463405126433, 1303008614294500, - 851908115948209, 1353742049788635 -#else - 54445282, 31372712, 1168161, 29749623, 26747876, 19416341, - 10609329, 12694420, 33473243, 20172328 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 750300956351719, 1487736556065813, 15158817002104, - 1511998221598392, 971739901354129 -#else - 33184999, 11180355, 15832085, 22169002, 65475192, 225883, - 15089336, 22530529, 60973201, 14480052 -#endif - }}, + {0xaa, 0x69, 0x6d, 0xff, 0x40, 0x2b, 0xd5, 0xff, 0xbb, 0x49, 0x40, + 0xdc, 0x18, 0xb, 0x53, 0x34, 0x97, 0x98, 0x4d, 0xa3, 0x2f, 0x5c, + 0x4a, 0x5e, 0x2d, 0xba, 0x32, 0x7d, 0x8e, 0x6f, 0x9, 0x78}, + {0xe2, 0xc4, 0x3e, 0xa3, 0xd6, 0x7a, 0xf, 0x99, 0x8e, 0xe0, 0x2e, + 0xbe, 0x38, 0xf9, 0x8, 0x66, 0x15, 0x45, 0x28, 0x63, 0xc5, 0x43, + 0xa1, 0x9c, 0xd, 0xb6, 0x2d, 0xec, 0x1f, 0x8a, 0xf3, 0x4c}, + {0xe7, 0x5c, 0xfa, 0xd, 0x65, 0xaa, 0xaa, 0xa0, 0x8c, 0x47, 0xb5, + 0x48, 0x2a, 0x9e, 0xc4, 0xf9, 0x5b, 0x72, 0x3, 0x70, 0x7d, 0xcc, + 0x9, 0x4f, 0xbe, 0x1a, 0x9, 0x26, 0x3a, 0xad, 0x3c, 0x37}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1874648163531693, 2124487685930551, 1810030029384882, - 918400043048335, 586348627300650 -#else - 31308717, 27934434, 31030839, 31657333, 15674546, 26971549, - 5496207, 13685227, 27595050, 8737275 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1235084464747900, 1166111146432082, 1745394857881591, - 1405516473883040, 4463504151617 -#else - 46790012, 18404192, 10933842, 17376410, 8335351, 26008410, - 36100512, 20943827, 26498113, 66511 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1663810156463827, 327797390285791, 1341846161759410, - 1964121122800605, 1747470312055380 -#else - 22644435, 24792703, 50437087, 4884561, 64003250, 19995065, - 30540765, 29267685, 53781076, 26039336 -#endif - }}, + {0xad, 0xbb, 0xdd, 0x89, 0xfb, 0xa8, 0xbe, 0xf1, 0xcb, 0xae, 0xae, + 0x61, 0xbc, 0x2c, 0xcb, 0x3b, 0x9d, 0x8d, 0x9b, 0x1f, 0xbb, 0xa7, + 0x58, 0x8f, 0x86, 0xa6, 0x12, 0x51, 0xda, 0x7e, 0x54, 0x21}, + {0x7c, 0xf5, 0xc9, 0x82, 0x4d, 0x63, 0x94, 0xb2, 0x36, 0x45, 0x93, + 0x24, 0xe1, 0xfd, 0xcb, 0x1f, 0x5a, 0xdb, 0x8c, 0x41, 0xb3, 0x4d, + 0x9c, 0x9e, 0xfc, 0x19, 0x44, 0x45, 0xd9, 0xf3, 0x40, 0x0}, + {0xd3, 0x86, 0x59, 0xfd, 0x39, 0xe9, 0xfd, 0xde, 0xc, 0x38, 0xa, + 0x51, 0x89, 0x2c, 0x27, 0xf4, 0xb9, 0x19, 0x31, 0xbb, 0x7, 0xa4, + 0x2b, 0xb7, 0xf4, 0x4d, 0x25, 0x4a, 0x33, 0xa, 0x55, 0x63}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 660005247548233, 2071860029952887, 1358748199950107, - 911703252219107, 1014379923023831 -#else - 39091017, 9834844, 18617207, 30873120, 63706907, 20246925, - 8205539, 13585437, 49981399, 15115438 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2206641276178231, 1690587809721504, 1600173622825126, - 2156096097634421, 1106822408548216 -#else - 23711543, 32881517, 31206560, 25191721, 6164646, 23844445, - 33572981, 32128335, 8236920, 16492939 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1344788193552206, 1949552134239140, 1735915881729557, - 675891104100469, 1834220014427292 -#else - 43198286, 20038905, 40809380, 29050590, 25005589, 25867162, - 19574901, 10071562, 6708380, 27332008 -#endif - }}, + {0x49, 0x7b, 0x54, 0x72, 0x45, 0x58, 0xba, 0x9b, 0xe0, 0x8, 0xc4, + 0xe2, 0xfa, 0xc6, 0x5, 0xf3, 0x8d, 0xf1, 0x34, 0xc7, 0x69, 0xfa, + 0xe8, 0x60, 0x7a, 0x76, 0x7d, 0xaa, 0xaf, 0x2b, 0xa9, 0x39}, + {0x37, 0xcf, 0x69, 0xb5, 0xed, 0xd6, 0x7, 0x65, 0xe1, 0x2e, 0xa5, + 0xc, 0xb0, 0x29, 0x84, 0x17, 0x5d, 0xd6, 0x6b, 0xeb, 0x90, 0x0, + 0x7c, 0xea, 0x51, 0x8f, 0xf7, 0xda, 0xc7, 0x62, 0xea, 0x3e}, + {0x4e, 0x27, 0x93, 0xe6, 0x13, 0xc7, 0x24, 0x9d, 0x75, 0xd3, 0xdb, + 0x68, 0x77, 0x85, 0x63, 0x5f, 0x9a, 0xb3, 0x8a, 0xeb, 0x60, 0x55, + 0x52, 0x70, 0xcd, 0xc4, 0xc9, 0x65, 0x6, 0x6a, 0x43, 0x68}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1920949492387964, 158885288387530, 70308263664033, - 626038464897817, 1468081726101009 -#else - 2101372, 28624378, 19702730, 2367575, 51681697, 1047674, - 5301017, 9328700, 29955601, 21876122 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 622221042073383, 1210146474039168, 1742246422343683, - 1403839361379025, 417189490895736 -#else - 3096359, 9271816, 45488000, 18032587, 52260867, 25961494, - 41216721, 20918836, 57191288, 6216607 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 22727256592983, 168471543384997, 1324340989803650, - 1839310709638189, 504999476432775 -#else - 34493015, 338662, 41913253, 2510421, 37895298, 19734218, - 24822829, 27407865, 40341383, 7525078 -#endif - }}, + {0x7c, 0x10, 0x20, 0xe8, 0x17, 0xd3, 0x56, 0x1e, 0x65, 0xe9, 0xa, + 0x84, 0x44, 0x68, 0x26, 0xc5, 0x7a, 0xfc, 0xf, 0x32, 0xc6, 0xa1, + 0xe0, 0xc1, 0x72, 0x14, 0x61, 0x91, 0x9c, 0x66, 0x73, 0x53}, + {0x27, 0x3f, 0x2f, 0x20, 0xe8, 0x35, 0x2, 0xbc, 0xb0, 0x75, 0xf9, + 0x64, 0xe2, 0x0, 0x5c, 0xc7, 0x16, 0x24, 0x8c, 0xa3, 0xd5, 0xe9, + 0xa4, 0x91, 0xf9, 0x89, 0xb7, 0x8a, 0xf6, 0xe7, 0xb6, 0x17}, + {0x57, 0x52, 0xe, 0x9a, 0xab, 0x14, 0x28, 0x5d, 0xfc, 0xb3, 0xca, + 0xc9, 0x84, 0x20, 0x8f, 0x90, 0xca, 0x1e, 0x2d, 0x5b, 0x88, 0xf5, + 0xca, 0xaf, 0x11, 0x7d, 0xf8, 0x78, 0xa6, 0xb5, 0xb4, 0x1c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1313240518756327, 1721896294296942, 52263574587266, - 2065069734239232, 804910473424630 -#else - 44042215, 19568808, 16133486, 25658254, 63719298, 778787, - 66198528, 30771936, 47722230, 11994100 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1337466662091884, 1287645354669772, 2018019646776184, - 652181229374245, 898011753211715 -#else - 21691500, 19929806, 66467532, 19187410, 3285880, 30070836, - 42044197, 9718257, 59631427, 13381417 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1969792547910734, 779969968247557, 2011350094423418, - 1823964252907487, 1058949448296945 -#else - 18445390, 29352196, 14979845, 11622458, 65381754, 29971451, - 23111647, 27179185, 28535281, 15779576 -#endif - }}, + {0xe7, 0x7, 0xa0, 0xa2, 0x62, 0xaa, 0x74, 0x6b, 0xb1, 0xc7, 0x71, + 0xf0, 0xb0, 0xe0, 0x11, 0xf3, 0x23, 0xe2, 0xb, 0x0, 0x38, 0xe4, + 0x7, 0x57, 0xac, 0x6e, 0xef, 0x82, 0x2d, 0xfd, 0xc0, 0x2d}, + {0x6c, 0xfc, 0x4a, 0x39, 0x6b, 0xc0, 0x64, 0xb6, 0xb1, 0x5f, 0xda, + 0x98, 0x24, 0xde, 0x88, 0xc, 0x34, 0xd8, 0xca, 0x4b, 0x16, 0x3, + 0x8d, 0x4f, 0xa2, 0x34, 0x74, 0xde, 0x78, 0xca, 0xb, 0x33}, + {0x4e, 0x74, 0x19, 0x11, 0x84, 0xff, 0x2e, 0x98, 0x24, 0x47, 0x7, + 0x2b, 0x96, 0x5e, 0x69, 0xf9, 0xfb, 0x53, 0xc9, 0xbf, 0x4f, 0xc1, + 0x8a, 0xc5, 0xf5, 0x1c, 0x9f, 0x36, 0x1b, 0xbe, 0x31, 0x3c}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 207343737062002, 1118176942430253, 758894594548164, - 806764629546266, 1157700123092949 -#else - 30098034, 3089662, 57874477, 16662134, 45801924, 11308410, - 53040410, 12021729, 9955285, 17251076 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1273565321399022, 1638509681964574, 759235866488935, - 666015124346707, 897983460943405 -#else - 9734894, 18977602, 59635230, 24415696, 2060391, 11313496, - 48682835, 9924398, 20194861, 13380996 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1717263794012298, 1059601762860786, 1837819172257618, - 1054130665797229, 680893204263559 -#else - 40730762, 25589224, 44941042, 15789296, 49053522, 27385639, - 65123949, 15707770, 26342023, 10146099 -#endif - }}, + {0x72, 0x42, 0xcb, 0xf9, 0x93, 0xbc, 0x68, 0xc1, 0x98, 0xdb, 0xce, + 0xc7, 0x1f, 0x71, 0xb8, 0xae, 0x7a, 0x8d, 0xac, 0x34, 0xaa, 0x52, + 0xe, 0x7f, 0xbb, 0x55, 0x7d, 0x7e, 0x9, 0xc1, 0xce, 0x41}, + {0xee, 0x8a, 0x94, 0x8, 0x4d, 0x86, 0xf4, 0xb0, 0x6f, 0x1c, 0xba, + 0x91, 0xee, 0x19, 0xdc, 0x7, 0x58, 0xa1, 0xac, 0xa6, 0xae, 0xcd, + 0x75, 0x79, 0xbb, 0xd4, 0x62, 0x42, 0x13, 0x61, 0xb, 0x33}, + {0x8a, 0x80, 0x6d, 0xa2, 0xd7, 0x19, 0x96, 0xf7, 0x6d, 0x15, 0x9e, + 0x1d, 0x9e, 0xd4, 0x1f, 0xbb, 0x27, 0xdf, 0xa1, 0xdb, 0x6c, 0xc3, + 0xd7, 0x73, 0x7d, 0x77, 0x28, 0x1f, 0xd9, 0x4c, 0xb4, 0x26}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2237039662793603, 2249022333361206, 2058613546633703, - 149454094845279, 2215176649164582 -#else - 41091971, 33334488, 21339190, 33513044, 19745255, 30675732, - 37471583, 2227039, 21612326, 33008704 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 79472182719605, 1851130257050174, 1825744808933107, - 821667333481068, 781795293511946 -#else - 54031477, 1184227, 23562814, 27583990, 46757619, 27205717, - 25764460, 12243797, 46252298, 11649657 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 755822026485370, 152464789723500, 1178207602290608, - 410307889503239, 156581253571278 -#else - 57077370, 11262625, 27384172, 2271902, 26947504, 17556661, - 39943, 6114064, 33514190, 2333242 -#endif - }}, + {0x83, 0x3, 0x73, 0x62, 0x93, 0xf2, 0xb7, 0xe1, 0x2c, 0x8a, 0xca, + 0xeb, 0xff, 0x79, 0x52, 0x4b, 0x14, 0x13, 0xd4, 0xbf, 0x8a, 0x77, + 0xfc, 0xda, 0xf, 0x61, 0x72, 0x9c, 0x14, 0x10, 0xeb, 0x7d}, + {0x75, 0x74, 0x38, 0x8f, 0x47, 0x48, 0xf0, 0x51, 0x3c, 0xcb, 0xbe, + 0x9c, 0xf4, 0xbc, 0x5d, 0xb2, 0x55, 0x20, 0x9f, 0xd9, 0x44, 0x12, + 0xab, 0x9a, 0xd6, 0xa5, 0x10, 0x1c, 0x6c, 0x9e, 0x70, 0x2c}, + {0x7a, 0xee, 0x66, 0x87, 0x6a, 0xaf, 0x62, 0xcb, 0xe, 0xcd, 0x53, + 0x55, 0x4, 0xec, 0xcb, 0x66, 0xb5, 0xe4, 0xb, 0xf, 0x38, 0x1, + 0x80, 0x58, 0xea, 0xe2, 0x2c, 0xf6, 0x9f, 0x8e, 0xe6, 0x8}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1418185496130297, 484520167728613, 1646737281442950, - 1401487684670265, 1349185550126961 -#else - 45675257, 21132610, 8119781, 7219913, 45278342, 24538297, - 60429113, 20883793, 24350577, 20104431 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1495380034400429, 325049476417173, 46346894893933, - 1553408840354856, 828980101835683 -#else - 62992557, 22282898, 43222677, 4843614, 37020525, 690622, - 35572776, 23147595, 8317859, 12352766 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1280337889310282, 2070832742866672, 1640940617225222, - 2098284908289951, 450929509534434 -#else - 18200138, 19078521, 34021104, 30857812, 43406342, 24451920, - 43556767, 31266881, 20712162, 6719373 -#endif - }}, + {0xf9, 0xf2, 0xb8, 0xa, 0xd5, 0x9, 0x2d, 0x2f, 0xdf, 0x23, 0x59, + 0xc5, 0x8d, 0x21, 0xb9, 0xac, 0xb9, 0x6c, 0x76, 0x73, 0x26, 0x34, + 0x8f, 0x4a, 0xf5, 0x19, 0xf7, 0x38, 0xd7, 0x3b, 0xb1, 0x4c}, + {0xad, 0x30, 0xc1, 0x4b, 0xa, 0x50, 0xad, 0x34, 0x9c, 0xd4, 0xb, + 0x3d, 0x49, 0xdb, 0x38, 0x8d, 0xbe, 0x89, 0xa, 0x50, 0x98, 0x3d, + 0x5c, 0xa2, 0x9, 0x3b, 0xba, 0xee, 0x87, 0x3f, 0x1f, 0x2f}, + {0x4a, 0xb6, 0x15, 0xe5, 0x75, 0x8c, 0x84, 0xf7, 0x38, 0x90, 0x4a, + 0xdb, 0xba, 0x1, 0x95, 0xa5, 0x50, 0x1b, 0x75, 0x3f, 0x3f, 0x31, + 0xd, 0xc2, 0xe8, 0x2e, 0xae, 0xc0, 0x53, 0xe3, 0xa1, 0x19}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 407703353998781, 126572141483652, 286039827513621, - 1999255076709338, 2030511179441770 -#else - 26656189, 6075253, 59250308, 1886071, 38764821, 4262325, - 11117530, 29791222, 26224234, 30256974 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1254958221100483, 1153235960999843, 942907704968834, - 637105404087392, 1149293270147267 -#else - 49939907, 18700334, 63713187, 17184554, 47154818, 14050419, - 21728352, 9493610, 18620611, 17125804 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 894249020470196, 400291701616810, 406878712230981, - 1599128793487393, 1145868722604026 -#else - 53785524, 13325348, 11432106, 5964811, 18609221, 6062965, - 61839393, 23828875, 36407290, 17074774 -#endif - }}, + {0xbd, 0xbd, 0x96, 0xd5, 0xcd, 0x72, 0x21, 0xb4, 0x40, 0xfc, 0xee, + 0x98, 0x43, 0x45, 0xe0, 0x93, 0xb5, 0x9, 0x41, 0xb4, 0x47, 0x53, + 0xb1, 0x9f, 0x34, 0xae, 0x66, 0x2, 0x99, 0xd3, 0x6b, 0x73}, + {0xc3, 0x5, 0xfa, 0xba, 0x60, 0x75, 0x1c, 0x7d, 0x61, 0x5e, 0xe5, + 0xc6, 0xa0, 0xa0, 0xe1, 0xb3, 0x73, 0x64, 0xd6, 0xc0, 0x18, 0x97, + 0x52, 0xe3, 0x86, 0x34, 0xc, 0xc2, 0x11, 0x6b, 0x54, 0x41}, + {0xb4, 0xb3, 0x34, 0x93, 0x50, 0x2d, 0x53, 0x85, 0x73, 0x65, 0x81, + 0x60, 0x4b, 0x11, 0xfd, 0x46, 0x75, 0x83, 0x5c, 0x42, 0x30, 0x5f, + 0x5f, 0xcc, 0x5c, 0xab, 0x7f, 0xb8, 0xa2, 0x95, 0x22, 0x41}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1497955250203334, 110116344653260, 1128535642171976, - 1900106496009660, 129792717460909 -#else - 43248326, 22321272, 26961356, 1640861, 34695752, 16816491, - 12248508, 28313793, 13735341, 1934062 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 452487513298665, 1352120549024569, 1173495883910956, - 1999111705922009, 367328130454226 -#else - 25089769, 6742589, 17081145, 20148166, 21909292, 17486451, - 51972569, 29789085, 45830866, 5473615 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1717539401269642, 1475188995688487, 891921989653942, - 836824441505699, 1885988485608364 -#else - 31883658, 25593331, 1083431, 21982029, 22828470, 13290673, - 59983779, 12469655, 29111212, 28103418 -#endif - }}, + {0xc6, 0xea, 0x93, 0xe2, 0x61, 0x52, 0x65, 0x2e, 0xdb, 0xac, 0x33, + 0x21, 0x3, 0x92, 0x5a, 0x84, 0x6b, 0x99, 0x0, 0x79, 0xcb, 0x75, + 0x9, 0x46, 0x80, 0xdd, 0x5a, 0x19, 0x8d, 0xbb, 0x60, 0x7}, + {0xe9, 0xd6, 0x7e, 0xf5, 0x88, 0x9b, 0xc9, 0x19, 0x25, 0xc8, 0xf8, + 0x6d, 0x26, 0xcb, 0x93, 0x53, 0x73, 0xd2, 0xa, 0xb3, 0x13, 0x32, + 0xee, 0x5c, 0x34, 0x2e, 0x2d, 0xb5, 0xeb, 0x53, 0xe1, 0x14}, + {0x8a, 0x81, 0xe6, 0xcd, 0x17, 0x1a, 0x3e, 0x41, 0x84, 0xa0, 0x69, + 0xed, 0xa9, 0x6d, 0x15, 0x57, 0xb1, 0xcc, 0xca, 0x46, 0x8f, 0x26, + 0xbf, 0x2c, 0xf2, 0xc5, 0x3a, 0xc3, 0x9b, 0xbe, 0x34, 0x6b}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1241784121422547, 187337051947583, 1118481812236193, - 428747751936362, 30358898927325 -#else - 24244947, 18504025, 40845887, 2791539, 52111265, 16666677, - 24367466, 6388839, 56813277, 452382 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2022432361201842, 1088816090685051, 1977843398539868, - 1854834215890724, 564238862029357 -#else - 41468082, 30136590, 5217915, 16224624, 19987036, 29472163, - 42872612, 27639183, 15766061, 8407814 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 938868489100585, 1100285072929025, 1017806255688848, - 1957262154788833, 152787950560442 -#else - 46701865, 13990230, 15495425, 16395525, 5377168, 15166495, - 58191841, 29165478, 59040954, 2276717 -#endif - }}, + {0xd3, 0xf2, 0x71, 0x65, 0x65, 0x69, 0xfc, 0x11, 0x7a, 0x73, 0xe, + 0x53, 0x45, 0xe8, 0xc9, 0xc6, 0x35, 0x50, 0xfe, 0xd4, 0xa2, 0xe7, + 0x3a, 0xe3, 0xb, 0xd3, 0x6d, 0x2e, 0xb6, 0xc7, 0xb9, 0x1}, + {0xb2, 0xc0, 0x78, 0x3a, 0x64, 0x2f, 0xdf, 0xf3, 0x7c, 0x2, 0x2e, + 0xf2, 0x1e, 0x97, 0x3e, 0x4c, 0xa3, 0xb5, 0xc1, 0x49, 0x5e, 0x1c, + 0x7d, 0xec, 0x2d, 0xdd, 0x22, 0x9, 0x8f, 0xc1, 0x12, 0x20}, + {0x29, 0x9d, 0xc8, 0x5a, 0xe5, 0x55, 0xb, 0x88, 0x63, 0xa7, 0xa0, + 0x45, 0x1f, 0x24, 0x83, 0x14, 0x1f, 0x6c, 0xe7, 0xc2, 0xdf, 0xef, + 0x36, 0x3d, 0xe8, 0xad, 0x4b, 0x4e, 0x78, 0x5b, 0xaf, 0x8}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 867319417678923, 620471962942542, 226032203305716, - 342001443957629, 1761675818237336 -#else - 30157899, 12924066, 49396814, 9245752, 19895028, 3368142, - 43281277, 5096218, 22740376, 26251015 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1295072362439987, 931227904689414, 1355731432641687, - 922235735834035, 892227229410209 -#else - 2041139, 19298082, 7783686, 13876377, 41161879, 20201972, - 24051123, 13742383, 51471265, 13295221 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1680989767906154, 535362787031440, 2136691276706570, - 1942228485381244, 1267350086882274 -#else - 33338218, 25048699, 12532112, 7977527, 9106186, 31839181, - 49388668, 28941459, 62657506, 18884987 -#endif - }}, + {0x4b, 0x2c, 0xcc, 0x89, 0xd2, 0x14, 0x73, 0xe2, 0x8d, 0x17, 0x87, + 0xa2, 0x11, 0xbd, 0xe4, 0x4b, 0xce, 0x64, 0x33, 0xfa, 0xd6, 0x28, + 0xd5, 0x18, 0x6e, 0x82, 0xd9, 0xaf, 0xd5, 0xc1, 0x23, 0x64}, + {0x33, 0x25, 0x1f, 0x88, 0xdc, 0x99, 0x34, 0x28, 0xb6, 0x23, 0x93, + 0x77, 0xda, 0x25, 0x5, 0x9d, 0xf4, 0x41, 0x34, 0x67, 0xfb, 0xdd, + 0x7a, 0x89, 0x8d, 0x16, 0x3a, 0x16, 0x71, 0x9d, 0xb7, 0x32}, + {0x6a, 0xb3, 0xfc, 0xed, 0xd9, 0xf8, 0x85, 0xcc, 0xf9, 0xe5, 0x46, + 0x37, 0x8f, 0xc2, 0xbc, 0x22, 0xcd, 0xd3, 0xe5, 0xf9, 0x38, 0xe3, + 0x9d, 0xe4, 0xcc, 0x2d, 0x3e, 0xc1, 0xfb, 0x5e, 0xa, 0x48}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 366018233770527, 432660629755596, 126409707644535, - 1973842949591662, 645627343442376 -#else - 47063583, 5454096, 52762316, 6447145, 28862071, 1883651, - 64639598, 29412551, 7770568, 9620597 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 535509430575217, 546885533737322, 1524675609547799, - 2138095752851703, 1260738089896827 -#else - 23208049, 7979712, 33071466, 8149229, 1758231, 22719437, - 30945527, 31860109, 33606523, 18786461 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1159906385590467, 2198530004321610, 714559485023225, - 81880727882151, 1484020820037082 -#else - 1439939, 17283952, 66028874, 32760649, 4625401, 10647766, - 62065063, 1220117, 30494170, 22113633 -#endif - }}, + {0x1f, 0x22, 0xce, 0x42, 0xe4, 0x4c, 0x61, 0xb6, 0x28, 0x39, 0x5, + 0x4c, 0xcc, 0x9d, 0x19, 0x6e, 0x3, 0xbe, 0x1c, 0xdc, 0xa4, 0xb4, + 0x3f, 0x66, 0x6, 0x8e, 0x1c, 0x69, 0x47, 0x1d, 0xb3, 0x24}, + {0x71, 0x20, 0x62, 0x1, 0xb, 0xe7, 0x51, 0xb, 0xc5, 0xaf, 0x1d, + 0x8b, 0xcf, 0x5, 0xb5, 0x6, 0xcd, 0xab, 0x5a, 0xef, 0x61, 0xb0, + 0x6b, 0x2c, 0x31, 0xbf, 0xb7, 0xc, 0x60, 0x27, 0xaa, 0x47}, + {0xc3, 0xf8, 0x15, 0xc0, 0xed, 0x1e, 0x54, 0x2a, 0x7c, 0x3f, 0x69, + 0x7c, 0x7e, 0xfe, 0xa4, 0x11, 0xd6, 0x78, 0xa2, 0x4e, 0x13, 0x66, + 0xaf, 0xf0, 0x94, 0xa0, 0xdd, 0x14, 0x5d, 0x58, 0x5b, 0x54}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1377485731340769, 2046328105512000, 1802058637158797, - 62146136768173, 1356993908853901 -#else - 62071265, 20526136, 64138304, 30492664, 15640973, 26852766, - 40369837, 926049, 65424525, 20220784 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2013612215646735, 1830770575920375, 536135310219832, - 609272325580394, 270684344495013 -#else - 13908495, 30005160, 30919927, 27280607, 45587000, 7989038, - 9021034, 9078865, 3353509, 4033511 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1237542585982777, 2228682050256790, 1385281931622824, - 593183794882890, 493654978552689 -#else - 37445433, 18440821, 32259990, 33209950, 24295848, 20642309, - 23161162, 8839127, 27485041, 7356032 -#endif - }}, + {0xe1, 0x21, 0xb3, 0xe3, 0xd0, 0xe4, 0x4, 0x62, 0x95, 0x1e, 0xff, + 0x28, 0x7a, 0x63, 0xaa, 0x3b, 0x9e, 0xbd, 0x99, 0x5b, 0xfd, 0xcf, + 0xc, 0xb, 0x71, 0xd0, 0xc8, 0x64, 0x3e, 0xdc, 0x22, 0x4d}, + {0xf, 0x3a, 0xd4, 0xa0, 0x5e, 0x27, 0xbf, 0x67, 0xbe, 0xee, 0x9b, + 0x8, 0x34, 0x8e, 0xe6, 0xad, 0x2e, 0xe7, 0x79, 0xd4, 0x4c, 0x13, + 0x89, 0x42, 0x54, 0x54, 0xba, 0x32, 0xc3, 0xf9, 0x62, 0xf}, + {0x39, 0x5f, 0x3b, 0xd6, 0x89, 0x65, 0xb4, 0xfc, 0x61, 0xcf, 0xcb, + 0x57, 0x3f, 0x6a, 0xae, 0x5c, 0x5, 0xfa, 0x3a, 0x95, 0xd2, 0xc2, + 0xba, 0xfe, 0x36, 0x14, 0x37, 0x36, 0x1a, 0xa0, 0xf, 0x1c}, }, }, { { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 47341488007760, 1891414891220257, 983894663308928, - 176161768286818, 1126261115179708 -#else - 9661008, 705443, 11980065, 28184278, 65480320, 14661172, - 60762722, 2625014, 28431036, 16782598 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1694030170963455, 502038567066200, 1691160065225467, - 949628319562187, 275110186693066 -#else - 43269631, 25243016, 41163352, 7480957, 49427195, 25200248, - 44562891, 14150564, 15970762, 4099461 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1124515748676336, 1661673816593408, 1499640319059718, - 1584929449166988, 558148594103306 -#else - 29262576, 16756590, 26350592, 24760869, 8529670, 22346382, - 13617292, 23617289, 11465738, 8317062 -#endif - }}, + {0x50, 0x6a, 0x93, 0x8c, 0xe, 0x2b, 0x8, 0x69, 0xb6, 0xc5, 0xda, + 0xc1, 0x35, 0xa0, 0xc9, 0xf9, 0x34, 0xb6, 0xdf, 0xc4, 0x54, 0x3e, + 0xb7, 0x6f, 0x40, 0xc1, 0x2b, 0x1d, 0x9b, 0x41, 0x5, 0x40}, + {0xff, 0x3d, 0x94, 0x22, 0xb6, 0x4, 0xc6, 0xd2, 0xa0, 0xb3, 0xcf, + 0x44, 0xce, 0xbe, 0x8c, 0xbc, 0x78, 0x86, 0x80, 0x97, 0xf3, 0x4f, + 0x25, 0x5d, 0xbf, 0xa6, 0x1c, 0x3b, 0x4f, 0x61, 0xa3, 0xf}, + {0xf0, 0x82, 0xbe, 0xb9, 0xbd, 0xfe, 0x3, 0xa0, 0x90, 0xac, 0x44, + 0x3a, 0xaf, 0xc1, 0x89, 0x20, 0x8e, 0xfa, 0x54, 0x19, 0x91, 0x9f, + 0x49, 0xf8, 0x42, 0xab, 0x40, 0xef, 0x8a, 0x21, 0xba, 0x1f}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1784525599998356, 1619698033617383, 2097300287550715, - 258265458103756, 1905684794832758 -#else - 41615764, 26591503, 32500199, 24135381, 44070139, 31252209, - 14898636, 3848455, 20969334, 28396916 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1288941072872766, 931787902039402, 190731008859042, - 2006859954667190, 1005931482221702 -#else - 46724414, 19206718, 48772458, 13884721, 34069410, 2842113, - 45498038, 29904543, 11177094, 14989547 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1465551264822703, 152905080555927, 680334307368453, - 173227184634745, 666407097159852 -#else - 42612143, 21838415, 16959895, 2278463, 12066309, 10137771, - 13515641, 2581286, 38621356, 9930239 -#endif - }}, + {0x94, 0x1, 0x7b, 0x3e, 0x4, 0x57, 0x3e, 0x4f, 0x7f, 0xaf, 0xda, + 0x8, 0xee, 0x3e, 0x1d, 0xa8, 0xf1, 0xde, 0xdc, 0x99, 0xab, 0xc6, + 0x39, 0xc8, 0xd5, 0x61, 0x77, 0xff, 0x13, 0x5d, 0x53, 0x6c}, + {0x3e, 0xf5, 0xc8, 0xfa, 0x48, 0x94, 0x54, 0xab, 0x41, 0x37, 0xa6, + 0x7b, 0x9a, 0xe8, 0xf6, 0x81, 0x1, 0x5e, 0x2b, 0x6c, 0x7d, 0x6c, + 0xfd, 0x74, 0x42, 0x6e, 0xc8, 0xa8, 0xca, 0x3a, 0x2e, 0x39}, + {0xaf, 0x35, 0x8a, 0x3e, 0xe9, 0x34, 0xbd, 0x4c, 0x16, 0xe8, 0x87, + 0x58, 0x44, 0x81, 0x7, 0x2e, 0xab, 0xb0, 0x9a, 0xf2, 0x76, 0x9c, + 0x31, 0x19, 0x3b, 0xc1, 0xa, 0xd5, 0xe4, 0x7f, 0xe1, 0x25}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2111017076203943, 1378760485794347, 1248583954016456, - 1352289194864422, 1895180776543896 -#else - 49357223, 31456605, 16544299, 20545132, 51194056, 18605350, - 18345766, 20150679, 16291480, 28240394 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 171348223915638, 662766099800389, 462338943760497, - 466917763340314, 656911292869115 -#else - 33879670, 2553287, 32678213, 9875984, 8534129, 6889387, - 57432090, 6957616, 4368891, 9788741 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 488623681976577, 866497561541722, 1708105560937768, - 1673781214218839, 1506146329818807 -#else - 16660737, 7281060, 56278106, 12911819, 20108584, 25452756, - 45386327, 24941283, 16250551, 22443329 -#endif - }}, + {0xa7, 0x21, 0xf1, 0x76, 0xf5, 0x7f, 0x5f, 0x91, 0xe3, 0x87, 0xcd, + 0x2f, 0x27, 0x32, 0x4a, 0xc3, 0x26, 0xe5, 0x1b, 0x4d, 0xde, 0x2f, + 0xba, 0xcc, 0x9b, 0x89, 0x69, 0x89, 0x8f, 0x82, 0xba, 0x6b}, + {0x76, 0xf6, 0x4, 0x1e, 0xd7, 0x9b, 0x28, 0xa, 0x95, 0xf, 0x42, + 0xd6, 0x52, 0x1c, 0x8e, 0x20, 0xab, 0x1f, 0x69, 0x34, 0xb0, 0xd8, + 0x86, 0x51, 0x51, 0xb3, 0x9f, 0x2a, 0x44, 0x51, 0x57, 0x25}, + {0x1, 0x39, 0xfe, 0x90, 0x66, 0xbc, 0xd1, 0xe2, 0xd5, 0x7a, 0x99, + 0xa0, 0x18, 0x4a, 0xb5, 0x4c, 0xd4, 0x60, 0x84, 0xaf, 0x14, 0x69, + 0x1d, 0x97, 0xe4, 0x7b, 0x6b, 0x7f, 0x4f, 0x50, 0x9d, 0x55}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 160425464456957, 950394373239689, 430497123340934, - 711676555398832, 320964687779005 -#else - 47343357, 2390525, 50557833, 14161979, 1905286, 6414907, - 4689584, 10604807, 36918461, 4782746 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 988979367990485, 1359729327576302, 1301834257246029, - 294141160829308, 29348272277475 -#else - 65754325, 14736940, 59741422, 20261545, 7710541, 19398842, - 57127292, 4383044, 22546403, 437323 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1434382743317910, 100082049942065, 221102347892623, - 186982837860588, 1305765053501834 -#else - 31665558, 21373968, 50922033, 1491338, 48740239, 3294681, - 27343084, 2786261, 36475274, 19457415 -#endif - }}, + {0xfd, 0x66, 0xd2, 0xf6, 0xe7, 0x91, 0x48, 0x9c, 0x1b, 0x78, 0x7, + 0x3, 0x9b, 0xa1, 0x44, 0x7, 0x3b, 0xe2, 0x61, 0x60, 0x1d, 0x8f, + 0x38, 0x88, 0xe, 0xd5, 0x4b, 0x35, 0xa3, 0xa6, 0x3e, 0x12}, + {0xd5, 0x54, 0xeb, 0xb3, 0x78, 0x83, 0x73, 0xa7, 0x7c, 0x3c, 0x55, + 0xa5, 0x66, 0xd3, 0x69, 0x1d, 0xba, 0x0, 0x28, 0xf9, 0x62, 0xcf, + 0x26, 0xa, 0x17, 0x32, 0x7e, 0x80, 0xd5, 0x12, 0xab, 0x1}, + {0x96, 0x2d, 0xe3, 0x41, 0x90, 0x18, 0x8d, 0x11, 0x48, 0x58, 0x31, + 0xd8, 0xc2, 0xe3, 0xed, 0xb9, 0xd9, 0x45, 0x32, 0xd8, 0x71, 0x42, + 0xab, 0x1e, 0x54, 0xa1, 0x18, 0xc9, 0xe2, 0x61, 0x39, 0x4a}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 2205916462268190, 499863829790820, 961960554686616, - 158062762756985, 1841471168298305 -#else - 52641566, 32870716, 33734756, 7448551, 19294360, 14334329, - 47418233, 2355318, 47824193, 27440058 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1191737341426592, 1847042034978363, 1382213545049056, - 1039952395710448, 788812858896859 -#else - 15121312, 17758270, 6377019, 27523071, 56310752, 20596586, - 18952176, 15496498, 37728731, 11754227 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1346965964571152, 1291881610839830, 2142916164336056, - 786821641205979, 1571709146321039 -#else - 64471568, 20071356, 8488726, 19250536, 12728760, 31931939, - 7141595, 11724556, 22761615, 23420291 -#endif - }}, + {0x1e, 0x3f, 0x23, 0xf3, 0x44, 0xd6, 0x27, 0x3, 0x16, 0xf0, 0xfc, + 0x34, 0xe, 0x26, 0x9a, 0x49, 0x79, 0xb9, 0xda, 0xf2, 0x16, 0xa7, + 0xb5, 0x83, 0x1f, 0x11, 0xd4, 0x9b, 0xad, 0xee, 0xac, 0x68}, + {0xa0, 0xbb, 0xe6, 0xf8, 0xe0, 0x3b, 0xdc, 0x71, 0xa, 0xe3, 0xff, + 0x7e, 0x34, 0xf8, 0xce, 0xd6, 0x6a, 0x47, 0x3a, 0xe1, 0x5f, 0x42, + 0x92, 0xa9, 0x63, 0xb7, 0x1d, 0xfb, 0xe3, 0xbc, 0xd6, 0x2c}, + {0x10, 0xc2, 0xd7, 0xf3, 0xe, 0xc9, 0xb4, 0x38, 0xc, 0x4, 0xad, + 0xb7, 0x24, 0x6e, 0x8e, 0x30, 0x23, 0x3e, 0xe7, 0xb7, 0xf1, 0xd9, + 0x60, 0x38, 0x97, 0xf5, 0x8, 0xb5, 0xd5, 0x60, 0x57, 0x59}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 787164375951248, 202869205373189, 1356590421032140, - 1431233331032510, 786341368775957 -#else - 16918416, 11729663, 49025285, 3022986, 36093132, 20214772, - 38367678, 21327038, 32851221, 11717399 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 492448143532951, 304105152670757, 1761767168301056, - 233782684697790, 1981295323106089 -#else - 11166615, 7338049, 60386341, 4531519, 37640192, 26252376, - 31474878, 3483633, 65915689, 29523600 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 665807507761866, 1343384868355425, 895831046139653, - 439338948736892, 1986828765695105 -#else - 66923210, 9921304, 31456609, 20017994, 55095045, 13348922, - 33142652, 6546660, 47123585, 29606055 -#endif - }}, + {0x90, 0x27, 0x2, 0xfd, 0xeb, 0xcb, 0x2a, 0x88, 0x60, 0x57, 0x11, + 0xc4, 0x5, 0x33, 0xaf, 0x89, 0xf4, 0x73, 0x34, 0x7d, 0xe3, 0x92, + 0xf4, 0x65, 0x2b, 0x5a, 0x51, 0x54, 0xdf, 0xc5, 0xb2, 0x2c}, + {0x97, 0x63, 0xaa, 0x4, 0xe1, 0xbf, 0x29, 0x61, 0xcb, 0xfc, 0xa7, + 0xa4, 0x8, 0x0, 0x96, 0x8f, 0x58, 0x94, 0x90, 0x7d, 0x89, 0xc0, + 0x8b, 0x3f, 0xa9, 0x91, 0xb2, 0xdc, 0x3e, 0xa4, 0x9f, 0x70}, + {0xca, 0x2a, 0xfd, 0x63, 0x8c, 0x5d, 0xa, 0xeb, 0xff, 0x4e, 0x69, + 0x2e, 0x66, 0xc1, 0x2b, 0xd2, 0x3a, 0xb0, 0xcb, 0xf8, 0x6e, 0xf3, + 0x23, 0x27, 0x1f, 0x13, 0xc8, 0xf0, 0xec, 0x29, 0xf0, 0x70}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 756096210874553, 1721699973539149, 258765301727885, - 1390588532210645, 1212530909934781 -#else - 34648249, 11266711, 55911757, 25655328, 31703693, 3855903, - 58571733, 20721383, 36336829, 18068118 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 852891097972275, 1816988871354562, 1543772755726524, - 1174710635522444, 202129090724628 -#else - 49102387, 12709067, 3991746, 27075244, 45617340, 23004006, - 35973516, 17504552, 10928916, 3011958 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1205281565824323, 22430498399418, 992947814485516, - 1392458699738672, 688441466734558 -#else - 60151107, 17960094, 31696058, 334240, 29576716, 14796075, - 36277808, 20749251, 18008030, 10258577 -#endif - }}, + {0xb9, 0xb0, 0x10, 0x5e, 0xaa, 0xaf, 0x6a, 0x2a, 0xa9, 0x1a, 0x4, + 0xef, 0x70, 0xa3, 0xf0, 0x78, 0x1f, 0xd6, 0x3a, 0xaa, 0x77, 0xfb, + 0x3e, 0x77, 0xe1, 0xd9, 0x4b, 0xa7, 0xa2, 0xa5, 0xec, 0x44}, + {0x33, 0x3e, 0xed, 0x2e, 0xb3, 0x7, 0x13, 0x46, 0xe7, 0x81, 0x55, + 0xa4, 0x33, 0x2f, 0x4, 0xae, 0x66, 0x3, 0x5f, 0x19, 0xd3, 0x49, + 0x44, 0xc9, 0x58, 0x48, 0x31, 0x6c, 0x8a, 0x5d, 0x7d, 0xb}, + {0x43, 0xd5, 0x95, 0x7b, 0x32, 0x48, 0xd4, 0x25, 0x1d, 0xf, 0x34, + 0xa3, 0x0, 0x83, 0xd3, 0x70, 0x2b, 0xc5, 0xe1, 0x60, 0x1c, 0x53, + 0x1c, 0xde, 0xe4, 0xe9, 0x7d, 0x2c, 0x51, 0x24, 0x22, 0x27}, }, { - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1050627428414972, 1955849529137135, 2171162376368357, - 91745868298214, 447733118757826 -#else - 44660220, 15655568, 7018479, 29144429, 36794597, 32352840, - 65255398, 1367119, 25127874, 6671743 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1287181461435438, 622722465530711, 880952150571872, - 741035693459198, 311565274989772 -#else - 29701166, 19180498, 56230743, 9279287, 67091296, 13127209, - 21382910, 11042292, 25838796, 4642684 -#endif - }}, - {{ -#if defined(BORINGSSL_CURVE25519_64BIT) - 1003649078149734, 545233927396469, 1849786171789880, - 1318943684880434, 280345687170552 -#else - 46678630, 14955536, 42982517, 8124618, 61739576, 27563961, - 30468146, 19653792, 18423288, 4177476 -#endif - }}, + {0xfc, 0x75, 0xa9, 0x42, 0x8a, 0xbb, 0x7b, 0xbf, 0x58, 0xa3, 0xad, + 0x96, 0x77, 0x39, 0x5c, 0x8c, 0x48, 0xaa, 0xed, 0xcd, 0x6f, 0xc7, + 0x7f, 0xe2, 0xa6, 0x20, 0xbc, 0xf6, 0xd7, 0x5f, 0x73, 0x19}, + {0x2e, 0x34, 0xc5, 0x49, 0xaf, 0x92, 0xbc, 0x1a, 0xd0, 0xfa, 0xe6, + 0xb2, 0x11, 0xd8, 0xee, 0xff, 0x29, 0x4e, 0xc8, 0xfc, 0x8d, 0x8c, + 0xa2, 0xef, 0x43, 0xc5, 0x4c, 0xa4, 0x18, 0xdf, 0xb5, 0x11}, + {0x66, 0x42, 0xc8, 0x42, 0xd0, 0x90, 0xab, 0xe3, 0x7e, 0x54, 0x19, + 0x7f, 0xf, 0x8e, 0x84, 0xeb, 0xb9, 0x97, 0xa4, 0x65, 0xd0, 0xa1, + 0x3, 0x25, 0x5f, 0x89, 0xdf, 0x91, 0x11, 0x91, 0xef, 0xf}, }, }, }; @@ -7639,7 +3031,7 @@ static const ge_precomp k25519Precomp[32][8] = { static const ge_precomp Bi[8] = { { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 #else @@ -7648,7 +3040,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 #else @@ -7657,7 +3049,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 #else @@ -7668,7 +3060,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 #else @@ -7677,7 +3069,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 #else @@ -7686,7 +3078,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 #else @@ -7697,7 +3089,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 #else @@ -7706,7 +3098,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 #else @@ -7715,7 +3107,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 #else @@ -7726,7 +3118,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 #else @@ -7735,7 +3127,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 #else @@ -7744,7 +3136,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 #else @@ -7755,7 +3147,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1802695059465007, 1664899123557221, 593559490740857, 2160434469266659, 927570450755031 #else @@ -7764,7 +3156,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1725674970513508, 1933645953859181, 1542344539275782, 1767788773573747, 1297447965928905 #else @@ -7773,7 +3165,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624 #else @@ -7784,7 +3176,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1970894096313054, 528066325833207, 1619374932191227, 2207306624415883, 1169170329061080 #else @@ -7793,7 +3185,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 2070390218572616, 1458919061857835, 624171843017421, 1055332792707765, 433987520732508 #else @@ -7802,7 +3194,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815 #else @@ -7813,7 +3205,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 213454002618221, 939771523987438, 1159882208056014, 317388369627517, 621213314200687 #else @@ -7822,7 +3214,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1971678598905747, 338026507889165, 762398079972271, 655096486107477, 42299032696322 #else @@ -7831,7 +3223,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791 #else @@ -7842,7 +3234,7 @@ static const ge_precomp Bi[8] = { }, { {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1913163449625248, 460779200291993, 2193883288642314, 1008900146920800, 1721983679009502 #else @@ -7851,7 +3243,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 1070401523076875, 1272492007800961, 1910153608563310, 2075579521696771, 1191169788841221 #else @@ -7860,7 +3252,7 @@ static const ge_precomp Bi[8] = { #endif }}, {{ -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) 692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901 #else diff --git a/third_party/boringssl/kit/src/crypto/curve25519/ed25519_test.cc b/third_party/boringssl/kit/src/crypto/curve25519/ed25519_test.cc index d56abe68..0b7c585c 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/ed25519_test.cc +++ b/third_party/boringssl/kit/src/crypto/curve25519/ed25519_test.cc @@ -35,9 +35,15 @@ TEST(Ed25519Test, TestVectors) { ASSERT_TRUE(t->GetBytes(&expected_signature, "SIG")); ASSERT_EQ(64u, expected_signature.size()); + // Signing should not leak the private key or the message. + CONSTTIME_SECRET(private_key.data(), private_key.size()); + CONSTTIME_SECRET(message.data(), message.size()); uint8_t signature[64]; ASSERT_TRUE(ED25519_sign(signature, message.data(), message.size(), private_key.data())); + CONSTTIME_DECLASSIFY(signature, sizeof(signature)); + CONSTTIME_DECLASSIFY(message.data(), message.size()); + EXPECT_EQ(Bytes(expected_signature), Bytes(signature)); EXPECT_TRUE(ED25519_verify(message.data(), message.size(), signature, public_key.data())); @@ -114,9 +120,12 @@ TEST(Ed25519Test, KeypairFromSeed) { uint8_t seed[32]; OPENSSL_memcpy(seed, private_key1, sizeof(seed)); + CONSTTIME_SECRET(seed, sizeof(seed)); uint8_t public_key2[32], private_key2[64]; ED25519_keypair_from_seed(public_key2, private_key2, seed); + CONSTTIME_DECLASSIFY(public_key2, sizeof(public_key2)); + CONSTTIME_DECLASSIFY(private_key2, sizeof(private_key2)); EXPECT_EQ(Bytes(public_key1), Bytes(public_key2)); EXPECT_EQ(Bytes(private_key1), Bytes(private_key2)); diff --git a/third_party/boringssl/kit/src/crypto/curve25519/internal.h b/third_party/boringssl/kit/src/crypto/curve25519/internal.h index 76ff78fa..0cd1a12a 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/internal.h +++ b/third_party/boringssl/kit/src/crypto/curve25519/internal.h @@ -15,14 +15,13 @@ #ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H #define OPENSSL_HEADER_CURVE25519_INTERNAL_H -#if defined(__cplusplus) -extern "C" { -#endif - -#include +#include #include "../internal.h" +#if defined(__cplusplus) +extern "C" { +#endif #if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) #define BORINGSSL_X25519_NEON @@ -32,11 +31,28 @@ void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]); #endif -#if defined(BORINGSSL_HAS_UINT128) -#define BORINGSSL_CURVE25519_64BIT +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && \ + defined(__GNUC__) && defined(__x86_64__) +#define BORINGSSL_FE25519_ADX + +// fiat_curve25519_adx_mul is defined in +// third_party/fiat/asm/fiat_curve25519_adx_mul.S +void __attribute__((sysv_abi)) +fiat_curve25519_adx_mul(uint64_t out[4], const uint64_t in1[4], + const uint64_t in2[4]); + +// fiat_curve25519_adx_square is defined in +// third_party/fiat/asm/fiat_curve25519_adx_square.S +void __attribute__((sysv_abi)) +fiat_curve25519_adx_square(uint64_t out[4], const uint64_t in[4]); + +// x25519_scalar_mult_adx is defined in third_party/fiat/curve25519_64_adx.h +void x25519_scalar_mult_adx(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +void x25519_ge_scalarmult_base_adx(uint8_t h[4][32], const uint8_t a[32]); #endif -#if defined(BORINGSSL_CURVE25519_64BIT) +#if defined(OPENSSL_64_BIT) // fe means field element. Here the field is \Z/(2^255-19). An element t, // entries t[0]...t[4], represents the integer t[0]+2^51 t[1]+2^102 t[2]+2^153 // t[3]+2^204 t[4]. @@ -139,6 +155,8 @@ struct spake2_ctx_st { }; +extern const uint8_t k25519Precomp[32][8][3][32]; + #if defined(__cplusplus) } // extern C #endif diff --git a/third_party/boringssl/kit/src/crypto/curve25519/make_curve25519_tables.py b/third_party/boringssl/kit/src/crypto/curve25519/make_curve25519_tables.py index 50dee2a9..c6edac2f 100755 --- a/third_party/boringssl/kit/src/crypto/curve25519/make_curve25519_tables.py +++ b/third_party/boringssl/kit/src/crypto/curve25519/make_curve25519_tables.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding=utf-8 # Copyright (c) 2020, Google Inc. # @@ -14,7 +14,7 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import StringIO +from io import StringIO import subprocess # Base field Z_p @@ -76,12 +76,7 @@ def point_mul(s, P): return Q def to_bytes(x): - ret = bytearray(32) - for i in range(len(ret)): - ret[i] = x % 256 - x >>= 8 - assert x == 0 - return ret + return x.to_bytes(32, "little") def to_ge_precomp(P): # typedef struct { @@ -109,8 +104,11 @@ def to_base_51(x): assert x == 0 return ret +def to_bytes_literal(x): + return "{" + ", ".join(map(hex, to_bytes(x))) + "}" + def to_literal(x): - ret = "{{\n#if defined(BORINGSSL_CURVE25519_64BIT)\n" + ret = "{{\n#if defined(OPENSSL_64_BIT)\n" ret += ", ".join(map(str, to_base_51(x))) ret += "\n#else\n" ret += ", ".join(map(str, to_base_25_5(x))) @@ -140,7 +138,7 @@ def main(): bi_precomp.append(to_ge_precomp(P)) - buf = StringIO.StringIO() + buf = StringIO() buf.write("""/* Copyright (c) 2020, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -190,14 +188,14 @@ static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = {""") #else // k25519Precomp[i][j] = (j+1)*256^i*B -static const ge_precomp k25519Precomp[32][8] = { +static const uint8_t k25519Precomp[32][8][3][32] = { """) for child in large_precomp: buf.write("{\n") for val in child: buf.write("{\n") for term in val: - buf.write(to_literal(term) + ",\n") + buf.write(to_bytes_literal(term) + ",\n") buf.write("},\n") buf.write("},\n") buf.write("""}; @@ -216,7 +214,7 @@ static const ge_precomp Bi[8] = { """) proc = subprocess.Popen(["clang-format"], stdin=subprocess.PIPE) - proc.communicate(buf.getvalue()) + proc.communicate(buf.getvalue().encode("utf8")) if __name__ == "__main__": main() diff --git a/third_party/boringssl/kit/src/crypto/curve25519/spake25519.c b/third_party/boringssl/kit/src/crypto/curve25519/spake25519.c index f7509114..c45d15a5 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/spake25519.c +++ b/third_party/boringssl/kit/src/crypto/curve25519/spake25519.c @@ -22,6 +22,7 @@ #include #include +#include "../fipsmodule/bn/internal.h" #include "../internal.h" #include "./internal.h" @@ -314,46 +315,30 @@ static void left_shift_3(uint8_t n[32]) { } } -typedef union { - uint8_t bytes[32]; - uint32_t words[8]; +typedef struct { + BN_ULONG words[32 / sizeof(BN_ULONG)]; } scalar; -// kOrder is the order of the prime-order subgroup of curve25519 in -// little-endian order. -static const scalar kOrder = {{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, - 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}}; +// kOrder is the order of the prime-order subgroup of curve25519. +static const scalar kOrder = { + {TOBN(0x5812631a, 0x5cf5d3ed), TOBN(0x14def9de, 0xa2f79cd6), + TOBN(0x00000000, 0x00000000), TOBN(0x10000000, 0x00000000)}}; // scalar_cmov copies |src| to |dest| if |mask| is all ones. static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { - for (size_t i = 0; i < 8; i++) { - dest->words[i] = - constant_time_select_w(mask, src->words[i], dest->words[i]); - } + bn_select_words(dest->words, mask, src->words, dest->words, + OPENSSL_ARRAY_SIZE(dest->words)); } // scalar_double sets |s| to |2×s|. static void scalar_double(scalar *s) { - uint32_t carry = 0; - - for (size_t i = 0; i < 8; i++) { - const uint32_t carry_out = s->words[i] >> 31; - s->words[i] = (s->words[i] << 1) | carry; - carry = carry_out; - } + bn_add_words(s->words, s->words, s->words, OPENSSL_ARRAY_SIZE(s->words)); } // scalar_add sets |dest| to |dest| plus |src|. static void scalar_add(scalar *dest, const scalar *src) { - uint32_t carry = 0; - - for (size_t i = 0; i < 8; i++) { - uint64_t tmp = ((uint64_t)dest->words[i] + src->words[i]) + carry; - dest->words[i] = (uint32_t)tmp; - carry = (uint32_t)(tmp >> 32); - } + bn_add_words(dest->words, dest->words, src->words, + OPENSSL_ARRAY_SIZE(dest->words)); } int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, @@ -412,25 +397,25 @@ int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, OPENSSL_memset(&tmp, 0, sizeof(tmp)); scalar_cmov(&tmp, &order, - constant_time_eq_w(password_scalar.bytes[0] & 1, 1)); + constant_time_eq_w(password_scalar.words[0] & 1, 1)); scalar_add(&password_scalar, &tmp); scalar_double(&order); OPENSSL_memset(&tmp, 0, sizeof(tmp)); scalar_cmov(&tmp, &order, - constant_time_eq_w(password_scalar.bytes[0] & 2, 2)); + constant_time_eq_w(password_scalar.words[0] & 2, 2)); scalar_add(&password_scalar, &tmp); scalar_double(&order); OPENSSL_memset(&tmp, 0, sizeof(tmp)); scalar_cmov(&tmp, &order, - constant_time_eq_w(password_scalar.bytes[0] & 4, 4)); + constant_time_eq_w(password_scalar.words[0] & 4, 4)); scalar_add(&password_scalar, &tmp); - assert((password_scalar.bytes[0] & 7) == 0); + assert((password_scalar.words[0] & 7) == 0); } - OPENSSL_memcpy(ctx->password_scalar, password_scalar.bytes, + OPENSSL_memcpy(ctx->password_scalar, password_scalar.words, sizeof(ctx->password_scalar)); ge_p3 mask; diff --git a/third_party/boringssl/kit/src/crypto/curve25519/x25519_test.cc b/third_party/boringssl/kit/src/crypto/curve25519/x25519_test.cc index 1bf398f9..c1b9e40a 100644 --- a/third_party/boringssl/kit/src/crypto/curve25519/x25519_test.cc +++ b/third_party/boringssl/kit/src/crypto/curve25519/x25519_test.cc @@ -20,14 +20,39 @@ #include +#include "internal.h" #include "../internal.h" +#include "../test/abi_test.h" #include "../test/file_test.h" #include "../test/test_util.h" #include "../test/wycheproof_util.h" +#include "internal.h" +static inline int ctwrapX25519(uint8_t out_shared_key[32], + const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { + uint8_t scalar[32], point[32]; + // Copy all the secrets into a temporary buffer, so we can run constant-time + // validation on them. + OPENSSL_memcpy(scalar, private_key, sizeof(scalar)); + OPENSSL_memcpy(point, peer_public_value, sizeof(point)); + + // X25519 should not leak the private key. + CONSTTIME_SECRET(scalar, sizeof(scalar)); + // All other inputs are also marked as secret. This is not to support any + // particular use case for calling X25519 with a secret *point*, but + // rather to ensure that the choice of the point cannot influence whether + // the scalar is leaked or not. Same for the initial contents of the + // output buffer. This conservative choice may be revised in the future. + CONSTTIME_SECRET(point, sizeof(point)); + CONSTTIME_SECRET(out_shared_key, 32); + int r = X25519(out_shared_key, scalar, point); + CONSTTIME_DECLASSIFY(out_shared_key, 32); + return r; +} TEST(X25519Test, TestVector) { - // Taken from https://tools.ietf.org/html/rfc7748#section-5.2 + // Taken from https://www.rfc-editor.org/rfc/rfc7748#section-5.2 static const uint8_t kScalar1[32] = { 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, @@ -39,9 +64,8 @@ TEST(X25519Test, TestVector) { 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, }; - uint8_t out[32]; - EXPECT_TRUE(X25519(out, kScalar1, kPoint1)); - + uint8_t out[32], secret[32]; + EXPECT_TRUE(ctwrapX25519(out, kScalar1, kPoint1)); static const uint8_t kExpected1[32] = { 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea, 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, @@ -59,15 +83,58 @@ TEST(X25519Test, TestVector) { 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93, }; - - EXPECT_TRUE(X25519(out, kScalar2, kPoint2)); - + EXPECT_TRUE(ctwrapX25519(out, kScalar2, kPoint2)); static const uint8_t kExpected2[32] = { 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4, 0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f, 0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57, }; EXPECT_EQ(Bytes(kExpected2), Bytes(out)); + + // Taken from https://www.rfc-editor.org/rfc/rfc7748.html#section-6.1 + static const uint8_t kPrivateA[32] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a, + }; + static const uint8_t kPublicA[32] = { + 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a, + }; + static const uint8_t kPrivateB[32] = { + 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, + 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, + 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb, + }; + static const uint8_t kPublicB[32] = { + 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f, + }; + static const uint8_t kSecret[32] = { + 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e, 0x3b, + 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, + 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42, + }; + + OPENSSL_memcpy(secret, kPrivateA, sizeof(secret)); + CONSTTIME_SECRET(secret, sizeof(secret)); + X25519_public_from_private(out, secret); + CONSTTIME_DECLASSIFY(out, sizeof(out)); + EXPECT_EQ(Bytes(out), Bytes(kPublicA)); + + OPENSSL_memcpy(secret, kPrivateB, sizeof(secret)); + CONSTTIME_SECRET(secret, sizeof(secret)); + X25519_public_from_private(out, secret); + CONSTTIME_DECLASSIFY(out, sizeof(out)); + EXPECT_EQ(Bytes(out), Bytes(kPublicB)); + + ctwrapX25519(out, kPrivateA, kPublicB); + EXPECT_EQ(Bytes(out), Bytes(kSecret)); + + ctwrapX25519(out, kPrivateB, kPublicA); + EXPECT_EQ(Bytes(out), Bytes(kSecret)); } TEST(X25519Test, SmallOrder) { @@ -81,7 +148,7 @@ TEST(X25519Test, SmallOrder) { OPENSSL_memset(private_key, 0x11, sizeof(private_key)); OPENSSL_memset(out, 0xff, sizeof(out)); - EXPECT_FALSE(X25519(out, private_key, kSmallOrderPoint)) + EXPECT_FALSE(ctwrapX25519(out, private_key, kSmallOrderPoint)) << "X25519 returned success with a small-order input."; // For callers which don't check, |out| should still be filled with zeros. @@ -94,7 +161,7 @@ TEST(X25519Test, Iterated) { uint8_t scalar[32] = {9}, point[32] = {9}, out[32]; for (unsigned i = 0; i < 1000; i++) { - EXPECT_TRUE(X25519(out, scalar, point)); + EXPECT_TRUE(ctwrapX25519(out, scalar, point)); OPENSSL_memcpy(point, scalar, sizeof(point)); OPENSSL_memcpy(scalar, out, sizeof(scalar)); } @@ -113,7 +180,7 @@ TEST(X25519Test, DISABLED_IteratedLarge) { uint8_t scalar[32] = {9}, point[32] = {9}, out[32]; for (unsigned i = 0; i < 1000000; i++) { - EXPECT_TRUE(X25519(out, scalar, point)); + EXPECT_TRUE(ctwrapX25519(out, scalar, point)); OPENSSL_memcpy(point, scalar, sizeof(point)); OPENSSL_memcpy(scalar, out, sizeof(scalar)); } @@ -141,9 +208,55 @@ TEST(X25519Test, Wycheproof) { ASSERT_TRUE(t->GetBytes(&shared, "shared")); ASSERT_EQ(32u, priv.size()); ASSERT_EQ(32u, pub.size()); + uint8_t secret[32]; - int ret = X25519(secret, priv.data(), pub.data()); + int ret = ctwrapX25519(secret, priv.data(), pub.data()); EXPECT_EQ(ret, result.IsValid({"NonCanonicalPublic", "Twist"}) ? 1 : 0); EXPECT_EQ(Bytes(secret), Bytes(shared)); }); } + +#if defined(BORINGSSL_X25519_NEON) && defined(SUPPORTS_ABI_TEST) +TEST(X25519Test, NeonABI) { + if (!CRYPTO_is_NEON_capable()) { + GTEST_SKIP() << "Can't test ABI of NEON code without NEON"; + } + + static const uint8_t kScalar[32] = { + 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, + 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, + 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4, + }; + static const uint8_t kPoint[32] = { + 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, + 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, + 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, + }; + uint8_t secret[32]; + CHECK_ABI(x25519_NEON, secret, kScalar, kPoint); +} +#endif // BORINGSSL_X25519_NEON && SUPPORTS_ABI_TEST + +#if defined(BORINGSSL_FE25519_ADX) && defined(SUPPORTS_ABI_TEST) +TEST(X25519Test, AdxMulABI) { + static const uint64_t in1[4] = {0}, in2[4] = {0}; + uint64_t out[4]; + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + CHECK_ABI(fiat_curve25519_adx_mul, out, in1, in2); + } else { + GTEST_SKIP() << "Can't test ABI of ADX code without ADX"; + } +} + +TEST(X25519Test, AdxSquareABI) { + static const uint64_t in[4] = {0}; + uint64_t out[4]; + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + CHECK_ABI(fiat_curve25519_adx_square, out, in); + } else { + GTEST_SKIP() << "Can't test ABI of ADX code without ADX"; + } +} +#endif // BORINGSSL_FE25519_ADX && SUPPORTS_ABI_TEST diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/des/des.c b/third_party/boringssl/kit/src/crypto/des/des.c similarity index 51% rename from third_party/boringssl/kit/src/crypto/fipsmodule/des/des.c rename to third_party/boringssl/kit/src/crypto/des/des.c index 95c430ca..a608accd 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/des/des.c +++ b/third_party/boringssl/kit/src/crypto/des/des.c @@ -63,231 +63,231 @@ static const uint32_t des_skb[8][64] = { { // for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 - 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, 0x00010000L, - 0x00010010L, 0x20010000L, 0x20010010L, 0x00000800L, 0x00000810L, - 0x20000800L, 0x20000810L, 0x00010800L, 0x00010810L, 0x20010800L, - 0x20010810L, 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, - 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, 0x00000820L, - 0x00000830L, 0x20000820L, 0x20000830L, 0x00010820L, 0x00010830L, - 0x20010820L, 0x20010830L, 0x00080000L, 0x00080010L, 0x20080000L, - 0x20080010L, 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, - 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, 0x00090800L, - 0x00090810L, 0x20090800L, 0x20090810L, 0x00080020L, 0x00080030L, - 0x20080020L, 0x20080030L, 0x00090020L, 0x00090030L, 0x20090020L, - 0x20090030L, 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, - 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, }, + 0x00000000, 0x00000010, 0x20000000, 0x20000010, 0x00010000, + 0x00010010, 0x20010000, 0x20010010, 0x00000800, 0x00000810, + 0x20000800, 0x20000810, 0x00010800, 0x00010810, 0x20010800, + 0x20010810, 0x00000020, 0x00000030, 0x20000020, 0x20000030, + 0x00010020, 0x00010030, 0x20010020, 0x20010030, 0x00000820, + 0x00000830, 0x20000820, 0x20000830, 0x00010820, 0x00010830, + 0x20010820, 0x20010830, 0x00080000, 0x00080010, 0x20080000, + 0x20080010, 0x00090000, 0x00090010, 0x20090000, 0x20090010, + 0x00080800, 0x00080810, 0x20080800, 0x20080810, 0x00090800, + 0x00090810, 0x20090800, 0x20090810, 0x00080020, 0x00080030, + 0x20080020, 0x20080030, 0x00090020, 0x00090030, 0x20090020, + 0x20090030, 0x00080820, 0x00080830, 0x20080820, 0x20080830, + 0x00090820, 0x00090830, 0x20090820, 0x20090830, }, { // for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 - 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, 0x00200000L, - 0x02200000L, 0x00202000L, 0x02202000L, 0x00000004L, 0x02000004L, - 0x00002004L, 0x02002004L, 0x00200004L, 0x02200004L, 0x00202004L, - 0x02202004L, 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, - 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, 0x00000404L, - 0x02000404L, 0x00002404L, 0x02002404L, 0x00200404L, 0x02200404L, - 0x00202404L, 0x02202404L, 0x10000000L, 0x12000000L, 0x10002000L, - 0x12002000L, 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, - 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, 0x10200004L, - 0x12200004L, 0x10202004L, 0x12202004L, 0x10000400L, 0x12000400L, - 0x10002400L, 0x12002400L, 0x10200400L, 0x12200400L, 0x10202400L, - 0x12202400L, 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, - 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, }, + 0x00000000, 0x02000000, 0x00002000, 0x02002000, 0x00200000, + 0x02200000, 0x00202000, 0x02202000, 0x00000004, 0x02000004, + 0x00002004, 0x02002004, 0x00200004, 0x02200004, 0x00202004, + 0x02202004, 0x00000400, 0x02000400, 0x00002400, 0x02002400, + 0x00200400, 0x02200400, 0x00202400, 0x02202400, 0x00000404, + 0x02000404, 0x00002404, 0x02002404, 0x00200404, 0x02200404, + 0x00202404, 0x02202404, 0x10000000, 0x12000000, 0x10002000, + 0x12002000, 0x10200000, 0x12200000, 0x10202000, 0x12202000, + 0x10000004, 0x12000004, 0x10002004, 0x12002004, 0x10200004, + 0x12200004, 0x10202004, 0x12202004, 0x10000400, 0x12000400, + 0x10002400, 0x12002400, 0x10200400, 0x12200400, 0x10202400, + 0x12202400, 0x10000404, 0x12000404, 0x10002404, 0x12002404, + 0x10200404, 0x12200404, 0x10202404, 0x12202404, }, { // for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 - 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, 0x01000000L, - 0x01000001L, 0x01040000L, 0x01040001L, 0x00000002L, 0x00000003L, - 0x00040002L, 0x00040003L, 0x01000002L, 0x01000003L, 0x01040002L, - 0x01040003L, 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, - 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, 0x00000202L, - 0x00000203L, 0x00040202L, 0x00040203L, 0x01000202L, 0x01000203L, - 0x01040202L, 0x01040203L, 0x08000000L, 0x08000001L, 0x08040000L, - 0x08040001L, 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, - 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, 0x09000002L, - 0x09000003L, 0x09040002L, 0x09040003L, 0x08000200L, 0x08000201L, - 0x08040200L, 0x08040201L, 0x09000200L, 0x09000201L, 0x09040200L, - 0x09040201L, 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, - 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, }, + 0x00000000, 0x00000001, 0x00040000, 0x00040001, 0x01000000, + 0x01000001, 0x01040000, 0x01040001, 0x00000002, 0x00000003, + 0x00040002, 0x00040003, 0x01000002, 0x01000003, 0x01040002, + 0x01040003, 0x00000200, 0x00000201, 0x00040200, 0x00040201, + 0x01000200, 0x01000201, 0x01040200, 0x01040201, 0x00000202, + 0x00000203, 0x00040202, 0x00040203, 0x01000202, 0x01000203, + 0x01040202, 0x01040203, 0x08000000, 0x08000001, 0x08040000, + 0x08040001, 0x09000000, 0x09000001, 0x09040000, 0x09040001, + 0x08000002, 0x08000003, 0x08040002, 0x08040003, 0x09000002, + 0x09000003, 0x09040002, 0x09040003, 0x08000200, 0x08000201, + 0x08040200, 0x08040201, 0x09000200, 0x09000201, 0x09040200, + 0x09040201, 0x08000202, 0x08000203, 0x08040202, 0x08040203, + 0x09000202, 0x09000203, 0x09040202, 0x09040203, }, { // for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 - 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, 0x00000008L, - 0x00100008L, 0x00000108L, 0x00100108L, 0x00001000L, 0x00101000L, - 0x00001100L, 0x00101100L, 0x00001008L, 0x00101008L, 0x00001108L, - 0x00101108L, 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, - 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, 0x04001000L, - 0x04101000L, 0x04001100L, 0x04101100L, 0x04001008L, 0x04101008L, - 0x04001108L, 0x04101108L, 0x00020000L, 0x00120000L, 0x00020100L, - 0x00120100L, 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, - 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, 0x00021008L, - 0x00121008L, 0x00021108L, 0x00121108L, 0x04020000L, 0x04120000L, - 0x04020100L, 0x04120100L, 0x04020008L, 0x04120008L, 0x04020108L, - 0x04120108L, 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, - 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, }, + 0x00000000, 0x00100000, 0x00000100, 0x00100100, 0x00000008, + 0x00100008, 0x00000108, 0x00100108, 0x00001000, 0x00101000, + 0x00001100, 0x00101100, 0x00001008, 0x00101008, 0x00001108, + 0x00101108, 0x04000000, 0x04100000, 0x04000100, 0x04100100, + 0x04000008, 0x04100008, 0x04000108, 0x04100108, 0x04001000, + 0x04101000, 0x04001100, 0x04101100, 0x04001008, 0x04101008, + 0x04001108, 0x04101108, 0x00020000, 0x00120000, 0x00020100, + 0x00120100, 0x00020008, 0x00120008, 0x00020108, 0x00120108, + 0x00021000, 0x00121000, 0x00021100, 0x00121100, 0x00021008, + 0x00121008, 0x00021108, 0x00121108, 0x04020000, 0x04120000, + 0x04020100, 0x04120100, 0x04020008, 0x04120008, 0x04020108, + 0x04120108, 0x04021000, 0x04121000, 0x04021100, 0x04121100, + 0x04021008, 0x04121008, 0x04021108, 0x04121108, }, { // for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 - 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, 0x00000004L, - 0x10000004L, 0x00010004L, 0x10010004L, 0x20000000L, 0x30000000L, - 0x20010000L, 0x30010000L, 0x20000004L, 0x30000004L, 0x20010004L, - 0x30010004L, 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, - 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, 0x20100000L, - 0x30100000L, 0x20110000L, 0x30110000L, 0x20100004L, 0x30100004L, - 0x20110004L, 0x30110004L, 0x00001000L, 0x10001000L, 0x00011000L, - 0x10011000L, 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, - 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, 0x20001004L, - 0x30001004L, 0x20011004L, 0x30011004L, 0x00101000L, 0x10101000L, - 0x00111000L, 0x10111000L, 0x00101004L, 0x10101004L, 0x00111004L, - 0x10111004L, 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, - 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, }, + 0x00000000, 0x10000000, 0x00010000, 0x10010000, 0x00000004, + 0x10000004, 0x00010004, 0x10010004, 0x20000000, 0x30000000, + 0x20010000, 0x30010000, 0x20000004, 0x30000004, 0x20010004, + 0x30010004, 0x00100000, 0x10100000, 0x00110000, 0x10110000, + 0x00100004, 0x10100004, 0x00110004, 0x10110004, 0x20100000, + 0x30100000, 0x20110000, 0x30110000, 0x20100004, 0x30100004, + 0x20110004, 0x30110004, 0x00001000, 0x10001000, 0x00011000, + 0x10011000, 0x00001004, 0x10001004, 0x00011004, 0x10011004, + 0x20001000, 0x30001000, 0x20011000, 0x30011000, 0x20001004, + 0x30001004, 0x20011004, 0x30011004, 0x00101000, 0x10101000, + 0x00111000, 0x10111000, 0x00101004, 0x10101004, 0x00111004, + 0x10111004, 0x20101000, 0x30101000, 0x20111000, 0x30111000, + 0x20101004, 0x30101004, 0x20111004, 0x30111004, }, { // for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 - 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, 0x00000400L, - 0x08000400L, 0x00000408L, 0x08000408L, 0x00020000L, 0x08020000L, - 0x00020008L, 0x08020008L, 0x00020400L, 0x08020400L, 0x00020408L, - 0x08020408L, 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, - 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, 0x00020001L, - 0x08020001L, 0x00020009L, 0x08020009L, 0x00020401L, 0x08020401L, - 0x00020409L, 0x08020409L, 0x02000000L, 0x0A000000L, 0x02000008L, - 0x0A000008L, 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, - 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, 0x02020400L, - 0x0A020400L, 0x02020408L, 0x0A020408L, 0x02000001L, 0x0A000001L, - 0x02000009L, 0x0A000009L, 0x02000401L, 0x0A000401L, 0x02000409L, - 0x0A000409L, 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, - 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, }, + 0x00000000, 0x08000000, 0x00000008, 0x08000008, 0x00000400, + 0x08000400, 0x00000408, 0x08000408, 0x00020000, 0x08020000, + 0x00020008, 0x08020008, 0x00020400, 0x08020400, 0x00020408, + 0x08020408, 0x00000001, 0x08000001, 0x00000009, 0x08000009, + 0x00000401, 0x08000401, 0x00000409, 0x08000409, 0x00020001, + 0x08020001, 0x00020009, 0x08020009, 0x00020401, 0x08020401, + 0x00020409, 0x08020409, 0x02000000, 0x0A000000, 0x02000008, + 0x0A000008, 0x02000400, 0x0A000400, 0x02000408, 0x0A000408, + 0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 0x02020400, + 0x0A020400, 0x02020408, 0x0A020408, 0x02000001, 0x0A000001, + 0x02000009, 0x0A000009, 0x02000401, 0x0A000401, 0x02000409, + 0x0A000409, 0x02020001, 0x0A020001, 0x02020009, 0x0A020009, + 0x02020401, 0x0A020401, 0x02020409, 0x0A020409, }, { // for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 - 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, 0x01000000L, - 0x01000100L, 0x01080000L, 0x01080100L, 0x00000010L, 0x00000110L, - 0x00080010L, 0x00080110L, 0x01000010L, 0x01000110L, 0x01080010L, - 0x01080110L, 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, - 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, 0x00200010L, - 0x00200110L, 0x00280010L, 0x00280110L, 0x01200010L, 0x01200110L, - 0x01280010L, 0x01280110L, 0x00000200L, 0x00000300L, 0x00080200L, - 0x00080300L, 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, - 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, 0x01000210L, - 0x01000310L, 0x01080210L, 0x01080310L, 0x00200200L, 0x00200300L, - 0x00280200L, 0x00280300L, 0x01200200L, 0x01200300L, 0x01280200L, - 0x01280300L, 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, - 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, }, + 0x00000000, 0x00000100, 0x00080000, 0x00080100, 0x01000000, + 0x01000100, 0x01080000, 0x01080100, 0x00000010, 0x00000110, + 0x00080010, 0x00080110, 0x01000010, 0x01000110, 0x01080010, + 0x01080110, 0x00200000, 0x00200100, 0x00280000, 0x00280100, + 0x01200000, 0x01200100, 0x01280000, 0x01280100, 0x00200010, + 0x00200110, 0x00280010, 0x00280110, 0x01200010, 0x01200110, + 0x01280010, 0x01280110, 0x00000200, 0x00000300, 0x00080200, + 0x00080300, 0x01000200, 0x01000300, 0x01080200, 0x01080300, + 0x00000210, 0x00000310, 0x00080210, 0x00080310, 0x01000210, + 0x01000310, 0x01080210, 0x01080310, 0x00200200, 0x00200300, + 0x00280200, 0x00280300, 0x01200200, 0x01200300, 0x01280200, + 0x01280300, 0x00200210, 0x00200310, 0x00280210, 0x00280310, + 0x01200210, 0x01200310, 0x01280210, 0x01280310, }, { // for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 - 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, 0x00000002L, - 0x04000002L, 0x00040002L, 0x04040002L, 0x00002000L, 0x04002000L, - 0x00042000L, 0x04042000L, 0x00002002L, 0x04002002L, 0x00042002L, - 0x04042002L, 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, - 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, 0x00002020L, - 0x04002020L, 0x00042020L, 0x04042020L, 0x00002022L, 0x04002022L, - 0x00042022L, 0x04042022L, 0x00000800L, 0x04000800L, 0x00040800L, - 0x04040800L, 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, - 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, 0x00002802L, - 0x04002802L, 0x00042802L, 0x04042802L, 0x00000820L, 0x04000820L, - 0x00040820L, 0x04040820L, 0x00000822L, 0x04000822L, 0x00040822L, - 0x04040822L, 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, - 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, }}; + 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000002, + 0x04000002, 0x00040002, 0x04040002, 0x00002000, 0x04002000, + 0x00042000, 0x04042000, 0x00002002, 0x04002002, 0x00042002, + 0x04042002, 0x00000020, 0x04000020, 0x00040020, 0x04040020, + 0x00000022, 0x04000022, 0x00040022, 0x04040022, 0x00002020, + 0x04002020, 0x00042020, 0x04042020, 0x00002022, 0x04002022, + 0x00042022, 0x04042022, 0x00000800, 0x04000800, 0x00040800, + 0x04040800, 0x00000802, 0x04000802, 0x00040802, 0x04040802, + 0x00002800, 0x04002800, 0x00042800, 0x04042800, 0x00002802, + 0x04002802, 0x00042802, 0x04042802, 0x00000820, 0x04000820, + 0x00040820, 0x04040820, 0x00000822, 0x04000822, 0x00040822, + 0x04040822, 0x00002820, 0x04002820, 0x00042820, 0x04042820, + 0x00002822, 0x04002822, 0x00042822, 0x04042822, }}; static const uint32_t DES_SPtrans[8][64] = { { // nibble 0 - 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, 0x02000000L, - 0x00080802L, 0x00080002L, 0x02000002L, 0x00080802L, 0x02080800L, - 0x02080000L, 0x00000802L, 0x02000802L, 0x02000000L, 0x00000000L, - 0x00080002L, 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, - 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, 0x00000002L, - 0x00000800L, 0x00080800L, 0x02080002L, 0x00000800L, 0x02000802L, - 0x02080002L, 0x00000000L, 0x00000000L, 0x02080802L, 0x02000800L, - 0x00080002L, 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, - 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, 0x00080802L, - 0x00000002L, 0x02000002L, 0x02080000L, 0x02080802L, 0x00080800L, - 0x02080000L, 0x02000802L, 0x02000000L, 0x00000802L, 0x00080002L, - 0x00000000L, 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, - 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, }, + 0x02080800, 0x00080000, 0x02000002, 0x02080802, 0x02000000, + 0x00080802, 0x00080002, 0x02000002, 0x00080802, 0x02080800, + 0x02080000, 0x00000802, 0x02000802, 0x02000000, 0x00000000, + 0x00080002, 0x00080000, 0x00000002, 0x02000800, 0x00080800, + 0x02080802, 0x02080000, 0x00000802, 0x02000800, 0x00000002, + 0x00000800, 0x00080800, 0x02080002, 0x00000800, 0x02000802, + 0x02080002, 0x00000000, 0x00000000, 0x02080802, 0x02000800, + 0x00080002, 0x02080800, 0x00080000, 0x00000802, 0x02000800, + 0x02080002, 0x00000800, 0x00080800, 0x02000002, 0x00080802, + 0x00000002, 0x02000002, 0x02080000, 0x02080802, 0x00080800, + 0x02080000, 0x02000802, 0x02000000, 0x00000802, 0x00080002, + 0x00000000, 0x00080000, 0x02000000, 0x02000802, 0x02080800, + 0x00000002, 0x02080002, 0x00000800, 0x00080802, }, { // nibble 1 - 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, 0x40000010L, - 0x00008010L, 0x40008000L, 0x00108000L, 0x00008000L, 0x40100010L, - 0x00000010L, 0x40008000L, 0x00100010L, 0x40108000L, 0x40100000L, - 0x00000010L, 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, - 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, 0x40008010L, - 0x00108010L, 0x40108000L, 0x40000010L, 0x40000000L, 0x00100000L, - 0x00008010L, 0x40108010L, 0x00100010L, 0x40108000L, 0x40008000L, - 0x00108010L, 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, - 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, 0x00008000L, - 0x40000000L, 0x00108010L, 0x40008010L, 0x40108000L, 0x00008000L, - 0x00000000L, 0x40000010L, 0x00000010L, 0x40108010L, 0x00108000L, - 0x40100000L, 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, - 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, }, + 0x40108010, 0x00000000, 0x00108000, 0x40100000, 0x40000010, + 0x00008010, 0x40008000, 0x00108000, 0x00008000, 0x40100010, + 0x00000010, 0x40008000, 0x00100010, 0x40108000, 0x40100000, + 0x00000010, 0x00100000, 0x40008010, 0x40100010, 0x00008000, + 0x00108010, 0x40000000, 0x00000000, 0x00100010, 0x40008010, + 0x00108010, 0x40108000, 0x40000010, 0x40000000, 0x00100000, + 0x00008010, 0x40108010, 0x00100010, 0x40108000, 0x40008000, + 0x00108010, 0x40108010, 0x00100010, 0x40000010, 0x00000000, + 0x40000000, 0x00008010, 0x00100000, 0x40100010, 0x00008000, + 0x40000000, 0x00108010, 0x40008010, 0x40108000, 0x00008000, + 0x00000000, 0x40000010, 0x00000010, 0x40108010, 0x00108000, + 0x40100000, 0x40100010, 0x00100000, 0x00008010, 0x40008000, + 0x40008010, 0x00000010, 0x40100000, 0x00108000, }, { // nibble 2 - 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, 0x00040001L, - 0x04000000L, 0x04000101L, 0x00040100L, 0x04000100L, 0x00040000L, - 0x04040000L, 0x00000001L, 0x04040101L, 0x00000101L, 0x00000001L, - 0x04040001L, 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, - 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, 0x04040001L, - 0x04000100L, 0x00040101L, 0x04040000L, 0x00040100L, 0x00000000L, - 0x04000000L, 0x00040101L, 0x04040100L, 0x00000100L, 0x00000001L, - 0x00040000L, 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, - 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, 0x00040001L, - 0x04000000L, 0x04040101L, 0x00000001L, 0x00040101L, 0x04000001L, - 0x04000000L, 0x04040101L, 0x00040000L, 0x04000100L, 0x04000101L, - 0x00040100L, 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, - 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, }, + 0x04000001, 0x04040100, 0x00000100, 0x04000101, 0x00040001, + 0x04000000, 0x04000101, 0x00040100, 0x04000100, 0x00040000, + 0x04040000, 0x00000001, 0x04040101, 0x00000101, 0x00000001, + 0x04040001, 0x00000000, 0x00040001, 0x04040100, 0x00000100, + 0x00000101, 0x04040101, 0x00040000, 0x04000001, 0x04040001, + 0x04000100, 0x00040101, 0x04040000, 0x00040100, 0x00000000, + 0x04000000, 0x00040101, 0x04040100, 0x00000100, 0x00000001, + 0x00040000, 0x00000101, 0x00040001, 0x04040000, 0x04000101, + 0x00000000, 0x04040100, 0x00040100, 0x04040001, 0x00040001, + 0x04000000, 0x04040101, 0x00000001, 0x00040101, 0x04000001, + 0x04000000, 0x04040101, 0x00040000, 0x04000100, 0x04000101, + 0x00040100, 0x04000100, 0x00000000, 0x04040001, 0x00000101, + 0x04000001, 0x00040101, 0x00000100, 0x04040000, }, { // nibble 3 - 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, 0x00000000L, - 0x10400000L, 0x10001008L, 0x00400008L, 0x10401000L, 0x10000008L, - 0x10000000L, 0x00001008L, 0x10000008L, 0x00401008L, 0x00400000L, - 0x10000000L, 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, - 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, 0x00001008L, - 0x00000000L, 0x00400008L, 0x10401000L, 0x10001000L, 0x10400008L, - 0x10401008L, 0x00400000L, 0x10400008L, 0x00001008L, 0x00400000L, - 0x10000008L, 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, - 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, 0x00000000L, - 0x10400008L, 0x10401000L, 0x00001000L, 0x10000000L, 0x10401008L, - 0x00401008L, 0x00400000L, 0x10401008L, 0x00000008L, 0x10001000L, - 0x00401008L, 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, - 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, }, + 0x00401008, 0x10001000, 0x00000008, 0x10401008, 0x00000000, + 0x10400000, 0x10001008, 0x00400008, 0x10401000, 0x10000008, + 0x10000000, 0x00001008, 0x10000008, 0x00401008, 0x00400000, + 0x10000000, 0x10400008, 0x00401000, 0x00001000, 0x00000008, + 0x00401000, 0x10001008, 0x10400000, 0x00001000, 0x00001008, + 0x00000000, 0x00400008, 0x10401000, 0x10001000, 0x10400008, + 0x10401008, 0x00400000, 0x10400008, 0x00001008, 0x00400000, + 0x10000008, 0x00401000, 0x10001000, 0x00000008, 0x10400000, + 0x10001008, 0x00000000, 0x00001000, 0x00400008, 0x00000000, + 0x10400008, 0x10401000, 0x00001000, 0x10000000, 0x10401008, + 0x00401008, 0x00400000, 0x10401008, 0x00000008, 0x10001000, + 0x00401008, 0x00400008, 0x00401000, 0x10400000, 0x10001008, + 0x00001008, 0x10000000, 0x10000008, 0x10401000, }, { // nibble 4 - 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, 0x08010020L, - 0x08000400L, 0x00010420L, 0x08010000L, 0x00010000L, 0x00000020L, - 0x08000020L, 0x00010400L, 0x08000420L, 0x08010020L, 0x08010400L, - 0x00000000L, 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, - 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, 0x00000020L, - 0x08000420L, 0x08010420L, 0x00010020L, 0x08010000L, 0x00000400L, - 0x00000420L, 0x08010400L, 0x08010400L, 0x08000420L, 0x00010020L, - 0x08010000L, 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, - 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, 0x00010420L, - 0x08000000L, 0x00000400L, 0x00010020L, 0x08000420L, 0x00000400L, - 0x00000000L, 0x08010420L, 0x08010020L, 0x08010400L, 0x00000420L, - 0x00010000L, 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, - 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, }, + 0x08000000, 0x00010000, 0x00000400, 0x08010420, 0x08010020, + 0x08000400, 0x00010420, 0x08010000, 0x00010000, 0x00000020, + 0x08000020, 0x00010400, 0x08000420, 0x08010020, 0x08010400, + 0x00000000, 0x00010400, 0x08000000, 0x00010020, 0x00000420, + 0x08000400, 0x00010420, 0x00000000, 0x08000020, 0x00000020, + 0x08000420, 0x08010420, 0x00010020, 0x08010000, 0x00000400, + 0x00000420, 0x08010400, 0x08010400, 0x08000420, 0x00010020, + 0x08010000, 0x00010000, 0x00000020, 0x08000020, 0x08000400, + 0x08000000, 0x00010400, 0x08010420, 0x00000000, 0x00010420, + 0x08000000, 0x00000400, 0x00010020, 0x08000420, 0x00000400, + 0x00000000, 0x08010420, 0x08010020, 0x08010400, 0x00000420, + 0x00010000, 0x00010400, 0x08010020, 0x08000400, 0x00000420, + 0x00000020, 0x00010420, 0x08010000, 0x08000020, }, { // nibble 5 - 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, 0x00200040L, - 0x00002000L, 0x80002040L, 0x00200000L, 0x00002040L, 0x80202040L, - 0x00202000L, 0x80000000L, 0x80002000L, 0x80000040L, 0x80200000L, - 0x00202040L, 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, - 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, 0x80202040L, - 0x80200000L, 0x80000000L, 0x00002040L, 0x00000040L, 0x00202000L, - 0x00202040L, 0x80002000L, 0x00002040L, 0x80000000L, 0x80002000L, - 0x00202040L, 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, - 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, 0x00200040L, - 0x80202040L, 0x00202000L, 0x00000040L, 0x80202040L, 0x00202000L, - 0x00200000L, 0x80002040L, 0x80000040L, 0x80200000L, 0x00202040L, - 0x00000000L, 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, - 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, }, + 0x80000040, 0x00200040, 0x00000000, 0x80202000, 0x00200040, + 0x00002000, 0x80002040, 0x00200000, 0x00002040, 0x80202040, + 0x00202000, 0x80000000, 0x80002000, 0x80000040, 0x80200000, + 0x00202040, 0x00200000, 0x80002040, 0x80200040, 0x00000000, + 0x00002000, 0x00000040, 0x80202000, 0x80200040, 0x80202040, + 0x80200000, 0x80000000, 0x00002040, 0x00000040, 0x00202000, + 0x00202040, 0x80002000, 0x00002040, 0x80000000, 0x80002000, + 0x00202040, 0x80202000, 0x00200040, 0x00000000, 0x80002000, + 0x80000000, 0x00002000, 0x80200040, 0x00200000, 0x00200040, + 0x80202040, 0x00202000, 0x00000040, 0x80202040, 0x00202000, + 0x00200000, 0x80002040, 0x80000040, 0x80200000, 0x00202040, + 0x00000000, 0x00002000, 0x80000040, 0x80002040, 0x80202000, + 0x80200000, 0x00002040, 0x00000040, 0x80200040, }, { // nibble 6 - 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, 0x01004204L, - 0x00004004L, 0x00004200L, 0x00000000L, 0x01000000L, 0x01000204L, - 0x00000204L, 0x01004000L, 0x00000004L, 0x01004200L, 0x01004000L, - 0x00000204L, 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, - 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, 0x01004004L, - 0x00004204L, 0x01004200L, 0x00000004L, 0x00004204L, 0x01004004L, - 0x00000200L, 0x01000000L, 0x00004204L, 0x01004000L, 0x01004004L, - 0x00000204L, 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, - 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, 0x00000200L, - 0x01000004L, 0x00000004L, 0x01000200L, 0x00000000L, 0x01000204L, - 0x01000200L, 0x00004200L, 0x00000204L, 0x00004000L, 0x01004204L, - 0x01000000L, 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, - 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, }, + 0x00004000, 0x00000200, 0x01000200, 0x01000004, 0x01004204, + 0x00004004, 0x00004200, 0x00000000, 0x01000000, 0x01000204, + 0x00000204, 0x01004000, 0x00000004, 0x01004200, 0x01004000, + 0x00000204, 0x01000204, 0x00004000, 0x00004004, 0x01004204, + 0x00000000, 0x01000200, 0x01000004, 0x00004200, 0x01004004, + 0x00004204, 0x01004200, 0x00000004, 0x00004204, 0x01004004, + 0x00000200, 0x01000000, 0x00004204, 0x01004000, 0x01004004, + 0x00000204, 0x00004000, 0x00000200, 0x01000000, 0x01004004, + 0x01000204, 0x00004204, 0x00004200, 0x00000000, 0x00000200, + 0x01000004, 0x00000004, 0x01000200, 0x00000000, 0x01000204, + 0x01000200, 0x00004200, 0x00000204, 0x00004000, 0x01004204, + 0x01000000, 0x01004200, 0x00000004, 0x00004004, 0x01004204, + 0x01000004, 0x01004200, 0x01004000, 0x00004004, }, { // nibble 7 - 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, 0x20020000L, - 0x00800080L, 0x20800000L, 0x20820080L, 0x00000080L, 0x20000000L, - 0x00820000L, 0x00020080L, 0x00820080L, 0x20020080L, 0x20000080L, - 0x20800000L, 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, - 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, 0x20000000L, - 0x00800000L, 0x20020080L, 0x20800080L, 0x00800000L, 0x00020000L, - 0x20820000L, 0x00000080L, 0x00800000L, 0x00020000L, 0x20000080L, - 0x20820080L, 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, - 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, 0x20820000L, - 0x00000080L, 0x00800080L, 0x20020000L, 0x20820080L, 0x00800000L, - 0x20800000L, 0x20000080L, 0x00820000L, 0x00020080L, 0x20020080L, - 0x20800000L, 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, - 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, }}; + 0x20800080, 0x20820000, 0x00020080, 0x00000000, 0x20020000, + 0x00800080, 0x20800000, 0x20820080, 0x00000080, 0x20000000, + 0x00820000, 0x00020080, 0x00820080, 0x20020080, 0x20000080, + 0x20800000, 0x00020000, 0x00820080, 0x00800080, 0x20020000, + 0x20820080, 0x20000080, 0x00000000, 0x00820000, 0x20000000, + 0x00800000, 0x20020080, 0x20800080, 0x00800000, 0x00020000, + 0x20820000, 0x00000080, 0x00800000, 0x00020000, 0x20000080, + 0x20820080, 0x00020080, 0x20000000, 0x00000000, 0x00820000, + 0x20800080, 0x20020080, 0x20020000, 0x00800080, 0x20820000, + 0x00000080, 0x00800080, 0x20020000, 0x20820080, 0x00800000, + 0x20800000, 0x20000080, 0x00820000, 0x00020080, 0x20020080, + 0x20800000, 0x00000080, 0x20820000, 0x00820080, 0x00000000, + 0x20000000, 0x20800080, 0x00020000, 0x00820080, }}; #define HPERM_OP(a, t, n, m) \ ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \ @@ -308,43 +308,43 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { // do PC1 in 47 simple operations :-) // Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) // for the inspiration. :-) - PERM_OP(d, c, t, 4, 0x0f0f0f0fL); - HPERM_OP(c, t, -2, 0xcccc0000L); - HPERM_OP(d, t, -2, 0xcccc0000L); - PERM_OP(d, c, t, 1, 0x55555555L); - PERM_OP(c, d, t, 8, 0x00ff00ffL); - PERM_OP(d, c, t, 1, 0x55555555L); - d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | - ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); - c &= 0x0fffffffL; + PERM_OP(d, c, t, 4, 0x0f0f0f0f); + HPERM_OP(c, t, -2, 0xcccc0000); + HPERM_OP(d, t, -2, 0xcccc0000); + PERM_OP(d, c, t, 1, 0x55555555); + PERM_OP(c, d, t, 8, 0x00ff00ff); + PERM_OP(d, c, t, 1, 0x55555555); + d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) | + ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4)); + c &= 0x0fffffff; for (i = 0; i < ITERATIONS; i++) { if (shifts2[i]) { - c = ((c >> 2L) | (c << 26L)); - d = ((d >> 2L) | (d << 26L)); + c = ((c >> 2) | (c << 26)); + d = ((d >> 2) | (d << 26)); } else { - c = ((c >> 1L) | (c << 27L)); - d = ((d >> 1L) | (d << 27L)); + c = ((c >> 1) | (c << 27)); + d = ((d >> 1) | (d << 27)); } - c &= 0x0fffffffL; - d &= 0x0fffffffL; + c &= 0x0fffffff; + d &= 0x0fffffff; // could be a few less shifts but I am to lazy at this // point in time to investigate s = des_skb[0][(c) & 0x3f] | - des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | - des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | - des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | - ((c >> 22L) & 0x38)]; + des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] | + des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] | + des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | + ((c >> 22) & 0x38)]; t = des_skb[4][(d) & 0x3f] | - des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | - des_skb[6][(d >> 15L) & 0x3f] | - des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; + des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] | + des_skb[6][(d >> 15) & 0x3f] | + des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)]; // table contained 0213 4657 - t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; + t2 = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff; schedule->subkeys[i][0] = CRYPTO_rotr_u32(t2, 30); - t2 = ((s >> 16L) | (t & 0xffff0000L)); + t2 = ((s >> 16) | (t & 0xffff0000)); schedule->subkeys[i][1] = CRYPTO_rotr_u32(t2, 26); } } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/des/internal.h b/third_party/boringssl/kit/src/crypto/des/internal.h similarity index 99% rename from third_party/boringssl/kit/src/crypto/fipsmodule/des/internal.h rename to third_party/boringssl/kit/src/crypto/des/internal.h index 3e3992ec..2124fd58 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/des/internal.h +++ b/third_party/boringssl/kit/src/crypto/des/internal.h @@ -59,7 +59,7 @@ #include -#include "../../internal.h" +#include "../internal.h" #if defined(__cplusplus) extern "C" { diff --git a/third_party/boringssl/kit/src/crypto/dh_extra/dh_asn1.c b/third_party/boringssl/kit/src/crypto/dh_extra/dh_asn1.c index 9d321807..de01077d 100644 --- a/third_party/boringssl/kit/src/crypto/dh_extra/dh_asn1.c +++ b/third_party/boringssl/kit/src/crypto/dh_extra/dh_asn1.c @@ -63,6 +63,7 @@ #include #include "../bytestring/internal.h" +#include "../fipsmodule/dh/internal.h" static int parse_integer(CBS *cbs, BIGNUM **out) { diff --git a/third_party/boringssl/kit/src/crypto/dh_extra/dh_test.cc b/third_party/boringssl/kit/src/crypto/dh_extra/dh_test.cc index 7933a8cc..8d2c5871 100644 --- a/third_party/boringssl/kit/src/crypto/dh_extra/dh_test.cc +++ b/third_party/boringssl/kit/src/crypto/dh_extra/dh_test.cc @@ -70,136 +70,46 @@ #include #include +#include "../fipsmodule/dh/internal.h" #include "../internal.h" #include "../test/test_util.h" -static bool RunBasicTests(); -static bool TestBadY(); -static bool TestASN1(); -static bool TestRFC3526(); - -// TODO(davidben): Convert this file to GTest properly. -TEST(DHTest, AllTests) { - if (!RunBasicTests() || - !TestBadY() || - !TestASN1() || - !TestRFC3526()) { - ADD_FAILURE() << "Tests failed."; - } -} - -static int GenerateCallback(int p, int n, BN_GENCB *arg) { - char c = '*'; - - if (p == 0) { - c = '.'; - } else if (p == 1) { - c = '+'; - } else if (p == 2) { - c = '*'; - } else if (p == 3) { - c = '\n'; - } - FILE *out = reinterpret_cast(arg->arg); - fputc(c, out); - fflush(out); - - return 1; -} - -static bool RunBasicTests() { - BN_GENCB cb; - BN_GENCB_set(&cb, &GenerateCallback, stdout); +TEST(DHTest, Basic) { bssl::UniquePtr a(DH_new()); - if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) { - return false; - } + ASSERT_TRUE(a); + ASSERT_TRUE(DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, nullptr)); int check_result; - if (!DH_check(a.get(), &check_result)) { - return false; - } - if (check_result & DH_CHECK_P_NOT_PRIME) { - printf("p value is not prime\n"); - } - if (check_result & DH_CHECK_P_NOT_SAFE_PRIME) { - printf("p value is not a safe prime\n"); - } - if (check_result & DH_CHECK_UNABLE_TO_CHECK_GENERATOR) { - printf("unable to check the generator value\n"); - } - if (check_result & DH_CHECK_NOT_SUITABLE_GENERATOR) { - printf("the g value is not a generator\n"); - } + ASSERT_TRUE(DH_check(a.get(), &check_result)); + EXPECT_FALSE(check_result & DH_CHECK_P_NOT_PRIME); + EXPECT_FALSE(check_result & DH_CHECK_P_NOT_SAFE_PRIME); + EXPECT_FALSE(check_result & DH_CHECK_UNABLE_TO_CHECK_GENERATOR); + EXPECT_FALSE(check_result & DH_CHECK_NOT_SUITABLE_GENERATOR); - printf("\np = "); - BN_print_fp(stdout, a->p); - printf("\ng = "); - BN_print_fp(stdout, a->g); - printf("\n"); + bssl::UniquePtr b(DHparams_dup(a.get())); + ASSERT_TRUE(b); - bssl::UniquePtr b(DH_new()); - if (!b) { - return false; - } - - b->p = BN_dup(a->p); - b->g = BN_dup(a->g); - if (b->p == nullptr || b->g == nullptr) { - return false; - } - - if (!DH_generate_key(a.get())) { - return false; - } - printf("pri1 = "); - BN_print_fp(stdout, a->priv_key); - printf("\npub1 = "); - BN_print_fp(stdout, a->pub_key); - printf("\n"); - - if (!DH_generate_key(b.get())) { - return false; - } - printf("pri2 = "); - BN_print_fp(stdout, b->priv_key); - printf("\npub2 = "); - BN_print_fp(stdout, b->pub_key); - printf("\n"); + ASSERT_TRUE(DH_generate_key(a.get())); + ASSERT_TRUE(DH_generate_key(b.get())); std::vector key1(DH_size(a.get())); - int ret = DH_compute_key(key1.data(), b->pub_key, a.get()); - if (ret < 0) { - return false; - } + int ret = DH_compute_key(key1.data(), DH_get0_pub_key(b.get()), a.get()); + ASSERT_GE(ret, 0); key1.resize(ret); - printf("key1 = "); - for (size_t i = 0; i < key1.size(); i++) { - printf("%02x", key1[i]); - } - printf("\n"); - std::vector key2(DH_size(b.get())); - ret = DH_compute_key(key2.data(), a->pub_key, b.get()); - if (ret < 0) { - return false; - } + ret = DH_compute_key(key2.data(), DH_get0_pub_key(a.get()), b.get()); + ASSERT_GE(ret, 0); key2.resize(ret); - printf("key2 = "); - for (size_t i = 0; i < key2.size(); i++) { - printf("%02x", key2[i]); - } - printf("\n"); + EXPECT_EQ(Bytes(key1), Bytes(key2)); - if (key1.size() < 4 || key1 != key2) { - fprintf(stderr, "Error in DH routines\n"); - return false; - } - - return true; + // |DH_compute_key|, unlike |DH_compute_key_padded|, removes leading zeros + // from the output, so the key will not have a fixed length. This test uses a + // small, 64-bit prime, so check for at least 32 bits of output after removing + // leading zeros. + EXPECT_GE(key1.size(), 4u); } // The following parameters are taken from RFC 5114, section 2.2. This is not a @@ -285,38 +195,30 @@ static const uint8_t kRFC5114_2048_224BadY[] = { 0x93, 0x74, 0x89, 0x59, }; -static bool TestBadY() { +TEST(DHTest, BadY) { bssl::UniquePtr dh(DH_new()); + ASSERT_TRUE(dh); dh->p = BN_bin2bn(kRFC5114_2048_224P, sizeof(kRFC5114_2048_224P), nullptr); dh->g = BN_bin2bn(kRFC5114_2048_224G, sizeof(kRFC5114_2048_224G), nullptr); dh->q = BN_bin2bn(kRFC5114_2048_224Q, sizeof(kRFC5114_2048_224Q), nullptr); - if (!dh->p || !dh->g || !dh->q) { - return false; - } + ASSERT_TRUE(dh->p); + ASSERT_TRUE(dh->g); + ASSERT_TRUE(dh->q); bssl::UniquePtr pub_key( BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr)); - if (!dh || !pub_key || !DH_generate_key(dh.get())) { - return false; - } + ASSERT_TRUE(pub_key); + ASSERT_TRUE(DH_generate_key(dh.get())); int flags; - if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) { - return false; - } - if (!(flags & DH_CHECK_PUBKEY_INVALID)) { - fprintf(stderr, "DH_check_pub_key did not reject the key.\n"); - return false; - } + ASSERT_TRUE(DH_check_pub_key(dh.get(), pub_key.get(), &flags)); + EXPECT_TRUE(flags & DH_CHECK_PUBKEY_INVALID) + << "DH_check_pub_key did not reject the key"; std::vector result(DH_size(dh.get())); - if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) { - fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n"); - return false; - } + EXPECT_LT(DH_compute_key(result.data(), pub_key.get(), dh.get()), 0) + << "DH_compute_key unexpectedly succeeded"; ERR_clear_error(); - - return true; } static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) { @@ -328,7 +230,7 @@ static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) { return BN_cmp(bn, hex_bn) == 0; } -static bool TestASN1() { +TEST(DHTest, ASN1) { // kParams are a set of Diffie-Hellman parameters generated with // openssl dhparam 256 static const uint8_t kParams[] = { @@ -341,27 +243,22 @@ static bool TestASN1() { CBS cbs; CBS_init(&cbs, kParams, sizeof(kParams)); bssl::UniquePtr dh(DH_parse_parameters(&cbs)); - if (!dh || CBS_len(&cbs) != 0 || - !BIGNUMEqualsHex( - dh->p, - "d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313") || - !BIGNUMEqualsHex(dh->g, "2") || dh->priv_length != 0) { - return false; - } + ASSERT_TRUE(dh); + EXPECT_EQ(CBS_len(&cbs), 0u); + EXPECT_TRUE(BIGNUMEqualsHex( + DH_get0_p(dh.get()), + "d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313")); + EXPECT_TRUE(BIGNUMEqualsHex(DH_get0_g(dh.get()), "2")); + EXPECT_EQ(dh->priv_length, 0u); bssl::ScopedCBB cbb; uint8_t *der; size_t der_len; - if (!CBB_init(cbb.get(), 0) || - !DH_marshal_parameters(cbb.get(), dh.get()) || - !CBB_finish(cbb.get(), &der, &der_len)) { - return false; - } + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(DH_marshal_parameters(cbb.get(), dh.get())); + ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); bssl::UniquePtr free_der(der); - if (der_len != sizeof(kParams) || - OPENSSL_memcmp(der, kParams, der_len) != 0) { - return false; - } + EXPECT_EQ(Bytes(kParams), Bytes(der, der_len)); // kParamsDSA are a set of Diffie-Hellman parameters generated with // openssl dhparam 256 -dsaparam @@ -382,38 +279,30 @@ static bool TestASN1() { CBS_init(&cbs, kParamsDSA, sizeof(kParamsDSA)); dh.reset(DH_parse_parameters(&cbs)); - if (!dh || CBS_len(&cbs) != 0 || - !BIGNUMEqualsHex(dh->p, - "93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8" - "22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467" - "3451952aac11e26a55") || - !BIGNUMEqualsHex(dh->g, - "44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86" - "b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec" - "a6a8ba1a078a77f55f") || - dh->priv_length != 160) { - return false; - } + ASSERT_TRUE(dh); + EXPECT_EQ(CBS_len(&cbs), 0u); + EXPECT_TRUE( + BIGNUMEqualsHex(DH_get0_p(dh.get()), + "93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8" + "22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467" + "3451952aac11e26a55")); + EXPECT_TRUE( + BIGNUMEqualsHex(DH_get0_g(dh.get()), + "44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86" + "b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec" + "a6a8ba1a078a77f55f")); + EXPECT_EQ(dh->priv_length, 160u); - if (!CBB_init(cbb.get(), 0) || - !DH_marshal_parameters(cbb.get(), dh.get()) || - !CBB_finish(cbb.get(), &der, &der_len)) { - return false; - } + ASSERT_TRUE(CBB_init(cbb.get(), 0)); + ASSERT_TRUE(DH_marshal_parameters(cbb.get(), dh.get())); + ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); bssl::UniquePtr free_der2(der); - if (der_len != sizeof(kParamsDSA) || - OPENSSL_memcmp(der, kParamsDSA, der_len) != 0) { - return false; - } - - return true; + EXPECT_EQ(Bytes(kParamsDSA), Bytes(der, der_len)); } -static bool TestRFC3526() { +TEST(DHTest, RFC3526) { bssl::UniquePtr bn(BN_get_rfc3526_prime_1536(nullptr)); - if (!bn) { - return false; - } + ASSERT_TRUE(bn); static const uint8_t kPrime1536[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, @@ -435,14 +324,9 @@ static bool TestRFC3526() { }; uint8_t buffer[sizeof(kPrime1536)]; - if (BN_num_bytes(bn.get()) != sizeof(kPrime1536) || - BN_bn2bin(bn.get(), buffer) != sizeof(kPrime1536) || - OPENSSL_memcmp(buffer, kPrime1536, sizeof(kPrime1536)) != 0) { - fprintf(stderr, "1536-bit MODP prime did not match.\n"); - return false; - } - - return true; + ASSERT_EQ(BN_num_bytes(bn.get()), sizeof(kPrime1536)); + ASSERT_EQ(BN_bn2bin(bn.get(), buffer), sizeof(kPrime1536)); + EXPECT_EQ(Bytes(buffer), Bytes(kPrime1536)); } TEST(DHTest, LeadingZeros) { @@ -482,3 +366,64 @@ TEST(DHTest, LeadingZeros) { ASSERT_GT(len, 0); EXPECT_EQ(Bytes(buf.data(), len), Bytes(padded)); } + +TEST(DHTest, Overwrite) { + // Generate a DH key with the 1536-bit MODP group. + bssl::UniquePtr p(BN_get_rfc3526_prime_1536(nullptr)); + ASSERT_TRUE(p); + bssl::UniquePtr g(BN_new()); + ASSERT_TRUE(g); + ASSERT_TRUE(BN_set_word(g.get(), 2)); + + bssl::UniquePtr key1(DH_new()); + ASSERT_TRUE(key1); + ASSERT_TRUE(DH_set0_pqg(key1.get(), p.get(), /*q=*/nullptr, g.get())); + p.release(); + g.release(); + ASSERT_TRUE(DH_generate_key(key1.get())); + + bssl::UniquePtr peer_key(BN_new()); + ASSERT_TRUE(peer_key); + ASSERT_TRUE(BN_set_word(peer_key.get(), 42)); + + // Use the key to fill in cached values. + std::vector buf1(DH_size(key1.get())); + ASSERT_GT(DH_compute_key_padded(buf1.data(), peer_key.get(), key1.get()), 0); + + // Generate a different key with a different group. + p.reset(BN_get_rfc3526_prime_2048(nullptr)); + ASSERT_TRUE(p); + g.reset(BN_new()); + ASSERT_TRUE(g); + ASSERT_TRUE(BN_set_word(g.get(), 2)); + + bssl::UniquePtr key2(DH_new()); + ASSERT_TRUE(key2); + ASSERT_TRUE(DH_set0_pqg(key2.get(), p.get(), /*q=*/nullptr, g.get())); + p.release(); + g.release(); + ASSERT_TRUE(DH_generate_key(key2.get())); + + // Overwrite |key1|'s contents with |key2|. + p.reset(BN_dup(DH_get0_p(key2.get()))); + ASSERT_TRUE(p); + g.reset(BN_dup(DH_get0_g(key2.get()))); + ASSERT_TRUE(g); + bssl::UniquePtr pub(BN_dup(DH_get0_pub_key(key2.get()))); + ASSERT_TRUE(pub); + bssl::UniquePtr priv(BN_dup(DH_get0_priv_key(key2.get()))); + ASSERT_TRUE(priv); + ASSERT_TRUE(DH_set0_pqg(key1.get(), p.get(), /*q=*/nullptr, g.get())); + p.release(); + g.release(); + ASSERT_TRUE(DH_set0_key(key1.get(), pub.get(), priv.get())); + pub.release(); + priv.release(); + + // Verify that |key1| and |key2| behave equivalently. + buf1.resize(DH_size(key1.get())); + ASSERT_GT(DH_compute_key_padded(buf1.data(), peer_key.get(), key1.get()), 0); + std::vector buf2(DH_size(key2.get())); + ASSERT_GT(DH_compute_key_padded(buf2.data(), peer_key.get(), key2.get()), 0); + EXPECT_EQ(Bytes(buf1), Bytes(buf2)); +} diff --git a/third_party/boringssl/kit/src/crypto/dh_extra/params.c b/third_party/boringssl/kit/src/crypto/dh_extra/params.c index 6023ab12..0e76747e 100644 --- a/third_party/boringssl/kit/src/crypto/dh_extra/params.c +++ b/third_party/boringssl/kit/src/crypto/dh_extra/params.c @@ -57,10 +57,29 @@ #include #include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/dh/internal.h" +static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, size_t num_words) { + BIGNUM *alloc = NULL; + if (ret == NULL) { + alloc = BN_new(); + if (alloc == NULL) { + return NULL; + } + ret = alloc; + } + + if (!bn_set_words(ret, words, num_words)) { + BN_free(alloc); + return NULL; + } + + return ret; +} + BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { - static const BN_ULONG kPrime1536Data[] = { + static const BN_ULONG kWords[] = { TOBN(0xffffffff, 0xffffffff), TOBN(0xf1746c08, 0xca237327), TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), @@ -74,24 +93,221 @@ BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); +} - static const BIGNUM kPrime1536BN = STATIC_BIGNUM(kPrime1536Data); +BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret) { + static const BN_ULONG kWords[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0x15728e5a, 0x8aacaa68), + TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5), + TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9), + TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603), + TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); +} - BIGNUM *alloc = NULL; - if (ret == NULL) { - alloc = BN_new(); - if (alloc == NULL) { - return NULL; - } - ret = alloc; - } +BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret) { + static const BN_ULONG kWords[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0x4b82d120, 0xa93ad2ca), + TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31), + TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c), + TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64), + TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b), + TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7), + TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d), + TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64), + TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d), + TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5), + TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9), + TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603), + TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); +} - if (!BN_copy(ret, &kPrime1536BN)) { - BN_free(alloc); - return NULL; - } +BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret) { + static const BN_ULONG kWords[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0x4df435c9, 0x34063199), + TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1), + TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c), + TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed), + TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d), + TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9), + TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda), + TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26), + TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801), + TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31), + TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c), + TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64), + TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b), + TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7), + TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d), + TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64), + TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d), + TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5), + TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9), + TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603), + TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); +} - return ret; +BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret) { + static const BN_ULONG kWords[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0xe694f91e, 0x6dcc4024), + TOBN(0x12bf2d5b, 0x0b7474d6), TOBN(0x043e8f66, 0x3f4860ee), + TOBN(0x387fe8d7, 0x6e3c0468), TOBN(0xda56c9ec, 0x2ef29632), + TOBN(0xeb19ccb1, 0xa313d55c), TOBN(0xf550aa3d, 0x8a1fbff0), + TOBN(0x06a1d58b, 0xb7c5da76), TOBN(0xa79715ee, 0xf29be328), + TOBN(0x14cc5ed2, 0x0f8037e0), TOBN(0xcc8f6d7e, 0xbf48e1d8), + TOBN(0x4bd407b2, 0x2b4154aa), TOBN(0x0f1d45b7, 0xff585ac5), + TOBN(0x23a97a7e, 0x36cc88be), TOBN(0x59e7c97f, 0xbec7e8f3), + TOBN(0xb5a84031, 0x900b1c9e), TOBN(0xd55e702f, 0x46980c82), + TOBN(0xf482d7ce, 0x6e74fef6), TOBN(0xf032ea15, 0xd1721d03), + TOBN(0x5983ca01, 0xc64b92ec), TOBN(0x6fb8f401, 0x378cd2bf), + TOBN(0x33205151, 0x2bd7af42), TOBN(0xdb7f1447, 0xe6cc254b), + TOBN(0x44ce6cba, 0xced4bb1b), TOBN(0xda3edbeb, 0xcf9b14ed), + TOBN(0x179727b0, 0x865a8918), TOBN(0xb06a53ed, 0x9027d831), + TOBN(0xe5db382f, 0x413001ae), TOBN(0xf8ff9406, 0xad9e530e), + TOBN(0xc9751e76, 0x3dba37bd), TOBN(0xc1d4dcb2, 0x602646de), + TOBN(0x36c3fab4, 0xd27c7026), TOBN(0x4df435c9, 0x34028492), + TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1), + TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c), + TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed), + TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d), + TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9), + TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda), + TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26), + TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801), + TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31), + TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c), + TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64), + TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b), + TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7), + TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d), + TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64), + TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d), + TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5), + TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9), + TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603), + TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); +} + +BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret) { + static const BN_ULONG kWords[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0x60c980dd, 0x98edd3df), + TOBN(0xc81f56e8, 0x80b96e71), TOBN(0x9e3050e2, 0x765694df), + TOBN(0x9558e447, 0x5677e9aa), TOBN(0xc9190da6, 0xfc026e47), + TOBN(0x889a002e, 0xd5ee382b), TOBN(0x4009438b, 0x481c6cd7), + TOBN(0x359046f4, 0xeb879f92), TOBN(0xfaf36bc3, 0x1ecfa268), + TOBN(0xb1d510bd, 0x7ee74d73), TOBN(0xf9ab4819, 0x5ded7ea1), + TOBN(0x64f31cc5, 0x0846851d), TOBN(0x4597e899, 0xa0255dc1), + TOBN(0xdf310ee0, 0x74ab6a36), TOBN(0x6d2a13f8, 0x3f44f82d), + TOBN(0x062b3cf5, 0xb3a278a6), TOBN(0x79683303, 0xed5bdd3a), + TOBN(0xfa9d4b7f, 0xa2c087e8), TOBN(0x4bcbc886, 0x2f8385dd), + TOBN(0x3473fc64, 0x6cea306b), TOBN(0x13eb57a8, 0x1a23f0c7), + TOBN(0x22222e04, 0xa4037c07), TOBN(0xe3fdb8be, 0xfc848ad9), + TOBN(0x238f16cb, 0xe39d652d), TOBN(0x3423b474, 0x2bf1c978), + TOBN(0x3aab639c, 0x5ae4f568), TOBN(0x2576f693, 0x6ba42466), + TOBN(0x741fa7bf, 0x8afc47ed), TOBN(0x3bc832b6, 0x8d9dd300), + TOBN(0xd8bec4d0, 0x73b931ba), TOBN(0x38777cb6, 0xa932df8c), + TOBN(0x74a3926f, 0x12fee5e4), TOBN(0xe694f91e, 0x6dbe1159), + TOBN(0x12bf2d5b, 0x0b7474d6), TOBN(0x043e8f66, 0x3f4860ee), + TOBN(0x387fe8d7, 0x6e3c0468), TOBN(0xda56c9ec, 0x2ef29632), + TOBN(0xeb19ccb1, 0xa313d55c), TOBN(0xf550aa3d, 0x8a1fbff0), + TOBN(0x06a1d58b, 0xb7c5da76), TOBN(0xa79715ee, 0xf29be328), + TOBN(0x14cc5ed2, 0x0f8037e0), TOBN(0xcc8f6d7e, 0xbf48e1d8), + TOBN(0x4bd407b2, 0x2b4154aa), TOBN(0x0f1d45b7, 0xff585ac5), + TOBN(0x23a97a7e, 0x36cc88be), TOBN(0x59e7c97f, 0xbec7e8f3), + TOBN(0xb5a84031, 0x900b1c9e), TOBN(0xd55e702f, 0x46980c82), + TOBN(0xf482d7ce, 0x6e74fef6), TOBN(0xf032ea15, 0xd1721d03), + TOBN(0x5983ca01, 0xc64b92ec), TOBN(0x6fb8f401, 0x378cd2bf), + TOBN(0x33205151, 0x2bd7af42), TOBN(0xdb7f1447, 0xe6cc254b), + TOBN(0x44ce6cba, 0xced4bb1b), TOBN(0xda3edbeb, 0xcf9b14ed), + TOBN(0x179727b0, 0x865a8918), TOBN(0xb06a53ed, 0x9027d831), + TOBN(0xe5db382f, 0x413001ae), TOBN(0xf8ff9406, 0xad9e530e), + TOBN(0xc9751e76, 0x3dba37bd), TOBN(0xc1d4dcb2, 0x602646de), + TOBN(0x36c3fab4, 0xd27c7026), TOBN(0x4df435c9, 0x34028492), + TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1), + TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c), + TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed), + TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d), + TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9), + TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda), + TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26), + TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801), + TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31), + TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c), + TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64), + TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b), + TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7), + TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d), + TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64), + TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d), + TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5), + TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9), + TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603), + TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); } int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, @@ -237,23 +453,10 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942) { return 1; } - if (!int_dh_bn_cpy(&to->q, from->q) || - !int_dh_bn_cpy(&to->j, from->j)) { + if (!int_dh_bn_cpy(&to->q, from->q)) { return 0; } - OPENSSL_free(to->seed); - to->seed = NULL; - to->seedlen = 0; - - if (from->seed) { - to->seed = OPENSSL_memdup(from->seed, from->seedlen); - if (!to->seed) { - return 0; - } - to->seedlen = from->seedlen; - } - return 1; } diff --git a/third_party/boringssl/kit/src/crypto/digest_extra/digest_extra.c b/third_party/boringssl/kit/src/crypto/digest_extra/digest_extra.c index 8cbb28e3..08ed671a 100644 --- a/third_party/boringssl/kit/src/crypto/digest_extra/digest_extra.c +++ b/third_party/boringssl/kit/src/crypto/digest_extra/digest_extra.c @@ -200,7 +200,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { CBB algorithm, oid, null; if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } @@ -209,7 +208,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { if (nid == kMDOIDs[i].nid) { if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } found = 1; @@ -224,7 +222,6 @@ int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_flush(cbb)) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/dsa/dsa.c b/third_party/boringssl/kit/src/crypto/dsa/dsa.c index 8e77ea39..5eb78948 100644 --- a/third_party/boringssl/kit/src/crypto/dsa/dsa.c +++ b/third_party/boringssl/kit/src/crypto/dsa/dsa.c @@ -74,6 +74,7 @@ #include "internal.h" #include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/dh/internal.h" #include "../internal.h" @@ -89,7 +90,6 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; DSA *DSA_new(void) { DSA *dsa = OPENSSL_malloc(sizeof(DSA)); if (dsa == NULL) { - OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -130,6 +130,8 @@ int DSA_up_ref(DSA *dsa) { return 1; } +unsigned DSA_bits(const DSA *dsa) { return BN_num_bits(dsa->p); } + const BIGNUM *DSA_get0_pub_key(const DSA *dsa) { return dsa->pub_key; } const BIGNUM *DSA_get0_priv_key(const DSA *dsa) { return dsa->priv_key; } @@ -200,6 +202,10 @@ int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) { dsa->g = g; } + BN_MONT_CTX_free(dsa->method_mont_p); + dsa->method_mont_p = NULL; + BN_MONT_CTX_free(dsa->method_mont_q); + dsa->method_mont_q = NULL; return 1; } @@ -214,16 +220,14 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, BIGNUM *g = NULL, *q = NULL, *p = NULL; BN_MONT_CTX *mont = NULL; int k, n = 0, m = 0; - unsigned i; int counter = 0; int r = 0; BN_CTX *ctx = NULL; unsigned int h = 2; - unsigned qsize; const EVP_MD *evpmd; evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); - qsize = EVP_MD_size(evpmd); + size_t qsize = EVP_MD_size(evpmd); if (bits < 512) { bits = 512; @@ -232,10 +236,10 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, bits = (bits + 63) / 64 * 64; if (seed_in != NULL) { - if (seed_len < (size_t)qsize) { + if (seed_len < qsize) { return 0; } - if (seed_len > (size_t)qsize) { + if (seed_len > qsize) { // Only consume as much seed as is expected. seed_len = qsize; } @@ -281,7 +285,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, OPENSSL_memcpy(buf, seed, qsize); OPENSSL_memcpy(buf2, seed, qsize); // precompute "SEED + 1" for step 7: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; @@ -293,7 +297,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) { goto err; } - for (i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { md[i] ^= buf2[i]; } @@ -337,7 +341,7 @@ int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, // now 'buf' contains "SEED + offset - 1" for (k = 0; k <= n; k++) { // obtain "SEED + offset + k" by incrementing: - for (i = qsize - 1; i < qsize; i--) { + for (size_t i = qsize - 1; i < qsize; i--) { buf[i]++; if (buf[i] != 0) { break; @@ -588,7 +592,12 @@ static int mod_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, } DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { - if (!dsa_check_parameters(dsa)) { + if (!dsa_check_key(dsa)) { + return NULL; + } + + if (dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return NULL; } @@ -609,6 +618,14 @@ DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { goto err; } + // Cap iterations so that invalid parameters do not infinite loop. This does + // not impact valid parameters because the probability of requiring even one + // retry is negligible, let alone 32. Unfortunately, DSA was mis-specified, so + // invalid parameters are reachable from most callers handling untrusted + // private keys. (The |dsa_check_key| call above is not sufficient. Checking + // whether arbitrary paremeters form a valid DSA group is expensive.) + static const int kMaxIterations = 32; + int iters = 0; redo: if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) { goto err; @@ -648,8 +665,14 @@ redo: // Redo if r or s is zero as required by FIPS 186-3: this is // very unlikely. if (BN_is_zero(r) || BN_is_zero(s)) { + iters++; + if (iters > kMaxIterations) { + OPENSSL_PUT_ERROR(DSA, DSA_R_TOO_MANY_ITERATIONS); + goto err; + } goto redo; } + ret = DSA_SIG_new(); if (ret == NULL) { goto err; @@ -683,7 +706,12 @@ int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig, int DSA_do_check_signature(int *out_valid, const uint8_t *digest, size_t digest_len, DSA_SIG *sig, const DSA *dsa) { *out_valid = 0; - if (!dsa_check_parameters(dsa)) { + if (!dsa_check_key(dsa)) { + return 0; + } + + if (dsa->pub_key == NULL) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return 0; } @@ -842,6 +870,10 @@ static size_t der_len_len(size_t len) { } int DSA_size(const DSA *dsa) { + if (dsa->q == NULL) { + return 0; + } + size_t order_len = BN_num_bytes(dsa->q); // Compute the maximum length of an |order_len| byte integer. Defensively // assume that the leading 0x00 is included. @@ -864,11 +896,6 @@ int DSA_size(const DSA *dsa) { static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv, BIGNUM **out_r) { - if (!dsa->p || !dsa->q || !dsa->g) { - OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); - return 0; - } - int ret = 0; BIGNUM k; BN_init(&k); diff --git a/third_party/boringssl/kit/src/crypto/dsa/dsa_asn1.c b/third_party/boringssl/kit/src/crypto/dsa/dsa_asn1.c index 3f3bd488..1985bb4f 100644 --- a/third_party/boringssl/kit/src/crypto/dsa/dsa_asn1.c +++ b/third_party/boringssl/kit/src/crypto/dsa/dsa_asn1.c @@ -70,15 +70,25 @@ // This function is in dsa_asn1.c rather than dsa.c because it is reachable from // |EVP_PKEY| parsers. This makes it easier for the static linker to drop most // of the DSA implementation. -int dsa_check_parameters(const DSA *dsa) { +int dsa_check_key(const DSA *dsa) { if (!dsa->p || !dsa->q || !dsa->g) { OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); return 0; } - // Reject invalid parameters. In particular, signing will infinite loop if |g| - // is zero. - if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) { + // Fully checking for invalid DSA groups is expensive, so security and + // correctness of the signature scheme depend on how |dsa| was computed. I.e. + // we leave "assurance of domain parameter validity" from FIPS 186-4 to the + // caller. However, we check bounds on all values to avoid DoS vectors even + // when domain parameters are invalid. In particular, signing will infinite + // loop if |g| is zero. + if (BN_is_negative(dsa->p) || BN_is_negative(dsa->q) || BN_is_zero(dsa->p) || + BN_is_zero(dsa->q) || !BN_is_odd(dsa->p) || !BN_is_odd(dsa->q) || + // |q| must be a prime divisor of |p - 1|, which implies |q < p|. + BN_cmp(dsa->q, dsa->p) >= 0 || + // |g| is in the multiplicative group of |p|. + BN_is_negative(dsa->g) || BN_is_zero(dsa->g) || + BN_cmp(dsa->g, dsa->p) >= 0) { OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); return 0; } @@ -97,6 +107,25 @@ int dsa_check_parameters(const DSA *dsa) { return 0; } + if (dsa->pub_key != NULL) { + // The public key is also in the multiplicative group of |p|. + if (BN_is_negative(dsa->pub_key) || BN_is_zero(dsa->pub_key) || + BN_cmp(dsa->pub_key, dsa->p) >= 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); + return 0; + } + } + + if (dsa->priv_key != NULL) { + // The private key is a non-zero element of the scalar field, determined by + // |q|. + if (BN_is_negative(dsa->priv_key) || BN_is_zero(dsa->priv_key) || + BN_cmp(dsa->priv_key, dsa->q) >= 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); + return 0; + } + } + return 1; } @@ -162,7 +191,7 @@ DSA *DSA_parse_public_key(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } return ret; @@ -200,7 +229,7 @@ DSA *DSA_parse_parameters(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } return ret; @@ -251,9 +280,10 @@ DSA *DSA_parse_private_key(CBS *cbs) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); goto err; } - if (!dsa_check_parameters(ret)) { + if (!dsa_check_key(ret)) { goto err; } + return ret; err: diff --git a/third_party/boringssl/kit/src/crypto/dsa/dsa_test.cc b/third_party/boringssl/kit/src/crypto/dsa/dsa_test.cc index 46821316..22e9e13b 100644 --- a/third_party/boringssl/kit/src/crypto/dsa/dsa_test.cc +++ b/third_party/boringssl/kit/src/crypto/dsa/dsa_test.cc @@ -69,8 +69,10 @@ #include #include #include +#include +#include -#include "../internal.h" +#include "../test/test_util.h" // The following values are taken from the updated Appendix 5 to FIPS PUB 186 @@ -168,160 +170,97 @@ static const uint8_t fips_sig_bad_r[] = { 0xdc, 0xd8, 0xc8, }; -static bssl::UniquePtr GetFIPSDSA(void) { - bssl::UniquePtr dsa(DSA_new()); +static bssl::UniquePtr GetFIPSDSAGroup(void) { + bssl::UniquePtr dsa(DSA_new()); if (!dsa) { return nullptr; } - dsa->p = BN_bin2bn(fips_p, sizeof(fips_p), nullptr); - dsa->q = BN_bin2bn(fips_q, sizeof(fips_q), nullptr); - dsa->g = BN_bin2bn(fips_g, sizeof(fips_g), nullptr); - dsa->pub_key = BN_bin2bn(fips_y, sizeof(fips_y), nullptr); - dsa->priv_key = BN_bin2bn(fips_x, sizeof(fips_x), nullptr); - if (dsa->p == nullptr || dsa->q == nullptr || dsa->g == nullptr || - dsa->pub_key == nullptr || dsa->priv_key == nullptr) { + bssl::UniquePtr p(BN_bin2bn(fips_p, sizeof(fips_p), nullptr)); + bssl::UniquePtr q(BN_bin2bn(fips_q, sizeof(fips_q), nullptr)); + bssl::UniquePtr g(BN_bin2bn(fips_g, sizeof(fips_g), nullptr)); + if (!p || !q || !g || !DSA_set0_pqg(dsa.get(), p.get(), q.get(), g.get())) { return nullptr; } + // |DSA_set0_pqg| takes ownership. + p.release(); + q.release(); + g.release(); return dsa; } -struct GenerateContext { - FILE *out = nullptr; - int ok = 0; - int num = 0; -}; - -static int GenerateCallback(int p, int n, BN_GENCB *arg) { - GenerateContext *ctx = reinterpret_cast(arg->arg); - char c = '*'; - switch (p) { - case 0: - c = '.'; - ctx->num++; - break; - case 1: - c = '+'; - break; - case 2: - c = '*'; - ctx->ok++; - break; - case 3: - c = '\n'; - } - fputc(c, ctx->out); - fflush(ctx->out); - if (!ctx->ok && p == 0 && ctx->num > 1) { - fprintf(stderr, "error in dsatest\n"); - return 0; - } - return 1; -} - -static int TestGenerate(FILE *out) { - BN_GENCB cb; - int counter, i, j; - uint8_t buf[256]; - unsigned long h; - uint8_t sig[256]; - unsigned int siglen; - - fprintf(out, "test generation of DSA parameters\n"); - - GenerateContext ctx; - ctx.out = out; - BN_GENCB_set(&cb, GenerateCallback, &ctx); - bssl::UniquePtr dsa(DSA_new()); - if (!dsa || - !DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h, - &cb)) { - return false; - } - - fprintf(out, "seed\n"); - for (i = 0; i < 20; i += 4) { - fprintf(out, "%02X%02X%02X%02X ", seed[i], seed[i + 1], seed[i + 2], - seed[i + 3]); - } - fprintf(out, "\ncounter=%d h=%ld\n", counter, h); - - if (counter != 105) { - fprintf(stderr, "counter should be 105\n"); - return false; - } - if (h != 2) { - fprintf(stderr, "h should be 2\n"); - return false; - } - - i = BN_bn2bin(dsa->q, buf); - j = sizeof(fips_q); - if (i != j || OPENSSL_memcmp(buf, fips_q, i) != 0) { - fprintf(stderr, "q value is wrong\n"); - return false; - } - - i = BN_bn2bin(dsa->p, buf); - j = sizeof(fips_p); - if (i != j || OPENSSL_memcmp(buf, fips_p, i) != 0) { - fprintf(stderr, "p value is wrong\n"); - return false; - } - - i = BN_bn2bin(dsa->g, buf); - j = sizeof(fips_g); - if (i != j || OPENSSL_memcmp(buf, fips_g, i) != 0) { - fprintf(stderr, "g value is wrong\n"); - return false; - } - - if (!DSA_generate_key(dsa.get()) || - !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa.get())) { - return false; - } - if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa.get()) != - 1) { - fprintf(stderr, "verification failure\n"); - return false; - } - - return true; -} - -static bool TestVerify(const uint8_t *sig, size_t sig_len, int expect) { - bssl::UniquePtr dsa = GetFIPSDSA(); +static bssl::UniquePtr GetFIPSDSA(void) { + bssl::UniquePtr dsa = GetFIPSDSAGroup(); if (!dsa) { - return false; + return nullptr; } - - int ret = - DSA_verify(0, fips_digest, sizeof(fips_digest), sig, sig_len, dsa.get()); - if (ret != expect) { - fprintf(stderr, "DSA_verify returned %d, want %d\n", ret, expect); - return false; + bssl::UniquePtr pub_key(BN_bin2bn(fips_y, sizeof(fips_y), nullptr)); + bssl::UniquePtr priv_key(BN_bin2bn(fips_x, sizeof(fips_x), nullptr)); + if (!pub_key || !priv_key || + !DSA_set0_key(dsa.get(), pub_key.get(), priv_key.get())) { + return nullptr; } - - // Clear any errors from a test with expected failure. - ERR_clear_error(); - return true; + // |DSA_set0_key| takes ownership. + pub_key.release(); + priv_key.release(); + return dsa; } -// TODO(davidben): Convert this file to GTest properly. -TEST(DSATest, AllTests) { - if (!TestGenerate(stdout) || - !TestVerify(fips_sig, sizeof(fips_sig), 1) || - !TestVerify(fips_sig_negative, sizeof(fips_sig_negative), -1) || - !TestVerify(fips_sig_extra, sizeof(fips_sig_extra), -1) || - !TestVerify(fips_sig_bad_length, sizeof(fips_sig_bad_length), -1) || - !TestVerify(fips_sig_bad_r, sizeof(fips_sig_bad_r), 0)) { - ADD_FAILURE() << "Tests failed"; - } +TEST(DSATest, Generate) { + bssl::UniquePtr dsa(DSA_new()); + ASSERT_TRUE(dsa); + int counter; + unsigned long h; + ASSERT_TRUE(DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h, + nullptr)); + EXPECT_EQ(counter, 105); + EXPECT_EQ(h, 2u); + + auto expect_bn_bytes = [](const char *msg, const BIGNUM *bn, + bssl::Span bytes) { + std::vector buf(BN_num_bytes(bn)); + BN_bn2bin(bn, buf.data()); + EXPECT_EQ(Bytes(buf), Bytes(bytes)) << msg; + }; + expect_bn_bytes("q value is wrong", DSA_get0_q(dsa.get()), fips_q); + expect_bn_bytes("p value is wrong", DSA_get0_p(dsa.get()), fips_p); + expect_bn_bytes("g value is wrong", DSA_get0_g(dsa.get()), fips_g); + + ASSERT_TRUE(DSA_generate_key(dsa.get())); + + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); + + EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(), + sig_len, dsa.get())); +} + +TEST(DSATest, Verify) { + bssl::UniquePtr dsa = GetFIPSDSA(); + ASSERT_TRUE(dsa); + + EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig, + sizeof(fips_sig), dsa.get())); + EXPECT_EQ(-1, + DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_negative, + sizeof(fips_sig_negative), dsa.get())); + EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_extra, + sizeof(fips_sig_extra), dsa.get())); + EXPECT_EQ(-1, + DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_length, + sizeof(fips_sig_bad_length), dsa.get())); + EXPECT_EQ(0, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_r, + sizeof(fips_sig_bad_r), dsa.get())); } TEST(DSATest, InvalidGroup) { bssl::UniquePtr dsa = GetFIPSDSA(); ASSERT_TRUE(dsa); - BN_zero(dsa->g); + bssl::UniquePtr zero(BN_new()); + ASSERT_TRUE(zero); + ASSERT_TRUE(DSA_set0_pqg(dsa.get(), /*p=*/nullptr, /*q=*/nullptr, + /*g=*/zero.release())); std::vector sig(DSA_size(dsa.get())); unsigned sig_len; @@ -332,3 +271,148 @@ TEST(DSATest, InvalidGroup) { EXPECT_EQ(ERR_LIB_DSA, ERR_GET_LIB(err)); EXPECT_EQ(DSA_R_INVALID_PARAMETERS, ERR_GET_REASON(err)); } + +// Signing and verifying should cleanly fail when the DSA object is empty. +TEST(DSATest, MissingParameters) { + bssl::UniquePtr dsa(DSA_new()); + ASSERT_TRUE(dsa); + EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig, + sizeof(fips_sig), dsa.get())); + + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); +} + +// Verifying should cleanly fail when the public key is missing. +TEST(DSATest, MissingPublic) { + bssl::UniquePtr dsa = GetFIPSDSAGroup(); + ASSERT_TRUE(dsa); + EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig, + sizeof(fips_sig), dsa.get())); +} + +// Signing should cleanly fail when the private key is missing. +TEST(DSATest, MissingPrivate) { + bssl::UniquePtr dsa = GetFIPSDSAGroup(); + ASSERT_TRUE(dsa); + + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); +} + +// A zero private key is invalid and can cause signing to loop forever. +TEST(DSATest, ZeroPrivateKey) { + bssl::UniquePtr dsa = GetFIPSDSA(); + ASSERT_TRUE(dsa); + bssl::UniquePtr zero(BN_new()); + ASSERT_TRUE(zero); + ASSERT_TRUE(DSA_set0_key(dsa.get(), /*pub_key=*/nullptr, + /*priv_key=*/zero.release())); + + static const uint8_t kZeroDigest[32] = {0}; + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + EXPECT_FALSE(DSA_sign(0, kZeroDigest, sizeof(kZeroDigest), sig.data(), + &sig_len, dsa.get())); +} + +// If the "field" is actually a ring and the "generator" of the multiplicative +// subgroup is actually nilpotent with low degree, DSA signing never completes. +// Test that we give up in the infinite loop. +TEST(DSATest, NilpotentGenerator) { + static const char kPEM[] = R"( +-----BEGIN DSA PRIVATE KEY----- +MGECAQACFQHH+MnFXh4NNlZiV/zUVb5a5ib3kwIVAOP8ZOKvDwabKzEr/moq3y1z +E3vJAhUAl/2Ylx9fWbzHdh1URsc/c6IM/TECAQECFCsjU4AZRcuks45g1NMOUeCB +Epvg +-----END DSA PRIVATE KEY----- +)"; + bssl::UniquePtr bio(BIO_new_mem_buf(kPEM, sizeof(kPEM))); + ASSERT_TRUE(bio); + bssl::UniquePtr dsa( + PEM_read_bio_DSAPrivateKey(bio.get(), nullptr, nullptr, nullptr)); + ASSERT_TRUE(dsa); + + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); +} + +TEST(DSATest, Overwrite) { + // Load an arbitrary DSA private key and use it. + static const char kPEM[] = R"( +-----BEGIN DSA PRIVATE KEY----- +MIIDTgIBAAKCAQEAyH68EuravtF+7PTFBtWJkwjmp0YJmh8e2Cdpu8ci3dZf87rk +GwXzfqYkAEkW5H4Hp0cxdICKFiqfxjSaiEauOrNV+nXWZS634hZ9H47I8HnAVS0p +5MmSmPJ7NNUowymMpyB6M6hfqHl/1pZd7avbTmnzb2SZ0kw0WLWJo6vMekepYWv9 +3o1Xove4ci00hnkr7Qo9Bh/+z84jgeT2/MTdsCVtbuMv/mbcYLhCKVWPBozDZr/D +qwhGTlomsTRvP3WIbem3b5eYhQaPuMsKiAzntcinoxQXWrIoZB+xJyF/sI013uBI +i9ePSxY3704U4QGxVM0aR/6fzORz5kh8ZjhhywIdAI9YBUR6eoGevUaLq++qXiYW +TgXBXlyqE32ESbkCggEBAL/c5GerO5g25D0QsfgVIJtlZHQOwYauuWoUudaQiyf6 +VhWLBNNTAGldkFGdtxsA42uqqZSXCki25LvN6PscGGvFy8oPWaa9TGt+l9Z5ZZiV +ShNpg71V9YuImsPB3BrQ4L6nZLfhBt6InzJ6KqjDNdg7u6lgnFKue7l6khzqNxbM +RgxHWMq7PkhMcl+RzpqbiGcxSHqraxldutqCWsnZzhKh4d4GdunuRY8GiFo0Axkb +Kn0Il3zm81ewv08F/ocu+IZQEzxTyR8YRQ99MLVbnwhVxndEdLjjetCX82l+/uEY +5fdUy0thR8odcDsvUc/tT57I+yhnno80HbpUUNw2+/sCggEAdh1wp/9CifYIp6T8 +P/rIus6KberZ2Pv/n0bl+Gv8AoToA0zhZXIfY2l0TtanKmdLqPIvjqkN0v6zGSs+ ++ahR1QzMQnK718mcsQmB4X6iP5LKgJ/t0g8LrDOxc/cNycmHq76MmF9RN5NEBz4+ +PAnRIftm/b0UQflP6uy3gRQP2X7P8ZebCytOPKTZC4oLyCtvPevSkCiiauq/RGjL +k6xqRgLxMtmuyhT+dcVbtllV1p1xd9Bppnk17/kR5VCefo/e/7DHu163izRDW8tx +SrEmiVyVkRijY3bVZii7LPfMz5eEAWEDJRuFwyNv3i6j7CKeZw2d/hzu370Ua28F +s2lmkAIcLIFUDFrbC2nViaB5ATM9ARKk6F2QwnCfGCyZ6A== +-----END DSA PRIVATE KEY----- +)"; + bssl::UniquePtr bio(BIO_new_mem_buf(kPEM, sizeof(kPEM))); + ASSERT_TRUE(bio); + bssl::UniquePtr dsa( + PEM_read_bio_DSAPrivateKey(bio.get(), nullptr, nullptr, nullptr)); + ASSERT_TRUE(dsa); + + std::vector sig(DSA_size(dsa.get())); + unsigned sig_len; + ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); + sig.resize(sig_len); + EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(), + sig.size(), dsa.get())); + + // Overwrite it with the sample key. + bssl::UniquePtr p(BN_bin2bn(fips_p, sizeof(fips_p), nullptr)); + ASSERT_TRUE(p); + bssl::UniquePtr q(BN_bin2bn(fips_q, sizeof(fips_q), nullptr)); + ASSERT_TRUE(q); + bssl::UniquePtr g(BN_bin2bn(fips_g, sizeof(fips_g), nullptr)); + ASSERT_TRUE(g); + ASSERT_TRUE(DSA_set0_pqg(dsa.get(), p.get(), q.get(), g.get())); + // |DSA_set0_pqg| takes ownership on success. + p.release(); + q.release(); + g.release(); + bssl::UniquePtr pub_key(BN_bin2bn(fips_y, sizeof(fips_y), nullptr)); + ASSERT_TRUE(pub_key); + bssl::UniquePtr priv_key(BN_bin2bn(fips_x, sizeof(fips_x), nullptr)); + ASSERT_TRUE(priv_key); + ASSERT_TRUE(DSA_set0_key(dsa.get(), pub_key.get(), priv_key.get())); + // |DSA_set0_key| takes ownership on success. + pub_key.release(); + priv_key.release(); + + // The key should now work correctly for the new parameters. + EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig, + sizeof(fips_sig), dsa.get())); + + // Test signing by verifying it round-trips through the real key. + sig.resize(DSA_size(dsa.get())); + ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(), + &sig_len, dsa.get())); + sig.resize(sig_len); + dsa = GetFIPSDSA(); + ASSERT_TRUE(dsa); + EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(), + sig.size(), dsa.get())); +} diff --git a/third_party/boringssl/kit/src/crypto/dsa/internal.h b/third_party/boringssl/kit/src/crypto/dsa/internal.h index 2d86edb2..61cf9a65 100644 --- a/third_party/boringssl/kit/src/crypto/dsa/internal.h +++ b/third_party/boringssl/kit/src/crypto/dsa/internal.h @@ -17,14 +17,34 @@ #include +#include + +#include "../internal.h" + #if defined(__cplusplus) extern "C" { #endif -// dsa_check_parameters checks that |dsa|'s group is within DoS bounds. It -// returns one on success and zero on error. -int dsa_check_parameters(const DSA *dsa); +struct dsa_st { + BIGNUM *p; + BIGNUM *q; + BIGNUM *g; + + BIGNUM *pub_key; + BIGNUM *priv_key; + + // Normally used to cache montgomery values + CRYPTO_MUTEX method_mont_lock; + BN_MONT_CTX *method_mont_p; + BN_MONT_CTX *method_mont_q; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + +// dsa_check_key performs cheap self-checks on |dsa|, and ensures it is within +// DoS bounds. It returns one on success and zero on error. +int dsa_check_key(const DSA *dsa); #if defined(__cplusplus) diff --git a/third_party/boringssl/kit/src/crypto/ec_extra/ec_asn1.c b/third_party/boringssl/kit/src/crypto/ec_extra/ec_asn1.c index 56cbbed1..5c0dab1a 100644 --- a/third_party/boringssl/kit/src/crypto/ec_extra/ec_asn1.c +++ b/third_party/boringssl/kit/src/crypto/ec_extra/ec_asn1.c @@ -67,9 +67,9 @@ #include "../internal.h" -static const unsigned kParametersTag = +static const CBS_ASN1_TAG kParametersTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; -static const unsigned kPublicKeyTag = +static const CBS_ASN1_TAG kPublicKeyTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { @@ -504,7 +504,6 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { ret = *keyp; if (ret->pub_key == NULL && (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { @@ -518,42 +517,18 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { } int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { - size_t buf_len = 0; - int new_buffer = 0; - if (key == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - - buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, - 0, NULL); - - if (outp == NULL || buf_len == 0) { - // out == NULL => just return the length of the octet string - return buf_len; + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !EC_POINT_point2cbb(&cbb, key->group, key->pub_key, key->conv_form, + NULL)) { + CBB_cleanup(&cbb); + return -1; } - - if (*outp == NULL) { - *outp = OPENSSL_malloc(buf_len); - if (*outp == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } - new_buffer = 1; - } - if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, - buf_len, NULL)) { - OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); - if (new_buffer) { - OPENSSL_free(*outp); - *outp = NULL; - } - return 0; - } - - if (!new_buffer) { - *outp += buf_len; - } - return buf_len; + int ret = CBB_finish_i2d(&cbb, outp); + // Historically, this function used the wrong return value on error. + return ret > 0 ? ret : 0; } diff --git a/third_party/boringssl/kit/src/crypto/ec_extra/hash_to_curve.c b/third_party/boringssl/kit/src/crypto/ec_extra/hash_to_curve.c index 9c824544..39403362 100644 --- a/third_party/boringssl/kit/src/crypto/ec_extra/hash_to_curve.c +++ b/third_party/boringssl/kit/src/crypto/ec_extra/hash_to_curve.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -28,7 +27,7 @@ // This file implements hash-to-curve, as described in -// draft-irtf-cfrg-hash-to-curve-07. +// draft-irtf-cfrg-hash-to-curve-16. // // This hash-to-curve implementation is written generically with the // expectation that we will eventually wish to support other curves. If it @@ -49,11 +48,17 @@ // templates to make specializing more convenient. // expand_message_xmd implements the operation described in section 5.3.1 of -// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on -// allocation failure or if |out_len| was too large. +// draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, const uint8_t *msg, size_t msg_len, const uint8_t *dst, size_t dst_len) { + // See https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/352 + if (dst_len == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + int ret = 0; const size_t block_size = EVP_MD_block_size(md); const size_t md_size = EVP_MD_size(md); @@ -61,7 +66,7 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len, EVP_MD_CTX_init(&ctx); // Long DSTs are hashed down to size. See section 5.3.3. - OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, "hashed DST still too large"); + static_assert(EVP_MAX_MD_SIZE < 256, "hashed DST still too large"); uint8_t dst_buf[EVP_MAX_MD_SIZE]; if (dst_len >= 256) { static const char kPrefix[] = "H2C-OVERSIZE-DST-"; @@ -133,7 +138,7 @@ err: // num_bytes_to_derive determines the number of bytes to derive when hashing to // a number modulo |modulus|. See the hash_to_field operation defined in -// section 5.2 of draft-irtf-cfrg-hash-to-curve-07. +// section 5.2 of draft-irtf-cfrg-hash-to-curve-16. static int num_bytes_to_derive(size_t *out, const BIGNUM *modulus, unsigned k) { size_t bits = BN_num_bits(modulus); size_t L = (bits + k + 7) / 8; @@ -166,7 +171,7 @@ static void big_endian_to_words(BN_ULONG *out, size_t num_words, } // hash_to_field implements the operation described in section 5.2 -// of draft-irtf-cfrg-hash-to-curve-07, with count = 2. |k| is the security +// of draft-irtf-cfrg-hash-to-curve-16, with count = 2. |k| is the security // factor. static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md, EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst, @@ -215,95 +220,131 @@ static inline void mul_A(const EC_GROUP *group, EC_FELEM *out, ec_felem_sub(group, out, in, &tmp); // out = -3*in } -static inline void mul_minus_A(const EC_GROUP *group, EC_FELEM *out, - const EC_FELEM *in) { - assert(group->a_is_minus3); - EC_FELEM tmp; - ec_felem_add(group, &tmp, in, in); // tmp = 2*in - ec_felem_add(group, out, &tmp, in); // out = 3*in -} - -// sgn0_le implements the operation described in section 4.1.2 of -// draft-irtf-cfrg-hash-to-curve-07. -static BN_ULONG sgn0_le(const EC_GROUP *group, const EC_FELEM *a) { +// sgn0 implements the operation described in section 4.1.2 of +// draft-irtf-cfrg-hash-to-curve-16. +static BN_ULONG sgn0(const EC_GROUP *group, const EC_FELEM *a) { uint8_t buf[EC_MAX_BYTES]; size_t len; ec_felem_to_bytes(group, buf, &len, a); return buf[len - 1] & 1; } -// map_to_curve_simple_swu implements the operation described in section 6.6.2 -// of draft-irtf-cfrg-hash-to-curve-07, using the optimization in appendix -// D.2.1. It returns one on success and zero on error. -static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, - const BN_ULONG *c1, size_t num_c1, - const EC_FELEM *c2, EC_RAW_POINT *out, - const EC_FELEM *u) { +OPENSSL_UNUSED static int is_3mod4(const EC_GROUP *group) { + return group->field.width > 0 && (group->field.d[0] & 3) == 3; +} + +// sqrt_ratio_3mod4 implements the operation described in appendix F.2.1.2 +// of draft-irtf-cfrg-hash-to-curve-16. +static BN_ULONG sqrt_ratio_3mod4(const EC_GROUP *group, const EC_FELEM *Z, + const BN_ULONG *c1, size_t num_c1, + const EC_FELEM *c2, EC_FELEM *out_y, + const EC_FELEM *u, const EC_FELEM *v) { + assert(is_3mod4(group)); + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, const EC_FELEM *b) = group->meth->felem_mul; void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = group->meth->felem_sqr; + EC_FELEM tv1, tv2, tv3, y1, y2; + felem_sqr(group, &tv1, v); // 1. tv1 = v^2 + felem_mul(group, &tv2, u, v); // 2. tv2 = u * v + felem_mul(group, &tv1, &tv1, &tv2); // 3. tv1 = tv1 * tv2 + group->meth->felem_exp(group, &y1, &tv1, c1, num_c1); // 4. y1 = tv1^c1 + felem_mul(group, &y1, &y1, &tv2); // 5. y1 = y1 * tv2 + felem_mul(group, &y2, &y1, c2); // 6. y2 = y1 * c2 + felem_sqr(group, &tv3, &y1); // 7. tv3 = y1^2 + felem_mul(group, &tv3, &tv3, v); // 8. tv3 = tv3 * v + + // 9. isQR = tv3 == u + // 10. y = CMOV(y2, y1, isQR) + // 11. return (isQR, y) + // + // Note the specification's CMOV function and our |ec_felem_select| have the + // opposite argument order. + ec_felem_sub(group, &tv1, &tv3, u); + const BN_ULONG isQR = ~ec_felem_non_zero_mask(group, &tv1); + ec_felem_select(group, out_y, isQR, &y1, &y2); + return isQR; +} + +// map_to_curve_simple_swu implements the operation described in section 6.6.2 +// of draft-irtf-cfrg-hash-to-curve-16, using the straight-line implementation +// in appendix F.2. +static void map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z, + const BN_ULONG *c1, size_t num_c1, + const EC_FELEM *c2, EC_JACOBIAN *out, + const EC_FELEM *u) { // This function requires the prime be 3 mod 4, and that A = -3. - if (group->field.width == 0 || (group->field.d[0] & 3) != 3 || - !group->a_is_minus3) { - OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); - return 0; - } + assert(is_3mod4(group)); + assert(group->a_is_minus3); - EC_FELEM tv1, tv2, tv3, tv4, xd, x1n, x2n, tmp, gxd, gx1, y1, y2; - felem_sqr(group, &tv1, u); // tv1 = u^2 - felem_mul(group, &tv3, Z, &tv1); // tv3 = Z * tv1 - felem_sqr(group, &tv2, &tv3); // tv2 = tv3^2 - ec_felem_add(group, &xd, &tv2, &tv3); // xd = tv2 + tv3 - ec_felem_add(group, &x1n, &xd, &group->one); // x1n = xd + 1 - felem_mul(group, &x1n, &x1n, &group->b); // x1n = x1n * B - mul_minus_A(group, &xd, &xd); // xd = -A * xd - BN_ULONG e1 = ec_felem_non_zero_mask(group, &xd); // e1 = xd == 0 [flipped] - mul_A(group, &tmp, Z); - ec_felem_select(group, &xd, e1, &xd, &tmp); // xd = CMOV(xd, Z * A, e1) - felem_sqr(group, &tv2, &xd); // tv2 = xd^2 - felem_mul(group, &gxd, &tv2, &xd); // gxd = tv2 * xd = xd^3 - mul_A(group, &tv2, &tv2); // tv2 = A * tv2 - felem_sqr(group, &gx1, &x1n); // gx1 = x1n^2 - ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 - felem_mul(group, &gx1, &gx1, &x1n); // gx1 = gx1 * x1n - felem_mul(group, &tv2, &group->b, &gxd); // tv2 = B * gxd - ec_felem_add(group, &gx1, &gx1, &tv2); // gx1 = gx1 + tv2 - felem_sqr(group, &tv4, &gxd); // tv4 = gxd^2 - felem_mul(group, &tv2, &gx1, &gxd); // tv2 = gx1 * gxd - felem_mul(group, &tv4, &tv4, &tv2); // tv4 = tv4 * tv2 - group->meth->felem_exp(group, &y1, &tv4, c1, num_c1); // y1 = tv4^c1 - felem_mul(group, &y1, &y1, &tv2); // y1 = y1 * tv2 - felem_mul(group, &x2n, &tv3, &x1n); // x2n = tv3 * x1n - felem_mul(group, &y2, &y1, c2); // y2 = y1 * c2 - felem_mul(group, &y2, &y2, &tv1); // y2 = y2 * tv1 - felem_mul(group, &y2, &y2, u); // y2 = y2 * u - felem_sqr(group, &tv2, &y1); // tv2 = y1^2 - felem_mul(group, &tv2, &tv2, &gxd); // tv2 = tv2 * gxd - ec_felem_sub(group, &tv3, &tv2, &gx1); - BN_ULONG e2 = - ec_felem_non_zero_mask(group, &tv3); // e2 = tv2 == gx1 [flipped] - ec_felem_select(group, &x1n, e2, &x2n, &x1n); // xn = CMOV(x2n, x1n, e2) - ec_felem_select(group, &y1, e2, &y2, &y1); // y = CMOV(y2, y1, e2) - BN_ULONG sgn0_u = sgn0_le(group, u); - BN_ULONG sgn0_y = sgn0_le(group, &y1); - BN_ULONG e3 = sgn0_u ^ sgn0_y; - e3 = ((BN_ULONG)0) - e3; // e3 = sgn0(u) == sgn0(y) [flipped] - ec_felem_neg(group, &y2, &y1); - ec_felem_select(group, &y1, e3, &y2, &y1); // y = CMOV(-y, y, e3) + void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a, + const EC_FELEM *b) = group->meth->felem_mul; + void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) = + group->meth->felem_sqr; - // Appendix D.1 describes how to convert (x1n, xd, y1, 1) to Jacobian - // coordinates. Note yd = 1. Also note that gxd computed above is xd^3. - felem_mul(group, &out->X, &x1n, &xd); // X = xn * xd - felem_mul(group, &out->Y, &y1, &gxd); // Y = yn * gxd = yn * xd^3 - out->Z = xd; // Z = xd - return 1; + EC_FELEM tv1, tv2, tv3, tv4, tv5, tv6, x, y, y1; + felem_sqr(group, &tv1, u); // 1. tv1 = u^2 + felem_mul(group, &tv1, Z, &tv1); // 2. tv1 = Z * tv1 + felem_sqr(group, &tv2, &tv1); // 3. tv2 = tv1^2 + ec_felem_add(group, &tv2, &tv2, &tv1); // 4. tv2 = tv2 + tv1 + ec_felem_add(group, &tv3, &tv2, &group->one); // 5. tv3 = tv2 + 1 + felem_mul(group, &tv3, &group->b, &tv3); // 6. tv3 = B * tv3 + + // 7. tv4 = CMOV(Z, -tv2, tv2 != 0) + const BN_ULONG tv2_non_zero = ec_felem_non_zero_mask(group, &tv2); + ec_felem_neg(group, &tv4, &tv2); + ec_felem_select(group, &tv4, tv2_non_zero, &tv4, Z); + + mul_A(group, &tv4, &tv4); // 8. tv4 = A * tv4 + felem_sqr(group, &tv2, &tv3); // 9. tv2 = tv3^2 + felem_sqr(group, &tv6, &tv4); // 10. tv6 = tv4^2 + mul_A(group, &tv5, &tv6); // 11. tv5 = A * tv6 + ec_felem_add(group, &tv2, &tv2, &tv5); // 12. tv2 = tv2 + tv5 + felem_mul(group, &tv2, &tv2, &tv3); // 13. tv2 = tv2 * tv3 + felem_mul(group, &tv6, &tv6, &tv4); // 14. tv6 = tv6 * tv4 + felem_mul(group, &tv5, &group->b, &tv6); // 15. tv5 = B * tv6 + ec_felem_add(group, &tv2, &tv2, &tv5); // 16. tv2 = tv2 + tv5 + felem_mul(group, &x, &tv1, &tv3); // 17. x = tv1 * tv3 + + // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6) + const BN_ULONG is_gx1_square = + sqrt_ratio_3mod4(group, Z, c1, num_c1, c2, &y1, &tv2, &tv6); + + felem_mul(group, &y, &tv1, u); // 19. y = tv1 * u + felem_mul(group, &y, &y, &y1); // 20. y = y * y1 + + // 21. x = CMOV(x, tv3, is_gx1_square) + ec_felem_select(group, &x, is_gx1_square, &tv3, &x); + // 22. y = CMOV(y, y1, is_gx1_square) + ec_felem_select(group, &y, is_gx1_square, &y1, &y); + + // 23. e1 = sgn0(u) == sgn0(y) + BN_ULONG sgn0_u = sgn0(group, u); + BN_ULONG sgn0_y = sgn0(group, &y); + BN_ULONG not_e1 = sgn0_u ^ sgn0_y; + not_e1 = ((BN_ULONG)0) - not_e1; + + // 24. y = CMOV(-y, y, e1) + ec_felem_neg(group, &tv1, &y); + ec_felem_select(group, &y, not_e1, &tv1, &y); + + // 25. x = x / tv4 + // + // Our output is in projective coordinates, so rather than inverting |tv4| + // now, represent (x / tv4, y) as (x * tv4, y * tv4^3, tv4). This is much more + // efficient if the caller will do further computation on the output. (If the + // caller will immediately convert to affine coordinates, it is slightly less + // efficient, but only by a few field multiplications.) + felem_mul(group, &out->X, &x, &tv4); + felem_mul(group, &out->Y, &y, &tv6); + out->Z = tv4; } static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, const EC_FELEM *Z, const EC_FELEM *c2, unsigned k, - EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len, + EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len) { EC_FELEM u0, u1; if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) { @@ -318,11 +359,9 @@ static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md, } bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1); - EC_RAW_POINT Q0, Q1; - if (!map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0) || - !map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1)) { - return 0; - } + EC_JACOBIAN Q0, Q1; + map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0); + map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1); group->meth->add(group, out, &Q0, &Q1); // R = Q0 + Q1 // All our curves have cofactor one, so |clear_cofactor| is a no-op. @@ -336,8 +375,111 @@ static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) { return ec_felem_from_bytes(group, out, bytes, len); } +// kP256Sqrt10 is sqrt(10) in P-256's field. It was computed as follows in +// python3: +// +// p = 2**256 - 2**224 + 2**192 + 2**96 - 1 +// c2 = pow(10, (p+1)//4, p) +// assert pow(c2, 2, p) == 10 +// ", ".join("0x%02x" % b for b in c2.to_bytes(256//8, 'big')) +static const uint8_t kP256Sqrt10[] = { + 0xda, 0x53, 0x8e, 0x3b, 0xe1, 0xd8, 0x9b, 0x99, 0xc9, 0x78, 0xfc, + 0x67, 0x51, 0x80, 0xaa, 0xb2, 0x7b, 0x8d, 0x1f, 0xf8, 0x4c, 0x55, + 0xd5, 0xb6, 0x2c, 0xcd, 0x34, 0x27, 0xe4, 0x33, 0xc4, 0x7f}; + +// kP384Sqrt12 is sqrt(12) in P-384's field. It was computed as follows in +// python3: +// +// p = 2**384 - 2**128 - 2**96 + 2**32 - 1 +// c2 = pow(12, (p+1)//4, p) +// assert pow(c2, 2, p) == 12 +// ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big')) +static const uint8_t kP384Sqrt12[] = { + 0x2a, 0xcc, 0xb4, 0xa6, 0x56, 0xb0, 0x24, 0x9c, 0x71, 0xf0, 0x50, 0x0e, + 0x83, 0xda, 0x2f, 0xdd, 0x7f, 0x98, 0xe3, 0x83, 0xd6, 0x8b, 0x53, 0x87, + 0x1f, 0x87, 0x2f, 0xcb, 0x9c, 0xcb, 0x80, 0xc5, 0x3c, 0x0d, 0xe1, 0xf8, + 0xa8, 0x0f, 0x7e, 0x19, 0x14, 0xe2, 0xec, 0x69, 0xf5, 0xa6, 0x26, 0xb3}; + +int ec_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group, + EC_JACOBIAN *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, + size_t msg_len) { + // See section 8.3 of draft-irtf-cfrg-hash-to-curve-16. + if (EC_GROUP_get_curve_name(group) != NID_X9_62_prime256v1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + // Z = -10, c2 = sqrt(10) + EC_FELEM Z, c2; + if (!felem_from_u8(group, &Z, 10) || + !ec_felem_from_bytes(group, &c2, kP256Sqrt10, sizeof(kP256Sqrt10))) { + return 0; + } + ec_felem_neg(group, &Z, &Z); + + return hash_to_curve(group, EVP_sha256(), &Z, &c2, /*k=*/128, out, dst, + dst_len, msg, msg_len); +} + +int EC_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group, EC_POINT *out, + const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_cmp(group, out->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_hash_to_curve_p256_xmd_sha256_sswu(group, &out->raw, dst, dst_len, + msg, msg_len); +} + +int ec_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group, + EC_JACOBIAN *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, + size_t msg_len) { + // See section 8.3 of draft-irtf-cfrg-hash-to-curve-16. + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + // Z = -12, c2 = sqrt(12) + EC_FELEM Z, c2; + if (!felem_from_u8(group, &Z, 12) || + !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) { + return 0; + } + ec_felem_neg(group, &Z, &Z); + + return hash_to_curve(group, EVP_sha384(), &Z, &c2, /*k=*/192, out, dst, + dst_len, msg, msg_len); +} + +int EC_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group, EC_POINT *out, + const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_cmp(group, out->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_hash_to_curve_p384_xmd_sha384_sswu(group, &out->raw, dst, dst_len, + msg, msg_len); +} + +int ec_hash_to_scalar_p384_xmd_sha384( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len) { + if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + return hash_to_scalar(group, EVP_sha384(), out, dst, dst_len, /*k=*/192, msg, + msg_len); +} + int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( - const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, + const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len) { // See section 8.3 of draft-irtf-cfrg-hash-to-curve-07. if (EC_GROUP_get_curve_name(group) != NID_secp384r1) { @@ -345,25 +487,10 @@ int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( return 0; } - // kSqrt1728 was computed as follows in python3: - // - // p = 2**384 - 2**128 - 2**96 + 2**32 - 1 - // z3 = 12**3 - // c2 = pow(z3, (p+1)//4, p) - // assert z3 == pow(c2, 2, p) - // ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big') - - static const uint8_t kSqrt1728[] = { - 0x01, 0x98, 0x77, 0xcc, 0x10, 0x41, 0xb7, 0x55, 0x57, 0x43, 0xc0, 0xae, - 0x2e, 0x3a, 0x3e, 0x61, 0xfb, 0x2a, 0xaa, 0x2e, 0x0e, 0x87, 0xea, 0x55, - 0x7a, 0x56, 0x3d, 0x8b, 0x59, 0x8a, 0x09, 0x40, 0xd0, 0xa6, 0x97, 0xa9, - 0xe0, 0xb9, 0xe9, 0x2c, 0xfa, 0xa3, 0x14, 0xf5, 0x83, 0xc9, 0xd0, 0x66 - }; - - // Z = -12, c2 = sqrt(1728) + // Z = -12, c2 = sqrt(12) EC_FELEM Z, c2; if (!felem_from_u8(group, &Z, 12) || - !ec_felem_from_bytes(group, &c2, kSqrt1728, sizeof(kSqrt1728))) { + !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) { return 0; } ec_felem_neg(group, &Z, &Z); diff --git a/third_party/boringssl/kit/src/crypto/ec_extra/internal.h b/third_party/boringssl/kit/src/crypto/ec_extra/internal.h index 55314ac7..8a9d9900 100644 --- a/third_party/boringssl/kit/src/crypto/ec_extra/internal.h +++ b/third_party/boringssl/kit/src/crypto/ec_extra/internal.h @@ -26,24 +26,48 @@ extern "C" { // Hash-to-curve. // -// The following functions implement primitives from -// draft-irtf-cfrg-hash-to-curve. The |dst| parameter in each function is the -// domain separation tag and must be unique for each protocol and between the -// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec -// for additional guidance on this parameter. +// Internal |EC_JACOBIAN| versions of the corresponding public APIs. + +// ec_hash_to_curve_p256_xmd_sha256_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P256_XMD:SHA-256_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int ec_hash_to_curve_p256_xmd_sha256_sswu( + const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + +// ec_hash_to_curve_p384_xmd_sha384_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P384_XMD:SHA-384_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha384_sswu( + const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + +// ec_hash_to_scalar_p384_xmd_sha384 hashes |msg| to a scalar on |group| +// and writes the result to |out|, using the hash_to_field operation from the +// P384_XMD:SHA-384_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-16, but +// generating a value modulo the group order rather than a field element. +OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha384( + const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); // ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 hashes |msg| to a point on // |group| and writes the result to |out|, implementing the // P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07. It // returns one on success and zero on error. +// +// TODO(https://crbug.com/1414562): Migrate this to the final version. OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( - const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst, - size_t dst_len, const uint8_t *msg, size_t msg_len); + const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); // ec_hash_to_scalar_p384_xmd_sha512_draft07 hashes |msg| to a scalar on |group| // and writes the result to |out|, using the hash_to_field operation from the // P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07, but // generating a value modulo the group order rather than a field element. +// +// TODO(https://crbug.com/1414562): Migrate this to the final version. OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07( const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len); diff --git a/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_extra.c b/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_extra.c index 237d973a..d275d1de 100644 --- a/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_extra.c +++ b/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_extra.c @@ -92,7 +92,7 @@ int ECDH_compute_key(void *out, size_t out_len, const EC_POINT *pub_key, return -1; } - EC_RAW_POINT shared_point; + EC_JACOBIAN shared_point; uint8_t buf[EC_MAX_BYTES]; size_t buf_len; if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) || diff --git a/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_test.cc b/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_test.cc index 4b88754f..39485259 100644 --- a/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_test.cc +++ b/third_party/boringssl/kit/src/crypto/ecdh_extra/ecdh_test.cc @@ -274,6 +274,7 @@ TEST(ECDHTest, GroupMismatch) { } bssl::UniquePtr key(EC_KEY_new()); + ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_set_group(key.get(), a.get())); ASSERT_TRUE(EC_KEY_generate_key(key.get())); diff --git a/third_party/boringssl/kit/src/crypto/ecdsa_extra/ecdsa_asn1.c b/third_party/boringssl/kit/src/crypto/ecdsa_extra/ecdsa_asn1.c index e6212cc3..8ddfb3b4 100644 --- a/third_party/boringssl/kit/src/crypto/ecdsa_extra/ecdsa_asn1.c +++ b/third_party/boringssl/kit/src/crypto/ecdsa_extra/ecdsa_asn1.c @@ -81,13 +81,11 @@ int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, } CBB cbb; - CBB_zero(&cbb); + CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)); size_t len; - if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || - !ECDSA_SIG_marshal(&cbb, s) || + if (!ECDSA_SIG_marshal(&cbb, s) || !CBB_finish(&cbb, NULL, &len)) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); - CBB_cleanup(&cbb); *sig_len = 0; goto err; } diff --git a/third_party/boringssl/kit/src/crypto/err/asn1.errordata b/third_party/boringssl/kit/src/crypto/err/asn1.errordata index 9344621b..8ba7cf62 100644 --- a/third_party/boringssl/kit/src/crypto/err/asn1.errordata +++ b/third_party/boringssl/kit/src/crypto/err/asn1.errordata @@ -44,6 +44,7 @@ ASN1,141,INVALID_BIT_STRING_BITS_LEFT ASN1,194,INVALID_BIT_STRING_PADDING ASN1,142,INVALID_BMPSTRING ASN1,143,INVALID_DIGIT +ASN1,196,INVALID_INTEGER ASN1,144,INVALID_MODIFIER ASN1,145,INVALID_NUMBER ASN1,146,INVALID_OBJECT_ENCODING @@ -90,6 +91,7 @@ ASN1,185,UNKNOWN_TAG ASN1,186,UNSUPPORTED_ANY_DEFINED_BY_TYPE ASN1,187,UNSUPPORTED_PUBLIC_KEY_TYPE ASN1,188,UNSUPPORTED_TYPE +ASN1,195,WRONG_INTEGER_TYPE ASN1,189,WRONG_PUBLIC_KEY_TYPE ASN1,190,WRONG_TAG ASN1,191,WRONG_TYPE diff --git a/third_party/boringssl/kit/src/crypto/err/conf.errordata b/third_party/boringssl/kit/src/crypto/err/conf.errordata index e6226e43..d01f50de 100644 --- a/third_party/boringssl/kit/src/crypto/err/conf.errordata +++ b/third_party/boringssl/kit/src/crypto/err/conf.errordata @@ -3,5 +3,6 @@ CONF,101,MISSING_CLOSE_SQUARE_BRACKET CONF,102,MISSING_EQUAL_SIGN CONF,103,NO_CLOSE_BRACE CONF,104,UNABLE_TO_CREATE_NEW_SECTION +CONF,107,VARIABLE_EXPANSION_NOT_SUPPORTED CONF,106,VARIABLE_EXPANSION_TOO_LONG CONF,105,VARIABLE_HAS_NO_VALUE diff --git a/third_party/boringssl/kit/src/crypto/err/dsa.errordata b/third_party/boringssl/kit/src/crypto/err/dsa.errordata index 1cf5206d..4a4b5862 100644 --- a/third_party/boringssl/kit/src/crypto/err/dsa.errordata +++ b/third_party/boringssl/kit/src/crypto/err/dsa.errordata @@ -6,3 +6,4 @@ DSA,107,INVALID_PARAMETERS DSA,101,MISSING_PARAMETERS DSA,102,MODULUS_TOO_LARGE DSA,103,NEED_NEW_SETUP_VALUES +DSA,108,TOO_MANY_ITERATIONS diff --git a/third_party/boringssl/kit/src/crypto/err/ecdsa.errordata b/third_party/boringssl/kit/src/crypto/err/ecdsa.errordata index 58ba591f..b1c60d45 100644 --- a/third_party/boringssl/kit/src/crypto/err/ecdsa.errordata +++ b/third_party/boringssl/kit/src/crypto/err/ecdsa.errordata @@ -4,3 +4,4 @@ ECDSA,101,MISSING_PARAMETERS ECDSA,102,NEED_NEW_SETUP_VALUES ECDSA,103,NOT_IMPLEMENTED ECDSA,104,RANDOM_NUMBER_GENERATION_FAILED +ECDSA,106,TOO_MANY_ITERATIONS diff --git a/third_party/boringssl/kit/src/crypto/err/err.c b/third_party/boringssl/kit/src/crypto/err/err.c index 9b6d2381..eff2dc9e 100644 --- a/third_party/boringssl/kit/src/crypto/err/err.c +++ b/third_party/boringssl/kit/src/crypto/err/err.c @@ -106,11 +106,15 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include #include #include #include +#include +#include #include #if defined(OPENSSL_WINDOWS) @@ -129,8 +133,8 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) struct err_error_st { // file contains the filename where the error occurred. const char *file; - // data contains a NUL-terminated string with optional data. It must be freed - // with |OPENSSL_free|. + // data contains a NUL-terminated string with optional data. It is allocated + // with system |malloc| and must be freed with |free| (not |OPENSSL_free|) char *data; // packed contains the error library and reason, as packed by ERR_PACK. uint32_t packed; @@ -162,7 +166,7 @@ extern const char kOpenSSLReasonStringData[]; // err_clear clears the given queued error. static void err_clear(struct err_error_st *error) { - OPENSSL_free(error->data); + free(error->data); OPENSSL_memset(error, 0, sizeof(struct err_error_st)); } @@ -170,19 +174,25 @@ static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { err_clear(dst); dst->file = src->file; if (src->data != NULL) { - dst->data = OPENSSL_strdup(src->data); + // Disable deprecated functions on msvc so it doesn't complain about strdup. + OPENSSL_MSVC_PRAGMA(warning(push)) + OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) + // We can't use OPENSSL_strdup because we don't want to call OPENSSL_malloc, + // which can affect the error stack. + dst->data = strdup(src->data); + OPENSSL_MSVC_PRAGMA(warning(pop)) } dst->packed = src->packed; dst->line = src->line; } + // global_next_library contains the next custom library value to return. static int global_next_library = ERR_NUM_LIBS; // global_next_library_mutex protects |global_next_library| from concurrent // updates. -static struct CRYPTO_STATIC_MUTEX global_next_library_mutex = - CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX global_next_library_mutex = CRYPTO_MUTEX_INIT; static void err_state_free(void *statep) { ERR_STATE *state = statep; @@ -194,15 +204,15 @@ static void err_state_free(void *statep) { for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->to_free); - OPENSSL_free(state); + free(state->to_free); + free(state); } // err_get_state gets the ERR_STATE object for the current thread. static ERR_STATE *err_get_state(void) { ERR_STATE *state = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR); if (state == NULL) { - state = OPENSSL_malloc(sizeof(ERR_STATE)); + state = malloc(sizeof(ERR_STATE)); if (state == NULL) { return NULL; } @@ -258,7 +268,10 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line, } else { *data = error->data; if (flags != NULL) { - *flags = ERR_FLAG_STRING; + // Without |ERR_FLAG_MALLOCED|, rust-openssl assumes the string has a + // static lifetime. In both cases, we retain ownership of the string, + // and the caller is not expected to free it. + *flags = ERR_FLAG_STRING | ERR_FLAG_MALLOCED; } // If this error is being removed, take ownership of data from // the error. The semantics are such that the caller doesn't @@ -267,7 +280,7 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line, // error queue. if (inc) { if (error->data != NULL) { - OPENSSL_free(state->to_free); + free(state->to_free); state->to_free = error->data; } error->data = NULL; @@ -335,7 +348,7 @@ void ERR_clear_error(void) { for (i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->to_free); + free(state->to_free); state->to_free = NULL; state->top = state->bottom = 0; @@ -353,9 +366,9 @@ void ERR_remove_thread_state(const CRYPTO_THREADID *tid) { int ERR_get_next_error_library(void) { int ret; - CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex); + CRYPTO_MUTEX_lock_write(&global_next_library_mutex); ret = global_next_library++; - CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex); + CRYPTO_MUTEX_unlock_write(&global_next_library_mutex); return ret; } @@ -629,13 +642,13 @@ static void err_set_error_data(char *data) { struct err_error_st *error; if (state == NULL || state->top == state->bottom) { - OPENSSL_free(data); + free(data); return; } error = &state->errors[state->top]; - OPENSSL_free(error->data); + free(error->data); error->data = data; } @@ -672,48 +685,42 @@ void ERR_put_error(int library, int unused, int reason, const char *file, // concatenates them and sets the result as the data on the most recent // error. static void err_add_error_vdata(unsigned num, va_list args) { - size_t alloced, new_len, len = 0, substr_len; - char *buf; + size_t total_size = 0; const char *substr; - unsigned i; + char *buf; - alloced = 80; - buf = OPENSSL_malloc(alloced + 1); - if (buf == NULL) { + va_list args_copy; + va_copy(args_copy, args); + for (size_t i = 0; i < num; i++) { + substr = va_arg(args_copy, const char *); + if (substr == NULL) { + continue; + } + size_t substr_len = strlen(substr); + if (SIZE_MAX - total_size < substr_len) { + return; // Would overflow. + } + total_size += substr_len; + } + va_end(args_copy); + if (total_size == SIZE_MAX) { + return; // Would overflow. + } + total_size += 1; // NUL terminator. + if ((buf = malloc(total_size)) == NULL) { return; } - - for (i = 0; i < num; i++) { + buf[0] = '\0'; + for (size_t i = 0; i < num; i++) { substr = va_arg(args, const char *); if (substr == NULL) { continue; } - - substr_len = strlen(substr); - new_len = len + substr_len; - if (new_len > alloced) { - char *new_buf; - - if (alloced + 20 + 1 < alloced) { - // overflow. - OPENSSL_free(buf); - return; - } - - alloced = new_len + 20; - new_buf = OPENSSL_realloc(buf, alloced + 1); - if (new_buf == NULL) { - OPENSSL_free(buf); - return; - } - buf = new_buf; + if (OPENSSL_strlcat(buf, substr, total_size) >= total_size) { + assert(0); // should not be possible. } - - OPENSSL_memcpy(buf + len, substr, substr_len); - len = new_len; } - - buf[len] = 0; + va_end(args); err_set_error_data(buf); } @@ -725,21 +732,13 @@ void ERR_add_error_data(unsigned count, ...) { } void ERR_add_error_dataf(const char *format, ...) { + char *buf = NULL; va_list ap; - char *buf; - static const unsigned buf_len = 256; - - // A fixed-size buffer is used because va_copy (which would be needed in - // order to call vsnprintf twice and measure the buffer) wasn't defined until - // C99. - buf = OPENSSL_malloc(buf_len + 1); - if (buf == NULL) { - return; - } va_start(ap, format); - BIO_vsnprintf(buf, buf_len, format, ap); - buf[buf_len] = 0; + if (OPENSSL_vasprintf_internal(&buf, format, ap, /*system_malloc=*/1) == -1) { + return; + } va_end(ap); err_set_error_data(buf); @@ -751,13 +750,20 @@ void ERR_set_error_data(char *data, int flags) { assert(0); return; } + // Disable deprecated functions on msvc so it doesn't complain about strdup. + OPENSSL_MSVC_PRAGMA(warning(push)) + OPENSSL_MSVC_PRAGMA(warning(disable : 4996)) + // We can not use OPENSSL_strdup because we don't want to call OPENSSL_malloc, + // which can affect the error stack. + char *copy = strdup(data); + OPENSSL_MSVC_PRAGMA(warning(pop)) + if (copy != NULL) { + err_set_error_data(copy); + } if (flags & ERR_FLAG_MALLOCED) { - err_set_error_data(data); - } else { - char *copy = OPENSSL_strdup(data); - if (copy != NULL) { - err_set_error_data(copy); - } + // We can not take ownership of |data| directly because it is allocated with + // |OPENSSL_malloc| and we will free it with system |free| later. + OPENSSL_free(data); } } @@ -819,8 +825,8 @@ void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) { for (size_t i = 0; i < state->num_errors; i++) { err_clear(&state->errors[i]); } - OPENSSL_free(state->errors); - OPENSSL_free(state); + free(state->errors); + free(state); } ERR_SAVE_STATE *ERR_save_state(void) { @@ -829,7 +835,7 @@ ERR_SAVE_STATE *ERR_save_state(void) { return NULL; } - ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE)); + ERR_SAVE_STATE *ret = malloc(sizeof(ERR_SAVE_STATE)); if (ret == NULL) { return NULL; } @@ -839,9 +845,9 @@ ERR_SAVE_STATE *ERR_save_state(void) { ? state->top - state->bottom : ERR_NUM_ERRORS + state->top - state->bottom; assert(num_errors < ERR_NUM_ERRORS); - ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st)); + ret->errors = malloc(num_errors * sizeof(struct err_error_st)); if (ret->errors == NULL) { - OPENSSL_free(ret); + free(ret); return NULL; } OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st)); diff --git a/third_party/boringssl/kit/src/crypto/err/err_data_generate.go b/third_party/boringssl/kit/src/crypto/err/err_data_generate.go index e8aefd8f..d4a7c28a 100644 --- a/third_party/boringssl/kit/src/crypto/err/err_data_generate.go +++ b/third_party/boringssl/kit/src/crypto/err/err_data_generate.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2015, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main @@ -115,23 +117,8 @@ func (st *stringList) Add(key uint32, value string) error { return nil } -// keySlice is a type that implements sorting of entries values. -type keySlice []uint32 - -func (ks keySlice) Len() int { - return len(ks) -} - -func (ks keySlice) Less(i, j int) bool { - return (ks[i] >> 15) < (ks[j] >> 15) -} - -func (ks keySlice) Swap(i, j int) { - ks[i], ks[j] = ks[j], ks[i] -} - func (st *stringList) buildList() []uint32 { - sort.Sort(keySlice(st.entries)) + sort.Slice(st.entries, func(i, j int) bool { return (st.entries[i] >> 15) < (st.entries[j] >> 15) }) return st.entries } @@ -270,15 +257,15 @@ func main() { #include #include -#include +#include `) for i, name := range libraryNames { - fmt.Fprintf(out, "OPENSSL_STATIC_ASSERT(ERR_LIB_%s == %d, \"library value changed\");\n", name, i+1) + fmt.Fprintf(out, "static_assert(ERR_LIB_%s == %d, \"library value changed\");\n", name, i+1) } - fmt.Fprintf(out, "OPENSSL_STATIC_ASSERT(ERR_NUM_LIBS == %d, \"number of libraries changed\");\n", len(libraryNames)+1) + fmt.Fprintf(out, "static_assert(ERR_NUM_LIBS == %d, \"number of libraries changed\");\n", len(libraryNames)+1) out.WriteString("\n") e.reasons.WriteTo(out, "Reason") diff --git a/third_party/boringssl/kit/src/crypto/err/err_test.cc b/third_party/boringssl/kit/src/crypto/err/err_test.cc index 5dbe7765..8e9f03c6 100644 --- a/third_party/boringssl/kit/src/crypto/err/err_test.cc +++ b/third_party/boringssl/kit/src/crypto/err/err_test.cc @@ -71,7 +71,7 @@ TEST(ErrTest, PutError) { EXPECT_STREQ("test", file); EXPECT_EQ(4, line); - EXPECT_TRUE(flags & ERR_FLAG_STRING); + EXPECT_EQ(flags, ERR_FLAG_STRING | ERR_FLAG_MALLOCED); EXPECT_EQ(1, ERR_GET_LIB(packed_error)); EXPECT_EQ(2, ERR_GET_REASON(packed_error)); EXPECT_STREQ("testing", data); @@ -167,7 +167,7 @@ TEST(ErrTest, SaveAndRestore) { EXPECT_STREQ("test1.c", file); EXPECT_EQ(line, 1); EXPECT_STREQ(data, "data1"); - EXPECT_EQ(flags, ERR_FLAG_STRING); + EXPECT_EQ(flags, ERR_FLAG_STRING | ERR_FLAG_MALLOCED); // The state may be restored, both over an empty and non-empty state. for (unsigned i = 0; i < 2; i++) { @@ -180,7 +180,7 @@ TEST(ErrTest, SaveAndRestore) { EXPECT_STREQ("test1.c", file); EXPECT_EQ(line, 1); EXPECT_STREQ(data, "data1"); - EXPECT_EQ(flags, ERR_FLAG_STRING); + EXPECT_EQ(flags, ERR_FLAG_STRING | ERR_FLAG_MALLOCED); packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); EXPECT_EQ(ERR_GET_LIB(packed_error), 2); @@ -196,7 +196,7 @@ TEST(ErrTest, SaveAndRestore) { EXPECT_STREQ("test3.c", file); EXPECT_EQ(line, 3); EXPECT_STREQ(data, "data3"); - EXPECT_EQ(flags, ERR_FLAG_STRING); + EXPECT_EQ(flags, ERR_FLAG_STRING | ERR_FLAG_MALLOCED); // The error queue is now empty for the next iteration. EXPECT_EQ(0u, ERR_get_error()); diff --git a/third_party/boringssl/kit/src/crypto/err/pkcs8.errordata b/third_party/boringssl/kit/src/crypto/err/pkcs8.errordata index 9aac7e23..02a3fe31 100644 --- a/third_party/boringssl/kit/src/crypto/err/pkcs8.errordata +++ b/third_party/boringssl/kit/src/crypto/err/pkcs8.errordata @@ -1,3 +1,4 @@ +PKCS8,133,AMBIGUOUS_FRIENDLY_NAME PKCS8,129,BAD_ITERATION_COUNT PKCS8,100,BAD_PKCS12_DATA PKCS8,101,BAD_PKCS12_VERSION diff --git a/third_party/boringssl/kit/src/crypto/err/ssl.errordata b/third_party/boringssl/kit/src/crypto/err/ssl.errordata index 68791344..4205402a 100644 --- a/third_party/boringssl/kit/src/crypto/err/ssl.errordata +++ b/third_party/boringssl/kit/src/crypto/err/ssl.errordata @@ -90,6 +90,7 @@ SSL,301,INVALID_DELEGATED_CREDENTIAL SSL,318,INVALID_ECH_CONFIG_LIST SSL,317,INVALID_ECH_PUBLIC_NAME SSL,159,INVALID_MESSAGE +SSL,320,INVALID_OUTER_EXTENSION SSL,251,INVALID_OUTER_RECORD_TYPE SSL,269,INVALID_SCT_LIST SSL,295,INVALID_SIGNATURE_ALGORITHM @@ -133,7 +134,6 @@ SSL,289,OCSP_CB_ERROR SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED SSL,268,OLD_SESSION_PRF_HASH_MISMATCH SSL,188,OLD_SESSION_VERSION_NOT_RETURNED -SSL,320,OUTER_EXTENSION_NOT_FOUND SSL,189,OUTPUT_ALIASES_INPUT SSL,190,PARSE_TLSEXT SSL,191,PATH_TOO_LONG diff --git a/third_party/boringssl/kit/src/crypto/err/x509.errordata b/third_party/boringssl/kit/src/crypto/err/x509.errordata index ffa42676..e30d667b 100644 --- a/third_party/boringssl/kit/src/crypto/err/x509.errordata +++ b/third_party/boringssl/kit/src/crypto/err/x509.errordata @@ -13,6 +13,7 @@ X509,110,INVALID_DIRECTORY X509,139,INVALID_FIELD_FOR_VERSION X509,111,INVALID_FIELD_NAME X509,136,INVALID_PARAMETER +X509,144,INVALID_POLICY_EXTENSION X509,112,INVALID_PSS_PARAMETERS X509,113,INVALID_TRUST X509,140,INVALID_VERSION @@ -25,8 +26,11 @@ X509,135,NAME_TOO_LONG X509,119,NEWER_CRL_NOT_NEWER X509,120,NOT_PKCS7_SIGNED_DATA X509,121,NO_CERTIFICATES_INCLUDED +X509,141,NO_CERTIFICATE_FOUND +X509,142,NO_CERTIFICATE_OR_CRL_FOUND X509,122,NO_CERT_SET_FOR_US_TO_VERIFY X509,123,NO_CRLS_INCLUDED +X509,143,NO_CRL_FOUND X509,124,NO_CRL_NUMBER X509,125,PUBLIC_KEY_DECODE_ERROR X509,126,PUBLIC_KEY_ENCODE_ERROR diff --git a/third_party/boringssl/kit/src/crypto/evp/evp.c b/third_party/boringssl/kit/src/crypto/evp/evp.c index bb316450..37b3631d 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp.c +++ b/third_party/boringssl/kit/src/crypto/evp/evp.c @@ -85,7 +85,6 @@ EVP_PKEY *EVP_PKEY_new(void) { ret = OPENSSL_malloc(sizeof(EVP_PKEY)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } @@ -99,7 +98,7 @@ EVP_PKEY *EVP_PKEY_new(void) { static void free_it(EVP_PKEY *pkey) { if (pkey->ameth && pkey->ameth->pkey_free) { pkey->ameth->pkey_free(pkey); - pkey->pkey.ptr = NULL; + pkey->pkey = NULL; pkey->type = EVP_PKEY_NONE; } } @@ -153,21 +152,35 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (to->type != from->type) { + if (to->type == EVP_PKEY_NONE) { + if (!EVP_PKEY_set_type(to, from->type)) { + return 0; + } + } else if (to->type != from->type) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); - goto err; + return 0; } if (EVP_PKEY_missing_parameters(from)) { OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); - goto err; + return 0; + } + + // Once set, parameters may not change. + if (!EVP_PKEY_missing_parameters(to)) { + if (EVP_PKEY_cmp_parameters(to, from) == 1) { + return 1; + } + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + return 0; } if (from->ameth && from->ameth->param_copy) { return from->ameth->param_copy(to, from); } -err: + // TODO(https://crbug.com/boringssl/536): If the algorithm takes no + // parameters, copying them should vacuously succeed. return 0; } @@ -216,6 +229,13 @@ static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { } } +static void evp_pkey_set_method(EVP_PKEY *pkey, + const EVP_PKEY_ASN1_METHOD *method) { + free_it(pkey); + pkey->ameth = method; + pkey->type = pkey->ameth->pkey_id; +} + int EVP_PKEY_type(int nid) { const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid); if (meth == NULL) { @@ -233,7 +253,9 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { } int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { - return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key); + evp_pkey_set_method(pkey, &rsa_asn1_meth); + pkey->pkey = key; + return key != NULL; } RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { @@ -241,7 +263,7 @@ RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } - return pkey->pkey.rsa; + return pkey->pkey; } RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { @@ -261,7 +283,9 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { } int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { - return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key); + evp_pkey_set_method(pkey, &dsa_asn1_meth); + pkey->pkey = key; + return key != NULL; } DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { @@ -269,7 +293,7 @@ DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return NULL; } - return pkey->pkey.dsa; + return pkey->pkey; } DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { @@ -289,7 +313,9 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { } int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { - return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); + evp_pkey_set_method(pkey, &ec_asn1_meth); + pkey->pkey = key; + return key != NULL; } EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { @@ -297,7 +323,7 @@ EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); return NULL; } - return pkey->pkey.ec; + return pkey->pkey; } EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { @@ -312,21 +338,32 @@ DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { return NULL; } DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey) { return NULL; } int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { - if (!EVP_PKEY_set_type(pkey, type)) { - return 0; + // This function can only be used to assign RSA, DSA, and EC keys. Other key + // types have internal representations which are not exposed through the + // public API. + switch (type) { + case EVP_PKEY_RSA: + return EVP_PKEY_assign_RSA(pkey, key); + case EVP_PKEY_DSA: + return EVP_PKEY_assign_DSA(pkey, key); + case EVP_PKEY_EC: + return EVP_PKEY_assign_EC_KEY(pkey, key); } - pkey->pkey.ptr = key; - return key != NULL; + + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", type); + return 0; } int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { - const EVP_PKEY_ASN1_METHOD *ameth; - - if (pkey && pkey->pkey.ptr) { + if (pkey && pkey->pkey) { + // This isn't strictly necessary, but historically |EVP_PKEY_set_type| would + // clear |pkey| even if |evp_pkey_asn1_find| failed, so we preserve that + // behavior. free_it(pkey); } - ameth = evp_pkey_asn1_find(type); + const EVP_PKEY_ASN1_METHOD *ameth = evp_pkey_asn1_find(type); if (ameth == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", type); @@ -334,8 +371,7 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { } if (pkey) { - pkey->ameth = ameth; - pkey->type = pkey->ameth->pkey_id; + evp_pkey_set_method(pkey, ameth); } return 1; @@ -416,6 +452,8 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { if (a->ameth && a->ameth->param_cmp) { return a->ameth->param_cmp(a, b); } + // TODO(https://crbug.com/boringssl/536): If the algorithm doesn't use + // parameters, they should compare as vacuously equal. return -2; } @@ -432,7 +470,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { void *EVP_PKEY_get0(const EVP_PKEY *pkey) { // Node references, but never calls this function, so for now we return NULL. // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc., - // rather than reading |pkey->pkey.ptr| directly. This avoids problems if our + // rather than reading |pkey->pkey| directly. This avoids problems if our // internal representation does not match the type the caller expects from // OpenSSL. return NULL; @@ -448,6 +486,25 @@ void OpenSSL_add_all_digests(void) {} void EVP_cleanup(void) {} +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + if (pkey->ameth->set1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->set1_tls_encodedpoint(pkey, in, len); +} + +size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { + if (pkey->ameth->get1_tls_encodedpoint == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return pkey->ameth->get1_tls_encodedpoint(pkey, out_ptr); +} + int EVP_PKEY_base_id(const EVP_PKEY *pkey) { // OpenSSL has two notions of key type because it supports multiple OIDs for // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling diff --git a/third_party/boringssl/kit/src/crypto/evp/evp_asn1.c b/third_party/boringssl/kit/src/crypto/evp/evp_asn1.c index da099816..f270c3e7 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/evp_asn1.c @@ -336,11 +336,11 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { switch (key->type) { case EVP_PKEY_RSA: - return i2d_RSAPublicKey(key->pkey.rsa, outp); + return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp); case EVP_PKEY_DSA: - return i2d_DSAPublicKey(key->pkey.dsa, outp); + return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(key), outp); case EVP_PKEY_EC: - return i2o_ECPublicKey(key->pkey.ec, outp); + return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(key), outp); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return -1; diff --git a/third_party/boringssl/kit/src/crypto/evp/evp_ctx.c b/third_party/boringssl/kit/src/crypto/evp/evp_ctx.c index 9ca2c558..771f13f0 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp_ctx.c +++ b/third_party/boringssl/kit/src/crypto/evp/evp_ctx.c @@ -71,6 +71,7 @@ static const EVP_PKEY_METHOD *const evp_methods[] = { &ec_pkey_meth, &ed25519_pkey_meth, &x25519_pkey_meth, + &hkdf_pkey_meth, }; static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { @@ -83,28 +84,10 @@ static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { return NULL; } -static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { - EVP_PKEY_CTX *ret; - const EVP_PKEY_METHOD *pmeth; - - if (id == -1) { - if (!pkey || !pkey->ameth) { - return NULL; - } - id = pkey->ameth->pkey_id; - } - - pmeth = evp_pkey_meth_find(id); - - if (pmeth == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - ERR_add_error_dataf("algorithm %d", id); - return NULL; - } - - ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); +static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, + const EVP_PKEY_METHOD *pmeth) { + EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); if (!ret) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); @@ -130,11 +113,30 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { } EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { - return evp_pkey_ctx_new(pkey, e, -1); + if (pkey == NULL || pkey->ameth == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + const EVP_PKEY_METHOD *pkey_method = pkey->ameth->pkey_method; + if (pkey_method == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", pkey->ameth->pkey_id); + return NULL; + } + + return evp_pkey_ctx_new(pkey, e, pkey_method); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - return evp_pkey_ctx_new(NULL, e, id); + const EVP_PKEY_METHOD *pkey_method = evp_pkey_meth_find(id); + if (pkey_method == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", id); + return NULL; + } + + return evp_pkey_ctx_new(NULL, e, pkey_method); } void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { diff --git a/third_party/boringssl/kit/src/crypto/evp/evp_extra_test.cc b/third_party/boringssl/kit/src/crypto/evp/evp_extra_test.cc index f5205988..948bfb5b 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp_extra_test.cc +++ b/third_party/boringssl/kit/src/crypto/evp/evp_extra_test.cc @@ -478,6 +478,319 @@ TEST(EVPExtraTest, d2i_AutoPrivateKey) { ERR_clear_error(); } +static bssl::UniquePtr ParsePrivateKey(int type, const uint8_t *in, + size_t len) { + const uint8_t *ptr = in; + bssl::UniquePtr pkey(d2i_PrivateKey(type, nullptr, &ptr, len)); + if (!pkey) { + return nullptr; + } + + EXPECT_EQ(in + len, ptr); + return pkey; +} + +static std::string PrintToString(const EVP_PKEY *pkey, int indent, + int (*print_func)(BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)) { + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + const uint8_t *data; + size_t len; + if (!bio || !print_func(bio.get(), pkey, indent, nullptr) || + !BIO_mem_contents(bio.get(), &data, &len)) { + ADD_FAILURE() << "Error printing."; + return ""; + } + return std::string(data, data + len); +} + +TEST(EVPExtraTest, Print) { + bssl::UniquePtr rsa = ParsePrivateKey( + EVP_PKEY_RSA, kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER)); + ASSERT_TRUE(rsa); + EXPECT_EQ(PrintToString(rsa.get(), /*indent=*/2, &EVP_PKEY_print_params), + " Parameters algorithm unsupported\n"); + EXPECT_EQ(PrintToString(rsa.get(), /*indent=*/2, &EVP_PKEY_print_public), + R"( Public-Key: (1024 bit) + Modulus: + 00:f8:b8:6c:83:b4:bc:d9:a8:57:c0:a5:b4:59:76: + 8c:54:1d:79:eb:22:52:04:7e:d3:37:eb:41:fd:83: + f9:f0:a6:85:15:34:75:71:5a:84:a8:3c:d2:ef:5a: + 4e:d3:de:97:8a:dd:ff:bb:cf:0a:aa:86:92:be:b8: + 50:e4:cd:6f:80:33:30:76:13:8f:ca:7b:dc:ec:5a: + ca:63:c7:03:25:ef:a8:8a:83:58:76:20:fa:16:77: + d7:79:92:63:01:48:1a:d8:7b:67:f1:52:55:49:4e: + d6:6e:4a:5c:d7:7a:37:36:0c:de:dd:8f:44:e8:c2: + a7:2c:2b:b5:af:64:4b:61:07 + Exponent: 65537 (0x10001) +)"); + EXPECT_EQ(PrintToString(rsa.get(), /*indent=*/2, &EVP_PKEY_print_private), + R"( Private-Key: (1024 bit) + modulus: + 00:f8:b8:6c:83:b4:bc:d9:a8:57:c0:a5:b4:59:76: + 8c:54:1d:79:eb:22:52:04:7e:d3:37:eb:41:fd:83: + f9:f0:a6:85:15:34:75:71:5a:84:a8:3c:d2:ef:5a: + 4e:d3:de:97:8a:dd:ff:bb:cf:0a:aa:86:92:be:b8: + 50:e4:cd:6f:80:33:30:76:13:8f:ca:7b:dc:ec:5a: + ca:63:c7:03:25:ef:a8:8a:83:58:76:20:fa:16:77: + d7:79:92:63:01:48:1a:d8:7b:67:f1:52:55:49:4e: + d6:6e:4a:5c:d7:7a:37:36:0c:de:dd:8f:44:e8:c2: + a7:2c:2b:b5:af:64:4b:61:07 + publicExponent: 65537 (0x10001) + privateExponent: + 74:88:64:3f:69:45:3a:6d:c7:7f:b9:a3:c0:6e:ec: + dc:d4:5a:b5:32:85:5f:19:d4:f8:d4:3f:3c:fa:c2: + f6:5f:ee:e6:ba:87:74:2e:c7:0c:d4:42:b8:66:85: + 9c:7b:24:61:aa:16:11:f6:b5:b6:a4:0a:c9:55:2e: + 81:a5:47:61:cb:25:8f:c2:15:7b:0e:7c:36:9f:3a: + da:58:86:1c:5b:83:79:e6:2b:cc:e6:fa:2c:61:f2: + 78:80:1b:e2:f3:9d:39:2b:65:57:91:3d:71:99:73: + a5:c2:79:20:8c:07:4f:e5:b4:60:1f:99:a2:b1:4f: + 0c:ef:bc:59:53:00:7d:b1 + prime1: + 00:fc:7e:23:65:70:f8:ce:d3:40:41:80:6a:1d:01: + d6:01:ff:b6:1b:3d:3d:59:09:33:79:c0:4f:de:96: + 27:4b:18:c6:d9:78:f1:f4:35:46:e9:7c:42:7a:5d: + 9f:ef:54:b8:f7:9f:c4:33:6c:f3:8c:32:46:87:67: + 30:7b:a7:ac:e3 + prime2: + 00:fc:2c:df:0c:0d:88:f5:b1:92:a8:93:47:63:55: + f5:ca:58:43:ba:1c:e5:9e:b6:95:05:cd:b5:82:df: + eb:04:53:9d:bd:c2:38:16:b3:62:dd:a1:46:db:6d: + 97:93:9f:8a:c3:9b:64:7e:42:e3:32:57:19:1b:d5: + 6e:85:fa:b8:8d + exponent1: + 00:bc:3d:de:6d:d6:97:e8:ba:9e:81:37:17:e5:a0: + 64:c9:00:b7:e7:fe:f4:29:d9:2e:43:6b:19:20:bd: + 99:75:e7:76:f8:d3:ae:af:7e:b8:eb:81:f4:9d:fe: + 07:2b:0b:63:0b:5a:55:90:71:7d:f1:db:d9:b1:41: + 41:68:2f:4e:39 + exponent2: + 5a:34:66:d8:f5:e2:7f:18:b5:00:6e:26:84:27:14: + 93:fb:fc:c6:0f:5e:27:e6:e1:e9:c0:8a:e4:34:da: + e9:a2:4b:73:bc:8c:b9:ba:13:6c:7a:2b:51:84:a3: + 4a:e0:30:10:06:7e:ed:17:5a:14:00:c9:ef:85:ea: + 52:2c:bc:65 + coefficient: + 51:e3:f2:83:19:9b:c4:1e:2f:50:3d:df:5a:a2:18: + ca:5f:2e:49:af:6f:cc:fa:65:77:94:b5:a1:0a:a9: + d1:8a:39:37:f4:0b:a0:d7:82:27:5e:ae:17:17:a1: + 1e:54:34:bf:6e:c4:8e:99:5d:08:f1:2d:86:9d:a5: + 20:1b:e5:df +)"); + + bssl::UniquePtr dsa = ParsePrivateKey( + EVP_PKEY_DSA, kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER)); + ASSERT_TRUE(dsa); + EXPECT_EQ(PrintToString(dsa.get(), /*indent=*/2, &EVP_PKEY_print_params), + R"( DSA-Parameters: (2048 bit) + P: + 00:9e:12:fa:b3:de:12:21:35:01:dd:82:aa:10:ca: + 2d:10:1d:2d:4e:bf:ef:4d:2a:3f:8d:aa:0f:e0:ce: + da:d8:d6:af:85:61:6a:a2:f3:25:2c:0a:2b:5a:6d: + b0:9e:6f:14:90:0e:0d:db:83:11:87:6d:d8:f9:66: + 95:25:f9:9e:d6:59:49:e1:84:d5:06:47:93:27:11: + 69:a2:28:68:0b:95:ec:12:f5:9a:8e:20:b2:1f:2b: + 58:eb:2a:20:12:d3:5b:de:2e:e3:51:82:2f:e8:f3: + 2d:0a:33:05:65:dc:ce:5c:67:2b:72:59:c1:4b:24: + 33:d0:b5:b2:ca:2b:2d:b0:ab:62:6e:8f:13:f4:7f: + e0:34:5d:90:4e:72:94:bb:03:8e:9c:e2:1a:9e:58: + 0b:83:35:62:78:70:6c:fe:76:84:36:c6:9d:e1:49: + cc:ff:98:b4:aa:b8:cb:4f:63:85:c9:f1:02:ce:59: + 34:6e:ae:ef:27:e0:ad:22:2d:53:d6:e8:9c:c8:cd: + e5:77:6d:d0:00:57:b0:3f:2d:88:ab:3c:ed:ba:fd: + 7b:58:5f:0b:7f:78:35:e1:7a:37:28:bb:f2:5e:a6: + 25:72:f2:45:dc:11:1f:3c:e3:9c:b6:ff:ac:c3:1b: + 0a:27:90:e7:bd:e9:02:24:ea:9b:09:31:53:62:af: + 3d:2b + Q: + 00:f3:81:dc:f5:3e:bf:72:4f:8b:2e:5c:a8:2c:01: + 0f:b4:b5:ed:a9:35:8d:0f:d8:8e:d2:78:58:94:88: + b5:4f:c3 + G: + 0c:40:2a:72:5d:cc:3a:62:e0:2b:f4:cf:43:cd:17: + f4:a4:93:59:12:20:22:36:69:cf:41:93:ed:ab:42: + 3a:d0:8d:fb:55:2e:30:8a:6a:57:a5:ff:bc:7c:d0: + fb:20:87:f8:1f:8d:f0:cb:08:ab:21:33:28:7d:2b: + 69:68:71:4a:94:f6:33:c9:40:84:5a:48:a3:e1:67: + 08:dd:e7:61:cc:6a:8e:ab:2d:84:db:21:b6:ea:5b: + 07:68:14:93:cc:9c:31:fb:c3:68:b2:43:f6:dd:f8: + c9:32:a8:b4:03:8f:44:e7:b1:5c:a8:76:34:4a:14: + 78:59:f2:b4:3b:39:45:86:68:ad:5e:0a:1a:9a:66: + 95:46:dd:28:12:e3:b3:61:7a:0a:ef:99:d5:8e:3b: + b4:cc:87:fd:94:22:5e:01:d2:dc:c4:69:a7:72:68: + 14:6c:51:91:8f:18:e8:b4:d7:0a:a1:f0:c7:62:3b: + cc:52:cf:37:31:d3:86:41:b2:d2:83:0b:7e:ec:b2: + f0:95:52:ff:13:7d:04:6e:49:4e:7f:33:c3:59:00: + 02:b1:6d:1b:97:d9:36:fd:a2:8f:90:c3:ed:3c:a3: + 53:38:16:8a:c1:6f:77:c3:c5:7a:dc:2e:8f:7c:6c: + 22:56:e4:1a:5f:65:45:05:90:db:b5:bc:f0:6d:66: + 61 +)"); + EXPECT_EQ(PrintToString(dsa.get(), /*indent=*/2, &EVP_PKEY_print_public), + R"( Public-Key: (2048 bit) + pub: + 31:97:31:a1:4e:38:56:88:db:94:1d:bf:65:5c:da: + 4b:c2:10:de:74:20:03:ce:13:60:f2:25:1d:55:7c: + 5d:94:82:54:08:53:db:85:95:bf:dd:5e:50:d5:96: + e0:79:51:1b:bf:4d:4e:b9:3a:c5:ee:c4:5e:98:75: + 7b:be:ff:30:e6:d0:7b:a6:f1:bc:29:ea:df:ec:f3: + 8b:fa:83:11:9f:3f:f0:5d:06:51:32:aa:21:fc:26: + 17:e7:50:c2:16:ba:fa:54:b7:7e:1d:2c:a6:a3:41: + 66:33:94:83:b9:bf:a0:4f:bd:a6:fd:2c:81:58:35: + 33:39:c0:6d:33:40:56:64:12:5a:cd:35:53:21:78: + 8f:27:24:37:66:8a:df:5e:5f:63:fc:8b:2d:ef:57: + db:40:25:d5:17:53:0b:e4:a5:ae:54:bf:46:4f:a6: + 79:c3:74:fa:1f:85:34:64:6d:c5:03:eb:72:98:80: + 7b:c0:8f:35:11:a7:09:eb:51:e0:b0:ac:92:14:f2: + ad:37:95:5a:ba:8c:c4:db:ed:c4:4e:8b:8f:84:33: + 64:f8:57:12:d7:08:7e:90:66:df:91:50:23:f2:73: + c0:6b:b1:15:dd:64:d7:c9:75:17:73:72:da:33:c4: + 6f:a5:47:a1:cc:d1:c6:62:e5:ca:ab:5f:2a:8f:6b: + cc + P: + 00:9e:12:fa:b3:de:12:21:35:01:dd:82:aa:10:ca: + 2d:10:1d:2d:4e:bf:ef:4d:2a:3f:8d:aa:0f:e0:ce: + da:d8:d6:af:85:61:6a:a2:f3:25:2c:0a:2b:5a:6d: + b0:9e:6f:14:90:0e:0d:db:83:11:87:6d:d8:f9:66: + 95:25:f9:9e:d6:59:49:e1:84:d5:06:47:93:27:11: + 69:a2:28:68:0b:95:ec:12:f5:9a:8e:20:b2:1f:2b: + 58:eb:2a:20:12:d3:5b:de:2e:e3:51:82:2f:e8:f3: + 2d:0a:33:05:65:dc:ce:5c:67:2b:72:59:c1:4b:24: + 33:d0:b5:b2:ca:2b:2d:b0:ab:62:6e:8f:13:f4:7f: + e0:34:5d:90:4e:72:94:bb:03:8e:9c:e2:1a:9e:58: + 0b:83:35:62:78:70:6c:fe:76:84:36:c6:9d:e1:49: + cc:ff:98:b4:aa:b8:cb:4f:63:85:c9:f1:02:ce:59: + 34:6e:ae:ef:27:e0:ad:22:2d:53:d6:e8:9c:c8:cd: + e5:77:6d:d0:00:57:b0:3f:2d:88:ab:3c:ed:ba:fd: + 7b:58:5f:0b:7f:78:35:e1:7a:37:28:bb:f2:5e:a6: + 25:72:f2:45:dc:11:1f:3c:e3:9c:b6:ff:ac:c3:1b: + 0a:27:90:e7:bd:e9:02:24:ea:9b:09:31:53:62:af: + 3d:2b + Q: + 00:f3:81:dc:f5:3e:bf:72:4f:8b:2e:5c:a8:2c:01: + 0f:b4:b5:ed:a9:35:8d:0f:d8:8e:d2:78:58:94:88: + b5:4f:c3 + G: + 0c:40:2a:72:5d:cc:3a:62:e0:2b:f4:cf:43:cd:17: + f4:a4:93:59:12:20:22:36:69:cf:41:93:ed:ab:42: + 3a:d0:8d:fb:55:2e:30:8a:6a:57:a5:ff:bc:7c:d0: + fb:20:87:f8:1f:8d:f0:cb:08:ab:21:33:28:7d:2b: + 69:68:71:4a:94:f6:33:c9:40:84:5a:48:a3:e1:67: + 08:dd:e7:61:cc:6a:8e:ab:2d:84:db:21:b6:ea:5b: + 07:68:14:93:cc:9c:31:fb:c3:68:b2:43:f6:dd:f8: + c9:32:a8:b4:03:8f:44:e7:b1:5c:a8:76:34:4a:14: + 78:59:f2:b4:3b:39:45:86:68:ad:5e:0a:1a:9a:66: + 95:46:dd:28:12:e3:b3:61:7a:0a:ef:99:d5:8e:3b: + b4:cc:87:fd:94:22:5e:01:d2:dc:c4:69:a7:72:68: + 14:6c:51:91:8f:18:e8:b4:d7:0a:a1:f0:c7:62:3b: + cc:52:cf:37:31:d3:86:41:b2:d2:83:0b:7e:ec:b2: + f0:95:52:ff:13:7d:04:6e:49:4e:7f:33:c3:59:00: + 02:b1:6d:1b:97:d9:36:fd:a2:8f:90:c3:ed:3c:a3: + 53:38:16:8a:c1:6f:77:c3:c5:7a:dc:2e:8f:7c:6c: + 22:56:e4:1a:5f:65:45:05:90:db:b5:bc:f0:6d:66: + 61 +)"); + EXPECT_EQ(PrintToString(dsa.get(), /*indent=*/2, &EVP_PKEY_print_private), + R"( Private-Key: (2048 bit) + priv: + 00:b0:c7:68:70:27:43:bc:51:24:29:93:a9:71:a5: + 28:89:79:54:44:f7:c6:45:22:03:d0:ce:84:fe:61: + 17:d4:6e + pub: + 31:97:31:a1:4e:38:56:88:db:94:1d:bf:65:5c:da: + 4b:c2:10:de:74:20:03:ce:13:60:f2:25:1d:55:7c: + 5d:94:82:54:08:53:db:85:95:bf:dd:5e:50:d5:96: + e0:79:51:1b:bf:4d:4e:b9:3a:c5:ee:c4:5e:98:75: + 7b:be:ff:30:e6:d0:7b:a6:f1:bc:29:ea:df:ec:f3: + 8b:fa:83:11:9f:3f:f0:5d:06:51:32:aa:21:fc:26: + 17:e7:50:c2:16:ba:fa:54:b7:7e:1d:2c:a6:a3:41: + 66:33:94:83:b9:bf:a0:4f:bd:a6:fd:2c:81:58:35: + 33:39:c0:6d:33:40:56:64:12:5a:cd:35:53:21:78: + 8f:27:24:37:66:8a:df:5e:5f:63:fc:8b:2d:ef:57: + db:40:25:d5:17:53:0b:e4:a5:ae:54:bf:46:4f:a6: + 79:c3:74:fa:1f:85:34:64:6d:c5:03:eb:72:98:80: + 7b:c0:8f:35:11:a7:09:eb:51:e0:b0:ac:92:14:f2: + ad:37:95:5a:ba:8c:c4:db:ed:c4:4e:8b:8f:84:33: + 64:f8:57:12:d7:08:7e:90:66:df:91:50:23:f2:73: + c0:6b:b1:15:dd:64:d7:c9:75:17:73:72:da:33:c4: + 6f:a5:47:a1:cc:d1:c6:62:e5:ca:ab:5f:2a:8f:6b: + cc + P: + 00:9e:12:fa:b3:de:12:21:35:01:dd:82:aa:10:ca: + 2d:10:1d:2d:4e:bf:ef:4d:2a:3f:8d:aa:0f:e0:ce: + da:d8:d6:af:85:61:6a:a2:f3:25:2c:0a:2b:5a:6d: + b0:9e:6f:14:90:0e:0d:db:83:11:87:6d:d8:f9:66: + 95:25:f9:9e:d6:59:49:e1:84:d5:06:47:93:27:11: + 69:a2:28:68:0b:95:ec:12:f5:9a:8e:20:b2:1f:2b: + 58:eb:2a:20:12:d3:5b:de:2e:e3:51:82:2f:e8:f3: + 2d:0a:33:05:65:dc:ce:5c:67:2b:72:59:c1:4b:24: + 33:d0:b5:b2:ca:2b:2d:b0:ab:62:6e:8f:13:f4:7f: + e0:34:5d:90:4e:72:94:bb:03:8e:9c:e2:1a:9e:58: + 0b:83:35:62:78:70:6c:fe:76:84:36:c6:9d:e1:49: + cc:ff:98:b4:aa:b8:cb:4f:63:85:c9:f1:02:ce:59: + 34:6e:ae:ef:27:e0:ad:22:2d:53:d6:e8:9c:c8:cd: + e5:77:6d:d0:00:57:b0:3f:2d:88:ab:3c:ed:ba:fd: + 7b:58:5f:0b:7f:78:35:e1:7a:37:28:bb:f2:5e:a6: + 25:72:f2:45:dc:11:1f:3c:e3:9c:b6:ff:ac:c3:1b: + 0a:27:90:e7:bd:e9:02:24:ea:9b:09:31:53:62:af: + 3d:2b + Q: + 00:f3:81:dc:f5:3e:bf:72:4f:8b:2e:5c:a8:2c:01: + 0f:b4:b5:ed:a9:35:8d:0f:d8:8e:d2:78:58:94:88: + b5:4f:c3 + G: + 0c:40:2a:72:5d:cc:3a:62:e0:2b:f4:cf:43:cd:17: + f4:a4:93:59:12:20:22:36:69:cf:41:93:ed:ab:42: + 3a:d0:8d:fb:55:2e:30:8a:6a:57:a5:ff:bc:7c:d0: + fb:20:87:f8:1f:8d:f0:cb:08:ab:21:33:28:7d:2b: + 69:68:71:4a:94:f6:33:c9:40:84:5a:48:a3:e1:67: + 08:dd:e7:61:cc:6a:8e:ab:2d:84:db:21:b6:ea:5b: + 07:68:14:93:cc:9c:31:fb:c3:68:b2:43:f6:dd:f8: + c9:32:a8:b4:03:8f:44:e7:b1:5c:a8:76:34:4a:14: + 78:59:f2:b4:3b:39:45:86:68:ad:5e:0a:1a:9a:66: + 95:46:dd:28:12:e3:b3:61:7a:0a:ef:99:d5:8e:3b: + b4:cc:87:fd:94:22:5e:01:d2:dc:c4:69:a7:72:68: + 14:6c:51:91:8f:18:e8:b4:d7:0a:a1:f0:c7:62:3b: + cc:52:cf:37:31:d3:86:41:b2:d2:83:0b:7e:ec:b2: + f0:95:52:ff:13:7d:04:6e:49:4e:7f:33:c3:59:00: + 02:b1:6d:1b:97:d9:36:fd:a2:8f:90:c3:ed:3c:a3: + 53:38:16:8a:c1:6f:77:c3:c5:7a:dc:2e:8f:7c:6c: + 22:56:e4:1a:5f:65:45:05:90:db:b5:bc:f0:6d:66: + 61 +)"); + + bssl::UniquePtr ec = + ParsePrivateKey(EVP_PKEY_EC, kExampleECKeyDER, sizeof(kExampleECKeyDER)); + ASSERT_TRUE(ec); + EXPECT_EQ(PrintToString(ec.get(), /*indent=*/2, &EVP_PKEY_print_params), + " ECDSA-Parameters: (P-256)\n"); + EXPECT_EQ(PrintToString(ec.get(), /*indent=*/2, &EVP_PKEY_print_public), + R"( Public-Key: (P-256) + pub: + 04:e6:2b:69:e2:bf:65:9f:97:be:2f:1e:0d:94:8a: + 4c:d5:97:6b:b7:a9:1e:0d:46:fb:dd:a9:a9:1e:9d: + dc:ba:5a:01:e7:d6:97:a8:0a:18:f9:c3:c4:a3:1e: + 56:e2:7c:83:48:db:16:1a:1c:f5:1d:7e:f1:94:2d: + 4b:cf:72:22:c1 +)"); + EXPECT_EQ(PrintToString(ec.get(), /*indent=*/2, &EVP_PKEY_print_private), + R"( Private-Key: (P-256) + priv: + 07:0f:08:72:7a:d4:a0:4a:9c:dd:59:c9:4d:89:68: + 77:08:b5:6f:c9:5d:30:77:0e:e8:d1:c9:ce:0a:8b: + b4:6a + pub: + 04:e6:2b:69:e2:bf:65:9f:97:be:2f:1e:0d:94:8a: + 4c:d5:97:6b:b7:a9:1e:0d:46:fb:dd:a9:a9:1e:9d: + dc:ba:5a:01:e7:d6:97:a8:0a:18:f9:c3:c4:a3:1e: + 56:e2:7c:83:48:db:16:1a:1c:f5:1d:7e:f1:94:2d: + 4b:cf:72:22:c1 +)"); +} + // Tests loading a bad key in PKCS8 format. TEST(EVPExtraTest, BadECKey) { const uint8_t *derp = kExampleBadECKeyDER; @@ -502,18 +815,6 @@ TEST(EVPExtraTest, MarshalEmptyPublicKey) { EXPECT_EQ(EVP_R_UNSUPPORTED_ALGORITHM, ERR_GET_REASON(ERR_peek_last_error())); } -static bssl::UniquePtr ParsePrivateKey(int type, const uint8_t *in, - size_t len) { - const uint8_t *ptr = in; - bssl::UniquePtr pkey(d2i_PrivateKey(type, nullptr, &ptr, len)); - if (!pkey) { - return nullptr; - } - - EXPECT_EQ(in + len, ptr); - return pkey; -} - TEST(EVPExtraTest, d2i_PrivateKey) { EXPECT_TRUE(ParsePrivateKey(EVP_PKEY_RSA, kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER))); @@ -782,3 +1083,140 @@ TEST(EVPExtraTest, Ed25519Keygen) { ASSERT_TRUE(EVP_DigestVerify(ctx.get(), sig, len, reinterpret_cast("hello"), 5)); } + +// Test that OpenSSL's legacy TLS-specific APIs in EVP work correctly. When we +// target OpenSSL 3.0, these should be renamed to +// |EVP_PKEY_get1_encoded_public_key|. +TEST(EVPExtraTest, TLSEncodedPoint) { + const struct { + int pkey_type; + std::vector spki; + std::vector encoded_point; + } kTests[] = { + {EVP_PKEY_EC, + {0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, + 0x25, 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, + 0xc7, 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, + 0x92, 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, + 0x0d, 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, + 0x31, 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9}, + {0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25, + 0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, + 0xc7, 0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, + 0x3b, 0x92, 0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, + 0xcf, 0xea, 0x0d, 0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, + 0x05, 0x6e, 0x65, 0x31, 0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9}}, + {EVP_PKEY_X25519, + {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x03, 0x21, + 0x00, 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, + 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, + 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c}, + {0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, + 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, + 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c}}}; + for (const auto& test : kTests) { + SCOPED_TRACE(test.pkey_type); + SCOPED_TRACE(Bytes(test.spki)); + CBS spki; + CBS_init(&spki, test.spki.data(), test.spki.size()); + bssl::UniquePtr from_spki(EVP_parse_public_key(&spki)); + ASSERT_TRUE(from_spki); + + uint8_t *data; + size_t len = EVP_PKEY_get1_tls_encodedpoint(from_spki.get(), &data); + ASSERT_GT(len, 0u); + EXPECT_EQ(Bytes(data, len), Bytes(test.encoded_point)); + OPENSSL_free(data); + + bssl::UniquePtr from_encoded_point(EVP_PKEY_new()); + ASSERT_TRUE(from_encoded_point); + if (test.pkey_type == EVP_PKEY_EC) { + // |EVP_PKEY_EC| should have been |EVP_PKEY_EC_P256|, etc., but instead + // part of the type is buried inside parameters. + ASSERT_TRUE( + EVP_PKEY_copy_parameters(from_encoded_point.get(), from_spki.get())); + } else { + ASSERT_TRUE(EVP_PKEY_set_type(from_encoded_point.get(), test.pkey_type)); + } + ASSERT_TRUE(EVP_PKEY_set1_tls_encodedpoint(from_encoded_point.get(), + test.encoded_point.data(), + test.encoded_point.size())); + + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), test.spki.size())); + ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), from_encoded_point.get())); + EXPECT_EQ(Bytes(CBB_data(cbb.get()), CBB_len(cbb.get())), Bytes(test.spki)); + } +} + +TEST(EVPExtraTest, Parameters) { + auto new_pkey_with_type = [](int type) -> bssl::UniquePtr { + bssl::UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || // + !EVP_PKEY_set_type(pkey.get(), type)) { + return nullptr; + } + return pkey; + }; + + auto new_pkey_with_curve = [](int curve_nid) -> bssl::UniquePtr { + bssl::UniquePtr ctx( + EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr)); + EVP_PKEY *pkey = nullptr; + if (!ctx || // + !EVP_PKEY_paramgen_init(ctx.get()) || + !EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), curve_nid) || + !EVP_PKEY_paramgen(ctx.get(), &pkey)) { + return nullptr; + } + return bssl::UniquePtr(pkey); + }; + + // RSA keys have no parameters. + bssl::UniquePtr rsa = new_pkey_with_type(EVP_PKEY_RSA); + ASSERT_TRUE(rsa); + EXPECT_FALSE(EVP_PKEY_missing_parameters(rsa.get())); + + // EC keys have parameters. + bssl::UniquePtr ec_no_params = new_pkey_with_type(EVP_PKEY_EC); + ASSERT_TRUE(ec_no_params); + EXPECT_TRUE(EVP_PKEY_missing_parameters(ec_no_params.get())); + + bssl::UniquePtr p256 = new_pkey_with_curve(NID_X9_62_prime256v1); + ASSERT_TRUE(p256); + EXPECT_FALSE(EVP_PKEY_missing_parameters(p256.get())); + + bssl::UniquePtr p256_2 = new_pkey_with_curve(NID_X9_62_prime256v1); + ASSERT_TRUE(p256_2); + EXPECT_FALSE(EVP_PKEY_missing_parameters(p256_2.get())); + + bssl::UniquePtr p384 = new_pkey_with_curve(NID_secp384r1); + ASSERT_TRUE(p384); + EXPECT_FALSE(EVP_PKEY_missing_parameters(p384.get())); + + EXPECT_EQ(1, EVP_PKEY_cmp_parameters(p256.get(), p256_2.get())); + EXPECT_EQ(0, EVP_PKEY_cmp_parameters(p256.get(), p384.get())); + + // Copying parameters onto a curve-less EC key works. + ASSERT_TRUE(EVP_PKEY_copy_parameters(ec_no_params.get(), p256.get())); + EXPECT_EQ(1, EVP_PKEY_cmp_parameters(p256.get(), ec_no_params.get())); + + // No-op copies silently succeed. + ASSERT_TRUE(EVP_PKEY_copy_parameters(ec_no_params.get(), p256.get())); + EXPECT_EQ(1, EVP_PKEY_cmp_parameters(p256.get(), ec_no_params.get())); + + // Copying parameters onto a type-less key works. + bssl::UniquePtr pkey(EVP_PKEY_new()); + ASSERT_TRUE(pkey); + ASSERT_TRUE(EVP_PKEY_copy_parameters(pkey.get(), p256.get())); + EXPECT_EQ(EVP_PKEY_EC, EVP_PKEY_id(pkey.get())); + EXPECT_EQ(1, EVP_PKEY_cmp_parameters(p256.get(), pkey.get())); + + // |EVP_PKEY_copy_parameters| cannot change a key's type or curve. + EXPECT_FALSE(EVP_PKEY_copy_parameters(rsa.get(), p256.get())); + EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(rsa.get())); + EXPECT_FALSE(EVP_PKEY_copy_parameters(rsa.get(), p256.get())); + EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(rsa.get())); +} diff --git a/third_party/boringssl/kit/src/crypto/evp/evp_test.cc b/third_party/boringssl/kit/src/crypto/evp/evp_test.cc index 9c4f14d7..fafd50bb 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp_test.cc +++ b/third_party/boringssl/kit/src/crypto/evp/evp_test.cc @@ -125,7 +125,7 @@ static int GetKeyType(FileTest *t, const std::string &name) { return EVP_PKEY_NONE; } -static int GetRSAPadding(FileTest *t, int *out, const std::string &name) { +static bool GetRSAPadding(FileTest *t, int *out, const std::string &name) { if (name == "PKCS1") { *out = RSA_PKCS1_PADDING; return true; @@ -138,6 +138,10 @@ static int GetRSAPadding(FileTest *t, int *out, const std::string &name) { *out = RSA_PKCS1_OAEP_PADDING; return true; } + if (name == "None") { + *out = RSA_NO_PADDING; + return true; + } ADD_FAILURE() << "Unknown RSA padding mode: " << name; return false; } diff --git a/third_party/boringssl/kit/src/crypto/evp/evp_tests.txt b/third_party/boringssl/kit/src/crypto/evp/evp_tests.txt index 0c890fd6..cbce1b08 100644 --- a/third_party/boringssl/kit/src/crypto/evp/evp_tests.txt +++ b/third_party/boringssl/kit/src/crypto/evp/evp_tests.txt @@ -21,6 +21,11 @@ PublicKey = RSA-2048-SPKI-Negative Input = 30820121300d06092a864886f70d01010105000382010e003082010902820100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001 Error = NEGATIVE_NUMBER +# An RSA key with an even modulus +PublicKey = RSA-2048-Even-Modulus +Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44e0203010001 +Error = BAD_RSA_PARAMETERS + # The same key but with missing parameters rather than a NULL. PublicKey = RSA-2048-SPKI-Invalid Input = 30820120300b06092a864886f70d0101010382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001 @@ -99,6 +104,16 @@ PrivateKey = P-256-ExplicitParameters-CofactorTwo Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020102046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9 Error = UNKNOWN_GROUP +# A zero ECDSA key, with the optional public key encoded. +PrivateKey = P-256-Zero +Input = 3047020100301306072a8648ce3d020106082a8648ce3d030107042d302b02010104200000000000000000000000000000000000000000000000000000000000000000a10403020000 +Error = INVALID_PRIVATE_KEY + +# A zero ECDSA key, with the optional public key omitted. +PrivateKey = P-256-Zero-NoPublic +Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104200000000000000000000000000000000000000000000000000000000000000000 +Error = INVALID_PRIVATE_KEY + # The public half of the same key encoded as a PublicKey. PublicKey = P-256-SPKI Type = EC @@ -123,6 +138,11 @@ Input = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de1221 ExpectNoRawPrivate ExpectNoRawPublic +# An invalid zero DSA private key. +PrivateKey = DSA-1024-Zero +Input = 308202450201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610403020100 +Error = INVALID_PARAMETERS + # A DSA public key. PublicKey = DSA-1024-SPKI Type = DSA @@ -635,6 +655,16 @@ Digest = SHA256 Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" Output = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f +# The input is 1 (mod p) and q - 1 (mod q). If the CRT implementation does not +# account for p < q, the subtraction step will break. However, this test only +# works when RSA blinding is disabled. When blinding is enabled, these values +# are randomized and, instead, either this or the above test will hit this case +# if repeated enough. (It hits it with probability (q-p)^2 / 2pq, or 1.8% here.) +Encrypt = RSA-Swapped +RSAPadding = None +Input = 7ab490e1f5e718ff23a9e738f9867559e3a6ea72332e3bcc1b6f58585218ed815a865dab75e3f44ea550bdef815101d6039251a513fd99188c1916abb94b15ef72de793f6472a342b33a125cfc96a4fc89d140e337f5fe6ff937ed3f34b6b09f5227f598e12faddf4423254acbee748197bed26954502c7484c65e279fed7fed +CheckDecrypt + # Though we will never generate such a key, test that RSA keys where p and q are # different sizes work properly. PrivateKey = RSA-PrimeMismatch diff --git a/third_party/boringssl/kit/src/crypto/evp/internal.h b/third_party/boringssl/kit/src/crypto/evp/internal.h index 8b6a5836..6678c41d 100644 --- a/third_party/boringssl/kit/src/crypto/evp/internal.h +++ b/third_party/boringssl/kit/src/crypto/evp/internal.h @@ -66,11 +66,16 @@ extern "C" { #endif +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; + struct evp_pkey_asn1_method_st { int pkey_id; uint8_t oid[9]; uint8_t oid_len; + const EVP_PKEY_METHOD *pkey_method; + // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo // and writes the result into |out|. It returns one on success and zero on // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER @@ -101,6 +106,17 @@ struct evp_pkey_asn1_method_st { int (*get_priv_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); int (*get_pub_raw)(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len); + // TODO(davidben): Can these be merged with the functions above? OpenSSL does + // not implement |EVP_PKEY_get_raw_public_key|, etc., for |EVP_PKEY_EC|, but + // the distinction seems unimportant. OpenSSL 3.0 has since renamed + // |EVP_PKEY_get1_tls_encodedpoint| to |EVP_PKEY_get1_encoded_public_key|, and + // what is the difference between "raw" and an "encoded" public key. + // + // One nuisance is the notion of "raw" is slightly ambiguous for EC keys. Is + // it a DER ECPrivateKey or just the scalar? + int (*set1_tls_encodedpoint)(EVP_PKEY *pkey, const uint8_t *in, size_t len); + size_t (*get1_tls_encodedpoint)(const EVP_PKEY *pkey, uint8_t **out_ptr); + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by // custom implementations which do not expose key material and parameters. int (*pkey_opaque)(const EVP_PKEY *pk); @@ -115,6 +131,20 @@ struct evp_pkey_asn1_method_st { void (*pkey_free)(EVP_PKEY *pkey); } /* EVP_PKEY_ASN1_METHOD */; +struct evp_pkey_st { + CRYPTO_refcount_t references; + + // type contains one of the EVP_PKEY_* values or NID_undef and determines + // the type of |pkey|. + int type; + + // pkey contains a pointer to a structure dependent on |type|. + void *pkey; + + // ameth contains a pointer to a method table that contains many ASN.1 + // methods for the key type. + const EVP_PKEY_ASN1_METHOD *ameth; +} /* EVP_PKEY */; #define EVP_PKEY_OP_UNDEFINED 0 #define EVP_PKEY_OP_KEYGEN (1 << 2) @@ -178,6 +208,11 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, #define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) #define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) #define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 13) +#define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 14) +#define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 15) +#define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 16) +#define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 17) +#define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 18) struct evp_pkey_ctx_st { // Method associated with this operation @@ -232,18 +267,16 @@ struct evp_pkey_method_st { } /* EVP_PKEY_METHOD */; typedef struct { - union { - uint8_t priv[64]; - struct { - // Shift the location of the public key to align with where it is in the - // private key representation. - uint8_t pad[32]; - uint8_t value[32]; - } pub; - } key; + // key is the concatenation of the private seed and public key. It is stored + // as a single 64-bit array to allow passing to |ED25519_sign|. If + // |has_private| is false, the first 32 bytes are uninitialized and the public + // key is in the last 32 bytes. + uint8_t key[64]; char has_private; } ED25519_KEY; +#define ED25519_PUBLIC_KEY_OFFSET 32 + typedef struct { uint8_t pub[32]; uint8_t priv[32]; @@ -260,6 +293,7 @@ extern const EVP_PKEY_METHOD rsa_pkey_meth; extern const EVP_PKEY_METHOD ec_pkey_meth; extern const EVP_PKEY_METHOD ed25519_pkey_meth; extern const EVP_PKEY_METHOD x25519_pkey_meth; +extern const EVP_PKEY_METHOD hkdf_pkey_meth; #if defined(__cplusplus) diff --git a/third_party/boringssl/kit/src/crypto/evp/p_dsa_asn1.c b/third_party/boringssl/kit/src/crypto/evp/p_dsa_asn1.c index ac91127b..fe042108 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_dsa_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_dsa_asn1.c @@ -61,6 +61,7 @@ #include #include +#include "../dsa/internal.h" #include "internal.h" @@ -102,7 +103,7 @@ err: } static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { - const DSA *dsa = key->pkey.dsa; + const DSA *dsa = key->pkey; const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; // See RFC 5480, section 2. @@ -136,25 +137,27 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } dsa->priv_key = BN_new(); - dsa->pub_key = BN_new(); - if (dsa->priv_key == NULL || dsa->pub_key == NULL) { + if (dsa->priv_key == NULL) { + goto err; + } + if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } - // Decode the key. To avoid DoS attacks when importing private keys, we bound - // |dsa->priv_key| against |dsa->q|, which itself bound by - // |DSA_parse_parameters|. (We cannot call |BN_num_bits| on |dsa->priv_key|. - // That would leak a secret bit width.) - if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || - CBS_len(key) != 0 || - BN_cmp(dsa->priv_key, dsa->q) >= 0) { + // To avoid DoS attacks when importing private keys, check bounds on |dsa|. + // This bounds |dsa->priv_key| against |dsa->q| and bounds |dsa->q|'s bit + // width. + if (!dsa_check_key(dsa)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } // Calculate the public key. ctx = BN_CTX_new(); - if (ctx == NULL || + dsa->pub_key = BN_new(); + if (ctx == NULL || dsa->pub_key == NULL || !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx, NULL)) { goto err; @@ -171,7 +174,7 @@ err: } static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { - const DSA *dsa = key->pkey.dsa; + const DSA *dsa = key->pkey; if (dsa == NULL || dsa->priv_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); return 0; @@ -196,17 +199,19 @@ static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { } static int int_dsa_size(const EVP_PKEY *pkey) { - return DSA_size(pkey->pkey.dsa); + const DSA *dsa = pkey->pkey; + return DSA_size(dsa); } static int dsa_bits(const EVP_PKEY *pkey) { - return BN_num_bits(pkey->pkey.dsa->p); + const DSA *dsa = pkey->pkey; + return BN_num_bits(DSA_get0_p(dsa)); } static int dsa_missing_parameters(const EVP_PKEY *pkey) { - DSA *dsa; - dsa = pkey->pkey.dsa; - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + const DSA *dsa = pkey->pkey; + if (DSA_get0_p(dsa) == NULL || DSA_get0_q(dsa) == NULL || + DSA_get0_g(dsa) == NULL) { return 1; } return 0; @@ -226,9 +231,11 @@ static int dup_bn_into(BIGNUM **out, BIGNUM *src) { } static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || - !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || - !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + DSA *to_dsa = to->pkey; + const DSA *from_dsa = from->pkey; + if (!dup_bn_into(&to_dsa->p, from_dsa->p) || + !dup_bn_into(&to_dsa->q, from_dsa->q) || + !dup_bn_into(&to_dsa->g, from_dsa->g)) { return 0; } @@ -236,42 +243,66 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { } static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && - BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && - BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; + const DSA *a_dsa = a->pkey; + const DSA *b_dsa = b->pkey; + return BN_cmp(DSA_get0_p(a_dsa), DSA_get0_p(b_dsa)) == 0 && + BN_cmp(DSA_get0_q(a_dsa), DSA_get0_q(b_dsa)) == 0 && + BN_cmp(DSA_get0_g(a_dsa), DSA_get0_g(b_dsa)) == 0; } static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; + const DSA *a_dsa = a->pkey; + const DSA *b_dsa = b->pkey; + return BN_cmp(DSA_get0_pub_key(b_dsa), DSA_get0_pub_key(a_dsa)) == 0; } -static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } +static void int_dsa_free(EVP_PKEY *pkey) { + DSA_free(pkey->pkey); + pkey->pkey = NULL; +} const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { - EVP_PKEY_DSA, - // 1.2.840.10040.4.1 - {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, + 7, - dsa_pub_decode, - dsa_pub_encode, - dsa_pub_cmp, + /*pkey_method=*/NULL, - dsa_priv_decode, - dsa_priv_encode, + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + dsa_priv_decode, + dsa_priv_encode, - NULL /* pkey_opaque */, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - int_dsa_size, - dsa_bits, + /*pkey_opaque=*/NULL, - dsa_missing_parameters, - dsa_copy_parameters, - dsa_cmp_parameters, + int_dsa_size, + dsa_bits, - int_dsa_free, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + + int_dsa_free, }; + +int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { + // BoringSSL does not support DSA in |EVP_PKEY_CTX|. + OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} + +int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits) { + // BoringSSL does not support DSA in |EVP_PKEY_CTX|. + OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} diff --git a/third_party/boringssl/kit/src/crypto/evp/p_ec.c b/third_party/boringssl/kit/src/crypto/evp/p_ec.c index 97675415..c9f26cb0 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_ec.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_ec.c @@ -117,9 +117,7 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { - unsigned int sltmp; - EC_KEY *ec = ctx->pkey->pkey.ec; - + const EC_KEY *ec = ctx->pkey->pkey; if (!sig) { *siglen = ECDSA_size(ec); return 1; @@ -128,6 +126,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, return 0; } + unsigned int sltmp; if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { return 0; } @@ -137,37 +136,32 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { - return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); + const EC_KEY *ec_key = ctx->pkey->pkey; + return ECDSA_verify(0, tbs, tbslen, sig, siglen, ec_key); } static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen) { - int ret; - size_t outlen; - const EC_POINT *pubkey = NULL; - EC_KEY *eckey; - if (!ctx->pkey || !ctx->peerkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); return 0; } - eckey = ctx->pkey->pkey.ec; - + const EC_KEY *eckey = ctx->pkey->pkey; if (!key) { const EC_GROUP *group; group = EC_KEY_get0_group(eckey); *keylen = (EC_GROUP_get_degree(group) + 7) / 8; return 1; } - pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + const EC_KEY *eckey_peer = ctx->peerkey->pkey; + const EC_POINT *pubkey = EC_KEY_get0_public_key(eckey_peer); // NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is // not an error, the result is truncated. - - outlen = *keylen; - - ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); + size_t outlen = *keylen; + int ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); if (ret < 0) { return 0; } @@ -179,18 +173,18 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { EC_PKEY_CTX *dctx = ctx->data; switch (type) { - case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + case EVP_PKEY_CTRL_MD: { + const EVP_MD *md = p2; + int md_type = EVP_MD_type(md); + if (md_type != NID_sha1 && md_type != NID_sha224 && + md_type != NID_sha256 && md_type != NID_sha384 && + md_type != NID_sha512) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); return 0; } - dctx->md = p2; + dctx->md = md; return 1; + } case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = dctx->md; @@ -224,7 +218,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); return 0; } - group = EC_KEY_get0_group(ctx->pkey->pkey.ec); + group = EC_KEY_get0_group(ctx->pkey->pkey); } EC_KEY *ec = EC_KEY_new(); if (ec == NULL || diff --git a/third_party/boringssl/kit/src/crypto/evp/p_ec_asn1.c b/third_party/boringssl/kit/src/crypto/evp/p_ec_asn1.c index dedc5e0a..2659100f 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_ec_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_ec_asn1.c @@ -66,7 +66,7 @@ static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { - const EC_KEY *ec_key = key->pkey.ec; + const EC_KEY *ec_key = key->pkey; const EC_GROUP *group = EC_KEY_get0_group(ec_key); const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); @@ -93,7 +93,6 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 5480, section 2. // The parameters are a named curve. - EC_POINT *point = NULL; EC_KEY *eckey = NULL; EC_GROUP *group = EC_KEY_parse_curve_name(params); if (group == NULL || CBS_len(params) != 0) { @@ -102,35 +101,29 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } eckey = EC_KEY_new(); - if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { - goto err; - } - - point = EC_POINT_new(group); - if (point == NULL || - !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || - !EC_KEY_set_public_key(eckey, point)) { + if (eckey == NULL || // + !EC_KEY_set_group(eckey, group) || + !EC_KEY_oct2key(eckey, CBS_data(key), CBS_len(key), NULL)) { goto err; } EC_GROUP_free(group); - EC_POINT_free(point); EVP_PKEY_assign_EC_KEY(out, eckey); return 1; err: EC_GROUP_free(group); - EC_POINT_free(point); EC_KEY_free(eckey); return 0; } static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - int r; - const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); - const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), - *pb = EC_KEY_get0_public_key(b->pkey.ec); - r = EC_POINT_cmp(group, pa, pb, NULL); + const EC_KEY *a_ec = a->pkey; + const EC_KEY *b_ec = b->pkey; + const EC_GROUP *group = EC_KEY_get0_group(b_ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a_ec), + *pb = EC_KEY_get0_public_key(b_ec); + int r = EC_POINT_cmp(group, pa, pb, NULL); if (r == 0) { return 1; } else if (r == 1) { @@ -162,7 +155,7 @@ static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { - const EC_KEY *ec_key = key->pkey.ec; + const EC_KEY *ec_key = key->pkey; // Omit the redundant copy of the curve name. This contradicts RFC 5915 but // aligns with PKCS #11. SEC 1 only says they may be omitted if known by other @@ -188,12 +181,36 @@ static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { return 1; } +static int eckey_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + EC_KEY *ec_key = pkey->pkey; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_oct2key(ec_key, in, len, NULL); +} + +static size_t eckey_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const EC_KEY *ec_key = pkey->pkey; + if (ec_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + return EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED, out_ptr, NULL); +} + static int int_ec_size(const EVP_PKEY *pkey) { - return ECDSA_size(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + return ECDSA_size(ec_key); } static int ec_bits(const EVP_PKEY *pkey) { - const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + const EC_GROUP *group = EC_KEY_get0_group(ec_key); if (group == NULL) { ERR_clear_error(); return 0; @@ -202,16 +219,41 @@ static int ec_bits(const EVP_PKEY *pkey) { } static int ec_missing_parameters(const EVP_PKEY *pkey) { - return EC_KEY_get0_group(pkey->pkey.ec) == NULL; + const EC_KEY *ec_key = pkey->pkey; + return ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL; } static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); + const EC_KEY *from_key = from->pkey; + if (from_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + const EC_GROUP *group = EC_KEY_get0_group(from_key); + if (group == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + if (to->pkey == NULL) { + to->pkey = EC_KEY_new(); + if (to->pkey == NULL) { + return 0; + } + } + return EC_KEY_set_group(to->pkey, group); } static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), - *group_b = EC_KEY_get0_group(b->pkey.ec); + const EC_KEY *a_ec = a->pkey; + const EC_KEY *b_ec = b->pkey; + if (a_ec == NULL || b_ec == NULL) { + return -2; + } + const EC_GROUP *group_a = EC_KEY_get0_group(a_ec), + *group_b = EC_KEY_get0_group(b_ec); + if (group_a == NULL || group_b == NULL) { + return -2; + } if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { // mismatch return 0; @@ -219,37 +261,46 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { return 1; } -static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } +static void int_ec_free(EVP_PKEY *pkey) { + EC_KEY_free(pkey->pkey); + pkey->pkey = NULL; +} static int eckey_opaque(const EVP_PKEY *pkey) { - return EC_KEY_is_opaque(pkey->pkey.ec); + const EC_KEY *ec_key = pkey->pkey; + return EC_KEY_is_opaque(ec_key); } const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { - EVP_PKEY_EC, - // 1.2.840.10045.2.1 - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, + 7, - eckey_pub_decode, - eckey_pub_encode, - eckey_pub_cmp, + &ec_pkey_meth, - eckey_priv_decode, - eckey_priv_encode, + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + eckey_priv_decode, + eckey_priv_encode, - eckey_opaque, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + eckey_set1_tls_encodedpoint, + eckey_get1_tls_encodedpoint, - int_ec_size, - ec_bits, + eckey_opaque, - ec_missing_parameters, - ec_copy_parameters, - ec_cmp_parameters, + int_ec_size, + ec_bits, - int_ec_free, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + + int_ec_free, }; diff --git a/third_party/boringssl/kit/src/crypto/evp/p_ed25519.c b/third_party/boringssl/kit/src/crypto/evp/p_ed25519.c index 9149afb2..647ea05e 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_ed25519.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_ed25519.c @@ -27,7 +27,6 @@ static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -37,18 +36,18 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { } uint8_t pubkey_unused[32]; - ED25519_keypair(pubkey_unused, key->key.priv); + ED25519_keypair(pubkey_unused, key->key); key->has_private = 1; - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = key; + OPENSSL_free(pkey->pkey); + pkey->pkey = key; return 1; } static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { - ED25519_KEY *key = ctx->pkey->pkey.ptr; + const ED25519_KEY *key = ctx->pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -64,7 +63,7 @@ static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, return 0; } - if (!ED25519_sign(sig, tbs, tbslen, key->key.priv)) { + if (!ED25519_sign(sig, tbs, tbslen, key->key)) { return 0; } @@ -75,9 +74,9 @@ static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { - ED25519_KEY *key = ctx->pkey->pkey.ptr; + const ED25519_KEY *key = ctx->pkey->pkey; if (siglen != 64 || - !ED25519_verify(tbs, tbslen, sig, key->key.pub.value)) { + !ED25519_verify(tbs, tbslen, sig, key->key + ED25519_PUBLIC_KEY_OFFSET)) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/evp/p_ed25519_asn1.c b/third_party/boringssl/kit/src/crypto/evp/p_ed25519_asn1.c index 1f996cf6..3b8f27fd 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_ed25519_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_ed25519_asn1.c @@ -24,8 +24,8 @@ static void ed25519_free(EVP_PKEY *pkey) { - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = NULL; + OPENSSL_free(pkey->pkey); + pkey->pkey = NULL; } static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { @@ -36,18 +36,17 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } // The RFC 8032 encoding stores only the 32-byte seed, so we must recover the // full representation which we use from it. uint8_t pubkey_unused[32]; - ED25519_keypair_from_seed(pubkey_unused, key->key.priv, in); + ED25519_keypair_from_seed(pubkey_unused, key->key, in); key->has_private = 1; ed25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } @@ -59,21 +58,20 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } - OPENSSL_memcpy(key->key.pub.value, in, 32); + OPENSSL_memcpy(key->key + ED25519_PUBLIC_KEY_OFFSET, in, 32); key->has_private = 0; ed25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -90,14 +88,14 @@ static int ed25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, } // The raw private key format is the first 32 bytes of the private key. - OPENSSL_memcpy(out, key->key.priv, 32); + OPENSSL_memcpy(out, key->key, 32); *out_len = 32; return 1; } static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (out == NULL) { *out_len = 32; return 1; @@ -108,7 +106,7 @@ static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 0; } - OPENSSL_memcpy(out, key->key.pub.value, 32); + OPENSSL_memcpy(out, key->key + ED25519_PUBLIC_KEY_OFFSET, 32); *out_len = 32; return 1; } @@ -126,7 +124,7 @@ static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { - const ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; // See RFC 8410, section 4. CBB spki, algorithm, oid, key_bitstring; @@ -136,7 +134,8 @@ static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || - !CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) || + !CBB_add_bytes(&key_bitstring, key->key + ED25519_PUBLIC_KEY_OFFSET, + 32) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -146,9 +145,10 @@ static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { } static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - const ED25519_KEY *a_key = a->pkey.ptr; - const ED25519_KEY *b_key = b->pkey.ptr; - return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0; + const ED25519_KEY *a_key = a->pkey; + const ED25519_KEY *b_key = b->pkey; + return OPENSSL_memcmp(a_key->key + ED25519_PUBLIC_KEY_OFFSET, + b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0; } static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { @@ -168,7 +168,7 @@ static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { - ED25519_KEY *key = pkey->pkey.ptr; + const ED25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -185,7 +185,7 @@ static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || // The PKCS#8 encoding stores only the 32-byte seed which is the first 32 // bytes of the private key. - !CBB_add_bytes(&inner, key->key.priv, 32) || + !CBB_add_bytes(&inner, key->key, 32) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -202,6 +202,7 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { EVP_PKEY_ED25519, {0x2b, 0x65, 0x70}, 3, + &ed25519_pkey_meth, ed25519_pub_decode, ed25519_pub_encode, ed25519_pub_cmp, @@ -211,11 +212,13 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ed25519_set_pub_raw, ed25519_get_priv_raw, ed25519_get_pub_raw, - NULL /* pkey_opaque */, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, + /*pkey_opaque=*/NULL, ed25519_size, ed25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, ed25519_free, }; diff --git a/third_party/boringssl/kit/src/crypto/evp/p_hkdf.c b/third_party/boringssl/kit/src/crypto/evp/p_hkdf.c new file mode 100644 index 00000000..0d7ede82 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/evp/p_hkdf.c @@ -0,0 +1,233 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +typedef struct { + int mode; + const EVP_MD *md; + uint8_t *key; + size_t key_len; + uint8_t *salt; + size_t salt_len; + CBB info; +} HKDF_PKEY_CTX; + +static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) { + HKDF_PKEY_CTX *hctx = OPENSSL_malloc(sizeof(HKDF_PKEY_CTX)); + if (hctx == NULL) { + return 0; + } + + OPENSSL_memset(hctx, 0, sizeof(HKDF_PKEY_CTX)); + if (!CBB_init(&hctx->info, 0)) { + OPENSSL_free(hctx); + return 0; + } + + ctx->data = hctx; + return 1; +} + +static int pkey_hkdf_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { + if (!pkey_hkdf_init(dst)) { + return 0; + } + + HKDF_PKEY_CTX *hctx_dst = dst->data; + const HKDF_PKEY_CTX *hctx_src = src->data; + hctx_dst->mode = hctx_src->mode; + hctx_dst->md = hctx_src->md; + + if (hctx_src->key_len != 0) { + hctx_dst->key = OPENSSL_memdup(hctx_src->key, hctx_src->key_len); + if (hctx_dst->key == NULL) { + return 0; + } + hctx_dst->key_len = hctx_src->key_len; + } + + if (hctx_src->salt_len != 0) { + hctx_dst->salt = OPENSSL_memdup(hctx_src->salt, hctx_src->salt_len); + if (hctx_dst->salt == NULL) { + return 0; + } + hctx_dst->salt_len = hctx_src->salt_len; + } + + if (!CBB_add_bytes(&hctx_dst->info, CBB_data(&hctx_src->info), + CBB_len(&hctx_src->info))) { + return 0; + } + + return 1; +} + +static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) { + HKDF_PKEY_CTX *hctx = ctx->data; + if (hctx != NULL) { + OPENSSL_free(hctx->key); + OPENSSL_free(hctx->salt); + CBB_cleanup(&hctx->info); + OPENSSL_free(hctx); + ctx->data = NULL; + } +} + +static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len) { + HKDF_PKEY_CTX *hctx = ctx->data; + if (hctx->md == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + if (hctx->key_len == 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if (out == NULL) { + if (hctx->mode == EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) { + *out_len = EVP_MD_size(hctx->md); + } + // HKDF-Expand is variable-length and returns |*out_len| bytes. "Output" the + // input length by leaving it alone. + return 1; + } + + switch (hctx->mode) { + case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: + return HKDF(out, *out_len, hctx->md, hctx->key, hctx->key_len, hctx->salt, + hctx->salt_len, CBB_data(&hctx->info), CBB_len(&hctx->info)); + + case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: + if (*out_len < EVP_MD_size(hctx->md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + return HKDF_extract(out, out_len, hctx->md, hctx->key, hctx->key_len, + hctx->salt, hctx->salt_len); + + case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: + return HKDF_expand(out, *out_len, hctx->md, hctx->key, hctx->key_len, + CBB_data(&hctx->info), CBB_len(&hctx->info)); + } + OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR); + return 0; +} + +static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + HKDF_PKEY_CTX *hctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_HKDF_MODE: + if (p1 != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND && + p1 != EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY && + p1 != EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); + return 0; + } + hctx->mode = p1; + return 1; + case EVP_PKEY_CTRL_HKDF_MD: + hctx->md = p2; + return 1; + case EVP_PKEY_CTRL_HKDF_KEY: { + const CBS *key = p2; + if (!CBS_stow(key, &hctx->key, &hctx->key_len)) { + return 0; + } + return 1; + } + case EVP_PKEY_CTRL_HKDF_SALT: { + const CBS *salt = p2; + if (!CBS_stow(salt, &hctx->salt, &hctx->salt_len)) { + return 0; + } + return 1; + } + case EVP_PKEY_CTRL_HKDF_INFO: { + const CBS *info = p2; + // |EVP_PKEY_CTX_add1_hkdf_info| appends to the info string, rather than + // replacing it. + if (!CBB_add_bytes(&hctx->info, CBS_data(info), CBS_len(info))) { + return 0; + } + return 1; + } + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +const EVP_PKEY_METHOD hkdf_pkey_meth = { + EVP_PKEY_HKDF, + pkey_hkdf_init, + pkey_hkdf_copy, + pkey_hkdf_cleanup, + /*keygen=*/NULL, + /*sign=*/NULL, + /*sign_message=*/NULL, + /*verify=*/NULL, + /*verify_message=*/NULL, + /*verify_recover=*/NULL, + /*encrypt=*/NULL, + /*decrypt=*/NULL, + pkey_hkdf_derive, + /*paramgen=*/NULL, + pkey_hkdf_ctrl, +}; + +int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL); +} + +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MD, 0, (void *)md); +} + +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const uint8_t *key, + size_t key_len) { + CBS cbs; + CBS_init(&cbs, key, key_len); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, 0, &cbs); +} + +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, const uint8_t *salt, + size_t salt_len) { + CBS cbs; + CBS_init(&cbs, salt, salt_len); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, 0, &cbs); +} + +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const uint8_t *info, + size_t info_len) { + CBS cbs; + CBS_init(&cbs, info, info_len); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, 0, &cbs); +} diff --git a/third_party/boringssl/kit/src/crypto/evp/p_rsa.c b/third_party/boringssl/kit/src/crypto/evp/p_rsa.c index 7872a922..15eb1efb 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_rsa.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_rsa.c @@ -67,7 +67,7 @@ #include #include "../internal.h" -#include "../fipsmodule/rsa/internal.h" +#include "../rsa_extra/internal.h" #include "internal.h" @@ -171,7 +171,7 @@ static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!sig) { @@ -210,7 +210,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; if (rctx->md) { switch (rctx->pad_mode) { @@ -243,7 +243,7 @@ static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, const uint8_t *sig, size_t sig_len) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (out == NULL) { @@ -307,7 +307,7 @@ static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { @@ -339,7 +339,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; + RSA *rsa = ctx->pkey->pkey; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { diff --git a/third_party/boringssl/kit/src/crypto/evp/p_rsa_asn1.c b/third_party/boringssl/kit/src/crypto/evp/p_rsa_asn1.c index c0971038..dd64731b 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_rsa_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_rsa_asn1.c @@ -68,6 +68,7 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { // See RFC 3279, section 2.3.1. + const RSA *rsa = key->pkey; CBB spki, algorithm, oid, null, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || @@ -76,7 +77,7 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || - !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || + !RSA_marshal_public_key(&key_bitstring, rsa) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -109,11 +110,14 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && - BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; + const RSA *a_rsa = a->pkey; + const RSA *b_rsa = b->pkey; + return BN_cmp(RSA_get0_n(b_rsa), RSA_get0_n(a_rsa)) == 0 && + BN_cmp(RSA_get0_e(b_rsa), RSA_get0_e(a_rsa)) == 0; } static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = key->pkey; CBB pkcs8, algorithm, oid, null, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || @@ -122,7 +126,7 @@ static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || - !RSA_marshal_private_key(&private_key, key->pkey.rsa) || + !RSA_marshal_private_key(&private_key, rsa) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; @@ -153,42 +157,55 @@ static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int rsa_opaque(const EVP_PKEY *pkey) { - return RSA_is_opaque(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_is_opaque(rsa); } static int int_rsa_size(const EVP_PKEY *pkey) { - return RSA_size(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_size(rsa); } static int rsa_bits(const EVP_PKEY *pkey) { - return RSA_bits(pkey->pkey.rsa); + const RSA *rsa = pkey->pkey; + return RSA_bits(rsa); } -static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } +static void int_rsa_free(EVP_PKEY *pkey) { + RSA_free(pkey->pkey); + pkey->pkey = NULL; +} const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { - EVP_PKEY_RSA, - // 1.2.840.113549.1.1.1 - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, + 9, - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, + &rsa_pkey_meth, - rsa_priv_decode, - rsa_priv_encode, + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, - NULL /* set_priv_raw */, - NULL /* set_pub_raw */, - NULL /* get_priv_raw */, - NULL /* get_pub_raw */, + rsa_priv_decode, + rsa_priv_encode, - rsa_opaque, + /*set_priv_raw=*/NULL, + /*set_pub_raw=*/NULL, + /*get_priv_raw=*/NULL, + /*get_pub_raw=*/NULL, + /*set1_tls_encodedpoint=*/NULL, + /*get1_tls_encodedpoint=*/NULL, - int_rsa_size, - rsa_bits, + rsa_opaque, - 0,0,0, + int_rsa_size, + rsa_bits, - int_rsa_free, + 0, + 0, + 0, + + int_rsa_free, }; diff --git a/third_party/boringssl/kit/src/crypto/evp/p_x25519.c b/third_party/boringssl/kit/src/crypto/evp/p_x25519.c index ed7df39a..6218943e 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_x25519.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_x25519.c @@ -27,7 +27,6 @@ static int pkey_x25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -39,8 +38,8 @@ static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { X25519_keypair(key->pub, key->priv); key->has_private = 1; - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = key; + OPENSSL_free(pkey->pkey); + pkey->pkey = key; return 1; } @@ -51,8 +50,8 @@ static int pkey_x25519_derive(EVP_PKEY_CTX *ctx, uint8_t *out, return 0; } - const X25519_KEY *our_key = ctx->pkey->pkey.ptr; - const X25519_KEY *peer_key = ctx->peerkey->pkey.ptr; + const X25519_KEY *our_key = ctx->pkey->pkey; + const X25519_KEY *peer_key = ctx->peerkey->pkey; if (our_key == NULL || peer_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); return 0; diff --git a/third_party/boringssl/kit/src/crypto/evp/p_x25519_asn1.c b/third_party/boringssl/kit/src/crypto/evp/p_x25519_asn1.c index 99b4cc9c..bf98427c 100644 --- a/third_party/boringssl/kit/src/crypto/evp/p_x25519_asn1.c +++ b/third_party/boringssl/kit/src/crypto/evp/p_x25519_asn1.c @@ -24,8 +24,8 @@ static void x25519_free(EVP_PKEY *pkey) { - OPENSSL_free(pkey->pkey.ptr); - pkey->pkey.ptr = NULL; + OPENSSL_free(pkey->pkey); + pkey->pkey = NULL; } static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { @@ -36,7 +36,6 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -45,7 +44,7 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 1; x25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } @@ -57,7 +56,6 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_KEY *key = OPENSSL_malloc(sizeof(X25519_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -65,13 +63,13 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { key->has_private = 0; x25519_free(pkey); - pkey->pkey.ptr = key; + pkey->pkey = key; return 1; } static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, - size_t *out_len) { - const X25519_KEY *key = pkey->pkey.ptr; + size_t *out_len) { + const X25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -94,7 +92,7 @@ static int x25519_get_priv_raw(const EVP_PKEY *pkey, uint8_t *out, static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { - const X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; if (out == NULL) { *out_len = 32; return 1; @@ -110,6 +108,23 @@ static int x25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 1; } +static int x25519_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, + size_t len) { + return x25519_set_pub_raw(pkey, in, len); +} + +static size_t x25519_get1_tls_encodedpoint(const EVP_PKEY *pkey, + uint8_t **out_ptr) { + const X25519_KEY *key = pkey->pkey; + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + *out_ptr = OPENSSL_memdup(key->pub, 32); + return *out_ptr == NULL ? 0 : 32; +} + static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 8410, section 4. @@ -123,7 +138,7 @@ static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { - const X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; // See RFC 8410, section 4. CBB spki, algorithm, oid, key_bitstring; @@ -143,8 +158,8 @@ static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { } static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - const X25519_KEY *a_key = a->pkey.ptr; - const X25519_KEY *b_key = b->pkey.ptr; + const X25519_KEY *a_key = a->pkey; + const X25519_KEY *b_key = b->pkey; return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0; } @@ -165,7 +180,7 @@ static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { } static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { - X25519_KEY *key = pkey->pkey.ptr; + const X25519_KEY *key = pkey->pkey; if (!key->has_private) { OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); return 0; @@ -199,6 +214,7 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { EVP_PKEY_X25519, {0x2b, 0x65, 0x6e}, 3, + &x25519_pkey_meth, x25519_pub_decode, x25519_pub_encode, x25519_pub_cmp, @@ -208,41 +224,13 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { x25519_set_pub_raw, x25519_get_priv_raw, x25519_get_pub_raw, - NULL /* pkey_opaque */, + x25519_set1_tls_encodedpoint, + x25519_get1_tls_encodedpoint, + /*pkey_opaque=*/NULL, x25519_size, x25519_bits, - NULL /* param_missing */, - NULL /* param_copy */, - NULL /* param_cmp */, + /*param_missing=*/NULL, + /*param_copy=*/NULL, + /*param_cmp=*/NULL, x25519_free, }; - -int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, - size_t len) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - return x25519_set_pub_raw(pkey, in, len); -} - -size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { - // TODO(davidben): In OpenSSL, this function also works for |EVP_PKEY_EC| - // keys. Add support if it ever comes up. - if (pkey->type != EVP_PKEY_X25519) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return 0; - } - - const X25519_KEY *key = pkey->pkey.ptr; - if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); - return 0; - } - - *out_ptr = OPENSSL_memdup(key->pub, 32); - return *out_ptr == NULL ? 0 : 32; -} diff --git a/third_party/boringssl/kit/src/crypto/evp/print.c b/third_party/boringssl/kit/src/crypto/evp/print.c index 3621d5f2..05383b72 100644 --- a/third_party/boringssl/kit/src/crypto/evp/print.c +++ b/third_party/boringssl/kit/src/crypto/evp/print.c @@ -64,8 +64,25 @@ #include "../fipsmodule/rsa/internal.h" -static int bn_print(BIO *bp, const char *number, const BIGNUM *num, - uint8_t *buf, int off) { +static int print_hex(BIO *bp, const uint8_t *data, size_t len, int off) { + for (size_t i = 0; i < len; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 || // + !BIO_indent(bp, off + 4, 128)) { + return 0; + } + } + if (BIO_printf(bp, "%02x%s", data[i], (i + 1 == len) ? "" : ":") <= 0) { + return 0; + } + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + return 1; +} + +static int bn_print(BIO *bp, const char *name, const BIGNUM *num, int off) { if (num == NULL) { return 1; } @@ -74,287 +91,163 @@ static int bn_print(BIO *bp, const char *number, const BIGNUM *num, return 0; } if (BN_is_zero(num)) { - if (BIO_printf(bp, "%s 0\n", number) <= 0) { + if (BIO_printf(bp, "%s 0\n", name) <= 0) { return 0; } return 1; } - if (BN_num_bytes(num) <= sizeof(long)) { + uint64_t u64; + if (BN_get_u64(num, &u64)) { const char *neg = BN_is_negative(num) ? "-" : ""; - if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, - (unsigned long)num->d[0], neg, - (unsigned long)num->d[0]) <= 0) { - return 0; - } + return BIO_printf(bp, "%s %s%" PRIu64 " (%s0x%" PRIx64 ")\n", name, neg, + u64, neg, u64) > 0; + } + + if (BIO_printf(bp, "%s%s", name, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; + } + + // Print |num| in hex, adding a leading zero, as in ASN.1, if the high bit + // is set. + // + // TODO(davidben): Do we need to do this? We already print "(Negative)" above + // and negative values are never valid in keys anyway. + size_t len = BN_num_bytes(num); + uint8_t *buf = OPENSSL_malloc(len + 1); + if (buf == NULL) { + return 0; + } + + buf[0] = 0; + BN_bn2bin(num, buf + 1); + int ret; + if (len > 0 && (buf[1] & 0x80) != 0) { + // Print the whole buffer. + ret = print_hex(bp, buf, len + 1, off); } else { - buf[0] = 0; - if (BIO_printf(bp, "%s%s", number, - (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { - return 0; - } - int n = BN_bn2bin(num, &buf[1]); - - if (buf[1] & 0x80) { - n++; - } else { - buf++; - } - - int i; - for (i = 0; i < n; i++) { - if ((i % 15) == 0) { - if (BIO_puts(bp, "\n") <= 0 || - !BIO_indent(bp, off + 4, 128)) { - return 0; - } - } - if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") <= 0) { - return 0; - } - } - if (BIO_write(bp, "\n", 1) <= 0) { - return 0; - } - } - return 1; -} - -static void update_buflen(const BIGNUM *b, size_t *pbuflen) { - if (!b) { - return; - } - - size_t len = BN_num_bytes(b); - if (*pbuflen < len) { - *pbuflen = len; + // Skip the leading zero. + ret = print_hex(bp, buf + 1, len, off); } + OPENSSL_free(buf); + return ret; } // RSA keys. static int do_rsa_print(BIO *out, const RSA *rsa, int off, int include_private) { - const char *s, *str; - uint8_t *m = NULL; - int ret = 0, mod_len = 0; - size_t buf_len = 0; - - update_buflen(rsa->n, &buf_len); - update_buflen(rsa->e, &buf_len); - - if (include_private) { - update_buflen(rsa->d, &buf_len); - update_buflen(rsa->p, &buf_len); - update_buflen(rsa->q, &buf_len); - update_buflen(rsa->dmp1, &buf_len); - update_buflen(rsa->dmq1, &buf_len); - update_buflen(rsa->iqmp, &buf_len); - } - - m = (uint8_t *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); - goto err; - } - + int mod_len = 0; if (rsa->n != NULL) { mod_len = BN_num_bits(rsa->n); } if (!BIO_indent(out, off, 128)) { - goto err; + return 0; } + const char *s, *str; if (include_private && rsa->d) { if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "modulus:"; s = "publicExponent:"; } else { if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { - goto err; + return 0; } str = "Modulus:"; s = "Exponent:"; } - if (!bn_print(out, str, rsa->n, m, off) || - !bn_print(out, s, rsa->e, m, off)) { - goto err; + if (!bn_print(out, str, rsa->n, off) || + !bn_print(out, s, rsa->e, off)) { + return 0; } if (include_private) { - if (!bn_print(out, "privateExponent:", rsa->d, m, off) || - !bn_print(out, "prime1:", rsa->p, m, off) || - !bn_print(out, "prime2:", rsa->q, m, off) || - !bn_print(out, "exponent1:", rsa->dmp1, m, off) || - !bn_print(out, "exponent2:", rsa->dmq1, m, off) || - !bn_print(out, "coefficient:", rsa->iqmp, m, off)) { - goto err; + if (!bn_print(out, "privateExponent:", rsa->d, off) || + !bn_print(out, "prime1:", rsa->p, off) || + !bn_print(out, "prime2:", rsa->q, off) || + !bn_print(out, "exponent1:", rsa->dmp1, off) || + !bn_print(out, "exponent2:", rsa->dmq1, off) || + !bn_print(out, "coefficient:", rsa->iqmp, off)) { + return 0; } } - ret = 1; -err: - OPENSSL_free(m); - return ret; + return 1; } -static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 0); } -static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_rsa_print(bp, EVP_PKEY_get0_RSA(pkey), indent, 1); } // DSA keys. static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { - uint8_t *m = NULL; - int ret = 0; - size_t buf_len = 0; - const char *ktype = NULL; - - const BIGNUM *priv_key, *pub_key; - - priv_key = NULL; + const BIGNUM *priv_key = NULL; if (ptype == 2) { - priv_key = x->priv_key; + priv_key = DSA_get0_priv_key(x); } - pub_key = NULL; + const BIGNUM *pub_key = NULL; if (ptype > 0) { - pub_key = x->pub_key; + pub_key = DSA_get0_pub_key(x); } - ktype = "DSA-Parameters"; + const char *ktype = "DSA-Parameters"; if (ptype == 2) { ktype = "Private-Key"; } else if (ptype == 1) { ktype = "Public-Key"; } - update_buflen(x->p, &buf_len); - update_buflen(x->q, &buf_len); - update_buflen(x->g, &buf_len); - update_buflen(priv_key, &buf_len); - update_buflen(pub_key, &buf_len); - - m = (uint8_t *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); - goto err; + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(DSA_get0_p(x))) <= + 0 || + // |priv_key| and |pub_key| may be NULL, in which case |bn_print| will + // silently skip them. + !bn_print(bp, "priv:", priv_key, off) || + !bn_print(bp, "pub:", pub_key, off) || + !bn_print(bp, "P:", DSA_get0_p(x), off) || + !bn_print(bp, "Q:", DSA_get0_q(x), off) || + !bn_print(bp, "G:", DSA_get0_g(x), off)) { + return 0; } - if (priv_key) { - if (!BIO_indent(bp, off, 128) || - BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) { - goto err; - } - } - - if (!bn_print(bp, "priv:", priv_key, m, off) || - !bn_print(bp, "pub: ", pub_key, m, off) || - !bn_print(bp, "P: ", x->p, m, off) || - !bn_print(bp, "Q: ", x->q, m, off) || - !bn_print(bp, "G: ", x->g, m, off)) { - goto err; - } - ret = 1; - -err: - OPENSSL_free(m); - return ret; + return 1; } -static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 0); } -static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 1); } -static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 2); } // EC keys. static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { - uint8_t *buffer = NULL; - const char *ecstr; - size_t buf_len = 0, i; - int ret = 0, reason = ERR_R_BIO_LIB; - BIGNUM *order = NULL; - BN_CTX *ctx = NULL; const EC_GROUP *group; - const EC_POINT *public_key; - const BIGNUM *priv_key; - uint8_t *pub_key_bytes = NULL; - size_t pub_key_bytes_len = 0; - if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; + OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - ctx = BN_CTX_new(); - if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (ktype > 0) { - public_key = EC_KEY_get0_public_key(x); - if (public_key != NULL) { - pub_key_bytes_len = EC_POINT_point2oct( - group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); - if (pub_key_bytes == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - pub_key_bytes_len = - EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), - pub_key_bytes, pub_key_bytes_len, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - buf_len = pub_key_bytes_len; - } - } - - if (ktype == 2) { - priv_key = EC_KEY_get0_private_key(x); - if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) { - buf_len = i; - } - } else { - priv_key = NULL; - } - - if (ktype > 0) { - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - } + const char *ecstr; if (ktype == 2) { ecstr = "Private-Key"; } else if (ktype == 1) { @@ -364,62 +257,61 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { } if (!BIO_indent(bp, off, 128)) { - goto err; + return 0; } - order = BN_new(); - if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || - BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { - goto err; + int curve_name = EC_GROUP_get_curve_name(group); + if (BIO_printf(bp, "%s: (%s)\n", ecstr, + curve_name == NID_undef + ? "unknown curve" + : EC_curve_nid2nist(curve_name)) <= 0) { + return 0; } - if ((priv_key != NULL) && - !bn_print(bp, "priv:", priv_key, buffer, off)) { - goto err; + if (ktype == 2) { + const BIGNUM *priv_key = EC_KEY_get0_private_key(x); + if (priv_key != NULL && // + !bn_print(bp, "priv:", priv_key, off)) { + return 0; + } } - if (pub_key_bytes != NULL) { - BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); - } - // TODO(fork): implement - /* - if (!ECPKParameters_print(bp, group, off)) - goto err; */ - ret = 1; -err: - if (!ret) { - OPENSSL_PUT_ERROR(EVP, reason); + if (ktype > 0 && EC_KEY_get0_public_key(x) != NULL) { + uint8_t *pub = NULL; + size_t pub_len = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL); + if (pub_len == 0) { + return 0; + } + int ret = BIO_indent(bp, off, 128) && // + BIO_puts(bp, "pub:") > 0 && // + print_hex(bp, pub, pub_len, off); + OPENSSL_free(pub); + if (!ret) { + return 0; + } } - OPENSSL_free(pub_key_bytes); - BN_free(order); - BN_CTX_free(ctx); - OPENSSL_free(buffer); - return ret; + + return 1; } -static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 0); } -static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 1); } -static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) { - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { + return do_EC_KEY_print(bp, EVP_PKEY_get0_EC_KEY(pkey), indent, 2); } typedef struct { int type; - int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); - int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent); } EVP_PKEY_PRINT_METHOD; static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { @@ -463,27 +355,27 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->pub_print != NULL) { - return method->pub_print(out, pkey, indent, pctx); + return method->pub_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Public Key"); } int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->priv_print != NULL) { - return method->priv_print(out, pkey, indent, pctx); + return method->priv_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Private Key"); } int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->param_print != NULL) { - return method->param_print(out, pkey, indent, pctx); + return method->param_print(out, pkey, indent); } return print_unsupported(out, pkey, indent, "Parameters"); } diff --git a/third_party/boringssl/kit/src/crypto/evp/scrypt.c b/third_party/boringssl/kit/src/crypto/evp/scrypt.c index 7ec6244a..8212cd15 100644 --- a/third_party/boringssl/kit/src/crypto/evp/scrypt.c +++ b/third_party/boringssl/kit/src/crypto/evp/scrypt.c @@ -13,7 +13,6 @@ #include #include -#include #include "../internal.h" @@ -30,7 +29,7 @@ // A block_t is a Salsa20 block. typedef struct { uint32_t words[16]; } block_t; -OPENSSL_STATIC_ASSERT(sizeof(block_t) == 64, "block_t has padding"); +static_assert(sizeof(block_t) == 64, "block_t has padding"); // salsa208_word_specification implements the Salsa20/8 core function, also // described in RFC 7914, section 3. It modifies the block at |inout| @@ -171,14 +170,13 @@ int EVP_PBE_scrypt(const char *password, size_t password_len, // Allocate and divide up the scratch space. |max_mem| fits in a size_t, which // is no bigger than uint64_t, so none of these operations may overflow. - OPENSSL_STATIC_ASSERT(UINT64_MAX >= ((size_t)-1), "size_t exceeds uint64_t"); + static_assert(UINT64_MAX >= ((size_t)-1), "size_t exceeds uint64_t"); size_t B_blocks = p * 2 * r; size_t B_bytes = B_blocks * sizeof(block_t); size_t T_blocks = 2 * r; size_t V_blocks = N * 2 * r; block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t)); if (B == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/evp/sign.c b/third_party/boringssl/kit/src/crypto/evp/sign.c index ced86bdf..e126704f 100644 --- a/third_party/boringssl/kit/src/crypto/evp/sign.c +++ b/third_party/boringssl/kit/src/crypto/evp/sign.c @@ -56,6 +56,8 @@ #include +#include + #include #include @@ -74,15 +76,20 @@ int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { return EVP_DigestUpdate(ctx, data, len); } -int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, - unsigned int *out_sig_len, EVP_PKEY *pkey) { +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, unsigned *out_sig_len, + EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; size_t sig_len = EVP_PKEY_size(pkey); + // Ensure the final result will fit in |unsigned|. + if (sig_len > UINT_MAX) { + sig_len = UINT_MAX; + } + *out_sig_len = 0; EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || @@ -92,19 +99,17 @@ int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, EVP_MD_CTX_cleanup(&tmp_ctx); pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + if (!pkctx || // + !EVP_PKEY_sign_init(pkctx) || !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { goto out; } - *out_sig_len = sig_len; + *out_sig_len = (unsigned)sig_len; ret = 1; out: - if (pkctx) { - EVP_PKEY_CTX_free(pkctx); - } - + EVP_PKEY_CTX_free(pkctx); return ret; } @@ -123,7 +128,7 @@ int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, EVP_PKEY *pkey) { uint8_t m[EVP_MAX_MD_SIZE]; - unsigned int m_len; + unsigned m_len; int ret = 0; EVP_MD_CTX tmp_ctx; EVP_PKEY_CTX *pkctx = NULL; diff --git a/third_party/boringssl/kit/src/crypto/ex_data.c b/third_party/boringssl/kit/src/crypto/ex_data.c index 71d60a52..7dc3272b 100644 --- a/third_party/boringssl/kit/src/crypto/ex_data.c +++ b/third_party/boringssl/kit/src/crypto/ex_data.c @@ -109,12 +109,13 @@ #include #include +#include +#include #include #include #include #include -#include #include #include "internal.h" @@ -126,67 +127,72 @@ struct crypto_ex_data_func_st { long argl; // Arbitary long void *argp; // Arbitary void pointer CRYPTO_EX_free *free_func; + // next points to the next |CRYPTO_EX_DATA_FUNCS| or NULL if this is the last + // one. It may only be read if synchronized with a read from |num_funcs|. + CRYPTO_EX_DATA_FUNCS *next; }; int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, long argl, void *argp, CRYPTO_EX_free *free_func) { - CRYPTO_EX_DATA_FUNCS *funcs; - int ret = 0; - - funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + CRYPTO_EX_DATA_FUNCS *funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); if (funcs == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } funcs->argl = argl; funcs->argp = argp; funcs->free_func = free_func; + funcs->next = NULL; - CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock); + CRYPTO_MUTEX_lock_write(&ex_data_class->lock); - if (ex_data_class->meth == NULL) { - ex_data_class->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + uint32_t num_funcs = CRYPTO_atomic_load_u32(&ex_data_class->num_funcs); + // The index must fit in |int|. + if (num_funcs > (size_t)(INT_MAX - ex_data_class->num_reserved)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); + CRYPTO_MUTEX_unlock_write(&ex_data_class->lock); + return 0; } - if (ex_data_class->meth == NULL || - !sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); - OPENSSL_free(funcs); - goto err; + // Append |funcs| to the linked list. + if (ex_data_class->last == NULL) { + assert(num_funcs == 0); + ex_data_class->funcs = funcs; + ex_data_class->last = funcs; + } else { + ex_data_class->last->next = funcs; + ex_data_class->last = funcs; } - *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + - ex_data_class->num_reserved; - ret = 1; - -err: - CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock); - return ret; + CRYPTO_atomic_store_u32(&ex_data_class->num_funcs, num_funcs + 1); + CRYPTO_MUTEX_unlock_write(&ex_data_class->lock); + *out_index = (int)num_funcs + ex_data_class->num_reserved; + return 1; } int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) { - int n, i; + if (index < 0) { + // A caller that can accidentally pass in an invalid index into this + // function will hit an memory error if |index| happened to be valid, and + // expected |val| to be of a different type. + abort(); + } if (ad->sk == NULL) { ad->sk = sk_void_new_null(); if (ad->sk == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } - n = sk_void_num(ad->sk); - // Add NULL values until the stack is long enough. - for (i = n; i <= index; i++) { + for (size_t i = sk_void_num(ad->sk); i <= (size_t)index; i++) { if (!sk_void_push(ad->sk, NULL)) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } } - sk_void_set(ad->sk, index, val); + sk_void_set(ad->sk, (size_t)index, val); return 1; } @@ -197,34 +203,6 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { return sk_void_value(ad->sk, idx); } -// get_func_pointers takes a copy of the CRYPTO_EX_DATA_FUNCS pointers, if any, -// for the given class. If there are some pointers, it sets |*out| to point to -// a fresh stack of them. Otherwise it sets |*out| to NULL. It returns one on -// success or zero on error. -static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, - CRYPTO_EX_DATA_CLASS *ex_data_class) { - size_t n; - - *out = NULL; - - // CRYPTO_EX_DATA_FUNCS structures are static once set, so we can take a - // shallow copy of the list under lock and then use the structures without - // the lock held. - CRYPTO_STATIC_MUTEX_lock_read(&ex_data_class->lock); - n = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth); - if (n > 0) { - *out = sk_CRYPTO_EX_DATA_FUNCS_dup(ex_data_class->meth); - } - CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock); - - if (n > 0 && *out == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); - return 0; - } - - return 1; -} - void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { ad->sk = NULL; } @@ -236,24 +214,22 @@ void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, return; } - STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; - if (!get_func_pointers(&func_pointers, ex_data_class)) { - // TODO(davidben): This leaks memory on malloc error. - return; - } + uint32_t num_funcs = CRYPTO_atomic_load_u32(&ex_data_class->num_funcs); + // |CRYPTO_get_ex_new_index| will not allocate indices beyond |INT_MAX|. + assert(num_funcs <= (size_t)(INT_MAX - ex_data_class->num_reserved)); - for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { - CRYPTO_EX_DATA_FUNCS *func_pointer = - sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); - if (func_pointer->free_func) { - void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved); - func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved, - func_pointer->argl, func_pointer->argp); + // Defer dereferencing |ex_data_class->funcs| and |funcs->next|. It must come + // after the |num_funcs| comparison to be correctly synchronized. + CRYPTO_EX_DATA_FUNCS *const *funcs = &ex_data_class->funcs; + for (uint32_t i = 0; i < num_funcs; i++) { + if ((*funcs)->free_func != NULL) { + int index = (int)i + ex_data_class->num_reserved; + void *ptr = CRYPTO_get_ex_data(ad, index); + (*funcs)->free_func(obj, ptr, ad, index, (*funcs)->argl, (*funcs)->argp); } + funcs = &(*funcs)->next; } - sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers); - sk_void_free(ad->sk); ad->sk = NULL; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/CMakeLists.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/CMakeLists.txt index 73f8a02a..3858e8b1 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/CMakeLists.txt +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/CMakeLists.txt @@ -1,157 +1,63 @@ -include_directories(../../include) +perlasm(BCM_SOURCES aarch64 aesv8-armv8 aes/asm/aesv8-armx.pl) +perlasm(BCM_SOURCES aarch64 aesv8-gcm-armv8 modes/asm/aesv8-gcm-armv8.pl) +perlasm(BCM_SOURCES aarch64 armv8-mont bn/asm/armv8-mont.pl) +perlasm(BCM_SOURCES aarch64 bn-armv8 bn/asm/bn-armv8.pl) +perlasm(BCM_SOURCES aarch64 ghash-neon-armv8 modes/asm/ghash-neon-armv8.pl) +perlasm(BCM_SOURCES aarch64 ghashv8-armv8 modes/asm/ghashv8-armx.pl) +perlasm(BCM_SOURCES aarch64 p256_beeu-armv8-asm ec/asm/p256_beeu-armv8-asm.pl) +perlasm(BCM_SOURCES aarch64 p256-armv8-asm ec/asm/p256-armv8-asm.pl) +perlasm(BCM_SOURCES aarch64 sha1-armv8 sha/asm/sha1-armv8.pl) +perlasm(BCM_SOURCES aarch64 sha256-armv8 sha/asm/sha512-armv8.pl) +perlasm(BCM_SOURCES aarch64 sha512-armv8 sha/asm/sha512-armv8.pl) +perlasm(BCM_SOURCES aarch64 vpaes-armv8 aes/asm/vpaes-armv8.pl) +perlasm(BCM_SOURCES arm aesv8-armv7 aes/asm/aesv8-armx.pl) +perlasm(BCM_SOURCES arm armv4-mont bn/asm/armv4-mont.pl) +perlasm(BCM_SOURCES arm bsaes-armv7 aes/asm/bsaes-armv7.pl) +perlasm(BCM_SOURCES arm ghash-armv4 modes/asm/ghash-armv4.pl) +perlasm(BCM_SOURCES arm ghashv8-armv7 modes/asm/ghashv8-armx.pl) +perlasm(BCM_SOURCES arm sha1-armv4-large sha/asm/sha1-armv4-large.pl) +perlasm(BCM_SOURCES arm sha256-armv4 sha/asm/sha256-armv4.pl) +perlasm(BCM_SOURCES arm sha512-armv4 sha/asm/sha512-armv4.pl) +perlasm(BCM_SOURCES arm vpaes-armv7 aes/asm/vpaes-armv7.pl) +perlasm(BCM_SOURCES x86 aesni-x86 aes/asm/aesni-x86.pl) +perlasm(BCM_SOURCES x86 bn-586 bn/asm/bn-586.pl) +perlasm(BCM_SOURCES x86 co-586 bn/asm/co-586.pl) +perlasm(BCM_SOURCES x86 ghash-ssse3-x86 modes/asm/ghash-ssse3-x86.pl) +perlasm(BCM_SOURCES x86 ghash-x86 modes/asm/ghash-x86.pl) +perlasm(BCM_SOURCES x86 md5-586 md5/asm/md5-586.pl) +perlasm(BCM_SOURCES x86 sha1-586 sha/asm/sha1-586.pl) +perlasm(BCM_SOURCES x86 sha256-586 sha/asm/sha256-586.pl) +perlasm(BCM_SOURCES x86 sha512-586 sha/asm/sha512-586.pl) +perlasm(BCM_SOURCES x86 vpaes-x86 aes/asm/vpaes-x86.pl) +perlasm(BCM_SOURCES x86 x86-mont bn/asm/x86-mont.pl) +perlasm(BCM_SOURCES x86_64 aesni-gcm-x86_64 modes/asm/aesni-gcm-x86_64.pl) +perlasm(BCM_SOURCES x86_64 aesni-x86_64 aes/asm/aesni-x86_64.pl) +perlasm(BCM_SOURCES x86_64 ghash-ssse3-x86_64 modes/asm/ghash-ssse3-x86_64.pl) +perlasm(BCM_SOURCES x86_64 ghash-x86_64 modes/asm/ghash-x86_64.pl) +perlasm(BCM_SOURCES x86_64 md5-x86_64 md5/asm/md5-x86_64.pl) +perlasm(BCM_SOURCES x86_64 p256_beeu-x86_64-asm ec/asm/p256_beeu-x86_64-asm.pl) +perlasm(BCM_SOURCES x86_64 p256-x86_64-asm ec/asm/p256-x86_64-asm.pl) +perlasm(BCM_SOURCES x86_64 rdrand-x86_64 rand/asm/rdrand-x86_64.pl) +perlasm(BCM_SOURCES x86_64 rsaz-avx2 bn/asm/rsaz-avx2.pl) +perlasm(BCM_SOURCES x86_64 sha1-x86_64 sha/asm/sha1-x86_64.pl) +perlasm(BCM_SOURCES x86_64 sha256-x86_64 sha/asm/sha512-x86_64.pl) +perlasm(BCM_SOURCES x86_64 sha512-x86_64 sha/asm/sha512-x86_64.pl) +perlasm(BCM_SOURCES x86_64 vpaes-x86_64 aes/asm/vpaes-x86_64.pl) +perlasm(BCM_SOURCES x86_64 x86_64-mont bn/asm/x86_64-mont.pl) +perlasm(BCM_SOURCES x86_64 x86_64-mont5 bn/asm/x86_64-mont5.pl) -if(ARCH STREQUAL "x86_64") - set( - BCM_ASM_SOURCES - - aesni-gcm-x86_64.${ASM_EXT} - aesni-x86_64.${ASM_EXT} - ghash-ssse3-x86_64.${ASM_EXT} - ghash-x86_64.${ASM_EXT} - md5-x86_64.${ASM_EXT} - p256-x86_64-asm.${ASM_EXT} - p256_beeu-x86_64-asm.${ASM_EXT} - rdrand-x86_64.${ASM_EXT} - rsaz-avx2.${ASM_EXT} - sha1-x86_64.${ASM_EXT} - sha256-x86_64.${ASM_EXT} - sha512-x86_64.${ASM_EXT} - vpaes-x86_64.${ASM_EXT} - x86_64-mont5.${ASM_EXT} - x86_64-mont.${ASM_EXT} - ) +if(OPENSSL_ASM) + list(APPEND BCM_SOURCES_ASM_USED ${BCM_SOURCES_ASM}) endif() - -if(ARCH STREQUAL "x86") - set( - BCM_ASM_SOURCES - - aesni-x86.${ASM_EXT} - bn-586.${ASM_EXT} - co-586.${ASM_EXT} - ghash-ssse3-x86.${ASM_EXT} - ghash-x86.${ASM_EXT} - md5-586.${ASM_EXT} - sha1-586.${ASM_EXT} - sha256-586.${ASM_EXT} - sha512-586.${ASM_EXT} - vpaes-x86.${ASM_EXT} - x86-mont.${ASM_EXT} - ) +if(OPENSSL_NASM) + list(APPEND BCM_SOURCES_ASM_USED ${BCM_SOURCES_NASM}) endif() -if(ARCH STREQUAL "arm") - set( - BCM_ASM_SOURCES - - aesv8-armx.${ASM_EXT} - armv4-mont.${ASM_EXT} - bsaes-armv7.${ASM_EXT} - ghash-armv4.${ASM_EXT} - ghashv8-armx.${ASM_EXT} - sha1-armv4-large.${ASM_EXT} - sha256-armv4.${ASM_EXT} - sha512-armv4.${ASM_EXT} - vpaes-armv7.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "aarch64") - set( - BCM_ASM_SOURCES - - aesv8-armx.${ASM_EXT} - armv8-mont.${ASM_EXT} - ghash-neon-armv8.${ASM_EXT} - ghashv8-armx.${ASM_EXT} - sha1-armv8.${ASM_EXT} - sha256-armv8.${ASM_EXT} - sha512-armv8.${ASM_EXT} - vpaes-armv8.${ASM_EXT} - ) -endif() - -if(ARCH STREQUAL "ppc64le") - set( - BCM_ASM_SOURCES - - aesp8-ppc.${ASM_EXT} - ghashp8-ppc.${ASM_EXT} - ) -endif() - -perlasm(aesni-gcm-x86_64.${ASM_EXT} modes/asm/aesni-gcm-x86_64.pl) -perlasm(aesni-x86_64.${ASM_EXT} aes/asm/aesni-x86_64.pl) -perlasm(aesni-x86.${ASM_EXT} aes/asm/aesni-x86.pl) -perlasm(aesp8-ppc.${ASM_EXT} aes/asm/aesp8-ppc.pl) -perlasm(aesv8-armx.${ASM_EXT} aes/asm/aesv8-armx.pl) -perlasm(armv4-mont.${ASM_EXT} bn/asm/armv4-mont.pl) -perlasm(armv8-mont.${ASM_EXT} bn/asm/armv8-mont.pl) -perlasm(bn-586.${ASM_EXT} bn/asm/bn-586.pl) -perlasm(bsaes-armv7.${ASM_EXT} aes/asm/bsaes-armv7.pl) -perlasm(co-586.${ASM_EXT} bn/asm/co-586.pl) -perlasm(ghash-armv4.${ASM_EXT} modes/asm/ghash-armv4.pl) -perlasm(ghashp8-ppc.${ASM_EXT} modes/asm/ghashp8-ppc.pl) -perlasm(ghashv8-armx.${ASM_EXT} modes/asm/ghashv8-armx.pl) -perlasm(ghash-neon-armv8.${ASM_EXT} modes/asm/ghash-neon-armv8.pl) -perlasm(ghash-ssse3-x86_64.${ASM_EXT} modes/asm/ghash-ssse3-x86_64.pl) -perlasm(ghash-ssse3-x86.${ASM_EXT} modes/asm/ghash-ssse3-x86.pl) -perlasm(ghash-x86_64.${ASM_EXT} modes/asm/ghash-x86_64.pl) -perlasm(ghash-x86.${ASM_EXT} modes/asm/ghash-x86.pl) -perlasm(md5-586.${ASM_EXT} md5/asm/md5-586.pl) -perlasm(md5-x86_64.${ASM_EXT} md5/asm/md5-x86_64.pl) -perlasm(p256-x86_64-asm.${ASM_EXT} ec/asm/p256-x86_64-asm.pl) -perlasm(p256_beeu-x86_64-asm.${ASM_EXT} ec/asm/p256_beeu-x86_64-asm.pl) -perlasm(rdrand-x86_64.${ASM_EXT} rand/asm/rdrand-x86_64.pl) -perlasm(rsaz-avx2.${ASM_EXT} bn/asm/rsaz-avx2.pl) -perlasm(sha1-586.${ASM_EXT} sha/asm/sha1-586.pl) -perlasm(sha1-armv4-large.${ASM_EXT} sha/asm/sha1-armv4-large.pl) -perlasm(sha1-armv8.${ASM_EXT} sha/asm/sha1-armv8.pl) -perlasm(sha1-x86_64.${ASM_EXT} sha/asm/sha1-x86_64.pl) -perlasm(sha256-586.${ASM_EXT} sha/asm/sha256-586.pl) -perlasm(sha256-armv4.${ASM_EXT} sha/asm/sha256-armv4.pl) -perlasm(sha256-armv8.${ASM_EXT} sha/asm/sha512-armv8.pl) -perlasm(sha256-x86_64.${ASM_EXT} sha/asm/sha512-x86_64.pl) -perlasm(sha512-586.${ASM_EXT} sha/asm/sha512-586.pl) -perlasm(sha512-armv4.${ASM_EXT} sha/asm/sha512-armv4.pl) -perlasm(sha512-armv8.${ASM_EXT} sha/asm/sha512-armv8.pl) -perlasm(sha512-x86_64.${ASM_EXT} sha/asm/sha512-x86_64.pl) -perlasm(vpaes-armv7.${ASM_EXT} aes/asm/vpaes-armv7.pl) -perlasm(vpaes-armv8.${ASM_EXT} aes/asm/vpaes-armv8.pl) -perlasm(vpaes-x86_64.${ASM_EXT} aes/asm/vpaes-x86_64.pl) -perlasm(vpaes-x86.${ASM_EXT} aes/asm/vpaes-x86.pl) -perlasm(x86_64-mont5.${ASM_EXT} bn/asm/x86_64-mont5.pl) -perlasm(x86_64-mont.${ASM_EXT} bn/asm/x86_64-mont.pl) -perlasm(x86-mont.${ASM_EXT} bn/asm/x86-mont.pl) - -function(cpreprocess dest src) - set(TARGET "") - if(CMAKE_ASM_COMPILER_TARGET) - set(TARGET "--target=${CMAKE_ASM_COMPILER_TARGET}") - endif() - - add_custom_command( - OUTPUT ${dest} - COMMAND ${CMAKE_ASM_COMPILER} ${TARGET} $CMAKE_ASM_FLAGS -E ${src} -I${PROJECT_SOURCE_DIR}/include > ${dest} - DEPENDS - ${src} - ${PROJECT_SOURCE_DIR}/include/openssl/arm_arch.h - WORKING_DIRECTORY . - ) -endfunction() - if(FIPS_DELOCATE) if(FIPS_SHARED) error("Can't set both delocate and shared mode for FIPS build") endif() - if(OPENSSL_NO_ASM) - # If OPENSSL_NO_ASM was defined then ASM will not have been enabled, but in - # FIPS mode we have to have it because the module build requires going via - # textual assembly. - enable_language(ASM) - endif() - add_library( bcm_c_generated_asm @@ -159,29 +65,32 @@ if(FIPS_DELOCATE) bcm.c ) - - if(ARCH STREQUAL "aarch64") - # Perlasm output on Aarch64 needs to pass through the C preprocessor before - # it can be parsed by delocate. - foreach(asm ${BCM_ASM_SOURCES}) - cpreprocess(${asm}.s ${asm}) - list(APPEND BCM_ASM_PROCESSED_SOURCES "${asm}.s") - endforeach() - else() - # No preprocessing is required on other platforms. - set(BCM_ASM_PROCESSED_SOURCES ${BCM_ASM_SOURCES}) - endif() - - add_dependencies(bcm_c_generated_asm global_target) - + add_dependencies(bcm_c_generated_asm boringssl_prefix_symbols) + target_include_directories(bcm_c_generated_asm PRIVATE ../../include) set_target_properties(bcm_c_generated_asm PROPERTIES COMPILE_OPTIONS "-S") set_target_properties(bcm_c_generated_asm PROPERTIES POSITION_INDEPENDENT_CODE ON) + set(TARGET "") + if(CMAKE_ASM_COMPILER_TARGET) + set(TARGET "--target=${CMAKE_ASM_COMPILER_TARGET}") + endif() + go_executable(delocate boringssl.googlesource.com/boringssl/util/fipstools/delocate) add_custom_command( OUTPUT bcm-delocated.S - COMMAND ./delocate -a $ -o bcm-delocated.S ${BCM_ASM_PROCESSED_SOURCES} - DEPENDS bcm_c_generated_asm delocate ${BCM_ASM_PROCESSED_SOURCES} + COMMAND + ./delocate + -a $ + -o bcm-delocated.S + -cc ${CMAKE_ASM_COMPILER} + -cc-flags "${TARGET} $CMAKE_ASM_FLAGS" + ${PROJECT_SOURCE_DIR}/include/openssl/arm_arch.h + ${BCM_SOURCES_ASM_USED} + DEPENDS + bcm_c_generated_asm + delocate + ${BCM_SOURCES_ASM_USED} + ${PROJECT_SOURCE_DIR}/include/openssl/arm_arch.h WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) @@ -192,25 +101,14 @@ if(FIPS_DELOCATE) bcm-delocated.S ) - - add_dependencies(bcm_hashunset global_target) - set_target_properties(bcm_hashunset PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(bcm_hashunset PROPERTIES LINKER_LANGUAGE C) - set(MAYBE_INJECT_HASH_SHA256_FLAG "") - # If building with OPENSSL_NO_ASM then ARCH will be "generic", but we still - # need to use SHA-256. Since this only matters for FIPS, we only need to - # worry about the Linux spelling of AArch64. - if (ARCH STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") - set(MAYBE_INJECT_HASH_SHA256_FLAG "-sha256") - endif() - go_executable(inject_hash boringssl.googlesource.com/boringssl/util/fipstools/inject_hash) add_custom_command( OUTPUT bcm.o - COMMAND ./inject_hash -o bcm.o -in-archive $ ${MAYBE_INJECT_HASH_SHA256_FLAG} + COMMAND ./inject_hash -o bcm.o -in-archive $ DEPENDS bcm_hashunset inject_hash WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) @@ -227,9 +125,8 @@ if(FIPS_DELOCATE) fips_shared_support.c ) - - add_dependencies(fipsmodule global_target) - + add_dependencies(fipsmodule boringssl_prefix_symbols) + target_include_directories(fipsmodule PRIVATE ../../include) set_target_properties(fipsmodule PROPERTIES LINKER_LANGUAGE C) elseif(FIPS_SHARED) if(NOT BUILD_SHARED_LIBS) @@ -243,8 +140,8 @@ elseif(FIPS_SHARED) fips_shared_support.c ) - - add_dependencies(fipsmodule global_target) + add_dependencies(fipsmodule boringssl_prefix_symbols) + target_include_directories(fipsmodule PRIVATE ../../include) add_library( bcm_library @@ -252,11 +149,10 @@ elseif(FIPS_SHARED) STATIC bcm.c - - ${BCM_ASM_SOURCES} + ${BCM_SOURCES_ASM_USED} ) - - add_dependencies(bcm_library global_target) + add_dependencies(bcm_library boringssl_prefix_symbols) + target_include_directories(bcm_library PRIVATE ../../include) add_custom_command( OUTPUT bcm.o @@ -274,9 +170,8 @@ else() bcm.c fips_shared_support.c - - ${BCM_ASM_SOURCES} + ${BCM_SOURCES_ASM_USED} ) - - add_dependencies(fipsmodule global_target) + add_dependencies(fipsmodule boringssl_prefix_symbols) + target_include_directories(fipsmodule PRIVATE ../../include) endif() diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/FIPS.md b/third_party/boringssl/kit/src/crypto/fipsmodule/FIPS.md index d3b3890f..92eebabb 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/FIPS.md +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/FIPS.md @@ -12,30 +12,22 @@ BoringCrypto has undergone the following validations: 1. 2018-07-30: certificate [#3318](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3318), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx) (in docx format). 1. 2019-08-08: certificate [#3678](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3678), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20190808.docx) (in docx format). 1. 2019-10-20: certificate [#3753](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3753), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Android-Security-Policy-20191020.docx) (in docx format). +1. 2021-01-28: certificate [#4156](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/4156), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Android-Security-Policy-20210319.docx) (in docx format). +1. 2021-04-29: certificate [#4407](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407). -## Running CAVP tests +## Running ACVP tests -CAVP results are calculated by `util/fipstools/cavp`, but that binary is almost always run by `util/fipstools/run_cavp.go`. The latter knows the set of tests to be processed and the flags needed to configure `cavp` for each one. It must be run from the top of a CAVP directory and needs the following options: +See `util/fipstools/acvp/ACVP.md` for details of how ACVP testing is done. -1. `-oracle-bin`: points to the location of `util/fipstools/cavp` -2. `-no-fax`: this is needed to suppress checking of the FAX files, which are only included in sample sets. +## Breaking known-answer and continuous tests -## Breaking power-on and continuous tests +Each known-answer test (KAT) uses a unique, random input value. `util/fipstools/break-kat.go` contains a listing of those values and can be used to corrupt a given test in a binary. Since changes to the KAT input values will invalidate the integrity test, `BORINGSSL_FIPS_BREAK_TESTS` can be defined in `fips_break_tests.h` to disable it for the purposes of testing. -In order to demonstrate failures of the various FIPS 140 tests, BoringSSL can be built in ways that will trigger such failures. This is controlled by passing `-DFIPS_BREAK_TEST=`(test to break) to CMake, where the following tests can be specified: +Some FIPS tests cannot be broken by replacing a known string in the binary. For those, when `BORINGSSL_FIPS_BREAK_TESTS` is defined, the environment variable `BORINGSSL_FIPS_BREAK_TEST` can be set to one of a number of values in order to break the corresponding test: -1. AES\_CBC -1. AES\_GCM -1. DES -1. SHA\_1 -1. SHA\_256 -1. SHA\_512 -1. RSA\_SIG -1. ECDSA\_SIG -1. DRBG -1. RSA\_PWCT -1. ECDSA\_PWCT -1. TLS\_KDF +1. `RSA_PWCT` +1. `ECDSA_PWCT` +1. `CRNG` ## Breaking the integrity test @@ -61,12 +53,6 @@ There is a second interface to the RNG which allows the caller to supply bytes t FIPS requires that RNG state be zeroed when the process exits. In order to implement this, all per-thread RNG states are tracked in a linked list and a destructor function is included which clears them. In order for this to be safe in the presence of threads, a lock is used to stop all other threads from using the RNG once this process has begun. Thus the main thread exiting may cause other threads to deadlock, and drawing on entropy in a destructor function may also deadlock. -## Self-test optimisation - -On Android, the self-tests are optimised in line with [IG](https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf) section 9.11. The module will always perform the integrity test at power-on, but the self-tests will test for the presence of a file named after the hex encoded, HMAC-SHA-256 hash of the module in `/dev/boringssl/selftest/`. If such a file is found then the self-tests are skipped. Otherwise, after the self-tests complete successfully, that file will be written. Any I/O errors are ignored and, if they occur when testing for the presence of the file, the module acts as if it's not present. - -It is intended that a `tmpfs` be mounted at that location in order to skip running the self tests for every process once they have already passed in a given instance of the operating system. - ## Integrity Test FIPS-140 mandates that a module calculate an HMAC of its own code in a constructor function and compare the result to a known-good value. Typical code produced by a C compiler includes large numbers of relocations: places in the machine code where the linker needs to resolve and inject the final value of a symbolic expression. These relocations mean that the bytes that make up any specific bit of code generally aren't known until the final link has completed. diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes.c b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes.c index f60281df..60f35457 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes.c @@ -50,8 +50,6 @@ #include -#include - #include "internal.h" #include "../modes/internal.h" diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_nohw.c b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_nohw.c index 12cabcb8..c5dec0e5 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_nohw.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_nohw.c @@ -18,6 +18,7 @@ #include #include "../../internal.h" +#include "internal.h" #if defined(OPENSSL_SSE2) #include @@ -151,10 +152,10 @@ static inline aes_word_t aes_nohw_shift_right(aes_word_t a, aes_word_t i) { } #endif // OPENSSL_SSE2 -OPENSSL_STATIC_ASSERT(AES_NOHW_BATCH_SIZE * 128 == 8 * 8 * sizeof(aes_word_t), - "batch size does not match word size"); -OPENSSL_STATIC_ASSERT(AES_NOHW_WORD_SIZE == sizeof(aes_word_t), - "AES_NOHW_WORD_SIZE is incorrect"); +static_assert(AES_NOHW_BATCH_SIZE * 128 == 8 * 8 * sizeof(aes_word_t), + "batch size does not match word size"); +static_assert(AES_NOHW_WORD_SIZE == sizeof(aes_word_t), + "AES_NOHW_WORD_SIZE is incorrect"); // Block representations. @@ -1181,29 +1182,27 @@ void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, aes_nohw_expand_round_keys(&sched, key); // Make |AES_NOHW_BATCH_SIZE| copies of |ivec|. - alignas(AES_NOHW_WORD_SIZE) union { - uint32_t u32[AES_NOHW_BATCH_SIZE * 4]; - uint8_t u8[AES_NOHW_BATCH_SIZE * 16]; - } ivs, enc_ivs; + alignas(AES_NOHW_WORD_SIZE) uint8_t ivs[AES_NOHW_BATCH_SIZE * 16]; + alignas(AES_NOHW_WORD_SIZE) uint8_t enc_ivs[AES_NOHW_BATCH_SIZE * 16]; for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { - memcpy(ivs.u8 + 16 * i, ivec, 16); + memcpy(ivs + 16 * i, ivec, 16); } - uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]); + uint32_t ctr = CRYPTO_load_u32_be(ivs + 12); for (;;) { // Update counters. for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { - ivs.u32[4 * i + 3] = CRYPTO_bswap4(ctr + i); + CRYPTO_store_u32_be(ivs + 16 * i + 12, ctr + (uint32_t)i); } size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks; AES_NOHW_BATCH batch; - aes_nohw_to_batch(&batch, ivs.u8, todo); + aes_nohw_to_batch(&batch, ivs, todo); aes_nohw_encrypt_batch(&sched, key->rounds, &batch); - aes_nohw_from_batch(enc_ivs.u8, todo, &batch); + aes_nohw_from_batch(enc_ivs, todo, &batch); for (size_t i = 0; i < todo; i++) { - aes_nohw_xor_block(out + 16 * i, in + 16 * i, enc_ivs.u8 + 16 * i); + aes_nohw_xor_block(out + 16 * i, in + 16 * i, enc_ivs + 16 * i); } blocks -= todo; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_test.cc index eef2567c..dd3b3748 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/aes_test.cc @@ -289,7 +289,7 @@ TEST(AESTest, ABI) { } if (bsaes_capable()) { - vpaes_set_encrypt_key(kKey, bits, &key); + ASSERT_EQ(vpaes_set_encrypt_key(kKey, bits, &key), 0); CHECK_ABI(vpaes_encrypt_key_to_bsaes, &key, &key); for (size_t blocks : block_counts) { SCOPED_TRACE(blocks); @@ -298,7 +298,7 @@ TEST(AESTest, ABI) { } } - vpaes_set_decrypt_key(kKey, bits, &key); + ASSERT_EQ(vpaes_set_decrypt_key(kKey, bits, &key), 0); CHECK_ABI(vpaes_decrypt_key_to_bsaes, &key, &key); for (size_t blocks : block_counts) { SCOPED_TRACE(blocks); @@ -308,7 +308,7 @@ TEST(AESTest, ABI) { } if (vpaes_capable()) { - CHECK_ABI(vpaes_set_encrypt_key, kKey, bits, &key); + ASSERT_EQ(CHECK_ABI(vpaes_set_encrypt_key, kKey, bits, &key), 0); CHECK_ABI(vpaes_encrypt, block, block, &key); for (size_t blocks : block_counts) { SCOPED_TRACE(blocks); @@ -321,7 +321,7 @@ TEST(AESTest, ABI) { #endif } - CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key); + ASSERT_EQ(CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key), 0); CHECK_ABI(vpaes_decrypt, block, block, &key); #if defined(VPAES_CBC) for (size_t blocks : block_counts) { @@ -333,7 +333,7 @@ TEST(AESTest, ABI) { } if (hwaes_capable()) { - CHECK_ABI(aes_hw_set_encrypt_key, kKey, bits, &key); + ASSERT_EQ(CHECK_ABI(aes_hw_set_encrypt_key, kKey, bits, &key), 0); CHECK_ABI(aes_hw_encrypt, block, block, &key); for (size_t blocks : block_counts) { SCOPED_TRACE(blocks); @@ -346,7 +346,7 @@ TEST(AESTest, ABI) { #endif } - CHECK_ABI(aes_hw_set_decrypt_key, kKey, bits, &key); + ASSERT_EQ(CHECK_ABI(aes_hw_set_decrypt_key, kKey, bits, &key), 0); CHECK_ABI(aes_hw_decrypt, block, block, &key); for (size_t blocks : block_counts) { SCOPED_TRACE(blocks); @@ -559,6 +559,10 @@ static int aes_ref_set_decrypt_key(const uint8_t *key, int bits, AES_KEY *out) { TEST(AESTest, VPAESToBSAESConvert) { + if (!vpaes_capable()) { + GTEST_SKIP(); + } + const int kNumIterations = 1000; for (int i = 0; i < kNumIterations; i++) { uint8_t key[256 / 8]; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl index 2abc8d03..215611fd 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesni-x86_64.pl @@ -1524,6 +1524,8 @@ $code.=<<___; pxor $rndkey0,$in3 movdqu 0x50($inp),$in5 pxor $rndkey0,$in4 + prefetcht0 0x1c0($inp) # We process 128 bytes (8*16), so to prefetch 1 iteration + prefetcht0 0x200($inp) # We need to prefetch 2 64 byte lines pxor $rndkey0,$in5 aesenc $rndkey1,$inout0 aesenc $rndkey1,$inout1 @@ -2764,955 +2766,6 @@ $code.=<<___; .cfi_endproc .size ${PREFIX}_xts_decrypt,.-${PREFIX}_xts_decrypt ___ -} - -###################################################################### -# void aesni_ocb_[en|de]crypt(const char *inp, char *out, size_t blocks, -# const AES_KEY *key, unsigned int start_block_num, -# unsigned char offset_i[16], const unsigned char L_[][16], -# unsigned char checksum[16]); -# -if (0) { # Omit these functions in BoringSSL -my @offset=map("%xmm$_",(10..15)); -my ($checksum,$rndkey0l)=("%xmm8","%xmm9"); -my ($block_num,$offset_p)=("%r8","%r9"); # 5th and 6th arguments -my ($L_p,$checksum_p) = ("%rbx","%rbp"); -my ($i1,$i3,$i5) = ("%r12","%r13","%r14"); -my $seventh_arg = $win64 ? 56 : 8; -my $blocks = $len; - -$code.=<<___; -.globl ${PREFIX}_ocb_encrypt -.type ${PREFIX}_ocb_encrypt,\@function,6 -.align 32 -${PREFIX}_ocb_encrypt: -.cfi_startproc - lea (%rsp),%rax - push %rbx -.cfi_push %rbx - push %rbp -.cfi_push %rbp - push %r12 -.cfi_push %r12 - push %r13 -.cfi_push %r13 - push %r14 -.cfi_push %r14 -___ -$code.=<<___ if ($win64); - lea -0xa0(%rsp),%rsp - movaps %xmm6,0x00(%rsp) # offload everything - movaps %xmm7,0x10(%rsp) - movaps %xmm8,0x20(%rsp) - movaps %xmm9,0x30(%rsp) - movaps %xmm10,0x40(%rsp) - movaps %xmm11,0x50(%rsp) - movaps %xmm12,0x60(%rsp) - movaps %xmm13,0x70(%rsp) - movaps %xmm14,0x80(%rsp) - movaps %xmm15,0x90(%rsp) -.Locb_enc_body: -___ -$code.=<<___; - mov $seventh_arg(%rax),$L_p # 7th argument - mov $seventh_arg+8(%rax),$checksum_p# 8th argument - - mov 240($key),$rnds_ - mov $key,$key_ - shl \$4,$rnds_ - $movkey ($key),$rndkey0l # round[0] - $movkey 16($key,$rnds_),$rndkey1 # round[last] - - movdqu ($offset_p),@offset[5] # load last offset_i - pxor $rndkey1,$rndkey0l # round[0] ^ round[last] - pxor $rndkey1,@offset[5] # offset_i ^ round[last] - - mov \$16+32,$rounds - lea 32($key_,$rnds_),$key - $movkey 16($key_),$rndkey1 # round[1] - sub %r10,%rax # twisted $rounds - mov %rax,%r10 # backup twisted $rounds - - movdqu ($L_p),@offset[0] # L_0 for all odd-numbered blocks - movdqu ($checksum_p),$checksum # load checksum - - test \$1,$block_num # is first block number odd? - jnz .Locb_enc_odd - - bsf $block_num,$i1 - add \$1,$block_num - shl \$4,$i1 - movdqu ($L_p,$i1),$inout5 # borrow - movdqu ($inp),$inout0 - lea 16($inp),$inp - - call __ocb_encrypt1 - - movdqa $inout5,@offset[5] - movups $inout0,($out) - lea 16($out),$out - sub \$1,$blocks - jz .Locb_enc_done - -.Locb_enc_odd: - lea 1($block_num),$i1 # even-numbered blocks - lea 3($block_num),$i3 - lea 5($block_num),$i5 - lea 6($block_num),$block_num - bsf $i1,$i1 # ntz(block) - bsf $i3,$i3 - bsf $i5,$i5 - shl \$4,$i1 # ntz(block) -> table offset - shl \$4,$i3 - shl \$4,$i5 - - sub \$6,$blocks - jc .Locb_enc_short - jmp .Locb_enc_grandloop - -.align 32 -.Locb_enc_grandloop: - movdqu `16*0`($inp),$inout0 # load input - movdqu `16*1`($inp),$inout1 - movdqu `16*2`($inp),$inout2 - movdqu `16*3`($inp),$inout3 - movdqu `16*4`($inp),$inout4 - movdqu `16*5`($inp),$inout5 - lea `16*6`($inp),$inp - - call __ocb_encrypt6 - - movups $inout0,`16*0`($out) # store output - movups $inout1,`16*1`($out) - movups $inout2,`16*2`($out) - movups $inout3,`16*3`($out) - movups $inout4,`16*4`($out) - movups $inout5,`16*5`($out) - lea `16*6`($out),$out - sub \$6,$blocks - jnc .Locb_enc_grandloop - -.Locb_enc_short: - add \$6,$blocks - jz .Locb_enc_done - - movdqu `16*0`($inp),$inout0 - cmp \$2,$blocks - jb .Locb_enc_one - movdqu `16*1`($inp),$inout1 - je .Locb_enc_two - - movdqu `16*2`($inp),$inout2 - cmp \$4,$blocks - jb .Locb_enc_three - movdqu `16*3`($inp),$inout3 - je .Locb_enc_four - - movdqu `16*4`($inp),$inout4 - pxor $inout5,$inout5 - - call __ocb_encrypt6 - - movdqa @offset[4],@offset[5] - movups $inout0,`16*0`($out) - movups $inout1,`16*1`($out) - movups $inout2,`16*2`($out) - movups $inout3,`16*3`($out) - movups $inout4,`16*4`($out) - - jmp .Locb_enc_done - -.align 16 -.Locb_enc_one: - movdqa @offset[0],$inout5 # borrow - - call __ocb_encrypt1 - - movdqa $inout5,@offset[5] - movups $inout0,`16*0`($out) - jmp .Locb_enc_done - -.align 16 -.Locb_enc_two: - pxor $inout2,$inout2 - pxor $inout3,$inout3 - - call __ocb_encrypt4 - - movdqa @offset[1],@offset[5] - movups $inout0,`16*0`($out) - movups $inout1,`16*1`($out) - - jmp .Locb_enc_done - -.align 16 -.Locb_enc_three: - pxor $inout3,$inout3 - - call __ocb_encrypt4 - - movdqa @offset[2],@offset[5] - movups $inout0,`16*0`($out) - movups $inout1,`16*1`($out) - movups $inout2,`16*2`($out) - - jmp .Locb_enc_done - -.align 16 -.Locb_enc_four: - call __ocb_encrypt4 - - movdqa @offset[3],@offset[5] - movups $inout0,`16*0`($out) - movups $inout1,`16*1`($out) - movups $inout2,`16*2`($out) - movups $inout3,`16*3`($out) - -.Locb_enc_done: - pxor $rndkey0,@offset[5] # "remove" round[last] - movdqu $checksum,($checksum_p) # store checksum - movdqu @offset[5],($offset_p) # store last offset_i - - xorps %xmm0,%xmm0 # clear register bank - pxor %xmm1,%xmm1 - pxor %xmm2,%xmm2 - pxor %xmm3,%xmm3 - pxor %xmm4,%xmm4 - pxor %xmm5,%xmm5 -___ -$code.=<<___ if (!$win64); - pxor %xmm6,%xmm6 - pxor %xmm7,%xmm7 - pxor %xmm8,%xmm8 - pxor %xmm9,%xmm9 - pxor %xmm10,%xmm10 - pxor %xmm11,%xmm11 - pxor %xmm12,%xmm12 - pxor %xmm13,%xmm13 - pxor %xmm14,%xmm14 - pxor %xmm15,%xmm15 - lea 0x28(%rsp),%rax -.cfi_def_cfa %rax,8 -___ -$code.=<<___ if ($win64); - movaps 0x00(%rsp),%xmm6 - movaps %xmm0,0x00(%rsp) # clear stack - movaps 0x10(%rsp),%xmm7 - movaps %xmm0,0x10(%rsp) - movaps 0x20(%rsp),%xmm8 - movaps %xmm0,0x20(%rsp) - movaps 0x30(%rsp),%xmm9 - movaps %xmm0,0x30(%rsp) - movaps 0x40(%rsp),%xmm10 - movaps %xmm0,0x40(%rsp) - movaps 0x50(%rsp),%xmm11 - movaps %xmm0,0x50(%rsp) - movaps 0x60(%rsp),%xmm12 - movaps %xmm0,0x60(%rsp) - movaps 0x70(%rsp),%xmm13 - movaps %xmm0,0x70(%rsp) - movaps 0x80(%rsp),%xmm14 - movaps %xmm0,0x80(%rsp) - movaps 0x90(%rsp),%xmm15 - movaps %xmm0,0x90(%rsp) - lea 0xa0+0x28(%rsp),%rax -.Locb_enc_pop: -___ -$code.=<<___; - mov -40(%rax),%r14 -.cfi_restore %r14 - mov -32(%rax),%r13 -.cfi_restore %r13 - mov -24(%rax),%r12 -.cfi_restore %r12 - mov -16(%rax),%rbp -.cfi_restore %rbp - mov -8(%rax),%rbx -.cfi_restore %rbx - lea (%rax),%rsp -.cfi_def_cfa_register %rsp -.Locb_enc_epilogue: - ret -.cfi_endproc -.size ${PREFIX}_ocb_encrypt,.-${PREFIX}_ocb_encrypt - -.type __ocb_encrypt6,\@abi-omnipotent -.align 32 -__ocb_encrypt6: - pxor $rndkey0l,@offset[5] # offset_i ^ round[0] - movdqu ($L_p,$i1),@offset[1] - movdqa @offset[0],@offset[2] - movdqu ($L_p,$i3),@offset[3] - movdqa @offset[0],@offset[4] - pxor @offset[5],@offset[0] - movdqu ($L_p,$i5),@offset[5] - pxor @offset[0],@offset[1] - pxor $inout0,$checksum # accumulate checksum - pxor @offset[0],$inout0 # input ^ round[0] ^ offset_i - pxor @offset[1],@offset[2] - pxor $inout1,$checksum - pxor @offset[1],$inout1 - pxor @offset[2],@offset[3] - pxor $inout2,$checksum - pxor @offset[2],$inout2 - pxor @offset[3],@offset[4] - pxor $inout3,$checksum - pxor @offset[3],$inout3 - pxor @offset[4],@offset[5] - pxor $inout4,$checksum - pxor @offset[4],$inout4 - pxor $inout5,$checksum - pxor @offset[5],$inout5 - $movkey 32($key_),$rndkey0 - - lea 1($block_num),$i1 # even-numbered blocks - lea 3($block_num),$i3 - lea 5($block_num),$i5 - add \$6,$block_num - pxor $rndkey0l,@offset[0] # offset_i ^ round[last] - bsf $i1,$i1 # ntz(block) - bsf $i3,$i3 - bsf $i5,$i5 - - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - pxor $rndkey0l,@offset[1] - pxor $rndkey0l,@offset[2] - aesenc $rndkey1,$inout4 - pxor $rndkey0l,@offset[3] - pxor $rndkey0l,@offset[4] - aesenc $rndkey1,$inout5 - $movkey 48($key_),$rndkey1 - pxor $rndkey0l,@offset[5] - - aesenc $rndkey0,$inout0 - aesenc $rndkey0,$inout1 - aesenc $rndkey0,$inout2 - aesenc $rndkey0,$inout3 - aesenc $rndkey0,$inout4 - aesenc $rndkey0,$inout5 - $movkey 64($key_),$rndkey0 - shl \$4,$i1 # ntz(block) -> table offset - shl \$4,$i3 - jmp .Locb_enc_loop6 - -.align 32 -.Locb_enc_loop6: - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - aesenc $rndkey1,$inout4 - aesenc $rndkey1,$inout5 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesenc $rndkey0,$inout0 - aesenc $rndkey0,$inout1 - aesenc $rndkey0,$inout2 - aesenc $rndkey0,$inout3 - aesenc $rndkey0,$inout4 - aesenc $rndkey0,$inout5 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_enc_loop6 - - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - aesenc $rndkey1,$inout4 - aesenc $rndkey1,$inout5 - $movkey 16($key_),$rndkey1 - shl \$4,$i5 - - aesenclast @offset[0],$inout0 - movdqu ($L_p),@offset[0] # L_0 for all odd-numbered blocks - mov %r10,%rax # restore twisted rounds - aesenclast @offset[1],$inout1 - aesenclast @offset[2],$inout2 - aesenclast @offset[3],$inout3 - aesenclast @offset[4],$inout4 - aesenclast @offset[5],$inout5 - ret -.size __ocb_encrypt6,.-__ocb_encrypt6 - -.type __ocb_encrypt4,\@abi-omnipotent -.align 32 -__ocb_encrypt4: - pxor $rndkey0l,@offset[5] # offset_i ^ round[0] - movdqu ($L_p,$i1),@offset[1] - movdqa @offset[0],@offset[2] - movdqu ($L_p,$i3),@offset[3] - pxor @offset[5],@offset[0] - pxor @offset[0],@offset[1] - pxor $inout0,$checksum # accumulate checksum - pxor @offset[0],$inout0 # input ^ round[0] ^ offset_i - pxor @offset[1],@offset[2] - pxor $inout1,$checksum - pxor @offset[1],$inout1 - pxor @offset[2],@offset[3] - pxor $inout2,$checksum - pxor @offset[2],$inout2 - pxor $inout3,$checksum - pxor @offset[3],$inout3 - $movkey 32($key_),$rndkey0 - - pxor $rndkey0l,@offset[0] # offset_i ^ round[last] - pxor $rndkey0l,@offset[1] - pxor $rndkey0l,@offset[2] - pxor $rndkey0l,@offset[3] - - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - $movkey 48($key_),$rndkey1 - - aesenc $rndkey0,$inout0 - aesenc $rndkey0,$inout1 - aesenc $rndkey0,$inout2 - aesenc $rndkey0,$inout3 - $movkey 64($key_),$rndkey0 - jmp .Locb_enc_loop4 - -.align 32 -.Locb_enc_loop4: - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesenc $rndkey0,$inout0 - aesenc $rndkey0,$inout1 - aesenc $rndkey0,$inout2 - aesenc $rndkey0,$inout3 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_enc_loop4 - - aesenc $rndkey1,$inout0 - aesenc $rndkey1,$inout1 - aesenc $rndkey1,$inout2 - aesenc $rndkey1,$inout3 - $movkey 16($key_),$rndkey1 - mov %r10,%rax # restore twisted rounds - - aesenclast @offset[0],$inout0 - aesenclast @offset[1],$inout1 - aesenclast @offset[2],$inout2 - aesenclast @offset[3],$inout3 - ret -.size __ocb_encrypt4,.-__ocb_encrypt4 - -.type __ocb_encrypt1,\@abi-omnipotent -.align 32 -__ocb_encrypt1: - pxor @offset[5],$inout5 # offset_i - pxor $rndkey0l,$inout5 # offset_i ^ round[0] - pxor $inout0,$checksum # accumulate checksum - pxor $inout5,$inout0 # input ^ round[0] ^ offset_i - $movkey 32($key_),$rndkey0 - - aesenc $rndkey1,$inout0 - $movkey 48($key_),$rndkey1 - pxor $rndkey0l,$inout5 # offset_i ^ round[last] - - aesenc $rndkey0,$inout0 - $movkey 64($key_),$rndkey0 - jmp .Locb_enc_loop1 - -.align 32 -.Locb_enc_loop1: - aesenc $rndkey1,$inout0 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesenc $rndkey0,$inout0 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_enc_loop1 - - aesenc $rndkey1,$inout0 - $movkey 16($key_),$rndkey1 # redundant in tail - mov %r10,%rax # restore twisted rounds - - aesenclast $inout5,$inout0 - ret -.size __ocb_encrypt1,.-__ocb_encrypt1 - -.globl ${PREFIX}_ocb_decrypt -.type ${PREFIX}_ocb_decrypt,\@function,6 -.align 32 -${PREFIX}_ocb_decrypt: -.cfi_startproc - lea (%rsp),%rax - push %rbx -.cfi_push %rbx - push %rbp -.cfi_push %rbp - push %r12 -.cfi_push %r12 - push %r13 -.cfi_push %r13 - push %r14 -.cfi_push %r14 -___ -$code.=<<___ if ($win64); - lea -0xa0(%rsp),%rsp - movaps %xmm6,0x00(%rsp) # offload everything - movaps %xmm7,0x10(%rsp) - movaps %xmm8,0x20(%rsp) - movaps %xmm9,0x30(%rsp) - movaps %xmm10,0x40(%rsp) - movaps %xmm11,0x50(%rsp) - movaps %xmm12,0x60(%rsp) - movaps %xmm13,0x70(%rsp) - movaps %xmm14,0x80(%rsp) - movaps %xmm15,0x90(%rsp) -.Locb_dec_body: -___ -$code.=<<___; - mov $seventh_arg(%rax),$L_p # 7th argument - mov $seventh_arg+8(%rax),$checksum_p# 8th argument - - mov 240($key),$rnds_ - mov $key,$key_ - shl \$4,$rnds_ - $movkey ($key),$rndkey0l # round[0] - $movkey 16($key,$rnds_),$rndkey1 # round[last] - - movdqu ($offset_p),@offset[5] # load last offset_i - pxor $rndkey1,$rndkey0l # round[0] ^ round[last] - pxor $rndkey1,@offset[5] # offset_i ^ round[last] - - mov \$16+32,$rounds - lea 32($key_,$rnds_),$key - $movkey 16($key_),$rndkey1 # round[1] - sub %r10,%rax # twisted $rounds - mov %rax,%r10 # backup twisted $rounds - - movdqu ($L_p),@offset[0] # L_0 for all odd-numbered blocks - movdqu ($checksum_p),$checksum # load checksum - - test \$1,$block_num # is first block number odd? - jnz .Locb_dec_odd - - bsf $block_num,$i1 - add \$1,$block_num - shl \$4,$i1 - movdqu ($L_p,$i1),$inout5 # borrow - movdqu ($inp),$inout0 - lea 16($inp),$inp - - call __ocb_decrypt1 - - movdqa $inout5,@offset[5] - movups $inout0,($out) - xorps $inout0,$checksum # accumulate checksum - lea 16($out),$out - sub \$1,$blocks - jz .Locb_dec_done - -.Locb_dec_odd: - lea 1($block_num),$i1 # even-numbered blocks - lea 3($block_num),$i3 - lea 5($block_num),$i5 - lea 6($block_num),$block_num - bsf $i1,$i1 # ntz(block) - bsf $i3,$i3 - bsf $i5,$i5 - shl \$4,$i1 # ntz(block) -> table offset - shl \$4,$i3 - shl \$4,$i5 - - sub \$6,$blocks - jc .Locb_dec_short - jmp .Locb_dec_grandloop - -.align 32 -.Locb_dec_grandloop: - movdqu `16*0`($inp),$inout0 # load input - movdqu `16*1`($inp),$inout1 - movdqu `16*2`($inp),$inout2 - movdqu `16*3`($inp),$inout3 - movdqu `16*4`($inp),$inout4 - movdqu `16*5`($inp),$inout5 - lea `16*6`($inp),$inp - - call __ocb_decrypt6 - - movups $inout0,`16*0`($out) # store output - pxor $inout0,$checksum # accumulate checksum - movups $inout1,`16*1`($out) - pxor $inout1,$checksum - movups $inout2,`16*2`($out) - pxor $inout2,$checksum - movups $inout3,`16*3`($out) - pxor $inout3,$checksum - movups $inout4,`16*4`($out) - pxor $inout4,$checksum - movups $inout5,`16*5`($out) - pxor $inout5,$checksum - lea `16*6`($out),$out - sub \$6,$blocks - jnc .Locb_dec_grandloop - -.Locb_dec_short: - add \$6,$blocks - jz .Locb_dec_done - - movdqu `16*0`($inp),$inout0 - cmp \$2,$blocks - jb .Locb_dec_one - movdqu `16*1`($inp),$inout1 - je .Locb_dec_two - - movdqu `16*2`($inp),$inout2 - cmp \$4,$blocks - jb .Locb_dec_three - movdqu `16*3`($inp),$inout3 - je .Locb_dec_four - - movdqu `16*4`($inp),$inout4 - pxor $inout5,$inout5 - - call __ocb_decrypt6 - - movdqa @offset[4],@offset[5] - movups $inout0,`16*0`($out) # store output - pxor $inout0,$checksum # accumulate checksum - movups $inout1,`16*1`($out) - pxor $inout1,$checksum - movups $inout2,`16*2`($out) - pxor $inout2,$checksum - movups $inout3,`16*3`($out) - pxor $inout3,$checksum - movups $inout4,`16*4`($out) - pxor $inout4,$checksum - - jmp .Locb_dec_done - -.align 16 -.Locb_dec_one: - movdqa @offset[0],$inout5 # borrow - - call __ocb_decrypt1 - - movdqa $inout5,@offset[5] - movups $inout0,`16*0`($out) # store output - xorps $inout0,$checksum # accumulate checksum - jmp .Locb_dec_done - -.align 16 -.Locb_dec_two: - pxor $inout2,$inout2 - pxor $inout3,$inout3 - - call __ocb_decrypt4 - - movdqa @offset[1],@offset[5] - movups $inout0,`16*0`($out) # store output - xorps $inout0,$checksum # accumulate checksum - movups $inout1,`16*1`($out) - xorps $inout1,$checksum - - jmp .Locb_dec_done - -.align 16 -.Locb_dec_three: - pxor $inout3,$inout3 - - call __ocb_decrypt4 - - movdqa @offset[2],@offset[5] - movups $inout0,`16*0`($out) # store output - xorps $inout0,$checksum # accumulate checksum - movups $inout1,`16*1`($out) - xorps $inout1,$checksum - movups $inout2,`16*2`($out) - xorps $inout2,$checksum - - jmp .Locb_dec_done - -.align 16 -.Locb_dec_four: - call __ocb_decrypt4 - - movdqa @offset[3],@offset[5] - movups $inout0,`16*0`($out) # store output - pxor $inout0,$checksum # accumulate checksum - movups $inout1,`16*1`($out) - pxor $inout1,$checksum - movups $inout2,`16*2`($out) - pxor $inout2,$checksum - movups $inout3,`16*3`($out) - pxor $inout3,$checksum - -.Locb_dec_done: - pxor $rndkey0,@offset[5] # "remove" round[last] - movdqu $checksum,($checksum_p) # store checksum - movdqu @offset[5],($offset_p) # store last offset_i - - xorps %xmm0,%xmm0 # clear register bank - pxor %xmm1,%xmm1 - pxor %xmm2,%xmm2 - pxor %xmm3,%xmm3 - pxor %xmm4,%xmm4 - pxor %xmm5,%xmm5 -___ -$code.=<<___ if (!$win64); - pxor %xmm6,%xmm6 - pxor %xmm7,%xmm7 - pxor %xmm8,%xmm8 - pxor %xmm9,%xmm9 - pxor %xmm10,%xmm10 - pxor %xmm11,%xmm11 - pxor %xmm12,%xmm12 - pxor %xmm13,%xmm13 - pxor %xmm14,%xmm14 - pxor %xmm15,%xmm15 - lea 0x28(%rsp),%rax -.cfi_def_cfa %rax,8 -___ -$code.=<<___ if ($win64); - movaps 0x00(%rsp),%xmm6 - movaps %xmm0,0x00(%rsp) # clear stack - movaps 0x10(%rsp),%xmm7 - movaps %xmm0,0x10(%rsp) - movaps 0x20(%rsp),%xmm8 - movaps %xmm0,0x20(%rsp) - movaps 0x30(%rsp),%xmm9 - movaps %xmm0,0x30(%rsp) - movaps 0x40(%rsp),%xmm10 - movaps %xmm0,0x40(%rsp) - movaps 0x50(%rsp),%xmm11 - movaps %xmm0,0x50(%rsp) - movaps 0x60(%rsp),%xmm12 - movaps %xmm0,0x60(%rsp) - movaps 0x70(%rsp),%xmm13 - movaps %xmm0,0x70(%rsp) - movaps 0x80(%rsp),%xmm14 - movaps %xmm0,0x80(%rsp) - movaps 0x90(%rsp),%xmm15 - movaps %xmm0,0x90(%rsp) - lea 0xa0+0x28(%rsp),%rax -.Locb_dec_pop: -___ -$code.=<<___; - mov -40(%rax),%r14 -.cfi_restore %r14 - mov -32(%rax),%r13 -.cfi_restore %r13 - mov -24(%rax),%r12 -.cfi_restore %r12 - mov -16(%rax),%rbp -.cfi_restore %rbp - mov -8(%rax),%rbx -.cfi_restore %rbx - lea (%rax),%rsp -.cfi_def_cfa_register %rsp -.Locb_dec_epilogue: - ret -.cfi_endproc -.size ${PREFIX}_ocb_decrypt,.-${PREFIX}_ocb_decrypt - -.type __ocb_decrypt6,\@abi-omnipotent -.align 32 -__ocb_decrypt6: - pxor $rndkey0l,@offset[5] # offset_i ^ round[0] - movdqu ($L_p,$i1),@offset[1] - movdqa @offset[0],@offset[2] - movdqu ($L_p,$i3),@offset[3] - movdqa @offset[0],@offset[4] - pxor @offset[5],@offset[0] - movdqu ($L_p,$i5),@offset[5] - pxor @offset[0],@offset[1] - pxor @offset[0],$inout0 # input ^ round[0] ^ offset_i - pxor @offset[1],@offset[2] - pxor @offset[1],$inout1 - pxor @offset[2],@offset[3] - pxor @offset[2],$inout2 - pxor @offset[3],@offset[4] - pxor @offset[3],$inout3 - pxor @offset[4],@offset[5] - pxor @offset[4],$inout4 - pxor @offset[5],$inout5 - $movkey 32($key_),$rndkey0 - - lea 1($block_num),$i1 # even-numbered blocks - lea 3($block_num),$i3 - lea 5($block_num),$i5 - add \$6,$block_num - pxor $rndkey0l,@offset[0] # offset_i ^ round[last] - bsf $i1,$i1 # ntz(block) - bsf $i3,$i3 - bsf $i5,$i5 - - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - pxor $rndkey0l,@offset[1] - pxor $rndkey0l,@offset[2] - aesdec $rndkey1,$inout4 - pxor $rndkey0l,@offset[3] - pxor $rndkey0l,@offset[4] - aesdec $rndkey1,$inout5 - $movkey 48($key_),$rndkey1 - pxor $rndkey0l,@offset[5] - - aesdec $rndkey0,$inout0 - aesdec $rndkey0,$inout1 - aesdec $rndkey0,$inout2 - aesdec $rndkey0,$inout3 - aesdec $rndkey0,$inout4 - aesdec $rndkey0,$inout5 - $movkey 64($key_),$rndkey0 - shl \$4,$i1 # ntz(block) -> table offset - shl \$4,$i3 - jmp .Locb_dec_loop6 - -.align 32 -.Locb_dec_loop6: - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - aesdec $rndkey1,$inout4 - aesdec $rndkey1,$inout5 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesdec $rndkey0,$inout0 - aesdec $rndkey0,$inout1 - aesdec $rndkey0,$inout2 - aesdec $rndkey0,$inout3 - aesdec $rndkey0,$inout4 - aesdec $rndkey0,$inout5 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_dec_loop6 - - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - aesdec $rndkey1,$inout4 - aesdec $rndkey1,$inout5 - $movkey 16($key_),$rndkey1 - shl \$4,$i5 - - aesdeclast @offset[0],$inout0 - movdqu ($L_p),@offset[0] # L_0 for all odd-numbered blocks - mov %r10,%rax # restore twisted rounds - aesdeclast @offset[1],$inout1 - aesdeclast @offset[2],$inout2 - aesdeclast @offset[3],$inout3 - aesdeclast @offset[4],$inout4 - aesdeclast @offset[5],$inout5 - ret -.size __ocb_decrypt6,.-__ocb_decrypt6 - -.type __ocb_decrypt4,\@abi-omnipotent -.align 32 -__ocb_decrypt4: - pxor $rndkey0l,@offset[5] # offset_i ^ round[0] - movdqu ($L_p,$i1),@offset[1] - movdqa @offset[0],@offset[2] - movdqu ($L_p,$i3),@offset[3] - pxor @offset[5],@offset[0] - pxor @offset[0],@offset[1] - pxor @offset[0],$inout0 # input ^ round[0] ^ offset_i - pxor @offset[1],@offset[2] - pxor @offset[1],$inout1 - pxor @offset[2],@offset[3] - pxor @offset[2],$inout2 - pxor @offset[3],$inout3 - $movkey 32($key_),$rndkey0 - - pxor $rndkey0l,@offset[0] # offset_i ^ round[last] - pxor $rndkey0l,@offset[1] - pxor $rndkey0l,@offset[2] - pxor $rndkey0l,@offset[3] - - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - $movkey 48($key_),$rndkey1 - - aesdec $rndkey0,$inout0 - aesdec $rndkey0,$inout1 - aesdec $rndkey0,$inout2 - aesdec $rndkey0,$inout3 - $movkey 64($key_),$rndkey0 - jmp .Locb_dec_loop4 - -.align 32 -.Locb_dec_loop4: - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesdec $rndkey0,$inout0 - aesdec $rndkey0,$inout1 - aesdec $rndkey0,$inout2 - aesdec $rndkey0,$inout3 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_dec_loop4 - - aesdec $rndkey1,$inout0 - aesdec $rndkey1,$inout1 - aesdec $rndkey1,$inout2 - aesdec $rndkey1,$inout3 - $movkey 16($key_),$rndkey1 - mov %r10,%rax # restore twisted rounds - - aesdeclast @offset[0],$inout0 - aesdeclast @offset[1],$inout1 - aesdeclast @offset[2],$inout2 - aesdeclast @offset[3],$inout3 - ret -.size __ocb_decrypt4,.-__ocb_decrypt4 - -.type __ocb_decrypt1,\@abi-omnipotent -.align 32 -__ocb_decrypt1: - pxor @offset[5],$inout5 # offset_i - pxor $rndkey0l,$inout5 # offset_i ^ round[0] - pxor $inout5,$inout0 # input ^ round[0] ^ offset_i - $movkey 32($key_),$rndkey0 - - aesdec $rndkey1,$inout0 - $movkey 48($key_),$rndkey1 - pxor $rndkey0l,$inout5 # offset_i ^ round[last] - - aesdec $rndkey0,$inout0 - $movkey 64($key_),$rndkey0 - jmp .Locb_dec_loop1 - -.align 32 -.Locb_dec_loop1: - aesdec $rndkey1,$inout0 - $movkey ($key,%rax),$rndkey1 - add \$32,%rax - - aesdec $rndkey0,$inout0 - $movkey -16($key,%rax),$rndkey0 - jnz .Locb_dec_loop1 - - aesdec $rndkey1,$inout0 - $movkey 16($key_),$rndkey1 # redundant in tail - mov %r10,%rax # restore twisted rounds - - aesdeclast $inout5,$inout0 - ret -.size __ocb_decrypt1,.-__ocb_decrypt1 -___ } }} ######################################################################## @@ -4727,6 +3780,7 @@ ___ } $code.=<<___; +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -4749,6 +3803,7 @@ $code.=<<___; .asciz "AES for Intel AES-NI, CRYPTOGAMS by " .align 64 +.text ___ # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesp8-ppc.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesp8-ppc.pl deleted file mode 100644 index 983cbbe6..00000000 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesp8-ppc.pl +++ /dev/null @@ -1,3807 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the OpenSSL license (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# This module implements support for AES instructions as per PowerISA -# specification version 2.07, first implemented by POWER8 processor. -# The module is endian-agnostic in sense that it supports both big- -# and little-endian cases. Data alignment in parallelizable modes is -# handled with VSX loads and stores, which implies MSR.VSX flag being -# set. It should also be noted that ISA specification doesn't prohibit -# alignment exceptions for these instructions on page boundaries. -# Initially alignment was handled in pure AltiVec/VMX way [when data -# is aligned programmatically, which in turn guarantees exception- -# free execution], but it turned to hamper performance when vcipher -# instructions are interleaved. It's reckoned that eventual -# misalignment penalties at page boundaries are in average lower -# than additional overhead in pure AltiVec approach. -# -# May 2016 -# -# Add XTS subroutine, 9x on little- and 12x improvement on big-endian -# systems were measured. -# -###################################################################### -# Current large-block performance in cycles per byte processed with -# 128-bit key (less is better). -# -# CBC en-/decrypt CTR XTS -# POWER8[le] 3.96/0.72 0.74 1.1 -# POWER8[be] 3.75/0.65 0.66 1.0 -# POWER9[le] 4.02/0.86 0.84 1.05 -# POWER9[be] 3.99/0.78 0.79 0.97 - -$flavour = shift; - -if ($flavour =~ /64/) { - $SIZE_T =8; - $LRSAVE =2*$SIZE_T; - $STU ="stdu"; - $POP ="ld"; - $PUSH ="std"; - $UCMP ="cmpld"; - $SHL ="sldi"; -} elsif ($flavour =~ /32/) { - $SIZE_T =4; - $LRSAVE =$SIZE_T; - $STU ="stwu"; - $POP ="lwz"; - $PUSH ="stw"; - $UCMP ="cmplw"; - $SHL ="slwi"; -} else { die "nonsense $flavour"; } - -$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../../perlasm/ppc-xlate.pl" and -f $xlate) or -die "can't locate ppc-xlate.pl"; - -open STDOUT,"| $^X \"$xlate\" $flavour ".shift || die "can't call $xlate: $!"; - -$FRAME=8*$SIZE_T; -$prefix="aes_hw"; - -$sp="r1"; -$vrsave="r12"; - -######################################################################### -{{{ # Key setup procedures # -my ($inp,$bits,$out,$ptr,$cnt,$rounds)=map("r$_",(3..8)); -my ($zero,$in0,$in1,$key,$rcon,$mask,$tmp)=map("v$_",(0..6)); -my ($stage,$outperm,$outmask,$outhead,$outtail)=map("v$_",(7..11)); - -$code.=<<___; -.machine "any" - -.text - -.align 7 -Lrcon: -.long 0x01000000, 0x01000000, 0x01000000, 0x01000000 ?rev -.long 0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000 ?rev -.long 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c ?rev -.long 0,0,0,0 ?asis -Lconsts: - mflr r0 - bcl 20,31,\$+4 - mflr $ptr #vvvvv "distance between . and rcon - addi $ptr,$ptr,-0x48 - mtlr r0 - blr - .long 0 - .byte 0,12,0x14,0,0,0,0,0 -.asciz "AES for PowerISA 2.07, CRYPTOGAMS by " - -.globl .${prefix}_set_encrypt_key -.align 5 -.${prefix}_set_encrypt_key: -Lset_encrypt_key: - mflr r11 - $PUSH r11,$LRSAVE($sp) - - li $ptr,-1 - ${UCMP}i $inp,0 - beq- Lenc_key_abort # if ($inp==0) return -1; - ${UCMP}i $out,0 - beq- Lenc_key_abort # if ($out==0) return -1; - li $ptr,-2 - cmpwi $bits,128 - blt- Lenc_key_abort - cmpwi $bits,256 - bgt- Lenc_key_abort - andi. r0,$bits,0x3f - bne- Lenc_key_abort - - lis r0,0xfff0 - mfspr $vrsave,256 - mtspr 256,r0 - - bl Lconsts - mtlr r11 - - neg r9,$inp - lvx $in0,0,$inp - addi $inp,$inp,15 # 15 is not typo - lvsr $key,0,r9 # borrow $key - li r8,0x20 - cmpwi $bits,192 - lvx $in1,0,$inp - le?vspltisb $mask,0x0f # borrow $mask - lvx $rcon,0,$ptr - le?vxor $key,$key,$mask # adjust for byte swap - lvx $mask,r8,$ptr - addi $ptr,$ptr,0x10 - vperm $in0,$in0,$in1,$key # align [and byte swap in LE] - li $cnt,8 - vxor $zero,$zero,$zero - mtctr $cnt - - ?lvsr $outperm,0,$out - vspltisb $outmask,-1 - lvx $outhead,0,$out - ?vperm $outmask,$zero,$outmask,$outperm - - blt Loop128 - addi $inp,$inp,8 - beq L192 - addi $inp,$inp,8 - b L256 - -.align 4 -Loop128: - vperm $key,$in0,$in0,$mask # rotate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vcipherlast $key,$key,$rcon - stvx $stage,0,$out - addi $out,$out,16 - - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vadduwm $rcon,$rcon,$rcon - vxor $in0,$in0,$key - bdnz Loop128 - - lvx $rcon,0,$ptr # last two round keys - - vperm $key,$in0,$in0,$mask # rotate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vcipherlast $key,$key,$rcon - stvx $stage,0,$out - addi $out,$out,16 - - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vadduwm $rcon,$rcon,$rcon - vxor $in0,$in0,$key - - vperm $key,$in0,$in0,$mask # rotate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vcipherlast $key,$key,$rcon - stvx $stage,0,$out - addi $out,$out,16 - - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vxor $in0,$in0,$key - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - stvx $stage,0,$out - - addi $inp,$out,15 # 15 is not typo - addi $out,$out,0x50 - - li $rounds,10 - b Ldone - -.align 4 -L192: - lvx $tmp,0,$inp - li $cnt,4 - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - stvx $stage,0,$out - addi $out,$out,16 - vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] - vspltisb $key,8 # borrow $key - mtctr $cnt - vsububm $mask,$mask,$key # adjust the mask - -Loop192: - vperm $key,$in1,$in1,$mask # roate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vcipherlast $key,$key,$rcon - - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - - vsldoi $stage,$zero,$in1,8 - vspltw $tmp,$in0,3 - vxor $tmp,$tmp,$in1 - vsldoi $in1,$zero,$in1,12 # >>32 - vadduwm $rcon,$rcon,$rcon - vxor $in1,$in1,$tmp - vxor $in0,$in0,$key - vxor $in1,$in1,$key - vsldoi $stage,$stage,$in0,8 - - vperm $key,$in1,$in1,$mask # rotate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vperm $outtail,$stage,$stage,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vcipherlast $key,$key,$rcon - stvx $stage,0,$out - addi $out,$out,16 - - vsldoi $stage,$in0,$in1,8 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vperm $outtail,$stage,$stage,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - stvx $stage,0,$out - addi $out,$out,16 - - vspltw $tmp,$in0,3 - vxor $tmp,$tmp,$in1 - vsldoi $in1,$zero,$in1,12 # >>32 - vadduwm $rcon,$rcon,$rcon - vxor $in1,$in1,$tmp - vxor $in0,$in0,$key - vxor $in1,$in1,$key - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - stvx $stage,0,$out - addi $inp,$out,15 # 15 is not typo - addi $out,$out,16 - bdnz Loop192 - - li $rounds,12 - addi $out,$out,0x20 - b Ldone - -.align 4 -L256: - lvx $tmp,0,$inp - li $cnt,7 - li $rounds,14 - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - stvx $stage,0,$out - addi $out,$out,16 - vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] - mtctr $cnt - -Loop256: - vperm $key,$in1,$in1,$mask # rotate-n-splat - vsldoi $tmp,$zero,$in0,12 # >>32 - vperm $outtail,$in1,$in1,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - vcipherlast $key,$key,$rcon - stvx $stage,0,$out - addi $out,$out,16 - - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in0,$in0,$tmp - vadduwm $rcon,$rcon,$rcon - vxor $in0,$in0,$key - vperm $outtail,$in0,$in0,$outperm # rotate - vsel $stage,$outhead,$outtail,$outmask - vmr $outhead,$outtail - stvx $stage,0,$out - addi $inp,$out,15 # 15 is not typo - addi $out,$out,16 - bdz Ldone - - vspltw $key,$in0,3 # just splat - vsldoi $tmp,$zero,$in1,12 # >>32 - vsbox $key,$key - - vxor $in1,$in1,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in1,$in1,$tmp - vsldoi $tmp,$zero,$tmp,12 # >>32 - vxor $in1,$in1,$tmp - - vxor $in1,$in1,$key - b Loop256 - -.align 4 -Ldone: - lvx $in1,0,$inp # redundant in aligned case - vsel $in1,$outhead,$in1,$outmask - stvx $in1,0,$inp - li $ptr,0 - mtspr 256,$vrsave - stw $rounds,0($out) - -Lenc_key_abort: - mr r3,$ptr - blr - .long 0 - .byte 0,12,0x14,1,0,0,3,0 - .long 0 -.size .${prefix}_set_encrypt_key,.-.${prefix}_set_encrypt_key - -.globl .${prefix}_set_decrypt_key -.align 5 -.${prefix}_set_decrypt_key: - $STU $sp,-$FRAME($sp) - mflr r10 - $PUSH r10,`$FRAME+$LRSAVE`($sp) - bl Lset_encrypt_key - mtlr r10 - - cmpwi r3,0 - bne- Ldec_key_abort - - slwi $cnt,$rounds,4 - subi $inp,$out,240 # first round key - srwi $rounds,$rounds,1 - add $out,$inp,$cnt # last round key - mtctr $rounds - -Ldeckey: - lwz r0, 0($inp) - lwz r6, 4($inp) - lwz r7, 8($inp) - lwz r8, 12($inp) - addi $inp,$inp,16 - lwz r9, 0($out) - lwz r10,4($out) - lwz r11,8($out) - lwz r12,12($out) - stw r0, 0($out) - stw r6, 4($out) - stw r7, 8($out) - stw r8, 12($out) - subi $out,$out,16 - stw r9, -16($inp) - stw r10,-12($inp) - stw r11,-8($inp) - stw r12,-4($inp) - bdnz Ldeckey - - xor r3,r3,r3 # return value -Ldec_key_abort: - addi $sp,$sp,$FRAME - blr - .long 0 - .byte 0,12,4,1,0x80,0,3,0 - .long 0 -.size .${prefix}_set_decrypt_key,.-.${prefix}_set_decrypt_key -___ -}}} -######################################################################### -{{{ # Single block en- and decrypt procedures # -sub gen_block () { -my $dir = shift; -my $n = $dir eq "de" ? "n" : ""; -my ($inp,$out,$key,$rounds,$idx)=map("r$_",(3..7)); - -$code.=<<___; -.globl .${prefix}_${dir}crypt -.align 5 -.${prefix}_${dir}crypt: - lwz $rounds,240($key) - lis r0,0xfc00 - mfspr $vrsave,256 - li $idx,15 # 15 is not typo - mtspr 256,r0 - - lvx v0,0,$inp - neg r11,$out - lvx v1,$idx,$inp - lvsl v2,0,$inp # inpperm - le?vspltisb v4,0x0f - ?lvsl v3,0,r11 # outperm - le?vxor v2,v2,v4 - li $idx,16 - vperm v0,v0,v1,v2 # align [and byte swap in LE] - lvx v1,0,$key - ?lvsl v5,0,$key # keyperm - srwi $rounds,$rounds,1 - lvx v2,$idx,$key - addi $idx,$idx,16 - subi $rounds,$rounds,1 - ?vperm v1,v1,v2,v5 # align round key - - vxor v0,v0,v1 - lvx v1,$idx,$key - addi $idx,$idx,16 - mtctr $rounds - -Loop_${dir}c: - ?vperm v2,v2,v1,v5 - v${n}cipher v0,v0,v2 - lvx v2,$idx,$key - addi $idx,$idx,16 - ?vperm v1,v1,v2,v5 - v${n}cipher v0,v0,v1 - lvx v1,$idx,$key - addi $idx,$idx,16 - bdnz Loop_${dir}c - - ?vperm v2,v2,v1,v5 - v${n}cipher v0,v0,v2 - lvx v2,$idx,$key - ?vperm v1,v1,v2,v5 - v${n}cipherlast v0,v0,v1 - - vspltisb v2,-1 - vxor v1,v1,v1 - li $idx,15 # 15 is not typo - ?vperm v2,v1,v2,v3 # outmask - le?vxor v3,v3,v4 - lvx v1,0,$out # outhead - vperm v0,v0,v0,v3 # rotate [and byte swap in LE] - vsel v1,v1,v0,v2 - lvx v4,$idx,$out - stvx v1,0,$out - vsel v0,v0,v4,v2 - stvx v0,$idx,$out - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,3,0 - .long 0 -.size .${prefix}_${dir}crypt,.-.${prefix}_${dir}crypt -___ -} -&gen_block("en"); -&gen_block("de"); -}}} -######################################################################### -{{{ # CBC en- and decrypt procedures # -my ($inp,$out,$len,$key,$ivp,$enc,$rounds,$idx)=map("r$_",(3..10)); -my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); -my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)= - map("v$_",(4..10)); -$code.=<<___; -.globl .${prefix}_cbc_encrypt -.align 5 -.${prefix}_cbc_encrypt: - ${UCMP}i $len,16 - bltlr- - - cmpwi $enc,0 # test direction - lis r0,0xffe0 - mfspr $vrsave,256 - mtspr 256,r0 - - li $idx,15 - vxor $rndkey0,$rndkey0,$rndkey0 - le?vspltisb $tmp,0x0f - - lvx $ivec,0,$ivp # load [unaligned] iv - lvsl $inpperm,0,$ivp - lvx $inptail,$idx,$ivp - le?vxor $inpperm,$inpperm,$tmp - vperm $ivec,$ivec,$inptail,$inpperm - - neg r11,$inp - ?lvsl $keyperm,0,$key # prepare for unaligned key - lwz $rounds,240($key) - - lvsr $inpperm,0,r11 # prepare for unaligned load - lvx $inptail,0,$inp - addi $inp,$inp,15 # 15 is not typo - le?vxor $inpperm,$inpperm,$tmp - - ?lvsr $outperm,0,$out # prepare for unaligned store - vspltisb $outmask,-1 - lvx $outhead,0,$out - ?vperm $outmask,$rndkey0,$outmask,$outperm - le?vxor $outperm,$outperm,$tmp - - srwi $rounds,$rounds,1 - li $idx,16 - subi $rounds,$rounds,1 - beq Lcbc_dec - -Lcbc_enc: - vmr $inout,$inptail - lvx $inptail,0,$inp - addi $inp,$inp,16 - mtctr $rounds - subi $len,$len,16 # len-=16 - - lvx $rndkey0,0,$key - vperm $inout,$inout,$inptail,$inpperm - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - vxor $inout,$inout,$ivec - -Loop_cbc_enc: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - bdnz Loop_cbc_enc - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - li $idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipherlast $ivec,$inout,$rndkey0 - ${UCMP}i $len,16 - - vperm $tmp,$ivec,$ivec,$outperm - vsel $inout,$outhead,$tmp,$outmask - vmr $outhead,$tmp - stvx $inout,0,$out - addi $out,$out,16 - bge Lcbc_enc - - b Lcbc_done - -.align 4 -Lcbc_dec: - ${UCMP}i $len,128 - bge _aesp8_cbc_decrypt8x - vmr $tmp,$inptail - lvx $inptail,0,$inp - addi $inp,$inp,16 - mtctr $rounds - subi $len,$len,16 # len-=16 - - lvx $rndkey0,0,$key - vperm $tmp,$tmp,$inptail,$inpperm - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$tmp,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - -Loop_cbc_dec: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vncipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - bdnz Loop_cbc_dec - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - li $idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vncipherlast $inout,$inout,$rndkey0 - ${UCMP}i $len,16 - - vxor $inout,$inout,$ivec - vmr $ivec,$tmp - vperm $tmp,$inout,$inout,$outperm - vsel $inout,$outhead,$tmp,$outmask - vmr $outhead,$tmp - stvx $inout,0,$out - addi $out,$out,16 - bge Lcbc_dec - -Lcbc_done: - addi $out,$out,-1 - lvx $inout,0,$out # redundant in aligned case - vsel $inout,$outhead,$inout,$outmask - stvx $inout,0,$out - - neg $enc,$ivp # write [unaligned] iv - li $idx,15 # 15 is not typo - vxor $rndkey0,$rndkey0,$rndkey0 - vspltisb $outmask,-1 - le?vspltisb $tmp,0x0f - ?lvsl $outperm,0,$enc - ?vperm $outmask,$rndkey0,$outmask,$outperm - le?vxor $outperm,$outperm,$tmp - lvx $outhead,0,$ivp - vperm $ivec,$ivec,$ivec,$outperm - vsel $inout,$outhead,$ivec,$outmask - lvx $inptail,$idx,$ivp - stvx $inout,0,$ivp - vsel $inout,$ivec,$inptail,$outmask - stvx $inout,$idx,$ivp - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,6,0 - .long 0 -___ -######################################################################### -{{ # Optimized CBC decrypt procedure # -my $key_="r11"; -my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); - $x00=0 if ($flavour =~ /osx/); -my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10..13)); -my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(14..21)); -my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys - # v26-v31 last 6 round keys -my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment - -$code.=<<___; -.align 5 -_aesp8_cbc_decrypt8x: - $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) - li r10,`$FRAME+8*16+15` - li r11,`$FRAME+8*16+31` - stvx v20,r10,$sp # ABI says so - addi r10,r10,32 - stvx v21,r11,$sp - addi r11,r11,32 - stvx v22,r10,$sp - addi r10,r10,32 - stvx v23,r11,$sp - addi r11,r11,32 - stvx v24,r10,$sp - addi r10,r10,32 - stvx v25,r11,$sp - addi r11,r11,32 - stvx v26,r10,$sp - addi r10,r10,32 - stvx v27,r11,$sp - addi r11,r11,32 - stvx v28,r10,$sp - addi r10,r10,32 - stvx v29,r11,$sp - addi r11,r11,32 - stvx v30,r10,$sp - stvx v31,r11,$sp - li r0,-1 - stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave - li $x10,0x10 - $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) - li $x20,0x20 - $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) - li $x30,0x30 - $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) - li $x40,0x40 - $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) - li $x50,0x50 - $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) - li $x60,0x60 - $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) - li $x70,0x70 - mtspr 256,r0 - - subi $rounds,$rounds,3 # -4 in total - subi $len,$len,128 # bias - - lvx $rndkey0,$x00,$key # load key schedule - lvx v30,$x10,$key - addi $key,$key,0x20 - lvx v31,$x00,$key - ?vperm $rndkey0,$rndkey0,v30,$keyperm - addi $key_,$sp,`$FRAME+15` - mtctr $rounds - -Load_cbc_dec_key: - ?vperm v24,v30,v31,$keyperm - lvx v30,$x10,$key - addi $key,$key,0x20 - stvx v24,$x00,$key_ # off-load round[1] - ?vperm v25,v31,v30,$keyperm - lvx v31,$x00,$key - stvx v25,$x10,$key_ # off-load round[2] - addi $key_,$key_,0x20 - bdnz Load_cbc_dec_key - - lvx v26,$x10,$key - ?vperm v24,v30,v31,$keyperm - lvx v27,$x20,$key - stvx v24,$x00,$key_ # off-load round[3] - ?vperm v25,v31,v26,$keyperm - lvx v28,$x30,$key - stvx v25,$x10,$key_ # off-load round[4] - addi $key_,$sp,`$FRAME+15` # rewind $key_ - ?vperm v26,v26,v27,$keyperm - lvx v29,$x40,$key - ?vperm v27,v27,v28,$keyperm - lvx v30,$x50,$key - ?vperm v28,v28,v29,$keyperm - lvx v31,$x60,$key - ?vperm v29,v29,v30,$keyperm - lvx $out0,$x70,$key # borrow $out0 - ?vperm v30,v30,v31,$keyperm - lvx v24,$x00,$key_ # pre-load round[1] - ?vperm v31,v31,$out0,$keyperm - lvx v25,$x10,$key_ # pre-load round[2] - - #lvx $inptail,0,$inp # "caller" already did this - #addi $inp,$inp,15 # 15 is not typo - subi $inp,$inp,15 # undo "caller" - - le?li $idx,8 - lvx_u $in0,$x00,$inp # load first 8 "words" - le?lvsl $inpperm,0,$idx - le?vspltisb $tmp,0x0f - lvx_u $in1,$x10,$inp - le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u - lvx_u $in2,$x20,$inp - le?vperm $in0,$in0,$in0,$inpperm - lvx_u $in3,$x30,$inp - le?vperm $in1,$in1,$in1,$inpperm - lvx_u $in4,$x40,$inp - le?vperm $in2,$in2,$in2,$inpperm - vxor $out0,$in0,$rndkey0 - lvx_u $in5,$x50,$inp - le?vperm $in3,$in3,$in3,$inpperm - vxor $out1,$in1,$rndkey0 - lvx_u $in6,$x60,$inp - le?vperm $in4,$in4,$in4,$inpperm - vxor $out2,$in2,$rndkey0 - lvx_u $in7,$x70,$inp - addi $inp,$inp,0x80 - le?vperm $in5,$in5,$in5,$inpperm - vxor $out3,$in3,$rndkey0 - le?vperm $in6,$in6,$in6,$inpperm - vxor $out4,$in4,$rndkey0 - le?vperm $in7,$in7,$in7,$inpperm - vxor $out5,$in5,$rndkey0 - vxor $out6,$in6,$rndkey0 - vxor $out7,$in7,$rndkey0 - - mtctr $rounds - b Loop_cbc_dec8x -.align 5 -Loop_cbc_dec8x: - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - vncipher $out6,$out6,v24 - vncipher $out7,$out7,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - vncipher $out6,$out6,v25 - vncipher $out7,$out7,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_cbc_dec8x - - subic $len,$len,128 # $len-=128 - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - vncipher $out6,$out6,v24 - vncipher $out7,$out7,v24 - - subfe. r0,r0,r0 # borrow?-1:0 - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - vncipher $out6,$out6,v25 - vncipher $out7,$out7,v25 - - and r0,r0,$len - vncipher $out0,$out0,v26 - vncipher $out1,$out1,v26 - vncipher $out2,$out2,v26 - vncipher $out3,$out3,v26 - vncipher $out4,$out4,v26 - vncipher $out5,$out5,v26 - vncipher $out6,$out6,v26 - vncipher $out7,$out7,v26 - - add $inp,$inp,r0 # $inp is adjusted in such - # way that at exit from the - # loop inX-in7 are loaded - # with last "words" - vncipher $out0,$out0,v27 - vncipher $out1,$out1,v27 - vncipher $out2,$out2,v27 - vncipher $out3,$out3,v27 - vncipher $out4,$out4,v27 - vncipher $out5,$out5,v27 - vncipher $out6,$out6,v27 - vncipher $out7,$out7,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vncipher $out0,$out0,v28 - vncipher $out1,$out1,v28 - vncipher $out2,$out2,v28 - vncipher $out3,$out3,v28 - vncipher $out4,$out4,v28 - vncipher $out5,$out5,v28 - vncipher $out6,$out6,v28 - vncipher $out7,$out7,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - - vncipher $out0,$out0,v29 - vncipher $out1,$out1,v29 - vncipher $out2,$out2,v29 - vncipher $out3,$out3,v29 - vncipher $out4,$out4,v29 - vncipher $out5,$out5,v29 - vncipher $out6,$out6,v29 - vncipher $out7,$out7,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - - vncipher $out0,$out0,v30 - vxor $ivec,$ivec,v31 # xor with last round key - vncipher $out1,$out1,v30 - vxor $in0,$in0,v31 - vncipher $out2,$out2,v30 - vxor $in1,$in1,v31 - vncipher $out3,$out3,v30 - vxor $in2,$in2,v31 - vncipher $out4,$out4,v30 - vxor $in3,$in3,v31 - vncipher $out5,$out5,v30 - vxor $in4,$in4,v31 - vncipher $out6,$out6,v30 - vxor $in5,$in5,v31 - vncipher $out7,$out7,v30 - vxor $in6,$in6,v31 - - vncipherlast $out0,$out0,$ivec - vncipherlast $out1,$out1,$in0 - lvx_u $in0,$x00,$inp # load next input block - vncipherlast $out2,$out2,$in1 - lvx_u $in1,$x10,$inp - vncipherlast $out3,$out3,$in2 - le?vperm $in0,$in0,$in0,$inpperm - lvx_u $in2,$x20,$inp - vncipherlast $out4,$out4,$in3 - le?vperm $in1,$in1,$in1,$inpperm - lvx_u $in3,$x30,$inp - vncipherlast $out5,$out5,$in4 - le?vperm $in2,$in2,$in2,$inpperm - lvx_u $in4,$x40,$inp - vncipherlast $out6,$out6,$in5 - le?vperm $in3,$in3,$in3,$inpperm - lvx_u $in5,$x50,$inp - vncipherlast $out7,$out7,$in6 - le?vperm $in4,$in4,$in4,$inpperm - lvx_u $in6,$x60,$inp - vmr $ivec,$in7 - le?vperm $in5,$in5,$in5,$inpperm - lvx_u $in7,$x70,$inp - addi $inp,$inp,0x80 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $in6,$in6,$in6,$inpperm - vxor $out0,$in0,$rndkey0 - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $in7,$in7,$in7,$inpperm - vxor $out1,$in1,$rndkey0 - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - vxor $out2,$in2,$rndkey0 - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x30,$out - vxor $out3,$in3,$rndkey0 - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x40,$out - vxor $out4,$in4,$rndkey0 - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x50,$out - vxor $out5,$in5,$rndkey0 - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x60,$out - vxor $out6,$in6,$rndkey0 - stvx_u $out7,$x70,$out - addi $out,$out,0x80 - vxor $out7,$in7,$rndkey0 - - mtctr $rounds - beq Loop_cbc_dec8x # did $len-=128 borrow? - - addic. $len,$len,128 - beq Lcbc_dec8x_done - nop - nop - -Loop_cbc_dec8x_tail: # up to 7 "words" tail... - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - vncipher $out6,$out6,v24 - vncipher $out7,$out7,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - vncipher $out6,$out6,v25 - vncipher $out7,$out7,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_cbc_dec8x_tail - - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - vncipher $out6,$out6,v24 - vncipher $out7,$out7,v24 - - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - vncipher $out6,$out6,v25 - vncipher $out7,$out7,v25 - - vncipher $out1,$out1,v26 - vncipher $out2,$out2,v26 - vncipher $out3,$out3,v26 - vncipher $out4,$out4,v26 - vncipher $out5,$out5,v26 - vncipher $out6,$out6,v26 - vncipher $out7,$out7,v26 - - vncipher $out1,$out1,v27 - vncipher $out2,$out2,v27 - vncipher $out3,$out3,v27 - vncipher $out4,$out4,v27 - vncipher $out5,$out5,v27 - vncipher $out6,$out6,v27 - vncipher $out7,$out7,v27 - - vncipher $out1,$out1,v28 - vncipher $out2,$out2,v28 - vncipher $out3,$out3,v28 - vncipher $out4,$out4,v28 - vncipher $out5,$out5,v28 - vncipher $out6,$out6,v28 - vncipher $out7,$out7,v28 - - vncipher $out1,$out1,v29 - vncipher $out2,$out2,v29 - vncipher $out3,$out3,v29 - vncipher $out4,$out4,v29 - vncipher $out5,$out5,v29 - vncipher $out6,$out6,v29 - vncipher $out7,$out7,v29 - - vncipher $out1,$out1,v30 - vxor $ivec,$ivec,v31 # last round key - vncipher $out2,$out2,v30 - vxor $in1,$in1,v31 - vncipher $out3,$out3,v30 - vxor $in2,$in2,v31 - vncipher $out4,$out4,v30 - vxor $in3,$in3,v31 - vncipher $out5,$out5,v30 - vxor $in4,$in4,v31 - vncipher $out6,$out6,v30 - vxor $in5,$in5,v31 - vncipher $out7,$out7,v30 - vxor $in6,$in6,v31 - - cmplwi $len,32 # switch($len) - blt Lcbc_dec8x_one - nop - beq Lcbc_dec8x_two - cmplwi $len,64 - blt Lcbc_dec8x_three - nop - beq Lcbc_dec8x_four - cmplwi $len,96 - blt Lcbc_dec8x_five - nop - beq Lcbc_dec8x_six - -Lcbc_dec8x_seven: - vncipherlast $out1,$out1,$ivec - vncipherlast $out2,$out2,$in1 - vncipherlast $out3,$out3,$in2 - vncipherlast $out4,$out4,$in3 - vncipherlast $out5,$out5,$in4 - vncipherlast $out6,$out6,$in5 - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out1,$out1,$out1,$inpperm - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x00,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x10,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x20,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x30,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x40,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x50,$out - stvx_u $out7,$x60,$out - addi $out,$out,0x70 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_six: - vncipherlast $out2,$out2,$ivec - vncipherlast $out3,$out3,$in2 - vncipherlast $out4,$out4,$in3 - vncipherlast $out5,$out5,$in4 - vncipherlast $out6,$out6,$in5 - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out2,$out2,$out2,$inpperm - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x00,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x10,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x20,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x30,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x40,$out - stvx_u $out7,$x50,$out - addi $out,$out,0x60 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_five: - vncipherlast $out3,$out3,$ivec - vncipherlast $out4,$out4,$in3 - vncipherlast $out5,$out5,$in4 - vncipherlast $out6,$out6,$in5 - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out3,$out3,$out3,$inpperm - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x00,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x10,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x20,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x30,$out - stvx_u $out7,$x40,$out - addi $out,$out,0x50 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_four: - vncipherlast $out4,$out4,$ivec - vncipherlast $out5,$out5,$in4 - vncipherlast $out6,$out6,$in5 - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out4,$out4,$out4,$inpperm - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x00,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x10,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x20,$out - stvx_u $out7,$x30,$out - addi $out,$out,0x40 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_three: - vncipherlast $out5,$out5,$ivec - vncipherlast $out6,$out6,$in5 - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out5,$out5,$out5,$inpperm - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x00,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x10,$out - stvx_u $out7,$x20,$out - addi $out,$out,0x30 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_two: - vncipherlast $out6,$out6,$ivec - vncipherlast $out7,$out7,$in6 - vmr $ivec,$in7 - - le?vperm $out6,$out6,$out6,$inpperm - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x00,$out - stvx_u $out7,$x10,$out - addi $out,$out,0x20 - b Lcbc_dec8x_done - -.align 5 -Lcbc_dec8x_one: - vncipherlast $out7,$out7,$ivec - vmr $ivec,$in7 - - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out7,0,$out - addi $out,$out,0x10 - -Lcbc_dec8x_done: - le?vperm $ivec,$ivec,$ivec,$inpperm - stvx_u $ivec,0,$ivp # write [unaligned] iv - - li r10,`$FRAME+15` - li r11,`$FRAME+31` - stvx $inpperm,r10,$sp # wipe copies of round keys - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - - mtspr 256,$vrsave - lvx v20,r10,$sp # ABI says so - addi r10,r10,32 - lvx v21,r11,$sp - addi r11,r11,32 - lvx v22,r10,$sp - addi r10,r10,32 - lvx v23,r11,$sp - addi r11,r11,32 - lvx v24,r10,$sp - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp - $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) - $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) - $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) - $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) - $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) - $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) - addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` - blr - .long 0 - .byte 0,12,0x04,0,0x80,6,6,0 - .long 0 -.size .${prefix}_cbc_encrypt,.-.${prefix}_cbc_encrypt -___ -}} }}} - -######################################################################### -{{{ # CTR procedure[s] # -my ($inp,$out,$len,$key,$ivp,$x10,$rounds,$idx)=map("r$_",(3..10)); -my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); -my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm,$one)= - map("v$_",(4..11)); -my $dat=$tmp; - -$code.=<<___; -.globl .${prefix}_ctr32_encrypt_blocks -.align 5 -.${prefix}_ctr32_encrypt_blocks: - ${UCMP}i $len,1 - bltlr- - - lis r0,0xfff0 - mfspr $vrsave,256 - mtspr 256,r0 - - li $idx,15 - vxor $rndkey0,$rndkey0,$rndkey0 - le?vspltisb $tmp,0x0f - - lvx $ivec,0,$ivp # load [unaligned] iv - lvsl $inpperm,0,$ivp - lvx $inptail,$idx,$ivp - vspltisb $one,1 - le?vxor $inpperm,$inpperm,$tmp - vperm $ivec,$ivec,$inptail,$inpperm - vsldoi $one,$rndkey0,$one,1 - - neg r11,$inp - ?lvsl $keyperm,0,$key # prepare for unaligned key - lwz $rounds,240($key) - - lvsr $inpperm,0,r11 # prepare for unaligned load - lvx $inptail,0,$inp - addi $inp,$inp,15 # 15 is not typo - le?vxor $inpperm,$inpperm,$tmp - - srwi $rounds,$rounds,1 - li $idx,16 - subi $rounds,$rounds,1 - - ${UCMP}i $len,8 - bge _aesp8_ctr32_encrypt8x - - ?lvsr $outperm,0,$out # prepare for unaligned store - vspltisb $outmask,-1 - lvx $outhead,0,$out - ?vperm $outmask,$rndkey0,$outmask,$outperm - le?vxor $outperm,$outperm,$tmp - - lvx $rndkey0,0,$key - mtctr $rounds - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$ivec,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - b Loop_ctr32_enc - -.align 5 -Loop_ctr32_enc: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - bdnz Loop_ctr32_enc - - vadduwm $ivec,$ivec,$one - vmr $dat,$inptail - lvx $inptail,0,$inp - addi $inp,$inp,16 - subic. $len,$len,1 # blocks-- - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key - vperm $dat,$dat,$inptail,$inpperm - li $idx,16 - ?vperm $rndkey1,$rndkey0,$rndkey1,$keyperm - lvx $rndkey0,0,$key - vxor $dat,$dat,$rndkey1 # last round key - vcipherlast $inout,$inout,$dat - - lvx $rndkey1,$idx,$key - addi $idx,$idx,16 - vperm $inout,$inout,$inout,$outperm - vsel $dat,$outhead,$inout,$outmask - mtctr $rounds - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vmr $outhead,$inout - vxor $inout,$ivec,$rndkey0 - lvx $rndkey0,$idx,$key - addi $idx,$idx,16 - stvx $dat,0,$out - addi $out,$out,16 - bne Loop_ctr32_enc - - addi $out,$out,-1 - lvx $inout,0,$out # redundant in aligned case - vsel $inout,$outhead,$inout,$outmask - stvx $inout,0,$out - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,6,0 - .long 0 -___ -######################################################################### -{{ # Optimized CTR procedure # -my $key_="r11"; -my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); - $x00=0 if ($flavour =~ /osx/); -my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10,12..14)); -my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(15..22)); -my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys - # v26-v31 last 6 round keys -my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment -my ($two,$three,$four)=($outhead,$outperm,$outmask); - -$code.=<<___; -.align 5 -_aesp8_ctr32_encrypt8x: - $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) - li r10,`$FRAME+8*16+15` - li r11,`$FRAME+8*16+31` - stvx v20,r10,$sp # ABI says so - addi r10,r10,32 - stvx v21,r11,$sp - addi r11,r11,32 - stvx v22,r10,$sp - addi r10,r10,32 - stvx v23,r11,$sp - addi r11,r11,32 - stvx v24,r10,$sp - addi r10,r10,32 - stvx v25,r11,$sp - addi r11,r11,32 - stvx v26,r10,$sp - addi r10,r10,32 - stvx v27,r11,$sp - addi r11,r11,32 - stvx v28,r10,$sp - addi r10,r10,32 - stvx v29,r11,$sp - addi r11,r11,32 - stvx v30,r10,$sp - stvx v31,r11,$sp - li r0,-1 - stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave - li $x10,0x10 - $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) - li $x20,0x20 - $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) - li $x30,0x30 - $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) - li $x40,0x40 - $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) - li $x50,0x50 - $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) - li $x60,0x60 - $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) - li $x70,0x70 - mtspr 256,r0 - - subi $rounds,$rounds,3 # -4 in total - - lvx $rndkey0,$x00,$key # load key schedule - lvx v30,$x10,$key - addi $key,$key,0x20 - lvx v31,$x00,$key - ?vperm $rndkey0,$rndkey0,v30,$keyperm - addi $key_,$sp,`$FRAME+15` - mtctr $rounds - -Load_ctr32_enc_key: - ?vperm v24,v30,v31,$keyperm - lvx v30,$x10,$key - addi $key,$key,0x20 - stvx v24,$x00,$key_ # off-load round[1] - ?vperm v25,v31,v30,$keyperm - lvx v31,$x00,$key - stvx v25,$x10,$key_ # off-load round[2] - addi $key_,$key_,0x20 - bdnz Load_ctr32_enc_key - - lvx v26,$x10,$key - ?vperm v24,v30,v31,$keyperm - lvx v27,$x20,$key - stvx v24,$x00,$key_ # off-load round[3] - ?vperm v25,v31,v26,$keyperm - lvx v28,$x30,$key - stvx v25,$x10,$key_ # off-load round[4] - addi $key_,$sp,`$FRAME+15` # rewind $key_ - ?vperm v26,v26,v27,$keyperm - lvx v29,$x40,$key - ?vperm v27,v27,v28,$keyperm - lvx v30,$x50,$key - ?vperm v28,v28,v29,$keyperm - lvx v31,$x60,$key - ?vperm v29,v29,v30,$keyperm - lvx $out0,$x70,$key # borrow $out0 - ?vperm v30,v30,v31,$keyperm - lvx v24,$x00,$key_ # pre-load round[1] - ?vperm v31,v31,$out0,$keyperm - lvx v25,$x10,$key_ # pre-load round[2] - - vadduwm $two,$one,$one - subi $inp,$inp,15 # undo "caller" - $SHL $len,$len,4 - - vadduwm $out1,$ivec,$one # counter values ... - vadduwm $out2,$ivec,$two - vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] - le?li $idx,8 - vadduwm $out3,$out1,$two - vxor $out1,$out1,$rndkey0 - le?lvsl $inpperm,0,$idx - vadduwm $out4,$out2,$two - vxor $out2,$out2,$rndkey0 - le?vspltisb $tmp,0x0f - vadduwm $out5,$out3,$two - vxor $out3,$out3,$rndkey0 - le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u - vadduwm $out6,$out4,$two - vxor $out4,$out4,$rndkey0 - vadduwm $out7,$out5,$two - vxor $out5,$out5,$rndkey0 - vadduwm $ivec,$out6,$two # next counter value - vxor $out6,$out6,$rndkey0 - vxor $out7,$out7,$rndkey0 - - mtctr $rounds - b Loop_ctr32_enc8x -.align 5 -Loop_ctr32_enc8x: - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vcipher $out4,$out4,v24 - vcipher $out5,$out5,v24 - vcipher $out6,$out6,v24 - vcipher $out7,$out7,v24 -Loop_ctr32_enc8x_middle: - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vcipher $out4,$out4,v25 - vcipher $out5,$out5,v25 - vcipher $out6,$out6,v25 - vcipher $out7,$out7,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_ctr32_enc8x - - subic r11,$len,256 # $len-256, borrow $key_ - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vcipher $out4,$out4,v24 - vcipher $out5,$out5,v24 - vcipher $out6,$out6,v24 - vcipher $out7,$out7,v24 - - subfe r0,r0,r0 # borrow?-1:0 - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vcipher $out4,$out4,v25 - vcipher $out5,$out5,v25 - vcipher $out6,$out6,v25 - vcipher $out7,$out7,v25 - - and r0,r0,r11 - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vcipher $out0,$out0,v26 - vcipher $out1,$out1,v26 - vcipher $out2,$out2,v26 - vcipher $out3,$out3,v26 - vcipher $out4,$out4,v26 - vcipher $out5,$out5,v26 - vcipher $out6,$out6,v26 - vcipher $out7,$out7,v26 - lvx v24,$x00,$key_ # re-pre-load round[1] - - subic $len,$len,129 # $len-=129 - vcipher $out0,$out0,v27 - addi $len,$len,1 # $len-=128 really - vcipher $out1,$out1,v27 - vcipher $out2,$out2,v27 - vcipher $out3,$out3,v27 - vcipher $out4,$out4,v27 - vcipher $out5,$out5,v27 - vcipher $out6,$out6,v27 - vcipher $out7,$out7,v27 - lvx v25,$x10,$key_ # re-pre-load round[2] - - vcipher $out0,$out0,v28 - lvx_u $in0,$x00,$inp # load input - vcipher $out1,$out1,v28 - lvx_u $in1,$x10,$inp - vcipher $out2,$out2,v28 - lvx_u $in2,$x20,$inp - vcipher $out3,$out3,v28 - lvx_u $in3,$x30,$inp - vcipher $out4,$out4,v28 - lvx_u $in4,$x40,$inp - vcipher $out5,$out5,v28 - lvx_u $in5,$x50,$inp - vcipher $out6,$out6,v28 - lvx_u $in6,$x60,$inp - vcipher $out7,$out7,v28 - lvx_u $in7,$x70,$inp - addi $inp,$inp,0x80 - - vcipher $out0,$out0,v29 - le?vperm $in0,$in0,$in0,$inpperm - vcipher $out1,$out1,v29 - le?vperm $in1,$in1,$in1,$inpperm - vcipher $out2,$out2,v29 - le?vperm $in2,$in2,$in2,$inpperm - vcipher $out3,$out3,v29 - le?vperm $in3,$in3,$in3,$inpperm - vcipher $out4,$out4,v29 - le?vperm $in4,$in4,$in4,$inpperm - vcipher $out5,$out5,v29 - le?vperm $in5,$in5,$in5,$inpperm - vcipher $out6,$out6,v29 - le?vperm $in6,$in6,$in6,$inpperm - vcipher $out7,$out7,v29 - le?vperm $in7,$in7,$in7,$inpperm - - add $inp,$inp,r0 # $inp is adjusted in such - # way that at exit from the - # loop inX-in7 are loaded - # with last "words" - subfe. r0,r0,r0 # borrow?-1:0 - vcipher $out0,$out0,v30 - vxor $in0,$in0,v31 # xor with last round key - vcipher $out1,$out1,v30 - vxor $in1,$in1,v31 - vcipher $out2,$out2,v30 - vxor $in2,$in2,v31 - vcipher $out3,$out3,v30 - vxor $in3,$in3,v31 - vcipher $out4,$out4,v30 - vxor $in4,$in4,v31 - vcipher $out5,$out5,v30 - vxor $in5,$in5,v31 - vcipher $out6,$out6,v30 - vxor $in6,$in6,v31 - vcipher $out7,$out7,v30 - vxor $in7,$in7,v31 - - bne Lctr32_enc8x_break # did $len-129 borrow? - - vcipherlast $in0,$out0,$in0 - vcipherlast $in1,$out1,$in1 - vadduwm $out1,$ivec,$one # counter values ... - vcipherlast $in2,$out2,$in2 - vadduwm $out2,$ivec,$two - vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] - vcipherlast $in3,$out3,$in3 - vadduwm $out3,$out1,$two - vxor $out1,$out1,$rndkey0 - vcipherlast $in4,$out4,$in4 - vadduwm $out4,$out2,$two - vxor $out2,$out2,$rndkey0 - vcipherlast $in5,$out5,$in5 - vadduwm $out5,$out3,$two - vxor $out3,$out3,$rndkey0 - vcipherlast $in6,$out6,$in6 - vadduwm $out6,$out4,$two - vxor $out4,$out4,$rndkey0 - vcipherlast $in7,$out7,$in7 - vadduwm $out7,$out5,$two - vxor $out5,$out5,$rndkey0 - le?vperm $in0,$in0,$in0,$inpperm - vadduwm $ivec,$out6,$two # next counter value - vxor $out6,$out6,$rndkey0 - le?vperm $in1,$in1,$in1,$inpperm - vxor $out7,$out7,$rndkey0 - mtctr $rounds - - vcipher $out0,$out0,v24 - stvx_u $in0,$x00,$out - le?vperm $in2,$in2,$in2,$inpperm - vcipher $out1,$out1,v24 - stvx_u $in1,$x10,$out - le?vperm $in3,$in3,$in3,$inpperm - vcipher $out2,$out2,v24 - stvx_u $in2,$x20,$out - le?vperm $in4,$in4,$in4,$inpperm - vcipher $out3,$out3,v24 - stvx_u $in3,$x30,$out - le?vperm $in5,$in5,$in5,$inpperm - vcipher $out4,$out4,v24 - stvx_u $in4,$x40,$out - le?vperm $in6,$in6,$in6,$inpperm - vcipher $out5,$out5,v24 - stvx_u $in5,$x50,$out - le?vperm $in7,$in7,$in7,$inpperm - vcipher $out6,$out6,v24 - stvx_u $in6,$x60,$out - vcipher $out7,$out7,v24 - stvx_u $in7,$x70,$out - addi $out,$out,0x80 - - b Loop_ctr32_enc8x_middle - -.align 5 -Lctr32_enc8x_break: - cmpwi $len,-0x60 - blt Lctr32_enc8x_one - nop - beq Lctr32_enc8x_two - cmpwi $len,-0x40 - blt Lctr32_enc8x_three - nop - beq Lctr32_enc8x_four - cmpwi $len,-0x20 - blt Lctr32_enc8x_five - nop - beq Lctr32_enc8x_six - cmpwi $len,0x00 - blt Lctr32_enc8x_seven - -Lctr32_enc8x_eight: - vcipherlast $out0,$out0,$in0 - vcipherlast $out1,$out1,$in1 - vcipherlast $out2,$out2,$in2 - vcipherlast $out3,$out3,$in3 - vcipherlast $out4,$out4,$in4 - vcipherlast $out5,$out5,$in5 - vcipherlast $out6,$out6,$in6 - vcipherlast $out7,$out7,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x30,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x40,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x50,$out - le?vperm $out7,$out7,$out7,$inpperm - stvx_u $out6,$x60,$out - stvx_u $out7,$x70,$out - addi $out,$out,0x80 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_seven: - vcipherlast $out0,$out0,$in1 - vcipherlast $out1,$out1,$in2 - vcipherlast $out2,$out2,$in3 - vcipherlast $out3,$out3,$in4 - vcipherlast $out4,$out4,$in5 - vcipherlast $out5,$out5,$in6 - vcipherlast $out6,$out6,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x30,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x40,$out - le?vperm $out6,$out6,$out6,$inpperm - stvx_u $out5,$x50,$out - stvx_u $out6,$x60,$out - addi $out,$out,0x70 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_six: - vcipherlast $out0,$out0,$in2 - vcipherlast $out1,$out1,$in3 - vcipherlast $out2,$out2,$in4 - vcipherlast $out3,$out3,$in5 - vcipherlast $out4,$out4,$in6 - vcipherlast $out5,$out5,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x30,$out - le?vperm $out5,$out5,$out5,$inpperm - stvx_u $out4,$x40,$out - stvx_u $out5,$x50,$out - addi $out,$out,0x60 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_five: - vcipherlast $out0,$out0,$in3 - vcipherlast $out1,$out1,$in4 - vcipherlast $out2,$out2,$in5 - vcipherlast $out3,$out3,$in6 - vcipherlast $out4,$out4,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - le?vperm $out4,$out4,$out4,$inpperm - stvx_u $out3,$x30,$out - stvx_u $out4,$x40,$out - addi $out,$out,0x50 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_four: - vcipherlast $out0,$out0,$in4 - vcipherlast $out1,$out1,$in5 - vcipherlast $out2,$out2,$in6 - vcipherlast $out3,$out3,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$inpperm - stvx_u $out2,$x20,$out - stvx_u $out3,$x30,$out - addi $out,$out,0x40 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_three: - vcipherlast $out0,$out0,$in5 - vcipherlast $out1,$out1,$in6 - vcipherlast $out2,$out2,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - le?vperm $out2,$out2,$out2,$inpperm - stvx_u $out1,$x10,$out - stvx_u $out2,$x20,$out - addi $out,$out,0x30 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_two: - vcipherlast $out0,$out0,$in6 - vcipherlast $out1,$out1,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - le?vperm $out1,$out1,$out1,$inpperm - stvx_u $out0,$x00,$out - stvx_u $out1,$x10,$out - addi $out,$out,0x20 - b Lctr32_enc8x_done - -.align 5 -Lctr32_enc8x_one: - vcipherlast $out0,$out0,$in7 - - le?vperm $out0,$out0,$out0,$inpperm - stvx_u $out0,0,$out - addi $out,$out,0x10 - -Lctr32_enc8x_done: - li r10,`$FRAME+15` - li r11,`$FRAME+31` - stvx $inpperm,r10,$sp # wipe copies of round keys - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - stvx $inpperm,r10,$sp - addi r10,r10,32 - stvx $inpperm,r11,$sp - addi r11,r11,32 - - mtspr 256,$vrsave - lvx v20,r10,$sp # ABI says so - addi r10,r10,32 - lvx v21,r11,$sp - addi r11,r11,32 - lvx v22,r10,$sp - addi r10,r10,32 - lvx v23,r11,$sp - addi r11,r11,32 - lvx v24,r10,$sp - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp - $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) - $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) - $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) - $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) - $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) - $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) - addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` - blr - .long 0 - .byte 0,12,0x04,0,0x80,6,6,0 - .long 0 -.size .${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks -___ -}} }}} - -######################################################################### -{{{ # XTS procedures # -# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len, # -# const AES_KEY *key1, const AES_KEY *key2, # -# [const] unsigned char iv[16]); # -# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which # -# input tweak value is assumed to be encrypted already, and last tweak # -# value, one suitable for consecutive call on same chunk of data, is # -# written back to original buffer. In addition, in "tweak chaining" # -# mode only complete input blocks are processed. # - -my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) = map("r$_",(3..10)); -my ($rndkey0,$rndkey1,$inout) = map("v$_",(0..2)); -my ($output,$inptail,$inpperm,$leperm,$keyperm) = map("v$_",(3..7)); -my ($tweak,$seven,$eighty7,$tmp,$tweak1) = map("v$_",(8..12)); -my $taillen = $key2; - - ($inp,$idx) = ($idx,$inp); # reassign - -$code.=<<___; -.globl .${prefix}_xts_encrypt -.align 5 -.${prefix}_xts_encrypt: - mr $inp,r3 # reassign - li r3,-1 - ${UCMP}i $len,16 - bltlr- - - lis r0,0xfff0 - mfspr r12,256 # save vrsave - li r11,0 - mtspr 256,r0 - - vspltisb $seven,0x07 # 0x070707..07 - le?lvsl $leperm,r11,r11 - le?vspltisb $tmp,0x0f - le?vxor $leperm,$leperm,$seven - - li $idx,15 - lvx $tweak,0,$ivp # load [unaligned] iv - lvsl $inpperm,0,$ivp - lvx $inptail,$idx,$ivp - le?vxor $inpperm,$inpperm,$tmp - vperm $tweak,$tweak,$inptail,$inpperm - - neg r11,$inp - lvsr $inpperm,0,r11 # prepare for unaligned load - lvx $inout,0,$inp - addi $inp,$inp,15 # 15 is not typo - le?vxor $inpperm,$inpperm,$tmp - - ${UCMP}i $key2,0 # key2==NULL? - beq Lxts_enc_no_key2 - - ?lvsl $keyperm,0,$key2 # prepare for unaligned key - lwz $rounds,240($key2) - srwi $rounds,$rounds,1 - subi $rounds,$rounds,1 - li $idx,16 - - lvx $rndkey0,0,$key2 - lvx $rndkey1,$idx,$key2 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $tweak,$tweak,$rndkey0 - lvx $rndkey0,$idx,$key2 - addi $idx,$idx,16 - mtctr $rounds - -Ltweak_xts_enc: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $tweak,$tweak,$rndkey1 - lvx $rndkey1,$idx,$key2 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipher $tweak,$tweak,$rndkey0 - lvx $rndkey0,$idx,$key2 - addi $idx,$idx,16 - bdnz Ltweak_xts_enc - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $tweak,$tweak,$rndkey1 - lvx $rndkey1,$idx,$key2 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipherlast $tweak,$tweak,$rndkey0 - - li $ivp,0 # don't chain the tweak - b Lxts_enc - -Lxts_enc_no_key2: - li $idx,-16 - and $len,$len,$idx # in "tweak chaining" - # mode only complete - # blocks are processed -Lxts_enc: - lvx $inptail,0,$inp - addi $inp,$inp,16 - - ?lvsl $keyperm,0,$key1 # prepare for unaligned key - lwz $rounds,240($key1) - srwi $rounds,$rounds,1 - subi $rounds,$rounds,1 - li $idx,16 - - vslb $eighty7,$seven,$seven # 0x808080..80 - vor $eighty7,$eighty7,$seven # 0x878787..87 - vspltisb $tmp,1 # 0x010101..01 - vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 - - ${UCMP}i $len,96 - bge _aesp8_xts_encrypt6x - - andi. $taillen,$len,15 - subic r0,$len,32 - subi $taillen,$taillen,16 - subfe r0,r0,r0 - and r0,r0,$taillen - add $inp,$inp,r0 - - lvx $rndkey0,0,$key1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - vperm $inout,$inout,$inptail,$inpperm - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$inout,$tweak - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - mtctr $rounds - b Loop_xts_enc - -.align 5 -Loop_xts_enc: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - bdnz Loop_xts_enc - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - li $idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $rndkey0,$rndkey0,$tweak - vcipherlast $output,$inout,$rndkey0 - - le?vperm $tmp,$output,$output,$leperm - be?nop - le?stvx_u $tmp,0,$out - be?stvx_u $output,0,$out - addi $out,$out,16 - - subic. $len,$len,16 - beq Lxts_enc_done - - vmr $inout,$inptail - lvx $inptail,0,$inp - addi $inp,$inp,16 - lvx $rndkey0,0,$key1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - - subic r0,$len,32 - subfe r0,r0,r0 - and r0,r0,$taillen - add $inp,$inp,r0 - - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $tweak,$tweak,$tmp - - vperm $inout,$inout,$inptail,$inpperm - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$inout,$tweak - vxor $output,$output,$rndkey0 # just in case $len<16 - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - - mtctr $rounds - ${UCMP}i $len,16 - bge Loop_xts_enc - - vxor $output,$output,$tweak - lvsr $inpperm,0,$len # $inpperm is no longer needed - vxor $inptail,$inptail,$inptail # $inptail is no longer needed - vspltisb $tmp,-1 - vperm $inptail,$inptail,$tmp,$inpperm - vsel $inout,$inout,$output,$inptail - - subi r11,$out,17 - subi $out,$out,16 - mtctr $len - li $len,16 -Loop_xts_enc_steal: - lbzu r0,1(r11) - stb r0,16(r11) - bdnz Loop_xts_enc_steal - - mtctr $rounds - b Loop_xts_enc # one more time... - -Lxts_enc_done: - ${UCMP}i $ivp,0 - beq Lxts_enc_ret - - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $tweak,$tweak,$tmp - - le?vperm $tweak,$tweak,$tweak,$leperm - stvx_u $tweak,0,$ivp - -Lxts_enc_ret: - mtspr 256,r12 # restore vrsave - li r3,0 - blr - .long 0 - .byte 0,12,0x04,0,0x80,6,6,0 - .long 0 -.size .${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt - -.globl .${prefix}_xts_decrypt -.align 5 -.${prefix}_xts_decrypt: - mr $inp,r3 # reassign - li r3,-1 - ${UCMP}i $len,16 - bltlr- - - lis r0,0xfff8 - mfspr r12,256 # save vrsave - li r11,0 - mtspr 256,r0 - - andi. r0,$len,15 - neg r0,r0 - andi. r0,r0,16 - sub $len,$len,r0 - - vspltisb $seven,0x07 # 0x070707..07 - le?lvsl $leperm,r11,r11 - le?vspltisb $tmp,0x0f - le?vxor $leperm,$leperm,$seven - - li $idx,15 - lvx $tweak,0,$ivp # load [unaligned] iv - lvsl $inpperm,0,$ivp - lvx $inptail,$idx,$ivp - le?vxor $inpperm,$inpperm,$tmp - vperm $tweak,$tweak,$inptail,$inpperm - - neg r11,$inp - lvsr $inpperm,0,r11 # prepare for unaligned load - lvx $inout,0,$inp - addi $inp,$inp,15 # 15 is not typo - le?vxor $inpperm,$inpperm,$tmp - - ${UCMP}i $key2,0 # key2==NULL? - beq Lxts_dec_no_key2 - - ?lvsl $keyperm,0,$key2 # prepare for unaligned key - lwz $rounds,240($key2) - srwi $rounds,$rounds,1 - subi $rounds,$rounds,1 - li $idx,16 - - lvx $rndkey0,0,$key2 - lvx $rndkey1,$idx,$key2 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $tweak,$tweak,$rndkey0 - lvx $rndkey0,$idx,$key2 - addi $idx,$idx,16 - mtctr $rounds - -Ltweak_xts_dec: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $tweak,$tweak,$rndkey1 - lvx $rndkey1,$idx,$key2 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipher $tweak,$tweak,$rndkey0 - lvx $rndkey0,$idx,$key2 - addi $idx,$idx,16 - bdnz Ltweak_xts_dec - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vcipher $tweak,$tweak,$rndkey1 - lvx $rndkey1,$idx,$key2 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vcipherlast $tweak,$tweak,$rndkey0 - - li $ivp,0 # don't chain the tweak - b Lxts_dec - -Lxts_dec_no_key2: - neg $idx,$len - andi. $idx,$idx,15 - add $len,$len,$idx # in "tweak chaining" - # mode only complete - # blocks are processed -Lxts_dec: - lvx $inptail,0,$inp - addi $inp,$inp,16 - - ?lvsl $keyperm,0,$key1 # prepare for unaligned key - lwz $rounds,240($key1) - srwi $rounds,$rounds,1 - subi $rounds,$rounds,1 - li $idx,16 - - vslb $eighty7,$seven,$seven # 0x808080..80 - vor $eighty7,$eighty7,$seven # 0x878787..87 - vspltisb $tmp,1 # 0x010101..01 - vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 - - ${UCMP}i $len,96 - bge _aesp8_xts_decrypt6x - - lvx $rndkey0,0,$key1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - vperm $inout,$inout,$inptail,$inpperm - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$inout,$tweak - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - mtctr $rounds - - ${UCMP}i $len,16 - blt Ltail_xts_dec - be?b Loop_xts_dec - -.align 5 -Loop_xts_dec: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vncipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - bdnz Loop_xts_dec - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - li $idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $rndkey0,$rndkey0,$tweak - vncipherlast $output,$inout,$rndkey0 - - le?vperm $tmp,$output,$output,$leperm - be?nop - le?stvx_u $tmp,0,$out - be?stvx_u $output,0,$out - addi $out,$out,16 - - subic. $len,$len,16 - beq Lxts_dec_done - - vmr $inout,$inptail - lvx $inptail,0,$inp - addi $inp,$inp,16 - lvx $rndkey0,0,$key1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $tweak,$tweak,$tmp - - vperm $inout,$inout,$inptail,$inpperm - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $inout,$inout,$tweak - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - - mtctr $rounds - ${UCMP}i $len,16 - bge Loop_xts_dec - -Ltail_xts_dec: - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak1,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $tweak1,$tweak1,$tmp - - subi $inp,$inp,16 - add $inp,$inp,$len - - vxor $inout,$inout,$tweak # :-( - vxor $inout,$inout,$tweak1 # :-) - -Loop_xts_dec_short: - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vncipher $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - bdnz Loop_xts_dec_short - - ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm - vncipher $inout,$inout,$rndkey1 - lvx $rndkey1,$idx,$key1 - li $idx,16 - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - vxor $rndkey0,$rndkey0,$tweak1 - vncipherlast $output,$inout,$rndkey0 - - le?vperm $tmp,$output,$output,$leperm - be?nop - le?stvx_u $tmp,0,$out - be?stvx_u $output,0,$out - - vmr $inout,$inptail - lvx $inptail,0,$inp - #addi $inp,$inp,16 - lvx $rndkey0,0,$key1 - lvx $rndkey1,$idx,$key1 - addi $idx,$idx,16 - vperm $inout,$inout,$inptail,$inpperm - ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm - - lvsr $inpperm,0,$len # $inpperm is no longer needed - vxor $inptail,$inptail,$inptail # $inptail is no longer needed - vspltisb $tmp,-1 - vperm $inptail,$inptail,$tmp,$inpperm - vsel $inout,$inout,$output,$inptail - - vxor $rndkey0,$rndkey0,$tweak - vxor $inout,$inout,$rndkey0 - lvx $rndkey0,$idx,$key1 - addi $idx,$idx,16 - - subi r11,$out,1 - mtctr $len - li $len,16 -Loop_xts_dec_steal: - lbzu r0,1(r11) - stb r0,16(r11) - bdnz Loop_xts_dec_steal - - mtctr $rounds - b Loop_xts_dec # one more time... - -Lxts_dec_done: - ${UCMP}i $ivp,0 - beq Lxts_dec_ret - - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $tweak,$tweak,$tmp - - le?vperm $tweak,$tweak,$tweak,$leperm - stvx_u $tweak,0,$ivp - -Lxts_dec_ret: - mtspr 256,r12 # restore vrsave - li r3,0 - blr - .long 0 - .byte 0,12,0x04,0,0x80,6,6,0 - .long 0 -.size .${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt -___ -######################################################################### -{{ # Optimized XTS procedures # -my $key_=$key2; -my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31)); - $x00=0 if ($flavour =~ /osx/); -my ($in0, $in1, $in2, $in3, $in4, $in5 )=map("v$_",(0..5)); -my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16)); -my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22)); -my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys - # v26-v31 last 6 round keys -my ($keyperm)=($out0); # aliases with "caller", redundant assignment -my $taillen=$x70; - -$code.=<<___; -.align 5 -_aesp8_xts_encrypt6x: - $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) - mflr r11 - li r7,`$FRAME+8*16+15` - li r3,`$FRAME+8*16+31` - $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) - stvx v20,r7,$sp # ABI says so - addi r7,r7,32 - stvx v21,r3,$sp - addi r3,r3,32 - stvx v22,r7,$sp - addi r7,r7,32 - stvx v23,r3,$sp - addi r3,r3,32 - stvx v24,r7,$sp - addi r7,r7,32 - stvx v25,r3,$sp - addi r3,r3,32 - stvx v26,r7,$sp - addi r7,r7,32 - stvx v27,r3,$sp - addi r3,r3,32 - stvx v28,r7,$sp - addi r7,r7,32 - stvx v29,r3,$sp - addi r3,r3,32 - stvx v30,r7,$sp - stvx v31,r3,$sp - li r0,-1 - stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave - li $x10,0x10 - $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) - li $x20,0x20 - $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) - li $x30,0x30 - $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) - li $x40,0x40 - $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) - li $x50,0x50 - $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) - li $x60,0x60 - $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) - li $x70,0x70 - mtspr 256,r0 - - subi $rounds,$rounds,3 # -4 in total - - lvx $rndkey0,$x00,$key1 # load key schedule - lvx v30,$x10,$key1 - addi $key1,$key1,0x20 - lvx v31,$x00,$key1 - ?vperm $rndkey0,$rndkey0,v30,$keyperm - addi $key_,$sp,`$FRAME+15` - mtctr $rounds - -Load_xts_enc_key: - ?vperm v24,v30,v31,$keyperm - lvx v30,$x10,$key1 - addi $key1,$key1,0x20 - stvx v24,$x00,$key_ # off-load round[1] - ?vperm v25,v31,v30,$keyperm - lvx v31,$x00,$key1 - stvx v25,$x10,$key_ # off-load round[2] - addi $key_,$key_,0x20 - bdnz Load_xts_enc_key - - lvx v26,$x10,$key1 - ?vperm v24,v30,v31,$keyperm - lvx v27,$x20,$key1 - stvx v24,$x00,$key_ # off-load round[3] - ?vperm v25,v31,v26,$keyperm - lvx v28,$x30,$key1 - stvx v25,$x10,$key_ # off-load round[4] - addi $key_,$sp,`$FRAME+15` # rewind $key_ - ?vperm v26,v26,v27,$keyperm - lvx v29,$x40,$key1 - ?vperm v27,v27,v28,$keyperm - lvx v30,$x50,$key1 - ?vperm v28,v28,v29,$keyperm - lvx v31,$x60,$key1 - ?vperm v29,v29,v30,$keyperm - lvx $twk5,$x70,$key1 # borrow $twk5 - ?vperm v30,v30,v31,$keyperm - lvx v24,$x00,$key_ # pre-load round[1] - ?vperm v31,v31,$twk5,$keyperm - lvx v25,$x10,$key_ # pre-load round[2] - - vperm $in0,$inout,$inptail,$inpperm - subi $inp,$inp,31 # undo "caller" - vxor $twk0,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $out0,$in0,$twk0 - vxor $tweak,$tweak,$tmp - - lvx_u $in1,$x10,$inp - vxor $twk1,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in1,$in1,$in1,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out1,$in1,$twk1 - vxor $tweak,$tweak,$tmp - - lvx_u $in2,$x20,$inp - andi. $taillen,$len,15 - vxor $twk2,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in2,$in2,$in2,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out2,$in2,$twk2 - vxor $tweak,$tweak,$tmp - - lvx_u $in3,$x30,$inp - sub $len,$len,$taillen - vxor $twk3,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in3,$in3,$in3,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out3,$in3,$twk3 - vxor $tweak,$tweak,$tmp - - lvx_u $in4,$x40,$inp - subi $len,$len,0x60 - vxor $twk4,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in4,$in4,$in4,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out4,$in4,$twk4 - vxor $tweak,$tweak,$tmp - - lvx_u $in5,$x50,$inp - addi $inp,$inp,0x60 - vxor $twk5,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in5,$in5,$in5,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out5,$in5,$twk5 - vxor $tweak,$tweak,$tmp - - vxor v31,v31,$rndkey0 - mtctr $rounds - b Loop_xts_enc6x - -.align 5 -Loop_xts_enc6x: - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vcipher $out4,$out4,v24 - vcipher $out5,$out5,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vcipher $out4,$out4,v25 - vcipher $out5,$out5,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_xts_enc6x - - subic $len,$len,96 # $len-=96 - vxor $in0,$twk0,v31 # xor with last round key - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk0,$tweak,$rndkey0 - vaddubm $tweak,$tweak,$tweak - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vsldoi $tmp,$tmp,$tmp,15 - vcipher $out4,$out4,v24 - vcipher $out5,$out5,v24 - - subfe. r0,r0,r0 # borrow?-1:0 - vand $tmp,$tmp,$eighty7 - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vxor $tweak,$tweak,$tmp - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vxor $in1,$twk1,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk1,$tweak,$rndkey0 - vcipher $out4,$out4,v25 - vcipher $out5,$out5,v25 - - and r0,r0,$len - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vcipher $out0,$out0,v26 - vcipher $out1,$out1,v26 - vand $tmp,$tmp,$eighty7 - vcipher $out2,$out2,v26 - vcipher $out3,$out3,v26 - vxor $tweak,$tweak,$tmp - vcipher $out4,$out4,v26 - vcipher $out5,$out5,v26 - - add $inp,$inp,r0 # $inp is adjusted in such - # way that at exit from the - # loop inX-in5 are loaded - # with last "words" - vxor $in2,$twk2,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk2,$tweak,$rndkey0 - vaddubm $tweak,$tweak,$tweak - vcipher $out0,$out0,v27 - vcipher $out1,$out1,v27 - vsldoi $tmp,$tmp,$tmp,15 - vcipher $out2,$out2,v27 - vcipher $out3,$out3,v27 - vand $tmp,$tmp,$eighty7 - vcipher $out4,$out4,v27 - vcipher $out5,$out5,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vxor $tweak,$tweak,$tmp - vcipher $out0,$out0,v28 - vcipher $out1,$out1,v28 - vxor $in3,$twk3,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk3,$tweak,$rndkey0 - vcipher $out2,$out2,v28 - vcipher $out3,$out3,v28 - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vcipher $out4,$out4,v28 - vcipher $out5,$out5,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - vand $tmp,$tmp,$eighty7 - - vcipher $out0,$out0,v29 - vcipher $out1,$out1,v29 - vxor $tweak,$tweak,$tmp - vcipher $out2,$out2,v29 - vcipher $out3,$out3,v29 - vxor $in4,$twk4,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk4,$tweak,$rndkey0 - vcipher $out4,$out4,v29 - vcipher $out5,$out5,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - - vcipher $out0,$out0,v30 - vcipher $out1,$out1,v30 - vand $tmp,$tmp,$eighty7 - vcipher $out2,$out2,v30 - vcipher $out3,$out3,v30 - vxor $tweak,$tweak,$tmp - vcipher $out4,$out4,v30 - vcipher $out5,$out5,v30 - vxor $in5,$twk5,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk5,$tweak,$rndkey0 - - vcipherlast $out0,$out0,$in0 - lvx_u $in0,$x00,$inp # load next input block - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vcipherlast $out1,$out1,$in1 - lvx_u $in1,$x10,$inp - vcipherlast $out2,$out2,$in2 - le?vperm $in0,$in0,$in0,$leperm - lvx_u $in2,$x20,$inp - vand $tmp,$tmp,$eighty7 - vcipherlast $out3,$out3,$in3 - le?vperm $in1,$in1,$in1,$leperm - lvx_u $in3,$x30,$inp - vcipherlast $out4,$out4,$in4 - le?vperm $in2,$in2,$in2,$leperm - lvx_u $in4,$x40,$inp - vxor $tweak,$tweak,$tmp - vcipherlast $tmp,$out5,$in5 # last block might be needed - # in stealing mode - le?vperm $in3,$in3,$in3,$leperm - lvx_u $in5,$x50,$inp - addi $inp,$inp,0x60 - le?vperm $in4,$in4,$in4,$leperm - le?vperm $in5,$in5,$in5,$leperm - - le?vperm $out0,$out0,$out0,$leperm - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk0 - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - vxor $out1,$in1,$twk1 - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - vxor $out2,$in2,$twk2 - le?vperm $out4,$out4,$out4,$leperm - stvx_u $out3,$x30,$out - vxor $out3,$in3,$twk3 - le?vperm $out5,$tmp,$tmp,$leperm - stvx_u $out4,$x40,$out - vxor $out4,$in4,$twk4 - le?stvx_u $out5,$x50,$out - be?stvx_u $tmp, $x50,$out - vxor $out5,$in5,$twk5 - addi $out,$out,0x60 - - mtctr $rounds - beq Loop_xts_enc6x # did $len-=96 borrow? - - addic. $len,$len,0x60 - beq Lxts_enc6x_zero - cmpwi $len,0x20 - blt Lxts_enc6x_one - nop - beq Lxts_enc6x_two - cmpwi $len,0x40 - blt Lxts_enc6x_three - nop - beq Lxts_enc6x_four - -Lxts_enc6x_five: - vxor $out0,$in1,$twk0 - vxor $out1,$in2,$twk1 - vxor $out2,$in3,$twk2 - vxor $out3,$in4,$twk3 - vxor $out4,$in5,$twk4 - - bl _aesp8_xts_enc5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk5 # unused tweak - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - vxor $tmp,$out4,$twk5 # last block prep for stealing - le?vperm $out4,$out4,$out4,$leperm - stvx_u $out3,$x30,$out - stvx_u $out4,$x40,$out - addi $out,$out,0x50 - bne Lxts_enc6x_steal - b Lxts_enc6x_done - -.align 4 -Lxts_enc6x_four: - vxor $out0,$in2,$twk0 - vxor $out1,$in3,$twk1 - vxor $out2,$in4,$twk2 - vxor $out3,$in5,$twk3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_enc5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk4 # unused tweak - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - vxor $tmp,$out3,$twk4 # last block prep for stealing - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - stvx_u $out3,$x30,$out - addi $out,$out,0x40 - bne Lxts_enc6x_steal - b Lxts_enc6x_done - -.align 4 -Lxts_enc6x_three: - vxor $out0,$in3,$twk0 - vxor $out1,$in4,$twk1 - vxor $out2,$in5,$twk2 - vxor $out3,$out3,$out3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_enc5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk3 # unused tweak - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $tmp,$out2,$twk3 # last block prep for stealing - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - stvx_u $out2,$x20,$out - addi $out,$out,0x30 - bne Lxts_enc6x_steal - b Lxts_enc6x_done - -.align 4 -Lxts_enc6x_two: - vxor $out0,$in4,$twk0 - vxor $out1,$in5,$twk1 - vxor $out2,$out2,$out2 - vxor $out3,$out3,$out3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_enc5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk2 # unused tweak - vxor $tmp,$out1,$twk2 # last block prep for stealing - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - stvx_u $out1,$x10,$out - addi $out,$out,0x20 - bne Lxts_enc6x_steal - b Lxts_enc6x_done - -.align 4 -Lxts_enc6x_one: - vxor $out0,$in5,$twk0 - nop -Loop_xts_enc1x: - vcipher $out0,$out0,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vcipher $out0,$out0,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_xts_enc1x - - add $inp,$inp,$taillen - cmpwi $taillen,0 - vcipher $out0,$out0,v24 - - subi $inp,$inp,16 - vcipher $out0,$out0,v25 - - lvsr $inpperm,0,$taillen - vcipher $out0,$out0,v26 - - lvx_u $in0,0,$inp - vcipher $out0,$out0,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vcipher $out0,$out0,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - - vcipher $out0,$out0,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vxor $twk0,$twk0,v31 - - le?vperm $in0,$in0,$in0,$leperm - vcipher $out0,$out0,v30 - - vperm $in0,$in0,$in0,$inpperm - vcipherlast $out0,$out0,$twk0 - - vmr $twk0,$twk1 # unused tweak - vxor $tmp,$out0,$twk1 # last block prep for stealing - le?vperm $out0,$out0,$out0,$leperm - stvx_u $out0,$x00,$out # store output - addi $out,$out,0x10 - bne Lxts_enc6x_steal - b Lxts_enc6x_done - -.align 4 -Lxts_enc6x_zero: - cmpwi $taillen,0 - beq Lxts_enc6x_done - - add $inp,$inp,$taillen - subi $inp,$inp,16 - lvx_u $in0,0,$inp - lvsr $inpperm,0,$taillen # $in5 is no more - le?vperm $in0,$in0,$in0,$leperm - vperm $in0,$in0,$in0,$inpperm - vxor $tmp,$tmp,$twk0 -Lxts_enc6x_steal: - vxor $in0,$in0,$twk0 - vxor $out0,$out0,$out0 - vspltisb $out1,-1 - vperm $out0,$out0,$out1,$inpperm - vsel $out0,$in0,$tmp,$out0 # $tmp is last block, remember? - - subi r30,$out,17 - subi $out,$out,16 - mtctr $taillen -Loop_xts_enc6x_steal: - lbzu r0,1(r30) - stb r0,16(r30) - bdnz Loop_xts_enc6x_steal - - li $taillen,0 - mtctr $rounds - b Loop_xts_enc1x # one more time... - -.align 4 -Lxts_enc6x_done: - ${UCMP}i $ivp,0 - beq Lxts_enc6x_ret - - vxor $tweak,$twk0,$rndkey0 - le?vperm $tweak,$tweak,$tweak,$leperm - stvx_u $tweak,0,$ivp - -Lxts_enc6x_ret: - mtlr r11 - li r10,`$FRAME+15` - li r11,`$FRAME+31` - stvx $seven,r10,$sp # wipe copies of round keys - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - - mtspr 256,$vrsave - lvx v20,r10,$sp # ABI says so - addi r10,r10,32 - lvx v21,r11,$sp - addi r11,r11,32 - lvx v22,r10,$sp - addi r10,r10,32 - lvx v23,r11,$sp - addi r11,r11,32 - lvx v24,r10,$sp - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp - $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) - $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) - $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) - $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) - $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) - $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) - addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` - blr - .long 0 - .byte 0,12,0x04,1,0x80,6,6,0 - .long 0 - -.align 5 -_aesp8_xts_enc5x: - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vcipher $out4,$out4,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vcipher $out4,$out4,v25 - lvx v25,$x10,$key_ # round[4] - bdnz _aesp8_xts_enc5x - - add $inp,$inp,$taillen - cmpwi $taillen,0 - vcipher $out0,$out0,v24 - vcipher $out1,$out1,v24 - vcipher $out2,$out2,v24 - vcipher $out3,$out3,v24 - vcipher $out4,$out4,v24 - - subi $inp,$inp,16 - vcipher $out0,$out0,v25 - vcipher $out1,$out1,v25 - vcipher $out2,$out2,v25 - vcipher $out3,$out3,v25 - vcipher $out4,$out4,v25 - vxor $twk0,$twk0,v31 - - vcipher $out0,$out0,v26 - lvsr $inpperm,0,$taillen # $in5 is no more - vcipher $out1,$out1,v26 - vcipher $out2,$out2,v26 - vcipher $out3,$out3,v26 - vcipher $out4,$out4,v26 - vxor $in1,$twk1,v31 - - vcipher $out0,$out0,v27 - lvx_u $in0,0,$inp - vcipher $out1,$out1,v27 - vcipher $out2,$out2,v27 - vcipher $out3,$out3,v27 - vcipher $out4,$out4,v27 - vxor $in2,$twk2,v31 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vcipher $out0,$out0,v28 - vcipher $out1,$out1,v28 - vcipher $out2,$out2,v28 - vcipher $out3,$out3,v28 - vcipher $out4,$out4,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - vxor $in3,$twk3,v31 - - vcipher $out0,$out0,v29 - le?vperm $in0,$in0,$in0,$leperm - vcipher $out1,$out1,v29 - vcipher $out2,$out2,v29 - vcipher $out3,$out3,v29 - vcipher $out4,$out4,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vxor $in4,$twk4,v31 - - vcipher $out0,$out0,v30 - vperm $in0,$in0,$in0,$inpperm - vcipher $out1,$out1,v30 - vcipher $out2,$out2,v30 - vcipher $out3,$out3,v30 - vcipher $out4,$out4,v30 - - vcipherlast $out0,$out0,$twk0 - vcipherlast $out1,$out1,$in1 - vcipherlast $out2,$out2,$in2 - vcipherlast $out3,$out3,$in3 - vcipherlast $out4,$out4,$in4 - blr - .long 0 - .byte 0,12,0x14,0,0,0,0,0 - -.align 5 -_aesp8_xts_decrypt6x: - $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) - mflr r11 - li r7,`$FRAME+8*16+15` - li r3,`$FRAME+8*16+31` - $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) - stvx v20,r7,$sp # ABI says so - addi r7,r7,32 - stvx v21,r3,$sp - addi r3,r3,32 - stvx v22,r7,$sp - addi r7,r7,32 - stvx v23,r3,$sp - addi r3,r3,32 - stvx v24,r7,$sp - addi r7,r7,32 - stvx v25,r3,$sp - addi r3,r3,32 - stvx v26,r7,$sp - addi r7,r7,32 - stvx v27,r3,$sp - addi r3,r3,32 - stvx v28,r7,$sp - addi r7,r7,32 - stvx v29,r3,$sp - addi r3,r3,32 - stvx v30,r7,$sp - stvx v31,r3,$sp - li r0,-1 - stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave - li $x10,0x10 - $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) - li $x20,0x20 - $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) - li $x30,0x30 - $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) - li $x40,0x40 - $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) - li $x50,0x50 - $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) - li $x60,0x60 - $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) - li $x70,0x70 - mtspr 256,r0 - - subi $rounds,$rounds,3 # -4 in total - - lvx $rndkey0,$x00,$key1 # load key schedule - lvx v30,$x10,$key1 - addi $key1,$key1,0x20 - lvx v31,$x00,$key1 - ?vperm $rndkey0,$rndkey0,v30,$keyperm - addi $key_,$sp,`$FRAME+15` - mtctr $rounds - -Load_xts_dec_key: - ?vperm v24,v30,v31,$keyperm - lvx v30,$x10,$key1 - addi $key1,$key1,0x20 - stvx v24,$x00,$key_ # off-load round[1] - ?vperm v25,v31,v30,$keyperm - lvx v31,$x00,$key1 - stvx v25,$x10,$key_ # off-load round[2] - addi $key_,$key_,0x20 - bdnz Load_xts_dec_key - - lvx v26,$x10,$key1 - ?vperm v24,v30,v31,$keyperm - lvx v27,$x20,$key1 - stvx v24,$x00,$key_ # off-load round[3] - ?vperm v25,v31,v26,$keyperm - lvx v28,$x30,$key1 - stvx v25,$x10,$key_ # off-load round[4] - addi $key_,$sp,`$FRAME+15` # rewind $key_ - ?vperm v26,v26,v27,$keyperm - lvx v29,$x40,$key1 - ?vperm v27,v27,v28,$keyperm - lvx v30,$x50,$key1 - ?vperm v28,v28,v29,$keyperm - lvx v31,$x60,$key1 - ?vperm v29,v29,v30,$keyperm - lvx $twk5,$x70,$key1 # borrow $twk5 - ?vperm v30,v30,v31,$keyperm - lvx v24,$x00,$key_ # pre-load round[1] - ?vperm v31,v31,$twk5,$keyperm - lvx v25,$x10,$key_ # pre-load round[2] - - vperm $in0,$inout,$inptail,$inpperm - subi $inp,$inp,31 # undo "caller" - vxor $twk0,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vand $tmp,$tmp,$eighty7 - vxor $out0,$in0,$twk0 - vxor $tweak,$tweak,$tmp - - lvx_u $in1,$x10,$inp - vxor $twk1,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in1,$in1,$in1,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out1,$in1,$twk1 - vxor $tweak,$tweak,$tmp - - lvx_u $in2,$x20,$inp - andi. $taillen,$len,15 - vxor $twk2,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in2,$in2,$in2,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out2,$in2,$twk2 - vxor $tweak,$tweak,$tmp - - lvx_u $in3,$x30,$inp - sub $len,$len,$taillen - vxor $twk3,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in3,$in3,$in3,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out3,$in3,$twk3 - vxor $tweak,$tweak,$tmp - - lvx_u $in4,$x40,$inp - subi $len,$len,0x60 - vxor $twk4,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in4,$in4,$in4,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out4,$in4,$twk4 - vxor $tweak,$tweak,$tmp - - lvx_u $in5,$x50,$inp - addi $inp,$inp,0x60 - vxor $twk5,$tweak,$rndkey0 - vsrab $tmp,$tweak,$seven # next tweak value - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - le?vperm $in5,$in5,$in5,$leperm - vand $tmp,$tmp,$eighty7 - vxor $out5,$in5,$twk5 - vxor $tweak,$tweak,$tmp - - vxor v31,v31,$rndkey0 - mtctr $rounds - b Loop_xts_dec6x - -.align 5 -Loop_xts_dec6x: - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_xts_dec6x - - subic $len,$len,96 # $len-=96 - vxor $in0,$twk0,v31 # xor with last round key - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk0,$tweak,$rndkey0 - vaddubm $tweak,$tweak,$tweak - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vsldoi $tmp,$tmp,$tmp,15 - vncipher $out4,$out4,v24 - vncipher $out5,$out5,v24 - - subfe. r0,r0,r0 # borrow?-1:0 - vand $tmp,$tmp,$eighty7 - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vxor $tweak,$tweak,$tmp - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vxor $in1,$twk1,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk1,$tweak,$rndkey0 - vncipher $out4,$out4,v25 - vncipher $out5,$out5,v25 - - and r0,r0,$len - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vncipher $out0,$out0,v26 - vncipher $out1,$out1,v26 - vand $tmp,$tmp,$eighty7 - vncipher $out2,$out2,v26 - vncipher $out3,$out3,v26 - vxor $tweak,$tweak,$tmp - vncipher $out4,$out4,v26 - vncipher $out5,$out5,v26 - - add $inp,$inp,r0 # $inp is adjusted in such - # way that at exit from the - # loop inX-in5 are loaded - # with last "words" - vxor $in2,$twk2,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk2,$tweak,$rndkey0 - vaddubm $tweak,$tweak,$tweak - vncipher $out0,$out0,v27 - vncipher $out1,$out1,v27 - vsldoi $tmp,$tmp,$tmp,15 - vncipher $out2,$out2,v27 - vncipher $out3,$out3,v27 - vand $tmp,$tmp,$eighty7 - vncipher $out4,$out4,v27 - vncipher $out5,$out5,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vxor $tweak,$tweak,$tmp - vncipher $out0,$out0,v28 - vncipher $out1,$out1,v28 - vxor $in3,$twk3,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk3,$tweak,$rndkey0 - vncipher $out2,$out2,v28 - vncipher $out3,$out3,v28 - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vncipher $out4,$out4,v28 - vncipher $out5,$out5,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - vand $tmp,$tmp,$eighty7 - - vncipher $out0,$out0,v29 - vncipher $out1,$out1,v29 - vxor $tweak,$tweak,$tmp - vncipher $out2,$out2,v29 - vncipher $out3,$out3,v29 - vxor $in4,$twk4,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk4,$tweak,$rndkey0 - vncipher $out4,$out4,v29 - vncipher $out5,$out5,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - - vncipher $out0,$out0,v30 - vncipher $out1,$out1,v30 - vand $tmp,$tmp,$eighty7 - vncipher $out2,$out2,v30 - vncipher $out3,$out3,v30 - vxor $tweak,$tweak,$tmp - vncipher $out4,$out4,v30 - vncipher $out5,$out5,v30 - vxor $in5,$twk5,v31 - vsrab $tmp,$tweak,$seven # next tweak value - vxor $twk5,$tweak,$rndkey0 - - vncipherlast $out0,$out0,$in0 - lvx_u $in0,$x00,$inp # load next input block - vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 - vncipherlast $out1,$out1,$in1 - lvx_u $in1,$x10,$inp - vncipherlast $out2,$out2,$in2 - le?vperm $in0,$in0,$in0,$leperm - lvx_u $in2,$x20,$inp - vand $tmp,$tmp,$eighty7 - vncipherlast $out3,$out3,$in3 - le?vperm $in1,$in1,$in1,$leperm - lvx_u $in3,$x30,$inp - vncipherlast $out4,$out4,$in4 - le?vperm $in2,$in2,$in2,$leperm - lvx_u $in4,$x40,$inp - vxor $tweak,$tweak,$tmp - vncipherlast $out5,$out5,$in5 - le?vperm $in3,$in3,$in3,$leperm - lvx_u $in5,$x50,$inp - addi $inp,$inp,0x60 - le?vperm $in4,$in4,$in4,$leperm - le?vperm $in5,$in5,$in5,$leperm - - le?vperm $out0,$out0,$out0,$leperm - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk0 - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - vxor $out1,$in1,$twk1 - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - vxor $out2,$in2,$twk2 - le?vperm $out4,$out4,$out4,$leperm - stvx_u $out3,$x30,$out - vxor $out3,$in3,$twk3 - le?vperm $out5,$out5,$out5,$leperm - stvx_u $out4,$x40,$out - vxor $out4,$in4,$twk4 - stvx_u $out5,$x50,$out - vxor $out5,$in5,$twk5 - addi $out,$out,0x60 - - mtctr $rounds - beq Loop_xts_dec6x # did $len-=96 borrow? - - addic. $len,$len,0x60 - beq Lxts_dec6x_zero - cmpwi $len,0x20 - blt Lxts_dec6x_one - nop - beq Lxts_dec6x_two - cmpwi $len,0x40 - blt Lxts_dec6x_three - nop - beq Lxts_dec6x_four - -Lxts_dec6x_five: - vxor $out0,$in1,$twk0 - vxor $out1,$in2,$twk1 - vxor $out2,$in3,$twk2 - vxor $out3,$in4,$twk3 - vxor $out4,$in5,$twk4 - - bl _aesp8_xts_dec5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk5 # unused tweak - vxor $twk1,$tweak,$rndkey0 - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk1 - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - le?vperm $out4,$out4,$out4,$leperm - stvx_u $out3,$x30,$out - stvx_u $out4,$x40,$out - addi $out,$out,0x50 - bne Lxts_dec6x_steal - b Lxts_dec6x_done - -.align 4 -Lxts_dec6x_four: - vxor $out0,$in2,$twk0 - vxor $out1,$in3,$twk1 - vxor $out2,$in4,$twk2 - vxor $out3,$in5,$twk3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_dec5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk4 # unused tweak - vmr $twk1,$twk5 - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk5 - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - le?vperm $out3,$out3,$out3,$leperm - stvx_u $out2,$x20,$out - stvx_u $out3,$x30,$out - addi $out,$out,0x40 - bne Lxts_dec6x_steal - b Lxts_dec6x_done - -.align 4 -Lxts_dec6x_three: - vxor $out0,$in3,$twk0 - vxor $out1,$in4,$twk1 - vxor $out2,$in5,$twk2 - vxor $out3,$out3,$out3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_dec5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk3 # unused tweak - vmr $twk1,$twk4 - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk4 - le?vperm $out2,$out2,$out2,$leperm - stvx_u $out1,$x10,$out - stvx_u $out2,$x20,$out - addi $out,$out,0x30 - bne Lxts_dec6x_steal - b Lxts_dec6x_done - -.align 4 -Lxts_dec6x_two: - vxor $out0,$in4,$twk0 - vxor $out1,$in5,$twk1 - vxor $out2,$out2,$out2 - vxor $out3,$out3,$out3 - vxor $out4,$out4,$out4 - - bl _aesp8_xts_dec5x - - le?vperm $out0,$out0,$out0,$leperm - vmr $twk0,$twk2 # unused tweak - vmr $twk1,$twk3 - le?vperm $out1,$out1,$out1,$leperm - stvx_u $out0,$x00,$out # store output - vxor $out0,$in0,$twk3 - stvx_u $out1,$x10,$out - addi $out,$out,0x20 - bne Lxts_dec6x_steal - b Lxts_dec6x_done - -.align 4 -Lxts_dec6x_one: - vxor $out0,$in5,$twk0 - nop -Loop_xts_dec1x: - vncipher $out0,$out0,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out0,$out0,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Loop_xts_dec1x - - subi r0,$taillen,1 - vncipher $out0,$out0,v24 - - andi. r0,r0,16 - cmpwi $taillen,0 - vncipher $out0,$out0,v25 - - sub $inp,$inp,r0 - vncipher $out0,$out0,v26 - - lvx_u $in0,0,$inp - vncipher $out0,$out0,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vncipher $out0,$out0,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - - vncipher $out0,$out0,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vxor $twk0,$twk0,v31 - - le?vperm $in0,$in0,$in0,$leperm - vncipher $out0,$out0,v30 - - mtctr $rounds - vncipherlast $out0,$out0,$twk0 - - vmr $twk0,$twk1 # unused tweak - vmr $twk1,$twk2 - le?vperm $out0,$out0,$out0,$leperm - stvx_u $out0,$x00,$out # store output - addi $out,$out,0x10 - vxor $out0,$in0,$twk2 - bne Lxts_dec6x_steal - b Lxts_dec6x_done - -.align 4 -Lxts_dec6x_zero: - cmpwi $taillen,0 - beq Lxts_dec6x_done - - lvx_u $in0,0,$inp - le?vperm $in0,$in0,$in0,$leperm - vxor $out0,$in0,$twk1 -Lxts_dec6x_steal: - vncipher $out0,$out0,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out0,$out0,v25 - lvx v25,$x10,$key_ # round[4] - bdnz Lxts_dec6x_steal - - add $inp,$inp,$taillen - vncipher $out0,$out0,v24 - - cmpwi $taillen,0 - vncipher $out0,$out0,v25 - - lvx_u $in0,0,$inp - vncipher $out0,$out0,v26 - - lvsr $inpperm,0,$taillen # $in5 is no more - vncipher $out0,$out0,v27 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vncipher $out0,$out0,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - - vncipher $out0,$out0,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vxor $twk1,$twk1,v31 - - le?vperm $in0,$in0,$in0,$leperm - vncipher $out0,$out0,v30 - - vperm $in0,$in0,$in0,$inpperm - vncipherlast $tmp,$out0,$twk1 - - le?vperm $out0,$tmp,$tmp,$leperm - le?stvx_u $out0,0,$out - be?stvx_u $tmp,0,$out - - vxor $out0,$out0,$out0 - vspltisb $out1,-1 - vperm $out0,$out0,$out1,$inpperm - vsel $out0,$in0,$tmp,$out0 - vxor $out0,$out0,$twk0 - - subi r30,$out,1 - mtctr $taillen -Loop_xts_dec6x_steal: - lbzu r0,1(r30) - stb r0,16(r30) - bdnz Loop_xts_dec6x_steal - - li $taillen,0 - mtctr $rounds - b Loop_xts_dec1x # one more time... - -.align 4 -Lxts_dec6x_done: - ${UCMP}i $ivp,0 - beq Lxts_dec6x_ret - - vxor $tweak,$twk0,$rndkey0 - le?vperm $tweak,$tweak,$tweak,$leperm - stvx_u $tweak,0,$ivp - -Lxts_dec6x_ret: - mtlr r11 - li r10,`$FRAME+15` - li r11,`$FRAME+31` - stvx $seven,r10,$sp # wipe copies of round keys - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - stvx $seven,r10,$sp - addi r10,r10,32 - stvx $seven,r11,$sp - addi r11,r11,32 - - mtspr 256,$vrsave - lvx v20,r10,$sp # ABI says so - addi r10,r10,32 - lvx v21,r11,$sp - addi r11,r11,32 - lvx v22,r10,$sp - addi r10,r10,32 - lvx v23,r11,$sp - addi r11,r11,32 - lvx v24,r10,$sp - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp - $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) - $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) - $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) - $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) - $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) - $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) - addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` - blr - .long 0 - .byte 0,12,0x04,1,0x80,6,6,0 - .long 0 - -.align 5 -_aesp8_xts_dec5x: - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - lvx v24,$x20,$key_ # round[3] - addi $key_,$key_,0x20 - - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - lvx v25,$x10,$key_ # round[4] - bdnz _aesp8_xts_dec5x - - subi r0,$taillen,1 - vncipher $out0,$out0,v24 - vncipher $out1,$out1,v24 - vncipher $out2,$out2,v24 - vncipher $out3,$out3,v24 - vncipher $out4,$out4,v24 - - andi. r0,r0,16 - cmpwi $taillen,0 - vncipher $out0,$out0,v25 - vncipher $out1,$out1,v25 - vncipher $out2,$out2,v25 - vncipher $out3,$out3,v25 - vncipher $out4,$out4,v25 - vxor $twk0,$twk0,v31 - - sub $inp,$inp,r0 - vncipher $out0,$out0,v26 - vncipher $out1,$out1,v26 - vncipher $out2,$out2,v26 - vncipher $out3,$out3,v26 - vncipher $out4,$out4,v26 - vxor $in1,$twk1,v31 - - vncipher $out0,$out0,v27 - lvx_u $in0,0,$inp - vncipher $out1,$out1,v27 - vncipher $out2,$out2,v27 - vncipher $out3,$out3,v27 - vncipher $out4,$out4,v27 - vxor $in2,$twk2,v31 - - addi $key_,$sp,`$FRAME+15` # rewind $key_ - vncipher $out0,$out0,v28 - vncipher $out1,$out1,v28 - vncipher $out2,$out2,v28 - vncipher $out3,$out3,v28 - vncipher $out4,$out4,v28 - lvx v24,$x00,$key_ # re-pre-load round[1] - vxor $in3,$twk3,v31 - - vncipher $out0,$out0,v29 - le?vperm $in0,$in0,$in0,$leperm - vncipher $out1,$out1,v29 - vncipher $out2,$out2,v29 - vncipher $out3,$out3,v29 - vncipher $out4,$out4,v29 - lvx v25,$x10,$key_ # re-pre-load round[2] - vxor $in4,$twk4,v31 - - vncipher $out0,$out0,v30 - vncipher $out1,$out1,v30 - vncipher $out2,$out2,v30 - vncipher $out3,$out3,v30 - vncipher $out4,$out4,v30 - - vncipherlast $out0,$out0,$twk0 - vncipherlast $out1,$out1,$in1 - vncipherlast $out2,$out2,$in2 - vncipherlast $out3,$out3,$in3 - vncipherlast $out4,$out4,$in4 - mtctr $rounds - blr - .long 0 - .byte 0,12,0x14,0,0,0,0,0 -___ -}} }}} - -my $consts=1; -foreach(split("\n",$code)) { - s/\`([^\`]*)\`/eval($1)/geo; - - # constants table endian-specific conversion - if ($consts && m/\.(long|byte)\s+(.+)\s+(\?[a-z]*)$/o) { - my $conv=$3; - my @bytes=(); - - # convert to endian-agnostic format - if ($1 eq "long") { - foreach (split(/,\s*/,$2)) { - my $l = /^0/?oct:int; - push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff; - } - } else { - @bytes = map(/^0/?oct:int,split(/,\s*/,$2)); - } - - # little-endian conversion - if ($flavour =~ /le$/o) { - SWITCH: for($conv) { - /\?inv/ && do { @bytes=map($_^0xf,@bytes); last; }; - /\?rev/ && do { @bytes=reverse(@bytes); last; }; - } - } - - #emit - print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n"; - next; - } - $consts=0 if (m/Lconsts:/o); # end of table - - # instructions prefixed with '?' are endian-specific and need - # to be adjusted accordingly... - if ($flavour =~ /le$/o) { # little-endian - s/le\?//o or - s/be\?/#be#/o or - s/\?lvsr/lvsl/o or - s/\?lvsl/lvsr/o or - s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or - s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or - s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o; - } else { # big-endian - s/le\?/#le#/o or - s/be\?//o or - s/\?([a-z]+)/$1/o; - } - - print $_,"\n"; -} - -close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl index 82022c77..9f62232e 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl @@ -975,6 +975,9 @@ if ($flavour =~ /64/) { ######## 64-bit code s/\.[ui]?64//o and s/\.16b/\.2d/go; s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o; + # Switch preprocessor checks to aarch64 versions. + s/__ARME([BL])__/__AARCH64E$1__/go; + print $_,"\n"; } } else { ######## 32-bit code diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/vpaes-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/vpaes-x86_64.pl index f6f67eaa..37e93d7a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/vpaes-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/asm/vpaes-x86_64.pl @@ -1288,6 +1288,7 @@ _vpaes_preheat: ## ## ######################################################## .type _vpaes_consts,\@object +.section .rodata .align 64 _vpaes_consts: .Lk_inv: # inv, inva @@ -1397,6 +1398,7 @@ _vpaes_consts: .asciz "Vector Permutation AES for x86_64/SSSE3, Mike Hamburg (Stanford University)" .align 64 .size _vpaes_consts,.-_vpaes_consts +.text ___ if ($win64) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/internal.h index 5b806955..98b2a14d 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/internal.h @@ -17,7 +17,7 @@ #include -#include +#include "../../internal.h" #if defined(__cplusplus) extern "C" { @@ -30,18 +30,14 @@ extern "C" { #define HWAES #define HWAES_ECB -OPENSSL_INLINE int hwaes_capable(void) { - return (OPENSSL_ia32cap_get()[1] & (1 << (57 - 32))) != 0; -} +OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_AESNI_capable(); } #define VPAES #if defined(OPENSSL_X86_64) #define VPAES_CTR32 #endif #define VPAES_CBC -OPENSSL_INLINE int vpaes_capable(void) { - return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0; -} +OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_SSSE3_capable(); } #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) #define HWAES @@ -63,12 +59,6 @@ OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } #endif -#elif defined(OPENSSL_PPC64LE) -#define HWAES - -OPENSSL_INLINE int hwaes_capable(void) { - return CRYPTO_is_PPC64LE_vcrypto_capable(); -} #endif #endif // !NO_ASM diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/key_wrap.c b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/key_wrap.c index 9a5b28da..95b12d28 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/key_wrap.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/key_wrap.c @@ -55,6 +55,7 @@ #include #include "../../internal.h" +#include "../service_indicator/internal.h" // kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. @@ -98,6 +99,7 @@ int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, } OPENSSL_memcpy(out, A, 8); + FIPS_service_indicator_update_state(); return (int)in_len + 8; } @@ -151,6 +153,7 @@ int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, return -1; } + FIPS_service_indicator_update_state(); return (int)in_len - 8; } @@ -161,10 +164,8 @@ static const uint8_t kPaddingConstant[4] = {0xa6, 0x59, 0x59, 0xa6}; int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, size_t max_out, const uint8_t *in, size_t in_len) { // See https://tools.ietf.org/html/rfc5649#section-4.1 - const uint32_t in_len32_be = CRYPTO_bswap4(in_len); const uint64_t in_len64 = in_len; const size_t padded_len = (in_len + 7) & ~7; - *out_len = 0; if (in_len == 0 || in_len64 > 0xffffffffu || in_len + 7 < in_len || padded_len + 8 < padded_len || max_out < padded_len + 8) { @@ -173,7 +174,7 @@ int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, uint8_t block[AES_BLOCK_SIZE]; memcpy(block, kPaddingConstant, sizeof(kPaddingConstant)); - memcpy(block + 4, &in_len32_be, sizeof(in_len32_be)); + CRYPTO_store_u32_be(block + 4, (uint32_t)in_len); if (in_len <= 8) { memset(block + 8, 0, 8); @@ -190,12 +191,15 @@ int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, assert(padded_len >= 8); memset(padded_in + padded_len - 8, 0, 8); memcpy(padded_in, in, in_len); + FIPS_service_indicator_lock_state(); const int ret = AES_wrap_key(key, block, out, padded_in, padded_len); + FIPS_service_indicator_unlock_state(); OPENSSL_free(padded_in); if (ret < 0) { return 0; } *out_len = ret; + FIPS_service_indicator_update_state(); return 1; } @@ -220,9 +224,7 @@ int AES_unwrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, crypto_word_t ok = constant_time_eq_int( CRYPTO_memcmp(iv, kPaddingConstant, sizeof(kPaddingConstant)), 0); - uint32_t claimed_len32; - memcpy(&claimed_len32, iv + 4, sizeof(claimed_len32)); - const size_t claimed_len = CRYPTO_bswap4(claimed_len32); + const size_t claimed_len = CRYPTO_load_u32_be(iv + 4); ok &= ~constant_time_is_zero_w(claimed_len); ok &= constant_time_eq_w((claimed_len - 1) >> 3, (in_len - 9) >> 3); @@ -232,5 +234,9 @@ int AES_unwrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, } *out_len = constant_time_select_w(ok, claimed_len, 0); - return ok & 1; + const int ret = ok & 1; + if (ret) { + FIPS_service_indicator_update_state(); + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/mode_wrappers.c b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/mode_wrappers.c index d29fb27e..10d98a6a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/aes/mode_wrappers.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/aes/mode_wrappers.c @@ -52,6 +52,7 @@ #include "../aes/internal.h" #include "../modes/internal.h" +#include "../service_indicator/internal.h" void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, @@ -74,6 +75,8 @@ void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num, aes_nohw_ctr32_encrypt_blocks); } + + FIPS_service_indicator_update_state(); } void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key, @@ -86,24 +89,23 @@ void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key, } else { AES_decrypt(in, out, key); } + + FIPS_service_indicator_update_state(); } void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, uint8_t *ivec, const int enc) { if (hwaes_capable()) { aes_hw_cbc_encrypt(in, out, len, key, ivec, enc); - return; - } - - if (!vpaes_capable()) { + } else if (!vpaes_capable()) { aes_nohw_cbc_encrypt(in, out, len, key, ivec, enc); - return; - } - if (enc) { + } else if (enc) { CRYPTO_cbc128_encrypt(in, out, len, key, ivec, AES_encrypt); } else { CRYPTO_cbc128_decrypt(in, out, len, key, ivec, AES_decrypt); } + + FIPS_service_indicator_update_state(); } void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bcm.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bcm.c index 3a1ad15d..8231eee6 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bcm.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bcm.c @@ -58,12 +58,13 @@ #include "cipher/aead.c" #include "cipher/cipher.c" #include "cipher/e_aes.c" -#include "cipher/e_des.c" -#include "des/des.c" +#include "cipher/e_aesccm.c" +#include "cmac/cmac.c" #include "dh/check.c" #include "dh/dh.c" #include "digest/digest.c" #include "digest/digests.c" +#include "digestsign/digestsign.c" #include "ecdh/ecdh.c" #include "ecdsa/ecdsa.c" #include "ec/ec.c" @@ -73,12 +74,13 @@ #include "ec/oct.c" #include "ec/p224-64.c" #include "ec/p256.c" -#include "ec/p256-x86_64.c" +#include "ec/p256-nistz.c" #include "ec/scalar.c" #include "ec/simple.c" #include "ec/simple_mul.c" #include "ec/util.c" #include "ec/wnaf.c" +#include "hkdf/hkdf.c" #include "hmac/hmac.c" #include "md4/md4.c" #include "md5/md5.c" @@ -99,7 +101,7 @@ #include "rsa/rsa_impl.c" #include "self_check/fips.c" #include "self_check/self_check.c" -#include "sha/sha1-altivec.c" +#include "service_indicator/service_indicator.c" #include "sha/sha1.c" #include "sha/sha256.c" #include "sha/sha512.c" @@ -171,6 +173,23 @@ BORINGSSL_bcm_power_on_self_test(void) { #if !defined(OPENSSL_ASAN) // Integrity tests cannot run under ASAN because it involves reading the full // .text section, which triggers the global-buffer overflow detection. + if (!BORINGSSL_integrity_test()) { + goto err; + } +#endif // OPENSSL_ASAN + + if (!boringssl_self_test_startup()) { + goto err; + } + + return; + +err: + BORINGSSL_FIPS_abort(); +} + +#if !defined(OPENSSL_ASAN) +int BORINGSSL_integrity_test(void) { const uint8_t *const start = BORINGSSL_bcm_text_start; const uint8_t *const end = BORINGSSL_bcm_text_end; @@ -192,17 +211,15 @@ BORINGSSL_bcm_power_on_self_test(void) { #endif assert_within(rodata_start, kPrimes, rodata_end); - assert_within(rodata_start, des_skb, rodata_end); assert_within(rodata_start, kP256Params, rodata_end); assert_within(rodata_start, kPKCS1SigPrefixes, rodata_end); -#if defined(OPENSSL_AARCH64) || defined(OPENSSL_ANDROID) uint8_t result[SHA256_DIGEST_LENGTH]; const EVP_MD *const kHashFunction = EVP_sha256(); -#else - uint8_t result[SHA512_DIGEST_LENGTH]; - const EVP_MD *const kHashFunction = EVP_sha512(); -#endif + if (!boringssl_self_test_sha256() || + !boringssl_self_test_hmac_sha256()) { + return 0; + } static const uint8_t kHMACKey[64] = {0}; unsigned result_len; @@ -211,7 +228,7 @@ BORINGSSL_bcm_power_on_self_test(void) { if (!HMAC_Init_ex(&hmac_ctx, kHMACKey, sizeof(kHMACKey), kHashFunction, NULL /* no ENGINE */)) { fprintf(stderr, "HMAC_Init_ex failed.\n"); - goto err; + return 0; } BORINGSSL_maybe_set_module_text_permissions(PROT_READ | PROT_EXEC); @@ -231,30 +248,22 @@ BORINGSSL_bcm_power_on_self_test(void) { if (!HMAC_Final(&hmac_ctx, result, &result_len) || result_len != sizeof(result)) { fprintf(stderr, "HMAC failed.\n"); - goto err; + return 0; } - HMAC_CTX_cleanup(&hmac_ctx); + HMAC_CTX_cleanse(&hmac_ctx); // FIPS 140-3, AS05.10. const uint8_t *expected = BORINGSSL_bcm_text_hash; if (!check_test(expected, result, sizeof(result), "FIPS integrity test")) { - goto err; +#if !defined(BORINGSSL_FIPS_BREAK_TESTS) + return 0; +#endif } - if (!boringssl_fips_self_test(BORINGSSL_bcm_text_hash, sizeof(result))) { - goto err; - } -#else - if (!BORINGSSL_self_test()) { - goto err; - } -#endif // OPENSSL_ASAN - - return; - -err: - BORINGSSL_FIPS_abort(); + OPENSSL_cleanse(result, sizeof(result)); // FIPS 140-3, AS05.10. + return 1; } +#endif // OPENSSL_ASAN void BORINGSSL_FIPS_abort(void) { for (;;) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/bn-armv8.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/bn-armv8.pl new file mode 100755 index 00000000..5aed8df1 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/bn-armv8.pl @@ -0,0 +1,118 @@ +#!/usr/bin/env perl +# Copyright (c) 2023, Google Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; + +my $flavour = shift; +my $output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; +my $dir = $1; +my $xlate; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT, "| \"$^X\" \"$xlate\" $flavour \"$output\""; +*STDOUT = *OUT; + +my ($rp, $ap, $bp, $num) = ("x0", "x1", "x2", "x3"); +my ($a0, $a1, $b0, $b1, $num_pairs) = ("x4", "x5", "x6", "x7", "x8"); +my $code = <<____; +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_add_words, %function +.globl bn_add_words +.align 4 +bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split $num = 2 * $num_pairs + $num. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr $num_pairs, $num, #1 + and $num, $num, #1 + + cbz $num_pairs, .Ladd_tail +.Ladd_loop: + ldp $a0, $a1, [$ap], #16 + ldp $b0, $b1, [$bp], #16 + sub $num_pairs, $num_pairs, #1 + adcs $a0, $a0, $b0 + adcs $a1, $a1, $b1 + stp $a0, $a1, [$rp], #16 + cbnz $num_pairs, .Ladd_loop + +.Ladd_tail: + cbz $num, .Ladd_exit + ldr $a0, [$ap], #8 + ldr $b0, [$bp], #8 + adcs $a0, $a0, $b0 + str $a0, [$rp], #8 + +.Ladd_exit: + cset x0, cs + ret +.size bn_add_words,.-bn_add_words + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); +.type bn_sub_words, %function +.globl bn_sub_words +.align 4 +bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split $num = 2 * $num_pairs + $num. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr $num_pairs, $num, #1 + and $num, $num, #1 + + cbz $num_pairs, .Lsub_tail +.Lsub_loop: + ldp $a0, $a1, [$ap], #16 + ldp $b0, $b1, [$bp], #16 + sub $num_pairs, $num_pairs, #1 + sbcs $a0, $a0, $b0 + sbcs $a1, $a1, $b1 + stp $a0, $a1, [$rp], #16 + cbnz $num_pairs, .Lsub_loop + +.Lsub_tail: + cbz $num, .Lsub_exit + ldr $a0, [$ap], #8 + ldr $b0, [$bp], #8 + sbcs $a0, $a0, $b0 + str $a0, [$rp], #8 + +.Lsub_exit: + cset x0, cc + ret +size bn_sub_words,.-bn_sub_words +____ + +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/rsaz-avx2.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/rsaz-avx2.pl index 65b0062a..9be0b140 100755 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/rsaz-avx2.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/rsaz-avx2.pl @@ -1738,6 +1738,7 @@ ___ } $code.=<<___; +.section .rodata .align 64 .Land_mask: .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1750,6 +1751,7 @@ $code.=<<___; .long 2,2,2,2, 3,3,3,3 .long 4,4,4,4, 4,4,4,4 .align 64 +.text ___ if ($win64) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/x86_64-mont5.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/x86_64-mont5.pl index 54335cc9..67ffc4a2 100755 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/x86_64-mont5.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/asm/x86_64-mont5.pl @@ -158,8 +158,12 @@ $code.=<<___; movdqa %xmm1,%xmm2 ___ ######################################################################## -# calculate mask by comparing 0..31 to index and save result to stack +# Calculate masks by comparing 0..31 to $idx and save result to stack. # +# We compute sixteen 16-byte masks and store them on the stack. Mask i is stored +# in `16*i - 128`(%rax) and contains the comparisons for idx == 2*i and +# idx == 2*i + 1 in its lower and upper halves, respectively. Mask calculations +# are scheduled in groups of four. $code.=<<___; paddd %xmm0,%xmm1 pcmpeqd %xmm5,%xmm0 # compare to 1,0 @@ -228,7 +232,8 @@ ___ } $code.=<<___; por %xmm1,%xmm0 - pshufd \$0x4e,%xmm0,%xmm1 + # Combine the upper and lower halves of %xmm0. + pshufd \$0x4e,%xmm0,%xmm1 # Swap upper and lower halves. por %xmm1,%xmm0 lea $STRIDE($bp),$bp movq %xmm0,$m0 # m0=bp[0] @@ -321,7 +326,8 @@ ___ } $code.=<<___; por %xmm5,%xmm4 - pshufd \$0x4e,%xmm4,%xmm0 + # Combine the upper and lower halves of %xmm4 as %xmm0. + pshufd \$0x4e,%xmm4,%xmm0 # Swap upper and lower halves. por %xmm4,%xmm0 lea $STRIDE($bp),$bp @@ -575,7 +581,6 @@ mul4x_internal: ___ $bp="%r12"; $STRIDE=2**5*8; # 5 is "window size" - $N=$STRIDE/4; # should match cache line size $tp=$i; $code.=<<___; movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000 @@ -589,8 +594,12 @@ $code.=<<___; movdqa %xmm1,%xmm2 ___ ######################################################################## -# calculate mask by comparing 0..31 to index and save result to stack +# Calculate masks by comparing 0..31 to $idx and save result to stack. # +# We compute sixteen 16-byte masks and store them on the stack. Mask i is stored +# in `16*i - 128`(%rax) and contains the comparisons for idx == 2*i and +# idx == 2*i + 1 in its lower and upper halves, respectively. Mask calculations +# are scheduled in groups of four. $code.=<<___; paddd %xmm0,%xmm1 pcmpeqd %xmm5,%xmm0 # compare to 1,0 @@ -659,7 +668,8 @@ ___ } $code.=<<___; por %xmm1,%xmm0 - pshufd \$0x4e,%xmm0,%xmm1 + # Combine the upper and lower halves of %xmm0. + pshufd \$0x4e,%xmm0,%xmm1 # Swap upper and lower halves. por %xmm1,%xmm0 lea $STRIDE($bp),$bp movq %xmm0,$m0 # m0=bp[0] @@ -836,7 +846,8 @@ ___ } $code.=<<___; por %xmm5,%xmm4 - pshufd \$0x4e,%xmm4,%xmm0 + # Combine the upper and lower halves of %xmm4 as %xmm0. + pshufd \$0x4e,%xmm4,%xmm0 # Swap upper and lower halves. por %xmm4,%xmm0 lea $STRIDE($bp),$bp movq %xmm0,$m0 # m0=bp[i] @@ -2088,194 +2099,6 @@ __bn_post4x_internal: .size __bn_post4x_internal,.-__bn_post4x_internal ___ } -{ -$code.=<<___; -.globl bn_from_montgomery -.type bn_from_montgomery,\@abi-omnipotent -.align 32 -bn_from_montgomery: -.cfi_startproc - testl \$7,`($win64?"48(%rsp)":"%r9d")` - jz bn_from_mont8x - xor %eax,%eax - ret -.cfi_endproc -.size bn_from_montgomery,.-bn_from_montgomery - -.type bn_from_mont8x,\@function,6 -.align 32 -bn_from_mont8x: -.cfi_startproc - .byte 0x67 - mov %rsp,%rax -.cfi_def_cfa_register %rax - push %rbx -.cfi_push %rbx - push %rbp -.cfi_push %rbp - push %r12 -.cfi_push %r12 - push %r13 -.cfi_push %r13 - push %r14 -.cfi_push %r14 - push %r15 -.cfi_push %r15 -.Lfrom_prologue: - - shl \$3,${num}d # convert $num to bytes - lea ($num,$num,2),%r10 # 3*$num in bytes - neg $num - mov ($n0),$n0 # *n0 - - ############################################################## - # Ensure that stack frame doesn't alias with $rptr+3*$num - # modulo 4096, which covers ret[num], am[num] and n[num] - # (see bn_exp.c). The stack is allocated to aligned with - # bn_power5's frame, and as bn_from_montgomery happens to be - # last operation, we use the opportunity to cleanse it. - # - lea -320(%rsp,$num,2),%r11 - mov %rsp,%rbp - sub $rptr,%r11 - and \$4095,%r11 - cmp %r11,%r10 - jb .Lfrom_sp_alt - sub %r11,%rbp # align with $aptr - lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) - jmp .Lfrom_sp_done - -.align 32 -.Lfrom_sp_alt: - lea 4096-320(,$num,2),%r10 - lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) - sub %r10,%r11 - mov \$0,%r10 - cmovc %r10,%r11 - sub %r11,%rbp -.Lfrom_sp_done: - and \$-64,%rbp - mov %rsp,%r11 - sub %rbp,%r11 - and \$-4096,%r11 - lea (%rbp,%r11),%rsp - mov (%rsp),%r10 - cmp %rbp,%rsp - ja .Lfrom_page_walk - jmp .Lfrom_page_walk_done - -.Lfrom_page_walk: - lea -4096(%rsp),%rsp - mov (%rsp),%r10 - cmp %rbp,%rsp - ja .Lfrom_page_walk -.Lfrom_page_walk_done: - - mov $num,%r10 - neg $num - - ############################################################## - # Stack layout - # - # +0 saved $num, used in reduction section - # +8 &t[2*$num], used in reduction section - # +32 saved *n0 - # +40 saved %rsp - # +48 t[2*$num] - # - mov $n0, 32(%rsp) - mov %rax, 40(%rsp) # save original %rsp -.cfi_cfa_expression %rsp+40,deref,+8 -.Lfrom_body: - mov $num,%r11 - lea 48(%rsp),%rax - pxor %xmm0,%xmm0 - jmp .Lmul_by_1 - -.align 32 -.Lmul_by_1: - movdqu ($aptr),%xmm1 - movdqu 16($aptr),%xmm2 - movdqu 32($aptr),%xmm3 - movdqa %xmm0,(%rax,$num) - movdqu 48($aptr),%xmm4 - movdqa %xmm0,16(%rax,$num) - .byte 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 # lea 64($aptr),$aptr - movdqa %xmm1,(%rax) - movdqa %xmm0,32(%rax,$num) - movdqa %xmm2,16(%rax) - movdqa %xmm0,48(%rax,$num) - movdqa %xmm3,32(%rax) - movdqa %xmm4,48(%rax) - lea 64(%rax),%rax - sub \$64,%r11 - jnz .Lmul_by_1 - - movq $rptr,%xmm1 - movq $nptr,%xmm2 - .byte 0x67 - mov $nptr,%rbp - movq %r10, %xmm3 # -num -___ -$code.=<<___ if ($addx); - leaq OPENSSL_ia32cap_P(%rip),%r11 - mov 8(%r11),%r11d - and \$0x80108,%r11d - cmp \$0x80108,%r11d # check for AD*X+BMI2+BMI1 - jne .Lfrom_mont_nox - - lea (%rax,$num),$rptr - call __bn_sqrx8x_reduction - call __bn_postx4x_internal - - pxor %xmm0,%xmm0 - lea 48(%rsp),%rax - jmp .Lfrom_mont_zero - -.align 32 -.Lfrom_mont_nox: -___ -$code.=<<___; - call __bn_sqr8x_reduction - call __bn_post4x_internal - - pxor %xmm0,%xmm0 - lea 48(%rsp),%rax - jmp .Lfrom_mont_zero - -.align 32 -.Lfrom_mont_zero: - mov 40(%rsp),%rsi # restore %rsp -.cfi_def_cfa %rsi,8 - movdqa %xmm0,16*0(%rax) - movdqa %xmm0,16*1(%rax) - movdqa %xmm0,16*2(%rax) - movdqa %xmm0,16*3(%rax) - lea 16*4(%rax),%rax - sub \$32,$num - jnz .Lfrom_mont_zero - - mov \$1,%rax - mov -48(%rsi),%r15 -.cfi_restore %r15 - mov -40(%rsi),%r14 -.cfi_restore %r14 - mov -32(%rsi),%r13 -.cfi_restore %r13 - mov -24(%rsi),%r12 -.cfi_restore %r12 - mov -16(%rsi),%rbp -.cfi_restore %rbp - mov -8(%rsi),%rbx -.cfi_restore %rbx - lea (%rsi),%rsp -.cfi_def_cfa_register %rsp -.Lfrom_epilogue: - ret -.cfi_endproc -.size bn_from_mont8x,.-bn_from_mont8x -___ -} }}} if ($addx) {{{ @@ -2415,7 +2238,6 @@ my ($aptr, $bptr, $nptr, $tptr, $mi, $bi, $zero, $num)= ("%rsi","%rdi","%rcx","%rbx","%r8","%r9","%rbp","%rax"); my $rptr=$bptr; my $STRIDE=2**5*8; # 5 is "window size" -my $N=$STRIDE/4; # should match cache line size $code.=<<___; movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000 movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002 @@ -2428,8 +2250,12 @@ $code.=<<___; movdqa %xmm1,%xmm2 ___ ######################################################################## -# calculate mask by comparing 0..31 to index and save result to stack +# Calculate masks by comparing 0..31 to $idx and save result to stack. # +# We compute sixteen 16-byte masks and store them on the stack. Mask i is stored +# in `16*i - 128`(%rax) and contains the comparisons for idx == 2*i and +# idx == 2*i + 1 in its lower and upper halves, respectively. Mask calculations +# are scheduled in groups of four. $code.=<<___; .byte 0x67 paddd %xmm0,%xmm1 @@ -2498,7 +2324,8 @@ ___ } $code.=<<___; pxor %xmm1,%xmm0 - pshufd \$0x4e,%xmm0,%xmm1 + # Combine the upper and lower halves of %xmm0. + pshufd \$0x4e,%xmm0,%xmm1 # Swap upper and lower halves. por %xmm1,%xmm0 lea $STRIDE($bptr),$bptr movq %xmm0,%rdx # bp[0] @@ -2618,7 +2445,8 @@ ___ } $code.=<<___; por %xmm5,%xmm4 - pshufd \$0x4e,%xmm4,%xmm0 + # Combine the upper and lower halves of %xmm4 as %xmm0. + pshufd \$0x4e,%xmm4,%xmm0 # Swap upper and lower halves. por %xmm4,%xmm0 lea $STRIDE($bptr),$bptr movq %xmm0,%rdx # m0=bp[i] @@ -3622,6 +3450,15 @@ bn_scatter5: .cfi_startproc cmp \$0, $num jz .Lscatter_epilogue + + # $tbl stores 32 entries, t0 through t31. Each entry has $num words. + # They are interleaved in memory as follows: + # + # t0[0] t1[0] t2[0] ... t31[0] + # t0[1] t1[1] t2[1] ... t31[1] + # ... + # t0[$num-1] t1[$num-1] t2[$num-1] ... t31[$num-1] + lea ($tbl,$idx,8),$tbl .Lscatter: mov ($inp),%rax @@ -3659,8 +3496,12 @@ bn_gather5: movdqa %xmm1,%xmm2 ___ ######################################################################## -# calculate mask by comparing 0..31 to $idx and save result to stack +# Calculate masks by comparing 0..31 to $idx and save result to stack. # +# We compute sixteen 16-byte masks and store them on the stack. Mask i is stored +# in `16*i - 128`(%rax) and contains the comparisons for idx == 2*i and +# idx == 2*i + 1 in its lower and upper halves, respectively. Mask calculations +# are scheduled in groups of four. for($i=0;$i<$STRIDE/16;$i+=4) { $code.=<<___; paddd %xmm0,%xmm1 @@ -3698,6 +3539,8 @@ $code.=<<___; pxor %xmm5,%xmm5 ___ for($i=0;$i<$STRIDE/16;$i+=4) { +# Combine the masks with the corresponding table entries to select the correct +# entry. $code.=<<___; movdqa `16*($i+0)-128`(%r11),%xmm0 movdqa `16*($i+1)-128`(%r11),%xmm1 @@ -3716,7 +3559,8 @@ ___ $code.=<<___; por %xmm5,%xmm4 lea $STRIDE(%r11),%r11 - pshufd \$0x4e,%xmm4,%xmm0 + # Combine the upper and lower halves of %xmm0. + pshufd \$0x4e,%xmm4,%xmm0 # Swap upper and lower halves. por %xmm4,%xmm0 movq %xmm0,($out) # m0=bp[0] lea 8($out),$out @@ -3732,11 +3576,13 @@ $code.=<<___; ___ } $code.=<<___; +.section .rodata .align 64 .Linc: .long 0,0, 1,1 .long 2,2, 2,2 .asciz "Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by " +.text ___ # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, @@ -3864,10 +3710,6 @@ mul_handler: .rva .LSEH_begin_bn_power5 .rva .LSEH_end_bn_power5 .rva .LSEH_info_bn_power5 - - .rva .LSEH_begin_bn_from_mont8x - .rva .LSEH_end_bn_from_mont8x - .rva .LSEH_info_bn_from_mont8x ___ $code.=<<___ if ($addx); .rva .LSEH_begin_bn_mulx4x_mont_gather5 @@ -3899,11 +3741,6 @@ $code.=<<___; .byte 9,0,0,0 .rva mul_handler .rva .Lpower5_prologue,.Lpower5_body,.Lpower5_epilogue # HandlerData[] -.align 8 -.LSEH_info_bn_from_mont8x: - .byte 9,0,0,0 - .rva mul_handler - .rva .Lfrom_prologue,.Lfrom_body,.Lfrom_epilogue # HandlerData[] ___ $code.=<<___ if ($addx); .align 8 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn.c index 424d4621..d7d86263 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn.c @@ -56,6 +56,7 @@ #include +#include #include #include @@ -66,11 +67,15 @@ #include "../delocate.h" +// BN_MAX_WORDS is the maximum number of words allowed in a |BIGNUM|. It is +// sized so byte and bit counts of a |BIGNUM| always fit in |int|, with room to +// spare. +#define BN_MAX_WORDS (INT_MAX / (4 * BN_BITS2)) + BIGNUM *BN_new(void) { BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM)); if (bn == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -80,6 +85,8 @@ BIGNUM *BN_new(void) { return bn; } +BIGNUM *BN_secure_new(void) { return BN_new(); } + void BN_init(BIGNUM *bn) { OPENSSL_memset(bn, 0, sizeof(BIGNUM)); } @@ -289,8 +296,9 @@ void bn_set_static_words(BIGNUM *bn, const BN_ULONG *words, size_t num) { } bn->d = (BN_ULONG *)words; - bn->width = num; - bn->dmax = num; + assert(num <= BN_MAX_WORDS); + bn->width = (int)num; + bn->dmax = (int)num; bn->neg = 0; bn->flags |= BN_FLG_STATIC_DATA; } @@ -343,7 +351,7 @@ int bn_wexpand(BIGNUM *bn, size_t words) { return 1; } - if (words > (INT_MAX / (4 * BN_BITS2))) { + if (words > BN_MAX_WORDS) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); return 0; } @@ -355,7 +363,6 @@ int bn_wexpand(BIGNUM *bn, size_t words) { a = OPENSSL_malloc(sizeof(BN_ULONG) * words); if (a == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return 0; } @@ -377,30 +384,13 @@ int bn_expand(BIGNUM *bn, size_t bits) { } int bn_resize_words(BIGNUM *bn, size_t words) { -#if defined(OPENSSL_PPC64LE) - // This is a workaround for a miscompilation bug in Clang 7.0.1 on POWER. - // The unittests catch the miscompilation, if it occurs, and it manifests - // as a crash in |bn_fits_in_words|. - // - // The bug only triggers if building in FIPS mode and with -O3. Clang 8.0.1 - // has the same bug but this workaround is not effective there---I've not - // been able to find a workaround for 8.0.1. - // - // At the time of writing (2019-08-08), Clang git does *not* have this bug - // and does not need this workaroud. The current git version should go on to - // be Clang 10 thus, once we can depend on that, this can be removed. - if (value_barrier_w((size_t)bn->width == words)) { - return 1; - } -#endif - if ((size_t)bn->width <= words) { if (!bn_wexpand(bn, words)) { return 0; } OPENSSL_memset(bn->d + bn->width, 0, (words - bn->width) * sizeof(BN_ULONG)); - bn->width = words; + bn->width = (int)words; return 1; } @@ -409,15 +399,15 @@ int bn_resize_words(BIGNUM *bn, size_t words) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); return 0; } - bn->width = words; + bn->width = (int)words; return 1; } void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, const BN_ULONG *b, size_t num) { for (size_t i = 0; i < num; i++) { - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); r[i] = constant_time_select_w(mask, a[i], b[i]); } } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test.cc index 72ec8c2f..92da5f2f 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test.cc @@ -74,6 +74,7 @@ #include #include +#include #include #include @@ -908,6 +909,14 @@ static void TestModInv(BIGNUMFileTest *t, BN_CTX *ctx) { bn_mod_inverse_consttime(ret.get(), &no_inverse, a.get(), m.get(), ctx)); EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (constant-time)", mod_inv.get(), ret.get()); + + ASSERT_TRUE(BN_copy(ret.get(), m.get())); + ASSERT_TRUE(BN_mod_inverse(ret.get(), a.get(), ret.get(), ctx)); + EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (ret == m)", mod_inv.get(), ret.get()); + + ASSERT_TRUE(BN_copy(ret.get(), a.get())); + ASSERT_TRUE(BN_mod_inverse(ret.get(), ret.get(), m.get(), ctx)); + EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (ret == a)", mod_inv.get(), ret.get()); } static void TestGCD(BIGNUMFileTest *t, BN_CTX *ctx) { @@ -978,7 +987,7 @@ class BNTest : public testing::Test { bssl::UniquePtr ctx_; }; -TEST_F(BNTest, TestVectors) { +static void RunBNFileTest(FileTest *t, BN_CTX *ctx) { static const struct { const char *name; void (*func)(BIGNUMFileTest *t, BN_CTX *ctx); @@ -999,37 +1008,84 @@ TEST_F(BNTest, TestVectors) { {"ModInv", TestModInv}, {"GCD", TestGCD}, }; - - FileTestGTest("crypto/fipsmodule/bn/bn_tests.txt", [&](FileTest *t) { - void (*func)(BIGNUMFileTest *t, BN_CTX *ctx) = nullptr; - for (const auto &test : kTests) { - if (t->GetType() == test.name) { - func = test.func; - break; - } - } - if (!func) { - FAIL() << "Unknown test type: " << t->GetType(); - return; + void (*func)(BIGNUMFileTest * t, BN_CTX * ctx) = nullptr; + for (const auto &test : kTests) { + if (t->GetType() == test.name) { + func = test.func; + break; } + } + if (!func) { + FAIL() << "Unknown test type: " << t->GetType(); + return; + } - // Run the test with normalize-sized |BIGNUM|s. - BIGNUMFileTest bn_test(t, 0); - BN_CTX_start(ctx()); - func(&bn_test, ctx()); - BN_CTX_end(ctx()); - unsigned num_bignums = bn_test.num_bignums(); + // Run the test with normalize-sized |BIGNUM|s. + BIGNUMFileTest bn_test(t, 0); + BN_CTX_start(ctx); + func(&bn_test, ctx); + BN_CTX_end(ctx); + unsigned num_bignums = bn_test.num_bignums(); - // Repeat the test with all combinations of large and small |BIGNUM|s. - for (unsigned large_mask = 1; large_mask < (1u << num_bignums); - large_mask++) { - SCOPED_TRACE(large_mask); - BIGNUMFileTest bn_test2(t, large_mask); - BN_CTX_start(ctx()); - func(&bn_test2, ctx()); - BN_CTX_end(ctx()); - } - }); + // Repeat the test with all combinations of large and small |BIGNUM|s. + for (unsigned large_mask = 1; large_mask < (1u << num_bignums); + large_mask++) { + SCOPED_TRACE(large_mask); + BIGNUMFileTest bn_test2(t, large_mask); + BN_CTX_start(ctx); + func(&bn_test2, ctx); + BN_CTX_end(ctx); + } +} + +TEST_F(BNTest, ExpTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/exp_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, GCDTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/gcd_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ModExpTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/mod_exp_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ModInvTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/mod_inv_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ModMulTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/mod_mul_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ModSqrtTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/mod_sqrt_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ProductTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/product_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, QuotientTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/quotient_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, ShiftTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/shift_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); +} + +TEST_F(BNTest, SumTestVectors) { + FileTestGTest("crypto/fipsmodule/bn/test/sum_tests.txt", + [&](FileTest *t) { RunBNFileTest(t, ctx()); }); } TEST_F(BNTest, BN2BinPadded) { @@ -2324,7 +2380,7 @@ TEST_F(BNTest, PrimeChecking) { TEST_F(BNTest, MillerRabinIteration) { FileTestGTest( - "crypto/fipsmodule/bn/miller_rabin_tests.txt", [&](FileTest *t) { + "crypto/fipsmodule/bn/test/miller_rabin_tests.txt", [&](FileTest *t) { BIGNUMFileTest bn_test(t, /*large_mask=*/0); bssl::UniquePtr w = bn_test.GetBIGNUM("W"); @@ -2712,6 +2768,99 @@ TEST_F(BNTest, WriteIntoNegative) { EXPECT_FALSE(BN_is_negative(r.get())); } +TEST_F(BNTest, ModSqrtInvalid) { + bssl::UniquePtr bn2140141 = ASCIIToBIGNUM("2140141"); + ASSERT_TRUE(bn2140141); + bssl::UniquePtr bn2140142 = ASCIIToBIGNUM("2140142"); + ASSERT_TRUE(bn2140142); + bssl::UniquePtr bn4588033 = ASCIIToBIGNUM("4588033"); + ASSERT_TRUE(bn4588033); + + // |BN_mod_sqrt| may fail or return an arbitrary value, so we do not use + // |TestModSqrt| or |TestNotModSquare|. We only promise it will not crash or + // infinite loop. (For some invalid inputs, it may even be non-deterministic.) + // See CVE-2022-0778. + BN_free(BN_mod_sqrt(nullptr, bn2140141.get(), bn4588033.get(), ctx())); + BN_free(BN_mod_sqrt(nullptr, bn2140142.get(), bn4588033.get(), ctx())); +} + +// Test that constructing Montgomery contexts for large bignums is not possible. +// Our Montgomery reduction implementation stack-allocates temporaries, so we +// cap how large of moduli we accept. +TEST_F(BNTest, MontgomeryLarge) { + std::vector large_bignum_bytes(16 * 1024, 0xff); + bssl::UniquePtr large_bignum( + BN_bin2bn(large_bignum_bytes.data(), large_bignum_bytes.size(), nullptr)); + ASSERT_TRUE(large_bignum); + bssl::UniquePtr mont( + BN_MONT_CTX_new_for_modulus(large_bignum.get(), ctx())); + EXPECT_FALSE(mont); + + // The same limit should apply when |BN_mod_exp_mont_consttime| internally + // constructs a |BN_MONT_CTX|. + bssl::UniquePtr r(BN_new()); + ASSERT_TRUE(r); + EXPECT_FALSE(BN_mod_exp_mont_consttime(r.get(), BN_value_one(), + large_bignum.get(), large_bignum.get(), + ctx(), nullptr)); +} + +TEST_F(BNTest, FormatWord) { + char buf[32]; + snprintf(buf, sizeof(buf), BN_DEC_FMT1, BN_ULONG{1234}); + EXPECT_STREQ(buf, "1234"); + snprintf(buf, sizeof(buf), BN_HEX_FMT1, BN_ULONG{1234}); + EXPECT_STREQ(buf, "4d2"); + + // |BN_HEX_FMT2| is zero-padded up to the maximum value. +#if defined(OPENSSL_64_BIT) + snprintf(buf, sizeof(buf), BN_HEX_FMT2, BN_ULONG{1234}); + EXPECT_STREQ(buf, "00000000000004d2"); + snprintf(buf, sizeof(buf), BN_HEX_FMT2, std::numeric_limits::max()); + EXPECT_STREQ(buf, "ffffffffffffffff"); +#else + snprintf(buf, sizeof(buf), BN_HEX_FMT2, BN_ULONG{1234}); + EXPECT_STREQ(buf, "000004d2"); + snprintf(buf, sizeof(buf), BN_HEX_FMT2, std::numeric_limits::max()); + EXPECT_STREQ(buf, "ffffffff"); +#endif +} + +#if defined(SUPPORTS_ABI_TEST) +// These functions are not always implemented in assembly, but they sometimes +// are, so include ABI tests for each. +TEST_F(BNTest, ArithmeticABI) { + EXPECT_EQ(0u, CHECK_ABI(bn_add_words, nullptr, nullptr, nullptr, 0)); + EXPECT_EQ(0u, CHECK_ABI(bn_sub_words, nullptr, nullptr, nullptr, 0)); + + for (size_t num : + {1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65}) { + SCOPED_TRACE(num); + std::vector a(num, 123456789); + std::vector b(num, static_cast(-1)); + std::vector r(num); + + CHECK_ABI(bn_add_words, r.data(), a.data(), b.data(), num); + CHECK_ABI(bn_sub_words, r.data(), a.data(), b.data(), num); + + CHECK_ABI(bn_mul_words, r.data(), a.data(), num, 42); + CHECK_ABI(bn_mul_add_words, r.data(), a.data(), num, 42); + + r.resize(2 * num); + CHECK_ABI(bn_sqr_words, r.data(), a.data(), num); + + if (num == 4) { + CHECK_ABI(bn_mul_comba4, r.data(), a.data(), b.data()); + CHECK_ABI(bn_sqr_comba4, r.data(), a.data()); + } + if (num == 8) { + CHECK_ABI(bn_mul_comba8, r.data(), a.data(), b.data()); + CHECK_ABI(bn_sqr_comba8, r.data(), a.data()); + } + } +} +#endif + #if defined(OPENSSL_BN_ASM_MONT) && defined(SUPPORTS_ABI_TEST) TEST_F(BNTest, BNMulMontABI) { for (size_t words : {4, 5, 6, 7, 8, 16, 32}) { @@ -2772,15 +2921,6 @@ TEST_F(BNTest, BNMulMont5ABI) { words, 13); CHECK_ABI(bn_power5, r.data(), a.data(), table.data(), m->d, mont->n0, words, 13); - EXPECT_EQ(1, CHECK_ABI(bn_from_montgomery, r.data(), r.data(), nullptr, - m->d, mont->n0, words)); - EXPECT_EQ(1, CHECK_ABI(bn_from_montgomery, r.data(), a.data(), nullptr, - m->d, mont->n0, words)); - } else { - EXPECT_EQ(0, CHECK_ABI(bn_from_montgomery, r.data(), r.data(), nullptr, - m->d, mont->n0, words)); - EXPECT_EQ(0, CHECK_ABI(bn_from_montgomery, r.data(), a.data(), nullptr, - m->d, mont->n0, words)); } } } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go index d1ee734c..2915db5f 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -21,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/big" "os" "path/filepath" @@ -139,7 +140,7 @@ func checkKeys(t test, keys ...string) bool { } } - for k, _ := range t.Values { + for k := range t.Values { var found bool for _, k2 := range keys { if k == k2 { @@ -221,8 +222,8 @@ func main() { if len(fuzzer) != 0 { hash := sha1.Sum(b) - path := filepath.Join(fuzzerDir, fuzzer + "_corpus", hex.EncodeToString(hash[:])) - if err := ioutil.WriteFile(path, b, 0666); err != nil { + path := filepath.Join(fuzzerDir, fuzzer+"_corpus", hex.EncodeToString(hash[:])) + if err := os.WriteFile(path, b, 0666); err != nil { fmt.Fprintf(os.Stderr, "Error writing to %s: %s.\n", path, err) os.Exit(1) } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_tests.txt deleted file mode 100644 index b4ad32c0..00000000 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bn_tests.txt +++ /dev/null @@ -1,11542 +0,0 @@ -# Sum tests. -# -# These test vectors satisfy A + B = Sum. - -Sum = 0 -A = 0 -B = 0 - -Sum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -A = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -B = 0 - -Sum = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -A = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -B = 0 - -Sum = 0 -A = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -B = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d - -Sum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 23f85668bf4d0fa273d8c7f63c5fee57811062a674111e295a73a58e08dd0fd58eda1f473960559d5b96d1862164e96efded31f756df3f57c - -Sum = c590e57ee64fceccd54e0bdc52476a756d32e794922dca0acc780d2c6af8852351102b40dfb97009f95e019a5bf38e5d127aa78bc34425edf96f763084a8b09f -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4b5b16252ba2355e0b87f01baa721783c403607a4c1b5652c09a68e96926c8e314fa580bf0ad3f8f59bd70f14df86a4676661899b54c79a62 - -Sum = -c590e57ee64fcec882fef3ffd015a3fd9024d8f5f6d53eb537d6abdb0ff5e76a8fb08d5feed113fc9e74745d957adf32704a08339ba42efd5746c5d478e3f57b -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 908007a2f3c551c58958d1059427a0391d4d768f61cb802e4cb062c778354ea3eaa8f0dfbd14ca8203e07ae6d07269b58088a39f7608c5586 - -Sum = -c590e57ee64fceeb242f8a0893eaa0d2ccc3dc57ec40fe917cfde66618fba678ce0c8fffc566d4e8c7944d6443def8014fe8ee410a1b8dfd06cb0b436619e0dd -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1999301bd9877fe07ca711f308b2f1bc4a704fd194ec4dbc297355d6285340d6ad7e90cb0add1770aea19737a06750c3a7a6fa0b778ca995dc - -Sum = c590e57ee64fcef321395bba088ca0a867e1e85a1ea77478f8783e6a6cf8f3e582bff83cb2d7d9fd549fcbb40dea22ac140351007030059500bdca81413600e9 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 219639ed8afc21e052422fff0ae5583231ebca2999404b099628093e6540b1dbc20b9c495aa7229b5965b19a5fcd653b3fa0eccab567c5b5e8 - -Sum = c590e57ee64fce834a00cc6282cb0eef49eac7a8d5b51988cb49253ed85ae261c76f2327a691fc63eceab02614807048b2816cdb9b89ca66a17b6ed1abdab580 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4e40fea1cc899fb166dbc721a6639a28be4164ef92545307ed934796afcb9401d75c18d23352471709fbd049c50740ffeebe5590fa2d959581 - -Sum = -c590e57ee64fce1a17609c61ce02f1020c6eb6e241e3fdd01546ce7247725589de32db95f36718d410f9ce9a94fecc8fb205e876fde75ce83f4d01e1bd5d818d -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = b7739ed1cd3e67cf541943326cf76b4476f767465ee53b94c57c83de417ebee5673809b3bed1c8bac2fc4bce29a4e36d6d2083fdea1c12c974 - -Sum = -c590e57ee64fd03e2d08c3d8e5110d08e3d36557d82e0e49b408337a8c9d4298802ae5f0145a9587531a70d2f8af932b8262245428b5c549817d333f2dfaeeec -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -16ca20955a9d8a64cb2be217c089edecc02a75a1ea95fef584925742c18a234974c0a16ee7991e80bd8d4106db385eafaf421ac3373548aa3eb - -Sum = c590e57ee64fd1bcac71b5b055e5934ba15dd7f56370063369c36e57a6b753269e085d0f4d38bfb711d5579dd1d89d07f266e727b232a497d5b0d9bfbc02d8a5 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2eb21724781497ad2f57babeea62a20c3ec5d1559867a0968d74351a337db12c17bc8d1d5446b1115b5441530870f67da4275dfd9f3e2928da4 - -Sum = c590e57ee64fc7860b0be6ce861bc2f099db7fb623912b7b0729c019a8183c669c73efe02b195483a4cd2c78244cd59678ac4d62f6887fe686a3eed37ed460ff -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -74b7ff38760864efd658bd6699915be16cc058454b78495ade8be42c9f7470ca9b7a43655e1427ab1bc35a5693dac424a6ed92d10f85a9bea02 - -Sum = -c590e57ee64fc3126776e79d9fca06233bd2ef5570a65e4521183627bdbdbc555e9118508cf63f519bc0caedbffd5b1a913ee8c3603804820a9ce54b1207bdef -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = bbf238886916ca0ba32e9def9f9c8a8e401eb95dea96ef02df9fc25a186e52fbee9ad42b76ba6ca2c381d12cddd4292c5d355341a80c7688d12 - -Sum = -c590e57ee64fe6dfd728dfbe45aee52380b5a00cf1e05e9f09ac582e2714bb589caf2ad038111c5b1b5573a45706ab1f6fd5d5a1ee7ef4a9bf186dca8a9ede12 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -180e4c29718f394424cd5b03b6bdb8911c57fcfe435cfa66d10941f870f8c5eb1e1fd251f14af03f23ccc1841f014bb42a545f476dfeb12e9311 - -Sum = c590e57ee65004b3e18a5820de4a6d25e7c3d310003e0b8716bbfd51d5f0f3e87fdf8e00599d713397255281e66ef419a9d9bb228e8f052764f5f861ccca656f -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 35e2568ae9f1d1dfaccfc211e9c0c6eec9400a0de880a94309992528d428e77772f84e21d0287fa76cc6fb880481ebc43ad20524f895f35a1a6e - -Sum = c590e57ee64f84896a5f11f575d34b6001f27d4b4d6e7cd9485260629f8f7f1c6ca6f6115b98d776774295dde4d59cdbbceccad097a0a054b501bfb47d81e85c -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4a4820a05c39969774f623bf6c03ebe0c56dc45bb46e8d1e6b32ee0fc3c6168d26c4d1c0ec7b81f1ea76f164ebd00b2a2a00aacf40175bee62a5 - -Sum = -c590e57ee64edf1b2b57b4cbb92d778ea6b9d9878a0374d4ea81691b09811b105bb6dbf23a57d89264f0e6c83f8d00fe00681644feed56e15fc81103ab9b7dd6 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = efb65fa7b963533d48c77ef80fc7af4bcd72222cabb6232ccf3efeffdde537ce25a8e4129b91273a8654ade9a05ba3dd73740008eec82dd4cd2b - -Sum = -c590e57ee650e25da7b60146e014f472bfff9809aa8f519db7943f69d9ad09ee75a3427c6127cce7bd27f224b9dec03111fb066956b4903f9f9740cce1aa4ba7 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1138c1cb69317d3aa341c9a4daeba71400f56aae62a98acff1f9f1aec88a4ef01ceac74246fcb531738de63a94fc8b3e9c5ea3fc64101083a00a6 - -Sum = c590e57ee653af8752322840ed720f628f9674c81073b58372e49ef26d4a2a9d46a0391bc170336614b27849de98709a4b321da4ddfb978e9f10df29154edb9f -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3e0b5c732ba11e1074f0c69e48b78d724733c66368a21409c404debe97f444f4a352acbaef5f077d0e9479ce067043b30cd393f3fdf5d3bde909e - -Sum = c590e57ee64bc13634cbd149aae35ee47bde6ea3663f74ff300cfdb2d845f902f017586c6d4f83f08c3b4f0c035055d13fc9d340b7b9ed164432aed44e8f4d7c -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -40d9b56339ce561876171a9d37aabd30fcd47dca1171e5467f14c6a9f616b04d67a4abcc8334d637731816e87e35feb10dd3f1b9e50f78ae0fd85 - -Sum = -c590e57ee6477eb692705f8da1357e71591336907a5e0a6e39715088d53b2610882765357563fd101bcf05ca545a0c718f52879fdf4f80cb9a12cf108eca60ed -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 8501af88f0ea16b3541e4cc9eb2bebef137d8d33cc4485772c43ed28f54a1fcc2012b2d347c8f126d7ae11eff2f00c37b4989c5be30bb4aa5ea14 - -Sum = -c590e57ee669b662e37f5abf13d00d2f0c1c9a8b99ec546361aad255f375bc2742a3487c351c5ba00efef09c77331577460a47c57125c620b643e9eaf36a146b -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -19e791587fec9007654cd8e66ab13c609d121c54fcbd84c6c7d1d7e7ec8ea4c2f65d64c5fb6e43106b8e2497b89124ce5afbcb5672ea1f19f9c96a - -Sum = c590e57ee681dcbf1554f22c0b1ffead917dd414299cb37ce6967ffec9c333931e70358729843c8130ac95aba47fa1fa5da74000eff25eecae176f093a4effca -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 320ded8a5583fcfeb53e576bcbeac4f04d7135d9e86b2d9d154943c3b97bafb75e3e45e7a913523db81aa7af5589604d2794974e466f3d60deb4c9 - -Sum = c590e57ee5e505ae4a2e1f25a1ae9b7b4d17dd2cccc09f2416d964e55af6d0d31fe259c160f87646a72e6732d5110256b3b35425225d622b81418435c9dd8cc4 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -6ac92340d14f096abc24dad89a0c226c8ea322f5d4afebd1b7197c3ad46016112d87f4a1d51b2691b684fbfa9e627b806d6829de8f7b960f92be3d - -Sum = -c590e57ee58c3ef1582bf7a516e36f92b60f5a587e2c8cb071d1d52ff215854e52de1519fd5204fa52292dfdc397d8d76b78005941358b63a3e6ca41b0eb09b7 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = c38fe032d37689f58750c36fa28ef6bb22b5969adc3fa13a98650107d8a4bd74d3f940f6da545ba32fae7b42d9b64761953ef1bbea358a2885414a - -Sum = -c590e57ee80262967da4038a143f8ff2e78646108f25ff7183444ba507d76f9b05a34c8310e682c05495d0863ceff264964dbfa7c064adf6d26d2dca6e22ab13 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1b293c4f2a4955b07d4cf9cc1d45cc155d6bd2a769636d3db29854baaec92ab9ec084850b924e2cd6286b11e7fc09071d99e3a1729c2dfe94b26012 - -Sum = c590e57ee85427f08e8c89ffebfcc05c73370ad4cb77696c2b2f3878e6f6df341d4d931b5097aba49f14ac0312e7da1c843d6fd08119822e75e6e7a8c7bcb7b0 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 204591f038d1bd0df9200064d852185922827251e8123a7ba48f4e4c296d943de71ad69561129a9ac2052c9d5ebb92fde4eb7d91615e7dcee4c6caf - -Sum = c590e57ee051ca1a363c47a4cc016c3de7f7e17985009b545528289e9fbc9086f4b42a73826eca0c278b0d1b4ef6d74b9a0bfcb7855d40fdb201fbad1074b927 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -5fe04b754c3268a406954183dba07d5b44ea6f2b785ec328cf159c866028f63efb7342f2178753e17d0b0071445b9e91d6d8957adcf041ec8fb91da - -Sum = -c590e57edcd6e9ef06fe33f3817ba3d0c50c8122b77615c4b8fa50c5514f113d7ba53ce057d487bcbc373c4384d07b29a527b7ef785ca609474879b42a9a4c3a -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 978e4e284013a3b8aef1c8560a5682c81d92c8253b3c40bdb5ed911df117cf71a51767e8ccc4615e1f70c290929feb12a6e244c18888617aed5fec7 - -Sum = -c590e57f0436bdceb586a093522eb1630e0fc08f8790957aba1875a42b7676f9ca936e8f6f3478d6ef5cd590bf6ded0700440dcd769496822af8015f0a6ba2b6 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1de6eefd2a87326445c3f10ce85dd7404e415333ad6a60d2fec88caa6fdcb4b7fd0e7a9ba659533758a665b451f2572cd3c9cc2ccb27019330fb57b5 - -Sum = c590e57f1df3f004d5e49f49fa28603b26659f1fd35e0d8d7a2753591dbc12c51e6b588427dbe3faba2f0c1f2f0a2aea9ba1fcb2fe71c6ff40555058d23c8661 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 37a421334ae5311aedbd9fe500b3b5d09a0ecb466d793e87f10e2875c3b49eacb5b5e5bf712b89c5c842a397ed5046125ba6fca9e084508cf8cc3b60 - -Sum = c590e57e9a4abf4572fa7c4c9f73e9d3fd1227646fd6d15b51924bd7a5d417b01fe6b4273eaa6ece387422b81c8116f29702d7d66d2f6e8c3454807b3b7d413c -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4c050f8c1804f1e26cf6d682289fc1eac97870ebbb1bc8f986d9d29f3ad005b0337b8f6d108f5fa14a467060174edeca359b5bc92b7c7f509df309c5 - -Sum = -c590e57e64216c306f17017ac9dd7085113e16c83168664dbb77c7ad3ddfc79b09f9ea0c474a0b497ca15e7fb258eed9666fd009f691a3b2d691c2c6b22ba3b3 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 822e62a11be86cb4428d4fd11473d28707e6dbf951364d23eece22b450bccfcb2adbf2f1cc6223d9b46e987947e1e696ac3926a2893f3d052744a74e - -Sum = -c590e5806ab4d09773c4f94a4aac09f6ed7609eec1d0bafecb09e30f032f706e9adadc191ff9e6d7dccc821f7a8666a590e521749d24912c5a5ffeff246f7c85 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1846501c5e8c58b1b3e4149a0c7c4209f888178b7be5bce3dd681861f40242241add3e89c93c8ffc613bedf52e2936ad3fa59c6d6fa8eff334aff3184 - -Sum = c590e58248cbf5dd61ec57994fc862ab479dc6cda51cc17356c45cef66bbfdd12f5cc421940a561581c123fb17483beb7a1cce2596fa9ca76e722a6f4621eae9 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3627c270bd6ece96a435da25521ebdd7e6bcd7f2c4a16481e3a0e1381d4a60a4a21e457da38bda1a1b080b498cbcb1784f42fd2520ea12aa36cb19fe8 - -Sum = c590e5771a85bdb1f26c0386ce837bec4b0af5656496efdf4f134d875f066dd6d477ca8f87ffb275da07da4dd1bed4232849a526836b47f2d69f2d53b6b3e2f1 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -7cbca111f98936aa83de74469daa6f3e9d4b85267bd9ac749cda77c78863eef47ea264bc56efba80b9508b32f8608117a1f5f82628931d27822bc6810 - -Sum = -c590e571c76afad23439f904e8a80fc28dcabb6cb732e361ed3eef471be6fa755e3fe746edbfe448c1f289ffed7dfc01fe9066d780564f57f93abbca9b9a995a -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = d1ee4d3ff56c5752a23c2b09397e72de2821c5ee51f6f258a10c6efd9fc76d290846619f28710f85979498b50afc14fc922747afd669644013dd5b1a7 - -Sum = -c590e598cd5d4a59ff5d6c97c6370fb517f1d492a7776f90063b0ddd6702e37c60fc78bb12857911cea37b7263584d7dc815676de6b8880200acea154b59b08b -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -19e70d7b88745dfe68b9cc4f5ef23feb436e282d48f98cf90c3a54f92d0645bee3a05f7ad6859ff918fc90c62b19c3b0cd43edbdaca0dbea4971e9658a - -Sum = c590e5b5829e6fceb77830fbe999a98127b50302fd0f6a86ea4aea27b846747a07e6fcf5457676e6446137d6bdd8ff4fb7ca747b650b066d65d7dc1e172488e7 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 369c4ea0fd2c78c2ccdd2ee92b020319b3c3c0283fdd9cd5568b988a2aad30431dd35078aafb5db57d571177fd0978bddac2403c180606dc523db43de6 - -Sum = c590e52a3ab5d5c458634254e2f672a322000750741e969d2f6cd12d172480ad1455300e3a0575b068b85d50b58f9737be13073188d0f03b71494bd0fd2fea16 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -54ab99f90d329c2bda29744db303b1e1fec530aba9dd4143a4158969a2466189c93820888ae04b2508b137f01af03eaf6f19f9da19ee87b3fadc4060eb - -Sum = -c590e4880579ef7241bde94e8c7847badc705f53828751f9975f0e66371d2ddff8740b143f32e88be8e686e2bf5a3ce03d864d7699a813b1777b9239af242c7d -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = f6e0d5df5f494184e07ff2789b494189fbb6c7f04d754f066af590bc6f6242aec332f315af601cfb76a76d4a7270cb692a0922b6a3e8556d922a4c1e84 - -Sum = -c590e6dbe54098694155509e38c61d503ab7e5237d2cdfc2b87fb57e3a8420fe37fe50a0dad4f0eae3d38fad6198e4ecaeae183a12078f53d09ac8099c715242 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -15cfef0c997b655e26f2c5b5cfa1505fbd443dd9d7babd1a0ad0dd636aedd4796c968aef2af9ad00d53fad15d9a005c61996f3cc4fe70c9c83dc3010741 - -Sum = c590e906254d013be2021ad591e76e26706a6815b8c484b6528fec65416e1066957002713e1183f1005f565983aad7aa031e549e6fc57094ca3e4383e7fdbc15 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3873efd326a5702aca6857cadd04ab87ec67f75426f45e1d79414c026173ab94899cbeb85b5b75bd4001ce3505754cc9dfdccfaa63f6a6d43b80e8d7114 - -Sum = c590e0e0079190d7afd80acd6326fe93cc00903318608df31ee4493d11271dac7291bd142cca0e5dd7dda59dabd460a69b7855d9c2acb5f062de76665e07cbd7 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -49edebe3df9db276361a943c1c259b1591c20eeb453edc9cb941b86cca2e824fcc3455befdd7125dcbbbaf326ac12d960c6e01e1464fcf289657b687f2a - -Sum = -c590d9ae456d66c1b132d844eb223867ba4560b36f53c42a616cf8cc657e6d252f813847fb9fc50127227684e5c0f5cd890eceb341d21e788e42f843e9b64080 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = bd0a0e2680fd9cc95ea214887ee6b6c889bc9fb7e1cab411c04c72f7d2a2b35818f7686393a21e10bd4810691852542e7ed60f8abdcd18e0787efba0a81 - -Sum = -c5910498291472fe1d0047d5bdd9e46deb3f26000e943fce8d83d700d9ae233ab3a28849bbb346803da142db6a471e9f79cd49571f40dbc46f7b727a4bb3016a -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1f1942c4a42c9200d9a6b16f2417c58d3cb0d544fd8780d5c22fad0038eb58ebce72498d4844f49dc082037f974ccb7b92b67c76116f0faa72ae7242b669 - -Sum = c59112d841ea109440e78563d9eefef201c81e86ae967083f8b7db80d1eaf58551d30519ca6dd79164fe69a29cf1ba22446cb2999f73292241005bf17b37528e -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2d595b9a41c2b5e81734cd843e9bdc16353775472e3cec09c6afa53d0b35f71c4b425847d9561bfae749362a32cf961afbf8fca85ecce12f5c25a1c7078d - -Sum = c590671f890ca06c74ac6d2c4d75aabeaaa55312e85a5e1ea9cef0e08e154e2b090eaba869e9f6e4a47ae10b9c1eb0f6ae4fb3ef12b3121d96066c6c8e592b6e -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -7e5f5d432e6516530102bef515977b0c963c50f4e42862df23f09e989c2451a80e2f083c0756a488a14dcaa8d65c000202b19017b837c9ca935f4b171f93 - -Sum = -c58ff0ae92ab03072154949a7143d45278ef77a0ba71a785d5a370e0d30a9b4b4f7e96a395d13e6afeebbd717365d471ee56ba11c472a63c0532558104bedfc5 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = f4d053a4cbca69aad9949b26ec03acc271ae7edd9ac1370aa3f059a34f040b382333dc54bfd04a17c4e7f361b2e0bffafc8ede5824195a9eaa4ad4b16b3c - -Sum = -c5927a5fcc3b31abeca3998ad99c07626112288a6ad95b24929fed581040757fdce73881c48b02daf09986ea436a3f5ceb6833c31fa2e1691567601a26c7a6c9 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -194e0e5eb62da61a42b5bcd31470c3b603f3b318a18dd85f1d886e3928b3082307eaa5265049fa7960490dca2b80a3d167d227cd81713b596604e4d575bc8 - -Sum = c59395e94d495451e3fea153f3e4361a088004a7d5426c1b94aec44108ad6f5cecc3a80dda0cea9f51b882747258137e171bf021b4fc59f4dcf0106d4ba952fa -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2b06a66f9858058ff3324e77975c3e2ce1b589bf329d48800af6fdbff850d920cee3667e6ec6408b5001b0b908c2b68ca398112318f9f7d1f10a1723907f9 - -Sum = c58bdb26c0fd6766f3affea389cbe7db25c06d5d56356d3d945347775bddf479ffc9e279e7d1ee88eddb239906749815ae4502fbbc6fe978a001ccdafd89cb10 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -50a582552676a974f6f8b829ed87afff17bf1e319d509785acd59d0cff5d55aecd75d8a540fb25b285ec06052ef3d000cb3a4e65ae0dcbfcf32f0dbe67ff1 - -Sum = -c581afe9b7ae86d4b7053f19649beea6cb935799a553f035f9b9a7fba6d5559e4ecdcd1637c73c8052c6cc52ee1c28d1e5aed9db7261b7356afd6e3dbc213684 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = f35952ea147fcd3fa2f15a7ced1af5a1e91b593fb521112f46cd585d894b10be8ecc13a5ec1baf63cb60678ab5e80c8a2dcc53069131ff4d3918e1d4f147d - -Sum = -c5a19f36a65a6a8d52a53a63f99a1b957d6e376b7010ad14695d78d67b0d7c86881006188bd27bbf205c8c9c200dc8f5c08ab6b97dcd512f6cb93ed9a361ff9f -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -10b9b7c00a9bbbc7a5cc34ed2f5b3f57bc4e1c36c16acd5caf64054e5f92372d594c4119ac7d83d7590a42b94641a312390018db0286da0ce83f0dc9f1b49e - -Sum = c5cd0e5da24b67a894402b0eee5dd586ab70e5beb0693e263a54995193663a9b770141379c1f097a49d1a889bbf0c348c6f40ed50bd7bdc11a7869c6106c6d80 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3c28debbfb98d70940bcdfe1f3153085befc6f7719fbdf2da6848066b8504c1c4a876029f90b3f00ce263055293bf618a25834690cf36bbaa769fa36fc227f - -Sum = c54e2c560a00226701b76cf03d5de27a8c69b38a6b85dad9f7c903d2e87f9a7d247522e72491460f6a529e5ca2aaaf690cb238b873ffb49d9fb0ecacfedd4e90 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -42b928dc4fac6a8948013ecf0cdddb994835c4cdc9676d14e510fe442e4fd2364196f04d94b82bdeb0e3fcc41cd7e9a19f7de82ecb15b7c020131eda92fc71 - -Sum = -c4bfb037f6e6e861efb090ee610c33e7568790259f747dc6e55d442aadd68c0cc93c7617f83980e8813c0fb7dd28c8aaca6ad8fdde5d2bfec9ae096faa9ef54e -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = d13546ef68e66f9b4edd40ab5e8c6ecf2a592999dac4802750d0a67ed75e42917a43bf79ec7d52c7c772a1899ebea7e3e6dda2c46d9e569622f65c2ed155b3 - -Sum = -c6aa2af8c9ae8be4aada83f66b7f31a8bce5e92c67d8938424a1405903e5502bffc4ee1e333da4bcfd0cb383b19a566372f877a8344b66dbceabc9786dd0e4f2 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1194579e35ebd131fdb15c75f1471529733ffdd2e89513d17f32b87d73765dca50e3446c117a681b409312a4ad2cf10c4a6c10791809c866edac9ac946099f1 - -Sum = c8aff66c9bdaa49eafac0f65d3ddff223b7a5471f7400431ca3a54615d600fc4a163f8fb648bddb5fd6915db1991611805040e0f86f152c8fd3333ef70d632e4 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 31f10edb58ad5cd24aca136c7733ecc15c86b22bdf0c1eabd8c3f9030b2257546ad3f23f265df7ab4659381b2c9d9c556b2576ee42688739d6234239765e7e3 - -Sum = be1b6eb768e2cef388eebe31f9b21e51b38b351cc8175eba06d49eef04c2936f32167174dcb82297fd4180d0afb5da2c455d158c7a5bf01bdef8c295a4f20390 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -77576c77d6cffde0210affd12b8a2047226b4327137e38d05d975e227eb56e028a04862956ddba34bc20188b711ad2668f4a114286eda3980d83d36347e4771 - -Sum = -ba32fca1d5cc5f31ecaf5407f376d3aef9f4abc04fd4c6893721d3e50e9141abf356eb2ff6f7a4f9b42983148670d2918e1dff7aa7ae33a6e9dadcb708b4f9dc -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = b5de8dd10836f9f9e501a2718f3eca72bbd3d8ee97a7bbdd58c40ec1e1ca8a3675fcea77b2e594194d9ff44e056b4c12033b725fb1c96ae75f62314d0bb5125 - -Sum = -e388afbf17c495f86aa7298a45f848eb57e5baaee42b1f7de8c2311bfbb8f74549712c05fd3bd11ab8874fb55abb22a37ba3512e733ecd5c472842e8e6f7b179 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1df7ca403174c726dfa7bb5b398d88953233d15faadbdd36dc141c4acf0b0cf5eeba722e8b15d2df6f83cd5bf3f39b50cd519a8dd0740306e757431d0d876678 - -Sum = e891babe65ee02c02e7e876c0df3dc3bb37491008f3642ca7affe2d623fa82a6d5a9e5400944a374ab70fbb8f952dad0c8b27c77475b0dfec7b0694051dcd1f4 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2300d53f7f9e33eea37f193d01891be58dc2a7b155e700836e51ce04f74c98577af32b68971ea539626d795f928b537e1a60c5d6a49043a967df6974786c86f3 - -Sum = 4dfc2f63d60f83fb1d397d2406b02a3b25c1a57c09c2fe02c76696b7c956e44facdef11470074d8fd8220c7bf8e647ba873fe9c3f9e77d6aae7b5fb64f1cf566 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -7794b61b10404ad66dc5f10b05ba961afff043d32f8c444445477e19635705ffadd7c8c3021eb0ab70e175dd6de13f982711ccdca8e34ceab155a0158a53559b - -Sum = -3c19bedc60e7d7dc3daaa36795e453d810c952dd5185fcdc857e2be806e520068dbedb91c4a1131b9eb6dcdfd500045209514e3e9f6e6df41d2ec67fba20e10a -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 897726a28567f6f54d54cac776866c7e14e89671e7c9456a872fe8e925c8ca48ccf7de45ad84eb1faa4ca57991c78300a5006862035c5c6142a2394c1f4f69f7 - -Sum = -28c2bddfeffbdbdb1ec6f06aa310d1bb6f0c4b88d0106a1b381ae6fe8f65c18bd9895fcba6931ecf06d9dab6c7a3ac9e00361bf165f16bd16af25230d040cd842 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1c69af880196deee0616f987b24a25b60cb12cf3dc7b75f6c75005b17c9ae2e6e3ddf42e2f70beeb5249a29131373428d55100875bc4bf2c14f5423412a9c8d41 - -Sum = 372ea360832e30b16a3c30a2157c8bddc4408ce0428169deb09bf68113e4b8482d887de1a7cfc80272e597c3f3f104e6825a1fd2a68b41cbc307caaae17d453e6 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2ad5950894c933c4518c39bf24b5dfd861e56e4b4eec75ba3fd115340119d9a337dd124430ad681ebe555f9e5d848c71577504689c5e95266d0abaae23e6408e5 - -Sum = -5b29f4991cad86845a50949f25ad6cd7c883d71ceec9795cc528f58a4a4aef9dc139e8e87cb82071e112b2d256181eaad0a98fa36b25b67dc673608939b48e08a -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -678302f10b12837173008b82167418dd2adef5b1e25e6d8135f3d6d75d15ce42b6e55485f3da805595a2eaf7ec84971ffb8eab0d755263231c707085f74b92b8b - -Sum = 98b37ecc0b42a15f52c8fc8bc2aba294031bc2dfa37dcba0fdf1f5f5da00b8b3daece033b47bf254e8b5e201bae24995034673800d53213f6ee0796be1ca93845 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = a50c8d23f9a79e4c6b78f36eb3724e996576e1749712bfc56ebcd742eccb9758d0984bd12b9e52389d461a27514ec20a2e2b8eea177fcde4c4dd89689f6198346 - -Sum = -1c15985f3ee941d7ab6bedad88143cf497681424e7456fe30eafbdedfcdf1e927db124c775b87f36cefff17a35972ac40d498c4be818883bfc206f44c5e5eec23b -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1b500779c002f208d9e0ee3f5907d2344142623b980c20a0c7a30fd92bb270a82e566e0d9e46593893b6edf7dc30633cba9b3a954775bd71a6c09e44fa0c7e773a - -Sum = 34ab71257e63b234258027e26bd35dfa5e07f67385b6772c5ed445438478bef5a835e87c9de413e23839849a71f5af99a67427098b682bfb6becb66d20eaecb2e7 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 33e5e03fff7d626553f528743cc6f33a07e2448a367d27ea17c7972eb34c110b58db31c2c671ede3fcf08118188ee81253c5d552eac56131168ce56d55117c67e6 - -Sum = -44f9508e3430f93d4e2c8be1b856f46c01d6940e1bfda8515c747a1a95239547322999e500e718ec98ed211ae04ffc76b0e6f2364ce9d913ffb80397f24ee8d64e -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -45bee173b317490c1fb78b4fe7635f2c57fc45f76b36f793a381282f665043318184509ed8593eead436249d39b6c3fe039543eced8ca3de5517d497be2859214f - -Sum = bea59d2cb0bf556876d4f8a248339af69644a12d3dc1d9a3d83929929b8db5aa26289bd06e2488a96820ea8f59168cc82f19b5dfaab20d245495d6e24bfb260a3a -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = bf6b2e122fa5a537485ff810774005b6ec6a53168cfb28e61f45d7a76cba63947583528a4596aea7a369ee11b27d544f81c807964b54d7eea9f5a7e217d496553b - -Sum = -166abef6a1682bef78d4c5905a833b81a03c0bf0f3735973bf7f02181a8ce5c7f125f41fcbb10c7f5905e492fc3f6b172f23d041620f8a7ac6f76e0c8a53d3cb5e8 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -165e65e84979c6f28bbc1599779274d59ad9b0d25e7fc47f9b0e3736cd7a1ae94c3048b42e39ea1f7551545ad6a8fe9eb9f8eb25f8055dce21a170fc8d963cc6ae7 - -Sum = 3245e002843eb7116b987b5cf9160e6891a74a6843039f8517fbda68b0e6ad87fd0aa836a2b6aacabcd67d45d327e6cab43ef569f488354e22f4553eed09e83d601 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 323986f42c5052147e7fcb66162547bc8c44ef49ae100a90f38b0f8763d3e2a95814fccb053f886ad921ed0dad917a523f14104e8a7e08a17d9e582ef04c5138b00 - -Sum = -464684d68716498baaa3744d20c112a854e148e6d004e4142c79f4e25a36c0acbff72c047925377f377ad690c63fd21a3f05911d11fb8bb79bec4ea68fef9f1d575 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4652dde4df04ae8897bc244403b1d9545a43a40564f8790850eabfc3a7498b8b64ecd770169c59df1b2f66c8ebd63e92b43076387c05b86441424bb68cad3622076 - -Sum = bb90e9e393538df233d499955020b8f3c9789b1f18fd5ba31cdcca6afe24842166e6cbf1985f7f9e002335be46de06ce11ffbf6dbfe743642cdeefca1a856219fe4 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = bb9d42f1eb41f2ef20ed498c33117f9fcedaf63dadf0f097414d954c4b374f000bdc775d35d6a1fde3d7c5f66c747346872aa48929f17010d234ecda1742f91eae5 - -Sum = -1804d154182f4b71cab3529447ced41ac310a1d14121847816c74171759998b707db0f1f3a9d6f6e01a2de48ec83a45e5dc7d0ac9133c8e00ec41814e3d2818834f4 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -18040bc332b06521fbe1c794d99fc7b002ba7c1f57d24b28d48034c360c86c091d8bb46880c5fd48036795456a2a3d96d675225ada932615446eb843e406a817e9f3 - -Sum = 3b75f0b892eb00075eb21961cc018a2d297764bf560cede3290cab6682a56931b831380b72a9afc3dff88f042ed5bd5d8468d8a1e267b36e508c09ccac2a565936e0 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3b752b27ad6c19b78fe08e625dd27dc269213f0d6cbdb493e6c59eb86dd43c83cde1dd54b8d23d9de1bd4600ac7c5695fd162a502bc710a38636a9fbac5e7ce8ebdf - -Sum = -4b4bf674436c9b1079c2b24cdda19247d0db44061c562ab6f5300eac53556fbe758151824b6bc6bb63a958895fd7c4205cde5484a9fcbbe787fe38c3d36f4549dc23 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4b4cbc0528eb816048943d4c4bd09eb2913169b805a5640637771b5a68269c6c5fd0ac39054338e161e4a18ce2312ae7e43102d6609d5eb252539894d33b1eba2724 - -Sum = dd8af6a278a84889cab2d444efb282a7259a608117db26583287f051bca1b70c21f8c3d95b2f4e0b7d25b6966771a5c41414c386bf4491ef7b055b07455c12b5d8d5 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = dd8bbc335e272ed999845f445de18f11e5f08633012a5fa774cefcffd172e3ba0c481e901506c0317b60ff99e9cb0c8b9b6771d875e534ba455abad84527ec2623d6 - -Sum = -16cac44109b24fd5d47dfb5994caecbbd534ee11178aaea4a100d9e63bb2c5ecdcafce1e2080eafdda00d26c29e01980166d8db67800e33027f5260d154efe1a98973 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -16cab7e7fb5a6170d790e2a99de7fbf5292f8bb5f8f5bb0facdc691b5a65b321fe0ad872b4e373db7a1d1ddbf1ba83139df862d15c96d9037b4fd0100552408393e72 - -Sum = 22db04aa783edd3e1a55d263262805f2892c013f78ebb86239f2e5981090158f57bdf3bb171c2e0c1c7bf9bc88ab62683581f8b02c5bec8f631bb24ade9be235108bb -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 22daf85169e6eed91d68b9b32f45152bdd269ee45a56c4cd45ce74cd2f4302c47918fe0fab7eb6e9bc98452c5085cbfbbd0ccdcb10f1e262b6765c4dce9f249e0bdba - -Sum = -4c8c0b74eb7a79a12ecaecf885b9672ac717b1c8db5ad251f1551ce80af89acf3a495066c85a96e6430be8e5888ab1ef3edd5e76645b5914ab55d221c34d07f8d5ce0 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4c8c17cdf9d268062bb805a87c9c57f1731d1423f9efc5e6e5798db2ec45ad9a18ee461233f80e08a2ef9d75c0b0485bb752895b7fc5634157fb281ed349c58fda7e1 - -Sum = e3718adf0c2546c8cceb0e8c7d909deaa50b50f51d7b80f8040763eafbf581c017e7e12325b258503fe651ffa4c3d3ff9200515d816dfa3ba372dc937480d121ef056 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = e37197381a7d352dc9d8273c74738eb15110b3503c10748cf82bd4b5dd42948af68cd6ce914fcf729fca068fdce96a6c0a757c429cd8046850183290847d8eb8f3b57 - -Sum = -18dd84a4e54a29c1b3106ef2f2d92be21ba64d2e26b3f4c2ea68685557d01a07f9229365c6d109205fa116fee59cf385cdd61b7fa5de8de751f02f1dc0eeb304babb4e -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -18dd83df5464aadb63419d67f36afcd5b0e5f70874caa5899b262148a9bb48db4b38440b101731ae39a2dbb5e21a9a1f064ec8d15427ed448725d9bdefeee72b4a704d - -Sum = 3ce64e7953aff0e057cdd6c17499461666f5bf8dc3a929ba7ba919486c1631c25c0e142584470d3f759157c045f9f488502a76024b6b7b2bf84c0adcce8dd7c6d6898f -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3ce64db3c2ca71fa07ff0536752b1709fc35696811bfda812c66d23bbe016095ae23c4cacd8d35cd4f931c7742779b2188a32353f9b4da892d81b57cfd8e0bed663e8e - -Sum = -6a392e555c2ae89dd73f86e11fd98d1d59ed03072a0dd61add633b317d5638d67984a55e51f01a2db94ad6eb6488fa80cf4f25a32d436886599c33b5287a9525f41a4a -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -6a392f1aed106784270e586c1f47bc29c4ad592cdbf725542ca5823e2b6b0a03276ef4b908a9f19fdf491234680b53e796d678517efa092924668914f97a60ff64654b - -Sum = 8202089b883a5e77457036254c2a73aaf32f03eb1e61fae428926028b499b7d0a4f4e5256094f34bc2478f0595aa01aa79b5d36d7f30136d3af2be93b70552fc6e988e -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 82020961191fdd5d953f07b04b98a2b75def5a10d04b4a1d77d4a73562ae88fd52df3480174ecabde845ca4e992c5b11413d261bd0e6b41005bd13f388051ed5dee38f - -Sum = -13a2e13d675e3fa89489c870cda617ae92ccb7d2f6b6405eafcad9c89a682b63364c333476adf0322febffad973f3dbddb7cbaa41a64b1ea24dcb2bc2196a0af42eac3f -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -13a2e1310e4fe7ba2f8cdb581daf34bdcc20b2709b97ab6b1ad6b557cf86de506b6d8e3ecb4252bb0d8c1bf9070718276f044579354947dff8300d662486a3f1abe613e - -Sum = 2bf9f45c817a8f5c589a208c57c30b52866e75a9b6ee0fb7c3f0c7ec3761f2c114858241a189e331aa9ab440132dc8f5ab7dac0891a69d5573dbe42fda019d30610f07b -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 2bf9f450286c376df39d3373a7cc2861bfc270475bcf7ac42efca37b6c80a5ae49a6dd4bf61e45ba883ad08b82f5a35f3f0536ddac8b334b472f3ed9dcf1a072ca0a57a - -Sum = -40557025ab86f90705fc86e3ab3d8494255bee490822e27c5551037f36f9ca834fd33c11a1a162357cb21eb83254c4da56b9f8f54aca29b95283ac03732a849258e7c41 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -40557032049550f56af973fc5b346784ec07f3ab6341776fea4527f001db17961ab1e1074d0cffac9f12026cc28cea70c3326e202fe593c37f305159703a814fefec742 - -Sum = d2985750cb9579d3f5dc3db7d2229f06e2a0d57d195819b3646f84c08eafc093def93748aaedf1f430eedb90c1694d894339caa4141ef5f07708e1a3607c5793df599b5 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = d298575d24a3d1c25ad92ad0821981f7a94cdadf7476aea6f963a93159910da6a9d7dc3e56598f6b534ebf4551a1731fafb23fcef93a5ffaa3b586f95d8c5451765e4b6 - -Sum = -13a024fb88eba47aea55fb69680479058efda97b81fb1e6e7cfe520e8dd8ad12deffb69662852f9a94f3b029a37befc620d792a8589660e2ebc7d6e1bc8c0c8f35ac1216 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -13a024fac35abefc04062c97dd050ad68292e9255c49351f43af0fc7812a9841b251cc4707ce75c322cdb1ee5a786d6cba100b55aa44aa4248fd0c8c5cbb0cc35c3bc715 - -Sum = 22701a8dfb82a2ddc8a5485b05362205a549bcdd24bbd660f2041a6672732824bbcac4ff58605ccf1d8ee066204a4a639828c41b722fb4a1e6c9bc3f82a89d85fd042f85 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 22701a8d35f1bd5ee25579897a36b3d698defc86ff09ed11b8b4d81f65c513538f1cdaaffda9a2f7ab68e22ad746c80a31613cc8c3ddfe0143fef1ea22d79dba2393e484 - -Sum = -4f73fdc6540686b350c859bdbe8f22340786ddb04b7ddb8858d33ce8931bcf660269129607f77dbc1db38d8186d8bae7ebb4ec8716c6eb26342ec8290d8d8988b1f5fb0d -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4f73fdc719976c323718288f498e906313f19e06712fc4d792227f2f9fc9e4372f16fce562ae37938fd98bbccfdc3d41527c73d9c518a1c6d6f9927e6d5e89548b66460e - -Sum = dcbcb3df6508052fd0d1cfb0a6088fe978227066c58317cc359f508bce9f45987ce3152022e19ef068b0381ce7d781ae3e7c04243541744c9f374a3f28dbd746acd3b9fa -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = dcbcb3e02a98eaaeb7219e823107fe18848d30bceb35011b6eee92d2db4d5a69a990ff6f7d9858c7dad6365830db0407a5438b76e3932aed4202149488acd712864404fb - -Sum = -163f4ba6595207387ef0956796ac29e3c6862b5344abdce3db4ff7e960b7727fa0a2870dbbe17bd8c446000b3074c1145368d4b84b39029110f915b61916fc29555d7d800 -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -163f4ba64cf8f8e0908b987a7dfc3300d5bf7f4de250be4ee7bb03c4efec91328dd7a868c636103b4d23a0277be488eebcfc5c432053e72706cc6910c319ec2c97c678cff - -Sum = 3588d982604f471ff0ff784942bd43d85cad820864e0b9ee80cc9a9e3807d2739eb58d447830f73fc8cadc88d864f98577e43adf5150b2eb104e75939caa7de02419b6575 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 3588d98253f638c8029a7b5c2a0d4cf56be6d60302859b598d37a679c73cf1268beaae9f82858ba251a87ca523d4c15fe177c26a266b97810621c8ee46ad6de36682b1a74 - -Sum = -4d51ba5f184e5d20b30f8e41d663d14dbe4f692f1a0749789c02290af4c889268c319fad8b9b7c9cc71e8d9878039931447fd6ede967c5c82c1915631f3237aaacf4a1763 -A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -4d51ba5f24a76b78a1748b2eef13c830af1615347c62680d8f971d2f65936a739efc7e528146e83a3e40ed7c2c93d156daec4f63144ce1323645c208752f47a76a8ba6264 - -Sum = 9d7a5610dcfc50699e6bc065584fed73fddbd58dfbefe377eaacc024e33e6b4fd361fac0844489fdf13efd8dca7fae0747603f4b26bb2a9bab9de5241a3af4a935ac940aa -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = 9d7a5610e9555ec18cd0bd5270ffe456eea281935e4b020cde41b44954094c9ce62cd96579eff59b68615d717f0fe62cddccb7c051a04605b5ca91c9703804a5f34398bab - -Sum = -1258b397182002c966f064c2cdadb06910e2042d0f51b4af494338c12b6efff052fe564a00e581c5aac0ea79fd8a1ff68ed92b7f74baabb03a51337d4b9b01a2f64ac803cd -A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 -B = -1258b397175a71e3e80a14f3fc22b0fae1d5996cb92c02c5fa09e97ee46251db81d1a85fb18acb0bd34ec47bc2411c74357263f8220c59f999ae68b2f63b30a32a7157b8cc - -Sum = a1eea50170df6807aef40929a52c097081e1755b575a49548ee5868281973a141920234cd0176d64f84a5874dc417cdc8a5c338cb54bca390538e1014d638b51 -A = a1eea50170df6807aef40929a52c097081e1755b575a49548ee5868281973a141920234cd0176d64f84a5874dc417cdc8a5c338cb54bca390538e1014d638b50 -B = 1 - -Sum = c7c26d68246f16d9d9996fe67616d2fd48809916e8121a5ef95b17bb9b8333d84e2416bf2a5eb3b686c936b9722e0a92a376f357aea7719610e864d9e2a5a677 -A = c7c26d68246f16d9d9996fe67616d2fd48809916e8121a5ef95b17bb9b8333d84e2416bf2a5eb3b686c936b9722e0a92a376f357aea7719610e864d9e2a5a676 -B = 1 - -Sum = 80d5de21acc1eb10fff4e534d23b5cd39e1eebc3d7f03aea438bb6e5237ced9955bf86898e93c74565c9a197e3ed2ff8edd3acc41ecef97c4fcfd52e1cdbb07e -A = 80d5de21acc1eb10fff4e534d23b5cd39e1eebc3d7f03aea438bb6e5237ced9955bf86898e93c74565c9a197e3ed2ff8edd3acc41ecef97c4fcfd52e1cdbb07c -B = 2 - -Sum = e020b9bd8d194468f8b563c8f586f6959533be8507bd4d3d7e494ef3733007c062caaa65da5c51b52f18cec4894966352f948517ee92d5f9b5ed00f020b1d1dd -A = e020b9bd8d194468f8b563c8f586f6959533be8507bd4d3d7e494ef3733007c062caaa65da5c51b52f18cec4894966352f948517ee92d5f9b5ed00f020b1d1d8 -B = 5 - -Sum = dad6af803cf2f40e75cbb564e8229c0d25465930d2ceea73715682c26d582148a943c1c767ac5167c0425975ff75a66eec5ad418ded078569dea2f77359c1cf8 -A = dad6af803cf2f40e75cbb564e8229c0d25465930d2ceea73715682c26d582148a943c1c767ac5167c0425975ff75a66eec5ad418ded078569dea2f77359c1cfc -B = -4 - -Sum = de90e3172430754f80e116cc8c848bee88c8e31810c6ef0ded5b05bbef6d5b81f9bf6593622ebfcb2b41be2e87d62ab7fd566763b74428275a16d1da482e5f76 -A = de90e3172430754f80e116cc8c848bee88c8e31810c6ef0ded5b05bbef6d5b81f9bf6593622ebfcb2b41be2e87d62ab7fd566763b74428275a16d1da482e5f7b -B = -5 - -Sum = c153ce69e35411c7f1e52809773ce03ce8d2af10b5c7aa3f4c9354de5ca044b7ef25089f1e96bd14d6c62c88b3c39951df19c73751ba25dc758534adba7faddc -A = c153ce69e35411c7f1e52809773ce03ce8d2af10b5c7aa3f4c9354de5ca044b7ef25089f1e96bd14d6c62c88b3c39951df19c73751ba25dc758534adba7fade2 -B = -6 - -Sum = f0c843f86e227571d67cfc34ac00d0e6f87f4cbd3273af68562657ae5ca82ddf5fd63476d56d5cccf62dd93f8320c0ba88658493dde282abc22bd09a01f6f2be -A = f0c843f86e227571d67cfc34ac00d0e6f87f4cbd3273af68562657ae5ca82ddf5fd63476d56d5cccf62dd93f8320c0ba88658493dde282abc22bd09a01f6f2c5 -B = -7 - -Sum = c5ba28844b8947aa0c2933f06aa88f0b34e0e10ca9baf1cc3bd5ff2dc0590e3ac5a2f2d3a1408009e1b35e08426bdda001adf93e872b03f4f6df28d34a3355e5 -A = c5ba28844b8947aa0c2933f06aa88f0b34e0e10ca9baf1cc3bd5ff2dc0590e3ac5a2f2d3a1408009e1b35e08426bdda001adf93e872b03f4f6df28d34a3355ed -B = -8 - -Sum = 84da246c2485e335d1f3b7e31c2408365f2afe7bff7b596440281c1618bbc8bf7a3896ece480fac4a29070539a95f1d718c151ffbfafbb82629bef9d2afbaaf7 -A = 84da246c2485e335d1f3b7e31c2408365f2afe7bff7b596440281c1618bbc8bf7a3896ece480fac4a29070539a95f1d718c151ffbfafbb82629bef9d2afba900 -B = 1f7 - -Sum = 9673d93165b5be256689ba4e750243537f85bc28daac7f65338074081f114b3a83871683c89fae3c87d44da053557aa16dd074b1bdc16c02a74c5b495f875449 -A = 9673d93165b5be256689ba4e750243537f85bc28daac7f65338074081f114b3a83871683c89fae3c87d44da053557aa16dd074b1bdc16c02a74c5b495f875453 -B = -a - -Sum = fce022b2dd492a96f8b095712803f318a45a9a8f00a48dec06accaf793e54e59daa14c56c2fce011e30e6394937f7bd6fa6afa1b6dc3b5359ec7bb4f757c5d89 -A = fce022b2dd492a96f8b095712803f318a45a9a8f00a48dec06accaf793e54e59daa14c56c2fce011e30e6394937f7bd6fa6afa1b6dc3b5359ec7bb4f757c5594 -B = 7f5 - -Sum = f04028fafffb1aee499812d12f9fcbb23e6a872b3f69fe7a7a246d8f98ba2aa954f78506b39c023397855ead87854412c881fdd16267c07ee12f085b055c7c71 -A = f04028fafffb1aee499812d12f9fcbb23e6a872b3f69fe7a7a246d8f98ba2aa954f78506b39c023397855ead87854412c881fdd16267c07ee12f085b055c6c7d -B = ff4 - -Sum = 9c008016815a6580728b3f690eddc7695fed44171557df8a4a6e8c0d5e7c3296832b4ba9ee4a4cd7e6a8ef23cf8c64fcd0518664289c4e72105b404cd6c0ab6d -A = 9c008016815a6580728b3f690eddc7695fed44171557df8a4a6e8c0d5e7c3296832b4ba9ee4a4cd7e6a8ef23cf8c64fcd0518664289c4e72105b404cd6c0ab7a -B = -d - -Sum = c12bf7e503d2c5845c60886ad5ef87d24e002498003b44922e462f36592a52c878123a6d1037896ce9fb7d2c680d008e80009da72c8e1415e957b2fefb52c34b -A = c12bf7e503d2c5845c60886ad5ef87d24e002498003b44922e462f36592a52c878123a6d1037896ce9fb7d2c680d008e80009da72c8e1415e957b2fefb52c359 -B = -e - -Sum = febba964e2548ed1474dac7c1eb9b1cd169ac913530b7fb358d67197517266707e5a176a814ec82cf8945214b30c36ca7ac0b1ade1848573e72d408dbede8f53 -A = febba964e2548ed1474dac7c1eb9b1cd169ac913530b7fb358d67197517266707e5a176a814ec82cf8945214b30c36ca7ac0b1ade1848573e72d408dbede8f62 -B = -f - -Sum = 8a3f9eeb76e96f13446c593fe2cabd4215e0debc54025df7791d924d8afc08dc8f607b82a3d07d75897bfeee0c42b9a32e0e77a098c1cce9c001aabe0481996d -A = 8a3f9eeb76e96f13446c593fe2cabd4215e0debc54025df7791d924d8afc08dc8f607b82a3d07d75897bfeee0c42b9a32e0e77a098c1cce9c001aabe0481997d -B = -10 - -Sum = be825a00c3c6b192d04863b0719ee1e687dbbf2cfc0c331c00b8b947c17fecb7700c9e534bbc49bd61978754ffae1e57d80aab34f5fd23a267e10a4b5a13a9d8 -A = be825a00c3c6b192d04863b0719ee1e687dbbf2cfc0c331c00b8b947c17fecb7700c9e534bbc49bd61978754ffae1e57d80aab34f5fd23a267e10a4b5a11a9e9 -B = 1ffef - -Sum = d1c861822ba0e93be81fc78a2628756480146225c79b4a389588a9c3bff9a7500660e99c28807d9ae7bf8c1e89e81d4f9ff2f72d35ea6b34d09df053d46dd294 -A = d1c861822ba0e93be81fc78a2628756480146225c79b4a389588a9c3bff9a7500660e99c28807d9ae7bf8c1e89e81d4f9ff2f72d35ea6b34d09df053d469d2a6 -B = 3ffee - -Sum = 98ac65b4c06400baeb40ed137ecdd930a3607423caecbe1f1a936a8210c28fd84b53324e5bb73b7e4b71209b1a4d106796d57a4a23fad2c23abc0c039539080d -A = 98ac65b4c06400baeb40ed137ecdd930a3607423caecbe1f1a936a8210c28fd84b53324e5bb73b7e4b71209b1a4d106796d57a4a23fad2c23abc0c0395390820 -B = -13 - -Sum = da02949862a4b26a4fb4bff43b21c2cdd048189199612616303d3ab34dc6f201be256f5889e368867a0da200a0b03e904048d6ba5caee1dafa16f4fdb1f00029 -A = da02949862a4b26a4fb4bff43b21c2cdd048189199612616303d3ab34dc6f201be256f5889e368867a0da200a0b03e904048d6ba5caee1dafa16f4fdb1e0003d -B = fffec - -Sum = ea9523fdde49d481c9f449969fd8e191e118058e0593f2a27ef0ade666ff478c50acb274a6c77d9ec4ca628ab0d7f3dc18708327423de28616235187acb197f8 -A = ea9523fdde49d481c9f449969fd8e191e118058e0593f2a27ef0ade666ff478c50acb274a6c77d9ec4ca628ab0d7f3dc18708327423de28616235187acb1980d -B = -15 - -Sum = dab5613ae3756d29f22bc30213363900e3fdced153a3c20852d51c71cbb9af41aba6a16d0b72926192ef48f25e8975881ca7973a69590dc6f0224395e6f3684d -A = dab5613ae3756d29f22bc30213363900e3fdced153a3c20852d51c71cbb9af41aba6a16d0b72926192ef48f25e8975881ca7973a69590dc6f0224395e6f36863 -B = -16 - -Sum = c442f3e574310f78e0ac187af96550d4999b79da9c9d6ffa9eb9437a2ac01479003d8e795ce68dfc0f87a4fd9b00b6c172c72c7f580a32af015a3a3375b85285 -A = c442f3e574310f78e0ac187af96550d4999b79da9c9d6ffa9eb9437a2ac01479003d8e795ce68dfc0f87a4fd9b00b6c172c72c7f580a32af015a3a3375b8529c -B = -17 - -Sum = b9ac1e23fbfe179d9d3ff99b2ad8399754ea5531e6fce5dad997e2c961110d49d0e3d9c2ec03289edeb39e5a6b4744dd4b3cdd6c43f4e8f4c8e91617772e7fd0 -A = b9ac1e23fbfe179d9d3ff99b2ad8399754ea5531e6fce5dad997e2c961110d49d0e3d9c2ec03289edeb39e5a6b4744dd4b3cdd6c43f4e8f4c8e91617762e7fe8 -B = ffffe8 - -Sum = e087174c20cba6c4e1e8ffc2ecfeeee770898916454724c24b56d8619c27db123078d406d6b7b836b0dd3092b34b736c472f1afd983971230f1e2b729b00acd4 -A = e087174c20cba6c4e1e8ffc2ecfeeee770898916454724c24b56d8619c27db123078d406d6b7b836b0dd3092b34b736c472f1afd983971230f1e2b729900aced -B = 1ffffe7 - -Sum = ba66837e8e8bdefa4c3df73ba5ee65d1ab45a68f51072bf2997446b13b6c73b29c26d15ddff186c9621e156bd3b650caa267dffa54abb782734c443bf502b276 -A = ba66837e8e8bdefa4c3df73ba5ee65d1ab45a68f51072bf2997446b13b6c73b29c26d15ddff186c9621e156bd3b650caa267dffa54abb782734c443bf102b290 -B = 3ffffe6 - -Sum = fc461dea452aaf0e2c1df10b7cb4293fbc498d40caa7a917a741c6d3534914fc039bb7a62d14cc3e9ea6cc8d2b41228628ad56687d18858c3867c75ae83a3216 -A = fc461dea452aaf0e2c1df10b7cb4293fbc498d40caa7a917a741c6d3534914fc039bb7a62d14cc3e9ea6cc8d2b41228628ad56687d18858c3867c75ae03a3231 -B = 7ffffe5 - -Sum = d109e7982ffd500ed77702054ccbfa49bb47b5cdb2220988ef58af3cbe0ac90bb3b2ac8a2c558fe744231bf227bf35343e12ecb312242ce50a85fe461e73b601 -A = d109e7982ffd500ed77702054ccbfa49bb47b5cdb2220988ef58af3cbe0ac90bb3b2ac8a2c558fe744231bf227bf35343e12ecb312242ce50a85fe461e73b61d -B = -1c - -Sum = babcba83c01843f6448fc3f91c006a673e514c9626c6399d43c016c31a8fd1a9fc58d1c63ba5b9565dd7320c4a04fe4331fbb79de1e03d68db331bbe2b4b9036 -A = babcba83c01843f6448fc3f91c006a673e514c9626c6399d43c016c31a8fd1a9fc58d1c63ba5b9565dd7320c4a04fe4331fbb79de1e03d68db331bbe0b4b9053 -B = 1fffffe3 - -Sum = c52e7fb27c4f670109b32cb6d3f705e1685e2cb7474a90d3815e486de77dd2584a0b65d22040059ae5279450682a189eb1b0f847e0d3fe022628a73eeb99c54c -A = c52e7fb27c4f670109b32cb6d3f705e1685e2cb7474a90d3815e486de77dd2584a0b65d22040059ae5279450682a189eb1b0f847e0d3fe022628a73eab99c56a -B = 3fffffe2 - -Sum = b5f074f655dbe68df022b0093534b609b23c17eefcfdc9b1b150c8cfdafe1d320fff7452c147c7d9f9cbe16be25970a23e6499bc90e689497c8bf2d38219e4f4 -A = b5f074f655dbe68df022b0093534b609b23c17eefcfdc9b1b150c8cfdafe1d320fff7452c147c7d9f9cbe16be25970a23e6499bc90e689497c8bf2d38219e513 -B = -1f - -Sum = a1a41b6638409305ab9ffa22bb3cb9434f587d4ce6f6da47c0ad6f8f720f397c37cd61254f35fc9f0cda36476ca6d95f233604b9ae5ea2f1a1207caf15682e81 -A = a1a41b6638409305ab9ffa22bb3cb9434f587d4ce6f6da47c0ad6f8f720f397c37cd61254f35fc9f0cda36476ca6d95f233604b9ae5ea2f1a1207cae15682ea1 -B = ffffffe0 - -Sum = f187feee94925d57f65f9b1200193d8e9359340d670bab27c022d6d63a54635e4573593790e6c6b779becb9e5ea81c9b075baa2d3bc95493b0c5a2da1fccebbd -A = f187feee94925d57f65f9b1200193d8e9359340d670bab27c022d6d63a54635e4573593790e6c6b779becb9e5ea81c9b075baa2d3bc95493b0c5a2d81fccebde -B = 1ffffffdf - -Sum = dc9c51e1313cb655969b4a069f2e8edd850d4fbc5bbc36f05df42a526f4e5b3ed18886263d86231193442b3ac3e7a71e5a6377021e71ad07dd9411953dbeedc5 -A = dc9c51e1313cb655969b4a069f2e8edd850d4fbc5bbc36f05df42a526f4e5b3ed18886263d86231193442b3ac3e7a71e5a6377021e71ad07dd9411913dbeede7 -B = 3ffffffde - -Sum = f2b5e665a6a2e7009bff8b2750b5fb11576bfd49dee5dd7f32b02c46430923b0ec95c3fcee0006b0c2591cbf1fb18dde331d8fb119d92f3196a7dfd8178be33e -A = f2b5e665a6a2e7009bff8b2750b5fb11576bfd49dee5dd7f32b02c46430923b0ec95c3fcee0006b0c2591cbf1fb18dde331d8fb119d92f3196a7dfd0178be361 -B = 7ffffffdd - -Sum = fb0f545b752979151bc6004b3db33bad63230c26d060ba00f5b82e7bee7e2c854b09b2a7c6b4186776c6b3cc45afbc50ef35df7abad11fec62523a12be1cb7a1 -A = fb0f545b752979151bc6004b3db33bad63230c26d060ba00f5b82e7bee7e2c854b09b2a7c6b4186776c6b3cc45afbc50ef35df7abad11fec62523a02be1cb7c5 -B = fffffffdc - -Sum = fc197e83249b069fb34552188cd6d06a7e0b42c6a6a9869ede485328a0fabd0c0ec2f79b81747129ccd70ee5c0f9efea62c36d1a4e1fb2b80393fe636469c25a -A = fc197e83249b069fb34552188cd6d06a7e0b42c6a6a9869ede485328a0fabd0c0ec2f79b81747129ccd70ee5c0f9efea62c36d1a4e1fb2b80393fe636469c27f -B = -25 - -Sum = aaf9a8ecbbfee9c3092d9887ec35118a9614a9fa84fc50b79b11d03a4967066c361f67cbf7a8e5beb620c7da55f4bc7dc50ad44b22c9128994781c7816a439af -A = aaf9a8ecbbfee9c3092d9887ec35118a9614a9fa84fc50b79b11d03a4967066c361f67cbf7a8e5beb620c7da55f4bc7dc50ad44b22c9128994781c7816a439d5 -B = -26 - -Sum = e74e32fc45d099ed147bcf7d798bd3aef9b046291038d98431698e90d22cf944a92bdcd8a5cf378e9a3aa0001150cf6e4dc37fa4e54a25e13c75099c64b9350f -A = e74e32fc45d099ed147bcf7d798bd3aef9b046291038d98431698e90d22cf944a92bdcd8a5cf378e9a3aa0001150cf6e4dc37fa4e54a25e13c75099c64b93536 -B = -27 - -Sum = a3486d022ef4d0a0c72170f05300cee78df844db19c63754c2d631d3d9ae20a0205cfe0fe947f8f4d2f9fa34e2081f448a938a446e8764ac2141157cab01dfa0 -A = a3486d022ef4d0a0c72170f05300cee78df844db19c63754c2d631d3d9ae20a0205cfe0fe947f8f4d2f9fa34e2081f448a938a446e8764ac2141147cab01dfc8 -B = ffffffffd8 - -Sum = 8952cb3f70b1344facdd7fe79747773f9c101bc2a083fa8fdef0679c24ba93218d14d4d7e848d293ce431119d1542833e9a0624b812f0b31b2b9f7ed9455e8b9 -A = 8952cb3f70b1344facdd7fe79747773f9c101bc2a083fa8fdef0679c24ba93218d14d4d7e848d293ce431119d1542833e9a0624b812f0b31b2b9f5ed9455e8e2 -B = 1ffffffffd7 - -Sum = de9cb4d4cdd1d58572fa1052edf72bb9241555bdb967bd8cefb26cb12c6622d6147385dc3f72e110b17afbdebc5feb959cb6c320a2ba01f36585b53fb1c5f07f -A = de9cb4d4cdd1d58572fa1052edf72bb9241555bdb967bd8cefb26cb12c6622d6147385dc3f72e110b17afbdebc5feb959cb6c320a2ba01f36585b13fb1c5f0a9 -B = 3ffffffffd6 - -Sum = d37f2e1638c0b3bd624104d244d9770ae05bf37f7a6ec32db552af413c0006fdcfc312cf281190eb6738370f3a8c4655beddb6b39b342f0a67cc9af92a2c7fdc -A = d37f2e1638c0b3bd624104d244d9770ae05bf37f7a6ec32db552af413c0006fdcfc312cf281190eb6738370f3a8c4655beddb6b39b342f0a67cc92f92a2c8007 -B = 7ffffffffd5 - -Sum = 831aca9ef43bea89f048250aab79b06207458647ce347c68f91013695299c80d610c6e49e2dcd46eb02dd56573d31720efc277469e573f6ecfb71b12886653ac -A = 831aca9ef43bea89f048250aab79b06207458647ce347c68f91013695299c80d610c6e49e2dcd46eb02dd56573d31720efc277469e573f6ecfb70b12886653d8 -B = fffffffffd4 - -Sum = da95fd2d2438a79843bdf92c1cadd0e9165d002d22dcacbe4118cc3cf7d5de2fd2106aaefc790aa1559b28b641f83e4e5aa0f8446b57fde5c3663c13efbc04fb -A = da95fd2d2438a79843bdf92c1cadd0e9165d002d22dcacbe4118cc3cf7d5de2fd2106aaefc790aa1559b28b641f83e4e5aa0f8446b57fde5c3661c13efbc0528 -B = 1fffffffffd3 - -Sum = bf9e3169dd4b6d336848e744231d1ca85678aa3d1d62d42eac0b16500ef527e028757da54a456b3d684199f3bb3c866a002ee3885c86d2a79180487f4e8a45f1 -A = bf9e3169dd4b6d336848e744231d1ca85678aa3d1d62d42eac0b16500ef527e028757da54a456b3d684199f3bb3c866a002ee3885c86d2a79180087f4e8a461f -B = 3fffffffffd2 - -Sum = b5880868d947554eeb536246c312c9765ca8c96888817f3ffdc16cdbafb41fe8f7c151cb316da27562d3b82b2d45abf7c9304f488538386e84c6a23e3dc375fa -A = b5880868d947554eeb536246c312c9765ca8c96888817f3ffdc16cdbafb41fe8f7c151cb316da27562d3b82b2d45abf7c9304f488538386e84c6223e3dc37629 -B = 7fffffffffd1 - -Sum = 84b1e4079d09df569a1623b990d917871b1197723b30b19fcf3c063b0e84c9cef1c3ffed16f33aa9bede08b4831bb3ecdadae1622c93e1f86b474a4989496fa4 -A = 84b1e4079d09df569a1623b990d917871b1197723b30b19fcf3c063b0e84c9cef1c3ffed16f33aa9bede08b4831bb3ecdadae1622c93e1f86b464a4989496fd4 -B = ffffffffffd0 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30c6365e1eeb044 -B = 1ffffffffffcf - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 80695b879bb74400c107619981f3bcb3c9987c76d545f6485ed128082377799534508a83112fbde2ee5558c246332c656455 -B = f6446ca2883d7e27209eeaa01fdec632d4027113b81bb47dacc8f10eadc3b3ffc26d84135d91e70deb8aec84c7820332e8cf786e2af9b4217a4c1d32b5894bbe - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1b510bc480138145e2a142fce8330ee5f4030dccaf6017a1dd85bc5bbe9b2fee4f9d8fb484661a839dc9613652bcca11a00eb -B = f6446ca2883d7e27209eeaa01fe0fbacebd20e03107a9f993e30f63358d6bdc91baf4f5acdf81e3ad94ef9af3ffc315c6e9acfff91167f0ce6738f328308b0fe - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 219f59352ebda4cfb785a18834ec1c99145a6647265baf5d8f3b405f29a746785a5e70777d528ff1526688c01b9eee288e6cd -B = -f6446ca2883d7e27209eeaa01fe16091c2dcf8a54917eddf26e5c1c43408c33ea356bf1449b339931985aa70a89cdd6a7aca5ec6e7f1c8df5f101d54c47796e0 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -7e5a2ec59519143f7bda2829cfee4ae75cc8038f31303ff9bbb1e2cbfe93c46a1367c9d6a2a3d9cb40f1a6930c18c78f85724 -B = -f6446ca2883d7e27209eeaa01fd760f94330bb39b824b7e28bc5741dbc01b11805f14655543e8ac0e6d326bffa760106d5e85f604c28935c69dda1d968f658ef - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 9f580ff614b449cf9c46c91256c20983f5c70200739de72b917344db81c1aa1bf3927c38c22d026d6ce38ac746ada2948e538 -B = f6446ca2883d7e27209eeaa01fd5511b3028c1865f22b1187d3d06e1d23821281edd1f7ae1212eaac5daf3e19f57fe5bafc666cdc205d43e2699f88bb8a5cadb - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -15773d29ba363a15a0cb31ac4a60c0c228967e857d7d11c1ebb0a8db855c0d0797c0e409899a50e1b1c989a7dcea6f26238d27 -B = f6446ca2883d7e27209eeaa01ff4bdd95944430511bd40b6baacd3c32ca01416c461d66b15c5f687ef186c0948aef8677cdc23eeca8e6c007aeb4dd508123d3a - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2f90f72f59dd7738f5572e31d41b91599ed500d59537bf5c21a1bedad709303cba0d5bf1b5e4eaac1a85c261ce94c45b64646e -B = -f6446ca2883d7e27209eeaa0200ed7935ee3ea423511ccb340368e93c416529914799118affbe79dee6a192c7dd144df65086e8894f7283934dcf82a3d531481 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -73978eee2b2a4ac8ef12b3042dd5e1ae8724a0a676d0a52035e801d741a61b92c638a3b0cece6a81bfd2703e3c502ad1fa784c -B = -f6446ca2883d7e27209eeaa01f6baf0d415ee280332d62d20a349d20bbf058f7986d88b433a45ddd3c5169e0ae50fedfc283bb33671cd00694d2133b0ff437c7 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = a462699ec5214f0d7860974a669d1728b4983a1c3c440213d12b2da58bba9dd1caf1d5ed391a3ebd80aa6e9ef0396e62260a1f -B = f6446ca2883d7e27209eeaa01f3ae43290c4eb7beea414edc3fbd5eb41c2e55e22a8155740091ab16e07555e6f4c45ad86196f5f2b5bf808341e29f77fc8a5f4 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -130f7a12825a6c5b6b109b91e2506505a261c9f7c1a62fdfbe252275d3f6844dda2aca2d0ff6d8406ac5c679c80ab6d29817b4d -B = f6446ca2883d7e27209eeaa021103e3d57afb390b2cd7f3e2c877952c49d9a37bafebc574fbc980670d278411eb9e4264451f721ef88fede6f8f0ed30b702b60 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2863fa82289aff06fb16bd1b866da9ac0ae0f411a8d8c2c084cf78b81d6713a9a4700248ef61d5e52ca7470f1f251380368df10 -B = -f6446ca2883d7e27209eeaa0226586445213bcbb6bcde156c6c94d9d2b258cd95971e5855c273d6a95698136db5e37a80248a6fc3ba716e7c500b49de5578f23 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -6176f648b54dc4e2d11ba7e32d2d9d3f400fbafa489fbe7f126daf1f929ef8f219c78ff1063dd27650d4751c63b6e7ad7d9a588 -B = -f6446ca2883d7e27209eeaa019c7d737a435307ccf0abb06db8f992e767681e89a5a5d7162b36aed1a69206d1f7abe8462eeac7683cf5b250cd2f4eb0a150a8b - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = ccff1ed8726e309c4e0f2e166c497cd718a8eac347674ca57b6f317ea491b743a89d25f87c37f379f6239b13d848eee1ffa9328 -B = f6446ca2883d7e27209eeaa0130f54aea86329c1373b82a3a79ddb34f8eceeec0a6de48efc2352c72949f488068d6523eb8f0a66497a68c59589d477c1f41ceb - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -13d1c041415fbc18179c970fe989ad9e1f10e4ff658c1bc550e93f6ab9f9cc9832fd49cf6f2e75af72a71dbd7b121111ee0d4098 -B = f6446ca2883d7e27209eeaa033b106dd70e9c8e313b90c94f7ec20a089886297a470751ea4c38549cd8cdc9474148152e280ff4d5b83c0344e207477cffbf0ab - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 27ede3a23479dcc5447bc3b64df32c121761de88086204484cea0782b8d63d72b57192f2b20dd3dff395e937c91e21cdbd13b68b -B = -f6446ca2883d7e27209eeaa047cd2a3e6403e9904098393b5c559f1481d95c2047465da1a0c44d61cc694d6ef688ca7625605d7ddc728bae9c2c85339f02669e - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -4ad10e7f5637cc48b04d4b250e4ca00a0d102c91caaaf6291f1248b7a1cec979f87b7251c50db8e5e49206bebb30b7f3f25c8577 -B = -f6446ca2883d7e27209eea9fd50e381cd95240824bcf2a600015d2f85d6751067439633034c7fd2771c44682489bc531ae44d0b8044a9bb817ddab71ef922a9c - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = c6b77c2c932d9d5ec6175def706d6e9c411216fe12ac52043c617761d3a37804487f158de60a9c18e7a19646c455804a65bd80f2 -B = f6446ca2883d7e27209eea9f5927ca6f9c5c6f6c360517959df504662965669a2c3807551778ce7d3fef97f7f89821f58d47ed85013b0c300eb8e31b7c312f21 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -187976849837d4ad4cfc9764fd0e3f865fa9d1d9f20d98ccd52a6b3652277100bcfff85fb8414c2967dacd26f269502d3c2caff12 -B = f6446ca2883d7e27209eeaa1a776aee5b307579fcbe5ebd4df466b6865149b375fbde626a680f944360a20081116bd7ef7674c34668974e5f9a36639a4b9af25 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 33913efb99088ab80c706ee229e7a6ea6b274097f6ed3734452dabe0865eb86fcf20c9c6ae0e613b72dbfb8b126383e7d10e8bbb4 -B = -f6446ca2883d7e27209eeaa358f33655c012b84bc32363a7acdce1a91ceb8717adb7cc9da6b503e7797e96f93323d3ee54389d55169c5b27f946a1e2f2d76bc7 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -5d84033a924ff84666d3ee1a1342ac118224264c439bc658213b9762586e8dbdef141024d757175f30bec23a960ab145832dee9af -B = -f6446ca2883d7e27209eea9a479f12f30a8a88648edd93e3da37b1ea483518d40527f3d74020cfb98caa341d4fd63535fde113aadcf07ecd72634f0daf0fc664 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = a2aeba6a0d6142f527358ffd4c9139c390c9dfab07947c902085d1f3c367035db0f22f249295b974b1d9ebe7add3dfac7ec237f72 -B = f6446ca2883d7e27209eea95f4f39ffb5975dd7888c375b0454ed6c95dd982e7c59c90574b7d26a2dd22da2131f4453a49f6f252cb3de3fbf5d0689df5cb30a1 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1e545f433c1bda45a7900793d2cd18ba630fcb11d4a2c88bc7a0fb392d270088a1ad126743b80342bcfcfa9e939c9ccdccb7f4f198 -B = f6446ca2883d7e27209eeabe743e89d84b6452728c240957db7b2d657a428f6ce1ace520f4d57f0c3a93989dee299ec72b55cc5ae5d7410a6fab313299e3a1ab - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 244bf1eb701c53bc7847a644269277f53b58dc23b55a2f996faaceff22666eece40fe14644aaa2ab0197a5a915fefa394a5c357db4 -B = -f6446ca2883d7e27209eeac46bd1320c4bddc94343c2b9aba0da683dc353a14d9913f2c8fea945017a01fce050f87dc81df5349f80824b8cd2089cb03e242dc7 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -7e3419b44f3596c6486e095c3fc9a84b5599868abd292354278a2520f54929d5bc325dc3d095e84431960265dcae84f0815ef5beb9 -B = -f6446ca2883d7e27209eea21ebc5924cf9f346828e13194544ba27acd0f0f2db15c10531c9b524e9ca693a400eb973b2dd6a456c52da3c9a248972e482f8f15a - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 81fae0f8555d46ede9e74a93b8a7c6273c9bee0eef0f51b4575aad5cbdc0e10a3d03d53cf2a42e6a3625074c812cd0ae41d94d34ee -B = f6446ca2883d7e27209eea1e24fe4e46d2431ee114d1e1cc669c4bc5ce896ea92f92a501f92ce92152b205bf3d41fa90cf241f67c3d555f5a63db52408a17b25 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1558c919b3dcd4cc2eacfee2ae98a3b4286bdb6aa67db97ce35df3ac72f6c6418df10444ce791109a9a71250896f20d4dbf19d559f0 -B = f6446ca2883d7e27209eebf5ac70e1d9fcd6cfb5cc0aa06e989db589282e28001a7c278f33150d0e7ff728db515b846b046324385a01ab0dc51bb124fbc40a03 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 3a9c8b150408b2449466b8328ccb0a5334f2340479203cb790780e71b6609f7999c691ba19f947d8cac4329a4e45377fd6bf226fed2 -B = -f6446ca2883d7e27209eee49e89096dcbaae5611679f9e51bf07a6518db7c52a42afd260d4c161451d8aa998aa32d92307d0164a2c06475b268660d1d415aee5 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -450c41a9cca23287b6448a0b248d24075ed20bec41c600279fd86869b1a51e1842cb7f4d59144436edc1c052f44428965b3b2d98757 -B = -f6446ca2883d7e27209ee64f5bc4a9d20c619166b37bc33c3c21fd1549b8b97bdee1df5bcd53aac4c1b18bcf892261f22f0f1ac1ccd773329084fdb22f1528bc - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 9d48745690ee5aa8fc448371f9236153c584466583aa30d999461a3defac314356230a763c204c2595794db93fcd3917f25b83d1b85 -B = f6446ca2883d7e27209ee0cb9899dd8d49df7d06b3e555f2d84d36aa2611255d9bd6bfc4f23666e4507eda9a106fd3c16e90304654010e79ff7ce44029b1948e - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1a3f8af71d423da8c007022421f09a53034c6e9d7d23572b8b4b273b091a6f024ea4216ebbca25daa4e9e83fb46a1d9e65fea344bcd4 -B = f6446ca2883d7e27209f04dfaad663de6d32ccd1fe409775a8b5764ed914fabb960fe4a47b154ef982955ea06285f34d992d2e87d11c56e0f0acc96485336ce7 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 3cd13ae384718065169d7e6b600ea1d1a514832649029f92f1d2b5bebbf83454fcde0133f3bb4716cf452a3f930d28f30e7f22f21982 -B = -f6446ca2883d7e27209f27715ac2cb0dafef23687a87d593b0341816ed9dc69ade774b2c099901d747e80cda424b2b3eba6958e3131c3583fc0171e504e0c995 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -5849ade77039ed0b15524c08929a4553a6c0825178f6522915592ffa9638a8143fe8426df9757e8c06aabc97a2ef87b4a58869d1df4d -B = -f6446ca2883d7e27209e925671f7d662427ef778b013e2eac90ecc41e82604a1ecbb440023dfafa66b7ed013fea93e0df4c682f32c44ff874b59bddd781cd0c6 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 9c4b4b4800fe2f11e1897ee8c8e147b143a252847548145e77d9a9d3e4e3a79283f833e760bdc69d5f75fc1d0356615b0c10b1e34f9f -B = f6446ca2883d7e27209e4e54d497459e00782b417d33aca3c6b12f6017f308502a85e17faa0660fb6c008c040d2fd6c5acb52a27ecbf9f2071b35755300b6074 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1bbe5a805b857ccd9dae7cba6f3dab95d22f7d2e1621a2ab382898bfb2b4efccb263929f752397da4ad030e6d5c8773dde8fe04c42f97 -B = f6446ca2883d7e2720a0a685c7e4fef3fc63e7b2c7c3695fc7bf95fa3d58dfb26997dbe2dfd5712e105e36356b0e89bcf0f736a0f749fefe46ec4c63e6b2dfaa - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 255c9a10ee08acfe197fecdc7b6cbae27f8dd38887f135cc5adb1b9276c94ccce420887a7476b2d17c2708c84b7e9a8b4160f676f8d1e -B = -f6446ca2883d7e2720a14069c0ee2726ff6ba4c9c9e42c50bc8a6bdfa2fffcab9baa070b0d01b273e0615204c8be7eeea06a4c0e75615a607bc27975495e3d31 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -4bb5296b4ce3e960ecadc3f15de0a3a0dacf12d34f690cafaa8f2e31b0e9e69d42a3b16bce84361c81b7584be32210daaddefd7184659 -B = -f6446ca2883d7e27209a2f4d892a785d997b41eebd06977ad454c6113d42870773e9b06670bf3740a9bee5c12a5a4f40118a6e28641e7055c56385760ad669ba - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = efb45966d1f6d79c9b4c72c3a584e26e7b7136295fb79a911433a10ef649b47b14b8d76cc42e54852176ef7da7d08b86186cbe6e98b23 -B = f6446ca2883d7e27208fef5a8972272eb5c05803cfe21d36e77abbef07e1821e95d3161f42eae143cbe1c46eca4af49e2b00722ef102256e1aacdc99fb0524f0 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1e30bf701cd589fa3d2adff0217e8f748d1a254b771d77d342fffe3e3138aa3d4a75ca8c1e6636919636d4d96d8b04d583af4dc208b51b -B = f6446ca2883d7e2720bd1b5f8ffc1c2629c737aaec3df41482ef8d27b5ee9b1012275957920b7e8950dd85c6cd359dba04e8c072c24a2d7ba89212b3a3f7652e - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 320eee30dae44f272fc9606477927bac85b677c3333fa55f4c5b5c7e71bc02266a906d8838a096551a8b5b94980cd819ac721a6ca70a71 -B = -f6446ca2883d7e2720d0f98e50ba2aeb56b9d62b60940800bae8297a2daabd3d9e30b4b5d24c01e139fda069c94fd819c86d14f97d74af4eecbad5804e95ba84 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -5819f4921a515433459006c62df3be1c4e642a52340381b5954df3f9dd0ed5f73f8dc9a17e536b88090ae8d5fbc411f16eeca2449ffb96 -B = -f6446ca2883d7e272046d0ab8dc4f547fc447cc435ee81c6f2140ed818437a16894f0b6559fd37091c5382329f98e417eb497eb512e0de64e19f76c39d4eb47d - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = f238bbcd9701966bc4482fb8df8ca395ad15e2b83c014e59898e33a36623580e9c91faa3873eb26a0e97c4d29ff209e22c4faa0a1295a0 -B = f6446ca2883d7e271facb1e452484505c3c5c49b433ce8e178b55d1fb23b7c49e55acb25b074228704f67e019d8ff8d10943f1d9163cb06cf0e213bbd7dc1a73 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1e00b3b3bab1081231e0f1a2029b146f8391869dad416f6c8443c124ea7c908ee402f6b6fe06d883c2d232713512ed5d8636a07898523f3 -B = f6446ca2883d7e27227ef5db5b8a571d52a81be51c4626cc069b8b6c454b948f0728956ba2820ee801d33f67b0f7a50baf7facc4fc2dd14cab71cd6d6b73d406 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2030dfab0a9e0af1764f416171c8eee2d0b87bd5b80e6cddee4ee2a7509a301956050b6e3bb067f827d13c33abf31693d4101951d4a0b96 -B = -f6446ca2883d7e2722a1f89ad089274b46ef00e1133904733b6dfabfc5f864661dc94783c8e3e8e0a8f360b324d23e02f5cf9d61239bd3e0104f64faff38bba9 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -7427bfdba61a57b644fdd11b2a3ea1d3507cdf4ea1389436bade3fbaf751724000774127923658c7b090f182d1d7e320aeaeb1e3dc0b30a -B = -f6446ca2883d7e27195c6ea2657da120cb3a2fb949788b67d95aa50d8063f454d336755da4652ebb138b9be9c7f3d1f6f8497a85bbbf2444c8237847a42dfd09 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = d23891ab621e6ee43b3b250d66ab139cc97db21429da33e01910635969af402b6792f6d741292a0e1bb6bc30b2a7b32fcce9f5e8c2e48bd -B = f6446ca2883d7e27137b618569bd5fadebd65a7a25b1c44b41ca97e127d9da5a3d535323bd3f51dc5d19e08ecd04a4e291971ddaddb22743d63fc40755c06756 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1d6d78b7e83cedb64f0afa17c56360a58eb5ccc4e647bd3c594feb6695531f9434adb169ce314d4c93b4efc260fc92b268ca22143fb7e994 -B = f6446ca2883d7e273e0c6358081c34527e9506e2c17fd62a9d183fc750bf3ad4983444bfe92d65734840c1660f4884d00707796049d935293bd8857a21a699a7 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 255261901144afcf37c28015f4ec493bfc06cbabf851997d06cdc2fa742a97e234085ce67dcd867451a19d3427acc5ac2fb5b919f1514e06 -B = -f6446ca2883d7e2745f14c303123f66b674c8ce0f108bec10a693eae62c9171545b21c53c804ddc1479b6ce2bee4bdf7c4f426d21089682302c41c7fd33ffe19 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -4c222346b39b4b87631fb26dd9b3a8942374f10ec577d0aced5cada7bb0fb34d9c85bd06b6d52a4229ec662ca5605aff7896f7d74483fe99 -B = -f6446ca2883d7e26d47cc7596c43fb14cc6a5a5d2268ccf0eaed81f3a4ffaceb5187abb198ca9291770d52f58a420d4149662371437c47775a776b8e9d6ab17a - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = b832106ab8bf5c27886927f67c5bb95d81280a5b4a3a044c39c816dfa5c5a4c6e8058d34c3e44bab649194932e42c197b40d16213f6565e4 -B = f6446ca2883d7e26686cda35671fea74a720e4d47fc0bc278d3a68a7203d794c051c4279ae14a1182b8d82c77d32ebd80ec0f50aba99e0df1f014d44a2894a2f - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1e4bd432a98b6d68d35627f4a46b56f04b378a535b50c7287ec949008e8ace3ed04a128043cbac7a49c6c1cb98dc27b684c4f971d69b51268 -B = f6446ca2883d7e29055c2dcab8961d2964ec8c1542d1e489c1db18381f83f0202b78e9623c8729cc183438007dd1ff280fbea657769f1ddf1f5dfa834ba3c27b - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2af2a9aa0364d970115f35b6ab676f4baf1f4ed52d07cd808dcc7fc7bcdf2268f917a7e4476e429200a37b246e786e85a2b62d6b52de13135 -B = -f6446ca2883d7e29cfc98540562cdd9d457d6835b2936a40005760553af455a11bac55d521cc6c6ea50d8e40b7fb60a37d8a3be4d0638ad0fe713a1b0fcfe148 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -5dcc7b06c24160a67934f3adf5f5a468f10b0bfe1b82e133c797674c941c9480bb1e71ceddd1151f88244bebc63c2da41557670132848e482 -B = -f6446ca2883d7e2143d73a33fbc93c349c3ad1eb9cc22ef5fdb1b320b2496a5bc56de4901210fdd361abf30e6405e58af10dcae18519c8357d97f352b9a5cb91 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = fe6a6b7e6ee19b5e4e2a4cef85f637a5b0a76007bf1080fcdc86c952a49adce824573dbb3c0d3f94d519698968594e0b840b6c91ec9153aa8 -B = f6446ca2883d7e1739f832b931c590b74ce53dd29cb8fb2a03ec7286796f6dca7677c42f0a2c775cce1f344880433e3621bbf1076347c1be92579a4718d9756b - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1f219dbf1e789d4d74f10ff27fb947bf6cc94bf1e742ba203caf33810589005f8326704b8414819d90698fe08d9b3c16bd261beb922a9af9a5 -B = f6446ca2883d7e46423ca9be987c94112099ff4ab56434f1d7ae64e9ad319dd4ee17da5edcdaa5623a035b805598d513dce26a2b8418b933f92a4ef80c89a9b8 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 25bbd6ed7646662f6dd8481ac4c4a531174bcd05123889d4cf904d12d8d2bcad5425074d9c7fa1ba70ac5c8a3723fe6b20e064fb4a9999e716 -B = -f6446ca2883d7e4cdc75d8166645760a07d2278fc0c1a69c5a2f7814a3015267cf316c322696f333389a5d98c0b8f1f41faf13d50cdb0d97b3735eb07b889729 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -74af822547dd8aa99da2b3b60b1aa5d45c33cbbdca0d2876531b31a25cec244482832671c861b749effc1cf5e150aeb9d8e88583953aacd577 -B = -f6446ca2883d7db2711cc55842549cfe8cd656bfe176a128da96b5385d4f074523b2b6fc67b6015c906c9e33df5fed93773593bc982de89dea88dfd0a741da9c - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = d35d55e21fdf90fb0abaea71ae6d7f44401f615e7dc6761713ec45650b94c02f85e7bca8c2f43ada8975617eb7ae6fa41f4eadedaeb544654f -B = f6446ca2883d7d53c3490880404e4b91749f9b1c8e9d3144ef011484a4016684529ef44dbf1a16592bd667394cdc5cf9fdf10ae63a6cfe57846075b72caa4ac4 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -14872666f07cb43b47b4b82ef6df5b7696c2ff49a88ec9308e27d27736df05f79d452957297271756ca1afbc47ad011f1b77f32bbff831bb941 -B = f6446ca2883d7f6f930559a7eb22fb177b0cfc38f1d3def13e570d8b570a867abc0bccc74439bfb366288293682e8e4d8e4e4e18b8ee942e52411f65650a6954 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2d2316a87167a23eff9da00b857c9423e44feb69620852e9e8d87ac70d96367a8947729b57804ab1d54022442f5504d23ea42a6cb0eddad04c3 -B = -f6446ca2883d80f9520971b69a033696098ac522c55eb3ca0d190922efa61c25c690ca32b741ee738abcc57445c254d77576cc933929c66115b52e74bf9bb4d6 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -4a296521345e531b059bd7bedbdee650280008947bb0de4012c11281d92be141b2d29b92812a4843eafc296fa69c55a697b4e9620a79fa8fd6d -B = -f6446ca2883d79848a4cd75a3aad9642720e1f0d0db773050dd92b475c937c6c2dbc3bc695c62ab1e9d9e7e99c92f8d3b0bb8f34238238fb847842be4245b2a6 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = a29d4661e53bde02d72f6e0e3d19ccbd85d8c0a0392d7153ed330ff11e6f75c9880dd1f77a89be8c4e48b10bc7b43b46fbffb592a9a2f23b932 -B = f6446ca2883d73fd4c38cc4c61ff192938a928f95f509d2782586f6f93623ec50de547725c7dad5e36739853a52e729ee841cd22a52832b6d7b538cbb2caf6e1 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1c7a1c6185b0a2d7c02f3a7884e5a11513785520f1a27e8c29cc30707300edbaaef99509e9c4f578d086b2a8c593d0a04d32682c7c71f6a3d025 -B = f6446ca2883d9aa13d007050c2b706cb6a0291b09d3188fd638364a4e903a7646f54cc5a4194f4d8a89cf9c13690080a25fb4f31b97cefa93b3adfd7d8928038 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 21eaee9881dff114d10dad6acbb6e712c6d1acc6b878ec60253c44ad7e9272bb5ab0e2ceb2023fa9f427a23ebb464b2c8c411bd86032c6873ef9 -B = -f6446ca2883da0120f376c8010f417a9dcf4d881e32f3c56bb292b7b56d7a2d48391d7ebc695a08ff661c1fe80c12bab159144e434092eb7eee6c398a875ef0c - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -46f16fa8b7a3b6ecf476f8cdf5f77ea3a7c9be958ced5db6c6a9e11e6bcf3a156b3fb60bd5ff862c80d7c3e3f23c15df57a8fd7822d4c7d9738a -B = -f6446ca2883d3735b0f632fc68f2522536bc16d37d78cdbb4fcce6150cc0b6ee5dc5ed8a19c4da9f5d8739fcbaeab6abaf6e9761d2fd4acdd59640911a153c89 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = bdd97dea2fd68c602862b0fdcbbe47d5e2e23ec1a10925cf34e9773d09d90caf70b5beed3ae1509392289be0ee66b649d45b3dc880ce4f48bb4c -B = f6446ca2883cc04da2b4bac9937f1e397e8c410cb44692a2cfa0d1f944a848aec7a74f80472ad52954a5d51af083a55ad7719b373292ce1b9545e29792a5f4c7 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -145dd43715b37e7df4b56e5afa79caff8668de6fe4c2f725866d0f84522682f38694a26bea588a576900862dee9c9498df909fe788d72db324f6f -B = f6446ca2883ec404641045d807be91f31539b467ac14dc12f560bf31dccfe46937297bc18312af293a51b584e68dc78bd6317367326a9b80d186f0d8bd20ff82 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 35094bde0256df169828d23a250e3a10f35f1fe30f168d463ccd8389197b8aaeb326ca86fd09b3d8a29769ac3c6ed856c34f10cb0d993e38252d5 -B = -f6446ca28840cebbde7f100e1148c929532c5dae9d2bab770c93646b3edb4a707775f111fec5784bbc02e0977ea160fa0e16508b6e48d767dfbf3cf9c57102e8 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -578294d2b3d43ffd19b79a65778710da245eb96fda50d50a3aa6ae3295dc50d8f7da1f5c8b98f4a9905ee840dcd139a62697eb45678259d7639ff -B = -f6446ca2883805fdd373ad5c200dab2289329459ee7a2f997764cdf519d3d32d5bbafb94464ac83d1dca566cf67e3194ef44bc8a4e7a38f81eb7eb4044787614 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = ab192cde88b1cb3e6b094409c1e81ff84715d64ddb7413f6fc5dc1182abfcaca481c8035d16e0d698476d7094f2bf7cb3de1b1210ba68701168a3 -B = f6446ca28832cc9452b65f836bf89607eeedee48fc980427a984bbc12b07b7bc2d61ad5ca735c4171035f91b6a7ef01602bd96de6c28c45bc0fda8fd71dd4770 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -19a7abdefad11d1c9b6c4e0c4c1ff1194c490f63086ede1e4c43d964555a2f5e561a9bf5dc3a670b7ddfe8894271197747860c78949e6c9e357460 -B = f6446ca2885725d2ff99bbbd3c7ab2ea3bd62cbc1568be94716ae1e088c3c171a339b388b230607b096f4a634c95176bfc94fab7602428834ba301d280242473 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 275ce169251250a596ac64ac6e23ae05f8785db63b9cb83a9dec067472d059ea3aef07cf9fc20b846b3292899a8d3fe1aed5b92f21a89c1d924bbd -B = -f6446ca28864db0889c3fcf0c575f300dbf830790214ede2c49e0fbaa515699eb35729b33e1534e6e332d207c5826a15fced16ddca8b783002300c01ff80fbd0 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -61039a571c78308b819da54c1849d8d6169a82e25f61f26e30ab16b545080417f2008ef89116e002660f95863c47ac02bc161bbb7aa8817457eade -B = -f6446ca287dc7a8cc982726f945da8f6e371c2f22605db022c03110ffc46d281899f51553be845501b01f91c3eb127eded1641f1e6208c5b1793bae46d96c535 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = fca0b32bf9e248320b8c10128ff4368a766dd34fbfbf77e66cb2298fa3833bbf24451f508a50afd0131ad49c9ac8e851d4fb53f2fe33675f5e6b34 -B = f6446ca28740dd73f4a50857edd3ba8c1cfa189471a607b1bea2b38a840acb6eaf40d61d94b600bfc308bf4c71041caed6b7c0b59707a722e0102ffe829044df - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1c6f81990e54d6894188d5b872009c3eb5b2f10137bf7a27999d918790b587594afab3950330296979c354851164f95938d1df77995f6c0a9a3edef -B = f6446ca28a047640b1843808b3f7d3f7b6aa168ee777a49521de6aa4e41156b0b7efb1cee889f11863c61292d8b36ccbc468d9337c69c06e4ca45a268b929e02 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 310b6086b85bf12c7e391184e070f623c9cfe07a8e495010fc13d584d748098f070ac4b7c31cbd28acd32ab6270e2a98f48d8d31525ada808858785 -B = -f6446ca28b4e342f8c24a9b2e7c2d7b47d911c2d38b9738cb74708037a38baf08c58d9f2444af22a8fc4dbcecbe46a2ed5c36c4778257b49e834110dea743798 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -4a51109cf8c033e683b1bff229f081d71cd5cafde15dc2d5f8ad0457e79b9b2e015659ee564de59f27204c685ef58977e13e19fe36a2d017fe6860b -B = -f6446ca283986d1d5112e761b7a42a9d0ceb04ad8a4f18d5304c96d50aecad52c06a9fa673c4e0402e2e31a24ea532bced6331066ac8c0d6efa4366462082a08 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = f3e425af6aa16899624f20b49c4e9115034aa4d06ce9db9aa742a6e60d59d6ce0a067f5645b8e7f896c8561315ef1f7151e073d115f8e38df274438 -B = f6446ca278ff3bcc29f4d41689ba5490e5c523b9abe7cb380793d548c0035329de0ebbec7339dde9af37817cb7aab22241f397a6d3be9b39c1aed52d02c76bdb - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -18b2de417fc4bef91b5dd82b0e93315b306bf3a7f7bf0a486a567e9cd1370587b7e47adcb9accba03a8dfda5871b0bb1bdb569a90c079f7a9a4e87d2 -B = f6446ca2a0f05c68a063a9993b3d1ec73e1d3e262c88692d06217d4ad4cdfc35101b5ee10bbec0bbcd3fdb9c7ba53528fa6d954fa6920c1fdf1602e07c3d37e5 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 26b556807e84a9bf7cdf2697050cbd7145a42b8ef6fe10666da7a2e69827ad04880bb97ab3108a27da5fcc29a041bd6aebbaf00ab25a841674ff9f1e -B = -f6446ca2aef2d4a79f23945f9cbe6d333496ca3c41c0a11405608368d81f207ed70c065ddbe5ff59c6a39a241b7703ad13944708d49792818568e77c56ee4f31 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -40b258c2211cc2cb9e2614ab4b23cb9eadb1ddcae903c93646e9f5e5afcaf912a2fdef26c864d83dcdd6f434ca2b0aa7f8ea7a21e790a9e4601de110 -B = -f6446ca2478b2564ff8227d481b931f0e466412c4e6a97ba255ea9cc238d87b28f196046b0dc56b84b2e37be7340434ea9277ef5eff22854eb7db98181d0cf03 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 97631efbd149bb0fdecce09d14aedf2efe30407c01c68e000be9c7be954999375e1f7720e8e5f1edfc48b92f9a063f6b2b378996459bffeae3d362e3 -B = f6446ca1f0da5f2b4f552f90411265ff1adb2d9bfdec35090c9be5025e8db5d9a99ac021f5bacebe2aad1e0e44ce7e53d94c4a32bda518e08d72637afe1b4d30 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -15f4c3634bbbd1ce04fdf96a69b2b8263290e188ca83956b74c6d190e7b877dbd176657a19ea125dfe9c95d2764002ca5d98e28315cb391779d56fcb2 -B = f6446ca3e789b45bdc5c07806fbedd42cab58f2e252a8e11b69bc9b9b6e496a6ba6bd7166b409d80b23435dc2ae094aad752b643c26acaa82fc1f4dd7f45acc5 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 39ecc3b285eb99a2ac91329da615e581f791eaebd477d87c7739dd961a2c5c6cf86a34c73856efcf3b812909d830186c910f8f053192cac9fca8ab7a3 -B = -f6446ca62709b94f7f5884cae8f2707690e864ea753b244255dffac9de1556f9e1aa2028da7d925299020ceff929c820f6541066f9d592c9ec3b1005ac7967b6 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -707e64f8bee7a679d9b72bd04b231cda716f5dc1b7a404f8c0679770c46fc944470ee2a221d1e3d166619ba6a430d0349e7e75c0ee021ed027dab5d74 -B = -f6446c9b80572e9b32248302846c89977d583f23e52699699422237663fe068bf7e7c514e2ec1bbcf674d2e5dafd7d193045865400f54667f2ec76636443529f - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 9ca2c37f4b1a392c34551f570ff06a74c5f027170815454c5ed3535d5232df54fb1f65f2304e32b4995bb77ccd4ece69db98452f182dbeda98d525a19 -B = f6446c98be1146326efb57dcda8d512b3083657e9d1a04148d0e1e3c7d4247c31bb66409a1e3e6bc0eafe4b2ab5bbfb69e65a3002f584f85503275bc549c55fa - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1190fea35b9a1ba1c280d57888664aa7db5f9d6d4325b35a6276bf61291d67e6e14e3001f5af1753faff61fa53861ab8ed15d15965e0dcb05718bdecc6 -B = f6446cb4193c2182baba8c62a0b4bf2495d4b4a65bb9e2c83415cd64e136dec15c4c403aa20a47d4c2aa63f7407931d6f96d428afeadfbdcb3eb13bcfaac9cd9 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 209797b717f068e5f808dd2b4e12576fa056879da881bfcc1819228e4f9dc6f84347edbdbe273657d533d7c928e51b68a82c59d93dfb038514c104c1bc -B = -f6446cc31fd5353f1107d09828bc71ea41e17c6b52a4132d90223f1a839a0be7dcab519c9bc8039d3ac967d174ef00ac586df24615367bb4ce11e87aa2f371cf - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -7198b6aa26be42e97cad682aaa63d68d51952dae52d4cfe5f9a6acef93f35b6d7b7be87a1f2a944cf7fa9483cd6c3df7599d44c5b56e5ff38cd43d23c0 -B = -f6446c30ef86d400625c012372771bf1cbb37f7966eec73239928d08c3ca8e044b88ebddd7f1cbbfe8fec3044682b3b6071492444b97dcc164ae6fd90db18c53 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = cb788549eee4fa559118f0bd66b68d94845bdb7d07b2042d53a64921f3e3df76a2b143e9e9ad39dacaf405cec5fed9fd59050c5d27322142e4e11d4ede -B = f6446bd70fb834383ba4950f06ee893578fc7846a040f87d5c5e45aec42e5ba45b04e2b6a2965bf5665935314d1168bd74788c44e3d0454fa0ed208100d16135 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1122c39c2c252ec96e9274bdf713bfa8200e35ed9f18dd087fedd2005e5898b6f8ed37e1cd7e1f7b0c5be137a71a27b7e4e4669b1f412e154e6ad2ad567 -B = f6446db4b47740e9738b8189472b260d6b848ecbdf7b4f769c32fb014797837dc86fc8e8275862b6f58ac0c1ff2ab1f515ce07ec2f46546ae5efb84c8f19857a - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 2d57e15c8039f8367d2e0198d9fc27616e53efdc9cb0adc0b0199362d08f5698af1f07499cd2b72005f1c09900c71b677e57cd62094743a9b3ae541e74d -B = -f6446f780653462ac0225272fff8d43bf20023b03b1a3f50193e7e0403adaaa1344de44b444edfac3f05105b5d20c78fe509018365b2c30b4748fea0c7309760 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -539b4413477ef77c15fd53e202d8e5d183eb1c91fecf5b89959bb8d60d3f7907e95c5dd045d698a6a17f0150861b43bfeb2e5d40bdc970839b0712ee17f -B = -f6446768d3fc49af312729404aa1266ea12cf48c4a53559818a9d9a8aeea1cc44753dac38dfd4181aa08a5e451022f21bf168aeb0308969a3c0629b570bfce94 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = fe46dc4f55346ee27d6ced0256b0ec64f82d5150c3b49d4cc7d56a60ae5d10bb649a57f4c97acc146388a6a9d25d3c3c7e42372e46bb4f8a72171ea5979 -B = f6445cbe1a7888d3d9b0c2c9510f213120c3bd4827076949c48da68513d172b26dd8a30fae5af94766d1c9c3b6ac9a5d9f8ec1b9c569be0b1e15bc447004569a - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1fbd702bd26d37bb1fa554ad261f1e7161ea438f49b41aab950884c5c87eb1e0b9a3a69807b759a1440ef9e5683c1a13b9d610fd87fb131619cb63997891 -B = f6448c5ff8695094585a0a45748c6cbb4dfb6eb53fabbf39290e080aef3d4616f0c512fcfa724d966d34540b3afc9fbf8d664373f9da2a71e6247d31458828a4 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 260abc8cb124b3c17698ee342bdbe4b1513a085effb4f79aca252c98c8799ad203dccc9c305cdccd2edc16159d0e2c7a125c50f8abff9e12dbe8d93c655d -B = -f64492ad44ca2f4bd46061390e137278143b5e05047b753a05fd3d2797104611d9b65d362076763bf0603ed8572cd4919fcc9bfa39d54e7671213f4ebb2b1570 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -6f961198d2039a92d24c53bfcafd73251b575d5e06565db36666545d5994e511c4c3905cc0b93586f05916c08b8f51a0e0fe1b6253fcfa41bfec25196482 -B = -f643fd0c76a4ac23860c1853cc1f7b9ebc64f1739ebe6f2eb0af0c9c161a240359d29495c37d8525de0c1fa32a56abf421b1a89fcd7a4e79d8cca379bcd54b91 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = ed86313f32aabf2f7487dd9f587431e17b9a46e1a78fe89b0ebe81c737a73c2a8fef92c0963fc36e9808309d00c3bd14612fdf4fb236e06add8fe9329252 -B = f6437f1c56fe4b7c616f7618423fee27fda89130b53acdf525c76443e8b045f102b9c969c119af9f502477f4107a36bfb63e286e098cf03ff2a385d5f8bc1dc1 - -Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -1741bce7ae27a7b3effa5b08b39f9d03d69efe7b0716cc57dc106aac17925a2d77c18386f7398db17f813c9c6f2dfcc9347e9f55de76b11475fcf77bbedb1 -B = f645e0be56b860a19bddea45d06a8095ffc776bae3cce6f1d3e034091538f6bde1bbd5718c49b977eeab08100ade2a633fe5d187de3a89e1e455c33559aa9dc4 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = 20bd41a0d6d691e8554ee8b90a775e04f086f318b7afdc7b5d6d7c3b7ab6b955aa286809856e1bd195dace84b18b2d0365edc8e066d2e8db9ae8325d00843 -B = -f6467876a24aeb903f243f8eab6fee120fd9153a2da7f082d61849da2e2f2903d43efbdfd4729cc0d0ac6da9296250364388e87a76e30fa560c811e907beb856 - -Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 -A = -685147a1e74dab824bc6cb7fb30a773fbe5e380f46189574038d2d2f3983ced8777a080af6b06e9bb3c2d134a3302fa099b4bc78a4f01a4c157424ee3c773 -B = -f63de78e0e1f094c687a2e3367e415f4bb8e26e77b2813fbb7223a2f9783e55b515ce1b8d32adad829d7d3cf2dcd04807948ee52215253752e4d0c23930ae8a0 - -Sum = 1 -A = 0 -B = 1 - -Sum = 2 -A = 1 -B = 1 - -Sum = 4 -A = 3 -B = 1 - -Sum = 8 -A = 7 -B = 1 - -Sum = 10 -A = f -B = 1 - -Sum = 20 -A = 1f -B = 1 - -Sum = 40 -A = 3f -B = 1 - -Sum = 80 -A = 7f -B = 1 - -Sum = 100 -A = ff -B = 1 - -Sum = 200 -A = 1ff -B = 1 - -Sum = 400 -A = 3ff -B = 1 - -Sum = 800 -A = 7ff -B = 1 - -Sum = 1000 -A = fff -B = 1 - -Sum = 2000 -A = 1fff -B = 1 - -Sum = 4000 -A = 3fff -B = 1 - -Sum = 8000 -A = 7fff -B = 1 - -Sum = 10000 -A = ffff -B = 1 - -Sum = 20000 -A = 1ffff -B = 1 - -Sum = 40000 -A = 3ffff -B = 1 - -Sum = 80000 -A = 7ffff -B = 1 - -Sum = 100000 -A = fffff -B = 1 - -Sum = 200000 -A = 1fffff -B = 1 - -Sum = 400000 -A = 3fffff -B = 1 - -Sum = 800000 -A = 7fffff -B = 1 - -Sum = 1000000 -A = ffffff -B = 1 - -Sum = 2000000 -A = 1ffffff -B = 1 - -Sum = 4000000 -A = 3ffffff -B = 1 - -Sum = 8000000 -A = 7ffffff -B = 1 - -Sum = 10000000 -A = fffffff -B = 1 - -Sum = 20000000 -A = 1fffffff -B = 1 - -Sum = 40000000 -A = 3fffffff -B = 1 - -Sum = 80000000 -A = 7fffffff -B = 1 - -Sum = 100000000 -A = ffffffff -B = 1 - -Sum = 200000000 -A = 1ffffffff -B = 1 - -Sum = 400000000 -A = 3ffffffff -B = 1 - -Sum = 800000000 -A = 7ffffffff -B = 1 - -Sum = 1000000000 -A = fffffffff -B = 1 - -Sum = 2000000000 -A = 1fffffffff -B = 1 - -Sum = 4000000000 -A = 3fffffffff -B = 1 - -Sum = 8000000000 -A = 7fffffffff -B = 1 - -Sum = 10000000000 -A = ffffffffff -B = 1 - -Sum = 20000000000 -A = 1ffffffffff -B = 1 - -Sum = 40000000000 -A = 3ffffffffff -B = 1 - -Sum = 80000000000 -A = 7ffffffffff -B = 1 - -Sum = 100000000000 -A = fffffffffff -B = 1 - -Sum = 200000000000 -A = 1fffffffffff -B = 1 - -Sum = 400000000000 -A = 3fffffffffff -B = 1 - -Sum = 800000000000 -A = 7fffffffffff -B = 1 - -Sum = 1000000000000 -A = ffffffffffff -B = 1 - -Sum = 2000000000000 -A = 1ffffffffffff -B = 1 - -Sum = 4000000000000 -A = 3ffffffffffff -B = 1 - -Sum = 8000000000000 -A = 7ffffffffffff -B = 1 - -Sum = 10000000000000 -A = fffffffffffff -B = 1 - -Sum = 20000000000000 -A = 1fffffffffffff -B = 1 - -Sum = 40000000000000 -A = 3fffffffffffff -B = 1 - -Sum = 80000000000000 -A = 7fffffffffffff -B = 1 - -Sum = 100000000000000 -A = ffffffffffffff -B = 1 - -Sum = 200000000000000 -A = 1ffffffffffffff -B = 1 - -Sum = 400000000000000 -A = 3ffffffffffffff -B = 1 - -Sum = 800000000000000 -A = 7ffffffffffffff -B = 1 - -Sum = 1000000000000000 -A = fffffffffffffff -B = 1 - -Sum = 2000000000000000 -A = 1fffffffffffffff -B = 1 - -Sum = 4000000000000000 -A = 3fffffffffffffff -B = 1 - -Sum = 8000000000000000 -A = 7fffffffffffffff -B = 1 - -Sum = 10000000000000000 -A = ffffffffffffffff -B = 1 - -Sum = 20000000000000000 -A = 1ffffffffffffffff -B = 1 - -Sum = 40000000000000000 -A = 3ffffffffffffffff -B = 1 - -Sum = 80000000000000000 -A = 7ffffffffffffffff -B = 1 - -Sum = 100000000000000000 -A = fffffffffffffffff -B = 1 - -Sum = 200000000000000000 -A = 1fffffffffffffffff -B = 1 - -Sum = 400000000000000000 -A = 3fffffffffffffffff -B = 1 - -Sum = 800000000000000000 -A = 7fffffffffffffffff -B = 1 - -Sum = 1000000000000000000 -A = ffffffffffffffffff -B = 1 - -Sum = 2000000000000000000 -A = 1ffffffffffffffffff -B = 1 - -Sum = 4000000000000000000 -A = 3ffffffffffffffffff -B = 1 - -Sum = 8000000000000000000 -A = 7ffffffffffffffffff -B = 1 - -Sum = 10000000000000000000 -A = fffffffffffffffffff -B = 1 - -Sum = 20000000000000000000 -A = 1fffffffffffffffffff -B = 1 - -Sum = 40000000000000000000 -A = 3fffffffffffffffffff -B = 1 - -Sum = 80000000000000000000 -A = 7fffffffffffffffffff -B = 1 - -Sum = 100000000000000000000 -A = ffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000 -A = 1ffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000 -A = 3ffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000 -A = 7ffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000 -A = fffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000 -A = 1fffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000 -A = 3fffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000 -A = 7fffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000 -A = ffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000 -A = 1ffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000 -A = 3ffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000 -A = 7ffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000 -A = fffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000 -A = 1fffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000 -A = 3fffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000 -A = 7fffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000 -A = ffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000 -A = 1ffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000 -A = 3ffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000 -A = 7ffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000 -A = fffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000 -A = 1fffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000 -A = 3fffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000 -A = 7fffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000 -A = ffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000 -A = 1ffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000 -A = 3ffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000 -A = 7ffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000 -A = fffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000 -A = 1fffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000 -A = 3fffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000 -A = 7fffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000 -A = ffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000 -A = 1ffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000 -A = 3ffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000 -A = 7ffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000 -A = fffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000 -A = 1fffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000 -A = 3fffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000 -A = 7fffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000 -A = ffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000 -A = fffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 200000000000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 400000000000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 800000000000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 1000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 2000000000000000000000000000000000000000000000000 -A = 1ffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 4000000000000000000000000000000000000000000000000 -A = 3ffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 8000000000000000000000000000000000000000000000000 -A = 7ffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 10000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 20000000000000000000000000000000000000000000000000 -A = 1fffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 40000000000000000000000000000000000000000000000000 -A = 3fffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 80000000000000000000000000000000000000000000000000 -A = 7fffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffffff -B = 1 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffffe -B = 2 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffffc -B = 4 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffff8 -B = 8 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffff0 -B = 10 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffffe0 -B = 20 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffffc0 -B = 40 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffff80 -B = 80 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffff00 -B = 100 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffe00 -B = 200 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffffc00 -B = 400 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffff800 -B = 800 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffff000 -B = 1000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffe000 -B = 2000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffffc000 -B = 4000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffff8000 -B = 8000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffff0000 -B = 10000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffe0000 -B = 20000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffffc0000 -B = 40000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffff80000 -B = 80000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffff00000 -B = 100000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffe00000 -B = 200000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffffc00000 -B = 400000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffff800000 -B = 800000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffff000000 -B = 1000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffe000000 -B = 2000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffffc000000 -B = 4000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffff8000000 -B = 8000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffff0000000 -B = 10000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffe0000000 -B = 20000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffffc0000000 -B = 40000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffff80000000 -B = 80000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffff00000000 -B = 100000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffe00000000 -B = 200000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffffc00000000 -B = 400000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffff800000000 -B = 800000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffff000000000 -B = 1000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffe000000000 -B = 2000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffffc000000000 -B = 4000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffff8000000000 -B = 8000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffff0000000000 -B = 10000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffe0000000000 -B = 20000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffffc0000000000 -B = 40000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffff80000000000 -B = 80000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffff00000000000 -B = 100000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffe00000000000 -B = 200000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffffc00000000000 -B = 400000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffff800000000000 -B = 800000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffff000000000000 -B = 1000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffe000000000000 -B = 2000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffffc000000000000 -B = 4000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffff8000000000000 -B = 8000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffff0000000000000 -B = 10000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffe0000000000000 -B = 20000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffffc0000000000000 -B = 40000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffff80000000000000 -B = 80000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffff00000000000000 -B = 100000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffe00000000000000 -B = 200000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffffc00000000000000 -B = 400000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffff800000000000000 -B = 800000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffff000000000000000 -B = 1000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffe000000000000000 -B = 2000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffffc000000000000000 -B = 4000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffff8000000000000000 -B = 8000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffff0000000000000000 -B = 10000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffe0000000000000000 -B = 20000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffffc0000000000000000 -B = 40000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffff80000000000000000 -B = 80000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffff00000000000000000 -B = 100000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffe00000000000000000 -B = 200000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffffc00000000000000000 -B = 400000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffff800000000000000000 -B = 800000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffff000000000000000000 -B = 1000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffe000000000000000000 -B = 2000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffffc000000000000000000 -B = 4000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffff8000000000000000000 -B = 8000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffff0000000000000000000 -B = 10000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffe0000000000000000000 -B = 20000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffffc0000000000000000000 -B = 40000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffff80000000000000000000 -B = 80000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffff00000000000000000000 -B = 100000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffe00000000000000000000 -B = 200000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffffc00000000000000000000 -B = 400000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffff800000000000000000000 -B = 800000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffff000000000000000000000 -B = 1000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffe000000000000000000000 -B = 2000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffffc000000000000000000000 -B = 4000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffff8000000000000000000000 -B = 8000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffff0000000000000000000000 -B = 10000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffe0000000000000000000000 -B = 20000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffffc0000000000000000000000 -B = 40000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffff80000000000000000000000 -B = 80000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffff00000000000000000000000 -B = 100000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffe00000000000000000000000 -B = 200000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffffc00000000000000000000000 -B = 400000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffff800000000000000000000000 -B = 800000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffff000000000000000000000000 -B = 1000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffe000000000000000000000000 -B = 2000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffffc000000000000000000000000 -B = 4000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffff8000000000000000000000000 -B = 8000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffff0000000000000000000000000 -B = 10000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffe0000000000000000000000000 -B = 20000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffffc0000000000000000000000000 -B = 40000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffff80000000000000000000000000 -B = 80000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffff00000000000000000000000000 -B = 100000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffe00000000000000000000000000 -B = 200000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffffc00000000000000000000000000 -B = 400000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffff800000000000000000000000000 -B = 800000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffff000000000000000000000000000 -B = 1000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffe000000000000000000000000000 -B = 2000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffffc000000000000000000000000000 -B = 4000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffff8000000000000000000000000000 -B = 8000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffff0000000000000000000000000000 -B = 10000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffe0000000000000000000000000000 -B = 20000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffffc0000000000000000000000000000 -B = 40000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffff80000000000000000000000000000 -B = 80000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffff00000000000000000000000000000 -B = 100000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffe00000000000000000000000000000 -B = 200000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffffc00000000000000000000000000000 -B = 400000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffff800000000000000000000000000000 -B = 800000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffff000000000000000000000000000000 -B = 1000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffe000000000000000000000000000000 -B = 2000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffffc000000000000000000000000000000 -B = 4000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffff8000000000000000000000000000000 -B = 8000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffff0000000000000000000000000000000 -B = 10000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffe0000000000000000000000000000000 -B = 20000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffffc0000000000000000000000000000000 -B = 40000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffff80000000000000000000000000000000 -B = 80000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffff00000000000000000000000000000000 -B = 100000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffe00000000000000000000000000000000 -B = 200000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffffc00000000000000000000000000000000 -B = 400000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffff800000000000000000000000000000000 -B = 800000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffff000000000000000000000000000000000 -B = 1000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffe000000000000000000000000000000000 -B = 2000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffffc000000000000000000000000000000000 -B = 4000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffff8000000000000000000000000000000000 -B = 8000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffff0000000000000000000000000000000000 -B = 10000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffe0000000000000000000000000000000000 -B = 20000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffffc0000000000000000000000000000000000 -B = 40000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffff80000000000000000000000000000000000 -B = 80000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffff00000000000000000000000000000000000 -B = 100000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffe00000000000000000000000000000000000 -B = 200000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffffc00000000000000000000000000000000000 -B = 400000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffff800000000000000000000000000000000000 -B = 800000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffff000000000000000000000000000000000000 -B = 1000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffe000000000000000000000000000000000000 -B = 2000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffffc000000000000000000000000000000000000 -B = 4000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffff8000000000000000000000000000000000000 -B = 8000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffff0000000000000000000000000000000000000 -B = 10000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffe0000000000000000000000000000000000000 -B = 20000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffffc0000000000000000000000000000000000000 -B = 40000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffff80000000000000000000000000000000000000 -B = 80000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffff00000000000000000000000000000000000000 -B = 100000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffe00000000000000000000000000000000000000 -B = 200000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffffc00000000000000000000000000000000000000 -B = 400000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffff800000000000000000000000000000000000000 -B = 800000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffff000000000000000000000000000000000000000 -B = 1000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffe000000000000000000000000000000000000000 -B = 2000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffffc000000000000000000000000000000000000000 -B = 4000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffff8000000000000000000000000000000000000000 -B = 8000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffff0000000000000000000000000000000000000000 -B = 10000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffe0000000000000000000000000000000000000000 -B = 20000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffffc0000000000000000000000000000000000000000 -B = 40000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffff80000000000000000000000000000000000000000 -B = 80000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffff00000000000000000000000000000000000000000 -B = 100000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffe00000000000000000000000000000000000000000 -B = 200000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffffc00000000000000000000000000000000000000000 -B = 400000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffff800000000000000000000000000000000000000000 -B = 800000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffff000000000000000000000000000000000000000000 -B = 1000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffe000000000000000000000000000000000000000000 -B = 2000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffffc000000000000000000000000000000000000000000 -B = 4000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffff8000000000000000000000000000000000000000000 -B = 8000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffff0000000000000000000000000000000000000000000 -B = 10000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffe0000000000000000000000000000000000000000000 -B = 20000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffffc0000000000000000000000000000000000000000000 -B = 40000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffff80000000000000000000000000000000000000000000 -B = 80000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffff00000000000000000000000000000000000000000000 -B = 100000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffe00000000000000000000000000000000000000000000 -B = 200000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffffc00000000000000000000000000000000000000000000 -B = 400000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffff800000000000000000000000000000000000000000000 -B = 800000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffff000000000000000000000000000000000000000000000 -B = 1000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffe000000000000000000000000000000000000000000000 -B = 2000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffffc000000000000000000000000000000000000000000000 -B = 4000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffff8000000000000000000000000000000000000000000000 -B = 8000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffff0000000000000000000000000000000000000000000000 -B = 10000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffe0000000000000000000000000000000000000000000000 -B = 20000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fffc0000000000000000000000000000000000000000000000 -B = 40000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fff80000000000000000000000000000000000000000000000 -B = 80000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fff00000000000000000000000000000000000000000000000 -B = 100000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffe00000000000000000000000000000000000000000000000 -B = 200000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ffc00000000000000000000000000000000000000000000000 -B = 400000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ff800000000000000000000000000000000000000000000000 -B = 800000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = ff000000000000000000000000000000000000000000000000 -B = 1000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fe000000000000000000000000000000000000000000000000 -B = 2000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = fc000000000000000000000000000000000000000000000000 -B = 4000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = f8000000000000000000000000000000000000000000000000 -B = 8000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = f0000000000000000000000000000000000000000000000000 -B = 10000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = e0000000000000000000000000000000000000000000000000 -B = 20000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = c0000000000000000000000000000000000000000000000000 -B = 40000000000000000000000000000000000000000000000000 - -Sum = 100000000000000000000000000000000000000000000000000 -A = 80000000000000000000000000000000000000000000000000 -B = 80000000000000000000000000000000000000000000000000 - - -# LShift1 tests. -# -# These test vectors satisfy A * 2 = LShift1 - -LShift1 = 0 -A = 0 - -LShift1 = 13116120bca5df64e13f314254 -A = 988b0905e52efb2709f98a12a - -LShift1 = -13116120bca5df64e13f314254 -A = -988b0905e52efb2709f98a12a - -LShift1 = 2622c241794bbec9c27e6284a8 -A = 13116120bca5df64e13f314254 - -LShift1 = -2622c241794bbec9c27e6284a8 -A = -13116120bca5df64e13f314254 - -LShift1 = 4c458482f2977d9384fcc50950 -A = 2622c241794bbec9c27e6284a8 - -LShift1 = -4c458482f2977d9384fcc50950 -A = -2622c241794bbec9c27e6284a8 - -LShift1 = 988b0905e52efb2709f98a12a2 -A = 4c458482f2977d9384fcc50951 - -LShift1 = -988b0905e52efb2709f98a12a2 -A = -4c458482f2977d9384fcc50951 - -LShift1 = 13116120bca5df64e13f3142544 -A = 988b0905e52efb2709f98a12a2 - -LShift1 = -13116120bca5df64e13f3142544 -A = -988b0905e52efb2709f98a12a2 - -LShift1 = 2622c241794bbec9c27e6284a8a -A = 13116120bca5df64e13f3142545 - -LShift1 = -2622c241794bbec9c27e6284a8a -A = -13116120bca5df64e13f3142545 - -LShift1 = 4c458482f2977d9384fcc509514 -A = 2622c241794bbec9c27e6284a8a - -LShift1 = -4c458482f2977d9384fcc509514 -A = -2622c241794bbec9c27e6284a8a - -LShift1 = 988b0905e52efb2709f98a12a28 -A = 4c458482f2977d9384fcc509514 - -LShift1 = -988b0905e52efb2709f98a12a28 -A = -4c458482f2977d9384fcc509514 - -LShift1 = 13116120bca5df64e13f31425450 -A = 988b0905e52efb2709f98a12a28 - -LShift1 = -13116120bca5df64e13f31425450 -A = -988b0905e52efb2709f98a12a28 - -LShift1 = 2622c241794bbec9c27e6284a8a0 -A = 13116120bca5df64e13f31425450 - -LShift1 = -2622c241794bbec9c27e6284a8a0 -A = -13116120bca5df64e13f31425450 - -LShift1 = 4c458482f2977d9384fcc5095142 -A = 2622c241794bbec9c27e6284a8a1 - -LShift1 = -4c458482f2977d9384fcc5095142 -A = -2622c241794bbec9c27e6284a8a1 - -LShift1 = 988b0905e52efb2709f98a12a286 -A = 4c458482f2977d9384fcc5095143 - -LShift1 = -988b0905e52efb2709f98a12a286 -A = -4c458482f2977d9384fcc5095143 - -LShift1 = 13116120bca5df64e13f31425450c -A = 988b0905e52efb2709f98a12a286 - -LShift1 = -13116120bca5df64e13f31425450c -A = -988b0905e52efb2709f98a12a286 - -LShift1 = 2622c241794bbec9c27e6284a8a18 -A = 13116120bca5df64e13f31425450c - -LShift1 = -2622c241794bbec9c27e6284a8a18 -A = -13116120bca5df64e13f31425450c - -LShift1 = 4c458482f2977d9384fcc50951430 -A = 2622c241794bbec9c27e6284a8a18 - -LShift1 = -4c458482f2977d9384fcc50951430 -A = -2622c241794bbec9c27e6284a8a18 - -LShift1 = 988b0905e52efb2709f98a12a2862 -A = 4c458482f2977d9384fcc50951431 - -LShift1 = -988b0905e52efb2709f98a12a2862 -A = -4c458482f2977d9384fcc50951431 - -LShift1 = 13116120bca5df64e13f31425450c6 -A = 988b0905e52efb2709f98a12a2863 - -LShift1 = -13116120bca5df64e13f31425450c6 -A = -988b0905e52efb2709f98a12a2863 - -LShift1 = 2622c241794bbec9c27e6284a8a18e -A = 13116120bca5df64e13f31425450c7 - -LShift1 = -2622c241794bbec9c27e6284a8a18e -A = -13116120bca5df64e13f31425450c7 - -LShift1 = 4c458482f2977d9384fcc50951431e -A = 2622c241794bbec9c27e6284a8a18f - -LShift1 = -4c458482f2977d9384fcc50951431e -A = -2622c241794bbec9c27e6284a8a18f - -LShift1 = 988b0905e52efb2709f98a12a2863c -A = 4c458482f2977d9384fcc50951431e - -LShift1 = -988b0905e52efb2709f98a12a2863c -A = -4c458482f2977d9384fcc50951431e - -LShift1 = 13116120bca5df64e13f31425450c7a -A = 988b0905e52efb2709f98a12a2863d - -LShift1 = -13116120bca5df64e13f31425450c7a -A = -988b0905e52efb2709f98a12a2863d - -LShift1 = 2622c241794bbec9c27e6284a8a18f4 -A = 13116120bca5df64e13f31425450c7a - -LShift1 = -2622c241794bbec9c27e6284a8a18f4 -A = -13116120bca5df64e13f31425450c7a - -LShift1 = 4c458482f2977d9384fcc50951431e8 -A = 2622c241794bbec9c27e6284a8a18f4 - -LShift1 = -4c458482f2977d9384fcc50951431e8 -A = -2622c241794bbec9c27e6284a8a18f4 - -LShift1 = 988b0905e52efb2709f98a12a2863d2 -A = 4c458482f2977d9384fcc50951431e9 - -LShift1 = -988b0905e52efb2709f98a12a2863d2 -A = -4c458482f2977d9384fcc50951431e9 - -LShift1 = 13116120bca5df64e13f31425450c7a4 -A = 988b0905e52efb2709f98a12a2863d2 - -LShift1 = -13116120bca5df64e13f31425450c7a4 -A = -988b0905e52efb2709f98a12a2863d2 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4a -A = 13116120bca5df64e13f31425450c7a5 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4a -A = -13116120bca5df64e13f31425450c7a5 - -LShift1 = 4c458482f2977d9384fcc50951431e94 -A = 2622c241794bbec9c27e6284a8a18f4a - -LShift1 = -4c458482f2977d9384fcc50951431e94 -A = -2622c241794bbec9c27e6284a8a18f4a - -LShift1 = 988b0905e52efb2709f98a12a2863d2a -A = 4c458482f2977d9384fcc50951431e95 - -LShift1 = -988b0905e52efb2709f98a12a2863d2a -A = -4c458482f2977d9384fcc50951431e95 - -LShift1 = 13116120bca5df64e13f31425450c7a56 -A = 988b0905e52efb2709f98a12a2863d2b - -LShift1 = -13116120bca5df64e13f31425450c7a56 -A = -988b0905e52efb2709f98a12a2863d2b - -LShift1 = 2622c241794bbec9c27e6284a8a18f4ae -A = 13116120bca5df64e13f31425450c7a57 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4ae -A = -13116120bca5df64e13f31425450c7a57 - -LShift1 = 4c458482f2977d9384fcc50951431e95c -A = 2622c241794bbec9c27e6284a8a18f4ae - -LShift1 = -4c458482f2977d9384fcc50951431e95c -A = -2622c241794bbec9c27e6284a8a18f4ae - -LShift1 = 988b0905e52efb2709f98a12a2863d2ba -A = 4c458482f2977d9384fcc50951431e95d - -LShift1 = -988b0905e52efb2709f98a12a2863d2ba -A = -4c458482f2977d9384fcc50951431e95d - -LShift1 = 13116120bca5df64e13f31425450c7a576 -A = 988b0905e52efb2709f98a12a2863d2bb - -LShift1 = -13116120bca5df64e13f31425450c7a576 -A = -988b0905e52efb2709f98a12a2863d2bb - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aee -A = 13116120bca5df64e13f31425450c7a577 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aee -A = -13116120bca5df64e13f31425450c7a577 - -LShift1 = 4c458482f2977d9384fcc50951431e95de -A = 2622c241794bbec9c27e6284a8a18f4aef - -LShift1 = -4c458482f2977d9384fcc50951431e95de -A = -2622c241794bbec9c27e6284a8a18f4aef - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbc -A = 4c458482f2977d9384fcc50951431e95de - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbc -A = -4c458482f2977d9384fcc50951431e95de - -LShift1 = 13116120bca5df64e13f31425450c7a577a -A = 988b0905e52efb2709f98a12a2863d2bbd - -LShift1 = -13116120bca5df64e13f31425450c7a577a -A = -988b0905e52efb2709f98a12a2863d2bbd - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef4 -A = 13116120bca5df64e13f31425450c7a577a - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef4 -A = -13116120bca5df64e13f31425450c7a577a - -LShift1 = 4c458482f2977d9384fcc50951431e95dea -A = 2622c241794bbec9c27e6284a8a18f4aef5 - -LShift1 = -4c458482f2977d9384fcc50951431e95dea -A = -2622c241794bbec9c27e6284a8a18f4aef5 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6 -A = 4c458482f2977d9384fcc50951431e95deb - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6 -A = -4c458482f2977d9384fcc50951431e95deb - -LShift1 = 13116120bca5df64e13f31425450c7a577ac -A = 988b0905e52efb2709f98a12a2863d2bbd6 - -LShift1 = -13116120bca5df64e13f31425450c7a577ac -A = -988b0905e52efb2709f98a12a2863d2bbd6 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5a -A = 13116120bca5df64e13f31425450c7a577ad - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5a -A = -13116120bca5df64e13f31425450c7a577ad - -LShift1 = 4c458482f2977d9384fcc50951431e95deb4 -A = 2622c241794bbec9c27e6284a8a18f4aef5a - -LShift1 = -4c458482f2977d9384fcc50951431e95deb4 -A = -2622c241794bbec9c27e6284a8a18f4aef5a - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6a -A = 4c458482f2977d9384fcc50951431e95deb5 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6a -A = -4c458482f2977d9384fcc50951431e95deb5 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad6 -A = 988b0905e52efb2709f98a12a2863d2bbd6b - -LShift1 = -13116120bca5df64e13f31425450c7a577ad6 -A = -988b0905e52efb2709f98a12a2863d2bbd6b - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5ae -A = 13116120bca5df64e13f31425450c7a577ad7 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5ae -A = -13116120bca5df64e13f31425450c7a577ad7 - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5e -A = 2622c241794bbec9c27e6284a8a18f4aef5af - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5e -A = -2622c241794bbec9c27e6284a8a18f4aef5af - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6be -A = 4c458482f2977d9384fcc50951431e95deb5f - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6be -A = -4c458482f2977d9384fcc50951431e95deb5f - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7e -A = 988b0905e52efb2709f98a12a2863d2bbd6bf - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7e -A = -988b0905e52efb2709f98a12a2863d2bbd6bf - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5afe -A = 13116120bca5df64e13f31425450c7a577ad7f - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5afe -A = -13116120bca5df64e13f31425450c7a577ad7f - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5fe -A = 2622c241794bbec9c27e6284a8a18f4aef5aff - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5fe -A = -2622c241794bbec9c27e6284a8a18f4aef5aff - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bfe -A = 4c458482f2977d9384fcc50951431e95deb5ff - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bfe -A = -4c458482f2977d9384fcc50951431e95deb5ff - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe -A = 988b0905e52efb2709f98a12a2863d2bbd6bff - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe -A = -988b0905e52efb2709f98a12a2863d2bbd6bff - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc -A = 13116120bca5df64e13f31425450c7a577ad7fe - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc -A = -13116120bca5df64e13f31425450c7a577ad7fe - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff8 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff8 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff0 -A = 4c458482f2977d9384fcc50951431e95deb5ff8 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff0 -A = -4c458482f2977d9384fcc50951431e95deb5ff8 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0 -A = 988b0905e52efb2709f98a12a2863d2bbd6bff0 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0 -A = -988b0905e52efb2709f98a12a2863d2bbd6bff0 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc0 -A = 13116120bca5df64e13f31425450c7a577ad7fe0 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc0 -A = -13116120bca5df64e13f31425450c7a577ad7fe0 - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff82 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1 - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff82 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06 -A = 4c458482f2977d9384fcc50951431e95deb5ff83 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06 -A = -4c458482f2977d9384fcc50951431e95deb5ff83 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0c -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0c -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1a -A = 13116120bca5df64e13f31425450c7a577ad7fe0d - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1a -A = -13116120bca5df64e13f31425450c7a577ad7fe0d - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06c -A = 4c458482f2977d9384fcc50951431e95deb5ff836 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06c -A = -4c458482f2977d9384fcc50951431e95deb5ff836 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0da -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06d - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0da -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06d - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b6 -A = 13116120bca5df64e13f31425450c7a577ad7fe0db - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b6 -A = -13116120bca5df64e13f31425450c7a577ad7fe0db - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836e -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7 - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836e -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06de -A = 4c458482f2977d9384fcc50951431e95deb5ff836f - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06de -A = -4c458482f2977d9384fcc50951431e95deb5ff836f - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbe -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbe -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7c -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbe - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7c -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbe - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fa -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7d - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fa -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7d - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6 -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6 -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbec -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbec -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7da -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7da -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb6 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb6 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb6 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb6 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8 -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8 -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8 - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0 -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0 -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60 - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed82 -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed82 -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed83 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed83 - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18 -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18 -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed832 -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed832 -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066 -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833 - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066 -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833 - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60ce -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067 - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60ce -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067 - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cf - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cf - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6 -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6 -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7 - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7 - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf - -LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe -A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f - -LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe -A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f - -LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc -A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe - -LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc -A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe - -LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 -A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc - -LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 -A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc - -LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0 -A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 - -LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0 -A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 - -LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 -A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 - -LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 -A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 - -LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 -A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 - -LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 -A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 - -LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 -A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 - -LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 -A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 - -LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000 -A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 - -LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000 -A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 - - -# LShift tests -# -# These test vectors satisfy A * 2^N = LShift. - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 6 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 7 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 8 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 9 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 10 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 11 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 12 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 13 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 14 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 15 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 16 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 17 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 18 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 19 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 1f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 20 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 21 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 22 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 23 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 24 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 25 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 26 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 27 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 28 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 29 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 2f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 30 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 31 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 32 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 33 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 34 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 35 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 36 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 37 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 38 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 39 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 3f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 40 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 41 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 42 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 43 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 44 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 45 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 46 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 47 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 48 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 49 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 4f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 50 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 51 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 52 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 53 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 54 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 55 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 56 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 57 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 58 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 59 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5a - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5b - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5c - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5d - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5e - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 5f - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 60 - -LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 61 - -LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 62 - -LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 63 - -LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000000 -A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 -N = 64 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 6 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 7 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 8 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 9 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 10 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 11 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 12 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 13 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 14 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 15 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 16 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 17 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 18 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 19 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 1f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 20 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 21 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 22 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 23 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 24 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 25 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 26 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 27 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 28 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 29 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 2f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 30 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 31 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 32 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 33 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 34 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 35 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 36 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 37 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 38 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 39 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 3f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 40 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 41 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 42 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 43 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 44 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 45 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 46 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 47 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 48 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 49 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 4f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 50 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 51 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 52 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 53 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 54 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 55 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 56 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 57 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 58 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 59 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5a - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5b - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5c - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5d - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5e - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 5f - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 60 - -LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 61 - -LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 62 - -LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 63 - -LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000000 -A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e -N = 64 - - -# RShift tests -# -# These test vectors satisfy A / 2^N = RShift, rounding towards zero. - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36380 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c0 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e0 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c70 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3638 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 6 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 7 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c7 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 8 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b363 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 9 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = a - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = b - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = c - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = d - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = e - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = f - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 10 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 11 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 12 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ec -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 13 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f6 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 14 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 15 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 16 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365e -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 17 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 18 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 19 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cb -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1a - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1b - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1c - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd9 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1d - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66c -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1e - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b36 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 1f - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 20 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 21 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 22 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b3 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 23 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 24 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596c -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 25 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb6 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 26 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 27 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 28 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 29 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2a - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2b - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2c - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d59 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2d - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806ac -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2e - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa5740356 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 2f - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 30 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d5 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 31 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806a -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 32 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa574035 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 33 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01a -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 34 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00d -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 35 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae806 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 36 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 37 - -RShift = d9ce8dff4f2f39c216ea39a461080552ba01 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 38 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d00 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 39 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae80 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3a - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa5740 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3b - -RShift = d9ce8dff4f2f39c216ea39a461080552ba0 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3c - -RShift = 6ce746ffa7979ce10b751cd2308402a95d0 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3d - -RShift = 3673a37fd3cbce7085ba8e6918420154ae8 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3e - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa574 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 3f - -RShift = d9ce8dff4f2f39c216ea39a461080552ba -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 40 - -RShift = 6ce746ffa7979ce10b751cd2308402a95d -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 41 - -RShift = 3673a37fd3cbce7085ba8e6918420154ae -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 42 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa57 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 43 - -RShift = d9ce8dff4f2f39c216ea39a461080552b -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 44 - -RShift = 6ce746ffa7979ce10b751cd2308402a95 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 45 - -RShift = 3673a37fd3cbce7085ba8e6918420154a -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 46 - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa5 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 47 - -RShift = d9ce8dff4f2f39c216ea39a461080552 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 48 - -RShift = 6ce746ffa7979ce10b751cd2308402a9 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 49 - -RShift = 3673a37fd3cbce7085ba8e6918420154 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4a - -RShift = 1b39d1bfe9e5e73842dd47348c2100aa -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4b - -RShift = d9ce8dff4f2f39c216ea39a46108055 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4c - -RShift = 6ce746ffa7979ce10b751cd2308402a -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4d - -RShift = 3673a37fd3cbce7085ba8e691842015 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4e - -RShift = 1b39d1bfe9e5e73842dd47348c2100a -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 4f - -RShift = d9ce8dff4f2f39c216ea39a4610805 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 50 - -RShift = 6ce746ffa7979ce10b751cd2308402 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 51 - -RShift = 3673a37fd3cbce7085ba8e69184201 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 52 - -RShift = 1b39d1bfe9e5e73842dd47348c2100 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 53 - -RShift = d9ce8dff4f2f39c216ea39a461080 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 54 - -RShift = 6ce746ffa7979ce10b751cd230840 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 55 - -RShift = 3673a37fd3cbce7085ba8e6918420 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 56 - -RShift = 1b39d1bfe9e5e73842dd47348c210 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 57 - -RShift = d9ce8dff4f2f39c216ea39a46108 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 58 - -RShift = 6ce746ffa7979ce10b751cd23084 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 59 - -RShift = 3673a37fd3cbce7085ba8e691842 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5a - -RShift = 1b39d1bfe9e5e73842dd47348c21 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5b - -RShift = d9ce8dff4f2f39c216ea39a4610 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5c - -RShift = 6ce746ffa7979ce10b751cd2308 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5d - -RShift = 3673a37fd3cbce7085ba8e69184 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5e - -RShift = 1b39d1bfe9e5e73842dd47348c2 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 5f - -RShift = d9ce8dff4f2f39c216ea39a461 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 60 - -RShift = 6ce746ffa7979ce10b751cd230 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 61 - -RShift = 3673a37fd3cbce7085ba8e6918 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 62 - -RShift = 1b39d1bfe9e5e73842dd47348c -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 63 - -RShift = d9ce8dff4f2f39c216ea39a46 -A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 -N = 64 - - -# Square tests. -# -# These test vectors satisfy A^2 = Square. - -# Regression test for a BN_sqr overflow bug. -Square = 4000000000000000800000000000000240000000000000000000000000000001fffffffffffffff8000000000000000400000000000000000000000000000000 -A = 80000000000000008000000000000001fffffffffffffffe0000000000000000 - -# Regression test for a BN_sqr overflow bug. -Square = 40000000000000000000000080000001fffffffe000000004000000200000001fffffff800000004000000000000000000000000000000000000000000000000 -A = 80000000000000000000000080000001fffffffe000000000000000000000000 - -Square = c2fa18e1d110a4639781 -A = -df6a253c3f - -Square = 4805f01d379f4ce8dc86ed269 -A = 21f253ddb5a6d - -Square = 57def107babc1c2bffeff858947e69 -A = -95fbaee5a09c86d - -Square = f3b01f7941961b3f5cc3361e3ac82423690 -A = -3e71292dd4ad3ed3b4 - -Square = 5e2d9c36d498ad1e8b6113f442ac513eaca74601 -A = 9b45cf6c7a43d910dcff - -Square = 7b7c2eb3fe55615e422b41c6f725341527626398cdee4 -A = 2c7314e72a2ffeef170de2a - -Square = af57c0ed328886642ed5d631b375fc89c03a99f1b427c6bbd1 -A = d3de077f8286a04daa9c497c9 - -Square = 4d9eac3058e6cbc0d12e639ced961c02ec1870afed62fdd44c67ce4 -A = -233da7e87ea4421ee8fe7e00c856 - -Square = 83c292d277fae28cfede74e8e80eba11dc132e16f78cdf64595c12c7dee4 -A = -b7a8aa7452678abd45d2ae6c349e2a - -Square = c80e07dd01f9d19a5cf7f3c328ccf4de70fdd113de69382701294dd29674b9a90 -A = 389387eead58fef2c76b5cf920f35c5cc - -Square = b9f69ca47ac855830fd7ed39c81822c520880c51c3ea60d3ccc106db37fc2b04c47831 -A = -da307c28ea67ca8d3117364ba93f0731bf9 - -Square = 81bbe3a13a22a73778233294ba0c132d9dddec111f768300f177468c204f8eab69b98e62d99 -A = -2d8f715bb32d410b4f475c4d000d56fec7cfc5 - -Square = f815ce34e9bc2e31e36e75cf49b2d15306d438a2a713b2a85b3ea156ba60c867c28cc65aa58fdf11 -A = fc02f2e1a26cd69f6a0e54cca4bbced739b43597 - -Square = 5f968707f58ea15c492ec9677be09c309d91164aafa754ab16ca47a411b5b2249858fb6f96135992e8a04 -A = 271b8eae3e96cc4900d4413d6c00b73736a5d89ed7e - -Square = 4aa616aabcdc7ad48dcfd40d71e00a3789bbf549ff39b3e2ebb52017cb56014941961a5a6d52d7a9980fc99b49 -A = 8a3d3f15e6d7d2130aebd8cb99767defbe4c7704e3c1d - -Square = 845e46db8c40f3f6f6f4928b5748618f021f9064c6522bcf2df004f8d2105e90cd354785c15a6cc32fcc77da2ea3001 -A = -2e0543ac8b8255ce30253cf2047a0ff353dea55a58551801 - -Square = 5dc5706dde9b326feb79941f08bd296ec3b6fb67270516b70fad9921438b9175f395310fb756b60d72d8e73e84ee8673cc40 -A = -9aefd7dfa709dec9e721f5c22867229435b2d6366462d0e438 - -Square = 63dc6565adba27974a66bdcc626596e16cf399541d679f754d9063ceeb320649bec09a940309dd1eae5fbba0b558939afae9689c9 -A = 27f8e071f70b0053d70eca9c6d1e28303b8da2d3c58083c2cc45d - -Square = cf2176449bb8b215fc37288b904ca27d5d410780fd054d2a190a94b405f6aa41970b41ba3cc43eaabb97c2248e1e21457949070ec0f6a4 -A = -e645c7edc27512d4b3170d3c5430d0712a25c13afcc09c9b30bb11a - -Square = 43194e5f12e828db6735824c194985108269ddec12c49a14658be3c2b7d298c2846da1aa3ecb7064e73c317af595601de59035faab6dc0fd911 -A = -20c3fb73a03217893fd4a9db6e53a3d83a8414d900213d0460dc91bf69 - -Square = fcee79e598f061157ca9416491f2eb069bb95a4d78a1d0538dab5c8008653db71b90ce3139e693ba284846be7b75d6b7aa80228420fe75599c12f090 -A = fe760dd61798c8f78e52b328fa27cfbe41b898de6e6bb4f4a684f038b5f4 - -Square = 4f0db9f9e6eff9fe7fc938f6d6f5e4fb017ffea0cea0f7c57f4fc1e5b2bdc00a1cb9c1e6c865e53309b6b73c4339b0bd485860ca9edde3019804902da6b61 -A = 23909968dd5d139994fe9baa0a7bbfa009b013df3859ff294c5872366eb7ecf - -Square = 4441ff36d785d18208481470a5b8ba8cd65a45436c39190dde0b8a2b7d00bf67b185d98ab5c4a7853423778d6333abf6b115dc9567a9f9c71916d3f9db3af82c41 -A = 84307277f79cfdf33d83d7093f1fd8aeb94499a7075ca32733b68fcf88e819421 - -Square = 50ee0dba369b0fb61d75706652487ca08043eee712ebb51399122353f77f13745ce2ef0d8f0ea7b3fd94e928b0b2b42c2c9141b5697b13b6d1f3d66c6a9186625b87e40 -A = -23fc02d45c820c3a4250124cc457fa3886beabb41d3c1e26f711309604eb253c6da8 - -Square = da11876b316d4891a2d650692ca776f77afd32a1db08f591c9579fd1053a4a46cf78b4e4cf417eb99eb067ff701dbe3483dff22e7878d2ef2b234244cf7a29d93f62d6d6b611 -A = -ec463653389de3689fe1881679b83ca65134a1498a3543168dd4833a51b23edd3fb617 - -Square = b342b4aff7e5bad38f7f532f0f32a3672f7ea6521d23652fa09ef7aeffcffe52f056ab1b54a0f3a2147f43330fd199d1f290988c866f61360dc4928c84b3dcde8f395120008472100 -A = 358e27805e2a56195fab2ccbe3f931a4bd14023ee56c8a191697926f387c40decc578cef0 - -Square = bf4045fd680caa514e9c410fb4404e5e3a381abee023d5b509d6dc0b97386421f55090af8bab5ac08e9b2eb8a36a64c55960be9179d564c5429f4ec595d03d12111defafb7359b418902b1 -A = -dd450a0fa0914f0d65a1b555baaaf9380eaf8d58b272bf9d95435bad53b01337ac8de562cc7 - -Square = 86abcdf183ca059257c2f6bb91efc9853f4ab42801d3cde88df72d4c904be184e93d6bd1af6fc21a6836c93c4e0a1f728b3722d568572f7ade418274ef2e6ac3463c5cc50990f1017e01cfb91a9 -A = -2e6b4d9eeede7a72b8d0fcf6429c7e30cf291352e1bb43e92c14236716aadc02c02f75c7e6aa8d - -Square = d5f37112733b097cab2bb11daa3d9481255060abd7bce42b752a7641a98e140922c375fcb68bf13d4326b374eabe3b01de0f8f6324b7b3e4142051c02d2f18ae2e748cf3c4bcc3fe157bc94227631d21 -A = ea087236372fbb01b80e57b1ae4edeeaa776355457e18165a5dc60ef4b6ddc0b127ef494dc44ae11 - -Square = 9e4db7885fa5f928ef236f99df3e7c8d17a5a21983ff882032817edd5658575f443eb9c5c97d95ee798a3809cda76d7a0ab9fde757a310e2f5cbb299ab88e92a5771027ab9f26816c02d0c97894da5976ec90 -A = 3253d712d4ada4c12dab41036fcf79b02e80d1a632ff6ccc44d3c1d08467a019cd6221507459b231c8c - -Square = cf9c50ee8773ba94c9e943989a35513fc370adc3622beb125252bb92ff9b258b81a497700e3bb15bcb23a5b3082c095f7a5d6eef20433d689c20a5427b661d43fb0f9b7d1b16d1b73b8fd59ed319a26c5eb92fce90 -A = e68a0812d2de2a922f24c4e63b4c33e62f93943b7673e900d12405dedd0bc2a906daf8b4bc336bdeb52b4 - -Square = f3aa49c906844692d3bc0cf101adcba80351c2e744be01762a8c24804a9d8d5a4cc3c113ccf529eb79cb3304aefa74178afa53f235c5211192d4cd8610c3b42e246621acb3e5d1f9d86ff39a20a7fa9c568356de5b86919 -A = -3e7069ce11472563b0dbeb9a936884df66db83273a690c40e5d3b5f8926fb502d3988591abfaea7b7bd76a85 - -Square = 7c9a5057ca8095cdfa289b2d60eec80548f9ab2f3a996137ff9be403b529c4672e003d1eb074c76c0086e3d875cfbc90a40ccb61b799cc0401ba160d8d6b6ee46b2f14ed31c83de54cdf83458dcfc01e3234d9717b5f2c7e5079 -A = -b299da84ef84095d8191fd1cfe847b960729a3d1857082f05b2fa30ac45e90d2fdc778013b023f38db2c8e780b - -Square = 488294b528e2c2da0145217ec69de2d021ca27f145f7321f06c03316fcc14bd4a9a900bd6a144086acad6d5ad32a6245f5a655e007742aa336430c6bfbe174278884d19fd93916ef57215069268ade899cb92dfed29628327b84d8240 -A = 220fa6eaae0238e78a91e43fd8c2fbd5db0c8501cb96d66265c8edcbd376814c39e4a6f21ec9a6472c6abe8c04818 - -Square = ebd685edd991dd5180706b72ce20ec4f6c5d9ce038cc8768f2ae2d0e676bd549d6d3f97f6c26f6e36bb664e8a7e6102192bccb354c024670085711db30159c6b7badab7c7c0b91925675ece3e23126ea6feaa28e977598a890e4e476ead100 -A = -f5b657cc38fd11ad2f1b188c61721b5ec6c9762c09dcbfac3edc1f07e675bc058e77eacd01a2b4139b1b00c40a6cb70 - -Square = d1b3ac1d7042c0200f80a989e053dee31cdddc835889a57482a0988afd82b0fe8d3667270a72967401c3e8d80dae349ccd4063f11cb24dd7f9a5aeaaa7c0bd7bf7991367b0d7b4d374dc9c5017da81ba39fadfc3b760f68da95ae1eaa2eea3fb040 -A = -39eca1bf5e4807fd6a9ccc9e3138a6fb390b10a330f0027f0ba9868beb77c93160b623de58054a4522183fb3e4e2d86b08 - -Square = 41c5e4bc851d48673e0a16336f0decbcb59dad36959b310cd1a042d24de00c587db47058c2d91d7f9982bdbf470c73f86e591a122b3fda71796e465513e10e3cdbd5e6bf035595644d588c091e23a57cc47b5173743b0dca965902918d61875f88735a59 -A = 81c2caee75e98f1822c854448302243feec55a5247bba948647f12d7e0bcde4b1dd6af63eb1ef948eec22a87d2f3213de75b - -Square = e712c3705ef2779ec997c430f1f8b7689d7edbf2daa733dca89612bcb298180b882cdfe8e5cc1104b9f5d6d8f0978b46eef4f297dcc83fce4c39821ed3205e399328d69ad484d8b3189e207193203ef79b763f5e11778dc24839b4feaab291a0464cc66edbe10 -A = 3ccdebe5106ff5642b4ac0751bb799c27454f904fb72863d1055d1412b2359120ad196b768f6137dce4cb85cd29a990838a95c4 - -Square = b5063c05ac122d0d4b1e0d15c913f70f1309933ba737fccbc02d13a6c712e7b75fa757ac0e4fbe65977f17bbefde31c8fcf51f867a698233bf25bbdb1f03c104dcdbf1173886a48eb5a8b4d27cd841196de0b53466a3f1d28500fb4dbcee8d3458662443eb2aaa5de9 -A = d745c04ed95d4090ed66784339202f9d0e57bdc1a6f6b6ca09337153f0236cdf99b61db85604791b3a373885210f6aade8530c8d3 - -Square = 974463573c968f1734741dde2a800761fa749b553dd6499b920d3af9bab73a87f40c9cad39c51cfabcfa0895f1970281af063d80f89f4103624a75bcb0d23f5ef6c1cd9a10930118e1459ee8732728ceb7961f7d83cd2344a51e6229fe708bda46382e142706137facf7161 -A = -31323f98f0f73fb66e541471774ce0e0fff53d69b2b726480b9ec7b0775b345ec4ec57c4334ab8ff4b388f4c7fbdfa3beeba0f3e0bcf - -Square = 673a62011d769ff0333f69f10f00b28781fece47ddeed25fb0bf4f8d95dde4efff60690076aa520ebaa3ba63e6d445541b9586241141ecc37cd75b178389265224533055ec82a393e5dd61640d3f442adaab917c8fee1f8fc0ff8ca8d577e1d2d976c2a8b873f699aa92c272c164 -A = -a28fdafefdd393f993a8fc1ae321e420451dd0c5071410367d5a911b2a3a668bcae4452e134159e0b1974505f99865cd97cdb020bab0b6 - -Square = c4f34585a29667b582a3ee69b1a5f6c04746d105a57bc92763958c5add45c64b5c1cfeb1a321fc5194aab818c92ede5408afae0a2a74ed4c7757dae0bcc602169a805d525c5a63ca97391a9a7987a3eaf04bc44c89547c5d312f7193fc571851b1a8f8f091849f649ae91e15a050f5799 -A = 3822b607fccfbf0c5be97d4358bc682784e6453c71781fd3eef9d247485211c55d742279a35bf35e64ba8ec8cfe20dc0889688e2bc81fe0c5 - -Square = cfdf0eb68dc27d60840b8afa8daf96bf831002dadb2801c5d6f7ca558256bf3c7c5372fa00f2b3e300287745f8664dcf8e679fa35adfcac93839cec53b349553f31058a4db05af40b047bb367234dd78717aaeb80334f0deabb09d2d4d90394ec28cc3589b0aa78cf227ce8678b8bb5cd775e9 -A = -e6af13779d5a5eedfecb7c4d34009affee1f0bb65934ea9656ed6eae02271ac8a29104439000650a3a8cd7fecb171a7154c0e2bb2b1cb908cd3 - -Square = 6ec1b1333481c37be059ed7e088c862f869bb559b34360781f7263eeb206a210b90321aca198aa41c2a79e3a8d7df4336c75c87ba2ed4b02052a07b234afd9d2cb55413d4296645cd0dc8f987120acbc82fbfb089190f50e55eb1f509c86734dc14b2e8ae42ce880023dc7a014b02727b53d0e5f779 -A = -2a18acca3306bf06fd90da4ec2cbce995fb08beaec6d1cf4b30694d682c83e04b39f9a569eec52782b9eda7db0680165c77a1b0f54a1b995f8bd75 - -Square = 5382be4ee86b9d80dc2d4ec58606ac538ba7074d57e2011346f0dfb9a9d6677fe015e4015ed607906e9068a3c5601f0bb77186a9d147416ac68e344318cbae5c70c437c5e1dfc2d6c3c8725198937ac2d8e796f749bfe95c7fe6d0e460a633be2d86462d48290a2f8b344ebcda2f6ad353d6fd5f3355d819 -A = 9236f7ad22da9cdd8c187082c630098bf3a558b04856e876433c570a63d39863416c9890dd089f7665d6ba073b2ce90f88e7d04af96f1c82287903fb - -Square = d68e15e8a46e001e47022daf63d2b33fee0f9d3dfefe9d204b0de6daea31dca4b287a60827bda9de2860c433b77186aca10bf3ac1d02a204ddf8bf070c3c20ea69d9638a865c8843e8e63211951e10a844f8527345c5bb5417e3301a19c929e6fc48902f0e0be8e393ecb3fe0e9de6188a72d102fbae846d05dc1 -A = 3a973dd50d4239f05d86ba25ee6ca8f8ef46424951a8bb89e7d1d6e066d6fcbabb3758ad9e1647a440e51976c0ce628d78b59a4d9e42fab0c723182b31f - -Square = f03a448bc7405d2d54c0ea1a9016d8757d4af893024e542df80fcce448491d07a4b451d67c9e7d9a6c7c5a6155bf156d3cdf8103162d8e0265111655fc0ae46f4be944fdf275221b217274357977abf64316615dafb6ec84c5466f617c4e8d9ad4739f3e5050e583892db75366a4a7d2c4558436ed036a79084c7f9100 -A = f7fd0a9634d14d540daea21c7b804d37de49b7c13bde85c045859ddae1dd3142994e385f455becb7ee30576d55d4dc2f3d9d82e86032e170da1730b2c8a90 - -Square = af945dc2241029744548517dfd7858d42097076b06427419e74ab08071a23aaaa1f5daa6290287ce8e832a0524ba5581d64abf054408ecf6ed21a4f8289c1e4c7a8087384d268a1ccf7ed40e74922a619b5c1f2c08d810065710046190b7cfff33d4f67e58927477500eec54ba4f63a57532ed10c6b861fca9d46bfc3d32640 -A = -3500a8b6d244f1a21e10de7cfbeeb75d57ffa62e9dfbbdba8fe93d17488c56dc89787f13e660d0d7c7755242f8412d00988bfc7d3f6704782324c48691e7ca28 - -Square = a466e34dc7875aaf945c088bac23f3347a41f7cd039b0c9120c2517ada94b96bdd72d7c9bb55539af12931a3a39f6e09a4cd4311fba57dbfcc51bd17b03905e2560275c8bb3d786defeb131a634e86ecb793867355b048dbaf2db8b654a4d50aace6bc9d60de6934ce25ab58381f6ddbd1c063652e283c30a2dcd61d9d776d60e209 -A = -cd26a0c3d84e83d9f14dbe95cc39e3ed2e8861b76f4bf55ab120ea636d8f9efb0b6198986eb52075108d0a5c6ae0ee762f834f3db802c3f20bedf938f47b8bfb03 - -Square = 9f3f4d5110ea1bad21fae923825ba869a9982b753284f1946edea19f22cf0a49485b9336a2af7df8bf2641cb2083f4dce82202162d85a5779a4394213bf3bb3e47356bfc1150e66ddb6cd945092c9af14eeefd2d08b76c5e4a585ed8ef39202c42dbbceb25697f22f9508e7d954d3c1da103818aa6f63121f895e2c26d3d7463aea7ca749 -A = 327a2f6607c41ce920c14e9c9e8a059a931d71aeebc3e05e93107265a2810ec286819a4b2af9d2b70b754bdab6022b10ee6b81b32a7382cee99fb2bbcf6fe85af05e3 - -Square = 50ac4c46f2014a7a382b0d5ec9db4a67f34ffe9fd5410995810d3ea8d7d87d47442d0253c7eceb1799272bb5f5e7bd63174959f9844e5b4b65b6a4920166d83d01a5c2638b4d3b6db7fed99e28b9128dcb7c10be539114c5887842f8e5a7fb743298ec9642e50bd0979156cc6aea9ce802a0c1b14a2a1b7afe28dba534c9933209f14474b6e484 -A = -8fb585e01a0c62367dfa8a1953e553476b1564e843bdc2c5d964864ab2da56e0bfa7f5ce5b7850398451619a061de02ffbe0c336ecbeae818d32dcd40355fd11a7a3822 - -Square = 9214e31bb62f62a7f92d6c7f1453bc4430595a1765b7223a1e50ec30f934908c19fe82d7bb8ef1174bb6787aba9df1a38a84203630ae9f62e08fb4ac55ed329282315937d193992e9e12adec9727ef91df5a065cc5858062c765f34bd2630fd3f654a8f8421b75dc384477744efef3d6f0d15820c9328bf43a43409f6527dce48a92c3e1ef145b5e284 -A = -30587ef092cb9456caa844be9629d77ef1bfe21d2ffd5625ea353beb1f294e38a7fdddd5bf77cffe5caffaf609b8976756c9eb4908ca77b1630ac0d706503c46177c5d905e - -Square = 54bf52644a244276ad3dac90661a1e21468f23a117a1fcc904c66119d86ce98a0b90fd4096708bcefa7a9df87c6bb85149305f193cf5505802172ef9ec343f662a4c895a9d19edeeed5d91e20abc894948fe59c1869928616392f3694d82aabee325b651e1170006ca1fc355212308442a5ec8a8fda4f5f90b7fef2aa731f3fe0f028143ead04490d78b2151 -A = 934b16f56700b455d5791ee8c119b5921976a829bb5d1fedb201e63c9ebb82afe4e29aaf0ae27148e4d34269c48dfa42131cc8b3b78e23ac3e7292eb0d715247a345c800f377 - -Square = 63b7884fbb6d5521c38f7deea5cc131ec6bea15a362322a8e27c762880836cffb69a069a168663908707bee9d83aad41c045bc84dadc6cd927ad62140f8c2fd001d34f0a7462bc939cc8996e17ebabafda95a73483c70191311a6fb7c670c76c9e2ed7e589e464617888d30cb7793e91672d7de9b3b4b1811b2c009dd1c690d44710bbab832d91f16f9b3564a0c49 -A = 27f17f0865513350381ea1aa1545439fde427ccc64385979bc787cfc4c7e6b624b2c77140da2c4176c55dbe43c506fac14b4cd7815e87f3120330dd3003bee087a371f85d6f4e9d - -Square = 9d1c4239accb286c3c7868ad3b4dd97b93774fd0c65e04ca8dd405c0298ec6d1f52d60be6ddb5f8f0389cde756b49b23dd2f0de568a432fb99dbbd40db798261d1dd39bf5017e6dc74cb9ca91f8b2f892c7eaa28485c04a96add206c7c38943912de065be17b65292db5a144f82427016b5e0eb4ded2e4d0b7d12b01cb0b2b61e5e1bf22dcf1567a8b149cc0ef5299a8b1 -A = c88cc5a46bc1cffedad4f45e66fb55dc4347eb2a24a09878358d40fbdb03e738ca1d54a1d26a777915248fd730daffb0d3b5305684709db0f258f581fde06b11a33a3f76b3fa53e39 - -Square = 789545f15fded8fbf0b4275cec30c3ac65eb42ab8cc75670fbb2ab0b4cd90ed41a1290383b5f14bf87a88c67ff1e04d0f478fb11fefa64e86eae5777855ddeae451e166e23ec30227fb4021d51ec7cfe4ce531c78ba1bf6c797dc73f093b0a5a5aa59ad8de3234808e776d690007c8c332b3f03331dbdbb8645b91552091afc36c28c3229220b1a7966c7cf13db6bdbd4673440 -A = -2bec94112014c1a506417e659157192dca1df58f933510d7a8d6f6feda5031d799a66d2746c09f827199ad9fcbf11f323a636feff5806c9fecb2ac684c2870d60c8a72358562c4eaddb8 - -Square = caa64c9f6bd66f76c99604d1f2b8a29a9a10c0d6a41cf32b5bc40edd7a1d97b295c63aa62c30498f15d70e427d5612ec3f6a2c1f2997fa9283f48018435fa6092269dc2e4ad524cc6da9689302f5c398d79e2b2d19470ea8240db9df0bc0bdc911c4d53f4f24a7ce44ec76378794d16d367434b4f8b6184c7651db77fcbebb8fcc5d3a51ee9739922cf20d4a8888139fe4669a164400 -A = -e3c4a10a64b7e67d786aeb81bb7ea14655637ce963f46cce59bc0cb6b5a9cb9c92afec3d527119db97bd2605d315cf28198992b4b2206e5616d3c560bc8163f56cb1f5626a7ac6d8427520 - -Square = 429e4283af7f895fe732ee88e4904348ed01bf579a93cffb7aa8e135d41cb9be218f8b9a9cb4f556124105cf042de51f34c8162fdc7a981de88e005a014149c955068e87214c174daa40fbc618c536a6e507ebd313763fba197059d68c69bd39933d614b2c32f235cc955e335c4a37b9e98cd7f98c7f26ea2da932c7f82ffd95be22a7741da423123f8908cb188abc26afaf4ba6d47b56e11 -A = 20a5e2a911627544219a1639c3321bbcd6192a32129b248cf62351f85b7a719cb275a4e44368a74f4d1a307ffd27ea2cae4d8584a57070609a30fb4e365564908f3d501b53c1a54f0e37745e9 - -Square = 9bcc8d423c3fdfaaaabe24a910e6ac3619eaa15e23b9f317c844d39d164c952fdf5c4bd270a83f3902e54d3817fd78c96018a706c1f652025dde0b98afe35597e0d8782deaeed23337ef6b3edc9317d54e3c8a57e4e7e2695f9d2681bf82927bab193ca1f135bd0e542696772f08520faab61fb4ea6ff0d15bb91f21e68bd7f084a6b8f24a47ecc30a779ee86610387b29a1de94de517f81318001 -A = -c7b60f4c355f2ca3937ba3c124eea2cd8d3536226a44afcaa3d17abe931c09ccaabf25a1986b172fcf46fb02a0fc36f2c163b6e42cee047c54ab05e9d30f03f6943b9fbab83aa6da12d7898c001 - -Square = 45df25540de94883dbc182009c29fec43627d3e5758e6a07cf40064e0befa0df184528a84757b445dd079c2b0feded48b651ab18b4bede2a81796be45caad0125c3692560d19cd9a6c8c0de8383fea0bc1ab46f6aca4e9c36b26575cff88fdf1eb1e13182308295457374968fe3a9ca34c6acd24c753fb84d41246614789dfe154faf34fc684cd15035dc9c1c6b0ea171e089e0f3236840e355bd123ac4 -A = -216f8a9a3e54d4afadf368c2693743efd3eaa4cbda7a87cd07f5b1a713eefd2548343e7f091ee4d9d6ed1d4343c06a0597db0eb5194b91bf2c858210557a8288c1aa7b0e0607a24dcff9de04146d8e - -Square = 5cc707d97eb107c5c40c0f19fd432cbac9855f280082802dbe4deb45bfd193ac7a9149fd12c4ae6e9282411e2f1f2ca92135424f215b800634092ed4ff2859d16ab9fb8619ece41b50f8888d3e13773d38789e19158e18396096dd57fa5470f50b391c22378d980e59b4585f013e6db52c1e24c14ad83262fd37d42f52323896f7d4cb3e38868abea8a07e7ad3f90512eea001c5147645bf00396cb0e7a553f1 -A = 9a1d1b0beea76e7f32bde9f4f2c8bcff9094db2d32c04fb7ff43624b61033646e482aa0fadb9f8b4225b47121070b4ee5d6818d3606ed775aa631e0ed42da68c2a09dab26b6a4d09ac226cc09321fed9 - -Square = a32fd053eb90c365e77ff47573a24add3b25b4c301f4c662dfc1fa635af8e18e7947381989b37a9c9de2713ca438b9f85890b7b160fe251933aa7dad1c3839d502debb42ddc927fa0e9b40c80dc3d408889be567699a856b1c9cf3a393b3b818432e95feea825c17d0981b942236b3779f2acaaccaf9a5817ca47bd03045fc4de454d8f1d4377e218c5f7ece369aacc35369ab57a71652dd42621491834119afbe729 -A = 33190b787a2c3327b122d1f5823bdee5c93b19b586ce1bf79d801a19b2558aafc8f6274d0908bb7a8362f7f71d3fb52b8ffc87d458249caba7af3a516ce868e8a620e3126ad43d6aeffee11866fe77677b3 - -Square = 74215d33fa398e21c34034af6f9c7af6a3e01982320ec8cf23074a938f1a31543f80e6aece01de247668fe67f276cb4411db27666e1dc8fb2bfa4eb68cfd3563167d1ac4efa3361f920d8dd0fbb7f06362167f5ab5ecfb72956c20db934f67ff1c75aabb594c853fa61f43d219a3f5d0d45274005e3b167cfff5493b0f26d15f85d8e906a0a6e7645eac1f40c6dc637e6d1e061e5b9071a1227469cfb2c0f17ff983684100 -A = ac6c0b9c69785f35dbe244dc85a54313ef836ac67c853531ef5db45b28835ffe61dd258c5528b0acea50f5aa5c0f5d08dcb8d82ee19bc432fa8a45badadb50693fedc1cc79a17d63aa73fe9597f1d4ce8ddf0 - -Square = dce5cac967c47b8a58ed6f1bb1d1e6185e849400228afa2bfa05b9c2dd327b04a86f2a4da2d02ea102868ea0c4da0f3e5a40bd02c87a08aaa5cd8d9358b3a5ebd8c9fc2dbb1268c261f46d6717b0307b993deff0adc8190d32b4f2bf695eb2cc74a6a9a712c5a621c673219ff8a24ded0997508f8f9eb1ea872008c46e71fa97f55b839950e63130c38b49c0ce3ce724a0e8faa9738d2e28ce6e7fc7eab62b3561d2981f314f751 -A = -3b735400064b15fad81b08362b8557f8318c20656839ffb4d2513512015036ab0039442032f1cf515f8c10c9933afe4206a2f309e933d1561b06bc665af2f04f4d064e073eed2280053f56cbeb137a9482c0a077 - -Square = 6b619bcaf632f0d8b1d715e8850c0cbbd29ac6373a9a5e93dd1bbd2b82744a8a50a7446b48c6e215911ffafcda9ed7becaf5d26b7d6df7dc8798d53239f62a482f974bdb654750def1c941c49a24fcdfcfe73881b556a7b528d88daeeaea8d62b357211a1946c81cbf0819ad8d0188f60aaaab4ea2dfef7e9012ade7abeaaa4a23d7403c1248c36aa26b43b8e7de8a5aea639a0449f50359e9b4c1b125a548383af33703f8dfbc2528e4 -A = -a5ccc69663a8712c15f96e6fc746252af89a8c2a6317caef905dd2d8a6d4fe878ac7aa66cdb3c3721ba7dd36da310753dde9801b31d759339ac919a464ab52541bb2e0dc938752bf0f1ff7a9524eb98340d62576aa - -Square = 77ea5b715823045afe13d10416dfd46a511141a7d1279ebd624f1de428cc04a4f246246e65c3f84344cebfa32864de9264b2e54d4b3010c4de9d3e6a27aae8f5f9e9d8e49fe26b73ac7e65bb216aa6a42db36ac03d749b5dc04192df819631593202a58264714628686507fc5655f169483b0ffecf45995cbc12faa105895564d287a9f4b220947d6c93786c85b2ee84a0a29183483f7c241d6a67fd0b1c38c7f74421355a14c6d9ed5720e24 -A = 2bcd67e6bde3f54c4ce0ea428418fc5c97272217c6c7de90549238ee322810dcc1bb9385967673aa3f9f5a5c05d987c6445135cf1efc26b3c17e55b93cc052761a77c9dcb5c22927b09e90a92e053ec1bc799bbe7597a - -Square = 40d113460ca3e70545bf3613c2ba5de5d8485641ebf531a43b6b8bb76884ff4f348727ac6606e026981d2116ef1e60d4b37b44ed7e2003410d7d636b58aed2f92e962003f28342aa5f059d23b3d58a1ddfb47833ffe1d1deee0a7e78b8f7d9d6487f22376664f1ed9ddb5ee3d17f43afda296bead11680fd17576a122c2599fa9802ddd84a2115f9fda03aba898f66e303895f452077c920a322b6aaa0965f51fbb36f01b1d412c6ccf390da050d24 -A = -80d0699a46619db033461aa6060983def7deeb976d1a71f5c6ddb85e8b46dc70b7ddb1d254971d38ca87c7ee3905e63506c6db105dd683375f4239523cbf1874069266c2c0f4b37edcdd261c51088081d25813758bdbfc6 - -Square = ace99f98cba0d1dc1c758dc7211aa4078a2aeb6d3fff19bdfa6981ded0982b15bac792e6b542ae48a86f9b40c6de937e402e230fcfc390b10c3e60202dee1337ab39da7a342999487b8d8b0e494f2809cd1bfdb39209da5daa590f78ded211b6bbd3fca9013300b951d8906c9ce8d1c0dd9554d5d1d352f9784f822c928dd9700ef8a5fecf3771966abb1dc6a70b301461eb6b6087d6ab80a4b624205489584224cf6578f75acd8091fd621d02306504389 -A = -349936d60c9d77a0974dc8985930d8674976db6b3cbaa067554ca6b30b1de33f2d4e1c9564ce102ac6387755aabf42916f63632a375d995913f9d45ebda54bee3fdb7cedee46ebb5c8ae7764e4de323c17c797d3b529230cbd - -Square = db6c73be2a59bdd35dd312240aef18dde4231c72aa28551bb370a87dded587accec2279bea24c930236f06f24d537fcf242497aafcbf72f085fd3ecf030cd750fb382efea0f82ad9d3195680324d73fa99d48802d085c150164aec0d29fdcc3262264bbe72311f89989cc71a4afdac6ab103ab4fbb6e973a42a1f8711bee463d198f727dc7bad848ff8fa77cd3b2f612d142ba46e95bd79a86a1fe4c2b8f9181be84825d05989695842113828a83b826e7d2c8c1 -A = ed01dd49d2e5d51fd30e9c578259cf107771b4ded6bf21f8b9b632fd360e34da740e0b1af6b5a67789fda5a44025af0f1547271ca8accc7a975d98ea7ec3d41c9697018d84ffb5d49b88d884ccdb011f715a199ddc44a4109261 - -Square = d6e38250ab89ffe11abaf8c5d07ba11e9053f1924ee1228f834111af16ed282389d04330cb0f47dbb186dee577aed82878ecb065b759312eaf167c4698eab5ed03a8657341bf5fb14a8e28e3b443a6b657c1f4379ff2549498a33922ea84f1fb19d10866fb0ad07ce1cc44c93cd4d9ec6bbb0e61c797750c6b5d7e8d55499655dde112f4747798f0e985fc2b937a44da9b04c2dc4b0816cfc57da1f80179db653c1ce287e786ed7eff7ad6d1383fc6de8c941d4af7bd1 -A = 3aa2e696ee570160b2a869c3f21c3f223959a185cda2274feea1c829af2234c70a504c959bcc49fe0313f4f5ffd27448e28aa0fc6ce24f36943d334c626459d7e6017339e787ab074879ebf697a93ad93835d69ab09294d007a0837 - -Square = fc39360cc0fe040b6f8340e0728c650e5e74cf1664f7b301e79986fe066f36e8df34d38d1a06b74a1bdc76867baeb3f39a9161acd200bc7532fa4aa0ea829377659646f073db82ee044279ae5fd797edd37d3261970819589853cb320887a085c4011c23d0da9b6d6f1b5911bb3399146c2912a967ab3b3f611f0bd52e00f418e6a6f0297fcf5c4a1f71c6bb8cc8e1c76694bb7301502d1d00c8b6c05bfabbf5d350590561abf3e2b1a82e98b56583e2e4e25cf707320a0e40 -A = fe1acf3d7b54e718c901c53f365894c22c8bb4182fee8a4c2558731e01e1519bfd1bf6e353483b8c4219453fa66f06063c6c99050068c15cd13cd1648ffc42b5badfc70f6fd4a0a5552fe637e54c4f92ca45c60cf9a0163978ac08d58 - -Square = 9abf1324ef65c726330f64643a024c466fad37604f4dd3dfc404d31c2a430fcfaa0c78283666c15a094d494b96d3c12de6e29a34d2c99f4f8cae8217bcd2a989d59807ac68c46d60600238a86155de499eeb35642d0f581045481b40e4f0a76905f9b6bc5b9585f77f8410b99333f7ea983c3f29f3fe66ca7b793b784a5a6a4f74512aa4385dd1e996832b1f41bb3af965be58c4ac5e867cdf8dc6a4f9d20a6f1e16e153fcbb45ae5fe8a798cb06a4ffe467d6b6aca2b31f335a344 -A = -31c243593ea611dffecc65d1439db345b2e89941113f9792c91a76b4890db6e4dbaf1482ee812e295d27956e48d07a14de38357f15b5931c5cc08d1d248df7bfee1cae5b5ce98984c5043a3e1a2b449ba1671bf1cfef91011e12bab94b6e - -Square = 66aee3e4f43c672e0478c76e2092bef33e7c60afee5d4c7defbcc5c0c86d8fe956c90a740cebe604224cc3f518463b1208699b8ea2316315474991d0f120ae905a67028492cf46fff2ae244869db2a02d06aac6ac6eb054fb3c14c756d8a3e7ca64f06586e3e86e4477f185ed527a8aea6a3c741f3fd4b64a2ee77ff140190260c431cc53f411fb227377c02f85d0258a75bf6d44dccbb8bd04ebdafa115dd55b176b6eff5567e5b1bedcae15110826574053681fe25a695ac4540186e90 -A = -a221dfee30286adc076673cbcebd24a41a438a0a7a6a547c75d33149cb1a094a8425feaa5a23cc234a722db4cca8d5912fe1dfb6db4e92bd87c12f0d06b6d954fdb9b172955412b2eb5c9fa3b4df2933390384fd1f929a2b1a8dac479ec94c - -Square = e880f8655b51739e34393c3e6d69d63e0256b1a887f7e69f40c78d21133b17e92277a136f5e37da2533ed599efad189975d22ad0340005ef58db0b471651d749dfbd48b3f7b3b8a42d4677048a855e99dae6c729d8bd7eef86911feca9f5490dd216b06d9e8d1ab695c1081e72449baad28dfe113744853382901e6bdab5413c67c52d6cbbb2e0bea711edbb3a219a4046e8739c04729cf8c8210028dbc4087737bc6c1d7e0c15ecf16774690168342b1372d3646d4d8696384bc932144c98529 -A = 3cfe075d4525a3c780d6d05f7bb708b2fdf7277a0f9967e0a209fee9d42136a0bbf98660d8ee8cb4720a8042da09f6271c45ad13db24eaac465f8207f78629e9085c1c890675f441c78efa38e5022b1b80afde5e3fd08e55648f2817631eb6cb3 - -Square = 8d6cf4eaf58099b1323fc598b7554b371f4afef5ab501dd162ab8429333d46916fe15dfc4ed6a99ca7fa7fc1aaa0cec3533b41e291fb7f69b560259507226eca87aabd07b1ae2eb93bb53f98fec508f051cc04db4a172901e06b74229c4fa3f550a81626c7a63fa99d41e46c2cf792287a5cf7bb68946971bd43c7c0356312cdc25e524665dd39a24b6464bbbe64fe8e87ee313b860639728a9143c3a6118bc8b150dde6c10a13bea637fa8873c393e6338319c506aec6ee973b4b52a272a74bb62084 -A = -be46a8072aa44b3bff0f90c81474dd576756fca624c15f55a17e1d0bd2842467ae000b04f79f561690c93ca7118ce17ecf830a8da3678c15436876d2a74324d9714dc8ad8181904be657d7f1da3313b78448cc06e32299a09ed59bfc1961e8bd722 - -Square = fbaa4fcf9800673fbd3a132305ed3e14f4889518fb56ab82aa5e9b3529b74d7f9a467626d68f4709a2030264aaebcf05c0a0edb511e81f357d85b79d925a24605f1bcd4645915bb75d363654b676266329df532cdb39152fb360df1b9500e0c296014289650ff77faa78a604397a82b34d16484e94a8de123fe720e514c88f11ec276725111563db91477480c3245542ec6bd0bb2f4aaec02c6c4eb1769030a31b05da3798c224c9117f7c38d3e98a343fca03ab584ec2d7e6db60fdc4273c3d8e23cc1ce09 -A = -3f74b25f2a9c4d8d977e69a4e067f9fcec281136a508e365b282e5fc3b1d097bc6a0f59f7827fb90d4890b08840a0a1919032c67448f8f1a771f785a0f125a4aa4137c154fdb489dc1099d57bfcfc75f4ca5e69f93f2bb87ed09cc0dc620d3e76ecd03 - -Square = 5135becca97d93dd4b16a5a1105ba3a3e3fe02bd6a7c3cd182186fc63ed4351641182a2727ab6715e9672458dfbc31aded4781fa345054eb4c317872e2af6d4ed64b2ca7e8c25e1e664b5349df937118632a64e4ce439ffc625a5ad3358270dc83fdfa73c7afba03406094fa36d87517e5e2e1fee5526fd2dc00d9210a0f6c3745b3d4bceee5f8b03d976d696c57a09d1e08e4ce780972eca4f2ed6500c23bf5782c31f13059e48246180fd09db693d2fb5d48d51846ece8beee45cef7efc87c003b44d7b137a900 -A = 902fbe2127354a7df5cb7fd057f3d080a7bebbdb83c86a50560b8c287a37a841bb9c8421c63d359078d2948b6b57559f98fad8f8014f93c912cb70a6701c4dc4fc5e88aa413fcfb685c32975a8b72424742eeff8262d28cebad00c5fcf88baeafe8f6730 - -Square = b5976cf6a6560412aefa6704b126e0d987dfcedbb4da436c08ce17b1bf1b6e0bab9f934abb5c4186a5415fa38724fb8fa341d381319e7d768209ab108c8debd99075d31deb3e03ff7d23957d4f3204d543b7d9079cf337be3037b1cb4908fd8c104d92e52f041b4cb27c045a741f4d64009980e8d27af75d9493920ed98c7234777592d6577f2d1b3a0eec645ab4cee2f28d9e4efd3e4514db6796487ba68a462fa0e316e1420d6604db2b901de46553546cab42976fd0d459afd81196275cd88ec4dd448ff331bb35499 -A = 35e700e034950bdd7318d5b3c17e90a4772ecdacdb055b9391b31538eb823fc8a4599f029e78e4fe5299ba1a423a449dc257a431d189dd5dca275c02cc1f12417e111c73b731631d8a1741b907dd8f24de226ddf9e3044cf4064e8e51ebd55be774be7ad2bb - -Square = b7de0f73397893a97928e266bc56299cc8d43b16a251992662646072b58fa578ca80f7be1e12619012b130e9514be803dc166b12ddfd26f558d36c2053ee6209b01458379e49469753300ef20f6b3dcd5383b121861c76ab25debb28c448ec33a81250d05f7eff80a5a4133d522d270fab29f739b607395a77278609aa5e1a55ef58d1d48492b71ee30a24a6505aab1a3ac22b9d143c9d6781fae14bbb980fe3a99dfa9a1a406611d7d0304493342f53faf5fd79f9c96b9583a219a1b22aad02dd58f32ee98146b3a8cf054bf9 -A = d8f4d3bcfc7eebd7068b851858c3668ce062a834927e165679b49132d4f780ca682876c65c7cf2e7ce34ed10e43696477da6301d13f92abb8c76e2424c4bc28a6565f15e59563d607b852dc946652b68fbfda1c3200ecc2976400ce7296b96e75fb059a4c8eb5 - -Square = 5ec02661f49fb9807bb73debc3c6eccdac1df1735e0d61fa7e0eee07471068a5809796a2af490c46a77d61f618b44a3168dde67aae1cf9e530382411056958d55bd18f0e76fe2c31c98b00f87fcb7f5691ed5b65424f82204156dc361ef6dec5d44cf690582599b3994ee47ef42850d5d2370a4169c5f73942657f85422ca24f66943877f73af493c865fbeb29574cc1cc730e9bbb097b598574f6b90257748e950bff867bcc01bf62f8df67d7aee1b6dc1d5db88826e86a3f9fcd8663e09cf8393ee71a09c43d0d38ba6ef643f4ab1 -A = -26ef9b6708a80d00f4d01e0f0a5546ed217085ff23519819ee89af430580ea1f086beb0eb51982682c6d3b922a2c92752dce63657836223a9d94964bd584bc8e37c6e30fdcaffbdb128344d51a92705e1c9f94205ca36452c15a08f7e62e0e02479ecd48085de8c7 - -Square = f6364409467a829abc2b13c93979dec84984caa12154b7cda2f4c8d91bf24ad7c45a968ffaac8d6722cc26e6aaf52dd29ea2f09370ba46d79684b7a06faedcd17136f35a58e5b550f3a2caef7b195d8409914fedd3c3154101bd735155098e8b10fbbb1b2e13555d2ab5d5b52b203d4efb27e498b240f37178f2e89b413f94859b0e8b2ec10b926c8c0b6f2937ee2d0355445364841c7e0539f7073b88c7d568edf1b253f3c10627e22c2ed731b7d4d199449cb0b5e7a66109932fe2c9cd741d75170deb9f98469049549c10a7a622bf6e91 -A = -fb0eec3246e99212879e51b17ea6615275818ecc5ea3058b13dbaba2576ef90e1519e3629b09fdaeb02661091c395c862b848f6326b9f536f7af45718c4412f09f19261b537bca36742d3ec66f964343516aae2ac27e249a15beb545b447e37b4062180f6c82809429 - -Square = bc4193ecb5dac900191e02be06297106155c6840c4908fbf6e41e9aae137d53c3d4ffb87f334f49837dc4ab7a66299994e4f5c9bf6ea03e7db663bdef066e94c610580a8896a9ae9c8f6587eb83d789683f5d6391bbac3a1dc1de60b4108428e6f5fdeaed6cd3e74fa01f85c6368023b61a413b69b14276b66f22653491e4f25790985053d075387cb13c79dcf963b6d880d01174314921afe1cc700c02efd2979dcbc59c417a6316db9ac45a2d60d2a036571bfbd75f9f5e42048ca086cfb4b818a9beca4a6e0ed51afa320ef3549151fb39e100 -A = 36e1f16043b4c9b4a304496c39dd63459d6521d2ac92916d348daca3f972835973fc8d21b07b09d8f5e3197b39a8f3fd0011168b815d67c48143c413e169ffe0f56ff2cf8b6596bd0a3b5b7a6b9a14ffb797f350b7e6aa7020d84d1d1b8006850139795abe2c74f03b8f0 - -Square = 4cbb5bc1dd7112326e2c94581f19efc8fb25339a299fa9c007114c3a22b395e9d39a8ffe21134e97ad1b87b97e667ba48b2a40af61afc81fb1e20e8e38c7ba666b146016af4dff3faf5de306591e5ce6eddc1173fdda6fe241a9f2fc6e054c41e56d296f8954377df0d140096b9e9d6a5a23a231db4dfab0cabfb11190c7a0d1c55ae35203836d433da96ca7339682bac0a7edb8b5b4dc267c6e83ac9b67a0d0d564717ee3c20aaf52c0a750f3aad94a12537c6971ee009d0f82ff576e984b06c7f7b357f5c049454e31326b952af17aa62104780e9ca1 -A = -8c279ebe466de3115b8740f3ff9c1f605b4eaa75512d82fdc8ca5ce84e11a68688154fd603ae1d607807dbfcbb822a8dc259098842c6a7b7ec350be29a3daa20fd5b093a56692e9d42e7a389c4ad2122a74205f835e268c9742d09ad36238c34e143f6e2ec69c0f490d29d1 - -Square = 4f771ade09cbd1a033d2bfc6036fe46ae6c12acc6f2b9bd52e7781693fa6358cf93089f23d1f0ee6fca476a43093b9b52446f3a7abd72ed0ce9b562dc438822ffd84bcd898ef9d092f1b0b7ff89c4fdb33d8715dd4a0d68ec49ad41338fbb62ca87867d847a4d99310641a37ea78b04c85606069d0c0950484ddbeedac8ec6f95124e7fd83da4e942d40103bc14474f5cb125fa0b06cf167f076979948003dd8dc3711923f5af5beb5f56c0a48ac0c5240b62738c1cdb06b87ac3dfa17befbe938ddc7281f6c248c41a1c7b99b93f69fac83a46eb298a9fd8b9 -A = -23a845bf2007ba8480e3ece0a1bbaf8bfccba6bf061e3fe1d8bcbcd6c761e650891c0958bac68618a1f55b27d2bc6e1e1b50afc29f58e2e034bdda8405e5378cb5bff0d84efcb458c5428fc607597d89d589d85d90f3da4b89a64c9d1623b98b10518a6f2e7d2295c37527026b - -Square = ab45d12a4e15a294830741f4b9d4a14cc7dbed1c3454612047f890211c749d92ae0418f11cd44acbf1585b1f7323b33ac9a4b13c44e1a7e31b0dcc1c6dd4eaa12a655b5de08f3b948270a152db7d9e04dc54677075797bfad6a9a0e3958458d40e3df5e15028954bae99518de4dd3adfb2ec4b38897a8a4e4807849e1416aa4040c95a0e49a8d2889f6fb0537875f87516c3723e8d3b46da8da855929c67c0eb83daad62ceced52b4f52d2bf1c4e34f26bf16aa7da3afe0f5df76c0858ed98f21e1fc3d01e1572715b774bd5c2faabec5fa3fa59a7a1f32565a4f1f9 -A = d164d875e1f766b4567e9228241213e69d6b6c58620600166fac56938c5d9643932d01f1f4a2263dca4b9ad26dca1548e4b5b7e27581a63375d0e624f4e4c99b7fb9aeb25307c61142760bc4771e48c7ce38f5eb2408def632096fe40b80d488fe17a455d80edfc1c23c429775b5 - -Square = 5ae4e7dc5727543af39ed3d5e9ac086d1a2220421231b82f6f41caee7b9815b4049aea0d43ff499c6c9e1f226f8641351d03f37731c64686d9a9ce68e9234d6a762efcffdecd42f81044111599963d9b6873cc20bf4c8284fae03d2e4f238a14a74df4388fdc80fad0375a5d0d974da7854ede5896ed2ab25d2b49a3c39093600f73120e4fd2faf75381854f6ae80f81b977f62fc72f1fd01c278d183544052b77bd753dd88ffdf5c01745521fb8474b5c23b0b7dc709bafeb91cee0863a0c23ad7192c43cf15fc181d629853cb9b8334082c915dd3d04e3a0a81511d2e84 -A = 2622a7bf45ccd3cd567c757f4c5796b5a0fbca555bd0ac2759c24083172d82d6a887dcf93d9788fde052cb20a8963cb6db22bf5eee6151600f9d1896a7606b11a1b100cbc0925bce037bcea57e361efcc560a9abc495d7f7f45831c6429ac8f979dedc08c304f4da9c0d4d687376d5e - -Square = 473cc933f5a650a4ae358c7f486d325c0e20c83b54838fc08b6ac3ff010f7c4b6a609bdf472974dfc5abda0c6b33c5ec7dc4628d85cb4276108e2b0bc4e19cba135533b3d7bb6a94332aea3165dccb230860d2353166b9905635e606185b014730e9dcf2c433e18cba83859fb2eac4aabef68c8314ef86dec2d534a184ebc4cb193643add0897341690cbe18bc2e775327fd7d71ffc7ebc49bad83cd68394eb276b2e615ec430180303010a454ef73b6a8f02bc48a1fc8a32f8150ef1b733f07da752b8e808000329f4924976bc8b8573927f18ca7c88c210845de6dcd0dee2904 -A = 870b2c4b054076d0d02877b19fe1210a8fad3422b00905a6db748239b8e807716ed9fee0d8c25496593717917edceb5db57f9960bddc1956b6652868d6ace82827bbbada5ae8c15efa26fda22657126c6300906f90e8fabfd58ddf312ce0eee760e0090fac44f00378c676115cd0639be - -Square = b151124402d2f04b0e6599222d380dcf67b9716ef50d2d9ded0b21521b34a7294171f71b41762511b7cca93d9f50e9e30083ef19144882928011dbb143807d1b88c55eea6b19f0c4180023be6da63a59b6bc027aff3f5abe2f65c73b2de1e71c5f4b248bc4547040764e83a860cb3f882bb8b5f7821f92802808fa37c50f2f94d8f56daca841f42d3362762ba843aedbd03d3cdda887f75ba92423965ab4256eb842ad755aa7a2af331b488186f891065b07f5a299c807dc24fc176e085a8024bbbf12f386ef49ccc91bd4ada0936b6de78088cf5952ae6c04f6916799378bc0ede0da4 -A = -35439da9e361700152a35ebdea253378a1febec5f288e5b2bb0bdf25b84751b47e4da5aad7453b70cfd6640d5832237d2115575c738482ac6036c5fc21a981c0a7f979c8d621a92c02166b777475618aa6362a0e225dd6138ead3b2766ed9785ee01e4950a863d2fa0b7f5cb4c9a108bb626 - -Square = 4ed7263ae5beb0069f24318b38afe951a5a058a2e960e67f086c9680d0cc6d713f943812070bf94152f7926bdab9e5908941261244542b832f458f05ed5dc048c8b9eb84c2a85efe717e257796b4ca816948a6c8ea209c0675efb2fb5af4622b44e36066593db01b17f4dee21d7c1337ff41436cd0e5a8d01e4030dcd3d49839e59996fbbf1d39bd205343a424f2395b4d3eacdeb9ed3235d8df0dd00a2573260af63db3116a7c65d1dc69684a05caebff34e3d2cba9d4869a953a7b1fce10ebd008cba021008ac3187bba846abd7b39a1b97c9c07d8080549e313dd58b716022de3c1920329 -A = -8e1141dcebae61d5c4d81697f001d792ee2e847c589816f923f0ed42bb4de0d8f911b8ca47ffe77f80b9da6896a9b42f0030a3276218868bbe1a3fa64fb0a577704339af5dd82e66780da6f58900da3f1d75ebfcc302f78ed66ea3c7a737898a29b1f2500686b43bae1e6571addd2842cdce4d - -Square = b09f5e9472cbb75070a67d025957fd5ac3be89c41e4acbcd5f75780ca459562461082c3f19c5a4a416a668b0a55f31f74cf2ec44555ddc43fde64da0ba781adfac4520dd0f78d04d9d2fd33d8b49c72663a6bc845015523e2e4e7ccc69e5b748b8b891e4089420bf0a3f6032602824c7230b5ff95f85a688dcdcfc890af3384710a9fe32ecf9ad7c6cc5761f13079b19d7b2906c7e63c14b64fc88c6f4bd7c41c0356c777d35c3626d49db8cb2d1e89ce682c7fccc3a459b08c20c4e5fc3a8eced9b37d01bed5af6ce9baff0d2b435e6e62871fcb20cf9ec10d1897a5c76e73a441e07fbcc2d9f4e4 -A = 3528e6581de547de385c93ccf1086a17614f23356a918b25bc6d73656a2302b318963bb679c9a93357f4a4f614e74f2e5e88e9c8aed8a6fdd8434630f664ed15ebb6095cbff1593f188a12f4dd6087a85b202f6c24df68ac3b137406c88c5098faf47d1eeec0743b35baaec7dae29b5a44eb09daa - -Square = 5d5dc40783411475a4aac7c1a1eb760f76fcc6ec68dfebb754251cf499870654cd309422935ec841e6be4f5a15078356235c2b8cbe1ae755cd6d814e811072bdb76156b83c7d2064a202ff90af1e0f88f5889e5729a3cffa9faf33c463b74d0ad21fbb4473d4d3ebfa8a52e9c209ded5ce5131b12b69747c365146fa17ee5810e0dbab992f9da28b6c323062484d62472232721d608cdb9b5a341a677e2d7a6e5a983247d9a4001e16687b489b10b18bbf205f982b7ceee27cc3e9c6641827ab7952373f15d36e5f177b82d7eebb3f5054e12cec82c5f520a2675afdec6cbf6235d358c2fe73344002e400 -A = -9a9a19fcdf11bba84b0395088c5d187d84d69b68b77bc6418f63c88bbd8dbbccfe02917d814f9e2241fa0709817a0c85bd554fe887babae7439d96248514c12d71587c906247b3e965e954cdd57f1e51f1979f73c3237509863169efdf281c1359488daad3d9eb990a50ecf4d3fd25d4820077832a0 - -Square = a4d69ed4c4c9c08116ec5cc49ad458f0fb2ca00f356aeb148f18037bc49621e14820f325af39f3954bddc9cf01de7ba1e443088545883a94c04ff41a7ed5f65676109c5b711b4115775489667e00aa1b77f6dee5ac5c1789bc71c9fc797abf41c7c5ae3e2c1cf82d5b49b6c0da25190dfa9360b99b2f63444d21ec6114038b8284bf598eed24a2ab2b9802d6edd5b0fdb52f60621a87a14612844ffc71ca98180ff0915cf75f47432f73d28dfd7a932a125095655f07f50722b1673df2cc4f7566a1c6035792ff3f02356b9b9d25e905121df768dc6a1884cf5483eeb813c1c009fe4ed043febd61800ba978a40 -A = -335b12e40bfe0b847ed6ec143490df33d2e64ef4363869cb78dec008cb5cd66ea671dba964a53e48267da288ef4040e06371e1209691b81df02f2c86a79cac85fdcbb6732a1e5309fbbdbcd899fdfed18518d47258c9e63ff7f116ef4a8f5c4867aedd907ccc7d222cf8087afebc108f2a0f197c717198 - -Square = 74dcdacc1a4f02a99e3642f54f9d917b117d2ae8d9c392f8b6dee53fac66ebe1680c8e8cc29f5330e0eed3f63d10980060799bc37b34c93dd7b384d4ba30a5b5d42a145acc412ae838d7b9b7137637546d1118f7cf3eadf88b785f0aa01da8638f027c56faa16aba8591b64b45dae6138c9a40309b2ad29c5029a867465f9c6de8fbc5fc4b0442c8a8946272667c7622454ed6f2a236103bed7697dba20db84b5154ff3fbc6b4b9eb67ee43bcaae741d87ee2093ee67defb8eebc4a4a22d97a4e2aa7d4c31a1c88abf4a440ba4e2a5e40c4d903ba5ee4d80b4e8dffb8864bcb9806e015c1ce16490068df87282393111 -A = acf70350e554732c1972903cce269b215e985ecb8d6eeaa67fd5398d0a1b57c0db63368c0f8c2288c3a0466e2b3db081106b90920c46462faf00b5bd654f7140a689b78ef656a26b82af8dd1988f166ea04e9aa777a094d892bc7da4bc7bcf0618526f496cddea6d67df7bb0de9e99a35a0b1b210ff07497 - -Square = 9668b9e40a8bdde3c93943a918ca71fa0009cb05a1f592b2bb2c6c6172b2950719bfd80cddaf45d044cbb6aa99715046088f40ec6812945885679231c07f4200023548ead086b834abd8c8f8294db28b203329553242fd2f778ef5cc5ed0b48c7356d8c2d782a01809ccdb6b012896617f11d963300e7bd38ff512829514d94343476818ddf9d712bc70cffe7f767a9fc75a5630e6250ed45e6831b4660eb49d47dd1b8b6a0dddf3fb3ff0e12834337f145f741f70a2aa43769af50f099e004269ac47fab79e060800dc74da88141adbc46c15c7330931e3a2bed9b958f78b30214f81a64d121f96fbcebf7569fec0cdc6b11 -A = 310e7a40667d9d5dc29744b123cdf6a663a1b995f62fa9d4d853cbae0dd23669f4778bb2040317ebf6a06ac6299b21067aece5c5c1afbe6e789d656745ad66464991cada0eb237c6ffe991cac4670bfc90eed5f8c75073f4f846ea244bca0e9502ff56f8e9bc9b6caf275aaef38e26566fef35329ca45392069 - -Square = 49e677c8b052b7db97542948542449af47e14248021f8d3d3f92b9af41c803072f71050f16dd848aebb270affc47e85427a7c73f227f0d63f140d0d293157af0d972eb5b38de494fbc78ad3a4c3d1ab40197bc4427752b6102d1ced6d6cbc9d7caa0d1bcc57e708535822180055ecc9d9667e0590274b778480a3720823e931ff6daef358b1a1a9092f1f05fbb5b10ad5707a124e8be63bc696f083eb74e5b4f0e3110de8f297ecd30dfd2bcb010dcad4e387520d3d00365fc51c2a3dfe064b1ac77a9295f66beffbe5dd4333e5cd823b0f36b0b94d66507b1d9381060980f62f38a62e38e5a75203233bb8d64089bfd100f3205f1 -A = 898b5f3655de74cec3b0fde2ab03fd18cdbcfc3eeea48ba39317d26917130c2b78e05237cb0454ece268f091cab699fbcd51ce341b53d6ec0cda5d0d5388bac25c6517214a39d03450ef8502e1675bfe8e57bb6086f10ce4cf8ce65eadc865b5bd8a00dc26394f3adb2ace609149e3582cf44246184b2adc0ffd9 - -Square = ad00f10fed55175159b2409dc80899f9113ba7c8099d0402ec0f520ab4aeeb46d36369494a4e6fa23675adb38148fd2efa082df5094c0acfb77a9ab6ba7a299298d69b04b58011c35325f46b765e580b5c05eca721904f1fcc355dbe39faa92af5c9a6dbc4ab80e62b815b45983d9506ebd52b9efa7a6b9da352d1e4fd6ffa81d3b4596a0c14fb825297da361461ff2240e4378340d2ae529932d78f3d9f6b3c6d65d717e66122e5f590c50ce0a5d81ad8e0f24e104c0913cd8d0eb2de4c8cf62a7535bab5502df3fba08bb4dfe73d89c8b00edaa7d5f3274be9959e7ab6b6dde54f2491728a1dc11fa8e1c6a95e67eb7617e9b7471ee40 -A = -349cc2a5658fdbe9ba5c350d3b25baa38b1ede01926694bd550d36883e53d8758e8f1ebe83e2f4560605510413a7d880929e2d9cbc2730b1736dc2689cf7bbcdc68a342b6398e547a9bd67cabe298796d76b98ed4c1dd9c22e36145892e8fcf2258529aed24252a70b6ca8fd2aad8a84becf7e1bf98b1e9bb024b8a8 - -Square = daa3835d3189ec9ade592e6076e76d441838077a9431273bdec02379b3a6ac38aecbbd57c3755ea58ddef8105ac28f2ecc8598ec0c4bfc9c1c80222fffc776722eb0621cdd8a0d55f08767fc2922282a76e529d81e4d6e21a2542b8c9a403709ed1132e3b52786b81e684591438fdddb5df2f0b72e6b39cd2db6c0cc55c759c2dc1b6ccc20a5cfd10c6fd345fc766035c7478570d4ac534db3fdb718e2bdad3d096b137bfc09a562043800957e2afe4fdcfe292881f6189edfce52370c0438c2822ce3b14d73b3eff32f7e5ca97e989326b4e3a8fa35544193f8590bbb0ddb1f914894ab87998090771a0be1fd23917cd792be86ea0b98e6eb24 -A = -ec953f1b7ba7d561edaaa23076987daf86f50e9a66c36f0993290549a9006dd9d424885c0fa77295cfe34fc81c5edce9e2371b3039ea18d8f998d1956196284e6d81eb1c62ecaa8cf3fcaca28ca7e64342803c8dc3c139080bdd4a1ff30d7288b085a579d9e90903bd363b48f2072bb6fbfbd9ba2cab30a8a63784d246 - -Square = b33f4f3ae453058f4e865ec78f0844bab7af66a97dc2f265ca73ae2232777474bfdda39e10652d7386c16f145272192af728893c3d8a8e92c60d77722b924c30269ff5a399a2449ce15e50320c528c22655ad06227ac4efe5a993179ec61c2fc9115f89d75b53961fd16f7797657f6fbf55662b019608a1d30f64a2c0838e0018b7526921fdd34fd462bfcb2462b7065e2bc7abd57d71371e45dfd8fcfcc00a71f7e45430820747c9a060b72e4f6d2919cbffd00beb0c31a2bdc32afe2cc540b38dd04a2b73ae5ba481a6e535f37a757bbd6aaa972986213afadfa47cb7a15a6f1d443f93cb0ed824a10b4b7d82cae524a096b65ccb39be3c37c07f59 -A = 358da59ef65f62f633675764e292e5a68879df24a4727eca1fc4d232b3a6d936976c92eeb11456b5e8c11319838c145c6529d2f3acc828e55b8274bfe9afb5db241b102715f8e8164e454ef39f13ff1b37cf367a5a66c4f743c750896b7c3c29026e448bb36c6c06b0d9a3d048086ef0c3cd922a02e794223f388b5d646db - -Square = cd4246489f6f221f920acbd8bdcdd17f47d2b77268f72254de4190685c123e8c5eab8517fded1852e8316c9e549d3fa355142d91b2921a3c94aafd8862cd2235429340da38a2af131b8d002f17662354f5805f6a7af7afb6dbd2f641036600614cea42bd8b24d86a5109eed29c0865a5f30c5291b1d1ef3223f9b9826dee773d98ce972da92daa19e843f84ca5f1cd77925a3c1117242ab0fb509b94a83f8de4fc8d21f856f37a4d025b3024bd0dbb6d8acfda4ab2993fd6eb7a7448d4f66ec725d37f0eb14eb242c0ff3f0c4572ba6b98a4ce905fe1b7ca3daca56c225171428c56af938fb66b37e99e54139157bbf41f536989ef813af738837afcd62290 -A = -e53ad05c88568f09f616797f0b7f2756fb543d691ec2a5b645c1e5892a247302826419a35b1348cfd2c1c569c23c31b4c46d6c57d4a488c29ab5beb77904d4adfcd0a01ea0a26bb0cc8790441cc2c8c900f030d7315b4319f1a3cf5685a140e03abe6b94730ad79e8de1f4a0cded86a3d6cfe2db267fa7dc9b2bb32872a90cc - -Square = eea8028b26e0df090504d54da714a6f5f2695202e53cff479c78aedd47a8dc676243ec586740fde53b3eca9ca02b91031ce766242184109503fbe25b1b6d318e3cd5970fabd16dfa22984dd2e9f1e0f14c189170fc69c031d66663703e6235a942d51a4545bd7b0769d01d302ce2b00b83f01568a1e378f61fd0ca6201b0490330580cd9de85719e174a71915d7efbf65cd73d8f4e66f27e0dd3144d58ec09ed0f7ed7d1238ee596922807100fb7a11127944ddcdec6a9ca3bbf6df7301e354f3f049bfb7c275b43c3d8cda5907a932fba507c9145ea3166081c1b48fcc710ee32cd931f936c796b14f8a78a592e67753a7c9e428a01719c8ba82652f3a89fae110 -A = -3dcb44be1e54c5a5d7db48055ca9afa1ebe2ae648aa6e16ac497502a7deee09ffa124720fad0ab163ce8b3ea6a90f110ea52b67dbc424d0cf1e8c9726dfd9e45bebcefaa5cd5706edeed27896525f31c6bbea3d67ee97badefabf3e2532470b66e3ae3100f66ddf50cf02fc3a8e3f44c304251d3b6a7ca3a6e4bd5d16a41bd97a4 - -Square = 0 -A = 0 - -Square = 1 -A = 1 - - -# Product tests. -# -# These test vectors satisfy A * B = Product. - -Product = 5befab3320f8f90542f3120235abd926aac3805a19e343f690 -A = b057af553afb120db6b7764f8 -B = 857734c4c27a1d17f7cf59dee - -Product = -ab1ce167f4b2945c55ae3f87df50ad07d4be87cf9f8aa07b0c -A = ae7a6a87ea8981a567d0b3ecc -B = -fb0fed5f8c737bcacef4d6cb1 - -Product = -c2606cd48e6b075c8da79eb4668e7157f1f175c2860fd4c475 -A = -c28dc31984d4583e9d45424c3 -B = ffc4581a5c3f885cf42767e67 - -Product = aa6805b5408aff7f914472756da07830dcad902834dbdd6944 -A = -ffa07ff9f503511954e5dd3f9 -B = -aaa7af472ad8957763f5a7c64 - -Product = 58ca2569173389df29b5ce4b784086055dee821a7243db7210 -A = af417d936f4690008811a1ae8 -B = 81b26b80b43aa65aa55ded52a - -Product = -a043d31dfce8bd01724d31c863d0a64f1bf013509d77737c42 -A = fb5fae5edefb6997d44a1ecd6 -B = -a336e50c6f7845a1686cc88a3 - -Product = -b5d6a45ffce851b201239d938ba551bab7dcb59fc11fc35fce -A = -f918faa58bb57a2ffb8b01f05 -B = bae08c3006fade695029a1df6 - -Product = 6f2fde7d1a18625d727c6345ed85e597d546d9228bf7f0564a -A = -8d108d7a16f0696d4ceb24445 -B = -c9c764cae465207097ef8d2c2 - -Product = 93808b1140841dc9735cd61c6f855ddbbb83066689b0d7e1a0 -A = b386d08daf3fa2154e9c768d6 -B = d2557dceb2d02d04d9c578670 - -Product = -ad04212ca8cadb1f7861c5130ba3a747046a2a7e4a0c72b69a -A = e4e5f7d1311e0c5f2e404d55b -B = -c18057a328d8c7375afdfd4ee - -Product = -685e75c232f2b4a0e455fe5ee8aea52f292ad8b8178320e692 -A = -a683312f132b2320632e74ef6 -B = a0758f12791453b4af354730b - -Product = 6f588c53185c503dc5b0dc3002d3817ca2e7eb2370b3e9a647 -A = -d70c9b93170261091f0c53f27 -B = -848c86c51a186ac4c9080d3e1 - -Product = 5e3bc5a04e054a9a244bf7c86cae215072fdb70e9199989427 -A = 898b64ef09d7cf63966e1a3b5 -B = af638b12f26aa5d12e97439eb - -Product = -8d8372b235b16108285203c03a8aef6fdd3c0e1a9fd31d4f68 -A = f6003dc83818c14fbe36c9998 -B = -9343f6cbcc81fa4c9399dce5f - -Product = -5ee6509abeeb7af7fc5caef40d1822ad3150c8d74f522dc7c8 -A = -875ff6f56ca72cbdf614bb9ca -B = b375a68a21dfb1f159c22fa14 - -Product = ada25be404a17385af5a330da799e5909da81bfa0715baa6f4 -A = -c9b8df392e76abc3eb7d5ce04 -B = -dc5ab818c70594dd917b4243d - -Product = bb24422ee4656ddfcd50ec38201b15baf679d3b75e5cb878ca -A = f8e12cf4defe388b78510f687 -B = c07ee817b4ae95c2915b88966 - -Product = -93da296ba164c7220a17330647aef0980c94eddd2cfa2a3b2d -A = bc5dc74ddf7a1363d1c2b1f25 -B = -c8f069bad7f93cbfe6df51169 - -Product = -6b2e1d132c4e0b0dc9b7e7de7d424fda5180480cb5ff47c755 -A = -a8048acb66a8bb88df39266e7 -B = a34e0b265d71435ae8c92a463 - -Product = 6ccb2cd93783576a8602ae43f41c786008b6623a4cca0a010a -A = -b071f1f54790c951c1dd2a1cf -B = -9dd89bb4d9b546207e282e2d6 - -Product = 5c742ba47d0d64bd97509927ce957deedb855766cc24c60016 -A = b44f3f252c368096fa62747f2 -B = 83439b97dbac579fa4f7b7d23 - -Product = -7347ba65691c913286c2fb55e45b177f031c1d86ae0e9f654f -A = 937cf0643ffa53cdea24d642f -B = -c81881f78243dd5737a7d28e1 - -Product = -9bc0649a703674e59f83ff9b8a560e5cbf51f65ca310f80f95 -A = -b536f8d9769be6f62da941ae5 -B = dc0746fb101881ae0cacde6f1 - -Product = bf4992fc3a124de350f9fb90ea825cf663b1fa051282ef22e2 -A = -ff7eacc7de1bb01d668c693aa -B = -bfaa6627f9fc7ba68ae41bb2d - -Product = 7c8992d34cc0b63f1c953f68d4e12a99d3f3a34d16bd76caa9 -A = 9e0d5a850d078890a983c0ec9 -B = c9b72c118b3e1f1023a696ce1 - -Product = -a75840c95082b9a0ae0d6e0a4eb5e09288e4e2a66e9697d9cd -A = b2b042a21045a74ef1a5091d9 -B = -efbf8b120b384e869692a1b15 - -Product = -a510b333bdb4ed7479c142e8fbe2b12f7671a42acbe16c0998 -A = -e7fd5e0bb5496b9d876c27f65 -B = b6262653b2be44501af1d85b8 - -Product = a1c1e90afc4684754155526e307fc6ed798746f347bae2c880 -A = -b84674832b26ded0a690a8ff0 -B = -e0b7bdf2fd05a038ed3640b78 - -Product = 5588e0c33bffbefcc5695ca0615abd383343f21a8a0d22b222 -A = 80cad81ad9a66ab6a1c2e5669 -B = aa0453a77c8af1584f54750d2 - -Product = -6460c2fcd6cf3304ab163ea883ac48e2031cd10f2e9014c0ab -A = c49ad3d7c8848d4fbf913b10b -B = -82b3dedbe3cc7cd532ad632e1 - -Product = -a18717330b711669e85abde8c4dce426529aa621ba3da2a477 -A = -cab4a9c0a331a5a5e826dda1f -B = cbfee5041c13075dfe3399aa9 - -Product = 8ab6282ee892b53c083d319a9dcab48af97a1ac8493c0bfcad -A = -f7d13e47f9aaac8c25f9bf75b -B = -8f4aa95231c1e2336aa092297 - -Product = 8f2d1c23c78777ed371f13155445ca3c88cbc0a9b299bdf9d3 -A = 9d8248d00defce1ad081337c3 -B = e8b479295ecd9cef7301f24b1 - -Product = -86d5e0c5b581fe59819730b4b71e33d1f85f9ab504c7dbe2d6 -A = b21b45e88acff48562a19729a -B = -c1cdfebccc763beeac394b997 - -Product = -484ca05aefa113bdfcb1bc623f730c9f9555b462a8ab4c9606 -A = -8c12b406c02c4417163c0956b -B = 8422b15c80c1c087b17eedd92 - -Product = 614c3c91f60050c785fd229a3ad74674577a90cacb654e0a5c -A = -93d45bce155a23a397506d96a -B = -a87e339c3fd5aebede5fb1b36 - -Product = 9683285f194a7e4feeab196a36bdfc4f828035fd184b9cc692 -A = f196d8fe760fdcae7eb60e2f7 -B = 9f7d88a2163ad818bf3a6377e - -Product = -988a64599c19cc64f3cadc1a83fea6550185f6cc3ab82af822 -A = d0584b2a306671e4d2c9d0c7b -B = -bb6e7559df199c68d6df3a3c6 - -Product = -68456814cb0edd951196d04c853172afdd5787a5bd69a57876 -A = -cefce1b0a1fb22862418bb597 -B = 80f614139947aea5e76cd55fa - -Product = b4b1cbf5d6566e7a57aee0cc5c9c8ec4ad885e8766aa7662a4 -A = -d68ed1bea046c6cad057e21db -B = -d7988b9be54f6e332d019032c - -Product = 6b09212675ff5257a1384371e17b37dcc268bbb141577902e4 -A = a8208053adc20a609d5d01404 -B = a2fa927c5458c4fe662d7a3b9 - -Product = -8361bc26f9bcf55f677e047d822d3004027da0d0455b244d10 -A = e82b6410b29020c2d6810a977 -B = -90ddfe0e7f0d6b9cdc0815f70 - -Product = -f1b6da00923fd513a83e32040a515649fbd362f69ebc016d9f -A = -f9b697d9ec774a8d1ee5ea905 -B = f7ccb46a8869cb028492bed53 - -Product = d06206963f2e150bacdb32c823c3a47f013d5a267c3c0d0c88 -A = -ea8e63afa99c719897ad7f2ab -B = -e36f11f55b6148d1b4f46e598 - -Product = af774a5eae6084df5ca499ef005642730adabf6a4f9533e2fd -A = e4c7af7eea3ec9cc2443b7319 -B = c457bc264c8461789931baf85 - -Product = -76350f428bfbb95e6c253ec0f457aa84cebe8c7cb1af2a2120 -A = 8fd1ff97465775d44dee58ae0 -B = -d268a7d328f44baf80e35119f - -Product = -787ae3f114f9a8dd4d249d5d3f3b0897b02564b9469416cefe -A = -bc0b398bd0ec045b0cf147b7e -B = a4050955c234e473257d0c641 - -Product = 9d6320b3d4aabac097a079b9bd2aca7f1898bcab0f23409fd0 -A = -9d7a4ebac630cc0662b816fb5 -B = -ffda517d3eb3214986b04e290 - -Product = 80bab8bd800ac8c9dc3bb57dca306f10af6fd88c5d8314833c -A = 834bc50140d6c6ab938dc58b6 -B = fafee47793cbc533b3c66af3a - -Product = -b08920f5922226b1dec87151ae087d8a7e5c1aea8c9be148b6 -A = bfd5b1ad323c79428cb2db36a -B = -eb956a10edebdd658e6810fcf - -Product = -6d428e08e8350bb4b0fae3b662c82df2aef7beadaa17430dbb -A = -a57da276998c548101f514e9f -B = a9040c1909712e1149d295765 - -Product = a57da276998c548101f514e9f -A = -a57da276998c548101f514e9f -B = -1 - -Product = 14afb44ed3318a90203ea29d3e -A = a57da276998c548101f514e9f -B = 2 - -Product = -295f689da6631520407d453a7c -A = a57da276998c548101f514e9f -B = -4 - -Product = -867614005cc204a8d19720fe13 -A = -a57da276998c548101f514e9f -B = d - -Product = 12bf3b676f64e5929d38c35e803 -A = -a57da276998c548101f514e9f -B = -1d - -Product = 24d8f92c68303ed0b96f91a8167 -A = a57da276998c548101f514e9f -B = 39 - -Product = -49b1f258d0607da172df23502ce -A = a57da276998c548101f514e9f -B = -72 - -Product = -6fd5e6ca25c3d51b2e529f22173 -A = -a57da276998c548101f514e9f -B = ad - -Product = 1276d4705b81b82da4c7e82559d7 -A = -a57da276998c548101f514e9f -B = -1c9 - -Product = 1ddb9abfc5d4017f068a67b5f4fd -A = a57da276998c548101f514e9f -B = 2e3 - -Product = -3a8b41c914b1b4a4e341433601f7 -A = a57da276998c548101f514e9f -B = -5a9 - -Product = -97c0f4ba414d6e7d4c8b7ced84d4 -A = -a57da276998c548101f514e9f -B = eac - -Product = 1198739e0c23639c176d46d13f7c8 -A = -a57da276998c548101f514e9f -B = -1b38 - -Product = 159150954ee0dedf541e4dbac0ec3 -A = a57da276998c548101f514e9f -B = 215d - -Product = -441d4bc44c86f02ff12c3d91a1562 -A = a57da276998c548101f514e9f -B = -695e - -Product = -64726b76005ebee27592237ba5dde -A = -a57da276998c548101f514e9f -B = 9b62 - -Product = bbe4ec7cf7c5bbd198e0ea86bb658 -A = -a57da276998c548101f514e9f -B = -122a8 - -Product = 21f717d05681fd2eb1796776a69ef7 -A = a57da276998c548101f514e9f -B = 348a9 - -Product = -396ac788a1748bc6955f99be4d2c64 -A = a57da276998c548101f514e9f -B = -58d1c - -Product = -54a213eb083aed1a04f3d1b2da62e7 -A = -a57da276998c548101f514e9f -B = 82eb9 - -Product = 1366fb9c20fb14b8b9a9be4b3e3dde1 -A = -a57da276998c548101f514e9f -B = -1e037f - -Product = 238d65fd26da4733e5d93ab2485d40b -A = a57da276998c548101f514e9f -B = 36ff15 - -Product = -38272a99be154d531e922be405aee9a -A = a57da276998c548101f514e9f -B = -56dd26 - -Product = -64651b62b6a454c08951632c7f2c398 -A = -a57da276998c548101f514e9f -B = 9b4d68 - -Product = fb272e3597b816144f8b945ae6130e0 -A = -a57da276998c548101f514e9f -B = -1848320 - -Product = 280d9f5ed7243712ecb9a7c6358bcb8b -A = a57da276998c548101f514e9f -B = 3df5795 - -Product = -2fbb6bb8e1ba78cefc47fbbc20e188ee -A = a57da276998c548101f514e9f -B = -49d6652 - -Product = -57f29c13691ffa1642d2860dab9d288e -A = -a57da276998c548101f514e9f -B = 880c2b2 - -Product = 139c19d7668e6aabf2d7206cb0723ed34 -A = -a57da276998c548101f514e9f -B = -1e55aa4c - -Product = 2950ce04bf0cf836d4fe94b88fb757d0a -A = a57da276998c548101f514e9f -B = 3fe968b6 - -Product = -5175239488dad05a58414251496d2a06c -A = a57da276998c548101f514e9f -B = -7e020414 - -Product = -945ff0ed38bc6020cf679cbd3e0758c6d -A = -a57da276998c548101f514e9f -B = e585e573 - -Product = 11c69ae98f6b27e95477986f796bc67c8c -A = -a57da276998c548101f514e9f -B = -1b7f653f4 - -Product = 209afe75e8fb5ac76d13c06b545f5d4d73 -A = a57da276998c548101f514e9f -B = 3270154ad - -Product = -386d64b215e41506514f4988ed237e4da2 -A = a57da276998c548101f514e9f -B = -5749c891e - -Product = -6c13cccdb1d140d0babd52707ea72fa278 -A = -a57da276998c548101f514e9f -B = a72fb6288 - -Product = 136228a8a45540372b9b3cd7f82021f6546 -A = -a57da276998c548101f514e9f -B = -1dfc08a2fa - -Product = 1f0ad3babf9d132eaa08cf5cdb8f19dbf01 -A = a57da276998c548101f514e9f -B = 30050f2e5f - -Product = -50d615ce183258e95af77319b766fac81e2 -A = a57da276998c548101f514e9f -B = -7d0bf92cde - -Product = -817d358293b86a56a4e881e50257c549471 -A = -a57da276998c548101f514e9f -B = c84efb12ef - -Product = f09b9e80be251de474d726b16e25a6865fc -A = -a57da276998c548101f514e9f -B = -1743322a484 - -Product = 22996cb0f9c60e35dce49f3825f8a479db26 -A = a57da276998c548101f514e9f -B = 3585acec11a - -Product = -2b307a37c91791a61c0691858f5f783e4678 -A = a57da276998c548101f514e9f -B = -42cf6be3e88 - -Product = -8826698fcba6c30d755fc523de1cc25301ae -A = -a57da276998c548101f514e9f -B = d29cc8af592 - -Product = ae37fc99fd419809310782714530d7428d77 -A = -a57da276998c548101f514e9f -B = -10d8059d4a29 - -Product = 1d544a20f9bc7d95ab67d1f65743979f23bba -A = a57da276998c548101f514e9f -B = 2d5eadef1c06 - -Product = -367897184e9929a0294d320f10278889fbeb7 -A = a57da276998c548101f514e9f -B = -54431582d0e9 - -Product = -943a509076a00060a2e7fa1cddb7468d734a1 -A = -a57da276998c548101f514e9f -B = e54bb102f4bf - -Product = fcce6e42879af5ad13545c0bcaab85b690cea -A = -a57da276998c548101f514e9f -B = -18711db522cd6 - -Product = 258c49f86d0cbb14ae9edbd3456be8cede2022 -A = a57da276998c548101f514e9f -B = 3a1562c7c269e - -Product = -4a8bbce59ad7daa51136d557f7fa16e9a2faad -A = a57da276998c548101f514e9f -B = -7350e780b0f33 - -Product = -82f53ec9333275d5cc271876a7db936db49280 -A = -a57da276998c548101f514e9f -B = ca94ad312dd80 - -Product = 11daee4fcc713db5b2806e47fa5dff3b5b770eb -A = -a57da276998c548101f514e9f -B = -1b9ed6758f9635 - -Product = 17038cac4f0c94dc24985ea108ae6682e175752 -A = a57da276998c548101f514e9f -B = 2399b8a9b1116e - -Product = -37e5f14394bf347a3ed061769fe8e6424af4348 -A = a57da276998c548101f514e9f -B = -567840a7569fb8 - -Product = -9253d4a32a88d8f725984514d969012ead7cc9a -A = -a57da276998c548101f514e9f -B = e25b246f733f26 - -Product = ace3648371c16a931d29004e79f5b9678391da5 -A = -a57da276998c548101f514e9f -B = -10b717b27b6a13b - -Product = 1faa5b45d04c143c339b09d3aad94d39b94ef960 -A = a57da276998c548101f514e9f -B = 30fbd672e106aa0 - -Product = -3fdfe246d27aae0d08d63b2bc501461d2bff3b8d -A = a57da276998c548101f514e9f -B = -62cef5f078a8253 - -Product = -5b792bfaeff04ee3d948cb343a249d49eb344f57 -A = -a57da276998c548101f514e9f -B = 8d805ac65649c49 - -Product = c5f824406161eec321da5a58e3e00d393b55abe9 -A = -a57da276998c548101f514e9f -B = -1323dd41d2e1e077 - -Product = 2226dec8a57be8e84e42559007e2d101ccbe67f8d -A = a57da276998c548101f514e9f -B = 34d47842b5d0be53 - -Product = -340f50f812c7420b502000940788a700f6769788a -A = a57da276998c548101f514e9f -B = -508836d8e1193d36 - -Product = -a00f1d96e19c590479625c5329a87774b5964cc78 -A = -a57da276998c548101f514e9f -B = f798fc858657f888 - -Product = cb94f830cba8997331912a6a31c34f1bef826d121 -A = -a57da276998c548101f514e9f -B = -13aec7a5c52a0883f - -Product = 16b45140b048d6dc0b9fc811df7ce7dd88357fff04 -A = a57da276998c548101f514e9f -B = 231f27f3e347bd67c - -Product = -2aa94179351b4e87de5849ab619d94f47450640199 -A = a57da276998c548101f514e9f -B = -41fe3ec2189599cc7 - -Product = -5489401d3da93158d4284e557d74016c0a7cfd935a -A = -a57da276998c548101f514e9f -B = 82c5281df41bfc066 - -Product = ae04d5b212ecfc9a6d7df07794d565df52991fb70e -A = -a57da276998c548101f514e9f -B = -10d3139229f5d02432 - -Product = 27821bc811f45d63089790b41d307be978d4b19564c -A = a57da276998c548101f514e9f -B = 3d1da85cc012b3e234 - -Product = -3de3c9e9d7fa3020a578706339314890dccf63096c2 -A = a57da276998c548101f514e9f -B = -5fbcfb28bfc9044bfe - -Product = -627dcb299a6720044abcf11469bdfd3f951edbb5bf7 -A = -a57da276998c548101f514e9f -B = 985b930517b78e6ba9 - -Product = cc0622441497a37fddf1856d5e2c99df52b99ea4573 -A = -a57da276998c548101f514e9f -B = -13b9b88948fb7e95cad - -Product = 1a5168e1a492210591ad1ed660adde9110390e4caf32 -A = a57da276998c548101f514e9f -B = 28b631c6e04b6ab0d8e - -Product = -4d8ec27b7460ce616421b9f5cae708c2ac241daa59b4 -A = a57da276998c548101f514e9f -B = -77f99bdf1eb09da6dcc - -Product = -55afd796db7bce822a00073fc8926d3bd0c79772f036 -A = -a57da276998c548101f514e9f -B = 848cdd6212b9bb3620a - -Product = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34 -A = -a57da276998c548101f514e9f -B = -154c39567bd8be5f6b4c - -Product = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c -A = a57da276998c548101f514e9f -B = 37c6e7ee89cf87674814 - -Product = -39002ecfd6d96661b336157ccef6536756ad2e9219be3 -A = a57da276998c548101f514e9f -B = -582cdab09915a652203d - -Product = -695f49fc891d53f396f0593efae3973082b76d4f9e944 -A = -a57da276998c548101f514e9f -B = a30074dbce2246af043c - -Product = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7 -A = -a57da276998c548101f514e9f -B = -1224195afc7b394ae8cc9 - -Product = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af -A = a57da276998c548101f514e9f -B = 26c6701c39334169e7bf1 - -Product = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100 -A = a57da276998c548101f514e9f -B = -5436e84b4a29858a68f00 - -Product = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871 -A = -a57da276998c548101f514e9f -B = c56e0f44fc63bca242eef - -Product = da7fe3367ce640fa5941c033ac1874312f10ba5950da75 -A = -a57da276998c548101f514e9f -B = -15200043166ff309f0426b - -Product = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57 -A = a57da276998c548101f514e9f -B = 25d057879db26fa29a5e49 - -Product = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857 -A = a57da276998c548101f514e9f -B = -5e46be70de21949df67349 - -Product = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63 -A = -a57da276998c548101f514e9f -B = 9238670897685a6c9cbdbd - -Product = f623344788efb857db55c924e95a437effa4dc8bb2bcd24 -A = -a57da276998c548101f514e9f -B = -17cc0ec84c228225a7cf45c - -Product = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72 -A = a57da276998c548101f514e9f -B = 20f9f925b3ed307edbb154e - -Product = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f -A = a57da276998c548101f514e9f -B = -6c5cbfd29f3dae1dce99221 - -Product = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43 -A = -a57da276998c548101f514e9f -B = 9136aa79080defd1bcf90dd - -Product = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd -A = -a57da276998c548101f514e9f -B = -1d03b512470dc3052779f3e3 - -Product = 28388a244214abf046488a8d95308d95f021eae4b994a5a52 -A = a57da276998c548101f514e9f -B = 3e37dce784274962ff862e6e - -Product = -4da476e76119deef291c0f56934a912a0877278a19a561ee0 -A = a57da276998c548101f514e9f -B = -781b2f2dc40094a7f8fed520 - -Product = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82 -A = -a57da276998c548101f514e9f -B = 87772a4fb582acafd3e4ef3e - -Product = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa -A = -a57da276998c548101f514e9f -B = -1563841bf7851ff158a395716 - -Product = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752 -A = a57da276998c548101f514e9f -B = 3918c30b5568318a58e9be16e - -Product = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a -A = a57da276998c548101f514e9f -B = -542fb814f45924aa09a16f2a6 - -Product = 0 -A = 0 -B = 542fb814f45924aa09a16f2a6 - -Product = 0 -A = 542fb814f45924aa09a16f2a6 -B = 0 - -Product = 542fb814f45924aa09a16f2a6 -A = 1 -B = 542fb814f45924aa09a16f2a6 - -Product = 542fb814f45924aa09a16f2a6 -A = 542fb814f45924aa09a16f2a6 -B = 1 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899f571f257fa81c36a868d80e7fa2bcbda68a72ca3e31db8892b94d073e006433dd7128b7bf677d2b411532e5662cdff66d657673d58e03d4a338bae1a5513296f91d4d2b5b680527a2e12318e422ec2b7f05ea4fd3ef4780576488211dad5733685a8f0e5d2ecda549a15eebb235495e70d26b194c994cf16d98d356218d08a34d1593d90bc0d3572df0e84bdb1705c6c5e64ea4895599bb21bf219abdd4329813ecc198e708cee199c22f749bdeb0c206690e8420883f6c0661e47b29969986a7a72996ef63234c31aa39b7be37995d2898063ef5c3b672c43afbc1a065dec2671ae87e17639cfcd3148145a8323e1e9dc4f9c9daf981dd6aba4e8be01344c2eda185b87 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899aa73af54a4e1825aa6714016da99d9e3d0c02eb139716db437705cd9efabf0123b0831689735f4e488f226e577d4688d30914dd50ed368939452af0a7a094c065c6718bd54f53a808585fc1728c3bd1e7c968d76c6dca32f95a8323bacad31cdd4aae544d4208262c40bcf726c2f26cf1e60341c3e1e0c8ed4542555b9bf00488680b737a245cc9b7817231f1f6f1e614cdf43ea281fb850ebbb9305b1aa441a45dfdaa1e98b9d79d9ca511be070bfa94d8cd3cc750607c93e1b451a14e32356bd48d77860b37fd2e714827e770a5648ce8579a00ba5cae034502a8b03ba754994d9e002130cfdee6bfdf078dc8f6767b927c964197664c8e32bd3d31bd461ce -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46feff82a92989bca577998c68ee619d9ea9972c6f139e97f5bdde635152830bedf302873508d2ed73badb82f9e32e1f4d12ea8c8b1059aa6d15f8e17d649bf41467903ab40d220d50570b5a263f637c0fcebc0ca29f8a81e2a01bf39bcb60cb9229dfd40618f706b941836bc5c291dec45ee9193e74d3a4cc5f73054ca56fd774a359f17a687268587393b76204a37cd48dcb09d3daed57a7e6d7d93a0ca3d6de8557fc4ddbfe9cb163fd10b7fe5f270dc57aa2fb88cdca2a3795015a17fd352d85fb688a38fa54883d0cab67aab08dbabd58d307c601f0f810014d78b101ff0bddb6d550b2480782406a905b9201e70ef6c1cb9765e91c10c8f5d240c -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e3812764dd3ebb7489e6e66058ca6ccf9c007f8c049eda369b2889cc411bca78d4f5b0e3a9e80243e87e112072b01922b595afdef4dd562e58ce917f11e69c8fe050de54fdb2d607d05f09afd6dd140e9d195b91d85269610a1e5d5036e8c9fea2d4fa693d80ecdc819b201c0aed27dfe0b92b4b3b9ecabb3b9548f0d27dc917ffb14308c4f970863e163f375852fcd9fb115640dc40534f8f51a7b903599117dca6c80924fa9a1aeb43cf5a9a3f67ae818b484feed51d7ef60b3656720891b13a983c02c281c8a0954f13b7bfaca844d2cb66de5c11ff507e39cf774c7c93b38e296a44f04e5ecf2819b57943fb0509774ddbcfeb -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899c7bedb01951b0f4fdb2c0fb64ad74707fda20027f4cee25da9b59be288d404cbd348f27600b87015d28f03cdf411f0e8c22deb9de5b3e0094f7820d78d59c90017cbd426297f8a32fb4b55b09362cf7cfb5910085acb24dbf618752b8b74c7e87f9cac44cb3b7486c43aa9b19a64d40a74eaf1de8b5f168b43d5750236aef753278c11294efd1adaddb6addb846f45fa55d7391898e8ec1c82bcf0008d9850c4c096571e8872e975dc8af1ba01bfbe8c8c27dc30cdaddd198936e4496579741a3a20e1b8e17241fe4abe5e98794e469180b742b2e1904940381f703f512885bda0340fe74e997ab269be00a3ca29bb937db2e06d8054e26dc13a5014ba51b175 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d88997cc097fe3f7ace3ffb0fcee52b45551165bb02354b229788b59128489879b1a0373e9862a17692464a2dfc5d09185a0f1c67d2359ba70b52b03f21c7b24feb96e25e1a2dc7f4723952bf203979f7c9e38790f881e2b35006157825555d4c867fce9ea0a3cc6f1c94ee308a68e33f64f286247465ffe854033e9c64f5d79d6d66dcb38ad03535b20376bf4c3cf26e07ef445192ba2baf08bb5286695a61ff6b5dc7aa1832017198d61a324b8c244572157323c7bb3a2fee226133e1b0e0f2ff067cf71fc24bf38d0e172f459b0cdf0707c5bc586390faacf428bfdeb04e850ee0c35f6807eb6ca8d3a473dcc2239541115a8b0d33ea33295ff8c13b2a -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46fc245133c3335163cce37555d36c555182e6d9a754b9aa9305c070083d0fe806d2c5eda4a976f749d6ef40515c425e6531a7f4d11926e49907b7a8a938205e0d6fefaacb145200cbe3deec686476bcdc1f6bb3535147ecb00818f2cd666ac0dd497f0fbc087bf05c6425b7752a02e2a695655d4310f04943a6178946a74dbe4688bd1eb3f1a166aef37e39f3e1d36b6d6d422ec0db264cae8d44869f57a92952bd74a026dd7cfc672803905f029c723487d4123a7520688fc9c68b2384be32e881f64d0ed7ae555bf00e5799740dd8c6accc40f3fe573f194f4848bb05aea8a5509f2dd10fce023093f1ef20267244a990d7ffd462f4e85a4 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e353744d86d954c06f3b84ef271b184ac9957a5f88b08b606fa6aa97afc4983a62f1e74aa3f242e14a3f4cf5ea415d1437818663556a29d117ea7df1cf1ee32f70d6d5566e25d53f892c42d3f92e481b622455fce36e400de09e2d435099695354ceee249c793b76b3c544d70164381e0420ef8b85609502afff9130729ba7851e0775dc5d8c606ba614e7607625fbc38908c88fac43e29ff9b8728f5809e63f20289246b5128016478437550a833c60edb0df43dd9a47654f2e4ef308d4a18cea57ea4b0c6d08add07f2e7adc427cf591c29dbd1f975432922e3f2b71c75e4d2557efccf626be7a0d522b658d420ae321 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7be8e75d54e5ba9405f671d624eaf8d7a115d0479f6fb773b940525fd46b69bc43c815b6bb1798813ca95790bc68032f0b9e73fc964a9922507d8aac25f859745939b828ef5ed326b226b555e5088f13531be16272a89ad41ae82c940935b5d8fe75dc520a230cc279a887bce01bae0a79356f044af13c6f4a5e53c00b2d03cfcbb0f93b26202441a207ec91576410ac1750e257906d945bfe9204b73fc417600bd191edcf2e3eb79acbf4f84dda372405b5e98397abe85c1593543cd7a5b17cb90e299f422f0ce107d86b56474e435dbbcbb5314fb579cd68d54777aa2d0ff9b6b96de62b4676edea5b09589698ed829cad22a52aaec732b79edf6af -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7739032d1f8bb68307f4adc912f1d9b83797606874d4f2c669fe0b263565c4898a07701585237aa444234719adb869c17142126611a9cbd6e689fabb2847bb9dc5e2dc89694621a7179df1fe7371deb9bbdf5fea0b271d86bcde2796a65331c27365fb97fa3647435c47e5c854a95718fa49072cc239d046ca0ac2bf453beb31070370d59483adb42b9876776e43fccb663887f1a999f625eb8e9c4cdd0a89099c42cdff06be29ad9ea66a957002925c9425a83c3e74096ca31324134f5d4a2b7d3b8d7fd8d72192049f79c670874f65201c068c5aac2008a7df4e5eba02d88be8ec23683513a9cffe06671a7c2fa5da7a7aa571914caba1e -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a808857c1bdb914ae0fec75b02d527263093a9d9b8a42289ec74dc73e0e46568a9e8ee117659597434048308c9b66fa7a539694285b1238a13d1163fbac33db147e5431af1c7aca5b1a118db4f6650ec6340491ef7a2d203b53e43d536639f980eb6e92a37bffb2149c5eb45d6718a9496f0784370674c1d29732b944a3c3885b68f0fd2a121f556dc82d1b942e7aabba780f087b9df359d86e2055248c3aabc568e93bba67d3ccca2c4240c876506d63bb05aad6fc4c77dfafff1731a46c6711bc60c4d23976268928bc63e1d133add0633c737bb508c81fa1ff3b452b49b992ebac930432d555ab8c62ae17357b1186e80689672f5a9f472c -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6783ab6c7314a43e85a92955a5fbfbffcd31ef0913ba93563dab2b7f54d90fa21ca827ad15b5b1fb399a303f94837536b2813cb563f793fb780e91f8333a2de7bb9f10efdb652a504d6f242e7c15362d3a6eb6e3d1a5abb03023dfe964656979765a14fe8fc36af3d785030ce549b92a91dcb8e2aa13f5b89eb8449b31961a0f77117c8cac79af95ee69f6594e557af7bb017cd885027ff7c0cb1d2f99d1ed5eacb788f645c25150e737cf1184b546bb2d55f2014a18015ffe647580df6fe4d528ce983309baeac0347ae8739e2b1f6d1a83e12e4dbfea1cd81b11b8628837432ad1906c70323529b718c8c6e398e1dfa73 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f225bca564b7e6561b56e0edbb3a7f5934f382b916ab38423221d656357ce0e9bf1e9b04c0678b9c555e8365a0f977c95bd8dca1fb2ad2268193531ca36cbe7f40da8e1afe097e451dc2931b323ce731c03cc027a92ed8ae105c5e9c1bd385e238d989fadbf3aa54c097a8666df8a66b7e2d016e65a2a632603f2c84290ccd7346ada28dff79dd06c7f7989689aca4f494b977f984650f91327ab9936cb92675932440f135e54e4abeecf255d7061482b4c8d91769e02fc94b8acc43325d69541903c3ef7a7a8a5bd19bf886506d42bcf0efcb6197a8d178d6a60516a5aa771ae238a342dc61df8c18c6ba1ed952d4e0c3409c14639 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f2210cc134828c520a58df29ae28863a158a044937809d7d84d2940efbdddb448c64da5f1f31977e7865fd5529eac82fee3e804064a6315936295f8cb26f0de16a47373f5e8365939e280a57dacb508166a583a630c75730c2fe54971e70a35e224e7a1a21e3bd8f417a47c4796d34148cae15068e19eec637bed8f32846dc5aa7e8f50599e840903a8129206fc384e0b4085f9f1e7e3bf2fc67b62b02566ce73cb4b22d471cde35b4f0cccb74283cdded5748d62286f7ea5c184c1308d520ecc7c7f1535b1132708298bf94c0967bc8f8541bb2f2b3c81f11e50f1d8cba4ce3746ad5f85e6bacbefada657c9b386b991b2 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c36ad2daaf856508e861c7f68a2611a215a93e3a15f68f72bb80a4fe9f4cfb6c7f91639179342c633db0f70c9dd849b5b5767908b27e61b812659dcd1a0613433f2c0940be49010886bb384d4676bd523f9827c1a48c7649fbfa73e872a5160796813956979b0f3fd3af728dd48f8a7348090300e41b181c8acae08a3b3106b61f90b0421803e6eba0d68e9bc93d3b659fd6316ba2815cb4b3b6a74f1f3fd24b0c07f619d995ac2beada44188eb72d371a6894f90087eaabe148755409bbff60114bcfefbfe2182e6dc4218d0da75af80059bbb14e848c2e60790fb35bf1cb685cbb133b2baf3f2faefcc3f69e34102def4 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 - -Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef9518c8ddd2bbd782e5f8cb06be77fc8d0c29f12d4ce67bb2478369710d003f0cb6f40a1341a5a5f2509d2d189084ea4346a44368a54f44c2be4c7b90c4d22976a31985927d0379b2e5d715a7e67eb3228943a07325a29316c695867e8f4ff676e00ffca0a6dfe8fe24652aef9e7f12616e8a54e367b90942f543a01dc7c1b8000ff991228ae83fe0131cfc235ba12ab2bdb33bd4ab0ba1b356bdbc6da4a70eed9fbf2c704e14ed6230eb5478dac0b02f4def1d8c076d1c0c0e2c4cdadb248de4acf961cee51dc41e545bd5a605a0860fb343c28ebf3f8814a9d5a7e0f3e9c93e742db76bc5671258d1da7758b41efead5 -A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 -B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad - - -# Quotient tests. -# -# These test vectors satisfy Quotient = A / B, rounded towards zero, and -# Remainder = A - B * Quotient. - -Quotient = 1 -Remainder = 0 -A = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c -B = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c - -Quotient = -2 -Remainder = 1 -A = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b -B = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d - -Quotient = -4 -Remainder = -2 -A = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536 -B = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d - -Quotient = 8 -Remainder = -3 -A = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b -B = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89 - -Quotient = 10 -Remainder = 4 -A = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4 -B = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b - -Quotient = -20 -Remainder = 5 -A = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805 -B = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40 - -Quotient = -40 -Remainder = -6 -A = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86 -B = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee - -Quotient = 80 -Remainder = -7 -A = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87 -B = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b - -Quotient = 100 -Remainder = 8 -A = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08 -B = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c - -Quotient = -200 -Remainder = 9 -A = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09 -B = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05 - -Quotient = -400 -Remainder = -a -A = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a -B = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6 - -Quotient = 800 -Remainder = -b -A = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b -B = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b - -Quotient = 1000 -Remainder = c -A = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c -B = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae - -Quotient = -2000 -Remainder = d -A = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d -B = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe - -Quotient = -4000 -Remainder = -e -A = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e -B = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8 - -Quotient = 8000 -Remainder = -f -A = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f -B = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1 - -Quotient = 10000 -Remainder = 10 -A = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010 -B = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2 - -Quotient = -20000 -Remainder = 11 -A = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011 -B = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e - -Quotient = -40000 -Remainder = -12 -A = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012 -B = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166 - -Quotient = 80000 -Remainder = -13 -A = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013 -B = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34 - -Quotient = 100000 -Remainder = 14 -A = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014 -B = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194 - -Quotient = -200000 -Remainder = 15 -A = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015 -B = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d - -Quotient = -400000 -Remainder = -16 -A = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608663e12291e9b0695449c1153800016 -B = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e - -Quotient = 800000 -Remainder = -17 -A = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017 -B = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec - -Quotient = 1000000 -Remainder = 18 -A = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018 -B = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd - -Quotient = -2000000 -Remainder = 19 -A = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019 -B = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5 - -Quotient = -4000000 -Remainder = -1a -A = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a -B = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722 - -Quotient = 8000000 -Remainder = -1b -A = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b -B = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a - -Quotient = 10000000 -Remainder = 1c -A = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c -B = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336 - -Quotient = -20000000 -Remainder = 1d -A = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d -B = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9 - -Quotient = -40000000 -Remainder = -1e -A = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e -B = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5 - -Quotient = 80000000 -Remainder = -1f -A = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f -B = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b - -Quotient = 100000000 -Remainder = 20 -A = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020 -B = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d - -Quotient = -200000000 -Remainder = 21 -A = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021 -B = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18 - -Quotient = -400000000 -Remainder = -22 -A = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022 -B = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab - -Quotient = 800000000 -Remainder = -23 -A = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023 -B = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed - -Quotient = 1000000000 -Remainder = 24 -A = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024 -B = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719 - -Quotient = -2000000000 -Remainder = 25 -A = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025 -B = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867 - -Quotient = -4000000000 -Remainder = -26 -A = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026 -B = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226 - -Quotient = 8000000000 -Remainder = -27 -A = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027 -B = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2 - -Quotient = 10000000000 -Remainder = 28 -A = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028 -B = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34 - -Quotient = -20000000000 -Remainder = 29 -A = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029 -B = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd - -Quotient = -40000000000 -Remainder = -2a -A = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a -B = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608 - -Quotient = 80000000000 -Remainder = -2b -A = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b -B = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12 - -Quotient = 100000000000 -Remainder = 2c -A = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c -B = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1 - -Quotient = -200000000000 -Remainder = 2d -A = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d -B = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1 - -Quotient = -400000000000 -Remainder = -2e -A = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e -B = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54 - -Quotient = 800000000000 -Remainder = -2f -A = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f -B = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb - -Quotient = 1000000000000 -Remainder = 30 -A = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030 -B = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7 - -Quotient = -2000000000000 -Remainder = 31 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13 - -Quotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346 -Remainder = -16e346b6a4297 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 30c77f3380ccf - -Quotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2 -Remainder = -16ebc86eb88339 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -197b6f6ad5b75c - -Quotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a -Remainder = 9bab19f12d81c3 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = eb90162ecae18b - -Quotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240 -Remainder = 1e4f817a2f52b71 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -546c109fa8a9d7b - -Quotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b -Remainder = -292e149300fdd1ad -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3246242094394c8c - -Quotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608 -Remainder = -dd3b3e32ddc79cb9 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1e928618913898b2f - -Quotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241 -Remainder = 16e021603d30dde2 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 948887c1634f4b08f - -Quotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253 -Remainder = 407ccb4f0b814dc5c5 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -4ad17434071e1ce664 - -Quotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293 -Remainder = -36f745b0f421d16db7 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3d71635bcc25183cdde - -Quotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82 -Remainder = -107334ab98e5099fec5f -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -198a54e35fa0cfa328a9 - -Quotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42 -Remainder = 170ebe9b83d4c43b79ab -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = f8e923a8bbc0242eafe3 - -Quotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d -Remainder = 4d404e93edb435dbd60af -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -52e36cee22274556059ea - -Quotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6 -Remainder = -3a2ea5f9d204dc31f21833 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3d3c79a115d9071b573d2d - -Quotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2 -Remainder = -17d02758f8fcadca911a95f -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1cc65a75211f2826c9d0811 - -Quotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac -Remainder = 5c95323f3b8861261dc31ed -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = c516e6e3fa6e3dc52cf5933 - -Quotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5 -Remainder = 1fc63797594c56160536faa9 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -462ee529b488d1db2b6c60e8 - -Quotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714 -Remainder = -15e79293d5e055f906381a899 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 32765b0a34c88864d39bedaae - -Quotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b -Remainder = -a158ccc7c055d64e7df3fbcf0 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -10c061a37f6cbd11bf0c327643 - -Quotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174 -Remainder = 21e766a0020ba429b330a325d5 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 9435cd2dc2a92c950bb9e69b83 - -Quotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d -Remainder = cafbe9caa1f83fd0dd3d5a6881 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -7924e4dcf8f96da61f54bf83870 - -Quotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497 -Remainder = -94ae72f78982ac1ff83f300cfe8 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3ad70d4b6b9b5f5b2eb65da67e1f - -Quotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155 -Remainder = -c83ac7582a02b47ee734e0f24dc5 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -14bbcff5423a260b21895327b18bc - -Quotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03 -Remainder = 8e07efb8ae4c9df39533042362081 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 93aebb72a81ba68e8881fd1a56a90 - -Quotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90 -Remainder = 794801d9d5770a60e312b99d6b9f91 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -7e408caf387a0ce9bbf4309c80755a - -Quotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68 -Remainder = -24227c242afedee2473c1a66a5cc29 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2f622c665af7f8126eabfd90df8e9c5 - -Quotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432 -Remainder = -dd290149e0e159f9ba6bb9f5a4b003d -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -14a7623d1d9dfc177e913d3119d0d30a - -Quotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb -Remainder = fb60aff5fdd2a2b794b0d973ac4d92a -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = d439da27b5e70342aa5cb365ece15665 - -Quotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515 -Remainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -50700f9c0da59482165a47a3eda2bf07a - -Quotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3 -Remainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 383c5a4f1767e83fc382ad4f1c7c2b7ddb - -Quotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437 -Remainder = -1035512a2717a89062d48f1bfd213333ed0 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1402b751a1e5f3fc46e22b43240d6ce9b27 - -Quotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe873570ab -Remainder = 72935d534bed5ba557b91ea023601f50b1d -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 9b4df766c608ff3efe5ea1f65cc850fa73c - -Quotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2 -Remainder = 249f6433af4e8e224eb570fd438197af62f3 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -6b382f812816c77d65c94c0c660b31a69b8f - -Quotient = -5f3ced1e42fbd3c6b2c6f1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8 -Remainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 31bc97372d17038fd842b72eaba2abb26df62 - -Quotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335 -Remainder = -a1493bcbf57a8480461d62796aa8f8541ece4 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9 - -Quotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c -Remainder = 273e33521f4d74840a96b3fffe169f79d32855 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = ba7746f4400f812919a3dc86b00642e1487691 - -Quotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f -Remainder = 456ebf56c636d54e37709b9e799e83b7a08cb93 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2 - -Quotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633 -Remainder = -4f62c678137df301c4bef216e6aa910104e76ff -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06 - -Quotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38 -Remainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1daecf01ec633610373b79e04c22cd7499012bc66 - -Quotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe -Remainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = a1598a12a84e9cba42ea0e200e88d4599c9f615fe - -Quotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7 -Remainder = 4610b2b1305220bc0de584dd3f87d90109012a8077 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6 - -Quotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516 -Remainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b - -Quotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2 -Remainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026 - -Quotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35 -Remainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = b1b959a7b3262d7f4dff488315903aeaffd982b726d7 - -Quotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada -Remainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f - -Quotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd -Remainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894 - -Quotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e -Remainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7 - -Quotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546 -Remainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d - -Quotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162 -Remainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a - -Quotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062 -Remainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831 - -Quotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf -Remainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017 - -Quotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec -Remainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0 - -Quotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9 -Remainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae - -Quotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00 -Remainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6 - -Quotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485 -Remainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd - -Quotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9 -Remainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b - -Quotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502 -Remainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7 - -Quotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb -Remainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04 - -Quotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab -Remainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80 - -Quotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532 -Remainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d - -Quotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83 -Remainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8 - -Quotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778 -Remainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b - -Quotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2 -Remainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9 - -Quotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012 -Remainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2 - -Quotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d -Remainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644 - -Quotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73 -Remainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97 - -Quotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb -Remainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82 - -Quotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a -Remainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff - -Quotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3 -Remainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046 - -Quotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1 -Remainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f - -Quotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2 -Remainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b - -Quotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413 -Remainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40 - -Quotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337 -Remainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575 - -Quotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508 -Remainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714 - -Quotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9 -Remainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d - -Quotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f -Remainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694 - -Quotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba -Remainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6 - -Quotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1 -Remainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb - -Quotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984 -Remainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235 - -Quotient = 180054f8c36833d44cab9dd61e6d89d28605c564af -Remainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018 - -Quotient = -31412e97045c19ec38951b0e3884c66d1d7479437 -Remainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3 - -Quotient = -8da1489ccf7203ecead94c67a5750884122b6e75 -Remainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467 - -Quotient = e635f8bdbf80e99723aa5718d3fade4e573be2c -Remainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed - -Quotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851 -Remainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f - -Quotient = -382586dfe93872abbe3a504fc62a8973913f96 -Remainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec8edea425 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52 - -Quotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38 -Remainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c - -Quotient = a9f7e5f235bae0e3e29393ac5c99d510b009 -Remainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba - -Quotient = 16de125df5936181981b4c2d0051a8b4d211 -Remainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040 - -Quotient = -268a52cd10ab4814268f66d9f44f71a98eb -Remainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85 - -Quotient = -8f051067ccb82b6a3dffedd0ff2ee97c46 -Remainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7 - -Quotient = 9b7ee4c499386f922432fcb1a453ee2ec -Remainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d - -Quotient = 23efb26228d7bcf281cd45f54572e2b3a -Remainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413 - -Quotient = -2cfcae0e922f2d884bfa0a3346dc9812 -Remainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072 - -Quotient = -4c0238ff3c18d4d58e543f020002802 -Remainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b - -Quotient = d41f9102a7785ce64f76b7d7b870b0 -Remainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d - -Quotient = 1616b432b3277e774aad92b0cf544c -Remainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79 - -Quotient = -320fd6a7375a42a3961362ae196d1 -Remainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb - -Quotient = -4bd06daed3f30345d269f51e4381 -Remainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5 - -Quotient = d6fd01a0c5b55fbe36e58bbe77b -Remainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642 -A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d - -Quotient = 18bd9a8f5678d28cefd955cf99d -Remainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa - -Quotient = -371239db55c79521206c9e60c0 -Remainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371 -A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 -B = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91 - -Quotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee -Remainder = 9f0e50ca76031b -A = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9 -B = 1b1313037e30f4d9 - -Quotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17 -Remainder = 93d7c547a9ba0a4a -A = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1 -B = 9ff8df899ee3b3f1 - -Quotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297 -Remainder = 6c97aace900389d0 -A = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48 -B = ec7123556af55a48 - -Quotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315 -Remainder = 2903c7cc2651bfa8 -A = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e -B = 4ea484a22ab0ad1e - -Quotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452 -Remainder = 4bdaf1f352e87aa5 -A = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb -B = 5d42fe145e66ffeb - -Quotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29 -Remainder = 55422f1caf4a9a00 -A = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0 -B = 908ae83784ee35c0 - -Quotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b873787206babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053 -Remainder = 124768541b600598 -A = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14 -B = 16d2c4a24099ca14 - -Quotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae -Remainder = 1ba15c46023500b9 -A = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243 -B = 40548136ce50f243 - -Quotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac -Remainder = 4cdfd72349c6110 -A = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0 -B = 3a74bba39671fcd0 - -Quotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88 -Remainder = 2950443357cd7477 -A = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f -B = 654686ff1368e96f - -Quotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5 -Remainder = 3013136f5f728b68 -A = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6 -B = fde3ee3bb61767d6 - -Quotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0 -Remainder = 1f130dd2ead0d35e -A = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de -B = 5b22f9d795df09de - -Quotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8 -Remainder = acb8702f0113e0c4 -A = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4 -B = b48a6b29025983a4 - -Quotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d -Remainder = 3d1890c5e1555d74 -A = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121 -B = 61c602477f849121 - -Quotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5 -Remainder = a93a0c5bd51004e4 -A = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf -B = ef1412873b2d8cbf - -Quotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75 -Remainder = 1ce3e5eb13ac7958 -A = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2 -B = b552d4f7eee617b2 - -Quotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c792e5125e322c27daa73301024080d73ba3491484b659 -Remainder = 3286bdce6dc3a828 -A = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691 -B = 85735e9b78002691 - -Quotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087 -Remainder = 135784870eb40c68 -A = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844 -B = 22d76a26aaf9b844 - -Quotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a -Remainder = 27b105741264f875 -A = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083 -B = 81a39fcadf738083 - -Quotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed -Remainder = 95f7434941f9d8 -A = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe -B = 1ddd0ab110b89fe - -Quotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8 -Remainder = 327cf78eed336523 -A = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb -B = 4ab08ad74f7be5cb - -Quotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95 -Remainder = 3b2f844440d7be00 -A = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680 -B = fa8e03d9ce6fc680 - -Quotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516 -Remainder = b620b7a3b752b78 -A = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468 -B = 115100eddabfb468 - -Quotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4 -Remainder = 53a0fcf5486c7a6f -A = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b -B = e340e9da9b305d3b - -Quotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d -Remainder = e7751deb047d98 -A = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6 -B = 542fcd4a46dcff6 - -Quotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0 -Remainder = 7c667ea307017c2 -A = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62 -B = 177907198f85cb62 - -Quotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb -Remainder = 429a380c9f8eeeba -A = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67 -B = 432376698f8d2f67 - -Quotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df -Remainder = 37924fea665f5c92 -A = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9 -B = 9f8220509f5106b9 - -Quotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88 -Remainder = de179463e3e91ad -A = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5 -B = 2c0323980d8841d5 - -Quotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3 -Remainder = 6bf69921db298b3e -A = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9 -B = 83a458f0372a57c9 - -Quotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539 -Remainder = 11c077beb8667d88 -A = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419 -B = 28d6ff55d5662419 - -Quotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca -Remainder = 1672a8aa119c3a1d -A = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b -B = 54df334dbfcfdd4b - -Quotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871 -Remainder = 44c3fdb374bc0c30 -A = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff2a3627d5b942300200c823d764b7a6c12d1c91b -B = 764b7a6c12d1c91b - -Quotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613 -Remainder = 2718de2dd0796f08 -A = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c -B = 51169b54c62b779c - -Quotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd -Remainder = abf5f6c8ab6ed4f4 -A = e2bf43c91cdbb244790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1 -B = b682c7ee6ab5f5f1 - -Quotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930 -Remainder = 6c3802d44dd4668f -A = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f -B = a71d9ad67ff2ff5f - -Quotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035 -Remainder = 660a35e1c1245910 -A = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac -B = 90593662c86fb5ac - -Quotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7 -Remainder = 2e4aeafa2ad76832 -A = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d -B = cafb4e30846cad1d - -Quotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a -Remainder = 8395953f744cfb31 -A = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967 -B = c473dc8dfed98967 - -Quotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26 -Remainder = b8ff45f31bdb58d8 -A = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08 -B = f9414ed2f4ba7e08 - -Quotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6 -Remainder = 7856ec047cec8dc -A = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14 -B = 2f4916d8b6201d14 - -Quotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157 -Remainder = 83649246ade8bb4 -A = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72 -B = 84eabd4ea553a72 - -Quotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811 -Remainder = 3daa032278ce53d0 -A = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba07b240886a6d5766cfb3ed0937a543 -B = 66cfb3ed0937a543 - -Quotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd -Remainder = c007da44faa80584 -A = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5 -B = c9e5b47ef8e63be5 - -Quotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd -Remainder = ef65a7789f54174 -A = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5 -B = 1a3d3a0050fa86f5 - -Quotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5 -Remainder = 398e30aff5bd284 -A = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787 -B = afd12b2c999e787 - -Quotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23 -Remainder = 378e44fdc7a5ec4c -A = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a -B = 7fae9be5dfd41a3a - -Quotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93 -Remainder = 39afe3275c01aae6 -A = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5 -B = a547d34edac1d3a5 - -Quotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874 -Remainder = 63e5ed36ff73a42 -A = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca -B = 459e52a6cfe4d9ca - -Quotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279 -Remainder = 19657d8ce516a138 -A = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557 -B = 1a41c1d517238557 - -Quotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573 -Remainder = 1bab5b03c372daee -A = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651 -B = add94e27f30ca651 - -Quotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc -Remainder = 18cd326996ccebc1 -A = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d -B = 2663ec896e1d6c6d - -Quotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d -Remainder = fe9b6b8ba7c30f8 -A = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6 -B = 6d80cf0c957788e6 - -Quotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7 -Remainder = 169e15b4d5aa180a -A = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89 -B = 2167f9ce5e233d89 - -Quotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2 -Remainder = da381ae5c97a506 -A = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a -B = 1274c5b4d821469a - -Quotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720 -Remainder = c41f9e7bf20b376c -A = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec -B = dae90967d9ab48ec - -Quotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0 -Remainder = 8e435da582e59809 -A = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739 -B = 904674f2ea3ff739 - -Quotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771 -Remainder = 14135c686d2e9f70 -A = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f -B = ea8f939c922b1e7f - -Quotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763 -Remainder = 230307c44cd55896 -A = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545 -B = 2633a0d905017545 - -Quotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7bfabb2c -Remainder = 40f5346f8775e20 -A = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0 -B = e3d7df32c15b75a0 - -Quotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81 -Remainder = 2e495a881876da00 -A = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c -B = 94331c1cfb1e941c - -Quotient = 5dce24b7a16d847b0c43cf365ea20bee9679fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6 -Remainder = d8ead1ae3126aded -A = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47 -B = f4dd6e462bbc8f47 - -Quotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a -Remainder = 57131776937c5df9 -A = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f -B = 793dc0907d9aa30f - -Quotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9 -Remainder = 5065b726dc6b3758 -A = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb -B = cec4f0466c1c47cb - -Quotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba -Remainder = 67f48d3584cf4fe5 -A = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73 -B = 73a6a288012c7c73 - -Quotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf -Remainder = a5356d04b64ee12 -A = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1 -B = 22664967d67dd5f1 - -Quotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329 -Remainder = a34980d5046e2ed0 -A = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e -B = cffee795d695f82e - -Quotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53 -Remainder = 36052bba2867f5f4 -A = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96 -B = c1bd491446a50b96 - -Quotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0 -Remainder = dc8c7d087bf24b0 -A = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0 -B = a26129615a2432b0 - -Quotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f -Remainder = 75c703f654ad630a -A = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5 -B = a1cc13a7108327f5 - -Quotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65 -Remainder = 453a3d59303ec3c -A = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19 -B = 84afe4979b5bb19 - -Quotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287 -Remainder = 5904e71034e3a02 -A = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95 -B = 70a6a40ab6c41d95 - -Quotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a -Remainder = 33431c3df719f946 -A = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea -B = dec06757dbe61aea - -Quotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696 -Remainder = 31540f5e05e8b4df -A = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d -B = aba050665c090b5d - -Quotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5 -Remainder = 4ed4f2d12e4f4ba0 -A = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8 -B = e0adf6f71df7eef8 - -Quotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af -Remainder = 7e5661558c345eea -A = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d -B = de41a7dfc5c3576d - -Quotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897 -Remainder = 29e9c1627537e5a4 -A = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca -B = 4671868b0526aeca - -Quotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87 -Remainder = 664d57c57d4952e -A = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3 -B = 4bef9c961e2958e3 - -Quotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4 -Remainder = 5ba8f49e0ca36ab4 -A = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44 -B = ff6d0277fe642f44 - -Quotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25 -Remainder = 1ef621737e81780 -A = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920 -B = 4d8ea8637e50920 - -Quotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f -Remainder = 9ae7de3edb6c7edc -A = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e -B = c6b738c0bb282c3e - -Quotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477 -Remainder = 3ef5c6ee67e6f5da -A = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09 -B = 77822f27d1e3cb09 - -Quotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a -Remainder = 7cf920ba2897f714 -A = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc -B = ae0c1fe238c726cc - -Quotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343 -Remainder = 2689c40a54df34bc -A = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662 -B = f05dc6676e51c662 - -Quotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958 -Remainder = 53da0b15ac079ccd -A = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85 -B = b54edbf4bbc9af85 - -Quotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328 -Remainder = 3d051148ec43a72 -A = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2 -B = 3ed5a2e7edaeec2 - -Quotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8 -Remainder = 1a1f4aeb882d7546 -A = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116 -B = 9196fe73d0e46116 - -Quotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee -Remainder = 4578107045b9cb81 -A = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b -B = c3acc56b72ddbe9b - -Quotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce -Remainder = 1b9861df51429a6 -A = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2 -B = 9672452618da9c2 - -Quotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8 -Remainder = 2525d52ecdec8814 -A = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4 -B = 5fe5cdbd30726df4 - -Quotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7 -Remainder = 14781a368471ecae -A = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b -B = 198221221724cc3b - -Quotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9 -Remainder = 6c754d5c167e1228 -A = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f -B = 7137cf7eabda038f - -Quotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee -Remainder = b14595005716bfe3 -A = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1 -B = c81ef51b30288cf1 - -Quotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464 -Remainder = 10fae644af084f8a -A = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092 -B = 1e1f583ae834b092 - -Quotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532 -Remainder = baff11e6961c72e3 -A = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad -B = d4929335a1623bad - -Quotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028 -Remainder = 29e33e0c2a515780 -A = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380 -B = 6199279c25d4e380 - -Quotient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90 -Remainder = 11d8f2f6d4c1f55c -A = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c -B = 651f629975faf91c - -Quotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589 -Remainder = 1ee700ffb0ea02d8 -A = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35 -B = 3bd460ee19887d35 - -Quotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172 -Remainder = 74785b6874d8fa37 -A = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9 -B = 9b9f4f097027ddd9 - -Quotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88 -Remainder = 9a836be71a24e72e -A = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e -B = bbc9a0bf08879b1e - -Quotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c -Remainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171 - -Quotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446 -Remainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd - -Quotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06 -Remainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450 - -Quotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80 -Remainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02 - -Quotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08 -Remainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40 - -Quotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a -Remainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485 - -Quotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643 -Remainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4 - -Quotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777 -Remainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1 - -Quotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4 -Remainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95 - -Quotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229 -Remainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492 - -Quotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845 -Remainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26 - -Quotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122 -Remainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15 - -Quotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62 -Remainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020 - -Quotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1 -Remainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e - -Quotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d -Remainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d - -Quotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596 -Remainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a - -Quotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc -Remainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a - -Quotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395 -Remainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571 - -Quotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912 -Remainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc4936d273 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c - -Quotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286 -Remainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08 - -Quotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8 -Remainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313 - -Quotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b -Remainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886bbcb851448dc1ed4cd66d6598 - -Quotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd -Remainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8 - -Quotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2 -Remainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6 - -Quotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4 -Remainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71 - -Quotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d -Remainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9 - -Quotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02 -Remainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5 - -Quotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6 -Remainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253 - -Quotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602 -Remainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410ddd1e0da - -Quotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb -Remainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041 - -Quotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780 -Remainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9 - -Quotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef -Remainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8 - -Quotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6 -Remainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39 - -Quotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c -Remainder = -24f3431858d5aee412443feab243b465b849f5dc97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d - -Quotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f -Remainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c - -Quotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9 -Remainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751 - -Quotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b -Remainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8 - -Quotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287 -Remainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5 - -Quotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e -Remainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5 - -Quotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581 -Remainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396f5db2d979d272798ed30efa15d52289d0c72f42582ea56f - -Quotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9 -Remainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1 - -Quotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e -Remainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c - -Quotient = 4213d04b9f0b30026bd355404bee887b22b2cf9 -Remainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08 - -Quotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8 -Remainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad584636352913b7429b99ecfbe - -Quotient = -448c4922b7a7d5e1efec2c3f41d0264b76 -Remainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514 - -Quotient = 152474a1a76700598c18d9301866ec00 -Remainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da - -Quotient = 5665f53d5a7405c83a5ff382ec376 -Remainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7 - -Quotient = -eeda035247bb13860f228d8f2c -Remainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4 - -Quotient = -5b37eb0c3e3f8f8d9ac6f4e4 -Remainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065 - -Quotient = 1c7ac058af2e7bfbda9484 -Remainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e - -Quotient = 472df5f4393f33cc382 -Remainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc - -Quotient = -12b4e74d76bd306d9 -Remainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec61962e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7 - -Quotient = -548c97fd02eca7 -Remainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1 - -Quotient = 14622572f311 -Remainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320 - -Quotient = 5cdbb03ee -Remainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a - -Quotient = -f16da1 -Remainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737 -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374 - -Quotient = -71bc -Remainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187 -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7 - -Quotient = 10 -Remainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c9596207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8ed469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -eced809145e696ceaa0ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13 - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b - -Quotient = 0 -Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb944181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0 - -Quotient = 0 -Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b -B = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449 - -Quotient = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91 -Remainder = 0 -A = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91 -B = 1 - -Quotient = 3b5c3007d9c49498ff8437b6f0014d146b63c20b6c5b91febee47211f42109f6081204b21a8af99e9ab2b5165d536344fec16bd691fb3883ee7335e12d69afc8bff57641ac7a4cee350209a08301553854873da153ccf056427a2415e3ce72972afb5883393806ec2388169b513674c0935f67ec79c89dfc4bdc6f9cf877a10f -Remainder = 1 -A = 76b8600fb3892931ff086f6de0029a28d6c78416d8b723fd7dc8e423e84213ec102409643515f33d35656a2cbaa6c689fd82d7ad23f67107dce66bc25ad35f917feaec8358f499dc6a0413410602aa70a90e7b42a799e0ac84f4482bc79ce52e55f6b10672700dd847102d36a26ce98126becfd8f3913bf897b8df39f0ef421f -B = 2 - -Quotient = 4f54d7e1ac8816945de169e9a2c497ff240e313c2b7d58612c8175e277f032cd4ee5dd640605028c59395a1eb4aa00772a8187a0568b93919aa5b95b0462e5bd31c1e507170039306e1b2f4f75f63ab0a3add0eb01217df61a74765fc37e941dedf10fe142ae317573a4f0c8ce408c213749a12f56add5d100d0973b019350a1 -Remainder = 0 -A = edfe87a5059843bd19a43dbce84dc7fd6c2a93b482780923858461a767d09867ecb1982c120f07a50bac0e5c1dfe01657f8496e103a2bab4cff12c110d28b1379545af154500ab914a518dee61e2b011eb0972c1036479e24f5d631f4a7bbc59c9d32fa3c80a94605aeed25a6ac1a463a5dce38e040981730271c5b104b9f1e3 -B = 3 - -Quotient = 2922aed641a12010a3099f3c03f708962e2791dd860e65440acf3b982a4041804dcbedf45deefdae5130df96902056f8b2942069fc17bfb29f46a096a36e842ecb30d0800da13b6572c5b3a095038baa3107ca28094063571b517f7cda3659b63099c57a40d7dd2893b92d60b1fe2fb4594fc3a19b7d7957921437556db0e353 -Remainder = 0 -A = a48abb59068480428c267cf00fdc2258b89e4776183995102b3cee60a9010601372fb7d177bbf6b944c37e5a40815be2ca5081a7f05efeca7d1a825a8dba10bb2cc342003684ed95cb16ce82540e2ea8c41f28a025018d5c6d45fdf368d966d8c26715e9035f74a24ee4b582c7f8bed1653f0e866df5e55e4850dd55b6c38d4c -B = 4 - -Quotient = 216236f9c82fe6f1c021853a21fde3e21e6de355cf193f16b403edf59a6a6ebeedb266d4c7a6683f5f6a434c7129f582d2a5a852269d66d2eda45a1e2f25286c665f6641ff8b55913603064cc7a157f755e515a426873e7bc6b9d699d1f316759c4505a67b7a025598f9d1af6ebff2ed0fe393db829f768178c1080ea004e4f4 -Remainder = 4 -A = a6eb12e0e8ef82b8c0a79a22a9f5736a982570ad0b7e3b718413a5cc041429baa47c0227e640093cdd13507e35d1cb8e1d3c499ac113021ea435c296ebb9ca1dffdcff49fdb8abd60e0f1f7fe626b7d4ad796c34c0a4386ae1a1310119bf704c0d591c4069620babfce1186d29bfbea14f71e3498d1d50875bc52849201878c8 -B = 5 - -Quotient = b9fbd48d54b9b70374425aabe16d6a8a819944a43185c2fd07073e20358510ac3de13cff33fe6220ba952d88b2e0f3f7eddb8daf27462b476b5e127e72ea60fd56cc54bf14d2d92765d5d21652d8e16aad4423cd9789515d59aaa02d42d3e957dde50ed1c9a69e2295144a643a8104660ccaafba250854e7f28a686935738 -Remainder = b6d -A = 8ec1cca67b888cfa26bcee98ee887c47507a253008032c2b37e50f2fb914a34c357f6351e368c2521f3781736d4dab43ce130640f1a55c3851e9b5320f34e772751fd70cab7bd7aebdaa9fc22297790661fecd7b4ed0e6f4275377f2bdcba89bf1d251e0074864618b6e1319eee807e054d193e2616ce52c09ab3d24c187332d -B = c48 - -Quotient = 5157f1bb35866dcaa3abb4abb73580d43d03536c3c7960aa95910db60f4d1ffada96c7d89dfcb290bd8c5bb154872e2dd6e50602fafb435193575a4cf253e4d22dbecf11f8f97408dcc83d6e591b1d5daa59825ed8cb08cf562fc50d62cd666b9720055dc11cd42278258e5bd8021aada0b39a340b6c5585bb6c9c84a9ff8 -Remainder = 3d2 -A = 469e999cc737f4d12c97d19a13ce331841f8232cb780602c18592e274ec8b503884566ffcf28a206288f1a9ab3a25bd74bd054781664a331922a96254d6155677836e7455a6690fcb1acd7550cdbca3e9124356ed7b644660092f8d2df06d22ae7f38ca8a4e7472aecce9ad73c47d3a93cc3ec9faeeacd3f59f70ae22c9614b2 -B = de4 - -Quotient = 3566586b9f864dac5ed132d95d4ac6d1fd5ef6a2c67fee39ece89d615b4c681284b4dd5e27b90c6270b85b150fa2a63440e470b0f937b0eb83432be03eaeb37a0927a9c76b07fe40e3509c93a7b660b77ebbec9bca235d387a9a80a6432c77ddd8190c0ae8ea1d72331d5f4985467755b27573bf23109a01c02975e07daf3 -Remainder = 2a2f -A = 9d68d0643f1d44b63aff6a83fca08c52bf800dc59260db9b7ff930eb1bc01a47966fa509abd7da21ad856f7cf536d32dc7c962afaca1c9e43bcde135e4c5b9cd9b3c8ad775e06fda06117f8cc03ffad8e5f4b456baba7eaa9c67af7a19c2f4d65120d51fa8d31d0cc1ec7502187cd784fd2d78514cbccff969123718de7cb30d -B = 2f2a - -Quotient = e36f2fbcfe134fdf3137539006d6d9c03b8774883211f759b0258bb09585440d6ff440e799ffc434a2fc529773a455db9abf72d8c55903d9ae5abd5b2b5e9ccf23c015882cab8565c654532d9407a188a40d0cb026fb3bfda428d4bdfc14bec72b5cbd59540c42598f1371e9e61a86e6b4c957ea331baca764b771212495 -Remainder = 6eeb -A = b669c646d1bbd7389fc642da6d2c440788fec53bd8409ee604222d08b1fc31b3d301e42a8168be0ac394e5f20eb51708b11e7b09d25043f19032310d6649d33eb6c9688506ebd56ebfd0d3f277511ad3caaba3642c53d27e8fb0eb991c75577f584c52b1ec44111b3a9bf5863c18d8a07b91d8ae0bdbbb3b05ec8d11380a9c3a -B = cd53 - -Quotient = a891f8a42093cd86d76cb11cf734a65dccd5b4d350328a7d2f2be76e2edb6b7dcf4c5e1915c65764c77ae73fd6e42eb8451253507e16f2e25ef80e5d1f27ea18dc976a9b12147ecb643b2ab060163307df818127b2e40dcea95a109d7841edc9288190587ac48ba9687ccd0d014d531bcf66ec401bbcbed777325fd1060c -Remainder = 6e66 -A = 9077614b809f4b22707cf965a7e79217e13ca2011cf9e069babe2b4d908e318608f91da095864403b168d750d904fbfe11c9ed80ba9f60d57a8dac2754647002a0848fefb7a5aa8e04fd28dcb9c8e669de4ef794eab2abc93d68dcbf4400d86de603d199a3ee93050638fca7063ea99a9465dfb60d0568b99dfa1ed79da41522 -B = db65 - -Quotient = 1b16f2e2ef7709fe285ede17beb7d9932caae2dd5fa0eebb541770ca1d53da4428820986cb7e79026eb8bc261eceb200b7696a4b90f675ea9af8389c60dde4d564c8adeba6b117edd05469d285670c0bc78afbc3ad047828cdc611fbcab403c0cb79665d6285b43fa04b77f0309bc7f74136778f8ec16899df040db34f4751 -Remainder = 68 -A = e91e7c26e2b562fe2568613656381d5581628e4705ede6660ca5b79b4a609748889707faf9295b57eecfbb1c0b1cb5cc2a5825b84878e8b9e3960f29b59580385a4af0aae375f8eb7fc66aa6a1fdc4a95e29048ce1e5760722c77cc1c95b1c4c16fdb3e59ed4961f8869711ff24c91ccbe2fb6e0617a5f242227e1e60b3ab673 -B = 89b - -Quotient = 37370826964cbd65a48598e73b519db77df6f520bcead8c0446f1288ac189403adb65603b2a68ab3cc232b667232f2e206b5bee0fd48fea8b3ff515f452b5ef0cac591b6ac8c8c509c59c6d3d4e3fa03e22578ff71f1c72ddad9d637ae0497ef0e2a4b261a72cb784f8283eb7e82b6a05aff0a2f61da4780e4e7cfcc4807 -Remainder = 3a29 -A = 16ad5614f9129c7952c5ee8057d8d12a70780144e616e3ed571b2e38a9ce482a52c436eb9ccb6e4f400321bf1f3ef4c8dc897cd91f868eb7018d084784c4840a1d078c8c6a75e950cb76cf2cd81b719ac04d2be5c9a830b1d1361f7ef6345af66a6d56c53234cd98f587b6762401674973df670addcc4a05ec0344d402453a25 -B = 6924 - -Quotient = 9bb00032a27651eac898b8a567e19ed6448669c8514b5659c4b1103069d9289c6c00b38b44160e0efb2c635b7a64c8296c1c1b5c2cdb285b749e614eb9247c6defa06f8dac077b1e1c26059847de56a1a5ddf7fb1254662624f2ffe6edc48f3b318ffdc7ba2a81ef2d963b934120f58afba2b107a215b58f324e2d923f75 -Remainder = c03 -A = 74524695d4dc11023ff202ed2d165551ace0c126f7a51ebb3ff21ecd7c058cd4a6bda2254c55ce6ef76fd11807f92e80dad31bfd254f9a2e1ca89949f65a1fab8f6a4978c488f2dfa61df46c1faa418ff45250d82958e8f5fdd9426c44a3bcd7c4eeca276abae466787a5ff0ec482514e03434ee68fce24fc620e31265c3718c -B = bf45 - -Quotient = cecbbc189fb1d44c5511f742b63207bcba9c78d09342cdcd12a1b1bc3a95466e7fdd8c59329a9b18f7c793c43f08d52339a8202dfa3a9fa86a2426bf5a94e006849b45cbe9a5dd74ca43e2acdf1051be23359624e8f146b203864d03651d98165b783398a59b446314c9b01f79b1139c30df348b14ffd25b22d9d90866b -Remainder = b265 -A = c3721776b9b5fea8608aa9d381d80ac603d27043089dac276832e7cde8d222ffe142f06c314e94c3b9f6148d029f260879b700e1d435b5f318c8c8caebe92236c9060c183783edec2845e6d4e816197196a0de3644544093b04ac6fb4c69d7446954fbabadcc5dc3309e9a3fcf70368ba7448455cec9c3dc78512a19ebb04f6 -B = f1f3 - -Quotient = 4090a2c78cf8711388347149926610d624543765c9667567ad86eef9f9777f53c0cc0f9a989d9195a5e0da875c03e5c74614f95b8752f9ab89fa61c264b8b5d3e02b043fd539d36dbc6782f45a555d1f36751603d5c3423c7f27b3b5dcb91ddc81bf1563dd3abb0970de6109d76da1f4f9d5208ade2b131fc407c5b169c -Remainder = 2a87 -A = 129d32cde3c648298f8e8e8123f2e8ee9cad3f909a5647ed09e91cb99549d177575f54a7a3ebbd4ed2b89940722927a8b9565ffbc13d8df6d2616d5b1925b87bbb6aa6d39f2b11d26d071fa30e63083ed5a5357ecf0ab1028cf0a43178486679e86fe4dcb071c49832c83c9de4599d672e5ecfc7c9190f1d7275f5a0abed80f -B = 49ce - -Quotient = 43340591e68e228fb03e44a5f2046afe41a3d7ca99ea9ff1a445d75f95f2ff7f55fb914791613b5db7369121d416a5f92f834b0b5e9280b49a9e66be4c682019881e6e8883d7a923d2a5d309b9d265b01d6b8a4ee07f7552934f2de002cf961fd93f33641aaaccc7c367fb6798436eecc9bb22357087a9c482131e1065eb -Remainder = 6332 -A = 42e75e3b8c23287044593d9fa4bc5df437a0f8e876d3105334a677b5ecebf653e8bd7e55dbbf6876005196e44980bc23df491949c59aa199cc9e0a111b58f954eaff2bd270214726e5c98de502ba71b42089fba51e8763f0c11f278faf4c61589ceb674d7c7c61f62f8d18ccd619c20243a508c26b934f06ddeec0421b372326 -B = fedc - -Quotient = 688c7120765f8ef7363f7ae1bb65bc568b16e32c59762f59f34a57f08839d19019313dfcc9e96d7415766bc0aa032b19ecea72c249bffa0538bb1ac06401657df2fbea5c46b18d8a79cee4029e5972d8361fb7e6c2c537673aecd727dbc758a3bca1a001765a216e9985eb7eea67ae979f3803f14587507ba0f8fa29957 -Remainder = 9970 -A = 688c0894053f1897a74844a2408400f0cec058157649d5e3c3f064a63049495647a124cb8beca38aa802564a3e428116c1d085d7d6fdb0453eb5e2054941017c8d7df7605c5546d8ec446a33ba56d47ec34781c70ade74a203859c3b049f7cdc63fde35fd658ab14781751f8fee8c42ff0a064b941960af4507d59309b50019 -B = ffff - - -# ModMul tests. -# -# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M. - -ModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277 -A = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b -B = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65 -A = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763 -B = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92 -A = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942 -B = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910 -A = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01 -B = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c -A = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc -B = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc -A = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f -B = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8 -A = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494 -B = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53 -A = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f -B = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3 -A = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3 -B = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c -A = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b -B = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f5303a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398 -A = -442c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9 -B = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b -A = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf -B = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c -A = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d -B = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c -A = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60 -B = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504 -A = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78 -B = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024 -A = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa -B = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8 -A = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c -B = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea -A = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1 -B = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5a99c8a6afaa97d8e7d84f4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c -A = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7 -B = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8 -A = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3df11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048 -B = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce73126508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8 -A = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d -B = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0 -A = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c -B = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450 -A = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c -B = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8 -A = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c -B = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c -A = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3 -B = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4 -A = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928 -B = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207 -A = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223 -B = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676 -A = -1bf5ae15f24c7c14eb59605136a3f679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52 -B = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c1d04b831b712d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba -A = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf -B = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd64bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073ff1a506d7460c57d54e10dc2991c028606a -A = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de -B = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed -A = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f -B = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc -A = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414 -B = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c -A = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65 -B = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c -A = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad -B = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130 -A = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c -B = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768 -A = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39 -B = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e595c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f -A = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9 -B = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e -A = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb150408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845 -B = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227 -A = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45 -B = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c -A = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382 -B = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad -A = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7 -B = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda -A = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf -B = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec -A = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8 -B = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5 -A = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf -B = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4 -A = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4 -B = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a -A = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822 -B = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26dfdb -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0 -A = -63bc10b8fbcb391dea305fe61b404d3bebd035514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b -B = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d -A = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb -B = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702 -A = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91 -B = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c -A = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643 -B = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18 -A = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33 -B = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a -A = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b -B = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6 -A = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6 -B = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121dae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b6243ffbb7a979bf9664cc7ec41e75f267d58a7127 -A = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625 -B = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db69f781e169 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0 -A = -75f903ed9bb0b6db8e3be16e797258f6c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164 -B = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5 -A = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb -B = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa -A = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296 -B = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2 -A = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f -B = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe -A = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a -B = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08 -A = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec -B = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886 -A = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f -B = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b -A = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3 -B = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820 -A = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e -B = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba -A = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed -B = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1 -A = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579 -B = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c -A = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4 -B = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754 -A = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00 -B = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a -A = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995 -B = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230 -A = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e -B = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35 -A = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891 -B = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955 -A = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9 -B = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8 -A = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a -B = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39 -A = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983 -B = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574 -A = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0 -B = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c -A = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc -B = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 76c31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c -A = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2 -B = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df502a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 5b704b3181e5d0494937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04 -A = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023 -B = 160120a35ae3edac3edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93 -A = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15 -B = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c -A = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e -B = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9 -A = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b -B = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014 -A = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410 -B = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90 -A = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8 -B = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409 -A = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9 -B = 44c336d7739118340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8 -A = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924 -B = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea -A = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19 -B = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea -A = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996 -B = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d -A = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9 -B = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2 -A = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3 -B = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c -A = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e -B = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8cddb5914e7657573804e63dc7b216b1a9aa175c -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168 -A = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c -B = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f19a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54 -A = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4 -B = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298 -A = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa -B = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227 -A = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1 -B = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179 -A = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655 -B = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c -A = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15 -B = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897 -A = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1 -B = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4 -A = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2 -B = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a20f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648 -A = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4 -B = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a -A = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6 -B = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c -A = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6 -B = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94 -M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 - -ModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c -A = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905 -B = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d -A = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5 -B = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf -A = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66 -B = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21 -A = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393 -B = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a -A = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152 -B = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d -A = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e -B = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d -A = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c -B = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4 -A = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232 -B = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761 -A = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a -B = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327 -A = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82 -B = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010 -A = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61 -B = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89 -A = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1 -B = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14 -A = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f -B = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe -A = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9 -B = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5 -A = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df -B = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f -A = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760 -B = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a -A = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207 -B = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd -A = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6 -B = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde -A = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454 -B = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8 -A = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615 -B = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a -A = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013 -B = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9 -A = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d -B = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f -A = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226 -B = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24 -A = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d3486949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a -B = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0 -A = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e -B = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23 -A = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928 -B = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9 -A = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3 -B = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f -A = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0 -B = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65 -A = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807 -B = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308 -A = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983 -B = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa -A = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7 -B = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f -A = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72 -B = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173 -A = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df -B = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848 -A = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40 -B = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146 -A = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa -B = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02 -A = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c -B = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c -A = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7 -B = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343 -A = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd -B = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35 -A = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d -B = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a -A = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50 -B = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff -A = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a -B = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7 -A = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967 -B = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453 -A = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8 -B = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c -A = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745 -B = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149 -A = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261 -B = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656 -A = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228 -B = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e -A = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d -B = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e -A = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5 -B = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb -A = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99 -B = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a -A = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8 -B = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc -A = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984 -B = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc -A = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275 -B = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472 -A = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6 -B = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d -A = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1 -B = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd -A = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1 -B = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f -A = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e -B = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad -A = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334 -B = 1311b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d -A = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e -B = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4da9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca -A = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431 -B = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f -A = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864 -B = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d -A = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5 -B = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233 -A = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244 -B = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e -A = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65 -B = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135 -A = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9 -B = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c -A = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1 -B = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb -A = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f -B = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511 -A = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5 -B = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79 -A = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15 -B = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e -A = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db -B = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b -A = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840 -B = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d -A = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c -B = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec -A = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b0702b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf -B = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc -A = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e413e23285066eab8e126c320bb6130a91d67ef26d4dabd -B = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158 -A = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d -B = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745 -A = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7 -B = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950 -A = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d -B = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a -A = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b -B = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82 -A = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5 -B = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3 -A = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7 -B = 78ec7dbfa2b28e268619ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861 -A = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3 -B = -2023c544b6cdd8d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c -A = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be -B = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce -A = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a -B = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68 -A = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783 -B = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866 -A = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91 -B = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069 -A = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933 -B = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901 -A = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8 -B = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b -A = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec -B = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3 -A = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e -B = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf -A = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830 -B = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0 -A = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7 -B = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d -A = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437 -B = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493 -A = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6 -B = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280 -A = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628 -B = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8 -A = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82 -B = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297 -A = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6 -B = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d -A = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8 -B = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2 -A = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf -B = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17 -A = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c -B = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8 -A = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8 -B = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b -A = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751ceab01cf9e49015d42371fac30d48ef5853b6894ca83 -B = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70 -M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb - -ModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02 -A = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb -B = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888 -A = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78 -B = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1 -A = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f -B = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e -A = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a -B = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a -A = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493 -B = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0 -A = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c -B = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096 -A = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e -B = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77 -A = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31 -B = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f -A = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83 -B = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0 -A = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357 -B = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb475ee818199a390b6 -A = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae -B = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca -A = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6 -B = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe -A = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32 -B = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0 -A = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92 -B = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc -A = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756 -B = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1 -A = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf -B = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6 -A = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a -B = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f -A = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87 -B = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928 -A = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58 -B = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304 -A = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5 -B = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a1b1b2d33cb610f1b398e03f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a -A = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6 -B = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3 -A = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7 -B = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d -A = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35 -B = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882 -A = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce -B = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2 -A = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a -B = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a -A = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13 -B = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1 -A = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db -B = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696 -A = -19d3e6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7 -B = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48 -A = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214 -B = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05ed24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2 -A = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da -B = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e -A = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda -B = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813 -A = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107 -B = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60 -A = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416 -B = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77 -A = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95 -B = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150 -A = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8 -B = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da -A = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae -B = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a9621b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de -A = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda -B = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210 -A = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20 -B = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80 -A = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf -B = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab -A = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d -B = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80 -A = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4 -B = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba -A = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b -B = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94 -A = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b -B = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a -A = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b -B = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8 -A = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa -B = 1fc4dc77f4a18d4406a4ba536e500aff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819 -A = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197 -B = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095c6a509d0fa15dcf45de8d0e901 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200 -A = -464cb16fdd395e32fdc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc -B = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08 -A = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670 -B = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208 -A = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019 -B = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6 -A = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d -B = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067 -A = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453 -B = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5 -A = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93 -B = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c -A = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7 -B = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca -A = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589 -B = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b2b63f84fb0023c81d031773f3652cd6 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8 -A = -78a99d206b4f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e -B = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31 -A = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f -B = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e -A = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7 -B = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28 -A = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756 -B = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6 -A = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29 -B = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f -A = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf -B = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec -A = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905 -B = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5 -A = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1 -B = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8 -A = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990 -B = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec -A = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1 -B = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a -A = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d -B = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5 -A = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3 -B = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264 -A = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d -B = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f -A = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b -B = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af -A = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b -B = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590 -A = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8 -B = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef -A = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f -B = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28 -A = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c -B = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4 -A = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814 -B = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0 -A = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4 -B = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08 -A = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73 -B = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58 -A = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50 -B = -26ea5079ba7ed137a14d00d413d6f818e911cc183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a -A = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae -B = 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8 -A = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9 -B = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1 -A = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131 -B = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e -A = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145 -B = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380 -A = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214 -B = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac -A = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205 -B = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4 -A = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2de4 -B = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4 -A = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda745658bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373 -B = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846 -A = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f -B = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04 -A = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a -B = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074 -A = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc -B = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590 -A = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4 -B = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb -A = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353 -B = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e6526be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11 -A = 1112d291463b28ef45e879412e6607a3e20d50dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1 -B = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c4487d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618 -A = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380 -B = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e -A = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa -B = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4 -A = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d -B = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1 -A = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375 -B = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229 -A = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f -B = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282 -A = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a812262309094ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e -B = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc -A = 60463fae1e9354559160d55a453c12d75775a53d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714 -B = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bcfb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420 -A = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8 -B = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7 -A = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47 -B = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce -A = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772 -B = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47 -M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 - -ModMul = 9ea62ef634 -A = 55cc58c9d8 -B = 6b49179821 -M = f753311ac9 - -ModMul = e9ab3a2aa60edd30108 -A = 5134a36c2bad180dd5bf -B = 2ba6485656d041690666 -M = 9b9cc4409e86c8b0fbbf - -ModMul = 621f9b797e866028b7bd1ff828bf29 -A = a202338dffe171c99434d84f3 -B = fb71eee7045b3e3ab5dd809dd -M = b3e6e8d53b7249df670e3c59c55d33 - -ModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672 -A = c669426a92d3cb5b316e2b5b9 -B = ccaea3874008dcc92450d8b2f -M = b04dd2bb325baed1940cd000e8cb2d786009ccd5 - -ModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0 -A = c3255cb24a813e27c3dc410f0 -B = b144f39e7c2d33605ba7bee16 -M = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077 - -ModMul = 6124d7d171 -A = 235b938139 -B = 3a56a22a28 -M = 83eb4af4e5 - -ModMul = 9c006f56095d442ba98c -A = 207e14237c42e3764e5e -B = 8a495a26872432fa8e33 -M = d0cf2b8ae5c67d6736b9 - -ModMul = 97387cfaef652932a230c82de59cac -A = 82ae0fc5e943af5bb8c4adebb -B = db1279be12d59ba3a9c036a61 -M = aa36dc1d13390169cd54d711eb511b - -ModMul = 32ee73c98da657464c6fed4274df20b099689e00 -A = 9baf08248ee24bcb17714e420 -B = a7f0428147bfe098666180749 -M = ce0bc198331c9ed1d21f0d498326e8185d3d602d - -ModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34 -A = b36249e259b303e453757721c -B = f0c1db50670d92abd93bdc84b -M = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9 - -ModMul = 2663b741ff -A = 58c8e7f7f6 -B = c84681fc87 -M = e0a50dcb45 - -ModMul = 21af3c0b42328f41b81e -A = 1f79f5b5bf78c9700d -B = 5bd1734ba0f0e59c2a25 -M = 9ff3fdfb5c089244f327 - -ModMul = cbc280b5106c2c36cb31ad7e7c986c -A = cadf6482b769e83ce7f7277dd -B = f9862a06da1a9c89547b76c61 -M = cc36144c88139ce921d2fd1740bc4b - -ModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b -A = 9c51a5bacb5d9f055a9ac2962 -B = bfed5625b21b4e82d1f105a0b -M = a47977acad7c5deeb683ccd265cb30cb193f22a9 - -ModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478 -A = 997c4a7b537d9500d73a205a4 -B = c679ce666af284a459ae5a26e -M = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9 - -ModMul = 1a90c92fdb -A = 94fa7bb475 -B = 564b0a3339 -M = a1501bdc75 - -ModMul = 5e7ae5470686bad7996a -A = c725797912c6c5f30d94 -B = 3a7f4c99ee3f5fa9582c -M = cc50c8b7408f09a74973 - -ModMul = 72a15b13bcd1b63747342a6be8f0f2 -A = c33357af48a2df569e3c11ce6 -B = a4b4c5c14d7796adab54b6cae -M = e22a0fdca62a37f4c8a61c96a429b9 - -ModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6 -A = ce8d3adab8cbf15c332c0b289 -B = 9333f94eeb7d7a86b82becc51 -M = a532a76bd5cff409b580d54d12ef75ad8179b381 - -ModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14 -A = 9a2b56a54bd0727ab4be57ff2 -B = edf1781b4296567990773005a -M = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1 - -ModMul = 917bcdb402 -A = 55c7dbd314 -B = 997b29ef79 -M = af5b4cbd0f - -ModMul = 660c4bb2b771f523a4fd -A = 43fe52461d5139620a11 -B = 1f8ec4b67de1db54ddda -M = d0458e215b7e6903d96f - -ModMul = 7aeff02c143e4426fcbcf32bd1277b -A = a2671586369a990dde7829f36 -B = c7ff67937c900daccc0ab1d8c -M = 8ad9c1d4d3cce681d1ae27c27982df - -ModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07 -A = aea36cf51dd2ce06c66b7a407 -B = 80c9fe5bb0afd2bf8b3644f96 -M = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9 - -ModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0 -A = f67636b03821c8f13f21217a5 -B = 8473a29f4ae33f36a0d2c6dc0 -M = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5 - -ModMul = 17fe4644a2 -A = 912611576f -B = 7a10d36b80 -M = c5fa605133 - -ModMul = 8159b23d4fd697b4fd35 -A = be2d646e76494439e60 -B = 60fa770d05ebc69772b2 -M = a6e7c940cd749925a85b - -ModMul = 7c412dad5c9fff91357bf181caf2bf -A = 80f476ed5acae75b34ed54c52 -B = fb818e2bdab3b5f4bd84db3d0 -M = d0339f7ee41337d8462d1a9c207d1d - -ModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b -A = ee9c92de52210e61adaa6eb4a -B = 8ab55a85b1abab62d33e75fe3 -M = cd3faa6de4cb62fece4c3f94492d457834a6a041 - -ModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28 -A = bd162c90bed25e84dd5b6b77c -B = d887ee03020c5df356f091db6 -M = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f - -ModMul = 958951bd0f -A = 12bd0d3375 -B = 668bb65b4e -M = 9c617dfaad - -ModMul = 8a109ebc9cbf86613e43 -A = a3e7019f1bbc35689a77 -B = 3189ecd3fd4ffd0229ef -M = ddadc50600dff2abc1af - -ModMul = 2b4d9f85a398c852b3a0cc82524619 -A = c244fd157267f707319ba6c6d -B = 8a07018a748992429bbdbf326 -M = bf3813fb54f749ea5627f59ce30e07 - -ModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f -A = c9909dcfd3a59a3cfa538b267 -B = 8bbf89cd5a4e24adc2d8c646b -M = c8f02682b9d480ea98faaca53b747ced33ed0419 - -ModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a -A = 8019266c548982a520ab48eff -B = d33c3e3b13576dcdb3ffaa796 -M = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1 - -ModMul = 3eaa4c99fd -A = 6fc42faa85 -B = dd0b4e318e -M = fd7f22301b - -ModMul = 56b6b811ced3433755cb -A = 145573d17cb0c996c69 -B = 9d3297d5ccc184896822 -M = dcfb3b383506239e83e1 - -ModMul = 34315b6bc6d3690c28060485ae331f -A = b963a26973894cfb42fcb2d22 -B = e8523304bbcdff1a0ed4141bb -M = d7a379aeac7d8cf94f19e7924d35d1 - -ModMul = 2ec9466e8b3357496f07e37ba24d36a237883846 -A = a75f3904e564997695b6707eb -B = f9f47bd779834dc1f5fba0654 -M = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed - -ModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044 -A = a38eceb9c551f0e69a544072c -B = d5f8e7c2d534b2b8985bfd213 -M = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7 - -ModMul = 172f2e2e22 -A = 1584ff1055 -B = 2e0aee014d -M = b904cb0bc9 - -ModMul = 122c10d3200270b9eaa1 -A = 86fd189e62a6dc1e4ba0 -B = 5235635f7b0336f5f235 -M = c93da97d0e95fb63dc4d - -ModMul = 3e461e10ac4eb749512097fbf76616 -A = cf4ce10cbca07164f3812f89c -B = b7e4639c233fbb0f923fb5104 -M = 949647857e1406871593fad5c30101 - -ModMul = 88117b59d9fed79dd6aaf083ee938215a995a221 -A = 94c888795567d434123d441a7 -B = c60ca79e61a352e34e0f78bee -M = d2553a7c5dccd639a3927697a2e1af03845f2f25 - -ModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c -A = c170eaddca5295d6ec6272dc2 -B = f94a5685ced7661df2efbd34e -M = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd - -ModMul = 1110cdbe5b -A = 5db02b38f3 -B = 3369537903 -M = a8863f7979 - -ModMul = 90fcc5f3a346d3d4ea4c -A = b93373680ea0feeb31d8 -B = 37f9dfaf0e180be64bd5 -M = d595cc29237d1c19e2db - -ModMul = 8623a9997e514cf3c1d06c33c14053 -A = b396f5ede6212f1fdfc7e7b77 -B = 81a1ddc18306f2d2e84030148 -M = a6be32a91b34857842255ef8b1aafd - -ModMul = 63f8f0254df06356f5cab8941b77619ad58025ed -A = 806b2627b08d987438f920bae -B = 83297039f4aa8efc1a185fea3 -M = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5 - -ModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438 -A = 930b04224bc097ac1d8bae8be -B = b79496a80e45212c4663e5b64 -M = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1 - -ModMul = cd93b5b8b1 -A = 47a51b2d5a -B = 86d6ba5155 -M = efb0ad3643 - -ModMul = 2037821ea789118bde0a -A = a92215dcae19be637ff -B = 93b9a3664a406737958f -M = 9df360b69ed26f610253 - -ModMul = 3bf11785d28ceb668dc55b870faf7b -A = bc8758854dc48e057cb6210de -B = f03ca689620a77ecd8a6f0de3 -M = f3ff0747d6e5f34a0ba4200f579259 - -ModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf -A = 993cd09f3e46423a8ba2053df -B = feabee384158032dd013dc08d -M = cd0b21388cb2033b1e792ec4078334df70b6c8f9 - -ModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650 -A = 90e5d18b017118177ffb080da -B = f8e7e09032574f6c66e623ec8 -M = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11 - -ModMul = 8fcd412054 -A = 2e7f9b1a -B = 6283de2c9a -M = 9bff560ae7 - -ModMul = 57d0d3b79f1e2f3632fc -A = 2f8cc403de5af54cfa39 -B = 3b798c3ead52878dfb2f -M = 805e6cbde400d4b4bc9b - -ModMul = 23331614e88633af879201f568c359 -A = f21f19da4b20980979a645dac -B = ea752050b79883dcd69222536 -M = aed3faf4c88f7c4afe257c5ed90599 - -ModMul = 56dcf9ae1c787e773774df3c8762babb4675a212 -A = 9accf901fa599da05fa6ab5ff -B = f7f6b9b1d7bae06237532e39f -M = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5 - -ModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0 -A = 8e57680f213d088ff1a1e7db3 -B = afebecc9943b0093f87022940 -M = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb - -ModMul = 143ae78a29 -A = 334abb952a -B = 74203e7a50 -M = c9535a9505 - -ModMul = 897a2b57e69f5a1469ea -A = 1ec8ca0ea4fed52bdbbf -B = 3a6273cab05e478a57b8 -M = dcb33163a8ea42c1ae6d - -ModMul = 4a2c10e90e2d37111db79a44d3e31b -A = a90e7bbd63fc4af6de83029ee -B = cf09c3dd50b41afc7045e057b -M = 8ab85d47e4270116a64f97dc4f0f15 - -ModMul = 70f94276c9d85fd3f71edfaad6051456f754da85 -A = fa3e9ff6e1aa1fb78e51711cb -B = b115ed197c50b7ec4040ca255 -M = ad63f69ef1346e7549ba71c13b24b279f53bc9bd - -ModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac -A = fc41a9ce06e882942f751be7a -B = 881c05a51d1ba8134d126a48e -M = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f - -ModMul = 4e0051898a -A = 2a06523f70 -B = 651b5044f0 -M = 9da4eb09b5 - -ModMul = cc8274c88d6affc3742f -A = 9ccf0133f9628532f4f6 -B = c1d80907057be7a67b01 -M = d6e76e362da831f32685 - -ModMul = 568f15bed5c4405be9dd04673a9c46 -A = dd6029c3196feb6da7f0f4a48 -B = a5f6745f2cb64913d1d3236d8 -M = f62f02c9b9ca8993e3be9a02b444bf - -ModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f -A = 963c51a9415b03e85ccb09f25 -B = b1cffe333afe44311cb968ffe -M = ab2128698d498e8d75455033cfbbf4487535773f - -ModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf -A = c3b33f391e78bee97ceddf313 -B = a9136f3af450fdeb245eff425 -M = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35 - -ModMul = 8735bd486d -A = 563e15c52a -B = 31293264e1 -M = 92f4b193df - -ModMul = a541f69ca163b288dd0e -A = a608b48c1dcaa18424b2 -B = 891b0b296e911068b00c -M = d4140921f4b2c84f1eb1 - -ModMul = adc1b7cf65967b013d046866b4ed9d -A = e97941448f65060cf63ecd486 -B = ca68936f76cb87a8fbdd37311 -M = ebbca2482fb82eeca2866057cf1179 - -ModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632 -A = c11f83f01bb964ffac93a2e30 -B = e05ee40eea39f4538d735193d -M = b5e8b511738979dc740a6a1f7291cf4561787be7 - -ModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a -A = acff8da571e1c96810bf95707 -B = cdd23e5504cc26d0c34a62b06 -M = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7 - -ModMul = 193f453197 -A = 8cb3078675 -B = a8fb003a87 -M = b60ff22f4b - -ModMul = 849c26c8cf5cae426a80 -A = 5d1e3d2b4d038a0a34be -B = 34f70325565bf0523314 -M = cbc189f9a732cad8f425 - -ModMul = 9a4e64ff530c53a4c6c5b6b5021920 -A = f53b81723cf74f520a61e614e -B = 9d8ac2e6b839143fdd079a2ff -M = a115375435151798f3644bede9d863 - -ModMul = aac303a4623e80158af1cb3331965cc8e3184edd -A = cce0a88606ff962fdc37e72c9 -B = 9840a500a2051625c517104db -M = b99dafdbd91ec3c05791031df5e193c03d6a441d - -ModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf -A = e6f48c027284856aaf3b96425 -B = b4c326f72a6a22fd4b93ba5b3 -M = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab - -ModMul = 8b0929adbf -A = 61fdf77ac0 -B = 8892f05400 -M = f12b3766eb - -ModMul = 91b57f353307b173679d -A = 33f8e73752072b4b5cfa -B = b4c730f79f4f2c07945d -M = d41be1d8d2e5753e3ae9 - -ModMul = af04c564adfeb120bc4770bc8c650c -A = af151333b3d4cd1d29fd801db -B = 9ccaac44ff91be11b30bdcdd0 -M = e0bd6e70d5f5ce08fbbfd48d43101f - -ModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd -A = a2fd08df2d4eab0cd6d29e213 -B = 92c9d26ae7c215b52199ee28b -M = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3 - -ModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd -A = 855f941d085305725da617f5d -B = 8f09b7d2c36e0340523da5421 -M = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b - -ModMul = 2d278e089 -A = 59d20a1716 -B = 8e2a58bc75 -M = b3d61ef699 - -ModMul = 2f937ce359d0f6cedd1 -A = 1019d11d26040ffd5b1d -B = 7cdb6252087423d43e08 -M = e8f537323004447e669f - -ModMul = 6567332e25af83089f7458786ab0ca -A = bf9565e9f8a098894447b58fb -B = fc867626f268c24cc0ab7bf8b -M = 930f39183353363dcd822933a438ef - -ModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9 -A = d0a42ce512629f0ffd233a9aa -B = 97f6d3c4c655c7353a62d6ac4 -M = eac2ea84851f880214b8f40f881a2e56a6ba6f2d - -ModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58 -A = c237eb242c40960861c938c08 -B = ab2f481f0d768eebd90d2574b -M = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f - -ModMul = c952f9aef -A = 81973bbcb3 -B = 28ddee3bf7 -M = c4a40993c9 - -ModMul = 241dd53d93f7bdbbb2ee -A = 2136eda4495c45c9f96c -B = e74c4baa8ca3f6b7cd5b -M = fff4594e7a5f0a1d3e15 - -ModMul = 5f861ed8b0aa835761613e6c869cfd -A = bfc5c1572086079f5f5d18d1b -B = 95902e14923c8010b7e905178 -M = a819c6c109d623f9b845aa23712c9b - -ModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598 -A = fbe65d3852224a812c432672a -B = d57a3f38da966d2471d70a048 -M = b9e6a626d3ad026d14248fc90c882bedd64a1f13 - -ModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed -A = fd91701ed2151f8e994bf4ee1 -B = 88b66e735b76972bccd9db182 -M = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55 - -ModMul = cb743c97a1 -A = 9c69ca9b60 -B = 7488f48f5 -M = d67040ed0d - -ModMul = 931b2bee1bc30725a31 -A = 650f567b544ce02303d4 -B = 5858da30dd1fae88a675 -M = 91ce30234bb29fb9e833 - -ModMul = 5b4f262cec958a20390b5e568ccdaf -A = f7e240e8a077e8e87506db2f1 -B = f8653fe64e3bd414782f51634 -M = fdb8225eefc1620648737d31dfe1f7 - -ModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1 -A = eda8e9a9ea3cdae17bd50b1b4 -B = 992e8ef4a45593e4ceff67876 -M = 95e2f120cfcefbada1058af6c8853cbebedd5763 - -ModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466 -A = ca6c51ba2f410d09bf71d60fe -B = 8bdfa8fe5ef3b2ad02bc63c4d -M = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb - -ModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d -A = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee -B = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca -M = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb - -ModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634 -A = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90 -B = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc -M = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59 - -ModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76 -A = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651 -B = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035 -M = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb - -ModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540 -A = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf -B = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7 -M = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7 - -ModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db -A = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c -B = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d -M = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401 - -ModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4 -A = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04 -B = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8 -M = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1 - -ModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658 -A = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0 -B = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590 -M = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227 - -ModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764 -A = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d -B = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf -M = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab - -ModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2 -A = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23 -B = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321 -M = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93 - -ModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764 -A = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20 -B = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88 -M = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735 - -ModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233 -A = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f -B = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538 -M = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793 - -ModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4 -A = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f -B = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45 -M = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47 - -ModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9 -A = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2 -B = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94 -M = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3 - -ModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9 -A = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f -B = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26 -M = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479 - -ModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d -A = 6500f3cf686eec4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2 -B = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a -M = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1 - -ModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113 -A = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4 -B = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb868dcf4e458b36f506ed7fe0ce5 -M = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817 - -ModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855 -A = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c -B = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323 -M = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7 - -ModMul = 4452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6 -A = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d -B = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f -M = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b - -ModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2 -A = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d4b2 -B = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3 -M = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955 - -ModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df -A = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876 -B = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300 -M = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9 - -ModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad -A = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c -B = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811 -M = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937 - -ModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6 -A = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110 -B = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b -M = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025 - -ModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d -A = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b -B = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a -M = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335 - -ModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66 -A = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9 -B = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173 -M = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1 - -ModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995 -A = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd -B = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10 -M = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9 - -ModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c -A = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b -B = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b -M = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09 - -ModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688 -A = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620 -B = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f -M = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9 - -ModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15 -A = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee -B = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec -M = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9 - -ModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244 -A = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941 -B = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd -M = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897 - -ModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6 -A = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6 -B = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80 -M = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923 - -ModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385 -A = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53 -B = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59 -M = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5 - -ModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f -A = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee -B = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7 -M = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed - -# Regression tests for CVE-2016-7055. - -ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9 -A = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 -B = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81 -M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf - -ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9 -A = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81 -B = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 -M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf - - -# ModSquare tests. -# -# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M. - -# Regression test for CVE-2017-3732. -ModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001 -A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000 -M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff - -# Regression test for CVE-2017-3736. -ModSquare = fe06fe0b06160c09 -A = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc -# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff -M = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff - - -# ModExp tests. -# -# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M. - -ModExp = 00 -A = -01 -E = 01 -M = 01 - -ModExp = 01 -A = -02 -E = 01 -M = 03 - -ModExp = 01 -A = -01 -E = 02 -M = 03 - -ModExp = 01 -A = -02 -E = 02 -M = 03 - -ModExp = 00 -A = -03 -E = 02 -M = 03 - -ModExp = 02 -A = -04 -E = 01 -M = 03 - -ModExp = 01 -A = -04 -E = 02 -M = 03 - -# Regression test for carry propagation bug in sqr8x_reduction. -ModExp = 19324b647d967d644b3219 -A = 050505050505 -E = 02 -M = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 - -# Cover the E = 0 case for small numbers. -ModExp = 01 -A = 86b49 -E = 00 -M = 30d26ecb - -ModExp = 00 -A = 00 -E = 00 -M = 01 - -ModExp = 208f8aa0 -A = 86b49 -E = 2 -M = 30d26ecb - -ModExp = 27308229 -A = 17591bb -E = 6 -M = 30d26ecb - -ModExp = 2bdf498f -A = 21292626 -E = d -M = 30d26ecb - -ModExp = 11317167 -A = 4a655df24 -E = 10 -M = 30d26ecb - -ModExp = 2e1b88e -A = da6b761a86 -E = 35 -M = 30d26ecb - -ModExp = 20a12ec3 -A = ea811 -E = 2 -M = 23bc042f - -ModExp = c42ced -A = 1011a6a -E = 4 -M = 23bc042f - -ModExp = 4637d79 -A = 28d9a601 -E = 8 -M = 23bc042f - -ModExp = 20e5669b -A = 72fe6bc20 -E = 11 -M = 23bc042f - -ModExp = 142ab9e3 -A = 9a07b9363c -E = 29 -M = 23bc042f - -ModExp = 14c64646 -A = 822df -E = 3 -M = 30915765 - -ModExp = 160e35a2 -A = 15ea542 -E = 5 -M = 30915765 - -ModExp = 2f23a488 -A = 34d2e02e -E = e -M = 30915765 - -ModExp = 28e67f93 -A = 636a32703 -E = 14 -M = 30915765 - -ModExp = 29bfeaa5 -A = c8646998e6 -E = 2c -M = 30915765 - -ModExp = 30959e22 -A = 81dad -E = 3 -M = 326dd68d - -ModExp = 1a1da4fa -A = 116adb9 -E = 5 -M = 326dd68d - -ModExp = 272bf0d8 -A = 2d21ef08 -E = 8 -M = 326dd68d - -ModExp = 29f5054b -A = 76989850a -E = 16 -M = 326dd68d - -ModExp = e6c7b77 -A = b88ee70d2a -E = 3e -M = 326dd68d - -ModExp = 369605e1 -A = cf26f -E = 2 -M = 3ce082eb - -ModExp = 168a3c5d -A = 1f82caf -E = 5 -M = 3ce082eb - -ModExp = 125c4bb8 -A = 2e9c4c07 -E = 9 -M = 3ce082eb - -ModExp = 1c5fe761 -A = 523ab37f1 -E = 14 -M = 3ce082eb - -ModExp = 21703009 -A = dc832165e8 -E = 20 -M = 3ce082eb - -ModExp = 1228d1e -A = a5555 -E = 3 -M = 24665b27 - -ModExp = 5226af4 -A = 1077bd6 -E = 4 -M = 24665b27 - -ModExp = 1b14eac1 -A = 2db3a834 -E = f -M = 24665b27 - -ModExp = 161727bc -A = 6bd962cb6 -E = 19 -M = 24665b27 - -ModExp = 10d61d0d -A = c10caed407 -E = 28 -M = 24665b27 - -ModExp = 233da406 -A = b125f -E = 3 -M = 33509981 - -ModExp = 24032799 -A = 1656b7c -E = 6 -M = 33509981 - -ModExp = 129ecebe -A = 2e671504 -E = a -M = 33509981 - -ModExp = 20c20bac -A = 4d7a2de44 -E = 1f -M = 33509981 - -ModExp = 2e3ce9d3 -A = c53b3def4d -E = 31 -M = 33509981 - -ModExp = 12fadfd6 -A = b4cf8 -E = 2 -M = 36e9d4ae - -ModExp = 457ac85 -A = 1b1c7e9 -E = 7 -M = 36e9d4ae - -ModExp = 31debef4 -A = 3a973028 -E = d -M = 36e9d4ae - -ModExp = 2333ad93 -A = 552b97c45 -E = 11 -M = 36e9d4ae - -ModExp = 99ba1fb -A = 8bfb949cbb -E = 28 -M = 36e9d4ae - -ModExp = 27b691de -A = 93492 -E = 3 -M = 298fdb16 - -ModExp = 3c2b70f -A = 14e7b0d -E = 4 -M = 298fdb16 - -ModExp = 1486cda7 -A = 29acff81 -E = c -M = 298fdb16 - -ModExp = 11725275 -A = 507489205 -E = 13 -M = 298fdb16 - -ModExp = 24d14627 -A = e71c55606d -E = 35 -M = 298fdb16 - -ModExp = 222b8d14 -A = 9b1a0 -E = 3 -M = 3db59d12 - -ModExp = 3b8bd47d -A = 13f4e8d -E = 7 -M = 3db59d12 - -ModExp = 17e72356 -A = 334774ce -E = a -M = 3db59d12 - -ModExp = 306447ca -A = 47079ddd2 -E = 12 -M = 3db59d12 - -ModExp = 90bef3b -A = a75d62616d -E = 37 -M = 3db59d12 - -ModExp = 1 -A = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678 -E = 0 -M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb - -ModExp = 0 -A = 0 -E = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e -M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb - -ModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9 -A = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd -E = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e -M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb - -ModExp = 1 -A = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1 -E = 0 -M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 - -ModExp = 0 -A = 0 -E = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d -M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 - -ModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0 -A = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d -E = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d -M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 - -ModExp = 1 -A = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600 -E = 0 -M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b - -ModExp = 0 -A = 0 -E = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b -M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b - -ModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff -A = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839 -E = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b -M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b - -ModExp = 1 -A = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc -E = 0 -M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f - -ModExp = 0 -A = 0 -E = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f -M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f - -ModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f -A = b4fde2908745ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe -E = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f -M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f - -ModExp = 1 -A = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f -E = 0 -M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d - -ModExp = 0 -A = 0 -E = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4 -M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d - -ModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9 -A = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6 -E = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4 -M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d - -ModExp = 1 -A = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef -E = 0 -M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d - -ModExp = 0 -A = 0 -E = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e -M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d - -ModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e -A = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914 -E = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e -M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d - -ModExp = 1 -A = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332 -E = 0 -M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 - -ModExp = 0 -A = 0 -E = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929 -M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 - -ModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8 -A = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1 -E = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929 -M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 - -ModExp = 1 -A = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79 -E = 0 -M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f - -ModExp = 0 -A = 0 -E = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436 -M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f - -ModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9 -A = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558 -E = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436 -M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f - -ModExp = 1 -A = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8 -E = 0 -M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 - -ModExp = 0 -A = 0 -E = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648 -M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 - -ModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa -A = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d -E = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648 -M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 - -ModExp = 1 -A = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d -E = 0 -M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 - -ModExp = 0 -A = 0 -E = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836 -M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 - -ModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca -A = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168 -E = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836 -M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 - -# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in -# order to test the const time precomputation scattering/gathering. - -ModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b -A = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898 -E = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f -M = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d - -ModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679 -A = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc -E = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3 -M = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf - -ModExp = 465ff295786a88496828fdc763e9292d557957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d -A = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d -E = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560 -M = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101 - -ModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd -A = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9 -E = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c -M = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479 - -ModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c -A = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785 -E = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082 -M = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d - -ModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e -A = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059 -E = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902 -M = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9 - -ModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556 -A = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0 -E = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965 -M = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed - -ModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510 -A = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83 -E = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693 -M = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11 - -ModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232 -A = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef -E = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6 -M = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d - -ModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e -A = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286 -E = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0 -M = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7 - - -# RSAZ 512-bit. -# -# These are regression tests for code which historically reached the RSAZ-512 -# code. That has since been removed, but the test vectors remain. Note that the -# lengths of the inputs, especially the *bit* length of |M|, matter a lot. - -# Control: No relationship between A and M except that A < M and they're the same number of limbs. -ModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4 -A = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - -# Same as above except A is negative. -ModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd -A = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - -# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A. -ModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 -A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - -# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ. -ModExp = 1 -A = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - -# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ. -ModExp = 0 -A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - -# A is negative, and A (mod M) is the right length for RSAZ. -ModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25 -A = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 -M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 - - -# RSAZ 1024-bit. -# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot. - -# Control: No relationship between A and M except that A < M and they're the same number of limbs. -ModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7 -A = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8 -E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575 -M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7 - -# Same as above except A is negative. -ModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10 -A = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8 -E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575 -M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7 - -# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A. -ModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 -A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 -E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 -M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 - -# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ. -ModExp = 1 -A = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 -E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 -M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 - -# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ. -ModExp = 0 -A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 -E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 -M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 - -# A is negative, and A (mod M) is the right length for RSAZ. -ModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d -A = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 -M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 - -# Regression test for CVE-2017-3738. -ModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461 -A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df -E = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020 -M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff - -# Test vectors for CVE-2019-1551. (We do not carry the assembly file with the -# bug, but we use the test vectors anyway.) - -# Original test vectors by OSS-Fuzz. -ModExp = 9d675d188a07e9bd1b32638cc8cfd5002ef89bd1a9648f806567b87939140a67977dc8da17323b8e4c6bc53875cda8b656df8f54cc32e44fd9c21d122ea3c0d6 -A = dea9b3e0b44ae67b2ac9b7c2b18eeb4dab206b014981a46ac409f195eeb6896f132cf8497c87d1188008ee511054ebb426203355b7d515dce9501cb759ac1373 -E = b01ae745b101e9e45ec05dcff72e7f8fc04c79ffe324301fda0b4f7be81d85c4e875c73fc6c5cb40000000000000000000000000000000000 -M = ffffffff01ffffffffffffffffffffffffffe2000000000000000000000000000010fab8d960706cd4c21818115650cad61d4f10da325dffffffff00ffff00ff - -ModExp = 651f811b62ee8770e3598c340864dd6b0be9bb6376b6f933ab216fd55538e6ad1000cb2b3c64f54d554e004b6eec8138e6ecff00452d443a42041b72e6cd9ead -A = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e -E = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e09003e3e3e3e3e3e3e3e3e3e3e3e3e3e010900230a01230a2100ffffff0000adf300a58700000000ffffff00 -M = ffffff0b00000000000000000000000000ffffffff0000ffffffff00000a0000000a00000000000000000000ffffffff000000000000ffffffffffff000000ff - -# Test vectors for rsaz_512_sqr bug, with rcx/rbx=1 - -# between first and second iteration -ModExp = 1 -A = 624e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d973b6 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between second and third iteration -ModExp = 1 -A = 11024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000f -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between third and fourth iteration -ModExp = 1 -A = 4171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d9736080000000000000000000000000000039 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between fourth and fifth iteration -ModExp = 1 -A = 6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000006 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between fifth and sixth iteration -ModExp = 1 -A = 44e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000000000000000000003c -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between sixth and seventh iteration -ModExp = 1 -A = 1024e6a171024e6a14ce297f2873536f959d8c3390d973608000000000000000000000000000000000000000000000000000000000000000000000000000000e -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between seventh and eighth iteration -ModExp = 1 -A = 626eee5e3c8653be47ed15e84b97cc7f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000187 -E = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f8 -M = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f9 - -# Test vectors for rsaz_512_srq bug, with rcx/rbx=2 - -# between first and second iteration -ModExp = 1 -A = 3c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf7c -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between second and third iteration -ModExp = 1 -A = 485c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000003f -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between third and forth iteration -ModExp = 1 -A = 59a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000004e -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between forth and fifth iteration -ModExp = 1 -A = 2939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000000000000000000000000000000000000024 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between fifth and sixth iteration -ModExp = 1 -A = 640939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000000000000000000000000000000000000057 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between sixth and seventh iteration -ModExp = 1 -A = 25c40939a85c4093995e8efdb195e8efd8caf477ed8caf4780000000000000000000000000000000000000000000000000000000000000000000000000000021 -E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e -M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f - -# between seventh and eighth iteration -ModExp = 1 -A = 7b4919849931b28a14fcace213f2b3884fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84b6e67b66ce4d9c -E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004c -M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004d - - -# Exp tests. -# -# These test vectors satisfy A ^ E = Exp. - -Exp = aa6d7ac431 -A = d0e07 -E = 2 - -Exp = 12d416b110dbb4e467ff0c89a22122f4da8240 -A = 1a18cf6 -E = 6 - -Exp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000 -A = 2a3acbd2 -E = d - -Exp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1 -A = 54b3ae461 -E = 1a - -Exp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f -A = fccec0f6df -E = 25 - - -# ModSqrt tests. -# -# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime. -# ModSqrt is in [0, (P-1)/2]. - -ModSqrt = 1 -A = 1 -P = 2 - -ModSqrt = 1 -A = 1 -P = 2 - -ModSqrt = 1 -A = 1 -P = 2 - -ModSqrt = 1 -A = -1 -P = 2 - -ModSqrt = 1 -A = -1 -P = 2 - -ModSqrt = 0 -A = 0 -P = 3 - -ModSqrt = 0 -A = -3 -P = 3 - -ModSqrt = 0 -A = -3 -P = 3 - -ModSqrt = 0 -A = 0 -P = 3 - -ModSqrt = 0 -A = 0 -P = 3 - -ModSqrt = 0 -A = 0 -P = 5 - -ModSqrt = 1 -A = -4 -P = 5 - -ModSqrt = 0 -A = -5 -P = 5 - -ModSqrt = 2 -A = 4 -P = 5 - -ModSqrt = 0 -A = -5 -P = 5 - -ModSqrt = 3 -A = -5 -P = 7 - -ModSqrt = 0 -A = 0 -P = 7 - -ModSqrt = 0 -A = 0 -P = 7 - -ModSqrt = 2 -A = 4 -P = 7 - -ModSqrt = 3 -A = -5 -P = 7 - -ModSqrt = 4 -A = 10 -P = b - -ModSqrt = 0 -A = 0 -P = b - -ModSqrt = 3 -A = -2 -P = b - -ModSqrt = 3 -A = -2 -P = b - -ModSqrt = 2 -A = 4 -P = b - -ModSqrt = 2 -A = 1e -P = d - -ModSqrt = 2 -A = 1e -P = d - -ModSqrt = 0 -A = -d -P = d - -ModSqrt = 0 -A = -d -P = d - -ModSqrt = 3 -A = 9 -P = d - -ModSqrt = 8 -A = d -P = 11 - -ModSqrt = 6 -A = df -P = 11 - -ModSqrt = 4 -A = 10 -P = 11 - -ModSqrt = 5 -A = 90 -P = 11 - -ModSqrt = 3 -A = 80 -P = 11 - -ModSqrt = 9 -A = -e -P = 13 - -ModSqrt = 7 -A = 7d -P = 13 - -ModSqrt = 6 -A = 37 -P = 13 - -ModSqrt = 1 -A = 1 -P = 13 - -ModSqrt = 8 -A = 1a -P = 13 - -ModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec -A = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4 -P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 - -ModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d -A = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a -P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 - -ModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444 -A = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc -P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 - -ModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4 -A = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9 -P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 - -ModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4 -A = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf -P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 - -ModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66 -A = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550 -P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 - -ModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d -A = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2 -P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 - -ModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387 -A = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269 -P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 - -ModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87 -A = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74 -P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 - -ModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23 -A = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7 -P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 - -ModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba -A = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a -P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 - -ModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc -A = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b -P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 - -ModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a -A = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07 -P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 - -ModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080 -A = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194 -P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 - -ModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c -A = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c -P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 - -ModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247 -A = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654 -P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 - -ModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065 -A = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090 -P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 - -ModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d -A = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe -P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 - -ModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14 -A = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34 -P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 - -ModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0 -A = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079 -P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 - -ModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c -A = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79 -P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 - -ModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106 -A = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a -P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 - -ModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e -A = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9 -P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 - -ModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096 -A = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7 -P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 - -ModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852 -A = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0 -P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 - -ModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077 -A = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024 -P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb - -ModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71 -A = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7 -P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb - -ModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0 -A = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d -P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb - -ModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5 -A = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b -P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb - -ModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556 -A = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840 -P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb - -ModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f -A = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f -P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d - -ModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029 -A = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb -P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d - -ModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e -A = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5 -P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d - -ModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c -A = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e -P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d - -ModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31 -A = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72 -P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d - -ModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765 -A = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39 -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - -ModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a -A = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507 -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - -ModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb -A = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - -ModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f -A = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - -ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186 -A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81 -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - - -# NotModSquare tests. -# -# These test vectors are such that NotModSquare is not a square modulo P. - -NotModSquare = 03 -P = 07 - -NotModSquare = 05 -P = 07 - -NotModSquare = 06 -P = 07 - -NotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e -P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f - - -# ModInv tests. -# -# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M. - -ModInv = 00 -A = 00 -M = 01 - -ModInv = 00 -A = 01 -M = 01 - -ModInv = 00 -A = 02 -M = 01 - -ModInv = 00 -A = 03 -M = 01 - -ModInv = 64 -A = 54 -M = e3 - -ModInv = 13 -A = 2b -M = 30 - -ModInv = 2f -A = 30 -M = 37 - -ModInv = 4 -A = 13 -M = 4b - -ModInv = 1c47 -A = cd4 -M = 6a21 - -ModInv = 2b97 -A = 8e7 -M = 49c0 - -ModInv = 29b9 -A = fcb -M = 3092 - -ModInv = a83 -A = 14bf -M = 41ae - -ModInv = 18f15fe1 -A = 11b5d53e -M = 322e92a1 - -ModInv = 32f9453b -A = 8af6df6 -M = 33d45eb7 - -ModInv = d696369 -A = c5f89dd5 -M = fc09c17c - -ModInv = 622839d8 -A = 60c2526 -M = 74200493 - -ModInv = fb5a8aee7bbc4ef -A = 24ebd835a70be4e2 -M = 9c7256574e0c5e93 - -ModInv = 846bc225402419c -A = 23026003ab1fbdb -M = 1683cbe32779c59b - -ModInv = 5ff84f63a78982f9 -A = 4a2420dc733e1a0f -M = a73c6bfabefa09e6 - -ModInv = 133e74d28ef42b43 -A = 2e9511ae29cdd41 -M = 15234df99f19fcda - -ModInv = 46ae1fabe9521e4b99b198fc8439609023aa69be2247c0d1e27c2a0ea332f9c5 -A = 6331fec5f01014046788c919ed50dc86ac7a80c085f1b6f645dd179c0f0dc9cd -M = 8ef409de82318259a8655a39293b1e762fa2cc7e0aeb4c59713a1e1fff6af640 - -ModInv = 444ccea3a7b21677dd294d34de53cc8a5b51e69b37782310a00fc6bcc975709b -A = 679280bd880994c08322143a4ea8a0825d0466fda1bb6b3eb86fc8e90747512b -M = e4fecab84b365c63a0dab4244ce3f921a9c87ec64d69a2031939f55782e99a2e - -ModInv = 1ac7d7a03ceec5f690f567c9d61bf3469c078285bcc5cf00ac944596e887ca17 -A = 1593ef32d9c784f5091bdff952f5c5f592a3aed6ba8ea865efa6d7df87be1805 -M = 1e276882f90c95e0c1976eb079f97af075445b1361c02018d6bd7191162e67b2 - -ModInv = 639108b90dfe946f498be21303058413bbb0e59d0bd6a6115788705abd0666d6 -A = 9258d6238e4923d120b2d1033573ffcac691526ad0842a3b174dccdbb79887bd -M = ce62909c39371d463aaba3d4b72ea6da49cb9b529e39e1972ef3ccd9a66fe08f - -ModInv = aebde7654cb17833a106231c4b9e2f519140e85faee1bfb4192830f03f385e773c0f4767e93e874ffdc3b7a6b7e6a710e5619901c739ee8760a26128e8c91ef8cf761d0e505d8b28ae078d17e6071c372893bb7b72538e518ebc57efa70b7615e406756c49729b7c6e74f84aed7a316b6fa748ff4b9f143129d29dad1bff98bb -A = a29dacaf5487d354280fdd2745b9ace4cd50f2bde41d0ee529bf26a1913244f708085452ff32feab19a7418897990da46a0633f7c8375d583367319091bbbe069b0052c5e48a7daac9fb650db5af768cd2508ec3e2cda7456d4b9ce1c39459627a8b77e038b826cd7e326d0685b0cd0cb50f026f18300dae9f5fd42aa150ee8b -M = d686f9b86697313251685e995c09b9f1e337ddfaa050bd2df15bf4ca1dc46c5565021314765299c434ea1a6ec42bf92a29a7d1ffff599f4e50b79a82243fb24813060580c770d4c1140aeb2ab2685007e948b6f1f62e8001a0545619477d498132c907774479f6d95899e6251e7136f79ab6d3b7c82e4aca421e7d22fe7db19c - -ModInv = 1ec872f4f20439e203597ca4de9d1296743f95781b2fe85d5def808558bbadef02a46b8955f47c83e1625f8bb40228eab09cad2a35c9ad62ab77a30e3932872959c5898674162da244a0ec1f68c0ed89f4b0f3572bfdc658ad15bf1b1c6e1176b0784c9935bd3ff1f49bb43753eacee1d8ca1c0b652d39ec727da83984fe3a0f -A = 2e527b0a1dc32460b2dd94ec446c692989f7b3c7451a5cbeebf69fc0ea9c4871fbe78682d5dc5b66689f7ed889b52161cd9830b589a93d21ab26dbede6c33959f5a0f0d107169e2daaac78bac8cf2d41a1eb1369cb6dc9e865e73bb2e51b886f4e896082db199175e3dde0c4ed826468f238a77bd894245d0918efc9ca84f945 -M = b13133a9ebe0645f987d170c077eea2aa44e85c9ab10386d02867419a590cb182d9826a882306c212dbe75225adde23f80f5b37ca75ed09df20fc277cc7fbbfac8d9ef37a50f6b68ea158f5447283618e64e1426406d26ea85232afb22bf546c75018c1c55cb84c374d58d9d44c0a13ba88ac2e387765cb4c3269e3a983250fa - -ModInv = 30ffa1876313a69de1e4e6ee132ea1d3a3da32f3b56f5cfb11402b0ad517dce605cf8e91d69fa375dd887fa8507bd8a28b2d5ce745799126e86f416047709f93f07fbd88918a047f13100ea71b1d48f6fc6d12e5c917646df3041b302187af641eaedf4908abc36f12c204e1526a7d80e96e302fb0779c28d7da607243732f26 -A = 31157208bde6b85ebecaa63735947b3b36fa351b5c47e9e1c40c947339b78bf96066e5dbe21bb42629e6fcdb81f5f88db590bfdd5f4c0a6a0c3fc6377e5c1fd8235e46e291c688b6d6ecfb36604891c2a7c9cbcc58c26e44b43beecb9c5044b58bb58e35de3cf1128f3c116534fe4e421a33f83603c3df1ae36ec88092f67f2a -M = 53408b23d6cb733e6c9bc3d1e2ea2286a5c83cc4e3e7470f8af3a1d9f28727f5b1f8ae348c1678f5d1105dc3edf2de64e65b9c99545c47e64b770b17c8b4ef5cf194b43a0538053e87a6b95ade1439cebf3d34c6aa72a11c1497f58f76011e16c5be087936d88aba7a740113120e939e27bd3ddcb6580c2841aa406566e33c35 - -ModInv = 87355002f305c81ba0dc97ca2234a2bc02528cefde38b94ac5bd95efc7bf4c140899107fff47f0df9e3c6aa70017ebc90610a750f112cd4f475b9c76b204a953444b4e7196ccf17e93fdaed160b7345ca9b397eddf9446e8ea8ee3676102ce70eaafbe9038a34639789e6f2f1e3f352638f2e8a8f5fc56aaea7ec705ee068dd5 -A = 42a25d0bc96f71750f5ac8a51a1605a41b506cca51c9a7ecf80cad713e56f70f1b4b6fa51cbb101f55fd74f318adefb3af04e0c8a7e281055d5a40dd40913c0e1211767c5be915972c73886106dc49325df6c2df49e9eea4536f0343a8e7d332c6159e4f5bdb20d89f90e67597c4a2a632c31b2ef2534080a9ac61f52303990d -M = d3d3f95d50570351528a76ab1e806bae1968bd420899bdb3d87c823fac439a4354c31f6c888c939784f18fe10a95e6d203b1901caa18937ba6f8be033af10c35fc869cf3d16bef479f280f53b3499e645d0387554623207ca4989e5de00bfeaa5e9ab56474fc60dd4967b100e0832eaaf2fcb2ef82a181567057b880b3afef62 - - -# GCD tests. -# -# These test vectors satisfy gcd(A, B) = GCD and lcm(A, B) = LCM. - -GCD = 0 -A = 0 -B = 0 -# Just to appease the syntax-checker. -LCM = 0 - -GCD = 1 -A = 92ff140ac8a659b31dd904161f9213706a08a817ae845e522c3af0c9096699e059b47c8c2f16434b1c5766ebb384b79190f2b2a62c2378f45e116890e7bb407a -B = 2f532c9e5902b0d68cd2ed69b2083bc226e8b04c549212c425a5287bb171c6a47fcb926c70cc0d34b8d6201c617aee66af865d31fdc8a2eeb986c19da8bb0897 -LCM = 1b2c97003e520b0bdd59d8c35a180b4aa36bce14211590435b990ad8f4c034ce3c77899581cb4ee1a022874203459b6d53859ab1d99ff755efa253fc0e5d8487bb000c13c566e8937f0fe90b95b68bc278610d4f232770b08d1f31bee55a03da47f2d0ebb9e7861c4f16cc22168b68593e9efcde00f54104b4c3e1a0b294d7f6 - -GCD = a -A = faaffa431343074f5c5d6f5788500d7bc68b86eb37edf166f699b4d75b76dae2cb7c8f6eccae8f18f6d510ef72f0b9633d5740c0bebb934d3be796bd9a53808e -B = 2f48ec5aa5511283c2935b15725d30f62244185573203b48c7eb135b2e6db5c115c9446ac78b020574665b06a75eb287e0dbeb5da7c193294699b4c2129d2ac4 -LCM = 4a15f305e9622aa19bd8f39e968bfc16d527a47f7a5219d7b02c242c77ef8b608a4a6141f643ca97cedf07c0f1f3e8879d2568b056718aa15c0756899a08ccbe0a658bae67face96fa110edb91757bfa4828e8ff7c5d71b204f36238b12dd26f17be8ba9771f7068d63e41d423671f898f054b1187605754bc5546f2b02c5ac - -GCD = 16 -A = cf0b21bde98b41b479ac8071086687a6707e9efaacd4e5299668ce1be8b13290f27fd32ae68df87c292e8583a09d73ec8e8a04a65a487380dcd7dacca3b6e692 -B = 3be3f563f81d5ad5c1211db7eff430aa345e830ce07b4bde7d4d32dba3ac618d2034351e5435fd6c7f077971fb4a1e83a7396a74fdff7fce1267112851db2582 -LCM = 233a2188de2c017235024b182286f17562b2ee5ab9fdfe4efa2f61c4ff99fa44e1ead5bf6cde05bd7502ce78373c83e3f9dbab0c9bb8620a87c2640bce5d12c685af656df789bb3d0ba1edbaa98cf4f0166d422ab17aa6706f8132264d45b72827d6671a00a9186e723379e3a3bb7902d08865f357c74100059f83800241976 - -GCD = 1 -A = dd7b7597d7c1eb399b1cea9b3042c14bd6022d31b1d2642a8f82fc32de6eadaf012fbbf349eaec4922a8468740ca73c6090833d6a69a380ed947b39c2f9b0b76 -B = 8e0dc8654e70eec55496038a8d3fff3c2086bc6dbfc0e2dbdf5bd7de03c5aef01a3982556ac3fc34fd5f13368be6cdc252c82367b7462e210f940f847d382dd9 -LCM = 7ae667df4bd4dd35bbec28719a9f1b5e1f396a9ab386c086742a6ab3014a3386d39f35b50624d0c5b4e6b206c2635c7de5ea69e2faa85dd616a7e36622962a07632839857aa49332942feccff2aee1c962e2f4e8ccfd738a5da5bf528b4c5a2440409350f5a17a39d234403e8482ccf838e0d2758ccfb8018198a51dbb407506 - -GCD = 1 -A = 0 -B = 1 -LCM = 0 - -GCD = 1 -A = 1 -B = 0 -LCM = 0 - -GCD = 1 -A = 1 -B = 1 -LCM = 1 - -GCD = 2b2 -A = dfccaa3549c1b59ab3e114fe87dc5d187719abad58c51724e972741eb895ab79a49f385f61d531ec5c88dbb505ae375093fa848165f71a5ed65e7832a42ade191a -B = fa58a81f43088da45e659fc1117d0f1cd015aa096c8e5377cf1832191baf7cc28b5c24998b93b64f8900a0973faedb9babaaf1854345f011739da8f1175d9684c -LCM = 5132f7ab7a982b9dc55114bd96800b7637f9742cf8a7a00a0d69d5e4574fc85792c89a1c52bcfc74b9d7f3f6164819466c46b2d622e280ced7ad1211604084a15dc1fd1951a05c8ce37122c0ec15891d818a70d3763670ea3195098de9b1ca50ea89893a9753fb9ea801541058f44801f7f50967124abfc864a2b01c41f94193c - -GCD = 8e -A = 248d96a8a4cab0a1b194e08c1146868b094597cadbc35531f0ed2d77cba9f15cb5cc7c10e64ce054bf93396d25259d750b3de3aba65073db1fd2b852a6454ac1a -B = 4c7bad8e1844901fd6a2ce2edc82e698d28ec95d6672ca148d85b49ecc78dd0a8b870e202244210bc98592b99ff6abbd20630f9eee7d46b15ccfae8d08b86799de -LCM = 13b01f9d9c6c13e90c97e3d95bbce5a835c631b3de3bd4ff5df13ad850f5223dbdf71c53912275d0397df9335ef3a3ba8e4684c6b25962bb7b18bc74144cb5edf0196f79863a7ff032619a71646a92281f7baace7f223d254cb4d05ec19bf8d4c8ce4455a9d770daec89c0d3cf338cbdae39cf982b3c4568f5c9def4e1133d28a - -GCD = 3e55 -A = 2fa97382f46676b7a4cc2b8153f17b58792d24660e187d33ce55c81cc193ccb6e1e2b89feea1d5fd8faa36e13bf947fb48635e450a4d1488d0978324194a1f43c6 -B = ab08ad074139963bc18e5d87ba68db64ca6f4c279616c64039b02c55f2375b3bc04114e8e05e1ba92fb6470768f61d123845aea36774c18612736a220934561faf -LCM = 82c7c377ecda2cb9228604cd287df5eff94edd4a539c3eb3b3fdd4b4a79d2f4eaf2b22f8286272d3dad2e370cfcd9ea4d93ebb3f049c52b8fa23b68a5bf79af989822e2cfb978f68c6a5058f47319dffcb455b089b06ae6db9e5c8a2b6e951d6e118bd2b4cd08b6e5733476a446a57387d940d1289ec00e24315821ed3a5daf2 - -GCD = a7a -A = 923706dfed67834a1e7e6c8e8e9f93bfbc0b43ca1f324886cf1f1380fb9b77109275d4b50af1b7689802fe9b3623ac46c7ba0e17e908c20278127b07a5c12d86ec -B = 64473e878a29021fac1c1ce34a63eae1f4f83ee6851333b67213278b9a4a16f005cba0e8cdb410035bb580062f0e486c1a3a01f4a4edf782495f1dc3ebfa837d86 -LCM = 57785ca45b8873032f1709331436995525eed815c55140582ce57fd852116835deac7ca9d95ce9f280e246ea4d4f1b7140ab7e0dd6dc869de87f1b27372098b155ad0a1828fd387dff514acc92eae708609285edaab900583a786caf95153f71e6e6092c8c5ee727346567e6f58d60a5e01c2fa8ebcf86da9ea46876ecc58e914 - -GCD = 42 -A = 0 -B = 42 -LCM = 0 - -GCD = 42 -A = 42 -B = 0 -LCM = 0 - -GCD = 42 -A = 42 -B = 42 -LCM = 42 - -GCD = f60d -A = ef7886c3391407529d5cf2e75ed53e5c3f74439ad2e2dc48a79bc1a5322789b4ced2914b97f8ff4b9910d212243b54001eb8b375365b9a87bd022dd3772c78a9fd63 -B = d1d3ec32fa3103911830d4ec9f629c5f75af7039e307e05bc2977d01446cd2cbeeb8a8435b2170cf4d9197d83948c7b8999d901fe47d3ce7e4d30dc1b2de8af0c6e4 -LCM = cc376ed2dc362c38a45a719b2ed48201dab3e5506e3f1314e57af229dc7f3a6a0dad3d21cfb148c23a0bbb0092d667051aa0b35cff5b5cc61a7c52dec4ed72f6783edf181b3bf0500b79f87bb95abc66e4055f259791e4e5eb897d82de0e128ecf8a091119475351d65b7f320272db190898a02d33f45f03e27c36cb1c45208037dc - -GCD = 9370 -A = 1ee02fb1c02100d1937f9749f628c65384ff822e638fdb0f42e27b10ee36e380564d6e861fcad0518f4da0f8636c1b9f5124c0bc2beb3ca891004a14cd7b118ddfe0 -B = 67432fd1482d19c4a1c2a4997eab5dbf9c5421977d1de60b739af94c41a5ad384cd339ebfaa43e5ad6441d5b9aaed5a9f7485025f4b4d5014e1e406d5bd838a44e50 -LCM = 159ff177bdb0ffbd09e2aa7d86de266c5de910c12a48cbe61f6fa446f63a2151194777555cd59903d24cb30965973571fb1f89c26f2b760526f73ded7ee8a34ebcecd1a3374a7559bcdb9ac6e78be17a62b830d6bb3982afdf10cf83d61fd0d588eab17d6abef8e6a7a5763fcb766d9a4d86adf5bb904f2dd6b528b9faec603987a0 - -GCD = c5f -A = 5a3a2088b5c759420ed0fb9c4c7685da3725b659c132a710ef01e79435e63d009d2931ea0a9ed9432f3d6b8851730c323efb9db686486614332c6e6ba54d597cf98 -B = 1b1eb33b006a98178bb35bbcf09c5bebd92d9ace79fa34c1567efa8d6cf6361547807cd3f8e7b8cd3ddb6209dccbae4b4c16c8c1ec19741a3a57f61571882b7aed7 -LCM = c5cbbbe9532d30d2a7dd7c1c8a6e69fd4fa4828a844d6afb44f3747fef584f7f1f3b835b006f8747d84f7699e88f6267b634e7aef78d6c7584829537d79514eec7d11219721f91015f5cefdc296261d85dba388729438991a8027de4827cd9eb575622e2912b28c9ce26d441e97880d18db025812cef5de01adeaec1322a9c9858 - -GCD = e052 -A = 67429f79b2ec3847cfc7e662880ab1d94acdf04284260fcfffd67c2862d59704ed45bcc53700c88a5eea023bc09029e9fd114fc94c227fd47a1faa1a5ef117b09bd2 -B = 39faa7cbdeb78f9028c1d50ab34fbe6924c83a1262596f6b85865d4e19cc258b3c3af1ee2898e39e5bee5839e92eac6753bbbb0253bd576d1839a59748b778846a86 -LCM = 1ab071fb733ef142e94def10b26d69982128561669e58b20b80d39cf7c2759d26b4a65d73b7f940c6e8fc417180ef62d7e52ac24678137bd927cd8d004ad52b02affe176a1ecde903dbc26dcc705678f76dd8cd874c0c3fe737474309767507bbe70dd7fb671bbb3694cedf0dcdaa0c716250ddd6dfec525261572fa3e1387f7b906 - -GCD = 3523 -A = 0 -B = 3523 -LCM = 0 - -GCD = 3523 -A = 3523 -B = 0 -LCM = 0 - -GCD = 3523 -A = 3523 -B = 3523 -LCM = 3523 - -GCD = f035a941 -A = 16cd5745464dfc426726359312398f3c4486ed8aaeea6386a67598b10f744f336c89cdafcb18e643d55c3a62f4ab2c658a0d19ea3967ea1af3aee22e11f12c6df6e886f7 -B = 74df09f309541d26b4b39e0c01152b8ad05ad2dfe9dd2b6706240e9d9f0c530bfb9e4b1cad3d4a94342aab309e66dd42d9df01b47a45173b507e41826f24eb1e8bcc4459 -LCM = b181771d0e9d6b36fdfcbf01d349c7de6b7e305e1485ea2aa32938aa919a3eee9811e1c3c649068a7572f5d251b424308da31400d81ac4078463f9f71d7efd2e681f92b13a6ab3ca5c9063032dcbdf3d3a9940ce65e54786463bbc06544e1280f25bc7579d264f6f1590cf09d1badbf542ce435a14ab04d25d88ddbac7d22e8cae1c91f - -GCD = 33ad1b8f -A = 1af010429a74e1b612c2fc4d7127436f2a5dafda99015ad15385783bd3af8d81798a57d85038bcf09a2a9e99df713b4d6fc1e3926910fbbf1f006133cb27dc5ebb9cca85 -B = 92a4f45a90965a4ef454f1cdd883d20f0f3be34d43588b5914677c39d577a052d1b25a522be1a656860a540970f99cbc8a3adf3e2139770f664b4b7b9379e13daf7d26c -LCM = 4c715520ed920718c3b2f62821bc75e3ff9fd184f76c60faf2906ef68d28cd540d3d6c071fa8704edd519709c3b09dfaee12cb02ab01ad0f3af4f5923d5705ce6d18bcab705a97e21896bb5dd8acb36ee8ec98c254a4ddc744297827a33c241f09016a5f109248c83dd41e4cea73ce3eabb28d76678b7e15545b96d22da83c111b6b624 - -GCD = dc0429aa -A = ccb423cfb78d7150201a97114b6644e8e0bbbb33cadb0ef5da5d3c521a244ec96e6d1538c64c10c85b2089bdd702d74c505adce9235aa4195068c9077217c0d431de7f96 -B = 710786f3d9022fc3acbf47ac901f62debcfda684a39234644bac630ab2d211111df71c0844b02c969fc5b4c5a15b785c96efd1e403514235dc9356f7faf75a0888de5e5a -LCM = 6929af911850c55450e2f2c4c9a72adf284fe271cf26e41c66e1a2ee19e30d928ae824f13d4e2a6d7bb12d10411573e04011725d3b6089c28d87738749107d990162b485805f5eedc8f788345bcbb5963641f73c303b2d92f80529902d3c2d7899623958499c8a9133aae49a616c96a2c5482a37947f23af18c3247203ac2d0e760340e6 - -GCD = 743166058 -A = 16cd476e8031d4624716238a3f85badd97f274cdfd9d53e0bd74de2a6c46d1827cc83057f3889588b6b7ca0640e7d743ed4a6eaf6f9b8df130011ecc72f56ef0af79680 -B = 86eba1fc8d761f22e0f596a03fcb6fe53ad15a03f5b4e37999f60b20966f78ba3280f02d3853f9ace40438ccfaf8faed7ace2f2bf089b2cdd4713f3f293bf602666c39f8 -LCM = 1a7a1b38727324d6ba0290f259b8e2b89c339b2445cada38a5a00ded1468ab069f40678ce76f7f78c7c6f97783cc8a49ef7e2a0c73abbac3abc66d1ce99566ce7f874a8949ca3442051e71967695dc65361184748c1908e1b587dc02ed899a524b34eb30b6f8db302432cfa1a8fbf2c46591e0ab3db7fd32c01b1f86c39832ee9f0c80 - -GCD = 6612ba2c -A = 0 -B = 6612ba2c -LCM = 0 - -GCD = 6612ba2c -A = 6612ba2c -B = 0 -LCM = 0 - -GCD = 6612ba2c -A = 6612ba2c -B = 6612ba2c -LCM = 6612ba2c - -GCD = 2272525aa08ccb20 -A = 11b9e23001e7446f6483fc9977140d91c3d82568dabb1f043a5620544fc3dda233b51009274cdb004fdff3f5c4267d34181d543d913553b6bdb11ce2a9392365fec8f9a3797e1200 -B = 11295529342bfb795f0611d03afb873c70bd16322b2cf9483f357f723b5b19f796a6206cf3ae3982daaeafcd9a68f0ce3355a7eba3fe4e743683709a2dd4b2ff46158bd99ff4d5a0 -LCM = 8d4cbf00d02f6adbaa70484bcd42ea932000843dcb667c69b75142426255f79b6c3b6bf22572597100c06c3277e40bf60c14c1f4a6822d86167812038cf1eefec2b0b19981ad99ad3125ff4a455a4a8344cbc609e1b3a173533db432bd717c72be25e05ed488d3970e7ed17a46353c5e0d91c8428d2fec7a93210759589df042cab028f545e3a00 - -GCD = 3480bf145713d56f9 -A = 8cf8ef1d4f216c6bcec673208fd93b7561b0eb8303af57113edc5c6ff4e1eeae9ddc3112b943d947653ba2179b7f63505465126d88ad0a0a15b682f5c89aa4a2a51c768cd9fdeaa9 -B = a6fd114023e7d79017c552a9051ca827f3ffa9f31e2ee9d78f8408967064fcdc9466e95cc8fac9a4fa88248987caf7cf57af58400d27abd60d9b79d2fe03fad76b879eceb504d7f -LCM = 1c05eee73a4f0db210a9007f94a5af88c1cdd2cba456061fd41de1e746d836fa4e0e972812842e0f44f10a61505f5d55760c48ba0d06af78bb6bde7da8b0080b29f82b1161e9c0b5458e05ac090b00f4d78b1cc10cf065124ba610e3acab092a36fe408525e21c0ddc7c9696ed4e48bd2f70423deecfe62cecc865c6088f265da0e5961d3f3a84f - -GCD = 917e74ae941fcaae -A = 652f8a92d96cbf0a309629011d0fbaceb1266bc2e8243d9e494eead4cf7100c661b537a8bea93dec88cfc68597d88a976c125c3b4de19aba38d4ea9578202e59848d42652518348a -B = 32e07b71979d57e8344e97c39680a61e07d692d824ae26b682156890792d8a766ee29a4968f461aaced5bf049044fba2f4120b1c1f05985676f975d4582e9e82750d73c532cd07b2 -LCM = 23620c7b897dc26c7717e32f3517ac70bf09fbe08f7255ab010cf4cf946f4e96304c425043452c5d5a0e841d3a3cfd9c2d84d9256f3b5974fe3ebfa9255fe20a710d3e6511606c0d85970381101c7f4986d65ad6a73a71507f146b11f903043cfa805cc0b14d4f3072da98bf22282f7762040406c02d5b3ef9e7587f63bab8b29c61d8e30911aa96 - -GCD = 2b9adc82005b2697 -A = 19764a84f46045ef1bca571d3cbf49b4545998e64d2e564cc343a53bc7a0bcfbe0baa5383f2b346e224eb9ce1137d9a4f79e8e19f946a493ff08c9b423574d56cbe053155177c37 -B = 1bbd489ad2ab825885cdac571a95ab4924e7446ce06c0f77cf29666a1e20ed5d9bc65e4102e11131d824acad1592075e13024e11f12f8210d86ab52aa60deb250b3930aabd960e5a -LCM = 1032a0c5fffc0425e6478185db0e5985c645dd929c7ebfeb5c1ee12ee3d7b842cfab8c9aa7ff3131ac41d4988fb928c0073103cea6bb2cc39808f1b0ad79a6d080eac5a0fc6e3853d43f903729549e03dba0a4405500e0096b9c8e00510c1852982baec441ed94efb80a78ed28ed526d055ad34751b831b8749b7c19728bf229357cc5e17eb8e1a - -GCD = 8d9d4f30773c4edf -A = 0 -B = 8d9d4f30773c4edf -LCM = 0 - -GCD = 8d9d4f30773c4edf -A = 8d9d4f30773c4edf -B = 0 -LCM = 0 - -GCD = 8d9d4f30773c4edf -A = 8d9d4f30773c4edf -B = 8d9d4f30773c4edf -LCM = 8d9d4f30773c4edf - -GCD = 6ebd8eafb9a957a6c3d3d5016be604f9624b0debf04d19cdabccf3612bbd59e00 -A = 34dc66a0ffd5b8b5e0ffc858dfc4655753e59247c4f82a4d2543b1f7bb7be0e24d2bbf27bb0b2b7e56ee22b29bbde7baf0d7bfb96331e27ba029de9ffdff7bdb7dc4da836d0e58a0829367ec84ea256833fd4fe1456ad4dd920557a345e12000 -B = 1f3406a20e20ebf96ccb765f898889a19b7636608fd7dc7c212607b641399543f71111d60e42989de01eaa6ff19a86ea8fbde1a3d368c0d86dc899e8e250fc764090f337958ca493119cbb4ad70cbfae7097d06d4f90ec62fbdd3f0a4496e600 -LCM = ee502c50e3667946e9089d0a9a0382e7fd0b75a17db23b56a0eec997a112c4dbd56d188808f76fe90451e5605550c9559ef14a95014c6eb97e9c1c659b98515c41470142843de60f72fb4c235faa55b0a97d943221003d44e2c28928f0b84bf071256254897ed31a7fd8d174fc962bc1311f67900ac3abcad83a28e259812f1ee229511ab1d82d41f5add34693ba7519babd52eb4ec9de31581f5f2e40a000 - -GCD = ef7399b217fc6a62b90461e58a44b22e5280d480b148ec4e3b4d106583f8e428 -A = 7025e2fe5f00aec73d90f5ad80d99ca873f71997d58e59937423a5e6ddeb5e1925ed2fd2c36a5a9fc560c9023d6332c5d8a4b333d3315ed419d60b2f98ccf28bbf5bf539284fd070d2690aeaac747a3d6384ee6450903a64c3017de33c969c98 -B = df0ac41dbabce1deeb0bceb1b65b1079850052ecf6534d0cff84a5a7fb5e63baee028d240f4419925154b96eaa69e8fbb1aae5102db7916234f290aa60c5d7e69406f02aeea9fe9384afbff7d878c9ac87cd31f7c35dff243b1441e09baff478 -LCM = 687669343f5208a6b2bb2e2efcac41ec467a438fde288cc5ef7157d130139ba65db9eb53e86a30c870bd769c0e0ab15a50f656cd9626621ae68d85eaff491b98da3ea5812062e4145af11ea5e1da457084911961ef2cd2ac45715f885ba94b4082aa76ffd1f32461f47c845b229d350bf36514c5ce3a7c782418746be342eca2721346ade73a59475f178c4f2448e1326110f5d26a0fef1a7a0c9288489e4dc8 - -GCD = 84b917557acf24dff70cb282a07fc52548b6fbbe96ca8c46d0397c8e44d30573 -A = 81dbb771713342b33912b03f08649fb2506874b96125a1ac712bc94bfd09b679db7327a824f0a5837046f58af3a8365c89e06ff4d48784f60086a99816e0065a5f6f0f49066b0ff4c972a6b837b63373ca4bb04dcc21e5effb6dfe38271cb0fa -B = 1da91553c0a2217442f1c502a437bb14d8c385aa595db47b23a97b53927b4493dd19f1bc8baf145bc10052394243089a7b88d19b6f106e64a5ab34acad94538ab504d1c8ebf22ac42048bbd1d4b0294a2e12c09fe2a3bd92756ba7578cb34b39 -LCM = 1d0530f8142754d1ee0249b0c3968d0ae7570e37dadbe4824ab966d655abf04cd6de5eb700eba89d8352dec3ae51f2a10267c32fbd39b788c7c5047fe69da3d7ad505435a6212f44899ba7e983bb780f62bcdee6f94b7dba8af7070a4cc008f351ae8be4579bc4a2e5c659ce000ad9c8cdc83723b32c96aeb0f5f4127f6347353d05525f559a8543cd389ad0af6f9d08a75b8c0b32419c097e6efe8746aee92e - -GCD = 66091477ea3b37f115038095814605896e845b20259a772f09405a8818f644aa -A = cedac27069a68edfd49bd5a859173c8e318ba8be65673d9d2ba13c717568754ed9cbc10bb6c32da3b7238cff8c1352d6325668fd21b4e82620c2e75ee0c4b1aff6fb1e9b948bbdb1af83cecdf356299b50543b72f801b6a58444b176e4369e0 -B = 5f64ca1ba481f42c4c9cf1ffa0e515b52aa9d69ceb97c4a2897f2e9fa87f72bae56ee6c5227f354304994c6a5cc742d9f09b2c058521975f69ca5835bce898cf22b28457cd7e28870df14e663bb46c9be8f6662f4ff34d5c4ae17a888eba504e -LCM = c163cb28642e19a40aa77887c63180c2c49fc10cda98f6f929c8131752ea30b5283a814a81681b69b9d1762e6c1a9db85f480bc17f998d235fd7e64c1caa70ef170c9e816d3e80f516b29f2c80cfb68bf208b4d5082ef078da4314b3f20c7d6c54b0aeb378096b029a7b61c0a4cd14aeddc01004c53915a4f692d2291752e5af46b23d7fa6dd61f2d56c6f4bf8e6119688abac8fd7aba80e846a7764bb3fca0 - -GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -A = 0 -B = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -LCM = 0 - -GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -A = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -B = 0 -LCM = 0 - -GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -A = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -B = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 -LCM = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 - -GCD = 120451d8307219aa0c96f328ad653ccd462e92423ca93ed8a3dde45bf5cb9b13cdaf9800e4d05dd71c4db6a129fb3280ee4ec96ec5297d881c1a8b5efccbd91fef21f5c5bf5fba42a4c8eaa358f620a074b7a17054527bdaa58d5acaa0dfdc48ecba1a10ebf4d57bb4215de406e6be13fed3fe493b1cd1e2d11a8d4ac03c47756 -A = 3f8179a8e1f0b342475a855c3e1bae402dd41424cf24a0b4d2e263c8efb08bde7d92eae8607fb5e88b1378f0f1bd0733f229a35be6b1383a48d32749d5d6b32427d26323b7ab05bb5781289e96bfbc21971439319b15f6c0fe93fdb35d0b67ec41443c59a081dd3cef047ac797fccb45bece84c0bb0bb7e1797259526d8ec9cc63ba4d32cfc692ccd3d243cb2b53ac216312f3a8e8c0daa09d21b6150d697639a5e52059414a417c607be8ec0eee2e708219cadbaf37a369c4485b01ed87bbc2 -B = 2c474e396a2dd9cd10b9d7313f69d3b4ca123e9fd853edd488339236d14c56453a1381958864a04d2624e81995dabcdd0ccf60db9917813f887de68da075d0ea4440001e18f470e43b38ee3440b49be651d709fbdef980e3e4149913f4ae2681124f54523f4881376ddb533b5219e804cc26f4c2e577be4e02613c4da80ba1215775b0a5178a965ad47bd2befb32493943ded1004ef66347b4983f8d1ba990d4a943505dfce6debcfb322842ed88106cd6dee9aa592ff0d2274bc727a6e1f14c -LCM = 9c129cf649555bfd2d3d9c64dc6d6f022295e53bca5d2f218adaa66aa60eb4694429b7e83bf81b6df4459c5104023ab9a33f006ffcd8114507baa17e2ef6fe23ebdd4740f66879033da2041f2cb7ba517ad3526ffe75614ea9432c085f71b2d65a736bac7ba42b639e330b82733372083843dcb78b6a273ab20e0d4b7c8998a14048aa15bb20a0a0bd997917107274c89b4cec175fb98043d52e6c555bd9e0036566d052a6d4e7e276d1e8835e1f06e3ca46d47747ba586e95fb1a790d992834b7c3e136141eb8a434e6c12067246ac3c0a81c69e03b1ed28aa0b3173d6eff83d278c2f461a47a416f3f9a5dae3bb410fd18817bd4115e7f1e84b936cc02364 - -GCD = 95aa569a2c76854300d7660847dd20fe0b8c445fdbcaa98465cee61aee76ad6a438e75a8c573198570ffb62bc07ec3a2be0ae0a1f631670fa88d6f75f3161e8b9a4d44b6801ffc884c7f469c5ed1f27b1edecce9f2977f9e92d1a3b230492fea7e6f2af739dc158a7fbd29856cbedb57b4119e64b27ab09eb1c2df01507d6e7fd -A = 4c653b5bfec44e9be100c064dffe5d8cd59b0cf4cc56b03eabb4ef87cfda6506c9a756b811907fe9d8b783eb7a0b9e129773bf1da365ddb488d27b16fb983e89345d1ccdb4f06a67a11925c3f266373be5d7b0075189c6f3c2157e2da197058fe0a7bcc50adc34e99e254a29abbe2d5948d3157e1b0c3fca3d641760f7b9862843b63abef0b3d83fd486f4526b30382fda355575da30e9a106718a3921774c4d69f5311f8d737fe618f5236b4763fe1b2ee7f13184db67367d3903c535ff6d7b -B = 2dcca83c99a28e9fd2f84e78973699baf2f04fd454094730948b22477834a0064817b86e0835e6d7b26e5b0b1dcf4ad91a07ac0780d6522df1fcac758cf5db6c2a5623d7c0f1afefd5718f7b6de639867d07a9ec525991304e9355d1635104bea837f74758d6aa2aab4e4afbb606af1d98de7417505e4710cd0589bdff9a0bf38a857cc59a5f1781043e694fc2337fd84bdeb28b13a222bb09328a81ec409ad586e74236393d27398cc24d412135e34247c589149e134b97f4bd538ac9a3424b -LCM = 1760c0b0066aa0695767099e87e9388729ea89b8e8c36bddcd04d257591e741613c07b0e69447c0a468c33a745084171e06523d987d8db40a1433bf435325e8a724a0876503b34495170ff3671d42117a2e4f3a75b1d9dd809a34fa0fb26fe50d84f80a9b02e40190e5efb927a5a61a03f13edbce2e666af6c3a2a9bcb84e47e3090008753ff27c4b8cf06480f471379a93f5230923623a83b286b71a555cd5e5347282f664ed90b14b2c4de84a70375e488211a7b3931119ef3bbe029b712389fe784818a0bf29d80733ce9cc940c547aa1eb3f06d492eb676bf37802283c82ce76156dfaab5c2d5107e08062681b5fa169f6eb68e1ab8bd9b2005e90bd4fd - -GCD = 244b9b1290cf5b4ba2f810574c050651489f2d3a2b03e702b76ebfaf4e33de9bbe5da24c919e68d3a72eadd35982b3a89c6b18b38ff7082ac65263e52b6ec75a5717b971c98257b194c828bff0216a99536603b41a396ea2fb50f5ea7cf3edf10bb0d039123e78593ae9ffcbbba02e51e038533e83b6bc73c70551d6467f39809 -A = 41a0b1310669500681cdf888836f6c556758750f562d743ac780dd4c0d161856380e44fdbb1f8a2786bf45be6b0e7f1cb2cd85f6b9e50acc72793d92383c7d7fb796fc74d32e8fac8225bdc19ae47546d9c9c75f5f06ca684f07daccaf89ccf2cddeb7ec255d530c7dd1e71daf44cafdc9d30fbcb1cbaefae3480585f79f4177e3834a5bc91845e2e8cd8aeb27f484e5e5b2c3c076dbb6c23e91303f0a0fdde83cd33a8ea6ed1549e727b4d766c1017c169710fd98e1585d60f66e121f9180b3 -B = 251f5aeaa60b3959285f49540cdaf8e21451110bbddb9933bbbcaea3112f4eb45e435a3ba37c52d2ab79ce997a8f6c829b3aa561f2852924b8effb52396d09d2bf257ebb4fb56c7aa25648f69b06d2cd01e876c9f9c0679de9e6fffa79eb7e603723e5af7de46ee405a5a079229577b5b6fffb8d43e391fe6f4eb89638e64d6eff8026249aaa355a91625eb0bfd14caa81e4c3586aaa2e94fde143a44f223a91e226661d12f55dfcdb4215e5a64e14e968005733be6a71c465de312ca109b34a -LCM = 431f918b274f3e43f446e4e85567883d6536a0332db662cef088f5a36b0f4b68372048174ba10fee94b9f8f1c2e189c974be2e6e8ae8e2ae108445326d40f63e38d8d4e2e46174589a3cbc9583e0036dc8146e79eee9e96f4436313b3f143dd0f5aceab05243def7f915169c360f55ef123977cf623c5ba432c3259c62fb5e37d5adab0f24b825aa4ada99ec4e83e9ca4698399e1ed633091ce5f9844c540a642cd264201116ed4168aa2105a5159f5df064f845830c469140f766c7319052ce59bd1ad7c3f2d8c30e54f147f6aeb5586c70c984302ba18d854a60aec01b394c7d66fa33fe18fe4a8cfb3238df219294e6e42190a30d28b10049a1b75853a4e - -GCD = 206695d52bc391a4db61bf8cb6ea96188333a9c78f477ee76976c2346dad682cf56ca6f176d86ef67d41ff5921b6162b0eca52359975872430dd14c45643eacdf028d830770714c033fd150669705851b2f02de932322d271d565d26768530c3f6cb84f0b3356f970b9070b26c050ead0417152c324c8ffe266d4e8b5b7bef3a -A = 1114eb9f1a9d5947eb1399e57f5c980833489685023ed2fe537fe1276c1e026b9a19e6fff55aa889d6c4e977b6e6f3111e2ad463138637b50f42cf32e57d83f282de9e72f813e5969195159a666d74dcd689bd527c60199ae327f7bd548ac36868fea5fdf6f35d19b921e7c10b6448ca480de6826478cd0642d72f05af3f8e65ce42409fbd49f56e81946e89c8e83962c4edc0ed54600600a305e52d081aed3c351e450e11f8fb0ce5754c92cf765b71393b2b7a89c95df79b9ea1b3cb600862 -B = 1d8f3179ca7b5cc7119360c10de939ffa57c9043da2f2b0ca3009c9bdad9f19ed16e3c2c197bef4b527fa1bf2bbab98b77e26c329911db68bd63d3d0fbfc727a977395b9ad067106de3094d68e097830858c5ccfa505fc25e972bdee6f347e7d1163efacd3d29a791ec2a94ffeed467884ae04896efc5e7e5f43d8d76c147e3c9951a1999173bc4e5767d51268b92cc68487ba1295372143b538711e0a62bf0ac111cc750ca4dd6c318c9cbe106d7fc492261404b86a1ba728e2d25b1976dc42 -LCM = f9570211f694141bfb096560551080cbe02a80271b4505591aaea9e3b99ea1d5ac1c1f2378fd72799e117ac2a73381b1ad26314e39972164d93971479ee3ba21a4d98cef0bd299d540ce5826995dcee0de420dff73d30b23cbf3188c625c7696df517535bc5675d71faa00807efbebdca547933f4a37849d1c014484a77da6df0670c4974bcc91eb5f5fe5faf9dd095ef195ec32ad9eeebf0e63288b4032ed9e70b888afc642f4ff96f0b4c0a68787301c12e4527fe79bdfe72dd3844ab5e094a9295df6616f24d1b9eeebc2116177dacf91969dda73667bc421ef3ccd8d5c23dddc283f5d36568d31f2654926be67f78e181075bdc148f2b39c630b141ae8a - -GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -A = 0 -B = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -LCM = 0 - -GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -A = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -B = 0 -LCM = 0 - -GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -A = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -B = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 -LCM = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 - -GCD = 2 -A = 14e95a85e59ade9ef39e2f400c65db18702fa5fc485b9bba479a5282b2206129160e54f73ef4917983c17b4c5ebff7be112a886de069706eee29ba902515cb038 -B = ddcfff1d39c90c599f55495bf71c1e7597c6b08b7430707f360c6a6e5137bbc7b403c6d9e2c34f3d2f29d5d32b869346853c2de239cc35381bdfb4a01569211a -LCM = 90f38564ee72e55d362c04599e7d74f068c75f541b84e97abba2841f1a9f66b06b5c9009f6a4c2e319fced85270588de03ccebddbd9279aaecb13bdc1dbea7f42acaee751cb7da83779b8785cc86f41b94b13b54964208ca287d981634778d1096f20e76ca636c0717fd27e0800c43f599a5eded807421b502eaf9990a8c8ed8 - -GCD = 4 -A = 3c719c1c363cdeb7b57c2aabb71f425da4c3e6d3e447204d555e7cf0f3d372bdda906f36078045044978dafc20171767c8b1464d52dfdf3e2ba8a4906da033a8 -B = 30fe0ef151ac51404e128c064d836b191921769dc02d9b09889ed40eb68d15bfdd2edea33580a1a4d7dcee918fefd5c776cbe80ca6131aa080d3989b5e77e1b24 -LCM = 2e4526157bbd765b0486d90bcd4728f890bc6dbd9a855c67ca5cb2d6b48f8e74e1d99485999e04b193afca58dbf282610185d6c0272007744ff26e00dbdc813929b47940b137dc56ba974da07d54a1c50ec4a5c2b26e83f47cf17f4ccce8c3687e8d1e91d7c491a599f3d057c73473723ce9eee52c20fe8ae1595447552a7ee8 - -GCD = 10 -A = 44e04071d09119ea9783a53df35de4a989200133bb20280fdca6003d3ca63fdd9350ad1a1673d444d2f7c7be639824681643ec4f77535c626bd3ee8fa100e0bb0 -B = ca927a5a3124ce89accd6ac41a8441d352a5d42feb7f62687a5ebc0e181cc2679888ecc2d38516bdc3b3443550efccac81e53044ae9341ecace2598fe5ce67780 -LCM = 36805ba9b2412a0cb3fe4ed9bdabfa55515c9d615a3d0af268c45c5f6098d2de4a583f3791f1e3883c55d51ce23c5658fd0e8faa9a3709a1cfbd6a61dbab861690f27c86664f084c86cfd4a183b24aaadf59a6f8cbec04f1b0ded8a59b188cb46ae920052e3e099a570540dbc00f7d4a571eef08aa70d2d189a1804bf04e94a80 - -GCD = 100 -A = 73725032b214a677687c811031555b0c51c1703f10d59b97a4d732b7feaec5726cb3882193419d3f057583b2bc02b297d76bb689977936febaae92638fdfc46a00 -B = 979f4c10f4dc60ad15068cedd62ff0ab293aeaa1d6935763aed41fe3e445de2e366e8661eadf345201529310f4b805c5800b99f351fddab95d7f313e3bb429d900 -LCM = 4460439b4be72f533e9c7232f7e99c48328b457969364c951868ceab56cb2cbbeda8be2e8e3cae45c0758048468b841fdb246b2086d19b59d17b389333166ab82ed785860620d53c44f7aaaff4625ee70fb8072df10fb4d1acb142eadc02978ff2bb07cea9f434e35424b3323a7bda3a1a57aa60c75e49ebb2f59fb653aa77da00 - -GCD = 100000000 -A = f8b4f19e09f5862d79fb2931c4d616a1b8e0dd44781ca52902c8035166c8fca52d33a56ff484c365ec1257de7fa8ed2786163cfc051d5223b4aad859a049e8ba00000000 -B = 6e54cb41b454b080e68a2c3dd0fa79f516eb80239af2be8250ca9cd377ba501aabafc09146fad4402bdc7a49f2c3eec815e25f4c0a223f58e36709eefd92410500000000 -LCM = 6b3020a880ddeff9d17d3dc234da8771962de3322cd15ba7b1e4b1dd4a6a2a802a16c49653865c6fdf6c207cbe0940f8d81ef4cb0e159385fd709d515ee99d109ad9ad680031cbae4eab2ed62944babdade4e3036426b18920022f737897c7d751dce98d626cdda761fec48ad87a377fb70f97a0a15aa3d10d865785719cc5a200000000 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bytes.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bytes.c index 56241e3b..331e0859 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bytes.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/bytes.c @@ -61,19 +61,38 @@ #include "internal.h" +void bn_big_endian_to_words(BN_ULONG *out, size_t out_len, const uint8_t *in, + size_t in_len) { + for (size_t i = 0; i < out_len; i++) { + if (in_len < sizeof(BN_ULONG)) { + // Load the last partial word. + BN_ULONG word = 0; + for (size_t j = 0; j < in_len; j++) { + word = (word << 8) | in[j]; + } + in_len = 0; + out[i] = word; + // Fill the remainder with zeros. + OPENSSL_memset(out + i + 1, 0, (out_len - i - 1) * sizeof(BN_ULONG)); + break; + } -BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { - size_t num_words; - unsigned m; - BN_ULONG word = 0; - BIGNUM *bn = NULL; - - if (ret == NULL) { - ret = bn = BN_new(); + in_len -= sizeof(BN_ULONG); + out[i] = CRYPTO_load_word_be(in + in_len); } + // The caller should have sized the output to avoid truncation. + assert(in_len == 0); +} + +BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + BIGNUM *bn = NULL; if (ret == NULL) { - return NULL; + bn = BN_new(); + if (bn == NULL) { + return NULL; + } + ret = bn; } if (len == 0) { @@ -81,12 +100,9 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { return ret; } - num_words = ((len - 1) / BN_BYTES) + 1; - m = (len - 1) % BN_BYTES; + size_t num_words = ((len - 1) / BN_BYTES) + 1; if (!bn_wexpand(ret, num_words)) { - if (bn) { - BN_free(bn); - } + BN_free(bn); return NULL; } @@ -96,15 +112,7 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { ret->width = (int)num_words; ret->neg = 0; - while (len--) { - word = (word << 8) | *(in++); - if (m-- == 0) { - ret->d[--num_words] = word; - word = 0; - m = BN_BYTES - 1; - } - } - + bn_big_endian_to_words(ret->d, ret->width, in, len); return ret; } @@ -112,13 +120,12 @@ BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { BIGNUM *bn = NULL; if (ret == NULL) { bn = BN_new(); + if (bn == NULL) { + return NULL; + } ret = bn; } - if (ret == NULL) { - return NULL; - } - if (len == 0) { ret->width = 0; ret->neg = 0; @@ -131,7 +138,7 @@ BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { BN_free(bn); return NULL; } - ret->width = num_words; + ret->width = (int)num_words; // Make sure the top bytes will be zeroed. ret->d[num_words - 1] = 0; @@ -142,38 +149,70 @@ BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { return ret; } -size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) { - size_t n, i; - BN_ULONG l; - - n = i = BN_num_bytes(in); - while (i--) { - l = in->d[i / BN_BYTES]; - *(out++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; - } - return n; -} - -static int fits_in_bytes(const uint8_t *bytes, size_t num_bytes, size_t len) { +// fits_in_bytes returns one if the |num_words| words in |words| can be +// represented in |num_bytes| bytes. +static int fits_in_bytes(const BN_ULONG *words, size_t num_words, + size_t num_bytes) { + const uint8_t *bytes = (const uint8_t *)words; + size_t tot_bytes = num_words * sizeof(BN_ULONG); uint8_t mask = 0; - for (size_t i = len; i < num_bytes; i++) { + for (size_t i = num_bytes; i < tot_bytes; i++) { mask |= bytes[i]; } return mask == 0; } -int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { - const uint8_t *bytes = (const uint8_t *)in->d; - size_t num_bytes = in->width * BN_BYTES; - if (len < num_bytes) { - if (!fits_in_bytes(bytes, num_bytes, len)) { - return 0; +void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num) { + const uint8_t *bytes = (const uint8_t *)bn->d; + size_t tot_bytes = bn->width * sizeof(BN_ULONG); + if (tot_bytes > num) { + CONSTTIME_DECLASSIFY(bytes + num, tot_bytes - num); + for (size_t i = num; i < tot_bytes; i++) { + assert(bytes[i] == 0); } - num_bytes = len; + (void)bytes; + } +} + +void bn_words_to_big_endian(uint8_t *out, size_t out_len, const BN_ULONG *in, + size_t in_len) { + // The caller should have selected an output length without truncation. + assert(fits_in_bytes(in, in_len, out_len)); + + // We only support little-endian platforms, so the internal representation is + // also little-endian as bytes. We can simply copy it in reverse. + const uint8_t *bytes = (const uint8_t *)in; + size_t num_bytes = in_len * sizeof(BN_ULONG); + if (out_len < num_bytes) { + num_bytes = out_len; + } + + for (size_t i = 0; i < num_bytes; i++) { + out[out_len - i - 1] = bytes[i]; + } + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out, 0, out_len - num_bytes); +} + +size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) { + size_t n = BN_num_bytes(in); + bn_words_to_big_endian(out, n, in->d, in->width); + return n; +} + +int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { + if (!fits_in_bytes(in->d, in->width, len)) { + return 0; } // We only support little-endian platforms, so we can simply memcpy into the // internal representation. + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + num_bytes = len; + } + OPENSSL_memcpy(out, bytes, num_bytes); // Pad out the rest of the buffer with zeroes. OPENSSL_memset(out + num_bytes, 0, len - num_bytes); @@ -181,22 +220,11 @@ int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { } int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) { - const uint8_t *bytes = (const uint8_t *)in->d; - size_t num_bytes = in->width * BN_BYTES; - if (len < num_bytes) { - if (!fits_in_bytes(bytes, num_bytes, len)) { - return 0; - } - num_bytes = len; + if (!fits_in_bytes(in->d, in->width, len)) { + return 0; } - // We only support little-endian platforms, so we can simply write the buffer - // in reverse. - for (size_t i = 0; i < num_bytes; i++) { - out[len - i - 1] = bytes[i]; - } - // Pad out the rest of the buffer with zeroes. - OPENSSL_memset(out, 0, len - num_bytes); + bn_words_to_big_endian(out, len, in->d, in->width); return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/check_bn_tests.go b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/check_bn_tests.go index 26443b93..032b9e32 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/check_bn_tests.go +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/check_bn_tests.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -135,7 +137,7 @@ func checkKeys(t test, keys ...string) bool { } } - for k, _ := range t.Values { + for k := range t.Values { var found bool for _, k2 := range keys { if k == k2 { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/cmp.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/cmp.c index fe478b60..84456a21 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/cmp.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/cmp.c @@ -56,8 +56,9 @@ #include +#include + #include -#include #include "internal.h" #include "../../internal.h" @@ -65,8 +66,8 @@ static int bn_cmp_words_consttime(const BN_ULONG *a, size_t a_len, const BN_ULONG *b, size_t b_len) { - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); int ret = 0; // Process the common words in little-endian order. size_t min = a_len < b_len ? a_len : b_len; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/ctx.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/ctx.c index f8c7ebfa..00731611 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/ctx.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/ctx.c @@ -108,7 +108,6 @@ struct bignum_ctx { BN_CTX *BN_CTX_new(void) { BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); if (!ret) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } @@ -162,7 +161,6 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) { if (ctx->bignums == NULL) { ctx->bignums = sk_BIGNUM_new_null(); if (ctx->bignums == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); ctx->error = 1; return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div.c index 02b9931c..6c137169 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div.c @@ -552,7 +552,7 @@ static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) { return NULL; } ret->neg = 0; - ret->width = width; + ret->width = (int)width; return ret; } @@ -711,15 +711,22 @@ int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx) { - if (!BN_copy(r, a)) { + if (!BN_copy(r, a) || + !bn_resize_words(r, m->width)) { return 0; } - for (int i = 0; i < n; i++) { - if (!bn_mod_lshift1_consttime(r, r, m, ctx)) { - return 0; + + BN_CTX_start(ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = tmp != NULL; + if (ok) { + for (int i = 0; i < n; i++) { + bn_mod_add_words(r->d, r->d, r->d, m->d, tmp->d, m->width); } + r->neg = 0; } - return 1; + BN_CTX_end(ctx); + return ok; } int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div_extra.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div_extra.c index 7f03f28d..141f7da6 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div_extra.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/div_extra.c @@ -70,7 +70,7 @@ uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d) { // This operation is not constant-time, but |p| and |d| are public values. // Note that |p| is at most 16, so the computation fits in |uint64_t|. assert(p <= 16); - uint32_t m = ((UINT64_C(1) << (32 + p)) + d - 1) / d; + uint32_t m = (uint32_t)(((UINT64_C(1) << (32 + p)) + d - 1) / d); uint16_t ret = 0; for (int i = bn->width - 1; i >= 0; i--) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/exponentiation.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/exponentiation.c index a0f2549e..41c72335 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/exponentiation.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/exponentiation.c @@ -109,10 +109,10 @@ #include #include +#include #include #include -#include #include #include @@ -397,7 +397,7 @@ err: // // (with draws in between). Very small exponents are often selected // with low Hamming weight, so we use w = 1 for b <= 23. -static int BN_window_bits_for_exponent_size(int b) { +static int BN_window_bits_for_exponent_size(size_t b) { if (b > 671) { return 6; } @@ -444,6 +444,7 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, return BN_one(r); } + BN_RECP_CTX_init(&recp); BN_CTX_start(ctx); aa = BN_CTX_get(ctx); val[0] = BN_CTX_get(ctx); @@ -451,7 +452,6 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, goto err; } - BN_RECP_CTX_init(&recp); if (m->neg) { // ignore sign of 'm' if (!BN_copy(aa, m)) { @@ -594,7 +594,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); return 0; } - if (a->neg || BN_ucmp(a, m) >= 0) { + // |a| is secret, but |a < m| is not. + if (a->neg || constant_time_declassify_int(BN_ucmp(a, m)) >= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); return 0; } @@ -722,12 +723,14 @@ err: void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, const BN_ULONG *p, size_t num_p, const BN_MONT_CTX *mont) { - if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS) { + if (num != (size_t)mont->N.width || num > BN_SMALL_MAX_WORDS || + num_p > ((size_t)-1) / BN_BITS2) { abort(); } assert(BN_is_odd(&mont->N)); - // Count the number of bits in |p|. Note this function treats |p| as public. + // Count the number of bits in |p|, skipping leading zeros. Note this function + // treats |p| as public. while (num_p != 0 && p[num_p - 1] == 0) { num_p--; } @@ -735,7 +738,7 @@ void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, bn_from_montgomery_small(r, num, mont->RR.d, num, mont); return; } - unsigned bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; + size_t bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; assert(bits != 0); // We exponentiate by looking at sliding windows of the exponent and @@ -759,7 +762,7 @@ void bn_mod_exp_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, // |p| is non-zero, so at least one window is non-zero. To save some // multiplications, defer initializing |r| until then. int r_is_one = 1; - unsigned wstart = bits - 1; // The top bit of the window. + size_t wstart = bits - 1; // The top bit of the window. for (;;) { if (!bn_is_bit_set_words(p, num_p, wstart)) { if (!r_is_one) { @@ -849,7 +852,11 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, OPENSSL_memset(b->d, 0, sizeof(BN_ULONG) * top); const int width = 1 << window; for (int i = 0; i < width; i++, table += top) { - BN_ULONG mask = constant_time_eq_int(i, idx); + // Use a value barrier to prevent Clang from adding a branch when |i != idx| + // and making this copy not constant time. Clang is still allowed to learn + // that |mask| is constant across the inner loop, so this won't inhibit any + // vectorization it might do. + BN_ULONG mask = value_barrier_w(constant_time_eq_int(i, idx)); for (int j = 0; j < top; j++) { b->d[j] |= table[j] & mask; } @@ -859,40 +866,15 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, return 1; } -#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK \ - (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) - // Window sizes optimized for fixed window size modular exponentiation // algorithm (BN_mod_exp_mont_consttime). // -// To achieve the security goals of BN_mode_exp_mont_consttime, the maximum -// size of the window must not exceed -// log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). -// -// Window size thresholds are defined for cache line sizes of 32 and 64, cache -// line sizes where log_2(32)=5 and log_2(64)=6 respectively. A window size of -// 7 should only be used on processors that have a 128 byte or greater cache -// line size. -#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 - +// TODO(davidben): These window sizes were originally set for 64-byte cache +// lines with a cache-line-dependent constant-time mitigation. They can probably +// be revised now that our implementation is no longer cache-time-dependent. #define BN_window_bits_for_ctime_exponent_size(b) \ ((b) > 937 ? 6 : (b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) -#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) - -#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 - -#define BN_window_bits_for_ctime_exponent_size(b) \ - ((b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1) -#define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) - -#endif - -// Given a pointer value, compute the next address that is a cache line -// multiple. -#define MOD_EXP_CTIME_ALIGN(x_) \ - ((unsigned char *)(x_) + \ - (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - \ - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) +#define BN_MAX_MOD_EXP_CTIME_WINDOW (6) // This variant of |BN_mod_exp_mont| uses fixed windows and fixed memory access // patterns to protect secret exponents (cf. the hyper-threading timing attacks @@ -901,14 +883,12 @@ static int copy_from_prebuf(BIGNUM *b, int top, const BN_ULONG *table, int idx, int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { - int i, ret = 0, window, wvalue; + int i, ret = 0, wvalue; BN_MONT_CTX *new_mont = NULL; - int numPowers; - unsigned char *powerbufFree = NULL; - int powerbufLen = 0; + unsigned char *powerbuf_free = NULL; + size_t powerbuf_len = 0; BN_ULONG *powerbuf = NULL; - BIGNUM tmp, am; if (!BN_is_odd(m)) { OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); @@ -954,8 +934,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, // paths. If we were to use separate static buffers for each then there is // some chance that both large buffers would be allocated on the stack, // causing the stack space requirement to be truly huge (~10KB). - alignas(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH) BN_ULONG - storage[MOD_EXP_CTIME_STORAGE_LEN]; + alignas(MOD_EXP_CTIME_ALIGN) BN_ULONG storage[MOD_EXP_CTIME_STORAGE_LEN]; #endif #if defined(RSAZ_ENABLED) // If the size of the operands allow it, perform the optimized RSAZ @@ -976,112 +955,115 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, #endif // Get the window size to use with size of p. - window = BN_window_bits_for_ctime_exponent_size(bits); + int window = BN_window_bits_for_ctime_exponent_size(bits); + assert(window <= BN_MAX_MOD_EXP_CTIME_WINDOW); + + // Calculating |powerbuf_len| below cannot overflow because of the bound on + // Montgomery reduction. + assert((size_t)top <= BN_MONTGOMERY_MAX_WORDS); + static_assert( + BN_MONTGOMERY_MAX_WORDS <= + INT_MAX / sizeof(BN_ULONG) / ((1 << BN_MAX_MOD_EXP_CTIME_WINDOW) + 3), + "powerbuf_len may overflow"); + #if defined(OPENSSL_BN_ASM_MONT5) if (window >= 5) { window = 5; // ~5% improvement for RSA2048 sign, and even for RSA4096 - // reserve space for mont->N.d[] copy - powerbufLen += top * sizeof(mont->N.d[0]); + // Reserve space for the |mont->N| copy. + powerbuf_len += top * sizeof(mont->N.d[0]); } #endif // Allocate a buffer large enough to hold all of the pre-computed - // powers of am, am itself and tmp. - numPowers = 1 << window; - powerbufLen += - sizeof(m->d[0]) * - (top * numPowers + ((2 * top) > numPowers ? (2 * top) : numPowers)); + // powers of |am|, |am| itself, and |tmp|. + int num_powers = 1 << window; + powerbuf_len += sizeof(m->d[0]) * top * (num_powers + 2); #if defined(OPENSSL_BN_ASM_MONT5) - if ((size_t)powerbufLen <= sizeof(storage)) { + if (powerbuf_len <= sizeof(storage)) { powerbuf = storage; } // |storage| is more than large enough to handle 1024-bit inputs. assert(powerbuf != NULL || top * BN_BITS2 > 1024); #endif if (powerbuf == NULL) { - powerbufFree = - OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); - if (powerbufFree == NULL) { + powerbuf_free = OPENSSL_malloc(powerbuf_len + MOD_EXP_CTIME_ALIGN); + if (powerbuf_free == NULL) { goto err; } - powerbuf = (BN_ULONG *)MOD_EXP_CTIME_ALIGN(powerbufFree); + powerbuf = align_pointer(powerbuf_free, MOD_EXP_CTIME_ALIGN); } - OPENSSL_memset(powerbuf, 0, powerbufLen); + OPENSSL_memset(powerbuf, 0, powerbuf_len); - // lay down tmp and am right after powers table - tmp.d = powerbuf + top * numPowers; + // Place |tmp| and |am| right after powers table. + BIGNUM tmp, am; + tmp.d = powerbuf + top * num_powers; am.d = tmp.d + top; tmp.width = am.width = 0; tmp.dmax = am.dmax = top; tmp.neg = am.neg = 0; tmp.flags = am.flags = BN_FLG_STATIC_DATA; - if (!bn_one_to_montgomery(&tmp, mont, ctx)) { + if (!bn_one_to_montgomery(&tmp, mont, ctx) || + !bn_resize_words(&tmp, top)) { goto err; } - // prepare a^1 in Montgomery domain + // Prepare a^1 in the Montgomery domain. assert(!a->neg); assert(BN_ucmp(a, m) < 0); - if (!BN_to_montgomery(&am, a, mont, ctx)) { + if (!BN_to_montgomery(&am, a, mont, ctx) || + !bn_resize_words(&am, top)) { goto err; } #if defined(OPENSSL_BN_ASM_MONT5) - // This optimization uses ideas from http://eprint.iacr.org/2011/239, - // specifically optimization of cache-timing attack countermeasures - // and pre-computation optimization. - - // Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as - // 512-bit RSA is hardly relevant, we omit it to spare size... + // This optimization uses ideas from https://eprint.iacr.org/2011/239, + // specifically optimization of cache-timing attack countermeasures, + // pre-computation optimization, and Almost Montgomery Multiplication. + // + // The paper discusses a 4-bit window to optimize 512-bit modular + // exponentiation, used in RSA-1024 with CRT, but RSA-1024 is no longer + // important. + // + // |bn_mul_mont_gather5| and |bn_power5| implement the "almost" reduction + // variant, so the values here may not be fully reduced. They are bounded by R + // (i.e. they fit in |top| words), not |m|. Additionally, we pass these + // "almost" reduced inputs into |bn_mul_mont|, which implements the normal + // reduction variant. Given those inputs, |bn_mul_mont| may not give reduced + // output, but it will still produce "almost" reduced output. + // + // TODO(davidben): Using "almost" reduction complicates analysis of this code, + // and its interaction with other parts of the project. Determine whether this + // is actually necessary for performance. if (window == 5 && top > 1) { - const BN_ULONG *n0 = mont->n0; - BN_ULONG *np; - - // BN_to_montgomery can contaminate words above .top - // [in BN_DEBUG[_DEBUG] build]... - for (i = am.width; i < top; i++) { - am.d[i] = 0; - } - for (i = tmp.width; i < top; i++) { - tmp.d[i] = 0; - } - - // copy mont->N.d[] to improve cache locality - for (np = am.d + top, i = 0; i < top; i++) { + // Copy |mont->N| to improve cache locality. + BN_ULONG *np = am.d + top; + for (i = 0; i < top; i++) { np[i] = mont->N.d[i]; } + // Fill |powerbuf| with the first 32 powers of |am|. + const BN_ULONG *n0 = mont->n0; bn_scatter5(tmp.d, top, powerbuf, 0); bn_scatter5(am.d, am.width, powerbuf, 1); bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, 2); - // same as above, but uses squaring for 1/2 of operations + // Square to compute powers of two. for (i = 4; i < 32; i *= 2) { bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, i); } - for (i = 3; i < 8; i += 2) { - int j; + // Compute odd powers |i| based on |i - 1|, then all powers |i * 2^j|. + for (i = 3; i < 32; i += 2) { bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); bn_scatter5(tmp.d, top, powerbuf, i); - for (j = 2 * i; j < 32; j *= 2) { + for (int j = 2 * i; j < 32; j *= 2) { bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, j); } } - for (; i < 16; i += 2) { - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_scatter5(tmp.d, top, powerbuf, 2 * i); - } - for (; i < 32; i += 2) { - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - } bits--; for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) { @@ -1138,15 +1120,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val); } } - - ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); - tmp.width = top; - if (ret) { - if (!BN_copy(rr, &tmp)) { - ret = 0; - } - goto err; // non-zero ret means it's not error - } + // The result is now in |tmp| in Montgomery form, but it may not be fully + // reduced. This is within bounds for |BN_from_montgomery| (tmp < R <= m*R) + // so it will, when converting from Montgomery form, produce a fully reduced + // result. + // + // This differs from Figure 2 of the paper, which uses AMM(h, 1) to convert + // from Montgomery form with unreduced output, followed by an extra + // reduction step. In the paper's terminology, we replace steps 9 and 10 + // with MM(h, 1). } else #endif { @@ -1164,7 +1146,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, copy_to_prebuf(&tmp, top, powerbuf, 2, window); - for (i = 3; i < numPowers; i++) { + for (i = 3; i < num_powers; i++) { // Calculate a^i = a^(i-1) * a if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) { goto err; @@ -1207,7 +1189,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, } } - // Convert the final result from montgomery to standard format + // Convert the final result from Montgomery to standard format. If we used the + // |OPENSSL_BN_ASM_MONT5| codepath, |tmp| may not be fully reduced. It is only + // bounded by R rather than |m|. However, that is still within bounds for + // |BN_from_montgomery|, which implements full Montgomery reduction, not + // "almost" Montgomery reduction. if (!BN_from_montgomery(rr, &tmp, mont, ctx)) { goto err; } @@ -1215,11 +1201,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, err: BN_MONT_CTX_free(new_mont); - if (powerbuf != NULL && powerbufFree == NULL) { - OPENSSL_cleanse(powerbuf, powerbufLen); + if (powerbuf != NULL && powerbuf_free == NULL) { + OPENSSL_cleanse(powerbuf, powerbuf_len); } - OPENSSL_free(powerbufFree); - return (ret); + OPENSSL_free(powerbuf_free); + return ret; } int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd.c index bd0fa6f5..df12569a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd.c @@ -263,15 +263,14 @@ int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, // Now Y*a == A (mod |n|). // Y*a == 1 (mod |n|) - if (!Y->neg && BN_ucmp(Y, n) < 0) { - if (!BN_copy(R, Y)) { - goto err; - } - } else { - if (!BN_nnmod(R, Y, n, ctx)) { + if (Y->neg || BN_ucmp(Y, n) >= 0) { + if (!BN_nnmod(Y, Y, n, ctx)) { goto err; } } + if (!BN_copy(R, Y)) { + goto err; + } ret = 1; @@ -286,7 +285,6 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, if (out == NULL) { new_out = BN_new(); if (new_out == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } out = new_out; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd_extra.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd_extra.c index 53ab1705..b4fe00e3 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd_extra.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/gcd_extra.c @@ -240,8 +240,10 @@ int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, // Each loop iteration halves at least one of |u| and |v|. Thus we need at // most the combined bit width of inputs for at least one value to be zero. - unsigned a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2; - unsigned num_iters = a_bits + n_bits; + // |a_bits| and |n_bits| cannot overflow because |bn_wexpand| ensures bit + // counts fit in even |int|. + size_t a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2; + size_t num_iters = a_bits + n_bits; if (num_iters < a_bits) { OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); goto err; @@ -260,7 +262,7 @@ int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, // // After each loop iteration, u and v only get smaller, and at least one of // them shrinks by at least a factor of two. - for (unsigned i = 0; i < num_iters; i++) { + for (size_t i = 0; i < num_iters; i++) { BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); // If both |u| and |v| are odd, subtract the smaller from the larger. diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/generic.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/generic.c index ee80a3ce..e4f4518e 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/generic.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/generic.c @@ -61,11 +61,25 @@ #include "internal.h" -// This file has two other implementations: x86 assembly language in -// asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. -#if defined(OPENSSL_NO_ASM) || \ - !(defined(OPENSSL_X86) || \ - (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__)))) +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) +// See asm/bn-586.pl. +#define BN_ADD_ASM +#define BN_MUL_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) +// See asm/x86_64-gcc.c +#define BN_ADD_ASM +#define BN_MUL_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) +// See asm/bn-armv8.pl. +#define BN_ADD_ASM +#endif + +#if !defined(BN_MUL_ASM) #ifdef BN_ULLONG #define mul_add(r, a, w, c) \ @@ -201,157 +215,6 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { } } -#ifdef BN_ULLONG -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULLONG ll = 0; - - if (n == 0) { - return 0; - } - - while (n & ~3) { - ll += (BN_ULLONG)a[0] + b[0]; - r[0] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[1] + b[1]; - r[1] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[2] + b[2]; - r[2] = (BN_ULONG)ll; - ll >>= BN_BITS2; - ll += (BN_ULLONG)a[3] + b[3]; - r[3] = (BN_ULONG)ll; - ll >>= BN_BITS2; - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - ll += (BN_ULLONG)a[0] + b[0]; - r[0] = (BN_ULONG)ll; - ll >>= BN_BITS2; - a++; - b++; - r++; - n--; - } - return (BN_ULONG)ll; -} - -#else // !BN_ULLONG - -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULONG c, l, t; - - if (n == 0) { - return (BN_ULONG)0; - } - - c = 0; - while (n & ~3) { - t = a[0]; - t += c; - c = (t < c); - l = t + b[0]; - c += (l < t); - r[0] = l; - t = a[1]; - t += c; - c = (t < c); - l = t + b[1]; - c += (l < t); - r[1] = l; - t = a[2]; - t += c; - c = (t < c); - l = t + b[2]; - c += (l < t); - r[2] = l; - t = a[3]; - t += c; - c = (t < c); - l = t + b[3]; - c += (l < t); - r[3] = l; - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - t = a[0]; - t += c; - c = (t < c); - l = t + b[0]; - c += (l < t); - r[0] = l; - a++; - b++; - r++; - n--; - } - return (BN_ULONG)c; -} - -#endif // !BN_ULLONG - -BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - size_t n) { - BN_ULONG t1, t2; - int c = 0; - - if (n == 0) { - return (BN_ULONG)0; - } - - while (n & ~3) { - t1 = a[0]; - t2 = b[0]; - r[0] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[1]; - t2 = b[1]; - r[1] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[2]; - t2 = b[2]; - r[2] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - t1 = a[3]; - t2 = b[3]; - r[3] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - a += 4; - b += 4; - r += 4; - n -= 4; - } - while (n) { - t1 = a[0]; - t2 = b[0]; - r[0] = t1 - t2 - c; - if (t1 != t2) { - c = (t1 < t2); - } - a++; - b++; - r++; - n--; - } - return c; -} - // mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) // mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) // sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) @@ -369,9 +232,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += (hi); \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define mul_add_c2(a, b, c0, c1, c2) \ @@ -382,16 +243,12 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(tt); \ hi = (BN_ULONG)Hw(tt); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ t += (c0); /* no carry */ \ (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define sqr_add_c(a, i, c0, c1, c2) \ @@ -402,9 +259,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, (c0) = (BN_ULONG)Lw(t); \ hi = (BN_ULONG)Hw(t); \ (c1) += hi; \ - if ((c1) < hi) { \ - (c2)++; \ - } \ + (c2) += (c1) < hi; \ } while (0) #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) @@ -708,4 +563,93 @@ void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { #undef sqr_add_c #undef sqr_add_c2 +#endif // !BN_MUL_ASM + +#if !defined(BN_ADD_ASM) + +// bn_add_with_carry returns |x + y + carry|, and sets |*out_carry| to the +// carry bit. |carry| must be zero or one. +static inline BN_ULONG bn_add_with_carry(BN_ULONG x, BN_ULONG y, BN_ULONG carry, + BN_ULONG *out_carry) { + assert(carry == 0 || carry == 1); +#if defined(BN_ULLONG) + BN_ULLONG ret = carry; + ret += (BN_ULLONG)x + y; + *out_carry = (BN_ULONG)(ret >> BN_BITS2); + return (BN_ULONG)ret; +#else + x += carry; + carry = x < carry; + BN_ULONG ret = x + y; + carry += ret < x; + *out_carry = carry; + return ret; #endif +} + +// bn_sub_with_borrow returns |x - y - borrow|, and sets |*out_borrow| to the +// borrow bit. |borrow| must be zero or one. +static inline BN_ULONG bn_sub_with_borrow(BN_ULONG x, BN_ULONG y, + BN_ULONG borrow, + BN_ULONG *out_borrow) { + assert(borrow == 0 || borrow == 1); + BN_ULONG ret = x - y - borrow; + *out_borrow = (x < y) | ((x == y) & borrow); + return ret; +} + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + if (n == 0) { + return 0; + } + + BN_ULONG carry = 0; + while (n & ~3) { + r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); + r[1] = bn_add_with_carry(a[1], b[1], carry, &carry); + r[2] = bn_add_with_carry(a[2], b[2], carry, &carry); + r[3] = bn_add_with_carry(a[3], b[3], carry, &carry); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); + a++; + b++; + r++; + n--; + } + return carry; +} + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + if (n == 0) { + return (BN_ULONG)0; + } + + BN_ULONG borrow = 0; + while (n & ~3) { + r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); + r[1] = bn_sub_with_borrow(a[1], b[1], borrow, &borrow); + r[2] = bn_sub_with_borrow(a[2], b[2], borrow, &borrow); + r[3] = bn_sub_with_borrow(a[3], b[3], borrow, &borrow); + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); + a++; + b++; + r++; + n--; + } + return borrow; +} + +#endif // !BN_ADD_ASM diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/internal.h index cab9a81f..7b939de5 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/internal.h @@ -189,14 +189,20 @@ extern "C" { #define BN_CAN_USE_INLINE_ASM #endif -// |BN_mod_exp_mont_consttime| is based on the assumption that the L1 data -// cache line width of the target processor is at least the following value. -#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH 64 +// MOD_EXP_CTIME_ALIGN is the alignment needed for |BN_mod_exp_mont_consttime|'s +// tables. +// +// TODO(davidben): Historically, this alignment came from cache line +// assumptions, which we've since removed. Is 64-byte alignment still necessary +// or ideal? The true alignment requirement seems to now be 32 bytes, coming +// from RSAZ's use of VMOVDQA to a YMM register. Non-x86_64 has even fewer +// requirements. +#define MOD_EXP_CTIME_ALIGN 64 -// The number of |BN_ULONG|s needed for the |BN_mod_exp_mont_consttime| stack- -// allocated storage buffer. The buffer is just the right size for the RSAZ -// and is about ~1KB larger than what's necessary (4480 bytes) for 1024-bit -// inputs. +// MOD_EXP_CTIME_STORAGE_LEN is the number of |BN_ULONG|s needed for the +// |BN_mod_exp_mont_consttime| stack-allocated storage buffer. The buffer is +// just the right size for the RSAZ and is about ~1KB larger than what's +// necessary (4480 bytes) for 1024-bit inputs. #define MOD_EXP_CTIME_STORAGE_LEN \ (((320u * 3u) + (32u * 9u * 16u)) / sizeof(BN_ULONG)) @@ -211,8 +217,8 @@ extern "C" { #define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) #endif -// bn_minimal_width returns the minimal value of |bn->top| which fits the -// value of |bn|. +// bn_minimal_width returns the minimal number of words needed to represent +// |bn|. int bn_minimal_width(const BIGNUM *bn); // bn_set_minimal_width sets |bn->width| to |bn_minimal_width(bn)|. If |bn| is @@ -228,7 +234,7 @@ int bn_wexpand(BIGNUM *bn, size_t words); // than a number of words. int bn_expand(BIGNUM *bn, size_t bits); -// bn_resize_words adjusts |bn->top| to be |words|. It returns one on success +// bn_resize_words adjusts |bn->width| to be |words|. It returns one on success // and zero on allocation error or if |bn|'s value is too large. OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words); @@ -257,6 +263,12 @@ int bn_fits_in_words(const BIGNUM *bn, size_t num); // is representable in |num| words. Otherwise, it returns zero. int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn); +// bn_assert_fits_in_bytes asserts that |bn| fits in |num| bytes. This is a +// no-op in release builds, but triggers an assert in debug builds, and +// declassifies all bytes which are therefore known to be zero in constant-time +// validation. +void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num); + // bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places // the result in |rp|. |ap| and |rp| must both be |num| words long. It returns // the carry word of the operation. |ap| and |rp| may be equal but otherwise may @@ -344,6 +356,12 @@ int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, const BIGNUM *max_exclusive); +// BN_MONTGOMERY_MAX_WORDS is the maximum numer of words allowed in a |BIGNUM| +// used with Montgomery reduction. Ideally this limit would be applied to all +// |BIGNUM|s, in |bn_wexpand|, but the exactfloat library needs to create 8 MiB +// values for other operations. +#define BN_MONTGOMERY_MAX_WORDS (8 * 1024 / sizeof(BN_ULONG)) + #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) @@ -353,11 +371,16 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // corresponding field in |BN_MONT_CTX|. It returns one if |bn_mul_mont| handles // inputs of this size and zero otherwise. // +// If at least one of |ap| or |bp| is fully reduced, |rp| will be fully reduced. +// If neither is fully-reduced, the output may not be either. +// +// This function allocates |num| words on the stack, so |num| should be at most +// |BN_MONTGOMERY_MAX_WORDS|. +// // TODO(davidben): The x86_64 implementation expects a 32-bit input and masks // off upper bits. The aarch64 implementation expects a 64-bit input and does // not. |size_t| is the safer option but not strictly correct for x86_64. But -// this function implicitly already has a bound on the size of |num| because it -// internally creates |num|-sized stack allocation. +// the |BN_MONTGOMERY_MAX_WORDS| bound makes this moot. // // See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word // inputs. @@ -371,46 +394,48 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, // bn_mul_mont_gather5 multiples loads index |power| of |table|, multiplies it // by |ap| modulo |np|, and stores the result in |rp|. The values are |num| // words long and represented in Montgomery form. |n0| is a pointer to the -// corresponding field in |BN_MONT_CTX|. +// corresponding field in |BN_MONT_CTX|. |table| must be aligned to at least +// 16 bytes. |power| must be less than 32 and is treated as secret. +// +// WARNING: This function implements Almost Montgomery Multiplication from +// https://eprint.iacr.org/2011/239. The inputs do not need to be fully reduced. +// However, even if they are fully reduced, the output may not be. void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, const BN_ULONG *n0, int num, int power); // bn_scatter5 stores |inp| to index |power| of |table|. |inp| and each entry of -// |table| are |num| words long. |power| must be less than 32. |table| must be -// 32*|num| words long. +// |table| are |num| words long. |power| must be less than 32 and is treated as +// public. |table| must be 32*|num| words long. |table| must be aligned to at +// least 16 bytes. void bn_scatter5(const BN_ULONG *inp, size_t num, BN_ULONG *table, size_t power); // bn_gather5 loads index |power| of |table| and stores it in |out|. |out| and -// each entry of |table| are |num| words long. |power| must be less than 32. -void bn_gather5(BN_ULONG *out, size_t num, BN_ULONG *table, size_t power); +// each entry of |table| are |num| words long. |power| must be less than 32 and +// is treated as secret. |table| must be aligned to at least 16 bytes. +void bn_gather5(BN_ULONG *out, size_t num, const BN_ULONG *table, size_t power); // bn_power5 squares |ap| five times and multiplies it by the value stored at // index |power| of |table|, modulo |np|. It stores the result in |rp|. The // values are |num| words long and represented in Montgomery form. |n0| is a // pointer to the corresponding field in |BN_MONT_CTX|. |num| must be divisible -// by 8. +// by 8. |power| must be less than 32 and is treated as secret. +// +// WARNING: This function implements Almost Montgomery Multiplication from +// https://eprint.iacr.org/2011/239. The inputs do not need to be fully reduced. +// However, even if they are fully reduced, the output may not be. void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, const BN_ULONG *n0, int num, int power); - -// bn_from_montgomery converts |ap| from Montgomery form modulo |np| and writes -// the result in |rp|, each of which is |num| words long. It returns one on -// success and zero if it cannot handle inputs of length |num|. |n0| is a -// pointer to the corresponding field in |BN_MONT_CTX|. -int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *not_used, const BN_ULONG *np, - const BN_ULONG *n0, int num); #endif // !OPENSSL_NO_ASM && OPENSSL_X86_64 uint64_t bn_mont_n0(const BIGNUM *n); -// bn_mod_exp_base_2_consttime calculates r = 2**p (mod n). |p| must be larger -// than log_2(n); i.e. 2**p must be larger than |n|. |n| must be positive and -// odd. |p| and the bit width of |n| are assumed public, but |n| is otherwise -// treated as secret. -int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, - BN_CTX *ctx); +// bn_mont_ctx_set_RR_consttime initializes |mont->RR|. It returns one on +// success and zero on error. |mont->N| and |mont->n0| must have been +// initialized already. The bit width of |mont->N| is assumed public, but +// |mont->N| is otherwise treated as secret. +int bn_mont_ctx_set_RR_consttime(BN_MONT_CTX *mont, BN_CTX *ctx); #if defined(_MSC_VER) #if defined(OPENSSL_X86_64) @@ -436,7 +461,7 @@ int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); // bn_is_bit_set_words returns one if bit |bit| is set in |a| and zero // otherwise. -int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit); +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, size_t bit); // bn_one_to_montgomery sets |r| to one in Montgomery form. It returns one on // success and zero on error. This function treats the bit width of the modulus @@ -632,6 +657,15 @@ int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx, const BN_MONT_CTX *mont_p); +// BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If +// so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It +// then stores it as |*pmont|. It returns one on success and zero on error. Note +// this function assumes |mod| is public. +// +// If |*pmont| is already non-NULL then it does nothing and returns one. +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx); + // Low-level operations for small numbers. // @@ -687,9 +721,10 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, // bn_mod_exp_mont_small sets |r| to |a|^|p| mod |mont->N|. It returns one on // success and zero on programmer or internal error. Both inputs and outputs are // in the Montgomery domain. |r| and |a| are |num| words long, which must be -// |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. -// This function runs in time independent of |a|, but |p| and |mont->N| are -// public values. |a| must be fully-reduced and may alias with |r|. +// |mont->N.width| and at most |BN_SMALL_MAX_WORDS|. |num_p|, measured in bits, +// must fit in |size_t|. |a| must be fully-reduced. This function runs in time +// independent of |a|, but |p| and |mont->N| are public values. |a| must be +// fully-reduced and may alias with |r|. // // Note this function differs from |BN_mod_exp_mont| which uses Montgomery // reduction but takes input and output outside the Montgomery domain. Combine @@ -708,6 +743,25 @@ void bn_mod_inverse0_prime_mont_small(BN_ULONG *r, const BN_ULONG *a, size_t num, const BN_MONT_CTX *mont); +// Word-based byte conversion functions. + +// bn_big_endian_to_words interprets |in_len| bytes from |in| as a big-endian, +// unsigned integer and writes the result to |out_len| words in |out|. |out_len| +// must be large enough to represent any |in_len|-byte value. That is, |out_len| +// must be at least |BN_BYTES * in_len|. +void bn_big_endian_to_words(BN_ULONG *out, size_t out_len, const uint8_t *in, + size_t in_len); + +// bn_words_to_big_endian represents |in_len| words from |in| as a big-endian, +// unsigned integer in |out_len| bytes. It writes the result to |out|. |out_len| +// must be large enough to represent |in| without truncation. +// +// Note |out_len| may be less than |BN_BYTES * in_len| if |in| is known to have +// leading zeros. +void bn_words_to_big_endian(uint8_t *out, size_t out_len, const BN_ULONG *in, + size_t in_len); + + #if defined(__cplusplus) } // extern C #endif diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery.c index e9fa08f7..a5df5ff4 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery.c @@ -116,7 +116,6 @@ #include #include #include -#include #include "internal.h" #include "../../internal.h" @@ -173,6 +172,10 @@ static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); return 0; } + if (!bn_fits_in_words(mod, BN_MONTGOMERY_MAX_WORDS)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } // Save the modulus. if (!BN_copy(&mont->N, mod)) { @@ -190,11 +193,10 @@ static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { // others, we could use a shorter R value and use faster |BN_ULONG|-based // math instead of |uint64_t|-based math, which would be double-precision. // However, currently only the assembler files know which is which. - OPENSSL_STATIC_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, - "BN_MONT_CTX_N0_LIMBS value is invalid"); - OPENSSL_STATIC_ASSERT( - sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == sizeof(uint64_t), - "uint64_t is insufficient precision for n0"); + static_assert(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + "BN_MONT_CTX_N0_LIMBS value is invalid"); + static_assert(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == sizeof(uint64_t), + "uint64_t is insufficient precision for n0"); uint64_t n0 = bn_mont_n0(&mont->N); mont->n0[0] = (BN_ULONG)n0; #if BN_MONT_CTX_N0_LIMBS == 2 @@ -246,19 +248,12 @@ BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, BN_CTX *ctx) { BN_MONT_CTX *BN_MONT_CTX_new_consttime(const BIGNUM *mod, BN_CTX *ctx) { BN_MONT_CTX *mont = BN_MONT_CTX_new(); if (mont == NULL || - !bn_mont_ctx_set_N_and_n0(mont, mod)) { - goto err; - } - unsigned lgBigR = mont->N.width * BN_BITS2; - if (!bn_mod_exp_base_2_consttime(&mont->RR, lgBigR * 2, &mont->N, ctx) || - !bn_resize_words(&mont->RR, mont->N.width)) { - goto err; + !bn_mont_ctx_set_N_and_n0(mont, mod) || + !bn_mont_ctx_set_RR_consttime(mont, ctx)) { + BN_MONT_CTX_free(mont); + return NULL; } return mont; - -err: - BN_MONT_CTX_free(mont); - return NULL; } int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, @@ -430,6 +425,9 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (!bn_wexpand(r, num)) { return 0; } + // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont| + // allocates |num| words on the stack, so |num| cannot be too large. + assert((size_t)num <= BN_MONTGOMERY_MAX_WORDS); if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { // The check above ensures this won't happen. assert(0); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery_inv.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery_inv.c index c80873f5..f496fe9a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery_inv.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/montgomery_inv.c @@ -22,11 +22,10 @@ static uint64_t bn_neg_inv_mod_r_u64(uint64_t n); -OPENSSL_STATIC_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, - "BN_MONT_CTX_N0_LIMBS value is invalid"); -OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == - sizeof(uint64_t), - "uint64_t is insufficient precision for n0"); +static_assert(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + "BN_MONT_CTX_N0_LIMBS value is invalid"); +static_assert(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == sizeof(uint64_t), + "uint64_t is insufficient precision for n0"); // LG_LITTLE_R is log_2(r). #define LG_LITTLE_R (BN_MONT_CTX_N0_LIMBS * BN_BITS2) @@ -160,27 +159,63 @@ static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) { return v; } -int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, - BN_CTX *ctx) { - assert(!BN_is_zero(n)); - assert(!BN_is_negative(n)); - assert(BN_is_odd(n)); +int bn_mont_ctx_set_RR_consttime(BN_MONT_CTX *mont, BN_CTX *ctx) { + assert(!BN_is_zero(&mont->N)); + assert(!BN_is_negative(&mont->N)); + assert(BN_is_odd(&mont->N)); + assert(bn_minimal_width(&mont->N) == mont->N.width); - BN_zero(r); - - unsigned n_bits = BN_num_bits(n); + unsigned n_bits = BN_num_bits(&mont->N); assert(n_bits != 0); - assert(p > n_bits); if (n_bits == 1) { - return 1; + BN_zero(&mont->RR); + return bn_resize_words(&mont->RR, mont->N.width); } - // Set |r| to the larger power of two smaller than |n|, then shift with - // reductions the rest of the way. - if (!BN_set_bit(r, n_bits - 1) || - !bn_mod_lshift_consttime(r, r, p - (n_bits - 1), n, ctx)) { + unsigned lgBigR = mont->N.width * BN_BITS2; + assert(lgBigR >= n_bits); + + // RR is R, or 2^lgBigR, in the Montgomery domain. We can compute 2 in the + // Montgomery domain, 2R or 2^(lgBigR+1), and then use Montgomery + // square-and-multiply to exponentiate. + // + // The multiply steps take 2^n R to 2^(n+1) R. It is faster to double + // the value instead. The square steps take 2^n R to 2^(2n) R. This is + // equivalent to doubling n times. When n is below some threshold, doubling is + // faster. When above, squaring is faster. + // + // We double to this threshold, then switch to Montgomery squaring. From + // benchmarking various 32-bit and 64-bit architectures, the word count seems + // to work well as a threshold. (Doubling scales linearly and Montgomery + // reduction scales quadratically, so the threshold should scale roughly + // linearly.) + unsigned threshold = mont->N.width; + unsigned iters; + for (iters = 0; iters < sizeof(lgBigR) * 8; iters++) { + if ((lgBigR >> iters) <= threshold) { + break; + } + } + + // Compute 2^(lgBigR >> iters) R, or 2^((lgBigR >> iters) + lgBigR), by + // doubling. The first n_bits - 1 doubles can be skipped because we don't need + // to reduce. + if (!BN_set_bit(&mont->RR, n_bits - 1) || + !bn_mod_lshift_consttime(&mont->RR, &mont->RR, + (lgBigR >> iters) + lgBigR - (n_bits - 1), + &mont->N, ctx)) { return 0; } - return 1; + for (unsigned i = iters - 1; i < iters; i--) { + if (!BN_mod_mul_montgomery(&mont->RR, &mont->RR, &mont->RR, mont, ctx)) { + return 0; + } + if ((lgBigR & (1u << i)) != 0 && + !bn_mod_lshift1_consttime(&mont->RR, &mont->RR, &mont->N, ctx)) { + return 0; + } + } + + return bn_resize_words(&mont->RR, mont->N.width); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/mul.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/mul.c index 6e1c3caa..fe4e4d7a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/mul.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/mul.c @@ -62,7 +62,6 @@ #include #include -#include #include "internal.h" #include "../../internal.h" @@ -281,8 +280,8 @@ static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); c = constant_time_select_w(neg, c_neg, c_pos); // We now have our three components. Add them together. @@ -395,8 +394,8 @@ static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a, BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); c = constant_time_select_w(neg, c_neg, c_pos); // We now have our three components. Add them together. diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/prime.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/prime.c index 0c5edfee..2d2ab693 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/prime.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/prime.c @@ -362,7 +362,6 @@ static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, BN_GENCB *BN_GENCB_new(void) { BN_GENCB *callback = OPENSSL_malloc(sizeof(BN_GENCB)); if (callback == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(callback, 0, sizeof(BN_GENCB)); @@ -386,6 +385,8 @@ int BN_GENCB_call(BN_GENCB *callback, int event, int n) { return callback->callback(event, n, callback); } +void *BN_GENCB_get_arg(const BN_GENCB *callback) { return callback->arg; } + int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/random.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/random.c index f6812f12..2500cc1a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/random.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/random.c @@ -108,16 +108,17 @@ #include +#include #include #include #include #include -#include -#include "internal.h" #include "../../internal.h" #include "../rand/internal.h" +#include "../service_indicator/internal.h" +#include "internal.h" int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { @@ -155,7 +156,10 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { return 0; } + FIPS_service_indicator_lock_state(); RAND_bytes((uint8_t *)rnd->d, words * sizeof(BN_ULONG)); + FIPS_service_indicator_unlock_state(); + rnd->d[words - 1] &= mask; if (top != BN_RAND_TOP_ANY) { if (top == BN_RAND_TOP_TWO && bits > 1) { @@ -195,8 +199,8 @@ static crypto_word_t bn_less_than_word_mask(const BN_ULONG *a, size_t len, } // |a| < |b| iff a[1..len-1] are all zero and a[0] < b. - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); crypto_word_t mask = 0; for (size_t i = 1; i < len; i++) { mask |= a[i]; @@ -270,8 +274,10 @@ int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, // Steps 4 and 5. Use |words| and |mask| together to obtain a string of N // bits, where N is the bit length of |max_exclusive|. + FIPS_service_indicator_lock_state(); RAND_bytes_with_additional_data((uint8_t *)out, words * sizeof(BN_ULONG), additional_data); + FIPS_service_indicator_unlock_state(); out[words - 1] &= mask; // If out >= max_exclusive or out < min_inclusive, retry. This implements @@ -313,7 +319,9 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, } // Select a uniform random number with num_bits(max_exclusive) bits. + FIPS_service_indicator_lock_state(); RAND_bytes((uint8_t *)r->d, words * sizeof(BN_ULONG)); + FIPS_service_indicator_unlock_state(); r->d[words - 1] &= mask; // Check, in constant-time, if the value is in range. @@ -328,7 +336,7 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, assert(bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words)); r->neg = 0; - r->width = words; + r->width = (int)words; return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.c index 7e15aaf9..da250306 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.c @@ -18,6 +18,8 @@ #include +#include + #include "internal.h" #include "../../internal.h" @@ -38,8 +40,8 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0, BN_ULONG storage[MOD_EXP_CTIME_STORAGE_LEN]) { - OPENSSL_STATIC_ASSERT(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH % 64 == 0, - "MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH is too small"); + static_assert(MOD_EXP_CTIME_ALIGN % 64 == 0, + "MOD_EXP_CTIME_ALIGN is too small"); assert((uintptr_t)storage % 64 == 0); BN_ULONG *a_inv, *m, *result, *table_s = storage + 40 * 3, *R2 = table_s; @@ -66,23 +68,14 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], // R2 = 2^3052 * 2^80 / 2^1044 = 2^2088 = (2^1044)^2 // table[0] = 1 - rsaz_1024_mul_avx2(result, R2, one, m, k0); // table[1] = a_inv^1 + rsaz_1024_mul_avx2(result, R2, one, m, k0); rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 0); rsaz_1024_scatter5_avx2(table_s, a_inv, 1); - // table[2] = a_inv^2 rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1); rsaz_1024_scatter5_avx2(table_s, result, 2); -#if 0 - // This is almost 2x smaller and less than 1% slower. - for (int index = 3; index < 32; index++) { - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, index); - } -#else // table[4] = a_inv^4 rsaz_1024_sqr_avx2(result, result, m, k0, 1); rsaz_1024_scatter5_avx2(table_s, result, 4); @@ -92,109 +85,25 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], // table[16] = a_inv^16 rsaz_1024_sqr_avx2(result, result, m, k0, 1); rsaz_1024_scatter5_avx2(table_s, result, 16); - // table[17] = a_inv^17 - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 17); - - // table[3] - rsaz_1024_gather5_avx2(result, table_s, 2); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 3); - // table[6] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 6); - // table[12] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 12); - // table[24] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 24); - // table[25] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 25); - - // table[5] - rsaz_1024_gather5_avx2(result, table_s, 4); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 5); - // table[10] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 10); - // table[20] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 20); - // table[21] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 21); - - // table[7] - rsaz_1024_gather5_avx2(result, table_s, 6); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 7); - // table[14] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 14); - // table[28] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 28); - // table[29] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 29); - - // table[9] - rsaz_1024_gather5_avx2(result, table_s, 8); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 9); - // table[18] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 18); - // table[19] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 19); - - // table[11] - rsaz_1024_gather5_avx2(result, table_s, 10); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 11); - // table[22] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 22); - // table[23] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 23); - - // table[13] - rsaz_1024_gather5_avx2(result, table_s, 12); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 13); - // table[26] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 26); - // table[27] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 27); - - // table[15] - rsaz_1024_gather5_avx2(result, table_s, 14); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 15); - // table[30] - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 30); - // table[31] - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 31); -#endif + for (int i = 3; i < 32; i += 2) { + // table[i] = table[i-1] * a_inv = a_inv^i + rsaz_1024_gather5_avx2(result, table_s, i - 1); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, i); + for (int j = 2 * i; j < 32; j *= 2) { + // table[j] = table[j/2]^2 = a_inv^j + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, j); + } + } + // Load the first window. const uint8_t *p_str = (const uint8_t *)exponent; - - // load first window int wvalue = p_str[127] >> 3; rsaz_1024_gather5_avx2(result, table_s, wvalue); int index = 1014; while (index > -1) { // Loop for the remaining 127 windows. - rsaz_1024_sqr_avx2(result, result, m, k0, 5); uint16_t wvalue_16; @@ -219,6 +128,8 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], rsaz_1024_mul_avx2(result, result, one, m, k0); rsaz_1024_red2norm_avx2(result_norm, result); + BN_ULONG scratch[16]; + bn_reduce_once_in_place(result_norm, /*carry=*/0, m_norm, scratch, 16); OPENSSL_cleanse(storage, MOD_EXP_CTIME_STORAGE_LEN * sizeof(BN_ULONG)); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.h b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.h index 3b061921..22ca3ec4 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/rsaz_exp.h @@ -16,9 +16,9 @@ #define OPENSSL_HEADER_BN_RSAZ_EXP_H #include -#include #include "internal.h" +#include "../../internal.h" #if defined(__cplusplus) extern "C" { @@ -32,8 +32,7 @@ extern "C" { // modulo |m_norm|. |base_norm| must be fully-reduced and |exponent| must have // the high bit set (it is 1024 bits wide). |RR| and |k0| must be |RR| and |n0|, // respectively, extracted from |m_norm|'s |BN_MONT_CTX|. |storage_words| is a -// temporary buffer that must be aligned to |MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH| -// bytes. +// temporary buffer that must be aligned to |MOD_EXP_CTIME_ALIGN| bytes. void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], const BN_ULONG base_norm[16], const BN_ULONG exponent[16], const BN_ULONG m_norm[16], const BN_ULONG RR[16], @@ -41,18 +40,17 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], const BN_ULONG base_norm[16], BN_ULONG storage_words[MOD_EXP_CTIME_STORAGE_LEN]); OPENSSL_INLINE int rsaz_avx2_capable(void) { - const uint32_t *cap = OPENSSL_ia32cap_get(); - return (cap[2] & (1 << 5)) != 0; // AVX2 + return CRYPTO_is_AVX2_capable(); } OPENSSL_INLINE int rsaz_avx2_preferred(void) { - const uint32_t *cap = OPENSSL_ia32cap_get(); - static const uint32_t kBMI2AndADX = (1 << 8) | (1 << 19); - if ((cap[2] & kBMI2AndADX) == kBMI2AndADX) { - // If BMI2 and ADX are available, x86_64-mont5.pl is faster. + if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && + CRYPTO_is_ADX_capable()) { + // If BMI1, BMI2, and ADX are available, x86_64-mont5.pl is faster. See the + // .Lmulx4x_enter and .Lpowerx5_enter branches. return 0; } - return (cap[2] & (1 << 5)) != 0; // AVX2 + return CRYPTO_is_AVX2_capable(); } @@ -80,18 +78,24 @@ void rsaz_1024_sqr_avx2(BN_ULONG ret[40], const BN_ULONG a[40], const BN_ULONG n[40], BN_ULONG k, int count); // rsaz_1024_scatter5_avx2 stores |val| at index |i| of |tbl|. |i| must be -// positive and at most 31. Note the table only uses 18 |BN_ULONG|s per entry -// instead of 40. It packs two 29-bit limbs into each |BN_ULONG| and only stores -// 36 limbs rather than the padded 40. +// positive and at most 31. It is treated as public. Note the table only uses 18 +// |BN_ULONG|s per entry instead of 40. It packs two 29-bit limbs into each +// |BN_ULONG| and only stores 36 limbs rather than the padded 40. void rsaz_1024_scatter5_avx2(BN_ULONG tbl[32 * 18], const BN_ULONG val[40], int i); -// rsaz_1024_gather5_avx2 loads index |i| of |tbl| and writes it to |val|. +// rsaz_1024_gather5_avx2 loads index |i| of |tbl| and writes it to |val|. |i| +// must be positive and at most 31. It is treated as secret. |tbl| must be +// aligned to 32 bytes. void rsaz_1024_gather5_avx2(BN_ULONG val[40], const BN_ULONG tbl[32 * 18], int i); // rsaz_1024_red2norm_avx2 converts |red| from RSAZ to |BIGNUM| representation -// and writes the result to |norm|. +// and writes the result to |norm|. The result will be <= the modulus. +// +// WARNING: The result of this operation may not be fully reduced. |norm| may be +// the modulus instead of zero. This function should be followed by a call to +// |bn_reduce_once|. void rsaz_1024_red2norm_avx2(BN_ULONG norm[16], const BN_ULONG red[40]); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/shift.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/shift.c index 523da674..6960e574 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/shift.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/shift.c @@ -56,10 +56,10 @@ #include +#include #include #include -#include #include "internal.h" @@ -258,9 +258,9 @@ int BN_clear_bit(BIGNUM *a, int n) { return 1; } -int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit) { - unsigned i = bit / BN_BITS2; - unsigned j = bit % BN_BITS2; +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, size_t bit) { + size_t i = bit / BN_BITS2; + size_t j = bit % BN_BITS2; if (i >= num) { return 0; } @@ -296,15 +296,14 @@ int BN_mask_bits(BIGNUM *a, int n) { } static int bn_count_low_zero_bits_word(BN_ULONG l) { - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); - OPENSSL_STATIC_ASSERT(sizeof(int) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); - OPENSSL_STATIC_ASSERT(BN_BITS2 == sizeof(BN_ULONG) * 8, - "BN_ULONG has padding bits"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + static_assert(sizeof(int) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + static_assert(BN_BITS2 == sizeof(BN_ULONG) * 8, "BN_ULONG has padding bits"); // C has very bizarre rules for types smaller than an int. - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) >= sizeof(int), - "BN_ULONG gets promoted to int"); + static_assert(sizeof(BN_ULONG) >= sizeof(int), + "BN_ULONG gets promoted to int"); crypto_word_t mask; int bits = 0; @@ -342,10 +341,10 @@ static int bn_count_low_zero_bits_word(BN_ULONG l) { } int BN_count_low_zero_bits(const BIGNUM *bn) { - OPENSSL_STATIC_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); - OPENSSL_STATIC_ASSERT(sizeof(int) <= sizeof(crypto_word_t), - "crypto_word_t is too small"); + static_assert(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); + static_assert(sizeof(int) <= sizeof(crypto_word_t), + "crypto_word_t is too small"); int ret = 0; crypto_word_t saw_nonzero = 0; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/sqrt.c b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/sqrt.c index db888297..f9767530 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/sqrt.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/sqrt.c @@ -306,8 +306,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { } // x := a^((q-1)/2) - if (BN_is_zero(t)) // special case: p = 2^e + 1 - { + if (BN_is_zero(t)) { // special case: p = 2^e + 1 if (!BN_nnmod(t, A, p, ctx)) { goto end; } @@ -350,7 +349,6 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { // We have a*b = x^2, // y^2^(e-1) = -1, // b^2^(e-1) = 1. - if (BN_is_one(b)) { if (!BN_copy(ret, x)) { goto end; @@ -359,23 +357,26 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { goto vrfy; } - - // find smallest i such that b^(2^i) = 1 - i = 1; - if (!BN_mod_sqr(t, b, p, ctx)) { + // Find the smallest i, 0 < i < e, such that b^(2^i) = 1 + for (i = 1; i < e; i++) { + if (i == 1) { + if (!BN_mod_sqr(t, b, p, ctx)) { + goto end; + } + } else { + if (!BN_mod_mul(t, t, t, p, ctx)) { + goto end; + } + } + if (BN_is_one(t)) { + break; + } + } + // If not found, a is not a square or p is not a prime. + if (i >= e) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); goto end; } - while (!BN_is_one(t)) { - i++; - if (i == e) { - OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); - goto end; - } - if (!BN_mod_mul(t, t, t, p, ctx)) { - goto end; - } - } - // t := y^2^(e - i - 1) if (!BN_copy(t, y)) { @@ -391,14 +392,15 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { !BN_mod_mul(b, b, y, p, ctx)) { goto end; } + + // e decreases each iteration, so this loop will terminate. + assert(i < e); e = i; } vrfy: if (!err) { - // verify the result -- the input might have been not a square - // (test added in 0.9.8) - + // Verify the result. The input might have been not a square. if (!BN_mod_sqr(x, ret, p, ctx)) { err = 1; } @@ -443,7 +445,6 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { last_delta = BN_CTX_get(ctx); delta = BN_CTX_get(ctx); if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { - OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/exp_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/exp_tests.txt new file mode 100644 index 00000000..15982242 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/exp_tests.txt @@ -0,0 +1,23 @@ +# Exp tests. +# +# These test vectors satisfy A ^ E = Exp. + +Exp = aa6d7ac431 +A = d0e07 +E = 2 + +Exp = 12d416b110dbb4e467ff0c89a22122f4da8240 +A = 1a18cf6 +E = 6 + +Exp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000 +A = 2a3acbd2 +E = d + +Exp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1 +A = 54b3ae461 +E = 1a + +Exp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f +A = fccec0f6df +E = 25 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/gcd_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/gcd_tests.txt new file mode 100644 index 00000000..b5a0c17e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/gcd_tests.txt @@ -0,0 +1,279 @@ +# GCD tests. +# +# These test vectors satisfy gcd(A, B) = GCD and lcm(A, B) = LCM. + +GCD = 0 +A = 0 +B = 0 +# Just to appease the syntax-checker. +LCM = 0 + +GCD = 1 +A = 92ff140ac8a659b31dd904161f9213706a08a817ae845e522c3af0c9096699e059b47c8c2f16434b1c5766ebb384b79190f2b2a62c2378f45e116890e7bb407a +B = 2f532c9e5902b0d68cd2ed69b2083bc226e8b04c549212c425a5287bb171c6a47fcb926c70cc0d34b8d6201c617aee66af865d31fdc8a2eeb986c19da8bb0897 +LCM = 1b2c97003e520b0bdd59d8c35a180b4aa36bce14211590435b990ad8f4c034ce3c77899581cb4ee1a022874203459b6d53859ab1d99ff755efa253fc0e5d8487bb000c13c566e8937f0fe90b95b68bc278610d4f232770b08d1f31bee55a03da47f2d0ebb9e7861c4f16cc22168b68593e9efcde00f54104b4c3e1a0b294d7f6 + +GCD = a +A = faaffa431343074f5c5d6f5788500d7bc68b86eb37edf166f699b4d75b76dae2cb7c8f6eccae8f18f6d510ef72f0b9633d5740c0bebb934d3be796bd9a53808e +B = 2f48ec5aa5511283c2935b15725d30f62244185573203b48c7eb135b2e6db5c115c9446ac78b020574665b06a75eb287e0dbeb5da7c193294699b4c2129d2ac4 +LCM = 4a15f305e9622aa19bd8f39e968bfc16d527a47f7a5219d7b02c242c77ef8b608a4a6141f643ca97cedf07c0f1f3e8879d2568b056718aa15c0756899a08ccbe0a658bae67face96fa110edb91757bfa4828e8ff7c5d71b204f36238b12dd26f17be8ba9771f7068d63e41d423671f898f054b1187605754bc5546f2b02c5ac + +GCD = 16 +A = cf0b21bde98b41b479ac8071086687a6707e9efaacd4e5299668ce1be8b13290f27fd32ae68df87c292e8583a09d73ec8e8a04a65a487380dcd7dacca3b6e692 +B = 3be3f563f81d5ad5c1211db7eff430aa345e830ce07b4bde7d4d32dba3ac618d2034351e5435fd6c7f077971fb4a1e83a7396a74fdff7fce1267112851db2582 +LCM = 233a2188de2c017235024b182286f17562b2ee5ab9fdfe4efa2f61c4ff99fa44e1ead5bf6cde05bd7502ce78373c83e3f9dbab0c9bb8620a87c2640bce5d12c685af656df789bb3d0ba1edbaa98cf4f0166d422ab17aa6706f8132264d45b72827d6671a00a9186e723379e3a3bb7902d08865f357c74100059f83800241976 + +GCD = 1 +A = dd7b7597d7c1eb399b1cea9b3042c14bd6022d31b1d2642a8f82fc32de6eadaf012fbbf349eaec4922a8468740ca73c6090833d6a69a380ed947b39c2f9b0b76 +B = 8e0dc8654e70eec55496038a8d3fff3c2086bc6dbfc0e2dbdf5bd7de03c5aef01a3982556ac3fc34fd5f13368be6cdc252c82367b7462e210f940f847d382dd9 +LCM = 7ae667df4bd4dd35bbec28719a9f1b5e1f396a9ab386c086742a6ab3014a3386d39f35b50624d0c5b4e6b206c2635c7de5ea69e2faa85dd616a7e36622962a07632839857aa49332942feccff2aee1c962e2f4e8ccfd738a5da5bf528b4c5a2440409350f5a17a39d234403e8482ccf838e0d2758ccfb8018198a51dbb407506 + +GCD = 1 +A = 0 +B = 1 +LCM = 0 + +GCD = 1 +A = 1 +B = 0 +LCM = 0 + +GCD = 1 +A = 1 +B = 1 +LCM = 1 + +GCD = 2b2 +A = dfccaa3549c1b59ab3e114fe87dc5d187719abad58c51724e972741eb895ab79a49f385f61d531ec5c88dbb505ae375093fa848165f71a5ed65e7832a42ade191a +B = fa58a81f43088da45e659fc1117d0f1cd015aa096c8e5377cf1832191baf7cc28b5c24998b93b64f8900a0973faedb9babaaf1854345f011739da8f1175d9684c +LCM = 5132f7ab7a982b9dc55114bd96800b7637f9742cf8a7a00a0d69d5e4574fc85792c89a1c52bcfc74b9d7f3f6164819466c46b2d622e280ced7ad1211604084a15dc1fd1951a05c8ce37122c0ec15891d818a70d3763670ea3195098de9b1ca50ea89893a9753fb9ea801541058f44801f7f50967124abfc864a2b01c41f94193c + +GCD = 8e +A = 248d96a8a4cab0a1b194e08c1146868b094597cadbc35531f0ed2d77cba9f15cb5cc7c10e64ce054bf93396d25259d750b3de3aba65073db1fd2b852a6454ac1a +B = 4c7bad8e1844901fd6a2ce2edc82e698d28ec95d6672ca148d85b49ecc78dd0a8b870e202244210bc98592b99ff6abbd20630f9eee7d46b15ccfae8d08b86799de +LCM = 13b01f9d9c6c13e90c97e3d95bbce5a835c631b3de3bd4ff5df13ad850f5223dbdf71c53912275d0397df9335ef3a3ba8e4684c6b25962bb7b18bc74144cb5edf0196f79863a7ff032619a71646a92281f7baace7f223d254cb4d05ec19bf8d4c8ce4455a9d770daec89c0d3cf338cbdae39cf982b3c4568f5c9def4e1133d28a + +GCD = 3e55 +A = 2fa97382f46676b7a4cc2b8153f17b58792d24660e187d33ce55c81cc193ccb6e1e2b89feea1d5fd8faa36e13bf947fb48635e450a4d1488d0978324194a1f43c6 +B = ab08ad074139963bc18e5d87ba68db64ca6f4c279616c64039b02c55f2375b3bc04114e8e05e1ba92fb6470768f61d123845aea36774c18612736a220934561faf +LCM = 82c7c377ecda2cb9228604cd287df5eff94edd4a539c3eb3b3fdd4b4a79d2f4eaf2b22f8286272d3dad2e370cfcd9ea4d93ebb3f049c52b8fa23b68a5bf79af989822e2cfb978f68c6a5058f47319dffcb455b089b06ae6db9e5c8a2b6e951d6e118bd2b4cd08b6e5733476a446a57387d940d1289ec00e24315821ed3a5daf2 + +GCD = a7a +A = 923706dfed67834a1e7e6c8e8e9f93bfbc0b43ca1f324886cf1f1380fb9b77109275d4b50af1b7689802fe9b3623ac46c7ba0e17e908c20278127b07a5c12d86ec +B = 64473e878a29021fac1c1ce34a63eae1f4f83ee6851333b67213278b9a4a16f005cba0e8cdb410035bb580062f0e486c1a3a01f4a4edf782495f1dc3ebfa837d86 +LCM = 57785ca45b8873032f1709331436995525eed815c55140582ce57fd852116835deac7ca9d95ce9f280e246ea4d4f1b7140ab7e0dd6dc869de87f1b27372098b155ad0a1828fd387dff514acc92eae708609285edaab900583a786caf95153f71e6e6092c8c5ee727346567e6f58d60a5e01c2fa8ebcf86da9ea46876ecc58e914 + +GCD = 42 +A = 0 +B = 42 +LCM = 0 + +GCD = 42 +A = 42 +B = 0 +LCM = 0 + +GCD = 42 +A = 42 +B = 42 +LCM = 42 + +GCD = f60d +A = ef7886c3391407529d5cf2e75ed53e5c3f74439ad2e2dc48a79bc1a5322789b4ced2914b97f8ff4b9910d212243b54001eb8b375365b9a87bd022dd3772c78a9fd63 +B = d1d3ec32fa3103911830d4ec9f629c5f75af7039e307e05bc2977d01446cd2cbeeb8a8435b2170cf4d9197d83948c7b8999d901fe47d3ce7e4d30dc1b2de8af0c6e4 +LCM = cc376ed2dc362c38a45a719b2ed48201dab3e5506e3f1314e57af229dc7f3a6a0dad3d21cfb148c23a0bbb0092d667051aa0b35cff5b5cc61a7c52dec4ed72f6783edf181b3bf0500b79f87bb95abc66e4055f259791e4e5eb897d82de0e128ecf8a091119475351d65b7f320272db190898a02d33f45f03e27c36cb1c45208037dc + +GCD = 9370 +A = 1ee02fb1c02100d1937f9749f628c65384ff822e638fdb0f42e27b10ee36e380564d6e861fcad0518f4da0f8636c1b9f5124c0bc2beb3ca891004a14cd7b118ddfe0 +B = 67432fd1482d19c4a1c2a4997eab5dbf9c5421977d1de60b739af94c41a5ad384cd339ebfaa43e5ad6441d5b9aaed5a9f7485025f4b4d5014e1e406d5bd838a44e50 +LCM = 159ff177bdb0ffbd09e2aa7d86de266c5de910c12a48cbe61f6fa446f63a2151194777555cd59903d24cb30965973571fb1f89c26f2b760526f73ded7ee8a34ebcecd1a3374a7559bcdb9ac6e78be17a62b830d6bb3982afdf10cf83d61fd0d588eab17d6abef8e6a7a5763fcb766d9a4d86adf5bb904f2dd6b528b9faec603987a0 + +GCD = c5f +A = 5a3a2088b5c759420ed0fb9c4c7685da3725b659c132a710ef01e79435e63d009d2931ea0a9ed9432f3d6b8851730c323efb9db686486614332c6e6ba54d597cf98 +B = 1b1eb33b006a98178bb35bbcf09c5bebd92d9ace79fa34c1567efa8d6cf6361547807cd3f8e7b8cd3ddb6209dccbae4b4c16c8c1ec19741a3a57f61571882b7aed7 +LCM = c5cbbbe9532d30d2a7dd7c1c8a6e69fd4fa4828a844d6afb44f3747fef584f7f1f3b835b006f8747d84f7699e88f6267b634e7aef78d6c7584829537d79514eec7d11219721f91015f5cefdc296261d85dba388729438991a8027de4827cd9eb575622e2912b28c9ce26d441e97880d18db025812cef5de01adeaec1322a9c9858 + +GCD = e052 +A = 67429f79b2ec3847cfc7e662880ab1d94acdf04284260fcfffd67c2862d59704ed45bcc53700c88a5eea023bc09029e9fd114fc94c227fd47a1faa1a5ef117b09bd2 +B = 39faa7cbdeb78f9028c1d50ab34fbe6924c83a1262596f6b85865d4e19cc258b3c3af1ee2898e39e5bee5839e92eac6753bbbb0253bd576d1839a59748b778846a86 +LCM = 1ab071fb733ef142e94def10b26d69982128561669e58b20b80d39cf7c2759d26b4a65d73b7f940c6e8fc417180ef62d7e52ac24678137bd927cd8d004ad52b02affe176a1ecde903dbc26dcc705678f76dd8cd874c0c3fe737474309767507bbe70dd7fb671bbb3694cedf0dcdaa0c716250ddd6dfec525261572fa3e1387f7b906 + +GCD = 3523 +A = 0 +B = 3523 +LCM = 0 + +GCD = 3523 +A = 3523 +B = 0 +LCM = 0 + +GCD = 3523 +A = 3523 +B = 3523 +LCM = 3523 + +GCD = f035a941 +A = 16cd5745464dfc426726359312398f3c4486ed8aaeea6386a67598b10f744f336c89cdafcb18e643d55c3a62f4ab2c658a0d19ea3967ea1af3aee22e11f12c6df6e886f7 +B = 74df09f309541d26b4b39e0c01152b8ad05ad2dfe9dd2b6706240e9d9f0c530bfb9e4b1cad3d4a94342aab309e66dd42d9df01b47a45173b507e41826f24eb1e8bcc4459 +LCM = b181771d0e9d6b36fdfcbf01d349c7de6b7e305e1485ea2aa32938aa919a3eee9811e1c3c649068a7572f5d251b424308da31400d81ac4078463f9f71d7efd2e681f92b13a6ab3ca5c9063032dcbdf3d3a9940ce65e54786463bbc06544e1280f25bc7579d264f6f1590cf09d1badbf542ce435a14ab04d25d88ddbac7d22e8cae1c91f + +GCD = 33ad1b8f +A = 1af010429a74e1b612c2fc4d7127436f2a5dafda99015ad15385783bd3af8d81798a57d85038bcf09a2a9e99df713b4d6fc1e3926910fbbf1f006133cb27dc5ebb9cca85 +B = 92a4f45a90965a4ef454f1cdd883d20f0f3be34d43588b5914677c39d577a052d1b25a522be1a656860a540970f99cbc8a3adf3e2139770f664b4b7b9379e13daf7d26c +LCM = 4c715520ed920718c3b2f62821bc75e3ff9fd184f76c60faf2906ef68d28cd540d3d6c071fa8704edd519709c3b09dfaee12cb02ab01ad0f3af4f5923d5705ce6d18bcab705a97e21896bb5dd8acb36ee8ec98c254a4ddc744297827a33c241f09016a5f109248c83dd41e4cea73ce3eabb28d76678b7e15545b96d22da83c111b6b624 + +GCD = dc0429aa +A = ccb423cfb78d7150201a97114b6644e8e0bbbb33cadb0ef5da5d3c521a244ec96e6d1538c64c10c85b2089bdd702d74c505adce9235aa4195068c9077217c0d431de7f96 +B = 710786f3d9022fc3acbf47ac901f62debcfda684a39234644bac630ab2d211111df71c0844b02c969fc5b4c5a15b785c96efd1e403514235dc9356f7faf75a0888de5e5a +LCM = 6929af911850c55450e2f2c4c9a72adf284fe271cf26e41c66e1a2ee19e30d928ae824f13d4e2a6d7bb12d10411573e04011725d3b6089c28d87738749107d990162b485805f5eedc8f788345bcbb5963641f73c303b2d92f80529902d3c2d7899623958499c8a9133aae49a616c96a2c5482a37947f23af18c3247203ac2d0e760340e6 + +GCD = 743166058 +A = 16cd476e8031d4624716238a3f85badd97f274cdfd9d53e0bd74de2a6c46d1827cc83057f3889588b6b7ca0640e7d743ed4a6eaf6f9b8df130011ecc72f56ef0af79680 +B = 86eba1fc8d761f22e0f596a03fcb6fe53ad15a03f5b4e37999f60b20966f78ba3280f02d3853f9ace40438ccfaf8faed7ace2f2bf089b2cdd4713f3f293bf602666c39f8 +LCM = 1a7a1b38727324d6ba0290f259b8e2b89c339b2445cada38a5a00ded1468ab069f40678ce76f7f78c7c6f97783cc8a49ef7e2a0c73abbac3abc66d1ce99566ce7f874a8949ca3442051e71967695dc65361184748c1908e1b587dc02ed899a524b34eb30b6f8db302432cfa1a8fbf2c46591e0ab3db7fd32c01b1f86c39832ee9f0c80 + +GCD = 6612ba2c +A = 0 +B = 6612ba2c +LCM = 0 + +GCD = 6612ba2c +A = 6612ba2c +B = 0 +LCM = 0 + +GCD = 6612ba2c +A = 6612ba2c +B = 6612ba2c +LCM = 6612ba2c + +GCD = 2272525aa08ccb20 +A = 11b9e23001e7446f6483fc9977140d91c3d82568dabb1f043a5620544fc3dda233b51009274cdb004fdff3f5c4267d34181d543d913553b6bdb11ce2a9392365fec8f9a3797e1200 +B = 11295529342bfb795f0611d03afb873c70bd16322b2cf9483f357f723b5b19f796a6206cf3ae3982daaeafcd9a68f0ce3355a7eba3fe4e743683709a2dd4b2ff46158bd99ff4d5a0 +LCM = 8d4cbf00d02f6adbaa70484bcd42ea932000843dcb667c69b75142426255f79b6c3b6bf22572597100c06c3277e40bf60c14c1f4a6822d86167812038cf1eefec2b0b19981ad99ad3125ff4a455a4a8344cbc609e1b3a173533db432bd717c72be25e05ed488d3970e7ed17a46353c5e0d91c8428d2fec7a93210759589df042cab028f545e3a00 + +GCD = 3480bf145713d56f9 +A = 8cf8ef1d4f216c6bcec673208fd93b7561b0eb8303af57113edc5c6ff4e1eeae9ddc3112b943d947653ba2179b7f63505465126d88ad0a0a15b682f5c89aa4a2a51c768cd9fdeaa9 +B = a6fd114023e7d79017c552a9051ca827f3ffa9f31e2ee9d78f8408967064fcdc9466e95cc8fac9a4fa88248987caf7cf57af58400d27abd60d9b79d2fe03fad76b879eceb504d7f +LCM = 1c05eee73a4f0db210a9007f94a5af88c1cdd2cba456061fd41de1e746d836fa4e0e972812842e0f44f10a61505f5d55760c48ba0d06af78bb6bde7da8b0080b29f82b1161e9c0b5458e05ac090b00f4d78b1cc10cf065124ba610e3acab092a36fe408525e21c0ddc7c9696ed4e48bd2f70423deecfe62cecc865c6088f265da0e5961d3f3a84f + +GCD = 917e74ae941fcaae +A = 652f8a92d96cbf0a309629011d0fbaceb1266bc2e8243d9e494eead4cf7100c661b537a8bea93dec88cfc68597d88a976c125c3b4de19aba38d4ea9578202e59848d42652518348a +B = 32e07b71979d57e8344e97c39680a61e07d692d824ae26b682156890792d8a766ee29a4968f461aaced5bf049044fba2f4120b1c1f05985676f975d4582e9e82750d73c532cd07b2 +LCM = 23620c7b897dc26c7717e32f3517ac70bf09fbe08f7255ab010cf4cf946f4e96304c425043452c5d5a0e841d3a3cfd9c2d84d9256f3b5974fe3ebfa9255fe20a710d3e6511606c0d85970381101c7f4986d65ad6a73a71507f146b11f903043cfa805cc0b14d4f3072da98bf22282f7762040406c02d5b3ef9e7587f63bab8b29c61d8e30911aa96 + +GCD = 2b9adc82005b2697 +A = 19764a84f46045ef1bca571d3cbf49b4545998e64d2e564cc343a53bc7a0bcfbe0baa5383f2b346e224eb9ce1137d9a4f79e8e19f946a493ff08c9b423574d56cbe053155177c37 +B = 1bbd489ad2ab825885cdac571a95ab4924e7446ce06c0f77cf29666a1e20ed5d9bc65e4102e11131d824acad1592075e13024e11f12f8210d86ab52aa60deb250b3930aabd960e5a +LCM = 1032a0c5fffc0425e6478185db0e5985c645dd929c7ebfeb5c1ee12ee3d7b842cfab8c9aa7ff3131ac41d4988fb928c0073103cea6bb2cc39808f1b0ad79a6d080eac5a0fc6e3853d43f903729549e03dba0a4405500e0096b9c8e00510c1852982baec441ed94efb80a78ed28ed526d055ad34751b831b8749b7c19728bf229357cc5e17eb8e1a + +GCD = 8d9d4f30773c4edf +A = 0 +B = 8d9d4f30773c4edf +LCM = 0 + +GCD = 8d9d4f30773c4edf +A = 8d9d4f30773c4edf +B = 0 +LCM = 0 + +GCD = 8d9d4f30773c4edf +A = 8d9d4f30773c4edf +B = 8d9d4f30773c4edf +LCM = 8d9d4f30773c4edf + +GCD = 6ebd8eafb9a957a6c3d3d5016be604f9624b0debf04d19cdabccf3612bbd59e00 +A = 34dc66a0ffd5b8b5e0ffc858dfc4655753e59247c4f82a4d2543b1f7bb7be0e24d2bbf27bb0b2b7e56ee22b29bbde7baf0d7bfb96331e27ba029de9ffdff7bdb7dc4da836d0e58a0829367ec84ea256833fd4fe1456ad4dd920557a345e12000 +B = 1f3406a20e20ebf96ccb765f898889a19b7636608fd7dc7c212607b641399543f71111d60e42989de01eaa6ff19a86ea8fbde1a3d368c0d86dc899e8e250fc764090f337958ca493119cbb4ad70cbfae7097d06d4f90ec62fbdd3f0a4496e600 +LCM = ee502c50e3667946e9089d0a9a0382e7fd0b75a17db23b56a0eec997a112c4dbd56d188808f76fe90451e5605550c9559ef14a95014c6eb97e9c1c659b98515c41470142843de60f72fb4c235faa55b0a97d943221003d44e2c28928f0b84bf071256254897ed31a7fd8d174fc962bc1311f67900ac3abcad83a28e259812f1ee229511ab1d82d41f5add34693ba7519babd52eb4ec9de31581f5f2e40a000 + +GCD = ef7399b217fc6a62b90461e58a44b22e5280d480b148ec4e3b4d106583f8e428 +A = 7025e2fe5f00aec73d90f5ad80d99ca873f71997d58e59937423a5e6ddeb5e1925ed2fd2c36a5a9fc560c9023d6332c5d8a4b333d3315ed419d60b2f98ccf28bbf5bf539284fd070d2690aeaac747a3d6384ee6450903a64c3017de33c969c98 +B = df0ac41dbabce1deeb0bceb1b65b1079850052ecf6534d0cff84a5a7fb5e63baee028d240f4419925154b96eaa69e8fbb1aae5102db7916234f290aa60c5d7e69406f02aeea9fe9384afbff7d878c9ac87cd31f7c35dff243b1441e09baff478 +LCM = 687669343f5208a6b2bb2e2efcac41ec467a438fde288cc5ef7157d130139ba65db9eb53e86a30c870bd769c0e0ab15a50f656cd9626621ae68d85eaff491b98da3ea5812062e4145af11ea5e1da457084911961ef2cd2ac45715f885ba94b4082aa76ffd1f32461f47c845b229d350bf36514c5ce3a7c782418746be342eca2721346ade73a59475f178c4f2448e1326110f5d26a0fef1a7a0c9288489e4dc8 + +GCD = 84b917557acf24dff70cb282a07fc52548b6fbbe96ca8c46d0397c8e44d30573 +A = 81dbb771713342b33912b03f08649fb2506874b96125a1ac712bc94bfd09b679db7327a824f0a5837046f58af3a8365c89e06ff4d48784f60086a99816e0065a5f6f0f49066b0ff4c972a6b837b63373ca4bb04dcc21e5effb6dfe38271cb0fa +B = 1da91553c0a2217442f1c502a437bb14d8c385aa595db47b23a97b53927b4493dd19f1bc8baf145bc10052394243089a7b88d19b6f106e64a5ab34acad94538ab504d1c8ebf22ac42048bbd1d4b0294a2e12c09fe2a3bd92756ba7578cb34b39 +LCM = 1d0530f8142754d1ee0249b0c3968d0ae7570e37dadbe4824ab966d655abf04cd6de5eb700eba89d8352dec3ae51f2a10267c32fbd39b788c7c5047fe69da3d7ad505435a6212f44899ba7e983bb780f62bcdee6f94b7dba8af7070a4cc008f351ae8be4579bc4a2e5c659ce000ad9c8cdc83723b32c96aeb0f5f4127f6347353d05525f559a8543cd389ad0af6f9d08a75b8c0b32419c097e6efe8746aee92e + +GCD = 66091477ea3b37f115038095814605896e845b20259a772f09405a8818f644aa +A = cedac27069a68edfd49bd5a859173c8e318ba8be65673d9d2ba13c717568754ed9cbc10bb6c32da3b7238cff8c1352d6325668fd21b4e82620c2e75ee0c4b1aff6fb1e9b948bbdb1af83cecdf356299b50543b72f801b6a58444b176e4369e0 +B = 5f64ca1ba481f42c4c9cf1ffa0e515b52aa9d69ceb97c4a2897f2e9fa87f72bae56ee6c5227f354304994c6a5cc742d9f09b2c058521975f69ca5835bce898cf22b28457cd7e28870df14e663bb46c9be8f6662f4ff34d5c4ae17a888eba504e +LCM = c163cb28642e19a40aa77887c63180c2c49fc10cda98f6f929c8131752ea30b5283a814a81681b69b9d1762e6c1a9db85f480bc17f998d235fd7e64c1caa70ef170c9e816d3e80f516b29f2c80cfb68bf208b4d5082ef078da4314b3f20c7d6c54b0aeb378096b029a7b61c0a4cd14aeddc01004c53915a4f692d2291752e5af46b23d7fa6dd61f2d56c6f4bf8e6119688abac8fd7aba80e846a7764bb3fca0 + +GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +A = 0 +B = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +LCM = 0 + +GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +A = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +B = 0 +LCM = 0 + +GCD = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +A = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +B = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 +LCM = bb80bf51757ba696c700fa4e4c0132b3151d2bf9ebff8382f808ded78be67182 + +GCD = 120451d8307219aa0c96f328ad653ccd462e92423ca93ed8a3dde45bf5cb9b13cdaf9800e4d05dd71c4db6a129fb3280ee4ec96ec5297d881c1a8b5efccbd91fef21f5c5bf5fba42a4c8eaa358f620a074b7a17054527bdaa58d5acaa0dfdc48ecba1a10ebf4d57bb4215de406e6be13fed3fe493b1cd1e2d11a8d4ac03c47756 +A = 3f8179a8e1f0b342475a855c3e1bae402dd41424cf24a0b4d2e263c8efb08bde7d92eae8607fb5e88b1378f0f1bd0733f229a35be6b1383a48d32749d5d6b32427d26323b7ab05bb5781289e96bfbc21971439319b15f6c0fe93fdb35d0b67ec41443c59a081dd3cef047ac797fccb45bece84c0bb0bb7e1797259526d8ec9cc63ba4d32cfc692ccd3d243cb2b53ac216312f3a8e8c0daa09d21b6150d697639a5e52059414a417c607be8ec0eee2e708219cadbaf37a369c4485b01ed87bbc2 +B = 2c474e396a2dd9cd10b9d7313f69d3b4ca123e9fd853edd488339236d14c56453a1381958864a04d2624e81995dabcdd0ccf60db9917813f887de68da075d0ea4440001e18f470e43b38ee3440b49be651d709fbdef980e3e4149913f4ae2681124f54523f4881376ddb533b5219e804cc26f4c2e577be4e02613c4da80ba1215775b0a5178a965ad47bd2befb32493943ded1004ef66347b4983f8d1ba990d4a943505dfce6debcfb322842ed88106cd6dee9aa592ff0d2274bc727a6e1f14c +LCM = 9c129cf649555bfd2d3d9c64dc6d6f022295e53bca5d2f218adaa66aa60eb4694429b7e83bf81b6df4459c5104023ab9a33f006ffcd8114507baa17e2ef6fe23ebdd4740f66879033da2041f2cb7ba517ad3526ffe75614ea9432c085f71b2d65a736bac7ba42b639e330b82733372083843dcb78b6a273ab20e0d4b7c8998a14048aa15bb20a0a0bd997917107274c89b4cec175fb98043d52e6c555bd9e0036566d052a6d4e7e276d1e8835e1f06e3ca46d47747ba586e95fb1a790d992834b7c3e136141eb8a434e6c12067246ac3c0a81c69e03b1ed28aa0b3173d6eff83d278c2f461a47a416f3f9a5dae3bb410fd18817bd4115e7f1e84b936cc02364 + +GCD = 95aa569a2c76854300d7660847dd20fe0b8c445fdbcaa98465cee61aee76ad6a438e75a8c573198570ffb62bc07ec3a2be0ae0a1f631670fa88d6f75f3161e8b9a4d44b6801ffc884c7f469c5ed1f27b1edecce9f2977f9e92d1a3b230492fea7e6f2af739dc158a7fbd29856cbedb57b4119e64b27ab09eb1c2df01507d6e7fd +A = 4c653b5bfec44e9be100c064dffe5d8cd59b0cf4cc56b03eabb4ef87cfda6506c9a756b811907fe9d8b783eb7a0b9e129773bf1da365ddb488d27b16fb983e89345d1ccdb4f06a67a11925c3f266373be5d7b0075189c6f3c2157e2da197058fe0a7bcc50adc34e99e254a29abbe2d5948d3157e1b0c3fca3d641760f7b9862843b63abef0b3d83fd486f4526b30382fda355575da30e9a106718a3921774c4d69f5311f8d737fe618f5236b4763fe1b2ee7f13184db67367d3903c535ff6d7b +B = 2dcca83c99a28e9fd2f84e78973699baf2f04fd454094730948b22477834a0064817b86e0835e6d7b26e5b0b1dcf4ad91a07ac0780d6522df1fcac758cf5db6c2a5623d7c0f1afefd5718f7b6de639867d07a9ec525991304e9355d1635104bea837f74758d6aa2aab4e4afbb606af1d98de7417505e4710cd0589bdff9a0bf38a857cc59a5f1781043e694fc2337fd84bdeb28b13a222bb09328a81ec409ad586e74236393d27398cc24d412135e34247c589149e134b97f4bd538ac9a3424b +LCM = 1760c0b0066aa0695767099e87e9388729ea89b8e8c36bddcd04d257591e741613c07b0e69447c0a468c33a745084171e06523d987d8db40a1433bf435325e8a724a0876503b34495170ff3671d42117a2e4f3a75b1d9dd809a34fa0fb26fe50d84f80a9b02e40190e5efb927a5a61a03f13edbce2e666af6c3a2a9bcb84e47e3090008753ff27c4b8cf06480f471379a93f5230923623a83b286b71a555cd5e5347282f664ed90b14b2c4de84a70375e488211a7b3931119ef3bbe029b712389fe784818a0bf29d80733ce9cc940c547aa1eb3f06d492eb676bf37802283c82ce76156dfaab5c2d5107e08062681b5fa169f6eb68e1ab8bd9b2005e90bd4fd + +GCD = 244b9b1290cf5b4ba2f810574c050651489f2d3a2b03e702b76ebfaf4e33de9bbe5da24c919e68d3a72eadd35982b3a89c6b18b38ff7082ac65263e52b6ec75a5717b971c98257b194c828bff0216a99536603b41a396ea2fb50f5ea7cf3edf10bb0d039123e78593ae9ffcbbba02e51e038533e83b6bc73c70551d6467f39809 +A = 41a0b1310669500681cdf888836f6c556758750f562d743ac780dd4c0d161856380e44fdbb1f8a2786bf45be6b0e7f1cb2cd85f6b9e50acc72793d92383c7d7fb796fc74d32e8fac8225bdc19ae47546d9c9c75f5f06ca684f07daccaf89ccf2cddeb7ec255d530c7dd1e71daf44cafdc9d30fbcb1cbaefae3480585f79f4177e3834a5bc91845e2e8cd8aeb27f484e5e5b2c3c076dbb6c23e91303f0a0fdde83cd33a8ea6ed1549e727b4d766c1017c169710fd98e1585d60f66e121f9180b3 +B = 251f5aeaa60b3959285f49540cdaf8e21451110bbddb9933bbbcaea3112f4eb45e435a3ba37c52d2ab79ce997a8f6c829b3aa561f2852924b8effb52396d09d2bf257ebb4fb56c7aa25648f69b06d2cd01e876c9f9c0679de9e6fffa79eb7e603723e5af7de46ee405a5a079229577b5b6fffb8d43e391fe6f4eb89638e64d6eff8026249aaa355a91625eb0bfd14caa81e4c3586aaa2e94fde143a44f223a91e226661d12f55dfcdb4215e5a64e14e968005733be6a71c465de312ca109b34a +LCM = 431f918b274f3e43f446e4e85567883d6536a0332db662cef088f5a36b0f4b68372048174ba10fee94b9f8f1c2e189c974be2e6e8ae8e2ae108445326d40f63e38d8d4e2e46174589a3cbc9583e0036dc8146e79eee9e96f4436313b3f143dd0f5aceab05243def7f915169c360f55ef123977cf623c5ba432c3259c62fb5e37d5adab0f24b825aa4ada99ec4e83e9ca4698399e1ed633091ce5f9844c540a642cd264201116ed4168aa2105a5159f5df064f845830c469140f766c7319052ce59bd1ad7c3f2d8c30e54f147f6aeb5586c70c984302ba18d854a60aec01b394c7d66fa33fe18fe4a8cfb3238df219294e6e42190a30d28b10049a1b75853a4e + +GCD = 206695d52bc391a4db61bf8cb6ea96188333a9c78f477ee76976c2346dad682cf56ca6f176d86ef67d41ff5921b6162b0eca52359975872430dd14c45643eacdf028d830770714c033fd150669705851b2f02de932322d271d565d26768530c3f6cb84f0b3356f970b9070b26c050ead0417152c324c8ffe266d4e8b5b7bef3a +A = 1114eb9f1a9d5947eb1399e57f5c980833489685023ed2fe537fe1276c1e026b9a19e6fff55aa889d6c4e977b6e6f3111e2ad463138637b50f42cf32e57d83f282de9e72f813e5969195159a666d74dcd689bd527c60199ae327f7bd548ac36868fea5fdf6f35d19b921e7c10b6448ca480de6826478cd0642d72f05af3f8e65ce42409fbd49f56e81946e89c8e83962c4edc0ed54600600a305e52d081aed3c351e450e11f8fb0ce5754c92cf765b71393b2b7a89c95df79b9ea1b3cb600862 +B = 1d8f3179ca7b5cc7119360c10de939ffa57c9043da2f2b0ca3009c9bdad9f19ed16e3c2c197bef4b527fa1bf2bbab98b77e26c329911db68bd63d3d0fbfc727a977395b9ad067106de3094d68e097830858c5ccfa505fc25e972bdee6f347e7d1163efacd3d29a791ec2a94ffeed467884ae04896efc5e7e5f43d8d76c147e3c9951a1999173bc4e5767d51268b92cc68487ba1295372143b538711e0a62bf0ac111cc750ca4dd6c318c9cbe106d7fc492261404b86a1ba728e2d25b1976dc42 +LCM = f9570211f694141bfb096560551080cbe02a80271b4505591aaea9e3b99ea1d5ac1c1f2378fd72799e117ac2a73381b1ad26314e39972164d93971479ee3ba21a4d98cef0bd299d540ce5826995dcee0de420dff73d30b23cbf3188c625c7696df517535bc5675d71faa00807efbebdca547933f4a37849d1c014484a77da6df0670c4974bcc91eb5f5fe5faf9dd095ef195ec32ad9eeebf0e63288b4032ed9e70b888afc642f4ff96f0b4c0a68787301c12e4527fe79bdfe72dd3844ab5e094a9295df6616f24d1b9eeebc2116177dacf91969dda73667bc421ef3ccd8d5c23dddc283f5d36568d31f2654926be67f78e181075bdc148f2b39c630b141ae8a + +GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +A = 0 +B = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +LCM = 0 + +GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +A = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +B = 0 +LCM = 0 + +GCD = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +A = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +B = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 +LCM = 3d319c42d872f21131ce5ff3ab8bec94339308e620316dda218e85fedcd511cd62f0b2f3448d5e58fd3520ae8118abd54ead9ad9e8ec3890365c6b2cca2172d4b8839b2d2c5ab02f65180826cb0cd5c9798f5d6261efe6e6ec31dea047da7c486b0590359e6f333557f67ceebf9ea9cd5dd986a999a8c88bdbd0ca21816b2423 + +GCD = 2 +A = 14e95a85e59ade9ef39e2f400c65db18702fa5fc485b9bba479a5282b2206129160e54f73ef4917983c17b4c5ebff7be112a886de069706eee29ba902515cb038 +B = ddcfff1d39c90c599f55495bf71c1e7597c6b08b7430707f360c6a6e5137bbc7b403c6d9e2c34f3d2f29d5d32b869346853c2de239cc35381bdfb4a01569211a +LCM = 90f38564ee72e55d362c04599e7d74f068c75f541b84e97abba2841f1a9f66b06b5c9009f6a4c2e319fced85270588de03ccebddbd9279aaecb13bdc1dbea7f42acaee751cb7da83779b8785cc86f41b94b13b54964208ca287d981634778d1096f20e76ca636c0717fd27e0800c43f599a5eded807421b502eaf9990a8c8ed8 + +GCD = 4 +A = 3c719c1c363cdeb7b57c2aabb71f425da4c3e6d3e447204d555e7cf0f3d372bdda906f36078045044978dafc20171767c8b1464d52dfdf3e2ba8a4906da033a8 +B = 30fe0ef151ac51404e128c064d836b191921769dc02d9b09889ed40eb68d15bfdd2edea33580a1a4d7dcee918fefd5c776cbe80ca6131aa080d3989b5e77e1b24 +LCM = 2e4526157bbd765b0486d90bcd4728f890bc6dbd9a855c67ca5cb2d6b48f8e74e1d99485999e04b193afca58dbf282610185d6c0272007744ff26e00dbdc813929b47940b137dc56ba974da07d54a1c50ec4a5c2b26e83f47cf17f4ccce8c3687e8d1e91d7c491a599f3d057c73473723ce9eee52c20fe8ae1595447552a7ee8 + +GCD = 10 +A = 44e04071d09119ea9783a53df35de4a989200133bb20280fdca6003d3ca63fdd9350ad1a1673d444d2f7c7be639824681643ec4f77535c626bd3ee8fa100e0bb0 +B = ca927a5a3124ce89accd6ac41a8441d352a5d42feb7f62687a5ebc0e181cc2679888ecc2d38516bdc3b3443550efccac81e53044ae9341ecace2598fe5ce67780 +LCM = 36805ba9b2412a0cb3fe4ed9bdabfa55515c9d615a3d0af268c45c5f6098d2de4a583f3791f1e3883c55d51ce23c5658fd0e8faa9a3709a1cfbd6a61dbab861690f27c86664f084c86cfd4a183b24aaadf59a6f8cbec04f1b0ded8a59b188cb46ae920052e3e099a570540dbc00f7d4a571eef08aa70d2d189a1804bf04e94a80 + +GCD = 100 +A = 73725032b214a677687c811031555b0c51c1703f10d59b97a4d732b7feaec5726cb3882193419d3f057583b2bc02b297d76bb689977936febaae92638fdfc46a00 +B = 979f4c10f4dc60ad15068cedd62ff0ab293aeaa1d6935763aed41fe3e445de2e366e8661eadf345201529310f4b805c5800b99f351fddab95d7f313e3bb429d900 +LCM = 4460439b4be72f533e9c7232f7e99c48328b457969364c951868ceab56cb2cbbeda8be2e8e3cae45c0758048468b841fdb246b2086d19b59d17b389333166ab82ed785860620d53c44f7aaaff4625ee70fb8072df10fb4d1acb142eadc02978ff2bb07cea9f434e35424b3323a7bda3a1a57aa60c75e49ebb2f59fb653aa77da00 + +GCD = 100000000 +A = f8b4f19e09f5862d79fb2931c4d616a1b8e0dd44781ca52902c8035166c8fca52d33a56ff484c365ec1257de7fa8ed2786163cfc051d5223b4aad859a049e8ba00000000 +B = 6e54cb41b454b080e68a2c3dd0fa79f516eb80239af2be8250ca9cd377ba501aabafc09146fad4402bdc7a49f2c3eec815e25f4c0a223f58e36709eefd92410500000000 +LCM = 6b3020a880ddeff9d17d3dc234da8771962de3322cd15ba7b1e4b1dd4a6a2a802a16c49653865c6fdf6c207cbe0940f8d81ef4cb0e159385fd709d515ee99d109ad9ad680031cbae4eab2ed62944babdade4e3036426b18920022f737897c7d751dce98d626cdda761fec48ad87a377fb70f97a0a15aa3d10d865785719cc5a200000000 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/miller_rabin_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/miller_rabin_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/fipsmodule/bn/miller_rabin_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/miller_rabin_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_exp_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_exp_tests.txt new file mode 100644 index 00000000..a6cf6f4e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_exp_tests.txt @@ -0,0 +1,775 @@ +# ModExp tests. +# +# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M. + +ModExp = 00 +A = -01 +E = 01 +M = 01 + +ModExp = 01 +A = -02 +E = 01 +M = 03 + +ModExp = 01 +A = -01 +E = 02 +M = 03 + +ModExp = 01 +A = -02 +E = 02 +M = 03 + +ModExp = 00 +A = -03 +E = 02 +M = 03 + +ModExp = 02 +A = -04 +E = 01 +M = 03 + +ModExp = 01 +A = -04 +E = 02 +M = 03 + +# Regression test for carry propagation bug in sqr8x_reduction. +ModExp = 19324b647d967d644b3219 +A = 050505050505 +E = 02 +M = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 + +# Cover the E = 0 case for small numbers. +ModExp = 01 +A = 86b49 +E = 00 +M = 30d26ecb + +ModExp = 00 +A = 00 +E = 00 +M = 01 + +ModExp = 208f8aa0 +A = 86b49 +E = 2 +M = 30d26ecb + +ModExp = 27308229 +A = 17591bb +E = 6 +M = 30d26ecb + +ModExp = 2bdf498f +A = 21292626 +E = d +M = 30d26ecb + +ModExp = 11317167 +A = 4a655df24 +E = 10 +M = 30d26ecb + +ModExp = 2e1b88e +A = da6b761a86 +E = 35 +M = 30d26ecb + +ModExp = 20a12ec3 +A = ea811 +E = 2 +M = 23bc042f + +ModExp = c42ced +A = 1011a6a +E = 4 +M = 23bc042f + +ModExp = 4637d79 +A = 28d9a601 +E = 8 +M = 23bc042f + +ModExp = 20e5669b +A = 72fe6bc20 +E = 11 +M = 23bc042f + +ModExp = 142ab9e3 +A = 9a07b9363c +E = 29 +M = 23bc042f + +ModExp = 14c64646 +A = 822df +E = 3 +M = 30915765 + +ModExp = 160e35a2 +A = 15ea542 +E = 5 +M = 30915765 + +ModExp = 2f23a488 +A = 34d2e02e +E = e +M = 30915765 + +ModExp = 28e67f93 +A = 636a32703 +E = 14 +M = 30915765 + +ModExp = 29bfeaa5 +A = c8646998e6 +E = 2c +M = 30915765 + +ModExp = 30959e22 +A = 81dad +E = 3 +M = 326dd68d + +ModExp = 1a1da4fa +A = 116adb9 +E = 5 +M = 326dd68d + +ModExp = 272bf0d8 +A = 2d21ef08 +E = 8 +M = 326dd68d + +ModExp = 29f5054b +A = 76989850a +E = 16 +M = 326dd68d + +ModExp = e6c7b77 +A = b88ee70d2a +E = 3e +M = 326dd68d + +ModExp = 369605e1 +A = cf26f +E = 2 +M = 3ce082eb + +ModExp = 168a3c5d +A = 1f82caf +E = 5 +M = 3ce082eb + +ModExp = 125c4bb8 +A = 2e9c4c07 +E = 9 +M = 3ce082eb + +ModExp = 1c5fe761 +A = 523ab37f1 +E = 14 +M = 3ce082eb + +ModExp = 21703009 +A = dc832165e8 +E = 20 +M = 3ce082eb + +ModExp = 1228d1e +A = a5555 +E = 3 +M = 24665b27 + +ModExp = 5226af4 +A = 1077bd6 +E = 4 +M = 24665b27 + +ModExp = 1b14eac1 +A = 2db3a834 +E = f +M = 24665b27 + +ModExp = 161727bc +A = 6bd962cb6 +E = 19 +M = 24665b27 + +ModExp = 10d61d0d +A = c10caed407 +E = 28 +M = 24665b27 + +ModExp = 233da406 +A = b125f +E = 3 +M = 33509981 + +ModExp = 24032799 +A = 1656b7c +E = 6 +M = 33509981 + +ModExp = 129ecebe +A = 2e671504 +E = a +M = 33509981 + +ModExp = 20c20bac +A = 4d7a2de44 +E = 1f +M = 33509981 + +ModExp = 2e3ce9d3 +A = c53b3def4d +E = 31 +M = 33509981 + +ModExp = 12fadfd6 +A = b4cf8 +E = 2 +M = 36e9d4ae + +ModExp = 457ac85 +A = 1b1c7e9 +E = 7 +M = 36e9d4ae + +ModExp = 31debef4 +A = 3a973028 +E = d +M = 36e9d4ae + +ModExp = 2333ad93 +A = 552b97c45 +E = 11 +M = 36e9d4ae + +ModExp = 99ba1fb +A = 8bfb949cbb +E = 28 +M = 36e9d4ae + +ModExp = 27b691de +A = 93492 +E = 3 +M = 298fdb16 + +ModExp = 3c2b70f +A = 14e7b0d +E = 4 +M = 298fdb16 + +ModExp = 1486cda7 +A = 29acff81 +E = c +M = 298fdb16 + +ModExp = 11725275 +A = 507489205 +E = 13 +M = 298fdb16 + +ModExp = 24d14627 +A = e71c55606d +E = 35 +M = 298fdb16 + +ModExp = 222b8d14 +A = 9b1a0 +E = 3 +M = 3db59d12 + +ModExp = 3b8bd47d +A = 13f4e8d +E = 7 +M = 3db59d12 + +ModExp = 17e72356 +A = 334774ce +E = a +M = 3db59d12 + +ModExp = 306447ca +A = 47079ddd2 +E = 12 +M = 3db59d12 + +ModExp = 90bef3b +A = a75d62616d +E = 37 +M = 3db59d12 + +ModExp = 1 +A = cddd44f47e84b3276cc36a5c0d742cc703e61c4756168601fbb1b6eb598c161019562344dd56ab6f603d920a12c360b285e6496a3605a2f8d691c3598233ee9366b5f2692554893bdeb67b7bdaf35ab7273ac593145e26bed82c70ba5793bf4bc5cac4c80b01785d1496beede493806e4f4aa89fd8d41de80dd6d0a3e2742678 +E = 0 +M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb + +ModExp = 0 +A = 0 +E = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e +M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb + +ModExp = 5150fb769d5c5d341aaf56639a7bcc77c415fe46439938a2190283409692f29cd080bfe3433005d98d24718a03a3553c8560c5e9c8ed0f53b8945eb18290e1c1a83d919302510f66dd89b58acc2de79ad54b8a30d3e1019d4d222556beefca0821b094ecf104b5e4cfce69d2d520d2abf54f3e393d25ed3d27e8c2e3ca2e5ff9 +A = ead8c5a451541c50cab74de530c89376d9a55c723e0cac3c84b25f0093c08a2961e49ab48966361c42c9f99111587252d98395b76788400d75c66ef208ea2767a28d6f8dc3a859f39c95765d57f139e7fc14f47c908c62df051e7216d379f52028843b4d82ef49133cce8fe671ae179423ac8da5be43b01caaf425cd969300cd +E = 8de689aef79eba6b20d7debb8d146541348df2f259dff6c3bfabf5517c8caf0473866a03ddbd03fc354bb00beda35e67f342d684896bf8dbb79238a6929692b1a87f58a2dcba596fe1a0514e3019baffe1b580fc810bd9774c00ab0f37af78619b30f273e3bfb95daac34e74566f84bb8809be7650dec75a20be61b4f904ed4e +M = c95943186c7567fe8cd1bb4f07e7c659475fd9f38217571af20dfe7e4666d86286bc5b2bb013197f9b1c452c69a95bb7e450cf6e45d46e452282d5d2826978e06c52c7ca204869e8d1b1fac4911e3aef92c7b2d7551ebd8c6fe0365fad49e275cc2949a124385cadc4ace24671c4fe86a849de07c6fafacb312f55e9f3c79dcb + +ModExp = 1 +A = 935561297d1d90255aef891e2e30aa09935409de3d4a5abc340ac9a9b7dce33e9f5ce407f3a67ec30e0dc30481070823f8542463e46828d9cafb672a506d6753688cbad3d2761079f770c726c0b957071a30876c4d448e884b647833befbcd6b582787bf769d63cf55e68c7b869a0b86374f8920516cf5d528f348b6057450a1 +E = 0 +M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 + +ModExp = 0 +A = 0 +E = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d +M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 + +ModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0 +A = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d +E = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d +M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061 + +ModExp = 1 +A = 9d92629c1ab181c50c31619e8acd0d235a1f5fc7a0bef4d4fd54b4f1968d45921f8522efe88e69c6c14c576c564592b9feb00d1554b88b038934eaf4a8ce81a2582732387490181ef158360c8b2d9ccb326ffe043f776a50cb8202837f08ca743b562eefa007150ab7012c341b16248478d4775c02ad71ea13d5e82b71e2d600 +E = 0 +M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b + +ModExp = 0 +A = 0 +E = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b +M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b + +ModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff +A = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839 +E = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b +M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b + +ModExp = 1 +A = a8558e7f455b27c0c46d7d0862eb409cdefbeca945e0284b5bf425b7ac0f3d316bc365594cc1639decffc621214d61479bc75135120d4ac09ea8b742ad7ec1822091b62b1c6f564fe5e2f4f5b7def92cbaaa9a898549207ab01b91c2324fbd306a87f7d6379b6fb6493c5fca76729767f136120da9c90bdc7d364f7d242d5acc +E = 0 +M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f + +ModExp = 0 +A = 0 +E = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f +M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f + +ModExp = 292f0b39ca0f1c850b1a00cffd2d54924fcd5fc7e7504c9d593e6c0ff74760b1f4bdd81679fe06c50248336f3108c593fa111072ee87d0fcc89a63243a1dc89044503663eee9bc18f51c3e0193d9108303e12ac90ff78f6ec752a4386af09c42db524a7cbe9a3d4fcccd56c34d283bcc9debc17158b5fe8df0c1888a9841bf8f +A = b4fde2908745ff92cc5826a27dcfdda09e8fffee681844fa4c7f1354d946d5d84e0e0c7a4a4cb20943d9c73dd707ca47d796945d6f6b55933b615e2c522f5dfc33e0652917b4809bab86f4fa56b32b746c177764895492d0a6a699812b2827fe701d40ef7effd78ea8efe1cac15ff74a295a09614bf04cae1a5017872ba22efe +E = a5524b41dfc6b570df1d8f6633ac7777c1131abe3a99c6166b0d29d3b8883c41b00a0c53cdd6f42820bf05c810b6ec53e77a8c1b9344ea0c91d4f410a2f204c369f3db33bf8c88217fc2cf802a9d9bce8119242d8e781875b85431be170076498c0963574ee423551aec9557e2fc672ab1ab5d0cbb1c400535df9481e7934d8f +M = 88f3c87ac5e3272a21b8a858da640d6939fb8113a95412c38663a0f352686d69a5d7927e60b484b9fcb8ef12978fe25ff2ebc9b61c5450e04222ef20ba3cbbdc5ec45581ce0f58e10be7bb9de7fa08752303a7a1db23b2ac9c6692ec63bf09ecd6639e06c5491ba568ea886620d71da32d329615f0e1443a75d09ae35b8a2d7f + +ModExp = 1 +A = e2845c572b46496ac158a731f612fd40ef626fa7134755c25b1b7614f4d7b29164e6142ddb7985e4c7ebc575855ff901e95927fe98a5aea2ad3a4720c75782323bea1518b2c57790f44efd9411be4e95b3896bad1e73c59658290b309e5a7eb5ef8be08125063e57336b80f17eacee88966d12bbaaa15a25929c82e027cf696f +E = 0 +M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d + +ModExp = 0 +A = 0 +E = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4 +M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d + +ModExp = c90e4c69df92e26549b016950b59080947f5403430698e128477782480dd70be96bed2b9042dd8c708eb432e02710555b97af11ce6fa9b53395022851c32d1f53f04237fb0763563b440ca6e81a50d909d907d9c26b7d3c420dbf88f7dadd488666848135f8cdc608dcfb0691989289fb54379c2e84c262f9765f68c012ca1b9 +A = 882ea1b9b6c79a3b1bdfd284658cb6227ad825e0178cab713c7413c2ec34f03cfaec470c4f5c521f5e9899a2123878ff0f5b36a4196c08ad1b04d03746c4bfb5d126f5eefbfe172627d6732710a8ac8890cedbd4fdef69a19f2b3253a5aa0e5dd5484f72d59b17bdd1dad3db209a3ab839368ed3975069685911d7b35e41a9e6 +E = a55703a72ca3f6074b939ed3d748196a684a3c8e411c2b39a9beb98993b6eb7ea3fa16f41bc5b5c3710b91c0fc74a8072793052f872f61695db3a2df872eaa427a110f1a8d568c85d58bd350d0df8eced7a10be80f7567360c1a8047b9c44aa2967cd0d9dd2caea2c1492358c2db4f0214da343fdf2e34272865dc5c63be2ae4 +M = cf0dee80177869a532f0c6c3a0bda3aad79bdb6b70b6c227b32d75c26e394a90c1f2a6c2bb841ba9f6556b15654a79d8b1dd0c90709a093497bf40be0807cdbb378a74de5893c25067224d3ea8d37387ed6c4a981138853cb89caa9ce6cd0f6a1e95de24d558e90960f93844db4d01e372650350d45a9d34a36042b4d4b9e78d + +ModExp = 1 +A = d7a99e65b8af86b1c51d851f0447e43cd4f343cb0ada7236283e69aa7ebd383826acc9809e5dbc4002d0f2430022cb026458189db3805ce2de1142a31ba71a6c064ab51f0059eb4b931b8bcbaef023c38d57aa5f3e14f5df77e547fc028702071b58bd57338be1e1e4f98d3553484e4de359cefa29c5f58d3fa5d823f389dbef +E = 0 +M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d + +ModExp = 0 +A = 0 +E = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e +M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d + +ModExp = 186c50ae259aa0fd31859cbcfea534e626a254de33956d5d719334bb32e7cf37cf199a21f079a5b90497228994d05efe19ccd8c769cd81f896286e8ae557cacd1630a928c629ecdfece29ab3697794aa707734e007318fa7029b050bb09ebbe6986187c6ca843f55266d275620b3f0fec0ad5f847ce8b314d929d128b33a249e +A = 9d5e345793faddca9867f23eeddf6816c1e837f7a2cf96fa077212514acb6be87ac01a237d8f2f1d07d27a8ddd1b0ae0d97e1bda4f205a89435017284cdedea3e407b1b940d6f52112b6359b3e86e4c83074b17c210ae2c8856b42b169b4a7a6dfa65b368a7959496cf9bb1ee93d019dbd79101830e3f5ed08604ab90890b914 +E = 95793fe33696f53e37498b2b65aaf27079e27acf1da97dda2c3e0803e8a02139f574e04ee03f7d1ddd029f528e3f3644515ad6f10f0beac2767f23d9cd8a8b9b6c6e376e36b64a0ae2711d7d31a5a75011641935b503110edbefe9f0ff2da27b5c5f6bb8cc151fdc86f67191bb99160c6cacc86ca368d5bdfafd3f3ff5161b1e +M = 8315dacf124bd473c578946347e83d1b20c750a7d9533d6215591be40bc78bcca77821f8c8f95375bbd6372515ada63d22bed2fa49bd6fabb0040c538d08db25b09d2fda02a93ab086cd1c27df93c37ee9c6a0527d089179b8f92b5dc3acf5ef1c75906fb80b03f5c2442a7a4088640f66376575ecfa4c697c1a571397ee5a0d + +ModExp = 1 +A = e6a079bdf7b0638d50b183475e9ddfd5cbdebfb29f5fae8e9be402a0bd36085737b556492ea7fb4b1000ae9ce59db66098129b757cfb29224275fdaa46b8b7eb18a93ca7d3e446dc38c734b683d7ba7927b008d993aab01f44239d3c76be76d1503908e9b5e73b36c43ae0771368b01f39c042693bd92c4fc50810f059e1b332 +E = 0 +M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 + +ModExp = 0 +A = 0 +E = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929 +M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 + +ModExp = 60719701a2dc0bcde281a93ce0b8421d1a718adee43c1b5d9fe9e697a48ab3db4f9f33c73cff305ab6b6c300c149b05c6b289dce4580860dc56bc59de81ac074ecebdc65aa3ca040b44e5b3c80ddba1658d78b9abbc4c77e5f171f5582e70ab4438a8e1e2f062d618c4ad09c70c73b5b5fbc9f8f0bbdf1d530a933b705f85af8 +A = e1b400cd3b1f2f1c6b437adfdb970d2c8108f1b39bdbb13582179552011c6c97cba6bff2c463212b7f62776aa3e3aff9f175990e79395e819c144350b0a23d61638d500ecc97726b098e1af334aece23a851c718612442c04eb7b3805a24cc8f5b90042145eb5e5d6a408092832b6bbeb8a621419a9282fb5c075f41c7f1fdc1 +E = f0460c5ca9b3a5c2d1b93c201d020dc43e1c81d1daba432e2cd310902da23eb81a5172b0b357484eb8fa2c04c270893b8198c8ad35453405dadaf05195b3aeb5ec0ccacecb4b6227ca43b27b97e240a4148a472670ed60f304302f757495fd4a91af0fe09800db0c3043a6ae213bee6703ad80523ca433d99ca0eab1e0b7c929 +M = 81dd561d5d5327fc5ed7c9236b5fb21ef713c6d5e36264ba65ccc801b8eb107b714aad65bb503bb1f4721c0a6f97e5ab89300f049f42a4616ae43d29c089c286687484d18629c1be1b5befbdd0b3cfc86b1d28add89df4cc5e68dac3f56f2490a9068ca9c634ec258c030ec5023baa9133fd2af32fd1112895f9da549d410247 + +ModExp = 1 +A = 9dd1e6f2d3ff24096b54e0ebf0f10e283e484a1cbafc0431adda1296ed97692f3ba99440fd4f67c96dd8bab850e1123361c99362df9ea205ff8e90d1b329459f54730992d5a360e46fcc5f5a909e691abb9a06613d6991bd7c2aa609f0d7b441d7ded0c07b8c394327672d38a905efb2d76aa3be5bb14d0c002aa37e287aee79 +E = 0 +M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f + +ModExp = 0 +A = 0 +E = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436 +M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f + +ModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9 +A = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558 +E = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436 +M = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f + +ModExp = 1 +A = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8 +E = 0 +M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 + +ModExp = 0 +A = 0 +E = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648 +M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 + +ModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa +A = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d +E = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648 +M = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745 + +ModExp = 1 +A = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d +E = 0 +M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 + +ModExp = 0 +A = 0 +E = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836 +M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 + +ModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca +A = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168 +E = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836 +M = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511 + +# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in +# order to test the const time precomputation scattering/gathering. + +ModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b +A = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898 +E = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f +M = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d + +ModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679 +A = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc +E = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3 +M = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf + +ModExp = 465ff295786a88496828fdc763e9292d557957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d +A = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d +E = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560 +M = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101 + +ModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd +A = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9 +E = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c +M = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479 + +ModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c +A = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785 +E = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082 +M = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d + +ModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e +A = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059 +E = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902 +M = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9 + +ModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556 +A = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0 +E = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965 +M = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed + +ModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510 +A = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83 +E = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693 +M = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11 + +ModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232 +A = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef +E = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6 +M = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d + +ModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e +A = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286 +E = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0 +M = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7 + +# See https://github.com/openssl/openssl/commit/e9e726506cd2a3fd9c0f12daf8cc1fe934c7dddb. +# OpenSSL's test vectors do not include the expected value, so ModExp was +# computed with Python 3. +ModExp = ccb051a34f9e26e381e50445632cbbd4abe56bc912020f3edd2db144aedb470095c4c33e3342d1dc4bb4056ba3078366af4cee507e85bb1b2e499ef25a933810f14faa8b1a9ce5e8d58f2789e27c887a4ff87fa59ff682727a3912a99aae6db8b3b8947d76c8454cffc6fb3f2422dca106c3845b0db68a06e5e9d7b90e552506579d812e7d96bfc6324feec90ea0800463346148f120e7caf403788539f5d87ee45aa5b313c340e0a323029f3a0bdb675510aefec171c01e2a94960cd507e461214028c86ed4e9fce31e7dbdf1a75fd6f973e2aed4a039e53a60a7aa62be8ee1f80a113833ab402d07e17151021cec29fa5b2e628ef9f2d7aa4bc86b6eec8faf +A = 95564994a96c45954227b845a1e99cb939d5a1da99ee91acc962396ae999a9ee38603790448f2f7694c242a875f0cad0aae658eba085f312d2febbbd128dd2b58f7d1149f03724215d704344d0d62c587ae3c5939cba4b9b5f3dc5e8e911ef9a5ce1a5a749a4989d0d8368f6e1f8cdf3a362a6c97fb02047ff152b480a4ad9852d45efdf0770542992afca6a0590d52930434bba96017afbc9f99e112950a8b1a359473ec376f329bdae6a19f503be6d4be7393c4e43468831234e27e3838680b949390d2e416a3f9759e5349ab4c253f6f29f819a6fe4cbfd27ada34903300eda021f62839f5878a36f1bc3085375b00fd5fa3e68d316c0fdace87a97558465 +E = f95dc0f980fbd22e90caa5a387cc4a369f3f830d50dd321c40db8c09a7e1a241a536e096622d3280c0c1ba849c1f4a79bf490f60006d081e8cf69960189f0d312cd9e17073a3fba7881b21474a13b334116cb2f5dbf3189a6de3515d0840f053c776d3982d391b6d04d642dda5cc6d1640174c09875addb70595658f89efb439dc6fbd55f903aadd307982d3f659207f265e1ec6271b274521b7a5e28e8fd7a55df089292820477802a43cf5b6b94e999e8c9944ddebb0d0e95a60f88cb7e813ba110d20e1024774107dd02949031864923b3cb8c3f7250d6d1287b0a40db6a47bd5a469518eb65aa207ddc47d8c6e5fc8e0c105be8fc1d4b57b2e27540471d5 +M = fef15d5ce4625f1bccfbba49fc8439c72bf8202af039a2259678941b60bb4a8f2987e965d58fd8cf86a856674d519763d0e1211cc9f8596971050d56d9b35db3785866cfbca17cfdbed6060be3629d894f924a89fdc1efc624f80d41a22f19009503fcc3824ef62ccb9208430c26f2d8ceb2c63488ec4c07437aa4c96c43dd8b9289ed00a712ff66ee195dc71f5e4ead02172b63c543d69baf495f5fd63ba7bcc633bd309c016e37736da92129d0b053d4ab28d21ad7d8b6fab2a8bbdc8ee647d2fbcf2cf426cf892e6f5639e0252993965dfb73ccd277407014ea784aaa280cb7b03972bc8b0baa72360bdb44b82415b86b2f260f877791cd33ba8f2d65229b + +# The following inputs trigger an edge case between Montgomery reduction and the +# "almost" reduction variant from https://eprint.iacr.org/2011/239 + +ModExp = 00 +A = 19c7bc9b97c6083cd7b8d1cd001452c9b67983247169c6532047eb7fc8933014dbf69fee7a358769f1429802c8ea89d4f9ca6ba6f368fbdb1fa5717b4a00 +E = bbc7e09147408571050e8d0c634682c5863b7e8a573626648902cff12e590c74f5a23ecce39732266bc15b8afbd6c48a48c83fbdc33947515cc0b6e4fb98ae2cd730e58f951fec8be7e2e3c74f4506c7fd7e29bdb28675fe8a59789ab1148e931a2ebd2d36f78bc241682a3d8083d8ff538858cd240c5a693936e5a391dc9d77118062a3f868c058440a4192267faaaba91112f45eee5842060febbf9353a6d3e7f7996573209136a5506062ea23d74067f08c613f3ff74bade25f8c3368e6dba84eae672eac11be1137fc514924fcab8c82e46d092bd047dcbadaa48c67a096ec1a04f392a8511e6acbad9954949b703e71ff837337b594055ae6f3c0fc154447a687c9ac8a2cdfd64a2e680c6ff21254735af7f5eb6b43f0bce86bda55a04143a991711081435ed4f4a89b23fc3a588022b7a8543db4bf5c8ac93603367c750ff2191f59a716340fab49bb7544759c8d846465eec1438e76395f73e7b5e945f31f1b87fefa854a0d208846eaab5fa27144fd039911608bab0eaee80f1d3553dfa2d9ba95268479b97a059613660df5ad79796e0b272244aca90ccc13449ec15c206eeed7b60405a4c5cfdf5da5d136c27fa9385d810ad198dfe794ffce9955e10520efea1e2eb794e379401b9affd863b9566ce941c4726755574a1b1946acf0090bfb93f37dd55f524485bbba7fa84b53addfde01ae1de9c57fe50d4b708dd0fa45d02af398b3d05c6d17f84c11e9aacdbe0b146cad6ddbd877731e26a17f3ebed459560d12ed7a6abc2ea6fe922e69d2622ef11b6b245b9ba8f0940faaa671a4beb727be5393a94dafaeff7221b29183e7418f4c5bb95a6a586c93dbc8ce0236d9dbe26c40513611b4141fed66599adbfb20fc30e09a4815e4159f65a6708f34584a7a77b3843941cd61a6917dcc3d07a3dfb5a2cb108bacea7e782f2111b4d22ecaaeff469ecd0da371df1ac5e9bf6df6ccba2d3a9f393d597499eaca2c206bfb81c3426c5fe45bcf16e38aecd246a319a1f37041c638b75a4839517e43a6d01bee7d85eaeedbce13cd15699d3ee42c7414cfed576590e4fb6ddb6edd3e1957efaf039bfe8b9dc75869b1f93abff15cae8b234161070fa3542303c2ed35ca66083d0ac299b81182317a2a3985269602b1fa1e822fcbda48e686d80b273f06b0a702ca7f42cbbbd2fc2b3601422c8bff6302eda3c61b293049636002649b16f3c1f0be2b6599d66493a4497cd795b10a2ab8220fafad24fa90e1bfcf39ecce337e705695c7a224bf9f445a287d6aab221341659ca4be7861f6ac4c9d33dac811e6 +M = 519b6e57781d40d897ec0c1b648d195526726b295438c9a70928ac25979563d72db91c8c42298a33b572edecdf40904c68a23337aa5341b56e92b0da5041 + +# To fully exercise BN_mod_exp_mont_consttime codepaths, we generate inputs at +# different bitwidths. rsaz-avx2.pl only runs at 1024-bit moduli, and +# x86_64-mont5.pl unrolls 8 64-bit words at a time, so we want to capture both +# multiples of 512- and non-multiples. Also include moduli that are not quite a +# full word. + +# 512-bit +ModExp = 00 +A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 8f42c9e9e351ba9b32ab0cf69da43f4acf7028d19cff6e5059ea0e3fcc97c97f36a31470044737d4c0c933ac441ecb29e32c81401523afdac7de9c3fd8493c97 + +# 1024-bit +ModExp = 00 +A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 9da8dc26fdf4d2e49833b240ee552beb7a6e251caa91bfb5d6cafaf8ed9461877fda8f6ac299036d35806bc1ae7872e54eaac1ec6bee6d02c6621a9cf8883b3abc33c49b3e601203e0e86ef8f0562412cc689ee2670704583909ca6d7774c9f9f9f4d77d37fedef9cb51d207cb629ec02fa03b526fd6594bfa8f2da71238a0b7 + +# 1025-bit +ModExp = 00 +A = 010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 010223abfdda02e84e11cec8ee7fc784fa135733935f7b9054bb70f1f06d234d76dcf3beed55c7f39e955dc1fef2b65009240fd02f7a1b27a78fc2867144bf666efb929856db9f671c356c4c67a068a70fe83c52eebda03668872fd270d0794f0771d217fb6b93b12529a944f7f0496a9158757c55b8ee14f803f1d2d887e2f561 + +# 1088-bit +ModExp = 00 +A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = e91f6d748773cb212a23aa348125615123b1800c9ea222c9374c757702ae4140fa333790ed8f6bf60a1d7dda65c2767cc5f33e32e333d19fbfb5a2b85795757c9ca070268763a618e9d33873d28a89bf88acd209efbb15b80cd33b92a6b3a682e1c91782fc24fb86ddff4f809219c977b54b99359094bbcc51dfe17b992ab24b74a17950ad754281 + +# 1472-bit +ModExp = 00 +A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = a8770362f4bfe4fc1ab0e52705c11a9b6ba235d5a5f22197c2d68e27ed18426ede3316af706aa79bcf943dbd51459eb15ae1f9386216b3f3a847f94440a65b97659bc5ba2adb67173714ecaa886c0b926d7a64ea45576f9d2171784ce7e801724d5b0abfd93357d538ea7ad3ad89a74f4660bdb66dfb5f684dcf00402e3cdf0ab58afd867c943c8f47b80268a789456aa7c50a619dd2f9f5e3f74b5d810f0f8dadbf4ad5b917cdcb156c4c132611c8b3b035118a9e03551f + +# 1536-bit +ModExp = 00 +A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 878cd000778f927b2f1a4b8bac86efd282079a7ac0d25e09ffd2f72fbc282e65e233929d2457c7b1d63c56fb706cdfa04fb87e654c578c98d7cf59c2293dc5641086b68db4867105981daaf147a0ee91f6932ef064deae4142c19e58d50c0686f0eaf778be72450f89a98b4680bbc5ffab942195e44dd20616150fd1deca058068ca31ab2f861e99082588f17a2025bf5e536150142fca3187a259c791fc721430f24d7e338f8dc02e693a7e694d42775e80f7f7c03600b6ae86b4aba2b0e991 + +# 2048-bit +ModExp = 00 +A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 9f40a7535c561208ecb38e17c9336d9bc8484d335901b2cd42759cf03689227f6992f10cb6b586d767fbcdf30e9d82a0eda60d2694ccd0194fa96b50b56e0cdeec1951ea9e58b07e334a7f108841a0ab28256917fecea561388807ed124a17386a7a7b501f9cbf3404247a76948d0561e48137d3f9669e36f175731796aeaf78851f7d866917f661422186a4814aa35c066b5a90b9cfc918af769a9f0bb30c12581027df64ac328a0f07dbd20adb704479f6d0f233a131828c71bab19c3c34795ea4fb68aa632c6f688e5b3b84413c9031d8dc251003a590dec0dd09bfa6109ed4570701439b6f265b84ac2170c317357b5fbe5535e2bbdd93c1aacfdaa28c85 + +# 3072-bit +ModExp = 00 +A = 80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = c23dfd244a58a668d514498a705c8f8f548311b24f0f98b023d2d33632534c2ae948d6641d41fd7a29fbbd594bfc7fdd6e8162cbb3056af3075347b6fc8876458d33a9d0ffdbcdf482de0c73d1310fd8fa8f9f92dd0dbb0e2034e98a30f6c11b482f7476c5b593f673a322b1130daa4314e9074270dce1076436f0d56cf196afcbb235a9a7b3ac85b9062e85fc0e63a12c468c787019f6805f9faab64fc6a0babc80785d88740243f11366bffb40ccbe8b2bb7a99a2c8238a6f656bb0117d7b2602aa400f4d77de5f93c673f13264ca70de949454e3e3f261993c1aa427e8ef4f507af744f71f3b4aaf3c981d44cc1bfb1eb1151168762b242b740573df698e500d99612e17dc760f7b3bf7c235e39e81ad7edbe6c07dbb8b139745bb394d61cb799bcafec5de074932b0b2d74797e779ac8d81f63a2b2e9baa229dfaa7f90f34ffade1d2ad022a3407d35eb2d7477c6ae8ad100f6e95c05b4f947c1fabfb11a17add384e6b4cd3a02fd9b43f46805c6c74e366b74aa3b766be7a5fbbd67fa81 + +# 4096-bit +ModExp = 00 +A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +M = 8030411ecbddcb0fe4e76fd6b5bf542e8b015d1610cf96130ded12ba2cda0641bd9692080f218ea8b0d751845b519d95b843542ec8d2a07f1f93afe3189b69a4f35c983011c7f7928c3df458cc3eae85c36e6934a4b1bc0a67c8a521de336642c49e10a7ffa8d0af911aacc19e3900449161940f139220e099a150dcaf0ff96ffff6e726c1ac139969103cf6a828ac3adf0301506aa02787b4f570d5dde53a34acab8fec6fa94760abf16ee99954371ad65a6e899daab87b95811d069404991de9abe064ebbddf886e970f10d260c899dda940191a82d4c8bd36651363aff5493f4f59e700007dcadf37ebea7fcfd7600d16617ffea0d9ae659446d851d93c564e50e558f734c894d735fa273770703dab62844d9f01badf632f3d14a00f739c022c9be95f54e9cea46ec6da7cb11f4602e06962951c48204726b7f120ddbd0eb3566dc8d1e6f195a9196e96db33322d088b43aecffe9b4df182dd016aca0bd14f1c56cd1a18b89165c027029862b09ffd78e92ab614349c4fd67f49cb12cd33d0728930d0538bda57acef1365a73cc8fbac7d463b9e3c3bae0bb6224b080cdb8b5cd47d546d53111fdc22b7ff679bcfe27192920ee163b2be337d8cccc93b4de7d2d31934b9c0e97af291dcc1135b4a473bd37114eec3ba75c411887b57799d3188e7353f33a4d31735ebfc9fcfc044985148dd96da3876a5ab7ea7a404b411 + + +# RSAZ 512-bit. +# +# These are regression tests for code which historically reached the RSAZ-512 +# code. That has since been removed, but the test vectors remain. Note that the +# lengths of the inputs, especially the *bit* length of |M|, matter a lot. + +# Control: No relationship between A and M except that A < M and they're the same number of limbs. +ModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4 +A = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + +# Same as above except A is negative. +ModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd +A = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + +# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A. +ModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 +A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + +# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ. +ModExp = 1 +A = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + +# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ. +ModExp = 0 +A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + +# A is negative, and A (mod M) is the right length for RSAZ. +ModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25 +A = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1 +M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491 + + +# RSAZ 1024-bit. +# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot. + +# Control: No relationship between A and M except that A < M and they're the same number of limbs. +ModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7 +A = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8 +E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575 +M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7 + +# Same as above except A is negative. +ModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10 +A = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8 +E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575 +M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7 + +# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A. +ModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 +A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 +E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 +M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 + +# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ. +ModExp = 1 +A = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964 +E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 +M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 + +# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ. +ModExp = 0 +A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 +E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 +M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 + +# A is negative, and A (mod M) is the right length for RSAZ. +ModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d +A = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103 +M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965 + +# Regression test for CVE-2017-3738. +ModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461 +A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df +E = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020 +M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff + +# Test vectors for CVE-2019-1551. (We do not carry the assembly file with the +# bug, but we use the test vectors anyway.) + +# Original test vectors by OSS-Fuzz. +ModExp = 9d675d188a07e9bd1b32638cc8cfd5002ef89bd1a9648f806567b87939140a67977dc8da17323b8e4c6bc53875cda8b656df8f54cc32e44fd9c21d122ea3c0d6 +A = dea9b3e0b44ae67b2ac9b7c2b18eeb4dab206b014981a46ac409f195eeb6896f132cf8497c87d1188008ee511054ebb426203355b7d515dce9501cb759ac1373 +E = b01ae745b101e9e45ec05dcff72e7f8fc04c79ffe324301fda0b4f7be81d85c4e875c73fc6c5cb40000000000000000000000000000000000 +M = ffffffff01ffffffffffffffffffffffffffe2000000000000000000000000000010fab8d960706cd4c21818115650cad61d4f10da325dffffffff00ffff00ff + +ModExp = 651f811b62ee8770e3598c340864dd6b0be9bb6376b6f933ab216fd55538e6ad1000cb2b3c64f54d554e004b6eec8138e6ecff00452d443a42041b72e6cd9ead +A = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e +E = 3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e09003e3e3e3e3e3e3e3e3e3e3e3e3e3e010900230a01230a2100ffffff0000adf300a58700000000ffffff00 +M = ffffff0b00000000000000000000000000ffffffff0000ffffffff00000a0000000a00000000000000000000ffffffff000000000000ffffffffffff000000ff + +# Test vectors for rsaz_512_sqr bug, with rcx/rbx=1 + +# between first and second iteration +ModExp = 1 +A = 624e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d973b6 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between second and third iteration +ModExp = 1 +A = 11024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000f +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between third and fourth iteration +ModExp = 1 +A = 4171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d9736080000000000000000000000000000039 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between fourth and fifth iteration +ModExp = 1 +A = 6a171024e6a171024e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000006 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between fifth and sixth iteration +ModExp = 1 +A = 44e6a171024e6a171024e6a171024e6a14ce297f2873536f959d8c3390d97360800000000000000000000000000000000000000000000000000000000000003c +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between sixth and seventh iteration +ModExp = 1 +A = 1024e6a171024e6a14ce297f2873536f959d8c3390d973608000000000000000000000000000000000000000000000000000000000000000000000000000000e +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between seventh and eighth iteration +ModExp = 1 +A = 626eee5e3c8653be47ed15e84b97cc7f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000187 +E = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f8 +M = c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f9 + +# Test vectors for rsaz_512_srq bug, with rcx/rbx=2 + +# between first and second iteration +ModExp = 1 +A = 3c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf7c +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between second and third iteration +ModExp = 1 +A = 485c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000003f +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between third and forth iteration +ModExp = 1 +A = 59a85c40939a85c40939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000004e +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between forth and fifth iteration +ModExp = 1 +A = 2939a85c40939a85c40939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf47800000000000000000000000000000000000000000000024 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between fifth and sixth iteration +ModExp = 1 +A = 640939a85c40939a85c40939a85c4093995e8efdb195e8efd8caf477ed8caf478000000000000000000000000000000000000000000000000000000000000057 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between sixth and seventh iteration +ModExp = 1 +A = 25c40939a85c4093995e8efdb195e8efd8caf477ed8caf4780000000000000000000000000000000000000000000000000000000000000000000000000000021 +E = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e +M = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f + +# between seventh and eighth iteration +ModExp = 1 +A = 7b4919849931b28a14fcace213f2b3884fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84b6e67b66ce4d9c +E = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004c +M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000004d diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_inv_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_inv_tests.txt new file mode 100644 index 00000000..4ebc1966 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_inv_tests.txt @@ -0,0 +1,115 @@ +# ModInv tests. +# +# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M. + +ModInv = 00 +A = 00 +M = 01 + +ModInv = 00 +A = 01 +M = 01 + +ModInv = 00 +A = 02 +M = 01 + +ModInv = 00 +A = 03 +M = 01 + +ModInv = 64 +A = 54 +M = e3 + +ModInv = 13 +A = 2b +M = 30 + +ModInv = 2f +A = 30 +M = 37 + +ModInv = 4 +A = 13 +M = 4b + +ModInv = 1c47 +A = cd4 +M = 6a21 + +ModInv = 2b97 +A = 8e7 +M = 49c0 + +ModInv = 29b9 +A = fcb +M = 3092 + +ModInv = a83 +A = 14bf +M = 41ae + +ModInv = 18f15fe1 +A = 11b5d53e +M = 322e92a1 + +ModInv = 32f9453b +A = 8af6df6 +M = 33d45eb7 + +ModInv = d696369 +A = c5f89dd5 +M = fc09c17c + +ModInv = 622839d8 +A = 60c2526 +M = 74200493 + +ModInv = fb5a8aee7bbc4ef +A = 24ebd835a70be4e2 +M = 9c7256574e0c5e93 + +ModInv = 846bc225402419c +A = 23026003ab1fbdb +M = 1683cbe32779c59b + +ModInv = 5ff84f63a78982f9 +A = 4a2420dc733e1a0f +M = a73c6bfabefa09e6 + +ModInv = 133e74d28ef42b43 +A = 2e9511ae29cdd41 +M = 15234df99f19fcda + +ModInv = 46ae1fabe9521e4b99b198fc8439609023aa69be2247c0d1e27c2a0ea332f9c5 +A = 6331fec5f01014046788c919ed50dc86ac7a80c085f1b6f645dd179c0f0dc9cd +M = 8ef409de82318259a8655a39293b1e762fa2cc7e0aeb4c59713a1e1fff6af640 + +ModInv = 444ccea3a7b21677dd294d34de53cc8a5b51e69b37782310a00fc6bcc975709b +A = 679280bd880994c08322143a4ea8a0825d0466fda1bb6b3eb86fc8e90747512b +M = e4fecab84b365c63a0dab4244ce3f921a9c87ec64d69a2031939f55782e99a2e + +ModInv = 1ac7d7a03ceec5f690f567c9d61bf3469c078285bcc5cf00ac944596e887ca17 +A = 1593ef32d9c784f5091bdff952f5c5f592a3aed6ba8ea865efa6d7df87be1805 +M = 1e276882f90c95e0c1976eb079f97af075445b1361c02018d6bd7191162e67b2 + +ModInv = 639108b90dfe946f498be21303058413bbb0e59d0bd6a6115788705abd0666d6 +A = 9258d6238e4923d120b2d1033573ffcac691526ad0842a3b174dccdbb79887bd +M = ce62909c39371d463aaba3d4b72ea6da49cb9b529e39e1972ef3ccd9a66fe08f + +ModInv = aebde7654cb17833a106231c4b9e2f519140e85faee1bfb4192830f03f385e773c0f4767e93e874ffdc3b7a6b7e6a710e5619901c739ee8760a26128e8c91ef8cf761d0e505d8b28ae078d17e6071c372893bb7b72538e518ebc57efa70b7615e406756c49729b7c6e74f84aed7a316b6fa748ff4b9f143129d29dad1bff98bb +A = a29dacaf5487d354280fdd2745b9ace4cd50f2bde41d0ee529bf26a1913244f708085452ff32feab19a7418897990da46a0633f7c8375d583367319091bbbe069b0052c5e48a7daac9fb650db5af768cd2508ec3e2cda7456d4b9ce1c39459627a8b77e038b826cd7e326d0685b0cd0cb50f026f18300dae9f5fd42aa150ee8b +M = d686f9b86697313251685e995c09b9f1e337ddfaa050bd2df15bf4ca1dc46c5565021314765299c434ea1a6ec42bf92a29a7d1ffff599f4e50b79a82243fb24813060580c770d4c1140aeb2ab2685007e948b6f1f62e8001a0545619477d498132c907774479f6d95899e6251e7136f79ab6d3b7c82e4aca421e7d22fe7db19c + +ModInv = 1ec872f4f20439e203597ca4de9d1296743f95781b2fe85d5def808558bbadef02a46b8955f47c83e1625f8bb40228eab09cad2a35c9ad62ab77a30e3932872959c5898674162da244a0ec1f68c0ed89f4b0f3572bfdc658ad15bf1b1c6e1176b0784c9935bd3ff1f49bb43753eacee1d8ca1c0b652d39ec727da83984fe3a0f +A = 2e527b0a1dc32460b2dd94ec446c692989f7b3c7451a5cbeebf69fc0ea9c4871fbe78682d5dc5b66689f7ed889b52161cd9830b589a93d21ab26dbede6c33959f5a0f0d107169e2daaac78bac8cf2d41a1eb1369cb6dc9e865e73bb2e51b886f4e896082db199175e3dde0c4ed826468f238a77bd894245d0918efc9ca84f945 +M = b13133a9ebe0645f987d170c077eea2aa44e85c9ab10386d02867419a590cb182d9826a882306c212dbe75225adde23f80f5b37ca75ed09df20fc277cc7fbbfac8d9ef37a50f6b68ea158f5447283618e64e1426406d26ea85232afb22bf546c75018c1c55cb84c374d58d9d44c0a13ba88ac2e387765cb4c3269e3a983250fa + +ModInv = 30ffa1876313a69de1e4e6ee132ea1d3a3da32f3b56f5cfb11402b0ad517dce605cf8e91d69fa375dd887fa8507bd8a28b2d5ce745799126e86f416047709f93f07fbd88918a047f13100ea71b1d48f6fc6d12e5c917646df3041b302187af641eaedf4908abc36f12c204e1526a7d80e96e302fb0779c28d7da607243732f26 +A = 31157208bde6b85ebecaa63735947b3b36fa351b5c47e9e1c40c947339b78bf96066e5dbe21bb42629e6fcdb81f5f88db590bfdd5f4c0a6a0c3fc6377e5c1fd8235e46e291c688b6d6ecfb36604891c2a7c9cbcc58c26e44b43beecb9c5044b58bb58e35de3cf1128f3c116534fe4e421a33f83603c3df1ae36ec88092f67f2a +M = 53408b23d6cb733e6c9bc3d1e2ea2286a5c83cc4e3e7470f8af3a1d9f28727f5b1f8ae348c1678f5d1105dc3edf2de64e65b9c99545c47e64b770b17c8b4ef5cf194b43a0538053e87a6b95ade1439cebf3d34c6aa72a11c1497f58f76011e16c5be087936d88aba7a740113120e939e27bd3ddcb6580c2841aa406566e33c35 + +ModInv = 87355002f305c81ba0dc97ca2234a2bc02528cefde38b94ac5bd95efc7bf4c140899107fff47f0df9e3c6aa70017ebc90610a750f112cd4f475b9c76b204a953444b4e7196ccf17e93fdaed160b7345ca9b397eddf9446e8ea8ee3676102ce70eaafbe9038a34639789e6f2f1e3f352638f2e8a8f5fc56aaea7ec705ee068dd5 +A = 42a25d0bc96f71750f5ac8a51a1605a41b506cca51c9a7ecf80cad713e56f70f1b4b6fa51cbb101f55fd74f318adefb3af04e0c8a7e281055d5a40dd40913c0e1211767c5be915972c73886106dc49325df6c2df49e9eea4536f0343a8e7d332c6159e4f5bdb20d89f90e67597c4a2a632c31b2ef2534080a9ac61f52303990d +M = d3d3f95d50570351528a76ab1e806bae1968bd420899bdb3d87c823fac439a4354c31f6c888c939784f18fe10a95e6d203b1901caa18937ba6f8be033af10c35fc869cf3d16bef479f280f53b3499e645d0387554623207ca4989e5de00bfeaa5e9ab56474fc60dd4967b100e0832eaaf2fcb2ef82a181567057b880b3afef62 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_mul_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_mul_tests.txt new file mode 100644 index 00000000..00fec9d5 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_mul_tests.txt @@ -0,0 +1,2191 @@ +# ModMul tests. +# +# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M. + +ModMul = ae2ca2ce7addaee2e2b7752e286b2bb6a58b51cfbed5c924f00398e59ec36fe6341cd83da43a33a12410f45f6228079c4aeb3912be87e2e81fa1799151bfa0fea29873097475b2c3efa312145d0bf7e51b2a7c9bc961a4f4dcf0c883ff90b919b87c21099fba40257645be31f95a3a277 +A = 6b18497fed9befdf22a01d988d34213f6687d8a96e86c188dea4172e7c6095a0d18d3c86c0f5a1af9c6e3aaeb6baac2a510930b3ed06ec78ec2e12b +B = 1a058d99397db0d209f01212dd4023ae01b15da04fe62d1f76f21622b2695558c67d706c535ca7f19b36f8ef2d508ffd6cf6fcf25e5 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c462c7cdd79b7604246a0cd97b40ea5a9a77408f13cbb548b56ee713c690dac0507fd988bf28e77462832f4307b08564a51510d4a951c1ad7564316dbead2b53540090827a8ade8092a6133af0e5fac7310f787dc1472836178ed6992b9f71224da3e884bef8e8379a58e6d4be0fbaf59bc520f786631857213305e23fd5ca65 +A = 16c92f77c139706430f396f72ec7adb045745cd9f5899b0074d9955bd32de66f57c05c7929b575312a7f1c04f19e724d64744bff7b31ad0e6171437763 +B = -8734c4a2361fc530f60b28a5f1c7e93136c5ff6bfc7553965eaca54c61e6befb3c0f8cef4280e780cc5940d21a740debba31f863ded75 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c462c7cdd79b76042469eb41a7a83115eb84103da4ba438c3e33227631dc185054ba4e607141d1e60990d8aad4e0bb0ceb645ce9ccdfe72d4738cbe1f6a73ed3e070194fa4feca6001c4a853940a227d15c1f1cc153d8c96e90e24805929fb11e0665e0c41c77d5a97fc5903a8b215360e26f6a19922d650f460f7056274ee92 +A = -6715098ab2ba3ea1e6341e89936e3ae913cdd450dc831c8534071f3c362841e47d88f2cd29c0d1239aa0949f3685f12f8519625bbf10b2c7a515e6d00942 +B = 536d4b3e4815ae5ed55bae6950f5a8a61d52439d2800ef1b5ba2285b85ed0f6ec4af9fa0e364a6b14f6f6b8bebce9200467804e787f9f3e9 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 309b3e30f74c58beca8b2c23f64fe1203830db8a7e306e1fa2e2022f0d6d422851da509d1b2936f088f0e35effe12a7463f47ca369bee2f2980bc48dd8e696b2d8c6f35cf55fb8baafc2e613b4c684de26129cf196741aab873f81e498b1e03018a539b5eadffeb5953029f31f8579df7ec0ff3f752491910 +A = -11fec955948e007b59fc50e729941ee9d43d552b9411510b73f6b4faafc0465f261f8381d96f647267f72175883172918b5c866cf1f1ffc43c55f3c96a60c01 +B = -2b3792f39499767e0a8b7a6a406e470a78f97ebb36765beab5fe52e95abf7582736db72a2ebfdb2405e3954c968b350a459ff84ef815dbc5910 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9143ec3e9f74a8eec476cab17ad8636eaa7c60e108e89ae0702dbdb2b255a217ba2530c6fd52658cd931b962054a9c20c8713976ef3b7989c40611cd25b0a9ad0635d61f6dc95dba6e0c4a7d53ff539b623b97ba3d66344fa324f905abb861c6b1e830c4b0fd5f6a4b01f09c8e1408941291b2285c4625267a108c +A = 7713413d87f1e50840255927ff27bad79e5de5898725a876e4647913158cda9f5fa031dd7fc11d2e8130a0ba99e8706341c1a98d5fee3218763ceb1d131e9cdcc +B = 1384e60753dd4bc20cdabf398525e7c4aa40065255c5058cae0b2ec90a3821bea8de672a712431aef5864eab719ba621cbbd8b46fe86fb31286091 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c462b3b4a0432890d141c0f46a28190a2e30ebb2e4ba90ed132169cd72316b290dbf5c261984d98e63eea6525fa890bf52185ad7f164cf49f67ca91c2f35511f3bef6eb7f3da31a602a78e4752e326d79dea729f4ca6438f2aa65eff44bc60979b42e44f6a301cb5de8fb42abb47bce5633c6ae9479d39c9e8b507d96161e0fc +A = 17d806d7c76aa8acb051fd9c0c782443f1b1b6387455f7cfb737c41658d0459bda5d13587055eafb87ad8d209bccac1fdc392aeca0774ea48799511c1fb9141cad2f +B = -d7c9b6574354e131de4b8643d766641e98554a03238ebfce1112c3da5f049d6c410a7f05758571aa2625f7190b936a214797570539317b32fb94cfd8 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 16c84ed15ec6352a8ce6d5c2bdc0d9f13b333072fc7041146e944a29391f83e346b8ac0bee6dde98a420ba4f8852801d7c5bea6f1177a6cbf799edf2146f8297013e0e796917cc967786788ff12d9c1d07d9ce4b897bd22a1b8a391d3b4ecaa5b5c85d0a03aea5145db6350c42a964a41ee5f83e7d35e14cf442e5d99ccd0ac8 +A = -6d84cdf18a2f53fe496248fafef183914d55c42267af3dd42a39515e80cf29211fd58454986f5fb6afb56170dd9865d3158249090270bb9af341c830522a4dcabfd494 +B = 6f6f3f74187b7d74dee92f79be864d0a2c56d4bca3283742e9cdf15112c8f4208e3ac8ecc98b44b4ad74b0671afa4aa9e48dc31d34224a1f66bb2b4658a +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 8fb782e4883ccf3aaa2d3e020b08993d580c69ec8fe66ecac152c5babc8aeffafe406736cea492450fe6adc25dfa2e12723a3f9baeb02fc0f785b3db760ed28048e1710a78a2ae0c96b67c109c5034375a512b6fc7906847253f66316baa0ef90facc9ab992235153684d49d6939ab9e91086529494d7386f604ed69aca2f53 +A = -1f745c8f0c8fe6ce3f893d77fb274c61b72b2d9f9c5a2eb2467bc00d1f496d0ad469d76bce318bd64ff1107ee5fcad4469f84d658586a5789c068b0cb9b866d8fdcbcac5f +B = -3a2347b491813252e8ebef1bd181534b074a368d076b8c80bde2e54ec3b4ec99001f43080c7857427e069d99b1b65cff998a141ca6963aa5fad1ee632986ad +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 7c0c1c05ae1d6420bd93596a01aa0153000ecce660a8a14d6fde7d4740719cc495fe6681a9a08163b2dfd51659b3ae7db0fbe09504370bfc695457d7b32665a4df53e879ac817bf715d5bd6ca0e242b1ebacb1ffd6698ec90c442910a92b35ec103b345f9a9e5c7b005f8028da4dde80f36f6f6e5675040d19e46aef06040eb3 +A = 4c09264420a9452c6f0b55baee42c076aae5a73697cc6bbb88b7c922f236ee4c18e477f88e2c40cee03f0bbe87d3ac8dffd75f635315f856a3881c6373e8b9a286c813325d3 +B = 10474ece7ddae5c53c4df5b594439124370932dd94aa5d5b4ddaa233b1a55634fb7d72e33bf1b02965fa9d1538f97e1cdb5ec0477cec8ebaf202aff8533211169 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 481543f1556df756ae2e422ffe35aae020c9bde9e9b1f760b43043a4654de363dc67f381c0df1c3c1b90edb4343c47ffb8345a1aaf5dae56f446fee08a0b9ee8c42fff57143e10846610a9925be96418c4c957b4e92af734b96fd6f21974877dba52a0db1fec4aa97640e357434f95ba74b6b8323cbe17118dc489552844602c +A = 11bccd165d9fa2d8b01a48c0ec549a6e600396cd2023f0240056193ad27e971c604eda8aaed6ff6be8be1001f3dbdc8655f1ae84eceb963938ae7bf428eb5c968f584798c1bd8b +B = -cfb6629ddfc98a242e3290959f4d0726c0b1770b52393bc7488a471a90f7f0951362c03e67f443c9ecf4987f5303a789bf65e0fd59cc5eeb9f5d4f40d3e4a14080c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2a770ccfbcb2bad207d0e2dfaeed04b6e7509daef00a1df88e57509451739a8a0f15106ce8b53d280a4b4e09900420714cb6961ebb0e00e88567c5df50d2f2908b4bf8e0a9a5a8b3c6120503c14f16a99297459543c467dcb67915e0a10e19f72ed5b6891a6121b66abaa602818801d3306630bb04ea57e6b31b2c05e368d398 +A = -442c80289bfbf00db06eafbf06109b55f99786a323fc2c6db5686f99094cc24aef50475841243ec3ade2a1e0ff28b4032fd8afb8bb5e28f3b2863bdb9fc8f033adbaeb5f2ab16fe9 +B = 6d43e3c46f4a55d49e78f40d34033a7f5fcbe50873930e7c5452b6b3b176534e6e70033868c85b4d63052964093214dfd0bda6a84e893b1aae3cc72aa83d039e51c014 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = ba0e8c91a86af1001b13deb115c77609a1e7a3736a6b807255aee898e3100f469ef6222be532dedb1b8d3db4b3b55aa4b5da5629c83e9b2bde76bf2f2a4119a5378b5cde000980b3e58595d988ff776f0388fe025625ccf368e20914fa90dc771c826e4a836b2890e82ac2274471d586b4de5dab3278f0e70207562ac6e6493b +A = -14be403d28c8451cac4dc83fbf895a9d2b74f730c39b0fcb33d7258f99211dde31a78f182ad1d27a559031d67d6f2f94a741f141bab80fc692afb452ee2d502099ebd5760ccec7f7ebf +B = -2742dfd02134594edc6d3025aba5ca4a34dfeb43821ad84164510b43be4fb95748f8d0eed7bbcbeca14efe843fb676882784bb36c889be29bdad9270e0956286552119561 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 20c691d6544912fadfd9894cbfd42745991f39a29cbe3a1cdd302bd0487bf70c0179b9579b77f8481bee13ddbe42f32d734b6118af92884c946ea8576f6dec867c1c251c73777cad7c7c76e90da00ae07f96c8d6a751e5b18157dac4468c05d32eb86e74e0e8312bef85905af8193a3f5c799c5875badbc9eb7ead1258e56d7c +A = 7ae9b4d5151b11bb7bd4d1569a6f4804f3b4d77948e0c6300e4f28d51c9a0afed2ae7503e53489edca5359e2b3d0c82a9cef316cd7e1c1275c31fc9c51a8c1e5fdf23935484e467d6460d +B = 1f46f88d39fbedffa8501fa1268bdf3460aa98e12b629da59676e61852a4d3f8c59f72a2fd717fe2faa09639bc651ba516cd39297e0cac67444ec57c0db47c2a4e250033d02c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = bf21b3cd55c0df8d4d568d00f757b10ef3de782ae71b289cb2b59d36df1341382bdc1825ba13199f2cf279a72968b3bbf5f7e3d13ea9adeb96d81132788231fd988eef04828119dcca21ec1fe844998909cc95a8d01720e883df27f07ef4dc3f09081015dbbdf019b96707c18b0b1db6e689e8f86466a2afea4a9cafc576e10c +A = 1243b14aa3d16a55935f6f8ca49295e35e7f75b03de7192e1e8a479abc0a430e0d340acc05eb9a61a5dcbfe3ce3a4c5c940699f5043e924f282bd21e341edf8b7a6741c6ac72d7587a9e7a60 +B = -bcf08b2153e8ca911096189e35dbdb21b77ce89685484f574c89f1747612f39340bf1b204a23530abb36b2c5e195940b86ef1252d6729393c25d4c73dd434b6dbc3057b05d3f15 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 460539d96c07e72acba5b59c88fe904bf7f1e1648612908444b0b08172d05968b31b43456918b4287dbe01afc3cb4860d9c2fe549a580c989b6507094f6c241eadff910d2603f747f8e289e7a8176ca4a978bba89288a4cf875bf3e03939af966c54e77c28119a39d34a2b7055465f58ef2efe7c82ac547fb675653198e4b504 +A = -5a44cb669c055ba7c28d49f84bf8d12179aa30bbb9db2a48d7a6b09e44dc0e0f7471e3629cd2fb51e5a53346ae025fb49f9591ed1d71bc79daeb3f1254342d8a2b091ae07a758c1555efe59e78 +B = 646cc0f766346aaecbc5147a4488ce157a6d844045b80884eaee9d419087285fa71108b5ab4a05689aacc8d2e3dd0e6714c55eb8f77487a3fc5e56c3c2df0c4acf28a457051118560 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 79b536f4f30f9f7483f90e65e6456ef8072d9a7430405cf8c9377ceea2c676afc338837643436d55ac6af2326ebb362684bccc5092367209822581700d641cb8d331432b761e4c6e22639a27335f45a25ec019d180fc53dfb53d69216d7cfaeaa07db8288adc35b7bbccf2829631c1eebb821e4d3299015c3d462dc17aee5024 +A = -167529b1e8668938ec02a68bf4d76c22dd018c41e19be25e2f821f63c2046085d0af30d8b4212ea0f3f9943be1c14fb2d2a944551107cd2bbf8dda5bf258957325f06277036282977db4575b0deaa +B = -378e1be10a57e03b197bc2b1287d643ba6d89da4bf6a6170816691fb6529c602eced237863ee39659be3729825f032a57eb5de0a87b0894d1a1244523e85b6f50a3d9976dbb038490e46 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 658169197ddd0bfae101c10c3e6a2b10dbb456048e81160b47b197fef439b1e0ed710399cfc80ead8e436f1c0399064f92da50afc335847515686e055fc7bcc0ca721184435955b896b0af4f4d96672ebed2f154538d49fa507b945c0a6ae926793751231980274213c80046666c28ada213a2f87509d1466b8d1b2122e93f8 +A = 49136d37ae8f3da71a6114327833e8aaf3dc8b5a9a27e9d04c953988456e525263f86ba94397321c2093803b789f8db3ed7cdba19c4b796500b979e02952e1625246f8e977e01fccc133f94cb22832c +B = 1dca005663385fc00b4fd58c73adc7589d15ddbcb8cb2fba03a737a320c447a2b21e576ceda73811a31d8277883fd31e22f776bff3261a098ecf8f40f2855b0c723d1265eeafb43f85323e3 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = a49fc8084f3e780537b4038bb769b8db3653a3315298a99c2ede6739a1732a636e9787f2e8b09d0b9bea08fac43cccca71a315e6f4a7d6417d171b4693dbdbee8cd9f95be0847ffd40ff027267125d67b89737e1d0365bef6c4429504d13cd8ddc7810f456d6293c0c57c14a307b94010d79d5c13b92a907f923966fd3c5c8ea +A = 1e7d8de2061cca59d1cc19b356a8fcdf2ccf917e0d81598f014167c5a8de027ccfc8f2cb8c37c396ebaac83ba862c146bb2d551d10ce03de9528f97725804e8a6de57b9d9da811200604c2a032462b6ac1 +B = -e38592f3acd75b575f64ced439d5ef2377d21c61bc70625639b01bf755fa2c6de803ce155744993493debcd4de40860bbfcee86d0b117d7f8c3f8ace68b67cb6fe7a81a145535553896424f7a +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5a99c8a6afaa97d8e7d84f4899803c7786b1bfd2ecabdbfbb3bbb92247ff91ac213a72f6d23c24699d60babe91a7d9cea751e686c027fa1c954474fa5680f0059118426c71299462b11de5f2817d190599cc4b352df4d2e80605f9ad1e32eb13712d3027a2b6a19d52151e37e7fa057d8fe59dfc8a943a42a1756a38f103a75c +A = -7df29221e6a102e32757c18f87927cdc90ecb012ab0557e0ab855daba832d76ddf595b9c5a62988ca968b64fd5bba2a147a5991810c17cae7edfde38bdbb7e13a1fe5206724c05a9fc9276c8d4e503a860c7 +B = 5c586d1aff7dafea3b8ee42e0e8854712c95385374b5bd1fc8ec41a72b296e070940c4160509a4a1699a678533ff3d12299338fc441b0f01e29a48677bfc5aebc644555285756e97c74e1af6aaa8 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 21fd2d881b6a52332dceea42664aeae1ca110512c13bb33e25ba4ec0f39f80eb73b1fa0834c998c23a2453dbff971eadb183c51a30ba78d593f23be9cb6b2b33a554ef31e4a36e0314fc2ec889f18debb956b89d1bf8172553271bd56d89ed0b30abb70e68abaa2c76f73cd5a3de93433747d09c845b5f8843f9fdf9f6c975c8 +A = -19fe3bdddcf08190a037768b77666de803ca4f7f0d7dbe6aaaf334a486dd0da7ca024d1b3df11e0406b0326595a171be30b04574c1a7d04f4d2ccd334663690fd20e4fd168386280510a00a70c1a11e99483048 +B = -33b2400173c057980b0e0cfabbda1a5cb5b83b7ae80708c199f28142237f04b071c6eeb63d42e80eec04b76152250c9e4d4c4f19a048cb9815dce6e66710fad1d27494db5c31d9af37d2aa779d12d7f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 1c45cfacf30682a876cfe253f05b393a2cd4dc065ce73126508ce897a99a723cf5145187643ee62d746f6edf70269ddce3c348a1432316286a648ee9ac31ef87feb14f25c42f2dfc2e84bb5bdb4ec0124e249c526c55ff2cd0ae938555c5f86d856eb181572ed01dc045f1ababa52d249e56aba0ecccda905d7d1e64bf89bfe8 +A = 6a40d948eac2fe5bf6db15d7f6b89fdc0712e32d39a881c21859e8f7722391ce05973efc7c40e2c0d7f56c217d8a986bfdb08bf87bc0435873cfe4d01967c46f7d39464bec411d0369f6f5d1d83f42596fa47451d +B = 12529775e8253ba220d890d4912fb95f91e4edb59610e889431208b6bb42b089cf2aaa12ff9ff98c2482e7f4cbf35b22d15fa28aa288217bf766e937a706fe1e600143087b0a67f668cb7b762c9b9f38c0 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 3b3b08e8eda8be3918bf648227eb0d569dd898729d9cd54deb32b1a1dc69cf7b2c4184c8ae9641f0f75950df263a5e236f428ca86244e617b14a04edd0f31c02bd4d84f25bacfcd4a2786825f0361251475eb6c7e99020dfee4298a1f1bc260d4e364a332bc6f651dde7ce5026dbeb0e5aa75ee98874da54c7930108ad28e3a0 +A = 149d36918fffa682cf90c4d3f3d48e6408e7ddcbeb44e78b9cc7fbb08108f65215761a61d79f37ec8f67cc51e0a9b4bcb3834b0ebcf6734985153f29a2778473b80147eddc813b4fbeb98843f5c1ae6cea68f88dbb4c +B = -ca87f66182e271a69c0964eda92a009d438078b584c3eede28ce1a501838c5f497186d305c09922f32ba858fb55f2a0dbfc9cd0f93b789c1f800cf092726d6d33db19e4f26c7dfca69b83925db14544ebfe2 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = b199655160d88b6b4157ada0e5675f82b33b5592408bb57c46e2f7d8791bfccaa51436dc3b772b83e907c20ce7edc2835ce96595b78c0647d244e9bad6f4184e0003eb0899e7a47ba0be888b9bf795eba95e5073a85c4d20416fcd4a8d4e1e16b403deb38845fb8bf9e9264d68807acf02d579e8cd104cf2bd555e6cf73d0450 +A = -70ccbb73e33a7cec30ef2071f3b1f2e008e70fd6d00fe8b7aa4b9146fc6d0549c57d984cd014c7e0a4ed6d33376998b7c2c9778fb9580d8ca4ba795c88612721c153c186740c58df3fa63b6cf7a4de76e049217218c05c +B = 6cf4168d44a8da8e8446b4420466fefbdeeaf9623a40e10b77547687b25f36916f2c18cf6060c03b3b40e0959479f6aad5e44dcff0ba799262ef53e280f4a7f667d262d472b2e573265774deb5ff8f25dc1822b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6ff91af444c61d2e2fe8ad73bdc5377d5becd55074eb60f0f98eca3d8f4be8c02f196b3afea12c36f78b78ae6a5ab677ffb7d9c0bd58987cca816affe468c7fb4b56055f5d2326532d6ed1c00ca2d052ecd103994e8929bce04e067082b4ded7e1973566f99c514b4e0d95b9a8a931ef4f6355066940990fead70208a63841f8 +A = -1c924bea12ad6f8b65abd1796e381fee2cfbec15138191bc22d57165928794bb080c83878fa5fd19a5d657b2fa91165459966f50aabf19440f7d75f027b32e999ff4d3f7a7ce878fe0f33a847d644d86ca19713ca9968d97c +B = -3abd4b281b8f25f5957d1f2fde904457d49a3a7eeceada26b454ceb4ae0e879135d376571f08b5038b7b3d73a9a9fecbe265b72375756a715a523ba66737085e5ef7a4ad988155adc93eadd5d95a0faea56914983b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = b9076229b1a1241e8b4da3fe143ac31d060785be6ac1e841c2fa9683d2bacff2e2b5dbac33f58b0b1718ad2053c37ee55ea54a9d258ddd8930d2784852844d85db24e4721762839a5c73cfe588efedc8932ccfa585e1b5975083919be9e32a86dbdf5cef84d3d4b2ccaf7a006c0cadca1e35fff2da9da7d7e779494d8f85bf4c +A = 75eb0fe6c07559c2b0c7b2acd7d29b5798f6c4cda64a504ebabdf54bdc773ab28b218f0defc040016178958d5561796230b71edf49bbdcbd3f14494859843c8ca7a0f777cb05827f2839f3982832f4f3e3c5e50af17ecebbbc3 +B = 1b8aa718d61447003fdbaa748a9d86befdd2675a677cf34a1be7c81e4577f665d71135a8a243976a4f6ffa1636695567bde522f8fb1948033a7e0941f833d827e957781cb4349a08c6be418befc8959960fd5fc1b288c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9df82b7c34ca97a3a5d4efa28d5ed4f35484914dd73af9090c4bb31ea3496ece8ec650f4e7b07dc779c97e597e76e43cdadbfc6e72b61ea718c073be1cd204f8ad2bad0df1e530e75705f3d3dc285e9d793c8d42f04dc20773d3fcda8ef3ac1cb10d33d20a91add0358ab8658f49d2fe51d0d2d72684e31c0eef85e5695bb4b4 +A = 1fc2a171445ee6add5c2e4d29e50b91d83338f8d63c111e4d3e95f16d2a33be02bef24dcc3d6ce6bb8f1ef980dbf8fed409a0232c0566153014eef840aff58ed8c33e8d463d408f93e2f5381a26fdea63676c4e5397eba1d39f928 +B = -bdac7a177c77451104852bb99004ce8e617036906667258d85adcbe8cda21ab7d03aa7dcf62cb210a9db8fc750c7e1ad290b35473be0fd607fcdc686de0b78fd9f258f5b25e2ed43c2ad1a38859f882b9f6b293dc258659 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = bd9f3d2e8a1086b177698f87a9860e3a5f030e04a0bf4ee9436ac55e005bda01ff4ac662cb85d39e98a41c723ae542a83a936c3bd0280c6801ffda080ec0aa4230b45dcd0bc5eb41cfcf272028bce3572847637a92d1543bb2b8408e880f5b776e1cf14fa28d15cfb584f025596ff10c9f091c837a3aa622d9e5c856db8ac207 +A = -7fd5357cbee7c5e31fb62ad03bd47b705b574d915200fc7f1013d836b9cb683db020b152ae9464de6aeb8baf14999ac7025dde6173fae6ade325c60ec310eff6dc4130a8efffb15ddae90d760cb7f76a27d0368175d4a44a22f7f223 +B = 5894a0223e4aafe4efd4572752fbde4952c8b09cdfc35137e7e6ed650f8fdcfce9de673853dbf73730b159b2656047e69377d7c5025a6b346fb08831e64bc8bc34b75765012460d8135a4f7a0f41d768fb85abf17f5e2f5c3f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2c61867bca70e8662c7e5435a5aec020faae86fb079b992bf49d8497fc5f96abbd38a6f04f6ca8510e0160e546b3f68b7baef4ef0f404e881771cc12ec5ed3e3787c2d2ad6bb957cc59f8d56f0afb4bea49cb671cb42f4e8a0ee1dfadb6fa14f84a5b3269dd33e20d658ea4cc39499c7a39a4b5650ad7018d32f97954610f676 +A = -1bf5ae15f24c7c14eb59605136a3f679f303cd5b81e4a27465281d17715afdc2c231d7ccbc59f80ad176f4e0326eb757b52e3695e27c6776d7936da47e3a8a904f735b151422029535045ef489e61ec93f02e6d588491c8dad1cc311f52 +B = -3238dcafb85ce557036d19e42e7e7e473de9f9da6f920e18845dd010546868d2652decc94596cd2c36bd16b02c02559892b9f573bf21ab18c3c75591413d046b385d08aa66d849ab8adc9fbf788e837b047a7ce2b9c63f7fbd263 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c1d04b831b712d0619db462c3f3fb5973f5984e9a48493ff273a5abe17a548e185d751628899e2851e425a7d4b2c72d4d908dc813cd122b8f497e08e299dca9166f19752ff8cd9840a70155ed9e8c063a3840838b3679f96f1cd5f1cbf0e037d222029e02769dce7fdaea0bbb5417f85497d77c76a387c6b970eac15dcd128ba +A = 7aeb60c134e84f289e419b74f99a5ce5b4aed5fc630d5d591ac7643251ad32d6ca7f052fdf8857f67138262d221de644140e9018f7b84879d74883f8f251303f65e06bb52246ec6a912772cb698b47de41c1826ddd065359f6b9f1ccb0cdf +B = 17f81e53d9fa6201e4d3eeebb32267929cd5258d10f053e7c021c4afd17094f8ecf433b1ca752f8740f6d6bd84f801b1b9fd64bc4787b9ae5e5aba0b4318a63dfe27e92d5a3ade192af7563c74c9d6006ae7701240efdd6021a83cf6 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = aef89874854ed34deae1b77286f9cb0e3017e3ae77fe050bb244acf4f30dc03504c73c1a4d44b769709bdb53811a5d0f8a76a08e6a66fc2cc4e98537ad6a8049f02494305b89a49a55e71fcc3f5fc42d6b478456ada9b19ec0a03f5ccfac5538c0040092771660312be5e51996073ff1a506d7460c57d54e10dc2991c028606a +A = 18d3af14bbffbfcabdaabe44074b407d69abdd80a6eaa5954f0e45fac85af7ced1715c78da872f7a8fabaad3207e31f12b7195cdb25abef0a1e54d3b13349d997f207fe130d7985e2033cfec899a0af310c9827749cd22bd062eb0b1faa254de +B = -85a7d9f08a60031e689b0e611d7f7f46e1178eaa2e6459602e738990c77f4d3783ac43fc04d53504cf67fccbeb02f9846756f8e32fa4a9316b6d3b45f644254077bef096a72bcff17ffa17070a4355121cc5daa2f782fc0d0bb48101db +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 14a85edc6297763547702c212b1a8274b8f85d53ef35cd1b01ed51039bbe030d0a1b9626ae2f571a43f1224d723847a1c6708f2238f6f6fd75db6656e6c703a5acb57f69717efe8ed58a3713ba2720d8c001d026d83de0ce5e24b67c41daacedaadfe404aaa9b672f00562e6901fbd0710c4303fec41ee3338100beb36c9b1ed +A = -44414ec207060d105f599b9a66aafecc5b232b55214c1a5e1922f6b59439b3ff77cd3a327bce4f7406871196b90350e6dca9aae147ce03027dc4de7563c734f111d95171f489105de5ca80047cfa43f7e932917b816ba7d41fb95b4106745d700f +B = 45f2cea1b9b75880ac3ec206740cfe0ecceb488c9155cfacf5885a8cb49be78af8cf221ff8de2328f4880479c031f830a3c9eaebfd83f7de501b7c5cde03c4720c56a676d331b2a13c4689a2e34a43fc11f62825b8776e75d31225ca7ff65 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 7670c1e2e141d8f8f5466de8ae2e0ba2eb3eb7634699eab8415d3a37f8df291d00def88361e9fb64a2f116433dac3ac2764fd62f3201dce4e48a3b7019e5465f82241ffda29d5eb0462fde74dea3168f8993ccd4d090b9c31a5a6cd7e05f725bbc89479836b89379b422250ab049f31c860110df5ed69089716877fb0ad7b0dc +A = -15b4a2f808a85a5bd466a342c4853c04ac0ab73f8e53a4a0477f73dfeb8d7a911ab2eb5d3d192b9b084d0e38db491148947c66f838aa5f460c37341b129137614259efa531c0e6ffdf163ec6851737037a5299060418d96da035e6f583e6ba79d0414 +B = -3e94fdf22004384f7881875b1d8f58019ed8afb1b6a31f5d591e77b0998f3100b34174d6f3466da44b4c7fc8b92ccc5679c26c146b704198a65a88554d24291adcf897bd758a035361f671a82972b5962002c6a828792980f86a64547165327f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 35b49beccd8d2010a8d777c1ff69e28e01a1bb78c6466e717f0a934bb62f9bbcec5ed29f9cd2c14d240a6c33b28c986eb9c8912a4927605532483dcfd31a50876e1819f3d7a0f49bd276ced5c4110470244fca52d2611ed7e31cd8b73e749aa70743b39e92810b3b52320342a65cad3180f6e2966059d15f79e5574348f5f66c +A = 6fd078e3cbcda6a71a710e99204da640edc71a65974fc765999a74ab50a0e4b090d57ed0ee869c8da2cf694b6fab56e87c4af62fbe73eb8890bc066ec3460beba04dac3b8fae7e4f316e8f954c6e8d934e946dfdc9f4cde0f26bb3d40d5c444b03bfc65 +B = 14d8041a3b83468d2f44f150ad8d8d0a1a22035d630f2a17b70d5c3d557d3abc7e4d753e1ebfb3a3ba465520b84746073d211a67e079ec7f47c2cff9c06da69bb5cbafcb6cabe7e0018867c42e07931d6797d4499463e3cf786c6d5d6c8cbd600d8 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2f6e0fed8a9720fbd83ce950d7545d2c6d5b271582194570424f90309227a51777cac974bca0ad3c1289ceb91cf75af73b0645cc20d71e7789144876b8c1bdd550328d9907accc316189e8ad81310848cddd2dbe362c9398d814a048f93f9368fdbec0f19ab87ad2a59d4066d738c3da3cb71d4716f2cd2336ad35ea1438276c +A = 14bda9e4aac85b0ab7abece728f61450b7779d3b5fb83be813758e742d2ad76597f132aed91e20a75c554f0d61ec4dd118eb733d04942b2548b1efdb4dd22fdb543d9bc1e4bf0574ae2cb2c46fb98cc4835b6a074d6df1a3bc5443beabdc784d542e3349ad +B = -efd765f8ffd72d041ac3244078b8dc4482233e9411b289cbc2cfc26fed2cf28e286835010438ddc9e7021ceb098b10c68bcc4732608ec1f4052df9362176ee14812bbf09ccf7c2882714ecbbf92bbff61c06e9dc35a368208a05dde949fa2cd091ce0 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 1f0c436379f6dff55a59093ff2a0626a9b959e3e3e59365afc33c7a7893f04bca863ec910c446957baa8de4e35a1f4e9c4a776ef41b053f03b775f327eb7e5fbe68bbb478aa4339ae703ee4b573d6931e47e09271d40239d527fe77098a7fbe519f5eda1f26dd6a7d0ee6833efe37187d8a85844690fecf9fdc3a4d80b921130 +A = -51eb34de29ba24d2b1fbeb0a1c324f4ebc69cda2dff971a315c0c2775d988b03ca29891ed0790f3dd507a1d26ead461dade9284613e45df338dd83aebfb66050465d8aee554970b43f7d4e0428e1512289fa1f9b23867b67095c455b66d536b91207b749189c +B = 55259a1122eb7eb611a69118d3d42c2f05dd228d71c0e1e42ae3a8d3d180a95b74150d844e916ac85105805126e4b995f2ed1cd3fcdf28e1fd241dbe3125dfb3e4d90556256eb513a2f7c9b596719c83b26931d92bfd3573560e8bf054138f5d6b9cde72 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = ac321a272d2206df4dcd6ed8ca194a1049c1e3a20bf325fa44809d302170f850721c077bb5d792f86f7ab03ca259567397cc2fa1429771190bb632ac2c92d3fccf6e05e13cd33149994cda5f9c57da155439663f6a13c66f9da553f5038fb92fdba186ed9ca04b8ec87cba4c5a68c8edeedb94e38a6dbe293340dee1a4ecc768 +A = -19ac99d7d51456b00a193b3b04693c7e5436e05763f0154768db078ea5111cfe9eda3451091af213b9c8cc649d341de66c12ab2803ea39655d3d7de182a77355ca444c5d2778f791d39952a7a11839e497f5dfd8a703df49ec4d7628bfc25a992e94a6477e6be39 +B = -286d1d436f113308be594f0f43d7a05120639152b7e2f93058cf602cbdbc016512bfd23f7aa937fb358b7b602d15998ecc150f2b9224c58527c0c1267739e065e24236771e2c683957871637468181e6e896b513569bd004b9845f0f0e4c26a5ca123365e1c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 3466804a1b7d1af8b6060aa93a4c325d9cadb33ebcc8bd991f9e44cc2cca8918411efeed0f005790d649382ec40278c8cff903cf3db177d24466c58cf6a56ffc14e595c36bfefaa2327d37f616b1466eb702f5c49170598bc361d892e18051b8233dbc5b3fd6832befd9a995bcef3b0f3beda6efaf09f7306ec203172e78264f +A = 6710c19330d3f974fc377e28039e0c0ee0a558621fd67fe724c326537c18c66dc5eec60980e07d401ad5556a05688d2dbe7b271f9d5eda3032bf7cb7c420e7b5d65a195bc037090b6fe83064ac3731624ce2baaaa62a6eb07156ca12ee51d4321988026cff573ede9 +B = 137ca18f47a151363a3e8c52dcf024262ba525ec8852e8e406f460fffc2cf88f1999b17a5821849317fcd84d09c88ebb6eb0340120f113d7ca5fbd91c6a40cd790bce7b422552cc0cfd2a6417add2501db1667f2802e5d0f4df824adbd033a90a155cebfbe0b53 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6f248a70b2cddd9627b32fbd130f05a604866799365f94d97f1eb582b28192959692a870be7c2614536a8de84cd8c1364a75a3927ef9dddbb8c6c87dbf526f2d3a7916384f2daed96002831173fa4a51863c28b4378f99b1b201010581d5eabd66ad1e328cc4e647bf5e0588bb775e130b4a4d029eeeeb5852c5742862ddbc3e +A = 1f014cdd87cb33ffee623cf454edf2c476e91df279b4f0879637eb6e8e5ccab305186de67585595d34ebc195fb150408c4620cf6c7a0b0d9695ba0e0e1d7552ca7d0be3dd678b1cce2beedd11939891a6804770f1c843e16dc2ea6aa8e4043940c37fd3d950caa122845 +B = -8d8d9dedc80994fc5db04d8c935301e47054250fea9020bde8d5fef01f2307cbf458d5afef5210a369c396287c5eb453637a2d721085af3de0d75a5dfb5dfd22fde3b229d438439af7b296b9e68ffc982efc6c825556c52a735f8be12a214a06c4270824d5268fb6 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = a35ff7e232f047e575b200b9fc4c9253de6ac04c612b8a82c275a951075eace5e7d6664fe8f78301d554cebe7b996c1f4ec3ca59d8d12d7196eb3909223de94c220f0445d24233534af1c93433b05c5924799d2c781fdb88c4537bb8d442e6bf76b2d966827bfb4f40378a3f135103513da056bc0d375b1339561700d15a0227 +A = -58346cc8a9a1e5b8babaed8e7f59415388e0db654ea7cd465d96781c57faae7a8af8e7578e46f3a8de7bd1027188e1cc32fd1c0d60be24fa3289a12cd822a6c9a77dcf8799624856c27ba88fbdb047473274e651760581b44457ed048cf76c166d38bb9b2afd3416ac7e45 +B = 61951a16dc6466a9fabae99df29b7229f1ab96b476092dca1e4f8fc8e7404e2fba56ee66486d1f27f89bb3f86f271307228d7d6cbcff943961e177300b6acec1eeb46af1c5725f745a2d2af0fd9642f57a09c9ce6742114be0aa6e939e638bd5c7a92a7c206b2d36e35 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 90b441d8277eb1ed454964acf567067925881b5db0b446a7d554dc61ae87ff979bfb0e58ca1706123453e62ce31284a5a2db1228d259e27abc7fb5cc5848dbeb9a6808fa1b4afa844ab39b652abc41423c2833e1209a1674db518b6df7ebae315dd7f416df54e73088762ef64cc2cd0a08b1cb01c49d9299d149cbe84145a55c +A = -1ebb693ea7d18e0ff4a9a51124ebb78bfa3a4635b75a6387e9fc745a2325409f927324d1289be8a4f5cf2d5c04adc7ead20564f97e453287f03e5ab59a6133584f970446652d05a131d7d382c47b7cb97580ef6710a532dd4f5a0369dd3db500ae5a3c5efb587cf0cd2638382 +B = -3916ebc4653e7d6e0a4f1e234d765d41e9e948b5acd7ebc73cb595559c1b20b037a3c8da0a7aebfa5fd327bdcc922551cdb8db3fb0a581fa0620ca2d2559ccde3ebc44542b4d80926d061e2a35c08c09547e0cd587c396ff2959ee93ea64b1e6b7e2b624cdf445988e1f42 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 3ac61c3a028f4a2df6645acbd36818a2f76a3229d229ce22471760807585a909727411e8b68bfa4e76adc459409a101a1ce83900d46918e8d0903a163de87c07bbafbd60c7f536a62c59370ea53b6cea4384345343146bbf529334b4201ebdc7585b6e5eee42696400c9be9f496406a4eb51d2fd1b40466224f1752b181774ad +A = 5a16d5fb9047949684b80805e5d962bdb939d0d0368b48517a2a826679c37ee0ded4fa83e657192d9ae84294e450f7e2f2773d1f13395169582cbf95860891b9fdf8f3240a16aadd1198e884f22b2718219d478e2410fd4bb98ea534a3626201959af099fa55488f5390791bcc7 +B = 1f67066dd06ed4a49cb556dc2fce22814754885a7cf6c13915d974b46b0e6269c0fafd688f45ed2deeb026a7cbb772c080dfd577d21ed2c81e50e7537a70dd550eb94fcdf626500040da88c43dabce13c82a93769a9e0ef66a471661292dfd3b3af07169e2dc909e43678400b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 7087dd62eed6ccffc7e1370cca9444dccc4ff160458941aa9f49dec1a2e9ecce4cf50ac2daf06994c5010cf225cc92238cd60e1aed9edb2befb0fb354ffdde94ef5e8ad0415bc95851d59095a5c4850ec52a74c78eab58309f395d3078dc481feb9d30bcd9f113af7a01611b94d085e32193dec738a64c5fe9bdfbf5dbc98cda +A = 13596eeefbf06e9ead8d883113d8ae6cc3da8b6fa13ab66681db5a9c083ef9e49d905ec19c39b149cc09452eea0446b29cc92d4e865e6f681827336945282fa6b276ef552363229a976c503b822e6e4a9862d3fb30dd0c3627ccb97a7046a6a679050a39166388a9daad5ec5555dbf +B = -a4e574363f2e5982cc087b38110d257019962fc166c2d6e6d396220bb308a8a0dc7d90c5cb2ab85faa19b07ed7dc11eae9bf2abde0a5fed279e77a717b43d35e70fec4e18445e37741262d0b0c20dc4375371d87d839d39934f1dc41122e815f3f37352d04d0cf514738b351f02 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 8495eeee238164082240ae1db1e3c1e36fb6621e6b714c9de914f9de8a587d7106b8dc5214f7c60c0ee231d7441e03cc26462e71adf8e29772ac95d0395722d2756f9f64daa8ed41d7ce824a572d7f9fd419112ae823b5b48b8aaae09fe093e9ed05918c4ec88ab159890910837ad0691849b44be95993682b2da2b124de39ec +A = -403f21e1a7911806747bb78a4f20c4e6572d49c6c4ce071db0c8c91ee985e68a16e60093e4628414b2673d25c9f13c4c43600633af95017e3846512197c9515aaf9953570ce5861620716b3d80eae7de0f033772fba82652484cb3ce7cc189d1fafb14e044e07a88da302547f2e623d8 +B = 689d1b4a968b7c00082ae3a29c8571f826c4630c947a7767fe4a71af43a5de84db9b5baec0980eafd0019e09de1b5c56173ede68c9a6acf260bef3d9a03f4c83a33106c94ca7e1a8615b3553088d1d05a62ddab0f1e5a126df5d960f67e3b92981022e1f0358c7970bb2fd5dce7a7c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 397df584bcd3b2e1ec7ed89de624e9d104bd6812901e38c5740755ce91bd54155c0b624c590ded199590be5d98bd1ad4acee56a62d05d6b5fdd1ade12f7db8e3eb08c4a5996450cc1204be7ba61b768af0efd563ea478033324731e24fedada1ad6e564238c891494e85ded4feb2165fda22f75bf120856034a9206511885fd5 +A = -19cc480d1e07523bac502872a971d78bb26955c5453386f5d51767150e229daad3ab2dc85e0fa0cf6e72389391fe627fd2d9f263f105508642eae5a095ec4d88545dc9d0a2c436907460e1ea7db174673000eb2e0b60d57163ced261bd0f6cd8ce54133cfa10591f1fd27996353110060cf +B = -39c45512fc7c9620194fb7ad22abea8f6dbff4a137dc4523115ad7e262934143cf1f320892f8c097a400d4099e787ea7041d0d69b6269d191fcdc8ea28340ecacab71058cb39a9c7362c848826b35ab560c27113fe53c497ca452397891c81365b6e7f07f916d47961e50b8c7c5cab38f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 263ab04c98efac12210beb66b13fec7c260c5b1cbc20cd732a511fb3786b917a617d6622847f4eed70f25982ef5d0b0d13848c62dcf447e3a1d491f4c80e69cec03cd318f6f93134d582210bfa81c1790562053a71091333348c6624d4d793fd6ef971d284a4ebf0be0771efad302015abfaf3edba017907f10ea14a46d9fdc4 +A = 7a354753e39b9ad1c0ad6b65575fc7247487f3ea320fa82d1d333ba8dd5d0ff925331994a6961c9c603be5775ef1842159551f0bfb34920b93d90ca60e6abd514650f77ee8ffff2bac0eecd0fe8ea0fffc6ed0285c9f3c3cfaacf338043975457d62f9c8dda8cce1e99f34529435016fe2ed4 +B = 1a4384f9620567c698ced05870b4dae983d8f0df6aec888353f9dd6ac8ad54340c3ba8346bfa47bac38897f3963fce972f6d55f3407ae03f5c7637be1a34e483e50dcc27148b76ef079f117104162beb191d146ec828ad5c5bde5ee1683a031d554c276d837bf1f2f622cd11baabce10212e +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 91cf4d1899e170bf75dda0d51a6481f79eb94c333b876382c9d04681073e949191223926523f6531f0a45765d7f382221eaa080d7bd05a3c19220ebe18802b15d8009714e8e4e9872223049622ca02040eb041707c7e525f698cc361847c66fe3673a72e4d701466bc374f55fa5437216eb59375c0e2c4f7020149d0118ea72a +A = 12f35c48024e8271e8f9a60a48b5a214bfb6595a837c041b230e6ac87a4c1d4b3f93a2d3a193c750c9857c8627d0f7c454d6c4f224dbf14a865eb83e990b1d9b8bfb729b8d3dedbbe9c95032e4d60676c2baa2aabafa698392590add3b83b521a7a5e7d6f8af207e44ebecd735374acd01ef5822 +B = -8fc18f92c0613d085cf3ee6f586b39b99ecca864bcbe60fffc63c585e5613df68f3534ad46e244916b1f9188507a3692526c9e403b8e93480b0a5a6297f65215f1a5d8e20631a9d559fa1acc15a98c9397761ce18903f393b10444ba51bc92ac44df90d4cf0852da9d75902230c6de6f26dfdb +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9af562a7b61c6c84c91bf979f32ba5d246d2ee2050f07ec2dd5cb3f9496bd37c3922ecb2b5b17085a13e93ab2dac6022077cc18c621cce3a2d2247e5e89de8692a36f596e5dc7a6969a4f3ff0d1580eed380e6550c6218c1938caa2b7ab401ae6f520063c811088504d60a19da3b5018d640ab8d340f35d1337a2ede8bc64bf0 +A = -63bc10b8fbcb391dea305fe61b404d3bebd035514a812d0e1d38daa3d67f9f1bb8f02d2979270cb9147aa51d66ca73d4b5787e472456a13fbe0d568e92b622439d33ad3c357a56dd26806ebda7b3bb592385ca5dba7e5eb5d85eed0a1746441e8d56e22decdbf8f4296e30d222da5af17c427e832b +B = 57a602bbdefcdd00f42ed1e2cbde2ba858d171804da56b0ac87081424ad1569df1308fee7c9ed349eb496d5409c4c46921f09ff0830bc9f57e920e17df16523598fd90314141955ddb84a1522ff3ebfa812cfeb6670525123476a739f64ebe6a5f1fc805a880f8e5a71b908c483a121b38d05cc2c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = b395c9f264172a3653af6637e72c4c8e564d1ce68032a5d761bf546e0c4b51b33cb026bb4256fa639ae98e54e5ff7d8921ae411497272b53d97c2c44b5b9ecc5aba43dde201f64f1d033056f19ceb0cbd04decb486a1d07ab1c64fd213d7eb6db9cd11efd743462e137f368acc4ca0b49a7f85587bbb5ede4be1616889e2699d +A = -1e71df5f04001f6468c3a192086bda948aedd19c5da9a5286856f30524238d95b0ae71940f2af123315ab5d2fc61964d3e970d5858b7c1a78d0f2cfd10cba7ba4830a8c19a09b59794ca5d7da32cd8376b5ab06079b51cd9819c0021ea41a9e43aee147befdbb17a92cac7c7767705fdd908bcd291fbb +B = -394c187308320ba1b14d91d75b8ff993dfd57f9c84e8185f12bf9924e046629ffcd7174879f9925bb643988259cbe9dc9277fa83a25012f91159b012f1964aefddd5a94ac6c2a55a22bbae93085dee079f84cea1d53dc4771901db9a3db5a14eb17c25aaf5377e2beaff6276cbce7cee97a9b8f32737 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6602ce0fb5002eca37e85b60cc871b7b2eed13d38c20a37a6e0886ee4814f3ce2515f8714c67ad81e8c3abf6a00464e6a51b15e55b6c11296ada43cf459e15915026d3260cce8fb796241fc2b0bdd2b65ec04bee3b7ab6626e10597f3b13b43d16c34afd5b43a219917626c88b24c6f8392bde1b2e65a50b7f1a8dc5eb096702 +A = 4855ce75a3d7dbb72a257f6291e9f6ccc158647aeb2f8beb3e8fb32f6f59af1a46617b77440798562d6f58bfe826d3ea7dd28daee8f5162d7d24ae6c24c2deb2669b15898689ca789e2005903f3a94e991e7d3c8f3ae6181029d959bb15e71d7ba94d2dfd3ddd10f6fc49a65798b5f6ffd64682c78b5d91 +B = 15b3e9992aa3f042fd58ff97a8c04aaebf46b75fdc38caa9224394a1805cc26e4311bfb498d5a04d19396e98d11c8810620979362df82b23a115fc1711b57c7a56b8408e2682a2edca36cf9311addfedd2d0889a78cc1ab170d1379245de6f1f6f4db815fea9130463dfe5283f195e6e81486a1d39634aa +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6a81ccd82f00d829bac186fb38b85097d52afa3ca83a026856bb83f94d6af6f6c6f3141d433f8fc159d11397df8d2f44c769f255cf8148249d8e9fc4f59ec3bc8e804d7d5189e71e20b8d0e540b59a2854ddd7feeebda5a95f17605e8bd5f311a63cc2e4ce23a51229d0a49ca04982c1bff79c201de6cc6150b690c98106a39c +A = 1f1589c9b5ad9d878631cb03c23ea7e94680220856285668838452a63b726e01709588b38e578da8a4845aa5cc2e4723beafa4f81a1a2e463f67d9a3e432de7064ba8bfcb943cd9efb0e5a136649cdcf5e85a667917075804991b997f318752304f4946d69abf161625ed0c03bf9abeb4ef28034f818e2a643 +B = -909dc7fcbd27d0bf7d6a3d0e2937ce725b5cca0acf78c103d633206cb431e2e2c785aea4bfe2042df32417143de76b71d21587112f36d067f878e556b94ef63d59a07d19647593efdba7f3f5324d64c55f93a283a0dafe080167f6576053f9beb326994f4a1d53e18e3f3e770e69450bb70f276d128e48ecc +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 69139f2e10726f83300505d15dcbad5b5f284d1c06789181683b7b8caf35dff063dfa4968c35facf32a3628dcfc19b3fa4c30ba0e030b06773832a2631529fe0c0c402e05a0c4e9446a8b6c22754c70ef540f90d903d83a2e3592169ce6b5edf939ac5ff25b8bd48aa2425321602a9571661a1109e275a3b3039ff0c2f430b18 +A = -5d02cf3969bff8789850ac898c00fcb3ff1fc49a22cb243ad18703bb8fae25f83502bcdd885417fe46e8237fd0b444712c4fdb8f4972dbf9278a83eb305efc7a8210ce55167c069d1c4136a9b66d0c4dfadbf036c079d12aa082fbb42bfb0098006136a61f3da43aba3d3bcf2f5ac2d7884caddd0cfc28681d33 +B = 50b369234d993721288662d83298d99b9052a0a66336a5a31b76dfb20ec2b5be3aa76f78b2c17c63d78402a15aacb585be5c8d2e7083145e316e71e111fd34f5c79363c4591c247b1a94b20ee042d840c42a3001d6c8dc7cc1e1348e0e3ea8c6551f9d24af2dc2d0c38a54ef065ff048b148ce4f11ed2b549c50 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 87de406a6c957e85c759f8ff684023a0f98e93ad4ffcbc6fb0038c7a7ceed2486f15f36555d286338aab3283aef677118f7cc3f88a7ff0ac9fed31da6786ce895c3c08d3edb652bbc9ac2b44c4cd24ad281ca3a8e8e6e4d730f4f0c25487cfc1b2afe222934eca8b1e1572780dcc149422a88eeb1bf31065c929685a0a97ac3a +A = -1878e0497aa1c2942a2e6956957c876dac73c4bdbf42bc92498f29a006bc92f788c24a4624b87324a7c8aedc6b2c0c8a1a442aa91557aed9bf2c02b6664979e8a9a21330dd839f4ba8f84515fa6f7db9287f7c20f31732b98fc09ee7796dc524870dc35851814bc57e1a8ac49d8935fea04bb08b8760df33a98149b +B = -32f4e94bd073cf3f70810d9af7a873996a0510109bc6fdebb855f27dcd012c59507491152d30849d75f95dd868992c6fbbf29b1d899cfd401e9e7f4e0436732cb4cc9e6a6d6b0cb63fb0bee21e422b7f7b7b14dc5d2b6d10447fc4add390fd3c8e7b06f1d9b181adfa8d04459ed051bbdc9666623b00e3871e597be +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = b456ccf9d066dcf4247a21c7f3820e324ac9cf004cecf8dd1f6c3aa40c2a33e24c423e97190fc71bb9fec21d36c5a687065a7877237a2a05e64cabfb3b20bfff0b1f5ef2e9adb7edcd7140d1047b0919a2c770579ab44a08e5ad9f63a06f90ec7d5885b91de5e524b2e187937609b4b81d40a0b33e31a48d7b9868add75286a6 +A = 6c484e3c6b530dcd3644b19fee66c41c7c2c1dbcde574d87ee13cabef9dccbe5b41e25c32c6a56df23f2e87176afd28249e5fcb918723707fca94d7e2c9623a3493d395db802a1b49d550f52c29666f785652fe81afcab00a60a5b50cbf523cd13dfa06d5a5b0809c68ff7264a2cb35b8d52284172c62ee658e8417e6 +B = 1b4fc753d0530bd07094bae09a02b1ea684fb4e8519086b1e2ed9d59af011f61d1b94ffca6f354a5b428417b328bb1e8af3f6c7ac9121dae58de9f1dcbaa9c73a357f408b870e62b0c7db1a72c4c440f2e6fe90b199b9dab29fc23927190d3f2bf8a7ee926a152e64474283695614ad696c85ea547f5f51d02d1b823e3 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5e7c63276f350f04816a6ed9f98507a78314f1d99081fcd906affa3b8395fb58d029ec657af82e77ef45611bc988095bba9c26f25f8fd404432fecd02398e69635f3315a824d6a98b33eaf6a91f12957a5e80cb48d5b086c795eb3b1e04da5432a7e8be3d683addc586a44b6243ffbb7a979bf9664cc7ec41e75f267d58a7127 +A = 18efe267d4c62576294f4ba44c67a058cdc0bb44c48f4035682b2d6b8a63106081af43d99098ce133f8d7f9cd04d4dd7414f704e32871d43d6e5d73fa9f447873168b43b32d6ad19378d74a967f92ec7629a690d29a62a5a6e734e9ccf5b84857a00d97b9db846b057004b03d88b827dde717fc30e6a5246c752d65dd625 +B = -ebaa580d3eef5361547c692e107439c8391ac0a2d1cec0cd275d0be69133eba8a94bd186ff9a129af3f5a015d5ebd30215643554d7064635dc11ec7a8ed2200fd637b099e534237f0495d2b629abd4c8f84aa1d925d53e98490d02f9fe51bdda08b043f67f0903c0195fcb886c04397d3612e4501ab8c7b7db69f781e169 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 76fcb39f94dd2756e8266c025cebe8e801524a757b976e35ed45e3da3db720061cee9037fdb34776c704ad2059ad8920e400bfbf10eca9bb157eca7750cc31fda06473bd22d4def80189c47ba32e2824c721425f225563df2a2ea1edd090e01c0bf980677db5a5dcad37d21a68e2832d1012586f506480e929b2fd9bb4aaddf0 +A = -75f903ed9bb0b6db8e3be16e797258f6c18f6cb7b16f835f04e3045f7e4974d7a86a63f2ec351c88fadc0635b6dc83a797cdcb5cce1a1674f89e44190991e0930575b19e2aa1512bbbf2ef6f8c3e707b17516756fadb635d8c6bf9caddeba14834b5950a4d1e98bca79a4d15e5fa5fa3c1727d7a49b33d481d32fb14ae4164 +B = 4ccc582c8460f7def2d26167b68788a681c41bdf6dc805dca83127a18bff6f5ebea6db75cd959beb859637b200ccb5c7644d571f436e46a357d027edc9769da226278f7ab947963f7caed1e7e70e572980e960e9764a40c6db67bb526694b084976142471270b2331da563a10427cbbb38e76203d7da5d67487eff701d75188 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5adef30c67aefea4da3884b8a1d0ce6724492bc76b477f1053621e7d19f3cac15448e9401d34e05ac4b508b9d1db9a8d323cf43722e0af6e3c3b6d463c6007449c3bc3236d156cdf988dfc308a1b4911554ecace52938a7b10f463d14f917ec3d9fddcf6d33081745009c59b58aa22bcd7dd8c3bbd489997d4e0bff5473ab9d5 +A = -174e8e057a1d66e22eff88de26f43fde1c8efe5611f6ba4f318f027f5a5818df02ec3f014dfedcdfc8c143c5005c3c5098d409710967c93474f5854c1113fe4030e6682bd56d389ca8b9a4587b8b9262d146bc92fcd81d75c3bfa4281898f394f45d5dd11cd4c7344ee7a933ee346bdaeb6f5188967c388b919a0ce6730c0bbdb +B = -22702bcc4f9d5bc6f803af6af8072780ff7de7a346d6b9293ca751d6ee3a81493fa86738c44cf2b7be4bf14a55a4f8179c35c09dcb1485f4c08ec5e9f9b1efa91f4b5f15a31a46e1ed71cd934ba6bd271bb22bb5703aa468d297f360ecbb48f9fd6c572683e83ebc3d432203347dc62e19fa06f93e087283347950829d4256bf5f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5c2f67b1607776c10fe2c30b112e541c4d8229f5f99f615fa02cf715d3f20556a28eff5c233c58994e9c6c1fcc37b3416b0875b9a62fa5a09a4b8f9e216487203b387ff97fad1f39f674ab19c5e34cb2f162e6b0b0b0084f0618e64928423b73b189c744e3de9fa50d66f45975f68b14866cc16c8c6c722a54420adf027880aa +A = 67056e93b69e8a7b789f1f8b835d9c6ecb7762f844d656b26df9844a60bfbe0d55684f61debeed31a24ef4246485e8a1d43d49eaf97ed9e7b9f2d2916a8d85b8c9e8ad5575cf5a3fea42392e5d1dfb23f7ad41a7b56a4f21e2828aab38a602d560c99783a4f807120292ceae366b1fbfb4be8e5d4561bc8944e7f17ebbcb0fb6296 +B = 1f874f244ed6cff9f910ba9a58db0dc0a7435e8d99ba6412e976b8f64d4106d3c5c57ba079384fced1c261aaa538e131734451fe84fd3cc5cc8b3ab46b2031f888d95084cd3a35a61092672a9118eee4ed1a0df0409e3613b3ef45a8b16b71ec892755dc3f83c5492b67fb9a143ee6102d053078f4875636b20b536d5cf851768cf73 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 7850019c6712f18eab877faa8489daba23cf34b512a3193852508185b13cd5a2e9f503fe8d61b74b5d3930021a5b8c38322aae9b9b1b4814fa4c2c5bc409b58f11fc8fd7854b17baa94a6bff5f234832f9468d90d148fa2bfed774ac03f2dab6a506a70db4ce363f932adcae202f04fdcae968f632dd674416c23d4e21345ef2 +A = 1e378a0f27e6259763890d29e112e3d8d2bdeb9994c49fb67ab680b6e71a52fa0a7db886d3baf52f36d943b5430ae8bcd82e229f4197239c35678eed254c5816722b995e9c311be942f8124e2f80c1e59658433a57f346adfcdb83202e55457308161d2f928b60efc39538a6469f90f1a868cf6077568c8241623896ddc2705cf04e4f +B = -f4ee37e39d4cadb692bab5483ceaf0258b068f2c0354c540438803780c983469ea28324ce7e209c3bf55b91f0a2f4544bf318585e4514333eafb9b8c2f02170c620e9b5280a828ce1d8dfc64ae9c28577e15071825a85a59656c5b47d9a382af6b78a5b3dab1078dd647e0b473174b8415d401543d30a4018cc3eddbfa546d0fad9cbb2 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 4c8f8b671443a3af5ef5749885ce5de8e2afeadef9051bc49c0d7e72922d049b1accdb79d82288e472b07578e8b6d2176d6cbdd7f0caab593dc0fd9224a94920235410501fddd6001b62a7f7d8eceaa7a8e4c0de52029fae68656e8120972b5cc1c2e909c2742e836f2fecfa51e12e4f8a2ec7e69eab061c81785374ac607fbe +A = -5769eae759dd6bf94468eae94189d3396886d4569b0ce264c22d39b623be3abb01bd5008b9fc86701a3373f7764118becadcc69481cbb134c20f669cefeb376dfc489dd4ee91cb333d06afa391dd322abe2b3b715d11ee372666473a473e29dd90fcc97e939049b455be52b3f288db306999019c1177ab5820d94859a9d2f050b7ee1d4a +B = 44adcaf1e2afbfddae19b23cfc0f0ba1f940d32945d0b541db23f3a0a9d06fb1f67ade9a8e620bd96f4005ced99430c7a55eb7e93a701c829fd5b9e55dbb4d3833afbcaa0d9c946916b1a86af4a6393b1155c6439b8b82260e09ccf0ce5d1c4856f4d524983e4b0fa123267694a1c6118beb8be26113a02721a02d7b0ccb01ec6e9c0f9e19 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 51e25767b8d4d7b2b0c2652d9ca6bfdbfea06acba543b1bc8d3d25b2fe5f2998febe1a6e742abc3f482b4267854c2223a5918a9b5c84e0864278283bcb5bace0c046db1d0240443404fb62d70ebff3ccc655e5f5977958df4c878d9859a69731744f3d33978ac31551487270bb4fb56ccbf59402ef9fee42cbc329420180de08 +A = -1966812979042198f70b3f1238c93ac5c6e5749f1108c2bba869b1dac7680f910e56318c9b59be9212e713a348767ba6e75917fb599e929ea2144880d18d4fbda4f4663c7abb49b02245169f385e09098a4e01b56dadfca8c803acb7cc244f3c98bc17440ab2afce318476b80e1d0b4ed9a8d6f2a0be64633f8faad5eb48de2681a38a633ec +B = -2e4f5eb92fc34c753c61dcc826abab6fc4f427c6ac7e73ffdf65b1037464b2a9a0b0290e713d81ab57c0e1dc30e76fdf96046fe10a34cc4511398319ee34bcaf73763a9042fcacf59a100c43d3333ffb3743048e8df0dc61fd0da3f935fadf882ffdfa9f0f42980c1af6edfdf161c4b16087e2b14277f655abe54582de79c51193e13169b55e6 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 33539b5f38a9943b15801d449adabe02da6e21651d96acd9aa40e866bf65015fa40178399254e8af6bb082d021e2a05da0f45b699d193b70112e114f0d25287476dc0c733c5cf9df57667ad0d3ffc4ea2f85b43cd10459cdca9465b0974e578c00a6e275e0b97ef2a4c9886aab7b5947b78a88f84a3f1d8c5f26bd07bcc59886 +A = 531b891fe9e8db322cec59a2115574c7a304c423e6b11516906b840542b2c608785e2c18033262ab9cf68f63edb40ad4f073ce8841db602cf8fae0a6771d741c6392976c9b333ecfcd0c8e9997da40616ae2a9e0c6be93fdc7af0dc0668ded1e42a9f729c70f74500ee76a91d3d993c075c2f645b35792a20edf17c157459e35c0a48da6c4c6f +B = 1a6fdbfed1054a0c5758f92f72db7e5737b0740c4d8c3ae4713366ef6709b21eaecb6b74c92541a9a0c99ae18ac6ef7de79d4c84ce39ad59cea9c203734a99bbb895916275e8778cfcf7fbb7b7d081a677769e4ab96bc7bcf23303100e629fa8e07f5b8fc2e39c7b5724c72907eaad09d3088783b3118e57c9c8ad1799b43a13f73864c5602c478a +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2eab6018361f557ab06725ad90f6886d4b468ab1a193f8fdcfb4ad15fff781c8681329a27aeb5f03a81d7c404b8017b12fe23165e941ea767c733513a07e921aedf20596763f6f977316e37bed70f6a617e5c2757c229c59b3d7b1fe8755b5f65f7f407f13634aca7c8a267e661ae2f77fc5a95f56cd6c8458119df587478b1b +A = 1cc779145b2b7bf9ef4c9692845e162329940f96eb43e04db8728bfe736698082aae6b6a1b3c32867c293b08547a0941cf4059d2d567840ab6ea526e3724ad59e715a3782ca656cbb739dfdf0c113a18f0dd62423d4edb60057fcaedbb852178d38f1b5a232842b4fc645cbfd97a8cac0b094b870064302dcdf23df2c9e9f736d93409cbb8ce9ab3 +B = -cbba16086b51bd83d3460e51cf193ebc79b826e4f30978274eac3b2dcb04e9d7b56a1449b7cb128bbfeff5c4720bae45271fcc64085d3ee501f0f21fe73cb7db5f275d88be55c339f9180ea21a8cf3755a875331931b75d23f57c2030c89c6f9c1ead431cb4dbd4480564c83f8470610e5673c7eb6c0fe7351ffd7ee460df5db7872c67041aff0227f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 96fd93535728b961b4167be8b304e570cc34e787c12a9a5d76e099b336ed6b837cfc246c5bceb04b0f4744c5da7071fc01d70e342509473e5bd7c60d6046c9b4f21c5ee71c4e678447f837db3a7694fc3936ca733efdb7d387f0f6e263b3ac0b89054a826da9716691c9d580ad38d701d08ca090b6c59be466e1b9833e75d820 +A = -6791fd686f46c3773fc8d7f4753d178a93f6fa4941f4305d9689c2a305bc67840bbef80ff05c7bc6de3a595f73846609327d28540cd705f5aa94a3ae5915ef55304c37c4c43a4b46906889331ee16585629bb303673d439de9c0236f708fd19a977e6e1032e0576a921853f7dd328979ad1f1aa945905dae93a82b3af9451a541f544c18ed2546b66e +B = 6ae062b39c77bebc2fef05743e6d35e14a31c6fe1fdc42d8de2db94ce70a6d60d66263c7414b1081ef2fa6ab511b361b8baa9c71ec628dba5bfd772c440baefc2fbed68d40897878232d9715c4b7e7c9bdd41cfe7b6986d825f68be8cc16d04afb0cf593f3028f3dcd91bc94923f3d7211aa5f0f12d3270e8df8bc191808f0e266c4fce2af97ac7ce06b0 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 949ea5f645ffe5d0d03359d51a663c7dd6e6013812a47be309575e036503126f48677c68c4ef6e7b3f72d76657fa282ad5881263e649b5297da82e24298300d032af3f5e8309ac7eb597b16e257a6f7af3476a264415aa7783433e83be57ffb3fdb404a9ddc3527d6a9c297f8cb7b6674961b3af837ebb65f218147a46c39cba +A = -10f59ba073126d92a201529a5374500612bc59a9e66322c6706b422d35a4f82d97e668b268f5527b4641c6099c80bcea504234f3c1e3fd29eba0f161da97c50aea542becba499f29d4ba5571873d4dd9eb3f48cb26fa6c929a704fe8e49791b2ca3293c2428d9cb453263935c9c90a4a2b39d23a0baa12535845f907d42b729033a0a1e74d18da30a88ed +B = -34fdf9ae6760d4f434d09ce2a7760ca2dda14bc256015809745524dc49d841b07102aefe5a1d0182e3e09d4d45b415e46f653185742b9b8ea6960160752080e5c9577a12182ccf1a293407b534ea8ddd33ad16cd19ba537d8db5b542f86a2a292423d452bf18d82361240a7efa831518184572c5a8b73b108a81d5036b3b530d98bd47c7fb2123418f12e05e +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9ab739ddae55a0d71b39974628d4601122ba6c5035c3ad0439691317f23dc33c0014f3e870a105e4dc1432ec79693bac658433b21cfc218ed411e003990b94ebfa87767f3614ec19f5bc30704adcaf85a9d3d15ea764c8f0bbd52ff388659637746d39859398c79016ace8c6f97d3a5616711a235b85f334fb889b9280ccbea1 +A = 76b15a0aa0f59ec804a5e9a627e1fed524320b29120b6789f8e71b1ac4e00a9a8c826919035b84f87d291e2f35460bee181342136dd9eaeb99ed00c6328b8e44c49ede3921d6275f6e7f03de179fb2374ae2fa6c58852fbb2649e214691daef945ead6c8bd5a53ad2b130e9eab6ad046ddd6b80874ca6515322bc171ee32749333669de0d9c883058423579 +B = 1fe2171056ed4585a143b6b2bb5f44047664f64d710dfc05c18be5840ef9426ef05b6e92e4ecb5544ee4622e9030153dd9827f2f01ef38e62b88ecd6c46b4457d16644ef6d863c226acfd6928a40de614a5853137124fe69127a7f05463eaa49bc742d8f7be300d06b302dfb0ba86801119bcdc01b516afa360aa8b22b7c6c1839cff859ca1bf26e3f7e030512d +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5631048ffdb2767aa04d59d8a5750016b38b983a2d53743ba4de5d93bcfc8ec30183a84bb1e290ef9c72c7ad357728acecfc613a6f9b3d712456d545ed54a337930937f4589fe41e66ee930db3dc10a4fe41481008c69eced65b9d1c46b8574c5ac8f7d94025d8fff00ced17a5e17508527681bf94c2dedd51502a2c4652538c +A = 1aca12b1933f25ea081e12ff4a4f6f9ce379f96d976da2ff7b8eb8ad791fabe31c1148fdec22dfd67828e540c955a1e13f40c5b125e1c7e6bd839bfa84e5bfb58bfed76058c6db77af7a34ffd25fabd60e19f65e1faeeea6371d7785f2e5bddc8650a7492e06691d61f997483661eeff54a30656f1daacf31182486bc40647975151fc05d2f64b50e632f5d5c4 +B = -88ed894287043e7e5cd2eda3c1e5c97f85809f7a246b0c20891fa9a024f3aba4ec1f3d112580fe6ba6b0bdcaa1325ac7ec9508aa88c187af08e4f37631eb6cc97e4481b18f747ce6d35ff355e425a4833834ffb8d34a818bdb015fb818ac9f58feb87020234243aff912da5590ea3f6cba74f1a9fc3ffa2b4aeea25479c55a3b572621e75d86d8c8f6ee4f587e0f5 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6ce341aa4a571cd5bc110dd436acaa09f409661967de0bd096c77c60db58b2b0ec95cda50acd7fa20ea4266b2c579eeb6ac214a75d40abbb70845db74c4d6c93f8c545add269d45fb15d985e7e630d0425565d06dad4a3ff9835411e51fdd9780c24f466dbf29244cd1b8c3445af181d0928db399bbc8632f7ebcb9d48c0b754 +A = -52c53999b02a92d6254557203cb31a21dcb896495d1f29f3277d19129ee43e521ab9d5a297204a844a9537d63b74686eceba72ea2e7b98ee8895513395cf7c44c99348f5c4eb657874a8115f0027d6a416b8a04a1ec0e6809b7701ee7d41e99996e307bee9c295ab3df1faf674e0067d0ab3bec4da998580203e33760870ae472a3045bbd66e352b8f4d284efc00 +B = 4329d110504caeb71ce0453b0706ff675f646e70a6bd9575791a38f672eff226f4958f8b1fe4123c0001d8f8595d8030d0e9798232942725a9b9d654ecf50546adfba7103fed796b455ffbb4c153e70f941bef7953c8a210d6f2f4ddf5d9a79d9938503ae8f24d69d5d7df1c988630ed960e12dd877bb80a1ab0bcf6db67e0c0578fc0c40408f72b19052534da8d31ed +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 4b9fc1e0eb4be199427c48bbe1b53948d0135bc1965b8aa5421a4ec704b13cf934c650405ba02ad611b0f29d46d82d4a1fc5a84651a29364524e37be2fc7001cbd3c792aa477802999841ff19620cf66dd2453c9b05aac349b9094d43b40e358f32805d87cea3cfa98e05240ff95ec57d88e0a12917628ebd34946eb1ad6799a +A = -15a223b691d8b3696306b0ccdb52c1d62c7c2d1ac71e5f07cd8fba960417b42fb5ebed5eb9469be67f231b5254bb0fcfadf5ac5d2906769e8bf8292f0442986cabd88805a162c0c1f60f9ff0bcc2029ce33452d05f754375c0bd147fba745bf8a0008792d4f90d0e0f2cf391f2d7865705544f4a220ded44732321473c0ae7870394d4e625df11bd0923340cb70b995 +B = -340e5ccd644849d982bdd455ddb3b9a23ca14e168bb87256bcc370ffb6b7fe78fd062b3bcc1ad3c8c3b8cb549f2baaf1b7f0f6522aba02fd35b651f7de52b3aa2e0e40352bfd6ed0f84a2bbc3b3a396dc8512ca1db01cc69611925f1037794c82a418f10e0d994f458d1f19051e8bea32b90ce744d46718f42e711c094ad0a1ee96c88920188078f1b044ccf307e4cad7de +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 31c090e5160faff9a136a7a482b42a43ae3c7d00c215cbdad28804be0e7b12b0b3af820c1350b1622a22c8875f24d48ff16231c826d1a946c66f70aef92d4e6582e3ce9213d907267251ac74fa3cca9f1c8fd53fe9898aec19936a2b797fc345d68f0791cc740199be39c05053d5591d874b415e62653b04a3f41e263d00f230 +A = 5419e87e50b28b6d24927934b541d8de548a8f4ec7e9b00aadb6d23f2d33406177d3fc72d29ad2c2e141ab2916adfd30ec4791c626af61d8d192276d632aaf3b54e2ffe83b44f6f1ac441e6823b6b58cc08fd7a0af945a02eabb5aebb2c7ff0622a17b38077cd0cba906ce23e71ac7f4da40ef6066565b4cb3a62ebda28f3629eaa251dbd9979b123a5447ea20331723e +B = 184782ba4daf429cbd13ac13fe93fe5833f09915cbbc707feca3293e505ce9cf0b4b12ffc8b178e0a4617f809be53d4895a4182e7a8a65043361e654befe8b01429ba4b7420193d1d7d90930ee19cee0316f33a5795335f5fa517e1ffbc99b95101b0f936353afd3bcfec34851ebff1ef02fea991a01b587d28640c935ec91496d1aa3ab8d38a6ac75b3a4198ed27b9019bb3e +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5eb9f3ca660de481968a3c7321281f22fb9273b16fc10d8eff1fe34842364dabcfaee4993c1c8ddb7c8d6e509a8d2afc005075d5fd3c4471f0622753c7797aea900e785ceef905e2606f64f34e47239c40b74f07e2ca70bd5a18cb0a88780489f3e98232221f65ac9c5ce703a256b7b75eb1dd38778d8bc05a37ac9ad8d36b35 +A = 1c73d8e3d5db127a81477a5c4c6d61ac62af446981773ca15a9a01fd5175a2826a8763f91d68df28ee606e8ffc203305875a238d2095345556f12f3b5e10c5bb6ce3f90342ac74b9ac057195c863c4b9d28ca1d958a98649c7f8897bc6abbc39becae963f61b33bab4fd20d9d0e5464f21c2cdf06d00f597dfde45dc5919f5124f26888b12d72cbd2f57de3f2de7c014f891 +B = -e406fb60e35f0abdd313b8431f4cc89fbb034daf71fae0cc727e9a93cdfde53566fc74e48f4cc2111fad158c63293bca0b21b98416381b81d2443d0e91647679481cd6b6869b37112d3b6e575eea7fbb5bdea422558d817b49ac36a829926553202cf9dcef09423c085d26176a89be741ae20a434ea461def090dbffaf2e2ef97bbd4ec779041ed69ec07d125c7b85a2d215bb0f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = acf9d363fc9b76ecf7e61c33270031340e66595e559dd1c9dd4d2243819b660183521a4124558fd4b216dcf5c52c4127fe517c48cef428b9ee0f1bebabab487c968a80b9815e82c12e807c096974ea3893a8d5597f745365c352a6bc6ce92479176092f02907538c5e784bf26dcde7672338f402753b08de8aa21b9480df6955 +A = -7c03ba6e3939ebbeabd35cca277eecaec31f326ab75f1a29e05af50c4e62e0175d4d6a57acab87cf1fa3a51791e9a2b2d4d5db570ec3941263902b0c74544c323c106557cd5139d2a25f3c3ef81ca009d4e3c16f1abf6e2b5196df1b30def46d61eccdcb3741a6dfc8e8c5e6db68ec29c82b0adf6e35ce7aacef8da806b3b58bfa489d319869b20768f8eebb604a9624d048f9 +B = 4e021959da96ebeaad17f9896ed53010d80ed3fd4c3a826a266e82b80ad81b3032303e7c0e58034a652b8aac00c08d42a530039de60d74ad349438f5ecca1256342ded6f30e3bd2aad5bf2b49124cb27f45f697e157550dbbb37f5aef0f04839aaf1ba43bf1e77a1529818d0fa91d940904eda6b748e5c86cd1b37592542c43b7b4afe2b8926fef6dc01784fa431d43900edef27f8b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 24124c69aaabec7a7b4e7a82245f6cb14b199852a8b314a7b8d9049cb66096d5ac93ac75eb58a2004de8b0fc8375638c0878fb6a45be8bfbcc292e3571df1bb8d6e346d5595fa395fef983a365e4e868154fb3e337d47771419e7f1dd5e4220900c564d7cbe8e7792ab288f99d265aeb296c5ebfdaf08b88d9b30ac660cc3ff8 +A = -167c959417e9566c93e7e05d2a410f4850e3a313e516ec958c3d2fbdecbf58072d05691c68981e176a867d7467091dfeca11f695f750c8c44ebc4d08e39e679d96c4791ceb1ea3b89fa3ce26f7ef214c5368c03ba694f7ae592bcd8ae53a66cb3eb1e0cd3c105faae6eb7e7a8fbc88248be722406f2d35e46c751b5ceabd992091eeba15191ccf6dd61a7ee0c624d43b188c42b6a +B = -343940f3b2a5f73a51d6f609e8af306f44ce7b5c2e79edf6f4dfc07866dc5c4b2e0ba48099b5503af87762a44ae451d166f8914ba25b3cc41a766583bf73d27e40784064582fd9fe952fc00e9aa2d4e4f1ef35818978e725e69c1bcf267fda4d635d1d292d54d3ad10bae9763dc5d7f7226f371184465695f2d384d749fe07967a1bb64df22f294ed88b13600c7068d881f713cb8e3ce6 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 50cac148215963e58cf6d2ebc36fa518c63a0ab8fb136ab84c9657fee459043ee9f42aafec89e8ba5fd1cc5c4495a41e80590ce197e12c087ff7e6ea88ed798735f55a1634562b82f8514488ada526e5dc10700058980885000e266cad55948d1e080f6343f84b12a3698d9ad5427fad4017d931df77ed2e45e2fb8380b7fa39 +A = 6a9833d768a22ea46aab1a1619f30283a1ec254a2de5652981d73146aabe31041ed04d271c6f2e5e2d090cd615518a06563a94ee2b12cf9f142de3f15599998a712974d0ce9b122a2aa65bf8750f54c6324f12e321a888154330f0f9e1e5b7999acd70d4e6da95c2df1da2d19544b7abd2bd3041e3228c7cdba44f7d1cbfbcf968f8fe87fab523eede0485efaf5cc9e56095cec8983 +B = 11e782e2b3f469b1e3d14ccd1b8301ffcde7e371f6e9afc99af5809110c6d70e1cca5c0bbfeb95fc3ef8352581c11ba75c0f8c445ce2aea903769a24289581c95ae5ebd9553fee61a30d155bf6011278807833eb2ce7ee2a98fececa23fabaaa259409e88e3c4f4eb1e04176d44878ad3f6961e0615ade2fe86b6eb02adeaa7c9019d63231a28f84b7dcc8bb0e71e2a717db09301e1dca20f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 7cd49d72bcf5ff4fa2c686f21e1f0146c4f24b9ad2e900dca1c0a5d2fac5047509064e65ac582946b251a3f04850c9abd8b80c92af0fb11ac13debdae8b94927f1de0e4bb217e78f5d04897c6a0762667d3d883cb754dc610442c9dbd44228a7ae4f14fca145550d813655befe3bfeb52f1c76f989ea8a1dd9c10fbc7e9d6574 +A = 109fe33568598972063279b71ba0efdc2e03f770cdec331428fb8ca084c9b20d0fdb5cf9ad7ce90c8cb8f0fef10d219d7dfcc6b4599440db8cff9971da7852880bf004266886eced8763b3569720df3a1fb0dde2717ce0183f2250034871146628430f206c12f5fd87574c206b203d90c0f2c705cad3484c73da8bf4e9f7e1bd433a6f7fd27df63079d30c490aed7161bc594eefad4bc0 +B = -b95da952cabdebe0194b7fba519768e1b56149353cd12023b97397b59e0d7f4dd1d27b65b833948f58e66d3f6928cc3140cced835dbd612cc82a7e9fae1621986f71ddb6707ad57926b03e87e165d30fb145795a70627975bbf9d9ac9bce07492de5227c666663cc28b3e70b19dbaba7f16849535ce5fd61e91cd2875e0a534a10c60d21f919d566a3469d108a35ec3f023210efd5d318c7210 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 98a89cb3c9602fe503c32c44609bd4487b6c8323737b3376dafacc3eff96efcce7a31f1b61ee6799dc9561e77ac058fe5195cc013e72a2864f7e492d9f35244b321d46270a582f6f14f15fa8203d392e81b183a1d64d48b51d70e38d49c93869ffb9d7509f15ccde547d2d9c4dccd50eba49190b6e831a9f4f9000a95dc83f3c +A = -67d7fc8f1766c40bd476cdb65d4dd161c3d4c2c5860a0c559f0e87ada213c9ed33308c36bb1c7d615fa69ec53656bbae6b57181a0134af23ea2a75f8fed3290a2f483392a3745fb57adf2121738c84f6d34325121a702c8ccac0090ea27fe9a5ebb6ba9d4f397e4a7e3151850b3d7d25643398bd3e4c1da081471389799245d986cab825a2e6ca72b38ff978a2753c835299ab4597bc65fc +B = 676ddc4d18960817ff8fd2adffaa68c87d234d62d445d6ba3847ded849356d929d9e4ff01f517d7b1c0778bf90f475923517d855956f17ece1e032e2fd474d2133d6b8a591995454d8b587cb4f6fdd0fa29305f146d340cbe6b6efd28a926c73735621be0c5decb792083b3f063a43dd9f635e03f78c1bb56389a5cc993c8f36134d755a324d4fccc2ac3bafa270df67db0a4ee6ea4497aa33b5a8 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 76c31404854006a7d55554762094df6e11e0393f5b0451d85de2e5b104432df72023a35f44da10dbde01cebf77b8f9d3ad582373c5d32232564729af0d03c5450e439045d96a2f0a38871c922af2bd38c545d219adce0ec80fccd121d6a733bac09253604a8a0b1ecf0f24e44b818ab9e9974181cef10e9eb17684c57d72257c +A = -134e8784878a8f3cf49ccb952075f9f9bcd24a20f8883955f262867045c11a9c566abee00638927e5de924872fb98f6376e321ebf3f567db6cfeede62e04f839617d78b7c9d3487b60a0d3897b3fa49b14c12511d04854bde4a9dbe5f31424a3d05cb75d23b46f6c0819536020880afa5a2c173f6881754b56f82a2864c99c820156f96b5cc4665d603597331d98d90a52f4a30c6215ee5eaa2 +B = -3c5c0d35de5fb21c84d2db228829f43b31132b582556b92b495f59df502a6d00584bb5bacd9b8c1a8c7eab91db0ea24b40f07e62a712842d5c2e1d208a6412a068cd5c6394d715260b67fbc03e3ae7eb4862f74f4d7484f747774fff03830c65fe022d579adb6737f6dfe297db750e6a58d1004e7e2716838befc2ea97179ecd53b7f36e3540e1c3a0f3e044bfe2d0efa9b89d2d308cbd0bd88ab3706 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 5b704b3181e5d0494937b4d6aa8172eea82919fd1d884493197a6a85ff047a7bcd5dcf072bdcef0287be20d4ac49918d1df550d184f86d7220f0a84fc4da3ad05e131c443fb529df01fec9fe4fa6fa2f36e791f9e16b4092759016d2f9b1ae7c3d071c57edf26386aaead767a3109c12a5004c7b9fa595e6d592daaa2dd1df04 +A = 48a0ccd2d14e14e2aa862d306501efe5de239e8ef36ff6251c861a0aee9f739411f402491bd99aebacdc26c4f30306f9137ffe4579c2f13efa81b979ddfffcd23675ac6307c0aa3ba8ee77a2e3a3c8e241bd2ade6484e6ead32ce8d752fb3584d14688f223758c5cb8705cea9c56136b219d87f9904bb56be2ea1c9a035df33455206e6b7972cba32ca4c3db41991117d88da3521780fe65c4023 +B = 160120a35ae3edac3edbede9ff1c6f317d95481227d87785b7ee46cfb80fac9973e418244884caca3211a3f6cd3bb419cf70fbc22d82ba5ab98ad80e1f6c2cda753aaf7be78613ef25577107a47ad1ee3c3645db85c4d29bd77900e99e1f439cb23c6c68662c05322f94feffcd9e37d8665cde984387093a043447de590e7874e6acfa37ed302040df4d5c3dcdf9fed91b3d17ab5c141d4494d0f301b508 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 448c3a64958b82ccaaed3c74706ce0a48c5e059c3610cc03a6b5a03a7de5d4f1d1e4b08a31478fa8edd58401f0171697f0662146ce2b371e335d695f9e4a671255f29fc0b9b7d1b2eca4cc7f8357aa0920b5942e31bcfae84e909828fbe5d02251ddf10dbe4c15351f675e96e2eae6d044da1f0858ce8ba9b7aa146850b85d93 +A = 1b2a52aefe44170376df29d17ae2dc1501c9c296f72f271c21f53db71247e72c3eb2b780190c45343bcc8f548507559ced3bd4a6fb13f9174dbddf965b9c4a56c3d88727736d78be9db2268cd02382e50c6fa28ddaf8eab9f44ad45d5882a5100b3027c150a7f3bb36f29d24a76e40f3820ba116d645800459f06c20679321cf5be72450879462f0eac99ab6ff8d26b464cd0e6d78621c9263394c15 +B = -b7d9bd08d7d8e0e9596851b7e03c78973a502afcc7b5fe5b0db6034ebb8a11df1ef7ed0ae1371eb4111cefd61c61935d768be3e3755e481daced219874cdf0d07a76e7144be626cf1fc21c8a0e9db4389ee213193775e95d4d86741d8d8fc820c239b7a90937000dc3e89b2fcd61b44e1c38c655bb3d31aa7e422b4406c9e4a88e6a2c18ec7c048f4a6b5b270c90d9fb378f64be3b5b351621db48a6c18625 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2192157490ae044a26c23eea6da51d3a3dd08c7fb67a9beb76d37ee24ac0089863aa7f00849b81bab8259f3a0e1bc744d841e07aa413c286e4bef2ff3356bdbecee756026915894584b4fcef7e49da4012cd9fcb5dbe3f3b867cb6a7ee959a328b0fd56a9eac1f4e40a22bf0a30073cd2d48f99245ac03c373810c54eaf3306c +A = -598eef47b40d1fa1ce260edc561bd1c1ab286a7e068af412ec2baaecd07c5b9cd596505ea1bf0370ea961c4ceeb9be76baec74e6952cb846f20e5da406bd01368b85d59569b403b7a305cd7448f331f10a34def43c738fd633df9a3eb194c32d53aeb567889927271d71d3929d43fb9338248b64f7d23cd1b053239e09cc2ccf5fe9c9ce240f1a10fb151a8583e4b4cbc70ec3082dd20a9962d564544e +B = 559fc917de34bd7dd7a23a432142ed79e3ac4a6caa357eea21e423eb9af7fd94f1eca735d2588ec4c2ff013520c3a0e209627217cc69bd5a07ca46a43ec1f1bdbee5f09ceb1b2c18bd388d3852e51070943f16152a73da624be680c671057677356c6f281a4ba1f7c60609125d7fd9086c907ca5c191820d80e483886b70c1074e2963c49996ee92577334881edafd88270bb967da795aa4fefb739e4367390ae +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 3488bf00f67b852592922fbae64fa56d2e4e7081678e789bbb3b4f48df62576d537da2e99c9bdd721c725b9a828194662bbd51ee20ba73d4ed5562482540880686d9fb1e8ae62d08e39fdbbab1d18e399ebf07b3a6559dda8b043fc25a8152858d39b10ff64776e00a839950e7a9ed5ea95b594b6e9e9d4348ceae08071ec5d9 +A = -1b135d8cec9969561be396323e2f8be0c60903ca59b6c418cb19876e9e3cdcb9ce4f5251eadea11fd6e785476c70822aebdc94617063d161ebe55584a8a774ab230b8228a2b65bd5a6c873bb6b261429eefdc7d0c64c7e78133e739efe57f835ad03ef8f84601e1a2310659db5e0ee706f23e3c5c38c9f8c36e5b15b654d1cc528f1dd392f1b08921af8be6fe4e4e6db774392441883ef867bc729338943b +B = -34fb63435c90018e5843098e379c76ef3ba0615b6b500854b3dda3e77fc5646228fcf3a6e1cd87a506e4959ab05e24474990ad98ad0865942737734c03dc289307f1b1f424b9a8c2264350943449b3d2b0f71f989039131e23095d122ae98c0089a184dc530669e804140134e5b602861a5e61c030fc3d3b3eef0a59f8c0579fc9b0afceaf16698de3fa07c43231312254c04ab11ad7a29efc4597780c2cd1b64b43 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 8ea5fcf7fd41803606c95729d2d910941e43b222f9b0c93a1a803b197fababbd653a92ee34e805906fde29b307a962a294aa4dabebf0d181c046653ad0fe6da1295eef817f3289dcc6579cee8869198c39a9f79992cf6894162d35d812df327a64470c935994aca4985d0e6a783b853ad762338dabd575ca71034e29d768d014 +A = 6858d029a62b0f75e4c59f3ec067e3990b2304c90a097daccaf554abec49a9d297ca14648471dba08f22ebbf8e238c89ea06f188203599aba56611eb3d4df09ea795a7e28f91f4a9a582c6b949c6ffc584a076de653446aff9b24e87202037974aede37aa9a121b5b70a3e9b5ca376c9056c2c91f5d5484baebb64cccb6a09b4f40529afad1ed64b4cc4aca586892693fb5f92edb6b4d5f678f7a2441e51410 +B = 197d6deff7adc30b025e7e418cca0a641e1a1b35f78fb56b9d8847f0690313475e6fbc6f73c3a718b10bf37434dd9fb1eca33a99bbba674195b20d35e3b34ba9d7c8438eede24ebb48e6d39eecd93fcd7dac44235ad32f208919f57b261da70ca378f9b03ae5e5a733f97f0b3f4102d971272015bf50b6f3e50c7b36cdaa14a8a580366c9cb0118ceec6e627827b0b8f614656292675ddb66e1c55355d5a1d78e69ed31 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = a25db977e7a8fa4578fc530995335411432ced67e131fee2cd7ff56970df64a6f0f4a7d225d2f4ccec8e98273ec9a0f1aef01dc0b866e425d64e09cafb9ebe3f80bc0ad71c769f1ecd5efdb4a990ebd3a94303f52f4a97e3a1d615918f8b2df5321c4aa9339b4453d7a710a803106dd0ab49c6cd9aea431f97fea9fcae0bbd90 +A = 13f97ba15ce46ae32147a0aa4c1639b6b555f4d8a1af15ede4f1103f7a0b06b4625bf456d667720adca0c4e26e858f008b012fae63cd89322b33fe51e87714519e7dc3cceea27d968b46ebc04024d063b17901a7ae978591ca6ca41afffd81769f04b714134cfaa6700cf23bfda6ce67313988bba5fd3782bc62f76cf551d140c978dc002a779ae37400d34cbea013a5d1338b203ff267861edd88ab8ee1e4c4d8 +B = -88d8a4c8c680fb01f493f73753c70ee753951d4734627da14962e36449db5490b8c575729fafbd203a125b500b96364e6799d9cfcf0efb4ec877e86865eea5e99e2fe5e7655c1ee0eac641e73b71c66d7a72c2934d1ccfefcf59781035b2c7b89e5de3f7d1e9128cac57947d22e7577832ba374492a2f53be37e17733d8bc625fa77fa5cf093975049a5c477f792fe75e85da26cceec820c8b255df0292824b4c3a8ed455 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c1f2165a402fe9becea284dae60453965ce327f540bb8969562485fd1bb60372b8689d9c9c97c91bcfd699dc370117ea8b704f06cae3d972dc6e5eaac971597c69d4dc24a68b256f97229e643706aa6d2d844078a5fee2d08270820055ea58155d7bc754f09d0c6f804e55ebe53e3ec418747d4130cec68533f6f0c2f8fd2409 +A = -626a1580e52ba52a877cdcd62b34cbc7f949148671d4a61201e03e98985d704b2975b9a2d9c4557deae065becd662ce8448171ac582894bfa2c59d4ed20c6d0471fcad1d0fed1291df5e4556aba72f3645486580c8bfd0e3c8f6cb34fe17ccdd75fad4d4a2db4e00bb8c2a23ed17a31e95631320590f40416c153efdaf897e3b278a1faf1917554d9292f90c4edd5992748b58492289eecde1af34976ea8ff507fb9 +B = 44c336d7739118340048939d6c198f73f90e13030b69be286ef920902391d87a58df3632091d0ef25340eab395203e8dcf3389e95debb7432165147e145735d2e3226637b4b8cb7d85d68308be07f217f57fe439b31fddf3fd469869a20f1f852e1645b0d4903432ecd1fb6397db4c11f6b6b9c0fd25778b0ff00bab9ff576b16538a6b7da40f01fa7b987af8ead41ecb66b8940c0e8a1208d0026773e711153d99348e92303 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 98eaf476f11168bb63fddf7dbf3347e619f9b580ea6804ab893214e94ebc089cb652e307f1f37ea7ab9052a352e260ff7d1e8c17461bae68c52a8a8f1a57a84c79b2c8fcc2d504ac4f553d2534f2a776ca129ec1942d83c8ae24c772f6a8429bd61949ca1aa714cc3881ed731497b84415c88ad4b9be34197a549737edcfeac8 +A = -15897a5a986641fc2cda42d185d72aa1552eb92f788bb71cc74c0e424bd038e02c620d0686ff88ebdf0bc1632093c0d89e724e7d5b526b0ddc4c7e145aa90b36be0d8574901fdf286df84a6b52674a78cf21ae4865618b4347bd905461d878537b33cc41710ddb290964c48e44d4d2ce2ed82847de75938d23ed418bb9ff1caa03b5c1ac5d65692dd1defbc6013b3270c4314a45dc67883762fda5509b915e8277c1924 +B = -3a7141f54a0bcef68cbc3006166f7e15a5c2394892a428fa417a485981316a537cb3ec757d4a2473fdec2cd61010a9ff865852af8f43afc79a97d394bb6c58643858e2b4dc5cb958c33781b5c35aced7882e8b8d7b4e4249c2b82150adfb0c8f2bbb1cff3d2ea27ed24eae030ef468ae4d6b7462f0b072cd2a2f02426b3290b87b14d14b34e91a94c5bd69e9eda53335cdfa7df90a57f97f3d023ff85537fe0a8bc5d8fd7901722 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 34464b7a50713d17b01b5940b5acfaa7006aa6b9b083bc17e0535b08783761391eaca8703af2edbe13dd0fe9036d38aecfd9faae08c0861042ea1a25b41fa8a15b7721909783de3aca127e955e177987518dd010306a795bb66466fccd55bd9e2bde17470cbd36b1e8f8b63805229754387a5fb40f3ee9a8afb2e51e25c8bea +A = 701ae8c5bafab7f41c999e492f04a7626b2b1054e6dce1b83002b2d3de46717225b018733b0fa8fe3f973202da8a090ae3fd14f48b27097513ecd4ceb1b9729e7783c17fee9be5221fce4ed3860275b3b36b7416594d2b65e198ff564e82301cae23756c878494e57b5ea8fd22ad800a582cae32fbc985d122cbc6e0eac77c1000d3ede45ae7aa087534adfdea8e9f924efa1b19c43dfd3b7bc83d7c40df7c6578a320a19 +B = 18e0256543619a750384d30b6a7afbbcbdcd9a2ce644dbfc97a8ff699e118032558f706502c9b956695cb25a46d7526596b3d0b67b69611009265838bec533a9488d24583e7d7f2284e23c3cc4ccc5920fc57e24f60da0d479d41f5b9c6ad9152903a4f37842176c6257fb1e3e0681d6d583e704c1d1b24cf616fe638106638fe9d79a0c74f0df67cb2df9d99185324ebb037d01ba0066ba947d5345cd3201b19769d438c43292f572 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = bc57cbb3e1051d3a3035f77c2e375c7e3221dd472edb1a5ccaa7521849fc0ccc7568238aea9335a733d839e89ace6f2b66ef238267e0050c065c3d9553cf50cc5cd93d34fb43c3ea1c31b8ebf0b751f595a7e5e3e860b366229de4286b9d3f0267f78c6888ab3f208c55d9292079116ea0eb9f4ec2934c97149aa132c03336ea +A = 1ffb0aac11f6d1d257ef7aa997a030e2a12b0615fb11ff04f344f6ecd550e8e77e9883c246e009af33a51204e4066ed4249950e022a61337848dae17c88317e15ade5b5499c0d7597a69a02b6c18db0f975c19c16d2167c583571e947676ae9c15be60e69d76e78329aed5fa57dc5e616795b5487f3d52bfe74b54bbf93ceda093c2e14104a6d2f017f0d200a9fc89deaa283e04b0bd9015ec67598425312868eeefeae9c996 +B = -9de2d82e25b449b8ca4b02b2d2fc0a023fc5804ea553aa84674a815bd74193a2e549070e2cfa0b90a53070646875282fdf855940905f834f5a07f073093c658cd1813fc5cd7092af592092d789ab5481bfb14b6683139646cff8eb1c5dcdb6a33113d1c97d4b587f15f972c06046730b7e712a8e3dd5f4bfd07cfae289047de31776f222d11510ab6b70a200ceeb6802d6c33f913c509b31b96e2b8dba9e25b0d2250c3b102d814683f1 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9f7f4e010370ec1d76fa83f73c80825c3b71521855fca5db06d7ed830c910d0430375bf319671f6a83bf6b57d9d53cfaaed5bc5d615c5690df0067b18791c33cb9f0ac9fa5f0473e4f4eb7840b0b660962097606b3de5744089ffb37d9c0df1123a91a5896d4deeab8aebec469b099a3a9a4f6d822030ec2fc4d11636706fd0d +A = -7f56093243ec2399548ed95df79363e6ff09de211dfffc314b7cee526535def0f9a8eb9aa6f1736528ee7aae8be55c06645708d576111766ea33e0564c12103edd61ede3128a7a642f968eefd0d7f3768b1325c2dd910d459b15e54145a234225fd29932234e59d3ff5099ec4d5b5c6075f56382ade1101115c7b94e1e2a7bf075dec210fdaf2357c735416dd5d616335002d1cde6056bf7c478f810b78c661a3dbe6e54084bc9 +B = 4df1a6296428d06f51f31a1b0f66d0b77a04db3bb8e1b80d64da649899a1a55d4041bf0bb47d3e3936ee0f3740e1e8c2b235e1b8944d28c7d617d1f968abcde9dce10d6e3c27b2e3607d8df815f5a39da9b5569e95eee1fe5532c0a80011e7415800d8a9ec175fb1d13dad959becf04964b70dabde6d37072dc9f6d914309b850cda33a565515dd6c0181fc48bc7033b314ae0bd5872480e02ffc08dac4e3030d83b33488cf149e19b0021b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 6da5fcea305cc6eb47fb17190889e6a39c339da1bea2d7c95e997fc538b4aeec8b0edf7c109faad7fb6c656420f4afa104ada7a0d3d14d3ef0fc6774b59aa2687c0b4efe7c3fc83194a89c832f7168346cadc2b1fa6fa9a23a67c91ad731b4cfb9943738c7f9951945b2eabb3743473d9c0444ade756291f53fc7641501597a2 +A = -19dfb98f9f7d20fd331ea749d2019d8367935fb75ecde45d6dabc815ab9e593e51178a72816f85aa678304e6ff3a2c24079a59aca253d76c4ac633fea1070753ce770765bce47428f8f5ae40c26a3ac91ddb551b3d575bad9a3b6fc7954acc93aad2131b78fd212fb0db7cca4195b41651a5311bbd4d8c64f1c93e6520eef8e6308e98caa1cd0d3c9b4041182cbfa131c4948257f1200b1c5351bee77ac8bc8e44680ce64ed0648f3 +B = -2736d5038c60553927f389c0650bb1355b0ce745a7dc5f52c9909039465344af910a5f6a9cc4ec130b9877c1cbb52fc08b20d672e42b853d26a02bc07eabb9e3f91399db8465b6a8b1c9f4a4b9eeeec6e9b6180f1a770c139c8f29ceced61cc7ba182884ae01d14dd85bc924391333e8ef039b586b6a0ae18db3570aa560c2b0226d5e23e7e753873637c25aeb19e74997da4f5d0755571785bebbc7dade57446e0df4cdb8df23c1003533f60a +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = c0265805aa8ab52da5aec06ef7cad2026fa0b18edb27b4903e3c068ca6464465e34d3f3bdb4bcc10a19441040deaf5569645f7e09b36c56631b3a6144d6206d39c9bcac53b54210db6d484cd6a2780bc68c07272de03a9bba7e51c9d86cc8883cd2e1864a2ed711d505930143c883c57545e9c40851c6df8b3314a8c9a0d201c +A = 5622f906b077d243521325be82a43fce321412bdab1f15e4ff0c11a7066a288b7939afc01d30243c8a4150e74286611ac1ca4daf457aa23508a7af869d2d55f54f2746afaec477cd7df0d5711dd636802ae7f673b3f730236ac3899330f89cb71d48c2838322fe856d9d8b4053d9c1e66acdb5e43614ecff954dbe37c5269d7ffe00b34e682c0be3d7cf653ef212daa3d55dff92b329126636e440b0bab55f4810a2849f77c39ebb93e +B = 1ebe0d1800b1fcfb67d7d54568e45dc604450c1dbe103ee21d48dda300c1d9b9415dcd9f5a56cf12c2ede3c862e895efb83621435377387b29b882b2acac78386895c7daa90810092bd3062a3a4867f92d54622d7f0b89b40fabc4709fd507d4002ca80de231596630c234fa418611ede0ae4a9616d570232c1b03329bad02220ef64e455c164aadc16190ce35b78060a6b117b4b0641fa64dd8e8cddb5914e7657573804e63dc7b216b1a9aa175c +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 606d2b6f756548568013bdaba6e811dbae88fb01f5f36d30d15dc1e099d86bdca9fc1eb3a785034ea14cb7f4776586327d57ca5a52ea1b30f26e2a76140bbb0e930c7780673770fe22c5ed443c349510e1494ebe402f2621b1e6bde39b8691edbe5c7242efaa6634553e6af146dd40666edf4a3db5d1e7f9347fa1189c1e5168 +A = 14ea5e6fd612945c71fdb17ec44d95015773edc908a85a6645a8eb823d11226545d05b81791401cefc81ce9765eacea7a619cb482f29d38988d355ce731bc9009969b7487a3acca2d2065c1faadc5d6dd8ca1dcd3f3d4ff61d0a75ef75272e62193618f6b802f70795041de26d6ce367ba996dfb91167cb1fa16c8977f982e1718de7d60275a7f66e4ad72ee55ea06267cc4e8b08f488579825cc674b0bdfd34a01bed08b62004fda15b7c +B = -8a542280f6c8bf4d9fbc96d5bfa6ee0d16a09dffdcbfeaa2dfa1097a760dec7bc540a0b5b2020bab1eaa594117a40a9bb99c3f16fc340c262b29909608740b8e77fe4706a88dc0fc3bcd47998e88fa02f617062393978ac1bfe14235d43f3d5edbdfb9f140412f4fc2dfc05a700f47b1f0f90da7ae07ae781d9ccdbb951f19a8b8a9a7dd8a65942842cf207f3baed3a0b2f08a06ad0d9ab7ad0110346293d51ec53ff8165b925c0e7906be8b7303252 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 512220042f151479a6a8b7c743ba83366cb7733caf37164e9c823422ccbf78b0b83f426a7230f559d50bb0ed3d9486c6a6e25f4cf96c4fdcb2c861566c6a73215b6d08995a14569710cf9e54abded1d77fc7722d06fda4557a3a99862e5ce963e1be25336fb42a4629391cde3aacd47ea5f5426e7185c5df27d9136a6df26f54 +A = -4d108217b778694931088bc255d1f69cf8f5a14252156163f948ae58d58f2ed54f518177d668e795474952c930052c1bcfcae11bcd15af168ec2e881e6ddc8de257d0cff90ff3ad409bb3a080d30fdfda99078cc3ad8302a4bdd77de66ac082b40fddb3cb36c75a86bacaf60984a74a0fd575d751ed2830650d85844aba9e3f781b2dc6b515bdb8d9459b083e1aa653ef177de76282e86c99e97dae9c0b050c9e6456a051e7d99adad7be4e4 +B = 7b9079504c635655a588ac360955fceb10cdea5f3de548ca2db681da38c17a70df5798f72cf18691d14a5f400ac69fbb47e64115cf071466c54bc7077a228249209542683ba57791352ef3409f6a947865d8f234ea9d39491b5c001685487b32130bce9aeade97d9537afe3f2f87e8f3315619ef7f215a73cb724f1adca99b90912aeecdc81485c0d00a74387ea99c965118fc6a9af1163e60d1ee6a1eeb12d7c2bb9a54f747a415beb5873d616fa0eafa +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = e36899d83a143c82e19e11494ba18478c0a9497fc89fd83df38adcb6b33918645a416626409a156899c6583ab9a4426438d9c32cac54b78df579cb7b6b1feb3f39ca4a6183743a4b823082896a89f9f1722be842cb2d2ceb605f84a9f9b61cdc7e184593fc2f9ff2994fe6cc4860d255809d04ab47e154eaec9ecc807ceb298 +A = -1422272d9e91a14b38b3e81cbd9411a0cafca23addf4f33c94a1bca70603db879dd8a9c0b95f5986bcb447731219c4f9b32a1e3253b027b7963ce40279dbf4008e526adc0bd7bcb2b533392a105c6e8e1bddfdd2bde7dfa0d2e3b1c6ffa07fea07ecdb9fc828283e93b0ce4861945562478b1a56de32251b7d31f9a2309488f7cbdcc38cd6b1c951570675ef0d61e1df69fed78979dc755f160d93ab5a3e65dc2944d3333cb85aaf87a153a90fa +B = -2424fc1e71286ce3be684a10dd885e4891b52e9009c3021d90ebcaf68b6db81130bdbb74869cbf142e0f44ae72684fc12c85abb5157987428c7812889beecfd7bb43fcac2eb6298ebf1dbcd2e70e4274841c2703b8685df18f6e5bbaa1422004797defc6ba843e77f891bbb46699a863bc1d77c5e3cab809c247e2975e8170da00fd9c8b232abc3fc6b16951ac4e6c96f9503c1ff2d6832ff9c35b2c8aa408645849c577d2b8599ef520da57fe2a9eccfcba6 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 4e8a59476d47ee2cd0217bae2981cf25a2c38e5f5d5c30c2d8bf95856a6e8f42429e565f1836365e550d85207246514624e7ed932d6f5802a50ff9f15d500dd84b27729c1717a3df0f2d6dfd40f0094208445193ba6500ba03fa3f4bdeaf9251aace8729b32ec3215bcfa170575e26265fe523cf44a071470e3b1547901e9227 +A = 452cfc78cb9597e67aacd4ec83e5b473ab8b7a1dcb6097fab37e25d5a6e25c69c73a6c20de0e2a744375bbfe7f612036e69c7a503255d9e17c6ec1dc6cc6f634d4c79bed4764496e5c7c026fdf9408242d3b234195e67a5681e7d7b861f58eb631ddb9aeeb0e5b3ff7a7657a7fde5975b8a9e1f643893bac47debf7918c7ef8f6d7439320dccaf63b80ec9761559078baa8e35d98fb9dc242ba83536eef7ba9901395ef02b19990d8312203df7dc1 +B = 1dc222e7a737e6d97a703fa232defc6c0a4fb2bafd247c8e547b9c474421cacb7692ec98f94be19a5e40269e1f5713d06a6d081a943dbc667bc867e481b99c55e437061cd44c4482649faf870d9347e0252ba9dbe116fb4992dc2c2a0583c1351e9e01e71e9324f5fa942322485bca93c2d95cf304028e68224fed446966073ec7326c93ae326a7a533a36e053437910418bf1761abd9c4c5ab7e6f538e9bf963903e6c80f21a0a38a683e8166e4626a8d8b743f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = a4d5e9fb7f0d75ce41ffecacd2ee1e4d15f82dfd4decf5ab1bee75fb97792d0d574fee60a30b15af80bd38e6a25b1821e61628dbe456e39fea3f8a9ee6ef3d2332412be1500fada0c1728a1457656eb3e9d94c64fb2d0ac89f10f2b9ff57d73207274ae7e8c7538936cb7241615b830cc9011d4363ef88f51c7b3ed503c25179 +A = 13eeef030b3110451fcb1a258434aeb51d3dc805b38c72ef7c79d4b0e18d600e5dd28b552b59f3dda1898367ec7da5dc6d9089a585cf52002eaf8f9ec64b8d3ec50d0bef7dc3faf203c48583ec89757cfeaf888ec4a91470a6b8ec9f26a6b07f3311b4fe972cac2f2ffe47f5c11d2dca87c62680e2229120cba4de9cfce9f7f5c33af8398c07ffabac1675de1845e05a32536329647214e54e5d9216fc0cbf2730898eae19e425688bf184d16bd1d655 +B = -ea324da99252edb03f40100e528d9a5080c43be97fe4b7e03d9563ba48040d328e57d0defd4b7ffa9bef3ca0d2682aefd2a0ffca8566e755b11f2e3c6c1b707f1b9465592aba6181e583babd5c70588e7123361a8ae77d8c398e33f894ee288babea1d7eb63e2f3de469e502b5048417043c5a9a9a3eb921cea1533162e3ce9c79e6caf62bbe7e17b180b72c59b9ef5fe1a001b733d909a8278029fb4a63077ef9b3545f1159ad73dd75030aad599ea4884677e01f +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 2f096fb8fe2156c41ab695956f13f0fd9a084f87ea5f5b1acb6b60c62617b8d7079f4b072223ba18cde474af3942599fe070ddb0ac1a99f42b9506a2648e1b8f6106015aba0bf7a824842403bd3f4ac8b6fc4a9861bf0e8ac59be0322f0495e4b515fd579dfef273160ddf96e453f4ab663e703609c709fb1f016ca919fb26c +A = -4212bf679cc00adb2ca502604b71dd5dab99cdfaf55ae92aee6bcf8b3b6354a384656c09eec6175a95c8cb4591ce118e783d6344525c25e5b356e45802ea3ce1fe764833132e6b7bec434e4481c9cc2986904988bd8da7dc2e31cdc481fd0e359674bbff524124bab1ba4379885a6cfc1b73d953e6d1aa1b938129d74fac9dc597c31383f2f7e02fd995f7065290a9812ba8e205316ad5bac6fc65c6c7310f1a6b033503ebfe85bf6d3851bea1b65b9c15 +B = 7ad83f97f40d5be508cb394c128764532f0aee9a108eb02840ca1c635860b6d751d5f676e8670e2f61466397e1bc68f97ea52d64b335d07aed22f20bb1ed19e3e42e4205d650e6d37714c2f80d39b111577725e3bc7ce75bd7ed5e44f8377d5fc2b97f05c3c1ed5ca1ec90ba3ff7935a25a8acbcb15fe1fc7aeaa1e444cc2f06c1e6711721d24b8969d465e4958cb87924b3e0fe99ccb371009b5b15747bf6dd5d0fb73b8fdf58d955c8773a55424a34c741406f6f904 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 909626a69c803e9acdca97c56781eb672d6fb31430a53b853f467ca26d4ae96c182d71c0212894b776c88e773acbe9602e3ca56584c39b5947724290def7dbf04c6853a108c1282def95dbd5bdc015b68daeea0ee959b35bc5af98a4ae4cc7486e627bc9432bd009b21ee9af3085f074a3ae1bca879e321018e991e7898f2897 +A = -14eb8e28dd04a159c576eb10578c24fad9eedd3d8b7560b681002a54a4bce2167de05cd061338f63c50b86327a79595a2dbfc1d3f4e76aabaf88cfedb69faf5148c61f8cfb2130511a3bf4a17d846ededd4c08f3b635182dff1854e8c4c48007af028e06f01235fc2becdb32adcb9e2058dcf8f8655624bed9915faa06be972282cfbf8530bc0cf2de5b2057df32e4a6cbc3c772feea0a511cfe3408a6dab0e2714fc4cf15602ba0da03bf0016f1f3f5ddfe1 +B = -388da160568aef9f82fc16f48a22e8d7aeac99121cfac9b748c815e5d3a823b673ddcd20c1168f98ba204df5e52535f61b224fc0374092f8c834321949fa0a812b5e65c492fd9fe8246b74143a943bcdbeba16024e311d673357a3dd3eaef9ae3a72bb06e03e34e091cbe5b6a9eb9fa3d7f36c03baa5c3e242f2c186b58db5dddbd73f6aa54aae027529b8f8f0a536b9b283ab08247b9977a2ac2d0d9f162ad03a2fe247d2c589b1a2d14b5f90d5b9c0a95918ea956e261b +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 128e8844a2f04704a4a60cd33e85cb7ad373ff683abd167894a35a1daf947f504c0abd7a614e293ce10797a5330147c88c4d5e1dad1bdbeaf74095e3f5a515f2af68b7bc11ee1f53b493133905b654318dcfe73118ef1931eac47deb6c4958406b704ce027d9b027803eb8e639b52d5983094b8ff4b54e86a7dc6ea169ff1af4 +A = 75e6b045aa44dd9b8f4b434dd4bb1346fcf558a5e96b00fef9b6cfaca72fe8b1672edc2a64beee8b959683b1861138b297629b44a0caec6bad2ac05665728379cffaf66a129f0ba40aab7c6b1c3fbdabaabc87ed3dd580ba80ec7ee765e9a8fbe845c0d207eee7a1a3a0c39650c75ccb6bcdae2e0d5149991dc3bf899ae9b7626a2baa17b168b260d82fba84a12f10e09234035e08b730cfc230f0d2651c03e34d4952fca6409b5c6ea5d8791c90466bdc4adf2 +B = 102fc193633b0e60a48dcc17aa76f3e52cbbd1012f179736a0ba7a102f8dfadaf434063b0ed1b1528a018b349eaf192fe62f868b538cddd7e8e6fd98b93147727d58561517b2836e4a373bb31fc8d5e42d16126ed80b880c1a37940c138fc1f7255ee0b7fd39b1b799c34e5178580cdc076ef3fbff65fdff7497398fb1cac75e5c09cc7df1168a20f88a16e7b3ac78091a90f1169bccd48c0d06b4707ab79b741a168deae5ced5d48bb5f5dd3f465e43c82b9db7edab24569b2 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9aa9699d1e5d2c6acb21e31890c1899f30a925b834adb5b8bc8cce83a1718944a2c90faa71b34379a21340457478c0c43121dbd65d62e290eda2ba6230bce4e6f18555a1380c7c95c1700793157f7c1cbabeb09460ca28dc596bb17851ab2ba6dc6bf311ea69bdb7fa8eb78df74adf171d4677a154b8536f8104d919bdd58648 +A = 157fb9e1b38f288db78a1a0e22fdd9f48a59779487a9ada2774a094d34536b85993e7b9ab6e24f081c4cdfb64a82271100a054169e4f1c24e3957ae9aa8300e85eb2a45a6d5987eed4f0fba6fe8557cbf6128e018c5f9df028131bbba6c544b2c6312aeddc71405f0e4ce648fbab9e5d51685949408e4ccbe06fe501a36fc13ee65c31f062313135054b7679eef45964c77f5a1556ac09b11c496d0ba8c6057e283bdaebb4e6d9e5c557d975745f9f98a288d5bbe4 +B = -82cb6334479bd997c771e894cac1ead87dcbaf8f5006be5c70ad48ef94303137bdc45f261af91a201b276a17d884a56ff27af7dc06cc5b7b9c94f7c4d4a36f68f8d309c477b4969a6e7cd1b2afab9deec06555cb753d8a0eb00965359ef865a84bfa87b815a42b2050e1635d5ae5e3743c007bd79e820aa37a968702a960fafbddecebe63f022553cadd7a4d4fb27b4dcb981e8b490e80bbbf13af8c4412d158775db71f5fbc9986e7b8a8f9299574abf7bdf9ce7544e8c4e85bc +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 46e401989fbcde9d830dc6e3c42768999f153d44d270d4805c5beefb470bc1e82706aa7173b359763c5e15d146eca91a32a36f0a80802871933cc7f2ed15a5472988849a2d2f57543345b531538db57ab9bcbfbe787efb0a82e61baa505aad628df5f9e881dababb35bc2decff267eaed3d3671757ae1764ec5163b792b4db3a +A = -590c16ea2cf7fa7f63b5cf74804333f22fd2d0e1da7d226da8425abad2b39a4672fcebcf5cc15d220b0ecfeec09665e682fff0140f16889f7a6ade9ec11aae3fa3a369b3fc133babe52e42b7a8bb9a24777521f4d9e0efe7d7977dced9e40784c24d2c6056b3b668ada7856da71af73d2dd33d2e481ddf40999d86a6e236d0d73f31a67c52cc8b38203bb2840c0b92c2612ffe5fdb6be87f9a787d70b3dd506f9a63d144db3417495f0a48523c812d14a89710d95bc6 +B = 5a2865cf2254710a1a51ee3056b0c1f6c5f77d22d7aa8f939e6f48ecec529a169e630c554bbe682a8c4de9ce4daca77a278d7e752cb678141ddefa75ba42e661885a82ab55d699414ffeb75802cb8f4e7583bec8a7ab58803b378bb60fd46f476ea490c9aaba568ec17f3a6afdd6f20ec54a512f7aaf62d2f941e35b4b72dea77095e863dcb38bcaf8777707c1dd437ef2ac6b6a8b2b832f80ad2a6d6f279c053d02058b1a657a1cf5b6b269e15d29087b0cfc0c2d4c3fbf32a167a3 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 1c9649f4540556ae82ffd71b2c71ea8588aeb845c50dab595db9f8faa01a26c809d30d8433b6c0add465e164cda2b6723c942ee87241eb7baf9944cae08babd8e22a0eaf35c09e9efdfb9f8bfa65d53ee6eb23fcbe1d12a66ae05e7592ed788b231b000f895d098a24febcfa4372d249575926a5faf966072f29a62a401ec51c +A = -1bc9ae5fc2f6a3f1274584bac1e145f02c5e8c4779f4df15e98dd34344c988c1437ee4428485a09090d81b18606a6ea5c1b9136872ab5b37373fbffbb5b3fa8fbeca1e112b9f1643658c2f38b9548cd8f0f271779ce0acad403177057ea0a2af2e7435109879941fbf463488a2522b831b95c1cff21d2d816d70c25156369dbcf04a0e28e1d746afb8a77713703fefa512816fe73e203bb4c3428efe09b946b750199bd7a03d30feb90230c219a103ad4528cbe0de1e5f6 +B = -39cae179d955049f830867d4115d3bae25127c945b1fa0c16fa850e8fd77c1b3b9b7916b9983c1659b7cee77b7dc72abfff1c56681b7931c5e58cfe4f1bf0168ae32df0df8f652223885717a98f858a497b1a4be62a2215c39316c34451b0d957791f49139921d9ac8041899b8fdd5d3d443547a26ddf5748147e4c3e93f5043ede42f38a9baa628df65d3d6148ac2ce182056700f0f94029be05d3ea3a218b40f65a87b4baf097fce107c080de24880259f1046175db1297016af76d94 +M = c462c7cdd79b7604246a0cd97c017700feb25908656b4733353af8119ecfa0212e4bd24304edd566adb5c1e9daa40894290a9e2e20d523bfdb5a2603409b312cba43d567a27118c15d4bb2f3867a7ba7594e02859850b77b929823049d43573a881948d674e95c7427e2d04d4ed81b5f4de21e0d5904c8e0359c99d4bdc901a4 + +ModMul = 9fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c +A = 71b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905 +B = 167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d +A = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5 +B = -bfee56cd412318cd62e7b6cc49217345d3a94e7fbf6fa19053fa685efbc0f8b320b7e43883189396781c49371dffe7d126c032d1ae4b6 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf +A = -7bc53f6f2e78628678ebc8e35ae4905caeec61acca5c64fdf595689cf005bde2265cd43172802fc133dafd933d7b48def44256868d202727a4aa6c0cde66 +B = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 43c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21 +A = -1e6ce0b44105047d0da0eca7b936980267db41d41319dd5315889fe8fa2329023d7cf54f71ee179b5bfedf442cdad1920d311966f7175cbb953bb42ee105393 +B = -23a330c7e06cdef4b6b121d15a9c0bc774eb5e432e72d04c5f03a0c588e55e010b61f57c03c51edb1211685d8dfd2a35393091fd0e3ad2304fb +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a +A = 6bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152 +B = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d +A = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e +B = -de60cd639044e863c6a49c73213dbc2ca84e4225aefa5f880e829f2d9cb48ae92e3f2680c462ac697dc34da38f65fcdc1b4d8c3c99e8cbe29660b539 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d +A = -50ff3e00feeb2efc6df6387d6409a622b7a8297a717b8d94d0dc41c6ec6f29a8455c3580019349660b31dea1e4f66b74147de93535e671c853b604ba06a9b62d34646c +B = 49ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4 +A = -167ee0fa8e5d8b569d7848b068df06f6baed80f6fa6a442f9d11d9712622b512249b92c7ccb821ac751fe4ec0a7a47e04ea5571c7cb45a7985749ecdd87f0c0faea01d232 +B = -2207fd8dbf2b8e9a5e3cc515479cde241dd3671803f9fbf7859459ac66705be055fa759c85631ed2a61139657eee7eb08fd963b49e33666e60b7e75dd26b5d +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761 +A = 413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a +B = 1b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327 +A = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82 +B = -d7b7701340c5a358455ca5fa314ad83860d9f765978ff652d7f542de2e123bb976930b8fe84b9608648324450d8ed2bac4e44f2fc71711ae813cd8793af8d3796e8 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010 +A = -4f1568c207a9ec970b5c26f068f3cc8019e8cb483525d251cd2919b368d072ac8f40017a19fc7437cf88e927c9e7d6f539ee84865f0af24be0d6d98fb33d74e3e0d28020c00bcd61 +B = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89 +A = -1fd1f634685eb1470dd9080529a891253a28a0b31e15c662733e20d43fc4cd71f4cfe83c3774adf8293a0fc3bd806d0b31b61c6ed0b4414ccdb91e2994e22797e5771c63defcc0887f1 +B = -3ec0478afdf54c949a097ca411be41f931acb750ef4f0ce97d0f0fc77cf15970cfbe24b170aa332de04836b7a0e6c5d456814182d27c8310d5fb662a818bc421587d95fc5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14 +A = 572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f +B = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe +A = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9 +B = -95ab2c47f85001aa852d6999f29644a6a55f9e4e12bf905f911f90d29cd1e4fa4fc9d1a2aa6c215bcb5c5643561499aab8f2678fdc5fa9c6ec138aeb2d62f635c45f239e46b0fa +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5 +A = -78a6a6ef40e443c52036e75f0b35938d632bd45aebf45a1fff5c2e1b6f601a57382b9a82c3e8b2984e643eb1570cd83f3a6be6daac567ddf9f37bd96785662bc3cfee6f47503d239c77781a8df +B = 4920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f +A = -143d843e3b12431fa0d873815a757a214cf731c298db61ab13cb87fe78b0a6184bd1fdcfec0c7661b10775b4ee2c815dede0ed497977c9ec5154f7b24a8a786501ddb8dd257bea51b9fd9401ff760 +B = -25d4da7b64f439987eacbde66abadf0da7c1653c1c1c6d9b2092351fbc714a20d2d7ad8093209da371150b69b3602480595533ecc1f3c5005a8ead10732272246d8cdfbab87c49e65223 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a +A = 402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207 +B = 1648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd +A = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6 +B = -851a39d8b0101fdb22ea9e367286e572dd132b8a77a6a14dd0e995131467aee898230f37dc6224e35bed2eaf459aae579181a161450bd7ebe6b62ea7154a8a0ab590ca4a6c2f05531c4e24650 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde +A = -511565611538828ff7dbc45c273fe46f4f5105d41ccf5dd343b41e9dc579429e56a9cefc54657ef0422960d1375b72411a5cc93ffa323455e006e242580358d6cfb641f46b9c36fa777a613b17dd4a187454 +B = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8 +A = -170cc62ad57094d307ce1b317ae5e825c2f2e317ad6060437afa105501caea00dc9a86af8729e2f3c3a854387dc3ba368c0a84aab1a527ab34fe27b0a69bc71c728cca87be728457c65eea7d7538ef3aa282615 +B = -3d9da1377a88f647de57ade46dc7caf71b4f42bbfaa5e77f16cfcc90f00b5d3e9e9d82355104c7cd0db4c1dac0496be3aa35706cfc0a30a1329755faa439694e8e9b41fba8f1ebb46140818c7008e27 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a +A = 4f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013 +B = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9 +A = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d +B = -94b683326e9de19e414f653aeb2cb4bd7b17e76a23de6a4d91c43d717a35e08f2155b444a9549dfd01a8aec4dc901ea9f629f16bafd2c84828b12d2f63dc154323eb2d54938895ec4c9efbcaaede274fd4ab +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f +A = -469f61cbff01f0e4124ba69a860ec6dbc75cd758dd8ac7cbfed97645b16488a329adee62d1a66e90ee4212569d56d58b61676262f49dcb68296bbe5d8e23853e3fefe8a304710cea568ca65c183531a992ec5b4d82e226 +B = 4a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24 +A = -122621d97f42b65b060c84df3f0c0da097b5e240731b77a37bb9471e7e398b242db6f1b5e25062a9bed702860ccf6aaf386c1d6fcf60fc31b8c190d3486949c5772b9e621b863a7cbf29449ddd68b7e0c21e669492e58e94a +B = -33978406dd30ec2b192c416e422428683deac210017cac9e4355e8446d6969295b0fbaa8cabc92c1fc0068da70efa047f938a419bac160ed6f794a9f69f53a88648c9725610d5f309b652f5462bd3011cf68ea859b +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0 +A = 7b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e +B = 156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23 +A = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928 +B = -e08372fc766eba6e0ef55a9149d700b503e2e3f978c8a397912e2735d5bcff69c461561ac0822c44160c7c1bbf722df421b74beada57462ac54a9bdcdb42d6a27b86413036ed2282abf62800fb2518a32a4a135bc948053 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9 +A = -5d3568858c05a15bc9777af949eb01d33dfdba58439fb3f7af2ba792efe8e78b16d7fbc2a303a4c4c4be7c9d43f57405e88be54d6ab55268a4739945ef582921d2877019659dadbc76e0939f4b2cfbc91e5356ba2ed531526ed5b9b3 +B = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f +A = -175011349a0a1ceba11756bd528f2bd631c106e709aab223032d08d52d7d6724e8c5b055b6f97b48261f4860eae297badc1214cdae9b2500a7a47b4b777dd7b8f1006757754ff1143b637d2a3adc555f38eafbd5478cde0b04e5f46d3f0 +B = -2aa7f75d6801b04ea9f690aa0c5448906595fd28b53775059c01efe54b463f1d87c9fb4b39cb038e770f99bb995a2118b86ff8d004bd964e958c2af82becf362fb0b927c671cc3bd7185990419d26a827a2d81bbc0126e1029556 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65 +A = 58e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807 +B = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308 +A = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983 +B = -87871b2058d33cb67d83b6a56ab27839c6a6c771bd94e55f200a1257f2c737e39c4a0403fa410ea64e8f442d300df1c19c2f03d07fb74d94f86d26814fca23d4cd2cd3718252cf0cd8a0e36726f6e68827a1dab6bbb1d23b884381c702 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa +A = -4ee01518f6581c560a186fa05c6f4bc26809c4822cc74a0bb74d5a6b0a368aa9bd0108f26113443422b8c589084ad49f919a9e7821d99127bb210670e732b7cdf610e464e300a39d3dfa7c82f90cf00ce329bc6763d7b1d4224a020095112fefa7 +B = 72dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f +A = -17b3e0c9288be15fda58c8fd228216bc466731d631218a7ddf1d2c9cc858c0219cb0757d3b680bca1b1964eb15031b5b9d761a8bcbd160db89be339067a2ea35e1ac3cfed701912a17ef9ea03999d92e3592e893183ddc05cbb98a656983b54590c72 +B = -269f96a4634eb37cf8a6608408128587ba45958405a29827d0d03d34816fcb1a2297f1319485439d3e8594532545086efbe4d21d31d30e2daf09b74fa8cb27df54e8f9f993630cd9a292c977eee70887158bd3fa3cfef321ef900a0598ac8cea +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173 +A = 7906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df +B = 1479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848 +A = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40 +B = -cc5349a9c5280a933e87ca38ce458a711c71ffebb40bb1f7612b42b4684afc495e99c4a5f32eef1c9564c2b7612ea4cda7a0f5df6b3ec9026447dc565ca08563d46aec7ced9fc4cc5645960210d44cdc3944149051d569c9295dc50862f8f6d1f6cd1 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146 +A = -5c3d24fdb193ed83f5f6a825c1716f98e3cde6b32e09659f253ca3fd2a39402b5bc3a6497ed7bc908838e93422559a13cf59156254bd3fe1e3b8600b2a777943cdb39b9d42c58043f1d587424425d3ef5f5538ea157112970ce3e09a87fbb5f7c96f1b5e65fa +B = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02 +A = -1be86e7c87827922d2e8a06e3cd6b64ac9a280c525749bcdbfac4856916321a964c9346d17465378251e6eada42dadf38bc9d7d87367bec94ebdc21af6b1302e520db08a64ba6b39920683725ef02b011a3e4ba46ef0eefadb98582cb911d0cbeae9c231b5e432c +B = -352059faf97b433089a688c702b97adefd0c91d51a0395647f822c6762fee3287693e302fc5a5584a12c048dea1a320cb96fa70b5daff7c2ea21d249467d14c6bbee15a1e94c030e908342a939fbe8ae0de58cb6d6eae7758485e392ff6d5d64465b701692c +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c +A = 65e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7 +B = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343 +A = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd +B = -afd61df72361260484fade8b432713eb740df83a401d73492883a5139c918d5c911ff5dc00140637da1c6acfbab4b0bc8fc1f337243d90beeb1c2a083ad8069494c73a99372bd38712a5b5393c779ec1915e878600e0b48157bea44ca8e97c6099c4ab07fbda57d1 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35 +A = -47c5755ca61ca8b7ea927f6fbe347f1362915548ab38c40f0418f4c9ba4ad520c3b2469d9ba3976669dec0b278461bae80eda53e9d11447512963e797f45460f74678acdd69fb9efe3897913b6568f8e03a6d90b4cb5bfb06af132bf118574b70e6bd2f6d6cb4d0089379d +B = 5bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a +A = -1d68bddd8c3e6b78daa0acfc63a6f39e97f19527a43f6cdec47568d57b47f4e4b7ee88e4a28d683b569e406ecd2510351dba25f10b9f7c82d6da16d848bb970cedf7675e67937921bd334eec4bc8fde83d67aca57eec804ce22bb342167602fbff452d5f0f2a7f38b576e1e50 +B = -34d219765916a4c8ec843ebee9a7aa1162974d41cb4d6b60532513608452da9993749455d9701af6b7b6c7454d7f2fd5c344cc938baa5259301d4b56ae8d25b6f6510ae6bca114cae6791fa5a9551e8a405f5b1c0bbfc27138563b2d64f9a4d7a8f42a23bfacc3f1ec9393 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff +A = 773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a +B = 13d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7 +A = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967 +B = -9711e5b3965654bd9427f79c89a0b3f3cdec1c857f4451eec236c1f221bb6773e5dcc30e7381a18a813ac2b03ff4a4ba679aad41e0e5d7181d4627f682ca2dc8af9a8b4f878771446fb225a979ef9c7e641cac819c307c8dc50d9c1ebadf912ec7c844e416f95b546cf09391f9f +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453 +A = -75231ed37f1dfa4487c9fc79a6f7b36929fdca086e42ed41f79430b2dff521919236fe415ccce590e1d3b986e16dda866f3f0d29ac1adcf55d87fa5cb67dbf4693293188516e360bac513303769c42181483fbef7abcbc4fea1310c916396d29f37d9058a62aead94511aded7c4b8de8 +B = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c +A = -1bc03897b02d1edb633e2c019e40c20c1d89a210b0733412aab675563fae8bd75dd7e65988cd8df4d9b343586e27f548becdde274f62dd421679554ed9eb127e527a69d69fa8b17aac0424dfa2a7692d1e63617ea45564b55f01a70325bca050862d583cdad96c4a2e123d0ed827348a745 +B = -3d5239dbe7bb3dcfd8027204eccf5e9444e68d322a0b0c535a203a1d0c054e7dc1e588bacb891388241462a5d2b43e6cce34ce46a23e6ef29670603d31001374dfa347dfcc794988e58945d0d2d17da6565cfea559203dec119fc357d396f65b296deb07686b0ad2d25a13fd4fad88d2c +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149 +A = 4a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261 +B = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656 +A = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228 +B = -a7cbbb6a434e4b022d312ecd4a45fc7fc4d3aaca038cca0fc56e529fe7119ccdddc8e76d51a2fb862ad3d27a16ec8a51e5f66b9c7fdfbddcd05a0ddea14172339cee340c8c651eb653c6aab6551c99ae94f26116e15dc62f2c2e63305bbf84590fba1327ee721150d46464d7e22d45d53ffd44 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e +A = -4df3899b40d51c83dacb442fb143835bcdb550136921df78800f0515a6cee77fe3236dadd2a0800b79ebdaaf8cf4aba5ebb60cdff3e4b4531ecd0903c1674a4559339123e9f09158080fc53c4c6ae72c961c8da2f357b7c05368157b4956e592c41b25642457651abfecb4fed5d9fc1fc3825b772d +B = 450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e +A = -143caf995b7783b1316b5551978727f06512fe114b419c735b3381ec351275fb7fbd6ca88b848c3e8c9faedebd6d084cb8a231636f68f6803d14bafd90534609d4a4ac0fb953417be7fee4e4cfefa452c5ee5d1e1b97ee75f83cca8691a0efeaa8bcc1f1e0f18c0c5d6c7684c9da6c9495d31a32f40a5 +B = -3025fa05c55826c40089b12741b7d406f748cabf692bb0227519a124653160142633700e3c0676000943556f97551171d231c1a35f7b7d8f96b0366eb74942466ceb4660f09aecb2fb2ac050ef699eb05bd8834a2ba959ac71550b5c026b9093c8cbbb7c5fb9390a7818db682b7c11e58996c9d0add5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb +A = 499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99 +B = 17a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a +A = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8 +B = -de3563925474e5408e245184b57f328e265b6cb62eedcaba809d8f257eccc0a457eeb82c451f93af93ce9f36dd1aab386e7c02b356f31c2d170169dbe15e70cf5bb9073b35fe0e7c7fd7faa91c5b2b0740734f12eb741a9d9ac6dcf7cff59f6e16324ea39e1e07dc5b9daea27ac674dfe5d0a5790abaebde9 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 1aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc +A = -4fb2e3fde2a0c653104c077cc6459c9234f86cc2d7b317329b68289826d3e2b975f1a69bed1a53418a0dd86e1b2723f4c4c5a29d003161e667c2315ec24a36f8bb5f2eb0a94f261e791bb829db685cd0ec9e1e301dc140ea57cac1da228124ae029e2b8ab1fa3ab99c55a9ca94dc7b767162c0a24af851fbb984 +B = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc +A = -1b2496ef929bc673042996ae80f27c6bbd33fa7c20580240ef8fba985d1a6117d6e746989924e34f281e7d2509175d0773dd999bde16662e88fcef52978d19cc45fbae3997fa580a66171d398f4f0e7605d9f4aa4f728902cb886e6b6dc9f0161e7cf1ebac05a09c5a1bd69a92273280758173fd2c14550ec221275 +B = -28399206ae2820d26a5aa0bddc4903776611d08fc4cb34a22a8bdc2a19e9f8cdab94217f346a8070a4145f989e1dfb49cfd100267635af0e062872cc879c534ff138fca603b5d45a6860ea85b6de37cfca000c81fcda3d14ffe81da919b2a25214209b085bab9cb511889665fc845acbcd038711533da171d8308aa +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472 +A = 796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6 +B = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d +A = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1 +B = -a31a574d105305e47f4fc00ccea0cdf854556886b524901c22e6f3b59a42915932ab209a8d5da29ab70d1472dd5378d9c79a7447d17665f9d1f1edc1e545e417cb65415cb8a368075c16264f42555d26e83adc704b5c126c6129318a8f394af8bdbb32c8114470d11b2acfe806acdc7b96e1e348a32ff96a988de76d4623 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd +A = -5fafbd498d610e9f29c38a5c6c262b71672fe9e9c84f0f071b549390353e4fd0101a059b7c547007e27df97761767302458f1936395142ce5776b0959fc5ea039429d64ac5d50c2ae0ee45d60c0c50b7ceb4ff9853d57c6e883f588017ffcaddf5a1aa3e23ab068877a114d9a2cf742f01f5f5d611424c8ec0d082f5c165b1 +B = 552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f +A = -1a6b046d691830d33eecf2c53953676ed3f6fdd20c2252f6e915052ec28ad1fbf7a5f264acf87ef8ecd515ed921ce6b85017f3d8a8f1d14f269f31e3307c6f935ad468cf012a912b0650a15106fb949cbae7b36c9cd496538bb0646a7a28989dfadc719424519bfa43cd8833d3a748c758f813881d83c98f7cb2a63c2a4d06b8e +B = -34f87db0f839af6e4c4bf146789db36b3d0bcebb9bad81db690ccc3a35070d8830c9745b2fe730a1f3a252612e7026bf9889169b57b8984a5479cc4cdd6844ee3e150a2e7bf7680eebbef30e0591c895cc8b2ca488d489554f2339e2f55598717ddd8ce444a060cc95cad9eb478491ee8d3b8358c3762a970224abdc1068af0bde +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad +A = 54ec203e2ababdb0348135c0679eca2a8e778ed46e53f195331a48d3828e5e40da804ecf95eed819ecefaeb9c5377cc1afb1fb220175990d347981353e7d90637adf8cbb16812af8a3783dd312d967a490f8efe3f23746929cf2a5a8df58e0b878367f6c5e4d3c086f947fc2bf70bfc3a0008a8bb1d7d83f002930640b6ed94c334 +B = 1311b88a05224e15f1465c8da26784dbaeae84f818e029301ea39a982f714c64312f9f02d094c401abb6a89e8537d64c178637364bd261f4a27beeaaa901cc7b3d4e36ebcd9453cda33d47a53c6dd1d121dfb83a222cfd16158eac23482c8abbfaca59e765f6c1fe871d884d281793eb19f6409dd6bbe4083bf762ef24c24f0127613 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d +A = 145f580c2ebc6c0354ebdfdbb1d3d7fa17f0b55493b0b9a11b71001c840a967dc77f0206c3dde161b5a773a6b5fd9471fa08b205cb6f728e3afba440b55268d6a9542e234ec313d53583c580a391d8da5943f4a900b279ec9d8933f2cfbb260b74ab714a8b9a1af3190d914b6e42212df84f933a237728a5fd5473ce2e272eb82bc83e +B = -c67f9b9295dd5844307b8fe3cb9c1875257258e4be6229ab097e148c0175ecd0de4d84fe03c8da6e27153c709c2526092b1abc73b5fb40f1d4da9e0f3d8d2fd5f8a4e6f3c30befd80e189b73fbd77e8547b34010d2aa57072db0f00537cf3ced95eb517b23e0c854b4becce128a575a31037c3a9e106a476d8b0277d26dcee435cebedc +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca +A = -5537630b7cfb8daf76d14e617f7b69f7b75b472801a9a818179d83ef2984d0abc8ea4214ed3d3d2bd785060e9c2819e861d0df760fc1daca8340e8a2c997c9ad201d6d2f12a82ae3883cf9f5c51ff1c25277c28175859a7b8e5b6cdec7cb3875071cbe415bb698b85cb19f617162587516f93c728ba8b2cfc19f238e2cfda115b8ec0431 +B = 597296cb27080f33a24241c1e98fdec32f7a4013a7340d367e4cf2a521cd462a2803109c27fcec353a30dd20053a1f744394fed75829e8396f8de434399bafd6cdb6e0ee81343f0cb99ef3087a7c69bd43bd722745a46cdff0c2c837fd87543c3c63df3896ac101a145b478dc224644996fc72460a89beb5741b91a42f2fbaf0d62c099b32 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f +A = -1c6ac9565d1950ae6c55025f76e0a040eed0462218e97aea87208ba879acedf413ffd5e63a92dd8658cf5f49d633ce7b126091a55701168ee4932db004dfe8c35c939887fae3a892b0b04d8eb74191bf8fdcf5566b4d3796a5d2596b1e750f64201057ae60aa705edd58aba4b48f6a2e511bf5007a6c44a27e3efd5bf2708f7046c1fff7864 +B = -244f2a90a57e5d066fe22f4d52f91b44882b8ef76d1dafc3387abcb224eda4a2100239e729bbc745237f8129d457e98eafb2ede2f3afb81e63520493da2a5730f1170b31fcac21259e90c894f8bc488c5e5dab2c2635bc7b1ff56c3685607f6fead73a09f83a7a168c4245729ce5b06e482d7d3d72eff33d14cfe2f32f72175484ffa292a9af6 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d +A = 558613de283911aea1ee21d6b926f531f778c5226e978ce329860682b5375fe5e5328ae27b00f504f2a2d24470d16c1edcb8e76b4d1a740e55538e79ac7da4b45c5299993513ec3bba7e7395dc829a00d4e228618dd348fbf838eaf0bd50f6c70253fb1c1c734a07d0813915be25d3163df13511f3675022cb85af7646c14ba5d13f615ded8e5 +B = 1f3c3c468146c29408d9207e15b25186d3b06b3fbf9556eff7ed7ef7788032d87ae1a4d2a0983902d4c70936c615d8c9ee26c89af8b58d60231ede54e859763237d5ac59af686300a3e92f456484ce77700557ddc0f93bb40e5d2e5117f2356ac7ffca26dcafb3ce7a5573e07ee97515b6b082fe75fcc9dccd76b4fd416e69a247fab2b30965d9be +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233 +A = 184845d3762ad1a9c925c51fabc7b9e15570a84a06ecef994910845d56869264273d75fbb84a31c97c27eb9779e8b39f6829638a78b266326b60546507f65128caaaf36d4e7f85939b75cfb3145e2b1bd8372531cda579f59efa0da9c95a8efc72faf326d35c660b4444627d328bedf50a919029dd164de051a4c0c924103e365cd640b9637d8244 +B = -977390f52af784b52c1d54e82131b072a1c308406e9b82587102e67c6f7145f0020952231a5f0ce9d130677bb5a7a37d5a06dc570a13a29673c8a9068f06242ac438806c37ec46136e7c1c1487ca2d330fc1f3c1f42ea51ba2805b74c44a61fb2fac109710dc3dae78a07057a753898d4e849b910f035bfd807178f0108812778345b256c7b59f8883 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e +A = -76e575cc79d7f0c313a489b255e85d114f3933383cdfe75cfef649f639921eefb9b3b3184351fd0ad252c6e477e153ee586a0ff6da1e1b2bfd7e953e6dd778c849843fa5cc355b31f5529ca45aec81ba67a1e364d5a74a4656d266f7decdd47b2fc2d81d6c298afa2d1c39b5e8eed519a9997a14513537cdcddde0b5b41314476264d59b7d3f0e9a65 +B = 6b7faa437b4e8db8fba56c62eddb8a81e9090d1b6655a2185d656b2db0e85225992297381d653e707aa15f3017880b0f07abf3dc455cb09c4e551b3df3516c6db4ead79b88339fc33dda96bba76ff7c388363c36b67fd5dd0ee63f92f67549dd77e37e9902ae51cb58057579f03286fc48e3b7fba763fc5844c222e6a1eed9e1634d0bd034cff222bf147 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135 +A = -18ddf976fec2090f7d1f4d41b8f875e56c813c04338f595d6e591b3eabf9e105be792f45354ee9beff997e6c0e8ec3fdc714c07b3466ad1a949b9d30da0115f5484c3b9e00c7cf0c117db57c3c6cd7434371c6d9ac7a5da1a0e2d705bacfc22f62785222d59bb5bcd3e3bf2df8e845953c6ddf1b546cb75b1698dc8e20bc611294ff288056723f1e46ec9 +B = -2cbaff39103570df7d85a5673b50fb8818434bbc19ab4e33bcc8289a4047d85de1b7029a5cda3976ab12e1d891b7efe3d5576bcb3713c597771f93532853290068761bea04200fcaf9b05d8553b960ef5e28064de89d9e5097d12b26af0b64beb40b33ff82a55af7c5838b44282917fd4342e2065942c724f3cca515d9142fb8e46652242e8f0ee5ae07b6cb +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c +A = 5cb6c49efc6767cf956885690ef740337aa71b90c1d4b9b0a9e4734de0c0c50f2358fd45aeedaca6e1dd0fb510bf097bf46513ee09f3343bbd1c11f507eb61d51ada40c5d6b730561756480063f60caf05141bec9a769c241d367cb92fa8e229ba2e471fc73f48812a25bfc7553c395ca77b80443ccaa82fbb7198f8c35c3b5a2fff977d8b2a29cf9358ee1 +B = 16ff229a0e67a410555dbd4b687f1470ec854ef67db73a902f2d19953c55071c4a26dc320baa8571586f1fd54fa490b0d87dc83e5bf20b78956084275518b307ce69aa4ca1079e3aa753d97fa1cff62e0b5f3b99d96a24e411fc3a3e375ea21b7b35a578a72df68d28286fd9a324c06930905f696424780083715f77961532bad061f3901ed276a9eb6e81ad4b4 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb +A = 188785951a3befcab56128cb6fb9576bee2412e6cdd7dd1bf5643babae83c8011af99aada405e119c3be33653862440005be994bf37d3802cb6c73cc312824c56841004c8e871ffb560e93a1d222c93d63684e90a91394b9c8ba8cac27b414bf818ee0de7217bc2faf099783800485ce2e93612ce39fc7e2f1db708bf9bb032d92b66159073fecdb2e0257058f +B = -8dddf094f30284c213577ceb7f1b2efb1e4213a548e6aa840f801cd6382fb6d4995908b7827078dc3f46fccdb9e071bb8531ea8971de0ddbb714d678bb71ba9d961e58cdd5f41b8472146ff9b814a5d1d6368bd94812f8d38f235f39aeb2421a57499fe7102c1ab167df7d33b32a6dc7c8eb8f4babdd6b6c929d1ebd9bf4774aa40cefbf136feda7b6e10ba4dbef1 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511 +A = -65ff4322f8e46e03aa6c1fd10a207a5e51db6991bdca232c0dbc9d73ba77fc485d881868be7b14c25b05bb59b7f5bb6c4b2a7d53f35d2d7af282a0423285c5de656429ab7d3af7d92837e41ca701f527845e98c2bfcb51647512e6abc6675cec2a7d34ce55ea4dcfe9e7a8397d45a7a3e73bdff06e303a8f04ab6285eeb1bb78b1455931cae203078eaae826a6e5 +B = 4d936b603eba3aeec3d3f1f9acff02a0ecc28a8ec64b6bfd9b153b1bbacf4f1e186d3deda8c1c81e759237921cec53251250e3e838f5063c4a1eb6cc93637f35aca10b965533d18b713617a312e74c446d63eccee93cc97e3723ab27357ae9b3cbfcb3e2bfc589a1bd582480e776198df047c3ad85f611ca6fa480c70aeb98af02f57d56dc9659b2a6bee222dc3e0566 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79 +A = -100f2984dc1451fd7b71e5d290e4b7de2d26175a47b9bed524fae02bd5abf96faba06e955107329559bff3805689633a4a57275732bc42183acdc792cbf7b6b24dbdc8921b73c0308d0c0ce5d8aad75f7eb16352e67116e859b323deccfe5d9ffdd1f0265297bc9eede073146a06acc3c330458b07b8fd0bb652c7325cafdcfa165f69cd0de8b145d49ddd576fdde15 +B = -21ac4953e54347a56800d75f6feb6ad660b0442174cf3c5dcbcf6528e2b5da95a614d3a8399da14507df4b8eacaddcddd627b10ec2dc5fb8c43d96a38e6dff37189ba275afb9484df800587f4953e327af71dbd58780bd5885b4cdab15ea0f2864f961bbfa9bba6b2d9448443af87c0cf178990254c1ae6e19003b1621f3240a6e5d0a3be2deb5dd253f5e1f88dbb60b522 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e +A = 56f4d397530f5c90203df1ec799f82a0096888fd370d543e33b5a2c8042108bb75a86265204c40fa5a9a44965ad2fb41896b134ea56c79699a230f38c0e3fa4e5d346cda70e0253b9993c9da5642f4e645a0d96cb732f8f04c99a83d1f1360a385c6e1a972b89915489245ce58830788ce23b9e62d6b48a7ff9a486614d6979033f7914a0735d201c6f29e512374088db +B = 10fe818f6af7a95cfefb0ea0726f9a3e0e7c30dc9785b1fdf6e2b810515448386c7efc656479794d389e109ef3efe37fa6124c5a7db3164268da0d98538606c57bd2f7df9482860e81f272a27c727d7d81a66fc1a9bc8c385cf02b7ca6bc7ec2d8d6ba1dc992caa216d02c9bf0fba8ee754af77567c6e275ac1b6b1b36b065760761300d156e40da8445712b8fb206c0df346a +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b +A = 1017a4fdce8bf41ce804b7c9c836d85ff6ee899807e1736bf0357b015b701b9675297e5ebf588ac6c295feed3c6a367987e192be0d89523ac7d64b0b9576f311b5b2705c5398276a52f06085027480c2ca72884ad7be34967bcc6c8cb4ec4fb761e88c16866a2e284b40180eb14536810eeeb180ab701ec47ece62af65a0753f95ca657e7d04ebf3c3a7db02993da9089840 +B = -aeb03379fcd4e87cfd18957a72fce42e016951a72b673a9e81f666b3cb20d2bba81400ecc2b38601bc3270eac46a633a1a6b55c50f00e9d7fc8a20176b93e971cfaa4f41573b17b8ccc498f8a3230825afd0d7f102daee347a9d59cc0914ac8689c1d8b39ccef1f3def44054307a7cb7706535f0cf4007231ba21696424c3d5b42c8e85c278f7c2e8b7d1787effa601ad357eeff +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d +A = -669660e75eae9930dcbdb99c477c980869417ec9c0e8c4053f0bd8ae62d496daf7539f37af96fd1cfcf3149bc02b8182a46b413e3397b49d4b4d204491440eea65505cf5d33a8e797af08f3da41f5a0804214846bd95d730260c6545d51126278181719ddd396c55f119e84da71f0683eb6db8393b098b3a0c5999862644e073b4918b5c8aff17efe860744d85bc94b582d45c +B = 6045f903a750b69b709cfd6a1c8ec9fc0d7da9c53a9d26fdb0ce9a17c6a0ed5ba633d6fc01f004f4a48cf247d61f7df609008ca5bdc8eafe06dcfa06bb67efa6a584b5a2f02768718a908978edd475a2d2926af2a6e523549a5cbecedc78323c5c295bc0b8d3e14053078492e82e339ea2c6301412a5dd7efc20da0aad0577a37d853eed820776e672bc6d23dc821b5855eabcceb18 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec +A = -17c1dbc1ad1d2d33dfe1af7b4cdc7b69fefec5a92656957e111aac292e44719c7c752ace33dc74a6568be38b576a5ba174bcba77a034af5fe101699c99ca39f8a3b0a20679e6d0180868a232fd8fc775089e185e5eb81585403f32619a2f4d857bb091a824a89de2e84529e5b0702b45771a5816c5a823d81ddc89f8a70cc3d3a0c6bd6d85e9d72b69d2713b61c46161f7f4700bf +B = -2252b54c602456c5deb86a0f249f3982c3836b70a946f636b22fe00c6e3b91b94e19200a33087fe734ce9a3f92a6099ad03a95ca523b7edb9e1ed3464d38fb96c470464e1c54790cd48769677efc5e1d22f5be4c15288bc5ea1dc184a05fddd5e576b3b4962f37437b4f9709dcec374377db44c8ba1d8611c0c3ec35f9bba213eac59a047e78195ebbbeff941c7f862e8c80eafb72b1e8 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc +A = 6b31ef80767a7693e7d0a9ecce54beaf5848120f036923d80b7a0245aa6a46135e32314f3b227268e0bfa1f45b4dce83bea890526c7ac3efdc8e485189ce2c51597c2864c2d3664584be23559c03670622a53edc2c17b3f1a92640078ec35189dd7953e55e4da0290ff1e2996d164d69f1bbe6f5285ae89209d611a7d760e413e23285066eab8e126c320bb6130a91d67ef26d4dabd +B = 183f06828033287497322b05ac08f62dcc5fa67b7a10c6c5a319c9a1e642754230c6d9809dcfd2de4bb9e360d6e6e1180f6ec6e0d4c6185e34ed299b6171e653521d0f7b8975ed5e7d2c51d27f9784a4b6f9b5e97379fcdb42e4df981462cd5bb9d0501f93f217d954f6baf70343ec710065eacbd2b778430ddc36a7ef0515f29d5fe78d8708d8ffb6c3391c6f632cb1bacb4ec52972ce0a5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158 +A = 1e1f2e44bc7c79a00afc3b2570d5cd27ad5ec9f45aa94f63f2ec3fa6b69077480212a1cbde25ded7ab1c6cb1ec26d5905948e5c1d6d109bd5047b1e038666054606b42e880b609f6f00a219dcfb504d481d6fe709f4362940f6c4b6f2e05d243722cb32bee5508ec94eeebb53b5befa551d3ab5dff9cba3daebdbc97179e56cb778aefdda6a0c24265728ff9e59ca3c2d615398d97e66d +B = -e018708df037aa2918850fabcad82731487fb812213b1c067d0688462a4d518e5ec7c4c84f2cb2017aa6bc960e2faabbe361ad8f66355366cae869d366f06d7cc32ea08dc51631e7f36a4c775611095d8aed06a0086d0a471749246d7157947a1eb5d5503f207723a7062382b3e45bb84c6f555e48f6d63aaa1c04fe13c0108507c0ced669a5296bcc16debf18e03c32eefd177bbc1dd2f19cd +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745 +A = -75e06b47f60edd23148c3736c9c125a617beea7c8fd47e662c9d9be883ae925b7801a0030df3f4bdd3c9fc386f18c4e002e5daf4a6f7fa27b2f71252c83d5f1695e50d62a10b99e1900987b342290decf681a064f789e11bc3fd75d64e2e78ace56e7491fbe0eddd6f9958a5f95775c920ad6c051ebe7750fa76891ab00f42c910550a42bbc1c1e5aea0ae13b7e6f916a5d228bd57e854f7 +B = 434c8e4767d0d7df2125def75a978bb1509a26bf8305cd03df748c6c12b6dc580a2c1ca9a4526eaf3936fbc4ec797d0733217a54ffc9e1d7c6ca04fb39679859d5bd3fa64cd0a09cf1a056094b9c20ddf1f00e134533ba9892c2ca7346ac8d0655250eb45df9f0b7983bbf71102c6f1a2d9497e7a45eea7b3095cac037b7aa755beeea8a6191da268780179a652d94a732a2a5c7b626c0de3145f4 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950 +A = -18dcd213e9938fe4b6a64abee3b9867f65e47e5b0365d45a8dee14ddf787f34072ce32f38d4d48ccad236005a23c5fcdc02b72cf27001495663fc56f428072d3f1bf5e33ab2c5f9dd9facf122f7225ea03c2f67321530a642803f65a2e9428f32d0d974e68a25f705e4f8140568f7e4b132942b49f9ff53f04f241feaa29aa353925fcade33a0cc192fee2628c2111da1e652cace9d304d0f1d +B = -2e5397658a5e6db9d30f09e93e67a30dc84b1e17c25786e041fca48ab710e1d0497ce615264f1abcb23d5aae8412b58430bd801775acdce06cd362438898697940712062b611c92ae6ad10da31784207c5e7b9362b20d7254da0df8caafe0736002dd466d76b1a03e91a8dbe8a71107abd5f07b00fcdca2017391c7c3263881a3d02a89b0e16a2a765a32d24ae6584cf44a88975c539402db9a301dca +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a +A = 6576c31d48daaf7d6bc3658952c4ba18095f1a0d73726f6fe59381af45a2a6b592adc79fbc3b597e1eea711ab295cd991441fb5fc4ce5f047e571a7d949c709e0d31156184be4b8a6a49691ef93d7d3b120193f6ee82246aeb896b8b7b4c74c27c02cb39fe0335883a3f088a71ab42b947a0cd59dd2155c65a0274ec0836bb8c2fe394500724ef84d869bee40291363389e7012d672b1eab6696b +B = 1ba2888f30be283b588cddf00eb3ae3c641e35fc0bb3a9fc85d7fac1e81052129f499afd3e8458d4cf893d51fe4a2bcddf70f28c8edef16c7bbfb791daedf1a8248faebe36953560498af652d1f1c7aa0e9a5a667d9c94f7d9525cbd5a82147d58b738dfbba5aa162858c2c66d0dd7d8db38d41a2261e6efc7d0c8b2dd2d6962be0fc796705cec8e87a13092e4a3febdda3d4dbed9d11a1d5f92d7dafcd6 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82 +A = 111940235b144a42a13201a41a3f9e4ff02948f8e9127d9a3007906988a50b36d7622d1221155f2516812074a7888b1d8334a01c02ee33b3164d761d02b36729c299ce2455a462bf18471fca42e5b01615d53723c3fefa5aaf4a039a6caad35c348a0a4dd3f0204f084f35c0b93ab233c4066dc50c5fd3897a769a7c5bf309f7a9c30e905466c8394d509b79d62a69b58c73d8d3f1665ecd9a8a4dd5 +B = -e2633e43c38c0b4b8713c20bf4e2b8ccba680ecfc1139954fc42724277beadea438596942fea1094091671c2060dfccd0351b2fba8cbed35dc963cc18f8e8835052da884799d88ec1887712000a0726b17cbc4302421011d5be8d234440eecc363f09e2c04bc9cded3cbbac9a5bdf0b6d418822fdd90dead20e5bbbb3566ca94ab85f3a00d32842eee6521edd18b9aa6872340b2f47deb961f58bf231e01f9 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3 +A = -402034484e499a8efd610200790d443c5d3be35d19d8808da85954d42dca3f24177de48f55fa2efd7e4f7f624d806a8d461c3bbe0b626fa1f3cad2145746464108b367b13f3537ff395262256bfccce5f0414e1f98b59ed29940171d46ebc4bfa1a27802cc30d9221cfbceeb92abdfa6e84ab4a54965568aa10ea631e82067ae358a1a93a3a3fe3a5ed5636a0c4cb373b4d49f46f8fbbaa665a19200b7 +B = 78ec7dbfa2b28e268619ba6db34a23adab25e7f8690aa9464a7d8fb7c6b87d5dd9d33d4c023bb665f2d96febf2638fc087ed30796fe7517fd58e4120c0d319688e67a32bbeaf62a987a9764be75384bd499b0e00a850f27e303f615031299c631844d10abc571f9f2a0f742cc0e8df2fe3c244bd825bf1d9134b2f1059e2a1b61985ae8daf9bfbd9eb24ba268ca58553891945ff1a314a78fdebb5444677ac081 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861 +A = -1869c53f86755aa350115a9f49d6248cedd42a339506b8ff59cb878b7745956f142fc4387322c41f369773ed375b72665026771d4ed1b9ece08f84e4782d4c3b0177853cf9ac3a55f7e52f39c1b82aa42b30628a4fa6a838754ec6ff9809308f675e455bca6f44e298394888d85fee29d8a0c8e9cdb9aa08d68cd70e13a243b5804a3ec199f52ccd462ba6594d856602cf1d5efa509047633923d31f78da3 +B = -2023c544b6cdd8d971bbb345300f7a101f6dd44dede6bfb5f4e6b4eafb7a40728a3063f6d4bdd0f606ddecf062828cf889b2f632d0c9254c28f36dd974aef116b73cabeb2bba98635841c2b4d2aea833e35eb1db9fa9a9d33bf7b51c49a14907dbc6036b027a039192b47406bcc56bccf375fbdf40b82ac4b3c660a43d5a6eb656868d383cebd099d2a73506f675cf29649617fe06097a46de93c13d1e590ef2cc71 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c +A = 5e7d4ef7d6ace6cb106e38d96085d3f3505983fd952498af3c1d9b2af61e4ba10e14961b339c6e64e11ac758d5fa18c3222138290866970d67d0a4f4e19f453503eb8dfb85b44d1050c86943e7c5d6faf7851bedf7d0cb6b13d2acee25372243591d37dd230907457fb440f83b62395f80f59a2d02b87134887406a78efd77614f3193e517f234434ab3be084f1484d3f2c1f68c67c0d6e863585a8a5ddd0be +B = 114b6e6726433ea88a2ba965f0881beb3ff4d377526e4e099741f069abfaf29e129a1f5fd243c6599f725a389728f755f9cad767ca1d6ae5c8b3a32102e47af211e86d67574bddfa42b2cb466d968f38b47333b1b55211fd9a315acd5ef62cfd3e83c13ee9d3fa20a06b2292177961dddc7dc39abad9ea31ead1fedd3d699f651b656edceebb0bace11bebd0cfa581dad577b8b42f0a844bcd8c8227880876dd7b0aad1 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce +A = 1e6a59efe0b14fa017c32ffd0962700fa9752242b06ffd0b604b9bfd125114d4e0909534ede704cdf1c9e88a6567f4a2989df752510d087d7b7afb515ad594627ece54b8a8e539074386121c9a3e1c12eb2641ded8719e56d42ef50e2f3b5d7d59f8a6f897174cc00a7449d2b91f33e9df07902a95479731a44fc4ebe8048c449bd515ef6cffed70ae78c832cd43491203a247fcfe0a403862266777947fc2542a +B = -8a9d3646831dcc852fecc8e2335549e8baa2e2d82fcb90846ee82bcc715c716d4a9f62be29d5e1531db73c2186a4d2f118266de33d966b78f989600d772ffc55b1364117d6750cef67f4bae851e7e3f8fbdae7b79de7eab54cc1fee56e25d0632b2929e352c882ce78fd64dd0a1473e80b6572f0d4eb67f6bd6e45c7617314219d6f7de5e505a9b395096cd36650d23e8d57d6abfa9faaf0ddbff90d32865bf5ddddcaf28 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68 +A = -73ecc8a6a1507fb5dad40677dc6ec75f0d130ea704d1e87b00d2bd56a6be21714bb30202739170b8dd3605f0553ff57439051efea2a97def70a6d2cc3fa2b9ec27a00c1338bbd588513f0f320272b8933fdf6635e585d1e79203efb5c95a454fcd7f33aa2aeac08902107e9bfb29587ce8610d50cdb7f2033c5b726742fa9f7f20b4780cf9244e6abf6b812171a64b870c3ca4c9e898d4c15e9f5b0194ae736c3783 +B = 4049ae926bb52e862606842bbcb4a5148bd1063b6a56f331cf10000c524b4aaa80b3bd914cd697ebc98d68bd3c2bd5c87fac4ec68606c264c56e25b19d118dc9f2eca19bebca07269714f2955e107b3fbf85530b1fe99c42d33031958280b8e8abea5a918a41cc7e6980149ad68fbf1c0041798d2046d7f88a395348b295858c61c2f33d8512b6fe75aa8fbad62e2f9b0b7876ef95af8a7b7338a2d6b25ec6355c276fc6ce23 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866 +A = -1e165ca7e1eabd2ad1264d5ed9c3d2b687f2db5b507a0e4d21d9e042cd46e93c2444c6aea8491b5caba2d8146bac656b7754b7b1ae0f6216029c7167fd3b1c3ba2e20469d386d8566ebbc05cb51bf1f1eb2cad9dc4fa454b07cc1bcdb9b8f5a43e354c4e0f4e62d52798f667080a0e0a15414391269fe8c92f06da74f6209a3b215adafa1eb6866f8b3e419468e2e5b4db0d0ada80514249320cecf034477977bcceb91 +B = -3f314681eaa4cb41a3feae8467f7d76b8b05939731fdfc943235aa4d67bdca30e64de541d17a8971e829bc0159384643672bdffbc93b3eaded7844d824604f46aa58b1f1b9d788106aff53438954af015a0387268266a6ba262e2fe7a4c51b5af6ff7f918674b7407ce8282f66e84fd2582edd809b465e4401c67e5faaa9e5748c06e3bb8ddb23fa649ccaf9657dbf79b937eb8959aae8d5bd9513c1e601c0e536cf60c4fc3802d +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069 +A = 5137226623f4ce4dc9b80a783777ef4e53ad3c2ec648264db472c517a96383ba1173e52c2659a97ce36341a11e832f4ad293b89696f91a051c35bb1db6182260d4a276d1a9b4be848c206899f87a361d318d38b4073a7470c5743b816cbbc3bc1b20dfd7971b11ad4e20d947e352d42760104a5a3cc590b985ee3b5e98c779e38d2581413a2208d31873f9644ec979602671c9da72fa6f66c603c1bb6d8e690dba8bf4933 +B = 13b45d4105e3f5e8e0ba36c812faeafccea2f1a30e2ce8ffad57ffe0dadeae3a23e813758f270423ecda3da083b42432eead7f04842db8865f9f1e2226a3d298ec1895ae69adc55d1d338c3fb787f0676664564eefe46ca95206e81678cf1a2f173c52d809b1e06641a9b467f191ea09fcdc597271eb43da1a9a856784972ce0eeedd49ad363dee882438f09863ba5af063925871c525c6c0ffdca428054e039e149a424c6d1b5b2b4 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901 +A = 16978c06a03276fa2e0bea45740a98d55fccc9d27321fd0a5b8522298a2a90d391c06c5c59e7eca85efeb9b4c91d4a1e9178adf816d597311f004ef98d209b59a2d4b901fa14c57b7297861ee58b89c9b2e931e4ce5818dd4006f3c40168bb4d3dbbd059c1f1cc24ecdc64d37df16b8e8d0529247c06f905ca88a5d283ca1b9e6856fbe8115a326061905b369791772a47900974339722d19b3aac16a0bedd93e1e4e4289bb8 +B = -de6dad276dcc0a9e271ad523620ec570fe6e3b350b934932ebbe36dd571edcde968b6590be14326e0f6394c0a2172052ff8dbc3ff15d94fb6e36a098286333768a84fd0404dfa354173d01f98484fb20897c439c48952b7f1791209fed94e9e72bfb3df5f368d420d587ae8bf036db6700f77b130459e9de2a541ed885c69c5641defa9436a4f7a69d2848d0e5d1074f77fa688b6dcc4d4c7de25a3b1b040546ef7f418112127cff173b +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b +A = -5144d5ca834f7bbb35d3fb95818c1f89ebe08efdffd35993a7691c05aa1b67f6a28e219b27fdcb66e516097c9ef5f00e4257c561b1f94c52c577471cfcd7a55314d3b0fa308b59449a36adc884c48ef5f34753bea746bd6fab2f20b86814c9fe50e8abaab742916313a50e3c390c67fda8e3729ee3329dc5e4b7d3107083aa3a07daf7952ebbcfea15fae7338cd0b114e9ab2f81dc2e80f90abff7a7ac59e3aecf76fab87633ec +B = 48b927a46dbc4e23d714b256084fdc7cb9d4c96a988a71c956e0bf98785ebc9bf22b9d5c6ba0c419e60afbef7b96cc0c4a13e397aa2d2dd7995875d2ccb127169423455d138131199a263151f28d232ff4ae24e316907ace1fedd02a02cb5ff9c831de33e6702010fee2232bbe3c1c193ce792eadcad0c81e7d7c17e49168377b68690bc61f22dfddb17d82a3b993804726037cfac8aabe8548befc52a3c6c6baaec89a392133cd9c45b1b5 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3 +A = -1343c391be3f2b72c4b79d8d6091389c9602e97774b18eabeaae81fc0539336cd8c899341cf75fa758421c7f32eba9df474c934642003408b32db66cfa92e6e414b42b1d49c7e655ffb4c80f5bbff8d2774ee4f7198839680175e1ffec0428939653c6697eb3681d0f92634cab1cabc63f423d5a71d65fc7150aaeea74f9e0153923a1c65dee4a165e6a01a88655fbecd2db7697f4d2b49fca2508e2b8f84129785d36d88bcf59f4e +B = -225a0a4afdde6f6450f28736c3ef6e67d67ec6206a63b11763bc6e69b03f1494b275ac504868caa6d56d684a12dc1098ab0d030583e73a2f45a42b8607c0f19031b9c5f07fb71919868911806d210d43aaaced5894e844881e89bab85a203af9ec3adb105e50b4250343ca50c26df14c46d73a22c2e4804d26d44ff0bbcc13d0dc7e326c9e4eb441f493c9743ae0eea0de045e05d19ac32d2379196a165e63ba640ca42e4861caa24c29cbfabc +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf +A = 5f1239e0b5dbfefaba906bfd9003336489ffdf634333cec2484c582dbc19b66782ba40942d047c3749597ec4d89ef61b7803d33a9842f0c903461be37c679ca213aea894d36c1e12bbcaa1c679599d2adda9bd23e712dd0d0bd3f91d146e7a04f3e7ddec8b0db7e12377ab32ba241ed1e01da070c1f3ec85efd8387a7b9421453969ecba8cbdeeeaae6ddb098084bcd250601af780960c32f0a1ad7d7e61fb19f40dff1060c5f332830 +B = 1113f145de014bb6dd6ca05de159b97e9736c45bd3bbd8477f739daf79615fe329ce948cab9787838d7daf797218af5ba7925685ea341b802690bc9588ba3e916145cd3ae9d0c4a149637b890cf50fdfa8f89a62e508eec68f9332787733aacdd57ec1f359ff7fde76138d5b33d32e64cf7d252f2bcff14be3adb1afd8da9dc930f5261e6d715ac75752b29f083bb1de7b0b89ddba633b8137f3fd299a7f77abf79781a10d897e7bf2c958a097227 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0 +A = 14f4e24627c773527ed2243c0d1947395aba5c9cf95ae62a48827ffc1477614ad9c7aaea4b4fdd97e3272d3e220601565aebf87928c301656e9edb08d6e680de845615bb3a81c61ed043adb9d708ec1447f057087211673fa6ad8977166a2b4a8079a4f29d48e7fdd6875ccad05d2c219922b814589996cd9642ea2b798197407acd274da30d3ca008fefb40a25b38cb6042a581393283d6448cc69df9a5dc2b0777052566a8608a1010d7 +B = -b4188ebc5bf3ba31cf7c5e100e79806e92ff6f863c3d68a66aeb3ae8385f596dabe6f627f3812d0f2baea319d93ae00de41ab65e42eae7d396cc8fd0a2dfd35f303117fde4db5e8438df0c2b3b680dca538b42a7c844a9bf0d3697fc89ad0a73594627578dabdc214e0f4aa06b40987aed473e7f42d318bebf7392d9c898b4b8d73a94726aef65807b2ff746d4a9aa76303ed7b4fefbab34f5c87c2df82d20457f68289f7b96dbeab581294974e322c +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d +A = -70e99398673324ee83495aa0aadfffd7bb9c94ee5251fff365124fabc50175d794fa84509f034c2b86d83607789338b0eebdbbf709a129a0ed0afd21c130d94b279c56f1c7c1eacfc6cd13f724a9352b2b37412242a47b23ec61ef0040a8855371aaf238003c45ab9d18a66cc7dab9653b93c323815e5404762d3f964d4654a6995af507bb2db2149eea59acd72af4d034217eaec0be5ba1d23890081a6a234e125572e3bcf68a6ea52d9437 +B = 661d8832671a4974b493e5d71e547cd46b36730f4017e50c5d1a7520fbb75f0314cbc2ac948744dd494d566ba580a2108106b120a797cfeb1fbfdefdab6bd6b2e073f90c77e814cafd0b7f79afeecd59778b1dfee3446fb32139b2311011576674f96f151f896b477c631237995e11e61e715dd8dd38e802af93124c66eee735c472972000cb4788b26752a630ba63b45e8ebbd979f0a4da5b359abd2905f0b7f3a21b1d381cd02ac08e284218ce41c907 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493 +A = -1896f67485a740720e23e1642ef02742ce5f10a92e51af19e112cc99c0fbddb60d7190086c942d293d076b474d056e74ec9f0c42055d745a57ba370c51ab2b761d889b766cec909811e2b2fd11d6916b753ae00622f038a4bc55b813a5d06e6ac136e81689407de721ee852cd21ea989ea7c8cbd00b64614caf0974a62097b2eb865f46fdb0c1a2e4f2d839066b797e51392e5ebd14dd92630c070acb546dc7438631fef01594878643a4cf77f6 +B = -3a8e2f3b8378a2605f5affa21c4fadcc655f2f8357a3427d2cec0118e55fc2bbc25931259e294d91bde8dcbacd39e6cbc125683da7d0dcbbc67d7c5866f08e7c4732cd4384d9366868370ea40a75beb23b81306303da4a3e26ad357c5c743d0a4ae775a472afddf8f21cb4a1a3350bb6aa71037607c334a0c79468668d3e727cf1d0610e49f27780901c68aecf1d145953e45f5b090855be714cb39aba2efb0f7db2786b331dd9bb8843de8c73c95ab13b6b1 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280 +A = 75e31ab221c08b3bd73bed03f878bf7742f9b36a89bbfa7e90f9b05ec11edeb0140dcff6e9ad1d62cd7af34bb4284b3a52bf1b48a40f744b561d9ece056a9405ab15f508700b14914e4f427ea1df3093497410a0108066e9b259c1a26ea72082b3cf0e3a99ad054804da7bfa0200d93d65354b75e605b47a4e1e17ef851a37c59a95e1b5172801e6ecabf70f1e6e382740998fcfd8a297aaaba7d04b668e3d6eed40358247767323a8393ec359628 +B = 107aca18938a9cb244ad646a37a212859b3dda7518a5827aa2146b47bfb3bd08d772eb7a866e1f674aab7a1c74cfdc2bc6e9ad1a365686213655b2c7b1977855bcd42ccecb804bc01d92bd7d2667069d853f18a0f0661f028955e39f71ee82b9ce6a81dfb2951b33b123e71264e819bba4d0a8c53a1d99964ad9ffb58b7cb5cfcd3e30b1baf5aa5b3cbd20a0df7ec37563e2b32b4cba91bbf3bb6fd1cbfb2fe0f84d720efdf36e9645c7e9ec70442ea5174528bb +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8 +A = 133a439cf006c753c132a8559ea13c64f598c5f8bd5043b89d04d7ecbf0ec58b225551c8df8dcb341198fb0b487774867e5b68f9058f58b3cc98168fbed0d0ffa86bf74b4fb0d4235976fa86d52b8dc7e82df176d70892954223cc484ae58b6a60459a9a0803ab856ff9699789172b163615e322e193bd758016f634c83cf50403e416ae241d9b1e44add17c2a663771ac88cf8b9dd94622d80d879ae41f0f4e7a1a32a1ab164f981900fc159aa85d82 +B = -fef33e21c07dc26a47d692c3094205bf4efae6af32f1c0f46ee579c1a22746a3663d66f2919f46f973fe558c61264157d531e66bb9ea10b4b49d9f6ad3ad8762a6ea8169a9cfe01d3dd65518c2e6e58e8c88d1b2f42d207399d7326752560cd45d0ff571309301683770793fe3765c1337d14021d39ea6980934c5fefadb93047ef07c807d0ea5625ae0cefd098988d6eb7af993c062ba313e23176e7abdebcc6e566304a5f9e03da05bc1cc58dfbbc898a67a5941 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297 +A = -534042b0811c9afca04d20d83898e7653f91a73de1e4b516f3228c6d6d9b963c7f8f4c36e05383da90f4edd072a7eda382c47b84b46b4dfa16f269c2d9ad0fc53ed2ce51cd31e4e32d0c1ee21604d3c7eed2deb35cf8df6fe1c0740a1515e4c702a2074ad6c0fcd403603b4a4e2195d19b265958ae854ccb0b41cf22480389a053f71544cf594f6833f3e4d91fd3d9091df0978d04d3922ed72a4fa3579c5fff50eee812dfb2a334148227a0f5739f8ac6 +B = 6935a3444434b0b03d27545721e253e4281884da027246e46ddefb01fa7cf7a9a030581dfe618431a68ef6d79b03b34f3ed598e7c8ac030e2b4cc887dd31664604fb8afe4e71fbc3135d6d3b4e596044d6b615de7184ebf8dae8fd58506286ae4d3b797aea911eb59ada39dac756d0e9eb6a6c767ab77b9348929a00f8e311f639d19ed88c86eb91f0d4cfddd34e98130eb520fcd2b77507c24b6804d3d65d1b21e6f6d55d1f6e92bba0544829687a096be79eaad7d88 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d +A = -1d476cc98529efe5b926aba3160b261723b009e9b880bdea04e9b5b03f173040ffafd1627b38be8e00840e85d7acd3abbae2f7a60b305256b920c2b25a8a4373ebbf1a0c69f6e74792cb0d849872500519b6d1c190da30c572e26b44590b7ffdb464a900fc38db013feecf909b43bea549e05f1b7e70d6ad879c613293cf61f0cecdba1a6565eff1bfcdf740bf553ffd5bb7d74f7e9537897184c527b990dea20387bab0dec3e32727786bb14975b23ff09f8 +B = -2b6e12c87ad91a2fa878b9245875209cbfef400e637b557c868ccbd6e94dae65f1ef8caab61f292d739b139e384137a747210c09ee6f3b2ceb6dd212e14525852b8c54215191e116b7097f6729f6426a8bebdff86cdc16effa08d932ab512d7265cc0f57303aa5e6fd2afe0a45180557935c230558d02c3030b38ca88de5fc75c1240d25a22fe32c4e5096aad0078d50989812d7dd0cbb02c736fa563efd32d14109c44297cdb3d4fa3b93a2e15bbb6eb678e93e943979c2 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 2c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2 +A = 5b0a181f07068af6e1e4b715d92c1b8391949a1e3cf0fe0aa49f3333c826f5582615d39ec28b1367804c1ef54f15fb83b3c578ef3ae957fc89ef22a343175df3ef2fd425f724ec1c3363aa000ef624d64c6d678a4cbd90b41cf7d69a7e03dd60c5d3470dbb75228b34d35469847772ff3d74b1a89a2c492c082d3ddb45ba4df6e3f228de6c64913b79679cbbbc36a2924e722c2c640d0c5a0e90ae86b5364dfbfae80df3d75823aa58ac6c1da78e988a11831bf +B = 19567bbcf615b777b35fa7030db7da18126cd695ca7dda67f5146c97beeb20df24ba0fda4a4f03523a0d9b9f85d9acbdb5793ecf9c1f4ceac81299a1aa34417779175a4bddc0e95ac68309da51e4f115dad6fec33a75d0c5520692a38df64e8d684c9304f9e2e6ac6a66d2e16a03c19a30efcac712aed2b9ee774ea28af4f37c45609464289de3f9be379c733d711875216bc223f2f468a0c9b4a8277bfe49c590ebce2e027102537bddbf2856c3b6e9389c4d1f5390cb0f346 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17 +A = 1dba8bd9d1e6cdc117a5a01b5046353084946fdddf2696f831a942d9db4637a5ee76b84d4ba63156b8cbc72e40559a2fe9b8e2682d8ba1db0cea042bb86f8ed71f6609df52526c42e7494f6114bb62263d36784dd55d396018b8fa47fa49ca6e5c76ebb0b00e6c764e36cb3ec75e3af6a2c14dee01fab78070239638521743d04f184dae79d49a2bf209ddeb4cc72e0c94a93a47c107f5369070ad95ffce034c554fe2a8391e67f817c6cab5b88ae9748072da5c9c +B = -849602ea3b79b33af2bd3ef9d1250c507d332e759d428902dbee054fdbcdcdc0a357a51d00aaafdacd696a15a64cbbdb7e1fdb347be5ddb1f609a4390a6f29f79ccdb51bd1f0547d0d9a2780517f8753a906428fd236f8ee1b433e57f2810d0ad51846304a5729f53a871d8b0e14355d24d3f092e50de4f044e2b8aa14cd8a51fbb2ff36b0b37defa7be768c56fbd4f5169d9d4698fb9072cbb0a037c219552728587d7c35f27456c02020f5f9374b6c53bcf8eeaa14be51899d3 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8 +A = -6a0753edddef8b74f762bf802d7fe9b38638923ee2d81bfdda354d40df4422e6ac43724de1715c4088da2e68b63c10c90b236d7dcab39b9a0ecbce57628f4c2950c79cc88a89daa20d7a8679232c8ce5fa30525c56011570107697222e0eaee6871adced52ba01a3aea0ccc9901cb3a09eb4db2f93aba0083180bb41f3f9eaae00fb458381213dad01997e9b88f21b0a79ada1ec3837ac2b63611455fab6839363b796b105c3be6106ff284544bda2a32352bbce6ef8 +B = 542c5fde65111ec8a38d76d8c5735cee17329dc41cfd0f13bf47e6d0e0093a129f3449db380ee9a70ec1e44640839ff18b950c8fd89346cb4701ef753e6ef49dfd9bd27d9987e572bf8e68df399cf945813582fa1d33e07be938a7729efd9a5e7d730bf61c537770a0727f6bb9ea6add5aac9267bf910eac1b7d92ab4184734ef8b1d184c292b2b4295ec1bfd17b8a2a2e4d315a8b37b8ff9bf6a1e94a4772267195c5a7ea6f0a0c267337fb97a023f1b50ad697ea31451192cebcbb +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b +A = -1cd74c052e62ee8156ba5d97f28aada75211979b1c5925ed015ea75f693a04c4dd0a705f6a723ae7b79958884c96fc07f81fca064ce2affc70768923bfbca6049952eea3ae048425b7c6ad1611ed4b8b77f7605629b9d198a77a27f25eff2f82867845cc868edee4ae31afc5d022b2ffbf43c14fa01bef8d7cd9d0e58362a0ff9abbf250e43ea5065512cd707791ea4868e95d8fd2357b3b3aec1a06888ae940751ceab01cf9e49015d42371fac30d48ef5853b6894ca83 +B = -2ac904d3632e25a4d536097d80a157791a6aca6eb10246ea21f4cae07aafe907c6e4c726694e14ce12e376c02d326f4bfc02ed539a5b4615a3cf5c838ffa52124f9b843598a3821cf9f1fe94e7206d6a525fad1ef77e7e77162e8c6d3d860d4f568e8f81153dc47f167860cd52c1ca59b15f1eaac6b9023c8b375bb63b6adf6972af8ca62b39f044378b11c4a969f3939d9fed5cbe18c06749956c7acbf963f640a1e1ceab73fc4c77463ee8d1575d018f49bf0f08161ce4f88aaab5a70 +M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb + +ModMul = cbbeda9c467ca801ec66fce801c6765a20148787dc6becb199a15c58fae8d20c1d391a1d9d57e1c74bb412e1b8f271dc2cc53c3355c83f3e2f00f15eaf0df735160a48e2273fd1bd75533cf94c5175ce67e79fa6c1422996fae36ba288a658a7a5422a59d39dd81ddea50979e933efc02 +A = 7ea551efeccda23622a1a5029e5525f46d5ccb83c28ec9adb7a3e97c2b7d936238c483a4a9bc92fe0e21208d5703611e2795b91fd5019272d255eeb +B = 19bd92c534f56dc4235dfb7efff6d941112d66acf81b079382c86fb10dc5473bb8adebfa53ea3fe6e4df8412e7807aed029694ca786 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = b18a9cd6a0a89578ea773fbfbf642e05935a995a38bbd54480ea3ecea1751370ef95ff5ad0e3203613f0ef6833237d549676a95b720848c5e9897cda82642a2f373951d5746b559bae2d98ac00fae26e5957c61ac1de95318b1b1aa6d5c64a6ceb6575f1b807060f9e2a241e378e6ebd72ade7d2df18d5353db7737caf52f888 +A = 13c68e450e9e091ae45863f6c1faed25906dcd90a43620b1a40e7a506e7a954256bab0225f3678e7ce6c4ba6e3a83c8f04a3491d9bf097adbd98fa6e78 +B = -ddef76382342178fa6636e62887fce6e19590065c766b047073329ea15fbba96f2cf088fa5a989f6ee3f6a513fbf66f621c6ea6ef2fe8 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = b18a9cd6a0a89578ea772021f58ce74cbdd8c44a09b3937b198adbd8e95e8e35541eca26438351bfdcd8600b4f9b71616e1f16cee707c712d40da9a440681f8c8647bc90ba4c68b08ce4cbca458bebd5110222f06b2ca980a2e9419e71064324e8c36289eff9c67f6d5d011e6db8538a54aeff8c20800b0949fa42c38fbabfa1 +A = -6d7e88715e9854b435876fc9bb2d25218a1451efb73ad9cc5f52b2bee929530e6618a858000b3f24fa5f47b5f461c84eca971e38cda6e1f475f6612ec32f +B = 49eb76e4614ac7b0ed3f534811a4ea6da5ea24be925ffeaa38bb228fa117ed56ae976b590d6c9d9a7a8546d8a6ebe4bba771d6587ac44f09 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 44f8596fc06afdb72a6e4f876b70b8d5d734589f41089c510b0da60ade642fd79cf8e705f09910912624fa1f646da596c137f124ec1a327beccba62a44f228f3c0977fda2af631e249b2a4de17d170df07bd812c233a96d17e1e93910267682d24c5c485f99aeeddceb658a7db258a2fdf73eb0266d26b92e +A = -122231b14c249820f0dae625342415f0c6e7f93787b4206b79e9ecaeb09623636730810c7936e17a1eece68edc7c97218efb17c069bc59bdb9681a79c910c4a +B = -3cdaed858523fd55553ef85d018c1097d7b88f6c30060d1e77b84821ca20b5625723c7d4331ccad1a70371eacc7f7aa11220f83f1bf3595650b +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 6de7efcfbc1e8d2cb14cbe4465c4ef71f0d1d7e80a1d80d9ac2d0b161d45fc9d915c54e33131591e8daeaa11ce02404c9b8494added1bd83e344ad4de7c04f626315caa56fcc5ca2ddd4e1ff064a2957afeb5d280477bf1f1195c7294d89049024fe821dceb53c7d270a8b4653e2fc0a4d8a3863a854bc3794753a +A = 47423c4fec1eb6779fd23e3d4070d0a7bf9a946f5610eb469876797a39c58577242daef8c34926f6974089fc595508d9c573d0a275cbeaf37172f10b8c849a493 +B = 18ad789cf09e9ea182eaf43b28b4f2540e533f0fccad325430b73101c00e440bb64b70ce0f2680184aa8caea2f6f6517e9b80285fea8b61887a41e +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = b18a906994d3247bf8a00f20e4b349a500159d086aa863772e71a68f91af9d19e4c021843f8bb6eeed1df708d55047dc8faf219e00d559517632dbd1cbf4bda61651b9644481d052903be1970f04bb4ee8faab9adbbf858324e6cf5aa9384ceba655a1a107210a9497552ba8a56d5e0e70b0c757baa71d1613683707357827f0 +A = 122773509ee608cd9ab3ff6763629a18eae41be64bcfb05122e0b3e112db48c64d2a5a515d96a042850c1c848ae5fd5f0ccc57b273d25bd8d68568cb00bb17b1589c +B = -af398208c01ec9700e332f3e694894c7cc412a73bde8a79e08764ded92f0d58db8056883972c79a0c9e0ce810786cdaa3629baeb9e5c370a5a59d3ba +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 64ef5e7063a1d95226569a27218e35e93d870a19a43fba9889a2ca98ca5c573fa56ebd77f1403b3bcad17c1351803a809c245a97bbe32b45e21768f28c5b11ad542f5e687a17f7811df6c8735e1778e94d9313c19fa32a6703af7ccbd88b489c96632d10eebb580cde3b905f6345a2a2b86a871b4fab36fa4b0dab9a6c1c5096 +A = -7dbdc37a51b601417efdda2516aba15827a40ffc304c523a47c544d5c0bba6c1367a20d8a6268a5c3f723b1b68de57eceabbb00d44185ec4ba7ecdce5d80456f8cfe7e +B = 641cf85fcb5fbacd6214be4b7b06fda1b80f4683c21c1d08311f6e23a15434b42d30a51912898a1c46b46c00aef7ab7663ecba683897825a4b07d2b7dd7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 370f20360ac844bf4275f78b7fe71ba5db6f0bbabfbac3384c04b256eddaf04725d2d57b31afa48f047aade156c34441b4a41c0b2146790a2e15d13b584021ad55965588c6e55ed3b5cf5c36b780a27c5dfb72678d57528ab17ca2ac696aed3d9abb0ca448d9d5789fe37e632fa9709f3bb924c4ce34244d239a940dcddd9c77 +A = -1a0cc5b07271098a23f01b3c0d47cab8b294794b74a8b162ff3b313fcf85ea81fc99433cdf4450970311e1d5ff81e9ba27eb867073ed250aaa7795e44ba8d4000e879bf31 +B = -308f93984acb78c5dac2426d9bccc2e3ac361143807c7d34c24ef8f8db5e68a904ac8bfed1edf3cc90d21c87ae4d224b8c46fa42eea77797f94aa848160fef +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4c8f466d1d9829aaca1a22fb6ca5bdba885606b9264933ac2b4c18e3afc0c406aa71ee7ff490fcaa804f457096e44576ff8096fb1d2b3c68450a8bc36d1a2797ab8b621ddc91d75e7d6ba01d86e959171fa428a5bb1f26766f94a553c94f6dcc2e0af90d7776ed3d9fb67e842e88f7d7342afd86e2f5d159db7304ae4d204a3f +A = 57e894e37159cf3c161be9c97a946454e43bf09a7ae8e1437570a86c6b06f84005c1463d27d726afd2e25aebb1657eb78957a9a12c8749049d12007a81d766dbe008aad6d83 +B = 16dba5cf077403ff4af47438f5840f65fa4e058c5cab3cb730154ae0fcc982ea097c6d0e75bbd635e97314f33ec7e31f0e41cf285ecfafaf36382b33d5e83cd55 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 29d13ec304f26247a45ab6869720720fe019d6cf370b9e2df9a65828214aeb4f8b17969b8dd54339d08eb99bbc66720ed78ef79033fdce6da33501fa8588af86ec18be4c4ecfe01781f9d1379865100dbbc020b892e77027d1f04f8171ca51fb73129dd9a96568904eb44e19f56f842b223724a9ffe28826803185e4208f0ff0 +A = 135ebb133a0beb909101da896e3aad7e26ea72b23e60802e54cc6c58a07b1205e2ba1fef6eb86c420f011b70e3f725aaf9fd1873b6e1c1cc7005c7c09e55550414875cfe846357 +B = -e8cbf3feb7be7fd12b01d5bd024e47538f434b496613320ad71f48a8972f687992f97e4b69b5842d2d6a4176a5701327c40325e98b27e4c0f8fee5a457d92181e40 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4309b728306535bafa6787dd79e58324b3f86eb5409d772018cce2159f75832b87909a672b8b4b14342b352e76ec5a6dd66737cb0a20b81c5ce222133bfddfea878b132b6f9fd557133973a0b44aa41a01d54ab565d6b9c62da67378a4058255047a95923daf5f0f7adff2a3f06074ab1facd986d7d26cb475ee818199a390b6 +A = -7a63e108bc9790ab687e0fb8a1cbe1e9ff876e7b5eccfbc136ba05fed93412dbc2ffb1ec49518e9fb867429cea1d7f82e2b159b75bd40eb8370e8a54bf0e0ac0ff24aa3662774bae +B = 51ee025b2ee8abf9dc5ebf1a4600131c00ae4b6bff966dae5c49ab5b9017e6b1abd6434736df6daabb2bde254022783764c94e66743dc752c9040563df7016a1581fe7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = b9ddcb9ab858d2229cbfab87d87236e8206cf5e1a042eb5ddde201d56e2695a3d0b2a42bda6a284fbd2a5b2c2b80446ce88c024137780c277ec80bfa6e9d15397cc5bac98e58c9130756ed0fde58d475a033fd94b1fe0ecc6fd91a8b42177abf3f77e87c0847a4244b9fd4980f3b42c7c955836bc994f2babfdf9c5b43315ca +A = -1f971ee9a7c966d1e82166503681afc280fab255665b850645321f67da8934baba1226e9efb59e0ac4483c8724f63556a213f2224b993e4e082eefff0056f7aa8a3cf5b655e0f72ddd6 +B = -39309313b04bda1103ca6f56514026538b4a29ae258a2a66424abe2c652b959f5c1dc4755ea37ebbfe404839505c2807ebe069c9abb9150205fe35bc286ca12b64ac46133 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 47555924c31f040619681d4a12064790e981db2c7853efa17e4d20f741f33c56d80862caf86bfe0730870b6c0afa9caf66e15047e60256fec29469d1760d5e9b77d79a84fcf7a1dcd0168a59f870f1635eb033e0ae0ac17bdb73da803206d48cfc1da48507cb812bea540daa2393321ccb0d88b57abdbf3a3bb765692a2c2ebe +A = 754d78d5608fe8c7ed8e26a174fa27833a24c48d23f0e702454b7eb578cb107da537dda11027dd6b41daad329e036794de562d7623bed8d9b0e909cb3fa38d4d21a95c5f4246e0b030a32 +B = 1839baa8b8fb6575832136f1d4632f72f36cdbbdcbd00f197fff3cdb88b851cbd74910ef6d43cfae9d3248e9c85662d7fb596ae45a460feaf308823f06345bc5fae8823230af +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 9b2f026b11d0674e9ec060fdb24b45fceade3070db4405b363d53df1219a02a664882819fe602f430636fc0bda935b14c55c8a0bbcc9b6683417e3ffe7f5d58fae229122ac6e42e76899254295dc5a08ed43c79120a5e5e4124b8fa6048ee90836bd2de51bbd2c6b9b53212e913cde871f11bf32f91b3a78575a006da36627f0 +A = 11402b3b1a45d67cde9730062e38aafe1d04fb1f8bb1975f25cd9098813efa2727cb229adf9490267bd437220d9ffa05bb993e45d2f889f140faed3ac3c7b53216455a830d6edceb02e8db92 +B = -d8e011f18bde068badedce8106f6602429fbcac4766334a0101b57fe94603203a4a8975fa499d8a68198aefd9e68f28e68914f920eea1083e37c67d59476bca9819a8bd628b89c +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 3a74066e7eebd9b63a1dd28548be60573c95f29816f3b3ceef68a5f6bb797d7eb0b0f4ee612dca794ff82f5d7461d995b9dcc09649e2587639ea017865328bb5deef17b5283691724e8aa331d75c635d5e19ebfd268fe5471714aaca8b48aeb846f241c1675e18d35f029b132f81128f19028b0a471b3f75a530321135e35fbc +A = -6c5dca3fb7b85573d1c8899868940794e428171e207b5f9f89fce4b7159236c0755e2959d870754e902e9c40dc1fddeeff6364f898ec0dd669283e6d26a612d9af3c3ab04468707bb8a7827756 +B = 5446269bbeb613e69286f1012ff62ea767965533624542f3b5c866cfb569d6193aa603061701992cb4873ea8b766606da1b57d7b37cf52f52bf85b58309387200b0ed36164f30d52e +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 2a4e727ac67451ca9dcba648050a085196460e4aa4836c5652de863c3e2a76213e0f590de3aee8639304c54a9dcd5f7d5d3592f647e3d07d322708e1e26329f4a31d66c7f2e9d482f22cd9823074dd57d14040a4f00ac2af9677a2c98d58ee1e094b1a8c40092e77eae454638bc3655e77441d4f218c637f95c147776f5bdac1 +A = -19fa688008a12cae228c6ac4982ecbc88da248d7ec785bf2289dc9103bfa3a91eb1e5fd6afe9e0cc035d3312e9ba64028fa6a229db6d0eaf8af43d8c410be7c689c3e557137ebd60d3fa04edb60cf +B = -3e8c87fba4a41c3a84874c987acee9f560b9f027338b584a775c1fcabb766700f758c4d451077a9427257334a569037b0bd006375f71223add62eca19b1e26b86dde0cc251e48d3b60ef +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 52e4a3f6892b425b935c6f9d1396d2034eb0331cbc5241e1d745a9619fa0cf0fc521585cb9d6b1034c5fbbbbecdc81c757f768c7a82f6ca291cf5afc98500c579f82ccf0be233066730f738c205c3c188f94b878c11268871ba42a5d950dc8a399887997cef2b6b68badec1ca641b88d1455e6d97a2841da49df7eeb766b7be6 +A = 67df01e34a26e8239c8edc7ddfccc3850f39864ed237d4dd67588efbeaaed1f884105508f69e20ff6a5cfae1516f6179ae6fb515a66ef0a7d633ba4218c30875287ecd0cfeb5bafafc492619942f97a +B = 19f5076405b3c81519c0863d0c963d545b2834343e42bb3c779788cbb46d89be3f775b62f4114268a0ca0e6af6c0dd659607d40071dfe7f1ad0df9a5c53b741c04612158de396e9c96f7523 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8ac1d96abd2cbcaa8f7e3267b716f675aebd23694d24c112d202653979636d4d47e27cc36f850355cfc5ca16b78cd1848944f8759fbf6b03fbb7eb347536a9328a5cbb778a6bcd983081374a3f543b1380add14a9468358009ec2baa7ecdf13e7260968eea74083459406e8889936b2fb98c8b9a3597e5f9ca10b76e1dd0337f +A = 1c9ab23ea37f324544280d176cc02762db7a39935f1ede9695b53a3ee2db49d0485c6a3742a3b5cfb51f3c21711bf89ed05afd0886bbf61cbd57b23439a8a165484ee8e4c0e1c0ca2b6478776aa2897d87 +B = -e30d28dd01655b7a419d939e3e7530258a667420fc759bad585802c63fe5efbb309cb502babdad0afb208aff5ce5830071c5a974604c69ee47f76fd87e2460a5b03a57ef0185881502625886f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5df0700adbd880a5730d8c0637a362a9d42c64503c3b9784046b946c2459a619b5bf804a41c92ed6370bba730c7d39fb2e01558f7ec38511b0449d6e9db8df2cece4ed348782ff1582396ca8b3196474e7e5817f8c197c44d771923b6e286e41e7e23c33fcd8765e06793169999544a310f2e080ffe13640b85f21a18fa11928 +A = -5c01fc52e86f3a344180bac284d2376d1bd693f20a46479c77fa57077df62f83b1e81c94e577d1d6733d276f9cf70555b20e3afcb97534e4e0108a6cce87e9292d78b2d7367ff15fb33d2c3289d2a2913b58 +B = 6bbc39283be06382ea91ad6b1630b38f32385ec90019d2ded7ca6fdaa39defbe22585be0df9c0cf613f6f146c71f901adf525336f6573f7f43e661c44b7097f110d4551e8c75449da8fd39201ca0 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 2a01005f1f387c4d8d24a365708e2506b044f86dfc011262d3577f7313a8f51ab943037361bed1858e021f8a46491a5c73284c666eb65cea1392a780219f13d7188721d7d4b975272293a5eef63480f30cc9618aa74bc51f4175246301a46fdbd34a6ec72d5974aa920be5f321a97b8f19c0ec56ba10eaf2e61f2b45f134b304 +A = -108bbd8824e8c16b81dfdd4dfee691e012e578cb9cc80cf050c0ec4cebf71a968732da36552979ffaccce6667e46c29144dab75132cb087681d5549dc5508f3719e129553fdc97f545d7ddb7d3a4fc575ea67c5 +B = -2ad4d4078c47a3c8f5f9b48e10d52d72349ecf0f54abc60bad63bbbf4d8efb185de90e5e1a686859e1c429e30977fca492aedbf084019e9ceb4490aa471776ed2e8a09151b37c5caed9ede66922b7ec +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a1b1b2d33cb610f1b398e03f274ef39a583d13af14b79e6766859b9ca748237b481a3cfd5d490a073e82e3c53d3ff5cb6219b2b2f71927f27ab6f567547a22dd35fb5919e1ed2b6dfae4d536d6d44fa6216d94d26b33f52db06c4ecb29702588b73ebce87569639f786df4fcf569bb07d5379bf8b83743327248c2d71b5dec6a +A = 5bc53b3895cff2bf7bf10e24fbdc43d17d277a982d5d92f17b9b5a2b9ed8b6104229292ef3997591e2e6a116fca21ad5d061ce438f33b7f7110293770f8313077152c7546cd522ef4054147edbe1878072b1043e6 +B = 1599b541c9809779df3ef40971e7a83f21564bd5d6596d51a3d96defa4dff41e83ca6247969a3dd9a746ab72ce21137f2d7ea015ac6b2ffa8a32997e8b821064d35afde3435b23e47cccafa74d5192535b +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4fe8897417446c493725521c0ea5b2110f91a1b5ba236cbb6ff3f52b0036a49fc82274ca949ac2b592fa4bcc792114bf2f2a78a2cb44cb22c6fe7e4bee7981604de47f6da2ed1fc6a8eb32cd9b8aaca0f2feec76a2438126ae6f409645d897769a6d340308f82dbc6a98ac059fca6f903c5aecd668fa838b67300c654d4013e3 +A = 1717c6503d069103f10bb4b36427fbdd2371b30793e492e4161fe185b2e27469fef6a25566d6b46f6a7f97446315a22d1f1f662f912b17e71feb2c82411ed7eebb84d4f594deffee14934b75a845d83761f36141ecb7 +B = -8808f540521c20eefaa037fc5da782c891fdfc668b955eaa2e4edb592e027a964b4cfbc94c548d785d92992abe282d90dd137c4d76419926740ce138d567da7350d89f2e56772d8f5bcc9ca8d7076540fab3 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8b9311808bef497d8a5d14f7d851567a196a051610246964917a1f9d4f4449357d2411ba9fd93983f6edd76b8a8e1501146b08b6e1fcdd97b6a41cf637b6ff0cff7a2d6351aa1ded93f8fc1cedc81879eef751bebfbd1559d5d0320595c79e3eb1db0951d7c67c663bc57a672faed9e14c7da6be6b0c6bcab3d4d515e51a0b5d +A = -511312fce1849c3d177d42088e55d534f9f7096282916e16b041f66ea90e2cccddab5cec0ba8ebf0b047ccce72da349f420cc28ab19bc156c1cccdcf5216f19ea922698127f090e97444751dd58fe7a2c90197a9ab3d35 +B = 6a5cab5e322d5f651f798aebf43a62af772fa2cc379905e72d253c49be8193a07ae6164f21cf08baff906ef800e361e1cdf1604f454483e10c8b2bfdcce77c12b0320dea63f9ac0afbb86115b656d0198aa883f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 665e16ba6cba87c646637a233ae04805a302ef4a10d79c5b65b146cbab8c9ccd491faa32937d0ee955dff7dd0ea3f79fa43c133021c8680490b91d9c1d8a8102ab709ada7508bd59042940b2bd3a4f8c195f781313e45fa8d3abda1f8e13b35811b638b2ab101d1caaa92188d2b75b2b10d596ab159583135b0d4d15fcd3d882 +A = -1375af024e9974cf8170801f4a709b4e5862ab7d18464077727bfc2581e557cada991e9484a1acf80182458158c44871e67e783f7573f214ee4ea1f1821a65068f2bbbed7575f03a4bba36b0fa8cb6dc58c73b100a6c4a6ce +B = -2d64b6bd987d496a3c121e89f4b0c88b6ebc6e30fa9d47981b52862551f3b7251a3fc376db0f2d6daab6e6fc5ea8fa10b040d0dce334ee91d8cfa6db9648df907b199bb11b2b5c41c67d72b760c404b0451f70fccf +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 49e9709810d9f3fef159e5cb45211453e7a94878dfdece19af839b89c0e43b226d7cfd46859963c7ccc753350e74c2501131474e3b8e0edcda18583b0392ee15f1dedcb7144000fc7fa7eabcbc83d12983d2ade477b4687d75b723c1a98a951d21b2e8ed95735aaec77e00de288d16422fd259c665a08a34331cb99299ac11e2 +A = 4e550ba2fc2a44452f068860ce2a59230738a7a15f5de0aeb4d15bda8c61ee3003568dc5971e48343d402112d7a86860a7f08f5cdc0de21fb1aa064ee5df26fa23839b5ff6adaf64a4a18c07efb3582c2fc9612d2208fe99f8a +B = 16f31365545772f276d8ac952506bf4033a884edf1ce583a63d8d9f6809e29d9cce3b3d227f839e6c09b459951465ab4570d2d36127c0f677fc0a63975801896f2fd17887ca16ff7f265e2e7adab1516ce56ee1ee9de1 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 89ca20a3fa109a65b9449edcc729fe97ed45a9bd69eeb31d4a566ec1787b24cb7a2c25b3f89b36fef1cb3645b17c69ac8ae243cdba35e17f5738b35278478bcc391add0b5ec42db9ec1eeffa63a3ecd2ac0338db57cde9d2eb9ca4bb1df84f1a62245c4e585c4f20f26c98fa1957df34409a99a18bb442ac14f0bd309266a35a +A = 1fd8a096be30e4435ce8cc604ded337a3d9d2fbc9666d1893c38546c4e155315b536d1bc323c1e7be162bb0fcd58440915b053ca0d0896e99265241f2afd46605a2a7486e1394a07b23f3382cd190e943e596c747b6529b04bdb13 +B = -a3960a51af5ecaaa70146ce55d639005e9b6b9b58592441d5876fa71470ade6d1e2cdde17bb80532551bee0dbbb71a0cb24dc8a129c1f6e28920055d87e9c66be27fc4b425737f36add7d72e39bc83aabee5534637e2e22 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 654d9c55d4a62976670a5ecac3a6165734a65f1edcc1ca81a8c444dbc98c3409ac8c4f6fbb92f122045fef8b7971a276c7dc4eaba21f7be7495394053d4f9bb14b63fc02c8a55ad8fa9bb9aa26aca5c47968ea1b7646ec606f53606d5529ded83639984683b8a020e8ded4b2d9f668ceadeaa8160245b36a819db14e58cf2bf1 +A = -67abdbc70db183b8c25b0664805ada269922556bf15aa80a47d31f215e216673b8d59edfa10a74f3f09d066055c3b9abd5434ce95eba91dd51576adcfbc7e2556df95fd6642a3b7e0486a635ed5699eb7fb285589c887c8659a2b7db +B = 6ad3e854ea57aafb8980f1e99ab9cda24f183dbbc513e1fc92d4e239077816843f47927bac28e41d3f31c9ef134b72c09dcf14e2e9677a430d43002ae70c577d9958341243030fe58a800a068d6b01fd377e61844f0d434dfd +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 74bb23f7b0cde7924ee52e58bc0680f151e6898cc1bd4a2eaaa05faf218b419a19ebf85b0219f924a26002f9251b83506684af659e5b680e05138432ba227977f38a479ad9d1f3cf68a86ea214645fc4bd1a032f995307e9c9ee432e816fd852655ef20214e24522c17799ef41d1eebc6e097b9792757f7fc43124c609ef9696 +A = -19d3e6fd6de9092cbea55d65154208a0c93ae409c3ee35569cf774b8c8b7b1c9dfdd52e9f408e14ea3153073ed8d92746474e524a903a45a882fe46af92b033f2c41eacdd7e3c1ff661dcc5349ed6bd1aa845eb1762f27593708aa185c7 +B = -3d466d29e8c0008ee6f402551e3d62fe044787bc9f243db9252ea97da9bb75f5be416def97f13cbb008fee77f2eeda672bccce1f36fbcd26e1f1299619535da0a3fa3ffa0c6fee82a494efd7407cc770cf46ed1b8b143f42790a2 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 197eaeb8221b431d5fed3d701a175abc146a9fedf8060e8e611a54f8da2fb27d2fee4539ddce1f3481e6a64435f09a2d5012540d6069900a332461471b22192fb87b63221c7822d3f2fcc35cc38feb6b3e49b5b0fceb52b0ccbdb4e1fd7b0f3eef3d582a6ae194c249ebc52f215b568712b3e50bb8e01c64b114955ebac2da48 +A = 7bd216d0acd4ee392258a7341cd56bfb0968492fe75da0c9d935713a6ac883525a4a520b5b7940b05e3f5e0c40372cb11b7ca193e93f0d3883fe5840e66346aff0f38829322bbc1f0a0e63ce5e528ba5b13596ad7ca19d20b2a7c9bea4214 +B = 1ed4805e53630b886cd733e5281f6d2699b3c79da615f4056120165cc63858ed2ddfcfd0af0c5fc54662aad90f26c55dcf70a30d04ce05bdf61028730b900587716e690dc0c6e02419622ab8c115078b92315e7c7a5ffe38c4a404a2 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 40f69f2d1660eeb6e1840164817621dc95eb930875333bc3f62a644ca5910c1080505de0d54fc9fb6404a61bb2c03b3981e558abf9e86f2047c3928599b529ef3d91c7ccd13c1d69431fb9ea3f02b001427cf519d9fd8182219ad904f47b3785fa05ed24cb0ceafd537311633a2e26c27e61be92eefb28a49d7f583cb6e072c2 +A = 155fb75044fc54a6ba6c46972e2f97531861b8d6afbc358db456bac33a44bb0545deea2fc83023c08b7be473eb68accf5b65b3c5d6af88bc6d8ce722c80d5d1527e475905226b01ab9d7b5a6557250cf8be935339db330df2dff92f2e88e80da +B = -8c6016966a2cdea4b2d8625aa367e1d079638870f1b61e6b3c3a1e6281ece41018d2ce93684d1f0088d021107fb595390664c11435c6c0a7b93c2c6895217a89c469a37d3250dfa457b928ba6119b5c9ca5f2d47b36e60e4325bcb4383 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 9b9e6e1727326fea099eeb008a36539f3d47e3882b77d6089032b99c6cd36ad79fa75b7c19d1509b3ff022ef781b6a8c16fa6881f9ee2c4e00a4dbc93a49829622f4ce6ba9c55639656102d81167ab8a5e1fcf14d71caa60be732f1fbc71250256520c7c5a4579c3fdafc39356a2bbf2c7ecc526dacc0293c7578424c939ab6e +A = -54cc11ea9806ef27911ba721f19e2ccb111045711d301863792f0cfac798758f0a29111e3a0f84d294a79721067f50858767abf507cc10ec9ea3eb27a91f06e7f6b7b4be7001b548cb7fb734166bad6739935081bdf6d35d58ef56180d377e5fda +B = 7263e8b9a6f5387f44c55af64b64160efe97ec8a8159e723ca8977bc17c861e22041ea227c9c9bb467faaacfe352b03cc620eceecabb6db2db108b49c69752bd0cc61a5e998ac2f404ad052a51286ccbcfaa214ea8ec14cd9a2a6db56c3d9 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a18a7498ac9194f600cea3d66615595c27a3efa7ea196ba12a80b5f608f85fa72afc366d23f5ca98452dd190b8f86031a9dc097f94a217b29fa676a6042a3aed2355cc8e767d464a8adb888491c8cb82dbec8f117f57c4a07b41e7e6f6cbd7dc25418603b1d1d865dd2140a649c9d52019ef39dbb6809d1b28b3c1ae64fc6813 +A = -1b663403c73e4a9003467ed12766f16354f79073ce89b66066857d19f3b42791eb360004d23e02874254bc6db54662717739eced153944c4776f334576746c5c4145b21a23caa2b2a137498554c7b749efcaf3393c5457b2bb87ee2ca3bef5f191107 +B = -21d12aad97a5c6e639a2ea0a82b1292aebd418567718014465a22b9ac5c8c927963a2a4530c41d5a7a6c14805e56a7092c8716e4767b54a393d8552c5d3c366b39fb3b8667c60e6075e9293bc938e407c53afdd1174843b76aed187f56bb4be5 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 1983576ed73d4d87d8b94cd3f70c149c0273e966176b85fbbbb7b3202e2c843bf1f8f4546ad7a4916ea4c731a22bd337b6177fcd2da8bd301f3af9bdcad800449b57986e7cbcbc7eb313d6512b2894c0cbb6cd753a870860a49d6a682c20b5e883b8c4839b3321aede51bfc42bca163a924191feaf05e196d8dcb7fdd9941a60 +A = 576759af0f02406e8dafa330babe9473d9d970bf371ceab30d2f98f4470f669e042e1708e2677d52cb9f99deb9b53f30727d16c389bb63e71e923475314b615762c7612269b5ad7bcb5108068bb5159cb8dbb8d08de2bd4fa4d9db6cf6e3f5997b9b416 +B = 1a4e34794747cf4aa626e964b839ac497b1357090ff63088f9fd4399312df894e41b395d17b8ca1806baec6115b1476912ca9c4309f00a46d5f7a52c8f640075422af06d6d6d796359132f4955072ce90e61b40c992a155b2bc31c262e753aa7d00 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 3448648ff9f7425937b6faa54551ce14dd15566e5d41b2bdb1a8db62037459235a5b9546d289cc2295b0ed584fab2e1a798bc25a0c114238f61ad3381a5b441cb67f92cbf66007c980db3351adb9cfd2cfc769b5b9b0bd1701425ce1ee8d4b9f438ce1207fa850aaa1d3d1f970aef874c2b2499a150d29c2ceb7bac375009b77 +A = 1fb54cec882c274b98913e76342a9b8e631bf1d381fd8a4f7e0eaef475642ab3f5da70ca2e38741bd0182a959e5e985f1e0e7d737beb8c725c9b5ea22f7ec25b6e564809601e8405a5b1362e7792791f55ab64a57c03a99a8518d7f65feb0e21be619a6a95 +B = -8180d172d3afe00e0423245f47591d5f750f20d2cedd8ba6ab6f9aa24f74498a96c9001a0124c4f98dbd402b63e71eaa3a7af8b0d2fa417fb1d45f64e10030232b9155169153496aa202745a432e547002954eedda7cc9c1ca76811bd902b192f1a1d +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = ae0fd585408a99643271eef575285a6261a4c4a92c1956b1ab436d3cacc8d4cffc07044e57b357ffa43bfa9aaea57824319579c5c3e2fe4dd48bc818178beb5fc1ed60afa08828657d00bb88894c975378b1dfb452a5b88fc3c1d81099644a998a47a497c8a2b12c444fd2a088f47576b7f4fa40f34a208fbc3348ce33e59150 +A = -7dc7dfb753c0bc3ab4d07d5aa78664a7f57d64be4d4780ea81e3efc967fbf1bd1390248bbe259da32108ad96bd8b39f2c9f118bfdc96bd06147f812af831288bb687e4e1742dcd1dbf2b7adc41afa28d07dfb8df8bb2da5359e66330f5c65964096a96b31dd8 +B = 756f3e407a3ae698f103fa37759e90554f38378a9b8eb38581e0970ec8f9c00f8392612c61aca5fd37d1063b78c19e3109f35c0684ce523c634190b3164ef06959cc42e2b77e1bb2fd50eb59c3dccdb6090beb809ecb0ca30457a5c5948328eb218e219d +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a2aa4550e855623a8ed488bb63db8fa4ac374c1ae953781aac590f78a364fc33380ca2806445fca5bb9ca2fc7ec4db5819dcd5769e3b746286c49a7c80149e7fe276d095929e2cac6ae57e8102f7d4c96261ca44cb6f1601f429528495b6c3169e15f9babc5be696074d45559d5abdac42393094c450d6a4a45bbf60ed7847da +A = -16d0aea9c752b2e6e4e13f7ab1f0a2c1776874967b0dfeeef7e00f8d9edd1e11d2aa702be45fffc284c47811c51dcee184a134b8f6d1874026eb51e2ec80c94837af4602cac3efde556ebfff578fcc56c00de99a43638ab68387ec087ee269ca64233eb5b1762ae +B = -3c6b60b0ce4b13a5d6d9ccd67c76ec6b71b94ea7205e408eea099c7ced2f3a462954741d353d0af850b10ffede8ce0bf80b6893288413674504829793d7ae0cba53b163e3f26cd99beb0a9ad540f6d2cd5097beac604b1694a9a2f4c48b28338f9d6a63e75b +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8a1a8fcb68c53846b3edae33ec070ef5cdcc1346ab3a98a116344e6d2810e2e3f60f0fe435fe7ff257c7ef4c122b3c34c776f4912a9621b6949308e2cfe2e0827536c7464371ce804bd7cac1d76c5bf8b4a6fd4ed56b65434c3fcf0ac7be543fe2d09ac01c564d7b9b463740dcdfa9068d4d8e33f29297ab452e6ec55c263de +A = 7c4878334ccd9e20cb11a643b206626ea5d0b20973f18535cd8f0fc2f0325a67d3558e4cc9cceed0d88c6d2215c220b8d0ce230fd701502b02081e3f6548e58e02bc2e79e4991f8ef188a84b0a367758b4e534b72cd87de7f82a26de14fafd162a50b359574812cda +B = 117d8b1d2a3e2049e6edbb9494c68a97145ac3e658aeaa05e8ecec4b090d5f467cde34e05fa7f5fbfa32f1d9dad70955f22130c358468eb371555fdf57a40e1df398c166a22a9df2e1f4e18590b00856b4f880f6629f1a4296056dc66a29b6f0f25490c6a8209b +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 2cd3de06953acb87b773b8bb28172b24adb283d6adada676f5f4548990827635c51506c85670767828dc5b4b91b45a7ab89a700d70bdba4e0355da32b52c173305767721d18dd2cb6c55f890611e7abc854277a453c7500efc4cd4fb8e6c9bb7a73fe5c77045e715fd35d415b3496f7463ec902cbdc18f9f6f67c33fd78c3210 +A = 1a20ad042f46330df937b879c72ef00dcf39fb85b59186b8e7a9d40723288677ff6ab2b9bce95f34f2de37887c8a9cdcaf231254bd00c7e25b6042695d7dfc05a11765120d1dbce29dc74f35aa1492ba0c5ee65114d9a246b57dcc2eb2ea4a310be98383fb934121db20 +B = -f8ec67323cff9d53499ceb3afd44b28f0538c39dae8c965ea27d645b430c2f8a4965eadc8ed864f2549eb636ec558419be71f986f4c5783d0dd5253738b876d9034735bd13b18fc670438387f84848308d9357ec2aa4f6a453bdd36ff08d54a6800bb41df416b17d +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 1aebe2bc35eb2e449bda63513b1bfb55988cc8e6ec8b3c8fed5ce4dcf53b95f1b438c41e3b2348412b35e1f734edba30273935b03d16efaede429960442a01849c352349e23b4af88de4d01e9ddb53ae900418d49a84b7fadd2669261a574557c4fbd782f8e8f400895f6a6c9679b72983ce01bcfdb641f5067c94694e9eb80 +A = -5f97994c39265b5389526e3847876a10aa3699e3c3762a127d1a9f892180cce68ca6139a6f71b235da26c287bd3e1aaa1436746d983c23c3105c33ed2e06baa1e880f1744d81a80b98ee1f16220940d721a92118a9b949d4da7d1477db8f5b357b3ceb7df34eb5f62078cf +B = 4bb4f8f4f4c8e63238e8774ed61a7eeafb3fe9a6e19cffa648defe82f4846e3378c892d223957564fcce79596151658a726031a6921cdca0adf0f5325d858c048a6b94312ebfd19b803eefcb93bbfaaddef120ec3b8c366b6d978524d5c74218da77e4c3b5ebbc66cf8 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5d64678a32c163874d1c81824d628a1051bce3b55c37055acc47a8630d3fee648df5d319e50b4c56f465bbf696433409b89c07e442425d3018a059ec757d77b3a40d516ca3148010036b003721ec9c999665915a3c442d95ec3c01c232feb201be08c88fa3c6b0769e3da30f1d73b66f98e31f4306bf4e23de78e74743b224ab +A = -178d81e419f0473c426e24428caf25d61b648bbf963f7fb753ae15e5ea3706b53b00bfc8fe917ac9fd6c7096518584566ff71e6d35197f9aa25107a235678cf9ff8ae1501c1d5a15d2a27d39d066e169745e1e8c808209bcede0d732423d0c9cfbea322ba3201ebefc5315c0d +B = -27ed464895b65d9518923fde5caaac0c72aad0d1b38fcb7827d6ad4e0c8dc09e119b8b98183f0ef8d5d1133f3f108e951caee035bed0d48bbeee6d1ddbff5864bc192b84eb8a500cefd223972ed51c7f720d1736646825f95f2f10ce6ad47a267bdd8c80f65d644df158d7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 52dfb6bcbbc5cff46942d76ba45301cbff76e9b894703a6a7fd1af29d615336372d147c3932589affe5c6533f28d3e6a57ce2d3cd7448bbd81e09a13266ea31630cf044f654b87ec3fa3294eb65873964110fd42d86e78d128bead5f117cac98145051552cc3a86c193d738b973f866d068a8994a49df3fc7c7314fbd9805e80 +A = 797c67ebdc083f3c8b3ddf9847b7f3c2a39e35ce2119f746ec87fd5d86671d8fcf2b4f6d440c43e93f45019032e629879799eb58adea729d43d2e40ede6485143bd35979609a12faae7e4393879c40c0511c886c66a24454e4f9912bea944eaa417c9942f09ddfb227feb14e4b4 +B = 1a599d1cd0ab3614f50b71b93c999942bd3d4cbfe7900122d5083151c71d9e0c299bd927095c5c3291418424a7c12947389bd4e0a3c2fdf67b3f512094ec0ce5b52695e527de2b3804dca2edaeb1ea4b487911053272ea926cf2fb3386dc4b1dc268b808bbcf4eaedd21168ca +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 99bb9082e4537426c61f3b813f8c97675c44ba9ca418960ca6e2464cf61ad4eabb01ba00798463567ed3d829d3f14201c740f19fca623b1e9b57b534a65df0f070a2130489afae89b91003cee432fab11426c4d13b7721e6f9db1bbaf0adc0064b33e4b9f4b795511a0744b52f93e3db7bc9c0a991e4e122c463ff344fe14cba +A = 187a8144a0045a92dcad94f0bae7285309ec8fac7dc864b08914e5a4dc3b1a6bb9212161a18c22682ace16a4bf3c03dbaef088b09844902a3255fd6adc0b7c6397dda86d6ab67204d8061c36ca20fd4bb348202037b249f6c110c31580148db46dc5b1bfffa38a683a27054c35326b +B = -e93ff16817b725016279a32dac247961ae9bb00af890fb49c4fd8cf5e815cf98b58cfa1e3735095e6034c9a2f2b5d8030ab30e2271abb45b347d755cd9ab5ab5ce37950380cb306bbec42b6b8056793a0955bcaeb23e2d6a9548684030566eca2d34c458f224c8e337cb8e3c252 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 631f53d02c031f592b3dfaeed106160488c08e0672083ff195b22a2c0b006f11165a245acad6f35dfb15a871a9a2b45c544111f71f86c920b42fdb6551e56c55199e6173c00e27c9f47256349a80236bcfd3acd1730f823031ff9ef594725cb9429ea183a7fb2e03124ebdd98d435313e43819d995c4fe81fdd4ba718aeade94 +A = -72e20f1aa2b5f2c4218fb9e11ced3f45a218f4c83a2017d97d0cfbbf227c9082cd43f939c8909e52c8795cfaa75d80392d3649dd85ddc35bf1cc54ba389bed9e9dcf867da1c05eda080274beb6b868b54fc85e12ae127dcbfffeb043f9d59333d0ab3374c24971e1bc7269450b418c8b +B = 61cb021a3a957703d14061c21d3b0fc19598e19a17df9d6f2418c76d4d37b3f62bd4037aeeb1eda37f83df44c440f5e49924cc72ec5b153856c6b621350ec89d98859d9d1ec7ac4f0c418c6599674322e7d618c5ca588d5a873d5af356d4771c6cd375f5dbbbc69f50b982b8c4d1ec +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4654a62d9491f28599a976288cd2068d8e3228da12f645413a92f482efc66d1737495cd4a4c733f147eb5414a2ef6266a116ce264491a3463c9df1b030d83b315f76f3bef8cbccb5c538478a65092547b91e991e6be91ce4549c3a6e34aa7b466e63eb3b88054f6714083695c616a078ed54e1ae46e00f3593af845fcd0ff51a +A = -1a342c154aad619e567fd32e7053aef8d98335a4fa0e35bf06acd7998c43d821de1076dc1fb67dfa1156d7ff30203ec736384a9aa7f5f08cfb302eb3a2a7179b2664094c2cc0df73fa05bf2af24a62b8e394fc76014dd83b434df26f8a67a624884a0b9b4f08f33e9828ae64f5d0c8cdc2b +B = -2c57e15889c3dc9c94361c17585d506933a72fa954ce44dda9f5e33408552ebf49cae87bd0be35197f887fc6c7deca1452a4345eb67d19bd2e7d3dcf651667a8900388e4d5ec71e9433e3b01d2b3d91bb94d0fc3c51c70793f978e4b5ef93a9c6356c0b2f7accb9e4eb457a2174b50dc6 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 6124d9ce4de2880ae3811836235d6d89a1a4b710f1d5a517153ed7729dfb5b56b0ac10a4bbc811db9b26465f03cda355701f9f28c5257fe288743cc0789cc54a8661f46e36eec357580b00a84f1d4c8e3d689bbc18242f1cac30a87cb7a47ea06f80d7c5633cde4c8cd8a1a7e27acdc3a2aacd608cce9e2efe7864d41a56ceb8 +A = 7b48a9663d914e0225d7275e965d866ee6649d7267474d5336d28d54027ffe8572f4aa26230dc7abe9957d211e6c2c8f3185cae962b878cfdfaaf6cfe32058c299247f372ae170a1f7cf71380787f6e90995da9ca5a4be8ab1ddfa8e6e5dc65b6f168b9b8e29e0257e0eec853a6e1911b1afa +B = 1fc4dc77f4a18d4406a4ba536e500aff68d133c6e7725717ae6537b527c6f40f93202a2292522fe7d04e0ef804d1a7013b04cd3d88462fba31534770b56d2e5672e8a6ec7a723186024c40b4717defd1433b9967bd692ef81d5d4e39ba10a3223d250ab6e71d5d253dd0a732ed386ad57e54 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 6443de73e1c826c90aa36fd7ec5d0c3324c42058b1c35d3adeda1685470d363732d23cceb08c3f973034c24fe65506bd33dc45d7d617a53048dcc103d3d1b4fd0534586c2fb7489ff5ffb98303bb068fc14b1bb6bb43f763dca2c891095e613bb7b6920163aa6cbce8cd93d9d39f4512b6e0b28d361ae11cf76037eab4cbc819 +A = 13f739846ed2c3aa0a1923168cbb46f4f0a2f3942ba57bfa5c426cb4d4b3d80d9530405a31bda329a1814c560d54defa3e03fc4f808606a598607783d539dbb1338d5bc0c2e272a7ff6ee6f93e1665d6f5a0ade30308fa047db086646c763106cb875e014e2c18ff8837e4d4d86861b85a5b7197 +B = -ba019333046f76325fa9f258006a7c10d27e89f6d482b95c79296c07a65b8e3bff4a9c9fa7e5d0038da129390ac851f8c0651dcf655a3d4164a731cd20a701895c12a906c732906038a8e459aaeb293fda21346964a6d53fa3e370ebf43c7ec8f66229405095c6a509d0fa15dcf45de8d0e901 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = d3a6fdf4a26993edd175de9a0f012e1eb15a5a1c4dd2741dfc6d0f9177cd5645508b8ab09c7fb34066ba893c38144c7f2ecadfc2b0d15728b407e5db4fcbbaf1871580426400433f14dceac43d28f03376e791b7ad01a112981f29ff4b66102305f0ecc4fd134c2cdc79a5e9d9f085bfcb7e6c187980e68b6c7639c12e8d200 +A = -464cb16fdd395e32fdc613c63ab4768f8cf72a5b74a0a5b0cc581ee4aad1972cd97db7966d3124e30c9a1c80d85c46da2d36eecd7c3bba5866f9eab4d0fa55b2d440a311654466432c681372a80a7896c9163c12314ac51f652aad68fd9012dc63fae6c7673c5da8faafcfa1b4ed5550f2baede5cc +B = 40389ba4d2f5fc152308c9e8a8c36258c770fb2d03e6189b96c4f8dee97ccbe426cc14595c8482e9e22486b61fc570f0e7aeddad2f4e3a480d4b75d14294a3b912928da5692043bd98ab88ece87a9bbd973ec82f990c0ae6091245318c2810187d69c38fa80e835300ed06c0723fe475f3fb22de6 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8a0f9eff3a210912828fd7b5f2d72479cc9ccdcfd3e8d21739e301de02dd5c257c7ce4bee2def06c9d0c90d5a86bc45fa9f31e456d353775916b3d5684759e4500f99ca1f91f6767a5e2f4b735ae4b756d56c358a06447fa2c2ccf0ce667be4ed143e9e1dc627a561d92ae53a62477270a7944482cbf671138bd2a85fce92b08 +A = -1da555639228fc6ead68049d836d60a4927ee77472fa0ffd3c787d55b6067012560f5b1c2ef8bbf6119345dc6419444c675c1c9cd50602a93ba3718a5b3e1a30bc108d796998b24474cdad19bc2960b295fee97e03f2ca7589a3daf35bd28eb37a67b5d2cb35a30998d5f8622bd7e6b7d3fddd1ae9670 +B = -291fea1ae6dd1c66c62ae3a3d22904f4b4adb2a48cb795d50074095345d661a033f67b20c5d7231236dab871892deaa9458c235c342bc81457cca3f014a75f5124ff4da005dcc1108e75527528e5cc9c051a97fc6cd202bb9166f9e72e366bdd77c965a70592e5684fcaaf2e03421a2025ca190fe158 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 50f4d25875150bab63e4162265a632109d6b4743f9d6b55306858034732a4895ffb3720286acceff287c38320ee9945dcd0a1bbe5ae1456b7f36337cb7d22b679a6821a450765471257d52b6ab7d59a763e75e9e64581a93aa54761f6a760866d6baf186cdf4ad2b1a6af26a3e76cdc261d1f07b0a7122c8ffdef595812e7208 +A = 78a1609a7f08c93c9bf9090ca7c93459aef815719b5dde5f217567a9f68ceca05594f6ab17a4666ce1c0c4434e0f4f38ca1f33e501d6958a10da47211cc011da219d4373d2bec4b7c6477b1ab3b00b6c45279212db39bcc11d1e7ba49916c4271adca7eea531adad509ae119348f374ef1203c5af8bc019 +B = 152b46095d3f8db5e6e1a9e3f35c085da00e52764b261c3aa775ecfcd38572d2e86bab2f4bf29c2de4fd2fb6f35f66e8685714634e1be980773526bdbf9c43b1335c5d59f4dffe1a1fe2495ff9b7a3fae3e53e7c3208968e1ad1dd1dc8cf2e2415cc76dfe5df9e2e1eb63f7c7687d539706502d56247728 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5a3ad8d6f1b0763b77f5d40169ff0013de638b459e401f50f4cfb505565c8a4465e28ca1bf988071701dbf52ac456e01e170788ebd2b7cccb50dbfe1a65a89a8aee18b3c11986c9d6e6571f964f376f322e10a1ddd9310bbb40f14b0680385c40975aba43153970237c535c6b0e2cbf6bec918a8fa26cb2f69e98d77215c23a6 +A = 1d5c14b0b51cf31e9d97b7c49cd26097d40454978663f8a74095fcbf9c63e533708befb1a467f94cf599a41220ce13493a273fc30c49275412c5205db712d5e1832b39e65c150c3a4b251e2aab853e4ecb4f00ee5ce6982ef9215775a33565bde3ddbd932665aae506941d3ee31b3f9e4ffc0651f1fb4a5c6d +B = -93cae5dd84584a2a3d88028d6d4cec4146cc5e350b4d92c52ba2393ab69fc1dba96e244f98e2f93f31230904169641aff30dfbdd3dc5fb1f3489d63aae1efd29335345a79ded546e42f2ee4a70ed932699fad17a771ba65fe6e689664bdd1135219aaa905c962d39531eba3e82c3425c24041e17858cbbcf2 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 61211c706730a1b98c628b3c8cb070a42e2ccf9fc6302bb1c2960fb165087f210e9d93416ad9fa21634a05dd0723cc23b8d2a846ab7c3bc402999138433725e737102094db5792249b4b5b1514a416b80c804ecfb04653c5ab18b0a34d8777f6c2955ac66fef62c9ec2819f0e3c075920f951f86b32e02bc43239d9218580067 +A = -46c8c68f492d8f7ac7834f89bc76098146432c59b3301d4eb70d9861a6e24c7c9073f910108c7b35538a79de10640291b54e5755359baf47482b97af56475211573576e9412ee017dcf961a090a6ffb5cd995992ab68e3fe60b6186f7595bd9b8acf8695c4f7359cb2ac709f032fb993d16a74822b4935536453 +B = 46953f424d988fd20700ea08880e7e09ac22d60cfc294bd4aefe637408a3cacfcd0ea6822a679b68b665d6bebed3506d25edc83cc7154b83e22953f9d91157cebd219cd5177fede28c63a15710d0f92bd9e542a7586855bbe57a94c520408fc920b3f8d65b194af2b2a580c90db1cdb27ec26ba929de4573c6eb +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 50a063fff02f2cdc68edccc23976f4b3db99641073c85709626292b9475b9a988fb8509a6223f0a517dbae0cf7cd39dcf1e8ae75196d9f5008c661d8b5153cbdb9520c71068e4719820bffda4c393032edabacf99339e0cbafddb6042ef887b8c498e87e16b62417934015172e63e7457242b864a47aa10e203f47320f03c0e5 +A = -1740e8be7b4775725516d37ba643fc64203f3a61e6b0164d112af56666ad97afb0059c2c4981fa81d72264f8669db4e50e11865907655b1f669c88f5935cacf1b12c1db63cc84507af12cf0210f990994055d04d93f148f213e3d4fdcfe9dc42117c059897697914e3e3fa8fdbf0eebbbb9c3b9fdaa7efa0c9d5c93 +B = -226308f8fbb35b5f9d129c0f6a2bd3e5c272a408bf32020905acc6d02d7e506191e76a3a2ac47cf7a63e6306b256f489ca5cdf76c7c3eede175ee4a7acedf922955e92599647b69d463cc14f2b178b88cd471b8a1c1512caa66b6d5fd8840b98b8d070e6593136e98cce9643e006b714388768920a79944be36624f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 747cba0d1cde75dfcc0b2af9072c5027986b3e3917845870c73c452858ba21d6d1615eb71ae1b5a03ca44e22845d5432b368541b52a4bb02498668e8b99dfa2eb90ec1948d90564e6ebc388ee9816e329e1d8da0d3e2b12d901d47e22e8a1fabc37408be0f89e7a4ab0f30a03f7e2ed817006809e69c21104d0efe548165f64c +A = 5fa76e37aaf0eb3d34d4f4c590e02b6c63fc62b1d4c9e172cb0dd82409df87ecb43a1680a2764f62d13a5e919db2db08feaf98d5cb92a859dd42bca1047ff57b8fe5974fb3ac11ba2c0d8e2203750f30650db4b2cbd31d07fe18c4df84a0dfdb30f9e528932c097e89d8f8be6ff029dd970a7d2c2551529455b9131e7 +B = 111199f91b3749f8cecfe90e9b9b6951472cb701beb39d63068c064cbb2a1e1d30736026f781836a52ad0d828be6c20303c6c0bd03ad664dbf6044a5bfb67fc20a049fd37c62ab0795d836487b883768ef7c8f427eb98e5ab6621fece77b4955822f8efd190c417ced398c221215b50e9532a869eceeb605fa1c936554 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 646cdb3ed472a7b4599f02329054846a8da173000eee7533240ade4dba82ee3d7a6a92baa3783c19dbd3f76fce6b5bdd83f1f229b1c71a6faa18602e368f1b0b9f8c62bd8c854844af85c2081924c9a153e27853b2a48147950fb614028e090e2198e613631c95e565c2b9b64a43237fd4052089f9d1dd2c00525dd35fa946ca +A = 1c8438247c0ca376f508ccef7933724df512f9e0877596f7f4ea73dcd824809bbc472749833b537eec01ab23656e9758da22ab8a4aaca1aab3fe8d2cffa6672ca0c44ac029c2ca6c3e71780c28c31b5f154c8dee782f6ba009a69d83b1a3a03a2d6275bb8bc3932a1170470fb7e405ae081f4770b535edf49f73a12ba589 +B = -e365c8edbca8dcc4cc11986a5a901e4ed0adbe89b0ab70a53aaf5821862432a1320cf1850b515177b630e12692cb025e3aa43e9acee0d8ad5e48bb15e9a3f34cbfd39d285127b52dde58751f572ae68ad98692899ab12d35e33652c4426ec60c5029e51f7e32ec3d2031032aa7b6b2b63f84fb0023c81d031773f3652cd6 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 7a3e22f4a3f7ae7512ed73a07abb5ce291bc90bad507a5ccc0c17185804b9d231b0ae2e72bf270dbd60170f34b240f716529a449abea0b3d98ea2890a4ce3d9e2214819aefd070e00201e9f271de925c4ba59651e55174c97a13a30197e46997c6c2b152548111aa98df120a617c54b71f8eb8b0c8b4dbd5251f5509fdb8a1a8 +A = -78a99d206b4f095847e9a21de273aa6c47034c9afd4c081a8e93c2d75f4ae5b090921ff5108c863785c413e2f7b4a361506fb66b7561b8b1c5cd537e90274bddaa4e91ce74ad81c6dfbfe1a34a631dbe455d74ed9d041a9183da3bc469bdb214d2ffe893f89c3ae30f8ab99c3aac4d2fe864b891fbf4f537745fddcc60504e +B = 5c41274e9590c1ea44c113ce505931758f2cef80ba3b10440941ec9aa2ac984b29868bece2922eaa225555dde84a8334f1caede99091165151a39538e5b7390e81df757f521236314239c213e9b874e396a022f04629c09bfaf929a0e9fe0b0c7386b0541446f6a2570491067f64e662d8611c4fd6d1c78a9f3ae69f34d14fc +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 7fd27b6549494c9bc860146a3e8ceee785ca03faa94b0ce0a964844e7871e813414cf3f111da49fed1ede5e71e5539f34173d41f9a17ed129016bb9b04c86487f5def9fe350fd4dffc67b6e181e3cb26378ea15ff9b9ebdf1fc86c072c82ecd8bcdc241301daf1b774af5f90f37e45e6126c5da7dd3753a1e5b366038af6ae31 +A = -1930548d105661dc25a5ee303b61b559c4bc1f2e28b2c40cf3e25f98dfe01a7dcca0f3dead6463b55a5b2e0440a651cc9e08e125535e081c742bb3b2f8955ae897909cfca683a4822896d8a4a7073c29a80571445c6a0d53d2efe4a30a79d2fb5d08c0f95b735a1cab17ba40d71b054c9270ba6bc870e58591fb1bf9dc9b7ee8f +B = -3e2a4c1509494f94406e3843c9446edaf0a6060144637234c6d9ce84d70fac54ed163d77d210bf557bbea0404922c8aebec67a0475a3c7b74bfa2f226403ce987c705c712bb8eb0934c2b390a173c3836378fe71a6939e48d187b27cc7236ac115309fbeabd9ffd0396fb7fcd6d46a1dc683606c757ddc3212f5d2ff3f2e450fc7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 2078bb5c82a394c30a287aedcfdc5271eb3246be05954181ae4f86ad2880ce674640ecd55c2ee3f4e89e2762139586516a28558481303e3071cc9ccb9a538f887553bf5726f3849fc41ab027fb1c680ce7dee3982587ec71b3760e5da6956d6894ad8c4526d8de953c0e681ecd44883a21f0abef1544fe601743efd3e5eadb8e +A = 40b4ba1e977825b7accb941fe0c0a49936a8a47429dfff53502fc0680d705b9fa0efe003eea3ff0b649998fdbae8d0831bea7f34159aa4c7add6bc7cd56fea97d25fb9a6a10f4572c26d792b76c18ada19b0ba06b6142c420dbb40d66be669b7c51d8cd2a5022fe1a8aef7b60965c0176eee69c32ca5023782c5410adc1b15dbdc7 +B = 1bb2f18d7c8d306bf80ae1901115c8dc3d286baf537b812ce06d6872b61e5bd44f3c53d7f31ca8461b3628b255f85338cc325856fda5a6248b7c476532c1bcdf9713dff9932a50e52a9441aff96092d3fb0fd76046a8d88288d0cd55741083a1bdb20fc6e9c20e82490273354bd826bfe001322dde9a15763f2c0e6ffd2cf60019aea +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = ef21dcee9eadceaeab13287d6e3c9741811f6ea9d5bd111799ae05260b1de2ffbc192818fa45dd7befc3baf6840e3b9d24cecbcb2cb1c3d653c4aec6531b941d926fb6692f548cf81526acd0b6b0289d70dd11ba50ca8de6e174f502eddf47e57440142c7f74f594a9abcb48ce1873df057b132ccce8b364de3edf411089d28 +A = 19d0109e0c47ad45f57b8bb8519265a4390534d2ea07f969d84ad33556518b6234d40d1631be3c3cce6d59b7be14750aed114008458f50a6a84ff75b4ee7e4b826ddcb2d2293842ed29e4e484260a92199c5c66367c402bdff0f1a8057127c6ffe452498bb352802e0005e6cb084663bcfa82783a3d72f3a2a341b8075983892e86756 +B = -81fce71491eda139ed996f6a289dde8635a3a257ad6756e844c768e66746011fd797658184fb44b0e3f3c5600c56238ac7687b5be42529d5c9b97c3ce10f3219e1e451bb2dfbbb44cae0828ef894eff3b52b8dba4c115c3b471984441045f2c2db426cf5f86949d5bb7662cd40bb3b3172a19ca3fb6858315d688f13c17550e700cd5dc +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8a5f90344071790373044193cc4fd92116248aacf05ce639b6aac4461ec3ccb0805ff9876ef44fa71088c295db14fc820f7ae2c0aeeffca055f8f7238c6c90db706d02f2cc43b4960abe3ca4b6dec8bba55327b958e75c60c5d1f43fcf9136f12481c267481a725eecc403a16aa6221346df680560ff316a63ec8b51dc37aad6 +A = -7a54e7ca04b9a22e2b986e72e634317ffa20f6f4ee90353d559db3f3c1bc6b3b92ac6b364f6c5929090373962b49b59cb5d87554387761164982955470cb45dd00c4a8982dbaae3a1ffe700e8903a4a8e4a21eff9d00fa496d475e0e1a205be267499dacecd31551f8a9d437f37dacfdf5a2754f0876a3e02509b78674e7ea2169c43f29 +B = 652001f073d63ddd526abc957bbb48ca74154c8f9698b988178b3313dcde9acbb19ea11a935184fcbcc31e0117d8d2ec695ac56b5a71614a12cf90f21c8882187428755b6a5f11c314ac8b952ced0f65db0987f0f87e20b82a811599f4160e65c7418af7f33604e7b8952b70581e3e02dafa025cecda970d04383ee552abc620dfb9c5df9a +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 67f903e0e5623258826b681506f3e94cc0b086e262bafaa1395294aefc9f6b6323410a44427010d5e8d8288993973ad9939199b85cf02ae0a09dfb69801536a3fa6af5ac373add7efd25ba5fee6d8f040e97056f9f6fbb45795c0bac94c51ffeaf496710b00bc9ddd8e445261d976168771060c9bd9d83838a84ee9428f59d6f +A = -19c695ee3a4ada840a7e3626e61047c5081867b15843ee9a6506ce45540d23ad25ff23b72f988bf26ab8b98363d9a2997773604f43fa732f59a4b16ddf3a45acdbc7976a1fce01b3dd55559c20acfbb7501730f794bc45fc09b1f035d60413bbcf32a83fd3c41599049a674f165ac5283c42aef213d777ae47eea960f7727f5758146efe5bf +B = -210697d47beb73f45207340a183a729a1e78d84bdde1c7d8f80bc84559c4aa4572ab0e6927ea175acc7a268d05616201cb235e610d1012500c8ba9351a37bd68b4ec42227bea55cef5ba7d12ffb180873ab9d33d09e6e969df99fca728dc12dda6903169acbad38388fa9b001edb09056a2ee2aecfab0468822bca14a4bcdd3a4122290ec5ce1 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5fbaff0ffcfb2330283fe59611ef51cf045bc2690e31f2ad3265046fedaa990b5d5060b3c38f17bbe8b2696e527fd77ead8650d329c2e0c1f3b2f5bec4dd85641022f3e0ae6f66ce98cde1a785bb52eca796ae45c33142e8264621ab447cafe988de926544e1a7036710128c42fe8b574f7ad69d830894237d95a55d1bc7f5ec +A = 482db04e35f9fc1d87b42bc5efe25a049ed924f816e1b0f9c8ebe34bc771e67e26d6057563fd5d5320681e1207c0b0f4b7df547cd6d5be6a2e0f2bfb088f990b0303d0ef263cf45681e0e9a1147c29f2ca5251faa633ca53f6e0b109ba69bbe20c58a76a22789243d1acf128dcc936602e832a20a2bfbfedf963bc1027650f483814d7f5e6905 +B = 105aaf563d4c1d436c6a4552770a527776f40bbb844b7701313c5ada95180160e7cd4b7175ddb943e5a22c910585dfc184b52935f06b12c84b6431395f28af2eb9ccfa66b2ee8f40fd44d753c6a83d67a6f3fe3658fecc7fb2f4a8f357c5d244422e48a33d0e2971059695a59d0d39b235d5194e919facbae7623ffc92d771532b6b0cf771912c24 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a9d204c1a497f350fa1300cbaf682c947eaeba8b3aa0450c1db9120852a2edd2a0249dedef3b3746298ee42834d869e9f765ce987a2aa4712a1f35ed10d0f7ba9cdef938b073c3a526e5bf45f3510c94ff1fb84bc77b08e2aa50f5cc75e2f4da37a8a711f8aed5e92f7e486877229cb4ff2a4d0755029972323c0b51a14fd1e5 +A = 13fd3d7cc9d6d6821d2f2b1c40c8e070bfa85b994ee8f3e0baab544dc71328a1a57b7ee57392ab6d24bd85f9ea0f2a312148fc4f4b22c589e9a265d97e73c7a5b420bee180409ec179c438a67abf37eba61ac76197f3c9ea5edf2d4b8aab91e9bb1a432ef1f214c043664a51ceed1f2854880dd458ca253f09d6f6acafafec310774a672d07147b1 +B = -8c90ecd56d6c7cb129d1c9c26e94cf919c5747450542cab52281d11d8fbfcf9ea797b29588340d146cc40e77dce007b68c0c24356d4b75513b75eccbef6e22a5b88417cb6c516578d17d871e7d0957c09795f9a0f19b811db75d61c27e1827fa2773846857fec020f98444e307d3e52af501114b962ea705cb0cdf815109054abd00810dcc270d7bd3 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 57aef35a3f5388c810f576dbc30d4e4e5a39248b319b7766311157179d8bc1d7ef019cdd8c2c0175a8424abe7b33565afc0128724fa38f0900140b6f96bda2e78d7c803124cec8c2f2d6649afde4030c76cd33394fb386342d1ce97a4ecd180872134fd4e22667a687915bb4fda21f7e0bc9100ed8cd3a6668ed3a235d7b15a8 +A = -673bb11795d9d20a1e4ce8ae71d041705990463964505befce5949f895fa31c92d53f91fbc110df4e789b3f3f01f184c55df92927b8b680cc92864466ce5590ed2e98901cfb78b32ea79bf68b57a14cddb53209e08a7f430fee23f4a1475fd2640a515f8b609e98c760b4301747ecb61f1e6209b07455f1c8a7bb4e20c269e17937f39c6a2fb7b2990 +B = 46beea6005cf96a2acb16f37e357bc8975f4dad502fc3aefb4666344dde456c0ee7ea43ec493b6aecbc7aecc7d4cd107aa09e874ff564f5d59d7e12047b048c1da1faea36a7e2d02d0567bc4db41b54a75110626d13597db698fffd577a5810286ea8bf50625296ee8070419345fa269a354ca2eb47fa3108387f6a4b2c0ea3e779908a14469106eefc14 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5cdb7c451b2950c9d87638857407276959142958b06241b2010a9f93625f9106f065798f79ce5c534b9e5a31fbcbfc63cd200fc1cf10217096aa0194acb9043ccf7ced30d9f0bf66e0dfe27ee2ecc40bcd8de66fe2ed6f8cb0d874ff7b5fe71951412731fe4e19c34bee64c9312577b9e7b2ac08ed15aea753a6cd3e286192ec +A = -1eee9d5d3854db52f9b43698e05d6a0f1d1f8df5f32884a775b25110309c46ec5c7e112eb64b2d7f948868bb9670068779b0a78bfc7e17860ee02692ec6790222b4384b9bd7db5abf29c46261c10d95f503b821a4694c45553e0dbaaa977892b916cb8990ac9ec29ab5c3d63ed77138fa1e95f395b3b233d039ab5daecb0296203166e9386d1071c61cb1 +B = -34587c2bf3473a2c5d7f3399d5ba2bb09be8105a0b9f3d8737d67b03d8b91b1c869f4e223d6246abd36d99d84052ae5894e58288a614a0da8d69f1aa57428632c2b059ba99315ea2f68ee210e65a741e94125ee4a723a7828bcc410aa2dae06ea8ed6cd23f66ccca7e85d2e071055787f230ee405e50d1519377cfe0cab4e5f97b6cb893b01134813a7c2c6c +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 95d0b209654de56bd7d6f74afaabed2cbb3247f449d80511d2d3c689f84c9b79587d78abdf0eb37f1b89f1f8dc8a83f7f9fac2c8cda1fd3fd64e16f5597b7f0a1df6da6db9e828ce7be0e876012bd52f5a74ca73ff8ca4611dd9f342bf77b485305ac28a1f8ac7538169f2bf3e4ff4dc5fdb9dedb97fa743fd8ac8791b8e288a +A = 7821d4b65d529c30b8747e184e450cefb11b5ac5dc77905e6fcd3df64336661c82ea68d588ba616d23df485ff0658fb3376d5276027a40b392f47219edc5ecbf510cf0c5b431b02c65e5f432092f941d32ac5f71ce3496e403c7637f63a23b91e3326d01d2d32e99e0ab265108dc5e7919d3983839b3c7541848dbcd420a594e850e587f1846951852ed76d +B = 1adf5c428f2a95c27a943637758d5dcd7ca36592fcb9d52ac0b7d27adddad5804e3edef257aa51c716801ad0c731e13c5dd000f11b5ff1b69c198f236695c1b2f99c0afffb5d084f80fdc534de3b0df4597404b50c7e784c3c55dfc9753c414d145eb0ca4d07e2f65b63f3eef8d391250a5500ef64d9bf963d7250d6906694e7670f92e3d5a7930f0f85964a21a +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 46914b197b84fa99addeaf55dd803182083a7ae34d6d4d3a55d6272af40a600563cc8d9f6b48110d0521b8b99751235bd5a340b1743497ef1cc459dccf5d6da970c4c3103c978ad2d513298f1fb3e68b24a9c7b0795f47d8f7f6ca9caaab9a9d80f15982599d764f8738217f9158517806fded5f3552fef8b7dcd2e725ee04d5 +A = 1c9f5f2a0d72806dcca92dac1450a50cba05b5dd571c2b3b988d33528d90ecc83444e3ea8df80802c30fbd5a6ec2ad9969be73aba6dd27e0dd2c842b95371d7547768916c0cb036964d041284cd323c8073095b2a8cb8797add5cd80f03595de9d18af8df7dee0d250ea7048faa47ae0131ba3f350d82864dc95e5829b88eeaf2681433dd4d58b2c6f70426af3 +B = -aa1e1b3cfd5ca0facc75e46d872584d55144620f849ab05931210b4e1526f12679bbd9cf00efdbd8863970e2abe8fc9fa7bbd21afa9e364e3c9e32f51fe66844fea4bab7f3b1bd278fd803f6bdbd0d296321e67751a0b894da338ab431871adf1514269ba05e0cea5558cd5691920fbc18237914f3dbe4b253f774e5dc1dc57023c080a3b90a004b809d237658ca1 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = ada55d93c533716ebd8c16e23603071950aa714deb942ebbf77206753d2676a7aaf61673c03a4db69d67faf6273828594d85e3c8cbf38460fa2af603fe9c1b6ce104854e7281757b26589f079da80685aec153fc5fd1a223004cdf30247f8398b8e92899857dd199d5d5c32412bedbf9d55f20e52895fc1dbd04c84cabfe1264 +A = -7d22392a8da1966e6cc5ef50d7409c614f8c8f8e5791778f68a00b4a056d0002707933043d05e48347bbd4d0dc1b6ca32a1aa4bab9992e7e620263283eb68d97af13b90a29c1b7dce39ec0b8a63878e8d65aebfb3bff4e67129e3b3725f999f1ec9ae92007911f2cdf738499661c5b6c9bf27712d0f29e871b17318e95c3d14b2e472cf9e466bea91fb71a493b2d +B = 40279eefe59f954aa8c51c9c214fa07707b1d095f697ca40edb820401a45c472d1d7bb413eeddb64c14ce6144b4863fe9337ae4ae8698db92facacd6a56f3b33129c5b608eafa29e9d92dea620113051b926b80b75f320d7ca3d2ab597168c68774e68c47670458f5ef2ffd4604f20bffcc7817eb09c9057fd9989a6786a7e067ebe6724a89e7d1580f94ee4ed502cd4 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4dcae9def5467526b0ff071003e56f5537852cc0bde9d86eaed2c15e36e6429c68c061e12d321bad12e29626b5013c28f118ee59624ae2f35d2c53bfd89e6afdb6db79f0321ad5c55cab03e6a1a97ff7bd58c760d0e9fd7507de987ed2f94f9c79569fe7f03652cd53c67ebc6bd3c9e6c5672891a9d2ee11b300ed3b19753c0f +A = -127f5ca6924851faa2340c4c8f425b1dcf41b313c5c2910e5eff8ef2faaeaa43305de2b3a65a75fe54c00fb30c0ce3e8007db1ea222521190ff1de6d0cf2e777ed61ce8211dc167bf115a77890d0bd1ca786e967a04f077c89939ce484bbb1c560f669aacf7756a4338d97cbd7f09a376d2dfd4d632bb451f52c03c05762f050ebbf112f8dc5acdd9b631292fd7073b +B = -3bc5e9c352c46449a9155b7ce5478c771293599cd2dda58a962010f1f21d094aa6bee03f9311545e8dc6213f6aa73c08b55bcdf4d1d84fecb9eda35c83eae5fedee75b2d15a003f8a82b2b788ea19f7460fdd8f447d973c950b3b250a3022c19ff312ccdc86b6ab50c4ba627b15968c8a66d306bbdae8e88fe28c1853fdfb3fde92353f46b5bc448ae42306a4c91202f03d +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 62a812e35f46e04b3afa7d26c8fd4eb168b6b64cdc839ebd0a46bf2a3a712af8e97380cdf0bfa8a274f7b73e887bb4cc73c6104a176d425aaf5352f14ee51ba549a6926bd8d059b8e3826b174385d4635b0c36df75a4e7da44c34e51eb82322b34ae00e8c712eb75b3882822bce5a2f2f5fd74355319ebe1973284c690bed2af +A = 71c57b08127a956f0c17fd3c639bd1923ba19bfdb83c0cb9dd78e62b8fe4b7e0019cd0a6b73a334c622118f96fd6d91c1e06d4dcef8a3d0d6bf8f5beb6389226c50d14d3947ce9f24f7e0e6a7befad2e4e92dc9ed8fbb9811d908c03ac074b2a5c67b67831a350c4d548ac70810bb5617d261a045e53cdc48117b9fe86d35950d0a181b73c8cfd35edd31af031178523b +B = 1cda2a51a707f8c4d2cbff6337c3f63519705614c26a489b545b1faf366b705af1d953701b568a684856fd3186c035f878788f7e5dbea16b5e7b6e767cf611452a4272abf2a9c5e72b7251a1ebea5098c60cc5bf649cb70980b97d48580967ffe2913309b6b78cc12d91025ae403928851902dcdaaa60f5b323a1302a5ce114cbe174e3eb3c2fb5eafc44076396c23d53b028d +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a9213cd809d41b6bbfc2123bb84860788ce22d5b91f8e24fb616efc286a218ae9652b42912a58bf8ce596a1b48e4c72f27e52c36be1940f7d2138eb895ee36bbb917a59f73e0b6c3266bf4759ffe2ffaee3f6179492658e0778bb43c4df4bfa1a46300c9da496033142ae2c1e33333fd7e82c5a14686b255e224c51aecc2a590 +A = 1cf4e2d5924510a5fd06ff4eeb94a740e430613277149993004b8de1a2b96ada54b05365f305e896df5fdffd3d7bcb54f9a9dba9689e5ad498012f7a684d083c31d7017aaaee720bbd42382e526a35d2add21d9369f7faa41dbcfe3dae426948a402635771a977e19d5c353ec7c1abd279975f2effc0b7bc19990154b723f2f8c29e606581ab9d3966702f68d8bb8065e9d8 +B = -cdab60f9b8e1add4c54427b638ec5f76b30654d3649b500f833b2943bf6cd5d8647549657a8ff999eaffe413ed87e06267b97bfc1b77637b57f29039235548a7569fe6d4bb16ae9c6cfd38c0b8c73aa60797d0d69b03d5a98314f7f7ee25df8b896ecdfc782cf8057f038b6c3e79c99df52f839fd4eff302ddd1256e51eb31cee24585782a0439da3db2eee79a58f889d8847fe2 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4dde3d63aeeee47441a7e733bcccbd4f2e495ca3c746468e9855177f7672d5d82e51da8e268ac24e8971d802e25d842a16a6b8d76b8e46a7724108c02d38a4830453408ca5ced7093676a1db4bf4c94b9b7a9531ab7c26f8de520bafe4431a55a5f5d8c7576427a0f5bf2081b998b82da2e8e959f2ec4d5141b55e40bf6ddeef +A = -5770ea0a75ff451fc2c86d428f2569884b2c88cb6d9d407cc22b191849d389f57a5765b83adcea21c350b37bc6d750d4859f547da22ea8a3698a5cb6154b946331ae2ca18e7eaace951dcd49405bf8d8a716f7762eb242b8bf5e4c53a662c906c3be89e53ddf7a706ee2406c7d0ac17b54ff259c1bd5a092325938832763ac4caf0232e80a016cd1994441808d8db7e546de3f +B = 7e4246ad4af268695a51912053ab6628969af4fcaf7f1e97dd977984a1604e8c9fe6b920f39a764c27d89f75986a4bbc122f92ccd1860f24677cf346474fd9441f572f769daf834e6a00cbc027e15d6aa7ec2030becad41e1068740cde82abed768de7e2cfd325848f6063e2186faa76982b9ca73ef22434a28bd2e3a5ac477af50f258140bff938d3fa02fb904a8ee0ef3c1f6fed7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 3d8bde8d0625fc46dec46fc657c49c8ab12a988cec4ec1c24e6f4d8ff94514c8d8fee4a08399c6bd23fb6464a38bb5f249591456c283325e343cc289c85df0ff2c1707a6e407ff7a24383b66ab603b75e2dc3835ffe9274eafea148f20764b8ca30cbe483c1cefd51f82dfb93d7793b3ec19a57f2ba03d884f345bcc3188fe28 +A = -1680dd51d8be6069c86ae157922d55df3b58ee6f53738677bcf7332d6e7ef304ecc7ff7c5a5e1f525459d77202f3e815c68f17f9a6bf358654a92f9f9acb252ed8e9e6a849da7491f26d0e33900541ab67ce966d042607258b4382b8108729a703b429babc34496528f198a7e0f814db80fad4900fbccdfb64908febf5e09805d3a3049c0f164f0bcdaaa9bbb06df8f05309be83c +B = -2c6c6b3c89f6e1d1cdd9abd1a9706e4f642a25738aebbc97cbd60e1f4ad79b419dd54bd14f2bd147b1d8e9bfcf92faccee61a43dbd1a2c084bf06a2ca476b3d169fa2c99794fc827b7f4dd010c0534e7cdd03d00456033ae0203b78a7ed229afcec2d1cb96892eb18898bf53584dde56b4316b3bc5186d97e3a9edcd059d7fe14561eefe4881beb8519c1cb7c3ba22cd2e13d874aab77e +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5b4fbf0445807c8feec7efa3c2bf8dd86b1070638f3c87f1e173ee980412a28847b263a266506e70381aae919ae05d306d3a67a6c1e72c8ccf1c27d6296526e87f0f436c98fd1391f83440b58fadd4fb1905a484bfe8f516661e7176a268660387fe6a7266ef02e5fad91ffa69247bb11cfc1b5c3a88c76b7923a26f8a31ece4 +A = 65fe4d55bfcbba2bbfbdae831aef3dc8c8746e1d04cea174c1d336974d81d026f562225b4a297b1c3b044ccc5dc9c830a805a399bf26c0369b52ab0dd2c0ad19e723fcf9f5de2990ebe5a1266653195a2aefd9a392fd3da8c22c523a362f195babbbf5329018e3b454221b3e77cd0dee79f612f86332b1d104aeae7d8d84ad06b107715bb76bce20220d1340ecfc666b2bfce812814 +B = 12f775dbabf1c112523feab443f6e95d773e8220d66fd87bb7fc702588136a048e17ab6845a9c784dca275cfa445d007e8d8383740b156df7048650f89c5ef1a84148488fc405898f9e326cb8052f626c8881abeb70f3a0f52dd83e3ae0cb82d178cbfe8c393449caa2a87e7c8e2901a87e276b49b6d012f3cbb65641add3694fed3e3177777e78fe375f3a3b378091bb8d2998286562faef +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 4f0af7cb0c4e82d0e6589b24b55528818bf2164d41f58505a2b302a8f677df146f8077945dad3790c323e19b37e3379eb95de8abdadfbe4417f8bf8da643768a622ad4898513fdbc72d3b1d2791ec9ff40634678faf0e17d6e0851f08c39405907db85b74937ac403a9a3a1004013c7bd95a585728010689fcaf63b2031bc8c0 +A = 156dcadeca94985ea8bc0d1378daf1e85ecc4c7f8b6d6c7a5cb9f9ac368a97c07e381004023bc575691c082b5e9e13a02fe813a55e76196e4ad4b0f9b1e089bb71a0d5c94254b66e3e645fea25d69bbc5af266e730482a60105306d664f0ddecbd76d54e7235979aa2d806b809b3468078b5d90aa22cbd2c441198d4a52f6259972cf3d02003dc39dafdf3581638e56d08c5181d36e9e4 +B = -9a54586072d093939ad86df11fcd3337ad7e9e478dcbefb2b89d7555883fe8565abcd5b0a9c88ab135ce5327b2a326db645bc7c0e3ce24f902544675ff9d946abf30302f123aeed0f4e28edc72758ffa760277caaf4817a3ae8615784c81896d2404e2cf47c06b09085cd0ad1ec46cfc1f04d0272eac29e774b30f19939d08c036b185983c93ba15d1d27aebe4a357b9f6a298acca3940d2730 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 7c3ac09486a6fb518b98a9bc8a8b382bf2293e2c1154470ff7961212430fe2dd28697e49256b1ad8add082ee27b6ecc016b120e971665be801b720069d30c0a8c6ea4795613017e8883e5c0d0e68f982c328379d7a0afb7825c553e087b33e9d78f90e0b95a6597076b8ec2c1d375e2143bb778c318ca0680a64072cf9a4fc08 +A = -71d8e7ef13d63b4f417c01ec1241020a8ff4c9b2db531500984fd3e45d22b2bd581894c8a248ed7cc345e70a5698407df8f0e4ac71ed2c0d42122a4f92279346f463aed899253206786928a0eb7c37f2e51e1cde7f97cf9288d85c3ed7f49e62af0bf9abf062d2c6544d83b9d3438b3881e0d07b1fa0f2a4446fd43ab3b4f81fa2cdaff199c87965e298943c68cc15f2f3f3225efad68b73 +B = 64d52de221f102af62ab1e9526935b005c81658f8fefa019bc58e641023fa785798ed0dff8f7f999dbcc2ecfa47d5314ac6676c82170d6f2b18122c17c1e1ec1b9b54e333a184a46ad35b2150c8165f0de19a24b98327715e5a641c1b6d3ff9d247c89c8749e775e6fcf5f967c6eb5e73523d4f1ec12db7321b14398f26201a364e1371f0ac922781ee252c6d2b3c657ef259ab73cb7992a370598 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = cd08b388ffd41d0aa29a3dbde74106c57b18d325be8f446a2d9ae95fa4144037dbd41eccd50fa34096984cb11bce555c117c5568d76a8f79d308ce11043fe2413d37d6aa60c366af6c1da93d525e4b2d79fc82c0a53ed62fbf72c919db8a3ae11f5ff8057d7501f5f6dfc9ae461c308d21919d0de9e31b759d1d8e3526fee58 +A = -12e58708c30c93383cfe6e99ee3c5caf1900a7e610605706e77d8f428fd59db2884f5021d7a382cb18b75ed22528961cf43be1c700c581ceac3877e83eabd860583e6e94f3f2989c179ee5047c82b53d37054c9cb7ae08be60a91b10d49510e9f0b90ddf89f93790c3e18cccad5a9d223c605a6c567550e2b4950e184fd97dd68bf30681d3f9c585365de2cadf36a43f5a5305dae555396dd50 +B = -26ea5079ba7ed137a14d00d413d6f818e911cc183c88764de4d91d7a9b4cc7af3fad703142dc7905992eb8bf489f6d8231bdb25603ddf3c31fda8bd9bc4d78835f9ddc1e6445037f05125cb1ccd92eea2e927297e5eb915d5d965a25e5d58feb8d79a890e6036c80ee91e7469d9eb672d7a8db68905d06f5981fc40bf486575a067d35cf14ceee3ccb79b72871bf8f52b92e4910ab17e5e59ab3ae6f9 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 34714506322dccb91308c403c267f1ec75f80faf3cc4272dff4a84c13eb1e6133af6681387006c61e7e087046b64e7ae74eea8a3c0564a7c1f381e1c940d92b2c766fffdaa7318d07dbeb877943a73b50517b49e5117778b8a60212284fb92f29a9f5304f8f537e88acf8afaf01fdf64773f988cfa9551d6884baa70587ab76a +A = 638b7c549ed14256956bad532945ef9e11a50313172965386635a2fc7db79deb0cb5c157e9854117c17f1509d505d01a0e138d2e510dfcca45b4f7ec968b5214a6699b61b8ac68adf64d5394f50d577a154c013612090e2045462160d1f552592197d7da78e03491ae284dc9faf643805f2674af8652bae93ff230fc3eaa833dc62781e5f74d0f0b90290d51d481b0a94ae6e972197c6e84ad7ae +B = 141f62297ee88ad527fd1e0e09d9ab5dd80e17b32f34a674a27b00d719839701664ccca1b00da2613396cf633b0bdc4482ad3a0c3e209eaea7c22f33706ae44155f527c9ca4e341e651760d1c39f65d5e99e649d013730d2502b6b65adb8a73e6bc734b7d879b430798dcd53fa6c0badd57896cb566d9f1e0a7b3a9161e9808e762ca819330ce9319dbe7f49bd663a9f57ac53d65c6851dc7bc4ee66e08f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 7adf54c77eaea2a1743bc5011ace45b7651846e77f90402297f117d8b1c0377f93f49e92a2457f3d3debec3022a96c74c166d01b2279553ef518ec0e612bd7b382529184640c55b89255b2679da9cf370913351592de39f804f1724de36db90c045fa644e8ff20627f67d6afd4546f00d7af093f668629f9a06c07fab5654ac8 +A = 19c491d5b55aa25f2e18cfb7fda18ed4b020e3f63244eb9f6c4dfa86eb8a70875cc898e305a7acdd3eee081300edb3e4c837940bbc1927f5ed9f651e46581639e133515457464e9c451390828e5e7e00a688daaea74620363706cb69e02717489ba9ad05774c424c18e295278caf4df4ced80b4cbd20cd631df43f2e16ec0334564d9dc03dfbc7111e4252504fb449d5a25cb13630b7c0c565a82ea9 +B = -c3f765349639beb80f888d9c8b7b335ab46b55064ce2a88180c80ad280c6b7314df52b7e73095dfd82896e24604854a48121353aa1de663eff07882771803010005905896357cd5a56a59f0db0045f1aa2c0b5626e132c169abc64b9893f95932f54c1d8cc25f215a9ef6e4cfdd6dba85f6faefeca81793b2258ae1d1427e81e458482aab87f6563abf435be69a05b195d1eda90146a8cc92748ca6f798b10 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 32ba5fc81a7747c3d812cf036bc0edc49f08824d53b91a65a6d41edfb1651d99c11ccb4c074d7f04e652276ae3fdc8d6eedb72c6e46cbb1f7f4070dc9d179ce3e21a3826f7dd2c27943a8d26b192d7f5c4aee9ba0647e406133e3e89c262d37cf468aa3ab8c5dd1b8900dd06cd600abc6d372d9408497d9e20c86a9a6a4ad9d1 +A = -73958019a5a52357b9c1d954c9b14f51ddaced32a4d7b7c95730697cf90029564118ea168d23a54381f7bbd6718a6b662e4c87410e48ac53b7767148582b0bd6a3d35f488e7fcf2b128e0a58b5d468dedabde4d624f4a82e808dd7b175af0d3658c6df1ac0da6495bc9a8dc012f8de55c2003da9b2d478e1a089fab776d99026684026968fc309dae46a6ef2412039a8207c3084f96b4e38e4fa01d131 +B = 4330fdf00bc6d13ffc267073b68aea7419ebef257d63f8f244accb9ee46edd04fe5481292de69d377ba6b6304804ba7ec0a063b42339e6e37867261b9945ec705d3a0029c6f499420e02a773476546993b3c5e1efc2417f51afcec7145a9c2625496865c11636e285d4c8b053ffe66887333c51a712fe9c8ea57606103fd689dc88f1fe37dbc33ae4e92067c5bf51b53e2f8205164c800e5abd677c73949b00ef +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 69b850a99b471003a56931f7856da357a2254ac50ed81dfae019c9b722b95af16047a0d5422cf7ab66ccd898e85caf0e03e74cc8a5a413661e5da483b3f0363e63a7031bb30626c8f73d6e99e290071094b7fe5bbaf4d303192e59acb5e53fc7cdee78576b51595d9f7a25ccf3c7f8889de68b9deec167778ca27ac9d4c71c3e +A = -1976b3bbbf92acbfddbc05b5d9e7b62a7666b239c1e6270db7ec6dc2929bad1024e745b897840853d14cd815aabb01aed580e1cc66ce37f9d1cc4c9bef8ddd35d28285faa29f2003d2a4623ead7d73302ea9f380f16b3fc06b7c2b8bb4ce4c8b03bfb6056a61c620e4decc6048cdda5e2d3ed8a13b779b8829e2bbab91e9f6b0304b1c08bf8fd85e0f3cd7ee72255e5342e077ababdbb545d7f809bdf8145 +B = -2cab554f7a5d21c499a1025f61e6c81ab0fc68a874bf60470cfac57425a451365be62c380ddd31f6e202f29769e2b6106868da7c81522e03fa6f0704522a5f8bfadbd007bac65595e149f6c585d7fc022db016bab32819049e7547bf85d4232a7fe19084907c528e7eb0434f2e5a375ad9b7d463821bef2f6a721a635252576c176ba42519bfa5d97d0e47facb4426aea0d755507dac81ccf1537b1003ddbb0727f6 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 2ce33adf34f2249f8a2d2e073976cb4c78b71414e027657fcefd56fceb022a06c1969dfafd519eb9e2542662c7647102f5c528734dd005fca666be57b46234123bc3db286cfce07bcbb399eb6764daf2b9aafbc2898a5ff43ddfae849c7549289640edc4ab7c4b9fcf5e159623e5497f509ad6f0270a41fd864c9437302ce380 +A = 509f5d5b160e923b4fdd72f4d522a713d780daa4bfd10ddbd62b26497a2e7925c495afc2abf0ecfcb7980e588f96c4078bde51c7b2c19d86d15bbdad5de72fec2e0a284dd693ce0902b40e54af87ac5a5df38ae6d1d882ea6299fbe6910121ebfebd06b454ec5f855bf3e7cd544a4b0d9a764428662e824e2a6185723534f5e6ad829734347d240c48c2c0f8bd6be6ae8a495a9e383fbc7402a4096b8c2c214 +B = 1a3b7f55307031609afc974857a6cc75821e73a1a9535bd6b8e141437c3fd4a6871c904e22c5d9289df7525ac69a0341d3620bcfc5f04b38ae540e26beadbce0002a8a8bfd0f6a270007e4c52aec2fab11fb2a831b9886997256e4b7e7ad3b0ec64c0f31fb0d637869143712291f5073a5756466d7c82c31e08e09683478229bccdedc2cabb7e426af9025185d8dd5124e08afa4e981236180e0a390004adb7918de6ba +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a81fcf9a18ce476a839c896cc5d9b639fb1d74610e2f618c25310147b57cd77806c2aab90be7be4ed10f0122baf9b862b141ee8e4be5e0c23ea776267f14c31e50b119bdd33f2b41f6a4c43d35bf6f095864593e0d8c0f1fd4656d8371af844d197308bbff14e5a28b7181eb6e6a2b31ead7361e287f3b4550ab0484bf7baaac +A = 19f1ce60ca50bfdf8e02313f1c9a45496720a2ce467f1e8bdedbb32525d762878b61476989c7f6ae8dd29c983ea596e521bd4cbf74dba4d505dd9ea5df423474fa9725d5b65f1575d26ead95725e2a59a6c8a5397ebd6b54123e42bca44781b84c014b8e5d2c1a86cf34d764b242baaad5be285cec72ba8ace808058a0226c04f95eb2b53a828d0ac41e6b40e5a4c4092788d9f7e988752f175f075d545f421205 +B = -b115a1101d97664759538d22154de4b000c008e551e2ab10ad05f12274b10a4cbfee762d232df5188fa1161f37ba61d146e8b95fa715d98e016da8beb0600de65216cecf8b8816f6e7e73e2a2bfa7d0bac74b517b906bbc43357fca69de9cb5507bd95205515b97b3a4d6842f3d7b09606cce1c7436c462f49dd05e915d04ab6fe2748ccaf025bd5d19749cc468d228ba43452ccc479c146ac6d781717bb9966bf3835dec +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 1473f092540ae30de595666beb33e430cbec42d7a28d4f7982e62f58025cdb617cfc33f1e5ab93d2ebefd7345561b81271bdc50bfbb0db6381dc0ea023ff7c72605da26dc7da2b5664d2ad7967426ca97b3745f82528964bb68e70087e14dcf2d71d30fa0d1f7b3f10b19b357e7053fdf22bccc5188c6919eff1e5c402b750a4 +A = -68f280cecc512d51ae534f30aa198cf7b170c346c1159fa9cf158d0127d43e50a8d4704ec54b8b4295dd7f51c6771cb5767fe0c975414cbe6d2bb58ae66a095e8832d5f443498b1ade1f5bf249da58595ebd878677b34e3b4c99ba6124e2b71d86a8d99727a16746469de51b0a61d9d981459a6cebe206cd36a09f00ffce7f532e2c31999847ba000b9e01a4b84f454544b6362a5c093b9abe9d583716f4534f2de4 +B = 5b79684387f18d7de6eec3a63d737490dc2a46c0616ec16388dca2be60adcda11ae13063ede3fec177171a51dbef430f8c4b3f6d297b9d6c020fc44e3ffab891d0d751d033fda813861bc067c181118dc613335ce89c5960f952e5fd28bc72c41b7b6e374ec29b837f1e00271cab646c794579d315260921dbc3b984b86d98b8f8816aca4f16de50657e4102f34d9e29ec3a03e0da06e70f69952339bf2ec4a7e74daca82239 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5e4b3f4aea7115d592bde9bf7c6594fee77372ffb19f7745b4de878a4024f81e8290c77d2915424df20004a7abb64c214104a3123e7c8f230c159ccb99bd937521b433dcfb065b186a685fc40f9166bad9380a02e297ffd6a307ce8d2c8f2f1330447a9c06c327b74f3cfc2e98f3351a8b385bae855941228969d1c29e9da3e4 +A = -11c1d396693139df5bd91825c119d1241c3f57b7ce95b46472dd82081738cdeb0868d18eb7c8ee7808016b3311f982adebd5a2e5f4e201ec4a34f3037d260fe580e771222de5a1a67947a4552cc03c5c59f9e60e25063a702ad3c3aa43f061a22567f938a91f1dd697c3e3978fa11ab1d65030bf327f8049bda745658bdd4ba8f3e34b060c6a2c6c5a8be54c7cb5f6b106f54a37d2be9f674f7747744d4350b3acdf373 +B = -25a65b6acda692ba3330d70dbc3ea4dfe208c0df358c50b7872245a909c5ac19ec568b1a1340e1a094f5b8e7d1e3b7e04bb4df002558aefd4540135d62d75bd5ce959128c1300b9d98429d7369610866d98b22c345e531f2beb80b042b6ad48da077043401a82e223e9e529e7407bfa466dd2680973006d047d837c26a60cabc36a7ef538f603ba19f8e923f168ebfc3834df8f77a559c9e0342e33df245f551bb242e5a66e5904 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 47872b544fa0425981ae17bb450ea346135e6ed7a9de0572ae14a6e85e8319f27cfab778cdd8cb5f93b417d9c66ae0fb7bcc6652620f7f3f74acc2bc9f2c090129fa8315aeec9ca7adc5356484474ee803883ba4695d7bc47c87eec508d16a15150cf3f757c4713de71366e958d6af045b2d282b6ce96976692c80b1e0b6f846 +A = 7e8f55c040862f12d8cc6e506608eeca65ce38e9e8ab18ef7007e3cf0f1c9a0696795bd10f8e1e1f55bb4f4f3a35c2e0ad18289e250571ccc26a961f730346efb1e29fb143ed97cf72deaab19834fa2e98e9c12ae4cd23b9c5ecef4a04c439f7d42e110b30caedc4334372ca24cfe4171ef1430528f7b57bbc823fd606fbd30915c5817e6c57c967c4c404a0847b1455da17effeebbec3f9357358e00001239aae209228f +B = 1cc00b95f6bd3abfa697400c98110725a7e109aa9b8cbbe9ae16327c4fc8e5bc93afc7a94da32e98e85e4fd5eb545192c73007d97a4e84ba64fe187ef61d17f0941e165c9fe64c7b8054e24dad30f92b50d1f526b4bb031e6b1b9058be24884b170a145212273c51692b71bc57ee53176d8702b975bb6ba96284b462da2ce38e12d86b342c7f4d3cd489fbce88a309c7df1121d7bbbaab6814cd1e54953e5cc46813ead98f02360372 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5d193b085e57c3f1e825cf3b36c8bdc936c603136bb782a244b04a79fa713dc7b08436b85ca3b483d2e100a012d6430679b30c8e4101c8f08ca0f9010dc0f27fb37be842054dfdd99362e03a7f55ae58db7b47f694bd35d91a58975ae1f255c41617e773f91c2640f768bc702a213f073682dc761e056b34c57edd85585fe04 +A = 1bb1c759ea94b61a1721ef5680f42af30fa31444b27591a03b7c9bf5b90845ab965339f463a78bddedcd62fa21197c32d6850c61bae195f86e1c7a23e7a20dc618c59ce3a1c6ea6306c0b01b11a36d0fadf8214c36a133d689438021ce7c78b20c85256ec607360cce14f139513d9f3ea6eab067b1ffd0935d7c43419b93ecfadf2c5a902b7c39a69bdc023173bdad574adc77706c1a666d66f69578a5bffdc7cd6eee28ad8a +B = -e8072c49cea603d48f20276df188fd2fb28f8721d578220cef7db1e56379c04a6b372e56a047cbe59ea84ad026adc5d0aa930011db63bf4959f15781e060e0240dfac0e2a2c26be12a21e5650d12140bb49a2a8e0f6a86e4b1eb79d9b8aab3202bfd339096529170cfe3e0c18263128686bd9305e92a3c43e1523f97d8a6a2707773e3d441da162a79089c9ea1e094cd5a23474121188013c8c287965a5e77599f6a7d64174b06cc165e +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = aa79c899c2b9518857c9e4f96523a44607c3f6a97d1f40d6474ec79deb2feadd955fe92d789df4d362c828084559fab56b5e33a971abc5449208d31671c7e220c5945886e33ed1d804c059a8e439a92524a785076f9730732bc5a152aeffb5b9ecf3a7e4b55983016355c4c29827496fd4d7e6532c270cb9ef263573e4c63074 +A = -41b326c2b86e7ac14a2050bff67bb5bf9697f02594789c4a2b3e8455df4522546278d0620f28a680f6a88ab545de5829305485422f4e70a5ebf0ad15508dfe3f16ac556436d8fe8a8cde83ead549d88e0bb24dee52ebbb49159ae71589d918d3fac8011cfc3afad613ea09173856b7b79b55a2e43e0f7cd21eb9122d5f6a1fc5408414f5aafcff863b870c67b740256d317a0c58af9a81d8025a086a1f3d79f7408d4bfa06b9dc +B = 4730f03c389f9bdd92fd864177e06140c9dcc02d01fe7d37b51d44de140696f116d11bb67adf7db797edeb7c304386a7f5e37bfac46a5462a6d4c49b1bc034c2e0dfa56f14bbd2a4bfaf86bbad4f6d0dfa13c782fe680847d4b43373d7137f5c2ebe4ad58c695a7d4c407bfd888ce04abaaec60a3fd33db10eaba6b6acf0e16cb61d1beb9212c2b07921bfb5595ef1eb389200b356eafe8b5288d8f0e2cf252b38301de65190d56bfadf57f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 23f9850dccd2af799f18268c3a2918a69019513c55268faf2477c50677fce277d8ce58a0cc06dfe389170faf5f0ae13ffc4954c746eebae66efc14eaef2c2ac9001f3c7ef7e32fdc31dd725b6a8093e33daa6d19808908e0c2d3e7c1c58e0fe9ed92f4d7cf3cc222393ca4f95feab5d34fe29116410a1882dff7cd92acb87590 +A = -10a75953e5fb9903411869a2949f8f04144d6e2d61f95704ff55a02f40c4f283add405353a68bf7d6acc1b8cce738f0c6f9271a538b4c688dbeface58eef0a0a1d491a9e66958750db97bd01466edfd245cef03bb6a3acb81acc63c38538e7f15deefd15afc422a8641c357c31a069258dc0ebb63f06094ed8fe7d4d420246b40302361967c81f0a9ca542fd1de01967514ff2565de7ae3b4a200d63feaa22fb99a251cad66624df4 +B = -351242b6e6d0122f7120deb8357c3bcf25d221a15f83579883bfb4dc2e6099e6b7b95fd08f6e573d93354b0676f7bc9fad563d6eb0f3567ef43efe3d874b9c7733e4fe1ef491043e1f80aab6094cc9b9c236570972233ea74e8779a6eecda23a65d08d878850cab6005159265893dc0f66920a12c26dfb421ec326a1ac09e9ab8085825c31aba488af02cd51f96b205c50e692dbf2d844ff0a989c3ba9f1c2bc7f2e7dd9458a72d310eb28d490 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 69c7fa326630d7de69249807cd8bc55c9315acac26fed3caa3c8a9c6b51ee96a7dd0b3bacd5cc13c15f199e268c5eb91d1ec36c085f83b437b9906caa6e39ed7bf09778610b621426cc8d36d96f541d0bfcc7693525d33e0c2ecd77ccfe80289a11155b37c7ea7791b5c2be3f9b954e230c19d746575afe9a1a3a9677d23c5bb +A = 7cb78ca8e5d903096630744c85975719c16333e2e44931956d8c45b001d35ed4e184dec88c9e2167d2f338fe6f25540a144cc419590a4ac7caedea3bbbc565365d3357baa62fdccef2c5ea616614e0bff60e81916eb4abde0c9725b1bf6869e8b1e11f6d0d08fd712bc68003e55ed462ad4946f7f982e663f65d45c07c659d9620d5139d2b3332a68d33aec36e21716a3b75f44272a19f860e6ab3864f06def9a5ddeed340ac0733353 +B = 16d5b074e008fdd30e73ea95cb5fb87de806319388b3a44f33c94d38be0e6f1a92103dbdfb3d23b6e1d19bdb29ac14833003e9482cb7524d0d7b4c377f4911e3372f2cea6f84c938d84e3994e80f0d68e7e385ca29e02f70294c921dce7cd3829c5854ce51d1f4fcf7dba910b51b48a3f53cb1f187182435f21f6981cf8440f9c8287a9749c92c0304cc2bc91eef32d8e6526be802de8aa16684e8854cb0b67d9f7ea00f6f0145d14e3c251f70881 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 72192604b2f3f68b9ed3e261120ea52b06a05869f6abd21828ce8abadb3a71c360a14947bc738e5d1d530b9636d796f785bb44508477eefa80c4b77d4e8e35463e15ea2a48c682d3288c5abeb66181e4bed7d5b4e0db20fdf5ed68513aa5ae7e0978ec1c4646368f206636ec90e808817bd1d03acf9adb9ba57dc153873fec11 +A = 1112d291463b28ef45e879412e6607a3e20d50dba5044e71883bb3cdfe9bc694a577fd7d896dfb836a171f3a4d8fd025d3a979b43e41baafaf7b535d9050e47f4880828640e952435648960bbb74a3c25dd90bccb3fedd254dfc0f031d0e8a468e93bb69f771ed35f1653cffea1a763491fdf6efa21aefc287cb611f5ea0085f64cc3705c784f87ce00846901833d01a3c45ce047d822ba390b538f0a24720155409f60ca0d90e13991aa1 +B = -d553fa2dff0265cd9d083ad097af87a99af3d8d93a9f4c07440a28a427082004ae5c81d22bda1dd2429f540de8df175c1b4d0d50f0227489ba570b28baa35055df951d05b584ae6b051a135d7eb2a501b2441f82c135a8ec0eb81d379b96ef8f2fd526ee62293bcb934c76ef8083727a4b28bbfc9f515ebcc2bb7ed9594a106e137ce94e9105b2e2f4776aa9c6abdf426a181181fece3251c3ef4f8eecb634e6bd47c5878663fd51c74a66b92713fb7 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 459e19faf105ab17ff794927aff86196b3cc3461e69cada53ab8c8c81e2b1820408421ea1af6ae10257e8cd9dc16386906410761fed62cf9ddcf0da2a92800d99563fbb9cb1ab0ba46a17cb9dee3f2b68992c2b832a5932e4533fbd5c4487d870f3fb5d7a1c358f4aef02993360915a9e9cfde234df5f51c761d84568400b618 +A = -7a964c62e38e4124cd2bad727138dd12a086a2bf01c095b078ce2f81288d3c8435ccce0c8e00229184091130989434bcd107a3a0787a2f5f4b0e8c23b1cee9a8f39ea279fb6081efb6c3df1704fae9e87d63ac6eac4c6687b3551ab7ddac5ca0541e12047d04c2fc760fda0916cd2b585a90d25880fcc1bde8f0a1a413969938d42e8b3b5f73118798e85b901c2e15860e29e2ee8b1c95336b97dc10a21f5300e0352adb60b40a8a99333380 +B = 743ff4d91ea3e0f9c4f72e5daecb4fb00b15b86e30bacebbe4384324523d14e22abe29b00573733f594d652a88d98c987f8db08b27b4dc68577784fde02dd410ebdbfaad9e9afc6a22a8cbb13a780222bd212fc61e38faf409e940fba35ed909e6938e83b0fdf5b5e3ce138604823e788efc3aa0df924554fb70fd2faf8249e17a827c5d85942005b328bed97e5ea1f1810219d77f2fe121ce66518e37c84d64aebda3c397684212384deebd520a776b95 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 183950095d9424b0ed09985aafbbd2e5d64bf541a56b68b42ea8cf9b2c051615ee7bb6c0687ca6fb0036888fbc927cb7aeb303750871442ff2c0087a95f4efad568f48b03bd2b9a9ac26af8c259a3fa97cd2af7e3d8f36148c26785489cda6c00a21e7eca219d1f41b2e82ba8e2c1cd752eb08a2fd50c6f9077f3096e2eba05e +A = -1d2fc778cf44c6992d1f3a056860eeb12f969358cadb087dcaebf5f96bec42bc0aa98672260adf1732da057e9e0d22081e33f5fa71f248cf89dd361036ad58692637cdfff584a191279f178242ec0ad397efc52e99462f496caa0f3133c4238aaa877fa7094662f080eb284c4cbeb992a368c2d157ac5c8c9160c167716406190fa39ce0abcdac52c8020969b87a4f84bc09a51f7b2ca288c93b1aac64e19623a7d9e69976a31074f637e4c82aa +B = -2f188f1245b75cd21d052ec76edeb5881944a143fee31c67370fab0420a748f3f1957bb8332ffefdeabd0ca806169629f130c86c99bab490a9668fd8200f4a9b1704c589e75b5c8c855f133d50b2ce06191875e2872b36c78438d6032d53004c047f49e4cb81e19fa84da16d053e6cbc7c8eec0b9129a8831eba690e0542ca3fefd204258624e92844c8b7bcdccab986475a47c8b22e89079ea6580ef8f496099cc24dc2911dcb1921d1451e2163b55bbb7db +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a02c38d5df9ff7055ff84122342ccdf6ed7f7d54fe8227af091371f5ae62844645586adaae99c11f4ccd828103a81471bac72dc20625962e41d603e760591bb3569a21f45bf062b86b5fd1c617a4769a4d767a0ee14d104084c12ae875316a8f2be7adec0104381dc02c20b5851efdf7d4bef0d68076975e0ada3e58e101e8b4 +A = 5daf37d616da184acb278a75fda4e4fa49e544eadcf373c054b203a309ba198233f2285a1b55dc92e05d0213b26c82e261d8383a845813077b2e1b5f4553400f09410987c8dd21d4383e0f05747d0482d1a89f160a5220b22c78393873564fc5b1e4d5627ef3d4a05612709f301381df35606e99560fba07a917d7ea7413110fb5a8290e114d5200cfecb00b6c53b2ee29911bcb2fb2930eadba0ab9dfaf46443370307d9c3b61a329f0b8b8cbe7d +B = 1d9539fdb1afabeb9be6e774dc7c7cc4bb4fd63af7abb557a5fc80a3fd23a4600de3c7fae89b91f3d441b61d3e24b2fd3d7803cd71620e7313917b4afb89ef5171a3d8a68c3c74aa3dfc8058d555eac429dfb6db40a9e0c25aacd2050418d6f32bf21cbb76981269dcd5883178d4b69a931a0338b93022a2ed0f78f3d8877989cc406f19d6d082ea344309318c56be7946412ea0867c78418ec32b9fa3a61017c10939c9345021133116933a3d1eb86a3ef16424 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 5fca287abf1f487e0ec18c230860eed4a2e550228b1500b1e33bcd6675646b5afe505b55073129f22352dc2b113c584ea1b98808214b6916933e90e036b129b61657cdea9026e1fa087ee300e055ae8f94ffca933a2d70453ed220468a5a3cf1a65d81eca11cf570d7d038722397f487af60531f24a5f069671354882c8bd2c1 +A = 1d9fe15171dce97475f4ad329fc8fb5469fb2b8086e4b01eddb6ceffe5324cfbd28d791705848569739b6758ca7e7d7d49adf0c11d891b0a5879ca870d1ca5ff475513322ff218cd26024f97623bb8a53084594e1fd64154e1db702522883fcf4c0d677a7fe90096fc76dc3800816996308d8f0be2dbf3b879f8a000c0ac534511437e2ce2d7ebcf42fd1698a829eb846b3afa581c24d5bf97abc6e247f110f4e872a2474e3acca6c8c0d518104c3375 +B = -dc0da8f7adb8e9f7b0e3f293cf623528dc8e9668317910417e52301c50c62e7d30e77ec7e38d6817d1f5a93e851f8560f642f23a0b9f836812d27b1b41c0867088a3108332b8711047560052ea30c8840f03a25c65b227a175d8f340095823788adb5bdf2b7ebb801e20f6b6435e154f78d17b8fc4373aecee56ec7b8f5686a7d22c8571797fde85cec884d45ddc4b1f2cc47ebf56a879bf286f349a0edfb531168b733d43de3b86b49eacb10b06a432c96c63440b +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 6222c1a14c6390d73944cead58eae5e7a6c19d19e4563c36cf624f5b61d99991bed7dbf6a0723abc56469eedfb1f7982987c2c7af6191178cf0933ed5f191b8117c9d726cdfa8b82a2fb25ca5436023f5860aff5fd482c611f134569ae87395dd99e5e9d400b5ab1e3064210ded096411654518110ea45899f4be2516e35a229 +A = -7f6766be6c6ca9bd1fd7ea1f80bfe68693f7ee4b5ba2946846839060d6028eabbb9079a165c1a07eb6a01239f3f14095225b8617753a1cc3d9c1e69b516d8705cfda396f4f0d05b0944a0f08b478d261e968c06918914ba87c8e7b7adef5cc2a875917d00585571542af219bd726e502b7f3f0bdf0cb1dfc6796be2e22e8ffb5b8bfac7e15e991022974e75d3a5eba214ab8a1aab2fcfcdbc6ded2abf834d1899d2e3ff94bad9c696aece045212531773f +B = 49c6f869745983cae44d33cb7ba141234905441ca53172abd1a2dd8bfeeac4b236605cd2dc5b04ff9aa13de84872145b935b85479136065d2d57fd15fbd97480c25c6354636c17ffbca33c9319d65e82523e39fab49321380a130fc160857a451a69b1d0509d5718a9cff8b49c2d677c1f66bf77333d2511f58d3eb2fb47b3c162cc9be8b012d8df70278f0e21123a69724a1f126369a236d54da026ebe222c513f24b577707b5ab4b90ab0e22b4e38ceb4181d4ca101 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 9e9cc8c5342dc6d6daf55fc9aa9f79ec18592e8b9724a66881c379245c91f06a7df50a6ba0964603a6dac97e77a55d06efff17c93d5faf107fe65788d0f56483915f6ea0f1ccbda7656eb58fc032b5771600beafdc12c2076110a9b9670bd0754ff6a72c5d6e1a9e4e42c688e1cc96d7aecd815bdf5dcb16fcd1be1275ce7282 +A = -11635fe16dafce21efb1c599305e9a16eb5651187cbf054cd9d911c13e8eafbb738013e212f9c2b3662ea15ac9bd82b5751d43a38e4475d2310945a812262309094ae9cf59e0e9f3d02c92d8ab01f5733a20f051054a240bcbe3a7b6bb3f7c434229f631c4af239d33bd3ce30a372a480fdb49b2716091d26071aef372b8bd8ee8eb7f2965a372a836000b3737d2a833a39230e721e4844e16031ad69cd45ced60a64510c1248fd776611934d8d2a913d965e +B = -3bb2cde9d3fda96fd7e6b24645f8e00b43affb223f2b5c3f4b7cfee905ddd6703a9d6c01f1f099ad1174da215a645ca4707d8156e762e2a253d7cfddd05ca19823ada9d33924013f677cfe4d86bde025391e0aaf91c6b776a9cf8a09dcad7cea59ee7aea1cf5f5bfe67c9d4456332d1f98e5310db9a0230381e1867a8f75b8757283f911f1a5e0d4afe5d544afa8d86637f9c9d87428fdcf8b4eb8f477e617960948253b24565b2f23081c47e211cd3c788a92732a49077f +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 30dc89bad4b449d1df9ea9b8f9d40b323c71d7e1133bc44d33bdb87c38cddedf83bb849e83436e4c92a06546fcf3e24ce6cc89d2e97a48aff2c7e3703da1b167a112f662a89742355e11e131e41052f1b379753cfa32cb0efa3a07465a258c585cd68c86bc9a473f5262c86c50992aeccbb9725b69ea8b3a7ebd2b6a24db52dc +A = 60463fae1e9354559160d55a453c12d75775a53d1606d1fd16bef7e4ad1c78f9568954112f9280c46781180951534c5372dd5aaff3f33ac9c2e0ce4934d7009aad2ab5d6a5e5a141a36846e8925c7a28d116c68fb78aa9a687ec9bef173c1b69e0d7261f96eacacf237e1fe5874e5d553985b0fe7692ce8f2a5feab9ad9a2ad9c4bbf050b73b8030ebc36b94af8c6ecb67f8c94607d80cf600efd4ce4aa006f9b1832da8a1fdf8a564be0b4369149e8639e1714 +B = 15bfc50290b771ad147695a4c6701c47f2e8aec0657a4ef999eb45685200981b0ab5f8abc143d64878b85e9548651a1afd0913e3b14d11d3a26ab9793596801662a67b0062fdc8888feb029266f71d170518b6a4a040f59996bd4f257f221e830d0faaa9688aaa6afbc1f9b40d25097eab9d71d80aabc085f3a07e48bcfb37119aa00de60be55fd07d5b1281adf7b98bb589cdf2026252edf2f075ee176e23afa6b1f924c9fcf3c34c76752e833278a2e6b62017b88b77eece5 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 8b506c9bfb75ab7ab420ae6c9b371ef035fab512188d9df76f0b31831573b44cb08266186a04d20cc761d61b6df3e33ecb86c269205c2c79ae6aa4d3ebacac8ec71d9bce1d7ab146530b131c9038041c6ce8152a6f1c09b9bec8eea4462dda0f08d75edf296eacbcefd62a0c197ed30f799343268bf6edfee4995958db7e0420 +A = 11c16713fbf8bc9696782cb5a88174cddbe68a04e8fe93dd074aab33dcd85f92baa178b2f3b8817be0cecb802cfd3ebb06734c9d399a1f090e3a8a2110aebbba0e920427bcda74bf11700b945985bd532286d44a1a615cf7c501412e454edd647f8371cb8149474557a0d47cbb782f460de7a3cc28991491ea0fc510286711b882987b09341c079565414f2c930e7c3c3a3e3e0f1d786260a7f45c70e0fa20dfc63849906af61707cfdf5a9b7a4291a1c1586d16b8 +B = -cf5638af39c6da3757a09a92e0bd54f852742682dc91c71dcdc6e72f7825a0979a1ead2e158479ce5565d22472dc3853e6bf7ba43296a5e0e0a355f0703cecc02ec79da83e3e9de10a6eccb858dedf7d4c400c27486a5b8cb34d787cde6a5fd271e83a6cf66057838fe30db1f30663cdfc22ef5d002b0b5a05831228ea200f95382a58d0d8aba36523d9b5cb7506f193131916f3ab66ac9552c26cd0c2ab1c449eaeb8fde752f4f3c3f9b060cc1f8a1e37c4fe5ec306674b66158 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 347706abeb168205cef9b0b8c6b9d6449ac501af7dfbdfbd41a20a6a47872cbd7d4cd32f7b0805ecf1573d534418b7cce98181e079d5061b02639fdf0161cea5314dbbb2ef39ec841f695281f3c7de45f33664e0dd1658f645adc1dd225f781a3fb1634517c556403587b2aecd56dceca9ec19b930cead2b1d303aa056d28bc7 +A = -5e1c869e5dbcc684c245d5c69093bfeaadf388cbf928d33a8ae2148a2b5145937e4f654c5f6a36de1124bad1de8bcc9067fe1f9a44fc6ffe55ce7ed5cd0dbb6337b0e1e96bac1eb2a3606dd97b0bdb975ea59448be50191cc7ea36481ca9fc85c1c3e1c97378dbcd6b355622046888df2ab3d18d805f4d31d464f62a8e630e955beeeb5e00c70242b8f8df708705abbeb95dea3561756298b5f3f7fe16e965294eeeea4546f5e8bacf9d6b4f2136d2e206a87dad1f47 +B = 70225f0cadd328be36ece2172c836405db3fe80ef99ec74fca25406b73a537adf5073f2b550abfc4c0fcc2c2850dace0da9a266768cb4d5ff7fc6c1c248ad74f47592101b61ef96c1302924381abbd96cf49f50c44bf7e0551721a8ae85abdf9925548d13b8c5d1a27be8a40d0f43eec3136bc3035057b75aea779b4262cc66e6bc68da93c218f1920979291105d4b02117d66deb92c3e511aa588b27130202acc9f69521957f79c7e731bbd5461552b9b6b24240dd71ac449be9777 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = a2cb238f326d47f95869e2dcb295eba819a443dcc7c2785461389b58327742702f4c86e47af129f1fd4611cda93631f9333c358a29121d58286333083d13e66f30a9533b77ba3e26089e7eff7baf19bef8054af4e24735525908864ea9c4756b42a69c897003cab7b63cfd9a5927ed562e29845308eb2a55e7f8f03c87a5b7ce +A = -1aa7ae6f56c38b654b281525b9da953ef366c2b9cffd3042105ed428dc7e5f2f2d53ef90b468bb471753606cc7a3775d86bcd2f4d5119cdde3c487cd39bf31752c5ba297e529c1b8121487e0e1de702156d0166ccaf51888a24fe7b48624eefaec855e2200929c21858676ec9bf4ceed0a832b69efd5065af544e49a3d209b85a77b0953652cbf0aa897527c52c9a98de9ae4c827f762e251478c88d410123625ea52b3478b52f6b9987d42009ae427763357ab53195772 +B = -226630b6fcdb5e274a25066ae2ca2c803549dbb935a97c0d7f6ab2c971d74cf6acd265c9d6815a6b2dd23dcb3c23b390fe8b1bed92b8c64c76c0ce62d5e7ddd7ce445bab0ca905dcfd0f128e5f4ffe966f3903d7ff1c61fe174e373cfe35a6d83249ec40b4a354d46fa1c90682efe468e895ea3da710838c262e8a47752dc6e7a79fe20051f51180173b58e0aa37b22eb8efee5b6dc264459ce4d135f430cb15afbf8c53f0de894bd2aca1f7ea32b4209a22a075f7b3b18e86f778a9e47 +M = b18a9cd6a0a89578ea773fbfc0767c8ab817cdd585c16afad3600540d056c323d83e7756b1b74e4c2a84df7edd562e011412a0e2eb6b64178a9e04f67550f3081797873f444dbd03d776835d696e464443a0a6f48d509228fe976c54cb82925e8a80ee65c01ad9a5f56784c54192112fbca30a76ce579d3eb6e783643e971d48 + +ModMul = 9ea62ef634 +A = 55cc58c9d8 +B = 6b49179821 +M = f753311ac9 + +ModMul = e9ab3a2aa60edd30108 +A = 5134a36c2bad180dd5bf +B = 2ba6485656d041690666 +M = 9b9cc4409e86c8b0fbbf + +ModMul = 621f9b797e866028b7bd1ff828bf29 +A = a202338dffe171c99434d84f3 +B = fb71eee7045b3e3ab5dd809dd +M = b3e6e8d53b7249df670e3c59c55d33 + +ModMul = 808d463d06b7b7f98e3cb2783e2196c349d62672 +A = c669426a92d3cb5b316e2b5b9 +B = ccaea3874008dcc92450d8b2f +M = b04dd2bb325baed1940cd000e8cb2d786009ccd5 + +ModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0 +A = c3255cb24a813e27c3dc410f0 +B = b144f39e7c2d33605ba7bee16 +M = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077 + +ModMul = 6124d7d171 +A = 235b938139 +B = 3a56a22a28 +M = 83eb4af4e5 + +ModMul = 9c006f56095d442ba98c +A = 207e14237c42e3764e5e +B = 8a495a26872432fa8e33 +M = d0cf2b8ae5c67d6736b9 + +ModMul = 97387cfaef652932a230c82de59cac +A = 82ae0fc5e943af5bb8c4adebb +B = db1279be12d59ba3a9c036a61 +M = aa36dc1d13390169cd54d711eb511b + +ModMul = 32ee73c98da657464c6fed4274df20b099689e00 +A = 9baf08248ee24bcb17714e420 +B = a7f0428147bfe098666180749 +M = ce0bc198331c9ed1d21f0d498326e8185d3d602d + +ModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34 +A = b36249e259b303e453757721c +B = f0c1db50670d92abd93bdc84b +M = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9 + +ModMul = 2663b741ff +A = 58c8e7f7f6 +B = c84681fc87 +M = e0a50dcb45 + +ModMul = 21af3c0b42328f41b81e +A = 1f79f5b5bf78c9700d +B = 5bd1734ba0f0e59c2a25 +M = 9ff3fdfb5c089244f327 + +ModMul = cbc280b5106c2c36cb31ad7e7c986c +A = cadf6482b769e83ce7f7277dd +B = f9862a06da1a9c89547b76c61 +M = cc36144c88139ce921d2fd1740bc4b + +ModMul = 3813f2fabe016e19fd8e70687ff473651a5fbb4b +A = 9c51a5bacb5d9f055a9ac2962 +B = bfed5625b21b4e82d1f105a0b +M = a47977acad7c5deeb683ccd265cb30cb193f22a9 + +ModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478 +A = 997c4a7b537d9500d73a205a4 +B = c679ce666af284a459ae5a26e +M = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9 + +ModMul = 1a90c92fdb +A = 94fa7bb475 +B = 564b0a3339 +M = a1501bdc75 + +ModMul = 5e7ae5470686bad7996a +A = c725797912c6c5f30d94 +B = 3a7f4c99ee3f5fa9582c +M = cc50c8b7408f09a74973 + +ModMul = 72a15b13bcd1b63747342a6be8f0f2 +A = c33357af48a2df569e3c11ce6 +B = a4b4c5c14d7796adab54b6cae +M = e22a0fdca62a37f4c8a61c96a429b9 + +ModMul = 31e179bfbf65b0695dde36a4fb72d131830dcdd6 +A = ce8d3adab8cbf15c332c0b289 +B = 9333f94eeb7d7a86b82becc51 +M = a532a76bd5cff409b580d54d12ef75ad8179b381 + +ModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14 +A = 9a2b56a54bd0727ab4be57ff2 +B = edf1781b4296567990773005a +M = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1 + +ModMul = 917bcdb402 +A = 55c7dbd314 +B = 997b29ef79 +M = af5b4cbd0f + +ModMul = 660c4bb2b771f523a4fd +A = 43fe52461d5139620a11 +B = 1f8ec4b67de1db54ddda +M = d0458e215b7e6903d96f + +ModMul = 7aeff02c143e4426fcbcf32bd1277b +A = a2671586369a990dde7829f36 +B = c7ff67937c900daccc0ab1d8c +M = 8ad9c1d4d3cce681d1ae27c27982df + +ModMul = 4b153d57433f0f7276674d3484e9bd0d25227d07 +A = aea36cf51dd2ce06c66b7a407 +B = 80c9fe5bb0afd2bf8b3644f96 +M = 8cc22a67ed7e5a7a2322aaa09ec2be94998494f9 + +ModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0 +A = f67636b03821c8f13f21217a5 +B = 8473a29f4ae33f36a0d2c6dc0 +M = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5 + +ModMul = 17fe4644a2 +A = 912611576f +B = 7a10d36b80 +M = c5fa605133 + +ModMul = 8159b23d4fd697b4fd35 +A = be2d646e76494439e60 +B = 60fa770d05ebc69772b2 +M = a6e7c940cd749925a85b + +ModMul = 7c412dad5c9fff91357bf181caf2bf +A = 80f476ed5acae75b34ed54c52 +B = fb818e2bdab3b5f4bd84db3d0 +M = d0339f7ee41337d8462d1a9c207d1d + +ModMul = 70432c749da4ade2c38237545ebfe6c4c6a92f6b +A = ee9c92de52210e61adaa6eb4a +B = 8ab55a85b1abab62d33e75fe3 +M = cd3faa6de4cb62fece4c3f94492d457834a6a041 + +ModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28 +A = bd162c90bed25e84dd5b6b77c +B = d887ee03020c5df356f091db6 +M = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f + +ModMul = 958951bd0f +A = 12bd0d3375 +B = 668bb65b4e +M = 9c617dfaad + +ModMul = 8a109ebc9cbf86613e43 +A = a3e7019f1bbc35689a77 +B = 3189ecd3fd4ffd0229ef +M = ddadc50600dff2abc1af + +ModMul = 2b4d9f85a398c852b3a0cc82524619 +A = c244fd157267f707319ba6c6d +B = 8a07018a748992429bbdbf326 +M = bf3813fb54f749ea5627f59ce30e07 + +ModMul = 28cab7d574e6dc56a6a622f8a7523cbb8dcc5e0f +A = c9909dcfd3a59a3cfa538b267 +B = 8bbf89cd5a4e24adc2d8c646b +M = c8f02682b9d480ea98faaca53b747ced33ed0419 + +ModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a +A = 8019266c548982a520ab48eff +B = d33c3e3b13576dcdb3ffaa796 +M = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1 + +ModMul = 3eaa4c99fd +A = 6fc42faa85 +B = dd0b4e318e +M = fd7f22301b + +ModMul = 56b6b811ced3433755cb +A = 145573d17cb0c996c69 +B = 9d3297d5ccc184896822 +M = dcfb3b383506239e83e1 + +ModMul = 34315b6bc6d3690c28060485ae331f +A = b963a26973894cfb42fcb2d22 +B = e8523304bbcdff1a0ed4141bb +M = d7a379aeac7d8cf94f19e7924d35d1 + +ModMul = 2ec9466e8b3357496f07e37ba24d36a237883846 +A = a75f3904e564997695b6707eb +B = f9f47bd779834dc1f5fba0654 +M = b3ae5abed45d09c4dc5abcadc3ac9abebe1949ed + +ModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044 +A = a38eceb9c551f0e69a544072c +B = d5f8e7c2d534b2b8985bfd213 +M = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7 + +ModMul = 172f2e2e22 +A = 1584ff1055 +B = 2e0aee014d +M = b904cb0bc9 + +ModMul = 122c10d3200270b9eaa1 +A = 86fd189e62a6dc1e4ba0 +B = 5235635f7b0336f5f235 +M = c93da97d0e95fb63dc4d + +ModMul = 3e461e10ac4eb749512097fbf76616 +A = cf4ce10cbca07164f3812f89c +B = b7e4639c233fbb0f923fb5104 +M = 949647857e1406871593fad5c30101 + +ModMul = 88117b59d9fed79dd6aaf083ee938215a995a221 +A = 94c888795567d434123d441a7 +B = c60ca79e61a352e34e0f78bee +M = d2553a7c5dccd639a3927697a2e1af03845f2f25 + +ModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c +A = c170eaddca5295d6ec6272dc2 +B = f94a5685ced7661df2efbd34e +M = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd + +ModMul = 1110cdbe5b +A = 5db02b38f3 +B = 3369537903 +M = a8863f7979 + +ModMul = 90fcc5f3a346d3d4ea4c +A = b93373680ea0feeb31d8 +B = 37f9dfaf0e180be64bd5 +M = d595cc29237d1c19e2db + +ModMul = 8623a9997e514cf3c1d06c33c14053 +A = b396f5ede6212f1fdfc7e7b77 +B = 81a1ddc18306f2d2e84030148 +M = a6be32a91b34857842255ef8b1aafd + +ModMul = 63f8f0254df06356f5cab8941b77619ad58025ed +A = 806b2627b08d987438f920bae +B = 83297039f4aa8efc1a185fea3 +M = bb8a7e7c19be02c25cf5682a0eee655fcd5b69a5 + +ModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438 +A = 930b04224bc097ac1d8bae8be +B = b79496a80e45212c4663e5b64 +M = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1 + +ModMul = cd93b5b8b1 +A = 47a51b2d5a +B = 86d6ba5155 +M = efb0ad3643 + +ModMul = 2037821ea789118bde0a +A = a92215dcae19be637ff +B = 93b9a3664a406737958f +M = 9df360b69ed26f610253 + +ModMul = 3bf11785d28ceb668dc55b870faf7b +A = bc8758854dc48e057cb6210de +B = f03ca689620a77ecd8a6f0de3 +M = f3ff0747d6e5f34a0ba4200f579259 + +ModMul = 7b30b44f75ed12f54136858ce4fe77d00e0952cf +A = 993cd09f3e46423a8ba2053df +B = feabee384158032dd013dc08d +M = cd0b21388cb2033b1e792ec4078334df70b6c8f9 + +ModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650 +A = 90e5d18b017118177ffb080da +B = f8e7e09032574f6c66e623ec8 +M = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11 + +ModMul = 8fcd412054 +A = 2e7f9b1a +B = 6283de2c9a +M = 9bff560ae7 + +ModMul = 57d0d3b79f1e2f3632fc +A = 2f8cc403de5af54cfa39 +B = 3b798c3ead52878dfb2f +M = 805e6cbde400d4b4bc9b + +ModMul = 23331614e88633af879201f568c359 +A = f21f19da4b20980979a645dac +B = ea752050b79883dcd69222536 +M = aed3faf4c88f7c4afe257c5ed90599 + +ModMul = 56dcf9ae1c787e773774df3c8762babb4675a212 +A = 9accf901fa599da05fa6ab5ff +B = f7f6b9b1d7bae06237532e39f +M = b5bcd776bb2eb0805ade3c8b47e883962d3cbdf5 + +ModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0 +A = 8e57680f213d088ff1a1e7db3 +B = afebecc9943b0093f87022940 +M = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb + +ModMul = 143ae78a29 +A = 334abb952a +B = 74203e7a50 +M = c9535a9505 + +ModMul = 897a2b57e69f5a1469ea +A = 1ec8ca0ea4fed52bdbbf +B = 3a6273cab05e478a57b8 +M = dcb33163a8ea42c1ae6d + +ModMul = 4a2c10e90e2d37111db79a44d3e31b +A = a90e7bbd63fc4af6de83029ee +B = cf09c3dd50b41afc7045e057b +M = 8ab85d47e4270116a64f97dc4f0f15 + +ModMul = 70f94276c9d85fd3f71edfaad6051456f754da85 +A = fa3e9ff6e1aa1fb78e51711cb +B = b115ed197c50b7ec4040ca255 +M = ad63f69ef1346e7549ba71c13b24b279f53bc9bd + +ModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac +A = fc41a9ce06e882942f751be7a +B = 881c05a51d1ba8134d126a48e +M = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f + +ModMul = 4e0051898a +A = 2a06523f70 +B = 651b5044f0 +M = 9da4eb09b5 + +ModMul = cc8274c88d6affc3742f +A = 9ccf0133f9628532f4f6 +B = c1d80907057be7a67b01 +M = d6e76e362da831f32685 + +ModMul = 568f15bed5c4405be9dd04673a9c46 +A = dd6029c3196feb6da7f0f4a48 +B = a5f6745f2cb64913d1d3236d8 +M = f62f02c9b9ca8993e3be9a02b444bf + +ModMul = a629452d5ed19df040eca26eaca37d82c0fb1d8f +A = 963c51a9415b03e85ccb09f25 +B = b1cffe333afe44311cb968ffe +M = ab2128698d498e8d75455033cfbbf4487535773f + +ModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf +A = c3b33f391e78bee97ceddf313 +B = a9136f3af450fdeb245eff425 +M = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35 + +ModMul = 8735bd486d +A = 563e15c52a +B = 31293264e1 +M = 92f4b193df + +ModMul = a541f69ca163b288dd0e +A = a608b48c1dcaa18424b2 +B = 891b0b296e911068b00c +M = d4140921f4b2c84f1eb1 + +ModMul = adc1b7cf65967b013d046866b4ed9d +A = e97941448f65060cf63ecd486 +B = ca68936f76cb87a8fbdd37311 +M = ebbca2482fb82eeca2866057cf1179 + +ModMul = 44aa9f0dd58d4510a7364e130698b34eda23a632 +A = c11f83f01bb964ffac93a2e30 +B = e05ee40eea39f4538d735193d +M = b5e8b511738979dc740a6a1f7291cf4561787be7 + +ModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a +A = acff8da571e1c96810bf95707 +B = cdd23e5504cc26d0c34a62b06 +M = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7 + +ModMul = 193f453197 +A = 8cb3078675 +B = a8fb003a87 +M = b60ff22f4b + +ModMul = 849c26c8cf5cae426a80 +A = 5d1e3d2b4d038a0a34be +B = 34f70325565bf0523314 +M = cbc189f9a732cad8f425 + +ModMul = 9a4e64ff530c53a4c6c5b6b5021920 +A = f53b81723cf74f520a61e614e +B = 9d8ac2e6b839143fdd079a2ff +M = a115375435151798f3644bede9d863 + +ModMul = aac303a4623e80158af1cb3331965cc8e3184edd +A = cce0a88606ff962fdc37e72c9 +B = 9840a500a2051625c517104db +M = b99dafdbd91ec3c05791031df5e193c03d6a441d + +ModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf +A = e6f48c027284856aaf3b96425 +B = b4c326f72a6a22fd4b93ba5b3 +M = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab + +ModMul = 8b0929adbf +A = 61fdf77ac0 +B = 8892f05400 +M = f12b3766eb + +ModMul = 91b57f353307b173679d +A = 33f8e73752072b4b5cfa +B = b4c730f79f4f2c07945d +M = d41be1d8d2e5753e3ae9 + +ModMul = af04c564adfeb120bc4770bc8c650c +A = af151333b3d4cd1d29fd801db +B = 9ccaac44ff91be11b30bdcdd0 +M = e0bd6e70d5f5ce08fbbfd48d43101f + +ModMul = 1b8d623796a5065d9e993a53a9587a0fdbea1bbd +A = a2fd08df2d4eab0cd6d29e213 +B = 92c9d26ae7c215b52199ee28b +M = cd529f4cfa46f3bd3e7fadf167fdc02f6f881da3 + +ModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd +A = 855f941d085305725da617f5d +B = 8f09b7d2c36e0340523da5421 +M = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b + +ModMul = 2d278e089 +A = 59d20a1716 +B = 8e2a58bc75 +M = b3d61ef699 + +ModMul = 2f937ce359d0f6cedd1 +A = 1019d11d26040ffd5b1d +B = 7cdb6252087423d43e08 +M = e8f537323004447e669f + +ModMul = 6567332e25af83089f7458786ab0ca +A = bf9565e9f8a098894447b58fb +B = fc867626f268c24cc0ab7bf8b +M = 930f39183353363dcd822933a438ef + +ModMul = 3692e73ad1d91ddc19cad3808eba2c5fc88e2bf9 +A = d0a42ce512629f0ffd233a9aa +B = 97f6d3c4c655c7353a62d6ac4 +M = eac2ea84851f880214b8f40f881a2e56a6ba6f2d + +ModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58 +A = c237eb242c40960861c938c08 +B = ab2f481f0d768eebd90d2574b +M = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f + +ModMul = c952f9aef +A = 81973bbcb3 +B = 28ddee3bf7 +M = c4a40993c9 + +ModMul = 241dd53d93f7bdbbb2ee +A = 2136eda4495c45c9f96c +B = e74c4baa8ca3f6b7cd5b +M = fff4594e7a5f0a1d3e15 + +ModMul = 5f861ed8b0aa835761613e6c869cfd +A = bfc5c1572086079f5f5d18d1b +B = 95902e14923c8010b7e905178 +M = a819c6c109d623f9b845aa23712c9b + +ModMul = 5b8ab089c4e4c6804e48a2bc1d218718b3a32598 +A = fbe65d3852224a812c432672a +B = d57a3f38da966d2471d70a048 +M = b9e6a626d3ad026d14248fc90c882bedd64a1f13 + +ModMul = 761438baf5b02dc095b7040e082da7b167c2b9ace956284ed +A = fd91701ed2151f8e994bf4ee1 +B = 88b66e735b76972bccd9db182 +M = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55 + +ModMul = cb743c97a1 +A = 9c69ca9b60 +B = 7488f48f5 +M = d67040ed0d + +ModMul = 931b2bee1bc30725a31 +A = 650f567b544ce02303d4 +B = 5858da30dd1fae88a675 +M = 91ce30234bb29fb9e833 + +ModMul = 5b4f262cec958a20390b5e568ccdaf +A = f7e240e8a077e8e87506db2f1 +B = f8653fe64e3bd414782f51634 +M = fdb8225eefc1620648737d31dfe1f7 + +ModMul = 4c011d1ddfa30c901793cc6ce74db47584cebbd1 +A = eda8e9a9ea3cdae17bd50b1b4 +B = 992e8ef4a45593e4ceff67876 +M = 95e2f120cfcefbada1058af6c8853cbebedd5763 + +ModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466 +A = ca6c51ba2f410d09bf71d60fe +B = 8bdfa8fe5ef3b2ad02bc63c4d +M = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb + +ModMul = 536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d +A = 9b474b6f7d7f11dfbeb7a0724694f2daf9ccbaf2ec13269b5ae3329e8df95f7833baa68324509dcddfb5afa1d14f2dafc55e2c225475f16fb396beecc7a66dee +B = d74a5081f00af2361c3537642c06cd47aae7e366741c9b4785e185af8b328acf3e2ed71e3b9a4b6fd49d956eef76740b3c6ec5850a90e7e444dfeaa7214c5eca +M = 5efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb + +ModMul = 6161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634 +A = e7d6b74a1af0834aaf93e09a6488340b661449ba2bbc73d775e7d828163813ddbcd82719351879a6d67ab6b518011e1db43a3d620d1f24403917691d15ed6f90 +B = 3ecc8fd3103fe52a7e73ec4be4e60b69584bd886a030f017b482bde9d4b0b964ba8471cb32b3e9bd49864d9028a22d6b6b46be0451bb4222c3987b74a509f8fc +M = 7c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59 + +ModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76 +A = c221d1f0d1b7efe7e078dd01bed773f8876fa324b3fe91985d47d343e7f3878b457dae2f9ae68971245278a1d23cb541c56b94dd9ac43a9fbe28a46efc627651 +B = 49f94c19ff7ce990637c3d2019ed66f7e6dbb1442b04a4593cc480521b991cb1b878f8c31903240f89e34336d9e6785433617e729b71adcbef622a683357e035 +M = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb + +ModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540 +A = 3fbabe2d65f443e7db0a6f332330ecc4d1d40e14fcb510499552020405cafcf10a50a5ee47cf60fd8c22a22b3f753b4167c213851f32109babe4b5c298d6c4cf +B = 62e5b0f887dcb1f1794bae7dad46a066f810cf5f82a1eea99207b5f0fb0ae9084c5e62cc97b2672b1cf4cc1400a19bdcb093c97404876b584a6482931e7ba9b7 +M = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7 + +ModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db +A = 7e1fd0bd9ab0aa75b264475604aea09f24239f94847ce2549d43b71890c0549938d167adebc7890d3c492b5874da7bf18d895ccaf1803b9776820598928b407c +B = 5e54e5185bc86f16177f1354a57d36ac2980def141b389e4bfda134fae7c158009ccc61ef66281905128b6297f876662104ead2315024f129c56eaa387f80b4d +M = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401 + +ModMul = 145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4 +A = a195e4315caa8cc0707063c7359c28139d4dfffb57eb726156336e13227ad9766ea1fc99152893ebb194fecfc153d47cb927a633217328f05e4d8782aeb89d04 +B = a97ae97dc7e9a224cab94ecedc08d0cbf7a012dc5209b1e1e8b5b843fcf61e65db3457d6085545a633be47b742e8237cc716357ff5bce9b00e23671ec1d049a8 +M = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1 + +ModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658 +A = e6b97c11ad44fd451d168d65d1691d2220db8c3b6c8436d59f4c1366aac52558d0d6b61f5d6966460a4a31085fac711e5a09af5563d938963555d4730982eb0 +B = 6805eab5a4da534f07def6d2c320a6cbdfe4831fc2163dfcef740607b3181d8647bfae8f8c16237c1c1c5d14b9e3417132f81b3a7db4b7fc11927aab30dca590 +M = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227 + +ModMul = dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764 +A = 7fd3310af09a67e0684dcd8e3b4b651c7c13c2f6a0a47b59a7f5cd8bd80854d1d4fe02eaa61843d6bb2b87f99d8ec4842864681eaf056538ffff610c231e1d +B = 15f1661c59ee9f93400073e18a91503a93d47537d2da5cf5e4bc69ccc87b07bed171a95f1c5eaa9c7d7ab207ab3f1f7634c5d16e706969e869364207f61d84bf +M = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab + +ModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2 +A = 8e3abb1f24e1f91496db99be9409f57f67cfb6e0e33d603a2a31e1309f1d0bbdc413c3e4fbb5e3d923f683afa9942b9b9fad6a6e558b2297889fff47ccef7d23 +B = dbdf5940dcd68127d476badbd5a2f3018aa4d8db79f81337ddfcb108637110b934e946d3284ec09d5255605ad72424f1894238ee4f7964dffc27fad838532321 +M = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93 + +ModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764 +A = 5137697bf48982edd869e4a42f3cb858bf65ad5b25d1c0e8b75d054460d0944ecb5a6924721c5728964d84231c7ae808f556837aefb23fe3ad36aec9f5f60f20 +B = c79554304620f8116b9a8bb56f6a23620e9fd504f7163f732e1e6367d25c6ff98cb01d16faf3e018dec6a067d1204a6aa95470598ce757bcfbc3ab4f5d8ec88 +M = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735 + +ModMul = 985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233 +A = 908bff40440aaeee6c90b6312dc017c3bdae884a9074e02b26f01be1f018390e01f0d111f99a06c16e20538df8000d4066cd4bb3628da88a3a5cc240cfac719f +B = 6ebfe9fe53909876784f9d6e5dcca4cfa9463fbd8426c5bb8890ae84c2fad119615fe1e1f2ee5fa544a5ac713ed1da8c1e04f282f1f1b9fba4b4c4bd9db20538 +M = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793 + +ModMul = 133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4 +A = afb695e3e40347f60a500e01fba4df1c1f2fd4ed79e3f65913d82369f79d80db6b3978e6351c70c148f572b9c0c2b1efeefa605251b3156d9b66d240467e550f +B = 8855046dcf50f80f278227d5260b9be53ca2e4a1cfe1afce4d35b11d0fa17a36a8bee8126e13bbb318d476becad5a935e9d160fa481e1437b292bdc169dc7d45 +M = 3eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47 + +ModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9 +A = bc2baf0153a4598f6b5f488c43b2546cadfaca2c1931b919f98ba71835a8fe78886da1fea25b194e60ed6f9e0ad23c988b64af9278155c1722dcf4983a1566c2 +B = d8374d91fd3c523ecdd6bdd265c9a8958dd222f9f0e25454fd683bd86d7900a273b56f1f47e033c46527e32c721094ce6bc927d25fac05d7fa6db4d7a6773c94 +M = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3 + +ModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9 +A = efed8e442154b1eb6c75775cc23e01fa65c9c361e222da123d07daad3039f305e7102edff23b65c333f0caae4f7929857c3169f4ae47c9f0fd920c38eb42bf2f +B = db05415ea90269a74b0919ff772c148c0eeb2ff9dea76a6e73e82eb86bc76fb42308b55ef83a769a91d23b7840d5d2f5129f15279dfab7cd8d63778acf202f26 +M = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479 + +ModMul = 40b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d +A = 6500f3cf686eec4e1f243616ac0ea8e8d11ddbade490b86baf231e7b2fd55968ee14b6bb7badf8c898874099831976af46bcbfbfaea10d49aa803c6e51238e2 +B = 1fac744fa1e26e789639e049679d0e2eb57336279f09555e10210e7143199a3df5fbf5294edc386ac762fa3a3b0b4bc28945adf21a8af747a29018bf76d3710a +M = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1 + +ModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113 +A = c4a5737a9496129a136753f8c2e52bbd2660f2d3fafe4ed702900b01c14e506d13e3bbeab19b357e5ba9fce8a4fc3dcc469406a16248d6fb53862781fd9d55e4 +B = 444e5a673eeb37fd3b4f6b6f5133b0f46c2ea532e1953da4a0e144407a8e2534c5ff40cc9af7756e5aff9df57d938fcedaffb868dcf4e458b36f506ed7fe0ce5 +M = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817 + +ModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855 +A = 4351965a421c75c5b4c251861e53316a300ed7983e27e17f9308420f0d2cb11e9c476294fcd9042a525bc1a044bb442d1d9f853c9e07245170e0e2711010cd1c +B = 4e1046647c362c8f9c414be54075b4e9d151c6fa0c3da40d90e6042625947ca2c9f20cfbcfdab8666dac5a15f6cda9d47b09f654131fc5addc07e382c9639323 +M = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7 + +ModMul = 4452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6 +A = 9fd1cc81981bff977244c044146918057ad06d3cc26edfb8fb4118ee02b959d45555f9507ffeb23c3688e29ccdfe5f583fa3761f6727573542bee8ab5f5b600d +B = 856e6a03b5c93fc19deea51b3bfe42c810c5bcf9ffbd08e2625eb209baf6a4e24943a3c090d89c1f70aea9f0128e511fe92e03715d917168c1e1ca77a3a8731f +M = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b + +ModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2 +A = add40f1dd6d4a2414b17f0c628eed9a8f082f3ad1f34ec41935fa86b34d4505b22ea80c062386a9ed63f95c67e55c686f837bddf8f4da791f98b08c02f32d4b2 +B = dab1caaa11d5a208b7a6b7a1d6482a4859daaba5e3a77b1b1020e8ae62a664953dfddd0b47d40526e7a3c6a5363c6d41dd9f529fd8b58d5d31bb67e745cb71b3 +M = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955 + +ModMul = 36fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df +A = 52ee1498bd6a1677db801ae2eab4951345a1fcf8fe7d38e3f28dbc27fae508d87c9958e02a375ff4891b88ee916b96331e7cc082615faa028f6d541b5ce37876 +B = 9343cfa074f50c20e8472f8f7c4a7d330aa30ee417ed8027a4c956e84cc5cb31d5411c14796d9325fceef79a51b5d8a4c89182ca273ab633e6a7b22a27352300 +M = 9d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9 + +ModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad +A = 19616a82b75b08499d4b1f869df2db8f71398672f3f97ffc6177a4a5aa913605ce8a6ab5f778cac508f0b3f2aa680b01ccdc57c0fdd6cd678a2ff2dcd7f01f3c +B = a5643a9a9fe3be4134082daae4ee7dfd85d9452beee856fd939d3be9788b6bebcf3571c67ec481ff9b20f70d23e82e2171b1d0ddf0a9435b40115d32aedb6811 +M = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937 + +ModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6 +A = 8e6cd7639b7c134b53e6ae6ac5f51268da83ed09e8e96d65e4bb130dcdbbab9e48226ddba6efe93faa510bde8ee92f2a641774c4272b5a2f88024b77a2cfa110 +B = fe4e8109a49b16b96871e384564cc096277dad4e1bbca8e5feb33f140a4fb800c8f3096b1bc7042bccf249aede88e6055c0db609f94e214b1251eda494be724b +M = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025 + +ModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d +A = b0fd7a936b0908ba6fa797e4b855d673ff85d665ef3a345e560e2c0049becf5c25b6c0068dd617ab47a8fd151939ea0631f86806ddd40e557933c0e880fcdd0b +B = 105c87fe2b1bf0be5405ca0d530beda1780f0045e892d7810f8a8abbe890f0a19de66497cba55bf38e190c52992467c22a320c38a4bd167f774ed812f1271d5a +M = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335 + +ModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66 +A = 2aa4a0a73df11f4e60956619d0b35eaef45730d619f9b920298e6d369b9861f6411de28a34af038f288d7a3d6a35b10c8082b8ad0fb275a8f67c6832ac46ba9 +B = fae1d50b72feb25da2581829409391bf289cd9f730c99d265b5b2d63889381cde4adbf85c3998c2478f2866526b8f64605d75765edd09b78ea45337207d173 +M = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1 + +ModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995 +A = b0a0f9d05d144d2ef257c1e63a7127a3b8e0d8b64ff8f6447618560593574b5c5da6258b274efc28da0defd988bef1efca0f481f809665a78954b36741d668bd +B = 10901b9dbf0016cbcc671da75a75b7a6ec6a66dd17b53a97344864b08f037098537380bfb0137b6becfc36a75206686d16bc4eb8fd54299494374e3f383d9b10 +M = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9 + +ModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c +A = a7714b249eb0f0cbe3e6fa0b04e895fcf14c404876197defafc6b57026ae7e5e993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b +B = b7278ecd154ef5243ad973ead291ea186acb63e09977e644a6a9fde195d1a33993fc47c1819581adc03860ce07f2b7877a3f6d0912c0cbc659f5f6170a1cb2b +M = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09 + +ModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688 +A = 2b65f491caf0b5cd9c66c859fbcadaec7213e6b848884638791b1620d6e4bc9dde087af0e7329d3b15a45df2d43ebde61b053ad7f63917aa922d58b4f3222620 +B = c1bfcdb34b0766be980540dc3256b9ee4158310fad2c43cf24bfafca08ee185647043f5842a9d9eda224449259341b7c50998086434528d47661bf5762a7ab5f +M = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9 + +ModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15 +A = a3d8b12a2c8f4021ca045a4e4903687dea63ee7e88893b1911aea77efbff00f8f5c7884cbafc71f59fa2636195c2ebee61edbf642923f34d87ba5eb49b06a7ee +B = 3231829c81b26dcac432b502ce22e126ab564922b1e9818cd3da46edc5ce7df026d0e515809c97bcfdb9666581efbfd364437ba9959dfad099f90472f97c69ec +M = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9 + +ModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244 +A = e4ba620125f58a63fe12fbd3eccdea477d56b120c76d5d1421bebd74e8686b4093f8169070453ccc04b63b173568385313a1d9c841a4aa82a61cb84d4286a941 +B = e87aaa990307855f8e5f2e5509d2ce31dd4b13bb7199cf5fa0593e350326e222efc33a26c69245565d6ebb5a484cfef7d2558f22dea8054d07831d536803d0dd +M = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897 + +ModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6 +A = bd64b1db27fa7da4c92a4ee092f58a2a53ed0f12d009fe13b36d5fd585defe778fafea4a60e8fe567d03e9ba3b72b189e22504ae8ca6aad7c2ac0f44abca2f6 +B = b487d8116198560d6c5b08c7ce63b0acc0c98e6f2a8d709cf4e3a409edd55f64d72fc27a70dc341e280ff5a1b09fe131773d466cb31991d2db23a2a86d225c80 +M = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923 + +ModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385 +A = 4181ee3bf9a98bcd49eaea243a179cddbf160981efc720685c7be1dfeb5aa552685a2cd46f340e1e1da893b3b460692fa2eaf6c100f24a14f239e45123242d53 +B = 77cd04d86dd5da322af78be54246dd6b7af490d903db1db03cbccde535570b81c6053a84110c07f097540ffe7510320024b7bafb77e9e239761def76092e1d59 +M = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5 + +ModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f +A = 1c08cec52d96136fbd9078b7b8db36ab63b86e19dd3dba7b2e3190ff566180e89dfee9423fa4e99be2187eda6aedfa86b9a45eb1e4655257315ae6a280f0a6ee +B = a8b4bc9647d8df9b7c76cc6d0f2248cdbc41f5da9c061f9864aa8415c9557582cada456cf23cc32d47d1fc1caf19d36b398019aac4734e10f55ce3cad419e5e7 +M = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed + +# Regression tests for CVE-2016-7055. + +ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9 +A = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 +B = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81 +M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf + +ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9 +A = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81 +B = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 +M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf + + +# ModSquare tests. +# +# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M. + +# Regression test for CVE-2017-3732. +ModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001 +A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000 +M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff + +# Regression test for CVE-2017-3736. +ModSquare = fe06fe0b06160c09 +A = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc +# A in Montgomery form is fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffeadbcfc4dae7fff908e92820306b9544d954000000006c000000000000000000000000000000000000000000000000000000000000000000ff030202fffff8ffebdbcfc4dae7fff908e92820306b9544d954000000006c000000ff0302030000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fc00ff02ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00fcfdfcffffffffff000000000000000000ff0302030000000000ffffffffffffffffff00fcfdfdff030202ff00000000ffffffffffffffffff00fcfdfcffffffffff +M = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_sqrt_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_sqrt_tests.txt new file mode 100644 index 00000000..64c752b9 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/mod_sqrt_tests.txt @@ -0,0 +1,341 @@ +# ModSqrt tests. +# +# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime. +# ModSqrt is in [0, (P-1)/2]. + +ModSqrt = 1 +A = 1 +P = 2 + +ModSqrt = 1 +A = 1 +P = 2 + +ModSqrt = 1 +A = 1 +P = 2 + +ModSqrt = 1 +A = -1 +P = 2 + +ModSqrt = 1 +A = -1 +P = 2 + +ModSqrt = 0 +A = 0 +P = 3 + +ModSqrt = 0 +A = -3 +P = 3 + +ModSqrt = 0 +A = -3 +P = 3 + +ModSqrt = 0 +A = 0 +P = 3 + +ModSqrt = 0 +A = 0 +P = 3 + +ModSqrt = 0 +A = 0 +P = 5 + +ModSqrt = 1 +A = -4 +P = 5 + +ModSqrt = 0 +A = -5 +P = 5 + +ModSqrt = 2 +A = 4 +P = 5 + +ModSqrt = 0 +A = -5 +P = 5 + +ModSqrt = 3 +A = -5 +P = 7 + +ModSqrt = 0 +A = 0 +P = 7 + +ModSqrt = 0 +A = 0 +P = 7 + +ModSqrt = 2 +A = 4 +P = 7 + +ModSqrt = 3 +A = -5 +P = 7 + +ModSqrt = 4 +A = 10 +P = b + +ModSqrt = 0 +A = 0 +P = b + +ModSqrt = 3 +A = -2 +P = b + +ModSqrt = 3 +A = -2 +P = b + +ModSqrt = 2 +A = 4 +P = b + +ModSqrt = 2 +A = 1e +P = d + +ModSqrt = 2 +A = 1e +P = d + +ModSqrt = 0 +A = -d +P = d + +ModSqrt = 0 +A = -d +P = d + +ModSqrt = 3 +A = 9 +P = d + +ModSqrt = 8 +A = d +P = 11 + +ModSqrt = 6 +A = df +P = 11 + +ModSqrt = 4 +A = 10 +P = 11 + +ModSqrt = 5 +A = 90 +P = 11 + +ModSqrt = 3 +A = 80 +P = 11 + +ModSqrt = 9 +A = -e +P = 13 + +ModSqrt = 7 +A = 7d +P = 13 + +ModSqrt = 6 +A = 37 +P = 13 + +ModSqrt = 1 +A = 1 +P = 13 + +ModSqrt = 8 +A = 1a +P = 13 + +ModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec +A = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4 +P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 + +ModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d +A = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a +P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 + +ModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444 +A = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc +P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 + +ModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4 +A = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9 +P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 + +ModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4 +A = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf +P = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1 + +ModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66 +A = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550 +P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 + +ModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d +A = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2 +P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 + +ModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387 +A = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269 +P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 + +ModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87 +A = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74 +P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 + +ModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23 +A = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7 +P = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3 + +ModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba +A = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a +P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 + +ModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc +A = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b +P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 + +ModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a +A = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07 +P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 + +ModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080 +A = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194 +P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 + +ModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c +A = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c +P = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95 + +ModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247 +A = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654 +P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 + +ModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065 +A = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090 +P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 + +ModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d +A = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe +P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 + +ModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14 +A = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34 +P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 + +ModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0 +A = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079 +P = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7 + +ModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c +A = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79 +P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 + +ModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106 +A = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a +P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 + +ModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e +A = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9 +P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 + +ModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096 +A = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7 +P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 + +ModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852 +A = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0 +P = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659 + +ModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077 +A = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024 +P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb + +ModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71 +A = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7 +P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb + +ModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0 +A = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d +P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb + +ModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5 +A = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b +P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb + +ModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556 +A = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840 +P = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb + +ModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f +A = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f +P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d + +ModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029 +A = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb +P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d + +ModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e +A = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5 +P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d + +ModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c +A = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e +P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d + +ModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31 +A = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72 +P = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d + +ModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765 +A = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39 +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + +ModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a +A = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507 +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + +ModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb +A = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + +ModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f +A = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + +ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186 +A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81 +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + + +# NotModSquare tests. +# +# These test vectors are such that NotModSquare is not a square modulo P. + +NotModSquare = 03 +P = 07 + +NotModSquare = 05 +P = 07 + +NotModSquare = 06 +P = 07 + +NotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e +P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/product_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/product_tests.txt new file mode 100644 index 00000000..8b596296 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/product_tests.txt @@ -0,0 +1,1014 @@ +# Square tests. +# +# These test vectors satisfy A^2 = Square. + +# Regression test for a BN_sqr overflow bug. +Square = 4000000000000000800000000000000240000000000000000000000000000001fffffffffffffff8000000000000000400000000000000000000000000000000 +A = 80000000000000008000000000000001fffffffffffffffe0000000000000000 + +# Regression test for a BN_sqr overflow bug. +Square = 40000000000000000000000080000001fffffffe000000004000000200000001fffffff800000004000000000000000000000000000000000000000000000000 +A = 80000000000000000000000080000001fffffffe000000000000000000000000 + +Square = c2fa18e1d110a4639781 +A = -df6a253c3f + +Square = 4805f01d379f4ce8dc86ed269 +A = 21f253ddb5a6d + +Square = 57def107babc1c2bffeff858947e69 +A = -95fbaee5a09c86d + +Square = f3b01f7941961b3f5cc3361e3ac82423690 +A = -3e71292dd4ad3ed3b4 + +Square = 5e2d9c36d498ad1e8b6113f442ac513eaca74601 +A = 9b45cf6c7a43d910dcff + +Square = 7b7c2eb3fe55615e422b41c6f725341527626398cdee4 +A = 2c7314e72a2ffeef170de2a + +Square = af57c0ed328886642ed5d631b375fc89c03a99f1b427c6bbd1 +A = d3de077f8286a04daa9c497c9 + +Square = 4d9eac3058e6cbc0d12e639ced961c02ec1870afed62fdd44c67ce4 +A = -233da7e87ea4421ee8fe7e00c856 + +Square = 83c292d277fae28cfede74e8e80eba11dc132e16f78cdf64595c12c7dee4 +A = -b7a8aa7452678abd45d2ae6c349e2a + +Square = c80e07dd01f9d19a5cf7f3c328ccf4de70fdd113de69382701294dd29674b9a90 +A = 389387eead58fef2c76b5cf920f35c5cc + +Square = b9f69ca47ac855830fd7ed39c81822c520880c51c3ea60d3ccc106db37fc2b04c47831 +A = -da307c28ea67ca8d3117364ba93f0731bf9 + +Square = 81bbe3a13a22a73778233294ba0c132d9dddec111f768300f177468c204f8eab69b98e62d99 +A = -2d8f715bb32d410b4f475c4d000d56fec7cfc5 + +Square = f815ce34e9bc2e31e36e75cf49b2d15306d438a2a713b2a85b3ea156ba60c867c28cc65aa58fdf11 +A = fc02f2e1a26cd69f6a0e54cca4bbced739b43597 + +Square = 5f968707f58ea15c492ec9677be09c309d91164aafa754ab16ca47a411b5b2249858fb6f96135992e8a04 +A = 271b8eae3e96cc4900d4413d6c00b73736a5d89ed7e + +Square = 4aa616aabcdc7ad48dcfd40d71e00a3789bbf549ff39b3e2ebb52017cb56014941961a5a6d52d7a9980fc99b49 +A = 8a3d3f15e6d7d2130aebd8cb99767defbe4c7704e3c1d + +Square = 845e46db8c40f3f6f6f4928b5748618f021f9064c6522bcf2df004f8d2105e90cd354785c15a6cc32fcc77da2ea3001 +A = -2e0543ac8b8255ce30253cf2047a0ff353dea55a58551801 + +Square = 5dc5706dde9b326feb79941f08bd296ec3b6fb67270516b70fad9921438b9175f395310fb756b60d72d8e73e84ee8673cc40 +A = -9aefd7dfa709dec9e721f5c22867229435b2d6366462d0e438 + +Square = 63dc6565adba27974a66bdcc626596e16cf399541d679f754d9063ceeb320649bec09a940309dd1eae5fbba0b558939afae9689c9 +A = 27f8e071f70b0053d70eca9c6d1e28303b8da2d3c58083c2cc45d + +Square = cf2176449bb8b215fc37288b904ca27d5d410780fd054d2a190a94b405f6aa41970b41ba3cc43eaabb97c2248e1e21457949070ec0f6a4 +A = -e645c7edc27512d4b3170d3c5430d0712a25c13afcc09c9b30bb11a + +Square = 43194e5f12e828db6735824c194985108269ddec12c49a14658be3c2b7d298c2846da1aa3ecb7064e73c317af595601de59035faab6dc0fd911 +A = -20c3fb73a03217893fd4a9db6e53a3d83a8414d900213d0460dc91bf69 + +Square = fcee79e598f061157ca9416491f2eb069bb95a4d78a1d0538dab5c8008653db71b90ce3139e693ba284846be7b75d6b7aa80228420fe75599c12f090 +A = fe760dd61798c8f78e52b328fa27cfbe41b898de6e6bb4f4a684f038b5f4 + +Square = 4f0db9f9e6eff9fe7fc938f6d6f5e4fb017ffea0cea0f7c57f4fc1e5b2bdc00a1cb9c1e6c865e53309b6b73c4339b0bd485860ca9edde3019804902da6b61 +A = 23909968dd5d139994fe9baa0a7bbfa009b013df3859ff294c5872366eb7ecf + +Square = 4441ff36d785d18208481470a5b8ba8cd65a45436c39190dde0b8a2b7d00bf67b185d98ab5c4a7853423778d6333abf6b115dc9567a9f9c71916d3f9db3af82c41 +A = 84307277f79cfdf33d83d7093f1fd8aeb94499a7075ca32733b68fcf88e819421 + +Square = 50ee0dba369b0fb61d75706652487ca08043eee712ebb51399122353f77f13745ce2ef0d8f0ea7b3fd94e928b0b2b42c2c9141b5697b13b6d1f3d66c6a9186625b87e40 +A = -23fc02d45c820c3a4250124cc457fa3886beabb41d3c1e26f711309604eb253c6da8 + +Square = da11876b316d4891a2d650692ca776f77afd32a1db08f591c9579fd1053a4a46cf78b4e4cf417eb99eb067ff701dbe3483dff22e7878d2ef2b234244cf7a29d93f62d6d6b611 +A = -ec463653389de3689fe1881679b83ca65134a1498a3543168dd4833a51b23edd3fb617 + +Square = b342b4aff7e5bad38f7f532f0f32a3672f7ea6521d23652fa09ef7aeffcffe52f056ab1b54a0f3a2147f43330fd199d1f290988c866f61360dc4928c84b3dcde8f395120008472100 +A = 358e27805e2a56195fab2ccbe3f931a4bd14023ee56c8a191697926f387c40decc578cef0 + +Square = bf4045fd680caa514e9c410fb4404e5e3a381abee023d5b509d6dc0b97386421f55090af8bab5ac08e9b2eb8a36a64c55960be9179d564c5429f4ec595d03d12111defafb7359b418902b1 +A = -dd450a0fa0914f0d65a1b555baaaf9380eaf8d58b272bf9d95435bad53b01337ac8de562cc7 + +Square = 86abcdf183ca059257c2f6bb91efc9853f4ab42801d3cde88df72d4c904be184e93d6bd1af6fc21a6836c93c4e0a1f728b3722d568572f7ade418274ef2e6ac3463c5cc50990f1017e01cfb91a9 +A = -2e6b4d9eeede7a72b8d0fcf6429c7e30cf291352e1bb43e92c14236716aadc02c02f75c7e6aa8d + +Square = d5f37112733b097cab2bb11daa3d9481255060abd7bce42b752a7641a98e140922c375fcb68bf13d4326b374eabe3b01de0f8f6324b7b3e4142051c02d2f18ae2e748cf3c4bcc3fe157bc94227631d21 +A = ea087236372fbb01b80e57b1ae4edeeaa776355457e18165a5dc60ef4b6ddc0b127ef494dc44ae11 + +Square = 9e4db7885fa5f928ef236f99df3e7c8d17a5a21983ff882032817edd5658575f443eb9c5c97d95ee798a3809cda76d7a0ab9fde757a310e2f5cbb299ab88e92a5771027ab9f26816c02d0c97894da5976ec90 +A = 3253d712d4ada4c12dab41036fcf79b02e80d1a632ff6ccc44d3c1d08467a019cd6221507459b231c8c + +Square = cf9c50ee8773ba94c9e943989a35513fc370adc3622beb125252bb92ff9b258b81a497700e3bb15bcb23a5b3082c095f7a5d6eef20433d689c20a5427b661d43fb0f9b7d1b16d1b73b8fd59ed319a26c5eb92fce90 +A = e68a0812d2de2a922f24c4e63b4c33e62f93943b7673e900d12405dedd0bc2a906daf8b4bc336bdeb52b4 + +Square = f3aa49c906844692d3bc0cf101adcba80351c2e744be01762a8c24804a9d8d5a4cc3c113ccf529eb79cb3304aefa74178afa53f235c5211192d4cd8610c3b42e246621acb3e5d1f9d86ff39a20a7fa9c568356de5b86919 +A = -3e7069ce11472563b0dbeb9a936884df66db83273a690c40e5d3b5f8926fb502d3988591abfaea7b7bd76a85 + +Square = 7c9a5057ca8095cdfa289b2d60eec80548f9ab2f3a996137ff9be403b529c4672e003d1eb074c76c0086e3d875cfbc90a40ccb61b799cc0401ba160d8d6b6ee46b2f14ed31c83de54cdf83458dcfc01e3234d9717b5f2c7e5079 +A = -b299da84ef84095d8191fd1cfe847b960729a3d1857082f05b2fa30ac45e90d2fdc778013b023f38db2c8e780b + +Square = 488294b528e2c2da0145217ec69de2d021ca27f145f7321f06c03316fcc14bd4a9a900bd6a144086acad6d5ad32a6245f5a655e007742aa336430c6bfbe174278884d19fd93916ef57215069268ade899cb92dfed29628327b84d8240 +A = 220fa6eaae0238e78a91e43fd8c2fbd5db0c8501cb96d66265c8edcbd376814c39e4a6f21ec9a6472c6abe8c04818 + +Square = ebd685edd991dd5180706b72ce20ec4f6c5d9ce038cc8768f2ae2d0e676bd549d6d3f97f6c26f6e36bb664e8a7e6102192bccb354c024670085711db30159c6b7badab7c7c0b91925675ece3e23126ea6feaa28e977598a890e4e476ead100 +A = -f5b657cc38fd11ad2f1b188c61721b5ec6c9762c09dcbfac3edc1f07e675bc058e77eacd01a2b4139b1b00c40a6cb70 + +Square = d1b3ac1d7042c0200f80a989e053dee31cdddc835889a57482a0988afd82b0fe8d3667270a72967401c3e8d80dae349ccd4063f11cb24dd7f9a5aeaaa7c0bd7bf7991367b0d7b4d374dc9c5017da81ba39fadfc3b760f68da95ae1eaa2eea3fb040 +A = -39eca1bf5e4807fd6a9ccc9e3138a6fb390b10a330f0027f0ba9868beb77c93160b623de58054a4522183fb3e4e2d86b08 + +Square = 41c5e4bc851d48673e0a16336f0decbcb59dad36959b310cd1a042d24de00c587db47058c2d91d7f9982bdbf470c73f86e591a122b3fda71796e465513e10e3cdbd5e6bf035595644d588c091e23a57cc47b5173743b0dca965902918d61875f88735a59 +A = 81c2caee75e98f1822c854448302243feec55a5247bba948647f12d7e0bcde4b1dd6af63eb1ef948eec22a87d2f3213de75b + +Square = e712c3705ef2779ec997c430f1f8b7689d7edbf2daa733dca89612bcb298180b882cdfe8e5cc1104b9f5d6d8f0978b46eef4f297dcc83fce4c39821ed3205e399328d69ad484d8b3189e207193203ef79b763f5e11778dc24839b4feaab291a0464cc66edbe10 +A = 3ccdebe5106ff5642b4ac0751bb799c27454f904fb72863d1055d1412b2359120ad196b768f6137dce4cb85cd29a990838a95c4 + +Square = b5063c05ac122d0d4b1e0d15c913f70f1309933ba737fccbc02d13a6c712e7b75fa757ac0e4fbe65977f17bbefde31c8fcf51f867a698233bf25bbdb1f03c104dcdbf1173886a48eb5a8b4d27cd841196de0b53466a3f1d28500fb4dbcee8d3458662443eb2aaa5de9 +A = d745c04ed95d4090ed66784339202f9d0e57bdc1a6f6b6ca09337153f0236cdf99b61db85604791b3a373885210f6aade8530c8d3 + +Square = 974463573c968f1734741dde2a800761fa749b553dd6499b920d3af9bab73a87f40c9cad39c51cfabcfa0895f1970281af063d80f89f4103624a75bcb0d23f5ef6c1cd9a10930118e1459ee8732728ceb7961f7d83cd2344a51e6229fe708bda46382e142706137facf7161 +A = -31323f98f0f73fb66e541471774ce0e0fff53d69b2b726480b9ec7b0775b345ec4ec57c4334ab8ff4b388f4c7fbdfa3beeba0f3e0bcf + +Square = 673a62011d769ff0333f69f10f00b28781fece47ddeed25fb0bf4f8d95dde4efff60690076aa520ebaa3ba63e6d445541b9586241141ecc37cd75b178389265224533055ec82a393e5dd61640d3f442adaab917c8fee1f8fc0ff8ca8d577e1d2d976c2a8b873f699aa92c272c164 +A = -a28fdafefdd393f993a8fc1ae321e420451dd0c5071410367d5a911b2a3a668bcae4452e134159e0b1974505f99865cd97cdb020bab0b6 + +Square = c4f34585a29667b582a3ee69b1a5f6c04746d105a57bc92763958c5add45c64b5c1cfeb1a321fc5194aab818c92ede5408afae0a2a74ed4c7757dae0bcc602169a805d525c5a63ca97391a9a7987a3eaf04bc44c89547c5d312f7193fc571851b1a8f8f091849f649ae91e15a050f5799 +A = 3822b607fccfbf0c5be97d4358bc682784e6453c71781fd3eef9d247485211c55d742279a35bf35e64ba8ec8cfe20dc0889688e2bc81fe0c5 + +Square = cfdf0eb68dc27d60840b8afa8daf96bf831002dadb2801c5d6f7ca558256bf3c7c5372fa00f2b3e300287745f8664dcf8e679fa35adfcac93839cec53b349553f31058a4db05af40b047bb367234dd78717aaeb80334f0deabb09d2d4d90394ec28cc3589b0aa78cf227ce8678b8bb5cd775e9 +A = -e6af13779d5a5eedfecb7c4d34009affee1f0bb65934ea9656ed6eae02271ac8a29104439000650a3a8cd7fecb171a7154c0e2bb2b1cb908cd3 + +Square = 6ec1b1333481c37be059ed7e088c862f869bb559b34360781f7263eeb206a210b90321aca198aa41c2a79e3a8d7df4336c75c87ba2ed4b02052a07b234afd9d2cb55413d4296645cd0dc8f987120acbc82fbfb089190f50e55eb1f509c86734dc14b2e8ae42ce880023dc7a014b02727b53d0e5f779 +A = -2a18acca3306bf06fd90da4ec2cbce995fb08beaec6d1cf4b30694d682c83e04b39f9a569eec52782b9eda7db0680165c77a1b0f54a1b995f8bd75 + +Square = 5382be4ee86b9d80dc2d4ec58606ac538ba7074d57e2011346f0dfb9a9d6677fe015e4015ed607906e9068a3c5601f0bb77186a9d147416ac68e344318cbae5c70c437c5e1dfc2d6c3c8725198937ac2d8e796f749bfe95c7fe6d0e460a633be2d86462d48290a2f8b344ebcda2f6ad353d6fd5f3355d819 +A = 9236f7ad22da9cdd8c187082c630098bf3a558b04856e876433c570a63d39863416c9890dd089f7665d6ba073b2ce90f88e7d04af96f1c82287903fb + +Square = d68e15e8a46e001e47022daf63d2b33fee0f9d3dfefe9d204b0de6daea31dca4b287a60827bda9de2860c433b77186aca10bf3ac1d02a204ddf8bf070c3c20ea69d9638a865c8843e8e63211951e10a844f8527345c5bb5417e3301a19c929e6fc48902f0e0be8e393ecb3fe0e9de6188a72d102fbae846d05dc1 +A = 3a973dd50d4239f05d86ba25ee6ca8f8ef46424951a8bb89e7d1d6e066d6fcbabb3758ad9e1647a440e51976c0ce628d78b59a4d9e42fab0c723182b31f + +Square = f03a448bc7405d2d54c0ea1a9016d8757d4af893024e542df80fcce448491d07a4b451d67c9e7d9a6c7c5a6155bf156d3cdf8103162d8e0265111655fc0ae46f4be944fdf275221b217274357977abf64316615dafb6ec84c5466f617c4e8d9ad4739f3e5050e583892db75366a4a7d2c4558436ed036a79084c7f9100 +A = f7fd0a9634d14d540daea21c7b804d37de49b7c13bde85c045859ddae1dd3142994e385f455becb7ee30576d55d4dc2f3d9d82e86032e170da1730b2c8a90 + +Square = af945dc2241029744548517dfd7858d42097076b06427419e74ab08071a23aaaa1f5daa6290287ce8e832a0524ba5581d64abf054408ecf6ed21a4f8289c1e4c7a8087384d268a1ccf7ed40e74922a619b5c1f2c08d810065710046190b7cfff33d4f67e58927477500eec54ba4f63a57532ed10c6b861fca9d46bfc3d32640 +A = -3500a8b6d244f1a21e10de7cfbeeb75d57ffa62e9dfbbdba8fe93d17488c56dc89787f13e660d0d7c7755242f8412d00988bfc7d3f6704782324c48691e7ca28 + +Square = a466e34dc7875aaf945c088bac23f3347a41f7cd039b0c9120c2517ada94b96bdd72d7c9bb55539af12931a3a39f6e09a4cd4311fba57dbfcc51bd17b03905e2560275c8bb3d786defeb131a634e86ecb793867355b048dbaf2db8b654a4d50aace6bc9d60de6934ce25ab58381f6ddbd1c063652e283c30a2dcd61d9d776d60e209 +A = -cd26a0c3d84e83d9f14dbe95cc39e3ed2e8861b76f4bf55ab120ea636d8f9efb0b6198986eb52075108d0a5c6ae0ee762f834f3db802c3f20bedf938f47b8bfb03 + +Square = 9f3f4d5110ea1bad21fae923825ba869a9982b753284f1946edea19f22cf0a49485b9336a2af7df8bf2641cb2083f4dce82202162d85a5779a4394213bf3bb3e47356bfc1150e66ddb6cd945092c9af14eeefd2d08b76c5e4a585ed8ef39202c42dbbceb25697f22f9508e7d954d3c1da103818aa6f63121f895e2c26d3d7463aea7ca749 +A = 327a2f6607c41ce920c14e9c9e8a059a931d71aeebc3e05e93107265a2810ec286819a4b2af9d2b70b754bdab6022b10ee6b81b32a7382cee99fb2bbcf6fe85af05e3 + +Square = 50ac4c46f2014a7a382b0d5ec9db4a67f34ffe9fd5410995810d3ea8d7d87d47442d0253c7eceb1799272bb5f5e7bd63174959f9844e5b4b65b6a4920166d83d01a5c2638b4d3b6db7fed99e28b9128dcb7c10be539114c5887842f8e5a7fb743298ec9642e50bd0979156cc6aea9ce802a0c1b14a2a1b7afe28dba534c9933209f14474b6e484 +A = -8fb585e01a0c62367dfa8a1953e553476b1564e843bdc2c5d964864ab2da56e0bfa7f5ce5b7850398451619a061de02ffbe0c336ecbeae818d32dcd40355fd11a7a3822 + +Square = 9214e31bb62f62a7f92d6c7f1453bc4430595a1765b7223a1e50ec30f934908c19fe82d7bb8ef1174bb6787aba9df1a38a84203630ae9f62e08fb4ac55ed329282315937d193992e9e12adec9727ef91df5a065cc5858062c765f34bd2630fd3f654a8f8421b75dc384477744efef3d6f0d15820c9328bf43a43409f6527dce48a92c3e1ef145b5e284 +A = -30587ef092cb9456caa844be9629d77ef1bfe21d2ffd5625ea353beb1f294e38a7fdddd5bf77cffe5caffaf609b8976756c9eb4908ca77b1630ac0d706503c46177c5d905e + +Square = 54bf52644a244276ad3dac90661a1e21468f23a117a1fcc904c66119d86ce98a0b90fd4096708bcefa7a9df87c6bb85149305f193cf5505802172ef9ec343f662a4c895a9d19edeeed5d91e20abc894948fe59c1869928616392f3694d82aabee325b651e1170006ca1fc355212308442a5ec8a8fda4f5f90b7fef2aa731f3fe0f028143ead04490d78b2151 +A = 934b16f56700b455d5791ee8c119b5921976a829bb5d1fedb201e63c9ebb82afe4e29aaf0ae27148e4d34269c48dfa42131cc8b3b78e23ac3e7292eb0d715247a345c800f377 + +Square = 63b7884fbb6d5521c38f7deea5cc131ec6bea15a362322a8e27c762880836cffb69a069a168663908707bee9d83aad41c045bc84dadc6cd927ad62140f8c2fd001d34f0a7462bc939cc8996e17ebabafda95a73483c70191311a6fb7c670c76c9e2ed7e589e464617888d30cb7793e91672d7de9b3b4b1811b2c009dd1c690d44710bbab832d91f16f9b3564a0c49 +A = 27f17f0865513350381ea1aa1545439fde427ccc64385979bc787cfc4c7e6b624b2c77140da2c4176c55dbe43c506fac14b4cd7815e87f3120330dd3003bee087a371f85d6f4e9d + +Square = 9d1c4239accb286c3c7868ad3b4dd97b93774fd0c65e04ca8dd405c0298ec6d1f52d60be6ddb5f8f0389cde756b49b23dd2f0de568a432fb99dbbd40db798261d1dd39bf5017e6dc74cb9ca91f8b2f892c7eaa28485c04a96add206c7c38943912de065be17b65292db5a144f82427016b5e0eb4ded2e4d0b7d12b01cb0b2b61e5e1bf22dcf1567a8b149cc0ef5299a8b1 +A = c88cc5a46bc1cffedad4f45e66fb55dc4347eb2a24a09878358d40fbdb03e738ca1d54a1d26a777915248fd730daffb0d3b5305684709db0f258f581fde06b11a33a3f76b3fa53e39 + +Square = 789545f15fded8fbf0b4275cec30c3ac65eb42ab8cc75670fbb2ab0b4cd90ed41a1290383b5f14bf87a88c67ff1e04d0f478fb11fefa64e86eae5777855ddeae451e166e23ec30227fb4021d51ec7cfe4ce531c78ba1bf6c797dc73f093b0a5a5aa59ad8de3234808e776d690007c8c332b3f03331dbdbb8645b91552091afc36c28c3229220b1a7966c7cf13db6bdbd4673440 +A = -2bec94112014c1a506417e659157192dca1df58f933510d7a8d6f6feda5031d799a66d2746c09f827199ad9fcbf11f323a636feff5806c9fecb2ac684c2870d60c8a72358562c4eaddb8 + +Square = caa64c9f6bd66f76c99604d1f2b8a29a9a10c0d6a41cf32b5bc40edd7a1d97b295c63aa62c30498f15d70e427d5612ec3f6a2c1f2997fa9283f48018435fa6092269dc2e4ad524cc6da9689302f5c398d79e2b2d19470ea8240db9df0bc0bdc911c4d53f4f24a7ce44ec76378794d16d367434b4f8b6184c7651db77fcbebb8fcc5d3a51ee9739922cf20d4a8888139fe4669a164400 +A = -e3c4a10a64b7e67d786aeb81bb7ea14655637ce963f46cce59bc0cb6b5a9cb9c92afec3d527119db97bd2605d315cf28198992b4b2206e5616d3c560bc8163f56cb1f5626a7ac6d8427520 + +Square = 429e4283af7f895fe732ee88e4904348ed01bf579a93cffb7aa8e135d41cb9be218f8b9a9cb4f556124105cf042de51f34c8162fdc7a981de88e005a014149c955068e87214c174daa40fbc618c536a6e507ebd313763fba197059d68c69bd39933d614b2c32f235cc955e335c4a37b9e98cd7f98c7f26ea2da932c7f82ffd95be22a7741da423123f8908cb188abc26afaf4ba6d47b56e11 +A = 20a5e2a911627544219a1639c3321bbcd6192a32129b248cf62351f85b7a719cb275a4e44368a74f4d1a307ffd27ea2cae4d8584a57070609a30fb4e365564908f3d501b53c1a54f0e37745e9 + +Square = 9bcc8d423c3fdfaaaabe24a910e6ac3619eaa15e23b9f317c844d39d164c952fdf5c4bd270a83f3902e54d3817fd78c96018a706c1f652025dde0b98afe35597e0d8782deaeed23337ef6b3edc9317d54e3c8a57e4e7e2695f9d2681bf82927bab193ca1f135bd0e542696772f08520faab61fb4ea6ff0d15bb91f21e68bd7f084a6b8f24a47ecc30a779ee86610387b29a1de94de517f81318001 +A = -c7b60f4c355f2ca3937ba3c124eea2cd8d3536226a44afcaa3d17abe931c09ccaabf25a1986b172fcf46fb02a0fc36f2c163b6e42cee047c54ab05e9d30f03f6943b9fbab83aa6da12d7898c001 + +Square = 45df25540de94883dbc182009c29fec43627d3e5758e6a07cf40064e0befa0df184528a84757b445dd079c2b0feded48b651ab18b4bede2a81796be45caad0125c3692560d19cd9a6c8c0de8383fea0bc1ab46f6aca4e9c36b26575cff88fdf1eb1e13182308295457374968fe3a9ca34c6acd24c753fb84d41246614789dfe154faf34fc684cd15035dc9c1c6b0ea171e089e0f3236840e355bd123ac4 +A = -216f8a9a3e54d4afadf368c2693743efd3eaa4cbda7a87cd07f5b1a713eefd2548343e7f091ee4d9d6ed1d4343c06a0597db0eb5194b91bf2c858210557a8288c1aa7b0e0607a24dcff9de04146d8e + +Square = 5cc707d97eb107c5c40c0f19fd432cbac9855f280082802dbe4deb45bfd193ac7a9149fd12c4ae6e9282411e2f1f2ca92135424f215b800634092ed4ff2859d16ab9fb8619ece41b50f8888d3e13773d38789e19158e18396096dd57fa5470f50b391c22378d980e59b4585f013e6db52c1e24c14ad83262fd37d42f52323896f7d4cb3e38868abea8a07e7ad3f90512eea001c5147645bf00396cb0e7a553f1 +A = 9a1d1b0beea76e7f32bde9f4f2c8bcff9094db2d32c04fb7ff43624b61033646e482aa0fadb9f8b4225b47121070b4ee5d6818d3606ed775aa631e0ed42da68c2a09dab26b6a4d09ac226cc09321fed9 + +Square = a32fd053eb90c365e77ff47573a24add3b25b4c301f4c662dfc1fa635af8e18e7947381989b37a9c9de2713ca438b9f85890b7b160fe251933aa7dad1c3839d502debb42ddc927fa0e9b40c80dc3d408889be567699a856b1c9cf3a393b3b818432e95feea825c17d0981b942236b3779f2acaaccaf9a5817ca47bd03045fc4de454d8f1d4377e218c5f7ece369aacc35369ab57a71652dd42621491834119afbe729 +A = 33190b787a2c3327b122d1f5823bdee5c93b19b586ce1bf79d801a19b2558aafc8f6274d0908bb7a8362f7f71d3fb52b8ffc87d458249caba7af3a516ce868e8a620e3126ad43d6aeffee11866fe77677b3 + +Square = 74215d33fa398e21c34034af6f9c7af6a3e01982320ec8cf23074a938f1a31543f80e6aece01de247668fe67f276cb4411db27666e1dc8fb2bfa4eb68cfd3563167d1ac4efa3361f920d8dd0fbb7f06362167f5ab5ecfb72956c20db934f67ff1c75aabb594c853fa61f43d219a3f5d0d45274005e3b167cfff5493b0f26d15f85d8e906a0a6e7645eac1f40c6dc637e6d1e061e5b9071a1227469cfb2c0f17ff983684100 +A = ac6c0b9c69785f35dbe244dc85a54313ef836ac67c853531ef5db45b28835ffe61dd258c5528b0acea50f5aa5c0f5d08dcb8d82ee19bc432fa8a45badadb50693fedc1cc79a17d63aa73fe9597f1d4ce8ddf0 + +Square = dce5cac967c47b8a58ed6f1bb1d1e6185e849400228afa2bfa05b9c2dd327b04a86f2a4da2d02ea102868ea0c4da0f3e5a40bd02c87a08aaa5cd8d9358b3a5ebd8c9fc2dbb1268c261f46d6717b0307b993deff0adc8190d32b4f2bf695eb2cc74a6a9a712c5a621c673219ff8a24ded0997508f8f9eb1ea872008c46e71fa97f55b839950e63130c38b49c0ce3ce724a0e8faa9738d2e28ce6e7fc7eab62b3561d2981f314f751 +A = -3b735400064b15fad81b08362b8557f8318c20656839ffb4d2513512015036ab0039442032f1cf515f8c10c9933afe4206a2f309e933d1561b06bc665af2f04f4d064e073eed2280053f56cbeb137a9482c0a077 + +Square = 6b619bcaf632f0d8b1d715e8850c0cbbd29ac6373a9a5e93dd1bbd2b82744a8a50a7446b48c6e215911ffafcda9ed7becaf5d26b7d6df7dc8798d53239f62a482f974bdb654750def1c941c49a24fcdfcfe73881b556a7b528d88daeeaea8d62b357211a1946c81cbf0819ad8d0188f60aaaab4ea2dfef7e9012ade7abeaaa4a23d7403c1248c36aa26b43b8e7de8a5aea639a0449f50359e9b4c1b125a548383af33703f8dfbc2528e4 +A = -a5ccc69663a8712c15f96e6fc746252af89a8c2a6317caef905dd2d8a6d4fe878ac7aa66cdb3c3721ba7dd36da310753dde9801b31d759339ac919a464ab52541bb2e0dc938752bf0f1ff7a9524eb98340d62576aa + +Square = 77ea5b715823045afe13d10416dfd46a511141a7d1279ebd624f1de428cc04a4f246246e65c3f84344cebfa32864de9264b2e54d4b3010c4de9d3e6a27aae8f5f9e9d8e49fe26b73ac7e65bb216aa6a42db36ac03d749b5dc04192df819631593202a58264714628686507fc5655f169483b0ffecf45995cbc12faa105895564d287a9f4b220947d6c93786c85b2ee84a0a29183483f7c241d6a67fd0b1c38c7f74421355a14c6d9ed5720e24 +A = 2bcd67e6bde3f54c4ce0ea428418fc5c97272217c6c7de90549238ee322810dcc1bb9385967673aa3f9f5a5c05d987c6445135cf1efc26b3c17e55b93cc052761a77c9dcb5c22927b09e90a92e053ec1bc799bbe7597a + +Square = 40d113460ca3e70545bf3613c2ba5de5d8485641ebf531a43b6b8bb76884ff4f348727ac6606e026981d2116ef1e60d4b37b44ed7e2003410d7d636b58aed2f92e962003f28342aa5f059d23b3d58a1ddfb47833ffe1d1deee0a7e78b8f7d9d6487f22376664f1ed9ddb5ee3d17f43afda296bead11680fd17576a122c2599fa9802ddd84a2115f9fda03aba898f66e303895f452077c920a322b6aaa0965f51fbb36f01b1d412c6ccf390da050d24 +A = -80d0699a46619db033461aa6060983def7deeb976d1a71f5c6ddb85e8b46dc70b7ddb1d254971d38ca87c7ee3905e63506c6db105dd683375f4239523cbf1874069266c2c0f4b37edcdd261c51088081d25813758bdbfc6 + +Square = ace99f98cba0d1dc1c758dc7211aa4078a2aeb6d3fff19bdfa6981ded0982b15bac792e6b542ae48a86f9b40c6de937e402e230fcfc390b10c3e60202dee1337ab39da7a342999487b8d8b0e494f2809cd1bfdb39209da5daa590f78ded211b6bbd3fca9013300b951d8906c9ce8d1c0dd9554d5d1d352f9784f822c928dd9700ef8a5fecf3771966abb1dc6a70b301461eb6b6087d6ab80a4b624205489584224cf6578f75acd8091fd621d02306504389 +A = -349936d60c9d77a0974dc8985930d8674976db6b3cbaa067554ca6b30b1de33f2d4e1c9564ce102ac6387755aabf42916f63632a375d995913f9d45ebda54bee3fdb7cedee46ebb5c8ae7764e4de323c17c797d3b529230cbd + +Square = db6c73be2a59bdd35dd312240aef18dde4231c72aa28551bb370a87dded587accec2279bea24c930236f06f24d537fcf242497aafcbf72f085fd3ecf030cd750fb382efea0f82ad9d3195680324d73fa99d48802d085c150164aec0d29fdcc3262264bbe72311f89989cc71a4afdac6ab103ab4fbb6e973a42a1f8711bee463d198f727dc7bad848ff8fa77cd3b2f612d142ba46e95bd79a86a1fe4c2b8f9181be84825d05989695842113828a83b826e7d2c8c1 +A = ed01dd49d2e5d51fd30e9c578259cf107771b4ded6bf21f8b9b632fd360e34da740e0b1af6b5a67789fda5a44025af0f1547271ca8accc7a975d98ea7ec3d41c9697018d84ffb5d49b88d884ccdb011f715a199ddc44a4109261 + +Square = d6e38250ab89ffe11abaf8c5d07ba11e9053f1924ee1228f834111af16ed282389d04330cb0f47dbb186dee577aed82878ecb065b759312eaf167c4698eab5ed03a8657341bf5fb14a8e28e3b443a6b657c1f4379ff2549498a33922ea84f1fb19d10866fb0ad07ce1cc44c93cd4d9ec6bbb0e61c797750c6b5d7e8d55499655dde112f4747798f0e985fc2b937a44da9b04c2dc4b0816cfc57da1f80179db653c1ce287e786ed7eff7ad6d1383fc6de8c941d4af7bd1 +A = 3aa2e696ee570160b2a869c3f21c3f223959a185cda2274feea1c829af2234c70a504c959bcc49fe0313f4f5ffd27448e28aa0fc6ce24f36943d334c626459d7e6017339e787ab074879ebf697a93ad93835d69ab09294d007a0837 + +Square = fc39360cc0fe040b6f8340e0728c650e5e74cf1664f7b301e79986fe066f36e8df34d38d1a06b74a1bdc76867baeb3f39a9161acd200bc7532fa4aa0ea829377659646f073db82ee044279ae5fd797edd37d3261970819589853cb320887a085c4011c23d0da9b6d6f1b5911bb3399146c2912a967ab3b3f611f0bd52e00f418e6a6f0297fcf5c4a1f71c6bb8cc8e1c76694bb7301502d1d00c8b6c05bfabbf5d350590561abf3e2b1a82e98b56583e2e4e25cf707320a0e40 +A = fe1acf3d7b54e718c901c53f365894c22c8bb4182fee8a4c2558731e01e1519bfd1bf6e353483b8c4219453fa66f06063c6c99050068c15cd13cd1648ffc42b5badfc70f6fd4a0a5552fe637e54c4f92ca45c60cf9a0163978ac08d58 + +Square = 9abf1324ef65c726330f64643a024c466fad37604f4dd3dfc404d31c2a430fcfaa0c78283666c15a094d494b96d3c12de6e29a34d2c99f4f8cae8217bcd2a989d59807ac68c46d60600238a86155de499eeb35642d0f581045481b40e4f0a76905f9b6bc5b9585f77f8410b99333f7ea983c3f29f3fe66ca7b793b784a5a6a4f74512aa4385dd1e996832b1f41bb3af965be58c4ac5e867cdf8dc6a4f9d20a6f1e16e153fcbb45ae5fe8a798cb06a4ffe467d6b6aca2b31f335a344 +A = -31c243593ea611dffecc65d1439db345b2e89941113f9792c91a76b4890db6e4dbaf1482ee812e295d27956e48d07a14de38357f15b5931c5cc08d1d248df7bfee1cae5b5ce98984c5043a3e1a2b449ba1671bf1cfef91011e12bab94b6e + +Square = 66aee3e4f43c672e0478c76e2092bef33e7c60afee5d4c7defbcc5c0c86d8fe956c90a740cebe604224cc3f518463b1208699b8ea2316315474991d0f120ae905a67028492cf46fff2ae244869db2a02d06aac6ac6eb054fb3c14c756d8a3e7ca64f06586e3e86e4477f185ed527a8aea6a3c741f3fd4b64a2ee77ff140190260c431cc53f411fb227377c02f85d0258a75bf6d44dccbb8bd04ebdafa115dd55b176b6eff5567e5b1bedcae15110826574053681fe25a695ac4540186e90 +A = -a221dfee30286adc076673cbcebd24a41a438a0a7a6a547c75d33149cb1a094a8425feaa5a23cc234a722db4cca8d5912fe1dfb6db4e92bd87c12f0d06b6d954fdb9b172955412b2eb5c9fa3b4df2933390384fd1f929a2b1a8dac479ec94c + +Square = e880f8655b51739e34393c3e6d69d63e0256b1a887f7e69f40c78d21133b17e92277a136f5e37da2533ed599efad189975d22ad0340005ef58db0b471651d749dfbd48b3f7b3b8a42d4677048a855e99dae6c729d8bd7eef86911feca9f5490dd216b06d9e8d1ab695c1081e72449baad28dfe113744853382901e6bdab5413c67c52d6cbbb2e0bea711edbb3a219a4046e8739c04729cf8c8210028dbc4087737bc6c1d7e0c15ecf16774690168342b1372d3646d4d8696384bc932144c98529 +A = 3cfe075d4525a3c780d6d05f7bb708b2fdf7277a0f9967e0a209fee9d42136a0bbf98660d8ee8cb4720a8042da09f6271c45ad13db24eaac465f8207f78629e9085c1c890675f441c78efa38e5022b1b80afde5e3fd08e55648f2817631eb6cb3 + +Square = 8d6cf4eaf58099b1323fc598b7554b371f4afef5ab501dd162ab8429333d46916fe15dfc4ed6a99ca7fa7fc1aaa0cec3533b41e291fb7f69b560259507226eca87aabd07b1ae2eb93bb53f98fec508f051cc04db4a172901e06b74229c4fa3f550a81626c7a63fa99d41e46c2cf792287a5cf7bb68946971bd43c7c0356312cdc25e524665dd39a24b6464bbbe64fe8e87ee313b860639728a9143c3a6118bc8b150dde6c10a13bea637fa8873c393e6338319c506aec6ee973b4b52a272a74bb62084 +A = -be46a8072aa44b3bff0f90c81474dd576756fca624c15f55a17e1d0bd2842467ae000b04f79f561690c93ca7118ce17ecf830a8da3678c15436876d2a74324d9714dc8ad8181904be657d7f1da3313b78448cc06e32299a09ed59bfc1961e8bd722 + +Square = fbaa4fcf9800673fbd3a132305ed3e14f4889518fb56ab82aa5e9b3529b74d7f9a467626d68f4709a2030264aaebcf05c0a0edb511e81f357d85b79d925a24605f1bcd4645915bb75d363654b676266329df532cdb39152fb360df1b9500e0c296014289650ff77faa78a604397a82b34d16484e94a8de123fe720e514c88f11ec276725111563db91477480c3245542ec6bd0bb2f4aaec02c6c4eb1769030a31b05da3798c224c9117f7c38d3e98a343fca03ab584ec2d7e6db60fdc4273c3d8e23cc1ce09 +A = -3f74b25f2a9c4d8d977e69a4e067f9fcec281136a508e365b282e5fc3b1d097bc6a0f59f7827fb90d4890b08840a0a1919032c67448f8f1a771f785a0f125a4aa4137c154fdb489dc1099d57bfcfc75f4ca5e69f93f2bb87ed09cc0dc620d3e76ecd03 + +Square = 5135becca97d93dd4b16a5a1105ba3a3e3fe02bd6a7c3cd182186fc63ed4351641182a2727ab6715e9672458dfbc31aded4781fa345054eb4c317872e2af6d4ed64b2ca7e8c25e1e664b5349df937118632a64e4ce439ffc625a5ad3358270dc83fdfa73c7afba03406094fa36d87517e5e2e1fee5526fd2dc00d9210a0f6c3745b3d4bceee5f8b03d976d696c57a09d1e08e4ce780972eca4f2ed6500c23bf5782c31f13059e48246180fd09db693d2fb5d48d51846ece8beee45cef7efc87c003b44d7b137a900 +A = 902fbe2127354a7df5cb7fd057f3d080a7bebbdb83c86a50560b8c287a37a841bb9c8421c63d359078d2948b6b57559f98fad8f8014f93c912cb70a6701c4dc4fc5e88aa413fcfb685c32975a8b72424742eeff8262d28cebad00c5fcf88baeafe8f6730 + +Square = b5976cf6a6560412aefa6704b126e0d987dfcedbb4da436c08ce17b1bf1b6e0bab9f934abb5c4186a5415fa38724fb8fa341d381319e7d768209ab108c8debd99075d31deb3e03ff7d23957d4f3204d543b7d9079cf337be3037b1cb4908fd8c104d92e52f041b4cb27c045a741f4d64009980e8d27af75d9493920ed98c7234777592d6577f2d1b3a0eec645ab4cee2f28d9e4efd3e4514db6796487ba68a462fa0e316e1420d6604db2b901de46553546cab42976fd0d459afd81196275cd88ec4dd448ff331bb35499 +A = 35e700e034950bdd7318d5b3c17e90a4772ecdacdb055b9391b31538eb823fc8a4599f029e78e4fe5299ba1a423a449dc257a431d189dd5dca275c02cc1f12417e111c73b731631d8a1741b907dd8f24de226ddf9e3044cf4064e8e51ebd55be774be7ad2bb + +Square = b7de0f73397893a97928e266bc56299cc8d43b16a251992662646072b58fa578ca80f7be1e12619012b130e9514be803dc166b12ddfd26f558d36c2053ee6209b01458379e49469753300ef20f6b3dcd5383b121861c76ab25debb28c448ec33a81250d05f7eff80a5a4133d522d270fab29f739b607395a77278609aa5e1a55ef58d1d48492b71ee30a24a6505aab1a3ac22b9d143c9d6781fae14bbb980fe3a99dfa9a1a406611d7d0304493342f53faf5fd79f9c96b9583a219a1b22aad02dd58f32ee98146b3a8cf054bf9 +A = d8f4d3bcfc7eebd7068b851858c3668ce062a834927e165679b49132d4f780ca682876c65c7cf2e7ce34ed10e43696477da6301d13f92abb8c76e2424c4bc28a6565f15e59563d607b852dc946652b68fbfda1c3200ecc2976400ce7296b96e75fb059a4c8eb5 + +Square = 5ec02661f49fb9807bb73debc3c6eccdac1df1735e0d61fa7e0eee07471068a5809796a2af490c46a77d61f618b44a3168dde67aae1cf9e530382411056958d55bd18f0e76fe2c31c98b00f87fcb7f5691ed5b65424f82204156dc361ef6dec5d44cf690582599b3994ee47ef42850d5d2370a4169c5f73942657f85422ca24f66943877f73af493c865fbeb29574cc1cc730e9bbb097b598574f6b90257748e950bff867bcc01bf62f8df67d7aee1b6dc1d5db88826e86a3f9fcd8663e09cf8393ee71a09c43d0d38ba6ef643f4ab1 +A = -26ef9b6708a80d00f4d01e0f0a5546ed217085ff23519819ee89af430580ea1f086beb0eb51982682c6d3b922a2c92752dce63657836223a9d94964bd584bc8e37c6e30fdcaffbdb128344d51a92705e1c9f94205ca36452c15a08f7e62e0e02479ecd48085de8c7 + +Square = f6364409467a829abc2b13c93979dec84984caa12154b7cda2f4c8d91bf24ad7c45a968ffaac8d6722cc26e6aaf52dd29ea2f09370ba46d79684b7a06faedcd17136f35a58e5b550f3a2caef7b195d8409914fedd3c3154101bd735155098e8b10fbbb1b2e13555d2ab5d5b52b203d4efb27e498b240f37178f2e89b413f94859b0e8b2ec10b926c8c0b6f2937ee2d0355445364841c7e0539f7073b88c7d568edf1b253f3c10627e22c2ed731b7d4d199449cb0b5e7a66109932fe2c9cd741d75170deb9f98469049549c10a7a622bf6e91 +A = -fb0eec3246e99212879e51b17ea6615275818ecc5ea3058b13dbaba2576ef90e1519e3629b09fdaeb02661091c395c862b848f6326b9f536f7af45718c4412f09f19261b537bca36742d3ec66f964343516aae2ac27e249a15beb545b447e37b4062180f6c82809429 + +Square = bc4193ecb5dac900191e02be06297106155c6840c4908fbf6e41e9aae137d53c3d4ffb87f334f49837dc4ab7a66299994e4f5c9bf6ea03e7db663bdef066e94c610580a8896a9ae9c8f6587eb83d789683f5d6391bbac3a1dc1de60b4108428e6f5fdeaed6cd3e74fa01f85c6368023b61a413b69b14276b66f22653491e4f25790985053d075387cb13c79dcf963b6d880d01174314921afe1cc700c02efd2979dcbc59c417a6316db9ac45a2d60d2a036571bfbd75f9f5e42048ca086cfb4b818a9beca4a6e0ed51afa320ef3549151fb39e100 +A = 36e1f16043b4c9b4a304496c39dd63459d6521d2ac92916d348daca3f972835973fc8d21b07b09d8f5e3197b39a8f3fd0011168b815d67c48143c413e169ffe0f56ff2cf8b6596bd0a3b5b7a6b9a14ffb797f350b7e6aa7020d84d1d1b8006850139795abe2c74f03b8f0 + +Square = 4cbb5bc1dd7112326e2c94581f19efc8fb25339a299fa9c007114c3a22b395e9d39a8ffe21134e97ad1b87b97e667ba48b2a40af61afc81fb1e20e8e38c7ba666b146016af4dff3faf5de306591e5ce6eddc1173fdda6fe241a9f2fc6e054c41e56d296f8954377df0d140096b9e9d6a5a23a231db4dfab0cabfb11190c7a0d1c55ae35203836d433da96ca7339682bac0a7edb8b5b4dc267c6e83ac9b67a0d0d564717ee3c20aaf52c0a750f3aad94a12537c6971ee009d0f82ff576e984b06c7f7b357f5c049454e31326b952af17aa62104780e9ca1 +A = -8c279ebe466de3115b8740f3ff9c1f605b4eaa75512d82fdc8ca5ce84e11a68688154fd603ae1d607807dbfcbb822a8dc259098842c6a7b7ec350be29a3daa20fd5b093a56692e9d42e7a389c4ad2122a74205f835e268c9742d09ad36238c34e143f6e2ec69c0f490d29d1 + +Square = 4f771ade09cbd1a033d2bfc6036fe46ae6c12acc6f2b9bd52e7781693fa6358cf93089f23d1f0ee6fca476a43093b9b52446f3a7abd72ed0ce9b562dc438822ffd84bcd898ef9d092f1b0b7ff89c4fdb33d8715dd4a0d68ec49ad41338fbb62ca87867d847a4d99310641a37ea78b04c85606069d0c0950484ddbeedac8ec6f95124e7fd83da4e942d40103bc14474f5cb125fa0b06cf167f076979948003dd8dc3711923f5af5beb5f56c0a48ac0c5240b62738c1cdb06b87ac3dfa17befbe938ddc7281f6c248c41a1c7b99b93f69fac83a46eb298a9fd8b9 +A = -23a845bf2007ba8480e3ece0a1bbaf8bfccba6bf061e3fe1d8bcbcd6c761e650891c0958bac68618a1f55b27d2bc6e1e1b50afc29f58e2e034bdda8405e5378cb5bff0d84efcb458c5428fc607597d89d589d85d90f3da4b89a64c9d1623b98b10518a6f2e7d2295c37527026b + +Square = ab45d12a4e15a294830741f4b9d4a14cc7dbed1c3454612047f890211c749d92ae0418f11cd44acbf1585b1f7323b33ac9a4b13c44e1a7e31b0dcc1c6dd4eaa12a655b5de08f3b948270a152db7d9e04dc54677075797bfad6a9a0e3958458d40e3df5e15028954bae99518de4dd3adfb2ec4b38897a8a4e4807849e1416aa4040c95a0e49a8d2889f6fb0537875f87516c3723e8d3b46da8da855929c67c0eb83daad62ceced52b4f52d2bf1c4e34f26bf16aa7da3afe0f5df76c0858ed98f21e1fc3d01e1572715b774bd5c2faabec5fa3fa59a7a1f32565a4f1f9 +A = d164d875e1f766b4567e9228241213e69d6b6c58620600166fac56938c5d9643932d01f1f4a2263dca4b9ad26dca1548e4b5b7e27581a63375d0e624f4e4c99b7fb9aeb25307c61142760bc4771e48c7ce38f5eb2408def632096fe40b80d488fe17a455d80edfc1c23c429775b5 + +Square = 5ae4e7dc5727543af39ed3d5e9ac086d1a2220421231b82f6f41caee7b9815b4049aea0d43ff499c6c9e1f226f8641351d03f37731c64686d9a9ce68e9234d6a762efcffdecd42f81044111599963d9b6873cc20bf4c8284fae03d2e4f238a14a74df4388fdc80fad0375a5d0d974da7854ede5896ed2ab25d2b49a3c39093600f73120e4fd2faf75381854f6ae80f81b977f62fc72f1fd01c278d183544052b77bd753dd88ffdf5c01745521fb8474b5c23b0b7dc709bafeb91cee0863a0c23ad7192c43cf15fc181d629853cb9b8334082c915dd3d04e3a0a81511d2e84 +A = 2622a7bf45ccd3cd567c757f4c5796b5a0fbca555bd0ac2759c24083172d82d6a887dcf93d9788fde052cb20a8963cb6db22bf5eee6151600f9d1896a7606b11a1b100cbc0925bce037bcea57e361efcc560a9abc495d7f7f45831c6429ac8f979dedc08c304f4da9c0d4d687376d5e + +Square = 473cc933f5a650a4ae358c7f486d325c0e20c83b54838fc08b6ac3ff010f7c4b6a609bdf472974dfc5abda0c6b33c5ec7dc4628d85cb4276108e2b0bc4e19cba135533b3d7bb6a94332aea3165dccb230860d2353166b9905635e606185b014730e9dcf2c433e18cba83859fb2eac4aabef68c8314ef86dec2d534a184ebc4cb193643add0897341690cbe18bc2e775327fd7d71ffc7ebc49bad83cd68394eb276b2e615ec430180303010a454ef73b6a8f02bc48a1fc8a32f8150ef1b733f07da752b8e808000329f4924976bc8b8573927f18ca7c88c210845de6dcd0dee2904 +A = 870b2c4b054076d0d02877b19fe1210a8fad3422b00905a6db748239b8e807716ed9fee0d8c25496593717917edceb5db57f9960bddc1956b6652868d6ace82827bbbada5ae8c15efa26fda22657126c6300906f90e8fabfd58ddf312ce0eee760e0090fac44f00378c676115cd0639be + +Square = b151124402d2f04b0e6599222d380dcf67b9716ef50d2d9ded0b21521b34a7294171f71b41762511b7cca93d9f50e9e30083ef19144882928011dbb143807d1b88c55eea6b19f0c4180023be6da63a59b6bc027aff3f5abe2f65c73b2de1e71c5f4b248bc4547040764e83a860cb3f882bb8b5f7821f92802808fa37c50f2f94d8f56daca841f42d3362762ba843aedbd03d3cdda887f75ba92423965ab4256eb842ad755aa7a2af331b488186f891065b07f5a299c807dc24fc176e085a8024bbbf12f386ef49ccc91bd4ada0936b6de78088cf5952ae6c04f6916799378bc0ede0da4 +A = -35439da9e361700152a35ebdea253378a1febec5f288e5b2bb0bdf25b84751b47e4da5aad7453b70cfd6640d5832237d2115575c738482ac6036c5fc21a981c0a7f979c8d621a92c02166b777475618aa6362a0e225dd6138ead3b2766ed9785ee01e4950a863d2fa0b7f5cb4c9a108bb626 + +Square = 4ed7263ae5beb0069f24318b38afe951a5a058a2e960e67f086c9680d0cc6d713f943812070bf94152f7926bdab9e5908941261244542b832f458f05ed5dc048c8b9eb84c2a85efe717e257796b4ca816948a6c8ea209c0675efb2fb5af4622b44e36066593db01b17f4dee21d7c1337ff41436cd0e5a8d01e4030dcd3d49839e59996fbbf1d39bd205343a424f2395b4d3eacdeb9ed3235d8df0dd00a2573260af63db3116a7c65d1dc69684a05caebff34e3d2cba9d4869a953a7b1fce10ebd008cba021008ac3187bba846abd7b39a1b97c9c07d8080549e313dd58b716022de3c1920329 +A = -8e1141dcebae61d5c4d81697f001d792ee2e847c589816f923f0ed42bb4de0d8f911b8ca47ffe77f80b9da6896a9b42f0030a3276218868bbe1a3fa64fb0a577704339af5dd82e66780da6f58900da3f1d75ebfcc302f78ed66ea3c7a737898a29b1f2500686b43bae1e6571addd2842cdce4d + +Square = b09f5e9472cbb75070a67d025957fd5ac3be89c41e4acbcd5f75780ca459562461082c3f19c5a4a416a668b0a55f31f74cf2ec44555ddc43fde64da0ba781adfac4520dd0f78d04d9d2fd33d8b49c72663a6bc845015523e2e4e7ccc69e5b748b8b891e4089420bf0a3f6032602824c7230b5ff95f85a688dcdcfc890af3384710a9fe32ecf9ad7c6cc5761f13079b19d7b2906c7e63c14b64fc88c6f4bd7c41c0356c777d35c3626d49db8cb2d1e89ce682c7fccc3a459b08c20c4e5fc3a8eced9b37d01bed5af6ce9baff0d2b435e6e62871fcb20cf9ec10d1897a5c76e73a441e07fbcc2d9f4e4 +A = 3528e6581de547de385c93ccf1086a17614f23356a918b25bc6d73656a2302b318963bb679c9a93357f4a4f614e74f2e5e88e9c8aed8a6fdd8434630f664ed15ebb6095cbff1593f188a12f4dd6087a85b202f6c24df68ac3b137406c88c5098faf47d1eeec0743b35baaec7dae29b5a44eb09daa + +Square = 5d5dc40783411475a4aac7c1a1eb760f76fcc6ec68dfebb754251cf499870654cd309422935ec841e6be4f5a15078356235c2b8cbe1ae755cd6d814e811072bdb76156b83c7d2064a202ff90af1e0f88f5889e5729a3cffa9faf33c463b74d0ad21fbb4473d4d3ebfa8a52e9c209ded5ce5131b12b69747c365146fa17ee5810e0dbab992f9da28b6c323062484d62472232721d608cdb9b5a341a677e2d7a6e5a983247d9a4001e16687b489b10b18bbf205f982b7ceee27cc3e9c6641827ab7952373f15d36e5f177b82d7eebb3f5054e12cec82c5f520a2675afdec6cbf6235d358c2fe73344002e400 +A = -9a9a19fcdf11bba84b0395088c5d187d84d69b68b77bc6418f63c88bbd8dbbccfe02917d814f9e2241fa0709817a0c85bd554fe887babae7439d96248514c12d71587c906247b3e965e954cdd57f1e51f1979f73c3237509863169efdf281c1359488daad3d9eb990a50ecf4d3fd25d4820077832a0 + +Square = a4d69ed4c4c9c08116ec5cc49ad458f0fb2ca00f356aeb148f18037bc49621e14820f325af39f3954bddc9cf01de7ba1e443088545883a94c04ff41a7ed5f65676109c5b711b4115775489667e00aa1b77f6dee5ac5c1789bc71c9fc797abf41c7c5ae3e2c1cf82d5b49b6c0da25190dfa9360b99b2f63444d21ec6114038b8284bf598eed24a2ab2b9802d6edd5b0fdb52f60621a87a14612844ffc71ca98180ff0915cf75f47432f73d28dfd7a932a125095655f07f50722b1673df2cc4f7566a1c6035792ff3f02356b9b9d25e905121df768dc6a1884cf5483eeb813c1c009fe4ed043febd61800ba978a40 +A = -335b12e40bfe0b847ed6ec143490df33d2e64ef4363869cb78dec008cb5cd66ea671dba964a53e48267da288ef4040e06371e1209691b81df02f2c86a79cac85fdcbb6732a1e5309fbbdbcd899fdfed18518d47258c9e63ff7f116ef4a8f5c4867aedd907ccc7d222cf8087afebc108f2a0f197c717198 + +Square = 74dcdacc1a4f02a99e3642f54f9d917b117d2ae8d9c392f8b6dee53fac66ebe1680c8e8cc29f5330e0eed3f63d10980060799bc37b34c93dd7b384d4ba30a5b5d42a145acc412ae838d7b9b7137637546d1118f7cf3eadf88b785f0aa01da8638f027c56faa16aba8591b64b45dae6138c9a40309b2ad29c5029a867465f9c6de8fbc5fc4b0442c8a8946272667c7622454ed6f2a236103bed7697dba20db84b5154ff3fbc6b4b9eb67ee43bcaae741d87ee2093ee67defb8eebc4a4a22d97a4e2aa7d4c31a1c88abf4a440ba4e2a5e40c4d903ba5ee4d80b4e8dffb8864bcb9806e015c1ce16490068df87282393111 +A = acf70350e554732c1972903cce269b215e985ecb8d6eeaa67fd5398d0a1b57c0db63368c0f8c2288c3a0466e2b3db081106b90920c46462faf00b5bd654f7140a689b78ef656a26b82af8dd1988f166ea04e9aa777a094d892bc7da4bc7bcf0618526f496cddea6d67df7bb0de9e99a35a0b1b210ff07497 + +Square = 9668b9e40a8bdde3c93943a918ca71fa0009cb05a1f592b2bb2c6c6172b2950719bfd80cddaf45d044cbb6aa99715046088f40ec6812945885679231c07f4200023548ead086b834abd8c8f8294db28b203329553242fd2f778ef5cc5ed0b48c7356d8c2d782a01809ccdb6b012896617f11d963300e7bd38ff512829514d94343476818ddf9d712bc70cffe7f767a9fc75a5630e6250ed45e6831b4660eb49d47dd1b8b6a0dddf3fb3ff0e12834337f145f741f70a2aa43769af50f099e004269ac47fab79e060800dc74da88141adbc46c15c7330931e3a2bed9b958f78b30214f81a64d121f96fbcebf7569fec0cdc6b11 +A = 310e7a40667d9d5dc29744b123cdf6a663a1b995f62fa9d4d853cbae0dd23669f4778bb2040317ebf6a06ac6299b21067aece5c5c1afbe6e789d656745ad66464991cada0eb237c6ffe991cac4670bfc90eed5f8c75073f4f846ea244bca0e9502ff56f8e9bc9b6caf275aaef38e26566fef35329ca45392069 + +Square = 49e677c8b052b7db97542948542449af47e14248021f8d3d3f92b9af41c803072f71050f16dd848aebb270affc47e85427a7c73f227f0d63f140d0d293157af0d972eb5b38de494fbc78ad3a4c3d1ab40197bc4427752b6102d1ced6d6cbc9d7caa0d1bcc57e708535822180055ecc9d9667e0590274b778480a3720823e931ff6daef358b1a1a9092f1f05fbb5b10ad5707a124e8be63bc696f083eb74e5b4f0e3110de8f297ecd30dfd2bcb010dcad4e387520d3d00365fc51c2a3dfe064b1ac77a9295f66beffbe5dd4333e5cd823b0f36b0b94d66507b1d9381060980f62f38a62e38e5a75203233bb8d64089bfd100f3205f1 +A = 898b5f3655de74cec3b0fde2ab03fd18cdbcfc3eeea48ba39317d26917130c2b78e05237cb0454ece268f091cab699fbcd51ce341b53d6ec0cda5d0d5388bac25c6517214a39d03450ef8502e1675bfe8e57bb6086f10ce4cf8ce65eadc865b5bd8a00dc26394f3adb2ace609149e3582cf44246184b2adc0ffd9 + +Square = ad00f10fed55175159b2409dc80899f9113ba7c8099d0402ec0f520ab4aeeb46d36369494a4e6fa23675adb38148fd2efa082df5094c0acfb77a9ab6ba7a299298d69b04b58011c35325f46b765e580b5c05eca721904f1fcc355dbe39faa92af5c9a6dbc4ab80e62b815b45983d9506ebd52b9efa7a6b9da352d1e4fd6ffa81d3b4596a0c14fb825297da361461ff2240e4378340d2ae529932d78f3d9f6b3c6d65d717e66122e5f590c50ce0a5d81ad8e0f24e104c0913cd8d0eb2de4c8cf62a7535bab5502df3fba08bb4dfe73d89c8b00edaa7d5f3274be9959e7ab6b6dde54f2491728a1dc11fa8e1c6a95e67eb7617e9b7471ee40 +A = -349cc2a5658fdbe9ba5c350d3b25baa38b1ede01926694bd550d36883e53d8758e8f1ebe83e2f4560605510413a7d880929e2d9cbc2730b1736dc2689cf7bbcdc68a342b6398e547a9bd67cabe298796d76b98ed4c1dd9c22e36145892e8fcf2258529aed24252a70b6ca8fd2aad8a84becf7e1bf98b1e9bb024b8a8 + +Square = daa3835d3189ec9ade592e6076e76d441838077a9431273bdec02379b3a6ac38aecbbd57c3755ea58ddef8105ac28f2ecc8598ec0c4bfc9c1c80222fffc776722eb0621cdd8a0d55f08767fc2922282a76e529d81e4d6e21a2542b8c9a403709ed1132e3b52786b81e684591438fdddb5df2f0b72e6b39cd2db6c0cc55c759c2dc1b6ccc20a5cfd10c6fd345fc766035c7478570d4ac534db3fdb718e2bdad3d096b137bfc09a562043800957e2afe4fdcfe292881f6189edfce52370c0438c2822ce3b14d73b3eff32f7e5ca97e989326b4e3a8fa35544193f8590bbb0ddb1f914894ab87998090771a0be1fd23917cd792be86ea0b98e6eb24 +A = -ec953f1b7ba7d561edaaa23076987daf86f50e9a66c36f0993290549a9006dd9d424885c0fa77295cfe34fc81c5edce9e2371b3039ea18d8f998d1956196284e6d81eb1c62ecaa8cf3fcaca28ca7e64342803c8dc3c139080bdd4a1ff30d7288b085a579d9e90903bd363b48f2072bb6fbfbd9ba2cab30a8a63784d246 + +Square = b33f4f3ae453058f4e865ec78f0844bab7af66a97dc2f265ca73ae2232777474bfdda39e10652d7386c16f145272192af728893c3d8a8e92c60d77722b924c30269ff5a399a2449ce15e50320c528c22655ad06227ac4efe5a993179ec61c2fc9115f89d75b53961fd16f7797657f6fbf55662b019608a1d30f64a2c0838e0018b7526921fdd34fd462bfcb2462b7065e2bc7abd57d71371e45dfd8fcfcc00a71f7e45430820747c9a060b72e4f6d2919cbffd00beb0c31a2bdc32afe2cc540b38dd04a2b73ae5ba481a6e535f37a757bbd6aaa972986213afadfa47cb7a15a6f1d443f93cb0ed824a10b4b7d82cae524a096b65ccb39be3c37c07f59 +A = 358da59ef65f62f633675764e292e5a68879df24a4727eca1fc4d232b3a6d936976c92eeb11456b5e8c11319838c145c6529d2f3acc828e55b8274bfe9afb5db241b102715f8e8164e454ef39f13ff1b37cf367a5a66c4f743c750896b7c3c29026e448bb36c6c06b0d9a3d048086ef0c3cd922a02e794223f388b5d646db + +Square = cd4246489f6f221f920acbd8bdcdd17f47d2b77268f72254de4190685c123e8c5eab8517fded1852e8316c9e549d3fa355142d91b2921a3c94aafd8862cd2235429340da38a2af131b8d002f17662354f5805f6a7af7afb6dbd2f641036600614cea42bd8b24d86a5109eed29c0865a5f30c5291b1d1ef3223f9b9826dee773d98ce972da92daa19e843f84ca5f1cd77925a3c1117242ab0fb509b94a83f8de4fc8d21f856f37a4d025b3024bd0dbb6d8acfda4ab2993fd6eb7a7448d4f66ec725d37f0eb14eb242c0ff3f0c4572ba6b98a4ce905fe1b7ca3daca56c225171428c56af938fb66b37e99e54139157bbf41f536989ef813af738837afcd62290 +A = -e53ad05c88568f09f616797f0b7f2756fb543d691ec2a5b645c1e5892a247302826419a35b1348cfd2c1c569c23c31b4c46d6c57d4a488c29ab5beb77904d4adfcd0a01ea0a26bb0cc8790441cc2c8c900f030d7315b4319f1a3cf5685a140e03abe6b94730ad79e8de1f4a0cded86a3d6cfe2db267fa7dc9b2bb32872a90cc + +Square = eea8028b26e0df090504d54da714a6f5f2695202e53cff479c78aedd47a8dc676243ec586740fde53b3eca9ca02b91031ce766242184109503fbe25b1b6d318e3cd5970fabd16dfa22984dd2e9f1e0f14c189170fc69c031d66663703e6235a942d51a4545bd7b0769d01d302ce2b00b83f01568a1e378f61fd0ca6201b0490330580cd9de85719e174a71915d7efbf65cd73d8f4e66f27e0dd3144d58ec09ed0f7ed7d1238ee596922807100fb7a11127944ddcdec6a9ca3bbf6df7301e354f3f049bfb7c275b43c3d8cda5907a932fba507c9145ea3166081c1b48fcc710ee32cd931f936c796b14f8a78a592e67753a7c9e428a01719c8ba82652f3a89fae110 +A = -3dcb44be1e54c5a5d7db48055ca9afa1ebe2ae648aa6e16ac497502a7deee09ffa124720fad0ab163ce8b3ea6a90f110ea52b67dbc424d0cf1e8c9726dfd9e45bebcefaa5cd5706edeed27896525f31c6bbea3d67ee97badefabf3e2532470b66e3ae3100f66ddf50cf02fc3a8e3f44c304251d3b6a7ca3a6e4bd5d16a41bd97a4 + +Square = 0 +A = 0 + +Square = 1 +A = 1 + +# See https://github.com/openssl/openssl/commit/e9e726506cd2a3fd9c0f12daf8cc1fe934c7dddb +# Test vectors from commit message. + +Square = 15c72e32605a3061d11b10123c1874836df96999bd0c22bad3e7d4374724a82f912c5e616a187efe8f7c47fcf6945fe575be8e3d97ed17d47950b4653cb32899 +A = 4aaac91962056c84fba7334e1a6be678022181bafd3aa878899b2346ee210f45 + +Square = 48a699fe82f8b62bd2ed18878133575be8e3d97ed17d47950b4653cb32899 +A = 22181bafd3aa878899b2346ee210f45 + +Square = 15c72e32272c4471392debf018c679c8b85496496bf8254cd0204f36611e2be10cdb3db8f3c081d8c94ba0e1bacc5061191b83d47ff929f65be0aebfc13ae68d3eea7a7fdf2f575842f7ec656cab3cb56a28095be34756f264f24687bf37de062822309cd1d292f96fa698c972372f09771e97d3a868cda0dc421e8a00000001 +A = 4aaac9190000000062056c8400000000fba7334e000000001a6be67800000000022181ba00000000fd3aa87800000000899b234635dad283ee210f4500000001 + + +# Product tests. +# +# These test vectors satisfy A * B = Product. + +Product = 5befab3320f8f90542f3120235abd926aac3805a19e343f690 +A = b057af553afb120db6b7764f8 +B = 857734c4c27a1d17f7cf59dee + +Product = -ab1ce167f4b2945c55ae3f87df50ad07d4be87cf9f8aa07b0c +A = ae7a6a87ea8981a567d0b3ecc +B = -fb0fed5f8c737bcacef4d6cb1 + +Product = -c2606cd48e6b075c8da79eb4668e7157f1f175c2860fd4c475 +A = -c28dc31984d4583e9d45424c3 +B = ffc4581a5c3f885cf42767e67 + +Product = aa6805b5408aff7f914472756da07830dcad902834dbdd6944 +A = -ffa07ff9f503511954e5dd3f9 +B = -aaa7af472ad8957763f5a7c64 + +Product = 58ca2569173389df29b5ce4b784086055dee821a7243db7210 +A = af417d936f4690008811a1ae8 +B = 81b26b80b43aa65aa55ded52a + +Product = -a043d31dfce8bd01724d31c863d0a64f1bf013509d77737c42 +A = fb5fae5edefb6997d44a1ecd6 +B = -a336e50c6f7845a1686cc88a3 + +Product = -b5d6a45ffce851b201239d938ba551bab7dcb59fc11fc35fce +A = -f918faa58bb57a2ffb8b01f05 +B = bae08c3006fade695029a1df6 + +Product = 6f2fde7d1a18625d727c6345ed85e597d546d9228bf7f0564a +A = -8d108d7a16f0696d4ceb24445 +B = -c9c764cae465207097ef8d2c2 + +Product = 93808b1140841dc9735cd61c6f855ddbbb83066689b0d7e1a0 +A = b386d08daf3fa2154e9c768d6 +B = d2557dceb2d02d04d9c578670 + +Product = -ad04212ca8cadb1f7861c5130ba3a747046a2a7e4a0c72b69a +A = e4e5f7d1311e0c5f2e404d55b +B = -c18057a328d8c7375afdfd4ee + +Product = -685e75c232f2b4a0e455fe5ee8aea52f292ad8b8178320e692 +A = -a683312f132b2320632e74ef6 +B = a0758f12791453b4af354730b + +Product = 6f588c53185c503dc5b0dc3002d3817ca2e7eb2370b3e9a647 +A = -d70c9b93170261091f0c53f27 +B = -848c86c51a186ac4c9080d3e1 + +Product = 5e3bc5a04e054a9a244bf7c86cae215072fdb70e9199989427 +A = 898b64ef09d7cf63966e1a3b5 +B = af638b12f26aa5d12e97439eb + +Product = -8d8372b235b16108285203c03a8aef6fdd3c0e1a9fd31d4f68 +A = f6003dc83818c14fbe36c9998 +B = -9343f6cbcc81fa4c9399dce5f + +Product = -5ee6509abeeb7af7fc5caef40d1822ad3150c8d74f522dc7c8 +A = -875ff6f56ca72cbdf614bb9ca +B = b375a68a21dfb1f159c22fa14 + +Product = ada25be404a17385af5a330da799e5909da81bfa0715baa6f4 +A = -c9b8df392e76abc3eb7d5ce04 +B = -dc5ab818c70594dd917b4243d + +Product = bb24422ee4656ddfcd50ec38201b15baf679d3b75e5cb878ca +A = f8e12cf4defe388b78510f687 +B = c07ee817b4ae95c2915b88966 + +Product = -93da296ba164c7220a17330647aef0980c94eddd2cfa2a3b2d +A = bc5dc74ddf7a1363d1c2b1f25 +B = -c8f069bad7f93cbfe6df51169 + +Product = -6b2e1d132c4e0b0dc9b7e7de7d424fda5180480cb5ff47c755 +A = -a8048acb66a8bb88df39266e7 +B = a34e0b265d71435ae8c92a463 + +Product = 6ccb2cd93783576a8602ae43f41c786008b6623a4cca0a010a +A = -b071f1f54790c951c1dd2a1cf +B = -9dd89bb4d9b546207e282e2d6 + +Product = 5c742ba47d0d64bd97509927ce957deedb855766cc24c60016 +A = b44f3f252c368096fa62747f2 +B = 83439b97dbac579fa4f7b7d23 + +Product = -7347ba65691c913286c2fb55e45b177f031c1d86ae0e9f654f +A = 937cf0643ffa53cdea24d642f +B = -c81881f78243dd5737a7d28e1 + +Product = -9bc0649a703674e59f83ff9b8a560e5cbf51f65ca310f80f95 +A = -b536f8d9769be6f62da941ae5 +B = dc0746fb101881ae0cacde6f1 + +Product = bf4992fc3a124de350f9fb90ea825cf663b1fa051282ef22e2 +A = -ff7eacc7de1bb01d668c693aa +B = -bfaa6627f9fc7ba68ae41bb2d + +Product = 7c8992d34cc0b63f1c953f68d4e12a99d3f3a34d16bd76caa9 +A = 9e0d5a850d078890a983c0ec9 +B = c9b72c118b3e1f1023a696ce1 + +Product = -a75840c95082b9a0ae0d6e0a4eb5e09288e4e2a66e9697d9cd +A = b2b042a21045a74ef1a5091d9 +B = -efbf8b120b384e869692a1b15 + +Product = -a510b333bdb4ed7479c142e8fbe2b12f7671a42acbe16c0998 +A = -e7fd5e0bb5496b9d876c27f65 +B = b6262653b2be44501af1d85b8 + +Product = a1c1e90afc4684754155526e307fc6ed798746f347bae2c880 +A = -b84674832b26ded0a690a8ff0 +B = -e0b7bdf2fd05a038ed3640b78 + +Product = 5588e0c33bffbefcc5695ca0615abd383343f21a8a0d22b222 +A = 80cad81ad9a66ab6a1c2e5669 +B = aa0453a77c8af1584f54750d2 + +Product = -6460c2fcd6cf3304ab163ea883ac48e2031cd10f2e9014c0ab +A = c49ad3d7c8848d4fbf913b10b +B = -82b3dedbe3cc7cd532ad632e1 + +Product = -a18717330b711669e85abde8c4dce426529aa621ba3da2a477 +A = -cab4a9c0a331a5a5e826dda1f +B = cbfee5041c13075dfe3399aa9 + +Product = 8ab6282ee892b53c083d319a9dcab48af97a1ac8493c0bfcad +A = -f7d13e47f9aaac8c25f9bf75b +B = -8f4aa95231c1e2336aa092297 + +Product = 8f2d1c23c78777ed371f13155445ca3c88cbc0a9b299bdf9d3 +A = 9d8248d00defce1ad081337c3 +B = e8b479295ecd9cef7301f24b1 + +Product = -86d5e0c5b581fe59819730b4b71e33d1f85f9ab504c7dbe2d6 +A = b21b45e88acff48562a19729a +B = -c1cdfebccc763beeac394b997 + +Product = -484ca05aefa113bdfcb1bc623f730c9f9555b462a8ab4c9606 +A = -8c12b406c02c4417163c0956b +B = 8422b15c80c1c087b17eedd92 + +Product = 614c3c91f60050c785fd229a3ad74674577a90cacb654e0a5c +A = -93d45bce155a23a397506d96a +B = -a87e339c3fd5aebede5fb1b36 + +Product = 9683285f194a7e4feeab196a36bdfc4f828035fd184b9cc692 +A = f196d8fe760fdcae7eb60e2f7 +B = 9f7d88a2163ad818bf3a6377e + +Product = -988a64599c19cc64f3cadc1a83fea6550185f6cc3ab82af822 +A = d0584b2a306671e4d2c9d0c7b +B = -bb6e7559df199c68d6df3a3c6 + +Product = -68456814cb0edd951196d04c853172afdd5787a5bd69a57876 +A = -cefce1b0a1fb22862418bb597 +B = 80f614139947aea5e76cd55fa + +Product = b4b1cbf5d6566e7a57aee0cc5c9c8ec4ad885e8766aa7662a4 +A = -d68ed1bea046c6cad057e21db +B = -d7988b9be54f6e332d019032c + +Product = 6b09212675ff5257a1384371e17b37dcc268bbb141577902e4 +A = a8208053adc20a609d5d01404 +B = a2fa927c5458c4fe662d7a3b9 + +Product = -8361bc26f9bcf55f677e047d822d3004027da0d0455b244d10 +A = e82b6410b29020c2d6810a977 +B = -90ddfe0e7f0d6b9cdc0815f70 + +Product = -f1b6da00923fd513a83e32040a515649fbd362f69ebc016d9f +A = -f9b697d9ec774a8d1ee5ea905 +B = f7ccb46a8869cb028492bed53 + +Product = d06206963f2e150bacdb32c823c3a47f013d5a267c3c0d0c88 +A = -ea8e63afa99c719897ad7f2ab +B = -e36f11f55b6148d1b4f46e598 + +Product = af774a5eae6084df5ca499ef005642730adabf6a4f9533e2fd +A = e4c7af7eea3ec9cc2443b7319 +B = c457bc264c8461789931baf85 + +Product = -76350f428bfbb95e6c253ec0f457aa84cebe8c7cb1af2a2120 +A = 8fd1ff97465775d44dee58ae0 +B = -d268a7d328f44baf80e35119f + +Product = -787ae3f114f9a8dd4d249d5d3f3b0897b02564b9469416cefe +A = -bc0b398bd0ec045b0cf147b7e +B = a4050955c234e473257d0c641 + +Product = 9d6320b3d4aabac097a079b9bd2aca7f1898bcab0f23409fd0 +A = -9d7a4ebac630cc0662b816fb5 +B = -ffda517d3eb3214986b04e290 + +Product = 80bab8bd800ac8c9dc3bb57dca306f10af6fd88c5d8314833c +A = 834bc50140d6c6ab938dc58b6 +B = fafee47793cbc533b3c66af3a + +Product = -b08920f5922226b1dec87151ae087d8a7e5c1aea8c9be148b6 +A = bfd5b1ad323c79428cb2db36a +B = -eb956a10edebdd658e6810fcf + +Product = -6d428e08e8350bb4b0fae3b662c82df2aef7beadaa17430dbb +A = -a57da276998c548101f514e9f +B = a9040c1909712e1149d295765 + +Product = a57da276998c548101f514e9f +A = -a57da276998c548101f514e9f +B = -1 + +Product = 14afb44ed3318a90203ea29d3e +A = a57da276998c548101f514e9f +B = 2 + +Product = -295f689da6631520407d453a7c +A = a57da276998c548101f514e9f +B = -4 + +Product = -867614005cc204a8d19720fe13 +A = -a57da276998c548101f514e9f +B = d + +Product = 12bf3b676f64e5929d38c35e803 +A = -a57da276998c548101f514e9f +B = -1d + +Product = 24d8f92c68303ed0b96f91a8167 +A = a57da276998c548101f514e9f +B = 39 + +Product = -49b1f258d0607da172df23502ce +A = a57da276998c548101f514e9f +B = -72 + +Product = -6fd5e6ca25c3d51b2e529f22173 +A = -a57da276998c548101f514e9f +B = ad + +Product = 1276d4705b81b82da4c7e82559d7 +A = -a57da276998c548101f514e9f +B = -1c9 + +Product = 1ddb9abfc5d4017f068a67b5f4fd +A = a57da276998c548101f514e9f +B = 2e3 + +Product = -3a8b41c914b1b4a4e341433601f7 +A = a57da276998c548101f514e9f +B = -5a9 + +Product = -97c0f4ba414d6e7d4c8b7ced84d4 +A = -a57da276998c548101f514e9f +B = eac + +Product = 1198739e0c23639c176d46d13f7c8 +A = -a57da276998c548101f514e9f +B = -1b38 + +Product = 159150954ee0dedf541e4dbac0ec3 +A = a57da276998c548101f514e9f +B = 215d + +Product = -441d4bc44c86f02ff12c3d91a1562 +A = a57da276998c548101f514e9f +B = -695e + +Product = -64726b76005ebee27592237ba5dde +A = -a57da276998c548101f514e9f +B = 9b62 + +Product = bbe4ec7cf7c5bbd198e0ea86bb658 +A = -a57da276998c548101f514e9f +B = -122a8 + +Product = 21f717d05681fd2eb1796776a69ef7 +A = a57da276998c548101f514e9f +B = 348a9 + +Product = -396ac788a1748bc6955f99be4d2c64 +A = a57da276998c548101f514e9f +B = -58d1c + +Product = -54a213eb083aed1a04f3d1b2da62e7 +A = -a57da276998c548101f514e9f +B = 82eb9 + +Product = 1366fb9c20fb14b8b9a9be4b3e3dde1 +A = -a57da276998c548101f514e9f +B = -1e037f + +Product = 238d65fd26da4733e5d93ab2485d40b +A = a57da276998c548101f514e9f +B = 36ff15 + +Product = -38272a99be154d531e922be405aee9a +A = a57da276998c548101f514e9f +B = -56dd26 + +Product = -64651b62b6a454c08951632c7f2c398 +A = -a57da276998c548101f514e9f +B = 9b4d68 + +Product = fb272e3597b816144f8b945ae6130e0 +A = -a57da276998c548101f514e9f +B = -1848320 + +Product = 280d9f5ed7243712ecb9a7c6358bcb8b +A = a57da276998c548101f514e9f +B = 3df5795 + +Product = -2fbb6bb8e1ba78cefc47fbbc20e188ee +A = a57da276998c548101f514e9f +B = -49d6652 + +Product = -57f29c13691ffa1642d2860dab9d288e +A = -a57da276998c548101f514e9f +B = 880c2b2 + +Product = 139c19d7668e6aabf2d7206cb0723ed34 +A = -a57da276998c548101f514e9f +B = -1e55aa4c + +Product = 2950ce04bf0cf836d4fe94b88fb757d0a +A = a57da276998c548101f514e9f +B = 3fe968b6 + +Product = -5175239488dad05a58414251496d2a06c +A = a57da276998c548101f514e9f +B = -7e020414 + +Product = -945ff0ed38bc6020cf679cbd3e0758c6d +A = -a57da276998c548101f514e9f +B = e585e573 + +Product = 11c69ae98f6b27e95477986f796bc67c8c +A = -a57da276998c548101f514e9f +B = -1b7f653f4 + +Product = 209afe75e8fb5ac76d13c06b545f5d4d73 +A = a57da276998c548101f514e9f +B = 3270154ad + +Product = -386d64b215e41506514f4988ed237e4da2 +A = a57da276998c548101f514e9f +B = -5749c891e + +Product = -6c13cccdb1d140d0babd52707ea72fa278 +A = -a57da276998c548101f514e9f +B = a72fb6288 + +Product = 136228a8a45540372b9b3cd7f82021f6546 +A = -a57da276998c548101f514e9f +B = -1dfc08a2fa + +Product = 1f0ad3babf9d132eaa08cf5cdb8f19dbf01 +A = a57da276998c548101f514e9f +B = 30050f2e5f + +Product = -50d615ce183258e95af77319b766fac81e2 +A = a57da276998c548101f514e9f +B = -7d0bf92cde + +Product = -817d358293b86a56a4e881e50257c549471 +A = -a57da276998c548101f514e9f +B = c84efb12ef + +Product = f09b9e80be251de474d726b16e25a6865fc +A = -a57da276998c548101f514e9f +B = -1743322a484 + +Product = 22996cb0f9c60e35dce49f3825f8a479db26 +A = a57da276998c548101f514e9f +B = 3585acec11a + +Product = -2b307a37c91791a61c0691858f5f783e4678 +A = a57da276998c548101f514e9f +B = -42cf6be3e88 + +Product = -8826698fcba6c30d755fc523de1cc25301ae +A = -a57da276998c548101f514e9f +B = d29cc8af592 + +Product = ae37fc99fd419809310782714530d7428d77 +A = -a57da276998c548101f514e9f +B = -10d8059d4a29 + +Product = 1d544a20f9bc7d95ab67d1f65743979f23bba +A = a57da276998c548101f514e9f +B = 2d5eadef1c06 + +Product = -367897184e9929a0294d320f10278889fbeb7 +A = a57da276998c548101f514e9f +B = -54431582d0e9 + +Product = -943a509076a00060a2e7fa1cddb7468d734a1 +A = -a57da276998c548101f514e9f +B = e54bb102f4bf + +Product = fcce6e42879af5ad13545c0bcaab85b690cea +A = -a57da276998c548101f514e9f +B = -18711db522cd6 + +Product = 258c49f86d0cbb14ae9edbd3456be8cede2022 +A = a57da276998c548101f514e9f +B = 3a1562c7c269e + +Product = -4a8bbce59ad7daa51136d557f7fa16e9a2faad +A = a57da276998c548101f514e9f +B = -7350e780b0f33 + +Product = -82f53ec9333275d5cc271876a7db936db49280 +A = -a57da276998c548101f514e9f +B = ca94ad312dd80 + +Product = 11daee4fcc713db5b2806e47fa5dff3b5b770eb +A = -a57da276998c548101f514e9f +B = -1b9ed6758f9635 + +Product = 17038cac4f0c94dc24985ea108ae6682e175752 +A = a57da276998c548101f514e9f +B = 2399b8a9b1116e + +Product = -37e5f14394bf347a3ed061769fe8e6424af4348 +A = a57da276998c548101f514e9f +B = -567840a7569fb8 + +Product = -9253d4a32a88d8f725984514d969012ead7cc9a +A = -a57da276998c548101f514e9f +B = e25b246f733f26 + +Product = ace3648371c16a931d29004e79f5b9678391da5 +A = -a57da276998c548101f514e9f +B = -10b717b27b6a13b + +Product = 1faa5b45d04c143c339b09d3aad94d39b94ef960 +A = a57da276998c548101f514e9f +B = 30fbd672e106aa0 + +Product = -3fdfe246d27aae0d08d63b2bc501461d2bff3b8d +A = a57da276998c548101f514e9f +B = -62cef5f078a8253 + +Product = -5b792bfaeff04ee3d948cb343a249d49eb344f57 +A = -a57da276998c548101f514e9f +B = 8d805ac65649c49 + +Product = c5f824406161eec321da5a58e3e00d393b55abe9 +A = -a57da276998c548101f514e9f +B = -1323dd41d2e1e077 + +Product = 2226dec8a57be8e84e42559007e2d101ccbe67f8d +A = a57da276998c548101f514e9f +B = 34d47842b5d0be53 + +Product = -340f50f812c7420b502000940788a700f6769788a +A = a57da276998c548101f514e9f +B = -508836d8e1193d36 + +Product = -a00f1d96e19c590479625c5329a87774b5964cc78 +A = -a57da276998c548101f514e9f +B = f798fc858657f888 + +Product = cb94f830cba8997331912a6a31c34f1bef826d121 +A = -a57da276998c548101f514e9f +B = -13aec7a5c52a0883f + +Product = 16b45140b048d6dc0b9fc811df7ce7dd88357fff04 +A = a57da276998c548101f514e9f +B = 231f27f3e347bd67c + +Product = -2aa94179351b4e87de5849ab619d94f47450640199 +A = a57da276998c548101f514e9f +B = -41fe3ec2189599cc7 + +Product = -5489401d3da93158d4284e557d74016c0a7cfd935a +A = -a57da276998c548101f514e9f +B = 82c5281df41bfc066 + +Product = ae04d5b212ecfc9a6d7df07794d565df52991fb70e +A = -a57da276998c548101f514e9f +B = -10d3139229f5d02432 + +Product = 27821bc811f45d63089790b41d307be978d4b19564c +A = a57da276998c548101f514e9f +B = 3d1da85cc012b3e234 + +Product = -3de3c9e9d7fa3020a578706339314890dccf63096c2 +A = a57da276998c548101f514e9f +B = -5fbcfb28bfc9044bfe + +Product = -627dcb299a6720044abcf11469bdfd3f951edbb5bf7 +A = -a57da276998c548101f514e9f +B = 985b930517b78e6ba9 + +Product = cc0622441497a37fddf1856d5e2c99df52b99ea4573 +A = -a57da276998c548101f514e9f +B = -13b9b88948fb7e95cad + +Product = 1a5168e1a492210591ad1ed660adde9110390e4caf32 +A = a57da276998c548101f514e9f +B = 28b631c6e04b6ab0d8e + +Product = -4d8ec27b7460ce616421b9f5cae708c2ac241daa59b4 +A = a57da276998c548101f514e9f +B = -77f99bdf1eb09da6dcc + +Product = -55afd796db7bce822a00073fc8926d3bd0c79772f036 +A = -a57da276998c548101f514e9f +B = 848cdd6212b9bb3620a + +Product = dc494b0d73e8ec07cd2bb6dd8191d2b4d48e7700cc34 +A = -a57da276998c548101f514e9f +B = -154c39567bd8be5f6b4c + +Product = 240e9301b4345b914ecd91a49a0e651524dcecb6fdc6c +A = a57da276998c548101f514e9f +B = 37c6e7ee89cf87674814 + +Product = -39002ecfd6d96661b336157ccef6536756ad2e9219be3 +A = a57da276998c548101f514e9f +B = -582cdab09915a652203d + +Product = -695f49fc891d53f396f0593efae3973082b76d4f9e944 +A = -a57da276998c548101f514e9f +B = a30074dbce2246af043c + +Product = bba2b7b45b97cb0d7fb30fed95089870742ad69e7aed7 +A = -a57da276998c548101f514e9f +B = -1224195afc7b394ae8cc9 + +Product = 1910edc278515ab7d4cc09b496dc3c06c32c75bc7368af +A = a57da276998c548101f514e9f +B = 26c6701c39334169e7bf1 + +Product = -3670b7f9b661aba35ce50984d83173c84c8fa60e04d100 +A = a57da276998c548101f514e9f +B = -5436e84b4a29858a68f00 + +Product = -7fa0d3e0082b37475342b7e22e5dbad7b8d4cb5d64f871 +A = -a57da276998c548101f514e9f +B = c56e0f44fc63bca242eef + +Product = da7fe3367ce640fa5941c033ac1874312f10ba5950da75 +A = -a57da276998c548101f514e9f +B = -15200043166ff309f0426b + +Product = 1871d72481f66b1d413100edd6b339cbbaa67b3b2b3cd57 +A = a57da276998c548101f514e9f +B = 25d057879db26fa29a5e49 + +Product = -3cf1dd1e2df3456757d72f35353c3c7a659b2ef844ad857 +A = a57da276998c548101f514e9f +B = -5e46be70de21949df67349 + +Product = -5e861cbe47aefab2a7ea59292aab1258932b9a322f66e63 +A = -a57da276998c548101f514e9f +B = 9238670897685a6c9cbdbd + +Product = f623344788efb857db55c924e95a437effa4dc8bb2bcd24 +A = -a57da276998c548101f514e9f +B = -17cc0ec84c228225a7cf45c + +Product = 15514c916b0ae7cde6add16c629d3e19ba52a101d75dff72 +A = a57da276998c548101f514e9f +B = 20f9f925b3ed307edbb154e + +Product = -460cf5b14f9d0b547c3084bf44207bf881745c409b08d07f +A = a57da276998c548101f514e9f +B = -6c5cbfd29f3dae1dce99221 + +Product = -5ddf7fb91d765af97dfda5333d8779e80837c2b51cfb4f43 +A = -a57da276998c548101f514e9f +B = 9136aa79080defd1bcf90dd + +Product = 12c1a0edfb6ab6a0caae2553fb3743827e1470a8954e0a3fd +A = -a57da276998c548101f514e9f +B = -1d03b512470dc3052779f3e3 + +Product = 28388a244214abf046488a8d95308d95f021eae4b994a5a52 +A = a57da276998c548101f514e9f +B = 3e37dce784274962ff862e6e + +Product = -4da476e76119deef291c0f56934a912a0877278a19a561ee0 +A = a57da276998c548101f514e9f +B = -781b2f2dc40094a7f8fed520 + +Product = -5792496d33dd45e225f9dfca17419a04e075ffc0c90b37b82 +A = -a57da276998c548101f514e9f +B = 87772a4fb582acafd3e4ef3e + +Product = dd3a3506a7d748de16fb43d666928a87de0354d8e8a1bcaaa +A = -a57da276998c548101f514e9f +B = -1563841bf7851ff158a395716 + +Product = 24e8fb09a9ab0808ff643122479dea5ed41060c6c5b74e8752 +A = a57da276998c548101f514e9f +B = 3918c30b5568318a58e9be16e + +Product = -366c125f96b38b58d01c939c27c4100af3377eabb792b5491a +A = a57da276998c548101f514e9f +B = -542fb814f45924aa09a16f2a6 + +Product = 0 +A = 0 +B = 542fb814f45924aa09a16f2a6 + +Product = 0 +A = 542fb814f45924aa09a16f2a6 +B = 0 + +Product = 542fb814f45924aa09a16f2a6 +A = 1 +B = 542fb814f45924aa09a16f2a6 + +Product = 542fb814f45924aa09a16f2a6 +A = 542fb814f45924aa09a16f2a6 +B = 1 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899f571f257fa81c36a868d80e7fa2bcbda68a72ca3e31db8892b94d073e006433dd7128b7bf677d2b411532e5662cdff66d657673d58e03d4a338bae1a5513296f91d4d2b5b680527a2e12318e422ec2b7f05ea4fd3ef4780576488211dad5733685a8f0e5d2ecda549a15eebb235495e70d26b194c994cf16d98d356218d08a34d1593d90bc0d3572df0e84bdb1705c6c5e64ea4895599bb21bf219abdd4329813ecc198e708cee199c22f749bdeb0c206690e8420883f6c0661e47b29969986a7a72996ef63234c31aa39b7be37995d2898063ef5c3b672c43afbc1a065dec2671ae87e17639cfcd3148145a8323e1e9dc4f9c9daf981dd6aba4e8be01344c2eda185b87 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899aa73af54a4e1825aa6714016da99d9e3d0c02eb139716db437705cd9efabf0123b0831689735f4e488f226e577d4688d30914dd50ed368939452af0a7a094c065c6718bd54f53a808585fc1728c3bd1e7c968d76c6dca32f95a8323bacad31cdd4aae544d4208262c40bcf726c2f26cf1e60341c3e1e0c8ed4542555b9bf00488680b737a245cc9b7817231f1f6f1e614cdf43ea281fb850ebbb9305b1aa441a45dfdaa1e98b9d79d9ca511be070bfa94d8cd3cc750607c93e1b451a14e32356bd48d77860b37fd2e714827e770a5648ce8579a00ba5cae034502a8b03ba754994d9e002130cfdee6bfdf078dc8f6767b927c964197664c8e32bd3d31bd461ce +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46feff82a92989bca577998c68ee619d9ea9972c6f139e97f5bdde635152830bedf302873508d2ed73badb82f9e32e1f4d12ea8c8b1059aa6d15f8e17d649bf41467903ab40d220d50570b5a263f637c0fcebc0ca29f8a81e2a01bf39bcb60cb9229dfd40618f706b941836bc5c291dec45ee9193e74d3a4cc5f73054ca56fd774a359f17a687268587393b76204a37cd48dcb09d3daed57a7e6d7d93a0ca3d6de8557fc4ddbfe9cb163fd10b7fe5f270dc57aa2fb88cdca2a3795015a17fd352d85fb688a38fa54883d0cab67aab08dbabd58d307c601f0f810014d78b101ff0bddb6d550b2480782406a905b9201e70ef6c1cb9765e91c10c8f5d240c +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e3812764dd3ebb7489e6e66058ca6ccf9c007f8c049eda369b2889cc411bca78d4f5b0e3a9e80243e87e112072b01922b595afdef4dd562e58ce917f11e69c8fe050de54fdb2d607d05f09afd6dd140e9d195b91d85269610a1e5d5036e8c9fea2d4fa693d80ecdc819b201c0aed27dfe0b92b4b3b9ecabb3b9548f0d27dc917ffb14308c4f970863e163f375852fcd9fb115640dc40534f8f51a7b903599117dca6c80924fa9a1aeb43cf5a9a3f67ae818b484feed51d7ef60b3656720891b13a983c02c281c8a0954f13b7bfaca844d2cb66de5c11ff507e39cf774c7c93b38e296a44f04e5ecf2819b57943fb0509774ddbcfeb +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c58ba611f7 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d8899c7bedb01951b0f4fdb2c0fb64ad74707fda20027f4cee25da9b59be288d404cbd348f27600b87015d28f03cdf411f0e8c22deb9de5b3e0094f7820d78d59c90017cbd426297f8a32fb4b55b09362cf7cfb5910085acb24dbf618752b8b74c7e87f9cac44cb3b7486c43aa9b19a64d40a74eaf1de8b5f168b43d5750236aef753278c11294efd1adaddb6addb846f45fa55d7391898e8ec1c82bcf0008d9850c4c096571e8872e975dc8af1ba01bfbe8c8c27dc30cdaddd198936e4496579741a3a20e1b8e17241fe4abe5e98794e469180b742b2e1904940381f703f512885bda0340fe74e997ab269be00a3ca29bb937db2e06d8054e26dc13a5014ba51b175 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a817a4d88997cc097fe3f7ace3ffb0fcee52b45551165bb02354b229788b59128489879b1a0373e9862a17692464a2dfc5d09185a0f1c67d2359ba70b52b03f21c7b24feb96e25e1a2dc7f4723952bf203979f7c9e38790f881e2b35006157825555d4c867fce9ea0a3cc6f1c94ee308a68e33f64f286247465ffe854033e9c64f5d79d6d66dcb38ad03535b20376bf4c3cf26e07ef445192ba2baf08bb5286695a61ff6b5dc7aa1832017198d61a324b8c244572157323c7bb3a2fee226133e1b0e0f2ff067cf71fc24bf38d0e172f459b0cdf0707c5bc586390faacf428bfdeb04e850ee0c35f6807eb6ca8d3a473dcc2239541115a8b0d33ea33295ff8c13b2a +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a80dbb5a46fc245133c3335163cce37555d36c555182e6d9a754b9aa9305c070083d0fe806d2c5eda4a976f749d6ef40515c425e6531a7f4d11926e49907b7a8a938205e0d6fefaacb145200cbe3deec686476bcdc1f6bb3535147ecb00818f2cd666ac0dd497f0fbc087bf05c6425b7752a02e2a695655d4310f04943a6178946a74dbe4688bd1eb3f1a166aef37e39f3e1d36b6d6d422ec0db264cae8d44869f57a92952bd74a026dd7cfc672803905f029c723487d4123a7520688fc9c68b2384be32e881f64d0ed7ae555bf00e5799740dd8c6accc40f3fe573f194f4848bb05aea8a5509f2dd10fce023093f1ef20267244a990d7ffd462f4e85a4 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6788e14a9e353744d86d954c06f3b84ef271b184ac9957a5f88b08b606fa6aa97afc4983a62f1e74aa3f242e14a3f4cf5ea415d1437818663556a29d117ea7df1cf1ee32f70d6d5566e25d53f892c42d3f92e481b622455fce36e400de09e2d435099695354ceee249c793b76b3c544d70164381e0420ef8b85609502afff9130729ba7851e0775dc5d8c606ba614e7607625fbc38908c88fac43e29ff9b8728f5809e63f20289246b5128016478437550a833c60edb0df43dd9a47654f2e4ef308d4a18cea57ea4b0c6d08add07f2e7adc427cf591c29dbd1f975432922e3f2b71c75e4d2557efccf626be7a0d522b658d420ae321 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9ffec082c5 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7be8e75d54e5ba9405f671d624eaf8d7a115d0479f6fb773b940525fd46b69bc43c815b6bb1798813ca95790bc68032f0b9e73fc964a9922507d8aac25f859745939b828ef5ed326b226b555e5088f13531be16272a89ad41ae82c940935b5d8fe75dc520a230cc279a887bce01bae0a79356f044af13c6f4a5e53c00b2d03cfcbb0f93b26202441a207ec91576410ac1750e257906d945bfe9204b73fc417600bd191edcf2e3eb79acbf4f84dda372405b5e98397abe85c1593543cd7a5b17cb90e299f422f0ce107d86b56474e435dbbcbb5314fb579cd68d54777aa2d0ff9b6b96de62b4676edea5b09589698ed829cad22a52aaec732b79edf6af +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a8126efa5e7739032d1f8bb68307f4adc912f1d9b83797606874d4f2c669fe0b263565c4898a07701585237aa444234719adb869c17142126611a9cbd6e689fabb2847bb9dc5e2dc89694621a7179df1fe7371deb9bbdf5fea0b271d86bcde2796a65331c27365fb97fa3647435c47e5c854a95718fa49072cc239d046ca0ac2bf453beb31070370d59483adb42b9876776e43fccb663887f1a999f625eb8e9c4cdd0a89099c42cdff06be29ad9ea66a957002925c9425a83c3e74096ca31324134f5d4a2b7d3b8d7fd8d72192049f79c670874f65201c068c5aac2008a7df4e5eba02d88be8ec23683513a9cffe06671a7c2fa5da7a7aa571914caba1e +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef989b0c6121e293a808857c1bdb914ae0fec75b02d527263093a9d9b8a42289ec74dc73e0e46568a9e8ee117659597434048308c9b66fa7a539694285b1238a13d1163fbac33db147e5431af1c7aca5b1a118db4f6650ec6340491ef7a2d203b53e43d536639f980eb6e92a37bffb2149c5eb45d6718a9496f0784370674c1d29732b944a3c3885b68f0fd2a121f556dc82d1b942e7aabba780f087b9df359d86e2055248c3aabc568e93bba67d3ccca2c4240c876506d63bb05aad6fc4c77dfafff1731a46c6711bc60c4d23976268928bc63e1d133add0633c737bb508c81fa1ff3b452b49b992ebac930432d555ab8c62ae17357b1186e80689672f5a9f472c +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96c826c5268b0a6783ab6c7314a43e85a92955a5fbfbffcd31ef0913ba93563dab2b7f54d90fa21ca827ad15b5b1fb399a303f94837536b2813cb563f793fb780e91f8333a2de7bb9f10efdb652a504d6f242e7c15362d3a6eb6e3d1a5abb03023dfe964656979765a14fe8fc36af3d785030ce549b92a91dcb8e2aa13f5b89eb8449b31961a0f77117c8cac79af95ee69f6594e557af7bb017cd885027ff7c0cb1d2f99d1ed5eacb788f645c25150e737cf1184b546bb2d55f2014a18015ffe647580df6fe4d528ce983309baeac0347ae8739e2b1f6d1a83e12e4dbfea1cd81b11b8628837432ad1906c70323529b718c8c6e398e1dfa73 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc95262b94a0aca2f9f +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f225bca564b7e6561b56e0edbb3a7f5934f382b916ab38423221d656357ce0e9bf1e9b04c0678b9c555e8365a0f977c95bd8dca1fb2ad2268193531ca36cbe7f40da8e1afe097e451dc2931b323ce731c03cc027a92ed8ae105c5e9c1bd385e238d989fadbf3aa54c097a8666df8a66b7e2d016e65a2a632603f2c84290ccd7346ada28dff79dd06c7f7989689aca4f494b977f984650f91327ab9936cb92675932440f135e54e4abeecf255d7061482b4c8d91769e02fc94b8acc43325d69541903c3ef7a7a8a5bd19bf886506d42bcf0efcb6197a8d178d6a60516a5aa771ae238a342dc61df8c18c6ba1ed952d4e0c3409c14639 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea39224eed9ef1 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c374bc58f2210cc134828c520a58df29ae28863a158a044937809d7d84d2940efbdddb448c64da5f1f31977e7865fd5529eac82fee3e804064a6315936295f8cb26f0de16a47373f5e8365939e280a57dacb508166a583a630c75730c2fe54971e70a35e224e7a1a21e3bd8f417a47c4796d34148cae15068e19eec637bed8f32846dc5aa7e8f50599e840903a8129206fc384e0b4085f9f1e7e3bf2fc67b62b02566ce73cb4b22d471cde35b4f0cccb74283cdded5748d62286f7ea5c184c1308d520ecc7c7f1535b1132708298bf94c0967bc8f8541bb2f2b3c81f11e50f1d8cba4ce3746ad5f85e6bacbefada657c9b386b991b2 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954a6ea3922 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef96ebae79ce1360c36ad2daaf856508e861c7f68a2611a215a93e3a15f68f72bb80a4fe9f4cfb6c7f91639179342c633db0f70c9dd849b5b5767908b27e61b812659dcd1a0613433f2c0940be49010886bb384d4676bd523f9827c1a48c7649fbfa73e872a5160796813956979b0f3fd3af728dd48f8a7348090300e41b181c8acae08a3b3106b61f90b0421803e6eba0d68e9bc93d3b659fd6316ba2815cb4b3b6a74f1f3fd24b0c07f619d995ac2beada44188eb72d371a6894f90087eaabe148755409bbff60114bcfefbfe2182e6dc4218d0da75af80059bbb14e848c2e60790fb35bf1cb685cbb133b2baf3f2faefcc3f69e34102def4 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad1eb654821c4af954 + +Product = 4f993781409d730da892c8451cc47a4c5c132a2c079f6c13a2689e9552450ed0b35c5291b82aae5614c0fc34f777940798a33b8bd5e010eb3c5c88595e8668fc8fb88ccd3d0cd5eee7c88e5b0b2be4605980fea4f8f2e42457963abe7860060482cfa2291e568ea55095ae2ada1c6bf9fda228664c9e02e7f12a8da4c355af044a537dd65dbf9c5d746c3c5f05a3d4d0515a48d9434b38fcbcc485558964fd9f212cf3c4aee9c03aebc468c25740df679d17823bfb20d96620c64b29f4013f0385cdd1a40fcbec3b06132a52aee615c4dbd880d0b030d5bc6aa06801d21fabd49774cd81ef504696d9655652db220ef9518c8ddd2bbd782e5f8cb06be77fc8d0c29f12d4ce67bb2478369710d003f0cb6f40a1341a5a5f2509d2d189084ea4346a44368a54f44c2be4c7b90c4d22976a31985927d0379b2e5d715a7e67eb3228943a07325a29316c695867e8f4ff676e00ffca0a6dfe8fe24652aef9e7f12616e8a54e367b90942f543a01dc7c1b8000ff991228ae83fe0131cfc235ba12ab2bdb33bd4ab0ba1b356bdbc6da4a70eed9fbf2c704e14ed6230eb5478dac0b02f4def1d8c076d1c0c0e2c4cdadb248de4acf961cee51dc41e545bd5a605a0860fb343c28ebf3f8814a9d5a7e0f3e9c93e742db76bc5671258d1da7758b41efead5 +A = f33cad5d3876f0b60a001e13043e41033ee78c29ed8528fd6f22a87fc65c8c650277fab430722fcf63b3984c35ac46883127d544e2f44a465647814e15c0ff595382eff8bdff3be862f8a57a51f27ab4af9899861240855380f5bb883476699ef9eff179a1b88c64cfd6648240a5fc68de054468dc91dac11aaebe696dc05b6b0de0f54bd365ad798f3c85bceaf6ddf976b72cdf69de58335520d358f90e9856de5357dd5d2686cd1a41293d8c2687ba2cb1504420ae2c07014521889172b30df89521e2f66142345115110adf3dc603b1ddba5d80dc6b42fb980e9994aba2dfca00a3df8ea9062f570ec7e0e94d2bc9 +B = 53c66ff2bc0e0d733d26f809aeedd151406ae8f44104f4e58f99e3eb54b06d542806932966bdbf30e13d81e5d6fa96f5308fc45613894b49dc7b766af02738dd89b10ca372d6232b0cbd57dcb873dea3c7598ef69b58ea5d72a0f2aaabd71025b488824a35cc33f8068ae4cd999fbb536be54e07f26df5d3bf8705281c8e94dd3712ad7c6a88f9d7b04f6f8924e18568ea07d46e58d197984824d797dd9ca1efe9763c62cc55fff69fad60d6501765dcf4926c18c027b4f9825d53cc38e99365c1b869245e66e7792f40dabeefe63e404cffc1d2ea63a9dd3fd4643afb2ddd288c6d4737abf20cec860584a7a600b4ad diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/quotient_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/quotient_tests.txt new file mode 100644 index 00000000..d848edee --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/quotient_tests.txt @@ -0,0 +1,1839 @@ +# Quotient tests. +# +# These test vectors satisfy Quotient = A / B, rounded towards zero, and +# Remainder = A - B * Quotient. + +Quotient = 1 +Remainder = 0 +A = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c +B = 8cdaaa7c422f3c2bb0ace2da7d7ff151e5bdefb23e6426cf3e6b21491e6e80e977bfa6c65931a8dee31fc7992c0c801d5d7c + +Quotient = -2 +Remainder = 1 +A = 107f0e6cebfe22ac11294a06fed2b994d01c9b3610d50bdd254adafd08c93be8ebdd1e85e1286fe9c9e682a90cbbd6351681b +B = -83f873675ff11560894a5037f695cca680e4d9b086a85ee92a56d7e84649df475ee8f42f09437f4e4f34154865deb1a8b40d + +Quotient = -4 +Remainder = -2 +A = -3d8746ae2123c2d3f1d35910b42af1f86f5e81f8e98986cea20b2a1bdb8af6cf111f1258f112c837accdf4868463fe9eba536 +B = f61d1ab8848f0b4fc74d6442d0abc7e1bd7a07e3a6261b3a882ca86f6e2bdb3c447c4963c44b20deb337d21a118ffa7ae94d + +Quotient = 8 +Remainder = -3 +A = -5645d65662eaac73050de06f8f982a9b2ae680467712284be3e2b0e58ef4bf4d72b5be5e12ee1fd803b47f161759662ff5c4b +B = -ac8bacacc5d558e60a1bc0df1f30553655cd008cee245097c7c561cb1de97e9ae56b7cbc25dc3fb00768fe2c2eb2cc5feb89 + +Quotient = 10 +Remainder = 4 +A = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4 +B = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b + +Quotient = -20 +Remainder = 5 +A = 12805392c55ffa0e27e85e15f2b339872793664e9ed3074cd2600aa52459a57197130d1ea46775ef43115c9413248cc7b34805 +B = -94029c962affd0713f42f0af9599cc393c9b3274f6983a669300552922cd2b8cb89868f5233baf7a188ae4a09924663d9a40 + +Quotient = -40 +Remainder = -6 +A = -3579fc4d6083394c691b060cf9e20318fe17da0487337f76710bd11512578830ba94ac7b587a2d5ab7cb4afe611e349cdcfb86 +B = d5e7f135820ce531a46c1833e7880c63f85f68121ccdfdd9c42f4454495e20c2ea52b1ed61e8b56adf2d2bf98478d27373ee + +Quotient = 80 +Remainder = -7 +A = -74ebad4b39ebaaff82cd91082408c979527907c363d8f0f75db410523f8477c074c45ff85851b6275b1ebc5279029818e78d87 +B = -e9d75a9673d755ff059b2210481192f2a4f20f86c7b1e1eebb6820a47f08ef80e988bff0b0a36c4eb63d78a4f2053031cf1b + +Quotient = 100 +Remainder = 8 +A = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c08 +B = d2d8a4419fb3b1c22bfca04ca08c2ee066ccbc9fce2f41861b5eef91efd3c13eeb7eae5abea0ef1849662cfdfef7bbff892c + +Quotient = -200 +Remainder = 9 +A = 1bf534da2f4365c96fc5dd4928e73ac24b157b5136ead90cf6596033ec387a2c14bca828000ae1725f3a5ace8ad67a8c07a0a09 +B = -dfa9a6d17a1b2e4b7e2eea494739d61258abda89b756c867b2cb019f61c3d160a5e5414000570b92f9d2d67456b3d4603d05 + +Quotient = -400 +Remainder = -a +A = -3a172cc9483774544311a1366659d9e61cc9fac7dc11c68e36aa991ef4d5e96becf5bac3e0967c904d926617ea11bb9551b980a +B = e85cb32520ddd1510c4684d9996767987327eb1f70471a38daaa647bd357a5afb3d6eb0f8259f2413649985fa846ee5546e6 + +Quotient = 800 +Remainder = -b +A = -5ecff3a3e47fa615b6e3ce2dedfdeefbfe1d437c394631820968a9650b59dc3a2dd1c9a0b06537e4e5c408a59e580921503580b +B = -bd9fe747c8ff4c2b6dc79c5bdbfbddf7fc3a86f8728c630412d152ca16b3b8745ba3934160ca6fc9cb88114b3cb01242a06b + +Quotient = 1000 +Remainder = c +A = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae00c +B = d3ef80fca0ab3ac3432b22e2b485131d816810c39d02a9c82dcc05ec5e6406bc216026de3abe53ab103ea3b2ddbc2ea377ae + +Quotient = -2000 +Remainder = d +A = 163956bc32325f28f48d41d32bb08d2a9c4ccbb0d818368fb13941e82b27da21d04094f7e897ce79c2d0ff8470505f1ef63fc00d +B = -b1cab5e19192f947a46a0e995d846954e2665d86c0c1b47d89ca0f41593ed10e8204a7bf44be73ce1687fc238282f8f7b1fe + +Quotient = -4000 +Remainder = -e +A = -3763f8e43bd05e6ffeec6d509bbe6ff9a9022ced8cb191c9abaf5fd0e0b75a53e2ad581455e3af09e702a77b164ed3fb54ae000e +B = dd8fe390ef4179bffbb1b5426ef9bfe6a408b3b632c64726aebd7f4382dd694f8ab56051578ebc279c0a9dec593b4fed52b8 + +Quotient = 8000 +Remainder = -f +A = -531dd44dfa9e79a5aec8fa7c84bd3b753c146770d22d2c14a6d2125f7ab95e9b320e84c31cf3e0d883e1295a220f2a546550800f +B = -a63ba89bf53cf34b5d91f4f9097a76ea7828cee1a45a58294da424bef572bd36641d098639e7c1b107c252b4441e54a8caa1 + +Quotient = 10000 +Remainder = 10 +A = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c20010 +B = 900996b61f58713f0755e68bbdfa4e0bb47f034bb0304f77829847923d14715def1771f43b526c41b9667438b434d2b966c2 + +Quotient = -20000 +Remainder = 11 +A = 179d7ede3db0c105525286551331d5b9e1f97a7883f0c13cf250afe9765bb5aaa527af7945c19cdd4596565cbc8532a3cfa5c0011 +B = -bcebf6f1ed86082a929432a8998eadcf0fcbd3c41f8609e792857f4bb2ddad55293d7bca2e0ce6ea2cb2b2e5e429951e7d2e + +Quotient = -40000 +Remainder = -12 +A = -293dc443c294c6a6c53dd49e84f58305d59a432afb6c7ea2039cd02a513231239571ae07f29b5427e869b9faa485511ca45980012 +B = a4f7110f0a531a9b14f7527a13d60c1756690cabedb1fa880e7340a944c8c48e55c6b81fca6d509fa1a6e7ea921544729166 + +Quotient = 80000 +Remainder = -13 +A = -5b637eb8aa51ef15a18d9b144031c9756527fc0fb96c84b6df03700e5079ae1b3e96940a2c1e07f3b47ad8a9b2b8ca99171a00013 +B = -b6c6fd7154a3de2b431b3628806392eaca4ff81f72d9096dbe06e01ca0f35c367d2d2814583c0fe768f5b153657195322e34 + +Quotient = 100000 +Remainder = 14 +A = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c19400014 +B = 87c846f5469d4c5819aed0c7e77797209b2c1b83a7a0e2be70280b9f30946b5db9bd0f25a06cf4bdba1c7183a1b9eb75c194 + +Quotient = -200000 +Remainder = 15 +A = 11c2a4509f419aa977c3d37fa446fcf21b4b3b9f983fbaddeba4f51c285ac4032200711a54cc6edf24297b1f3d46ad020131a00015 +B = -8e152284fa0cd54bbe1e9bfd2237e790da59dcfcc1fdd6ef5d27a8e142d62019100388d2a66376f9214bd8f9ea356810098d + +Quotient = -400000 +Remainder = -16 +A = -39e37ae0edd92b957e84682358039f5e432c42492a44f3de01cdf74d643760260f2837946608663e12291e9b0695449c1153800016 +B = e78deb83b764ae55fa11a08d600e7d790cb10924a913cf780737dd3590dd80983ca0de51982198f848a47a6c1a551270454e + +Quotient = 800000 +Remainder = -17 +A = -72f725edd5a3dd6f20b5e9ca7da08a99f8ec9214c80588182c0d42e03bcff34b488b28c03cdf41813a6193c10672a8ee68f6000017 +B = -e5ee4bdbab47bade416bd394fb411533f1d92429900b1030581a85c0779fe6969116518079be830274c327820ce551dcd1ec + +Quotient = 1000000 +Remainder = 18 +A = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018 +B = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd + +Quotient = -2000000 +Remainder = 19 +A = 190790727c1514b4ef83a1c6aa07493c0af7087fbc8a675bfd9a1e97b8ef80ef684219d6c6f1a5fb5b919f105fd7717cdd5aa000019 +B = -c83c8393e0a8a5a77c1d0e35503a49e057b843fde4533adfecd0f4bdc77c077b4210ceb6378d2fdadc8cf882febb8be6ead5 + +Quotient = -4000000 +Remainder = -1a +A = -22d115ab02f8663d8c009960086a0275d301d358cd3b250bb9e7c16cc6ebed4a8fbe43bbced856d93be64a17377d95f5f9c8800001a +B = 8b4456ac0be198f63002658021a809d74c074d6334ec942ee79f05b31bafb52a3ef90eef3b615b64ef99285cddf657d7e722 + +Quotient = 8000000 +Remainder = -1b +A = -41f2e708ba47494a13607223b08e6d99c0b4247436632961d873804e83446dc97139ffaef3e25969950bd4b5bb4ff73b1a25000001b +B = -83e5ce11748e929426c0e447611cdb33816848e86cc652c3b0e7009d0688db92e273ff5de7c4b2d32a17a96b769fee76344a + +Quotient = 10000000 +Remainder = 1c +A = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336000001c +B = e4b52f78179039499c2f6b500840f41103fbd60eac0d7082297236f25189c18a8301a92f533945047fbb83427dcade334336 + +Quotient = -20000000 +Remainder = 1d +A = 10888959278661bc36089519a215bda60f9ce24ff7c0ac1f543b6e652f94dbff1f32aa40cad2b4b4d676f16948551501c29f2000001d +B = -84444ac93c330de1b044a8cd10aded307ce7127fbe0560faa1db73297ca6dff8f99552065695a5a6b3b78b4a42a8a80e14f9 + +Quotient = -40000000 +Remainder = -1e +A = -3ada453530a180fda58533ab8c62beb4f693a134f512e4d23e487dac3b575e5390c0a90992400e402bb47aac93d46ded55f54000001e +B = eb6914d4c28603f69614ceae318afad3da4e84d3d44b9348f921f6b0ed5d794e4302a42649003900aed1eab24f51b7b557d5 + +Quotient = 80000000 +Remainder = -1f +A = -57879eb5d92d565daac3ac5173639bfe44b6ecc69ff770af57bd79c9b93841c5677042cb362b794f3d8b24b0d3b73ed1cba58000001f +B = -af0f3d6bb25aacbb558758a2e6c737fc896dd98d3feee15eaf7af3937270838acee085966c56f29e7b164961a76e7da3974b + +Quotient = 100000000 +Remainder = 20 +A = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020 +B = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d + +Quotient = -200000000 +Remainder = 21 +A = 1c267719338a4562e934bc57fabe6da86ca534a34244bd38c15032f01f47c2fd498c83f644b345c5c661ada0e586a096bb63000000021 +B = -e133b8c99c522b1749a5e2bfd5f36d436529a51a1225e9c60a819780fa3e17ea4c641fb2259a2e2e330d6d072c3504b5db18 + +Quotient = -400000000 +Remainder = -22 +A = -250249f2185d4b428fa9534f03ef3cbed535bd31c56c0b273e6c3d35e0266f7777a6e59a99da5738b8e3af8ac60061d6716ac00000022 +B = 940927c861752d0a3ea54d3c0fbcf2fb54d6f4c715b02c9cf9b0f4d78099bdddde9b966a67695ce2e38ebe2b18018759c5ab + +Quotient = 800000000 +Remainder = -23 +A = -710b30c23c3c4e646ba90da33d2ce35af2ff181c40b02e3ffa607966730c6b6e274dd4c3c78e578e0b10f431f2d832274bf6800000023 +B = -e216618478789cc8d7521b467a59c6b5e5fe303881605c7ff4c0f2cce618d6dc4e9ba9878f1caf1c1621e863e5b0644e97ed + +Quotient = 1000000000 +Remainder = 24 +A = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024 +B = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719 + +Quotient = -2000000000 +Remainder = 25 +A = 1ed1b7d9e4cf3d44ee98ef69850e61a39f54cc407c6795c07c887374441fd9ec258c21193f8a8c55802fb8f8c579cf94cb0ce000000025 +B = -f68dbecf2679ea2774c77b4c28730d1cfaa66203e33cae03e4439ba220fecf612c6108c9fc5462ac017dc7c62bce7ca65867 + +Quotient = -4000000000 +Remainder = -26 +A = -35d324ba37d2000f960ca1c9e1ab96e341a2ae6a5ea5cef014c73a39dde000d8ad9606b817ad67e4e4593cc5894d354854898000000026 +B = d74c92e8df48003e5832872786ae5b8d068ab9a97a973bc0531ce8e777800362b6581ae05eb59f939164f3162534d5215226 + +Quotient = 8000000000 +Remainder = -27 +A = -7039477c3e0a6f415e25e9f9b1dab1edcd8a23f984e7e3bc149c206a3b756b1be001450af4049cd4535e4243d7032afcf6790000000027 +B = -e0728ef87c14de82bc4bd3f363b563db9b1447f309cfc778293840d476ead637c0028a15e80939a8a6bc8487ae0655f9ecf2 + +Quotient = 10000000000 +Remainder = 28 +A = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba340000000028 +B = d6c59dd07409da98f7bbc7ee471b6e06c4d9e832e9f4d04ed9da63564d37d3072a950564cf549bb5d6e7dc85565d3cc8ba34 + +Quotient = -20000000000 +Remainder = 29 +A = 14d27a16a9cf2fdbc85b88a604dd8f0e57b5b34a27089d75d805e05fbb367dfa61c085aa98b896e3e53b85ef774a3fa52417a0000000029 +B = -a693d0b54e797ede42dc453026ec7872bdad9a513844ebaec02f02fdd9b3efd30e042d54c5c4b71f29dc2f7bba51fd2920bd + +Quotient = -40000000000 +Remainder = -2a +A = -3bd0119619fbb5b260c44050d61e6b1925a49713d754ceb06bafb1d730a93f199df654b153c40e75096ebbaf5a6ce3c801820000000002a +B = ef40465867eed6c9831101435879ac6496925c4f5d533ac1aebec75cc2a4fc6677d952c54f1039d425baeebd69b38f200608 + +Quotient = 80000000000 +Remainder = -2b +A = -61a283fe41d965ee770704bb453f689cb82a81089422d6d904a91776a06d32857220286e6ef6327807b724062dda143b46890000000002b +B = -c34507fc83b2cbdcee0e09768a7ed139705502112845adb209522eed40da650ae44050dcddec64f00f6e480c5bb428768d12 + +Quotient = 100000000000 +Remainder = 2c +A = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c +B = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1 + +Quotient = -200000000000 +Remainder = 2d +A = 1eb7cfb197d19f56ad994eca52d1af6466fd09da07d68d63067602046b2d42d3063ef5eda6b58afd69fd92b0b727a0ecde1420000000002d +B = -f5be7d8cbe8cfab56cca7652968d7b2337e84ed03eb46b1833b01023596a169831f7af6d35ac57eb4fec9585b93d0766f0a1 + +Quotient = -400000000000 +Remainder = -2e +A = -3ab858b3329e5bd0469118be52a867b2febbe2894d962cedeb3a5be1738db1cea106cd0710c9f6937348c2c63b109ae623d500000000002e +B = eae162ccca796f411a4462f94aa19ecbfaef8a253658b3b7ace96f85ce36c73a841b341c4327da4dcd230b18ec426b988f54 + +Quotient = 800000000000 +Remainder = -2f +A = -6137bae6cf7573afcbb6fd5c066ba37648cba8db0ecafe9dbc66959b19deabf42f3083719a2268b7602bafa2140a1ee8ce7d80000000002f +B = -c26f75cd9eeae75f976dfab80cd746ec919751b61d95fd3b78cd2b3633bd57e85e6106e33444d16ec0575f4428143dd19cfb + +Quotient = 1000000000000 +Remainder = 30 +A = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030 +B = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7 + +Quotient = -2000000000000 +Remainder = 31 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -940693131e2ba7b2af531803794983337dd526f0d84d08d58723edf002a388d55c8502d88c2a2a6e78233a2a1b1c8d339a13 + +Quotient = -611b743a0e2acb1043bb33de50a59eaa0405b37bf6b622075dd69291fe5b53305dbfcc377d1f3082319c153d0c1ffb3b3346 +Remainder = -16e346b6a4297 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 30c77f3380ccf + +Quotient = b9e34073d5e6e5b9e5d2d7250150f8ad86870faeb88d5aed5029fb25c176de216e2388e0f5d33f7c3b56102873eb40b06f2 +Remainder = -16ebc86eb88339 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -197b6f6ad5b75c + +Quotient = 141bc8752e846cd63743e6fce4a22efc3eb5f0ce46ba81b8f578c94c516288ec3610fc9923f45d4af2b94c0b0a20b48ed0a +Remainder = 9bab19f12d81c3 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = eb90162ecae18b + +Quotient = -381bd85c951e1dd775b0d7fab344aadf06b1b592c643b5852fa44aa55159eedf3b3e47fe0d9f399ad92da85ab2bfd18240 +Remainder = 1e4f817a2f52b71 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -546c109fa8a9d7b + +Quotient = -5e385a83b56830626cf8306acc232f955178080e86384bbcf92eec3a8961360223c4cfc1d8d118022972e61866cbfc46b +Remainder = -292e149300fdd1ad +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3246242094394c8c + +Quotient = 9af0246f4b49316df43f61ae3795a764fe9b1d071ce227982ebda7988a7a7a98129c94a76635c6913cb15e4f75ea1608 +Remainder = -dd3b3e32ddc79cb9 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1e928618913898b2f + +Quotient = 1fe40099811c648aa4e84e4fbb8cbc19706774a11391fc03a9667d8dc72dd0b26c4a46d0bae56ba90fe4bfac1517d241 +Remainder = 16e021603d30dde2 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 948887c1634f4b08f + +Quotient = -3f4fa4c179dab02ad461bbea8f890292c934496db560f72878323a4463d77ae261363f4dc8f53eab145fcc3815d3253 +Remainder = 407ccb4f0b814dc5c5 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -4ad17434071e1ce664 + +Quotient = -4d17d19f7f6861189a520776339a1e425876808111c303e391118714370111151ef4ad2e6e84250f59b0fe09ab3293 +Remainder = -36f745b0f421d16db7 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3d71635bcc25183cdde + +Quotient = b976d544af44e711351c6618106d3a002c42ebbe22fe939a2457d24e8dcc35c95dde5c7c77af6b4545344a198be82 +Remainder = -107334ab98e5099fec5f +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -198a54e35fa0cfa328a9 + +Quotient = 1307bb8e89aaff7466bc238d32672fbbde7be19d15423bcfa14f9a23fe85af9739b72807fd4bc420ad0b0fac37a42 +Remainder = 170ebe9b83d4c43b79ab +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = f8e923a8bbc0242eafe3 + +Quotient = -3925a167c1c4d2fae265f277302b989466e309a7211e0b7173031cbbb91ab7fac8dfe43c9d832764e222e9d8581d +Remainder = 4d404e93edb435dbd60af +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -52e36cee22274556059ea + +Quotient = -4d5a6ef346a872142b999ff9a5429198b3c2a97e968f55aa2c01583efe30e9687c57e2bca2372db4d3d443052b6 +Remainder = -3a2ea5f9d204dc31f21833 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3d3c79a115d9071b573d2d + +Quotient = a49dee54430f1737a04543d5f549efafab25f0f28f5e304f1bbca191f99521c2c4be1b9927bde19e1ec2060bb2 +Remainder = -17d02758f8fcadca911a95f +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1cc65a75211f2826c9d0811 + +Quotient = 1808ab7c0ccac2ff8f7cb61248bf4624fb60352a356fdd1408904f8c6fb0cc52b7642ec59183bcaf5dd89ca0ac +Remainder = 5c95323f3b8861261dc31ed +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = c516e6e3fa6e3dc52cf5933 + +Quotient = -437e04d7076794850aada0cb4ca7a1055df103e74e00766be6a2fdb2631bf294cdbf2695d0a2f8f9eb5587aa5 +Remainder = 1fc63797594c56160536faa9 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -462ee529b488d1db2b6c60e8 + +Quotient = -5dde5497accc4575a412e7232ce75bdf7905936e09e382d5c9f133faf82a05ad9dcc94ad858aed34cc14c714 +Remainder = -15e79293d5e055f906381a899 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 32765b0a34c88864d39bedaae + +Quotient = 11ac52a9287472e1d3b8577b3d50c95076e190714796761322b3ce869d96b44387e190e824849ee345d0a22b +Remainder = -a158ccc7c055d64e7df3fbcf0 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -10c061a37f6cbd11bf0c327643 + +Quotient = 1ff5cda1551867577c5ca72c86516a82fb8fc5f59ce967b73c6bcc1b85168389872c9a747ddf044d6dba174 +Remainder = 21e766a0020ba429b330a325d5 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 9435cd2dc2a92c950bb9e69b83 + +Quotient = -2719c892fa3f4dbc9951b2095056a16159adaf32dff902e20a800a0cc2e858ccae408f2161aae25d3e1f6d +Remainder = cafbe9caa1f83fd0dd3d5a6881 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -7924e4dcf8f96da61f54bf83870 + +Quotient = -5080dc99dba295f4a2d9a474c2ddfa3b232a82fe629fe62177514988983eff8195b37d3fee3afa343b497 +Remainder = -94ae72f78982ac1ff83f300cfe8 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3ad70d4b6b9b5f5b2eb65da67e1f + +Quotient = e475eebcfc53d49ffad2e0c2a4ba48fe7ce02c42ff107e01ab3fe5b26eee45c83c4f58c181d77c259155 +Remainder = -c83ac7582a02b47ee734e0f24dc5 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -14bbcff5423a260b21895327b18bc + +Quotient = 201308a421b85291d23465d648ad2a8d6f3393efc16fb675a42ea7bbca635ddd8c2449b1b34e5db30a03 +Remainder = 8e07efb8ae4c9df39533042362081 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 93aebb72a81ba68e8881fd1a56a90 + +Quotient = -2584cc534f88f091fe471c652ac66a695906a7cde1fc1cde9be3ee09026b690c1a899378ff31f6acb90 +Remainder = 794801d9d5770a60e312b99d6b9f91 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -7e408caf387a0ce9bbf4309c80755a + +Quotient = -63f7bfc0fe5a5421bc0a19fa6c87713a72eeb2a33e5eadee8c2f32c20d14f403ab8bdc424b9e8e0c68 +Remainder = -24227c242afedee2473c1a66a5cc29 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2f622c665af7f8126eabfd90df8e9c5 + +Quotient = e557e6d2180aeeee5d2cef453fbdf38e84cc148f4608ade8836045498be2d318520ffadcea6319432 +Remainder = -dd290149e0e159f9ba6bb9f5a4b003d +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -14a7623d1d9dfc177e913d3119d0d30a + +Quotient = 1651d852316d472b41ba0460566e43fabb9257861859ad0fb6ea5a6433a4164299e078f4d50c58afb +Remainder = fb60aff5fdd2a2b794b0d973ac4d92a +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = d439da27b5e70342aa5cb365ece15665 + +Quotient = -3ae357761a8ff43d3b1bc53eb336260342a39d22f8fac44eeeac96c2f6de32580dd6a688faa9c515 +Remainder = 4fa6f7ee4faf2f6be99c5ce4b65cd642f +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -50700f9c0da59482165a47a3eda2bf07a + +Quotient = -543b4390e4e254226683aa0b83b2ca176ec27a373969fb88f766ac72adc9125ff83b2652e46afd3 +Remainder = -12ff398d9a7d9e97a7f63a0bb293c8fb0 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 383c5a4f1767e83fc382ad4f1c7c2b7ddb + +Quotient = ecb72c14c59d49287fb6b2cacdf04619ee617d5f3f0f1b2890fd4e79746a4fbd848613cf5eb437 +Remainder = -1035512a2717a89062d48f1bfd213333ed0 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1402b751a1e5f3fc46e22b43240d6ce9b27 + +Quotient = 1e800ddc5d5126f322298383f32fd593623eb88a91b2d68c5d9f56e20c16ffe2cefabe873570ab +Remainder = 72935d534bed5ba557b91ea023601f50b1d +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 9b4df766c608ff3efe5ea1f65cc850fa73c + +Quotient = -2c2dc2378abceb983904cdf6728f361d279b4c821710ae785724a7251c43fe4f705f023afa7e2 +Remainder = 249f6433af4e8e224eb570fd438197af62f3 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -6b382f812816c77d65c94c0c660b31a69b8f + +Quotient = -5f3ced1e42fbd3c6b2c6f1e16953e0c1bb6efb4e49566f974a968f69a1a66a3d7558f5a802a8 +Remainder = -317a7fb1af65982fe4641fbb1e5837e6ea3e1 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 31bc97372d17038fd842b72eaba2abb26df62 + +Quotient = af3fef8111c449b9e0858e7e53e1d00b764232f7a077d75043249c387ece30af351c8a40335 +Remainder = -a1493bcbf57a8480461d62796aa8f8541ece4 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1b076b2f7b78b4a0f0e24ba3a05d6c697efab9 + +Quotient = 196734cefb08f09cb32ffefc07da8d9545d3451d5a08736757184bad94c73be71311cf1e01c +Remainder = 273e33521f4d74840a96b3fffe169f79d32855 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = ba7746f4400f812919a3dc86b00642e1487691 + +Quotient = -3c5989cf33145057a9c8e904435d12939db519cc6b9ca1c0a11934399cb139a73613950f2f +Remainder = 456ebf56c636d54e37709b9e799e83b7a08cb93 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -4e7d4f389423f42e980eda55b4a6a45f6f4bdc2 + +Quotient = -8432cf3338bce1d12586f83025aea50cff3864af3eb2103a36bbb0aba10b0ba4831641633 +Remainder = -4f62c678137df301c4bef216e6aa910104e76ff +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 23d4c57b5a8162aae8d937be12efbcfd7b96ec06 + +Quotient = 9f94c4399eef16dfc65a1e015e0786c86470299865932c4d564b71c9b1551a9c0308af38 +Remainder = -168b74a6073b4a5b54fa14aacb5c3bb7897ed0fe1 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1daecf01ec633610373b79e04c22cd7499012bc66 + +Quotient = 1d5b838dce6c0324f157ad125adefde6e1045dce9ff97cf8d1d39b79bce02128e3433ffe +Remainder = 3aa816216d55fc3c910a030fd10fbda1e12f2ac2d +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = a1598a12a84e9cba42ea0e200e88d4599c9f615fe + +Quotient = -3edb182b53890ca8762f3039d2d71a8a27c36cc884d0879e0635e6326af0182bc47cad7 +Remainder = 4610b2b1305220bc0de584dd3f87d90109012a8077 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -4b5c2f1ba3a82047c9de61d47cbf1bec86b6ef90d6 + +Quotient = -7571ed4c509630886483f6ca0923859e644063acb38cfb338bf3a681fe449501262516 +Remainder = -21c579846594fc3e5efc53ab01576a7b32d69faf41f +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 28550e1f7c6492f4cb682c37b105f92b049c13fc03b + +Quotient = 9ed8fb31327a110ef4377258681c5287de8ef9dbe62aa4fe84a7f2a94bb69607cbdb2 +Remainder = -1b7bb759dd0ebc346cbe216e56be8063f063490c17c5 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1dd1e61caed1efc07d21ce05d889de1ad65808cae026 + +Quotient = 1aa716227d1ca6af68286062b2d6dafd7ade16abbd5d6fa4ada0365832fe18f73bf35 +Remainder = 32e714b0c4ecefb38735cb88cd5e07c21c81be858cae +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = b1b959a7b3262d7f4dff488315903aeaffd982b726d7 + +Quotient = -2a9979a530046939e0b43a25edfbea6775784eb5cf346a9fc3a2d22e1aad473cdada +Remainder = 4edeb91a2472e80068b1883cf2cc45d68ff9bbed1756b +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -6f31bbe097587a68fdf01d0bf93830bd03a23920ccc0f + +Quotient = -566ff76814e1c7d31ad53bfb9f3c0607ef1f7d1cf9bdee6e1cfb78b3ad7018f8bbd +Remainder = -1eac095d6d84021c33aa9b219d191bd0637f20b5920eed +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 36ccf5bdece624b4f54c729a8cde13325d8dd764f44894 + +Quotient = aee4f377611179d8b6315811dd94639aaaee63e99bddcfa8eee297ce1dc04daf8e +Remainder = -59cb3ba7efa1637c46b21795872e8deaff90f13402cfaf +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1b157ad838684b45065aa77ca3238a4d8c5427f719cdfb7 + +Quotient = 1c72d32cb83cf4a9043d3bb5002f61b03e29c34e44a9fc5cc4d613726f5e618546 +Remainder = 7312d11fb5828c7f1a0060a5152a7644fc1e6a59de28d03 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = a681444c4d47d829f7b629b561ffaa0c3be1232346c907d + +Quotient = -2702afc4095a0396215e3ca36e2a59725f743b30de0dd8d4ec4d943fef6c37162 +Remainder = 223dd3080ede3a64744b14df8742cedd71388b0df99073bd +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -796c9ea38ccf516a2054a1e584c18b64b996c9679960585a + +Quotient = -805585c6a7badc933bced6f8373ffdfe9796e963d3fc90e85b1a22c38f842062 +Remainder = -a6ebff3f651644915d5c466cc2915d104f0f85a44e08fd6f +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 24e8fb7a6a3057ddcafff92916c46f7e4038b98c3104ae831 + +Quotient = 10383ff8feeb180d4fde925b534be97ec3d5f1f1dab5d8cd9ab5d8ea646cfcdf +Remainder = -a7efdd0401c74a69cf74442fe3da907acf92e8edc51668828 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1240a71ed8d81e86fd9b16e1d64f438b35d6f8eff672494017 + +Quotient = 195d95a520fd22317492117dc756ff97806c48c1aac67a41ae56fe503a60cec +Remainder = 8b8692bee56f8a1ada9ffd8b3583eae33a0df9b73a7d8585f1 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = babe02063b61cb90634ac0493174073d2419e00728d46ad2b0 + +Quotient = -37791adae674b866e4791c107a697363847dee4a58a37806391426ea48b8c9 +Remainder = 33986fc6a5f5c4f4e31458fc7de55e08a4e9320509d90299b93 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -5563bb852e7338c65aa21c516eecf47f498e5788c608ed46cae + +Quotient = -68a30494eceff55e4f54a556dd9b30025ccfa22c0952fd746adfd13d31d00 +Remainder = -1b511d0ab81d528d00a1058850bef48df2e9ae9357e779bb9231 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2d44e919fd27bb3fd2093062d11830c30fa77febafe0a2082cc6 + +Quotient = bd30999592dbeabb8871b76aa04cc1c6c3794a83f0178c2ad505d8189485 +Remainder = -b0dbce286df5faccf0bdb40ca60f508d436f9410c5e49c3f1360 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1909930e2d16fc877c15895a3ec8b2125858bfa1c5a1b8776bedd + +Quotient = 2171694ef4a9d57b83b09357a511d4e11cecbab5e9387928b480d686a0e9 +Remainder = 29abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 8da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b + +Quotient = -267d470f32911150d9944e684c14e1834734b15475bee968748dd5f6502 +Remainder = 53a2ffef61709bd7143c4c876e021f20a99ba481f2b11abcd45da3 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -7b117ddccee97816c2ca2f1a612cc0d94ac67f5a79ed41744c8fc7 + +Quotient = -5a21a3bdd3a3d4f1361a978706ba1cec409c296a5b3c369e91fc8317bb +Remainder = -2cdc818f1e445fb3772d2a56833aefb2f5565a5fca80662e6fc1845 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 348dfba3c793f0018d7d3a70c4060c3148b4a3163ba60af9d6f8b04 + +Quotient = b301b4050fdf4ede8f9c746b26d968110e1eb119ca42cd9c9bd8d4fab +Remainder = -17993daf81711fe59204ec82e363d2b91971129af9206ff9506d3cb1 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1a76328184b9bea8770c91cfccf8ab98e75b2224d666af58022aca80 + +Quotient = 19c401336dd43c221a61264f8b91791d250e6c99c61850efe6d1e3532 +Remainder = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d + +Quotient = -38a77853de88a8db14612884b515e3cd7c673175779d4ab71ba58f83 +Remainder = 51851549cfa00dbfae388cc3b46fd4824268e00e12fba288acceab339 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -539c0171f48e4160e5c308ee9e74f35d8b6d032e946dbcf748b1335a8 + +Quotient = -79a7eab82e5b65f4f6734e8803fa7c30852ea3ae56e801c5dd11778 +Remainder = -f89592eedcbcc68d5df80663b3cdc638d9d779707d4ae5a552d97d009 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 26efac15401a945ffd37066bc5af23191292765164a0f1e4fd537fd64b + +Quotient = d33afb58753a21581c5b2351a74f3d220599ed56ebeacf1d43eeb2 +Remainder = -f699437f44af44b3ddc080f5b74f753d35f70baf3866040ba3c64b30f +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -166cc6a3c60facfa0d8d318f26c6514c7eb9113f6b625c1de804ad379f9 + +Quotient = 19e55bdaaa5a375c36e6869700f8677db563e5cf985be2a8d1b012 +Remainder = 7bccc3a653f29f3f45b52b8de2449c868c64d976666c01bff2dca03a8d +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = b6eae7a82b5dd1554795573cbf558d7cfed813eec270c326bf290adccc2 + +Quotient = -297530094c3e4270ab5cf67e60fa5af6a32eb41b18b050fa6d46d +Remainder = 62d8b502e172da7bce53fbb7c1ae376b6c21b3a3a47523aa0023406e353d +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -7241ae5f1aaee9340d437ad2dab94b70dd29fc6fff7fe31b100aa5001644 + +Quotient = -640f3c38230962c6d6fca459afe0e46137525e8d62dd9b84da73 +Remainder = -16fcadd5155910764ecf0b4bd0afc3707e2ce49cedcbd5414f1c7d860e95c +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2f570d2da7a4e62097eb494ca43f7bde33e36525308dc864ffbaeb5d48f97 + +Quotient = b3895ebba13c8f383ac0482be02e1f5518511420cb4513426bb +Remainder = -21bc847fdfd48c7a4c36c778681ea20481081cbb7af6b281c8b8ebf2b2c3b +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1a6233954b3480af5f911a6bb8ad33967d5e0446c3e56f521e892c986b6b82 + +Quotient = 243f3fbefbf842c79c5e96162fc42fe4f177a59d27681c54b3a +Remainder = bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff + +Quotient = -30f7cef2948c9ebed8fa3c5ea9a9bfa96ee4e9729c9b18e9d3 +Remainder = 1feb3fd887629cca60c664e385dddf538d9bf7fff2d34ca9e0e7614946d807f +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -60bba60d69093c0134fcb90aefdb9c190e7bf037ecc13dab3cc7915d7893046 + +Quotient = -6b6f0183c1f598a68683ba7435c05d700d74681fe472669a1 +Remainder = -1f4d58f81a8c18523918d31791a00ea9aafbbb87792d90a5392273ec4e405da2 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2c17372a5128d7c403a3b94838072ecf9aff88d164764b12bfbf6261df957e2f + +Quotient = c4347fe42b2a7d9d5a650b72724369c5c1f59262a7be3fc2 +Remainder = -1103ec9c4a15373949cae4e34b7b42e242da41edbf5ad8362ce5e5426d3154a1b +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1824671758069b7660bad819f06c86fc76a9344ea38412058380363e5c5b4086b + +Quotient = 15e8c8d6847dfe974cefeef5fee93da9e58b74d640c6c413 +Remainder = 61dac240f2b39832903d5ecad9cfda5162bf8ebb0610545f259b75c3dc6ab8771 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = d83386fb9682576cc70cf84520c53169e391b414f5421cddca6e257bd77753c40 + +Quotient = -3572711bf994e6ad48535cc4d65ac323ef1ccff530b4337 +Remainder = b5899d4cb879e37022c539962959339d055900cca16153da09b54c658753cf50e +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -58a05faf5c61f85ac5a090b6bb045c851ea17332d9bfad4309ce2b7a79ad3cc575 + +Quotient = -6931ebfc6e34305e5d7cba5284829d088d1ec0abdde508 +Remainder = -1b09eafde481064bab3a5c7fd895edceca40b1e62a9cf953eae1061dfbe00936391 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2d0769f392ca9ec629ef1bfbdf08cd8cc9219330ffe3c05343df792dd94b1147714 + +Quotient = 9a4800f0cb2bfbe8d234410deb510103b7da30cbac7d9 +Remainder = -971e4a529e439a1b96b942001631027ff2fbe40b8939e224adb7f2ed30faff64d1c +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1eb3d7971125a036c3a67d9f5ce580a4ef4c469a492be53a55bafd2eafd4032b5b9d + +Quotient = 23116704b7a1a86cfa2ee5707ee46268634db5d50dc0f +Remainder = 467c6b64c8121e4f250492191ea36a27119a0a6d19af519bf7ccdc2436c885c99d85 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 87134e98f73470e23a96c6a9139af3d4d21574de8aa9ea1d720df8940bcbda343694 + +Quotient = -3b7f72ecf4f55c02366c52f38a827f5773b7cdebb9ba +Remainder = 194b334b2046a66be3ddd7c6df01c88967fcb11e97b8206d000bcf6043c6e9ccb13f5 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -4f9d0341cadfb1f0bc38184d93503faa196fb8170f8ba2b5d3b512c09d39b7f79a5b6 + +Quotient = -6db1d69019dd4cb26fd65d5b88a31bb6413b30278a1 +Remainder = -2042a060391e181882dc0c8d91c3b03c1ea35e2eff01babb3ae876ba1e57a505d44856 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2b2e8f445c0c3aaef0285945e4ca37a700310e003086f34d02c891b94b117f3d3032fb + +Quotient = c0e5b9a5853bb21b5e2e37f469764579d5cb2bf984 +Remainder = -154669d4bce7914cdc8d79f2b8d1faa43e8cc3b20fb0767e1c9a47c9e1daed4b665cfdd +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -188e619dbb719381e701363de874fe168529c10f30d3ff184e4356991fdec1649f72235 + +Quotient = 180054f8c36833d44cab9dd61e6d89d28605c564af +Remainder = 59192ec5c6fbd9773b8b7dd7d8ab1800dfecc8eb01c29997d15ad75b79575d9e26e1fc9 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = c55b5eb165c63ac2794bfac21980ebacadb93f1e059309fd2b855621572e8d9b3f29018 + +Quotient = -31412e97045c19ec38951b0e3884c66d1d7479437 +Remainder = 56f1425227bfc6eb1ecda7bfae0e5cb59e92a2cc5306b28465c8739e40893dc5c1e94cbc +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -602b8c25ded1ab3877f58cb048c733649c7dcadf87b2652e35c4e5544d2306107ebff7b3 + +Quotient = -8da1489ccf7203ecead94c67a5750884122b6e75 +Remainder = -15162026586a1e55dda72785f31c9e6140d166a1fd34c87a7d8c78f8d8f87bbdcf8f75b1e +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 2171ee4a6f7f67d5a33d0a08c367184d70ffe39da28562655e75f6b66c866b1c2ac93e467 + +Quotient = e635f8bdbf80e99723aa5718d3fade4e573be2c +Remainder = -ffbd73bfe05f95bc2b135f12682288c620215eac3d6d56503d93a90e06f236e597d1df975 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -149375d478a096e724b84faf795c589ef0d772c4623f5be38da99006cd833dc5b28363faed + +Quotient = 20f76f5c6d0c8284764a10f6936c22bfba5f851 +Remainder = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f + +Quotient = -382586dfe93872abbe3a504fc62a8973913f96 +Remainder = 4d407323ef56093eea2f3993334215950f4e1a85ba18cdcd77d819d92b8b292c3ec8edea425 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -545d81ed25602b158bc79aadf98a8f655fc399fb8652ae94333bf54c8c9ffaf8c6b3f2a9d52 + +Quotient = -7d179efc493eaceaf46572a1f3a62bdfc4a38 +Remainder = -3de3d817a9cf7d529b5229a503e8ebbbd2c53215ac3c584c010947f780198dee16ffbf47791 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 25dddb00f65d6a1ba8caf7815a8063c5da656d775eae9e0108c68ce11dc925183810888dd04c + +Quotient = a9f7e5f235bae0e3e29393ac5c99d510b009 +Remainder = -150478b4a0df3eb20dcd1be8da283a00636c021c5c6337e7732aae9c4b49853b95f6d2475ea7 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1bde6cae7f5ced9006c0b1a61fb50982a433e4e2050aa486298f456556d8e909e96933e2ba3ba + +Quotient = 16de125df5936181981b4c2d0051a8b4d211 +Remainder = 29ac7c8a11f9beb9ad649257994216146b663bf4f237c561bf315d95778fcdb1010283475ebf1 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = cf24735a60ff5906410be5c4d98e3c9247919b57e404aeabc7eaefbf07bd64762bc61b96c9040 + +Quotient = -268a52cd10ab4814268f66d9f44f71a98eb +Remainder = 20293699f12fbfef2e391963866fc082a7884cd13b1c9bd8d5d203558feed2b889720be936451a +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -7ae7d548212830013b7d653072c33f0dd54a6ebd8792bf75809d29a8c798dbc67c3edd99a69b85 + +Quotient = -8f051067ccb82b6a3dffedd0ff2ee97c46 +Remainder = -100dac0d3bf5aacc5fade281c071eb2399560a65349566567ce1c0c34e43f175a575ed1eeeb3b07 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 211ebb5dc59a051fdfa3b18ac491971e863f2086cdc099672c1215af4ec877e29950efa4f487be7 + +Quotient = 9b7ee4c499386f922432fcb1a453ee2ec +Remainder = -f410122a74386d724cdd45b2e548645ac5ee4a44cbfecb82aad34ae470526674da44ebbf557bb75 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -1e76750814dec1ecbb1af0fa2281ab3185e94e47fc16a77fed312f23f261ad7709ad7c9f85862c1d + +Quotient = 23efb26228d7bcf281cd45f54572e2b3a +Remainder = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413 + +Quotient = -2cfcae0e922f2d884bfa0a3346dc9812 +Remainder = 14de2725b11a9c6784d9608c52770d29b9fbf824ecd4890bf28f3ec0dc6c52e4df9be540332b8882d +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -694b057ff381badb37c7c15c81e74cbd6774e8d61c9e7d450811c36262ea834fc1287fa59708ee072 + +Quotient = -4c0238ff3c18d4d58e543f020002802 +Remainder = -2ddef796c50817e82ea6f64a02a8c6b30ab40070ff5401c2d39ca14b9c4d99de33834bfe566a0c2efb +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3e51c9ab14f522b55e8f9d3ba995c0846a864dfa2d568ea211b0cac1463ce6a1da72d0a15746fdcc9b + +Quotient = d41f9102a7785ce64f76b7d7b870b0 +Remainder = -106eaafdd518c658bd371164ee43ccd915a01b513fc7d220900039ff840ba36450e16ce9987e08e7141 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -16549c5d57b531528dd4d781f03cf275b66cb94eba038b782b739c3ab30b8631c8706abac06004a942d + +Quotient = 1616b432b3277e774aad92b0cf544c +Remainder = 2c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79 + +Quotient = -320fd6a7375a42a3961362ae196d1 +Remainder = 5336711bf81237ea3449f4e9f4e6358dc250f8ebd86082cab92a8079f2c8f835bc783082efb0ed7e3f66 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -5e9e8e1d446fdd314d487cac1226088696e33161d923acb67d3c75e87e428bdbc193e02f53200610fcdb + +Quotient = -4bd06daed3f30345d269f51e4381 +Remainder = -1f3513bdefa40662f0f50a04b418a833aa2f85522dc6c399298b1b147662ef2164ddbfb7247ba9511b8ec +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = 3e7ab7ffe5f63a6c1e109b95b83af470ff820cdedbb3c90c398ec42e44a45e1ca894870a7fa51f17ad5c5 + +Quotient = d6fd01a0c5b55fbe36e58bbe77b +Remainder = -c51af3e8b430870388357cb366ea888bd7b4ccde09ad3a1d2ee1426af060245c6d6b5980ae87fb66c4642 +A = -1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -16086df3dd5e665f2631a294563c68931faa19ee67d6a2153d262940a648ae71bb3c1745daca5ea977331d + +Quotient = 18bd9a8f5678d28cefd955cf99d +Remainder = e193f2fece67b7abe16373c3f84f18dfedcf654d951bf47585fccfaf67ee04f5037354d057c9f5eaa8eef +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = bf758acacd11f3f3e6665cd740517c9ab2384266f3c7ff9afd0888cdad2f6c9401c24d6c11fc3949aabbaa + +Quotient = -371239db55c79521206c9e60c0 +Remainder = 93773085af7582dd298b09d7098835787978d820289ea6850f27d0d77eecce8614785e32b228f46ca4b371 +A = 1280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031 +B = -56033fd85be464301f10177b58d895fbb6df6154da5c2a2a7cfc3a24d83a96f5295fb17a08148a4e51dde91 + +Quotient = 696d8e378d12221e2d970c53bf63a20ef381db8566701972c22fe067cdba99c57b68706a5c6e52f21bb3de861e49ed2141b3036f07d1fd0ee +Remainder = 9f0e50ca76031b +A = b2668f5fbcf4170820ed3fc9b12a61862acf8e3cb17175482efe23c5cfd3556e77634d407b6d1f98a73437a8d6066319a7a860afcab2338a1b1313037e30f4d9 +B = 1b1313037e30f4d9 + +Quotient = babe271ea266bc7bc16d193097903037819f82366c7e9ff8f2cb14157b40433c6ee327038d5dcc44140b070d823befaefbee5e13419f6f17 +Remainder = 93d7c547a9ba0a4a +A = 74b1a591f449377836f378e05d2902b29964df59c6926e5a9182cc09ce3111783cb7021a185340b4880d56635de268d6f3855c4d9997373b9ff8df899ee3b3f1 +B = 9ff8df899ee3b3f1 + +Quotient = 890139fef28aa3b77814e1122b9c7f26e746ee3c507e6082b508fcbe380de83b06a01f735239c6847c30eae44749fc8c5e3bd97eb40ba297 +Remainder = 6c97aace900389d0 +A = 7e89adea82b4cb6feb41297b6dc8d948e72c3d5554a987900e7fae48cfb38fb5282b13d9a1f5793cf7cbf1ef551865041c3ffe0e287714a6ec7123556af55a48 +B = ec7123556af55a48 + +Quotient = 1fdeead441e2d7a6ce3cce2389b2a22248ddca7970ae3f7e7d8453052fd08534ff7c46f6a4537fb6f28df6c5fc8a7d384336e679b74205315 +Remainder = 2903c7cc2651bfa8 +A = 9ca66de3d83f0a747fe986464522bde5e42aeac20e8ace1ea13fa6bc9514c58517479a4281d4128c6d775489b85dfd114ad184613f308f6c4ea484a22ab0ad1e +B = 4ea484a22ab0ad1e + +Quotient = 12f16c8f9f898a08853982e2ac5a906d784c5ab8d74007ba3ab311e861d7c1ac115efe694cab7583f75a4a59ceff2887dab53b2f1022aa452 +Remainder = 4bdaf1f352e87aa5 +A = 6e6a97b358b591b78db43772378dc084a11836ddc9dd4607f263ce620714e8fdf6bf67387c163b6f2999f84270802b4bd5c0f0377e949fbd5d42fe145e66ffeb +B = 5d42fe145e66ffeb + +Quotient = 14e0c06c8cff1f9f5dd8afb6fa6c340f0953a18ba7d2b26b22d8e7f946ef20fd5ac277ceb59cbd4ce3e8213803c3b5b0452ed449e22bf2c29 +Remainder = 55422f1caf4a9a00 +A = bc9c054ff568af73e301e0751bc1ee055e82826cdc53449f2d9f45feda2ba227bedd6df9b74fb58a85917d60b087bef04a156a571716e9bc908ae83784ee35c0 +B = 908ae83784ee35c0 + +Quotient = a457ea94da3237c0dd15ee30e9c13e7b4ca1dc90fcd67951b873787206babaed837a3eb17e298d74cae92d1059636f9aefe11aef9ffa31053 +Remainder = 124768541b600598 +A = ea6dc82b1906c277526ed867fe8b0fbe32feecfb935dbab860aef59a7d72799fd4e952e70b4c9304c7b2a06af8badcd6cfa12d0b6c9db38d16d2c4a24099ca14 +B = 16d2c4a24099ca14 + +Quotient = da0a37eece8972a0e2e8817c54e67c4d9f92373340488539d5051984bce0ae3300ef6ca9d0902daa4d485dec3b4db6c8b1ffd2c5d08b18ae +Remainder = 1ba15c46023500b9 +A = 36ca8763e20e6ebf07a55cdfdd83892bef0bab68ac092093bfdac1a49c1da015541196a24249bb2262e70f7ed53e0fbae61f02ebac4b61f740548136ce50f243 +B = 40548136ce50f243 + +Quotient = 3d8c433daedfbf681b528f88d610204d33bbe74d0b13978c34a617ae94177e07a757519b5a8f1a93a73d0751c7b5b72b4bdf475a9708fecac +Remainder = 4cdfd72349c6110 +A = e0dd7e73b2a64dc017da65992176e2535c43b6fc14f2f7b0a7d894d768bbc77507eac0112b2dc3ca83d70989a1b949ccf374be6a012d80a23a74bba39671fcd0 +B = 3a74bba39671fcd0 + +Quotient = 39d084b444e39c32f2883e9968301151802da15141f65893f37b8b834eb01c074aa1e1a978c5c99732c87ae106bf8db09e1728c8bf2aae88 +Remainder = 2950443357cd7477 +A = 16df31dc290559c3b6a3d192cf15d825cfe79f8dbd5c9848eac7fa90eea5d87f8b430cccf9baab3e8e4dc33467a4234d8551ff25e33af175654686ff1368e96f +B = 654686ff1368e96f + +Quotient = bbead8f70c8e61114f22d36e97861f16037efabe1347613e78c51d7f539065421a66c907faddaed13ad2a0f0b00f8fd594e917799cd937e5 +Remainder = 3013136f5f728b68 +A = ba5e688ab4f8ab5c25592bc4334b6dc2b7a06d491d0f919b716bf1cf109b62a30d9dd59dd4bdf870dd2687894edab303277a5f3e3a537cc8fde3ee3bb61767d6 +B = fde3ee3bb61767d6 + +Quotient = 42aefe467ff2a5614efef1edce25a1acba9c476b3abbcd680140a3aecf8f51c1ebaab8912de217451bfaca2842c0bae717b8a030b6318c0 +Remainder = 1f130dd2ead0d35e +A = 17bd50b5322c51ac883852ad2a4446c039dbc210ca3aa0313065fc88cce6819b324e93b036bd0c71be58586cd2b243d01a4a918c10ea0cc5b22f9d795df09de +B = 5b22f9d795df09de + +Quotient = 13de73dcd72a3638fe2a907fd7f6574bbb228698fa60e4ecffb082911c5f09c74bb4f50564d3d4035d07eedea38b634a3e3acc26c8e9aeff8 +Remainder = acb8702f0113e0c4 +A = e0327b2e59236a3f91ccf960490cc69b2afc854de9299ad2edff9618f9fe24251886afc65f5c581a9bc86013f356d599e98b8b10f5236a51b48a6b29025983a4 +B = b48a6b29025983a4 + +Quotient = 27d11481f00519b786eaee96220afd45bc51700f7366fb5e7da35bbc84891aac3d9d2b709dddae371a6b78439fef810c68eef586e1d68350d +Remainder = 3d1890c5e1555d74 +A = f3504d5d96c9e27a1527725ced337f1cd0a183531642051e166507432c01e8d44c4e8918701c2a05eb8a9d7e26bf04993f9adeef2826ae4e61c602477f849121 +B = 61c602477f849121 + +Quotient = 10bdeac209c67b023044186704735c7291423054bcddc24b731ad601b49372f4d5ce6e9d85002f8dddf0411efce943f81a5e42cee2d0c9fe5 +Remainder = a93a0c5bd51004e4 +A = fa29e37b0d0410d19fd180149b14f94ec2edccd347da65f6832850aa06a61b7b78c96faf64dcb347893c93c560b8043466419864a382c6f2ef1412873b2d8cbf +B = ef1412873b2d8cbf + +Quotient = 1c9b6cffe44241292320c0660b89f2f77aaadc8d36e33f5ac3da0f12b3c114a156870a92079f7192d237f8bf49aeee6282531c929cc56d75 +Remainder = 1ce3e5eb13ac7958 +A = 144325a641463ed6bddfcbd73e50620a44c606d71fac38efb1c9d2747b4903f7b51fdedacfb66db022aea09b43c7c2ad7b851035165ebe59b552d4f7eee617b2 +B = b552d4f7eee617b2 + +Quotient = 1b4ad18dc0e634053beb3cf840b53e35117ea06309ea8ca22e37123fd7e1d391c96c792e5125e322c27daa73301024080d73ba3491484b659 +Remainder = 3286bdce6dc3a828 +A = e3a2b90d3ef446f6bde30d3e726cf3e78212324054b40deb0b18fe00645568fb0a6234b6bded6240977373731bb30d1349e25cefd54b7a9985735e9b78002691 +B = 85735e9b78002691 + +Quotient = 28f5e8da6733240cc2f18e3cf4d42a50d92816062af33a9e1871fa89bdb39a0d905c49faf51cc1c1378741bea34d25ac2c8e522881a6f6087 +Remainder = 135784870eb40c68 +A = 593206f9367b72f9cc59b3e37d2eb23b2061422859162ee53656899c2471017474f500c6e23efe1f6b1e57852cd4229329dc182ba01a257122d76a26aaf9b844 +B = 22d76a26aaf9b844 + +Quotient = 1ab276448d16c533b6e90b5b5ca266e13ec27b5a58c80b7657df963ec2d1fe4eb1c1d24873eff6408bcb3d0cf97c31e85240eedf0efcc1e5a +Remainder = 27b105741264f875 +A = d84fde3d851b52ed3b2a1268e9b765ec6c09c5768bba709b3b799802fadac30a6c3184185e6d57249b1c34619f3c9d2b90bc0c348b22537281a39fcadf738083 +B = 81a39fcadf738083 + +Quotient = 84a87678485b3e60ee1cae3701ebdf0a29ee44115a492c34a0c8e84090e14070eb2ad0abfe2c339f26b5099327515104fe3d1c5546feea98ed +Remainder = 95f7434941f9d8 +A = f79a0643bcd9c28cc22cc7b4178b3340e4685dd2672792516d6fc08567d2de2d3e25d43f100a58826edb146ac94acac4213bb09bdf8a258001ddd0ab110b89fe +B = 1ddd0ab110b89fe + +Quotient = 516a2ac26e5b3afa502c7f3c6f15376f7a380e5842c229443343b5b74dc3de84db3ae99a0c57043e32a504ded19943c0310cababb3e92cf8 +Remainder = 327cf78eed336523 +A = 17c0d5814e1020d5d69674bdf6b9df193a16c0c8567a589d014e8eb7f6c9c36560791f7acbbbacee7c456eb51a4cdd7ca88011e9d8d9f2d64ab08ad74f7be5cb +B = 4ab08ad74f7be5cb + +Quotient = f0da0beebcfaa716f494cf3fc81fe65117c90adde3b3942e8e66986fe8050fd5c9ebe1c88c5db04cea4c4c14779555d70cafb53870671f95 +Remainder = 3b2f844440d7be00 +A = ebba8c393c2a22b094d824ed95b4acf6875719fc165f73ee6d359e1134949169fdacbb42d5deb8cea96e11e3aac985635b5bcc6c02a6778cfa8e03d9ce6fc680 +B = fa8e03d9ce6fc680 + +Quotient = 56527f07593774f0fa642241400985d0bb9b41d3dc9e025ca069130d93afc972d75e3fe0f798e127c3e1b4e925000459a3a5a83b15186e516 +Remainder = b620b7a3b752b78 +A = 5d6cad9e26267abb480b2b9ac5ea323bc4c3c53e0de8ce40c89c85accf0499aea5b11703a04296519047585ff12f8795f98da0546c20016a115100eddabfb468 +B = 115100eddabfb468 + +Quotient = 294dca3b56ce9529aed2c132a9bd6c0c61de7a58ac50582f396b4fadcf7873b502bb869f801a9ab1f12384631cefee72b3e6050a7f69eba4 +Remainder = 53a0fcf5486c7a6f +A = 24aa73803f270185d23310df2cf3ef67b18d7800bc41aad2ca13f372a27ef0a9217194f3f512e79f545a903895def195a5eb9a1a1b6b3f4de340e9da9b305d3b +B = e340e9da9b305d3b + +Quotient = 16bf4dab1c29bd284c9b6649de65a4ee58f21d6a8b51627ca133fa817872b1a4a9956662db0aead5898ed0eda08511be7c47449638f2fab95d +Remainder = e7751deb047d98 +A = 77b04d93272491322ed2fe651044e28cadb2ae7825f02b55aeb0f73b8b8a8b336802416fe08c718ab681581ac04d87116323f61f50bfd2180542fcd4a46dcff6 +B = 542fcd4a46dcff6 + +Quotient = 388ae1c243bc9111e663c0c80495c36e8767bafe188b532b7ac84b5160d902af1b638aec6e4c66955d16bd8ce94ce6027a7bf95910f705ad0 +Remainder = 7c667ea307017c2 +A = 52f357e9a57722a867d8199242e100f06e8df810ee913d6992bfd9dc03ed78bcf44d692aaa7be806df0c9e0802851d7ae8405f76114e6322177907198f85cb62 +B = 177907198f85cb62 + +Quotient = 33dc2fcceef7dce92e3a9df58566c6e28d03b58ff6ecbbb31e43936cda6380a56788285d37b5e8f11487afd78c39cb2150cc98d9d78a0c6cb +Remainder = 429a380c9f8eeeba +A = d99cf9a0bfc347c9631ae8c69defe1f1509c3ecaeeee5dbc61317bb73fa5cc6e704f64c865cf4d898f8a2f63214dbd511f61aa6e09856222432376698f8d2f67 +B = 432376698f8d2f67 + +Quotient = 18ecac9e5539a014cffd8310ceb1170577cb23aa9cb3c523d57ad83069d1609ff743cd3c275b67097a038b85afcd7105ad21672f9ecbbc7df +Remainder = 37924fea665f5c92 +A = f87aa8b6e62b09291e0e9b832ad71d8f85d60501a8d89d2638dccd4022e89bc4932c186a198557282527dfa86dfacc2f90fe0656695b61429f8220509f5106b9 +B = 9f8220509f5106b9 + +Quotient = 37c0649a53c8cab91a7458702870bf64cb1de9fc1c6b9a3b92444119d368501b62d3a5138af72bdb7752eab8af6bf4e3bdb9e3beb1805b88 +Remainder = de179463e3e91ad +A = 995c04c1f24c4efe88393bab7a7545e39193662d5db7c8e557d6c554ed4367f5af82c463d0ba6bc3148620481140add5677937989e03fb52c0323980d8841d5 +B = 2c0323980d8841d5 + +Quotient = a6d193cfe7d8983768ff29908ee6e07fee99927a4bc4ef41d01f63f3b4a2e7029630b7d925d0979458cdaa903771286af672253cd99593b3 +Remainder = 6bf69921db298b3e +A = 55c856daa8110599cc4fde0a44acbd69a68eb177e0438f7d843ba0fb74caab2a7e0c8a6f176f5555779e65c555e9157a16a1497edf36ccb583a458f0372a57c9 +B = 83a458f0372a57c9 + +Quotient = 63f379bef9866b59f8bfd6bb0120a75dc03506b0034e7440764afc8ec14d8d735aa6f03a568ea98d0a74ab9bbe9c6e11b288467e5f79a2539 +Remainder = 11c077beb8667d88 +A = ff1fc3ea60fb37ff23e2f2f4e207a86e055cca41eebcc5bd6376904b51fb3d233cb04666fdc92be33239b5ee552870e45717890e35fdbe3728d6ff55d5662419 +B = 28d6ff55d5662419 + +Quotient = 285ba8cdfbf00b112e496ce65cdba2271c82a273b3d30bed82ef2d360790c5deb97f3311bd5eb9876a61e33b3a37782d00c2d5ffbeec752ca +Remainder = 1672a8aa119c3a1d +A = d614352268930d301aa4046cd38e2eda4dcfcc52eac984943f2c863de5c4f8a44473a8ecebf12cb8f4da4722d305e5c9c3eddc0109d416e854df334dbfcfdd4b +B = 54df334dbfcfdd4b + +Quotient = 358178128648fa9ea28dcfe68b4cecc7071e129e3ce4d113f5d1e387f7e5a412e9d2dfe5ff16d9987a544004d213ade9c134cc240eeb6871 +Remainder = 44c3fdb374bc0c30 +A = 18b973dd011969e29a1f4a5b8f118313f715c2e31dfebd9fe0957cf23cf36eded89c38637a8d3512bb23324ff2a3627d5b942300200c823d764b7a6c12d1c91b +B = 764b7a6c12d1c91b + +Quotient = 19ea7212f6604d423b308fe3f2f4986f31aea9d6a117a3e207e38ce5bbd8d7a866285ac60433630de547fc84e364c451457fbf864a82c6613 +Remainder = 2718de2dd0796f08 +A = 83577f755a448d5586e19486b04de7836818223ea920465c4eee979a9ce5696ad8e2fd5253b5d5dcfdf355465e8c0819658ccc5580fd29b351169b54c62b779c +B = 51169b54c62b779c + +Quotient = 13e0c5b9905770b60a6f978d1c983cbc84dccfaed0f4222f534df80c7d3d129f5e8f74f19581332a7f6d383915424c71db4ca19bde2591fcd +Remainder = abf5f6c8ab6ed4f4 +A = e2bf43c91cdbb244790eb165cc13feafea36f5187cc9bf8aa8cf202042efd5441e3822a1164992da5be750aaac0bb11f09375bdfbd4a39e3b682c7ee6ab5f5f1 +B = b682c7ee6ab5f5f1 + +Quotient = 3919f31521e87f90df3a4463d0c83fa31e3f569449009d307962d26f07d854e8d3f0badbf55311c206bf34e6227949327a93b1a5ada7a930 +Remainder = 6c3802d44dd4668f +A = 2546880cc6f97fb379afbc4a2664115ba7909414f35a5bf88be2ed5187bd1a24afaf82eeceb0b438d4999ebf9b7ec752236669425bd3cce6a71d9ad67ff2ff5f +B = a71d9ad67ff2ff5f + +Quotient = 121d5ad4115c2768b962e51d09f426d61624e0f203ac6c923289b4e7964e165b34f3dc1ff938a7cf37478d407de251c64db71d3ee629c1035 +Remainder = 660a35e1c1245910 +A = a36d3250c123697adbbbdf489e6cb40be57febaff654ca951c9fa0b396b1714c55ed6e05e468153ac443dabca29de9b43cc0cc4e62cdf24690593662c86fb5ac +B = 90593662c86fb5ac + +Quotient = ad81debaa02f6e60da58b46e76ce041fc4da64138634ea7b3c165b8fbda027eb64b6b5339e70babbb83430d60383c2cfe22029e617fd03a7 +Remainder = 2e4aeafa2ad76832 +A = 8992cd131757ba5cbe54aa58be115723ea3438ddc782a4d1996980b7b312fa76e4483584df744b10340e5fc9e468690cef538920a732a8f0cafb4e30846cad1d +B = cafb4e30846cad1d + +Quotient = 67a71b9ebaec91121a8cf6bc2932b6be01af7954eca69c5202d771c2c2d13683cdf90ec942a3445771ccfe484f947f078de825ea88b3c05a +Remainder = 8395953f744cfb31 +A = 4f8ada84096198175174896167405b85cbc03fe0642f6b263a70f9a22f19ad6c9aef38da8ac036d409e6fd925023c95312cebe04eb653e0ec473dc8dfed98967 +B = c473dc8dfed98967 + +Quotient = 9416326e2347a541b777a0fa1b0c35d8fe76c940d24c6f6806d6ae8ac1e280c16e480786478bda3f780ee92f3f3c361574efc2ed5ca98e26 +Remainder = b8ff45f31bdb58d8 +A = 902f5e48b96b9b1fd16c3b21292ed495987ddac4e1d92b2ab10378f2966c4399d6a41eef622a4991ccd1f647531dcd145de4ac99b3036779f9414ed2f4ba7e08 +B = f9414ed2f4ba7e08 + +Quotient = 403c651b4e571e8301c4158fc185396554bf61d900708d2af5c2bdf495b3cb539b0b9b5acd0d71654b3aa68024961d5a7bc9e2788e6c822b6 +Remainder = 7856ec047cec8dc +A = bdd6d846983fbf140173a26d2b709b9f31b4fee1eac9d25fdf0ef3523be0e6afb372acab470cfe1806b36d84017ec99302eb9eb5eb2862222f4916d8b6201d14 +B = 2f4916d8b6201d14 + +Quotient = 1b6d967173f9777cb6194c8f69289b91da731456fe5a1515a49e4463cd906c84f97381cabdf9f358d97fad5d3cb140e3a3de397e7f9f683157 +Remainder = 83649246ade8bb4 +A = e3da80658acd53ada7c2dc57178e697f2907c5b0c64f4a87a794ca7521105a0568a32874207646df3768ee60964b7d1d2e29ea6bf7fbaa7e084eabd4ea553a72 +B = 84eabd4ea553a72 + +Quotient = 27b8f1e49e404455cc68217a20766590e749507976a3a6de25a7cf2c32593aaabb04d84deba1ec6bbe048a2959ffd747243c396dc53c9c811 +Remainder = 3daa032278ce53d0 +A = ff3ead7c7b27f607d16f1ef4ffa91b6cc28301b9256cfcb0c22b6818371ce648ae8812dc50a86e4bdc0d0b1e5b0d55c6ba07b240886a6d5766cfb3ed0937a543 +B = 66cfb3ed0937a543 + +Quotient = bf987f58700508356fb6274f64a9f78d455e4c436fc6fcc980ec0800287ab3789b91c29a8a72b16645ecfeec926b6f8242f3c7dc3adb40cd +Remainder = c007da44faa80584 +A = 971aa67c9af10f70977f600e10f9278b8e66d2471956da38e5f4b3fedce9a5fc7ff42b800bb4a78314c70bb59394d0880383f5182b6c1960c9e5b47ef8e63be5 +B = c9e5b47ef8e63be5 + +Quotient = 7332104442474715d7c4cdac15fc1731240f8b4dd0e6ff3284a15a62a8f9a071dedb87f2220efcc5839cb7e6933a8f65d767819db26e134dd +Remainder = ef65a7789f54174 +A = bcea2ae4b1edfebf905a5820f0481b6c58d76a69df9dbe84764add3f49496a5d7005d645eaee3754e0ed105c13a114e6a0eae5cc4efab6aa1a3d3a0050fa86f5 +B = 1a3d3a0050fa86f5 + +Quotient = 3f6182804a7ff12fe7ed3c8521b55564559b1a47a78e1fd56597b9470e7e0f6e7e48c58bc8841c9d118718ccd5e0c0bf9a08d8e244ae60da5 +Remainder = 398e30aff5bd284 +A = 2b877181a960c5e29ab1b2672ee22539256a82369e8f6cb5bcfb69e5e4a41f782e89b58fc0ef6ca336469ff929729f8492b44f12199f0e1c0afd12b2c999e787 +B = afd12b2c999e787 + +Quotient = 1a80a681d2c42edbcbde552323dac3a1c03b43251a99b5549da6cb39ec6947daa0d574f0df68512984fa8e269b0b27a5576b3aaccb76ebc23 +Remainder = 378e44fdc7a5ec4c +A = d37e62f44de27a1418f348139eac5ab9fcc1ada21ea6d7695273daf638b4d7eee6745f54b99a9678cf742d304736ee356f66d16d874f8cc67fae9be5dfd41a3a +B = 7fae9be5dfd41a3a + +Quotient = ee982a63816d56758c29d284c19b9b984908cf0a9ae3f1f926e162a2cae4f88703aa477c5c14042247635c103494d11593c2c3839baf4d93 +Remainder = 39afe3275c01aae6 +A = 9a0b0476cd33861d2fc3137df292728e1f636f6fcba5105f384533723231a3104e7c77df46f7f34a4bdc63d5c67b418cafcf106b26ad020ea547d34edac1d3a5 +B = a547d34edac1d3a5 + +Quotient = fb3f4a39a661e5c31228a6b7b4c27e6e52d1954e8ce262b98b61650efffd762cf2a1aec228bec5d5787683cad6b2e6e49a0de91c15c81874 +Remainder = 63e5ed36ff73a42 +A = 4453712f56467328401a69d4d749a0771732734a760a74094e50a62a030cb604e735bfe0bf0641754edff94ac0e0549e8c10941255f0f21f459e52a6cfe4d9ca +B = 459e52a6cfe4d9ca + +Quotient = 7af60a7c0f995178be76c070cf49eee311e6d1e3afaf50c8c93ff200c1b3fe742b23259b4fc0b9ed0947be4fc9a6c212d86de9a0f7dbb5279 +Remainder = 19657d8ce516a138 +A = c9c92a31ad0f3cfb56a294c42a26eaecb77edf33ed40a7e6797927a0c996a7c0a701b484741163df388bb082e3daebf4e1b7a99002632d6f1a41c1d517238557 +B = 1a41c1d517238557 + +Quotient = c890c55a8e2a3105b9bf9344a57a9b9fab5fa1fd57083d52431b695553bfbe7a44a9b6cd1f83958224f351f8511b14215d1648e88e938573 +Remainder = 1bab5b03c372daee +A = 88341550e470016c7ab600b9f6cb410071a77f907a58cb6da4ce3e955d1e859534c2c1098fcfd91b9fa66926e51896733c36a824c3a20844add94e27f30ca651 +B = add94e27f30ca651 + +Quotient = 34c240c42da400317f66f5151630493a2f200ee418d5ca3300cab10dfb429c2acd7280bf066fe19115f86db83d8f5b93cda714533b16abfdc +Remainder = 18cd326996ccebc1 +A = 7e96d7b90ff09b114dd4393e9bdfb13d8ff517681126c566e18dd6369d87d248734d94bd02a1f19cca90be7642822b636369c51dee441a9d2663ec896e1d6c6d +B = 2663ec896e1d6c6d + +Quotient = 10d18159e75efa8204e325e6be830b4ee8d2c07419e8276edeac6cc286488fc0c888300db3ebb5f935aa82654d3b932540f0093d1880e1d6d +Remainder = fe9b6b8ba7c30f8 +A = 731aa6e2fb2ad1e1f80d7668c7b0642203af24af382abd207a5ffb588209e8b5caf953e9a96b478f39ec03a397d1433998e3c95e382d93376d80cf0c957788e6 +B = 6d80cf0c957788e6 + +Quotient = 450d1f4a105ff8d1a3efbb12165ca98c67ae70404472e4862db479e03313b08783ecc42104780c9d57df0ddf19c5b4547ee9ba52ea82dd0c7 +Remainder = 169e15b4d5aa180a +A = 902bcb1904b80183656dcbd51879e2982e2b46a547c9ae3119ffc12c6a003e4321b519289b7f22fad19d16480182d1d797c3045b2d29dcc12167f9ce5e233d89 +B = 2167f9ce5e233d89 + +Quotient = a426f71cb3d75365cd076a6c35c10765bbc3f4bd317fb83a70083b0f7dc43a4e0b95508e60dc1dedb780e9b485f4f7a8870960de669b73af2 +Remainder = da381ae5c97a506 +A = bd59dcdefcbaecd9292c4c3685fb87d3a94c0f0ed01e43e63e1f36fb65d6c5eab3b584f3d1f76d31458c9f6b4c69869d96e943c61df102771274c5b4d821469a +B = 1274c5b4d821469a + +Quotient = 26ccd4b7be090af22221729b0ca51a5e66435c2d33f8d88f94405f6c0123ccbbbbc8080cd8448a977946019ccbf5d267ac3f151ebe686720 +Remainder = c41f9e7bf20b376c +A = 212dbeff03f14b5825f0d7cf8a7501db21b60581a01a26d522ee44e7fe69545cfcaaac64dbc76c7e3027ac39ddc2d80af6f3fca1824c6ff6dae90967d9ab48ec +B = dae90967d9ab48ec + +Quotient = 801df28f4fd987b4e980760f4f2625276a2a7191d453095c82aa98a2253324ad2873abae70cd98c28ef3ce102fdd53469b9f01889f3ba8b0 +Remainder = 8e435da582e59809 +A = 48341b28138dd04807e522e341f74ac46b0449fa45f96d7fc586997c056a21eb3c399752a6a6c023509f042cf9e879f397a34af9aa2ec2e8904674f2ea3ff739 +B = 904674f2ea3ff739 + +Quotient = d3857b72b70adff9b5dec3cbc63de7c90ccd7aab6595339b2de39bd6b9789045141d224aa4e6bf9a06e017aa3edd00e716a771b3f5b97771 +Remainder = 14135c686d2e9f70 +A = c1cea45dd46409d5e24fb7ed7d849dbb079247af2d312e01083754ed07f65f090e4dd50d23a973488702ef00936c5d78af603ec0fdf03dceea8f939c922b1e7f +B = ea8f939c922b1e7f + +Quotient = abe20c90896e261e7d31bf40e7f3136d36b0b78006d12225a4dbef6aaf2062b609379eefe7e5af5bcec17126286f196f1330da8477096763 +Remainder = 230307c44cd55896 +A = 19a637e4f3051be0f7c4d35513bca4a91ca9b8082fe3c73899b70b6805a7aa0458512495cb6ee1ade55ecd5851be1dba96d65202f06bc7122633a0d905017545 +B = 2633a0d905017545 + +Quotient = 5ed3765c4a777a903e182f7c9ce39d19c01460f389b904c3ce1d3525edf25ffe7dc0f4d9e24f0bc8b7e01bef19c83e74f17884bd7bfabb2c +Remainder = 40f5346f8775e20 +A = 546578393e914be30581e24508a33f6560a5805dfb1c675d1ff1d6f5eaa7ee638b9e0265f543413e04e3f1f3b0895dec271c9897a48d9ce9e3d7df32c15b75a0 +B = e3d7df32c15b75a0 + +Quotient = ed73a67932746985465fb0606fb0e81595514f1647c911c303d4d31eb0306e3b2aece07320f6fea57a7071d73150591ab2a82a7d53968a81 +Remainder = 2e495a881876da00 +A = 8976445bc318921f7e12c8d4e8e50596849a1503b5efb65e939c291de136597c05a1fd16137f0bbbd7197df943cd612118d1e55a50ee097c94331c1cfb1e941c +B = 94331c1cfb1e941c + +Quotient = 5dce24b7a16d847b0c43cf365ea20bee9679fa0e8732813e827cf6ef3c9bdb7fd8846b5689ce8b80a7dc0dd05721cb06d2700aeeb7ff04d6 +Remainder = d8ead1ae3126aded +A = 59b99e5d028e6771d27004bc19830a5fcb347f7ae04c0ba7c49130bfb198c5b16821e425c979e6d2dddc14889ae58475bb52c6cdefecf2a8f4dd6e462bbc8f47 +B = f4dd6e462bbc8f47 + +Quotient = 170e10b399a4c5fe354b536fe59d53602102f215d5107493680ab6e181f67d75ffd45bf49ffb23cf9269b856156b5ac6b1c5def4ab1abb18a +Remainder = 57131776937c5df9 +A = aeb35966e2a616762768b7f63ce3aee5e81561080617bbabd7846b3ca03fafaaef83dd05b8d16cef40db0a56f3b0ef6eca5e236681cb57c8793dc0907d9aa30f +B = 793dc0907d9aa30f + +Quotient = 1acdb88f047f9bf679c50ed67ba01dd24dca92103f8ea2677215b6142083b64f9fd2a365499dc8f2bc61e29fa176f7d76b55557fa58e34f9 +Remainder = 5065b726dc6b3758 +A = 15a6292c9fb66c6770a8dbc6fd431d2a4b57338581f78d0860fda90182cca563eb2272a79fb4f5a6fc72c90dc23e8a95713b65988b5b3f9bcec4f0466c1c47cb +B = cec4f0466c1c47cb + +Quotient = add8127c0a27c961203ea0351aed5b3c75aa816e9c2684574e55f55c7140adcbf69d2cff843e5f53c157bd60b43c45c8b6658de72062fbba +Remainder = 67f48d3584cf4fe5 +A = 4e8938c8cc46d34e3369c5d8536b18c963dbde56020678f77cebac5f8777e0afc62ca2ba4f533cf6cf7561bdce77b6f495bc1b05f1416d1173a6a288012c7c73 +B = 73a6a288012c7c73 + +Quotient = 688ddf883a0bcc1ff9bd582119c2fea7c059e19aded8c048390a1d8fd7d769666987418bbe0d4cf4b67009a342958928769375c1c0d558acf +Remainder = a5356d04b64ee12 +A = e0c9e32056977aeca72e229d83f0d320fbaf5cd8bf3e033289f46101c75ef59a854982f33bcbcfd200034e8ff439d669a03fa404e7dbfea822664967d67dd5f1 +B = 22664967d67dd5f1 + +Quotient = 39d4d94587fd1445f31457c275fd6294fcb69ba155e7da3e6cfef38ed1272d6c95755bca49007ca62cc101b038d264876f18594b8fd4c329 +Remainder = a34980d5046e2ed0 +A = 2efcb12fb55c923f5c6ca7ae076765059e15d9e75240a6e5fc3db92de184143fab1934c7450c3a380a9851846c9f43d67bc199a314e82e72cffee795d695f82e +B = cffee795d695f82e + +Quotient = 145ea82eff186b7db4b11fa1514674fb9d41c698efb33227eb1abbc4eb78bdb2a280c0c4c47adaf4e010a4336cbb5650becd1ef544e223e53 +Remainder = 36052bba2867f5f4 +A = f6a6c7e33fd4c664652d696c495df387b85b132cfdfe34bbd35759477b4a3c052f610df57e49e85720489e4bb8dc923696400a4a28dd000cc1bd491446a50b96 +B = c1bd491446a50b96 + +Quotient = 35d0c9d870348b113868282aaba22b21ec87cf421519a23b288b150604729356f924090ba038d7400c0ccd4932836c65902b4d3c46a202a0 +Remainder = dc8c7d087bf24b0 +A = 22228c8a5966ebdec64007704a373b0596ae702d62e29e468653b21a890ace2f02c27f26b043f48495687ce8c2ca8092ead21aa250ce0f6ca26129615a2432b0 +B = a26129615a2432b0 + +Quotient = 52fc995a486c4bfd17ed9722948e9ede1c4ac2fe80e6bd7482fc47944c4337a185a506a9ca473d49073e1b813ad742f19b13d57914888d5f +Remainder = 75c703f654ad630a +A = 3473041ae301dd2806da30dcf06b9c09600086d6873cf3ee9d5a0be638849afb56bce2664f797de4123f6f8fe3e12acd32e33a285bb7f493a1cc13a7108327f5 +B = a1cc13a7108327f5 + +Quotient = 1744946730b2789977620f2e7439641125dd338d1b31fc50813b34dea70b83d209330bd17fd527db9a402ad9752c26b8823082ec9971f4ae65 +Remainder = 453a3d59303ec3c +A = c0f592d83649bcafb7e2de1a8a71fa863c1f51b595bfa638c8fe30731c6fca36da975b6f19c657e3ca29efff6febfb311c003ec68189998c084afe4979b5bb19 +B = 84afe4979b5bb19 + +Quotient = 468f3eece20aa9d6473f3c559760793e702758a3d9cc19d7817216392c7cc7c3968778cf2fe0c3f0c1424d7512cee19ac0717952f18aa287 +Remainder = 5904e71034e3a02 +A = 1f0c99a128c757d76ae6dfcd01012f0453c8f89b00476ec46321ecb872f99a48b4da29a4abffd0bbff2b727dfa182652ca85350b4ce100fb70a6a40ab6c41d95 +B = 70a6a40ab6c41d95 + +Quotient = 12198913ef16c1cfc7c1be13f1cc5991a61ff74935e09f0c46d26456b7cf2825403b9851d07d27e0197c1fa2ac5e32e836979a184f14cd94a +Remainder = 33431c3df719f946 +A = fbfbf5494a9c5384c7ae3df6c02a5e1f9f32dc31cd7f437832696bba164bae1a9d95daefb8bc08e0e8e637436fb747084460697b5ef5ac9ddec06757dbe61aea +B = dec06757dbe61aea + +Quotient = 376c2f902566d83c21eb7c3aa3a6fa0482ed52c253f67f00d5b915d0183c2d9a2891c2ff837fcb426a4c990c48bda4f90e0bf69d13558696 +Remainder = 31540f5e05e8b4df +A = 2527f8cafaf7e8319ca53104229199188ab1ca5fe592bde8ecf605e17ca6446414e06898a85e177d6985b5cc6d4eeabd6b222b5f44b4fc1baba050665c090b5d +B = aba050665c090b5d + +Quotient = b8fdd5cd7b2d9295258bd99e2780921cb2ea70627a79088039fc3ab1c62bcfc6307e86db4a7803f18e5339f152063f9e41d370e97b1ba2f5 +Remainder = 4ed4f2d12e4f4ba0 +A = a25bd113c5a8c67ef65aa80f1512de43c9441fec0c41250048d29c406fbdae80912eb3970457d621c552e3af7ef2d6bc1b5448e7df5be724e0adf6f71df7eef8 +B = e0adf6f71df7eef8 + +Quotient = 5421daac8cdeb6acc2b8b0dd85b592f255ee4fedb3a9e90f2a5bedfb0f9f033d7c562c96958346bcdda4664c67848b9d9fa7d3892bc4e9af +Remainder = 7e5661558c345eea +A = 490aef65c81b32f5df76dd58decdec3e3f73bc1fcbdb6aee0c93cd98725056153b572509e75d2cc4b042bbeb0a77d27fbca1e39efbc765adde41a7dfc5c3576d +B = de41a7dfc5c3576d + +Quotient = 156a8a24e7804c5f576cd1757dba44cb4185bc13cb56603b54ee3b70fa35cd98db1992904d4f7d99a63b3a486e6fb31141a9d39cc0301f897 +Remainder = 29e9c1627537e5a4 +A = 5e4a10e772de8dd2c96acd714f7d3880ae8ab460095a01038f3aa9b8ac8165889403b42019a1e70e0e7f32e77fb388eae3579dbcb690729c4671868b0526aeca +B = 4671868b0526aeca + +Quotient = 1b0eff2ff0aeb2c02ee3cc9e0bff808f4d616eb290293b13a6b58a84127972bb417d55e1d001a9720ec72562ef3ea688e64c4f32c7e26cc87 +Remainder = 664d57c57d4952e +A = 806b8504abfbeec4d5923f83ddc071be88e11c4394168854448df96160b95adb1fd9c288852e2f3df3e36916ba5118815ca2e83a6a7d9e074bef9c961e2958e3 +B = 4bef9c961e2958e3 + +Quotient = 2e363b13b0457a0e9effc2d7e297df78f35e5d24d0f8ad4525b573fb2f66f374871291ee8a8ee3d15a823b560156d474c678f79ee480bbe4 +Remainder = 5ba8f49e0ca36ab4 +A = 2e1bb261d98ec405dbb068daac5efeb0a51f08149181864e9dd6bf6cfcb617b76d8facaee2ef468807e0403bc550d58e8ad9e5cc0f094b02ff6d0277fe642f44 +B = ff6d0277fe642f44 + +Quotient = 149a5b1a81b9e47ed36be76252055bb202dc25f8fe7beaa1ce59c279b32941cfbaf8fe4555867850b2fba43b10b74534db82398320f9786d25 +Remainder = 1ef621737e81780 +A = 63de892cf5df40c98de78c755c99e94e0e76cd5dc0b49b8856fe69dd0abcdc535bb1416f0d02b4eeb54e8a939cf7ad4edfb7de4dac87523e04d8ea8637e50920 +B = 4d8ea8637e50920 + +Quotient = dea8a9211974758752d89965eeeb93cc616f88ce757ec2809f829cbb8d99b4ffdc3f0f643779fc5e0bb53b5273a5b15965f4a364863592f +Remainder = 9ae7de3edb6c7edc +A = acd5cebd069f7febc38c318867ba3a562bbf8ea9b19a6b33538ba107e49439f8ac6e880c6267c29b39141dbe2273d93062464de307efdb7c6b738c0bb282c3e +B = c6b738c0bb282c3e + +Quotient = e9149b347cdea84d740be70060b239af000c4336ddf36fd5159083b795c4763588c87a959df0104212a04cc928baf60b0ea72e8cccc6d477 +Remainder = 3ef5c6ee67e6f5da +A = 6ccf1b8b406e6a106160e73ac4122a04c0814ef5a47708a6776eb52002d52772d3fce3fc05398172bba191390aba925bb23aa1eee626410877822f27d1e3cb09 +B = 77822f27d1e3cb09 + +Quotient = 1606c2fe44cd0b780ee474a9c7daf0b2bebf62db0ba8ef5a99fe22036019890a4c7dff73e678965bb0e2a6e61d00a74a1d33dc1106842115a +Remainder = 7cf920ba2897f714 +A = ef9a3983f26237576311a871e4a3df0538593dd0cfda58ab90b889fdb35c700f7d158abafad127605057ca0532e846992c41ec06902ce58cae0c1fe238c726cc +B = ae0c1fe238c726cc + +Quotient = 8ccf17de5068451fef1c2808c62e19997c7f920d5cc0fde1f5a247cc57c6d730df553cf33094b786597a343a0ce9e4bffef568247e904343 +Remainder = 2689c40a54df34bc +A = 8435babd279b7a3833d01988c58005d4557f7689ea9b7168ef42ce2b31a1a3c32a982aff654f271a651085335496dd826ee4b3bc27f58920f05dc6676e51c662 +B = f05dc6676e51c662 + +Quotient = a9e78c48c779140b1d15843089765ce9ece3855537ce88cad3eb7aa7bd6ec72df65adacba2bdf6c491066406bdc3dd3dd734a70e93eed958 +Remainder = 53da0b15ac079ccd +A = 78550cb7b58b58d6878b615dfa25a5b90a1ff631740e631c7f8829962446903c686c810c46a1551b6c1f7a89ae898435bb8e36d1bae24a80b54edbf4bbc9af85 +B = b54edbf4bbc9af85 + +Quotient = 1e3b41304ee07f6baf1ca061e0e28a3740991c6ca2749eba70d3ea1f9cba8adec45cb69a31cbff22784a9e056e884713c0812e8c7981e49328 +Remainder = 3d051148ec43a72 +A = 76b9453d315e7a9c592e1f2640f5b6b90a65e7f2ff8ac24b9b47e35abb76fa5d303be6d501b341a882bdd9d2a1c81a9280724673f87fbe9803ed5a2e7edaeec2 +B = 3ed5a2e7edaeec2 + +Quotient = 1921410e1a538a71d33d9c5de95593fada116200c399fa7590ebc374282570477f5f4abdd5166784ccee9671a1a23b96378df62168049f6b8 +Remainder = 1a1f4aeb882d7546 +A = e4aa84f782a65d376b10e7789a7d56695885aae274db6cb37e0a34414397a57b4a5f76dced11376af5fd11d31828203e685861a6dea239789196fe73d0e46116 +B = 9196fe73d0e46116 + +Quotient = ed2afbd2e63617a651911017d9d02224d521e99275ab642ad1a941827983b17ef0f2067b5405b20e8e97f2ae6099150a1989df94276aadee +Remainder = 4578107045b9cb81 +A = b547cd987638ff7e3c30fec9b728bc10c3b8cf16e7040bfe0fe9a26e44d2898c4c4d28ef525cde2b4007b2ffb3aa80fc4514a99b9aa2e112c3acc56b72ddbe9b +B = c3acc56b72ddbe9b + +Quotient = 56181509251931afca3bb9dca21eedd6ed4226be67497d8d1bd0ec052af146993e7358f132e842f9b6c4934cf1b4501f5d6c5912e65c8d3ce +Remainder = 1b9861df51429a6 +A = 32988a4e0769a5aca200f6f6f1498512e13b4904a9a311cd8a962fdd688de0c6e50b04f42cdd2cf8bf9b0a6922657f9ad195773e1250f85509672452618da9c2 +B = 9672452618da9c2 + +Quotient = 1fa45bb973dd1d2df0002772afba55284a1e41f6aa4b0d1a6c6a4beb8ae00b52e88a9889037b8bfa9b7ee38036c57b713b48af156c3f9e8d8 +Remainder = 2525d52ecdec8814 +A = bda657ddeabe24c82c883e85822941bf64448b7cbb368468078101289b6fca36680b3884e35edc1fce5a5cdbdfc11359a1ba8ac0785c09ba5fe5cdbd30726df4 +B = 5fe5cdbd30726df4 + +Quotient = 63e21f5568d07976aa81a2690b9e81b76fc3291cdeb010d1693d0e80191186815c7b2f83551a5f1b172640425d4733f06f4df1b2c8a7e6ed7 +Remainder = 14781a368471ecae +A = 9f3dad0b3b56de15ac46cde1d79aba6a2f3b34d685cc810e9fa3f2d865bea4afb480d58653630319a258e9e8ded9be93cda3bc52b80a9359198221221724cc3b +B = 198221221724cc3b + +Quotient = aae37878db016dd758003b85ef52acc7288b7b74c4723e3876a710baed4751d3be2ae49123b248f2b2c55a5be702c4428b1dba9b8a6ae8a9 +Remainder = 6c754d5c167e1228 +A = 4b93a98eb7b92cea0a4f5c2223e77abdfbd332b39f295b4ac40f71625d88e4add7e482adf3010082d8dd8854cf714a54fba0887de87946e97137cf7eabda038f +B = 7137cf7eabda038f + +Quotient = 9881f551c4b7e67611f37df29e77cbe4e2d9fd5e17b7da3d013d6f3d4312e53dd26dfe3a2a12525cfef1ef81e6ebeeb7ef8fb4f918bf15ee +Remainder = b14595005716bfe3 +A = 7737f8e7337160c14cfa8411236ca0354d8aeabf389b9fc4b14bb2ec3bb68286f3d82eb394dbd8062862b955e9fc8e86eb646317d1315d09c81ef51b30288cf1 +B = c81ef51b30288cf1 + +Quotient = 4c8519d4d85ccf845fc5b8f31c27c60f0893ffda29ba86e8a3fd5fe67de5d29cb29362679abde996039b8febda2ecf71f6b9e1c1874361464 +Remainder = 10fae644af084f8a +A = 900f7846e927760d9986894de6489e53cbbcdd59f7707917e7581422508f2ce79b77bd2c56d964a41e60baa927ca679faedcd9cd8102dde91e1f583ae834b092 +B = 1e1f583ae834b092 + +Quotient = 16ef17b40bb73063f3cd0929cfe2405ca0ff2d3d426ac05f8a8dfadc85659105f7f728e113baab59247c4c7936ab975c08d6f1c72c12c532 +Remainder = baff11e6961c72e3 +A = 130b212cb6f3d854e4f17524953fd8592f5e59dfe92fc7d955e2899d1dde1ae4aa20d749caa349ca8d1bda7eeec2310532a7af54660e2a1fd4929335a1623bad +B = d4929335a1623bad + +Quotient = 1cdd7ee2eff733b83beda5b862673177e2f2151ee0fd9ac0bf0ec5b7e05516f1d1b59ea754b0483d0e4bfb7668bb99117907a58a8ceb78028 +Remainder = 29e33e0c2a515780 +A = b0131ec2c1ffe9a523591a9453d2fc740bf885e7efc1a0158905da1e646745ef1bbf39b406564cb3da2f842bee307b36219bdee5991c969d6199279c25d4e380 +B = 6199279c25d4e380 + +Quotient = 20bfcd06f9c54c537ae563e33dab31047aa30a6bc4e7eb0902bfbab3bbb7e65df442c46625c39e08c88310116348e9ebca2450ab463727f90 +Remainder = 11d8f2f6d4c1f55c +A = cefafbaa2990eaa88184162ecb118d20e5999e5a8fdd25ae7f6248650ea74a8cfb92c58efecdd5d31eceb618f1596d7a6bfd31d092cf86da651f629975faf91c +B = 651f629975faf91c + +Quotient = 37204c5735e4ba5e47e845d8b652cfc2b1dc715abf21ea0ecf5b1c6c8b9e596591fd7a7f41787be1a028c147a721ebb891b0abe3bd079b589 +Remainder = 1ee700ffb0ea02d8 +A = ce22d36b3cb913b32bd0e25cc14c7270d3f7b8e600a9b6732377f846adafd7fbd8a09d12fb7011f2283d988fc29aa25948dd4a0f24512b4a3bd460ee19887d35 +B = 3bd460ee19887d35 + +Quotient = 191051194e4362bb201f5471d4bfaf92f79b6fbd119ca3dc1afffba334869ed9f8acd14fc42a2d8f616d652610a483ad90f5140e9a5ca4172 +Remainder = 74785b6874d8fa37 +A = f3c79f9a6af1c5bec72218d969620149afe8bf068cf7a7aceda977076665bb5a2c30729ac3aa976c9be379c6a5458f1501db8802652ef69d9b9f4f097027ddd9 +B = 9b9f4f097027ddd9 + +Quotient = 6c46c17fdb03d192f75d636e1e2ab4e858d55f0f205cffd75550c4347726b5cfe036c6c901782cbe5a04f1985d9fd1dd39d747d25a6a7a88 +Remainder = 9a836be71a24e72e +A = 4f6cf6e357b4985442a25b5c84e2cc0a5e685e2f5ff71ceba439b81f4123e16db2296dd4333fff23eea92bdbb812daf1d27c721412fa9847bbc9a0bf08879b1e +B = bbc9a0bf08879b1e + +Quotient = -4984390f93e11c9a77880cfbe157dc41d43fe901c8895ac5091c5367a77370b16d42e8cc260058adf4d3fc8ee8cc6c0099804f4c319f15561b0a2b1caa7d703db82a726c9eab569c +Remainder = -19374dcf21822188d720d6ec892bda2c084e8af84f38012da7029a3c3660c7e813fd4f7644ca80373575ff98ab6d743e939269c51bf62e04f +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 330af318ce0ffdaa92448777ed117de9c104e0f975651322c8e01b1c470f3cfb7a78b11f7daeea57614cec37d18b89155f19babeda0016171 + +Quotient = 1a56f7d6c06a316a9a466319cbd558a99f06843782673a54775d859768a61933de3fc410068d00d5f6ab13fafc9228fd40ad41434501f8827bd7461441140eb6977f18d102d446 +Remainder = -3c3d566cd48a909292be2ce30f88ebb68e9122a3359f52d1d7b0189c467b829a9f226c0b64845715020dee12d179913ddb7f17da2db86d854bd +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -8e770450768d07ce20ff8f5f6af464b1ee5f1d0e8faaf927a19d3ff801f6089378133e822b8e63cf29c4c9ed721adfc91d3355a3c7bbde77bdd + +Quotient = 42131cf8f52a6a3f189697ce402a8c9439bf05cb3dc1cf8bc49dc2f07cef15b3bf0102c941b5b3bde6440abc6eacfbf77ea8da06ce932fffb226b33dedf001e9657464b0f06 +Remainder = 4cd483574fce075404dd22072abe61200fc455c15b382c7f2962ffd82c38ec1e2c60f71267cbc35fcf77fe1f9301d6b5f884f1c416304aa9f4d4b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 38caa64e74b29a7e9bbf341edbab112a730b17103831a9ecb70ef077e9660b2dd1fbf71d7f6bb4cdae2ed7cdbe9070ec9fde996c91b9bca5b83450 + +Quotient = -11d6883fcd705ac97cae5bb7f8a2929d6f636f4f232ae9a4af9769183dfce9a9296fa0714c3f4fa1eea467a5c96a484a59d0cdd87496b9398e7a818daf89a58add3a39e80 +Remainder = a6b7984fd80d719ffe2e6eb756e4e3bd7ab51f6088e04ac8fecdc744b0385294dd23b5007910109abf40cfca814c10addcb5330e422b6f5eab6efa2b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -d25d50f53c694cddd56aadda2654ae5888603b39cdbace93d19c117af5505750aa24e615f95446862bd693f5b444e2a876eb2cf49f6c7acd007eae02 + +Quotient = -3fa898b02c621915f44b213ba4e80b8e85c7a2f4c78df2bda7d99494bbca3eb2d9354965d83e1c9001f10aad9b3f3ed837a630b329f5a4b28935158fbd9d291a120b08 +Remainder = -320d41a3875da2e83ea9a83947f5abb1a7026c84020e983381722bf7aa87d5987ab088cb2c37fc3781c82c81bef3263fec560023e236a747030618e9d2b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3af2721aad4b18db27842b5e539d8cada9dcd7ac4c5b885065dd2496a6f76fa73c8a51b239b5c068ea6feffda22d8ea806fb488ad5a94210264597edb40 + +Quotient = 179307c3e14de14a744d082825ed723b996a4e15f156ac473960583138c43f4275b4436c50ef8f21a7b450a969819b81c15bc355fbc5fb55cdd8e124d931d142851a +Remainder = -9c8eabd36a25e995c1811b79a2a0357f6aeef4477cac0ffdd130046cb2a647f928a34d91d9b489d394965719cd58604b957c693a93145328e5568d33d88a9 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -9f2d3da1da77914df66bc889a40847a0d705d4648a11f282e09173d170e96d84b5a45092d995318fe7a954b54b88b784423402519a38bb521e84a4f6c5485 + +Quotient = 6c0f316406afb4cc2aebe34f7948422de0b612a02dc47f4ae59419c579fc465ceae1980a3e524fdfdbdfad4862f168a9851664688c9ba01a8bc1ac156a6276643 +Remainder = bf52a2fb6493eac22fc8b334ccd8e8fa347620539d9189d535373f94503310a027c5423197c7279bb51ab8c459e27f548d57b55740320e80b753290d077aa7f +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 22b9e55639ad3ff4f071a49c8bba6bd9047e162fb31882421db8ec5ce46f28fbc35040bbc74ead5a948c47c43e9c7adc32fa52046b53f12b07b5224e0d8e93e4 + +Quotient = -1008fcb6894d8c411905136fb3e05b38ec5d8df35db06379fc2d6d3e3579bcb34fa6e021b98b899d9d082c111b1a6ac8e50418fcd5968ade6aff8828d8e4777 +Remainder = 3d7dca387b00c677d855fc4af4d86d86331fe4309929039e828765f0937990bffa964d3ffc5d4f2f4b8bea978329e7cedb847c7cc341ee52217f903ddcf9446ce4 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -ea045323f406bd7ce25b3ab4993b5f6dd92ca80e3a02607a862deb13470ccef229fad67ae958cd87fecf4f08d9609595077d0d1360d9fe48c4566e237aa877e7b1 + +Quotient = -42a50301031962754ebf9c4b1e125e6df3dd40ffbe09c044b1cf4b62ffb4f92d298b05933a450bcef65e86398da80740a610ba45928000a5c12d26e9f6a4 +Remainder = -c5485b82cfefb3f980e0fc7c6cd89b1345a8fb942299bdc36ed4ff8916016315a0da84ca0ee2824dce3c7e5ed49d517c45173c9c8e30b224940af6cf828c73db8db7 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 384e523d5a687bd1a90101e43334894b6a27e8c6809a8bf5bffabc34d558a8309997dd6f2a3b7c1a63100dcc0b6647b444ef7e5aa4a9c52c7caba1ebd096c3fae6f95 + +Quotient = 1054439945ccb5bc5461fed04e364c7a36d5dd2c0428872676debe07654b2ce31e435a90c81f2bac1032143acb0c49ad101398feee8426bf270bdc0229 +Remainder = -7bf919e14b2559ab82b3c1bf428d083a4c851a7a1fea44718377e9e945caa5cf48e0b1ad727e251bbb330292402a75ecd96a56db4ad07146533a3ab5a717d0a25a3a7c9 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -e5cd83a644ec86b94f5e33d4dc307a2f14ee8653288145dabb2b5f894560c164470197fb9e37749656f47df343c245258627aeea17965fea10a57336bdc6b4a47443492 + +Quotient = 62675274798218da426a54ed7158f8f737b7b3c328a9c351371f0cf61f41712f9b28741f187eb635ce45866762fb5fc5051776151d202e2556c5845 +Remainder = 1aeb5d1fde3c259917e430e6790b00484d0d9508391ba6ebab0f6299190d4b34f5f7d8ea2174974471a1e28ee2c15e05da645db971f699d5d0e80569b7eba7908ae579f5ed +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2622350611b486e6be7a7c1c073c230d604d782c2696038a3233ebcc3f01c6a711969094e47f49e294f2c5bcd04fb1b7c0934f19bf6e7aa519a8d4ec2c172ac59cc1a57b26 + +Quotient = -12970cdd96b92c37787971cd8dd166999ff241be881eb9543ff29165a9c1a3beeb38b1910a5724ffe2b73ab95ac1ca88d3989aa531374d4ec6122 +Remainder = 627455cb555398150e5b4c1c53ee16dac8d80d9616ed1ef40031424287f8028a9cad1a10bdd8430f6f65368cfd00390c8d4355aa5ecdbd1ff0266a1ade235f33cb5309446961 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c9dac93cfb7abaa3fcde359e09a92ab0b5c06359bc09ae9bade3c6783064dba90b233b4c8d5c6236a13ef96c7a223e37bbdd931eae61e845e5a10088f75b3ff5f1158e833b15 + +Quotient = -6742b3871dece5986d4e219bf5f43c101da8896f247521fa286fde696e0b71ffeb3b6a3e4f33710c9ab150b7a1f747cee76839c5e7f2509f62 +Remainder = -203b2d6eec9d485f7b439fe9d4c640bb31170af38418faf4daad577c30e44ca06efda55ceea4fbd959b3809fa2002b6e2cb891decb09334ed89ac66ff05502036b2155ff62f8aeb +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2457088096865cd052e9cd9349c6e5e34e46c89d6e860a36f8e2a0bb1e5d983e07d05e6f6b31edc67e4793cb4d40979c029c80a13e654b66c8acf6b894f615a3ac800bbd09ce020 + +Quotient = 15eafc416460d757d0abbda8d094eb535262a71dd033c25e704a6df54265b6123247e5625da476e0c220ba88582a1ed94265135bf8bf1fb1 +Remainder = -64ccd9a0ae0b0abcb5507d51b2e6c8e52e67907474605c439796febda06eabd8a3185fdfc0bd088cc49fdf564b5b45890b07269c15b1aa2f993cd9872b97aa6cc37dea2f03444b3ed +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -ab34d3906d8a2b806b22c73d44948d703c1e05a9337f75cb0b5df5205c5e2d23f8a92d8381372f9398c9ac2f7b9302b83e48b26512ccd0b06e6b8ef1b930ec2678d71e2eddbf7349e + +Quotient = 3b22916d9fe3145fcc3b8872bebf5aee4e14235f618e0aed09199852c6bed80df39256d8407d334c06f4479f230913370b7d451fad99d +Remainder = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d + +Quotient = -12ffa4b6fc369404968911c17358012b993c18c2ff34122e06f450d3d441926b5f5638b40efb012d76d8bcd3c0012d0a0ce5d55c596 +Remainder = 64548684fd5f6c816bd296234740a4eed772570bd4a48852462f9cddf14f1350ce7c7c6a58aee8f66ad7df87927458db09e3af08eb5376de08444f35e5171cfa0992fb27f70b81574f6e8f +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c58383afca9e1c480ee75d3cb6b0b99ea42e827d39fc96bab6b0dddc97e3eaaaec02a74847f9f7d49937f5ade3580bfcd491990737d172d4079437067251ab403c36a9826e974b113e2d2a + +Quotient = -4964410c2b038573107b0151b36177cdd62495e0dbef536b59c8aacb8836bb45e7bb014e5022360621e8e82a273d0d462b8eb6fc +Remainder = -1250c42f8c9b129a5c477be446b86356edd1b19409d362c3a5fb5d59c30f1c3fdc1424a88a0d6ce20bae885905d98c8a5a6495931f73edf4c60112ed78834e3bff6de3ed54c867fbf16a1cd53 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 33212ef4a8e80daf1049ac6f639f8e1990142ac32f7ebc97675ec90f8eb1a2814dfdd295ae67317253d0187ad33f3932a3a7efb056d0a3c87d28e64e23e9f1de751ee6f0f61c6f39d08d72f0a + +Quotient = 17f77efddeed52ef2e423bc2c10d2ae15c97384b766f4108474964c2a44789e61249103d9f5fe00b4d612772dc6ea12a42e395 +Remainder = -1ec95323b7b95169d5ec0667f3cbf683e98c15dd0fe44df4ed9de9586e43f1f69337e41a6d11d889452665dc0b03cf8d9ef2effe0b350eeb9f6468751b8a2c42608ba2a33192b770cb62381a966 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -9c91fdf2dd1827ed103a102db254630c278bf8b47bb12a342a92f081acbdd8ae5f5476ae194e24b187011ac25b19fd09e6e690777f9d3efb6b3a32c8f5905e1478a27fe4b1adf17a70abb4e7571 + +Quotient = 4f5dec525ffc737094f40d27446ca0be5b7a2aff02d51d99609165c4cea0dbbc1d92bc0a8680782b616c149bbef7f5ca912 +Remainder = 1bc84ce56a9a0c74962681c02ac927051c81f3824d9f3f0f91465df333ecdb449473d9c26ae3abb9509add5795e89ba5eba6ec7c89b114c86e6991ca0c185b34d6e66925a14fd82809dbc4936d273 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2f47be01e6dc6a86097676fbd472c2af0c83a2f743fcaa885e44fda7e9f350e9fb7a8cd07fda59ccb7963f1e95e6a1236f5f94939decdc85afc0e523c711b24641c844cd3113c17fe35ca988ba407c + +Quotient = -163cafed5bcfdeda88555f30bd4cc2da2cefe2bcec9a7c19c36ccd04a45121a5a0dc28d0bf6ab7fa4b78933c47a5d5286 +Remainder = 93f856077f5b2907cefcddc4d767ffeb0acb7af64bb9dd8a15dcfdda6c244c24fb8404ff9ea2fe1dc337faa05930d33cac4f61e171d0236e222374cb3da76396ae1329a407fb4ac652fcbdc568d0fafb +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -a8bfcac452a5e48fee9132b73bc2fef771450143ab80aabd8690ce54c9b52c2b5a669076a7a35fa6d926268077bec6d90b722b5d074f28ce3843fb0147e567c45f4e91a11416c082762e71b5c6129c08 + +Quotient = -617dbaeb8c6f9d584e8eae923c872048f9f9bf039ec6b50cf8f09c061bf79acc3311b37c2502e560848c05ab316fe8 +Remainder = -1ab4613767c4f1f7d127e848f2bb7c72a3a9e1dd6173b63198b80d3bbebce6a31494f19b53ad9e3a77248e6f9b26fc59060e2759a20dcdbe785297bbd912da9a1819527fac550d64bfd20ed1f96450c30f3 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 267d9397138fd0374a7a58593d41627ba1203a646ec2c04997acf607e9d217b8f40183d2f9304447d6f7e727a476e636ded4697a5ff30a9ae3d249baf97969658209c1b32ddc0edf920b0b278e9b5464313 + +Quotient = 10ad85703fd51870306c5e36b51512341d6d39e0bac47a03732787b2f62e49c76666f7f49b2596de6cb5c5b2f31b +Remainder = -846b4479713bb19ebb8c1f1b75d2be0f39fc1095a3d2ca149b5565146bc19382b86e5ab0d098ab1fca1ce701d582400190fee34b602845c3c0c498925710f0b9e3af2412ed5ead1fe03d77e9b2b407ac83823 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -e0ffa4e120f2f46fd1430b6022fd03f71a22f9b120f8d40e901279be235b32d94760fb8c2403d23cdeb728ae73e2b16af7322d6ebd5f5673187668c99805e700f1e997423886bbcb851448dc1ed4cd66d6598 + +Quotient = 41567bbf616ab41da51108d7edcb5a8a4877c5a8663b3aed7559421b1fcf4b535a54989efedfcc935b3917fcd +Remainder = fc026e554a0821e0d36b796fe6a676fcd7383a55fd6158d78ace4edfc3d8aa87c65f0eb41baa2aafadc51218b0562ff4b5c9b17bbe84afc491d9e309217a5138ad48dd51e1b1a9aa51d69963b608ec47d63fcd3 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 396e9b45ce43d3f89386cfad8ddef4b483ecb5173234530c67447ab74629d246c18b9da09522c77f598957e3fd2a1c0c9417399912fd547fb1023ba6b90d63d223bcbf3e7ba155e51bba7e8635aa5c39d2b9dbb8 + +Quotient = -18f1f395347ce8df530d9330c61c0e30ac9531b50a0af2ae7809db1258285c15ba7a436121287990fcdbda2 +Remainder = 51417b9e9995de34316a66a2f70c146df8e36952fe64124819607bd8691a465f4fde98e590dcd56f0faeb95d1b67751081c2393626713c27ec2a2123aec2a4ec3761e5ace4aaeb612d46e52e16d72a186d2ec8a7ff +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -966dfc779cbf9c388a84e947d1128e2392399ff45d9491259c7cb19589154f82f41e852e0c6bb5a728f6e87ff4ff95abcb9b2b57af1b6b7fc125497775ecc1338e4bbcb5315f7afde4e283347184b908545211afb6 + +Quotient = -3fd962e88dc1d501fe9335fff8b6b2d50eea967c3035a3dcbcdc9599b81f9a445ed5a6ae7413b8865fd4 +Remainder = -97f06f6155f8d0ee6850728192e0b4fcf55fbd9ba982c5f1d598ddcbc4e1c4be0e209fefa6ab3b7eb2b4c645e4dc40217202285ab0a7270d085dd9d4fd24e5293faf6797b4c3c79bbf3ec63fd82942549f9e8f862297 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3ac566d6b2d18572360fbdc626ec488aa316a74f33d71a17a2d0e1d2bf26395623eb91dc4abebf2f944e9bc3d669fae2e4332088e9ff9d9f43927a7888b1390ef60f05efd6e63ec606ecb3e164ed6dbdc9d088586aa71 + +Quotient = fb5ce21bcf28490afb64e6746a1a81792c90eae17407c0b4c5ebf2464eeea43e516be2c615f84901d +Remainder = -3d255bf94c3d610c32266fd472d070c0f5e7dddb88d32723b2e1a20709aed2faf28701e0d0227c2b33ecfa9e708e5ac354a97be732b786210d86f1f05d191513386c580b1ad1f4ac6890f87fd0d4270f23cc5c2064502c6 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -eedb64a6e204ee3d6df508830704f1d5b2d2e627698d38a114c07458ea0befd593a80dfd2e08fcb1893adf57061ec4fbcd3130692de7c46f5ca51361e9b79bb7a91963618b8e5b7591392a5f0e3be954e8b9978c97f12e9 + +Quotient = 6933a3123d0b32693351a834751345300c49324b861a663e8700bdb3b70ad996747b284a8ea5c02 +Remainder = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5 + +Quotient = -10e67cbb33dc6e24765893a047252766c2bfad8385150689dd4fec9ef495dff63ede1fdf78bb6 +Remainder = 9dabe2cbc734b910fa1bd25616daee5657d25b6e4dbc2cd93cf8549715c87974a8336fc5070d86c11f6b670d4b3bd5ee8ae3af2bb321fbb4f8fade3f5c6c2d6c366b4d800dd13ce897f13b0d3fb79f1d9ca525b4e7286c56ff29 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -de093dba98747499f2876c8b6b7a6b9587284835ae35f0716dd594c826cdf5b9179f2c6b08d800a77a6936602ff2b64ee0b7c94493bd5009633f5bbe423454b7f018ae96c21230510ab4bf5db394ff153b0e9eda3ef90eb4c253 + +Quotient = -521f5e35300b9ec2742ff472cf61235dfe2e449772afa638b1adb812cccf269afd164b7602 +Remainder = -2ad10e8758e1d358d4744ad344ce319617027107c0b8db195d1b58c6e6035450c9b377f026fdf9e5737750af5615cff2ac3ccee623c060d779373136d48a735b353d64bcc5f2e6ea1e46083fd799b5f57dd5ad0ff3e6df9764af977 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2db1990ba1e353a1a62de1b914ccb691380b6ea937c13621a29f0a40ecef460cea52cfbc77d98706fb3c9939ceaaf962fb8003b0cfb40535e0dee22e8e7d04b5648fce2e58803242c199421cc4b26cae776d3603f2ce410ddd1e0da + +Quotient = 1d45aa6fe6837a1b7ac95efd55d1690b66487202949a286fc85da7ac0b50b860215e44fb +Remainder = -7984639b596f1d4e6efea9d8b4719215588620ac959034b303584679a44fa84a4be0c89fd2e29f54e62959f9b7a858c06b0cc051176af82d4b85e7334555ba11c39e6cfa1829995c383ba81dbc220e527e90a1d440c1d069703cc1370 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -80316fdc405bb002990d3ef7d0e98defcd1f0e370d1e51db2d21ecbd96230baf69d00b168afcb7b8da9edc3ef7f6621ae5c5a0d7797e5c92283342e42468dba1036fcb2ffef1f493ff97826477364f6b5a41dc56d6389a01b83eee041 + +Quotient = 3c0c3f7a777e611d1bd0d17d669a1ef7920b72ea8de06d4b415a73b836e37d6cf0780 +Remainder = d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9 + +Quotient = -178d749de2dae3a2ea4898c59aaba98ad9f340762040f5aea13cad45a793f1256ef +Remainder = 6c5d9b19aed9f099255b6e3d251aa50d1e534e6c86d82eebe097dc8dd0748201e48ac62eec070a999c21f5c7684e5a700212e9079b5fb731321dd1e16ca82ce80c1f5c17fd1720f1353bb90997f47f5fce335a43a6f59facff0b3724423393 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -9f52ead13916f9807d0cf0c6699578af52c54816828f22de62328fbd7b4fd6c3740ffc82af4e24892092c7ecac44b5e775944445e6615fce25610984030a345731f944128f5734e6e315a0ea97aafd7563105695d026880d065761687b75e8 + +Quotient = -4fe43bfa9417839ee408b254603c3dd176653b6915a89de5b781b400162fbed6 +Remainder = -1c15816e03751a203ae23c48965c8541849b09996bc81d28e28d7871fa87d1c3b2d383c056d3084d7d01d853bebe270fe2c0839e71851e169d417c47caacab2aff8a8e05f65dfb20eb17ed8f67475702fa83087bd868246cbb885d52639797b85 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2ef8419306ebfd215d9079c7a2b959a53ca2f4553845e3cd32caab2635c0e77fee8c5c016c121e3cbedfac57f810c132486ba78df9e719a976e0112516893f14cf9b89f95a89aaabf31cce509ac8e7e62ec3833f0be4336afe6d7d73518141d39 + +Quotient = 127e8c06e12943017f9dd57ca24dca0ead230092811d307386c81b6efe009c +Remainder = -24f3431858d5aee412443feab243b465b849f5dc97e4de4db88c7adf774d9bdda65fa0a28cf6b18eac6078b00cbeed2ac406f8426aef868d4b59ab045825d4b0a18af6c9105e32abc72fadef55b221278d329ff6fb9019630411bec143c4156df7f +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -cae6399216401dec0f8ff5eaca884ab061469082ee3a18e49e0b4d5f9cfc98a598c373249a8ad2374e0b3de71370e93a98650684fbb931aa5d8b4482cb0be142492bb71743c251346df66896806f926a4a5dd4c16ca3294f01bb998835e6583d29d + +Quotient = 3f180694e59df85f48ac02b6d4faa26278af9641db18d79f198da5d802f +Remainder = 36cf82dcf8c7ec783b4de68e0627a4a4b2a508637c176de09feef62dcf382bfa5d8b88539b5ca2cab6cbbdbbd0e54c092f00ee13f4a352cb570034cb0a012cc0fbdb6ed32967f3b81d146f352139bd3d9a5c27789468b7d79b84d6a8f6085f859532f7 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3b7983bfaf565c5ca444367654a07b8bc2bf7fdc04ef12128c392bef2f6b67d9475b4d2f0ce1c380913aa98616fbe1d74dc5c9d64df15f5c9b87a8bfbcadf335a6e8f863c7a01ac175a7d79645ababa5f961fad7d1b9926f7284e254fed33765339e0c + +Quotient = -11f635baf7b7d613e84dc38978a21ade2f4cd741d0c4f6ae592d93af9 +Remainder = 4317c686dfd56216bc4865f8dcb6a3446e13d8b33861e74d6c4a3223c387ffb8caeea0141049898609ed1abfc2adbd21756cf64a72272aab6c0b8f2177419abcbf9086635dfbea80a7b884181f2f2ec9a402cb0505e8208909fe062d5e6dc7094d66af62 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -d0ea50558197566f22704e66a70328cacd6f4b7ca9b00c16b7c4b4e7dcbd47c9b2526b3858ebb4de7a571ac570872f3b44ba1fec655c0778a8a87ca24851f6072c5c0b7591b5e67a8cdaca78fa46f201e02379fcb9a8470e4a4971acde36cf501d369751 + +Quotient = -64a078497f85588d3402355bf3e83d25ca1f0ed2c24a395ef6de6b +Remainder = -87fc31ac66a24ebd629a26209ccac1b2c85e52dc83c5240269ae5a27333f33d31152c9470efd41472af034e8536bbe94b0a49e892b1d23db3c13fd84b7395d7e3f19d7d4cb4a4c07dd1860826696cf7202483446452aed2b4980388e7eda0ccac792d77a33 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 254a85bf512d9159b00a70678239902ee7e15ac2790ce5747c4a4743c6a0851e6a179b64c75acf312dd37a7b82a729246f79196b8a399ff476c48a05f89c29fb106bb06ef0300c4b330a7b2bcd4ea1e82584c7a96b99ec2131c885c5851343cfa6ae4d384e8 + +Quotient = 116a06b1d38067cef9f55875fee1254c8ce39b42c19fb232a287 +Remainder = -c15a797fed3810e4f536e9509564b2142ffbfc0c961ee5aa923d43a824765c05d2a99fef79bfcb6310c77a91d9bc6d0762bd687493865de270c99989e891fbf6da7ea5c7c7a1032449457eb73222a011bb755ff44e4bdce8e86f8aa9f687840c0832f7fd8ce48 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -d77c14100d19fbaff6334ca6aa504001a1d56f274632dc89d48e1d517935503c26b60c047cab9e186a55b72439761c884f63fdd2a38ca1acc653f6ccbb4b7262e6215e6d00c8829b448b7ac8716fe0bfdbf8088c8c61eee8f8db43b7b5551f6278081ac2eb1c5 + +Quotient = 6fc9533f6d0e6c55494cb1b319ec47bde8e621aa92d91155e +Remainder = a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5 + +Quotient = -1abc689fd19523d2e295f260d248041bd00ad3009cc7581 +Remainder = 1ab5af1478fe7373d012befb319b53ff9e36899c1749ea763fb74f7d24624e70ee78faf3115c2a423629528f45295e4adec7b122b993b5c29260558be4831df06468bb1c63e8afcfb1b9b533ec6acf754563d2ae25e2adb4cfe5ee3024611e03a156484a130ee01f3c +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -8c5a7b6bc8ed6ac015ec24efff607b0446c1b736dc8b409e2f433e69d0ca015d70c64b4c924175d0e0102ebc3e1dd96dd4d5bb01cccad229e699f9d8f9ad0e04339d70cd113e93d50c10c03083a81264396f5db2d979d272798ed30efa15d52289d0c72f42582ea56f + +Quotient = -4aa210fbc0457fa7366a8aa9a3acb3f9fce812303ec9 +Remainder = -737bc4fdd3d5496fc7f936ccf14bfc3d93f5b7caf4718c444db7a3228b41015c67aed304fec7704ea8238ba6cccb1e94cac3bcf4764a44bafb49e5fcb0339ae44c0114cc304b9c4370363657cd2bec09bf962ccb21f6091b081e71d2bff8556600576e18d4f78fc68b12 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 324774e49bb429553c10156e8db122670d6dcaf6ef5291f515c517d7ffaee36ec5ec5ccb4d12dff71ae7a05bdfbb03ebaf4dc6c4e8bfdc165b77cae20153c27d53bf27d92ff25643b4888cb586e773955a1c02ecbf0fa6958a8ec0b832332eab2e449be6e72c48d2f1ad1 + +Quotient = 1c8631a18d189f1fb689f896005f2dd2098e0dae9e +Remainder = -1a1ac9612fc3354056a5378de5b315f12591ee71f0fa9d8a6b2ea2b1c4eca9947e5c4f5ed3d4b78e69ef7a1f5a9894b9c7d85f6e2244ae76881eb06584eaa98c78b60b46084b517f4882758691f91d9e2acfd580d5e901dae14ff4a4fd6b0d7c73450e4928fc6f02fb5463 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -838df2a27bbb033fa0e581073b879d6e8747fff38539801a1870f2e52d91bc84cf10f2560e93784650fba080304244dbfe9da679f207b6920be46b0214a1e490537e56d99beef3f58b30f311a12283501ad79a5407ff209d19a6efd0421aa144e0cd427380d89bfae5d1f5c + +Quotient = 4213d04b9f0b30026bd355404bee887b22b2cf9 +Remainder = c2bc097d1c20f050e88912f066b658446cacc7a4d510343a8d88ed007a8c0cfd5d44fe5f067a0e81536d121b39f2d0feb8dd053bb5632e3f9c04be5f6bf4091d646860cd38c96271cdba466ef8b7e2377a51d5669117e664269fe3c08a51b10e1e019ac063d670a3c7db12563 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 38ca0c2f03a5c56676a2f95cd7a69d4aa2085343af6b1d2a71e0d1c54157ec0e8f9125df2a499cdd484c04feb23b1e0042ca908db74744584036c79f21c25c40401d551a65afed0ef35f1ea000fa1a99cb29e6307f6ca0304145f7e483d008cf9efb028ebb654115a8c6b87a08 + +Quotient = -134e043b3b88b31f89ff4bc709cfa1bd2c1a8 +Remainder = 99c1c846cbce5e9a26c5afcc0186bb1e43b2501ab3205d13fdf01dccb9b1a935bc1cf8adf74d58f1c316381577366b6d126da49991a0d5e02acaa678085f335ff8b8e975e5bf2e52a05488ebfc21a3e0d0bc5bbe67442f77bfc3c1f0c03b7f7ce42bd0fedd8a498f018d8cbea47b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c261a6c562fcdd56e67fbd2b91027f17c95da43175eaca6e4069c16d240ebbd240582dcde953eea739a4668fbfcdc6af8ff3ab58674c95de90fdb43f64a61108b030d644a44b0319b912bb563f61e520dca9c88f411b32e99c872cf00a01f5badad584636352913b7429b99ecfbe + +Quotient = -448c4922b7a7d5e1efec2c3f41d0264b76 +Remainder = -2599e928027d10d3a11056eb719768e5edb1a625fc0b8a1dd4439ebd30a82bfdf89e617ac7c71622058cc64ba32dc242d96fe3ecb856f1b146f831334af562cf88139a99410dcb869b9ad6ac4826563b400b59f55d8fff262dc920fe525b12b2fa167ec237028a098c9117cb77bc3f3 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 36be11eb72832f8ae7b6bdf689f794f62cc1c885e64706d14a77a11df9761c2e9cd81d8f6a0ad0cb1696c69afd80c8bb992cda5100cf1162d600515568b9dc9c81a518da9d240888d4984df65c129ac0b4c557b4e63ee5be79a27473ff5bca58e559cb04c4ac93b61545e7351bb6514 + +Quotient = 152474a1a76700598c18d9301866ec00 +Remainder = -274a2f9e2bc5f9d75f9897b28f840b71bb10a3e4e7a35ee1dc1150be61130b4e0e987e8742c5edb75a1ce3158eb8bdb7d657b8ba39436d7c88fbff160c7488ddff2f13b3b95ffe149a3d0d2d406b1737a7671f69c0e5d7074a151cb2776b2d13ca24bec261662f2967fd22339ed6c3f2b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -b17c79a31d5085b49793b6a6d628109a6047e3b1afc947e5212d0a9ae32b1955cfd6fed07fc60634ad15f32a9e402d7d5f750fb6d1ad958211f9e8ecda8990689e5212cf72b24e9b51bd07a6e0477dd4c02381d0ab6c0ad3cac1f620f723ab004880800736804751349f6bb19d3db48da + +Quotient = 5665f53d5a7405c83a5ff382ec376 +Remainder = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7 + +Quotient = -eeda035247bb13860f228d8f2c +Remainder = 3976edf710ab42bf069e5829de7e16962d1b765f6ae6ad0ffabe723e21ab01cb9f3f5f4edb1d8c13cafc0556c0aa93d72dbcff754ae9260abd294647b71785bb049bbb865a26bba22defc458a14af019a796e942e77d03484028aac2b3798fa730ae0193d89728bf80a8728715a0807b3c497b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -fb5e55f261aa96f54983869d58b3e9f0757d363b9c43aca5580b7c0380096f396ec79d1b30037702c19be5889fc6376793cad51975100f33ebf43e0897dfabcb9adf3adf8d845aa7589ba1f6d155b25f73dae3b2f835595ad6050401fd4e6392012d06194af415b810b0c10a53bc56350bfcc4 + +Quotient = -5b37eb0c3e3f8f8d9ac6f4e4 +Remainder = -28fde388257b9a11441c592580cd38caf2d69e2ba57d43151c77d26535226e05e08a9e6d8ed470d4354e9f46b7626e5f2b22b652a2d78f817bb51598c727a765941fba63510b58fb3dd5f30717f237da43b42d20bc260b06d488c9c912bfcea1e7808544c58960a3e1355c50c889cefe75d4d9937 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 29232a3fb059242cae6e0b419ff13c479048cfe46a9063188706c6a3842674b16a1aeaf771c5b0ef401d2dc8a57f6fb4fe1b3c7bb545c18ae763e39421e6a07c4469d234f9fc737ac21ca67a5553c7ed693eede4325dbd132dbd9889d815c02f426801eff1f46e7a52f72845234acc6c153f34065 + +Quotient = 1c7ac058af2e7bfbda9484 +Remainder = -54d7aa6dace87e61e24d87053b9d094bd160916b720d7cf4f740a4fc5a7f03909773d0456c530ea0204427146fd44d3ecec51d8627b5768de1494bf42081a8a4fa97163b0b93b59e70e533f3257723e441cafa4aab471ec4086601021c4462e1f74bebf298ef45fec98fa8e6ea97415f84c93c12633 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -83c2cdca7577b32c20e9e20fb498a2bceb7174ea9aca09d4dd2fc7a1d3b922797b4e9640c7eb9dbdb4d93c7fb9daadd680c1c7645d8102d77e9c877a9f65b13239f9a650dceefc1fd41ea9bd2b38a622bbec99cfddbc6e88f377cd51cc29fd17a27f3d0d970403a2aeeac6ff9fd69c3bbc5c2b0fe7e + +Quotient = 472df5f4393f33cc382 +Remainder = 16579a289cc776a47611353e158c43dadf0a78833396f8419fcbbe47d90c7e840e2c90e73e563e6c505bfcf691120ab0f1e9ef9c31db608cade70eb8e487b1113a46e2b5c7f4a172ad99b502eacdc0f91c295fe608389e61d030607a94d09d349fe1a0cc46d1e07c8db533cedebcb4a3b89afd8b924993 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 34b7f6780620246f5a0a92a768072185f02e57a52db1d865c21c952f4386ddb7e2dc1df076316cb4f2f394397cbcde1af0197fcf33e6428e6f5d42a9ccf623f75fae5940873097d4591d9b1a4cbd00074d134272700ab06d901742da695c3ca9d4f917a808113336f883e769fa8051cdcb0cad7cabd1cc + +Quotient = -12b4e74d76bd306d9 +Remainder = 8768fbe8ddbf60b548938d8b4a74c4a326ef335257e5f513e65a7d2cfbe9d456425ceb719407bde3cbc74c9c978970597b5663a0ec61962e77eb351adaee2d2d37f1fb55b5d2ceccf282ea3a0d398be1dd1b166d55dce04a39ef434fa392893618003adcfa61401276ce4e599051ad93152e3477ff524f0c +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c898a753745f0fc178227a7004d917557cf3dcae2e85e95aee51e137b29c895755853ce2d61f214b80070174cad8ebc2795a7d070790acd335b383f9dc88c01227eeab85f1f29d76c1136ffcc7b9fdc073a3a03d8812c7c561b32d8e69754fff64acfd64994b7e9574d2a7cae6bfd5a6fd61dee7ee993bb7 + +Quotient = -548c97fd02eca7 +Remainder = -939e90e281f97a433eb1c6510668d0fc448f03d737d92693b6362c692167add7e4442105d60ff3db29c03ed06c3121aa4a53c4625906519a4092e4821c918d2264ed0cf088b7da43a222877f3ad9a9fe8ec06fc66b9cfbb44e0fdca1dbe4e461dda9b85231b5b9733e0c78852da83bae557755de3680ab61d4 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2c61dce04200e725ab0ecc5016f66044218391bdf650bc0bd31f3749ac06c24707e79526ee459ccfd4bc22834f8d23f391f2e99135f92b5abd0b04079ab75a263c0e98e46edfb440cd865269ed7872e8c1ada312df1bfd6a5fcd2ebf548d7b7d1d75bc36f62e5e9d15262bb8652a8041e5c8f4d673eecb777d1 + +Quotient = 14622572f311 +Remainder = -6d197a84d2ed486327790059adb5c073218c56345f48c15caf6892734fff0aa7af4782738bebf24d984bc8adb3056f67e57f9960001a67fa462afd8c57ac9d60ae6517d58ffb4773b637ebe6bf2473a5490511fcdc576a4c40ed03b3afcb2fd27c57b66a26f6d3f9b2bb101502b1117ba3ce7214c9db6302fe20b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -b818674faf69bc92085b7230d9335d7bead0413f2905539a54e8d1233843ef13f07cb5538e0787097cb24f152cf54a92e62ef143e31cfbbaf3c09650b14229a4f61a783eead26430949c88a87f1618788abab9728aa52dd8419f5d568e6a109f278b2afdea91cdedca43e562d4bb8fb7f1b7aef13992fa7edc320 + +Quotient = 5cdbb03ee +Remainder = 1cfa68d5da7a600a7ac598b9ca1a0759f972fd9a46ba62e5e96d8f6f00fbccd0ab26ca03d14470b43793411ea9803c9409908625fd74ef8f9b2d7c2064b2e3439adcb684e6f01432a1feb0f492fcdd2b8b5a6cdbd0bf460272218bcf763974be8784e5306c219ee535baf5541b8580952e3690b585fd99f77c46d69f +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2869338cd16322409d3efbd328b27e2ba53cbf71816ff5c093849b1d866b8cdecbd6bd8ffea0b7787251acb760f85c277ded21e56acef05d29bc728cf44f55be87cb4c8913408a01a1ad53461058a1cf94538f05ec14a6d3eba804264df957de7eb1a61b794a1141218966463dd42402c260c229241ec46afdb5a06a + +Quotient = -f16da1 +Remainder = d8b66b622b5a54963c2c84aa186bfde5b67a3562e07a23a5f6843bdb615a3c5d4f007ad8b275ad7e4c5b1436252efe35699cff2e0546e6dd8c7230d6ad560c51cd54db6d312be32ae4c708e9047c3a25c211e2566c58d6b9291de31612006d4e847c6916702be99b3f7ce40e1ac842908acb7f03dc120aa8998c60737 +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -f8af8fb7002a9d2218dcd0f0c139b8e3dbbd48e25a5c910f6d0b6684bca224f62768b64955580306bac6bfd45b99ad77483563fc7dbe015edc06bee3ff93b0afa8f5866c23c7a7570b366550490c97ad84062c2495cff30717aaa965a8e15e270b504dbd4fa943be4f97a7fd1f3b589bc9fcf4f907a7690d99c978a374 + +Quotient = -71bc +Remainder = -13316e9b053a06520526f579718c326402d2a9686d51a340375cb53d7cebba99c8d1ae93388db0a41cf55d5753dd1174014ff3305fcdbd5b02de9e90c45ec0d2900ebf6ef847c2a045eab7f80f07f01c81b9fff093a779a280ae42239df79de8d2ec4bff6723788c86786fe276ae6a4dc1472442b552258e1e5b597305187 +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 20fe256859a2e4c4f77db6adef78b2aa4758b29ad0787ce7e277bc68391d5949bb4dd07a9b1a79fe890c8a760871d81adfd3858e27d1bd6de33fd31b8aa6131fef9130a50f995c3be1d615d1bfb9878804b7f6494237d8ad78ac219488f17335ae54b494532f03a3fc8e9576cab6facd90c662658878fec86db66bacda3a7 + +Quotient = 10 +Remainder = -23e09736f469c83f280052ff01071b1bdb52b7e2b061e8a1a8c6a4e091fcd7ca0b33ade885d928a11a3375599aedfe554d1c2289795daba08f07327a19a8adfc219592bcdf9fc5aee5961a48b3b1b5fc380eff5ed2ba7d7e564462397fb6c6187254ee41c74602b141d7adba99205d2e0b35da57efa96397b3a5d112751cf7b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -e849bc0bfd9560cb90e42c8e4e88df175133c14466e530716d89ad0326b660b0e617b4efe8df6b000f517d3cc24d9dd4cafa2773dafd4c6bace0aba54e43c17e8e3ff9497a97ed83e6408aa0aee0e6485dd1d89d52520d1acf4d587422b0c5cd2d5e7e81fdcf842d6331779e800f96628206e8be020ad4021789008a641f67b + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 22004040a65f9b6f120bb7243c638cf3a4cf6fc58c230da932c79568f68e31af7a7b8569aae77af671f8335ae68d6dc1698baa9d6ba9cd633a662101b45bde51d55098b50fabde8546f317ecc2ae7a39521bc075942e3751a349f51ca3c371f3b8a6cbbea3e11a334d677c07612bcdca767194c07fca78ea8a06cc3b0dc6dcb8ba + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -cad46f410062dc33ad4d712c3b743ae2b7613576b2bd7c346a8479ed679a08e3644c7ee4f23b95f1cc9111905714b170abc37ee1003956f64f0a7e876b38d524fbb2436ed56069479d8d2e4029770f7801a7278fff99b3dc76280f35c7d43ee594073f725554a92eaf4f785c18a7cf6669dce5adb0995233241f3294cfb5bd8f4741 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2fef69f9745646aa13e0c38d77951161a1f881a7ceef032698da3fce00764959f11140bec7d7f53d6777c3622453d4525fb068da48047609d18d463a8fbacde1d21035963b668ca11d5b9ae66db13de7a7a5b66a40608dfb56d9f9f0c8880426641083a05b5ff9e6ba0d6da3a04af1af01dc218e9b4f6ad7b1d3a4d1d26a5c906093b2c + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c50a24e5ddafb768f64677233c5cf09da1b4f06894bd68e194b23feb5c5d6844320a12a02d13ad012f13b1438eedd6313bac9c1f9bb4548fcd314988d8fe0ce6458306735307afe08a96a0c2bcd9cf126f529e48b7ff4b8266caa28c40b5c3d2a473ab8805c860d27d7ee9c032423148d96fad019490ea019d40679de7a2a3323e80979f9 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -f00fb238bc9383079c7ecad9b9f6efc622d58a76f2d5d40ec7cd7c3c083c459fbcf3d128df4d20ead5f585505515aab11c36584ca622d28e0cf037419a649d598346063a07e29c61b7a8e76d1949dbce3720d45576763aa0d391b39dd6b694c7cc60a1b4f4f107d87130402985695e1847e82cce39b8d0fb5c88bcf3b37d6dbb90baf5a8553c3a + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2b809f6baacecf61198856d9edbb768ca2df2abe9b7b8ce1669fd9259732c8569c0cafde2e32d253094480ed281a8db230f84e780c6e8bbf3657c0b0baaf19ea973fd8daa2870c9d79f3695d78e063f9130fe07ce806a088ca267fd2820f10dac34b5b32aebec20e4362dce26eee0c29d2fedc1e020d452bc2499234d07a2a6e54314e3fd6dd85fe5 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -90ed75629073df816ec1d6dfedd1cdbed9239661e362db706288dc4d774d806bfacfd4b32c3013ec67d8c2af133b46989f12f809fe202d33d5ba53659bd2a9a85d3fa542de4a5c656aacbbf8899aa66ba816b809f2629f37b0444cd3a6dfc99103bcf2a5ee87790b8401be806b5d7fb7064ff0a6fc8ec769d0ccbddbc3d35f7dc4d388d8d28021c95b6 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3f60052c9dfe0bac797a674ca7f11377a24c28a1396ffa0f46acab7909543086aee1995cf51852ea4a21ff4bbf6e7309cba9848a7b2e3b33dbe660bdc58d513d16bc709f1f2253648b46daa7aa037332552db1da81b4ab9850ac4ec66621648fc856a71eee3cedc6617071600ecbc5ac8636233f288ec249b7ae0bac942a5fd539d03990c4fb28a46653aa + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c12fc156d9345cdfcff94bdd324429530ad8caf8afaaa1a82297eb3a8aecf2ac021384036749e489fae05e8776da0deca7e4325436bc8f383bed579c2d67a456c4e23871489780d760d63d0bc0d1d0ab41f06a091b44f602bcdc0bd4e817202e39ca6a934c0c9405adb5a14d24da895c58a81d1c7ce52734183e00d80a414ddd8869998822364e029b3f42cc + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 205dc6227dbd3adf8ee49dffd43f835882822b1c94f92cf38f5efc62f943075d80b33588973a0e0a8ff5e800ede21d394736ba98d4eedc53a9122f8c262cd09fe9e91cedfd0237003b0124d757797ee13cd03e7a3a257bd8df756940a4d22face9287edca00ca23e7d5e629966ef710b07e54241dbace041aa6d9f82687c3ecba818203adb376ec0b201894a500 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -82c30a9ef6a83d81b77825c71ddc563939b8508f1b7e44c725ae0f61006646ba9b86507ec9a4dfd3755ecd8bfb451c2d43a61599732b8aaeedff7a304ce0a9327e2333f75e9a010556ecbc3abaed02214f25e1c8373bfafc2c288ea36b8d5f848b76295a141d8f633609a6656c07f3d98177f5fa83833476dcd111aad179001f81d6013ca3a54cddcd8dc0ce7eb24 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -b897bc87a40211ef8f93645b1f6c981fa00ab3b12e117a89375400ab5f4c64bfbba01d265c7bc6f5e3a8e26de5de9df3b8f70f4a39c0eba577db5e4b7a68f751b4a69ff4a38915983cbf70dd7e066779405d572f5bbe0719c978b6865ea1a72d90d3ec8a8c146f20d98595036b3de88a7500d7b476644913e4b63e85c4e2632048e9600d553e560759770a902cca680b17 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 20604e080549e1c503049ebf4a56cf9447d90fe699a9773915b0a65588890e15bd58f55ad7b52bd7b7992a8b24704f1dfd5fd07c70aae4ccba5646405ff8a9cbf542dc334cc0c27a790c05420b552539fbf0a155861bec0e4d9e3fbf045720ea3aed58307d5738b64252a963f3fd5ecd0587cb4d7e159b4980dcb112e26c9c34f10a192e090ade157eac1d7a6f970871eaa69 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -f11fc9682601cab97c25533b2599f50edb1ac65d46f1969bd9c3cb3717461627621c8cd401a0a0b91f3645b8804e095aecab31c1bab0c26df556adafdd7e7f4f0510e0bceefa3619e26b8c9a1bc613db03857f53e9eb5d4b8f75a8cd1429feb81edc705e5a779d5f95373d2243368ce17ef22da79a6a2672496bdf629171b7973fc4659c8eae9ae867cf38d6d7617029bf59d2e + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3cb0ffbd9ad21d0e86e4e4dab4d237e2a17d97356bdd305fda772fdd99acefcfb8309d813643c852f66e1c6c7fa41ffd44f8335ef7333b2b3e846139fa9be2c4ea762afba4e11263c0b5fab18c5efff2a18d83ee89844f5f4db2c1325f0f55e066a9e01030c07a85e2c9bbd37b5e767ebcc9b95f474ecff24df9ae52a19edeb66546a3a28980f616eb5a351cd399e5f8436f17faf6 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -b8aaffe779855c6ae51807f8cba780aa64bc22e8fa5e33f7f1dcb084fc476791565bc33eb37b4f791ef5cf46d64576f48b5fadc9f096f20c798355861ce5d24a7be1450bb871f9821099f98213d74a5e5cf83b895ae65e0e0fd096698463906a112e6e169a1cc0769df7a5ba6812300fdd33611761b6339385e1a70f8f8b2be7679ca216f5b183140e69586a27aaa9f2fac118118875 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2b7ee3ee34347dd89ba4a81415aa1269d0390346597b07444f0febb71d490a01b6fee174634bd88e8aa180409549b2726d044b4690353de2fb2294c8f69c612485aa066f68fdb89466760a85901cbc7312bfe5a6f656e67dfd2d4ee099ff97694b01d6d5b8626ab1650eac5267be53f5f3ced5dda1aa86bf42ae132a28fddb94902a515da40e0fd0586dc8b17a34af8eb03d06f70ab89df + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -bf8213944ba785e01b8d37a12de77b2ce1492f34bf6f67406cb51da89675b4f70f4d4f314f30ca8d65cbc48ee2fa1f0a3e4ac0de3a87d2c4c589b6812e850623d78ef2e46fbb555f6d3c69b211892c11a4a2dc3d8a9a19e96a07952602ed5ffc0232c140c3e828acf990e5425d8dd9ce0c1107ad1c6f96c8fbc90ffa457abab0d843094dca3c8a45ddad81b7850190625613a4851485f38fd + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -d736bce537f47ae4797faad797af8cfeaf8a4fd42df1f7e61febf8ebf6e47dabc48252ff7948f3dbf8cc369b6952dc58f64cf09b4c53447d135c7a753c21b6052a9726a47a61e13628edf0f2bdb357f2e780ac1ae1f28f211296c8961c2955b773d7dc2904dfea96780b2877af133c9591a0dd54cb20884f014f363862478ee7ec45236bfdcf0321af0692e68f744af28fbcca827ebdc7b210da38 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2cf1708f1e675ba688c0d19eb61a05d2c8642528ea6b1512375faa732acc59ec04ea0aa55e0049144be09eae1292b6cba6db7a9823f1e912df6a5032bb9674f4f26c0c8244ea0dde7acfda566574956cdc33e4a27bcdea25fe255c19f218cc4316ae8428ea61d1bf865197a066b959c5fcbd7c9596207997d05fc38e32322aa189ea06cf5139522571661745c0d72b740dc6d842f1dd8481e318b5792 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -a9180e44a284b5bbe72fff46e55869f749b626ac33c8cb17be1fc260d7c6f460f24a89e1367112e00d0da4d213a821d09f103f35bc4eade5605bef23c5d048b1cfb45dace8b9c637af626a85fc773cf51e6602a7a5999a030030cf114ed6a4ed7583465b9303a72e7f60824c12329517c6763b0f64abd8ba2b9b26cebe882a51f05ef8076e527d53a213db910a5f42be5fb78729a3dcd08d69a709920a2 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -9fe18ae697576dd36ebdb621d14cac1cfdfd1f5cbb7cfa8962c5a7dace96f9f54fb4f4cf2e650dbec5d1ba89ba53d251ecef7dcc1cab8c2ff3d77903f5fb5f29a4e8e3a2a3c05c105d5733b5132f2f8d88f99d17de86ca1191c32ad8ed469bb649ef188306f69f183bd0fcc32759e4f855170f88c0a3f6745aa98f6225536821bfa056a42b37535a622f42b009859c974cabf2e14f75c749d0fe5a01fb3ab0c0 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 33ab185854b20a8126884eed85181b14e75d4ee452958cc1043b099bc16c24b9c2f3e0b792744f230013907844496e600389800e45fd55133fff0cf19c9c152b9d031039eb90da568f9c5212a3ba283f4d1353ff8ff9dd04d292c265bdcb77c3e411716f471930bccbb8ddb819ebb0e0036dc1a18457cd97f4f5909a725baabbd15e8ce33875895aa8dce77a4dbedeb0271a2a4a17f77f5920c3776caa4a75ac650 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -e7ca0c037bf8bad5f8d9c5a2737e044d9f7284c616156d142612a53eb217f57f4aa00b6daa424e6c0d9163939e1ad0510a1cd64fbd576f3e54c59d7aa6228fb3caaba7cdcc951e00ed141ac3a68abb9780bf46bf544fe0e347f677288e962fb69782741df49b27cbbe8720c6f8f2e769147d89df6e17e3c592bede2e696d384b9f01b99b31c505d67eb6193a8844f8c4cdadc9fe45dd446a0dc572c9da6e58ed303f2 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 22b76d6973e37aff4a09216e57662f186c0a0748c4375d6bed370ea61d1f6fac2d9bbe04487a629118b6b0b0c8cc4179fff7bedcf048cc529498bbd9cc81ef3a103d6cac49d58bc41c83f961b6df7f00c7171fb7d9359e03c76e4364cffae5f67321ce646e9b05f9c04aa16ea65389e940022eda6dc740ddc070bfc7e589b86fd1559dc320701c39de20d54d0483fdeef6c4fd012850630b982c2e243ac1ff918377ceb4 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -e6e4d69a82b83e26ef8ac0f4c3a211153ea6655b7ca12840e7b866510d114693049c5b8b22c3a097eac832bbd1986e60564298e54dba3316807ad64bd6c18903a0f22660c9e8d5dac180f57cbb90b176b842d5b58d6dd9f47499a037833a92a18f397238a8bcdc4afd129382fd6d200d3d267ca1e6bcc2cc65950831cb8e30bcc01665c8149b874c9f11168153c187341afdc43e4d8652ce4fbed9f9eac75db40d64344ade + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 319a81f052db21ee213c536db2cb8a71e0dcd0a9b2ce780a9588c38b717c5e487a337f82b5223f638fb552e92b826192e6a1c27771d1e86584bc6c7cbc5d9a6ce6edf2ea2ccf6939485959ccbf3183b40e410768c4665adf90a0ae2792fb4b5d8aaa06c6294e31893620decc3bc72fb4eb68f1e56b48e39c59abe869d07509b7564268d0b7f178ef09ef5dcde6e7dbd2a20fd1d4fcd707943dd63adf590a117ead1ad10ff85cb + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -eced809145e696ceaa0ee8f831eca67049509b31a1b15e7fc86cdd97a73a2ca05bfea5f4b283d287e49906463ef36f2f8ea23c2aa12d5534c08e9769055e04822be0f8ac85f404f5c025a6833b4115f78da9470451c852ba0f24062397d20385f58c5aca10f3f09072b2592e5672ffb989a390abf86cbce74268aef1f4ffde730b3b962df1088bf8745105a7462379ce142f819c2538d9bba99e094ffbc4478625bc54df16c5e1a + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2c1ffbbb30e71d5fa77b5473392f95297b489c85f83013262abbe948842473154e00c86b2e354278844083f960fd746a3b7cb9baecb9c66932774b3a28f678d50dd8fe52fbeead43d8c8adad7c0fcdbe5e02664b0feb0ce214c5fa007c5fa2d08c5fe96787b95639311cc4b7eb2a7217c9c38c6d93444fa60c1f52ddae9bb2ec1a49a593e210e47377d3623cd2c4994ad9343863443911062e12233176f4a65ec715b3c9731c4a0cec + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c3bf056b905c0392a7b5fa57446ed350f325eb67d59f1784c744b04c7f4d8f5397db913407aa8a7f1dd0225c1a9673828db0d8bf3d4908ef53307131bf5b5c4c6068ad73b874aab98e8db33b0a758532172acd8b2c830d0679a8226537090166317b8eea91e8ee4a7282c0ab0ab6f2b7b63d728d22b534fdc88294c376a8d036ba9a644c2489bcc84f6aec83afbac08067a7b93f3897f8dadfb68c327b751841927a728faba47dc44ec4 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 23fcf9510caa531a304eee8d0b2d49050fca83abbf287b6b6dea06501c5afc6d87d2924df1d45b1bf6c4bf77b563a3013cfb4ad9094f8ee9892d33f6ee1c70131cd5721c5af804a9da7654510e8591aa185ee723f8caa78046d9e6fbb891e6024d2ec70110ae61c3969995e35941d2c7f3779d5bb71ce5b693bc9ce4b087068adbb554acc4ab23624e060f7cea169ab512a06ff3d2a36c2b6e3bd9a75f1a9ad30a6a16b0256c42eaff2c3f4 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -c32d5e643b12db6616554116299c1da672efff1eee394378c5e9e5f702ea4ad64f0dac8904bd2751d2cef91adcb283599f6c661967dbab27059e94dd50025489cf74c6897a22e95013669aa3063fcdd4b73aa6a9a1ba5cad3956bb26346e22df6741cd0ba1c0ab87fbe74035618a394383823216df47b910cae495b8fe7ac5feb3b2cf0d0ef6c75db477160b75324db8eeac48a0fce72b9abbd7079ce6f529a89025a03a3777cc7d1deaf3e4a + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -bcd2b2362aa146cd120b729e81c98ae598804006d046a7ed0f9782baa10a85e37c7c22288dc61c24830a1b42b123d63779e88d7555028292fed5ada1793264b35e961b608bdd7398e421c5474c33a65059ef13787e0cedf4f8f032beac48c4b5e5a67417109142a43b198ab617d1de1a38d6fb4922c6ef70a5aad3faf6f8d5da3af9679c94cf61ee760ba792d2972376425e2ec9c4109e969e3d9c3dd90cdbaeaeb7382cb7bd024b75a1fd6d621c13 + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 3940430ace4b5b87bf4baa2673582db3d27307ca4cd8e55e976ea3e10da72b6deb7de932253bc9228c85cd4ae7766cd0264004c658a66d81e60bb9bf4dd66e2afe11057b7f7b53a1ec222510748be53a93970fb056e8082631b2b77413fccb6e61cdc6f224b7903d75345afed8a4f194b4bcedfee1f16dc256c2bb9f4a129fab6a9fe752895a93937a3d087ab7ca212991ff34f1bf1c55987a574674af43986312bbc3bad3280bbddf4ab0217440f851b + +Quotient = 0 +Remainder = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = -ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -f0dc20b88450f45381791e85d080e4f2cf38837391e16e608b8cb5e0ac0ca75e9f72cc04bf2f56f130d46aff31efbabc0ab14f0c0ad680d6899797297152be85ac012644c8d0927b5b6c70dc3e5a8d79ef92a0873ec22af3d9683bb5db1ffd5ebfb698c5ea64cbe2b6a8b9f14d4c18624be1b78b19eca14942ae9542012692cd0d5289ebf75fcf5486596f92659143e9f952af3622137e633376fb95e628055e0fb1ba3a37ccdf0af69a4c0d6b0793078e0 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = 2f2135850715f623909e41a745eaf7b37593567fa8be2d1ccf76d10b93a096e244b91d8700cca37a2ec1bff7c3d21cc3211ea8b03a3594921dec32faa185e7f3d9d17e98cbf8d881fd2abb944181659242ede21df7e5e8784f541cad678df1ef6ca4a5fa91f7856c62fe593c4d24436810cf4fbd11125bcb571f6975d82afeb81bd0c7700e053fc175fb5fc7b329c438479a863b8d5fbe6b4436b67355c51d0306e8847a27a30c9e61f0e08232673cdf0ba4e0 + +Quotient = 0 +Remainder = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b +B = -cf429f101a2e19a65af1e238f6745215cf476ff2609c846f10289f1ef21b89af2aec53def3f4ec07ea42041f8b5862dc37fd03b2df12adaa8c9f1933cc69b526d47797b40f49545fd093b8ceddee3c55721d1fa19b336218de0cac56d410cc6cff4e620578cf820f5cdaadc367dc4d6372aab1e0ae3831a6d153c14920b1dcf09e7629b7442a06385420d79742e409677e3b82ec58bcbfa668ca072e981e20728a983d84a432605389c855a6668e0ee0d2b67449 + +Quotient = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91 +Remainder = 0 +A = 6f949f45c70d69f65ace3e8d79071803fc6b8cbecc1ec1105ee6dd4e3a07577f1df5674853637faf6e5064ac86c3595627497311d749864c87ae8d6a0fcdbf258de637ac8db6cf079a230105582230644422186051875243269bdd6558b95eea7db6f16147554764d8a36d8faca89e8e7583576a0f9beb7142bf4d4d77d97c91 +B = 1 + +Quotient = 3b5c3007d9c49498ff8437b6f0014d146b63c20b6c5b91febee47211f42109f6081204b21a8af99e9ab2b5165d536344fec16bd691fb3883ee7335e12d69afc8bff57641ac7a4cee350209a08301553854873da153ccf056427a2415e3ce72972afb5883393806ec2388169b513674c0935f67ec79c89dfc4bdc6f9cf877a10f +Remainder = 1 +A = 76b8600fb3892931ff086f6de0029a28d6c78416d8b723fd7dc8e423e84213ec102409643515f33d35656a2cbaa6c689fd82d7ad23f67107dce66bc25ad35f917feaec8358f499dc6a0413410602aa70a90e7b42a799e0ac84f4482bc79ce52e55f6b10672700dd847102d36a26ce98126becfd8f3913bf897b8df39f0ef421f +B = 2 + +Quotient = 4f54d7e1ac8816945de169e9a2c497ff240e313c2b7d58612c8175e277f032cd4ee5dd640605028c59395a1eb4aa00772a8187a0568b93919aa5b95b0462e5bd31c1e507170039306e1b2f4f75f63ab0a3add0eb01217df61a74765fc37e941dedf10fe142ae317573a4f0c8ce408c213749a12f56add5d100d0973b019350a1 +Remainder = 0 +A = edfe87a5059843bd19a43dbce84dc7fd6c2a93b482780923858461a767d09867ecb1982c120f07a50bac0e5c1dfe01657f8496e103a2bab4cff12c110d28b1379545af154500ab914a518dee61e2b011eb0972c1036479e24f5d631f4a7bbc59c9d32fa3c80a94605aeed25a6ac1a463a5dce38e040981730271c5b104b9f1e3 +B = 3 + +Quotient = 2922aed641a12010a3099f3c03f708962e2791dd860e65440acf3b982a4041804dcbedf45deefdae5130df96902056f8b2942069fc17bfb29f46a096a36e842ecb30d0800da13b6572c5b3a095038baa3107ca28094063571b517f7cda3659b63099c57a40d7dd2893b92d60b1fe2fb4594fc3a19b7d7957921437556db0e353 +Remainder = 0 +A = a48abb59068480428c267cf00fdc2258b89e4776183995102b3cee60a9010601372fb7d177bbf6b944c37e5a40815be2ca5081a7f05efeca7d1a825a8dba10bb2cc342003684ed95cb16ce82540e2ea8c41f28a025018d5c6d45fdf368d966d8c26715e9035f74a24ee4b582c7f8bed1653f0e866df5e55e4850dd55b6c38d4c +B = 4 + +Quotient = 216236f9c82fe6f1c021853a21fde3e21e6de355cf193f16b403edf59a6a6ebeedb266d4c7a6683f5f6a434c7129f582d2a5a852269d66d2eda45a1e2f25286c665f6641ff8b55913603064cc7a157f755e515a426873e7bc6b9d699d1f316759c4505a67b7a025598f9d1af6ebff2ed0fe393db829f768178c1080ea004e4f4 +Remainder = 4 +A = a6eb12e0e8ef82b8c0a79a22a9f5736a982570ad0b7e3b718413a5cc041429baa47c0227e640093cdd13507e35d1cb8e1d3c499ac113021ea435c296ebb9ca1dffdcff49fdb8abd60e0f1f7fe626b7d4ad796c34c0a4386ae1a1310119bf704c0d591c4069620babfce1186d29bfbea14f71e3498d1d50875bc52849201878c8 +B = 5 + +Quotient = b9fbd48d54b9b70374425aabe16d6a8a819944a43185c2fd07073e20358510ac3de13cff33fe6220ba952d88b2e0f3f7eddb8daf27462b476b5e127e72ea60fd56cc54bf14d2d92765d5d21652d8e16aad4423cd9789515d59aaa02d42d3e957dde50ed1c9a69e2295144a643a8104660ccaafba250854e7f28a686935738 +Remainder = b6d +A = 8ec1cca67b888cfa26bcee98ee887c47507a253008032c2b37e50f2fb914a34c357f6351e368c2521f3781736d4dab43ce130640f1a55c3851e9b5320f34e772751fd70cab7bd7aebdaa9fc22297790661fecd7b4ed0e6f4275377f2bdcba89bf1d251e0074864618b6e1319eee807e054d193e2616ce52c09ab3d24c187332d +B = c48 + +Quotient = 5157f1bb35866dcaa3abb4abb73580d43d03536c3c7960aa95910db60f4d1ffada96c7d89dfcb290bd8c5bb154872e2dd6e50602fafb435193575a4cf253e4d22dbecf11f8f97408dcc83d6e591b1d5daa59825ed8cb08cf562fc50d62cd666b9720055dc11cd42278258e5bd8021aada0b39a340b6c5585bb6c9c84a9ff8 +Remainder = 3d2 +A = 469e999cc737f4d12c97d19a13ce331841f8232cb780602c18592e274ec8b503884566ffcf28a206288f1a9ab3a25bd74bd054781664a331922a96254d6155677836e7455a6690fcb1acd7550cdbca3e9124356ed7b644660092f8d2df06d22ae7f38ca8a4e7472aecce9ad73c47d3a93cc3ec9faeeacd3f59f70ae22c9614b2 +B = de4 + +Quotient = 3566586b9f864dac5ed132d95d4ac6d1fd5ef6a2c67fee39ece89d615b4c681284b4dd5e27b90c6270b85b150fa2a63440e470b0f937b0eb83432be03eaeb37a0927a9c76b07fe40e3509c93a7b660b77ebbec9bca235d387a9a80a6432c77ddd8190c0ae8ea1d72331d5f4985467755b27573bf23109a01c02975e07daf3 +Remainder = 2a2f +A = 9d68d0643f1d44b63aff6a83fca08c52bf800dc59260db9b7ff930eb1bc01a47966fa509abd7da21ad856f7cf536d32dc7c962afaca1c9e43bcde135e4c5b9cd9b3c8ad775e06fda06117f8cc03ffad8e5f4b456baba7eaa9c67af7a19c2f4d65120d51fa8d31d0cc1ec7502187cd784fd2d78514cbccff969123718de7cb30d +B = 2f2a + +Quotient = e36f2fbcfe134fdf3137539006d6d9c03b8774883211f759b0258bb09585440d6ff440e799ffc434a2fc529773a455db9abf72d8c55903d9ae5abd5b2b5e9ccf23c015882cab8565c654532d9407a188a40d0cb026fb3bfda428d4bdfc14bec72b5cbd59540c42598f1371e9e61a86e6b4c957ea331baca764b771212495 +Remainder = 6eeb +A = b669c646d1bbd7389fc642da6d2c440788fec53bd8409ee604222d08b1fc31b3d301e42a8168be0ac394e5f20eb51708b11e7b09d25043f19032310d6649d33eb6c9688506ebd56ebfd0d3f277511ad3caaba3642c53d27e8fb0eb991c75577f584c52b1ec44111b3a9bf5863c18d8a07b91d8ae0bdbbb3b05ec8d11380a9c3a +B = cd53 + +Quotient = a891f8a42093cd86d76cb11cf734a65dccd5b4d350328a7d2f2be76e2edb6b7dcf4c5e1915c65764c77ae73fd6e42eb8451253507e16f2e25ef80e5d1f27ea18dc976a9b12147ecb643b2ab060163307df818127b2e40dcea95a109d7841edc9288190587ac48ba9687ccd0d014d531bcf66ec401bbcbed777325fd1060c +Remainder = 6e66 +A = 9077614b809f4b22707cf965a7e79217e13ca2011cf9e069babe2b4d908e318608f91da095864403b168d750d904fbfe11c9ed80ba9f60d57a8dac2754647002a0848fefb7a5aa8e04fd28dcb9c8e669de4ef794eab2abc93d68dcbf4400d86de603d199a3ee93050638fca7063ea99a9465dfb60d0568b99dfa1ed79da41522 +B = db65 + +Quotient = 1b16f2e2ef7709fe285ede17beb7d9932caae2dd5fa0eebb541770ca1d53da4428820986cb7e79026eb8bc261eceb200b7696a4b90f675ea9af8389c60dde4d564c8adeba6b117edd05469d285670c0bc78afbc3ad047828cdc611fbcab403c0cb79665d6285b43fa04b77f0309bc7f74136778f8ec16899df040db34f4751 +Remainder = 68 +A = e91e7c26e2b562fe2568613656381d5581628e4705ede6660ca5b79b4a609748889707faf9295b57eecfbb1c0b1cb5cc2a5825b84878e8b9e3960f29b59580385a4af0aae375f8eb7fc66aa6a1fdc4a95e29048ce1e5760722c77cc1c95b1c4c16fdb3e59ed4961f8869711ff24c91ccbe2fb6e0617a5f242227e1e60b3ab673 +B = 89b + +Quotient = 37370826964cbd65a48598e73b519db77df6f520bcead8c0446f1288ac189403adb65603b2a68ab3cc232b667232f2e206b5bee0fd48fea8b3ff515f452b5ef0cac591b6ac8c8c509c59c6d3d4e3fa03e22578ff71f1c72ddad9d637ae0497ef0e2a4b261a72cb784f8283eb7e82b6a05aff0a2f61da4780e4e7cfcc4807 +Remainder = 3a29 +A = 16ad5614f9129c7952c5ee8057d8d12a70780144e616e3ed571b2e38a9ce482a52c436eb9ccb6e4f400321bf1f3ef4c8dc897cd91f868eb7018d084784c4840a1d078c8c6a75e950cb76cf2cd81b719ac04d2be5c9a830b1d1361f7ef6345af66a6d56c53234cd98f587b6762401674973df670addcc4a05ec0344d402453a25 +B = 6924 + +Quotient = 9bb00032a27651eac898b8a567e19ed6448669c8514b5659c4b1103069d9289c6c00b38b44160e0efb2c635b7a64c8296c1c1b5c2cdb285b749e614eb9247c6defa06f8dac077b1e1c26059847de56a1a5ddf7fb1254662624f2ffe6edc48f3b318ffdc7ba2a81ef2d963b934120f58afba2b107a215b58f324e2d923f75 +Remainder = c03 +A = 74524695d4dc11023ff202ed2d165551ace0c126f7a51ebb3ff21ecd7c058cd4a6bda2254c55ce6ef76fd11807f92e80dad31bfd254f9a2e1ca89949f65a1fab8f6a4978c488f2dfa61df46c1faa418ff45250d82958e8f5fdd9426c44a3bcd7c4eeca276abae466787a5ff0ec482514e03434ee68fce24fc620e31265c3718c +B = bf45 + +Quotient = cecbbc189fb1d44c5511f742b63207bcba9c78d09342cdcd12a1b1bc3a95466e7fdd8c59329a9b18f7c793c43f08d52339a8202dfa3a9fa86a2426bf5a94e006849b45cbe9a5dd74ca43e2acdf1051be23359624e8f146b203864d03651d98165b783398a59b446314c9b01f79b1139c30df348b14ffd25b22d9d90866b +Remainder = b265 +A = c3721776b9b5fea8608aa9d381d80ac603d27043089dac276832e7cde8d222ffe142f06c314e94c3b9f6148d029f260879b700e1d435b5f318c8c8caebe92236c9060c183783edec2845e6d4e816197196a0de3644544093b04ac6fb4c69d7446954fbabadcc5dc3309e9a3fcf70368ba7448455cec9c3dc78512a19ebb04f6 +B = f1f3 + +Quotient = 4090a2c78cf8711388347149926610d624543765c9667567ad86eef9f9777f53c0cc0f9a989d9195a5e0da875c03e5c74614f95b8752f9ab89fa61c264b8b5d3e02b043fd539d36dbc6782f45a555d1f36751603d5c3423c7f27b3b5dcb91ddc81bf1563dd3abb0970de6109d76da1f4f9d5208ade2b131fc407c5b169c +Remainder = 2a87 +A = 129d32cde3c648298f8e8e8123f2e8ee9cad3f909a5647ed09e91cb99549d177575f54a7a3ebbd4ed2b89940722927a8b9565ffbc13d8df6d2616d5b1925b87bbb6aa6d39f2b11d26d071fa30e63083ed5a5357ecf0ab1028cf0a43178486679e86fe4dcb071c49832c83c9de4599d672e5ecfc7c9190f1d7275f5a0abed80f +B = 49ce + +Quotient = 43340591e68e228fb03e44a5f2046afe41a3d7ca99ea9ff1a445d75f95f2ff7f55fb914791613b5db7369121d416a5f92f834b0b5e9280b49a9e66be4c682019881e6e8883d7a923d2a5d309b9d265b01d6b8a4ee07f7552934f2de002cf961fd93f33641aaaccc7c367fb6798436eecc9bb22357087a9c482131e1065eb +Remainder = 6332 +A = 42e75e3b8c23287044593d9fa4bc5df437a0f8e876d3105334a677b5ecebf653e8bd7e55dbbf6876005196e44980bc23df491949c59aa199cc9e0a111b58f954eaff2bd270214726e5c98de502ba71b42089fba51e8763f0c11f278faf4c61589ceb674d7c7c61f62f8d18ccd619c20243a508c26b934f06ddeec0421b372326 +B = fedc + +Quotient = 688c7120765f8ef7363f7ae1bb65bc568b16e32c59762f59f34a57f08839d19019313dfcc9e96d7415766bc0aa032b19ecea72c249bffa0538bb1ac06401657df2fbea5c46b18d8a79cee4029e5972d8361fb7e6c2c537673aecd727dbc758a3bca1a001765a216e9985eb7eea67ae979f3803f14587507ba0f8fa29957 +Remainder = 9970 +A = 688c0894053f1897a74844a2408400f0cec058157649d5e3c3f064a63049495647a124cb8beca38aa802564a3e428116c1d085d7d6fdb0453eb5e2054941017c8d7df7605c5546d8ec446a33ba56d47ec34781c70ade74a203859c3b049f7cdc63fde35fd658ab14781751f8fee8c42ff0a064b941960af4507d59309b50019 +B = ffff diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/shift_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/shift_tests.txt new file mode 100644 index 00000000..fa1aa590 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/shift_tests.txt @@ -0,0 +1,2416 @@ +# LShift1 tests. +# +# These test vectors satisfy A * 2 = LShift1 + +LShift1 = 0 +A = 0 + +LShift1 = 13116120bca5df64e13f314254 +A = 988b0905e52efb2709f98a12a + +LShift1 = -13116120bca5df64e13f314254 +A = -988b0905e52efb2709f98a12a + +LShift1 = 2622c241794bbec9c27e6284a8 +A = 13116120bca5df64e13f314254 + +LShift1 = -2622c241794bbec9c27e6284a8 +A = -13116120bca5df64e13f314254 + +LShift1 = 4c458482f2977d9384fcc50950 +A = 2622c241794bbec9c27e6284a8 + +LShift1 = -4c458482f2977d9384fcc50950 +A = -2622c241794bbec9c27e6284a8 + +LShift1 = 988b0905e52efb2709f98a12a2 +A = 4c458482f2977d9384fcc50951 + +LShift1 = -988b0905e52efb2709f98a12a2 +A = -4c458482f2977d9384fcc50951 + +LShift1 = 13116120bca5df64e13f3142544 +A = 988b0905e52efb2709f98a12a2 + +LShift1 = -13116120bca5df64e13f3142544 +A = -988b0905e52efb2709f98a12a2 + +LShift1 = 2622c241794bbec9c27e6284a8a +A = 13116120bca5df64e13f3142545 + +LShift1 = -2622c241794bbec9c27e6284a8a +A = -13116120bca5df64e13f3142545 + +LShift1 = 4c458482f2977d9384fcc509514 +A = 2622c241794bbec9c27e6284a8a + +LShift1 = -4c458482f2977d9384fcc509514 +A = -2622c241794bbec9c27e6284a8a + +LShift1 = 988b0905e52efb2709f98a12a28 +A = 4c458482f2977d9384fcc509514 + +LShift1 = -988b0905e52efb2709f98a12a28 +A = -4c458482f2977d9384fcc509514 + +LShift1 = 13116120bca5df64e13f31425450 +A = 988b0905e52efb2709f98a12a28 + +LShift1 = -13116120bca5df64e13f31425450 +A = -988b0905e52efb2709f98a12a28 + +LShift1 = 2622c241794bbec9c27e6284a8a0 +A = 13116120bca5df64e13f31425450 + +LShift1 = -2622c241794bbec9c27e6284a8a0 +A = -13116120bca5df64e13f31425450 + +LShift1 = 4c458482f2977d9384fcc5095142 +A = 2622c241794bbec9c27e6284a8a1 + +LShift1 = -4c458482f2977d9384fcc5095142 +A = -2622c241794bbec9c27e6284a8a1 + +LShift1 = 988b0905e52efb2709f98a12a286 +A = 4c458482f2977d9384fcc5095143 + +LShift1 = -988b0905e52efb2709f98a12a286 +A = -4c458482f2977d9384fcc5095143 + +LShift1 = 13116120bca5df64e13f31425450c +A = 988b0905e52efb2709f98a12a286 + +LShift1 = -13116120bca5df64e13f31425450c +A = -988b0905e52efb2709f98a12a286 + +LShift1 = 2622c241794bbec9c27e6284a8a18 +A = 13116120bca5df64e13f31425450c + +LShift1 = -2622c241794bbec9c27e6284a8a18 +A = -13116120bca5df64e13f31425450c + +LShift1 = 4c458482f2977d9384fcc50951430 +A = 2622c241794bbec9c27e6284a8a18 + +LShift1 = -4c458482f2977d9384fcc50951430 +A = -2622c241794bbec9c27e6284a8a18 + +LShift1 = 988b0905e52efb2709f98a12a2862 +A = 4c458482f2977d9384fcc50951431 + +LShift1 = -988b0905e52efb2709f98a12a2862 +A = -4c458482f2977d9384fcc50951431 + +LShift1 = 13116120bca5df64e13f31425450c6 +A = 988b0905e52efb2709f98a12a2863 + +LShift1 = -13116120bca5df64e13f31425450c6 +A = -988b0905e52efb2709f98a12a2863 + +LShift1 = 2622c241794bbec9c27e6284a8a18e +A = 13116120bca5df64e13f31425450c7 + +LShift1 = -2622c241794bbec9c27e6284a8a18e +A = -13116120bca5df64e13f31425450c7 + +LShift1 = 4c458482f2977d9384fcc50951431e +A = 2622c241794bbec9c27e6284a8a18f + +LShift1 = -4c458482f2977d9384fcc50951431e +A = -2622c241794bbec9c27e6284a8a18f + +LShift1 = 988b0905e52efb2709f98a12a2863c +A = 4c458482f2977d9384fcc50951431e + +LShift1 = -988b0905e52efb2709f98a12a2863c +A = -4c458482f2977d9384fcc50951431e + +LShift1 = 13116120bca5df64e13f31425450c7a +A = 988b0905e52efb2709f98a12a2863d + +LShift1 = -13116120bca5df64e13f31425450c7a +A = -988b0905e52efb2709f98a12a2863d + +LShift1 = 2622c241794bbec9c27e6284a8a18f4 +A = 13116120bca5df64e13f31425450c7a + +LShift1 = -2622c241794bbec9c27e6284a8a18f4 +A = -13116120bca5df64e13f31425450c7a + +LShift1 = 4c458482f2977d9384fcc50951431e8 +A = 2622c241794bbec9c27e6284a8a18f4 + +LShift1 = -4c458482f2977d9384fcc50951431e8 +A = -2622c241794bbec9c27e6284a8a18f4 + +LShift1 = 988b0905e52efb2709f98a12a2863d2 +A = 4c458482f2977d9384fcc50951431e9 + +LShift1 = -988b0905e52efb2709f98a12a2863d2 +A = -4c458482f2977d9384fcc50951431e9 + +LShift1 = 13116120bca5df64e13f31425450c7a4 +A = 988b0905e52efb2709f98a12a2863d2 + +LShift1 = -13116120bca5df64e13f31425450c7a4 +A = -988b0905e52efb2709f98a12a2863d2 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4a +A = 13116120bca5df64e13f31425450c7a5 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4a +A = -13116120bca5df64e13f31425450c7a5 + +LShift1 = 4c458482f2977d9384fcc50951431e94 +A = 2622c241794bbec9c27e6284a8a18f4a + +LShift1 = -4c458482f2977d9384fcc50951431e94 +A = -2622c241794bbec9c27e6284a8a18f4a + +LShift1 = 988b0905e52efb2709f98a12a2863d2a +A = 4c458482f2977d9384fcc50951431e95 + +LShift1 = -988b0905e52efb2709f98a12a2863d2a +A = -4c458482f2977d9384fcc50951431e95 + +LShift1 = 13116120bca5df64e13f31425450c7a56 +A = 988b0905e52efb2709f98a12a2863d2b + +LShift1 = -13116120bca5df64e13f31425450c7a56 +A = -988b0905e52efb2709f98a12a2863d2b + +LShift1 = 2622c241794bbec9c27e6284a8a18f4ae +A = 13116120bca5df64e13f31425450c7a57 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4ae +A = -13116120bca5df64e13f31425450c7a57 + +LShift1 = 4c458482f2977d9384fcc50951431e95c +A = 2622c241794bbec9c27e6284a8a18f4ae + +LShift1 = -4c458482f2977d9384fcc50951431e95c +A = -2622c241794bbec9c27e6284a8a18f4ae + +LShift1 = 988b0905e52efb2709f98a12a2863d2ba +A = 4c458482f2977d9384fcc50951431e95d + +LShift1 = -988b0905e52efb2709f98a12a2863d2ba +A = -4c458482f2977d9384fcc50951431e95d + +LShift1 = 13116120bca5df64e13f31425450c7a576 +A = 988b0905e52efb2709f98a12a2863d2bb + +LShift1 = -13116120bca5df64e13f31425450c7a576 +A = -988b0905e52efb2709f98a12a2863d2bb + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aee +A = 13116120bca5df64e13f31425450c7a577 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aee +A = -13116120bca5df64e13f31425450c7a577 + +LShift1 = 4c458482f2977d9384fcc50951431e95de +A = 2622c241794bbec9c27e6284a8a18f4aef + +LShift1 = -4c458482f2977d9384fcc50951431e95de +A = -2622c241794bbec9c27e6284a8a18f4aef + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbc +A = 4c458482f2977d9384fcc50951431e95de + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbc +A = -4c458482f2977d9384fcc50951431e95de + +LShift1 = 13116120bca5df64e13f31425450c7a577a +A = 988b0905e52efb2709f98a12a2863d2bbd + +LShift1 = -13116120bca5df64e13f31425450c7a577a +A = -988b0905e52efb2709f98a12a2863d2bbd + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef4 +A = 13116120bca5df64e13f31425450c7a577a + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef4 +A = -13116120bca5df64e13f31425450c7a577a + +LShift1 = 4c458482f2977d9384fcc50951431e95dea +A = 2622c241794bbec9c27e6284a8a18f4aef5 + +LShift1 = -4c458482f2977d9384fcc50951431e95dea +A = -2622c241794bbec9c27e6284a8a18f4aef5 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6 +A = 4c458482f2977d9384fcc50951431e95deb + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6 +A = -4c458482f2977d9384fcc50951431e95deb + +LShift1 = 13116120bca5df64e13f31425450c7a577ac +A = 988b0905e52efb2709f98a12a2863d2bbd6 + +LShift1 = -13116120bca5df64e13f31425450c7a577ac +A = -988b0905e52efb2709f98a12a2863d2bbd6 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5a +A = 13116120bca5df64e13f31425450c7a577ad + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5a +A = -13116120bca5df64e13f31425450c7a577ad + +LShift1 = 4c458482f2977d9384fcc50951431e95deb4 +A = 2622c241794bbec9c27e6284a8a18f4aef5a + +LShift1 = -4c458482f2977d9384fcc50951431e95deb4 +A = -2622c241794bbec9c27e6284a8a18f4aef5a + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6a +A = 4c458482f2977d9384fcc50951431e95deb5 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6a +A = -4c458482f2977d9384fcc50951431e95deb5 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad6 +A = 988b0905e52efb2709f98a12a2863d2bbd6b + +LShift1 = -13116120bca5df64e13f31425450c7a577ad6 +A = -988b0905e52efb2709f98a12a2863d2bbd6b + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5ae +A = 13116120bca5df64e13f31425450c7a577ad7 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5ae +A = -13116120bca5df64e13f31425450c7a577ad7 + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5e +A = 2622c241794bbec9c27e6284a8a18f4aef5af + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5e +A = -2622c241794bbec9c27e6284a8a18f4aef5af + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6be +A = 4c458482f2977d9384fcc50951431e95deb5f + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6be +A = -4c458482f2977d9384fcc50951431e95deb5f + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7e +A = 988b0905e52efb2709f98a12a2863d2bbd6bf + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7e +A = -988b0905e52efb2709f98a12a2863d2bbd6bf + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5afe +A = 13116120bca5df64e13f31425450c7a577ad7f + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5afe +A = -13116120bca5df64e13f31425450c7a577ad7f + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5fe +A = 2622c241794bbec9c27e6284a8a18f4aef5aff + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5fe +A = -2622c241794bbec9c27e6284a8a18f4aef5aff + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bfe +A = 4c458482f2977d9384fcc50951431e95deb5ff + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bfe +A = -4c458482f2977d9384fcc50951431e95deb5ff + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe +A = 988b0905e52efb2709f98a12a2863d2bbd6bff + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe +A = -988b0905e52efb2709f98a12a2863d2bbd6bff + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc +A = 13116120bca5df64e13f31425450c7a577ad7fe + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc +A = -13116120bca5df64e13f31425450c7a577ad7fe + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff8 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff8 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff0 +A = 4c458482f2977d9384fcc50951431e95deb5ff8 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff0 +A = -4c458482f2977d9384fcc50951431e95deb5ff8 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0 +A = 988b0905e52efb2709f98a12a2863d2bbd6bff0 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0 +A = -988b0905e52efb2709f98a12a2863d2bbd6bff0 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc0 +A = 13116120bca5df64e13f31425450c7a577ad7fe0 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc0 +A = -13116120bca5df64e13f31425450c7a577ad7fe0 + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff82 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1 + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff82 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06 +A = 4c458482f2977d9384fcc50951431e95deb5ff83 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06 +A = -4c458482f2977d9384fcc50951431e95deb5ff83 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0c +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0c +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1a +A = 13116120bca5df64e13f31425450c7a577ad7fe0d + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1a +A = -13116120bca5df64e13f31425450c7a577ad7fe0d + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06c +A = 4c458482f2977d9384fcc50951431e95deb5ff836 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06c +A = -4c458482f2977d9384fcc50951431e95deb5ff836 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0da +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06d + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0da +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06d + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b6 +A = 13116120bca5df64e13f31425450c7a577ad7fe0db + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b6 +A = -13116120bca5df64e13f31425450c7a577ad7fe0db + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836e +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7 + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836e +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06de +A = 4c458482f2977d9384fcc50951431e95deb5ff836f + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06de +A = -4c458482f2977d9384fcc50951431e95deb5ff836f + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbe +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbe +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7c +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbe + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7c +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbe + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fa +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7d + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fa +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7d + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6 +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6 +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbec +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbec +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7da +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7da +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb6 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb6 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb6 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb6 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8 +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8 +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed8 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed8 + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db0 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0 +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c0 +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60 + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed82 +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed82 +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c1 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed83 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed83 + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db06 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18 +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60c + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c18 +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60c + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed832 +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed832 +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066 +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833 + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db066 +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833 + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60ce +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067 + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60ce +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067 + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cf + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19e +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cf + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833e + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067c +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833e + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfa +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067d + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6 +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f6 +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfb + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7 + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ee +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7 + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067de +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833ef + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbe +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067df + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7e +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf + +LShift1 = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe +A = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f + +LShift1 = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe +A = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f + +LShift1 = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc +A = 13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe + +LShift1 = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc +A = -13116120bca5df64e13f31425450c7a577ad7fe0dbed833efe + +LShift1 = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 +A = 2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc + +LShift1 = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 +A = -2622c241794bbec9c27e6284a8a18f4aef5affc1b7db067dfc + +LShift1 = 988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0 +A = 4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 + +LShift1 = -988b0905e52efb2709f98a12a2863d2bbd6bff06df6c19f7f0 +A = -4c458482f2977d9384fcc50951431e95deb5ff836fb60cfbf8 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e0000000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c0000000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c8380000000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b41386190700000000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e00000000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c00000000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c83800000000000000000000000 + +LShift1 = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 +A = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 + +LShift1 = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 +A = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b413861907000000000000000000000000 + +LShift1 = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 +A = 1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 + +LShift1 = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 +A = -1569d01c96acaadb32211d67966be2fa35d07b46768270c320e000000000000000000000000 + +LShift1 = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 +A = 2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 + +LShift1 = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 +A = -2ad3a0392d5955b664423acf2cd7c5f46ba0f68ced04e18641c000000000000000000000000 + +LShift1 = ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000 +A = 55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 + +LShift1 = -ab4e80e4b56556d99108eb3cb35f17d1ae83da33b4138619070000000000000000000000000 +A = -55a740725ab2ab6cc884759e59af8be8d741ed19da09c30c838000000000000000000000000 + + +# LShift tests +# +# These test vectors satisfy A * 2^N = LShift. + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 6 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 7 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 8 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 9 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 10 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 11 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 12 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 13 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 14 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 15 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 16 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 17 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 18 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 19 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 1f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 20 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 21 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 22 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 23 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 24 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 25 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 26 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 27 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 28 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 29 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 2f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 30 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 31 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 32 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 33 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 34 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 35 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 36 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 37 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 38 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 39 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 3f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 40 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 41 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 42 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 43 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 44 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 45 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 46 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 47 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 48 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 49 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 4f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 50 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 51 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 52 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 53 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 54 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 55 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 56 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 57 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 58 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e00000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 59 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c00000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5a + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b27800000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5b + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5c + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5d + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5e + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b278000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 5f + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 60 + +LShift = 18c9e860855d594dcb06d00b7d1933608ba906d85fa2d92c9e0000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 61 + +LShift = 3193d0c10abab29b960da016fa3266c117520db0bf45b2593c0000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 62 + +LShift = 6327a182157565372c1b402df464cd822ea41b617e8b64b2780000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 63 + +LShift = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f00000000000000000000000000 +A = c64f43042aeaca6e5836805be8c99b045d4836c2fd16c964f0 +N = 64 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 6 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 7 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 8 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 9 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 10 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 11 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 12 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 13 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 14 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 15 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 16 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 17 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 18 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 19 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 1f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 20 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 21 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 22 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 23 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 24 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 25 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 26 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 27 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 28 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 29 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 2f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 30 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 31 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 32 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 33 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 34 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 35 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 36 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 37 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 38 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 39 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 3f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 40 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 41 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 42 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 43 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 44 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 45 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 46 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 47 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 48 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 49 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 4f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 50 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 51 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 52 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 53 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 54 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 55 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 56 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 57 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 58 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c0000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 59 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b2380000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5a + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f300551844764700000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5b + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e00000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5c + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c00000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5d + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b23800000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5e + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f3005518447647000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 5f + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 60 + +LShift = 1d1cf8b5ccbae667bd05797fbaf9d4c1ff623cc01546111d91c000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 61 + +LShift = 3a39f16b9975cccf7a0af2ff75f3a983fec479802a8c223b238000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 62 + +LShift = 7473e2d732eb999ef415e5feebe75307fd88f30055184476470000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 63 + +LShift = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e0000000000000000000000000 +A = e8e7c5ae65d7333de82bcbfdd7cea60ffb11e600aa3088ec8e +N = 64 + + +# RShift tests +# +# These test vectors satisfy A / 2^N = RShift, rounding towards zero. + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36380 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c0 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e0 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c70 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3638 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1c +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 6 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8e +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 7 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c7 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 8 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b363 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 9 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b1 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = a + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd8 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = b + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = c + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b36 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = d + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9b +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = e + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ecd +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = f + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 10 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b3 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 11 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd9 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 12 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365ec +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 13 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f6 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 14 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97b +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 15 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cbd +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 16 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365e +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 17 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 18 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd97 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 19 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66cb +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1a + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b365 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1b + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1c + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd9 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1d + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66c +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1e + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b36 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 1f + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 20 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596cd +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 21 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb66 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 22 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b3 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 23 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 24 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596c +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 25 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb6 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 26 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565b +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 27 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2d +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 28 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d596 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 29 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806acb +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2a + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403565 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2b + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab2 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2c + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d59 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2d + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806ac +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2e + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa5740356 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 2f + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01ab +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 30 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d5 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 31 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806a +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 32 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa574035 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 33 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01a +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 34 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00d +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 35 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae806 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 36 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57403 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 37 + +RShift = d9ce8dff4f2f39c216ea39a461080552ba01 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 38 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d00 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 39 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae80 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3a + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa5740 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3b + +RShift = d9ce8dff4f2f39c216ea39a461080552ba0 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3c + +RShift = 6ce746ffa7979ce10b751cd2308402a95d0 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3d + +RShift = 3673a37fd3cbce7085ba8e6918420154ae8 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3e + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa574 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 3f + +RShift = d9ce8dff4f2f39c216ea39a461080552ba +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 40 + +RShift = 6ce746ffa7979ce10b751cd2308402a95d +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 41 + +RShift = 3673a37fd3cbce7085ba8e6918420154ae +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 42 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa57 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 43 + +RShift = d9ce8dff4f2f39c216ea39a461080552b +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 44 + +RShift = 6ce746ffa7979ce10b751cd2308402a95 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 45 + +RShift = 3673a37fd3cbce7085ba8e6918420154a +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 46 + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa5 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 47 + +RShift = d9ce8dff4f2f39c216ea39a461080552 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 48 + +RShift = 6ce746ffa7979ce10b751cd2308402a9 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 49 + +RShift = 3673a37fd3cbce7085ba8e6918420154 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4a + +RShift = 1b39d1bfe9e5e73842dd47348c2100aa +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4b + +RShift = d9ce8dff4f2f39c216ea39a46108055 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4c + +RShift = 6ce746ffa7979ce10b751cd2308402a +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4d + +RShift = 3673a37fd3cbce7085ba8e691842015 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4e + +RShift = 1b39d1bfe9e5e73842dd47348c2100a +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 4f + +RShift = d9ce8dff4f2f39c216ea39a4610805 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 50 + +RShift = 6ce746ffa7979ce10b751cd2308402 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 51 + +RShift = 3673a37fd3cbce7085ba8e69184201 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 52 + +RShift = 1b39d1bfe9e5e73842dd47348c2100 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 53 + +RShift = d9ce8dff4f2f39c216ea39a461080 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 54 + +RShift = 6ce746ffa7979ce10b751cd230840 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 55 + +RShift = 3673a37fd3cbce7085ba8e6918420 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 56 + +RShift = 1b39d1bfe9e5e73842dd47348c210 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 57 + +RShift = d9ce8dff4f2f39c216ea39a46108 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 58 + +RShift = 6ce746ffa7979ce10b751cd23084 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 59 + +RShift = 3673a37fd3cbce7085ba8e691842 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5a + +RShift = 1b39d1bfe9e5e73842dd47348c21 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5b + +RShift = d9ce8dff4f2f39c216ea39a4610 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5c + +RShift = 6ce746ffa7979ce10b751cd2308 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5d + +RShift = 3673a37fd3cbce7085ba8e69184 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5e + +RShift = 1b39d1bfe9e5e73842dd47348c2 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 5f + +RShift = d9ce8dff4f2f39c216ea39a461 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 60 + +RShift = 6ce746ffa7979ce10b751cd230 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 61 + +RShift = 3673a37fd3cbce7085ba8e6918 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 62 + +RShift = 1b39d1bfe9e5e73842dd47348c +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 63 + +RShift = d9ce8dff4f2f39c216ea39a46 +A = d9ce8dff4f2f39c216ea39a461080552ba01ab2d9b2f66c701 +N = 64 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/sum_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/sum_tests.txt new file mode 100644 index 00000000..3aba8914 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/bn/test/sum_tests.txt @@ -0,0 +1,2619 @@ +# Sum tests. +# +# These test vectors satisfy A + B = Sum. + +Sum = 0 +A = 0 +B = 0 + +Sum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +A = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +B = 0 + +Sum = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +A = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +B = 0 + +Sum = 0 +A = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +B = -c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d + +Sum = c590e57ee64fced3ca84d4bb013bba7d633e68b2ff4e27bf1db43f386dbfcce501f112b7fff6fb9436a576ccfccce12867becf02b91961453ea41f414764407d +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 23f85668bf4d0fa273d8c7f63c5fee57811062a674111e295a73a58e08dd0fd58eda1f473960559d5b96d1862164e96efded31f756df3f57c + +Sum = c590e57ee64fceccd54e0bdc52476a756d32e794922dca0acc780d2c6af8852351102b40dfb97009f95e019a5bf38e5d127aa78bc34425edf96f763084a8b09f +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4b5b16252ba2355e0b87f01baa721783c403607a4c1b5652c09a68e96926c8e314fa580bf0ad3f8f59bd70f14df86a4676661899b54c79a62 + +Sum = -c590e57ee64fcec882fef3ffd015a3fd9024d8f5f6d53eb537d6abdb0ff5e76a8fb08d5feed113fc9e74745d957adf32704a08339ba42efd5746c5d478e3f57b +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 908007a2f3c551c58958d1059427a0391d4d768f61cb802e4cb062c778354ea3eaa8f0dfbd14ca8203e07ae6d07269b58088a39f7608c5586 + +Sum = -c590e57ee64fceeb242f8a0893eaa0d2ccc3dc57ec40fe917cfde66618fba678ce0c8fffc566d4e8c7944d6443def8014fe8ee410a1b8dfd06cb0b436619e0dd +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1999301bd9877fe07ca711f308b2f1bc4a704fd194ec4dbc297355d6285340d6ad7e90cb0add1770aea19737a06750c3a7a6fa0b778ca995dc + +Sum = c590e57ee64fcef321395bba088ca0a867e1e85a1ea77478f8783e6a6cf8f3e582bff83cb2d7d9fd549fcbb40dea22ac140351007030059500bdca81413600e9 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 219639ed8afc21e052422fff0ae5583231ebca2999404b099628093e6540b1dbc20b9c495aa7229b5965b19a5fcd653b3fa0eccab567c5b5e8 + +Sum = c590e57ee64fce834a00cc6282cb0eef49eac7a8d5b51988cb49253ed85ae261c76f2327a691fc63eceab02614807048b2816cdb9b89ca66a17b6ed1abdab580 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4e40fea1cc899fb166dbc721a6639a28be4164ef92545307ed934796afcb9401d75c18d23352471709fbd049c50740ffeebe5590fa2d959581 + +Sum = -c590e57ee64fce1a17609c61ce02f1020c6eb6e241e3fdd01546ce7247725589de32db95f36718d410f9ce9a94fecc8fb205e876fde75ce83f4d01e1bd5d818d +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = b7739ed1cd3e67cf541943326cf76b4476f767465ee53b94c57c83de417ebee5673809b3bed1c8bac2fc4bce29a4e36d6d2083fdea1c12c974 + +Sum = -c590e57ee64fd03e2d08c3d8e5110d08e3d36557d82e0e49b408337a8c9d4298802ae5f0145a9587531a70d2f8af932b8262245428b5c549817d333f2dfaeeec +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -16ca20955a9d8a64cb2be217c089edecc02a75a1ea95fef584925742c18a234974c0a16ee7991e80bd8d4106db385eafaf421ac3373548aa3eb + +Sum = c590e57ee64fd1bcac71b5b055e5934ba15dd7f56370063369c36e57a6b753269e085d0f4d38bfb711d5579dd1d89d07f266e727b232a497d5b0d9bfbc02d8a5 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2eb21724781497ad2f57babeea62a20c3ec5d1559867a0968d74351a337db12c17bc8d1d5446b1115b5441530870f67da4275dfd9f3e2928da4 + +Sum = c590e57ee64fc7860b0be6ce861bc2f099db7fb623912b7b0729c019a8183c669c73efe02b195483a4cd2c78244cd59678ac4d62f6887fe686a3eed37ed460ff +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -74b7ff38760864efd658bd6699915be16cc058454b78495ade8be42c9f7470ca9b7a43655e1427ab1bc35a5693dac424a6ed92d10f85a9bea02 + +Sum = -c590e57ee64fc3126776e79d9fca06233bd2ef5570a65e4521183627bdbdbc555e9118508cf63f519bc0caedbffd5b1a913ee8c3603804820a9ce54b1207bdef +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = bbf238886916ca0ba32e9def9f9c8a8e401eb95dea96ef02df9fc25a186e52fbee9ad42b76ba6ca2c381d12cddd4292c5d355341a80c7688d12 + +Sum = -c590e57ee64fe6dfd728dfbe45aee52380b5a00cf1e05e9f09ac582e2714bb589caf2ad038111c5b1b5573a45706ab1f6fd5d5a1ee7ef4a9bf186dca8a9ede12 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -180e4c29718f394424cd5b03b6bdb8911c57fcfe435cfa66d10941f870f8c5eb1e1fd251f14af03f23ccc1841f014bb42a545f476dfeb12e9311 + +Sum = c590e57ee65004b3e18a5820de4a6d25e7c3d310003e0b8716bbfd51d5f0f3e87fdf8e00599d713397255281e66ef419a9d9bb228e8f052764f5f861ccca656f +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 35e2568ae9f1d1dfaccfc211e9c0c6eec9400a0de880a94309992528d428e77772f84e21d0287fa76cc6fb880481ebc43ad20524f895f35a1a6e + +Sum = c590e57ee64f84896a5f11f575d34b6001f27d4b4d6e7cd9485260629f8f7f1c6ca6f6115b98d776774295dde4d59cdbbceccad097a0a054b501bfb47d81e85c +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4a4820a05c39969774f623bf6c03ebe0c56dc45bb46e8d1e6b32ee0fc3c6168d26c4d1c0ec7b81f1ea76f164ebd00b2a2a00aacf40175bee62a5 + +Sum = -c590e57ee64edf1b2b57b4cbb92d778ea6b9d9878a0374d4ea81691b09811b105bb6dbf23a57d89264f0e6c83f8d00fe00681644feed56e15fc81103ab9b7dd6 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = efb65fa7b963533d48c77ef80fc7af4bcd72222cabb6232ccf3efeffdde537ce25a8e4129b91273a8654ade9a05ba3dd73740008eec82dd4cd2b + +Sum = -c590e57ee650e25da7b60146e014f472bfff9809aa8f519db7943f69d9ad09ee75a3427c6127cce7bd27f224b9dec03111fb066956b4903f9f9740cce1aa4ba7 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1138c1cb69317d3aa341c9a4daeba71400f56aae62a98acff1f9f1aec88a4ef01ceac74246fcb531738de63a94fc8b3e9c5ea3fc64101083a00a6 + +Sum = c590e57ee653af8752322840ed720f628f9674c81073b58372e49ef26d4a2a9d46a0391bc170336614b27849de98709a4b321da4ddfb978e9f10df29154edb9f +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3e0b5c732ba11e1074f0c69e48b78d724733c66368a21409c404debe97f444f4a352acbaef5f077d0e9479ce067043b30cd393f3fdf5d3bde909e + +Sum = c590e57ee64bc13634cbd149aae35ee47bde6ea3663f74ff300cfdb2d845f902f017586c6d4f83f08c3b4f0c035055d13fc9d340b7b9ed164432aed44e8f4d7c +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -40d9b56339ce561876171a9d37aabd30fcd47dca1171e5467f14c6a9f616b04d67a4abcc8334d637731816e87e35feb10dd3f1b9e50f78ae0fd85 + +Sum = -c590e57ee6477eb692705f8da1357e71591336907a5e0a6e39715088d53b2610882765357563fd101bcf05ca545a0c718f52879fdf4f80cb9a12cf108eca60ed +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 8501af88f0ea16b3541e4cc9eb2bebef137d8d33cc4485772c43ed28f54a1fcc2012b2d347c8f126d7ae11eff2f00c37b4989c5be30bb4aa5ea14 + +Sum = -c590e57ee669b662e37f5abf13d00d2f0c1c9a8b99ec546361aad255f375bc2742a3487c351c5ba00efef09c77331577460a47c57125c620b643e9eaf36a146b +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -19e791587fec9007654cd8e66ab13c609d121c54fcbd84c6c7d1d7e7ec8ea4c2f65d64c5fb6e43106b8e2497b89124ce5afbcb5672ea1f19f9c96a + +Sum = c590e57ee681dcbf1554f22c0b1ffead917dd414299cb37ce6967ffec9c333931e70358729843c8130ac95aba47fa1fa5da74000eff25eecae176f093a4effca +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 320ded8a5583fcfeb53e576bcbeac4f04d7135d9e86b2d9d154943c3b97bafb75e3e45e7a913523db81aa7af5589604d2794974e466f3d60deb4c9 + +Sum = c590e57ee5e505ae4a2e1f25a1ae9b7b4d17dd2cccc09f2416d964e55af6d0d31fe259c160f87646a72e6732d5110256b3b35425225d622b81418435c9dd8cc4 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -6ac92340d14f096abc24dad89a0c226c8ea322f5d4afebd1b7197c3ad46016112d87f4a1d51b2691b684fbfa9e627b806d6829de8f7b960f92be3d + +Sum = -c590e57ee58c3ef1582bf7a516e36f92b60f5a587e2c8cb071d1d52ff215854e52de1519fd5204fa52292dfdc397d8d76b78005941358b63a3e6ca41b0eb09b7 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = c38fe032d37689f58750c36fa28ef6bb22b5969adc3fa13a98650107d8a4bd74d3f940f6da545ba32fae7b42d9b64761953ef1bbea358a2885414a + +Sum = -c590e57ee80262967da4038a143f8ff2e78646108f25ff7183444ba507d76f9b05a34c8310e682c05495d0863ceff264964dbfa7c064adf6d26d2dca6e22ab13 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1b293c4f2a4955b07d4cf9cc1d45cc155d6bd2a769636d3db29854baaec92ab9ec084850b924e2cd6286b11e7fc09071d99e3a1729c2dfe94b26012 + +Sum = c590e57ee85427f08e8c89ffebfcc05c73370ad4cb77696c2b2f3878e6f6df341d4d931b5097aba49f14ac0312e7da1c843d6fd08119822e75e6e7a8c7bcb7b0 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 204591f038d1bd0df9200064d852185922827251e8123a7ba48f4e4c296d943de71ad69561129a9ac2052c9d5ebb92fde4eb7d91615e7dcee4c6caf + +Sum = c590e57ee051ca1a363c47a4cc016c3de7f7e17985009b545528289e9fbc9086f4b42a73826eca0c278b0d1b4ef6d74b9a0bfcb7855d40fdb201fbad1074b927 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -5fe04b754c3268a406954183dba07d5b44ea6f2b785ec328cf159c866028f63efb7342f2178753e17d0b0071445b9e91d6d8957adcf041ec8fb91da + +Sum = -c590e57edcd6e9ef06fe33f3817ba3d0c50c8122b77615c4b8fa50c5514f113d7ba53ce057d487bcbc373c4384d07b29a527b7ef785ca609474879b42a9a4c3a +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 978e4e284013a3b8aef1c8560a5682c81d92c8253b3c40bdb5ed911df117cf71a51767e8ccc4615e1f70c290929feb12a6e244c18888617aed5fec7 + +Sum = -c590e57f0436bdceb586a093522eb1630e0fc08f8790957aba1875a42b7676f9ca936e8f6f3478d6ef5cd590bf6ded0700440dcd769496822af8015f0a6ba2b6 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1de6eefd2a87326445c3f10ce85dd7404e415333ad6a60d2fec88caa6fdcb4b7fd0e7a9ba659533758a665b451f2572cd3c9cc2ccb27019330fb57b5 + +Sum = c590e57f1df3f004d5e49f49fa28603b26659f1fd35e0d8d7a2753591dbc12c51e6b588427dbe3faba2f0c1f2f0a2aea9ba1fcb2fe71c6ff40555058d23c8661 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 37a421334ae5311aedbd9fe500b3b5d09a0ecb466d793e87f10e2875c3b49eacb5b5e5bf712b89c5c842a397ed5046125ba6fca9e084508cf8cc3b60 + +Sum = c590e57e9a4abf4572fa7c4c9f73e9d3fd1227646fd6d15b51924bd7a5d417b01fe6b4273eaa6ece387422b81c8116f29702d7d66d2f6e8c3454807b3b7d413c +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4c050f8c1804f1e26cf6d682289fc1eac97870ebbb1bc8f986d9d29f3ad005b0337b8f6d108f5fa14a467060174edeca359b5bc92b7c7f509df309c5 + +Sum = -c590e57e64216c306f17017ac9dd7085113e16c83168664dbb77c7ad3ddfc79b09f9ea0c474a0b497ca15e7fb258eed9666fd009f691a3b2d691c2c6b22ba3b3 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 822e62a11be86cb4428d4fd11473d28707e6dbf951364d23eece22b450bccfcb2adbf2f1cc6223d9b46e987947e1e696ac3926a2893f3d052744a74e + +Sum = -c590e5806ab4d09773c4f94a4aac09f6ed7609eec1d0bafecb09e30f032f706e9adadc191ff9e6d7dccc821f7a8666a590e521749d24912c5a5ffeff246f7c85 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1846501c5e8c58b1b3e4149a0c7c4209f888178b7be5bce3dd681861f40242241add3e89c93c8ffc613bedf52e2936ad3fa59c6d6fa8eff334aff3184 + +Sum = c590e58248cbf5dd61ec57994fc862ab479dc6cda51cc17356c45cef66bbfdd12f5cc421940a561581c123fb17483beb7a1cce2596fa9ca76e722a6f4621eae9 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3627c270bd6ece96a435da25521ebdd7e6bcd7f2c4a16481e3a0e1381d4a60a4a21e457da38bda1a1b080b498cbcb1784f42fd2520ea12aa36cb19fe8 + +Sum = c590e5771a85bdb1f26c0386ce837bec4b0af5656496efdf4f134d875f066dd6d477ca8f87ffb275da07da4dd1bed4232849a526836b47f2d69f2d53b6b3e2f1 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -7cbca111f98936aa83de74469daa6f3e9d4b85267bd9ac749cda77c78863eef47ea264bc56efba80b9508b32f8608117a1f5f82628931d27822bc6810 + +Sum = -c590e571c76afad23439f904e8a80fc28dcabb6cb732e361ed3eef471be6fa755e3fe746edbfe448c1f289ffed7dfc01fe9066d780564f57f93abbca9b9a995a +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = d1ee4d3ff56c5752a23c2b09397e72de2821c5ee51f6f258a10c6efd9fc76d290846619f28710f85979498b50afc14fc922747afd669644013dd5b1a7 + +Sum = -c590e598cd5d4a59ff5d6c97c6370fb517f1d492a7776f90063b0ddd6702e37c60fc78bb12857911cea37b7263584d7dc815676de6b8880200acea154b59b08b +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -19e70d7b88745dfe68b9cc4f5ef23feb436e282d48f98cf90c3a54f92d0645bee3a05f7ad6859ff918fc90c62b19c3b0cd43edbdaca0dbea4971e9658a + +Sum = c590e5b5829e6fceb77830fbe999a98127b50302fd0f6a86ea4aea27b846747a07e6fcf5457676e6446137d6bdd8ff4fb7ca747b650b066d65d7dc1e172488e7 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 369c4ea0fd2c78c2ccdd2ee92b020319b3c3c0283fdd9cd5568b988a2aad30431dd35078aafb5db57d571177fd0978bddac2403c180606dc523db43de6 + +Sum = c590e52a3ab5d5c458634254e2f672a322000750741e969d2f6cd12d172480ad1455300e3a0575b068b85d50b58f9737be13073188d0f03b71494bd0fd2fea16 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -54ab99f90d329c2bda29744db303b1e1fec530aba9dd4143a4158969a2466189c93820888ae04b2508b137f01af03eaf6f19f9da19ee87b3fadc4060eb + +Sum = -c590e4880579ef7241bde94e8c7847badc705f53828751f9975f0e66371d2ddff8740b143f32e88be8e686e2bf5a3ce03d864d7699a813b1777b9239af242c7d +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = f6e0d5df5f494184e07ff2789b494189fbb6c7f04d754f066af590bc6f6242aec332f315af601cfb76a76d4a7270cb692a0922b6a3e8556d922a4c1e84 + +Sum = -c590e6dbe54098694155509e38c61d503ab7e5237d2cdfc2b87fb57e3a8420fe37fe50a0dad4f0eae3d38fad6198e4ecaeae183a12078f53d09ac8099c715242 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -15cfef0c997b655e26f2c5b5cfa1505fbd443dd9d7babd1a0ad0dd636aedd4796c968aef2af9ad00d53fad15d9a005c61996f3cc4fe70c9c83dc3010741 + +Sum = c590e906254d013be2021ad591e76e26706a6815b8c484b6528fec65416e1066957002713e1183f1005f565983aad7aa031e549e6fc57094ca3e4383e7fdbc15 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3873efd326a5702aca6857cadd04ab87ec67f75426f45e1d79414c026173ab94899cbeb85b5b75bd4001ce3505754cc9dfdccfaa63f6a6d43b80e8d7114 + +Sum = c590e0e0079190d7afd80acd6326fe93cc00903318608df31ee4493d11271dac7291bd142cca0e5dd7dda59dabd460a69b7855d9c2acb5f062de76665e07cbd7 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -49edebe3df9db276361a943c1c259b1591c20eeb453edc9cb941b86cca2e824fcc3455befdd7125dcbbbaf326ac12d960c6e01e1464fcf289657b687f2a + +Sum = -c590d9ae456d66c1b132d844eb223867ba4560b36f53c42a616cf8cc657e6d252f813847fb9fc50127227684e5c0f5cd890eceb341d21e788e42f843e9b64080 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = bd0a0e2680fd9cc95ea214887ee6b6c889bc9fb7e1cab411c04c72f7d2a2b35818f7686393a21e10bd4810691852542e7ed60f8abdcd18e0787efba0a81 + +Sum = -c5910498291472fe1d0047d5bdd9e46deb3f26000e943fce8d83d700d9ae233ab3a28849bbb346803da142db6a471e9f79cd49571f40dbc46f7b727a4bb3016a +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1f1942c4a42c9200d9a6b16f2417c58d3cb0d544fd8780d5c22fad0038eb58ebce72498d4844f49dc082037f974ccb7b92b67c76116f0faa72ae7242b669 + +Sum = c59112d841ea109440e78563d9eefef201c81e86ae967083f8b7db80d1eaf58551d30519ca6dd79164fe69a29cf1ba22446cb2999f73292241005bf17b37528e +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2d595b9a41c2b5e81734cd843e9bdc16353775472e3cec09c6afa53d0b35f71c4b425847d9561bfae749362a32cf961afbf8fca85ecce12f5c25a1c7078d + +Sum = c590671f890ca06c74ac6d2c4d75aabeaaa55312e85a5e1ea9cef0e08e154e2b090eaba869e9f6e4a47ae10b9c1eb0f6ae4fb3ef12b3121d96066c6c8e592b6e +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -7e5f5d432e6516530102bef515977b0c963c50f4e42862df23f09e989c2451a80e2f083c0756a488a14dcaa8d65c000202b19017b837c9ca935f4b171f93 + +Sum = -c58ff0ae92ab03072154949a7143d45278ef77a0ba71a785d5a370e0d30a9b4b4f7e96a395d13e6afeebbd717365d471ee56ba11c472a63c0532558104bedfc5 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = f4d053a4cbca69aad9949b26ec03acc271ae7edd9ac1370aa3f059a34f040b382333dc54bfd04a17c4e7f361b2e0bffafc8ede5824195a9eaa4ad4b16b3c + +Sum = -c5927a5fcc3b31abeca3998ad99c07626112288a6ad95b24929fed581040757fdce73881c48b02daf09986ea436a3f5ceb6833c31fa2e1691567601a26c7a6c9 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -194e0e5eb62da61a42b5bcd31470c3b603f3b318a18dd85f1d886e3928b3082307eaa5265049fa7960490dca2b80a3d167d227cd81713b596604e4d575bc8 + +Sum = c59395e94d495451e3fea153f3e4361a088004a7d5426c1b94aec44108ad6f5cecc3a80dda0cea9f51b882747258137e171bf021b4fc59f4dcf0106d4ba952fa +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2b06a66f9858058ff3324e77975c3e2ce1b589bf329d48800af6fdbff850d920cee3667e6ec6408b5001b0b908c2b68ca398112318f9f7d1f10a1723907f9 + +Sum = c58bdb26c0fd6766f3affea389cbe7db25c06d5d56356d3d945347775bddf479ffc9e279e7d1ee88eddb239906749815ae4502fbbc6fe978a001ccdafd89cb10 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -50a582552676a974f6f8b829ed87afff17bf1e319d509785acd59d0cff5d55aecd75d8a540fb25b285ec06052ef3d000cb3a4e65ae0dcbfcf32f0dbe67ff1 + +Sum = -c581afe9b7ae86d4b7053f19649beea6cb935799a553f035f9b9a7fba6d5559e4ecdcd1637c73c8052c6cc52ee1c28d1e5aed9db7261b7356afd6e3dbc213684 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = f35952ea147fcd3fa2f15a7ced1af5a1e91b593fb521112f46cd585d894b10be8ecc13a5ec1baf63cb60678ab5e80c8a2dcc53069131ff4d3918e1d4f147d + +Sum = -c5a19f36a65a6a8d52a53a63f99a1b957d6e376b7010ad14695d78d67b0d7c86881006188bd27bbf205c8c9c200dc8f5c08ab6b97dcd512f6cb93ed9a361ff9f +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -10b9b7c00a9bbbc7a5cc34ed2f5b3f57bc4e1c36c16acd5caf64054e5f92372d594c4119ac7d83d7590a42b94641a312390018db0286da0ce83f0dc9f1b49e + +Sum = c5cd0e5da24b67a894402b0eee5dd586ab70e5beb0693e263a54995193663a9b770141379c1f097a49d1a889bbf0c348c6f40ed50bd7bdc11a7869c6106c6d80 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3c28debbfb98d70940bcdfe1f3153085befc6f7719fbdf2da6848066b8504c1c4a876029f90b3f00ce263055293bf618a25834690cf36bbaa769fa36fc227f + +Sum = c54e2c560a00226701b76cf03d5de27a8c69b38a6b85dad9f7c903d2e87f9a7d247522e72491460f6a529e5ca2aaaf690cb238b873ffb49d9fb0ecacfedd4e90 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -42b928dc4fac6a8948013ecf0cdddb994835c4cdc9676d14e510fe442e4fd2364196f04d94b82bdeb0e3fcc41cd7e9a19f7de82ecb15b7c020131eda92fc71 + +Sum = -c4bfb037f6e6e861efb090ee610c33e7568790259f747dc6e55d442aadd68c0cc93c7617f83980e8813c0fb7dd28c8aaca6ad8fdde5d2bfec9ae096faa9ef54e +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = d13546ef68e66f9b4edd40ab5e8c6ecf2a592999dac4802750d0a67ed75e42917a43bf79ec7d52c7c772a1899ebea7e3e6dda2c46d9e569622f65c2ed155b3 + +Sum = -c6aa2af8c9ae8be4aada83f66b7f31a8bce5e92c67d8938424a1405903e5502bffc4ee1e333da4bcfd0cb383b19a566372f877a8344b66dbceabc9786dd0e4f2 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1194579e35ebd131fdb15c75f1471529733ffdd2e89513d17f32b87d73765dca50e3446c117a681b409312a4ad2cf10c4a6c10791809c866edac9ac946099f1 + +Sum = c8aff66c9bdaa49eafac0f65d3ddff223b7a5471f7400431ca3a54615d600fc4a163f8fb648bddb5fd6915db1991611805040e0f86f152c8fd3333ef70d632e4 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 31f10edb58ad5cd24aca136c7733ecc15c86b22bdf0c1eabd8c3f9030b2257546ad3f23f265df7ab4659381b2c9d9c556b2576ee42688739d6234239765e7e3 + +Sum = be1b6eb768e2cef388eebe31f9b21e51b38b351cc8175eba06d49eef04c2936f32167174dcb82297fd4180d0afb5da2c455d158c7a5bf01bdef8c295a4f20390 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -77576c77d6cffde0210affd12b8a2047226b4327137e38d05d975e227eb56e028a04862956ddba34bc20188b711ad2668f4a114286eda3980d83d36347e4771 + +Sum = -ba32fca1d5cc5f31ecaf5407f376d3aef9f4abc04fd4c6893721d3e50e9141abf356eb2ff6f7a4f9b42983148670d2918e1dff7aa7ae33a6e9dadcb708b4f9dc +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = b5de8dd10836f9f9e501a2718f3eca72bbd3d8ee97a7bbdd58c40ec1e1ca8a3675fcea77b2e594194d9ff44e056b4c12033b725fb1c96ae75f62314d0bb5125 + +Sum = -e388afbf17c495f86aa7298a45f848eb57e5baaee42b1f7de8c2311bfbb8f74549712c05fd3bd11ab8874fb55abb22a37ba3512e733ecd5c472842e8e6f7b179 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1df7ca403174c726dfa7bb5b398d88953233d15faadbdd36dc141c4acf0b0cf5eeba722e8b15d2df6f83cd5bf3f39b50cd519a8dd0740306e757431d0d876678 + +Sum = e891babe65ee02c02e7e876c0df3dc3bb37491008f3642ca7affe2d623fa82a6d5a9e5400944a374ab70fbb8f952dad0c8b27c77475b0dfec7b0694051dcd1f4 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2300d53f7f9e33eea37f193d01891be58dc2a7b155e700836e51ce04f74c98577af32b68971ea539626d795f928b537e1a60c5d6a49043a967df6974786c86f3 + +Sum = 4dfc2f63d60f83fb1d397d2406b02a3b25c1a57c09c2fe02c76696b7c956e44facdef11470074d8fd8220c7bf8e647ba873fe9c3f9e77d6aae7b5fb64f1cf566 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -7794b61b10404ad66dc5f10b05ba961afff043d32f8c444445477e19635705ffadd7c8c3021eb0ab70e175dd6de13f982711ccdca8e34ceab155a0158a53559b + +Sum = -3c19bedc60e7d7dc3daaa36795e453d810c952dd5185fcdc857e2be806e520068dbedb91c4a1131b9eb6dcdfd500045209514e3e9f6e6df41d2ec67fba20e10a +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 897726a28567f6f54d54cac776866c7e14e89671e7c9456a872fe8e925c8ca48ccf7de45ad84eb1faa4ca57991c78300a5006862035c5c6142a2394c1f4f69f7 + +Sum = -28c2bddfeffbdbdb1ec6f06aa310d1bb6f0c4b88d0106a1b381ae6fe8f65c18bd9895fcba6931ecf06d9dab6c7a3ac9e00361bf165f16bd16af25230d040cd842 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1c69af880196deee0616f987b24a25b60cb12cf3dc7b75f6c75005b17c9ae2e6e3ddf42e2f70beeb5249a29131373428d55100875bc4bf2c14f5423412a9c8d41 + +Sum = 372ea360832e30b16a3c30a2157c8bddc4408ce0428169deb09bf68113e4b8482d887de1a7cfc80272e597c3f3f104e6825a1fd2a68b41cbc307caaae17d453e6 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2ad5950894c933c4518c39bf24b5dfd861e56e4b4eec75ba3fd115340119d9a337dd124430ad681ebe555f9e5d848c71577504689c5e95266d0abaae23e6408e5 + +Sum = -5b29f4991cad86845a50949f25ad6cd7c883d71ceec9795cc528f58a4a4aef9dc139e8e87cb82071e112b2d256181eaad0a98fa36b25b67dc673608939b48e08a +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -678302f10b12837173008b82167418dd2adef5b1e25e6d8135f3d6d75d15ce42b6e55485f3da805595a2eaf7ec84971ffb8eab0d755263231c707085f74b92b8b + +Sum = 98b37ecc0b42a15f52c8fc8bc2aba294031bc2dfa37dcba0fdf1f5f5da00b8b3daece033b47bf254e8b5e201bae24995034673800d53213f6ee0796be1ca93845 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = a50c8d23f9a79e4c6b78f36eb3724e996576e1749712bfc56ebcd742eccb9758d0984bd12b9e52389d461a27514ec20a2e2b8eea177fcde4c4dd89689f6198346 + +Sum = -1c15985f3ee941d7ab6bedad88143cf497681424e7456fe30eafbdedfcdf1e927db124c775b87f36cefff17a35972ac40d498c4be818883bfc206f44c5e5eec23b +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1b500779c002f208d9e0ee3f5907d2344142623b980c20a0c7a30fd92bb270a82e566e0d9e46593893b6edf7dc30633cba9b3a954775bd71a6c09e44fa0c7e773a + +Sum = 34ab71257e63b234258027e26bd35dfa5e07f67385b6772c5ed445438478bef5a835e87c9de413e23839849a71f5af99a67427098b682bfb6becb66d20eaecb2e7 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 33e5e03fff7d626553f528743cc6f33a07e2448a367d27ea17c7972eb34c110b58db31c2c671ede3fcf08118188ee81253c5d552eac56131168ce56d55117c67e6 + +Sum = -44f9508e3430f93d4e2c8be1b856f46c01d6940e1bfda8515c747a1a95239547322999e500e718ec98ed211ae04ffc76b0e6f2364ce9d913ffb80397f24ee8d64e +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -45bee173b317490c1fb78b4fe7635f2c57fc45f76b36f793a381282f665043318184509ed8593eead436249d39b6c3fe039543eced8ca3de5517d497be2859214f + +Sum = bea59d2cb0bf556876d4f8a248339af69644a12d3dc1d9a3d83929929b8db5aa26289bd06e2488a96820ea8f59168cc82f19b5dfaab20d245495d6e24bfb260a3a +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = bf6b2e122fa5a537485ff810774005b6ec6a53168cfb28e61f45d7a76cba63947583528a4596aea7a369ee11b27d544f81c807964b54d7eea9f5a7e217d496553b + +Sum = -166abef6a1682bef78d4c5905a833b81a03c0bf0f3735973bf7f02181a8ce5c7f125f41fcbb10c7f5905e492fc3f6b172f23d041620f8a7ac6f76e0c8a53d3cb5e8 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -165e65e84979c6f28bbc1599779274d59ad9b0d25e7fc47f9b0e3736cd7a1ae94c3048b42e39ea1f7551545ad6a8fe9eb9f8eb25f8055dce21a170fc8d963cc6ae7 + +Sum = 3245e002843eb7116b987b5cf9160e6891a74a6843039f8517fbda68b0e6ad87fd0aa836a2b6aacabcd67d45d327e6cab43ef569f488354e22f4553eed09e83d601 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 323986f42c5052147e7fcb66162547bc8c44ef49ae100a90f38b0f8763d3e2a95814fccb053f886ad921ed0dad917a523f14104e8a7e08a17d9e582ef04c5138b00 + +Sum = -464684d68716498baaa3744d20c112a854e148e6d004e4142c79f4e25a36c0acbff72c047925377f377ad690c63fd21a3f05911d11fb8bb79bec4ea68fef9f1d575 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4652dde4df04ae8897bc244403b1d9545a43a40564f8790850eabfc3a7498b8b64ecd770169c59df1b2f66c8ebd63e92b43076387c05b86441424bb68cad3622076 + +Sum = bb90e9e393538df233d499955020b8f3c9789b1f18fd5ba31cdcca6afe24842166e6cbf1985f7f9e002335be46de06ce11ffbf6dbfe743642cdeefca1a856219fe4 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = bb9d42f1eb41f2ef20ed498c33117f9fcedaf63dadf0f097414d954c4b374f000bdc775d35d6a1fde3d7c5f66c747346872aa48929f17010d234ecda1742f91eae5 + +Sum = -1804d154182f4b71cab3529447ced41ac310a1d14121847816c74171759998b707db0f1f3a9d6f6e01a2de48ec83a45e5dc7d0ac9133c8e00ec41814e3d2818834f4 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -18040bc332b06521fbe1c794d99fc7b002ba7c1f57d24b28d48034c360c86c091d8bb46880c5fd48036795456a2a3d96d675225ada932615446eb843e406a817e9f3 + +Sum = 3b75f0b892eb00075eb21961cc018a2d297764bf560cede3290cab6682a56931b831380b72a9afc3dff88f042ed5bd5d8468d8a1e267b36e508c09ccac2a565936e0 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3b752b27ad6c19b78fe08e625dd27dc269213f0d6cbdb493e6c59eb86dd43c83cde1dd54b8d23d9de1bd4600ac7c5695fd162a502bc710a38636a9fbac5e7ce8ebdf + +Sum = -4b4bf674436c9b1079c2b24cdda19247d0db44061c562ab6f5300eac53556fbe758151824b6bc6bb63a958895fd7c4205cde5484a9fcbbe787fe38c3d36f4549dc23 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4b4cbc0528eb816048943d4c4bd09eb2913169b805a5640637771b5a68269c6c5fd0ac39054338e161e4a18ce2312ae7e43102d6609d5eb252539894d33b1eba2724 + +Sum = dd8af6a278a84889cab2d444efb282a7259a608117db26583287f051bca1b70c21f8c3d95b2f4e0b7d25b6966771a5c41414c386bf4491ef7b055b07455c12b5d8d5 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = dd8bbc335e272ed999845f445de18f11e5f08633012a5fa774cefcffd172e3ba0c481e901506c0317b60ff99e9cb0c8b9b6771d875e534ba455abad84527ec2623d6 + +Sum = -16cac44109b24fd5d47dfb5994caecbbd534ee11178aaea4a100d9e63bb2c5ecdcafce1e2080eafdda00d26c29e01980166d8db67800e33027f5260d154efe1a98973 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -16cab7e7fb5a6170d790e2a99de7fbf5292f8bb5f8f5bb0facdc691b5a65b321fe0ad872b4e373db7a1d1ddbf1ba83139df862d15c96d9037b4fd0100552408393e72 + +Sum = 22db04aa783edd3e1a55d263262805f2892c013f78ebb86239f2e5981090158f57bdf3bb171c2e0c1c7bf9bc88ab62683581f8b02c5bec8f631bb24ade9be235108bb +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 22daf85169e6eed91d68b9b32f45152bdd269ee45a56c4cd45ce74cd2f4302c47918fe0fab7eb6e9bc98452c5085cbfbbd0ccdcb10f1e262b6765c4dce9f249e0bdba + +Sum = -4c8c0b74eb7a79a12ecaecf885b9672ac717b1c8db5ad251f1551ce80af89acf3a495066c85a96e6430be8e5888ab1ef3edd5e76645b5914ab55d221c34d07f8d5ce0 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4c8c17cdf9d268062bb805a87c9c57f1731d1423f9efc5e6e5798db2ec45ad9a18ee461233f80e08a2ef9d75c0b0485bb752895b7fc5634157fb281ed349c58fda7e1 + +Sum = e3718adf0c2546c8cceb0e8c7d909deaa50b50f51d7b80f8040763eafbf581c017e7e12325b258503fe651ffa4c3d3ff9200515d816dfa3ba372dc937480d121ef056 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = e37197381a7d352dc9d8273c74738eb15110b3503c10748cf82bd4b5dd42948af68cd6ce914fcf729fca068fdce96a6c0a757c429cd8046850183290847d8eb8f3b57 + +Sum = -18dd84a4e54a29c1b3106ef2f2d92be21ba64d2e26b3f4c2ea68685557d01a07f9229365c6d109205fa116fee59cf385cdd61b7fa5de8de751f02f1dc0eeb304babb4e +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -18dd83df5464aadb63419d67f36afcd5b0e5f70874caa5899b262148a9bb48db4b38440b101731ae39a2dbb5e21a9a1f064ec8d15427ed448725d9bdefeee72b4a704d + +Sum = 3ce64e7953aff0e057cdd6c17499461666f5bf8dc3a929ba7ba919486c1631c25c0e142584470d3f759157c045f9f488502a76024b6b7b2bf84c0adcce8dd7c6d6898f +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3ce64db3c2ca71fa07ff0536752b1709fc35696811bfda812c66d23bbe016095ae23c4cacd8d35cd4f931c7742779b2188a32353f9b4da892d81b57cfd8e0bed663e8e + +Sum = -6a392e555c2ae89dd73f86e11fd98d1d59ed03072a0dd61add633b317d5638d67984a55e51f01a2db94ad6eb6488fa80cf4f25a32d436886599c33b5287a9525f41a4a +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -6a392f1aed106784270e586c1f47bc29c4ad592cdbf725542ca5823e2b6b0a03276ef4b908a9f19fdf491234680b53e796d678517efa092924668914f97a60ff64654b + +Sum = 8202089b883a5e77457036254c2a73aaf32f03eb1e61fae428926028b499b7d0a4f4e5256094f34bc2478f0595aa01aa79b5d36d7f30136d3af2be93b70552fc6e988e +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 82020961191fdd5d953f07b04b98a2b75def5a10d04b4a1d77d4a73562ae88fd52df3480174ecabde845ca4e992c5b11413d261bd0e6b41005bd13f388051ed5dee38f + +Sum = -13a2e13d675e3fa89489c870cda617ae92ccb7d2f6b6405eafcad9c89a682b63364c333476adf0322febffad973f3dbddb7cbaa41a64b1ea24dcb2bc2196a0af42eac3f +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -13a2e1310e4fe7ba2f8cdb581daf34bdcc20b2709b97ab6b1ad6b557cf86de506b6d8e3ecb4252bb0d8c1bf9070718276f044579354947dff8300d662486a3f1abe613e + +Sum = 2bf9f45c817a8f5c589a208c57c30b52866e75a9b6ee0fb7c3f0c7ec3761f2c114858241a189e331aa9ab440132dc8f5ab7dac0891a69d5573dbe42fda019d30610f07b +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 2bf9f450286c376df39d3373a7cc2861bfc270475bcf7ac42efca37b6c80a5ae49a6dd4bf61e45ba883ad08b82f5a35f3f0536ddac8b334b472f3ed9dcf1a072ca0a57a + +Sum = -40557025ab86f90705fc86e3ab3d8494255bee490822e27c5551037f36f9ca834fd33c11a1a162357cb21eb83254c4da56b9f8f54aca29b95283ac03732a849258e7c41 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -40557032049550f56af973fc5b346784ec07f3ab6341776fea4527f001db17961ab1e1074d0cffac9f12026cc28cea70c3326e202fe593c37f305159703a814fefec742 + +Sum = d2985750cb9579d3f5dc3db7d2229f06e2a0d57d195819b3646f84c08eafc093def93748aaedf1f430eedb90c1694d894339caa4141ef5f07708e1a3607c5793df599b5 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = d298575d24a3d1c25ad92ad0821981f7a94cdadf7476aea6f963a93159910da6a9d7dc3e56598f6b534ebf4551a1731fafb23fcef93a5ffaa3b586f95d8c5451765e4b6 + +Sum = -13a024fb88eba47aea55fb69680479058efda97b81fb1e6e7cfe520e8dd8ad12deffb69662852f9a94f3b029a37befc620d792a8589660e2ebc7d6e1bc8c0c8f35ac1216 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -13a024fac35abefc04062c97dd050ad68292e9255c49351f43af0fc7812a9841b251cc4707ce75c322cdb1ee5a786d6cba100b55aa44aa4248fd0c8c5cbb0cc35c3bc715 + +Sum = 22701a8dfb82a2ddc8a5485b05362205a549bcdd24bbd660f2041a6672732824bbcac4ff58605ccf1d8ee066204a4a639828c41b722fb4a1e6c9bc3f82a89d85fd042f85 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 22701a8d35f1bd5ee25579897a36b3d698defc86ff09ed11b8b4d81f65c513538f1cdaaffda9a2f7ab68e22ad746c80a31613cc8c3ddfe0143fef1ea22d79dba2393e484 + +Sum = -4f73fdc6540686b350c859bdbe8f22340786ddb04b7ddb8858d33ce8931bcf660269129607f77dbc1db38d8186d8bae7ebb4ec8716c6eb26342ec8290d8d8988b1f5fb0d +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4f73fdc719976c323718288f498e906313f19e06712fc4d792227f2f9fc9e4372f16fce562ae37938fd98bbccfdc3d41527c73d9c518a1c6d6f9927e6d5e89548b66460e + +Sum = dcbcb3df6508052fd0d1cfb0a6088fe978227066c58317cc359f508bce9f45987ce3152022e19ef068b0381ce7d781ae3e7c04243541744c9f374a3f28dbd746acd3b9fa +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = dcbcb3e02a98eaaeb7219e823107fe18848d30bceb35011b6eee92d2db4d5a69a990ff6f7d9858c7dad6365830db0407a5438b76e3932aed4202149488acd712864404fb + +Sum = -163f4ba6595207387ef0956796ac29e3c6862b5344abdce3db4ff7e960b7727fa0a2870dbbe17bd8c446000b3074c1145368d4b84b39029110f915b61916fc29555d7d800 +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -163f4ba64cf8f8e0908b987a7dfc3300d5bf7f4de250be4ee7bb03c4efec91328dd7a868c636103b4d23a0277be488eebcfc5c432053e72706cc6910c319ec2c97c678cff + +Sum = 3588d982604f471ff0ff784942bd43d85cad820864e0b9ee80cc9a9e3807d2739eb58d447830f73fc8cadc88d864f98577e43adf5150b2eb104e75939caa7de02419b6575 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 3588d98253f638c8029a7b5c2a0d4cf56be6d60302859b598d37a679c73cf1268beaae9f82858ba251a87ca523d4c15fe177c26a266b97810621c8ee46ad6de36682b1a74 + +Sum = -4d51ba5f184e5d20b30f8e41d663d14dbe4f692f1a0749789c02290af4c889268c319fad8b9b7c9cc71e8d9878039931447fd6ede967c5c82c1915631f3237aaacf4a1763 +A = c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -4d51ba5f24a76b78a1748b2eef13c830af1615347c62680d8f971d2f65936a739efc7e528146e83a3e40ed7c2c93d156daec4f63144ce1323645c208752f47a76a8ba6264 + +Sum = 9d7a5610dcfc50699e6bc065584fed73fddbd58dfbefe377eaacc024e33e6b4fd361fac0844489fdf13efd8dca7fae0747603f4b26bb2a9bab9de5241a3af4a935ac940aa +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = 9d7a5610e9555ec18cd0bd5270ffe456eea281935e4b020cde41b44954094c9ce62cd96579eff59b68615d717f0fe62cddccb7c051a04605b5ca91c9703804a5f34398bab + +Sum = -1258b397182002c966f064c2cdadb06910e2042d0f51b4af494338c12b6efff052fe564a00e581c5aac0ea79fd8a1ff68ed92b7f74baabb03a51337d4b9b01a2f64ac803cd +A = -c590e57ee64fced18aff6e2f0c6ac05625b1e94f394f42470cae14d12cadea4f5ab6b9d77225fe3b4903825966c78752ae51b6a0a2caca555fd0ffcbd9704b01 +B = -1258b397175a71e3e80a14f3fc22b0fae1d5996cb92c02c5fa09e97ee46251db81d1a85fb18acb0bd34ec47bc2411c74357263f8220c59f999ae68b2f63b30a32a7157b8cc + +Sum = a1eea50170df6807aef40929a52c097081e1755b575a49548ee5868281973a141920234cd0176d64f84a5874dc417cdc8a5c338cb54bca390538e1014d638b51 +A = a1eea50170df6807aef40929a52c097081e1755b575a49548ee5868281973a141920234cd0176d64f84a5874dc417cdc8a5c338cb54bca390538e1014d638b50 +B = 1 + +Sum = c7c26d68246f16d9d9996fe67616d2fd48809916e8121a5ef95b17bb9b8333d84e2416bf2a5eb3b686c936b9722e0a92a376f357aea7719610e864d9e2a5a677 +A = c7c26d68246f16d9d9996fe67616d2fd48809916e8121a5ef95b17bb9b8333d84e2416bf2a5eb3b686c936b9722e0a92a376f357aea7719610e864d9e2a5a676 +B = 1 + +Sum = 80d5de21acc1eb10fff4e534d23b5cd39e1eebc3d7f03aea438bb6e5237ced9955bf86898e93c74565c9a197e3ed2ff8edd3acc41ecef97c4fcfd52e1cdbb07e +A = 80d5de21acc1eb10fff4e534d23b5cd39e1eebc3d7f03aea438bb6e5237ced9955bf86898e93c74565c9a197e3ed2ff8edd3acc41ecef97c4fcfd52e1cdbb07c +B = 2 + +Sum = e020b9bd8d194468f8b563c8f586f6959533be8507bd4d3d7e494ef3733007c062caaa65da5c51b52f18cec4894966352f948517ee92d5f9b5ed00f020b1d1dd +A = e020b9bd8d194468f8b563c8f586f6959533be8507bd4d3d7e494ef3733007c062caaa65da5c51b52f18cec4894966352f948517ee92d5f9b5ed00f020b1d1d8 +B = 5 + +Sum = dad6af803cf2f40e75cbb564e8229c0d25465930d2ceea73715682c26d582148a943c1c767ac5167c0425975ff75a66eec5ad418ded078569dea2f77359c1cf8 +A = dad6af803cf2f40e75cbb564e8229c0d25465930d2ceea73715682c26d582148a943c1c767ac5167c0425975ff75a66eec5ad418ded078569dea2f77359c1cfc +B = -4 + +Sum = de90e3172430754f80e116cc8c848bee88c8e31810c6ef0ded5b05bbef6d5b81f9bf6593622ebfcb2b41be2e87d62ab7fd566763b74428275a16d1da482e5f76 +A = de90e3172430754f80e116cc8c848bee88c8e31810c6ef0ded5b05bbef6d5b81f9bf6593622ebfcb2b41be2e87d62ab7fd566763b74428275a16d1da482e5f7b +B = -5 + +Sum = c153ce69e35411c7f1e52809773ce03ce8d2af10b5c7aa3f4c9354de5ca044b7ef25089f1e96bd14d6c62c88b3c39951df19c73751ba25dc758534adba7faddc +A = c153ce69e35411c7f1e52809773ce03ce8d2af10b5c7aa3f4c9354de5ca044b7ef25089f1e96bd14d6c62c88b3c39951df19c73751ba25dc758534adba7fade2 +B = -6 + +Sum = f0c843f86e227571d67cfc34ac00d0e6f87f4cbd3273af68562657ae5ca82ddf5fd63476d56d5cccf62dd93f8320c0ba88658493dde282abc22bd09a01f6f2be +A = f0c843f86e227571d67cfc34ac00d0e6f87f4cbd3273af68562657ae5ca82ddf5fd63476d56d5cccf62dd93f8320c0ba88658493dde282abc22bd09a01f6f2c5 +B = -7 + +Sum = c5ba28844b8947aa0c2933f06aa88f0b34e0e10ca9baf1cc3bd5ff2dc0590e3ac5a2f2d3a1408009e1b35e08426bdda001adf93e872b03f4f6df28d34a3355e5 +A = c5ba28844b8947aa0c2933f06aa88f0b34e0e10ca9baf1cc3bd5ff2dc0590e3ac5a2f2d3a1408009e1b35e08426bdda001adf93e872b03f4f6df28d34a3355ed +B = -8 + +Sum = 84da246c2485e335d1f3b7e31c2408365f2afe7bff7b596440281c1618bbc8bf7a3896ece480fac4a29070539a95f1d718c151ffbfafbb82629bef9d2afbaaf7 +A = 84da246c2485e335d1f3b7e31c2408365f2afe7bff7b596440281c1618bbc8bf7a3896ece480fac4a29070539a95f1d718c151ffbfafbb82629bef9d2afba900 +B = 1f7 + +Sum = 9673d93165b5be256689ba4e750243537f85bc28daac7f65338074081f114b3a83871683c89fae3c87d44da053557aa16dd074b1bdc16c02a74c5b495f875449 +A = 9673d93165b5be256689ba4e750243537f85bc28daac7f65338074081f114b3a83871683c89fae3c87d44da053557aa16dd074b1bdc16c02a74c5b495f875453 +B = -a + +Sum = fce022b2dd492a96f8b095712803f318a45a9a8f00a48dec06accaf793e54e59daa14c56c2fce011e30e6394937f7bd6fa6afa1b6dc3b5359ec7bb4f757c5d89 +A = fce022b2dd492a96f8b095712803f318a45a9a8f00a48dec06accaf793e54e59daa14c56c2fce011e30e6394937f7bd6fa6afa1b6dc3b5359ec7bb4f757c5594 +B = 7f5 + +Sum = f04028fafffb1aee499812d12f9fcbb23e6a872b3f69fe7a7a246d8f98ba2aa954f78506b39c023397855ead87854412c881fdd16267c07ee12f085b055c7c71 +A = f04028fafffb1aee499812d12f9fcbb23e6a872b3f69fe7a7a246d8f98ba2aa954f78506b39c023397855ead87854412c881fdd16267c07ee12f085b055c6c7d +B = ff4 + +Sum = 9c008016815a6580728b3f690eddc7695fed44171557df8a4a6e8c0d5e7c3296832b4ba9ee4a4cd7e6a8ef23cf8c64fcd0518664289c4e72105b404cd6c0ab6d +A = 9c008016815a6580728b3f690eddc7695fed44171557df8a4a6e8c0d5e7c3296832b4ba9ee4a4cd7e6a8ef23cf8c64fcd0518664289c4e72105b404cd6c0ab7a +B = -d + +Sum = c12bf7e503d2c5845c60886ad5ef87d24e002498003b44922e462f36592a52c878123a6d1037896ce9fb7d2c680d008e80009da72c8e1415e957b2fefb52c34b +A = c12bf7e503d2c5845c60886ad5ef87d24e002498003b44922e462f36592a52c878123a6d1037896ce9fb7d2c680d008e80009da72c8e1415e957b2fefb52c359 +B = -e + +Sum = febba964e2548ed1474dac7c1eb9b1cd169ac913530b7fb358d67197517266707e5a176a814ec82cf8945214b30c36ca7ac0b1ade1848573e72d408dbede8f53 +A = febba964e2548ed1474dac7c1eb9b1cd169ac913530b7fb358d67197517266707e5a176a814ec82cf8945214b30c36ca7ac0b1ade1848573e72d408dbede8f62 +B = -f + +Sum = 8a3f9eeb76e96f13446c593fe2cabd4215e0debc54025df7791d924d8afc08dc8f607b82a3d07d75897bfeee0c42b9a32e0e77a098c1cce9c001aabe0481996d +A = 8a3f9eeb76e96f13446c593fe2cabd4215e0debc54025df7791d924d8afc08dc8f607b82a3d07d75897bfeee0c42b9a32e0e77a098c1cce9c001aabe0481997d +B = -10 + +Sum = be825a00c3c6b192d04863b0719ee1e687dbbf2cfc0c331c00b8b947c17fecb7700c9e534bbc49bd61978754ffae1e57d80aab34f5fd23a267e10a4b5a13a9d8 +A = be825a00c3c6b192d04863b0719ee1e687dbbf2cfc0c331c00b8b947c17fecb7700c9e534bbc49bd61978754ffae1e57d80aab34f5fd23a267e10a4b5a11a9e9 +B = 1ffef + +Sum = d1c861822ba0e93be81fc78a2628756480146225c79b4a389588a9c3bff9a7500660e99c28807d9ae7bf8c1e89e81d4f9ff2f72d35ea6b34d09df053d46dd294 +A = d1c861822ba0e93be81fc78a2628756480146225c79b4a389588a9c3bff9a7500660e99c28807d9ae7bf8c1e89e81d4f9ff2f72d35ea6b34d09df053d469d2a6 +B = 3ffee + +Sum = 98ac65b4c06400baeb40ed137ecdd930a3607423caecbe1f1a936a8210c28fd84b53324e5bb73b7e4b71209b1a4d106796d57a4a23fad2c23abc0c039539080d +A = 98ac65b4c06400baeb40ed137ecdd930a3607423caecbe1f1a936a8210c28fd84b53324e5bb73b7e4b71209b1a4d106796d57a4a23fad2c23abc0c0395390820 +B = -13 + +Sum = da02949862a4b26a4fb4bff43b21c2cdd048189199612616303d3ab34dc6f201be256f5889e368867a0da200a0b03e904048d6ba5caee1dafa16f4fdb1f00029 +A = da02949862a4b26a4fb4bff43b21c2cdd048189199612616303d3ab34dc6f201be256f5889e368867a0da200a0b03e904048d6ba5caee1dafa16f4fdb1e0003d +B = fffec + +Sum = ea9523fdde49d481c9f449969fd8e191e118058e0593f2a27ef0ade666ff478c50acb274a6c77d9ec4ca628ab0d7f3dc18708327423de28616235187acb197f8 +A = ea9523fdde49d481c9f449969fd8e191e118058e0593f2a27ef0ade666ff478c50acb274a6c77d9ec4ca628ab0d7f3dc18708327423de28616235187acb1980d +B = -15 + +Sum = dab5613ae3756d29f22bc30213363900e3fdced153a3c20852d51c71cbb9af41aba6a16d0b72926192ef48f25e8975881ca7973a69590dc6f0224395e6f3684d +A = dab5613ae3756d29f22bc30213363900e3fdced153a3c20852d51c71cbb9af41aba6a16d0b72926192ef48f25e8975881ca7973a69590dc6f0224395e6f36863 +B = -16 + +Sum = c442f3e574310f78e0ac187af96550d4999b79da9c9d6ffa9eb9437a2ac01479003d8e795ce68dfc0f87a4fd9b00b6c172c72c7f580a32af015a3a3375b85285 +A = c442f3e574310f78e0ac187af96550d4999b79da9c9d6ffa9eb9437a2ac01479003d8e795ce68dfc0f87a4fd9b00b6c172c72c7f580a32af015a3a3375b8529c +B = -17 + +Sum = b9ac1e23fbfe179d9d3ff99b2ad8399754ea5531e6fce5dad997e2c961110d49d0e3d9c2ec03289edeb39e5a6b4744dd4b3cdd6c43f4e8f4c8e91617772e7fd0 +A = b9ac1e23fbfe179d9d3ff99b2ad8399754ea5531e6fce5dad997e2c961110d49d0e3d9c2ec03289edeb39e5a6b4744dd4b3cdd6c43f4e8f4c8e91617762e7fe8 +B = ffffe8 + +Sum = e087174c20cba6c4e1e8ffc2ecfeeee770898916454724c24b56d8619c27db123078d406d6b7b836b0dd3092b34b736c472f1afd983971230f1e2b729b00acd4 +A = e087174c20cba6c4e1e8ffc2ecfeeee770898916454724c24b56d8619c27db123078d406d6b7b836b0dd3092b34b736c472f1afd983971230f1e2b729900aced +B = 1ffffe7 + +Sum = ba66837e8e8bdefa4c3df73ba5ee65d1ab45a68f51072bf2997446b13b6c73b29c26d15ddff186c9621e156bd3b650caa267dffa54abb782734c443bf502b276 +A = ba66837e8e8bdefa4c3df73ba5ee65d1ab45a68f51072bf2997446b13b6c73b29c26d15ddff186c9621e156bd3b650caa267dffa54abb782734c443bf102b290 +B = 3ffffe6 + +Sum = fc461dea452aaf0e2c1df10b7cb4293fbc498d40caa7a917a741c6d3534914fc039bb7a62d14cc3e9ea6cc8d2b41228628ad56687d18858c3867c75ae83a3216 +A = fc461dea452aaf0e2c1df10b7cb4293fbc498d40caa7a917a741c6d3534914fc039bb7a62d14cc3e9ea6cc8d2b41228628ad56687d18858c3867c75ae03a3231 +B = 7ffffe5 + +Sum = d109e7982ffd500ed77702054ccbfa49bb47b5cdb2220988ef58af3cbe0ac90bb3b2ac8a2c558fe744231bf227bf35343e12ecb312242ce50a85fe461e73b601 +A = d109e7982ffd500ed77702054ccbfa49bb47b5cdb2220988ef58af3cbe0ac90bb3b2ac8a2c558fe744231bf227bf35343e12ecb312242ce50a85fe461e73b61d +B = -1c + +Sum = babcba83c01843f6448fc3f91c006a673e514c9626c6399d43c016c31a8fd1a9fc58d1c63ba5b9565dd7320c4a04fe4331fbb79de1e03d68db331bbe2b4b9036 +A = babcba83c01843f6448fc3f91c006a673e514c9626c6399d43c016c31a8fd1a9fc58d1c63ba5b9565dd7320c4a04fe4331fbb79de1e03d68db331bbe0b4b9053 +B = 1fffffe3 + +Sum = c52e7fb27c4f670109b32cb6d3f705e1685e2cb7474a90d3815e486de77dd2584a0b65d22040059ae5279450682a189eb1b0f847e0d3fe022628a73eeb99c54c +A = c52e7fb27c4f670109b32cb6d3f705e1685e2cb7474a90d3815e486de77dd2584a0b65d22040059ae5279450682a189eb1b0f847e0d3fe022628a73eab99c56a +B = 3fffffe2 + +Sum = b5f074f655dbe68df022b0093534b609b23c17eefcfdc9b1b150c8cfdafe1d320fff7452c147c7d9f9cbe16be25970a23e6499bc90e689497c8bf2d38219e4f4 +A = b5f074f655dbe68df022b0093534b609b23c17eefcfdc9b1b150c8cfdafe1d320fff7452c147c7d9f9cbe16be25970a23e6499bc90e689497c8bf2d38219e513 +B = -1f + +Sum = a1a41b6638409305ab9ffa22bb3cb9434f587d4ce6f6da47c0ad6f8f720f397c37cd61254f35fc9f0cda36476ca6d95f233604b9ae5ea2f1a1207caf15682e81 +A = a1a41b6638409305ab9ffa22bb3cb9434f587d4ce6f6da47c0ad6f8f720f397c37cd61254f35fc9f0cda36476ca6d95f233604b9ae5ea2f1a1207cae15682ea1 +B = ffffffe0 + +Sum = f187feee94925d57f65f9b1200193d8e9359340d670bab27c022d6d63a54635e4573593790e6c6b779becb9e5ea81c9b075baa2d3bc95493b0c5a2da1fccebbd +A = f187feee94925d57f65f9b1200193d8e9359340d670bab27c022d6d63a54635e4573593790e6c6b779becb9e5ea81c9b075baa2d3bc95493b0c5a2d81fccebde +B = 1ffffffdf + +Sum = dc9c51e1313cb655969b4a069f2e8edd850d4fbc5bbc36f05df42a526f4e5b3ed18886263d86231193442b3ac3e7a71e5a6377021e71ad07dd9411953dbeedc5 +A = dc9c51e1313cb655969b4a069f2e8edd850d4fbc5bbc36f05df42a526f4e5b3ed18886263d86231193442b3ac3e7a71e5a6377021e71ad07dd9411913dbeede7 +B = 3ffffffde + +Sum = f2b5e665a6a2e7009bff8b2750b5fb11576bfd49dee5dd7f32b02c46430923b0ec95c3fcee0006b0c2591cbf1fb18dde331d8fb119d92f3196a7dfd8178be33e +A = f2b5e665a6a2e7009bff8b2750b5fb11576bfd49dee5dd7f32b02c46430923b0ec95c3fcee0006b0c2591cbf1fb18dde331d8fb119d92f3196a7dfd0178be361 +B = 7ffffffdd + +Sum = fb0f545b752979151bc6004b3db33bad63230c26d060ba00f5b82e7bee7e2c854b09b2a7c6b4186776c6b3cc45afbc50ef35df7abad11fec62523a12be1cb7a1 +A = fb0f545b752979151bc6004b3db33bad63230c26d060ba00f5b82e7bee7e2c854b09b2a7c6b4186776c6b3cc45afbc50ef35df7abad11fec62523a02be1cb7c5 +B = fffffffdc + +Sum = fc197e83249b069fb34552188cd6d06a7e0b42c6a6a9869ede485328a0fabd0c0ec2f79b81747129ccd70ee5c0f9efea62c36d1a4e1fb2b80393fe636469c25a +A = fc197e83249b069fb34552188cd6d06a7e0b42c6a6a9869ede485328a0fabd0c0ec2f79b81747129ccd70ee5c0f9efea62c36d1a4e1fb2b80393fe636469c27f +B = -25 + +Sum = aaf9a8ecbbfee9c3092d9887ec35118a9614a9fa84fc50b79b11d03a4967066c361f67cbf7a8e5beb620c7da55f4bc7dc50ad44b22c9128994781c7816a439af +A = aaf9a8ecbbfee9c3092d9887ec35118a9614a9fa84fc50b79b11d03a4967066c361f67cbf7a8e5beb620c7da55f4bc7dc50ad44b22c9128994781c7816a439d5 +B = -26 + +Sum = e74e32fc45d099ed147bcf7d798bd3aef9b046291038d98431698e90d22cf944a92bdcd8a5cf378e9a3aa0001150cf6e4dc37fa4e54a25e13c75099c64b9350f +A = e74e32fc45d099ed147bcf7d798bd3aef9b046291038d98431698e90d22cf944a92bdcd8a5cf378e9a3aa0001150cf6e4dc37fa4e54a25e13c75099c64b93536 +B = -27 + +Sum = a3486d022ef4d0a0c72170f05300cee78df844db19c63754c2d631d3d9ae20a0205cfe0fe947f8f4d2f9fa34e2081f448a938a446e8764ac2141157cab01dfa0 +A = a3486d022ef4d0a0c72170f05300cee78df844db19c63754c2d631d3d9ae20a0205cfe0fe947f8f4d2f9fa34e2081f448a938a446e8764ac2141147cab01dfc8 +B = ffffffffd8 + +Sum = 8952cb3f70b1344facdd7fe79747773f9c101bc2a083fa8fdef0679c24ba93218d14d4d7e848d293ce431119d1542833e9a0624b812f0b31b2b9f7ed9455e8b9 +A = 8952cb3f70b1344facdd7fe79747773f9c101bc2a083fa8fdef0679c24ba93218d14d4d7e848d293ce431119d1542833e9a0624b812f0b31b2b9f5ed9455e8e2 +B = 1ffffffffd7 + +Sum = de9cb4d4cdd1d58572fa1052edf72bb9241555bdb967bd8cefb26cb12c6622d6147385dc3f72e110b17afbdebc5feb959cb6c320a2ba01f36585b53fb1c5f07f +A = de9cb4d4cdd1d58572fa1052edf72bb9241555bdb967bd8cefb26cb12c6622d6147385dc3f72e110b17afbdebc5feb959cb6c320a2ba01f36585b13fb1c5f0a9 +B = 3ffffffffd6 + +Sum = d37f2e1638c0b3bd624104d244d9770ae05bf37f7a6ec32db552af413c0006fdcfc312cf281190eb6738370f3a8c4655beddb6b39b342f0a67cc9af92a2c7fdc +A = d37f2e1638c0b3bd624104d244d9770ae05bf37f7a6ec32db552af413c0006fdcfc312cf281190eb6738370f3a8c4655beddb6b39b342f0a67cc92f92a2c8007 +B = 7ffffffffd5 + +Sum = 831aca9ef43bea89f048250aab79b06207458647ce347c68f91013695299c80d610c6e49e2dcd46eb02dd56573d31720efc277469e573f6ecfb71b12886653ac +A = 831aca9ef43bea89f048250aab79b06207458647ce347c68f91013695299c80d610c6e49e2dcd46eb02dd56573d31720efc277469e573f6ecfb70b12886653d8 +B = fffffffffd4 + +Sum = da95fd2d2438a79843bdf92c1cadd0e9165d002d22dcacbe4118cc3cf7d5de2fd2106aaefc790aa1559b28b641f83e4e5aa0f8446b57fde5c3663c13efbc04fb +A = da95fd2d2438a79843bdf92c1cadd0e9165d002d22dcacbe4118cc3cf7d5de2fd2106aaefc790aa1559b28b641f83e4e5aa0f8446b57fde5c3661c13efbc0528 +B = 1fffffffffd3 + +Sum = bf9e3169dd4b6d336848e744231d1ca85678aa3d1d62d42eac0b16500ef527e028757da54a456b3d684199f3bb3c866a002ee3885c86d2a79180487f4e8a45f1 +A = bf9e3169dd4b6d336848e744231d1ca85678aa3d1d62d42eac0b16500ef527e028757da54a456b3d684199f3bb3c866a002ee3885c86d2a79180087f4e8a461f +B = 3fffffffffd2 + +Sum = b5880868d947554eeb536246c312c9765ca8c96888817f3ffdc16cdbafb41fe8f7c151cb316da27562d3b82b2d45abf7c9304f488538386e84c6a23e3dc375fa +A = b5880868d947554eeb536246c312c9765ca8c96888817f3ffdc16cdbafb41fe8f7c151cb316da27562d3b82b2d45abf7c9304f488538386e84c6223e3dc37629 +B = 7fffffffffd1 + +Sum = 84b1e4079d09df569a1623b990d917871b1197723b30b19fcf3c063b0e84c9cef1c3ffed16f33aa9bede08b4831bb3ecdadae1622c93e1f86b474a4989496fa4 +A = 84b1e4079d09df569a1623b990d917871b1197723b30b19fcf3c063b0e84c9cef1c3ffed16f33aa9bede08b4831bb3ecdadae1622c93e1f86b464a4989496fd4 +B = ffffffffffd0 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30c6365e1eeb044 +B = 1ffffffffffcf + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 80695b879bb74400c107619981f3bcb3c9987c76d545f6485ed128082377799534508a83112fbde2ee5558c246332c656455 +B = f6446ca2883d7e27209eeaa01fdec632d4027113b81bb47dacc8f10eadc3b3ffc26d84135d91e70deb8aec84c7820332e8cf786e2af9b4217a4c1d32b5894bbe + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1b510bc480138145e2a142fce8330ee5f4030dccaf6017a1dd85bc5bbe9b2fee4f9d8fb484661a839dc9613652bcca11a00eb +B = f6446ca2883d7e27209eeaa01fe0fbacebd20e03107a9f993e30f63358d6bdc91baf4f5acdf81e3ad94ef9af3ffc315c6e9acfff91167f0ce6738f328308b0fe + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 219f59352ebda4cfb785a18834ec1c99145a6647265baf5d8f3b405f29a746785a5e70777d528ff1526688c01b9eee288e6cd +B = -f6446ca2883d7e27209eeaa01fe16091c2dcf8a54917eddf26e5c1c43408c33ea356bf1449b339931985aa70a89cdd6a7aca5ec6e7f1c8df5f101d54c47796e0 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -7e5a2ec59519143f7bda2829cfee4ae75cc8038f31303ff9bbb1e2cbfe93c46a1367c9d6a2a3d9cb40f1a6930c18c78f85724 +B = -f6446ca2883d7e27209eeaa01fd760f94330bb39b824b7e28bc5741dbc01b11805f14655543e8ac0e6d326bffa760106d5e85f604c28935c69dda1d968f658ef + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 9f580ff614b449cf9c46c91256c20983f5c70200739de72b917344db81c1aa1bf3927c38c22d026d6ce38ac746ada2948e538 +B = f6446ca2883d7e27209eeaa01fd5511b3028c1865f22b1187d3d06e1d23821281edd1f7ae1212eaac5daf3e19f57fe5bafc666cdc205d43e2699f88bb8a5cadb + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -15773d29ba363a15a0cb31ac4a60c0c228967e857d7d11c1ebb0a8db855c0d0797c0e409899a50e1b1c989a7dcea6f26238d27 +B = f6446ca2883d7e27209eeaa01ff4bdd95944430511bd40b6baacd3c32ca01416c461d66b15c5f687ef186c0948aef8677cdc23eeca8e6c007aeb4dd508123d3a + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2f90f72f59dd7738f5572e31d41b91599ed500d59537bf5c21a1bedad709303cba0d5bf1b5e4eaac1a85c261ce94c45b64646e +B = -f6446ca2883d7e27209eeaa0200ed7935ee3ea423511ccb340368e93c416529914799118affbe79dee6a192c7dd144df65086e8894f7283934dcf82a3d531481 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -73978eee2b2a4ac8ef12b3042dd5e1ae8724a0a676d0a52035e801d741a61b92c638a3b0cece6a81bfd2703e3c502ad1fa784c +B = -f6446ca2883d7e27209eeaa01f6baf0d415ee280332d62d20a349d20bbf058f7986d88b433a45ddd3c5169e0ae50fedfc283bb33671cd00694d2133b0ff437c7 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = a462699ec5214f0d7860974a669d1728b4983a1c3c440213d12b2da58bba9dd1caf1d5ed391a3ebd80aa6e9ef0396e62260a1f +B = f6446ca2883d7e27209eeaa01f3ae43290c4eb7beea414edc3fbd5eb41c2e55e22a8155740091ab16e07555e6f4c45ad86196f5f2b5bf808341e29f77fc8a5f4 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -130f7a12825a6c5b6b109b91e2506505a261c9f7c1a62fdfbe252275d3f6844dda2aca2d0ff6d8406ac5c679c80ab6d29817b4d +B = f6446ca2883d7e27209eeaa021103e3d57afb390b2cd7f3e2c877952c49d9a37bafebc574fbc980670d278411eb9e4264451f721ef88fede6f8f0ed30b702b60 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2863fa82289aff06fb16bd1b866da9ac0ae0f411a8d8c2c084cf78b81d6713a9a4700248ef61d5e52ca7470f1f251380368df10 +B = -f6446ca2883d7e27209eeaa0226586445213bcbb6bcde156c6c94d9d2b258cd95971e5855c273d6a95698136db5e37a80248a6fc3ba716e7c500b49de5578f23 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -6176f648b54dc4e2d11ba7e32d2d9d3f400fbafa489fbe7f126daf1f929ef8f219c78ff1063dd27650d4751c63b6e7ad7d9a588 +B = -f6446ca2883d7e27209eeaa019c7d737a435307ccf0abb06db8f992e767681e89a5a5d7162b36aed1a69206d1f7abe8462eeac7683cf5b250cd2f4eb0a150a8b + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = ccff1ed8726e309c4e0f2e166c497cd718a8eac347674ca57b6f317ea491b743a89d25f87c37f379f6239b13d848eee1ffa9328 +B = f6446ca2883d7e27209eeaa0130f54aea86329c1373b82a3a79ddb34f8eceeec0a6de48efc2352c72949f488068d6523eb8f0a66497a68c59589d477c1f41ceb + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -13d1c041415fbc18179c970fe989ad9e1f10e4ff658c1bc550e93f6ab9f9cc9832fd49cf6f2e75af72a71dbd7b121111ee0d4098 +B = f6446ca2883d7e27209eeaa033b106dd70e9c8e313b90c94f7ec20a089886297a470751ea4c38549cd8cdc9474148152e280ff4d5b83c0344e207477cffbf0ab + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 27ede3a23479dcc5447bc3b64df32c121761de88086204484cea0782b8d63d72b57192f2b20dd3dff395e937c91e21cdbd13b68b +B = -f6446ca2883d7e27209eeaa047cd2a3e6403e9904098393b5c559f1481d95c2047465da1a0c44d61cc694d6ef688ca7625605d7ddc728bae9c2c85339f02669e + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -4ad10e7f5637cc48b04d4b250e4ca00a0d102c91caaaf6291f1248b7a1cec979f87b7251c50db8e5e49206bebb30b7f3f25c8577 +B = -f6446ca2883d7e27209eea9fd50e381cd95240824bcf2a600015d2f85d6751067439633034c7fd2771c44682489bc531ae44d0b8044a9bb817ddab71ef922a9c + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = c6b77c2c932d9d5ec6175def706d6e9c411216fe12ac52043c617761d3a37804487f158de60a9c18e7a19646c455804a65bd80f2 +B = f6446ca2883d7e27209eea9f5927ca6f9c5c6f6c360517959df504662965669a2c3807551778ce7d3fef97f7f89821f58d47ed85013b0c300eb8e31b7c312f21 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -187976849837d4ad4cfc9764fd0e3f865fa9d1d9f20d98ccd52a6b3652277100bcfff85fb8414c2967dacd26f269502d3c2caff12 +B = f6446ca2883d7e27209eeaa1a776aee5b307579fcbe5ebd4df466b6865149b375fbde626a680f944360a20081116bd7ef7674c34668974e5f9a36639a4b9af25 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 33913efb99088ab80c706ee229e7a6ea6b274097f6ed3734452dabe0865eb86fcf20c9c6ae0e613b72dbfb8b126383e7d10e8bbb4 +B = -f6446ca2883d7e27209eeaa358f33655c012b84bc32363a7acdce1a91ceb8717adb7cc9da6b503e7797e96f93323d3ee54389d55169c5b27f946a1e2f2d76bc7 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -5d84033a924ff84666d3ee1a1342ac118224264c439bc658213b9762586e8dbdef141024d757175f30bec23a960ab145832dee9af +B = -f6446ca2883d7e27209eea9a479f12f30a8a88648edd93e3da37b1ea483518d40527f3d74020cfb98caa341d4fd63535fde113aadcf07ecd72634f0daf0fc664 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = a2aeba6a0d6142f527358ffd4c9139c390c9dfab07947c902085d1f3c367035db0f22f249295b974b1d9ebe7add3dfac7ec237f72 +B = f6446ca2883d7e27209eea95f4f39ffb5975dd7888c375b0454ed6c95dd982e7c59c90574b7d26a2dd22da2131f4453a49f6f252cb3de3fbf5d0689df5cb30a1 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1e545f433c1bda45a7900793d2cd18ba630fcb11d4a2c88bc7a0fb392d270088a1ad126743b80342bcfcfa9e939c9ccdccb7f4f198 +B = f6446ca2883d7e27209eeabe743e89d84b6452728c240957db7b2d657a428f6ce1ace520f4d57f0c3a93989dee299ec72b55cc5ae5d7410a6fab313299e3a1ab + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 244bf1eb701c53bc7847a644269277f53b58dc23b55a2f996faaceff22666eece40fe14644aaa2ab0197a5a915fefa394a5c357db4 +B = -f6446ca2883d7e27209eeac46bd1320c4bddc94343c2b9aba0da683dc353a14d9913f2c8fea945017a01fce050f87dc81df5349f80824b8cd2089cb03e242dc7 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -7e3419b44f3596c6486e095c3fc9a84b5599868abd292354278a2520f54929d5bc325dc3d095e84431960265dcae84f0815ef5beb9 +B = -f6446ca2883d7e27209eea21ebc5924cf9f346828e13194544ba27acd0f0f2db15c10531c9b524e9ca693a400eb973b2dd6a456c52da3c9a248972e482f8f15a + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 81fae0f8555d46ede9e74a93b8a7c6273c9bee0eef0f51b4575aad5cbdc0e10a3d03d53cf2a42e6a3625074c812cd0ae41d94d34ee +B = f6446ca2883d7e27209eea1e24fe4e46d2431ee114d1e1cc669c4bc5ce896ea92f92a501f92ce92152b205bf3d41fa90cf241f67c3d555f5a63db52408a17b25 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1558c919b3dcd4cc2eacfee2ae98a3b4286bdb6aa67db97ce35df3ac72f6c6418df10444ce791109a9a71250896f20d4dbf19d559f0 +B = f6446ca2883d7e27209eebf5ac70e1d9fcd6cfb5cc0aa06e989db589282e28001a7c278f33150d0e7ff728db515b846b046324385a01ab0dc51bb124fbc40a03 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 3a9c8b150408b2449466b8328ccb0a5334f2340479203cb790780e71b6609f7999c691ba19f947d8cac4329a4e45377fd6bf226fed2 +B = -f6446ca2883d7e27209eee49e89096dcbaae5611679f9e51bf07a6518db7c52a42afd260d4c161451d8aa998aa32d92307d0164a2c06475b268660d1d415aee5 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -450c41a9cca23287b6448a0b248d24075ed20bec41c600279fd86869b1a51e1842cb7f4d59144436edc1c052f44428965b3b2d98757 +B = -f6446ca2883d7e27209ee64f5bc4a9d20c619166b37bc33c3c21fd1549b8b97bdee1df5bcd53aac4c1b18bcf892261f22f0f1ac1ccd773329084fdb22f1528bc + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 9d48745690ee5aa8fc448371f9236153c584466583aa30d999461a3defac314356230a763c204c2595794db93fcd3917f25b83d1b85 +B = f6446ca2883d7e27209ee0cb9899dd8d49df7d06b3e555f2d84d36aa2611255d9bd6bfc4f23666e4507eda9a106fd3c16e90304654010e79ff7ce44029b1948e + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1a3f8af71d423da8c007022421f09a53034c6e9d7d23572b8b4b273b091a6f024ea4216ebbca25daa4e9e83fb46a1d9e65fea344bcd4 +B = f6446ca2883d7e27209f04dfaad663de6d32ccd1fe409775a8b5764ed914fabb960fe4a47b154ef982955ea06285f34d992d2e87d11c56e0f0acc96485336ce7 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 3cd13ae384718065169d7e6b600ea1d1a514832649029f92f1d2b5bebbf83454fcde0133f3bb4716cf452a3f930d28f30e7f22f21982 +B = -f6446ca2883d7e27209f27715ac2cb0dafef23687a87d593b0341816ed9dc69ade774b2c099901d747e80cda424b2b3eba6958e3131c3583fc0171e504e0c995 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -5849ade77039ed0b15524c08929a4553a6c0825178f6522915592ffa9638a8143fe8426df9757e8c06aabc97a2ef87b4a58869d1df4d +B = -f6446ca2883d7e27209e925671f7d662427ef778b013e2eac90ecc41e82604a1ecbb440023dfafa66b7ed013fea93e0df4c682f32c44ff874b59bddd781cd0c6 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 9c4b4b4800fe2f11e1897ee8c8e147b143a252847548145e77d9a9d3e4e3a79283f833e760bdc69d5f75fc1d0356615b0c10b1e34f9f +B = f6446ca2883d7e27209e4e54d497459e00782b417d33aca3c6b12f6017f308502a85e17faa0660fb6c008c040d2fd6c5acb52a27ecbf9f2071b35755300b6074 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1bbe5a805b857ccd9dae7cba6f3dab95d22f7d2e1621a2ab382898bfb2b4efccb263929f752397da4ad030e6d5c8773dde8fe04c42f97 +B = f6446ca2883d7e2720a0a685c7e4fef3fc63e7b2c7c3695fc7bf95fa3d58dfb26997dbe2dfd5712e105e36356b0e89bcf0f736a0f749fefe46ec4c63e6b2dfaa + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 255c9a10ee08acfe197fecdc7b6cbae27f8dd38887f135cc5adb1b9276c94ccce420887a7476b2d17c2708c84b7e9a8b4160f676f8d1e +B = -f6446ca2883d7e2720a14069c0ee2726ff6ba4c9c9e42c50bc8a6bdfa2fffcab9baa070b0d01b273e0615204c8be7eeea06a4c0e75615a607bc27975495e3d31 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -4bb5296b4ce3e960ecadc3f15de0a3a0dacf12d34f690cafaa8f2e31b0e9e69d42a3b16bce84361c81b7584be32210daaddefd7184659 +B = -f6446ca2883d7e27209a2f4d892a785d997b41eebd06977ad454c6113d42870773e9b06670bf3740a9bee5c12a5a4f40118a6e28641e7055c56385760ad669ba + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = efb45966d1f6d79c9b4c72c3a584e26e7b7136295fb79a911433a10ef649b47b14b8d76cc42e54852176ef7da7d08b86186cbe6e98b23 +B = f6446ca2883d7e27208fef5a8972272eb5c05803cfe21d36e77abbef07e1821e95d3161f42eae143cbe1c46eca4af49e2b00722ef102256e1aacdc99fb0524f0 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1e30bf701cd589fa3d2adff0217e8f748d1a254b771d77d342fffe3e3138aa3d4a75ca8c1e6636919636d4d96d8b04d583af4dc208b51b +B = f6446ca2883d7e2720bd1b5f8ffc1c2629c737aaec3df41482ef8d27b5ee9b1012275957920b7e8950dd85c6cd359dba04e8c072c24a2d7ba89212b3a3f7652e + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 320eee30dae44f272fc9606477927bac85b677c3333fa55f4c5b5c7e71bc02266a906d8838a096551a8b5b94980cd819ac721a6ca70a71 +B = -f6446ca2883d7e2720d0f98e50ba2aeb56b9d62b60940800bae8297a2daabd3d9e30b4b5d24c01e139fda069c94fd819c86d14f97d74af4eecbad5804e95ba84 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -5819f4921a515433459006c62df3be1c4e642a52340381b5954df3f9dd0ed5f73f8dc9a17e536b88090ae8d5fbc411f16eeca2449ffb96 +B = -f6446ca2883d7e272046d0ab8dc4f547fc447cc435ee81c6f2140ed818437a16894f0b6559fd37091c5382329f98e417eb497eb512e0de64e19f76c39d4eb47d + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = f238bbcd9701966bc4482fb8df8ca395ad15e2b83c014e59898e33a36623580e9c91faa3873eb26a0e97c4d29ff209e22c4faa0a1295a0 +B = f6446ca2883d7e271facb1e452484505c3c5c49b433ce8e178b55d1fb23b7c49e55acb25b074228704f67e019d8ff8d10943f1d9163cb06cf0e213bbd7dc1a73 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1e00b3b3bab1081231e0f1a2029b146f8391869dad416f6c8443c124ea7c908ee402f6b6fe06d883c2d232713512ed5d8636a07898523f3 +B = f6446ca2883d7e27227ef5db5b8a571d52a81be51c4626cc069b8b6c454b948f0728956ba2820ee801d33f67b0f7a50baf7facc4fc2dd14cab71cd6d6b73d406 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2030dfab0a9e0af1764f416171c8eee2d0b87bd5b80e6cddee4ee2a7509a301956050b6e3bb067f827d13c33abf31693d4101951d4a0b96 +B = -f6446ca2883d7e2722a1f89ad089274b46ef00e1133904733b6dfabfc5f864661dc94783c8e3e8e0a8f360b324d23e02f5cf9d61239bd3e0104f64faff38bba9 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -7427bfdba61a57b644fdd11b2a3ea1d3507cdf4ea1389436bade3fbaf751724000774127923658c7b090f182d1d7e320aeaeb1e3dc0b30a +B = -f6446ca2883d7e27195c6ea2657da120cb3a2fb949788b67d95aa50d8063f454d336755da4652ebb138b9be9c7f3d1f6f8497a85bbbf2444c8237847a42dfd09 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = d23891ab621e6ee43b3b250d66ab139cc97db21429da33e01910635969af402b6792f6d741292a0e1bb6bc30b2a7b32fcce9f5e8c2e48bd +B = f6446ca2883d7e27137b618569bd5fadebd65a7a25b1c44b41ca97e127d9da5a3d535323bd3f51dc5d19e08ecd04a4e291971ddaddb22743d63fc40755c06756 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1d6d78b7e83cedb64f0afa17c56360a58eb5ccc4e647bd3c594feb6695531f9434adb169ce314d4c93b4efc260fc92b268ca22143fb7e994 +B = f6446ca2883d7e273e0c6358081c34527e9506e2c17fd62a9d183fc750bf3ad4983444bfe92d65734840c1660f4884d00707796049d935293bd8857a21a699a7 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 255261901144afcf37c28015f4ec493bfc06cbabf851997d06cdc2fa742a97e234085ce67dcd867451a19d3427acc5ac2fb5b919f1514e06 +B = -f6446ca2883d7e2745f14c303123f66b674c8ce0f108bec10a693eae62c9171545b21c53c804ddc1479b6ce2bee4bdf7c4f426d21089682302c41c7fd33ffe19 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -4c222346b39b4b87631fb26dd9b3a8942374f10ec577d0aced5cada7bb0fb34d9c85bd06b6d52a4229ec662ca5605aff7896f7d74483fe99 +B = -f6446ca2883d7e26d47cc7596c43fb14cc6a5a5d2268ccf0eaed81f3a4ffaceb5187abb198ca9291770d52f58a420d4149662371437c47775a776b8e9d6ab17a + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = b832106ab8bf5c27886927f67c5bb95d81280a5b4a3a044c39c816dfa5c5a4c6e8058d34c3e44bab649194932e42c197b40d16213f6565e4 +B = f6446ca2883d7e26686cda35671fea74a720e4d47fc0bc278d3a68a7203d794c051c4279ae14a1182b8d82c77d32ebd80ec0f50aba99e0df1f014d44a2894a2f + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1e4bd432a98b6d68d35627f4a46b56f04b378a535b50c7287ec949008e8ace3ed04a128043cbac7a49c6c1cb98dc27b684c4f971d69b51268 +B = f6446ca2883d7e29055c2dcab8961d2964ec8c1542d1e489c1db18381f83f0202b78e9623c8729cc183438007dd1ff280fbea657769f1ddf1f5dfa834ba3c27b + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2af2a9aa0364d970115f35b6ab676f4baf1f4ed52d07cd808dcc7fc7bcdf2268f917a7e4476e429200a37b246e786e85a2b62d6b52de13135 +B = -f6446ca2883d7e29cfc98540562cdd9d457d6835b2936a40005760553af455a11bac55d521cc6c6ea50d8e40b7fb60a37d8a3be4d0638ad0fe713a1b0fcfe148 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -5dcc7b06c24160a67934f3adf5f5a468f10b0bfe1b82e133c797674c941c9480bb1e71ceddd1151f88244bebc63c2da41557670132848e482 +B = -f6446ca2883d7e2143d73a33fbc93c349c3ad1eb9cc22ef5fdb1b320b2496a5bc56de4901210fdd361abf30e6405e58af10dcae18519c8357d97f352b9a5cb91 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = fe6a6b7e6ee19b5e4e2a4cef85f637a5b0a76007bf1080fcdc86c952a49adce824573dbb3c0d3f94d519698968594e0b840b6c91ec9153aa8 +B = f6446ca2883d7e1739f832b931c590b74ce53dd29cb8fb2a03ec7286796f6dca7677c42f0a2c775cce1f344880433e3621bbf1076347c1be92579a4718d9756b + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1f219dbf1e789d4d74f10ff27fb947bf6cc94bf1e742ba203caf33810589005f8326704b8414819d90698fe08d9b3c16bd261beb922a9af9a5 +B = f6446ca2883d7e46423ca9be987c94112099ff4ab56434f1d7ae64e9ad319dd4ee17da5edcdaa5623a035b805598d513dce26a2b8418b933f92a4ef80c89a9b8 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 25bbd6ed7646662f6dd8481ac4c4a531174bcd05123889d4cf904d12d8d2bcad5425074d9c7fa1ba70ac5c8a3723fe6b20e064fb4a9999e716 +B = -f6446ca2883d7e4cdc75d8166645760a07d2278fc0c1a69c5a2f7814a3015267cf316c322696f333389a5d98c0b8f1f41faf13d50cdb0d97b3735eb07b889729 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -74af822547dd8aa99da2b3b60b1aa5d45c33cbbdca0d2876531b31a25cec244482832671c861b749effc1cf5e150aeb9d8e88583953aacd577 +B = -f6446ca2883d7db2711cc55842549cfe8cd656bfe176a128da96b5385d4f074523b2b6fc67b6015c906c9e33df5fed93773593bc982de89dea88dfd0a741da9c + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = d35d55e21fdf90fb0abaea71ae6d7f44401f615e7dc6761713ec45650b94c02f85e7bca8c2f43ada8975617eb7ae6fa41f4eadedaeb544654f +B = f6446ca2883d7d53c3490880404e4b91749f9b1c8e9d3144ef011484a4016684529ef44dbf1a16592bd667394cdc5cf9fdf10ae63a6cfe57846075b72caa4ac4 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -14872666f07cb43b47b4b82ef6df5b7696c2ff49a88ec9308e27d27736df05f79d452957297271756ca1afbc47ad011f1b77f32bbff831bb941 +B = f6446ca2883d7f6f930559a7eb22fb177b0cfc38f1d3def13e570d8b570a867abc0bccc74439bfb366288293682e8e4d8e4e4e18b8ee942e52411f65650a6954 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2d2316a87167a23eff9da00b857c9423e44feb69620852e9e8d87ac70d96367a8947729b57804ab1d54022442f5504d23ea42a6cb0eddad04c3 +B = -f6446ca2883d80f9520971b69a033696098ac522c55eb3ca0d190922efa61c25c690ca32b741ee738abcc57445c254d77576cc933929c66115b52e74bf9bb4d6 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -4a296521345e531b059bd7bedbdee650280008947bb0de4012c11281d92be141b2d29b92812a4843eafc296fa69c55a697b4e9620a79fa8fd6d +B = -f6446ca2883d79848a4cd75a3aad9642720e1f0d0db773050dd92b475c937c6c2dbc3bc695c62ab1e9d9e7e99c92f8d3b0bb8f34238238fb847842be4245b2a6 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = a29d4661e53bde02d72f6e0e3d19ccbd85d8c0a0392d7153ed330ff11e6f75c9880dd1f77a89be8c4e48b10bc7b43b46fbffb592a9a2f23b932 +B = f6446ca2883d73fd4c38cc4c61ff192938a928f95f509d2782586f6f93623ec50de547725c7dad5e36739853a52e729ee841cd22a52832b6d7b538cbb2caf6e1 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1c7a1c6185b0a2d7c02f3a7884e5a11513785520f1a27e8c29cc30707300edbaaef99509e9c4f578d086b2a8c593d0a04d32682c7c71f6a3d025 +B = f6446ca2883d9aa13d007050c2b706cb6a0291b09d3188fd638364a4e903a7646f54cc5a4194f4d8a89cf9c13690080a25fb4f31b97cefa93b3adfd7d8928038 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 21eaee9881dff114d10dad6acbb6e712c6d1acc6b878ec60253c44ad7e9272bb5ab0e2ceb2023fa9f427a23ebb464b2c8c411bd86032c6873ef9 +B = -f6446ca2883da0120f376c8010f417a9dcf4d881e32f3c56bb292b7b56d7a2d48391d7ebc695a08ff661c1fe80c12bab159144e434092eb7eee6c398a875ef0c + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -46f16fa8b7a3b6ecf476f8cdf5f77ea3a7c9be958ced5db6c6a9e11e6bcf3a156b3fb60bd5ff862c80d7c3e3f23c15df57a8fd7822d4c7d9738a +B = -f6446ca2883d3735b0f632fc68f2522536bc16d37d78cdbb4fcce6150cc0b6ee5dc5ed8a19c4da9f5d8739fcbaeab6abaf6e9761d2fd4acdd59640911a153c89 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = bdd97dea2fd68c602862b0fdcbbe47d5e2e23ec1a10925cf34e9773d09d90caf70b5beed3ae1509392289be0ee66b649d45b3dc880ce4f48bb4c +B = f6446ca2883cc04da2b4bac9937f1e397e8c410cb44692a2cfa0d1f944a848aec7a74f80472ad52954a5d51af083a55ad7719b373292ce1b9545e29792a5f4c7 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -145dd43715b37e7df4b56e5afa79caff8668de6fe4c2f725866d0f84522682f38694a26bea588a576900862dee9c9498df909fe788d72db324f6f +B = f6446ca2883ec404641045d807be91f31539b467ac14dc12f560bf31dccfe46937297bc18312af293a51b584e68dc78bd6317367326a9b80d186f0d8bd20ff82 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 35094bde0256df169828d23a250e3a10f35f1fe30f168d463ccd8389197b8aaeb326ca86fd09b3d8a29769ac3c6ed856c34f10cb0d993e38252d5 +B = -f6446ca28840cebbde7f100e1148c929532c5dae9d2bab770c93646b3edb4a707775f111fec5784bbc02e0977ea160fa0e16508b6e48d767dfbf3cf9c57102e8 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -578294d2b3d43ffd19b79a65778710da245eb96fda50d50a3aa6ae3295dc50d8f7da1f5c8b98f4a9905ee840dcd139a62697eb45678259d7639ff +B = -f6446ca2883805fdd373ad5c200dab2289329459ee7a2f997764cdf519d3d32d5bbafb94464ac83d1dca566cf67e3194ef44bc8a4e7a38f81eb7eb4044787614 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = ab192cde88b1cb3e6b094409c1e81ff84715d64ddb7413f6fc5dc1182abfcaca481c8035d16e0d698476d7094f2bf7cb3de1b1210ba68701168a3 +B = f6446ca28832cc9452b65f836bf89607eeedee48fc980427a984bbc12b07b7bc2d61ad5ca735c4171035f91b6a7ef01602bd96de6c28c45bc0fda8fd71dd4770 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -19a7abdefad11d1c9b6c4e0c4c1ff1194c490f63086ede1e4c43d964555a2f5e561a9bf5dc3a670b7ddfe8894271197747860c78949e6c9e357460 +B = f6446ca2885725d2ff99bbbd3c7ab2ea3bd62cbc1568be94716ae1e088c3c171a339b388b230607b096f4a634c95176bfc94fab7602428834ba301d280242473 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 275ce169251250a596ac64ac6e23ae05f8785db63b9cb83a9dec067472d059ea3aef07cf9fc20b846b3292899a8d3fe1aed5b92f21a89c1d924bbd +B = -f6446ca28864db0889c3fcf0c575f300dbf830790214ede2c49e0fbaa515699eb35729b33e1534e6e332d207c5826a15fced16ddca8b783002300c01ff80fbd0 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -61039a571c78308b819da54c1849d8d6169a82e25f61f26e30ab16b545080417f2008ef89116e002660f95863c47ac02bc161bbb7aa8817457eade +B = -f6446ca287dc7a8cc982726f945da8f6e371c2f22605db022c03110ffc46d281899f51553be845501b01f91c3eb127eded1641f1e6208c5b1793bae46d96c535 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = fca0b32bf9e248320b8c10128ff4368a766dd34fbfbf77e66cb2298fa3833bbf24451f508a50afd0131ad49c9ac8e851d4fb53f2fe33675f5e6b34 +B = f6446ca28740dd73f4a50857edd3ba8c1cfa189471a607b1bea2b38a840acb6eaf40d61d94b600bfc308bf4c71041caed6b7c0b59707a722e0102ffe829044df + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1c6f81990e54d6894188d5b872009c3eb5b2f10137bf7a27999d918790b587594afab3950330296979c354851164f95938d1df77995f6c0a9a3edef +B = f6446ca28a047640b1843808b3f7d3f7b6aa168ee777a49521de6aa4e41156b0b7efb1cee889f11863c61292d8b36ccbc468d9337c69c06e4ca45a268b929e02 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 310b6086b85bf12c7e391184e070f623c9cfe07a8e495010fc13d584d748098f070ac4b7c31cbd28acd32ab6270e2a98f48d8d31525ada808858785 +B = -f6446ca28b4e342f8c24a9b2e7c2d7b47d911c2d38b9738cb74708037a38baf08c58d9f2444af22a8fc4dbcecbe46a2ed5c36c4778257b49e834110dea743798 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -4a51109cf8c033e683b1bff229f081d71cd5cafde15dc2d5f8ad0457e79b9b2e015659ee564de59f27204c685ef58977e13e19fe36a2d017fe6860b +B = -f6446ca283986d1d5112e761b7a42a9d0ceb04ad8a4f18d5304c96d50aecad52c06a9fa673c4e0402e2e31a24ea532bced6331066ac8c0d6efa4366462082a08 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = f3e425af6aa16899624f20b49c4e9115034aa4d06ce9db9aa742a6e60d59d6ce0a067f5645b8e7f896c8561315ef1f7151e073d115f8e38df274438 +B = f6446ca278ff3bcc29f4d41689ba5490e5c523b9abe7cb380793d548c0035329de0ebbec7339dde9af37817cb7aab22241f397a6d3be9b39c1aed52d02c76bdb + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -18b2de417fc4bef91b5dd82b0e93315b306bf3a7f7bf0a486a567e9cd1370587b7e47adcb9accba03a8dfda5871b0bb1bdb569a90c079f7a9a4e87d2 +B = f6446ca2a0f05c68a063a9993b3d1ec73e1d3e262c88692d06217d4ad4cdfc35101b5ee10bbec0bbcd3fdb9c7ba53528fa6d954fa6920c1fdf1602e07c3d37e5 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 26b556807e84a9bf7cdf2697050cbd7145a42b8ef6fe10666da7a2e69827ad04880bb97ab3108a27da5fcc29a041bd6aebbaf00ab25a841674ff9f1e +B = -f6446ca2aef2d4a79f23945f9cbe6d333496ca3c41c0a11405608368d81f207ed70c065ddbe5ff59c6a39a241b7703ad13944708d49792818568e77c56ee4f31 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -40b258c2211cc2cb9e2614ab4b23cb9eadb1ddcae903c93646e9f5e5afcaf912a2fdef26c864d83dcdd6f434ca2b0aa7f8ea7a21e790a9e4601de110 +B = -f6446ca2478b2564ff8227d481b931f0e466412c4e6a97ba255ea9cc238d87b28f196046b0dc56b84b2e37be7340434ea9277ef5eff22854eb7db98181d0cf03 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 97631efbd149bb0fdecce09d14aedf2efe30407c01c68e000be9c7be954999375e1f7720e8e5f1edfc48b92f9a063f6b2b378996459bffeae3d362e3 +B = f6446ca1f0da5f2b4f552f90411265ff1adb2d9bfdec35090c9be5025e8db5d9a99ac021f5bacebe2aad1e0e44ce7e53d94c4a32bda518e08d72637afe1b4d30 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -15f4c3634bbbd1ce04fdf96a69b2b8263290e188ca83956b74c6d190e7b877dbd176657a19ea125dfe9c95d2764002ca5d98e28315cb391779d56fcb2 +B = f6446ca3e789b45bdc5c07806fbedd42cab58f2e252a8e11b69bc9b9b6e496a6ba6bd7166b409d80b23435dc2ae094aad752b643c26acaa82fc1f4dd7f45acc5 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 39ecc3b285eb99a2ac91329da615e581f791eaebd477d87c7739dd961a2c5c6cf86a34c73856efcf3b812909d830186c910f8f053192cac9fca8ab7a3 +B = -f6446ca62709b94f7f5884cae8f2707690e864ea753b244255dffac9de1556f9e1aa2028da7d925299020ceff929c820f6541066f9d592c9ec3b1005ac7967b6 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -707e64f8bee7a679d9b72bd04b231cda716f5dc1b7a404f8c0679770c46fc944470ee2a221d1e3d166619ba6a430d0349e7e75c0ee021ed027dab5d74 +B = -f6446c9b80572e9b32248302846c89977d583f23e52699699422237663fe068bf7e7c514e2ec1bbcf674d2e5dafd7d193045865400f54667f2ec76636443529f + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 9ca2c37f4b1a392c34551f570ff06a74c5f027170815454c5ed3535d5232df54fb1f65f2304e32b4995bb77ccd4ece69db98452f182dbeda98d525a19 +B = f6446c98be1146326efb57dcda8d512b3083657e9d1a04148d0e1e3c7d4247c31bb66409a1e3e6bc0eafe4b2ab5bbfb69e65a3002f584f85503275bc549c55fa + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1190fea35b9a1ba1c280d57888664aa7db5f9d6d4325b35a6276bf61291d67e6e14e3001f5af1753faff61fa53861ab8ed15d15965e0dcb05718bdecc6 +B = f6446cb4193c2182baba8c62a0b4bf2495d4b4a65bb9e2c83415cd64e136dec15c4c403aa20a47d4c2aa63f7407931d6f96d428afeadfbdcb3eb13bcfaac9cd9 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 209797b717f068e5f808dd2b4e12576fa056879da881bfcc1819228e4f9dc6f84347edbdbe273657d533d7c928e51b68a82c59d93dfb038514c104c1bc +B = -f6446cc31fd5353f1107d09828bc71ea41e17c6b52a4132d90223f1a839a0be7dcab519c9bc8039d3ac967d174ef00ac586df24615367bb4ce11e87aa2f371cf + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -7198b6aa26be42e97cad682aaa63d68d51952dae52d4cfe5f9a6acef93f35b6d7b7be87a1f2a944cf7fa9483cd6c3df7599d44c5b56e5ff38cd43d23c0 +B = -f6446c30ef86d400625c012372771bf1cbb37f7966eec73239928d08c3ca8e044b88ebddd7f1cbbfe8fec3044682b3b6071492444b97dcc164ae6fd90db18c53 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = cb788549eee4fa559118f0bd66b68d94845bdb7d07b2042d53a64921f3e3df76a2b143e9e9ad39dacaf405cec5fed9fd59050c5d27322142e4e11d4ede +B = f6446bd70fb834383ba4950f06ee893578fc7846a040f87d5c5e45aec42e5ba45b04e2b6a2965bf5665935314d1168bd74788c44e3d0454fa0ed208100d16135 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1122c39c2c252ec96e9274bdf713bfa8200e35ed9f18dd087fedd2005e5898b6f8ed37e1cd7e1f7b0c5be137a71a27b7e4e4669b1f412e154e6ad2ad567 +B = f6446db4b47740e9738b8189472b260d6b848ecbdf7b4f769c32fb014797837dc86fc8e8275862b6f58ac0c1ff2ab1f515ce07ec2f46546ae5efb84c8f19857a + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 2d57e15c8039f8367d2e0198d9fc27616e53efdc9cb0adc0b0199362d08f5698af1f07499cd2b72005f1c09900c71b677e57cd62094743a9b3ae541e74d +B = -f6446f780653462ac0225272fff8d43bf20023b03b1a3f50193e7e0403adaaa1344de44b444edfac3f05105b5d20c78fe509018365b2c30b4748fea0c7309760 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -539b4413477ef77c15fd53e202d8e5d183eb1c91fecf5b89959bb8d60d3f7907e95c5dd045d698a6a17f0150861b43bfeb2e5d40bdc970839b0712ee17f +B = -f6446768d3fc49af312729404aa1266ea12cf48c4a53559818a9d9a8aeea1cc44753dac38dfd4181aa08a5e451022f21bf168aeb0308969a3c0629b570bfce94 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = fe46dc4f55346ee27d6ced0256b0ec64f82d5150c3b49d4cc7d56a60ae5d10bb649a57f4c97acc146388a6a9d25d3c3c7e42372e46bb4f8a72171ea5979 +B = f6445cbe1a7888d3d9b0c2c9510f213120c3bd4827076949c48da68513d172b26dd8a30fae5af94766d1c9c3b6ac9a5d9f8ec1b9c569be0b1e15bc447004569a + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1fbd702bd26d37bb1fa554ad261f1e7161ea438f49b41aab950884c5c87eb1e0b9a3a69807b759a1440ef9e5683c1a13b9d610fd87fb131619cb63997891 +B = f6448c5ff8695094585a0a45748c6cbb4dfb6eb53fabbf39290e080aef3d4616f0c512fcfa724d966d34540b3afc9fbf8d664373f9da2a71e6247d31458828a4 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 260abc8cb124b3c17698ee342bdbe4b1513a085effb4f79aca252c98c8799ad203dccc9c305cdccd2edc16159d0e2c7a125c50f8abff9e12dbe8d93c655d +B = -f64492ad44ca2f4bd46061390e137278143b5e05047b753a05fd3d2797104611d9b65d362076763bf0603ed8572cd4919fcc9bfa39d54e7671213f4ebb2b1570 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -6f961198d2039a92d24c53bfcafd73251b575d5e06565db36666545d5994e511c4c3905cc0b93586f05916c08b8f51a0e0fe1b6253fcfa41bfec25196482 +B = -f643fd0c76a4ac23860c1853cc1f7b9ebc64f1739ebe6f2eb0af0c9c161a240359d29495c37d8525de0c1fa32a56abf421b1a89fcd7a4e79d8cca379bcd54b91 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = ed86313f32aabf2f7487dd9f587431e17b9a46e1a78fe89b0ebe81c737a73c2a8fef92c0963fc36e9808309d00c3bd14612fdf4fb236e06add8fe9329252 +B = f6437f1c56fe4b7c616f7618423fee27fda89130b53acdf525c76443e8b045f102b9c969c119af9f502477f4107a36bfb63e286e098cf03ff2a385d5f8bc1dc1 + +Sum = f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -1741bce7ae27a7b3effa5b08b39f9d03d69efe7b0716cc57dc106aac17925a2d77c18386f7398db17f813c9c6f2dfcc9347e9f55de76b11475fcf77bbedb1 +B = f645e0be56b860a19bddea45d06a8095ffc776bae3cce6f1d3e034091538f6bde1bbd5718c49b977eeab08100ade2a633fe5d187de3a89e1e455c33559aa9dc4 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = 20bd41a0d6d691e8554ee8b90a775e04f086f318b7afdc7b5d6d7c3b7ab6b955aa286809856e1bd195dace84b18b2d0365edc8e066d2e8db9ae8325d00843 +B = -f6467876a24aeb903f243f8eab6fee120fd9153a2da7f082d61849da2e2f2903d43efbdfd4729cc0d0ac6da9296250364388e87a76e30fa560c811e907beb856 + +Sum = -f6446ca2883d7e27209eeaa01fdf469c2f8a0ccafc1c75850e6273026a777d983ee4595953da45df13930ffc411737837352899de8dca276d30e6365e1eeb013 +A = -685147a1e74dab824bc6cb7fb30a773fbe5e380f46189574038d2d2f3983ced8777a080af6b06e9bb3c2d134a3302fa099b4bc78a4f01a4c157424ee3c773 +B = -f63de78e0e1f094c687a2e3367e415f4bb8e26e77b2813fbb7223a2f9783e55b515ce1b8d32adad829d7d3cf2dcd04807948ee52215253752e4d0c23930ae8a0 + +Sum = 1 +A = 0 +B = 1 + +Sum = 2 +A = 1 +B = 1 + +Sum = 4 +A = 3 +B = 1 + +Sum = 8 +A = 7 +B = 1 + +Sum = 10 +A = f +B = 1 + +Sum = 20 +A = 1f +B = 1 + +Sum = 40 +A = 3f +B = 1 + +Sum = 80 +A = 7f +B = 1 + +Sum = 100 +A = ff +B = 1 + +Sum = 200 +A = 1ff +B = 1 + +Sum = 400 +A = 3ff +B = 1 + +Sum = 800 +A = 7ff +B = 1 + +Sum = 1000 +A = fff +B = 1 + +Sum = 2000 +A = 1fff +B = 1 + +Sum = 4000 +A = 3fff +B = 1 + +Sum = 8000 +A = 7fff +B = 1 + +Sum = 10000 +A = ffff +B = 1 + +Sum = 20000 +A = 1ffff +B = 1 + +Sum = 40000 +A = 3ffff +B = 1 + +Sum = 80000 +A = 7ffff +B = 1 + +Sum = 100000 +A = fffff +B = 1 + +Sum = 200000 +A = 1fffff +B = 1 + +Sum = 400000 +A = 3fffff +B = 1 + +Sum = 800000 +A = 7fffff +B = 1 + +Sum = 1000000 +A = ffffff +B = 1 + +Sum = 2000000 +A = 1ffffff +B = 1 + +Sum = 4000000 +A = 3ffffff +B = 1 + +Sum = 8000000 +A = 7ffffff +B = 1 + +Sum = 10000000 +A = fffffff +B = 1 + +Sum = 20000000 +A = 1fffffff +B = 1 + +Sum = 40000000 +A = 3fffffff +B = 1 + +Sum = 80000000 +A = 7fffffff +B = 1 + +Sum = 100000000 +A = ffffffff +B = 1 + +Sum = 200000000 +A = 1ffffffff +B = 1 + +Sum = 400000000 +A = 3ffffffff +B = 1 + +Sum = 800000000 +A = 7ffffffff +B = 1 + +Sum = 1000000000 +A = fffffffff +B = 1 + +Sum = 2000000000 +A = 1fffffffff +B = 1 + +Sum = 4000000000 +A = 3fffffffff +B = 1 + +Sum = 8000000000 +A = 7fffffffff +B = 1 + +Sum = 10000000000 +A = ffffffffff +B = 1 + +Sum = 20000000000 +A = 1ffffffffff +B = 1 + +Sum = 40000000000 +A = 3ffffffffff +B = 1 + +Sum = 80000000000 +A = 7ffffffffff +B = 1 + +Sum = 100000000000 +A = fffffffffff +B = 1 + +Sum = 200000000000 +A = 1fffffffffff +B = 1 + +Sum = 400000000000 +A = 3fffffffffff +B = 1 + +Sum = 800000000000 +A = 7fffffffffff +B = 1 + +Sum = 1000000000000 +A = ffffffffffff +B = 1 + +Sum = 2000000000000 +A = 1ffffffffffff +B = 1 + +Sum = 4000000000000 +A = 3ffffffffffff +B = 1 + +Sum = 8000000000000 +A = 7ffffffffffff +B = 1 + +Sum = 10000000000000 +A = fffffffffffff +B = 1 + +Sum = 20000000000000 +A = 1fffffffffffff +B = 1 + +Sum = 40000000000000 +A = 3fffffffffffff +B = 1 + +Sum = 80000000000000 +A = 7fffffffffffff +B = 1 + +Sum = 100000000000000 +A = ffffffffffffff +B = 1 + +Sum = 200000000000000 +A = 1ffffffffffffff +B = 1 + +Sum = 400000000000000 +A = 3ffffffffffffff +B = 1 + +Sum = 800000000000000 +A = 7ffffffffffffff +B = 1 + +Sum = 1000000000000000 +A = fffffffffffffff +B = 1 + +Sum = 2000000000000000 +A = 1fffffffffffffff +B = 1 + +Sum = 4000000000000000 +A = 3fffffffffffffff +B = 1 + +Sum = 8000000000000000 +A = 7fffffffffffffff +B = 1 + +Sum = 10000000000000000 +A = ffffffffffffffff +B = 1 + +Sum = 20000000000000000 +A = 1ffffffffffffffff +B = 1 + +Sum = 40000000000000000 +A = 3ffffffffffffffff +B = 1 + +Sum = 80000000000000000 +A = 7ffffffffffffffff +B = 1 + +Sum = 100000000000000000 +A = fffffffffffffffff +B = 1 + +Sum = 200000000000000000 +A = 1fffffffffffffffff +B = 1 + +Sum = 400000000000000000 +A = 3fffffffffffffffff +B = 1 + +Sum = 800000000000000000 +A = 7fffffffffffffffff +B = 1 + +Sum = 1000000000000000000 +A = ffffffffffffffffff +B = 1 + +Sum = 2000000000000000000 +A = 1ffffffffffffffffff +B = 1 + +Sum = 4000000000000000000 +A = 3ffffffffffffffffff +B = 1 + +Sum = 8000000000000000000 +A = 7ffffffffffffffffff +B = 1 + +Sum = 10000000000000000000 +A = fffffffffffffffffff +B = 1 + +Sum = 20000000000000000000 +A = 1fffffffffffffffffff +B = 1 + +Sum = 40000000000000000000 +A = 3fffffffffffffffffff +B = 1 + +Sum = 80000000000000000000 +A = 7fffffffffffffffffff +B = 1 + +Sum = 100000000000000000000 +A = ffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000 +A = 1ffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000 +A = 3ffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000 +A = 7ffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000 +A = fffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000 +A = 1fffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000 +A = 3fffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000 +A = 7fffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000 +A = ffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000 +A = 1ffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000 +A = 3ffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000 +A = 7ffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000 +A = fffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000 +A = 1fffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000 +A = 3fffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000 +A = 7fffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000 +A = ffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000 +A = 1ffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000 +A = 3ffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000 +A = 7ffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000 +A = fffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000 +A = 1fffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000 +A = 3fffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000 +A = 7fffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000 +A = ffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000 +A = 1ffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000 +A = 3ffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000 +A = 7ffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000 +A = fffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000 +A = 1fffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000 +A = 3fffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000 +A = 7fffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000 +A = ffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000 +A = 1ffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000 +A = 3ffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000 +A = 7ffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000 +A = fffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000 +A = 1fffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000 +A = 3fffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000 +A = 7fffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000 +A = ffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000 +A = fffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 200000000000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 400000000000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 800000000000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 1000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 2000000000000000000000000000000000000000000000000 +A = 1ffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 4000000000000000000000000000000000000000000000000 +A = 3ffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 8000000000000000000000000000000000000000000000000 +A = 7ffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 10000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 20000000000000000000000000000000000000000000000000 +A = 1fffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 40000000000000000000000000000000000000000000000000 +A = 3fffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 80000000000000000000000000000000000000000000000000 +A = 7fffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffffff +B = 1 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffffe +B = 2 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffffc +B = 4 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffff8 +B = 8 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffff0 +B = 10 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffffe0 +B = 20 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffffc0 +B = 40 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffff80 +B = 80 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffff00 +B = 100 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffe00 +B = 200 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffffc00 +B = 400 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffff800 +B = 800 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffff000 +B = 1000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffe000 +B = 2000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffffc000 +B = 4000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffff8000 +B = 8000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffff0000 +B = 10000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffe0000 +B = 20000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffffc0000 +B = 40000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffff80000 +B = 80000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffff00000 +B = 100000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffe00000 +B = 200000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffffc00000 +B = 400000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffff800000 +B = 800000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffff000000 +B = 1000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffe000000 +B = 2000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffffc000000 +B = 4000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffff8000000 +B = 8000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffff0000000 +B = 10000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffe0000000 +B = 20000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffffc0000000 +B = 40000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffff80000000 +B = 80000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffff00000000 +B = 100000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffe00000000 +B = 200000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffffc00000000 +B = 400000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffff800000000 +B = 800000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffff000000000 +B = 1000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffe000000000 +B = 2000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffffc000000000 +B = 4000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffff8000000000 +B = 8000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffff0000000000 +B = 10000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffe0000000000 +B = 20000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffffc0000000000 +B = 40000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffff80000000000 +B = 80000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffff00000000000 +B = 100000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffe00000000000 +B = 200000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffffc00000000000 +B = 400000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffff800000000000 +B = 800000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffff000000000000 +B = 1000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffe000000000000 +B = 2000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffffc000000000000 +B = 4000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffff8000000000000 +B = 8000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffff0000000000000 +B = 10000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffe0000000000000 +B = 20000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffffc0000000000000 +B = 40000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffff80000000000000 +B = 80000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffff00000000000000 +B = 100000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffe00000000000000 +B = 200000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffffc00000000000000 +B = 400000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffff800000000000000 +B = 800000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffff000000000000000 +B = 1000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffe000000000000000 +B = 2000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffffc000000000000000 +B = 4000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffff8000000000000000 +B = 8000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffff0000000000000000 +B = 10000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffe0000000000000000 +B = 20000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffffc0000000000000000 +B = 40000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffff80000000000000000 +B = 80000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffff00000000000000000 +B = 100000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffe00000000000000000 +B = 200000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffffc00000000000000000 +B = 400000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffff800000000000000000 +B = 800000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffff000000000000000000 +B = 1000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffe000000000000000000 +B = 2000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffffc000000000000000000 +B = 4000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffff8000000000000000000 +B = 8000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffff0000000000000000000 +B = 10000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffe0000000000000000000 +B = 20000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffffc0000000000000000000 +B = 40000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffff80000000000000000000 +B = 80000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffff00000000000000000000 +B = 100000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffe00000000000000000000 +B = 200000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffffc00000000000000000000 +B = 400000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffff800000000000000000000 +B = 800000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffff000000000000000000000 +B = 1000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffe000000000000000000000 +B = 2000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffffc000000000000000000000 +B = 4000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffff8000000000000000000000 +B = 8000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffff0000000000000000000000 +B = 10000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffe0000000000000000000000 +B = 20000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffffc0000000000000000000000 +B = 40000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffff80000000000000000000000 +B = 80000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffff00000000000000000000000 +B = 100000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffe00000000000000000000000 +B = 200000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffffc00000000000000000000000 +B = 400000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffff800000000000000000000000 +B = 800000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffff000000000000000000000000 +B = 1000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffe000000000000000000000000 +B = 2000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffffc000000000000000000000000 +B = 4000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffff8000000000000000000000000 +B = 8000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffff0000000000000000000000000 +B = 10000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffe0000000000000000000000000 +B = 20000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffffc0000000000000000000000000 +B = 40000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffff80000000000000000000000000 +B = 80000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffff00000000000000000000000000 +B = 100000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffe00000000000000000000000000 +B = 200000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffffc00000000000000000000000000 +B = 400000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffff800000000000000000000000000 +B = 800000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffff000000000000000000000000000 +B = 1000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffe000000000000000000000000000 +B = 2000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffffc000000000000000000000000000 +B = 4000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffff8000000000000000000000000000 +B = 8000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffff0000000000000000000000000000 +B = 10000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffe0000000000000000000000000000 +B = 20000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffffc0000000000000000000000000000 +B = 40000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffff80000000000000000000000000000 +B = 80000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffff00000000000000000000000000000 +B = 100000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffe00000000000000000000000000000 +B = 200000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffffc00000000000000000000000000000 +B = 400000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffff800000000000000000000000000000 +B = 800000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffff000000000000000000000000000000 +B = 1000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffe000000000000000000000000000000 +B = 2000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffffc000000000000000000000000000000 +B = 4000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffff8000000000000000000000000000000 +B = 8000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffff0000000000000000000000000000000 +B = 10000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffe0000000000000000000000000000000 +B = 20000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffffc0000000000000000000000000000000 +B = 40000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffff80000000000000000000000000000000 +B = 80000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffff00000000000000000000000000000000 +B = 100000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffe00000000000000000000000000000000 +B = 200000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffffc00000000000000000000000000000000 +B = 400000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffff800000000000000000000000000000000 +B = 800000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffff000000000000000000000000000000000 +B = 1000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffe000000000000000000000000000000000 +B = 2000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffffc000000000000000000000000000000000 +B = 4000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffff8000000000000000000000000000000000 +B = 8000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffff0000000000000000000000000000000000 +B = 10000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffe0000000000000000000000000000000000 +B = 20000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffffc0000000000000000000000000000000000 +B = 40000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffff80000000000000000000000000000000000 +B = 80000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffff00000000000000000000000000000000000 +B = 100000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffe00000000000000000000000000000000000 +B = 200000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffffc00000000000000000000000000000000000 +B = 400000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffff800000000000000000000000000000000000 +B = 800000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffff000000000000000000000000000000000000 +B = 1000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffe000000000000000000000000000000000000 +B = 2000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffffc000000000000000000000000000000000000 +B = 4000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffff8000000000000000000000000000000000000 +B = 8000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffff0000000000000000000000000000000000000 +B = 10000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffe0000000000000000000000000000000000000 +B = 20000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffffc0000000000000000000000000000000000000 +B = 40000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffff80000000000000000000000000000000000000 +B = 80000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffff00000000000000000000000000000000000000 +B = 100000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffe00000000000000000000000000000000000000 +B = 200000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffffc00000000000000000000000000000000000000 +B = 400000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffff800000000000000000000000000000000000000 +B = 800000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffff000000000000000000000000000000000000000 +B = 1000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffe000000000000000000000000000000000000000 +B = 2000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffffc000000000000000000000000000000000000000 +B = 4000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffff8000000000000000000000000000000000000000 +B = 8000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffff0000000000000000000000000000000000000000 +B = 10000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffe0000000000000000000000000000000000000000 +B = 20000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffffc0000000000000000000000000000000000000000 +B = 40000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffff80000000000000000000000000000000000000000 +B = 80000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffff00000000000000000000000000000000000000000 +B = 100000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffe00000000000000000000000000000000000000000 +B = 200000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffffc00000000000000000000000000000000000000000 +B = 400000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffff800000000000000000000000000000000000000000 +B = 800000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffff000000000000000000000000000000000000000000 +B = 1000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffe000000000000000000000000000000000000000000 +B = 2000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffffc000000000000000000000000000000000000000000 +B = 4000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffff8000000000000000000000000000000000000000000 +B = 8000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffff0000000000000000000000000000000000000000000 +B = 10000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffe0000000000000000000000000000000000000000000 +B = 20000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffffc0000000000000000000000000000000000000000000 +B = 40000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffff80000000000000000000000000000000000000000000 +B = 80000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffff00000000000000000000000000000000000000000000 +B = 100000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffe00000000000000000000000000000000000000000000 +B = 200000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffffc00000000000000000000000000000000000000000000 +B = 400000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffff800000000000000000000000000000000000000000000 +B = 800000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffff000000000000000000000000000000000000000000000 +B = 1000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffe000000000000000000000000000000000000000000000 +B = 2000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffffc000000000000000000000000000000000000000000000 +B = 4000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffff8000000000000000000000000000000000000000000000 +B = 8000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffff0000000000000000000000000000000000000000000000 +B = 10000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffe0000000000000000000000000000000000000000000000 +B = 20000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fffc0000000000000000000000000000000000000000000000 +B = 40000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fff80000000000000000000000000000000000000000000000 +B = 80000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fff00000000000000000000000000000000000000000000000 +B = 100000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffe00000000000000000000000000000000000000000000000 +B = 200000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ffc00000000000000000000000000000000000000000000000 +B = 400000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ff800000000000000000000000000000000000000000000000 +B = 800000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = ff000000000000000000000000000000000000000000000000 +B = 1000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fe000000000000000000000000000000000000000000000000 +B = 2000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = fc000000000000000000000000000000000000000000000000 +B = 4000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = f8000000000000000000000000000000000000000000000000 +B = 8000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = f0000000000000000000000000000000000000000000000000 +B = 10000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = e0000000000000000000000000000000000000000000000000 +B = 20000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = c0000000000000000000000000000000000000000000000000 +B = 40000000000000000000000000000000000000000000000000 + +Sum = 100000000000000000000000000000000000000000000000000 +A = 80000000000000000000000000000000000000000000000000 +B = 80000000000000000000000000000000000000000000000000 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/aead.c b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/aead.c index 8d2ad048..97f0b0df 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/aead.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/aead.c @@ -51,6 +51,9 @@ EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key, } void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) { + if (ctx == NULL) { + return; + } EVP_AEAD_CTX_cleanup(ctx); OPENSSL_free(ctx); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/cipher.c b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/cipher.c index 64ee544a..18b5e0a5 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/cipher.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/cipher.c @@ -65,6 +65,7 @@ #include #include "internal.h" +#include "../service_indicator/internal.h" #include "../../internal.h" @@ -103,6 +104,11 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { return 0; } + if (in->poisoned) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + EVP_CIPHER_CTX_cleanup(out); OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX)); @@ -110,7 +116,6 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); if (!out->cipher_data) { out->cipher = NULL; - OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); @@ -159,7 +164,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); if (!ctx->cipher_data) { ctx->cipher = NULL; - OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -225,6 +229,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->buf_len = 0; ctx->final_used = 0; + // Clear the poisoned flag to permit re-use of a CTX that previously had a + // failed operation. + ctx->poisoned = 0; return 1; } @@ -249,6 +256,15 @@ static int block_remainder(const EVP_CIPHER_CTX *ctx, int len) { int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len) { + if (ctx->poisoned) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + // If the first call to |cipher| succeeds and the second fails, |ctx| may be + // left in an indeterminate state. We set a poison flag on failure to ensure + // callers do not continue to use the object in that case. + ctx->poisoned = 1; + // Ciphers that use blocks may write up to |bl| extra bytes. Ensure the output // does not overflow |*out_len|. int bl = ctx->cipher->block_size; @@ -264,17 +280,23 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, } else { *out_len = ret; } + ctx->poisoned = 0; return 1; } if (in_len <= 0) { *out_len = 0; - return in_len == 0; + if (in_len == 0) { + ctx->poisoned = 0; + return 1; + } + return 0; } if (ctx->buf_len == 0 && block_remainder(ctx, in_len) == 0) { if (ctx->cipher->cipher(ctx, out, in, in_len)) { *out_len = in_len; + ctx->poisoned = 0; return 1; } else { *out_len = 0; @@ -289,6 +311,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, OPENSSL_memcpy(&ctx->buf[i], in, in_len); ctx->buf_len += in_len; *out_len = 0; + ctx->poisoned = 0; return 1; } else { int j = bl - i; @@ -318,28 +341,36 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, OPENSSL_memcpy(ctx->buf, &in[in_len], i); } ctx->buf_len = i; + ctx->poisoned = 0; return 1; } int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { - int n, ret; + int n; unsigned int i, b, bl; + if (ctx->poisoned) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - ret = ctx->cipher->cipher(ctx, out, NULL, 0); - if (ret < 0) { + // When EVP_CIPH_FLAG_CUSTOM_CIPHER is set, the return value of |cipher| is + // the number of bytes written, or -1 on error. Otherwise the return value + // is one on success and zero on error. + const int num_bytes = ctx->cipher->cipher(ctx, out, NULL, 0); + if (num_bytes < 0) { return 0; - } else { - *out_len = ret; } - return 1; + *out_len = num_bytes; + goto out; } b = ctx->cipher->block_size; assert(b <= sizeof(ctx->buf)); if (b == 1) { *out_len = 0; - return 1; + goto out; } bl = ctx->buf_len; @@ -349,24 +380,30 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { return 0; } *out_len = 0; - return 1; + goto out; } n = b - bl; for (i = bl; i < b; i++) { ctx->buf[i] = n; } - ret = ctx->cipher->cipher(ctx, out, ctx->buf, b); - - if (ret) { - *out_len = b; + if (!ctx->cipher->cipher(ctx, out, ctx->buf, b)) { + return 0; } + *out_len = b; - return ret; +out: + EVP_Cipher_verify_service_indicator(ctx); + return 1; } int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len) { + if (ctx->poisoned) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + // Ciphers that use blocks may write up to |bl| extra bytes. Ensure the output // does not overflow |*out_len|. unsigned int b = ctx->cipher->block_size; @@ -429,6 +466,11 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { unsigned int b; *out_len = 0; + if (ctx->poisoned) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { i = ctx->cipher->cipher(ctx, out, NULL, 0); if (i < 0) { @@ -436,7 +478,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { } else { *out_len = i; } - return 1; + goto out; } b = ctx->cipher->block_size; @@ -446,7 +488,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { return 0; } *out_len = 0; - return 1; + goto out; } if (b > 1) { @@ -480,12 +522,30 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { *out_len = 0; } +out: + EVP_Cipher_verify_service_indicator(ctx); return 1; } int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { - return ctx->cipher->cipher(ctx, out, in, in_len); + const int ret = ctx->cipher->cipher(ctx, out, in, in_len); + + // |EVP_CIPH_FLAG_CUSTOM_CIPHER| never sets the FIPS indicator via + // |EVP_Cipher| because it's complicated whether the operation has completed + // or not. E.g. AES-GCM with a non-NULL |in| argument hasn't completed an + // operation. Callers should use the |EVP_AEAD| API or, at least, + // |EVP_CipherUpdate| etc. + // + // This call can't be pushed into |EVP_Cipher_verify_service_indicator| + // because whether |ret| indicates success or not depends on whether + // |EVP_CIPH_FLAG_CUSTOM_CIPHER| is set. (This unreasonable, but matches + // OpenSSL.) + if (!(ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) && ret) { + EVP_Cipher_verify_service_indicator(ctx); + } + + return ret; } int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aes.c b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aes.c index 76f40663..0db77b84 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aes.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aes.c @@ -47,12 +47,12 @@ * ==================================================================== */ #include +#include #include #include #include #include -#include #include #include #include @@ -62,6 +62,7 @@ #include "../../internal.h" #include "../aes/internal.h" #include "../modes/internal.h" +#include "../service_indicator/internal.h" #include "../delocate.h" @@ -99,16 +100,13 @@ static void vpaes_ctr32_encrypt_blocks_with_bsaes(const uint8_t *in, out += 16 * bsaes_blocks; blocks -= bsaes_blocks; - union { - uint32_t u32[4]; - uint8_t u8[16]; - } new_ivec; - memcpy(new_ivec.u8, ivec, 16); - uint32_t ctr = CRYPTO_bswap4(new_ivec.u32[3]) + bsaes_blocks; - new_ivec.u32[3] = CRYPTO_bswap4(ctr); + uint8_t new_ivec[16]; + memcpy(new_ivec, ivec, 12); + uint32_t ctr = CRYPTO_load_u32_be(ivec + 12) + bsaes_blocks; + CRYPTO_store_u32_be(new_ivec + 12, ctr); // Finish any remaining blocks with |vpaes_ctr32_encrypt_blocks|. - vpaes_ctr32_encrypt_blocks(in, out, blocks, key, new_ivec.u8); + vpaes_ctr32_encrypt_blocks(in, out, blocks, key, new_ivec); } #endif // BSAES @@ -292,8 +290,10 @@ static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, block128_f *out_block, const uint8_t *key, size_t key_bytes) { + // This function assumes the key length was previously validated. + assert(key_bytes == 128 / 8 || key_bytes == 192 / 8 || key_bytes == 256 / 8); if (hwaes_capable()) { - aes_hw_set_encrypt_key(key, key_bytes * 8, aes_key); + aes_hw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); if (gcm_key != NULL) { CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_hw_encrypt, 1); } @@ -304,7 +304,7 @@ ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, } if (vpaes_capable()) { - vpaes_set_encrypt_key(key, key_bytes * 8, aes_key); + vpaes_set_encrypt_key(key, (int)key_bytes * 8, aes_key); if (out_block) { *out_block = vpaes_encrypt; } @@ -321,7 +321,7 @@ ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, #endif } - aes_nohw_set_encrypt_key(key, key_bytes * 8, aes_key); + aes_nohw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); if (gcm_key != NULL) { CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_nohw_encrypt, 0); } @@ -338,11 +338,9 @@ ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, #endif static EVP_AES_GCM_CTX *aes_gcm_from_cipher_ctx(EVP_CIPHER_CTX *ctx) { -#if defined(__GNUC__) || defined(__clang__) - OPENSSL_STATIC_ASSERT( + static_assert( alignof(EVP_AES_GCM_CTX) <= 16, "EVP_AES_GCM_CTX needs more alignment than this function provides"); -#endif // |malloc| guarantees up to 4-byte alignment on 32-bit and 8-byte alignment // on 64-bit systems, so we need to adjust to reach 16-byte alignment. @@ -486,8 +484,13 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { if (arg) { OPENSSL_memcpy(gctx->iv, ptr, arg); } - if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) { - return 0; + if (c->encrypt) { + // |RAND_bytes| calls within the fipsmodule should be wrapped with state + // lock functions to avoid updating the service indicator with the DRBG + // functions. + FIPS_service_indicator_lock_state(); + RAND_bytes(gctx->iv + arg, gctx->ivlen - arg); + FIPS_service_indicator_unlock_state(); } gctx->iv_gen = 1; return 1; @@ -526,11 +529,10 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { if (gctx->iv == c->iv) { gctx_out->iv = out->iv; } else { - gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + gctx_out->iv = OPENSSL_memdup(gctx->iv, gctx->ivlen); if (!gctx_out->iv) { return 0; } - OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); } return 1; } @@ -552,6 +554,14 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, return -1; } + if (len > INT_MAX) { + // This function signature can only express up to |INT_MAX| bytes encrypted. + // + // TODO(https://crbug.com/boringssl/494): Make the internal |EVP_CIPHER| + // calling convention |size_t|-clean. + return -1; + } + if (in) { if (out == NULL) { if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) { @@ -580,7 +590,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } } } - return len; + return (int)len; } else { if (!ctx->encrypt) { if (gctx->taglen < 0 || @@ -598,7 +608,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, } } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_128_cbc) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_128_cbc; @@ -611,7 +621,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) { out->cipher = aes_cbc_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_128_ctr) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_128_ctr; @@ -636,7 +646,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) { out->cipher = aes_ecb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_128_ofb) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_128_ofb128; @@ -649,7 +659,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) { out->cipher = aes_ofb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_128_gcm) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_128_gcm; @@ -666,7 +676,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) { out->ctrl = aes_gcm_ctrl; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_192_cbc) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_192_cbc; @@ -679,7 +689,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) { out->cipher = aes_cbc_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_192_ctr) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_192_ctr; @@ -704,7 +714,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) { out->cipher = aes_ecb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ofb_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_192_ofb) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_192_ofb128; @@ -717,7 +727,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ofb_generic) { out->cipher = aes_ofb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_192_gcm) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_192_gcm; @@ -734,7 +744,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) { out->ctrl = aes_gcm_ctrl; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_256_cbc) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_256_cbc; @@ -747,7 +757,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) { out->cipher = aes_cbc_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_256_ctr) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_256_ctr; @@ -772,7 +782,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) { out->cipher = aes_ecb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_256_ofb) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_256_ofb128; @@ -785,7 +795,7 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) { out->cipher = aes_ofb_cipher; } -DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) { +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_aes_256_gcm) { memset(out, 0, sizeof(EVP_CIPHER)); out->nid = NID_aes_256_gcm; @@ -870,26 +880,6 @@ DEFINE_LOCAL_DATA(EVP_CIPHER, aes_hw_256_ecb) { #endif // HWAES_ECB -#define EVP_CIPHER_FUNCTION(keybits, mode) \ - const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ - return aes_##keybits##_##mode##_generic(); \ - } - -EVP_CIPHER_FUNCTION(128, cbc) -EVP_CIPHER_FUNCTION(128, ctr) -EVP_CIPHER_FUNCTION(128, ofb) -EVP_CIPHER_FUNCTION(128, gcm) - -EVP_CIPHER_FUNCTION(192, cbc) -EVP_CIPHER_FUNCTION(192, ctr) -EVP_CIPHER_FUNCTION(192, ofb) -EVP_CIPHER_FUNCTION(192, gcm) - -EVP_CIPHER_FUNCTION(256, cbc) -EVP_CIPHER_FUNCTION(256, ctr) -EVP_CIPHER_FUNCTION(256, ofb) -EVP_CIPHER_FUNCTION(256, gcm) - EVP_ECB_CIPHER_FUNCTION(128) EVP_ECB_CIPHER_FUNCTION(192) EVP_ECB_CIPHER_FUNCTION(256) @@ -941,14 +931,12 @@ static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, return 1; } -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_gcm_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_gcm_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_ctx), + "AEAD state has insufficient alignment"); static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t requested_tag_len) { @@ -1100,9 +1088,14 @@ static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len) { struct aead_aes_gcm_ctx *gcm_ctx = (struct aead_aes_gcm_ctx *)&ctx->state; - return aead_aes_gcm_open_gather_impl(gcm_ctx, out, nonce, nonce_len, in, - in_len, in_tag, in_tag_len, ad, ad_len, - ctx->tag_len); + if (!aead_aes_gcm_open_gather_impl(gcm_ctx, out, nonce, nonce_len, in, in_len, + in_tag, in_tag_len, ad, ad_len, + ctx->tag_len)) { + return 0; + } + + AEAD_GCM_verify_service_indicator(ctx); + return 1; } DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) { @@ -1187,7 +1180,12 @@ static int aead_aes_gcm_seal_scatter_randnonce( return 0; } + // |RAND_bytes| calls within the fipsmodule should be wrapped with state lock + // functions to avoid updating the service indicator with the DRBG functions. + FIPS_service_indicator_lock_state(); RAND_bytes(nonce, sizeof(nonce)); + FIPS_service_indicator_unlock_state(); + const struct aead_aes_gcm_ctx *gcm_ctx = (const struct aead_aes_gcm_ctx *)&ctx->state; if (!aead_aes_gcm_seal_scatter_impl(gcm_ctx, out, out_tag, out_tag_len, @@ -1202,6 +1200,7 @@ static int aead_aes_gcm_seal_scatter_randnonce( memcpy(out_tag + *out_tag_len, nonce, sizeof(nonce)); *out_tag_len += sizeof(nonce); + AEAD_GCM_verify_service_indicator(ctx); return 1; } @@ -1224,10 +1223,15 @@ static int aead_aes_gcm_open_gather_randnonce( const struct aead_aes_gcm_ctx *gcm_ctx = (const struct aead_aes_gcm_ctx *)&ctx->state; - return aead_aes_gcm_open_gather_impl( + if (!aead_aes_gcm_open_gather_impl( gcm_ctx, out, nonce, AES_GCM_NONCE_LENGTH, in, in_len, in_tag, in_tag_len - AES_GCM_NONCE_LENGTH, ad, ad_len, - ctx->tag_len - AES_GCM_NONCE_LENGTH); + ctx->tag_len - AES_GCM_NONCE_LENGTH)) { + return 0; + } + + AEAD_GCM_verify_service_indicator(ctx); + return 1; } DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_randnonce) { @@ -1265,14 +1269,12 @@ struct aead_aes_gcm_tls12_ctx { uint64_t min_next_nonce; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_gcm_tls12_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_gcm_tls12_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_tls12_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_tls12_ctx), + "AEAD state has insufficient alignment"); static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t requested_tag_len) { @@ -1305,21 +1307,23 @@ static int aead_aes_gcm_tls12_seal_scatter( } // The given nonces must be strictly monotonically increasing. - uint64_t given_counter; - OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), - sizeof(given_counter)); - given_counter = CRYPTO_bswap8(given_counter); - if (given_counter == UINT64_MAX || - given_counter < gcm_ctx->min_next_nonce) { + uint64_t given_counter = + CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t)); + if (given_counter == UINT64_MAX || given_counter < gcm_ctx->min_next_nonce) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); return 0; } gcm_ctx->min_next_nonce = given_counter + 1; - return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, - max_out_tag_len, nonce, nonce_len, in, - in_len, extra_in, extra_in_len, ad, ad_len); + if (!aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, in_len, + extra_in, extra_in_len, ad, ad_len)) { + return 0; + } + + AEAD_GCM_verify_service_indicator(ctx); + return 1; } DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls12) { @@ -1359,14 +1363,12 @@ struct aead_aes_gcm_tls13_ctx { uint8_t first; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_gcm_tls13_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_gcm_tls13_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_gcm_tls13_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_gcm_tls13_ctx), + "AEAD state has insufficient alignment"); static int aead_aes_gcm_tls13_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t requested_tag_len) { @@ -1402,10 +1404,8 @@ static int aead_aes_gcm_tls13_seal_scatter( // The given nonces must be strictly monotonically increasing. See // https://tools.ietf.org/html/rfc8446#section-5.3 for details of the TLS 1.3 // nonce construction. - uint64_t given_counter; - OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), - sizeof(given_counter)); - given_counter = CRYPTO_bswap8(given_counter); + uint64_t given_counter = + CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t)); if (gcm_ctx->first) { // In the first call the sequence number will be zero and therefore the @@ -1423,9 +1423,14 @@ static int aead_aes_gcm_tls13_seal_scatter( gcm_ctx->min_next_nonce = given_counter + 1; - return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, - max_out_tag_len, nonce, nonce_len, in, - in_len, extra_in, extra_in_len, ad, ad_len); + if (!aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, in_len, + extra_in, extra_in_len, ad, ad_len)) { + return 0; + } + + AEAD_GCM_verify_service_indicator(ctx); + return 1; } DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls13) { @@ -1463,8 +1468,6 @@ int EVP_has_aes_hardware(void) { return hwaes_capable() && crypto_gcm_clmul_enabled(); #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable(); -#elif defined(OPENSSL_PPC64LE) - return CRYPTO_is_PPC64LE_vcrypto_capable(); #else return 0; #endif diff --git a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesccm.c b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aesccm.c similarity index 88% rename from third_party/boringssl/kit/src/crypto/cipher_extra/e_aesccm.c rename to third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aesccm.c index e9e9e16e..c00bf61e 100644 --- a/third_party/boringssl/kit/src/crypto/cipher_extra/e_aesccm.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/e_aesccm.c @@ -50,12 +50,13 @@ #include -#include #include #include #include -#include "../fipsmodule/cipher/internal.h" +#include "../delocate.h" +#include "../service_indicator/internal.h" +#include "internal.h" struct ccm128_context { @@ -275,14 +276,12 @@ struct aead_aes_ccm_ctx { struct ccm128_context ccm; }; -OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= - sizeof(struct aead_aes_ccm_ctx), - "AEAD state is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(union evp_aead_ctx_st_state) >= - alignof(struct aead_aes_ccm_ctx), - "AEAD state has insufficient alignment"); -#endif +static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >= + sizeof(struct aead_aes_ccm_ctx), + "AEAD state is too small"); +static_assert(alignof(union evp_aead_ctx_st_state) >= + alignof(struct aead_aes_ccm_ctx), + "AEAD state has insufficient alignment"); static int aead_aes_ccm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, unsigned M, @@ -351,6 +350,7 @@ static int aead_aes_ccm_seal_scatter( } *out_tag_len = ctx->tag_len; + AEAD_CCM_verify_service_indicator(ctx); return 1; } @@ -391,6 +391,7 @@ static int aead_aes_ccm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, return 0; } + AEAD_CCM_verify_service_indicator(ctx); return 1; } @@ -399,25 +400,18 @@ static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key, return aead_aes_ccm_init(ctx, key, key_len, tag_len, 4, 2); } -static const EVP_AEAD aead_aes_128_ccm_bluetooth = { - 16, // key length (AES-128) - 13, // nonce length - 4, // overhead - 4, // max tag length - 0, // seal_scatter_supports_extra_in +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_ccm_bluetooth) { + memset(out, 0, sizeof(EVP_AEAD)); - aead_aes_ccm_bluetooth_init, - NULL /* init_with_direction */, - aead_aes_ccm_cleanup, - NULL /* open */, - aead_aes_ccm_seal_scatter, - aead_aes_ccm_open_gather, - NULL /* get_iv */, - NULL /* tag_len */, -}; + out->key_len = 16; + out->nonce_len = 13; + out->overhead = 4; + out->max_tag_len = 4; -const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void) { - return &aead_aes_128_ccm_bluetooth; + out->init = aead_aes_ccm_bluetooth_init; + out->cleanup = aead_aes_ccm_cleanup; + out->seal_scatter = aead_aes_ccm_seal_scatter; + out->open_gather = aead_aes_ccm_open_gather; } static int aead_aes_ccm_bluetooth_8_init(EVP_AEAD_CTX *ctx, const uint8_t *key, @@ -425,23 +419,35 @@ static int aead_aes_ccm_bluetooth_8_init(EVP_AEAD_CTX *ctx, const uint8_t *key, return aead_aes_ccm_init(ctx, key, key_len, tag_len, 8, 2); } -static const EVP_AEAD aead_aes_128_ccm_bluetooth_8 = { - 16, // key length (AES-128) - 13, // nonce length - 8, // overhead - 8, // max tag length - 0, // seal_scatter_supports_extra_in +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_ccm_bluetooth_8) { + memset(out, 0, sizeof(EVP_AEAD)); - aead_aes_ccm_bluetooth_8_init, - NULL /* init_with_direction */, - aead_aes_ccm_cleanup, - NULL /* open */, - aead_aes_ccm_seal_scatter, - aead_aes_ccm_open_gather, - NULL /* get_iv */, - NULL /* tag_len */, -}; + out->key_len = 16; + out->nonce_len = 13; + out->overhead = 8; + out->max_tag_len = 8; -const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void) { - return &aead_aes_128_ccm_bluetooth_8; + out->init = aead_aes_ccm_bluetooth_8_init; + out->cleanup = aead_aes_ccm_cleanup; + out->seal_scatter = aead_aes_ccm_seal_scatter; + out->open_gather = aead_aes_ccm_open_gather; +} + +static int aead_aes_ccm_matter_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 16, 2); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_ccm_matter) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 13; + out->overhead = 16; + out->max_tag_len = 16; + + out->init = aead_aes_ccm_matter_init; + out->cleanup = aead_aes_ccm_cleanup; + out->seal_scatter = aead_aes_ccm_seal_scatter; + out->open_gather = aead_aes_ccm_open_gather; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/internal.h index 68efe33d..6ec9a3b3 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cipher/internal.h @@ -112,6 +112,45 @@ struct evp_aead_st { size_t extra_in_len); }; +struct evp_cipher_st { + // type contains a NID identifying the cipher. (e.g. NID_aes_128_gcm.) + int nid; + + // block_size contains the block size, in bytes, of the cipher, or 1 for a + // stream cipher. + unsigned block_size; + + // key_len contains the key size, in bytes, for the cipher. If the cipher + // takes a variable key size then this contains the default size. + unsigned key_len; + + // iv_len contains the IV size, in bytes, or zero if inapplicable. + unsigned iv_len; + + // ctx_size contains the size, in bytes, of the per-key context for this + // cipher. + unsigned ctx_size; + + // flags contains the OR of a number of flags. See |EVP_CIPH_*|. + uint32_t flags; + + // app_data is a pointer to opaque, user data. + void *app_data; + + int (*init)(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, + int enc); + + int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl); + + // cleanup, if non-NULL, releases memory associated with the context. It is + // called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been + // called at this point. + void (*cleanup)(EVP_CIPHER_CTX *); + + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); +}; + // aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, // where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is // set to a function that encrypts single blocks. If not NULL, |*gcm_key| is diff --git a/third_party/boringssl/kit/src/crypto/cmac/cavp_3des_cmac_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/cmac/cavp_3des_cmac_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/cmac/cavp_aes128_cmac_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/cmac/cavp_aes128_cmac_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/cmac/cavp_aes192_cmac_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/cmac/cavp_aes192_cmac_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/cmac/cavp_aes256_cmac_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/cmac/cavp_aes256_cmac_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/cmac/cmac.c b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac.c similarity index 83% rename from third_party/boringssl/kit/src/crypto/cmac/cmac.c rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac.c index b6a10f79..efffe5f6 100644 --- a/third_party/boringssl/kit/src/crypto/cmac/cmac.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac.c @@ -49,13 +49,15 @@ #include #include +#include #include #include #include #include -#include "../internal.h" +#include "../../internal.h" +#include "../service_indicator/internal.h" struct cmac_ctx_st { @@ -85,6 +87,8 @@ int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, const uint8_t *in, size_t in_len) { const EVP_CIPHER *cipher; switch (key_len) { + // WARNING: this code assumes that all supported key sizes are FIPS + // Approved. case 16: cipher = EVP_aes_128_cbc(); break; @@ -99,10 +103,17 @@ int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, CMAC_CTX ctx; CMAC_CTX_init(&ctx); + // We have to verify that all the CMAC services actually succeed before + // updating the indicator state, so we lock the state here. + FIPS_service_indicator_lock_state(); const int ok = CMAC_Init(&ctx, key, key_len, cipher, NULL /* engine */) && CMAC_Update(&ctx, in, in_len) && CMAC_Final(&ctx, out, &scratch_out_len); + FIPS_service_indicator_unlock_state(); + if (ok) { + FIPS_service_indicator_update_state(); + } CMAC_CTX_cleanup(&ctx); return ok; } @@ -173,8 +184,13 @@ static const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0}; int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, const EVP_CIPHER *cipher, ENGINE *engine) { + int ret = 0; uint8_t scratch[AES_BLOCK_SIZE]; + // We have to avoid the underlying AES-CBC |EVP_CIPHER| services updating the + // indicator state, so we lock the state here. + FIPS_service_indicator_lock_state(); + size_t block_size = EVP_CIPHER_block_size(cipher); if ((block_size != AES_BLOCK_SIZE && block_size != 8 /* 3-DES */) || EVP_CIPHER_key_length(cipher) != key_len || @@ -182,7 +198,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, !EVP_Cipher(&ctx->cipher_ctx, scratch, kZeroIV, block_size) || // Reset context again ready for first data. !EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV)) { - return 0; + goto out; } if (block_size == AES_BLOCK_SIZE) { @@ -193,8 +209,11 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, binary_field_mul_x_64(ctx->k2, ctx->k1); } ctx->block_used = 0; + ret = 1; - return 1; +out: + FIPS_service_indicator_unlock_state(); + return ret; } int CMAC_Reset(CMAC_CTX *ctx) { @@ -203,6 +222,12 @@ int CMAC_Reset(CMAC_CTX *ctx) { } int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) { + int ret = 0; + + // We have to avoid the underlying AES-CBC |EVP_Cipher| services updating the + // indicator state, so we lock the state here. + FIPS_service_indicator_lock_state(); + size_t block_size = EVP_CIPHER_CTX_block_size(&ctx->cipher_ctx); assert(block_size <= AES_BLOCK_SIZE); uint8_t scratch[AES_BLOCK_SIZE]; @@ -224,38 +249,51 @@ int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) { // case we don't want to process this block now because it might be the last // block and that block is treated specially. if (in_len == 0) { - return 1; + ret = 1; + goto out; } assert(ctx->block_used == block_size); if (!EVP_Cipher(&ctx->cipher_ctx, scratch, ctx->block, block_size)) { - return 0; + goto out; } } // Encrypt all but one of the remaining blocks. while (in_len > block_size) { if (!EVP_Cipher(&ctx->cipher_ctx, scratch, in, block_size)) { - return 0; + goto out; } in += block_size; in_len -= block_size; } OPENSSL_memcpy(ctx->block, in, in_len); - ctx->block_used = in_len; + // |in_len| is bounded by |block_size|, which fits in |unsigned|. + static_assert(EVP_MAX_BLOCK_LENGTH < UINT_MAX, + "EVP_MAX_BLOCK_LENGTH is too large"); + ctx->block_used = (unsigned)in_len; + ret = 1; - return 1; +out: + FIPS_service_indicator_unlock_state(); + return ret; } int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) { + int ret = 0; size_t block_size = EVP_CIPHER_CTX_block_size(&ctx->cipher_ctx); assert(block_size <= AES_BLOCK_SIZE); + // We have to avoid the underlying AES-CBC |EVP_Cipher| services updating the + // indicator state, so we lock the state here. + FIPS_service_indicator_lock_state(); + *out_len = block_size; if (out == NULL) { - return 1; + ret = 1; + goto out; } const uint8_t *mask = ctx->k1; @@ -273,6 +311,12 @@ int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) { for (unsigned i = 0; i < block_size; i++) { out[i] = ctx->block[i] ^ mask[i]; } + ret = EVP_Cipher(&ctx->cipher_ctx, out, out, block_size); - return EVP_Cipher(&ctx->cipher_ctx, out, out, block_size); +out: + FIPS_service_indicator_unlock_state(); + if (ret) { + FIPS_service_indicator_update_state(); + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/cmac/cmac_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac_test.cc similarity index 94% rename from third_party/boringssl/kit/src/crypto/cmac/cmac_test.cc rename to third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac_test.cc index e8a220ac..9e3744e0 100644 --- a/third_party/boringssl/kit/src/crypto/cmac/cmac_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/cmac/cmac_test.cc @@ -23,9 +23,9 @@ #include #include -#include "../test/file_test.h" -#include "../test/test_util.h" -#include "../test/wycheproof_util.h" +#include "../../test/file_test.h" +#include "../../test/test_util.h" +#include "../../test/wycheproof_util.h" static void test(const char *name, const uint8_t *key, size_t key_len, @@ -248,20 +248,21 @@ static void RunCAVPTest(const char *path, const EVP_CIPHER *cipher, } TEST(CMACTest, CAVPAES128) { - RunCAVPTest("crypto/cmac/cavp_aes128_cmac_tests.txt", EVP_aes_128_cbc(), - false); + RunCAVPTest("crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt", + EVP_aes_128_cbc(), false); } TEST(CMACTest, CAVPAES192) { - RunCAVPTest("crypto/cmac/cavp_aes192_cmac_tests.txt", EVP_aes_192_cbc(), - false); + RunCAVPTest("crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt", + EVP_aes_192_cbc(), false); } TEST(CMACTest, CAVPAES256) { - RunCAVPTest("crypto/cmac/cavp_aes256_cmac_tests.txt", EVP_aes_256_cbc(), - false); + RunCAVPTest("crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt", + EVP_aes_256_cbc(), false); } TEST(CMACTest, CAVP3DES) { - RunCAVPTest("crypto/cmac/cavp_3des_cmac_tests.txt", EVP_des_ede3_cbc(), true); + RunCAVPTest("crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt", + EVP_des_ede3_cbc(), true); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/delocate.h b/third_party/boringssl/kit/src/crypto/fipsmodule/delocate.h index d6564e48..5890ea88 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/delocate.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/delocate.h @@ -27,9 +27,8 @@ type *name##_bss_get(void) __attribute__((const)); // For FIPS builds we require that CRYPTO_ONCE_INIT be zero. #define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name) -// For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero. -#define DEFINE_STATIC_MUTEX(name) \ - DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name) +// For FIPS builds we require that CRYPTO_MUTEX_INIT be zero. +#define DEFINE_STATIC_MUTEX(name) DEFINE_BSS_GET(CRYPTO_MUTEX, name) // For FIPS builds we require that CRYPTO_EX_DATA_CLASS_INIT be zero. #define DEFINE_STATIC_EX_DATA_CLASS(name) \ DEFINE_BSS_GET(CRYPTO_EX_DATA_CLASS, name) @@ -40,9 +39,9 @@ #define DEFINE_STATIC_ONCE(name) \ static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \ static CRYPTO_once_t *name##_bss_get(void) { return &name; } -#define DEFINE_STATIC_MUTEX(name) \ - static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \ - static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_MUTEX(name) \ + static CRYPTO_MUTEX name = CRYPTO_MUTEX_INIT; \ + static CRYPTO_MUTEX *name##_bss_get(void) { return &name; } #define DEFINE_STATIC_EX_DATA_CLASS(name) \ static CRYPTO_EX_DATA_CLASS name = CRYPTO_EX_DATA_CLASS_INIT; \ static CRYPTO_EX_DATA_CLASS *name##_bss_get(void) { return &name; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/dh/check.c b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/check.c index 5b6e03a5..0c82c17f 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/dh/check.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/check.c @@ -58,6 +58,8 @@ #include +#include "internal.h" + int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) { *out_flags = 0; @@ -165,9 +167,6 @@ int DH_check(const DH *dh, int *out_flags) { if (!BN_is_one(t2)) { *out_flags |= DH_CHECK_INVALID_Q_VALUE; } - if (dh->j && BN_cmp(dh->j, t1)) { - *out_flags |= DH_CHECK_INVALID_J_VALUE; - } } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { l = BN_mod_word(dh->p, 24); if (l == (BN_ULONG)-1) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/dh/dh.c b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/dh.c index ab596e9d..80940fdb 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/dh/dh.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/dh.c @@ -66,6 +66,8 @@ #include "../../internal.h" #include "../bn/internal.h" +#include "../service_indicator/internal.h" +#include "internal.h" #define OPENSSL_DH_MAX_MODULUS_BITS 10000 @@ -73,7 +75,6 @@ DH *DH_new(void) { DH *dh = OPENSSL_malloc(sizeof(DH)); if (dh == NULL) { - OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); return NULL; } @@ -99,9 +100,6 @@ void DH_free(DH *dh) { BN_clear_free(dh->p); BN_clear_free(dh->g); BN_clear_free(dh->q); - BN_clear_free(dh->j); - OPENSSL_free(dh->seed); - BN_clear_free(dh->counter); BN_clear_free(dh->pub_key); BN_clear_free(dh->priv_key); CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); @@ -109,6 +107,8 @@ void DH_free(DH *dh) { OPENSSL_free(dh); } +unsigned DH_bits(const DH *dh) { return BN_num_bits(dh->p); } + const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; } const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; } @@ -177,6 +177,9 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { dh->g = g; } + // Invalidate the cached Montgomery parameters. + BN_MONT_CTX_free(dh->method_mont_p); + dh->method_mont_p = NULL; return 1; } @@ -186,6 +189,8 @@ int DH_set_length(DH *dh, unsigned priv_length) { } int DH_generate_key(DH *dh) { + boringssl_ensure_ffdh_self_test(); + int ok = 0; int generate_new_key = 0; BN_CTX *ctx = NULL; @@ -322,7 +327,8 @@ static int dh_compute_key(DH *dh, BIGNUM *out_shared_key, return ret; } -int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { +int dh_compute_key_padded_no_self_test(unsigned char *out, + const BIGNUM *peers_key, DH *dh) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { return -1; @@ -343,7 +349,15 @@ int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { return ret; } +int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + boringssl_ensure_ffdh_self_test(); + + return dh_compute_key_padded_no_self_test(out, peers_key, dh); +} + int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + boringssl_ensure_ffdh_self_test(); + BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { return -1; @@ -353,7 +367,8 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { int ret = -1; BIGNUM *shared_key = BN_CTX_get(ctx); if (shared_key && dh_compute_key(dh, shared_key, peers_key, ctx)) { - ret = BN_bn2bin(shared_key, out); + // A |BIGNUM|'s byte count fits in |int|. + ret = (int)BN_bn2bin(shared_key, out); } BN_CTX_end(ctx); @@ -371,6 +386,8 @@ int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, return 0; } + FIPS_service_indicator_lock_state(); + int ret = 0; const size_t dh_len = DH_size(dh); uint8_t *shared_bytes = OPENSSL_malloc(dh_len); @@ -392,6 +409,7 @@ int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, ret = 1; err: + FIPS_service_indicator_unlock_state(); OPENSSL_free(shared_bytes); return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/dh/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/internal.h new file mode 100644 index 00000000..fe7fda4e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/dh/internal.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct dh_st { + BIGNUM *p; + BIGNUM *g; + BIGNUM *q; + BIGNUM *pub_key; // g^x mod p + BIGNUM *priv_key; // x + + // priv_length contains the length, in bits, of the private value. If zero, + // the private value will be the same length as |p|. + unsigned priv_length; + + CRYPTO_MUTEX method_mont_p_lock; + BN_MONT_CTX *method_mont_p; + + int flags; + CRYPTO_refcount_t references; +}; + +// dh_compute_key_padded_no_self_test does the same as |DH_compute_key_padded|, +// but doesn't try to run the self-test first. This is for use in the self tests +// themselves, to prevent an infinite loop. +int dh_compute_key_padded_no_self_test(unsigned char *out, + const BIGNUM *peers_key, DH *dh); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_DH_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/digest/digest.c b/third_party/boringssl/kit/src/crypto/fipsmodule/digest/digest.c index 059d72c3..f499c468 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/digest/digest.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/digest/digest.c @@ -106,6 +106,11 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { return 1; } +void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx) { + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + EVP_MD_CTX_cleanup(ctx); +} + void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { if (!ctx) { return; @@ -139,7 +144,6 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { if (in->pctx) { pctx = in->pctx_ops->dup(in->pctx); if (!pctx) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } } @@ -153,7 +157,6 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { if (pctx) { in->pctx_ops->free(pctx); } - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -202,7 +205,6 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { assert(type->ctx_size != 0); uint8_t *md_data = OPENSSL_malloc(type->ctx_size); if (md_data == NULL) { - OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/evp/digestsign.c b/third_party/boringssl/kit/src/crypto/fipsmodule/digestsign/digestsign.c similarity index 83% rename from third_party/boringssl/kit/src/crypto/evp/digestsign.c rename to third_party/boringssl/kit/src/crypto/fipsmodule/digestsign/digestsign.c index 6e4d305f..e5b6bc76 100644 --- a/third_party/boringssl/kit/src/crypto/evp/digestsign.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/digestsign/digestsign.c @@ -57,8 +57,10 @@ #include -#include "internal.h" -#include "../fipsmodule/digest/internal.h" +#include "../../evp/internal.h" +#include "../delocate.h" +#include "../digest/internal.h" +#include "../service_indicator/internal.h" enum evp_sign_verify_t { @@ -66,9 +68,9 @@ enum evp_sign_verify_t { evp_verify, }; -static const struct evp_md_pctx_ops md_pctx_ops = { - EVP_PKEY_CTX_free, - EVP_PKEY_CTX_dup, +DEFINE_LOCAL_DATA(struct evp_md_pctx_ops, md_pctx_ops) { + out->free = EVP_PKEY_CTX_free; + out->dup = EVP_PKEY_CTX_dup; }; static int uses_prehash(EVP_MD_CTX *ctx, enum evp_sign_verify_t op) { @@ -85,7 +87,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, if (ctx->pctx == NULL) { return 0; } - ctx->pctx_ops = &md_pctx_ops; + ctx->pctx_ops = md_pctx_ops(); if (op == evp_verify) { if (!EVP_PKEY_verify_init(ctx->pctx)) { @@ -159,11 +161,17 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, uint8_t md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + FIPS_service_indicator_lock_state(); EVP_MD_CTX_init(&tmp_ctx); ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); EVP_MD_CTX_cleanup(&tmp_ctx); + FIPS_service_indicator_unlock_state(); + + if (ret) { + EVP_DigestSign_verify_service_indicator(ctx); + } return ret; } else { @@ -184,48 +192,76 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, uint8_t md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + FIPS_service_indicator_lock_state(); EVP_MD_CTX_init(&tmp_ctx); ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + FIPS_service_indicator_unlock_state(); EVP_MD_CTX_cleanup(&tmp_ctx); + if (ret) { + EVP_DigestVerify_verify_service_indicator(ctx); + } + return ret; } int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len, const uint8_t *data, size_t data_len) { + FIPS_service_indicator_lock_state(); + int ret = 0; + if (uses_prehash(ctx, evp_sign)) { // If |out_sig| is NULL, the caller is only querying the maximum output // length. |data| should only be incorporated in the final call. if (out_sig != NULL && !EVP_DigestSignUpdate(ctx, data, data_len)) { - return 0; + goto end; } - return EVP_DigestSignFinal(ctx, out_sig, out_sig_len); + ret = EVP_DigestSignFinal(ctx, out_sig, out_sig_len); + goto end; } if (ctx->pctx->pmeth->sign_message == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return 0; + goto end; } - return ctx->pctx->pmeth->sign_message(ctx->pctx, out_sig, out_sig_len, data, - data_len); + ret = ctx->pctx->pmeth->sign_message(ctx->pctx, out_sig, out_sig_len, data, + data_len); + +end: + FIPS_service_indicator_unlock_state(); + if (ret) { + EVP_DigestSign_verify_service_indicator(ctx); + } + return ret; } int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, const uint8_t *data, size_t len) { + FIPS_service_indicator_lock_state(); + int ret = 0; + if (uses_prehash(ctx, evp_verify)) { - return EVP_DigestVerifyUpdate(ctx, data, len) && - EVP_DigestVerifyFinal(ctx, sig, sig_len); + ret = EVP_DigestVerifyUpdate(ctx, data, len) && + EVP_DigestVerifyFinal(ctx, sig, sig_len); + goto end; } if (ctx->pctx->pmeth->verify_message == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return 0; + goto end; } - return ctx->pctx->pmeth->verify_message(ctx->pctx, sig, sig_len, data, len); + ret = ctx->pctx->pmeth->verify_message(ctx->pctx, sig, sig_len, data, len); + +end: + FIPS_service_indicator_unlock_state(); + if (ret) { + EVP_DigestVerify_verify_service_indicator(ctx); + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl new file mode 100644 index 00000000..95dc4c88 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl @@ -0,0 +1,1676 @@ +#! /usr/bin/env perl +# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# ECP_NISTZ256 module for ARMv8. +# +# February 2015. +# +# Original ECP_NISTZ256 submission targeting x86_64 is detailed in +# http://eprint.iacr.org/2013/816. +# +# with/without -DECP_NISTZ256_ASM +# Apple A7 +190-360% +# Cortex-A53 +190-400% +# Cortex-A57 +190-350% +# Denver +230-400% +# +# Ranges denote minimum and maximum improvement coefficients depending +# on benchmark. Lower coefficients are for ECDSA sign, server-side +# operation. Keep in mind that +400% means 5x improvement. + +# The first two arguments should always be the flavour and output file path. +if ($#ARGV < 1) { die "Not enough arguments provided. + Two arguments are necessary: the flavour and the output file path."; } + +$flavour = shift; +$output = shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +{ +my ($rp,$ap,$bp,$bi,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3,$poly1,$poly3, + $acc0,$acc1,$acc2,$acc3,$acc4,$acc5) = + map("x$_",(0..17,19,20)); + +my ($acc6,$acc7)=($ap,$bp); # used in __ecp_nistz256_sqr_mont + +$code.=<<___; +#include "openssl/arm_arch.h" + +.section .rodata +.align 5 +.Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +.LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +.Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +.Lone: +.quad 1,0,0,0 +.Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +.LordK: +.quad 0xccd1c8aaee00bc4f +.asciz "ECP_NISTZ256 for ARMv8, CRYPTOGAMS by " +.text + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont +.type ecp_nistz256_mul_mont,%function +.align 4 +ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr $bi,[$bp] // bp[0] + ldp $a0,$a1,[$ap] + ldp $a2,$a3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont +.type ecp_nistz256_sqr_mont,%function +.align 4 +ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp $a0,$a1,[$ap] + ldp $a2,$a3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 +.type ecp_nistz256_div_by_2,%function +.align 4 +ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp $acc0,$acc1,[$ap] + ldp $acc2,$acc3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 +.type ecp_nistz256_mul_by_2,%function +.align 4 +ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp $acc0,$acc1,[$ap] + ldp $acc2,$acc3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + mov $t0,$acc0 + mov $t1,$acc1 + mov $t2,$acc2 + mov $t3,$acc3 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 +.type ecp_nistz256_mul_by_3,%function +.align 4 +ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp $acc0,$acc1,[$ap] + ldp $acc2,$acc3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + mov $t0,$acc0 + mov $t1,$acc1 + mov $t2,$acc2 + mov $t3,$acc3 + mov $a0,$acc0 + mov $a1,$acc1 + mov $a2,$acc2 + mov $a3,$acc3 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov $t0,$a0 + mov $t1,$a1 + mov $t2,$a2 + mov $t3,$a3 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub +.type ecp_nistz256_sub,%function +.align 4 +ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp $acc0,$acc1,[$ap] + ldp $acc2,$acc3,[$ap,#16] + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_sub,.-ecp_nistz256_sub + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg +.type ecp_nistz256_neg,%function +.align 4 +ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov $bp,$ap + mov $acc0,xzr // a = 0 + mov $acc1,xzr + mov $acc2,xzr + mov $acc3,xzr + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_neg,.-ecp_nistz256_neg + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to $a0-$a3 and b[0] - to $bi +.type __ecp_nistz256_mul_mont,%function +.align 4 +__ecp_nistz256_mul_mont: + mul $acc0,$a0,$bi // a[0]*b[0] + umulh $t0,$a0,$bi + + mul $acc1,$a1,$bi // a[1]*b[0] + umulh $t1,$a1,$bi + + mul $acc2,$a2,$bi // a[2]*b[0] + umulh $t2,$a2,$bi + + mul $acc3,$a3,$bi // a[3]*b[0] + umulh $t3,$a3,$bi + ldr $bi,[$bp,#8] // b[1] + + adds $acc1,$acc1,$t0 // accumulate high parts of multiplication + lsl $t0,$acc0,#32 + adcs $acc2,$acc2,$t1 + lsr $t1,$acc0,#32 + adcs $acc3,$acc3,$t2 + adc $acc4,xzr,$t3 + mov $acc5,xzr +___ +for($i=1;$i<4;$i++) { + # Reduction iteration is normally performed by accumulating + # result of multiplication of modulus by "magic" digit [and + # omitting least significant word, which is guaranteed to + # be 0], but thanks to special form of modulus and "magic" + # digit being equal to least significant word, it can be + # performed with additions and subtractions alone. Indeed: + # + # ffff0001.00000000.0000ffff.ffffffff + # * abcdefgh + # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh + # + # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we + # rewrite above as: + # + # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh + # + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000 + # - 0000abcd.efgh0000.00000000.00000000.abcdefgh + # + # or marking redundant operations: + # + # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.-------- + # + abcdefgh.abcdefgh.0000abcd.efgh0000.-------- + # - 0000abcd.efgh0000.--------.--------.-------- + +$code.=<<___; + subs $t2,$acc0,$t0 // "*0xffff0001" + sbc $t3,$acc0,$t1 + adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0] + mul $t0,$a0,$bi // lo(a[0]*b[i]) + adcs $acc1,$acc2,$t1 + mul $t1,$a1,$bi // lo(a[1]*b[i]) + adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001 + mul $t2,$a2,$bi // lo(a[2]*b[i]) + adcs $acc3,$acc4,$t3 + mul $t3,$a3,$bi // lo(a[3]*b[i]) + adc $acc4,$acc5,xzr + + adds $acc0,$acc0,$t0 // accumulate low parts of multiplication + umulh $t0,$a0,$bi // hi(a[0]*b[i]) + adcs $acc1,$acc1,$t1 + umulh $t1,$a1,$bi // hi(a[1]*b[i]) + adcs $acc2,$acc2,$t2 + umulh $t2,$a2,$bi // hi(a[2]*b[i]) + adcs $acc3,$acc3,$t3 + umulh $t3,$a3,$bi // hi(a[3]*b[i]) + adc $acc4,$acc4,xzr +___ +$code.=<<___ if ($i<3); + ldr $bi,[$bp,#8*($i+1)] // b[$i+1] +___ +$code.=<<___; + adds $acc1,$acc1,$t0 // accumulate high parts of multiplication + lsl $t0,$acc0,#32 + adcs $acc2,$acc2,$t1 + lsr $t1,$acc0,#32 + adcs $acc3,$acc3,$t2 + adcs $acc4,$acc4,$t3 + adc $acc5,xzr,xzr +___ +} +$code.=<<___; + // last reduction + subs $t2,$acc0,$t0 // "*0xffff0001" + sbc $t3,$acc0,$t1 + adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0] + adcs $acc1,$acc2,$t1 + adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001 + adcs $acc3,$acc4,$t3 + adc $acc4,$acc5,xzr + + adds $t0,$acc0,#1 // subs $t0,$acc0,#-1 // tmp = ret-modulus + sbcs $t1,$acc1,$poly1 + sbcs $t2,$acc2,xzr + sbcs $t3,$acc3,$poly3 + sbcs xzr,$acc4,xzr // did it borrow? + + csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus + csel $acc1,$acc1,$t1,lo + csel $acc2,$acc2,$t2,lo + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,lo + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to $a0-$a3 +.type __ecp_nistz256_sqr_mont,%function +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul $acc1,$a1,$a0 // a[1]*a[0] + umulh $t1,$a1,$a0 + mul $acc2,$a2,$a0 // a[2]*a[0] + umulh $t2,$a2,$a0 + mul $acc3,$a3,$a0 // a[3]*a[0] + umulh $acc4,$a3,$a0 + + adds $acc2,$acc2,$t1 // accumulate high parts of multiplication + mul $t0,$a2,$a1 // a[2]*a[1] + umulh $t1,$a2,$a1 + adcs $acc3,$acc3,$t2 + mul $t2,$a3,$a1 // a[3]*a[1] + umulh $t3,$a3,$a1 + adc $acc4,$acc4,xzr // can't overflow + + mul $acc5,$a3,$a2 // a[3]*a[2] + umulh $acc6,$a3,$a2 + + adds $t1,$t1,$t2 // accumulate high parts of multiplication + mul $acc0,$a0,$a0 // a[0]*a[0] + adc $t2,$t3,xzr // can't overflow + + adds $acc3,$acc3,$t0 // accumulate low parts of multiplication + umulh $a0,$a0,$a0 + adcs $acc4,$acc4,$t1 + mul $t1,$a1,$a1 // a[1]*a[1] + adcs $acc5,$acc5,$t2 + umulh $a1,$a1,$a1 + adc $acc6,$acc6,xzr // can't overflow + + adds $acc1,$acc1,$acc1 // acc[1-6]*=2 + mul $t2,$a2,$a2 // a[2]*a[2] + adcs $acc2,$acc2,$acc2 + umulh $a2,$a2,$a2 + adcs $acc3,$acc3,$acc3 + mul $t3,$a3,$a3 // a[3]*a[3] + adcs $acc4,$acc4,$acc4 + umulh $a3,$a3,$a3 + adcs $acc5,$acc5,$acc5 + adcs $acc6,$acc6,$acc6 + adc $acc7,xzr,xzr + + adds $acc1,$acc1,$a0 // +a[i]*a[i] + adcs $acc2,$acc2,$t1 + adcs $acc3,$acc3,$a1 + adcs $acc4,$acc4,$t2 + adcs $acc5,$acc5,$a2 + lsl $t0,$acc0,#32 + adcs $acc6,$acc6,$t3 + lsr $t1,$acc0,#32 + adc $acc7,$acc7,$a3 +___ +for($i=0;$i<3;$i++) { # reductions, see commentary in + # multiplication for details +$code.=<<___; + subs $t2,$acc0,$t0 // "*0xffff0001" + sbc $t3,$acc0,$t1 + adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0] + adcs $acc1,$acc2,$t1 + lsl $t0,$acc0,#32 + adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001 + lsr $t1,$acc0,#32 + adc $acc3,$t3,xzr // can't overflow +___ +} +$code.=<<___; + subs $t2,$acc0,$t0 // "*0xffff0001" + sbc $t3,$acc0,$t1 + adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0] + adcs $acc1,$acc2,$t1 + adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001 + adc $acc3,$t3,xzr // can't overflow + + adds $acc0,$acc0,$acc4 // accumulate upper half + adcs $acc1,$acc1,$acc5 + adcs $acc2,$acc2,$acc6 + adcs $acc3,$acc3,$acc7 + adc $acc4,xzr,xzr + + adds $t0,$acc0,#1 // subs $t0,$acc0,#-1 // tmp = ret-modulus + sbcs $t1,$acc1,$poly1 + sbcs $t2,$acc2,xzr + sbcs $t3,$acc3,$poly3 + sbcs xzr,$acc4,xzr // did it borrow? + + csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus + csel $acc1,$acc1,$t1,lo + csel $acc2,$acc2,$t2,lo + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,lo + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// $a0-$a3 and $t0-$t3. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.type __ecp_nistz256_add_to,%function +.align 4 +__ecp_nistz256_add_to: + adds $acc0,$acc0,$t0 // ret = a+b + adcs $acc1,$acc1,$t1 + adcs $acc2,$acc2,$t2 + adcs $acc3,$acc3,$t3 + adc $ap,xzr,xzr // zap $ap + + adds $t0,$acc0,#1 // subs $t0,$a0,#-1 // tmp = ret-modulus + sbcs $t1,$acc1,$poly1 + sbcs $t2,$acc2,xzr + sbcs $t3,$acc3,$poly3 + sbcs xzr,$ap,xzr // did subtraction borrow? + + csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus + csel $acc1,$acc1,$t1,lo + csel $acc2,$acc2,$t2,lo + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,lo + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_add_to,.-__ecp_nistz256_add_to + +.type __ecp_nistz256_sub_from,%function +.align 4 +__ecp_nistz256_sub_from: + ldp $t0,$t1,[$bp] + ldp $t2,$t3,[$bp,#16] + subs $acc0,$acc0,$t0 // ret = a-b + sbcs $acc1,$acc1,$t1 + sbcs $acc2,$acc2,$t2 + sbcs $acc3,$acc3,$t3 + sbc $ap,xzr,xzr // zap $ap + + subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = ret+modulus + adcs $t1,$acc1,$poly1 + adcs $t2,$acc2,xzr + adc $t3,$acc3,$poly3 + cmp $ap,xzr // did subtraction borrow? + + csel $acc0,$acc0,$t0,eq // ret = borrow ? ret+modulus : ret + csel $acc1,$acc1,$t1,eq + csel $acc2,$acc2,$t2,eq + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,eq + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from + +.type __ecp_nistz256_sub_morf,%function +.align 4 +__ecp_nistz256_sub_morf: + ldp $t0,$t1,[$bp] + ldp $t2,$t3,[$bp,#16] + subs $acc0,$t0,$acc0 // ret = b-a + sbcs $acc1,$t1,$acc1 + sbcs $acc2,$t2,$acc2 + sbcs $acc3,$t3,$acc3 + sbc $ap,xzr,xzr // zap $ap + + subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = ret+modulus + adcs $t1,$acc1,$poly1 + adcs $t2,$acc2,xzr + adc $t3,$acc3,$poly3 + cmp $ap,xzr // did subtraction borrow? + + csel $acc0,$acc0,$t0,eq // ret = borrow ? ret+modulus : ret + csel $acc1,$acc1,$t1,eq + csel $acc2,$acc2,$t2,eq + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,eq + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf + +.type __ecp_nistz256_div_by_2,%function +.align 4 +__ecp_nistz256_div_by_2: + subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = a+modulus + adcs $t1,$acc1,$poly1 + adcs $t2,$acc2,xzr + adcs $t3,$acc3,$poly3 + adc $ap,xzr,xzr // zap $ap + tst $acc0,#1 // is a even? + + csel $acc0,$acc0,$t0,eq // ret = even ? a : a+modulus + csel $acc1,$acc1,$t1,eq + csel $acc2,$acc2,$t2,eq + csel $acc3,$acc3,$t3,eq + csel $ap,xzr,$ap,eq + + lsr $acc0,$acc0,#1 // ret >>= 1 + orr $acc0,$acc0,$acc1,lsl#63 + lsr $acc1,$acc1,#1 + orr $acc1,$acc1,$acc2,lsl#63 + lsr $acc2,$acc2,#1 + orr $acc2,$acc2,$acc3,lsl#63 + lsr $acc3,$acc3,#1 + stp $acc0,$acc1,[$rp] + orr $acc3,$acc3,$ap,lsl#63 + stp $acc2,$acc3,[$rp,#16] + + ret +.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 +___ +######################################################################## +# following subroutines are "literal" implementation of those found in +# ecp_nistz256.c +# +######################################################################## +# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp); +# +{ +my ($S,$M,$Zsqr,$tmp0)=map(32*$_,(0..3)); +# above map() describes stack layout with 4 temporary +# 256-bit vectors on top. +my ($rp_real,$ap_real) = map("x$_",(21,22)); + +$code.=<<___; +.globl ecp_nistz256_point_double +.type ecp_nistz256_point_double,%function +.align 5 +ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +.Ldouble_shortcut: + ldp $acc0,$acc1,[$ap,#32] + mov $rp_real,$rp + ldp $acc2,$acc3,[$ap,#48] + mov $ap_real,$ap + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + mov $t0,$acc0 + ldr $poly3,[$poly3,#24] + mov $t1,$acc1 + ldp $a0,$a1,[$ap_real,#64] // forward load for p256_sqr_mont + mov $t2,$acc2 + mov $t3,$acc3 + ldp $a2,$a3,[$ap_real,#64+16] + add $rp,sp,#$S + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add $rp,sp,#$Zsqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp $t0,$t1,[$ap_real] + ldp $t2,$t3,[$ap_real,#16] + mov $a0,$acc0 // put Zsqr aside for p256_sub + mov $a1,$acc1 + mov $a2,$acc2 + mov $a3,$acc3 + add $rp,sp,#$M + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add $bp,$ap_real,#0 + mov $acc0,$a0 // restore Zsqr + mov $acc1,$a1 + ldp $a0,$a1,[sp,#$S] // forward load for p256_sqr_mont + mov $acc2,$a2 + mov $acc3,$a3 + ldp $a2,$a3,[sp,#$S+16] + add $rp,sp,#$Zsqr + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add $rp,sp,#$S + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr $bi,[$ap_real,#32] + ldp $a0,$a1,[$ap_real,#64] + ldp $a2,$a3,[$ap_real,#64+16] + add $bp,$ap_real,#32 + add $rp,sp,#$tmp0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov $t0,$acc0 + mov $t1,$acc1 + ldp $a0,$a1,[sp,#$S] // forward load for p256_sqr_mont + mov $t2,$acc2 + mov $t3,$acc3 + ldp $a2,$a3,[sp,#$S+16] + add $rp,$rp_real,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add $rp,sp,#$tmp0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr $bi,[sp,#$Zsqr] // forward load for p256_mul_mont + ldp $a0,$a1,[sp,#$M] + ldp $a2,$a3,[sp,#$M+16] + add $rp,$rp_real,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add $bp,sp,#$Zsqr + add $rp,sp,#$M + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov $t0,$acc0 // duplicate M + mov $t1,$acc1 + mov $t2,$acc2 + mov $t3,$acc3 + mov $a0,$acc0 // put M aside + mov $a1,$acc1 + mov $a2,$acc2 + mov $a3,$acc3 + add $rp,sp,#$M + bl __ecp_nistz256_add_to + mov $t0,$a0 // restore M + mov $t1,$a1 + ldr $bi,[$ap_real] // forward load for p256_mul_mont + mov $t2,$a2 + ldp $a0,$a1,[sp,#$S] + mov $t3,$a3 + ldp $a2,$a3,[sp,#$S+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add $bp,$ap_real,#0 + add $rp,sp,#$S + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov $t0,$acc0 + mov $t1,$acc1 + ldp $a0,$a1,[sp,#$M] // forward load for p256_sqr_mont + mov $t2,$acc2 + mov $t3,$acc3 + ldp $a2,$a3,[sp,#$M+16] + add $rp,sp,#$tmp0 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add $rp,$rp_real,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add $bp,sp,#$tmp0 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add $bp,sp,#$S + add $rp,sp,#$S + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr $bi,[sp,#$M] + mov $a0,$acc0 // copy S + mov $a1,$acc1 + mov $a2,$acc2 + mov $a3,$acc3 + add $bp,sp,#$M + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add $bp,$rp_real,#32 + add $rp,$rp_real,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_double,.-ecp_nistz256_point_double +___ +} + +######################################################################## +# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1, +# const P256_POINT *in2); +{ +my ($res_x,$res_y,$res_z, + $H,$Hsqr,$R,$Rsqr,$Hcub, + $U1,$U2,$S1,$S2)=map(32*$_,(0..11)); +my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); +# above map() describes stack layout with 12 temporary +# 256-bit vectors on top. +my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp0,$temp1,$temp2)=map("x$_",(21..28)); + +$code.=<<___; +.globl ecp_nistz256_point_add +.type ecp_nistz256_point_add,%function +.align 5 +ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp $a0,$a1,[$bp,#64] // in2_z + ldp $a2,$a3,[$bp,#64+16] + mov $rp_real,$rp + mov $ap_real,$ap + mov $bp_real,$bp + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + orr $t0,$a0,$a1 + orr $t2,$a2,$a3 + orr $in2infty,$t0,$t2 + cmp $in2infty,#0 + csetm $in2infty,ne // ~in2infty + add $rp,sp,#$Z2sqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp $a0,$a1,[$ap_real,#64] // in1_z + ldp $a2,$a3,[$ap_real,#64+16] + orr $t0,$a0,$a1 + orr $t2,$a2,$a3 + orr $in1infty,$t0,$t2 + cmp $in1infty,#0 + csetm $in1infty,ne // ~in1infty + add $rp,sp,#$Z1sqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr $bi,[$bp_real,#64] + ldp $a0,$a1,[sp,#$Z2sqr] + ldp $a2,$a3,[sp,#$Z2sqr+16] + add $bp,$bp_real,#64 + add $rp,sp,#$S1 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr $bi,[$ap_real,#64] + ldp $a0,$a1,[sp,#$Z1sqr] + ldp $a2,$a3,[sp,#$Z1sqr+16] + add $bp,$ap_real,#64 + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr $bi,[$ap_real,#32] + ldp $a0,$a1,[sp,#$S1] + ldp $a2,$a3,[sp,#$S1+16] + add $bp,$ap_real,#32 + add $rp,sp,#$S1 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr $bi,[$bp_real,#32] + ldp $a0,$a1,[sp,#$S2] + ldp $a2,$a3,[sp,#$S2+16] + add $bp,$bp_real,#32 + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add $bp,sp,#$S1 + ldr $bi,[sp,#$Z2sqr] // forward load for p256_mul_mont + ldp $a0,$a1,[$ap_real] + ldp $a2,$a3,[$ap_real,#16] + add $rp,sp,#$R + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr $acc0,$acc0,$acc1 // see if result is zero + orr $acc2,$acc2,$acc3 + orr $temp0,$acc0,$acc2 // ~is_equal(S1,S2) + + add $bp,sp,#$Z2sqr + add $rp,sp,#$U1 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr $bi,[sp,#$Z1sqr] + ldp $a0,$a1,[$bp_real] + ldp $a2,$a3,[$bp_real,#16] + add $bp,sp,#$Z1sqr + add $rp,sp,#$U2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add $bp,sp,#$U1 + ldp $a0,$a1,[sp,#$R] // forward load for p256_sqr_mont + ldp $a2,$a3,[sp,#$R+16] + add $rp,sp,#$H + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr $acc0,$acc0,$acc1 // see if result is zero + orr $acc2,$acc2,$acc3 + orr $acc0,$acc0,$acc2 // ~is_equal(U1,U2) + + mvn $temp1,$in1infty // -1/0 -> 0/-1 + mvn $temp2,$in2infty // -1/0 -> 0/-1 + orr $acc0,$acc0,$temp1 + orr $acc0,$acc0,$temp2 + orr $acc0,$acc0,$temp0 + cbnz $acc0,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +.Ladd_double: + mov $ap,$ap_real + mov $rp,$rp_real + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b .Ldouble_shortcut + +.align 4 +.Ladd_proceed: + add $rp,sp,#$Rsqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr $bi,[$ap_real,#64] + ldp $a0,$a1,[sp,#$H] + ldp $a2,$a3,[sp,#$H+16] + add $bp,$ap_real,#64 + add $rp,sp,#$res_z + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp $a0,$a1,[sp,#$H] + ldp $a2,$a3,[sp,#$H+16] + add $rp,sp,#$Hsqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr $bi,[$bp_real,#64] + ldp $a0,$a1,[sp,#$res_z] + ldp $a2,$a3,[sp,#$res_z+16] + add $bp,$bp_real,#64 + add $rp,sp,#$res_z + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr $bi,[sp,#$H] + ldp $a0,$a1,[sp,#$Hsqr] + ldp $a2,$a3,[sp,#$Hsqr+16] + add $bp,sp,#$H + add $rp,sp,#$Hcub + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr $bi,[sp,#$Hsqr] + ldp $a0,$a1,[sp,#$U1] + ldp $a2,$a3,[sp,#$U1+16] + add $bp,sp,#$Hsqr + add $rp,sp,#$U2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov $t0,$acc0 + mov $t1,$acc1 + mov $t2,$acc2 + mov $t3,$acc3 + add $rp,sp,#$Hsqr + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add $bp,sp,#$Rsqr + add $rp,sp,#$res_x + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add $bp,sp,#$Hcub + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add $bp,sp,#$U2 + ldr $bi,[sp,#$Hcub] // forward load for p256_mul_mont + ldp $a0,$a1,[sp,#$S1] + ldp $a2,$a3,[sp,#$S1+16] + add $rp,sp,#$res_y + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add $bp,sp,#$Hcub + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr $bi,[sp,#$R] + ldp $a0,$a1,[sp,#$res_y] + ldp $a2,$a3,[sp,#$res_y+16] + add $bp,sp,#$R + add $rp,sp,#$res_y + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add $bp,sp,#$S2 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp $a0,$a1,[sp,#$res_x] // res + ldp $a2,$a3,[sp,#$res_x+16] + ldp $t0,$t1,[$bp_real] // in2 + ldp $t2,$t3,[$bp_real,#16] +___ +for($i=0;$i<64;$i+=32) { # conditional moves +$code.=<<___; + ldp $acc0,$acc1,[$ap_real,#$i] // in1 + cmp $in1infty,#0 // ~$in1intfy, remember? + ldp $acc2,$acc3,[$ap_real,#$i+16] + csel $t0,$a0,$t0,ne + csel $t1,$a1,$t1,ne + ldp $a0,$a1,[sp,#$res_x+$i+32] // res + csel $t2,$a2,$t2,ne + csel $t3,$a3,$t3,ne + cmp $in2infty,#0 // ~$in2intfy, remember? + ldp $a2,$a3,[sp,#$res_x+$i+48] + csel $acc0,$t0,$acc0,ne + csel $acc1,$t1,$acc1,ne + ldp $t0,$t1,[$bp_real,#$i+32] // in2 + csel $acc2,$t2,$acc2,ne + csel $acc3,$t3,$acc3,ne + ldp $t2,$t3,[$bp_real,#$i+48] + stp $acc0,$acc1,[$rp_real,#$i] + stp $acc2,$acc3,[$rp_real,#$i+16] +___ +} +$code.=<<___; + ldp $acc0,$acc1,[$ap_real,#$i] // in1 + cmp $in1infty,#0 // ~$in1intfy, remember? + ldp $acc2,$acc3,[$ap_real,#$i+16] + csel $t0,$a0,$t0,ne + csel $t1,$a1,$t1,ne + csel $t2,$a2,$t2,ne + csel $t3,$a3,$t3,ne + cmp $in2infty,#0 // ~$in2intfy, remember? + csel $acc0,$t0,$acc0,ne + csel $acc1,$t1,$acc1,ne + csel $acc2,$t2,$acc2,ne + csel $acc3,$t3,$acc3,ne + stp $acc0,$acc1,[$rp_real,#$i] + stp $acc2,$acc3,[$rp_real,#$i+16] + +.Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add,.-ecp_nistz256_point_add +___ +} + +######################################################################## +# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1, +# const P256_POINT_AFFINE *in2); +{ +my ($res_x,$res_y,$res_z, + $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..9)); +my $Z1sqr = $S2; +# above map() describes stack layout with 10 temporary +# 256-bit vectors on top. +my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26)); + +$code.=<<___; +.globl ecp_nistz256_point_add_affine +.type ecp_nistz256_point_add_affine,%function +.align 5 +ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov $rp_real,$rp + mov $ap_real,$ap + mov $bp_real,$bp + adrp $poly3,:pg_hi21:.Lpoly + add $poly3,$poly3,:lo12:.Lpoly + ldr $poly1,[$poly3,#8] + ldr $poly3,[$poly3,#24] + + ldp $a0,$a1,[$ap,#64] // in1_z + ldp $a2,$a3,[$ap,#64+16] + orr $t0,$a0,$a1 + orr $t2,$a2,$a3 + orr $in1infty,$t0,$t2 + cmp $in1infty,#0 + csetm $in1infty,ne // ~in1infty + + ldp $acc0,$acc1,[$bp] // in2_x + ldp $acc2,$acc3,[$bp,#16] + ldp $t0,$t1,[$bp,#32] // in2_y + ldp $t2,$t3,[$bp,#48] + orr $acc0,$acc0,$acc1 + orr $acc2,$acc2,$acc3 + orr $t0,$t0,$t1 + orr $t2,$t2,$t3 + orr $acc0,$acc0,$acc2 + orr $t0,$t0,$t2 + orr $in2infty,$acc0,$t0 + cmp $in2infty,#0 + csetm $in2infty,ne // ~in2infty + + add $rp,sp,#$Z1sqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov $a0,$acc0 + mov $a1,$acc1 + mov $a2,$acc2 + mov $a3,$acc3 + ldr $bi,[$bp_real] + add $bp,$bp_real,#0 + add $rp,sp,#$U2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add $bp,$ap_real,#0 + ldr $bi,[$ap_real,#64] // forward load for p256_mul_mont + ldp $a0,$a1,[sp,#$Z1sqr] + ldp $a2,$a3,[sp,#$Z1sqr+16] + add $rp,sp,#$H + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add $bp,$ap_real,#64 + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr $bi,[$ap_real,#64] + ldp $a0,$a1,[sp,#$H] + ldp $a2,$a3,[sp,#$H+16] + add $bp,$ap_real,#64 + add $rp,sp,#$res_z + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr $bi,[$bp_real,#32] + ldp $a0,$a1,[sp,#$S2] + ldp $a2,$a3,[sp,#$S2+16] + add $bp,$bp_real,#32 + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add $bp,$ap_real,#32 + ldp $a0,$a1,[sp,#$H] // forward load for p256_sqr_mont + ldp $a2,$a3,[sp,#$H+16] + add $rp,sp,#$R + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add $rp,sp,#$Hsqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp $a0,$a1,[sp,#$R] + ldp $a2,$a3,[sp,#$R+16] + add $rp,sp,#$Rsqr + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr $bi,[sp,#$H] + ldp $a0,$a1,[sp,#$Hsqr] + ldp $a2,$a3,[sp,#$Hsqr+16] + add $bp,sp,#$H + add $rp,sp,#$Hcub + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr $bi,[$ap_real] + ldp $a0,$a1,[sp,#$Hsqr] + ldp $a2,$a3,[sp,#$Hsqr+16] + add $bp,$ap_real,#0 + add $rp,sp,#$U2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov $t0,$acc0 + mov $t1,$acc1 + mov $t2,$acc2 + mov $t3,$acc3 + add $rp,sp,#$Hsqr + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add $bp,sp,#$Rsqr + add $rp,sp,#$res_x + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add $bp,sp,#$Hcub + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add $bp,sp,#$U2 + ldr $bi,[$ap_real,#32] // forward load for p256_mul_mont + ldp $a0,$a1,[sp,#$Hcub] + ldp $a2,$a3,[sp,#$Hcub+16] + add $rp,sp,#$res_y + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add $bp,$ap_real,#32 + add $rp,sp,#$S2 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr $bi,[sp,#$R] + ldp $a0,$a1,[sp,#$res_y] + ldp $a2,$a3,[sp,#$res_y+16] + add $bp,sp,#$R + add $rp,sp,#$res_y + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add $bp,sp,#$S2 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp $a0,$a1,[sp,#$res_x] // res + ldp $a2,$a3,[sp,#$res_x+16] + ldp $t0,$t1,[$bp_real] // in2 + ldp $t2,$t3,[$bp_real,#16] +___ +for($i=0;$i<64;$i+=32) { # conditional moves +$code.=<<___; + ldp $acc0,$acc1,[$ap_real,#$i] // in1 + cmp $in1infty,#0 // ~$in1intfy, remember? + ldp $acc2,$acc3,[$ap_real,#$i+16] + csel $t0,$a0,$t0,ne + csel $t1,$a1,$t1,ne + ldp $a0,$a1,[sp,#$res_x+$i+32] // res + csel $t2,$a2,$t2,ne + csel $t3,$a3,$t3,ne + cmp $in2infty,#0 // ~$in2intfy, remember? + ldp $a2,$a3,[sp,#$res_x+$i+48] + csel $acc0,$t0,$acc0,ne + csel $acc1,$t1,$acc1,ne + ldp $t0,$t1,[$bp_real,#$i+32] // in2 + csel $acc2,$t2,$acc2,ne + csel $acc3,$t3,$acc3,ne + ldp $t2,$t3,[$bp_real,#$i+48] + stp $acc0,$acc1,[$rp_real,#$i] + stp $acc2,$acc3,[$rp_real,#$i+16] +___ +$code.=<<___ if ($i == 0); + adrp $bp_real,:pg_hi21:.Lone_mont-64 + add $bp_real,$bp_real,:lo12:.Lone_mont-64 +___ +} +$code.=<<___; + ldp $acc0,$acc1,[$ap_real,#$i] // in1 + cmp $in1infty,#0 // ~$in1intfy, remember? + ldp $acc2,$acc3,[$ap_real,#$i+16] + csel $t0,$a0,$t0,ne + csel $t1,$a1,$t1,ne + csel $t2,$a2,$t2,ne + csel $t3,$a3,$t3,ne + cmp $in2infty,#0 // ~$in2intfy, remember? + csel $acc0,$t0,$acc0,ne + csel $acc1,$t1,$acc1,ne + csel $acc2,$t2,$acc2,ne + csel $acc3,$t3,$acc3,ne + stp $acc0,$acc1,[$rp_real,#$i] + stp $acc2,$acc3,[$rp_real,#$i+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine +___ +} +if (1) { +my ($ord0,$ord1) = ($poly1,$poly3); +my ($ord2,$ord3,$ordk,$t4) = map("x$_",(21..24)); +my $acc7 = $bi; + +$code.=<<___; +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont +.type ecp_nistz256_ord_mul_mont,%function +.align 4 +ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp $ordk,:pg_hi21:.Lord + add $ordk,$ordk,:lo12:.Lord + ldr $bi,[$bp] // bp[0] + ldp $a0,$a1,[$ap] + ldp $a2,$a3,[$ap,#16] + + ldp $ord0,$ord1,[$ordk,#0] + ldp $ord2,$ord3,[$ordk,#16] + ldr $ordk,[$ordk,#32] + + mul $acc0,$a0,$bi // a[0]*b[0] + umulh $t0,$a0,$bi + + mul $acc1,$a1,$bi // a[1]*b[0] + umulh $t1,$a1,$bi + + mul $acc2,$a2,$bi // a[2]*b[0] + umulh $t2,$a2,$bi + + mul $acc3,$a3,$bi // a[3]*b[0] + umulh $acc4,$a3,$bi + + mul $t4,$acc0,$ordk + + adds $acc1,$acc1,$t0 // accumulate high parts of multiplication + adcs $acc2,$acc2,$t1 + adcs $acc3,$acc3,$t2 + adc $acc4,$acc4,xzr + mov $acc5,xzr +___ +for ($i=1;$i<4;$i++) { + ################################################################ + # ffff0000.ffffffff.yyyyyyyy.zzzzzzzz + # * abcdefgh + # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx + # + # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we + # rewrite above as: + # + # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx + # - 0000abcd.efgh0000.abcdefgh.00000000.00000000 + # + abcdefgh.abcdefgh.yzayzbyz.cyzdyzey.zfyzgyzh +$code.=<<___; + ldr $bi,[$bp,#8*$i] // b[i] + + lsl $t0,$t4,#32 + subs $acc2,$acc2,$t4 + lsr $t1,$t4,#32 + sbcs $acc3,$acc3,$t0 + sbcs $acc4,$acc4,$t1 + sbc $acc5,$acc5,xzr + + subs xzr,$acc0,#1 + umulh $t1,$ord0,$t4 + mul $t2,$ord1,$t4 + umulh $t3,$ord1,$t4 + + adcs $t2,$t2,$t1 + mul $t0,$a0,$bi + adc $t3,$t3,xzr + mul $t1,$a1,$bi + + adds $acc0,$acc1,$t2 + mul $t2,$a2,$bi + adcs $acc1,$acc2,$t3 + mul $t3,$a3,$bi + adcs $acc2,$acc3,$t4 + adcs $acc3,$acc4,$t4 + adc $acc4,$acc5,xzr + + adds $acc0,$acc0,$t0 // accumulate low parts + umulh $t0,$a0,$bi + adcs $acc1,$acc1,$t1 + umulh $t1,$a1,$bi + adcs $acc2,$acc2,$t2 + umulh $t2,$a2,$bi + adcs $acc3,$acc3,$t3 + umulh $t3,$a3,$bi + adc $acc4,$acc4,xzr + mul $t4,$acc0,$ordk + adds $acc1,$acc1,$t0 // accumulate high parts + adcs $acc2,$acc2,$t1 + adcs $acc3,$acc3,$t2 + adcs $acc4,$acc4,$t3 + adc $acc5,xzr,xzr +___ +} +$code.=<<___; + lsl $t0,$t4,#32 // last reduction + subs $acc2,$acc2,$t4 + lsr $t1,$t4,#32 + sbcs $acc3,$acc3,$t0 + sbcs $acc4,$acc4,$t1 + sbc $acc5,$acc5,xzr + + subs xzr,$acc0,#1 + umulh $t1,$ord0,$t4 + mul $t2,$ord1,$t4 + umulh $t3,$ord1,$t4 + + adcs $t2,$t2,$t1 + adc $t3,$t3,xzr + + adds $acc0,$acc1,$t2 + adcs $acc1,$acc2,$t3 + adcs $acc2,$acc3,$t4 + adcs $acc3,$acc4,$t4 + adc $acc4,$acc5,xzr + + subs $t0,$acc0,$ord0 // ret -= modulus + sbcs $t1,$acc1,$ord1 + sbcs $t2,$acc2,$ord2 + sbcs $t3,$acc3,$ord3 + sbcs xzr,$acc4,xzr + + csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus + csel $acc1,$acc1,$t1,lo + csel $acc2,$acc2,$t2,lo + stp $acc0,$acc1,[$rp] + csel $acc3,$acc3,$t3,lo + stp $acc2,$acc3,[$rp,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl ecp_nistz256_ord_sqr_mont +.type ecp_nistz256_ord_sqr_mont,%function +.align 4 +ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp $ordk,:pg_hi21:.Lord + add $ordk,$ordk,:lo12:.Lord + ldp $a0,$a1,[$ap] + ldp $a2,$a3,[$ap,#16] + + ldp $ord0,$ord1,[$ordk,#0] + ldp $ord2,$ord3,[$ordk,#16] + ldr $ordk,[$ordk,#32] + b .Loop_ord_sqr + +.align 4 +.Loop_ord_sqr: + sub $bp,$bp,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul $acc1,$a1,$a0 // a[1]*a[0] + umulh $t1,$a1,$a0 + mul $acc2,$a2,$a0 // a[2]*a[0] + umulh $t2,$a2,$a0 + mul $acc3,$a3,$a0 // a[3]*a[0] + umulh $acc4,$a3,$a0 + + adds $acc2,$acc2,$t1 // accumulate high parts of multiplication + mul $t0,$a2,$a1 // a[2]*a[1] + umulh $t1,$a2,$a1 + adcs $acc3,$acc3,$t2 + mul $t2,$a3,$a1 // a[3]*a[1] + umulh $t3,$a3,$a1 + adc $acc4,$acc4,xzr // can't overflow + + mul $acc5,$a3,$a2 // a[3]*a[2] + umulh $acc6,$a3,$a2 + + adds $t1,$t1,$t2 // accumulate high parts of multiplication + mul $acc0,$a0,$a0 // a[0]*a[0] + adc $t2,$t3,xzr // can't overflow + + adds $acc3,$acc3,$t0 // accumulate low parts of multiplication + umulh $a0,$a0,$a0 + adcs $acc4,$acc4,$t1 + mul $t1,$a1,$a1 // a[1]*a[1] + adcs $acc5,$acc5,$t2 + umulh $a1,$a1,$a1 + adc $acc6,$acc6,xzr // can't overflow + + adds $acc1,$acc1,$acc1 // acc[1-6]*=2 + mul $t2,$a2,$a2 // a[2]*a[2] + adcs $acc2,$acc2,$acc2 + umulh $a2,$a2,$a2 + adcs $acc3,$acc3,$acc3 + mul $t3,$a3,$a3 // a[3]*a[3] + adcs $acc4,$acc4,$acc4 + umulh $a3,$a3,$a3 + adcs $acc5,$acc5,$acc5 + adcs $acc6,$acc6,$acc6 + adc $acc7,xzr,xzr + + adds $acc1,$acc1,$a0 // +a[i]*a[i] + mul $t4,$acc0,$ordk + adcs $acc2,$acc2,$t1 + adcs $acc3,$acc3,$a1 + adcs $acc4,$acc4,$t2 + adcs $acc5,$acc5,$a2 + adcs $acc6,$acc6,$t3 + adc $acc7,$acc7,$a3 +___ +for($i=0; $i<4; $i++) { # reductions +$code.=<<___; + subs xzr,$acc0,#1 + umulh $t1,$ord0,$t4 + mul $t2,$ord1,$t4 + umulh $t3,$ord1,$t4 + + adcs $t2,$t2,$t1 + adc $t3,$t3,xzr + + adds $acc0,$acc1,$t2 + adcs $acc1,$acc2,$t3 + adcs $acc2,$acc3,$t4 + adc $acc3,xzr,$t4 // can't overflow +___ +$code.=<<___ if ($i<3); + mul $t3,$acc0,$ordk +___ +$code.=<<___; + lsl $t0,$t4,#32 + subs $acc1,$acc1,$t4 + lsr $t1,$t4,#32 + sbcs $acc2,$acc2,$t0 + sbc $acc3,$acc3,$t1 // can't borrow +___ + ($t3,$t4) = ($t4,$t3); +} +$code.=<<___; + adds $acc0,$acc0,$acc4 // accumulate upper half + adcs $acc1,$acc1,$acc5 + adcs $acc2,$acc2,$acc6 + adcs $acc3,$acc3,$acc7 + adc $acc4,xzr,xzr + + subs $t0,$acc0,$ord0 // ret -= modulus + sbcs $t1,$acc1,$ord1 + sbcs $t2,$acc2,$ord2 + sbcs $t3,$acc3,$ord3 + sbcs xzr,$acc4,xzr + + csel $a0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus + csel $a1,$acc1,$t1,lo + csel $a2,$acc2,$t2,lo + csel $a3,$acc3,$t3,lo + + cbnz $bp,.Loop_ord_sqr + + stp $a0,$a1,[$rp] + stp $a2,$a3,[$rp,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret +.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont +___ +} } + +######################################################################## +# select subroutines +# These select functions are similar to those in p256-x86_64-asm.pl +# They load all points in the lookup table +# keeping in the output only the one corresponding to the input index. +{ +my ($val,$in_t)=map("x$_",(0..1)); +my ($index)=("w2"); +my ($Idx_ctr,$Val_in, $Mask_64)=("w9", "x10", "x11"); +my ($Mask)=("v3"); +my ($Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("v$_",(16..21)); +my ($T0a,$T0b,$T0c,$T0d,$T0e,$T0f)=map("v$_",(22..27)); +$code.=<<___; +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w5 +.type ecp_nistz256_select_w5,%function +.align 4 +ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // $Val_in := $val + // $Idx_ctr := 0; loop counter and incremented internal index + mov $Val_in, $val + mov $Idx_ctr, #0 + + // [$Ra-$Rf] := 0 + movi $Ra.16b, #0 + movi $Rb.16b, #0 + movi $Rc.16b, #0 + movi $Rd.16b, #0 + movi $Re.16b, #0 + movi $Rf.16b, #0 + +.Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add $Idx_ctr, $Idx_ctr, #1 + + // [$T0a-$T0f] := Load a (3*256-bit = 6*128-bit) table entry starting at $in_t + // and advance $in_t to point to the next entry + ld1 {$T0a.2d, $T0b.2d, $T0c.2d, $T0d.2d}, [$in_t],#64 + + // $Mask_64 := ($Idx_ctr == $index)? All 1s : All 0s + cmp $Idx_ctr, $index + csetm $Mask_64, eq + + // continue loading ... + ld1 {$T0e.2d, $T0f.2d}, [$in_t],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup $Mask.2d, $Mask_64 + + // [$Ra-$Rd] := (Mask == all 1s)? [$T0a-$T0d] : [$Ra-$Rd] + // i.e., values in output registers will remain the same if $Idx_ctr != $index + bit $Ra.16b, $T0a.16b, $Mask.16b + bit $Rb.16b, $T0b.16b, $Mask.16b + + bit $Rc.16b, $T0c.16b, $Mask.16b + bit $Rd.16b, $T0d.16b, $Mask.16b + + bit $Re.16b, $T0e.16b, $Mask.16b + bit $Rf.16b, $T0f.16b, $Mask.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz $Idx_ctr, #4, .Lselect_w5_loop + + // Write [$Ra-$Rf] to memory at the output pointer + st1 {$Ra.2d, $Rb.2d, $Rc.2d, $Rd.2d}, [$Val_in],#64 + st1 {$Re.2d, $Rf.2d}, [$Val_in] + + ret +.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5 + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w7 +.type ecp_nistz256_select_w7,%function +.align 4 +ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // $Idx_ctr := 0; loop counter and incremented internal index + mov $Idx_ctr, #0 + + // [$Ra-$Rf] := 0 + movi $Ra.16b, #0 + movi $Rb.16b, #0 + movi $Rc.16b, #0 + movi $Rd.16b, #0 + +.Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add $Idx_ctr, $Idx_ctr, #1 + + // [$T0a-$T0d] := Load a (2*256-bit = 4*128-bit) table entry starting at $in_t + // and advance $in_t to point to the next entry + ld1 {$T0a.2d, $T0b.2d, $T0c.2d, $T0d.2d}, [$in_t],#64 + + // $Mask_64 := ($Idx_ctr == $index)? All 1s : All 0s + cmp $Idx_ctr, $index + csetm $Mask_64, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup $Mask.2d, $Mask_64 + + // [$Ra-$Rd] := (Mask == all 1s)? [$T0a-$T0d] : [$Ra-$Rd] + // i.e., values in output registers will remain the same if $Idx_ctr != $index + bit $Ra.16b, $T0a.16b, $Mask.16b + bit $Rb.16b, $T0b.16b, $Mask.16b + + bit $Rc.16b, $T0c.16b, $Mask.16b + bit $Rd.16b, $T0d.16b, $Mask.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz $Idx_ctr, #6, .Lselect_w7_loop + + // Write [$Ra-$Rd] to memory at the output pointer + st1 {$Ra.2d, $Rb.2d, $Rc.2d, $Rd.2d}, [$val] + + ret +.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7 +___ +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + print $_,"\n"; +} +close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl index c75d7845..0701996d 100755 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl @@ -62,6 +62,7 @@ $code.=<<___; .extern OPENSSL_ia32cap_P # The polynomial +.section .rodata .align 64 .Lpoly: .quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001 @@ -80,6 +81,7 @@ $code.=<<___; .quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000 .LordK: .quad 0xccd1c8aaee00bc4f +.text ___ { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl new file mode 100644 index 00000000..e259aeff --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl @@ -0,0 +1,455 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +# +# +# This code is based on p256_beeu-x86_64-asm.pl (which is based on BN_mod_inverse_odd). +# + +# The first two arguments should always be the flavour and output file path. +if ($#ARGV < 1) { die "Not enough arguments provided. + Two arguments are necessary: the flavour and the output file path."; } + +$flavour = shift; +$output = shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; +############################################################################# +# extern int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS], +# BN_ULONG a[P256_LIMBS], +# BN_ULONG n[P256_LIMBS]); +# +# (Binary Extended GCD (Euclidean) Algorithm. +# See A. Menezes, P. vanOorschot, and S. Vanstone's Handbook of Applied Cryptography, +# Chapter 14, Algorithm 14.61 and Note 14.64 +# http://cacr.uwaterloo.ca/hac/about/chap14.pdf) + +# Assumption 1: n is odd for the BEEU +# Assumption 2: 1 < a < n < 2^256 + +# Details +# The inverse of x modulo y can be calculated using Alg. 14.61, where "a" would be that inverse. +# In other words, +# ax == 1 (mod y) (where the symbol “==“ denotes ”congruent“) +# a == x^{-1} (mod y) +# +# It can be shown that throughout all the iterations of the algorithm, the following holds: +# u = Ax + By +# v = Cx + Dy +# The values B and D are not of interest in this case, so they need not be computed by the algorithm. +# This means the following congruences hold through the iterations of the algorithm. +# Ax == u (mod y) +# Cx == v (mod y) + +# Now we will modify the notation to match that of BN_mod_inverse_odd() +# on which beeu_mod_inverse_vartime() in `p256_beeu-x86_64-asm` is based. +# In those functions: +# x, y -> a, n +# u, v -> B, A +# A, C -> X, Y’, where Y’ = -Y +# Hence, the following holds throughout the algorithm iterations +# Xa == B (mod n) +# -Ya == A (mod n) +# +# Same algorithm in Python: +# def beeu(a, n): +# X = 1 +# Y = 0 +# B = a +# A = n +# while (B != 0): +# while (B % 2) == 0: +# B >>= 1 +# if (X % 2) == 1: +# X = X + n +# X >>= 1 +# while (A % 2) == 0: +# A >>= 1 +# if (Y % 2) == 1: +# Y = Y + n +# Y >>= 1 +# if (B >= A): +# B = B - A +# X = X + Y +# else: +# A = A - B +# Y = Y + X +# if (A != 1): +# # error +# return 0 +# else: +# while (Y > n): +# Y = Y - n +# Y = n - Y +# return Y + + +# For the internal variables, +# x0-x2, x30 are used to hold the modulus n. The input parameters passed in +# x1,x2 are copied first before corrupting them. x0 (out) is stored on the stack. +# x3-x7 are used for parameters, which is not the case in this function, so they are corruptible +# x8 is corruptible here +# (the function doesn't return a struct, hence x8 doesn't contain a passed-in address +# for that struct). +# x9-x15 are corruptible registers +# x19-x28 are callee-saved registers + +# X/Y will hold the inverse parameter +# Assumption: a,n,X,Y < 2^(256) +# Initially, X := 1, Y := 0 +# A := n, B := a + +# Function parameters (as per the Procedure Call Standard) +my($out, $a_in, $n_in)=map("x$_",(0..2)); +# Internal variables +my($n0, $n1, $n2, $n3)=map("x$_",(0..2,30)); +my($x0, $x1, $x2, $x3, $x4)=map("x$_",(3..7)); +my($y0, $y1, $y2, $y3, $y4)=map("x$_",(8..12)); +my($shift)=("x13"); +my($t0, $t1, $t2, $t3)=map("x$_",(14,15,19,20)); +my($a0, $a1, $a2, $a3)=map("x$_",(21..24)); +my($b0, $b1, $b2, $b3)=map("x$_",(25..28)); + +# if B == 0, jump to end of loop +sub TEST_B_ZERO { + return <<___; + orr $t0, $b0, $b1 + orr $t0, $t0, $b2 + + // reverse the bit order of $b0. This is needed for clz after this macro + rbit $t1, $b0 + + orr $t0, $t0, $b3 + cbz $t0,.Lbeeu_loop_end +___ +} + +# Shift right by 1 bit, adding the modulus first if the variable is odd +# if least_sig_bit(var0) == 0, +# goto shift1_ +# else +# add n and goto shift1_ +# Prerequisite: t0 = 0 +$g_next_label = 0; +sub SHIFT1 { + my ($var0, $var1, $var2, $var3, $var4) = @_; + my $label = ".Lshift1_${g_next_label}"; + $g_next_label++; + return <<___; + tbz $var0, #0, $label + adds $var0, $var0, $n0 + adcs $var1, $var1, $n1 + adcs $var2, $var2, $n2 + adcs $var3, $var3, $n3 + adc $var4, $var4, $t0 +$label: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr $var0, $var1, $var0, #1 + extr $var1, $var2, $var1, #1 + extr $var2, $var3, $var2, #1 + extr $var3, $var4, $var3, #1 + lsr $var4, $var4, #1 +___ +} + +# compilation by clang 10.0.0 with -O2/-O3 of +# a[0] = (a[0] >> count) | (a[1] << (64-count)); +# a[1] = (a[1] >> count) | (a[2] << (64-count)); +# a[2] = (a[2] >> count) | (a[3] << (64-count)); +# a[3] >>= count; +# Note: EXTR instruction used in SHIFT1 is similar to x86_64's SHRDQ +# except that the second source operand of EXTR is only immediate; +# that's why it cannot be used here where $shift is a variable +# +# In the following, +# t0 := 0 - shift +# +# then var0, for example, will be shifted right as follows: +# var0 := (var0 >> (uint(shift) mod 64)) | (var1 << (uint(t0) mod 64)) +# "uint() mod 64" is from the definition of LSL and LSR instructions. +# +# What matters here is the order of instructions relative to certain other +# instructions, i.e. +# - lsr and lsl must precede orr of the corresponding registers. +# - lsl must preced the lsr of the same register afterwards. +# The chosen order of the instructions overall is to try and maximize +# the pipeline usage. +sub SHIFT256 { + my ($var0, $var1, $var2, $var3) = @_; + return <<___; + neg $t0, $shift + lsr $var0, $var0, $shift + lsl $t1, $var1, $t0 + + lsr $var1, $var1, $shift + lsl $t2, $var2, $t0 + + orr $var0, $var0, $t1 + + lsr $var2, $var2, $shift + lsl $t3, $var3, $t0 + + orr $var1, $var1, $t2 + + lsr $var3, $var3, $shift + + orr $var2, $var2, $t3 +___ +} + +$code.=<<___; +#include "openssl/arm_arch.h" + +.text +.globl beeu_mod_inverse_vartime +.type beeu_mod_inverse_vartime, %function +.align 4 +beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp $b0,$b1,[$a_in] + ldp $b2,$b3,[$a_in,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp $n0,$n1,[$n_in] + ldp $n2,$n3,[$n_in,#16] + + // A = a3..a0 := n + mov $a0, $n0 + mov $a1, $n1 + mov $a2, $n2 + mov $a3, $n3 + + // X = x4..x0 := 1 + mov $x0, #1 + eor $x1, $x1, $x1 + eor $x2, $x2, $x2 + eor $x3, $x3, $x3 + eor $x4, $x4, $x4 + + // Y = y4..y0 := 0 + eor $y0, $y0, $y0 + eor $y1, $y1, $y1 + eor $y2, $y2, $y2 + eor $y3, $y3, $y3 + eor $y4, $y4, $y4 + +.Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + ${\TEST_B_ZERO} + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in $b0 + // ( = number of leading 0s in $t1; see the "rbit" instruction in TEST_B_ZERO) + clz $shift, $t1 + + // If there is no shift, goto shift_A_Y + cbz $shift, .Lbeeu_shift_A_Y + + // Shift B right by "$shift" bits + ${\SHIFT256($b0, $b1, $b2, $b3)} + + // Shift X right by "$shift" bits, adding n whenever X becomes odd. + // $shift--; + // $t0 := 0; needed in the addition to the most significant word in SHIFT1 + eor $t0, $t0, $t0 +.Lbeeu_shift_loop_X: + ${\SHIFT1($x0, $x1, $x2, $x3, $x4)} + subs $shift, $shift, #1 + bne .Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "$shift" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and $shift is decreased while executing the X loop. + // - SHIFT256(B, $shift) is performed before right-shifting X; they are independent + +.Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of $a0 + // $shift := number of trailing 0s in $a0 (= number of leading 0s in $t1) + rbit $t1, $a0 + clz $shift, $t1 + + // If there is no shift, goto |B-A|, X+Y update + cbz $shift, .Lbeeu_update_B_X_or_A_Y + + // Shift A right by "$shift" bits + ${\SHIFT256($a0, $a1, $a2, $a3)} + + // Shift Y right by "$shift" bits, adding n whenever Y becomes odd. + // $shift--; + // $t0 := 0; needed in the addition to the most significant word in SHIFT1 + eor $t0, $t0, $t0 +.Lbeeu_shift_loop_Y: + ${\SHIFT1($y0, $y1, $y2, $y3, $y4)} + subs $shift, $shift, #1 + bne .Lbeeu_shift_loop_Y + +.Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs $t0, $b0, $a0 + sbcs $t1, $b1, $a1 + sbcs $t2, $b2, $a2 + sbcs $t3, $b3, $a3 + bcs .Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs $a0, $a0, $b0 + sbcs $a1, $a1, $b1 + sbcs $a2, $a2, $b2 + sbcs $a3, $a3, $b3 + + adds $y0, $y0, $x0 + adcs $y1, $y1, $x1 + adcs $y2, $y2, $x2 + adcs $y3, $y3, $x3 + adc $y4, $y4, $x4 + b .Lbeeu_loop + +.Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov $b0, $t0 + mov $b1, $t1 + mov $b2, $t2 + mov $b3, $t3 + + adds $x0, $x0, $y0 + adcs $x1, $x1, $y1 + adcs $x2, $x2, $y2 + adcs $x3, $x3, $y3 + adc $x4, $x4, $y4 + b .Lbeeu_loop + +.Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub $t0, $a0, #1 + orr $t0, $t0, $a1 + orr $t0, $t0, $a2 + orr $t0, $t0, $a3 + cbnz $t0, .Lbeeu_err + + // If Y>n ==> Y:=Y-n +.Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // ($t0 = 0 from above) + subs $x0, $y0, $n0 + sbcs $x1, $y1, $n1 + sbcs $x2, $y2, $n2 + sbcs $x3, $y3, $n3 + sbcs $x4, $y4, $t0 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel $y0, $x0, $y0, cs + csel $y1, $x1, $y1, cs + csel $y2, $x2, $y2, cs + csel $y3, $x3, $y3, cs + csel $y4, $x4, $y4, cs + bcs .Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs $y0, $n0, $y0 + sbcs $y1, $n1, $y1 + sbcs $y2, $n2, $y2 + sbcs $y3, $n3, $y3 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp $y0, $y1, [x3] + stp $y2, $y3, [x3,#16] + // return 1 (success) + mov x0, #1 + b .Lbeeu_finish + +.Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +.Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size beeu_mod_inverse_vartime,.-beeu_mod_inverse_vartime +___ + + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + print $_,"\n"; +} +close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec.c index 1f03e15f..ac14f2e0 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec.c @@ -246,7 +246,8 @@ DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) { out->curves[2].param_len = 32; out->curves[2].params = kP256Params; out->curves[2].method = -#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_SMALL) EC_GFp_nistz256_method(); #else @@ -284,7 +285,6 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) { ret = OPENSSL_malloc(sizeof(EC_GROUP)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); @@ -446,7 +446,6 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } @@ -521,9 +520,9 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { return NULL; } - CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get()); + CRYPTO_MUTEX_lock_read(built_in_groups_lock_bss_get()); EC_GROUP *ret = *group_ptr; - CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get()); + CRYPTO_MUTEX_unlock_read(built_in_groups_lock_bss_get()); if (ret != NULL) { return ret; } @@ -534,7 +533,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { } EC_GROUP *to_free = NULL; - CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get()); + CRYPTO_MUTEX_lock_write(built_in_groups_lock_bss_get()); if (*group_ptr == NULL) { *group_ptr = ret; // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup| @@ -544,7 +543,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { to_free = ret; ret = *group_ptr; } - CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get()); + CRYPTO_MUTEX_unlock_write(built_in_groups_lock_bss_get()); EC_GROUP_free(to_free); return ret; @@ -685,7 +684,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) { EC_POINT *ret = OPENSSL_malloc(sizeof *ret); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -803,7 +801,7 @@ int EC_POINT_get_affine_coordinates(const EC_GROUP *group, return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx); } -void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, +void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out, const EC_AFFINE *p) { out->X = p->X; out->Y = p->Y; @@ -811,12 +809,12 @@ void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, } int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { return group->meth->point_get_affine_coordinates(group, p, &out->X, &out->Y); } int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *in, size_t num) { + const EC_JACOBIAN *in, size_t num) { if (group->meth->jacobian_to_affine_batch == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -943,8 +941,9 @@ static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, return ok; } -int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, - const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { +int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const EC_POINT *p, + const BIGNUM *p_scalar, BN_CTX *ctx) { // Previously, this function set |r| to the point at infinity if there was // nothing to multiply. But, nobody should be calling this function with // nothing to multiply in the first place. @@ -991,13 +990,13 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, if (p_scalar != NULL) { EC_SCALAR scalar; - EC_RAW_POINT tmp; + EC_JACOBIAN tmp; if (!arbitrary_bignum_to_scalar(group, &scalar, p_scalar, ctx) || !ec_point_mul_scalar(group, &tmp, &p->raw, &scalar)) { goto err; } if (g_scalar == NULL) { - OPENSSL_memcpy(&r->raw, &tmp, sizeof(EC_RAW_POINT)); + OPENSSL_memcpy(&r->raw, &tmp, sizeof(EC_JACOBIAN)); } else { group->meth->add(group, &r->raw, &r->raw, &tmp); } @@ -1010,8 +1009,15 @@ err: return ret; } -int ec_point_mul_scalar_public(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_SCALAR *g_scalar, const EC_RAW_POINT *p, +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { + boringssl_ensure_ecc_self_test(); + + return ec_point_mul_no_self_test(group, r, g_scalar, p, p_scalar, ctx); +} + +int ec_point_mul_scalar_public(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_SCALAR *g_scalar, const EC_JACOBIAN *p, const EC_SCALAR *p_scalar) { if (g_scalar == NULL || p_scalar == NULL || p == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); @@ -1026,9 +1032,9 @@ int ec_point_mul_scalar_public(const EC_GROUP *group, EC_RAW_POINT *r, return 1; } -int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *points, + const EC_JACOBIAN *points, const EC_SCALAR *scalars, size_t num) { if (group->meth->mul_public_batch == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -1039,8 +1045,8 @@ int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, num); } -int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, const EC_SCALAR *scalar) { +int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar) { if (p == NULL || scalar == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -1058,7 +1064,7 @@ int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r, return 1; } -int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar) { if (scalar == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); @@ -1068,8 +1074,10 @@ int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, group->meth->mul_base(group, r, scalar); // Check the result is on the curve to defend against fault attacks or bugs. - // This has negligible cost compared to the multiplication. - if (!ec_GFp_simple_is_on_curve(group, r)) { + // This has negligible cost compared to the multiplication. This can only + // happen on bug or CPU fault, so it okay to leak this. The alternative would + // be to proceed with bad data. + if (!constant_time_declassify_int(ec_GFp_simple_is_on_curve(group, r))) { OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); return 0; } @@ -1077,10 +1085,10 @@ int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, return 1; } -int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, +int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2) { if (group->meth->mul_batch == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -1100,7 +1108,7 @@ int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_RAW_POINT *r, } int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { if (group->meth->init_precomp == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -1109,7 +1117,7 @@ int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, return group->meth->init_precomp(group, out, p); } -int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_JACOBIAN *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, @@ -1131,8 +1139,8 @@ int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, return 1; } -void ec_point_select(const EC_GROUP *group, EC_RAW_POINT *out, BN_ULONG mask, - const EC_RAW_POINT *a, const EC_RAW_POINT *b) { +void ec_point_select(const EC_GROUP *group, EC_JACOBIAN *out, BN_ULONG mask, + const EC_JACOBIAN *a, const EC_JACOBIAN *b) { ec_felem_select(group, &out->X, mask, &a->X, &b->X); ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y); ec_felem_select(group, &out->Z, mask, &a->Z, &b->Z); @@ -1146,35 +1154,32 @@ void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask, void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, const EC_PRECOMP *a, const EC_PRECOMP *b) { - OPENSSL_STATIC_ASSERT(sizeof(out->comb) == sizeof(*out), - "out->comb does not span the entire structure"); + static_assert(sizeof(out->comb) == sizeof(*out), + "out->comb does not span the entire structure"); for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(out->comb); i++) { ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]); } } -int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, +int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p, const EC_SCALAR *r) { return group->meth->cmp_x_coordinate(group, p, r); } int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { uint8_t bytes[EC_MAX_BYTES]; size_t len; if (!ec_get_x_coordinate_as_bytes(group, bytes, &len, sizeof(bytes), p)) { return 0; } - // For simplicity, in case of width mismatches between |group->field| and - // |group->order|, zero any untouched words in |out|. - OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); - for (size_t i = 0; i < len; i++) { - out->bytes[len - i - 1] = bytes[i]; - } - - // We must have p < 2×order, assuming p is not tiny (p >= 17). Thus rather we - // can reduce by performing at most one subtraction. + // The x-coordinate is bounded by p, but we need a scalar, bounded by the + // order. These may not have the same size. However, we must have p < 2×order, + // assuming p is not tiny (p >= 17). + // + // Thus |bytes| will fit in |order.width + 1| words, and we can reduce by + // performing at most one subtraction. // // Proof: We only work with prime order curves, so the number of points on // the curve is the order. Thus Hasse's theorem gives: @@ -1188,20 +1193,17 @@ int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, // // Additionally, one can manually check this property for built-in curves. It // is enforced for legacy custom curves in |EC_GROUP_set_generator|. - - // The above does not guarantee |group->field| is not one word larger than - // |group->order|, so read one extra carry word. - BN_ULONG tmp[EC_MAX_WORDS]; - BN_ULONG carry = - group->order.width < EC_MAX_WORDS ? out->words[group->order.width] : 0; - bn_reduce_once_in_place(out->words, carry, group->order.d, tmp, - group->order.width); + const BIGNUM *order = &group->order; + BN_ULONG words[EC_MAX_WORDS + 1] = {0}; + bn_big_endian_to_words(words, order->width + 1, bytes, len); + bn_reduce_once(out->words, words, /*carry=*/words[order->width], order->d, + order->width); return 1; } int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, size_t max_out, - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { size_t len = BN_num_bytes(&group->field); assert(len <= EC_MAX_BYTES); if (max_out < len) { @@ -1219,7 +1221,7 @@ int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, return 1; } -void ec_set_to_safe_point(const EC_GROUP *group, EC_RAW_POINT *out) { +void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out) { if (group->generator != NULL) { ec_GFp_simple_point_copy(out, &group->generator->raw); } else { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_key.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_key.c index 7a6daab4..84a29ab8 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_key.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_key.c @@ -79,6 +79,7 @@ #include "internal.h" #include "../delocate.h" +#include "../service_indicator/internal.h" #include "../../internal.h" @@ -87,7 +88,6 @@ DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class) static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); if (wrapped == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -108,7 +108,6 @@ EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } EC_KEY *EC_KEY_new_method(const ENGINE *engine) { EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -141,7 +140,6 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { EC_KEY *EC_KEY_new_by_curve_name(int nid) { EC_KEY *ret = EC_KEY_new(); if (ret == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); return NULL; } ret->group = EC_GROUP_new_by_curve_name(nid); @@ -246,8 +244,9 @@ int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { if (scalar == NULL) { return 0; } - if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { - OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key) || + ec_scalar_is_zero(key->group, &scalar->scalar)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); ec_wrapped_scalar_free(scalar); return 0; } @@ -308,8 +307,11 @@ int EC_KEY_check_key(const EC_KEY *eckey) { } // Check the public and private keys match. + // + // NOTE: this is a FIPS pair-wise consistency check for the ECDH case. See SP + // 800-56Ar3, page 36. if (eckey->priv_key != NULL) { - EC_RAW_POINT point; + EC_JACOBIAN point; if (!ec_point_mul_scalar_base(eckey->group, &point, &eckey->priv_key->scalar)) { OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); @@ -326,32 +328,43 @@ int EC_KEY_check_key(const EC_KEY *eckey) { } int EC_KEY_check_fips(const EC_KEY *key) { + int ret = 0; + FIPS_service_indicator_lock_state(); + if (EC_KEY_is_opaque(key)) { // Opaque keys can't be checked. OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); - return 0; + goto end; } if (!EC_KEY_check_key(key)) { - return 0; + goto end; } if (key->priv_key) { uint8_t data[16] = {0}; ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key); -#if defined(BORINGSSL_FIPS_BREAK_ECDSA_PWCT) - data[0] = ~data[0]; -#endif + if (boringssl_fips_break_test("ECDSA_PWCT")) { + data[0] = ~data[0]; + } int ok = sig != NULL && ECDSA_do_verify(data, sizeof(data), sig, key); ECDSA_SIG_free(sig); if (!ok) { OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); - return 0; + goto end; } } - return 1; + ret = 1; + +end: + FIPS_service_indicator_unlock_state(); + if (ret) { + EC_KEY_keygen_verify_service_indicator(key); + } + + return ret; } int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, @@ -379,14 +392,73 @@ err: return ok; } -size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx) { - if (key == NULL || key->pub_key == NULL || key->group == NULL) { +int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, BN_CTX *ctx) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); return 0; } - const size_t len = - EC_POINT_point2oct(key->group, key->pub_key, form, NULL, 0, ctx); + EC_POINT *point = EC_POINT_new(key->group); + int ok = point != NULL && + EC_POINT_oct2point(key->group, point, in, len, ctx) && + EC_KEY_set_public_key(key, point); + EC_POINT_free(point); + return ok; +} + +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + uint8_t **out_buf, BN_CTX *ctx) { + if (key == NULL || key->pub_key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + return EC_POINT_point2buf(key->group, key->pub_key, form, out_buf, ctx); +} + +int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (len != BN_num_bytes(EC_GROUP_get0_order(key->group))) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + BIGNUM *priv_key = BN_bin2bn(in, len, NULL); + int ok = priv_key != NULL && // + EC_KEY_set_private_key(key, priv_key); + BN_free(priv_key); + return ok; +} + +size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, size_t max_out) { + if (key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + size_t len = BN_num_bytes(EC_GROUP_get0_order(key->group)); + if (out == NULL) { + return len; + } + + if (max_out < len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + size_t bytes_written; + ec_scalar_to_bytes(key->group, out, &bytes_written, &key->priv_key->scalar); + assert(bytes_written == len); + return len; +} + +size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf) { + *out_buf = NULL; + size_t len = EC_KEY_priv2oct(key, NULL, 0); if (len == 0) { return 0; } @@ -396,8 +468,8 @@ size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, return 0; } - if (EC_POINT_point2oct(key->group, key->pub_key, form, buf, len, ctx) != - len) { + len = EC_KEY_priv2oct(key, buf, len); + if (len == 0) { OPENSSL_free(buf); return 0; } @@ -439,6 +511,8 @@ int EC_KEY_generate_key(EC_KEY *key) { } int EC_KEY_generate_key_fips(EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + if (EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey)) { return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_montgomery.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_montgomery.c index 21d5d40d..78e05076 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_montgomery.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_montgomery.c @@ -156,8 +156,8 @@ int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, return 1; } -static void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, - const BN_ULONG *words, size_t num) { +void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num) { // Convert "from" Montgomery form so the value is reduced mod p. bn_from_montgomery_small(out->words, group->field.width, words, num, group->mont); @@ -167,17 +167,18 @@ static void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, ec_GFp_mont_felem_to_montgomery(group, out, out); } -static void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, - const EC_FELEM *a, const BN_ULONG *exp, - size_t num_exp) { +void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a, const BN_ULONG *exp, + size_t num_exp) { bn_mod_exp_mont_small(out->words, a->words, group->field.width, exp, num_exp, group->mont); } static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, - const EC_RAW_POINT *point, + const EC_JACOBIAN *point, EC_FELEM *x, EC_FELEM *y) { - if (ec_GFp_simple_is_at_infinity(group, point)) { + if (constant_time_declassify_int( + ec_GFp_simple_is_at_infinity(group, point))) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; } @@ -202,7 +203,7 @@ static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, static int ec_GFp_mont_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *in, + const EC_JACOBIAN *in, size_t num) { if (num == 0) { return 1; @@ -246,8 +247,8 @@ static int ec_GFp_mont_jacobian_to_affine_batch(const EC_GROUP *group, return 1; } -void ec_GFp_mont_add(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_RAW_POINT *a, const EC_RAW_POINT *b) { +void ec_GFp_mont_add(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_JACOBIAN *a, const EC_JACOBIAN *b) { if (a == b) { ec_GFp_mont_dbl(group, out, a); return; @@ -317,7 +318,7 @@ void ec_GFp_mont_add(const EC_GROUP *group, EC_RAW_POINT *out, // This case will never occur in the constant-time |ec_GFp_mont_mul|. BN_ULONG is_nontrivial_double = ~xneq & ~yneq & z1nz & z2nz; - if (is_nontrivial_double) { + if (constant_time_declassify_w(is_nontrivial_double)) { ec_GFp_mont_dbl(group, out, a); return; } @@ -357,8 +358,8 @@ void ec_GFp_mont_add(const EC_GROUP *group, EC_RAW_POINT *out, ec_felem_select(group, &out->Z, z2nz, &z_out, &a->Z); } -void ec_GFp_mont_dbl(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a) { +void ec_GFp_mont_dbl(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a) { if (group->a_is_minus3) { // The method is taken from: // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b @@ -453,7 +454,7 @@ void ec_GFp_mont_dbl(const EC_GROUP *group, EC_RAW_POINT *r, } static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *r) { if (!group->field_greater_than_order || group->field.width != group->order.width) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_test.cc index edcfeaac..a40dd169 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/ec_test.cc @@ -105,6 +105,20 @@ static const uint8_t kECKeyWithZeros[] = { 0x37, 0xbf, 0x51, 0xf5, }; +static const uint8_t kECKeyWithZerosPublic[] = { + 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, + 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, + 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, + 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, + 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, +}; + +static const uint8_t kECKeyWithZerosRawPrivate[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + // DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the // result or nullptr on error. static bssl::UniquePtr DecodeECPrivateKey(const uint8_t *in, @@ -191,11 +205,52 @@ TEST(ECTest, ZeroPadding) { EXPECT_TRUE(EncodeECPrivateKey(&out, key.get())); EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size())); + // Check the private key encodes correctly, including with the leading zeros. + EXPECT_EQ(32u, EC_KEY_priv2oct(key.get(), nullptr, 0)); + uint8_t buf[32]; + ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf))); + EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate)); + + // Buffer too small. + EXPECT_EQ(0u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf) - 1)); + + // Extra space in buffer. + uint8_t large_buf[33]; + ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), large_buf, sizeof(large_buf))); + EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate)); + + // Allocating API. + uint8_t *buf_alloc; + size_t len = EC_KEY_priv2buf(key.get(), &buf_alloc); + ASSERT_GT(len, 0u); + bssl::UniquePtr free_buf_alloc(buf_alloc); + EXPECT_EQ(Bytes(buf_alloc, len), Bytes(kECKeyWithZerosRawPrivate)); + // Keys without leading zeros also parse, but they encode correctly. key = DecodeECPrivateKey(kECKeyMissingZeros, sizeof(kECKeyMissingZeros)); ASSERT_TRUE(key); EXPECT_TRUE(EncodeECPrivateKey(&out, key.get())); EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size())); + + // Test the key can be constructed with |EC_KEY_oct2*|. + key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + ASSERT_TRUE(key); + ASSERT_TRUE(EC_KEY_oct2key(key.get(), kECKeyWithZerosPublic, + sizeof(kECKeyWithZerosPublic), nullptr)); + ASSERT_TRUE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate, + sizeof(kECKeyWithZerosRawPrivate))); + EXPECT_TRUE(EncodeECPrivateKey(&out, key.get())); + EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size())); + + // |EC_KEY_oct2priv|'s format is fixed-width and must match the group order. + key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + ASSERT_TRUE(key); + EXPECT_FALSE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate + 1, + sizeof(kECKeyWithZerosRawPrivate) - 1)); + uint8_t padded[sizeof(kECKeyWithZerosRawPrivate) + 1] = {0}; + memcpy(padded + 1, kECKeyWithZerosRawPrivate, + sizeof(kECKeyWithZerosRawPrivate)); + EXPECT_FALSE(EC_KEY_oct2priv(key.get(), padded, sizeof(padded))); } TEST(ECTest, SpecifiedCurve) { @@ -474,12 +529,12 @@ TEST(ECTest, BrainpoolP256r1) { EXPECT_EQ(0, BN_cmp(y.get(), qy.get())); } -class ECCurveTest : public testing::TestWithParam { +class ECCurveTest : public testing::TestWithParam { public: const EC_GROUP *group() const { return group_.get(); } void SetUp() override { - group_.reset(EC_GROUP_new_by_curve_name(GetParam().nid)); + group_.reset(EC_GROUP_new_by_curve_name(GetParam())); ASSERT_TRUE(group_); } @@ -489,7 +544,7 @@ class ECCurveTest : public testing::TestWithParam { TEST_P(ECCurveTest, SetAffine) { // Generate an EC_KEY. - bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_generate_key(key.get())); @@ -531,7 +586,7 @@ TEST_P(ECCurveTest, SetAffine) { } TEST_P(ECCurveTest, IsOnCurve) { - bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_generate_key(key.get())); @@ -555,12 +610,12 @@ TEST_P(ECCurveTest, IsOnCurve) { } TEST_P(ECCurveTest, Compare) { - bssl::UniquePtr key1(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key1(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key1); ASSERT_TRUE(EC_KEY_generate_key(key1.get())); const EC_POINT *pub1 = EC_KEY_get0_public_key(key1.get()); - bssl::UniquePtr key2(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key2(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key2); ASSERT_TRUE(EC_KEY_generate_key(key2.get())); const EC_POINT *pub2 = EC_KEY_get0_public_key(key2.get()); @@ -601,6 +656,7 @@ TEST_P(ECCurveTest, Compare) { bssl::UniquePtr inf1(EC_POINT_new(group())), inf2(EC_POINT_new(group())); ASSERT_TRUE(inf1); + ASSERT_TRUE(inf2); ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf1.get())); // |q| is currently -|pub2|. ASSERT_TRUE(EC_POINT_add(group(), inf2.get(), pub2, q.get(), nullptr)); @@ -610,13 +666,13 @@ TEST_P(ECCurveTest, Compare) { TEST_P(ECCurveTest, GenerateFIPS) { // Generate an EC_KEY. - bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_generate_key_fips(key.get())); } TEST_P(ECCurveTest, AddingEqualPoints) { - bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_generate_key(key.get())); @@ -785,11 +841,11 @@ TEST_P(ECCurveTest, MulNonMinimal) { // Test that EC_KEY_set_private_key rejects invalid values. TEST_P(ECCurveTest, SetInvalidPrivateKey) { - bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam().nid)); + bssl::UniquePtr key(EC_KEY_new_by_curve_name(GetParam())); ASSERT_TRUE(key); - bssl::UniquePtr bn(BN_new()); - ASSERT_TRUE(BN_one(bn.get())); + bssl::UniquePtr bn(BN_dup(BN_value_one())); + ASSERT_TRUE(bn); BN_set_negative(bn.get(), 1); EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get())) << "Unexpectedly set a key of -1"; @@ -800,6 +856,11 @@ TEST_P(ECCurveTest, SetInvalidPrivateKey) { EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get())) << "Unexpectedly set a key of the group order."; ERR_clear_error(); + + BN_zero(bn.get()); + EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get())) + << "Unexpectedly set a key of 0"; + ERR_clear_error(); } TEST_P(ECCurveTest, IgnoreOct2PointReturnValue) { @@ -882,26 +943,53 @@ TEST_P(ECCurveTest, P224Bug) { TEST_P(ECCurveTest, GPlusMinusG) { const EC_POINT *g = EC_GROUP_get0_generator(group()); + bssl::UniquePtr p(EC_POINT_dup(g, group())); ASSERT_TRUE(p); ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr)); - bssl::UniquePtr sum(EC_POINT_new(group())); + bssl::UniquePtr sum(EC_POINT_new(group())); + ASSERT_TRUE(sum); ASSERT_TRUE(EC_POINT_add(group(), sum.get(), g, p.get(), nullptr)); EXPECT_TRUE(EC_POINT_is_at_infinity(group(), sum.get())); } -static std::vector AllCurves() { +// Test that we refuse to encode or decode the point at infinity. +TEST_P(ECCurveTest, EncodeInfinity) { + // The point at infinity is encoded as a single zero byte, but we do not + // support it. + static const uint8_t kInfinity[] = {0}; + bssl::UniquePtr inf(EC_POINT_new(group())); + ASSERT_TRUE(inf); + EXPECT_FALSE(EC_POINT_oct2point(group(), inf.get(), kInfinity, + sizeof(kInfinity), nullptr)); + + // Encoding it also fails. + ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf.get())); + uint8_t buf[128]; + EXPECT_EQ( + 0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED, + buf, sizeof(buf), nullptr)); + + // Measuring the length of the encoding also fails. + EXPECT_EQ( + 0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED, + nullptr, 0, nullptr)); +} + +static std::vector AllCurves() { const size_t num_curves = EC_get_builtin_curves(nullptr, 0); std::vector curves(num_curves); EC_get_builtin_curves(curves.data(), num_curves); - return curves; + std::vector nids; + for (const auto& curve : curves) { + nids.push_back(curve.nid); + } + return nids; } -static std::string CurveToString( - const testing::TestParamInfo ¶ms) { - // The comment field contains characters GTest rejects, so use the OBJ name. - return OBJ_nid2sn(params.param.nid); +static std::string CurveToString(const testing::TestParamInfo ¶ms) { + return OBJ_nid2sn(params.param); } INSTANTIATE_TEST_SUITE_P(All, ECCurveTest, testing::ValuesIn(AllCurves()), @@ -1124,8 +1212,18 @@ TEST(ECTest, DeriveFromSecret) { } TEST(ECTest, HashToCurve) { + auto hash_to_curve_p384_sha512_draft07 = + [](const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, + size_t dst_len, const uint8_t *msg, size_t msg_len) -> int { + if (EC_GROUP_cmp(group, out->group, NULL) != 0) { + return 0; + } + return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(group, &out->raw, dst, + dst_len, msg, msg_len); + }; + struct HashToCurveTest { - int (*hash_to_curve)(const EC_GROUP *group, EC_RAW_POINT *out, + int (*hash_to_curve)(const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, size_t dst_len, const uint8_t *msg, size_t msg_len); int curve_nid; @@ -1135,26 +1233,71 @@ TEST(ECTest, HashToCurve) { const char *y_hex; }; static const HashToCurveTest kTests[] = { + // See draft-irtf-cfrg-hash-to-curve-16, appendix J.1.1. + {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1, + "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "", + "2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91" + "c44247d3e4", + "8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9a" + "b5c43e8415"}, + {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1, + "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abc", + "0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775da" + "c4a3388a0f", + "5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71" + "ffd424212e"}, + {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1, + "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abcdef0123456789", + "65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c15268118" + "64e544ed80", + "cad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d" + "6df9b56ca3"}, + {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1, + "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", + "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqqqqqqqq", + "4be61ee205094282ba8a2042bcb48d88dfbb609301c49aa8b07853" + "3dc65a0b5d", + "98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539" + "d2bfb3c29e"}, + {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1, + "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", + "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "457ae2981f70ca85d8e24c308b14db22f3e3862c5ea0f652ca38b5" + "e49cd64bc5", + "ecb9f0eadc9aeed232dabc53235368c1394c78de05dd96893eefa6" + "2b0f4757dc"}, + // See draft-irtf-cfrg-hash-to-curve-07, appendix G.2.1. - {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1, + {hash_to_curve_p384_sha512_draft07, NID_secp384r1, "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "", "2fc0b9efdd63a8e43b4db88dc12f03c798f6fd91bccac0c9096185" "4386e58fdc54fc2a01f0f358759054ce1f9b762025", "949b936fabb72cdb02cd7980b86cb6a3adf286658e81301648851d" "b8a49d9bec00ccb57698d559fc5960fa5030a8e54b"}, - {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1, + {hash_to_curve_p384_sha512_draft07, NID_secp384r1, "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abc", "4f3338035391e8ce8ce40c974136f0edc97f392ffd44a643338741" "8ed1b8c2603487e1688ec151f048fbc6b2c138c92f", "152b90aef6558be328a3168855fb1906452e7167b0f7c8a56ff9d4" "fa87d6fb522cdf8e409db54418b2c764fd26260757"}, - {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1, + {hash_to_curve_p384_sha512_draft07, NID_secp384r1, "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789", "e9e5d7ac397e123d060ad44301cbc8eb972f6e64ebcff29dcc9b9a" "10357902aace2240c580fec85e5b427d98b4e80703", "916cb8963521ad75105be43cc4148e5a5bbb4fcf107f1577e4f7fa" "3ca58cd786aa76890c8e687d2353393bc16c78ec4d"}, - {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1, + {hash_to_curve_p384_sha512_draft07, NID_secp384r1, "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" @@ -1181,7 +1324,7 @@ TEST(ECTest, HashToCurve) { bssl::UniquePtr p(EC_POINT_new(group.get())); ASSERT_TRUE(p); ASSERT_TRUE(test.hash_to_curve( - group.get(), &p->raw, reinterpret_cast(test.dst), + group.get(), p.get(), reinterpret_cast(test.dst), strlen(test.dst), reinterpret_cast(test.msg), strlen(test.msg))); @@ -1198,11 +1341,30 @@ TEST(ECTest, HashToCurve) { // hash-to-curve functions should check for the wrong group. bssl::UniquePtr p224(EC_GROUP_new_by_curve_name(NID_secp224r1)); ASSERT_TRUE(p224); - EC_RAW_POINT p; + bssl::UniquePtr p384(EC_GROUP_new_by_curve_name(NID_secp384r1)); + ASSERT_TRUE(p384); + EC_JACOBIAN raw; + bssl::UniquePtr p_p384(EC_POINT_new(p384.get())); + ASSERT_TRUE(p_p384); + bssl::UniquePtr p_p224(EC_POINT_new(p224.get())); + ASSERT_TRUE(p_p224); static const uint8_t kDST[] = {0, 1, 2, 3}; static const uint8_t kMessage[] = {4, 5, 6, 7}; - EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( - p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); + EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu( + p224.get(), &raw, kDST, sizeof(kDST), kMessage, sizeof(kMessage))); + EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu( + p224.get(), p_p224.get(), kDST, sizeof(kDST), kMessage, + sizeof(kMessage))); + EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu( + p224.get(), p_p384.get(), kDST, sizeof(kDST), kMessage, + sizeof(kMessage))); + EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu( + p384.get(), p_p224.get(), kDST, sizeof(kDST), kMessage, + sizeof(kMessage))); + + // Zero-length DSTs are not allowed. + EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu( + p384.get(), &raw, nullptr, 0, kMessage, sizeof(kMessage))); } TEST(ECTest, HashToScalar) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/internal.h index 289c3aa5..bb418151 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/internal.h @@ -70,10 +70,11 @@ #include +#include + #include #include #include -#include #include "../bn/internal.h" @@ -90,9 +91,11 @@ extern "C" { // be the largest fields anyone plausibly uses. #define EC_MAX_BYTES 66 #define EC_MAX_WORDS ((EC_MAX_BYTES + BN_BYTES - 1) / BN_BYTES) +#define EC_MAX_COMPRESSED (EC_MAX_BYTES + 1) +#define EC_MAX_UNCOMPRESSED (2 * EC_MAX_BYTES + 1) -OPENSSL_STATIC_ASSERT(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS, - "bn_*_small functions not usable"); +static_assert(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS, + "bn_*_small functions not usable"); // Scalars. @@ -100,9 +103,7 @@ OPENSSL_STATIC_ASSERT(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS, // An EC_SCALAR is an integer fully reduced modulo the order. Only the first // |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP| // and must not be mixed between groups. -typedef union { - // bytes is the representation of the scalar in little-endian order. - uint8_t bytes[EC_MAX_BYTES]; +typedef struct { BN_ULONG words[EC_MAX_WORDS]; } EC_SCALAR; @@ -120,8 +121,8 @@ OPENSSL_EXPORT void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, // ec_scalar_from_bytes deserializes |in| and stores the resulting scalar over // group |group| to |out|. It returns one on success and zero if |in| is // invalid. -int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out, - const uint8_t *in, size_t len); +OPENSSL_EXPORT int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t *in, size_t len); // ec_scalar_reduce sets |out| to |words|, reduced modulo the group order. // |words| must be less than order^2. |num| must be at most twice the width of @@ -192,9 +193,7 @@ void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask, // are used. An |EC_FELEM| is specific to an |EC_GROUP| and must not be mixed // between groups. Additionally, the representation (whether or not elements are // represented in Montgomery-form) may vary between |EC_METHOD|s. -typedef union { - // bytes is the representation of the field element in little-endian order. - uint8_t bytes[EC_MAX_BYTES]; +typedef struct { BN_ULONG words[EC_MAX_WORDS]; } EC_FELEM; @@ -244,16 +243,14 @@ int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a, const EC_FELEM *b); // Points. // // Points may represented in affine coordinates as |EC_AFFINE| or Jacobian -// coordinates as |EC_RAW_POINT|. Affine coordinates directly represent a +// coordinates as |EC_JACOBIAN|. Affine coordinates directly represent a // point on the curve, but point addition over affine coordinates requires // costly field inversions, so arithmetic is done in Jacobian coordinates. // Converting from affine to Jacobian is cheap, while converting from Jacobian // to affine costs a field inversion. (Jacobian coordinates amortize the field // inversions needed in a sequence of point operations.) -// -// TODO(davidben): Rename |EC_RAW_POINT| to |EC_JACOBIAN|. -// An EC_RAW_POINT represents an elliptic curve point in Jacobian coordinates. +// An EC_JACOBIAN represents an elliptic curve point in Jacobian coordinates. // Unlike |EC_POINT|, it is a plain struct which can be stack-allocated and // needs no cleanup. It is specific to an |EC_GROUP| and must not be mixed // between groups. @@ -261,7 +258,7 @@ typedef struct { // X, Y, and Z are Jacobian projective coordinates. They represent // (X/Z^2, Y/Z^3) if Z != 0 and the point at infinity otherwise. EC_FELEM X, Y, Z; -} EC_RAW_POINT; +} EC_JACOBIAN; // An EC_AFFINE represents an elliptic curve point in affine coordinates. // coordinates. Note the point at infinity cannot be represented in affine @@ -272,7 +269,7 @@ typedef struct { // ec_affine_to_jacobian converts |p| to Jacobian form and writes the result to // |*out|. This operation is very cheap and only costs a few copies. -void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, +void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out, const EC_AFFINE *p); // ec_jacobian_to_affine converts |p| to affine form and writes the result to @@ -282,8 +279,8 @@ void ec_affine_to_jacobian(const EC_GROUP *group, EC_RAW_POINT *out, // // If only extracting the x-coordinate, use |ec_get_x_coordinate_*| which is // slightly faster. -int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *p); +OPENSSL_EXPORT int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, + const EC_JACOBIAN *p); // ec_jacobian_to_affine_batch converts |num| points in |in| from Jacobian // coordinates to affine coordinates and writes the results to |out|. It returns @@ -292,7 +289,7 @@ int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out, // This function is not implemented for all curves. Add implementations as // needed. int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *in, size_t num); + const EC_JACOBIAN *in, size_t num); // ec_point_set_affine_coordinates sets |out|'s to a point with affine // coordinates |x| and |y|. It returns one if the point is on the curve and @@ -301,14 +298,21 @@ int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out, int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out, const EC_FELEM *x, const EC_FELEM *y); +// ec_point_mul_no_self_test does the same as |EC_POINT_mul|, but doesn't try to +// run the self-test first. This is for use in the self tests themselves, to +// prevent an infinite loop. +int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *g_scalar, const EC_POINT *p, + const BIGNUM *p_scalar, BN_CTX *ctx); + // ec_point_mul_scalar sets |r| to |p| * |scalar|. Both inputs are considered // secret. -int ec_point_mul_scalar(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, const EC_SCALAR *scalar); +int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar); // ec_point_mul_scalar_base sets |r| to generator * |scalar|. |scalar| is // treated as secret. -int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar); // ec_point_mul_scalar_batch sets |r| to |p0| * |scalar0| + |p1| * |scalar1| + @@ -329,10 +333,10 @@ int ec_point_mul_scalar_base(const EC_GROUP *group, EC_RAW_POINT *r, // none. If generalizing to tuned curves, this may be useful. However, we still // must double up to the least efficient input, so precomputed tables can only // save table setup and allow a wider window size. -int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); +int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2); #define EC_MONT_PRECOMP_COMB_SIZE 5 @@ -351,7 +355,7 @@ typedef union { // This function is not implemented for all curves. Add implementations as // needed. int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, - const EC_RAW_POINT *p); + const EC_JACOBIAN *p); // ec_point_mul_scalar_precomp sets |r| to |p0| * |scalar0| + |p1| * |scalar1| + // |p2| * |scalar2|. |p1| or |p2| may be NULL to skip the corresponding term. @@ -375,7 +379,7 @@ int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, // none. If generalizing to tuned curves, we should add a parameter for the base // point and arrange for the generic implementation to have base point tables // available. -int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_JACOBIAN *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, const EC_SCALAR *scalar2); @@ -384,9 +388,9 @@ int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_RAW_POINT *r, // generator * |g_scalar| + |p| * |p_scalar|. It assumes that the inputs are // public so there is no concern about leaking their values through timing. OPENSSL_EXPORT int ec_point_mul_scalar_public(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *p_scalar); // ec_point_mul_scalar_public_batch sets |r| to the sum of generator * @@ -397,15 +401,15 @@ OPENSSL_EXPORT int ec_point_mul_scalar_public(const EC_GROUP *group, // // This function is not implemented for all curves. Add implementations as // needed. -int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *points, + const EC_JACOBIAN *points, const EC_SCALAR *scalars, size_t num); // ec_point_select, in constant time, sets |out| to |a| if |mask| is all ones // and |b| if |mask| is all zeros. -void ec_point_select(const EC_GROUP *group, EC_RAW_POINT *out, BN_ULONG mask, - const EC_RAW_POINT *a, const EC_RAW_POINT *b); +void ec_point_select(const EC_GROUP *group, EC_JACOBIAN *out, BN_ULONG mask, + const EC_JACOBIAN *a, const EC_JACOBIAN *b); // ec_affine_select behaves like |ec_point_select| but acts on affine points. void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask, @@ -418,14 +422,14 @@ void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, // ec_cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group // order, with |r|. It returns one if the values match and zero if |p| is the // point at infinity of the values do not match. -int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, +int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p, const EC_SCALAR *r); // ec_get_x_coordinate_as_scalar sets |*out| to |p|'s x-coordinate, modulo // |group->order|. It returns one on success and zero if |p| is the point at // infinity. int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, - const EC_RAW_POINT *p); + const EC_JACOBIAN *p); // ec_get_x_coordinate_as_bytes writes |p|'s affine x-coordinate to |out|, which // must have at must |max_out| bytes. It sets |*out_len| to the number of bytes @@ -433,13 +437,20 @@ int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out, // field. This function returns one on success and zero on failure. int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, size_t max_out, - const EC_RAW_POINT *p); + const EC_JACOBIAN *p); -// ec_point_to_bytes behaves like |EC_POINT_point2oct| but takes an -// |EC_AFFINE|. +// ec_point_byte_len returns the number of bytes in the byte representation of +// a non-infinity point in |group|, encoded according to |form|, or zero if +// |form| is invalid. +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form); + +// ec_point_to_bytes encodes |point| according to |form| and writes the result +// |buf|. It returns the size of the output on success or zero on error. At most +// |max_out| bytes will be written. The buffer should be at least +// |ec_point_byte_len| long to guarantee success. size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, point_conversion_form_t form, uint8_t *buf, - size_t len); + size_t max_out); // ec_point_from_uncompressed parses |in| as a point in uncompressed form and // sets the result to |out|. It returns one on success and zero if the input was @@ -450,12 +461,12 @@ int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out, // ec_set_to_safe_point sets |out| to an arbitrary point on |group|, either the // generator or the point at infinity. This is used to guard against callers of // external APIs not checking the return value. -void ec_set_to_safe_point(const EC_GROUP *group, EC_RAW_POINT *out); +void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out); // ec_affine_jacobian_equal returns one if |a| and |b| represent the same point // and zero otherwise. It treats both inputs as secret. int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a, - const EC_RAW_POINT *b); + const EC_JACOBIAN *b); // Implementation details. @@ -468,49 +479,50 @@ struct ec_method_st { // point_get_affine_coordinates sets |*x| and |*y| to the affine coordinates // of |p|. Either |x| or |y| may be NULL to omit it. It returns one on success - // and zero if |p| is the point at infinity. - int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_RAW_POINT *p, + // and zero if |p| is the point at infinity. It leaks whether |p| was the + // point at infinity, but otherwise treats |p| as secret. + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_JACOBIAN *p, EC_FELEM *x, EC_FELEM *y); // jacobian_to_affine_batch implements |ec_jacobian_to_affine_batch|. int (*jacobian_to_affine_batch)(const EC_GROUP *group, EC_AFFINE *out, - const EC_RAW_POINT *in, size_t num); + const EC_JACOBIAN *in, size_t num); // add sets |r| to |a| + |b|. - void (*add)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *a, - const EC_RAW_POINT *b); + void (*add)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *a, + const EC_JACOBIAN *b); // dbl sets |r| to |a| + |a|. - void (*dbl)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *a); + void (*dbl)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *a); // mul sets |r| to |scalar|*|p|. - void (*mul)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *p, + void (*mul)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *p, const EC_SCALAR *scalar); // mul_base sets |r| to |scalar|*generator. - void (*mul_base)(const EC_GROUP *group, EC_RAW_POINT *r, + void (*mul_base)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar); // mul_batch implements |ec_mul_scalar_batch|. - void (*mul_batch)(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); + void (*mul_batch)(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2); // mul_public sets |r| to |g_scalar|*generator + |p_scalar|*|p|. It assumes // that the inputs are public so there is no concern about leaking their // values through timing. // // This function may be omitted if |mul_public_batch| is provided. - void (*mul_public)(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_SCALAR *g_scalar, const EC_RAW_POINT *p, + void (*mul_public)(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_SCALAR *g_scalar, const EC_JACOBIAN *p, const EC_SCALAR *p_scalar); // mul_public_batch implements |ec_point_mul_scalar_public_batch|. - int (*mul_public_batch)(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_SCALAR *g_scalar, const EC_RAW_POINT *points, + int (*mul_public_batch)(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_SCALAR *g_scalar, const EC_JACOBIAN *points, const EC_SCALAR *scalars, size_t num); // init_precomp implements |ec_init_precomp|. int (*init_precomp)(const EC_GROUP *group, EC_PRECOMP *out, - const EC_RAW_POINT *p); + const EC_JACOBIAN *p); // mul_precomp implements |ec_point_mul_scalar_precomp|. - void (*mul_precomp)(const EC_GROUP *group, EC_RAW_POINT *r, + void (*mul_precomp)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, const EC_SCALAR *scalar2); @@ -549,6 +561,12 @@ struct ec_method_st { // // This function is used in hash-to-curve and may be NULL in curves not used // with hash-to-curve. + // + // TODO(https://crbug.com/boringssl/567): hash-to-curve uses this as part of + // computing a square root, which is what compressed coordinates ultimately + // needs to avoid |BIGNUM|. Can we unify this a bit? By generalizing to + // arbitrary exponentiation, we also miss an opportunity to use a specialized + // addition chain. void (*felem_exp)(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a, const BN_ULONG *exp, size_t num_exp); @@ -564,7 +582,7 @@ struct ec_method_st { // cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group // order, with |r|. It returns one if the values match and zero if |p| is the // point at infinity of the values do not match. - int (*cmp_x_coordinate)(const EC_GROUP *group, const EC_RAW_POINT *p, + int (*cmp_x_coordinate)(const EC_GROUP *group, const EC_JACOBIAN *p, const EC_SCALAR *r); } /* EC_METHOD */; @@ -618,27 +636,32 @@ struct ec_point_st { EC_GROUP *group; // raw is the group-specific point data. Functions that take |EC_POINT| // typically check consistency with |EC_GROUP| while functions that take - // |EC_RAW_POINT| do not. Thus accesses to this field should be externally + // |EC_JACOBIAN| do not. Thus accesses to this field should be externally // checked for consistency. - EC_RAW_POINT raw; + EC_JACOBIAN raw; } /* EC_POINT */; EC_GROUP *ec_group_new(const EC_METHOD *meth); -void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, const EC_SCALAR *scalar); -void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, +void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar); +void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar); -void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, const EC_SCALAR *scalar2); +void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2); int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, - const EC_RAW_POINT *p); -void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, + const EC_JACOBIAN *p); +void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_JACOBIAN *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, const EC_SCALAR *scalar2); +void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out, + const BN_ULONG *words, size_t num); +void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out, + const EC_FELEM *a, const BN_ULONG *exp, + size_t num_exp); // ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of // |scalar| to |out|. |out| must have room for |bits| + 1 elements, each of @@ -651,9 +674,9 @@ void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, void ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar, size_t bits, int w); -int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *points, + const EC_JACOBIAN *points, const EC_SCALAR *scalars, size_t num); // method functions in simple.c @@ -663,17 +686,17 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b); -void ec_GFp_simple_point_init(EC_RAW_POINT *); -void ec_GFp_simple_point_copy(EC_RAW_POINT *, const EC_RAW_POINT *); -void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_RAW_POINT *); -void ec_GFp_mont_add(const EC_GROUP *, EC_RAW_POINT *r, const EC_RAW_POINT *a, - const EC_RAW_POINT *b); -void ec_GFp_mont_dbl(const EC_GROUP *, EC_RAW_POINT *r, const EC_RAW_POINT *a); -void ec_GFp_simple_invert(const EC_GROUP *, EC_RAW_POINT *); -int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_RAW_POINT *); -int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_RAW_POINT *); -int ec_GFp_simple_points_equal(const EC_GROUP *, const EC_RAW_POINT *a, - const EC_RAW_POINT *b); +void ec_GFp_simple_point_init(EC_JACOBIAN *); +void ec_GFp_simple_point_copy(EC_JACOBIAN *, const EC_JACOBIAN *); +void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_JACOBIAN *); +void ec_GFp_mont_add(const EC_GROUP *, EC_JACOBIAN *r, const EC_JACOBIAN *a, + const EC_JACOBIAN *b); +void ec_GFp_mont_dbl(const EC_GROUP *, EC_JACOBIAN *r, const EC_JACOBIAN *a); +void ec_GFp_simple_invert(const EC_GROUP *, EC_JACOBIAN *); +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_JACOBIAN *); +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_JACOBIAN *); +int ec_GFp_simple_points_equal(const EC_GROUP *, const EC_JACOBIAN *a, + const EC_JACOBIAN *b); void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a); @@ -681,7 +704,7 @@ int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a); -int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, +int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p, const EC_SCALAR *r); void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go index 716da55b..1d3896aa 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2018, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-x86_64-tests.go b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go similarity index 84% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-x86_64-tests.go rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go index 958a97a5..e10990b3 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-x86_64-tests.go +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2018, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main @@ -69,7 +71,7 @@ func fromMontgomery(z, x *big.Int) *big.Int { func isAffineInfinity(x, y *big.Int) bool { // Infinity, in affine coordinates, is represented as (0, 0) by - // both Go and p256-x86_64-asm.pl. + // both Go, p256-x86_64-asm.pl and p256-armv8-asm.pl. return x.Sign() == 0 && y.Sign() == 0 } @@ -107,8 +109,8 @@ func toJacobian(xIn, yIn *big.Int) (x, y, z *big.Int) { // arbitrary X and Y and include the special case. We also have // not verified that add and double preserve this // property. Thus, generate test vectors with unrelated X and Y, - // to test that p256-x86_64-asm.pl correctly handles - // unconstrained representations of infinity. + // to test that p256-x86_64-asm.pl and p256-armv8-asm.pl correctly + // handle unconstrained representations of infinity. x = randNonZeroInt(p) y = randNonZeroInt(p) z = zero diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_tables.go b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_tables.go index 34e8c23a..120c40bd 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_tables.go +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/make_tables.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2020, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2020, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main @@ -23,8 +25,8 @@ import ( ) func main() { - if err := writeP256X86_64Table("p256-x86_64-table.h"); err != nil { - fmt.Fprintf(os.Stderr, "Error writing p256-x86_64-table.h: %s\n", err) + if err := writeP256NistzTable("p256-nistz-table.h"); err != nil { + fmt.Fprintf(os.Stderr, "Error writing p256-nistz-table.h: %s\n", err) os.Exit(1) } @@ -34,7 +36,7 @@ func main() { } } -func writeP256X86_64Table(path string) error { +func writeP256NistzTable(path string) error { curve := elliptic.P256() tables := make([][][2]*big.Int, 0, 37) for shift := 0; shift < 256; shift += 7 { @@ -59,7 +61,7 @@ func writeP256X86_64Table(path string) error { */ // This is the precomputed constant time access table for the code in -// p256-x86_64.c, for the default generator. The table consists of 37 +// p256-nistz.c, for the default generator. The table consists of 37 // subtables, each subtable contains 64 affine points. The affine points are // encoded as eight uint64's, four for the x coordinate and four for the y. // Both values are in little-endian order. There are 37 tables because a @@ -151,7 +153,7 @@ func writeP256Table(path string) error { // Tables for other points have table[i] = iG for i in 0 .. 16. // fiat_p256_g_pre_comp is the table of precomputed base points -#if defined(BORINGSSL_NISTP256_64BIT) +#if defined(OPENSSL_64_BIT) static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = ` if _, err := f.WriteString(fileHeader); err != nil { return err diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/oct.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/oct.c index ddd0f37a..eb77643c 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/oct.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/oct.c @@ -73,9 +73,7 @@ #include "internal.h" -size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, - point_conversion_form_t form, uint8_t *buf, - size_t len) { +size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form) { if (form != POINT_CONVERSION_COMPRESSED && form != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); @@ -88,27 +86,30 @@ size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, // Uncompressed points have a second coordinate. output_len += field_len; } + return output_len; +} - // if 'buf' is NULL, just return required length - if (buf != NULL) { - if (len < output_len) { - OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); - return 0; - } +size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point, + point_conversion_form_t form, uint8_t *buf, + size_t max_out) { + size_t output_len = ec_point_byte_len(group, form); + if (max_out < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + return 0; + } - size_t field_len_out; - ec_felem_to_bytes(group, buf + 1, &field_len_out, &point->X); - assert(field_len_out == field_len); + size_t field_len; + ec_felem_to_bytes(group, buf + 1, &field_len, &point->X); + assert(field_len == BN_num_bytes(&group->field)); - if (form == POINT_CONVERSION_UNCOMPRESSED) { - ec_felem_to_bytes(group, buf + 1 + field_len, &field_len_out, &point->Y); - assert(field_len_out == field_len); - buf[0] = form; - } else { - uint8_t y_buf[EC_MAX_BYTES]; - ec_felem_to_bytes(group, y_buf, &field_len_out, &point->Y); - buf[0] = form + (y_buf[field_len_out - 1] & 1); - } + if (form == POINT_CONVERSION_UNCOMPRESSED) { + ec_felem_to_bytes(group, buf + 1 + field_len, &field_len, &point->Y); + assert(field_len == BN_num_bytes(&group->field)); + buf[0] = form; + } else { + uint8_t y_buf[EC_MAX_BYTES]; + ec_felem_to_bytes(group, y_buf, &field_len, &point->Y); + buf[0] = form + (y_buf[field_len - 1] & 1); } return output_len; @@ -209,16 +210,46 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, uint8_t *buf, - size_t len, BN_CTX *ctx) { + size_t max_out, BN_CTX *ctx) { if (EC_GROUP_cmp(group, point->group, NULL) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } + if (buf == NULL) { + // When |buf| is NULL, just return the number of bytes that would be + // written, without doing an expensive Jacobian-to-affine conversion. + if (ec_GFp_simple_is_at_infinity(group, &point->raw)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + return ec_point_byte_len(group, form); + } EC_AFFINE affine; if (!ec_jacobian_to_affine(group, &affine, &point->raw)) { return 0; } - return ec_point_to_bytes(group, &affine, form, buf, len); + return ec_point_to_bytes(group, &affine, form, buf, max_out); +} + +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t **out_buf, + BN_CTX *ctx) { + *out_buf = NULL; + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *buf = OPENSSL_malloc(len); + if (buf == NULL) { + return 0; + } + len = EC_POINT_point2oct(group, point, form, buf, len, ctx); + if (len == 0) { + OPENSSL_free(buf); + return 0; + } + *out_buf = buf; + return len; } int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, @@ -289,8 +320,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, } if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { - unsigned long err = ERR_peek_last_error(); - + uint32_t err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { ERR_clear_error(); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p224-64.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p224-64.c index da4308c0..b646e821 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p224-64.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p224-64.c @@ -52,11 +52,6 @@ typedef uint128_t p224_widelimb; typedef p224_limb p224_felem[4]; typedef p224_widelimb p224_widefelem[7]; -// Field element represented as a byte arrary. 28*8 = 224 bits is also the -// group order size for the elliptic curve, and we also use this type for -// scalars for point multiplication. -typedef uint8_t p224_felem_bytearray[28]; - // Precomputed multiples of the standard generator // Points are given in coordinates (X, Y, Z) where Z normally is 1 // (0 for the point at infinity). @@ -180,31 +175,16 @@ static const p224_felem g_p224_pre_comp[2][16][3] = { {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, {1, 0, 0, 0}}}}; -static uint64_t p224_load_u64(const uint8_t in[8]) { - uint64_t ret; - OPENSSL_memcpy(&ret, in, sizeof(ret)); - return ret; -} // Helper functions to convert field elements to/from internal representation -static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) { - out[0] = p224_load_u64(in) & 0x00ffffffffffffff; - out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff; - out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff; - out[3] = p224_load_u64(in + 20) >> 8; -} - -static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) { - for (size_t i = 0; i < 7; ++i) { - out[i] = in[0] >> (8 * i); - out[i + 7] = in[1] >> (8 * i); - out[i + 14] = in[2] >> (8 * i); - out[i + 21] = in[3] >> (8 * i); - } -} static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) { - p224_bin28_to_felem(out, in->bytes); + // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM| + // uses four 64-bit words. (The top-most word only has 32 bits.) + out[0] = in->words[0] & 0x00ffffffffffffff; + out[1] = ((in->words[0] >> 56) | (in->words[1] << 8)) & 0x00ffffffffffffff; + out[2] = ((in->words[1] >> 48) | (in->words[2] << 16)) & 0x00ffffffffffffff; + out[3] = ((in->words[2] >> 40) | (in->words[3] << 24)) & 0x00ffffffffffffff; } // Requires 0 <= in < 2*p (always call p224_felem_reduce first) @@ -256,9 +236,12 @@ static void p224_felem_to_generic(EC_FELEM *out, const p224_felem in) { tmp2[2] = tmp[2]; tmp2[3] = tmp[3]; - p224_felem_to_bin28(out->bytes, tmp2); - // 224 is not a multiple of 64, so zero the remaining bytes. - OPENSSL_memset(out->bytes + 28, 0, 32 - 28); + // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM| + // uses four 64-bit words. (The top-most word only has 32 bits.) + out->words[0] = tmp2[0] | (tmp2[1] << 56); + out->words[1] = (tmp2[1] >> 8) | (tmp2[2] << 48); + out->words[2] = (tmp2[2] >> 16) | (tmp2[3] << 40); + out->words[3] = tmp2[3] >> 24; } @@ -751,8 +734,8 @@ static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3, // tmp[i] < 2^116 + 2^64 + 8 < 2^117 p224_felem_reduce(ftmp, tmp); - // the formulae are incorrect if the points are equal - // so we check for this and do doubling if this happens + // The formulae are incorrect if the points are equal, so we check for this + // and do doubling if this happens. x_equal = p224_felem_is_zero(ftmp); y_equal = p224_felem_is_zero(ftmp3); z1_is_zero = p224_felem_is_zero(z1); @@ -760,7 +743,7 @@ static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3, // In affine coordinates, (X_1, Y_1) == (X_2, Y_2) p224_limb is_nontrivial_double = x_equal & y_equal & (1 - z1_is_zero) & (1 - z2_is_zero); - if (is_nontrivial_double) { + if (constant_time_declassify_w(is_nontrivial_double)) { p224_point_double(x3, y3, z3, x1, y1, z1); return; } @@ -865,20 +848,22 @@ static void p224_select_point(const uint64_t idx, size_t size, } } -// p224_get_bit returns the |i|th bit in |in| -static crypto_word_t p224_get_bit(const p224_felem_bytearray in, size_t i) { +// p224_get_bit returns the |i|th bit in |in|. +static crypto_word_t p224_get_bit(const EC_SCALAR *in, size_t i) { if (i >= 224) { return 0; } - return (in[i >> 3] >> (i & 7)) & 1; + static_assert(sizeof(in->words[0]) == 8, "BN_ULONG is not 64-bit"); + return (in->words[i >> 6] >> (i & 63)) & 1; } // Takes the Jacobian coordinates (X, Y, Z) of a point and returns // (X', Y') = (X/Z^2, Y/Z^3) static int ec_GFp_nistp224_point_get_affine_coordinates( - const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x, + const EC_GROUP *group, const EC_JACOBIAN *point, EC_FELEM *x, EC_FELEM *y) { - if (ec_GFp_simple_is_at_infinity(group, point)) { + if (constant_time_declassify_int( + ec_GFp_simple_is_at_infinity(group, point))) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; } @@ -911,8 +896,8 @@ static int ec_GFp_nistp224_point_get_affine_coordinates( return 1; } -static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a, const EC_RAW_POINT *b) { +static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a, const EC_JACOBIAN *b) { p224_felem x1, y1, z1, x2, y2, z2; p224_generic_to_felem(x1, &a->X); p224_generic_to_felem(y1, &a->Y); @@ -927,8 +912,8 @@ static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_RAW_POINT *r, p224_felem_to_generic(&r->Z, z1); } -static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a) { +static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a) { p224_felem x, y, z; p224_generic_to_felem(x, &a->X); p224_generic_to_felem(y, &a->Y); @@ -941,7 +926,7 @@ static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_RAW_POINT *r, } static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3], - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { OPENSSL_memset(out[0], 0, sizeof(p224_felem) * 3); p224_generic_to_felem(out[1][0], &p->X); @@ -959,8 +944,8 @@ static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3], } } -static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, +static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar) { p224_felem p_pre_comp[17][3]; ec_GFp_nistp224_make_precomp(p_pre_comp, p); @@ -977,12 +962,12 @@ static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, // Add every 5 doublings. if (i % 5 == 0) { - crypto_word_t bits = p224_get_bit(scalar->bytes, i + 4) << 5; - bits |= p224_get_bit(scalar->bytes, i + 3) << 4; - bits |= p224_get_bit(scalar->bytes, i + 2) << 3; - bits |= p224_get_bit(scalar->bytes, i + 1) << 2; - bits |= p224_get_bit(scalar->bytes, i) << 1; - bits |= p224_get_bit(scalar->bytes, i - 1); + crypto_word_t bits = p224_get_bit(scalar, i + 4) << 5; + bits |= p224_get_bit(scalar, i + 3) << 4; + bits |= p224_get_bit(scalar, i + 2) << 3; + bits |= p224_get_bit(scalar, i + 1) << 2; + bits |= p224_get_bit(scalar, i) << 1; + bits |= p224_get_bit(scalar, i - 1); crypto_word_t sign, digit; ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); @@ -1008,7 +993,7 @@ static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, } static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *scalar) { // Set nq to the point at infinity. p224_felem nq[3], tmp[3]; @@ -1022,10 +1007,10 @@ static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group, } // First, look 28 bits upwards. - crypto_word_t bits = p224_get_bit(scalar->bytes, i + 196) << 3; - bits |= p224_get_bit(scalar->bytes, i + 140) << 2; - bits |= p224_get_bit(scalar->bytes, i + 84) << 1; - bits |= p224_get_bit(scalar->bytes, i + 28); + crypto_word_t bits = p224_get_bit(scalar, i + 196) << 3; + bits |= p224_get_bit(scalar, i + 140) << 2; + bits |= p224_get_bit(scalar, i + 84) << 1; + bits |= p224_get_bit(scalar, i + 28); // Select the point to add, in constant time. p224_select_point(bits, 16, g_p224_pre_comp[1], tmp); @@ -1038,10 +1023,10 @@ static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group, } // Second, look at the current position/ - bits = p224_get_bit(scalar->bytes, i + 168) << 3; - bits |= p224_get_bit(scalar->bytes, i + 112) << 2; - bits |= p224_get_bit(scalar->bytes, i + 56) << 1; - bits |= p224_get_bit(scalar->bytes, i); + bits = p224_get_bit(scalar, i + 168) << 3; + bits |= p224_get_bit(scalar, i + 112) << 2; + bits |= p224_get_bit(scalar, i + 56) << 1; + bits |= p224_get_bit(scalar, i); // Select the point to add, in constant time. p224_select_point(bits, 16, g_p224_pre_comp[0], tmp); p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, @@ -1055,9 +1040,9 @@ static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group, } static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *p_scalar) { // TODO(davidben): If P-224 ECDSA verify performance ever matters, using // |ec_compute_wNAF| for |p_scalar| would likely be an easy improvement. @@ -1080,10 +1065,10 @@ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group, // Add multiples of the generator. if (i <= 27) { // First, look 28 bits upwards. - crypto_word_t bits = p224_get_bit(g_scalar->bytes, i + 196) << 3; - bits |= p224_get_bit(g_scalar->bytes, i + 140) << 2; - bits |= p224_get_bit(g_scalar->bytes, i + 84) << 1; - bits |= p224_get_bit(g_scalar->bytes, i + 28); + crypto_word_t bits = p224_get_bit(g_scalar, i + 196) << 3; + bits |= p224_get_bit(g_scalar, i + 140) << 2; + bits |= p224_get_bit(g_scalar, i + 84) << 1; + bits |= p224_get_bit(g_scalar, i + 28); size_t index = (size_t)bits; p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, @@ -1092,10 +1077,10 @@ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group, assert(!skip); // Second, look at the current position. - bits = p224_get_bit(g_scalar->bytes, i + 168) << 3; - bits |= p224_get_bit(g_scalar->bytes, i + 112) << 2; - bits |= p224_get_bit(g_scalar->bytes, i + 56) << 1; - bits |= p224_get_bit(g_scalar->bytes, i); + bits = p224_get_bit(g_scalar, i + 168) << 3; + bits |= p224_get_bit(g_scalar, i + 112) << 2; + bits |= p224_get_bit(g_scalar, i + 56) << 1; + bits |= p224_get_bit(g_scalar, i); index = (size_t)bits; p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1], @@ -1104,12 +1089,12 @@ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group, // Incorporate |p_scalar| every 5 doublings. if (i % 5 == 0) { - crypto_word_t bits = p224_get_bit(p_scalar->bytes, i + 4) << 5; - bits |= p224_get_bit(p_scalar->bytes, i + 3) << 4; - bits |= p224_get_bit(p_scalar->bytes, i + 2) << 3; - bits |= p224_get_bit(p_scalar->bytes, i + 1) << 2; - bits |= p224_get_bit(p_scalar->bytes, i) << 1; - bits |= p224_get_bit(p_scalar->bytes, i - 1); + crypto_word_t bits = p224_get_bit(p_scalar, i + 4) << 5; + bits |= p224_get_bit(p_scalar, i + 3) << 4; + bits |= p224_get_bit(p_scalar, i + 2) << 3; + bits |= p224_get_bit(p_scalar, i + 1) << 2; + bits |= p224_get_bit(p_scalar, i) << 1; + bits |= p224_get_bit(p_scalar, i - 1); crypto_word_t sign, digit; ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64-table.h b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz-table.h similarity index 99% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64-table.h rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz-table.h index 3af0b016..b81480bd 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64-table.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz-table.h @@ -9,7 +9,7 @@ */ // This is the precomputed constant time access table for the code in -// p256-x86_64.c, for the default generator. The table consists of 37 +// p256-nistz.c, for the default generator. The table consists of 37 // subtables, each subtable contains 64 affine points. The affine points are // encoded as eight uint64's, four for the x coordinate and four for the y. // Both values are in little-endian order. There are 37 tables because a diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.c similarity index 84% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.c rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.c index 29ae1936..85343fd9 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -31,10 +30,10 @@ #include "../delocate.h" #include "../../internal.h" #include "internal.h" -#include "p256-x86_64.h" +#include "p256-nistz.h" - -#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_SMALL) typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; @@ -46,7 +45,7 @@ static const BN_ULONG ONE[P256_LIMBS] = { }; // Precomputed tables for the default generator -#include "p256-x86_64-table.h" +#include "p256-nistz-table.h" // Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in // util.c for details @@ -188,7 +187,7 @@ static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS], // r = p * p_scalar static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *p_scalar) { assert(p != NULL); assert(p_scalar != NULL); @@ -202,7 +201,7 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, // ~1599 ((96 * 16) + 63) bytes of stack space. alignas(64) P256_POINT table[16]; uint8_t p_str[33]; - OPENSSL_memcpy(p_str, p_scalar->bytes, 32); + OPENSSL_memcpy(p_str, p_scalar->words, 32); p_str[32] = 0; // table[0] is implicitly (0,0,0) (the point at infinity), therefore it is @@ -278,11 +277,6 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, ecp_nistz256_point_add(r, r, &h); } -typedef union { - P256_POINT p; - P256_POINT_AFFINE a; -} p256_point_union_t; - static crypto_word_t calc_first_wvalue(size_t *index, const uint8_t p_str[33]) { static const size_t kWindowSize = 7; static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; @@ -305,8 +299,8 @@ static crypto_word_t calc_wvalue(size_t *index, const uint8_t p_str[33]) { return booth_recode_w7(wvalue); } -static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, +static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar) { alignas(32) P256_POINT out; ecp_nistz256_windowed_mul(group, &out, p, scalar); @@ -317,57 +311,60 @@ static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, OPENSSL_memcpy(r->Z.words, out.Z, P256_LIMBS * sizeof(BN_ULONG)); } -static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, +static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar) { - alignas(32) p256_point_union_t t, p; - uint8_t p_str[33]; - OPENSSL_memcpy(p_str, scalar->bytes, 32); + OPENSSL_memcpy(p_str, scalar->words, 32); p_str[32] = 0; // First window size_t index = 0; crypto_word_t wvalue = calc_first_wvalue(&index, p_str); - ecp_nistz256_select_w7(&p.a, ecp_nistz256_precomputed[0], wvalue >> 1); - ecp_nistz256_neg(p.p.Z, p.p.Y); - copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + alignas(32) P256_POINT_AFFINE t; + alignas(32) P256_POINT p; + ecp_nistz256_select_w7(&t, ecp_nistz256_precomputed[0], wvalue >> 1); + ecp_nistz256_neg(p.Z, t.Y); + copy_conditional(t.Y, p.Z, wvalue & 1); - // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p| - // is infinity and |ONE| otherwise. |p| was computed from the table, so it + // Convert |t| from affine to Jacobian coordinates. We set Z to zero if |t| + // is infinity and |ONE| otherwise. |t| was computed from the table, so it // is infinity iff |wvalue >> 1| is zero. - OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); - copy_conditional(p.p.Z, ONE, is_not_zero(wvalue >> 1)); + OPENSSL_memcpy(p.X, t.X, sizeof(p.X)); + OPENSSL_memcpy(p.Y, t.Y, sizeof(p.Y)); + OPENSSL_memset(p.Z, 0, sizeof(p.Z)); + copy_conditional(p.Z, ONE, is_not_zero(wvalue >> 1)); for (int i = 1; i < 37; i++) { wvalue = calc_wvalue(&index, p_str); - ecp_nistz256_select_w7(&t.a, ecp_nistz256_precomputed[i], wvalue >> 1); + ecp_nistz256_select_w7(&t, ecp_nistz256_precomputed[i], wvalue >> 1); - ecp_nistz256_neg(t.p.Z, t.a.Y); - copy_conditional(t.a.Y, t.p.Z, wvalue & 1); + alignas(32) BN_ULONG neg_Y[P256_LIMBS]; + ecp_nistz256_neg(neg_Y, t.Y); + copy_conditional(t.Y, neg_Y, wvalue & 1); - // Note |ecp_nistz256_point_add_affine| does not work if |p.p| and |t.a| - // are the same non-infinity point. - ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + // Note |ecp_nistz256_point_add_affine| does not work if |p| and |t| are the + // same non-infinity point. + ecp_nistz256_point_add_affine(&p, &p, &t); } assert(group->field.width == P256_LIMBS); - OPENSSL_memcpy(r->X.words, p.p.X, P256_LIMBS * sizeof(BN_ULONG)); - OPENSSL_memcpy(r->Y.words, p.p.Y, P256_LIMBS * sizeof(BN_ULONG)); - OPENSSL_memcpy(r->Z.words, p.p.Z, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG)); } static void ecp_nistz256_points_mul_public(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *p_, + const EC_JACOBIAN *p_, const EC_SCALAR *p_scalar) { assert(p_ != NULL && p_scalar != NULL && g_scalar != NULL); - alignas(32) p256_point_union_t t, p; + alignas(32) P256_POINT p; uint8_t p_str[33]; - OPENSSL_memcpy(p_str, g_scalar->bytes, 32); + OPENSSL_memcpy(p_str, g_scalar->words, 32); p_str[32] = 0; // First window @@ -378,51 +375,55 @@ static void ecp_nistz256_points_mul_public(const EC_GROUP *group, // is infinity and |ONE| otherwise. |p| was computed from the table, so it // is infinity iff |wvalue >> 1| is zero. if ((wvalue >> 1) != 0) { - OPENSSL_memcpy(&p.a, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1], - sizeof(p.a)); - OPENSSL_memcpy(&p.p.Z, ONE, sizeof(p.p.Z)); + OPENSSL_memcpy(p.X, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1].X, + sizeof(p.X)); + OPENSSL_memcpy(p.Y, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1].Y, + sizeof(p.Y)); + OPENSSL_memcpy(p.Z, ONE, sizeof(p.Z)); } else { - OPENSSL_memset(&p.a, 0, sizeof(p.a)); - OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); + OPENSSL_memset(p.X, 0, sizeof(p.X)); + OPENSSL_memset(p.Y, 0, sizeof(p.Y)); + OPENSSL_memset(p.Z, 0, sizeof(p.Z)); } if ((wvalue & 1) == 1) { - ecp_nistz256_neg(p.p.Y, p.p.Y); + ecp_nistz256_neg(p.Y, p.Y); } for (int i = 1; i < 37; i++) { wvalue = calc_wvalue(&index, p_str); - if ((wvalue >> 1) == 0) { continue; } - OPENSSL_memcpy(&t.a, &ecp_nistz256_precomputed[i][(wvalue >> 1) - 1], - sizeof(p.a)); - + alignas(32) P256_POINT_AFFINE t; + OPENSSL_memcpy(&t, &ecp_nistz256_precomputed[i][(wvalue >> 1) - 1], + sizeof(t)); if ((wvalue & 1) == 1) { - ecp_nistz256_neg(t.a.Y, t.a.Y); + ecp_nistz256_neg(t.Y, t.Y); } - // Note |ecp_nistz256_point_add_affine| does not work if |p.p| and |t.a| - // are the same non-infinity point, so it is important that we compute the + // Note |ecp_nistz256_point_add_affine| does not work if |p| and |t| are + // the same non-infinity point, so it is important that we compute the // |g_scalar| term before the |p_scalar| term. - ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + ecp_nistz256_point_add_affine(&p, &p, &t); } - ecp_nistz256_windowed_mul(group, &t.p, p_, p_scalar); - ecp_nistz256_point_add(&p.p, &p.p, &t.p); + alignas(32) P256_POINT tmp; + ecp_nistz256_windowed_mul(group, &tmp, p_, p_scalar); + ecp_nistz256_point_add(&p, &p, &tmp); assert(group->field.width == P256_LIMBS); - OPENSSL_memcpy(r->X.words, p.p.X, P256_LIMBS * sizeof(BN_ULONG)); - OPENSSL_memcpy(r->Y.words, p.p.Y, P256_LIMBS * sizeof(BN_ULONG)); - OPENSSL_memcpy(r->Z.words, p.p.Z, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG)); + OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG)); } static int ecp_nistz256_get_affine(const EC_GROUP *group, - const EC_RAW_POINT *point, EC_FELEM *x, + const EC_JACOBIAN *point, EC_FELEM *x, EC_FELEM *y) { - if (ec_GFp_simple_is_at_infinity(group, point)) { + if (constant_time_declassify_int( + ec_GFp_simple_is_at_infinity(group, point))) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; } @@ -444,8 +445,8 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, return 1; } -static void ecp_nistz256_add(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a_, const EC_RAW_POINT *b_) { +static void ecp_nistz256_add(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a_, const EC_JACOBIAN *b_) { P256_POINT a, b; OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG)); OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG)); @@ -459,8 +460,8 @@ static void ecp_nistz256_add(const EC_GROUP *group, EC_RAW_POINT *r, OPENSSL_memcpy(r->Z.words, a.Z, P256_LIMBS * sizeof(BN_ULONG)); } -static void ecp_nistz256_dbl(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a_) { +static void ecp_nistz256_dbl(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a_) { P256_POINT a; OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG)); OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG)); @@ -555,10 +556,12 @@ static void ecp_nistz256_inv0_mod_ord(const EC_GROUP *group, EC_SCALAR *out, static int ecp_nistz256_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *out, const EC_SCALAR *in) { - if ((OPENSSL_ia32cap_get()[1] & (1 << 28)) == 0) { +#if defined(OPENSSL_X86_64) + if (!CRYPTO_is_AVX_capable()) { // No AVX support; fallback to generic code. return ec_simple_scalar_to_montgomery_inv_vartime(group, out, in); } +#endif assert(group->order.width == P256_LIMBS); if (!beeu_mod_inverse_vartime(out->words, in->words, group->order.d)) { @@ -571,7 +574,7 @@ static int ecp_nistz256_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, } static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *r) { if (ec_GFp_simple_is_at_infinity(group, p)) { return 0; @@ -623,11 +626,16 @@ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) { out->felem_sqr = ec_GFp_mont_felem_sqr; out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->felem_reduce = ec_GFp_mont_felem_reduce; + // TODO(davidben): This should use the specialized field arithmetic + // implementation, rather than the generic one. + out->felem_exp = ec_GFp_mont_felem_exp; out->scalar_inv0_montgomery = ecp_nistz256_inv0_mod_ord; out->scalar_to_montgomery_inv_vartime = ecp_nistz256_scalar_to_montgomery_inv_vartime; out->cmp_x_coordinate = ecp_nistz256_cmp_x_coordinate; } -#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ +#endif /* !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_SMALL) */ diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.h b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.h similarity index 88% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.h rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.h index 5deb81a3..3f5ea021 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz.h @@ -30,7 +30,8 @@ extern "C" { #endif -#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_SMALL) // P-256 field operations. @@ -63,16 +64,6 @@ static inline void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], ecp_nistz256_mul_mont(res, in, ONE); } -// ecp_nistz256_to_mont sets |res| to |in|, converted to Montgomery domain -// by multiplying with RR = 2^512 mod P precomputed for NIST P256 curve. -static inline void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS], - const BN_ULONG in[P256_LIMBS]) { - static const BN_ULONG RR[P256_LIMBS] = { - TOBN(0x00000000, 0x00000003), TOBN(0xfffffffb, 0xffffffff), - TOBN(0xffffffff, 0xfffffffe), TOBN(0x00000004, 0xfffffffd)}; - ecp_nistz256_mul_mont(res, in, RR); -} - // P-256 scalar operations. // @@ -142,8 +133,9 @@ void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a, const P256_POINT_AFFINE *b); -#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ - !defined(OPENSSL_SMALL) */ +#endif /* !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_SMALL) */ #if defined(__cplusplus) diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz_test.cc similarity index 95% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64_test.cc rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz_test.cc index f699fc80..a53d94ee 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz_test.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -31,21 +30,24 @@ #include "../../test/abi_test.h" #include "../../test/file_test.h" #include "../../test/test_util.h" -#include "p256-x86_64.h" +#include "p256-nistz.h" // Disable tests if BORINGSSL_SHARED_LIBRARY is defined. These tests need access // to internal functions. -#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_SMALL) && !defined(BORINGSSL_SHARED_LIBRARY) -TEST(P256_X86_64Test, SelectW5) { +TEST(P256_NistzTest, SelectW5) { // Fill a table with some garbage input. alignas(64) P256_POINT table[16]; for (size_t i = 0; i < 16; i++) { - OPENSSL_memset(table[i].X, 3 * i, sizeof(table[i].X)); - OPENSSL_memset(table[i].Y, 3 * i + 1, sizeof(table[i].Y)); - OPENSSL_memset(table[i].Z, 3 * i + 2, sizeof(table[i].Z)); + OPENSSL_memset(table[i].X, static_cast(3 * i), sizeof(table[i].X)); + OPENSSL_memset(table[i].Y, static_cast(3 * i + 1), + sizeof(table[i].Y)); + OPENSSL_memset(table[i].Z, static_cast(3 * i + 2), + sizeof(table[i].Z)); } for (int i = 0; i <= 16; i++) { @@ -69,12 +71,13 @@ TEST(P256_X86_64Test, SelectW5) { CHECK_ABI(ecp_nistz256_select_w5, &val, table, 7); } -TEST(P256_X86_64Test, SelectW7) { +TEST(P256_NistzTest, SelectW7) { // Fill a table with some garbage input. alignas(64) P256_POINT_AFFINE table[64]; for (size_t i = 0; i < 64; i++) { - OPENSSL_memset(table[i].X, 2 * i, sizeof(table[i].X)); - OPENSSL_memset(table[i].Y, 2 * i + 1, sizeof(table[i].Y)); + OPENSSL_memset(table[i].X, static_cast(2 * i), sizeof(table[i].X)); + OPENSSL_memset(table[i].Y, static_cast(2 * i + 1), + sizeof(table[i].Y)); } for (int i = 0; i <= 64; i++) { @@ -98,11 +101,13 @@ TEST(P256_X86_64Test, SelectW7) { CHECK_ABI(ecp_nistz256_select_w7, &val, table, 42); } -TEST(P256_X86_64Test, BEEU) { - if ((OPENSSL_ia32cap_P[1] & (1 << 28)) == 0) { +TEST(P256_NistzTest, BEEU) { +#if defined(OPENSSL_X86_64) + if (!CRYPTO_is_AVX_capable()) { // No AVX support; cannot run the BEEU code. return; } +#endif bssl::UniquePtr group( EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); @@ -147,8 +152,8 @@ TEST(P256_X86_64Test, BEEU) { EXPECT_TRUE(bn_less_than_words(out, order_words, P256_LIMBS)); // Calculate out*in and confirm that it equals one, modulo the order. - OPENSSL_memcpy(in_scalar.bytes, in, sizeof(in)); - OPENSSL_memcpy(out_scalar.bytes, out, sizeof(out)); + OPENSSL_memcpy(in_scalar.words, in, sizeof(in)); + OPENSSL_memcpy(out_scalar.words, out, sizeof(out)); ec_scalar_to_montgomery(group.get(), &in_scalar, &in_scalar); ec_scalar_to_montgomery(group.get(), &out_scalar, &out_scalar); ec_scalar_mul_montgomery(group.get(), &result, &in_scalar, &out_scalar); @@ -484,8 +489,8 @@ static void TestOrdMulMont(FileTest *t) { } } -TEST(P256_X86_64Test, TestVectors) { - return FileTestGTest("crypto/fipsmodule/ec/p256-x86_64_tests.txt", +TEST(P256_NistzTest, TestVectors) { + return FileTestGTest("crypto/fipsmodule/ec/p256-nistz_tests.txt", [](FileTest *t) { if (t->GetParameter() == "Negate") { TestNegate(t); @@ -504,7 +509,7 @@ TEST(P256_X86_64Test, TestVectors) { } // Instrument the functions covered in TestVectors for ABI checking. -TEST(P256_X86_64Test, ABI) { +TEST(P256_NistzTest, ABI) { BN_ULONG a[P256_LIMBS], b[P256_LIMBS], c[P256_LIMBS]; OPENSSL_memset(a, 0x01, sizeof(a)); // These functions are all constant-time, so it is only necessary to diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64_tests.txt b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz_tests.txt similarity index 100% rename from third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-x86_64_tests.txt rename to third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256-nistz_tests.txt diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256.c index 9f5694c2..76e865f3 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -31,11 +30,10 @@ #include "../delocate.h" #include "./internal.h" - -// MSVC does not implement uint128_t, and crashes with intrinsics #if defined(BORINGSSL_HAS_UINT128) -#define BORINGSSL_NISTP256_64BIT 1 #include "../../../third_party/fiat/p256_64.h" +#elif defined(OPENSSL_64_BIT) +#include "../../../third_party/fiat/p256_64_msvc.h" #else #include "../../../third_party/fiat/p256_32.h" #endif @@ -43,7 +41,7 @@ // utility functions, handwritten -#if defined(BORINGSSL_NISTP256_64BIT) +#if defined(OPENSSL_64_BIT) #define FIAT_P256_NLIMBS 4 typedef uint64_t fiat_p256_limb_t; typedef uint64_t fiat_p256_felem[FIAT_P256_NLIMBS]; @@ -79,17 +77,22 @@ static void fiat_p256_cmovznz(fiat_p256_limb_t out[FIAT_P256_NLIMBS], fiat_p256_selectznz(out, !!t, z, nz); } +static void fiat_p256_from_words(fiat_p256_felem out, + const BN_ULONG in[32 / sizeof(BN_ULONG)]) { + // Typically, |BN_ULONG| and |fiat_p256_limb_t| will be the same type, but on + // 64-bit platforms without |uint128_t|, they are different. However, on + // little-endian systems, |uint64_t[4]| and |uint32_t[8]| have the same + // layout. + OPENSSL_memcpy(out, in, 32); +} + static void fiat_p256_from_generic(fiat_p256_felem out, const EC_FELEM *in) { - fiat_p256_from_bytes(out, in->bytes); + fiat_p256_from_words(out, in->words); } static void fiat_p256_to_generic(EC_FELEM *out, const fiat_p256_felem in) { - // This works because 256 is a multiple of 64, so there are no excess bytes to - // zero when rounding up to |BN_ULONG|s. - OPENSSL_STATIC_ASSERT( - 256 / 8 == sizeof(BN_ULONG) * ((256 + BN_BITS2 - 1) / BN_BITS2), - "fiat_p256_to_bytes leaves bytes uninitialized"); - fiat_p256_to_bytes(out->bytes, in); + // See |fiat_p256_from_words|. + OPENSSL_memcpy(out->words, in, 32); } // fiat_p256_inv_square calculates |out| = |in|^{-2} @@ -321,7 +324,7 @@ static void fiat_p256_point_add(fiat_p256_felem x3, fiat_p256_felem y3, fiat_p256_limb_t is_nontrivial_double = constant_time_is_zero_w(xneq | yneq) & ~constant_time_is_zero_w(z1nz) & ~constant_time_is_zero_w(z2nz); - if (is_nontrivial_double) { + if (constant_time_declassify_w(is_nontrivial_double)) { fiat_p256_point_double(x3, y3, z3, x1, y1, z1); return; } @@ -392,12 +395,18 @@ static void fiat_p256_select_point(const fiat_p256_limb_t idx, size_t size, } } -// fiat_p256_get_bit returns the |i|th bit in |in| -static crypto_word_t fiat_p256_get_bit(const uint8_t *in, int i) { +// fiat_p256_get_bit returns the |i|th bit in |in|. +static crypto_word_t fiat_p256_get_bit(const EC_SCALAR *in, int i) { if (i < 0 || i >= 256) { return 0; } - return (in[i >> 3] >> (i & 7)) & 1; +#if defined(OPENSSL_64_BIT) + static_assert(sizeof(BN_ULONG) == 8, "BN_ULONG was not 64-bit"); + return (in->words[i >> 6] >> (i & 63)) & 1; +#else + static_assert(sizeof(BN_ULONG) == 4, "BN_ULONG was not 32-bit"); + return (in->words[i >> 5] >> (i & 31)) & 1; +#endif } // OPENSSL EC_METHOD FUNCTIONS @@ -405,9 +414,10 @@ static crypto_word_t fiat_p256_get_bit(const uint8_t *in, int i) { // Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = // (X/Z^2, Y/Z^3). static int ec_GFp_nistp256_point_get_affine_coordinates( - const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x_out, + const EC_GROUP *group, const EC_JACOBIAN *point, EC_FELEM *x_out, EC_FELEM *y_out) { - if (ec_GFp_simple_is_at_infinity(group, point)) { + if (constant_time_declassify_int( + ec_GFp_simple_is_at_infinity(group, point))) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; } @@ -435,8 +445,8 @@ static int ec_GFp_nistp256_point_get_affine_coordinates( return 1; } -static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a, const EC_RAW_POINT *b) { +static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a, const EC_JACOBIAN *b) { fiat_p256_felem x1, y1, z1, x2, y2, z2; fiat_p256_from_generic(x1, &a->X); fiat_p256_from_generic(y1, &a->Y); @@ -451,8 +461,8 @@ static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_RAW_POINT *r, fiat_p256_to_generic(&r->Z, z1); } -static void ec_GFp_nistp256_dbl(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *a) { +static void ec_GFp_nistp256_dbl(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *a) { fiat_p256_felem x, y, z; fiat_p256_from_generic(x, &a->X); fiat_p256_from_generic(y, &a->Y); @@ -463,8 +473,8 @@ static void ec_GFp_nistp256_dbl(const EC_GROUP *group, EC_RAW_POINT *r, fiat_p256_to_generic(&r->Z, z); } -static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, +static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar) { fiat_p256_felem p_pre_comp[17][3]; OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); @@ -498,12 +508,12 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, // do other additions every 5 doublings if (i % 5 == 0) { - crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 4) << 5; - bits |= fiat_p256_get_bit(scalar->bytes, i + 3) << 4; - bits |= fiat_p256_get_bit(scalar->bytes, i + 2) << 3; - bits |= fiat_p256_get_bit(scalar->bytes, i + 1) << 2; - bits |= fiat_p256_get_bit(scalar->bytes, i) << 1; - bits |= fiat_p256_get_bit(scalar->bytes, i - 1); + crypto_word_t bits = fiat_p256_get_bit(scalar, i + 4) << 5; + bits |= fiat_p256_get_bit(scalar, i + 3) << 4; + bits |= fiat_p256_get_bit(scalar, i + 2) << 3; + bits |= fiat_p256_get_bit(scalar, i + 1) << 2; + bits |= fiat_p256_get_bit(scalar, i) << 1; + bits |= fiat_p256_get_bit(scalar, i - 1); crypto_word_t sign, digit; ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); @@ -531,7 +541,7 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r, } static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *scalar) { // Set nq to the point at infinity. fiat_p256_felem nq[3] = {{0}, {0}, {0}}, tmp[3]; @@ -543,10 +553,10 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, } // First, look 32 bits upwards. - crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 224) << 3; - bits |= fiat_p256_get_bit(scalar->bytes, i + 160) << 2; - bits |= fiat_p256_get_bit(scalar->bytes, i + 96) << 1; - bits |= fiat_p256_get_bit(scalar->bytes, i + 32); + crypto_word_t bits = fiat_p256_get_bit(scalar, i + 224) << 3; + bits |= fiat_p256_get_bit(scalar, i + 160) << 2; + bits |= fiat_p256_get_bit(scalar, i + 96) << 1; + bits |= fiat_p256_get_bit(scalar, i + 32); // Select the point to add, in constant time. fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, fiat_p256_g_pre_comp[1], tmp); @@ -562,10 +572,10 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, } // Second, look at the current position. - bits = fiat_p256_get_bit(scalar->bytes, i + 192) << 3; - bits |= fiat_p256_get_bit(scalar->bytes, i + 128) << 2; - bits |= fiat_p256_get_bit(scalar->bytes, i + 64) << 1; - bits |= fiat_p256_get_bit(scalar->bytes, i); + bits = fiat_p256_get_bit(scalar, i + 192) << 3; + bits |= fiat_p256_get_bit(scalar, i + 128) << 2; + bits |= fiat_p256_get_bit(scalar, i + 64) << 1; + bits |= fiat_p256_get_bit(scalar, i); // Select the point to add, in constant time. fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, fiat_p256_g_pre_comp[0], tmp); @@ -579,9 +589,9 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, } static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, - EC_RAW_POINT *r, + EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *p_scalar) { #define P256_WSIZE_PUBLIC 4 // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|. @@ -615,10 +625,10 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, // constant-time lookup. if (i <= 31) { // First, look 32 bits upwards. - crypto_word_t bits = fiat_p256_get_bit(g_scalar->bytes, i + 224) << 3; - bits |= fiat_p256_get_bit(g_scalar->bytes, i + 160) << 2; - bits |= fiat_p256_get_bit(g_scalar->bytes, i + 96) << 1; - bits |= fiat_p256_get_bit(g_scalar->bytes, i + 32); + crypto_word_t bits = fiat_p256_get_bit(g_scalar, i + 224) << 3; + bits |= fiat_p256_get_bit(g_scalar, i + 160) << 2; + bits |= fiat_p256_get_bit(g_scalar, i + 96) << 1; + bits |= fiat_p256_get_bit(g_scalar, i + 32); if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], @@ -629,10 +639,10 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, } // Second, look at the current position. - bits = fiat_p256_get_bit(g_scalar->bytes, i + 192) << 3; - bits |= fiat_p256_get_bit(g_scalar->bytes, i + 128) << 2; - bits |= fiat_p256_get_bit(g_scalar->bytes, i + 64) << 1; - bits |= fiat_p256_get_bit(g_scalar->bytes, i); + bits = fiat_p256_get_bit(g_scalar, i + 192) << 3; + bits |= fiat_p256_get_bit(g_scalar, i + 128) << 2; + bits |= fiat_p256_get_bit(g_scalar, i + 64) << 1; + bits |= fiat_p256_get_bit(g_scalar, i); if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], @@ -671,7 +681,7 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, } static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group, - const EC_RAW_POINT *p, + const EC_JACOBIAN *p, const EC_SCALAR *r) { if (ec_GFp_simple_is_at_infinity(group, p)) { return 0; @@ -685,7 +695,7 @@ static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group, fiat_p256_mul(Z2_mont, Z2_mont, Z2_mont); fiat_p256_felem r_Z2; - fiat_p256_from_bytes(r_Z2, r->bytes); // r < order < p, so this is valid. + fiat_p256_from_words(r_Z2, r->words); // r < order < p, so this is valid. fiat_p256_mul(r_Z2, r_Z2, Z2_mont); fiat_p256_felem X; @@ -731,10 +741,12 @@ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) { out->felem_sqr = ec_GFp_mont_felem_sqr; out->felem_to_bytes = ec_GFp_mont_felem_to_bytes; out->felem_from_bytes = ec_GFp_mont_felem_from_bytes; + out->felem_reduce = ec_GFp_mont_felem_reduce; + // TODO(davidben): This should use the specialized field arithmetic + // implementation, rather than the generic one. + out->felem_exp = ec_GFp_mont_felem_exp; out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery; out->scalar_to_montgomery_inv_vartime = ec_simple_scalar_to_montgomery_inv_vartime; out->cmp_x_coordinate = ec_GFp_nistp256_cmp_x_coordinate; } - -#undef BORINGSSL_NISTP256_64BIT diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256_table.h b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256_table.h index 14129a36..d823d37f 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256_table.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/p256_table.h @@ -50,7 +50,7 @@ // Tables for other points have table[i] = iG for i in 0 .. 16. // fiat_p256_g_pre_comp is the table of precomputed base points -#if defined(BORINGSSL_NISTP256_64BIT) +#if defined(OPENSSL_64_BIT) static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = { {{{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6}, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/scalar.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/scalar.c index e4ae9d7f..036049e0 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/scalar.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/scalar.c @@ -54,9 +54,7 @@ int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, const EC_SCALAR *in) { size_t len = BN_num_bytes(&group->order); - for (size_t i = 0; i < len; i++) { - out[len - i - 1] = in->bytes[i]; - } + bn_words_to_big_endian(out, len, in->words, group->order.width); *out_len = len; } @@ -67,11 +65,7 @@ int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out, return 0; } - OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); - - for (size_t i = 0; i < len; i++) { - out->bytes[i] = in[len - i - 1]; - } + bn_big_endian_to_words(out->words, group->order.width, in, len); if (!bn_less_than_words(out->words, group->order.d, group->order.width)) { OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple.c index b6d93125..6498bdc0 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple.c @@ -152,36 +152,36 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, return 1; } -void ec_GFp_simple_point_init(EC_RAW_POINT *point) { +void ec_GFp_simple_point_init(EC_JACOBIAN *point) { OPENSSL_memset(&point->X, 0, sizeof(EC_FELEM)); OPENSSL_memset(&point->Y, 0, sizeof(EC_FELEM)); OPENSSL_memset(&point->Z, 0, sizeof(EC_FELEM)); } -void ec_GFp_simple_point_copy(EC_RAW_POINT *dest, const EC_RAW_POINT *src) { +void ec_GFp_simple_point_copy(EC_JACOBIAN *dest, const EC_JACOBIAN *src) { OPENSSL_memcpy(&dest->X, &src->X, sizeof(EC_FELEM)); OPENSSL_memcpy(&dest->Y, &src->Y, sizeof(EC_FELEM)); OPENSSL_memcpy(&dest->Z, &src->Z, sizeof(EC_FELEM)); } void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, - EC_RAW_POINT *point) { + EC_JACOBIAN *point) { // Although it is strictly only necessary to zero Z, we zero the entire point // in case |point| was stack-allocated and yet to be initialized. ec_GFp_simple_point_init(point); } -void ec_GFp_simple_invert(const EC_GROUP *group, EC_RAW_POINT *point) { +void ec_GFp_simple_invert(const EC_GROUP *group, EC_JACOBIAN *point) { ec_felem_neg(group, &point->Y, &point->Y); } int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, - const EC_RAW_POINT *point) { + const EC_JACOBIAN *point) { return ec_felem_non_zero_mask(group, &point->Z) == 0; } int ec_GFp_simple_is_on_curve(const EC_GROUP *group, - const EC_RAW_POINT *point) { + const EC_JACOBIAN *point) { // We have a curve defined by a Weierstrass equation // y^2 = x^3 + a*x + b. // The point to consider is given in Jacobian projective coordinates @@ -237,8 +237,8 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, return 1 & ~(not_infinity & not_equal); } -int ec_GFp_simple_points_equal(const EC_GROUP *group, const EC_RAW_POINT *a, - const EC_RAW_POINT *b) { +int ec_GFp_simple_points_equal(const EC_GROUP *group, const EC_JACOBIAN *a, + const EC_JACOBIAN *b) { // This function is implemented in constant-time for two reasons. First, // although EC points are usually public, their Jacobian Z coordinates may be // secret, or at least are not obviously public. Second, more complex @@ -285,7 +285,7 @@ int ec_GFp_simple_points_equal(const EC_GROUP *group, const EC_RAW_POINT *a, } int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a, - const EC_RAW_POINT *b) { + const EC_JACOBIAN *b) { // If |b| is not infinity, we have to decide whether // (X_a, Y_a) = (X_b/Z_b^2, Y_b/Z_b^3), // or equivalently, whether @@ -314,7 +314,7 @@ int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a, return equal & 1; } -int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, +int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p, const EC_SCALAR *r) { if (ec_GFp_simple_is_at_infinity(group, p)) { // |ec_get_x_coordinate_as_scalar| will check this internally, but this way @@ -330,9 +330,7 @@ int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_RAW_POINT *p, void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len, const EC_FELEM *in) { size_t len = BN_num_bytes(&group->field); - for (size_t i = 0; i < len; i++) { - out[i] = in->bytes[len - 1 - i]; - } + bn_words_to_big_endian(out, len, in->words, group->field.width); *out_len = len; } @@ -343,10 +341,7 @@ int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, return 0; } - OPENSSL_memset(out, 0, sizeof(EC_FELEM)); - for (size_t i = 0; i < len; i++) { - out->bytes[i] = in[len - 1 - i]; - } + bn_big_endian_to_words(out->words, group->field.width, in, len); if (!bn_less_than_words(out->words, group->field.d, group->field.width)) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple_mul.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple_mul.c index 0e6384ec..9a72a664 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple_mul.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/simple_mul.c @@ -21,14 +21,14 @@ #include "../../internal.h" -void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p, const EC_SCALAR *scalar) { +void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p, const EC_SCALAR *scalar) { // This is a generic implementation for uncommon curves that not do not // warrant a tuned one. It uses unsigned digits so that the doubling case in // |ec_GFp_mont_add| is always unreachable, erring on safety and simplicity. // Compute a table of the first 32 multiples of |p| (including infinity). - EC_RAW_POINT precomp[32]; + EC_JACOBIAN precomp[32]; ec_GFp_simple_point_set_to_infinity(group, &precomp[0]); ec_GFp_simple_point_copy(&precomp[1], p); for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) { @@ -56,8 +56,8 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, window |= bn_is_bit_set_words(scalar->words, width, i); // Select the entry in constant-time. - EC_RAW_POINT tmp; - OPENSSL_memset(&tmp, 0, sizeof(EC_RAW_POINT)); + EC_JACOBIAN tmp; + OPENSSL_memset(&tmp, 0, sizeof(EC_JACOBIAN)); for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) { BN_ULONG mask = constant_time_eq_w(j, window); ec_point_select(group, &tmp, mask, &precomp[j], &tmp); @@ -76,13 +76,13 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_RAW_POINT *r, } } -void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_RAW_POINT *r, +void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar) { ec_GFp_mont_mul(group, r, &group->generator->raw, scalar); } -static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_RAW_POINT *out, - size_t num, const EC_RAW_POINT *p) { +static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_JACOBIAN *out, + size_t num, const EC_JACOBIAN *p) { assert(num > 1); ec_GFp_simple_point_set_to_infinity(group, &out[0]); ec_GFp_simple_point_copy(&out[1], p); @@ -96,8 +96,8 @@ static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_RAW_POINT *out, } static void ec_GFp_mont_batch_get_window(const EC_GROUP *group, - EC_RAW_POINT *out, - const EC_RAW_POINT precomp[17], + EC_JACOBIAN *out, + const EC_JACOBIAN precomp[17], const EC_SCALAR *scalar, unsigned i) { const size_t width = group->order.width; uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 5; @@ -112,7 +112,7 @@ static void ec_GFp_mont_batch_get_window(const EC_GROUP *group, ec_GFp_nistp_recode_scalar_bits(&sign, &digit, window); // Select the entry in constant-time. - OPENSSL_memset(out, 0, sizeof(EC_RAW_POINT)); + OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN)); for (size_t j = 0; j < 17; j++) { BN_ULONG mask = constant_time_eq_w(j, digit); ec_point_select(group, out, mask, &precomp[j], out); @@ -126,11 +126,11 @@ static void ec_GFp_mont_batch_get_window(const EC_GROUP *group, ec_felem_select(group, &out->Y, sign_mask, &neg_Y, &out->Y); } -void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_RAW_POINT *r, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, const EC_SCALAR *scalar2) { - EC_RAW_POINT precomp[3][17]; +void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_JACOBIAN *r, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2) { + EC_JACOBIAN precomp[3][17]; ec_GFp_mont_batch_precomp(group, precomp[0], 17, p0); ec_GFp_mont_batch_precomp(group, precomp[1], 17, p1); if (p2 != NULL) { @@ -145,7 +145,7 @@ void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_RAW_POINT *r, ec_GFp_mont_dbl(group, r, r); } if (i % 5 == 0) { - EC_RAW_POINT tmp; + EC_JACOBIAN tmp; ec_GFp_mont_batch_get_window(group, &tmp, precomp[0], scalar0, i); if (r_is_at_infinity) { ec_GFp_simple_point_copy(r, &tmp); @@ -174,13 +174,13 @@ static unsigned ec_GFp_mont_comb_stride(const EC_GROUP *group) { } int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, - const EC_RAW_POINT *p) { + const EC_JACOBIAN *p) { // comb[i - 1] stores the ith element of the comb. That is, if i is // b4 * 2^4 + b3 * 2^3 + ... + b0 * 2^0, it stores k * |p|, where k is // b4 * 2^(4*stride) + b3 * 2^(3*stride) + ... + b0 * 2^(0*stride). stride // here is |ec_GFp_mont_comb_stride|. We store at index i - 1 because the 0th // comb entry is always infinity. - EC_RAW_POINT comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1]; + EC_JACOBIAN comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1]; unsigned stride = ec_GFp_mont_comb_stride(group); // We compute the comb sequentially by the highest set bit. Initially, all @@ -202,15 +202,14 @@ int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, // Store the comb in affine coordinates to shrink the table. (This reduces // cache pressure and makes the constant-time selects faster.) - OPENSSL_STATIC_ASSERT( - OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb), - "comb sizes did not match"); + static_assert(OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb), + "comb sizes did not match"); return ec_jacobian_to_affine_batch(group, out->comb, comb, OPENSSL_ARRAY_SIZE(comb)); } static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, - EC_RAW_POINT *out, + EC_JACOBIAN *out, const EC_PRECOMP *precomp, const EC_SCALAR *scalar, unsigned i) { const size_t width = group->order.width; @@ -224,7 +223,7 @@ static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, // Select precomp->comb[window - 1]. If |window| is zero, |match| will always // be zero, which will leave |out| at infinity. - OPENSSL_memset(out, 0, sizeof(EC_RAW_POINT)); + OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN)); for (unsigned j = 0; j < OPENSSL_ARRAY_SIZE(precomp->comb); j++) { BN_ULONG match = constant_time_eq_w(window, j + 1); ec_felem_select(group, &out->X, match, &precomp->comb[j].X, &out->X); @@ -234,7 +233,7 @@ static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, ec_felem_select(group, &out->Z, is_infinity, &out->Z, &group->one); } -void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, +void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_JACOBIAN *r, const EC_PRECOMP *p0, const EC_SCALAR *scalar0, const EC_PRECOMP *p1, const EC_SCALAR *scalar1, const EC_PRECOMP *p2, const EC_SCALAR *scalar2) { @@ -245,7 +244,7 @@ void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_RAW_POINT *r, ec_GFp_mont_dbl(group, r, r); } - EC_RAW_POINT tmp; + EC_JACOBIAN tmp; ec_GFp_mont_get_comb_window(group, &tmp, p0, scalar0, i); if (r_is_at_infinity) { ec_GFp_simple_point_copy(r, &tmp); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/wnaf.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/wnaf.c index 65cc8945..beb92954 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ec/wnaf.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ec/wnaf.c @@ -148,18 +148,18 @@ void ec_compute_wNAF(const EC_GROUP *group, int8_t *out, } // compute_precomp sets |out[i]| to (2*i+1)*p, for i from 0 to |len|. -static void compute_precomp(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_RAW_POINT *p, size_t len) { +static void compute_precomp(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_JACOBIAN *p, size_t len) { ec_GFp_simple_point_copy(&out[0], p); - EC_RAW_POINT two_p; + EC_JACOBIAN two_p; ec_GFp_mont_dbl(group, &two_p, p); for (size_t i = 1; i < len; i++) { ec_GFp_mont_add(group, &out[i], &out[i - 1], &two_p); } } -static void lookup_precomp(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_RAW_POINT *precomp, int digit) { +static void lookup_precomp(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_JACOBIAN *precomp, int digit) { if (digit < 0) { digit = -digit; ec_GFp_simple_point_copy(out, &precomp[digit >> 1]); @@ -179,9 +179,9 @@ static void lookup_precomp(const EC_GROUP *group, EC_RAW_POINT *out, // avoid a malloc. #define EC_WNAF_STACK 3 -int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, +int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *g_scalar, - const EC_RAW_POINT *points, + const EC_JACOBIAN *points, const EC_SCALAR *scalars, size_t num) { size_t bits = BN_num_bits(&group->order); size_t wNAF_len = bits + 1; @@ -190,9 +190,9 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, int8_t wNAF_stack[EC_WNAF_STACK][EC_MAX_BYTES * 8 + 1]; int8_t (*wNAF_alloc)[EC_MAX_BYTES * 8 + 1] = NULL; int8_t (*wNAF)[EC_MAX_BYTES * 8 + 1]; - EC_RAW_POINT precomp_stack[EC_WNAF_STACK][EC_WNAF_TABLE_SIZE]; - EC_RAW_POINT (*precomp_alloc)[EC_WNAF_TABLE_SIZE] = NULL; - EC_RAW_POINT (*precomp)[EC_WNAF_TABLE_SIZE]; + EC_JACOBIAN precomp_stack[EC_WNAF_STACK][EC_WNAF_TABLE_SIZE]; + EC_JACOBIAN (*precomp_alloc)[EC_WNAF_TABLE_SIZE] = NULL; + EC_JACOBIAN (*precomp)[EC_WNAF_TABLE_SIZE]; if (num <= EC_WNAF_STACK) { wNAF = wNAF_stack; precomp = precomp_stack; @@ -205,7 +205,6 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, wNAF_alloc = OPENSSL_malloc(num * sizeof(wNAF_alloc[0])); precomp_alloc = OPENSSL_malloc(num * sizeof(precomp_alloc[0])); if (wNAF_alloc == NULL || precomp_alloc == NULL) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); goto err; } wNAF = wNAF_alloc; @@ -213,9 +212,9 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, } int8_t g_wNAF[EC_MAX_BYTES * 8 + 1]; - EC_RAW_POINT g_precomp[EC_WNAF_TABLE_SIZE]; + EC_JACOBIAN g_precomp[EC_WNAF_TABLE_SIZE]; assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF)); - const EC_RAW_POINT *g = &group->generator->raw; + const EC_JACOBIAN *g = &group->generator->raw; if (g_scalar != NULL) { ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS); compute_precomp(group, g_precomp, g, EC_WNAF_TABLE_SIZE); @@ -227,7 +226,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_RAW_POINT *r, compute_precomp(group, precomp[i], &points[i], EC_WNAF_TABLE_SIZE); } - EC_RAW_POINT tmp; + EC_JACOBIAN tmp; int r_is_at_infinity = 1; for (size_t k = wNAF_len - 1; k < wNAF_len; k--) { if (!r_is_at_infinity) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdh/ecdh.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdh/ecdh.c index 4e6d0bf8..eeb591f8 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdh/ecdh.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdh/ecdh.c @@ -74,11 +74,15 @@ #include #include +#include "../../internal.h" #include "../ec/internal.h" +#include "../service_indicator/internal.h" int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, const EC_KEY *priv_key) { + boringssl_ensure_ecc_self_test(); + if (priv_key->priv_key == NULL) { OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); return 0; @@ -90,7 +94,7 @@ int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, return 0; } - EC_RAW_POINT shared_point; + EC_JACOBIAN shared_point; uint8_t buf[EC_MAX_BYTES]; size_t buflen; if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) || @@ -100,6 +104,7 @@ int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, return 0; } + FIPS_service_indicator_lock_state(); switch (out_len) { case SHA224_DIGEST_LENGTH: SHA224(buf, buflen, out); @@ -115,8 +120,11 @@ int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, break; default: OPENSSL_PUT_ERROR(ECDH, ECDH_R_UNKNOWN_DIGEST_LENGTH); + FIPS_service_indicator_unlock_state(); return 0; } + FIPS_service_indicator_unlock_state(); + ECDH_verify_service_indicator(priv_key); return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/ecdsa.c b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/ecdsa.c index 5d99903a..1be147f9 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/ecdsa.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/ecdsa.c @@ -59,11 +59,11 @@ #include #include #include -#include #include "../../internal.h" #include "../bn/internal.h" #include "../ec/internal.h" +#include "../service_indicator/internal.h" #include "internal.h" @@ -78,10 +78,7 @@ static void digest_to_scalar(const EC_GROUP *group, EC_SCALAR *out, if (digest_len > num_bytes) { digest_len = num_bytes; } - OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); - for (size_t i = 0; i < digest_len; i++) { - out->bytes[i] = digest[digest_len - 1 - i]; - } + bn_big_endian_to_words(out->words, order->width, digest, digest_len); // If it is still too long, truncate remaining bits with a shift. if (8 * digest_len > num_bits) { @@ -151,8 +148,8 @@ int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { return 1; } -int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, - const ECDSA_SIG *sig, const EC_KEY *eckey) { +int ecdsa_do_verify_no_self_test(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { const EC_GROUP *group = EC_KEY_get0_group(eckey); const EC_POINT *pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || pub_key == NULL || sig == NULL) { @@ -184,7 +181,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, ec_scalar_mul_montgomery(group, &u1, &m, &s_inv_mont); ec_scalar_mul_montgomery(group, &u2, &r, &s_inv_mont); - EC_RAW_POINT point; + EC_JACOBIAN point; if (!ec_point_mul_scalar_public(group, &point, &u1, &pub_key->raw, &u2)) { OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); return 0; @@ -198,6 +195,13 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, return 1; } +int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + + return ecdsa_do_verify_no_self_test(digest, digest_len, sig, eckey); +} + static ECDSA_SIG *ecdsa_sign_impl(const EC_GROUP *group, int *out_retry, const EC_SCALAR *priv_key, const EC_SCALAR *k, const uint8_t *digest, size_t digest_len) { @@ -212,14 +216,14 @@ static ECDSA_SIG *ecdsa_sign_impl(const EC_GROUP *group, int *out_retry, } // Compute r, the x-coordinate of k * generator. - EC_RAW_POINT tmp_point; + EC_JACOBIAN tmp_point; EC_SCALAR r; if (!ec_point_mul_scalar_base(group, &tmp_point, k) || !ec_get_x_coordinate_as_scalar(group, &r, &tmp_point)) { return NULL; } - if (ec_scalar_is_zero(group, &r)) { + if (constant_time_declassify_int(ec_scalar_is_zero(group, &r))) { *out_retry = 1; return NULL; } @@ -246,11 +250,13 @@ static ECDSA_SIG *ecdsa_sign_impl(const EC_GROUP *group, int *out_retry, ec_scalar_inv0_montgomery(group, &tmp, k); // tmp = k^-1 R^2 ec_scalar_from_montgomery(group, &tmp, &tmp); // tmp = k^-1 R ec_scalar_mul_montgomery(group, &s, &s, &tmp); - if (ec_scalar_is_zero(group, &s)) { + if (constant_time_declassify_int(ec_scalar_is_zero(group, &s))) { *out_retry = 1; return NULL; } + CONSTTIME_DECLASSIFY(r.words, sizeof(r.words)); + CONSTTIME_DECLASSIFY(s.words, sizeof(r.words)); ECDSA_SIG *ret = ECDSA_SIG_new(); if (ret == NULL || // !bn_set_words(ret->r, r.words, order->width) || @@ -292,12 +298,16 @@ ECDSA_SIG *ecdsa_sign_with_nonce_for_known_answer_test(const uint8_t *digest, ECDSA_SIG *ECDSA_sign_with_nonce_and_leak_private_key_for_testing( const uint8_t *digest, size_t digest_len, const EC_KEY *eckey, const uint8_t *nonce, size_t nonce_len) { + boringssl_ensure_ecc_self_test(); + return ecdsa_sign_with_nonce_for_known_answer_test(digest, digest_len, eckey, nonce, nonce_len); } ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, const EC_KEY *eckey) { + boringssl_ensure_ecc_self_test(); + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); return NULL; @@ -313,8 +323,11 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, // Pass a SHA512 hash of the private key and digest as additional data // into the RBG. This is a hardening measure against entropy failure. - OPENSSL_STATIC_ASSERT(SHA512_DIGEST_LENGTH >= 32, - "additional_data is too large for SHA-512"); + static_assert(SHA512_DIGEST_LENGTH >= 32, + "additional_data is too large for SHA-512"); + + FIPS_service_indicator_lock_state(); + SHA512_CTX sha; uint8_t additional_data[SHA512_DIGEST_LENGTH]; SHA512_Init(&sha); @@ -322,17 +335,38 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, SHA512_Update(&sha, digest, digest_len); SHA512_Final(additional_data, &sha); + // Cap iterations so callers who supply invalid values as custom groups do not + // infinite loop. This does not impact valid parameters (e.g. those covered by + // FIPS) because the probability of requiring even one retry is negligible, + // let alone 32. + static const int kMaxIterations = 32; + ECDSA_SIG *ret = NULL; + int iters = 0; for (;;) { EC_SCALAR k; if (!ec_random_nonzero_scalar(group, &k, additional_data)) { - return NULL; + ret = NULL; + goto out; } + // TODO(davidben): Move this inside |ec_random_nonzero_scalar| or lower, so + // that all scalars we generate are, by default, secret. + CONSTTIME_SECRET(k.words, sizeof(k.words)); + int retry; - ECDSA_SIG *sig = - ecdsa_sign_impl(group, &retry, priv_key, &k, digest, digest_len); - if (sig != NULL || !retry) { - return sig; + ret = ecdsa_sign_impl(group, &retry, priv_key, &k, digest, digest_len); + if (ret != NULL || !retry) { + goto out; + } + + iters++; + if (iters > kMaxIterations) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_TOO_MANY_ITERATIONS); + goto out; } } + +out: + FIPS_service_indicator_unlock_state(); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/internal.h index 5115dfa4..645959fb 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/ecdsa/internal.h @@ -31,6 +31,12 @@ ECDSA_SIG *ecdsa_sign_with_nonce_for_known_answer_test(const uint8_t *digest, const uint8_t *nonce, size_t nonce_len); +// ecdsa_do_verify_no_self_test does the same as |ECDSA_do_verify|, but doesn't +// try to run the self-test first. This is for use in the self tests themselves, +// to prevent an infinite loop. +int ecdsa_do_verify_no_self_test(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey); + #if defined(__cplusplus) } diff --git a/third_party/boringssl/kit/src/crypto/hkdf/hkdf.c b/third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf.c similarity index 98% rename from third_party/boringssl/kit/src/crypto/hkdf/hkdf.c rename to third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf.c index 23b60afe..c2ebce82 100644 --- a/third_party/boringssl/kit/src/crypto/hkdf/hkdf.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf.c @@ -20,7 +20,7 @@ #include #include -#include "../internal.h" +#include "../../internal.h" int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, @@ -94,7 +94,7 @@ int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, } todo = digest_len; - if (done + todo > out_len) { + if (todo > out_len - done) { todo = out_len - done; } OPENSSL_memcpy(out_key + done, previous, todo); diff --git a/third_party/boringssl/kit/src/crypto/hkdf/hkdf_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf_test.cc similarity index 73% rename from third_party/boringssl/kit/src/crypto/hkdf/hkdf_test.cc rename to third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf_test.cc index 793506ff..dd7dd583 100644 --- a/third_party/boringssl/kit/src/crypto/hkdf/hkdf_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/hkdf/hkdf_test.cc @@ -14,13 +14,15 @@ #include #include +#include #include +#include #include -#include "../test/file_test.h" -#include "../test/test_util.h" -#include "../test/wycheproof_util.h" +#include "../../test/file_test.h" +#include "../../test/test_util.h" +#include "../../test/wycheproof_util.h" struct HKDFTestVector { @@ -266,6 +268,108 @@ TEST(HKDFTest, TestVectors) { test->ikm_len, test->salt, test->salt_len, test->info, test->info_len)); EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, test->out_len)); + + // Repeat the test with the OpenSSL compatibility |EVP_PKEY_derive| API. + bssl::UniquePtr ctx( + EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr)); + ASSERT_TRUE(ctx); + ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get())); + ASSERT_TRUE( + EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY)); + ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func())); + ASSERT_TRUE( + EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->ikm, test->ikm_len)); + ASSERT_TRUE( + EVP_PKEY_CTX_set1_hkdf_salt(ctx.get(), test->salt, test->salt_len)); + for (bool copy_ctx : {false, true}) { + SCOPED_TRACE(copy_ctx); + bssl::UniquePtr copy; + EVP_PKEY_CTX *use_ctx = ctx.get(); + if (copy_ctx) { + copy.reset(EVP_PKEY_CTX_dup(ctx.get())); + ASSERT_TRUE(copy); + use_ctx = copy.get(); + } + + // A null output should report the length. + prk_len = 0; + ASSERT_TRUE(EVP_PKEY_derive(use_ctx, nullptr, &prk_len)); + EXPECT_EQ(prk_len, test->prk_len); + + // Too small of a buffer should cleanly fail. + prk_len = test->prk_len - 1; + EXPECT_FALSE(EVP_PKEY_derive(use_ctx, prk, &prk_len)); + ERR_clear_error(); + + // Test the correct buffer size. + OPENSSL_memset(prk, 0, sizeof(prk)); + prk_len = test->prk_len; + ASSERT_TRUE(EVP_PKEY_derive(use_ctx, prk, &prk_len)); + EXPECT_EQ(Bytes(test->prk, test->prk_len), Bytes(prk, prk_len)); + + // Test a larger buffer than necessary. + OPENSSL_memset(prk, 0, sizeof(prk)); + prk_len = test->prk_len + 1; + ASSERT_TRUE(EVP_PKEY_derive(use_ctx, prk, &prk_len)); + EXPECT_EQ(Bytes(test->prk, test->prk_len), Bytes(prk, prk_len)); + } + + ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr)); + ASSERT_TRUE(ctx); + ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get())); + ASSERT_TRUE( + EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY)); + ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func())); + ASSERT_TRUE( + EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->prk, test->prk_len)); + // |info| can be passed in multiple parts. + size_t half = test->info_len / 2; + ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info, half)); + ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info + half, + test->info_len - half)); + for (bool copy_ctx : {false, true}) { + SCOPED_TRACE(copy_ctx); + bssl::UniquePtr copy; + EVP_PKEY_CTX *use_ctx = ctx.get(); + if (copy_ctx) { + copy.reset(EVP_PKEY_CTX_dup(ctx.get())); + ASSERT_TRUE(copy); + use_ctx = copy.get(); + } + OPENSSL_memset(buf, 0, sizeof(buf)); + size_t len = test->out_len; + ASSERT_TRUE(EVP_PKEY_derive(use_ctx, buf, &len)); + EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, len)); + } + + ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr)); + ASSERT_TRUE(ctx); + ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_hkdf_mode(ctx.get(), + EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND)); + ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func())); + ASSERT_TRUE( + EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->ikm, test->ikm_len)); + ASSERT_TRUE( + EVP_PKEY_CTX_set1_hkdf_salt(ctx.get(), test->salt, test->salt_len)); + // |info| can be passed in multiple parts. + ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info, half)); + ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info + half, + test->info_len - half)); + for (bool copy_ctx : {false, true}) { + SCOPED_TRACE(copy_ctx); + bssl::UniquePtr copy; + EVP_PKEY_CTX *use_ctx = ctx.get(); + if (copy_ctx) { + copy.reset(EVP_PKEY_CTX_dup(ctx.get())); + ASSERT_TRUE(copy); + use_ctx = copy.get(); + } + OPENSSL_memset(buf, 0, sizeof(buf)); + size_t len = test->out_len; + ASSERT_TRUE(EVP_PKEY_derive(use_ctx, buf, &len)); + EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, len)); + } } } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/hmac/hmac.c b/third_party/boringssl/kit/src/crypto/fipsmodule/hmac/hmac.c index fb57bf24..c6f12e2a 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/hmac/hmac.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/hmac/hmac.c @@ -63,6 +63,7 @@ #include #include "../../internal.h" +#include "../service_indicator/internal.h" uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, @@ -70,13 +71,22 @@ uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, unsigned int *out_len) { HMAC_CTX ctx; HMAC_CTX_init(&ctx); - if (!HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) || - !HMAC_Update(&ctx, data, data_len) || - !HMAC_Final(&ctx, out, out_len)) { - out = NULL; - } + + // The underlying hash functions should not set the FIPS service indicator + // until all operations have completed. + FIPS_service_indicator_lock_state(); + const int ok = HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) && + HMAC_Update(&ctx, data, data_len) && + HMAC_Final(&ctx, out, out_len); + FIPS_service_indicator_unlock_state(); HMAC_CTX_cleanup(&ctx); + + if (!ok) { + return NULL; + } + + HMAC_verify_service_indicator(evp_md); return out; } @@ -102,6 +112,13 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx) { OPENSSL_cleanse(ctx, sizeof(HMAC_CTX)); } +void HMAC_CTX_cleanse(HMAC_CTX *ctx) { + EVP_MD_CTX_cleanse(&ctx->i_ctx); + EVP_MD_CTX_cleanse(&ctx->o_ctx); + EVP_MD_CTX_cleanse(&ctx->md_ctx); + OPENSSL_cleanse(ctx, sizeof(HMAC_CTX)); +} + void HMAC_CTX_free(HMAC_CTX *ctx) { if (ctx == NULL) { return; @@ -113,6 +130,9 @@ void HMAC_CTX_free(HMAC_CTX *ctx) { int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, const EVP_MD *md, ENGINE *impl) { + int ret = 0; + FIPS_service_indicator_lock_state(); + if (md == NULL) { md = ctx->md; } @@ -131,12 +151,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, size_t block_size = EVP_MD_block_size(md); assert(block_size <= sizeof(key_block)); + assert(EVP_MD_size(md) <= block_size); if (block_size < key_len) { // Long keys are hashed. if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) || !EVP_DigestFinal_ex(&ctx->md_ctx, key_block, &key_block_len)) { - return 0; + goto out; } } else { assert(key_len <= sizeof(key_block)); @@ -144,34 +165,32 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, key_block_len = (unsigned)key_len; } // Keys are then padded with zeros. - if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) { - OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); - } + OPENSSL_memset(key_block + key_block_len, 0, block_size - key_block_len); - for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + for (size_t i = 0; i < block_size; i++) { pad[i] = 0x36 ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || - !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { - return 0; + !EVP_DigestUpdate(&ctx->i_ctx, pad, block_size)) { + goto out; } - for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + for (size_t i = 0; i < block_size; i++) { pad[i] = 0x5c ^ key_block[i]; } if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || - !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { - return 0; + !EVP_DigestUpdate(&ctx->o_ctx, pad, block_size)) { + goto out; } ctx->md = md; } - if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) { - return 0; - } + ret = EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx); - return 1; +out: + FIPS_service_indicator_unlock_state(); + return ret; } int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) { @@ -179,9 +198,11 @@ int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) { } int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) { + int ret = 0; unsigned int i; uint8_t buf[EVP_MAX_MD_SIZE]; + FIPS_service_indicator_lock_state(); // TODO(davidben): The only thing that can officially fail here is // |EVP_MD_CTX_copy_ex|, but even that should be impossible in this case. if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) || @@ -189,15 +210,22 @@ int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) { !EVP_DigestUpdate(&ctx->md_ctx, buf, i) || !EVP_DigestFinal_ex(&ctx->md_ctx, out, out_len)) { *out_len = 0; - return 0; + goto out; } - return 1; + ret = 1; + + out: + FIPS_service_indicator_unlock_state(); + if (ret) { + HMAC_verify_service_indicator(ctx->md); + } + return ret; } -size_t HMAC_size(const HMAC_CTX *ctx) { - return EVP_MD_size(ctx->md); -} +size_t HMAC_size(const HMAC_CTX *ctx) { return EVP_MD_size(ctx->md); } + +const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx) { return ctx->md; } int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src) { if (!EVP_MD_CTX_copy_ex(&dest->i_ctx, &src->i_ctx) || diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl index 793f34c5..7c235f82 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl @@ -71,14 +71,27 @@ open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; # no AVX2 instructions being used. if ($avx>1) {{{ -($inp,$out,$len,$key,$ivp,$Xip)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); +# On Windows, only four parameters are passed in registers. The last two +# parameters will be manually loaded into %rdi and %rsi. +my ($inp, $out, $len, $key, $ivp, $Htable) = + $win64 ? ("%rcx", "%rdx", "%r8", "%r9", "%rdi", "%rsi") : + ("%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"); + +# The offset from %rbp to the Xip parameter. On Windows, all parameters have +# corresponding stack positions, not just ones passed on the stack. +# (0x40 = 6*8 + 0x10) +# +# Xip only needs to be accessed at the beginning and end of the function, and +# this function is short on registers, so we make it the last parameter for +# convenience. +my $Xip_offset = $win64 ? 0x40 : 0x10; ($Ii,$T1,$T2,$Hkey, $Z0,$Z1,$Z2,$Z3,$Xi) = map("%xmm$_",(0..8)); ($inout0,$inout1,$inout2,$inout3,$inout4,$inout5,$rndkey) = map("%xmm$_",(9..15)); -($counter,$rounds,$ret,$const,$in0,$end0)=("%ebx","%ebp","%r10","%r11","%r14","%r15"); +($counter,$rounds,$const,$in0,$end0)=("%ebx","%r10d","%r11","%r14","%r15"); $code=<<___; .text @@ -104,7 +117,7 @@ _aesni_ctr32_ghash_6x: .Loop6x: add \$`6<<24`,$counter jc .Lhandle_ctr32 # discard $inout[1-5]? - vmovdqu 0x00-0x20($Xip),$Hkey # $Hkey^1 + vmovdqu 0x00-0x20($Htable),$Hkey # $Hkey^1 vpaddb $T2,$inout5,$T1 # next counter value vpxor $rndkey,$inout1,$inout1 vpxor $rndkey,$inout2,$inout2 @@ -144,7 +157,7 @@ _aesni_ctr32_ghash_6x: setnc %r12b vpclmulqdq \$0x11,$Hkey,$Z3,$Z3 vaesenc $T2,$inout2,$inout2 - vmovdqu 0x10-0x20($Xip),$Hkey # $Hkey^2 + vmovdqu 0x10-0x20($Htable),$Hkey # $Hkey^2 neg %r12 vaesenc $T2,$inout3,$inout3 vpxor $Z1,$Z2,$Z2 @@ -171,7 +184,7 @@ _aesni_ctr32_ghash_6x: mov %r13,0x20+8(%rsp) vaesenc $rndkey,$inout4,$inout4 mov %r12,0x28+8(%rsp) - vmovdqu 0x30-0x20($Xip),$Z1 # borrow $Z1 for $Hkey^3 + vmovdqu 0x30-0x20($Htable),$Z1 # borrow $Z1 for $Hkey^3 vaesenc $rndkey,$inout5,$inout5 vmovups 0x30-0x80($key),$rndkey @@ -189,7 +202,7 @@ _aesni_ctr32_ghash_6x: vaesenc $rndkey,$inout3,$inout3 vaesenc $rndkey,$inout4,$inout4 vpxor $T1,$Z0,$Z0 - vmovdqu 0x40-0x20($Xip),$T1 # borrow $T1 for $Hkey^4 + vmovdqu 0x40-0x20($Htable),$T1 # borrow $T1 for $Hkey^4 vaesenc $rndkey,$inout5,$inout5 vmovups 0x40-0x80($key),$rndkey @@ -211,7 +224,7 @@ _aesni_ctr32_ghash_6x: vaesenc $rndkey,$inout4,$inout4 mov %r12,0x38+8(%rsp) vpxor $T2,$Z0,$Z0 - vmovdqu 0x60-0x20($Xip),$T2 # borrow $T2 for $Hkey^5 + vmovdqu 0x60-0x20($Htable),$T2 # borrow $T2 for $Hkey^5 vaesenc $rndkey,$inout5,$inout5 vmovups 0x50-0x80($key),$rndkey @@ -233,7 +246,7 @@ _aesni_ctr32_ghash_6x: vaesenc $rndkey,$inout4,$inout4 mov %r12,0x48+8(%rsp) vpxor $Hkey,$Z0,$Z0 - vmovdqu 0x70-0x20($Xip),$Hkey # $Hkey^6 + vmovdqu 0x70-0x20($Htable),$Hkey # $Hkey^6 vaesenc $rndkey,$inout5,$inout5 vmovups 0x60-0x80($key),$rndkey @@ -335,7 +348,7 @@ _aesni_ctr32_ghash_6x: vmovdqu 0x30($const),$Z1 # borrow $Z1, .Ltwo_lsb vpaddd 0x40($const),$Z2,$inout1 # .Lone_lsb vpaddd $Z1,$Z2,$inout2 - vmovdqu 0x00-0x20($Xip),$Hkey # $Hkey^1 + vmovdqu 0x00-0x20($Htable),$Hkey # $Hkey^1 vpaddd $Z1,$inout1,$inout3 vpshufb $Ii,$inout1,$inout1 vpaddd $Z1,$inout2,$inout4 @@ -375,6 +388,9 @@ _aesni_ctr32_ghash_6x: vpaddb $T2,$T1,$Ii mov %r13,0x70+8(%rsp) lea 0x60($inp),$inp + # These two prefetches were added in BoringSSL. See change that added them. + prefetcht0 512($inp) # We use 96-byte block so prefetch 2 lines (128 bytes) + prefetcht0 576($inp) vaesenclast $Z1,$inout2,$inout2 vpaddb $T2,$Ii,$Z1 mov %r12,0x78+8(%rsp) @@ -387,7 +403,7 @@ _aesni_ctr32_ghash_6x: vaesenclast $Hkey,$inout5,$inout5 vpaddb $T2,$Z3,$Hkey - add \$0x60,$ret + add \$0x60,%rax sub \$0x6,$len jc .L6x_done @@ -417,64 +433,95 @@ ___ ###################################################################### # # size_t aesni_gcm_[en|de]crypt(const void *inp, void *out, size_t len, -# const AES_KEY *key, unsigned char iv[16], -# struct { u128 Xi,H,Htbl[9]; } *Xip); +# const AES_KEY *key, unsigned char iv[16], const u128 *Htbl[9], +# u128 *Xip); $code.=<<___; .globl aesni_gcm_decrypt -.type aesni_gcm_decrypt,\@function,6 +.type aesni_gcm_decrypt,\@abi-omnipotent .align 32 aesni_gcm_decrypt: .cfi_startproc - xor $ret,$ret +.seh_startproc + xor %rax,%rax # We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60) # bytes of input. cmp \$0x60,$len # minimal accepted length jb .Lgcm_dec_abort - lea (%rsp),%rax # save stack pointer -.cfi_def_cfa_register %rax - push %rbx -.cfi_push %rbx push %rbp .cfi_push %rbp +.seh_pushreg %rbp + mov %rsp, %rbp # save stack pointer +.cfi_def_cfa_register %rbp + push %rbx +.cfi_push %rbx +.seh_pushreg %rbx push %r12 .cfi_push %r12 +.seh_pushreg %r12 push %r13 .cfi_push %r13 +.seh_pushreg %r13 push %r14 .cfi_push %r14 +.seh_pushreg %r14 push %r15 .cfi_push %r15 +.seh_pushreg %r15 ___ -$code.=<<___ if ($win64); - lea -0xa8(%rsp),%rsp - movaps %xmm6,-0xd8(%rax) - movaps %xmm7,-0xc8(%rax) - movaps %xmm8,-0xb8(%rax) - movaps %xmm9,-0xa8(%rax) - movaps %xmm10,-0x98(%rax) - movaps %xmm11,-0x88(%rax) - movaps %xmm12,-0x78(%rax) - movaps %xmm13,-0x68(%rax) - movaps %xmm14,-0x58(%rax) - movaps %xmm15,-0x48(%rax) -.Lgcm_dec_body: +if ($win64) { +$code.=<<___ + lea -0xa8(%rsp),%rsp # 8 extra bytes to align the stack +.seh_allocstack 0xa8 +.seh_setframe %rbp, 0xa8+5*8 + # Load the last two parameters. These go into %rdi and %rsi, which are + # non-volatile on Windows, so stash them in the parameter stack area + # first. + mov %rdi, 0x10(%rbp) +.seh_savereg %rdi, 0xa8+5*8+0x10 + mov %rsi, 0x18(%rbp) +.seh_savereg %rsi, 0xa8+5*8+0x18 + mov 0x30(%rbp), $ivp + mov 0x38(%rbp), $Htable + # Save non-volatile XMM registers. + movaps %xmm6,-0xd0(%rbp) +.seh_savexmm128 %xmm6, 0xa8+5*8-0xd0 + movaps %xmm7,-0xc0(%rbp) +.seh_savexmm128 %xmm7, 0xa8+5*8-0xc0 + movaps %xmm8,-0xb0(%rbp) +.seh_savexmm128 %xmm8, 0xa8+5*8-0xb0 + movaps %xmm9,-0xa0(%rbp) +.seh_savexmm128 %xmm9, 0xa8+5*8-0xa0 + movaps %xmm10,-0x90(%rbp) +.seh_savexmm128 %xmm10, 0xa8+5*8-0x90 + movaps %xmm11,-0x80(%rbp) +.seh_savexmm128 %xmm11, 0xa8+5*8-0x80 + movaps %xmm12,-0x70(%rbp) +.seh_savexmm128 %xmm12, 0xa8+5*8-0x70 + movaps %xmm13,-0x60(%rbp) +.seh_savexmm128 %xmm13, 0xa8+5*8-0x60 + movaps %xmm14,-0x50(%rbp) +.seh_savexmm128 %xmm14, 0xa8+5*8-0x50 + movaps %xmm15,-0x40(%rbp) +.seh_savexmm128 %xmm15, 0xa8+5*8-0x40 ___ +} $code.=<<___; vzeroupper + mov $Xip_offset(%rbp), %r12 vmovdqu ($ivp),$T1 # input counter value add \$-128,%rsp mov 12($ivp),$counter lea .Lbswap_mask(%rip),$const lea -0x80($key),$in0 # borrow $in0 mov \$0xf80,$end0 # borrow $end0 - vmovdqu ($Xip),$Xi # load Xi + vmovdqu (%r12),$Xi # load Xi and \$-128,%rsp # ensure stack alignment vmovdqu ($const),$Ii # borrow $Ii for .Lbswap_mask lea 0x80($key),$key # size optimization - lea 0x20+0x20($Xip),$Xip # size optimization + lea 0x20($Htable),$Htable # size optimization mov 0xf0-0x80($key),$rounds vpshufb $Ii,$Xi,$Xi @@ -488,7 +535,7 @@ $code.=<<___; .Ldec_no_key_aliasing: vmovdqu 0x50($inp),$Z3 # I[5] - lea ($inp),$in0 + mov $inp,$in0 vmovdqu 0x40($inp),$Z0 # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0) @@ -501,7 +548,7 @@ $code.=<<___; vmovdqu 0x30($inp),$Z1 shr \$4,$len - xor $ret,$ret + xor %rax,%rax vmovdqu 0x20($inp),$Z2 vpshufb $Ii,$Z3,$Z3 # passed to _aesni_ctr32_ghash_6x vmovdqu 0x10($inp),$T2 @@ -519,6 +566,7 @@ $code.=<<___; call _aesni_ctr32_ghash_6x + mov $Xip_offset(%rbp), %r12 vmovups $inout0,-0x60($out) # save output vmovups $inout1,-0x50($out) vmovups $inout2,-0x40($out) @@ -527,40 +575,42 @@ $code.=<<___; vmovups $inout5,-0x10($out) vpshufb ($const),$Xi,$Xi # .Lbswap_mask - vmovdqu $Xi,-0x40($Xip) # output Xi + vmovdqu $Xi,(%r12) # output Xi vzeroupper ___ $code.=<<___ if ($win64); - movaps -0xd8(%rax),%xmm6 - movaps -0xc8(%rax),%xmm7 - movaps -0xb8(%rax),%xmm8 - movaps -0xa8(%rax),%xmm9 - movaps -0x98(%rax),%xmm10 - movaps -0x88(%rax),%xmm11 - movaps -0x78(%rax),%xmm12 - movaps -0x68(%rax),%xmm13 - movaps -0x58(%rax),%xmm14 - movaps -0x48(%rax),%xmm15 + movaps -0xd0(%rbp),%xmm6 + movaps -0xc0(%rbp),%xmm7 + movaps -0xb0(%rbp),%xmm8 + movaps -0xa0(%rbp),%xmm9 + movaps -0x90(%rbp),%xmm10 + movaps -0x80(%rbp),%xmm11 + movaps -0x70(%rbp),%xmm12 + movaps -0x60(%rbp),%xmm13 + movaps -0x50(%rbp),%xmm14 + movaps -0x40(%rbp),%xmm15 + mov 0x10(%rbp),%rdi + mov 0x18(%rbp),%rsi ___ $code.=<<___; - mov -48(%rax),%r15 -.cfi_restore %r15 - mov -40(%rax),%r14 -.cfi_restore %r14 - mov -32(%rax),%r13 -.cfi_restore %r13 - mov -24(%rax),%r12 -.cfi_restore %r12 - mov -16(%rax),%rbp -.cfi_restore %rbp - mov -8(%rax),%rbx -.cfi_restore %rbx - lea (%rax),%rsp # restore %rsp -.cfi_def_cfa_register %rsp + lea -0x28(%rbp), %rsp # restore %rsp to fixed allocation +.cfi_def_cfa %rsp, 0x38 + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp .Lgcm_dec_abort: - mov $ret,%rax # return value ret +.seh_endproc .cfi_endproc .size aesni_gcm_decrypt,.-aesni_gcm_decrypt ___ @@ -660,15 +710,16 @@ _aesni_ctr32_6x: .size _aesni_ctr32_6x,.-_aesni_ctr32_6x .globl aesni_gcm_encrypt -.type aesni_gcm_encrypt,\@function,6 +.type aesni_gcm_encrypt,\@abi-omnipotent .align 32 aesni_gcm_encrypt: .cfi_startproc +.seh_startproc #ifdef BORINGSSL_DISPATCH_TEST .extern BORINGSSL_function_hit movb \$1,BORINGSSL_function_hit+2(%rip) #endif - xor $ret,$ret + xor %rax,%rax # We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of # input. Then we call |_aesni_ctr32_ghash_6x|, which requires at @@ -676,35 +727,64 @@ aesni_gcm_encrypt: cmp \$0x60*3,$len # minimal accepted length jb .Lgcm_enc_abort - lea (%rsp),%rax # save stack pointer -.cfi_def_cfa_register %rax - push %rbx -.cfi_push %rbx push %rbp .cfi_push %rbp +.seh_pushreg %rbp + mov %rsp, %rbp # save stack pointer +.cfi_def_cfa_register %rbp + push %rbx +.cfi_push %rbx +.seh_pushreg %rbx push %r12 .cfi_push %r12 +.seh_pushreg %r12 push %r13 .cfi_push %r13 +.seh_pushreg %r13 push %r14 .cfi_push %r14 +.seh_pushreg %r14 push %r15 .cfi_push %r15 +.seh_pushreg %r15 ___ -$code.=<<___ if ($win64); - lea -0xa8(%rsp),%rsp - movaps %xmm6,-0xd8(%rax) - movaps %xmm7,-0xc8(%rax) - movaps %xmm8,-0xb8(%rax) - movaps %xmm9,-0xa8(%rax) - movaps %xmm10,-0x98(%rax) - movaps %xmm11,-0x88(%rax) - movaps %xmm12,-0x78(%rax) - movaps %xmm13,-0x68(%rax) - movaps %xmm14,-0x58(%rax) - movaps %xmm15,-0x48(%rax) -.Lgcm_enc_body: +if ($win64) { +$code.=<<___ + lea -0xa8(%rsp),%rsp # 8 extra bytes to align the stack +.seh_allocstack 0xa8 +.seh_setframe %rbp, 0xa8+5*8 + # Load the last two parameters. These go into %rdi and %rsi, which are + # non-volatile on Windows, so stash them in the parameter stack area + # first. + mov %rdi, 0x10(%rbp) +.seh_savereg %rdi, 0xa8+5*8+0x10 + mov %rsi, 0x18(%rbp) +.seh_savereg %rsi, 0xa8+5*8+0x18 + mov 0x30(%rbp), $ivp + mov 0x38(%rbp), $Htable + # Save non-volatile XMM registers. + movaps %xmm6,-0xd0(%rbp) +.seh_savexmm128 %xmm6, 0xa8+5*8-0xd0 + movaps %xmm7,-0xc0(%rbp) +.seh_savexmm128 %xmm7, 0xa8+5*8-0xc0 + movaps %xmm8,-0xb0(%rbp) +.seh_savexmm128 %xmm8, 0xa8+5*8-0xb0 + movaps %xmm9,-0xa0(%rbp) +.seh_savexmm128 %xmm9, 0xa8+5*8-0xa0 + movaps %xmm10,-0x90(%rbp) +.seh_savexmm128 %xmm10, 0xa8+5*8-0x90 + movaps %xmm11,-0x80(%rbp) +.seh_savexmm128 %xmm11, 0xa8+5*8-0x80 + movaps %xmm12,-0x70(%rbp) +.seh_savexmm128 %xmm12, 0xa8+5*8-0x70 + movaps %xmm13,-0x60(%rbp) +.seh_savexmm128 %xmm13, 0xa8+5*8-0x60 + movaps %xmm14,-0x50(%rbp) +.seh_savexmm128 %xmm14, 0xa8+5*8-0x50 + movaps %xmm15,-0x40(%rbp) +.seh_savexmm128 %xmm15, 0xa8+5*8-0x40 ___ +} $code.=<<___; vzeroupper @@ -728,7 +808,7 @@ $code.=<<___; sub $end0,%rsp # avoid aliasing with key .Lenc_no_key_aliasing: - lea ($out),$in0 + mov $out,$in0 # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0) # bytes before the end of the input. Note, in particular, that this is @@ -756,18 +836,19 @@ $code.=<<___; call _aesni_ctr32_6x - vmovdqu ($Xip),$Xi # load Xi - lea 0x20+0x20($Xip),$Xip # size optimization + mov $Xip_offset(%rbp), %r12 + lea 0x20($Htable),$Htable # size optimization + vmovdqu (%r12),$Xi # load Xi sub \$12,$len - mov \$0x60*2,$ret + mov \$0x60*2,%rax vpshufb $Ii,$Xi,$Xi call _aesni_ctr32_ghash_6x vmovdqu 0x20(%rsp),$Z3 # I[5] vmovdqu ($const),$Ii # borrow $Ii for .Lbswap_mask - vmovdqu 0x00-0x20($Xip),$Hkey # $Hkey^1 + vmovdqu 0x00-0x20($Htable),$Hkey # $Hkey^1 vpunpckhqdq $Z3,$Z3,$T1 - vmovdqu 0x20-0x20($Xip),$rndkey # borrow $rndkey for $HK + vmovdqu 0x20-0x20($Htable),$rndkey # borrow $rndkey for $HK vmovups $inout0,-0x60($out) # save output vpshufb $Ii,$inout0,$inout0 # but keep bswapped copy vpxor $Z3,$T1,$T1 @@ -787,7 +868,7 @@ ___ $code.=<<___; vmovdqu 0x30(%rsp),$Z2 # I[4] - vmovdqu 0x10-0x20($Xip),$Ii # borrow $Ii for $Hkey^2 + vmovdqu 0x10-0x20($Htable),$Ii # borrow $Ii for $Hkey^2 vpunpckhqdq $Z2,$Z2,$T2 vpclmulqdq \$0x00,$Hkey,$Z3,$Z1 vpxor $Z2,$T2,$T2 @@ -796,19 +877,19 @@ $code.=<<___; vmovdqu 0x40(%rsp),$T3 # I[3] vpclmulqdq \$0x00,$Ii,$Z2,$Z0 - vmovdqu 0x30-0x20($Xip),$Hkey # $Hkey^3 + vmovdqu 0x30-0x20($Htable),$Hkey # $Hkey^3 vpxor $Z1,$Z0,$Z0 vpunpckhqdq $T3,$T3,$Z1 vpclmulqdq \$0x11,$Ii,$Z2,$Z2 vpxor $T3,$Z1,$Z1 vpxor $Z3,$Z2,$Z2 vpclmulqdq \$0x10,$HK,$T2,$T2 - vmovdqu 0x50-0x20($Xip),$HK + vmovdqu 0x50-0x20($Htable),$HK vpxor $T1,$T2,$T2 vmovdqu 0x50(%rsp),$T1 # I[2] vpclmulqdq \$0x00,$Hkey,$T3,$Z3 - vmovdqu 0x40-0x20($Xip),$Ii # borrow $Ii for $Hkey^4 + vmovdqu 0x40-0x20($Htable),$Ii # borrow $Ii for $Hkey^4 vpxor $Z0,$Z3,$Z3 vpunpckhqdq $T1,$T1,$Z0 vpclmulqdq \$0x11,$Hkey,$T3,$T3 @@ -819,19 +900,19 @@ $code.=<<___; vmovdqu 0x60(%rsp),$T2 # I[1] vpclmulqdq \$0x00,$Ii,$T1,$Z2 - vmovdqu 0x60-0x20($Xip),$Hkey # $Hkey^5 + vmovdqu 0x60-0x20($Htable),$Hkey # $Hkey^5 vpxor $Z3,$Z2,$Z2 vpunpckhqdq $T2,$T2,$Z3 vpclmulqdq \$0x11,$Ii,$T1,$T1 vpxor $T2,$Z3,$Z3 vpxor $T3,$T1,$T1 vpclmulqdq \$0x10,$HK,$Z0,$Z0 - vmovdqu 0x80-0x20($Xip),$HK + vmovdqu 0x80-0x20($Htable),$HK vpxor $Z1,$Z0,$Z0 vpxor 0x70(%rsp),$Xi,$Xi # accumulate I[0] vpclmulqdq \$0x00,$Hkey,$T2,$Z1 - vmovdqu 0x70-0x20($Xip),$Ii # borrow $Ii for $Hkey^6 + vmovdqu 0x70-0x20($Htable),$Ii # borrow $Ii for $Hkey^6 vpunpckhqdq $Xi,$Xi,$T3 vpxor $Z2,$Z1,$Z1 vpclmulqdq \$0x11,$Hkey,$T2,$T2 @@ -841,17 +922,17 @@ $code.=<<___; vpxor $Z0,$Z3,$Z0 vpclmulqdq \$0x00,$Ii,$Xi,$Z2 - vmovdqu 0x00-0x20($Xip),$Hkey # $Hkey^1 + vmovdqu 0x00-0x20($Htable),$Hkey # $Hkey^1 vpunpckhqdq $inout5,$inout5,$T1 vpclmulqdq \$0x11,$Ii,$Xi,$Xi vpxor $inout5,$T1,$T1 vpxor $Z1,$Z2,$Z1 vpclmulqdq \$0x10,$HK,$T3,$T3 - vmovdqu 0x20-0x20($Xip),$HK + vmovdqu 0x20-0x20($Htable),$HK vpxor $T2,$Xi,$Z3 vpxor $Z0,$T3,$Z2 - vmovdqu 0x10-0x20($Xip),$Ii # borrow $Ii for $Hkey^2 + vmovdqu 0x10-0x20($Htable),$Ii # borrow $Ii for $Hkey^2 vpxor $Z1,$Z3,$T3 # aggregated Karatsuba post-processing vpclmulqdq \$0x00,$Hkey,$inout5,$Z0 vpxor $T3,$Z2,$Z2 @@ -865,7 +946,7 @@ $code.=<<___; vpxor $Z2,$Z3,$Z3 vpclmulqdq \$0x00,$Ii,$inout4,$Z1 - vmovdqu 0x30-0x20($Xip),$Hkey # $Hkey^3 + vmovdqu 0x30-0x20($Htable),$Hkey # $Hkey^3 vpxor $Z0,$Z1,$Z1 vpunpckhqdq $inout3,$inout3,$T3 vpclmulqdq \$0x11,$Ii,$inout4,$inout4 @@ -873,11 +954,11 @@ $code.=<<___; vpxor $inout5,$inout4,$inout4 vpalignr \$8,$Xi,$Xi,$inout5 # 1st phase vpclmulqdq \$0x10,$HK,$T2,$T2 - vmovdqu 0x50-0x20($Xip),$HK + vmovdqu 0x50-0x20($Htable),$HK vpxor $T1,$T2,$T2 vpclmulqdq \$0x00,$Hkey,$inout3,$Z0 - vmovdqu 0x40-0x20($Xip),$Ii # borrow $Ii for $Hkey^4 + vmovdqu 0x40-0x20($Htable),$Ii # borrow $Ii for $Hkey^4 vpxor $Z1,$Z0,$Z0 vpunpckhqdq $inout2,$inout2,$T1 vpclmulqdq \$0x11,$Hkey,$inout3,$inout3 @@ -891,7 +972,7 @@ $code.=<<___; vxorps $inout5,$Xi,$Xi vpclmulqdq \$0x00,$Ii,$inout2,$Z1 - vmovdqu 0x60-0x20($Xip),$Hkey # $Hkey^5 + vmovdqu 0x60-0x20($Htable),$Hkey # $Hkey^5 vpxor $Z0,$Z1,$Z1 vpunpckhqdq $inout1,$inout1,$T2 vpclmulqdq \$0x11,$Ii,$inout2,$inout2 @@ -899,7 +980,7 @@ $code.=<<___; vpalignr \$8,$Xi,$Xi,$inout5 # 2nd phase vpxor $inout3,$inout2,$inout2 vpclmulqdq \$0x10,$HK,$T1,$T1 - vmovdqu 0x80-0x20($Xip),$HK + vmovdqu 0x80-0x20($Htable),$HK vpxor $T3,$T1,$T1 vxorps $Z3,$inout5,$inout5 @@ -907,7 +988,7 @@ $code.=<<___; vxorps $inout5,$Xi,$Xi vpclmulqdq \$0x00,$Hkey,$inout1,$Z0 - vmovdqu 0x70-0x20($Xip),$Ii # borrow $Ii for $Hkey^6 + vmovdqu 0x70-0x20($Htable),$Ii # borrow $Ii for $Hkey^6 vpxor $Z1,$Z0,$Z0 vpunpckhqdq $Xi,$Xi,$T3 vpclmulqdq \$0x11,$Hkey,$inout1,$inout1 @@ -942,46 +1023,50 @@ $code.=<<___; ___ } $code.=<<___; + mov $Xip_offset(%rbp), %r12 vpshufb ($const),$Xi,$Xi # .Lbswap_mask - vmovdqu $Xi,-0x40($Xip) # output Xi + vmovdqu $Xi,(%r12) # output Xi vzeroupper ___ $code.=<<___ if ($win64); - movaps -0xd8(%rax),%xmm6 - movaps -0xc8(%rax),%xmm7 - movaps -0xb8(%rax),%xmm8 - movaps -0xa8(%rax),%xmm9 - movaps -0x98(%rax),%xmm10 - movaps -0x88(%rax),%xmm11 - movaps -0x78(%rax),%xmm12 - movaps -0x68(%rax),%xmm13 - movaps -0x58(%rax),%xmm14 - movaps -0x48(%rax),%xmm15 + movaps -0xd0(%rbp),%xmm6 + movaps -0xc0(%rbp),%xmm7 + movaps -0xb0(%rbp),%xmm8 + movaps -0xa0(%rbp),%xmm9 + movaps -0x90(%rbp),%xmm10 + movaps -0x80(%rbp),%xmm11 + movaps -0x70(%rbp),%xmm12 + movaps -0x60(%rbp),%xmm13 + movaps -0x50(%rbp),%xmm14 + movaps -0x40(%rbp),%xmm15 + mov 0x10(%rbp),%rdi + mov 0x18(%rbp),%rsi ___ $code.=<<___; - mov -48(%rax),%r15 -.cfi_restore %r15 - mov -40(%rax),%r14 -.cfi_restore %r14 - mov -32(%rax),%r13 -.cfi_restore %r13 - mov -24(%rax),%r12 -.cfi_restore %r12 - mov -16(%rax),%rbp -.cfi_restore %rbp - mov -8(%rax),%rbx -.cfi_restore %rbx - lea (%rax),%rsp # restore %rsp -.cfi_def_cfa_register %rsp + lea -0x28(%rbp), %rsp # restore %rsp to fixed allocation +.cfi_def_cfa %rsp, 0x38 + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp .Lgcm_enc_abort: - mov $ret,%rax # return value ret +.seh_endproc .cfi_endproc -.size aesni_gcm_encrypt,.-aesni_gcm_encrypt +.size aesni_gcm_decrypt,.-aesni_gcm_decrypt ___ $code.=<<___; +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -995,128 +1080,8 @@ $code.=<<___; .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .asciz "AES-NI GCM module for x86_64, CRYPTOGAMS by " .align 64 +.text ___ -if ($win64) { -$rec="%rcx"; -$frame="%rdx"; -$context="%r8"; -$disp="%r9"; - -$code.=<<___ -.extern __imp_RtlVirtualUnwind -.type gcm_se_handler,\@abi-omnipotent -.align 16 -gcm_se_handler: - push %rsi - push %rdi - push %rbx - push %rbp - push %r12 - push %r13 - push %r14 - push %r15 - pushfq - sub \$64,%rsp - - mov 120($context),%rax # pull context->Rax - mov 248($context),%rbx # pull context->Rip - - mov 8($disp),%rsi # disp->ImageBase - mov 56($disp),%r11 # disp->HandlerData - - mov 0(%r11),%r10d # HandlerData[0] - lea (%rsi,%r10),%r10 # prologue label - cmp %r10,%rbx # context->RipRsp - - mov 4(%r11),%r10d # HandlerData[1] - lea (%rsi,%r10),%r10 # epilogue label - cmp %r10,%rbx # context->Rip>=epilogue label - jae .Lcommon_seh_tail - - mov 120($context),%rax # pull context->Rax - - mov -48(%rax),%r15 - mov -40(%rax),%r14 - mov -32(%rax),%r13 - mov -24(%rax),%r12 - mov -16(%rax),%rbp - mov -8(%rax),%rbx - mov %r15,240($context) - mov %r14,232($context) - mov %r13,224($context) - mov %r12,216($context) - mov %rbp,160($context) - mov %rbx,144($context) - - lea -0xd8(%rax),%rsi # %xmm save area - lea 512($context),%rdi # & context.Xmm6 - mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax) - .long 0xa548f3fc # cld; rep movsq - -.Lcommon_seh_tail: - mov 8(%rax),%rdi - mov 16(%rax),%rsi - mov %rax,152($context) # restore context->Rsp - mov %rsi,168($context) # restore context->Rsi - mov %rdi,176($context) # restore context->Rdi - - mov 40($disp),%rdi # disp->ContextRecord - mov $context,%rsi # context - mov \$154,%ecx # sizeof(CONTEXT) - .long 0xa548f3fc # cld; rep movsq - - mov $disp,%rsi - xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER - mov 8(%rsi),%rdx # arg2, disp->ImageBase - mov 0(%rsi),%r8 # arg3, disp->ControlPc - mov 16(%rsi),%r9 # arg4, disp->FunctionEntry - mov 40(%rsi),%r10 # disp->ContextRecord - lea 56(%rsi),%r11 # &disp->HandlerData - lea 24(%rsi),%r12 # &disp->EstablisherFrame - mov %r10,32(%rsp) # arg5 - mov %r11,40(%rsp) # arg6 - mov %r12,48(%rsp) # arg7 - mov %rcx,56(%rsp) # arg8, (NULL) - call *__imp_RtlVirtualUnwind(%rip) - - mov \$1,%eax # ExceptionContinueSearch - add \$64,%rsp - popfq - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbp - pop %rbx - pop %rdi - pop %rsi - ret -.size gcm_se_handler,.-gcm_se_handler - -.section .pdata -.align 4 - .rva .LSEH_begin_aesni_gcm_decrypt - .rva .LSEH_end_aesni_gcm_decrypt - .rva .LSEH_gcm_dec_info - - .rva .LSEH_begin_aesni_gcm_encrypt - .rva .LSEH_end_aesni_gcm_encrypt - .rva .LSEH_gcm_enc_info -.section .xdata -.align 8 -.LSEH_gcm_dec_info: - .byte 9,0,0,0 - .rva gcm_se_handler - .rva .Lgcm_dec_body,.Lgcm_dec_abort -.LSEH_gcm_enc_info: - .byte 9,0,0,0 - .rva gcm_se_handler - .rva .Lgcm_enc_body,.Lgcm_enc_abort -___ -} }}} else {{{ $code=<<___; # assembler is too old .text diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesv8-gcm-armv8.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesv8-gcm-armv8.pl new file mode 100644 index 00000000..08ea58de --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/aesv8-gcm-armv8.pl @@ -0,0 +1,1542 @@ +#! /usr/bin/env perl + +# Copyright (c) 2022, ARM Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#======================================================================== +# Written by Fangming Fang for the OpenSSL project, +# derived from https://github.com/ARM-software/AArch64cryptolib, original +# author Samuel Lee . +#======================================================================== +# +# Approach - assume we don't want to reload constants, so reserve ~half of +# vector register file for constants +# +# main loop to act on 4 16B blocks per iteration, and then do modulo of the +# accumulated intermediate hashes from the 4 blocks +# +# ____________________________________________________ +# | | +# | PRE | +# |____________________________________________________| +# | | | | +# | CTR block 4k+8 | AES block 4k+4 | GHASH block 4k+0 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+9 | AES block 4k+5 | GHASH block 4k+1 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+10| AES block 4k+6 | GHASH block 4k+2 | +# |________________|________________|__________________| +# | | | | +# | CTR block 4k+11| AES block 4k+7 | GHASH block 4k+3 | +# |________________|____(mostly)____|__________________| +# | | +# | MODULO | +# |____________________________________________________| +# +# PRE: Ensure previous generated intermediate hash is aligned and merged with +# result for GHASH 4k+0 +# +# EXT low_acc, low_acc, low_acc, #8 +# EOR res_curr (4k+0), res_curr (4k+0), low_acc +# +# CTR block: Increment and byte reverse counter in scalar registers and transfer +# to SIMD registers +# +# REV ctr32, rev_ctr32 +# ORR ctr64, constctr96_top32, ctr32, LSL #32 +# // Keeping this in scalar registers to free up space in SIMD RF +# INS ctr_next.d[0], constctr96_bottom64 +# INS ctr_next.d[1], ctr64X +# ADD rev_ctr32, #1 +# +# AES block: +# +# Do AES encryption/decryption on CTR block X and EOR it with input block X. +# Take 256 bytes key below for example. Doing small trick here of loading input +# in scalar registers, EORing with last key and then transferring Given we are +# very constrained in our ASIMD registers this is quite important +# +# Encrypt: +# LDR input_low, [ input_ptr ], #8 +# LDR input_high, [ input_ptr ], #8 +# EOR input_low, k14_low +# EOR input_high, k14_high +# INS res_curr.d[0], input_low +# INS res_curr.d[1], input_high +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# EOR res_curr, res_curr, ctr_curr +# ST1 { res_curr.16b }, [ output_ptr ], #16 +# +# Decrypt: +# AESE ctr_curr, k0; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k1; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k2; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k3; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k4; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k5; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k6; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k7; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k8; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k9; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k10; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k11; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k12; AESMC ctr_curr, ctr_curr +# AESE ctr_curr, k13 +# LDR res_curr, [ input_ptr ], #16 +# EOR res_curr, res_curr, ctr_curr +# MOV output_low, res_curr.d[0] +# MOV output_high, res_curr.d[1] +# EOR output_low, k14_low +# EOR output_high, k14_high +# STP output_low, output_high, [ output_ptr ], #16 +# +# GHASH block X: +# Do 128b karatsuba polynomial multiplication on block. We only have +# 64b->128b polynomial multipliers, naively that means we need to do 4 64b +# multiplies to generate a 128b. +# +# multiplication: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ +# (Pmull(Ah,Bl) ^ Pmull(Al,Bh))<<64 +# +# The idea behind Karatsuba multiplication is that we can do just 3 64b +# multiplies: +# Pmull(A,B) == (Pmull(Ah,Bh)<<128 | Pmull(Al,Bl)) ^ +# (Pmull(Ah^Al,Bh^Bl) ^ Pmull(Ah,Bh) ^ +# Pmull(Al,Bl))<<64 +# +# There is some complication here because the bit order of GHASH's PMULL is +# reversed compared to elsewhere, so we are multiplying with "twisted" +# powers of H +# +# Note: We can PMULL directly into the acc_x in first GHASH of the loop +# +# Note: For scheduling big cores we want to split the processing to happen over +# two loop iterations - otherwise the critical path latency dominates the +# performance. +# +# This has a knock on effect on register pressure, so we have to be a bit +# more clever with our temporary registers than indicated here +# +# REV64 res_curr, res_curr +# INS t_m.d[0], res_curr.d[1] +# EOR t_m.8B, t_m.8B, res_curr.8B +# PMULL2 t_h, res_curr, HX +# PMULL t_l, res_curr, HX +# PMULL t_m, t_m, HX_k +# EOR acc_h, acc_h, t_h +# EOR acc_l, acc_l, t_l +# EOR acc_m, acc_m, t_m +# +# MODULO: take the partial accumulators (~representing sum of 256b +# multiplication results), from GHASH and do modulo reduction on them +# There is some complication here because the bit order of GHASH's +# PMULL is reversed compared to elsewhere, so we are doing modulo with +# a reversed constant +# +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, acc_l // Finish off karatsuba processing +# PMULL t_mod, acc_h, mod_constant +# EXT acc_h, acc_h, acc_h, #8 +# EOR acc_m, acc_m, acc_h +# EOR acc_m, acc_m, t_mod +# PMULL acc_h, acc_m, mod_constant +# EXT acc_m, acc_m, acc_m, #8 +# EOR acc_l, acc_l, acc_h +# EOR acc_l, acc_l, acc_m +# +# This code was then modified to merge the AES-128-GCM, AES-192-GCM, and +# AES-256-GCM implementations into a single function to reduce size. We move the +# last two round keys into consistent registers across all sizes, as they're +# treated special. Then, after rounds 0 through 8, we added some branches to +# conditionally run rounds 9-10 (AES-192 + AES-256) and 11-12 (AES-256), before +# merging back into code which finishes up the last two rounds. +# +# There is a mostly decision to be made around how much parallel work goes +# before or after the conditional part. We attempted to preserve the original +# scheduling where possible, but it's possible other schedulings are more +# optimal with the current ordering. + +$flavour = shift; +$output = shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$code=<<___; +#include +#if __ARM_MAX_ARCH__ >= 8 + +.arch armv8-a+crypto +.text +___ + +$input_ptr="x0"; #argument block +$bit_length="x1"; +$output_ptr="x2"; +$current_tag="x3"; +$Htable="x6"; +$counter="x16"; +$cc="x8"; + +{ +my ($end_input_ptr,$main_end_input_ptr,$input_l0,$input_h0)=map("x$_",(4..7)); +my ($input_l1,$input_h1,$input_l2,$input_h2,$input_l3,$input_h3)=map("x$_",(19..24)); +my ($output_l1,$output_h1,$output_l2,$output_h2,$output_l3,$output_h3)=map("x$_",(19..24)); +my ($output_l0,$output_h0)=map("x$_",(6..7)); + +# rkN_l and rkN_h store the final round key, which is handled slightly +# differently because it is EORed through general-purpose registers. +my $ctr32w="w9"; +my ($ctr32x,$ctr96_b64x,$ctr96_t32x,$rctr32x,$rkN_l,$rkN_h,$len)=map("x$_",(9..15)); +my ($ctr96_t32w,$rctr32w)=map("w$_",(11..12)); + +my $rounds="x17"; +my $roundsw="w17"; + +my ($ctr0b,$ctr1b,$ctr2b,$ctr3b,$res0b,$res1b,$res2b,$res3b)=map("v$_.16b",(0..7)); +my ($ctr0,$ctr1,$ctr2,$ctr3,$res0,$res1,$res2,$res3)=map("v$_",(0..7)); +my ($ctr0d,$ctr1d,$ctr2d,$ctr3d,$res0d,$res1d,$res2d,$res3d)=map("d$_",(0..7)); +my ($res0q,$res1q,$res2q,$res3q)=map("q$_",(4..7)); + +my ($acc_hb,$acc_mb,$acc_lb)=map("v$_.16b",(9..11)); +my ($acc_h,$acc_m,$acc_l)=map("v$_",(9..11)); +my ($acc_hd,$acc_md,$acc_ld)=map("d$_",(9..11)); + +my ($h1,$h2,$h3,$h4,$h12k,$h34k)=map("v$_",(12..17)); +my ($h1q,$h2q,$h3q,$h4q)=map("q$_",(12..15)); +my ($h1b,$h2b,$h3b,$h4b)=map("v$_.16b",(12..15)); + +my $t0="v8"; +my $t0d="d8"; +my $t1="v4"; +my $t1d="d4"; +my $t2="v8"; +my $t2d="d8"; +my $t3="v4"; +my $t3d="d4"; +my $t4="v4"; +my $t4d="d4"; +my $t5="v5"; +my $t5d="d5"; +my $t6="v8"; +my $t6d="d8"; +my $t7="v5"; +my $t7d="d5"; +my $t8="v6"; +my $t8d="d6"; +my $t9="v4"; +my $t9d="d4"; + +my ($ctr_t0,$ctr_t1,$ctr_t2,$ctr_t3)=map("v$_",(4..7)); +my ($ctr_t0d,$ctr_t1d,$ctr_t2d,$ctr_t3d)=map("d$_",(4..7)); +my ($ctr_t0b,$ctr_t1b,$ctr_t2b,$ctr_t3b)=map("v$_.16b",(4..7)); + +my $mod_constantd="d8"; +my $mod_constant="v8"; +my $mod_t="v7"; + +# rkNm1 stores the second-to-last round key, which is handled slightly +# differently because it uses plain AESE instead of an AESE + AESMC macro-op. +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7,$rk8,$rk9,$rk10,$rk11,$rk12,$rkNm1)=map("v$_.16b",(18..31)); +my ($rk0q,$rk1q,$rk2q,$rk3q,$rk4q,$rk5q,$rk6q,$rk7q,$rk8q,$rk9q,$rk10q,$rk11q,$rk12q,$rkNm1q)=map("q$_",(18..31)); +my $rk2q1="v20.1q"; +my $rk3q1="v21.1q"; +my $rk4v="v22"; +my $rk4d="d22"; + +################################################################################ +# size_t aes_gcm_enc_kernel(const uint8_t *in, +# size_t len_bits, +# uint8_t *out, +# u64 *Xi, +# uint8_t ivec[16], +# const void *key, +# const void *Htable); +# +$code.=<<___; +.global aes_gcm_enc_kernel +.type aes_gcm_enc_kernel,%function +.align 4 +aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov $counter, x4 + mov $cc, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr $roundsw, [$cc, #240] + add $input_l1, $cc, $rounds, lsl #4 // borrow input_l1 for last key + ldp $rkN_l, $rkN_h, [$input_l1] // load round N keys + ldr $rkNm1q, [$input_l1, #-16] // load round N-1 keys + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 // end_input_ptr + lsr $main_end_input_ptr, $bit_length, #3 // byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] // ctr96_b64, ctr96_t32 + ld1 { $ctr0b}, [$counter] // special case vector load initial counter so we can start first AES block as quickly as possible + sub $main_end_input_ptr, $main_end_input_ptr, #1 // byte_len - 1 + ldr $rk0q, [$cc, #0] // load rk0 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr $rk7q, [$cc, #112] // load rk7 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + lsr $rctr32x, $ctr96_t32x, #32 + fmov $ctr2d, $ctr96_b64x // CTR block 2 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + rev $rctr32w, $rctr32w // rev_ctr32 + fmov $ctr1d, $ctr96_b64x // CTR block 1 + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 0 + add $rctr32w, $rctr32w, #1 // increment rev_ctr32 + rev $ctr32w, $rctr32w // CTR block 1 + fmov $ctr3d, $ctr96_b64x // CTR block 3 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 1 + add $rctr32w, $rctr32w, #1 // CTR block 1 + ldr $rk1q, [$cc, #16] // load rk1 + fmov $ctr1.d[1], $ctr32x // CTR block 1 + rev $ctr32w, $rctr32w // CTR block 2 + add $rctr32w, $rctr32w, #1 // CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 2 + ldr $rk2q, [$cc, #32] // load rk2 + fmov $ctr2.d[1], $ctr32x // CTR block 2 + rev $ctr32w, $rctr32w // CTR block 3 + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 3 + fmov $ctr3.d[1], $ctr32x // CTR block 3 + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 0 + ldr $rk3q, [$cc, #48] // load rk3 + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 2 + ldr $rk6q, [$cc, #96] // load rk6 + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 0 + ldr $rk5q, [$cc, #80] // load rk5 + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 1 + ldr $h3q, [$Htable, #48] // load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 0 + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 1 + ldr $rk4q, [$cc, #64] // load rk4 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 2 + ldr $h2q, [$Htable, #32] // load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 1 + ldr $rk12q, [$cc, #192] // load rk12 + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 2 + ldr $h4q, [$Htable, #80] // load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 3 + ldr $rk11q, [$cc, #176] // load rk11 + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 2 + ldr $rk8q, [$cc, #128] // load rk8 + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 3 + add $rctr32w, $rctr32w, #1 // CTR block 3 + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 3 + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 3 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 4 + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 4 + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 4 + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 4 + cmp $rounds, #12 // setup flags for AES-128/192/256 check + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 5 + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 5 + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 5 + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 5 + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 6 + trn2 $h34k.2d, $h3.2d, $h4.2d // h4l | h3l + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 6 + ldr $rk9q, [$cc, #144] // load rk9 + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 6 + ldr $h1q, [$Htable] // load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 6 + ldr $rk10q, [$cc, #160] // load rk10 + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 7 + trn1 $acc_h.2d, $h3.2d, $h4.2d // h4h | h3h + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 7 + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 7 + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 7 + trn2 $h12k.2d, $h1.2d, $h2.2d // h2l | h1l + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 8 + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 8 + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 8 + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 8 + b.lt .Lenc_finish_first_blocks // branch if AES-128 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 9 + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 9 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 10 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 10 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 10 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 10 + b.eq .Lenc_finish_first_blocks // branch if AES-192 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 11 + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 11 + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 11 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 11 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 12 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 12 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 12 + +.Lenc_finish_first_blocks: + cmp $input_ptr, $main_end_input_ptr // check if we have <= 4 blocks + eor $h34k.16b, $h34k.16b, $acc_h.16b // h4k | h3k + aese $ctr2b, $rkNm1 // AES block 2 - round N-1 + trn1 $t0.2d, $h1.2d, $h2.2d // h2h | h1h + aese $ctr1b, $rkNm1 // AES block 1 - round N-1 + aese $ctr0b, $rkNm1 // AES block 0 - round N-1 + aese $ctr3b, $rkNm1 // AES block 3 - round N-1 + eor $h12k.16b, $h12k.16b, $t0.16b // h2k | h1k + b.ge .Lenc_tail // handle tail + + ldp $input_l1, $input_h1, [$input_ptr, #16] // AES block 1 - load plaintext + rev $ctr32w, $rctr32w // CTR block 4 + ldp $input_l0, $input_h0, [$input_ptr, #0] // AES block 0 - load plaintext + ldp $input_l3, $input_h3, [$input_ptr, #48] // AES block 3 - load plaintext + ldp $input_l2, $input_h2, [$input_ptr, #32] // AES block 2 - load plaintext + add $input_ptr, $input_ptr, #64 // AES input_ptr update + eor $input_l1, $input_l1, $rkN_l // AES block 1 - round N low + eor $input_h1, $input_h1, $rkN_h // AES block 1 - round N high + fmov $ctr_t1d, $input_l1 // AES block 1 - mov low + eor $input_l0, $input_l0, $rkN_l // AES block 0 - round N low + eor $input_h0, $input_h0, $rkN_h // AES block 0 - round N high + eor $input_h3, $input_h3, $rkN_h // AES block 3 - round N high + fmov $ctr_t0d, $input_l0 // AES block 0 - mov low + cmp $input_ptr, $main_end_input_ptr // check if we have <= 8 blocks + fmov $ctr_t0.d[1], $input_h0 // AES block 0 - mov high + eor $input_l3, $input_l3, $rkN_l // AES block 3 - round N low + eor $input_l2, $input_l2, $rkN_l // AES block 2 - round N low + fmov $ctr_t1.d[1], $input_h1 // AES block 1 - mov high + fmov $ctr_t2d, $input_l2 // AES block 2 - mov low + add $rctr32w, $rctr32w, #1 // CTR block 4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4 + fmov $ctr_t3d, $input_l3 // AES block 3 - mov low + eor $input_h2, $input_h2, $rkN_h // AES block 2 - round N high + fmov $ctr_t2.d[1], $input_h2 // AES block 2 - mov high + eor $res0b, $ctr_t0b, $ctr0b // AES block 0 - result + fmov $ctr0d, $ctr96_b64x // CTR block 4 + fmov $ctr0.d[1], $ctr32x // CTR block 4 + rev $ctr32w, $rctr32w // CTR block 5 + add $rctr32w, $rctr32w, #1 // CTR block 5 + eor $res1b, $ctr_t1b, $ctr1b // AES block 1 - result + fmov $ctr1d, $ctr96_b64x // CTR block 5 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 5 + fmov $ctr1.d[1], $ctr32x // CTR block 5 + rev $ctr32w, $rctr32w // CTR block 6 + st1 { $res0b}, [$output_ptr], #16 // AES block 0 - store result + fmov $ctr_t3.d[1], $input_h3 // AES block 3 - mov high + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 6 + eor $res2b, $ctr_t2b, $ctr2b // AES block 2 - result + st1 { $res1b}, [$output_ptr], #16 // AES block 1 - store result + add $rctr32w, $rctr32w, #1 // CTR block 6 + fmov $ctr2d, $ctr96_b64x // CTR block 6 + fmov $ctr2.d[1], $ctr32x // CTR block 6 + st1 { $res2b}, [$output_ptr], #16 // AES block 2 - store result + rev $ctr32w, $rctr32w // CTR block 7 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 7 + eor $res3b, $ctr_t3b, $ctr3b // AES block 3 - result + st1 { $res3b}, [$output_ptr], #16 // AES block 3 - store result + b.ge .Lenc_prepretail // do prepretail + +.Lenc_main_loop: // main loop start + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 0 + rev64 $res0b, $res0b // GHASH block 4k (only t0 is free) + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 0 + fmov $ctr3d, $ctr96_b64x // CTR block 4k+3 + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 0 + ext $acc_lb, $acc_lb, $acc_lb, #8 // PRE 0 + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 1 + fmov $ctr3.d[1], $ctr32x // CTR block 4k+3 + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 1 + ldp $input_l3, $input_h3, [$input_ptr, #48] // AES block 4k+7 - load plaintext + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 1 + ldp $input_l2, $input_h2, [$input_ptr, #32] // AES block 4k+6 - load plaintext + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 2 + eor $res0b, $res0b, $acc_lb // PRE 1 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 2 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 0 + eor $input_l3, $input_l3, $rkN_l // AES block 4k+7 - round N low + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 3 + mov $acc_md, $h34k.d[1] // GHASH block 4k - mid + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH block 4k - high + eor $input_h2, $input_h2, $rkN_h // AES block 4k+6 - round N high + mov $t0d, $res0.d[1] // GHASH block 4k - mid + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 1 + rev64 $res1b, $res1b // GHASH block 4k+1 (t0 and t1 free) + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 4 + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH block 4k - low + eor $t0.8b, $t0.8b, $res0.8b // GHASH block 4k - mid + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 2 + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 5 + rev64 $res3b, $res3b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 $t1.1q, $res1.2d, $h3.2d // GHASH block 4k+1 - high + pmull $acc_m.1q, $t0.1d, $acc_m.1d // GHASH block 4k - mid + rev64 $res2b, $res2b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull $t2.1q, $res1.1d, $h3.1d // GHASH block 4k+1 - low + eor $acc_hb, $acc_hb, $t1.16b // GHASH block 4k+1 - high + mov $t3d, $res1.d[1] // GHASH block 4k+1 - mid + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 3 + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 2 + eor $acc_lb, $acc_lb, $t2.16b // GHASH block 4k+1 - low + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 3 + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 4 + mov $t6d, $res2.d[1] // GHASH block 4k+2 - mid + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 3 + eor $t3.8b, $t3.8b, $res1.8b // GHASH block 4k+1 - mid + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 4 + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 6 + eor $t6.8b, $t6.8b, $res2.8b // GHASH block 4k+2 - mid + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 4 + pmull $t3.1q, $t3.1d, $h34k.1d // GHASH block 4k+1 - mid + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 7 + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] // GHASH block 4k+2 - mid + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 5 + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 8 + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 5 + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 6 + eor $acc_mb, $acc_mb, $t3.16b // GHASH block 4k+1 - mid + pmull2 $t4.1q, $res2.2d, $h2.2d // GHASH block 4k+2 - high + pmull $t5.1q, $res2.1d, $h2.1d // GHASH block 4k+2 - low + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 7 + pmull $t8.1q, $res3.1d, $h1.1d // GHASH block 4k+3 - low + eor $acc_hb, $acc_hb, $t4.16b // GHASH block 4k+2 - high + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 6 + ldp $input_l1, $input_h1, [$input_ptr, #16] // AES block 4k+5 - load plaintext + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 8 + mov $t9d, $res3.d[1] // GHASH block 4k+3 - mid + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 6 + eor $acc_lb, $acc_lb, $t5.16b // GHASH block 4k+2 - low + pmull2 $t6.1q, $t6.2d, $h12k.2d // GHASH block 4k+2 - mid + pmull2 $t7.1q, $res3.2d, $h1.2d // GHASH block 4k+3 - high + eor $t9.8b, $t9.8b, $res3.8b // GHASH block 4k+3 - mid + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 7 + eor $input_l1, $input_l1, $rkN_l // AES block 4k+5 - round N low + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $t6.16b // GHASH block 4k+2 - mid + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 7 + eor $input_l2, $input_l2, $rkN_l // AES block 4k+6 - round N low + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 8 + movi $mod_constant.8b, #0xc2 + pmull $t9.1q, $t9.1d, $h12k.1d // GHASH block 4k+3 - mid + eor $acc_hb, $acc_hb, $t7.16b // GHASH block 4k+3 - high + cmp $rounds, #12 // setup flags for AES-128/192/256 check + fmov $ctr_t1d, $input_l1 // AES block 4k+5 - mov low + ldp $input_l0, $input_h0, [$input_ptr, #0] // AES block 4k+4 - load plaintext + b.lt .Lenc_main_loop_continue // branch if AES-128 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 9 + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 9 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 10 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 10 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 10 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 10 + b.eq .Lenc_main_loop_continue // branch if AES-192 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 11 + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 11 + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 11 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 11 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 12 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 12 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 12 + +.Lenc_main_loop_continue: + shl $mod_constantd, $mod_constantd, #56 // mod_constant + eor $acc_lb, $acc_lb, $t8.16b // GHASH block 4k+3 - low + eor $acc_mb, $acc_mb, $t9.16b // GHASH block 4k+3 - mid + add $rctr32w, $rctr32w, #1 // CTR block 4k+3 + eor $t9.16b, $acc_lb, $acc_hb // MODULO - karatsuba tidy up + add $input_ptr, $input_ptr, #64 // AES input_ptr update + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d // MODULO - top 64b align with mid + rev $ctr32w, $rctr32w // CTR block 4k+8 + ext $acc_hb, $acc_hb, $acc_hb, #8 // MODULO - other top alignment + eor $input_l0, $input_l0, $rkN_l // AES block 4k+4 - round N low + eor $acc_mb, $acc_mb, $t9.16b // MODULO - karatsuba tidy up + eor $input_h0, $input_h0, $rkN_h // AES block 4k+4 - round N high + fmov $ctr_t0d, $input_l0 // AES block 4k+4 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+8 + eor $mod_t.16b, $acc_hb, $mod_t.16b // MODULO - fold into mid + eor $input_h1, $input_h1, $rkN_h // AES block 4k+5 - round N high + eor $input_h3, $input_h3, $rkN_h // AES block 4k+7 - round N high + add $rctr32w, $rctr32w, #1 // CTR block 4k+8 + aese $ctr0b, $rkNm1 // AES block 4k+4 - round N-1 + fmov $ctr_t0.d[1], $input_h0 // AES block 4k+4 - mov high + eor $acc_mb, $acc_mb, $mod_t.16b // MODULO - fold into mid + fmov $ctr_t3d, $input_l3 // AES block 4k+7 - mov low + aese $ctr1b, $rkNm1 // AES block 4k+5 - round N-1 + fmov $ctr_t1.d[1], $input_h1 // AES block 4k+5 - mov high + fmov $ctr_t2d, $input_l2 // AES block 4k+6 - mov low + cmp $input_ptr, $main_end_input_ptr // LOOP CONTROL + fmov $ctr_t2.d[1], $input_h2 // AES block 4k+6 - mov high + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d // MODULO - mid 64b align with low + eor $res0b, $ctr_t0b, $ctr0b // AES block 4k+4 - result + fmov $ctr0d, $ctr96_b64x // CTR block 4k+8 + fmov $ctr0.d[1], $ctr32x // CTR block 4k+8 + rev $ctr32w, $rctr32w // CTR block 4k+9 + add $rctr32w, $rctr32w, #1 // CTR block 4k+9 + eor $res1b, $ctr_t1b, $ctr1b // AES block 4k+5 - result + fmov $ctr1d, $ctr96_b64x // CTR block 4k+9 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+9 + fmov $ctr1.d[1], $ctr32x // CTR block 4k+9 + aese $ctr2b, $rkNm1 // AES block 4k+6 - round N-1 + rev $ctr32w, $rctr32w // CTR block 4k+10 + st1 { $res0b}, [$output_ptr], #16 // AES block 4k+4 - store result + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+10 + eor $acc_lb, $acc_lb, $acc_hb // MODULO - fold into low + fmov $ctr_t3.d[1], $input_h3 // AES block 4k+7 - mov high + ext $acc_mb, $acc_mb, $acc_mb, #8 // MODULO - other mid alignment + st1 { $res1b}, [$output_ptr], #16 // AES block 4k+5 - store result + add $rctr32w, $rctr32w, #1 // CTR block 4k+10 + aese $ctr3b, $rkNm1 // AES block 4k+7 - round N-1 + eor $res2b, $ctr_t2b, $ctr2b // AES block 4k+6 - result + fmov $ctr2d, $ctr96_b64x // CTR block 4k+10 + st1 { $res2b}, [$output_ptr], #16 // AES block 4k+6 - store result + fmov $ctr2.d[1], $ctr32x // CTR block 4k+10 + rev $ctr32w, $rctr32w // CTR block 4k+11 + eor $acc_lb, $acc_lb, $acc_mb // MODULO - fold into low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+11 + eor $res3b, $ctr_t3b, $ctr3b // AES block 4k+7 - result + st1 { $res3b}, [$output_ptr], #16 // AES block 4k+7 - store result + b.lt .Lenc_main_loop + +.Lenc_prepretail: // PREPRETAIL + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 0 + rev64 $res2b, $res2b // GHASH block 4k+2 (t0, t1, and t2 free) + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 0 + fmov $ctr3d, $ctr96_b64x // CTR block 4k+3 + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 0 + rev64 $res0b, $res0b // GHASH block 4k (only t0 is free) + fmov $ctr3.d[1], $ctr32x // CTR block 4k+3 + ext $acc_lb, $acc_lb, $acc_lb, #8 // PRE 0 + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 1 + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 1 + eor $res0b, $res0b, $acc_lb // PRE 1 + rev64 $res1b, $res1b // GHASH block 4k+1 (t0 and t1 free) + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 2 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 0 + mov $acc_md, $h34k.d[1] // GHASH block 4k - mid + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 1 + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH block 4k - low + mov $t0d, $res0.d[1] // GHASH block 4k - mid + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH block 4k - high + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 3 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b // GHASH block 4k - mid + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 2 + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 1 + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 3 + pmull $acc_m.1q, $t0.1d, $acc_m.1d // GHASH block 4k - mid + pmull2 $t1.1q, $res1.2d, $h3.2d // GHASH block 4k+1 - high + pmull $t2.1q, $res1.1d, $h3.1d // GHASH block 4k+1 - low + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 2 + eor $acc_hb, $acc_hb, $t1.16b // GHASH block 4k+1 - high + mov $t3d, $res1.d[1] // GHASH block 4k+1 - mid + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 3 + eor $acc_lb, $acc_lb, $t2.16b // GHASH block 4k+1 - low + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 3 + eor $t3.8b, $t3.8b, $res1.8b // GHASH block 4k+1 - mid + mov $t6d, $res2.d[1] // GHASH block 4k+2 - mid + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 4 + rev64 $res3b, $res3b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 4 + pmull $t3.1q, $t3.1d, $h34k.1d // GHASH block 4k+1 - mid + eor $t6.8b, $t6.8b, $res2.8b // GHASH block 4k+2 - mid + add $rctr32w, $rctr32w, #1 // CTR block 4k+3 + pmull $t5.1q, $res2.1d, $h2.1d // GHASH block 4k+2 - low + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 5 + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 4 + eor $acc_mb, $acc_mb, $t3.16b // GHASH block 4k+1 - mid + pmull2 $t4.1q, $res2.2d, $h2.2d // GHASH block 4k+2 - high + eor $acc_lb, $acc_lb, $t5.16b // GHASH block 4k+2 - low + ins $t6.d[1], $t6.d[0] // GHASH block 4k+2 - mid + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 5 + eor $acc_hb, $acc_hb, $t4.16b // GHASH block 4k+2 - high + mov $t9d, $res3.d[1] // GHASH block 4k+3 - mid + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 4 + pmull2 $t6.1q, $t6.2d, $h12k.2d // GHASH block 4k+2 - mid + eor $t9.8b, $t9.8b, $res3.8b // GHASH block 4k+3 - mid + pmull2 $t7.1q, $res3.2d, $h1.2d // GHASH block 4k+3 - high + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 5 + pmull $t9.1q, $t9.1d, $h12k.1d // GHASH block 4k+3 - mid + eor $acc_mb, $acc_mb, $t6.16b // GHASH block 4k+2 - mid + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 5 + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 6 + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 6 + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 6 + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 7 + eor $acc_hb, $acc_hb, $t7.16b // GHASH block 4k+3 - high + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 7 + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 // mod_constant + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 8 + eor $acc_mb, $acc_mb, $t9.16b // GHASH block 4k+3 - mid + pmull $t8.1q, $res3.1d, $h1.1d // GHASH block 4k+3 - low + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 8 + cmp $rounds, #12 // setup flags for AES-128/192/256 check + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 8 + eor $acc_lb, $acc_lb, $t8.16b // GHASH block 4k+3 - low + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 7 + eor $acc_mb, $acc_mb, $acc_hb // karatsuba tidy up + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 8 + pmull $t1.1q, $acc_h.1d, $mod_constant.1d + ext $acc_hb, $acc_hb, $acc_hb, #8 + eor $acc_mb, $acc_mb, $acc_lb + b.lt .Lenc_finish_prepretail // branch if AES-128 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 9 + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 9 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 10 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 10 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 10 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 10 + b.eq .Lenc_finish_prepretail // branch if AES-192 + + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 11 + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 11 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 11 + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 11 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 12 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 12 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 12 + +.Lenc_finish_prepretail: + eor $acc_mb, $acc_mb, $t1.16b + eor $acc_mb, $acc_mb, $acc_hb + pmull $t1.1q, $acc_m.1d, $mod_constant.1d + ext $acc_mb, $acc_mb, $acc_mb, #8 + aese $ctr1b, $rkNm1 // AES block 4k+5 - round N-1 + eor $acc_lb, $acc_lb, $t1.16b + aese $ctr3b, $rkNm1 // AES block 4k+7 - round N-1 + aese $ctr0b, $rkNm1 // AES block 4k+4 - round N-1 + aese $ctr2b, $rkNm1 // AES block 4k+6 - round N-1 + eor $acc_lb, $acc_lb, $acc_mb + +.Lenc_tail: // TAIL + ext $t0.16b, $acc_lb, $acc_lb, #8 // prepare final partial tag + sub $main_end_input_ptr, $end_input_ptr, $input_ptr // main_end_input_ptr is number of bytes left to process + ldp $input_l0, $input_h0, [$input_ptr], #16 // AES block 4k+4 - load plaintext + eor $input_l0, $input_l0, $rkN_l // AES block 4k+4 - round N low + eor $input_h0, $input_h0, $rkN_h // AES block 4k+4 - round N high + cmp $main_end_input_ptr, #48 + fmov $ctr_t0d, $input_l0 // AES block 4k+4 - mov low + fmov $ctr_t0.d[1], $input_h0 // AES block 4k+4 - mov high + eor $res1b, $ctr_t0b, $ctr0b // AES block 4k+4 - result + b.gt .Lenc_blocks_more_than_3 + cmp $main_end_input_ptr, #32 + mov $ctr3b, $ctr2b + movi $acc_l.8b, #0 + movi $acc_h.8b, #0 + sub $rctr32w, $rctr32w, #1 + mov $ctr2b, $ctr1b + movi $acc_m.8b, #0 + b.gt .Lenc_blocks_more_than_2 + mov $ctr3b, $ctr1b + sub $rctr32w, $rctr32w, #1 + cmp $main_end_input_ptr, #16 + b.gt .Lenc_blocks_more_than_1 + sub $rctr32w, $rctr32w, #1 + b .Lenc_blocks_less_than_1 +.Lenc_blocks_more_than_3: // blocks left > 3 + st1 { $res1b}, [$output_ptr], #16 // AES final-3 block - store result + ldp $input_l0, $input_h0, [$input_ptr], #16 // AES final-2 block - load input low & high + rev64 $res0b, $res1b // GHASH final-3 block + eor $input_l0, $input_l0, $rkN_l // AES final-2 block - round N low + eor $res0b, $res0b, $t0.16b // feed in partial tag + eor $input_h0, $input_h0, $rkN_h // AES final-2 block - round N high + mov $rk4d, $res0.d[1] // GHASH final-3 block - mid + fmov $res1d, $input_l0 // AES final-2 block - mov low + fmov $res1.d[1], $input_h0 // AES final-2 block - mov high + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-3 block - mid + movi $t0.8b, #0 // suppress further partial tag feed in + mov $acc_md, $h34k.d[1] // GHASH final-3 block - mid + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH final-3 block - low + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH final-3 block - high + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d // GHASH final-3 block - mid + eor $res1b, $res1b, $ctr1b // AES final-2 block - result +.Lenc_blocks_more_than_2: // blocks left > 2 + st1 { $res1b}, [$output_ptr], #16 // AES final-2 block - store result + ldp $input_l0, $input_h0, [$input_ptr], #16 // AES final-1 block - load input low & high + rev64 $res0b, $res1b // GHASH final-2 block + eor $input_l0, $input_l0, $rkN_l // AES final-1 block - round N low + eor $res0b, $res0b, $t0.16b // feed in partial tag + fmov $res1d, $input_l0 // AES final-1 block - mov low + eor $input_h0, $input_h0, $rkN_h // AES final-1 block - round N high + fmov $res1.d[1], $input_h0 // AES final-1 block - mov high + movi $t0.8b, #0 // suppress further partial tag feed in + pmull2 $rk2q1, $res0.2d, $h3.2d // GHASH final-2 block - high + mov $rk4d, $res0.d[1] // GHASH final-2 block - mid + pmull $rk3q1, $res0.1d, $h3.1d // GHASH final-2 block - low + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-2 block - mid + eor $res1b, $res1b, $ctr2b // AES final-1 block - result + eor $acc_hb, $acc_hb, $rk2 // GHASH final-2 block - high + pmull $rk4v.1q, $rk4v.1d, $h34k.1d // GHASH final-2 block - mid + eor $acc_lb, $acc_lb, $rk3 // GHASH final-2 block - low + eor $acc_mb, $acc_mb, $rk4v.16b // GHASH final-2 block - mid +.Lenc_blocks_more_than_1: // blocks left > 1 + st1 { $res1b}, [$output_ptr], #16 // AES final-1 block - store result + rev64 $res0b, $res1b // GHASH final-1 block + ldp $input_l0, $input_h0, [$input_ptr], #16 // AES final block - load input low & high + eor $res0b, $res0b, $t0.16b // feed in partial tag + movi $t0.8b, #0 // suppress further partial tag feed in + eor $input_l0, $input_l0, $rkN_l // AES final block - round N low + mov $rk4d, $res0.d[1] // GHASH final-1 block - mid + pmull2 $rk2q1, $res0.2d, $h2.2d // GHASH final-1 block - high + eor $input_h0, $input_h0, $rkN_h // AES final block - round N high + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-1 block - mid + eor $acc_hb, $acc_hb, $rk2 // GHASH final-1 block - high + ins $rk4v.d[1], $rk4v.d[0] // GHASH final-1 block - mid + fmov $res1d, $input_l0 // AES final block - mov low + fmov $res1.d[1], $input_h0 // AES final block - mov high + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d // GHASH final-1 block - mid + pmull $rk3q1, $res0.1d, $h2.1d // GHASH final-1 block - low + eor $res1b, $res1b, $ctr3b // AES final block - result + eor $acc_mb, $acc_mb, $rk4v.16b // GHASH final-1 block - mid + eor $acc_lb, $acc_lb, $rk3 // GHASH final-1 block - low +.Lenc_blocks_less_than_1: // blocks left <= 1 + and $bit_length, $bit_length, #127 // bit_length %= 128 + mvn $rkN_l, xzr // rkN_l = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 // bit_length -= 128 + neg $bit_length, $bit_length // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { $rk0}, [$output_ptr] // load existing bytes where the possibly partial last block is to be stored + mvn $rkN_h, xzr // rkN_h = 0xffffffffffffffff + and $bit_length, $bit_length, #127 // bit_length %= 128 + lsr $rkN_h, $rkN_h, $bit_length // rkN_h is mask for top 64b of last block + cmp $bit_length, #64 + csel $input_l0, $rkN_l, $rkN_h, lt + csel $input_h0, $rkN_h, xzr, lt + fmov $ctr0d, $input_l0 // ctr0b is mask for last block + fmov $ctr0.d[1], $input_h0 + and $res1b, $res1b, $ctr0b // possibly partial last block has zeroes in highest bits + rev64 $res0b, $res1b // GHASH final block + eor $res0b, $res0b, $t0.16b // feed in partial tag + bif $res1b, $rk0, $ctr0b // insert existing bytes in top end of result before storing + pmull2 $rk2q1, $res0.2d, $h1.2d // GHASH final block - high + mov $t0d, $res0.d[1] // GHASH final block - mid + rev $ctr32w, $rctr32w + pmull $rk3q1, $res0.1d, $h1.1d // GHASH final block - low + eor $acc_hb, $acc_hb, $rk2 // GHASH final block - high + eor $t0.8b, $t0.8b, $res0.8b // GHASH final block - mid + pmull $t0.1q, $t0.1d, $h12k.1d // GHASH final block - mid + eor $acc_lb, $acc_lb, $rk3 // GHASH final block - low + eor $acc_mb, $acc_mb, $t0.16b // GHASH final block - mid + movi $mod_constant.8b, #0xc2 + eor $t9.16b, $acc_lb, $acc_hb // MODULO - karatsuba tidy up + shl $mod_constantd, $mod_constantd, #56 // mod_constant + eor $acc_mb, $acc_mb, $t9.16b // MODULO - karatsuba tidy up + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d // MODULO - top 64b align with mid + ext $acc_hb, $acc_hb, $acc_hb, #8 // MODULO - other top alignment + eor $acc_mb, $acc_mb, $mod_t.16b // MODULO - fold into mid + eor $acc_mb, $acc_mb, $acc_hb // MODULO - fold into mid + pmull $acc_h.1q, $acc_m.1d, $mod_constant.1d // MODULO - mid 64b align with low + ext $acc_mb, $acc_mb, $acc_mb, #8 // MODULO - other mid alignment + str $ctr32w, [$counter, #12] // store the updated counter + st1 { $res1b}, [$output_ptr] // store all 16B + eor $acc_lb, $acc_lb, $acc_hb // MODULO - fold into low + eor $acc_lb, $acc_lb, $acc_mb // MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_enc_kernel,.-aes_gcm_enc_kernel +___ + +{ +my $t8="v4"; +my $t8d="d4"; +my $t9="v6"; +my $t9d="d6"; +################################################################################ +# size_t aes_gcm_dec_kernel(const uint8_t *in, +# size_t len_bits, +# uint8_t *out, +# u64 *Xi, +# uint8_t ivec[16], +# const void *key); +# +$code.=<<___; +.global aes_gcm_dec_kernel +.type aes_gcm_dec_kernel,%function +.align 4 +aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov $counter, x4 + mov $cc, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr $roundsw, [$cc, #240] + add $input_l1, $cc, $rounds, lsl #4 // borrow input_l1 for last key + ldp $rkN_l, $rkN_h, [$input_l1] // load round N keys + ldr $rkNm1q, [$input_l1, #-16] // load round N-1 keys + lsr $main_end_input_ptr, $bit_length, #3 // byte_len + mov $len, $main_end_input_ptr + ldp $ctr96_b64x, $ctr96_t32x, [$counter] // ctr96_b64, ctr96_t32 + ldr $rk8q, [$cc, #128] // load rk8 + sub $main_end_input_ptr, $main_end_input_ptr, #1 // byte_len - 1 + ldr $rk7q, [$cc, #112] // load rk7 + and $main_end_input_ptr, $main_end_input_ptr, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add $end_input_ptr, $input_ptr, $bit_length, lsr #3 // end_input_ptr + ldr $rk6q, [$cc, #96] // load rk6 + lsr $rctr32x, $ctr96_t32x, #32 + ldr $rk5q, [$cc, #80] // load rk5 + orr $ctr96_t32w, $ctr96_t32w, $ctr96_t32w + ldr $rk3q, [$cc, #48] // load rk3 + add $main_end_input_ptr, $main_end_input_ptr, $input_ptr + rev $rctr32w, $rctr32w // rev_ctr32 + add $rctr32w, $rctr32w, #1 // increment rev_ctr32 + fmov $ctr3d, $ctr96_b64x // CTR block 3 + rev $ctr32w, $rctr32w // CTR block 1 + add $rctr32w, $rctr32w, #1 // CTR block 1 + fmov $ctr1d, $ctr96_b64x // CTR block 1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 1 + ld1 { $ctr0b}, [$counter] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov $ctr1.d[1], $ctr32x // CTR block 1 + rev $ctr32w, $rctr32w // CTR block 2 + add $rctr32w, $rctr32w, #1 // CTR block 2 + fmov $ctr2d, $ctr96_b64x // CTR block 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 2 + fmov $ctr2.d[1], $ctr32x // CTR block 2 + rev $ctr32w, $rctr32w // CTR block 3 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 3 + ldr $rk0q, [$cc, #0] // load rk0 + fmov $ctr3.d[1], $ctr32x // CTR block 3 + add $rctr32w, $rctr32w, #1 // CTR block 3 + ldr $rk4q, [$cc, #64] // load rk4 + ldr $rk1q, [$cc, #16] // load rk1 + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 0 + ldr $h3q, [$Htable, #48] // load h3l | h3h + ext $h3b, $h3b, $h3b, #8 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 0 + ldr $h4q, [$Htable, #80] // load h4l | h4h + ext $h4b, $h4b, $h4b, #8 + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 0 + ldr $h2q, [$Htable, #32] // load h2l | h2h + ext $h2b, $h2b, $h2b, #8 + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 0 + ldr $rk2q, [$cc, #32] // load rk2 + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 1 + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 1 + ld1 { $acc_lb}, [$current_tag] + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 1 + ldr $rk9q, [$cc, #144] // load rk9 + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 1 + ldr $rk12q, [$cc, #192] // load rk12 + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 2 + ldr $h1q, [$Htable] // load h1l | h1h + ext $h1b, $h1b, $h1b, #8 + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 2 + ldr $rk10q, [$cc, #160] // load rk10 + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 2 + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 3 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 2 + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 3 + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 4 + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 3 + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 3 + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 4 + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 4 + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 4 + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 5 + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 5 + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 5 + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 5 + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 6 + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 6 + cmp $rounds, #12 // setup flags for AES-128/192/256 check + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 6 + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 6 + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 7 + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 7 + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 7 + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 8 + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 7 + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 8 + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 8 + ldr $rk11q, [$cc, #176] // load rk11 + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 8 + b.lt .Ldec_finish_first_blocks // branch if AES-128 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 9 + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 9 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 10 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 10 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 10 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 10 + b.eq .Ldec_finish_first_blocks // branch if AES-192 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 11 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 11 + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 11 + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 11 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 1 - round 12 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 0 - round 12 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 2 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 3 - round 12 + +.Ldec_finish_first_blocks: + cmp $input_ptr, $main_end_input_ptr // check if we have <= 4 blocks + trn1 $acc_h.2d, $h3.2d, $h4.2d // h4h | h3h + trn2 $h34k.2d, $h3.2d, $h4.2d // h4l | h3l + trn1 $t0.2d, $h1.2d, $h2.2d // h2h | h1h + trn2 $h12k.2d, $h1.2d, $h2.2d // h2l | h1l + eor $h34k.16b, $h34k.16b, $acc_h.16b // h4k | h3k + aese $ctr1b, $rkNm1 // AES block 1 - round N-1 + aese $ctr2b, $rkNm1 // AES block 2 - round N-1 + eor $h12k.16b, $h12k.16b, $t0.16b // h2k | h1k + aese $ctr3b, $rkNm1 // AES block 3 - round N-1 + aese $ctr0b, $rkNm1 // AES block 0 - round N-1 + b.ge .Ldec_tail // handle tail + + ldr $res0q, [$input_ptr, #0] // AES block 0 - load ciphertext + ldr $res1q, [$input_ptr, #16] // AES block 1 - load ciphertext + rev $ctr32w, $rctr32w // CTR block 4 + eor $ctr0b, $res0b, $ctr0b // AES block 0 - result + eor $ctr1b, $res1b, $ctr1b // AES block 1 - result + rev64 $res1b, $res1b // GHASH block 1 + ldr $res3q, [$input_ptr, #48] // AES block 3 - load ciphertext + mov $output_h0, $ctr0.d[1] // AES block 0 - mov high + mov $output_l0, $ctr0.d[0] // AES block 0 - mov low + rev64 $res0b, $res0b // GHASH block 0 + add $rctr32w, $rctr32w, #1 // CTR block 4 + fmov $ctr0d, $ctr96_b64x // CTR block 4 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4 + fmov $ctr0.d[1], $ctr32x // CTR block 4 + rev $ctr32w, $rctr32w // CTR block 5 + add $rctr32w, $rctr32w, #1 // CTR block 5 + mov $output_l1, $ctr1.d[0] // AES block 1 - mov low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 5 + mov $output_h1, $ctr1.d[1] // AES block 1 - mov high + eor $output_h0, $output_h0, $rkN_h // AES block 0 - round N high + eor $output_l0, $output_l0, $rkN_l // AES block 0 - round N low + stp $output_l0, $output_h0, [$output_ptr], #16 // AES block 0 - store result + fmov $ctr1d, $ctr96_b64x // CTR block 5 + ldr $res2q, [$input_ptr, #32] // AES block 2 - load ciphertext + add $input_ptr, $input_ptr, #64 // AES input_ptr update + fmov $ctr1.d[1], $ctr32x // CTR block 5 + rev $ctr32w, $rctr32w // CTR block 6 + add $rctr32w, $rctr32w, #1 // CTR block 6 + eor $output_l1, $output_l1, $rkN_l // AES block 1 - round N low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 6 + eor $output_h1, $output_h1, $rkN_h // AES block 1 - round N high + stp $output_l1, $output_h1, [$output_ptr], #16 // AES block 1 - store result + eor $ctr2b, $res2b, $ctr2b // AES block 2 - result + cmp $input_ptr, $main_end_input_ptr // check if we have <= 8 blocks + b.ge .Ldec_prepretail // do prepretail + +.Ldec_main_loop: // main loop start + mov $output_l2, $ctr2.d[0] // AES block 4k+2 - mov low + ext $acc_lb, $acc_lb, $acc_lb, #8 // PRE 0 + eor $ctr3b, $res3b, $ctr3b // AES block 4k+3 - result + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] // AES block 4k+2 - mov high + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x // CTR block 4k+6 + fmov $ctr2.d[1], $ctr32x // CTR block 4k+6 + eor $res0b, $res0b, $acc_lb // PRE 1 + rev $ctr32w, $rctr32w // CTR block 4k+7 + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 1 + mov $output_h3, $ctr3.d[1] // AES block 4k+3 - mov high + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 1 + mov $output_l3, $ctr3.d[0] // AES block 4k+3 - mov low + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH block 4k - high + mov $t0d, $res0.d[1] // GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x // CTR block 4k+7 + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+7 + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 0 + fmov $ctr3.d[1], $ctr32x // CTR block 4k+7 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 2 + eor $t0.8b, $t0.8b, $res0.8b // GHASH block 4k - mid + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 3 + eor $output_h2, $output_h2, $rkN_h // AES block 4k+2 - round N high + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 1 + mov $acc_md, $h34k.d[1] // GHASH block 4k - mid + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 3 + rev64 $res2b, $res2b // GHASH block 4k+2 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 0 + eor $output_l2, $output_l2, $rkN_l // AES block 4k+2 - round N low + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 2 + stp $output_l2, $output_h2, [$output_ptr], #16 // AES block 4k+2 - store result + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH block 4k - low + pmull2 $t1.1q, $res1.2d, $h3.2d // GHASH block 4k+1 - high + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 3 + rev64 $res3b, $res3b // GHASH block 4k+3 + pmull $acc_m.1q, $t0.1d, $acc_m.1d // GHASH block 4k - mid + eor $output_l3, $output_l3, $rkN_l // AES block 4k+3 - round N low + pmull $t2.1q, $res1.1d, $h3.1d // GHASH block 4k+1 - low + eor $output_h3, $output_h3, $rkN_h // AES block 4k+3 - round N high + eor $acc_hb, $acc_hb, $t1.16b // GHASH block 4k+1 - high + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 4 + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] // GHASH block 4k+1 - mid + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 4 + eor $acc_lb, $acc_lb, $t2.16b // GHASH block 4k+1 - low + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 5 + add $rctr32w, $rctr32w, #1 // CTR block 4k+7 + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 2 + mov $t6d, $res2.d[1] // GHASH block 4k+2 - mid + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 4 + eor $t3.8b, $t3.8b, $res1.8b // GHASH block 4k+1 - mid + pmull $t5.1q, $res2.1d, $h2.1d // GHASH block 4k+2 - low + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b // GHASH block 4k+2 - mid + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 5 + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b // GHASH block 4k+2 - low + pmull $t3.1q, $t3.1d, $h34k.1d // GHASH block 4k+1 - mid + rev $ctr32w, $rctr32w // CTR block 4k+8 + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 6 + ins $t6.d[1], $t6.d[0] // GHASH block 4k+2 - mid + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 6 + add $rctr32w, $rctr32w, #1 // CTR block 4k+8 + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 4 + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 7 + eor $acc_mb, $acc_mb, $t3.16b // GHASH block 4k+1 - mid + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 7 + pmull2 $t4.1q, $res2.2d, $h2.2d // GHASH block 4k+2 - high + mov $t9d, $res3.d[1] // GHASH block 4k+3 - mid + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 5 + pmull2 $t6.1q, $t6.2d, $h12k.2d // GHASH block 4k+2 - mid + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 8 + eor $acc_hb, $acc_hb, $t4.16b // GHASH block 4k+2 - high + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 6 + pmull $t8.1q, $res3.1d, $h1.1d // GHASH block 4k+3 - low + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+8 + eor $acc_mb, $acc_mb, $t6.16b // GHASH block 4k+2 - mid + pmull2 $t7.1q, $res3.2d, $h1.2d // GHASH block 4k+3 - high + cmp $rounds, #12 // setup flags for AES-128/192/256 check + eor $t9.8b, $t9.8b, $res3.8b // GHASH block 4k+3 - mid + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 8 + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 6 + eor $acc_hb, $acc_hb, $t7.16b // GHASH block 4k+3 - high + pmull $t9.1q, $t9.1d, $h12k.1d // GHASH block 4k+3 - mid + movi $mod_constant.8b, #0xc2 + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 7 + eor $acc_lb, $acc_lb, $t8.16b // GHASH block 4k+3 - low + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 7 + shl $mod_constantd, $mod_constantd, #56 // mod_constant + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 8 + eor $acc_mb, $acc_mb, $t9.16b // GHASH block 4k+3 - mid + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 8 + b.lt .Ldec_main_loop_continue // branch if AES-128 + + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 9 + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 9 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 10 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 10 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 10 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 10 + b.eq .Ldec_main_loop_continue // branch if AES-192 + + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 11 + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 11 + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 11 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 11 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 12 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 12 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 12 + +.Ldec_main_loop_continue: + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d // MODULO - top 64b align with mid + eor $t9.16b, $acc_lb, $acc_hb // MODULO - karatsuba tidy up + ldr $res0q, [$input_ptr, #0] // AES block 4k+4 - load ciphertext + aese $ctr0b, $rkNm1 // AES block 4k+4 - round N-1 + ext $acc_hb, $acc_hb, $acc_hb, #8 // MODULO - other top alignment + eor $acc_mb, $acc_mb, $t9.16b // MODULO - karatsuba tidy up + ldr $res1q, [$input_ptr, #16] // AES block 4k+5 - load ciphertext + eor $ctr0b, $res0b, $ctr0b // AES block 4k+4 - result + stp $output_l3, $output_h3, [$output_ptr], #16 // AES block 4k+3 - store result + eor $acc_mb, $acc_mb, $mod_t.16b // MODULO - fold into mid + ldr $res3q, [$input_ptr, #48] // AES block 4k+7 - load ciphertext + ldr $res2q, [$input_ptr, #32] // AES block 4k+6 - load ciphertext + mov $output_h0, $ctr0.d[1] // AES block 4k+4 - mov high + eor $acc_mb, $acc_mb, $acc_hb // MODULO - fold into mid + aese $ctr1b, $rkNm1 // AES block 4k+5 - round N-1 + add $input_ptr, $input_ptr, #64 // AES input_ptr update + mov $output_l0, $ctr0.d[0] // AES block 4k+4 - mov low + fmov $ctr0d, $ctr96_b64x // CTR block 4k+8 + fmov $ctr0.d[1], $ctr32x // CTR block 4k+8 + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d // MODULO - mid 64b align with low + eor $ctr1b, $res1b, $ctr1b // AES block 4k+5 - result + rev $ctr32w, $rctr32w // CTR block 4k+9 + aese $ctr2b, $rkNm1 // AES block 4k+6 - round N-1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+9 + cmp $input_ptr, $main_end_input_ptr // LOOP CONTROL + add $rctr32w, $rctr32w, #1 // CTR block 4k+9 + eor $output_l0, $output_l0, $rkN_l // AES block 4k+4 - round N low + eor $output_h0, $output_h0, $rkN_h // AES block 4k+4 - round N high + mov $output_h1, $ctr1.d[1] // AES block 4k+5 - mov high + eor $ctr2b, $res2b, $ctr2b // AES block 4k+6 - result + eor $acc_lb, $acc_lb, $mod_constant.16b // MODULO - fold into low + mov $output_l1, $ctr1.d[0] // AES block 4k+5 - mov low + fmov $ctr1d, $ctr96_b64x // CTR block 4k+9 + ext $acc_mb, $acc_mb, $acc_mb, #8 // MODULO - other mid alignment + fmov $ctr1.d[1], $ctr32x // CTR block 4k+9 + rev $ctr32w, $rctr32w // CTR block 4k+10 + add $rctr32w, $rctr32w, #1 // CTR block 4k+10 + aese $ctr3b, $rkNm1 // AES block 4k+7 - round N-1 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+10 + rev64 $res1b, $res1b // GHASH block 4k+5 + eor $output_h1, $output_h1, $rkN_h // AES block 4k+5 - round N high + stp $output_l0, $output_h0, [$output_ptr], #16 // AES block 4k+4 - store result + eor $output_l1, $output_l1, $rkN_l // AES block 4k+5 - round N low + stp $output_l1, $output_h1, [$output_ptr], #16 // AES block 4k+5 - store result + rev64 $res0b, $res0b // GHASH block 4k+4 + eor $acc_lb, $acc_lb, $acc_mb // MODULO - fold into low + b.lt .Ldec_main_loop + +.Ldec_prepretail: // PREPRETAIL + ext $acc_lb, $acc_lb, $acc_lb, #8 // PRE 0 + mov $output_l2, $ctr2.d[0] // AES block 4k+2 - mov low + eor $ctr3b, $res3b, $ctr3b // AES block 4k+3 - result + aese $ctr0b, $rk0 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 0 + mov $output_h2, $ctr2.d[1] // AES block 4k+2 - mov high + aese $ctr1b, $rk0 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 0 + fmov $ctr2d, $ctr96_b64x // CTR block 4k+6 + fmov $ctr2.d[1], $ctr32x // CTR block 4k+6 + rev $ctr32w, $rctr32w // CTR block 4k+7 + eor $res0b, $res0b, $acc_lb // PRE 1 + rev64 $res2b, $res2b // GHASH block 4k+2 + orr $ctr32x, $ctr96_t32x, $ctr32x, lsl #32 // CTR block 4k+7 + mov $output_l3, $ctr3.d[0] // AES block 4k+3 - mov low + aese $ctr1b, $rk1 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 1 + mov $output_h3, $ctr3.d[1] // AES block 4k+3 - mov high + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH block 4k - low + mov $t0d, $res0.d[1] // GHASH block 4k - mid + fmov $ctr3d, $ctr96_b64x // CTR block 4k+7 + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH block 4k - high + fmov $ctr3.d[1], $ctr32x // CTR block 4k+7 + aese $ctr2b, $rk0 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 0 + mov $acc_md, $h34k.d[1] // GHASH block 4k - mid + aese $ctr0b, $rk1 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 1 + eor $t0.8b, $t0.8b, $res0.8b // GHASH block 4k - mid + pmull2 $t1.1q, $res1.2d, $h3.2d // GHASH block 4k+1 - high + aese $ctr2b, $rk1 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 1 + rev64 $res3b, $res3b // GHASH block 4k+3 + aese $ctr3b, $rk0 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 0 + pmull $acc_m.1q, $t0.1d, $acc_m.1d // GHASH block 4k - mid + eor $acc_hb, $acc_hb, $t1.16b // GHASH block 4k+1 - high + pmull $t2.1q, $res1.1d, $h3.1d // GHASH block 4k+1 - low + aese $ctr3b, $rk1 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 1 + mov $t3d, $res1.d[1] // GHASH block 4k+1 - mid + aese $ctr0b, $rk2 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 2 + aese $ctr1b, $rk2 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 2 + eor $acc_lb, $acc_lb, $t2.16b // GHASH block 4k+1 - low + aese $ctr2b, $rk2 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 2 + aese $ctr0b, $rk3 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 3 + mov $t6d, $res2.d[1] // GHASH block 4k+2 - mid + aese $ctr3b, $rk2 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 2 + eor $t3.8b, $t3.8b, $res1.8b // GHASH block 4k+1 - mid + pmull $t5.1q, $res2.1d, $h2.1d // GHASH block 4k+2 - low + aese $ctr0b, $rk4 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 4 + aese $ctr3b, $rk3 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 3 + eor $t6.8b, $t6.8b, $res2.8b // GHASH block 4k+2 - mid + pmull $t3.1q, $t3.1d, $h34k.1d // GHASH block 4k+1 - mid + aese $ctr0b, $rk5 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 5 + eor $acc_lb, $acc_lb, $t5.16b // GHASH block 4k+2 - low + aese $ctr3b, $rk4 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 4 + pmull2 $t7.1q, $res3.2d, $h1.2d // GHASH block 4k+3 - high + eor $acc_mb, $acc_mb, $t3.16b // GHASH block 4k+1 - mid + pmull2 $t4.1q, $res2.2d, $h2.2d // GHASH block 4k+2 - high + aese $ctr3b, $rk5 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 5 + ins $t6.d[1], $t6.d[0] // GHASH block 4k+2 - mid + aese $ctr2b, $rk3 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 3 + aese $ctr1b, $rk3 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 3 + eor $acc_hb, $acc_hb, $t4.16b // GHASH block 4k+2 - high + pmull $t8.1q, $res3.1d, $h1.1d // GHASH block 4k+3 - low + aese $ctr2b, $rk4 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 4 + mov $t9d, $res3.d[1] // GHASH block 4k+3 - mid + aese $ctr1b, $rk4 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 4 + pmull2 $t6.1q, $t6.2d, $h12k.2d // GHASH block 4k+2 - mid + aese $ctr2b, $rk5 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 5 + eor $t9.8b, $t9.8b, $res3.8b // GHASH block 4k+3 - mid + aese $ctr1b, $rk5 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 5 + aese $ctr3b, $rk6 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 6 + eor $acc_mb, $acc_mb, $t6.16b // GHASH block 4k+2 - mid + aese $ctr2b, $rk6 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 6 + aese $ctr0b, $rk6 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 6 + movi $mod_constant.8b, #0xc2 + aese $ctr1b, $rk6 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 6 + eor $acc_lb, $acc_lb, $t8.16b // GHASH block 4k+3 - low + pmull $t9.1q, $t9.1d, $h12k.1d // GHASH block 4k+3 - mid + aese $ctr3b, $rk7 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 7 + cmp $rounds, #12 // setup flags for AES-128/192/256 check + eor $acc_hb, $acc_hb, $t7.16b // GHASH block 4k+3 - high + aese $ctr1b, $rk7 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 7 + aese $ctr0b, $rk7 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 7 + eor $acc_mb, $acc_mb, $t9.16b // GHASH block 4k+3 - mid + aese $ctr3b, $rk8 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 8 + aese $ctr2b, $rk7 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 7 + eor $t9.16b, $acc_lb, $acc_hb // MODULO - karatsuba tidy up + aese $ctr1b, $rk8 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 8 + aese $ctr0b, $rk8 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 8 + shl $mod_constantd, $mod_constantd, #56 // mod_constant + aese $ctr2b, $rk8 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 8 + b.lt .Ldec_finish_prepretail // branch if AES-128 + + aese $ctr1b, $rk9 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 9 + aese $ctr2b, $rk9 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 9 + aese $ctr3b, $rk9 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 9 + aese $ctr0b, $rk9 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 9 + aese $ctr2b, $rk10 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 10 + aese $ctr3b, $rk10 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 10 + aese $ctr0b, $rk10 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 10 + aese $ctr1b, $rk10 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 10 + b.eq .Ldec_finish_prepretail // branch if AES-192 + + aese $ctr2b, $rk11 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 11 + aese $ctr0b, $rk11 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 11 + aese $ctr1b, $rk11 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 11 + aese $ctr2b, $rk12 \n aesmc $ctr2b, $ctr2b // AES block 4k+6 - round 12 + aese $ctr3b, $rk11 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 11 + aese $ctr1b, $rk12 \n aesmc $ctr1b, $ctr1b // AES block 4k+5 - round 12 + aese $ctr0b, $rk12 \n aesmc $ctr0b, $ctr0b // AES block 4k+4 - round 12 + aese $ctr3b, $rk12 \n aesmc $ctr3b, $ctr3b // AES block 4k+7 - round 12 + +.Ldec_finish_prepretail: + eor $acc_mb, $acc_mb, $t9.16b // MODULO - karatsuba tidy up + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d // MODULO - top 64b align with mid + ext $acc_hb, $acc_hb, $acc_hb, #8 // MODULO - other top alignment + eor $acc_mb, $acc_mb, $mod_t.16b // MODULO - fold into mid + eor $output_h2, $output_h2, $rkN_h // AES block 4k+2 - round N high + eor $output_l3, $output_l3, $rkN_l // AES block 4k+3 - round N low + eor $acc_mb, $acc_mb, $acc_hb // MODULO - fold into mid + add $rctr32w, $rctr32w, #1 // CTR block 4k+7 + eor $output_l2, $output_l2, $rkN_l // AES block 4k+2 - round N low + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d // MODULO - mid 64b align with low + eor $output_h3, $output_h3, $rkN_h // AES block 4k+3 - round N high + stp $output_l2, $output_h2, [$output_ptr], #16 // AES block 4k+2 - store result + ext $acc_mb, $acc_mb, $acc_mb, #8 // MODULO - other mid alignment + stp $output_l3, $output_h3, [$output_ptr], #16 // AES block 4k+3 - store result + + eor $acc_lb, $acc_lb, $mod_constant.16b // MODULO - fold into low + aese $ctr1b, $rkNm1 // AES block 4k+5 - round N-1 + aese $ctr0b, $rkNm1 // AES block 4k+4 - round N-1 + aese $ctr3b, $rkNm1 // AES block 4k+7 - round N-1 + aese $ctr2b, $rkNm1 // AES block 4k+6 - round N-1 + eor $acc_lb, $acc_lb, $acc_mb // MODULO - fold into low + +.Ldec_tail: // TAIL + sub $main_end_input_ptr, $end_input_ptr, $input_ptr // main_end_input_ptr is number of bytes left to process + ld1 { $res1b}, [$input_ptr], #16 // AES block 4k+4 - load ciphertext + eor $ctr0b, $res1b, $ctr0b // AES block 4k+4 - result + mov $output_l0, $ctr0.d[0] // AES block 4k+4 - mov low + mov $output_h0, $ctr0.d[1] // AES block 4k+4 - mov high + ext $t0.16b, $acc_lb, $acc_lb, #8 // prepare final partial tag + cmp $main_end_input_ptr, #48 + eor $output_l0, $output_l0, $rkN_l // AES block 4k+4 - round N low + eor $output_h0, $output_h0, $rkN_h // AES block 4k+4 - round N high + b.gt .Ldec_blocks_more_than_3 + sub $rctr32w, $rctr32w, #1 + mov $ctr3b, $ctr2b + movi $acc_m.8b, #0 + movi $acc_l.8b, #0 + cmp $main_end_input_ptr, #32 + movi $acc_h.8b, #0 + mov $ctr2b, $ctr1b + b.gt .Ldec_blocks_more_than_2 + sub $rctr32w, $rctr32w, #1 + mov $ctr3b, $ctr1b + cmp $main_end_input_ptr, #16 + b.gt .Ldec_blocks_more_than_1 + sub $rctr32w, $rctr32w, #1 + b .Ldec_blocks_less_than_1 +.Ldec_blocks_more_than_3: // blocks left > 3 + rev64 $res0b, $res1b // GHASH final-3 block + ld1 { $res1b}, [$input_ptr], #16 // AES final-2 block - load ciphertext + stp $output_l0, $output_h0, [$output_ptr], #16 // AES final-3 block - store result + mov $acc_md, $h34k.d[1] // GHASH final-3 block - mid + eor $res0b, $res0b, $t0.16b // feed in partial tag + eor $ctr0b, $res1b, $ctr1b // AES final-2 block - result + mov $rk4d, $res0.d[1] // GHASH final-3 block - mid + mov $output_l0, $ctr0.d[0] // AES final-2 block - mov low + mov $output_h0, $ctr0.d[1] // AES final-2 block - mov high + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-3 block - mid + movi $t0.8b, #0 // suppress further partial tag feed in + pmull2 $acc_h.1q, $res0.2d, $h4.2d // GHASH final-3 block - high + pmull $acc_m.1q, $rk4v.1d, $acc_m.1d // GHASH final-3 block - mid + eor $output_l0, $output_l0, $rkN_l // AES final-2 block - round N low + pmull $acc_l.1q, $res0.1d, $h4.1d // GHASH final-3 block - low + eor $output_h0, $output_h0, $rkN_h // AES final-2 block - round N high +.Ldec_blocks_more_than_2: // blocks left > 2 + rev64 $res0b, $res1b // GHASH final-2 block + ld1 { $res1b}, [$input_ptr], #16 // AES final-1 block - load ciphertext + eor $res0b, $res0b, $t0.16b // feed in partial tag + stp $output_l0, $output_h0, [$output_ptr], #16 // AES final-2 block - store result + eor $ctr0b, $res1b, $ctr2b // AES final-1 block - result + mov $rk4d, $res0.d[1] // GHASH final-2 block - mid + pmull $rk3q1, $res0.1d, $h3.1d // GHASH final-2 block - low + pmull2 $rk2q1, $res0.2d, $h3.2d // GHASH final-2 block - high + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-2 block - mid + mov $output_l0, $ctr0.d[0] // AES final-1 block - mov low + mov $output_h0, $ctr0.d[1] // AES final-1 block - mov high + eor $acc_lb, $acc_lb, $rk3 // GHASH final-2 block - low + movi $t0.8b, #0 // suppress further partial tag feed in + pmull $rk4v.1q, $rk4v.1d, $h34k.1d // GHASH final-2 block - mid + eor $acc_hb, $acc_hb, $rk2 // GHASH final-2 block - high + eor $output_l0, $output_l0, $rkN_l // AES final-1 block - round N low + eor $acc_mb, $acc_mb, $rk4v.16b // GHASH final-2 block - mid + eor $output_h0, $output_h0, $rkN_h // AES final-1 block - round N high +.Ldec_blocks_more_than_1: // blocks left > 1 + stp $output_l0, $output_h0, [$output_ptr], #16 // AES final-1 block - store result + rev64 $res0b, $res1b // GHASH final-1 block + ld1 { $res1b}, [$input_ptr], #16 // AES final block - load ciphertext + eor $res0b, $res0b, $t0.16b // feed in partial tag + movi $t0.8b, #0 // suppress further partial tag feed in + mov $rk4d, $res0.d[1] // GHASH final-1 block - mid + eor $ctr0b, $res1b, $ctr3b // AES final block - result + pmull2 $rk2q1, $res0.2d, $h2.2d // GHASH final-1 block - high + eor $rk4v.8b, $rk4v.8b, $res0.8b // GHASH final-1 block - mid + pmull $rk3q1, $res0.1d, $h2.1d // GHASH final-1 block - low + mov $output_l0, $ctr0.d[0] // AES final block - mov low + ins $rk4v.d[1], $rk4v.d[0] // GHASH final-1 block - mid + mov $output_h0, $ctr0.d[1] // AES final block - mov high + pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d // GHASH final-1 block - mid + eor $output_l0, $output_l0, $rkN_l // AES final block - round N low + eor $acc_lb, $acc_lb, $rk3 // GHASH final-1 block - low + eor $acc_hb, $acc_hb, $rk2 // GHASH final-1 block - high + eor $acc_mb, $acc_mb, $rk4v.16b // GHASH final-1 block - mid + eor $output_h0, $output_h0, $rkN_h // AES final block - round N high +.Ldec_blocks_less_than_1: // blocks left <= 1 + and $bit_length, $bit_length, #127 // bit_length %= 128 + mvn $rkN_h, xzr // rkN_h = 0xffffffffffffffff + sub $bit_length, $bit_length, #128 // bit_length -= 128 + mvn $rkN_l, xzr // rkN_l = 0xffffffffffffffff + ldp $end_input_ptr, $main_end_input_ptr, [$output_ptr] // load existing bytes we need to not overwrite + neg $bit_length, $bit_length // bit_length = 128 - #bits in input (in range [1,128]) + and $bit_length, $bit_length, #127 // bit_length %= 128 + lsr $rkN_h, $rkN_h, $bit_length // rkN_h is mask for top 64b of last block + cmp $bit_length, #64 + csel $ctr32x, $rkN_l, $rkN_h, lt + csel $ctr96_b64x, $rkN_h, xzr, lt + fmov $ctr0d, $ctr32x // ctr0b is mask for last block + and $output_l0, $output_l0, $ctr32x + mov $ctr0.d[1], $ctr96_b64x + bic $end_input_ptr, $end_input_ptr, $ctr32x // mask out low existing bytes + rev $ctr32w, $rctr32w + bic $main_end_input_ptr, $main_end_input_ptr, $ctr96_b64x // mask out high existing bytes + orr $output_l0, $output_l0, $end_input_ptr + and $output_h0, $output_h0, $ctr96_b64x + orr $output_h0, $output_h0, $main_end_input_ptr + and $res1b, $res1b, $ctr0b // possibly partial last block has zeroes in highest bits + rev64 $res0b, $res1b // GHASH final block + eor $res0b, $res0b, $t0.16b // feed in partial tag + pmull $rk3q1, $res0.1d, $h1.1d // GHASH final block - low + mov $t0d, $res0.d[1] // GHASH final block - mid + eor $t0.8b, $t0.8b, $res0.8b // GHASH final block - mid + pmull2 $rk2q1, $res0.2d, $h1.2d // GHASH final block - high + pmull $t0.1q, $t0.1d, $h12k.1d // GHASH final block - mid + eor $acc_hb, $acc_hb, $rk2 // GHASH final block - high + eor $acc_lb, $acc_lb, $rk3 // GHASH final block - low + eor $acc_mb, $acc_mb, $t0.16b // GHASH final block - mid + movi $mod_constant.8b, #0xc2 + eor $t9.16b, $acc_lb, $acc_hb // MODULO - karatsuba tidy up + shl $mod_constantd, $mod_constantd, #56 // mod_constant + eor $acc_mb, $acc_mb, $t9.16b // MODULO - karatsuba tidy up + pmull $mod_t.1q, $acc_h.1d, $mod_constant.1d // MODULO - top 64b align with mid + ext $acc_hb, $acc_hb, $acc_hb, #8 // MODULO - other top alignment + eor $acc_mb, $acc_mb, $mod_t.16b // MODULO - fold into mid + eor $acc_mb, $acc_mb, $acc_hb // MODULO - fold into mid + pmull $mod_constant.1q, $acc_m.1d, $mod_constant.1d // MODULO - mid 64b align with low + ext $acc_mb, $acc_mb, $acc_mb, #8 // MODULO - other mid alignment + eor $acc_lb, $acc_lb, $mod_constant.16b // MODULO - fold into low + stp $output_l0, $output_h0, [$output_ptr] + str $ctr32w, [$counter, #12] // store the updated counter + eor $acc_lb, $acc_lb, $acc_mb // MODULO - fold into low + ext $acc_lb, $acc_lb, $acc_lb, #8 + rev64 $acc_lb, $acc_lb + mov x0, $len + st1 { $acc_l.16b }, [$current_tag] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size aes_gcm_dec_kernel,.-aes_gcm_dec_kernel +___ +} +} + +$code.=<<___; +#endif +___ + +print $code; +close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-ssse3-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-ssse3-x86_64.pl index f7364739..00364f0b 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-ssse3-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-ssse3-x86_64.pl @@ -103,16 +103,15 @@ my $code = <<____; .align 16 gcm_gmult_ssse3: .cfi_startproc -.Lgmult_seh_begin: +.seh_startproc ____ $code .= <<____ if ($win64); subq \$40, %rsp -.Lgmult_seh_allocstack: +.seh_allocstack 40 movdqa %xmm6, (%rsp) -.Lgmult_seh_save_xmm6: +.seh_savexmm128 %xmm6, 0 movdqa %xmm10, 16(%rsp) -.Lgmult_seh_save_xmm10: -.Lgmult_seh_prolog_end: +.seh_savexmm128 %xmm10, 16 ____ $code .= <<____; movdqu ($Xi), %xmm0 @@ -230,8 +229,8 @@ $code .= <<____ if ($win64); ____ $code .= <<____; ret -.Lgmult_seh_end: .cfi_endproc +.seh_endproc .size gcm_gmult_ssse3,.-gcm_gmult_ssse3 ____ @@ -245,19 +244,18 @@ $code .= <<____; .globl gcm_ghash_ssse3 .align 16 gcm_ghash_ssse3: -.Lghash_seh_begin: .cfi_startproc +.seh_startproc ____ $code .= <<____ if ($win64); subq \$56, %rsp -.Lghash_seh_allocstack: +.seh_allocstack 56 movdqa %xmm6, (%rsp) -.Lghash_seh_save_xmm6: +.seh_savexmm128 %xmm6, 0 movdqa %xmm10, 16(%rsp) -.Lghash_seh_save_xmm10: +.seh_savexmm128 %xmm10, 16 movdqa %xmm11, 32(%rsp) -.Lghash_seh_save_xmm11: -.Lghash_seh_prolog_end: +.seh_savexmm128 %xmm11, 32 ____ $code .= <<____; movdqu ($Xi), %xmm0 @@ -329,10 +327,11 @@ $code .= <<____ if ($win64); ____ $code .= <<____; ret -.Lghash_seh_end: .cfi_endproc +.seh_endproc .size gcm_ghash_ssse3,.-gcm_ghash_ssse3 +.section .rodata .align 16 # .Lreverse_bytes is a permutation which, if applied with pshufb, reverses the # bytes in an XMM register. @@ -341,73 +340,8 @@ $code .= <<____; # .Llow4_mask is an XMM mask which selects the low four bits of each byte. .Llow4_mask: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.text ____ -if ($win64) { - # Add unwind metadata for SEH. - # - # TODO(davidben): This is all manual right now. Once we've added SEH tests, - # add support for emitting these in x86_64-xlate.pl, probably based on MASM - # and Yasm's unwind directives, and unify with CFI. Then upstream it to - # replace the error-prone and non-standard custom handlers. - - # See https://docs.microsoft.com/en-us/cpp/build/struct-unwind-code?view=vs-2017 - my $UWOP_ALLOC_SMALL = 2; - my $UWOP_SAVE_XMM128 = 8; - - $code .= <<____; -.section .pdata -.align 4 - .rva .Lgmult_seh_begin - .rva .Lgmult_seh_end - .rva .Lgmult_seh_info - - .rva .Lghash_seh_begin - .rva .Lghash_seh_end - .rva .Lghash_seh_info - -.section .xdata -.align 8 -.Lgmult_seh_info: - .byte 1 # version 1, no flags - .byte .Lgmult_seh_prolog_end-.Lgmult_seh_begin - .byte 5 # num_slots = 1 + 2 + 2 - .byte 0 # no frame register - - .byte .Lgmult_seh_save_xmm10-.Lgmult_seh_begin - .byte @{[$UWOP_SAVE_XMM128 | (10 << 4)]} - .value 1 - - .byte .Lgmult_seh_save_xmm6-.Lgmult_seh_begin - .byte @{[$UWOP_SAVE_XMM128 | (6 << 4)]} - .value 0 - - .byte .Lgmult_seh_allocstack-.Lgmult_seh_begin - .byte @{[$UWOP_ALLOC_SMALL | (((40 - 8) / 8) << 4)]} - -.align 8 -.Lghash_seh_info: - .byte 1 # version 1, no flags - .byte .Lghash_seh_prolog_end-.Lghash_seh_begin - .byte 7 # num_slots = 1 + 2 + 2 + 2 - .byte 0 # no frame register - - .byte .Lghash_seh_save_xmm11-.Lghash_seh_begin - .byte @{[$UWOP_SAVE_XMM128 | (11 << 4)]} - .value 2 - - .byte .Lghash_seh_save_xmm10-.Lghash_seh_begin - .byte @{[$UWOP_SAVE_XMM128 | (10 << 4)]} - .value 1 - - .byte .Lghash_seh_save_xmm6-.Lghash_seh_begin - .byte @{[$UWOP_SAVE_XMM128 | (6 << 4)]} - .value 0 - - .byte .Lghash_seh_allocstack-.Lghash_seh_begin - .byte @{[$UWOP_ALLOC_SMALL | (((56 - 8) / 8) << 4)]} -____ -} - print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl index 1aeb7b7d..19b18cc6 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghash-x86_64.pl @@ -205,13 +205,14 @@ $code.=<<___; .align 16 gcm_init_clmul: .cfi_startproc +.seh_startproc .L_init_clmul: ___ $code.=<<___ if ($win64); -.LSEH_begin_gcm_init_clmul: - # I can't trust assembler to use specific encoding:-( - .byte 0x48,0x83,0xec,0x18 #sub $0x18,%rsp - .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp) + sub \$0x18,%rsp +.seh_allocstack 0x18 + movaps %xmm6,(%rsp) +.seh_savexmm128 %xmm6, 0 ___ $code.=<<___; movdqu ($Xip),$Hkey @@ -270,11 +271,11 @@ ___ $code.=<<___ if ($win64); movaps (%rsp),%xmm6 lea 0x18(%rsp),%rsp -.LSEH_end_gcm_init_clmul: ___ $code.=<<___; ret .cfi_endproc +.seh_endproc .size gcm_init_clmul,.-gcm_init_clmul ___ } @@ -338,23 +339,33 @@ $code.=<<___; .align 32 gcm_ghash_clmul: .cfi_startproc +.seh_startproc .L_ghash_clmul: ___ $code.=<<___ if ($win64); lea -0x88(%rsp),%rax -.LSEH_begin_gcm_ghash_clmul: - # I can't trust assembler to use specific encoding:-( - .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax),%rsp - .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6,-0x20(%rax) - .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7,-0x10(%rax) - .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8,0(%rax) - .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9,0x10(%rax) - .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10,0x20(%rax) - .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11,0x30(%rax) - .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12,0x40(%rax) - .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13,0x50(%rax) - .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14,0x60(%rax) - .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15,0x70(%rax) + lea -0x20(%rax),%rsp +.seh_allocstack 0x20+0x88 + movaps %xmm6,-0x20(%rax) +.seh_savexmm128 %xmm6, 0x20-0x20 + movaps %xmm7,-0x10(%rax) +.seh_savexmm128 %xmm7, 0x20-0x10 + movaps %xmm8,0(%rax) +.seh_savexmm128 %xmm8, 0x20+0 + movaps %xmm9,0x10(%rax) +.seh_savexmm128 %xmm9, 0x20+0x10 + movaps %xmm10,0x20(%rax) +.seh_savexmm128 %xmm10, 0x20+0x20 + movaps %xmm11,0x30(%rax) +.seh_savexmm128 %xmm11, 0x20+0x30 + movaps %xmm12,0x40(%rax) +.seh_savexmm128 %xmm12, 0x20+0x40 + movaps %xmm13,0x50(%rax) +.seh_savexmm128 %xmm13, 0x20+0x50 + movaps %xmm14,0x60(%rax) +.seh_savexmm128 %xmm14, 0x20+0x60 + movaps %xmm15,0x70(%rax) +.seh_savexmm128 %xmm15, 0x20+0x70 ___ $code.=<<___; movdqa .Lbswap_mask(%rip),$T3 @@ -682,11 +693,11 @@ $code.=<<___ if ($win64); movaps 0x80(%rsp),%xmm14 movaps 0x90(%rsp),%xmm15 lea 0xa8(%rsp),%rsp -.LSEH_end_gcm_ghash_clmul: ___ $code.=<<___; ret .cfi_endproc +.seh_endproc .size gcm_ghash_clmul,.-gcm_ghash_clmul ___ } @@ -703,10 +714,11 @@ my ($Htbl,$Xip)=@_4args; my $HK="%xmm6"; $code.=<<___ if ($win64); -.LSEH_begin_gcm_init_avx: - # I can't trust assembler to use specific encoding:-( - .byte 0x48,0x83,0xec,0x18 #sub $0x18,%rsp - .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp) +.seh_startproc + sub \$0x18,%rsp +.seh_allocstack 0x18 + movaps %xmm6,(%rsp) +.seh_savexmm128 %xmm6, 0 ___ $code.=<<___; vzeroupper @@ -821,10 +833,10 @@ ___ $code.=<<___ if ($win64); movaps (%rsp),%xmm6 lea 0x18(%rsp),%rsp -.LSEH_end_gcm_init_avx: ___ $code.=<<___; ret +.seh_endproc .cfi_endproc .size gcm_init_avx,.-gcm_init_avx ___ @@ -861,20 +873,30 @@ my ($Xlo,$Xhi,$Xmi, $Xi,$Xo,$Tred,$bswap,$Ii,$Ij) = map("%xmm$_",(0..15)); $code.=<<___ if ($win64); +.seh_startproc lea -0x88(%rsp),%rax -.LSEH_begin_gcm_ghash_avx: - # I can't trust assembler to use specific encoding:-( - .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax),%rsp - .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6,-0x20(%rax) - .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7,-0x10(%rax) - .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8,0(%rax) - .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9,0x10(%rax) - .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10,0x20(%rax) - .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11,0x30(%rax) - .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12,0x40(%rax) - .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13,0x50(%rax) - .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14,0x60(%rax) - .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15,0x70(%rax) + lea -0x20(%rax),%rsp +.seh_allocstack 0x20+0x88 + movaps %xmm6,-0x20(%rax) +.seh_savexmm128 %xmm6, 0x20-0x20 + movaps %xmm7,-0x10(%rax) +.seh_savexmm128 %xmm7, 0x20-0x10 + movaps %xmm8,0(%rax) +.seh_savexmm128 %xmm8, 0x20+0 + movaps %xmm9,0x10(%rax) +.seh_savexmm128 %xmm9, 0x20+0x10 + movaps %xmm10,0x20(%rax) +.seh_savexmm128 %xmm10, 0x20+0x20 + movaps %xmm11,0x30(%rax) +.seh_savexmm128 %xmm11, 0x20+0x30 + movaps %xmm12,0x40(%rax) +.seh_savexmm128 %xmm12, 0x20+0x40 + movaps %xmm13,0x50(%rax) +.seh_savexmm128 %xmm13, 0x20+0x50 + movaps %xmm14,0x60(%rax) +.seh_savexmm128 %xmm14, 0x20+0x60 + movaps %xmm15,0x70(%rax) +.seh_savexmm128 %xmm15, 0x20+0x70 ___ $code.=<<___; vzeroupper @@ -1260,11 +1282,11 @@ $code.=<<___ if ($win64); movaps 0x80(%rsp),%xmm14 movaps 0x90(%rsp),%xmm15 lea 0xa8(%rsp),%rsp -.LSEH_end_gcm_ghash_avx: ___ $code.=<<___; ret .cfi_endproc +.seh_endproc .size gcm_ghash_avx,.-gcm_ghash_avx ___ } else { @@ -1275,6 +1297,7 @@ ___ } $code.=<<___; +.section .rodata .align 64 .Lbswap_mask: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 @@ -1286,52 +1309,9 @@ $code.=<<___; .asciz "GHASH for x86_64, CRYPTOGAMS by " .align 64 +.text ___ -if ($win64) { -$code.=<<___; -.section .pdata -.align 4 - .rva .LSEH_begin_gcm_init_clmul - .rva .LSEH_end_gcm_init_clmul - .rva .LSEH_info_gcm_init_clmul - - .rva .LSEH_begin_gcm_ghash_clmul - .rva .LSEH_end_gcm_ghash_clmul - .rva .LSEH_info_gcm_ghash_clmul -___ -$code.=<<___ if ($avx); - .rva .LSEH_begin_gcm_init_avx - .rva .LSEH_end_gcm_init_avx - .rva .LSEH_info_gcm_init_clmul - - .rva .LSEH_begin_gcm_ghash_avx - .rva .LSEH_end_gcm_ghash_avx - .rva .LSEH_info_gcm_ghash_clmul -___ -$code.=<<___; -.section .xdata -.align 8 -.LSEH_info_gcm_init_clmul: - .byte 0x01,0x08,0x03,0x00 - .byte 0x08,0x68,0x00,0x00 #movaps 0x00(rsp),xmm6 - .byte 0x04,0x22,0x00,0x00 #sub rsp,0x18 -.LSEH_info_gcm_ghash_clmul: - .byte 0x01,0x33,0x16,0x00 - .byte 0x33,0xf8,0x09,0x00 #movaps 0x90(rsp),xmm15 - .byte 0x2e,0xe8,0x08,0x00 #movaps 0x80(rsp),xmm14 - .byte 0x29,0xd8,0x07,0x00 #movaps 0x70(rsp),xmm13 - .byte 0x24,0xc8,0x06,0x00 #movaps 0x60(rsp),xmm12 - .byte 0x1f,0xb8,0x05,0x00 #movaps 0x50(rsp),xmm11 - .byte 0x1a,0xa8,0x04,0x00 #movaps 0x40(rsp),xmm10 - .byte 0x15,0x98,0x03,0x00 #movaps 0x30(rsp),xmm9 - .byte 0x10,0x88,0x02,0x00 #movaps 0x20(rsp),xmm8 - .byte 0x0c,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7 - .byte 0x08,0x68,0x00,0x00 #movaps 0x00(rsp),xmm6 - .byte 0x04,0x01,0x15,0x00 #sub rsp,0xa8 -___ -} - $code =~ s/\`([^\`]*)\`/eval($1)/gem; print $code; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashp8-ppc.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashp8-ppc.pl deleted file mode 100644 index e9ca11a8..00000000 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashp8-ppc.pl +++ /dev/null @@ -1,670 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the OpenSSL license (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# -# ==================================================================== -# Written by Andy Polyakov for the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see http://www.openssl.org/~appro/cryptogams/. -# ==================================================================== -# -# GHASH for for PowerISA v2.07. -# -# July 2014 -# -# Accurate performance measurements are problematic, because it's -# always virtualized setup with possibly throttled processor. -# Relative comparison is therefore more informative. This initial -# version is ~2.1x slower than hardware-assisted AES-128-CTR, ~12x -# faster than "4-bit" integer-only compiler-generated 64-bit code. -# "Initial version" means that there is room for futher improvement. - -# May 2016 -# -# 2x aggregated reduction improves performance by 50% (resulting -# performance on POWER8 is 1 cycle per processed byte), and 4x -# aggregated reduction - by 170% or 2.7x (resulting in 0.55 cpb). - -$flavour=shift; -$output =shift; - -if ($flavour =~ /64/) { - $SIZE_T=8; - $LRSAVE=2*$SIZE_T; - $STU="stdu"; - $POP="ld"; - $PUSH="std"; - $UCMP="cmpld"; - $SHRI="srdi"; -} elsif ($flavour =~ /32/) { - $SIZE_T=4; - $LRSAVE=$SIZE_T; - $STU="stwu"; - $POP="lwz"; - $PUSH="stw"; - $UCMP="cmplw"; - $SHRI="srwi"; -} else { die "nonsense $flavour"; } - -$sp="r1"; -$FRAME=6*$SIZE_T+13*16; # 13*16 is for v20-v31 offload - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../../perlasm/ppc-xlate.pl" and -f $xlate) or -die "can't locate ppc-xlate.pl"; - -open STDOUT,"| $^X \"$xlate\" $flavour \"$output\"" || die "can't call $xlate: $!"; - -my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6)); # argument block - -my ($Xl,$Xm,$Xh,$IN)=map("v$_",(0..3)); -my ($zero,$t0,$t1,$t2,$xC2,$H,$Hh,$Hl,$lemask)=map("v$_",(4..12)); -my ($Xl1,$Xm1,$Xh1,$IN1,$H2,$H2h,$H2l)=map("v$_",(13..19)); -my $vrsave="r12"; - -$code=<<___; -.machine "any" - -.text - -.globl .gcm_init_p8 -.align 5 -.gcm_init_p8: - li r0,-4096 - li r8,0x10 - mfspr $vrsave,256 - li r9,0x20 - mtspr 256,r0 - li r10,0x30 - lvx_u $H,0,r4 # load H - - vspltisb $xC2,-16 # 0xf0 - vspltisb $t0,1 # one - vaddubm $xC2,$xC2,$xC2 # 0xe0 - vxor $zero,$zero,$zero - vor $xC2,$xC2,$t0 # 0xe1 - vsldoi $xC2,$xC2,$zero,15 # 0xe1... - vsldoi $t1,$zero,$t0,1 # ...1 - vaddubm $xC2,$xC2,$xC2 # 0xc2... - vspltisb $t2,7 - vor $xC2,$xC2,$t1 # 0xc2....01 - vspltb $t1,$H,0 # most significant byte - vsl $H,$H,$t0 # H<<=1 - vsrab $t1,$t1,$t2 # broadcast carry bit - vand $t1,$t1,$xC2 - vxor $IN,$H,$t1 # twisted H - - vsldoi $H,$IN,$IN,8 # twist even more ... - vsldoi $xC2,$zero,$xC2,8 # 0xc2.0 - vsldoi $Hl,$zero,$H,8 # ... and split - vsldoi $Hh,$H,$zero,8 - - stvx_u $xC2,0,r3 # save pre-computed table - stvx_u $Hl,r8,r3 - li r8,0x40 - stvx_u $H, r9,r3 - li r9,0x50 - stvx_u $Hh,r10,r3 - li r10,0x60 - - vpmsumd $Xl,$IN,$Hl # H.lo·H.lo - vpmsumd $Xm,$IN,$H # H.hi·H.lo+H.lo·H.hi - vpmsumd $Xh,$IN,$Hh # H.hi·H.hi - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - vxor $t1,$t1,$Xh - vxor $IN1,$Xl,$t1 - - vsldoi $H2,$IN1,$IN1,8 - vsldoi $H2l,$zero,$H2,8 - vsldoi $H2h,$H2,$zero,8 - - stvx_u $H2l,r8,r3 # save H^2 - li r8,0x70 - stvx_u $H2,r9,r3 - li r9,0x80 - stvx_u $H2h,r10,r3 - li r10,0x90 -___ -{ -my ($t4,$t5,$t6) = ($Hl,$H,$Hh); -$code.=<<___; - vpmsumd $Xl,$IN,$H2l # H.lo·H^2.lo - vpmsumd $Xl1,$IN1,$H2l # H^2.lo·H^2.lo - vpmsumd $Xm,$IN,$H2 # H.hi·H^2.lo+H.lo·H^2.hi - vpmsumd $Xm1,$IN1,$H2 # H^2.hi·H^2.lo+H^2.lo·H^2.hi - vpmsumd $Xh,$IN,$H2h # H.hi·H^2.hi - vpmsumd $Xh1,$IN1,$H2h # H^2.hi·H^2.hi - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - vpmsumd $t6,$Xl1,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vsldoi $t4,$Xm1,$zero,8 - vsldoi $t5,$zero,$Xm1,8 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - vxor $Xl1,$Xl1,$t4 - vxor $Xh1,$Xh1,$t5 - - vsldoi $Xl,$Xl,$Xl,8 - vsldoi $Xl1,$Xl1,$Xl1,8 - vxor $Xl,$Xl,$t2 - vxor $Xl1,$Xl1,$t6 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vsldoi $t5,$Xl1,$Xl1,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - vpmsumd $Xl1,$Xl1,$xC2 - vxor $t1,$t1,$Xh - vxor $t5,$t5,$Xh1 - vxor $Xl,$Xl,$t1 - vxor $Xl1,$Xl1,$t5 - - vsldoi $H,$Xl,$Xl,8 - vsldoi $H2,$Xl1,$Xl1,8 - vsldoi $Hl,$zero,$H,8 - vsldoi $Hh,$H,$zero,8 - vsldoi $H2l,$zero,$H2,8 - vsldoi $H2h,$H2,$zero,8 - - stvx_u $Hl,r8,r3 # save H^3 - li r8,0xa0 - stvx_u $H,r9,r3 - li r9,0xb0 - stvx_u $Hh,r10,r3 - li r10,0xc0 - stvx_u $H2l,r8,r3 # save H^4 - stvx_u $H2,r9,r3 - stvx_u $H2h,r10,r3 - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,2,0 - .long 0 -.size .gcm_init_p8,.-.gcm_init_p8 -___ -} -$code.=<<___; -.globl .gcm_gmult_p8 -.align 5 -.gcm_gmult_p8: - lis r0,0xfff8 - li r8,0x10 - mfspr $vrsave,256 - li r9,0x20 - mtspr 256,r0 - li r10,0x30 - lvx_u $IN,0,$Xip # load Xi - - lvx_u $Hl,r8,$Htbl # load pre-computed table - le?lvsl $lemask,r0,r0 - lvx_u $H, r9,$Htbl - le?vspltisb $t0,0x07 - lvx_u $Hh,r10,$Htbl - le?vxor $lemask,$lemask,$t0 - lvx_u $xC2,0,$Htbl - le?vperm $IN,$IN,$IN,$lemask - vxor $zero,$zero,$zero - - vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo - vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi - vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - vxor $t1,$t1,$Xh - vxor $Xl,$Xl,$t1 - - le?vperm $Xl,$Xl,$Xl,$lemask - stvx_u $Xl,0,$Xip # write out Xi - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,2,0 - .long 0 -.size .gcm_gmult_p8,.-.gcm_gmult_p8 - -.globl .gcm_ghash_p8 -.align 5 -.gcm_ghash_p8: - li r0,-4096 - li r8,0x10 - mfspr $vrsave,256 - li r9,0x20 - mtspr 256,r0 - li r10,0x30 - lvx_u $Xl,0,$Xip # load Xi - - lvx_u $Hl,r8,$Htbl # load pre-computed table - li r8,0x40 - le?lvsl $lemask,r0,r0 - lvx_u $H, r9,$Htbl - li r9,0x50 - le?vspltisb $t0,0x07 - lvx_u $Hh,r10,$Htbl - li r10,0x60 - le?vxor $lemask,$lemask,$t0 - lvx_u $xC2,0,$Htbl - le?vperm $Xl,$Xl,$Xl,$lemask - vxor $zero,$zero,$zero - - ${UCMP}i $len,64 - bge Lgcm_ghash_p8_4x - - lvx_u $IN,0,$inp - addi $inp,$inp,16 - subic. $len,$len,16 - le?vperm $IN,$IN,$IN,$lemask - vxor $IN,$IN,$Xl - beq Lshort - - lvx_u $H2l,r8,$Htbl # load H^2 - li r8,16 - lvx_u $H2, r9,$Htbl - add r9,$inp,$len # end of input - lvx_u $H2h,r10,$Htbl - be?b Loop_2x - -.align 5 -Loop_2x: - lvx_u $IN1,0,$inp - le?vperm $IN1,$IN1,$IN1,$lemask - - subic $len,$len,32 - vpmsumd $Xl,$IN,$H2l # H^2.lo·Xi.lo - vpmsumd $Xl1,$IN1,$Hl # H.lo·Xi+1.lo - subfe r0,r0,r0 # borrow?-1:0 - vpmsumd $Xm,$IN,$H2 # H^2.hi·Xi.lo+H^2.lo·Xi.hi - vpmsumd $Xm1,$IN1,$H # H.hi·Xi+1.lo+H.lo·Xi+1.hi - and r0,r0,$len - vpmsumd $Xh,$IN,$H2h # H^2.hi·Xi.hi - vpmsumd $Xh1,$IN1,$Hh # H.hi·Xi+1.hi - add $inp,$inp,r0 - - vxor $Xl,$Xl,$Xl1 - vxor $Xm,$Xm,$Xm1 - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xh,$Xh,$Xh1 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - lvx_u $IN,r8,$inp - addi $inp,$inp,32 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - le?vperm $IN,$IN,$IN,$lemask - vxor $t1,$t1,$Xh - vxor $IN,$IN,$t1 - vxor $IN,$IN,$Xl - $UCMP r9,$inp - bgt Loop_2x # done yet? - - cmplwi $len,0 - bne Leven - -Lshort: - vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo - vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi - vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - vxor $t1,$t1,$Xh - -Leven: - vxor $Xl,$Xl,$t1 - le?vperm $Xl,$Xl,$Xl,$lemask - stvx_u $Xl,0,$Xip # write out Xi - - mtspr 256,$vrsave - blr - .long 0 - .byte 0,12,0x14,0,0,0,4,0 - .long 0 -___ -{ -my ($Xl3,$Xm2,$IN2,$H3l,$H3,$H3h, - $Xh3,$Xm3,$IN3,$H4l,$H4,$H4h) = map("v$_",(20..31)); -my $IN0=$IN; -my ($H21l,$H21h,$loperm,$hiperm) = ($Hl,$Hh,$H2l,$H2h); - -$code.=<<___; -.align 5 -.gcm_ghash_p8_4x: -Lgcm_ghash_p8_4x: - $STU $sp,-$FRAME($sp) - li r10,`15+6*$SIZE_T` - li r11,`31+6*$SIZE_T` - stvx v20,r10,$sp - addi r10,r10,32 - stvx v21,r11,$sp - addi r11,r11,32 - stvx v22,r10,$sp - addi r10,r10,32 - stvx v23,r11,$sp - addi r11,r11,32 - stvx v24,r10,$sp - addi r10,r10,32 - stvx v25,r11,$sp - addi r11,r11,32 - stvx v26,r10,$sp - addi r10,r10,32 - stvx v27,r11,$sp - addi r11,r11,32 - stvx v28,r10,$sp - addi r10,r10,32 - stvx v29,r11,$sp - addi r11,r11,32 - stvx v30,r10,$sp - li r10,0x60 - stvx v31,r11,$sp - li r0,-1 - stw $vrsave,`$FRAME-4`($sp) # save vrsave - mtspr 256,r0 # preserve all AltiVec registers - - lvsl $t0,0,r8 # 0x0001..0e0f - #lvx_u $H2l,r8,$Htbl # load H^2 - li r8,0x70 - lvx_u $H2, r9,$Htbl - li r9,0x80 - vspltisb $t1,8 # 0x0808..0808 - #lvx_u $H2h,r10,$Htbl - li r10,0x90 - lvx_u $H3l,r8,$Htbl # load H^3 - li r8,0xa0 - lvx_u $H3, r9,$Htbl - li r9,0xb0 - lvx_u $H3h,r10,$Htbl - li r10,0xc0 - lvx_u $H4l,r8,$Htbl # load H^4 - li r8,0x10 - lvx_u $H4, r9,$Htbl - li r9,0x20 - lvx_u $H4h,r10,$Htbl - li r10,0x30 - - vsldoi $t2,$zero,$t1,8 # 0x0000..0808 - vaddubm $hiperm,$t0,$t2 # 0x0001..1617 - vaddubm $loperm,$t1,$hiperm # 0x0809..1e1f - - $SHRI $len,$len,4 # this allows to use sign bit - # as carry - lvx_u $IN0,0,$inp # load input - lvx_u $IN1,r8,$inp - subic. $len,$len,8 - lvx_u $IN2,r9,$inp - lvx_u $IN3,r10,$inp - addi $inp,$inp,0x40 - le?vperm $IN0,$IN0,$IN0,$lemask - le?vperm $IN1,$IN1,$IN1,$lemask - le?vperm $IN2,$IN2,$IN2,$lemask - le?vperm $IN3,$IN3,$IN3,$lemask - - vxor $Xh,$IN0,$Xl - - vpmsumd $Xl1,$IN1,$H3l - vpmsumd $Xm1,$IN1,$H3 - vpmsumd $Xh1,$IN1,$H3h - - vperm $H21l,$H2,$H,$hiperm - vperm $t0,$IN2,$IN3,$loperm - vperm $H21h,$H2,$H,$loperm - vperm $t1,$IN2,$IN3,$hiperm - vpmsumd $Xm2,$IN2,$H2 # H^2.lo·Xi+2.hi+H^2.hi·Xi+2.lo - vpmsumd $Xl3,$t0,$H21l # H^2.lo·Xi+2.lo+H.lo·Xi+3.lo - vpmsumd $Xm3,$IN3,$H # H.hi·Xi+3.lo +H.lo·Xi+3.hi - vpmsumd $Xh3,$t1,$H21h # H^2.hi·Xi+2.hi+H.hi·Xi+3.hi - - vxor $Xm2,$Xm2,$Xm1 - vxor $Xl3,$Xl3,$Xl1 - vxor $Xm3,$Xm3,$Xm2 - vxor $Xh3,$Xh3,$Xh1 - - blt Ltail_4x - -Loop_4x: - lvx_u $IN0,0,$inp - lvx_u $IN1,r8,$inp - subic. $len,$len,4 - lvx_u $IN2,r9,$inp - lvx_u $IN3,r10,$inp - addi $inp,$inp,0x40 - le?vperm $IN1,$IN1,$IN1,$lemask - le?vperm $IN2,$IN2,$IN2,$lemask - le?vperm $IN3,$IN3,$IN3,$lemask - le?vperm $IN0,$IN0,$IN0,$lemask - - vpmsumd $Xl,$Xh,$H4l # H^4.lo·Xi.lo - vpmsumd $Xm,$Xh,$H4 # H^4.hi·Xi.lo+H^4.lo·Xi.hi - vpmsumd $Xh,$Xh,$H4h # H^4.hi·Xi.hi - vpmsumd $Xl1,$IN1,$H3l - vpmsumd $Xm1,$IN1,$H3 - vpmsumd $Xh1,$IN1,$H3h - - vxor $Xl,$Xl,$Xl3 - vxor $Xm,$Xm,$Xm3 - vxor $Xh,$Xh,$Xh3 - vperm $t0,$IN2,$IN3,$loperm - vperm $t1,$IN2,$IN3,$hiperm - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - vpmsumd $Xl3,$t0,$H21l # H.lo·Xi+3.lo +H^2.lo·Xi+2.lo - vpmsumd $Xh3,$t1,$H21h # H.hi·Xi+3.hi +H^2.hi·Xi+2.hi - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xm2,$IN2,$H2 # H^2.hi·Xi+2.lo+H^2.lo·Xi+2.hi - vpmsumd $Xm3,$IN3,$H # H.hi·Xi+3.lo +H.lo·Xi+3.hi - vpmsumd $Xl,$Xl,$xC2 - - vxor $Xl3,$Xl3,$Xl1 - vxor $Xh3,$Xh3,$Xh1 - vxor $Xh,$Xh,$IN0 - vxor $Xm2,$Xm2,$Xm1 - vxor $Xh,$Xh,$t1 - vxor $Xm3,$Xm3,$Xm2 - vxor $Xh,$Xh,$Xl - bge Loop_4x - -Ltail_4x: - vpmsumd $Xl,$Xh,$H4l # H^4.lo·Xi.lo - vpmsumd $Xm,$Xh,$H4 # H^4.hi·Xi.lo+H^4.lo·Xi.hi - vpmsumd $Xh,$Xh,$H4h # H^4.hi·Xi.hi - - vxor $Xl,$Xl,$Xl3 - vxor $Xm,$Xm,$Xm3 - - vpmsumd $t2,$Xl,$xC2 # 1st reduction phase - - vsldoi $t0,$Xm,$zero,8 - vsldoi $t1,$zero,$Xm,8 - vxor $Xh,$Xh,$Xh3 - vxor $Xl,$Xl,$t0 - vxor $Xh,$Xh,$t1 - - vsldoi $Xl,$Xl,$Xl,8 - vxor $Xl,$Xl,$t2 - - vsldoi $t1,$Xl,$Xl,8 # 2nd reduction phase - vpmsumd $Xl,$Xl,$xC2 - vxor $t1,$t1,$Xh - vxor $Xl,$Xl,$t1 - - addic. $len,$len,4 - beq Ldone_4x - - lvx_u $IN0,0,$inp - ${UCMP}i $len,2 - li $len,-4 - blt Lone - lvx_u $IN1,r8,$inp - beq Ltwo - -Lthree: - lvx_u $IN2,r9,$inp - le?vperm $IN0,$IN0,$IN0,$lemask - le?vperm $IN1,$IN1,$IN1,$lemask - le?vperm $IN2,$IN2,$IN2,$lemask - - vxor $Xh,$IN0,$Xl - vmr $H4l,$H3l - vmr $H4, $H3 - vmr $H4h,$H3h - - vperm $t0,$IN1,$IN2,$loperm - vperm $t1,$IN1,$IN2,$hiperm - vpmsumd $Xm2,$IN1,$H2 # H^2.lo·Xi+1.hi+H^2.hi·Xi+1.lo - vpmsumd $Xm3,$IN2,$H # H.hi·Xi+2.lo +H.lo·Xi+2.hi - vpmsumd $Xl3,$t0,$H21l # H^2.lo·Xi+1.lo+H.lo·Xi+2.lo - vpmsumd $Xh3,$t1,$H21h # H^2.hi·Xi+1.hi+H.hi·Xi+2.hi - - vxor $Xm3,$Xm3,$Xm2 - b Ltail_4x - -.align 4 -Ltwo: - le?vperm $IN0,$IN0,$IN0,$lemask - le?vperm $IN1,$IN1,$IN1,$lemask - - vxor $Xh,$IN0,$Xl - vperm $t0,$zero,$IN1,$loperm - vperm $t1,$zero,$IN1,$hiperm - - vsldoi $H4l,$zero,$H2,8 - vmr $H4, $H2 - vsldoi $H4h,$H2,$zero,8 - - vpmsumd $Xl3,$t0, $H21l # H.lo·Xi+1.lo - vpmsumd $Xm3,$IN1,$H # H.hi·Xi+1.lo+H.lo·Xi+2.hi - vpmsumd $Xh3,$t1, $H21h # H.hi·Xi+1.hi - - b Ltail_4x - -.align 4 -Lone: - le?vperm $IN0,$IN0,$IN0,$lemask - - vsldoi $H4l,$zero,$H,8 - vmr $H4, $H - vsldoi $H4h,$H,$zero,8 - - vxor $Xh,$IN0,$Xl - vxor $Xl3,$Xl3,$Xl3 - vxor $Xm3,$Xm3,$Xm3 - vxor $Xh3,$Xh3,$Xh3 - - b Ltail_4x - -Ldone_4x: - le?vperm $Xl,$Xl,$Xl,$lemask - stvx_u $Xl,0,$Xip # write out Xi - - li r10,`15+6*$SIZE_T` - li r11,`31+6*$SIZE_T` - mtspr 256,$vrsave - lvx v20,r10,$sp - addi r10,r10,32 - lvx v21,r11,$sp - addi r11,r11,32 - lvx v22,r10,$sp - addi r10,r10,32 - lvx v23,r11,$sp - addi r11,r11,32 - lvx v24,r10,$sp - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp - addi $sp,$sp,$FRAME - blr - .long 0 - .byte 0,12,0x04,0,0x80,0,4,0 - .long 0 -___ -} -$code.=<<___; -.size .gcm_ghash_p8,.-.gcm_ghash_p8 - -.asciz "GHASH for PowerISA 2.07, CRYPTOGAMS by " -.align 2 -___ - -foreach (split("\n",$code)) { - s/\`([^\`]*)\`/eval $1/geo; - - if ($flavour =~ /le$/o) { # little-endian - s/le\?//o or - s/be\?/#be#/o; - } else { - s/le\?/#le#/o or - s/be\?//o; - } - print $_,"\n"; -} - -close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl index 24eb7735..74f4b9b7 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl @@ -735,6 +735,9 @@ if ($flavour =~ /64/) { ######## 64-bit code s/\.[uisp]?64//o and s/\.16b/\.2d/go; s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o; + # Switch preprocessor checks to aarch64 versions. + s/__ARME([BL])__/__AARCH64E$1__/go; + print $_,"\n"; } } else { ######## 32-bit code diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cbc.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cbc.c index 192580eb..511a5de4 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cbc.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cbc.c @@ -49,8 +49,6 @@ #include #include -#include - #include "internal.h" #include "../../internal.h" @@ -68,10 +66,7 @@ void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, size_t n; const uint8_t *iv = ivec; while (len >= 16) { - for (n = 0; n < 16; n += sizeof(crypto_word_t)) { - CRYPTO_store_word_le( - out + n, CRYPTO_load_word_le(in + n) ^ CRYPTO_load_word_le(iv + n)); - } + CRYPTO_xor16(out, in, iv); (*block)(out, out, key); iv = out; len -= 16; @@ -116,23 +111,14 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, assert(inptr >= outptr || inptr + len <= outptr); size_t n; - union { - crypto_word_t t[16 / sizeof(crypto_word_t)]; - uint8_t c[16]; - } tmp; - + alignas(16) uint8_t tmp[16]; if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { // If |out| is at least two blocks behind |in| or completely disjoint, there // is no need to decrypt to a temporary block. - OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, - "block cannot be evenly divided into words"); const uint8_t *iv = ivec; while (len >= 16) { (*block)(in, out, key); - for (n = 0; n < 16; n += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(out + n) ^ - CRYPTO_load_word_le(iv + n)); - } + CRYPTO_xor16(out, out, iv); iv = in; len -= 16; in += 16; @@ -140,14 +126,14 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, } OPENSSL_memcpy(ivec, iv, 16); } else { - OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, - "block cannot be evenly divided into words"); + static_assert(16 % sizeof(crypto_word_t) == 0, + "block cannot be evenly divided into words"); while (len >= 16) { - (*block)(in, tmp.c, key); + (*block)(in, tmp, key); for (n = 0; n < 16; n += sizeof(crypto_word_t)) { crypto_word_t c = CRYPTO_load_word_le(in + n); - CRYPTO_store_word_le(out + n, tmp.t[n / sizeof(crypto_word_t)] ^ + CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(tmp + n) ^ CRYPTO_load_word_le(ivec + n)); CRYPTO_store_word_le(ivec + n, c); } @@ -159,10 +145,10 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, while (len) { uint8_t c; - (*block)(in, tmp.c, key); + (*block)(in, tmp, key); for (n = 0; n < 16 && n < len; ++n) { c = in[n]; - out[n] = tmp.c[n] ^ ivec[n]; + out[n] = tmp[n] ^ ivec[n]; ivec[n] = c; } if (len <= 16) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cfb.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cfb.c index 283a1078..37a81843 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cfb.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/cfb.c @@ -46,16 +46,13 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ -#include - #include #include #include "internal.h" -OPENSSL_STATIC_ASSERT(16 % sizeof(size_t) == 0, - "block cannot be divided into size_t"); +static_assert(16 % sizeof(size_t) == 0, "block cannot be divided into size_t"); void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, uint8_t ivec[16], unsigned *num, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ctr.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ctr.c index cea79ad9..8c333bb1 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ctr.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ctr.c @@ -46,8 +46,6 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ -#include - #include #include @@ -70,8 +68,8 @@ static void ctr128_inc(uint8_t *counter) { } while (n); } -OPENSSL_STATIC_ASSERT(16 % sizeof(crypto_word_t) == 0, - "block cannot be divided into crypto_word_t"); +static_assert(16 % sizeof(crypto_word_t) == 0, + "block cannot be divided into crypto_word_t"); // The input encrypted as though 128bit counter mode is being used. The extra // state information to record how much of the 128bit block we have used is @@ -103,10 +101,7 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, while (len >= 16) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); - for (n = 0; n < 16; n += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(in + n) ^ - CRYPTO_load_word_le(ecount_buf + n)); - } + CRYPTO_xor16(out, in, ecount_buf); len -= 16; out += 16; in += 16; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm.c index b010cd5a..8413951e 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm.c @@ -52,7 +52,6 @@ #include #include -#include #include "internal.h" #include "../../internal.h" @@ -63,9 +62,9 @@ static const size_t kSizeTWithoutLower4Bits = (size_t) -16; -#define GCM_MUL(ctx, Xi) gcm_gmult_nohw((ctx)->Xi.u, (ctx)->gcm_key.Htable) +#define GCM_MUL(ctx, Xi) gcm_gmult_nohw((ctx)->Xi, (ctx)->gcm_key.Htable) #define GHASH(ctx, in, len) \ - gcm_ghash_nohw((ctx)->Xi.u, (ctx)->gcm_key.Htable, in, len) + gcm_ghash_nohw((ctx)->Xi, (ctx)->gcm_key.Htable, in, len) // GHASH_CHUNK is "stride parameter" missioned to mitigate cache // trashing effect. In other words idea is to hash data while it's // still in L1 cache after encryption pass... @@ -127,87 +126,111 @@ void gcm_init_ssse3(u128 Htable[16], const uint64_t H[2]) { #ifdef GCM_FUNCREF #undef GCM_MUL -#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi.u, (ctx)->gcm_key.Htable) +#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi, (ctx)->gcm_key.Htable) #undef GHASH #define GHASH(ctx, in, len) \ - (*gcm_ghash_p)((ctx)->Xi.u, (ctx)->gcm_key.Htable, in, len) + (*gcm_ghash_p)((ctx)->Xi, (ctx)->gcm_key.Htable, in, len) #endif // GCM_FUNCREF +#if defined(HW_GCM) && defined(OPENSSL_X86_64) +static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t Xi[16], const u128 Htable[16]) { + return aesni_gcm_encrypt(in, out, len, key, ivec, Htable, Xi); +} + +static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t Xi[16], const u128 Htable[16]) { + return aesni_gcm_decrypt(in, out, len, key, ivec, Htable, Xi); +} +#endif // HW_GCM && X86_64 + +#if defined(HW_GCM) && defined(OPENSSL_AARCH64) + +static size_t hw_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t Xi[16], const u128 Htable[16]) { + const size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (!len_blocks) { + return 0; + } + aes_gcm_enc_kernel(in, len_blocks * 8, out, Xi, ivec, key, Htable); + return len_blocks; +} + +static size_t hw_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[16], + uint8_t Xi[16], const u128 Htable[16]) { + const size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (!len_blocks) { + return 0; + } + aes_gcm_dec_kernel(in, len_blocks * 8, out, Xi, ivec, key, Htable); + return len_blocks; +} + +#endif // HW_GCM && AARCH64 + void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, - u128 *out_key, u128 out_table[16], int *out_is_avx, + u128 out_table[16], int *out_is_avx, const uint8_t gcm_key[16]) { *out_is_avx = 0; - union { - uint64_t u[2]; - uint8_t c[16]; - } H; - - OPENSSL_memcpy(H.c, gcm_key, 16); - - // H is stored in host byte order - H.u[0] = CRYPTO_bswap8(H.u[0]); - H.u[1] = CRYPTO_bswap8(H.u[1]); - - OPENSSL_memcpy(out_key, H.c, 16); + // H is passed to |gcm_init_*| as a pair of byte-swapped, 64-bit values. + uint64_t H[2] = {CRYPTO_load_u64_be(gcm_key), + CRYPTO_load_u64_be(gcm_key + 8)}; #if defined(GHASH_ASM_X86_64) if (crypto_gcm_clmul_enabled()) { - if (((OPENSSL_ia32cap_get()[1] >> 22) & 0x41) == 0x41) { // AVX+MOVBE - gcm_init_avx(out_table, H.u); + if (CRYPTO_is_AVX_capable() && CRYPTO_is_MOVBE_capable()) { + gcm_init_avx(out_table, H); *out_mult = gcm_gmult_avx; *out_hash = gcm_ghash_avx; *out_is_avx = 1; return; } - gcm_init_clmul(out_table, H.u); + gcm_init_clmul(out_table, H); *out_mult = gcm_gmult_clmul; *out_hash = gcm_ghash_clmul; return; } - if (gcm_ssse3_capable()) { - gcm_init_ssse3(out_table, H.u); + if (CRYPTO_is_SSSE3_capable()) { + gcm_init_ssse3(out_table, H); *out_mult = gcm_gmult_ssse3; *out_hash = gcm_ghash_ssse3; return; } #elif defined(GHASH_ASM_X86) if (crypto_gcm_clmul_enabled()) { - gcm_init_clmul(out_table, H.u); + gcm_init_clmul(out_table, H); *out_mult = gcm_gmult_clmul; *out_hash = gcm_ghash_clmul; return; } - if (gcm_ssse3_capable()) { - gcm_init_ssse3(out_table, H.u); + if (CRYPTO_is_SSSE3_capable()) { + gcm_init_ssse3(out_table, H); *out_mult = gcm_gmult_ssse3; *out_hash = gcm_ghash_ssse3; return; } #elif defined(GHASH_ASM_ARM) if (gcm_pmull_capable()) { - gcm_init_v8(out_table, H.u); + gcm_init_v8(out_table, H); *out_mult = gcm_gmult_v8; *out_hash = gcm_ghash_v8; return; } if (gcm_neon_capable()) { - gcm_init_neon(out_table, H.u); + gcm_init_neon(out_table, H); *out_mult = gcm_gmult_neon; *out_hash = gcm_ghash_neon; return; } -#elif defined(GHASH_ASM_PPC64LE) - if (CRYPTO_is_PPC64LE_vcrypto_capable()) { - gcm_init_p8(out_table, H.u); - *out_mult = gcm_gmult_p8; - *out_hash = gcm_ghash_p8; - return; - } #endif - gcm_init_nohw(out_table, H.u); + gcm_init_nohw(out_table, H); *out_mult = gcm_gmult_nohw; *out_hash = gcm_ghash_nohw; } @@ -222,84 +245,88 @@ void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, const AES_KEY *aes_key, (*block)(ghash_key, ghash_key, aes_key); int is_avx; - CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, &gcm_key->H, - gcm_key->Htable, &is_avx, ghash_key); + CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, gcm_key->Htable, &is_avx, + ghash_key); - gcm_key->use_aesni_gcm_crypt = (is_avx && block_is_hwaes) ? 1 : 0; +#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_NO_ASM) + gcm_key->use_hw_gcm_crypt = (gcm_pmull_capable() && block_is_hwaes) ? 1 : 0; +#else + gcm_key->use_hw_gcm_crypt = (is_avx && block_is_hwaes) ? 1 : 0; +#endif } void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, const uint8_t *iv, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; #endif - ctx->Yi.u[0] = 0; - ctx->Yi.u[1] = 0; - ctx->Xi.u[0] = 0; - ctx->Xi.u[1] = 0; - ctx->len.u[0] = 0; // AAD length - ctx->len.u[1] = 0; // message length + OPENSSL_memset(&ctx->Yi, 0, sizeof(ctx->Yi)); + OPENSSL_memset(&ctx->Xi, 0, sizeof(ctx->Xi)); + ctx->len.aad = 0; + ctx->len.msg = 0; ctx->ares = 0; ctx->mres = 0; uint32_t ctr; if (len == 12) { - OPENSSL_memcpy(ctx->Yi.c, iv, 12); - ctx->Yi.c[15] = 1; + OPENSSL_memcpy(ctx->Yi, iv, 12); + ctx->Yi[15] = 1; ctr = 1; } else { uint64_t len0 = len; while (len >= 16) { - for (size_t i = 0; i < 16; ++i) { - ctx->Yi.c[i] ^= iv[i]; - } + CRYPTO_xor16(ctx->Yi, ctx->Yi, iv); GCM_MUL(ctx, Yi); iv += 16; len -= 16; } if (len) { for (size_t i = 0; i < len; ++i) { - ctx->Yi.c[i] ^= iv[i]; + ctx->Yi[i] ^= iv[i]; } GCM_MUL(ctx, Yi); } - len0 <<= 3; - ctx->Yi.u[1] ^= CRYPTO_bswap8(len0); + + uint8_t len_block[16]; + OPENSSL_memset(len_block, 0, 8); + CRYPTO_store_u64_be(len_block + 8, len0 << 3); + CRYPTO_xor16(ctx->Yi, ctx->Yi, len_block); GCM_MUL(ctx, Yi); - ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + ctr = CRYPTO_load_u32_be(ctx->Yi + 12); } - (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EK0.c, key); + (*ctx->gcm_key.block)(ctx->Yi, ctx->EK0, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); } int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; - void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) = ctx->gcm_key.ghash; #endif - if (ctx->len.u[1]) { + if (ctx->len.msg != 0) { + // The caller must have finished the AAD before providing other input. return 0; } - uint64_t alen = ctx->len.u[0] + len; + uint64_t alen = ctx->len.aad + len; if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { return 0; } - ctx->len.u[0] = alen; + ctx->len.aad = alen; unsigned n = ctx->ares; if (n) { while (n && len) { - ctx->Xi.c[n] ^= *(aad++); + ctx->Xi[n] ^= *(aad++); --len; n = (n + 1) % 16; } @@ -323,7 +350,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { if (len != 0) { n = (unsigned int)len; for (size_t i = 0; i < len; ++i) { - ctx->Xi.c[i] ^= aad[i]; + ctx->Xi[i] ^= aad[i]; } } @@ -335,18 +362,18 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, const uint8_t *in, uint8_t *out, size_t len) { block128_f block = ctx->gcm_key.block; #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; - void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) = ctx->gcm_key.ghash; #endif - uint64_t mlen = ctx->len.u[1] + len; + uint64_t mlen = ctx->len.msg + len; if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } - ctx->len.u[1] = mlen; + ctx->len.msg = mlen; if (ctx->ares) { // First call to encrypt finalizes GHASH(AAD) @@ -357,7 +384,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, unsigned n = ctx->mres; if (n) { while (n && len) { - ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= *(out++) = *(in++) ^ ctx->EKi[n]; --len; n = (n + 1) % 16; } @@ -369,19 +396,15 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, } } - uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); while (len >= GHASH_CHUNK) { size_t j = GHASH_CHUNK; while (j) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); - for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + i, - CRYPTO_load_word_le(in + i) ^ - ctx->EKi.t[i / sizeof(crypto_word_t)]); - } + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); + CRYPTO_xor16(out, in, ctx->EKi); out += 16; in += 16; j -= 16; @@ -392,14 +415,10 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, size_t len_blocks = len & kSizeTWithoutLower4Bits; if (len_blocks != 0) { while (len >= 16) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); - for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + i, - CRYPTO_load_word_le(in + i) ^ - ctx->EKi.t[i / sizeof(crypto_word_t)]); - } + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); + CRYPTO_xor16(out, in, ctx->EKi); out += 16; in += 16; len -= 16; @@ -407,11 +426,11 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, GHASH(ctx, out - len_blocks, len_blocks); } if (len) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { - ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= out[n] = in[n] ^ ctx->EKi[n]; ++n; } } @@ -425,18 +444,18 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, size_t len) { block128_f block = ctx->gcm_key.block; #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; - void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) = ctx->gcm_key.ghash; #endif - uint64_t mlen = ctx->len.u[1] + len; + uint64_t mlen = ctx->len.msg + len; if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } - ctx->len.u[1] = mlen; + ctx->len.msg = mlen; if (ctx->ares) { // First call to decrypt finalizes GHASH(AAD) @@ -448,8 +467,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, if (n) { while (n && len) { uint8_t c = *(in++); - *(out++) = c ^ ctx->EKi.c[n]; - ctx->Xi.c[n] ^= c; + *(out++) = c ^ ctx->EKi[n]; + ctx->Xi[n] ^= c; --len; n = (n + 1) % 16; } @@ -461,20 +480,16 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, } } - uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); while (len >= GHASH_CHUNK) { size_t j = GHASH_CHUNK; GHASH(ctx, in, GHASH_CHUNK); while (j) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); - for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + i, - CRYPTO_load_word_le(in + i) ^ - ctx->EKi.t[i / sizeof(crypto_word_t)]); - } + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); + CRYPTO_xor16(out, in, ctx->EKi); out += 16; in += 16; j -= 16; @@ -485,27 +500,23 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const AES_KEY *key, if (len_blocks != 0) { GHASH(ctx, in, len_blocks); while (len >= 16) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); - for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { - CRYPTO_store_word_le(out + i, - CRYPTO_load_word_le(in + i) ^ - ctx->EKi.t[i / sizeof(crypto_word_t)]); - } + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); + CRYPTO_xor16(out, in, ctx->EKi); out += 16; in += 16; len -= 16; } } if (len) { - (*block)(ctx->Yi.c, ctx->EKi.c, key); + (*block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { uint8_t c = in[n]; - ctx->Xi.c[n] ^= c; - out[n] = c ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= c; + out[n] = c ^ ctx->EKi[n]; ++n; } } @@ -518,18 +529,18 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, const uint8_t *in, uint8_t *out, size_t len, ctr128_f stream) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; - void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) = ctx->gcm_key.ghash; #endif - uint64_t mlen = ctx->len.u[1] + len; + uint64_t mlen = ctx->len.msg + len; if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } - ctx->len.u[1] = mlen; + ctx->len.msg = mlen; if (ctx->ares) { // First call to encrypt finalizes GHASH(AAD) @@ -540,7 +551,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, unsigned n = ctx->mres; if (n) { while (n && len) { - ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= *(out++) = *(in++) ^ ctx->EKi[n]; --len; n = (n + 1) % 16; } @@ -552,23 +563,24 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, } } -#if defined(AESNI_GCM) +#if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { - // |aesni_gcm_encrypt| may not process all the input given to it. It may + if (ctx->gcm_key.use_hw_gcm_crypt && len > 0) { + // |hw_gcm_encrypt| may not process all the input given to it. It may // not process *any* of its input if it is deemed too small. - size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + size_t bulk = hw_gcm_encrypt(in, out, len, key, ctx->Yi, ctx->Xi, + ctx->gcm_key.Htable); in += bulk; out += bulk; len -= bulk; } #endif - uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); while (len >= GHASH_CHUNK) { - (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi); ctr += GHASH_CHUNK / 16; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); GHASH(ctx, out, GHASH_CHUNK); out += GHASH_CHUNK; in += GHASH_CHUNK; @@ -578,20 +590,20 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, if (len_blocks != 0) { size_t j = len_blocks / 16; - (*stream)(in, out, j, key, ctx->Yi.c); + (*stream)(in, out, j, key, ctx->Yi); ctr += (unsigned int)j; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); in += len_blocks; len -= len_blocks; GHASH(ctx, out, len_blocks); out += len_blocks; } if (len) { - (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EKi.c, key); + (*ctx->gcm_key.block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { - ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= out[n] = in[n] ^ ctx->EKi[n]; ++n; } } @@ -604,18 +616,18 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, const uint8_t *in, uint8_t *out, size_t len, ctr128_f stream) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; - void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) = ctx->gcm_key.ghash; #endif - uint64_t mlen = ctx->len.u[1] + len; + uint64_t mlen = ctx->len.msg + len; if (mlen > ((UINT64_C(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) { return 0; } - ctx->len.u[1] = mlen; + ctx->len.msg = mlen; if (ctx->ares) { // First call to decrypt finalizes GHASH(AAD) @@ -627,8 +639,8 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, if (n) { while (n && len) { uint8_t c = *(in++); - *(out++) = c ^ ctx->EKi.c[n]; - ctx->Xi.c[n] ^= c; + *(out++) = c ^ ctx->EKi[n]; + ctx->Xi[n] ^= c; --len; n = (n + 1) % 16; } @@ -640,24 +652,25 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, } } -#if defined(AESNI_GCM) +#if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) { - // |aesni_gcm_decrypt| may not process all the input given to it. It may + if (ctx->gcm_key.use_hw_gcm_crypt && len > 0) { + // |hw_gcm_decrypt| may not process all the input given to it. It may // not process *any* of its input if it is deemed too small. - size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + size_t bulk = hw_gcm_decrypt(in, out, len, key, ctx->Yi, ctx->Xi, + ctx->gcm_key.Htable); in += bulk; out += bulk; len -= bulk; } #endif - uint32_t ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); while (len >= GHASH_CHUNK) { GHASH(ctx, in, GHASH_CHUNK); - (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi); ctr += GHASH_CHUNK / 16; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); out += GHASH_CHUNK; in += GHASH_CHUNK; len -= GHASH_CHUNK; @@ -667,21 +680,21 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, size_t j = len_blocks / 16; GHASH(ctx, in, len_blocks); - (*stream)(in, out, j, key, ctx->Yi.c); + (*stream)(in, out, j, key, ctx->Yi); ctr += (unsigned int)j; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); out += len_blocks; in += len_blocks; len -= len_blocks; } if (len) { - (*ctx->gcm_key.block)(ctx->Yi.c, ctx->EKi.c, key); + (*ctx->gcm_key.block)(ctx->Yi, ctx->EKi, key); ++ctr; - ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { uint8_t c = in[n]; - ctx->Xi.c[n] ^= c; - out[n] = c ^ ctx->EKi.c[n]; + ctx->Xi[n] ^= c; + out[n] = c ^ ctx->EKi[n]; ++n; } } @@ -692,7 +705,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = ctx->gcm_key.gmult; #endif @@ -700,15 +713,15 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { GCM_MUL(ctx, Xi); } - ctx->Xi.u[0] ^= CRYPTO_bswap8(ctx->len.u[0] << 3); - ctx->Xi.u[1] ^= CRYPTO_bswap8(ctx->len.u[1] << 3); + uint8_t len_block[16]; + CRYPTO_store_u64_be(len_block, ctx->len.aad << 3); + CRYPTO_store_u64_be(len_block + 8, ctx->len.msg << 3); + CRYPTO_xor16(ctx->Xi, ctx->Xi, len_block); GCM_MUL(ctx, Xi); - - ctx->Xi.u[0] ^= ctx->EK0.u[0]; - ctx->Xi.u[1] ^= ctx->EK0.u[1]; + CRYPTO_xor16(ctx->Xi, ctx->Xi, ctx->EK0); if (tag && len <= sizeof(ctx->Xi)) { - return CRYPTO_memcmp(ctx->Xi.c, tag, len) == 0; + return CRYPTO_memcmp(ctx->Xi, tag, len) == 0; } else { return 0; } @@ -716,16 +729,13 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) { CRYPTO_gcm128_finish(ctx, NULL, 0); - OPENSSL_memcpy(tag, ctx->Xi.c, - len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); + OPENSSL_memcpy(tag, ctx->Xi, len <= sizeof(ctx->Xi) ? len : sizeof(ctx->Xi)); } #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) int crypto_gcm_clmul_enabled(void) { #if defined(GHASH_ASM_X86) || defined(GHASH_ASM_X86_64) - const uint32_t *ia32cap = OPENSSL_ia32cap_get(); - return (ia32cap[0] & (1 << 24)) && // check FXSR bit - (ia32cap[1] & (1 << 1)); // check PCLMULQDQ bit + return CRYPTO_is_FXSR_capable() && CRYPTO_is_PCLMUL_capable(); #else return 0; #endif diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_nohw.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_nohw.c index 92d54413..4a630282 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_nohw.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_nohw.c @@ -274,31 +274,29 @@ static void gcm_polyval_nohw(uint64_t Xi[2], const u128 *H) { Xi[1] = r3; } -void gcm_gmult_nohw(uint64_t Xi[2], const u128 Htable[16]) { +void gcm_gmult_nohw(uint8_t Xi[16], const u128 Htable[16]) { uint64_t swapped[2]; - swapped[0] = CRYPTO_bswap8(Xi[1]); - swapped[1] = CRYPTO_bswap8(Xi[0]); + swapped[0] = CRYPTO_load_u64_be(Xi + 8); + swapped[1] = CRYPTO_load_u64_be(Xi); gcm_polyval_nohw(swapped, &Htable[0]); - Xi[0] = CRYPTO_bswap8(swapped[1]); - Xi[1] = CRYPTO_bswap8(swapped[0]); + CRYPTO_store_u64_be(Xi, swapped[1]); + CRYPTO_store_u64_be(Xi + 8, swapped[0]); } -void gcm_ghash_nohw(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, +void gcm_ghash_nohw(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len) { uint64_t swapped[2]; - swapped[0] = CRYPTO_bswap8(Xi[1]); - swapped[1] = CRYPTO_bswap8(Xi[0]); + swapped[0] = CRYPTO_load_u64_be(Xi + 8); + swapped[1] = CRYPTO_load_u64_be(Xi); while (len >= 16) { - uint64_t block[2]; - OPENSSL_memcpy(block, inp, 16); - swapped[0] ^= CRYPTO_bswap8(block[1]); - swapped[1] ^= CRYPTO_bswap8(block[0]); + swapped[0] ^= CRYPTO_load_u64_be(inp + 8); + swapped[1] ^= CRYPTO_load_u64_be(inp); gcm_polyval_nohw(swapped, &Htable[0]); inp += 16; len -= 16; } - Xi[0] = CRYPTO_bswap8(swapped[1]); - Xi[1] = CRYPTO_bswap8(swapped[0]); + CRYPTO_store_u64_be(Xi, swapped[1]); + CRYPTO_store_u64_be(Xi + 8, swapped[0]); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_test.cc index 02ba2d1d..b4f9b90d 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/gcm_test.cc @@ -54,8 +54,8 @@ #include #include -#include +#include "../../internal.h" #include "../../test/abi_test.h" #include "../../test/file_test.h" #include "../../test/test_util.h" @@ -129,14 +129,12 @@ TEST(GCMTest, ABI) { uint8_t buf[16 * 32]; OPENSSL_memset(buf, 42, sizeof(buf)); - uint64_t X[2] = { - UINT64_C(0x0388dace60b6a392), - UINT64_C(0xf328c2b971b2fe78), - }; + uint8_t X[16] = {0x92, 0xa3, 0xb3, 0x60, 0xce, 0xda, 0x88, 0x03, + 0x78, 0xfe, 0xb2, 0x71, 0xb9, 0xc2, 0x28, 0xf3}; alignas(16) u128 Htable[16]; #if defined(GHASH_ASM_X86) || defined(GHASH_ASM_X86_64) - if (gcm_ssse3_capable()) { + if (CRYPTO_is_SSSE3_capable()) { CHECK_ABI_SEH(gcm_init_ssse3, Htable, kH); CHECK_ABI_SEH(gcm_gmult_ssse3, X, Htable); for (size_t blocks : kBlockCounts) { @@ -152,7 +150,7 @@ TEST(GCMTest, ABI) { } #if defined(GHASH_ASM_X86_64) - if (((OPENSSL_ia32cap_get()[1] >> 22) & 0x41) == 0x41) { // AVX+MOVBE + if (CRYPTO_is_AVX_capable() && CRYPTO_is_MOVBE_capable()) { CHECK_ABI_SEH(gcm_init_avx, Htable, kH); CHECK_ABI_SEH(gcm_gmult_avx, X, Htable); for (size_t blocks : kBlockCounts) { @@ -162,28 +160,21 @@ TEST(GCMTest, ABI) { if (hwaes_capable()) { AES_KEY aes_key; static const uint8_t kKey[16] = {0}; - - // aesni_gcm_* makes assumptions about |GCM128_CONTEXT|'s layout. - GCM128_CONTEXT gcm; - memset(&gcm, 0, sizeof(gcm)); - memcpy(&gcm.gcm_key.H, kH, sizeof(kH)); - memcpy(&gcm.gcm_key.Htable, Htable, sizeof(Htable)); - memcpy(&gcm.Xi, X, sizeof(X)); uint8_t iv[16] = {0}; aes_hw_set_encrypt_key(kKey, 128, &aes_key); for (size_t blocks : kBlockCounts) { - CHECK_ABI(aesni_gcm_encrypt, buf, buf, blocks * 16, &aes_key, iv, - gcm.Xi.u); - CHECK_ABI(aesni_gcm_encrypt, buf, buf, blocks * 16 + 7, &aes_key, iv, - gcm.Xi.u); + CHECK_ABI_SEH(aesni_gcm_encrypt, buf, buf, blocks * 16, &aes_key, iv, + Htable, X); + CHECK_ABI_SEH(aesni_gcm_encrypt, buf, buf, blocks * 16 + 7, &aes_key, + iv, Htable, X); } aes_hw_set_decrypt_key(kKey, 128, &aes_key); for (size_t blocks : kBlockCounts) { - CHECK_ABI(aesni_gcm_decrypt, buf, buf, blocks * 16, &aes_key, iv, - gcm.Xi.u); - CHECK_ABI(aesni_gcm_decrypt, buf, buf, blocks * 16 + 7, &aes_key, iv, - gcm.Xi.u); + CHECK_ABI_SEH(aesni_gcm_decrypt, buf, buf, blocks * 16, &aes_key, iv, + Htable, X); + CHECK_ABI_SEH(aesni_gcm_decrypt, buf, buf, blocks * 16 + 7, &aes_key, + iv, Htable, X); } } } @@ -209,14 +200,20 @@ TEST(GCMTest, ABI) { } #endif // GHASH_ASM_ARM -#if defined(GHASH_ASM_PPC64LE) - if (CRYPTO_is_PPC64LE_vcrypto_capable()) { - CHECK_ABI(gcm_init_p8, Htable, kH); - CHECK_ABI(gcm_gmult_p8, X, Htable); - for (size_t blocks : kBlockCounts) { - CHECK_ABI(gcm_ghash_p8, X, Htable, buf, 16 * blocks); +#if defined(OPENSSL_AARCH64) && defined(HW_GCM) + if (hwaes_capable() && gcm_pmull_capable()) { + static const uint8_t kKey[16] = {0}; + uint8_t iv[16] = {0}; + + for (size_t key_bits = 128; key_bits <= 256; key_bits += 64) { + AES_KEY aes_key; + aes_hw_set_encrypt_key(kKey, key_bits, &aes_key); + CHECK_ABI(aes_gcm_enc_kernel, buf, sizeof(buf) * 8, buf, X, iv, &aes_key, + Htable); + CHECK_ABI(aes_gcm_dec_kernel, buf, sizeof(buf) * 8, buf, X, iv, &aes_key, + Htable); } } -#endif // GHASH_ASM_PPC64LE +#endif } #endif // SUPPORTS_ABI_TEST && !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/internal.h index 2fea5585..3b84015d 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/internal.h @@ -52,8 +52,8 @@ #include #include -#include +#include #include #include @@ -76,6 +76,20 @@ extern "C" { typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], const AES_KEY *key); +OPENSSL_INLINE void CRYPTO_xor16(uint8_t out[16], const uint8_t a[16], + const uint8_t b[16]) { + // TODO(davidben): Ideally we'd leave this to the compiler, which could use + // vector registers, etc. But the compiler doesn't know that |in| and |out| + // cannot partially alias. |restrict| is slightly two strict (we allow exact + // aliasing), but perhaps in-place could be a separate function? + static_assert(16 % sizeof(crypto_word_t) == 0, + "block cannot be evenly divided into words"); + for (size_t i = 0; i < 16; i += sizeof(crypto_word_t)) { + CRYPTO_store_word_le( + out + i, CRYPTO_load_word_le(a + i) ^ CRYPTO_load_word_le(b + i)); + } +} + // CTR. @@ -116,47 +130,45 @@ typedef struct { uint64_t hi,lo; } u128; // gmult_func multiplies |Xi| by the GCM key and writes the result back to // |Xi|. -typedef void (*gmult_func)(uint64_t Xi[2], const u128 Htable[16]); +typedef void (*gmult_func)(uint8_t Xi[16], const u128 Htable[16]); // ghash_func repeatedly multiplies |Xi| by the GCM key and adds in blocks from // |inp|. The result is written back to |Xi| and the |len| argument must be a // multiple of 16. -typedef void (*ghash_func)(uint64_t Xi[2], const u128 Htable[16], +typedef void (*ghash_func)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len); typedef struct gcm128_key_st { - // Note the MOVBE-based, x86-64, GHASH assembly requires |H| and |Htable| to - // be the first two elements of this struct. Additionally, some assembly - // routines require a 16-byte-aligned |Htable| when hashing data, but not + // |gcm_*_ssse3| require a 16-byte-aligned |Htable| when hashing data, but not // initialization. |GCM128_KEY| is not itself aligned to simplify embedding in // |EVP_AEAD_CTX|, but |Htable|'s offset must be a multiple of 16. - u128 H; + // TODO(crbug.com/boringssl/604): Revisit this. u128 Htable[16]; gmult_func gmult; ghash_func ghash; block128_f block; - // use_aesni_gcm_crypt is true if this context should use the assembly - // functions |aesni_gcm_encrypt| and |aesni_gcm_decrypt| to process data. - unsigned use_aesni_gcm_crypt:1; + // use_hw_gcm_crypt is true if this context should use platform-specific + // assembly to process GCM data. + unsigned use_hw_gcm_crypt:1; } GCM128_KEY; // GCM128_CONTEXT contains state for a single GCM operation. The structure // should be zero-initialized before use. typedef struct { // The following 5 names follow names in GCM specification - union { - uint64_t u[2]; - uint32_t d[4]; - uint8_t c[16]; - crypto_word_t t[16 / sizeof(crypto_word_t)]; - } Yi, EKi, EK0, len, Xi; + uint8_t Yi[16]; + uint8_t EKi[16]; + uint8_t EK0[16]; + struct { + uint64_t aad; + uint64_t msg; + } len; + uint8_t Xi[16]; - // Note that the order of |Xi| and |gcm_key| is fixed by the MOVBE-based, - // x86-64, GHASH assembly. Additionally, some assembly routines require - // |gcm_key| to be 16-byte aligned. |GCM128_KEY| is not itself aligned to - // simplify embedding in |EVP_AEAD_CTX|. + // |gcm_*_ssse3| require |Htable| to be 16-byte-aligned. + // TODO(crbug.com/boringssl/604): Revisit this. alignas(16) GCM128_KEY gcm_key; unsigned mres, ares; @@ -173,7 +185,7 @@ int crypto_gcm_clmul_enabled(void); // accelerated) functions for performing operations in the GHASH field. If the // AVX implementation was used |*out_is_avx| will be true. void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, - u128 *out_key, u128 out_table[16], int *out_is_avx, + u128 out_table[16], int *out_is_avx, const uint8_t gcm_key[16]); // CRYPTO_gcm128_init_key initialises |gcm_key| to use |block| (typically AES) @@ -241,8 +253,8 @@ OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, // GCM assembly. void gcm_init_nohw(u128 Htable[16], const uint64_t H[2]); -void gcm_gmult_nohw(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_nohw(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, +void gcm_gmult_nohw(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_nohw(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len); #if !defined(OPENSSL_NO_ASM) @@ -250,33 +262,31 @@ void gcm_ghash_nohw(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) #define GCM_FUNCREF void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_clmul(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_clmul(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, +void gcm_gmult_clmul(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_clmul(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len); -OPENSSL_INLINE char gcm_ssse3_capable(void) { - return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0; -} - // |gcm_gmult_ssse3| and |gcm_ghash_ssse3| require |Htable| to be // 16-byte-aligned, but |gcm_init_ssse3| does not. void gcm_init_ssse3(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_ssse3(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_ssse3(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, +void gcm_gmult_ssse3(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_ssse3(uint8_t Xi[16], const u128 Htable[16], const uint8_t *in, size_t len); #if defined(OPENSSL_X86_64) #define GHASH_ASM_X86_64 void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, +void gcm_gmult_avx(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_avx(uint8_t Xi[16], const u128 Htable[16], const uint8_t *in, size_t len); -#define AESNI_GCM +#define HW_GCM size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, - const AES_KEY *key, uint8_t ivec[16], uint64_t *Xi); + const AES_KEY *key, uint8_t ivec[16], + const u128 Htable[16], uint8_t Xi[16]); size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, - const AES_KEY *key, uint8_t ivec[16], uint64_t *Xi); + const AES_KEY *key, uint8_t ivec[16], + const u128 Htable[16], uint8_t Xi[16]); #endif // OPENSSL_X86_64 #if defined(OPENSSL_X86) @@ -284,6 +294,7 @@ size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, #endif // OPENSSL_X86 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + #define GHASH_ASM_ARM #define GCM_FUNCREF @@ -291,25 +302,29 @@ OPENSSL_INLINE int gcm_pmull_capable(void) { return CRYPTO_is_ARMv8_PMULL_capable(); } -void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_v8(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, +void gcm_init_v8(u128 Htable[16], const uint64_t H[2]); +void gcm_gmult_v8(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_v8(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len); OPENSSL_INLINE int gcm_neon_capable(void) { return CRYPTO_is_NEON_capable(); } -void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, +void gcm_init_neon(u128 Htable[16], const uint64_t H[2]); +void gcm_gmult_neon(uint8_t Xi[16], const u128 Htable[16]); +void gcm_ghash_neon(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, size_t len); -#elif defined(OPENSSL_PPC64LE) -#define GHASH_ASM_PPC64LE -#define GCM_FUNCREF -void gcm_init_p8(u128 Htable[16], const uint64_t Xi[2]); -void gcm_gmult_p8(uint64_t Xi[2], const u128 Htable[16]); -void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, - size_t len); +#if defined(OPENSSL_AARCH64) +#define HW_GCM +// These functions are defined in aesv8-gcm-armv8.pl. +void aes_gcm_enc_kernel(const uint8_t *in, uint64_t in_bits, void *out, + void *Xi, uint8_t *ivec, const AES_KEY *key, + const u128 Htable[16]); +void aes_gcm_dec_kernel(const uint8_t *in, uint64_t in_bits, void *out, + void *Xi, uint8_t *ivec, const AES_KEY *key, + const u128 Htable[16]); +#endif + #endif #endif // OPENSSL_NO_ASM @@ -382,19 +397,12 @@ size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len, // // POLYVAL is a polynomial authenticator that operates over a field very // similar to the one that GHASH uses. See -// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#section-3. - -typedef union { - uint64_t u[2]; - uint8_t c[16]; -} polyval_block; +// https://www.rfc-editor.org/rfc/rfc8452.html#section-3. struct polyval_ctx { - // Note that the order of |S|, |H| and |Htable| is fixed by the MOVBE-based, - // x86-64, GHASH assembly. Additionally, some assembly routines require - // |Htable| to be 16-byte aligned. - polyval_block S; - u128 H; + uint8_t S[16]; + // |gcm_*_ssse3| require |Htable| to be 16-byte-aligned. + // TODO(crbug.com/boringssl/604): Revisit this. alignas(16) u128 Htable[16]; gmult_func gmult; ghash_func ghash; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ofb.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ofb.c index 9d73d8a3..9260f2d4 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ofb.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/ofb.c @@ -46,16 +46,13 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ -#include - #include #include #include "internal.h" -OPENSSL_STATIC_ASSERT(16 % sizeof(size_t) == 0, - "block cannot be divided into size_t"); +static_assert(16 % sizeof(size_t) == 0, "block cannot be divided into size_t"); void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, uint8_t ivec[16], unsigned *num, @@ -73,14 +70,7 @@ void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, while (len >= 16) { (*block)(ivec, ivec, key); - for (; n < 16; n += sizeof(size_t)) { - size_t a, b; - OPENSSL_memcpy(&a, in + n, sizeof(size_t)); - OPENSSL_memcpy(&b, ivec + n, sizeof(size_t)); - - const size_t c = a ^ b; - OPENSSL_memcpy(out + n, &c, sizeof(size_t)); - } + CRYPTO_xor16(out, in, ivec); len -= 16; out += 16; in += 16; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/polyval.c b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/polyval.c index 857dc0e3..4e532229 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/modes/polyval.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/modes/polyval.c @@ -22,70 +22,69 @@ // byte_reverse reverses the order of the bytes in |b->c|. -static void byte_reverse(polyval_block *b) { - const uint64_t t = CRYPTO_bswap8(b->u[0]); - b->u[0] = CRYPTO_bswap8(b->u[1]); - b->u[1] = t; +static void byte_reverse(uint8_t b[16]) { + uint64_t hi = CRYPTO_load_u64_le(b); + uint64_t lo = CRYPTO_load_u64_le(b + 8); + CRYPTO_store_u64_le(b, CRYPTO_bswap8(lo)); + CRYPTO_store_u64_le(b + 8, CRYPTO_bswap8(hi)); } -// reverse_and_mulX_ghash interprets the bytes |b->c| as a reversed element of -// the GHASH field, multiplies that by 'x' and serialises the result back into -// |b|, but with GHASH's backwards bit ordering. -static void reverse_and_mulX_ghash(polyval_block *b) { - uint64_t hi = b->u[0]; - uint64_t lo = b->u[1]; +// reverse_and_mulX_ghash interprets |b| as a reversed element of the GHASH +// field, multiplies that by 'x' and serialises the result back into |b|, but +// with GHASH's backwards bit ordering. +static void reverse_and_mulX_ghash(uint8_t b[16]) { + uint64_t hi = CRYPTO_load_u64_le(b); + uint64_t lo = CRYPTO_load_u64_le(b + 8); const crypto_word_t carry = constant_time_eq_w(hi & 1, 1); hi >>= 1; hi |= lo << 63; lo >>= 1; lo ^= ((uint64_t) constant_time_select_w(carry, 0xe1, 0)) << 56; - b->u[0] = CRYPTO_bswap8(lo); - b->u[1] = CRYPTO_bswap8(hi); + CRYPTO_store_u64_le(b, CRYPTO_bswap8(lo)); + CRYPTO_store_u64_le(b + 8, CRYPTO_bswap8(hi)); } // POLYVAL(H, X_1, ..., X_n) = // ByteReverse(GHASH(mulX_GHASH(ByteReverse(H)), ByteReverse(X_1), ..., // ByteReverse(X_n))). // -// See https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#appendix-A. +// See https://www.rfc-editor.org/rfc/rfc8452.html#appendix-A. void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]) { - polyval_block H; - OPENSSL_memcpy(H.c, key, 16); - reverse_and_mulX_ghash(&H); + alignas(8) uint8_t H[16]; + OPENSSL_memcpy(H, key, 16); + reverse_and_mulX_ghash(H); int is_avx; - CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, - H.c); + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, ctx->Htable, &is_avx, H); OPENSSL_memset(&ctx->S, 0, sizeof(ctx->S)); } void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, size_t in_len) { assert((in_len & 15) == 0); - polyval_block reversed[32]; + alignas(8) uint8_t buf[32 * 16]; while (in_len > 0) { size_t todo = in_len; - if (todo > sizeof(reversed)) { - todo = sizeof(reversed); + if (todo > sizeof(buf)) { + todo = sizeof(buf); } - OPENSSL_memcpy(reversed, in, todo); + OPENSSL_memcpy(buf, in, todo); in += todo; in_len -= todo; - size_t blocks = todo / sizeof(polyval_block); + size_t blocks = todo / 16; for (size_t i = 0; i < blocks; i++) { - byte_reverse(&reversed[i]); + byte_reverse(buf + 16 * i); } - ctx->ghash(ctx->S.u, ctx->Htable, (const uint8_t *) reversed, todo); + ctx->ghash(ctx->S, ctx->Htable, buf, todo); } } void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]) { - polyval_block S = ctx->S; - byte_reverse(&S); - OPENSSL_memcpy(out, &S.c, sizeof(polyval_block)); + OPENSSL_memcpy(out, &ctx->S, 16); + byte_reverse(out); } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/policydocs/BoringCrypto-Android-Security-Policy-20210319.docx b/third_party/boringssl/kit/src/crypto/fipsmodule/policydocs/BoringCrypto-Android-Security-Policy-20210319.docx new file mode 100644 index 00000000..17fcd25f Binary files /dev/null and b/third_party/boringssl/kit/src/crypto/fipsmodule/policydocs/BoringCrypto-Android-Security-Policy-20210319.docx differ diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg.c index b2fda1da..805372fd 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg.c @@ -12,13 +12,15 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include + +#include -#include #include #include "internal.h" #include "../cipher/internal.h" +#include "../service_indicator/internal.h" // Section references in this file refer to SP 800-90Ar1: @@ -27,6 +29,21 @@ // See table 3. static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; +CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, + size_t personalization_len) { + CTR_DRBG_STATE *drbg = OPENSSL_malloc(sizeof(CTR_DRBG_STATE)); + if (drbg == NULL || + !CTR_DRBG_init(drbg, entropy, personalization, personalization_len)) { + CTR_DRBG_free(drbg); + return NULL; + } + + return drbg; +} + +void CTR_DRBG_free(CTR_DRBG_STATE *state) { OPENSSL_free(state); } + int CTR_DRBG_init(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, size_t personalization_len) { @@ -58,20 +75,20 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg, } drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); - OPENSSL_memcpy(drbg->counter.bytes, seed_material + 32, 16); + OPENSSL_memcpy(drbg->counter, seed_material + 32, 16); drbg->reseed_counter = 1; return 1; } -OPENSSL_STATIC_ASSERT(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, - "not a multiple of AES block size"); +static_assert(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, + "not a multiple of AES block size"); // ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a // big-endian number. static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { - drbg->counter.words[3] = - CRYPTO_bswap4(CRYPTO_bswap4(drbg->counter.words[3]) + n); + uint32_t ctr = CRYPTO_load_u32_be(drbg->counter + 12); + CRYPTO_store_u32_be(drbg->counter + 12, ctr + n); } static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, @@ -86,7 +103,7 @@ static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, uint8_t temp[CTR_DRBG_ENTROPY_LEN]; for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { ctr32_add(drbg, 1); - drbg->block(drbg->counter.bytes, temp + i, &drbg->ks); + drbg->block(drbg->counter, temp + i, &drbg->ks); } for (size_t i = 0; i < data_len; i++) { @@ -94,7 +111,7 @@ static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, } drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32); - OPENSSL_memcpy(drbg->counter.bytes, temp + 32, 16); + OPENSSL_memcpy(drbg->counter, temp + 32, 16); return 1; } @@ -166,12 +183,12 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, if (drbg->ctr) { OPENSSL_memset(out, 0, todo); ctr32_add(drbg, 1); - drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter.bytes); - ctr32_add(drbg, num_blocks - 1); + drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter); + ctr32_add(drbg, (uint32_t)(num_blocks - 1)); } else { for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) { ctr32_add(drbg, 1); - drbg->block(drbg->counter.bytes, out + i, &drbg->ks); + drbg->block(drbg->counter, out + i, &drbg->ks); } } @@ -182,7 +199,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, if (out_len > 0) { uint8_t block[AES_BLOCK_SIZE]; ctr32_add(drbg, 1); - drbg->block(drbg->counter.bytes, block, &drbg->ks); + drbg->block(drbg->counter, block, &drbg->ks); OPENSSL_memcpy(out, block, out_len); } @@ -194,6 +211,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, } drbg->reseed_counter++; + FIPS_service_indicator_update_state(); return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg_test.cc index 0cc48b14..50f42973 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/ctrdrbg_test.cc @@ -14,7 +14,7 @@ #include -#include +#include #include #include "internal.h" @@ -60,6 +60,16 @@ TEST(CTRDRBGTest, Basic) { CTR_DRBG_clear(&drbg); } +TEST(CTRDRBGTest, Allocated) { + const uint8_t kSeed[CTR_DRBG_ENTROPY_LEN] = {0}; + + bssl::UniquePtr allocated(CTR_DRBG_new(kSeed, nullptr, 0)); + ASSERT_TRUE(allocated); + + allocated.reset(CTR_DRBG_new(kSeed, nullptr, 1<<20)); + ASSERT_FALSE(allocated); +} + TEST(CTRDRBGTest, Large) { const uint8_t kSeed[CTR_DRBG_ENTROPY_LEN] = {0}; diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.c index 8dd2c958..5ae15445 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.c @@ -21,30 +21,30 @@ #include "fork_detect.h" #if defined(OPENSSL_LINUX) +#include #include #include #include -#include - #include "../delocate.h" #include "../../internal.h" #if defined(MADV_WIPEONFORK) -OPENSSL_STATIC_ASSERT(MADV_WIPEONFORK == 18, "MADV_WIPEONFORK is not 18"); +static_assert(MADV_WIPEONFORK == 18, "MADV_WIPEONFORK is not 18"); #else #define MADV_WIPEONFORK 18 #endif DEFINE_STATIC_ONCE(g_fork_detect_once); DEFINE_STATIC_MUTEX(g_fork_detect_lock); -DEFINE_BSS_GET(volatile char *, g_fork_detect_addr); +DEFINE_BSS_GET(CRYPTO_atomic_u32 *, g_fork_detect_addr); DEFINE_BSS_GET(uint64_t, g_fork_generation); -DEFINE_BSS_GET(int, g_ignore_madv_wipeonfork); +DEFINE_BSS_GET(int, g_force_madv_wipeonfork); +DEFINE_BSS_GET(int, g_force_madv_wipeonfork_enabled); static void init_fork_detect(void) { - if (*g_ignore_madv_wipeonfork_bss_get()) { + if (*g_force_madv_wipeonfork_bss_get()) { return; } @@ -70,7 +70,7 @@ static void init_fork_detect(void) { return; } - *((volatile char *) addr) = 1; + CRYPTO_atomic_store_u32(addr, 1); *g_fork_detect_addr_bss_get() = addr; *g_fork_generation_bss_get() = 1; } @@ -83,51 +83,61 @@ uint64_t CRYPTO_get_fork_generation(void) { // is initialised atomically, even if multiple threads enter this function // concurrently. // - // In the limit, the kernel may clear WIPEONFORK pages while a multi-threaded - // process is running. (For example, because a VM was cloned.) Therefore a - // lock is used below to synchronise the potentially multiple threads that may - // concurrently observe the cleared flag. + // Additionally, while the kernel will only clear WIPEONFORK at a point when a + // child process is single-threaded, the child may become multi-threaded + // before it observes this. Therefore, we must synchronize the logic below. CRYPTO_once(g_fork_detect_once_bss_get(), init_fork_detect); - // This pointer is |volatile| because the value pointed to may be changed by - // external forces (i.e. the kernel wiping the page) thus the compiler must - // not assume that it has exclusive access to it. - volatile char *const flag_ptr = *g_fork_detect_addr_bss_get(); + CRYPTO_atomic_u32 *const flag_ptr = *g_fork_detect_addr_bss_get(); if (flag_ptr == NULL) { - // Our kernel is too old to support |MADV_WIPEONFORK|. + // Our kernel is too old to support |MADV_WIPEONFORK| or + // |g_force_madv_wipeonfork| is set. + if (*g_force_madv_wipeonfork_bss_get() && + *g_force_madv_wipeonfork_enabled_bss_get()) { + // A constant generation number to simulate support, even if the kernel + // doesn't support it. + return 42; + } return 0; } - struct CRYPTO_STATIC_MUTEX *const lock = g_fork_detect_lock_bss_get(); + // In the common case, try to observe the flag without taking a lock. This + // avoids cacheline contention in the PRNG. uint64_t *const generation_ptr = g_fork_generation_bss_get(); - - CRYPTO_STATIC_MUTEX_lock_read(lock); - uint64_t current_generation = *generation_ptr; - if (*flag_ptr) { - CRYPTO_STATIC_MUTEX_unlock_read(lock); - return current_generation; + if (CRYPTO_atomic_load_u32(flag_ptr) != 0) { + // If we observe a non-zero flag, it is safe to read |generation_ptr| + // without a lock. The flag and generation number are fixed for this copy of + // the address space. + return *generation_ptr; } - CRYPTO_STATIC_MUTEX_unlock_read(lock); - CRYPTO_STATIC_MUTEX_lock_write(lock); - current_generation = *generation_ptr; - if (*flag_ptr == 0) { + // The flag was zero. The generation number must be incremented, but other + // threads may have concurrently observed the zero, so take a lock before + // incrementing. + CRYPTO_MUTEX *const lock = g_fork_detect_lock_bss_get(); + CRYPTO_MUTEX_lock_write(lock); + uint64_t current_generation = *generation_ptr; + if (CRYPTO_atomic_load_u32(flag_ptr) == 0) { // A fork has occurred. - *flag_ptr = 1; - current_generation++; if (current_generation == 0) { + // Zero means fork detection isn't supported, so skip that value. current_generation = 1; } + + // We must update |generation_ptr| before |flag_ptr|. Other threads may + // observe |flag_ptr| without taking a lock. *generation_ptr = current_generation; + CRYPTO_atomic_store_u32(flag_ptr, 1); } - CRYPTO_STATIC_MUTEX_unlock_write(lock); + CRYPTO_MUTEX_unlock_write(lock); return current_generation; } -void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void) { - *g_ignore_madv_wipeonfork_bss_get() = 1; +void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(int on) { + *g_force_madv_wipeonfork_bss_get() = 1; + *g_force_madv_wipeonfork_enabled_bss_get() = on; } #else // !OPENSSL_LINUX diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.h b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.h index 8518830c..f9bbe02f 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/fork_detect.h @@ -38,9 +38,10 @@ extern "C" { // should only be used as a hardening measure. OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void); -// CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing is an internal detail +// CRYPTO_fork_detect_force_madv_wipeonfork_for_testing is an internal detail // used for testing purposes. -OPENSSL_EXPORT void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void); +OPENSSL_EXPORT void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing( + int on); #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/getrandom_fillin.h b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/getrandom_fillin.h index 98718546..0f290e96 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/getrandom_fillin.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/getrandom_fillin.h @@ -30,8 +30,8 @@ #define EXPECTED_NR_getrandom 278 #elif defined(OPENSSL_ARM) #define EXPECTED_NR_getrandom 384 -#elif defined(OPENSSL_PPC64LE) -#define EXPECTED_NR_getrandom 359 +#elif defined(OPENSSL_RISCV64) +#define EXPECTED_NR_getrandom 278 #endif #if defined(EXPECTED_NR_getrandom) diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/internal.h index 127e5d1e..3c996f17 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/internal.h @@ -16,7 +16,7 @@ #define OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H #include -#include +#include #include "../../internal.h" #include "../modes/internal.h" @@ -50,10 +50,10 @@ void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, int *out_used_cpu); // RAND_load_entropy supplies |entropy_len| bytes of entropy to the module. The -// |from_cpu| parameter is true iff the entropy was obtained directly from the -// CPU. +// |want_additional_input| parameter is true iff the entropy was obtained from +// a source other than the system, e.g. directly from the CPU. void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len, - int from_cpu); + int want_additional_input); // RAND_need_entropy is implemented outside of the FIPS module and is called // when the module has stopped because it has run out of entropy. @@ -96,20 +96,13 @@ int rand_fork_unsafe_buffering_enabled(void); // CTR_DRBG_STATE contains the state of a CTR_DRBG based on AES-256. See SP // 800-90Ar1. -typedef struct { +struct ctr_drbg_state_st { AES_KEY ks; block128_f block; ctr128_f ctr; - union { - uint8_t bytes[16]; - uint32_t words[4]; - } counter; + uint8_t counter[16]; uint64_t reseed_counter; -} CTR_DRBG_STATE; - -// See SP 800-90Ar1, table 3. -#define CTR_DRBG_ENTROPY_LEN 48 -#define CTR_DRBG_MAX_GENERATE_LENGTH 65536 +}; // CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of // entropy in |entropy| and, optionally, a personalization string up to @@ -120,39 +113,17 @@ OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, const uint8_t *personalization, size_t personalization_len); -// CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy -// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of -// additional data. It returns one on success or zero on error. -OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, - const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], - const uint8_t *additional_data, - size_t additional_data_len); - -// CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional -// data (if any) and then writes |out_len| random bytes to |out|, where -// |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or -// zero on error. -OPENSSL_EXPORT int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, - size_t out_len, - const uint8_t *additional_data, - size_t additional_data_len); - -// CTR_DRBG_clear zeroises the state of |drbg|. -OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); - - #if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) OPENSSL_INLINE int have_rdrand(void) { - return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0; + return CRYPTO_is_RDRAND_capable(); } // have_fast_rdrand returns true if RDRAND is supported and it's reasonably // fast. Concretely the latter is defined by whether the chip is Intel (fast) or // not (assumed slow). OPENSSL_INLINE int have_fast_rdrand(void) { - const uint32_t *const ia32cap = OPENSSL_ia32cap_get(); - return (ia32cap[1] & (1u << 30)) && (ia32cap[0] & (1u << 30)); + return CRYPTO_is_RDRAND_capable() && CRYPTO_is_intel_cpu(); } // CRYPTO_rdrand writes eight bytes of random data from the hardware RNG to diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/rand.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/rand.c index 0fc9fa17..04ea8a3b 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/rand.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/rand.c @@ -23,9 +23,8 @@ #endif #include -#include +#include #include -#include #include "internal.h" #include "fork_detect.h" @@ -66,6 +65,9 @@ struct rand_thread_state { // last_block_valid is non-zero iff |last_block| contains data from // |get_seed_entropy|. int last_block_valid; + // fork_unsafe_buffering is non-zero iff, when |drbg| was last (re)seeded, + // fork-unsafe buffering was enabled. + int fork_unsafe_buffering; #if defined(BORINGSSL_FIPS) // last_block contains the previous block from |get_seed_entropy|. @@ -73,6 +75,10 @@ struct rand_thread_state { // next and prev form a NULL-terminated, double-linked list of all states in // a process. struct rand_thread_state *next, *prev; + // clear_drbg_lock synchronizes between uses of |drbg| and + // |rand_thread_state_clear_all| clearing it. This lock should be uncontended + // in the common case, except on shutdown. + CRYPTO_MUTEX clear_drbg_lock; #endif }; @@ -83,18 +89,19 @@ struct rand_thread_state { // called when the whole process is exiting. DEFINE_BSS_GET(struct rand_thread_state *, thread_states_list); DEFINE_STATIC_MUTEX(thread_states_list_lock); -DEFINE_STATIC_MUTEX(state_clear_all_lock); static void rand_thread_state_clear_all(void) __attribute__((destructor)); static void rand_thread_state_clear_all(void) { - CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); - CRYPTO_STATIC_MUTEX_lock_write(state_clear_all_lock_bss_get()); + CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get()); for (struct rand_thread_state *cur = *thread_states_list_bss_get(); cur != NULL; cur = cur->next) { + CRYPTO_MUTEX_lock_write(&cur->clear_drbg_lock); CTR_DRBG_clear(&cur->drbg); } // The locks are deliberately left locked so that any threads that are still - // running will hang if they try to call |RAND_bytes|. + // running will hang if they try to call |RAND_bytes|. It also ensures + // |rand_thread_state_free| cannot free any thread state while we've taken the + // lock. } #endif @@ -108,7 +115,7 @@ static void rand_thread_state_free(void *state_in) { } #if defined(BORINGSSL_FIPS) - CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get()); if (state->prev != NULL) { state->prev->next = state->next; @@ -120,7 +127,7 @@ static void rand_thread_state_free(void *state_in) { state->next->prev = state->prev; } - CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + CRYPTO_MUTEX_unlock_write(thread_states_list_lock_bss_get()); CTR_DRBG_clear(&state->drbg); #endif @@ -163,19 +170,13 @@ static int rdrand(uint8_t *buf, size_t len) { #if defined(BORINGSSL_FIPS) void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, - int *out_used_cpu) { - *out_used_cpu = 0; + int *out_want_additional_input) { + *out_want_additional_input = 0; if (have_rdrand() && rdrand(out_entropy, out_entropy_len)) { - *out_used_cpu = 1; + *out_want_additional_input = 1; } else { CRYPTO_sysrand_for_seed(out_entropy, out_entropy_len); } - -#if defined(BORINGSSL_FIPS_BREAK_CRNG) - // This breaks the "continuous random number generator test" defined in FIPS - // 140-2, section 4.9.2, and implemented in |rand_get_seed|. - OPENSSL_memset(out_entropy, 0, out_entropy_len); -#endif } // In passive entropy mode, entropy is supplied from outside of the module via @@ -184,23 +185,25 @@ void CRYPTO_get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, struct entropy_buffer { // bytes contains entropy suitable for seeding a DRBG. - uint8_t bytes[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t + bytes[CRNGT_BLOCK_SIZE + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; // bytes_valid indicates the number of bytes of |bytes| that contain valid // data. size_t bytes_valid; - // from_cpu is true if any of the contents of |bytes| were obtained directly - // from the CPU. - int from_cpu; + // want_additional_input is true if any of the contents of |bytes| were + // obtained via a method other than from the kernel. In these cases entropy + // from the kernel is also provided via an additional input to the DRBG. + int want_additional_input; }; DEFINE_BSS_GET(struct entropy_buffer, entropy_buffer); DEFINE_STATIC_MUTEX(entropy_buffer_lock); void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len, - int from_cpu) { + int want_additional_input) { struct entropy_buffer *const buffer = entropy_buffer_bss_get(); - CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get()); const size_t space = sizeof(buffer->bytes) - buffer->bytes_valid; if (entropy_len > space) { entropy_len = space; @@ -208,73 +211,87 @@ void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len, OPENSSL_memcpy(&buffer->bytes[buffer->bytes_valid], entropy, entropy_len); buffer->bytes_valid += entropy_len; - buffer->from_cpu |= from_cpu && (entropy_len != 0); - CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); + buffer->want_additional_input |= + want_additional_input && (entropy_len != 0); + CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); } // get_seed_entropy fills |out_entropy_len| bytes of |out_entropy| from the // global |entropy_buffer|. static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, - int *out_used_cpu) { + int *out_want_additional_input) { struct entropy_buffer *const buffer = entropy_buffer_bss_get(); if (out_entropy_len > sizeof(buffer->bytes)) { abort(); } - CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get()); while (buffer->bytes_valid < out_entropy_len) { - CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); + CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); RAND_need_entropy(out_entropy_len - buffer->bytes_valid); - CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get()); + CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get()); } - *out_used_cpu = buffer->from_cpu; + *out_want_additional_input = buffer->want_additional_input; OPENSSL_memcpy(out_entropy, buffer->bytes, out_entropy_len); OPENSSL_memmove(buffer->bytes, &buffer->bytes[out_entropy_len], buffer->bytes_valid - out_entropy_len); buffer->bytes_valid -= out_entropy_len; if (buffer->bytes_valid == 0) { - buffer->from_cpu = 0; + buffer->want_additional_input = 0; } - CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); + CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get()); } -// rand_get_seed fills |seed| with entropy and sets |*out_used_cpu| to one if -// that entropy came directly from the CPU and zero otherwise. +// rand_get_seed fills |seed| with entropy. In some cases, it will additionally +// fill |additional_input| with entropy to supplement |seed|. It sets +// |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, uint8_t seed[CTR_DRBG_ENTROPY_LEN], - int *out_used_cpu) { - if (!state->last_block_valid) { - int unused; - get_seed_entropy(state->last_block, sizeof(state->last_block), &unused); - state->last_block_valid = 1; + uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + size_t *out_additional_input_len) { + uint8_t entropy_bytes[sizeof(state->last_block) + + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t *entropy = entropy_bytes; + size_t entropy_len = sizeof(entropy_bytes); + + if (state->last_block_valid) { + // No need to fill |state->last_block| with entropy from the read. + entropy += sizeof(state->last_block); + entropy_len -= sizeof(state->last_block); } - uint8_t entropy[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; - get_seed_entropy(entropy, sizeof(entropy), out_used_cpu); + int want_additional_input; + get_seed_entropy(entropy, entropy_len, &want_additional_input); + + if (!state->last_block_valid) { + OPENSSL_memcpy(state->last_block, entropy, sizeof(state->last_block)); + entropy += sizeof(state->last_block); + entropy_len -= sizeof(state->last_block); + } // See FIPS 140-2, section 4.9.2. This is the “continuous random number // generator test” which causes the program to randomly abort. Hopefully the // rate of failure is small enough not to be a problem in practice. - if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) { + if (CRYPTO_memcmp(state->last_block, entropy, sizeof(state->last_block)) == + 0) { fprintf(stderr, "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } - OPENSSL_STATIC_ASSERT(sizeof(entropy) % CRNGT_BLOCK_SIZE == 0, ""); - for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy); - i += CRNGT_BLOCK_SIZE) { + assert(entropy_len % CRNGT_BLOCK_SIZE == 0); + for (size_t i = CRNGT_BLOCK_SIZE; i < entropy_len; i += CRNGT_BLOCK_SIZE) { if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, CRNGT_BLOCK_SIZE) == 0) { fprintf(stderr, "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } } - OPENSSL_memcpy(state->last_block, - entropy + sizeof(entropy) - CRNGT_BLOCK_SIZE, + OPENSSL_memcpy(state->last_block, entropy + entropy_len - CRNGT_BLOCK_SIZE, CRNGT_BLOCK_SIZE); + assert(entropy_len == BORINGSSL_FIPS_OVERREAD * CTR_DRBG_ENTROPY_LEN); OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); for (size_t i = 1; i < BORINGSSL_FIPS_OVERREAD; i++) { @@ -282,19 +299,30 @@ static void rand_get_seed(struct rand_thread_state *state, seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; } } + + // If we used something other than system entropy then also + // opportunistically read from the system. This avoids solely relying on the + // hardware once the entropy pool has been initialized. + *out_additional_input_len = 0; + if (want_additional_input && + CRYPTO_sysrand_if_available(additional_input, CTR_DRBG_ENTROPY_LEN)) { + *out_additional_input_len = CTR_DRBG_ENTROPY_LEN; + } } #else -// rand_get_seed fills |seed| with entropy and sets |*out_used_cpu| to one if -// that entropy came directly from the CPU and zero otherwise. +// rand_get_seed fills |seed| with entropy. In some cases, it will additionally +// fill |additional_input| with entropy to supplement |seed|. It sets +// |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, uint8_t seed[CTR_DRBG_ENTROPY_LEN], - int *out_used_cpu) { + uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + size_t *out_additional_input_len) { // If not in FIPS mode, we don't overread from the system entropy source and // we don't depend only on the hardware RDRAND. CRYPTO_sysrand_for_seed(seed, CTR_DRBG_ENTROPY_LEN); - *out_used_cpu = 0; + *out_additional_input_len = 0; } #endif @@ -306,6 +334,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, } const uint64_t fork_generation = CRYPTO_get_fork_generation(); + const int fork_unsafe_buffering = rand_fork_unsafe_buffering_enabled(); // Additional data is mixed into every CTR-DRBG call to protect, as best we // can, against forks & VM clones. We do not over-read this information and @@ -320,7 +349,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, // entropy is used. This can be expensive (one read per |RAND_bytes| call) // and so is disabled when we have fork detection, or if the application has // promised not to fork. - if (fork_generation != 0 || rand_fork_unsafe_buffering_enabled()) { + if (fork_generation != 0 || fork_unsafe_buffering) { OPENSSL_memset(additional_data, 0, sizeof(additional_data)); } else if (!have_rdrand()) { // No alternative so block for OS entropy. @@ -353,20 +382,9 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, state->last_block_valid = 0; uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - int used_cpu; - rand_get_seed(state, seed, &used_cpu); - uint8_t personalization[CTR_DRBG_ENTROPY_LEN] = {0}; size_t personalization_len = 0; -#if defined(OPENSSL_URANDOM) - // If we used RDRAND, also opportunistically read from the system. This - // avoids solely relying on the hardware once the entropy pool has been - // initialized. - if (used_cpu && - CRYPTO_sysrand_if_available(personalization, sizeof(personalization))) { - personalization_len = sizeof(personalization); - } -#endif + rand_get_seed(state, seed, personalization, &personalization_len); if (!CTR_DRBG_init(&state->drbg, seed, personalization, personalization_len)) { @@ -374,10 +392,12 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, } state->calls = 0; state->fork_generation = fork_generation; + state->fork_unsafe_buffering = fork_unsafe_buffering; #if defined(BORINGSSL_FIPS) + CRYPTO_MUTEX_init(&state->clear_drbg_lock); if (state != &stack_state) { - CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get()); struct rand_thread_state **states_list = thread_states_list_bss_get(); state->next = *states_list; if (state->next != NULL) { @@ -385,35 +405,41 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, } state->prev = NULL; *states_list = state; - CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + CRYPTO_MUTEX_unlock_write(thread_states_list_lock_bss_get()); } #endif } if (state->calls >= kReseedInterval || - state->fork_generation != fork_generation) { + // If we've forked since |state| was last seeded, reseed. + state->fork_generation != fork_generation || + // If |state| was seeded from a state with different fork-safety + // preferences, reseed. Suppose |state| was fork-safe, then forked into + // two children, but each of the children never fork and disable fork + // safety. The children must reseed to avoid working from the same PRNG + // state. + state->fork_unsafe_buffering != fork_unsafe_buffering) { uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - int used_cpu; - rand_get_seed(state, seed, &used_cpu); + uint8_t reseed_additional_data[CTR_DRBG_ENTROPY_LEN] = {0}; + size_t reseed_additional_data_len = 0; + rand_get_seed(state, seed, reseed_additional_data, + &reseed_additional_data_len); #if defined(BORINGSSL_FIPS) // Take a read lock around accesses to |state->drbg|. This is needed to // avoid returning bad entropy if we race with // |rand_thread_state_clear_all|. - // - // This lock must be taken after any calls to |CRYPTO_sysrand| to avoid a - // bug on ppc64le. glibc may implement pthread locks by wrapping user code - // in a hardware transaction, but, on some older versions of glibc and the - // kernel, syscalls made with |syscall| did not abort the transaction. - CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get()); + CRYPTO_MUTEX_lock_read(&state->clear_drbg_lock); #endif - if (!CTR_DRBG_reseed(&state->drbg, seed, NULL, 0)) { + if (!CTR_DRBG_reseed(&state->drbg, seed, reseed_additional_data, + reseed_additional_data_len)) { abort(); } state->calls = 0; state->fork_generation = fork_generation; + state->fork_unsafe_buffering = fork_unsafe_buffering; } else { #if defined(BORINGSSL_FIPS) - CRYPTO_STATIC_MUTEX_lock_read(state_clear_all_lock_bss_get()); + CRYPTO_MUTEX_lock_read(&state->clear_drbg_lock); #endif } @@ -442,7 +468,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, } #if defined(BORINGSSL_FIPS) - CRYPTO_STATIC_MUTEX_unlock_read(state_clear_all_lock_bss_get()); + CRYPTO_MUTEX_unlock_read(&state->clear_drbg_lock); #endif } @@ -455,3 +481,10 @@ int RAND_bytes(uint8_t *out, size_t out_len) { int RAND_pseudo_bytes(uint8_t *buf, size_t len) { return RAND_bytes(buf, len); } + +void RAND_get_system_entropy_for_custom_prng(uint8_t *buf, size_t len) { + if (len > 256) { + abort(); + } + CRYPTO_sysrand_for_seed(buf, len); +} diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom.c index fa0a3337..a3fb15b1 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom.c @@ -59,17 +59,20 @@ #endif // OPENSSL_LINUX #if defined(OPENSSL_MACOS) +// getentropy exists in any supported version of MacOS (Sierra and later) #include #endif -#if defined(OPENSSL_FREEBSD) -#define URANDOM_BLOCKS_FOR_ENTROPY -#if __FreeBSD__ >= 12 +#if defined(OPENSSL_OPENBSD) +// getentropy exists in any supported version of OpenBSD +#include +#endif + +#if defined(OPENSSL_FREEBSD) && __FreeBSD__ >= 12 // getrandom is supported in FreeBSD 12 and up. #define FREEBSD_GETRANDOM #include #endif -#endif #include #include @@ -135,7 +138,7 @@ static void maybe_set_extra_getrandom_flags(void) { } value[length] = 0; - if (strcasecmp(value, "true") == 0) { + if (OPENSSL_strcasecmp(value, "true") == 0) { *extra_getrandom_flags_for_seed_bss_get() = GRND_RANDOM; } #endif @@ -176,29 +179,26 @@ static void init_once(void) { } #endif // USE_NR_getrandom -#if defined(OPENSSL_MACOS) - // getentropy is available in macOS 10.12 and up. iOS 10 and up may also - // support it, but the header is missing. See https://crbug.com/boringssl/287. - if (__builtin_available(macos 10.12, *)) { +#if defined(OPENSSL_MACOS) || defined(OPENSSL_OPENBSD) || defined(FREEBSD_GETRANDOM) *urandom_fd_bss_get() = kHaveGetrandom; return; - } #endif -#if defined(FREEBSD_GETRANDOM) - *urandom_fd_bss_get() = kHaveGetrandom; - return; -#endif - - // Android FIPS builds must support getrandom. -#if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID) + // FIPS builds must support getrandom. + // + // Historically, only Android FIPS builds required getrandom, while Linux FIPS + // builds had a /dev/urandom fallback which used RNDGETENTCNT as a poor + // approximation for getrandom's blocking behavior. This is now removed, but + // avoid making assumptions on this removal until March 2023, in case it needs + // to be restored. This comment can be deleted after March 2023. +#if defined(BORINGSSL_FIPS) perror("getrandom not found"); abort(); #endif int fd; do { - fd = open("/dev/urandom", O_RDONLY); + fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); } while (fd == -1 && errno == EINTR); if (fd < 0) { @@ -206,20 +206,6 @@ static void init_once(void) { abort(); } - int flags = fcntl(fd, F_GETFD); - if (flags == -1) { - // Native Client doesn't implement |fcntl|. - if (errno != ENOSYS) { - perror("failed to get flags from urandom fd"); - abort(); - } - } else { - flags |= FD_CLOEXEC; - if (fcntl(fd, F_SETFD, flags) == -1) { - perror("failed to set FD_CLOEXEC on urandom fd"); - abort(); - } - } *urandom_fd_bss_get() = fd; } @@ -269,29 +255,6 @@ static void wait_for_entropy(void) { #endif // USE_NR_getrandom return; } - -#if defined(BORINGSSL_FIPS) && !defined(URANDOM_BLOCKS_FOR_ENTROPY) - // In FIPS mode on platforms where urandom doesn't block at startup, we ensure - // that the kernel has sufficient entropy before continuing. This is - // automatically handled by getrandom, which requires that the entropy pool - // has been initialised, but for urandom we have to poll. - for (;;) { - int entropy_bits; - if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { - fprintf(stderr, - "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " - "case when in FIPS mode.\n"); - abort(); - } - - static const int kBitsNeeded = 256; - if (entropy_bits >= kBitsNeeded) { - break; - } - - usleep(250000); - } -#endif // BORINGSSL_FIPS && !URANDOM_BLOCKS_FOR_ENTROPY } // fill_with_entropy writes |len| bytes of entropy into |out|. It returns one @@ -334,19 +297,10 @@ static int fill_with_entropy(uint8_t *out, size_t len, int block, int seed) { r = boringssl_getrandom(out, len, getrandom_flags); #elif defined(FREEBSD_GETRANDOM) r = getrandom(out, len, getrandom_flags); -#elif defined(OPENSSL_MACOS) - if (__builtin_available(macos 10.12, *)) { - // |getentropy| can only request 256 bytes at a time. - size_t todo = len <= 256 ? len : 256; - if (getentropy(out, todo) != 0) { - r = -1; - } else { - r = (ssize_t)todo; - } - } else { - fprintf(stderr, "urandom fd corrupt.\n"); - abort(); - } +#elif defined(OPENSSL_MACOS) || defined(OPENSSL_OPENBSD) + // |getentropy| can only request 256 bytes at a time. + size_t todo = len <= 256 ? len : 256; + r = getentropy(out, todo) != 0 ? -1 : (ssize_t)todo; #else // USE_NR_getrandom fprintf(stderr, "urandom fd corrupt.\n"); abort(); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom_test.cc index b9e90075..f92fe948 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom_test.cc +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rand/urandom_test.cc @@ -15,25 +15,50 @@ #include #include +#include +#include #include -#include "internal.h" #include "getrandom_fillin.h" +#include "internal.h" -#if defined(OPENSSL_X86_64) && !defined(BORINGSSL_SHARED_LIBRARY) && \ - !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && defined(USE_NR_getrandom) +#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ + !defined(BORINGSSL_SHARED_LIBRARY) && \ + defined(OPENSSL_URANDOM) && defined(USE_NR_getrandom) +#include #include #include +#include #include +#include +#include #include #include "fork_detect.h" +#include "getrandom_fillin.h" #if !defined(PTRACE_O_EXITKILL) #define PTRACE_O_EXITKILL (1 << 20) #endif +#if defined(OPENSSL_ANDROID) +static const bool kIsAndroid = true; +#else +static const bool kIsAndroid = false; +#endif + +#if defined(BORINGSSL_FIPS) +static const bool kIsFIPS = true; +#else +static const bool kIsFIPS = false; +#endif + +static const bool kUsesDaemon = kIsFIPS && kIsAndroid; + +// kDaemonWriteLength is the number of bytes that the entropy daemon writes. +static const size_t kDaemonWriteLength = 496; + // This test can be run with $OPENSSL_ia32cap=~0x4000000000000000 in order to // simulate the absence of RDRAND of machines that have it. @@ -44,7 +69,10 @@ struct Event { kGetRandom, kOpen, kUrandomRead, - kUrandomIoctl, + kSocket, + kConnect, + kSocketRead, + kSocketClose, kAbort, }; @@ -53,8 +81,7 @@ struct Event { bool operator==(const Event &other) const { return type == other.type && length == other.length && flags == other.flags && - ((filename == nullptr && other.filename == nullptr) || - strcmp(filename, other.filename) == 0); + filename == other.filename; } static Event GetRandom(size_t length, unsigned flags) { @@ -64,7 +91,7 @@ struct Event { return e; } - static Event Open(const char *filename) { + static Event Open(const std::string &filename) { Event e(Syscall::kOpen); e.filename = filename; return e; @@ -76,8 +103,24 @@ struct Event { return e; } - static Event UrandomIoctl() { - Event e(Syscall::kUrandomIoctl); + static Event Socket() { + Event e(Syscall::kSocket); + return e; + } + + static Event Connect() { + Event e(Syscall::kConnect); + return e; + } + + static Event SocketRead(size_t length) { + Event e(Syscall::kSocketRead); + e.length = length; + return e; + } + + static Event SocketClose() { + Event e(Syscall::kSocketClose); return e; } @@ -91,19 +134,29 @@ struct Event { switch (type) { case Syscall::kGetRandom: - snprintf(buf, sizeof(buf), "getrandom(_, %zu, %d)", length, flags); + snprintf(buf, sizeof(buf), "getrandom(_, %zu, %u)", length, flags); break; case Syscall::kOpen: - snprintf(buf, sizeof(buf), "open(%s, _)", filename); + snprintf(buf, sizeof(buf), "open(%s, _)", filename.c_str()); break; case Syscall::kUrandomRead: snprintf(buf, sizeof(buf), "read(urandom_fd, _, %zu)", length); break; - case Syscall::kUrandomIoctl: - return "ioctl(urandom_fd, RNDGETENTCNT, _)"; + case Syscall::kSocket: + return "socket(UNIX, STREAM, _)"; + + case Syscall::kConnect: + return "connect(sock, _, _)"; + + case Syscall::kSocketRead: + snprintf(buf, sizeof(buf), "read(sock_fd, _, %zu)", length); + break; + + case Syscall::kSocketClose: + return "close(sock)"; case Syscall::kAbort: return "abort()"; @@ -115,7 +168,7 @@ struct Event { const Syscall type; size_t length = 0; unsigned flags = 0; - const char *filename = nullptr; + std::string filename; }; static std::string ToString(const std::vector &trace) { @@ -138,14 +191,217 @@ static const unsigned NO_GETRANDOM = 1; static const unsigned NO_URANDOM = 2; // getrandom always returns |EAGAIN| if given |GRNG_NONBLOCK|. static const unsigned GETRANDOM_NOT_READY = 4; -// The ioctl on urandom returns only 255 bits of entropy the first time that -// it's called. -static const unsigned URANDOM_NOT_READY = 8; // getrandom gives |EINVAL| unless |NO_GETRANDOM| is set. -static const unsigned GETRANDOM_ERROR = 16; +static const unsigned GETRANDOM_ERROR = 8; // Reading from /dev/urandom gives |EINVAL|. -static const unsigned URANDOM_ERROR = 32; -static const unsigned NEXT_FLAG = 64; +static const unsigned URANDOM_ERROR = 16; +static const unsigned SOCKET_ERROR = 32; +static const unsigned CONNECT_ERROR = 64; +static const unsigned SOCKET_READ_ERROR = 128; +static const unsigned SOCKET_READ_SHORT = 256; +static const unsigned NEXT_FLAG = 512; + +// regs_read fetches the registers of |child_pid| and writes them to |out_regs|. +// That structure will contain at least the following members: +// syscall: the syscall number, if registers were read just before entering +// one. +// args[0..2]: syscall arguments, if registers were read just before +// entering one. +// ret: the syscall return value, if registers were read just after finishing +// one. +// +// This call returns true on success and false otherwise. +static bool regs_read(struct regs *out_regs, int child_pid); + +// regs_set_ret sets the return value of the system call that |child_pid| has +// just finished, to |ret|. It returns true on success and false otherwise. +static bool regs_set_ret(int child_pid, int ret); + +// regs_break_syscall causes the system call that |child_pid| is about to enter +// to fail to run. +static bool regs_break_syscall(int child_pid, const struct regs *orig_regs); + +struct regs { + uintptr_t syscall; + uintptr_t args[3]; + uintptr_t ret; + struct user_regs_struct regs; +}; + +#if defined(OPENSSL_X86_64) + +static bool regs_read(struct regs *out_regs, int child_pid) { + if (ptrace(PTRACE_GETREGS, child_pid, nullptr, &out_regs->regs) != 0) { + return false; + } + + out_regs->syscall = out_regs->regs.orig_rax; + out_regs->ret = out_regs->regs.rax; + out_regs->args[0] = out_regs->regs.rdi; + out_regs->args[1] = out_regs->regs.rsi; + out_regs->args[2] = out_regs->regs.rdx; + return true; +} + +static bool regs_set_ret(int child_pid, int ret) { + struct regs regs; + if (!regs_read(®s, child_pid)) { + return false; + } + regs.regs.rax = ret; + return ptrace(PTRACE_SETREGS, child_pid, nullptr, ®s.regs) == 0; +} + +static bool regs_break_syscall(int child_pid, const struct regs *orig_regs) { + // Replace the syscall number with -1 to cause the kernel to fail the call. + struct user_regs_struct regs = orig_regs->regs; + regs.orig_rax = -1; + return ptrace(PTRACE_SETREGS, child_pid, nullptr, ®s) == 0; +} + +#elif defined(OPENSSL_AARCH64) + +static bool regs_read(struct regs *out_regs, int child_pid) { + struct iovec io; + io.iov_base = &out_regs->regs; + io.iov_len = sizeof(out_regs->regs); + if (ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &io) != 0) { + return false; + } + + out_regs->syscall = out_regs->regs.regs[8]; + out_regs->ret = out_regs->regs.regs[0]; + out_regs->args[0] = out_regs->regs.regs[0]; + out_regs->args[1] = out_regs->regs.regs[1]; + out_regs->args[2] = out_regs->regs.regs[2]; + + return true; +} + +static bool set_regset(int child_pid, int regset, const void *data, + size_t len) { + struct iovec io; + io.iov_base = const_cast(data); + io.iov_len = len; + return ptrace(PTRACE_SETREGSET, child_pid, reinterpret_cast(regset), + &io) == 0; +} + +static bool regs_set_ret(int child_pid, int ret) { + struct regs regs; + if (!regs_read(®s, child_pid)) { + return false; + } + regs.regs.regs[0] = ret; + return set_regset(child_pid, NT_PRSTATUS, ®s.regs, sizeof(regs.regs)); +} + +static bool regs_break_syscall(int child_pid, const struct regs *orig_regs) { + // Replace the syscall number with -1 to cause the kernel to fail the call. + int syscall = -1; + return set_regset(child_pid, NT_ARM_SYSTEM_CALL, &syscall, sizeof(syscall)); +} + +#endif + +// SyscallResult is like std::optional. +// TODO: use std::optional when we can use C++17. +class SyscallResult { + public: + SyscallResult &operator=(int value) { + has_value_ = true; + value_ = value; + return *this; + } + + int value() const { + if (!has_value_) { + abort(); + } + return value_; + } + + bool has_value() const { return has_value_; } + + private: + bool has_value_ = false; + int value_ = 0; +}; + +// memcpy_to_remote copies |n| bytes from |in_src| in the local address space, +// to |dest| in the address space of |child_pid|. +static void memcpy_to_remote(int child_pid, uint64_t dest, const void *in_src, + size_t n) { + const uint8_t *src = reinterpret_cast(in_src); + + // ptrace always works with ill-defined "words", which appear to be 64-bit + // on 64-bit systems. +#if !defined(OPENSSL_64_BIT) +#error "This code probably doesn't work" +#endif + + while (n) { + const uintptr_t aligned_addr = dest & ~7; + const uintptr_t offset = dest - aligned_addr; + const size_t space = 8 - offset; + size_t todo = n; + if (todo > space) { + todo = space; + } + + uint64_t word; + if (offset == 0 && todo == 8) { + word = CRYPTO_load_u64_le(src); + } else { + uint8_t bytes[8]; + CRYPTO_store_u64_le( + bytes, ptrace(PTRACE_PEEKDATA, child_pid, + reinterpret_cast(aligned_addr), nullptr)); + memcpy(&bytes[offset], src, todo); + word = CRYPTO_load_u64_le(bytes); + } + + ASSERT_EQ(0, ptrace(PTRACE_POKEDATA, child_pid, + reinterpret_cast(aligned_addr), + reinterpret_cast(word))); + + src += todo; + n -= todo; + dest += todo; + } +} + +static uint8_t get_byte_from_remote(int child_pid, uint64_t ptr) { + // ptrace always works with ill-defined "words", which appear to be 64-bit + // on 64-bit systems. +#if !defined(OPENSSL_64_BIT) +#error "This code probably doesn't work" +#endif + + const uintptr_t aligned_addr = ptr & ~7; + const uintptr_t offset = ptr - aligned_addr; + + uint64_t word = ptrace(PTRACE_PEEKDATA, child_pid, + reinterpret_cast(aligned_addr), 0); + uint8_t bytes[8]; + CRYPTO_store_u64_le(bytes, word); + return bytes[offset]; +} + +static std::string get_string_from_remote(int child_pid, uint64_t ptr) { + std::string ret; + + for (;;) { + const uint8_t byte = get_byte_from_remote(child_pid, ptr); + if (byte == 0) { + break; + } + ret.push_back((char)byte); + ptr++; + } + + return ret; +} // GetTrace runs |thunk| in a forked process and observes the resulting system // calls using ptrace. It simulates a variety of failures based on the contents @@ -169,7 +425,8 @@ static void GetTrace(std::vector *out_trace, unsigned flags, // Parent process int status; ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); - ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP); + ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP) + << "Child was not stopped with SIGSTOP: " << status; // Set options so that: // a) the child process is killed once this process dies. @@ -184,6 +441,10 @@ static void GetTrace(std::vector *out_trace, unsigned flags, // process, if it opens it. int urandom_fd = -1; + // sock_fd tracks the file descriptor number for the socket to the entropy + // daemon, if one is opened. + int sock_fd = -1; + for (;;) { // Advance the child to the next system call. ASSERT_EQ(0, ptrace(PTRACE_SYSCALL, child_pid, 0, 0)); @@ -196,78 +457,123 @@ static void GetTrace(std::vector *out_trace, unsigned flags, } // Otherwise the only valid ptrace event is a system call stop. - ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80)); + ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80)) + << "Child was not stopped with a syscall stop: " << status; - struct user_regs_struct regs; - ASSERT_EQ(0, ptrace(PTRACE_GETREGS, child_pid, nullptr, ®s)); - const auto syscall_number = regs.orig_rax; + struct regs regs; + ASSERT_TRUE(regs_read(®s, child_pid)); bool is_opening_urandom = false; - bool is_urandom_ioctl = false; - uintptr_t ioctl_output_addr = 0; - // inject_error is zero to indicate that the system call should run + bool is_socket_call = false; + bool is_socket_read = false; + uint64_t socket_read_bytes = 0; + // force_result is unset to indicate that the system call should run // normally. Otherwise it's, e.g. -EINVAL, to indicate that the system call - // should not run and that error should be injected on return. - int inject_error = 0; + // should not run and that the given value should be injected on return. + SyscallResult force_result; - switch (syscall_number) { + switch (regs.syscall) { case __NR_getrandom: if (flags & NO_GETRANDOM) { - inject_error = -ENOSYS; + force_result = -ENOSYS; } else if (flags & GETRANDOM_ERROR) { - inject_error = -EINVAL; + force_result = -EINVAL; } else if (flags & GETRANDOM_NOT_READY) { - if (regs.rdx & GRND_NONBLOCK) { - inject_error = -EAGAIN; + if (regs.args[2] & GRND_NONBLOCK) { + force_result = -EAGAIN; } } out_trace->push_back( - Event::GetRandom(/*length=*/regs.rsi, /*flags=*/regs.rdx)); + Event::GetRandom(/*length=*/regs.args[1], /*flags=*/regs.args[2])); break; case __NR_openat: - case __NR_open: { - // It's assumed that any arguments to open(2) are constants in read-only - // memory and thus the pointer in the child's context will also be a - // valid pointer in our address space. - const char *filename = reinterpret_cast( - (syscall_number == __NR_openat) ? regs.rsi : regs.rdi); - out_trace->push_back(Event::Open(filename)); - is_opening_urandom = strcmp(filename, "/dev/urandom") == 0; +#if defined(OPENSSL_X86_64) + case __NR_open: +#endif + { + uintptr_t filename_ptr = + (regs.syscall == __NR_openat) ? regs.args[1] : regs.args[0]; + const std::string filename = get_string_from_remote(child_pid, filename_ptr); + if (filename.find("/dev/__properties__/") == 0) { + // Android may try opening these files as part of SELinux support. + // They are ignored here. + } else { + out_trace->push_back(Event::Open(filename)); + } + is_opening_urandom = (filename == "/dev/urandom"); if (is_opening_urandom && (flags & NO_URANDOM)) { - inject_error = -ENOENT; + force_result = -ENOENT; } break; } case __NR_read: { - const int read_fd = regs.rdi; + const int read_fd = regs.args[0]; if (urandom_fd >= 0 && urandom_fd == read_fd) { - out_trace->push_back(Event::UrandomRead(/*length=*/regs.rdx)); + out_trace->push_back(Event::UrandomRead(/*length=*/regs.args[2])); if (flags & URANDOM_ERROR) { - inject_error = -EINVAL; + force_result = -EINVAL; + } + } else if (sock_fd >= 0 && sock_fd == read_fd) { + uint64_t length = regs.args[2]; + out_trace->push_back(Event::SocketRead(length)); + if (flags & SOCKET_READ_ERROR) { + force_result = -EINVAL; + } else { + is_socket_read = true; + socket_read_bytes = length; + + if (flags & SOCKET_READ_SHORT) { + ASSERT_GT(socket_read_bytes, 0u); + socket_read_bytes--; + flags &= ~SOCKET_READ_SHORT; + } } } break; } - case __NR_ioctl: { - const int ioctl_fd = regs.rdi; - if (urandom_fd >= 0 && ioctl_fd == urandom_fd && - regs.rsi == RNDGETENTCNT) { - out_trace->push_back(Event::UrandomIoctl()); - is_urandom_ioctl = true; - ioctl_output_addr = regs.rdx; + case __NR_close: { + if (sock_fd >= 0 && static_cast(regs.args[0]) == sock_fd) { + out_trace->push_back(Event::SocketClose()); + sock_fd = -1; } + break; + } + + case __NR_socket: { + const int family = regs.args[0]; + const int type = regs.args[1]; + if (family == AF_UNIX && type == SOCK_STREAM) { + out_trace->push_back(Event::Socket()); + is_socket_call = true; + if (flags & SOCKET_ERROR) { + force_result = -EINVAL; + } + } + break; + } + + case __NR_connect: { + const int connect_fd = regs.args[0]; + if (sock_fd >= 0 && connect_fd == sock_fd) { + out_trace->push_back(Event::Connect()); + if (flags & CONNECT_ERROR) { + force_result = -EINVAL; + } else { + // The test system might not have an entropy daemon running so + // inject a success result. + force_result = 0; + } + } + + break; } } - if (inject_error) { - // Replace the system call number with -1 to cause the kernel to ignore - // the call. The -ENOSYS will be replaced later with the value of - // |inject_error|. - regs.orig_rax = -1; - ASSERT_EQ(0, ptrace(PTRACE_SETREGS, child_pid, nullptr, ®s)); + if (force_result.has_value()) { + ASSERT_TRUE(regs_break_syscall(child_pid, ®s)); } ASSERT_EQ(0, ptrace(PTRACE_SYSCALL, child_pid, 0, 0)); @@ -284,42 +590,26 @@ static void GetTrace(std::vector *out_trace, unsigned flags, // and know that these events happen in pairs. ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80)); - if (inject_error) { - if (inject_error != -ENOSYS) { - ASSERT_EQ(0, ptrace(PTRACE_GETREGS, child_pid, nullptr, ®s)); - regs.rax = inject_error; - ASSERT_EQ(0, ptrace(PTRACE_SETREGS, child_pid, nullptr, ®s)); - } + if (force_result.has_value()) { + ASSERT_TRUE(regs_set_ret(child_pid, force_result.value())); } else if (is_opening_urandom) { - ASSERT_EQ(0, ptrace(PTRACE_GETREGS, child_pid, nullptr, ®s)); - urandom_fd = regs.rax; - } else if (is_urandom_ioctl) { - // The result is the number of bits of entropy that the kernel currently - // believes that it has. urandom.c waits until 256 bits are ready. - int result = 256; + ASSERT_TRUE(regs_read(®s, child_pid)); + urandom_fd = regs.ret; + } else if (is_socket_call) { + ASSERT_TRUE(regs_read(®s, child_pid)); + sock_fd = regs.ret; + } else if (is_socket_read) { + // Simulate a response from the entropy daemon since it might not be + // running on the current system. + uint8_t entropy[kDaemonWriteLength]; + ASSERT_LE(socket_read_bytes, sizeof(entropy)); - // If we are simulating urandom not being ready then we have the ioctl - // indicate one too few bits of entropy the first time it's queried. - if (flags & URANDOM_NOT_READY) { - result--; - flags &= ~URANDOM_NOT_READY; + for (size_t i = 0; i < sizeof(entropy); i++) { + entropy[i] = i & 0xff; } + memcpy_to_remote(child_pid, regs.args[1], entropy, socket_read_bytes); - // ptrace always works with ill-defined "words", which appear to be 64-bit - // on x86-64. Since the ioctl result is a 32-bit int, do a - // read-modify-write to inject the answer. - const uintptr_t aligned_addr = ioctl_output_addr & ~7; - const uintptr_t offset = ioctl_output_addr - aligned_addr; - union { - uint64_t word; - uint8_t bytes[8]; - } u; - u.word = ptrace(PTRACE_PEEKDATA, child_pid, - reinterpret_cast(aligned_addr), nullptr); - memcpy(&u.bytes[offset], &result, sizeof(result)); - ASSERT_EQ(0, ptrace(PTRACE_POKEDATA, child_pid, - reinterpret_cast(aligned_addr), - reinterpret_cast(u.word))); + ASSERT_TRUE(regs_set_ret(child_pid, socket_read_bytes)); } } } @@ -331,23 +621,47 @@ static void TestFunction() { RAND_bytes(&byte, sizeof(byte)); } -static bool have_fork_detection() { - return CRYPTO_get_fork_generation() != 0; +static bool have_fork_detection() { return CRYPTO_get_fork_generation() != 0; } + +static bool AppendDaemonEvents(std::vector *events, unsigned flags) { + events->push_back(Event::Socket()); + if (flags & SOCKET_ERROR) { + return false; + } + + bool ret = false; + events->push_back(Event::Connect()); + if (flags & CONNECT_ERROR) { + goto out; + } + + events->push_back(Event::SocketRead(kDaemonWriteLength)); + if (flags & SOCKET_READ_ERROR) { + goto out; + } + + if (flags & SOCKET_READ_SHORT) { + events->push_back(Event::SocketRead(1)); + } + + ret = true; + +out: + events->push_back(Event::SocketClose()); + return ret; } // TestFunctionPRNGModel is a model of how the urandom.c code will behave when // |TestFunction| is run. It should return the same trace of events that // |GetTrace| will observe the real code making. static std::vector TestFunctionPRNGModel(unsigned flags) { -#if defined(BORINGSSL_FIPS) - static const bool is_fips = true; -#else - static const bool is_fips = false; -#endif - std::vector ret; - bool urandom_probed = false; bool getrandom_ready = false; + bool used_daemon = false; + + if (have_fork_detection()) { + used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags); + } // Probe for getrandom support ret.push_back(Event::GetRandom(1, GRND_NONBLOCK)); @@ -355,32 +669,19 @@ static std::vector TestFunctionPRNGModel(unsigned flags) { std::function sysrand; if (flags & NO_GETRANDOM) { + if (kIsFIPS) { + // FIPS builds require getrandom. + ret.push_back(Event::Abort()); + return ret; + } + ret.push_back(Event::Open("/dev/urandom")); if (flags & NO_URANDOM) { ret.push_back(Event::Abort()); return ret; } - wait_for_entropy = [&ret, &urandom_probed, flags] { - if (!is_fips || urandom_probed) { - return; - } - - // Probe urandom for entropy. - ret.push_back(Event::UrandomIoctl()); - if (flags & URANDOM_NOT_READY) { - // If the first attempt doesn't report enough entropy, probe - // repeatedly until it does, which will happen with the second attempt. - ret.push_back(Event::UrandomIoctl()); - } - - urandom_probed = true; - }; - - sysrand = [&ret, &wait_for_entropy, flags](bool block, size_t len) { - if (block) { - wait_for_entropy(); - } + sysrand = [&ret, flags](bool block, size_t len) { ret.push_back(Event::UrandomRead(len)); if (flags & URANDOM_ERROR) { ret.push_back(Event::Abort()); @@ -413,14 +714,20 @@ static std::vector TestFunctionPRNGModel(unsigned flags) { }; } - const size_t kSeedLength = CTR_DRBG_ENTROPY_LEN * (is_fips ? 10 : 1); + const size_t kSeedLength = CTR_DRBG_ENTROPY_LEN * (kIsFIPS ? 10 : 1); const size_t kAdditionalDataLength = 32; if (!have_rdrand()) { - if ((!have_fork_detection() && !sysrand(true, kAdditionalDataLength)) || - // Initialise CRNGT. - (is_fips && !sysrand(true, 16)) || - !sysrand(true, kSeedLength) || + if (!have_fork_detection()) { + if (!sysrand(true, kAdditionalDataLength)) { + return ret; + } + used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags); + } + if (// Initialise CRNGT. + (!used_daemon && !sysrand(true, kSeedLength + (kIsFIPS ? 16 : 0))) || + // Personalisation draw if the daemon was used. + (used_daemon && !sysrand(false, CTR_DRBG_ENTROPY_LEN)) || // Second entropy draw. (!have_fork_detection() && !sysrand(true, kAdditionalDataLength))) { return ret; @@ -433,7 +740,7 @@ static std::vector TestFunctionPRNGModel(unsigned flags) { // Opportuntistic entropy draw in FIPS mode because RDRAND was used. // In non-FIPS mode it's just drawn from |CRYPTO_sysrand| in a blocking // way. - !sysrand(!is_fips, CTR_DRBG_ENTROPY_LEN) || + !sysrand(!kIsFIPS, CTR_DRBG_ENTROPY_LEN) || // Second entropy draw's additional data. (!have_fast_rdrand() && !have_fork_detection() && !sysrand(false, kAdditionalDataLength))) { @@ -457,11 +764,6 @@ static void CheckInvariants(const std::vector &events) { } break; - case Event::Syscall::kUrandomIoctl: - ADD_FAILURE() << "Urandom polling found with RDRAND: " - << ToString(events); - break; - default: break; } @@ -475,17 +777,37 @@ static void CheckInvariants(const std::vector &events) { TEST(URandomTest, Test) { char buf[256]; + // Some Android systems lack getrandom. + uint8_t scratch[1]; + const bool has_getrandom = + (syscall(__NR_getrandom, scratch, sizeof(scratch), GRND_NONBLOCK) != -1 || + errno != ENOSYS); + #define TRACE_FLAG(flag) \ snprintf(buf, sizeof(buf), #flag ": %d", (flags & flag) != 0); \ SCOPED_TRACE(buf); for (unsigned flags = 0; flags < NEXT_FLAG; flags++) { + if (!kUsesDaemon && (flags & (SOCKET_ERROR | CONNECT_ERROR | + SOCKET_READ_ERROR | SOCKET_READ_SHORT))) { + // These cases are meaningless unless the code will try to use the entropy + // daemon. + continue; + } + + if (!has_getrandom && !(flags & NO_GETRANDOM)) { + continue; + } + TRACE_FLAG(NO_GETRANDOM); TRACE_FLAG(NO_URANDOM); TRACE_FLAG(GETRANDOM_NOT_READY); - TRACE_FLAG(URANDOM_NOT_READY); TRACE_FLAG(GETRANDOM_ERROR); TRACE_FLAG(URANDOM_ERROR); + TRACE_FLAG(SOCKET_ERROR); + TRACE_FLAG(CONNECT_ERROR); + TRACE_FLAG(SOCKET_READ_ERROR); + TRACE_FLAG(SOCKET_READ_SHORT); const std::vector expected_trace = TestFunctionPRNGModel(flags); CheckInvariants(expected_trace); @@ -503,7 +825,9 @@ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); if (getenv("BORINGSSL_IGNORE_MADV_WIPEONFORK")) { - CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(); + CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(0); + } else { + CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(1); } return RUN_ALL_TESTS(); @@ -516,5 +840,5 @@ int main(int argc, char **argv) { return 0; } -#endif // X86_64 && !SHARED_LIBRARY && !UNSAFE_DETERMINISTIC_MODE && - // USE_NR_getrandom +#endif // (X86_64 || AARCH64) && !SHARED_LIBRARY && + // !UNSAFE_DETERMINISTIC_MODE && USE_NR_getrandom diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/blinding.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/blinding.c index 29477bd7..c4cfcc23 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/blinding.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/blinding.c @@ -132,7 +132,6 @@ static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, BN_BLINDING *BN_BLINDING_new(void) { BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING)); if (ret == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(BN_BLINDING)); diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/internal.h index d9d6fac8..5a993a27 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/internal.h @@ -60,13 +60,71 @@ #include #include +#include +#include "../../internal.h" #if defined(__cplusplus) extern "C" { #endif +typedef struct bn_blinding_st BN_BLINDING; + +struct rsa_st { + RSA_METHOD *meth; + + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + + // be careful using this if the RSA structure is shared + CRYPTO_EX_DATA ex_data; + CRYPTO_refcount_t references; + int flags; + + CRYPTO_MUTEX lock; + + // Used to cache montgomery values. The creation of these values is protected + // by |lock|. + BN_MONT_CTX *mont_n; + BN_MONT_CTX *mont_p; + BN_MONT_CTX *mont_q; + + // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, + // but with the correct widths to prevent side channels. These must use + // separate copies due to threading concerns caused by OpenSSL's API + // mistakes. See https://github.com/openssl/openssl/issues/5158 and + // the |freeze_private_key| implementation. + BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; + + // iqmp_mont is q^-1 mod p in Montgomery form, using |mont_p|. + BIGNUM *iqmp_mont; + + // num_blindings contains the size of the |blindings| and |blindings_inuse| + // arrays. This member and the |blindings_inuse| array are protected by + // |lock|. + size_t num_blindings; + // blindings is an array of BN_BLINDING structures that can be reserved by a + // thread by locking |lock| and changing the corresponding element in + // |blindings_inuse| from 0 to 1. + BN_BLINDING **blindings; + unsigned char *blindings_inuse; + uint64_t blinding_fork_generation; + + // private_key_frozen is one if the key has been used for a private key + // operation and may no longer be mutated. + unsigned private_key_frozen:1; +}; + + +#define RSA_PKCS1_PADDING_SIZE 11 + // Default implementations of RSA operations. const RSA_METHOD *RSA_default_method(void); @@ -75,8 +133,6 @@ size_t rsa_default_size(const RSA *rsa); int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); -int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding); int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len); @@ -90,21 +146,13 @@ int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, BN_CTX *ctx); +int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len, + const EVP_MD *md); int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, size_t max_out, const uint8_t *from, size_t from_len); -int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len); -int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len); -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len, const uint8_t *param, - size_t param_len, const EVP_MD *md, - const EVP_MD *mgf1md); int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); @@ -112,18 +160,52 @@ int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, // within DoS bounds. int rsa_check_public_key(const RSA *rsa); -// RSA_private_transform calls either the method-specific |private_transform| -// function (if given) or the generic one. See the comment for -// |private_transform| in |rsa_meth_st|. -int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, +// rsa_private_transform_no_self_test calls either the method-specific +// |private_transform| function (if given) or the generic one. See the comment +// for |private_transform| in |rsa_meth_st|. +int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, + const uint8_t *in, size_t len); + +// rsa_private_transform acts the same as |rsa_private_transform_no_self_test| +// but, in FIPS mode, performs an RSA self test before calling the default RSA +// implementation. +int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len); +// rsa_invalidate_key is called after |rsa| has been mutated, to invalidate +// fields derived from the original structure. This function assumes exclusive +// access to |rsa|. In particular, no other thread may be concurrently signing, +// etc., with |rsa|. +void rsa_invalidate_key(RSA *rsa); + // This constant is exported for test purposes. extern const BN_ULONG kBoringSSLRSASqrtTwo[]; extern const size_t kBoringSSLRSASqrtTwoLen; +// Functions that avoid self-tests. +// +// Self-tests need to call functions that don't try and ensure that the +// self-tests have passed. These functions, in turn, need to limit themselves +// to such functions too. +// +// These functions are the same as their public versions, but skip the self-test +// check. + +int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, RSA *rsa); + +int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa); + + #if defined(__cplusplus) } // extern C #endif diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/padding.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/padding.c index 28f1b45b..998e4591 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/padding.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/padding.c @@ -67,11 +67,10 @@ #include #include "internal.h" +#include "../service_indicator/internal.h" #include "../../internal.h" -#define RSA_PKCS1_PADDING_SIZE 11 - int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { // See RFC 8017, section 9.2. @@ -145,115 +144,6 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, return 1; } -static int rand_nonzero(uint8_t *out, size_t len) { - if (!RAND_bytes(out, len)) { - return 0; - } - - for (size_t i = 0; i < len; i++) { - while (out[i] == 0) { - if (!RAND_bytes(out + i, 1)) { - return 0; - } - } - } - - return 1; -} - -int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len) { - // See RFC 8017, section 7.2.1. - if (to_len < RSA_PKCS1_PADDING_SIZE) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - to[0] = 0; - to[1] = 2; - - size_t padding_len = to_len - 3 - from_len; - if (!rand_nonzero(to + 2, padding_len)) { - return 0; - } - - to[2 + padding_len] = 0; - OPENSSL_memcpy(to + to_len - from_len, from, from_len); - return 1; -} - -int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len) { - if (from_len == 0) { - OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); - return 0; - } - - // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography - // Standard", section 7.2.2. - if (from_len < RSA_PKCS1_PADDING_SIZE) { - // |from| is zero-padded to the size of the RSA modulus, a public value, so - // this can be rejected in non-constant time. - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); - crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); - - crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; - for (size_t i = 2; i < from_len; i++) { - crypto_word_t equals0 = constant_time_is_zero_w(from[i]); - zero_index = - constant_time_select_w(looking_for_index & equals0, i, zero_index); - looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); - } - - // The input must begin with 00 02. - crypto_word_t valid_index = first_byte_is_zero; - valid_index &= second_byte_is_two; - - // We must have found the end of PS. - valid_index &= ~looking_for_index; - - // PS must be at least 8 bytes long, and it starts two bytes into |from|. - valid_index &= constant_time_ge_w(zero_index, 2 + 8); - - // Skip the zero byte. - zero_index++; - - // NOTE: Although this logic attempts to be constant time, the API contracts - // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it - // impossible to completely avoid Bleichenbacher's attack. Consumers should - // use |RSA_PADDING_NONE| and perform the padding check in constant-time - // combined with a swap to a random session key or other mitigation. - CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index)); - CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index)); - - if (!valid_index) { - OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return 0; - } - - const size_t msg_len = from_len - zero_index; - if (msg_len > max_out) { - // This shouldn't happen because this function is always called with - // |max_out| as the key size and |from_len| is bounded by the key size. - OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); - return 0; - } - - OPENSSL_memcpy(out, &from[zero_index], msg_len); - *out_len = msg_len; - return 1; -} - int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { if (from_len > to_len) { @@ -270,11 +160,12 @@ int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, return 1; } -static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, - size_t seed_len, const EVP_MD *md) { +int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len, + const EVP_MD *md) { int ret = 0; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); + FIPS_service_indicator_lock_state(); size_t md_len = EVP_MD_size(md); @@ -310,204 +201,32 @@ static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, err: EVP_MD_CTX_cleanup(&ctx); + FIPS_service_indicator_unlock_state(); return ret; } -int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, - const uint8_t *from, size_t from_len, - const uint8_t *param, size_t param_len, - const EVP_MD *md, const EVP_MD *mgf1md) { - if (md == NULL) { - md = EVP_sha1(); - } - if (mgf1md == NULL) { - mgf1md = md; - } - - size_t mdlen = EVP_MD_size(md); - - if (to_len < 2 * mdlen + 2) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - size_t emlen = to_len - 1; - if (from_len > emlen - 2 * mdlen - 1) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - if (emlen < 2 * mdlen + 1) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - to[0] = 0; - uint8_t *seed = to + 1; - uint8_t *db = to + mdlen + 1; - - if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { - return 0; - } - OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); - db[emlen - from_len - mdlen - 1] = 0x01; - OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); - if (!RAND_bytes(seed, mdlen)) { - return 0; - } - - uint8_t *dbmask = OPENSSL_malloc(emlen - mdlen); - if (dbmask == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - return 0; - } - - int ret = 0; - if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { - goto out; - } - for (size_t i = 0; i < emlen - mdlen; i++) { - db[i] ^= dbmask[i]; - } - - uint8_t seedmask[EVP_MAX_MD_SIZE]; - if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { - goto out; - } - for (size_t i = 0; i < mdlen; i++) { - seed[i] ^= seedmask[i]; - } - ret = 1; - -out: - OPENSSL_free(dbmask); - return ret; -} - -int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, - size_t max_out, const uint8_t *from, - size_t from_len, const uint8_t *param, - size_t param_len, const EVP_MD *md, - const EVP_MD *mgf1md) { - uint8_t *db = NULL; - - if (md == NULL) { - md = EVP_sha1(); - } - if (mgf1md == NULL) { - mgf1md = md; - } - - size_t mdlen = EVP_MD_size(md); - - // The encoded message is one byte smaller than the modulus to ensure that it - // doesn't end up greater than the modulus. Thus there's an extra "+1" here - // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. - if (from_len < 1 + 2*mdlen + 1) { - // 'from_len' is the length of the modulus, i.e. does not depend on the - // particular ciphertext. - goto decoding_err; - } - - size_t dblen = from_len - mdlen - 1; - db = OPENSSL_malloc(dblen); - if (db == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - - const uint8_t *maskedseed = from + 1; - const uint8_t *maskeddb = from + 1 + mdlen; - - uint8_t seed[EVP_MAX_MD_SIZE]; - if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { - goto err; - } - for (size_t i = 0; i < mdlen; i++) { - seed[i] ^= maskedseed[i]; - } - - if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { - goto err; - } - for (size_t i = 0; i < dblen; i++) { - db[i] ^= maskeddb[i]; - } - - uint8_t phash[EVP_MAX_MD_SIZE]; - if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { - goto err; - } - - crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); - bad |= ~constant_time_is_zero_w(from[0]); - - crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; - size_t one_index = 0; - for (size_t i = mdlen; i < dblen; i++) { - crypto_word_t equals1 = constant_time_eq_w(db[i], 1); - crypto_word_t equals0 = constant_time_eq_w(db[i], 0); - one_index = - constant_time_select_w(looking_for_one_byte & equals1, i, one_index); - looking_for_one_byte = - constant_time_select_w(equals1, 0, looking_for_one_byte); - bad |= looking_for_one_byte & ~equals0; - } - - bad |= looking_for_one_byte; - - if (bad) { - goto decoding_err; - } - - one_index++; - size_t mlen = dblen - one_index; - if (max_out < mlen) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); - goto err; - } - - OPENSSL_memcpy(out, db + one_index, mlen); - *out_len = mlen; - OPENSSL_free(db); - return 1; - -decoding_err: - // to avoid chosen ciphertext attacks, the error message should not reveal - // which kind of decoding error happened - OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); - err: - OPENSSL_free(db); - return 0; -} - static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, const uint8_t *EM, int sLen) { - int i; - int ret = 0; - int maskedDBLen, MSBits, emLen; - size_t hLen; - const uint8_t *H; - uint8_t *DB = NULL; - EVP_MD_CTX ctx; - uint8_t H_[EVP_MAX_MD_SIZE]; - EVP_MD_CTX_init(&ctx); - if (mgf1Hash == NULL) { mgf1Hash = Hash; } - hLen = EVP_MD_size(Hash); + int ret = 0; + uint8_t *DB = NULL; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + FIPS_service_indicator_lock_state(); // Negative sLen has special meanings: - // -1 sLen == hLen - // -2 salt length is autorecovered from signature - // -N reserved + // -1 sLen == hLen + // -2 salt length is autorecovered from signature + // -N reserved + size_t hLen = EVP_MD_size(Hash); if (sLen == -1) { - sLen = hLen; + sLen = (int)hLen; } else if (sLen == -2) { sLen = -2; } else if (sLen < -2) { @@ -515,8 +234,8 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, goto err; } - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; - emLen = RSA_size(rsa); + unsigned MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + size_t emLen = RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID); goto err; @@ -525,8 +244,9 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, EM++; emLen--; } - if (emLen < (int)hLen + 2 || emLen < ((int)hLen + sLen + 2)) { - // sLen can be small negative + // |sLen| may be -2 for the non-standard salt length recovery mode. + if (emLen < hLen + 2 || + (sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); goto err; } @@ -534,51 +254,58 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID); goto err; } - maskedDBLen = emLen - hLen - 1; - H = EM + maskedDBLen; + size_t maskedDBLen = emLen - hLen - 1; + const uint8_t *H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); if (!DB) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) { goto err; } - for (i = 0; i < maskedDBLen; i++) { + for (size_t i = 0; i < maskedDBLen; i++) { DB[i] ^= EM[i]; } if (MSBits) { DB[0] &= 0xFF >> (8 - MSBits); } - for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) { + // This step differs slightly from EMSA-PSS-VERIFY (RFC 8017) step 10 because + // it accepts a non-standard salt recovery flow. DB should be some number of + // zeros, a one, then the salt. + size_t salt_start; + for (salt_start = 0; DB[salt_start] == 0 && salt_start < maskedDBLen - 1; + salt_start++) { ; } - if (DB[i++] != 0x1) { + if (DB[salt_start] != 0x1) { OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED); goto err; } - if (sLen >= 0 && (maskedDBLen - i) != sLen) { + salt_start++; + // If a salt length was specified, check it matches. + if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) { OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } + uint8_t H_[EVP_MAX_MD_SIZE]; if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || !EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) || !EVP_DigestUpdate(&ctx, mHash, hLen) || - !EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i) || + !EVP_DigestUpdate(&ctx, DB + salt_start, maskedDBLen - salt_start) || !EVP_DigestFinal_ex(&ctx, H_, NULL)) { goto err; } - if (OPENSSL_memcmp(H_, H, hLen)) { + if (OPENSSL_memcmp(H_, H, hLen) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); - ret = 0; - } else { - ret = 1; + goto err; } + ret = 1; + err: OPENSSL_free(DB); EVP_MD_CTX_cleanup(&ctx); - + FIPS_service_indicator_unlock_state(); return ret; } @@ -595,6 +322,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, mgf1Hash = Hash; } + FIPS_service_indicator_lock_state(); hLen = EVP_MD_size(Hash); if (BN_is_zero(rsa->n)) { @@ -639,7 +367,6 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (!salt) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (!RAND_bytes(salt, sLen)) { @@ -690,6 +417,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, err: OPENSSL_free(salt); + FIPS_service_indicator_unlock_state(); return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa.c index 3205d7da..77ab6c6e 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa.c @@ -56,6 +56,7 @@ #include +#include #include #include @@ -82,12 +83,131 @@ OPENSSL_DECLARE_ERROR_REASON(RSA, BLOCK_TYPE_IS_NOT_02) DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class) +static int bn_dup_into(BIGNUM **dst, const BIGNUM *src) { + if (src == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_free(*dst); + *dst = BN_dup(src); + return *dst != NULL; +} + +RSA *RSA_new_public_key(const BIGNUM *n, const BIGNUM *e) { + RSA *rsa = RSA_new(); + if (rsa == NULL || // + !bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->e, e) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, + const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp) { + RSA *rsa = RSA_new(); + if (rsa == NULL || // + !bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->e, e) || // + !bn_dup_into(&rsa->d, d) || // + !bn_dup_into(&rsa->p, p) || // + !bn_dup_into(&rsa->q, q) || // + !bn_dup_into(&rsa->dmp1, dmp1) || // + !bn_dup_into(&rsa->dmq1, dmq1) || // + !bn_dup_into(&rsa->iqmp, iqmp) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e, + const BIGNUM *d) { + RSA *rsa = RSA_new(); + if (rsa == NULL || // + !bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->e, e) || // + !bn_dup_into(&rsa->d, d) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +RSA *RSA_new_private_key_no_e(const BIGNUM *n, const BIGNUM *d) { + RSA *rsa = RSA_new(); + if (rsa == NULL) { + return NULL; + } + + rsa->flags |= RSA_FLAG_NO_PUBLIC_EXPONENT; + if (!bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->d, d) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +RSA *RSA_new_public_key_large_e(const BIGNUM *n, const BIGNUM *e) { + RSA *rsa = RSA_new(); + if (rsa == NULL) { + return NULL; + } + + rsa->flags |= RSA_FLAG_LARGE_PUBLIC_EXPONENT; + if (!bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->e, e) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +RSA *RSA_new_private_key_large_e(const BIGNUM *n, const BIGNUM *e, + const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp) { + RSA *rsa = RSA_new(); + if (rsa == NULL) { + return NULL; + } + + rsa->flags |= RSA_FLAG_LARGE_PUBLIC_EXPONENT; + if (!bn_dup_into(&rsa->n, n) || // + !bn_dup_into(&rsa->e, e) || // + !bn_dup_into(&rsa->d, d) || // + !bn_dup_into(&rsa->p, p) || // + !bn_dup_into(&rsa->q, q) || // + !bn_dup_into(&rsa->dmp1, dmp1) || // + !bn_dup_into(&rsa->dmq1, dmq1) || // + !bn_dup_into(&rsa->iqmp, iqmp) || // + !RSA_check_key(rsa)) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + RSA *RSA_new(void) { return RSA_new_method(NULL); } RSA *RSA_new_method(const ENGINE *engine) { RSA *rsa = OPENSSL_malloc(sizeof(RSA)); if (rsa == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -118,9 +238,18 @@ RSA *RSA_new_method(const ENGINE *engine) { return rsa; } -void RSA_free(RSA *rsa) { - unsigned u; +RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n) { + RSA *rsa = RSA_new_method(engine); + if (rsa == NULL || + !bn_dup_into(&rsa->n, n)) { + RSA_free(rsa); + return NULL; + } + rsa->flags |= RSA_FLAG_NO_PUBLIC_EXPONENT; + return rsa; +} +void RSA_free(RSA *rsa) { if (rsa == NULL) { return; } @@ -144,18 +273,7 @@ void RSA_free(RSA *rsa) { BN_free(rsa->dmp1); BN_free(rsa->dmq1); BN_free(rsa->iqmp); - BN_MONT_CTX_free(rsa->mont_n); - BN_MONT_CTX_free(rsa->mont_p); - BN_MONT_CTX_free(rsa->mont_q); - BN_free(rsa->d_fixed); - BN_free(rsa->dmp1_fixed); - BN_free(rsa->dmq1_fixed); - BN_free(rsa->inv_small_mod_large_mont); - for (u = 0; u < rsa->num_blindings; u++) { - BN_BLINDING_free(rsa->blindings[u]); - } - OPENSSL_free(rsa->blindings); - OPENSSL_free(rsa->blindings_inuse); + rsa_invalidate_key(rsa); CRYPTO_MUTEX_cleanup(&rsa->lock); OPENSSL_free(rsa); } @@ -244,6 +362,7 @@ int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { rsa->d = d; } + rsa_invalidate_key(rsa); return 1; } @@ -262,6 +381,7 @@ int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { rsa->q = q; } + rsa_invalidate_key(rsa); return 1; } @@ -285,26 +405,13 @@ int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { rsa->iqmp = iqmp; } + rsa_invalidate_key(rsa); return 1; } -int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return out_len; -} - -int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { +static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { if (rsa->meth->sign_raw) { return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); } @@ -312,66 +419,20 @@ int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding); } -int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return out_len; -} - -int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { - if (rsa->meth->decrypt) { - return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); - } - - return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); -} - -int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return out_len; -} - -int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, - int padding) { - size_t out_len; - - if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { - return -1; - } - - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - return -1; - } - return out_len; +int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + return rsa_sign_raw_no_self_test(rsa, out_len, out, max_out, in, in_len, + padding); } unsigned RSA_size(const RSA *rsa) { - if (rsa->meth->size) { - return rsa->meth->size(rsa); - } - - return rsa_default_size(rsa); + size_t ret = rsa->meth->size ? rsa->meth->size(rsa) : rsa_default_size(rsa); + // RSA modulus sizes are bounded by |BIGNUM|, which must fit in |unsigned|. + // + // TODO(https://crbug.com/boringssl/516): Should we make this return |size_t|? + assert(ret < UINT_MAX); + return (unsigned)ret; } int RSA_is_opaque(const RSA *rsa) { @@ -463,49 +524,65 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { }, }; -int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, - int *is_alloced, int hash_nid, const uint8_t *digest, - size_t digest_len) { - unsigned i; - +static int rsa_check_digest_size(int hash_nid, size_t digest_len) { if (hash_nid == NID_md5_sha1) { - // Special case: SSL signature, just check the length. if (digest_len != SSL_SIG_LENGTH) { OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } + return 1; + } + for (size_t i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; + if (sig_prefix->nid == hash_nid) { + if (digest_len != sig_prefix->hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + return 1; + } + } + + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + +} + +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *digest, + size_t digest_len) { + if (!rsa_check_digest_size(hash_nid, digest_len)) { + return 0; + } + + if (hash_nid == NID_md5_sha1) { + // The length should already have been checked. + assert(digest_len == SSL_SIG_LENGTH); *out_msg = (uint8_t *)digest; - *out_msg_len = SSL_SIG_LENGTH; + *out_msg_len = digest_len; *is_alloced = 0; return 1; } - for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + for (size_t i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; if (sig_prefix->nid != hash_nid) { continue; } - if (digest_len != sig_prefix->hash_len) { - OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); - return 0; - } - + // The length should already have been checked. + assert(digest_len == sig_prefix->hash_len); const uint8_t* prefix = sig_prefix->bytes; - unsigned prefix_len = sig_prefix->len; - unsigned signed_msg_len; - uint8_t *signed_msg; - - signed_msg_len = prefix_len + digest_len; + size_t prefix_len = sig_prefix->len; + size_t signed_msg_len = prefix_len + digest_len; if (signed_msg_len < prefix_len) { OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG); return 0; } - signed_msg = OPENSSL_malloc(signed_msg_len); + uint8_t *signed_msg = OPENSSL_malloc(signed_msg_len); if (!signed_msg) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -523,28 +600,41 @@ int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, return 0; } -int RSA_sign(int hash_nid, const uint8_t *digest, unsigned digest_len, - uint8_t *out, unsigned *out_len, RSA *rsa) { +int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa) { + if (rsa->meth->sign) { + if (!rsa_check_digest_size(hash_nid, digest_len)) { + return 0; + } + // All supported digest lengths fit in |unsigned|. + assert(digest_len <= EVP_MAX_MD_SIZE); + static_assert(EVP_MAX_MD_SIZE <= UINT_MAX, "digest too long"); + return rsa->meth->sign(hash_nid, digest, (unsigned)digest_len, out, out_len, + rsa); + } + const unsigned rsa_size = RSA_size(rsa); int ret = 0; uint8_t *signed_msg = NULL; size_t signed_msg_len = 0; int signed_msg_is_alloced = 0; size_t size_t_out_len; - - if (rsa->meth->sign) { - return rsa->meth->sign(hash_nid, digest, digest_len, out, out_len, rsa); - } - if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, hash_nid, digest, digest_len) || - !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg, - signed_msg_len, RSA_PKCS1_PADDING)) { + !rsa_sign_raw_no_self_test(rsa, &size_t_out_len, out, rsa_size, + signed_msg, signed_msg_len, + RSA_PKCS1_PADDING)) { goto err; } - *out_len = size_t_out_len; + if (size_t_out_len > UINT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + goto err; + } + + *out_len = (unsigned)size_t_out_len; ret = 1; err: @@ -554,6 +644,13 @@ err: return ret; } +int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, + uint8_t *out, unsigned *out_len, RSA *rsa) { + boringssl_ensure_rsa_self_test(); + + return rsa_sign_no_self_test(hash_nid, digest, digest_len, out, out_len, rsa); +} + int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *digest, size_t digest_len, const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len) { @@ -565,7 +662,6 @@ int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, size_t padded_len = RSA_size(rsa); uint8_t *padded = OPENSSL_malloc(padded_len); if (padded == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -577,8 +673,9 @@ int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, return ret; } -int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, - const uint8_t *sig, size_t sig_len, RSA *rsa) { +int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, RSA *rsa) { if (rsa->n == NULL || rsa->e == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; @@ -598,16 +695,12 @@ int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, buf = OPENSSL_malloc(rsa_size); if (!buf) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } - if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len, - RSA_PKCS1_PADDING)) { - goto out; - } - - if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + if (!rsa_verify_raw_no_self_test(rsa, &len, buf, rsa_size, sig, sig_len, + RSA_PKCS1_PADDING) || + !RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, hash_nid, digest, digest_len)) { goto out; @@ -630,6 +723,13 @@ out: return ret; } +int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, RSA *rsa) { + boringssl_ensure_rsa_self_test(); + return rsa_verify_no_self_test(hash_nid, digest, digest_len, sig, sig_len, + rsa); +} + int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len, const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len, const uint8_t *sig, size_t sig_len) { @@ -641,7 +741,6 @@ int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len, size_t em_len = RSA_size(rsa); uint8_t *em = OPENSSL_malloc(em_len); if (em == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -722,7 +821,6 @@ int RSA_check_key(const RSA *key) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -737,7 +835,8 @@ int RSA_check_key(const RSA *key) { // Check that p * q == n. Before we multiply, we check that p and q are in // bounds, to avoid a DoS vector in |bn_mul_consttime| below. Note that - // n was bound by |rsa_check_public_key|. + // n was bound by |rsa_check_public_key|. This also implicitly checks p and q + // are odd, which is a necessary condition for Montgomery reduction. if (BN_is_negative(key->p) || BN_cmp(key->p, key->n) >= 0 || BN_is_negative(key->q) || BN_cmp(key->q, key->n) >= 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); @@ -849,7 +948,6 @@ int RSA_check_fips(RSA *key) { BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -896,7 +994,6 @@ int RSA_check_fips(RSA *key) { unsigned sig_len = RSA_size(key); uint8_t *sig = OPENSSL_malloc(sig_len); if (sig == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -905,9 +1002,9 @@ int RSA_check_fips(RSA *key) { ret = 0; goto cleanup; } -#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT) - data[0] = ~data[0]; -#endif + if (boringssl_fips_break_test("RSA_PWCT")) { + data[0] = ~data[0]; + } if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); ret = 0; @@ -919,8 +1016,8 @@ cleanup: return ret; } -int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, - size_t len) { +int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, + const uint8_t *in, size_t len) { if (rsa->meth->private_transform) { return rsa->meth->private_transform(rsa, out, in, len); } @@ -928,6 +1025,12 @@ int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, return rsa_default_private_transform(rsa, out, in, len); } +int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + boringssl_ensure_rsa_self_test(); + return rsa_private_transform_no_self_test(rsa, out, in, len); +} + int RSA_flags(const RSA *rsa) { return rsa->flags; } int RSA_test_flags(const RSA *rsa, int flags) { return rsa->flags & flags; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa_impl.c b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa_impl.c index a6865c03..6cdc2909 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa_impl.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/rsa/rsa_impl.c @@ -64,56 +64,82 @@ #include #include #include -#include -#include "internal.h" -#include "../bn/internal.h" #include "../../internal.h" +#include "../bn/internal.h" #include "../delocate.h" #include "../rand/fork_detect.h" +#include "../service_indicator/internal.h" +#include "internal.h" int rsa_check_public_key(const RSA *rsa) { - if (rsa->n == NULL || rsa->e == NULL) { + if (rsa->n == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } + // TODO(davidben): 16384-bit RSA is huge. Can we bring this down to a limit of + // 8192-bit? unsigned n_bits = BN_num_bits(rsa->n); if (n_bits > 16 * 1024) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); return 0; } - // Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as - // the limit based on the recommendations in [1] and [2]. Windows CryptoAPI - // doesn't support values larger than 32 bits [3], so it is unlikely that - // exponents larger than 32 bits are being used for anything Windows commonly - // does. - // - // [1] https://www.imperialviolet.org/2012/03/16/rsae.html - // [2] https://www.imperialviolet.org/2012/03/17/rsados.html - // [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx - static const unsigned kMaxExponentBits = 33; - unsigned e_bits = BN_num_bits(rsa->e); - if (e_bits > kMaxExponentBits || - // Additionally reject e = 1 or even e. e must be odd to be relatively - // prime with phi(n). - e_bits < 2 || - !BN_is_odd(rsa->e)) { - OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); - return 0; - } - - // Verify |n > e|. Comparing |n_bits| to |kMaxExponentBits| is a small - // shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits| - // is much smaller than the minimum RSA key size that any application should - // accept. - if (n_bits <= kMaxExponentBits) { + // TODO(crbug.com/boringssl/607): Raise this limit. 512-bit RSA was factored + // in 1999. + if (n_bits < 512) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } - assert(BN_ucmp(rsa->n, rsa->e) > 0); + + // RSA moduli must be positive and odd. In addition to being necessary for RSA + // in general, we cannot setup Montgomery reduction with even moduli. + if (!BN_is_odd(rsa->n) || BN_is_negative(rsa->n)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + return 0; + } + + static const unsigned kMaxExponentBits = 33; + if (rsa->e != NULL) { + // Reject e = 1, negative e, and even e. e must be odd to be relatively + // prime with phi(n). + unsigned e_bits = BN_num_bits(rsa->e); + if (e_bits < 2 || BN_is_negative(rsa->e) || !BN_is_odd(rsa->e)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + if (rsa->flags & RSA_FLAG_LARGE_PUBLIC_EXPONENT) { + // The caller has requested disabling DoS protections. Still, e must be + // less than n. + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + } else { + // Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen + // as the limit based on the recommendations in [1] and [2]. Windows + // CryptoAPI doesn't support values larger than 32 bits [3], so it is + // unlikely that exponents larger than 32 bits are being used for anything + // Windows commonly does. + // + // [1] https://www.imperialviolet.org/2012/03/16/rsae.html + // [2] https://www.imperialviolet.org/2012/03/17/rsados.html + // [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + if (e_bits > kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + // The upper bound on |e_bits| and lower bound on |n_bits| imply e is + // bounded by n. + assert(BN_ucmp(rsa->n, rsa->e) > 0); + } + } else if (!(rsa->flags & RSA_FLAG_NO_PUBLIC_EXPONENT)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } return 1; } @@ -153,6 +179,11 @@ static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { goto err; } + // Check the public components are within DoS bounds. + if (!rsa_check_public_key(rsa)) { + goto err; + } + // Pre-compute various intermediate values, as well as copies of private // exponents with correct widths. Note that other threads may concurrently // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate @@ -176,7 +207,7 @@ static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { goto err; } - if (rsa->p != NULL && rsa->q != NULL) { + if (rsa->e != NULL && rsa->p != NULL && rsa->q != NULL) { // TODO: p and q are also CONSTTIME_SECRET but not yet marked as such // because the Montgomery code does things like test whether or not values // are zero. So the secret marking probably needs to happen inside that @@ -212,37 +243,24 @@ static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { } // CRT components are only publicly bounded by their corresponding - // moduli's bit lengths. |rsa->iqmp| is unused outside of this one-time - // setup, so we do not compute a fixed-width version of it. + // moduli's bit lengths. if (!ensure_fixed_copy(&rsa->dmp1_fixed, rsa->dmp1, p_fixed->width) || !ensure_fixed_copy(&rsa->dmq1_fixed, rsa->dmq1, q_fixed->width)) { goto err; } - // Compute |inv_small_mod_large_mont|. Note that it is always modulo the - // larger prime, independent of what is stored in |rsa->iqmp|. - if (rsa->inv_small_mod_large_mont == NULL) { - BIGNUM *inv_small_mod_large_mont = BN_new(); - int ok; - if (BN_cmp(rsa->p, rsa->q) < 0) { - ok = inv_small_mod_large_mont != NULL && - bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p, - rsa->q, ctx, rsa->mont_q) && - BN_to_montgomery(inv_small_mod_large_mont, - inv_small_mod_large_mont, rsa->mont_q, ctx); - } else { - ok = inv_small_mod_large_mont != NULL && - BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp, - rsa->mont_p, ctx); - } - if (!ok) { - BN_free(inv_small_mod_large_mont); + // Compute |iqmp_mont|, which is |iqmp| in Montgomery form and with the + // correct bit width. + if (rsa->iqmp_mont == NULL) { + BIGNUM *iqmp_mont = BN_new(); + if (iqmp_mont == NULL || + !BN_to_montgomery(iqmp_mont, rsa->iqmp, rsa->mont_p, ctx)) { + BN_free(iqmp_mont); goto err; } - rsa->inv_small_mod_large_mont = inv_small_mod_large_mont; - CONSTTIME_SECRET( - rsa->inv_small_mod_large_mont->d, - sizeof(BN_ULONG) * rsa->inv_small_mod_large_mont->width); + rsa->iqmp_mont = iqmp_mont; + CONSTTIME_SECRET(rsa->iqmp_mont->d, + sizeof(BN_ULONG) * rsa->iqmp_mont->width); } } } @@ -255,95 +273,38 @@ err: return ret; } -size_t rsa_default_size(const RSA *rsa) { - return BN_num_bytes(rsa->n); +void rsa_invalidate_key(RSA *rsa) { + rsa->private_key_frozen = 0; + + BN_MONT_CTX_free(rsa->mont_n); + rsa->mont_n = NULL; + BN_MONT_CTX_free(rsa->mont_p); + rsa->mont_p = NULL; + BN_MONT_CTX_free(rsa->mont_q); + rsa->mont_q = NULL; + + BN_free(rsa->d_fixed); + rsa->d_fixed = NULL; + BN_free(rsa->dmp1_fixed); + rsa->dmp1_fixed = NULL; + BN_free(rsa->dmq1_fixed); + rsa->dmq1_fixed = NULL; + BN_free(rsa->iqmp_mont); + rsa->iqmp_mont = NULL; + + for (size_t i = 0; i < rsa->num_blindings; i++) { + BN_BLINDING_free(rsa->blindings[i]); + } + OPENSSL_free(rsa->blindings); + rsa->blindings = NULL; + rsa->num_blindings = 0; + OPENSSL_free(rsa->blindings_inuse); + rsa->blindings_inuse = NULL; + rsa->blinding_fork_generation = 0; } -int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { - if (!rsa_check_public_key(rsa)) { - return 0; - } - - const unsigned rsa_size = RSA_size(rsa); - BIGNUM *f, *result; - uint8_t *buf = NULL; - BN_CTX *ctx = NULL; - int i, ret = 0; - - if (max_out < rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) { - goto err; - } - - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - buf = OPENSSL_malloc(rsa_size); - if (!f || !result || !buf) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); - break; - case RSA_PKCS1_OAEP_PADDING: - // Use the default parameters: SHA-1 for both hashes and no label. - i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, - NULL, 0, NULL, NULL); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, rsa_size, in, in_len); - break; - default: - OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - - if (i <= 0) { - goto err; - } - - if (BN_bin2bn(buf, rsa_size, f) == NULL) { - goto err; - } - - if (BN_ucmp(f, rsa->n) >= 0) { - // usually the padding functions would catch this - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || - !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { - goto err; - } - - // put in leading 0 bytes if the number is less than the length of the - // modulus - if (!BN_bn2bin_padded(out, rsa_size, result)) { - OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); - goto err; - } - - *out_len = rsa_size; - ret = 1; - -err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - OPENSSL_free(buf); - - return ret; +size_t rsa_default_size(const RSA *rsa) { + return BN_num_bytes(rsa->n); } // MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per @@ -363,7 +324,7 @@ err: // // On success, the index of the assigned BN_BLINDING is written to // |*index_used| and must be passed to |rsa_blinding_release| when finished. -static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, +static BN_BLINDING *rsa_blinding_get(RSA *rsa, size_t *index_used, BN_CTX *ctx) { assert(ctx != NULL); assert(rsa->mont_n != NULL); @@ -374,7 +335,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, // Wipe the blinding cache on |fork|. if (rsa->blinding_fork_generation != fork_generation) { - for (unsigned i = 0; i < rsa->num_blindings; i++) { + for (size_t i = 0; i < rsa->num_blindings; i++) { // The inuse flag must be zero unless we were forked from a // multi-threaded process, in which case calling back into BoringSSL is // forbidden. @@ -403,9 +364,9 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, } // Double the length of the cache. - OPENSSL_STATIC_ASSERT(MAX_BLINDINGS_PER_RSA < UINT_MAX / 2, - "MAX_BLINDINGS_PER_RSA too large"); - unsigned new_num_blindings = rsa->num_blindings * 2; + static_assert(MAX_BLINDINGS_PER_RSA < UINT_MAX / 2, + "MAX_BLINDINGS_PER_RSA too large"); + size_t new_num_blindings = rsa->num_blindings * 2; if (new_num_blindings == 0) { new_num_blindings = 1; } @@ -414,9 +375,6 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, } assert(new_num_blindings > rsa->num_blindings); - OPENSSL_STATIC_ASSERT( - MAX_BLINDINGS_PER_RSA < UINT_MAX / sizeof(BN_BLINDING *), - "MAX_BLINDINGS_PER_RSA too large"); BN_BLINDING **new_blindings = OPENSSL_malloc(sizeof(BN_BLINDING *) * new_num_blindings); uint8_t *new_blindings_inuse = OPENSSL_malloc(new_num_blindings); @@ -428,10 +386,10 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, sizeof(BN_BLINDING *) * rsa->num_blindings); OPENSSL_memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); - for (unsigned i = rsa->num_blindings; i < new_num_blindings; i++) { + for (size_t i = rsa->num_blindings; i < new_num_blindings; i++) { new_blindings[i] = BN_BLINDING_new(); if (new_blindings[i] == NULL) { - for (unsigned j = rsa->num_blindings; j < i; j++) { + for (size_t j = rsa->num_blindings; j < i; j++) { BN_BLINDING_free(new_blindings[j]); } goto err; @@ -465,7 +423,7 @@ out: // rsa_blinding_release marks the cached BN_BLINDING at the given index as free // for other threads to use. static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding, - unsigned blinding_index) { + size_t blinding_index) { if (blinding_index == MAX_BLINDINGS_PER_RSA) { // This blinding wasn't cached. BN_BLINDING_free(blinding); @@ -492,7 +450,6 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, buf = OPENSSL_malloc(rsa_size); if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -512,7 +469,7 @@ int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, goto err; } - if (!RSA_private_transform(rsa, out, buf, rsa_size)) { + if (!rsa_private_transform_no_self_test(rsa, out, buf, rsa_size)) { goto err; } @@ -526,75 +483,17 @@ err: return ret; } -int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { - const unsigned rsa_size = RSA_size(rsa); - uint8_t *buf = NULL; - int ret = 0; - - if (max_out < rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } - - if (padding == RSA_NO_PADDING) { - buf = out; - } else { - // Allocate a temporary buffer to hold the padded plaintext. - buf = OPENSSL_malloc(rsa_size); - if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (in_len != rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); - goto err; - } - - if (!RSA_private_transform(rsa, buf, in, rsa_size)) { - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - ret = - RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); - break; - case RSA_PKCS1_OAEP_PADDING: - // Use the default parameters: SHA-1 for both hashes and no label. - ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, - rsa_size, NULL, 0, NULL, NULL); - break; - case RSA_NO_PADDING: - *out_len = rsa_size; - ret = 1; - break; - default: - OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - - CONSTTIME_DECLASSIFY(&ret, sizeof(ret)); - if (!ret) { - OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); - } else { - CONSTTIME_DECLASSIFY(out, *out_len); - } - -err: - if (padding != RSA_NO_PADDING) { - OPENSSL_free(buf); - } - - return ret; -} static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); -int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, - const uint8_t *in, size_t in_len, int padding) { +int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + if (!rsa_check_public_key(rsa)) { return 0; } @@ -624,7 +523,6 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -634,7 +532,6 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, // Allocate a temporary buffer to hold the padded plaintext. buf = OPENSSL_malloc(rsa_size); if (buf == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } } @@ -686,6 +583,14 @@ err: return ret; } +int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding) { + boringssl_ensure_rsa_self_test(); + return rsa_verify_raw_no_self_test(rsa, out_len, out, max_out, in, in_len, + padding); +} + int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { if (rsa->n == NULL || rsa->d == NULL) { @@ -695,7 +600,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, BIGNUM *f, *result; BN_CTX *ctx = NULL; - unsigned blinding_index = 0; + size_t blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; @@ -708,10 +613,11 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } + // The caller should have ensured this. + assert(len == BN_num_bytes(rsa->n)); if (BN_bin2bn(in, len, f) == NULL) { goto err; } @@ -727,13 +633,18 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, goto err; } - const int do_blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0; + const int do_blinding = + (rsa->flags & (RSA_FLAG_NO_BLINDING | RSA_FLAG_NO_PUBLIC_EXPONENT)) == 0; if (rsa->e == NULL && do_blinding) { // We cannot do blinding or verification without |e|, and continuing without // those countermeasures is dangerous. However, the Java/Android RSA API // requires support for keys where only |d| and |n| (and not |e|) are known. - // The callers that require that bad behavior set |RSA_FLAG_NO_BLINDING|. + // The callers that require that bad behavior must set + // |RSA_FLAG_NO_BLINDING| or use |RSA_new_private_key_no_e|. + // + // TODO(davidben): Update this comment when Conscrypt is updated to use + // |RSA_new_private_key_no_e|. OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); goto err; } @@ -773,16 +684,16 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, // works when the CRT isn't used. That attack is much less likely to succeed // than the CRT attack, but there have likely been improvements since 1997. // - // This check is cheap assuming |e| is small; it almost always is. + // This check is cheap assuming |e| is small, which we require in + // |rsa_check_public_key|. if (rsa->e != NULL) { BIGNUM *vrfy = BN_CTX_get(ctx); if (vrfy == NULL || !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || - !BN_equal_consttime(vrfy, f)) { + !constant_time_declassify_int(BN_equal_consttime(vrfy, f))) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } - } if (do_blinding && @@ -796,6 +707,7 @@ int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, // // See Falko Strenzke, "Manger's Attack revisited", ICICS 2010. assert(result->width == rsa->mont_n->N.width); + bn_assert_fits_in_bytes(result, len); if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; @@ -873,52 +785,54 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { goto err; } - // Implementing RSA with CRT in constant-time is sensitive to which prime is - // larger. Canonicalize fields so that |p| is the larger prime. - const BIGNUM *dmp1 = rsa->dmp1_fixed, *dmq1 = rsa->dmq1_fixed; - const BN_MONT_CTX *mont_p = rsa->mont_p, *mont_q = rsa->mont_q; - if (BN_cmp(rsa->p, rsa->q) < 0) { - mont_p = rsa->mont_q; - mont_q = rsa->mont_p; - dmp1 = rsa->dmq1_fixed; - dmq1 = rsa->dmp1_fixed; - } - // Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if // someone gives us non-minimal values, these will be slightly more efficient // on the non-Montgomery operations. const BIGNUM *n = &rsa->mont_n->N; - const BIGNUM *p = &mont_p->N; - const BIGNUM *q = &mont_q->N; + const BIGNUM *p = &rsa->mont_p->N; + const BIGNUM *q = &rsa->mont_q->N; // This is a pre-condition for |mod_montgomery|. It was already checked by the // caller. assert(BN_ucmp(I, n) < 0); if (// |m1| is the result modulo |q|. - !mod_montgomery(r1, I, q, mont_q, p, ctx) || - !BN_mod_exp_mont_consttime(m1, r1, dmq1, q, ctx, mont_q) || + !mod_montgomery(r1, I, q, rsa->mont_q, p, ctx) || + !BN_mod_exp_mont_consttime(m1, r1, rsa->dmq1_fixed, q, ctx, + rsa->mont_q) || // |r0| is the result modulo |p|. - !mod_montgomery(r1, I, p, mont_p, q, ctx) || - !BN_mod_exp_mont_consttime(r0, r1, dmp1, p, ctx, mont_p) || - // Compute r0 = r0 - m1 mod p. |p| is the larger prime, so |m1| is already - // fully reduced mod |p|. - !bn_mod_sub_consttime(r0, r0, m1, p, ctx) || + !mod_montgomery(r1, I, p, rsa->mont_p, q, ctx) || + !BN_mod_exp_mont_consttime(r0, r1, rsa->dmp1_fixed, p, ctx, + rsa->mont_p) || + // Compute r0 = r0 - m1 mod p. |m1| is reduced mod |q|, not |p|, so we + // just run |mod_montgomery| again for simplicity. This could be more + // efficient with more cases: if |p > q|, |m1| is already reduced. If + // |p < q| but they have the same bit width, |bn_reduce_once| suffices. + // However, compared to over 2048 Montgomery multiplications above, this + // difference is not measurable. + !mod_montgomery(r1, m1, p, rsa->mont_p, q, ctx) || + !bn_mod_sub_consttime(r0, r0, r1, p, ctx) || // r0 = r0 * iqmp mod p. We use Montgomery multiplication to compute this - // in constant time. |inv_small_mod_large_mont| is in Montgomery form and - // r0 is not, so the result is taken out of Montgomery form. - !BN_mod_mul_montgomery(r0, r0, rsa->inv_small_mod_large_mont, mont_p, - ctx) || + // in constant time. |iqmp_mont| is in Montgomery form and r0 is not, so + // the result is taken out of Montgomery form. + !BN_mod_mul_montgomery(r0, r0, rsa->iqmp_mont, rsa->mont_p, ctx) || // r0 = r0 * q + m1 gives the final result. Reducing modulo q gives m1, so // it is correct mod p. Reducing modulo p gives (r0-m1)*iqmp*q + m1 = r0, // so it is correct mod q. Finally, the result is bounded by [m1, n + m1), // and the result is at least |m1|, so this must be the unique answer in // [0, n). - !bn_mul_consttime(r0, r0, q, ctx) || - !bn_uadd_consttime(r0, r0, m1) || - // The result should be bounded by |n|, but fixed-width operations may - // bound the width slightly higher, so fix it. - !bn_resize_words(r0, n->width)) { + !bn_mul_consttime(r0, r0, q, ctx) || // + !bn_uadd_consttime(r0, r0, m1)) { + goto err; + } + + // The result should be bounded by |n|, but fixed-width operations may + // bound the width slightly higher, so fix it. This trips constant-time checks + // because a naive data flow analysis does not realize the excess words are + // publicly zero. + assert(BN_cmp(r0, n) < 0); + bn_assert_fits_in_bytes(r0, BN_num_bytes(n)); + if (!bn_resize_words(r0, n->width)) { goto err; } @@ -1324,6 +1238,8 @@ static void replace_bn_mont_ctx(BN_MONT_CTX **out, BN_MONT_CTX **in) { static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, const BIGNUM *e_value, BN_GENCB *cb, int check_fips) { + boringssl_ensure_rsa_self_test(); + RSA *tmp = NULL; uint32_t err; int ret = 0; @@ -1359,6 +1275,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, goto out; } + rsa_invalidate_key(rsa); replace_bignum(&rsa->n, &tmp->n); replace_bignum(&rsa->e, &tmp->e); replace_bignum(&rsa->d, &tmp->d); @@ -1373,8 +1290,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, replace_bignum(&rsa->d_fixed, &tmp->d_fixed); replace_bignum(&rsa->dmp1_fixed, &tmp->dmp1_fixed); replace_bignum(&rsa->dmq1_fixed, &tmp->dmq1_fixed); - replace_bignum(&rsa->inv_small_mod_large_mont, - &tmp->inv_small_mod_large_mont); + replace_bignum(&rsa->iqmp_mont, &tmp->iqmp_mont); rsa->private_key_frozen = tmp->private_key_frozen; ret = 1; @@ -1404,6 +1320,10 @@ int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb) { BN_set_word(e, RSA_F4) && RSA_generate_key_ex_maybe_fips(rsa, bits, e, cb, /*check_fips=*/1); BN_free(e); + + if (ret) { + FIPS_service_indicator_update_state(); + } return ret; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/fips.c b/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/fips.c index d55c493c..ce039576 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/fips.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/fips.c @@ -28,6 +28,47 @@ int FIPS_mode(void) { int FIPS_mode_set(int on) { return on == FIPS_mode(); } +const char *FIPS_module_name(void) { return "BoringCrypto"; } + +uint32_t FIPS_version(void) { + return 0; +} + +int FIPS_query_algorithm_status(const char *algorithm) { +#if defined(BORINGSSL_FIPS) + static const char kApprovedAlgorithms[][13] = { + "AES-CBC", + "AES-CCM", + "AES-CTR", + "AES-ECB", + "AES-GCM", + "AES-KW", + "AES-KWP", + "ctrDRBG", + "ECC-SSC", + "ECDSA-sign", + "ECDSA-verify", + "FFC-SSC", + "HMAC", + "RSA-sign", + "RSA-verify", + "SHA-1", + "SHA2-224", + "SHA2-256", + "SHA2-384", + "SHA2-512", + "SHA2-512/256", + }; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kApprovedAlgorithms); i++) { + if (strcmp(algorithm, kApprovedAlgorithms[i]) == 0) { + return 1; + } + } +#endif // BORINGSSL_FIPS + + return 0; +} + #if defined(BORINGSSL_FIPS_COUNTERS) size_t FIPS_read_counter(enum fips_counter_t counter) { diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/self_check.c b/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/self_check.c index 94f2da75..525cd169 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/self_check.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/self_check/self_check.c @@ -20,20 +20,25 @@ #include #include #include -#include +#include #include #include #include #include #include +#include +#include #include #include #include #include "../../internal.h" +#include "../dh/internal.h" #include "../ec/internal.h" #include "../ecdsa/internal.h" #include "../rand/internal.h" +#include "../rsa/internal.h" +#include "../service_indicator/internal.h" #include "../tls/internal.h" @@ -47,21 +52,6 @@ int BORINGSSL_self_test(void) { #else -#if defined(BORINGSSL_FIPS) && defined(OPENSSL_ANDROID) -// FIPS builds on Android will test for flag files, named after the module hash, -// in /dev/boringssl/selftest/. If such a flag file exists, it's assumed that -// self-tests have already passed and thus do not need to be repeated. (The -// integrity tests always run, however.) -// -// If self-tests complete successfully and the environment variable named in -// |kFlagWriteEnableEnvVar| is present, then the flag file will be created. The -// flag file isn't written without the environment variable being set in order -// to avoid SELinux violations on Android. -#define BORINGSSL_FIPS_SELF_TEST_FLAG_FILE -static const char kFlagPrefix[] = "/dev/boringssl/selftest/"; -static const char kFlagWriteEnableEnvVar[] = "BORINGSSL_SELF_TEST_CREATE_FLAG"; -#endif - static void hexdump(const uint8_t *in, size_t len) { for (size_t i = 0; i < len; i++) { fprintf(stderr, "%02x", in[i]); @@ -71,7 +61,7 @@ static void hexdump(const uint8_t *in, size_t len) { static int check_test(const void *expected, const void *actual, size_t expected_len, const char *name) { if (OPENSSL_memcmp(actual, expected, expected_len) != 0) { - fprintf(stderr, "%s failed.\nExpected: ", name); + fprintf(stderr, "%s failed.\nExpected: ", name); hexdump(expected, expected_len); fprintf(stderr, "\nCalculated: "); hexdump(actual, expected_len); @@ -87,6 +77,28 @@ static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) { return *out != NULL; } +static int serialize_ecdsa_sig(uint8_t *out, size_t out_len, + const ECDSA_SIG *sig) { + if ((out_len & 1) || // + !BN_bn2bin_padded(out, out_len / 2, sig->r) || + !BN_bn2bin_padded(out + out_len / 2, out_len / 2, sig->s)) { + return 0; + } + return 1; +} + +static ECDSA_SIG *parse_ecdsa_sig(const uint8_t *in, size_t in_len) { + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (!ret || // + (in_len & 1) || + BN_bin2bn(in, in_len/2, ret->r) == NULL || + BN_bin2bn(in + in_len/2, in_len/2, ret->s) == NULL) { + ECDSA_SIG_free(ret); + ret = NULL; + } + return ret; +} + static RSA *self_test_rsa_key(void) { static const uint8_t kN[] = { 0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc, @@ -289,195 +301,188 @@ err: return NULL; } -#if defined(OPENSSL_ANDROID) -#define MODULE_DIGEST_SIZE SHA256_DIGEST_LENGTH -#else -#define MODULE_DIGEST_SIZE SHA512_DIGEST_LENGTH -#endif -int boringssl_fips_self_test( - const uint8_t *module_hash, size_t module_hash_len) { -#if defined(BORINGSSL_FIPS_SELF_TEST_FLAG_FILE) - char flag_path[sizeof(kFlagPrefix) + 2 * MODULE_DIGEST_SIZE]; - if (module_hash_len != 0) { - if (module_hash_len != MODULE_DIGEST_SIZE) { - fprintf(stderr, - "module hash of length %zu does not match expected length %d\n", - module_hash_len, MODULE_DIGEST_SIZE); - BORINGSSL_FIPS_abort(); - } +// Lazy self-tests +// +// Self tests that are slow are deferred until the corresponding algorithm is +// actually exercised, in FIPS mode. (In non-FIPS mode these tests are only run +// when requested by |BORINGSSL_self_test|.) - // Test whether the flag file exists. - memcpy(flag_path, kFlagPrefix, sizeof(kFlagPrefix) - 1); - static const char kHexTable[17] = "0123456789abcdef"; - for (size_t i = 0; i < MODULE_DIGEST_SIZE; i++) { - flag_path[sizeof(kFlagPrefix) - 1 + 2 * i] = - kHexTable[module_hash[i] >> 4]; - flag_path[sizeof(kFlagPrefix) - 1 + 2 * i + 1] = - kHexTable[module_hash[i] & 15]; - } - flag_path[sizeof(flag_path) - 1] = 0; +static int boringssl_self_test_rsa(void) { + int ret = 0; + uint8_t output[256]; - if (access(flag_path, F_OK) == 0) { - // Flag file found. Skip self-tests. - return 1; - } + RSA *const rsa_key = self_test_rsa_key(); + if (rsa_key == NULL) { + fprintf(stderr, "RSA key construction failed\n"); + goto err; } -#endif // BORINGSSL_FIPS_SELF_TEST_FLAG_FILE + // Disable blinding for the power-on tests because it's not needed and + // triggers an entropy draw. + rsa_key->flags |= RSA_FLAG_NO_BLINDING; - static const uint8_t kAESKey[16] = "BoringCrypto Key"; - static const uint8_t kAESIV[16] = {0}; - static const uint8_t kPlaintext[64] = - "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!"; - static const uint8_t kAESCBCCiphertext[64] = { - 0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b, - 0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c, - 0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45, - 0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad, - 0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55, - 0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8, -#if !defined(BORINGSSL_FIPS_BREAK_AES_CBC) - 0x35 -#else - 0x00 -#endif + // RSA Sign KAT + + static const uint8_t kRSASignDigest[32] = { + 0xd2, 0xb5, 0x6e, 0x53, 0x30, 0x6f, 0x72, 0x0d, 0x79, 0x29, 0xd8, + 0x70, 0x8b, 0xf4, 0x6f, 0x1c, 0x22, 0x30, 0x03, 0x05, 0x58, 0x2b, + 0x11, 0x5b, 0xed, 0xca, 0xc7, 0x22, 0xd8, 0xaa, 0x5a, 0xb2, }; - static const uint8_t kAESGCMCiphertext[80] = { - 0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9, - 0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82, - 0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa, - 0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4, - 0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33, - 0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61, - 0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64, -#if !defined(BORINGSSL_FIPS_BREAK_AES_GCM) - 0x0d -#else - 0x00 -#endif + static const uint8_t kRSASignSignature[256] = { + 0x64, 0xce, 0xdd, 0x91, 0x27, 0xb0, 0x4f, 0xb9, 0x14, 0xea, 0xc0, 0xb4, + 0xa2, 0x06, 0xc5, 0xd8, 0x40, 0x0f, 0x6c, 0x54, 0xac, 0xf7, 0x02, 0xde, + 0x26, 0xbb, 0xfd, 0x33, 0xe5, 0x2f, 0x4d, 0xb1, 0x53, 0xc4, 0xff, 0xd0, + 0x5f, 0xea, 0x15, 0x89, 0x83, 0x4c, 0xe3, 0x80, 0x0b, 0xe9, 0x13, 0x82, + 0x1d, 0x71, 0x92, 0x1a, 0x03, 0x60, 0x2c, 0xaf, 0xe2, 0x16, 0xc7, 0x43, + 0x3f, 0xde, 0x6b, 0x94, 0xfd, 0x6e, 0x08, 0x7b, 0x11, 0xf1, 0x34, 0x52, + 0xe5, 0xc0, 0x97, 0x66, 0x4a, 0xe0, 0x91, 0x45, 0xc8, 0xb1, 0x3d, 0x6a, + 0x54, 0xc1, 0x32, 0x0f, 0x32, 0xad, 0x25, 0x11, 0x3e, 0x49, 0xad, 0x41, + 0xce, 0x7b, 0xca, 0x95, 0x6b, 0x54, 0x5e, 0x86, 0x1b, 0xce, 0xfa, 0x2a, + 0x60, 0xe8, 0xfa, 0xbb, 0x23, 0xb2, 0x41, 0xbc, 0x7c, 0x98, 0xec, 0x73, + 0x20, 0xed, 0xb3, 0xcf, 0xab, 0x07, 0x24, 0x85, 0x6a, 0x2a, 0x61, 0x76, + 0x28, 0xf8, 0x00, 0x80, 0xeb, 0xd9, 0x3a, 0x63, 0xe2, 0x01, 0xb1, 0xee, + 0x6d, 0xe9, 0x73, 0xe9, 0xb6, 0x75, 0x2e, 0xf9, 0x81, 0xd9, 0xa8, 0x79, + 0xf6, 0x8f, 0xe3, 0x02, 0x7d, 0xf6, 0xea, 0xdc, 0x35, 0xe4, 0x62, 0x0d, + 0x91, 0xba, 0x3e, 0x7d, 0x8b, 0x82, 0xbf, 0x15, 0x74, 0x6a, 0x4e, 0x29, + 0xf8, 0x9b, 0x2c, 0x94, 0x8d, 0xa7, 0x00, 0x4d, 0x7b, 0xbf, 0x35, 0x07, + 0xeb, 0xdd, 0x10, 0xef, 0xd5, 0x2f, 0xe6, 0x98, 0x4b, 0x7e, 0x24, 0x80, + 0xe2, 0x01, 0xf2, 0x66, 0xb7, 0xd3, 0x93, 0xfe, 0x2a, 0xb3, 0x74, 0xed, + 0xec, 0x4b, 0xb1, 0x5f, 0x5f, 0xee, 0x85, 0x44, 0xa7, 0x26, 0xdf, 0xc1, + 0x2e, 0x7a, 0xf3, 0xa5, 0x8f, 0xf8, 0x64, 0xda, 0x65, 0xad, 0x91, 0xe2, + 0x90, 0x94, 0x20, 0x16, 0xb8, 0x61, 0xa5, 0x0a, 0x7d, 0xb4, 0xbf, 0xc0, + 0x10, 0xaf, 0x72, 0x67, }; - static const DES_cblock kDESKey1 = {"BCMDESK1"}; - static const DES_cblock kDESKey2 = {"BCMDESK2"}; - static const DES_cblock kDESKey3 = {"BCMDESK3"}; - static const DES_cblock kDESIV = {"BCMDESIV"}; - static const uint8_t kDESCiphertext[64] = { - 0xa4, 0x30, 0x7a, 0x4c, 0x1f, 0x60, 0x16, 0xd7, 0x4f, 0x41, 0xe1, - 0xbb, 0x27, 0xc4, 0x27, 0x37, 0xd4, 0x7f, 0xb9, 0x10, 0xf8, 0xbc, - 0xaf, 0x93, 0x91, 0xb8, 0x88, 0x24, 0xb1, 0xf6, 0xf8, 0xbd, 0x31, - 0x96, 0x06, 0x76, 0xde, 0x32, 0xcd, 0x29, 0x29, 0xba, 0x70, 0x5f, - 0xea, 0xc0, 0xcb, 0xde, 0xc7, 0x75, 0x90, 0xe0, 0x0f, 0x5e, 0x2c, - 0x0d, 0x49, 0x20, 0xd5, 0x30, 0x83, 0xf8, 0x08, -#if !defined(BORINGSSL_FIPS_BREAK_DES) - 0x5a -#else - 0x00 -#endif + + unsigned sig_len; + if (!rsa_sign_no_self_test(NID_sha256, kRSASignDigest, sizeof(kRSASignDigest), + output, &sig_len, rsa_key) || + !check_test(kRSASignSignature, output, sizeof(kRSASignSignature), + "RSA-sign KAT")) { + fprintf(stderr, "RSA signing test failed.\n"); + goto err; + } + + // RSA Verify KAT + + static const uint8_t kRSAVerifyDigest[32] = { + 0x09, 0x65, 0x2f, 0xd8, 0xed, 0x9d, 0xc2, 0x6d, 0xbc, 0xbf, 0xf2, + 0xa7, 0xa5, 0xed, 0xe1, 0x37, 0x13, 0x78, 0x21, 0x36, 0xcf, 0x8d, + 0x22, 0x3d, 0xab, 0x93, 0xb4, 0x12, 0xa8, 0xb5, 0x15, 0x53, }; - static const uint8_t kPlaintextSHA1[20] = { - 0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd, - 0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8, -#if !defined(BORINGSSL_FIPS_BREAK_SHA_1) - 0x28 -#else - 0x00 -#endif + static const uint8_t kRSAVerifySignature[256] = { + 0xab, 0xe2, 0xcb, 0xc1, 0x3d, 0x6b, 0xd3, 0x9d, 0x48, 0xdb, 0x53, 0x34, + 0xdd, 0xbf, 0x8d, 0x07, 0x0a, 0x93, 0xbd, 0xcb, 0x10, 0x4e, 0x2c, 0xc5, + 0xd0, 0xee, 0x48, 0x6e, 0xe2, 0x95, 0xf6, 0xb3, 0x1b, 0xda, 0x12, 0x6c, + 0x41, 0x89, 0x0b, 0x98, 0xb7, 0x3e, 0x70, 0xe6, 0xb6, 0x5d, 0x82, 0xf9, + 0x5c, 0x66, 0x31, 0x21, 0x75, 0x5a, 0x90, 0x74, 0x4c, 0x8d, 0x1c, 0x21, + 0x14, 0x8a, 0x19, 0x60, 0xbe, 0x0e, 0xca, 0x44, 0x6e, 0x9f, 0xf4, 0x97, + 0xf1, 0x34, 0x5c, 0x53, 0x7e, 0xf8, 0x11, 0x9b, 0x9a, 0x43, 0x98, 0xe9, + 0x5c, 0x5c, 0x6d, 0xe2, 0xb1, 0xc9, 0x55, 0x90, 0x5c, 0x52, 0x99, 0xd8, + 0xce, 0x7a, 0x3b, 0x6a, 0xb7, 0x63, 0x80, 0xd9, 0xba, 0xbd, 0xd1, 0x5f, + 0x61, 0x02, 0x37, 0xe1, 0xf3, 0xf2, 0xaa, 0x1c, 0x1f, 0x1e, 0x77, 0x0b, + 0x62, 0xfb, 0xb5, 0x96, 0x38, 0x1b, 0x2e, 0xbd, 0xd7, 0x7e, 0xce, 0xf9, + 0xc9, 0x0d, 0x4c, 0x92, 0xf7, 0xb6, 0xb0, 0x5f, 0xed, 0x29, 0x36, 0x28, + 0x5f, 0xa9, 0x48, 0x26, 0xe6, 0x20, 0x55, 0x32, 0x2a, 0x33, 0xb6, 0xf0, + 0x4c, 0x74, 0xce, 0x69, 0xe5, 0xd8, 0xd7, 0x37, 0xfb, 0x83, 0x8b, 0x79, + 0xd2, 0xd4, 0x8e, 0x3d, 0xaf, 0x71, 0x38, 0x75, 0x31, 0x88, 0x25, 0x31, + 0xa9, 0x5a, 0xc9, 0x64, 0xd0, 0x2e, 0xa4, 0x13, 0xbf, 0x85, 0x95, 0x29, + 0x82, 0xbb, 0xc0, 0x89, 0x52, 0x7d, 0xaf, 0xf5, 0xb8, 0x45, 0xc9, 0xa0, + 0xf4, 0xd1, 0x4e, 0xf1, 0x95, 0x6d, 0x9c, 0x3a, 0xca, 0xe8, 0x82, 0xd1, + 0x2d, 0xa6, 0x6d, 0xa0, 0xf3, 0x57, 0x94, 0xf5, 0xee, 0x32, 0x23, 0x23, + 0x33, 0x51, 0x7d, 0xb9, 0x31, 0x52, 0x32, 0xa1, 0x83, 0xb9, 0x91, 0x65, + 0x4d, 0xbe, 0xa4, 0x16, 0x15, 0x34, 0x5c, 0x88, 0x53, 0x25, 0x92, 0x67, + 0x44, 0xa5, 0x39, 0x15, }; - static const uint8_t kPlaintextSHA256[32] = { - 0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb, - 0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb, - 0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, -#if !defined(BORINGSSL_FIPS_BREAK_SHA_256) - 0x0f -#else - 0x00 -#endif + if (!rsa_verify_no_self_test(NID_sha256, kRSAVerifyDigest, + sizeof(kRSAVerifyDigest), kRSAVerifySignature, + sizeof(kRSAVerifySignature), rsa_key)) { + fprintf(stderr, "RSA-verify KAT failed.\n"); + goto err; + } + + ret = 1; + +err: + RSA_free(rsa_key); + + return ret; +} + +static int boringssl_self_test_ecc(void) { + int ret = 0; + EC_KEY *ec_key = NULL; + EC_GROUP *ec_group = NULL; + EC_POINT *ec_point_in = NULL; + EC_POINT *ec_point_out = NULL; + BIGNUM *ec_scalar = NULL; + ECDSA_SIG *sig = NULL; + + ec_key = self_test_ecdsa_key(); + if (ec_key == NULL) { + fprintf(stderr, "ECDSA KeyGen failed\n"); + goto err; + } + + // ECDSA Sign/Verify KAT + + static const uint8_t kECDSASignDigest[32] = { + 0x1e, 0x35, 0x93, 0x0b, 0xe8, 0x60, 0xd0, 0x94, 0x2c, 0xa7, 0xbb, + 0xd6, 0xf6, 0xde, 0xd8, 0x7f, 0x15, 0x7e, 0x4d, 0xe2, 0x4f, 0x81, + 0xed, 0x4b, 0x87, 0x5c, 0x0e, 0x01, 0x8e, 0x89, 0xa8, 0x1f, }; - static const uint8_t kPlaintextSHA512[64] = { - 0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e, - 0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74, - 0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c, - 0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c, - 0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b, - 0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68, -#if !defined(BORINGSSL_FIPS_BREAK_SHA_512) - 0x14 -#else - 0x00 -#endif - }; - static const uint8_t kRSASignature[256] = { - 0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33, - 0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d, - 0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5, - 0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6, - 0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9, - 0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63, - 0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29, - 0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff, - 0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68, - 0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8, - 0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14, - 0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9, - 0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3, - 0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a, - 0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4, - 0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5, - 0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae, - 0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e, - 0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b, - 0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf, - 0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d, - 0xd2, 0x0c, 0xb1, -#if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG) - 0x64 -#else - 0x00 -#endif - }; - const uint8_t kDRBGEntropy[48] = - "BCM Known Answer Test DBRG Initial Entropy "; - const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; - const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; - const uint8_t kDRBGOutput[64] = { - 0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5, - 0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1, - 0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9, - 0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32, - 0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d, - 0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22, -#if !defined(BORINGSSL_FIPS_BREAK_DRBG) - 0x95 -#else - 0x00 -#endif - }; - const uint8_t kDRBGEntropy2[48] = - "BCM Known Answer Test DBRG Reseed Entropy "; - const uint8_t kDRBGReseedOutput[64] = { - 0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8, - 0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2, - 0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6, - 0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e, - 0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b, - 0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4, - }; - const uint8_t kECDSASigR[32] = { + static const uint8_t kECDSASignSig[64] = { 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, - 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, -#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG) - 0x0c, -#else - 0x00, -#endif + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x68, + 0x04, 0x73, 0x40, 0x94, 0xb2, 0xd1, 0x90, 0xac, 0x2d, 0x0c, 0xd7, + 0xa5, 0x7f, 0x2f, 0x2e, 0xb2, 0x62, 0xb0, 0x09, 0x16, 0xe1, 0xa6, + 0x70, 0xb5, 0xbb, 0x0d, 0xfd, 0x8e, 0x0c, 0x02, 0x3f, }; - const uint8_t kECDSASigS[32] = { - 0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6, - 0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a, - 0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8, + + // The 'k' value for ECDSA is fixed to avoid an entropy draw. + uint8_t ecdsa_k[32] = {0}; + ecdsa_k[31] = 42; + + sig = ecdsa_sign_with_nonce_for_known_answer_test( + kECDSASignDigest, sizeof(kECDSASignDigest), ec_key, ecdsa_k, + sizeof(ecdsa_k)); + + uint8_t ecdsa_sign_output[64]; + if (sig == NULL || + !serialize_ecdsa_sig(ecdsa_sign_output, sizeof(ecdsa_sign_output), sig) || + !check_test(kECDSASignSig, ecdsa_sign_output, sizeof(ecdsa_sign_output), + "ECDSA-sign signature")) { + fprintf(stderr, "ECDSA-sign KAT failed.\n"); + goto err; + } + + static const uint8_t kECDSAVerifyDigest[32] = { + 0x78, 0x7c, 0x50, 0x5c, 0x60, 0xc9, 0xe4, 0x13, 0x6c, 0xe4, 0x48, + 0xba, 0x93, 0xff, 0x71, 0xfa, 0x9c, 0x18, 0xf4, 0x17, 0x09, 0x4f, + 0xdf, 0x5a, 0xe2, 0x75, 0xc0, 0xcc, 0xd2, 0x67, 0x97, 0xad, }; + static const uint8_t kECDSAVerifySig[64] = { + 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, + 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, 0x0c, 0x2d, + 0x36, 0xe5, 0x79, 0x97, 0x90, 0xbf, 0xbe, 0x21, 0x83, 0xd3, 0x3e, + 0x96, 0xf3, 0xc5, 0x1f, 0x6a, 0x23, 0x2f, 0x2a, 0x24, 0x48, 0x8c, + 0x8e, 0x5f, 0x64, 0xc3, 0x7e, 0xa2, 0xcf, 0x05, 0x29, + }; + + ECDSA_SIG_free(sig); + sig = parse_ecdsa_sig(kECDSAVerifySig, sizeof(kECDSAVerifySig)); + if (!sig || + !ecdsa_do_verify_no_self_test(kECDSAVerifyDigest, + sizeof(kECDSAVerifyDigest), sig, ec_key)) { + fprintf(stderr, "ECDSA-verify KAT failed.\n"); + goto err; + } + + // Primitive Z Computation KAT (IG 9.6). + // kP256Point is SHA256("Primitive Z Computation KAT")×G within P-256. - const uint8_t kP256Point[65] = { + static const uint8_t kP256Point[65] = { 0x04, 0x4e, 0xc1, 0x94, 0x8c, 0x5c, 0xf4, 0x37, 0x35, 0x0d, 0xa3, 0xf9, 0x55, 0xf9, 0x8b, 0x26, 0x23, 0x5c, 0x43, 0xe0, 0x83, 0x51, 0x2b, 0x0d, 0x4b, 0x56, 0x24, 0xc3, 0xe4, 0xa5, 0xa8, 0xe2, 0xe9, @@ -486,50 +491,64 @@ int boringssl_fips_self_test( 0x79, 0x93, 0x7c, 0x0b, 0x92, 0x2b, 0x7f, 0x17, 0xa5, 0x80, }; // kP256Scalar is SHA256("Primitive Z Computation KAT scalar"). - const uint8_t kP256Scalar[32] = { + static const uint8_t kP256Scalar[32] = { 0xe7, 0x60, 0x44, 0x91, 0x26, 0x9a, 0xfb, 0x5b, 0x10, 0x2d, 0x6e, 0xa5, 0x2c, 0xb5, 0x9f, 0xeb, 0x70, 0xae, 0xde, 0x6c, 0xe3, 0xbf, 0xb3, 0xe0, 0x10, 0x54, 0x85, 0xab, 0xd8, 0x61, 0xd7, 0x7b, }; // kP256PointResult is |kP256Scalar|×|kP256Point|. - const uint8_t kP256PointResult[65] = { + static const uint8_t kP256PointResult[65] = { 0x04, 0xf1, 0x63, 0x00, 0x88, 0xc5, 0xd5, 0xe9, 0x05, 0x52, 0xac, 0xb6, 0xec, 0x68, 0x76, 0xb8, 0x73, 0x7f, 0x0f, 0x72, 0x34, 0xe6, 0xbb, 0x30, 0x32, 0x22, 0x37, 0xb6, 0x2a, 0x80, 0xe8, 0x9e, 0x6e, 0x6f, 0x36, 0x02, 0xe7, 0x21, 0xd2, 0x31, 0xdb, 0x94, 0x63, 0xb7, 0xd8, 0x19, 0x0e, 0xc2, 0xc0, 0xa7, 0x2f, 0x15, 0x49, 0x1a, 0xa2, - 0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a, -#if !defined(BORINGSSL_FIPS_BREAK_Z_COMPUTATION) - 0x0c, -#else - 0x00, -#endif - }; - const uint8_t kTLSOutput[32] = { - 0x67, 0x85, 0xde, 0x60, 0xfc, 0x0a, 0x83, 0xe9, 0xa2, 0x2a, 0xb3, - 0xf0, 0x27, 0x0c, 0xba, 0xf7, 0xfa, 0x82, 0x3d, 0x14, 0x77, 0x1d, - 0x86, 0x29, 0x79, 0x39, 0x77, 0x8a, 0xd5, 0x0e, 0x9d, -#if !defined(BORINGSSL_FIPS_BREAK_TLS_KDF) - 0x32, -#else - 0x00, -#endif - }; - const uint8_t kTLSSecret[32] = { - 0xbf, 0xe4, 0xb7, 0xe0, 0x26, 0x55, 0x5f, 0x6a, 0xdf, 0x5d, 0x27, - 0xd6, 0x89, 0x99, 0x2a, 0xd6, 0xf7, 0x65, 0x66, 0x07, 0x4b, 0x55, - 0x5f, 0x64, 0x55, 0xcd, 0xd5, 0x77, 0xa4, 0xc7, 0x09, 0x61, - }; - const char kTLSLabel[] = "FIPS self test"; - const uint8_t kTLSSeed1[16] = { - 0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2, - 0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65, - }; - const uint8_t kTLSSeed2[16] = { - 0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c, - 0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81, + 0x7c, 0x41, 0x8f, 0xaf, 0x9c, 0x40, 0xaf, 0x2e, 0x4a, 0x0c, }; + ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (ec_group == NULL) { + fprintf(stderr, "Failed to create P-256 group.\n"); + goto err; + } + ec_point_in = EC_POINT_new(ec_group); + ec_point_out = EC_POINT_new(ec_group); + ec_scalar = BN_new(); + uint8_t z_comp_result[65]; + if (ec_point_in == NULL || ec_point_out == NULL || ec_scalar == NULL || + !EC_POINT_oct2point(ec_group, ec_point_in, kP256Point, sizeof(kP256Point), + NULL) || + !BN_bin2bn(kP256Scalar, sizeof(kP256Scalar), ec_scalar) || + !ec_point_mul_no_self_test(ec_group, ec_point_out, NULL, ec_point_in, + ec_scalar, NULL) || + !EC_POINT_point2oct(ec_group, ec_point_out, POINT_CONVERSION_UNCOMPRESSED, + z_comp_result, sizeof(z_comp_result), NULL) || + !check_test(kP256PointResult, z_comp_result, sizeof(z_comp_result), + "Z Computation Result")) { + fprintf(stderr, "Z-computation KAT failed.\n"); + goto err; + } + + ret = 1; + +err: + EC_KEY_free(ec_key); + EC_POINT_free(ec_point_in); + EC_POINT_free(ec_point_out); + EC_GROUP_free(ec_group); + BN_free(ec_scalar); + ECDSA_SIG_free(sig); + + return ret; +} + +static int boringssl_self_test_ffdh(void) { + int ret = 0; + DH *dh = NULL; + BIGNUM *ffdhe2048_value = NULL; + + // FFC Diffie-Hellman KAT + // kFFDHE2048PublicValueData is an arbitrary public value, mod // kFFDHE2048Data. (The private key happens to be 4096.) static const BN_ULONG kFFDHE2048PublicValueData[] = { @@ -550,8 +569,7 @@ int boringssl_fips_self_test( TOBN(0xbae7b0b3, 0x6e362dc0), TOBN(0xa57c73bd, 0xdc70fb82), TOBN(0xfaff50d2, 0x9d573457), TOBN(0x352bd399, 0xbe84058e), }; - - const uint8_t kDHOutput[2048 / 8] = { + static const uint8_t kDHOutput[2048 / 8] = { 0x2a, 0xe6, 0xd3, 0xa6, 0x13, 0x58, 0x8e, 0xce, 0x53, 0xaa, 0xf6, 0x5d, 0x9a, 0xae, 0x02, 0x12, 0xf5, 0x80, 0x3d, 0x06, 0x09, 0x76, 0xac, 0x57, 0x37, 0x9e, 0xab, 0x38, 0x62, 0x25, 0x05, 0x1d, 0xf3, 0xa9, 0x39, 0x60, @@ -573,23 +591,150 @@ int boringssl_fips_self_test( 0x06, 0x80, 0x2a, 0x4e, 0x5a, 0xf0, 0x1e, 0xaa, 0xcb, 0xab, 0x06, 0x0e, 0x27, 0x0f, 0xd9, 0x88, 0xd9, 0x01, 0xe3, 0x07, 0xeb, 0xdf, 0xc3, 0x12, 0xe3, 0x40, 0x88, 0x7b, 0x5f, 0x59, 0x78, 0x6e, 0x26, 0x20, 0xc3, 0xdf, - 0xc8, 0xe4, 0x5e, -#if !defined(BORINGSSL_FIPS_BREAK_FFC_DH) - 0xb8, -#else - 0x00, -#endif + 0xc8, 0xe4, 0x5e, 0xb8, }; + ffdhe2048_value = BN_new(); + if (ffdhe2048_value) { + bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData, + OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData)); + } + + dh = self_test_dh(); + uint8_t dh_out[sizeof(kDHOutput)]; + if (dh == NULL || ffdhe2048_value == NULL || sizeof(dh_out) != DH_size(dh) || + dh_compute_key_padded_no_self_test(dh_out, ffdhe2048_value, dh) != + sizeof(dh_out) || + !check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH")) { + fprintf(stderr, "FFDH failed.\n"); + goto err; + } + + ret = 1; + +err: + DH_free(dh); + BN_free(ffdhe2048_value); + + return ret; +} + +#if defined(BORINGSSL_FIPS) + +static void run_self_test_rsa(void) { + FIPS_service_indicator_lock_state(); + if (!boringssl_self_test_rsa()) { + BORINGSSL_FIPS_abort(); + } + FIPS_service_indicator_unlock_state(); +} + +DEFINE_STATIC_ONCE(g_self_test_once_rsa); + +void boringssl_ensure_rsa_self_test(void) { + CRYPTO_once(g_self_test_once_rsa_bss_get(), run_self_test_rsa); +} + +static void run_self_test_ecc(void) { + FIPS_service_indicator_lock_state(); + if (!boringssl_self_test_ecc()) { + BORINGSSL_FIPS_abort(); + } + FIPS_service_indicator_unlock_state(); +} + +DEFINE_STATIC_ONCE(g_self_test_once_ecc); + +void boringssl_ensure_ecc_self_test(void) { + CRYPTO_once(g_self_test_once_ecc_bss_get(), run_self_test_ecc); +} + +static void run_self_test_ffdh(void) { + FIPS_service_indicator_lock_state(); + if (!boringssl_self_test_ffdh()) { + BORINGSSL_FIPS_abort(); + } + FIPS_service_indicator_unlock_state(); +} + +DEFINE_STATIC_ONCE(g_self_test_once_ffdh); + +void boringssl_ensure_ffdh_self_test(void) { + CRYPTO_once(g_self_test_once_ffdh_bss_get(), run_self_test_ffdh); +} + +#endif // BORINGSSL_FIPS + + +// Startup self tests. +// +// These tests are run at process start when in FIPS mode. + +int boringssl_self_test_sha256(void) { + static const uint8_t kInput[16] = { + 0xff, 0x3b, 0x85, 0x7d, 0xa7, 0x23, 0x6a, 0x2b, + 0xaa, 0x0f, 0x39, 0x6b, 0x51, 0x52, 0x22, 0x17, + }; + static const uint8_t kPlaintextSHA256[32] = { + 0x7f, 0xe4, 0xd5, 0xf1, 0xa1, 0xe3, 0x82, 0x87, 0xd9, 0x58, 0xf5, + 0x11, 0xc7, 0x1d, 0x5e, 0x27, 0x5e, 0xcc, 0xd2, 0x66, 0xcf, 0xb9, + 0xc8, 0xc6, 0x60, 0xd8, 0x92, 0x1e, 0x57, 0xfd, 0x46, 0x75, + }; + uint8_t output[SHA256_DIGEST_LENGTH]; + + // SHA-256 KAT + SHA256(kInput, sizeof(kInput), output); + return check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), + "SHA-256 KAT"); +} + +int boringssl_self_test_sha512(void) { + static const uint8_t kInput[16] = { + 0x21, 0x25, 0x12, 0xf8, 0xd2, 0xad, 0x83, 0x22, + 0x78, 0x1c, 0x6c, 0x4d, 0x69, 0xa9, 0xda, 0xa1, + }; + static const uint8_t kPlaintextSHA512[64] = { + 0x29, 0x3c, 0x94, 0x35, 0x4e, 0x98, 0x83, 0xe5, 0xc2, 0x78, 0x36, + 0x7a, 0xe5, 0x18, 0x90, 0xbf, 0x35, 0x41, 0x01, 0x64, 0x19, 0x8d, + 0x26, 0xeb, 0xe1, 0xf8, 0x2f, 0x04, 0x8e, 0xfa, 0x8b, 0x2b, 0xc6, + 0xb2, 0x9d, 0x5d, 0x46, 0x76, 0x5a, 0xc8, 0xb5, 0x25, 0xa3, 0xea, + 0x52, 0x84, 0x47, 0x6d, 0x6d, 0xf4, 0xc9, 0x71, 0xf3, 0x3d, 0x89, + 0x4c, 0x3b, 0x20, 0x8c, 0x5b, 0x75, 0xe8, 0xf8, 0x7c, + }; + uint8_t output[SHA512_DIGEST_LENGTH]; + + // SHA-512 KAT + SHA512(kInput, sizeof(kInput), output); + return check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), + "SHA-512 KAT"); +} + +int boringssl_self_test_hmac_sha256(void) { + static const uint8_t kInput[16] = { + 0xda, 0xd9, 0x12, 0x93, 0xdf, 0xcf, 0x2a, 0x7c, + 0x8e, 0xcd, 0x13, 0xfe, 0x35, 0x3f, 0xa7, 0x5b, + }; + static const uint8_t kPlaintextHMACSHA256[32] = { + 0x36, 0x5f, 0x5b, 0xd5, 0xf5, 0xeb, 0xfd, 0xc7, 0x6e, 0x53, 0xa5, + 0x73, 0x6d, 0x73, 0x20, 0x13, 0xaa, 0xd3, 0xbc, 0x86, 0x4b, 0xb8, + 0x84, 0x94, 0x16, 0x46, 0x88, 0x9c, 0x48, 0xee, 0xa9, 0x0e, + }; + uint8_t output[EVP_MAX_MD_SIZE]; + + unsigned output_len; + HMAC(EVP_sha256(), kInput, sizeof(kInput), kInput, sizeof(kInput), output, + &output_len); + return output_len == sizeof(kPlaintextHMACSHA256) && + check_test(kPlaintextHMACSHA256, output, sizeof(kPlaintextHMACSHA256), + "HMAC-SHA-256 KAT"); +} + +static int boringssl_self_test_fast(void) { + static const uint8_t kAESKey[16] = "BoringCrypto Key"; + static const uint8_t kAESIV[16] = {0}; + EVP_AEAD_CTX aead_ctx; EVP_AEAD_CTX_zero(&aead_ctx); - RSA *rsa_key = NULL; - EC_KEY *ec_key = NULL; - EC_GROUP *ec_group = NULL; - EC_POINT *ec_point_in = NULL; - EC_POINT *ec_point_out = NULL; - BIGNUM *ec_scalar = NULL; - ECDSA_SIG *sig = NULL; int ret = 0; AES_KEY aes_key; @@ -597,28 +742,48 @@ int boringssl_fips_self_test( uint8_t output[256]; // AES-CBC Encryption KAT + static const uint8_t kAESCBCEncPlaintext[32] = { + 0x07, 0x86, 0x09, 0xa6, 0xc5, 0xac, 0x25, 0x44, 0x69, 0x9a, 0xdf, + 0x68, 0x2f, 0xa3, 0x77, 0xf9, 0xbe, 0x8a, 0xb6, 0xae, 0xf5, 0x63, + 0xe8, 0xc5, 0x6a, 0x36, 0xb8, 0x4f, 0x55, 0x7f, 0xad, 0xd3, + }; + static const uint8_t kAESCBCEncCiphertext[sizeof(kAESCBCEncPlaintext)] = { + 0x56, 0x46, 0xc1, 0x41, 0xf4, 0x13, 0xd6, 0xff, 0x62, 0x92, 0x41, + 0x7a, 0x26, 0xc6, 0x86, 0xbd, 0x30, 0x5f, 0xb6, 0x57, 0xa7, 0xd2, + 0x50, 0x3a, 0xc5, 0x5e, 0x8e, 0x93, 0x40, 0xf2, 0x10, 0xd8, + }; memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { fprintf(stderr, "AES_set_encrypt_key failed.\n"); goto err; } - AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv, - AES_ENCRYPT); - if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), - "AES-CBC Encryption KAT")) { + AES_cbc_encrypt(kAESCBCEncPlaintext, output, sizeof(kAESCBCEncPlaintext), + &aes_key, aes_iv, AES_ENCRYPT); + if (!check_test(kAESCBCEncCiphertext, output, sizeof(kAESCBCEncCiphertext), + "AES-CBC-encrypt KAT")) { goto err; } // AES-CBC Decryption KAT + static const uint8_t kAESCBCDecCiphertext[32] = { + 0x34, 0x7a, 0xa5, 0xa0, 0x24, 0xb2, 0x82, 0x57, 0xb3, 0x65, 0x10, + 0xbe, 0x58, 0x3d, 0x4f, 0x47, 0xad, 0xb7, 0xbb, 0xee, 0xdc, 0x60, + 0x05, 0xbb, 0xbd, 0x0d, 0x0a, 0x9f, 0x06, 0xbb, 0x7b, 0x10, + }; + static const uint8_t kAESCBCDecPlaintext[sizeof(kAESCBCDecCiphertext)] = { + 0x51, 0xa7, 0xa0, 0x1f, 0x6b, 0x79, 0x6c, 0xcd, 0x48, 0x03, 0xa1, + 0x41, 0xdc, 0x56, 0xa6, 0xc2, 0x16, 0xb5, 0xd1, 0xd3, 0xb7, 0x06, + 0xb2, 0x25, 0x6f, 0xa6, 0xd0, 0xd2, 0x0e, 0x6f, 0x19, 0xb5, + }; memcpy(aes_iv, kAESIV, sizeof(kAESIV)); if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { fprintf(stderr, "AES_set_decrypt_key failed.\n"); goto err; } - AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + AES_cbc_encrypt(kAESCBCDecCiphertext, output, sizeof(kAESCBCDecCiphertext), &aes_key, aes_iv, AES_DECRYPT); - if (!check_test(kPlaintext, output, sizeof(kPlaintext), - "AES-CBC Decryption KAT")) { + if (!check_test(kAESCBCDecPlaintext, output, sizeof(kAESCBCDecPlaintext), + "AES-CBC-decrypt KAT")) { goto err; } @@ -632,194 +797,115 @@ int boringssl_fips_self_test( } // AES-GCM Encryption KAT + static const uint8_t kAESGCMEncPlaintext[32] = { + 0x8f, 0xcc, 0x40, 0x99, 0x80, 0x8e, 0x75, 0xca, 0xaf, 0xf5, 0x82, + 0x89, 0x88, 0x48, 0xa8, 0x8d, 0x80, 0x8b, 0x55, 0xab, 0x4e, 0x93, + 0x70, 0x79, 0x7d, 0x94, 0x0b, 0xe8, 0xcc, 0x1d, 0x78, 0x84, + }; + static const uint8_t kAESGCMCiphertext[sizeof(kAESGCMEncPlaintext) + 16] = { + 0x87, 0x7b, 0xd5, 0x8d, 0x96, 0x3e, 0x4b, 0xe6, 0x64, 0x94, 0x40, 0x2f, + 0x61, 0x9b, 0x7e, 0x56, 0x52, 0x7d, 0xa4, 0x5a, 0xf9, 0xa6, 0xe2, 0xdb, + 0x1c, 0x63, 0x2e, 0x97, 0x93, 0x0f, 0xfb, 0xed, 0xb5, 0x9e, 0x1c, 0x20, + 0xb2, 0xb0, 0x58, 0xda, 0x48, 0x07, 0x2d, 0xbd, 0x96, 0x0d, 0x34, 0xc6, + }; if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce, EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), - kPlaintext, sizeof(kPlaintext), NULL, 0) || + kAESGCMEncPlaintext, sizeof(kAESGCMEncPlaintext), NULL, + 0) || !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), - "AES-GCM Encryption KAT")) { + "AES-GCM-encrypt KAT")) { fprintf(stderr, "EVP_AEAD_CTX_seal for AES-128-GCM failed.\n"); goto err; } // AES-GCM Decryption KAT + static const uint8_t kAESGCMDecCiphertext[48] = { + 0x35, 0xf3, 0x05, 0x8f, 0x87, 0x57, 0x60, 0xff, 0x09, 0xd3, 0x12, 0x0f, + 0x70, 0xc4, 0xbc, 0x9e, 0xd7, 0xa8, 0x68, 0x72, 0xe1, 0x34, 0x52, 0x20, + 0x21, 0x76, 0xf7, 0x37, 0x1a, 0xe0, 0x4f, 0xaa, 0xe1, 0xdd, 0x39, 0x19, + 0x20, 0xf5, 0xd1, 0x39, 0x53, 0xd8, 0x96, 0x78, 0x59, 0x94, 0x82, 0x3c, + }; + static const uint8_t kAESGCMDecPlaintext[sizeof(kAESGCMDecCiphertext) - 16] = + { + 0x3d, 0x44, 0x90, 0x9b, 0x91, 0xe7, 0x5e, 0xd3, 0xc2, 0xb2, 0xd0, + 0xa9, 0x99, 0x17, 0x6a, 0x45, 0x05, 0x5e, 0x99, 0x83, 0x56, 0x01, + 0xc0, 0x82, 0x40, 0x81, 0xd2, 0x48, 0x45, 0xf2, 0xcc, 0xc3, + }; if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce, EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), - kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL, - 0) || - !check_test(kPlaintext, output, sizeof(kPlaintext), - "AES-GCM Decryption KAT")) { - fprintf(stderr, "EVP_AEAD_CTX_open for AES-128-GCM failed.\n"); - goto err; - } - - DES_key_schedule des1, des2, des3; - DES_cblock des_iv; - DES_set_key(&kDESKey1, &des1); - DES_set_key(&kDESKey2, &des2); - DES_set_key(&kDESKey3, &des3); - - // 3DES Encryption KAT - memcpy(&des_iv, &kDESIV, sizeof(des_iv)); - DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2, - &des3, &des_iv, DES_ENCRYPT); - if (!check_test(kDESCiphertext, output, sizeof(kDESCiphertext), - "3DES Encryption KAT")) { - goto err; - } - - // 3DES Decryption KAT - memcpy(&des_iv, &kDESIV, sizeof(des_iv)); - DES_ede3_cbc_encrypt(kDESCiphertext, output, sizeof(kDESCiphertext), &des1, - &des2, &des3, &des_iv, DES_DECRYPT); - if (!check_test(kPlaintext, output, sizeof(kPlaintext), - "3DES Decryption KAT")) { + kAESGCMDecCiphertext, sizeof(kAESGCMDecCiphertext), + NULL, 0) || + !check_test(kAESGCMDecPlaintext, output, sizeof(kAESGCMDecPlaintext), + "AES-GCM-decrypt KAT")) { + fprintf(stderr, + "AES-GCM-decrypt KAT failed because EVP_AEAD_CTX_open failed.\n"); goto err; } // SHA-1 KAT - SHA1(kPlaintext, sizeof(kPlaintext), output); - if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1), + static const uint8_t kSHA1Input[16] = { + 0x13, 0x2f, 0xd9, 0xba, 0xd5, 0xc1, 0x82, 0x62, + 0x63, 0xba, 0xfb, 0xb6, 0x99, 0xf7, 0x07, 0xa5, + }; + static const uint8_t kSHA1Digest[20] = { + 0x94, 0x19, 0x55, 0x93, 0x0a, 0x58, 0x29, 0x38, 0xeb, 0xf5, + 0x09, 0x11, 0x6d, 0x1a, 0xfd, 0x0f, 0x1e, 0x11, 0xe3, 0xcb, + }; + SHA1(kSHA1Input, sizeof(kSHA1Input), output); + if (!check_test(kSHA1Digest, output, sizeof(kSHA1Digest), "SHA-1 KAT")) { goto err; } - // SHA-256 KAT - SHA256(kPlaintext, sizeof(kPlaintext), output); - if (!check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), - "SHA-256 KAT")) { - goto err; - } - - // SHA-512 KAT - SHA512(kPlaintext, sizeof(kPlaintext), output); - if (!check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), - "SHA-512 KAT")) { - goto err; - } - - rsa_key = self_test_rsa_key(); - if (rsa_key == NULL) { - fprintf(stderr, "RSA KeyGen failed\n"); - goto err; - } - - // RSA Sign KAT - unsigned sig_len; - - // Disable blinding for the power-on tests because it's not needed and - // triggers an entropy draw. - rsa_key->flags |= RSA_FLAG_NO_BLINDING; - - if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output, - &sig_len, rsa_key) || - !check_test(kRSASignature, output, sizeof(kRSASignature), - "RSA Sign KAT")) { - fprintf(stderr, "RSA signing test failed.\n"); - goto err; - } - - // RSA Verify KAT - if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), - kRSASignature, sizeof(kRSASignature), rsa_key)) { - fprintf(stderr, "RSA Verify KAT failed.\n"); - goto err; - } - - ec_key = self_test_ecdsa_key(); - if (ec_key == NULL) { - fprintf(stderr, "ECDSA KeyGen failed\n"); - goto err; - } - - // ECDSA Sign/Verify KAT - - // The 'k' value for ECDSA is fixed to avoid an entropy draw. - uint8_t ecdsa_k[32] = {0}; - ecdsa_k[31] = 42; - - sig = ecdsa_sign_with_nonce_for_known_answer_test( - kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key, ecdsa_k, - sizeof(ecdsa_k)); - - uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)]; - uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)]; - if (sig == NULL || - BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) || - !BN_bn2bin(sig->r, ecdsa_r_bytes) || - BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) || - !BN_bn2bin(sig->s, ecdsa_s_bytes) || - !check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") || - !check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) { - fprintf(stderr, "ECDSA signature KAT failed.\n"); - goto err; - } - - if (!ECDSA_do_verify(kPlaintextSHA256, sizeof(kPlaintextSHA256), sig, - ec_key)) { - fprintf(stderr, "ECDSA verification KAT failed.\n"); - goto err; - } - - // Primitive Z Computation KAT (IG 9.6). - ec_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); - if (ec_group == NULL) { - fprintf(stderr, "Failed to create P-256 group.\n"); - goto err; - } - ec_point_in = EC_POINT_new(ec_group); - ec_point_out = EC_POINT_new(ec_group); - ec_scalar = BN_new(); - uint8_t z_comp_result[65]; - if (ec_point_in == NULL || ec_point_out == NULL || ec_scalar == NULL || - !EC_POINT_oct2point(ec_group, ec_point_in, kP256Point, sizeof(kP256Point), - NULL) || - !BN_bin2bn(kP256Scalar, sizeof(kP256Scalar), ec_scalar) || - !EC_POINT_mul(ec_group, ec_point_out, NULL, ec_point_in, ec_scalar, - NULL) || - !EC_POINT_point2oct(ec_group, ec_point_out, POINT_CONVERSION_UNCOMPRESSED, - z_comp_result, sizeof(z_comp_result), NULL) || - !check_test(kP256PointResult, z_comp_result, sizeof(z_comp_result), - "Z Computation Result")) { - fprintf(stderr, "Z Computation KAT failed.\n"); - goto err; - } - - // FFC Diffie-Hellman KAT - - BIGNUM *const ffdhe2048_value = BN_new(); - DH *const dh = self_test_dh(); - int dh_ok = 0; - if (ffdhe2048_value && dh) { - bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData, - OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData)); - - uint8_t dh_out[sizeof(kDHOutput)]; - dh_ok = - sizeof(dh_out) == DH_size(dh) && - DH_compute_key_padded(dh_out, ffdhe2048_value, dh) == sizeof(dh_out) && - check_test(kDHOutput, dh_out, sizeof(dh_out), "FFC DH"); - } - - BN_free(ffdhe2048_value); - DH_free(dh); - if (!dh_ok) { - fprintf(stderr, "FFDH failed.\n"); + if (!boringssl_self_test_sha256() || + !boringssl_self_test_sha512() || + !boringssl_self_test_hmac_sha256()) { goto err; } // DBRG KAT + static const uint8_t kDRBGEntropy[48] = { + 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, 0xe5, + 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, 0xbb, 0x4a, + 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, 0x40, 0xc2, 0xb5, 0x0b, + 0xab, 0xe1, 0x4a, 0xae, 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, + }; + static const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; + static const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; + static const uint8_t kDRBGOutput[64] = { + 0x19, 0x1f, 0x2b, 0x49, 0x76, 0x85, 0xfd, 0x51, 0xb6, 0x56, 0xbc, + 0x1c, 0x7d, 0xd5, 0xdd, 0x44, 0x76, 0xa3, 0x5e, 0x17, 0x9b, 0x8e, + 0xb8, 0x98, 0x65, 0x12, 0xca, 0x35, 0x6c, 0xa0, 0x6f, 0xa0, 0x22, + 0xe4, 0xf6, 0xd8, 0x43, 0xed, 0x4e, 0x2d, 0x97, 0x39, 0x43, 0x3b, + 0x57, 0xfc, 0x23, 0x3f, 0x71, 0x0a, 0xe0, 0xed, 0xfe, 0xd5, 0xb8, + 0x67, 0x7a, 0x00, 0x39, 0xb2, 0x6e, 0xa9, 0x25, 0x97, + }; + static const uint8_t kDRBGEntropy2[48] = { + 0xc7, 0x16, 0x1c, 0xa3, 0x6c, 0x23, 0x09, 0xb7, 0x16, 0xe9, 0x85, 0x9b, + 0xb9, 0x6c, 0x6d, 0x49, 0xbd, 0xc8, 0x35, 0x21, 0x03, 0xa1, 0x8c, 0xd2, + 0x4e, 0xf4, 0x2e, 0xc9, 0x7e, 0xf4, 0x6b, 0xf4, 0x46, 0xeb, 0x1a, 0x45, + 0x76, 0xc1, 0x86, 0xe9, 0x35, 0x18, 0x03, 0x76, 0x3a, 0x79, 0x12, 0xfe, + }; + static const uint8_t kDRBGReseedOutput[64] = { + 0x00, 0xf2, 0x05, 0xaa, 0xfd, 0x11, 0x6c, 0x77, 0xbc, 0x81, 0x86, + 0x99, 0xca, 0x51, 0xcf, 0x80, 0x15, 0x9f, 0x02, 0x9e, 0x0b, 0xcd, + 0x26, 0xc8, 0x4b, 0x87, 0x8a, 0x15, 0x1a, 0xdd, 0xf2, 0xf3, 0xeb, + 0x94, 0x0b, 0x08, 0xc8, 0xc9, 0x57, 0xa4, 0x0b, 0x4b, 0x0f, 0x13, + 0xde, 0x7c, 0x0c, 0x6a, 0xac, 0x34, 0x4a, 0x9a, 0xf2, 0xd0, 0x83, + 0x02, 0x05, 0x17, 0xc9, 0x81, 0x8f, 0x2a, 0x81, 0x92, + }; CTR_DRBG_STATE drbg; if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, sizeof(kDRBGPersonalization)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, sizeof(kDRBGAD)) || !check_test(kDRBGOutput, output, sizeof(kDRBGOutput), - "DBRG Generate KAT") || + "DRBG Generate KAT") || !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, sizeof(kDRBGAD)) || !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), - "DRBG Reseed KAT")) { + "DRBG-reseed KAT")) { fprintf(stderr, "CTR-DRBG failed.\n"); goto err; } @@ -832,43 +918,129 @@ int boringssl_fips_self_test( } // TLS KDF KAT + static const uint8_t kTLSSecret[32] = { + 0xab, 0xc3, 0x65, 0x7b, 0x09, 0x4c, 0x76, 0x28, 0xa0, 0xb2, 0x82, + 0x99, 0x6f, 0xe7, 0x5a, 0x75, 0xf4, 0x98, 0x4f, 0xd9, 0x4d, 0x4e, + 0xcc, 0x2f, 0xcf, 0x53, 0xa2, 0xc4, 0x69, 0xa3, 0xf7, 0x31, + }; + static const char kTLSLabel[] = "FIPS self test"; + static const uint8_t kTLSSeed1[16] = { + 0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2, + 0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65, + }; + static const uint8_t kTLSSeed2[16] = { + 0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c, + 0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81, + }; + static const uint8_t kTLSOutput[32] = { + 0xe2, 0x1d, 0xd6, 0xc2, 0x68, 0xc7, 0x57, 0x03, 0x2c, 0x2c, 0xeb, + 0xbb, 0xb8, 0xa9, 0x7d, 0xe9, 0xee, 0xe6, 0xc9, 0x47, 0x83, 0x0a, + 0xbd, 0x11, 0x60, 0x5d, 0xd5, 0x2c, 0x47, 0xb6, 0x05, 0x88, + }; uint8_t tls_output[sizeof(kTLSOutput)]; if (!CRYPTO_tls1_prf(EVP_sha256(), tls_output, sizeof(tls_output), kTLSSecret, sizeof(kTLSSecret), kTLSLabel, sizeof(kTLSLabel), kTLSSeed1, sizeof(kTLSSeed1), kTLSSeed2, sizeof(kTLSSeed2)) || - !check_test(kTLSOutput, tls_output, sizeof(kTLSOutput), "TLS KDF KAT")) { + !check_test(kTLSOutput, tls_output, sizeof(kTLSOutput), "TLS-KDF KAT")) { fprintf(stderr, "TLS KDF failed.\n"); goto err; } + // TLS v1.3: derives a dummy client-early-traffic secret. + static const uint8_t kTLS13Secret[32] = { + 0x02, 0x4a, 0x0d, 0x80, 0xf3, 0x57, 0xf2, 0x49, 0x9a, 0x12, 0x44, + 0xda, 0xc2, 0x6d, 0xab, 0x66, 0xfc, 0x13, 0xed, 0x85, 0xfc, 0xa7, + 0x1d, 0xac, 0xe1, 0x46, 0x21, 0x11, 0x19, 0x52, 0x58, 0x74, + }; + static const uint8_t kTLS13Salt[16] = { + 0x54, 0x61, 0x11, 0x36, 0x75, 0x91, 0xf0, 0xf8, + 0x92, 0xec, 0x70, 0xbd, 0x78, 0x2a, 0xef, 0x61, + }; + static const uint8_t kTLS13Label[] = "c e traffic"; + static const uint8_t kTLS13ClientHelloHash[32] = { + 0x1d, 0xe8, 0x67, 0xed, 0x93, 0x6a, 0x73, 0x65, 0x9b, 0x05, 0xcf, + 0x8a, 0x22, 0x77, 0xb7, 0x37, 0x29, 0xf2, 0x44, 0x94, 0x81, 0x6a, + 0x83, 0x33, 0x7f, 0x09, 0xbb, 0x6c, 0xc2, 0x6f, 0x48, 0x9c, + }; + static const uint8_t kTLS13ExpandLabelOutput[32] = { + 0x62, 0x91, 0x52, 0x90, 0x2e, 0xc9, 0xcf, 0x9c, 0x5f, 0x1e, 0x0a, + 0xb7, 0x00, 0x33, 0x42, 0x24, 0xc4, 0xe3, 0xba, 0x01, 0x40, 0x32, + 0x06, 0xab, 0x09, 0x23, 0x8a, 0xdd, 0x01, 0xa4, 0x05, 0xcd, + }; + uint8_t tls13_extract_output[32]; + size_t tls13_extract_output_len; + uint8_t tls13_expand_label_output[32]; + if (!HKDF_extract(tls13_extract_output, &tls13_extract_output_len, + EVP_sha256(), kTLS13Secret, sizeof(kTLS13Secret), + kTLS13Salt, sizeof(kTLS13Salt)) || + tls13_extract_output_len != sizeof(tls13_extract_output) || + !CRYPTO_tls13_hkdf_expand_label( + tls13_expand_label_output, sizeof(tls13_expand_label_output), + EVP_sha256(), tls13_extract_output, sizeof(tls13_extract_output), + kTLS13Label, sizeof(kTLS13Label) - 1, kTLS13ClientHelloHash, + sizeof(kTLS13ClientHelloHash)) || + !check_test(kTLS13ExpandLabelOutput, tls13_expand_label_output, + sizeof(kTLS13ExpandLabelOutput), + "CRYPTO_tls13_hkdf_expand_label")) { + fprintf(stderr, "TLSv1.3 KDF failed.\n"); + goto err; + } + + // HKDF + static const uint8_t kHKDFSecret[32] = { + 0x68, 0x67, 0x85, 0x04, 0xb9, 0xb3, 0xad, 0xd1, 0x7d, 0x59, 0x67, + 0xa1, 0xa7, 0xbd, 0x37, 0x99, 0x3f, 0xd8, 0xa3, 0x3c, 0xe7, 0x30, + 0x30, 0x71, 0xf3, 0x9c, 0x09, 0x6d, 0x16, 0x35, 0xb3, 0xc9, + }; + static const uint8_t kHKDFSalt[32] = { + 0x8a, 0xab, 0x18, 0xb4, 0x9b, 0x0a, 0x17, 0xf9, 0xe8, 0xe6, 0x97, + 0x1a, 0x3d, 0xff, 0xda, 0x9b, 0x26, 0x8b, 0x3d, 0x17, 0x78, 0x0a, + 0xb3, 0xea, 0x65, 0xdb, 0x2a, 0xc0, 0x29, 0x9c, 0xfa, 0x72, + }; + static const uint8_t kHKDFInfo[32] = { + 0xe5, 0x6f, 0xf9, 0xe1, 0x18, 0x5e, 0x64, 0x8c, 0x6c, 0x8f, 0xee, + 0xc6, 0x93, 0x5a, 0xc5, 0x14, 0x8c, 0xf3, 0xd9, 0x78, 0xd2, 0x3a, + 0x86, 0xdd, 0x01, 0xdf, 0xb9, 0xe9, 0x5e, 0xe5, 0x1a, 0x56, + }; + static const uint8_t kHKDFOutput[32] = { + 0xa6, 0x29, 0xb4, 0xd7, 0xf4, 0xc1, 0x16, 0x64, 0x71, 0x5e, 0xa4, + 0xa8, 0xe6, 0x60, 0x8c, 0xf3, 0xc1, 0xa5, 0x03, 0xe2, 0x22, 0xf9, + 0x89, 0xe2, 0x12, 0x18, 0xbe, 0xef, 0x16, 0x86, 0xe0, 0xec, + }; + uint8_t hkdf_output[sizeof(kHKDFOutput)]; + if (!HKDF(hkdf_output, sizeof(hkdf_output), EVP_sha256(), kHKDFSecret, + sizeof(kHKDFSecret), kHKDFSalt, sizeof(kHKDFSalt), kHKDFInfo, + sizeof(kHKDFInfo)) || + !check_test(kHKDFOutput, hkdf_output, sizeof(kHKDFOutput), "HKDF")) { + fprintf(stderr, "HKDF failed.\n"); + goto err; + } + ret = 1; -#if defined(BORINGSSL_FIPS_SELF_TEST_FLAG_FILE) - // Tests were successful. Write flag file if requested. - if (module_hash_len != 0 && getenv(kFlagWriteEnableEnvVar) != NULL) { - const int fd = open(flag_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd >= 0) { - close(fd); - } - } -#endif // BORINGSSL_FIPS_SELF_TEST_FLAG_FILE - err: EVP_AEAD_CTX_cleanup(&aead_ctx); - RSA_free(rsa_key); - EC_KEY_free(ec_key); - EC_POINT_free(ec_point_in); - EC_POINT_free(ec_point_out); - EC_GROUP_free(ec_group); - BN_free(ec_scalar); - ECDSA_SIG_free(sig); return ret; } int BORINGSSL_self_test(void) { - return boringssl_fips_self_test(NULL, 0); + if (!boringssl_self_test_fast() || + // When requested to run self tests, also run the lazy tests. + !boringssl_self_test_rsa() || + !boringssl_self_test_ecc() || + !boringssl_self_test_ffdh()) { + return 0; + } + + return 1; } +#if defined(BORINGSSL_FIPS) +int boringssl_self_test_startup(void) { + return boringssl_self_test_fast(); +} +#endif + #endif // !_MSC_VER diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/internal.h new file mode 100644 index 00000000..bbc4e4ee --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/internal.h @@ -0,0 +1,89 @@ +/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SERVICE_INDICATOR_INTERNAL_H +#define OPENSSL_HEADER_SERVICE_INDICATOR_INTERNAL_H + +#include +#include + +#if defined(BORINGSSL_FIPS) + +// FIPS_service_indicator_update_state records that an approved service has been +// invoked. +void FIPS_service_indicator_update_state(void); + +// FIPS_service_indicator_lock_state and |FIPS_service_indicator_unlock_state| +// stop |FIPS_service_indicator_update_state| from actually updating the service +// indicator. This is used when a primitive calls a potentially approved +// primitive to avoid false positives. For example, just because a key +// generation calls |RAND_bytes| (and thus the approved DRBG) doesn't mean that +// the key generation operation itself is approved. +// +// This lock nests: i.e. locking twice is fine so long as each lock is paired +// with an unlock. If the (64-bit) counter overflows, the process aborts. +void FIPS_service_indicator_lock_state(void); +void FIPS_service_indicator_unlock_state(void); + +// The following functions may call |FIPS_service_indicator_update_state| if +// their parameter specifies an approved operation. + +void AEAD_GCM_verify_service_indicator(const EVP_AEAD_CTX *ctx); +void AEAD_CCM_verify_service_indicator(const EVP_AEAD_CTX *ctx); +void EC_KEY_keygen_verify_service_indicator(const EC_KEY *eckey); +void ECDH_verify_service_indicator(const EC_KEY *ec_key); +void EVP_Cipher_verify_service_indicator(const EVP_CIPHER_CTX *ctx); +void EVP_DigestSign_verify_service_indicator(const EVP_MD_CTX *ctx); +void EVP_DigestVerify_verify_service_indicator(const EVP_MD_CTX *ctx); +void HMAC_verify_service_indicator(const EVP_MD *evp_md); +void TLSKDF_verify_service_indicator(const EVP_MD *dgst); + +#else + +// Service indicator functions are no-ops in non-FIPS builds. + +OPENSSL_INLINE void FIPS_service_indicator_update_state(void) {} +OPENSSL_INLINE void FIPS_service_indicator_lock_state(void) {} +OPENSSL_INLINE void FIPS_service_indicator_unlock_state(void) {} + +OPENSSL_INLINE void AEAD_GCM_verify_service_indicator( + OPENSSL_UNUSED const EVP_AEAD_CTX *ctx) {} + +OPENSSL_INLINE void AEAD_CCM_verify_service_indicator( + OPENSSL_UNUSED const EVP_AEAD_CTX *ctx) {} + +OPENSSL_INLINE void EC_KEY_keygen_verify_service_indicator( + OPENSSL_UNUSED const EC_KEY *eckey) {} + +OPENSSL_INLINE void ECDH_verify_service_indicator( + OPENSSL_UNUSED const EC_KEY *ec_key) {} + +OPENSSL_INLINE void EVP_Cipher_verify_service_indicator( + OPENSSL_UNUSED const EVP_CIPHER_CTX *ctx) {} + +OPENSSL_INLINE void EVP_DigestSign_verify_service_indicator( + OPENSSL_UNUSED const EVP_MD_CTX *ctx) {} + +OPENSSL_INLINE void EVP_DigestVerify_verify_service_indicator( + OPENSSL_UNUSED const EVP_MD_CTX *ctx) {} + +OPENSSL_INLINE void HMAC_verify_service_indicator( + OPENSSL_UNUSED const EVP_MD *evp_md) {} + +OPENSSL_INLINE void TLSKDF_verify_service_indicator( + OPENSSL_UNUSED const EVP_MD *dgst) {} + +#endif // BORINGSSL_FIPS + +#endif // OPENSSL_HEADER_SERVICE_INDICATOR_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator.c b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator.c new file mode 100644 index 00000000..b1ea28e8 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator.c @@ -0,0 +1,334 @@ +/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include +#include +#include +#include + +#include "../../evp/internal.h" +#include "../../internal.h" +#include "internal.h" + +#if defined(BORINGSSL_FIPS) + +#define STATE_UNLOCKED 0 + +// fips_service_indicator_state is a thread-local structure that stores the +// state of the FIPS service indicator. +struct fips_service_indicator_state { + // lock_state records the number of times the indicator has been locked. + // When it is zero (i.e. |STATE_UNLOCKED|) then the indicator can be updated. + uint64_t lock_state; + // counter is the indicator state. It is incremented when an approved service + // completes. + uint64_t counter; +}; + +// service_indicator_get returns a pointer to the |fips_service_indicator_state| +// for the current thread. It returns NULL on error. +// +// FIPS 140-3 requires that the module should provide the service indicator +// for approved services irrespective of whether the user queries it or not. +// Hence, it is lazily initialized in any call to an approved service. +static struct fips_service_indicator_state *service_indicator_get(void) { + struct fips_service_indicator_state *indicator = CRYPTO_get_thread_local( + OPENSSL_THREAD_LOCAL_FIPS_SERVICE_INDICATOR_STATE); + + if (indicator == NULL) { + indicator = OPENSSL_malloc(sizeof(struct fips_service_indicator_state)); + if (indicator == NULL) { + return NULL; + } + + indicator->lock_state = STATE_UNLOCKED; + indicator->counter = 0; + + if (!CRYPTO_set_thread_local( + OPENSSL_THREAD_LOCAL_FIPS_SERVICE_INDICATOR_STATE, indicator, + OPENSSL_free)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR); + return NULL; + } + } + + return indicator; +} + +static uint64_t service_indicator_get_counter(void) { + struct fips_service_indicator_state *indicator = service_indicator_get(); + if (indicator == NULL) { + return 0; + } + return indicator->counter; +} + +uint64_t FIPS_service_indicator_before_call(void) { + return service_indicator_get_counter(); +} + +uint64_t FIPS_service_indicator_after_call(void) { + return service_indicator_get_counter(); +} + +void FIPS_service_indicator_update_state(void) { + struct fips_service_indicator_state *indicator = service_indicator_get(); + if (indicator && indicator->lock_state == STATE_UNLOCKED) { + indicator->counter++; + } +} + +void FIPS_service_indicator_lock_state(void) { + struct fips_service_indicator_state *indicator = service_indicator_get(); + if (indicator == NULL) { + return; + } + + // |FIPS_service_indicator_lock_state| and + // |FIPS_service_indicator_unlock_state| should not under/overflow in normal + // operation. They are still checked and errors added to facilitate testing in + // service_indicator_test.cc. This should only happen if lock/unlock are + // called in an incorrect order or multiple times in the same function. + const uint64_t new_state = indicator->lock_state + 1; + if (new_state < indicator->lock_state) { + // Overflow. This would imply that our call stack length has exceeded a + // |uint64_t| which impossible on a 64-bit system. + abort(); + } + + indicator->lock_state = new_state; +} + +void FIPS_service_indicator_unlock_state(void) { + struct fips_service_indicator_state *indicator = service_indicator_get(); + if (indicator == NULL) { + return; + } + + if (indicator->lock_state == 0) { + abort(); + } + + indicator->lock_state--; +} + +void AEAD_GCM_verify_service_indicator(const EVP_AEAD_CTX *ctx) { + const size_t key_len = EVP_AEAD_key_length(ctx->aead); + if (key_len == 16 || key_len == 32) { + FIPS_service_indicator_update_state(); + } +} + +void AEAD_CCM_verify_service_indicator(const EVP_AEAD_CTX *ctx) { + if (EVP_AEAD_key_length(ctx->aead) == 16 && ctx->tag_len == 4) { + FIPS_service_indicator_update_state(); + } +} + +// is_ec_fips_approved returns one if the curve corresponding to the given NID +// is FIPS approved, and zero otherwise. +static int is_ec_fips_approved(int curve_nid) { + switch (curve_nid) { + case NID_secp224r1: + case NID_X9_62_prime256v1: + case NID_secp384r1: + case NID_secp521r1: + return 1; + default: + return 0; + } +} + +// is_md_fips_approved_for_signing returns one if the given message digest type +// is FIPS approved for signing, and zero otherwise. +static int is_md_fips_approved_for_signing(int md_type) { + switch (md_type) { + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha512_256: + return 1; + default: + return 0; + } +} + +// is_md_fips_approved_for_verifying returns one if the given message digest +// type is FIPS approved for verifying, and zero otherwise. +static int is_md_fips_approved_for_verifying(int md_type) { + switch (md_type) { + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha512_256: + return 1; + default: + return 0; + } +} + +static void evp_md_ctx_verify_service_indicator(const EVP_MD_CTX *ctx, + int rsa_1024_ok, + int (*md_ok)(int md_type)) { + if (EVP_MD_CTX_md(ctx) == NULL) { + // Signature schemes without a prehash are currently never FIPS approved. + goto err; + } + + EVP_PKEY_CTX *const pctx = ctx->pctx; + const EVP_PKEY *const pkey = EVP_PKEY_CTX_get0_pkey(pctx); + const int pkey_type = EVP_PKEY_id(pkey); + const int md_type = EVP_MD_CTX_type(ctx); + + // EVP_PKEY_RSA_PSS SPKIs aren't supported. + if (pkey_type == EVP_PKEY_RSA) { + // Message digest used in the private key should be of the same type + // as the given one, so we extract the MD type from the |EVP_PKEY| + // and compare it with the type in |ctx|. + const EVP_MD *pctx_md; + if (!EVP_PKEY_CTX_get_signature_md(pctx, &pctx_md)) { + goto err; + } + if (EVP_MD_type(pctx_md) != md_type) { + goto err; + } + + int padding; + if (!EVP_PKEY_CTX_get_rsa_padding(pctx, &padding)) { + goto err; + } + if (padding == RSA_PKCS1_PSS_PADDING) { + int salt_len; + const EVP_MD *mgf1_md; + if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pctx, &salt_len) || + !EVP_PKEY_CTX_get_rsa_mgf1_md(pctx, &mgf1_md) || + (salt_len != -1 && salt_len != (int)EVP_MD_size(pctx_md)) || + EVP_MD_type(mgf1_md) != md_type) { + // Only PSS where saltLen == hashLen is tested with ACVP. Cases with + // non-standard padding functions are also excluded. + goto err; + } + } + + // The approved RSA key sizes for signing are 2048, 3072 and 4096 bits. + // Note: |EVP_PKEY_size| returns the size in bytes. + size_t pkey_size = EVP_PKEY_size(ctx->pctx->pkey); + + // Check if the MD type and the RSA key size are approved. + if (md_ok(md_type) && + ((rsa_1024_ok && pkey_size == 128) || pkey_size == 256 || + pkey_size == 384 || pkey_size == 512)) { + FIPS_service_indicator_update_state(); + } + } else if (pkey_type == EVP_PKEY_EC) { + // Check if the MD type and the elliptic curve are approved. + if (md_ok(md_type) && + is_ec_fips_approved(EC_GROUP_get_curve_name( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ctx->pctx->pkey))))) { + FIPS_service_indicator_update_state(); + } + } + + err: + // Ensure that junk errors aren't left on the queue. + ERR_clear_error(); +} + +void EC_KEY_keygen_verify_service_indicator(const EC_KEY *eckey) { + if (is_ec_fips_approved(EC_GROUP_get_curve_name(eckey->group))) { + FIPS_service_indicator_update_state(); + } +} + +void ECDH_verify_service_indicator(const EC_KEY *ec_key) { + if (is_ec_fips_approved(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)))) { + FIPS_service_indicator_update_state(); + } +} + +void EVP_Cipher_verify_service_indicator(const EVP_CIPHER_CTX *ctx) { + switch (EVP_CIPHER_CTX_nid(ctx)) { + case NID_aes_128_ecb: + case NID_aes_192_ecb: + case NID_aes_256_ecb: + + case NID_aes_128_cbc: + case NID_aes_192_cbc: + case NID_aes_256_cbc: + + case NID_aes_128_ctr: + case NID_aes_192_ctr: + case NID_aes_256_ctr: + FIPS_service_indicator_update_state(); + } +} + +void EVP_DigestVerify_verify_service_indicator(const EVP_MD_CTX *ctx) { + return evp_md_ctx_verify_service_indicator(ctx, /*rsa_1024_ok=*/1, + is_md_fips_approved_for_verifying); +} + +void EVP_DigestSign_verify_service_indicator(const EVP_MD_CTX *ctx) { + return evp_md_ctx_verify_service_indicator(ctx, /*rsa_1024_ok=*/0, + is_md_fips_approved_for_signing); +} + +void HMAC_verify_service_indicator(const EVP_MD *evp_md) { + switch (evp_md->type) { + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha512_256: + FIPS_service_indicator_update_state(); + break; + } +} + +void TLSKDF_verify_service_indicator(const EVP_MD *md) { + // HMAC-MD5, HMAC-SHA1, and HMAC-MD5/HMAC-SHA1 (both used concurrently) are + // approved for use in the KDF in TLS 1.0/1.1. + // HMAC-SHA{256, 384, 512} are approved for use in the KDF in TLS 1.2. + // These Key Derivation functions are to be used in the context of the TLS + // protocol. + switch (EVP_MD_type(md)) { + case NID_md5: + case NID_sha1: + case NID_md5_sha1: + case NID_sha256: + case NID_sha384: + case NID_sha512: + FIPS_service_indicator_update_state(); + break; + } +} + +#else + +uint64_t FIPS_service_indicator_before_call(void) { return 0; } + +uint64_t FIPS_service_indicator_after_call(void) { + // One is returned so that the return value is always greater than zero, the + // return value of |FIPS_service_indicator_before_call|. This makes everything + // report as "approved" in non-FIPS builds. + return 1; +} + +#endif // BORINGSSL_FIPS diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator_test.cc b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator_test.cc new file mode 100644 index 00000000..8ae52ded --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/service_indicator/service_indicator_test.cc @@ -0,0 +1,2411 @@ +/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../test/abi_test.h" +#include "../../test/test_util.h" +#include "../bn/internal.h" +#include "../rand/internal.h" +#include "../tls/internal.h" + + +using bssl::FIPSStatus; + +static const uint8_t kAESKey[16] = {'A', 'W', 'S', '-', 'L', 'C', 'C', 'r', + 'y', 'p', 't', 'o', ' ', 'K', 'e', 'y'}; + +static const uint8_t kPlaintext[64] = { + 'A', 'W', 'S', '-', 'L', 'C', 'C', 'r', 'y', 'p', 't', 'o', 'M', + 'o', 'd', 'u', 'l', 'e', ' ', 'F', 'I', 'P', 'S', ' ', 'K', 'A', + 'T', ' ', 'E', 'n', 'c', 'r', 'y', 'p', 't', 'i', 'o', 'n', ' ', + 'a', 'n', 'd', ' ', 'D', 'e', 'c', 'r', 'y', 'p', 't', 'i', 'o', + 'n', ' ', 'P', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't', '!'}; + +#if defined(BORINGSSL_FIPS) + +// kEVPKeyGenShouldCallFIPSFunctions determines whether |EVP_PKEY_keygen_*| +// functions should call the FIPS versions of the key-generation functions. +static const bool kEVPKeyGenShouldCallFIPSFunctions = false; + +// kCurveSecp256k1Supported determines whether secp256k1 tests should be run. +static const bool kCurveSecp256k1Supported = false; + +// kEVPDeriveSetsServiceIndicator is true if `EVP_PKEY_derive` should set the +// service indicator for some algorithms. +static const bool kEVPDeriveSetsServiceIndicator = false; + +template +class TestWithNoErrors : public testing::TestWithParam { + void TearDown() override { + if (ERR_peek_error() != 0) { + auto f = [](const char *str, size_t len, void *unused) -> int { + fprintf(stderr, "%s\n", str); + return 1; + }; + ERR_print_errors_cb(f, nullptr); + ADD_FAILURE(); + } + } +}; + +static const uint8_t kAESKey_192[24] = {'A', 'W', 'S', '-', 'L', 'C', 'C', 'r', + 'y', 'p', 't', 'o', ' ', '1', '9', '2', + '-', 'b', 'i', 't', ' ', 'K', 'e', 'y'}; + +static const uint8_t kAESKey_256[32] = {'A', 'W', 'S', '-', 'L', 'C', 'C', 'r', + 'y', 'p', 't', 'o', ' ', '2', '5', '6', + '-', 'b', 'i', 't', ' ', 'L', 'o', 'n', + 'g', ' ', 'K', 'e', 'y', '!', '!', '!'}; + +static const uint8_t kAESIV[AES_BLOCK_SIZE] = {0}; + +static bssl::UniquePtr GetDH() { + // kFFDHE2048PrivateKeyData is a 225-bit value. (225 because that's the + // minimum private key size in + // https://tools.ietf.org/html/rfc7919#appendix-A.1.) + static const uint8_t kFFDHE2048PrivateKey[] = { + 0x01, 0x91, 0x17, 0x3f, 0x2a, 0x05, 0x70, 0x18, 0x7e, 0xc4, + 0x22, 0xee, 0xb7, 0x0a, 0x15, 0x2f, 0x39, 0x64, 0x58, 0xf3, + 0xb8, 0x18, 0x7b, 0xe3, 0x6b, 0xd3, 0x8a, 0x4f, 0xa1}; + bssl::UniquePtr priv( + BN_bin2bn(kFFDHE2048PrivateKey, sizeof(kFFDHE2048PrivateKey), nullptr)); + if (!priv) { + return nullptr; + } + bssl::UniquePtr dh(DH_get_rfc7919_2048()); + if (!dh || !DH_set0_key(dh.get(), nullptr, priv.get())) { + return nullptr; + } + priv.release(); // |DH_set0_key| takes ownership on success. + return dh; +} + +static void DoCipherFinal(EVP_CIPHER_CTX *ctx, std::vector *out, + bssl::Span in, + FIPSStatus expect_approved) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + size_t max_out = in.size(); + if (EVP_CIPHER_CTX_encrypting(ctx)) { + unsigned block_size = EVP_CIPHER_CTX_block_size(ctx); + max_out += block_size - (max_out % block_size); + } + out->resize(max_out); + + size_t total = 0; + int len; + ASSERT_TRUE(EVP_CipherUpdate(ctx, out->data(), &len, in.data(), in.size())); + total += static_cast(len); + // Check if the overall service is approved by checking |EVP_CipherFinal_ex|, + // which should be the last part of the service. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_CipherFinal_ex(ctx, out->data() + total, &len))); + total += static_cast(len); + ASSERT_LE(total, max_out); + out->resize(total); + + EXPECT_EQ(approved, expect_approved); +} + +static const uint8_t kTDES_EDE3_CipherText[64] = { + 0x2a, 0x17, 0x79, 0x5a, 0x9b, 0x1d, 0xd8, 0x72, 0x06, 0xc6, 0xe7, + 0x55, 0x14, 0xaa, 0x7b, 0x2a, 0x6e, 0xfc, 0x71, 0x29, 0xff, 0x9b, + 0x67, 0x73, 0x7c, 0x9e, 0x15, 0x74, 0x80, 0xc8, 0x2f, 0xca, 0x93, + 0xaa, 0x8e, 0xba, 0x2c, 0x48, 0x88, 0x51, 0xc7, 0xa4, 0xf4, 0xe3, + 0x2b, 0x33, 0xe5, 0xa1, 0x58, 0x0a, 0x08, 0x3c, 0xb9, 0xf6, 0xf1, + 0x20, 0x67, 0x02, 0x49, 0xa0, 0x92, 0x18, 0xde, 0x2b}; + +static const uint8_t kTDES_EDE3_CBCCipherText[64] = { + 0x2a, 0x17, 0x79, 0x5a, 0x9b, 0x1d, 0xd8, 0x72, 0xbf, 0x3f, 0xfd, + 0xe4, 0x0d, 0x66, 0x33, 0x49, 0x3b, 0x8c, 0xa6, 0xd0, 0x0a, 0x66, + 0xae, 0xf1, 0xd9, 0xa7, 0xd6, 0xfb, 0xa2, 0x39, 0x6f, 0xf6, 0x1b, + 0x8f, 0x67, 0xe1, 0x2b, 0x58, 0x1c, 0xb6, 0xa2, 0xec, 0xb3, 0xc2, + 0xe6, 0xd1, 0xcc, 0x11, 0x05, 0xdd, 0xee, 0x9d, 0x87, 0x95, 0xe9, + 0x58, 0xc7, 0xef, 0xa4, 0x6d, 0x5e, 0xd6, 0x57, 0x01}; + +// AES-OFB is not an approved service, and is only used to test we are not +// validating un-approved services correctly. +static const uint8_t kAESOFBCiphertext[64] = { + 0x49, 0xf5, 0x6a, 0x7d, 0x3e, 0xd7, 0xb2, 0x47, 0x35, 0xca, 0x54, + 0xf5, 0xf1, 0xb8, 0xd1, 0x48, 0x8e, 0x47, 0x09, 0x95, 0xd5, 0xa0, + 0xc6, 0xa3, 0xe4, 0x94, 0xaf, 0xd4, 0x1b, 0x64, 0x25, 0x65, 0x28, + 0x9e, 0x82, 0xba, 0x92, 0xca, 0x75, 0xb3, 0xf3, 0x78, 0x44, 0x87, + 0xd6, 0x11, 0xf9, 0x22, 0xa3, 0xf3, 0xc6, 0x1d, 0x30, 0x00, 0x5b, + 0x77, 0x18, 0x38, 0x39, 0x08, 0x5e, 0x0a, 0x56, 0x6b}; + +static const uint8_t kAESECBCiphertext[64] = { + 0xa4, 0xc1, 0x5c, 0x51, 0x2a, 0x2e, 0x2a, 0xda, 0xd9, 0x02, 0x23, + 0xe7, 0xa9, 0x34, 0x9d, 0xd8, 0x15, 0xc5, 0xf5, 0x55, 0x8e, 0xb0, + 0x29, 0x95, 0x48, 0x6c, 0x7f, 0xa9, 0x47, 0x19, 0x0b, 0x54, 0xe5, + 0x0f, 0x05, 0x76, 0xbb, 0xd0, 0x1a, 0x6c, 0xab, 0xe9, 0xfd, 0x5b, + 0xd8, 0x0b, 0x0a, 0xbd, 0x7f, 0xea, 0xda, 0x52, 0x07, 0x65, 0x13, + 0x6c, 0xbe, 0xfc, 0x36, 0x82, 0x4b, 0x6a, 0xc3, 0xd5}; + +static const uint8_t kAESECBCiphertext_192[64] = { + 0x1d, 0xc8, 0xaa, 0xa7, 0x29, 0x01, 0x17, 0x09, 0x72, 0xc6, 0xe9, + 0x63, 0x02, 0x9d, 0xeb, 0x01, 0xeb, 0xc0, 0xda, 0x82, 0x6c, 0x30, + 0x7d, 0x60, 0x1b, 0x3e, 0xc7, 0x7b, 0xe3, 0x18, 0xa2, 0x43, 0x59, + 0x15, 0x4a, 0xe4, 0x8a, 0x84, 0xda, 0x16, 0x90, 0x7b, 0xfa, 0x64, + 0x37, 0x62, 0x19, 0xf1, 0x95, 0x11, 0x61, 0x84, 0xb0, 0x70, 0x49, + 0x72, 0x9f, 0xe7, 0x3a, 0x18, 0x99, 0x01, 0xba, 0xb0}; + +static const uint8_t kAESECBCiphertext_256[64] = { + 0x6f, 0x2d, 0x6d, 0x7a, 0xc1, 0x8f, 0x00, 0x9f, 0x2d, 0xcf, 0xba, + 0xe6, 0x4f, 0xdd, 0xe0, 0x09, 0x5b, 0xf3, 0xa4, 0xaf, 0xce, 0x45, + 0x49, 0x6e, 0x28, 0x7b, 0x48, 0x57, 0xb5, 0xf5, 0xd8, 0x05, 0x16, + 0x0f, 0xea, 0x21, 0x0c, 0x39, 0x78, 0xee, 0x9e, 0x57, 0x3c, 0x40, + 0x11, 0x9c, 0xd9, 0x34, 0x97, 0xb9, 0xa6, 0x06, 0x40, 0x60, 0xa2, + 0x0c, 0x01, 0xe3, 0x9c, 0xda, 0x3e, 0xad, 0x99, 0x3d}; + +static const uint8_t kAESCBCCiphertext[64] = { + 0xa4, 0xc1, 0x5c, 0x51, 0x2a, 0x2e, 0x2a, 0xda, 0xd9, 0x02, 0x23, + 0xe7, 0xa9, 0x34, 0x9d, 0xd8, 0x5c, 0xb3, 0x65, 0x54, 0x72, 0xc8, + 0x06, 0xf1, 0x36, 0xc3, 0x97, 0x73, 0x87, 0xca, 0x44, 0x99, 0x21, + 0xb8, 0xdb, 0x93, 0x22, 0x00, 0x89, 0x7c, 0x1c, 0xea, 0x36, 0x23, + 0x18, 0xdb, 0xc1, 0x52, 0x8c, 0x23, 0x66, 0x11, 0x0d, 0xa8, 0xe9, + 0xb8, 0x08, 0x8b, 0xaa, 0x81, 0x47, 0x01, 0xa4, 0x4f}; + +static const uint8_t kAESCBCCiphertext_192[64] = { + 0x1d, 0xc8, 0xaa, 0xa7, 0x29, 0x01, 0x17, 0x09, 0x72, 0xc6, 0xe9, + 0x63, 0x02, 0x9d, 0xeb, 0x01, 0xb4, 0x48, 0xa8, 0x00, 0x94, 0x46, + 0x7f, 0xe3, 0xc1, 0x24, 0xea, 0x41, 0xa0, 0x2b, 0x47, 0x2f, 0xae, + 0x19, 0xce, 0x0d, 0xfa, 0x90, 0x45, 0x85, 0xce, 0xc4, 0x21, 0x0c, + 0x74, 0x38, 0x13, 0xfd, 0x64, 0xba, 0x58, 0x10, 0x37, 0x53, 0x48, + 0x66, 0x02, 0x76, 0xfb, 0xb1, 0x3a, 0x19, 0xce, 0x61}; + +static const uint8_t kAESCBCCiphertext_256[64] = { + 0x6f, 0x2d, 0x6d, 0x7a, 0xc1, 0x8f, 0x00, 0x9f, 0x2d, 0xcf, 0xba, + 0xe6, 0x4f, 0xdd, 0xe0, 0x09, 0x9e, 0xa8, 0x28, 0xdc, 0x27, 0xde, + 0x89, 0x26, 0xc7, 0x94, 0x6a, 0xbf, 0xb6, 0x94, 0x05, 0x08, 0x6c, + 0x39, 0x07, 0x52, 0xfa, 0x7b, 0xca, 0x7d, 0x9b, 0xbf, 0xb2, 0x43, + 0x2b, 0x69, 0xee, 0xc5, 0x68, 0x4c, 0xdd, 0x62, 0xae, 0x8d, 0x7e, + 0x71, 0x0c, 0x8f, 0x11, 0xce, 0x1d, 0x8b, 0xee, 0x94}; + +static const uint8_t kAESCTRCiphertext[64] = { + 0x49, 0xf5, 0x6a, 0x7d, 0x3e, 0xd7, 0xb2, 0x47, 0x35, 0xca, 0x54, + 0xf5, 0xf1, 0xb8, 0xd1, 0x48, 0xb0, 0x18, 0xc4, 0x5e, 0xeb, 0x42, + 0xfd, 0x10, 0x49, 0x1f, 0x2b, 0x11, 0xe9, 0xb0, 0x07, 0xa4, 0x00, + 0x56, 0xec, 0x25, 0x53, 0x4d, 0x70, 0x98, 0x38, 0x85, 0x5d, 0x54, + 0xab, 0x2c, 0x19, 0x13, 0x6d, 0xf3, 0x0e, 0x6f, 0x48, 0x2f, 0xab, + 0xe1, 0x82, 0xd4, 0x30, 0xa9, 0x16, 0x73, 0x93, 0xc3}; + +static const uint8_t kAESCTRCiphertext_192[64] = { + 0x72, 0x7d, 0xbb, 0xd4, 0x8b, 0x16, 0x8b, 0x19, 0xa4, 0xeb, 0xa6, + 0xfa, 0xa0, 0xd0, 0x2b, 0xbb, 0x9b, 0x1f, 0xbf, 0x4d, 0x67, 0xfb, + 0xea, 0x89, 0x16, 0xd7, 0xa4, 0xb6, 0xbe, 0x1a, 0x78, 0x1c, 0x3d, + 0x44, 0x49, 0xa0, 0xf2, 0xb2, 0xb3, 0x82, 0x0f, 0xdd, 0xac, 0xd6, + 0xea, 0x6e, 0x1f, 0x09, 0x8d, 0xa5, 0xdb, 0x4f, 0x3f, 0x97, 0x90, + 0x26, 0xed, 0xf6, 0xbb, 0x62, 0xb3, 0x6f, 0x52, 0x67}; + +static const uint8_t kAESCTRCiphertext_256[64] = { + 0x4a, 0x87, 0x44, 0x09, 0xf4, 0x1d, 0x80, 0x94, 0x51, 0x9a, 0xe4, + 0x89, 0x49, 0xcb, 0x98, 0x0d, 0x27, 0xc5, 0xba, 0x20, 0x00, 0x45, + 0xbb, 0x29, 0x75, 0xc0, 0xb7, 0x23, 0x0d, 0x81, 0x9f, 0x43, 0xaa, + 0x78, 0x89, 0xc0, 0xc4, 0x6d, 0x99, 0x0d, 0xb8, 0x9b, 0xc3, 0x25, + 0xa6, 0xd1, 0x7c, 0x98, 0x3e, 0xff, 0x06, 0x59, 0x41, 0xcf, 0xb2, + 0xd5, 0x2f, 0x95, 0xea, 0x83, 0xb1, 0x42, 0xb8, 0xb2}; + +static const uint8_t kAESCFBCiphertext[64] = { + 0x49, 0xf5, 0x6a, 0x7d, 0x3e, 0xd7, 0xb2, 0x47, 0x35, 0xca, 0x54, + 0xf5, 0xf1, 0xb8, 0xd1, 0x48, 0x01, 0xdc, 0xba, 0x43, 0x3a, 0x7b, + 0xbf, 0x84, 0x91, 0x49, 0xc5, 0xc9, 0xd6, 0xcf, 0x6a, 0x2c, 0x3a, + 0x66, 0x99, 0x68, 0xe3, 0xd0, 0x56, 0x05, 0xe7, 0x99, 0x7f, 0xc3, + 0xbc, 0x09, 0x13, 0xa6, 0xf0, 0xde, 0x17, 0xf4, 0x85, 0x9a, 0xee, + 0x29, 0xc3, 0x77, 0xab, 0xc4, 0xf6, 0xdb, 0xae, 0x24}; + +static const uint8_t kAESCCMCiphertext[64 + 4] = { + 0x7a, 0x02, 0x5d, 0x48, 0x02, 0x44, 0x78, 0x7f, 0xb4, 0x71, 0x74, 0x7b, + 0xec, 0x4d, 0x90, 0x29, 0x7b, 0xa7, 0x65, 0xbb, 0x3e, 0x80, 0x41, 0x7e, + 0xab, 0xb4, 0x58, 0x22, 0x4f, 0x86, 0xcd, 0xcc, 0xc2, 0x12, 0xeb, 0x36, + 0x39, 0x89, 0xe3, 0x66, 0x2a, 0xbf, 0xe3, 0x6c, 0x95, 0x60, 0x13, 0x9e, + 0x93, 0xcc, 0xb4, 0x06, 0xbe, 0xaf, 0x3f, 0xba, 0x13, 0x73, 0x09, 0x92, + 0xd1, 0x80, 0x73, 0xb3, 0xc3, 0xa3, 0xa4, 0x8b, +}; + +static const uint8_t kAESKWCiphertext[72] = { + 0x44, 0xec, 0x7d, 0x92, 0x2c, 0x9f, 0xf3, 0xe8, 0xac, 0xb1, 0xea, 0x3d, + 0x0a, 0xc7, 0x51, 0x27, 0xe8, 0x03, 0x11, 0x78, 0xe5, 0xaf, 0x8d, 0xb1, + 0x70, 0x96, 0x2e, 0xfa, 0x05, 0x48, 0x48, 0x99, 0x1a, 0x58, 0xcc, 0xfe, + 0x11, 0x36, 0x5d, 0x49, 0x98, 0x1e, 0xbb, 0xd6, 0x0b, 0xf5, 0xb9, 0x64, + 0xa4, 0x30, 0x3e, 0x60, 0xf6, 0xc5, 0xff, 0x82, 0x30, 0x9a, 0xa7, 0x48, + 0x82, 0xe2, 0x00, 0xc1, 0xe9, 0xc2, 0x73, 0x6f, 0xbc, 0x89, 0x66, 0x9d}; + +static const uint8_t kAESKWPCiphertext[72] = { + 0x29, 0x5e, 0xb9, 0xea, 0x96, 0xa7, 0xa5, 0xca, 0xfa, 0xeb, 0xda, 0x78, + 0x13, 0xea, 0x83, 0xca, 0x41, 0xdb, 0x4d, 0x36, 0x7d, 0x39, 0x8a, 0xd6, + 0xef, 0xd3, 0xd2, 0x2d, 0x3a, 0xc8, 0x55, 0xc8, 0x73, 0xd7, 0x79, 0x55, + 0xad, 0xc0, 0xce, 0xad, 0x12, 0x54, 0x51, 0xf0, 0x70, 0x76, 0xff, 0xe7, + 0x0c, 0xb2, 0x8e, 0xdd, 0xb6, 0x9a, 0x27, 0x74, 0x98, 0x28, 0xe0, 0xfa, + 0x11, 0xe6, 0x3f, 0x86, 0x93, 0x23, 0xf8, 0x0d, 0xcb, 0xaf, 0x2b, 0xb7}; + +static const uint8_t kAESCMACOutput[16] = {0xe7, 0x32, 0x43, 0xb4, 0xae, 0x79, + 0x08, 0x86, 0xe7, 0x9f, 0x0d, 0x3f, + 0x88, 0x3f, 0x1a, 0xfd}; + +const uint8_t kDHOutput[2048 / 8] = { + 0x83, 0xf0, 0xd8, 0x4f, 0xdb, 0xe7, 0x65, 0xb6, 0x80, 0x6f, 0xa3, 0x22, + 0x9b, 0x33, 0x1c, 0x87, 0x89, 0xc8, 0x1d, 0x2c, 0xa1, 0xba, 0xa3, 0xb8, + 0xdf, 0xad, 0x42, 0xea, 0x9a, 0x75, 0xfe, 0xbf, 0xc1, 0xa8, 0xf6, 0xda, + 0xec, 0xdf, 0x48, 0x61, 0x7d, 0x7f, 0x3d, 0xab, 0xbd, 0xda, 0xd1, 0xd3, + 0xd8, 0xaf, 0x44, 0x4a, 0xba, 0x3f, 0x0e, 0x99, 0x8d, 0x11, 0xdc, 0x63, + 0xb1, 0xe0, 0x65, 0xf2, 0xb9, 0x82, 0x81, 0x8c, 0x88, 0x75, 0x8f, 0xa0, + 0x94, 0x52, 0x2a, 0x2f, 0x2d, 0x10, 0xb1, 0xf4, 0xd2, 0xdd, 0x0f, 0x8a, + 0x7e, 0x49, 0x7b, 0x1e, 0xfd, 0x8c, 0x78, 0xf9, 0x11, 0xdf, 0x80, 0x8b, + 0x2e, 0x86, 0x34, 0xbf, 0x4b, 0xca, 0x13, 0x3e, 0x85, 0x63, 0xeb, 0xe4, + 0xff, 0xec, 0xb0, 0xe8, 0x83, 0xf6, 0x2c, 0x45, 0x21, 0x90, 0x34, 0x9c, + 0x9d, 0x9d, 0xfe, 0x1a, 0x48, 0x53, 0xef, 0x97, 0xd5, 0xea, 0x6a, 0x65, + 0xf5, 0xe9, 0x9f, 0x91, 0x4f, 0xb4, 0x43, 0xe7, 0x1f, 0x0a, 0x2e, 0xdb, + 0xe6, 0x84, 0x30, 0xdb, 0xad, 0xe4, 0xaf, 0x2c, 0xf9, 0x93, 0xe8, 0x0a, + 0xab, 0x7f, 0x1c, 0xde, 0xb3, 0x80, 0xb6, 0x02, 0x42, 0xba, 0x18, 0x0d, + 0x0f, 0xc2, 0x1d, 0xa4, 0x4b, 0x2b, 0x84, 0x74, 0x10, 0x97, 0x6d, 0xdc, + 0xfa, 0x99, 0xdc, 0xba, 0xf2, 0xcb, 0x1b, 0xe8, 0x1a, 0xba, 0x0c, 0x67, + 0x60, 0x07, 0x87, 0xcc, 0xc6, 0x0d, 0xef, 0x56, 0x07, 0x80, 0x55, 0xae, + 0x03, 0xa3, 0x62, 0x31, 0x4c, 0x50, 0xf7, 0xf6, 0x87, 0xb3, 0x8d, 0xe2, + 0x11, 0x86, 0xe7, 0x9d, 0x98, 0x3c, 0x2a, 0x6c, 0x8a, 0xf0, 0xa7, 0x73, + 0x33, 0x07, 0x4e, 0x70, 0xee, 0x14, 0x4b, 0xa3, 0xf7, 0x4f, 0x8f, 0x1a, + 0xa2, 0xf6, 0xd1, 0xeb, 0x4d, 0x04, 0xf9, 0x4c, 0x07, 0x36, 0xb1, 0x46, + 0x53, 0x55, 0xb1, 0x23}; + +static const uint8_t kOutput_md4[MD4_DIGEST_LENGTH] = { + 0xab, 0x6b, 0xda, 0x84, 0xc0, 0x6b, 0xd0, 0x1d, + 0x19, 0xc0, 0x08, 0x11, 0x07, 0x8d, 0xce, 0x0e}; + +static const uint8_t kOutput_md5[MD5_DIGEST_LENGTH] = { + 0xe9, 0x70, 0xa2, 0xf7, 0x9c, 0x55, 0x57, 0xac, + 0x4e, 0x7f, 0x6b, 0xbc, 0xa3, 0xb9, 0xb7, 0xdb}; + +static const uint8_t kOutput_sha1[SHA_DIGEST_LENGTH] = { + 0xaa, 0x18, 0x71, 0x34, 0x00, 0x71, 0x67, 0x9f, 0xa1, 0x6d, + 0x20, 0x82, 0x91, 0x0f, 0x53, 0x0a, 0xcd, 0x6e, 0xa4, 0x34}; + +static const uint8_t kOutput_sha224[SHA224_DIGEST_LENGTH] = { + 0x5f, 0x1a, 0x9e, 0x68, 0x4c, 0xb7, 0x42, 0x68, 0xa0, 0x8b, + 0x87, 0xd7, 0x96, 0xb6, 0xcf, 0x1e, 0x4f, 0x85, 0x1c, 0x47, + 0xe9, 0x29, 0xb3, 0xb2, 0x73, 0x72, 0xd2, 0x69}; + +static const uint8_t kOutput_sha256[SHA256_DIGEST_LENGTH] = { + 0xe7, 0x63, 0x1c, 0xbb, 0x12, 0xb5, 0xbf, 0x4f, 0x99, 0x05, 0x9d, + 0x40, 0x15, 0x55, 0x34, 0x9c, 0x26, 0x36, 0xd2, 0xfe, 0x6a, 0xd6, + 0x26, 0xb4, 0x9d, 0x33, 0x07, 0xf5, 0xe6, 0x29, 0x13, 0x92}; + +static const uint8_t kOutput_sha384[SHA384_DIGEST_LENGTH] = { + 0x15, 0x81, 0x48, 0x8d, 0x95, 0xf2, 0x66, 0x84, 0x65, 0x94, 0x3e, 0xb9, + 0x8c, 0xda, 0x36, 0x30, 0x2a, 0x85, 0xc0, 0xcd, 0xec, 0x38, 0xa0, 0x1f, + 0x72, 0xe2, 0x68, 0xfe, 0x4e, 0xdb, 0x27, 0x8b, 0x50, 0x15, 0xe0, 0x24, + 0xc3, 0x65, 0xd1, 0x66, 0x2a, 0x3e, 0xe7, 0x00, 0x16, 0x51, 0xf5, 0x18}; + +static const uint8_t kOutput_sha512[SHA512_DIGEST_LENGTH] = { + 0x71, 0xcc, 0xec, 0x03, 0xf8, 0x76, 0xf4, 0x0b, 0xf1, 0x1b, 0x89, + 0x27, 0x83, 0xa1, 0x70, 0x02, 0x00, 0x2b, 0xe9, 0x3c, 0x3c, 0x65, + 0x12, 0xb9, 0xa8, 0x8c, 0xc5, 0x9d, 0xae, 0x3c, 0x73, 0x43, 0x76, + 0x4d, 0x98, 0xed, 0xd0, 0xbe, 0xb4, 0xf9, 0x0b, 0x5c, 0x5d, 0x34, + 0x46, 0x30, 0x18, 0xc2, 0x05, 0x88, 0x8a, 0x3c, 0x25, 0xcc, 0x06, + 0xf8, 0x73, 0xb9, 0xe4, 0x18, 0xa8, 0xc2, 0xf0, 0xe5}; + +static const uint8_t kOutput_sha512_256[SHA512_256_DIGEST_LENGTH] = { + 0x1a, 0x78, 0x68, 0x6b, 0x69, 0x6d, 0x28, 0x14, 0x6b, 0x37, 0x11, + 0x2d, 0xfb, 0x72, 0x35, 0xfa, 0xc1, 0xc4, 0x5f, 0x5c, 0x49, 0x91, + 0x08, 0x95, 0x0b, 0x0f, 0xc9, 0x88, 0x44, 0x12, 0x01, 0x6a}; + +static const uint8_t kHMACOutput_sha1[SHA_DIGEST_LENGTH] = { + 0x34, 0xac, 0x50, 0x9b, 0xa9, 0x4c, 0x39, 0xef, 0x45, 0xa0, + 0x6b, 0xdc, 0xfc, 0xbd, 0x3d, 0x42, 0xe8, 0x0a, 0x97, 0x86}; + +static const uint8_t kHMACOutput_sha224[SHA224_DIGEST_LENGTH] = { + 0x30, 0x62, 0x97, 0x45, 0x9e, 0xea, 0x62, 0xe4, 0x5d, 0xbb, + 0x7d, 0x25, 0x3f, 0x77, 0x0f, 0x9d, 0xa4, 0xbd, 0x17, 0x96, + 0x23, 0x53, 0xe1, 0x76, 0xf3, 0xf8, 0x9b, 0x74}; + +static const uint8_t kHMACOutput_sha256[SHA256_DIGEST_LENGTH] = { + 0x68, 0x33, 0x3e, 0x74, 0x9a, 0x49, 0xab, 0x77, 0xb4, 0x1a, 0x40, + 0xd8, 0x55, 0x07, 0xa7, 0xb6, 0x48, 0xa1, 0xa5, 0xa9, 0xd1, 0x7b, + 0x85, 0xe9, 0x33, 0x09, 0x16, 0x79, 0xcc, 0xe9, 0x29, 0x97}; + +static const uint8_t kHMACOutput_sha384[SHA384_DIGEST_LENGTH] = { + 0xcc, 0x39, 0x22, 0x0e, 0x9f, 0x2e, 0x26, 0x4a, 0xb5, 0xf8, 0x4a, 0x0f, + 0x73, 0x51, 0x26, 0x1a, 0xf2, 0xef, 0x15, 0xf3, 0x5f, 0x77, 0xce, 0xbb, + 0x4c, 0x69, 0x86, 0x0e, 0x1f, 0x5c, 0x4d, 0xc9, 0x96, 0xd9, 0xed, 0x74, + 0x6c, 0x45, 0x05, 0x7a, 0x0e, 0x3f, 0x36, 0x8a, 0xda, 0x2a, 0x35, 0xf9}; + +static const uint8_t kHMACOutput_sha512[SHA512_DIGEST_LENGTH] = { + 0x4c, 0x09, 0x46, 0x50, 0x7c, 0xb3, 0xa1, 0xfa, 0xbc, 0xf2, 0xc4, + 0x4f, 0x1e, 0x3d, 0xa9, 0x0b, 0x29, 0x4e, 0x12, 0x09, 0x09, 0x32, + 0xde, 0x82, 0xa0, 0xab, 0xf6, 0x5e, 0x66, 0x19, 0xd0, 0x86, 0x9a, + 0x92, 0xe3, 0xf9, 0x13, 0xa7, 0xe6, 0xfc, 0x1a, 0x2e, 0x50, 0xda, + 0xf6, 0x8f, 0xb2, 0xd5, 0xb2, 0x6e, 0x97, 0x82, 0x25, 0x5a, 0x1e, + 0xbf, 0x9b, 0x99, 0x8c, 0xf0, 0x37, 0xe6, 0x3d, 0x40}; + +static const uint8_t kHMACOutput_sha512_256[SHA512_256_DIGEST_LENGTH] = { + 0x9c, 0x95, 0x9c, 0x03, 0xc9, 0x8c, 0x90, 0xee, 0x7a, 0xff, 0xed, + 0x26, 0xba, 0x75, 0x90, 0xd0, 0xb9, 0xd4, 0x09, 0xf5, 0x22, 0xd6, + 0xb6, 0xab, 0xa8, 0xb9, 0xae, 0x01, 0x06, 0x37, 0x8f, 0xd1}; + +static const uint8_t kDRBGEntropy[48] = { + 'B', 'C', 'M', ' ', 'K', 'n', 'o', 'w', 'n', ' ', 'A', 'n', + 's', 'w', 'e', 'r', ' ', 'T', 'e', 's', 't', ' ', 'D', 'B', + 'R', 'G', ' ', 'I', 'n', 'i', 't', 'i', 'a', 'l', ' ', 'E', + 'n', 't', 'r', 'o', 'p', 'y', ' ', ' ', ' ', ' ', ' ', ' '}; + +static const uint8_t kDRBGPersonalization[18] = {'B', 'C', 'M', 'P', 'e', 'r', + 's', 'o', 'n', 'a', 'l', 'i', + 'z', 'a', 't', 'i', 'o', 'n'}; + +static const uint8_t kDRBGAD[16] = {'B', 'C', 'M', ' ', 'D', 'R', 'B', 'G', + ' ', 'K', 'A', 'T', ' ', 'A', 'D', ' '}; + +const uint8_t kDRBGOutput[64] = { + 0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5, + 0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1, + 0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9, + 0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32, + 0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d, + 0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22, 0x95}; + +static const uint8_t kDRBGEntropy2[48] = { + 'B', 'C', 'M', ' ', 'K', 'n', 'o', 'w', 'n', ' ', 'A', 'n', + 's', 'w', 'e', 'r', ' ', 'T', 'e', 's', 't', ' ', 'D', 'B', + 'R', 'G', ' ', 'R', 'e', 's', 'e', 'e', 'd', ' ', 'E', 'n', + 't', 'r', 'o', 'p', 'y', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; + +static const uint8_t kDRBGReseedOutput[64] = { + 0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8, + 0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2, + 0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6, + 0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e, + 0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b, + 0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4, +}; + +static const uint8_t kTLSSecret[32] = { + 0xbf, 0xe4, 0xb7, 0xe0, 0x26, 0x55, 0x5f, 0x6a, 0xdf, 0x5d, 0x27, + 0xd6, 0x89, 0x99, 0x2a, 0xd6, 0xf7, 0x65, 0x66, 0x07, 0x4b, 0x55, + 0x5f, 0x64, 0x55, 0xcd, 0xd5, 0x77, 0xa4, 0xc7, 0x09, 0x61, +}; +static const char kTLSLabel[] = "FIPS self test"; +static const uint8_t kTLSSeed1[16] = { + 0x8f, 0x0d, 0xe8, 0xb6, 0x90, 0x8f, 0xb1, 0xd2, + 0x6d, 0x51, 0xf4, 0x79, 0x18, 0x63, 0x51, 0x65, +}; +static const uint8_t kTLSSeed2[16] = { + 0x7d, 0x24, 0x1a, 0x9d, 0x3c, 0x59, 0xbf, 0x3c, + 0x31, 0x1e, 0x2b, 0x21, 0x41, 0x8d, 0x32, 0x81, +}; + +static const uint8_t kTLSOutput_mdsha1[32] = { + 0x36, 0xa9, 0x31, 0xb0, 0x43, 0xe3, 0x64, 0x72, 0xb9, 0x47, 0x54, + 0x0d, 0x8a, 0xfc, 0xe3, 0x5c, 0x1c, 0x15, 0x67, 0x7e, 0xa3, 0x5d, + 0xf2, 0x3a, 0x57, 0xfd, 0x50, 0x16, 0xe1, 0xa4, 0xa6, 0x37, +}; + +static const uint8_t kTLSOutput_md[32] = { + 0x79, 0xef, 0x46, 0xc4, 0x35, 0xbc, 0xe5, 0xda, 0xd3, 0x66, 0x91, + 0xdc, 0x86, 0x09, 0x41, 0x66, 0xf2, 0x0c, 0xeb, 0xe6, 0xab, 0x5c, + 0x58, 0xf4, 0x65, 0xce, 0x2f, 0x5f, 0x4b, 0x34, 0x1e, 0xa1, +}; + +static const uint8_t kTLSOutput_sha1[32] = { + 0xbb, 0x0a, 0x73, 0x52, 0xf8, 0x85, 0xd7, 0xbd, 0x12, 0x34, 0x78, + 0x3b, 0x54, 0x4c, 0x75, 0xfe, 0xd7, 0x23, 0x6e, 0x22, 0x3f, 0x42, + 0x34, 0x99, 0x57, 0x6b, 0x14, 0xc4, 0xc8, 0xae, 0x9f, 0x4c, +}; + +static const uint8_t kTLSOutput_sha224[32] = { + 0xdd, 0xaf, 0x6f, 0xaa, 0xd9, 0x2b, 0x3d, 0xb9, 0x46, 0x4c, 0x55, + 0x8a, 0xf7, 0xa6, 0x9b, 0x0b, 0x35, 0xcc, 0x07, 0xa7, 0x55, 0x5b, + 0x5e, 0x39, 0x12, 0xc0, 0xd4, 0x30, 0xdf, 0x0c, 0xdf, 0x6b, +}; + +static const uint8_t kTLSOutput_sha256[32] = { + 0x67, 0x85, 0xde, 0x60, 0xfc, 0x0a, 0x83, 0xe9, 0xa2, 0x2a, 0xb3, + 0xf0, 0x27, 0x0c, 0xba, 0xf7, 0xfa, 0x82, 0x3d, 0x14, 0x77, 0x1d, + 0x86, 0x29, 0x79, 0x39, 0x77, 0x8a, 0xd5, 0x0e, 0x9d, 0x32, +}; + +static const uint8_t kTLSOutput_sha384[32] = { + 0x75, 0x15, 0x3f, 0x44, 0x7a, 0xfd, 0x34, 0xed, 0x2b, 0x67, 0xbc, + 0xd8, 0x57, 0x96, 0xab, 0xff, 0xf4, 0x0c, 0x05, 0x94, 0x02, 0x23, + 0x81, 0xbf, 0x0e, 0xd2, 0xec, 0x7c, 0xe0, 0xa7, 0xc3, 0x7d, +}; + +static const uint8_t kTLSOutput_sha512[32] = { + 0x68, 0xb9, 0xc8, 0x4c, 0xf5, 0x51, 0xfc, 0x7a, 0x1f, 0x6c, 0xe5, + 0x43, 0x73, 0x80, 0x53, 0x7c, 0xae, 0x76, 0x55, 0x67, 0xe0, 0x79, + 0xbf, 0x3a, 0x53, 0x71, 0xb7, 0x9c, 0xb5, 0x03, 0x15, 0x3f, +}; + +static const uint8_t kAESGCMCiphertext_128[64 + 16] = { + 0x38, 0x71, 0xcb, 0x61, 0x70, 0x60, 0x13, 0x8b, 0x2f, 0x91, 0x09, 0x7f, + 0x83, 0x20, 0x0f, 0x1f, 0x71, 0xe2, 0x47, 0x46, 0x6f, 0x5f, 0xa8, 0xad, + 0xa8, 0xfc, 0x0a, 0xfd, 0x36, 0x65, 0x84, 0x90, 0x28, 0x2b, 0xcb, 0x4f, + 0x68, 0xae, 0x09, 0xba, 0xae, 0xdd, 0xdb, 0x91, 0xcc, 0x38, 0xb3, 0xad, + 0x10, 0x84, 0xb8, 0x45, 0x36, 0xf3, 0x96, 0xb4, 0xef, 0xba, 0xda, 0x10, + 0xf8, 0x8b, 0xf3, 0xda, 0x91, 0x1f, 0x8c, 0xd8, 0x39, 0x7b, 0x1c, 0xfd, + 0xe7, 0x99, 0x7d, 0xb7, 0x22, 0x69, 0x67, 0xbd, +}; + +static const uint8_t kAESGCMCiphertext_192[64 + 16] = { + 0x05, 0x63, 0x6e, 0xe4, 0xd1, 0x9f, 0xd0, 0x91, 0x18, 0xc9, 0xf8, 0xfd, + 0xc2, 0x62, 0x09, 0x05, 0x91, 0xb4, 0x92, 0x66, 0x18, 0xe7, 0x93, 0x6a, + 0xc7, 0xde, 0x81, 0x36, 0x93, 0x79, 0x45, 0x34, 0xc0, 0x6d, 0x14, 0x94, + 0x93, 0x39, 0x2b, 0x7f, 0x4f, 0x10, 0x1c, 0xa5, 0xfe, 0x3b, 0x37, 0xd7, + 0x0a, 0x98, 0xd7, 0xb5, 0xe0, 0xdc, 0xe4, 0x9f, 0x36, 0x40, 0xad, 0x03, + 0xbf, 0x53, 0xe0, 0x7c, 0x3f, 0x57, 0x4f, 0x80, 0x99, 0xe6, 0x90, 0x4e, + 0x59, 0x2e, 0xe0, 0x76, 0x53, 0x09, 0xc3, 0xd3, +}; + +static const uint8_t kAESGCMCiphertext_256[64 + 16] = { + 0x92, 0x5f, 0xae, 0x84, 0xe7, 0x40, 0xfa, 0x1e, 0xaf, 0x8f, 0x97, 0x0e, + 0x8e, 0xdd, 0x6a, 0x94, 0x22, 0xee, 0x4f, 0x70, 0x66, 0xbf, 0xb1, 0x99, + 0x05, 0xbd, 0xd0, 0xd7, 0x91, 0x54, 0xaf, 0xe1, 0x52, 0xc9, 0x4e, 0x55, + 0xa5, 0x23, 0x62, 0x8b, 0x23, 0x40, 0x90, 0x56, 0xe0, 0x68, 0x63, 0xe5, + 0x7e, 0x5b, 0xbe, 0x96, 0x7b, 0xc4, 0x16, 0xf9, 0xbe, 0x18, 0x06, 0x79, + 0x8f, 0x99, 0x35, 0xe3, 0x2a, 0x82, 0xb5, 0x5e, 0x8a, 0x06, 0xbe, 0x99, + 0x57, 0xb1, 0x76, 0xe1, 0xc5, 0xaa, 0x82, 0xe7, +}; + +static const struct AEADTestVector { + const char *name; + const EVP_AEAD *aead; + const uint8_t *key; + const int key_length; + const uint8_t *expected_ciphertext; + const int cipher_text_length; + const FIPSStatus expect_approved; + const bool test_repeat_nonce; +} kAEADTestVectors[] = { + // Internal IV usage of AES-GCM is approved. + { + "AES-GCM 128-bit key internal iv test", + EVP_aead_aes_128_gcm_randnonce(), + kAESKey, + sizeof(kAESKey), + nullptr, + 0, + FIPSStatus::APPROVED, + false, + }, + { + "AES-GCM 256-bit key internal iv test", + EVP_aead_aes_256_gcm_randnonce(), + kAESKey_256, + sizeof(kAESKey_256), + nullptr, + 0, + FIPSStatus::APPROVED, + false, + }, + // External IV usage of AES-GCM is not approved unless used within a TLS + // context. + { + "Generic AES-GCM 128-bit key external iv test", + EVP_aead_aes_128_gcm(), + kAESKey, + sizeof(kAESKey), + kAESGCMCiphertext_128, + sizeof(kAESGCMCiphertext_128), + FIPSStatus::NOT_APPROVED, + false, + }, + { + "Generic AES-GCM 192-bit key external iv test", + EVP_aead_aes_192_gcm(), + kAESKey_192, + 24, + kAESGCMCiphertext_192, + sizeof(kAESGCMCiphertext_192), + FIPSStatus::NOT_APPROVED, + false, + }, + { + "Generic AES-GCM 256-bit key external iv test", + EVP_aead_aes_256_gcm(), + kAESKey_256, + sizeof(kAESKey_256), + kAESGCMCiphertext_256, + sizeof(kAESGCMCiphertext_256), + FIPSStatus::NOT_APPROVED, + false, + }, + // External IV usage of AEAD AES-GCM APIs specific for TLS is approved. + { + "TLS1.2 AES-GCM 128-bit key external iv test", + EVP_aead_aes_128_gcm_tls12(), + kAESKey, + sizeof(kAESKey), + kAESGCMCiphertext_128, + sizeof(kAESGCMCiphertext_128), + FIPSStatus::APPROVED, + true, + }, + { + "TLS1.2 AES-GCM 256-bit key external iv test", + EVP_aead_aes_256_gcm_tls12(), + kAESKey_256, + sizeof(kAESKey_256), + kAESGCMCiphertext_256, + sizeof(kAESGCMCiphertext_256), + FIPSStatus::APPROVED, + true, + }, + { + "TLS1.3 AES-GCM 128-bit key external iv test", + EVP_aead_aes_128_gcm_tls13(), + kAESKey, + sizeof(kAESKey), + kAESGCMCiphertext_128, + sizeof(kAESGCMCiphertext_128), + FIPSStatus::APPROVED, + true, + }, + { + "TLS1.3 AES-GCM 256-bit key external iv test", + EVP_aead_aes_256_gcm_tls13(), + kAESKey_256, + sizeof(kAESKey_256), + kAESGCMCiphertext_256, + sizeof(kAESGCMCiphertext_256), + FIPSStatus::APPROVED, + true, + }, + // 128 bit keys with 32 bit tag lengths are approved for AES-CCM. + { + "AES-CCM 128-bit key test", + EVP_aead_aes_128_ccm_bluetooth(), + kAESKey, + sizeof(kAESKey), + kAESCCMCiphertext, + sizeof(kAESCCMCiphertext), + FIPSStatus::APPROVED, + false, + }, +}; + +class AEADServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, AEADServiceIndicatorTest, + testing::ValuesIn(kAEADTestVectors)); + +TEST_P(AEADServiceIndicatorTest, EVP_AEAD) { + const AEADTestVector &test = GetParam(); + SCOPED_TRACE(test.name); + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::ScopedEVP_AEAD_CTX aead_ctx; + std::vector nonce(EVP_AEAD_nonce_length(test.aead), 0); + std::vector encrypt_output(256); + std::vector decrypt_output(256); + size_t out_len; + + // Test running the EVP_AEAD_CTX interfaces one by one directly, and check + // |EVP_AEAD_CTX_seal| and |EVP_AEAD_CTX_open| for approval at the end. + // |EVP_AEAD_CTX_init| should not be approved because the function does not + // indicate that a service has been fully completed yet. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_AEAD_CTX_init(aead_ctx.get(), test.aead, test.key, + test.key_length, 0, nullptr))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_AEAD_CTX_seal(aead_ctx.get(), encrypt_output.data(), + &out_len, encrypt_output.size(), nonce.data(), + EVP_AEAD_nonce_length(test.aead), kPlaintext, + sizeof(kPlaintext), nullptr, 0))); + EXPECT_EQ(approved, test.expect_approved); + encrypt_output.resize(out_len); + if (test.expected_ciphertext) { + EXPECT_EQ(Bytes(test.expected_ciphertext, test.cipher_text_length), + Bytes(encrypt_output)); + } + + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_AEAD_CTX_open(aead_ctx.get(), decrypt_output.data(), &out_len, + decrypt_output.size(), nonce.data(), nonce.size(), + encrypt_output.data(), out_len, nullptr, 0))); + // Decryption doesn't have nonce uniqueness requirements and so is always + // approved for approved key lengths. + EXPECT_EQ(approved, test.key_length != 24 ? FIPSStatus::APPROVED + : FIPSStatus::NOT_APPROVED); + decrypt_output.resize(out_len); + EXPECT_EQ(Bytes(kPlaintext), Bytes(decrypt_output)); + + // Second call when encrypting using the same nonce for AES-GCM TLS specific + // functions should fail and return |FIPSStatus::NOT_APPROVED|. + if (test.test_repeat_nonce) { + ASSERT_FALSE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_AEAD_CTX_seal(aead_ctx.get(), encrypt_output.data(), &out_len, + encrypt_output.size(), nonce.data(), nonce.size(), + kPlaintext, sizeof(kPlaintext), nullptr, 0))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + EXPECT_EQ(ERR_GET_REASON(ERR_get_error()), CIPHER_R_INVALID_NONCE); + } +} + +static const struct CipherTestVector { + const EVP_CIPHER *cipher; + const uint8_t *key; + const int key_length; + const uint8_t *expected_ciphertext; + const int cipher_text_length; + const bool has_iv; + const FIPSStatus expect_approved; +} kTestVectors[] = { + { + EVP_aes_128_ecb(), + kAESKey, + sizeof(kAESKey), + kAESECBCiphertext, + sizeof(kAESECBCiphertext), + false, + FIPSStatus::APPROVED, + }, + { + EVP_aes_192_ecb(), + kAESKey_192, + sizeof(kAESKey_192), + kAESECBCiphertext_192, + sizeof(kAESECBCiphertext_192), + false, + FIPSStatus::APPROVED, + }, + { + EVP_aes_256_ecb(), + kAESKey_256, + sizeof(kAESKey_256), + kAESECBCiphertext_256, + sizeof(kAESECBCiphertext_256), + false, + FIPSStatus::APPROVED, + }, + { + EVP_aes_128_cbc(), + kAESKey, + sizeof(kAESKey), + kAESCBCCiphertext, + sizeof(kAESCBCCiphertext), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_192_cbc(), + kAESKey_192, + sizeof(kAESKey_192), + kAESCBCCiphertext_192, + sizeof(kAESCBCCiphertext_192), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_256_cbc(), + kAESKey_256, + sizeof(kAESKey_256), + kAESCBCCiphertext_256, + sizeof(kAESCBCCiphertext_256), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_128_ctr(), + kAESKey, + sizeof(kAESKey), + kAESCTRCiphertext, + sizeof(kAESCTRCiphertext), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_192_ctr(), + kAESKey_192, + sizeof(kAESKey_192), + kAESCTRCiphertext_192, + sizeof(kAESCTRCiphertext_192), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_256_ctr(), + kAESKey_256, + sizeof(kAESKey_256), + kAESCTRCiphertext_256, + sizeof(kAESCTRCiphertext_256), + true, + FIPSStatus::APPROVED, + }, + { + EVP_aes_128_ofb(), + kAESKey, + sizeof(kAESKey), + kAESOFBCiphertext, + sizeof(kAESOFBCiphertext), + true, + FIPSStatus::NOT_APPROVED, + }, + { + EVP_des_ede3(), + kAESKey_192, + sizeof(kAESKey_192), + kTDES_EDE3_CipherText, + sizeof(kTDES_EDE3_CipherText), + false, + FIPSStatus::NOT_APPROVED, + }, + { + EVP_des_ede3_cbc(), + kAESKey_192, + sizeof(kAESKey_192), + kTDES_EDE3_CBCCipherText, + sizeof(kTDES_EDE3_CBCCipherText), + false, + FIPSStatus::NOT_APPROVED, + }, +}; + +class EVPServiceIndicatorTest : public TestWithNoErrors {}; + +static void TestOperation(const EVP_CIPHER *cipher, bool encrypt, + const bssl::Span key, + const bssl::Span plaintext, + const bssl::Span ciphertext, + FIPSStatus expect_approved) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + bssl::Span in, out; + if (encrypt) { + in = plaintext; + out = ciphertext; + } else { + in = ciphertext; + out = plaintext; + } + + bssl::ScopedEVP_CIPHER_CTX ctx; + // Test running the EVP_Cipher interfaces one by one directly, and check + // |EVP_EncryptFinal_ex| and |EVP_DecryptFinal_ex| for approval at the end. + ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr, + encrypt ? 1 : 0)); + ASSERT_LE(EVP_CIPHER_CTX_iv_length(ctx.get()), sizeof(kAESIV)); + + ASSERT_TRUE(EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size())); + ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), cipher, nullptr, key.data(), kAESIV, + encrypt ? 1 : 0)); + ASSERT_TRUE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0)); + std::vector encrypt_result; + DoCipherFinal(ctx.get(), &encrypt_result, in, expect_approved); + EXPECT_EQ(Bytes(out), Bytes(encrypt_result)); + + // Test using the one-shot |EVP_Cipher| function for approval. + bssl::ScopedEVP_CIPHER_CTX ctx2; + uint8_t output[256]; + ASSERT_TRUE(EVP_CipherInit_ex(ctx2.get(), cipher, nullptr, key.data(), kAESIV, + encrypt ? 1 : 0)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_Cipher(ctx2.get(), output, in.data(), in.size())); + EXPECT_EQ(approved, expect_approved); + EXPECT_EQ(Bytes(out), Bytes(output, in.size())); +} + +INSTANTIATE_TEST_SUITE_P(All, EVPServiceIndicatorTest, + testing::ValuesIn(kTestVectors)); + +TEST_P(EVPServiceIndicatorTest, EVP_Ciphers) { + const CipherTestVector &test = GetParam(); + + const EVP_CIPHER *cipher = test.cipher; + std::vector key(test.key, test.key + test.key_length); + std::vector plaintext(kPlaintext, kPlaintext + sizeof(kPlaintext)); + std::vector ciphertext( + test.expected_ciphertext, + test.expected_ciphertext + test.cipher_text_length); + + TestOperation(cipher, true /* encrypt */, key, plaintext, ciphertext, + test.expect_approved); + TestOperation(cipher, false /* decrypt */, key, plaintext, ciphertext, + test.expect_approved); +} + +static const struct DigestTestVector { + // name is the name of the digest test. + const char *name; + // length of digest. + const int length; + // func is the digest to test. + const EVP_MD *(*func)(); + // one_shot_func is the convenience one-shot version of the digest. + uint8_t *(*one_shot_func)(const uint8_t *, size_t, uint8_t *); + // expected_digest is the expected digest. + const uint8_t *expected_digest; + // expected to be approved or not. + const FIPSStatus expect_approved; +} kDigestTestVectors[] = { + { + "MD4", + MD4_DIGEST_LENGTH, + &EVP_md4, + &MD4, + kOutput_md4, + FIPSStatus::NOT_APPROVED, + }, + { + "MD5", + MD5_DIGEST_LENGTH, + &EVP_md5, + &MD5, + kOutput_md5, + FIPSStatus::NOT_APPROVED, + }, + { + "SHA-1", + SHA_DIGEST_LENGTH, + &EVP_sha1, + &SHA1, + kOutput_sha1, + FIPSStatus::APPROVED, + }, + { + "SHA-224", + SHA224_DIGEST_LENGTH, + &EVP_sha224, + &SHA224, + kOutput_sha224, + FIPSStatus::APPROVED, + }, + { + "SHA-256", + SHA256_DIGEST_LENGTH, + &EVP_sha256, + &SHA256, + kOutput_sha256, + FIPSStatus::APPROVED, + }, + { + "SHA-384", + SHA384_DIGEST_LENGTH, + &EVP_sha384, + &SHA384, + kOutput_sha384, + FIPSStatus::APPROVED, + }, + { + "SHA-512", + SHA512_DIGEST_LENGTH, + &EVP_sha512, + &SHA512, + kOutput_sha512, + FIPSStatus::APPROVED, + }, + { + "SHA-512/256", + SHA512_256_DIGEST_LENGTH, + &EVP_sha512_256, + &SHA512_256, + kOutput_sha512_256, + FIPSStatus::APPROVED, + }, +}; + +class EVPMDServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, EVPMDServiceIndicatorTest, + testing::ValuesIn(kDigestTestVectors)); + +TEST_P(EVPMDServiceIndicatorTest, EVP_Digests) { + const DigestTestVector &test = GetParam(); + SCOPED_TRACE(test.name); + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + bssl::ScopedEVP_MD_CTX ctx; + std::vector digest(test.length); + unsigned digest_len; + + // Test running the EVP_Digest interfaces one by one directly, and check + // |EVP_DigestFinal_ex| for approval at the end. |EVP_DigestInit_ex| and + // |EVP_DigestUpdate| should not be approved, because the functions do not + // indicate that a service has been fully completed yet. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestInit_ex(ctx.get(), test.func(), nullptr))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestUpdate(ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestFinal_ex(ctx.get(), digest.data(), &digest_len))); + EXPECT_EQ(approved, test.expect_approved); + EXPECT_EQ(Bytes(test.expected_digest, digest_len), Bytes(digest)); + + // Test using the one-shot |EVP_Digest| function for approval. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_Digest(kPlaintext, sizeof(kPlaintext), digest.data(), + &digest_len, test.func(), nullptr))); + EXPECT_EQ(approved, test.expect_approved); + EXPECT_EQ(Bytes(test.expected_digest, test.length), Bytes(digest)); + + // Test using the one-shot API for approval. + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + test.one_shot_func(kPlaintext, sizeof(kPlaintext), digest.data())); + EXPECT_EQ(approved, test.expect_approved); + EXPECT_EQ(Bytes(test.expected_digest, test.length), Bytes(digest)); +} + +static const struct HMACTestVector { + // func is the hash function for HMAC to test. + const EVP_MD *(*func)(void); + // expected_digest is the expected digest. + const uint8_t *expected_digest; + // expected to be approved or not. + const FIPSStatus expect_approved; +} kHMACTestVectors[] = { + {EVP_sha1, kHMACOutput_sha1, FIPSStatus::APPROVED}, + {EVP_sha224, kHMACOutput_sha224, FIPSStatus::APPROVED}, + {EVP_sha256, kHMACOutput_sha256, FIPSStatus::APPROVED}, + {EVP_sha384, kHMACOutput_sha384, FIPSStatus::APPROVED}, + {EVP_sha512, kHMACOutput_sha512, FIPSStatus::APPROVED}, + {EVP_sha512_256, kHMACOutput_sha512_256, FIPSStatus::APPROVED}, +}; + +class HMACServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, HMACServiceIndicatorTest, + testing::ValuesIn(kHMACTestVectors)); + +TEST_P(HMACServiceIndicatorTest, HMACTest) { + const HMACTestVector &test = GetParam(); + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + // The key is deliberately long in order to trigger digesting it down to a + // block size. This tests that doing so does not cause the indicator to be + // mistakenly set in |HMAC_Init_ex|. + const uint8_t kHMACKey[512] = {0}; + const EVP_MD *const digest = test.func(); + const unsigned expected_mac_len = EVP_MD_size(digest); + std::vector mac(expected_mac_len); + + // Test running the HMAC interfaces one by one directly, and check + // |HMAC_Final| for approval at the end. |HMAC_Init_ex| and |HMAC_Update| + // should not be approved, because the functions do not indicate that a + // service has been fully completed yet. + unsigned mac_len; + bssl::ScopedHMAC_CTX ctx; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + HMAC_Init_ex(ctx.get(), kHMACKey, sizeof(kHMACKey), digest, nullptr))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, HMAC_Update(ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, HMAC_Final(ctx.get(), mac.data(), &mac_len))); + EXPECT_EQ(approved, test.expect_approved); + EXPECT_EQ(Bytes(test.expected_digest, expected_mac_len), + Bytes(mac.data(), mac_len)); + + // Test using the one-shot API for approval. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, HMAC(digest, kHMACKey, sizeof(kHMACKey), kPlaintext, + sizeof(kPlaintext), mac.data(), &mac_len))); + EXPECT_EQ(approved, test.expect_approved); + EXPECT_EQ(Bytes(test.expected_digest, expected_mac_len), + Bytes(mac.data(), mac_len)); +} + +// RSA tests are not parameterized with the |kRSATestVectors| as key +// generation for RSA is time consuming. +TEST(ServiceIndicatorTest, RSAKeyGen) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + bssl::UniquePtr rsa(RSA_new()); + ASSERT_TRUE(rsa); + + // |RSA_generate_key_fips| may only be used for 2048-, 3072-, and 4096-bit + // keys. + for (const size_t bits : {512, 1024, 3071, 4095}) { + SCOPED_TRACE(bits); + + rsa.reset(RSA_new()); + EXPECT_FALSE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, RSA_generate_key_fips(rsa.get(), bits, nullptr))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + } + + // Test that we can generate keys of the supported lengths: + for (const size_t bits : {2048, 3072, 4096}) { + SCOPED_TRACE(bits); + + rsa.reset(RSA_new()); + EXPECT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, RSA_generate_key_fips(rsa.get(), bits, nullptr))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + EXPECT_EQ(bits, RSA_bits(rsa.get())); + } + + // Test running the EVP_PKEY_keygen interfaces one by one directly, and check + // |EVP_PKEY_keygen| for approval at the end. |EVP_PKEY_keygen_init| should + // not be approved because it does not indicate an entire service has been + // completed. + bssl::UniquePtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr)); + EVP_PKEY *raw = nullptr; + bssl::UniquePtr pkey(raw); + ASSERT_TRUE(ctx); + + if (kEVPKeyGenShouldCallFIPSFunctions) { + // Test unapproved key sizes of RSA. + for (const size_t bits : {512, 1024, 3071, 4095}) { + SCOPED_TRACE(bits); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_keygen_init(ctx.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), bits)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_keygen(ctx.get(), &raw))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + pkey.reset(raw); + raw = nullptr; + } + + // Test approved key sizes of RSA. + for (const size_t bits : {2048, 3072, 4096}) { + SCOPED_TRACE(bits); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_keygen_init(ctx.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), bits)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_keygen(ctx.get(), &raw))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + pkey.reset(raw); + raw = nullptr; + } + } +} + +struct RSATestVector { + // key_size is the input rsa key size. + int key_size; + // md_func is the digest to test. + const EVP_MD *(*func)(); + // whether to use pss testing or not. + bool use_pss; + // expected to be approved or not for signature generation. + FIPSStatus sig_gen_expect_approved; + // expected to be approved or not for signature verification. + FIPSStatus sig_ver_expect_approved; +}; + +static const struct RSATestVector kRSATestVectors[] = { + // RSA test cases that are not approved in any case. + {512, &EVP_sha1, false, FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + // PSS with hashLen == saltLen is not possible for 512-bit modulus. + {1024, &EVP_md5, false, FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {1536, &EVP_sha256, false, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED}, + {1536, &EVP_sha512, true, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED}, + {2048, &EVP_md5, false, FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {3071, &EVP_md5, true, FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {3071, &EVP_sha256, false, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED}, + {3071, &EVP_sha512, true, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED}, + {4096, &EVP_md5, false, FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + + // RSA test cases that are approved. + {1024, &EVP_sha1, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {1024, &EVP_sha256, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {1024, &EVP_sha512, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {1024, &EVP_sha1, true, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {1024, &EVP_sha256, true, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + // PSS with hashLen == saltLen is not possible for 1024-bit modulus and + // SHA-512. + + {2048, &EVP_sha1, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha224, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha256, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha384, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha512, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha1, true, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha224, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha256, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha384, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {2048, &EVP_sha512, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + + {3072, &EVP_sha1, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha224, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha256, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha384, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha512, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha1, true, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha224, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha256, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha384, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {3072, &EVP_sha512, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + + {4096, &EVP_sha1, false, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha224, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha256, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha384, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha512, false, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha1, true, FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha224, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha256, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha384, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {4096, &EVP_sha512, true, FIPSStatus::APPROVED, FIPSStatus::APPROVED}, +}; + +class RSAServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, RSAServiceIndicatorTest, + testing::ValuesIn(kRSATestVectors)); + +static std::map> &CachedRSAKeys() { + static std::map> keys; + return keys; +} + +static RSA *GetRSAKey(unsigned bits) { + auto it = CachedRSAKeys().find(bits); + if (it != CachedRSAKeys().end()) { + return it->second.get(); + } + + bssl::UniquePtr e(BN_new()); + if (!e || !BN_set_word(e.get(), RSA_F4)) { + abort(); + } + + bssl::UniquePtr key(RSA_new()); + if (!key || !RSA_generate_key_ex(key.get(), bits, e.get(), nullptr)) { + abort(); + } + + RSA *const ret = key.get(); + CachedRSAKeys().emplace(static_cast(bits), std::move(key)); + + return ret; +} + +TEST_P(RSAServiceIndicatorTest, RSASigGen) { + const RSATestVector &test = GetParam(); + SCOPED_TRACE(test.key_size); + + bssl::UniquePtr pkey(EVP_PKEY_new()); + ASSERT_TRUE(pkey); + + RSA *const rsa = GetRSAKey(test.key_size); + ASSERT_TRUE(EVP_PKEY_set1_RSA(pkey.get(), rsa)); + + // Test running the EVP_DigestSign interfaces one by one directly, and check + // |EVP_DigestSignFinal| for approval at the end. |EVP_DigestSignInit|, and + // |EVP_DigestSignUpdate| should not be approved because they do not indicate + // an entire service has been completed. + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + bssl::ScopedEVP_MD_CTX md_ctx; + EVP_PKEY_CTX *pctx = nullptr; + size_t sig_len; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + if (test.use_pss) { + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + } + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestSignUpdate(md_ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + // Determine the size of the signature. The first call of + // |EVP_DigestSignFinal| should not return an approval check because no crypto + // is being done when |nullptr| is inputted in the |*out_sig| field. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignFinal(md_ctx.get(), nullptr, &sig_len))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + std::vector signature(sig_len); + // The second call performs the actual operation. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignFinal(md_ctx.get(), signature.data(), &sig_len))); + EXPECT_EQ(approved, test.sig_gen_expect_approved); + + // Test using the one-shot |EVP_DigestSign| function for approval. + md_ctx.Reset(); + std::vector oneshot_output(sig_len); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + if (test.use_pss) { + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + } + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSign(md_ctx.get(), oneshot_output.data(), &sig_len, + kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, test.sig_gen_expect_approved); + + if (test.use_pss) { + // Odd configurations of PSS, for example where the salt length is not equal + // to the hash length, are not approved. + md_ctx.Reset(); + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, 10)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSign(md_ctx.get(), oneshot_output.data(), &sig_len, + kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + } +} + +TEST_P(RSAServiceIndicatorTest, RSASigVer) { + const RSATestVector &test = GetParam(); + + bssl::UniquePtr pkey(EVP_PKEY_new()); + RSA *const rsa = GetRSAKey(test.key_size); + + ASSERT_TRUE(pkey); + ASSERT_TRUE(EVP_PKEY_set1_RSA(pkey.get(), rsa)); + + std::vector signature; + size_t sig_len; + bssl::ScopedEVP_MD_CTX md_ctx; + EVP_PKEY_CTX *pctx = nullptr; + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get())); + if (test.use_pss) { + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)); + } + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), nullptr, &sig_len, nullptr, 0)); + signature.resize(sig_len); + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), signature.data(), &sig_len, + kPlaintext, sizeof(kPlaintext))); + signature.resize(sig_len); + + // Service Indicator approval checks for RSA signature verification. + + // Test running the EVP_DigestVerify interfaces one by one directly, and check + // |EVP_DigestVerifyFinal| for approval at the end. |EVP_DigestVerifyInit|, + // |EVP_DigestVerifyUpdate| should not be approved because they do not + // indicate an entire service has been done. + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + md_ctx.Reset(); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestVerifyInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + if (test.use_pss) { + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)); + } + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerifyUpdate(md_ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerifyFinal(md_ctx.get(), signature.data(), signature.size()))); + EXPECT_EQ(approved, test.sig_ver_expect_approved); + + // Test using the one-shot |EVP_DigestVerify| function for approval. + md_ctx.Reset(); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestVerifyInit(md_ctx.get(), &pctx, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + if (test.use_pss) { + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)); + } + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerify(md_ctx.get(), signature.data(), signature.size(), + kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, test.sig_ver_expect_approved); +} + +struct ECDSATestVector { + // nid is the input curve nid. + int nid; + // md_func is the digest to test. + const EVP_MD *(*func)(); + // expected to be approved or not for signature generation. + FIPSStatus key_check_expect_approved; + // expected to be approved or not for signature generation. + FIPSStatus sig_gen_expect_approved; + // expected to be approved or not for signature verification. + FIPSStatus sig_ver_expect_approved; +}; + +static const struct ECDSATestVector kECDSATestVectors[] = { + // Only the following NIDs for |EC_GROUP| are creatable with + // |EC_GROUP_new_by_curve_name|, and |NID_secp256k1| will only work if + // |kCurveSecp256k1Supported| is true. + {NID_secp224r1, &EVP_sha1, FIPSStatus::APPROVED, FIPSStatus::NOT_APPROVED, + FIPSStatus::APPROVED}, + {NID_secp224r1, &EVP_sha224, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp224r1, &EVP_sha256, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp224r1, &EVP_sha384, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp224r1, &EVP_sha512, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + + {NID_X9_62_prime256v1, &EVP_sha1, FIPSStatus::APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, &EVP_sha224, FIPSStatus::APPROVED, + FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, &EVP_sha256, FIPSStatus::APPROVED, + FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, &EVP_sha384, FIPSStatus::APPROVED, + FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, &EVP_sha512, FIPSStatus::APPROVED, + FIPSStatus::APPROVED, FIPSStatus::APPROVED}, + + {NID_secp384r1, &EVP_sha1, FIPSStatus::APPROVED, FIPSStatus::NOT_APPROVED, + FIPSStatus::APPROVED}, + {NID_secp384r1, &EVP_sha224, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp384r1, &EVP_sha256, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp384r1, &EVP_sha384, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp384r1, &EVP_sha512, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + + {NID_secp521r1, &EVP_sha1, FIPSStatus::APPROVED, FIPSStatus::NOT_APPROVED, + FIPSStatus::APPROVED}, + {NID_secp521r1, &EVP_sha224, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp521r1, &EVP_sha256, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp521r1, &EVP_sha384, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + {NID_secp521r1, &EVP_sha512, FIPSStatus::APPROVED, FIPSStatus::APPROVED, + FIPSStatus::APPROVED}, + + {NID_secp256k1, &EVP_sha1, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, &EVP_sha224, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, &EVP_sha256, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, &EVP_sha384, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, &EVP_sha512, FIPSStatus::NOT_APPROVED, + FIPSStatus::NOT_APPROVED, FIPSStatus::NOT_APPROVED}, +}; + +class ECDSAServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, ECDSAServiceIndicatorTest, + testing::ValuesIn(kECDSATestVectors)); + +TEST_P(ECDSAServiceIndicatorTest, ECDSAKeyCheck) { + const ECDSATestVector &test = GetParam(); + if (test.nid == NID_secp256k1 && !kCurveSecp256k1Supported) { + GTEST_SKIP(); + } + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + // Test service indicator approval for |EC_KEY_generate_key_fips| and + // |EC_KEY_check_fips|. + bssl::UniquePtr key(EC_KEY_new_by_curve_name(test.nid)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EC_KEY_generate_key_fips(key.get()))); + EXPECT_EQ(approved, test.key_check_expect_approved); + ASSERT_TRUE( + CALL_SERVICE_AND_CHECK_APPROVED(approved, EC_KEY_check_fips(key.get()))); + EXPECT_EQ(approved, test.key_check_expect_approved); + + // See if |EC_KEY_check_fips| still returns approval with only the public + // component. + bssl::UniquePtr key_only_public(EC_KEY_new_by_curve_name(test.nid)); + ASSERT_TRUE(EC_KEY_set_public_key(key_only_public.get(), + EC_KEY_get0_public_key(key.get()))); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EC_KEY_check_fips(key_only_public.get()))); + EXPECT_EQ(approved, test.key_check_expect_approved); + + if (kEVPKeyGenShouldCallFIPSFunctions) { + // Test running the EVP_PKEY_keygen interfaces one by one directly, and + // check |EVP_PKEY_keygen| for approval at the end. |EVP_PKEY_keygen_init| + // should not be approved because it does not indicate that an entire + // service has been completed. + bssl::UniquePtr ctx( + EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr)); + EVP_PKEY *raw = nullptr; + ASSERT_TRUE(ctx); + ASSERT_TRUE(EVP_PKEY_keygen_init(ctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), test.nid)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_keygen(ctx.get(), &raw))); + EXPECT_EQ(approved, test.key_check_expect_approved); + + EVP_PKEY_free(raw); + } +} + +TEST_P(ECDSAServiceIndicatorTest, ECDSASigGen) { + const ECDSATestVector &test = GetParam(); + if (test.nid == NID_secp256k1 && !kCurveSecp256k1Supported) { + GTEST_SKIP(); + } + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::UniquePtr group(EC_GROUP_new_by_curve_name(test.nid)); + bssl::UniquePtr eckey(EC_KEY_new()); + bssl::UniquePtr pkey(EVP_PKEY_new()); + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(eckey); + ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get())); + + // Generate a generic EC key. + ASSERT_TRUE(EC_KEY_generate_key(eckey.get())); + ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(pkey.get(), eckey.get())); + + // Test running the EVP_DigestSign interfaces one by one directly, and check + // |EVP_DigestSignFinal| for approval at the end. |EVP_DigestSignInit|, + // |EVP_DigestSignUpdate| should not be approved because they do not indicate + // an entire service has been done. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignInit(md_ctx.get(), nullptr, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestSignUpdate(md_ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + // Determine the size of the signature. The first call of + // |EVP_DigestSignFinal| should not return an approval check because no crypto + // is being done when |nullptr| is given as the |out_sig| field. + size_t max_sig_len; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignFinal(md_ctx.get(), nullptr, &max_sig_len))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + std::vector signature(max_sig_len); + // The second call performs the actual operation. + size_t sig_len = max_sig_len; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignFinal(md_ctx.get(), signature.data(), &sig_len))); + ASSERT_LE(sig_len, signature.size()); + EXPECT_EQ(approved, test.sig_gen_expect_approved); + + // Test using the one-shot |EVP_DigestSign| function for approval. + md_ctx.Reset(); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSignInit(md_ctx.get(), nullptr, test.func(), nullptr, + pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + sig_len = max_sig_len; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestSign(md_ctx.get(), signature.data(), &sig_len, + kPlaintext, sizeof(kPlaintext)))); + ASSERT_LE(sig_len, signature.size()); + EXPECT_EQ(approved, test.sig_gen_expect_approved); +} + +TEST_P(ECDSAServiceIndicatorTest, ECDSASigVer) { + const ECDSATestVector &test = GetParam(); + if (test.nid == NID_secp256k1 && !kCurveSecp256k1Supported) { + GTEST_SKIP(); + } + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::UniquePtr group(EC_GROUP_new_by_curve_name(test.nid)); + bssl::UniquePtr eckey(EC_KEY_new()); + bssl::UniquePtr pkey(EVP_PKEY_new()); + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(eckey); + ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get())); + + // Generate ECDSA signatures for ECDSA verification. + ASSERT_TRUE(EC_KEY_generate_key(eckey.get())); + ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(pkey.get(), eckey.get())); + std::vector signature; + size_t sig_len = 0; + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, test.func(), nullptr, + pkey.get())); + ASSERT_TRUE(EVP_DigestSignFinal(md_ctx.get(), nullptr, &sig_len)); + signature.resize(sig_len); + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), signature.data(), &sig_len, + kPlaintext, sizeof(kPlaintext))); + signature.resize(sig_len); + + // Service Indicator approval checks for ECDSA signature verification. + + // Test running the EVP_DigestVerify interfaces one by one directly, and check + // |EVP_DigestVerifyFinal| for approval at the end. |EVP_DigestVerifyInit|, + // |EVP_DigestVerifyUpdate| should not be approved because they do not + // indicate an entire service has been done. + md_ctx.Reset(); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestVerifyInit(md_ctx.get(), nullptr, test.func(), + nullptr, pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerifyUpdate(md_ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerifyFinal(md_ctx.get(), signature.data(), signature.size()))); + EXPECT_EQ(approved, test.sig_ver_expect_approved); + + // Test using the one-shot |EVP_DigestVerify| function for approval. + md_ctx.Reset(); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_DigestVerifyInit(md_ctx.get(), nullptr, test.func(), + nullptr, pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_DigestVerify(md_ctx.get(), signature.data(), signature.size(), + kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, test.sig_ver_expect_approved); +} + +#if defined(AWSLC_FIPS) + +// Test that |EVP_DigestSignFinal| and |EVP_DigestSignVerify| are approved with +// manually constructing using the context setting functions. +TEST_P(ECDSAServiceIndicatorTest, ManualECDSASignVerify) { + const ECDSATestVector &test = GetParam(); + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::ScopedEVP_MD_CTX ctx; + ASSERT_TRUE(EVP_DigestInit(ctx.get(), test.func())); + ASSERT_TRUE(EVP_DigestUpdate(ctx.get(), kPlaintext, sizeof(kPlaintext))); + + bssl::UniquePtr group(EC_GROUP_new_by_curve_name(test.nid)); + bssl::UniquePtr eckey(EC_KEY_new()); + bssl::UniquePtr pkey(EVP_PKEY_new()); + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(eckey); + ASSERT_TRUE(EC_KEY_set_group(eckey.get(), group.get())); + + // Generate a generic ec key. + EC_KEY_generate_key(eckey.get()); + ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(pkey.get(), eckey.get())); + + // Manual construction for signing. + bssl::UniquePtr pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + ASSERT_TRUE(EVP_PKEY_sign_init(pctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_signature_md(pctx.get(), test.func())); + EVP_MD_CTX_set_pkey_ctx(ctx.get(), pctx.get()); + // Determine the size of the signature. + size_t sig_len = 0; + CALL_SERVICE_AND_CHECK_APPROVED( + approved, ASSERT_TRUE(EVP_DigestSignFinal(ctx.get(), nullptr, &sig_len))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + std::vector sig; + sig.resize(sig_len); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + ASSERT_TRUE(EVP_DigestSignFinal(ctx.get(), sig.data(), &sig_len))); + EXPECT_EQ(approved, test.sig_gen_expect_approved); + sig.resize(sig_len); + + // Manual construction for verification. + ASSERT_TRUE(EVP_PKEY_verify_init(pctx.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_signature_md(pctx.get(), test.func())); + EVP_MD_CTX_set_pkey_ctx(ctx.get(), pctx.get()); + + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + ASSERT_TRUE(EVP_DigestVerifyFinal(ctx.get(), sig.data(), sig_len))); + EXPECT_EQ(approved, test.sig_ver_expect_approved); +} + +#endif // AWSLC_FIPS + +struct ECDHTestVector { + // nid is the input curve nid. + const int nid; + // digest_length is the length of the hash output to test with. + const int digest_length; + // expect_approved to be approved or not. + const FIPSStatus expect_approved; +}; + +static const struct ECDHTestVector kECDHTestVectors[] = { + // Only the following NIDs for |EC_GROUP| are creatable with + // |EC_GROUP_new_by_curve_name|. + // |ECDH_compute_key_fips| fails directly when an invalid hash length is + // inputted. + {NID_secp224r1, SHA224_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp224r1, SHA256_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp224r1, SHA384_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp224r1, SHA512_DIGEST_LENGTH, FIPSStatus::APPROVED}, + + {NID_X9_62_prime256v1, SHA224_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, SHA256_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, SHA384_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_X9_62_prime256v1, SHA512_DIGEST_LENGTH, FIPSStatus::APPROVED}, + + {NID_secp384r1, SHA224_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp384r1, SHA256_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp384r1, SHA384_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp384r1, SHA512_DIGEST_LENGTH, FIPSStatus::APPROVED}, + + {NID_secp521r1, SHA224_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp521r1, SHA256_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp521r1, SHA384_DIGEST_LENGTH, FIPSStatus::APPROVED}, + {NID_secp521r1, SHA512_DIGEST_LENGTH, FIPSStatus::APPROVED}, + + {NID_secp256k1, SHA224_DIGEST_LENGTH, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, SHA256_DIGEST_LENGTH, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, SHA384_DIGEST_LENGTH, FIPSStatus::NOT_APPROVED}, + {NID_secp256k1, SHA512_DIGEST_LENGTH, FIPSStatus::NOT_APPROVED}, +}; + +class ECDH_ServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, ECDH_ServiceIndicatorTest, + testing::ValuesIn(kECDHTestVectors)); + +TEST_P(ECDH_ServiceIndicatorTest, ECDH) { + const ECDHTestVector &test = GetParam(); + if (test.nid == NID_secp256k1 && !kCurveSecp256k1Supported) { + GTEST_SKIP(); + } + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::UniquePtr group(EC_GROUP_new_by_curve_name(test.nid)); + bssl::UniquePtr our_key(EC_KEY_new()); + bssl::UniquePtr peer_key(EC_KEY_new()); + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(our_key); + ASSERT_TRUE(peer_key); + + // Generate two generic ec key pairs. + ASSERT_TRUE(EC_KEY_set_group(our_key.get(), group.get())); + ASSERT_TRUE(EC_KEY_generate_key(our_key.get())); + ASSERT_TRUE(EC_KEY_check_key(our_key.get())); + + ASSERT_TRUE(EC_KEY_set_group(peer_key.get(), group.get())); + ASSERT_TRUE(EC_KEY_generate_key(peer_key.get())); + ASSERT_TRUE(EC_KEY_check_key(peer_key.get())); + + // Test that |ECDH_compute_key_fips| has service indicator approval as + // expected. + std::vector digest(test.digest_length); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, ECDH_compute_key_fips(digest.data(), digest.size(), + EC_KEY_get0_public_key(peer_key.get()), + our_key.get()))); + EXPECT_EQ(approved, test.expect_approved); + + // Test running the EVP_PKEY_derive interfaces one by one directly, and check + // |EVP_PKEY_derive| for approval at the end. |EVP_PKEY_derive_init| and + // |EVP_PKEY_derive_set_peer| should not be approved because they do not + // indicate an entire service has been done. + bssl::UniquePtr our_pkey(EVP_PKEY_new()); + ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(our_pkey.get(), our_key.get())); + bssl::UniquePtr our_ctx( + EVP_PKEY_CTX_new(our_pkey.get(), nullptr)); + bssl::UniquePtr peer_pkey(EVP_PKEY_new()); + ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(peer_pkey.get(), peer_key.get())); + + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_derive_init(our_ctx.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_derive_set_peer(our_ctx.get(), peer_pkey.get()))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + // Determine the size of the output key. The first call of |EVP_PKEY_derive| + // should not return an approval check because no crypto is being done when + // |nullptr| is inputted in the |*key| field + size_t out_len = 0; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_PKEY_derive(our_ctx.get(), nullptr, &out_len))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + std::vector derive_output(out_len); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_PKEY_derive(our_ctx.get(), derive_output.data(), &out_len))); + EXPECT_EQ(approved, kEVPDeriveSetsServiceIndicator + ? test.expect_approved + : FIPSStatus::NOT_APPROVED); +} + +static const struct KDFTestVector { + // func is the hash function for KDF to test. + const EVP_MD *(*func)(); + const uint8_t *expected_output; + const FIPSStatus expect_approved; +} kKDFTestVectors[] = { + {EVP_md5, kTLSOutput_md, FIPSStatus::APPROVED}, + {EVP_sha1, kTLSOutput_sha1, FIPSStatus::APPROVED}, + {EVP_md5_sha1, kTLSOutput_mdsha1, FIPSStatus::APPROVED}, + {EVP_sha224, kTLSOutput_sha224, FIPSStatus::NOT_APPROVED}, + {EVP_sha256, kTLSOutput_sha256, FIPSStatus::APPROVED}, + {EVP_sha384, kTLSOutput_sha384, FIPSStatus::APPROVED}, + {EVP_sha512, kTLSOutput_sha512, FIPSStatus::APPROVED}, +}; + +class KDF_ServiceIndicatorTest : public TestWithNoErrors {}; + +INSTANTIATE_TEST_SUITE_P(All, KDF_ServiceIndicatorTest, + testing::ValuesIn(kKDFTestVectors)); + +TEST_P(KDF_ServiceIndicatorTest, TLSKDF) { + const KDFTestVector &test = GetParam(); + + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + uint8_t output[32]; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CRYPTO_tls1_prf(test.func(), output, sizeof(output), kTLSSecret, + sizeof(kTLSSecret), kTLSLabel, + sizeof(kTLSLabel), kTLSSeed1, sizeof(kTLSSeed1), + kTLSSeed2, sizeof(kTLSSeed2)))); + EXPECT_EQ(Bytes(test.expected_output, sizeof(output)), + Bytes(output, sizeof(output))); + EXPECT_EQ(approved, test.expect_approved); +} + +TEST(ServiceIndicatorTest, CMAC) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::UniquePtr ctx(CMAC_CTX_new()); + ASSERT_TRUE(ctx); + + // Test running the CMAC interfaces one by one directly, and check + // |CMAC_Final| for approval at the end. |CMAC_Init| and |CMAC_Update| + // should not be approved, because the functions do not indicate that a + // service has been fully completed yet. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CMAC_Init(ctx.get(), kAESKey, sizeof(kAESKey), + EVP_aes_128_cbc(), nullptr))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CMAC_Update(ctx.get(), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + uint8_t mac[16]; + size_t out_len; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CMAC_Final(ctx.get(), mac, &out_len))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + EXPECT_EQ(Bytes(kAESCMACOutput), Bytes(mac)); + + // Test using the one-shot API for approval. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_CMAC(mac, kAESKey, sizeof(kAESKey), kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(Bytes(kAESCMACOutput), Bytes(mac)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, BasicTest) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + bssl::ScopedEVP_AEAD_CTX aead_ctx; + ASSERT_TRUE(EVP_AEAD_CTX_init(aead_ctx.get(), + EVP_aead_aes_128_gcm_randnonce(), kAESKey, + sizeof(kAESKey), 0, nullptr)); + // This test ensures that the counter gets incremented once, i.e. it was + // locked through the internal calls. + const int counter_before = FIPS_service_indicator_after_call(); + size_t out_len; + uint8_t output[256]; + EVP_AEAD_CTX_seal(aead_ctx.get(), output, &out_len, sizeof(output), nullptr, + 0, kPlaintext, sizeof(kPlaintext), nullptr, 0); + const int counter_after = FIPS_service_indicator_after_call(); + EXPECT_EQ(counter_after, counter_before + 1); + + // Call an approved service. + CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_AEAD_CTX_seal(aead_ctx.get(), output, &out_len, + sizeof(output), nullptr, 0, kPlaintext, + sizeof(kPlaintext), nullptr, 0)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // Fail an approved service on purpose. + ASSERT_FALSE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_AEAD_CTX_seal(aead_ctx.get(), output, &out_len, 0, nullptr, 0, + kPlaintext, sizeof(kPlaintext), nullptr, 0))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + // Call a non-approved service. + uint8_t aes_iv[sizeof(kAESIV)]; + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + AES_KEY aes_key; + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + int num = 0; + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ofb128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, &num)); + EXPECT_EQ(Bytes(kAESOFBCiphertext), Bytes(output, sizeof(kAESOFBCiphertext))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); +} + +// Test the SHA interfaces one by one and check that only |*_Final| does the +// approval at the end. +TEST(ServiceIndicatorTest, SHA) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + std::vector digest; + + digest.resize(MD4_DIGEST_LENGTH); + MD4_CTX md4_ctx; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED(approved, MD4_Init(&md4_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, MD4_Update(&md4_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, MD4_Final(digest.data(), &md4_ctx))); + EXPECT_EQ(Bytes(kOutput_md4), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + digest.resize(MD5_DIGEST_LENGTH); + MD5_CTX md5_ctx; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED(approved, MD5_Init(&md5_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, MD5_Update(&md5_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, MD5_Final(digest.data(), &md5_ctx))); + EXPECT_EQ(Bytes(kOutput_md5), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + digest.resize(SHA_DIGEST_LENGTH); + SHA_CTX sha_ctx; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED(approved, SHA1_Init(&sha_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA1_Update(&sha_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA1_Final(digest.data(), &sha_ctx))); + EXPECT_EQ(Bytes(kOutput_sha1), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + digest.resize(SHA224_DIGEST_LENGTH); + SHA256_CTX sha224_ctx; + ASSERT_TRUE( + CALL_SERVICE_AND_CHECK_APPROVED(approved, SHA224_Init(&sha224_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA224_Update(&sha224_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA224_Final(digest.data(), &sha224_ctx))); + EXPECT_EQ(Bytes(kOutput_sha224), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + digest.resize(SHA256_DIGEST_LENGTH); + SHA256_CTX sha256_ctx; + ASSERT_TRUE( + CALL_SERVICE_AND_CHECK_APPROVED(approved, SHA256_Init(&sha256_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA256_Update(&sha256_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA256_Final(digest.data(), &sha256_ctx))); + EXPECT_EQ(Bytes(kOutput_sha256), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + digest.resize(SHA384_DIGEST_LENGTH); + SHA512_CTX sha384_ctx; + ASSERT_TRUE( + CALL_SERVICE_AND_CHECK_APPROVED(approved, SHA384_Init(&sha384_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA384_Update(&sha384_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA384_Final(digest.data(), &sha384_ctx))); + EXPECT_EQ(Bytes(kOutput_sha384), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + digest.resize(SHA512_DIGEST_LENGTH); + SHA512_CTX sha512_ctx; + ASSERT_TRUE( + CALL_SERVICE_AND_CHECK_APPROVED(approved, SHA512_Init(&sha512_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA512_Update(&sha512_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA512_Final(digest.data(), &sha512_ctx))); + EXPECT_EQ(Bytes(kOutput_sha512), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + digest.resize(SHA512_256_DIGEST_LENGTH); + SHA512_CTX sha512_256_ctx; + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA512_256_Init(&sha512_256_ctx))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + SHA512_256_Update(&sha512_256_ctx, kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, SHA512_256_Final(digest.data(), &sha512_256_ctx))); + EXPECT_EQ(Bytes(kOutput_sha512_256), Bytes(digest)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, AESECB) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t output[256]; + + // AES-ECB Encryption KAT for 128 bit key. + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + // AES_ecb_encrypt encrypts (or decrypts) a single, 16 byte block from in to + // out. + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kPlaintext[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_ENCRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kAESECBCiphertext), Bytes(output, sizeof(kAESECBCiphertext))); + + // AES-ECB Decryption KAT for 128 bit key. + ASSERT_TRUE(AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kAESECBCiphertext[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_DECRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kPlaintext), Bytes(output, sizeof(kPlaintext))); + + // AES-ECB Encryption KAT for 192 bit key. + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_192, 8 * sizeof(kAESKey_192), &aes_key) == 0); + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kPlaintext[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_ENCRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kAESECBCiphertext_192), + Bytes(output, sizeof(kAESECBCiphertext_192))); + + // AES-ECB Decryption KAT for 192 bit key. + ASSERT_TRUE( + AES_set_decrypt_key(kAESKey_192, 8 * sizeof(kAESKey_192), &aes_key) == 0); + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kAESECBCiphertext_192[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_DECRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kPlaintext), Bytes(output, sizeof(kPlaintext))); + + // AES-ECB Encryption KAT for 256 bit key. + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_256, 8 * sizeof(kAESKey_256), &aes_key) == 0); + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kPlaintext[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_ENCRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kAESECBCiphertext_256), + Bytes(output, sizeof(kAESECBCiphertext_256))); + + // AES-ECB Decryption KAT for 256 bit key. + ASSERT_TRUE( + AES_set_decrypt_key(kAESKey_256, 8 * sizeof(kAESKey_256), &aes_key) == 0); + for (size_t i = 0; i < sizeof(kPlaintext) / AES_BLOCK_SIZE; i++) { + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ecb_encrypt(&kAESECBCiphertext_256[i * AES_BLOCK_SIZE], + &output[i * AES_BLOCK_SIZE], &aes_key, AES_DECRYPT)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + } + EXPECT_EQ(Bytes(kPlaintext), Bytes(output, sizeof(kPlaintext))); +} + +TEST(ServiceIndicatorTest, AESCBC) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t aes_iv[sizeof(kAESIV)]; + uint8_t output[sizeof(kPlaintext)]; + + // AES-CBC Encryption KAT for 128 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, AES_ENCRYPT)); + EXPECT_EQ(Bytes(kAESCBCCiphertext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CBC Decryption KAT for 128 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE(AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + &aes_key, aes_iv, AES_DECRYPT)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CBC Encryption KAT for 192 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_192, 8 * sizeof(kAESKey_192), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, AES_ENCRYPT)); + EXPECT_EQ(Bytes(kAESCBCCiphertext_192), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CBC Decryption KAT for 192 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_decrypt_key(kAESKey_192, 8 * sizeof(kAESKey_192), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cbc_encrypt(kAESCBCCiphertext_192, output, + sizeof(kAESCBCCiphertext_192), &aes_key, aes_iv, + AES_DECRYPT)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CBC Encryption KAT for 256 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_256, 8 * sizeof(kAESKey_256), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, AES_ENCRYPT)); + EXPECT_EQ(Bytes(kAESCBCCiphertext_256), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CBC Decryption KAT for 256 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_decrypt_key(kAESKey_256, 8 * sizeof(kAESKey_256), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cbc_encrypt(kAESCBCCiphertext_256, output, + sizeof(kAESCBCCiphertext_256), &aes_key, aes_iv, + AES_DECRYPT)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, AESCTR) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t aes_iv[sizeof(kAESIV)]; + uint8_t output[sizeof(kPlaintext)]; + unsigned num = 0; + uint8_t ecount_buf[AES_BLOCK_SIZE]; + + // AES-CTR Encryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ctr128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kAESCTRCiphertext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CTR Decryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ctr128_encrypt(kAESCTRCiphertext, output, sizeof(kAESCTRCiphertext), + &aes_key, aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CTR Encryption KAT for 192 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_192, 8 * sizeof(kAESKey_192), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ctr128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kAESCTRCiphertext_192), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CTR Decryption KAT for 192 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ctr128_encrypt(kAESCTRCiphertext_192, output, + sizeof(kAESCTRCiphertext_192), &aes_key, + aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CTR Encryption KAT for 256 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE( + AES_set_encrypt_key(kAESKey_256, 8 * sizeof(kAESKey_256), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ctr128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kAESCTRCiphertext_256), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-CTR Decryption KAT for 256 bit key. + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ctr128_encrypt(kAESCTRCiphertext_256, output, + sizeof(kAESCTRCiphertext_256), &aes_key, + aes_iv, ecount_buf, &num)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, AESOFB) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t aes_iv[sizeof(kAESIV)]; + uint8_t output[sizeof(kPlaintext)]; + int num = 0; + + // AES-OFB Encryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_ofb128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, &num)); + EXPECT_EQ(Bytes(kAESOFBCiphertext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + // AES-OFB Decryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_ofb128_encrypt(kAESOFBCiphertext, output, sizeof(kAESOFBCiphertext), + &aes_key, aes_iv, &num)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); +} + +TEST(ServiceIndicatorTest, AESCFB) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t aes_iv[sizeof(kAESIV)]; + uint8_t output[sizeof(kPlaintext)]; + int num = 0; + + // AES-CFB Encryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_cfb128_encrypt(kPlaintext, output, sizeof(kPlaintext), + &aes_key, aes_iv, &num, AES_ENCRYPT)); + EXPECT_EQ(Bytes(kAESCFBCiphertext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + + // AES-CFB Decryption KAT + memcpy(aes_iv, kAESIV, sizeof(aes_iv)); + CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_cfb128_encrypt(kAESCFBCiphertext, output, sizeof(kAESCFBCiphertext), + &aes_key, aes_iv, &num, AES_DECRYPT)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); +} + +TEST(ServiceIndicatorTest, AESKW) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t output[sizeof(kPlaintext) + 8]; + size_t outlen; + + // AES-KW Encryption KAT + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + outlen = CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_wrap_key(&aes_key, nullptr, output, kPlaintext, sizeof(kPlaintext))); + ASSERT_EQ(outlen, sizeof(kAESKWCiphertext)); + EXPECT_EQ(Bytes(kAESKWCiphertext), Bytes(output)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-KW Decryption KAT + ASSERT_TRUE(AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + outlen = CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_unwrap_key(&aes_key, nullptr, output, kAESKWCiphertext, + sizeof(kAESKWCiphertext))); + ASSERT_EQ(outlen, sizeof(kPlaintext)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output, sizeof(kPlaintext))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, AESKWP) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + AES_KEY aes_key; + uint8_t output[sizeof(kPlaintext) + 15]; + size_t outlen; + + // AES-KWP Encryption KAT + ASSERT_TRUE(AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, AES_wrap_key_padded(&aes_key, output, &outlen, sizeof(output), + kPlaintext, sizeof(kPlaintext)))); + EXPECT_EQ(Bytes(kAESKWPCiphertext), Bytes(output, outlen)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // AES-KWP Decryption KAT + ASSERT_TRUE(AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) == 0); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + AES_unwrap_key_padded(&aes_key, output, &outlen, sizeof(output), + kAESKWPCiphertext, sizeof(kAESKWPCiphertext)))); + EXPECT_EQ(Bytes(kPlaintext), Bytes(output, outlen)); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +TEST(ServiceIndicatorTest, FFDH) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + + // |DH_compute_key_padded| should be a non-approved service. + bssl::UniquePtr dh(GetDH()); + uint8_t dh_out[sizeof(kDHOutput)]; + ASSERT_EQ(DH_size(dh.get()), static_cast(sizeof(dh_out))); + ASSERT_EQ(CALL_SERVICE_AND_CHECK_APPROVED( + approved, DH_compute_key_padded( + dh_out, DH_get0_priv_key(dh.get()), dh.get())), + static_cast(sizeof(dh_out))); + EXPECT_EQ(Bytes(kDHOutput), Bytes(dh_out)); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); +} + +TEST(ServiceIndicatorTest, DRBG) { + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + CTR_DRBG_STATE drbg; + uint8_t output[sizeof(kDRBGOutput)]; + + // Test running the DRBG interfaces and check |CTR_DRBG_generate| for approval + // at the end since it indicates a service is being done. |CTR_DRBG_init| and + // |CTR_DRBG_reseed| should not be approved, because the functions do not + // indicate that a service has been fully completed yet. + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + sizeof(kDRBGPersonalization)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, + sizeof(kDRBGAD)))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + EXPECT_EQ(Bytes(kDRBGOutput), Bytes(output)); + + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)))); + EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), + kDRBGAD, sizeof(kDRBGAD)))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); + EXPECT_EQ(Bytes(kDRBGReseedOutput), Bytes(output)); + + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, RAND_bytes(output, sizeof(output)))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +#else // !BORINGSSL_FIPS + +// Service indicator calls should not be used in non-FIPS builds. However, if +// used, the macro |CALL_SERVICE_AND_CHECK_APPROVED| will return +// |FIPSStatus::APPROVED|, but the direct calls to +// |FIPS_service_indicator_xxx| will not indicate an approved state. +TEST(ServiceIndicatorTest, BasicTest) { + // Reset and check the initial state and counter. + FIPSStatus approved = FIPSStatus::NOT_APPROVED; + uint64_t before = FIPS_service_indicator_before_call(); + ASSERT_EQ(before, (uint64_t)0); + + // Call an approved service. + bssl::ScopedEVP_AEAD_CTX aead_ctx; + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH] = {0}; + uint8_t output[256]; + size_t out_len; + ASSERT_TRUE(EVP_AEAD_CTX_init(aead_ctx.get(), + EVP_aead_aes_128_gcm_randnonce(), kAESKey, + sizeof(kAESKey), 0, nullptr)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, EVP_AEAD_CTX_seal(aead_ctx.get(), output, &out_len, + sizeof(output), nullptr, 0, kPlaintext, + sizeof(kPlaintext), nullptr, 0))); + // Macro should return true, to ensure FIPS/non-FIPS compatibility. + EXPECT_EQ(approved, FIPSStatus::APPROVED); + + // Call a non-approved service. + ASSERT_TRUE(EVP_AEAD_CTX_init(aead_ctx.get(), EVP_aead_aes_128_gcm(), kAESKey, + sizeof(kAESKey), 0, nullptr)); + ASSERT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( + approved, + EVP_AEAD_CTX_seal(aead_ctx.get(), output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kPlaintext, sizeof(kPlaintext), nullptr, 0))); + EXPECT_EQ(approved, FIPSStatus::APPROVED); +} + +#endif // BORINGSSL_FIPS diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-armv8.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-armv8.pl index 25e52346..856b819b 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-armv8.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-armv8.pl @@ -61,7 +61,7 @@ $code.=<<___ if ($i<14 && !($i&1)); ldr @Xx[$i+2],[$inp,#`($i+2)*4-64`] ___ $code.=<<___ if ($i<14 && ($i&1)); -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror @Xx[$i+1],@Xx[$i+1],#32 #else rev32 @Xx[$i+1],@Xx[$i+1] @@ -209,7 +209,7 @@ sha1_block_data_order: movz $K,#0x7999 sub $num,$num,#1 movk $K,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror $Xx[0],@Xx[0],#32 #else rev32 @Xx[0],@Xx[0] diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl index 51260253..d9afacbd 100755 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha1-x86_64.pl @@ -389,6 +389,7 @@ $code.=<<___; lea 0x40($inp),%r8 # next input block paddd @MSG[0],$E cmovne %r8,$inp + prefetcht0 512($inp) movdqa $ABCD,$ABCD_SAVE # offload $ABCD ___ for($i=0;$i<20-4;$i+=2) { @@ -1815,6 +1816,7 @@ ___ } } $code.=<<___; +.section .rodata .align 64 K_XX_XX: .long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 # K_00_19 @@ -1833,6 +1835,7 @@ ___ $code.=<<___; .asciz "SHA1 block transform for x86_64, CRYPTOGAMS by " .align 64 +.text ___ # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-armv8.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-armv8.pl index ae803a9a..8cb312fa 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-armv8.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -27,6 +27,7 @@ # Denver 2.01 10.5 (+26%) 6.70 (+8%) # X-Gene 20.0 (+100%) 12.8 (+300%(***)) # Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +# Kryo 1.92 17.4 (+30%) 11.2 (+8%) # # (*) Software SHA256 results are of lesser relevance, presented # mostly for informational purposes. @@ -35,7 +36,7 @@ # on Cortex-A53 (or by 4 cycles per round). # (***) Super-impressive coefficients over gcc-generated code are # indication of some compiler "pathology", most notably code -# generated with -mgeneral-regs-only is significanty faster +# generated with -mgeneral-regs-only is significantly faster # and the gap is only 40-90%. $output=pop; @@ -89,7 +90,7 @@ my ($T0,$T1,$T2)=(@X[($i-8)&15],@X[($i-9)&15],@X[($i-10)&15]); $T0=@X[$i+3] if ($i<11); $code.=<<___ if ($i<16); -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev @X[$i],@X[$i] // $i #endif ___ @@ -184,8 +185,6 @@ $code.=<<___; .type $func,%function .align 6 $func: -___ -$code.=<<___ if ($SZ==4); AARCH64_VALID_CALL_TARGET #ifndef __KERNEL__ #if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 @@ -194,11 +193,17 @@ $code.=<<___ if ($SZ==4); adrp x16,:pg_hi21:OPENSSL_armcap_P #endif ldr w16,[x16,:lo12:OPENSSL_armcap_P] +___ +$code.=<<___ if ($SZ==4); tst w16,#ARMV8_SHA256 b.ne .Lv8_entry -#endif +___ +$code.=<<___ if ($SZ==8); + tst w16,#ARMV8_SHA512 + b.ne .Lv8_entry ___ $code.=<<___; +#endif AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -424,6 +429,110 @@ $code.=<<___; ___ } +if ($SZ==8) { +my $Ktbl="x3"; + +my @H = map("v$_.16b",(0..4)); +my ($fg,$de,$m9_10)=map("v$_.16b",(5..7)); +my @MSG=map("v$_.16b",(16..23)); +my ($W0,$W1)=("v24.2d","v25.2d"); +my ($AB,$CD,$EF,$GH)=map("v$_.16b",(26..29)); + +$code.=<<___; +.text +#ifndef __KERNEL__ +.type sha512_block_armv8,%function +.align 6 +sha512_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {@MSG[0]-@MSG[3]},[$inp],#64 // load input + ld1 {@MSG[4]-@MSG[7]},[$inp],#64 + + ld1.64 {@H[0]-@H[3]},[$ctx] // load context + adrp $Ktbl,:pg_hi21:.LK512 + add $Ktbl,$Ktbl,:lo12:.LK512 + + rev64 @MSG[0],@MSG[0] + rev64 @MSG[1],@MSG[1] + rev64 @MSG[2],@MSG[2] + rev64 @MSG[3],@MSG[3] + rev64 @MSG[4],@MSG[4] + rev64 @MSG[5],@MSG[5] + rev64 @MSG[6],@MSG[6] + rev64 @MSG[7],@MSG[7] + b .Loop_hw + +.align 4 +.Loop_hw: + ld1.64 {$W0},[$Ktbl],#16 + subs $num,$num,#1 + sub x4,$inp,#128 + orr $AB,@H[0],@H[0] // offload + orr $CD,@H[1],@H[1] + orr $EF,@H[2],@H[2] + orr $GH,@H[3],@H[3] + csel $inp,$inp,x4,ne // conditional rewind +___ +for($i=0;$i<32;$i++) { +$code.=<<___; + add.i64 $W0,$W0,@MSG[0] + ld1.64 {$W1},[$Ktbl],#16 + ext $W0,$W0,$W0,#8 + ext $fg,@H[2],@H[3],#8 + ext $de,@H[1],@H[2],#8 + add.i64 @H[3],@H[3],$W0 // "T1 + H + K512[i]" + sha512su0 @MSG[0],@MSG[1] + ext $m9_10,@MSG[4],@MSG[5],#8 + sha512h @H[3],$fg,$de + sha512su1 @MSG[0],@MSG[7],$m9_10 + add.i64 @H[4],@H[1],@H[3] // "D + T1" + sha512h2 @H[3],$H[1],@H[0] +___ + ($W0,$W1)=($W1,$W0); push(@MSG,shift(@MSG)); + @H = (@H[3],@H[0],@H[4],@H[2],@H[1]); +} +for(;$i<40;$i++) { +$code.=<<___ if ($i<39); + ld1.64 {$W1},[$Ktbl],#16 +___ +$code.=<<___ if ($i==39); + sub $Ktbl,$Ktbl,#$rounds*$SZ // rewind +___ +$code.=<<___; + add.i64 $W0,$W0,@MSG[0] + ld1 {@MSG[0]},[$inp],#16 // load next input + ext $W0,$W0,$W0,#8 + ext $fg,@H[2],@H[3],#8 + ext $de,@H[1],@H[2],#8 + add.i64 @H[3],@H[3],$W0 // "T1 + H + K512[i]" + sha512h @H[3],$fg,$de + rev64 @MSG[0],@MSG[0] + add.i64 @H[4],@H[1],@H[3] // "D + T1" + sha512h2 @H[3],$H[1],@H[0] +___ + ($W0,$W1)=($W1,$W0); push(@MSG,shift(@MSG)); + @H = (@H[3],@H[0],@H[4],@H[2],@H[1]); +} +$code.=<<___; + add.i64 @H[0],@H[0],$AB // accumulate + add.i64 @H[1],@H[1],$CD + add.i64 @H[2],@H[2],$EF + add.i64 @H[3],@H[3],$GH + + cbnz $num,.Loop_hw + + st1.64 {@H[0]-@H[3]},[$ctx] // store context + + ldr x29,[sp],#16 + ret +.size sha512_block_armv8,.-sha512_block_armv8 +#endif +___ +} + { my %opcode = ( "sha256h" => 0x5e004000, "sha256h2" => 0x5e005000, "sha256su0" => 0x5e282800, "sha256su1" => 0x5e006000 ); @@ -439,6 +548,21 @@ ___ } } +{ my %opcode = ( + "sha512h" => 0xce608000, "sha512h2" => 0xce608400, + "sha512su0" => 0xcec08000, "sha512su1" => 0xce608800 ); + + sub unsha512 { + my ($mnemonic,$arg)=@_; + + $arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o + && + sprintf ".inst\t0x%08x\t//%s %s", + $opcode{$mnemonic}|$1|($2<<5)|($3<<16), + $mnemonic,$arg; + } +} + open SELF,$0; while() { next if (/^#!/); @@ -449,12 +573,18 @@ close SELF; foreach(split("\n",$code)) { - s/\`([^\`]*)\`/eval($1)/geo; + s/\`([^\`]*)\`/eval($1)/ge; - s/\b(sha256\w+)\s+([qv].*)/unsha256($1,$2)/geo; + s/\b(sha512\w+)\s+([qv].*)/unsha512($1,$2)/ge or + s/\b(sha256\w+)\s+([qv].*)/unsha256($1,$2)/ge; - s/\.\w?32\b//o and s/\.16b/\.4s/go; - m/(ld|st)1[^\[]+\[0\]/o and s/\.4s/\.s/go; + s/\bq([0-9]+)\b/v$1.16b/g; # old->new registers + + s/\.[ui]?8(\s)/$1/; + s/\.\w?64\b// and s/\.16b/\.2d/g or + s/\.\w?32\b// and s/\.16b/\.4s/g; + m/\bext\b/ and s/\.2d/\.16b/g or + m/(ld|st)1[^\[]+\[0\]/ and s/\.4s/\.s/g; print $_,"\n"; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl index 61f67cb6..e831ae5c 100755 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/asm/sha512-x86_64.pl @@ -126,15 +126,12 @@ die "can't locate x86_64-xlate.pl"; # versions, but BoringSSL is intended to be used with pre-generated perlasm # output, so this isn't useful anyway. # -# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it -# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream -# did not tie them together until after $shaext was added. +# This file also has an AVX2 implementation, controlled by setting $avx to 2. +# For now, we intentionally disable it. While it gives a 13-16% perf boost, the +# CFI annotations are wrong. It allocates stack in a loop and should be +# rewritten to avoid this. $avx = 1; - -# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's -# been tested. -$shaext=0; ### set to zero if compiling for 1.0.1 -$avx=1 if (!$shaext && $avx); +$shaext = 1; open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; *STDOUT=*OUT; @@ -275,7 +272,7 @@ $code.=<<___ if ($SZ==4 || $avx); ___ $code.=<<___ if ($SZ==4 && $shaext); test \$`1<<29`,%r11d # check for SHA - jnz _shaext_shortcut + jnz .Lshaext_shortcut ___ # XOP codepath removed. $code.=<<___ if ($avx>1); @@ -407,6 +404,7 @@ ___ if ($SZ==4) { $code.=<<___; +.section .rodata .align 64 .type $TABLE,\@object $TABLE: @@ -450,9 +448,11 @@ $TABLE: .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .long 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 .asciz "SHA256 block transform for x86_64, CRYPTOGAMS by " +.text ___ } else { $code.=<<___; +.section .rodata .align 64 .type $TABLE,\@object $TABLE: @@ -540,6 +540,7 @@ $TABLE: .quad 0x0001020304050607,0x08090a0b0c0d0e0f .quad 0x0001020304050607,0x08090a0b0c0d0e0f .asciz "SHA512 block transform for x86_64, CRYPTOGAMS by " +.text ___ } @@ -559,7 +560,8 @@ $code.=<<___; .type sha256_block_data_order_shaext,\@function,3 .align 64 sha256_block_data_order_shaext: -_shaext_shortcut: +.cfi_startproc +.Lshaext_shortcut: ___ $code.=<<___ if ($win64); lea `-8-5*16`(%rsp),%rsp @@ -703,6 +705,7 @@ $code.=<<___ if ($win64); ___ $code.=<<___; ret +.cfi_endproc .size sha256_block_data_order_shaext,.-sha256_block_data_order_shaext ___ }}} diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/internal.h index cc909149..605f1665 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/internal.h @@ -22,23 +22,14 @@ extern "C" { #endif -#if defined(OPENSSL_PPC64LE) || \ - (!defined(OPENSSL_NO_ASM) && \ - (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ - defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) -// POWER has an intrinsics-based implementation of SHA-1 and thus the functions -// normally defined in assembly are available even with |OPENSSL_NO_ASM| in -// this case. -#define SHA1_ASM -void sha1_block_data_order(uint32_t *state, const uint8_t *in, - size_t num_blocks); -#endif - #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA1_ASM #define SHA256_ASM #define SHA512_ASM +void sha1_block_data_order(uint32_t *state, const uint8_t *in, + size_t num_blocks); void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num_blocks); void sha512_block_data_order(uint64_t *state, const uint8_t *in, diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1-altivec.c b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1-altivec.c deleted file mode 100644 index 3152827a..00000000 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1-altivec.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -// Altivec-optimized SHA1 in C. This is tested on ppc64le only. -// -// References: -// https://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1 -// http://arctic.org/~dean/crypto/sha1.html -// -// This code used the generic SHA-1 from OpenSSL as a basis and AltiVec -// optimisations were added on top. - -#include - -#if defined(OPENSSL_PPC64LE) - -#include - -void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); - -static uint32_t rotate(uint32_t a, int n) { return (a << n) | (a >> (32 - n)); } - -typedef vector unsigned int vec_uint32_t; -typedef vector unsigned char vec_uint8_t; - -// Vector constants -static const vec_uint8_t k_swap_endianness = {3, 2, 1, 0, 7, 6, 5, 4, - 11, 10, 9, 8, 15, 14, 13, 12}; - -// Shift amounts for byte and bit shifts and rotations -static const vec_uint8_t k_4_bytes = {32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32}; -static const vec_uint8_t k_12_bytes = {96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96}; - -#define K_00_19 0x5a827999UL -#define K_20_39 0x6ed9eba1UL -#define K_40_59 0x8f1bbcdcUL -#define K_60_79 0xca62c1d6UL - -// Vector versions of the above. -static const vec_uint32_t K_00_19_x_4 = {K_00_19, K_00_19, K_00_19, K_00_19}; -static const vec_uint32_t K_20_39_x_4 = {K_20_39, K_20_39, K_20_39, K_20_39}; -static const vec_uint32_t K_40_59_x_4 = {K_40_59, K_40_59, K_40_59, K_40_59}; -static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; - -// vector message scheduling: compute message schedule for round i..i+3 where i -// is divisible by 4. We return the schedule w[i..i+3] as a vector. In -// addition, we also precompute sum w[i..+3] and an additive constant K. This -// is done to offload some computation of f() in the integer execution units. -// -// Byte shifting code below may not be correct for big-endian systems. -static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, - vec_uint32_t k) { - const vector unsigned char unaligned_data = - vec_vsx_ld(0, (const unsigned char*) data); - const vec_uint32_t v = (vec_uint32_t) unaligned_data; - const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); - vec_st(w + k, 0, pre_added); - return w; -} - -// Compute w[i..i+3] using these steps for i in [16, 20, 24, 28] -// -// w'[i ] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) <<< 1 -// w'[i+1] = (w[i-2] ^ w[i-7] ^ w[i-13] ^ w[i-15]) <<< 1 -// w'[i+2] = (w[i-1] ^ w[i-6] ^ w[i-12] ^ w[i-14]) <<< 1 -// w'[i+3] = ( 0 ^ w[i-5] ^ w[i-11] ^ w[i-13]) <<< 1 -// -// w[ i] = w'[ i] -// w[i+1] = w'[i+1] -// w[i+2] = w'[i+2] -// w[i+3] = w'[i+3] ^ (w'[i] <<< 1) -static vec_uint32_t sched_16_31(vec_uint32_t *pre_added, vec_uint32_t minus_4, - vec_uint32_t minus_8, vec_uint32_t minus_12, - vec_uint32_t minus_16, vec_uint32_t k) { - const vec_uint32_t minus_3 = vec_sro(minus_4, k_4_bytes); - const vec_uint32_t minus_14 = vec_sld((minus_12), (minus_16), 8); - const vec_uint32_t k_1_bit = vec_splat_u32(1); - const vec_uint32_t w_prime = - vec_rl(minus_3 ^ minus_8 ^ minus_14 ^ minus_16, k_1_bit); - const vec_uint32_t w = - w_prime ^ vec_rl(vec_slo(w_prime, k_12_bytes), k_1_bit); - vec_st(w + k, 0, pre_added); - return w; -} - -// Compute w[i..i+3] using this relation for i in [32, 36, 40 ... 76] -// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]), 2) <<< 2 -static vec_uint32_t sched_32_79(vec_uint32_t *pre_added, vec_uint32_t minus_4, - vec_uint32_t minus_8, vec_uint32_t minus_16, - vec_uint32_t minus_28, vec_uint32_t minus_32, - vec_uint32_t k) { - const vec_uint32_t minus_6 = vec_sld(minus_4, minus_8, 8); - const vec_uint32_t k_2_bits = vec_splat_u32(2); - const vec_uint32_t w = - vec_rl(minus_6 ^ minus_16 ^ minus_28 ^ minus_32, k_2_bits); - vec_st(w + k, 0, pre_added); - return w; -} - -// As pointed out by Wei Dai , F() below can be simplified -// to the code in F_00_19. Wei attributes these optimisations to Peter -// Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define -// F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another -// tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a -#define F_00_19(b, c, d) ((((c) ^ (d)) & (b)) ^ (d)) -#define F_20_39(b, c, d) ((b) ^ (c) ^ (d)) -#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d))) -#define F_60_79(b, c, d) F_20_39(b, c, d) - -// We pre-added the K constants during message scheduling. -#define BODY_00_19(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_00_19((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_20_39(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_20_39((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_40_59(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_40_59((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -#define BODY_60_79(i, a, b, c, d, e, f) \ - do { \ - (f) = w[i] + (e) + rotate((a), 5) + F_60_79((b), (c), (d)); \ - (b) = rotate((b), 30); \ - } while (0) - -void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { - uint32_t A, B, C, D, E, T; - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - - for (;;) { - vec_uint32_t vw[20]; - const uint32_t *w = (const uint32_t *)&vw; - - vec_uint32_t k = K_00_19_x_4; - const vec_uint32_t w0 = sched_00_15(vw + 0, data + 0, k); - BODY_00_19(0, A, B, C, D, E, T); - BODY_00_19(1, T, A, B, C, D, E); - BODY_00_19(2, E, T, A, B, C, D); - BODY_00_19(3, D, E, T, A, B, C); - - const vec_uint32_t w4 = sched_00_15(vw + 1, data + 16, k); - BODY_00_19(4, C, D, E, T, A, B); - BODY_00_19(5, B, C, D, E, T, A); - BODY_00_19(6, A, B, C, D, E, T); - BODY_00_19(7, T, A, B, C, D, E); - - const vec_uint32_t w8 = sched_00_15(vw + 2, data + 32, k); - BODY_00_19(8, E, T, A, B, C, D); - BODY_00_19(9, D, E, T, A, B, C); - BODY_00_19(10, C, D, E, T, A, B); - BODY_00_19(11, B, C, D, E, T, A); - - const vec_uint32_t w12 = sched_00_15(vw + 3, data + 48, k); - BODY_00_19(12, A, B, C, D, E, T); - BODY_00_19(13, T, A, B, C, D, E); - BODY_00_19(14, E, T, A, B, C, D); - BODY_00_19(15, D, E, T, A, B, C); - - const vec_uint32_t w16 = sched_16_31(vw + 4, w12, w8, w4, w0, k); - BODY_00_19(16, C, D, E, T, A, B); - BODY_00_19(17, B, C, D, E, T, A); - BODY_00_19(18, A, B, C, D, E, T); - BODY_00_19(19, T, A, B, C, D, E); - - k = K_20_39_x_4; - const vec_uint32_t w20 = sched_16_31(vw + 5, w16, w12, w8, w4, k); - BODY_20_39(20, E, T, A, B, C, D); - BODY_20_39(21, D, E, T, A, B, C); - BODY_20_39(22, C, D, E, T, A, B); - BODY_20_39(23, B, C, D, E, T, A); - - const vec_uint32_t w24 = sched_16_31(vw + 6, w20, w16, w12, w8, k); - BODY_20_39(24, A, B, C, D, E, T); - BODY_20_39(25, T, A, B, C, D, E); - BODY_20_39(26, E, T, A, B, C, D); - BODY_20_39(27, D, E, T, A, B, C); - - const vec_uint32_t w28 = sched_16_31(vw + 7, w24, w20, w16, w12, k); - BODY_20_39(28, C, D, E, T, A, B); - BODY_20_39(29, B, C, D, E, T, A); - BODY_20_39(30, A, B, C, D, E, T); - BODY_20_39(31, T, A, B, C, D, E); - - const vec_uint32_t w32 = sched_32_79(vw + 8, w28, w24, w16, w4, w0, k); - BODY_20_39(32, E, T, A, B, C, D); - BODY_20_39(33, D, E, T, A, B, C); - BODY_20_39(34, C, D, E, T, A, B); - BODY_20_39(35, B, C, D, E, T, A); - - const vec_uint32_t w36 = sched_32_79(vw + 9, w32, w28, w20, w8, w4, k); - BODY_20_39(36, A, B, C, D, E, T); - BODY_20_39(37, T, A, B, C, D, E); - BODY_20_39(38, E, T, A, B, C, D); - BODY_20_39(39, D, E, T, A, B, C); - - k = K_40_59_x_4; - const vec_uint32_t w40 = sched_32_79(vw + 10, w36, w32, w24, w12, w8, k); - BODY_40_59(40, C, D, E, T, A, B); - BODY_40_59(41, B, C, D, E, T, A); - BODY_40_59(42, A, B, C, D, E, T); - BODY_40_59(43, T, A, B, C, D, E); - - const vec_uint32_t w44 = sched_32_79(vw + 11, w40, w36, w28, w16, w12, k); - BODY_40_59(44, E, T, A, B, C, D); - BODY_40_59(45, D, E, T, A, B, C); - BODY_40_59(46, C, D, E, T, A, B); - BODY_40_59(47, B, C, D, E, T, A); - - const vec_uint32_t w48 = sched_32_79(vw + 12, w44, w40, w32, w20, w16, k); - BODY_40_59(48, A, B, C, D, E, T); - BODY_40_59(49, T, A, B, C, D, E); - BODY_40_59(50, E, T, A, B, C, D); - BODY_40_59(51, D, E, T, A, B, C); - - const vec_uint32_t w52 = sched_32_79(vw + 13, w48, w44, w36, w24, w20, k); - BODY_40_59(52, C, D, E, T, A, B); - BODY_40_59(53, B, C, D, E, T, A); - BODY_40_59(54, A, B, C, D, E, T); - BODY_40_59(55, T, A, B, C, D, E); - - const vec_uint32_t w56 = sched_32_79(vw + 14, w52, w48, w40, w28, w24, k); - BODY_40_59(56, E, T, A, B, C, D); - BODY_40_59(57, D, E, T, A, B, C); - BODY_40_59(58, C, D, E, T, A, B); - BODY_40_59(59, B, C, D, E, T, A); - - k = K_60_79_x_4; - const vec_uint32_t w60 = sched_32_79(vw + 15, w56, w52, w44, w32, w28, k); - BODY_60_79(60, A, B, C, D, E, T); - BODY_60_79(61, T, A, B, C, D, E); - BODY_60_79(62, E, T, A, B, C, D); - BODY_60_79(63, D, E, T, A, B, C); - - const vec_uint32_t w64 = sched_32_79(vw + 16, w60, w56, w48, w36, w32, k); - BODY_60_79(64, C, D, E, T, A, B); - BODY_60_79(65, B, C, D, E, T, A); - BODY_60_79(66, A, B, C, D, E, T); - BODY_60_79(67, T, A, B, C, D, E); - - const vec_uint32_t w68 = sched_32_79(vw + 17, w64, w60, w52, w40, w36, k); - BODY_60_79(68, E, T, A, B, C, D); - BODY_60_79(69, D, E, T, A, B, C); - BODY_60_79(70, C, D, E, T, A, B); - BODY_60_79(71, B, C, D, E, T, A); - - const vec_uint32_t w72 = sched_32_79(vw + 18, w68, w64, w56, w44, w40, k); - BODY_60_79(72, A, B, C, D, E, T); - BODY_60_79(73, T, A, B, C, D, E); - BODY_60_79(74, E, T, A, B, C, D); - BODY_60_79(75, D, E, T, A, B, C); - - // We don't use the last value - (void)sched_32_79(vw + 19, w72, w68, w60, w48, w44, k); - BODY_60_79(76, C, D, E, T, A, B); - BODY_60_79(77, B, C, D, E, T, A); - BODY_60_79(78, A, B, C, D, E, T); - BODY_60_79(79, T, A, B, C, D, E); - - const uint32_t mask = 0xffffffffUL; - state[0] = (state[0] + E) & mask; - state[1] = (state[1] + T) & mask; - state[2] = (state[2] + A) & mask; - state[3] = (state[3] + B) & mask; - state[4] = (state[4] + C) & mask; - - data += 64; - if (--num == 0) { - break; - } - - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - } -} - -#endif // OPENSSL_PPC64LE - -#undef K_00_19 -#undef K_20_39 -#undef K_40_59 -#undef K_60_79 -#undef F_00_19 -#undef F_20_39 -#undef F_40_59 -#undef F_60_79 -#undef BODY_00_19 -#undef BODY_20_39 -#undef BODY_40_59 -#undef BODY_60_79 diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1.c b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1.c index e482c776..f921e312 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha1.c @@ -62,6 +62,7 @@ #include "../../internal.h" #include "../digest/md32_common.h" +#include "../service_indicator/internal.h" #include "internal.h" @@ -108,6 +109,7 @@ int SHA1_Final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *c) { CRYPTO_store_u32_be(out + 8, c->h[2]); CRYPTO_store_u32_be(out + 12, c->h[3]); CRYPTO_store_u32_be(out + 16, c->h[4]); + FIPS_service_indicator_update_state(); return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha256.c b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha256.c index c187c4a1..046f6e25 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha256.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha256.c @@ -62,6 +62,7 @@ #include "../../internal.h" #include "../digest/md32_common.h" +#include "../service_indicator/internal.h" #include "internal.h" @@ -132,7 +133,7 @@ int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) { return SHA256_Update(ctx, data, len); } -static int sha256_final_impl(uint8_t *out, SHA256_CTX *c) { +static int sha256_final_impl(uint8_t *out, size_t md_len, SHA256_CTX *c) { crypto_md32_final(&sha256_block_data_order, c->h, c->data, SHA256_CBLOCK, &c->num, c->Nh, c->Nl, /*is_big_endian=*/1); @@ -140,16 +141,18 @@ static int sha256_final_impl(uint8_t *out, SHA256_CTX *c) { // 'final' function can fail. SHA-512 does not have a corresponding check. // These functions already misbehave if the caller arbitrarily mutates |c|, so // can we assume one of |SHA256_Init| or |SHA224_Init| was used? - if (c->md_len > SHA256_DIGEST_LENGTH) { + if (md_len > SHA256_DIGEST_LENGTH) { return 0; } - assert(c->md_len % 4 == 0); - const size_t out_words = c->md_len / 4; + assert(md_len % 4 == 0); + const size_t out_words = md_len / 4; for (size_t i = 0; i < out_words; i++) { CRYPTO_store_u32_be(out, c->h[i]); out += 4; } + + FIPS_service_indicator_update_state(); return 1; } @@ -159,13 +162,14 @@ int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], SHA256_CTX *c) { // |SHA256_Final| and expects |sha->md_len| to carry the size over. // // TODO(davidben): Add an assert and fix code to match them up. - return sha256_final_impl(out, c); + return sha256_final_impl(out, c->md_len, c); } + int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], SHA256_CTX *ctx) { - // SHA224_Init sets |ctx->md_len| to |SHA224_DIGEST_LENGTH|, so this has a - // smaller output. + // This function must be paired with |SHA224_Init|, which sets |ctx->md_len| + // to |SHA224_DIGEST_LENGTH|. assert(ctx->md_len == SHA224_DIGEST_LENGTH); - return sha256_final_impl(out, ctx); + return sha256_final_impl(out, SHA224_DIGEST_LENGTH, ctx); } #ifndef SHA256_ASM diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha512.c b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha512.c index d94de284..2c7ce314 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha512.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/sha/sha512.c @@ -60,8 +60,9 @@ #include -#include "internal.h" #include "../../internal.h" +#include "../service_indicator/internal.h" +#include "internal.h" // The 32-bit hash algorithms share a common byte-order neutral collector and @@ -70,7 +71,7 @@ // this writing, so there is no need for a common collector/padding // implementation yet. -static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha); +static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha); int SHA384_Init(SHA512_CTX *sha) { sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); @@ -161,10 +162,10 @@ static void sha512_block_data_order(uint64_t *state, const uint8_t *in, int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], SHA512_CTX *sha) { - // |SHA384_Init| sets |sha->md_len| to |SHA384_DIGEST_LENGTH|, so this has a - // smaller output. + // This function must be paired with |SHA384_Init|, which sets |sha->md_len| + // to |SHA384_DIGEST_LENGTH|. assert(sha->md_len == SHA384_DIGEST_LENGTH); - return sha512_final_impl(out, sha); + return sha512_final_impl(out, SHA384_DIGEST_LENGTH, sha); } int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { @@ -176,10 +177,10 @@ int SHA512_256_Update(SHA512_CTX *sha, const void *data, size_t len) { } int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], SHA512_CTX *sha) { - // |SHA512_256_Init| sets |sha->md_len| to |SHA512_256_DIGEST_LENGTH|, so this - // has a |smaller output. + // This function must be paired with |SHA512_256_Init|, which sets + // |sha->md_len| to |SHA512_256_DIGEST_LENGTH|. assert(sha->md_len == SHA512_256_DIGEST_LENGTH); - return sha512_final_impl(out, sha); + return sha512_final_impl(out, SHA512_256_DIGEST_LENGTH, sha); } void SHA512_Transform(SHA512_CTX *c, const uint8_t block[SHA512_CBLOCK]) { @@ -240,10 +241,10 @@ int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], SHA512_CTX *sha) { // |SHA512_Final| and expects |sha->md_len| to carry the size over. // // TODO(davidben): Add an assert and fix code to match them up. - return sha512_final_impl(out, sha); + return sha512_final_impl(out, sha->md_len, sha); } -static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha) { +static int sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { uint8_t *p = sha->p; size_t n = sha->num; @@ -267,13 +268,14 @@ static int sha512_final_impl(uint8_t *out, SHA512_CTX *sha) { return 0; } - assert(sha->md_len % 8 == 0); - const size_t out_words = sha->md_len / 8; + assert(md_len % 8 == 0); + const size_t out_words = md_len / 8; for (size_t i = 0; i < out_words; i++) { CRYPTO_store_u64_be(out, sha->h[i]); out += 8; } + FIPS_service_indicator_update_state(); return 1; } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/tls/internal.h b/third_party/boringssl/kit/src/crypto/fipsmodule/tls/internal.h index ef642a6c..535b7ebe 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/tls/internal.h +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/tls/internal.h @@ -31,6 +31,14 @@ OPENSSL_EXPORT int CRYPTO_tls1_prf(const EVP_MD *digest, const uint8_t *seed1, size_t seed1_len, const uint8_t *seed2, size_t seed2_len); +// CRYPTO_tls13_hkdf_expand_label computes the TLS 1.3 KDF function of the same +// name. See https://www.rfc-editor.org/rfc/rfc8446#section-7.1. +OPENSSL_EXPORT int CRYPTO_tls13_hkdf_expand_label( + uint8_t *out, size_t out_len, const EVP_MD *digest, // + const uint8_t *secret, size_t secret_len, // + const uint8_t *label, size_t label_len, // + const uint8_t *hash, size_t hash_len); + #if defined(__cplusplus) } diff --git a/third_party/boringssl/kit/src/crypto/fipsmodule/tls/kdf.c b/third_party/boringssl/kit/src/crypto/fipsmodule/tls/kdf.c index 347e9987..c4f4976c 100644 --- a/third_party/boringssl/kit/src/crypto/fipsmodule/tls/kdf.c +++ b/third_party/boringssl/kit/src/crypto/fipsmodule/tls/kdf.c @@ -52,12 +52,15 @@ #include +#include #include +#include #include #include #include "internal.h" #include "../../internal.h" +#include "../service_indicator/internal.h" // tls1_P_hash computes the TLS P_ function as described in RFC 5246, @@ -90,7 +93,7 @@ static int tls1_P_hash(uint8_t *out, size_t out_len, } for (;;) { - unsigned len; + unsigned len_u; uint8_t hmac[EVP_MAX_MD_SIZE]; if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || !HMAC_Update(&ctx, A1, A1_len) || @@ -99,16 +102,17 @@ static int tls1_P_hash(uint8_t *out, size_t out_len, !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || !HMAC_Update(&ctx, seed1, seed1_len) || !HMAC_Update(&ctx, seed2, seed2_len) || - !HMAC_Final(&ctx, hmac, &len)) { + !HMAC_Final(&ctx, hmac, &len_u)) { goto err; } + size_t len = len_u; assert(len == chunk); // XOR the result into |out|. if (len > out_len) { len = out_len; } - for (unsigned i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) { out[i] ^= hmac[i]; } out += len; @@ -146,12 +150,16 @@ int CRYPTO_tls1_prf(const EVP_MD *digest, OPENSSL_memset(out, 0, out_len); + const EVP_MD *const original_digest = digest; + FIPS_service_indicator_lock_state(); + int ret = 0; + if (digest == EVP_md5_sha1()) { // If using the MD5/SHA1 PRF, |secret| is partitioned between MD5 and SHA-1. size_t secret_half = secret_len - (secret_len / 2); if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half, label, label_len, seed1, seed1_len, seed2, seed2_len)) { - return 0; + goto end; } // Note that, if |secret_len| is odd, the two halves share a byte. @@ -160,6 +168,44 @@ int CRYPTO_tls1_prf(const EVP_MD *digest, digest = EVP_sha1(); } - return tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, - seed1, seed1_len, seed2, seed2_len); + ret = tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, + seed1, seed1_len, seed2, seed2_len); + +end: + FIPS_service_indicator_unlock_state(); + if (ret) { + TLSKDF_verify_service_indicator(original_digest); + } + return ret; } + +int CRYPTO_tls13_hkdf_expand_label(uint8_t *out, size_t out_len, + const EVP_MD *digest, // + const uint8_t *secret, size_t secret_len, + const uint8_t *label, size_t label_len, + const uint8_t *hash, size_t hash_len) { + static const uint8_t kProtocolLabel[] = "tls13 "; + CBB cbb, child; + uint8_t *hkdf_label = NULL; + size_t hkdf_label_len; + + CBB_zero(&cbb); + if (!CBB_init(&cbb, 2 + 1 + sizeof(kProtocolLabel) - 1 + label_len + 1 + + hash_len) || + !CBB_add_u16(&cbb, out_len) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, kProtocolLabel, sizeof(kProtocolLabel) - 1) || + !CBB_add_bytes(&child, label, label_len) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, hash, hash_len) || + !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) { + CBB_cleanup(&cbb); + return 0; + } + + const int ret = HKDF_expand(out, out_len, digest, secret, secret_len, + hkdf_label, hkdf_label_len); + OPENSSL_free(hkdf_label); + return ret; +} + diff --git a/third_party/boringssl/kit/src/crypto/hmac_extra/hmac_test.cc b/third_party/boringssl/kit/src/crypto/hmac_extra/hmac_test.cc index c2d61993..e65cd6a8 100644 --- a/third_party/boringssl/kit/src/crypto/hmac_extra/hmac_test.cc +++ b/third_party/boringssl/kit/src/crypto/hmac_extra/hmac_test.cc @@ -99,8 +99,7 @@ TEST(HMACTest, TestVectors) { ASSERT_EQ(EVP_MD_size(digest), output.size()); // Test using the one-shot API. - unsigned expected_mac_len = EVP_MD_size(digest); - std::unique_ptr mac(new uint8_t[expected_mac_len]); + std::unique_ptr mac(new uint8_t[EVP_MD_size(digest)]); unsigned mac_len; ASSERT_TRUE(HMAC(digest, key.data(), key.size(), input.data(), input.size(), mac.get(), &mac_len)); diff --git a/third_party/boringssl/kit/src/crypto/hpke/hpke.c b/third_party/boringssl/kit/src/crypto/hpke/hpke.c index c71ac2ac..144b1278 100644 --- a/third_party/boringssl/kit/src/crypto/hpke/hpke.c +++ b/third_party/boringssl/kit/src/crypto/hpke/hpke.c @@ -30,7 +30,7 @@ #include "../internal.h" -// This file implements draft-irtf-cfrg-hpke-12. +// This file implements RFC 9180. #define MAX_SEED_LEN X25519_PRIVATE_KEY_LEN #define MAX_SHARED_SECRET_LEN SHA256_DIGEST_LENGTH @@ -40,6 +40,7 @@ struct evp_hpke_kem_st { size_t public_key_len; size_t private_key_len; size_t seed_len; + size_t enc_len; int (*init_key)(EVP_HPKE_KEY *key, const uint8_t *priv_key, size_t priv_key_len); int (*generate_key)(EVP_HPKE_KEY *key); @@ -52,6 +53,17 @@ struct evp_hpke_kem_st { int (*decap)(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, size_t *out_shared_secret_len, const uint8_t *enc, size_t enc_len); + int (*auth_encap_with_seed)(const EVP_HPKE_KEY *key, + uint8_t *out_shared_secret, + size_t *out_shared_secret_len, uint8_t *out_enc, + size_t *out_enc_len, size_t max_enc, + const uint8_t *peer_public_key, + size_t peer_public_key_len, const uint8_t *seed, + size_t seed_len); + int (*auth_decap)(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len, const uint8_t *peer_public_key, + size_t peer_public_key_len); }; struct evp_hpke_kdf_st { @@ -115,7 +127,7 @@ static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key, // KEM implementations. // dhkem_extract_and_expand implements the ExtractAndExpand operation in the -// DHKEM construction. See section 4.1 of draft-irtf-cfrg-hpke-12. +// DHKEM construction. See section 4.1 of RFC 9180. static int dhkem_extract_and_expand(uint16_t kem_id, const EVP_MD *hkdf_md, uint8_t *out_key, size_t out_len, const uint8_t *dh, size_t dh_len, @@ -210,22 +222,105 @@ static int x25519_decap(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, return 1; } +static int x25519_auth_encap_with_seed( + const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, uint8_t *out_enc, size_t *out_enc_len, + size_t max_enc, const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *seed, size_t seed_len) { + if (max_enc < X25519_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + if (seed_len != X25519_PRIVATE_KEY_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + X25519_public_from_private(out_enc, seed); + + uint8_t dh[2 * X25519_SHARED_KEY_LEN]; + if (peer_public_key_len != X25519_PUBLIC_VALUE_LEN || + !X25519(dh, seed, peer_public_key) || + !X25519(dh + X25519_SHARED_KEY_LEN, key->private_key, peer_public_key)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY); + return 0; + } + + uint8_t kem_context[3 * X25519_PUBLIC_VALUE_LEN]; + OPENSSL_memcpy(kem_context, out_enc, X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, peer_public_key, + X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + 2 * X25519_PUBLIC_VALUE_LEN, key->public_key, + X25519_PUBLIC_VALUE_LEN); + if (!dhkem_extract_and_expand(key->kem->id, EVP_sha256(), out_shared_secret, + SHA256_DIGEST_LENGTH, dh, sizeof(dh), + kem_context, sizeof(kem_context))) { + return 0; + } + + *out_enc_len = X25519_PUBLIC_VALUE_LEN; + *out_shared_secret_len = SHA256_DIGEST_LENGTH; + return 1; +} + +static int x25519_auth_decap(const EVP_HPKE_KEY *key, + uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len, const uint8_t *peer_public_key, + size_t peer_public_key_len) { + uint8_t dh[2 * X25519_SHARED_KEY_LEN]; + if (enc_len != X25519_PUBLIC_VALUE_LEN || + peer_public_key_len != X25519_PUBLIC_VALUE_LEN || + !X25519(dh, key->private_key, enc) || + !X25519(dh + X25519_SHARED_KEY_LEN, key->private_key, peer_public_key)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY); + return 0; + } + + uint8_t kem_context[3 * X25519_PUBLIC_VALUE_LEN]; + OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, key->public_key, + X25519_PUBLIC_VALUE_LEN); + OPENSSL_memcpy(kem_context + 2 * X25519_PUBLIC_VALUE_LEN, peer_public_key, + X25519_PUBLIC_VALUE_LEN); + if (!dhkem_extract_and_expand(key->kem->id, EVP_sha256(), out_shared_secret, + SHA256_DIGEST_LENGTH, dh, sizeof(dh), + kem_context, sizeof(kem_context))) { + return 0; + } + + *out_shared_secret_len = SHA256_DIGEST_LENGTH; + return 1; +} + const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void) { static const EVP_HPKE_KEM kKEM = { /*id=*/EVP_HPKE_DHKEM_X25519_HKDF_SHA256, /*public_key_len=*/X25519_PUBLIC_VALUE_LEN, /*private_key_len=*/X25519_PRIVATE_KEY_LEN, /*seed_len=*/X25519_PRIVATE_KEY_LEN, + /*enc_len=*/X25519_PUBLIC_VALUE_LEN, x25519_init_key, x25519_generate_key, x25519_encap_with_seed, x25519_decap, + x25519_auth_encap_with_seed, + x25519_auth_decap, }; return &kKEM; } uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem) { return kem->id; } +size_t EVP_HPKE_KEM_public_key_len(const EVP_HPKE_KEM *kem) { + return kem->public_key_len; +} + +size_t EVP_HPKE_KEM_private_key_len(const EVP_HPKE_KEM *kem) { + return kem->private_key_len; +} + +size_t EVP_HPKE_KEM_enc_len(const EVP_HPKE_KEM *kem) { return kem->enc_len; } + void EVP_HPKE_KEY_zero(EVP_HPKE_KEY *key) { OPENSSL_memset(key, 0, sizeof(EVP_HPKE_KEY)); } @@ -238,7 +333,6 @@ void EVP_HPKE_KEY_cleanup(EVP_HPKE_KEY *key) { EVP_HPKE_KEY *EVP_HPKE_KEY_new(void) { EVP_HPKE_KEY *key = OPENSSL_malloc(sizeof(EVP_HPKE_KEY)); if (key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } EVP_HPKE_KEY_zero(key); @@ -315,6 +409,10 @@ const EVP_HPKE_KDF *EVP_hpke_hkdf_sha256(void) { uint16_t EVP_HPKE_KDF_id(const EVP_HPKE_KDF *kdf) { return kdf->id; } +const EVP_MD *EVP_HPKE_KDF_hkdf_md(const EVP_HPKE_KDF *kdf) { + return kdf->hkdf_md_func(); +} + const EVP_HPKE_AEAD *EVP_hpke_aes_128_gcm(void) { static const EVP_HPKE_AEAD kAEAD = {EVP_HPKE_AES_128_GCM, &EVP_aead_aes_128_gcm}; @@ -350,18 +448,18 @@ const EVP_AEAD *EVP_HPKE_AEAD_aead(const EVP_HPKE_AEAD *aead) { static int hpke_build_suite_id(const EVP_HPKE_CTX *ctx, uint8_t out[HPKE_SUITE_ID_LEN]) { CBB cbb; - int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) && - add_label_string(&cbb, "HPKE") && - CBB_add_u16(&cbb, EVP_HPKE_DHKEM_X25519_HKDF_SHA256) && - CBB_add_u16(&cbb, ctx->kdf->id) && - CBB_add_u16(&cbb, ctx->aead->id); - CBB_cleanup(&cbb); - return ret; + CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN); + return add_label_string(&cbb, "HPKE") && // + CBB_add_u16(&cbb, ctx->kem->id) && // + CBB_add_u16(&cbb, ctx->kdf->id) && // + CBB_add_u16(&cbb, ctx->aead->id); } #define HPKE_MODE_BASE 0 +#define HPKE_MODE_AUTH 2 -static int hpke_key_schedule(EVP_HPKE_CTX *ctx, const uint8_t *shared_secret, +static int hpke_key_schedule(EVP_HPKE_CTX *ctx, uint8_t mode, + const uint8_t *shared_secret, size_t shared_secret_len, const uint8_t *info, size_t info_len) { uint8_t suite_id[HPKE_SUITE_ID_LEN]; @@ -393,8 +491,8 @@ static int hpke_key_schedule(EVP_HPKE_CTX *ctx, const uint8_t *shared_secret, uint8_t context[sizeof(uint8_t) + 2 * EVP_MAX_MD_SIZE]; size_t context_len; CBB context_cbb; - if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) || - !CBB_add_u8(&context_cbb, HPKE_MODE_BASE) || + CBB_init_fixed(&context_cbb, context, sizeof(context)); + if (!CBB_add_u8(&context_cbb, mode) || !CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) || !CBB_add_bytes(&context_cbb, info_hash, info_hash_len) || !CBB_finish(&context_cbb, NULL, &context_len)) { @@ -451,7 +549,6 @@ void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) { EVP_HPKE_CTX *EVP_HPKE_CTX_new(void) { EVP_HPKE_CTX *ctx = OPENSSL_malloc(sizeof(EVP_HPKE_CTX)); if (ctx == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return NULL; } EVP_HPKE_CTX_zero(ctx); @@ -487,6 +584,7 @@ int EVP_HPKE_CTX_setup_sender_with_seed_for_testing( size_t seed_len) { EVP_HPKE_CTX_zero(ctx); ctx->is_sender = 1; + ctx->kem = kem; ctx->kdf = kdf; ctx->aead = aead; uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; @@ -494,8 +592,8 @@ int EVP_HPKE_CTX_setup_sender_with_seed_for_testing( if (!kem->encap_with_seed(kem, shared_secret, &shared_secret_len, out_enc, out_enc_len, max_enc, peer_public_key, peer_public_key_len, seed, seed_len) || - !hpke_key_schedule(ctx, shared_secret, shared_secret_len, info, - info_len)) { + !hpke_key_schedule(ctx, HPKE_MODE_BASE, shared_secret, shared_secret_len, + info, info_len)) { EVP_HPKE_CTX_cleanup(ctx); return 0; } @@ -509,13 +607,85 @@ int EVP_HPKE_CTX_setup_recipient(EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key, size_t info_len) { EVP_HPKE_CTX_zero(ctx); ctx->is_sender = 0; + ctx->kem = key->kem; ctx->kdf = kdf; ctx->aead = aead; uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; size_t shared_secret_len; if (!key->kem->decap(key, shared_secret, &shared_secret_len, enc, enc_len) || - !hpke_key_schedule(ctx, shared_secret, sizeof(shared_secret), info, - info_len)) { + !hpke_key_schedule(ctx, HPKE_MODE_BASE, shared_secret, shared_secret_len, + info, info_len)) { + EVP_HPKE_CTX_cleanup(ctx); + return 0; + } + return 1; +} + + +int EVP_HPKE_CTX_setup_auth_sender( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len) { + uint8_t seed[MAX_SEED_LEN]; + RAND_bytes(seed, key->kem->seed_len); + return EVP_HPKE_CTX_setup_auth_sender_with_seed_for_testing( + ctx, out_enc, out_enc_len, max_enc, key, kdf, aead, peer_public_key, + peer_public_key_len, info, info_len, seed, key->kem->seed_len); +} + +int EVP_HPKE_CTX_setup_auth_sender_with_seed_for_testing( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len, const uint8_t *seed, + size_t seed_len) { + if (key->kem->auth_encap_with_seed == NULL) { + // Not all HPKE KEMs support AuthEncap. + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + EVP_HPKE_CTX_zero(ctx); + ctx->is_sender = 1; + ctx->kem = key->kem; + ctx->kdf = kdf; + ctx->aead = aead; + uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; + size_t shared_secret_len; + if (!key->kem->auth_encap_with_seed( + key, shared_secret, &shared_secret_len, out_enc, out_enc_len, max_enc, + peer_public_key, peer_public_key_len, seed, seed_len) || + !hpke_key_schedule(ctx, HPKE_MODE_AUTH, shared_secret, shared_secret_len, + info, info_len)) { + EVP_HPKE_CTX_cleanup(ctx); + return 0; + } + return 1; +} + +int EVP_HPKE_CTX_setup_auth_recipient( + EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, + const EVP_HPKE_AEAD *aead, const uint8_t *enc, size_t enc_len, + const uint8_t *info, size_t info_len, const uint8_t *peer_public_key, + size_t peer_public_key_len) { + if (key->kem->auth_decap == NULL) { + // Not all HPKE KEMs support AuthDecap. + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + EVP_HPKE_CTX_zero(ctx); + ctx->is_sender = 0; + ctx->kem = key->kem; + ctx->kdf = kdf; + ctx->aead = aead; + uint8_t shared_secret[MAX_SHARED_SECRET_LEN]; + size_t shared_secret_len; + if (!key->kem->auth_decap(key, shared_secret, &shared_secret_len, enc, + enc_len, peer_public_key, peer_public_key_len) || + !hpke_key_schedule(ctx, HPKE_MODE_AUTH, shared_secret, shared_secret_len, + info, info_len)) { EVP_HPKE_CTX_cleanup(ctx); return 0; } @@ -609,6 +779,10 @@ size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *ctx) { return EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(&ctx->aead_ctx)); } +const EVP_HPKE_KEM *EVP_HPKE_CTX_kem(const EVP_HPKE_CTX *ctx) { + return ctx->kem; +} + const EVP_HPKE_AEAD *EVP_HPKE_CTX_aead(const EVP_HPKE_CTX *ctx) { return ctx->aead; } diff --git a/third_party/boringssl/kit/src/crypto/hpke/hpke_test.cc b/third_party/boringssl/kit/src/crypto/hpke/hpke_test.cc index 87c72a81..03b23b52 100644 --- a/third_party/boringssl/kit/src/crypto/hpke/hpke_test.cc +++ b/third_party/boringssl/kit/src/crypto/hpke/hpke_test.cc @@ -66,11 +66,26 @@ class HPKETestVector { // Test the sender. ScopedEVP_HPKE_CTX sender_ctx; uint8_t enc[EVP_HPKE_MAX_ENC_LENGTH]; - size_t enc_len; - ASSERT_TRUE(EVP_HPKE_CTX_setup_sender_with_seed_for_testing( - sender_ctx.get(), enc, &enc_len, sizeof(enc), kem, kdf, aead, - public_key_r_.data(), public_key_r_.size(), info_.data(), info_.size(), - secret_key_e_.data(), secret_key_e_.size())); + size_t enc_len = 0; + switch (mode_) { + case Mode::kBase: + ASSERT_TRUE(EVP_HPKE_CTX_setup_sender_with_seed_for_testing( + sender_ctx.get(), enc, &enc_len, sizeof(enc), kem, kdf, aead, + public_key_r_.data(), public_key_r_.size(), info_.data(), + info_.size(), secret_key_e_.data(), secret_key_e_.size())); + break; + case Mode::kAuth: { + ScopedEVP_HPKE_KEY sender_key; + ASSERT_TRUE(EVP_HPKE_KEY_init( + sender_key.get(), kem, secret_key_s_.data(), secret_key_s_.size())); + ASSERT_TRUE(EVP_HPKE_CTX_setup_auth_sender_with_seed_for_testing( + sender_ctx.get(), enc, &enc_len, sizeof(enc), sender_key.get(), kdf, + aead, public_key_r_.data(), public_key_r_.size(), info_.data(), + info_.size(), secret_key_e_.data(), secret_key_e_.size())); + break; + } + } + EXPECT_EQ(Bytes(enc, enc_len), Bytes(public_key_e_)); VerifySender(sender_ctx.get()); @@ -101,9 +116,18 @@ class HPKETestVector { // Set up the recipient. ScopedEVP_HPKE_CTX recipient_ctx; - ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient(recipient_ctx.get(), key, kdf, - aead, enc, enc_len, info_.data(), - info_.size())); + switch (mode_) { + case Mode::kBase: + ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient(recipient_ctx.get(), key, + kdf, aead, enc, enc_len, + info_.data(), info_.size())); + break; + case Mode::kAuth: + ASSERT_TRUE(EVP_HPKE_CTX_setup_auth_recipient( + recipient_ctx.get(), key, kdf, aead, enc, enc_len, info_.data(), + info_.size(), public_key_s_.data(), public_key_s_.size())); + break; + } VerifyRecipient(recipient_ctx.get()); } @@ -168,6 +192,11 @@ class HPKETestVector { } } + enum class Mode { + kBase = 0, + kAuth = 2, + }; + struct Encryption { std::vector aad; std::vector ciphertext; @@ -180,6 +209,7 @@ class HPKETestVector { std::vector exported_value; }; + Mode mode_; uint16_t kdf_id_; uint16_t aead_id_; std::vector context_; @@ -188,6 +218,8 @@ class HPKETestVector { std::vector secret_key_e_; std::vector public_key_r_; std::vector secret_key_r_; + std::vector public_key_s_; + std::vector secret_key_s_; std::vector encryptions_; std::vector exports_; }; @@ -227,7 +259,6 @@ bool FileTestReadInt(FileTest *file_test, T *out, const std::string &key) { bool HPKETestVector::ReadFromFileTest(FileTest *t) { uint8_t mode = 0; if (!FileTestReadInt(t, &mode, "mode") || - mode != 0 /* mode_base */ || !FileTestReadInt(t, &kdf_id_, "kdf_id") || !FileTestReadInt(t, &aead_id_, "aead_id") || !t->GetBytes(&info_, "info") || @@ -238,6 +269,21 @@ bool HPKETestVector::ReadFromFileTest(FileTest *t) { return false; } + switch (mode) { + case static_cast(Mode::kBase): + mode_ = Mode::kBase; + break; + case static_cast(Mode::kAuth): + mode_ = Mode::kAuth; + if (!t->GetBytes(&secret_key_s_, "skSm") || + !t->GetBytes(&public_key_s_, "pkSm")) { + return false; + } + break; + default: + return false; + } + for (int i = 1; t->HasAttribute(BuildAttrName("aad", i)); i++) { Encryption encryption; if (!t->GetBytes(&encryption.aad, BuildAttrName("aad", i)) || @@ -282,14 +328,25 @@ TEST(HPKETest, RoundTrip) { Span info_values[] = {{nullptr, 0}, info_a, info_b}; Span ad_values[] = {{nullptr, 0}, ad_a, ad_b}; + const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256(); + // Generate the recipient's keypair. ScopedEVP_HPKE_KEY key; - ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256())); + ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), kem)); uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN]; size_t public_key_r_len; ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key_r, &public_key_r_len, sizeof(public_key_r))); + // Generate the sender's keypair, for auth modes. + ScopedEVP_HPKE_KEY sender_key; + ASSERT_TRUE( + EVP_HPKE_KEY_generate(sender_key.get(), kem)); + uint8_t public_key_s[X25519_PUBLIC_VALUE_LEN]; + size_t public_key_s_len; + ASSERT_TRUE(EVP_HPKE_KEY_public_key(sender_key.get(), public_key_s, + &public_key_s_len, sizeof(public_key_r))); + for (const auto kdf : kAllKDFs) { SCOPED_TRACE(EVP_HPKE_KDF_id(kdf())); for (const auto aead : kAllAEADs) { @@ -298,45 +355,70 @@ TEST(HPKETest, RoundTrip) { SCOPED_TRACE(Bytes(info)); for (const Span &ad : ad_values) { SCOPED_TRACE(Bytes(ad)); - // Set up the sender. - ScopedEVP_HPKE_CTX sender_ctx; - uint8_t enc[X25519_PUBLIC_VALUE_LEN]; - size_t enc_len; - ASSERT_TRUE(EVP_HPKE_CTX_setup_sender( - sender_ctx.get(), enc, &enc_len, sizeof(enc), - EVP_hpke_x25519_hkdf_sha256(), kdf(), aead(), public_key_r, - public_key_r_len, info.data(), info.size())); - // Set up the recipient. - ScopedEVP_HPKE_CTX recipient_ctx; - ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient( - recipient_ctx.get(), key.get(), kdf(), aead(), enc, enc_len, - info.data(), info.size())); + auto check_messages = [&](EVP_HPKE_CTX *sender_ctx, + EVP_HPKE_CTX *recipient_ctx) { + const char kCleartextPayload[] = "foobar"; - const char kCleartextPayload[] = "foobar"; + // Have sender encrypt message for the recipient. + std::vector ciphertext( + sizeof(kCleartextPayload) + + EVP_HPKE_CTX_max_overhead(sender_ctx)); + size_t ciphertext_len; + ASSERT_TRUE(EVP_HPKE_CTX_seal( + sender_ctx, ciphertext.data(), &ciphertext_len, + ciphertext.size(), + reinterpret_cast(kCleartextPayload), + sizeof(kCleartextPayload), ad.data(), ad.size())); - // Have sender encrypt message for the recipient. - std::vector ciphertext( - sizeof(kCleartextPayload) + - EVP_HPKE_CTX_max_overhead(sender_ctx.get())); - size_t ciphertext_len; - ASSERT_TRUE(EVP_HPKE_CTX_seal( - sender_ctx.get(), ciphertext.data(), &ciphertext_len, - ciphertext.size(), - reinterpret_cast(kCleartextPayload), - sizeof(kCleartextPayload), ad.data(), ad.size())); + // Have recipient decrypt the message. + std::vector cleartext(ciphertext.size()); + size_t cleartext_len; + ASSERT_TRUE(EVP_HPKE_CTX_open(recipient_ctx, cleartext.data(), + &cleartext_len, cleartext.size(), + ciphertext.data(), ciphertext_len, + ad.data(), ad.size())); - // Have recipient decrypt the message. - std::vector cleartext(ciphertext.size()); - size_t cleartext_len; - ASSERT_TRUE(EVP_HPKE_CTX_open(recipient_ctx.get(), cleartext.data(), - &cleartext_len, cleartext.size(), - ciphertext.data(), ciphertext_len, - ad.data(), ad.size())); + // Verify that decrypted message matches the original. + ASSERT_EQ(Bytes(cleartext.data(), cleartext_len), + Bytes(kCleartextPayload, sizeof(kCleartextPayload))); + }; - // Verify that decrypted message matches the original. - ASSERT_EQ(Bytes(cleartext.data(), cleartext_len), - Bytes(kCleartextPayload, sizeof(kCleartextPayload))); + // Test the base mode. + { + ScopedEVP_HPKE_CTX sender_ctx; + uint8_t enc[X25519_PUBLIC_VALUE_LEN]; + size_t enc_len; + ASSERT_TRUE(EVP_HPKE_CTX_setup_sender( + sender_ctx.get(), enc, &enc_len, sizeof(enc), kem, kdf(), + aead(), public_key_r, public_key_r_len, info.data(), + info.size())); + + ScopedEVP_HPKE_CTX recipient_ctx; + ASSERT_TRUE(EVP_HPKE_CTX_setup_recipient( + recipient_ctx.get(), key.get(), kdf(), aead(), enc, enc_len, + info.data(), info.size())); + + check_messages(sender_ctx.get(), recipient_ctx.get()); + } + + // Test the auth mode. + { + ScopedEVP_HPKE_CTX sender_ctx; + uint8_t enc[X25519_PUBLIC_VALUE_LEN]; + size_t enc_len; + ASSERT_TRUE(EVP_HPKE_CTX_setup_auth_sender( + sender_ctx.get(), enc, &enc_len, sizeof(enc), sender_key.get(), + kdf(), aead(), public_key_r, public_key_r_len, info.data(), + info.size())); + + ScopedEVP_HPKE_CTX recipient_ctx; + ASSERT_TRUE(EVP_HPKE_CTX_setup_auth_recipient( + recipient_ctx.get(), key.get(), kdf(), aead(), enc, enc_len, + info.data(), info.size(), public_key_s, public_key_s_len)); + + check_messages(sender_ctx.get(), recipient_ctx.get()); + } } } } @@ -352,6 +434,11 @@ TEST(HPKETest, X25519EncapSmallOrderPoint) { 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, }; + static const uint8_t kValidPoint[32] = { + 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, + 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, + 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, + }; ScopedEVP_HPKE_KEY key; ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256())); @@ -364,16 +451,32 @@ TEST(HPKETest, X25519EncapSmallOrderPoint) { ScopedEVP_HPKE_CTX sender_ctx; uint8_t enc[X25519_PUBLIC_VALUE_LEN]; size_t enc_len; - ASSERT_FALSE(EVP_HPKE_CTX_setup_sender( + EXPECT_FALSE(EVP_HPKE_CTX_setup_sender( sender_ctx.get(), enc, &enc_len, sizeof(enc), EVP_hpke_x25519_hkdf_sha256(), kdf(), aead(), kSmallOrderPoint, sizeof(kSmallOrderPoint), nullptr, 0)); + // Likewise with auth. + EXPECT_FALSE(EVP_HPKE_CTX_setup_auth_sender( + sender_ctx.get(), enc, &enc_len, sizeof(enc), key.get(), kdf(), + aead(), kSmallOrderPoint, sizeof(kSmallOrderPoint), nullptr, 0)); + // Set up the recipient, passing in kSmallOrderPoint as |enc|. ScopedEVP_HPKE_CTX recipient_ctx; - ASSERT_FALSE(EVP_HPKE_CTX_setup_recipient( + EXPECT_FALSE(EVP_HPKE_CTX_setup_recipient( recipient_ctx.get(), key.get(), kdf(), aead(), kSmallOrderPoint, sizeof(kSmallOrderPoint), nullptr, 0)); + + // Likewise with auth. With auth, a small-order point could appear as + // either |enc| or the peer public key. + EXPECT_FALSE(EVP_HPKE_CTX_setup_auth_recipient( + recipient_ctx.get(), key.get(), kdf(), aead(), kSmallOrderPoint, + sizeof(kSmallOrderPoint), nullptr, 0, kValidPoint, + sizeof(kValidPoint))); + EXPECT_FALSE(EVP_HPKE_CTX_setup_auth_recipient( + recipient_ctx.get(), key.get(), kdf(), aead(), kValidPoint, + sizeof(kValidPoint), nullptr, 0, kSmallOrderPoint, + sizeof(kSmallOrderPoint))); } } } diff --git a/third_party/boringssl/kit/src/crypto/hpke/hpke_test_vectors.txt b/third_party/boringssl/kit/src/crypto/hpke/hpke_test_vectors.txt index bb708b37..f99ee236 100644 --- a/third_party/boringssl/kit/src/crypto/hpke/hpke_test_vectors.txt +++ b/third_party/boringssl/kit/src/crypto/hpke/hpke_test_vectors.txt @@ -1047,6 +1047,1057 @@ exporter_context = 54657374436f6e74657874 L = 32 exported_value = e9e43065102c3836401bed8c3c3c75ae46be1639869391d62c61f1ec7af54931 +mode = 2 +kdf_id = 1 +aead_id = 1 +info = 4f6465206f6e2061204772656369616e2055726e +skRm = fdea67cf831f1ca98d8e27b1f6abeb5b7745e9d35348b80fa407ff6958f9137e +skEm = ff4442ef24fbc3c1ff86375b0be1e77e88a0de1e79b30896d73411c5ff4c3518 +pkRm = 1632d5c2f71c2b38d0a8fcc359355200caa8b1ffdf28618080466c909cb69b2e +pkEm = 23fb952571a14a25e3d678140cd0e5eb47a0961bb18afcf85896e5453c312e76 +pkSm = 8b0c70873dc5aecb7f9ee4e62406a397b350e57012be45cf53b7105ae731790b +skSm = dc4a146313cce60a278a5323d321f051c5707e9c45ba21a3479fecdf76fc69dd +# encryptions[0] +aad = 436f756e742d30 +ct = 5fd92cc9d46dbf8943e72a07e42f363ed5f721212cd90bcfd072bfd9f44e06b80fd17824947496e21b680c141b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[1] +aad = 436f756e742d31 +ct = d3736bb256c19bfa93d79e8f80b7971262cb7c887e35c26370cfed62254369a1b52e3d505b79dd699f002bc8ed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[2] +aad = 436f756e742d32 +ct = 122175cfd5678e04894e4ff8789e85dd381df48dcaf970d52057df2c9acc3b121313a2bfeaa986050f82d93645 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[3] +aad = 436f756e742d33 +ct = 81448cec70230638b6c6b8fab63b430f3ee3d506a96229bd825fe8139f3231c6e1db349beb18bdcd8bcf796ff9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[4] +aad = 436f756e742d34 +ct = dae12318660cf963c7bcbef0f39d64de3bf178cf9e585e756654043cc5059873bc8af190b72afc43d1e0135ada +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[5] +aad = 436f756e742d35 +ct = f998abcc1c84c6e421d6b7049fddf1839e7c5464645b7c5376edbfcd4d74352648645b08f6803a56ea624158e3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[6] +aad = 436f756e742d36 +ct = e0b80588421e345c607b6dcf7485dfa28ecba51c083a5e4c748deabf49cd8ce8ad64ab16a818d97c94f5cbcba4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[7] +aad = 436f756e742d37 +ct = ad7d5a8737c52c89521932e36470236e171c6e0e020983b4e8f7bd443a743f616220c23ad15b6eba04a0490f7a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[8] +aad = 436f756e742d38 +ct = 12990eadd503e2684efd367ef6eb7c10bd901a8db1d7cbd76f1eab25b1770fda29756f2432334b7cb59ddc5ad7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[9] +aad = 436f756e742d39 +ct = 6df5a172c5ed16fc3d4c7e55e3bc931a359282ba7142f3fa7da6d7feea0ae0c8071a081876df3d38cfaea8089b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[10] +aad = 436f756e742d3130 +ct = ac214db460440110a9874b512e41384d7960711016d470a9e8059e6f4d46338742a4e0c8190e51b0c8a7d3322b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[11] +aad = 436f756e742d3131 +ct = 8ecc6adb36ae93e951da72468b99141e38103e5d5e872577d1d5e4a7fb9d12729a678c4905471fd2b767b2cdac +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[12] +aad = 436f756e742d3132 +ct = d5ae8d2f471d28ae1ec85a0ea544ccf9d828bdf76946556d705d0900f4f52edabe8b1b86f760d5b27ede114bb4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[13] +aad = 436f756e742d3133 +ct = d2d736316eb91cb3a019402f1ea2f95601e16a5f7cf2aa0493b9a0a9822e8a0c5ff701e2dc4dd98c7a4361eae1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[14] +aad = 436f756e742d3134 +ct = c98347b851ad8570f2a6e25a7d8ffbaa0514fad0a67a567cafb7f2f16bd185a2d366fbaeb993aade524c288c11 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[15] +aad = 436f756e742d3135 +ct = a6ec1b6537df7d82ddd411da2fd2d6c80a6e1a81a94c14a04f928cc43f6595dbfb9820e201034b69d4361fa294 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[16] +aad = 436f756e742d3136 +ct = 64136b023c77e329b6c0585cbef0ef139b7da50fb37ef0d465687be24da10465e1a4dcb9f9d10ff8d4b8b2adf6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[17] +aad = 436f756e742d3137 +ct = 4781db96aaca00e95d6a33a87b5aa4d4febc7a11cf984365651e793b96bb2fca0a5c5addeb0a4eda8558eb4639 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[18] +aad = 436f756e742d3138 +ct = efbcd0926dddc95b33bca922dbadf82df2d928f211cd1a95059bca159cbb2ad1ae4b44983c15079c3f3e5548a6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[19] +aad = 436f756e742d3139 +ct = b00418a10ed979ddc5f733c8d6e1feac93398f99a03ba258ec3ce46b801028ca218de871dbf35a9f90230a2d28 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[20] +aad = 436f756e742d3230 +ct = 9a69b169ef765433fe6ec1414ee5c7aa84974d2dd47c7ca95eca39cc3016730656fbc2632dd8b0fac86bdb36e8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[21] +aad = 436f756e742d3231 +ct = 781645d997518600d2d331939f4306c2f4ab72b4b8b6aac3d0bae922518821f5f3eef7356ede837d706c9e0ad8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[22] +aad = 436f756e742d3232 +ct = c7ab847bda8e799ce31cb751d8d8b40a44a69a797c61de5b4b26b5083ffd6ead2dc6c9c85e044ae953d59e9226 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[23] +aad = 436f756e742d3233 +ct = e598a17f69b9f2516abea3602756f864cceb7e75c292e152c0fcafbe006321d6d7229d8eb7d7a5bc233daeb93e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[24] +aad = 436f756e742d3234 +ct = 6c93a379fe85e3cb345d3f3c78983003900283ac7cb685796b739b77eb15da62834c87169fca6da3f33f12782e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[25] +aad = 436f756e742d3235 +ct = 62be42591a5e2cdcf43ee38d4a01e36a46dd349ae5e25f0cf0f9d1d303a49788b2d782abce7a9015983eaac1de +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[26] +aad = 436f756e742d3236 +ct = 88ffba9f0cb873174ce8467e4f0101e1b4408ac8dc6cdd9f924551ba9eee57c96901ca19c592cc0e7aee3652d4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[27] +aad = 436f756e742d3237 +ct = ab98458f4280faa8a00d5bf65846ea270ce47b05e887fdb48b2ecc17e62d1399ba45eb23a370dbde5067b7ac27 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[28] +aad = 436f756e742d3238 +ct = 4181af4e773e309ce7a4ac04ad08828378b4644e8a33b8be02776659d1c13c25d1cf3d95de95d15e4f251098eb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[29] +aad = 436f756e742d3239 +ct = 566c4c023069ac3a2e9ad94e29819d0846fcb023614f04fcc107b825a6004dd48082173da952b9466b898e9514 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[30] +aad = 436f756e742d3330 +ct = 14e76dca587889d13c87b6f9198e40bf708b59eeb7524a3330acde681414f0b563bb73681077ab2c3e49a34b2c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[31] +aad = 436f756e742d3331 +ct = 02be122d5b3fa62dd45baacc13c060c726da0ed95e6cb64b75d91abd08c237a0e0f48b7442737c403a470ef86e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[32] +aad = 436f756e742d3332 +ct = 608ceaf60a18be198b8b3ef4772a550f5803412108a8fbb97dfe7ddbb34900774f4c22056c48f9abec995be7ef +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[33] +aad = 436f756e742d3333 +ct = c229036df4aff67458d0779e2d9a4a50ff775ff64dc73acde6abb01098c2b25b7e7075707d3ffaaa696fa2db2a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[34] +aad = 436f756e742d3334 +ct = b5d56ebb67daa05ca9b6c8d65742a8ef164b2ad5a108d61a77af584897ee41d349903af4e1c9a2a0f16d16ac52 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[35] +aad = 436f756e742d3335 +ct = a9406787523a3fc63adf9a04a1df6fffe90a8f8251a623bc144aa3ee0efa0d5aee37d95f0cb769d49293e154c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[36] +aad = 436f756e742d3336 +ct = 9ed258258a8f8bf329162d322a3edb75ed1799e0543f39fe168bb1aae05ccc1a5532a3c4df7aae26fcd39513dd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[37] +aad = 436f756e742d3337 +ct = 958ff65e212d9dcfe399ee93a921bd0235fca5a8e4836bf854ecc5e2fdbb664fa7d9ebd5d3bd52018290b793c6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[38] +aad = 436f756e742d3338 +ct = 329831514fd6313f44895b2acc15657966fd6b800e63f7a53fe5198d34e30df848de3068b1921661ddf05681c2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[39] +aad = 436f756e742d3339 +ct = dc37ec0e2c08be44d9ec709138e811b116a2bdff4f89c8a0639783165ca3da21967e4d2c08927e5beb446662c6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[40] +aad = 436f756e742d3430 +ct = 7b8c1fd6061641cef0913dcb80dec12274352bd94eaf46b631b1968daf5b3db6aa21336c9878a194957b466058 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[41] +aad = 436f756e742d3431 +ct = 09227ba8d90dafd0948dcb79cc661011b022ae576102c7ba67cfbc4b04fecd6cc7edd86718a23a11bf97100631 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[42] +aad = 436f756e742d3432 +ct = 86ca60e820b54fb1d39b4c23d3f390e9cdbbd4220e24267cea51bfd90021b2f16762a7bf44a66e79040c63933b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[43] +aad = 436f756e742d3433 +ct = e9108564d752c2c56faecfdf36ac2c849c8d1e923ad6bf331a60bc5bbb45aff7ea7c334193bbd7f4143b61c185 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[44] +aad = 436f756e742d3434 +ct = 87ffaa9446a4a80fad33fdab7e397b9376f8ca33e20e48a500446b60204f2937bae2836798735a3dac0ff5a880 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[45] +aad = 436f756e742d3435 +ct = 0da994a818399e05a41f120b7b84c1470bb33828908876b9bee7754a52b6487b092da01ca67cb021eeed43c223 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[46] +aad = 436f756e742d3436 +ct = 0217ccaf0e54da8efbbad4948d54e90ca3c3b60ad39e54ac9f716ef0dd33cacdb897f6973ec66024862829b0e2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[47] +aad = 436f756e742d3437 +ct = b700163bb5c7b11c8e8808199cd8a6cc82db500abaf3a2facfaf678431ec5bf7783d9395e450bb7d107463618e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[48] +aad = 436f756e742d3438 +ct = 8fccbfb3882371b7a04af739edb48c87f1f1d34621563ce766815ff4a049da9045943860e5cf2cd1cc02bfb8b4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[49] +aad = 436f756e742d3439 +ct = 13813c57857656d5dea3730a4e6430b300a1dc2942a5b1400cb45776533a407143224af56785e9149bf072721a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[50] +aad = 436f756e742d3530 +ct = 975c0845a0955774ba4ae6386218491084b22a721d4bfb977ab50611fb5fe579fbd041beb05c04566feb1a7a69 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[51] +aad = 436f756e742d3531 +ct = a5b8ac851160bdea05e5d85f5c4ff730c967edb4665134633dd2ca26a802760a8ff0f64096814698ed5eb0e546 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[52] +aad = 436f756e742d3532 +ct = 1da6e12454409f9ae5560fdc8274069345307c9b719d54d42c8053b18fad3b369aeaa6a27126aa846776b06c15 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[53] +aad = 436f756e742d3533 +ct = 50de3f90d54c98ca5e52d854d107b7f52c22576f1a9e77973baa6e9e9e4a69430e504094a1818294645f475cbe +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[54] +aad = 436f756e742d3534 +ct = e8460cf57d8bb3ab36a6b577f1c24d4a7d55c71e0b47422b950ff046ae25ed41a66d89d70bb4b40edae7666cd7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[55] +aad = 436f756e742d3535 +ct = df0a371a1a83bcbc24105317a97e134f4ca95c2aa875ac86b99b36347159c25d84d84882e48bbc7942fc25047f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[56] +aad = 436f756e742d3536 +ct = 5eeceae1e61e5ee09bab6d6c793226a642bf5dfc281ab2f8a6da7bbdaf44578b3fcbd3386685ed8e28b7af9aa7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[57] +aad = 436f756e742d3537 +ct = fa6dcdca295a350c7614f14b491ac3b25ee40241ae6ee36a2b416e1a46a6b3806ada8b7a525921e6b98b085498 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[58] +aad = 436f756e742d3538 +ct = 439423232f496bb252d246e44c7bfcb1f8a62c8fd3a97ca98107dad5632d17fd423e6b36265a67764f08db8fe6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[59] +aad = 436f756e742d3539 +ct = fc9eb541b325893b4a4818619b00b5988356bf07af8fe4c34c6dd0eca427a829fef7a3dbcf0172e868b0353d16 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[60] +aad = 436f756e742d3630 +ct = 23e5725b20a8b5db67fb9b64861718c1f148c1927533e2b499891f33c66b46700fb0c6e99f37b98aa278c1044a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[61] +aad = 436f756e742d3631 +ct = db051cd509ded5ba54169f883df5ec36dcf155242c24cb999aace1c2d05805814af27b5ac85bf5201282c5437f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[62] +aad = 436f756e742d3632 +ct = 63436a676cb38ed9f79cef1a7a255e6ea5aeddcb23187a43628990dc4810049c3ceb87b0b603d9f0671ca17023 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[63] +aad = 436f756e742d3633 +ct = 3cc01a55b16ba7baeff8b99bad41156c284f12876e288ef0706f0bafccb6e1a02c9dba61e766a7992073f2267a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[64] +aad = 436f756e742d3634 +ct = ece18db78b48e32e9880fd5bcdc69ba51b7d4d1f9fd3aab4542c87260d15f86bacafee4f59aa743a38c0b15355 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[65] +aad = 436f756e742d3635 +ct = a0523c4744573ac4900f9945c36bb8d85c36e890b302a53f310805f59295e66dc5276a9b4a3a2c320b957a1384 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[66] +aad = 436f756e742d3636 +ct = 4fdf4ade68a050e46002772274f44d948aa705798279fa4404e42b2e4edcac0b09f0099514e3a93bd7a0f8b68d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[67] +aad = 436f756e742d3637 +ct = 63acdebd758d7776c0de540d44de08fac33a9eeff15b6c06e9ee74d52416e7c791e407486c82c88f46b4d50b62 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[68] +aad = 436f756e742d3638 +ct = f86f589944e090e7bcad7eca46ff36e976a464145d3991d4ddf3381fd8683177d5ee87b1c8178c86dc183bae81 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[69] +aad = 436f756e742d3639 +ct = 05f5471471b5b660deb10c97bddd25dd194f7f43f256725f055110b25bbccf4033cc99da41dab17b650b6a88d0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[70] +aad = 436f756e742d3730 +ct = 5fff11dd9778ac87d60b20639d261508326ddbb935a6f9fa71c58d20678bb71356ad42f0110f62a798b0941e02 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[71] +aad = 436f756e742d3731 +ct = 80b2e9bba9e59d89c86251450b7bd08a53aa618a0b555e74224642d43924f5b46d4e40efc5291178bd162cc38a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[72] +aad = 436f756e742d3732 +ct = c31baa7d0246c32738420a7c848f998be00e155022636b90a4e2f5957fe7d41ca78005d5562e1a2ed06e3f80ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[73] +aad = 436f756e742d3733 +ct = a0bd8668746dd5718d0890b32df5a7edff64a31917f2174e124c64f2a9e454f9cbba573cd6a338f85c6570c437 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[74] +aad = 436f756e742d3734 +ct = bf893670d1f7b8fc9980b0dcdfc7245bc8b27fb894f9607f0e2fb4cf09b50951ddab19165579b00421696ac21f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[75] +aad = 436f756e742d3735 +ct = aedf69ddaf28dae07110560ebb7d1ff2f20949ca874009b7c99c6c316f1592e72e48c877a859dbc506cf99e76b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[76] +aad = 436f756e742d3736 +ct = 41e85cbcc31f046537ca10d1e0a66e3b6056a1f46a27cc96645d885aa6eeff6bb0a4ea4edab73fb544dfe58581 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[77] +aad = 436f756e742d3737 +ct = f9e5f909b0a75b5d92b586597d4de6e740b5a83fa2d78ed1f32bc11e147c85496a16fcc85b66fce6ba94e6c67c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[78] +aad = 436f756e742d3738 +ct = 9baf794b4d654aeea56be02d01bcb21d2b186809e138724cb6114d49a7a6fc3803cd4d864de78665d12c5a6425 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[79] +aad = 436f756e742d3739 +ct = 2f224c7f088822260ad71775444c01c71bc871a7f56803b95c13c9f159a523ae53c000d5c21f12fc76763d2074 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[80] +aad = 436f756e742d3830 +ct = b8047bf627a69f930658561d2d005a7e2f12e90292dc16a9c629645409a4de2e86679db9faf011901a69269e1f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[81] +aad = 436f756e742d3831 +ct = 64e7d452410b8d53713677ad165fe962cc08952f10f9d278f16f73806b64b14f8780834a1338a19924c4fec4a3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[82] +aad = 436f756e742d3832 +ct = a47b2785274a366fcfb0444ab8efd960194d6ca56d43c982c6b0b50fde16a9ee95a22cf54c985e2429b2c21a61 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[83] +aad = 436f756e742d3833 +ct = 200afde88045125efb6515a23c8caf595f05a35509095a967378bd84e5383a306f72f6d5cef6af15c4563b554f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[84] +aad = 436f756e742d3834 +ct = 4b4843954a9e2ba61595c5d2b71b4feff5c84232e53d6593a702dca7cd0a5ccb5d0d3725d7f9795ba1e7689b49 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[85] +aad = 436f756e742d3835 +ct = dfb69ecc70667ad3d2adf8d263d012cb44235778a61ccd579863c6bb8b2d2582cf1a391de20f155b2fbb84ef2d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[86] +aad = 436f756e742d3836 +ct = da056aeeac653289bbbab6a1aca568ae68103d1cb1295f7fd5491b2e285d26e0ce4502786495cdd6dea5119050 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[87] +aad = 436f756e742d3837 +ct = 51a2ddf0c656fb01e203dd54bd80f2626727c33a37aad2414e3fe5e07a9d9c53f7f035924c89ae068bf8005aec +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[88] +aad = 436f756e742d3838 +ct = 95a1a85f709d79b0a58e7116b6323ddad572c165ffaadac7ffa9598a262e30522603d4fe1761e42408c595d0f2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[89] +aad = 436f756e742d3839 +ct = c4c2c129dbbfe2b327352ef4a137159de3a85802c4930b744134a62e35868f3722053fbaa9a5f1cb16d49592ac +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[90] +aad = 436f756e742d3930 +ct = e5992c2caf9e0596fcd502a4b554300fb454a26ba2a99e5fca0e8c0f2a1d640726e322e41986b600b94f82e8ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[91] +aad = 436f756e742d3931 +ct = 27887d96745fa8c476b816c1e8de4fc7389079baed2c0c291af27f9b802d49d768ab7ee7d8b8ad6a4b4efdf081 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[92] +aad = 436f756e742d3932 +ct = 49f4ab17cc03b6e18d393b56a3860e9d88f7177fad47678c94e15da52f3aabbba208803c1d3ebe630385a612da +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[93] +aad = 436f756e742d3933 +ct = 0aa5ff588989b5f855c507fbe0b002108bfa9aba5d3459041c6282216baa58b82a54e81ea4cd7ab8a6fc5d239c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[94] +aad = 436f756e742d3934 +ct = 98b19c082e948172ea6a0c2e7bd1b99adbf828936f6d2b1b356fc4bb7545839bc56d81f7754f32110a768a908d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[95] +aad = 436f756e742d3935 +ct = af857d081486a28209db9124f78e6bebb651854092483d7b74e0c26b076e8d848918ecb6c7ebb0a3b86f31b54f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[96] +aad = 436f756e742d3936 +ct = 7fb0ebececaafa792613ffc21ddd744cce2c117a7fb4f7dd98630d5aa588557502835d75375fce13af191f2c1b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[97] +aad = 436f756e742d3937 +ct = f5c519e52b8ff3f45f42eb20df56c11da4c44f65b14518b7d8fd663517cc33121f2606d7d0ebd28965ca7c79f7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[98] +aad = 436f756e742d3938 +ct = e215ae3bc8168ae5c1e24cd9ed4ddefee8a663813c98aaa94c97fc7299e27b749e30b63e8a63ba7d66a397c8f5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[99] +aad = 436f756e742d3939 +ct = d3fc389d3a47d3b4f57ec7bebe6df29561d5fd0d08fe087db6bcf11c3859cce5e31a43d123d3a765ae425db2e3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[100] +aad = 436f756e742d313030 +ct = d559c490d3bf31b205c1c24df652bee186bebcc9bf2798f3e3839a171765d4fd6064cfcab00d0a4fa924bd77db +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[101] +aad = 436f756e742d313031 +ct = d94b85acd8b65f6c30d0928c4ab64cfd20b68cd32b6e9c66085255d3adfddff964f21f6a6a0de506b3d0e60afa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[102] +aad = 436f756e742d313032 +ct = 844d58bd48a973956b27134c63c95abc6ed159671601f69b49e07d372a9df1c754c68ea906c4826d40979bf6cb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[103] +aad = 436f756e742d313033 +ct = 98032e309da113a76dcd4ed0a1a4c1f912701b39a744070bebe648395d67cb4d7e45862a8b1e0bccc068da3658 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[104] +aad = 436f756e742d313034 +ct = 80586eb97612a4216cc17ae8a28e0f53ecc59c09cb51d48b59c546e067db7ca9080656297d797d1861b3f31aa6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[105] +aad = 436f756e742d313035 +ct = d881138799714f3c37801f45169a681cab1ca82c05f7ec3bbcf9dc46268129dd6d06696fcd0441bccd0fecd084 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[106] +aad = 436f756e742d313036 +ct = e22d4de220344386a58c2c9227c390d64c629c896db4983c719117a3b296db4b8167d022416dae6e2577a1c831 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[107] +aad = 436f756e742d313037 +ct = 1dc52775bf6b3039aff1c911e795d0ff4ff8d33e11a22af4ded075c5d9c3d32082fb29e30b219776ace8e9108d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[108] +aad = 436f756e742d313038 +ct = 319f7752f2922e1998b657deef0d60fdf8be55774ef2e092d0b14cda85b53fba177892cda90eeb8484f209ff67 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[109] +aad = 436f756e742d313039 +ct = 6bffdd2a91a76ef016820755729dd1cc762e3b96dd4e21a1a07522384dd59d027f4fbbade6bea645ceedb7cf3a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[110] +aad = 436f756e742d313130 +ct = 11e601289456e29cadb4573105efe2d186915d7f1c45b77dbd2fc21d1ad78b9ba57d5a48f0713c46275eb61e9d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[111] +aad = 436f756e742d313131 +ct = 4fc545841eb688bec47b35667bfca116d95f075e710fb3480441c4e0182f7d70b87fdcc4325c79b36ce6a46c8d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[112] +aad = 436f756e742d313132 +ct = f7097d2cdb98ee9eda11bf59d64b43aa10fb8b81b027df316488664f6720cf582b2ed8748aa1b76bf476056d68 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[113] +aad = 436f756e742d313133 +ct = 3af5a80b57cf7fdc0fe58c1d86ba214d79c5ef1412948d8eaa4047613b5b4e6bb65808fe2fcc559aa0fd6c0ce6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[114] +aad = 436f756e742d313134 +ct = 073638839b556b5f816e00d901a84eaed65a1d0f7fe71bfd1c25d09a44a03cb89cea8c194bb497eb04293ccba2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[115] +aad = 436f756e742d313135 +ct = 9cbeb946854deb363f3019e125cb4eafcbf05e29355736fd3c46358db24a63a97c727a49f49d89ae0b8e5c19a3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[116] +aad = 436f756e742d313136 +ct = 02aa1edf942b970989451f81f00521cbde12a481a59ca407a5b0ab61ad25f861535af165f4c09dcdf8cbe6f4f3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[117] +aad = 436f756e742d313137 +ct = 6f37b8476decd18a872a1662eae5906c0ef03bf6d1c6c33965723de049c54ddb7075c67b1330ebe3ac9ed69cfe +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[118] +aad = 436f756e742d313138 +ct = e4b262588afcabc486d0dbcd4b84ce500bd171e88487766bb4d63e6572c2c614ea75cbd81818c42f30b26232a1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[119] +aad = 436f756e742d313139 +ct = 662e4486489c51c83574350ae1f76eeea80ef585d7232a4db6f2ea5fb818d59e5219a754b6b5a4d86012e9389e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[120] +aad = 436f756e742d313230 +ct = 5562be7291f09cf9b3c9e7622af65846baefa84b38a69353084656c9681bc3c33b7c3ec6d1c3c0111de711b8b0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[121] +aad = 436f756e742d313231 +ct = 710caf513593d917cebb4a3d12a49f47b4316540f8c8446db7abc82da4710d43323d1f9fac121c36e39544c34c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[122] +aad = 436f756e742d313232 +ct = d8c8ef69c4ee6a0f820d6a8e45403fab4549192aaaf48ecb56cb3f2becb39657c89ddd45d1dec4972551c5cb19 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[123] +aad = 436f756e742d313233 +ct = d77337383dae131898513e758d30af2f0800a418668a6d159670d26d2550e92703565d84babc97014e517d32ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[124] +aad = 436f756e742d313234 +ct = 8904b0c8f8dd8186e9434f24b62e28f9109caa6f74ba9a1881e5eaf76fd52904b969bb6dbeae9fadd82a4ee832 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[125] +aad = 436f756e742d313235 +ct = 983be08bed47991c01a1475d5dae7c24b20cf54ba0d7efccfcd5fd03567bccf7d2efb4668fda9b3e0f4641ed60 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[126] +aad = 436f756e742d313236 +ct = 0e639053bc508f725b7049bdbea8e4e14439d0b91208ec0a5ec3a2af4b9bcfdcd82a1cab379280af9401f4c87c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[127] +aad = 436f756e742d313237 +ct = 59836a335a151ef278be252723abee0953fe521b7187f523b03690526060e27097e0387fcf4d54347a5a037595 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[128] +aad = 436f756e742d313238 +ct = 9d69bdc61e64e2bbb59ab52d51a5d6b126e9e7b2106198fe700381c8dc35064c9f3de37bb360da618be14c20de +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[129] +aad = 436f756e742d313239 +ct = c55c37cad984284d634ee73db6eb5a76a4d683a86deb2f53be6cadf460f84a1a60b5035f3a0ca45b321bec43a4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[130] +aad = 436f756e742d313330 +ct = 755a83c6d6a702070665eceb72f71d1e9a5ba1223445a251f8be5e3e218103b61f1926be9e0a86efc1212fba07 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[131] +aad = 436f756e742d313331 +ct = 6b7907669ff3987ee9c3ea832b7b19abe12623b141c6c1c4c6d6a49000026b3d90232da644fbaee197ab67df64 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[132] +aad = 436f756e742d313332 +ct = 1b32957f79a49363d4d667c051f76d8ba143207e4a91e870dd0106cb506336d261329002c92ef9f121094bbadb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[133] +aad = 436f756e742d313333 +ct = fb489163a7e7ac0b9c2d731919b0e484eb2d31fc9a5cec166b2dba01d6f18589e8da0c892d3b45dcb2a8ee91fa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[134] +aad = 436f756e742d313334 +ct = 2e5e5092c57963424f18ac82cd2813f727f8a26a155f71e32f4e09d6887bb8d21695da3215acbcdc13c3514cce +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[135] +aad = 436f756e742d313335 +ct = 86a7d68707aeb690f327bace44b39f091635626446353652dde9bac18e9a2c4c477557052ba3bcf801b976b608 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[136] +aad = 436f756e742d313336 +ct = c1bb44d1ce3a6796ebc9cf92d252de0e711336b645fb1f63459df7a3bed93d2fd8a76bf80ea3004041ad075a16 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[137] +aad = 436f756e742d313337 +ct = b49e9cb962459433d55d940628e5f4ca0147cdfdbd63a8dbd6fadcde9f567be0d84f766bc0c309e1af83171155 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[138] +aad = 436f756e742d313338 +ct = 3c7581c6b7cd65668f29f99ea81ec939bf926e80ce6a585fcde3d6515d2a94ef5ce6e625acad1d6d0a10d10f5e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[139] +aad = 436f756e742d313339 +ct = 1008b16c05c29ba352d69570147f63d7588115d43c2f4272d6d208985d3302538b44786f27e6179d1c8ba87d46 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[140] +aad = 436f756e742d313430 +ct = 6d10b989a058a5a9f08146519fc37dd98a54821a90a3340b93e3013a2ca87fae8a30c0d6dd633116516df9c1ef +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[141] +aad = 436f756e742d313431 +ct = 7ae87645153c2b643430bfb2f34ddb268381ec60e1b895a533cf4e5bf91166258f078f67f5b14922090a3f27fd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[142] +aad = 436f756e742d313432 +ct = 6e52e215f4abd43ab4b1bea110953e5da9e9a6af452373f1eefe86ae1657f0f63560c394519f2c16294cd55825 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[143] +aad = 436f756e742d313433 +ct = 7346f609ab37a2819baa8dd5151bc0b60405dbe83b84730794f1efe0cf2cb40777a110095f23aee9adbb8e0e36 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[144] +aad = 436f756e742d313434 +ct = 90b135d13e01f5b2bd1a2fe275e771e960b1ddbbb7f8f297495a79cf0bbc221ffb6949561aa8e52934e654e653 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[145] +aad = 436f756e742d313435 +ct = 9949b6ec08af333d9edbec6f24d1492b4c86ddfad845ffedbdb976095a653f050aae63d2a9118c27d9cdf3e47e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[146] +aad = 436f756e742d313436 +ct = 40edc2b843da05fa20c84b7e1051f623afd235270fcca29552cdff69c2f727277a287dc3d7d4906b5f0bcef44a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[147] +aad = 436f756e742d313437 +ct = 0365c963b4ea7da34bba7484e803fd7b825f858ec3352610361b41d0c589de508e7b71296c08573018a78e2f59 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[148] +aad = 436f756e742d313438 +ct = ed3d116c4af961f795d735338bac2b14170dcb5c3e6e2696804e55e3bb65eaebc23ae875268b520e48be029b94 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[149] +aad = 436f756e742d313439 +ct = 89752e534d425a179b43616db8fe503c4ee3fc6dfac8e85ef984565044982abcc7d46212c607ed81041ca9b85c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[150] +aad = 436f756e742d313530 +ct = a988260aec1a06011b2c740bfc4cae0482eabfd191810cd2fb95e342104a14d0d95176081d9be161bb597b6f00 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[151] +aad = 436f756e742d313531 +ct = 7363c1bc299398934f4fad4185c93573bc80b367c93f7605ee2ab97a3b18179dc4761177c0e2b0c3d87dbd7bf1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[152] +aad = 436f756e742d313532 +ct = 83cd7966ea988b9fdb064c1282d30d41dc9c4f37de5ec390ca0a1d55c508bd0d3af1b481f64541830cfb9b0e5d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[153] +aad = 436f756e742d313533 +ct = c5a20c2cf5336d791e45a4e97a1df88779a79cc259ebd9ad3b7406c2f42f655ba5a235e4f3e6687b21d21c129e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[154] +aad = 436f756e742d313534 +ct = b84401ad73b092c5be750404eb74ad48c5f2193835495fcb2a6ac8f0bf9433d92d8d3c17f0722e3cfaff428c39 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[155] +aad = 436f756e742d313535 +ct = 233c14c55330a706f1269f1a81c7381779c14ef2cafd12054eaf740bc9ce13f7849a0143ae9ad5924c9c31121b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[156] +aad = 436f756e742d313536 +ct = 4888309bc44a04ba1708d59d30495247c0eb1e55e68d3d814d8eb8d2d9df704babd92e5d2a3b61cf0fa0599570 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[157] +aad = 436f756e742d313537 +ct = b8be632847c77c4c9bd4d6e448942a698a23a630d7bca02e4eed4e79b146032d60400aa41d5bc1d82799044b3a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[158] +aad = 436f756e742d313538 +ct = 53497421c5eda1f339ddafb9d21842d5ba7e1e93909308512ca76044b5f18c5eeabeae194c434a3ca9b6573c22 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[159] +aad = 436f756e742d313539 +ct = 2bc98ea9344da4e9beb2b19100397809f75d5c4fe960c7616380111b5831096de6155c9fe8a16ccba73feae3b1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[160] +aad = 436f756e742d313630 +ct = 61205ce18b656b2861cb38fa0ea5d91de1e27df60fd23c476a641ffbfa7eb0c50ea000962e2d1f1796bf99aa8c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[161] +aad = 436f756e742d313631 +ct = a6c01951f5e2a019ee77b4028ba33c2e204d21563795b2c1ea78271280255f98f1b903ab05d3afd089439ae6a2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[162] +aad = 436f756e742d313632 +ct = 5c1dca44abdbcb6c895800e2d0a0e4112bc1b2a81e1953d80268c99ad235da2888ced02fa53ab60f2ce737fb9c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[163] +aad = 436f756e742d313633 +ct = bdc83d3cf8044b9b91ba3c4c4c5470c7bfffb1cf44762b977de0c79635253d71b8a9ba32d82ad5625e23ba3046 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[164] +aad = 436f756e742d313634 +ct = ea6acf6fe36fc0e728874232c30390a5e2fba7e8ee95e9f2ca719f980bc6203deaa5d704ab3f8ef47ba3cdd789 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[165] +aad = 436f756e742d313635 +ct = 3b7823bb868dfccb41d9460742d3e845187ad100fcb1b4c0fce18c58bfb5e48d39f02a630cf2454dbf50d1ba85 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[166] +aad = 436f756e742d313636 +ct = 6fb22b75d0a26ae07bf894e54fb066976b45a386c4f616b13c48923613ad5b87a13dece0cfa6e35c4837ba73c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[167] +aad = 436f756e742d313637 +ct = 0bf18ee332538b314d98a0f850469e2c54827923565102712558bb07af9a6fb0297510dd46d0975ba2869a4170 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[168] +aad = 436f756e742d313638 +ct = 6d823e5a8fd645b8f53dedafd7a592975d8e8f0f124c0229d7c8b6db80b043cb2365f39bd8d63d468c70cba26b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[169] +aad = 436f756e742d313639 +ct = 14e7e71ed3a662f1fc9d4f9eb9432ac788a125ef1d0d15941d98d0db8026eb3de49758d4001945046bc8d0fa7b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[170] +aad = 436f756e742d313730 +ct = 1c4ede11879727fd70080e8d33106f1319a5aace4e35831d143c046f2acd1640321b9df29d606ceb29b479f95e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[171] +aad = 436f756e742d313731 +ct = 778ef01e05e75d9ddbaa5e2732797973d0a0d40e53310f829b2c7fd31f96a50fdcd13229db146795cbfd6254f3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[172] +aad = 436f756e742d313732 +ct = 25807db1f5a3a6481a240dab4a8173601600e577cad5703db9973ae5a3cecdbaa454a57064ecd7fde4f0ca5aee +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[173] +aad = 436f756e742d313733 +ct = 64cc1acc033bb52a4ece52d51500052e41c4f716a6b93f92351557184ebd3ac2f1c8dca0bde406a36f8e6cb03c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[174] +aad = 436f756e742d313734 +ct = 1414cb7aa19771b187ab8847f9bfb3d8fbea142ac7e458779751eb357ea12fe5789aabfcd027576fcbf60a0baf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[175] +aad = 436f756e742d313735 +ct = aab3afdf79e28db0ad509fa8d64d35cda533a1da3e6a76a14b2ac1952ac2b573adb22e5c7ccd4824783f35e5db +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[176] +aad = 436f756e742d313736 +ct = 381cfc887f4a33bad777c29c9d706ca8349a887f72bece0826e49d87e964a5307e86d24f09c104cdc30f18fa4c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[177] +aad = 436f756e742d313737 +ct = 0f98fc2a6d41379342df0dfeafd13a679dc166193bb40316383aee3397ae7606798be7414f941fcaf8c7136679 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[178] +aad = 436f756e742d313738 +ct = f50864b8e23d0d56476113d7195a9878abcc16b1f1538970dfceea4ce3fb738ffb9af5ace7204fff3d62e2ad46 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[179] +aad = 436f756e742d313739 +ct = 123ad7cb5df5d0f172f1767513dc77543851ad63c15b90192a00f80c417079a02ac7838bf13640ad79171e58ab +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[180] +aad = 436f756e742d313830 +ct = 00ff6ee0d24c38b8ba9073824b547375381fe08cd921c4ae3ce9dd6dc51d595a64b2ab61b268e4883f12322e09 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[181] +aad = 436f756e742d313831 +ct = c06f35ff7ed289407ccce5100e43833c86248e35be2eb60c365c87e2e189326b345c831ff639219bee69aa9148 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[182] +aad = 436f756e742d313832 +ct = 4adc642f976ec1de0e1177f0ea29f0da33f20e99f5f957b1bd219da9a2a90d6f38e8194ea7812b7b7dd6a2ed7f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[183] +aad = 436f756e742d313833 +ct = f08f65f247619c09c77f0c36b873d423800cbbb68b6012e39182be10f03fd05cb0df4a9063b8fea215ec613014 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[184] +aad = 436f756e742d313834 +ct = 795a1860ccd2777ec87e7691c8c7b87fa60905c973d5b4cb63fb4c1ac2d64bc2ebf5f3baf43b5388ecce3e3c81 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[185] +aad = 436f756e742d313835 +ct = 4eb24b8ef9de11652206ffd21185b00cb5738d4d3836422f64ba3da86e0b512141434cd91b189b3ad178975817 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[186] +aad = 436f756e742d313836 +ct = bdc4f22e46b5e4bec8c7013d3e2419fd36b47d8b3d4323c508374c97c2673083a550a5a8e425b3b3f2952449f6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[187] +aad = 436f756e742d313837 +ct = 0d2faa408d419e3fd7c39175b5052df2c9243843494f27e29721533446ff551ebfead78f2a19b8243a33915c3d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[188] +aad = 436f756e742d313838 +ct = 08a2211770ded14e210dc9a5a711b011aec7283624be62d67754b7c0e37bf88e947180b7ba035ccccc754e7139 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[189] +aad = 436f756e742d313839 +ct = 706b1f001fa04d7639aa1838e6b94c710231a25f10d30426f098965961f13be8ecc9b9031b120e4af5652b1e27 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[190] +aad = 436f756e742d313930 +ct = 3550a384167bb99f123c4ab49ecd62e2a7c21b151ecd6dd0252465b45d532402aaf767f139708abfa31857037f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[191] +aad = 436f756e742d313931 +ct = d07ab8c75beec6f9b3bfa5b580aeba179c93f607828f43bb1acddcd698b12509db5a08f110d1d46fe124953e01 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[192] +aad = 436f756e742d313932 +ct = fe1c8f5e53563225b7192250e3f07bc47ae46fa77c441a2479fe28241d2b83ac3f8ab24a8b16ea628f8f7dc138 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[193] +aad = 436f756e742d313933 +ct = ca0001a376ec98bc5195d861f61d699fc08ab8e8933becb9a1d4dbb46092439e5bde711f817258a91ce864a972 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[194] +aad = 436f756e742d313934 +ct = f5ec0401b4bb76ad6664bc88e104c84ab9e23aa3df077d4019d6e81efb838f95bc6e4cc0950db56dc7e4415969 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[195] +aad = 436f756e742d313935 +ct = 3287b895c5ab198fd61e498118d4c91ba8559c5a5feb2e1e1bdaa14691c8fa3b868a3c6962aa6905f8421bc141 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[196] +aad = 436f756e742d313936 +ct = 887a2c0746336d67fa4edfa866313be32b3950013c0aa3eb2bd666a6d277060f0f5913d8c0cfcc95b2e70c29ee +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[197] +aad = 436f756e742d313937 +ct = 9e246a263d6662f70f8d5a05487cfcc99965489ae233c209262bd0ec65b4994e1d7dfcfddef63a956f3cc91193 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[198] +aad = 436f756e742d313938 +ct = 5fe3f5242df92c284ea2806c0492e5c47837921cbfd8c49d5769ec8a54206ca34156358756681664090a8ec2b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[199] +aad = 436f756e742d313939 +ct = 726f0392cbd3f225064c5408c90c7486dc6028deb9fb3e60ebb84ddc0b339ad872dbac9aeae61985a3cd03a5ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[200] +aad = 436f756e742d323030 +ct = 82e3074ee6f828726fd8da9cb54ff24181e01a379e01bbc1d00b4ec69937ac24dc7e055aa5e9924531f907fbcc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[201] +aad = 436f756e742d323031 +ct = 8383e31c4dfc253cb64eedb29bb50e3f03fb7d88216146cfd8bc46a6e24b259831df8aeefa9484a2b1c50b713c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[202] +aad = 436f756e742d323032 +ct = d1064f889c0a1c74c9e812980ddeb4db85ccae0b770d0d9797f79edc8924c3af354c92519566b1856e7d4da7e1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[203] +aad = 436f756e742d323033 +ct = 5cc0e2246dc23cbcdedc6be5ff8563ea527ab0b7976016eb23d029f359816c998d980f4c30668c662260b17869 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[204] +aad = 436f756e742d323034 +ct = 4989fcb35d8c5d52e61f4a1dbd7de520fe36dce0bacde2832689f76b26ddd4ca326576562a939474b6813c0711 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[205] +aad = 436f756e742d323035 +ct = cb2cf08cf6eaae26dc2824aed8b93627c570956427732c9e18e8f77b9c255d0c01cf546d9f80d7edd594c5978f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[206] +aad = 436f756e742d323036 +ct = 7559eddc8eac912b20fd672610acd68d92f8e0d608182e3689542d69d8015facdf09ccd6e62ae902d4a7a31005 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[207] +aad = 436f756e742d323037 +ct = ebe4067990f4439d84f7684139de6fa2f0abdcb9002738821e4e6c2392124f17ab77ddfec293ad790044b06a94 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[208] +aad = 436f756e742d323038 +ct = b2442c7c263cf07bc84857281860c2b5e3e12865bfce9ed32b0f86af630d718f5b14da335658e256de2243445e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[209] +aad = 436f756e742d323039 +ct = 2ef92ede552eb2a291d9dd81034f2b47ce79f6b9e88f87cc84b0c460fb66535197f5d3936c1b99b5ba66c0de33 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[210] +aad = 436f756e742d323130 +ct = 183220a6989012152186d775d6f15bbf56cae846e3a6c534a863b4287ab778851315d24621defe982a4c735759 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[211] +aad = 436f756e742d323131 +ct = ec0704f1a68006acc6142b6294936199228144706a5cf730be95078585686c1501f57a97d2e7a1ce561dadaa5f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[212] +aad = 436f756e742d323132 +ct = 4f182c1f81ab60e667c48fc78fedf17d3f4be43479956c06871b9935a28db8ef1fb91ca7a05cf06c6c16bdd3b0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[213] +aad = 436f756e742d323133 +ct = 26da513d75efa918a650d24c738473713383f129ce85ad996513db0284dedfba7b04def48d985e3f77b24f31a7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[214] +aad = 436f756e742d323134 +ct = 57966eb046bcd25b0f530cc8f844ba2999a0faf954e7106f40ce041d97f99e69d71e0bb20034a5ee46790753ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[215] +aad = 436f756e742d323135 +ct = 554122776faeec90d03157835252732eb116d796603cc16c075a89a01b943f80f334bc2b584590de10a082ac2a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[216] +aad = 436f756e742d323136 +ct = 4a93387559a484b91fbd298b3bb2609270c48feb7a31c1168c2c229bf345aeee4bec0e4b71271413bf9c211c94 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[217] +aad = 436f756e742d323137 +ct = 725a88ae41bcab900b27b92450c3cc081de9fcccffa58afd0f23533189443d04659d8c6eda37f10fdf0a1573f3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[218] +aad = 436f756e742d323138 +ct = e37ed1b71ab95aa52fc9ac19f0a0b0449797cbaf5cc73f0da89025d52e11481801dc3de65b34845e193391775d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[219] +aad = 436f756e742d323139 +ct = 3539ee61e9a5d7b83e44c16e7a814da6fb440a55f6548b4df7b9797309bce67f63959a8a237c59723cdac3ee77 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[220] +aad = 436f756e742d323230 +ct = a192300578ca40a4d88bc195814c80725b01d479c1c4e7140c61963c5aeb0939e2fc9100dc0893da4a4ec0fa62 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[221] +aad = 436f756e742d323231 +ct = aa9cc7b2224b57e280a0e56bd4a8dcacd4981d7516a4a7e526e925bd97260b6b3c75427da747e006bc2ddf3ae6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[222] +aad = 436f756e742d323232 +ct = eebe5ba2f3a25eb3602188a6fa7d7600f83b31e447e0bd950ab5064e6ce714df761b4599ba7818c2cc80365b20 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[223] +aad = 436f756e742d323233 +ct = ae81d85a6a29eb394bd83ac3843eb61cd5e8f322d639c3a5b8ce3222c85ef0b058d1c34695fb783eca8aaf3658 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[224] +aad = 436f756e742d323234 +ct = a3265e946f45a0dfc2d20dafaf4d65cd4595c9c9c9dbd3bf7745bdef26f35d1588906e122de8143b3e316dd43c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[225] +aad = 436f756e742d323235 +ct = b68e78ed1ea01475d0775a6e20be845084de3c7d68c58611fb8c9dda3b83ad980fbc4bf99e3ee9980ebef862ff +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[226] +aad = 436f756e742d323236 +ct = 1a065a204fff91b71d0a8d92858b77cd4d9ab9f7293dbfad8ae4173d6752be925bf7f996d40ceca5099f424484 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[227] +aad = 436f756e742d323237 +ct = ae8ac359da42f98628985f27bc96aa25acc9a9e1354491a8325cbc4a5e17d30f8f77a0275761ec1d7e1c0b1dc0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[228] +aad = 436f756e742d323238 +ct = fd831d62c9cce5a711697891110acede3b5885dba0d1c1333c009a6715402e6dd5ce8d629f1056eb2eb990c798 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[229] +aad = 436f756e742d323239 +ct = 2ab45b2a78a28a874bca7625da63ced2e83c11d9640c428a5a16e311053152a04b9d8db7e1bb58ab60da47df0f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[230] +aad = 436f756e742d323330 +ct = d9221ea8c84f6dffb37fca1211eef538d24e2a180a5e24dc535291faf32c7ccbe03747a1d790d8e00bb1f1f61c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[231] +aad = 436f756e742d323331 +ct = d2cf65a555de09dc505b894dbcef2f72b4ed6fe15e685b41a15182ef1105542c462689bc16ed29c3e3badd0b50 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[232] +aad = 436f756e742d323332 +ct = 6dcc61746a8aa5c549fccec383e9a387039cc4ab617ac1c6b0014de3e02a104217e1c7f404724b8beb3f684803 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[233] +aad = 436f756e742d323333 +ct = 8fedb6438e1d014c4eed849b7497c681bb91fe6491752ee3abb61b6329544aab8896ea1a2b80b6f1291d99cc43 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[234] +aad = 436f756e742d323334 +ct = 1746236a4775e8841dbd4e1a3e95a1b15fee50a9e3b137bc094545989eada59ef1d4a35cbcd90eafa149126de6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[235] +aad = 436f756e742d323335 +ct = 075f3e87792e9ec9f1c7b7f5af2e80d3e6b3db51a319cedf79d06161abffa9ea35d8b56caf2eaf5a6e06e225cd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[236] +aad = 436f756e742d323336 +ct = 7c71f10dc7f02913ae8692e93a886119f6b5940a9c4bdc24850502dc163939c5e74364780d414774a0b0b6e757 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[237] +aad = 436f756e742d323337 +ct = a7660bd0d3420f847c09a034d34e086049c70baf1d183fe58af2e4d8f581eab7fb043ffe2b75b54f24b51ff8c9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[238] +aad = 436f756e742d323338 +ct = 173ea65a00440de994e2a6751b3d553641c57b4bf2cd9f41b10e4bb16c6b2d6c5ab715dd970114b6486d1f6a6a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[239] +aad = 436f756e742d323339 +ct = daf7fa1a6a83741e82f13262e7730447ee1c1f29cc60810b4f0f10001ae0c37858db6a3aace4a03f3e70d4ec5b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[240] +aad = 436f756e742d323430 +ct = 6a581b9771b748adbaa26d20085da812933d5ecf2ab2d11dee1ad560a2333f9182d31f017f02ed6b47b2fdc50d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[241] +aad = 436f756e742d323431 +ct = abd6668670bdeaba122f577eb635e56bab0f9f861b3223e8e17facf19ad716a9457029a09174791322810ff81b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[242] +aad = 436f756e742d323432 +ct = 7a2f1b4b5cab79ef46c15d764461ccaa4124cb98f019782013904877ee830de5632c551ddb8119cdd2e38de5d7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[243] +aad = 436f756e742d323433 +ct = e97b38dc3a965a1b2c7eac9071a4ac388145a9fc3d975c857859d3cc73574c65bf111ec3c8155ebec8a5d5452d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[244] +aad = 436f756e742d323434 +ct = 6301deb287ffc74bf231704ad1a59aa60cb470953fa6bb7d0c03cf69fbc8c4fb89acd0162dff353756a73d6415 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[245] +aad = 436f756e742d323435 +ct = 1921a34039e2579c8e86fbdc731449bcec690214d157f3f9c528102f19d228ca36e8eee061f733e0eb64bbdf50 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[246] +aad = 436f756e742d323436 +ct = 4943f4dc007e9d1366cb4efbb5e71cb19e70ab4bd917f07770db6bb956c7bc00fef39fb5e7f1f5f0d116552147 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[247] +aad = 436f756e742d323437 +ct = d45b763713b7aa7d36da691a52a1a6edf128ba72397fd20d2ca59afaf6df53751f04c5879e9a4118298944110a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[248] +aad = 436f756e742d323438 +ct = abb4bfa463b825b00ce013d965cb8c232593819411ed494ee6087932d4c088f3c64b0e75585726dde1b28cf37d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[249] +aad = 436f756e742d323439 +ct = 17ca4cf2e6fe5ac0ffa1409a272e29766acbb73c3454be25eea8e3ceb5d3c00a37d9ff3b7400daa2039cee9d43 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[250] +aad = 436f756e742d323530 +ct = 8d73d3eac79d6462dfd82bc0f7a0a2532e2903a88259b3891a5622be390ccb882384557704ae7866fc623dfbcc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[251] +aad = 436f756e742d323531 +ct = 24262541ad0b43fb8f007debefe2d0493863fe5ed9c51080c6a08e5cf747a0ff2c203b2c8b22e4647a3de753d9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[252] +aad = 436f756e742d323532 +ct = 624fc58b855bda904dedecce0391e91b8cb2ff6e45f04f56311512b19de81337a6efa8685a33c36b5642fb7d65 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[253] +aad = 436f756e742d323533 +ct = 769ac35e2820405b0bf9b41d1390a57665230606cfd3e61aa4b3780fda6244b2c3671fac7e67cc2a727d671f3a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[254] +aad = 436f756e742d323534 +ct = 31aa9fc2c5276ddf3e045df4a3c471146e834a7e827988654843999f0d0c1507c77c57069dabcef90a286df87a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[255] +aad = 436f756e742d323535 +ct = 55d53d85fe4d9e1e97903101eab0b4865ef20cef28765a47f840ff99625b7d69dee927df1defa66a036fc58ff2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[256] +aad = 436f756e742d323536 +ct = 42fa248a0e67ccca688f2b1d13ba4ba84755acf764bd797c8f7ba3b9b1dc3330326f8d172fef6003c79ec72319 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# exports[0] +exporter_context = +L = 32 +exported_value = 28c70088017d70c896a8420f04702c5a321d9cbf0279fba899b59e51bac72c85 +# exports[1] +exporter_context = 00 +L = 32 +exported_value = 25dfc004b0892be1888c3914977aa9c9bbaf2c7471708a49e1195af48a6f29ce +# exports[2] +exporter_context = 54657374436f6e74657874 +L = 32 +exported_value = 5a0131813abc9a522cad678eb6bafaabc43389934adb8097d23c5ff68059eb64 + mode = 0 kdf_id = 1 aead_id = 2 @@ -2096,6 +3147,1057 @@ exporter_context = 54657374436f6e74657874 L = 32 exported_value = 7c5ded445732c14fe09727d29b4251c0fd38455fe8440571e687f0886aac94d2 +mode = 2 +kdf_id = 1 +aead_id = 2 +info = 4f6465206f6e2061204772656369616e2055726e +skRm = 47f1eee3670dfaaf27c30a83d06ee9f257af174727c17b35328ef730dfc1cd81 +skEm = 805b278cabd22c9dbd461bf25771703eda4950ed3ef35b369163097899555356 +pkRm = 3668d659cec6f338f4f8dc6da6733118d2a633f186a3c1415c895111a8eb7c7d +pkEm = 9e59f4b1fa5c876f684765290c34e51145894cc4f244342b9fb1a4bdfd8bb426 +pkSm = 4a91c3d0893433f5e31a79fc520f885527a1bc60bf2b0c72693dd7f0b2e41a5a +skSm = 98fdf9b9773578a79d4ba82fbe483c74cc2e3b8d9525d148a18969fd79a74876 +# encryptions[0] +aad = 436f756e742d30 +ct = 10b964283ac2cc0bdc4c85ab617291b446bf3832e9359b2c3a0facc50ea75a3c1afd08aeaacd6041d02eb560ec +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[1] +aad = 436f756e742d31 +ct = 83b24287a5ac672289ccebf5ec303d3c0a85bc60bb7a748014d85179b51c7552ca93a70817ee3140442f92e23b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[2] +aad = 436f756e742d32 +ct = f42d890891825c1a57dea5a66baf2c940126704682826bc7c5caee60ca71578d767db256b0c2a4051bef1236f7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[3] +aad = 436f756e742d33 +ct = fab3f66ea4273bcc0e40858c346f4e12067b685dc8ad6d57f3d398bb3035c4144b578991c99df545c214a53373 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[4] +aad = 436f756e742d34 +ct = 470a09a528036f80a2f1e23bced44551e5da71dff490bd7de6e01e2eb412cfe69be650b201f10e55a9c289e712 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[5] +aad = 436f756e742d35 +ct = 96838a987715414de7048ce44f8bd0cf7634638d4d4ea25748baf44c65bed08692a8442f060bd87def25098d2a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[6] +aad = 436f756e742d36 +ct = 2c088d57556144930fe7f52d49d8a451cea3aa6e307d794a034fd5fc91e69f56c8c31464dcfa26ff1b5782c80f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[7] +aad = 436f756e742d37 +ct = ef8b777272642c61eedb8bf809e92e2ea35f92a53f09b131e7f7a6004cbf0b7e6c528d27567638cb54f86fd89b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[8] +aad = 436f756e742d38 +ct = 953a2067e752c7355f30364979ae55efc9f36346e6fc2c51c5fca956a6367080b045381612cd85aea2b41f8291 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[9] +aad = 436f756e742d39 +ct = be96bd02bc6cfada4561a2655b4214d541bd812b0ecb45b4446d93785287a68dda16dcda9790603327996004e9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[10] +aad = 436f756e742d3130 +ct = 4b553762b63d15769e5b0594f87971776044b2e0ed4b58aa6379769a56334f87361dd5ac710b0a4afdb61e42b2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[11] +aad = 436f756e742d3131 +ct = 1b92f016ae4ba14d4662d6f65f2cf3d1df4b99bf98b1c8b7a7f9c7d722085e5a2cd7f242c4680dd896c08fb9fe +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[12] +aad = 436f756e742d3132 +ct = 93cef4666cbb4c191fe7791b0dd46cfd09c7a9bccd3dd120e31e1592379c5112268661c738c27fd583d1a69aed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[13] +aad = 436f756e742d3133 +ct = ec195f886d5ee74f79eae5cbd1b46e143a92a598b1c0b585c709d704d97ff256cfba127afb2a9f1a23f26ad6ed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[14] +aad = 436f756e742d3134 +ct = b7a4f0af656ad0afeb7c3718971940a31f4822125943171520981b17473a5ee7b7f1192478534db62ebb79e546 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[15] +aad = 436f756e742d3135 +ct = fc8b1d895f7d85c4a07e756ceecf6add2141056a80e86eabbe62feff6cf69db47d6c3e9735d8c5befa973196b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[16] +aad = 436f756e742d3136 +ct = 328ed2e5b69f06a3ee88aac0851952c7723f9bb28370db85a300b01b5a2d41c7355bc2286784cd0fcebc433ff6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[17] +aad = 436f756e742d3137 +ct = 19cd1196f10eb2df0b1fdad07c36ae1ef483d66c0a474cf82447d2a8906093880b1d8360c507ce0ea06fa16532 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[18] +aad = 436f756e742d3138 +ct = e281b6d64b0f97ceee63df5923192a42eed46a87551d476b5e6a01e0a6ddae36415394c3bcb2c2c51b9ccbe80e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[19] +aad = 436f756e742d3139 +ct = d764613d9a6359243a9f37dc8d1b2fb384c9d036beba29aaa99e966f5624300da396952413ef482a5034c66300 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[20] +aad = 436f756e742d3230 +ct = f0d056ca8484082c5e08980dcce8e5bac8503d914bb6662c196dee3778f0ba795d108361e3b82c01883d6b4880 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[21] +aad = 436f756e742d3231 +ct = 47d384a5108791541732373492c339e4001760802862ee2307ed01d8692f81efa8750d940a0f8ecc1d509053f5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[22] +aad = 436f756e742d3232 +ct = c0bbebe48e5980326bafb7840ca6d408a4ab796acf26634991b21c34170c40817199cc71345c2e467acf5cab30 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[23] +aad = 436f756e742d3233 +ct = 0ea456e2deb27ade97571f5c51835dda401585260eec29f29896bb7a6947667cddec9d52fbdd0155d33c0cb318 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[24] +aad = 436f756e742d3234 +ct = b525498a5ffde5bdd0c0c50b0c1d8c8e64ed47124d3ba52b0c5fcdb11b773f568906e5643b390f73abf178860e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[25] +aad = 436f756e742d3235 +ct = 019b344de40001e1d18fae03002be1be4d2e020c32a514ff4d84b15d066cbcdf045490ebfe9e4fe536cc001b6b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[26] +aad = 436f756e742d3236 +ct = 6542b6f3e9abae49d31af2a8871f5260648cb9d3c5ade0d7d3c43ece10186f6b1ab465d71c5503a703aee2d889 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[27] +aad = 436f756e742d3237 +ct = 8079a278f77b5dc928f17125af7f62f0ce040ca8d90afef0de758da1694b056be1efde71258636c8a39a300428 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[28] +aad = 436f756e742d3238 +ct = 2f4cbdbfc8e9e1498dfe1f20addcd16e00fba26f06fe8bf510ce726f4e6e38141a027eb9b930512300ba50d772 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[29] +aad = 436f756e742d3239 +ct = ef6390e3d57f95aeb00e6a8cdb3b545bbffee6755c8215d3b431a7327da4981bc3dc35b5b913b18de0abdbe721 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[30] +aad = 436f756e742d3330 +ct = 0aa56230de06dee53bd6e405bac54899367a1f6d4dc4791f99a86f6eeced0b50acfc68eb49393482325dceb15d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[31] +aad = 436f756e742d3331 +ct = bc0812f89e395491f19b70d43b4ce1be7d0d274352817134ef9baf7d9c5d7b93a272a79350b8bc541997097023 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[32] +aad = 436f756e742d3332 +ct = 86980d73a1f515952156be21c6b42ecfdb40ba67ddc9c8af12dc4afab2e659622f341e84adf06ec71f2c4fb19a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[33] +aad = 436f756e742d3333 +ct = 97205bd532ca8dca11de6245d21fdfac06d6b48fdcbd399cdfc3cd18415a78bbc62bb9aae0ec326fdba7c1c846 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[34] +aad = 436f756e742d3334 +ct = 625be4d9e0e0caa56cf6e7c24ceb7cb336ce4265b0177b93783d6225bf347b84b3c872de9992666d8d7255b3b1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[35] +aad = 436f756e742d3335 +ct = e1957331f9fcab02fa9697924b1a22b7ca36ac728a4bd2c4db20b839987aebc6db741669ed96f63bc52d949f64 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[36] +aad = 436f756e742d3336 +ct = 5d83fd726dd22802afb242f25923de6d55e1a481c1d5041c2dd05986b5be5f72d611efbaf8071fe2bc0d416438 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[37] +aad = 436f756e742d3337 +ct = ec453efb75c777cb1fe3322f3504da40c2fbb613bb4735a02b33280c1383748377bd33c35eae2f48930a6aeaa7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[38] +aad = 436f756e742d3338 +ct = 3a050cf76b072e1897fb498d090dc4591dd06200f8c74e8f7a6b43e455680b32fc831fd7891450c626a847aa4c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[39] +aad = 436f756e742d3339 +ct = cd6a04939353bf21e3c68fb190cc2e450bee3403938db4fe9eb1d826cc15ee1f0b7b32af11a32310c2e4b49e30 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[40] +aad = 436f756e742d3430 +ct = 2242c9f6d2b04a400892c3d7d7f4086f7851489e4bc86ac090ea5723585dbf61bace21248c2643e062329c32c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[41] +aad = 436f756e742d3431 +ct = 6bcdf8d421bd9623a6872b1aea124a4b978312e29d24a3b0f019c1434e55d2de4775b256aa91096533fe51d292 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[42] +aad = 436f756e742d3432 +ct = 4e02b9b212688ca51278baed8e57f3c948d70d096afb6842920b8fe504992b7920ebbd4e3e655ae6cc598244e0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[43] +aad = 436f756e742d3433 +ct = c2acfa09b1f580da4d924247b5c98c3122c09a37b72b5aac9826e579bdf194d7a3d179e15a7085c9fa8c53de19 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[44] +aad = 436f756e742d3434 +ct = c7f6c9d6360f14a124bbee3624e2f03e34b73248576f2c83127eeba3fd9da799a456f27bfffd9211c5a40a414a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[45] +aad = 436f756e742d3435 +ct = fb885e9fb8012b9d801ac0c1cab978b753ec391ececcae9582b360f0c28e6b58f7e432d3f0e020dfe0831231c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[46] +aad = 436f756e742d3436 +ct = b10033bc7cf55378cf7d919a0773bcc79b6878117071674df4028cf59ff3554963dc3f6a5edda250170fc55d85 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[47] +aad = 436f756e742d3437 +ct = 3e62ec8300d4c6d0195a7403ba2d8c70c347a920a9f1051a9825fb5620bfad8aa139940b5f3a91e5409a00849e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[48] +aad = 436f756e742d3438 +ct = a7d0016602e0501f39ebb6f4173005a5732fad028dee2a3dc3e087ac7b43afbe0f486c6267a883f223081dd89f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[49] +aad = 436f756e742d3439 +ct = 93c01585a1d1775f3fd3b1925c26bb6e810842a24bb69a9c2521db72f6d66a2e005bb875a480cccf2eca122d8f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[50] +aad = 436f756e742d3530 +ct = ed18775671121dc68a6413f544a45a3a197faf39c43cc244b32c606ebb61cd1333f830414624530e43c5328216 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[51] +aad = 436f756e742d3531 +ct = 4cdc7b5fbb3c8f392e84b238ab3cdc7b490cfe1476259d0db4eefe53f718f1f6a7a32bbbeef1574ddc41358b83 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[52] +aad = 436f756e742d3532 +ct = b47aee63fdb669daf990181bb75bc094bb9919b2df809615b3aed0ddfdef0235f79cbb95082bcb44f76513876e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[53] +aad = 436f756e742d3533 +ct = 55b76bcd5f44cab153ffb90b809f5cb504bd02f705b6649dcff9917bbc9df878e2265d96591d6d0bd856afd1d1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[54] +aad = 436f756e742d3534 +ct = 67eab42d7d1bd9a03221c283669ec7ade98f5b3a970f7903b9dc160501f643eb614625f35fa89c834d582282fe +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[55] +aad = 436f756e742d3535 +ct = 95d31adf6ca4f047c5097816a6e6cd02e2c952f3d63710cc05df53da29bb37abb8caa037bfa2c50b59948ab656 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[56] +aad = 436f756e742d3536 +ct = a48d3ef0c3f065e7cc4b6ddebedcda1b27a8dc0664f4049521a3c446834a9cfdb76dd83a506c1f6f25178287cf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[57] +aad = 436f756e742d3537 +ct = 57d1902ba96fa509d930d5ed2c7cbd57fa43232b14c7c6fa3f33168fd543f4d96777902707cb02a1282f83856e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[58] +aad = 436f756e742d3538 +ct = bee02243ee8196cdd8470528e5f2a0a366a0c48fe71827c07783192a762506d283c6903419e84404738f27a31b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[59] +aad = 436f756e742d3539 +ct = da1e009146d60483a43a1518c2bd545f21392f98f5d2761b6b54d455d6903ed8f8a7e5794946b1d2c8b46ebdeb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[60] +aad = 436f756e742d3630 +ct = 99bd8213cf3e48db8b0cae6cca6088b3c3f25d8d8a4e1d38b1cecfaa777ca0975b579f2858ad29f5d292b59295 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[61] +aad = 436f756e742d3631 +ct = c49043927a47694c3e0c6095fc3fd7ef19b947b1c15d455504a72286238be0aca23bbb8c78e9c5c066d7d2d965 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[62] +aad = 436f756e742d3632 +ct = d056c8521b101402202aebbd5ebdff1085a1e0f32e177f44787c2f25b47c3ad598ed05a2441002637cb15b7257 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[63] +aad = 436f756e742d3633 +ct = 3790260dba51810aa30b24f7e841c0c485b40f234ae1e0cc66bf895c6fc00e5515b3b4b383844eab29c706c336 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[64] +aad = 436f756e742d3634 +ct = 6fa82757e4a3cd33d8480a35c303250ca6bfbc7584296ce67af456be72b58a9ff310c7ec6a50f86b20a92994f0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[65] +aad = 436f756e742d3635 +ct = 44dfa1d42f6f7e2acab917cff4536463a3e73c4f5dc0c2ddb189e28dd7c3e6b84540b98dc0c51e1f5d00f9805c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[66] +aad = 436f756e742d3636 +ct = 26a22d894060884040677def8afd4502c79873f13c1b4c5e0b093ce0e21e6c07c07106bdab1b1e57e365433a34 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[67] +aad = 436f756e742d3637 +ct = db85091e34637ca4b5d709285d61e13cbd5db120cadef028caf4d7975dd8f2eabf8cc33d0ad6bdd9f4b3d270b2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[68] +aad = 436f756e742d3638 +ct = 294b49e84bfaa136422bde1ec4d15a75cb8a8c0c7b9063d08d798e641c6aa7fde89ebcfbdcf7bce1823a9ff3cf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[69] +aad = 436f756e742d3639 +ct = 93ded3b6c98642921cdd0663bc2f3bd844b6aab133cadce857a06a9b125a34ab62fd21699f834c6c961c567ad3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[70] +aad = 436f756e742d3730 +ct = 41c05ee1b1d21d9779f39d8331945636f0e6214e0293da5c13457cc6e2ac700fe39086ab35fb700225671cf680 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[71] +aad = 436f756e742d3731 +ct = a26d2e109a3dcf33fb46f2283d3427b92275afaa1e8f0f8cc0129e6900e9c3278f614525851e1939a97b1acb02 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[72] +aad = 436f756e742d3732 +ct = 4160b4d94a4c4f08cebf3360d64188de51b2a062463d6af30d8e60844f915528acbf675f86b6517c7b605979d3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[73] +aad = 436f756e742d3733 +ct = e2396d75603d928144c116457245275f48e681f627fda6a888fb02b00bc61648e010d4b82a993c9d882fc9c209 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[74] +aad = 436f756e742d3734 +ct = cf469851b3a16878978082d773079252e7646e3d1c15ce10e11533ea5b89389baf5677679b792337b107d4cf8d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[75] +aad = 436f756e742d3735 +ct = e5913c4c0403b0cf15e20443cd18a91365022f141e8e480e271d335c4fab1fc5c9e4af70107daa43f2869e1978 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[76] +aad = 436f756e742d3736 +ct = 7a6a29c5e897b0df0f986bad7d073e3680f6447b820d36cdcc24c7a6d5881bfb8d42a812ee74dc3a945c3aa23b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[77] +aad = 436f756e742d3737 +ct = e88641d6c70b5eaa39e00ab2a7d55188066e9520cf517aab36724dcf00de2e9614b10f389aa79044c21574236d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[78] +aad = 436f756e742d3738 +ct = 0f97f67f90f69d087390b081c7d026f4f37df0086c3dce2e9a02a930a39e68c894ddf92bbd7111e0451fe6cf7f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[79] +aad = 436f756e742d3739 +ct = 06b7381cb3efda92c617ba646a92e2e7afb22671c71f913eebfd6d3f9595beaeb90011d7e18ca545d3fc2a29d9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[80] +aad = 436f756e742d3830 +ct = 4d6f4638c2f8b3b8282c87b7d5881ee4572d0a8878842119d21b89d519fb4c7d063e0d553b4eb0da11df6d33b0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[81] +aad = 436f756e742d3831 +ct = 294110587b38ce5ae4b34f037a8ddef605754c6951b5f6c0f1288e17f6d0045acbd4a0f41e98b2178d9acf4b6a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[82] +aad = 436f756e742d3832 +ct = 5918e4d0b1dd3ebb1812b715a46a9674bee2207a1bbe77f810a3a481b0ed0b84f60e5adc2228915b4fc4da58cc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[83] +aad = 436f756e742d3833 +ct = ea7c2a8fe7d6cc0237fef4002226d2b0b1dd9e9c37e0a7d083c57ea7f3118368f8337b972f7642d52152e16a37 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[84] +aad = 436f756e742d3834 +ct = e6ab7aecfd81e4808eaf4d160f726275c006761f4ead2e9c9637b81cdd8759a35469342b9066f65ecb8f6336a6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[85] +aad = 436f756e742d3835 +ct = 72d49670b3dff4551c1c6ea2a5cb7d74e9655a2bdb94048ac9173b5a5918d551a818bae8c78070aa580fadb7ab +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[86] +aad = 436f756e742d3836 +ct = d8615ddb96a5ee3a29e17f00fc1bfd64199bb4587f54a41b60b516a9ac590dc4ff2ce7ccef1baf56ba08d25a32 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[87] +aad = 436f756e742d3837 +ct = bdb6cb3fd276d11f8b3839f1daa23c25407b85e50d990becbc7548406664060b3e5ea7b8744cd6d01f7d6246dc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[88] +aad = 436f756e742d3838 +ct = f11c35cd0da9d7986d34525226edbe665c332af3f265ec9ac3252349d13e2079d90e733e67d3a05153876f8b1e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[89] +aad = 436f756e742d3839 +ct = 21207c730b60ed9139203c845156fa9ed93166eaeaf33d91501f2a183e98d6f9941eb270df1d0fa455f028a9c2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[90] +aad = 436f756e742d3930 +ct = febca60a4ef7ee6a73993ba1ed1d39427d96597d04e1ae338ff3418fc4323227143a6f5ab874cefd098bdb3b8c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[91] +aad = 436f756e742d3931 +ct = 08ec4f99873f2548a2bc8ae0de56543e927944c305a31543fd56d5f1bee086acf96387d918e7af898598fe427c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[92] +aad = 436f756e742d3932 +ct = 99b47953bab7e516974cf195a7f14d09ed9ea6f74fe612e6cdf58a9ef0710b2ea7582fdfd98c90a343c6110d85 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[93] +aad = 436f756e742d3933 +ct = b70561bf36b2acad3eb13d7c551af56e0e2fd6d81ba181489c857f66c88817fdb8b76b8d7d594585427b032c7a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[94] +aad = 436f756e742d3934 +ct = 2180d3d0a7d925c0af160101f6b334f0f94bbb32142fc1e6efca3e82e9099e382caffdd909b0fa7f4e5407a0d3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[95] +aad = 436f756e742d3935 +ct = 03d6a815ea1f2f88f0028ee0670e07bf4a0db028a5dfcacb9c281daffcd9226565fa56f92da3ce5eb36e095d8f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[96] +aad = 436f756e742d3936 +ct = d5e0da3bde65864905f8f8c8f9b6082f22a18f035fb9c04a2973f71bda24eade1772c27faa8c3e2552f817996c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[97] +aad = 436f756e742d3937 +ct = f13df7ecf2282a7aff702530d169134c0bad279a94e4de7a0604c4b57a2e394189bbf6c0237e6872e0614599ed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[98] +aad = 436f756e742d3938 +ct = f9c348a57f3249fdce7612d3329293519f6a675d2a030ef812ebe8c7fe1c69408608152e5f489eb41671c36891 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[99] +aad = 436f756e742d3939 +ct = 18335b721b8f80ea3c5b0eb16d6fd9eed45f96f7b11140d3692f2dba9ade5cc48a16b4b316ddc704b70e299138 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[100] +aad = 436f756e742d313030 +ct = 3801b54b9a1d15b10a84eb78a8a84e2f70b4e57e0f6b7638a3d75a40720c101fdd92cfbca87ad22ff7dd20d317 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[101] +aad = 436f756e742d313031 +ct = 7d1b5a06d94e07e677cb647b44f378114ddcb55798dcb8c98fc263f61f4b34d4bcd375cab0c1ef2224c9540961 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[102] +aad = 436f756e742d313032 +ct = 08891c005d9ebc0f9f8d07ab3dd15a88c3d9c60402b9516e3c6727bd0b26ad70f78e8d1a1bf269077a35fc745a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[103] +aad = 436f756e742d313033 +ct = ddabdfb862b8e4d6f03e2858e2a05976286fedcec6447355c2ea0f0540f0d3abe3d9dc17f7aec0f4684ac8a11d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[104] +aad = 436f756e742d313034 +ct = 533056df19cd99b22c522903837e9b04b38f072e869fcf98e63ab4e138116fb1a327090612b2cd01ce60a92c04 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[105] +aad = 436f756e742d313035 +ct = 84a75eae557806a60d8dec4e0a030b31e2150299ebaafba2118e1d9f8a4332dd383c3cd1bf01bff70f235e7ca3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[106] +aad = 436f756e742d313036 +ct = 5288205e740e6eb70b52dcf29f44ade64979a07023888f5a098d6b386b926e5b2b3dbf1aac04a6f80920d27f2e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[107] +aad = 436f756e742d313037 +ct = 24f72645798f856137576f8044502e55f03c53cb3fbdbe9b13a3caeac07631ecdf5b30c11757f6d66697244aaf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[108] +aad = 436f756e742d313038 +ct = 178de8bef65b6abca9a55a1819a9573a248e0612832f255f4d307df38a8f29554fd664639a6a6277b5e33201b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[109] +aad = 436f756e742d313039 +ct = 34613e05962717b7a5c60c9c3a2cc0c2039e584948c9a028da05bf31317efbfdb0fd86252e6061712e3b03a53d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[110] +aad = 436f756e742d313130 +ct = bce0ba4438567b1570821759d9f6d84a6c600701b8632e9fc82a5e68f3568f05a00080bbc4c69d1043fe09a2e2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[111] +aad = 436f756e742d313131 +ct = c848e35cec53b724b632a27d3b90abcf1044b93ab5db0a5e63c93f15b8e3e599f737826db5258ff8078d4cc379 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[112] +aad = 436f756e742d313132 +ct = 2026cfc3ee0f725ebf11c9474bdda1560dd4046eda764d9656cb46c949cf0cdec3fa8a21cd0ed4eff3a7b64ee8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[113] +aad = 436f756e742d313133 +ct = aaa53f387b1651d71fbe2b11f541f6f8b6d70a92ed1668a797d89be0862e2867a35b43f746482271bc8337eb79 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[114] +aad = 436f756e742d313134 +ct = 426bd3f51bb64eaadcc1444282dc0d25edb2b4e777c2437910d355cf3e6cd09ca989a76a34ea8c415e9b9af767 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[115] +aad = 436f756e742d313135 +ct = 1e8c313e38d847030c366926fc26029045fa4cf5523d86e883e386d348b9d2cb3ea727a0ebc586191f45017320 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[116] +aad = 436f756e742d313136 +ct = e44024793dd020b4a059346e2e4d325a301c643fccae7994b620972ad3c5d249cc08bc4c30d3434a62a93825a3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[117] +aad = 436f756e742d313137 +ct = b608878acfd7c879b587555c43f5713f5b8c0f6abe2f1c781e72cbadb32dbec4697f23d8af80eabf32ab969417 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[118] +aad = 436f756e742d313138 +ct = 0563bb0cfbb03d236e68090252082c866c2d05dc48c530fa5920b32eccf2d4913a190c12aa8d55f6a834458684 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[119] +aad = 436f756e742d313139 +ct = c0191c7b91f01ab891336ce5d77d97261632ffff8fcaaf25a0da0f563604a5cdcfda6d7d0d6a492d4bc8f8eb64 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[120] +aad = 436f756e742d313230 +ct = 2e71a5a07fa44ac159d7eb2e483d46d59d4552895973fd7fe32f4919310b814c45699dcace887744d4bac9eb36 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[121] +aad = 436f756e742d313231 +ct = 6c769767ccc92a2e3c6ef2f94df67d72b9c02b6d1993281d2ffdea0b40b5af09f25b3898f05ccdcebe4bd6f31c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[122] +aad = 436f756e742d313232 +ct = 5dcc6147c104f9f5586d88a7cd715830d70d88820a6b2157a574b96b7e9c37f834aa6adb957cd8e0aace79bf47 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[123] +aad = 436f756e742d313233 +ct = 5839720b5f44874828ba95443c2685d53d079f83d3246895906decd87ee41a3cd7969e66c7fd5e88330b6f354f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[124] +aad = 436f756e742d313234 +ct = b01ece5e6481555fa1db96bdead1d578508b9d601a6aab00a1d433e2f94ad75b843809b4d85aaa4f0ba88f0d11 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[125] +aad = 436f756e742d313235 +ct = bfef11050cca99cbcefd59be7f27a793de11dd74793ed2bbfeb600fb1ffb0e2d1e559a68e14ca6369dd48036ae +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[126] +aad = 436f756e742d313236 +ct = bedb06bef935d7035b316b485408a8c4bb745af2ca5214bfd87560f33fb2841618b431988373018adb03e58cc0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[127] +aad = 436f756e742d313237 +ct = 72d0e6266e19f5bbec3f4a5ced9dcfcce96c3d98ec677cb1e91953f0d3774a9c17d766ea497a25397bab478964 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[128] +aad = 436f756e742d313238 +ct = cab945a20e896773bc7408ac7e90e39e7530b2f6408c09693c241835a76d7a9f0894f9f7275a8c9ab78df0bea8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[129] +aad = 436f756e742d313239 +ct = a8c02c46ac55f9b655b547d29bd5b00be116094f1208edbc83b8b27aa1edfa4e3b7d7eed3199cd64ee4f451c1c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[130] +aad = 436f756e742d313330 +ct = 878713ff6c3375f2ac8a2b38c7c0d8b49a7ec57811118b9990b0952c08f097d7f1f41bd86974e0b419246379a5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[131] +aad = 436f756e742d313331 +ct = 36bc1b88559208bc331263d2ed1a16ffd8ddf3770290531f8a6198701d9b668d2819744befffa6d2d0ac01b1af +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[132] +aad = 436f756e742d313332 +ct = 94e5ac2d046cf385ab849a7327278e6d3c51cad5b5d38adc071a113ff3273b1ad5fb5289a01e4da180c77e8ab2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[133] +aad = 436f756e742d313333 +ct = 7db0c79103f304fb6cbe56ffd5876aae98322e285fb705fe724f31e283bef9ed1ae4946c7e7dd8de2ea6073cfd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[134] +aad = 436f756e742d313334 +ct = 516d927bc91d3e6c822fd7612af2b129a5ded8bf590faedeb8495b7493d12e8ccf52f34d630280800a126ba478 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[135] +aad = 436f756e742d313335 +ct = eed3aeedab617f72af68573c059ef7e786c233a2420b58426f01689e65a5c89d48ad08713102536c7beaa37d16 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[136] +aad = 436f756e742d313336 +ct = 8fe4c52fadc9175a6468a45fc8b96be427e570531dd5ee573d70e5dd0b9b1a67cb3873ce2a7148a066b26c8c3a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[137] +aad = 436f756e742d313337 +ct = d506cd6d849069d44977b1fcd4233ea51f812ae84bfc912b7ad80fbc4b7eb330755ee73c037e04ea4d54cc06ce +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[138] +aad = 436f756e742d313338 +ct = cbe30ec8e0fa8aa643cd53fd08c036f27ff2b56d46f2fb071bc9730c3bba256dd0317f14cd658b7d347e0eeccc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[139] +aad = 436f756e742d313339 +ct = f3029bda331c4e1c90960d60c2536bd0dc758e23d59ad17da680318fa9253f952e4fb019642920307f9dd59e94 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[140] +aad = 436f756e742d313430 +ct = 8d1b5e14384b86b38dfa1b837573247c3bb58ca07bd6d8a0261306e6a04fec85ce2e0999eb994efe91cef0d8a6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[141] +aad = 436f756e742d313431 +ct = de39ba2be428a69e47b70eee0315663e5d169da6ef2218bfe7f0ac59957022e5eda5c0b3e804f65138bfb09b8b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[142] +aad = 436f756e742d313432 +ct = d26d5406228c57ea78ed35a5d5725411b86b82a7f155d845b2e024aa86e2eeac11d33be3c986fa065fdc92ad68 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[143] +aad = 436f756e742d313433 +ct = 8a8dff67b3d101c00e48d1c6f77d2e6e123417064f5798e0efc7e994cd31a5e34c913e2262c609991e56000b4e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[144] +aad = 436f756e742d313434 +ct = 90443aa2655619390b627e09daf3949f79e77b903cf2343b84ce5c109eb02238e442bbb9bd2a158c445c7e57fd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[145] +aad = 436f756e742d313435 +ct = a3df261a314fb20a519cb4b116832fcfca255372e9582c51bca30df529df7f8bea576390abdc25a8c09c030dfc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[146] +aad = 436f756e742d313436 +ct = 764b6ef88a4ef4e00495eae59c83eb4d4da8512ad24982c04c332cdc0c39944bd322d74c89b78977c649e344f2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[147] +aad = 436f756e742d313437 +ct = c1149b45a6f6dacca8342741b452c3c0fe8ffe65f12ba4dcc731f38a0e29cfd551984ebf4d2850c05b05e4638e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[148] +aad = 436f756e742d313438 +ct = f5c2222655ded319eb73adcb75cfdab103855d43bc8e2098cadabcb6f02c75d5017fa95854d4dc16514cb85bc6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[149] +aad = 436f756e742d313439 +ct = 67de8b5afc35709924eb1598c90d1f8db559e5d1f224e7549205cba6ba70dc4bb67b1f7f3f9a15d56692d3e88f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[150] +aad = 436f756e742d313530 +ct = e6add3f1f1dbad46769e62b770e0e79f795d43c64b76e46d578447bfc7c01e48a7bef0607791fa51b9f8f73db6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[151] +aad = 436f756e742d313531 +ct = d974c073ea225646215fef776186673b1c3b10c8fd130dd6c46216c90cdb05e5d899c55be32dafb2f52777be56 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[152] +aad = 436f756e742d313532 +ct = dbb16370248672972c240fbe7558669713aa40221a8138789a4b1fd95edfbe5dabc361b95e1adbcb804fe38188 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[153] +aad = 436f756e742d313533 +ct = 0021cb3186fd692c8ab715950564165ee8f89a17ea7e308ce48c6337103a1a505ab2aac137e5a110b7c92260b9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[154] +aad = 436f756e742d313534 +ct = fffc59f2ff1d3a761d8e5005c25e12044f10875aad3ebd5e9346534aae5e4896eaecdf05f7fdc8c60952a0056c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[155] +aad = 436f756e742d313535 +ct = 84d2ab92172e21b7251bf2825f3c083f474d891ca0b8cb7f5661ce37956446cbce80046c82bcec29eba26b4289 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[156] +aad = 436f756e742d313536 +ct = e80ba09d1d2d7de13067e460755f3609840f017e8a6e4561b7b4078817696936ad19ff6b5c5cdac2b25ce809c5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[157] +aad = 436f756e742d313537 +ct = 445d8be1d404aa0e508f7021b22e48dd6a349141c182e601520420ae4610791a8db67f4584ecbeafd3b4169e50 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[158] +aad = 436f756e742d313538 +ct = aee6debdac56b80f9b55435fdf649d174fcb801a93866fdd8f6bde22ff85a3baba12409fe7f41b1c9b248711f2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[159] +aad = 436f756e742d313539 +ct = fe39078d272abc9c7999630c5eebfd1e1628a4a694430c105f119d20e524e99face043b5da613d3b11ecc897d4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[160] +aad = 436f756e742d313630 +ct = ae4193c43e06948b19d2c912613f772c6be49b16a4f7dca4991c06417530681b54821b94ad8ad6c0d388884ff5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[161] +aad = 436f756e742d313631 +ct = 114fccd21850ebd4069127be28198c5c2e9f270b598baa7be337975510299aa20c054f8498f51898eac61567ac +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[162] +aad = 436f756e742d313632 +ct = f11d3b4bc526d850043c454f9936f85bca7df5fc1957c55677d3dbc18a55de8a02efcfbd407cd8a4d0a30d366d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[163] +aad = 436f756e742d313633 +ct = e59152496079561fe9f114ac73ed3356720542d395921f7a4c5c50da7f6afa3f492848361cd3a1a13f4b7a2fbb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[164] +aad = 436f756e742d313634 +ct = c62cfe00dfced3a0d9f35f6f9bbbab100bf6d609f3d78230e1bdbc7a2b3f1c4713975b62133bec7cdb8cdd91fa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[165] +aad = 436f756e742d313635 +ct = f7e0185224ec145225b3cf0451dfb014dd44137775617ee72d9da4f7b41ec248904c107d6c6db25f3f8e2aecf9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[166] +aad = 436f756e742d313636 +ct = 93c68f805eca253c23dc452302ef9ae791b4ffab97853c01f5967b6891cf2c5bde002ccd85a365fe348a57d6ca +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[167] +aad = 436f756e742d313637 +ct = eaeda86b4f90c1f66e5929454220ef8ae0cefec40a6c03911212810abe11d5d961f625fd973855c7d6d8bd6426 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[168] +aad = 436f756e742d313638 +ct = 72ab591663e0fd2edbce4d5ee04997d259b834bfb7bc10d36fc14e04e2808ae38cf601af89ef33d28224301424 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[169] +aad = 436f756e742d313639 +ct = 5da0811d6bb5b9d00402c1f803062e6e6db4da219d695ff502ed4e74f011cefc3c74bfe86f142a6d5ebcef873e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[170] +aad = 436f756e742d313730 +ct = fe429d92e1cdbc0c738fa1b057762a61b6d0b3bf3d6c4a480504f3d8c07363d3d9adb50c5c44fc9ad2f80afbb4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[171] +aad = 436f756e742d313731 +ct = 73d7980299de66489e24e2b042d8cb62bf02a50ea4f6edfb3a265fdb54028a2284c5090fbd5bf7401d8f7d8c55 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[172] +aad = 436f756e742d313732 +ct = 9b81f97ffded87a9697145b6d0b0210cc20afdd117311238a5354d1ac0a5d0b834becda5de16280c7ea3728e26 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[173] +aad = 436f756e742d313733 +ct = eb9a1e55a34f825c13d2b7b014cbb7db6249c4c511111af9ae9bf441a9b9b1a701f778f2bfdac6383a9fa79ad2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[174] +aad = 436f756e742d313734 +ct = a0603640d761fba6ace56a20de14ccbc45baf0997755175d7f3e3742edb274368ce0a776eda420c0eff6a4785a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[175] +aad = 436f756e742d313735 +ct = 0abb86f71c0d2e456c4322bf4a26cc5dd898952a98b6fc815b5ddcdfba4308e6ec2c6260d7540bd0bc2a399141 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[176] +aad = 436f756e742d313736 +ct = 2d076ed5858dd9f5441b6cdc386bc30eed7471a8f819de6eb6173f0704365f8043fb6e8fc4a7d7f9549457a3fa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[177] +aad = 436f756e742d313737 +ct = c51e01a9dc463c20728a6d15fd59525709a8c51d9f46f15cf093773aa7a968d40232c9ef26d20257762ee49f56 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[178] +aad = 436f756e742d313738 +ct = 6be4673041b4f9281b6f5f5b3a4a611062254f82d7d298e93ac3395b0f93ee4277f3d60d1116c5f559ee498c1b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[179] +aad = 436f756e742d313739 +ct = 56fb203d31045da80ade5e18a2a2e16b361fe1ed4edf4ed654d75edbe82d0326ce9dc51f75454fb7651d5d25b7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[180] +aad = 436f756e742d313830 +ct = 046305f4ac30a91936afe73f55363480558b476ffee4ba19a4a99a6edab9bdb712f8dd2abf16e37839382f1c07 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[181] +aad = 436f756e742d313831 +ct = cb90b1ea72f58b73984e41ef7297338ca0db1b4bf51d1bde41372e4e4bb9ca00f6da1a54e55fd20f1c21ee996e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[182] +aad = 436f756e742d313832 +ct = 33fc92d18d7aff541c2d8d3d0d590fbf94c7fac0f5403ef4abab82ee855e42a0753ecef6154dde04926799b2f6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[183] +aad = 436f756e742d313833 +ct = 1fcdce642c0628dbd694cf14df7182c5f5bc300ded6c2c9354866a52f4ebbcdb3a07f16cd66a1f6e25f1aa5c36 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[184] +aad = 436f756e742d313834 +ct = fb4ee64e15307f7209e60aaaf58ffa1e3348c3e6aff46cf95c3a15e96b65762cf72749898649aa4f2554ec973c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[185] +aad = 436f756e742d313835 +ct = a64ad7dc7d7f2c272293f2c0fd957c4748f3911e6bc7242a3bad175a20b4508b0cb065a7ec848677ed9d349e5f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[186] +aad = 436f756e742d313836 +ct = 95eec59259b5fb711157229920349524e7e85756419492df26298ec7b16668a892a5fa41ef7728bc8929a1f942 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[187] +aad = 436f756e742d313837 +ct = 8cc240907d8cab9b1a0168abfd01aed8cdeeda252e298de2f3f89190e1e03719e40845b9b5d93df184702bfd7c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[188] +aad = 436f756e742d313838 +ct = 5cece69c96911efcf1406c5faff0de7e7965ce0b6b661df3290ee4b86b4ced5db98d2782cf8ca5c7ec81191ee3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[189] +aad = 436f756e742d313839 +ct = 9a37d67894742202ac23904b65d72e40b7afe31f7aef8083e3f41185e402481f1f6466bd441a27dcf5a135f6c3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[190] +aad = 436f756e742d313930 +ct = db536753e52ccee922ca4578dbfc8b24069dc526202b9e95d865ef7f76b9406ba6afbb665f4a2d048f0c8afb9e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[191] +aad = 436f756e742d313931 +ct = 015649389a63f9410008083f30a4ae626ac78d8cf4b35f701845a56ca07c58aea12908020c43890db3f91745b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[192] +aad = 436f756e742d313932 +ct = bf7df6bf223d74a821afeff194aa402a5f71eda3a2a78ae319b4f996aa7b0da67c221c87ff2a778b7a20030a2f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[193] +aad = 436f756e742d313933 +ct = 9003c98d71b1aa4f531c51537cf538302b5b6036e7af1cb4aadae99921baa5fc30aa86abc8ac525495d92f8b69 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[194] +aad = 436f756e742d313934 +ct = 6b7980f6b429998a899dcd87ba98a96cbf03b9a0878d3afe10acc0742114a7ee003047deb911ca38ef760fc903 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[195] +aad = 436f756e742d313935 +ct = 4681f2b8075420e813ad70b9dd169187ee65779371d3f1abc6e62a99c8ee1cfe9be5088cdb20ebc11373d8af38 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[196] +aad = 436f756e742d313936 +ct = 66361f11cf2515e44be30d93a4a8d9497945f5cc8e7f06df6e4f3f58cb47951841d00ab8b4a52011303bc58be1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[197] +aad = 436f756e742d313937 +ct = 09cbadadec104db37f240fcfcbcabecc92a03ec3157b789cc12c25e01c376a2f59189ff77fd8488b43bb81e8fd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[198] +aad = 436f756e742d313938 +ct = d490d9602e9e59f96b8aeda570e2e58428ce7c06a4e4dd3b8a3b61307d6fd4c6cb89d07776c30417484ad2f249 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[199] +aad = 436f756e742d313939 +ct = fc5ae84ab4afbc898cb4b5712e1fbe7f75465bb6e834a50f039a0d2b7095cb732db60b053ded3c0e3df0626864 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[200] +aad = 436f756e742d323030 +ct = 8f1af0ac6b21371f2a347a007b9de28f54cdc3ee1db93552bd340732e61d1bbaf3194e24cb3707b018d97f5010 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[201] +aad = 436f756e742d323031 +ct = 45eb8bc519b8ffb448af0dddcf31b378029d916aef6c91dff98dc01a10d1a2a4c0e43445da2d2cc6da4037193b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[202] +aad = 436f756e742d323032 +ct = 65cd2f48815dc6ecadc4d751cb8f9aab5e678d87abad28d4499670eb5b61c4d1c3c808d62cc946771a5673afdc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[203] +aad = 436f756e742d323033 +ct = fb0111868c29bc462791ef235b845450873cbce9d64a7d8851b993de034e13f40e9998046e9d29caebd1625be1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[204] +aad = 436f756e742d323034 +ct = 6f6b24fe3698cb0c0a8b8b4f6c999aac265a81a25e85db60dd0847b8be655480e462cf8d3bf6f9beb21de26feb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[205] +aad = 436f756e742d323035 +ct = c93a9ae61a56dc361674f9e6c2570b464840afb49842807989c6d9f700552245151e85e06e37d7a30c09780cf4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[206] +aad = 436f756e742d323036 +ct = 145048e595c7c405afbea4c8013fe3dff529a2cee5117c61d70150a3c0b97200809c03cb7d317ae9aa3c06628a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[207] +aad = 436f756e742d323037 +ct = 29f01ab2a7ffa29fbd4c63a590ad7ecf87ae93a2c0eb1b5936b3a6d649e7803fc950a94810dedf18b930536170 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[208] +aad = 436f756e742d323038 +ct = 633d7ef1a17ff121485a82bf4bcbc9051d9768343e547ee9531f3b3c1cdcbc11dc45705553b1e16a1182488b1a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[209] +aad = 436f756e742d323039 +ct = 37bc7fc586ccb2579fdb41d13865c8d9659bd8d383910e2474fad0dce89dd418404a458f02eb8172a1f56d8453 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[210] +aad = 436f756e742d323130 +ct = 92c1f5393dfe1325ffa85d86c1acdb492476ec7a5564820771a761a2df780ac6be823900edc2fb0b61a1ed5aa3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[211] +aad = 436f756e742d323131 +ct = 7da1a3fb27f68587bfb66e54aa2b98b1217c1b274802dda873c2143aa69b0dc999537f07d473fe2f0b9dc6a8d5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[212] +aad = 436f756e742d323132 +ct = aad51528d9d7518519e3e610e9048077062eb164e64388c9bb8f63e0eab617be0ace7878cb261fa426fb051d12 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[213] +aad = 436f756e742d323133 +ct = a646e6617fbe4e18d4908a1f0cf46500fe3b82cc306e249b76586865cbfcc39d7b5c73b3f372a18a135aee8523 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[214] +aad = 436f756e742d323134 +ct = ba2a96778c42d5be2c036ff75cab34898896b62b1b2d0adee7dfa194e3da00a2c36967a74107c25030d1b23bd4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[215] +aad = 436f756e742d323135 +ct = b7c0b4fc91764f3935da56c764311e6ac6d3c8af44fd5b5f53901842e9bbbc6ce886dd615d6f6c4b6c285dc9c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[216] +aad = 436f756e742d323136 +ct = 3420f14b4463e393dfaaaf07d48b383d6f082e5d58708b2f2ae51e432c435fc9e2fc17f5db6b1575343e91482e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[217] +aad = 436f756e742d323137 +ct = 0f37542535f680177a32128a9f79ebe52d34821fd818298d6dbba4a51c484d1426d904b5afe80f60e180dbff91 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[218] +aad = 436f756e742d323138 +ct = 67325db96b9572e0b1082446950019b05da85c062e9a5978c3065aa5bb938b03cddcb50575b8b3b5b689bb59e6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[219] +aad = 436f756e742d323139 +ct = c5211f82cc9a8261a0a5d93b005a241eb23404497b77689975437b19a2e42b6b7bb38a16ac51d813a413997e4c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[220] +aad = 436f756e742d323230 +ct = 4d9571193ceffe27a4944d1c78fa0ffe3aa6cfbca6c970b0f93e32aa7a96333fd16abfe81de9114ddc45fec762 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[221] +aad = 436f756e742d323231 +ct = aa0133057136602263f523658181fa9bb1e66262a9c79b97b1579bb0b5b1bf4bc0a0fd64b607b01cccf52d8e9a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[222] +aad = 436f756e742d323232 +ct = 825b7894b5a6c4ade04f5f70cd98d975c5ae7707c5f8c1ea197e1faeb280562c77a3e5130d0037d64eb1c86cce +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[223] +aad = 436f756e742d323233 +ct = 46f11fa25fe412843fedade29098bdf448fcc6473ff0ee7503d1345667d75e74746905166924db804399ec2b8c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[224] +aad = 436f756e742d323234 +ct = f7fd8d51d9b9d2d5e24b9d4de9f61c9d604cab2bb65712f80de2d94e8daa307de22283c4bb8614504f71b4a819 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[225] +aad = 436f756e742d323235 +ct = 6f54ae130c8cd9b75627495187d6aacf564778a7bc9f6fbe7001b5a284592dd0c3e7ba3f14d955fe42eec72e31 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[226] +aad = 436f756e742d323236 +ct = b0ead5ca3c514d405e22f57459bf3e4b3b10480bc5c5ed6cdc907eec7d7c55791c3ea020640cdef28995163a6e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[227] +aad = 436f756e742d323237 +ct = a0fcdb684a93d7a27ddbdf6c2dcfb191d9a9bfa0a7ec64ce88b408cf8a8deb19b966cb641d944895b85f0b954d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[228] +aad = 436f756e742d323238 +ct = 616bc44dfe78f7f3ef9d56dd2312e8ac0d08de8f4852dae7794a7e7a415094f59665645ed09387507d00303def +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[229] +aad = 436f756e742d323239 +ct = 8929024200819b1fd946627756e9bee6efe49fc6a80c6e720fe00c2ec5689f330eaff95e77398a09ac8d3b9aed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[230] +aad = 436f756e742d323330 +ct = 54e672bb9e4ecdecfa3526f5bcf1a6745f2007658f794712c8f68e2544c6dcc9946f4a81288c3e76475c1c929c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[231] +aad = 436f756e742d323331 +ct = 9846eab40523dd43878ff150ee10a54c5fe54248fbbed57cfc64ca52aa5817caf0465eb934b4dd99b96e5464f4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[232] +aad = 436f756e742d323332 +ct = aa6e8697ae32fc0908b8f6fc79639f65f59282329f74f65d82bd23d5cffb83ad289b7400f25a87825658c551a3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[233] +aad = 436f756e742d323333 +ct = 8412449390ae9f7a8811282c45109e2074213a282edee6014f0f9b51ad5a573de7c98d02c19fe9f29336d4e4e4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[234] +aad = 436f756e742d323334 +ct = ec413d776c28591efa625f57ac7b1efc0137654044c3763a103b86e94082b92c2ba158eabf8ddc80e232f184a0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[235] +aad = 436f756e742d323335 +ct = 179626ccb1dda5d800312a158da372a184fd6f1803bdb472da045467f2d8e4676114881aa10cd1c3979be9cfaa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[236] +aad = 436f756e742d323336 +ct = 6de796ba74b37a78fac00a329ec3e7c936425aceb4e36a623671cb39b04a571408fa1992bc592a44ac56f2a96d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[237] +aad = 436f756e742d323337 +ct = 48b947a68b838f5393acc967cbb6f52dbd161328817438df5dfb9533cb1ec2f7f77aac3c8d1a487691ff3f917e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[238] +aad = 436f756e742d323338 +ct = bce1baf335f9a2a0677cac2bc6b5d3d2618e772f3af688bc82fa63d839c5e7fcd51535fcd9ccbea75936d90b51 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[239] +aad = 436f756e742d323339 +ct = 952e38288246111e5cc6a6f0fc5901577dfafd4e28bc544ef5e468e71bbac87ab338773f859ca87f3474fa629f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[240] +aad = 436f756e742d323430 +ct = 660c6a8f448d5b0680cc1dc929628405e2a6c02da409cd3c6fe3cf7141811abb751b223ad789fd14b9e1602afb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[241] +aad = 436f756e742d323431 +ct = e5747a16c008e797c3be09d597b2884945db07314faed0f8f778d4b6b9cfc59620d53be6ed8b4aab2e4d9f59be +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[242] +aad = 436f756e742d323432 +ct = 07ae27bbcee503b65523d33d061e97316f061f7c355e633d3c4ab131fbf33f4c6792e947072774bdf8adfae78e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[243] +aad = 436f756e742d323433 +ct = 3d9f2b4d7c14170cdfd535f6190d35e7a1abb2021b30b40ee8f3bbe3d54c02cf69f2b9da331a916e739d74f959 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[244] +aad = 436f756e742d323434 +ct = e2c42282ea2f99db6d93c31bd90e7bbff5e3376d32303a99e358bd5083918986469f01263bcf60c38b7c822230 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[245] +aad = 436f756e742d323435 +ct = db37f6664496ccd0cc0422c0151cbd0a5ae14cc5355504e76b52d7cdc0625eae945ff1c39f37a78de712d9d30f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[246] +aad = 436f756e742d323436 +ct = 98c02dac817d309004e910ff1aad1ee768d641f717e68a951762dee0384f8a5fd09b47a5ce35aac62a1093db4c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[247] +aad = 436f756e742d323437 +ct = ffb8ec458cb1d80e79871777e3d6340e41acfee88b8a777d08f83a95e9e8c0806f23a5ae627b85c1bf67031d3d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[248] +aad = 436f756e742d323438 +ct = 9666674453d6e55e481ac351253fd806f1dff6833c755f16737acb4e01a52a15eb51549892f08c039710ff17f7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[249] +aad = 436f756e742d323439 +ct = 87faac25c2e84bbf72abc74bb8f86ae409bc36c1d7f4ee3583c6246a2cc4f72bd4503c92209f0bdcf2bf9b97c8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[250] +aad = 436f756e742d323530 +ct = 9b779902d73179cc203b8551e595b2525005f1b963768fa742471bb8e399ed016806052cffe16ec1113bb92761 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[251] +aad = 436f756e742d323531 +ct = 9cdc91cd4dcf786f3d64b9e60f60aa39185aa9124d67474e8d5ccf252a486b8f99475f2391acb83cfc97572329 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[252] +aad = 436f756e742d323532 +ct = 5a8ac0f7e52b423a242ddf4a109c81d67d340f6c73115e327fa34768cd57e2b2f03b97b59040757a0ce78c8d41 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[253] +aad = 436f756e742d323533 +ct = 77796249ac3cb85b11d8a912f4e3ab18e941875e4fbfff3ed13b0e1e8b6f70199fb1aaf82c90e0106abd697fdf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[254] +aad = 436f756e742d323534 +ct = c62723610b47a9702d7226f58e4b309a3165e81425a0e0fac70dd6c3c2dad7230da418743a3f196a51c7cd06db +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[255] +aad = 436f756e742d323535 +ct = f2783a56b5f0cac017424bbe7d29dc9cc45ea7a6050ef83c3284f5ad7bc889aab2cb46e6916a683b17b903b63e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[256] +aad = 436f756e742d323536 +ct = 16bc024eb0af9037260c822d45fa786e3c259aab1b7a4a196a72c3e794e78446440ba42b531da44d3d36d0a042 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# exports[0] +exporter_context = +L = 32 +exported_value = 8890c5615e5d6b0e1b212e26d80a7e8c0d03e796377f09e9377aa0497ccf89c9 +# exports[1] +exporter_context = 00 +L = 32 +exported_value = 51f60f1d4505688a1aca99c9b789e44f38a5bfa177a6b4660ff57114bf50c6be +# exports[2] +exporter_context = 54657374436f6e74657874 +L = 32 +exported_value = 25f7c731201fe73978b5c66405f17de3e59b7f1c4bbe21e9ff57541d152841ac + mode = 0 kdf_id = 1 aead_id = 3 @@ -3144,3 +5246,1054 @@ exported_value = 8c1df14732580e5501b00f82b10a1647b40713191b7c1240ac80e2b68808ba6 exporter_context = 54657374436f6e74657874 L = 32 exported_value = 5acb09211139c43b3090489a9da433e8a30ee7188ba8b0a9a1ccf0c229283e53 + +mode = 2 +kdf_id = 1 +aead_id = 3 +info = 4f6465206f6e2061204772656369616e2055726e +skRm = 3ca22a6d1cda1bb9480949ec5329d3bf0b080ca4c45879c95eddb55c70b80b82 +skEm = c94619e1af28971c8fa7957192b7e62a71ca2dcdde0a7cc4a8a9e741d600ab13 +pkRm = 1a478716d63cb2e16786ee93004486dc151e988b34b475043d3e0175bdb01c44 +pkEm = f7674cc8cd7baa5872d1f33dbaffe3314239f6197ddf5ded1746760bfc847e0e +pkSm = f0f4f9e96c54aeed3f323de8534fffd7e0577e4ce269896716bcb95643c8712b +skSm = 2def0cb58ffcf83d1062dd085c8aceca7f4c0c3fd05912d847b61f3e54121f05 +# encryptions[0] +aad = 436f756e742d30 +ct = ab1a13c9d4f01a87ec3440dbd756e2677bd2ecf9df0ce7ed73869b98e00c09be111cb9fdf077347aeb88e61bdf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[1] +aad = 436f756e742d31 +ct = 3265c7807ffff7fdace21659a2c6ccffee52a26d270c76468ed74202a65478bfaedfff9c2b7634e24f10b71016 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[2] +aad = 436f756e742d32 +ct = 3aadee86ad2a05081ea860033a9d09dbccb4acac2ded0891da40f51d4df19925f7a767b076a5cbc9355c8fd35e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[3] +aad = 436f756e742d33 +ct = b7de2d672ecddcc77718bb6736d3982fcaa5362198e63690f0452b0137f55480f5d5d3ad7c3265f7aa3f72f140 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[4] +aad = 436f756e742d34 +ct = 502ecccd5c2be3506a081809cc58b43b94f77cbe37b8b31712d9e21c9e61aa6946a8e922f54eae630f88eb8033 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[5] +aad = 436f756e742d35 +ct = 0ca5f85ce4569e0ff208fc23c691c2fc85da677a270cae116fd5357f9c4548f5e08a3ded8e137649b86cb5cc97 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[6] +aad = 436f756e742d36 +ct = 9a953b1823973147329f2fb802f2944e5b01a889b21700374b3dbc2cf41ddacd04266796a47364cefae16db6b7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[7] +aad = 436f756e742d37 +ct = 472bbda3a67603e6a242ef8fb037d033560cb9e8f95132e9a52f16d0d4fdce88bee88c00f682fea1798976b3da +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[8] +aad = 436f756e742d38 +ct = 2f1a2b7fa25d10af90c993c87a533da919c3d274e25bd74b4e5a299afb283138a8f1e6d85a08d6af19a384ed22 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[9] +aad = 436f756e742d39 +ct = 8afc7a43e9e8d575f8e09c71dbaf2259fab97b5f48d90a284a1b9e0d52c2974e22518e9c22076e7aab14c7dc7a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[10] +aad = 436f756e742d3130 +ct = 10d3c4181248ac1e01aa263439ad123ad9458e46da3d513c8eea06b4218a442ced2b27c68f2bb27b29b0f9fba5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[11] +aad = 436f756e742d3131 +ct = 14d77d5349d17d3f3cd787356180d424ef93835485e82593ce8b0403eca1e1924a7aedab78a2f3be37994bfec3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[12] +aad = 436f756e742d3132 +ct = 1665cc5b2829613ac24feedf9847207bee8ec2ad536aa0a3b1de5cf614e5eb419b00aaabcc7d9b85d03626a053 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[13] +aad = 436f756e742d3133 +ct = 4beb712b2dc79cb2923affcc5ee55df481a807922b74894741f1a8ea1ca4145b3872ae617dc23c1b940320dc5f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[14] +aad = 436f756e742d3134 +ct = d24b966c9ee0dad75457b0bfbbc0f204540cbb01e0875fbbf6e434111b0934b4a4d1cff94ad918135233021ced +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[15] +aad = 436f756e742d3135 +ct = 64fcf95695b71766b8447d96ce5af5c8629268d6738e46032a5a14d7f69d280ce004876eee8dc3009987e5a774 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[16] +aad = 436f756e742d3136 +ct = 0ab4da8253b8eb87f8c934527484e9b1371ea99bd48c47ec9060cc43803a8640ffb0c904f41d5821c3312a5d7a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[17] +aad = 436f756e742d3137 +ct = e813a7fab6db458b5b819788c35671485d53b2647c8989e865cd0adbf9fdf21e98c69b9e49976b6d29611768ba +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[18] +aad = 436f756e742d3138 +ct = ef43d472e241bada94631ea7f713b553fb01df4abb004f56a4f0b0b35c2879259d94c48b087b9eb84393d5029d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[19] +aad = 436f756e742d3139 +ct = 87573897dcb5e2ded008addde56b4652b44b286662689a651bed7949dad1034c8751462d9e7d7c7dabb976d4ff +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[20] +aad = 436f756e742d3230 +ct = 99e8c16b09b11d63912d23b29b9514c5a8a13c7f6d26352088b648c6cf1ba6fd71cb15c16a911d2538023fe4b6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[21] +aad = 436f756e742d3231 +ct = e82e1588353a993dc57e713d9f1dffd711152edb7667370044424291877f93143751643a3d2b646de364d40060 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[22] +aad = 436f756e742d3232 +ct = c07ab9089b2406c2f8f8871e555042ad683c6e9182b3e5198032062b81c59850342b653085bef4525def9078da +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[23] +aad = 436f756e742d3233 +ct = 882f8fde7e025247d9684126e08f44dbe6e8158804b9c42b652a471ba904ce19f8f3d3a9162230d717ae083815 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[24] +aad = 436f756e742d3234 +ct = e14ef552b77de117f9fa7384c93bce3dfc471e78853b6c35d2c5b18b57ba7940650805e61c3b915e1640aed9e6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[25] +aad = 436f756e742d3235 +ct = d258655d099fb86e3e2740c0c1e11621ef7dc61c9e770ceb07fa9249a3dc42790b0e0eaa63f22bfeee9181ba03 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[26] +aad = 436f756e742d3236 +ct = dd836e8c628a4d794cd731a26cfd591985445be24cb5ce9eadafb86dc93e03b1b53dae2808d5a8a56ad4ce76b7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[27] +aad = 436f756e742d3237 +ct = 95dd4f0d739fa6d3a5c823af5be5cbff4f67681ff4e91da4dd60862e0aac191a01a2a786e3bc4ab17968c921fb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[28] +aad = 436f756e742d3238 +ct = 4826674734200324d6111c86c76cd574b2e6838b61fcdec1ff9166140791919ee848122aceb4fa39a4b00d487c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[29] +aad = 436f756e742d3239 +ct = c23f7e91ffccfab228848435d09a8d5b540b3263ee03381dccbf268244e109b3ef00f46c7328e5bc5904a8e4f8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[30] +aad = 436f756e742d3330 +ct = a1951f639b495355fde23c6097dbd93a2291c84e2e5d047e07f0db291b2a23a162106328bb257ea78c87ce1499 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[31] +aad = 436f756e742d3331 +ct = 2efee285dce215c4d318a7e7cb3c79a5f4ed206810badfd13db42f4af0aad43675e2c3c7f2818018ababfc0bee +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[32] +aad = 436f756e742d3332 +ct = 19fa32f8a868463888d6468a9177c2c09ef5eb09502646a6f2f24055d670e3714f5bee6c15a6fd3cfb8caf6a7c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[33] +aad = 436f756e742d3333 +ct = ec8cf86893c64175c3247ab71f71669de7152cdf2735ee855b272535445d707a58c9188c386c9d62cefde9ad4e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[34] +aad = 436f756e742d3334 +ct = 2bcb2e07356124e3bf185777306701d48c3f007df73ad77ed95e87e18d503fedf881f9b428edefff6dcbf35457 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[35] +aad = 436f756e742d3335 +ct = d112973726df1719a6756479b75ccb218d5cd493f0a641344ceced3c1e7e48a62dfaf2eb27f943b321ffd11eb0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[36] +aad = 436f756e742d3336 +ct = f7e38aa4187cb6f9f2b46990dc690a340b1244b0e96ff3b4599ede765b1982cdefdd3738be0b2e98f929e04cf9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[37] +aad = 436f756e742d3337 +ct = 43011ed36c336f6c499a33fa35ef185e08434ca63f9fa5478a533133af82c3bf38a31729af87a7ad1a0db6e886 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[38] +aad = 436f756e742d3338 +ct = 3241fa612f4feb1f2dba73beef8a35da4b3650af9edcf0fb6d364b2028b335933e3dd04bcf013ddc5df174a8c1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[39] +aad = 436f756e742d3339 +ct = 195052ebbd8afd125f4462e935ded4c6cc999f41d11aaacf6d645fab1f6e64ab0ea600a480ec7c21921c6a49a2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[40] +aad = 436f756e742d3430 +ct = d659b5beb44258ab7f5045a91e4ae127d1bec460fe58af259cd3ba8eba696efb4d8344e0438ff64a952955f16a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[41] +aad = 436f756e742d3431 +ct = 1e5d05cf7eace9542eada2db4f7579452febe6ed7f4b3b53b5971238ec182e0c2a898204f47338dc469b1a2298 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[42] +aad = 436f756e742d3432 +ct = 1cbe40802bc5a0c96414ae9330eff0adf7bc160944863bb354f6602d49989076010cb8381892ea8f30384226ae +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[43] +aad = 436f756e742d3433 +ct = 02d88f0941c79663d90b8f8603c1a78101242cce044fe72ec585b48bd71bb79636f04b04084b4007cb24bf1ddc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[44] +aad = 436f756e742d3434 +ct = 5910202f4266d349ca3b1e40f051fe16be784545bc8031f533d30e82b900b9edf5096f448d5e2de8fdaea4b72e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[45] +aad = 436f756e742d3435 +ct = 1f8e71b30e4a199f7ffd05a7feea60a09bfe3d052047def72c8f8bbc94ebfcdb9b6bbea97eb15a30ad80f67ea8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[46] +aad = 436f756e742d3436 +ct = 4feea6befa30b7318fbd769cdd44e4b30374993edcdc3bba868056b30f1f1fbb32b7ba9f17807feec73e646cbc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[47] +aad = 436f756e742d3437 +ct = e62536d436e2bbbfcb8f01aa84671ca601ccf537b3288491b20ad62046602d8f3d1b2fef5e0af542b29eb7cb07 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[48] +aad = 436f756e742d3438 +ct = 57e90938ec88919ad5c7de2e2ed9b410e8e8ab46e1983f71ba3a1a85bd8726e7a84777a97532165b0a1d00636d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[49] +aad = 436f756e742d3439 +ct = 056625bc0f5da4d70678d51a0b9e79278042a18d81e4c12362dcffbe91d53b8c5f357a9e0afde2b841fdd65cbe +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[50] +aad = 436f756e742d3530 +ct = 2e4ae62382e4ae36dea0d243bb69e02195188eeb91009c6a02dc4295543452233e97caf6fdb1909b7c4c9782ca +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[51] +aad = 436f756e742d3531 +ct = 6a5101ea9f65bc392d82cb52aa6e5d5e09262639ac5a7fa4684c3724c2c9883d20873b4a03816d0d62ce550820 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[52] +aad = 436f756e742d3532 +ct = 8c3ee8a0bff374943428dcfd6d6fd0ff06103c776a26a04ea4c25c606e1442e4be786fd71c412ae9916f45f8ae +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[53] +aad = 436f756e742d3533 +ct = b382567d688e25f95da3b8d7dd290115b5012acf4783bb70336e192ec4c52a9769b29c20325d9a4caaa72e9ece +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[54] +aad = 436f756e742d3534 +ct = e048715bb0bfbd3c5cf4df882d03d5464ce682400dc4c349a2f1d1827473100e7d4dd88735e21cc3d9017c097f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[55] +aad = 436f756e742d3535 +ct = 17863a9136085e486347c5bb9e13b13d311c7453881a6632eb9711e6bb0aa8e4eed65a3f77025eec5b18b4b180 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[56] +aad = 436f756e742d3536 +ct = 5eae326e0d64c3d2eb3ca030b86574aec87ef9aaa3e8f73e10a55f15d54cbcdffb1599a30fe765cbb4b01b1620 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[57] +aad = 436f756e742d3537 +ct = d8f57a7357b566b35bb59f12d7cececc675ff42a849cc0204b59fa8dd8f32e28367e194d5f0e6686b5a304d5fa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[58] +aad = 436f756e742d3538 +ct = 5291cd0c0007d0f903ea34a44c8416604cd581e135cd53388fccb2760e64c497148f510a74bc0bf8c5d9300dc2 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[59] +aad = 436f756e742d3539 +ct = 8e686ad247050455bc96e7fd09bbd75b811479f19c74a4b9efb42358138c0665154508b40d066cf01786e5b14f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[60] +aad = 436f756e742d3630 +ct = 16b50d9f5803b951a5cf311bc2f974db9dab83290a29c892173400864af47909d89bdce645f43b18a40ad224c7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[61] +aad = 436f756e742d3631 +ct = 069c4eeb76b1fab4025818cd505109062398b57d996e16487ad944f97fba4225299801806753ed2008a930d792 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[62] +aad = 436f756e742d3632 +ct = 0daf3b2ddf8acdf78228d418742f97a43bc4175c4490d627ae4b689a1b58187cd95eb8919031ef450b43b5a3af +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[63] +aad = 436f756e742d3633 +ct = 0e87df1bb6c8e6c39bfc581703caa8c8c89283578766bf180bc1c47d297d42ce90e87172f7f7d75de175379e93 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[64] +aad = 436f756e742d3634 +ct = ca21ba4e95aea092d5514267e6fda85ecc1aae1b52bb03c598655e64e839aa54aadcedbb65c1d1d5d7c19971c0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[65] +aad = 436f756e742d3635 +ct = b38a51ef7d68dcda26f36ba9430c841310fbcef1dc2b0656747faf4987c6da76e81cc098b6da02883c47e9cb80 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[66] +aad = 436f756e742d3636 +ct = 1a8c0cbc4967c3da7ccc5e14748fca5b1ae0ce7b07b99c60ae133f493ad94fba50c2e0f44edb68a1a6d6ded1d1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[67] +aad = 436f756e742d3637 +ct = 4b232c97fa9cef6fea482bd90002a6637629e59e6839aa4b51a9698b0db79ec010bb06aba00c1b05f282115181 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[68] +aad = 436f756e742d3638 +ct = 277542b55e05f4f5b6f1149a45e981973c860e140b0be9be700605be226b5482bdc94873971d7a03b03b180b1a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[69] +aad = 436f756e742d3639 +ct = d1bd44f2aaac3cec6dad09ec5939c8bcfeaa45a020b104af54db92805c150ceec660c14be21114e691c17100b6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[70] +aad = 436f756e742d3730 +ct = fe86fe64f4424a3cc43ae90ca90c4c829555be0d346195fc6f98c027326c5907f652e9ed292e88c262c8d1333d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[71] +aad = 436f756e742d3731 +ct = 4b1a3c565eb99b18edf4240a06cb30acf037dc1a932937f649c24c3bc313368f9c13aa814886886cb8250e33f8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[72] +aad = 436f756e742d3732 +ct = 82b190bd232d86589e0e1e7f37c0185ad0ddcf2b082c76429e1995b0d1f62acd588bba85b94f226da892db271f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[73] +aad = 436f756e742d3733 +ct = 51f98f99fa19184916e1b08c76345b5998ca5fa7fb5242aaa521f7b07b47cd53ac3dc9637e13b436ca617a0b92 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[74] +aad = 436f756e742d3734 +ct = 323a32f6c87217db499ac6bda975371333f1189a618fbad68e0d8887d1c71b0520fc301f259598de1e48b1044a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[75] +aad = 436f756e742d3735 +ct = 43227f6091853dd20734cbb1f0aa1ca58d8fcada7a6b8366a1ad0f777b34ebd040abcaed06be5dc6f4c05df706 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[76] +aad = 436f756e742d3736 +ct = 209ac341492e0d028320704c2af7c2a3ea84b86e6542b9b3f2a9a3b7da467d3faa471fe2dae932dccff31f30aa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[77] +aad = 436f756e742d3737 +ct = a68f24e02ad3f221d11e3ccd7f6a749f7e3c1b2f37bf20108ab4996db6c599d62ce4425bdb4f596b84eef05e12 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[78] +aad = 436f756e742d3738 +ct = 04309d4b824c4c2d7aa0586b90b18f3b96b8139e27ddc64b9a2e16850025b4e837b9c4e2965d46d69d5580a2b7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[79] +aad = 436f756e742d3739 +ct = 015dfc58fa0be8ad7b4fa8fdd2705a07c9d70a615abe09ea744535667f0a444616b888f16a744ba50bee990ca6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[80] +aad = 436f756e742d3830 +ct = 583194570397fd8c5f366627b695df81b281f70c97acb4f9e957739e7741e64aded30ed2bb892a082cff249d5b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[81] +aad = 436f756e742d3831 +ct = 2e8468cb395a1b361f4ae24d1fa7b080451edf50ebcc5a605cc0c64926a0a36adcbeebba318189e3a3f10ec1bd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[82] +aad = 436f756e742d3832 +ct = db3a33983fec5d55e1152118386a3942313dd11a52b43ea2453e555619bdd8f2272c4ae6b6b2e45afa0708e62e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[83] +aad = 436f756e742d3833 +ct = a55d4f5c9e4b54d5c430984040d9e3250a4ef60b51c6913ad9f0ffd24485c5220dce9368047b2bb275aded5d1f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[84] +aad = 436f756e742d3834 +ct = 7546ced9a69893f81e8a1fe01ee428f1fa989d81a91b67b37335d4e3d74f4c568e37673c8357aea9585f1bf8e7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[85] +aad = 436f756e742d3835 +ct = da9ad2308781a5e98f26623db55632458b1213d6255d9f93eec34dc122d92882a573f4489dfe8819a33712a56f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[86] +aad = 436f756e742d3836 +ct = 8807ebf2c3017769a8fcdf49724b6e87ce6b78946f157fa7b596909ded7f3fc5a74c96e6a30bc94c693a10484a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[87] +aad = 436f756e742d3837 +ct = 617fbe2f615fe2d78e7ebd09d7119ab6aff2f6948f5b11b0fdbb38f0097fe9728d87478699ba2c4418833e3111 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[88] +aad = 436f756e742d3838 +ct = 50a2a02f5394690595cb345db18c4da427fc31bd1e7aa225780a9f707296429f3ba7ea55dbfb4e9071ad46c33c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[89] +aad = 436f756e742d3839 +ct = 7ad5ce81fc409119042466e46b8b5f69a9ba6ef9ab8f774d6931971854ae54dd26534ac8ff8006c6c5b6bfc080 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[90] +aad = 436f756e742d3930 +ct = 9ae0d06ce9213dbea68533a6f45db7819a38ba452251aca8c648fd4ce55fa98ea1016e9b607bc2a1c86b9dbd5b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[91] +aad = 436f756e742d3931 +ct = 7411c84f11d4b995887faebd4068eb91f4cc6a4210e78db48a5b95349c55797280ee86efbf50aa4979c4291658 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[92] +aad = 436f756e742d3932 +ct = 00c70bb93351ff8c53993390f9739ba7c6ea01b7340d98eca81a48c833af3694586d80d9eb84a28609ae505e66 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[93] +aad = 436f756e742d3933 +ct = c1292deef48fbd48a60e5ceea9d2de9aa74d6a6c2f4ad7af550502d48e85340031608f7c6be408909723e96619 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[94] +aad = 436f756e742d3934 +ct = dcf02c0f52dad173ab81af5ba6a71c6aeab76a2f6bedb95a9686a11073ceaa555aad04cca16d61c3000d8f2707 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[95] +aad = 436f756e742d3935 +ct = 99c731a1024760cfabed4c9e6e06ba16362bf9cf8af0984e3e524a35c57e1b70132b401e879ac25b5a19e52608 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[96] +aad = 436f756e742d3936 +ct = 380da1568940ae8141c20d77a0c3ca063a0f742aad509a244cc4218a0894f2d4f70d442f2bc3f45e898e8709dc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[97] +aad = 436f756e742d3937 +ct = 577edaf7ba9b06c19d8b3afad647f1fbe2cfe0a1e56532a9942d4d3288dbcf2d65720c5cc5bee93b4524924e0d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[98] +aad = 436f756e742d3938 +ct = b8819cad3a864fabdbf303f761b2622ef5f12599684c59a81618b3e8055aae2b62030fa487e672339abb772624 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[99] +aad = 436f756e742d3939 +ct = 8d0ccbebe563ba37f5973677e0b3cfc333032d0c6fed82158702b1c39a3378b02e8a474079ee03e7be10c3f8b9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[100] +aad = 436f756e742d313030 +ct = f7b0d944940dcb42172ff7f050ced108a040c92cd111f62f64c7c52bfaf0768eb2c22fc50371c6c73a22abd7d1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[101] +aad = 436f756e742d313031 +ct = 8a2759704dd2c7712e7fc09674b5c786a0c08fe6abffecb93eae0667adfc68f5b69a8dd1527fe7ef9260b665a1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[102] +aad = 436f756e742d313032 +ct = be595d327a37a484b706780f14a48626426b35a61ca0c897304a8d3cdfa4e0f769bf7c489f207240a548494d1a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[103] +aad = 436f756e742d313033 +ct = 58081bd5e9bb449b50338e606a5c9ddb06323e0b30606ec2e7ba914e9783be9455c5864e5cd591cecda45d3818 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[104] +aad = 436f756e742d313034 +ct = 5b841f947cb3000c81e0dceb2a647d87fce6fdb8ffc1b168b483ce2a7575f03a02a4a7ec748b21a18d75d94f69 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[105] +aad = 436f756e742d313035 +ct = 7db27590c2b9d81f0c51505db4aff4aba0114977c04ab386078368f4a6efa239d94efb93c2291a031dae851324 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[106] +aad = 436f756e742d313036 +ct = 3d3d4b63bf33ffe734df92cdb7ff38133c3661f985770e814d5961c8bf8934b7151f722fc0d801afa031cd9a5c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[107] +aad = 436f756e742d313037 +ct = a123bb67617a8d49db372b9158d3b741b55c6052bc23ac936dc1c86371594fce34e40f7a85041642f2941442b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[108] +aad = 436f756e742d313038 +ct = e593774a7353ef7730ee7fedf79199fd47df3f4a0f35aad4a584112283d137bb7d1fdbcf9d8980ed4244b6eaec +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[109] +aad = 436f756e742d313039 +ct = a083192b5973ed1a6adb237cec62aad1a304ca0044e272fc023f3a906f696bd60f545f1dbc0ec7ff551619e0a4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[110] +aad = 436f756e742d313130 +ct = 7bfcbaebb82a899a39ea6c34bd76be9358f53e7397d40f76b46c7262510f264d547c56fed89a688c4d9a2b2e4b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[111] +aad = 436f756e742d313131 +ct = fbfc7bc29317c97a62de2ec25cdef1729d169986b334f9272a50110e1b37a71b6cb1e12b762022d4f49685979d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[112] +aad = 436f756e742d313132 +ct = 21fa26c371405a806346f540f8c82bd562d517a1a9bc531f089819b7bcd66cd6adf4e93afaf2aa1b7ba2f06baf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[113] +aad = 436f756e742d313133 +ct = 6c254fb53652021322d5ef73a16b6562e57432f51ac20b364aeedaae603cd4f391b06f305d9a2fb266a2d3e55b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[114] +aad = 436f756e742d313134 +ct = 9d0e3c870e95145533491b24626dedfa8c2b54508ea88310c285e60d4064f3e033aa9ed7b0d06e759e9bb8cc1d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[115] +aad = 436f756e742d313135 +ct = e18e654b8bfb3ebaa9a42de68fc117f1df0b50d1f690101d7ea5905441733f776a1bb789f6490dcd902b232924 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[116] +aad = 436f756e742d313136 +ct = 44c2bc8b27fbcc94f7861e6d115203940d437c0bc10f6abfe3f7f54a1dbbf7e16d83a624de58d6d984db4629aa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[117] +aad = 436f756e742d313137 +ct = 40c149be04bf41e6edc15e40f44276ab6b76f9e2da3a6060680075467b696310320d3bb21ba23de62070cd2d56 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[118] +aad = 436f756e742d313138 +ct = 582a5f80a54af024cdde0bf597d332f94b58094ad4930e470e9122a00da2823761733ed6efd7ebb208e5dc11c6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[119] +aad = 436f756e742d313139 +ct = 6fedb508a62f8119866fa2f77680511461d6acffd5fe5c9cbdf755d0d696416245e94efe70c440d02968f4682e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[120] +aad = 436f756e742d313230 +ct = 7b0baf62119a4aa6f261f840ff529913c0d430042581939fd5c4c706eca535d4bb8b27f4b85b063d6c4b672194 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[121] +aad = 436f756e742d313231 +ct = 788717ddb583b85e508ed3adde0a02dd665d887ef538261718f5e08a1d25ccd6d3f669bed5ce34cb12fe94512a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[122] +aad = 436f756e742d313232 +ct = 2d306491874eb01fcbfeeb9ca73bb6ae048077b87f524e597cc87e560ae8faf08a38fcac3b1608431715b232a0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[123] +aad = 436f756e742d313233 +ct = e5b3e678e0e0df8de042871dbc3d2bc3acbfbda12646825ae162340636177e73aebc28265cb0430553940e5cd5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[124] +aad = 436f756e742d313234 +ct = 6efccc349b12e2f49b660d577783681b571aa00faba56cc51e71c041eea5e2c855090a0183b395bdc5c1e649c3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[125] +aad = 436f756e742d313235 +ct = 5a43b00495f38c68f39eed4151935cbb44104f3aae74307c474e824f8f5e2cc4bc967c4b9fe8ed41a6e00c1704 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[126] +aad = 436f756e742d313236 +ct = 884e27f01a7fc3b3c01204a8d4d21128c597a06aca13081e82305ab6b3369d0ea39c401088129d9484d511dbac +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[127] +aad = 436f756e742d313237 +ct = 6708a8ab40099f4fcc5ce3a1f4c1eaad0959f40d52d7efde9805a1e309cda3da9a229e3388f7fdc5798ddcf8ef +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[128] +aad = 436f756e742d313238 +ct = 2b59c9116a3cf4a2b1ff7b862f05d0a9f4fa5b21beb071a417f9ddd229fbdd3160fcf1f5588f85fe1583d910d3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[129] +aad = 436f756e742d313239 +ct = 05e5f0ef2c208da0fce32169d86aadcd206ca2b1a64f06b602cefbf791960f99c6763708362b0d321e8b917bd9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[130] +aad = 436f756e742d313330 +ct = 55fbb90f11eb01007b31682815a474280ab8718957856ad32b4dc0d86f71fd49ee1000957b76ba3f56ba5749bf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[131] +aad = 436f756e742d313331 +ct = cfffd60cbd241199eeaf529be3cbef77a67d9c5b62fd65861c84056037c73149988be4d6031d036b9d5ead6494 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[132] +aad = 436f756e742d313332 +ct = e065c3fa01c9b0d1d2c20132b5fb21d85c50715ca55d85fbf29e29c95b4119dc054a02a7061e9373ee6ed49736 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[133] +aad = 436f756e742d313333 +ct = 2ceeb7fe75ad7845efa4867ad23de6816467b5305f5bec964c5d4726e6cedc42e18654c2000cddbdd18e013382 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[134] +aad = 436f756e742d313334 +ct = b0a31296ead350554678e5460b31ce11c7f5928433ee2f948f441702112d838718170e81f4b3038139316a154c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[135] +aad = 436f756e742d313335 +ct = d8e3e2a3c1452588477be454dea80c7ec1d84f63430fdc46143bbabd77348c37ac4eb24fa23ae7b4fc0e5bf04e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[136] +aad = 436f756e742d313336 +ct = db487ed57bb04f39a39e6ae8e82e86ff0efb765c47bc49333671b6394b2b50f0e56907adb2a40bedb7fe70c460 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[137] +aad = 436f756e742d313337 +ct = 7f7277bd1a14fb3843c88306b5f7480c2621b98d76a42e5cb6f3ca139443a2f3a07fdea341dff01e29d68a5afd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[138] +aad = 436f756e742d313338 +ct = 3fc4dc2569ecf94fc28f7a61109351c4ddb7648d7c42285cf33d732075e3852d528cb7e0858313b5be0f00c6dd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[139] +aad = 436f756e742d313339 +ct = 825c39e7cfe13ce352225b76abcc4f434d3fbf8e1209f852326ae195c669ce411b150149e14d4634b6eedf0b05 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[140] +aad = 436f756e742d313430 +ct = 9de9581a72f883c91a4e160c2a9ebb75e41538a9612a930b86d5c86cef16c4c88c86c6cb9c4b4aeb91b9ca988e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[141] +aad = 436f756e742d313431 +ct = e04a92935f4ac59e99aab8d602b4816bf7c1dec5d5d47e5d76f75bdddf80ac7f6ed46e6a0986c5d50a980a61d3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[142] +aad = 436f756e742d313432 +ct = da4285f3b19a5a63611948f89a9141b060987ac46739c68e65d85e1265043efdb0aa5d390b9e216660c29c9185 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[143] +aad = 436f756e742d313433 +ct = 72c1383d0adf2021832cf8e7be8565f68f2693fbb79d1b181331fb84c189d8543cba13e6b7a6dea80208bb6f39 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[144] +aad = 436f756e742d313434 +ct = 7ffaef3ded32191024d313221da9a3652cfd1ec17cf65aff57b1b67224e5ff7a931e32c72ebf8b226911bddeee +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[145] +aad = 436f756e742d313435 +ct = 8eaf068482dec200d6e13a15f23fcb59f30cb2948ac226aecd002cea99c89686daf77848f956933cc25fd26f48 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[146] +aad = 436f756e742d313436 +ct = 264cc5d6a0b7a0b10f6b1b3248b5a3324e3d6f478145618d09c47fa28978493bf1aff64ed4fabd094d5ddabcc6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[147] +aad = 436f756e742d313437 +ct = c148c4bcadd21fdcdd7e068507fa3ca526b14443164eaff48a81db46148cd2ae333bfb325a335296bd19efbbc0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[148] +aad = 436f756e742d313438 +ct = 098d1dc0cb7cd977948f0b44542af26e09aa4d6ea63b17b5e72a78723ca9efe1eb002c98a08bdaa8b3fda0b7b3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[149] +aad = 436f756e742d313439 +ct = 13fc200eb7d9ac3ec5672a9dab0e813903576fd05bf8fb7ee5635fcc8741419b869a7b8d9f863b12e88e2c5930 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[150] +aad = 436f756e742d313530 +ct = 81a5873565aca0a8bf27d7e0a40b5190406a8be971a79e71a249fbba371cd6e95297140bf30a9a247db65b5573 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[151] +aad = 436f756e742d313531 +ct = dbc759f3edd826642105b502435edfb28a66c7c9053f77f701d019e8054a854c50ddd9951c8d329afdfc5afaa7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[152] +aad = 436f756e742d313532 +ct = ddf2376a8e02ff6aae395fc4455a4c776c0c9783453a2e42b28b3ea3cd1dece1d6a87924307611ccab815bbc4c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[153] +aad = 436f756e742d313533 +ct = 87757e2c0821f95564bcc568723acb7171f293e955173726017985e9cb3383b33ed8066fa6f48ceaa6cac6df0c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[154] +aad = 436f756e742d313534 +ct = 036d4fd7e9e72929cfd2e1fcecdc572aea5bd5ef16a92e5b711cdd9646eb3a1008a2e7d39ce74e67df6b73f468 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[155] +aad = 436f756e742d313535 +ct = 5cad074af3887ff07a8d3ce2e8a20e67feba06ba4893e26f14123894d7819392f827f646bb28cd29bfbf7be7f7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[156] +aad = 436f756e742d313536 +ct = e52d575fdb08e3d2084927dc3da9c7084bcdccdc88d997de6e06109d203b2c030ba2cb79a50ae8e0e738fc0736 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[157] +aad = 436f756e742d313537 +ct = 4c98fe2ce4b77757ee09bfef308f9973c2aa28939ab24ef5fe619124b1c94e3aaf67d7739b22af2f3e158a04c8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[158] +aad = 436f756e742d313538 +ct = f74e7f2532e417fbcd01f4683bd5ea14e94dd4a42f0834819d283c39f27fed8c3dc8dd3e74dcd5fb525d099044 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[159] +aad = 436f756e742d313539 +ct = 48aa523a358b5777f7dbe60c24eaa1240bd2fc186d91b7d9fd340a62cdee8a79a84785873efb9ff65bfec68f6f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[160] +aad = 436f756e742d313630 +ct = ce4db0c062b8195e46f62aa014b1cd99c00697e6c04cb0adeea45f076ae31200cc03f32e224c585208e580fc87 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[161] +aad = 436f756e742d313631 +ct = a53b8dc05218c1f4dfcc2af880df86233ec8fdcf3697c4ffee694c0c042fd545e01a652fb30ce0c46c00f1c7cd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[162] +aad = 436f756e742d313632 +ct = 18459e8a46abe63533022ab99edc9417f41f0e43704e3146bf7b3638d9ee9715e89d2593f47296d6e287fc25b1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[163] +aad = 436f756e742d313633 +ct = d3d522979eeb9e6be40d83ad69cff87fc3b1c7b664629454f97087a61de9743586c129ba27849449edc3e218dd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[164] +aad = 436f756e742d313634 +ct = 8ecc61ed64cea2091b3e5b13ebc92f91f3daff14b029c0741b7b7541b5e4c4db44e6cb3ead3f379ab6f7ba2134 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[165] +aad = 436f756e742d313635 +ct = 2344551199f0e4ffd040d05ebd33ed4e72b8798bb9e0a48c3cad3c3b6953dc51eeb28ed9bdf7dda5c96faf453b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[166] +aad = 436f756e742d313636 +ct = 45247cc2629c2dceda0e9260ae8cd347d82ffe9986407b1d4279216ef9599dbdb6427d5a8b1ca999b6a86626fa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[167] +aad = 436f756e742d313637 +ct = 451db2902d2b4391c47be9a54d5d53b476b5d5d71ba02832fa5b28f35c5a0604d161f4b2baebb09013ea8d5d1b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[168] +aad = 436f756e742d313638 +ct = 97fd72b9c01b4974522d4bd494563f05404725034db95a4b4bd6dd147d6258cfe473e5425c39273302f654f09c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[169] +aad = 436f756e742d313639 +ct = 77ef019177e690acfe0eceeaa26094135271e14125c3c9d84d539bf86150cf2f4d5e1871fcea5ab3a881e98f10 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[170] +aad = 436f756e742d313730 +ct = 89819d7bbe96c3cd71d90279ae98765d701b3b21c07dc287b6b5af0fab9e4569dbf57701e4e20a9a68840c04e7 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[171] +aad = 436f756e742d313731 +ct = bf4206d7896f079093d3e6fd309ce43999554b8d961f51e2070bd23850cba7071065369af22a56122318a34d9a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[172] +aad = 436f756e742d313732 +ct = f10322e7dc93246fc9528b238fda0e8bdc779b908ac5dddf1411b2aaff19dddef9a5ea8eb464ac38939c5147f5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[173] +aad = 436f756e742d313733 +ct = e2a426d1a686b4d994cc9a919c50a207f5c86c5d4f019592fd0c3255dea61a5230be629c77d69bcaebad454196 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[174] +aad = 436f756e742d313734 +ct = 8b0ac7f5154a3adffe0463b0a7c86e7397bcd7ad1eb9db45721c6a472f55a30546de99cffd4042fdd7ac071b27 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[175] +aad = 436f756e742d313735 +ct = 712953e4994fe54d6a5e02d1ab33df9b5f028726af60795aa8571ab53a1cf3c44024cd40d2bfccd79afaabd13d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[176] +aad = 436f756e742d313736 +ct = 929f4f028c846ed34b643f5bf111e7c2b2cc38676c37918be2cf1cf1432528194f8210eebb330415ffec3ee601 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[177] +aad = 436f756e742d313737 +ct = b5622dd7e3eec8cbb474ce5ec72505100f85c98725c2ab0ec69747b6a8ba6740417c1b90ba2d285f2e7e8aed23 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[178] +aad = 436f756e742d313738 +ct = b94bfdec74e4da59e23a0abdf35e78230df609e6e939e1590483ccd7168cc0d730afa2aae1bf5c04c10b5d146f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[179] +aad = 436f756e742d313739 +ct = 825fd8362d28d8c9ee2cfeefb8baa0ad579acd6380cadd617eb4241a45571fe75407f1c3c288476a1951f13799 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[180] +aad = 436f756e742d313830 +ct = e91fd4c291642964a2e3206668e41e7a833b3eaf3c73d8ae18224479d5e603ad0d266dba04d07e187dcc7e8817 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[181] +aad = 436f756e742d313831 +ct = e9cb31df1943fa60763a5883b2dd803f1a1e114b945ea746fe1169ee04206339a109b33d6dd4963a46c95b9d60 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[182] +aad = 436f756e742d313832 +ct = e907d69102325aaa155644e2fbf83402752bd7c769abc9d587eaaddf75fa196de4c100c9dde8ab273328f8895d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[183] +aad = 436f756e742d313833 +ct = 7ec7579899f8c4000fce0f7b6c5ebfaf4b65cf973181dbb4f8cae39256ab61843605f58dd2f40e5a375136011b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[184] +aad = 436f756e742d313834 +ct = 6470ca4f7442d31ac907fcf167ad10b185ea0673a48f0fb52e08df541707ddfce14df56e1f1ec136eceda5dde8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[185] +aad = 436f756e742d313835 +ct = 712c2484fee14b3eaeaf6e68f22016121302a6c4071e3bb4dcb41315bc056c7de29504bd30461dc61e2a62290a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[186] +aad = 436f756e742d313836 +ct = 1089d0ad01eb981b0e75d04ac8ff62a2a8b611b932bb524cde1a33f1103765022b056f0d082aa41d162e9643be +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[187] +aad = 436f756e742d313837 +ct = 7055173920dab9eccfbbeefe136fc57ef767e1e8e6db8eae6783235755ae9b0cccdbca572fad83b28bcc7b4248 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[188] +aad = 436f756e742d313838 +ct = 62a7f47491f3d31a422fc9e908823a8f2d7254f36131d363c32df985ed6dda80871e3829375f25a96d90b45235 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[189] +aad = 436f756e742d313839 +ct = 192f865b9b0f87c8f3b35b2ce1900e3687554a48736e6188aba905ef472c7377db213d32d56b903f7be0acee06 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[190] +aad = 436f756e742d313930 +ct = d0f7f686a5225d8183394c33b1f10c707e7f085660f858d3491198b3a9b4e42f6a9eb365c409993c59093228aa +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[191] +aad = 436f756e742d313931 +ct = cf3f64e8b054cf660298d2e7ec7d644a2337429476a7108f14f491345c42e1164a6d96a83b0c56ebee45cce38c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[192] +aad = 436f756e742d313932 +ct = 9893da31204738a3f8f4c107c533f64cf8c01b81060308576cb94bfef56c7c204421503eda93d05f5f9ff3f7c9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[193] +aad = 436f756e742d313933 +ct = e407a8a84fc18a3df9833de5ce4e227f338cbe0549bb70d1b30abd5c8ad89f0a0de24bc8dcdb8455c80f507cb3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[194] +aad = 436f756e742d313934 +ct = c400c9a6494c2c62cfc420c7348f03b5598648842115975d204d7b039b3e6bec4f5a24b879d688b590ea0ad3fc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[195] +aad = 436f756e742d313935 +ct = 49ab830a7a7be18d1fce87538b02c4514ce2e33fe7dd0041bf206923270ce1eae49fa7afdcc23c2e7095ccd371 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[196] +aad = 436f756e742d313936 +ct = d5beef3acedf662be1ac545ff22e0968ded5e7f835082563cbf32f2f97e2ec57ac0a24ef9b69b311c08b2d0705 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[197] +aad = 436f756e742d313937 +ct = 3200011bd93203e202108feb721f33cff9adf984d7b765c152c42c71a08f6a4b914f59aaea2373dede1d84f49c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[198] +aad = 436f756e742d313938 +ct = 0d546040e599350adfce92d598fc83b2f17b8210648ff39c91d7382f1ddf9316fd55762a863bd39ac183d71cfc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[199] +aad = 436f756e742d313939 +ct = 56d782dcc5ae009b8b10f486678fc31d04d3e2c2fd14557bc160540eb5b40eb2f4d76a2a54f6ca7debbc8f6091 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[200] +aad = 436f756e742d323030 +ct = 57584651099749aa985fa971b34618aa8d30aa9c1fcbc8cd15d887ee5ab0fa3d515d8dbba66eb3b1bd53d5849e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[201] +aad = 436f756e742d323031 +ct = d18e9ec60dfb849deb7f665a032f5819b9d047516a4be94a48e8bd2066662d183f7853b3baadfe8971e34a88dd +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[202] +aad = 436f756e742d323032 +ct = b05faf558aeadfc164859a477e9cbcab1d27edf19bbcb35a813aa49282b42f8a20bf5fcf943ebaa6d94f93eb32 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[203] +aad = 436f756e742d323033 +ct = c069204693e8b828a9ac4d6001f8b0c49a9e7f606a45a8829dcfbc7ef0c23618f7c5ac44a76b00d6b06bd32e5f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[204] +aad = 436f756e742d323034 +ct = 957d7c12afc411e4c87d7cc1bfac25e4f3391aa9d71bfd0b8606ccd7565a78c39b02c7c9d763a2d3529600f7f1 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[205] +aad = 436f756e742d323035 +ct = 648a024a31fd41c542eb6bc1ae2bc234ad3cb899fa65b1d22e947f061c5804f86df390f8ae79642630c26ab5e9 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[206] +aad = 436f756e742d323036 +ct = a54a551ae735941e911b84b09c3a33b97c8324f745220f78a0514ad814502654b0377fb45e8628575a7fb14018 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[207] +aad = 436f756e742d323037 +ct = 35dd21130084fcf97491b42348efcb8271dc611c94cc57d9f1d7700efdcb207d9b725aab10b33868cacb53b5b4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[208] +aad = 436f756e742d323038 +ct = 2d7946eaf65d501637c5a51139ffe27bd5c0189c986731e9519ae256f17cc2b363adc654e28622236e9517007b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[209] +aad = 436f756e742d323039 +ct = 2182643ecb216095a07ec8e341bbc3bbd9700b98cf6108caf2c6e6a99c567ae9650e18e7137784ea60c0037bed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[210] +aad = 436f756e742d323130 +ct = 5cb48c09ae88281008141e22f274be6aeab55d061bd0592388330518bd4e9877f14edcebcdaed09b17839526eb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[211] +aad = 436f756e742d323131 +ct = ddb662da553a5f64f9e70dec7a00b5fe2492c5a8e7fac8b11a24225fec99b72b46a259f58d30ea1e565c3621d4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[212] +aad = 436f756e742d323132 +ct = a812ef927ca2d5a7e6f6c25dba203a28b3749e94ceda1d2ae2f1e4a9607304521eb2b87a74ea8d22cbddee107e +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[213] +aad = 436f756e742d323133 +ct = 94f9430c6563ac09a8fa019177cb0bf6be3e222e3299211cb771a2e3c39dc490ed2962621d18988f6a8494dcf3 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[214] +aad = 436f756e742d323134 +ct = 88277b8afc800e1bb7f26f46223b8ec3175d1397c6f132f1930429397b40bead4dfbd194f030b5f9eefeb88c39 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[215] +aad = 436f756e742d323135 +ct = 409e3d1897304b141d13abe0f59a4b10d0af57618577b340ed6d5480e4e83457b7186a3ea05a18f80a9a6cd637 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[216] +aad = 436f756e742d323136 +ct = 7ec49da8a4de583b3edebc5b67357cc3ffc51362866c02523ababe69f6a5ee3049d737e25610eb0c3a61899f0f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[217] +aad = 436f756e742d323137 +ct = 4246008ed7b0791df31f88250292a3a1e26dd47b14035e9ee4279aaa5d51bf2dfb594d68761ef239da62d38d67 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[218] +aad = 436f756e742d323138 +ct = c5d310202308ed77fb3bef60298eac77608ae541bc5ab2d9fb3e43c1b3e2f20cb266927ca85af01353dbaa0166 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[219] +aad = 436f756e742d323139 +ct = 812334975ad365ad977fe1df9fb18bfba5af83ee39455f877a9f496c1e883f64571917ce52499479270c7db7cc +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[220] +aad = 436f756e742d323230 +ct = 7455ec4dafadc6a32c4a1482e78e7c80d34ade86bcf44860230055fedae26b642f2577dd5ec3742e06fc72b285 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[221] +aad = 436f756e742d323231 +ct = d99776edf6dfa1683b926c03a35a08f5fa6e5ed4307a6bffec785ebe2ad4663e824aea40958ef2fdfcca851a3d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[222] +aad = 436f756e742d323232 +ct = e1773f8fd60b35fe8459a194b3ed05ba72f4d0f16f64169577e2ee4f0d1e9dd1fc5bc5d10da552ae5fbebb0605 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[223] +aad = 436f756e742d323233 +ct = b0977a21fb86e2f53605146703243dd713979041ad41b7f4e2eb07a81823a741dfd6296f7a021d0863cdf407a6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[224] +aad = 436f756e742d323234 +ct = dcc76d9c0b453f3bfa0e93e4b21665157670d6363a0444bcc2cbbe3a82017712420fa62e5976f1eb459627350d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[225] +aad = 436f756e742d323235 +ct = 4630e92285a0940af56c00a34b93ef07e755000d4b1faafd93eb01a076798dc5304c9119ca4b458ba39742a4ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[226] +aad = 436f756e742d323236 +ct = f980e55d2dd9dfbd6f0d7f26e681cb6a99b01536ed287570db15819ebadea6c383970e5935faa97f3f7567d419 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[227] +aad = 436f756e742d323237 +ct = 8b1b4be8257e2d2383b2b5236ac58a4bbc0619129a6af82201034f27bf762f14c9e113d36b94066a52b81edb63 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[228] +aad = 436f756e742d323238 +ct = 79368883a496b5f8962d2dd3c54116730aed4a6652fd2c222490470b66a91fbf2d8abf8d1336cf596a0c89b488 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[229] +aad = 436f756e742d323239 +ct = 6e0315642bc29b8a0f6eae9f0f3772c4af2d9451b6756847cefce570299cc8a09bcb14bd3c8e4e348dc60a80cf +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[230] +aad = 436f756e742d323330 +ct = d74717cc168f8cc3340346e442a7b789776ba2f5f3f50b18cb61608f1a638d57d5f6f819713bf617936f7193da +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[231] +aad = 436f756e742d323331 +ct = 8885a9956a8864f070e8b83175dc2a76208c32c669fd64c84c7efbc9eae048e3a3bda1a6c5e9e014177985f345 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[232] +aad = 436f756e742d323332 +ct = 8248c633eb511e4148c97a9d997288ffe3e9b130f7e1768900e07a3dbd0322bf5feaa3ef1069a69d2f63b8b5e4 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[233] +aad = 436f756e742d323333 +ct = 661b8260a395a229aadb89a0b0afddd08f65597d5e2965763b4c8779bec4f5a91c6a73f395ee45aacdc03f244c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[234] +aad = 436f756e742d323334 +ct = 9e270862f567f91b5fc378247693a6a598dca076802c15f311ad977c862cae39feaf9da66ea276e3f6826ecf3d +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[235] +aad = 436f756e742d323335 +ct = 9e07269e710dea587007ea36f823e5a6c361a7d852e411d0f608468b61a1a4cda1e79cfa8ae3e0398a471970b6 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[236] +aad = 436f756e742d323336 +ct = a2cd8eb604f9dab48b73b5e09a99be8b4fffb8eed1ae639866fa1626acba6469a4389f867c068601e1622a61a0 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[237] +aad = 436f756e742d323337 +ct = fe968506c8c9a82cac93961e2470e048eee80c4a2898677f624d8a1051412475ea905a499cf6eabe8c2ec58348 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[238] +aad = 436f756e742d323338 +ct = bb45acdb4652e760404402bf5d2a424e8fccc7c5dde8b26338ad64fe2b2cd5e53f32e9e3f69a896bfc3489408f +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[239] +aad = 436f756e742d323339 +ct = 828fc85f305e3e63442ea0b178d182b53055c4ad909be23ed57603d9572f8c146e17648a3a4787c120daa8feed +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[240] +aad = 436f756e742d323430 +ct = b0bbbc30e91367092697057b87e49a0278d6783e7100e58052aae3d6e43d86acf15aa52826bc29b0e1a3b22790 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[241] +aad = 436f756e742d323431 +ct = 2dd238f23bf4c01ec65d5a5852358a6179783673414daa0007ac448744072057ca090203229d79ad6fa7676219 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[242] +aad = 436f756e742d323432 +ct = 1f086bb895f86ebca24d03d530e085e64e99194e4c4b741d80a8ecfda0a93c791b84b9c5df8fb054573bb3cd55 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[243] +aad = 436f756e742d323433 +ct = 530bca4e6045806f7cbc7f47ccbfbaab6fb78470f1d722f039f37f9ce03dd0f7c466f0288cdd70bd76e57298ee +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[244] +aad = 436f756e742d323434 +ct = 32d031fe93733f5494d4bf4cdf2f331e477e993daa98fea19601255e768848fac11410026b796e10b106ae8e80 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[245] +aad = 436f756e742d323435 +ct = 0dfb7b313aea0e91dcd2ba7595ee587ec910e6c669f2518355538dd4be47e137873db3c9b34b2ac95ac3f7278b +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[246] +aad = 436f756e742d323436 +ct = e602015ac66b00e8b34b1091368b4e1f3eb1d94277d6dcf11829a8cf3a71a554e6e2df953c916f278aafcc072c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[247] +aad = 436f756e742d323437 +ct = 9dc47953aae535a27441e77b6eee0db9a884f69c6c3ba1e6ef046d04cad1b4028c34ae259900853f104e6d5edb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[248] +aad = 436f756e742d323438 +ct = 1b174d49afa1ed54c34a0d23921d4426b72133b094e5876c9f5089a20bd01ee740b9bf9623d35079b2a7f764ea +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[249] +aad = 436f756e742d323439 +ct = e9a9a9a54a5909f74cbaa86707b6a3db088f2a4458d3075be9d50795284abf0912ac094a17e8228011fe8584e5 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[250] +aad = 436f756e742d323530 +ct = 5c21e68187f15c7d68c30c1d515567a6bb812f79646c97122de81e2f4603487f2398622ad573ec22d6c8d07b9c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[251] +aad = 436f756e742d323531 +ct = 5ebbb4ce70e2e65fd6efc03cf6fda8892321740fec30ea21fd742dbc1b53f531f58697dced5c6b1623bf659feb +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[252] +aad = 436f756e742d323532 +ct = 0d4a1a33581ef910547ec8bde264a46441bcde2e06050b780d887bebc13f7853ab8b264fe4633cee8c4caed106 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[253] +aad = 436f756e742d323533 +ct = 4e89d3f7b4f86e71601eb768ac42df8afeb983c18397fd4f277e3d1caa631d66960f923798e4b0fcd78c1ccb3c +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[254] +aad = 436f756e742d323534 +ct = b640e286eef2d6078f8d5a3e801a2466042121f5f001f8ac8f3461cc261c9f772904b9c15cead99bf305063f29 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[255] +aad = 436f756e742d323535 +ct = 652e597ba20f3d9241cda61f33937298b1169e6adf72974bbe454297502eb4be132e1c5064702fc165c2ddbde8 +pt = 4265617574792069732074727574682c20747275746820626561757479 +# encryptions[256] +aad = 436f756e742d323536 +ct = 3be14e8b3bbd1028cf2b7d0a691dbbeff71321e7dec92d3c2cfb30a0994ab246af76168480285a60037b4ba13a +pt = 4265617574792069732074727574682c20747275746820626561757479 +# exports[0] +exporter_context = +L = 32 +exported_value = 070cffafd89b67b7f0eeb800235303a223e6ff9d1e774dce8eac585c8688c872 +# exports[1] +exporter_context = 00 +L = 32 +exported_value = 2852e728568d40ddb0edde284d36a4359c56558bb2fb8837cd3d92e46a3a14a8 +# exports[2] +exporter_context = 54657374436f6e74657874 +L = 32 +exported_value = 1df39dc5dd60edcbf5f9ae804e15ada66e885b28ed7929116f768369a3f950ee diff --git a/third_party/boringssl/kit/src/crypto/hpke/translate_test_vectors.py b/third_party/boringssl/kit/src/crypto/hpke/translate_test_vectors.py index a4e399bf..6879e421 100755 --- a/third_party/boringssl/kit/src/crypto/hpke/translate_test_vectors.py +++ b/third_party/boringssl/kit/src/crypto/hpke/translate_test_vectors.py @@ -19,7 +19,7 @@ Usage: translate_test_vectors.py TEST_VECTORS_JSON_FILE The TEST_VECTORS_JSON_FILE is expected to come from the JSON copy of -draft-irtf-cfrg-hpke-12's test vectors, linked from its [TestVectors] citation. +RFC 9180's test vectors, linked from its [TestVectors] citation. The output is written to "hpke_test_vectors.txt". """ @@ -29,6 +29,7 @@ import sys HPKE_MODE_BASE = 0 HPKE_MODE_PSK = 1 +HPKE_MODE_AUTH = 2 HPKE_DHKEM_X25519_SHA256 = 0x0020 HPKE_HKDF_SHA256 = 0x0001 HPKE_AEAD_EXPORT_ONLY = 0xffff @@ -49,7 +50,7 @@ def read_test_vectors_and_generate_code(json_file_in_path, test_file_out_path): lines = [] for test in test_vecs: # Filter out test cases that we don't use. - if (test["mode"] != HPKE_MODE_BASE or + if (test["mode"] not in (HPKE_MODE_BASE, HPKE_MODE_AUTH) or test["kem_id"] != HPKE_DHKEM_X25519_SHA256 or test["aead_id"] == HPKE_AEAD_EXPORT_ONLY or test["kdf_id"] != HPKE_HKDF_SHA256): @@ -57,9 +58,9 @@ def read_test_vectors_and_generate_code(json_file_in_path, test_file_out_path): keys = ["mode", "kdf_id", "aead_id", "info", "skRm", "skEm", "pkRm", "pkEm"] - if test["mode"] == HPKE_MODE_PSK: - keys.append("psk") - keys.append("psk_id") + if test["mode"] == HPKE_MODE_AUTH: + keys.append("pkSm") + keys.append("skSm") for key in keys: lines.append("{} = {}".format(key, str(test[key]))) diff --git a/third_party/boringssl/kit/src/crypto/hrss/asm/poly_rq_mul.S b/third_party/boringssl/kit/src/crypto/hrss/asm/poly_rq_mul.S index c37d7d0b..eaf45a87 100644 --- a/third_party/boringssl/kit/src/crypto/hrss/asm/poly_rq_mul.S +++ b/third_party/boringssl/kit/src/crypto/hrss/asm/poly_rq_mul.S @@ -12,7 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && defined(__linux__) +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SMALL) && defined(__linux__) && defined(__x86_64__) #if defined(BORINGSSL_PREFIX) #include @@ -8489,5 +8489,5 @@ ret #endif #if defined(__ELF__) -.section .note.GNU-stack,"",@progbits +.section .note.GNU-stack,"",%progbits #endif diff --git a/third_party/boringssl/kit/src/crypto/hrss/hrss.c b/third_party/boringssl/kit/src/crypto/hrss/hrss.c index 0247001e..572e9817 100644 --- a/third_party/boringssl/kit/src/crypto/hrss/hrss.c +++ b/third_party/boringssl/kit/src/crypto/hrss/hrss.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -38,8 +37,7 @@ #include #endif -#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ - (defined(__ARM_NEON__) || defined(__ARM_NEON)) +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && defined(__ARM_NEON) #include #endif @@ -189,8 +187,7 @@ static inline vec_t vec_broadcast_bit(vec_t a) { // compiler requires that |i| be a compile-time constant.) #define vec_get_word(v, i) _mm_extract_epi16(v, i) -#elif (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ - (defined(__ARM_NEON__) || defined(__ARM_NEON)) +#elif (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && defined(__ARM_NEON) #define HRSS_HAVE_VECTOR_UNIT typedef uint16x8_t vec_t; @@ -929,6 +926,20 @@ struct poly { #endif }; +// poly_normalize zeros out the excess elements of |x| which are included only +// for alignment. +static void poly_normalize(struct poly *x) { + OPENSSL_memset(&x->v[N], 0, 3 * sizeof(uint16_t)); +} + +// poly_assert_normalized asserts that the excess elements of |x| are zeroed out +// for the cases that case. (E.g. |poly_mul_vec|.) +static void poly_assert_normalized(const struct poly *x) { + assert(x->v[N] == 0); + assert(x->v[N + 1] == 0); + assert(x->v[N + 2] == 0); +} + OPENSSL_UNUSED static void poly_print(const struct poly *p) { printf("["); for (unsigned i = 0; i < N; i++) { @@ -1215,13 +1226,12 @@ static void poly_mul_vec_aux(vec_t *restrict out, vec_t *restrict scratch, // poly_mul_vec sets |*out| to |x|×|y| mod (𝑥^n - 1). static void poly_mul_vec(struct POLY_MUL_SCRATCH *scratch, struct poly *out, const struct poly *x, const struct poly *y) { - OPENSSL_memset((uint16_t *)&x->v[N], 0, 3 * sizeof(uint16_t)); - OPENSSL_memset((uint16_t *)&y->v[N], 0, 3 * sizeof(uint16_t)); - - OPENSSL_STATIC_ASSERT(sizeof(out->v) == sizeof(vec_t) * VECS_PER_POLY, - "struct poly is the wrong size"); - OPENSSL_STATIC_ASSERT(alignof(struct poly) == alignof(vec_t), - "struct poly has incorrect alignment"); + static_assert(sizeof(out->v) == sizeof(vec_t) * VECS_PER_POLY, + "struct poly is the wrong size"); + static_assert(alignof(struct poly) == alignof(vec_t), + "struct poly has incorrect alignment"); + poly_assert_normalized(x); + poly_assert_normalized(y); vec_t *const prod = scratch->u.vec.prod; vec_t *const aux_scratch = scratch->u.vec.scratch; @@ -1317,22 +1327,24 @@ static void poly_mul_novec(struct POLY_MUL_SCRATCH *scratch, struct poly *out, static void poly_mul(struct POLY_MUL_SCRATCH *scratch, struct poly *r, const struct poly *a, const struct poly *b) { #if defined(POLY_RQ_MUL_ASM) - const int has_avx2 = (OPENSSL_ia32cap_P[2] & (1 << 5)) != 0; - if (has_avx2) { + if (CRYPTO_is_AVX2_capable()) { poly_Rq_mul(r->v, a->v, b->v, scratch->u.rq); - return; - } + poly_normalize(r); + } else #endif #if defined(HRSS_HAVE_VECTOR_UNIT) if (vec_capable()) { poly_mul_vec(scratch, r, a, b); - return; - } + } else #endif // Fallback, non-vector case. - poly_mul_novec(scratch, r, a, b); + { + poly_mul_novec(scratch, r, a, b); + } + + poly_assert_normalized(r); } // poly_mul_x_minus_1 sets |p| to |p|×(𝑥 - 1) mod (𝑥^n - 1). @@ -1497,6 +1509,8 @@ static void poly_from_poly2(struct poly *out, const struct poly2 *in) { shift = 0; } } + + poly_normalize(out); } static void poly_from_poly3(struct poly *out, const struct poly3 *in) { @@ -1521,6 +1535,8 @@ static void poly_from_poly3(struct poly *out, const struct poly3 *in) { shift = 0; } } + + poly_normalize(out); } // Polynomial inversion @@ -1574,6 +1590,7 @@ static void poly_invert_mod2(struct poly *out, const struct poly *in) { assert(f.v[0] & 1); poly2_reverse_700(&v, &v); poly_from_poly2(out, &v); + poly_assert_normalized(out); } // poly_invert sets |*out| to |in^-1| (i.e. such that |*out|×|in| = 1 mod Φ(N)). @@ -1587,6 +1604,7 @@ static void poly_invert(struct POLY_MUL_SCRATCH *scratch, struct poly *out, for (unsigned i = 0; i < N; i++) { a.v[i] = -in->v[i]; } + poly_normalize(&a); // b = in^-1 mod 2. b = out; @@ -1599,6 +1617,8 @@ static void poly_invert(struct POLY_MUL_SCRATCH *scratch, struct poly *out, tmp.v[0] += 2; poly_mul(scratch, b, b, &tmp); } + + poly_assert_normalized(out); } // Marshal and unmarshal functions for various basic types. @@ -1688,6 +1708,7 @@ static int poly_unmarshal(struct poly *out, const uint8_t in[POLY_BYTES]) { } out->v[N - 1] = (uint16_t)(0u - sum); + poly_normalize(out); return 1; } @@ -1730,8 +1751,7 @@ static void poly_marshal_mod3(uint8_t out[HRSS_POLY3_BYTES], // function uses that freedom to implement a flatter distribution of values. static void poly_short_sample(struct poly *out, const uint8_t in[HRSS_SAMPLE_BYTES]) { - OPENSSL_STATIC_ASSERT(HRSS_SAMPLE_BYTES == N - 1, - "HRSS_SAMPLE_BYTES incorrect"); + static_assert(HRSS_SAMPLE_BYTES == N - 1, "HRSS_SAMPLE_BYTES incorrect"); for (size_t i = 0; i < N - 1; i++) { uint16_t v = mod3(in[i]); // Map {0, 1, 2} -> {0, 1, 0xffff} @@ -1739,6 +1759,7 @@ static void poly_short_sample(struct poly *out, out->v[i] = v; } out->v[N - 1] = 0; + poly_normalize(out); } // poly_short_sample_plus performs the T+ sample as defined in [HRSSNIST], @@ -1761,6 +1782,7 @@ static void poly_short_sample_plus(struct poly *out, for (unsigned i = 0; i < N; i += 2) { out->v[i] = (unsigned) out->v[i] * scale; } + poly_assert_normalized(out); } // poly_lift computes the function discussed in [HRSS], appendix B. @@ -1876,6 +1898,7 @@ static void poly_lift(struct poly *out, const struct poly *a) { } poly_mul_x_minus_1(out); + poly_normalize(out); } struct public_key { @@ -1897,7 +1920,7 @@ struct private_key { // that up.) static struct public_key *public_key_from_external( struct HRSS_public_key *ext) { - OPENSSL_STATIC_ASSERT( + static_assert( sizeof(struct HRSS_public_key) >= sizeof(struct public_key) + 15, "HRSS public key too small"); @@ -1909,7 +1932,7 @@ static struct public_key *public_key_from_external( // issues. static struct private_key *private_key_from_external( struct HRSS_private_key *ext) { - OPENSSL_STATIC_ASSERT( + static_assert( sizeof(struct HRSS_private_key) >= sizeof(struct private_key) + 15, "HRSS private key too small"); @@ -1955,6 +1978,10 @@ int HRSS_generate_key( return 0; } +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + OPENSSL_memcpy(priv->hmac_key, in + 2 * HRSS_SAMPLE_BYTES, sizeof(priv->hmac_key)); @@ -2014,6 +2041,10 @@ int HRSS_encap(uint8_t out_ciphertext[POLY_BYTES], uint8_t out_shared_key[32], return 0; } +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + poly_short_sample(&vars->m, in); poly_short_sample(&vars->r, in + HRSS_SAMPLE_BYTES); poly_lift(&vars->m_lifted, &vars->m); @@ -2071,11 +2102,15 @@ int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], return 0; } +#if !defined(NDEBUG) + OPENSSL_memset(vars, 0xff, sizeof(struct vars)); +#endif + // This is HMAC, expanded inline rather than using the |HMAC| function so that // we can avoid dealing with possible allocation failures and so keep this // function infallible. - OPENSSL_STATIC_ASSERT(sizeof(priv->hmac_key) <= sizeof(vars->masked_key), - "HRSS HMAC key larger than SHA-256 block size"); + static_assert(sizeof(priv->hmac_key) <= sizeof(vars->masked_key), + "HRSS HMAC key larger than SHA-256 block size"); for (size_t i = 0; i < sizeof(priv->hmac_key); i++) { vars->masked_key[i] = priv->hmac_key[i] ^ 0x36; } @@ -2097,8 +2132,8 @@ int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], SHA256_Init(&vars->hash_ctx); SHA256_Update(&vars->hash_ctx, vars->masked_key, sizeof(vars->masked_key)); SHA256_Update(&vars->hash_ctx, inner_digest, sizeof(inner_digest)); - OPENSSL_STATIC_ASSERT(HRSS_KEY_BYTES == SHA256_DIGEST_LENGTH, - "HRSS shared key length incorrect"); + static_assert(HRSS_KEY_BYTES == SHA256_DIGEST_LENGTH, + "HRSS shared key length incorrect"); SHA256_Final(out_shared_key, &vars->hash_ctx); // If the ciphertext is publicly invalid then a random shared key is still @@ -2121,6 +2156,7 @@ int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], for (unsigned i = 0; i < N; i++) { vars->r.v[i] = vars->c.v[i] - vars->m_lifted.v[i]; } + poly_normalize(&vars->r); poly_mul(&vars->scratch, &vars->r, &vars->r, &priv->ph_inverse); poly_mod_phiN(&vars->r); poly_clamp(&vars->r); @@ -2150,8 +2186,8 @@ int HRSS_decap(uint8_t out_shared_key[HRSS_KEY_BYTES], // The |poly_marshal| here then is just confirming that |poly_unmarshal| is // strict and could be omitted. - OPENSSL_STATIC_ASSERT(HRSS_CIPHERTEXT_BYTES == POLY_BYTES, - "ciphertext is the wrong size"); + static_assert(HRSS_CIPHERTEXT_BYTES == POLY_BYTES, + "ciphertext is the wrong size"); assert(ciphertext_len == sizeof(vars->expected_ciphertext)); poly_marshal(vars->expected_ciphertext, &vars->c); diff --git a/third_party/boringssl/kit/src/crypto/hrss/hrss_test.cc b/third_party/boringssl/kit/src/crypto/hrss/hrss_test.cc index 7adbe9e8..8c4d15f3 100644 --- a/third_party/boringssl/kit/src/crypto/hrss/hrss_test.cc +++ b/third_party/boringssl/kit/src/crypto/hrss/hrss_test.cc @@ -14,10 +14,10 @@ #include -#include #include #include +#include "../internal.h" #include "../test/abi_test.h" #include "../test/test_util.h" #include "internal.h" @@ -201,6 +201,33 @@ TEST(HRSS, Random) { } } +TEST(HRSS, NoWritesToConstData) { + // Normalisation of some polynomials used to write into the generated keys. + // This is fine in a purely ephemeral setting, but triggers TSAN warnings in + // more complex ones. + uint8_t generate_key_entropy[HRSS_GENERATE_KEY_BYTES]; + RAND_bytes(generate_key_entropy, sizeof(generate_key_entropy)); + HRSS_public_key pub, pub_orig; + HRSS_private_key priv, priv_orig; + OPENSSL_memset(&pub, 0xa3, sizeof(pub)); + OPENSSL_memset(&priv, 0x3a, sizeof(priv)); + ASSERT_TRUE(HRSS_generate_key(&pub, &priv, generate_key_entropy)); + OPENSSL_memcpy(&priv_orig, &priv, sizeof(priv)); + OPENSSL_memcpy(&pub_orig, &pub, sizeof(pub)); + + uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; + uint8_t shared_key[HRSS_KEY_BYTES]; + uint8_t encap_entropy[HRSS_ENCAP_BYTES]; + RAND_bytes(encap_entropy, sizeof(encap_entropy)); + ASSERT_TRUE(HRSS_encap(ciphertext, shared_key, &pub, encap_entropy)); + + ASSERT_EQ(OPENSSL_memcmp(&pub, &pub_orig, sizeof(pub)), 0); + + ASSERT_TRUE(HRSS_decap(shared_key, &priv, ciphertext, sizeof(ciphertext))); + + ASSERT_EQ(OPENSSL_memcmp(&priv, &priv_orig, sizeof(priv)), 0); +} + TEST(HRSS, Golden) { uint8_t generate_key_entropy[HRSS_GENERATE_KEY_BYTES]; for (unsigned i = 0; i < HRSS_SAMPLE_BYTES; i++) { @@ -453,8 +480,7 @@ TEST(HRSS, Golden) { #if defined(POLY_RQ_MUL_ASM) && defined(SUPPORTS_ABI_TEST) TEST(HRSS, ABI) { - const bool has_avx2 = (OPENSSL_ia32cap_P[2] & (1 << 5)) != 0; - if (!has_avx2) { + if (!CRYPTO_is_AVX2_capable()) { fprintf(stderr, "Skipping ABI test due to lack of AVX2 support.\n"); return; } @@ -464,7 +490,7 @@ TEST(HRSS, ABI) { alignas(16) uint16_t b[N + 3] = {0}; uint8_t kCanary[256]; - OPENSSL_STATIC_ASSERT(sizeof(kCanary) % 32 == 0, "needed for alignment"); + static_assert(sizeof(kCanary) % 32 == 0, "needed for alignment"); memset(kCanary, 42, sizeof(kCanary)); alignas(32) uint8_t scratch[sizeof(kCanary) + POLY_MUL_RQ_SCRATCH_SPACE + sizeof(kCanary)]; diff --git a/third_party/boringssl/kit/src/crypto/impl_dispatch_test.cc b/third_party/boringssl/kit/src/crypto/impl_dispatch_test.cc index 10a4d1ba..631e78f0 100644 --- a/third_party/boringssl/kit/src/crypto/impl_dispatch_test.cc +++ b/third_party/boringssl/kit/src/crypto/impl_dispatch_test.cc @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -34,9 +33,9 @@ class ImplDispatchTest : public ::testing::Test { public: void SetUp() override { #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) - aesni_ = OPENSSL_ia32cap_P[1] & (1 << (57 - 32)); - avx_movbe_ = ((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41; - ssse3_ = OPENSSL_ia32cap_P[1] & (1 << (41 - 32)); + aesni_ = CRYPTO_is_AESNI_capable(); + avx_movbe_ = CRYPTO_is_AVX_capable() && CRYPTO_is_MOVBE_capable(); + ssse3_ = CRYPTO_is_SSSE3_capable(); is_x86_64_ = #if defined(OPENSSL_X86_64) true; diff --git a/third_party/boringssl/kit/src/crypto/internal.h b/third_party/boringssl/kit/src/crypto/internal.h index 41c42dd9..98e21781 100644 --- a/third_party/boringssl/kit/src/crypto/internal.h +++ b/third_party/boringssl/kit/src/crypto/internal.h @@ -121,12 +121,28 @@ #include #endif +#if defined(BORINGSSL_FIPS_BREAK_TESTS) +#include +#endif + #if !defined(__cplusplus) -#if defined(_MSC_VER) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#include +#elif defined(_MSC_VER) && !defined(__clang__) #define alignas(x) __declspec(align(x)) #define alignof __alignof #else -#include +// With the exception of MSVC, we require C11 to build the library. C11 is a +// prerequisite for improved refcounting performance. All our supported C +// compilers have long implemented C11 and made it default. The most likely +// cause of pre-C11 modes is stale -std=c99 or -std=gnu99 flags in build +// configuration. Such flags can be removed. +// +// TODO(davidben): In MSVC 2019 16.8 or higher (_MSC_VER >= 1928), +// |__STDC_VERSION__| will be 201112 when passed /std:c11 and unset otherwise. +// C11 alignas and alignof are only implemented in C11 mode. Can we mandate C11 +// mode for those versions? +#error "BoringSSL must be built in C11 mode or higher." #endif #endif @@ -139,6 +155,32 @@ #if defined(OPENSSL_THREADS) && !defined(OPENSSL_PTHREADS) && \ defined(OPENSSL_WINDOWS) #define OPENSSL_WINDOWS_THREADS +#endif + +// Determine the atomics implementation to use with C. +#if !defined(__cplusplus) +#if !defined(OPENSSL_C11_ATOMIC) && defined(OPENSSL_THREADS) && \ + !defined(__STDC_NO_ATOMICS__) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 201112L +#define OPENSSL_C11_ATOMIC +#endif + +#if defined(OPENSSL_C11_ATOMIC) +#include +#endif + +// Older MSVC does not support C11 atomics, so we fallback to the Windows APIs. +// When both are available (e.g. clang-cl), we prefer the C11 ones. The Windows +// APIs don't allow some operations to be implemented as efficiently. This can +// be removed once we can rely on +// https://devblogs.microsoft.com/cppblog/c11-atomics-in-visual-studio-2022-version-17-5-preview-2/ +#if !defined(OPENSSL_C11_ATOMIC) && defined(OPENSSL_THREADS) && \ + defined(OPENSSL_WINDOWS) +#define OPENSSL_WINDOWS_ATOMIC +#endif +#endif // !__cplusplus + +#if defined(OPENSSL_WINDOWS_THREADS) || defined(OPENSSL_WINDOWS_ATOMIC) OPENSSL_MSVC_PRAGMA(warning(push, 3)) #include OPENSSL_MSVC_PRAGMA(warning(pop)) @@ -150,7 +192,7 @@ extern "C" { #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ - defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) + defined(OPENSSL_AARCH64) // OPENSSL_cpuid_setup initializes the platform-specific feature cache. void OPENSSL_cpuid_setup(void); #endif @@ -209,19 +251,29 @@ typedef __uint128_t uint128_t; #define OPENSSL_SSE2 #endif +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +// OPENSSL_reset_malloc_counter_for_testing, when malloc testing is enabled, +// resets the internal malloc counter, to simulate further malloc failures. This +// should be called in between independent tests, at a point where failure from +// a previous test will not impact subsequent ones. +OPENSSL_EXPORT void OPENSSL_reset_malloc_counter_for_testing(void); +#else +OPENSSL_INLINE void OPENSSL_reset_malloc_counter_for_testing(void) {} +#endif + // Pointer utility functions. // buffers_alias returns one if |a| and |b| alias and zero otherwise. -static inline int buffers_alias(const uint8_t *a, size_t a_len, - const uint8_t *b, size_t b_len) { +static inline int buffers_alias(const void *a, size_t a_bytes, + const void *b, size_t b_bytes) { // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated // objects are undefined whereas pointer to integer conversions are merely // implementation-defined. We assume the implementation defined it in a sane // way. uintptr_t a_u = (uintptr_t)a; uintptr_t b_u = (uintptr_t)b; - return a_u + a_len > b_u && b_u + b_len > a_u; + return a_u + a_bytes > b_u && b_u + b_bytes > a_u; } // align_pointer returns |ptr|, advanced to |alignment|. |alignment| must be a @@ -286,7 +338,7 @@ typedef uint32_t crypto_word_t; // always has the same output for a given input. This allows it to eliminate // dead code, move computations across loops, and vectorize. static inline crypto_word_t value_barrier_w(crypto_word_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; @@ -294,7 +346,7 @@ static inline crypto_word_t value_barrier_w(crypto_word_t a) { // value_barrier_u32 behaves like |value_barrier_w| but takes a |uint32_t|. static inline uint32_t value_barrier_u32(uint32_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; @@ -302,12 +354,15 @@ static inline uint32_t value_barrier_u32(uint32_t a) { // value_barrier_u64 behaves like |value_barrier_w| but takes a |uint64_t|. static inline uint64_t value_barrier_u64(uint64_t a) { -#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +#if defined(__GNUC__) || defined(__clang__) __asm__("" : "+r"(a) : /* no inputs */); #endif return a; } +// |value_barrier_u8| could be defined as above, but compilers other than +// clang seem to still materialize 0x00..00MM instead of reusing 0x??..??MM. + // constant_time_msb_w returns the given value with the MSB copied to all the // other bits. static inline crypto_word_t constant_time_msb_w(crypto_word_t a) { @@ -424,16 +479,23 @@ static inline crypto_word_t constant_time_select_w(crypto_word_t mask, // to a cmov, it sometimes further transforms it into a branch, which we do // not want. // - // Adding barriers to both |mask| and |~mask| breaks the relationship between - // the two, which makes the compiler stick with bitmasks. - return (value_barrier_w(mask) & a) | (value_barrier_w(~mask) & b); + // Hiding the value of the mask from the compiler evades this transformation. + mask = value_barrier_w(mask); + return (mask & a) | (~mask & b); } // constant_time_select_8 acts like |constant_time_select| but operates on // 8-bit values. -static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a, +static inline uint8_t constant_time_select_8(crypto_word_t mask, uint8_t a, uint8_t b) { - return (uint8_t)(constant_time_select_w(mask, a, b)); + // |mask| is a word instead of |uint8_t| to avoid materializing 0x000..0MM + // Making both |mask| and its value barrier |uint8_t| would allow the compiler + // to materialize 0x????..?MM instead, but only clang is that clever. + // However, vectorization of bitwise operations seems to work better on + // |uint8_t| than a mix of |uint64_t| and |uint8_t|, so |m| is cast to + // |uint8_t| after the value barrier but before the bitwise operations. + uint8_t m = value_barrier_w(mask); + return (m & a) | (~m & b); } // constant_time_select_int acts like |constant_time_select| but operates on @@ -443,26 +505,78 @@ static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { (crypto_word_t)(b))); } +// constant_time_conditional_memcpy copies |n| bytes from |src| to |dst| if +// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory +// ranges at |dst| and |src| must not overlap, as when calling |memcpy|. +static inline void constant_time_conditional_memcpy(void *dst, const void *src, + const size_t n, + const crypto_word_t mask) { + assert(!buffers_alias(dst, n, src, n)); + uint8_t *out = (uint8_t *)dst; + const uint8_t *in = (const uint8_t *)src; + for (size_t i = 0; i < n; i++) { + out[i] = constant_time_select_8(mask, in[i], out[i]); + } +} + +// constant_time_conditional_memxor xors |n| bytes from |src| to |dst| if +// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory +// ranges at |dst| and |src| must not overlap, as when calling |memcpy|. +static inline void constant_time_conditional_memxor(void *dst, const void *src, + const size_t n, + const crypto_word_t mask) { + assert(!buffers_alias(dst, n, src, n)); + uint8_t *out = (uint8_t *)dst; + const uint8_t *in = (const uint8_t *)src; + for (size_t i = 0; i < n; i++) { + out[i] ^= value_barrier_w(mask) & in[i]; + } +} + #if defined(BORINGSSL_CONSTANT_TIME_VALIDATION) // CONSTTIME_SECRET takes a pointer and a number of bytes and marks that region // of memory as secret. Secret data is tracked as it flows to registers and // other parts of a memory. If secret data is used as a condition for a branch, // or as a memory index, it will trigger warnings in valgrind. -#define CONSTTIME_SECRET(x, y) VALGRIND_MAKE_MEM_UNDEFINED(x, y) +#define CONSTTIME_SECRET(ptr, len) VALGRIND_MAKE_MEM_UNDEFINED(ptr, len) // CONSTTIME_DECLASSIFY takes a pointer and a number of bytes and marks that // region of memory as public. Public data is not subject to constant-time // rules. -#define CONSTTIME_DECLASSIFY(x, y) VALGRIND_MAKE_MEM_DEFINED(x, y) +#define CONSTTIME_DECLASSIFY(ptr, len) VALGRIND_MAKE_MEM_DEFINED(ptr, len) #else -#define CONSTTIME_SECRET(x, y) -#define CONSTTIME_DECLASSIFY(x, y) +#define CONSTTIME_SECRET(ptr, len) +#define CONSTTIME_DECLASSIFY(ptr, len) #endif // BORINGSSL_CONSTANT_TIME_VALIDATION +static inline crypto_word_t constant_time_declassify_w(crypto_word_t v) { + // Return |v| through a value barrier to be safe. Valgrind-based constant-time + // validation is partly to check the compiler has not undone any constant-time + // work. Any place |BORINGSSL_CONSTANT_TIME_VALIDATION| influences + // optimizations, this validation is inaccurate. + // + // However, by sending pointers through valgrind, we likely inhibit escape + // analysis. On local variables, particularly booleans, we likely + // significantly impact optimizations. + // + // Thus, to be safe, stick a value barrier, in hopes of comparably inhibiting + // compiler analysis. + CONSTTIME_DECLASSIFY(&v, sizeof(v)); + return value_barrier_w(v); +} + +static inline int constant_time_declassify_int(int v) { + static_assert(sizeof(uint32_t) == sizeof(int), + "int is not the same size as uint32_t"); + // See comment above. + CONSTTIME_DECLASSIFY(&v, sizeof(v)); + return value_barrier_u32(v); +} + // Thread-safe initialisation. @@ -489,15 +603,117 @@ typedef pthread_once_t CRYPTO_once_t; OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); -// Reference counting. +// Atomics. +// +// The following functions provide an API analogous to from C11 +// and abstract between a few variations on atomics we need to support. + +#if defined(__cplusplus) + +// In C++, we can't easily detect whether C will use |OPENSSL_C11_ATOMIC| or +// |OPENSSL_WINDOWS_ATOMIC|. Instead, we define a layout-compatible type without +// the corresponding functions. When we can rely on C11 atomics in MSVC, that +// will no longer be a concern. +typedef uint32_t CRYPTO_atomic_u32; + +#elif defined(OPENSSL_C11_ATOMIC) + +typedef _Atomic uint32_t CRYPTO_atomic_u32; + +// This should be const, but the |OPENSSL_WINDOWS_ATOMIC| implementation is not +// const due to Windows limitations. When we can rely on C11 atomics, make this +// const-correct. +OPENSSL_INLINE uint32_t CRYPTO_atomic_load_u32(CRYPTO_atomic_u32 *val) { + return atomic_load(val); +} + +OPENSSL_INLINE int CRYPTO_atomic_compare_exchange_weak_u32( + CRYPTO_atomic_u32 *val, uint32_t *expected, uint32_t desired) { + return atomic_compare_exchange_weak(val, expected, desired); +} + +OPENSSL_INLINE void CRYPTO_atomic_store_u32(CRYPTO_atomic_u32 *val, + uint32_t desired) { + atomic_store(val, desired); +} + +#elif defined(OPENSSL_WINDOWS_ATOMIC) + +typedef LONG CRYPTO_atomic_u32; + +OPENSSL_INLINE uint32_t CRYPTO_atomic_load_u32(volatile CRYPTO_atomic_u32 *val) { + // This is not ideal because it still writes to a cacheline. MSVC is not able + // to optimize this to a true atomic read, and Windows does not provide an + // InterlockedLoad function. + // + // The Windows documentation [1] does say "Simple reads and writes to + // properly-aligned 32-bit variables are atomic operations", but this is not + // phrased in terms of the C11 and C++11 memory models, and indeed a read or + // write seems to produce slightly different code on MSVC than a sequentially + // consistent std::atomic::load in C++. Moreover, it is unclear if non-MSVC + // compilers on Windows provide the same guarantees. Thus we avoid relying on + // this and instead still use an interlocked function. This is still + // preferable a global mutex, and eventually this code will be replaced by + // [2]. Additionally, on clang-cl, we'll use the |OPENSSL_C11_ATOMIC| path. + // + // [1] https://learn.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access + // [2] https://devblogs.microsoft.com/cppblog/c11-atomics-in-visual-studio-2022-version-17-5-preview-2/ + return (uint32_t)InterlockedCompareExchange(val, 0, 0); +} + +OPENSSL_INLINE int CRYPTO_atomic_compare_exchange_weak_u32( + volatile CRYPTO_atomic_u32 *val, uint32_t *expected32, uint32_t desired) { + LONG expected = (LONG)*expected32; + LONG actual = InterlockedCompareExchange(val, (LONG)desired, expected); + *expected32 = (uint32_t)actual; + return actual == expected; +} + +OPENSSL_INLINE void CRYPTO_atomic_store_u32(volatile CRYPTO_atomic_u32 *val, + uint32_t desired) { + InterlockedExchange(val, (LONG)desired); +} + +#elif !defined(OPENSSL_THREADS) + +typedef uint32_t CRYPTO_atomic_u32; + +OPENSSL_INLINE uint32_t CRYPTO_atomic_load_u32(CRYPTO_atomic_u32 *val) { + return *val; +} + +OPENSSL_INLINE int CRYPTO_atomic_compare_exchange_weak_u32( + CRYPTO_atomic_u32 *val, uint32_t *expected, uint32_t desired) { + if (*val != *expected) { + *expected = *val; + return 0; + } + *val = desired; + return 1; +} + +OPENSSL_INLINE void CRYPTO_atomic_store_u32(CRYPTO_atomic_u32 *val, + uint32_t desired) { + *val = desired; +} + +#else + +// Require some atomics implementation. Contact BoringSSL maintainers if you +// have a platform with fails this check. +#error "Thread-compatible configurations require atomics" -// Automatically enable C11 atomics if implemented. -#if !defined(OPENSSL_C11_ATOMIC) && defined(OPENSSL_THREADS) && \ - !defined(__STDC_NO_ATOMICS__) && defined(__STDC_VERSION__) && \ - __STDC_VERSION__ >= 201112L -#define OPENSSL_C11_ATOMIC #endif +// See the comment in the |__cplusplus| section above. +static_assert(sizeof(CRYPTO_atomic_u32) == sizeof(uint32_t), + "CRYPTO_atomic_u32 does not match uint32_t size"); +static_assert(alignof(CRYPTO_atomic_u32) == alignof(uint32_t), + "CRYPTO_atomic_u32 does not match uint32_t alignment"); + + +// Reference counting. + // CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. #define CRYPTO_REFCOUNT_MAX 0xffffffff @@ -519,37 +735,24 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count); // Locks. -// -// Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in -// structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as -// a global lock. A global lock must be initialised to the value -// |CRYPTO_STATIC_MUTEX_INIT|. -// -// |CRYPTO_MUTEX| can appear in public structures and so is defined in -// thread.h as a structure large enough to fit the real type. The global lock is -// a different type so it may be initialized with platform initializer macros. #if !defined(OPENSSL_THREADS) -struct CRYPTO_STATIC_MUTEX { +typedef struct crypto_mutex_st { char padding; // Empty structs have different sizes in C and C++. -}; -#define CRYPTO_STATIC_MUTEX_INIT { 0 } +} CRYPTO_MUTEX; +#define CRYPTO_MUTEX_INIT { 0 } #elif defined(OPENSSL_WINDOWS_THREADS) -struct CRYPTO_STATIC_MUTEX { - SRWLOCK lock; -}; -#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT } +typedef SRWLOCK CRYPTO_MUTEX; +#define CRYPTO_MUTEX_INIT SRWLOCK_INIT #elif defined(OPENSSL_PTHREADS) -struct CRYPTO_STATIC_MUTEX { - pthread_rwlock_t lock; -}; -#define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER } +typedef pthread_rwlock_t CRYPTO_MUTEX; +#define CRYPTO_MUTEX_INIT PTHREAD_RWLOCK_INITIALIZER #else #error "Unknown threading library" #endif // CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a -// |CRYPTO_STATIC_MUTEX|. +// |CRYPTO_MUTEX_INIT|. OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock); // CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a @@ -569,28 +772,6 @@ OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock); // CRYPTO_MUTEX_cleanup releases all resources held by |lock|. OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock); -// CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also -// have a read lock, but none may have a write lock. The |lock| variable does -// not need to be initialised by any function, but must have been statically -// initialised with |CRYPTO_STATIC_MUTEX_INIT|. -OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read( - struct CRYPTO_STATIC_MUTEX *lock); - -// CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has -// any type of lock on it. The |lock| variable does not need to be initialised -// by any function, but must have been statically initialised with -// |CRYPTO_STATIC_MUTEX_INIT|. -OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write( - struct CRYPTO_STATIC_MUTEX *lock); - -// CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading. -OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read( - struct CRYPTO_STATIC_MUTEX *lock); - -// CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing. -OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write( - struct CRYPTO_STATIC_MUTEX *lock); - #if defined(__cplusplus) extern "C++" { @@ -636,6 +817,7 @@ typedef enum { OPENSSL_THREAD_LOCAL_ERR = 0, OPENSSL_THREAD_LOCAL_RAND, OPENSSL_THREAD_LOCAL_FIPS_COUNTERS, + OPENSSL_THREAD_LOCAL_FIPS_SERVICE_INDICATOR_STATE, OPENSSL_THREAD_LOCAL_TEST, NUM_OPENSSL_THREAD_LOCALS, } thread_local_data_t; @@ -671,22 +853,25 @@ OPENSSL_EXPORT int CRYPTO_set_thread_local( typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS; -DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) - // CRYPTO_EX_DATA_CLASS tracks the ex_indices registered for a type which // supports ex_data. It should defined as a static global within the module // which defines that type. typedef struct { - struct CRYPTO_STATIC_MUTEX lock; - STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + CRYPTO_MUTEX lock; + // funcs is a linked list of |CRYPTO_EX_DATA_FUNCS| structures. It may be + // traversed without serialization only up to |num_funcs|. last points to the + // final entry of |funcs|, or NULL if empty. + CRYPTO_EX_DATA_FUNCS *funcs, *last; + // num_funcs is the number of entries in |funcs|. + CRYPTO_atomic_u32 num_funcs; // num_reserved is one if the ex_data index zero is reserved for legacy // |TYPE_get_app_data| functions. uint8_t num_reserved; } CRYPTO_EX_DATA_CLASS; -#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0} +#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_MUTEX_INIT, NULL, NULL, 0, 0} #define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \ - {CRYPTO_STATIC_MUTEX_INIT, NULL, 1} + {CRYPTO_MUTEX_INIT, NULL, NULL, 0, 1} // CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes // it to |*out_index|. Each class of object should provide a wrapper function @@ -868,6 +1053,16 @@ static inline void CRYPTO_store_u32_be(void *out, uint32_t v) { OPENSSL_memcpy(out, &v, sizeof(v)); } +static inline uint64_t CRYPTO_load_u64_le(const void *in) { + uint64_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void CRYPTO_store_u64_le(void *out, uint64_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + static inline uint64_t CRYPTO_load_u64_be(const void *ptr) { uint64_t ret; OPENSSL_memcpy(&ret, ptr, sizeof(ret)); @@ -889,6 +1084,18 @@ static inline void CRYPTO_store_word_le(void *out, crypto_word_t v) { OPENSSL_memcpy(out, &v, sizeof(v)); } +static inline crypto_word_t CRYPTO_load_word_be(const void *in) { + crypto_word_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); +#if defined(OPENSSL_64_BIT) + static_assert(sizeof(v) == 8, "crypto_word_t has unexpected size"); + return CRYPTO_bswap8(v); +#else + static_assert(sizeof(v) == 4, "crypto_word_t has unexpected size"); + return CRYPTO_bswap4(v); +#endif +} + // Bit rotation functions. // @@ -932,19 +1139,50 @@ static inline uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) { // FIPS functions. #if defined(BORINGSSL_FIPS) + // BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test // fails. It prevents any further cryptographic operations by the current // process. void BORINGSSL_FIPS_abort(void) __attribute__((noreturn)); -#endif -// boringssl_fips_self_test runs the FIPS KAT-based self tests. It returns one -// on success and zero on error. The argument is the integrity hash of the FIPS -// module and may be used to check and write flag files to suppress duplicate -// self-tests. If |module_hash_len| is zero then no flag file will be checked -// nor written and tests will always be run. -int boringssl_fips_self_test(const uint8_t *module_hash, - size_t module_hash_len); +// boringssl_self_test_startup runs all startup self tests and returns one on +// success or zero on error. Startup self tests do not include lazy tests. +// Call |BORINGSSL_self_test| to run every self test. +int boringssl_self_test_startup(void); + +// boringssl_ensure_rsa_self_test checks whether the RSA self-test has been run +// in this address space. If not, it runs it and crashes the address space if +// unsuccessful. +void boringssl_ensure_rsa_self_test(void); + +// boringssl_ensure_ecc_self_test checks whether the ECDSA and ECDH self-test +// has been run in this address space. If not, it runs it and crashes the +// address space if unsuccessful. +void boringssl_ensure_ecc_self_test(void); + +// boringssl_ensure_ffdh_self_test checks whether the FFDH self-test has been +// run in this address space. If not, it runs it and crashes the address space +// if unsuccessful. +void boringssl_ensure_ffdh_self_test(void); + +#else + +// Outside of FIPS mode, the lazy tests are no-ops. + +OPENSSL_INLINE void boringssl_ensure_rsa_self_test(void) {} +OPENSSL_INLINE void boringssl_ensure_ecc_self_test(void) {} +OPENSSL_INLINE void boringssl_ensure_ffdh_self_test(void) {} + +#endif // FIPS + +// boringssl_self_test_sha256 performs a SHA-256 KAT. +int boringssl_self_test_sha256(void); + +// boringssl_self_test_sha512 performs a SHA-512 KAT. +int boringssl_self_test_sha512(void); + +// boringssl_self_test_hmac_sha256 performs an HMAC-SHA-256 KAT. +int boringssl_self_test_hmac_sha256(void); #if defined(BORINGSSL_FIPS_COUNTERS) void boringssl_fips_inc_counter(enum fips_counter_t counter); @@ -952,6 +1190,257 @@ void boringssl_fips_inc_counter(enum fips_counter_t counter); OPENSSL_INLINE void boringssl_fips_inc_counter(enum fips_counter_t counter) {} #endif +#if defined(BORINGSSL_FIPS_BREAK_TESTS) +OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { + const char *const value = getenv("BORINGSSL_FIPS_BREAK_TEST"); + return value != NULL && strcmp(value, test) == 0; +} +#else +OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { + return 0; +} +#endif // BORINGSSL_FIPS_BREAK_TESTS + + +// Runtime CPU feature support + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or +// x86-64 system. +// +// Index 0: +// EDX for CPUID where EAX = 1 +// Bit 20 is always zero +// Bit 28 is adjusted to reflect whether the data cache is shared between +// multiple logical cores +// Bit 30 is used to indicate an Intel CPU +// Index 1: +// ECX for CPUID where EAX = 1 +// Bit 11 is used to indicate AMD XOP support, not SDBG +// Index 2: +// EBX for CPUID where EAX = 7 +// Index 3: +// ECX for CPUID where EAX = 7 +// +// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM +// bits in XCR0, so it is not necessary to check those. +extern uint32_t OPENSSL_ia32cap_P[4]; + +#if defined(BORINGSSL_FIPS) && !defined(BORINGSSL_SHARED_LIBRARY) +// The FIPS module, as a static library, requires an out-of-line version of +// |OPENSSL_ia32cap_get| so accesses can be rewritten by delocate. Mark the +// function const so multiple accesses can be optimized together. +const uint32_t *OPENSSL_ia32cap_get(void) __attribute__((const)); +#else +OPENSSL_INLINE const uint32_t *OPENSSL_ia32cap_get(void) { + return OPENSSL_ia32cap_P; +} +#endif + +// See Intel manual, volume 2A, table 3-11. + +OPENSSL_INLINE int CRYPTO_is_FXSR_capable(void) { +#if defined(__FXSR__) + return 1; +#else + return (OPENSSL_ia32cap_get()[0] & (1 << 24)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_intel_cpu(void) { + // The reserved bit 30 is used to indicate an Intel CPU. + return (OPENSSL_ia32cap_get()[0] & (1 << 30)) != 0; +} + +// See Intel manual, volume 2A, table 3-10. + +OPENSSL_INLINE int CRYPTO_is_PCLMUL_capable(void) { +#if defined(__PCLMUL__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 1)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_SSSE3_capable(void) { +#if defined(__SSSE3__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 9)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_SSE4_1_capable(void) { +#if defined(__SSE4_1__) + return 1; +#else + return (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_MOVBE_capable(void) { +#if defined(__MOVBE__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 22)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AESNI_capable(void) { +#if defined(__AES__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 25)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AVX_capable(void) { +#if defined(__AVX__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1 << 28)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_RDRAND_capable(void) { + // The GCC/Clang feature name and preprocessor symbol for RDRAND are "rdrnd" + // and |__RDRND__|, respectively. +#if defined(__RDRND__) + return 1; +#else + return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0; +#endif +} + +// See Intel manual, volume 2A, table 3-8. + +OPENSSL_INLINE int CRYPTO_is_BMI1_capable(void) { +#if defined(__BMI1__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 3)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_AVX2_capable(void) { +#if defined(__AVX2__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 5)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_BMI2_capable(void) { +#if defined(__BMI2__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 8)) != 0; +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ADX_capable(void) { +#if defined(__ADX__) + return 1; +#else + return (OPENSSL_ia32cap_get()[2] & (1 << 19)) != 0; +#endif +} + +#endif // OPENSSL_X86 || OPENSSL_X86_64 + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#if defined(OPENSSL_APPLE) && defined(OPENSSL_ARM) +// We do not detect any features at runtime for Apple's 32-bit ARM platforms. On +// 64-bit ARM, we detect some post-ARMv8.0 features. +#define OPENSSL_STATIC_ARMCAP +#endif + +// Normalize some older feature flags to their modern ACLE values. +// https://developer.arm.com/architectures/system-architectures/software-standards/acle +#if defined(__ARM_NEON__) && !defined(__ARM_NEON) +#define __ARM_NEON 1 +#endif +#if defined(__ARM_FEATURE_CRYPTO) +#if !defined(__ARM_FEATURE_AES) +#define __ARM_FEATURE_AES 1 +#endif +#if !defined(__ARM_FEATURE_SHA2) +#define __ARM_FEATURE_SHA2 1 +#endif +#endif + +#if !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON +// unit. Note that |OPENSSL_armcap_P| also exists and contains the same +// information in a form that's easier for assembly to use. +OPENSSL_EXPORT int CRYPTO_is_NEON_capable_at_runtime(void); + +// CRYPTO_is_ARMv8_AES_capable_at_runtime returns true if the current CPU +// supports the ARMv8 AES instruction. +int CRYPTO_is_ARMv8_AES_capable_at_runtime(void); + +// CRYPTO_is_ARMv8_PMULL_capable_at_runtime returns true if the current CPU +// supports the ARMv8 PMULL instruction. +int CRYPTO_is_ARMv8_PMULL_capable_at_runtime(void); +#endif // !OPENSSL_STATIC_ARMCAP + +// CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If +// this is known statically, it is a constant inline function. +OPENSSL_INLINE int CRYPTO_is_NEON_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_NEON_capable_at_runtime(); +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ARMv8_AES_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_AES) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_ARMv8_AES_capable_at_runtime(); +#endif +} + +OPENSSL_INLINE int CRYPTO_is_ARMv8_PMULL_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_AES) + return 1; +#elif defined(OPENSSL_STATIC_ARMCAP) + return 0; +#else + return CRYPTO_is_ARMv8_PMULL_capable_at_runtime(); +#endif +} + +#endif // OPENSSL_ARM || OPENSSL_AARCH64 + +#if defined(BORINGSSL_DISPATCH_TEST) +// Runtime CPU dispatch testing support + +// BORINGSSL_function_hit is an array of flags. The following functions will +// set these flags if BORINGSSL_DISPATCH_TEST is defined. +// 0: aes_hw_ctr32_encrypt_blocks +// 1: aes_hw_encrypt +// 2: aesni_gcm_encrypt +// 3: aes_hw_set_encrypt_key +// 4: vpaes_encrypt +// 5: vpaes_set_encrypt_key +extern uint8_t BORINGSSL_function_hit[7]; +#endif // BORINGSSL_DISPATCH_TEST + +// OPENSSL_vasprintf_internal is just like |vasprintf(3)|. If |system_malloc| is +// 0, memory will be allocated with |OPENSSL_malloc| and must be freed with +// |OPENSSL_free|. Otherwise the system |malloc| function is used and the memory +// must be freed with the system |free| function. +OPENSSL_EXPORT int OPENSSL_vasprintf_internal(char **str, const char *format, + va_list args, int system_malloc) + OPENSSL_PRINTF_FORMAT_FUNC(2, 0); + #if defined(__cplusplus) } // extern C #endif diff --git a/third_party/boringssl/kit/src/crypto/kyber/internal.h b/third_party/boringssl/kit/src/crypto/kyber/internal.h new file mode 100644 index 00000000..b3bfa86b --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/internal.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// KYBER_ENCAP_ENTROPY is the number of bytes of uniformly random entropy +// necessary to encapsulate a secret. The entropy will be leaked to the +// decapsulating party. +#define KYBER_ENCAP_ENTROPY 32 + +// KYBER_GENERATE_KEY_ENTROPY is the number of bytes of uniformly random entropy +// necessary to generate a key. +#define KYBER_GENERATE_KEY_ENTROPY 64 + +struct BORINGSSL_keccak_st { + uint64_t state[25]; + size_t rate_bytes; + size_t offset; +}; + +enum boringssl_keccak_config_t { + boringssl_sha3_256, + boringssl_sha3_512, + boringssl_shake128, + boringssl_shake256, +}; + +// BORINGSSL_keccak hashes |in_len| bytes from |in| and writes |out_len| bytes +// of output to |out|. If the |config| specifies a fixed-output function, like +// SHA3-256, then |out_len| must be the correct length for that function. +OPENSSL_EXPORT void BORINGSSL_keccak(uint8_t *out, size_t out_len, + const uint8_t *in, size_t in_len, + enum boringssl_keccak_config_t config); + +// BORINGSSL_keccak_init absorbs |in_len| bytes from |in| and sets up |ctx| for +// squeezing. The |config| must specify a SHAKE variant, otherwise callers +// should use |BORINGSSL_keccak|. +OPENSSL_EXPORT void BORINGSSL_keccak_init( + struct BORINGSSL_keccak_st *ctx, const uint8_t *in, size_t in_len, + enum boringssl_keccak_config_t config); + +// BORINGSSL_keccak_squeeze writes |out_len| bytes to |out| from |ctx|. +OPENSSL_EXPORT void BORINGSSL_keccak_squeeze(struct BORINGSSL_keccak_st *ctx, + uint8_t *out, size_t out_len); + +// KYBER_generate_key_external_entropy is a deterministic function to create a +// pair of Kyber768 keys, using the supplied entropy. The entropy needs to be +// uniformly random generated. This function is should only be used for tests, +// regular callers should use the non-deterministic |KYBER_generate_key| +// directly. +OPENSSL_EXPORT void KYBER_generate_key_external_entropy( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key, + const uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]); + +// KYBER_encap_external_entropy is a deterministic function to encapsulate +// |out_shared_secret_len| bytes of |out_shared_secret| to |ciphertext|, using +// |KYBER_ENCAP_ENTROPY| bytes of |entropy| for randomization. The +// decapsulating side will be able to recover |entropy| in full. This +// function is should only be used for tests, regular callers should use the +// non-deterministic |KYBER_encap| directly. +OPENSSL_EXPORT void KYBER_encap_external_entropy( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], uint8_t *out_shared_secret, + size_t out_shared_secret_len, const struct KYBER_public_key *public_key, + const uint8_t entropy[KYBER_ENCAP_ENTROPY]); + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/kyber/keccak.c b/third_party/boringssl/kit/src/crypto/kyber/keccak.c new file mode 100644 index 00000000..f1c012d1 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/keccak.c @@ -0,0 +1,204 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +// keccak_f implements the Keccak-1600 permutation as described at +// https://keccak.team/keccak_specs_summary.html. Each lane is represented as a +// 64-bit value and the 5×5 lanes are stored as an array in row-major order. +static void keccak_f(uint64_t state[25]) { + static const int kNumRounds = 24; + for (int round = 0; round < kNumRounds; round++) { + // θ step + uint64_t c[5]; + for (int x = 0; x < 5; x++) { + c[x] = state[x] ^ state[x + 5] ^ state[x + 10] ^ state[x + 15] ^ + state[x + 20]; + } + + for (int x = 0; x < 5; x++) { + const uint64_t d = c[(x + 4) % 5] ^ CRYPTO_rotl_u64(c[(x + 1) % 5], 1); + for (int y = 0; y < 5; y++) { + state[y * 5 + x] ^= d; + } + } + + // ρ and π steps. + // + // These steps involve a mapping of the state matrix. Each input point, + // (x,y), is rotated and written to the point (y, 2x + 3y). In the Keccak + // pseudo-code a separate array is used because an in-place operation would + // overwrite some values that are subsequently needed. However, the mapping + // forms a trail through 24 of the 25 values so we can do it in place with + // only a single temporary variable. + // + // Start with (1, 0). The value here will be mapped and end up at (0, 2). + // That value will end up at (2, 1), then (1, 2), and so on. After 24 + // steps, 24 of the 25 values have been hit (as this mapping is injective) + // and the sequence will repeat. All that remains is to handle the element + // at (0, 0), but the rotation for that element is zero, and it goes to (0, + // 0), so we can ignore it. + static const uint8_t kIndexes[24] = {10, 7, 11, 17, 18, 3, 5, 16, + 8, 21, 24, 4, 15, 23, 19, 13, + 12, 2, 20, 14, 22, 9, 6, 1}; + static const uint8_t kRotations[24] = {1, 3, 6, 10, 15, 21, 28, 36, + 45, 55, 2, 14, 27, 41, 56, 8, + 25, 43, 62, 18, 39, 61, 20, 44}; + uint64_t prev_value = state[1]; + for (int i = 0; i < 24; i++) { + const uint64_t value = CRYPTO_rotl_u64(prev_value, kRotations[i]); + const size_t index = kIndexes[i]; + prev_value = state[index]; + state[index] = value; + } + + // χ step + for (int y = 0; y < 5; y++) { + const int row_index = 5 * y; + const uint64_t orig_x0 = state[row_index]; + const uint64_t orig_x1 = state[row_index + 1]; + state[row_index] ^= ~orig_x1 & state[row_index + 2]; + state[row_index + 1] ^= ~state[row_index + 2] & state[row_index + 3]; + state[row_index + 2] ^= ~state[row_index + 3] & state[row_index + 4]; + state[row_index + 3] ^= ~state[row_index + 4] & orig_x0; + state[row_index + 4] ^= ~orig_x0 & orig_x1; + } + + // ι step + // + // From https://keccak.team/files/Keccak-reference-3.0.pdf, section + // 1.2, the round constants are based on the output of a LFSR. Thus, as + // suggested in the appendix of of + // https://keccak.team/keccak_specs_summary.html, the values are + // simply encoded here. + static const uint64_t kRoundConstants[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, + }; + + state[0] ^= kRoundConstants[round]; + } +} + +static void keccak_init(struct BORINGSSL_keccak_st *ctx, + size_t *out_required_out_len, const uint8_t *in, + size_t in_len, enum boringssl_keccak_config_t config) { + size_t capacity_bytes; + uint8_t terminator; + switch (config) { + case boringssl_sha3_256: + capacity_bytes = 512 / 8; + *out_required_out_len = 32; + terminator = 0x06; + break; + case boringssl_sha3_512: + capacity_bytes = 1024 / 8; + *out_required_out_len = 64; + terminator = 0x06; + break; + case boringssl_shake128: + capacity_bytes = 256 / 8; + *out_required_out_len = 0; + terminator = 0x1f; + break; + case boringssl_shake256: + capacity_bytes = 512 / 8; + *out_required_out_len = 0; + terminator = 0x1f; + break; + default: + abort(); + } + + OPENSSL_memset(ctx, 0, sizeof(*ctx)); + ctx->rate_bytes = 200 - capacity_bytes; + assert(ctx->rate_bytes % 8 == 0); + const size_t rate_words = ctx->rate_bytes / 8; + + while (in_len >= ctx->rate_bytes) { + for (size_t i = 0; i < rate_words; i++) { + ctx->state[i] ^= CRYPTO_load_u64_le(in + 8 * i); + } + keccak_f(ctx->state); + in += ctx->rate_bytes; + in_len -= ctx->rate_bytes; + } + + // XOR the final block. Accessing |ctx->state| as a |uint8_t*| is allowed by + // strict aliasing because we require |uint8_t| to be a character type. + uint8_t *state_bytes = (uint8_t *)ctx->state; + assert(in_len < ctx->rate_bytes); + for (size_t i = 0; i < in_len; i++) { + state_bytes[i] ^= in[i]; + } + state_bytes[in_len] ^= terminator; + state_bytes[ctx->rate_bytes - 1] ^= 0x80; + keccak_f(ctx->state); +} + +void BORINGSSL_keccak(uint8_t *out, size_t out_len, const uint8_t *in, + size_t in_len, enum boringssl_keccak_config_t config) { + struct BORINGSSL_keccak_st ctx; + size_t required_out_len; + keccak_init(&ctx, &required_out_len, in, in_len, config); + if (required_out_len != 0 && out_len != required_out_len) { + abort(); + } + BORINGSSL_keccak_squeeze(&ctx, out, out_len); +} + +void BORINGSSL_keccak_init(struct BORINGSSL_keccak_st *ctx, const uint8_t *in, + size_t in_len, + enum boringssl_keccak_config_t config) { + size_t required_out_len; + keccak_init(ctx, &required_out_len, in, in_len, config); + if (required_out_len != 0) { + abort(); + } +} + +void BORINGSSL_keccak_squeeze(struct BORINGSSL_keccak_st *ctx, uint8_t *out, + size_t out_len) { + // Accessing |ctx->state| as a |uint8_t*| is allowed by strict aliasing + // because we require |uint8_t| to be a character type. + const uint8_t *state_bytes = (const uint8_t *)ctx->state; + while (out_len) { + size_t remaining = ctx->rate_bytes - ctx->offset; + size_t todo = out_len; + if (todo > remaining) { + todo = remaining; + } + OPENSSL_memcpy(out, &state_bytes[ctx->offset], todo); + out += todo; + out_len -= todo; + ctx->offset += todo; + if (ctx->offset == ctx->rate_bytes) { + keccak_f(ctx->state); + ctx->offset = 0; + } + } +} diff --git a/third_party/boringssl/kit/src/crypto/kyber/keccak_tests.txt b/third_party/boringssl/kit/src/crypto/kyber/keccak_tests.txt new file mode 100644 index 00000000..c13aeb3d --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/keccak_tests.txt @@ -0,0 +1,3071 @@ +Input: +SHA3-256: a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a +SHA3-512: a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26 +SHAKE-128: 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32def58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c922a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b1de33fd75081f592305f2e4526edc09631b10958f464d889f31ba010250fda7f1368ec2967fc84ef2ae9aff268e0b1700affc6820b523a3d917135f2dff2ee06bfe72b3124721d4a26c04e53a75e30e73a7a9c4a95d91c55d495e9f51dd0b5e9d83c6d5e8ce803aa62b8d654db53d09b8dcff273cdfeb573fad8bcd45578bec2e770d01efde86e721a3f7c6cce275dabe6e2143f1af18da7efddc4c7b70b5e345db93cc936bea323491ccb38a388f546a9ff00dd4e1300b9b2153d2041d205b443e41b45a653f2a5c4492c1add544512dda2529833462b71a41a45be97290b6f +SHAKE-256: 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a + +Input: 33 +SHA3-256: 1bf0b26eb2090599dd68cbb42c86a674cb07ab7adc103ad3ccdf521bb79056b9 +SHA3-512: 73fb266a903f956a9034d52c2d2793c37fddc32077898f5d871173da1d646fb80bbc21a0522390b75d3bcc88bd78960bdb73be323ad5fc5b3a16089992957d3a +SHAKE-128: 0a7fddc22e37eaf05b744459f6129fd1c97cb501aaf497ecb6d5d9b1cfadcbf5c16f4e2ca3f6f0d5e02a0a73d266d2ae0541395f5094b7bd6ee75e9610a5609a88991ebf24555644d9e62ad7284dffa9ca9d6f9e913c4024131bb401c795c7a241da8db9eb403185e29d0639c0c09b46a27cf06f886485cfc2019a930840cbdb48cf9bd8f53e5aa349487a79b904cd18b2721dc1b31a31ab5443e2aa7c02a1dfc8fb439c0838e68753218d2d1eaf4cc1af4ec3e42339612a7dffe12be85affd9f167cddafe96b921a9d50382f6cc91ebb843508ba58910e2cd4352fea695b874ed9bb2d207f2ee33e938566492ade9edca7993a09633f248465b6f9a80984284f6f898406deaa74c83dfeeb99e268f372748bc3ff1953974c81a4a804e06baf8b705b6d93b01721713af41c852daf16a935cc4f0767b77c9c28ce1296c2da0ef5e285b0fb38819183428bc702b26b0ae0030df070e49acc40438baa50888a14f54a8a13f7f6bcd3ff14544afe61ddcbeaf118681a7b43c965f969c04deb4d8e860f083d8659a62e1155e21d114dd7741aaeeb8b781bc7f95256c7f1915e29670082ae9a59825d21fd26e06ac8f3e4f60b1dbd8cd59ff196291412cde99f4efe383f32f235010be4109c8aaa2dce3086ad4562a8bbbeb26de4f6056a801991e10580860f193d3c07eb3920599cce1aa162a3000a18c13379ef90590d6e0260799 +SHAKE-256: 08946cd494a2c00b0e9321af0c225309e9d1b9d14ce8eeb4ed5182031c3f29b0708cd8a24edee1ceaf383c20bf625dcdbce94504416cead3bcdb65572207b36678097a1f5c88491efa2392f470046290da06ee5370964dbfc80f1aeb4881d5611dd6c87d28e151749402027148d428407db197af35fe83b42190689455acb39c9fa8fc9e361ea33a264ecd92b82e7c991eb2de0bb583ad92b3670733e5005200b64afa3fe8f49f44262b349a9be799f949736846f90cb7fafccba6ab1e2b29f6bdf885e7772aea1ca6a2c971c9c8b464fc17a06f44c916c56597d92e3882f82661fbef6f046b737d51a3801aa074ad1f2b67c16ae2f629cd542b9da8b27699a1fddd0f4d239ec93e74e7491802e5a7f4f271c85ff95722f665131f84de26e9f63a3d7abdbf284e9e644559fbb76017c6b136f907eb3155b18bd42f8cf49899660098738b85ae2d259da369030a22256eec14a9f68f74a20927753679dcd296bc28227e380271b56a9b8d799ad6d344c76e40ce174e457e44d74b878159b43b3654fc6c464f25ec6590e4da4f5a6f191c066ddf4d9e93c215c10fc83082e71e6c1f4e5bdf466aba05328d68943cd1f1a6643302457cffdbe168ed1af88cbb0b762d048f8bfb31bd788d8db02ba68e544ba6d2cf587bcff7f28e44c0812123d4ad62747f9c024559f5c120741fc5032f101241a55662b225d9098f5d92e9853f0b + +Input: ffe6 +SHA3-256: ad581974ff7b0df546160c70c4386752ce54299e543b3ac95b0f3062a2aefa75 +SHA3-512: 0920fe4bcad9346fed8ed00e5e03f7e6366f725ea35b60459b5f59e09765571950e2903ea88613f481c7170a3a172ee2541433842ed25a1b9d19c662990dd251 +SHAKE-128: 918511e7f7475a759bfee28d0d39ba918ad101233993b382ff4c0b85ce90161712776a52f57e1fc8374fe677cdca50c56a80f30d47389ab4f1c95bfef80ccbf916bb12b9e02a2ac68dc10f834018822522468a5f88accbc6e5a99dc775853643acab45347c91ea650c13a72755dcbe08b916eef30499e1744cc0257a15ac6691c7b02fdf29c94b8f5a9a49d2381bd95b168a840a3c262b9ab0d455ce576b111e326473c3f2b51aadd589eb2c44195f99bca88e49d9f4c8c133072c1a3f615d13d6d0a4dd4d56511630540af1bd86c0ccb65eeb88e81b15904650b9a1e4c4c9849d7b78dbf006241ab334be7fc5172de1341001cd4138933551f87db3264c2c41e1977cc03be143541440fff9d778bf673d70eb9b383be3fb8b01559ef9343291180fe0585533db847217ab28be3559da19b5ddfd85e9898601458851ebc950532521bf03c97298e192caa657d2f60ef8676607f6a9baf5b30126d755f2058742daed9100d303060dca8a9ca4fb44066b6cbd14fd3280f4060bd2282b510ccf59f51202e8e5f635fb4609ab1ebf3b46a6c3791650a74386e62228f755eced0301bce93aea26d5dadfab9648a3989a9f058b4798570fce8709b3340f958fa348e2366cc011edcbc0e37188853c7caa34ce2d51129541cc9ae3eb9e8bb3cfcffc052078c3dcae11f68aa69b9eb52794faad71d2ccf97d1b45aa8156ef2005d98187 +SHAKE-256: a08da3fb5cfb640b24137e3d2835379a5ceae0635591c74228e524cdb7da37e56b70f040cde146699805b8bbafc4f20cf3f54d21ba5a19cf76613c343449747a22952efcd12aab67defbb2182a5cfd6cf4a1ce4a1e8ab0225191b72515142d70b2a2d5f351a2cdc23e68655ad6ae981a5c9f01634d6e438477eec4b9b0a69f7da98afea221fcfdd8f7bac47c0ebe6a510802332bffebead87a4ea4d842fe86be1216c14658645a097876dfee6eb9c1aa3b02809cd3de3abffb2611e8ad7f0df783c458ac02a52b493df113edd9f4a6a42a15135eaa6574e4a85d295edc2409fbdc4f97550290660cb49c23840327c22b0109fbb1b317845b19b6362d90348c05d3cc94da54cb0833a29ec71696f20a6aa6f9b0d7dba50508485b81c4c68e1bc2d6f30e6afb243ccff3664e4aad130aec4b4792d94f9899a581acd0fd1f52d949b0ec555e19c2bbed480178684c8ee196a87d475c41acd0d68e05d0d3cadbc9fd7e48ea14f506a0f6819944d75875eaf8b1f2cdb4f0d995ae33fdc159ca298be2e147ce3f5370a2d9636b5700c7296ce5bff266b1ce897cbeba4fb7980200bfcee8dd7eae98328fee41656e4a3cf6d675d4f3193707bedcbe74bd2f50805f715b04453b1ab38baba5b371c46c2c4b6eee5fd07504b8c6b1c156a62aa66903abd65261a810f34dfcbeb316178c947b2801445cccfcd4d91e3b710d56894396518d + +Input: 11a654 +SHA3-256: cadf843ed7a78e23f2efe6ebfc781f9b5580bd73689746c3f0f0156a1a6e1755 +SHA3-512: f3790f001ff50078300d72db9eb86412a85f86ee474854c83b7a4ebd10bc51fa461ad8e1797e9c2047657d35b94925f408fcd30662e82450ebcb2952c5309174 +SHAKE-128: 5e8c78ab6668b98083e2ddf60ca1fa9201060ea0c5ab8ea7d7e983c0f4e8f0eb39cedb030a177978758c4f0c505f5a47ddcb4e1760b9e438814e367c4ee0ba8334009dc211d92cac3d9dc96f4e1165dfd72c46c1d8072e02b02ad0be8fc35f74cd0a8d11b4341fcad8bbc30a6e7a4ca970f834f9d4270bd322906e71a4710b0c1b830f238e735db61ae7685811027b640639c168200da500b0d0ed083fc1335136b438c8774cb2799e368e5f3a45dfb25c6e9f48cc29529211a127838252ffd9d11b2431dc4571daf2f5447439fab6f11a061f5bf8c1406c11373b9cfcb6ba0b9cea8744d50dade323500951cd27acc03210ab1c394bc5872501c57a7c11e2f9421c8f4a2b5b11484276c08f85bb09445598e2749425450be45fd27f30a39922f7ad8af5edda3535b829ea0a194c1c29922d72cc1851aa7494324205cd165d23cc073dcc31b0f4cb55c034d9d792048ea3a063a84a6cedcd277aeb5c364b8356582b5f1497f32b06f3b19e13debf321fc04be12c0983c49824f919ebfc0d73d2ae723ba57023f0eaa737630d2f2bb917d1c4eb880a87609e2449998231a75dfd5ffee2fc9e60991d476d0bb47552d8706a8c0a09483b32805a455e18b1fe32fc29f084add155eac67b0a0fe9667f80da3aafddc0edbb84c6519c7bc1ed6d10b6cb3e6dfed6a4a818a31955449395ae4fc83bab0d53607c138508391c52b67b12 +SHAKE-256: 1f85405fa99fae5332e040268ea598580218bdaf799cec847159b9cac0b0a7dec3c71d5a2da14c10794b8c9948fc20af66fefcbe038b4f7ec71451948ff393854f80d28642ceb1535220e091d862e821c9b4e4bda6c6c8355672a4bc01b5e87b81a17f14d460207bdeebd6af4fd9ce66caa0245fbb414e3454d83dc22ecbc8efb3d5547f21835cb42c507442fc852a50a10ed7b791a8297036d4204d226957beca62cc461b297c620baabee036c715f0f0756c85c22a372a08c1479c801532c86d85836362b9ccd03754dd9f060b471a01102cf69488bb893beca104063db22fd60a9bef63fa847b10a14e1e9c9ad83224e3eb33a5573fa1f68dba8fb0a10707263439b2fd84c9bd69798aaf208eac2bf2d7f82ff2df47f9aed97ba94f7efc18b5eff9c1e891a78c6b42d9f7dbd5c9ef409cc25af7dc2d354343136741857321d5fb92cc6f52edd0ce6a7257adca5b88167e2021cf837d1d4461e5d6156658b8884ae87fad04ff7905f89720947ece55912b1633203ce874694a29a21bd29678d1d13c70240e5476ae103bead724f65e734f9bd9e23175ae4432968424d52ec95b75593703964a665106ad1dfd25eb5f47441303cb1f882e229024a73c93642a9acac84026d2c28ee861659584cc4342c31224b6b2ab006a3e021e25b1cda9bdac6445f8ba77bf1bfe0363ce6fe5fc8eee4558c221aa290a8dc3735d80500f2e + +Input: 9fc87b9c +SHA3-256: d6bc044f3c040762bfd6714b272aa6b0f592f6f5a8438418807f66def7f8667c +SHA3-512: f7e9e5f13338d81148e5b38856e23c3de659e149cf2563dbfb862835994a553741845e03c39b2b2042a95edb7e8e03c773496cc86c489918fe43bc37605e791d +SHAKE-128: 0cadb697b8cc098f18bb95bda4bda04d8c73c26ad25c1373d348d663cf7d162eaaff6515990c7251a7fd21d2ad82d5c45ab5c8d0fa876910216c8da909328aa2b30ad73c49a5c3a88c5a24a5b521b27b112e9d5dfa2f476e88804e27756078a98f1cb22568b3a3dc76f42602814d2ff363c932d000fd5625f160d5eb38570df81674f19b2cb0e04a88f92ed559d0bb439f2e1eaaa6650e70eb234f00426e580e0e8de5bc5aaa6e54729354e95775b39445f54462cbf4dc35b2a2d0421ad1f17a9b02bb6c11bd4745a8c2511aff4027b12eef7da3924e266b3566efc2de97d47d88f6381d3b8c0d93535d2ee5972e2d508227ea9e443bf74f088c4d8d7ea13cef854e28e50ec712287bef78721e18eca806379dd09a743ae9656df5e844af9eb58fde125c33d3fcc07e54a761fd784c62e9557a8b60111773616d2342f35bc1c9c2327630c438431daf46e233fcb0a4e88e553b1d36c8363b3c833b055a3573778a0731fa9ee54ba3a19acb76efbbba062f9aee539a3db1753ade94368fa9197b52bbd61abd01fab0841a43129034bcc56d1152191cb28afdbc44ee62a17bbbd55216348d33ac6de7880c63be0430ec181d4972cb23685b734f409fefc6b9496501cf5b783412ffdb10d481f9b7865f49b56616fe22c69976315fb1368184e375b8debb8ddbe55d9df717d62c564e167ba6d06b9f010a0c07d172b3b2147621c2 +SHAKE-256: 8248a3121c02a23f36df9e1c64b2844e57b5b5fba28b2c35d2f33045be874badce70360c1752a27a6d895e48e8003f60f12c2aa68d2ce53e2ba900e190c13f158c17fe3a292efce04cc82627f4bd8d48f61fea209c42cdc88e1b6caf114a3272b471a9dbd1a58546da3d85f33fe9ac53312ff5c7bfd02c79e2914ca0f781efaa2459955b0535eed461cfc62347afc2f0e223f59a21c1861da0eb3ac39af381c8b6f18d40c366b23f0172066c3c5737078d0cb87fb4982deb3054e4671556b5c172c892cd8845fe9d1e15f2b88668a532aeff5c777d89cccfe2a1f3aced536cfed22cf840fc77f918e9b431ae7430e371cc5e73ddf0faf86c3dcdfebc80a42eb7d044a4c6b12d02a4baf46d67f7b5aa6670525e673231c245e7e3804679c5f9be3db4dfca93942d54c124436be80f0165938adc339657b23f0f6e0dba9de2d07bda3ca8195282c183b8bd250963f59b62b53676a85098b39e8bae576567f14835ee125ee1efd0d136707ec5c3c28db9539e6a1244c581784e39dcd7638e548c55dbadb980b41cc18ab053c32bca5e00de8b5eb5a8e4c17a896a894ab195958e2fde195153b7db73bae4d42a0780b9924786769f1be6e2b1d8ebb3b3429257251e373a351f651e7a06f6601557216c2f0d8c9d5af81aedcc7cd4157de5a572ba7a66aab87dc1f58d4340f5fc8c285e58ad6053f334313e9e7a85bd631dfea7473c + +Input: 7c518d2209 +SHA3-256: 71398643fc90d0a8deaaa35af60e66db8ce8a26dfe29127c28b2a863cf0a6055 +SHA3-512: bda63ca97373b6552963805f07480e31879773ff7f242c14ee893f908970ab66724c21574d856e30e66eb6c58e5466a95c2c5985fd5a9689641f987f48361ef7 +SHAKE-128: 41b0c62b7b258ed91fd9859b087145baae04fab0d3d8fc646f6d678cf7ab1de223908737bae96b44c8d293c87ed14c48e4e053cf135e55d4d46db250594ba9ca69fe7ab013cd51be3cf94099e7f68409eea430193f4068047ad8d4e7864959f62a402d56deff2471e5a271ece7c426785f6e8b69e8818d571c1c7a5a642db1e88daae203943f956caa6579fc0efdd8e53d53ef78c455b153809d510152a79b5e29e402a2795fd662694ef1eebd3b3ad4b153275a5556b5cbcc7811277b9ab940eaa1357b721e6eda70bec722ba3951388a9b153f07221c72297352c514d02879a598358b79facfcbc8f62c4bb95aec328eb504dd98f1081dd2179528290909548bd277da6f595195324b63022ddab667ae1e371097d973998a008a6a170a9ea733e4822194ca02ee964827691533215ca1892357cef581edd330e666fadce00c543f0e1fb1022664132d5b7ea5f10ee7c3784999d32a1aac9853324a1bb52aad18ddd49856462978037744d6468bfec992d66bd27055ed8b5043bee51bb3a1271bb7478d31cf3c0d61ef56fa50153f75aae6807d4b73b1d3d23e639e6d538a6b9b22daa4bc1f297eed37c7de4a597cdb3f2ee437e42e9aca0298e3f78f2e79d7324b8d1a5d642d98bd223bfffa8244c930bd2b5e945e4e3ff5e1620586f201f343c1c1f3329ff5addc2d3e10bc4fbd83e0bddbc98bf8feab260e94c56273d9bb +SHAKE-256: 7d891923450f519128d72794d8fb529f50868ceaf17b160e311b173ce72d1b05617c374c2373d40499d27b724707931553eb945f3e5c60689c0e18a1623477ca48652b59b7fb8a13b3c8fafc4cbb95243370380c475c5b4ab88a780ccb137ed02111917b50915bcf68dc702d86403659fbbae0448a18651a34b85b49ca02e3752e0cdb0c256d8507d072548119742540e983ad4551be9ec158ecf1787a20c54af359df4e04e12e9cdfc33d43286203f361725fff83af5727e4a8d4a566664a4efc77a39ff6d3ee9bd3b99d8066dae0be2789682d9d161fe89c78b48b83ca174c1daa291d54f715d8ee7a34917cf4438b707495eb358b76fffe91dd3cbaa2c16121cb0a9031ac55476ac75b30220adfa913d5aaf3a827744f7faa99643bbf854eb69b21257e17d42c692fdb87fe1657789886db2383d6a3474c882b619dc94ac203f851436ba1d46b765fffba01e5cd8946ccf2cbaa8241f7ef6a550e71b79a94dabb6b5d3d92accefc4d6553f81bed9a226bffca001ce246ba5bdbd1c41fa663f6ee72252700b0d9758211be5bf1846b875692b304d507879de451a21ecd2b3cb20185a6b278f2b5bbfd6444712cf3dc295c70638a04f3ab6190e815551d1e58d83a6e35bf3fed2520ec98ba4a7fbdfaf0eaa2c3da6d9df83234f8999458d4f153e236cc586b249debc27302a8e9a16861ce2304562483036d0d4a8c58285a28 + +Input: 8227c838da3e +SHA3-256: d88ae623fcac9fe12649827898db33731ab7bf20b9934888ef9bea3bb5d9c27f +SHA3-512: 305d3788da885cc771a52af3ed3929f03645ee11ffd275eed8d375004ab8073eec30feae99dde05454de1dc3748935359de710463e38f2565bfa5854779fb7b0 +SHAKE-128: 3c3a2163bca02a9b2b928c8c178013a16c019f7ac840e075029656c9e2bea08737735113f7171cf416a4f9768e1fee7b1b6d0906157709cb6eb17d93559e39ba33f09bfc8439cb7851ac89cdbdc69d984389783342e1d5b474480786dff485607d0c941c52f52e8988d95f3402dc6ac4e72755221ae06b5301e373d3c8bf58209fa710a53fc2627d7cd62e12eff1acf71aaf6ceba466aede52997bfe8f232635088975391d1a58cfb8944cb8606ddcc8be054cdc3a42b9303e4ad69d8098b78bf3216ea57062590a826326b87eb5962d0923acd72fd4585d0eca49fa8b9fbcee97dac0ae988fe28de40ff670cbfc888cede4b666d89ee0b791a2fb75a01971867c139c85ed68e0f7ffbd3e990439bb335c01eb9ef28d6e8d11f0f7f04246bfd40590026e7f9dfe0c7f2ac3ec288f9afbd0aeb7b36b3544e27e591daaf643f04e6d4983286444c948b6ebffd7646cc0f17537339a8e71e7ebe7c181ca9ea36055dcc82e9e54e614d04b980887b4323a28afb2952e0c51e2b2b6c9d08cdf41c39b57b1c3a62177efeb524e9487279b5760efcf2046588b549faddcde9162892421f02a15b59375750197b839b897a6559d29d786db5ee5ed4c698a1b70b8e25304ae5c0162b7a4adb5c23771df1e719230b7bef8292753dfa0b2712447fb070075a77e889a6e49bdaa59f2495ead0d5792b8240f8c968223f49e0041c66305b9bc +SHAKE-256: 4221abaa92641871e69e5da3f2df48f8780e29577f03465caa2c4f3438ba170326bd57e1a3ac429710eb6eed5ad425cfd14c10b87ecdfd80b3dc059dfa00547ac4a377d2d3c1b8488c0ca438c88f00b9899002229c809c29aa61d3d7a42c777c53b31fbffc1184481e555645b6fc92a1755c30af25a206b13529606931eda8d96cf34de3e1341aa68fda7238455e5e999db5f5d9ccb2a02058ccdcd2426a3808d57c7f2da74c579738dc9f4b30dc70be4018cf8eed1680fb9b02f11b1d943afd7fd9d2b14093c5c661bee9735bcd33588f6656d6a2db3673ada616ff6c75906c23606947cd984d6fdba218a59bfe0976cc6e142beafef8af7b8e4c377182b4e930a279cf02060bb5af95eefb3296a259952a7fcfa9a6a27a4a97b1509d7598f464e63a13c3658e33d193af77dc98f96cda99a7e22c82f555e58d479ccff946471aeb7af02a18106ea665cc1b7922498087133d6c28ae1f4b8425a70a645bf755b6dd0392e0d66048ae43f5ba3f7c487732250f1ea4fb7ff7b52e780ae400699d4f9a0b0d90f58e2371e497639cec5138fae155aef6d16002e52699b7ac188905ddf094bb3519cc658466782c6a54cdb53e7faf003de015dffa7d822068bbd19119a294c1653f1a30d03046d9d9975c607c00e842c9683882d93b0799cdc45985bf4e05e23e86b3f7b1d23095dbb44108ff23aebde09995f142a22d703ef5d899 + +Input: 4f662296b11190 +SHA3-256: 71d13f441503986a93836b2382cca09dc5fd79243163b8cc546fae1f0e7a2b49 +SHA3-512: 8db9bdab35e5c755ed9d269b6c8785ecd15bb6d6175453111d34bc27326ed07d4fcf28b28f18d5b0f50197f5a9c243014527dd40bd5bf9a19629e65899e9ad1e +SHAKE-128: 1334c0fde66ad64a381e7b7f4654be757680d78814d751f1e444c2a3c9141ef6ff5b29e61c07f2a206d904bd67cd2637a7f6f475dd83434709939b8c6e5c94814a29eaa1eca4af7abaad9249f7afc06954b098cfbb3f8e87acf500e89a27e1db6221c51af783b2ade8a979ad093bfb6c75615f15c0db4a5de178a82eed2e4a289a3b5042246ed9deb55a84ea54a8ead119a8ee6ab3e5b350e7a2321bd4d5ad7a3858fbad294b1aabaa384e238f273399981ec6794d2db723111653800ba3f2b5e1bf3715b76e740066f0fd5c6bbb4f64c20ecc7e74716e296c81668cc47b6b5f3020f4475a4f9a669c9e279170b2bac0ffaf987d9929c3d7b2ed39c79c95479b12d77c27479951e299350f7ba9c0262a14bbe42ee4da408ef0abdeb129f4d59404cd290e32084f8827d05116165c685af9057c1eef166163f40b6f6b1edd4d8042b87d1e8b374a67d187a1b624caf1e883875e58d6acbe03c5b7a9afb7f01908eee831f7cf9dbebfea4846db2a7af020399cb2f199122e55c151ebfe1fbdfefc657a9ec5ac155ac52cb13df096c46e60ec12557dfd8fd74615073b9e436626f22a3b5b8247f0b7a8672bdd86cdf7e0fc4fa7e018a734f3dfa71b09c3e7702b4e942f5bdfe051f9fd90a7940df05ed388a53bdf68a5467eb03e373b76754903f0d33df84c51e71ee6d0eb46809d4a6afc2a84e7f3513593f23dd908073611fc6e +SHAKE-256: 30be161d2a53a1726311cc87056eaa95051d545bbae46d537b8f7e31feb04ef9baca4a94c46ae583d5ddf2b6c0ca4894df1ca1d529280e4347e426681dbf2a323a0d46357c3cdb5c384dd72a794966cd29a9d7cb71c4141d9042fdf40ba7c594e9700004e7066a9eeec6642b79f6259e8e60f259b10ce2c7425ae8a862b2832278602cda8c9523ad2ab92d837ea2c8355e1758c6a1bd4979170befc8496d122683e7d2f818e119a561f1320dba7c5edfdaf3fc18205c568f0037a454b8b0fa9ffce0b3c597c8349d9b596a9846c43f4dae226dea0190d2ed8816a12a07f07c24a6f893cdf90cf23926b2ad9d6d2e8f5c71d248bc07ffd5c8437fb2524667f42166c7bcb5a18dace4aef5c6a0e7b6586d1609c102c3932662c884549c5af31c06e27d98674df45ce58e242bb580f522a594a9b1027e0d7b7f2696b8e666fa3ee1ca94cc449da57ea3a373edf7db4e508e66407a47ae0e778f9a90747673b6cd0bc8c187c26c2a777e6fb98a24717e7bfe12729245b1d16fd555f5228fb8710b04f3d70f8ef95885efc2ec997351533a5915634e7b975be56a689d8ef1385781407c5d8c250c676a0129d5073098e9f6b8f1676dc51b6c6799eecf9df58c69c44e062696ce992e78c00fd541f114101be231262d154130e3bf98b9509c59b50ac9c40f8b608eaeba7c8d7334613f58cf59957622478bd4d2c0c5fb796d5fd83d02 + +Input: fae2503b2539e4ef +SHA3-256: accfa4d9e87975dc9484f59c4f74c2d6ddb85c6eef7be26c00deb5f6c0387b75 +SHA3-512: 126643570019138a7c9a74ca9696dab0ba7aad00a988df4b0c281ae5ab318c19ceb0a7260c764d3268c81ffb655d84771051f086e3e785d1f53452011af0e357 +SHAKE-128: 130212b6ef03ddf21acc384a8bc12ccf9e75acac27610eaff19ff0195cf6ce1bb9695fc2475e88d7639abe222b85fbcfc7e744934a34057956934b1e5751431313df7b255e816504df399a345bf87a49be2059dd6223a51d38745d7c9875d4fd1c3528121f8a0544fdd00f04f81ddb7d243db21c6093f471a77390882bad02021b497e7214aaf38e962ad58b20d3c24165951e44c3080148419f96eaea7e890ffe1760b4655af6c05aef3b619ea3c9e8ded69e65f95e3b5776335064bee0120c8190e98973a084326cab4bca1ace3789729ab97421c894934d0821277ef6a868e1ba590e0b0c15f838b0494b7cb5c9b1002bb93664e37321a1ce6d549895160084f7a3bbc8a46374abd4f2a7ba75c055130f0d4a403c91449e6bb3e022ea35ef6b97df54963938b2394b50954237d8b93a5153a919b7de8e731f197c9f8532c26ce238660bcdebbd9021473e31761afe37f7f3e4de3a039300ff197ebe31c8d52390f56dab1a3b54783397920f883b2cd6e0a9955dd7d75ec0e59b92e914e283af0306490cb5c137ee7c3bb35b0cad5324a7674a6ab025cf2ab4bee85564454a0ac3777c135eb9ca537cc84194db103395fb20730c981706183d40fc3235f59953ffdcac579bd42ccf590fa1c9ced5a425ca1cfe9eade0575d37f2c4a1a7aca781847f9e76692bbc7e0b9c4f1939689c50c64a3fb176306cd11647a5a7fd5020 +SHAKE-256: fc41fc848ad550fc33f77b678dea5ca0965f0e59f8cbb77d3d8dfa1ba113b50495034dda20436eb00c26f403a2d087ab170142316dfc89484c7a43d8b68779da248fcf1402a69005154d0ca3deac843ee2c3d6eccd14739a61b6eb031805c4d7e37f0282711f0ffa5d59a924493e57bb1573821e88b32f0078e4dcc2117f887425cf5684326a2b331927c3a1925cbe615238cff89c299a83d9c17fff0dd11d12dd50711562ef5e08b03d131e1d920acbea6658446f1aafdc774dc4caf8e5d9176ece53d5c09b93b9e3ea344d5b6ac593e734619c30126ce237c904285ace9f17244053cbe2017e3a79f4778f46168fb7d05f46d103c0d6358220337e1e3077e15b474a07a17f6a75855edd410623f6af4dadfc6b5c336c1e45c0acebe61b95ca42227e09d8768bb78f0f1ff7ab2803a7e25c8876dbbc6c45300a861e27c0093bd0a83e2d494615ccf5958f3c68d8f97d35438c9adbf873048c61c6d183ec0cccce2301d7cc1a17c245373cd6bc177e1557534e3b55e85c3e925c7608cebf4d06f4525ee5aaa20fa628b0e3338188efca66969131efd7577d88fe9715ffb019edaae83ce7702dc81c68a7bab54c2c147838feece6c2991bbcd7f718d96aa1b180a16984cb1d71cf48c0c635ce4b386679922d0c0846a846d1fb66b99b36b1a6a0a60b7ae87b73f4a7f4e2ab28f1f691c6a255ef336bede975946ff510a73ed943 + +Input: 36ec9190843bde0cfd +SHA3-256: 5510a8c5cc5fe00fa20382d78cf48bb194493bf1bb82e2e836b4e4546ce1edac +SHA3-512: 10eb990bdc39846694a126c3383a4564b197adbbb84feff1ec53af2feefde24292ef84882647929915b9f50c52cae0c9a1b076f2901a494a099855603efc3bfe +SHAKE-128: 8d84aba1072f69c1752ad15123726fc207cace0bcb454d227651b5d6165f784fabbd96b13ce202e0fb923959f378d8af2c1c27f4d7c7742550c4cf9a23df86fe04198ad88520597fe86fab4e60487eaa2aff8effd2c801bd5cb13d9796ba81dab607f129676c196c9fe9f9a1c5a933403d175b21cd5c72ccb9d50f5f26d6c590bd12254e4764da7d8031cde0f93d5fb63e311a7c846ff0a414ae38e92422caa96887cad74261eb0bcd2bc678d5fb78d8ac017b7932ba2d7cc57cf44e688ab4a34b17cfc3bea1f0820b8664c98061ad49e75319c5107ff8c68288495744994a84593ae974fffeaa532f1811d75a374480b7337cb099c232846a24525b4ecbd7e0dff2912371e0ef413af74b9586dd0f091087c7ebb17e9e5e910f79f619881f171763456b006032b86ecf8795289814d3380457daaff22c2507298ccb05c8312459a78130aab1fd476bf6e39470178b5055578f0042b2b0f70590abfefd191ddce4fc99976606080bf0326601b5ecb0555d59d670ddaa248893e5a628070e791102e3c6abca0a60b4f0735a51ee7b9df1fc6e0033074cdaaf2399e8939a8265440a340b0868de27131e3128e8344c19cbd580fdba781f30b916750809dd43d4418c5bfb179908d10d7530eb77a1c844d4b7de0adba12bbafc93593ef64940a923b9a440f26ebf43a1cdcb91b5f75445463f62f8db4b6a0691e93ec719c80aadb6 +SHAKE-256: 8a7d7a8367ed699ee74fd1ac4d1950cefec733e02c3d3bc90a11fcc0fed37db4c1ff92b28cdbaeaa4db1155320b88ab64a3e4b741014dbf3a820fe5488f2639d49c209952e9d6952174c5ac2a2df0204e8686912be4b5c50c5ca1cdb3b6a1116738882c749a5eec78a758ed113d32a9124e29ca0b6450069fc1a9c5ace62350bb3902926060b3e3742b837b9fb944a0961816543a5abb880c9b0a3203f02c1c09a5f5db5ded3989df4b4834c6e188de5361b8d2d16a4816518a654a6a85665bcc7ed1ab3c5fddba195ce7c39ac58168b1f3e9bc9886ae269e1edd6a2391cf2babcd755947544092432957c6956381d7d854da1a1be589415fb1a5d7970a620a6849831c6ccf1c86e8dc5082a0d6f8573c2bfb54ea5418af5048c573dae47eeb9103075198d17a36f418c3d605ff078ef85539c1898f46e1982e2a880f2d0c7760becbb54c231436a1a50983bfb3b7bc2223a0df901469576bd7bbeb2f318ef5575e230863928fffebe1c37b83cc861c5aef03bf1ac2f1ce03ee0a0e29c4bf20bc51a623247b0633e950b62d52119c9e52c0911d5974fc462a8f8b35eef65e623bc87354e16e1b67cd32e8e7743db45a8ce00cfb227e2eba8718847627e4d1d614a51b7ef205a3f40a5b5bee5e0f0427482abdc8a10c121617d2d3a94e2f2701347058724b5efe28dd320b1cf098d5f20b8716acebc186016c2731f21da4487aa + +Input: 11c1adb3bbf568e78273 +SHA3-256: a08841f8bcff9b3b1fd889a949ea20bbe48b13e4c770ce18e544ce3dc6ba21dd +SHA3-512: 345a95b8628db509e6fa8657db263c5d6313dd034ac42fcb2b7a7401df8843e0b7028c10aa39360fc92ef47ed2c8402c14a8135b8c70ae5b585418807fd9e895 +SHAKE-128: b8359b57c2229241fd25c3ffc8255250a117279b08f213fac689445d1f798e7fe3bac3c783c56679090b085031d97dd7417c0260d289d04fe74614d9e3eb5dec6b14e8ab314145de44a445ff0b8d60c25d03e9a426284c66151c7d03846e29ff07e0180c0696f121bb3d6f0d677abfdec59dff379b485151e6ed915e4edd0add374e741a0dd449a405c07782953e9928fe1121135c6edc3e23d42f98b5afffb9f3eb6b3265dfe7bc36be7162b9db1219391575d654ebc196e292b25872c44a87251d40a9e1a48ec9c520cbeb745cbe6d908545a112a3155dfbd12e556f2a636b8ff61e92f26145ed20904445891a8d9bebdd1425e58f0d2bad30137c3efd4454c54587093aaf5f5700deba8e7d7d1f90fa5b0204fa2e62dad742106a118021bfd4508f1476ec98c42b6747aa1a052f47cb1fb3890b70376cf9059069f0b5eb9227664bab422cd98904c4ee30d21c2432c198d9c5901ea605215e7ec3202d1587f0f09deb8adfc6b4fb7a65177aac0850e00ddeb258254da34759afab0fcb365dec73bc39c81e5ef32f5c9e8e017967df4958f9aa9dc592583b7614cc6431587f69c1ae749cae12111e2fd11cd92846e61fa0c1bba2402305ab6c56b088cb67569b6347f01e6b67e6f16c8bfd1fee595dd08eca56cfcf48182e22a0d51b1e7a6522c0497ca10b0e0a922dd0d312622657652de54d369f47e9088320b5ceb651ce +SHAKE-256: ac206334849f388c40f75d118928a802dd2917c8bc6f477c075e600be4d102d1682c8ca2f66e2de01f64499432a1539e94be68a7e055ae4c31fd9dd9f7ce6c2455b10fa40c9f4b785540fae35507641335c01babd9f4ea3dd59eb1113325a8d8607aa53da35dcc0199a6f4d085c778d37991c8571a38733265e2af335f249d583aab3d6a9f84d60d6deaf1a0c35fec92d5d521cc791dca72c31d907dc3f7a41dbfd1abf96757d7ff791340dcbc45724d35271171f35d10dd4457546980cd101b274413c81c20075a7f9b7a70b821733c33b20ae2a3ad8755b8b0f3f4c0df9f804f58750d8309ecf751d4dc9eee69c610abcb3761dd28f5ef609c84ffa20f47bd5540dc7409b163c582f593d9b21c85ea30dd304bb500380c9346588ea91bbec0003b313908480db0fde4bc181df09373a7b4b7ad8053a9dbc908bd84dc5f44d518b1f47d6ceddd703dfb4356e6dcbf07a1a480604eea40ebd909796340759ccf4757237e98cb8fa33fe7ffdd31b7ad23ea773984fd297455267aa82a6ac5d34e00933ace84f02d1e5d97293f0f5ec2ab9e5d3b3efbc7cb4a984db7333ed3dbb200bdebc3a4fc09a3540913f1ddbbda354ee151cce1ec77c8a71d97a0ba960c844f6d161793d2ae2f58304d49f2c17f1daab6a76e163c921d7323beca1223053c853762b8c0f93ff6681f35442690b88687a235a0c2e46f4597f7796b97693fc7 + +Input: 043f0c672734757d22899b +SHA3-256: 309a1cbee401a477764f1c96f91540e22043ff9d74f6a89c760b2c68a19e86c1 +SHA3-512: 08100dc4126f7c1498b1b9b8e1ab03c4b93152c00cb451310a6be8dd4bd95d7b5249a56634fe37904ec014d2420379d609a1deca380a9d03685597dd24374eff +SHAKE-128: f8278126ea82044f9d2057e2b5667d2dc110898bf65146159c11d29d636ff0d9c6bb47fcdba5076f7e9e501c007c27333714ab470a5de3445836995fb2040c9264bfe7efb041a2632f5943e064512364ff63e16f0fef097331fdebfaa84146a29488ff0cbe48ed6d77316b8efb9d3cbdde38f08772c925cbb064862b228927c8a2d86ee37db1450e85f841b55e6ab398ec25f4acf5969d6f487348e1a501cb51a1c31110193e5c555ca99245ea79ea882c7d2337b2014eb690e1fadba57d8be61920f7b6dc19498ec0a0519781cb50328100ba340488af7b810081bccce6a835b322a8d94c5e19f826d7955ab1faf4b21ebad46e91392f1954db6a25e3bbd2cd93f03a186d1e2f658886f508ec7a29fde9dfc83b562b16d97131b544e3551b2978d9b83cfa4debc1970c593b69ebb66efbd3d24f5e4355b3e2a64fc717b9ff033414c8da2675e751774fc39f1b38158326d91c53099c66d5b15d69b22ff68bf44858d00ed43d0d2142790ffc50ba5297c5f1216c44c7d5aed53cec685730771c6403dfdc1126be77676d91565877fcc40c1926217ed45383bc6ec956d108ee74f922f8809d248de7ea4ff35a022f94d9d59d3de13288137e1949f3cbf609af06a4e64e88bcd51c0c7f27cfaf8773bf7079bb803e0df0978a90743fa7c65fc1d9130b463e8f1cb32dafb4e1330b669ba34ebd7fe6eb40f1af2e379d8b18a91ce4 +SHAKE-256: b288b308fb32711a26c8e803ba7493ebbf1b74a9925232bfab56f40488658c1fcf5e331942ed380f5a7fee75993274fbbb09f806988af7ecec9740da23e6bca66d3765cb401889c82c2e0e2d16bdcbc334208a9bc0ee5a7bda1b4c7990b324e022caf05b598f116b52cb09e59a429c1b76f6b0a2b529b87e9abe98099e736dbd6e318bfacc030dd68fa993754877969f7da3e55f3774fabd2b3cd1a515ac6f01baf8ad57804f72eb2b55d5c1356000cd77df039024b6e9cc4bab52d4c01440a6ba89ce95dbadc5af743bf032e08b6aa30423e65da56d93fa145981863203b06a7a4abcaa62517d920e72b8573afd6815e2765339a9ff01d64abfad24d5ee18ad326565400026bb4f14af8be3b312ac6ae42889428b82de8a531a8b183e7add6366c1526d6a473b1aeb44a893854cb9dc5ac3345a125eb3203b6affcd22dcfff04d8c702cf9f44dd97144272eff2354deca3c0f8292618b3b0da43e30d7d337a28ffcd7f191ef0953b1fefd29de0c64e0f19d07b5079d86469bda5ce5be776ec11f87315826e7622c5a0b3f0e8a2409855bf0b5ebac7afdbf4375d476a4f68d790122df80f16f07f01737f95828ef9b562d3ecdf6cf5ce812eb8becc4ac78f7e1bb50f77c80e17965eef5d13dd2b2cd51319c29ffb7ef8bb17319a0f62b3bb52fa89e7fda397f2d831ca9d2881319b8421181ea5d251d42703ca1346845c9eee5 + +Input: db9e5816e1f35ce7b33e6cac +SHA3-256: 53b707ed1ac627cc458384fdb40fc138abaf4d817e87622c355550ab26bac330 +SHA3-512: 303d3aec5c1f7231c0e55801064b36a5704b415cc5fc652168b3ad2bdf8f21798479f6fa7927b5a897706c88d67522fe9254c95db10a69cfd82947f39873d1b0 +SHAKE-128: 045c70d2735a302ec9ee594f8d4757267914249ebd3e0d6d349aee0f7a0e8b2a6d13729e0e6a629ad3e3c00171dd6d3d9d59418005791161338fa995c7ac9cc2639ec27d985bdb074d64c703af04207fe72bc57972da2ee9b81eaa71c278467e9bfad32ae9eea648069264ee04fe14ab98c08ad79acdea8baed2543a0ddce05a0d0117c00000d09fa2ce37f0c10a496cad6bdc858a019ceb10d8e4df7f1059daadcef7acce15ac3c54223aad1fd4ed401aaa93041059c6ecaf88abf16f7a0dbdfd0f0d39e0191d3c48fdd6208c481d177e9c429f87fece2436e55c034b2777716fa69e08eaf305d3150e114e1b18c3fbd281ca444f024ed09351882e917585b8d5bc7a70d914d954704f58d1d8d68e459671e22d5f53c7c09357dad1cfe5f76fb6fab8f9a7cee950e0c46ecf879f5a7064f5f58ce324c8d54979a3ba7ae0b389bf228fad7453c680427072e4cc499ec59516d51a52a2d1aa6bc1975bf6a01d9f331eb5589a2cf8ac51a8d252988791bb80a384885ba99e73687428b75244447648d9a0f2b879bb729ec1cf5e477bf51a763eceaa7f5a83c2d831e216d268edea3381c224cd2f59d2cddda4f17f3b1ec2c9385347ff412ac9c8a83f08c5a3852bb02aca4cec85a4d05b48d12736dc83d9baaf5ff18c386c1b47423df60f807c02bc544496d1579f365a085e5b6df6590a5c40e350987412c33846031d10ebddfe +SHAKE-256: 4b90ecd04c70c519861ac01ee4f2ec22443273d6d8ccc49b8b63ff5a7c3824dad9d3b046f783f8b9fa87c1bff3371f80f306e95652f89de91d3ca7e0f5c11d397b3acba2327a7677bf81ec8b5dfb1d7950be9494a0d829707152ecf123eb4338cb4b8fb2c172393d13f25aee9a50fe106055aa996bcb61d249ccbfffced3dc5d1ab84274e8a51849c79b0552432712832e3e0b9b3d791b1460f75a390658935695837e27fa87a6842b37333f490733f256a4d2631ce94ab3224832495dcb36a5f3cafe0152865cbd464a1b3efd05862484437845decadd55cb5a431e846c5f6041f21b734902e675c46fa9a0ec6d39e8d90692ac02b1d6fde8471add624f4b26ba5b46a15fe453bbb0d4bc4c9a8ad9c990cdb4ba8803967985518125e41e178879ac3d5a2dca80dcab74a209b4bb6cbd7d4d71a7d2432fbb739027b2223ec31602070db1c7501f6a9cf0f4a9eeccfa4da9324457911334442eb7da8557a4ac6a97cbe7debc339fe99807724a6ce78abf5f9e7a9c3b38a9817b43bbf3952e353b9a0ce82e8fed9b0ed5db8a8734352fd72d6e017f6bd838db7c78a09c40c1c902ff15e5d6db094e106e8d7691b16319e06550c608a78592dd1228993a84902baa9d96f6e0e52a0d86681e346098fd2f8cae94efd77b55cfe328984547c2cae42b8ec843732d70bf0fad10dc9d30fcba98fde7454bc3c78db0b7de1b9558c44817 + +Input: bb47364ecd0647d77e397730fe +SHA3-256: 6f71194df501afccddac9bcb408c774d7041ec29861cd2d1e4ded3f079dab513 +SHA3-512: 484b51509d8d63974c80cb3592cf6db3be77ef9a8ef97f9fe39b5e2db0def4ddf5ecae22f0784f6f768c4fcee3fd858e36ac93f56a9d4a92bc2f07cea6d50cb1 +SHAKE-128: 297910584ea4e6e3b6eedca785d817f88e95aa71eb7902a86e55fabfecc445fdab4cdd067ff36b68a7fba7572aa2b1e23f724efb63fbe0f0e433ec60755da0faa1860f127b40f77bf7fedb5295a38c75e7397c1f8b67fdb98bf2c82ea147092a31a968403c9a8669d5e1273fef400f326b66c9d0257cf2c42168b031cb716d4a94b15c1fe1694ecbceab12e8b0c5b9fb4e2dc96d808a30b9e6c7ea8c164076331d7dc668f0fd5e5184d6a5cafa5e181618debb0a99de1ad988e5d59ebd8769474a1b702a44bb422541df91bc0cd6fcc186ab6b19bbe5a408fbde50a0330c6d10f00940ea80694a1a52b80c25cba15fcdbe64b1f26c277d6ded1b1122839979fe84c2f8d37d65adf7bdc0f95a49e837e19241769a28fa378ee291e26d92b50d6332a451e0790db8d44abc632712792a0777a99e219c5508a1ea43bb7442badb63d0299a956f87c5eabddbed30c57dc20bd3643bd8cf2bd2c09d1d5e5cb47c6d5b972a968c069705fc23812193b8d7a9eead3e6add5297ef262c7e2a1899dbc8af325d78374428277eff5a7639d53ea7dd78bcfcd6e6ba0ee678152da8c177a98b3f36283f2c41dc10b118a218b78c4cc975868e29b37347132cb324be9f84f7b24acdc53078da0eb7edf3a415d87d6c0b11cceca8b1df87d44c231c7c4e265d3811426f1c1b40ce97770c35d9a277c027fdbb1bf774487cf022b717fc4a4c7ef0 +SHAKE-256: d313f55a9518697d46c97a725d26c23e3a740eeca5f168b871885da9a6beb576209ff5fc61442e0b3c90173f88fb1e6ab9305aac1a54849f16fd289b5661dcfd3b91ff966a2951608fb63a220cefb7f4bc5eef965f8c30135c5a0e4eb17f40f3abd18c9067394bc06ab6cc9898eb2b9cd68085af9432cc29dac718ad885f129510f415201841d6774d01aa1a15f870c494816ab4e13f386ad94a279408af09f5b73dfc687902bbad653d375ae2da8ff9c375ac7a8ea6ab9bcaa10d85bcda53c73834d4401fe5186b562d003595007decd722cd6894b18e3efa426c260d6452670ff9428299aa702f3d31e9a336e147414cdf1c85522651c3dd0fdcb126e56dca18f2445af4e123322c0beb9b8e186e67ebb3c00cc657aa31e23b6e1e73ffd3596396cc0a682ab5c8d33239a3a7d82ee90fdcfcf56c4fddb53089e5dde57bfe16991e5211e50eed627092ed4984f266c2b6d04aa4668ce7843ec63482dbb4e66ea2c0369d765dda72a97efacc51f6bf7dfd5b3347e421f373ab4d02eefda9081a1e9978c31bc940c92cc29244d17d4f050362fabbc3f98959efdeec3f3f9c18396f4a3cda066be65646923ca6374a77f6ef0cf85e3dcc06473f40506d5ed99e09672aa2bd7d3e71d05f5b116ceb0b2e2221b05ba9665cb7fc77432e1af426bb9cb75847a2a57b0085858336aa13e2b41d340820ba6fde5571504d60781894c46b + +Input: 7eb6e8745e9cff4a1c7332094427 +SHA3-256: 97adfeadbc7bb16decb0fc209162e47515b79adf087cd2b6d01d71ff60cd97eb +SHA3-512: d54f9b028d2be866cdefd057d8984c0bd93b7a0ac566648f74535073a1a1e92d60ccfa2c4813f3411ff90cce61eb0986f193bf0fa909e0276ad8c5b53bf3e318 +SHAKE-128: 53e08f0d4a9345e4fa1ea520eca1874b6d7b9f8001bc0af52b7f1459d5198abee61af86987aaa44a8ec9708c45b04f2e7286197aa06442f42e9746f2647542cb9efa645647ee60a5117385128c576e6402da9c9b4366db80a9175829d4d20e15ac20b718144599e921dcb29bd22cbef35782ca5c38bb2c75331cf58e5b6c7cd84a6e3dc4ae5eaee913c3a54c2ec167ea90b80086fc2911918dfa82eeb1d419151f1cd74264671f07c7afde17e528fd5be717ea68b491b30611121fa31402d02fbc9443ae854a7a2e54891f0783095451816c7d5593dec07d5009bea6a9796a1b085df7bbdb594e7ac390aad4abe837a2fea3220f5a72d6371d32117709ec35e8c65e2aba23f772eaa4dd8a338ff9765b8ec6054d9bfc7b8647dda23e7d3b4f82addf176bf5dcdba454d21c7a8f154db73c55461e1269ef3e515566bdbe339f0f14ba6a50f06737a620df4d8c7302cd18d102d5805fdeafbd44a99b6f8f4d529b6ff224bf268103c844054e52d08222b8e47902ce0d4dbe0f5b9997521fc22bcb203ea57bef5c2958ff0975af3756b6ae160efe5ffbe6c69da8996b95764db5fe38e514e41459ba9755f8dd5a28282c7487ee745967a0dc60c6f6361d2159063acd7fd4b0542494df23c176f338b7935271d04db4d89434c66a5e0d88087f89d07348f48c95c674392d8f0b90d5c6e32b646411d50875ba1a8f3c8262da797736 +SHAKE-256: 42fb58bdca40152b48b7190adbf376ecf36cdb0a9c10e37ec9985efffcd7bb59e5b0878a18155aa83b77c57db5faf9b59e8092b28358609f4a75a4ca8bb3e74034e5811d2d9fefd15efa5377b5b6150a437e5f84bbba6a38e5ab847003e38abb20b50713f424ad39fbaa513b0afa868a4b5a9ba0466cb1e60cc8904ffe6db3f2c5013f65f9a5df6bfcf9cf27665ab2ddb5221e6dd5e6febb37a773923e299fffd1f7bf3c8b6b60ed1451960faab2cce19b04363a4a530dae067ce29de407922acd9783f8f4719112ab03213245939e061da90ff2a418f964fa21eecba047186f0b4ce847e954607c5ced0fd4de775d0fe342b462b90938cea33869ec6a3058d9d62530118fefe297cab2a02165214b78f605ca2c266ccf128e753cef351d94a514f34dcfe79604f7d53443f7e16c1a54d5d719ec32595f3b152f3004ffd31131a337d85a41bd46b8beb045c9f63693771f0296a16034dc55aa9ec8f3c27ffa4dda533f8588254191814109a3eeb2cd329dbf49500f4973b51d54ec289cacfa9255f909112552531076a0ce1b5c54990379d79d902361287edd05f41698080bceba2e98fbfc1c885240287ce2222b23eb2518b966dcd91e1be7a617a8539bcb05185e12b7106e86e0d996126063168750a6042c576f397b80561b734018c2b680a391e58af440fcf970d61f7824048e46dcff005825196db2f5493ecdf7b7a976 + +Input: 9bac4256ebde5d24b0a6466684a420 +SHA3-256: 58ab4a7101e87c05d5c55186655f3f596e4144f13ed36e3d971db59015f87bb6 +SHA3-512: 975e3348410e4f29f93d117129f7ec24a3f8fe94fcf526cdfd1dd6bff4f28d3bced4d79b8b0736358c7b0fe62e30395ebcba53cd0161b213d101bfde1273999b +SHAKE-128: 1be7e622342d6adc2ddf7fd5c06250738fda066ae9175df5e4859e659ae249ffea84bd73d54fafb877719b1bdf2f87629547c456c1e5e03372de0f1e72e65a253480ea5c137e2461f792e2960c2c84124bef91cad6585b51e0f4b07d2f4d60710b64f430f14380152d73f46e238965af06aaf3938668befa8346364c295823c591d11c9257892a096630d59c0da031a1a2eab39950791a7c364634dda3840c2088701e618bb88e43d5c3238aaa5f96a3c3637059ba47a0e13bb67ba0e706c8893f2b9fe71d279f3e7537bebc121bfae5a8bab31050fc423b48410487d2599e52dcab7196e839cc941900d11d5f11777950c5bb72b10a6ad87cea33b85130f79bae2c86f742bd61e8d77bbe8fb0054c0d194f72d88d9483785988a0a67f5d442376852f0575de83184817941df23101807a5f712bcbc470c65639652475518529b65aaf91bea1e6896af759a66a29fcc59aea7b90dccbda2813c5580a8a08c11af23cb8cb9d41b60636706328e019de64a4ff23a463969734b45245889c160929a01f66863bb944ca335c28afcbde60d736a95ae0661b76a1c55906c780bbb3379248e1bb62c7d2dde67faf1be6efd458a6409abeac88910efc5886a2a964bc5b05203d9548056ae877b2c6ca60b00489de851e66e6a4fdb71a938486fd324a4723b2161970463ab84394547c134b6e45b0d4b8715d601d7d14f02b6dc38baa3c +SHAKE-256: ecd9b35410ddc2744bfc21688fcbad9e3fe779e31c6192440bfe64b5ae3b4ddb8d4cf2f6e960908a1f7427bd9d0c000e20d5528e827b472c8b3fb8b62779f43f86f985752677f7f85945e83c8db5affce156538d2547cb423fd041aa2259289ac4e40e5f50c273941b941269eb00397dec8257c6bc462d2d9c2613f6f1461f4550a443081b6e12c5165c70c3fef045357fdf67404b0ae5672bea5e01b8f40627f8967a6df058fbf88227c5ab6c7ace3fd23b0259e6f3ad8379874d17d7493332e8cfa3db8943d24925a06518ab1fe262a4827f02d6544d133d23164b729f595522997afdc1335060a69c47104483b01e2e0a37c00dba1aaef67b93c0f1a732600e7f4544b802456913ff23811a6e976e909d3ebeb3085a0530ac5110394381c37c9bfdd96dc77d143760a48cb45e64da6d05df12b605a16aebd95ca6ccf3e4b9badf292333144f5d2663889993e395e5ca12d10e7ae8cd9af1dcce6bf438b374251371293c36bb2b1e47e8b11bda7287fadc1f5c464e020874ca8b6992b4cc6b08b2e91f01820aba11220f857edb1a2734f2f85141bf34f4e25b437f6448219970c8c0c0f8a6e508335b4990228cc0e47cd7cf6e3d2a4544b389f1ae2f02e25c16cd1d347de5434f1339e95b62a075d8fedbfcbf0c038925ef2ea3f1d6beff8b1f9c7019d611adedeeabc749739c531f4cdba4d97427876b3a0b03f4460cb911 + +Input: a91c3e7119b43d7c675548a37357e246 +SHA3-256: f6bc15a3d2343b19ce5fdd7214ca50bc1f0a31d5e66585accb90712941b4530b +SHA3-512: c5f432de1d18b6c7ba4480acce9a2c62a6ff1ede15704404be3bd8dae9bc0578721030eace6e25ea24910bf9f5a7a3600e9c03ec3f3c795646dccc8333108234 +SHAKE-128: 34c109a8b5915ebac04d5281a103a7bc02d587955f0bc602b12903f74fa44c0d34d51f6a2fd9d02d30c1a648293da70443f9b7f5658bdf9d694986f9a546aa7f1fc6b4e79aebf9f8c3ced78c4386c5d0241b0a55ab497b74ce824e2eb168b5c5a6ca74d6efcfcb2cc34f008c34b1ee3c8b2735d9ef3dfb6148b1be5eedaaebe90b631300ee74878187271f3f7284cd88c1c3921abb87e3b749e3c136fadbb98730a7679b80b9e622223df2aa5a7c0adb9191a44e196ca67cb6a134c70b267e6334e081544e0de4b57d807ea02c10bb30896e7e77dc02660e380253fac4924a9720c6b3fc3f13aa15818c61d18d947f9ff94d424729de7e81e280752eef1456dc77499f18756d940548319d0d1c0601b99f4f759477fa9cb5695f23d82532bb04a2a30a05039fd5d8765048a8f9b6a69d10957d8f4484995f9212a89214fb10323a0ae880dc2a2c20eafb3bb1eeeca16167415f774c8d0b95ec0df79c61603d077b6276aa22e22fc64c0909d334e77c16912a4259affb5186be9ee7a1d91756313a695b6c319a753510de6580bb453ed983e35455b954044c77db682c36bbb45e9907502c72d04172f88b9baaae0d21fc8339619268e9fd630eab66372284f3a25944c9784874a974028847276532b4fb60996b6c5da75daef90cfcd9ba14144878d21c66f9faa55b8e3850968e692fbddbaeb830f9b3d12e0d7cf8e9f71ba083 +SHAKE-256: 7940cb003352278e463f3d5e71c16676cb6058841c896106507df5f5050ed17b00c3470184f4611c9209130c4a52e2d976c6d6629a5e3ee4384dd6aebe513996741f9cda5ec2057b87092c57f475f5f830d741e7a28b7f2d00fe603bcd91ca0f8d40c8f23979e7d583f618c139424d3cf35466ab1e50e74aa9969eb8a48d5bda63e47fecaf3febd07dfb57c5da23f7951fe6907292fd1562f5ae187797303cc854e7906e9a7083901b81606548ca2a873156728a851fc608e0221524c2840acb6dd38424e0ddfbec08975fd0a268069d6193012337af24bc2e7bd736f172ed1a69f23a447132efbf3d8d1370d5d4d4f24994c47f2a57e0fa3ce755a2465f7e2b25e355114aa9f31ca22feef39bf9e760e53dd720c62aee59e6917059646f25279f71816f3146ba7e1582add728e0a20fbd13a2278e591e0c819a7410fc624b1848250b18e7c33df06a579b9ecc7a945731a44f4cf4eda1cdb5e873049768467932ac7cffb14c4ee1ebd2b5f504ea73a6912e840460ad278632fea968b02f66ecfd11a9dd6246972d310815c499c361248810b5dd92973a79fd3ef964d2c17f6670451c7033b80b7934c47c18a2be566485e887ad39e730c9e7327687f95bb63b858dd1e9876b23ec94e0d3f5f447074975ae9ddd9d27a6b9715bec670961c3d24a23f84abd002cfe51a59df1d7516c656fe9dbb108f6fff2c07d8b1079e23981 + +Input: bc3f62cf3df0b82025ac38e112eda280db +SHA3-256: d489ca1938887440617093bda8560f8b27b4d7147c0018d8ba7aecd93901f338 +SHA3-512: 1f7870a61f6191b12cad832c1aebb60b86e52d1cd124eb181d1782822b68d4fab7d9ef83eeb24b2e4b84475fec7c4cb1c4dffbd920ad8441444cab5f78e47902 +SHAKE-128: cb524f5155f7925864a4a4e6fff28a262dafafea56307a840e9af96899a62916d2b4906b106930d2abd1de46bfca3ede61167888f1e1b09bd3b3f1558b9b47d05e3ae5fb77be3d373d24e5db14aa1b93dcbfb1cdeab883ce59f22cd81b09f55dc253ff26210d2113ede3d3c42fc70ebc87fab5c9ac9a4ba4db8361cc836f51ebfa91f01b4239ecf62021cdc999c711d4be623ce2bb53a544b9ebbe4ec02ee031b9ef714a5bb5552eccedd984f55afdcb0d882632a24d73300d0d375af9212b4d21a7dbd9b059350bb94df0fd50d8ef9f12a6058027fa92aec0c919a03eec3c872379f6c52679920ee3d367f2f97522e4e618e8ba37ecaa69619577b1d18836b61af66577adfa30aca67fa2d60e8a16ecc6c07399d0725c8b278206cca343ea6210e04ec5e7cf60345ca7cfc4e763ee83f4442e542ebdcafa6d66b742acc0f75b3f63d4a6cf5c8e69677aaad2e50a36da6cb208880f49228de3d1e6df53a33b30715cf41d0e7b882b64516b13561dc3b9debbe6d60d61dd96e8134f7b6975860369eed0e52cb48a89ddba19673933506fec060e4c13ed176234da417450a04bc76209056f68cc8991d07c26a1f5c0c5c37bed42d4f20ff8b37c8fe5a4cf22c0f7305d61ee37d4aa3546c87208ee48f087bb519025b9117c91d75e1ae61aa0676143696414d6747a5fe9b9da0c410f62171b4e31c37239e58c0a33f56706903549 +SHAKE-256: 8fcff21ddc3e69121ae466654467c50e11b0ec3c7b72db7c43d6a494cc6ca571cbfdeb6056bfe2ac8d98772928ab49e67a3c3c122c72084ecc01c8df2e9183ffb61bc57bc3e860ac3fc3f020abe302f3a331cb663b3fb4e4960f7b9c1c9bdda91b72b9ab5212c4dc71676ccb6584c636b7ad1a30e3e1fd12c4b22c07ac464bf81ebfc55f8104da87944009442e5e6acbad5a8747ce98b10b5891531c2c6c858cdc49dd42cf6d5aa2aaf0ed2a7d3e9ce8e414d1cf5bf7462b0cf10fed0dc42ecb8de2367aaf65bddda1583d137cb7a431e1ef10cce07257d6b1aa3ab00bc47e78a17c4580624a6438a1c707fc56944c5d75421898891f857dbfa1c3c26ae65724df288da4ece1046766f90adeabb2ae4a1d31863b852bd1e61bea62c247dec1225f73ad4ccfedc79a9a909b3add048969e07b0df037b5cb631e1f1c7bd316dfb4bd9bf46b25f0adb6aa91dd75f8170e269211f959a7fe1fed4a18ec0ddbcc059539c1c0822d2dfc1add48b5a9991eccbd8586d6d4dd2306bb700e7ec6d37cc17f51d5ab383dd8e8133daf834da687d69aefcd2089083756f40233d26f13517a54a1366d36b3975ff2e9cd916e07614393810dc74399abf75032fc70cc79d22ac194283f78262a79fba5c37aba72c1258467c1aca7ab3bafe340c9d514b15eb06fe8439c9e4a936a398c6bbe92803735c4025a3ceb80d7bc224d82c42008c9d4b1 + +Input: 5d47df1fd0f97013d9a187ba4de0a0fb5a7a +SHA3-256: 44eeb88166a6e0d752d9137fb1f0a784a372ed1f0915681e28917d5470100d26 +SHA3-512: 140fd0a4cff59059c118b9c980427e10af7d447f6613ad09d48379626713e6f07738a4226975b13b850c58c67c3d0bb70634bca18b7a94f63fddd7c4de3e8e42 +SHAKE-128: 14e2b17b6de7d9385e8243b3831ae1cb5279473c3012aae5b93d60ebee2c9cc564ea74d25524ad013942f4f72930f151363d4f50cd7f1af697f610d583523dfaef8efdf24ad86e7bc6d7530e6ee0b91948c7ed46285dd4ddec0fc4e5a288913c563cccbd1cbe8e65a28f7b4bb84831103e055eeab58f56cae49f3039f2199b6e5e668455bf93356c3574279176312744556fc9709c0e40b8cba8074bcdafc4a017d0dc63642b04c50a6660ba15e1d65759d21f1cd6721551d011fac95470e39d1892586b13e211df6a0b2e93d342c4362546ebb826867dcefd84c8f7e1cc8833160a91604b6b676fc838848dee885b1dddf167d2c2ce08d340f60946050de2a2a10e48eac1331de749d3d706c88089a7dc4d6243b2752cd13064d20be6d742b0effccd606d1247809ff8adf9767ab017b609350dfe11be6f4914e56bc55971cf6696225c606d0d8f803bef2b5526b5664b4d1973eb3d88ca65de08cfe90adbaa5f60ef9216a82718c86c6f098c7b96634b479fa90ed20a7baeee929d064c7c5489f4eec8189ebb88239dcf9c44928d75b38f51d4fbbd1dde9eddb26a599ec25719e2648bf86b67645fd345dccb162d3727a3465f9d31d54010c4e8820a4c11a4133561e9217e49c6eb21b227b1b7bb89ec654e1a185326aef75e3630ddcd0b173e95ad6ede8c5076bd2cb8ac2582fcccbd0a4209f8c70b1c1124bc980e3aae93 +SHAKE-256: 9ec46fe1a17dd8b7fc7be6ee1b6666b9e6967140fa342ad4b27c2564b0841f0115b6416f95702f0c18303f2fc5c94ee51a3a2a74a63e7d91616a9a48dc86cc92afd55b7afb66b1237704a0238745a5ce2a49f18b424e4cccc9f90e879d0230acc7d6ebffd6b34e77f041d34625382265b4246e27cc48fd82e3b0644583a9e3498ec1f64fa007ba8b2eaed66a3402eaad5517487e538e76a7da3ae22b1f0d339c220f071d4d345453f03b4514760ae99b3c079146a100f8252aff84b2330066dde7dc4fdcc66cbdfd27352511879696b075deccc0e3be814074546d109ac293b7fcb1cc67ea30fe50d8061aacb6d0e149c589da145bbdaf0f0f68c3844b78a1bc7481aaebd49bff0c3e97ad9c7a8fc7adfe12dcfcdeddd3f47b96b562c4d549fc5e8764db5a28f56afea623fbe4445731caa4f13a6faaff8057791baab9fcf9768e55b7c46bc9669c2fe86da5463c690ea33bd2205de9ad6c045033c4cbe26d7e31e0298c2530a2bc38c3861835346abc0140a708e2dce9a5a5c5ed9bd1c78b37863018cdd2a52a6b765bdfbf17398dc1d92459e361195d13383f2522921c694049f4db70639350709fd0b56e8cfb27d146675dccc891c794b7b29156acb9f3174fbb8efa9ee4ea13331058a46a977d235581ee3e7a8c6037f28211a7f6b9a3deb1d82595887360841856cb90982c63a700adfad8bbc5169f796e8b355e98aa56 + +Input: 189dc113c516af57290ebe6b2b74789d400701 +SHA3-256: fc01db7a65f9b323227da499d956c28cbbc69fa5533d9d1242644f24ea692030 +SHA3-512: ddf459e459e60f8846f20d3b4139f4e599a4d9838c6e8ea10eafb9fa04adf3aa6a82f3a6519a14ed2ad151599f853d385d48c1e586ca4c0a4bbcfe4c2a1fb23b +SHAKE-128: 16d28cdc53b6071b2d63c7a13e52139166e1f49ff582e07ad3707a06e77ecd400258dc833a3c49534df462ef51f705f7c9454fbd4c34beae0a7fcbb504c97a09b030052808800be67569d8a1917ace4bc00735bb0d19f83ad4a19eddeef99e39a7de6c013aa7cd2ade2a900821f2eb0cc06bd0de41a75970c718fca3c5ef0c654c7bc834946595bca3c769390875e7ab1afaf0f0bf83b8fec127e4b142e471d40d72964edf301512effaf0ee068523eaf847edbd77cc32cb786fcfb103b2fd019ea834c7fb55513ea38b962ca8286645f5feac74dfcc39f4adbabbe7df8391fcabb6ed7f31a91bc7191b2c7c9a53c7379385bef027a5afd817b952103efbadf374f8f6a965da5c987d6a279f5e507e468e6edd9fdb1ab4e9b69ecfba47fcc5e9f4550473e7edc8a8afbf89eda6df5bfde259b8348d4ca4ab0e84d38935bf4330b7b2c6ebc63dfd74cfd4ecd58f03f4ed26d413d422807dfdf7aebbd6f61d317e06f35a2141f7bf33abd96d52114a70b0d1f44b25a1efd84590546f5bc7760a63bbe2bf30310d5ae9ea6f5b490469af5da2105c507c4dfafd182c11ed1b0a6c572c27ce0bab7fe1a8d7619a8efe7d8cf0e95732d658a89ad63005a58bfa945a2d32a813e741f73d4d58ccc90c5a54ae39ba6e3cb5baa2dcdf231c5a2e3205b3cdec7aec1c2d661c54c3f335d08e7a8a5fad985fabb88c7793867ca83287368532 +SHAKE-256: 281b0436f2ab52c8073906ac430e0cd1f5f53cf55f0be90a5f20575ab3950e42947c8cec7b4ab802629205c3e1bc3e165135524edca7214efb80e9fcf931d27c0394d405260007513e486c026d124d592c55e2cb7e89cb975819fbab86b1b2f13e96256d3f71eda88631c172b0e5af215a9dc8348b698d136b48c46ce17c6ec693713f38b9716399bce28a60bc5119dc9671386436dd7940d418c60be132377bcd5aa1ca96e12e3b6c49a992a6b8f0a0aede893cd4a41f9ea8ca3c33023946653c3f25e986c91070c6afd56c2ba22b16242a562426eb98cee9ce6659ada5662977ed149db1586d49f7c61c2d723f4ca71aacadfbb7ab190ea322cf5793a2c539248cb2849df97e366b8d919af16be6a9f0ac4d8ac1268dc7886f53d5a09a370d93159259bd33ad8df60aef7043be934660b4123bdfb4314a880b878bdfafffe3b87dd519f99817538d47cc76cfce5864839d8cb4e02f0ff3e6c3bfc84c6cddbf2d97f61da42192487879aeb4d526e2283833313145db0f78654bc3744ceab4dde23b3ddeb556f6e07d0b3bffd8f6af7fceecbac6e8ff928c8cb77cf5980dce3c79d8f7697de1ca2c75e2c3cd2aae37b6358818f26820f8a60c211a2c4824321eaa6e62b4ed350df94086beb76b6e7d8b2fff4a6e0ff5911091153d7759b292ea537d3126599bf411fdc4d42e503f285ea3802cd14ef7dfb12bc7fb52fcbf7286 + +Input: 2b478a1b167d15db075fc7fc02b62f83ed4a8aea +SHA3-256: 88ef8b9cf6f91458c2ae0d9e55e69a97ee29b8308495590b0cfeec709f103b00 +SHA3-512: 771d6d0967b1043982df3d73e33bb7ba8b518f960ef1356c13db41e6a068495740ac94ebb9f025685d30a6ed49a3b2a4a9447a1c7a024efa753cebb726933d13 +SHAKE-128: 8069654eb46da19674a38d14569ea4d513ae27e8787e87317a1293a3f81eb39443388595c7fae7b3a0b7320e37c72154a46e5fa861a312c74fe25a7d9f4efd248096849b97551af785c71fa1bf6c15e72c3042523a956b3700068dcb4e85f6a4d955e0ab3ebc3d2719773a8ea101e36b37a255d754d0547068eb60523a0efb22bb279b3e5dd603a078c8e14534e2fbfe87d1269226d3d3a2e41ac56e08254043ced4708a1a6743389246a00b083862f555903dbb6cbacee01d6758b336089645a4ba10fa99f16157c1e40e36b78f6cb4cf37c6362fc256937e57aa8f29b6b6cc4bc941856cb4993307d76cb81e83393dee7fc7856368fca66697ae7a983bc644a0468b1a5903b95e20d6dc776ec6f105e44b5737b0a39cc6b398e4845af103bb9230e73e6c5df24f3e6e951bd753353d1f2d21388ffc1d47f4a295f78d8458e90f86099185fbff1112c523cd53232f9a7cbd263669bfb0f2d675447b3b3160cda41167f6d8e5be37746c2ca2896304dab7a40a6953a593876efcd4e1f496781d803db8f6e169522d4be125070507fe8a055218290b2cb1412e93834989e5dae53bb112de3882e0619e9c2fb935f1c38b17bb9067888e2c94368c4b490caf9b68334752db8d22114c325b231914f0f1f3a4194480d54801bb491d55709ae6a1d203eb0e86a9856162929aa838bedf1e36b45fb287489a5e06058af92e38a271d8 +SHAKE-256: f911e154504fad5e4c3380645cbae088dd31dd7dee06a362af362c669f69364acc161f63a0cacbbeef35e14b8b3e08ba327e91e46ea29ac8c2e587e18398981eae787d4aed81c58ed55066bd2cae2d73f23bac22525c2506ffd69d12c446f4d4bdc54aa5b77517e746b14a406796cddad60cf1fb38fc7bc1236c3cdeb514a44764d473e597c18ce817379634997dfb66b929b32c93aef84d3221b3f757279d2d07b7400aa6f718adc4c80e15ccacbfc41baf29c0a3fd9012d26ac2c7c402e8108e32dc158598c6ff3572e35071a64b7fc942adcb37c21d48f5cb2911331cf1bfad23c0c552d7a7a4c5e1da44a5d44b0407179fb43144b04752203d9f495a62412756176c8b1a0264894919c3c375a6050912f1f5db124ce85d5e2a1848b64e5b7caa6d5ef6859dc36ce8f566f99d7300177ed0c1857b7c11aaf6422e4e81d96e549616ca116be39eaef20aec3ddddcf7e674f6cdadc92caae566c6e623ca5258b0d7b96c933130f15d4e4bfb4b73bc6ac2845caee190d0958d2960aff26aa692b4fd766d710e453ea5df09802141f3eb8541a230d81b5cd995a34f6d7801f0455e337bcda591a5566fcd10f71a13802ad416e2bcf65eb2b5f4f89131460a77cd95d9b43e3b793bfb249c020c936a182ddcc7b15f1080d54b260551ddd70da63021a6b14aeaad6a5a50d28d464cd89cc316d8360f9632930e72a65d50a6f7e518 + +Input: ea3b01340dcc414761cf572fa65cfc3bbd4f7998b8 +SHA3-256: 912ed6e91a3eed4c16e029a17d6246dcb11937ee435d022717b7a72a28ac25dd +SHA3-512: 769b8cb47b210b263cba11c48e1c0262f258a498d38e4170d9472b4d95dbf9386b243e0b1be4201162782e80be6a9b73d6cd177681a46f987b6a4309b0819520 +SHAKE-128: 1d52e4ff7b1bf5df0f4155dc34cba89e47e48e9d21d03462b21ac34cffba48c5ca1fa42ba58927d19d766adef6508154a00ff5d4064aecc2c54f511f17a4582a46eb9778413181937175f1432dd0fa5c1ddfa58e10161d8dd21b9402ef5f09859d11bbb8d79f710fc873a6ca2f8c92b3bb3ff7fa0d114f23c0f665f37fc1f96b2fc04b5a1b84827b618953186c07f4997db3ebc86024bb0677bf6f720800381550b098ff857affc1e9a68681963ef148786b6874d2122a1dfb82d49f597be27a081a3336f9dff2a27c6372a42bed7be69d576eb97f87f4138aaa863fef2c26a69c06ca3fe9993910b8f72cdf877631febeb78d4f98bf78e3fdc344234b3e58180e20c9cb23c5d99975a1e73842f322e13565f1e88035860540424b7d27dd944330fbc7ee622fa2be53f68613984f4f22d5dbd7c2a23de05ec4842c5a668721bb87332dd9e585ac25eedaeee89c299ea7fcb1eb12bccbb2fd79aa4067fac613a52be2230990a75f97b078944e6552fd5f5a30b4103d81af458a37f59fe256dcb3f08b8772910169f7dc0e6edf5e0408447db862b4c0ee3ddd068a245d8cf45625cbb123edd13eac979d1258476726aaec4e543860ffa70866857a3a8d2aa0c6bed35dd636e146b0f1ca255ee284be3768fdeee4f1e7636aef0765ef23084bf1a940c4acd17b6082e480ed4c6c6f07eafee7b2756ed53793f888aa87a991678e5b +SHAKE-256: ed0ba9c308166bda24f7855508dfe81a2187e2fbb51d4ee003061f90e42e06f4c732476031637d7a7585d33459f65e79284cf8523c31f245b7d7a24dd612e1615ca74e9ecb6a74856e622dc89c98a92207ebd3585341425f355b2b325e5b2889fa2f0ba90ded9c1094064ae01b6390c17381ba915db408a328459a5bac63402d84642b964301affd2b82170fd2e3c27b2a49bb5693dca2af0b82a9c7a37bbd847dec88f6bfce0138c2d2bb07a0addd2bb8f73f7001d84769da86ecc0e3374881f27e1cf5d2315172fc60450defec0d12eec9493073fa089b3bd7e584c463f2cd97ddd8a5490394e8e68063811b45050b2a1aae1b40678e508d9e5af47cab880526a4e587f08a630729a26bf944e7201043da5cf7ba6e7f1a9f677f3e141f8933e81a6a13a163ee45c0158afcaeb39b060b7faba9c01df3c3a19484693a348c706f81c35d263b253531c469ca94d8e1570e06f0c4ff97e33fd116d4c596a0b7110586ee3dd23995c8668622d78d2ff63fce8e1c08179ac43668e622604b555773b6df4bd148b435dcb206f4ccb242c976b6cba242198738cd4d7c36f0a8fa41c723c1866c5293ee86a77e64bc7e4f266344c047fb8d4042c11b359b8df4d9663d34ce4cfa944a8a347c8432b047d3c4ca9a4b7f2e1eeb11f686a8a2220e0833660ab449b38f72f8f2fd647be6e0fa4c87ded6a49c8206a9a2718084fcf246890f + +Input: 03eff8768d8e35efa08606a346916a334ff3cab22724 +SHA3-256: 67a80739c6eb039dc27c633aac8f35400f226137176622dcbd89f355040b9e9a +SHA3-512: e27642f7fc370e8b9d9cac21ef89b9483209ef885228edd00bd51b277432e9e7896fddea4870d7c9faaadfe85d42c7bc08185962f8c4e9edc40c8b7d336d042a +SHAKE-128: 092d5e3d7506ddc42886fade9e8b4f7c27f71259e60329d1950bc0f85f259061d1672303a15465f0df65f8497c8852704214de2a2c31d687e7a0292305e4649b6c1a013a7f29b22fe98d38c2adc513198c44eede75d43db3d69fa181a4e689f38be52263367159a11ae863619d553466010d5ad65466e58fd100fca0cf6f6ad2a07371452a50e262c011302be9d68b21ad5cef188da94491397849f238eeb58850c4ebf9eb0cb6040698e74b544a4bbe527e36f8e00b81e1b3b83834bea349bfd88ab43b93b84d1e98bcc944cfddd6010b753b563c2c298afc54cb863291e969581fd00257321aec56dfd59beba88e1075dbc4f9bc463a437b7acafffb3be06f78dc1991f5857da132fbc9b0c96fd95035b4c7f372c99e68dc7e92cafe3eb6a5ca17bc8c208ba87aafdbb019721ffe3dc2002f52b3b2a2eb1a18dcb57c789dc35f291cea513f792579918a95dcd009d9e454ff5af9ae1304334bd052259e024001deef0fb798fd65132d61a011237a270aba9417cc96d6643ad32ee727ebfef56d5bc664eba3bdf058f9d74d642ff9bc5061f7701eb8372811ca0f1ad836e678bf0af2c62ce3194a3f8e004f28c3c848787b0f0e0a42ae8781a4db5de6f21857d3e3129205b4a7bd609f570a7a0a50afd7f5696f883e1bf5a9e25ffe1858ae81e58ad79be7d90909841cc0f12341d9b24a65056ef39c6415176fe950c7db2662 +SHAKE-256: ea349979a8da595a625568c35024c29b4a3e76b063dcd9af23cd7d3539eb586e0944f51d6a15a196ce9e3279895b316e37e1052cd8b734fc47826eedabd7b5f9402ecef7ee513e9512a229fc2c54321406cd5d178465c35fc59e6d85b01c85262de6e8d38945d8643e3cec9fe7f2c699480939edadfe731132bfde06c88d90cd68c0a69bcbf52fb2a172ca7f0b0e9ab073d547ed6913c21221e12b6a8e81b7d74f6afaee368eeef9aa4ca6401e613c6df82faaccc4661233490a8710cc084c663c7e51821987c8e7c8a482a912f67e66eff1bfbde23e04c55c1658ce15ca873ada17391ae4ada75f82d81ac78f136a63445261f9a79165bcc16393c7799adf4a0c75d66a046d7ce1d042da701ae5be7cd272f77ed01050eab3d349645b9c201082dfd3f5f653a485128a293b78ffa5804f992fb53b8ed899f10a7b5e01d0f83e065ba3ecd6f9784df4658c7929b71385790038e07d2a64b873cda68af11eeaa846e9234408bf21c0f144f8c0f34db703187b9b9222041a6f2303517c6ea24d10670142f3441ea93f62d7f655a4f4219aa8a3fb49df9947238f3fff71a111e53282d9c834e6d9393f9c8656b9b4bc93621639cf544f957b441f6cba327c36e099c2b15383485c29eeec1d7a1c1677da0a5a31a0e4ecd640f34974dfd4f661f137df6d47bb37673bc0e4acebff55bc799625dc78f0da91b1865761c753c2dea002 + +Input: 2046da183873fb9bb52cfd5138d64ee479a6561141997f +SHA3-256: e916ff6591c5e9af44bdf1cdf4fb075d75792061aa4f79cab7a1560ade447403 +SHA3-512: 28863ea7228f9ee25a6db7d89db6183edbd3d6c2bb3a5e54182a73bf32fdaf377c3f844deb2beff3ee7e737f266ebf8d854b26bc0c758d01be7e0e9936931fe8 +SHAKE-128: 792228ec594e3685110bc17dc494b68e17a5b23827465048dfe83f30ad8373f0bd3f8a00fb0cd3b43ebe5008d987d78d1d1c21b43eef6b766619ec219d5e134923e2cd1acf462e5396a94ef9a86a073ac17faa2a72a223be96c387213b4038c6cb460ca8bb421d76e6874068924b09a2243d41e73f6e703560151f43b8451d6d804befedec46b72a41204ff92f1fab2c1dd8780bc24e9e6953b3384d9dbc591974bd4b226d3b4f2af50d6a5e1810c36d32c1126a972352da088007e026c8b7927c59483a61f3ab3ac3ed38068d195b078113b59000eb5204740378c864fa8aea7d6fe65cb944c34f980caae8e619cf707a7c28aefb4c2804e3bb841cfba599754072d1d8b2fdc5d89b1b97a0f753d71b10aec1fdf18701d6f470ed843dd1c0ba8f2152a4305194924bfb610393acc8d65493fb1a6e1db19c52d4dda5ee465968c4e028e0320f09baa683f17ebaa95130aaebdad2a18432435417a7d113888a6ca62474b4117d8e6d52764a3165ff70c6151076c79a65a51ec93211cac08ac32c7f1da4df3f5e41c3f556acc9b8c50158b15b1fe8035cda97b80473fc8cafee21a708fdba4eb67d826cac0d3187379ef8703172f6b511220c07e22f97711e157c12e2cd3feae397512460a4de0c95b275d3fd46ecbcd7ec6fbe1020422ed9d71ba12bea7e2c357cf7c2166d963635259bb8838c20fb4806f2141accb35a6ea36d +SHAKE-256: 986060e94c0c34299bab9217083820267cb1d26e20e6d0276d746d2608817dd179a11831b4e5857e4a99c971dd31c8cc69038645679cc05f96ae34dca1650367aabada4eb3eb046b87ec261dd317f7a2ac9851a7b7e0dfbcbe663c88718ea6248a0be3b6ae7b92c7561dda7d29303a7a10c1e49fb1321e1e812669aecbc390d3f05b2edae96c8a98cbfdaa045c790a8b4223abea50361982549e3e5acf05c8a141183a941ed55d742fe7c45a9d69aec0e7998c2047648ac8ae919e9fcaec18616fd2b1f82cfa9cf885f6e2be405d5f1edbfb688b55a123ab45540a006a3fbf138ffda74bc26c67e98b0b6db2f286a1170fe50bf3f870fa4df1b0f12a18132e503c351a471a4ee8871a685f4ae121a037e6b7a073f0e0bba39cb13cfca9e8823e7245ad0440601139563502c7c787887e09caf2883f40cb9fb316fec50999fc6772f370228a68d91163ef436ca6fa7673653b91c743766cef8ecbea2ebd2d8988f21b6748756bb00c094a08db8eadc30f687a91bb424f11c64d7ca58bb56eb2ba636ce493bd2bab8ab285cb459cd040a77ca0b72546c5da4d466b24abfa62ff3c6b65e0bb2d8174f2038d0145302b190a6cbe7386364dcdf6aa971871c23d4216af369bb26d83a32b6460857d3438d6a169047dabe3edfad7677be1f2b7fd82fecef9d7969c32956dce673281ece315757f0c4e9a5ac81ae9c4bcfcb67c884403 + +Input: 4e7afc0d05e09895c03643e17342c55096c4b0b093cbf41b +SHA3-256: abcbb82310cc801e5882001f11ad9516c726ef67242bd761c3f029605333ca9a +SHA3-512: 2604063998c7e2669bf33bf47ddda0fe697ead4ff9cbe7bcad411569cedaceb2ab1cd09cd63a6deab26c157e6294a9492e96c1d716b79197887121ea6aa1d00a +SHAKE-128: 9e1aa6debe9e3e12f8f89a7ad69be4b679f57eff4dc6691ca18d48cecc535045ba5ea2622633b158eb2dad673274e444f4461125b99435968821052521fe57f3f7af2ec62f252747283b914e3af2e1362342c40c7174205a8805be0203bfe852a74631b51265c9ce1b09c9a40f07422a4e6d3f82e8bb17dc98c793adf54493fc6e40b60d68f90abeda3f388968e3b7eb5e4d8745f806ca9283045581e9b78e5b4d7a1bb25bf38438921c446c2f598e48a5646591eb0b09dba5a51daf779277e25f0ca960c42999e20a5e5993d875580c374440bb1c7f019ef236a602ef68105d5ceefbdda214c062a06d6f646292fca0ea5cf806f0640b8d081f90b236da9689dc3699f8dd9ad065fc87a147aef57ea34b7fa239da51d4df281a85c88a74116512a6b02350f264afc0d978be13e971c028cce3781001a80a8cf6260e2e66d66a5b67c7e6924fe9c3ef43f74376175c8109d28c6ab1ef89d004ac811f88aab67b648dae5cb814aff1c6ca96fc002fb7cb33e483812400cc72fb9d75df1fa60b6856c2ec4457c09244c1ea8d4d5145e32d3a20631961431210d35fe9e57b31e2690cfc440d46cc9018cb8de27da74c7c89043e8ceeb5f05e1ff54138c664e507954fec5413852310435cb64433824a342cbe3d5f5bc7c5ff8a0a19be89d4193c8ae6908184887ed999cbd854c50b2410694999fe10a07bc283019149522cfc83f9 +SHAKE-256: 07e32c3debaf29b22abae2765409770c8f0120cb07314aaacbd6a913d5639bee56ba5731bcfc91ff0d2e9980678b5652d85c04efe93c8ff9437b1a780d7d21e4d26f1ccda2c9d32a40e63bca23d6c51241c515f6b1be1ea0627b64a1b8951109ed409b707e79d7cb7238d324c90ec26f6ac9166a1a839cbcb23212ceb127fe4dbd96aa49814976c22d1cfdf1dffe60d6a621887d6514c3e9fbb17e1c458da20322917caaa3f1af7fcbadea78b9a3f5cc25dc32aa07fd13536f7b7d7c476bc279346ec198bd9023a799472524789b3a98d8b2a12f621d932b158ace68c73e54a877ed15dd7271aac2a825ccfdd90be73290bb2e2e266cf2feaee1968555d2085587e52e2b14b5b012e0dfa5bb580549c350aacc4ce7dac6cf71e32440e168f5ac35c9718117d18218f860865d1c8fc62606887121a0212abb23727dc0a041a6e79bcb2c1f58240b277f58576a84fe7271a16cc4f6655327b5b11fc8f6feba9d8b0cf08a6eada0d5556dea55dea6a89bdab8bc5b9909f70b9631ad7816ea3f3e076d049421b6f120dfd3ca12f0c6ff55396f56e901f59fd259957008cfa73c4a4b2023795776e99a4194ecaa0db47903ad9374b46530d82085b96a5ae683c814238c59a8af958963547190e536e8197e1d71a9e1a2322a5d1cb3ef4ff7db51dc12f91cf05e6ef33864bcdeb3285dc56c017981f85bee0d2fbf7667ab031e6a900c + +Input: 0dc319d9ac96a391c6862369bc918fdfb08f67e2cd8324f099 +SHA3-256: de0c3cef50531a1d20bdae04dd82bc6377073d1e770b5cec9dcc7be62ebfbb9a +SHA3-512: 21b90e766e86341c43c9f2b4541b71e66d9cce2306b4f3e7b0b5780ade02d1a711be77eb6554f0bd358d6767ea0929d619b777011bfc591b0c9e91201180c406 +SHAKE-128: 229b77134727ef1ab4abfcdc0db57928e1780bd493dc1343c738baacd5484f294a98582494f46d770b43018b80ef8e70dc278eb9a4f138e1947d3ffb3040109cd12288f12bb211825c55fba549859f9f17081c132f2cca8ffeeb65c91f8ef75bf283203bf753c113a069f431288c4307ba98aafa86c8ec3962a4a3c14d44a21c7ab7b3327fc684077e498724a8ff033fd3a09bf0d2feb38251c206df21e07eaff050c482827f500cc69e4154feaf93d4bdb5ffe1b77e4d2b4286cac1f382fdcc84f924903f9d973e3f59ac87f56c39ef9e59af6ac3b7c54e827c3637d537ee891ed0887579874f15e0bac1e5e1da6c47b2f5fb36957a0fe91c6bc749f9859a8568a80f5d15f7c4b0229c3362cd86595d26d9bdcaf1ede6a2637398835f33e557f45a396ef2ab7aa80aadae2e241cc769429cb195c389c34f85bd43d7aa055b1d05579e2fcbe848df1d7f084b8ee895953f3f0f703bdbc58110483d12b092a59ab4faffc123baa460b1e985a494cf2c75e72d37afc56a0d28b6e9df09459c2c9036d4ece4b4f0d449f42d5ee3ef3cfff132274c5e860bcf9e25b628cfd34d0074c67cffe2f231bdec8e2a090a0a68c2f44dc29c85d1e47cb20a8e7ce5257d9398780a7733e0e62813d77186a32876a43db85d93e310c714f1e56bb6020a6d208f0602b69f8791aee42e6d7bd986095588e56989c2619f524b62fe669e6f736966 +SHAKE-256: 02b5c47eea0b809686c5b5f1fffc9543736ca0b169cd64e0c5f17eda795f0704dbbcb12ecb66f50f3fcd50fd94a3f79ffbc776dbe4288180e2296ab2b041a201109923e1b441fa60d7ec4c2cf56575ef6b2ba1b16a7d996f02d2abcf3ab416fbe2122b5fc698888d47dc3d33be304997201bf7b7bb497b87e12bf9d3efb04612a0a12de221525c93d6701d602b8ca0209f2f3d77d3926696cec2fb0118fab3216e6746d28ecaafc1b8c8d69124a4db9d2bce0a03dba443e708f443e9a9918c134fb617a0237db59a2b7b1ba86ce573f58c901f2aa549476746fd681f123ff3ebbc564a9caf5728612c52f52dbbc1c9589a93e9161226249973d42befc9849e8c774e72b5466ebbd4cb5f88f89a1c944a73612c959974bfabae7d34ca7d891c5c1386cc617d14e45d05ae8a9aff2856aff537e27272b165ead9c5f2f932266638bdfcb2e44788e64d11e56421fb4528e401c21bafa90562ff7e57ca660f918d3fa61613973c9c58f0b02a0b86a910710a1b10adca16f8e9815840370f84d408f7251de1923630710f92c7752ca4dc60153fc24564bf22c3b4aa51068895e7480a101ab4e6e944bf2e6191fdc28d1d5b8c90a4abdbf6b0165cc4185c1378688367dbf240d18a63204174a276c6921e2eece6d51496c3444560fbe812d8d1df7590bda36942ccac2ff0b8f13c91c7a7decae255981214463188ad9df0aac82272fd + +Input: 8e5a21913069202ddd1db028143c455d22d0a7146ae1f0319bd9 +SHA3-256: 9ab79dd9d96007b8ab1e8193cf55974b04e8fa665d9bdd304b33a70bb7b59127 +SHA3-512: 1a6f6e794f8bc989df9326bceaf9b34770c1c00ccd9879023f60a72662c21fea849c3023db22ebfa4ee4c731d8e5c8ff8e74c976ef94ef5767dbd424107c88b9 +SHAKE-128: 5fedcad6e307439586222b40f49a08ed83115057f0afa1adf3621ace8f5325e06695a4506a49ec97ace3b77a89ff69a3fe116c5dac95d43c150ac594f6ef7503dde32e747beb48149326f5592a708d729740cd74b54e20f730c622319d0910b0d679e274774b1880b117417f0feb11d6584f38f2cabd992170e24cebc955c8eec10f55e79a37706a9957e004a667b272e0f4f80a187cb1c63b279129d7b63ac1aba4db6b3b262e05e42f179f35400a34d11cf6aa5c9ee029e392c00931388d3f6ed7d716baadaafce5e8ff27dc500683407fdf603501e0a4a697cf8d465bcf1a95a639de3461555c4473f33800712e9142221f2f68d77bd871b012161f235ae6d216967d7d0ed30fd0a65fd1276cf953630687fa52d161e43d833a3af71df0bd073c63d3fe480f1934a2116f039fe952404ae3e6d7b6795d24c848e331eef3bc4859b9b899980fd78e8e8e5e239c6221a82cbb8eadb18f3d3a45efb439ede14fdab36c4b67489ad151d2766b1b9d288ebc956735787c1b1db65ad7c697d09db802f5218d2801363bf1a7dd97a7b636359928c0ba7f0aef3df536f81a6669965b0478ee1e3ead37f18c7c740419a6a761c89ea716f647b6d962c7f070ffaad6ae99e5a41d3f7e2157e3049be674b8f7b5b84154ce895735f92fdb5e2603e1e95ea38249745d8f7e0bbaa438804ef46579826c8f49e21511602d0b334bba5aa64b +SHAKE-256: 2e94d95b8a8b0fac681ffd50746b91de654ef8763b7b60111f7822527ae4f9d19fb4c54a3f3982ff62c398a138625dd11b27802e161bcf0c8137cec630ddf5a47f9f4cc4b07a117398fb28f8ff40ce58dc0e1afb8e5d4c97bc452fb432406a0e0f352be770e4b1e6de1422898c9ce39363e22c49c215b7368b39286c5e75d11604d20af5e4e12afb1c24f4faf4f76492793d7e4e72ba916795d686115e8238bc41380c484ad073f753fe21f8575204fa9971e70976cb7bab7f4af9339b1b149873a4630a5aad4706c0315072729f0e25305df21561395b94a5bd4020927864e2931199d2db4f4d161f72910b69d4b598bbee34e26646ca1ad0b23f0e769021fd4f9006e7594f92aa8a7a5649bffbe3763421c3fb923e4e7aa2f845f7b7a97f1589405cb33f062dd198579ffbb52d0977ac152affbd74a35ec8d99c41fd069aeb0c5b9407677381e65d0d4c843edfa1c039e18036007d34ccff5f18e8ef3dbf0705357efdd0b6c8f5d1e245edfbcd2a6adca161d01955fe4845b2bd340f743afcb98af90925ff0968f82b3161904fc54df691227815b7f4a522852d1ac1f0458d0d81e470d8d5d0a0a93754ec6dc4be72890b10cf12e14f5e2fd5a8bbb4259d1fb30b7e32c1f40f5dec1c1cf3082e850d8e965695d6099d23f0086ebcb33be20755ef66422558abd25a3982e444610dd8439cd41bc361a4ed534405935f02ecb2 + +Input: 5fdba563608c12748eeba272d8de349426e52c3be893e4965b3004 +SHA3-256: 54699ad1647da340b66fc3a04c3be7f34e538ea819b57f4987d469f2b90bee84 +SHA3-512: b8fca907b4fb8e724d4dcadd166813522866c6ecad2745ec580bae4cabc6ba272291fec2da3e4df3ce2edfef4463e566c207c644eaea5aada42b3c9eb4e81fc7 +SHAKE-128: bf96272205b208e3967d99a5aece30def712575548df530c14e46aa82f49a7c660947a97dfd13dde44301d72b273546d05c17dc970a2b68b7297def20b93eb3c0aeedf912c0f4cb7bec330ba0c39186ece341eac8846cd870bd872ef04ead4a1a53585569cea3563b3d09bec288516dfd028404f996cb59ae04529c5a69b9de783440ef91e9539391d7fa09d79c0e33815f31ec3f27609a46c783935fa407293906e282452e5b0720a73186f1ed71421558fe8396ac325b80ec28ff5138b9eafbb590e9b5cb0573df2c39d4332e9d151519017d320b96fbca32e7561a8d28e7385d28320d29e85265c8ab1229ea6118a3e47aa8fea9468a4c87761f7157492c373ce3b3e405c536519e3321fa7bcad21e57cb3bef52f7092078a8c84008dbd92274dc17bc5f79d8a12fbbffa968b3ba4489944a94591f005792776ee57d6f28f7248ccd16c92e3fed7810ea3a40aa241579bb59f10ac2d96bdc5abc2af554261b887c6c853d596f3667b4c861d33b0d55e2a462f4c791814d6d3a97a23477f67a274c00e06835980869a29ebe0644fc00dffc4fe43e8f977161fc2a461d071fca2283d071222858685174c3814ce30b8dbbd18e36f15b22895208515ed5f25b443d74d4f1b191787a3277e8cb71096933cdae475a78bfa711a1343db22f1c0ed9ece088daf35f349aa0d65b9f6cbff203a55ad8b5d7f12032bc013f8e73967ed +SHAKE-256: 22da597be4a76adb8a1818a5e916cb10a65f103aeb194569eccfc3297bb82822fab958202559d157f38a2942be666a51eb0f74303b0d8d6bae8949d4cb1bb0d247dc6cd0a2584fe3ee85589678a5bf14414e4980a069f6551062738eb75ac568cd083777262fa563deeab4f75234aa6804ccc888b4373dcc1336b67db3b32a51b283e7b037e5b749e25cf49bb3dfee1f75af76317b0dd60c8ea785e05a2f477739f2a0e082e9374688b6dfaba29c44252e00f93f47f4297c858f220721a00b783f5fa8d4d8de39122825a9a01888c285f54a0dc54e02b50a77b4ee4f54a8472dc1497326d2b43c00c8a4de4574915c2937cbc9bb7957e32a9a0e7c1fe8f03d81a2374580fcd70a3a83c8f28409dfb2a4b749ad221c16cdda00eead1230ac0ab7cdd5311b5f3ba717232b9b62c03dfd1a928263b7f424ad4e8c9d4b8e4921e85814d4cec98a9786f422695067b47860d941312129a97b4dcbfc3dd43d83fc484b4fca6e53b7ec49e7ca5355470bc429e91b035526b97b27bfaf7889d38e09a9618389131e5ed3b41c29e0c67323ca9f912e9f6ceb25cd1b2d42fbdd71d1bcfc7dcf92aa50860960d80602fdf9e458d7112271fe0ae049529a1323f496cc62f6e5168461f33319fb50a4fe3029ba0ee2a619bb5a344050d49e71531d79d5ac10f53f2086881afc7fd496bdfb75a8e5a7a7cfae034ebe8f4a41e3facff03110e5de + +Input: 21005bac451d9afc964972ff66bd4128bff16e906b35457c5238e1b4 +SHA3-256: 39eda830533b9970760737c1ff84dd82bb0a553a45550c1def9381c7b9412e83 +SHA3-512: 444cae26b016422e89345938aeada69effceddc9429d53e8699c6d27e307f0e6718ee54cd8cc01b7d40aba1381883ac22c6a7f85c3fa120f066c1dbfe9fa86f1 +SHAKE-128: 26d6fd4817751f625d03d2a9341d5bb6e965b300f8f4ed665597655f8fc5d592e5821c1bdd4e8e42fa43852cde3592fdb511237a3662d76f78c4ef1878842c17caed8fe72948431a5fcfb535be25a28f21ee97caed6e9a7fe487deca37a40e5c6a1b01cfeb4da864dac364863f3d7b71c287d6b9c7d8ca2e9594c0c8ff755a709b729530db88836cc846adf800358c953438ee4d7e013553e16878813c7b36fdc80c1ec559cd5e5d4bc240f66c4a51dccd1a35fd58ffdde5500b4f02fc41dfc9af65d27bdf43f1aa0a0ed11ee1e14623d4d8d9ba0ed86df33fc8319f897b3e2c313fbce96905979942f2570f1fa48af8d669535af6ec303a328d2e28ec940298b2b40559221f7771627e188abc991b0976f894891da1b5eb1662a75cc27cdecf085bca4482c052d4fe4f189bdd619c12ef0aa2194dd043fe3389e43792a68f5ca87e18edc805a5cb460d1209551c06c9aa5c8a609b5e969a50d66319077aceca29939e839864bb1e07af34bab26ad21e36cf44d51bcf459638fa92a2165a8b8b2a1d9547c0ec459fffee65a50ac221bd94eb32f94923848110c1febaeaf5c9f83e21c6b6db842dab1ff800b28a87af6438c2321119490c18cf1d57d723cf47d429d510ea21cc8488c906570257dade9eda09cde5741f2da86f4ca4f58a112c0f418453d68b5fe1491783f181d8b2d1f997cf28d5261da689bc6a21d4e846b2e0 +SHAKE-256: 74dbedf9c64aed6f22990f8472e1c99e3336a20836b5cb3596ade1943bba158d1427ff107ac8a578fafadde93541e88ff79c50a1bb468a2f31e48b08b1dab3ca9a6d517b7988a5e9d553cd653aabe7da9d0bdddfc925c980705799ca9698d027162547299d256a42f11b63ff41902bf8ae747cd530404ffae8efcef6f92e8f600fb2e56c29966d6063cf9993bcbc877211991c9f0844582901ff8bbc7502e4e2c1718efb31148955b84f86af1bd82efd9a2c1b8bbce6e346552faabdaf727cdbe48362dd04de7f6751a1149d3b14e7c4bfb2825a42703a128a1b330cdfbeba8f249e4c61630cf081049220e8e0e6f6c8ade1057e6469d6ab6a29be0fa8130a026d6bb1be7492fb5c0f55226985fd073b1d0c4975b87ad6fe5b829e285a61dc4a55c9cf9c22a1e452046f6a4e1768a518b1ead08cf2960570bdf5c3d87ec0b3da65a5233cf09d844a3a5b36512a97a65fd8d7f0a9367c5eaad1a34a7b6d82551a44dec51ae04ba9d74071819062e829a983477e0ae2a47ebd2d0113f7e30a63c411df89e06cdf135b050dbf6cd765bd22038121cad24a7c06f5433b749389f91b2c4b98fa80877715f60fc9682b681475eaea2726d9be7880e6af5b38c53af6c4876a4d1beec684663202e2a12ba9d8d1594b745a591cb8c242385de19710d48fd8b1191219b9ab04911f28470b6ac3333b558cb6a10b56ce679b38a952a3116e + +Input: 4864ee08579b78e11ce9c39a5d834e6f1286d541f5aae515c1bec39a7b +SHA3-256: 92983df41874e898ce89437bb4a0a3358e2c6989babf1d1a12d1a9ff8358afc3 +SHA3-512: dd21b44a9e5cd0e25325e1b20739ac953f12da16751d5d9482947a25e9c71a0f772130797f69f531978450d1f766b72732fcd12b22f90e71d07656cd9748a766 +SHAKE-128: 93d2273ddd77c2886466ff91b62e491bd80d2b22d1aabb0b4554c8fc63cdefa3102b84a44ae99e60a3c556632bf6f2c454bf6c69fc696f0076a65ccc252ca0fe14751b9779c44bb46f83dc49fedb7ab51a69f7f58661a942d16235a1fb0576ac6e776df6c57f224b8f91a95e343d84f8deff43c4d7263dd2c44724142604998c65c25cfe666343d75ece79af73c1fdb88d7114abc9a62a4a636b07b69ab8d83894397683801e6fb1b0c06adab13b883c5a6d225a034371bf28622e945bfc64036375dab8597cf5d7566a64a367e9e7362acf5324864ad1ca930492d1df862bf9434a14c977815ad8e658f3cb7d06c0f0faecd2ab01727edfd6fdaab6ef3bec620a768e33f74663e96f1aa420c8bbb47e0bad3626dee4264bc18cf83e31ca683ed4ba112414f5e4c4b4d2dec8b48a47e4eb1094313b53b0cc03406003fd04a6104160dd07334a98f60f1872775447627c12fa194783c25c9353bc49c9b5d6a872368d829d461e75aaef59e408f4817116d042aba1bfb035e75018e29264134d2e09b3e0f0be00f12228bb01642fbe607762af0126810e764beb97fe4b7915899251602feebf76f5e9df24ba9b0a5465a8b94dc788629655a5b38c7275548f61b2a0add819cf3c11ea1112d5b2b5668e375b04efc7d733c1022c42f16c863b4c9a6f6bec119f7bcf30963d5b3a1ea8a936cf5230bf1bffb75fb93753dac8d4387b +SHAKE-256: e9e35283c8e01f2b4719247ee1559de3d79a7c9aa806239f8ef9f306e225704901152a23c5d5636d4492e4a0597f716efa2347ec678a08346597c910381741f7e1ee1d31814948636175126379f2efe0d3afb3dd897df0d0de32a0d9bd13f31b86220c8c57a3ee5dd7e1d741899a57c5485bd7a3785e9fb44eedaadf5bd61adada805fa348bffc487cc188194fd08d00517db609c5c20fd43007b65ae8a2bbb91342e6c53f7db2457b01859173884ac30aee4e4145ffc7ad48f3bca8e448ed8947c66d863df1e46f554fabdbf22b59167579dc20ca7daedaff8409c7c1b157a7523c9de8be4b0367475f26ba4018bb8554c28afd9e7aae901d23188993d0f76706e9470eaddfc039169f0e52941fe1c9764709c80a887374f9db19f00844e7deb8035a47ce0cd3d6b6fe0b3fc27d9e15d9ae64299114a3f18eb5605e88fff7450f17400f29968a640d8da4c9c63e3e6aed7453a28f574553d86a28a12d65ab3292adc48812a8b4312b996b0af7ee055ab002618b8ce33142828181fa69205e12f35f7c3276d0cbd4398729700b6a141f6575c51453b09ec13abec4b141bf7b1df9261bafcb9cd319e9bba899445a5d82f09e3f1f5fd41497537d534c3bcd7684c5488af7e29fb1d5db3db12a7298bbe0396e6c255309d0feda66728fb5d241c344fe2d73b61ac68b0a74fa983c9a31a1504e5627bce52dcd2cf4cd7d13c89a58 + +Input: 01aa4958d39bb9d00ab7800a81f99baa348181548e338b3e9a9b4d20cf07 +SHA3-256: 4df05bc94300199c4327e5e70c8eac44125bbf43175255c5434bce6553b42d89 +SHA3-512: fd459d25d4a5fb1bbb803413c88b3f4973f4ddb63e6806a73f9c5d52b3a64a2cee3c1b528a79b4ce1627d82cc81cd0a7876413779f74209612e1430bf7aa3483 +SHAKE-128: 582b756f5e1c3b499fc795897ccc392f110645fec4a2f1c5b462d5c91358321c97002f50091c08c0000901bf39768137eebdce84ffae5e4c4af56c93603e86fbfd2320f050520d0ed1b06a5c6fc6896eb22e10875804b428353291f4236c3924effbc5b77fb2cc96e55cb58546655ed658adbbf72527b726beab53ba6556c70c76d32d213ee58471c11414893115cbe9b21d9ce8b8f7d435df760b2b0c156bbfa9dde991fbab57cd842366661d17a77d2136058de9ab4ac8a6a6a769501c4cfb923f59eee7c97202009267b59407e7fb004b1bfcce1eb44bb5366d1fc44015ed5e889ffe4623383046025901ee8628b32dcd59efe4147e06c2d7b4209287f6acf09ec7bc18cb8e8793f28ac40baad522c27d14e4b2fe7fed22dc8ee6646beab751e1403490cd43fedd2e630e9b302b6db46311e29cb0e5acf4ff92bd7436ef79e0c84e5ec1b7932851c1096f307fe005c7766c6dc0928c0b106bff6526c76a05425925d4046b7bb747b107acde81dfd8a9b1963d8010cea4dcca888cbd68de54d557c3d64a46725e69613f85e3c8a0f140cf4f56e1da6253b3c08c89de8202a5aca73306823b067407b2a9d42108aece95352786a5ba5d26394a79e19f2647e060b10306db24f0d29c518a58d2ae102766ed36b798a6b8e2ec20bb839c0bbbad9e9f5f6c86148dcd25a8f15b1b486967de06aa1725401b22b9d3902b32c8e643 +SHAKE-256: 33f6559bc75f2891dc44530bcd793ae36852602c507a6d9df7db36be56d1b45fe15e6af912a4aa9cfa3a661fb5e52a75d571bbba2f7038fc499a55a84bc53aae96997431a7ee62256b811347dc8b5540fbed64e8c3ae93f761d80a73ffffdaa03e7ac1dce88b1cac4f3754bee0cf23b4f1b7477da3aea813a6c22ba9413cc0a4686209e451c28e71ff29ec5f796802c13b4fe78c64d0fc85b9784c92e331503d582671dcf3efd2704df2fc9e08f4c36b68bb3b1137d6cba9d67296547c9d7722d6e92beb83f651011731d785ac41f4845883360bb7e96542b138a21b109d66f59bcb959d7f3d41e59dc468149a2f9208fcb8d34066675e7f13e3363f9e60770ba1df6eaf2e3bbc812a4300f3bdce8c7c5cbd6720642974e39a3ca1a6c4d1390d6c37e6a31d90ed6ffd6e6b77de2a8bdc7df9373fe54e7ad79e82fcf5296d3eb3d1ea640c9246b3d177150f1c79e44f8c842b98713329fcd512cac1180765b3a75b30199c7edfb079f90ad180b303e996ccc138d4307a023cb04d8e69b653298cc310e09503c60929aa319334775d7e34f0f96c34dcf05bbafc123d71c389ed0c5984524822836a6cdad4145e2a52a795a6926a13fdadd2047e803bdeab92c0b017bfc10b290b4c22dfc638f9e120be274678032ebde6f010145dc6b37dfd8ce33755c90ed0c4224422e3ad8f06878d10a29a6a8a8e975cf2f81f5e3d31241ccd + +Input: 30066460fe3e141746cc61e728fa0f72b103d10b690044ce4bd3ad4f9d5572 +SHA3-256: f29cb96f81ff684d9a964f4396754c8a137e36eea5850c9b9faa346746d7d8d7 +SHA3-512: 552d35d6bbab94d0f1149e920b2c4e664a7265843386a8ecfb16a1ef1859967cdd4869435f6a42a992c1a32f5a5533ec9e4881263cd3f997f28eb639c27c281e +SHAKE-128: d66ca38196b2d09b784008adf9423e63b64146564a62832e06cddfc13a28b2dea2f6db634c4d0d1fe6fb3924dd588e7ee3af85d71177af7a20a90cf5a80c075307cfc10cbd17c6e1cae5658d351540e2f722a14214896874c85a341297bea8e2e86dd5c94d197efe751b01a6a33316c294cd0b7e947c269f706ec6438610a1333b927f76dc9b01a8e88e7027235287446ba4bd7e952c0803993a2588e8002b678b6b547b50cc92d8d7e50a9d13e9c9537bfd85755216fa33c2b769dab7795fe10222f64afa6ab4696957871cf14fc397194dd199332dd17acd1987db6c1f22778fcf3e569e7e02e4c6a72bc1a7804287947092201cc0df05812e0d89608055082c77edcfeaacef63ce2a09021639e2b1abbedb7d0e2982731b45053dba70d736f597327402cacac3bcb18575901d322a78f49b75c3941655858c26ed526ffca575e4006a98b426f54f96d5d49ce77c092dc93f35be2f0be1d22fa7cc5e0dad08ae4c8bc1f52a74bffc7037269a42f3ca0ed67b6a631ba90caa8583520bffd675a3b7dbfb6d90423ec9a2281ca9f46019882a34b1ae0fb3fe926ac4af17d014d7e54d19150d1fc4fca5eeadd57d36f82aad50943151380d309b7f0bb0c7b73d2ff5ae09174c037fdbb2478aeed678724f6d105d9e95ba8b6e625300a415ac124d834583c427b2e847417053bb60fd0ea99c5ed7cd12cd2aab55268d1e4c30e070 +SHAKE-256: bae5f0d6fd4e3f9f243bfb799745e80f58b75205d049cbe40d13664979b8a2b343ae8dc78ebb10e77c9c133d6ba1989dcf08973621789f110750585dec6cbbd8c3051b949a323786c05b3be8e6fb8f6cd836335460cc88962d04e4e6a271b67e3dec0da0dd54865426ae32ae4104d05a37d35ab08fc047a032403c790c146668aa4f46a00974e06ae9205df10e26f73e9d903c96ebc657c1baa62f52587e201b1247f152b1ac34ccdfd5977ab0e69760ec34bc6590eb8381d721b7a78ad059edbe1ebada3735a70c6e4acbaec11892f998083ba17b273d457d8bc1210f25a0add04df61780336990ad3ab3ace0dadb0a87a7cb3b16cdb1b7868b0a2cab833cc23c315fd42174e722e9d38ccc3db54c71cc65ef3faeaeab082cd33a7d9e9a9e8faef3ee6140bb672051af9209851629c3f3b2f351cd688c95538fd1e5cca8f86c23f0c3dab34c95fc2a510fde43744bd075c38b75237c9fb51bf3260d2182583773f4d2a51e27d58ecc7dddce01ecfd9c891c729c4220926c8acca749a73daa7a5bdb7fe137a9e91b2c55de1d9527aa3cf8587335c61c2a6871a62c22008a6831d4eba4e6ed3f6d5529530b8633d8c7888d28bb4f64f11fc1decaf9cc02a9b1795917d89aa9d7a7406efb12be2988614174d66e6a840c96e881808703b6d2194e685bc3358992ef7a14962c6ce9080c2843a99cd47bf15efdfa2aa6c3d13a253c + +Input: 3baaef4694b244d3e6bdfd5c37fc8b3905369c60fb0f930bc11c9ea374b1b5a4 +SHA3-256: 8155e0ca922f5d5a64dc70cd951b8e665327ee9c12b7ec433ca830ac8bba58ef +SHA3-512: 407ccf40e6da04d40e4afa36913bc5e2727367a31bec25ea9cc0bac3bd2423ed139abb882d69f070f8b78f3cbfb1f4335b480ad802a1197b62332f701067b30a +SHAKE-128: b66be8559de5345f79350f813b737da008a76c9028aa030bc285e4cbbe2691a098f0261113038fa567a5ad38a6c234fdf00dee6903a292b3e8ad95cade62768985a3655423b44020c51a31505b76afd509aa51a2b7c55c729e9baf1cd2a9f1a0763def0ad46b3e4a733f36040d1b80158cdc77ea2441659373ebeb900466dcc2bbc8404cca499c899f1cdfe81b6969e4c0ee4555f5009293f3a65cc37f98faa69171445e625947e60363115e4f3857f0c1a5bf39a4ebf61278cff04acf03242688dfa889a35a66afb4383dc36b5a52172d57104e7d5f51ad5d46be84501be7abad3302ccb0796fae9421967097d40b71a3a24a7b1b03569460fceea4904f25ed7801c0b1eac292806902b887beea84546c86998743b3c8c124bb6cc249b1a6dc516cb802e358cdd51a106abeffe3b34fddb8962caafd759792a7c9abe8658994e9e8ac8ca1287fe1b9b12d8f49f7ea03ed4d1fb2c2dca62016e4ba5caac452a93a51b9874e0f9c9a94ba80d10d34045051a98e3b0b56dd383b10e91a95f1d0673cb3a78807ae7beeed3fcb45fb4d3ce96d0ab0ec84a0b9c7a9b1247d4ecd9eef08a009f6f54ac7148a31dd93a1852c5b1e54286e4fffc6010681d95ce58afda9c7391887f002f5ce5f1eb64f093a28841f6ecc5463f35a9cd2dd7e5f61391864484b6fa2d62c6eed8b9641370e944e646720c1789937fda2f87b4c03c729152c +SHAKE-256: c38ee443ab657a90f927827f8eb0a53cdf2be2e20b490af6babbec8335e1b24f5b973804fb3bb777666f56a4588acda942e1c7846b006334c46dba7b6ca2fbe234e0efd1a74d80030e1c1cb84a6c351951273925a4122671ff0afb0be51f9f615ddf5d090b8e6a99c9b37b8223e40864412983b91f96253a6d651be3beda5edb1f0053c8044b2bd71514d9be24322f84436db047437a72124b2afaca7ba284f2c9401c485bbf1408e6b98e5a1f4fd42e967d825b529d445381fcf657e82d1b05ff765280b04856c91c53776f6c83fb88134f6fbc61bec41d6d56158b804b59ff9ca2151dd184182facbe0e43d24d17a6977ac632f5557b5653a0e7e2ae7a5025b1d9f70d1b01bcae9092cfda1614d0d8ddb088d1d572bf5edec8b10522e499ec3a49699738078d640656147f1331caf7a263cf4086931ac8248cc715c6d602027acbc9977332d038f26c733c5cc6c07c6af9cd200105e3561cf69d4c4d4247f3638462780e999da919d9cbe4c3f45abfd57809e9336a884f079e7f8ec38b3707f78b5eb1f4122482637fd976933d6a0f92e82ee2a35d02b17498cfa5b090877f0badc39de4e858bb3cf1eb32a5815aac1459fdea1dddf43fc70bd0ce1cdb0697416f2ee3c506420979c1180d13305d1f1ac98c919f8bef5165149a7a4eb9ea2a149d923e8500cc52f4a50a74dbd671438e0e864ea812132d3e7040d057ff5937 + +Input: 2f9e99ce29d4597fa0fdbdf7c383e790f60088c2f660c97ae5fdd8475f98b79e5a +SHA3-256: d48b8d6763781da35eca0740540f7bc7abd1acc169e5849de8869d330df91b13 +SHA3-512: 6c39b8b25e9f82f36e3123244ebca307be7c0f8ded8cdefee1e91408aa19b55b2d31fdee033dfc685865cf25f4330ceb836f9f7ffc48d68d3899b63a71b35b2f +SHAKE-128: 861b9d463405dc3a76d2295d94858d5a59cc36f9b636a7b6572a4302f002d13ea6b6d4ae91dfc04fee9bb27d14f1ec3e444ae5b6a41eba1a12f61e6c4f97f7e773c314cc882f74d72548b4091cc622ea1ef677937c87801b6ad7dc07fd422b35f2cf0efc12e75dd0c291e74049a6d0bee35091dc8fbbd1858cd5aa71eb171d1f7a7b6b8e660aa467452d1da4e250c4b0b1f23b4ea12eefb2bc4960d9826e61be7194a49314c5eb426e83023d212555226503d6fe371d0a3c718d713ec6ef599ba749423285dc69a7c01b9883b435723ce9bb1d22c0059bb507fe3a1630513c33000c99fe917e653247a1e4329ddf05266e8be858ca128721425aab6555dc840f6b29b9e5886247a66645af06739fa737d404ba7fd41807f360de125cd496efbeb087d40acf52d65ee745fd231afc2f79f0557293e960a1d97b1a0b138343c7dc9abc6bf6c2873775585ace3192c025f96caa9bb1531672d1562e30be3276d0491321d82ac1c5590e5bf114d5c6dc92722690c3490093a210d0e7dfeadf8a41617632a3e728064c7b22785fc0483ba4bb20c633ec964d5b9267bec51ca70fcea65b7b25bbf58579a833413e993b7ba466d9bd04ee3a411cde85b1801d96f37a0c9aa900a35630a266d8a1c604949f98ebe57ebce69d65288323ed684bb1885255dc04c5ce2b77dad448a3e1183fc6595d85b1714570a2ffe9f98ca320e7308eb5 +SHAKE-256: 23158da1cc6b70244350f7ec3c3a3605eefad2cf85b7b8d7f47b8ae4317ccc0acbb82c7a66a9be86ec1d720b5183b031d015788d64cba5602f18f309e1462ee5548e4f7936913f7e5aae21df9b7a11bd96d3b54526b17790f417790363d896f3ea6eecd264189ec6d5bd562ce90e51948c0ab4fcc9663fd22326707fa1c5799a96b8cacba9c6d65441428936bf523b29c2bea01eb93fc65f236eb310d3ce6073934beedd6a7bd065b193a21eeb5f206ff77d42da520f2470bd9699d5195de1f6f2e863f3274fe9bb5b21dc4be8af79d55d9854f45f51b91199bef28921f4555e81e672dc9023f2662852b8f9e0042890b7e6160354ea756f02269a286ba7c3935c18ad79c7711063a9bc91a046e496cb0383c26fda249853c3e995dee89947838aca4d1f65238b7675ff4db7b318db107eb09da4add22931600ad3a036ffde18077cfdeb3498e5e2ca614729267276b879a1b593dab8016b725dc0f708b83b4c96de0fd43da8384f53defa3b27fa551bad7e8feb5815ab00f8ddae7979b0a9d83b0d48324fc2769fd073f551325fdf4aa82faf72db484b7e1f38c7880e73572a6272b0a35b18b14be0ea756ccfb5e03a014ac54513596d0fe5377ebf033ae8a9e1f92afd228f6f7969922917390b72b6ab58559790b5293f9eaab58445bbf2a1099467ff2e7815eb8fc615ec7d2eed0634f6a418e9f413f3aff8856f5a915bf4 + +Input: 44d71697eeaf1e246b7f6913ba918dc13a1d47badc8a34c2cd3b979cb5d02e20b6bb +SHA3-256: d6b804de67c52bee73936e37eefbb986e89da3a2b4ce740cbf2621e137feb5b9 +SHA3-512: 8e6acec231e23eb621fdd6df9300c625f4e4bc781761b03073c88c38a874db3c825976bd095b5d7d533afe2f4666f47a3254f933bfc7947d81d9c512300e86a2 +SHAKE-128: 7dd23d0115e6e0ba813f6b573a37158b9fefa6c7c27a80ee6e1d1af376aa0745c1a5856f6ff7f363b9223976c72e14868197e15d1e1618e0f700c47448686ce61a06546d761e25b484ab2f8c848eccc40ed7fe6b04dd2ec3194806235ec46195f46af35279a3c965f32f23a450dc2e6c5f903cbd7fa72b92030fb30a78cef123b4d0a3f0b0c7f1fe4de29ed6e3b49772ac8626bf4f29404ba0b62d3127c6b610a20beb34eaceb1254a3cca64cfbf27183b95113461cf9134e75d2569c714625e4781e4cba0556036a2b7497cf9a465cb0b730a05e98bc32bb49598973e24a6c74a5152d7ea7038f37ffad3c3e852c79929f9db478306a85c1c85547595502f272e494f0a789539c0301b55fc1f6a0e97c42ef1f3fc384e884a98f9e658bb512f31c20186436c1759b184bb16d1557b65e80dfa61c21a625ee27b78890a228ed4515a6473b58e22fe5c519c873c6c2715f3cc907b0a720d6cc5359ae210b001781cbe82b0ee7479162b1801950551b07f249efc260860a2040685899477408d4855e338e4f73f5add727aa87949e093ee1709fadc4afd689bb4f88e20947f3afa3792ef7dce1711e20ff8c55ddea9e058bed8a409e6c314e730691488a4f91427ecfa33b1e6392cc9e73339eaa39a6aa62ff406c58198de5a384241890a1f6fa8c90506677cb4fba1b00d6c8a582bafa231d235ff197817cc45421517e42be30f +SHAKE-256: 319eda251365f2e12d14640d2d2c9256d0e7d58bf602a1653094b4f3136aec84f1fdfb41bd2630e1541dc19fd9b37a6a4b5bd18d9601e9368d931f5226f3e300cf18dc1e188ce455c02db8e225897e22a64b488bc18f046f1de59cda01552917700bd8d93b006a143095f4ab989339841fe8ff4459f7e23271ad5786e8a55db61aae6859c5e688888f7ee43eb3e535a130abc01551656dd86b67fa7fc77223e885c42aaad774de7f6cd112ea51f0ab77261fe56f3adf9a9df3b83529a63170dc0b555190f4a2c82bdc09347e65d3d65fba9069ca2e4485d675b3c3292f36bb9ce51848926f06059499de9835665a1d88dd873cdd3cf849d11d6e1c22ea87f49dfeef7decdbc109115ac5558249275cd9f78177eed24a457d4ada0a557abe9668bfe2f47cd23ce6888233dd4f29a0d3411a7a0ced427e25087486d5f9a1bf4b0530f31dc0487b8c44dbfb553e816908ff53064dd4fda8c59d8ce9e0f8e151b0b19fb854d49be7162356cfa9e81f757caa25c3d321b56b1ba0b586c2b29c33b5195fe3a09a86b9ae194316098ef13f8522931a7632726714c7ae1f2e9f9be57e98c4c4d01333a2d56cc151074f99edc3a41c0d77ffdbf64b78e8ad35b3464a66c4afcdf27557466d62e3a423a215ceedd114600b37618f0505d70a6c506a10d5f301eaa2bf3ce57c2c040a3530e9e35921d7c46014b6411409c57aa240944ccdc3 + +Input: c694bce845d9dd6ce314023a26c498e6dfa62810cdd2f5dd41c1dba73a4731a4bb2cbb +SHA3-256: 6c3a66520463ea3b50be0aca73c044e6d67cb4920357b5e923e421f07e0618c1 +SHA3-512: dc32c5b3f7203a7245233df3de4ddfc965fae48ea97ceb33e0f9c8c76eff0295d02c557420f87c1b6cb4f2c9a15d4583149ac50ffc20fee06a27bddc3bf0a0b2 +SHAKE-128: 2a415cc91562c63cd6df030a8dbeab504ce8d1806d0b2267c48a7856c02142d19b3251896221b5c75eb586560b9adce338a5eb57035b00b68df03456ab12a97e5a151deb6c34e66ca37a327275c7f45f9fbe4d16790a316c28580dc4c867c06bb54cfb1bb49c0d8906dc3509c9a223588392e0f7416e162feae74207259deb1c09149bd64b35b09f27246af11bce03eb5be9b64f4d847690d78eedb89d511f6f854c2700bf41d9a95426b9789de7d09e9e50e3720b5934cea9fddf59eaeaaaee245504b721b5401dd59b349c54166c7e5e27875b3acf38fd4f752133aba03570bec9645af628f831f30c113f4000570d47bc43f99457ae6eb550fdb36f2fdcafa223c0202c7ce0f81e696b08770a70ea298c087637255ba9cf60c740c51b92ea8bb8e1faa7624977c65baf9975b8927f60d7f756a2efbc274d5f3e8200e54275da395a8500b874247975f0e7c0c8704395488b4eaa996e3d6563c0925600190b9a64d9b2f9a35fc7a8fb38c494435a792ed932c14d2a9ef4c4ba7681aa154c4568550796629d4974baa3b435cd2dff407adc1f384a557f093eba4d0eb854d52388f84dbc97658b43c1368ea0ff6bb1c2a228519429e7b0a6c2bbb7c56b61a110a0569a7e453263c6e88589996959504d032f512e711221437b7dd935bcd03550d88fda2b2ea4e138141a21027a95a09da7b8e1b1e62159cd260f38a783eb3d59 +SHAKE-256: de82b0282a47cbe163c7adec398eec7325f8df8a749591d09914a45030c636a5524ead02de020ad9af8f9bb596212fcdd6b0b6e8755bcb611bf388e7ebd4fbf7cf020fbb8d169d369b904f325e09707d6aefbf9a2434b75c7db54522307dca61b9c18ed1ea801d8d6b1f4b64f633c36c0cc2fa503c9413b662eca9a0707df65de85f32ff33c12823facd80f46f4f6b7001323ba8ca7867d09b014867b9057d600e45b01922df86a1956e284d3e40d7d863dbdeffbbfa03bc961c2b8fbd870a6d60b23463753457e1fb9977527b4628b4c6956fde108f9380646bd2b23bb5ae35c64e2190582fbd9d4435595ad785e5480f23507e54b8a33adce9b0537ca7097d30651f1be1b15ca38dd8ee010fde51849526ce9c6a7a74e02c1620ce6f86242c923848e678152f45cb1b8e43f04ed691106a4dbcb653e99914c8ddcbcc78520b807d2ca316937a29db01ca34dbf2314e342f065e7b850bdd5cdb73a2215133077a1181f9fda5a7ddc388b3b76b3a7d7619cf043b19c47a59d8c75750d057cec65cfe9e5c3a3a7dd03167dc7f3f2cf37d438346e5fe7143e4487993fe374abdce9975aac23fdd42d1b96df7ba694cc936dd56db58f507923d80524bcbc89c064ad96e42ba74523366f753e34c807e8ac5af1722e5fdeccbba2841582482aaa19160cf52b867b88c7c61f2e0a126bee207ed29fc923ed29285e78141cea198398d + +Input: 0d772d9bfbaead0d163a6cc4ed5b2783db5bcb4aa63d3b95094ed40b780bccc05e2e7d0c +SHA3-256: 438ae74a49f4ef828a99c98629541652aa8c03819cbe1a27a6b9f7eeb462c3f0 +SHA3-512: c99403eb127b0eb40abfb241121f8e6ca17e0841ccf9af66ae3155f22a29a881646e7ca98c3c726ac34485eaee5a31d55faa7cf3348a75c1de20108115fb3517 +SHAKE-128: c44cb03a62e32b2bc704876fba5dae7dc61dd4ec95794599933f5d1a36d482554abb3fd5abc1dc460e48d184befbbb1bc2ba027c73da2ea65fdb4d82a4aa4957527d0d97c149ab9eb50a8a5fec7b8c18b11cded0b0839b67d92f1b13377337803250181977fbf851cb7bf899b8086c26522788b72912ae5f8820b23e801a57a84d4ce5dfaeb3db4159e68b1c7517093491e440caf020ff13c07123893d8399606d41f59c939068dbd2ea94c83359a9761dadc5a1889dabd04ff711eb013e6ce4bf0936531e7bbd620c4f3dc341b461dc5fb7faf00155d5ff3685043f40865ca7b8fb7a11a5dd21b40f41a27b33396b006efa2c1d667211777b9b83e078f705f48e4201c86c29bcc8e1d7b563f08339c179928478827598b3d8708832a388ff01c0daa4d777ddb8e9815ebb3e72892f32d099490f9083cb9c5b257bd520a9a2a76e038aa6110e0c90361047de26d4eeaba2cf67b62916561a06de9ccf5756e86e3fcd43cbf2986c87c42b3fc7989e28db739785783494d9937888cbaaa8da22c0d473c0475b02afe996aa23e65f7e664e60969761a7e76cc09da7a516ae3d6f01429b3f063d254d62f8980aebe22a5788f307876226557c58c4bcc264afcf71fb3d775718361d7caedcfa6eb1438f9bbb5422a14074a140e66127a30657a34ebc3b4857530a4f24b53168c7e4aaf9ea0c4e3cdf7134b0c77a6242d9617c71703d +SHAKE-256: 36f48807470d7526051c6ddc3d7da7a827e68070e8e7853e7d77fee8a13aba817160de027102f8134de1d4d233923531a2aa7ffcb7701ed401e6ad514f4eaa0a956a6e2ab14f1c61bccc3fe2f2450823b08a25052eea26b589fbd2f052be6d7b5578ae9a773cf11f9d00847d982556a221692d89a5d6e8cd2cc98b64f5b65bda634a418d4c29c0a2dc8dec2d61280f3638562aa46dbc8f5d1bb140693042a575430e49ebab59d6816c085b3567a6e4d03014cfb30e6e2abe855a2a73a28140eb4656078eedf99471d19f96afcde898adb54141685acd81f067ea1bd50bf1ecdda3ad0ad3674f3305ea7a57e55b915c0d3db83a352563b7c381bb88aaf176ea1385d3ffc3686f0465c803c90da2e5477fa9996e042c1eb5ccf4846f380f039813f1aea19bf058f47a3a734d241e6e89adf2b8152dfbd958cbdd0c205199a0165a709d7a58daba7ab09b7e4b10203232d23ce18eb47b074374d22496eacd7222a7cdee85ae3fc8f3f9b216608e1e251f1dd4465926058764d65ced460599eff184d66a2bf7abffd49a720eb4ac6e6be62052e34b2388e458d26359189c35a4aafef2b0b48a17e108e696b4881d802e75aad91b5c0bc58797a2a9f14210d08eba3b5177e43dabfac5cadeecbd48a29b3945a94d923045dba482c9135dd2bc3275c25784988cb05fd119ddf823b34eff3d905f9a5e32e01e72e697a43460c011e494 + +Input: 03299b44e194c177ac85764d575c6816edaa8075d3341218cd9c1cd0dbafe447427201ba2e +SHA3-256: fd95d2e2b8d9696855bc4eb17c7f0c59a5db26670c9d729b2c31dacdf083862c +SHA3-512: 3bf5f5f85d09c632be494b0e7efb408127668e25d30f2ec1a3d82c4efcd50e5f5cc4791514dac73d97607d334a26a995cd06f4cf13f50c1c981a1a1f6f85b280 +SHAKE-128: 84ed5bd3059dfba0a2fa56f8db08695c241bfbbc76482f3f52200a4c44358e050486e3717b2e74a856ca8b83e9aca12d1d456aebf519a50e858639a1dbd74cdfad7cad2a60cd0db3c3cb2ef5e94942f336436d76a15e26ee44e47ebc28fe059f58e89ce6ea2741be2e362a5869d8f3cf93918b88906f58d4a65a4381d92706f35654c5d4aa5b1dd7a1a977c089d1488c236232fb6e77ad5fb131cfa4b9240304816311460fe88175f71c2d575396ea052b84059855dcf4b14c9c1bcd6ec12f9360e8775d8a1c49efdb097f9ea369711bd82752dbe9b35c7fcfd8133255180f4f99ee30421b174ec5aeb9f1393d44b848ebb101dd5186218bf6528d00ad43e1ed892cfc3b6c66beccaff0b8d09c06b17eb4bd3f3826a04acf355b325fedff15696ead77c3da4084e99a9fd27626afe8f68ff9abded28139cc67715422fc5760e9092a417a96f3374939540cd80d5f19316b7db7dde09915051ab056678f78c9bb5df4ef232efd5824f7b15f52095a4b6919a5537ed3a992e522af5a8f2ff7ec875ad0b33dba05e934c08fba74d06ee3a90150a4b361e6540ce7d76d0fbd038e16edd949ab68b43ce0316991ff659bfe87709ef1ff059b68d2fad9c8cd24639ee6bd77f178ef4adf74210ccfc883e4054fe7350041cd7db5c4395b3a7f31a57b02b128f68ec15df29a923ed90ab6b012c46f286db69f6e2e1674599873d8f235a7 +SHAKE-256: dccb6f5534478981acd1fe0275445abfb9f7fb9d738e05ef51a9d9dd6b84d4711d2b3ecda1824f63272abf1a4c75a806f60f0a31a0980a35835c42cd3037b0028899788179c234a98609f70ee008959dbb817806a190cc51cd31b6a73b45778526917a9373c3d69756de76dd8c78fd0c7be16ec2690aaeb1bea1708273ba2add62c3df45b7fde538edb582729fc3fcef58904d838cccb3bf542b27cfc3bbd201a040ee0dd548caabe2fd0d10877635b44f33c49f1ec58e876e0e752f68efb9912161a0188704286291d74c29235f06c8b24a1fc7dacc6797ce802a851a0b51143e77dd60679efacfe2f6493a1d5228fddf58b94c228d9b417cdd40e8dca8881f5fcd88f8653d259325c77260ff8848a216c8a6e1fb56d37271458ebc22ca8645c6a8ed38e14f1a7b02b167db8db2a803964fd9b93475dc1e86487b0e0a29b3f586c53baa5fee027a96ae02a50a6bbdb7e808b6973a32165e5f408901b84d2c3fa6da7aafe5fb7c853e7c39ed6c407c49ac3b8ad6ce5d6656f973575f44374db477225de8698ee514c312a749b5335332751828b275738f954cee6810f12e1fae4b8debd41760931edee29c306f0471a43beb178a08133a674bffd68fbbd1957e65ba65c585776a4bca044f61a1a3f5536bcb0f60887a6345395535ac133c6b101280629abfc87b3bfb821ccf48b89a4b02b8075c3ed6cba2a857dbfa14bde03e + +Input: 84f640ba62910ca3ec1ac2aa24ed47249f28e2ed64f0d856ac01a59da16e85ff965ed1b988d9 +SHA3-256: cf2b0d953542899b3fd685facc8fff04ab576b3365129e3f58978c90be41b311 +SHA3-512: 5a40eb8b2775da0239801950517d37140e1aea0df0eb77ade8ca14a293ba3ec50dd98cd0660502fed6d4aa196e13f1b7f647873cdf87c04656bcbea326902eee +SHAKE-128: 6bb90dcd71caddb89e8806f1568279d306b32f98c4d8b64eb0685833afb74c6031b6aef1445e6d9b24dbb0c320977a55484ba1d8ed77f17c5d2e637aff0b62cc2aab75c0f03bff91fccd9a05b59d0d21c51da992fa7fc5de0f94e322b3f9423c6ca780ab75ac0223336bf9d33fe9318cf646699e3820d087a59b8d2389989e6c53b73d6524233907169ec2e58723624d452bd8f474d15b51c5875d2252c641144f3bf2f61f2ed3cc12f7b4df59856321159864607c78c7797276a41bde4216304940d6cd08ffcbd213beb950491956e11726cab868f406495534fd10514369a568c9b4c7fb4d1f5a3600d6943a7cf599a6d63b320b6e4cab266a709ee4f67d4c120d47676b473dfd92fc9e8fa9a9cdb5ca4a7ba8063f190db5a648595ea4d94ca505a38909dec2a3179d2b5e6d29c3e5a4461037e712d12013ff6ad21a0b70d0130a98949a3ff26c973080e3d1e3e9f351426ef4f24c06d28a5b9785482f863c066d3649d56348b8b5fbc1efcaedecce7e35fc2700fd27f2b8137c0e38d74d2a0626abab9a8a22aee3a3fb32421646ed406f47e01619718793a7e28c0f5f4bfce1931d007fe9f363f8a58b3fcca3677982e5c190b2efcbc3ab18670dd2be383391aeb2b4d341c37c6ddc5e56648376a876648e8b259d3f9a2df5b9012f4ab0a5f026995ce48586578d16e042b7a489d19b96a20ab424bc1cad5e90114cec8829 +SHAKE-256: 141c74c023d8764799c190f1d609ab2f533d843b0f5ce416f403bb6b36a70a727cf5bf6271e646b2672a43d70cca655051edf9f8b1a65b29ab904d070cc7f5556afd0214cec6396f882109fd68f86905ca0f7d4103827de810b93e951e4940cf28d2b47e4ce384ff6d0ecd2d9ad21451ec9f20bbb05062e2ec75ee41711e4014cfa55c90a6ac2eebd92feb4817cc915e9bebea6034e0df196c6963a381f8a464b28a2f0946c69cdd3ad049984a26d25c80f933a572c708a31e0654d791b6f935f5ea4c66e098ed72d85dbe2bc7ad6dead1edc7af5c5be258fb491056afcbf0f22bfd3d8f001f35c691f65c54ad1cd63f48ff94ac76b8afd6c4607635b5394ea9683ec1a14e129fec22cb9e99dca27a0b040b1c3fd5f93f14cf972e52bb9bc8a4329ef9a8c8844149af5bd471e18cbf5e9a0e71281239920c934ac8eb3ba10393d4819ecadb053f36d25a1d08d62fcafbb878377aa3baaf92a8ea2f318bf93897fe7bb13f110e7c81f04aed2abd96299a4f35d299e1bca6bd96343f9f0a97d7430734e3e02d9c291ba2ad8247c147299df882e1deb5ab25dc41c5e1ec8cecd4141282cbff27f6d2faaad45bc811fa3e934af60eb89c9c01f030ac5c306f1e44f824186adb90d26547a258734a9b5b4ff81f1d97aaace0343ecb050f3134068d5324a0666ba8ecc1d744b9b7eaf66a92a078c5691bf8b82be425b2fbd0ba4b14b4 + +Input: bd8bed4f51232fb1fe83174deb66fa3f5094b5f303753bec1b39043e0823de8437043bd576b895 +SHA3-256: 599abade9819bcc0c09e3e73dcb51ae7098953ae064e1124fc18e1c8f07c646f +SHA3-512: 3b11228897abb8df8471aba9466d863d57bc5bb8b0d31b59f1574ac77279dff51e5f996bc8eca7484d128a966fc4d6e38a376d137b54c0590df851f0de7a056b +SHAKE-128: 811a0d3862be612c2ee8e75a5812172a0e620092cdcf589806e9f006a306e31a66bd96015e9a9e0309f081ad6750b3e0a4a36e15b235cb1418d4224506f057f5f6aff88b42ea3271ec40c8dc58e7cd7ac2cc6483b06dff396a85b1e7d0cbe533c3626ab12512b99ea0cc7ae5e114119e78a2719245445aae106f67d12580d6348356be53f004fa4b66d7c965640613e0df2bc087b141b09a40b871ac6fd8447d1000f9be0f028f1d58e6c6562f60ec94d02976df49fe3ac9a70a78bd8be9f75c37ec1bd31ff4de821a291deaa5f7c768bf080e527d1affd123b1f529bd35b0be52d8a1608d5a95ae5ae85eaa5b3deadf32b9c0732bfe77b799e6904e4cd61be7bc05543cab87a1d0367357f56b6a49870fc83d95be3c9c9ba4d06f4d0988c7b95ea6e1bf0cbccc58d2e086d2bd063b05ce62c44a1c8b9fb3cd042f9057d1cdddbf870e759016f263d95ad485e4d66ca4aff14160b4ad3d65e7481c9c02eac098e2e29b34541786e0919ca6c1937b13eae992a2ba395391d16269bb905890c6362d062ef12392aedcd46ec9337444ec2d3703033ed56d0e0db8d18cfbee2e96e7ba47ea0b6e2ef2e866f0f3bf3d28d0bf3a7acb7dbaff967d9eaf260bd6d4d131c17e275ae95eec31d42855f658a49fbfebff37a543f92bbbc50a04fe8b2b5a4afefdc2728367343e2f5c5046a338ed52f01448b38224b4797fca06e5c20342a8 +SHAKE-256: 400604b1d9809435833c8eeed07604d95722fe522a028272743265124270d85c5bc563c89e5e6ad7e2b9f72dc636d58a8df2bf6156535cb0f083a87d30fdc8b6b8044dda81f763fca24a8693a62b89bfac5e1b0094846625a554e196b51cfd8fac5bd714a4d0eefed570b0c280ca7ca8025fc870bdfdabb780f0b0274faeeed57a8656e51a48044c16110401971d7f0486bcee3786636ab0159ce09d286af01ba448b431f4e4805045539aca8e6b2302cfa988620d51cbe72beefcb205ef6b0d95d8b3377947ba7980c21b682c734adf7cdc3306157b0304bd53777212eef94419a0293f9bce0f2a0f8370924ecdc2c2cb8113fd46ebfca618def3ea8a103a3f295df6bfc9b87ac9d22a451d42922f2f9254817fbae13c58a57d3ed8dc1b7d1571fa6911a97ee3faec3b9cd776894919096639312964bce538f02a60797433b46858ec5504e5c61d69ee2b49ca21f3c1d4be150d89ae9e24d91249a094e1cda38ebe8d0fd6c99d6e2d82c3a6497feaacfc602db6b22f4e419e05eb4cf068bba3643c1e473da8a0fcf08662c84e1502f3f81d7ef6611470a629e4f9bbebccb908ddfa45419ae1060e104f970afed6c7756b2ad43d13f623f3c84baba265863d2ed26a20eca274561295672101a57e9422b9ec7af0c941932b21d2bbc3f5c2d9c3f0a996e9a425d1fefa28a2985fd3d53ed5ce5f194998c279d32f8b37ed129c0c + +Input: 1b9c65e6a2f87fffd9a57f890b61c449b0e3118901dcbbbf19ce044345d85b192c1dc61bdad64bbe +SHA3-256: 4a60ad2de4dbb39db69d3edc21c1f672a3f82f0b9a2932c8a48042298154d13d +SHA3-512: 17e45b083ff9d2d227599bbc07076148398f321d232b5e39f340d7fa610f6a360a57e2a50c6e170f940661212adfef7ff6d90cee1792e8fc72ede9d550f27bcb +SHAKE-128: 8e1baabb938de72d8bfab0e5192378f7aac81f15d5f529750da96ba706537c6f2978ba7983602b103ca6a47431c7e04af61a94afe84269618cbc673feec65f9f53dae8f779c3eea8faff9998a04a89a3be63fd80c5412c52b632805346dd43f56b2808f652f6b36fb33205f789222ad09fcc3d25ee19fd15c4d6c10c0208240534f8a963784d3da1d61d570bc751c0c2dde94365fd4d57b33bdf7e2e17165242d89bff50c16121c33844a5a5a6eb4c12be6c835718b93cf1e972efe076f5dffdabac87d7dc7ac58c40db797ac249443c7e3f1fd79d17cf78992b9df5978ede51453ec664d855632442a5687eb82d58d8f180a4b00236e4c2ed6e5e52eeeba6813ded0c5ce51fc80d248650a420c000745514c4f6b0d363a816feab00502a32064f1ea13ef6d73f00b10aad47fc50e016f34fd6f6064ce13022e9a82cbfadc7d0412e0bad0ae49aafb9f1f2fbaf9b8e5f632de4a46a3285a40a8f0146b8772b61046ab4ecc39c57d662e6eee2f8037d4a7b612346ab29a3310096b9f00ef23c564948bdb0b3f7fc7d3aed7f4b893aa60a3078d3c59cb720bd7b57f96e723f47b26a1f11003dcb4e15eb1461374c9e4bdd065a02d8675b8b9eeb05b74676385c2adfc46fefae6b21d9587e9aa66de48d70f0de2ae248cec374508fbe2ac25787a8f2cc79a43cb39d772c0005061bbd06c68c284c3c4622f84c36357f08144c1c8e +SHAKE-256: 87abc9e86b46445a60844fcf6c7fc59e09d60eb6594661defce6f8dbf2dd25689b27f990459bb31b63ddcc8a97122a0fbdc7f3b792eba01af0ad1e2248d319a284fd8cac6a91fb07fe3292b49786094bd76f560b48f595bc53c4fac06b6c1b10333d0a16823a001e2bd2b396b58a173cd896d487408d9a98837e58b80da674e4a1585c39d576a249e1976236ba8f8844112961fb92409eb79db494570d7949ae8141f0c3bd3946629136dcd9bc8b65262dd6cce989f280a333eb9774e129930ad0e745da9b5c7d6070b1e721acfeeb05fabf158169dcf7ba0955e965bfdbfecda7e2a657e076f511f1a76f8a805e5d3baae7da440ee70d74575923942add0327f775f722f282605751c44cc731f6f0b96c9257a59b81fc365f82800de1f432c5e34d2c61725d359a8724a2875a3ac6ed1d3c5aea608bcddef30a9481a264e29e216e290845a0da638c7cc92e9c65cb40c113601d20fd4f01aee38ef6767b2b2b4454f811debb4ad362a8dd0f95c18e1b9c2567cae2fa9c1106d557b2a257865ecd2be612b2092381381262db19703cb5a88f88b387e34676425bad2f52d009f217500969a99db6e7607b20eba512bec3fcf0f37d08dd8ec89adc059ab194a3c8fc1341520dace26107011e4f5fa7d2c24968f301c13f65e8cf61b560e556280b0b0200aa90bbc9d4af9069a0646ea197bc41a0fd34c5f0e94470364ac11bb33f + +Input: 101aa19c7ffbb9646ba711798c5c802861a56f0d712295f4f8bc12e5ef93132637cab5c69abce78167 +SHA3-256: c64464eb5cfb4311c9aa9f8c82e24d9448ddd04b59bf85ebf0fa4a3bf9a25fc7 +SHA3-512: 0f6f906a01c18b71a4f1824c26c138c19a46166a54badd3fa489de03f8ac84d0cfb5f571c1fc011b2f3716e2d844537f02ffa4931cf75be6ef02f73e082e0a80 +SHAKE-128: dc186094f4ce80166046d1916092e40e792dfe3bbc7273ad9d3a1e672948bdc97af6e9e1c945823051f10674b84da6805b2a787f854eda0ee680a2c3fd1f79a490e465be98c99b0b64ee229958736d07d16de466e1e56615a083ba9019a928a036723f0361fcc116010340eb1786123114eb0a8a2543347ed027ea096623172ab0ec33bd7466a977aa250351d1ff84e903d29cb901a9f08f76c9a9979fe722011c595ae169b401617f4673fa300d3f3490eba6dbce5dee727f63e3097707cfbdd89728435d8a05bfc1fe8d0fd99f3cdcc3713638fa51706e68e417c5314867c59a57b65754b89c07cd45207de8e377f62517a8ce259c2078b6142a21f76b88a606ab502ac0740042586e65fb7a9da123256183b8fb1790a3f298cfbe06ea3a9d87ce9a7f0890bbfa930514a5fa4208ce08ba673288a98d4ececf9e31d346eebe714914364bf7d7e0e160d5fd2841b7e577fb614fb13db7d0ac9d71fae11ab26a75b28f2097a9e4761f6ea3b9ecdce87944f7f15965a80342b611dad45caccc72ab1df962748819bbe4c70c8b080a1af8a9af31aa2ecaa3560ab08bc2a022537a3da85e6d1bc636d5d5ce0a7069b0d5ab046f4106e7699bed682ba00ed67ba8922a8310c208166f9cac957e91d7102421b30260635ec179a509630a1a95ea3d27ee8e737b49f0a8ca9482b24c2744851b6299e8b9a91e6b2ba35d4869efd5ed23 +SHAKE-256: b98361f3cdc74b392edb971879595a0a1b45362866599f7371a2ceb90850c95992e0f796670d4643b2032036e21f46f1d8c1d40cd158067897537f75c11ddf0542175227dd391b9f4dfbfae00a5ea59e79b8a02cf3f03056ebbcb5032b9fa0ddf3c986ebab6821c137176686f30a989fe450dd62eb26c87415f9976f55e3c3520adf35f34d8092b727ea8dc9d259a90c2fbc63f84c5b2c1000eedb2a74e5dc96f966ec3c4b5f9ee04485d826abcebf57ac50410612cbaa06009226a30f12248fbb55f415bcec6a2b27b29b1f976869e531c65cf433b0156edd412b2d136827c4d70c1b51e504703cf986835e4cb2994f1330f63ccac93dd88d96b3f3f194520b2df2e6d830b0c83359137f1b9571809c14f2da071f667fe8fd6b4651f3fc9b2ab49e700e9324a494637ad4595519944aa061a061f8856149d49b23882f064bfe07a883f6daefec8ebeaf39cecfb83afa8a1d6a35cfb41958e94489a5b83585863cd358ddb64a09097cb60725233b868416a5ee195a625b2560966fa440ebaea6c0fa82c15f42a92dd597d5721040f437e7e259d2f35b04fb0be9b6a0fc55b40a8fc5af06ddeb3261fcc33103eda07a02921518d574498cf7c0e96ddeb4ff393826c69402c4464d51a9c476f33ab44c90e51783e66fdb4d743f651d69f9a7113c643ec4a744326e1612056ef1229f800850f1573f5fef1ddaafa120df0bf337ab + +Input: e15cb62bbd40ab5f15fde6dbb0d8ce437019d12f94d70d862e7a0898a3191c6fc6fbf684e79048912a58 +SHA3-256: 924744167698219299e17a618ac449a520fbfc3030d7e02ae7171a96224060d6 +SHA3-512: cd8ee20526b1468c47c6f49897a361101ec88770d18c2da7142cc73e97973e300927f130cad114cdedf7912fc30394c42dfcc94a29c68dfe6e3e291fb490191d +SHAKE-128: f23e2976c279afa8e6ef9fb5962486b4f62664500721215beac6cdc1b3af773d7bdda23c5174f9817c47efc55ff981cee81d5d80357cda6d9a55183249bc9808cf7d40bd73db7e02b5fef215c2d5e373606b3c139ed53801ccbf8366c6f9c60c9019f164772c5576beb684b7e8109e16b739574912f68505b11cd1252af63c0982e7dfc858bb3e13de4b4722f42c7c418a5d1925b944d4ca56cd189dce312c0fd87ff663fae241b0ce538e96ec79cf128f44029f5c859ffe09a50be7ee441614ec5345e256d74654ff9f2f1c7198e1eeb13d2fa56b80e9256b7c88717038278644a4820ab3efed9f3b194efe9f61841368ea28e8f8a4a2db1f9713851131eef3b05732c92ab42f7e493822949d8134c8578c27b865b03c07f7a598485bbc336a6008c582df49aea876d34ca6f5d82e4a1718e0cb53eb773a3cb3cd9b42355dd14c9ecf30aca5e4f44df642883d17f773154fe0e4ad2cbeb7d3e6d40851b4d7da776bb1bc8c1e7c1baafe744f72c8925210504f1488ab3af14d375e0cad875dafc6a13c425f6f0025d61e0b2e3008639acd6db32470c1bdd57606717a287fb800ead123281d4d5fb27dd6c11626b4cf9409e39d349462776b839598a99cc703fb35c82cd57cc593cbccda0dc5bc6fded808597da694fcc2962cdeae7d31e818901226016f672208b3de4c3a20813d7c11fe66e43045b2bf2ae20dee5bd76cf8d6 +SHAKE-256: 180ca4d79a7b7ba820d46a067fe7c947999530a1151c515362886af44fdb289a5cdb70cdddea1c9252ce9baba2bc3a7342e0ef83e7b98587e0e9e8e1d80e6a06a52305b28528620b9152b70977e4b8cd9da628f878560923b05bf399ea4802cd2e5af6989f4fb033749454222be5fdb877940f6a349db9469f30ab8f75eb2a4a152e04046f22b86849517cd87435c790f39de89a6c288ec922a70a6f3c6deb4e97ae5abf25572ddb3236750d86b175067dcc7eb981dc4dd241bc9243ac857a21d047d97f2a3c44456e6cb6c7a8dfdc9d7efd14598b6a87b40204bab1147939dbb9a2136c107bc98a52f7a3548519c81e2f9509a937b047070fcc2e47c4a919e99e962bebc38117a6a2f055028f45f9951f41d2cfc6180ac1cb216b2e0c9a5a79a9559c3f300d74ff114a8f916de54fc77bfda3e1a426b84e402d14f1a25f7fa9d428e37b6d3350278b51544e6c2ecb8050f3b7b9b927cb2dd368e722a19f4cc933611dec6074ec704201a110fdf549dd5ad316e161a1df844a15b5faebc5a66b7d4516c198b27fbca3b6c6e9d4af8f97f4f7be9c83206f643629cf2d81e91f980858c92a8f2557d4bad8010016590f5da8d97f3ce72ca3b9b769e37bff26418935b2a0f2e55acd7fdf32512c149a924a3de44f5b778cd9cfbbf7a9b1d241fc94f8e0bac90b126c6a093bf1a351275a230a6050b55a769ae0786291c82ebd1f4a + +Input: 5a4fedb8ea111e4f47e81ff8f2bbadfdf1c194bfc798446b7d46ffdd4b385f228f4c9b4f39f9c16f4a91d2 +SHA3-256: a7a605a3cf851c2080a835c1eb8383a5a719887443108acbbcacdbbc3e639281 +SHA3-512: 68acaba0f375d73ef9b7baf86b462f01b19a30885966f9ac9a6995125a6f6f83bd983959d1b432292766031f9ff4e7cac1e14b6ecd2c82fd3984807cd552ab73 +SHAKE-128: 5c143f2d4244319ffe8126568e1bab4ab71c515b1a91db4892b0961b59dd31f6a8d864d8eb4efd77e942e03c7c05a54129e301fe43e3fb3b773ec3ffe64291133c66ead5d3b068b02ee1a59d7347c8493d28798b0e9bce310f5681df35f026aef9081f0011c5f6dedc0ba4ab1d9efd0bfca44e770dfabdd8a332f9b3d52c83b73aae4bd75317a0836efbfa9cb369a841163d3496b13c036aabe0930d24f1f1a0d5943dc69ccfbf98cfdc109692902b72ff8a9b6edb494d51b1d7e58bb106799bbe0e37c95452cd47709de53653ddcc41c06bf72cee7d2e8823be52e9206ca379cc8e8f5a64b7f8fa9d224a9aa08c4e93649e45385a44a4af04991cb5469176c12e7eee34ea37219804cff241dca4a4d4e3b306659bdd32f4d203f542e3f407e1852e899086494714390c99b4cc07e7258f5647d677d99bd19f6136b075332daecfa31d3f802462e1e35a494188df5cf5ad68d6328fb62e299475d5f95a80a0dc2eb3965874cbae9f11f58b3808b20ae1120f74e40fff91308f3958b0016209c2782d54b0fefacea7752ca4388566cb5c5e3fce0f8a5cb830f9287dcba7c15b66ea9f1a0126ea24e5316cf09faebca41e231105ccba2c2c287a2364884e3b4f467bbef324f5bc6359862b772641874ad8bef3ca2fc43d1798da890e2b303cc957f5197e587034c3726d001eaefdaf571fe5f634a7b8d8a0daf5b1200c33cf9d66 +SHAKE-256: e30a8bdda6169e84bcca9805021cb2522f154766200b6e796b4d9c261aa3d977e68a6d850946e579c04788d1b47133bb56a76028a4da881a414cd46d18601f46aadd7616850b895bd3ba6a70b9dd58e01e70a5bf9e7e96b273e177f93599030f749a994a0510c08ef4fd205d2ee7a49c5be53e1df20817299997b10311b897272f2cf5d90b1bb9b1395462332a561ce32adc09ae8f6bd9c3d496779f6a5e9edb69c51d05077a8e7f489065c1630e351031dd6b56c86fe85d57dac0f63c0e7b846a31339136530566b55386c6cf000c3ad7c024a5129ffcc25bf272c54c23ade62b159fe9166eb480dd241682d875274f3d0425a7621d4976ef6db852fefd8cdf9e7fda64ff5b6e6aee344a66d961e2e62e266080b73b0314fab5fa18e6d4361c508c5592c436c8d0c0bac284bd54d5baa3b49a239fbe5efdcf28dd7caf203294f6f579f5fbee9ce08d1b1eab96a0c3497ea5dc9143db813c760abe537cf8fba09a90e5f014df8b2c131f4a1a47c44c3026956a8ded0b87d8cf1b0c2e66b2b64afc5ab88a19c8e19a88de3a83e949b012ee450c079b519260760382be3b1eb2f48ad68eba33fc66b1fc9a9cba9e621c750ffb4ddf3c7f1a436e732f1b7ecc88a84f51361f8545dbb0edf43b1be0b2ddcb960d4e36034b9395bf7354e84d48a1d5fb0f77e67cac8df546f40dec8624ec63caccb2d7d82bca1686d919e182e7d86a + +Input: 35d464596131a3fe25997c1e3bf8a5f02c532b934304a5e42d4759714f8efbbe83f7cce78118320bb7462eed +SHA3-256: ac930961cede24899ebafc4552319f6e413569f876ee3177a46437d596dee1a8 +SHA3-512: 8a8fbb6465c5eb8a7960a03e06a6d990b33981481a8867829195a3b8deddc8924319186fdfad0080ad13c64d62e8e8b8db92a18693f2da143e80a82c27c9ee15 +SHAKE-128: bbc78c2166cbb08c5bb4f1f01ed532b0cffd73790a8ee0aa4e0a0427f6ffb28b994829ceebac951038ca2a0a97e0987a9e9c13c6b500a4365a5c5749fb77cbda6f06f1d84daf9a0bd150123dd6814baad12bda15420c88f3205f83c8de707db3b642e526ff2b35846c6ea2de1e1c919a0ed383a147f1da48940a67d7a5fda7cbff6c56d35312c85f6c1c1171b4179ca6873948abb57cab2d1197f3cc8b2b11db947c6fdd43f96de8f6a2d0faba6f30e218848d1f3cced4125dbe22bdcfc534c3a1c28baaf12d92ec215c4c339ea9c3fea17122db8f4653b72de3cc51d379e24ab46c52e940a2dec13cda9002d463f65a09937d8eb8224d335c8ae94f296e75cccb0e1fb5c2d4b4d6264fba84e5abc0efe29c1899f3052809122eb356e902474e6eb83bd89217b15b096aa4c1eddd0c25aed4eb2c83921ad2888603f0518ca867a6704dfbf95baaef53c0d9f7eb2a6c0a109ea93b08a65c783dbcccfb4bad8633e4aa3502e1c136312ce0929820db0ec40a7c0907c999d651c0f64bdcecf4db65cf259074bc6775a62fcd11d4aeb17c913eb7ee683f5a5ca0736dea140fb5487eda84af91efd15897497d4822116bd66211b00c8d49ed3498ec44419df921c8af9b73aff5ad00a0ae0f9629e398afbb16d42d5733235766f7e36abf8550bec2a1d0838d60e2f4eb77c80401a0846832e12a8eb4d7dd84bf20a382a5e5e2f5984c +SHAKE-256: 904b686130e05f0ea1d070d3999f3374d3f1dbf717ac9a837d8df362b09a3b8c1629d228e246d1fb943ff6b6ec64ec36b726cc5c2973bc0cc92009c525057a10dd4f939e2438089f66b03dbacba695f5c5f2c8fba4b53a993c63ae3fdd265b4e6a3f6e70857852808ac5620cd99db39a296d36d5713a65527e5b31bbb37d55e3c5f630489f43444bf393fc89a7b42a33370cdad27dc6a2722b29c173b4e2d5dcef079f0585334162d3ec99b00f01bac49c04f1811b7c50921423ed2a2df07dbb430790cfa815fff4616c8e335b97c61de567cb9d3764bffca861eb2f7b5b28889658addf477a541f60d614929fb010e06b78dcc1be39bd49bff747cdeb453eba4c64ba0161628f2cc9c0bad25570d1e36cb462d0195a9a624f7878b78f654904407bd4240984489e62d676a2a5efbde42982c79cdfa00367d4cdee04bb4e55b479055d43eb76193caf840392743a6ca25aa29598bfb65e8d1c6227e50b75fcdd7dcdea82a610fa5367d17b4e6cbbfe3040ed8232e585a5ef2002902bc82921b20f94c9f5d527d737989ca4c226502ea0a852dc0f1a6c721146ce99922886d03b98324fdef187f2f101b7914c7fc7da08e63f3196b54afb2d77067729154298a3ee30834b6289c508b302cd9da89b48bf9640bc4ff97cf022016e8e43d8a99421491274d6a8b8c01064bcddd004e1e3e46a175af59cd6fb01fcad351f00da0a8c + +Input: 4d70d3bf7e9238943734230177696a09f3e84b1422ad81e0cb096a55ee61bcc3f13e0116dd8da4c389cc2116f1 +SHA3-256: 96d30ce0d1d88e96cc19cefed4787d015078cc6425617a5d56e2cd0b56a658dc +SHA3-512: f9a450c4c7b0494b2aafa34fbcc0940ee1fd20cc15c37f216671e9027c14a716c5e9753b376992e3903db2ad034ca4c88eab591e03616b4fa203b782984af951 +SHAKE-128: 4596c587904f1c424d126fe55c70450193a9dfdd3178a285f3ba46fcc0bdbcf7b28a18022eeb0189d90560cf021956c6025194ab1d37bba95c0d9a08cd6cd3ac34eebf89f1f4d9d2016ea98cbbee3efb5f76639204be225c635ebdfa6080c543719fa210252b8be729329bdf39a15e6403b710918d8eff4db37a376bc3163bc8f8bcde49dc377c318d81b77a03d148079a5be6f3bf6664e7b4fdb827073fb9de892723f3be19ccf9cbff923015dee4afc1fdf2e592a4c9a6782b4ffd19d579498d48752249901772c48d2b2257e4c3308f95cd0c48222bfee7209061e9087232c40787fae9441a0f4e7711dbed3905420d3ceced5f633792883b8ce541ca9afd54166042b90419ffad7ebebf89fb40102d6946f7038e88506db4a666880384c6f5e1952b2982cb7f14e88e1def7bd6863d0ec867f4992e55891f018e517830cef1ed649039f8f3fd2783c426117ebf5a1526a3cb60702fb92e52ea6a2c41ae5225fb71e701e1105f7764cfe6c49e45ce27cd2c27efffa40973f30599e0da7d7d440f42a9554dc1db558001ce61e9a22cc3ef55c3b90f1dc20801cc6d092112bd1fe9dc320a767b130704a88a17f78bc3e94f938a29fa4079dab60af977edb29998820ba5e7b1ba79e8548c618a846289bab0baa3ccefd830deede0baf7c64bf5da46ea5656e0797cfbfd71ee0a56d92aad1d01d50e4a0f3183bbf67da6089e3a +SHAKE-256: 3e81728121f9f284532f5c48ac9b4dff1a51ed61e4abb5c914518a8edd45b20ee6a84b024c8325492207a3de24ca31505e3d70a3ce1edac1bf5b36d0033aa9826c7a138a7201c829cf5ba2df57ddb5ce3be001c51e758716d513d4ffbaf26d38b5740fe8889b601e27a3438ae58a49601da7658aa419c8a963569ae7a25677a44560039ffd0b3869543ba4252f3e8eb33a41dc24348e7707e5fe207195130d867aa6eaad0ef93e619070a6b31f775cbe113d92ee5594d591d0034802fc681a8d25479e79bf8bbc7d266cebe70e161f68489c1a17114f34932d4293c105c2f2ffe8cd274c160de6aa11416c43537712b565f71637a62af1de859dbd1dab350df38c0ffe8c23542e32be909a821ce770587637b1b1d12fe86cf1ec0c9f8a9cb8ddbda996100008b05eae66e6379e14044fdc6daaf1ce33f616f68215a22699eba633767376a9b77c89dc72610d282721722d35d4c4b34ebb6259a9ad554ebeb5c0a96768403426e53ed0cbce8a070a81dbbff523bb76ac194914092892d0af56ae7668d637648a2156c3179d1e30603a9c38b49fb0414aa67de4c68dcd1e30c9d97d9c42940f645f77e1be3987ce3c2824d41422bee9603ef9607bfe6f59ced39286dece14d656cf6c6e09ab16b95c33a646ecda8ab9ba4de6ddfed7ea7ab868c6836caf8d111fa2af56233f11845d1e728afc80a467a939fa6886cc038a49df4b + +Input: 2f6abf66f6839ae507d33d1ffca3c8655509693eb09073d5ac0f4c1b906fc9d2aeaa0bbb3d0f88ca10d3e4e3bbd7 +SHA3-256: 30cb41af84471525d246779b8fab405e1d5fbd9fd29e7e29913ba72fffbd12e7 +SHA3-512: 1c4c599739feef90c4bef91048d235e05bc69c2b74b93d1b5d47f7531c32a7545d6973376e90e50e37be82c7a60d3da313d572aa16ded535b365bc5cca75eb4f +SHAKE-128: 46c4b180fb326cdbbb5cca502765396bfdc624765daa826be979de9dea92c5df86f86ecb9bed6f29f6728a1819d64a9132fe601b81c28971fc97a453c273f47f470d81e2679a2351bf5672ea00ab56122b9e732d3c64ca3e92626cd5bad06fd5f20905182a9c8f40817218202b4d11a6d10e1bbdcbdf96998e5561897f13761255096d8feca1cc7cf5da36d36de737c7902a89f0e984a642de0ae0efacdf8eb325486777169319619e3622270cf271f619cb6bcf99b234fc438042081c65a8c9419e2fd0e2fd85c70dc1a6f9b11d53396c7e6ecb6806ca02e7caaedccdc0e89a6a89acfa63adf6fd48677e60c1a3cf71d7b59ad300934b63b9a377ee59f5f212db1e6ce0f1fd5b94d7d96c92f15dcf8c0cf4523107886211aac3cca3590a6cf101323a26c89604d63a97a349b80af1eb27c7a637d31e3bb9f50734a884107209a6a1e2206926595d662dafcfbc033a7f31bd6f48567161d3c1e3b740f11ce4b2c2c76f70a3ab131acaecafe584820bcca84fd2d943191f0e954096533a61381bcf503c45fc6c2868927c1c390f753f6e7f722ebb45309310e9b59ca2328d72bacc04ac1ed1c7a0728c7fdf71110fef2df34a11cc3942f004e64b0fc0d939d1d0cf41bac5b8764adad93d6307adef39334de5c85dbd52138f9b2208d21b2e2ef534de8d098176073178e6d592345fe53d158131cc25ff55383810d2fbda44ffde +SHAKE-256: be2eafaa1c0ec39d825dd62b7d7e53ebcf945a8f6cbb3fa52947d8a64579853ad1e23bd3a9443a1e5b36c90eb5ff0b71704c743d22e9d44e299fd7ad83ed3f447bd6d8f06e84318a6ffeb46afd01d32d72e2be62b85ca43b54df92cee98ba4ecbca30afc9133a2a6513a0b309905d00e381986a912305450d66516e10a6f7d8965111673823347775c48f80063e3bf81dd267116957998dc5c348b230dd359527a087637d0a6c724a01736b7be491521cf46ab18ba9a1045208a1d4567480de1b503c4139e02aaf3f37144b4def04aa1dd36ad26dc604871eefef521e82aa8478083e1d07dd67d995d66529f37bcc1cdcf6739a23ee08be7339b9df32cf50a6f6de6030557063e0df18f7c4343d1f873bfce918ae7613c1888bc095481e34f872abd2b73bacc96ffda63bc8659eb97e894da5a50a76ace391d35eaf5492d16278bcfe42ea58307744ab42155c93f44f2721bfc013fc7caf6b25231de572fde03404ccd3b882839404835a91c9b02392fd1d91876d72ad98ac75ed2d91310f530505a5aa1fdbaab54ebed14b689e8f763d6a8ac1d5c2a085fb67193432f03b38e83fee0aadee422ce531d0dc860b5714d698fcdb1837610f66f699476747375c5c5d297c00253ae03e97d42bbc165e633601408aedc695bd14ba4a767d79780abc2a38903135737ebb91f43c7834dae7d92d2de1ab0d11af9a2f0040f107d482f + +Input: d380c1db053d9c111d49d396393858158f7782a1c7f3b610386a64d6fbdc13a6f0bc0834abcb9c0c5771502022480d +SHA3-256: 0fe6b5c2b370211a270c2a769da3b57370656da2860f226899229fd5ab345f9f +SHA3-512: 21bcc4bdc76fc9f8b42549af3bc27c8e1941524a0f0474555eae6a2c0d6db5bde5b66ee41e9cfc6f2a7c6b05c08692a48a436a853441aa139423fd786defbd6f +SHAKE-128: 406ef25d8c529b360e7fa01922896bf7c997bc17ebd12e283df2347843442c1547bc113806dd66679b3c77665bebb71fabc3c0808ceb13a3322162eb556356f0ac64f4886e538e0dd41eca81ed55ac4179e5344e34f8a056b434fed04af1dee2778dc2a59d5a1811f92e95cecbd1733e4ff67db9a6e65a81cad569914a21a74809aebf17087f9c94d4ec55a0463d573521fc614835750068ae825a2e3543d3f8e0948cf3d87cc899a2df359579bb0f2c1872579b08f84fb25b1a86eb6df7d24e63bdc6cd83a465a3f3752fc08fcc93f3c93a121887732886c11a4c81cf3da554c90614226f0bd3bbf18bb0f4c77438db998a854f5d8f993d6f054525ee0a6cda5e204f95eb050bce4603b86ce821b9efbeb8dea50763015cad0f703498779500da88a1094b95f2d2519629eaf3b4a8b83b0900e06e2b3678db8bc0299970ef53e000a8dae0da4c9f8b102bd41ebf62144dfb86804351a49a748a460b4b5a9b2d3f964265f353fa8b00b14135756d3443fa758f23f3da7a913f328ce6c85449306bd5c5bc9ae69457185cde331bbc6cab11c6a41260cb60b3161ee5ae5aed4982f045ad570597ef7fdeee96e848b036fc8f47920781d7b9f499f102f6517bbbb62110d5bd04a19cb184edfaa5e953b02a523511a65fc459f362aa4c10a9ddab248f086efe8bbd0dffa8a78905d524cdb059d354c737faa879dbc91550cbddc212 +SHAKE-256: 266523e1a6211719ce79de23035f3c6f137be6f254011696abe43b9e13b856feb9436d7cd4b0ebcd793a2a154e0f7ba86ddfc208e3d004d28f51ad919941ca0f8e36f476652b0d9529f6947afe67f250929a74b9d48d83cb646e505aec45d889a2b7c71e36e19f4a9a2785b59c62050907465ba2ccb219e31c8cc5ef3d9b112d64c988bf5eb3b239d48ed73b4371058b03bd30c185fdda640009e453ef7058beeaa4cea44b55bb30a945296c6fd59bb8232305374aa71c93cbc116900897bf9172646c124b1edfd136bce795852c2e0991c9a851bde757a65b1439696576a147c7b1508c0a0e14b737a072432fdd988841c2ac372fd990d7deebdb5a6c9e7a13b8d2d61b4d12f115c1fd9e7fa8fed7eaaeddfd92969e41ed8eaa02e7d26bde8ba46233764fd3a6bfd4cb53b893adac6a72350f8b91827c4fefa1dd7bd9c6dc419505823dbb0d6359fbf23f0a453b27cb70dd705165ba0fc7644921fa9d06f2407df2c4682dcc6bc00dc7a74fd1780283506879a220c0952b63a97cb6892c5d6af0c81a487acb50996faaf39924b5ad090e1b3a3320a80e88ffc4390dd2645c2e40ff43a3afde53262781798227b7415ff77397946eef420264c4e935f1a97e31dc0a6b4ac9e4ae4b0803b929d1e3eb24a3a977b2ee2bad3ff7943b9d4bed6dc968757a704d57026347fb6996bbc3a7f73fabd6f28c25a1e6c187f9798d71608a + +Input: f39fd7828e22b3c7b91fd885b468ce3b6a790d70dfa0aae900d85b5a55cb09adb6b9616b29f766c79a0fa5f7e6d895c5 +SHA3-256: 9237c1a9cf6a5814942d425d556216234e5aa0aec6916e914b2a3819d597aa75 +SHA3-512: 8c1e009893ab70e8e0f93ee450478a36a4c19beee25c040598a8b77d94192d8bf012d9eca45d7c6948f67e2c4e13f21e7311db255ceb32ee6f5c873a49d50c2c +SHAKE-128: 7841d70f81c0d5129991f801c5a9f0a8ddb85692b48c5f90dd3852db9289d0a328975b9ff360e6a57564cb0367358036633132feabf6c4a4c27dee7189472e49528666563c5d70f8e5c10b04e1ccf061d8d5f5cd42221d9937e2cab5197285a3d1fa282fd78fca9ac9be3a5f4654cacca9ac2948688d44cc9981174420f036756b7150868d5cea6e34d5d05eb8249ce7787d042c8d40bcc418e9b1d207370c996ff2beed191152ab868e97996d7371f0990091d220a16d94f839bfe9a7437a3e9bf68a5851e83db0fbb6ea796de8bb3751d5ed1f145e1f9398acfafdf6be9a6de6a200be7a28c52325e03ffb04b99c815787090d5167ee688d56e8d3f7b8a1e5f926814df6c1f71a92fbf4c3884363a961cbf4841f4f6ea50165b5fa81b2f44b508feeb5b11eca3bb3a092423c4ad2c9d2a4518ae64a3b6702d5448241805a95c67c8d9d7145c95a45dd375c2240b4077d4a0e30710673ec525d90d37d881ff899c8ea1215ac9f124c7416e153642a1ab04da80c64216ca3dd117ea55b0a074fabd2988a6c24da7d1764fde36090f4188c21d0cf536eb5ea9de5ed2bf8b7751cae2f021f741475a1eef1bcf811cbebfce53598309ded5ab003c256f59eadab25398e3175df1c980a392c33f056a0810555772fb495577a73c5effcc401677a71832fb8441da9819ca1c01268e103edca142be0dc9498ce470befec1ccfbc79bc +SHAKE-256: b3b80256e144e30bfc7eafe307ea0c181a0be32f46b557998fe0775e1f63a1257789fbfff41f49a1cd7136e4e297a0625e52cf063341f6bdfaf7dd2dc9812033db7f42c93d0d072cd08f3a48007491e25291fbc21b38f3cbae9a13a1126721602bc7fc729164e3bf3a3e7fb4cebd683935fb614b7e1f1b225563dfedfb2f043c1c675a603cb1744d87be179527c3e2bc7c178f48be7bd2a701ae34d397da14ed9dbf7cc748230c9f695fde0f9592a9f950831d81e5c7a3d267c77b2559101ef11583386ddd164b7ce9e9ca361d18f2370db91f06ea370ffe174222ea887e01de54e8a7f88c3b3706a04b0d0cad8cb03659c5c140b558cc739444f7950c4aa0864f48ba89732e498876a4e0f6086ddfd9c2c4f0a9fb31647a87ebdd3d5a9124b6bc3a5714539c0daf0e0f371b6608a210181f8f65547e3482295a6073746d1da4efe24b4e592ae01a1eafba81660630115aba2b77e7da7ce3f6826aad9bf1ab1add6bc981095a17b4cd26ba689fdafbd2291bca5ebfac762fed40d74071b22c94a104bdbde406bb20b12c0ef8c6861ff6cc8d9af483e2fc8e1b61d717c43bc2b808578626d0d8cc735fa769721753a624acc53fcd078baf3436795e4ada1fc9007db2a053e1b3fdfd23e6f59661ff9e0fbeb749a2a36f9e4d83d6a2533092bb98d066dcb9d99e09190bd45bf6de93fd63fc171b66952947028b6a009699540df1 + +Input: 4d101db2686fd80ed41580f0f5e183c571c80d513ebffc97b32dd1d5fd49e4b83461419fd195d4449a6e4e218199b75edd +SHA3-256: cd8d0dee49c55315d715388c4ca5a8769886d2f69d78b2ef090ebf27fb19782c +SHA3-512: 24e1dcbdd7f795e5303552c0d7a464193092e24588cb63d06f2e4876832957a4dec1016773c34d960466d7f3b0f296e47472ff4bf053815c0f1f7dab7b607477 +SHAKE-128: 765992f4176067a17088eccd552499445e642b15ea63f842ee401c393aa4e0bb68f6dfd8baa3d68aba67c8c72d046dd7b7b1df72b425632eb176601f2ba6b4e3ba7cb719f5a3599b4adb2d327cc9e00016ec8be82f0317b3fc80bf624e8ddbf429243c1fe2acb9cf72c0716f379ae41d60b21ce9ede4f306b08d4716429a2a4e54e81c87db4c99d36168b0278c76f8a140548f667473d927163d0d4cb32e6d0b792fea5f0a4d2ca82fd79bc0e1830b2b14298aca8aa866e32c0c1d3919eb45b174323cdb40be0780a9b5f0c11c075d9e4fac4007492b196734d659b424f9874af24ca1b4a4664a5dfa57e7285e4d4f409a844065502e58475c35558f4f6c04f2bd2640078debf3f314f370dc4cdb41bea716ef3413b7df68833ab1ddfc49a006dcad7ae53212cc28d10b5d06dc5e5385d3f1cfb846cd100cd877154fc8033a0692c002475e09aba2ab3448d625d38d6f9b08d29b11f3876fe468bd89605807c29d386ae7502934a7aae1761be854f32dc36c9ddc3b7315a8034166dc2395770cee76a1fcbd92759271bde87064ea222c5dede7b8f9ba134df5056d0b8e5c060fd1a16a82220092aed686a2e029b4a3432848fc2b8506cfc2a4426b6386bda478c0cd3b5c94b39ecc55498fe7643a8cec944975cd5a8ed9241a0a108b2213ce8093f60825d3079a1dd502b6177fb87b6e2905b7eeb10081fdf395372dfb9669dd +SHAKE-256: af9606e5fa452fafd7ed0dfe46af2e91637d1339f3e5c982bdf5525416a2ec30c59d815240ea3612e3de7f546103821d4d17d5ad889d7679036ef5d90c6cdc4719853ffbb528442dbdb56da08a44a8e4b5830cf2ab155f361ac3a914450fff53d33de12b496b3e7c02d557cab17a6662ef3bcba3d30c81c2388ff36a81a4c0617be5d4c558c967d21ebe056ccea48d75ab90710d9c01243059dc7446a727d0da5f8d8ba67bc1f8c773afcaa3b2dcb5b4c7c4d807f78ca569ef9402b3fac77c96f1552a9e805030e7227a3685c0b468b3491e661fcf63f700c79ee6d831c7549c7ef04f872460379de6e43da379bc802a4b2a135eb6d5103471b295dc1aed59a48a815debf9a446f2484f567f5a46fc6213b680864b457806d4eff062fc74f6dc402ea56a47aca62152d1d3d796f2a65c9131d9c4574906f8729ccd5e30520f7d7ebaf6b58c4d2bcfed15acba0e40c756e5c8a9103009a4878840ba9dba4e85a7752184c50d177671144aec6dbcf956a57045dae0dacc3242c3610565c40557760be0a23e5fa0e3bdeb76edf3e4fcd19a1993c022085b82322da73e1f124b3b046ae9e3e079fbda35cacf04c9629fd22c924e4dbf115dfca028f47db12132e1d4e5b96cc21278719e6c1f04cb519569b4cbf515f06fbaea46adc8c18a7fa9807d2cc6384f43197a7f6d4997cbcfe0fb8366aedaa902044dfeafafd4032b319a85 + +Input: 7d7be4b02ecedbaa424ac42b6bffe9a3ec7f75ad44a4df2ce0cb88a59ba84694b0ed7f6f2b4d55f5b3ed7d28d71055c6d26e +SHA3-256: dc06ae7e4df0107c80818b102c935dcaf66ac8d10359b423ab9cadb4f98bcf8f +SHA3-512: 402c2e34c174e4ed4a4d680dc4301bc88caea40c12a065f9668f08b5caaf99c376eccec32ecbe62425b28472ed08dfa67469c053fdd53b2b202fc8e584580926 +SHAKE-128: 4248b42bda953e672cd03b18f8798b688546a7a79a3e16f498c0e9b83557695e3d02416c60cc691796f8c9f36e73cb32ae3c3437b81fd793b96a25d8975b92d14694c8bed6b4e24087f7e8b9517b66fd114b17880c83141f439a750204a94145ff71cf95b1da46720e9fc1df3435ab67d4d637e965e599e2958e31e3edab92d7c41780bd13bca29dedeee88796006f0bef002b520c9e9a141cba32034dc2bf727090200d854db7216d4a40e779dba15794ea5ec2d2585459d78893eb33d6b0edbd98ac766266e83b6c476eca165085fec8559d4fb9b0bdb84c1489f020a0a2cae1352b6d6d496a982b1c1e2d4fe1daf4eb87fe649c2ff320cbc1828ef169e20447eafc3f644d62e030a230d0409071adbf445b67dff1a05d8c250cf7e5fefefabe902123c386ea72d12d4ea4e4edc5512d8b63b9299d30b5243cc339046cd859e72b109bb97e53f139f6d203a96537a50cc4cf7500d6504f03cff3b1b9dcc2999fb7001f0e657579d33a9aebf43d770cc4f4b92c63a88326c027cc9a8ae0a05b7b4a7219162d2a73f85d556f9946bb07964d8b6c9944a1defa6235c4095e919722f671e258d8748600480059926be033dae70bd42d7d09a24aa78fccaa0f05db5c57f6cde7afefb2ed2ac97224ae12fd393d2c772ad67267ac10d26f4a1c114cb2b4875eb078440a63b7ef13dcd94c70159c2fbd73ee8b382027304b3faba36c +SHAKE-256: 8f16bbcb9fb0889a7a78d992bea4fa8e2cda8482c906d3b5344d657ea903b5532aa8d24d8cff12c1254e732a58d60a0ce594a2106a003d034a95c35810f53900d3ad0a01004bc7071feddbb06bded15d849e1416cdbb1b01a4315a8bf7e147d2eb7c60a666dfc66e4c73b5c9fbb5e9b64c1ed11f8585b31a6acc0844906165a09b29610cd6fe6ea47dfdd289e160a7df96596e27a02c235098ad937a8b7006b3f54983415585eae106e435bb6f20ac257491c446d98e0bca9be85235b9b4b780ffbb5cbb3cc71b63976f1a77f1000602cb8185c9f4f9fea78521267e54fb4913c742ff43d297ac64310a33fb563fd278a6dd61b8c91e95e4a626aef5350da11d32bca67fe7134e45af13f64446f45ad15a375c295affce07b44e06db2e0b2f90c2e6045a524594ee91af7eb4ced4b745e78dd09d076ef3540c94c302cb1225ca08c515dce25bfafc4c3b3d5688d68f63ddb6bee6aa64fb79ae89aab5d0ad255272e9460747364b290823c619a944a100f69f07409f30184d06707b044ccb1db0a4da35bcdd70b274ace7cf30133f3d013a948738edcb2d88fd11425907c22088a5c43afb5ddf6c7391748ffd6a29b2c2ea5678181e7a753710b8d73d6e1083011f32ae68a0459637a0062e9c5c9e5d9d29eb6f898a2acd4845e05725b80046f8e8509f5b86dad4b7c697b4137fe7ab7b6287fb9c936971bb33774217159627f0 + +Input: dd80fa702c10fea35ff234749dec19d443b3811a0deaacb873aa677a284ffe5cfc5bae4c042080154a7cab325e9d19baec49f4 +SHA3-256: 4d72b922f8460a14e9266d58a486bbcfa4f5464adf79ce376ebc4491f5f46eec +SHA3-512: 9afb669305462243435bb6a24b279eee1be13a1485e4b48dcbabc90dfe0e542d5a09dd2c16f6fa096322aeefda0b57c22eb4616b5d913b6481bd49aa46a2e661 +SHAKE-128: a3e8b13326ba6085a64d8bc54f9d83e6cfdf922a6eb7751c9103305b40a5a63594ceda863d8833ccf0e115a1685489a337df1273878c9bb2d48dc95ae7440446de01b9096bc67394f86106eecb774f103f3485b09c7da333ee8b573d3076c96aa8cfea3179fa9c25747e085502262c7620bd5016cf4e0789152432017c961fbbefe37994efe41e02d93af54216c03bd17e6809b962542fac8766ec75a21601c5142cd69d9140045b134a1cfe592cfbf349bc6a02a2592c6fbbb4ce1dfb8647158c05f73544d477f8eae57bb99d343c5739c6bf8f7f8885cec4bd0cba6d357b4e054f65d24751c45effaa34244b7b0008302f94fe15724c2a2a4ce580504b99515d94fd270d182432224c2b397fd99235a0d8390961967aa56974b0e32ca449e41c575a085d6fdc0b81f48378b7e7f69e2b0ff0ba4568a6826af88cd2be852eaca151ffd34783fda8498eb4c97791c60cde6f9faf77d58a2bd28ca2dd2387bc04df8fed6ec8a27b4a1a2f46060424d6107b3eee03f15a8be527718425ca29dc339713fe82e1cbc21d6f086a72b62d4f920e462e2037c84bb4c7e9ca8eb809c76ebadbc66979b044c2dc69df0b95ea2118ef006b84f7ea4b331c4c604fc0c5f2fef621b5c9276cd10edcd3a090de045b1c16e31997725ff6d2bd4468ed539192c8f790860b1c4cc48bb4a4d60590cc94b18d2919262a759848c357317d3eabec46 +SHAKE-256: e789cbb6cd66edd83ecb9aa040160361df29c2df5d4cab9c06de6c52ae0b4180dc3c924bfb93902a31ac658a27ab7c0c1d09bf80d1d2f5f30cde2eb29433d330f0d535ac5530aedc82b9c1a6b669f38e8fb0df5bce1d8cb8b1ef62add4ca774249e44c070558fd8dc8bd8e7b3ac9f58d540d2cd07089092095b6a2ef2c1c4e0e6d3e31a3befebcdfbb463ab51c5e5381ba0aeb44fbc64949aeb47dcd164478260bb66f06e2f1e72764098c198bf01abea3a0e5afcd59bf5fddd70a9b4f20270f40e1b3049daa43c6ffc7eaa603442384f1ecfb770b3d20fb1d687f2a2ec571c2f9a3b24baa677a65b0d406bcbb4397a6d8f1ab728d571882180731231a51dcb12824de6d046eb5e0ff0787b21bd621e5b0a2c1c32b389d158c1c6df9af1ab5c1fb77ecc3d13c21cd3bd1c0c6b6b86debf0bf31f5e5acc220ae0b99d2a8d4640a484af7ff9c2342d5d30309299b13bdc7f94208e36209a59b5b91d063f5731101505904e6715bf56845148cc410bcef45b5812ea734e4eab7de7dda3a6e6360568141d09648f50b8930f7757214c0e0c41922fa78d861e201d787ca86dc40ab76af12c50c25ac8335c310aa92b502c51e2719dee53b31cbcbbe06fdfc04dc346404aac43c055a9f75f6bd38a73340878c16608c843a41c3aad41efc78caab02e063c1e9300c0ddc9a3f0a080cdeac740fb0c75864b63ac6c91a4030bc0e475c77 + +Input: ddfbf02e5d6d9d497f4f7a437872eee3fc734d623f9a9959b718a5d4477946dcccf63235cbbd809407ba33b51259bd361367e7c0 +SHA3-256: fc06bee42a610b25c0fad23f70014028808609127491858f8a78066e070c88e8 +SHA3-512: 9aadd08290e18576a42c9fc0b0a13100b7ec2052839f125c8db964cc4227357d888a22f3e0e7b907b33969d8cf0bc270065d185df054f40315c9bc901593ca8f +SHAKE-128: 6e99d49aa56489101a57619964597925d206798b2c78d077a05121bc2c98f5dfa01eba8bd66ea6cd2344df00706c82af5bc593f05c1b5384576f45e0cfbfeb664ef2b04bf76126ea6a8e30cf4162c084b4201bca5a234db5305f94641f31cc1fcce1aa17e528a9761dccfeea28ba75564c87f31534a8b8845e0589f4a7f125bd2c1bb9214d58999bb81198df7901b1258e29d37d70c9842ff712c0ebd0bb0cab682632c76bfab732e47910c2a02a2e236e8805c057a68863b274a2aeef856b69dc5521d5e3e15f86eae76949adb4e2f09c1782fc32582248b2b250e6d8484f3e3612e8b36745ab81e2a5204e3f6cb26a661b913ea63d5cfe3920855847082cdee3c5265627754440d2f60dff91191020f5571ba61d8149d79c3e010d63c0ec4cd974d393a7ee81a198d7bae30f8288d80718878c2e13dcbf0f40683a526bef8a9417bb72e1222493788e37a5ef3fcb7c7814cc859870c616e53468de44867d594dc692edfc53b0af0a65f2cc8eead43cc31abfabfd69209b809c806ed9964ecf8612202d9bccc87287f1bf5fc74edee5aef79d9f68e00a4273c94a4f2de03b4308eae213acd3ee599ea81a1cd82e5cb3c726666cce9897b82139ab7c42de618b5ad918f702b1f35c8295fe6076a98e8b55b126abf7aacd5f9cd1a97dcd30d9efa7edf49d9b44af123f17070734a3c25698fcd69a5974efb3a1fa2faa550e79f2 +SHAKE-256: 3b52a060fc5f4f2ef98fde3f839e24f3c08fddadf386a4f3b04a75a181e723b5aede63c72471392a109693c119a071c2017adc6474f69a8490001ca189fd1fa17a31739fcc91d187bc0f1d1a9a5f3580fc2eb32e58fb6250a82785d9ea5f98a02f6f7e208e8acaee2c9cb1dcbbc2f6c5dfac4188cacecaf9b0bd64b0f350f8a8172139cf00b637b6b36cb363c947ef71564fd0f2c010fac7165ed213f86a9610d2d21427e8f6a8da5127af1a650e072191f0880083a1ec77ddd3b4ea79e44a49715a0df3a6431236b58a58c11c171bcf37dfe24e3e89e2318605b5c16811dff435cd21164be851070110ab9a387822677fc167e04d946ef8d1fe9d95edab0114d93465570c3d11d9661d30cc7e9fb5a56d520a4ac7437f2995ed0039071b43c2b6ec1f953caa9fdb3ded271b53b35856daba9e8497022c09e95d941a37b1df45ad508c3a92cfb34806dccba60ac1dd228475d7665cdc048270fea13424badf64a3ed2d2ed18bf609e73507c04166e71eb04525195faa63fb8c9b63878eb51051c53c879c9a363375dca71d8cb61bd63b33f5b877ca2359ff077712ce8919803fb022295daa89f9e6fb37e00bd7bc8f137f18a899a3b268567a1cda83f71e6a02cef3adfec5b7f1766d6fbd9696cad24e9e57e60c4137b515391985f835a0d545c98a9600bf717d61b7fa46757ab61cd99e35f1e18bd8073cb90c5b3c96ea75dc + +Input: 37a8c4fe65fe5b6d9ac559d50f4de8f252f7361bfbd4a4097b6b8fcffcd137d743060a620064aa8d8238b46e40c173fa18373cae13 +SHA3-256: 1cc16d8a32c8da579134146bd66c44b859a3c69b2a16887b25f5b7354e357769 +SHA3-512: 7c7280d5e03689d8452b13e359880836b33696d8f68cdd23cd5a4c1c47867149e45e20717f930cc0030007d671321891892ff400ad6a2613dfbb08bf1d97d11d +SHAKE-128: 9f503979035b9449e65898ab26cb0313e98473f27d22f92f620b802f99f0440d1d38a75dfbc30a24d2e193347e804b4c19c675f6ad046ef1ea62b5a899b20d2721ad10119e0d877e138ed3cb90bdd131fdddaadd4248dc940ebfbb214709d21d1753997e862f5242d30a0c003a1dc70a2db96146114107b5d5f6e423eb0425401c2e78141cb1c52fc19e3cd7ba6ab5350adf101e67c6c12f4e453729e897eb1d8c15cd6b8b25e72f710ccf1e15c4a75386ce380fe608135335f1ccb843af902a4289eccb94f2dc169a52da16bc8f94b9f33c26cbf4f3ff1b42e6f02d78523131ac3e8f538d922790a1b505aaaaa215cb3c795a9bf72fb7182c1a94758a915277c2dfd6cc60ab95641626057c1c6a28aefb66d4453d625c58c14084a936fd537517ed96b0fd1be35c0766e03e8511642e78f6a4fe7a148e599d53411f87a95d2ed62e1f71fed9fe3d5893b07b6bdc8ff885106222ba15fae6cd7225e39874c2300778d7fe69b84c175008eb1b326fc092b3e870458de60b857d434140b7eb93f7f77f59bf8e5beb43adacf1ab7634ad3c95e87620bdbe24dd40e0966be68c0a88acd7cd4f2b0709578e77331b0d4bb0524be9611f660b0996c28195686030719ed507ecc96a888929116adefaafe9637254841c8cb237b7e83f02240d498c697dd75c0ec1f5380c1e1cf90d8f1120054e44097ec5337c39adfaf1ee6d413cbf6c +SHAKE-256: d65965965a6046f83cb81692650e20c023ae66d2b6799ddcd2331dc3b012567ef394840725b5d77eacc99303113f290971fccf0e5d82c07a9154633ff751acdd36789b832cf852795a8d8862093e5bd506af37bcd446dc80ea01d1c4d5cac69cead6c33677bf3e73b3239d936c002401abdcfd67dadbc05a9c6e28498401c71e871d84d73db0fe3c440467f7a287ffc014e26c9ca5d21120aed8c9c91bc3607eb92e2ef3dba9080e399d6bb010fa94b362f06281a5f1d5cfe49c459fa206634d1ab78137902224c706b9474ddc23dd447fc484bb2676cffb8e0a98bbc099f6c1eeb5e7671d3f759d49e3294271b4d0e04148bdb9b632b1680334d7394ece590e6f477b6edfd5f5d5796326590886b30851a72df4c65cbdd3f93ef0fd7406acd7ebd1041400614bd333e4a35b17159382cda4d0686f870877af24bbbdd6902e62ccb29aa6151caa61513ac73f91367e54fc0bbcacb728a971a413e88052726c1d603ef5c1042ed23f4278168e5168767c477ab5dd64475d5fbcbecdee68975f14681f9223b1ff4e7c1ec672fd248040cd91f58e771501cebc0c8cb6304ff44de6eac8d4ef90766badebfcd1003ad648908abd72b90c8fa353c4c9a25a26cc07aa2641120300fefe627cbe7635d25480e69c29a2c1f21cad00d5136edf2f583fece31bc57a76c9ba7d557c7b0034394268eec21be8645a951e7abb473c6ca918d0 + +Input: 8496ec3de3bcd449cbb35f6ab61f12b56bbeee2739612a3a28a435727c42b868a9a3f3a189531708b35e5a3d2b9f95e19a9740f2182a +SHA3-256: b12813656c16efd43912400a4d32c800b26f169e114a5b489399001a5f067ce1 +SHA3-512: 2784b5adfba9d516b6402419e37cf2fa00c5d8e9fef384ceb24de176e5de0d9074f66d64b09b8b48361eb5d562a15a48a8ef867224bde8e1b5999471e4b0607b +SHAKE-128: 143337563999b2ce15481f2b29a8c29632c02b8969d5538e21aad8c58374a26659d4928fd4df530e030843afef90309b32a6ae267091ebcbf3e327aeefb9152b8c487443fa043d2621e4e4f1158367841b103bc6c67f3f5bcf2f03aec2df76b280ad8ec75ee3b3516ed24f432782b9e9000cf18466d5f3e4ec37bef78df34304d3357cf8c8209197bce46838a5db98b2300f1be2b923ea860f6d153db2068d1ea72109a55f5194ea52a9cdcadeda1eb5f58e0a94a54c78d967652bf3923708198251f7c59a4ba8e199a0ec3f9052086c6da0392a73dbf47f89b7d10b771664207ca13e6e52ee0e9a61de4e8c591388ba8edea5df5b75593bbdc7a79cb81e7b556468b8636b10527fe8eddc9a9fbee6e44a429a9767364992dd4a490e5a53dabb9285cec85fa8fd182da6423693d46882f605a1c2928384c4a2e8558eeb4cc31e028892631359c4faffe2807d1d1cc13060abb125cc49922832df65af2cb10c04c6f3d555479a9fc70f283b9e2a86948e94be7cd1a39420dcaa4c786b4a84a556932b0782a0254bd78a91340c573759401605c29244738d256979ec275aaa17a14e12d83d6da94914e1b1ef69c0185b336dfbdea28d3d1e4c6922db8ba538cbd77e70dd200e90475623910dbefc0651398c8a75141d6a179abe2039361177bc24cc42040f423343f0cfb1092554ccf6fe7e37daa9c672d51d7f4514a4485c4861 +SHAKE-256: 482717d0513f165df6e953017b5cfffea3d9c5bacfe65ea789686c24535c29f636c44986557c468b4dd3050d790bd553244c8c2a88622c4534c50f42db1dc42414adedeaa10e1f49d2716aaf3d24f9c71f6a480599550524baec78cf1ba1361a4bb13053d547641c89001cc01ede407c31d7bbdc6cd3204fb790239be50af60f19544617b0e87cd5cb0fb5b4a6d945353111513ffab6081e8b56ee87bbfdbdaa14e1355d0b431065d082f78efd1872fe796e3c4119eb975b49a3a08000e1a431474a7e3774150a02672f6c27373ad26cacf140b7141d4ebe208761a52779f262a12cdfadb2e2d7915fe551f8b65f4edb4a9ad590784e18f2846494ed6048a51046642fd8bf86578650e77ede74f23e670f1bdc2471fa94f43c514d6e74c9fdd963047688f707164e34d0096097a259e97e23133edd9f95f2c1c094b2df81db17a0b19da7096ab41d25728b54d09b29a833e9ccc3917e9bb208f455cb9e9ce4a5d715a1931b01a51d73058dc4aa61dc425379150e20e953aefd96514ceda97de45cd52fccf8e240f1767e24f2fa5f20ef4a930a1330d631b24b3e2de9041fffeee35011646036fda133eb863f7521018221334307df13e3b708697a8753b48fefac13ab9a56db074f5143a6b8b8491f4c7c62ceec24aabcc188aca253e2c2b59fbe85d645e135cd8b64a1fbf58e08a69e2a20489dedd92a48b75e939cee7625c9 + +Input: c4c7cc0682eeff5b6624743392f783bc7958541acbba5ce8c5ed561122d59db99d8c15175d13d586de46aa0c817eff67a3f0998e7f9fc8 +SHA3-256: 554013212e6c414a08eec3c569a4493cfbb60b7f88c09c85863448023ece4434 +SHA3-512: 7decf4e85b911f1dc3f2df78c60022c97f08f7f3084d0945ad193a4960bf1286eaa12d5d318e57135eda4962d4d0bcce26eb52a6b8fb7a3854403a427c01ec20 +SHAKE-128: b034812e5c5065643db679bbec20df24b7b2efb0ff687a117371e1a1daad9ffeac38e777260f21f3985d227b987ca5b32840083cdfb29bf7ec7207d990f7f535f992aa435aa9b63a4d3851f20e96d828fc25bcba2cd3aadfcc8521f525d08f156da7f602774e3cc3b58be8662315eeeb797ee257f4e45dc094c730e31fabda20699eb31a3c3f829a743f1fdf46b5a94856a032aa76038c65250c4c2cf10953586bc814f4a6c54b9e874719178e5b39e281ecbc57ac0248ddeaf4080c3b7b55b4acd8dc7213482dce63abac44e5b1eed89204ece529a1da443bc446619fa0667ec0053401ea3c2dcc6e4257aed7beefca197cbd5497f1141c90d339c6b362a8c974bc4ca64971bdc80e60f47a47323b061f8a2bbd1ab235eba9c7fff71c5c17b5a9d115e2c4cc8c082cd99ae8c3190c01f76f3e0fe9b18447b659da597e407cf07de2d490ffb74bbbe8364e79540204eab06f121b43c1e6dc843e21e2304f8bbd32039f3188cdc67d8683700cb76e815034eae76eccc8e6917c03ad51cd78ca4a42d27434740df67f5a22fcd4b954178a97b9fd25a20c5d4527f2a2818459cfd439bb7f72290542e10b642dc5986bd8720817a0c5c7d5f09396d0dcb3474ae15517696d94861a515a835ea98f317ae16e0c4151ef33d6062ff466b3c606968a59b6a91010d607192fe4f3e7b6a3975e75c6b03531eb2f03a733dfb1e38fcc32a8 +SHAKE-256: 448155483ba01e6ba182b787449d34261332f0869f36c278732a99b871af3842d43b4be659ed76b8e742bbdb2712f855c9c94e938225fcdd4bdcaece06c8bd158aca12d615b81ea5748437f793822df77a58d923701cb2fc2b468abf2ee2db5c1b173914a2c1c9936cc32e25758482b28f346ae5b3b58bb481e2d3f62ca307c56cc2d6e639d581b08b3c9cd868a18b80f38a8ab53a3cd198ec3537299af782ee9843ade5f3c5c7f2f0edea59f10ed7f82f0f3dbaf35bdcc15c44ea869078cee550b3ac130f72f3dd76b19ea2669e2bb89124fd39a858a45f4f4a3f672e93f82f7b9d2bc21a4c95a5fbe52eb8fd1dbe08e624b980634ba5a61aea77978afb0cea1e227f4bc67747cb77267d19ed564627d1aa2ad3c52b1f0b10b898c5664378c9a6a0d7b37a178b6f6d770db282a37edc5dd5d15756ef153adbbeee8490b954fcae62d364db0a2e7bf6cfb0ee20937b291b0b9393426e7722f40546970cbbc943c7bdb40765146344cc336f1b65e942b0a2439973bd2ac669405e677164a658f30cdaace2a7063e07788a4c5c5eee1735a529a6bb33d51469f626aa42db9741a11d39e32032f95f4ef89991c5cd9f962e6a8e9299dd483e5f1fc1e938a533df48e30b76d728bdc1eb2a100f412340e1d37a920da112ca13755e4501c893e7d79ac0eb982e737cbf387c52ed369986e16e7a758694a856465ca808ae0bcfcdff90 + +Input: 57ad6f51c14c180d9e916dff86171fd0609dd429a01dc5a765cf9e1038cbb3da2d9e70493f9d18cb78b93e6b5be14e8fec41f28f7a6000eb +SHA3-256: c848025f88c9ce19492d2de2bb606adeb1433d10f461fde47e08f3552b088191 +SHA3-512: dd1610d08075bc007c6e19844d37637d039286c8d531c65a947256923683a5704ad9838536abf77eecc0f4c8e320067e1413622800849f6e85635f4099815e91 +SHAKE-128: 12f962f39bb6b0017c17aac6f35e6e196ee89b431090c6f17624f9cc06f8dae72bf44dcc602e4f3e3522b93430048a702cd4349d6ccb366c894d48efae290b56e8e61f89cc2763ad4380e8f21415284317501bc4d3374e2e29b6d28228c459ca44e1f48b1559563737cc2ff387d33b5422445d06fc247820ad74e8433ee63f4a8ef588c7b53afd49f90b2c919ab7a7f2a0a4f4906b1128bc5175cc95dbaf4554660c923b88974cdba054461cda616b4a97700814fbd11988aadabddbb9b2548f540dc9093418be5347e40237fdc8f911f65cd1e50580187d3de6cb075320e426c35fd3ef5ecb026c0ae2e06f517ae626306999a58bb37933036d5d5619084c4a7d133f2d113a3a430558774d14d30a8fb27ef5ca2672251a8bfc79ce110a8a244b42780ecf55a027f1c84b357d3f3bc2b7a49a88002a57a779c9dc2e82e8701b12b93f2428df830e0bbb9c62bba1fe7e9a891ae501f32ddb862924408f24d98444afc677b695915f6aa2da1833d0540440eaafdfc9f1ae5618818dd3b3e41a6872ca041b5b35f0588092e5e3c7702db0f483a4ba39e2717e31659c2e4e81651a0b5dd405bcb369af07f4f9acc5c5e17ddc71f06b5ed0a917015d994488ffd3083a793d23e2179e4744051a2495d37338f002af1c0ab685c7b277c4c4f73bd4c7925e845bc8668f32c4f342b7f7e2c681a2a7c63e41b8bd4d2df17310b077997c +SHAKE-256: 4604f292fa45e5cec93a22148709f74d05837afdb1cd91aebb26286076c8dc3a571115af05841e89909df784784403fdc37e1fc9b368fae327b629799c00b8455ac1f44a4e487b6e16e4a0829ff3d0095f99e5dc0056e56e6bbca6167580acbdf028318b229ac397bd05c57252ca2784e0007154b48999a4abb762be6df51a8cd33df9841d9eb88b1444d1bf11511682aca2d437f1b4491f7fb2cb43b7155f8701d5949fa82d56b56409622c57c816f7b8044bfe4ae6d540733884ac754c907dd2d91a6807a47085f66c54a5e91eed5afd77f62ec75fb00ed0b58ece86bba3a3bd242bd439f4799f00dfaddb8a771fea8afa453bb2aa18f2bd0aef1b3536fd694d35475ca023835408264aea1c60ca22c85a4a7b6682b6d175c306e293c38e9e0634216a26c2dcef8ef3051b7a1daa2388d3ea89d6faf047146b4f0f8916f7b911e6e994dac407ffa2ead672d1d16413afbcb26475480cfc0096fc7faeed8c726e8c5e0fa10486d8081de252aa4ea63fd1edf6dda1c6934d5a08a35ca38a51484962063e1e07087172a4ea02bfea4db6b6b713f1b9e8c20b7c741dcecaa50a5dbb056e21e95b4d8f28de8ee5543ea64fea01d2bbb4ee3423727b781a822a974db30f4b7bfb1b085356879d561c108c2a6b5366888e1df26352f329f5ba8f249736374e622ca399614855055545f363f5066827d320549e5a8034dfb0b61d58e7 + +Input: 7029b593a62275941ee22b46814b594b0e962bd4aef0b79dada2cf0c28983efb8a8528e018ae640b06a2c770c72ab6135923f79588d4bf1705 +SHA3-256: b02569d72f0e08e855ceaaac5eb10aa6d1ef8182f9b538059cf8e867b567a34a +SHA3-512: 3bdbadafbeefb5c4e4e06bef4aec9167cdebdabe00ea1b0a8070832c6d930702a2b7f4a092fe147c75abc0af45d67ce45704d9072716607b1515ca637788601c +SHAKE-128: 35ac8e427cabcb13e233c043ae77ceeb1e3b4d33adf0b16289d3a17c0b296e372d49392ec5334f76c874b432994c05967d01aacf411197274a11eb3727f2845890da5da9c1900ce4ac1ba38933342a8166d057c6dbae3c5271e6c86e7c00edce8781e72c54b16bc1153b76b8a713fd338dc60462a10145fe56affb0323394e3cb56c89cfd4fef48d9e520b5c4acda030d869ca96ef0b09c3e56ebae914162eb946bf9e9b6e6b0e944ddeb44438f961a3d8bba96a4ab31f65622b7e618f6ee2c85277a2f4836fda531996391e6927370332d3d5a2767aed6741079af67037a43fe57afa304beab47ada56d1deba86ba3ac3c079725702f7815cdc3bc1d84675a66380e692efb0885e3fcb094bfe2760b3c9691335b6a6257cbc2f9cf9e101a2a8db5490c576ab783eb69ac026d13cdf0820955b24fe16fe2ee72450cfb53b90909c7d4e80c1f36426725b7771f046d96a8ed24a296d80311da54ee3cd03d4753e16115029fed2b0914f00900186a8a8a81a17b994768b3a1ede8102927be9be616524bed52543047e652e40804477c87019c2bbf8efe5a745a9ba6975fee0d0eb0a2c26d73b2486666b08ec53668ee55ba5d76d78049d2abdee82bea7801a66f68288436a06fdcabfa4de7ad081755fd70cbc2cc95df390644b28705fadf1d150d319b7dfdcf52b0dfa1ee3bc7a3cae71374fbd420f40d63cebc348383d5f151f +SHAKE-256: 7ca002966f635a4f09b4bdc0eb28427bc83a447d6fe2eaf1ff1438eea5cb70111ce178518676236c571ee86a592b9fddc58a3edab27f3624461a7a027fdde0b113619e72b7b27d0d051fce7e9733554ae4111ded41c2d70fb63179944e11e68bb3a4f4323ff211221e4ba2e3ffd9142ab06fd9ddfbc62e026db42fc4ca91d8c6cfb67dfa732232f28509e436b772b4ca17085fca2f5c35e2a8511a1de7bb866601f4c6f33969d02a9b5c80d9c4c76babcd8f21a1bc0ebe4fb31a0212e9961837d95a28d347352a9921a95eafc70da85b7c11ee3a2fd84aa8bee8fe9449c53763ecf5a3df102a21d5ecaf2d1bba8e24435dcb865980df02ee64c61fc5140ff5cd5fd8917020b4da9e0e7bb0aa33051256170b3977f14f7bf6465a697c24edfba6e575360fccb3ec6d299202ef91775be9e61cbf6bad169588c8217f12dd9e376b2a22b593b49fc1a2c0a1ecbe1e659caa1b88a112390ff91e93bf65eb162b2ebed42380d4918c74890763bcf641489fd93fc187adeeb57796c5d44c26b7fdf0036abb3101548b25a70b9846e07ea329d4aa92270daf64e8f8f4741e755ff6a6a6dab85f706d31a5f9190bc94e642e817783b11e0909aef448fd657ea4c986861411d4b6d8bccd9bb260863df2c5ce957ae986bd8e8ab408ece604f6fe6f62c99e0da41e1320f3681305fd27817f28e1bd6519c958c66d7616ea00b61a8386e64c + +Input: e2d5ce5fd35438de1c68bc51ce953e8445b49a53267455d3c99c203bef392c33025cd4be8b8f1b9da41d7722de7357605fa4da21606fe7bbaafb +SHA3-256: 7844b094e2a71bd14b2109abf3aab9a0879a3c80c9ec4f76dae2e17f372a7526 +SHA3-512: 645e43e6172987725df7321c84b2824a2aaad8b334e2625ae2f4ecf1b66932f87bb860ffe20fb529559c8cacc465077458148a26ee262c8d6591942030f1f6f5 +SHAKE-128: 8473eddf56115b8f82f20c3ea7e4b100bd8cf905d290409bec85eb10535fdb806d23ec048cb86c64b2155ea08e5662cf201629123efb37b0535767e0c180cec8fe2bcf7f2a1dac950d4e2059f087033b46a0a936ceed627d2c6be815baff915909b427080ddbf88412c4ef9aaeb3b04498aad8a9afa5e54708bb831272536f4868080ebc6510089c3930673c23e90c0db88b3403d93263c18a50367969aef0fec3a6324883fdb9cfb27d688f8b268872033e19362a03658e71cea58fc69e800789c1143be37527db9ced9e845bf41834b6accfe91fcee96533558533e4e24d273a53df559f3c0d4bec65af4dd6f77568bafba48009ecc01b5b1da2e18cd55ee49b3cd3263c0afab658aad6962f325f0066437a85e59fe9fa4e860dcd2a0db5d278dda9b8e3b4f0fcffb2f010b7e09905382fd27722f85feea19ea080fcfe2cd48f6fb9923d90fb742eae8befeacbd87e9664b1d73c41f4eb59f2519843e64a6524a778bbf36caf54e266f4b5a5330b06f20878933d94a51b9c0d5e04f44a26c536efc6cb392c57d42569c8d31e20ebdf110f5f6d874a2b6347bba9ae2b700a17cfaca1900a23566946f177b20a4138aac6f19f36bc1c04ef92793a0505ada030f28de0c89c0e824d34ae19f9db53401da4db5d75aa3f1ca5d8e3a63ecd577209c5504ed6a43bf46075c714f9102bbcb9592a1d695bbbcd47652265fc39b47f45 +SHAKE-256: 831386c569efdb703fda3ddde2e549320e832a1eacf0bb44f48bbfea660785ae25cf2825e4b4a43d15279ca9e3eb6e57355cae2ba6671dd80020e8008373657b6340f47de756433d28ce6ade50ec03ef4acbf10bf1554efbb09ac450aa3c423e51a5646fc0dfc86696646b1f346acadc84e7dabd7c6dea1bfde54729b550fe1dcc318c11b25095f1e67131a4a2933f94d7c84262fc865eac097959a1aa089ce02c4f76a3dc00430f6e19a3d7937908ce27f1e17ab693f4c3556a6ea743a3db0dcf6c72fd5315ba7826c878a3fdb187e916a9110dfc8294e55cbc3f4735ec55f41de01b7828c47bcd162031b8933253d765e88f52544153406f3ec8ae51faa3880586e136fedbae170af6ff32226392dabf256a109de067a28e65bdf420fd99306f730aeb5bdb4fa5eeb8de8cc9c912802ab82cef2154958bc9d3392ecfc3a9b120bdfc37bed1997f29ff87b957baed1c3223cde1f379312aaf158a99813befca826c5ab96663382a07a0a2a06d8ec1aa99172a52e3ea556e0403328d700399211f04b53a5c3ffaa060cc864512f194f3aeb03a5b2a7fffaa080112532148a2524a9ccbd470fdc1c5c3409152e2dfaba60a7a36a38beaa8031001c1ce3030baa865328165cef7846b562d90c4e49328e54d987dbf89ffc7d756f459592fe843c76e9d508dd88dc1362a2b8b392ded9a0e51d06cd2854e78f5b76dac95ae2bf615 + +Input: 3cf94966b97498f5d67314756913bedaf4ef574dffeadd2823b78cafb2c1b4239d88c7a7cf188f3754bb44f800074930670e03c643a96e0610aeee +SHA3-256: 7b5dd6a11f0975fea2b57a64690fbfe2f3740f7832cc0bed6e7d3071959c79f1 +SHA3-512: f9024e88ac10327c320c03eeadb4c1c48ddfc37187add808389f46198da2760898b5f542d639235a2ff7da1c6dcf069f28ec7750b829f70a1420c3ffb745ff09 +SHAKE-128: 739c61330e3159e22ee0eed4808d5cfc8bf6004f88929712ac56b7ff33c678ceac5c6467535b746f31cf79a6c2db34a21b78c370f3eef7b610e909ea32b6a5759b43c43c8ce6de6b1a7f09e888fe2146f15dac008962b464c82abc1ff43436ad6ef5fffda19c31022983b5855fdf135d25d100deee8bf01ff2a0f537ef7c623d7a5001865f21162c964f868b43a354fec820d67dd31385621601b8db127bab248773fdf88e6ff2ceb62495f9a5f83109e4b57b7ad5e899c05d4a2614d4a6ae99d07271c86e28bd13b894e1ba97609d757923573fc34743d271c29dc274c56e91d5ffa69f9914bc6c575dba9deeb2285c9487982b13964ab28ceb39c9791b842d584ed9a3ac2807fae0e9624a77dc6872f20f2cbc933eae630d5fd0c33cca662bc086667a53bd04db2a26e9e1d90b7e4b92a31f8ff25546e824436e802b44913cb9b0bf6521acebfb0218fd20c25db5571f18eb9747f01b0f0db48ffd10155a170ae94652c94baa1df16d9b8b8b33da02a7f953b057380db5d8e2c67c897ae28275f888f0fdfec2bf48f6f092749b4d89233fe98fd351214d545c5a463fd504dd3e2f921e809fa2c8d623a8109279ee43f66e064b120be924b6c1939a6aee17fe42b921a78f251ccd72c51520771087c548f8b976720625b0a03f6ccc82ab173f5c1ea511fd4d4f657ab33929a0e6ae5afbb9a4d4058ba21334c53c538c45595f +SHAKE-256: f8b0b1da88d27ccf28f6f55b896f952a8c2dbcc5729a6810834e9f8c026252d61ceb32e425d512e4ee02beec1a294a9da429fd4611606bf0d5c1586079ce01b3851de6bd9d60fe057d158e7d9086bbd78a0fa38e99ce4def07811b3230642540cf0fb3b682b0542f5e1527d1395ad95a6568f2d358642b4a450ced51ab5ab17ea5b0eb3f4b163d5219543fb5ca2626f6d3a37e37e6352d957675ae63ac8a3aee9df37d8186ffce03441d917f17c8afe177fc59313a6202d13b1893a38fc02941252e137bdfc3834179cbcad4decfe4d6860cf1da2397c802fcfb214222794cc0fece3940ff6546e57f25ef2868679388c6d41012ae52740f52cc396fdba69c14214956f8b9cbf81281a89526591c682aeeae9a0c20b167c8ed4d0e4522ba90984e3acd7b9740e6b59de6cdf6dbc6383db7d7b6d86c016a12fb7554f495c34286611bb37a38d184f768e28d6541cef8e1d461b9348e3439faf05e44026a77d4147b38d104eb4b43c1a72818ab5f7e7a10c7486c23d146011bb1bcd4e41d22176b749561a9442fa8879c8e7014311476e5d61dec0f47c8f6c522a797cdfc02741e95c1fc1e889c14e0243b7f8c18de1dc3f0e88eedaa37b622846b09a0102d2eaeba6549260edaea597c9a4c1a758907ea57f814d3307966a877c425f45ea4f1ecee5ef0586e3120c263201bd7d6cf250cebc952cb38d3ac0bc5e916f595adf618 + +Input: 75ba921ae852d20adf19761b09b697209a422385fabaab50abd126e27af0529dcbbfc30fe3ad38a6cd01d099530668be4871c8679dcdf7d81cebb558 +SHA3-256: ed06fd039a86da95658d42ccd0a3abe2df6bd4e8887d67fb397c9f098e9724c1 +SHA3-512: b0898f35429a876260a1d5191cc020ea055931f02380c8cf02bff17e3d6d8be8a030239a25903b8e29b158de5c9a6aaf2f50e821aeb6895193a55e95fd4063c1 +SHAKE-128: b426454e70af7d8ef52625e72b7f04112e92024d4e15334bdb81ffd4609179a1b8e4e2b3c9e1f22bb0140c39a1fd15dd8e9947d7c19dfc9b305855c492a9495c872b8b5acd45c0603e71177f83fd59432c8440a38a67d0b608519a5ca0ce0bce0c3bdeafad2a330230177ec648688ae1f675d8ac6453b2a48c34cf6566d7e9ff63a48444921f72c08c76eabecebcb14330907d6aa9055c2dd3295a881ca1081c93653d575eeae31ec0c2b673089c99838300f326f047f9c05b505993b3027b66fb70928cb9bee122f4e26f181162539d1612baa72f8574397d00bc313eb023222ea5b570e5d91b947dbd6da54be56283a465737102c318c1ca7d5cafe7a9577467aeeac64feeab29e2b37a2063f724cf4be58f40107513a51cfbd9a642d3f6372bdf1d36b071468efcaa7487d5cbb55790c59bc6b119bbd2f805cbd89b19c6544406269c25a432f6fb50d976e3f993daccf2a3914bbefa7245413db118bda05cee309dc3dfa65d3594777d4a29d942b36fcb9af4b514bb324680c4af1d8cc75cdfce4093500fbcf5ff6df47fa53344063ae400c7dc17dcd43f9c86e47fdd298c41a7ffc4182c71b0cfcdb93f9858c947744d05bb21ad043d2d962a17c07bf1dbc5825e29135213775fce7e167680e1736e190bd977b22f33353447dd07e990a68de9a4a3d30acfcc00fd8eb7840ea101790e1e37e6e6debcc4b03103f827c433 +SHAKE-256: f08395712f6d359d4f0cf258d9460d67975a7bef7d89849a5b1a0994183c5925b326b66ade872b048c65f032b1c7bf925febba208d72a7ff64841e9ce2f251d2b2496b98a3e0b0156bc5c1b58e5938e6e88556dfd66d2fc52d1d91bf504cebe2ef35d1e2db31914c7fba35930b31627acd5aaa6858fecc1c08e7ef64acd9c03f211e79a22cccf878a65228d7173d71455856c74a306c1272bceb2049dc9866ea53674dee5496a4f1c616f518f16759252847cc0bc6489d282c8e9aede4ec2fc2fe7811bb0fabbb1c3a07e768e1688821f90dade72ca265ff5f33cb70932b1a6c039b1ade189ac5c03f186f05df68fc17ff1756542e1fba35981d33b34bedcca911c506ce63b65ace07ee08a9b8b824345e2679a6259e6ca38b24377e2b1c6db0c256bb477bfd4ef962bece5577b35874eeef673dffb76da01322ab7fff29c1ca185b0bee14ddd4bdd1bc820a7c41e9b99703839063f58e58cc99b3c9d5faec4d17b4ce254e1e564ef0bb8d3d069156b67d1c939f5dbd387a21c4a35d6a6916ef5d4379c5f759c6c64f13b48f0e6b96510b19655901747e0e195393c4614b48092c57bd632a9ff4a27cc73cf6ce6448aed648d0a3937d6708177885211b51dc5a5f7afe87ae158b590bff8b39fd7fd39bbb5d4a21c77f71aa96be89bde8943e16c6e267a57732f23f18e9f43862614846e689b5e0ae7147041e64e167001799c4 + +Input: 754e30eb272a52fea2a4ff6164f94ca5b9dfb140d6be78594d14b5987e2ba45f2e237f259640e704d8badb21ebd48ffa2bd8edf2ed379fa2ddc976ba4b +SHA3-256: 8df64280bcdae9dc7f8e4bf429fb2b8add250b5bef3b86d02c20956ee986c9b2 +SHA3-512: 375d42a4623670aa92060f9b43f943beaeb3a469862a36fffe6be4b7ceda860d1b9803f8801fc1f82c25d0cdfbb6f0a5d730cbf296100f97a6da1d5807e738d6 +SHAKE-128: 895c62236f41c932bc5045448459237e1479ffacef72b877028b8f2fed9199cfe066fe198073b96a59a8452d037f34d2ac49193b40aade352e5e5c0478b62e96d5b95492d8af8c73707dfe9e937a1d2f27d056820aa17e40bab1c84d3da3d9ae71a1f1a6ec6129d8af0d052b040694afec52fbdde7c06d6fcbf844a2cffec4b47072c99ad5f8e785c2b34f9fd675798e4615f1a5ef28deb1c19a15e382082791cff76d8d3a79c4f2bee9d374a887cca79881e1073be62426f94ca077c94b6a177425454ee5ba6605bef5d84bd4ed3ba5b90b35f21e65e9dc9ae16402636104a9d412b53ce7c9ccf4a35ebc55e9da5948c070810050f6530c2ed56735241c8c411df32ba7597e09116a8a10a5aa54f9f07b05dc3943b73465edba9888c19327ea3a1cc228f2c2b0aeb091b03223b7e344360648260c69b9791eb9e239e97a862e51298a21ef1f4fd46bb6cebc9911c85f6efa0bf70d960435e68c880cd0836b15ef28280375562d5b63f190d795af486c42483a3ef2d74d36fea63c493de5cfaa6461a0fa262fa8441bf0fce992dae71af98f3e1a1bbc3152ce8e6cc57ea75ab29dc9fa1b9d2dbf58bfc1df4fb480e015ac608c939807581b3891310d610e03b86897a222c10f740f6f688030432e612fbe402da806256d5f479a99da8ea8e5e342526583b6ac4721ff5ab7c95717abd4c86cce5cc6585224fb66ba51607b36af +SHAKE-256: aed22bf278da38a8f6bf5499fc6ac9f40f2b4325cffcf2ca07549daaef5a6da0812f19f9435e774563115e3c847c6bfd9777f30e7ef2ab0751b251243a441ba13c2770d5fad6f00985232eafb5533b9d62a9f0f44ee507b88b76d8df3021785444d2a83720c4f41566731e12e1955dfc9e939644c7ea99b54297920f26e9d1f411c82ac60c970f72eac9b6f2f0171f0be322b4f35ee7ebb4e638a42f4bf7eba4866e47198c04fc5f6ff4689f81d848328996f7c01b1dcd3fbba95df6e84e68ae6d80265a19808d81616bacb9194fc821b001755175a7af88e841ad9302b20b0a897cdbed7ce3847099e0120069ad4959444325d3ca53594b25e97c813337f2cfd45194429891d5a7508fdd778512cbf0f7b9ad0d2e556c0dbd3c37eab622b263fa379a0d513e45890d705288c62add66050a1a655dcd2f80ecdbaff2e6a60f0f6cfeb0bcd9d6a2363dc64e2f3c27a39bd707ebdfa53960f4c6218aebbbb12293aa0bc9dc30ba3f11062fadbcd74650b15ff1ff7ef3cf7ceb708e41aa10a3176c44ed4e0480ced77cf6063c3e3bff4e547d207299accd29f3df586e4639155ef22cad7a191e43540834ff5b0f623d0f6653ba0b0b0738e8bd32d57ff33ffe45abc185e75062608a2a93e993b460e08fd690ce0b24e1030288f195558fceb0bef1460a22d620e43992ff9fedacf72a747e68d15af5b99a493a9169ae725ac79430 + +Input: 12f65da49d593018d4bd5d90b83e46b7190daa5d68a944a6390beee24046313c3e3f6a24064d6d45ffaa2b6b5872a04284495c1e893c59cb5a97d4ac766a +SHA3-256: 1b3c8db0dc76f9f3e0cafe87b55a722155874cf273b9dc15f738d9428c59e8ee +SHA3-512: 6f0fc4b3a2830eaa649638abf7dbecf279d263e630cfb9dcf0e7b7ba5bb5549a97ad96bd46771bd2912337981fe15402807adb275741a5104717dd792e884f10 +SHAKE-128: 73ee2d1711960feae29df60d8b5de3bad8cec6ecf6be8d8a287b1ff492113bcfb2804e74abe369cd1a19ffedf0aff6dfef876ad4a05842362cbd0687203f98223934d3d696983e92ef30175de7ff2ca3074961d44c600f6f70ccc5dfe3317b0f6a46da58b96ec7f5b62d93d3d4033019aec924f24ab6bd3cb805c8bd50b2303b51b5863820928257aa2de67ed9699eec25f07300761354f7b6f82452a95e96c131e2cd4287617ae643bc9c9bf4bd48039ca679a3df27b33ac29fd9b086663fec62ac56df288d568ab73bcb3ef88791a2ce5db96809e632e3b990123bb8333148cd9ca7519281f23bf678989c77aa9ac55ef86d0845abdb3561380b31e8a5886441d51cc785ecafb77819db8d7cf96a9a55dd5fa851ee49f6b923fb9114734fcc6521d9f650c0a45f77899695767c2bdb036d420fa6822d4041fec998d8efc7585ab5123751817d68634a8a7b8917ddcec767f54ea649fd25722464755dcd85730eba4e03a81e034c42748e17d7ce867079ff5b583853aa8f47637f4e1f3b85d712636daeb1186284ac7f6e814d95c106af81e70f06cd0716121c888717db91887dabe80030f07b3e6bdb76fc210178f36761749333263a97789fa243f2d8a70df833b06ed946b982e68cfbe6e5b20f94445f1b158f44dac070c47ece9741dcd67fab98d5c9801add03436e328bb192c7724b6e613a9fdcb50a80ef961f7b5e5c +SHAKE-256: ca0ebde1e3a4e829e4d09e54338c7dc59d4e89029fa8d3a916f1596a0da21d75da21d94110658b11ada83a230228357d640d604bb1f7f3bc551b48c7c9aee580dadb96c0ebcbf663469fda0a6a261932a9866938b96de58b9fd9204a9cf69b67a34865319f3b98307c5cccead1f63c202a53982986be719b550be22de9d0e323017422313678c09c32e954d8307c4ecb6be7d93f80aebc9ba9fbd635c78338d3b5b5274a5f2d70cc5496ba22a07033f357493ced80883f0d5aedbc52aa38e9389b92fc49f9edbcbe11512a714dae356b8ada8f0641eddf8313e66b4acf1d6a891f5013f00b3013feacfe933bd97ceb7ec87a2f76e09c3e357d2774298876790169b58565942e4b8c900dd50f4cde0d1f910fd2c1fbfb014538b9eb5ab3e7862ffa1c80cc5d16226ea3f96fc3a672646e9a2c06e7328125970062345b356679bc157a7c0fe15b3ba04ed70fec6167addae4adfd88ad148d18fc7d87e890acb512d4dffa245f3e3b2ee723f6bc7fe2787b4cec72f4e39e917dd39ba330d09eccbeb2c5e703ae0577950aa7dce4a4bcfdfee6d1a2fbb11a402dfae58e8a60d8fe2ef65f5ee64bcb422a69d739627c2c5cf92600af2452986c752de9045816943ecd27acf033e7e576c8f2c766f9154d8b04de42a0d0bc0f807b45ce3bad3fcdd7295961d70a460621dbc90bce7685ea426939e400936e355ea9af925b3d2e78a165 + +Input: 3c53a0b11e41857cbd821b844f606f25854f6aed8717039ecc91939374783679a108f6258348927a2cd66901123c7feb55e165179565dc4ff38d0b560e0cc4 +SHA3-256: 11eafea069d8aa20a4a0e087fd4f62540ff02ed803f090e49e8611d0a322bf95 +SHA3-512: decf3d3e66beae6ab2de0647c73de1ee0c1ca8d9f7bba2fe140d22a32fad2a9fd5dad3ac02cabb2a39b33ade661e449449f9407d7eddcde772a81a15efcf9dbb +SHAKE-128: fd35d1783e53a508f235f076b827a519af479152d725581a904c7b740f4fb5f1c84b2e3eb3097b0382dcdc5c835777f3b0e9f2bd9061dab2bfad12bb8c8369c775af5940502b6bc2600bf987d8314f3e7edb73514073309c4559c3376ac913e2f30ff70f875bf26ad9777f032d9b66f26cf1361e29d815d97f7c38ca038bb807a9df5069563c6f1c2152fe135c96f424255599507692bc7e74748c0afc9c198d836870c50657db969baed3a0f8b2617c30696bac1cb10551fcb036e3e9562e622e675cbfe5edbe1fa2e537282f2ebebef7e93d2d15ee2d4093ca1b93e5f521347ce647f52eba77e578fdb0ed32dda58f300ea425d168a1b3b220a44f6ed30d9d0b959531c8dd4d7a507f67756ec9a2ef3667bf04bb4a8f298445c09d5a9009e1ea7e525d90a73109715209e4fa95fb1604ce1baa5f7030ffd5fe8ac9ad6751900d73cb718f471866b1fb9a49509c6de83e2aa797f42c52e27ccab8c9390de3de4a7d2b0bc07926e67a4daf364441f809536da9d8b04895ec60deba438a32b33f71c13464c187858753a0e97edd3c6c708d00f25adb5864e08b9c955b8aab1ad335a05895ec8f6c7bd913f2289a4ef318ed9cbde255609d7fe8879b4beeb86d2fc445b5ad37c29f48720ac65cdc69dfd33b9a6ba632bea363f305219b6e28fbc40d3b0c7c31bb9a740851a01a3030c247e5f02698ba7bf9de3ea07e312beaac96 +SHAKE-256: 236bf57cd87c8bd82f7808a880055c5ec5c8174afdc157eead42cdc5807d57c40df54d7363b077c57b37999a344f85eae50292e712e2dd3f2da06a0859257150c20be81549d64ccfc265704d37a008ab651fd4ed01f8ecf436c66e0fe711a753284bc5fbcdf02ce5b51188fb3b59b016c8fc116241f1200d6f5f588efee440a7812edf60ee33c06e98a0717938b9a65740db3c172b90dbc9c973fec0d6c36a27d1485613c4d430ce0bc29da145aea9c3ec4713e7555be6e8e0d5019ac6da5916e97e881a72ef0712803f3202e627eb64719af50d9b9f58de29a3010f436a0e0f869588a7fd05fc23bdd16023bbf82e92925deff6b6044ec987c7d9f7b50ffa2e0a9ef1392dc4d0c5bb0c3244cf3f3cf1a8fea1e87d61465989e81621c50c95cbd21cb16e68af075a8b400c379349ca7e2ebf5056b55aa3869c843bff1b04c517f6015cfe93f93da7a71a5bea89973e3e84686851da1e1fe797c5df34c7c7c95b82a2f33a7a4182f8c906174c3767e1cecdbdfc66e3f9b407a55d4158f77626cd0c0cf7e10ab13499199eec6ec356cd4a6286420bd51c4f139dc86b62e2b822fe39b86bf5b7fdaf6750706a48ea8f297ebe5cb7934ee8ec9153f40a0e148fdfa97a612a90f4dec889a7e331ea5d9c940232dfe365b53c8d9782ac0ee21ced50be3ab0b98140dfc06d41577f6fb69d84662bf207179f3ad27f2eb20fc16dbdd800 + +Input: 0bfc630357a46239c4a9ed1aa5e421fd9a3e3ef1f2389eecbebc869e029dd6ffddf2c7f173ff5f0bfffbfa2fa876b329ff7ffa9ba2f6844176eb85dcbf2d4d5d +SHA3-256: e3ff4bdcceb21003693e2967a091c3891d81d119234180f86133aed009475fd1 +SHA3-512: 0a59c2905d85b2c36fe3eeab08f1cacef0e0a3a19f6f0cf47773f5734dd5ad47d6a7e4eb3edfb70c97567653c3e4ec8154af29e203f126c568e014b2566c5c99 +SHAKE-128: 728274a7c07893eaaddcde6ab9cf4c95279501075bad804209053a1e644f632eb86cbeb737b4bb579236e2233692da728c22c40bd3440f050a02f5f894937dc5ed6be861ec3dd0e34eaacbd145f7e4599a5619740296fe8fe8bfa793c281ba8bcc39d290b9b56fa976e728049cf63d380a2ffbba099481e1460db038070de1c743eeea25d228735e42d432ebbe092eb2d5167ca3a7c8e02528e88e44aa3107bb1733d966ca4a0905b8f4434bca171ed83b183e85064b36d8f41aa57a9758c3667f75d9829fd1eb8cc40b8db89973883b7154a8294e74536b4419ad84ddb54a4bcc8e0654fe259638c55d8f0a537ae8a7bd3d46603ce4ab2e6f1f2c0858a542346e63a81b414bbc537f4cd401d264c6b2b7ef05a9303399068aee5592340f42ddb48391528c0aa79164c364b9c326e0b9abc7371e97954eb7f7e61d66e11b69ede459d4aa676da969daf4a62ad9549483f37faaacd8fdeb80f4472a51f3be2e52b51ad7b0e8f7a2c1bd72fe505dfb10e3d531ca78d1fad7beddd7d0160b72b4617069ef25637633c9ec3b97430090a4be2e2c56e1469f0f84e5baf4a9c6d347da831d6b1cc4cd89704b37bded9947279d6f4fb43b5bab68b72a0a4fee53425ac77adc8a5e9a0743271b0dca2134ec407ad79bd79d46c43bf13097bda90def112532b57a2d55ba659c201295a43b1c6fd688ee7854c7ef10abd69c8406e24cf581 +SHAKE-256: 47bd1b499562670a34fff9df86771d1aaf0f63a325fddd85a9d4b91a85d401c9f2bbd60c9a1ca5f09e4a3e0880e6b850493a2bf11cc42f5eb3e766874876d7ce92568c0c510183e979573d661f869e5c77e8c988ac1f7e3e77979e6dc50e8af19f6b6e87a19e1750057c6f533584fb558ee5ec5ca6e0a533bb0b433b9b22b2fa13240a21130eed49085e2b32566395578e42a32c7feb2aab582a41d90c223b7d88f78cc4ebd4130b5358f582aa5330e68b24139a24a29cb83e685c459c458cac58ecf0ddfc9a5f278d43f3df21a15aec9018c95ff4f7f6fbc26ce46a047592338c369bf155bd18faf0d75fb7d85a25c0cbac6151a8c507e1496545916c9d4d4482f6c86ad04310317288aed0ef414e2985395f7515abce13101304a213dd8ac8e5dd4e00e738bafee810b4c8d38d3741926fdd8be93a8f17b141bd98f637bb97e817d27f9b0deb8f360892de1d5d496d573dc85fd3864a13a80c0beb217a26da80736adaa71311913edcf15b15a197b0568ba9d08232824dc2a9d169048bdf1be983159256190628c86d13ddd51ee25cf02f59752334b341ea24e5993df3f0c8472173a78cd97bb9e18f604414fdff5a1086babe421c5d95b0d9fe9b8fcba84f5ac51ab9731ad29891ed5ef94f6f090157160e340ff078ba2c7548b451fc4056b6d5bda83cc001d305a178286e2eeca4b66dabbc08c5823ee0450474eac6fe35 + +Input: c493a93f3eeb7f8fa2ad1375ff7189945595265bfbe3d0aa987d55eee05574b9a69c5393e30ae256da33a11058d2ea43e4689ae63ef1864753570870cfca7068c0 +SHA3-256: 933e13aaa54e1e3e5330c8995d18e0f0ef9a74c9dc7894925a4f99726b683fc4 +SHA3-512: 7b9128362284a109dc4737166bb2b4f2861d76c720d77bba9d42c51f2959f74108e9a9975e124173cea9686664b570921497706214272b3732bb9a5154752f7a +SHAKE-128: e3b651aeea2c4bc184e1cef7bc87bd88065fe2c8dfae4f585e4082c057c787cc3f8bff9d5edc5364e750823729777b2b5cc9b92dd6b65117ae1d4a8ae576631de77a291e65b11605e982066a13cc3102e8205db8f32bd58c44546426b47a5874aac7399b82e4f0dfa9dbfb12eb015fba479f774670e565e6ddeafb0d1a3e131c0f7055592902fd254f1e5ed955c83700397e4da7a42e4dbcb01916741a854584aea774ac0a6771ca7df1ac3601908d0e9ff7501a508f66b07376d562620742d8dc879e48c66b720f7dbc2bfa2b9e00febf84f1aab1fe810365630d54f126d4bf227fd35fa69361e94847d1a48084f9281f38eb6758a938099a587d753281e35d6973f410db8ad9828dfd949e89dc8aa92e5350e82b7c128ee4e6eb15fb47b61af326289568a2afb216863e4b428fa316435120e423fdcbbf05a7e04cfd57fa6b1708a181521699beb644130fdc0fa9e66f8b05df2f283f80971641d5bfe6b8aaf224a60fa813f6b8fb029542272675d170787ef9dcbf862ec30126ee17af7d5d57e6ed0d3e876cf9126e7ebd49aa86f72ebe2d7afb6e023559f0818827187ac196f577c6585fb7227aa40f395bd2203c62e4777e6e2d097d29895e967ebca6756005b99c519b4029de633755302aa6e30df6fb86e06330bb774c0492ed6cf2bb3af1257628e96a9697edef4b9a787ee3d6b324c1491bc220f3d36bb7a2b15212 +SHAKE-256: 8b7f9583a76e483b7f6253bfd689e8a633243a18cc377814bc304cdfebb0e1ca08ce2e593caee6442477548066a74d4cc07ede61400fbe276d1a1e1389ef7ca0cfe4263e448e5c6a6018f288f49c139d702b707782afe199d83486fc101fa2473925119062343eff03b6959a581c2e76e39e9a92cc5ca1f40be70e19b113b19f6dc634cd7c37c13ea91887b5cc3890c6a03ad0d5685fea9edcbd64a838a5d633493c900d6677dd3f209148a010fb71a3205161ec8f914dedd0bd5e6aed048cdc216f8e968c6bd02c7ac2392b1c5016fbadadd366eed11f5eeced898f074708c24bfa453a4658895861e32415e9d8bc9567553b0e96cf6f318aaf2673933243eeb66ecb8f00a9a23ace1b0f9022e717d8fad6ff2bee6dd0926df4beec5baab17e1bc83918136c0427869efb0caf9353070d34bc3912bc2a27155ffcc4a2b0a5aba2a00a989ad57abea7caa83b280038b2d71d6fa82288c69822e17b07f08bf15e8fdb8c62ff1b2b717c29122e6abed21e2161d854df98e76b43cf90c29b95ffcfa9e69afa37679c273b74e00623f4c3591a0f260fb56c853e4281e54bad61076fd4dd27d0ec31c199671ea2d242d06b4630116f31bf8885c02579a750f43867a2d5ff3970da12ed3cb5654baead5ccdbd30bf608897c5b45fd289d279ec44aabd4ba946e45482aa65485309f1b436b0f97c762594815dee5212ebe78f7cca65d9 + +Input: 446a5542aa0335d67f1b22176e7c9817c6d172ac26a741fd85da46b01fea43b0db0968da07fc7817e95fbaecbd441e0141b70e13aa59873fa91e6e93e50b6423bb5c +SHA3-256: 30c29bd416ab6a14f640ca9115dd8aab86218307ce00383d8ec87220043210fe +SHA3-512: 92694fbb0587de18866d9281c312831ef5e7bb6ea36259faf9638cbf106f0daa3b45bbb770cddfe919bfea61741e2a58036c3264f320320d124cf7877b11bd3f +SHAKE-128: 71274bc8e44a45afda79ebb794240700420089c6ea397a557d650ed2b5952a99171359a5f2afe216095e5991e5bfbfc7a8c25d329fc6bba5ab0ab905ff8e1981d9b18a7858787dd9892ccd850715a06581bad3ccc8c4f3be2a4fb62b10e427af9500b9be425d8b578b4a344db0aaec29a19cc1cde8cd0c80f4f4b0986b6c0c491215d7c9615d4ca8153076ea5a1dea0cfcc9d93d3e261d8c06a87772be4bc1b51848d38aa1390574f2980bd35e08ea19ff1cf7dc48adff572f7e44ef9c8123e8fb820ae80cea939ebe0c489f8157fac2e4b24007a7bf21629023694475e467c6c8ea5cf93f79aebdce9bcc68d57a5d45637687c0a3c0521501145f711f4202577e63fa4f0d1dd02857f082ac8e718c5baadd1403af588a6c5ac6f9063be825061b2f1ab36371b833a44143a5ad8b31afff66f5e8c2ac37d469678ff9068e13d9e211fbdd71a7b4abd17fa6d2dd06c6eb8122f41516bc4849a15e20159c8a953bc985ab5745b8197d3a04e2128d6c5a787700582f29e91d2033632e7bae715d00190370bc8630e2a36548382a12bc0dc84b259576df2fb04af0554d6e5b57d56ee078604f7a2b02c0778b96ce28f8160980b25a78afda67a5f62aad286e1b0d752c2eba4cccaa109f0fa1beed137c66caf39a82103482611095fd6056f05d22d709e21d4487f84035d831ae5bdcf77bf4520c6a07691b029d5c991b37734bb54f +SHAKE-256: a483f18f71fcbb78a30af0e0f3831fb3afc7eb4f2cee7c46c7b768e2bf166265a3441f36234e3e12d168ac8b241f08e97217f6044b24f8ff48a2d04fc1e27920f0be8469e082f878389ea6319793a9e1a09d8c7e5e3690feb5590e3dc9e776404e4a84fb46acb1e19288c94bbd262749878a5950ddb6cdc190d90064ca1b91e11dc950cb386e876a6538d9f8b2013a8c491a3c15017b68a6c74158c67d73b92f1478a65acbe36b053cf910e59b92e2649e9a535bd7e5b7e5c1acfae5c8ef3dfb9b3a99e26f7e1377bf7a019d18e58e2a9373a79205e3f7185ac78126cde2413660cffddced977e2a32bf532817ba09f70bc83fc609d8639e92d536a582afc5cb5873ef482341204f6818d6db3ce902b85123dd4f52372dcfa302dc93255d128565224956a61ad3af0d4892952551a268c3d4c0ebfb2b5c76d1015c2362216f79009359c6e5eb3bef4a618c1e865a4eb5e85d89ac3a64feb76b1d84ebbcdcf69edaf7a35f81a24e54d47ba3f1fcb93762eb73c9c2cc3b644306fe590c27ecee9197c1802d7ccff4583e7be23a42037236f926717b33477a61b7a54ae8f4934281275509356ab9079158a7793f298dd0a02a577ecbea6461b1701e4e6777a2d48ddf156118b68836d029f7ebf743fe827d245c951274c93f8cef8032097f391586b659b761a5f551b02b413a091fac65cf3592a992f02cdfd8a32606f24050ae2a + +Input: e232eb3948cc2167e2658a6652b7da5c5ec6d43c85264d73451817dd385a4e65c368d8a83e4ef36fef5659bd8903d82eefa8f8c6cb39e4fd1d473e110b0b1993d4c4dc +SHA3-256: 2239e965239941955e33f82786da1093fa7ed00175b07a17ef8aae148805fd49 +SHA3-512: 93e30b220e778566049585cc57200be471e3cb08faa82bd0d368a4ecbf3d173fa60cba84fe7f1933a56a419ab5a3b477d0797185df39922e8b5e14dad75c8672 +SHAKE-128: c14b46e44b19014199b9addbfc061aec923a8952958a2939ef313f12936a8b72f935cbafc3ab912b89c166e6e13f0e31513be67de9423aec889c32db485d11c7c8a48fcc61a013ba5ac66efe0d5502689589b1bd2bc0eff94b65d35370d461916719652259a71075d901f9e5b7af16e0801941009c4316eb23033462df3978a5d3d9305d32951353e3f83c93815fac66acfc7dc26051461418cb7b5e9970c595b8be9c207d453dda3f37016a7e52999400a2ff24d8d5468e6187284e0a962074bb9a5492a13cab2bc1638c78ce96e9a9e8d38e60b9d350243682124c9b85929cd6ad2e1b9a59ba333dacd6b3d97f75bba45cb815d617daf64b0f7893c8ed202330aca4144bfe6fae8a23c30239e0e6b9b5af51c6e010c43ade06472c950f4e0aa2c1d78d1bce81cf19aa7c0d1eaa247dbe750b04738026c6425c9bec85726b4c1a6f26d0d817a60ce9308cd8e60102e566a11a93e9baa588993a40482fa783a9a833815d8d5d82de8140d2e1036e34e08578cc4866eb5cb0ae1d2eb22eb36a9373ad74a1c0a43679d7a8c1d272d2b5d5d998b9446beb6af77f68c11230914fef2a9a86c658a894557a94158376a55767dc7270fd6f3a35aee4536a812c97d44af3e8bca1620645c25671e3aed9989cac78af7ac2896eff3d857b2b718bdc856afc0a904f8afe8b3fc59a7695926c3568001476d2b5179976361d532fb9fab298 +SHAKE-256: 76110579fdeab911a296dc9c29900661ae8ad404c5012726329a74e8cd27d145b41ce7fd165edf068abbac7ab7f313fa1caa6bd647d73bbcb7e63132737a04daec2145e7f76914649fcd50ed6127b021e8e8eca0d0e5b084c0e24bc8ff6a43ae81082d5eb7b21eeda6f40a6ce442bf7f6e9132e9dc8dbadc43ae79ad5c8be8bc6c4988fb3a3a2a35576d03ef7b4ca169a1a36289c2bdfad398a4c86c53de594f32b2fa5c8b43e43d13c4596d8e14d79275cddbc863f233afc5854354c1589a2f523a50a0434150070bc2caf34c55fcc397d3877dfd586888d45fe86cd9d187a6e4d97f979054003f732afee583e9701d93de679af806b8e8e498bd1cb8617b9590eb63d786c0e5ad88bebefeefa280aec789a96f3abe7a8b78c09268831f216506e50b55abe1f2c8664ce7c6767a3069796c01213b3bcf39688d1b69ea4c1b18e07f72b7eb79c1da6c5b0403188f6caa00298180f066ebb7b2d816b46d8504ed06bea93fdc467762f97a17605229dabb38b3b25cb92d1f6e13217878c6b83a14ae2f640f7e34aa203ccf64c233c51be6d2925d971a5865a235f265aaaf108750b33e0c47b23f733bd1649ed51aca270ca0e48dd5168d652088a2aeb5f94e09a12475b398fa5af03583d1fff507036fc6f7d638ca8d944186724f61c8a50daff1f0c76ef727b78f4c5eebfd54cecf2abaf143765f4d5ca962b9962f042222caa8 + +Input: f685aac046b016ee5d6efb32ae7b3d021d63a3bf5778a80a3b76b1a6ca1af12fecde9b5f60f6380733f5a5934948980b68b8cec7a27a317a39041e6f0afa542f939f4815 +SHA3-256: 2ad04e6a20bf4f00a86ea729b9fe9fabba8cba8642e7e8964b0c4dff93ad0244 +SHA3-512: f4cadb9a533a93e597df80a32e515bbb875035803130c583b81d166beb1298bd1f7b28241ff3505ccd63825ae8fafd726e3b99c3adddc17b1d6f79b5dbb713f5 +SHAKE-128: 84ca5b836ea1518c8812c24ef0c866ef99cfe35633738f27ccb92ff8ac4a3ead7e4cef90d42c19f2253ebf3472e2bb38306d9bc9e543b71e2696ebcb12c6056f2ad157c27573b6af3e93085a7e3db7c766dc4849925b7389eb379284ab8debc72d41e8974bddc0e798ba888131d5440b84d7786f869de3cdec60fbf5dd7af4a5e9a588d361799e023c508c854903bcffbba8bdf45697f4c96b20c898f8ae299ecd3685ea9b603554d88b3ea205d60234a336afca3748a06c0948329d6b122fc8bbbe6af72f6b4e7ba1cd3b958c9f666288502aa96e85a1794ea190720cc9f3cc68a3e203e361eef00552f847cda4b6a7540db29c215d4ee9e7a30b0756f4717bb91d63bc6bac70e5a7a4f03b28d39f9aa5b859aa3a864b1f5cf98800f15096de1fdcfd7dfebeed7a84260f14e0b769d7ba7383578911d46de1164b5f70c071f83582626efcacd206679b286e50c579c6bf72d3056462445c1d4f1acbbcf5353645891709e4ec465ddbd1c22a19a9b4a3b857a8a37919b1406fcc785a46547b264b2f33766ec8b1b07fe595cbb754cd96e4dba8ea90ad93d26dfe6c581e2670f27695f483de1293b9c0e950301be9ce5e753028e62c636cf55df5dbb43dfc8c04d3d655007b84601e0887682e47a9d8ad573aca39231da82d957dc2f1963ecfed54fe0c566cb6fc9ddc2787b61939f60b73e9611a0d4458dd6e2ab39a03f93577 +SHAKE-256: 33326e9dfc09ebf385f246548b4f667441fe2bf9f0c307d0bb90f9301d0a6d80e439ead419d1db7488e8f06f70868cf9291b81a178fdff85924d0123a69af1fd7576d26cfa07cd5b5d39e5364a3885387ef18337c50851c11dfb1cccf827ee094c51d78910c94400b55c249fdd63dcc09acda120a1cac629e813536e0f9951cbabb7462ad3f085a1ccdba227a4cc0075b86c02350115fae9ad86efc643ebeb01c486f4c00def25ad251bf8d08be3e669f5e4f40f14dae6f6c46114a2b23ef4e82c3de0ee95610c7043cdc602115fea6374e9abc901041ff03e09192f950f4ac6a259cff1327d5585f3ebed3a4267776b8e40d3f8df57bee3d2b60a855c0514c1a6594b066bc638d1128a1526c5e34fb3d63e53f345ed1ef7f61e904b290b3cecd4e177f8b92321a979f010eaf2bd92d724443af899e3dc9f4334f6d5596d62c97b790068b84dbfbfae7928cb75870b5d648c5b1d54c5317e47d32b1b976a42f96d44db23c8b2c7f575e64bc7253331579cab153d53def42cd710484ce83bb13e4104494ba1577c97e87ff2c0605e0c1216510a5443a4fb5a9a0da68e904f41b2075d0b8c2c270430a3f9a343f07c8fe8b55066ef63cf2761a0444b05a5c788bab3d22f2caed58eda455cb834fa35ea7501ce06167f223c3541c09e63cd03fcd470652c9f7e2d7c3d1f18b3299d42138bedb51d0b60286bdc9e1978f9fbf15e89 + +Input: 83d71959ccd94bdb722444897af34a1f241136631a86dd8883c29cc41ed72b719ed228a210ea76c4ef69e30897434fee86b062f840b33934d8e9d85b5b2dc0facd6ecfc5fc +SHA3-256: 15d713090d5d4fe8175ac0a848906c96895f60379a435c8835d5d2715dab949a +SHA3-512: a9f6021bb02367ab501caf3153e2f2c6dda96b55dcedd060802ffc43909e8e6874cf84eef86728a4c7802817b923d5f85d458c564e19195ef1c6fac9319aa221 +SHAKE-128: 57e18d71027861eefed813d71f32eae2ca2573dc157bc5d1a8902f35d8ee08b8556daa8fafb7ee474f3748f21475c52d3d688e822aa2f5bb8d4cd991980d3ff9cccd521d4d6fcf846eb1c8ed9e5cf47a013ab57c95a8e5c2c4cf5989922e6275085a8e07251f99e17c4d804b62e88812a5bb3ca97f52039717ef0e99035f7cb60ad699a8612bc82a70c38c6a26a62f549505e9135e2a7757c38cd99364f4c7a1124ef3ea134f540bcd0a44a722b1fb34203b5b75063fa3eee9bc9cf4ebfb668a299ff6beb7fcbbeaf6733794d55fba61c64c14f71eeb6f41346282dba33ef7a1dfd6e9b9225beb3dff5e20650059150e64a3b6f5a3c21ee29d9da8c79ee75c851cb651204fd67e73f30736eaca8424210095171ba9eba39e680ea9c394d21ffe5a7543ba0d711de23de6cf93bb91549211c2fabd3cf909ad985262c55c3f13f22e477a86729b2ab2b9a11b4e0949431ee2dabe021f5b37bac854bbfbcd6bf73d9a9be2039b34c407181e7532bdbdaefd6cca960334b9433e2c4b46a7029ef9eda8e18e0127d082761a1a8eee90188bfa8d396f218604d6380da6b3fb0d1d7ca383606843f3b538574a62bcbfef6933cb9d01f6ca3a63e61b33eace604780f6a2d3d5b05c460fec1b07c4eab0fb1f110a257a9443c855739ba6d441767872910fc2f9cc3ed3192ef5768fe42444d692db5d6709e35fdd3a3a324df68e57fcffd5 +SHAKE-256: 54dc72d28ba8ef42c88c558eb19f7d87ccc160d5ae857351348d288bea1907c0722f7415bcf62a2cbc327adc6cc9025d7816fd7b5ac6aa87c3f4271bdb1f4ebd6ce04d124282be98496e7daee4f35788df0f85d895bdd16f5058280e891b6a973afab3cdaea18ba77cc992b1ef9ae1d008d3ac448b225390860329690b1a6b7279dc58f8980002796c527fd46161ca272902c7b026aeaa38fcd24fe97eec536dd00484219b9a71198bda2da1ac46c141a22e913dee5172b4a9042c20cecfddfa79f7a3f8f22792450e7df2e311741edba0c74257a1ce7a9adc8811b49744d7cdb9e65ead7d369c3dbd6d4b5e6518f7c75a8746ae7e2cd1667ceb9cfb3c0bd91b0adebe5e2c4efa9cc30d04bba33f5ede1c0dff87c457a122757ab070b0c53067567c2efc31486ceb11bc470defb50a204c938f6ec9b549037bd06f9db408a4808cd4773b9c2bbd473e51d3f53f8a84291f5c7795ea7d863eaaab9e700dcff99d3279b33814b43e50e90116ac1e3f65cc6b6d08dd568296c686e7181b616ab2c8115b9a782f206176d8a4697f7e8ae41d973a244109354a2cd4247d876d13c1d2e1643be41aa2718f8cd8d54b0e1d4436259a2a889e3f533b539e8225ac65d10a74f59a9af1d6e77442a321a11f5b42cedcbd840a8e0add1393f01f41f0519f606dce8cd260bd696ac7198d3bd761798409db0a04294908c504ccf2592f4125a6 + +Input: f524741527cbd01fdaa1f313debe5e0c711916f053dbe20480af1c8e52eeb1e28f80403fe3d5042c0a4adbb8283c2255d7c6f99eb190d911af7d6f01cdf9f81de3ecc65e12e1 +SHA3-256: 0095d0c3e5fb1ce5b1e507daf7ad9c49f285654333406d3c60e0f738fe49e6fa +SHA3-512: 3ff1abd6e788e8e653b46a326f24c2dd17b96b027d4809ca8ae61eb7786bc16460560c5842087c9a3c046fad44a562f415f60258a00de1cd661b7cd18d5d7ef5 +SHAKE-128: e96d01bcde4721b7153da2086686538ad8a5e45f3957c12de12f9e32e1f33d57aa22ef14fbb8ea9c93a233f738bdf04018dc285f6782e85edb0c1d8f0f4a1757ba684e6b627e3574e465979f8382de10e78f92b7c6783eb361a108d72a18cdbd5e05e928f6eab746d544414a4c36a01e193582562adf06c0b88994b3284ce805234dde9df671d7816d58e235d0fc24a96ed02027e10dc3b6da317d4e5aa4da93451c520c17832202db4860a5efd30e4e9dd6a5cd5e4ee78f941018963c6059493c47bc661cfd6ae8993d32821b4847bc7d58f817295f938d497c3da0d99bb55bca3a1c8ae90e6f99392ea3adfe35d3c34a694793b625cde73e76b2c8b562138c0ebb899dc50a452965e2869bcb902f5507c222546a5ed893de70e3833337a9525f2c1d1fafe8d5e21888076a9b72410a7f76908432fd2f64e3a712bef9fdb62176ae537574eecd780a1288dfa9039921703e19f11fe49a28d4f31029bed38435a892dfcbda317c882ee6dfab2b5d2001b7bd530f4142424a9288de3513b9ae0fcf6232c515dfe0802b5f1bbf464665435122fb78680201c5028a75472a89b51142799e1125bea400e32a2f2c23e4b904ca475c5e446984df593719b6d38a3c14732cfd5739a065ef9236431bf67290165282adfe7411274b5598aa493b4c5f3bd57ef4162d678d765027fc04e1b9a6c1ec40576e83f0fa27786a365ba2db7339 +SHAKE-256: 00d50a80ff6cd547b74394eb4da8bf3a0338007acd5de6a2a1c53632777f4a85ad2e3b8c13c6c98283d6158dfcd7369d0d6b159345568436a2b97b58ca9c55394ed9f8afee36a10a8f1a66e4e8f34102581e30d55342faf30653efcbbdee80944a2292688c304b1fee10439b65db3bc68c05c5ce8a82092e4a5cbc81c1832402dac13c16a6af8d987264d48dc9b9f98b364103b114dfabe1f706642626d9ccda5db02d9424740de1f3095d0a61f72389ee892a01b08cfcc575ec86b4d20d98f502800d8d44173bf149ca7bc48ab80374d694e4e4ed68c29b82bf6c23d8b157a1048899cffdb2ba74a66f701fa65fc7f9d97f066c6f1756c9d098c768d01548f63f8ebd7a83b34cf0302b0dfcc8dea59ecd26943a43e64d2a59de6344cd8f2ea0914631fafeb871e2c2414130bbf2d1947ed63e0fabaaa4486a43fef28d6aab4515cfc23995dd59871b7887573dbcea098474165960258b481e36cbc4e6dd3185de1473aace4ecf77d63eb09e4ffaa7fa3376c7f704ca49601cf3dfb0abb5f5d5186e5765177591a6d3a1d6a705f738252b38bb1ba3de28267969c844c5c23950d3191982062008b87946499cc9a329cbc79088cd923813fb1f739529f24f1fdc12cae7c5c287ffdd1f0d5e6a201f8f464c0f4394b6a5decfa7afd87a9b8ee625e664a9a6cc737934a31baa3b1ff7943197aa5e68918c0ee52fcca028cb95db83 + +Input: cbff1209f9c383d4cddcf902e07dc780afbab61ae4f963ed2ea87e06e9f0c77be39b9f9eba43a045e0899a87a610a8f0c32d11e506e8094b6b269ea91e79b6c1abd00c90f3af7a +SHA3-256: da5a90b0747aa27bac0cda0294a5b4524a46069775e00d43900a5170f88c273a +SHA3-512: 61a8fe7df85215fc57234db4aac7c41f8be1876f7128160324a5f4c0a5c7105a64be79cdb7e67561be21bffaf6e55da64b3b3321834b4c18215c779bbfbad530 +SHAKE-128: f94b142d3299c018fb1b67a98fa54ce27c336cffffd9999a1b73a3ea9f6d90c95bc56a377fa382b31d9fe456b31a0872cdbfb5bfff696b0421459cf8465943a9354b4a9cbb00f906df2adc8257032307ce6efa3d70e27a99cbd5c684aeb6843da781ffc20d7ef2f28bbd3460065865877f31f8694e1cc08525290efba5c20e630572169ead9fe2e052049c529309e753d0486ec5f5c6131fe3c4eeb2dcf7fcc95f3d0ade91dbccfc02f450a0bb66103da5d95661602bb86755b0e62e1e68aec5507b7d5fd751cf0a353185b5bfde2b89e11564553a5e15c175c438394a013cb362c0122bd088c2c2d5db1fae5e2831cca6326ad885b76455d544348aa1b696eda12431b24e03ca02e21b681f9d051f0421bea719cdc5b2952517e2371a227b90d015ca1ac7aecc4963b777b246a9e04defbd743533f4c0353e92db10f4bf0e3bd35c3ee1d2510e3870f8e33274bc68c1e350c1249d3c085551f58ddb50af7399521337f3bd7c3ea4042bca7021a90b5f361d94d91f0cb9dfd6dca02986b0eb4970d6a707a3cdc8ed37dedfaece5bf6cd44e12696a8e70f5acb0dd896e84739cbe1e81d96d4062f745e98c2459e4b88cb5b371d9f6391c474ec43c42b920201ea31821c9ee675a068e4dc02fbba9cc7c0fb2c30aa80ce9a7a1d41ecd83da2b9029f0c0f20ed9baeee1a75b434c1db35996d8634ad7e7bd80ccf100159657bc527 +SHAKE-256: 8eb8f740662490fcba21b9d3ffc9e8fdd5927ceaf5288b7eb92b6c716cdfcfe60498ce5f70deb8598e3e43d17ad34f80dabbdb5cf266b950230f0ec5c0ffd28858d3a1b9e42fb6e021517b3d47d36d8c1cd751ce86433c3d219bd379678b518e52eb2fc9b5debdf13dce59edba450d0c20456b60dc5f513a12a533c872f9fb2e8d4c63ec5c28be79efc429b4920f60017c1e8c42c22bc592be91d66ac8eb092e85442649997539d06ba3e3173b486b60551dcf2026f266a3f67fc3a51add7973d7527e95fab9633ada3849b0e0e98f4703bd797ce1ab4c549685b3f6681ab5ecbff1aa7a91e088190186aea0f78c5e93149982a142ad7a518e7ab9db6d3d339aea6a0a971d09474cf97f23cf396ba54bb2311b0c464ebe238182b5e4ff7350806826e89def107b9204cb83df3974a31e63b2f8a8c820c36baa9c957f4ffe196674c9c5dd0917a650f803b5f023a8e828fc5fbe8f7c2fdaef1066e3f9d11b6a3b3b651c7b0207c27cae1899c1649f2592a8943fe7cc2cc1b4f70bbe7a276bd53e5d780176b7545bd5275ba02b275a4a7cfdf829f6920514bc02deb9eb993981476e8ee3b7846de0c26643e56aac8557c31f0cb5b8a7e767073e651c57ddfccf51cfe769e1c0761f6066d86534e3c2b33f2f1801ae40168294b014ada5a6b8956a0f8e81e8ebfc3961edcee8d5596f6f738fa89a0b151e959b546c695f52741773 + +Input: 91e6c2992563533da91c6c2a1546b18fd3aa48f1e601b7ccf3888c18a8c00efeb20999dc811beb2c09ddc11d37e0958682508c90f11de5e167747053129deb69d0d8594b1da009d7 +SHA3-256: 948b9fb49309ec0ea5e15dde14b50a98af48231af3788188423f82f16029b39b +SHA3-512: f9b1d8cf7de9d77623ee9c58028aaca313f2d5ef1e7e18766f384f446469edeedb6eefd93589f938544ca319f57f160c451dcd42bd22ef30e60a392767d7bfbf +SHAKE-128: 3fcf6e900f8e10e478c6076ecb2002aa6166461ddc36f0e4315e470958911007f46708ebd79746c4f32e5135625acd24ae721e9eb900973366ce15619a2ecc379ccb9ec2eb14e4f4ac96e427031a0bf47489cac3ace1498f4ee1772605287bc7728cd0148ad132d20f81e85457e6c86a3e4fe5ded3f322e69016430067b3e8b868c38078ddc9a5cb8f605bfa5d5c6cd0ac91921e43448ed621c6f6cb97b1ad0d411db3e34904285d19ffe827bdf56df8da879829ff394426631cb6ab415f2e8be8f45dc072afff34d4683bfd7f23f19a9223bb6a212b35a0431e00242f7ebe7ec0dfe1ad0850129d89c6b66c506f53a4b0c357e6a3b8a164eef9cfe256255253718a6f56fb518b0dde5166d23c5593c39ad4871f1e16f45f38b976b6b9ba8f922005c0bdc7ee09fe8d16bcd5be7f8fc84316e6aadb611afecebe9e20ad782fdf42292ae64cc8be119f4dc42d7f1b1e984c40dd7c8fd88b42cdc2a7d38fe68853b412b5c644efc10ef3c52a037779f31747b3d1febcbf2f8b19f6666aec4d6c8681951c1dd22f79507973230d1bd7ff9b3fd1bc3a00aa443ef5a7817fec7a52a1f584a44d72a39169acaaac0cc6274c1229679c052f47b02002dfecbdc0e5c980832067f024d4dbe1a44aa593f2007c1bdf2e4d11ff79062c86d8d3fe08b827a04d8f827264e889ecde37f5c392b594beae422ea3041c1918c35adef9a9f8f45d +SHAKE-256: 85677afeeb6b08a5fc06bc2a0e5fcc4bba23f7a365df3a4910caf878ddfbe6e6585baa75b5b7990ab252a9789a0fc3d10d136a0bf7467f640fd4eff193afd865cb807b79e292351649d713f6cc685fee05859ba9c64c3fd49ee4a88b2625fc42d03f670ed1bdd1aacd266f2a56264ef4f9a224468e2a6637f2c1d5d64c9e948cc5c47b791d595087f991f81e2b8b0c38e6e0b59c1ae60a586d65bd85c1b8e0338031878e1ca0f9d139f8436e483c8cdd73965202fe0ebac0209c94440d09754cbc099cd0260ef4ff0702f15b1166089a617e989992b18b923662e2609bcc06c227b3f87d1e327fdad07f0a5a054a3436d7d77bf787c658a9800552f98f52708e2d3b649d77ef2b1ebcf7cfd672da132ae6ea5b2d82f6bc7bbbdee2730116142527b861a2a0b6b9760c65400af4c1f8615fc935e71882428ebc2bcb922c27b38af3c635624f330cebdbacce7e4864f5d66fce20b0f9c93721f9ad1507ff664fbef83ea3f64fca38aa6571f4978f1022dd1341e624740dfcd3fa0cf304911d62ed16854a84ae7c2c966e2c329aef8188ab8ba80623f680ff859ce00dad35ff005b12c09068c31f2d95c68dc77416c932a6ce062dc28beff895794b1faa8b7bd5bcdb0af2e16c180119a90d7484ba9fb6e45b161df982d08a0511ec32846b58560ebdb071d753fa3ebbcc89d7a8b84148b833a81280739e2cec81a6cd812e05fb5f + +Input: a51c1a148b54d086361da6fb68964475428273153ac145532a23bf5889efd3e9a419b5384205ac381f9983fe6ecbf414cf302281f97e82e3e0a51171eb0df1d1b243bdc8b335368437 +SHA3-256: 9fa4cf24baac213facb18094c57732f9dd9ceff2b18b5056c2700d695b148a22 +SHA3-512: 88cd3efd6026f8045315cb9c56306b148d7f398608da04e5c830e34bcc86996cd21c76c7f3bd5d4d02ef14a866c0155002f53b7811d85b527373c9820b8ab117 +SHAKE-128: 6c9941a24023dca0a0cb3c19b5e7dc0d129b1d0cdfc1d90a0e11784de12d91ea9a61efbf52a744a4ed087b8c25282367df62ca275d8f17d3e19a2bf84773fbef44ed01009c34976d4ab01d410eef9e806c5d61da0339d9cd8e2f35ae70b3a661570e7ded79542d27a307e98388191557d367d9b8065c6a258d2bce924f5fcfc1702ba06fac26ba0e1a0165682d5257e8626660994048fad8f27ebdddb63a4be79b5bfc66f2bd30ac1bd99017eafcbed18a440600077284664a786ca23b59f5f5d4a6beabca3116159aa20cbd96e456665f11ed70a04572f3de560c29372156f84c68ba2b23be71b05446953990267d341fb0e2eb72e4992b9f1bdc6a841ecc8bb6c7bef8ed76379957b9c78d63d18dbbcad1d6a5ab1648a372b4507fcec95f799015996833092f42c836ab21714d138611f9cea5fb70f41f893df9f56e73cc19dce1f159f78d6d760705af3187facd745c2c4e39413ad8cb6487f7499bcf8090b0acaf7d30d29105221cfb6ae10ce12449b69227aa589ba07a44c06820170000d29d5013e89fba2468c3ea610e3f67acd9dcedd09f843db48da6480314cc22eedbbf832fb21d8018a6285be823f80f1f7979da31b75b6619284b477f45e3db8c54a6ded5effd439967dac15bcf03d0e0389332bc5758a231e0f5298f27e77827d02c43728d4dfd442624d6a17d70758fd786b9fe0b0f0fa8d525a1e772fb2ecc +SHAKE-256: 28ae05e3e7681924268357d3af54f589e08ed584335fbe3b97cc05386fa3b5ccce5a7e1746718859527a09b1559147cd03eeb8930ab3f0f0b45b8c4b0fae8d8afd6c99ab3d3b544287cf1621410bd9a476969d234e8f98d26d7f6d72f42806b4224c814cdbfed4f7a3d8ec14e7b8ad3f59128611cfac1313765955d4e34804ed8c4387e6f0f906a6b7ff08ca957256400211b0a726d756e1162d40dfded3e0c7f2469f6984761acc659bd86d70753d3f6a1408162627ef7893e2343ff3385171eb5d7fe7214933c6d5b8bdbb389e70fc967f0b073cc7fd06b8dcbc71233af8956f43bf151977fd54d429c88f4f8ffabf029ecbe3b38dea6ba71ebc67a878f87319ba7eb150d97d0ad8398e2fab16bf02d98d388acfa7c799f82853098cd15d28a4621a52223a43507731afb61c0c7a4e4503cbca52f318b47abcfbf37f03d5c36278763f27b0ff801f2f54fe8fd3398854d8b433103e46f0df48963a6c60986877519fc88ca69565ef5ec165ea0576552e195df93808279dca9516c380e796bbe22424a14495cb7a8a67debc34a30da5ab938efff5788652107716cbd8bdf6298c1de9215f952a8b332bc3e6dee98e9cf059910f2247f90842e398610385f69646da32d9c7a93da2fc68c5bdfa548a5cd00705766c0574bd6ecd5562b78f1b25c854df2bea2e268cdd354f5ab9da3cc349536c75325e4a68d243fe819f5fc60f + +Input: 40e3a3b001f88ff676059da5e248fea60b3d44e6153fbf1a84755a60f31ef477a8254844143000c3a9d4df9da73827e970f47c96a3c0827432b41a60e0f3def0bc1f4f0d94c186d76067 +SHA3-256: dfb9995afb4341366d90d388c3c2deb4bc9f4278fd1764a5360d081dcd7ad0ef +SHA3-512: 839e0cdc3e1c625d5358d75bbcf39d25791f720f98e4c87b0036daa719b607d9389e02ab028f88cffe2462b67103cee4cf71566193a5b465366642dce2445fd5 +SHAKE-128: 4b4b8eae8635c4751423b10ba08ce2a8de4fd6b35db0876fd5bc4f9d352c4f6a4abc3c2cb1dced3414279597eaf18043cc39e1198aa6ee5c7ead4a97b26d74c3cd54efacaf7491ca74200e68357849daad4b691fb4808c570f7c04caaca774ca70860fbedb2317f97d6f4fb6162d12834172d0152ec41a07b5517ed2034ac96014a45e184a52c065d6b9599d7b5d4e6fc011b53932c4288afc4ca65206066a362d1d52ac3edb0fab549d5a49f895943a9838dbd5eb36aefe4018a4ebc3b0c80d6b2687f4750508acf8b7fae95d8ea941d2deab112573e23c40f3f6e95f160eae039893feba65a05ba19c1983267ea31836394f5326184d251fe6154558a40c107759c7d06c04abda3b2ffb1b41f79f28041060280f51674abf4978552a05cef5ff6c07412b76dcaf1ef249d86d50cecb98f6064cf3911a26b5a645d1798eda7176d638d4802a4c6809149017bbc46eea3cd0d0d2a789d2bf926b494a757ddb39dc253e218df087243cc8714825ae6351f1fc3e1ccbcc7489204fbd315cfc3269d0ccbda071189c976800946ad7155ea35c1eaa858cfd72eef4a60ca47969f6b4b9ce0834bbd901c4fdb4b648f5ca3fdbe27ddab6c558a1d8405ea86dad5863ed8ef119330ebb1f87134b26cb44602ad1a1e552307905a5f21306bcf4cd28d0fd66385c4402df2ce0218b235de0f5ee1052217c586db22fdcf07037de90ad9713 +SHAKE-256: a1d0c6491012388b17e84f28dbd66be5408e495b82aebaaad263e011e962b8b9b9fe51099cae73bddb4e8f18a8ceb6c1442ff1426119ade79927ad794ea84d353695cc054d9ecbfc52a3fccf1944d8dc0893ebb4453a393a5625c8ef4cfbb407d46826b45eec94a6ffa5f8b77b3ba4d91e1422eec0dae50ae5e0f3d9205f69bc193bbf84d03f7f816a5c170e24273c242210db18933b47ccacf9189b016a81ef51ffc027744b8705b4f8257954cb1bb0241662e0176fe718611b3c5ac17f928f32c3956f0b8184b082c58ee94f3c5ab8578a979850f55a7450c5649b1e3f34c589d0b2805fe6d33a35e241590576574f5ce19135e4291a50b7329acc9f21692f33e2573b2ba60624abf8d7eb38fe5a19740c9569cca7a413290139f386669a59d77a4817a9f5a304ca6b395f2b11ceea0f814ad80d70d4c18ab87a43cee0ed2585779a62c13ec9df27efd4233d7c4bdd10fed212311053d8d27d7170bc1d1d6dd4e82931035248ec35a37e6aebc65f8f388a7143292144976ad4080bd5652b0170b33a9ad836d751f1c09d98eb488202af325baeb56631aa21159ea7af06695eafada435da14abc49d76ea48d41fce7708632724034c56b95658ac30603d1629950a65c8936f7dce93430664b6df3a5e93091d59d539fbb94effa79419ae89b200c3eb8898969bfbbfd2e1fb7f458fe08d0640bc0ef62ff882128e1cf89781bb + +Input: b7a5e0f41e801da38c9ae31a4868fc016983eb518da2264aade0884152637fef2991fe59447995929e068fc3c3d210f80ea7a83c370ed67facc2093f5c52ebabfc474f0bf9afe13873cb34 +SHA3-256: 0769c5b23c0c6719c2f11b1a4bb60f047cb418c6a0516f3a0398f1e853d9c596 +SHA3-512: d81d3eee1fc52cb4146658f48c03761cd7442bc8dee3500ad86531b9f482f900cc1d549a1319451b5dd4b2149c8696891951979e9ba8e4876ac27e9023067d0d +SHAKE-128: b055c86d79c6a5021f07442708a12277e1bcbfbd0630f04d65083bd0efdd90369a707e1588976ccda1779ceaaa72895161603630b4022947d0cf2edceecfb3c4bf293326836952a15cab46d745b1ea929687255b64172997cde05684d59c16c2d259658bdfa08ea149949b49b17dcc2a5a33592715336de67544f90e43b1522fda5f72f1c196616de6c07fd11cfe74842b23acd48f0e1aaf895a0caa26f52fefc0f8eb03c7da6895b1f78e7b6e312352ded22c38577244b865382bc38a39ad3f0e351f9f9c051b3d90b08936e0cbd6137150729928039855d17040ec25eeb0d14a93aebd7b4819cd67de76315a24b3fd3869e353747ef5c6f3d447a11028f7a28130e1285616ac46ae2c028dcf17914eb38a973566dff6ac57f64857eadbe19207fccb6f70334ae10f1329cc40f9560299ae79dd84e872735cda3ca99f1c68d86348ca1f5338d3d8c06ad1f642474ac4222c92d2e610d4960ceb69094c2700b87ce769a346bff372785522a3a6176cc435914c64b8888aac2654c196f72a449fa10d209488ce221f3f44c5f8a7bafe34d4d8fb346aed65973d4e29331e6bedf58f10e304fe8cebd371f24a28ef047a3e37e43e35db501c6821107d4e7e1b135681bcf7a615ecd565703346039888ad06dfe73b2756dd7c5b7926f47acc298ac48c40153078364e2ce45149d7eca68d8c452d3e077bf53825eb89acee5dca5da9 +SHAKE-256: 1b9907b03f4b2f536c7077928226d7d8965e2757c5853f7fa7204ba30359b6def28fb02645f79125bec9b96022b58ca837fce4f899ed40588e39b51722d1e429288d2f852f99f3ff137ef34300f2a2c84d986cf26d4c24aded54b8e0fdcffc25f41a1e8de54299c82992993a1643c884471a95a5349fdfd61fd8cf5c5c82378a2a373956696467275aba9b827c0d83dcd7a4dfdc3f0e83c8389a2f4fbe9df0e1e349f8e49a0c424155f13acb10a562163faf30fff1583ca60d84d890cd00fd8c3e7fffbde667233aef9308bd86a782f645448f796faba481aeb5331985a03dcae82110c4ebf1a626119f3253a8b11793a32a063db700255773724de596d473e67195c8f590b37978a8f8d0af4ca0d02a5da9da5a09f96c88d4d57413ac495916619d0fadbf43840f45a5c2d3d08b23dda32166dea5ea3e1865268b2bd82efd5fda7c576cff26f222074f8e5c44cb82896155e5d0ed5a82b81086a20c0d867c635b3078e7541832000daf2012b0d6125732bce889cd53727aee17b7a1c2182c87131a8b908148af135ae51ce88c080442bcfdc22706e819f54c6a678aba2ff3e1593dc74e6e2163c67e7c873ad9b7a0be9797024a2decff9befcd81378ae8cdbab21f9af7d6f874e4496496996d7211842f2b09f3321be094d0a29efecaf1f04d3450ff1c95d11ef9228fabe6859fe5cab246206725b7241330eb74e209764689 + +Input: bb9185d5f94c1dd0b2fe1c98d24d76a35d09212d01ebd46eda42abf0ce64c0cebf51df6cae7af6665b13e90dc3cefe9c64d55f5cc37e843fddcf45437e073ab68f296fea018a8b0b289c0b99 +SHA3-256: 55d1a9882bdb8e98a7b12817ab9030d78223853cad39ced49afa2f296634b4e5 +SHA3-512: ef7d22900473c916b7aa062a264cf1b6928cf2a7eed5b4c88ab41abcee554b547fbe726e2e3f8b22fdbfe51329873746c5f4625e9492305d93ea1e9cacf7e004 +SHAKE-128: 0d092affaaa0dd89308eecc3f6f511a9d742ba16b68f80afcd7eb33e5308ae1647c476ad0fd54cc731308482f4bd76e85f55a9ce3fd0d6437b6833c1010c786db2d653c16af814b5538ea64a8212d83ee80b088dc620c4e2601342ab17710d268e722ef0dce5b2e8ca73584e4008c7de27ab56d76a44193746838136bc6a62e6980decdb2c945c5811993e5875b92a3f8d38b1d76cc3f9cc0b832f31072d56a11aaf44c575121256d9a3696858068c855c19fbd0ade893e1b5298200e47681bb99f1cbedd4a1c73f954b4ef7d4d28786a5697590de0bfb615dae3892c0024349cd809778aaf001e2ce90f390f84a0b810dececad6a9b90492d55eead14f14a99a761c44b8919a79729d0a2ff0bfbd45fbf9091c784f07718a9e99c05bfb0eac934a3c7aa7f2c0c6fd4299189f37a03a99e3d0b2328d5f4cb89273374090d79fb8e98db0130a1528d1a0df937b5cd3ac8e35fd14d42290a275e6002a7b1a50b9c4e84eaaf31f94fe53ca91a9970e6f1abe081a298e3fa89bd664a690cf04393203f9c0a9cf194abff3a9399cf961c7e6ddd2f65cf83a6bad28ce8ed47dbdb80ba7ab8193ae323c9525d8658ea96a7756d9fe22575a01ae9b7221e01ad4612e748a7e2d716b57cc35d1d32ef55aeed18220333b6473bbc80ac5ea111e451a8143a83394d10fc6dae120455a314cb6961abb0e4a58d7e78eca8e37873adb97df02b +SHAKE-256: 60882c8d1b5e250193fc3f071fffd088bd73a908a797796327153ce07050382a6e29482ef6e3d1b478db796684a8ebe0d58f1573714ee2b8609be34838af568f175b2c9ae594e3b91513152eefad8badae58751f213cffcb6123287b70f7425193bad479a4a10166088a72af00624ddfd05b61a055e0791230550c8bc2181f5ebd6f68f757bab2b83c9be4708e3801e3a5d95aff0a90ee26c320796899a5e355fd73be10ec23c0539f16cdfeddd06c39ea53071509216de31a275f19879a7901ca82409eb607612d3b0a93ac348fec12c5e2faada0c1d59367a3d6e71785d0fb95f7ec514a890192fc56faf02765e676b8161b5bab583077d227452e52fa040503654a73f6bc956893e4258223e94b75ff3a64be5107b4da9ca27f5988af4f710d6acad9c2074e6f6ac5a2903aa8edb61ed89a995ecef81cdc825ed96ba5d3946e8e7502394f527671bd1f383fb5f87d2c386e2d059c9507c373e2e6942b13190ad094ae03af7e778769a84f7c387dbe76a81fdd5ee2625f68925af171602680cc6c022da167d9dbebfab079bfd215dbe6b3e753d00fe4fcb2e33ee42cc767cf60167019bdd3d0df5cddf2654875c6ed4864dfbfc0dd95c71b3f4e81f948a38be42c0327990fc74f6bb346f60a8f739b924522230df2bf700670f5001ec7d7bcf91023609e6fe3330aa81327c212f3748160581c937fa2d8d12947a28ae933a1 + +Input: 660fe039891d87e954d0102b01dc8c6bcb460e4bc177542f82cbd244b8b5e5d5ff25e1c6abf906884bba5b6807a9c8eda79d25e73994b61e9b7e85af43277376bfc3439ae53846a9c463c6393f +SHA3-256: ebbb154b6b6aebfb4dae2de18c85d320a97fd0b2cd72514e10704b9b614fc5e0 +SHA3-512: 2f4f8876da1437ffc80eb6718894b63f37746a50ba7faa4a24a56b8db1da6ae411901db1d2290703d0e88d1939306907ab22808aeda2ce313eaa4f9cb5de4665 +SHAKE-128: a1ac04a6dc71f1d2548288083437dbcda8b29168dd44f3af8f26af96f4ed5e7cf991909230ddd86641696fe72a92b8977d3fdbe9c447322e710bf6586a340d53d9bef84c27011a7576bf3a3b5d9f3faf3ff3b9d544775fe9dc0aef9b4d7f869e158ad8344c906ac4f6c5edec319e49c62eb5c1943d8ac05aa2c0c7ab707f3381142ed0b9bf1098be6b9d161c0ff760524aee825bd78a7cf7660974759850266c2d722b1add2ce63fdef210636c5c64cf55a90885c25a7e001274e47f98c3cedff0fbfe4f83561ec2bbb59f4c901673fd1c346def1b211737c12000fdeba0264007b37f0f205d72dbe52402d313bb127ff1d4c7963e9af5a47d65f184ea5f3cb7112eb3860cc75b00ff66f05282bcaea0e3c3596be090187c3ff40cb46e163132abf572a946bca781473743648ec5a0ad140d45f6313f1584bb52d8ea74c55c2611d0cfb9b89a8539b5d6d6114a6e14515ec6bd4dcae81847bcf99478dcb25ac9bcf5efc19d0e60827b1d311d7688bc35f3ae610b4aab6c604fecf7a93758e3b0c5bd8a97ee1a642c0964fa0d080cda8bda7a8981729508c51b44123714b4a2dff6fba94f5d6f9780757d93e68768a2ba579fba7e4e6f2b5604065891110e1705b0d96570c59cf2103ffad0623ef66307bde012d34f1b6452bf125566d73189202120bef73363e8cee0e826c2c8958372da550992cb6e382154dc1dcf54250766 +SHAKE-256: 6e05b2b1179ee333f38837ed76f7e16262eb5090a7f430fb119fa1170f740aa7eb7a112b9b4abd6ef1694a8887523e3504ff6ef056de45221f1d0aa88ebdd79e5e95bb7731297d778f8f6d470d2fb57a9400cdce1298db26dfb730f6c711d49378a0cb5b578dc3568b3ae89c40c0f357e1fb4a1c77098015ac876468e09af22c40262b38eb1fb380978bed6428a680c2581ee0a647c12b886fa66d38a1b951edab374ef74aa9a1ef4d9c02e52510b1f1fe83d5218b819983d7d8a02617db0d479569d9f3206f26efe5d78ec1f5f001f558e4794d725add528d2bc7d51bb4e0af2d159d050636864bb95478662092a55695cb4cbc47c1a2e64de9c4fadf02f38d75318f94f26d09fc87f92a0bf7aeba1c3854369e5da67435e6e3dfcd7dd9297e6fed038f32bcc108cf909bcbcdfdd5423511e903176640f2934d11428147c5b5cdf3b0fc432e238bdbb48c63612182cfffa84026137c51fc7b29b85dcd82a01c989221760066baed91b7ce70f7ab0cb96d2a8f170c2262e02e4cd5d7ec21bc3fd3c1517e8515895bf3442157ad3d123cbd01ccd0d65584600d97451601e33e8be3272f97e6cab7c21c19be48adc7d8ce840980a62014f6e1dd494958edd463bdb8e1f2a785d241e843d715998611c6bbbe8843f7d29ad21dceafc7993aae7ef9a279efe673bae8224f07a9b70c28e261dbefadca21408b83ade66f579b995f06 + +Input: 9e7e411cd73dcd42fce39dbdd34aba115fa067de5431318bfbd4005305c9fb8d8930f30f741af6d7fead326a8184e73aab8dd173c800006bfce3916fc1c04e186c7a0302842b1d5ff949b6a336b7 +SHA3-256: a27026fa9c3347a8be47e225664d17d4b20f811f0dc23c74685210f544a7d832 +SHA3-512: 328db541058bb39941ce7d13287733005d0181572cef3e8767e230421578c71e23a125fc5a17880b52a23f861436d9f3d735b9fd6bef3f244d3e86bffe0f6fd5 +SHAKE-128: 8a7cf91d22a70f75f24cc3fbf084d4ecae4d835a5ce4e5bbcd46a5e326a21c1fd680eb182018193ca05b846adb0323701701f6915cfd9e697f2cec74533a43a2ea65a3b03faee89cf243b224845bd71c0d5f4cf76aa143c2433832fa23c3b883bf7fb7615311af787b039d5fee4af2effa398e1d47531adff800ca9472ba1b13e10e370f4f058131016f35e86b932110bc8abad9ef63e8eed0c9c7ea0fb68540de4967d8146bb15e8052ef223efcdf29747aeed41e91186d255bbffbcb5f99ddbdd09a4f0bb95e93174a0200806af2eb6bebdb57a0d08ae8960cba6c5fbd5dc9eb2c70d2e9a75ec3a9a00c35e0047ee0f41108f4ddd9f244c142146371d7572cf0ec81504f4874ec83c579d4a92cd67580695149c1b8057ef402d2be1beb30f56f9e1dc037bb37b91b4c1da49644a0853fd8bf1d2667109a02e2215bdfe54f359d30f893331db75536d568d142295da94495c95ddf9f1e30f9ec3612c8cb3ecf8e2a767d18465579c483ce156a4cc590746b81265ac9ba9dff95873928d2e9c361b6ec2ed6d8822f07848f61630164acccaa619270587237f0f8c7c7bbcc35a880e6efc3ce02efb5c0da8c2db65a18d68fea45d596e80168c7c7d7b6ef118c44e1b529aa770b479b24dc6785f7ef4de6045b6c71e2de672eed757de9995fcfbf0b61d25f06ad175cdbdd5be7330c97944f3d53dac94a4e3e720217cecf5b5d70 +SHAKE-256: 9304947e788a2d843ac096642186816f99695d82c74a956999ea8df1671c556081b0b3898d06b05086d2319f24d6e69f08169c32cc11b6f6a67e7948e5e1eb153f853da58f9a2aa38a68f411b23c1926b283aad55557d56e7de8e532b717f26b916f9cc8c2f22a337ce35b934fa3e3e753e8d12432725cb21f178aae33ab3bf862502f255323f2116c840ebb361d2b2b15e92b04674486c4097759b43d1de3e63a07cfeec0e3aff2c7345e69fa3fc100f6d0265b4f300f423eb71a4005b262fa2ef8533baf1730fb5c399de4d5f7ad117a357ea5ea8277b12be00dcbe7bbf7be51e1c1c2b4f54f01b9b30e34df1b27c56d626fd8101d2c2a799a02a80ecf5fc6ea4cb1d8660a73a7dfa362297d15d6434786603ca31cccd98b009916294fd3b87474d8d86d391162f09da6551c9af26e0e2e9c72790c8c7bf63ad3f6df253a981ca5bb113a266701a962bfcb02fa1986b275cd98baf933e42ba3cc6907aeb54b889a4396eb401a8a0e68dab068cf42f78f2c6ee6a55609fb8abed4bb41e3fa55a6bf50254f007a7bc87f5be2117c803e2636cf827827c7d219c4b1d48376dcb8bb5ada0c282a862b238ca2f9417b3786dac6700c31356c9712f2164b16602754f36b868d051b2ae9bed67e673223f5a1374a00018eb1f10de8f4e0134e5ff976129ecf378640fc57ae859c81a655e768036dd1eee0d73d2cd24f52d01c798c97 + +Input: c767258594d2fe24eb62b948ab2672f89923964f17f6ce7afef074b52dd3de9ddb050be2a7db2ce893326670ee4ba2f060d83614c60efa7dd805809e550f9e8c1c709ef4e6209e6b43794940393a8b +SHA3-256: 1d9ace700005aa14098dad7d25509399b743b97a28f61455ab0dba8e7bc50fe7 +SHA3-512: eb6f0a9b9692b53314a35d231a91b007fdf7e8dd826f07b814a372bae59bb57112c6c44280b0a44080a401dc2fda30c65f071a69a182ab33568fd9984460d784 +SHAKE-128: 148affbd9ef3b83410a5213b4d00808e85c471df7380822965807e33aa9defcb825fb70e5d8d0267a787c2b1234332a6eca6e3436fdf325d620f51c909063a3be0cfe92612e5369b1c6f2a19b721c0104a34bfbb7a995aebb224b2ab20b98d18a85ec58116735c398077e1e38942f3e2af9604a2c47f95ad029ee15a9ef7aff9a86974a2cc468302c204c4da1f89a3c041176d4f8a70899962c0a8f9d416ee0d54cde901b147d0a8fd8aa3443683b4b4f624abb8907d31af361d00050a34200cb624fc91f64ef8899704f6ae4124516dd7c325c6398389f5875398d51532410bdcb2df046dafae1e8effc15eccd5ac3519bb930b56ff03c544bf60a79c086207e6959446f9ad4349bebe3794e0ccd77d88a8e1f24acf9e0f730c154ee42e7a582aaaea296427c5c1e5d932bb9f79a182959f780e92024c9d575e22b1efd225343188e713243698f4f118d76614e9a7a7b17276ada9b311949d78609444b3a331a16c110c984ff31e829896fb5b66f0a0e852af918e111a331f49e3db790f51318b05e05549bd697747b3d988c92f76abbae74ef3b3bdbed986b2bd7b772195281a5f48436d3032498d42dd4389afa4fb1e0252501289e53a6bcc63e05336b35911c9b7abcb8e0dedee6188891aa3b91a028c7ce2f98fc41aa50e26b4d85b82621861565c1c6000bc6836eeaa3542aef9dccf10a72039c355f3d89f8bb96895ca +SHAKE-256: 5fca527861751709c18f1b2b9966d71ee3ab417231e15e2d1a78ccc52935dd2d71d0927c957f69f7e08fbffff64a34a10defb149dfbe0c7a4a15d334cf19e2f7815e57b64964ac591ee04254de19e8ab59bea5ad0c950c18ab5a8f81efede783546a16d11debbecbbff09ec67019114155d783c925624e9725c4da44998b5d0dc8f9d1983cb72eb5c411f072043eebeafe8221fbbe14d74e1ac09c3905eec055767853fa663b091895bbd57ba2caead2a63eb0c4ebbcc5c343091ffa9b5a5f97dae7fc9ea34bed83a79d6096b7d9a883cc8b189eed475fb4a35757ffef085ee3cc334d987f4cc43a196e9f83a29c1fe6d88341ae2b98f6a730cfe0b7772bf23d0f6f8077756649964fc20d4f6be402c73296147489a4598dbf25cec4bb6d3cc46bd28669cf5b9fbf2530ece0fa9e9efe320ed107e89b99263e03857725f2ca461e3a9ea64bf50b716dfca9834022e85d74f1906edcdfe8497abe0b07b3bfd46b5b4050972b0dbd1e551969741e12966881e9177de152d652d7ade352879a726f478866ac2cf0a865e0b6938fb6e8177641213590c94403d3c5f1b590cd1dce65fd901a3bc4951ec0c98b5be97c552862d5202992a3e0c7ebf2b05036fecb88fcd3a5c542f728662eff7d96eaa9844c68f8a4f371bb2340585b63e3cbf52db5c4016e1bc1ec310b9b162ec8b004e9ebc613d4ce6435eefcf0b51e63cf8cea931d + +Input: 841c10102731b914ab98389beec42974e833af78537499334b1519bab5173e5e057de09ded0281229235d1d6f81794085444b3840be748bba793f4165ed0d918d2fe138b495a44bfd2ac071565cf8be7 +SHA3-256: a2a1cd48e5df62dd2a4a771cdef9d6081a4577ade325ceba377503eedde874e4 +SHA3-512: b7dae82620f7fbef24bae22d8a9231bc0213597930576d72bcaa65e9f060e3f8f90bfa736d3848acf579d1005de206d826abea5d7e1df3f7110ea5d9c111d48c +SHAKE-128: e7857cba05c7149d29f7f1e4e541f40cda7e0698d05bde45b2407e6c3398c753f507be861bbbbb89b64d4742b057bf5128132ce91da2d4b3477f1cfe8fc1421537340a2408bf348eda5ca3171ff145e1949a97006341ce8df8b2dcf4370077f712c867f0767aa2f778a28dbf47b24305887d07e81fd97582c59c6779526068d955b36ad6726b594e3c2d51602de57606c8725f04b43df09eb8baf2e98e508b4ea49b4d6e03f75882e1769d70026c28d06ed9bd5687c9627856b9e76fc29ed19c4cb5c78701e419379cb08294b343a3b8dd8a4a0a1957ff246471bc5715c79b497f6ee466b775c8f49cf9a46b41445434c633b877583539d3d24b044284fabfc00a3a6c234b6f262616c7578a5ea050a4ebc88d122525b1fd3124b975505bef417dd6fa2f55f72d47995e767b3f5d8aa4ebfb686d1a464968583a648a0ea2d6d60a446bd2e1046146ecb4e499d12939dbdc427c5dadc205673daaa6940f00b7fc481b3c883048b39565d8418fdab70118d112bb678f27bd265cc3941d544dbcd699ed4ec16342ef998b9b15fc54e6a66f405ddd54bd4b110448de6e2ba9b2246508c33e5847b5d2c0b90f3041fd073a448b40719840a0d5c9aeeb89d12929a4e6144f79715cbe741d1499f7f1bfa3987c92894be2e3a734187d13b1ebc35ec3cbd5b3f7a1b9da70d086a7de7c76abc73057b5468f378ae5ba83929c4b976bb9be +SHAKE-256: 96cda06cbefdc46f0ed5872d0a81322bcbd5ff2873468b9946b761bdcd31cbc4d20fab18d0e3052564075a24bb667acade85ea247766c4e8fc53f4b605aba9dcad2484a2d1c46837f82223d6e9253f9fc61dad368a3bbbb646c32bdd3f645d10868627a96147bb2fb7689ce2f1592e273d8ce8ef4cab9dd00647e7e811c4aaae9c524d980e9125218aa308c95e33de1924dba5e0a36c9fc7e2709be4dfbce341128cb9b4e6e3ef09329431e036e83287f050e07f92f0ff412aa69a5c1a073371a09ccce60e197e6df4e7157bac2ea07480a8fa82d9ed5d4b63d3465d9d0cb2e23c5b819152b5b366bebe2cf60948c2a76a17291691210cddec170777975e7b1606f024477e3c2be32b8a2d6cc5f6643fa447b436b7127d2689d8b63d8b7e21d17b3a4d105f25855fb6259f59848ded2c919971de25cb73761e3f865ed98e8215fdd887b2e756257f5fb0f4f964ef9774cb33b87a936b65c577a0bf453d95556a1029ae377d89a15573cc48aa3542998748bb5c1a8f9f32e57f6e3b13c6d88c602639a7818950e5bd208fbb1779bebd244438bd6f4965e29cdd2bad68f478606d4efb97325f949c704072fbd30cbfb46e022e5bd0e01dc5a4ca007c7c547cf529c9d3c6195de9e2d460f196adaeaa36615a2ecaf45bdda8c059ca77c9c4672f86934bfb87a8fb0dfce00e1bb2a02e892c359d2c6c0c17af7eaae309d5cb3be015 + +Input: d9becf1e7b37309ad81695eeb36db252a5d5e211cb7f0da414f83ca0b5b0ea36c73b3242f3314b6f93bc39da33d2a9a0db6499d7fad81f9106180b19b83cc734d7196c99ec54ccf254c9c6959197e2c5ff +SHA3-256: 9f13d522a37cdb1ab4ec69248632becb63f0c62658655d689d572524693d0f84 +SHA3-512: f2549804e34e2fb3c4874a8c92ea9acaf6d4088243978edb450e667359f297e47fd71538a0e6c1bac69316219382eb2da06917d506d86cf06b564409201760e3 +SHAKE-128: b9c79585fe65477159bc4b55dcac2bc95b173b29d90b218c55d01c9c381c410fc221fcd872779b7d64395f68c0884a5da2af57dc48f3f5c02c9173c4fe3ca45c04bb26a3ed2cdf0570a66a4d9e98cc0a3281fb585558e4d8975fc17eb6147a4b4a54fcd8ad6fc067070aa77419fcbbab047e585262da1eff76e503fb98d153015d01c8b299429f08e21072892682c252f0034384d71fca0b4c30116cc72fbac0d825f5db112a97830cff6c8373458548ee38c269320728b759ebb1894a50d580f56f8a23bb45d6d8e5944c30d3aec5ae713ad01ec3b57cc6609da6525ae1900e6fa776fca52aa234da6712fabb87fdab903845738a5362133e464c2e6d78e1ce2c9b419ec301885173e11e08f922e0e937f6d2b8c86b5e5d09ea4c96aec8bc572a6a86cfc77d37e204b954e14716c26f6c492d1f09d208aa7e259c850e4548aa7147496a90a39baca85bea414167c05af60246927567e31d02f156c97b0b86bfa8b3832ac10acdeb0d2d119985a63ec53b436ba5943fed268b4ee4834ff0829275afbcabdc371d6da0e6e16f2a40213ff7d4851badb7bb38554ce2018c3943570059f6af19c699d353a6e7f3a5e32cf3934649eafa0690a964a5630b9d4cac38fcdc00f37b29802f1b8b2d1b3864d7cdd0cf85e635113b71bc558172fd66a7f5a01bbce42b12d33c5a38f6292e3e74a3bfc6bef2f777632600329fba507842f3 +SHAKE-256: 48db6978546e8b173007446a686e48977751ae724d4be05745ad608fb0e1e93e05a24370201e92369f03206c398633953f5ad865b9f7917f59cbad9ed40dad7ba3de3397fc1a55d3931fc4b45657727167dd9ea7d24a317427f0063d95caf29fed04f1ca2b2cce09fc348cf20bfdabe066d049de6320f8e6e7c545e87f9058cb197d71c45eafd0f249121d4049fd37d419c7469a2d591ee6890c429c2d51768b0663687b408df38c5b7c8bf653620fff8601a8025a65bb32516c7b3655e92faf3297633b25ee55168554585083537505db84ba8f815205cc804292dc3eb5c054fbb24dd7701c34c9a757e117304a2c8c3b54c7c37e0135996fd8e0582ea10ed61e0fd33573d86e24141a4b2bb7a7a1cb6ff4720b8a3eb1c1c5c4c2dec62bee460094165b86b5a46593401f9f2a97d9327215f113c7163d5e0f707cccf283b7b46ae83caf25baa2975054001275a858b0c43123cee11adc04eeda963e88cfd0c2a1bb9dab1d6b4041029358c49d3cc5357ff4ec582f47923ffb9fb13e41cacd63393b156ed1f8d413c60d4a357281dec33a1f0f9bfcce6c3051178e3e074888d466b0d0f5522b170143cd6e5d1daebba3f3c531856f58a18d14b5735acf52efeeb4a1b666987c72a25b0fb739e7b5ce3fa7b5cd0c7c853097bc811c81d23b356cf462953ebcc411dbef3aa44dfdd74006ef9d56bd6f3b87652e591e470f2fdd5c + +Input: 8266fcc5eb3f5f41f7cb430df3a65d62ef90319c7ae2332c5d6169cdaa3a68b1bda548af443309faa22bc23a25b382484d8d90586e5f44f47542ecf6279f678a16315d349c1ca6b8ef6564249f6f9dc0ff97 +SHA3-256: f5b571e20ac6c48d570d656fb8400a8cd56f24d882bb269afeec0bd5aff0c0f3 +SHA3-512: 5d99d2dfd4123381c029424cf49dd9b3327d9d5ec59d88bc3781b63992508e1daf58787adfe1a36595727b6094cb8771853521c8c8c824ac17a9d70dd72ef936 +SHAKE-128: 66a8840e0613700fac4324bf8d81b1a740cad667915ff93aece787ec6d6d1848daa5ee3eb4b34107dc49f65a273d921d202823844d79ccf62d43c5f0fa2bb3219cb67784826049c5e14d9ad9d0af09d34fe7d8c2519a587d6b92c3d108d8983ce7a3960a0a7b538eddde3bb335c9f2b3b885a4f87fefd635b9b24ecd9fba4a5961e943233ca21e3d8e2505016eb60db2c4f3598eea7829d33235449f63c6409f66a7f188838191b385ba3dff11566732aac53c60c66389438dca7c9f0b1f2f25ac1158afb18a8e351be6349ef14c78499e2ebf58c319a97a696a8c9129d79e94db6c28e1513f58a375888ef8aae3e49983c1c5552f578c8331cbfc7dec8b69721fc51b37466ab5365627341495014d08f5b8e14d43c22c90238daf77d516ad11bfd1479f0308dd7187637bc0487ad64b6df9dd10a6618654da3e0d34b90101933a23235bdd112105d52e6d125b44d4d4849569c075716ce6241d00977539d7998cd8f892443657ab9a86056cb161ed941c934d8c17f46fac5301240f61c3510d544f43a011f5765fec94ec09860e529b27f0c5c1e8e5ae7dfd504f8ebbb08b5cf741f60deac0feb16507e178131ba877665ee9d6928fb337b299b87c3bebd213854001ac0592f390a140b05af44a50f136c7a8f222ce76f3faf673476cbae1652ac67c3ddb8ef81418a99a9f72e05790191c9c7d1f550e0a1d3d00fde4159299 +SHAKE-256: 058ec7248d8a973e190c505b558abf8744ceee120fe2c59263cd5da85d1b27a99649e379dd2f4b8d860b260bdd90b4bc3b58c63bc438cf6493138e97aa6a97a720a1d218ed666616588641932e8c0aa0eb6e5b1f581718e1a401693c00972258e9a9c49ce8106292f55044ed0793b3afe05dfa99ecf64af94cc38f8c4262d866bd285d8db805d3fd38b46b80fc66bd9c36233f87cfbcf7080ef9296ace7174b0f6564d13ca55d1f868eb6c5087a648cb2111001ac2c280f2b87de3d33a2643018856bc4ce7123cd7e569ffcccf1805a724d672ed71b13ee164d182d75832ccdddd65aaca57fff3adac4c218637cc6f7815e9810d6cac266deb28db3e151cd4844d749061481479bfd3034d23f6ac90ccdcc3ea88b6ddebd18b8213f43c08ddc95f410e8dcbaa6eddd9fc7420b30e157fbb136aa92f041311ef327ced8ae0c8568d0bc2817c19fb3ee6462cd95e4455839eb2f88205231d23cd098b4cd4db4580baf53e5c5bb4eb91548ea6557c8e48c2596c4746b220690d2e3fde6ce6868c869f30541df21b3d6ffd73c10db9650ecb1ebe2ce217fda22ec763e9a095aa7c93494e6fc239224c55752191c010061b55a80a4c6a4a61dfbf6f977bbac67bca554b7e010ee4326bbb5cdd103c6ae2d0c7c6a8d8fa9d933d22cefc372cac74fdcebc57c8371c7a604fa9978ba14c668b8dd74f6299404ccb227ae3a52b6f47277f + +Input: 298323ab396aa86e3a4c10d06a1f47eceb77bffc8d03e51082f1343d3c0c21aa870703b909cdb2f446edfba44b8967816585fdf3a512d62e56f258cabb4fc50b326c116ee0ec1746d6ec4be229ecbdb7fe9678 +SHA3-256: 1ce273944d7da9455aee7fed04bd0652c20c9b9cfe92f93e661dbfb3f44623f4 +SHA3-512: 98f11eef7d02242442ece3908fef59b9625668f21fd582e31faf18a10455bab6e8f69fcf36473bf5c7da777fd537e8c80d10e4986672153320d44743600994e4 +SHAKE-128: 4f603c1a60160d3bd1f495e2912b29ccef1a0d6cb0b8ac5e744e4eed433f309bff039c70bbba98c5c45db47315e3e696adb4958f975e85d18b4ed8cee52b0ef24a6e2c692dddd075f9c8f42ab145e6525750b231143d32f10196993520914eeb0df635f3ad460877570a2e81e3f90b9d2f35cbb93512b54151171e4d3f6854706c76d9fcd0c4c074d8aebe66c045f3b303f4cd50a135bcd4eb96ec56b0f8a3a55f36e8a3fab2a0879aa198993ff2cb2dbc5b894a96cc624b7514646d078fa1376f4dabd78804f4b1e2c7c700b1359fd62d7ff1dee7f46b153abe58f4ff900f007a37f2c01ac570d08cc545053afa4ea7b632b0602c00d269998a019e8f9b4f7a65ad40e45f6bc4c3920fee8d87e4c750cb0d19152da0aa490a4cf41c4890aaa7ec1c3017fd3ee83f34cbd6d69257681a4615defdca57ce6d73e00c442ca88caeeb4e6170fb5b6aa2ea893f4d0803649840889a4414f1843de1c10e568239863bd1563257abba5d1b540821492321dbfe70d650ba4c4e606a4aa5957f731d2eef6fa5799897e54e9e9bb58501a50a5471ffaa377c9dcf4c35dba59f823cceac9016f8d2755b6cf7a43ae3958e50fb8d1674699c448df6efa775e6a1da49da1754f522b1d902c19c9b2e949a385006e38c71f5518bcb02675b32301d48117e72eb97ce8e59cd1584dc0cef3722a034814bd39a82770ddb14dc1123fffb21e5b7f2 +SHAKE-256: a1e7c4205de1636422129e772632198bc56d96a9bc66658ac4563c4445edd17c7e0acf50f6997baf1bdb84eb7b0ca2770883ebe4fcea2085a5bf2f15d7b226d72c3e7a4a8bb128ee4401ff2aa909e450ecc350f7133cebbbb7cb5d44e6388dd749424f02d49e707c5b2326abff0cbf3e72b3a196dda6f513a8eb89d13c1066308eb5918ea22d2da5e87e480ed9a9fcf91f6c9e1774a1df9c5a8d107ffdd3bc6098926b4c868fff13d3baea829734f15440d465473f62e64057e707491d0230872503c383e744919853868d2a3153e27c8ba3ef09f871ba048b7bc45ceb3eb7212bc72a33f2abc5deb8a3961c1552fa6f589158475dbf45eb9b871d6250d1d826e8b074cf41fa6cfeb963ef6c08d1322a06e79ec7fcf3d59323c234a9bb6c2761cef5f2505e830fd249f0a6698eeb897076306f4a6af8655c912984603198d5e6387cf20200d29f5e0b0d763a7b4605490a1a4797e09cada29c533213171688d1dc87dfc5ce873337b71d6179e7568589a306a4123f472b285c92c8243e374075ef5f038152f96072fac7b5f90e034589b56b63955ab16c2ed45248e2590922493b48bcd1a984aa64d0d3600c1b7076e48a7a8acebc689dba2e2575fab54b3f5329d3e682d14f8761e58fc9f254c00c5570690ed4ff1b7047b51fcbf29fed053e968020bc579817abe01233056e56c0abcff27979044ee6096abc27247e43fbd3 + +Input: 5984e119a2af00c1c1bbb47bec7d6d60fa95ee0db721afcaee0ff190719de9058c854733bee1e392afbc1c7fda4d22d6a2a3984551e90fb35f9a05fd9cd377bcd73b1eb0745a37926459c3407332ad1ab36e41bc +SHA3-256: 08da9a98371d8480406619ef9870e20637c69ac234fa02548a00818c12225bb7 +SHA3-512: 345bb1115e9804292a0891e53c0d111aa2ba988792f6d010c49660e328fddd87bec535183cdbf41109309b8eded23806c818b9830a2b5eb6197af39d663ca707 +SHAKE-128: 9f9c80a7d10fdbc9ef7af847e0b876accff1880b2321db5e52a51bfb219c03f98db2999b8015746fd7a46c812240acb3a8eec7fcd5411f5849fffb89667def36904d9e23581f0851320841747945d17e55ff856e94fad2dc38baa777399d198d9aae9f1bddcc641af323a477f1ca7f0979a658951735672a99f9d1a0d501c652bf0a65c5286245558ebb84dd4cec4f6b329a7693e575a1ca43b2f19a1a9e6feb0678cc62f5080a65d89baa2cb08c93cdc89c2b8d16d069281c0912713268428f7df0f62c227aff943e301bf5056510e8caa7c556a6e1729dedf042faabd931507dbc5ed38dadd29a7a9f844e5dd3773caae1074e10eaeaede69ff4a1572f4945dc3ed2992707cf5e211cc3b02066fcb6f4dd241f29bf513d5d50a9b7470fb88d3cf917540d9037ce9fa7853a5129f33970780a1b4bfd4ddc547e99c5c1cb8209536d386a1099ed2f3378875bb8b788c66f3e3781ae452086d2b122f4fae5a760d16c1962b476bd7a2cc2dad0a47f83dbf2c4ca1f5b2cea60546bc6a336ea28838f0ca7bf3ef6a47d1dd516851a210eb1f5233044c75c38b5b36514226c219ca2061c1958d3f17659a3d591fac4f2cb6c1dd5b14e58340c19c43786fa750a8d0acdf322172030b3cd1862562881159489240e43fc40adcb57f8b1f775b63f392ce8308b2e5c25bf3f06824d6442d454f1454cea36df8e885f857971ab952effcd +SHAKE-256: c137fb1b3de72f8198fd405c5dc8b5d0771517cbc43f019c872045f85acfca90f4b3f67757218a287f625864267604b9a678edea9ff8e66b71f9595ae92567c6c830c8c238b3ab759346f82ed9bf4241d67c39a465f2582ef8e0dc5fc531bdab6d83abcb2d70360343b1e3979fdab489c504f69ba6584fc18f26f9ae4967953e511b0990b907d0c2be60376fbd368732c0d056c6ca4e14946b6d6b08f2cc5e326f68a521b14b6c07b04124a2bce101b9ab21dc9c73a142197c1817991077e659dceb7781bb0a7d7c794fb95f8179e54537fde724f782dccd862a09eeba5d291e8138fbc6c74233968981e0afe8f88f563757a279a536c3f39aa06be75f7047494f6b4e49965b45f08c9217f868c9aced53d5d2989de55b42d625a3348fa1e2600058d88bbf6bf2fed20b52a9e4c5ce61c8774465f715ab70685292640a61be64294e142aca153ab0525e77afde384a107e4515252369bf6c9c893256c9cad2ba33a96eac126e6ca0ed58fc08ae80f88dee095bfc3914426938d203c739a7c7e99c40e85042332542c9825e520f41ae89b96d83c5be36094e915628fafc57fd2c2b5c63bc871f8e02957f5fb859a485727f15ca47826d0d71ae4a5965ed3c9fdf4c0f987091327a35c868966a1d9a37c1c0b278d067b9a77ad4fff7e465b16bb280d56fdae4a98cc0236811a7a2f35a3b09d50b665f86f76261b11832759fae7f + +Input: 51c4a33da38dcd9a81d67e5c5ad7d471067a8782ca6d25b79945f1690ba17372f72c716241411fdf61b134270536312e0ccf1d827f60b8a77a5d1035084180994ea576339444f054e90abb7166c5848fd6c27347d1 +SHA3-256: f287cfdf0d4010a0e2eed87dc8e7830d49bb8c3b86a1f1c09abbdabddebbe42d +SHA3-512: a381a1f9a5a3c2cf3480e5a33cbf32148f8aa4f04ba41bcafa75a321721b6890850bb8cdd94e7d8691541a65d3058796efee022b7cc15c600254039b7691fc76 +SHAKE-128: 557525dc11ae6b2bdadef053e23493d81e48d204e911257c32792ee10508297e975f6f23e1397336b255e154e01dabd680165348c6e23a6a098552a10ed03a80283c5bd6158ee5a8222383c36267f2da576518b8f3b7af0fdacb2be74aa258fedbce179aa2d3b83b74e8fcceaff633ebee7e426059bbc0443071059f360db994fdf933c1c65a901007a9668e0679fe68d41bf82fc8492aa167fdd08761268a94fd8872ae62755bf1e1c1846bb5146d6c7f41d5db6259c5cb9f42e4fea6838dfe9fef6c5f7c47ce97a6622eeb886eef263c7b48347c8636f8ede26ff849f30ecc827a05085d45d51057875c8f072a00fa10eb5ed5554a5310d93803d4c7b7ff020660ae1305ff97639439ee284471a0c3296df5fa2c292b5c4966531ea272e19ecf87ff714a409ead7f7e47306afd948faa667b0eeae844150cfc9193cc0f63e49ac9ee13b41b58275c7262d9e1c283731f07996f7f71bd045a9c63e2b4439e035ac2ae93e0fa2cbbf479daaf0456b8c664fe62ab60216b158cadf223d69eda5f2f35043b727d79ac5c341ddee0df202191fc36b865d924b5c21d4aa091c146cb7203e551884936a5febe0dee42bd79310459fdec93cd09196f0b9faf86d0b3265a5f0aeb24f5be19d1a99e980a5a8a292f158e2ac54d168b49d6225c8b67b0c8732f834258720c337c828c20640b6976a2504dd87b528cc0faf11dc79d957916 +SHAKE-256: ba28bb2b3b6128c1eaa40f7fad34e07cd9a58a7c219faf7c623987c202ae2a37a09ff24c673deef4ae0228b2cf368f5627657951c1939732fe4262ef28c1c096ea29853292dd64e3ba01f33ab257ac7692570dc76efa14cd5e8a61ecd752d5efcc5c8eb66f23f9eeb9e188575c205a396d54a60b0a95bc725210dd4046a6638e30a9949ee3eea7a7e2ce98490a23109fb8b6b08312696839aaca3ec790ffb1553a0edfef0c9d47a6ec90de812b70c631fdc68bdf65d4a6e1ad3a136d852dc881eeafdcaf05a6067255d512b0f86441ad2d375ba2f78282ad2e45577795906e5fe213dfe1c7014db2dec266ca893b42b90204072c55ef8db315dd7c15f7a286126de1b598bbae239c1c1e6e07a53551768ddc3398e9ba464753044a660cd08a8df670deb8bb4b7e85cdf903d1bf09f49123fa07aff19d804a24e2663e85508f9a575cb07303351f18814a1c7d98f7b68cae47573e4a65d12c671137a601aaf70f0238bc3e850e569b42320b48c132a7da05b7b4bf7822ff3c8ca41699b7cefa66ed3ca5634a19f976a5da041bd5d538813886ddc3d984ce8857a1141be5a74faa7574eb355eade42323dc30cbe8b7cd5492efd8f1ad7a36fe4ef1a34debe44f594fa2f6ad18e5e8e2bc43f109b98e9b98f1068218be13d9fea875766064f22331d85387a5fb593b726ef902d50328a434e75d3c03b093be3e490ed0bbcf6d7c26 + +Input: af5aefb61b5938cd55aa7ef696ddca26e89f9438ec35afa4e0c49b26dbf169dd6df7ca5a3f02a35a7c76ee9506d322b1c8f9399ef0e84f10191fe6c37ee25d57d1a016d0c258297c35f88b3f96531e0f29d5a3f8fe00 +SHA3-256: 901914cd3c43b94f752fdbda8e8be676c492bb5ff1b259d129ecddbd013af284 +SHA3-512: e7dd2e33e60be0d42b12c8373a36fb964b7efd01c89bc854dc5c50431d8f7edade2605141b50814c39e5bca6c8a6ecc25871d7e76868c8d77d2d91bb224be259 +SHAKE-128: 0c96a1f92e5207bd5b0f737c4fadfb150f295149c7d433a6dd8a2ced262ddbdad5647bf4db930e4462e1a1d1c192f48bf73fda06f6d73e3487b73e869774052e7cf22c9a3619ae2a8b5547e5231ac1528bafdc56b27cca3fc66291f135258a7a2f9a30b2684fbbb368d513a6046c50c5846bd2d260cf0d37e75c2d3b244c39667b3df12803a4658fc89f927e6fb8f709d14905758de13a902d0b39039c8ea6cebb65813d211fd739558724e0b57be1aa272a4e3dfef0d90396404c52d54cfea2dfa8a01a36aa9c152891d1e99e465551c78e7af69b5363819ffe14d4e33e31d99182f250ce19a9070b12ca106a5ba140d2ccdaa111db057596e399f2b18e98faa6397e0cfbd538f14d6271bd9834a3f7b17b9e97fb44acef5efffcc68d860378bc4c0446a0ff90d8a4ec0fe044b7e248f5255f185858f30ec20d12b7985154fb4ac207b11b9c465705148087daae1645cc40a2de2986ea766649523673c8cc340a4d1ef3edecd3bcf13c20c868b3978aca1835284c07e517e3446ca33b82f1984012fdeca395e356e205febd0a962c1351794b735355fafe1db65b40c222191df06c55b7676b6f883136d2f273b048864c75f42efc96232fada93bd3e86b41cf318968b838b7fed32e378558067470c9f376d4abcbabcb4edacdd1dacaf17addddb287f86b6284a106b333c6685e84de826bb0aed18436a9465ba564c6d1bdb0 +SHAKE-256: 7d52250724a0ecc27102de01f447dcc5f8f880b5c63c092d30d0b4428afaf236c3efb4db8d8e259b98d841985311a4c1b0b4569d43d92293d10df96475aa16fc2f77eee4488b1137ac155c8b86e2e9cf7f856b3b9be1e39fbc66ddf41ffedc0727d680651ae15c37df874213af12e8c2639af4304a8175aceedb90ed25a857092a90cf06e7f2de31f55586a322bf3cbe1838eea3289abdeea9863e63b8008f7178a9f4098a87380c2465577cc21a46144c84571c59dca710d31410e6c16e46b997f12a72b4558f4cc44450a05938e67f1b2223eaf49a067d173c7afb963ae23d8d7f339c2e104c4c8b54e1f687f8be775931be8c27a6afee239a2eb1668bef7124c6d533f0db0324c12105307c75835a6f5a8395222bda00134b0ad5ee8b6cb646c1128c5cb1f5ab56f7111a89bb647519be4a2ec26e58a0429ab6b9562f0b900cbdd0dcbf89137e85e10894f7b0d350d9f365ad93224c16c973228d95e40b1a7f5646c629bcae798a72a89fd98fbe4d002d15135ba1d6b31f48a1e80a581fced231cf8c735774423061dc393f011325dece9bf8159be64e7e0def54b696519858582efed05370682ad19b1c393cece3dfb84db80395b9d36efc73f3c0026eb2929c508f5a3477c96fbffff94b796f67844b7ce7eecdd0b601e74021f7bc5642123f90da2738d9a8760e5d22070d5e069ee51132e726cffd2dc1502a1f9486c8 + +Input: 587422531899b69a4210335f71ce016d83172bc0accc2a66e117dbc02351d7f98d0723e04968862d77398d195fae5a52a5553af85a6bdadb292fc66d040cf74c33fcb8cbf7a985d40a8b1a97b364e06d5a311f4f3f074d +SHA3-256: 745c6840143e4fb44533ed5a288599c3bfda2518ba76e2df4f816f2f71c5fd18 +SHA3-512: 2c19e49a0555e4c2739fefba00fbf1d31a9406473fc22f632467934fe242bfa8c644d6fe9e419fbd4f3e51ec89684718a351cfb73b9cf0e3cb85e4a9dd2ea2df +SHAKE-128: 496380cebfd7b2ed2afeee85c5f34f66e30d553ce47b1dd241620142807ecae2c96c032ea36fd74dc2a1683d68ebb526bbc2adc86c1a3a9c5bb0d59ce547c3f57aa5f750028ef4f65dc6bd2c9df4e3aca166c6c8ff30b9399841e14c380c9aca0d52ea494fdcea22539121fe4665f5309e2e8a18b8870f9cb16d36f56dfc93b97860ee991e0e1f2f898a70448edda7e3d17e8f5d6eb46e04646ca8fc35e813b3216c8cf854507f7082b025ca33d95c1282b7ae3a40349b5ee09a3f6900dfcd59f761b7727e9827a368dbd77a38d8757dce7a3f79261c8463925991b45a05e008dcbbf427a886f0995712ab30285e24d216a39b0da65df5273f78af071ed287ac01e2f2784202724f5c3c84545b2dcfa9258a83fb960b50c87ea3a1d895af20abf53c7bf8fe94e699629f0b9a874cd3203c7bc477afe4571b4f6c582429ba3f551708c0d63813e7ab80b2851bfc7472f5647f9f5c48fe776205107772af2e8c80a7dd7bce1747a3c010c8494c1ff10e41ef5a8b6b7f3d8ea19be74c92b433f0be43f469183678eebbf2cb0a5ebcc932d10cb86999cf8315c887a7613c899a0a2fa953a2dd965a21bb89ec202426b241337aa0df69a0a3845796849a9f988651d9929effaaa5193bf4d8acc08c6dacf8172ba295babf565bfebe9b11714d8db876ab4cb679e801f1d056df3577950ea71552070dd93be1c9e3d755022c22f8e827 +SHAKE-256: d748e4469dab41a98e31077395480aeef613551061c8923e4f8f4bd3ad6792d2c3c9431899da77c57b9d207812f1c9df9a13307a884f0d96f8d31092b4abe74bfd2d1db255a82f65f3f0dce9dd4d4fe39e5d7c6d77b1737616ae463d2b9e67f7bc0ef729e3f834d1068091a47cc90f112c537e82a7b1266c3b93e671087f912a63a05b6b0c6d80cdca232e14218f1d8d71079d307861273ae462420a7049fa3350bd40cbffcf43012e60573845a1df2431095d76d8de8840b4fd87e33d49d10713c5ade6b482ae9e0c86a25b668a8add1fbc3eb15f2225914a9a5091127d835a6a9efe874b08da73ed34d46208875d4d592f9cc2bb58e9b15803e4c7fa0e3ca6cc34e950b22938ac54cf788aad8ffeb8211742d3b668792c65b086f928ab91ca38c28fc8425623dad5b6207aed0a6318a31b1937c83f6e1620726817b8319523691931e05b0d0d5c53dc01bb3ec268c57c2cbb2d9d5c9a5a1ac91ab7210aa40c7e2f91abff073ea40b738ce3f6d7708467b21fbc047afae7d7729925e6ca58f29479863a004e3b11c36fe22efaf67a021320c04778b79e5a3eacd9206c4401f7bd61ec4d1caffab5b9a801b7417d095c45b2d096dce4e1b797fdea1c95b3100ef47210b49db4180cc26d6c29a2d41c9bca93fa3825fded61c3569edfbba127f76ce00f84fe86f6361d688206caa841a90c1d698120dacdeaae646c6f1546580c + +Input: e1ce4dd63d0da4e12cea38011bb478d02c9f338ee93b44374540ed3a4eb0dd27aa66b5a7b1ba4ce921a8b0783ccb2736b1af28375ccf9e549cd33ef34ed36762253064b8b2487bdb65f8a11f27848334638eea482b2bccc9 +SHA3-256: 5d8f48bb2981b33f91a1c401a6420940d3b9ce550f10f9739a14fb08dfc55214 +SHA3-512: 2accd26d6364cb4170df06e4964edb21d88fc03f306630c44811f05960d8173e0b167b26dd5ba6e205ee59429750fad81fa5eb0da0884888f46b41800de8e730 +SHAKE-128: 247230813012a82ff8b3bbdd6a5992116bd770dce995387f0ce97c6093ae60531e43dd187eb071aa44bbc324e8b49d8a998008202669e43b4596a4139e57715508bcfac38a324ff664a289246c3a6174d58fc97dcd3525b173454524cf836daff7fc578e066bceb28240b56e2d92f9bde7da3dba90e62832dc0550a298a5e158a501585475afd0579b5414009d977827c77b00bb612d02858b176df93980ac2fc4977b41110a84da27d06b2d13eb39347e106e3d31a5a174bfc801778e9f5bd7b109e354c76e1d468de7919108d095040819ae6cdc77d6bc2f0a1f3d3a8dff1f40cc3143907a271e82c78f9143f5c90fdb3dd90390d60af99cc9fec5ceea413c667a225a2420d42d671e60cd2ae160509cf2a6e4fa6d9bc92955a3a635f1d198319ee874dea47940274e84b3723581f3c4fe4649e378a43a012a74122073313f8bd405484e26d46d19ea7713866c9696f23784235850308054c0ab40dd0c5af88125069b36ebf06717ff1eaa2bc60fd3780db465f59ead5a35382b7dd567395fe37299f8ea13148b87624530a849c2131f77ef3f4696e9db1845c4eb50ae85b44a428d1f01f257f8efaff0524807065d4859507f6d5927d117fca14baa6a70350cbeeb82b60d4499c0ac205a2ebceff921672e51bea674f342734ec04580ef53665aa24003fae748332625562c444d5f3de9a6f390c0e9635211cc998c670d5f +SHAKE-256: 14858342ecdaacacbf11e359e835cbcf58ea9db1f1b0db9581f9c7664c45b9680f3efb9c73ff7c6baec27f8be31434995bcbc48f720867bc41dcbcfc5a55328b57f6776f3433187d2ac668cd02b471d5700ba0a5ae75487379422bce671ea8599e5ab109a7bbf3a783ea8bb09d52878260f58dfa71b54e42e23a9f1618c45e70bdb7f6507a03a59c177142cc77b59ea7e627a329a0edd2b5357f194dee695a5b5e660ba886ce6105f6296fb3cde595a3b204c543d20795aaee7799c8fff8b526f8c0c3df86aa6786eb0929d21da3f9a6947fd50f2bc78bd8be825861f9d4d9326c34952633a316d56367173e9fb6855e1e0ca674958dc6deb39f226d0964b91ee63ea060302fe30cbe7133a3f8e7ef86db6a2507bceb5403a4726e0a0eae04afbe61b675f063cd7b9e55b7f084598d0db11ed433c546a8259b85bc7f382e010a7bdb253b387acf7b12a49e9a012adeb1ec9ca9883808af6f50e0dc6aaa0ffa4a994160317d8ca8b905f26c2cbe86c94c745ac53115358edeebd796563aecae76b7e7dfe89e18db56cde0214d49922730a56f882e69d025c0e3658cb4b2832eb8a3fca57aa1c4236e70371938e270a752ceaa8a45ea045b8fe47a4059270acf5414df3252402fd57fd51acc7b14f2315540372bb184bfd1cb496284d0e8d573a903054a449f3bd3ab66b45bad026485417b7d83bb96f7268cd367e0355e9fab75 + +Input: 7d3b2faabf7f0e115074f9ea9abd75c57408ef1110422f7ab6aad7d7ba16114323a50d852c62c89e2596e51553f64464e57d80e3d3db023b5128bf9db397d3ec6e1dca6cdc4cfe52b701be280cf50b74e19359718687bfeb92 +SHA3-256: 0800cbf70683163396596d298a4fd71499256b085eec12fb0f3dd48f55179b92 +SHA3-512: f5597d5d3c00620f8efc700ea68c74179bab920f26e1645f1ff4a4c932a962a7d14da5e4face8ec339d7e624856cc36b742d6bcee1fc7607a0de58f1d57fb277 +SHAKE-128: 97d219b4922f32f8e353d2ca1d6f84a7fa2045de30bff7d27429926c43ad8a189575817096a145ccfcfeb7bbda0949697233af85d206eaef7794d2c23e5ece28342631628227594b2ac7b70ed434576802cd986299e495359e3c75c33ff1f37ce4ef00b8f17fec6901e4504bf84bb12d53eb66295c945c1695ac6452f446663a920f57e083198d00ad964ff2832fee8da2cf6b033d43396dc8906cd44df14b4a8ae0748b08dcf75208f434429c83bb891e9af2d2515b670249e75936f1300032ceab050e07d2c31447dbbfa2f642814488c6c7dba32d963429f13389addc3f3c55eaa529c13c8c5354904abcb3823715a141c204031b44a861bc610affe923a7c375e6b0ad926eff423ade762594328c8faedb3e8c80ca4aa68cede5eaa14a6eda6bc2d786211ac8306e45acb013ffbdfce37b9234d73c7c6c8519c15a28fa6a8c17c18573aae91faf358d52cbc3f0da810b5220df7707642d6ce7d209a7cf13e30860c1204ea16e34bc1c0d67239aca9c4d13b58fa588e07f4ec88928bfd6bc1a292f9d9b669ad5648503eb1e58050643f8861c87339c8250d2fb4341ad5bf5edf41f200e43278f6a654a575cc4d6f9ec794c84f9d060bee6ce9e47027ebc058f53f262bc322c4b9350e0ffb209cb18a382a39c5a80af6e8b2612de8de7effbaa877a9a76ae923badba214b8b579503535114ad6cffeffe80bbae0513beca10 +SHAKE-256: 38084b2cfd610b21711da5a97f92e3f328ac66184d4d36e629d54e311fcec9d15a4d2d4ee69b17fe69bc7a5ca3a335473121551e0b39afcec96e77a4494184f48d1e8117560b17f3ffcc644a73b6ccb629b4fe8ef8bea791fb90fbb9ce54c74c4ba2a6256b5af3a62b9feeb9439b75b0235bb599494eb346aa7ca657b7005b65f0fe4ecf379aef6a84d5d8e0360ffce7a6fd49fc30233f6c8d4d8d939927dd8d0d40686ad50d6af985e5df41a84cd3ecbff083bf5dda1579d116441c69787a1d5b0e15a14806fda0005dfaffc67ff482f7dbfcd91f5167d8f735bb37e4cff006d8b4ea3632869d3e607410936741d471b98e72b87be1c4a0f5f109e1e3dc823d377fb05d72ddce8f35b923f89fe5be22368be895d35e314649d5976c809b8bf5e54741fa0976e129e812a30965678c7fb2711c452ecbb72a572c1c8eb61597ce8d5e175a0f7c50be56df02711734cf1319729652ff96340abd14885af1168af7302305c778c4c784c91689f6869ff143925252e48aa8a776fd599ad333a88cc74881543f9299829ff7cae89fbda115a5f138e0836e690382171046ac4ed6ab7dc3a394d25a4a8883c14120204c35064af70871d0c70d30c2b5abf8c5a2e561443e417d7658d76c78e028ef9a937bca7c6bedba3ba9c82e3fd5e99de1e0f717964d3d5b739a1f17a82409d5a4b20426ba4829389978efac6faca990b1ce265088 + +Input: 026f6f6f05302933c456870c990134163902de8c998b7bb8cc0b78daa9d03f8a0d8c038bb7092e07dd5ba00a743cf7cb4ab8e3c7b6b624f2533ce2c4233f4e352c43af2b1fed779916d79a8fea06bf8561c2881fe0cdbadb2395 +SHA3-256: 84b7e0090567d3ac3ace568927aa57aeb4b4d88d7466d1462267795b253aec18 +SHA3-512: b5541ed65d59251d1137cad24de4979a3ffa0ecda1384e92ddbacfe6d193ee8bd1d582aa2d73eacd1f0949585becb47701bd3ab764ecbf8ed3c6ce32240d1e1e +SHAKE-128: d27510661de6066bd2027ff51f41d66e5bfdabd3fa19f3c47d1c8607a96c25225f5df6d7f15f8e3d92a53e47e9723ad33ef3200fa9497a0470b6eecfd98df477b3eee5d8805f73efb589518c34bb54a9794efd89d45490526bf2017cdd57ff93f6fb27b98299b2b151635853abcd9bb270976d74347d9cabac6b6cd8ccb5fc520150790934445fb3c01d748f1be8f86133f36a533678e55de791becf9448e1bb07bd7a5f8a94253915a2c717cb900d692be20c5099ae3f8f16b7f477f5475282a632471a1f1e3773b64af8979837b0737725ec1840e41b8fdc7cdaf60a9e3b451392366bd555e7c9087952f5cc88986334e081d4309450665163f97fb4d661797752ad1d3ace059b94cd823246ed49f1ac29912bd96bcfc284fef2c3bb3473ad085a6b7e337378056562134a20d82914d5058c2e12d5a7b8b8bdc78bde3d0371fa5d83072321cb6d4dfd3cfe023a5fe4cfa9647912fbc7984afff4d918f1c436bb0105eb12194704107532edf28db65d538d38a739e3e2e542e449d49b96bcaf36816cace4382d2581a6f92d0b193287e88ad595d635958dfa317f6d5f660ba3f43df86164bc2e7fa092a0c06b0e47cef34d4ad135d9c54eee9cc0f53f621e0953511053ad42f88113638887077a9fba0604faeca893140e741daf4207ade4cde04ad7c865590967deb43e82eb93c214e8b96f50927d04782e934e3a71338f87 +SHAKE-256: 250897fd36c8abffe12be394df2b6e3b824726ccf3e593c2216a3054077de7e34931293dc10930abb7f8d82749ed34923ee7c35ffc2b7030ad053d38a050ae70cd07f3963a21fb7ba2bdf93a31696a1cbb9528855c78c861bee27f42c09dd2ed5785a9cf0fb3e23c7b48d09b45fddf594dce4fedbd87f3d8acdc1a6d90b787726ff031326cea22e8a0e002ba77f157391703c04c7b0d463cb9b41a4e1a46ab40f6595a31b10c0fe6ad3165048610b04b5e42484d80a178ed989a585c4f29dad8a1033dfcf507e192ca70c1cfb7bf93327f30cc3179e1d9fe608a6bccc6e6b247c5203c2856e0063975cac8f9fa78d9f28e1d60ecbc3386b4acb841b3c9c43c04599fb4f062793613770a5504f7b18f01aa20a1efb9ceba70fdde1f6914cfc300c6f4d6eb4877191d8b41866b6f08beabeb523528c28334aefc8ed68311d7d04dbc215fd0c9193e1952991236ded46b743e50bdddce37917715971bb958213ca0716dae67d8f217d94d6ab50c757c8680ee430fe4c448aba260f3f677c251c208b7e4cfc743711b6da6b3fd7070966230093c245517514cf1121d17278fa976b2c426840b52d90cbf5456f6227aa8c778f6381251d8c90883686e4dc854d0b63f76687620e3120a7d308288c85296f8da6134eb7105fabe487ee0ff497751921db85ccb66dd0eade3736b332d104802a51aa4a916e72c075d7fe222994e3913d1 + +Input: 9d23e38ac6706488f7dd2b6f87e3761506dd7e93a7b3699d87d08967aa52fa64565cfb8aa8e883cebab09fe24ecec25a6e908a940933182eefbdab8e63243aa086eee375a5759e0631e0dbc8fd4f2bb5e7205502ddc7ec2e3cf02e +SHA3-256: cb4ad71cea10814f40f3bf9b9d4d645fe3c19e85516800110d40f8ef73907b29 +SHA3-512: d90d6ffea56b9c241c931cc3decf892dbc188d30ade4c3f6f3f937f7f621fb2e3747b394ccd6e98f94d6367703acb576de7fc1503dfa58d9680520969b83bce0 +SHAKE-128: 55257719bbcae66813dab30ea0d61bd99999b36ec3f5c70d4e43a767eb14ec9d801e5cac7ddff3953d28a68d5add288a227530a64c3ab12702ac7e94c9b620b5680e25e4ce407a44448328679351554364f211f56acdf44e159a9468ee25718aeba2ddb033d8c6062f96af674699bd9444abf79e90e171234bb5b7018a22e96068a185e981f718d14644231079d1e9d4afd547f43fd441369e286182b740e14c5fc0ddde0d5beadc84f80073304beab8d45bf015560bdc80e59a9bb2c686b587fd6f4e19dc9921fab0fec24ba1f3361a3ca7c57d70a6ddacc15af87cd7eac343165e5e8fa700193a94f3a4e1b326ea4e3ad630ba713043a4ba78a439f274e6facecaf4176c5641661f030160bcd806fb904c0b715d3e7bc603f2864533434d6c500a504e374ced40fe08d0e1a4d3a0bc689c40962188cb8d8a82b7fe5a91154c98470e4f59c06d7d4d023e3701619e6303a06fae769dc12d7aa4eed45bf7b5143e472e905a837f9f2e97e56cdc9f0b0661f13b776e7e61c354c690d56dfd539690a8230a10bfeaf08aa046f3c5bd8e93588acff43f23b6c5aa48826560a61a0a89c475cf38888cde67e8a316484038590013727033d8fff87f99920bc13140e2806818b14ea027433fea7a4392ee321e7badbfae9ab4ccf5bd45f15953fb9320d3b05736164cc77a36c5bad10c8226217ad3cb2eb89df387b67154981901e68e +SHAKE-256: 21754cc0bf73502e459215539932e58d15eec9080272083e1d37866f5dc1fd55bad7ff611920359401088c02bda64fc5f1241b9099ebcb293bb90bc27831bac0021400b7170aaefd019d3e2164eaa5df1b422834f9853304e2505d52f5b05a9a43eb69d7896355527c4ab233c7677e9d5c1ba778a57d80a2d9e8373ca8e84d252a227101bf73b8df6f8296187476f2ae50777526d4ce3e3b9ce53f7e5fad13b1cd5c1ddb808f1ef7f3b1185a772a0dfd81d25a9d677b69454319486b48dde7a5138ee634cbe4a1f21770bebfdd069fb119d00eb45997639938f0e1ea09a145b87276ac242595533869ff49cf341fce485ba63d3023c8f9f015e8e0d42932087a7d5b9df36b960a31a8ba963903767dea2b166d17ce346722c4528ea083848a1df988c54dd61406c1e2c2702bba80bcac21c26fcc29721a8aeebc22cfa194e8ff7be9d92a43c56ec239b8571dc26e5b4a70c5537973322e08a3b121095e873fbf125da1c76a1ce4c14d6311e93b0341f7339842d5e87249b15dda9f07c0212bef7a14fe0afdebd7002610b487888768268e74ec938522ee1597662e797d0822b858c2ea888c78647bcde64c1411b7335fa4c23c6151e6bba93fdf49c231e4c64e6424690959d95ef6ad792bd5077276696c7cc31bf76c5c0365c7431b4b32c37b526762dc2f849b60efb10636a6f8f87337f6512c0a2bc29137ee7d4b908793b3 + +Input: c6361cb5c9b8d03b126324ba43509f9fa8a0628fd59a45315f7392b4f552be15b3cb1fa668e70f038fc272de922118230d12848915a77a80d03b5edb0fbf7b98965d0fd9e2bfd2ba999c1943c32439ff017b7c6a5b392d6daceb661e +SHA3-256: 54255d6afda6da8ae4dae17943d3fd52eca903e6b678ebc13b869f3aec4edb41 +SHA3-512: 180d74a3318fe1ddc6f98a788ad52ed30cff77e31714a6960f291b476501e3a36b8444576fc70809db9b08f7cbe7c73a8b4c87720d9079a05b1d6b2bed8a9f99 +SHAKE-128: 0c8192d81efd7bf6b9f357cbbc9464471e607b6b3dc59507848026a94822fc8341a1d14a9b31e34596933c2ef458ae33bda0fe2e97618c5c1ffe6ddc0834ad9337ec1ebe76c6d48de1c274e75888f9f666aedaf5bf3bb85ba8fbf7b08bc2a3fd325f3c22c44f0fffb59da41ade87ba2f537dc9bc9fc1353c66d36f0d079e042689a22a1439c54045e3f2b0cc535d34ef86b0cae88630e6b112ec2e88c99aec71a22e974f2e6a25d8a748c27d51739ff2ce97ace19fe9ef4d1501684e31568b2fdcede38715b112c7e6e8f5b42b010aa3c0a80e2e28cd3d32cf9332f8fbf3ad6ea87136575fa4bc6809d00174850988bb2367737f819da25d36c708d00e2139769a4b0ecde6da112f4b9bcb3f7def59e407d1d505496b782b8c7e87c5ac9ce619257739f31bcc6dd7c14cf100d199d12939d7e2a8d492b4bcce4b946369d999de580ebaab9c5b39ed89f124b1c6e9a3e9ac396d35d08d0e3cb4da9f42c14999724d3ae54bcfead719ea4a29b1be840b5db9b2261b6ce81d857be36d9b6dc6ad169a36c98be353ec2f944c69146fd1c07c03bd80bbda7502af326bda85e6d574b6bee682f0e12dc2e8edc686ba6630c88f6e9c8fcf4a09137cb53f1c556b13408e3285ccc07587c92550fd79826208586a4b14d122d78f2f976060fefe4edeef0c1f61b48026a2cb8a2ce5f9692e99759b9e34952a2fb3d8aaa64ae6a9ab6ee136 +SHAKE-256: 8c6f9ea5a91b61911d2ff807a2fae9d8036bd3e111e7add0d7fb2e336977ea814747d8585543028606d6c80299fb254ed1ad5945e08be0f05000ee3523234fcdec189470dacc349da7fb83d97ad39cfb049d01ef2399f65320e7856a872e1cff75bc096126701082ba6aaf2dba67c9cee12d1118fad215aaaa6c5cf9a2d398ed61330eaac68cf988b2573cfd616b720cdddf5781b575d965eb175e56092c2b409ce9247d06f7d572f41a3eb33e4028ce28468803fcd9387c2394c4d876bca1ab807da19c62c81b3de6ee4f476c9dece51f01e37a7c5bc9e71e5ae258a91d609f538f1c18273a704cf2e220db241474a5240cb4a9ecbf978201c99543a60a9fea8f5db2f108b1a3a335f3b9a40425a62c9c7e4d8666f2f6f25e23477f5cebec7fe8143e0153071acd71b0d773e340c2cf484738c613c1de3c680412d69ae3fc367c3e772985b2ced66c0364d7dccb2a4843f6481f26ff0af9b30dcc2f4fcf9a6f07a5ca8d0612866a5913cda9ddeb2a6c763e37b6c8316b6ae4bcabaef53cee189cb5316a49d423820ba967bfb4375148cd33407cf77a23215884ca27bda0139f970a0db0c93fd20dac887145644326db4751c865da2f41c43b7489dc6f156953371dd1f2e5139aba252100a61c8eab517c5f4326133b42d1721737c8e43a49720c01c55d279d511c9058711f33a43bcaca341ff065758dc968afc1d1373920c5 + +Input: 7bf763dccf44a6333d887207bef0937e665b829b04add35a2c6c6b96137993b6b0e5fca1600dc3b70935ef519fe86c1831dcdab6c4589f9104dabdadad69765bdad6e00fd651cda696bf9705f7db40a720a1aed47ef6363b345365c4ab +SHA3-256: 0200275effd7abc405054a471f295744c11ac480bd68fdb28d94b6e0ee3cc396 +SHA3-512: 7f4509d8cf8db08cdf280ebfe5082f987dfdc77a35686661661dad7947773f626fd8ab01d8cfb730f05e1d466815b8465c74e7b836b29b8d8b1a206c0e7414f1 +SHAKE-128: 21de48aed9c76315176999df80996d7469c099020f65c45d4be7ad89f376c89060b20932cd066e520190293fb3a8f972ee70af41d125c00388ce945e3d6415444d65db641254a79e8b8b78330822d3d7959c674346997b83db3ad2c0e3c603435661528a93429d821de449fb4b58e1441074080fd2711b5c16be28698bbd9def1c1eb7c6a7a69a72708ae169b0acae6cc11ddf87968583d865fe068732f3330b0299dffbff6f492c7e51634e2df9652e690bc0c27b8498b374628cf7796ceb23073533487fec76430f6b45d9f63fb1c7c898fb65c77d0bc73e6149cbaf6ae785ff71480300bbe8932f353fac59e047f3c7a9afce44b94c1c379207acc431a2f41527b405d21e4816c6a2450710e940fe64b46854f0179af91fe24c2b5cbaddf1b57a72b06d80d913f3a055cd950a3082cc6eca922a42143cc5eb6d45c73019e5e669b6d3d9aaa340a6ef2441ee9006ab1060d06a304a9e4eecd5a0e96b8e2a58236c1f2a4faf51bee1a78f28766a8da29ef28262c39483a75edc23fbebabdec83dc19f94e0a2cf7742f0d9782671756f1e0e01ea8866adca3ae1b8c896c34e6956b220ef8affed3297b2747a0a64ba4aff09b1de13f8d64bbdd8198a9b03ddf3b8dcdddaeb74d98cc071126609c9a9b12bdaa9281be176c76b1d39806dd52c9ca8eedaa10d41f13a1192e5bfc204d484d4b42eed1905b69e8f22bcd3c9360945 +SHAKE-256: 597dc9c838d9d63c934853118ef09d7671cb29f248de1c4b0824fa340d96c56896e61cb512ed14642aae2e4b6925251918ad8d38b6b9b81a4c2518925e73a5aedcfc6074c72f8655d5e61bde0d282b7f01fad3b2877836566643d3a743022fcd7274f696d35e1ec7fd742fc8b522dcfb9fb6b0b8f39dfce2956d667cdc509ec8e39978db96ab0bc67e3f3bbe3b8985778ca8dc619920ca05d1f8319a2b353925900310f22af11284686016294beb379923ef8e83439a63302ae0cc4c4c53a6c2d24137aed274854a0ea359d656de607969bd0f9195a909ee06fa14e26a0308a2bbaa08c51963fb7165669a685ee0241045e59362336c8634967ace60786f92c53820b4383bf0c142bf23acfd3d896e885bbc1967be5fccb848eaba4a0c7bf9f8813ad95d9c791bc1ee0ce11a7a43dfa6dc3663eae0960279881fcf61d361da95208a5f0a1700e046ea0036321091ada9e686d5642e9d761692045e29b9e8e9f5a764a3c1e92c093a259091fb6eacbb9744efe5875dcc39c9a401b746d6d3f79100714774551318a2c0c3c11510540cbcfbd86bef903d2324e993b01de429a05d4b48faa4f36ac2345b6546d8ce95739610937312975005b3e5574a2a319fcfe337f57dad62c9849343f778b66a6179a58c66503a4769b397d404ffee03790b4f2d59770f74553db6a0cec5176bbc466a476b99c93ad36b50c0c59060d390472c + +Input: 5415d15820000e1a488c2bc7076b50cd22befa33c2915146d092615168f6dafefd806de15a3144df50c6afa546e5057186bba9722afcf4736a6b70a3a10e56fd74243f89e812eb3917a6f9082e794cd3f95425bc8d53b93663b07e738100 +SHA3-256: e74b94a28b1cd757b863f5d1f4467dce3b23840170fb8c96a913d236e9426173 +SHA3-512: f06a46168dd515fd8bed004a066fd64dee3ff932d19f461039af26596b9e99ce13b80d1edb15c9866c2d4a6304142eed9478fb8bd41ede252c96c43cf51975bb +SHAKE-128: 2b976f8eadebe15cc99ffeb62eb705966a45cd6835f4a97500c190f3ffd875336a5b4a5cd54c3a9aab605f19109a19e8465504395ee6db7e6f0f3858ec68a6a7a565fe4566021c55a7cc575b4e9b168da7715518c7bf8b8153d5947d19c69314d94f66fb41a4fdd4181bf5a4381dd042e36f57ff34bea5557acf4f2b1b68e6589be1feac46dd466104f6c3f849d77b1035114996696abc7862b8ce2df12d297d467ef9fb54ec4ba4a150b399ad6cefdb8ae40794a99f4ef03ee88c21021f6b787b2c19286627b964db57b08220ae39687be21a6582a2cd83d128b8149e9820d88ea7aa3ba970678c7a04ca2cefdbe9048b64a9309ca27acc0e11ec66b47a55c1f0b4b89ae57099d5774f063bfc4f2dc8c446a18ca9dee5d79538473d569e190c53c856df8a03f8fe1ae2e76dbb5a21973f960ca6a64eb82b573533e2bb840acc09eff8a3c61d882b29cc417208c87faa718770567a6b8fba8d3fa782aa9a69bb9429d40cd1361d5251b573d3c0b89656e74292c661dc9340d65a9a737cc37f1b2f2515985941126fe395501ff762114f5ff61e44f88bfbf8cb5f53d4f145cffd72c105dd76247f0fe814cd781f20b9716db865fb7d553cc545fd691053dffc0088fbef6042f77f2f0458bcff6f76d9138789cbf91936ff0f00f827815a10cb7761da5272806885d2c622172527f8952f37063be01e5a279fde34a0ec5b2b8bf2 +SHAKE-256: a7554b32621046f3e5d68e1ead1437fa53749908912275d445972a796dbe168632cd0705b3573fa01b7a14f5e101b5c4f31fa18d059d0883075cdfbf8bbc67211c9232e9cc05bba2590fb29b0cede00fceaf37bbf9f671197743695cd3882519965a58dd171d20f8194376ef4cb229d9bf4978dbdd859d57f101f83cf74f3a3ba306d0431f8fd07423513960d10295d9016b7b4e74eb6441f6b4c88f567329ef7bbedc89b47bff0afdaea325fdff7f3d5f0ea87f89f08fcba941c28d7a96604e1d5c2a4d41f1b0274bee3b43a404c9a956f3db677e3e9a16c5d6e6436412a9a04e04f3869263e420be3dda6a1c98e494f999d78bfa92578e89ce584e13eb6169cb13cf295978f37b058faa691a8f1fc1d8c5e6efd6403bccc1a078351b90a9c6bb54b849ddf2fcbb6b8339e04ba8e305135cb4eea8d2c743c3b822ae9c35e3b284755c9088143c1dbfba7af07261387063c85a81bba504b6883b894f6ccf03b676d41de20b57c4cc6cb150673cb6fa3ab9bc054ef0b2f30f77c6639669b015051e01c33744c32c48151156f0a054806e3b3c59ad220003238b7c99a276b0d8b8006f04c38af016db865759d8d45201056494eb18a568f0f107b4cc40964ac073539ec18953b692dd0b78050fd3f6f52306a9d4d6b76ed1ddc37bad9369b9fa8a7347b8f34ca8874d666d07a64519dbe9af724a9ed582d9fc2e5e3049cd3d40f6 + +Input: 9fd6dc35f5a262f697280f2f02c5afb3bbb8472368510c56649732a02366e2e30986239cf17b06b12fbdd2a2b9fde72a4d03ffa2cea599299106415735ee3e565fbe194e2daf7effa03ff1eb655768895c41feb811a0da9621100c03599518 +SHA3-256: a1e53a1689157ba4e3eebdd453483b93decf2e902410e8b96375aaea3877602f +SHA3-512: f926cbb911690568b3482c542818afd24c9e3f0523f5aa2b619131449df498e91e1c51a03d15e26ad6a105d0cb49e06b25076e453159ce9d58b13fc3604267d1 +SHAKE-128: 8715cda875410d832aa1fd358c47f3c7480547b2ff4b171d062cb8a5a8d8787f3e316056f52d1d9951b2714495a42ab9b48ba509b91f1aaacada87c28d7d5dce5469c131373d2de9fdebf0592267a1e7667f9bdf11f8347626b69e98ada84ff2cefa5776580fa0fe2bbd99c0afce5fb27922588203ed5c3e18b68ba1530fa68e4277ae5951b64b39207088edb900bf1be512019320c0a1ec59d2983b845577eeccf7cf6901b129aa62bd2dadbe1134a721a6d05775855c0a79a12988a792f1e630a53828f23fe3644f54f6be9ce3fbe69c432f5d96899c5ad8a2b5eb72c2e90f9fe625c8e2c9a22bf153f53ab993939fdc642d9afc3d1c0402626a58fde974399cbf872a38b6fb518cb19ccc94f41a306d0883404926e09a6d5a6faf069a5e95ad56e535511b37c63d668cefc770b73384c391b629c7a2d0b8b10a13a8dc4e91fadf0a233e1c3bd9f804ffe715a57ffb7ee761217c4b7532bdfd63f8c6692f9478fdf89cf5e79b7ad0cb6d50ce7310ca269b5b441617773e7ede9b34449f6d21effcee39bf6c09b85351b7ca4f314b291b7ab1e665e1b2131853af28faa5478a054d9e21fd72a79cf4a8c2e252965a291075dfb2effa7cf58307fb0f1f9d7909961103223c53eddf8f058afdcb72e3cd08953baffb6ac6432786a65f2907ab2d01e73d48e13bbecb98e5a498e3264d5f9c4d49cd99b6391ff6cdb7c62f299bd6 +SHAKE-256: 94d6441be046af6d276dd611826b017165fb240cf6300f37791fa5f08d54edb1c92e279fa1ee2b4d7053bff2c0922a6c1d981908bc14a340dd5ae636ce3f649b2dfc8fada905941a023f99eefe1b2f2cbad7a1d5b4ae59e7d547891527eba4b26edf3afdbe86f8f64ddc4b8e544235998b424d73f1025980c08db26dc5e4a5ece1b95b0ab6939df0d3f127db81af87c37612416dd5f8a209c81a5c97ee7cfff616d500c69a1b066b6155a6a58e27c0ff5125621449ba614803fe32d667f93f32b26ae23783917109bb8dd92f1afca98add622a5e253972d9b54aaae0891af9092681c1c81a7d34021ffa945ad0c25c7c76cfa083c72f6a39c6a884561a22d9334f1411ea02bf14ce793e9c1144204ec20f60bb72e6d34390df5d1f5d1cd6967c4e3d1dff760d2f46ff403bebc4bebfeb7118595553a3084a9f82e431a4e0c3113f3fd9a7b2bab8710bed6a605de0e20ad4ddb8e98a321d77ac46488bde96799456488c30795fe2d35b35900a35533197cb4325655aef35f068c2eb084488e97903af2ecd89cfb753da331938b994d075277b04cf45999a17c71d4fd5cc09d2c9c8e64907f7b1580bacc2dc47a56be480ffc008fd8a2bfe627133e0e48e0180dfb1d51857a6649b7483fb81773a0aae1bcb0dbfa60518b438b60b4a726a5ba20eb5ffb3cf9e0ef11ace7bce448847338dae24b25fed4f6a163e8be81cc9d9a43b + +Input: fef8f97e9c7b78604bdf862e367b530c0e78fe440b2a9b9d1070ec5ac3c54d3af1664ab10ee585c74a1ff66adf4071ea381968cc4dedb45d54dc070b0b6971c966feff79a3ab4597ac2ea4cc2acb62cb977c99daf1fac18b31cf7ce582e6598e +SHA3-256: 71fc2ee2b0f65d92a641c96de854caa02a091f4418d24ffa330a02ab8ab1d114 +SHA3-512: 1996c82450ba523bdf777e428f1e92d226613bbb40f5cede9ef7452d9f128be2ac7f013efb991ae1d0b6b24d6080051f7d5cc68883ae69584db094d8861b00bc +SHAKE-128: cf60cec3e74ff7f2872c7803f1650122e1a4b60ba63fe0709c43ad2e79e6cb1f3f6e5c56d5360def71c5ce548b90aaa967fc33e94f3f9cce40e705c2e6e9648cddcec54d8bee72d63b8cd15a3ef0ab530d391590091d70c40835c5fb6929c5f6212e1b26b59945570eb6671843cfb7b277883d2bd7aee517477dd78c9e1e564507fa7c8273f0c34a25313e68624d50ac600decf4e61bbf1bbd89848044b3617342ed7f5b1810ab2a2cbf76fbf2aceaae1d46dda5b43cd6820cc08be7cb7c3a4f0ef5b1ccf0a21a3a43ed68dada2ad7527007ed0dbef96bbb7431dbd2c74c1b6573fba73bf9df1a4213ba567e1f19dd4c4ae047a8e5a2da7fedc9050b460775e9ac9ee356a8e579382e50bea24c6866becd19f723ea3725f49381fa45194f65db690db4450f98207a6f4a7dc47cdd89ae4633d936479f6640b1900e77f6d075a63dc76ee63608c66e434aef6b2ad9f3224dbeadbdb515812e7156842a454f55efd407f4e6cfb4a08dd5b1613be47aaa2ea76c1eb75e2647e28d068554338e314eba2bf82576da349b63fd72549da7eb3f391f975dbe3f1c774e6e39708c7973cfb045f1b2e4fa3b34414ec9f85aaf45008070f1d57f0c3874b5688d515b636c77ced23e0557736494dc17d8cac3b3b161f3bd66513281ee26fb48a4fcb81d1882659e8b90e4db542e705e85898c7ae8e80590682848c0ecf371202eecfc25b1e9 +SHAKE-256: 8531faee306337264a5ce4dab36cfe75b6eff44682fb38d3aa571dc4f6832546a5ccfa6f8885bb88d5f2ae04771434c020152212b09ea62b8eb5caf805c66ae10fe05f2df2baa5a96fa4b4df06e80422df03310b5255df69a138ca9f28406d9e698e5f0de7afd6b2fe3cf652cd0818b0e096f40d88919f41286350a6026b1ed629844ed79ef3436a77a25c06476b5047bac8da8187507c7b0772e12ca201fb6f0c2a09ac30b0be1e9c3b9fb7d8bbd57d36284d307a187b8fbf99ce1d52a7b384c312b39d1634b1ae66a1b1173e0991098357c887378b2b6f96b66d3fac9d4e3bb8f772288a627cc4d829d59d573ac734da755d61166d4cc350dc1a29f4e472cf12170e18219de1a5c396fb874235eed26d9dd04ddd384fd85aecff2d55cd10402e3f2024d96981d213532b09cfb1199256fc4406241dfa0affa4a607a806083fa7f406d74bb05a5ec014bde3b302060153bd683d542c1871d80af259c505347975fdaaaf1c1bfd83538f3cd0beb068bf6f75e308982ddf578245dd9058e85c13a559c2ae06e3dc1771224873867e92c15a45567309981ecd7f452f009ada7424c169774d83ce63e0a2c92102ed36fd0ce89aa00981f148ea782e4d4d69b4e1bb55bc0cf24b2b58976c90f6fc10bae429e09cb90ca4b751ddff5e4acac52cd99816f06c59d82a174f03126a5123ffad873156abdb736b9716c1015f92ebb4710a + +Input: f3d3226eac14d6204a72aa3814fe609a960cb49b23ac29bce72d06cb378f7d29a1483f99cd0ef4902cdc5f819ea11eb871bf6108157fb05937e9a580395eab43b9feec72b69561e066bd6a4ab52ad60066307919195320c166eceb622a1aaa8779 +SHA3-256: 7da625f7af3b57ea3bf2826722d03d2e0a093f7fc1ab3be16ef4853288943cc8 +SHA3-512: 33a98ed1590484d60b149507a6ed6ee13200dc356608be4519b2faf84b6087efcba295b380f43f9ae372a83319b39422e96ba7dcc44ffb419f3c465c9fa1541e +SHAKE-128: fb12cb4de9e6620d1dc75962896a66c3ceea98b40665529be95c11c10aa733503228536401ffc38494af704ae73462ba4ec0ca45c6b814bef7f16414603f9d645f5737c3f8fdf14eae147cdf4723208de000d1bbcdb0fd6787c2eb3eb60645f170eb08ba6738e8060ff248a3e548c3229d92fe27800ea7729630bc7e321c192a1fbb2f49fd052dc2bd6746dd9a878a53c2ec61fe31daabb73e9d8634d4e9fad56a66ab4f19901b66b6dacc766bb8250e880ef513416f4dd3fa42b0c8b172c8ae199fc8d4e1d0452b15d9865692e1ea522ddd197b202b96d8321054996c509e068c21aca3b9da33c1dd7caf2971c4e35034a0541bd54d4dc06bc9fb98837c3df04fb501944e1581710ec7a77cbac83d28a742f519d3d42e1440ee765b064bbe93612ee64c136fff202cce33f177f9309d3e1d3a953607a1e6a836da6ff5b539fe78aef1bba10310328baf6fbfaca69a5e72117ced8f3ccef57e668d1b9c6f32a2cf81fdbcab441e8af34ecea7fac38f05366a516e33aeb5b119d4e0f94317d641f6f546c659dbc922d24c6e1102098b344d651a7f79c2f09527789c09f0fe3159ef6913e910c70dbbf7c087ddf26eb42abfca439befb7794785cb88205465678afa9d76189baf1b85bc8b059261d908fd9f096cc966a696184880cee81759e581bd4816e8980d016702e27dc730a9b0c87aee3f23215bb62fb459153c5bd107e6 +SHAKE-256: ee80e5705f423446c944c123efbe15972ff72dac1310fb1c010cc66d1bb21c66084b242bc39bd881e755ae4f61bdd5a57ce87284d4e81c7eff570165a66e7894425a6bb4f5475c0c792604962637286750ddec91519601736febeeb35fe11d02bce2bcadbb37079be4bdf71cb777d582444ea15884513c486a343ca4d9f41f9e4df8bd3f8403aaa8e676af52dce812de685fbea566df862a7e3e28044e07dd0e55ee2b2a26985df864b03af809a45314415b2c2ab6c3625915be50cb213a5cb362e177b40d6e2b9415029249abd224358ef52490dcde39cecca69b313797166dd7ad5ba1c5c02294e8f81bcf4b395288a4885e4baaee6174aa5b600651f39cee7897c321ea1311817ca97c5532d0fcb4eec9961c26548edbd09bd75111a2cf9ba400e055887d5f81b84415fc8980901bd48dd5dd3b83b65e184d515835265c36940598e5292fcc4c2c79f506b199941142aea01ca60d4f1a8231d2d8fed8fd2125c6546b089643c5bb6056bd3de226708765161b55af0babdd051a37ae5ee91b7f7392ce9cd2687916b784b23aec3e10affb6c8365cca79325d910eff982506fa8179251ba5e3284aefb6f9cd86d5813f1dad4b7f1466665dbf670b9208a26f87bed1f3a1cf7de556625149891496d3add375c2397231e89d91c5ba1d80ae58832cf6fd483cef4507cce4e8518867175e2f1deed27118b098d57c9ad64ec6ca3 + +Input: 35c1d99c7a4b1ebc4afa5ee2d59300c9c7a0416dc27d9270370c913c1e7ee90ea7a8eac4846721003bcf667ec3c6a1d904af4075ad17a5448bc9af0a0a1b170f814ee4feddfdbfe4112748e93958f00a250608a5e23e5770b75bd74cbd361a3b6ba7 +SHA3-256: d16792fd65145017cbc7b459cece6175ea71bebe645905bec5b6f7e3f08b1b68 +SHA3-512: 94d42440814739587447600f78a1209e32ec3898068962133ad8cb131e55e0d71933ad06cbc88b57b62dfceb8c007f95341afaa4a4e66acfdf934753cbc3335c +SHAKE-128: 0f084c6ba1d72c6428b0f8bd4f874c77aa4cd16480374493f80df21bf986d204c6892875cc61bbad2e469a03b082bc26388eb41c863db775dc082b79c770ca8ed6bcd63cc96f2f2cca7bae5851f4111e856a8c618ebe112e31926336879f5b0ade23026076c5ff5b68ac6103387c2db593de91b08a5efdb86f4da0ff62e9118963cb7c235cda314fb0503f4a0cb99b0376c6e03b83a089c6504f05d07a2d14e286f46b52490c9b41661e0f372c52b5977ff5cd149bcb195cde578adb10cc0c2eb1820bfb20fa9883fc5836e0350c4c105af6eb576848103691d74a65064c4a6cb43cfb5124437399c2d8117a590b149bca4e07f87971c892d2f6b4c73ccfbafc5f75a55bd2cac81a38feb1eb0c8cd0c22d5dc4b4e650e2cc17919a0fe612b748c6dc1e96ce44c4cf90177f77d9d40dcddf1297f23551fc0f1a365f2fe35e06093c4a80b5be2a3667257dd6649957dfa2ec007ee8824a4cc2186ebc2c1511fd2020cea8dfdf676ee064ff2b378ae27a7c11c16989a5d1ebc7cb0b222d6166746787c02d22e6c27750c51a2a376f905c08fcecd5bcd90e2fa071a8890817d17dfcc9f3f5df43d94e55d3a3b27f428be895e229d1aabad52f84c1814878fc14a93e55438b16ace6c3e57d2198bb5f19770d9ee75034979d908f8166fda8d121a671430e6d761f44f26247cab72fd2bf6f5fae52f74cb75375709f1abd5dbec80e38 +SHAKE-256: c8d924239ce5ce0f47335316f9d65f157b063d130e2352a48385ede6366473d1206f429199d0493ecf656ad7ae952889d90722f85420b38dc18d74ffc3442914c9d78843b08072b02bcaf4cbe575ebf8a117b57c5169bef30b0bd1ae64841be7a6d81f012bbd3da7bc4b75c06d58195e759f00b6024847c656b9bc55e5a4ae93733bcf9c8e198a4a39c47710e1e9d334be8d4fdd7af9f1d338d4db701fa1597c2e48489691a57293b8dedcdb549f4e95b3534092d07ee56989c011590ff555bcf08b7f3132c3e56d331a6785d7c5d35210d7e18ef67cf03f4b0e1430eaa11225d1e6c3709a1d5ad7f043d0381589d3ec2e2e251ad6bedee737e5a841ed40e49a84b818621e3adea56aaa86d4f7e808be98f47cab79b88cc03f66a95f855e6321c6ccfc31ac2862778e87e25f024cfbe1ba1249831baed64594b6c672d05d70284b5252629d9ca508e471871d1cd0902ff66bcfdffbec253e638dd9e25c2e0bfbb62d43cd5f80b820e5af462cefe4b584aeffe251c64a477d74b14f7c34b838924570df3a44e6bc30c43f15df683224297016dd214729cd3a717ad10ba65ecce3ca84f7f95a8d06e39251a06353e390a9e259d095a35414d0cec4fded093b949f33ea8c35f485a0ac4210cac6e4e88ff9aa4b7cf9bda78c1da0b320958bdadc6f12af84b9b6affcabd241871f047c9b98536825799bf35deefc8a37789003c670 + +Input: 3c6ba9073b3e434e295dcf913cba6675d372b2588e1be48cf5c4483bcfecfae6e5b25f4547233d50a27104c4a772734616579308a87095f2c629af46669516ef514111e44bb0cc0b58b3cda35a7bb2ea6862d056ca68ab5d06dd4e457bf6aa01ea225f +SHA3-256: e48658f69e93496284a59a0d4a9df639dc751c903faa4de0a2b23e12e040eb1a +SHA3-512: 6cf1a0274c86a702c43d1d8f550a30cb33cfe2d9cb33237298732ac6ff4d285a842449480513734e0c4fcfd03a982dcbf380b24c327f3dfde512a8ef42cbd7a3 +SHAKE-128: a0c763b55920412584267b81f48fae5f7d6f18311bc8b32b57c205c6d0f0c8b661f171c94cf66a555423876fb4dd5359a3491791a2257f779562978478a03dbb7e176d3487d6f1d7543b247a8e1d42e9483fa996a3487d5552ba50a61ab28377586b32c400bf6663ffb7d3e7d3af6fa2bc81d4c368f93cbbdd31c73e7d151701aff7627448bad9ace94d2512d45477577bc83e81abdbbeb3e8c319871847f31f04edbafdb69653b4620af05e5ee7105c1766909bf55ffd46df09a22947dac99384bca2172836cea8376457c24bb43fc567039e8b471f3b09812dd013b25dda072211612fadc166e2bb2d303960af063b1ee50c6cd8f173ee3373aee2a3172ebf9f2638d550c7f28664d5473909f605996aa5ff73c22298164a41ca888064af08ac07392e200442246bac7b3764139703bab9ae64320d0676afbf295e3a50fae5e2df68ac05776a298453a933447b681dec3ff2088ff3a7eb126a86c5a13b50d9ccea12c48bdeb6af0f503566a8321cfb15e12c99b62fb8ad043571ae37c5acb4a63923f6ab63e360f4b52a9ad65b2d0b9484fbd354544c461f7feda6c8a5937fb0f3ac2319cff7c252275e926787738911955917dc018771a21a8342873436da1972eb53ee239fb3cc887a2b502ed363e686caddf102b6da5c8f0506268c0e5e7021d1e85e2b37eb9cb93111fdde4a33804d667f3dc6e1df6324133cd2533f68 +SHAKE-256: 9b43a7e61d41c03861f1e07dfdd8ef50780acc4b59b7c61431af948c7d779d53a406ebd5018d35753595371ae4adf08f3b41ecaf0f7beb28d0adb60cc2a86ba22369862ec617122ef1716fe309740f0754844c06142aa3a7f720f75b1da0008812b7d0f6c81a7bfcace3468385f5673705bb7cbe15c5578d35fa2a5694a9969caf67b3764df9c963eeb358fa3222ebbfbedc758b17d38695d6e18ba82f523d12e4537eb7604f2d1108351161f6caf5fd4723c0ca11641c9f92d065461a8c17ff68b04ff26cad14f6aaa6ae4f9fa20491e1aea1b925f0bf385c3baec611a70f8553c7b46567e5ffae040251cb4f97095a222f1b599a6c55c61e3b9001c6dd654e47ac52f05d51b3cfc56b9d6ed2a072e0bade5acf574ce918de83d200165ec67daf1a639cee4d0632ed23bdf718addff425ae83f527e62e67b2533b3728d1005d1a70ac6a6f5f9ea14b4f72da3c21588e237fbc9825e32005874b82dccf61fc77638c6125bd097aae9165191b1c71b8a134d4b92cd37ae9273a415a5c9287d5b95f9a4043e8ff5fc6997ebc80865cb4d094a2ba718631b909c14741ebae62fcd36a2258e99ec691696af2c8eebdb71e82e488eb857ee58f28ffc5e38f528d8c1a0a0992a10aa90fff14362c34db571dcdcbfd0ae97eccff02b92ef6af866415a323531adf657810bfcd0e3dd3cdfe344a22e9014c636de77dfc1467e2db72d932 + +Input: aceabca849e574dc7f1e4ff0f4e029376131394f3f06047ed392c9f9673fa3bb1ffb657e069b5a85c5e25ecdc768a789b1cb9825edc9666fe7a9311e460bfc22885ad264e45868b12cfd8b666f20cbfb575cc84056545089e6a8ffd880d0abad34e3b6aa +SHA3-256: b8ba283002afb7eac3f41487648ad04c2f8b34ab7c4dfc6e3c2cd761d8e3a41c +SHA3-512: dade49fbed3939363a9895a4ff4da6975aaac658ee460d0d3cd59da156f7540a3167d853eaebd4736fc7df6ab2c3b03a27ffafded29423a977295b8fc747f5f3 +SHAKE-128: eac76b25aafeec4aa1b0f86e15483a3f66b00b343d639340f5ae69241c326d3d2920f7b797f4d866326ff9a897a1007b9f3e7a2ad5f8dc04ab38228bcdfeee24817d390842d66900ca47171e457c1a7dd5e2aa1c8d763276d40c0f4cfee04d30be5faad1c1ff6330dad9e1de1acff98c0a8d51eef9863392d34609f4735f6a47492116afbb94e9f4b63254a2f51143568952a7ce114d3e8f50ae09c4af8a8e02431ad0137706995d56f536765534eb4272075b66ff81ac98423344e117c6381eca7a86a3bf4cc35ba818ca4357dc44189e0c5b13eb57f036aae718d4db3bc30682b79f156171ca633aa995fdcbeea114d77273830a15aa08005acc4096b4718b349be94efa75b72e3f83157cda7da57f1ed3deab9dd8fb04d986ead497cf2452ca7226d96e852bafee99450f6b3395c567a23056a95d035c4a80c51efb48b3c661bd22413a01f9861b893050d16546abf0cf8fa3df35a83fff4406c70eb775b3e05bd9ff49f814edb97037776f173e04d1a44c403fe1a7d0e1e861465e9ba279ca15a2b87821a1ddd789e3c79a368971dbdb93b56ad3bf0b6df141ef21c16f66acb67c57980500aaa9c5222c5e1bf528ca81ea65b160b0abfb68af5d95baf955e296b97ac6ec1068764f6a2bbd715bd796d1819b40f357d943b2312beb41733d4ff2fd435e87d4315b75c9333d789b7e4de0f23d08f0ba6cfb39e8ecf53db952 +SHAKE-256: 7076e05eb3fed9216bdaa24cf872c16fe18091f334f24316224d10d23c079e2b9a4e0e2b06df19c24cebb7515b5dce134905309bdbc0d5344a3129205bffeb634061766976e5fb3a8f6c4299065eb9d5827894182f80f5c4e1d3310b186bc67dcbde13649f3874b2f0d2546eb273e3b90c26cb607e45a60a332d0896f519361611fd5ca03ddb696e774e7e93b9b93c2392045fd8dad6a05f5baba7717454ada1e2b91ed7efa2f8d41bcd6888ef23f4e0e8ea58ae1773345ea7fc659276bce91f3b57f5edf19316f02da5c9ca9f65650ff7467f83f08e0ed5c0954983279891172e0584a2d91459050b462a00face843afd5000e3333f252d1215b6f2da7d8837e43ce8dd755f91f2479bebfbf094f1f0c5e9c44887a1ee598282baa95a259df13c920487e334cd6124b5192e1bbc3d491c1f263158fa0f2bc031e804380af8b7b9d5556733719966bfd97e10d357455847ae83515a706866f0a941f96c8d889fa1d2788b9a81e8c1a49ee94fd54367b2914075a4ae848fa6f5882c5cbfcb1b1152f93b58e7a8ce6973e201c3cccbec40959835239938f4cc1a8d3231bbb2f697cab1096a4ade3061de1f5f4178a82ab5feb14965bb0cf1f5869460bd2960cf7fa48b137227c59c3f458e1307a9402888bed1b1176281bd7675e545b1e5d9eca4ee4e2065c3bc8a77abb094a423da90c6cb095431b8d0c596678650ffc7c86eb0 + +Input: 2d3ade8ede8e46d0a93037c1317396b3d5e20d9e80f50ada4d21c5b8e16ce0382dbf57ba46d590621bc75f7e12b0e0045e45570daff572e904646d1b5e2f92eaeda264ee82301b01c43df23e73cec786f23c54ea66ea856455ba8c7ec4c1c31c30b4550d78 +SHA3-256: d30f9baeacd3c84595dd8882fcdabdbb348a682252372df9664fa26e8a5530c4 +SHA3-512: 039fcd70581bc7e28c8be280d617dcd553ab2bfc74f509393019f9cb07184a61e1f8f667299f8f0e83559629de6b73beb3e063e586140fcca2458498a8b2ff17 +SHAKE-128: 6d01aaa95321656f333010d53c3da6c194a6fae2e9f8d76f40522e87df2b6735dd7287b3a184b243bb617c8287cca01106dca5ee7d07d2ce60e19ef0bb6adf52ee9ecf953465714171726fc5d48d781b858d5215cd2dfa6eaf88b4806e511a565a2d4d29837a79c5f497a46ee89c5887f7f6bab3a0368fa13e3e2e4228f846159944c25150a97ff8801a3f3adf8377bc0a3ab9e9875c81a5e4959270921eb8bf6069ced5374f794bca1a84a5064659c9272731d8dbf3d016af2282c68d6bbe4fc33f3d9f220991a60bedb2033ab17334ebe5a9d817529c267d3f0fa846577d7334f2476f6744e4d737a0738e86f9eb1b8c9b2f9359365f2c39e19ffb6d700e77d1e3e11e62d4dc9739164854851b51d2550b68818667ba27df8642c597b13db50aeaa0f7fd8b331db099fc7a11f7007f32d0ebe62e0785a8db2a9c3fb041a543e3fe3a256eda487a07c9bf31e656c396f11b94952e9ca2a977971156905e3cf0f5a1245076649ec831f539eb601cdbabe79cc32e0660bfe988daba6a57cbe2c28f4ff3416762aa2f75c5d574c78d3948fbf05611cc89b022a391bb6257ec48841684f12362440da77269715472361706883b3243c5f85c140910bd72c4ea992472929994ef8bab2996f8c6255bbf0e154ae57d10fd678a8f1530e601c3d8cef1ff40ec8b8b0107c459d6ba9b21b65c1d129295897324733d4d1c7197717d0078 +SHAKE-256: 9fd1ae601c7184f305ab6f79ebdd570dc05202081b57ecd9be172b26f38cb7a22d68c13616f0cbb2db29b3205f69683bd2479b0b7b6c26303298463fcd545171b5b527df3a065852b6174d438f860f7daf9e7bd60ebc26b64c07d2c8f9b228abda53866a501311b6a1e477db5254f7af7d81d8d2a5e7f1eef61a49dd02af2e8537ecdb1bdc9e97a470ab99ddaf6c4c29c5c448eb4c60e611b7ce88fe944421767032f1c2c3b659db9641caab566a981c636b9324ad5a7c43828ed509ce33b9703f91cf96dfd9f71b9e95af981cc11e695450656c7be37534f47a1873b1112f10ba33e69794a4f51fef4ed4b8700fecaad48512b40f730f2f937728d23d96aa1ebb2f3b9c338e8373cc7822c382163d82402d95621d2d0ee35f479b3386d67717bafaf9efd95dbe53e1964626efbc0be48d771c3d53380ce36caa89bce4625d82e34bda0d2e929d08977996bb81a3ff204d3f16bbc81dde28b9528592b1b16ee0253347f2a9f539911821a3b2efad6dcdd8cede707d57cb1fb8a9f78bed7f3c602fd812d1f5bb8f555be8b0f4cabdef3f8f1704c20ce485f6e8acb6f2ca0f6ef5a95b08bf8ca68ace7b35739c7e215584902d8db632d1f731663a4ee9294d401c6b09e36860b3fe53e8a5b0f0c8abf76f19e8b334ee98d1677b94769553583d8487184a08d94bfbdf2d26eddda1bd89f02aca22571a049de363f23425f5d8b2bc + +Input: 2b500debb9773def6e8630658cf5bce6e083624ebd2c57e92e792e6cddda58e3b72662981d43d3e89585cb29f6daeb9d5ba45d486ed302be4dea9a2ccc82b641feb238164d3cd8a8d9bab40a9d2230d97fa13b88f67582ba5db2e077f54ec6634b9acf765bc5 +SHA3-256: ce68de7e53335162618dece848c9ca12b39a8402411398d0ba9f14f6d3d67638 +SHA3-512: 2e3cee24e11dfd59565454611cd66f74f97acc7c244246ee01189ff7e1b920ff57ac96cc865f8376643cad83a15763022a7e44d6ac3968f2342e15759bb52d4e +SHAKE-128: 6f05b022adfd1ed3e3ec94c984eb8fb9a5aeb64c589031fd31171ed151f9272da60a819c136f63a16c619989850718729d1d194aee19e9ee01f2a35bdffc2203fce0a7130c14780614663815405292aab1f2a7144db63c4830b358d4a8004a3abff2cddba734bd920e742967072796cd6597d6e41b410ed613c95c5e10c751339b3100562b6a25e56a90c2e701de5a52d7a11329e4e8cdba0987ac13dc4008eb5dd31d90560bec2d608e14116576cac7096097b9aced88a804b2a68d133ec2b63ab71dc85791bc68168a852424504ae0d62dec581aaaad5e3cab0b90c05f9a7942b0084e4bac2731898e3ed07fe94ab5026c45cd7f3b6abc785056c8b02a3134dc49619b1cc0ff8f101c93e4b1e5608e2bf75f1158fd43c0e93f1e150fbdc3d854cf1081ac80040a2aa5395fbba7d09e61b7d5429d8b9f06a5d70fc47dfcfa55ecb417c7f91bce26af94b7bd81c56b10a68a015c62a66f5f9a847ee41a32556b99d5089fa0413176491363ad1236af6aa1bf8375e5986371c81318be58ab2dc120c6fe35311a705dd662ed27c5b1645c1ae53f48b99ba8b333d5fb28da97464ab028933d949c908c24840add50b3219fe0f8d872dc749d36f7bb98f302c32eba150ef88c0f963059db5f0018b87bbc097f1d046d1a7c709f913fc177e8bba378e1617980c8fd53bfc69f0f4b37d18ea929c04a89430513634d3d3679b56e985f +SHAKE-256: 39fbbbf06a348f021b53794e45ba06e342ea8a4a0c72ecb6077dbc095060e00f897aee0e1afa703018b4b5f4088c13498166f27aed3a4d7ea1bcb27d6eb3a04a1daa97bf264b85910aefeca9cb5308fe55fd3f47750f5b542c486ecff062ffa4cc724aa13073663270adccb589f6c42843a4e56e1877a6413e7cc916e34fc3af89df0f712d1da220fc28c07a36dca87f27c8ecf3a43bd136f8c87579a50d2c7719c1ced8a6e4219c081773dce4380a246b7ba74ab725d16343de9c221927d3a980795a40dcc12ecdef19d6311c23192409714512385987fb5619eff76de1c98dc0dff0259807211a913303ac8a6644a5884683e210b7cdbc94df9125459a1664fce38b3bc394e4f5ce0bc2e282ed9c3606ab4f723b2554a2c7dd62cdcf5ee90347929665eb56b1ac55d81d813cd5f4e618d1b4b0739d72d85b9eeca8824ee3a6e9f1c399076b2f1088b9a76e82823fc900fc78fc13e4b78db431528d83e06fc3f7e603461faee335d430b884b87afbe87df8debe24a86fb5e1a8a39be98c448e545042758a52d4d02f65a7bc48a3059caf4c943583fe65166b36bee735673b6872081a319e214c27995b30e63c460f973f3d41a9446158559802855f4c95783034f878ef135685b4f1c9032f88481e88f80e4b0a291e78c43b084560392286230f356e17f0ab85625836e72f2b037ae545ca6fcbbd9e8c607c5cca88c8ba9083 + +Input: 3796254e39b006b8f145485c6eab86dc8f7d1fce265de0e12d9a96e9b0559727dbbd7af9385826bb5f1476e94222dc748c41657991def02c03e37a5eef35059bf7aa3f430ca31730951eed529e9c78c7f5b2274993bb03ca5b2ac23ef64c121dd6c7e3110a6dcb +SHA3-256: ccef493e344639a7bbb18a9b96c54cd1582d19f6053e03967433321350499023 +SHA3-512: 672a2619db96f5d981c203ff2018dfd520980cf4aa25827e0181d8e7c85cdbff5b38a9645157a5f55e77e9647499aec9d1fb3be42476df1a43a18e4d69b9a98d +SHAKE-128: a8ff0db1daf2286ca2d4a71b282706778e4eafb78fafe6602e646535a5e1716f387e0d343887e1bbd37faf64d51c8586109aad3b193c463d72cad15dd8e791737397848a9909b6c5dc8f0dec4b41e2d72388c631d9065881716aee90168bd362fa239e231663691ad8a46b40f71c964bd544d14d21121c562e7a47854f5e1e445ce8f340ec485b756fe7239f4f83a8c744c4e9ff9a2931d1cac5da592b9f78f0c475735a7e6cbb3150640f7589be14fa0070b759528af35572097d0bb9a533ac1409345e183ac38ce3c67bb6fe42a76fa97469c51d2be07dc5918ab6b5ad266dc41533b42c8f5672d4d1c6773b735875ae0b9c959e6c5f2bf1d21aa97e0f6289774b9ec850ce6697546dc377800222e12302c48f44b41af1f873ea9fe448db49c9e7febcc346c4b503b03f6485f1ec805a2a7d529ffcedc7bcfeac51b019f2c7e319fee026df03b56d0a80d9fd88959dfd6b4929bce8222483040ad6ead3e05a7e00d45c8b58963ad8b62ecf768468601745fc036826c6a8d234bba05a8a5959ee8b0f9fc814f285e2c0f3bd6c76018cae094093de2a935f906b39fa92849e73711eb7b3d13ab9dd50e12a00f45fe3e3833900a2d66971b0fe9d5905dce8a729948f5192352a4afbacb234c397bff37a42545c92a8c4d2ea3cb8ffa5cc8b1480dfb3c77912189ce7d3d670d9a08f564cb27b04e7c46ef6429466c7f25ae7239e +SHAKE-256: d8c48bbcff9cd9b879a760faac34a4f0d8bf98273230d3d4a6f3adfd0554fe0c4e1f5781eb8b6a52af20050faeac182254765dbdb1cb0f493a4e688c0680c0c5dc66ef69c3ad9e72f21d853b070eb3be71fd499c89970d108b9ac7f7e47463125e63b6300b743dd8426d37008a641f94fb898991a3d06c97570c73615dd25ff3a5680d4f3605361ef50f9a8ab504e6268e055026d776020ccf50f735bdee32db1887599eb547a8829a670bcc891deed3605d6713be02273c2a1a34bebbb9137c1e6284aa254ba66219d8450d5307428c1b76da16533c1fba2d5b71af072c54ead8f4f48401bba1c6409a400c49606cd155273fa07deccfe9dc73c5d129730457ddfb2f1de4106b86991329e3c830471193b826ce73d726b8559b366fca520702831141c313f8b07a9c1a140a4e86e32f472c8ba558840bcd4ef8a4d9ad2760e3af0f046273fbfd435f86aa1984a51c6f40852bf567ecb06724ffdd1ff8e0535d290ec7d77696ca709c2a4c58d471e51706c7f452fb2f03ede2d24201da6f227521ed00c3efb8375b3e7118b90daf3a7c2ce3d99d64aaef411ff2f5e3c9e6511688f28f077ec66f42ae16032f95bc0b1cc2ec6186e8686c9459570cac293c9f5b92f9b4e0a5d90e07ecd1938425aa32d4d720f83c23fcc6364be8a8f1eb44cf3f30e6edace8a69983db2142003fd403c49950aa1fc07eeee52b38f70d9a0c63af + +Input: 9854203fdf1e91287fa6b1465b82af9a6daeeb5516f82a803e23d36d79719a5a8614f33e81b4cf1f9a9d3e5713f0d968ffe265e2fb9b752f7a05225de65e024c02dab90016264e4a469ab7c1f756ea4913f6111967a96893868f8e735873262230b50f31b1da2fca +SHA3-256: 8a45686fb32b04a1f6fd09c31e58ffdc5abcd41c2476455d5be69f5fd8ee28c2 +SHA3-512: 161bed160157af792723b9f90b967267817a441652a6b76835f10e368d24c7c0430698d005ad36640a9ae20f6f2732e2fd64ff79f62475b846b9281234d90216 +SHAKE-128: 0e2a5b8360b72d91874fbc24d859862e6284e9aa14ff4900bea7395374d9f44bf0cc911b70e790f6b56fa655cda322ab597d6eb3b979f5d6ee0261b5258e1614743a7b03fa191606a46deb808e409af4d28cd83942bc205731eaf142745147e0f635ba96f2e474b8d9953f5d3436ef990cd1c232cb61442e70f69c52b9f276c626ed4266580b6fba58c1367a261479b824dbdb5f6b4fca2bd72d26eec88aa95d911d4592220957c5dd66089ef38f0d7eee8f05a303ccf0c5ef338f28e6c636f295e8c1fd24464a7e13a07625c80a273e775081ba83f915f1fb29b8dd059ef0b64a68a3572bb8900620aebba597860de1dcac422b7c1b0de78e8c7329bd8fe492ed1a4fed87d2728a9302a8a9647457c958742aebd260732fc276db35c93da4ef9024136b5fd71b026b82dcfafd595ee177e365ab87842143f0c60a7b43e18a1010fd109a59c44a82738739fc07559bc04702a06871f059a67bbb875bbd815ac66077ef09554d26ea1a7c9ab01fe38a869741af50a3913020d847dc7e9c5406b94c72237eb7a39982181faaf943221ef3a849c5f17e405db99dc3c0d16a416b9c5f30724aa729e8b218154cddbfba6d71ca289f0d7f528f80c8956f4fb755fd0c7c7de3f0dbab93f734c24a2d03049384b0dd86a03b621f8b2888d1d09c64954a57402feae878f2834a9d9a7b1d3314c093a9c3608a87bb06e5c01024d1bee245 +SHAKE-256: 13fd2bd3831dc5e56150c22abf9d3fe878d0eae8e3e4c5918e22942a10a5c4f1e4a79ec16759b705f93e39f9020c967d9c42cc5b4a719d95296e434af9965017bbd37f4ac00b46f58e1dd82223304ad6096a1be820b10d564ecfebe0a039c311be195d101f1e5f50b2f884d96bd0b0e074114d687c1f6eba9d2c23d4000a7a36dc9055d034ac9b9b952db014c2304d34c4e5eed0441a14ec47aeec036a0f9d9be2c3f7047913b02ca96f544bee0c06b88b5fe88e4a07e4e4d6085791814f27c8c6f3012ce979a550fecfc385ab851a7b174c57252ddafacf9581ef65d94e6e9e61306f8c94a30ced1b4743b65f2c34426a2eb6476bc2931d0c103c42497b3fb126ce1c68b9d2847c458c1ca3b81960656b6af23b737bdff65d8c3ba676ea5768a70285e2d6f9252bbcc1a1c66bc3905d3e3bd0362b66f4038fbbdf4a46425892680ef7d0516ad3740e4c466888776a6e4b55dedcfe149cc6c4eb752523e48ebe31bef009950e4359fcef09eb09943e93d50d979132d01dc75e14bd5cacff151bf5807433dda091eaba9c17aa3d59f3a73bae7c0c5a9a593fc3de7f0ea91e183f3777b1cc7f2abd1e7a1420c7455798001949b400a7b0b8716e09af409d141d9d0c072fab691e51b85d9aec9fc3b7afda0fd967142a53f6bad08808eda66d18305e6acb95fcf765a2077908e5ea96907f765c6ed2a01abf4747f699a58ee90e2e + +Input: 1efa493b8e796bdd65499d7370055a43d7db9ce58ba8daa2f52996d1c3c3e3a05dbcc92a22951efa55f8fdcb6e1d18741655afcdf01479aa916afeaf7bdc524b71c1432fa9ca52c5ee9015df22b66361d7040f6b13e6a661a1412f78ce19d3d5790959719ebcbc8282 +SHA3-256: 4a34eb30231583f43df135804e8b608bbec0d176107d2ac70956def41bf23c3f +SHA3-512: 119bfa6f5daf2bf4692fb589bd500ed45caddf61ac6a509531f91182d2e6fddf60719cc42697f8b458921f8bf9679164b38d17a7262e9368e34afec1d6ea0b7a +SHAKE-128: 098319c0b9cf7e28b4ff3e9a8813b7bfb894342a0a009e84a3c4831f8cc355fb6fde6098d87c568d98e9b2dd41ee337355e256486ab8c3787d779c869ff2efb33206e92acb4ab495d32c6de7d2b1405424d545a47d75f51a7f3d87bf9ea02dde951e0c12f744e2ff8eff0ec76409be1fb06430a5ddc1c11e7a7cab53be97340e4fa4314d353f2de2c89d92902b96a1790e15ef3c3ecd982ed05b9206273c3fd57f60d764365fcb7c0bf106f8ced9093fe22ba68481ec1c4e8baef6f2d9e512f118dd53cac79206b6befa44ff641c1b3d5c899adba20174683df618a657390e8b8673b87518e906d48341d09b61c36d6b6ec2f8b904d04b6d093e33a2d015fe6de2476409ed24f6a25816f350002a2e5521fbf28db49bc8f916fd815516878bfd1ea86e093eb0663b5aebb2662824ba518c4bdcefd06404a2c4eee4d7c898e2c1b8201ec451fb1adaf9514d01766e354448efab62fc45bcf8635a1d26ab30309850834afc1f35cf2aabc9da6168c9a6475c0456a3b961810e0af5de0844a6b47d3ce3e43f29253b381c66727fd4f197ca81641bce4ab117e70447fba451712122dee5596b7eaf4c78e681ba2d6bb430f8daeaabcad8828c5b2aa33a609e7d7a2aa9fc877a3f73ee5eaac5c782e4dd843564104829926e9d85d9436d404280309a573b2ddb544f8c0bcf1c8db74a0bd97b63875edfa466eee1d51e3610884add09 +SHAKE-256: f7ac227aff5175fe81a618865470e23df0cf2647a6470063bec560a35ef7dbfb148b334ce66bfb937323f8a1bd9184861995bad2e8e765e9f74b8b3340001ed642a1de5073bbfd804b3dcf3f4757ec1dcfb7696c85a4056424c2d0807a64afa0156a5c2616170209b9e834d30064687e84e48213d4f1bc139f750f7090023a72c72b7c7b3e422e597f939ab88538ba327ed5b3a876ba4dced9e167d4d0032ac70717d080d0be9beba150f11299ace18a2f2508418e3db60f61cd52fe810b15b6b6d9fe7e1ef514ed6a8eba6edd21a7616c52696f44b42c6c3fb09ade21bfae012d152038db1b8c345e4d592fb5fed8f406ee83af132c432e2839bad3152cbad99d981e39b9a6f74f801e990831a24a17b4cd61e775a40a03e021049cfee457aade3e415431d3d50a5b828844edc75b827dc8aba7cf4d8b9054b26694fce640bc4a3a1741944decd9ff54bdaf0c49394498b7ef61ee5a8d5d6afc28d203f9e5989bd6d12b7907f21cbe08611e96622e9e2aea5d88c8d64792f95535c35fc4d4b26050908534a6f4d9e77368265ba49585f63598be0d65694f446aea374cac499f8bff1a88ab7e967a5748c68b4947178e1192912cd05cfd754512d295ba304e3aa31e18df690331c3ba6dc80fedb7de3cd7705a25a8f7c4d2830846441d49a2e29369f0969947d056b7062dc5722744a4077d423f96df850eae2adb06fa96ab42 + +Input: 0423487a1c6ebc37b35693aa1973c0d1d468b67159b0cd1e63e8198fb6d2e49d46d176f1339b89de7d248cac92d492cc35d60ad688694c35103814173f87607b5a3b2c7a852b278930ad212e3041f390945f1c234dc5ffe7d6bf10cc909306a12fa4f687494d84498061 +SHA3-256: a11fdb3fb398aa719b28a4772636499e7f68566c61cc99fa3f277c86900cb671 +SHA3-512: 9e45ba286c4f7fcb2ddbdc4ea62a417b7f6138351e3495066904f7974ed5b838494dd18e360beefb8958d52c9d7e2683905c059d22e6e491a35c74afb2241039 +SHAKE-128: 7231145e7a185e939116b05c0ac37d227d52b93ad91e08cebd311ea124fe3f4ca54c0fd88411259782886dc3cb5d7f99fa5477c60a8eb91f5402d45bc27bbe394749fc3d44d76e329b0bfcd8b8317a8a2e718efdb6319c39d15a8c24837b897d47675c770c5330d1e2a99a3895c30755a786bae9d6ad7646cdd440d3caf3861335751fada2a2eef029405d498f0d3bc338b85c8b1f90369e307c425ba95eee382ca536f95dac0c6cb3bdca535246815a9a47fe471435b51c885d46b92a91beda6502e30e3a6168519d7c1c14638f182b5d3daf46946cb6fce6425e9db15da3bd2826a3c892a8b7934a5c4d3d17267f6480387f076d5ee34ed541e47bdac288b1775c41c44e20d10b1eaec27b0d17d1706b40197df58053a6ca3109954a32b6daefb3c4180e2b0d95bb2d662099381b76c7a83b212bbd9b09e45dc51a7665dfa90512f1f3a01b728c7e8815c8b1dc85938271671034cd530961dd64b2380c99f52c40609f76135d1eb974e59b5379bd8753a0f16adc6b95ba6a953d7dc32ccf7c66b40680f6634c7e89161de3142b40353f9b81668d8a497e89af52bc580e7bfd72639d032db83ec834e3b5830cfa927a74b0dc252e616d7674f3fd6060ab12d6145f045751a570e65d49b2a8dcc26f4de91bee9aa74adc502b4e164992a4108a615ec8675e1d955a67466c798b88f723a833334b3ad52dcdc11d115d2b386f93 +SHAKE-256: b90f6a48d415f59e6e345c6f2e48eafc0a57b99a718e88f7c8886c2f4c3b897152b62407ca1ba800e35dc09f78112af6c743416f21eabb87fb2f125560fccc51ca0ffaeae6eb07e1ef8fe2dbecb92c1a9044c4da93156ca899f906c9fe49de57467aa6c150f81f32dd12f2a9f133381129d71e6215dd934842743f1a4401d8b8d4010071fa1dcfe0330607ed0f9952f039c6f85fb8df19cec65a6b322b4bde1508eaa36c313edcc651ee0c0891a30dc5a3490bf47a2b9e327b09f4172eb2c506d9dba0a06131da2f3697c5be3c0e35479b4e758c654bcfc95944978df3804b79270b7f2df463604aea17dd63917303e1e25f9bff1a6ad91098d70e32066280ea6d8cd356dc2d4e4ebaf37e1645b3703db566e96b21b2e6a4de4751775da7fce721f81d167f2ecaa801c3f6fffc4b9dcc8eaef5cf4698a7da81e0c8deb2f90824be5407d21f4e6574f682f6e6fe3f75c9ce970e900ebb9c6bc166179a8c805b4ee6bfb6c9d18998df3014ae54c0f4abab6bb7191e44c9048fa65d012235c377630423ea23d3398966fa2ef6cb0157cf9e72b248dd570b08baebf64776125ba200d3d664d4e0f3e7bd917c8a95d5d7d8776e215364f88fb05d3d434d4794a9f0fb2e3beb158789a992b333201dc519fb030eeeb4d9724a43e9bb2ea6f38c3d89633112e03e85081a69dca1d12f72fb364098fbf65d8ad5ee52a3b4033b61654749 + +Input: b82e4b246a92bc8a006460be8c81bcdcbacf89438c22eb0f487ba5b713a9fd245bd5427bb518faa7aa9dc8f62d8b54d1c6a075f374da48e80d7ec6bed3a4c721276c0ab5fcfb42b4a0589d774860e3b38aab3ede08eb1a3fd177641f94e3649db2849bee1146f7978d73de +SHA3-256: 6e7a51d6aabfb589ae14085034b3cab302610a022497f3a197acaec8ae8e40e9 +SHA3-512: 08ffe79f8e857f8b5697f7b2e888649d40af50d6f997261131f1290c402316bd4db237f2a34ac6942526500d67fc172815213bbd09011246e8d57d8cbbb7fa82 +SHAKE-128: f45a5af7bcfcdc4f9f68092b2490bd7343af97802ad29e38c8400c89a1136087befc59831bc934e20258e0fedbbd002ead105bcdf5c2636c30c021ae9b7d16fbc9c7061b537f71ece7276eedd0188e94c8afdad4a3d21e7d7226cf43ab3fd71b638096806dbe8485a550c9b5e706812a664fb99902b14a2b5c63b4b6f06cd87a714c322fe4b98cc9cdac5ee618e71333c0c1ad0612c97898280d3bd553552673e8c46b2920523e744c3c424b18ef0a52f7f24f21ded1809fdcd4a00ebe82d5482a76e8d39e335102ffba14df3124da4d03dadfc96c2d3a1328e366d81bac271e1b744a40b7d5f56bb5ab370496f86c172190135230c8429b853d671a47ce45909f7c3073ee2878fdf24682fa3cbfd06d35b408197dc35fb80057b4cf19f013df8a6f2bfeb5c3add696c64fe46148948ae15296f403aa7378f59308dd40884c44c3bf59a7f3462f66f81d871bdc34f74000bb431a5d080f834c8d9d6a7551a4744be571aaab8b3d90709c7314b56d99b592cf768ef0fafd1a01d5900b1b84c19fa22dd1afdc7a3c93f62fe673d06b36d91ab2eeeadb65f7baaaa1b8c88686ab97da197d07cca731801702386624e1ddb56c1824f362c5f31416722d62d78e3ab7e07b763cde2ec79b882af79cf1f5759e9498655a53a930368d33314d041a1c1052560c049eafffa0bd92f9679bc582bc30b6038addaef5856e6dfbb1534457c7 +SHAKE-256: 57f734a9515111f93a6899c592147ca3b4c0296683f2d7491a7b7e6469dfef514ac2b850221f39e6dbbd1b659f63f6b88d8f861759c078a76c3fbe07545f6eb52ba104940e6c8390f2afe61a0c2081330520d8433ca01213ab214309316418e2955a25c0f261fea74950492fbe0e0a33b4c3a29e978004d5d36adbe0ada5eb5ecbaa2ba7d4c8101e95a1fe38152e8ae3d4d5dd3ae671a6fcae3c0d8d963ac873134c2c963d29eed8a905cf1839e81392225a9ef129c29130f0eca8c3307b39baa8a7440b094bfa564db3ffc641fbfc69cfade4fc0f9b24396cfe25d73163706027cbcfb7644147f699d066d2b2355c79a38eb462e335812f25fafd573165d41c4e90a65e6e7b09ecf6aa747b5f951fd7c26d2a929ab03d7a130c1f94a5284935c700c47f805a15ce73340f14d67cb482ba7b1a9807648bc8593b656029fe92ebb909dae644130419a4871efe4dff16202710b46f84a398be958e519d6c0d14235df767c1e8bbce7d279d1160cfe3f03f9b8b262bd28e67a1f62d9b851330a53f45822cff6ce31489f5331a6f61885e3212b29450fc7b47270b352a6582501f0b54a27fa1e99aba84c4cc5a3f16b22482c9d94f53f96086ee6768441d633104b4390e80412144358941da7ac76a5cdc1380d4b6c39b2c65aafc1005f70e7dbc950e5909d003e07184199798882127d02a6b30ca09f407e5ab4319b4f5095452fd + +Input: d4849bd34af6a40f6fe6a2c87e061a83dbe0ce7161f3cbae54b36c6b9784ad4fc5fa563269004afb8fd2ed90dea412fc4408db95a69618a743f5946f1249c2136f3ad2c28e6264230b977db7596cc0ea370dcf68956630fccc000b8fb6c90d56966b5d6a9a158fa8fe8053a3 +SHA3-256: d21bc9790be2ffc87e21a0fec1208e1ff3c8fbd67ee73928065b6f95d1796880 +SHA3-512: 99b6a1ba0dcdfa414a72bee0d28a4af672b80db2a88580082b37ce834b5ce59d2babfd3a534cd09ad8ff130643d926f1cb1c188dab8b356c50c643e5359fed5b +SHAKE-128: 100e253944a90ff4774a36793d56449ed3579907703057cbede51c7d5f9c2c2ed992ba48062e01311e438a16d9726bd2e15839a73ad256c0e946710414e56b15652f6c37ac713bcced6bacf8ea6696a970af87c7a3edcca7cfddf280b5b5c5eb1c67ab09d74f1a3c88db5d757d72d514eb22dbfe889fcba1acc3963d178d8a60f513d59d009e09c5a6bae0797ec88a3d2f8db5ebcb94c364bc42986785d16a884f2db799f165c9813b133ee268bac2c2c1ae57badee159f531a4f0da3de0a7e2c4abc5a28add8abbae954ccf81ab2c00cc355d82f9f1db23ef81b7fcae12263a2c919bb1060df6af0380a6c9bc52ab82eae9e5d9dfdccc0ba43dd65ea0e2755e9ded68069111c9993bcca5c335d51cd749e72d4ba253abc934c6b6e92fcee3be011257d8d13efb2acd8ee91408ab1ebc67e92205d42271d39cddc90efc174c53e3665982b397fb5ed2c9ef162f96570138f9bc842c8bdd2bef7684c951e17da796b4d7054faefd434a8c36d755ab7bda6a76382692497b6830e1a09d7ac58595bed3d2ebdc309a4804136737d2e28b45ca873e6312b743cb53cb582a010a83fa0ea5746cfa2de108f0551e452a314f1f990e72963ad7af7a89c968499922f0a3565019960f70c801e2cebce759a7adff9874c00c244a890cf25288f0408d19f13c8567570ccc46e4563091af49c17fe499efd8e47987f0d3d015d2d6bbe74341 +SHAKE-256: d67d044ab331603c8dd6368e6bb6a24d48137c4b4badcdb52071c6701ea076b3ee326f10379abc0785d7703b618c45ebba0cffe0c259a403c058799ac908ab45c3c7bdbf9de83db39173c894f23800ae22777be6fe1ddea721f5271f7bbf3653a2828fee3e63e34779dd9a1ae96bd24fbef798e1452099d2d520faf56b16db50dc06cfaa2e6678b2492d6c238408f7b7bfa55485fb595778b481ca5bb5e75ecc0a51b44916eb67e02272d023d4aa463eff068d39ee2b14181aced2aa71fa73d90a0c398054b6231c196baa6b16f5effb0cc9e628d3c963d42235cbd0abc38c10f97d4e4fc6c6f5a014ac98a07f5806b5749c7981bf85b67b1e04b6f197a8e40a245977d1e6842483a97e5af4a959b29157187834a6e0884ab37e40a074731f535e642702edef14a060a2eca68f84d2ef4133c8fb2d58008c2d201f353fdba1cedae6bcdae64b4c84555b9a8160e8c7c69bc81590317b8a90114ae1161ff91b4313172983fb9c9cc4e38df0d5f86e2858482e17cfdd612fbe684194fae79e600e0c6a5e5f86c993d86d9fa51b660dee83f522496e55e00228158c4491e8eecca856bb49f52e27e1147de571ea1b3d036166145b695081a4e16d0d48b6952e9ed04553e8977706355c307388adac0b247428c4ce66c56733e8cd5013e0ad02cbe4d76fec481ee8cca0d72d84f4f6ed1c499004036f5cc0ad594feedb4e4d22017a + +Input: 2f481cc5401fcf621a235530b48e2537817f318c3a6e0cd51ecef080ed853c4f16b6c9e1ad7d21ad27d2c82f70cd638b734f6aab33607d2b23045787a4a0e0ff256c5482641bd2469d1a6ca45f05eeff1571fb86d8abe0e356104169219d5caa38043fda057643c01f90f73986 +SHA3-256: 45cc7520aa2e4602b71674011df3623d24c85f0ac5a28aad444abb7c7401dce5 +SHA3-512: 3fcdddfa31609acc73907b03fb0a779ae4f0b6e7ee50555d6969c9ebf0a0d4db90d5178f4ad26c342fa6c75a7a8f59326aa847f556238ec3183b9d5adf847baf +SHAKE-128: 52a98f5599003819cf76a1c08168db76134dd914d688df2c1f2f1e006aeb1730cd022dd7ed1d7aadc7a850d557f9a1e6b334f6bf79141339c993ffcf0f0ec9d3f4886cca6b372cedcf76f2c3b2a13f4bb19abb85b8589d104712670564ded4b866e3290b13ea5e7d68035b9cc7836c0bf28111c84db799ecaf9c5c5ac7f5270f72ae59737e72bb04d894f2ac37a3f017b148fd9ac1d43ccbcb6de0aa75c356247b11b07ddae10977190a66a49cb0b5dee5cd9c2726e86b86b00fde6eaaece0b5e9be1628747b7857c3da602f67fd0bdfb9c796efd68df839423e19739c46b66c05e9fb15338e664226c6d11036a02d43fce9e98e42fa544933a7d28a47343221dfe3c2e099e6180f18f1ea23c28554e02e2d88343de89216f14065e5118276fe13ea79cf5ce0f35ab8b891aa27665324e8a5a47aa64c9fa4ef82669f4ae4b3b987543267532f7bf54ac3df767c380101272b9c8dbbe1d74dcd4a0889d9b154cc67fb7fab41016a4c3610b1f366f68efc69a97ce8824b42b9b57053fec6a939f83fa82fd9b5fabb9ed59eaef64b8ad4711d5eff7841d40efd563f56cb4938476e82dd78b7231660c77d140bfab6b574cd7bb8500cf534b227bdb487afa97d9a15183679d23a897a609004560be5f91dfe7a538d8ead173eb8727916fe4a19b1a4368217047b4e58b0a77259363910295f2072168669bcb4ff392fb01ec7e41557 +SHAKE-256: da1e92fa8f5a02a0f584bb49e3ec81d2ede70425f4235d97d242f99669b7d151a378a294752764aea96adddb50a782a00713bfe0111e1536e0ce9d8398dff672d58106b567207f68fd9cdb7a1767d48e26e9ecc1b017a0023eb933ce2506651f092863948eb07f48dc370f993937ccc9aabc07ad0e1d9d76e7333d0da7e676a49171ac4721fd2b7e7499bbbd0cf3bec0ee7e49a3e3348641f517b46877361b0d01a7300fb62914863f2262f0e32b92c3bfd09970fe4fbf82c90ac84e250844835805582475c99c1cf48ba667e647df79f36b5ad7bd5f11fd74e3441512b641a8811bacba142fc6b0c0bf98fb68719d9e3e4af0cf1e4328a30db6bd1d60ab4b821b320dbfb20eaac7816d49a88dfa7a831abd685e145982666d6b0b6d6ada4f4e39fc010f3a26118ca1e74caf7048086b15586a0b2c1ce5f8078d16e92e3230f469a6bfad539fc768031d44fd39c2563e9a8f8f864a57ce3b489e141e9da44386e6e467bae2a20e58079b93a7694ae40e1c62aa5ad8cc451a0a483956d13ca63dcabde110e7444a46a3963db9ad6bfb138262311641a27d8d8df3fcd0afe87406f4dc954cbb471fad46f4bcd8bbb933fc222fb1b6de90c8b9c8ce6c444922e9dbdd58a839f029e53bb815d31bb5bf4ea0abfbaee5d1daba0b3c71b1beb429e41a1ed9505d9a2730d0e42bc89b20651f7d3fd53af5a6c18b23e3d82ec09e07be7e + +Input: 64645da0fc47a27ea0a695ba67645df97a07742693abb78844578d4afecd64c12afbb69d6b213b48c4c3eff956067ecfba0a7943e32d2158ddbfdbd1d40c36c84d9ff3e171c1f64173be3e8e7d96619f18d0846cd76bfb6ff4719f19c4281b006eea5b437f091c9d0409f9317987 +SHA3-256: d3f0761f7bce557c2107e4ae9565059038466fc5c3e918f46875f948e824a561 +SHA3-512: 706ad421a96edc398388500010406c41383e70fdf72f434eb2b96b8ed5f30d5c210484e2a4dd8899d0e4a59d8176e47e21c2a8b04c21f54be16e06f963fd7300 +SHAKE-128: f01d3b339b9b8a15feb2fb1c127fe3bad0d602fffd73d0a64f3a23a7e19b3c3d20557ccff0721bb371b02d4084d2d40020b225e7ebd47bc24786c0efe725be81ef66b7f8c80b14eb3cc053567963d32899cb7dc029801cdbafad4451762a97173c6198891e1774da25e107d26dfeabc2780ad2ffcec3c26eecbbf6c9f362fa278e838f047baeea8033f2301df07c7ea2cfc732095f40c443c6d78cc98141eb62004cb006e607ccaeb14d4a77d25ebff37930d77193483e192e82e016a05b101039c4dc2cc49f18da1a6fbd0e8363369fc2cadeae1a565dd4ca56ec97611419a53b1018652080e335e279f5217c7dde527e16f6b22146f66bbb15037ac8d443d84f510af587e1c77dd48ec39395c730620bb60c44d9ca05e7c261ec1d58c2114edc5998eed54d3aad7527c8667f0bbe1f6bb7b27549591ec1b62f5394f06c5f582f4b55fde5ef705aefb200015c927da27403b6eb9e70d86555433e858539331fd72df83653fd84e8029ac263fbb2acaf5f0f833f9720d899d04cf5cdf25724013f48efcebeb7c7ec2dfb8db280dcfb1c125f429bcf4296e2572334d74b85db72417e5297edf0122cfc1c6c239e2398bb87195cbf1410ad09e0fa9593b08e7b10aa4e09c7e6f3825ccd1833a7ca550949e8eff9e01fac657e7e5e5e84c3f0ba569a010c4b5eb44d2f6b31a94197e2162b6698b4ada8f02072d925080c5c8934fd +SHAKE-256: 90fa125f0e327ae38b97463bf631909d5ca60a0de33fa65a8033822678d674091e38201c0ca732ee29c319b6ab2fd5173ab8ae36f57a98eef5a70497cb013a373854c5bd66299c21e0823fff4b274b868333b0b19eede58995afb9af478819d8dfcf48b06bfc2e1a315d91d2839d00eca22c0415438f89211c68ef710009eb2ef6b15c02c8e40e410183cb5177673746bd6408181ae12c2a5192b6c8163895bbc87b3ea0d4a7292df28e6e40a14c6ffd97dfa38c01511e1dd11e5ba816c2806f870477b73fb13e965a768865501ab6c7ce29c2a0b971ff1ade63277bbae3c489080d209022ff5a528d393905b45688b42e693a91788b109e13e19e85d16e801f356103e012fa5e2a13e40963215510599191573f38426427fc455d6bb123f79f7569e2933be29ed870ae0ecd39a35629baaede711bc81bb6f520455f22ea0bd16e016326c67e01fcd92897d0e685a6798f9da022c4e678011ad755a4b3b4cc0f6839a27f03df00cdedfb77532a77ac7f6690c6bc8091f4bc1e46079290bf2f94691e234a65dc9802dd6ffc9158c3326973410faae1d972d3337a0e4ff292642ae78c0ff1d9394914db65789545e582039cd232adbba74e829c95baf0300b2225c134492382efd4537b6c98382c0f123be28e249f81426513bf2c4b2aeb3541b620f6b8e8f8817e961442aef8fc820d89355cad04cc50d36aebcaacf646ae6cb4 + +Input: ca602596e85c8d1cb7fc37de34daa9cd0f6692afecfc25fde42a9230dc8e7e09da2f5da0db9eb2642f8ab42a2a69750f3890b4726d5a6a482e9aad1ad0301276eff7938524bf15d94e9d2d115e259edff2df1f208e3aee6f8e7548651dfcf52d3f71601e1ad7e8be6f758bef48bbee +SHA3-256: 533c392b55f81ffdee01b29a608866c60d9e083f817c9e14e85db645c1c82891 +SHA3-512: a084593f7c82b3bb74c18075eeb0304244476b5ea714083f1cf906734f200680bff3fae2de3d6b4e41c4eb18846291f806a7226071d276b8fb528d3b887fb8d7 +SHAKE-128: 8446eddfa873a874cb06a0b50a2afbe14a3212b1418b7266e096b7112de36511f898b71f8b21ba908c1923cb7279c7c9be1e3655aa51d73d2a0a0350e7ed50cff4cd002049c95e2205b65d4875d22d73eda85b15be2dc995d581ba8f1d3eb8a57cac8ed8ba30d9a358d380ae19424c0201a4462f9c38142cee3ea89f0850686cda85548c16a882bf965a64ac02ed6240b89225bfdf2a34954763d9146ce739f71f142b2fc1fab44bc3f859d3ce5e732f171a73993392b96ff4ba7f2900407b36a3ff0070a9d96c5d038b0f8b569ac913ba4e43f409c97ad7bc54b134eb6310656233df77dbac87215afca1b8fd1019e3efe04d3e2d77ac7c9669a1e75a406911d1549acbef941c505021340050fbedc21a5ac646bb378ae6eeae4293a6a742b33ce00cbb522acee956f6c7a9037a468a3830808b29ebe6118b39b690f6a643a80a296e45690cdb7aa5f91d7e7a061d2f0ba74b935c9b6fbe2dd958569b799d7ca1234bbb6f3a58d87bfdedc6b81f18698545072baacda7d58b88ae5d10cc478e53b56e6688aa449390a2f01fa56d25e0885127fd36a15d0d4a69073dcea53de893cdd4719378cd11b7ab410c7371fcc030e23f633829ee8abc3bf274264f79419696a4f85ee3fb58b2d6d3fa59bae3831d0bada3d1e9ec05010cd83c5e8a31f15da227f5cefecb795513c27a4693bba493bbd6ea3f44d3e736adb1486d4637f1 +SHAKE-256: b341658bd64d77ded0c1dc505522c1724827bc143879641d86db3459448d425a7297cfa5769f6036b55e6a30f70cdf98d9748ec7280316f3c51820541838b142faf7f5e7b90a32fa0e7b264340bdeee65dff90032f5342c9392c20984be2c2c1da6f30e760dbebd83b462624cb76105f56ef3eaa74d75b0fb2257c65c982529212d8a106c9c73b5a553066cfe7fd79723587a9762c6f79f0852268f7a84926d0d880477ca8a877ce137636971a92284ac78acfcf8215c2466bd178fb2c0fa1d5c0d68687022b2542696c8a5eb7fb11c8febdae45259f773fca8ba0829a7fed77ac2a6dda4c6364edc61d5ac740dbf6708f34da81e057570945e170b482c94fde4d7b2b77d3d17a2a5eef40075ef918fd31131f49e4b2cc2306ec2ba046d2f9f35b1145c6e87a0228dd19586b5b67d157797392d2e2da13330018ceb48a9e934908d0fd8dde84a272ba26349540dd449c08e610c8e30213a53d6094e3512f157ea24dd3233bd43a8bfaaf331f17d825f633432976fe77b050371c371e96211951807c6b01fc190e81c7c1cdcaf528cafdb6abd92a0c45f186f587adfb14acdfab8ffc4af2f16943f92317e44e0f6f018661c1e55e2032c36b93811b5fc7fe78dcb49078d23c217e0643e5e26626105fa9efce6cbe76fd8e143520560e43a131d215f58f144a55b80c3930f8cb5ffe9f1eeff909c170fe1cbf7d4571562aa238c1 + +Input: f07790b21001198ab70f89558b4d47a06ae3428ea414468610df5ee6fb2f7879031c6f6b7f1fcf7e81b17d1cd2c59c7480c2a9acf901557ad725f836ec714977a4392f9e64b151bbe76248df5a276c0c74350b099f29297abcaab97e033b2fc65ab86ee65ae0eff819d629f774cc7595 +SHA3-256: 4a50eb3417f00dbb5cbe1299862eabe8a655bfca87bb87e9ff5b6934099f534d +SHA3-512: 718d43996b9eee05f74d1b55a60a945ccf976411dd621dab7ad92ee78e46bd7f98e1e2d9cedd4d636c54c7bf13604d7612b6000fc1edefb6ca6d2037e3d46e95 +SHAKE-128: 8e57b6223a1640e667277d54cecdb342a1aeb6cd95ea1240457c43f16bba3fb9d2d83c3f2671bf3e7ba1f176cc910570326980e05668a9c80553a0011aabf5faec9337202f434bda9af24d02bb0d9e1c727ffe1b1b1cfe9a3ce711a090dc68da6c115e815823ed4be862305eda148f707c69d406ac95e1d81ff03beafbc294f56a19ebef5a09ba302141e185e4e197aa3e5743cbcbf856575cfe560bcb44a149c2e8e488c6ba5fae2b38a14a4ebef2fe64b4a9b1c23113293f02614e5d2d14018794b3fbd6ad606ec29c8279143b37234bea697d5a03c9fcb5a7bd92c4f0cf7a730c61e00ce01b6c57281a3e672012bebc471eedcb3994d6dae9d3b55ce70f6d5e61c85459b07c3ec94b5a146a27f8c804871697bf2b5fcd13d61827ca88191cec6a3f61cbe23c31393e5a4a10ba341e64237f19a0ced77f774fbff2bcd4ef8f262c07103a0e4ddc3312b2a3deeb9bacf947cc53cda4e7630da3a88f97c17873344d5343b30c2035a723311c0d7b60abc147cc1b4051176427baa3ec97dbd6534cf50d3ea3673417d50e64c9a3b57f2361396f60eb15b3f4bbab1efd935c73898acb6fa17365137001e0c0eee3a3631fc8c5ffe5782a8438f52d4d1248817dfb6baed20061a7dfda4aec5b83e8e386c27d359b342b70091785bd36782688410b5e260f9d155cdde4c06089eb427d37c2384d316767c38bcb046c2d21e9b7bfd0 +SHAKE-256: 3c852324bfb91777cbbed7229267951d47744eddf03b3c8aa5c86378e96f03f17e2f9f361ca9f2fcf63f65b31ac91db5b4f18e6202b854f9674c72cb9d1ccd3b96d8015d2d4d3f60f5b991c294eb9e8ab4089ffba3b8201d3fce484ed5ad76df3a5cafaa7cbfa1f29b17ef2e3e03ca1b03415207cf5c9a2b35c834398f715a0b979bfcbec19344fbffc703efbd440a9e22118f685839288ef6696a90ce7cb50cfce83cad42931dda697a5587287ab822f62953672f3d9ba7183e3f79b9a249886eb6f11e45c6abeb76bb50990671f9ac5f4bdc44359239587703f56b9de9a5f70bada9e84f560c96490cc2059a9fa463d6316154357533183d98f87d06e6c1812649b8e1187ba1a82d561cc514e4d26d4bd644094705407b30f5bc7cc9614c2d68b51b9360c0a1bd8bbb215087b8da38cecad4994de06a828ef11167e0f4869b66fad60a3bf813ad5350a6690d1cfc788a352c1bc3442a6b2ca5e42bbefbad8198d99c0c6f3f3743e73e4705109f40d72bdc8dc20f66d87fa7e3ff1267e96a8b956ed0eb695abb0cc18aeefe3c3df562433c9ddd890c5b97169090ad935bfcb5d8bb46cc4aa46456c392d4f26fd85b7e78f8a5a28854f828071e6fe94f1e18dd66f8ae81d7eaeb7da1cc814bdd43b70aa047d513748cc77f34a717108ddbaa20777ebe0280d68d6c5abd23c0844ae3f76061c4683e0e4bf7886de76b37df5b85 + +Input: 89f27e3affb00c9f33713b6c5abe419580593f63ef40eeb1f130d30138bd9d5fefba58983df50f6d4c29148ccbf2ecbb4495eaf8cd4cb050b732f185695d40f0ddaed73f43aafc27a56e5293df48dcb9d234074baf06f49bf8fd75f5e1e8843a60aa3124c621c831183e103753d8b0ecd2 +SHA3-256: 756ef5591413061a1b2d44ea87425bf96074a631d1646ac967def3befc4ef9af +SHA3-512: c56d1d68c249f1485de1391275815ee619f17a2186f8ab650de4ec1d4ba37071f6d9f1fa7eac500bc077dd2d4a8ce85423ac7c3ebc58e2bfb0909bac8969ff97 +SHAKE-128: 2a71995ac3b504751619b853edff136ba026eda8752699644822bf6250be4e7d422d672116394d1823fdf349fd1b81e4dc29af166683feb2b07754b052e31b948940e954cff493aff5de93080955ee57b24fd2c5c15c3359a065b9f8ab8344ba090ddc8a02b63d633c80354d61000a583b412b79a6b915e0276c9617a87177b9f2fe99346ed726187fd0685e9f2cd836a49fea3d443341affecf93ca960f441991886ac338d2786afd90df1d485eadc0570a9aa7c10d345d932ff09df6c85e1dc0ac69e2c6780577303c387746c89402f0595a1dc6098f2cda5ece4c071ff43d6fa58aaf5080afa7c8b2ddfef61ece3365cad3cd2d0dbe03b603054726d77e83135c9775171167a4450fdfb8179ff2bf749aaf8c805572dc111d494ab04a4bf11fcdd681d16a70c8b96b87d23a46fa457b2c2a003e8813492a99a2f4b8373a26779a5980000fcfece7ba74fb3bd8ca841dbd3f87f5f02cfa13b88f94b3a523676f854f26b05eb854ceb505429151303b3b83d4b88e068b3cc35d096350990113c08253fc2a545e0d373f2042bad258aa5a029d5965bcf4f585b38c03f7f310ff62951c68f158afeda252ee369cfe7d2e57571fe1c19e20971438e48a2429e08f8e0fd8401468e20183d6d9fe7802c289b2118f5036e0bac92ac69b5da47800d7194318445bc39defe2a5c7f7e8cd46ef4191dc6915a424adfa8c45ba9101cb8e +SHAKE-256: f15a62d91f9a3708f1d1763d84b920b46786935ff6234f8ae1957694087ba3205daf3250bb26973d64fd998abfe82ead5d394e95c0c4838bb5989a6c343d5fcefd7b7cd5904c78de0cb841c93fddb1311edb9b1c17779739855b53436f28e5d09205e556e68391d83e4a6993aaecf09219c08ab579690903dc6d33a63aca7f74d03f48e92f25ae5e8cfee869104169e91af08b23db6d8c26c69c56c6452a37b6f7c36f232c9f91b7f9a6ba1666b5ffe2dc5f48ef96866ba6b9a08dca85a37ac02adf961cd5b6fa947e37233121afb987a09aad66ae7d4ba7fd1c5a754cd295269f40b19139bc91d199b1237d6c805ee1fff71552e10fcddf349217feb7e39ab9467eb91d96345abc6c17ccbf75fdf06cfdc74ae29a7f3355b2e72f213067aa3b2b335f7a673b85b392859b0b49a1d5dd539c843ace412f3e21558bfa415d347ef5c3ecb44d8ae91870f6da3da2b16b9786bc8dfe4dd92a93ca5b9c3826649d35616c31b629b8483b1ed1d2f3901a77ef5759d6db479d611ab9d6ef2783c9762c32a937399062b7693c3254fafbed260b154cf3c7fde7f5a864321136760a7e9f58a8cade0e046a2f4d922c78702dc6ad1da1fddbc387cc35df7db5a2d883a8dc90224f1e0eff1cf8cfd74a4c289ac9a1515a01919f587d0b3233ce592eef0394a81b9727d76a3ab47a58d74d08dc2b09db40107a621ce5e33eb29cff527e49e4 + +Input: 73ae72dd4538f9b6e578c03bea4997f9a52de49ccfa6f9f66d04b3bc3332ff218180169592060ce41fd8de23db05dea9ed9948ae67ece5cfa87d5beff20368ccbb27b4757e466f3a038ce7eb8d67a1381c757792f052f11610382d48aeb2927d120545cdf60a875065868afdff548acbab15 +SHA3-256: 0588b1db2bca3c8f29d4ff13b932e5de8645c3958aa846032fd02f2279ca8f15 +SHA3-512: 34cd81ddb175a27ae15614896f32f7f0cf5673476abdab74910d1e4b9b996f41b2634a1cae08eb5ac912347f34e9a0ad885f8c272ff01f66e23521ec6f5f9e7d +SHAKE-128: 3b25b65b8dd67930da89729c9d04809450b35a653856eda7365366ed420eb7ca1d4ac63844b0d01b0be7417aba6233fd50975d49e6e2de82a61e1ed6d5b8aeb44cf4ac985c0015f49fc96eb20ea92cfd1130f697308da87c79f1ee89926f29661f38696a633b392785fbd229e25a10164c87b9a489157870db698f3230c01edb18932c85fc5be79b0dbf1d72c9181e6a00052615c50bd590358fe8b44214a411a682f469781419a6f2b4527ce6519c2965979892c5ef4f0275ae021f07f5e30df0bd171b45289671585bfee6d577b7b9211bfddfcc479e5eeed5726b8663e42700fafa93d2d2559806c980b3c86d2fc7639b8e467da8d060085469ed8f2f5d28d5700d8136463611d583f87bc7de93afdba4b1d0814a2384dddfa2e167538aa21765b75560d77ddc5b24a0d1e065fc5b1059bb862671343c4eb6bddfa74a37becc934f70ad8a9efa535623ebe4cc1fa3c4a027c86c40af58a4192f24392d6a95f15efc13adbd073081a131dd20c6fd1da62105eb5b6829be92dc3e00c1d161db17c72f0e03ce5c0da930e9758f5fd71f184d3fc5829c3f863fdcf847d61283e990fccf64489742c2b7e8920c1a0bb7c84b7851f19f4fb6a8d7cd9dc3160b8ece8f49eae69085a12b0f016232fa40c35bebf39b02a5c3f443cbd8e7ee53faf9868eebe01a1b64c19e16647eaacf6f1a85f07e59eac429e0a2b1a45cafffd31d11 +SHAKE-256: 6023874f432b60ee32d8d1090046d520f83c095458a7a27ea632d1fdb8c1428701c62e13a59a2aaea4691e1d06dde6bd2ec60491f7dca4aa1577c3240b540bc72cb851dd54052588cb59c1dbae29f5e8e1c341905df6d09a36fbf5bcba287c29dba0398434ff8a69fe0332b129af03a6f40d9a51eb55512052deddad3e1b8cd1b41aec792b070fb7d9a953bea684113589c9caf38696217572b4a9612329f9a4ed5b93f5c7aa31ec6b5e07fb2e2e0e2fcdf843ed7f860def0a1c8758dadc5c80c7c959414d7cc9df6eb6f0a22564086a75f59604333976c6da1f2f7878a69fa5cf211395ff4b890e7864a1aa44bcaae3509c2fa8ceed4181018f808f945f36b21a8cc2aabf7699ff722ada3121eae9d0b47dfa55dcccbc7190c02093cc8fac37d81f54f71890a2c5960fa0f9e19f86a29e7aa715625b74e449e041a8df3e31b1004bd897c157fa326eaa4db7fca6ca7efd821ad811c0f401057d02bed122bbf394b8f13ec0a7c6541d7464a9681136d807291f5d4ffa975b27cbd2a270ed1f1b5e408db0923c845aba3c445279dddf6750eadaf9cd454895032cf44c09b42e96fec0fb0d89ddaf55359b68732719a059106b023bf81bacdc88f03b97954a34f348da8620d7aa2c2d5747d38c10b4208c331e1a1405dc3f93a81cf1051096340863a3bb123ac32c05f7995f0403137916b67c1c7f381e5653d16d63e05dd78014 + +Input: c2266b0009cc5bf8188f06a7eac129d916e340b0b6213f603f81ecb490cfaee610626f9155a431b69f0fe6e40f7bb6343406b716c541a4cf2dc36823635e61f972ead865d781fe3144ef0ea9c5a22b490574544da6019f1f8ef09dbfdbc1e5a6b7346b1be9de72109265eec7b9cea5493e7dd3 +SHA3-256: 150903290db4cf71fcee3aa3d10fe38927aa450ed0446c49edfa861793c98deb +SHA3-512: 183ef809e5184a1d8283fe044c5016e5f9342c2da3db10e703f2127e7c5c72e72d0a41a518615e95e378b144a3d0e09225717c44157830844c5bc23a0307b21f +SHAKE-128: e8ce313951b79619c22a02618da53d7e091e4827468e7cfe74aab373cbc2d1c3a522a35890eef7af22ea6719907d4f529d2c0fc73e01606882f9de38f5a89895692141bf07e65d876aaec9ea5c11464684a5387e44c03e1e1eebeca5ddbf911dd81d58e0c90b4ac55ae6c49040d72deb303ea51ae0fd5f6cee209986e9094bf8c577e4f26736c12e952116057f7ec158b933a417126457b4ff15f5e698356472b0ca6ee325acb45ae808ccbe9cbaff49a412c13e322efd1a165b8b5e40a68cf0bb8a415f9824b3ba3b1bdf3041024f2898e75fafdd259c8ab35197282007d1d43bcff9b47190c524107908fcd693ce0f4d90c3c0aab9088562b84c25fb8600c56206f73f9226cf24a25b86d41f7533464cbc466c845af0bb112718bcd14f3f12fd7e9263fc2eb67769093b0f6c6fb8b46fb04bd63a4f0207ff12ac8240fc0f4095ba5acd64ee48513b939e384e83bc7ee97355c03eceb66c6d3eacc640de48362ac15f43d54e741449b18cde04f9dbc032b0126460e8d5ff4fb3e912d5875ce8caba98e4cacbf31820d4450cf318a230a3f29e18d6ce04ef165d61488bf94093270aaafe7f8b8d14f4bbd8a95bcb23170c784c34969dda2f36da089103d601e2fba262e0a560642b77435a32642d105b388f06d298651c5df29ab93a9e09c113e22ec2e1d71f660a96d56162d6169db3fee567633652845bddc8742fcb61cbad +SHAKE-256: 1beb9bca6135e309311dcc248295e0a0d8fb4c94602ddceeaf3f2c59e7b989ae40721d407db96ad71bae049f0a325c9c5133b585ab788e360ee22d5e3ce71d56f0a5f7674ac3ab9f16f47a47446b00e35c9ffca54e4637005a5fcd395754abc7dd7b5fdcbb41e561a76e5c97821fc43aec647e96f7cf3d5fed5adff3e360af41404c6336e1b61bfe2be502f99233dfb1f08018eda247f2a96d17302837d6278854188cc1a8e3344014cf05b9549164a55e6b0d31e6fbc358799d59ed4bc1244f3069ec98caa805733f3b7d89622c9394b5cf4a6a0fabe5f01d66da7f6a78fd92fac492c3caf81f54cc03c8aa295892bbfae8d9a1b262f8afdc29a78aba155feee6726f99d119609b7a803ef96e980f53c0825ae85b6fc1cba3b67546447cd8a3090daac43f736a985349d46ac66e11f8390284227bd975cede4a85c847916140f91dc1d505eac37b9a29238091a31e9ff0baa4e7ee1c6619d93c23c532458bc9587c1ee41cb8e057122509e623aac6db0f25984012ce85b77fa3ad83254ef9d4965bcb708f7d1c7840276a53bbd17c32eba2fb4bf337e432ddfb6b175d26cf25a2d1d8cf59f4d10df6c8b8aad41d78e7013c041ea4ae4c6ce7e1cd6ab9771b9f1b5110b27ca392fad00a95868d9f945b036b2c83af88986cf95fbdf844f84b5bd1beb8dbdb64f29d1d2287263f810b0b546af929f28f2fc751746996aa5d8339 + +Input: 32cb40435e87277bcf62c24b0b695d97d56879f9015ea48c82e1dd43c1a2161314dde71d16fd6d2d9a5fc3fd21f8bc8ebc704ce75afaa53e6195b2e87c9b5b2dd839b84792307c84d6c4d8ffd87769c3eea0e35b48336dc4d05713d6db16345aa314f27b2885621fc1b2aa8e107c3e45bcc61626 +SHA3-256: 4713623868d3438760d1edc51a2b06aeeff6bc51c9cad4fb6c87c432564c3786 +SHA3-512: 75966495292dc84d1ebcb88e9322393435e18443face019254bdb576639e5063a8d2f979ce83ddfd036d86a7895b19b21c984fe70e7eed6e2691366765e927fc +SHAKE-128: 2d035aebf8bf8971131a2c84c3a7c9b118ff9d2a6bef0a76fbd617e26b63ff32f07198c76e096edcd0fecbd5f5123c0c3f5e7df76502ec9ab520cc6967f13e927a43487889afe5af9325f7d1605c111132f4dd49ce3b53ba722942fab0f377a25a267ddc4c82c6c5656962a0db2e7e6826339e6c2e37b98eb19a1b5eacd159f5cdcd139b13895f168d1a7b416a96404f3d76e5215bbedd0a12c7ad3e2d09072857f645d303fa7300a43f81be90e70da684a056b5b497a89cb16673d92b5c557708980f79d671bd42bf46bc22b6b50ef3f1ba7a4596e6d78476be6bbe2d0f9a3d22f4eb9358af8b5fcce37045281c2b1c020424a57c262c69ce74d5e0af96babc3470c5d0872fcc8873c4f7ffd772d67d3f80a3954b6be05d15d4dfb93044a996a97713487e614149cdc7462cfef0fa4c0c27b72f985d3fbf91291d35169222ece7c3534e4bd7fde7cc39e5eaf2f556b14c9947db2fb996fbec1bb9f54471ca3d15609b5a9183f7529ad666a281968fde70519a55209275226e0569d0b1d2267fbe009ca1a0704c2543036cb494dcc8e50f891445401be9b0701da81ccc7734d021b98de7f72bcb011527ddaedcfae4f5772ab3b8fc04fb9fb4cd3f4b88bf9c9ed05fd7aab5e4f3bd468d1492887762dbf253425e304b1f63356a51c0cffa669140f3e5c92157ccf26c520eb2399018ab86c50ae4a8710757a49b723a75cc8f23 +SHAKE-256: 893e2df39e247e1e0e52f20e9ce594e45b084cbdc8421f72fb18a1fba20c9c11390e332d31e487fff5cf2c3c63aa4875a16673c462329a24154a14d4015421ae04b4bd2577db785549a4b0eb6361365612ea56e54b9b0e305b4c20b25816eaaf34992a13a4773f3bb2b602ef0f9d2e5e185a8f3ef8ea75b07b29ba19e4af55f2c5cbe0ca769a4d229ad51c46707d9ad2fd436b76a72c2115993c8135b69f2bd86075aafb5bff85467496d0e69468730875f3785f8b3a07c5e7338741fb1752f4dad517bdb01e1708af74d893f503cbcdc930261696d1e6b65258f0a1eeb355768f48c02e8293fc8b190ddb12f4df057f1e70df2dbfe99c13147d6c1bfee0250e2fe38afbadefca63945d3589ac5def3f2c8fa4bb152f78d2c06ecaf548b190f4670703e8dedab086651f97e6f561a6b61f0aad0a966813942773c1b5e2466a26d97690b30ea2f7b06c81b3817bfabdd08b794bdbc500cb35963803efcde65b00c6abf682c276e1efc2cf95247a42893fe21998367ca69e8a632c8884485e34471caef2792a312dcc4f9192685a34eee9e4059692c5405cd7ab4aa61c32879a4a358b5f610eb09e66cef34519593dbf8460d640d6f604ea903f7558f8c22f6a8963445b5d77ad14b7d6f4f0c0e5cfdf01893cfc39ff85d4e804041e1b62d46eb41410bc52c21f8eedaefd5ff4e55fe2936b9bef5dcf20e7e242513f28da91cd02 + +Input: eb97a9f7256f7f1d01f8985b36cbcfadcafe70f75723d87dfdccd7a4dc812e13f081d533e5a96d666b955894958f61698c59aec84573c16aaa90178b34e2b8cb2ad16d5e205df48fbd9f62276740a425a1ba09ba1ccb67e0c0abc4cbd9b521cdf38f45111b841da78fa24f26f72209ed7f207e08f2 +SHA3-256: b23993d84586e9e505140b3dbad20550c69c39d0ce23d2adf58778c86535940d +SHA3-512: 5a7c24a6492a33485415623a8b28010f5af942eea03fdadb251674e08a02e86283ac1fab281340b6fedc173e26c1bdc3a740d61c2174fc30cb455648c4ddd823 +SHAKE-128: 38fd19d8a5bf457c28150381774249ca68d2de02109745ec95f832da44cb2c7d8f290eeb3477347be2090e1fc0c9cc22bbecc5aca21d01aeebeb0b64598985edcd59147d0a13ea1c9ff0728ac0f772b1b1cac9038b916535b7d4a650b3f87f925e48e2a0d9e9be0761d37e54bbae6bd16f855e1942b326a5d6e86de47da0879ff3a0c583bab074dac3fe90648f4d83b88a7fdcc7b3017627e60f79ac70103a01e430123888b85dbc31ec75bccbb4e69baf6396efbb94b809e3516f9adad1d25d8f85c250a729f43e156a16aaa8431be3cba49e66609680c1092e7f8bd0197cad2fc2264e451aa37af63cb1e1a86413ec86c5079b98f4b91abcb10ce5d4c2455d717e14dd93d0e0888520543fcd6e3000d4618c4bb93885e90866cad9fce3421d96b0f512aad3c7b4fd84f5eed05ac903cc11f3aa7473e85144b19fc66d28d842a7fdfd7eb796782937c12bcc04d791e5a1a394d7de47c1937dee99454a27d6308ad4c20d7f523a9e2a83818de0546c827116d439067323875fef53672035755d20a5472e637f5fac387d039a2dec1f7e6348179b3b6d914aa410155e1fc69044952610619a974cfa406be4f3f8d7ad710a687ec0ff4d7b05effd61055eace3a82ebed5cbc4f6a26d326d538baa5eeb9cacfe666689774fa14609d5919d6ae067fea3a907b570a28d7a5f6026c2dc03d09640c40be448c8adc96506d22a025bf2 +SHAKE-256: 7a9ba6bd8fc0ff9b9ce71d5a9280496a32c4879b9dcf8bacbf0b1d9802988373134e43fd7328d27e0c2f7c9e39de67ab048ef2e68eece88e9d3aa7539338757c0d018a8ba97b8afa28eca0caed9428b79871af1cf7e21404ceacc440c6efa42f1f40dc9764edd7cd590e5b339cc9e6d37cd5543968389da4599096aa7958a5f90bb272e9b8bd447445075b730a5015bb83741e291d46fd7ba3e49ac280108ce424e98fddfd59f645d50095f45a887909c5788f65df59fda726057d747858d563ff51b385598789cd342f5dfeb4d7e2786cfa24096cc55b76cb311b2581a963b8ed663ae47a13eca74eb6a6fdf0b1e75ea51882e8f42af5ba5802758f933d49326913757d4bbf90f95bf7285607d2f188c01e8dd2a6bab4a9f880fde1bf04f7a2870d6ee70c4525ab41435e0dca0dca38e993a25545ce1c3a02f52f998c3526029e2fe9a69cf20b8e6051c3324752c33c6bfea44f18e3506780a39ddfdfefd6da88f57d4f0e6735138046b4578b700a09a0437e55ce45601d5e3ee820f59d6476e7ee74bc09f5a5a9c5d170b2238690fb24a9dd19ed8b4c32696aede4401276c04084d71cf47e2c288158716449b4f54895f5dac13bdeb724d636caabb9420ff42b2cc3f01785e0d18df44f716a016168b640f29238654ac351613d8936f7228c2229a2e9eed086f19348e89b1a850dd4bd34d4fac5c87de9f16d29a47989e0a7 + +Input: 41c7e9f0edbf31719ca7de349262e2dab8a810e053b19388b0ac26f053f927ec86fe24f45106c9762ed2b354dfa34c5deefa6f6fcd4d612b1022ded6b30a9baaeb793f44b65ddace690e6ff507609979ad1e90ae49339a3b8eb1b8b126eb74e61804b3625b73b47708dcb810c731e0bafd17c7f668a0 +SHA3-256: 712daef73d35c49320e01db642ca593579251a88bca8d8d147a18e3cb96eaa05 +SHA3-512: 6b2a7533d54227e40e0f706dd727aed0ab7ffb94ec30318f2452543a30f0c33508715cfd5e201b3f0f06566c9310ca3cf268bce53a45b36514eeaa23c03f03d5 +SHAKE-128: 51564072d6d6ef14e37a534fc76d1a28d5a86806b6b15a28e0356e7db311f118db2c2902383b3a965725bfd10bb2e6f3d976170b2d6eb473413db481c361209fcd1b73b9aa3ceae64d4dbc011367030192fbe23a1f8a12fbeeaafe09803e6de236b37b87792161e01036a31baa2fab5abc45675a5627c5e864e0e95538553adcec15a42a7ad4c520991cf7d7ec58c430fe6cb8aefddaf0874aaec1d91fff145c8b5ad494c2d390b92712b19019f4092c6a6b186c66d3c06ffde6136904a2aebad6bb211a66c97bf71fe28c86406ae7ca135dafef79b0d2e0cda51e4cb2b20d66b5ea24972c646f2bf52bef2fb06add84191842807b678ba7c67c34734df131af8db12a4f5cbc63eecbf212393eceb7bce20c2d33538fa26371ffb86cc8a33f526e7976a5b4c6f450271f7ab03f5e951dece9896b3ab27581d94200dc4be1d5c784ee118d63fef89566c4c49d3b7e6f4606678344b3c650a63e68b718f924bed53550b13e1abbc474fa62e8866309e52166b4ec40b98c0f98d66b261e8020e7bca033a19ef1abfe38be70d8178baface7591e6c9f6d377969dfd8c0246812c7a28e87be780a4ab4a4a567303e30d15d6268e8c4a6c0de18825c8ac457a572837a9d165fd5980096e0f830b11be7c94a6f3ba8f0d2d33291a259635fbc9b3f1ec444f1b6c7a1278d572821260005eba3b529e500e242b32ddc37b26a990d22a982 +SHAKE-256: 984724f2c422fad05d484415250b633501a59f9dfe4de2fb51975e1b8a1a3f65557865a7a25b8d9fd0a7b8780c2c97428abcb0d0f2b43db9b301e3ece6b533d9d368820e65040b0d1575f8a10142802fdd5c14e3ab92b675260867b2e28e8fbbcce98945e03e8bde3828c0b83637621b14f4d1d5ee07e6730fd963acd0000ee29f33649894d792c505950ae4c0c9181ef94518e192ed0e3cb75202ced3d9e19e2ecd39ba5f7a798b81fd8c17328674307739ba483c4c9dcb2c4561227df9e50406cf79ac386714cd8ff89fb9d68f619bd1409e2202a8489b9d145f87f3463d82a21bbd5638ffee146089fd85fdb759890fb714b7efcee6bc097d2cbc1a3fb67a4b70e8c8c6a13485384ce862bdf7edec2460efb7c77f0d6887087164d996565e2a097e815ae81afe5e70bad418ee1f36c1e8426cbaf76cc92b828974683fc573d0eb6605ff64dbb0fc5c2c6ea8ba614adfa2c6114734162b07fbc050483f4e1525a6ad629f9cb28172e9ab24dcd3090f4899d64430bcbf194f8f0edc90a1721cf6c557be71ca28997295d2bf85cbdc41626281a55e897b322ebf77bd3ae8b9bbce9cfe21789524fb7a4ae17bb1db1d02db2f12d2c863e858a6aa6c038c23e6bd7111fbcfe97ad71212820c8cab56bd667092065063a7bbfe3c47ab353413cba03accbb1edf2d93b905f8ccca622edeefc16840814978b11618aa815e5b24909c + +Input: 049a6c914cb7ca30f499deff144df93af7984bc3c0388bee7dda2574e380ea8e3f38ecc5a60413e7a4ca05f46596f5140f8732f362c79379d2692c7b4c4a7108a7aaad4e855a2953b0cb68c9efe258c63f69c2b6f6dccd79dbc373765666fd41fca6edbc820ba1d4fed7f16207b6bf3a862425c62194d1 +SHA3-256: 986905859363ad095848b5cb0407b64fa652173d8b164e6c280df8f21dea613d +SHA3-512: ff7fcf4086f68de574d792046974de3e318ff1afd7ad87202b28ff95d98946b12aaaced29a6ff8618100b0d139e29951159dfbc23b0920b572136a0c8021b950 +SHAKE-128: d1a14bf38a12924266ce77db2beb6a90e75b6d162c4a2328332048100e1493ca20ff10004bca77df9f095690d603102645025894a75a41987f5031798b5e449c2f48e2bd041b365a7b296bbf7a2a2ec3c4941ee377be1881536c7475604672a203278ae35b4c645700b1237652a90e936079aef2eda1b0ef271825ba9bbe8923af33dce1fef4a4190db56245e4ae77e9306b76dcce6e48ab9140f59922f11a3e9e7b76a4780b95ebd095a842ddd93b7184aa5cc668648c1ada90916756ba4f37a430f5ce601bb8cded574194cc711c0da6080254bf985ecf75c17e34bb3c06297c0a08efe763c69f9c20bdf2a81f1230ad4864b88dd35f4fe3ebff8acb178ac9d922f407b347c76e8d10c7da7c16653a009070c1d58fa6842f4fdd28290b9575fac7a396e317cd5987a0fe0b092a53e3f151c486dd200d83efddf14dda67fa4370dfb65ac53f5b61c30cc4b1158fa83e45157b661695559b2c01bd3fb60a00a5a4338202d57a6913ebf2b5773db03e7f4095570e13a97eb33affb25a7001626cb1c52de252fd8a697f241d22ef7bbee7964cadbb4e91ee3d3adf2d1e79effa061474b35f6bbe9d2c9e0b31b8e7b1eb46b09fd8922680fb56e3744b5ea2a2258cc2c067ed06bdd7e03a46381fde1d461496061947b3b9cd4d8c21bc5bb00bd6153ebc98a7b726b356693ec652301275d14f5a386147e5acdc20948e71191f99a9 +SHAKE-256: fd2844697dcc66c47e7bd76abedb348f745c2a61cda353f260cafc52f98eb49c30e4a85097eff79de7580e857212788ae47700f71c3d6d7c27cfa01916c96dd864ed728fddee20ba9f7fe0b0d6a93191120d803a89a1c27129f120c061aff1375b1b495383cfaebeab141265d1ab730b60720c23455442268a7cbd1a315923c0062ca297a550b8bfc1eb2e3d6eb8fafcf4ca17bb2455152ca8d724ad25c523f928fa8c60d900a39fe92ae1cbc4af4fe04a12e71b1ed1f3aa4e4dd7787261f0469763bcd5e9b134a03916f1af0f028811c748dc5d03bfec40a83b469da8b5395c9969a6ca2a7b0f64cd5b4ef14fad89972ff766f234f5bacdb79886a14a84f8e38b5fa2ed396364136cd289a7d1e9fca494123d660d429e69779653f2e011b416d5c93c07ba93fba0f35e36d88a3f36a460be12e27978f7a3f3d9e59f78ca7e01647d41b68c116c5119f83cd235d99ee2277d3607f5b869f75185cc00a72d151be161ad6ee9a303b3c1cec8b1221995a4734aef396a581676f90599995e91b74e8bb076f8d2b823d7f607e4c0780cf9464fe28f05a5673eeb1aca9bec81ad53407f75feaf7e1ef8f86c3a6ee453ba3cd411e23e307b482b6f9cf69e4c63a9bde328a8e1b7ec7826f5c228cc9d8b22b1fe44c638e7be8ed1219adfdfc5439d1d4ef85bdd33d02d00709ec5dd9e529fb8dd445210cf70dee720aca690d2f34a873d + +Input: ae63dfc2f09be9982adb090e01e52c32c644af813d2bba345703a6fc28ed4424b87ced5ca6082fab581ea087503dfc55e2186201652fe6eb3ea2ae373a7818cf5db95e2ffa3d3866bb626f5eff7fc489e8c511cbeaab3416fec00cbf5621452a429f7263df9f1f837abbc81bbfc98b86464a1001bf98cabd +SHA3-256: 4f3dbceadb4ac0ad62f08c19cf060b3a117ed368c8b4ddc83f7beb91c8f7e496 +SHA3-512: dedbfb6569e2f2bf633fe7bd64e6d378a66e7e70062d5a9ee2de301ae64297c12586c3362ce6d9eee22ff6605ab3da4755845cfabf6f251182dd5b787ec7cc1a +SHAKE-128: 5409253a0a57c0e0b7917007fb91aeb2b9b97c8cb06ebb1063d9170a52b13d8a1e2abdb8722c0e6b083e7deb5abc8115867804b6d6a78e6ecb2589938b4a749ca75103272b73e733863443a87aeafc95d842e59316ec665dc80b77ab61a9fcb6c5bf2fcd17850c3281b80cc1faa94b88403fa4808b7bbe2c9f7d7e9f7665cc593047540e39b710a37d56ae9ce2f036822a280990935767ae2e1dfa8c12b3606d41040303ab635d2cb44ac050f2724bef9bb2ca0d665f448d0d01984e1e83159fd956f9dba37b00af3dc83cf66fee4674aedd018031cfb140d6eb17f2b6f1887811291fa50608170d10cf19bf137b9d16e15131d5e906c6e7a850b9297a876f2f0573d2802900de26759c7531ef8c9ae3ef7597cd7bfef10297f22aa79643a49ed6df8fa66e72c5f420eb44ee4d4fbd648e8c21397b532399b4a997039e3b1fff758aa874073bada425a29e356db0a1df20bb0ebcf8ab945b4f0addc834402a2cbfb6f912d68623e33ba70270cf61954a550df1bb116288667f8a05b5e8a066f6be76976393cb4c2b6462c17b6d3f8b61444056a3310528f98d26cec739bd7315b653d4a481e24adcba16ce11954d2022a78667f1ac36d25f00894ff3a356aaee2dbb20681a058b6af32e0b39c5d90c7efc3e45b3771e2d365d4e82a4a7d4737b61dfd6b39a4d0100413111d835c6d533c9be207fde8c73287b8cde79ec034377 +SHAKE-256: efc6b890389fde367055837a3ee74b3fefee089ffa75fc42ddcacf98c81f8ac0ecb05df104b5a109240b1c6bf6ac2827debd4c926df2a34bea7dca98d9842f5c5f04c4aa4cc1cbac86f4eaa3bf904528b7ae9dde02932c229663fbc5e6f1b4dfa40dd48f2c3e6b28fa63e08f2442cd811346a3fa7fe5cbc3d4054fd2a99d63cb09e72521ed67048f9fb6fd579ca85d19d65b409f0212ed3cb69eb05b5c010335297f2156cd786d86759043649775939df265bd2d9765950c31a5512b01cf992874ace7b64035730eed60255d30b713ad2d45bce4b30334d812b297ca681b4de8a6545555393880b96d13054cf05fc74fcb8f29be9b9950fbcaa9b3dfe93582c184b9599dab2aab8660ca93972c8d9595e20319292b967277156c351416e2634785bbe370f112e222f78f9b50059ec27519377089dca2fd2f1a597feb78f972a626a110f6f45d99d4f9d72eab9f01ec3f16e9aa44c284daee45e52a720d271e87593111c57f0d710e31b8b299a901d4728a22476cb22b86c1894f1856f9d609525a906b6241047b42903ff110c7b007c55514e35aabb15284db7903731e128f2f77fc1da63687f96f0edb47a371739dd94de965d4a3372872ca20a32647cb42193c68449940ac603b51d71f5706ba0d6efc49763366d74164f038f97bdffd97be0190a1227fe696b8231af9059b50a0693909866355600a9116057dc0aba921ae + +Input: 28001497cb75486c18ef2f28207ef12403d0095d7d743fc0c43363bdfa155c7f3bae0c18ba1fc393b48b360205225d7e09f57ff9a0f4967a7bbd632e63b49a5a47861b396cda2324528f0d8aa4ee23d04f9d19a7b06880f957bb5ff804d7a31e267c6041b3a64417ca18bb89bfd90deeaab98f1058ecbdaa68 +SHA3-256: 737a58a3f767c1eacadbdb0694c842c65e65d3664b219ebddb01f0ae80769b68 +SHA3-512: 61fd02f4402dcbe34e1f610398df54eb64d19f6ce76bfe42ab4bf4e0a6f33f79e26fd32324fb35dca59e16e166d49c36164066b1ae2ae1cbed573289a1235942 +SHAKE-128: d937e6720115fded4915f00d19aee91c9c7dbae74ab5310153a658db55b59193875792bf8b6c1a8bd53d41c3468583dc12225dd586fe66ab48a831a255bc3f178619ffef7e3ab6787416db187c17cf82ade24ec585540203d654a70b28b8b2dfd88300e3feae3bda45d383a033cf8dc2e82725d187a40c49577d601f2a013eb6f38bbe4af4d496c4d1eb3d18c89759b2fc37719722ad3b49dad8da54f48a27e48ccc56cd711be02ec4016ff823d2084eb0ff783c71cd553282e02c1470118281d8685add175a1f57392548429570641252b46bcf72207943eda715d53073b15ee15100e7f9de765b59cb8d7090a5cea53e52398216f1edb7e819713ba19475fb6209e2ba712def04025f5d6f114c8508236026baf0d45e0dd828401602bec46a1796ffda1df852fa992e17a1ebca822c91fd2fa6576bfc8ccd3ba7b18ab4a321ecbcb66044791dc25f5e8d5bde77b39ccda620f088a282d4058b0a8081b26d03410c11d80961f30fcd83107dd6696cf2e0542c2c18b0409e7b765cce710fce81e8c41ffec307f1623547c1754d540c5acc43d2956b56bbb4fe027d7c07e99e75bcaf4ffc15a67ef5175f194f36407ab6f4bd77a57493c4d5f61bcb0b241dddd1565ab2bd8893afa00e9b427518a9a2807ec88ebbbaf1acb6734836e18539700c935dad6ab1fa79c1814d08e69ca29a53142d72d9726aa0c9cbf14cefa269ff1a +SHAKE-256: e4e68f478e81c2ae1aa8396e68e9a5b69d4fb5ce79879652ad230c3928b3645edfe0329b53c5d728c95b5a89cb74bdd8924d40ee437b8837c5890e539e49dff20e1d55b8ecf7956f3224eda53fed98ae7223471e9cabb94ce2f7428e76695c4f4ad818f954997db7dcf58ab960aa8e460c342d4dee393e826aa4d991678e027916a2edce6e2b2dc8eb52e5eed290ff653f411970b9cd05482ee31c5294a3aac3507884a600143ceb8cf13206db86a0f33b3050b9ddf49ed6f6f8a0d89d89b24448fc3e9886812841a43ac0505768b6d30b2f7cae6f927d924896427a6304c1ccad0f97e7f32c379c9b99a7cdaa5e02ad7c4ed8894543216cc9454339aef2eb2ae144ba0a478b16fb652bd48cf237d3784642fee8922d0c5a3b2f741019480115b731627202148bc26edae5da5530a754b2c40f5dad45d824bfb4f40c0f71d119a6ddd1a43f8f599762a1682142bc3d5bb46b8395f778c853cc18521a8d5ccbc78fdc0a05b34361440fb67150d6fd9ea5328dfc8543b3f74a29fba90ecc0873b8a593806cef07e21ecbd60ab06eae15f4ff4579d46a4b7030ca6cc97a34885bc762381b44523b5f7099331b0212d0af43402763ba319feece6201fff803734d53f476032fe674be2acf8a7a3d3c30f4571ea29b3fb2105be11bfcd38e2f644bd7ed356a71b3f3dcbab4da944fa0e0fd822369e9131cf51576040c113cd66c3a6b + +Input: a6cac62be9e7f2ecd19cef222384c6dc668c28026d78b3be985d29204a842ddeada52a6d6a620e0f57b6c4e74ffaf5398a32963904e77db01b2077aa173a23fd3962fc86ed1318a629629e882c9eae89db1246ceb739d101c27f48363a658fd869c2ed72c277d680d28bf4cdf0d396baa3ae79d4ee7ca52ff89d +SHA3-256: 22e9643af462293ae170ee5180840516c7247d0bebaf524206a10178201fe554 +SHA3-512: 1a03ba5b21ecceb5928de4f2361b8506caecf131922c56b9115545b781cf8b232d680071561e433793ebfd2773918a11d449eab2f4f116858263afc8d6e14cc3 +SHAKE-128: d6a7cd994b84489b1d670c126141667f4de746bdbac6a3e5adb5cb6f174ddc21f586ad0ecd6322434909bea75b1a25530a37220a857bc25f2e3b220e9aa72c9463a36451e06a951612dde0bafab385effb32fa49edb5aba3998d26c986fb40f7dcca114ef9d9b0d70fccfa05210642c82456dcc56421f1b43ed02dd1fdff266d2e87a1dbe991269d16046d7ea437263402a3034d4b53011aac19829001d6344cd51b1623871f1b900253108a7d632145b57f6edc345945d592222b173bc7338e64686047aa1ce76bad45621d91ee3f0050658cec075e412549b0e96a9a465eae7643b0fd2b0f89790d677cf9678d0ca641c5284bc4eafadc6ec200be69e120e917ffa07bed42d0c87081aa7713e7c3f9579dca816c82750133ffbc1bdfb1957e75b8909b6ad88a35533be317f7a6d5395caa22daf43d6f98ff231ae224a4d77bd0340d338913c45eaa0f9dfdda49ddb30274a346e53957e1e0b021adf3b113427c3c5f6d0103adde978f0a297c381a516da895391b5e61a34c6005271fe45192288ae4722d0a03d1ff2adb356a50cbcf6520bc11f4824439faed20c16be1498ae1e3a854389995832d32b5e21f247852c223786e59e702d2cb74750f7416564137bf8fbd1fe210eadbca5bc41ce1fd8752b676e160890c5a17cef9e7c850db6a6cacb3319bc5b2133171eeaa74cd27c7c634693fc052a6937289aa20d49cb961 +SHAKE-256: 4a3230a7711bbfa063ce369a00a4efa90f999a92a1e2b8e367b6c1cc4efd99276652bf316045e0d158b5b3c1948ec1ea0a669dcbcbb2c11950cc5b32bd90c39de49cfebd0139c07a4a72cc91272faa4cd38c6f999bb50655b5d9f801589c212e5f9b5dad7d70c05a053f39a46d2a8d178fd242306f16a0e4a4f7dfc2e99420fa128d974a835ecff7fa73cab13a2b452f01560de30d6ce7970a0998cfe041b59f562ff576a86299d29e8b60906b754628fa8db8daa01f0e229c681246ca1c92220165a914514cb51d488b8c39ce092762b1824ef0edf2fd92b222f82f3ca5b57945fe92cd172d948579b43e5d71c9986a24557c8408465a8112fbbfa045dbf311f3b7fcf69bde058bf256c78e9c5f6aaad9350b5092aa74dd2165c5fd04ece86fe5a60b07cadf07d8503e2211a0ec593d8870686e8804c90007e1e7e4fc874e15572c2ff71daef350b75e4523f90fbe9158516f11bcf8dd75b1fcc6ac444aff1f082b6b7280cea01ea588b3218bae47f1f85e44b10471850cb1e6850df3f777cea3285e79405c55426826d515209e78757a1b649e0ec27e374a243721265feb178310b58d53d1f287133e9149599539b6fa3ed2425e4fb19ca2342d0779c3cdb9941e51b1c2aa7b3911958dd7d163904dabfdff9a8e51876a470eda1665fda77a9f1bbd933be4fc4377392a9257267a372c64c1a061397497adc44d2499890db5 + +Input: a380063e2dc27a6ada0a6c018d7cc5d7e28cc20cd81ed67a02631b866be02083051fbf2742507655f82c75e5644b6b0d87db4f3eeb19730bb910853311860af20afc1a3571b61f0341bf75fe6b89649d21f9431f68774c1b604a75639d90fd9fd5b8362794dd09cb45ad42496064d180453a17b611e1fcac7542e2 +SHA3-256: 6d7ea8152f1745205cda99dc24d730a482319e1d177caf04ba32713d90d4c37e +SHA3-512: f2f32088526ad75d08a1ed73170829afa4f4936b6f3fc57f757cd2d12dbf9bec7e80f464d998cd8285986395e2219983b7bfb87066e2c9cc60fb8df3a028fc84 +SHAKE-128: cf87384910dbf1e75c3f4ef4d12d78161cd2993ba196971275273928dfd7664df9d45a384e06394705fc15b9a4b14205b48a36ff994b70211a1a53efba8cae369084175f5602b27a74bb4589819d897694213b316ce8abc6089879c44eb8e33df7e3b6b69eb694d632fbcda33393623cd499a97964c9ea352e3aae6f53b2410c17c12eb243503552313365340fdbc3bc0e6f027a2179230ec80c70cc22b7720ccd34bbe388c63181182b6c8580367b6839dea9e3e889c242c4bc0cedfefe3707eb9c3e04f4b0ba7359878b4a9292d172a74efa8070d06a43b4f24377bf830122f56577c8c2773055e0b6974da818b8433110c5fc01d35daa9eec76b0cc24eaad0fa60be0868fadc3cab544e3797211318da3add07dfabbda12932a5e00c0942e54c61ce8b70b1f44af78065b192099da4ee179a73e2966fb3cea98b384fbeadebf7f54900858103cc843858f7276b58279fbec18b367a77531bf957477838c37a6857d46836fb342fe28d012e04945f9deb4c18a780e14ca0cae0a3874ca295540db68d8ff18c5edcd72cb6db452b1593e9842e5efbb24e96c43752b7932a5ce9bf81b2ad3965c2adb44ba131281a855f7c0b2bdac6bb94d9183849449d409b9ac2bcc953ed94d8538817431382fbee05bcde3ec1ea427142e33dd992902fc1906932219f0c4be7b42171bcad3c459a0855193a5ce5f3c6dae7ccfe82ee547db +SHAKE-256: 179895cc083b075df85b99d04a915f0a06b719ca79ca1f09c43d758c0c0978d6ac30b7488d0d1fdf6941f955341b11cf58a8ea7a3745d01bca9ebbe870a3cc3ef274642162503a85a6a41b7629e550440e6b11ed4af7845faff397797528b2739fcf68264b9b09c4a9ad9bc414492009e84b0f4d68280fccf2ba97c858fbb4747d73c02df45520f9de9e657b46b01f426facaf13a5cd5205320b7c8dc648c0b7f77f8754662362602b06f39afd05d60747af85190a723ce417af86328d279bc980a17c3b2ff44678d7863802706fa075d48fd3263dba1b15e2857b8b4716e9784e193c551c75c2a4111a0a739a06dd517437a3e51b6bffc45d027285a6b25c6dc706f670eb52b26074f57c911fbd8ff5433318e0065d108d6d36de697e826535ec3d866f8f0d264b88ad0fd856f12feb8e1538c2a38ec3d13d7794161de3e118479d1c1e2b00f1d3db3088ef77dc59c9f5370c01508ff77ce1e26de81f5aa88fb4cab529bf0b417bf0ad837a2fe88f57060422acab56ab6bd04b4255e4b2bc46197003683449c67de84db758a39536433f6db32411e44557eb6b1fcb46320093a43d43b9eb988e6a2f2b61bfdda4a7c25684c76d6e669eee233a44dcd1b654ab50631455ae6a6a3d6dafc2165ad5273af0d5cff61b6c4a8ad39bbabc9c4a1ae01a3facc977fbabc5bcd127b0eff3c5b74eaf8e85eb520ca6106f04227cd953a9 + +Input: ee6f4a1d83fa81348e0f4f20ba5369cfc7156397a1a3085606ec8d0d6f2ddb4553b0c1a46c6a343a1cc08d1127e1e84252c2279ff1ac4697503c6d69fe6a7b53d67720052a275e4ebf5dbecd2428beb1be0236c8fde377a425ece6fb51b1c8b5ad25c81bd807a438cc65f52663b327cc553a73ff85d9ecc136c040bd +SHA3-256: b9c603b04b16f4c97e775249584f2d3a1243aae1e15785fe46bc9b3711e2ef77 +SHA3-512: be5ce65df06c490e4f9ae5976193d82d216e357b183a8e59680c18351bfd9047e6299a54b1ce26093b2f05789ab29dd5f28a7cebe98983b21d8bada77e8c035c +SHAKE-128: dbe58db0264066be2a7d2cecb07045300e9e9539ba7b3d849286bc6031bc7d8563f4005ffa2be7452f6403d1fd4716edc5933d1b542255b8b13348e77875e554629629f9d403766846bfcbc7ef5e5220ad5337cb428c1f91b89591e8c6b868629b7f941c5ef70f29597de36e902cdd6f2eb11b8809794ec12462c860978a44b3dfc1831dbf45171c27072e3b8038a8abecaef436113731243ae4e91faa4ad17ea308a79863b7c15bdace208bbd53ffc0461a8e58312b8ace3c78ad559ef26bbcf87eb1d5c8f710a89dc76d58d0a74da99c8d1ee5e25e99c6ca0bef2ce1676ceafa2a7123dc2784d1305df1fc3c92c0335980c327c767e76c274aa959452f01d0151d7cd91f88e702188f5c457e9285bb620b6c117d62b4d80c1e6f8786d0dd6fedc668d0834dc6e70c0e94088dd4a1d584b0f4c49ab24b080d83e2c78e6bbed1bf17743ecd379ba166022d745c7ffb44b13483f63935769aab711806e6b0a999adc3805397d9c378f5044b8bdb38fa50952009486f88b358121be9d007e14e347b6608c2ff062f8a4415a178d0c409e5a0b2d7c0e01e2aeacf05a49ba556a5ca5b60c6e28a33310880d4c96a3a5d8d44aa374a77b4bc55869a99ee06a725d5d8df8445d2cbb4d21e6597d9ee58fe6a4105ba9532f4b47acb77c0ed3341a5b3b4a578b088c81b29fd80f28449c9f5c7e188d423b57f8c7188ccc6dd94162f3caa +SHAKE-256: cfb3dbd092250c22445e77f3cf3e348757d97faf3964ad104ff6dbea6870ae37f94f5e5bd2164ccc93cbeb3782261e0b20305f7cf3c936949c2918a9a9264f1f60e2a1107f2b7b1b88af6bf70e3ca2ed656244025a87ca72dd8c8eb7e4054436b6e1ee8f18ffeb32e2febcf6f0b6315ba90a485ac16ceed790c3864b262a6ef7bb9c52db2b5433074dea30d3b52e4cc500e5411b3c62294f5cf08710cd538b16224f6a78ebeadbbc4d6f72f8219306b4fcb32fe5572a75e2b085562c95d0d1a30e2453c366f61d59646a7dab3c387e636846d8ca1d1890a8971a011711f8dd0252cd0cec0298cfe48ac8cf053a9bd24559db313a5ffce2f368c4c42b62c43596f69316156fbf76c4dc0522a3a170fda2078eba14a6ca5fbe829c6981d9f85a42361c41f8dcfa480d55d021e0648863a330517afab53ebd5f5330d3ffe6e8d6509239ebc1b28f9278830ea221ab0e3a0b72f44260ac0dc64da5ceac3507be2639a314f2ba665993c6138ed57a9e4506feb2557f3ae719310623a2926c4af553b38b68471e1526509ec45a237c234bcf96e4700eaf2dd5c0a8edcfbd40dbea29b6ebcc0f09e65b6ef4e0ccd7f12a5b7844921d499247fd4294f0836041d12eceab0ba03ea33786f4dc267b225f4d247fc4a5f44003c14f77e93635e7fa0e2001109bde540e74daada52c269632e6989810a6cc256972ac9607bbd903ed571e0c16 + +Input: 34e6324031346009d2609987de9f92728996a23ae893e8e791fb044301dd42b245acdafb1ed02957749e8a90c2ec2ac97074e5c56e674f72e39a8fce710e48560b03da9daf41d4f515a2416facbdd6b2c9346ce9690810f93829a893eaf8a1ed5fd92651c9395f5d5823412a55570aebc5d87b319fe3e0e472a7342931 +SHA3-256: f9ec2c4638735cea016fec3ae1841d8539e7f53e2c00f26130f5ffe6a528e018 +SHA3-512: accf81b2841e70b427e7eb449f5bfcabed47dd5b860dc8205517a28ce48cd999723c322e48aa3710c49b91cf66f4934de71f847135fe3d572bcbad00fc1171a5 +SHAKE-128: 3479c045076ce92192482dd6444ec86e28caf8f6511f4f40229ac61dc36a1697a4cd3165093b6f110e9391ebc739b8723712d3d213ec814837b67080b9650a7e7457d1fbdd64160a714829083c485c04dd14506add4452173cb3cba37881b467b6bfc7c463915be86cbc26dffe52a6d8cff31c2eb041b8c79f3fe4ec993bab07d5dc8db74de022e6febc5e980885fc4579620503c92bdce83acedcaaf3c7b0b1cf3831dc75b80c88ba9a3b8345b251828fe1bd337485980ad90225e1594a1fa334e2c5e96c1944ce0f325920e3a4e7d0ff09d358d482f90ebedc787cdc4c7c2418ab665942171a1a15aaf413bcfc0d0f2f5cc042ca12ca13b3c17b1d53661f6eceb1bd8aa346979d75f95a992009f2717b1a3b446a15d7edb117fa776286ce097a80a18723a6a267d544fb52bc226227aafc012998feb4d79e324e67237080f61204dfa14169f7e4b60dff077f8f1e45c051423a01caa09b96270c63087f5b069ab691ec814f211784c6a5393f9e03a8af680e0627aadc89c92f194469de78152b9533c375b809111df7597317dae40a9918902570a7de8e9b48448b21548cb320e138b6b491ce6b83af90d9ce382afa10fb899a50c9ac8cdff8dcc1596540e48045872df3ae2d50fced17336003369f8516a1ca1216eb82ecd157bbf4238ef7d82ed9c2f981aa6bbc305e5d27d943f82de78535c37d1352c7c8d39c65056008 +SHAKE-256: 72abdb1a7cb78b16160592898e26cdb327ee4b364b8a059632878efec973ca7673ddf296bf31009dd2e57dccd6dbf6e90d5981d8688139900576fd64d18c72fd135232133fca1992aa998cf119fa6d824ff85f5759854cdca26a3db4d2ec1695c4e5909ca9e1ff702b16537fce8098d25ed4c9f9c4e9af2207b0aba3c173b24423a28f2ec9114a98a40371007f3b6913c7e848b30d5c1d95e89c41ee94556f86179c638e026de0b4bc86b17f84d453ec7726d0a1c6981eefce687a436e00c8290947b5f6db04d25da4f43d7a4b3189f307e3a225356075b16664e6300bc2a807b627b3fd009d69488e2dfc71d0b80333ac39eaff02616721eb711016db1f428435db32f7182aaa119fbb643ac8ad56f3b28ebefabad3415b789f27f279edde1050788c029b8ccc6a271d126080b7c2f682e7b7450c80cfe900c40f12678af974897c50282d2999d65f754019c8462bd2700e241505fb1cee22727d2e48af7df16a0798afb27c1677f086c225f2bf2a39763bbf9c5d6efbbcf0cd884eebb9e200d03ad2dfe14027ccb4e0dfe681897f4b57facef27fcdea251c04a1b6723d3698333e3287c15da5d0fbeda0b69b31c0f552072be54e498c9ea8e14c92a5850d0231e3dd9cdd811cec3ae9df1e407623d54c986df03763b5c822f1c3b0597f6fc90345d74946709ef886c51cdea9ce4d5c37fedd91603e8d2f8663b3f983eed541 + +Input: ec5039af0779ec867f2c69892809ddb0a1ecbe61da78ab75af94c589241f0c36dd44fc89c43e1a71236da6c6e78c202df425293eb6314fc31c44ee78b748cb2086107720a6f1e11611a5236fc0d5e76ceec4c6bf1dc17877789f6ac8268dd547b0486f637421418cef73fc5a2e823e217db7ad950f489ab229e7230c291c +SHA3-256: a473a599d897a3da1c8fdcbd2a4512ed8416bd089c5037109bdfc84f80e1797f +SHA3-512: ec7047dc72674fbda3ee35b400bc1f884ec360419fe2eec376829c3194882e1388ed09ee0ae56f586f25d960acd497a988a6495414a9c233d9f766cd5aba3b92 +SHAKE-128: 572637b19cfbfb8e47c618a28368da2c666f114aff39be92e9a5eabe31ccda14fa43133ad03b7e6a2db54a8251671d041e36d49024c2bda3706b53307def1c2d4e30bc1ccc425729eefe19404ab6a87279a2da4dcbd751acec101d6399655c0b4e4f25457f1fd8f46e68020c788948e763d3079086eb60acc2defca9f61e2c40ef8290dc6ac01c435d9959b0a23fd19a550280cc9c2d73e8206c118dd4f105764c95168ea767e9d1e9b27b38700d6bbb09f3e777bfe8f51903b5034c8a8d697907be92379fc43b6f73bd742a5a04a5f3639d84090dd4751a0c15fa583150a12c186cfe6a19a188c2be7bd10d562f7af8f35bf3d67e8f5cd53edc3b2aa7ae017790dfc4740b9b19d968b3cd2aaff5b4f9c00cf7f8134447689009f4c2bffcec22b16e53fc8ec1dbd2ab32223f2d98e745bde2438b4daf5c0d1d2145ac5862ebf59c28a7bef63a6e8925d70fb2c7476ddfc6c82f4b8d6fcc3f62526788f44567ba72051de51a4b9f59910e9d94cfeee78ef48fb5f30488cdc0909d93fe2d2182b3266320d1a601f917c8d7829c80eabb8993e248c7302e0d9e454d43e219f530b467eb6981a3ad877643a24ca50b80a5e86be6b55acf36df16ef085b8a43cf839e1ceedf7753183dd42e84cc0f813a857ff9597577890faeb945402506d27de41e8b2f77c4c3e328822a2fef792ca49fe51a986709b176b08ceaed41dd3fbe7b58 +SHAKE-256: 2e8754af8dbc1fa132e4d408e0b0489beebb03ad3d1b1d550dfa9adeef7094add624e492b2f4c7103cb24c62937901987bcbdb6e4e1666ae8507178f715539b7908b8069d6d3de87cd04eced6d500633db4924b1d6219dab64267373cfcc28bf6884dcd1e3841d5f4365f068e4a4c494f39318556eb1b4172375969a062735286c0bc3b29a4bbadafe9fda3139716aed0088f6ae09a1f862fae61399a2b2ac5abdee18a2fef8cd4dbe82acebda7cbc097819a66dde85d14fd6087947460a32a77bbe252acd3302c2c9344f19e4253235456713e8854a4d23a6ef5d8854a3d0a6762618509ea7dabb3239b4953e0c01ca31fe0d6977bf23cf36f35a3dec33555e1b14cbb253622489529607eea10b7683172fe280c184264e35a8b6e5167d79d51b400890aa0eb66eb0e066b285be46d6a5e47a03ca540852e4840fbb3382f0553f7e08ef65b98ae48b5e3e82cca46b4aaf85cdc3618a41f0cde5c7979990ff67eb8c895b605a165d276571b64bc8b4b9ac9448a0031216f6f1047cf20e5b068c07df2bef82e7b5b6df09a3a06543ef1ccb4b0677174c0a08612e6500da75207a8e6d799de734747d8ca9834146e414bf2a754b1b5ba4b0f74107289ea82d4ca4a64d8a4de9ab275cfda1ca200e7bbe7956b47942a81b584e9e6e894710722272b1e2d2c373706597109441438e22eaed83c0f17c0aad9ec93979ac4f87492b67 + +Input: 68ce168e461c0ef58050cfa5a8d0e972de71b6bad0a8030ca6f897e85fe7dfa787583bf18a7e609c6e05111e35e1eced69477a4e26a4b011156aef475866c6ad41bae79da1be3330640db24e21f290ccdf03e1b706f67627cfb1177f694a75e3733b2c0ee9b25ceac1c86f5adee2f2dedcd0e366a9b5519c96a6387efa3a24 +SHA3-256: bee74e4eb770d8f4e061e9c708f1916f00153832ab5e24ebbf5e9b8b30b542f1 +SHA3-512: 13612bb71fb0f676a862f119be44ef04f98074e3399bc3f0dbc55af18fad890cef29e7a381400b8963f10edd02374a3e372c20c66a560608bcf8f06e9759ce35 +SHAKE-128: 39effcaf324adcb0fd28758f714a94236b3a4118e09415e44046d8845dde51d916761f5728b40554810e4542c67736a118afea34cb7cc7d87b645a9d2d1cd6350680d01c0a3cc827cac0155cc41baf45c2ff82b245b674ac298d3369b0a02ba279fa3c6f6fe114018313149705107f3750c16f36df52941ee3c2f28b87413eabfa4d8fd0a574aa87c25e520c78f3fec5ccf03f6d35a75e3b9366d37058bf2cdb8dce5cf0dd64f8524666bfe17370e6c7f5105d6425c6564b47d74f79c81501776276cfa784d4a0ea87fc91af461936f9687fb88adda48a5f814afb6c57c64a57bee662805a01dcf8add10aa1d0b3c2dfd454f9cfdc147836a820c878b89fe78e2546943041e5176ae91e26c65be21d1922385a9f67e157adf9a64267d9d51b41266e368a5d6eb61c222bae40ccfb88fc72c70835a70291ebdf83c9ba05347bf2e2dc1bd92c66d8cb9bd6570435efaff4f88385a32f5abc46ef7b58b971153f70b2ef657408951ff5cc0ee072631199542e69f630d9378e01af68760affd04fed1b0ec9b78db747b797c216a00cf0e0e7901c17679af65769657284dea615dccd0ef48bd34deaddea1651a2b67d149ae65c7393b304c9fb90017851421913d289079ae61a807c5cd9d6bc6803cd09b369d14b480611b30d4cdaddd9c4b2c794bd3837620aac9952c3c24a68b9aebe05a3369c07843b4357e62e3e1eac20642afa +SHAKE-256: 56b4dab1858bc936fd304a649f05d86d93c19e0b839516a8b781d6ec7b6b796fe86ea4a30b5a5bcf1f23359820ce907c1f71318c2ffc3d57b7812eb53192b9d35eec73a755b64453c06621b8235ad483db7071c2d83b508750c89517cfe9cf439620459c4c3151f2f360c5d55f68c40ce1f0f1ef5102892e9b931f95cc462bfb54c2c57581201dbc7a61e25000577b799f163f454e01bef1f5cc8a721a60e88fb9c1a07afafc989cb818a23ba9daa46dcfa981213f12e3a85716ea51ca02e23bb894e54195abb9a51c0b60dd4d066124e1830ac8b8c48fac68f8b0b30095a08c051663de40daa3bbce76bdf016186559342b122e7bd61d7af31b5574d28f9f4dbd940ed6b0e41976946af256977eced173030d86e44739d2a882447806d37626f0d824584dd8c3f71ba93a3d9fb0c81a71666a99e230bbd1605e21a1fd015348f6cf9473aa84b70c732fdaa8873d6b2d739f1394b49c1eb7fa74613a051d425a22c0f424d870c78f47917293cfb8b56957eab89e8995a73cb3da237191ab79fbd6106d043db7be0d1905ec88820741c16b55a77c7507f7cdd667bda56ce2cc53418f5e51cf635f3da4028aa39304fbc2ffd048b0d262ebb2376fbb69234b4d594ee07c87a10ed333c5fb141acd14eef124a7cae00c773fb4524c28b14966cab9f5f89b72be484488ff1fd5b5d15ffde25cfbea0b2652e398fcb4c15ba7b12c5a + +Input: 37c613d7467c9c7bed6e3b146d94b981c5dbac9322a2407a4fec381111c4bda2f56aa4ce4ded9694950bf1ff5794505e12fcd2aef9985f28645bc5c486d063970ed2328e139876a7ebe066e088161058b7a05970a83d81b1929772b34dc1edc05094c5243a97b9e16a1a8ce89555d8836e9224d2414dcf59f6740640379e24e8 +SHA3-256: 78834b13ecd041cc6fee48422830219dbf00d04c4f8b1122a0681f4d7c7f8fa3 +SHA3-512: ff7763b88c470469b610899f7c10a265041e39e1f10e4f03cc97e5eee4a264e79864da497f16d0e9dfd10185cab9282c1a0f00838b916c8ec54f0414c4d9b13b +SHAKE-128: bb0367c0bf50c7cc407c9d99dc9a71679dbcfe3a3e6e745f42f147c9cf15564732a8aa8a039142bdc1e2dcc37fcd8b6fc6aabceb5ea1332a7f944c216f99703f19509b68667393aab5980c244b67a1baa6e5f0520b23ceb0bcd1ed17e2608a9caca086186ffa564b1014c202a5e8499a55ea6bb60a03727c2fd1f2c586bda213ab896fcf4392f0fd18b26540362bf156ed4582e5688cf8a3a64e661abfc32207b18f9e1ded38a0cec52b8b8d8271c27f73c6be7d11af68a4da18cab65e4e6499c1d2ecc59b5bc758b22b75e3aeb9670f059659eb35ae2381c2b1708b8c615f02afccfeaab1a9a814c47fd10d098e7f10f0c4a83edc2d588061b45d7ea6d3e860d2c03a5dd75172ea1392943610b281166172847fcc2fc87ce30f5263fbb7b4f4b6e39ae8b7eb3935923e9a8f572d2f95a70462cc54e0f1b0bc5839cc74e5c719a20837bf6626171a1326b5a3feb3ff424a9d2926e29aa2444718813549b0d13183af149d8842981e6296c4a4bdec9d1f04a7c7c0f0879f054b4b1107aa542e6397bc1c8e598cce3fb32654b3ad6ce9b45135195697b0da42da3646e0dfcda3c148fee2613d5ca8acfa04c505e63d6828f066234e1259c4c113ac9367ab7ded34d52d657087f5ccd6818303c7b427b4babf8b7b08e7db074d66f0190fdf7091df7efa51169ec96772c80bfc523d275165eaac6af18d5ba428f5c3e09eb59e6af8 +SHAKE-256: 11bf70eaaa3c944971ddad23e1caddc862a2affde5ef454a2414d0f1a42a7e7d28d7858dba32e2b555c529825fcb1217001de6cf8cf012bd42fe32ba5df6af7a056c85f7d57aec4dbd0fb7e1277d0cf2cba44a2d43a3689e3239446b6520c3e85a698e290f3267567fc1c7739f19096d4885dd941d9981eaf4c8b817f9df23b15047bd5cace0394c9b2a3293391e87c08f1e6167fb2ee2c412b693c36734fcf331378fd6080358380d24e44e934f110e8d4fd2c3eca427a8973548de7f818c7f9c226ef2d5a280c087305f0c053970ca78f6db4e2ee9a2bdff0194c6f2fd463aee7a64326d086db73d0bb4162502b6c37765789dbcd509db887ba27f469a8ea85dbcbcae2a33ea5ddb1563d4276e612e79ef1fa25cbf54141e0a8182b46d4f197633add70d0030961f26cb26cd889ee90f306ddcfb605243dc5f7f584234a4e3665e66b73b8dc5b97df2e7b99d4e10c0fe7b0abac8cb2181dfa652aff7304de4b97ca739bee8270fdb88a18fb948bed5d999de4e567e836042114703359dc59e054d6e27a689c2acc60be7de6ceb9a9029ff4d3ba1381ebcfd04ea42bd1702c8f0a87f7d9de155910d29b22dbacdd36010c664e361b18d96e93df0d1c6a082fbb323b740e9fc8663d4da6ad910e65801d7548cefcd7de346de528e6a99854fc8e79ebeb77fa9c4a5217e7fee4f168c3476c32d238115661189373f81c4a12ddc + +Input: a822ed3dc2f1fe3998e2d733821ba4ea54e9595658967356dfd525e2e758555e2d70acaa6c993df921de4beda0bd459849f58bdac8eb4b06fc08e34ca5a0a9f89a2fbb8c84e63c97744a834cb5c63b8821b06dc6bf80b699cd3dc2aa565aff75979fd911e9ad3e706299c46dd47d42962a9b9db3d3146736a0397845ed00eb904e +SHA3-256: d1bc17fee89897d851bd9d5f5362b999cd1d02639bdd6181e55256a536d26215 +SHA3-512: 252164f74eb730edc743df60b5e755ebb7cd6d451d680f770c739f6ce2b7422312e36a67b5400efcca006343ca7ba2e9e716b635674e26ef297ab361a7fb65c5 +SHAKE-128: 7f7bc9bfd0dcb80134667ac0fe22ecd805148e76c4e6fc411746a771ba23d1fdadd1b76b928805a0da2ae5fe7e0870561c21af3ca5bd6880e5a325de0a485c74283b0e39da280a599348c6983518545526d1ccead1708863f1d2f72b505d5e95fd0479bbe4d0a4efa3f3784b02e22a6caa53379514df0bbd7e0c10c18b2a5f13af878bc7c131f216f259967369d51c25042da6bc0d663145e69397dd5f53eec7c094e1e57216ff1810eaf047bc00ef31d6a1086053fe401dd90ce5a337cc24bbb4f90578023b01526df2b96a448e15fef8dce2e64b03db3e5bb450c0521516ede835711cc7566c51073fc30fd395223998db6f7bc98a01a040507be97ccc7ad64bb29b3db066b8214072798f02556429969a15ea7612c860610b7e7d8f618cee9a0f29d16c2d2e4153695fa64d3e31ffd7171382b51e125991a6de4246c1e5a54fbf29d7516f66107cb71c206dbb24bd24cde5f8e24dbccaa12501bfbacda8eb7d93cb9a3030083a9e0a6240fb5354e8a9505b1192b421ed66888f8bd4eb715337620edfa9c3e90033276dd0b88086eccb553495b6a2a7ffab378cfccc438f39bf8db1bf1c6e9bb96ac74ba0888c5f0639d7940180aee191b41b1bd4c157027ea3755c11b457312836c3f30dc552745004ade8ffc404f71975fbeb68ee4d9338dfc2f856243f24eb49ca44c4b6468ff4ac9aec62831a0ebc53e55c4def039a8e +SHAKE-256: cf1d4cc392dca0081cb89a1f177ab711a3b5440240a1cb6e832d238d393c4513a8a9d002a73f3f8395fc1819f082a52758f141d72c5185f1a2b679d4c5010ebc6e8dd445d9e4a2e310e726ea00be29b36b870a37d75649d1becdbdc7afa561364b4236e580a7c30898bda66bf5b00d4dfbc19fc11969336836807d81c8f21179b9e05f65ebfd9a919156cf1b10cb0a3b53f7bc7ac460c179edc0e2094b7052fd3719ff6adf679a7209bcbf5a1c8e6b1eada056759207a93a27504fb6d8f42893dcced18087f3599783648c8d11306a7e1fae5a0f7b192635907617ad3bb23b18e3f02c2b8243c3a1ba936cf98b9f4b30087b53e51e0f686da136377cb96877d75779521006f2c07eb0ca3f6b1a1985b22ea99e481b94fbdd516eb4ec5f4d2ab2b8a657837fbfe98bbfc534fc8e341d39b557d8326cdcfe8ff66f59f94aff9d8027149523a4fd658d135c36fc12fcd621bbf3fb566d45e868b6544a8cb061af44b82b441243b9f998c5246214c6c74da6f90ccc8711db787f5e7ac44fc8da63e970625a788f71585b75eab40c0aba1d84512a3b04ded9037975299ac7534c44c810380f768c93dd621ee022338b81bf12f5009d58cdc50f250f42f336a74b1f3f50a798fdefd4c4b282fb193e2b5af73837f954b5b626f7016b150c218384400b2bcf4d53cba69d768a463342aa1a546347fa106f73c91d3cce2496a43f480cd8 + +Input: 93d3549d81b752655ebee995eba6a3efacd208627ee7d6b487f60e77178c7bbfa26120fba577f61ac86319ba22fcab9703dc96152f6a091fbe6ac3f35fa92c9e3d2a63549c8f5179e390e2fd373c27d492e580f0f854fa44be656e0feff416304307dfaf52b1bb50190bf4689b000468aacdd8bbc64095193d6ca5c0da7d9006b1a3 +SHA3-256: ecce62ffa6585e79d3c3f72abfddae91b589da964399bb6360f3f072ab38dedc +SHA3-512: 433b5b162fd791323aaeb44a931434a1f2a8649997a1bd1fef9de9ffe8376ba67cd0a343f998a21a38fe87657591bdbc095af389df5d2176387da3258dd2c0d4 +SHAKE-128: d13276f14cc08ea815f0e74fec9223d21ed02f80d9b45c0b15cca7d11d40725919d7541fc41f91f9d04b5d8704952763575fa1e4229ec0ae1ff47821af2871b73ed43b334dae0b8d3e7e256f10731b969b46ef6e5329e86afd96ef9531967a642586158f0702473784155a7c6f4cdc9b5ba0fcd6e2da23dc32e5d63a80344365ece7dcea679f92394ea0a304f90ab8ba6fb5cbdb29b8328aaf21fdce6e0ef087953ac02b95c38a7ae114966c98977cee0379f65fb2b49013a6ca20cfb93f0e83215975c64de4f6b817d0deededc18b8ec7e99244096d86e12f30a99312d0fa203a29fbd1c28d0fa5a59516a3bc64080c9a069eea2f35b0a92ac97bd9d4af4c819f84363358e593e8c2e39dcf00863471929935270c84e64ef955b2affbc1a13afe5c34f7e8ed494881070a350ff3a5f8a93845fa8c559e006e92d0267f5df13293d1d07146ebb8088b7d5eecba083b43f0b5965381c196f59bb39fb9a9245589b8ca2e7240ab470d0bbd2c51718cd065f5907b9d09b61d8fb60221bd35ce9caf8908c38482ae73a460e94494263330e6b541b7459fdfc5a2a5ce28bff9a580b8d35d0f3516b0c772ffb1ff8c044fe21136f5b9a46f48dea628fbea81cfb54765671750b145eb7a1b5afd98cc25866e93351b2510e9499ea3e1e930284b299fc0dadd89a7159b7576c9ac20e04a480092daf09d0889897720b36e53d0f1fb64df +SHAKE-256: 8b4b56492b2815289538e7bfc086aaf4b30dcec3ffa054198b07e45862a09a9cb62066646c69ce1269a60d3fd80e7761eab1f93d8af130a3b5605f93c333b03bbf8571831f554b1cdd0e38a11dcc169d4e8ef797dcf2b06028555fbf6082c3b597edaf8d6d7cb18ae84ef8d89006a02f304d4d27a952091892d1e1f4d92c2ae329dd75aa401163d03eda0b69118d11dc0ea82574fc086e4be968e204961655adc1c3e4d9c038b9cec0107ae34e8a50ebb21b556f4d99f62767aee163b07128486542f33454d3a0ac42f7f5ee2754c10bef087ecd5f42de3a9bc160e145c50de14cdad9d83f1dfeefbcf42dc13dfccebf503750748c3fd01574980c00db1112f621025858cf0bb669ceece3a07f65b12f3d5664296e05cf7a7a18084122e48348256b29412bbe534334b032b6d1281f45f35ffbaead248308c99ff96a9198ee82a00cc3c219634077598b356bc033d2e618aa888f922a000d224b965ce82bcfe39d12260a48f9ad6aa2a899089cdc770cb313aa807a90d625927bd3b4c1f5cf85270d743e6fb256367a959ab505f43ee758d99b871ede33f217c30a2ef1c9533a8cb16b50da087f95fb92d5c4d1d269eac69b62ce5fa8fe918a29d2dea24d4645ab4b26794e6d79217baa2d8b0d1c12acbc110a344989a2ad0a5d7bc0f54b19fdf95ea98b0cebb34880b988181b25042e1cc8421f3d1f6ba382829036032aa461 + +Input: ce13d351614d4b3a8433156a1d8ca9da3865c08cd824022c836e2d204f8d05ec61f7edf59fe8a3fd90bc50314951b58dfb7f8c56ceee1fe400fa25d150e3270fd789ee2823b01504457d8429663e0ba78ee2c39e8016bcf2c9e1be459dba5a1d50ea3eee5b91e09e29a755e33870d8fbc3ffe87ed6425b4ae815833e3f7c3c32c2ad05 +SHA3-256: 283da78f172708fc0058f128a74214067ce44b708286c483d63b9ad51fa4ede1 +SHA3-512: 54e9b4afab2922f39b6186fb5842bcd8c7233ef5bb66785917a4976f63889d2933e9e4223d212add25830dd490227d97e760e4d4fa657c50ff7914298956cd5e +SHAKE-128: 517512791fd67c6be32634a5ef21341c1fbf4168a7b6bf456625e66efda6350b7db4ce1f9b2e73bb54f334231b6455359912887ac4052274707d8ec4e41907642553f95d58f94f54f7f2290a42e50a13cee9af3bf5c89bb9e6ed83f23c5e8c692cfde82c251121574cd25ecc86ea3c2ec31267dcde8de572799f3508cc0b9998aeaff74b6ad70f0207bb06fc34e727734ddc07a603c6851d3356fe31fe55662c8bc36fb97214e7179c0664653239061b4583837e30a67d07e206f96187b0e42e68b68ae8bed7a40731ece4eab6b2b89a2c5d0078e2cb6c793e4dc1b556492ce83726f34727fd253bdb1eac507ecd33d473133e4ac55f208dd8d2e4098d1cdcb17ec96cebda830db449312828b57c1ceba46d7a6845a7f0df63ca646173695051fe13c5b2eec568b8650a2eb8ca5972170d9237cb5000f24d9b985c85ab6f832ba7def440530a3491d4870f8f5e5bd7bd4bb87d4e9879966fc02cbf06360355b7cb6cc924a2e539a3f5b8562b980269d02d5a67db8862c2146a156adb6808cdc08f7940ef0b33bf5bd8c60282da7b828870d48e2e2e634e2a4c1ec7e76bd5da938a8b5101abc10364560588b6066129aa312d0b6dd24446dbe88867be381e61cca27cd572d2f6ad76411a25911a10a8c70636c10b003a2cbfba25ce2a537f533a286cd0b317744cd563bf68a95c8480b1117b8b4b7c84c8bd30ebc0cb1c729906 +SHAKE-256: 7ab3bfaef07fe0bd3c45a7bb89942d5c66d7c74a3cb41926e03b6a69d19d5b68595cf275269c792e01901bcd62cfcf05e817379ea66ec09b861de0bf48b8e436f47b43739c6273e5b81698499ce3724f1eeadb99913c0b93bff867952ae8c3d427d751da298309852bfeb65825a6f653c360917fc7fdaf60363fbd7c5944febda76975fdc0b22fea0a69634fb3dd10001cf631ba94f2ece8cb7a85c8cd349d925fda6cce5c173e19e229832020fbd8fb87ad900ae5cc730ab38fb156d176b76abe7d79374fad508a7812ade43daad487668d10daad078cb37f339d0bda87c14d4e0c5f7cc1ea2a1eb2b648b9a218878859ea837eb74f159837d25fea9c6f621cf1dd9e1e010e5f397904040cafa7dc35d87ff7aa1ddb3e20f1e827b1ab5c5ce0d247d7d791178365a3af3987e07fba819737f9326ed1fb8e8d95f15308507294067021cc3e964b09b2b3da9b7e100d15fa726c4c89206582afc2a6688d9a8a8638fcb27d67ed1d1dc5b31aaec0ae3714c1f965b6b60da22fcd5314abc5a85b4fd82c3494c151a3fd9d46d1f22bd3326a11c9125a0014e8b9a935c8fb504b20fa061503675dde2645b527b4cb0d7b955a07938e3ed29ee3ec37475b9bc1c2b3d338ab0f3cb234315cb93370d76124828c59fecdd8e5f5454eba68e5be8c9f450f0a73a48d7febbdc3a924e6f8502143f805271b4db2ddccaadc4cb07064c406c6 + +Input: a36332dc9d1474e02587a0575bb2226a7b74d1c391dd1de1adc552f2e64a167f1886ec7c9217f128b07555fedae6bcf2aa8ecd4ee8a582d84d6ad252794cb3316d060690211997e285f629c5f264c39da1771d7fc10a678ae6f92b079e81aae9abc290fd5ef4b30f4097fbe111052786043f649f4f1a7ddaa56111f72db2950b37a5e58b +SHA3-256: c33d885f5a0cbb797341396ce23a467696fa9d95ad5573629fc607b83d57d010 +SHA3-512: e15170e4cbe718f42f570151c531acf88e0b448ee56a836553473fdca1d73ebb19b9b0569f6cf15214445c9e993e2d219ccd2fbb6c6c00a578db1250a779046e +SHAKE-128: d8b54fc3d921d1a2262655a51cf14af350508f2acd21940432b86525b27253206e9b14a46641f010f8739918691f051b17b531945d5f43d27fc9ac65f00372075ce7e79f3ebe908488ca5fb3198ad9edc51d394e3a6f9ff098a15a44cdc5c7bbb4cf8b074a0959e39ab85e1f8783924859ea338c4b99980010827cd174b8340ab5e053e0a7e501467468ccd19cac702ffa77529c1fd379b71fb66fdc54db3ededaa625e3711fa1b6dea9d31fee8a26c977c1391848ba08c8ec4d7900a71033d048466ab417bbd721efd7126f109b05a6942f7bc0a844bce6880547ace57ef2e989159ffc69ce02343ee4bad123c588c75f56294b9c5fc25324890618086619d86fabc9983e7d4cb8e8dc6cfb3eaf3c8334ffe1e265ae84ebe38958ec9a2a4b8efa75c50d1144a6bf87b5b6f5b8c08bff47153fe4c48f94068e204281355e4ab5ac96e4228abbf6108df5016458bb7e6f257bfd63da7ec12db754def0d227618aeb8278241f72bed11e89a7c8bfa58db7e80c9ce508fd9ea062852c3d90e6676489fdf7ea2c4332740edd386594e86f5ab6bd7d0d5301dcd882479920fb91980898abcee5b471c4f8ab8d4804a4e98c77f92cfe4a658acd630ba80b3ccee5eab25343c31315b4a811ae78c180a1c217c2dff12668a727419229b07408a9164a566956c871c9d75c36ee895c454dd5342c018f8571935ef70af7c6b32b531e52f3 +SHAKE-256: c64022e9e52618e44ccfee0b920c615753a12f7f8e85f3f1ae144d3d481baf19ebeb5253807887ffa74d16ee67d1b23c5fff4ff8eb6e8e38f18fcff48591a86331d9a1307a132df2f3d1f2a16e16cf0a8ba187a6ed27d0e275b48409b3e09a0841664a0e716a244fbc7eb485275e6672589697ca313f64651e11e74a64c2b7c847d673e18f0d79f8dcd8e81a4d4d3bc2fc7dff81e604d8b5a77f39afdea80ed1cf1014d4cae519b8732f4cb2d390c7b16b0dbef4f53de34319ffafcf293e248a054a191f45ce6a11aa564621fb5dfb4c910ba2562e627c01eae49451a5a2f9f6df90877c7770be01c94946c286237334a906fd82e653b2c7d6bd32433f6aeef0a6d42e93930794e3acdead02be6ccc15834deb057f7e85552d2a38c9032f548f7c5e274dfa69494c7066ce185fc637a82856a6b2ce1c7eb895592a9dba5b9567d96b594e394cee241c42289542c89ce07632c98ffe383ec0fefaea2a81ec92566bcc811751c31a7017c79e4b2b2f0f0906d31d915d7b0838e9f2bf055bf132b9454e2f470f09e15da0152fa0fb0d060b3368e42a49b0c3b791a4f98863c7b612469e65cc03b2a3a74e0ece49ab14897ada9eb777fa63dfd81d5de10221137dd32c9e4c0481cd30fe1cd8f432d1597ff2dc644216fdd944e6dbec05141d1ad8ec7e0b09fdaaed3b4113fe94362f59c44e47ff4c5ad7de99a049635074adf11339 + +Input: b7639c3e054c8b1b1c5fa748f1e9459585e22cbd5548f933a8000414ea4b1ad18753e45843b352581c50a44f2650e5828999af0381c4de516f906fb8fdb3b1a34716c5f14eddf2d3e64dfd01c2b48fdc7775e90971393729855b6d7dcdf382b7bdce212483d712f00c7d6b993a3f70ddd47fc490951fec5236c2d873e391f56862d655a383 +SHA3-256: aabf0cedeee7fe03ced7be95a52f5c0ad3a4f4793f378e50e2094b5b01e0bcff +SHA3-512: 8278d511be1bdc5bb57b287d1b3d97a16da0400d35e396c95a618fd34fcb7ee11135a034c9d34fbbd0e35931ba49f04bbd0497a163a5f04205f990cbc57968f0 +SHAKE-128: 7bdddb878f5005e678eb9e3fcd868dd9c3069ebf611d1a46c2e6a4e745758a60e3872cc995f98b141b1070659eb14b30a4e734e03e2c5aa471740bea6cfa376c85b8dd794ab825b19b9f2d3afe6b8a13f75db282fe3fd22d654b504a25160a4130c9bfa2e0d3dd60430ec6d1c2f6e42c346e5a40bc594ccf983e28c1c076443575eae8d49d252d97edcacad10b1807e753e65e8df5cde408a20914cf9bf8e64ff5cb9ea12c69b611c7406b9d8cb5168e6737b2d30d50339c0a9c73ab3246b3ab7fd2ad8e5bca331aee4b5df21a377e953106b9b1f390e403532fda41b3f9397a2b23cb81aeca179a6a394c11ad5a57ba054e4c62bf38fa719ebaccc37b54ae81b46c3f8357cf2fc2846805d26631d2c447ee07a079f489e2315212aba1e27a6f1a99b10f3d7208b614170f368c08ed13b9053a5d4c3265db22957c120fe63a767ec9def5c3bca25509ab0a70677340baebc4609d885faaf3e5a651576c247ba809036b3adce1bd573154478f6d78c78600d1777d5025aca4499db44007a1b311f95a053efaa4ff3015a7a2247f53d1c388224d228b27797f86a9728f8d1f831ad3000ecd88857065dfe230bf4fe384cb61ed13d5a275dd483951cdaf36b0b3c86d3251e2c42a92e7ae54697c400a945f7203f3537ee120d9d9d8bf32230045b1d70e1d8e346bd7f61ebc07dedeff36e9e9d2662d7a70543600e20cfa183d7ad0 +SHAKE-256: 242cc0773ada5c7a9795d56a4cbc9b690bf87ea2b884bec0741c139c5526209edd8760f3e0ac1ceff51048f45d9ce0dd92a9a5e1016b582155475662d00aa9893ed6c94d9b54265d0d5167aa5ab37812f43cc2a07e914371d76949059c3c82776d8d702f0efb9d877a5f0b4acc6e87d59701c6d0f383129384d9722903db32dfbd161d69fc845ff2f738630c031677c2cfd43fd2aa7813e6bcbd60c636e5f6e40ff340c5b937171179b01e4a0d74642fa745bc9f2c2cf1a4be45e3d5894f98550e5ac2928934fe7c72102b7515fa365bc5a4b9db43cc98687583df135e107b38b980615b723d1c1906c5a9c58b0d983c52c48ba94878db8cf317ebe6dbc00fd3e5b8e1398962d96be9813f744bd8e297b76894663cca732c4a91a180ebde43c5e2993b11837b9d3e24ddb64b180d3c9254a9e62aa3f6a7824e8640e45cdffb666536414a09831dedb6a8202d4d01abe6531d62acfeb4f46ea0dfb6bed4b410c0a4f6c197fd18e2bf27c70581b382190266607eb8f6e4fffd18e06cd45d4999952bf2061ff4f52af51efab5433bce3a2510407d374d2d53701163bfeda0c0e2acbe64bac15e3be31a17bb676d781f9742e9d34272834e5cd1d6e14a01727f17978056aec039f70014f3c6c6a826cf4797c7a89814eeb1e966e2430f6a28846d4a99a874b7caf369bd950e00d7cb73d8911f3c26c6e11774dabbcb4c1b1d691f30 + +Input: 574c00bdfc9ab2f7c09ce02d209e975ed609d9ddd16712ab1ac4f592189643e2b10e2ea13a6137359c0ad3956647d9c0c0169d41f5a43dbbce350a2c83e45716d17c7f0ce4919559737de007a610eb9d1d96f19a48364dc70edbb09514573c1ee6ebb1131d26ce836b14e141b963c073bd586ff50125158a5242fd232ce7e7f5d86ad2eb9543 +SHA3-256: 2bbee2795dfdd0d733e7a84f6f0773d003ce1dba900d701777b0c17d4b62a950 +SHA3-512: 8893f3bac1dcb1124cf6d763fe0147d185c4fda24116d5db9a089ce4a39934d54e1daa11f2fc02797f5fb2b38864d8cfbfcd44069e7eeccb4b1f616912477576 +SHAKE-128: 7157859a930736c636f201eff4fa23f753712a2b8bf0251a65b2b0bce24d957b0a2b50b03b2ec142c6e0eb7c30431c4468e9d8b5371bc43346210949d31c8640d253344ec86d64264d6c3f03a41555e94e071c4658efbcfcc8c8bde2c1646a74607f0198b3a96c20b3e93cac4e7024b19152d7ea3efcb848f3cf92ba635f09cc999c1af86c422454254a037ccde5ae45ed4ca7388c61fb7dfbb3cd4757aac4dc6cc689514500b0fe4514a3a274105d132b7c30a960046ef19be35d711850071c9f8875aa651d4144913ff683f31c713d025be987d5897ac63ee573733aec2f818d00099fcde33f9f40c77d59f07cdabf6324ebc610ef8d399915a8171685d4abd66a8b458269ac065b2a38eb548397b7e8976ef0349d588512e8111196e0fa3e65c2a19c9bdf044bb9714800575d6b09a52a203a0d2d8d0e3b4238221ec90f86cc0d4a9b4b3a1d3828411098166a71d1659fc96517d0684c4bd587412c0d74195c86d673a9661b5c824eed70e263664e90f1d6f771e60846f5c7bbbc32ff08a4e3c87f56d5b7a06c31d8412aba6518af73186cf30f10c8c8a0d298ebb59f7bc51fd8a43f2107e822b393880239783a8ba0cc7bf4f475f3b8a3206fb66d357786f2404a30a38abe483edd8bdf9cfa491762f16dfe5ea3f904ca89e1024eae7a30b8dee2037f3deb10c0a071c275cee5e8df4cb13ecbd08236d48662fdcff4d15b +SHAKE-256: 92f8461bcbda3a94d56701eeb6f982cb8508353f78145bd549087865fddb92f0276c0ef9bf196452bb4f9e15d88872d8231185e276200710682116236418b2eae77021514f5a98ed685daf983e9bd13dd29c6753337d28a2cbb0608fb8a61eb637943a951eeb9b88dd810226055b56df6fcd6112056cb86c4c16db33078432fe093554a275eae8f65c2f1da7c57f51a470b3191df54f13f0c3977af1d7df910477cbc8cf91abf8c850f020eaf6c353a4e321994c332cdcb4783745d24d328bde50ce195ea075e5e49b62ba83c1eb0fc652b5d81a36e54ab022ea2371150ad9eda2b128ac15c24f8775a6e591b919d4c9b34da20c8033c5440ab81040b3c07e2f144dab18f190e4d61aa1cfc67f00ada67c903b27e78a854c986f39ca67a4d1145370e54a1ce2c2d278f54f096359606376e3e8bf40b7be1d1d69961a78c26b62295f5b0e6c9a31dc23dfb4461ad25d98713aacaaef08f6ce9a82d5f6fb91b79d35591f783265d986417f741d048578fd913234a2a2595bbff12857c3c7e65768b4f9cd54256b2c10cfbe3fe948522ab6cad2954db47b0237a0f9408c0074a1fa68b0fa1ef61923b9be021bb4a0cc0c1015311fab51aa9eacf7137c5b536d1bc889c248f68005d5606773cd75c5981351077036f3e7852d923cccc38b89b01058dfa885c00a949e53182e2931d2fcb173a3a51b6f58a03459a9b33eba2f859ed4 + +Input: bd9216aa0bb848df6d137e5e0b5f9d294d8e06183c0be2bcd1f36dcedfcad7ff7551a9409d1f91f74759be71e83938c24c020f4995b0e1086b7bf8bb432ee5dca8fb2a6e534a1d39376b04d39040a818d7626587a4b25c86633f6f8c72a673d9880a0d11cd37658acc7a1c990f0aa2006236622c2876a315a025b3dca94cd267f29e940fd98fa9 +SHA3-256: 53c3ffd99923ef24c44d422a779c4ce81a1131c400e500d0bf220def62cef9bf +SHA3-512: ed4b9d297bb0e65977f5891bffde362799fac57c8e71d9695080239c4e4848be84db2755bcbb2104696081b3b95c1b190a4f9d73c7f960bbac5f8d435b6c65d6 +SHAKE-128: 6b95cdbea85bfa40ece1de7cbd1ada561e372f613325cf3d842bc6ad54efa3ebf8ffc7b2a30d7d1bd163d2e8b75dde7e25234115cf0873080522a1338aec767cb2aefd9288e2e2b1722fb87cb9f82517320b0362a27bc59c6e2450bf80c3cdcf69803f61f6ef0a2b122b6be9cd6d02b16f1547ef189dc388de3fdaa60757fecb22d9d492a299a14f73d898ccf38f84846c4ac51bf8f7970c9a9e95cd7af5dd9ab19aeff18e776b909a0c6616157ddcb2ae86fbe3f67c3b7a8369d54365a772b2aba9b68e679690423a53b034d92a6878c64b0916e256b1c0750db1ed03c91082c3c795ad7723b0b56a8a15ed7c66b51643af31f8ce4bc43f4f584c0c4e8dba038b6a2ad3604a9a2cb600ef50f9b17dc8708b6742b357976e0e949120da83cf67d0c4cc00aafe836cecc53584cc48483434edd0e8d4a78046672e5b818cf1bec03fb2c7c29e945784e6829493f49c3c308f11520472851dce9e4310f093cb2f73b3d0605ce764081f114105781f50029293a92a788e46dabda8a53ca689dc43e9a8878311b0c9e0252d6361489395ed5da897349a0393f57261cdcda7d83bf0a18cdc621f82213988fb3515aaa8a997c7eb541b18d8cc13115720ae8700d61cb570559e7b2c70f27009ed744dfcad16a7f2411c5d515d584e1c70011254e66f7d34fe72f3d649e4b83506f4ff416f77de480515462a51aaec3c2abaef8d9e749a +SHAKE-256: fc38b53bc8bdf48b4a9ccc1ea3b76d6f6dfb65658971f5fa83e7124335265ce881f11eebf925d1ad0dd3444419aa8cc5aaf7ab92d086c641af0311dcfc3f46cf8d1f81861f0b1e25f6aedccecef792d52a2fdf9f5a7b076af8574c321e6c13ae1f7eba7d0f068d9b669162035fad087c57fe28c648c168d6e69a815394eb079fb250a231dea8f6c2cac96f72b06eab13d366475bbd397a49c65498cba4ea092a93ddd257b1938b9926d5ca06eca0dd2f427f3162c34f90541dc29fbee807664643a31d624b2a241ea7dd7dc1f5193fbc98d0253eb76e9fbfb927eecea9616035c9158443e5b86ab2305ec8198599d6a1956e65e7faad9ad6109fe5c407ff0f46e372a00ce14b20fe7e5135a48652e32e313f6f4eefe5f865ff05200acf1ba68b8fbf4907005450d2c414b9361580ea4300c86bf003c44f3c758d6a89acc429c805cc148f224e66700fd2463dbf858ed751cc59abaa154f0b64df93106951f0e2ab5fb4743388fe694b5b6ef02511bd20c7cf9d13ddf63ff7b31924f2cdce2416c71fd11d1e1eae1345191b180541e6708a00e8d3d6570df36d31a73d36e1643d06b332490b3e4071e97c47b7a1a49f1a61afa7db26142a41c1797d4c65df0934851b6ba3d4e683551cb82254a3af647c9464c80a032db328f35e8e16d525c86bd881da650bed38b273bc661782695fa45b687af8566636e5473c389ec7dcb614 + +Input: 89917b5c2e40a353ffe580be25efc5d56424d1c56ae6188146e3ce2f209b30c5c575b65108e6888ca5eb7db5d7cf41b39518acea853e741b2fbe3083a27988e1b83bbdcea87e804e6820407a59756e9ccdd5cdc225625228a056f16fe663913e550c458f32d10a6250ed461c15ce7635410faa5b071f8ff3a65c1ad7976ff83f0e181b291e4caa61 +SHA3-256: 7b7b53b54ff340a351310e81b816dae770bc9614f7eaad68c809256904c35af9 +SHA3-512: 3431236679660fc13fd09d7a22d16b566b2c96064d44b774996d0907e0a96102f683e99d1d8cda92d8be351b3d7ecf802997fecad864948f2277a08c7a011488 +SHAKE-128: 4be60d4a7b7b0d0876560cbdaac7410788d490a3d2fdf4ef8e4ba092052d135f6750586359f4251307ecc75823e1abd162bf2a0a3e2c22f7dedc80b2991b3d273725458deaaf95c45e0b448c3a89fbb84dd4e6619aeb911250f0e9e56e62b128935ab11b426ccfa043206c6fb913ea0479f44e7ffffe9730653c84c729fa63fa74da032bc210e0ddb45ccf0e8f670d0028c8817a1afec945234c621f2da33c950d530b806eeb1880086ff4f0a11a66569af904786750b0d34d39ddbc77da8d6607d7159c3e22bc13216b2fe69e0dc580a79d9692022dd274072625901424462c7a7042ccd822eb76b421a98c23954ec8f451e1e6ab981fbe5d811bd6569a5ed765c2e27d5b4a89cc6130952fdf78822edab36745a9aa548da600efe07e9b548dd8be0e48a8ec4c4e7a3107d0a8684bcd07cdf0b164bac2d70ba8873d28ca9cefe7b210e887ef7c245ac0640d9c36e7dc517d80e8052ef4d2de522aa8348138122c8e1bbc520e2246f6fb7ab9dbd68ad35d8a90fbaf8123c849625b32e745c72fb77e415698774ecc01e75004d3561cdadb55a4d663501ca10ef8761b87257fe743c257b001ea7b2a1ffb18bbeb496c0bab40928394064d5778a2224ec13d33df1997d9623ab2fad08c16667e3c2b78b375a49f62ff33955f835fa843fbac28724f8a82070b898cf5a30f204f001d094ab7ab3e6a568dceea8ff97dceea9497fd +SHAKE-256: 962e382db26ec28ed8935a7d1987e2e882e465178ab9d848ed29d575e7717e0d24daa5811309cd0ff5d53629b1bd46ee15082d82b83f57fa1f2dabde0b6ab5126c929d03fe1b02ce66f3075cda95708d1e53794b79305705d0dca27305a2bd5b38ab10c8c197731bd0efd70b48bd5d30f57805116f2f2d6c409d74d2424c6f7ff76a039841f2e7cc4f3b264d94347b8ae846ac135b3613721201b8ffcb341bf1ef44ba5544a295e7a7dfa3099c6e41f666f769632cf4d6caf4505e19a6030adb42fd16a4d32ea86b587b0f37134322da09a92ce17ad037cfffa46df105aeef74bcc449847b83dd43e8e18a4ddce028e9d17638b87296dfc6987f5b42b810719a830e7103574c4bc9703d8f7201f9c2ae661a2bc3934c065516ff8e3e934a2817230bd8498351c992ec57e837f17ce50d882446cb888d4ec7dd16503d71bca187cc7bc86670d10dedbdf0923b8e3ee8bd54412678d4c79dff669c8a704f4ebad14a19af384295cf596b3cf9cc0d4c34d4993447a09adc117972e6c91c30b0c381c85096d05c8c8e2447b4d1ba5e653862de2b4a9b92a500564ee47dca8265a1ede9ca6e3d9fa34a7f219b08f5b1bef2407ad2511af72198fef2555ffd9614102f3723c42802b72a0d80de4d25190c0f7e8e03ef644d5a7c7a7b83e69e4f150ef455a58811d93f161a742ceb897baaeca88a7cd2299107ce0ebda1e02fec865b1a + +Input: 700bad39588403361ff086244ee3e72a60541cf640277e12b47f0adbee3d8a55cd9d2f5b91c9da969a5514e664406ce4d217c2be532db2c1def5f8316cb8054d13950484c5178b008c9c19c9fb516689e67bf897b60f3d69206dad8515eadadba1f0343e76dc4292bb507e14840786933aad4f1121ab22b70647b54998296139f375c6cf67cbd4829a +SHA3-256: 5f2606b9c4a89acaaf506c85f26b7f35b26d595d43bf5be5c99a490e3daae9e4 +SHA3-512: 8148cc206fdbfb98992d6997afec75ebbdf8c5c07a61eafd6fca292a86fe1a3e6fc70099f9f4ea068628c82416ce890913178264f14d8681f1057f3bf70e67f8 +SHAKE-128: eb03f27078f1fd2e32cd7be93e36c166d426745e95d203b491905dc3d4f3a48727e309b6993a02744cd7108d4934eddf65adc872127105ece70b49af41226393f39cdc89b749ef3f917349fed7d56173f85c769f81ebbb9cee66c03bd1a9479ead4af7524b76deaa88966179b86a19353e03864dc4d1dbcf9b940b3adb05886b3d6d69011d5d59d06067e9f379ce39e3df3fdaadb657b8a6ee3892258ea892e259f488ea221447f6ec1da550a17a11d01a6ed06f82adad792ad229514e503d7cf9b4d4bb92ca3d388a74bd67a2d913c7ffb1ea0fb15456eaebc9f5ee970b40241c7eb874383dd64e1daa9a0300a978b3b2f3fcd035ef20b5e8ccee159513e5bf978c9c9da31870c4bd6155de05963eb1da66efa8e03a11e75aaa5b735cf30ef2f883e2f029b8a619666708323afecf1499554796920c8bcf263c6caf92964a7cf27de1a43340d2f41797a9528eec96fc9c476d1955282579cc809f6d5e6507018a2b68d99564ab424ffb1e968ea60034648d8959c71a6f14f4b4b37735291c96d336b958eb54674e6f7057d585598bb7518489af010fb94c2d1394e51674e21309e0cce95afe4d6661fb91b4821a4ebe2c9ca1a4910a027ecb900239d5a2f2bbcf3d4595e9b7310d47bb3dc47e2faad48b9b27cab4198ab1f0dd78f95e3e3292bcbb52bda87168e654db2572ab3e7272d30189a1040aad9cc6efaa866651fd14 +SHAKE-256: e4801de7475e60ae13b070a3dd860f43fad63b5bef1f498a130562c3bcba9851e791b8649d72f62abd44271915aaee445d96313a0c0b5d388a513830996c5bef5be7b86e5af238f8e6ee89f9b7697f25e11b61a03247a5f120c6431bef3e21eff6c22a4a199a98774da15957fcd21e2370efcdaaf1a7a3f98d43c3842c845787d42107f63cf5f3244d2c8fc17af9d371643d7f6db1524da3908ae4383d6f0c887d67f69e24ec2b57dd301872cf9cbee6a9ea36147f80a59165037f8e9effa7f07848f1623689c8fd1ff90eb48c7afcea434bf3e83f7a9ac56a024e329971ee3d72487d195d10cc13f9cad3ac14c1ac4cbd99af3dfd6a4fb83bf1eb42fc994f6f6178d219734cfb9c4dc060d9609d7dbbfebbc5f2fcce7c8836555d05a7c532102f981b4d82fe67cc02bb2104e4d9f354812e24d14d130131da38c2c58b8075f70425ef4f66c27382db5104cbd629b80f69a78102cd66d995ad3d74a1dd71f36ca75f69e8062d7204b33ee301173ef0c3b014265cd7f30f19b50a7130b7b1604d716a4358b364a589fc3caa98909ea6d3fedf67fb17825c05bed4f194d67df484dc6c00c3460050e53c28304e9d407e74e43d4184614874b90fd952fffc54e0da042b539b96b833a1aa2ee71f6a6d5bc18a2d3b878a77be74e3fb6edd0fe3bb046aa93d2c91e20a18c296f8cb11d8fd61362890742d638b5bd6f4c41747880fb2 + +Input: 1751740e80bd25ee5b5c6a1bcfecf420c8e7fad8a7d0c4fd65e83569e43641662b5637c6f8715460f5ca025e27022cef61c9b86a99d4f4ddfb315890eed541b5459e33838677d0f1839d46b22a688ec0645b9ca9b0597e9d039e7b77b541e3515445a785ce630ad84e9b61220e6660db0f3c78d9f3c437abd2b7358b213290d759e05668ebe78c23a5ae +SHA3-256: 79e11b42bf5bca15565aed94ef9345f4e5de59a3fd90f2e52eb44785ab02d3de +SHA3-512: 92f0c2d042d7d5b3a6faa5a4cbc0cbb014ba1acc69586cec2b607a5b34480381d77f7da46e5637ad808a96a517adfca1c230b370fbdd71bcfffa47ce8c7e4321 +SHAKE-128: 67a29f36fe9b43ff172079d457b4417d64836017136761fdc97782c7544ea6fc5db21c058b5909afc245ec26eb382274413bcbe44664e1fe1ab34dabc680774d709fd433a8dfe8aa1e1d74b6b816b1f93687b3a9855803507ba665e7ab604ecd118fbbb161ff5c7ca6248d4605ceed55e850479fc691e993f0f91dde84436a9e885e596f169d5e6caf42666e2fd4e6f8d88175ac37d66d677baea4cc257232f65a2fac3d9f46583051e5f3801b742a9cb9e7d875e30c62fca9cce1c659ea03d452997fbcf06f9f130d428c5ada01ab87af3e5a021afa446e51f3d694cc0fd4b9af8d6493cde4ec915e9da21b6f67b926492e721bacfdd82353f43a5ef9b2bf9ca29b91a4b3a12e6f8efb772440f55122f452731e27a748bf57ccd7cdada17b7aebc6d9ffce62537d09f8679d4631f676d8f06760f58e67fefe61d1d1fc4dbfbd3ba373944064bded08bcf14f912f6f31593d2f507ad3870f3b022905077046688d7e35d29a5c26e82a826f073c802d0422b2f1eb27301f368cf43c1c1655327fbd9bad31b4d68dedaa15465d63e9ccf309fa18625aa8a60ea737e24261d89a84932090501aa202377e5903e31b33c2489c5ab076feb7b0ea73be2b23bb20b254e5dc40f5e6fc501172bc53002d72907820b52ede638218a3170c84c37e88e0f7bf042b0b226f55bd2cfb2712e339e7390619672afe79c6fc4298d15b2e69c6cf +SHAKE-256: b33c67ef49de5fdf94ffeac05fd3f95c8b0523c589467b62fa397cbe59215887e2999328ba323395e7a642b3cc35788652c985774722296e160d88ca4508883b7a3c8b4b35723345cfc6b617ade36fa9cceb064e743a51994cb95e222d4684757c37dd46232dbcc76a7ca43cd2c4cb27b86e93597a61282842839e4e97e17262823dc3956105c18d15fc16917d3e0627a0bc9e4a74c78c1e2d6f7fbccb536e4f4cc762b91cdbe5b36db6463e4353d0a1515d4cb1382c4384e670675f0dfbbbddceb6e31fc40d6e52327a6bc1a69201185c892fcc2f2b2ab5efaf169dfb4638de205a30385134d110fa2b7c04fd63dda663645c4bc83573b0a82ff73665cc805917d751327d3c703627f1c38c3dc6f6e9c6d725e84b5b8f63b200e3927215d02b668ff50dc8f6f8188ba95ec1482f5fd008f98118cfb59e3049995366054c11321773053b4d4f146b4d65e81b4a902fe94a4cdf2c7cf3b928545d9160b3667d90f6362a3a59971ae407d24c57973876afe4006b5f5c27b1085aca17d0db8e481ac38b8f571f734bdc355c0a1867c1d1f5aa4619dbecf8a7640dc222213ab08208f8b829af9f78e5ec6f2e2a29051242f6daedeab953ac8092887ad26fd3e891fb2b57d43f6e68100a1b55a4d9076de51120d4561ef10e87549f660780832faf58ef0c48238c02b54eed22a8aea664648a5d64ab870a1ad720507a6ee00068f393 + +Input: 2011ad3f23ebd4f5a3729211f158753714739047f7e8c5ce2daedc7f5eb26bd9b9722cb0b3f811cb328410e8fcc2c30c166b12d4a8306f289f7c643221e14118b6af3d0ff800879e305eeb5655a213957ccc1498293cd9871fd32c2c0b2b5a85f7952b32554658b5ac963d3c0c3567b3c199feac1f66bf286f8ff5c0ab940b2f6bf1e0091a437fcde575dd +SHA3-256: 1482baf89a1ade8eabf131f25c73b28713c848929e20b3dae4485ca2149d507a +SHA3-512: d0187b0863a0a4d2fb407dc0f520bafc0639445ac8343d8468a13383396021e121a3c878ebfdd9d834a5b2f23d18b91c8b096b4a21ce44b6af8d0ff7a655034f +SHAKE-128: ca4cb7ecab9917233bb3bcabc2430330a6c5f72c4f3ee3203ef461a03af968e20d6978863dad68977ff9ea062824e52157ebae9f8f7f4d25c2e360701d4e5273b5c66d9e75a7e5ff1f6646de35c18c3b889fa00d754809ff9fa309b5c90ecafcdd768f674df085c22119fb63514994a38eb755afd35a945833d7db0cb53896a531e08aa67475993287ce3361f098a05d46315e97345fba00ee7a658644ab13b50911e4e91fa2f4d90efe1ec9cba048a4fae547bd36bdcb89b04bc009f86b6fff1f25f6c1bb20a4ad78f18f800f8ae58785b868aa6d25e9afda57c0e7816141b00f4b8bef5fb243c91412d26ce0ef3fe4c4942941158955e60c330eb5f9195f6c618ca955fe9447acbc9480c35e9b463bd2dd423023f6ce24b5113e598d7b176fdd80c364e797f44f1f460be6c22b2d0e0a7cd8194e2bdd999d23abf1d25d642f622ea62808b710d3da2fed9bc5af83a5718f79817ebd975934e00fa10cb7315a9b9b785916d58fe5a2364b8746797183971bf9a13093fd7e599d34bc920c86a01aafe4a67d85183653a18e4282de5ea47841b6705fa910baaac802d8cefd45bba746fd0b6f5d17f97662ab13bff621ae48c26ca3dee75cc18f5bd53a98e31c03f630f31ded4ea463552c64b6b12abf29e3bf824992f56ead1742c6e684881123e4231fc18e1c7c1f613c6ca7a6a2fc07f3e72ddf252f6651505fa332e8a3b45f +SHAKE-256: 2f14be6bc0f5b754d05b3f37e4110a9786785d6f982f67d896250a0887bea3276ed5dbeca632415b2f6b5898ed6bda6a32f2e3397ffe5d699c0adc2147e26980812d327c09745f166d5ab0a1aa874eaa0017ab0691d19c3811882b9c19b6fecfd01425238ed47cf9e43dc2fe2919d9c3ba53fb50e7d3b346463b8b9cc177f00695e3ef070ffc1743808a54f2415cc07134e12a08eb6017ed73424e738e75eb5eabaf83a75a64e830537a160f4057e0b646ef19be7eaf770638765ee409936639ccbda76e271d8f3f9fdc9d5d17382cff658492ad3f4be9c493099e893cc9a3aef7727de37961cc59af90b379561b3582087fa9c5b4902220604296f104c2ca7833c28ba264eebbc2acbf6c4225d72fe73b03123c3502b9582d2b0a7fff72dcd803bd3c588b437eb6dd2286525aa3d05cbb38dce120f5c2b3bdf771cf7b91986f8e2fcd2d04489a6fb3db312bb2152da6058642b95b54f74e67a71fdccfbce9d83ff56b2f1d24f207e0c31a8e3a4f6a99440ca67baf35515e9f344e50d8855868591c8c57b8fa4be43ac01b95d0406c231d351978262e15a20e86b8bc03a6b4271a4fb2f582ec303346ebeb58b4c0387d55eae80c9d1e3933ec75f50f15d2aaa6e0b8f040829b48d253ad0f61e709446af5dfb6bdd4d3eb721bf38baa3abec99b29b8538be3080e0a3c613370e9edd540b408d7b648979c00b2eec7add68a91d2 + +Input: 87cdfa57b6ff82c5c8d87f57a71528ea355186d1c130933d51fa8f8dbc003a907fb3f8abf102ea7b22c12c4edc8762b6ee540c14b17ecb11cb688fa1ff6724c4c5fce79c7768b5ae37f7d70dce53b9941b733bdd9598389f0d422279bc67bf34861a0a0f34ea6ca725fa101c8fc14f37fa9485e1a6f9d469aeae234a3f853680bdc0c19219abedd7a41d2ad3 +SHA3-256: ca6dcfca889a56e7abe44560b4b40cf9235be2571b31d3dc084fb398ca5d823d +SHA3-512: 40b44640bc438713469ed23b9cafe57f6b41d8f92ae143a9fd2253915bdf92f0585bd39b7d0a2d7970bf5056adb24f284286755a24760f18681dae0b7b9f0e9e +SHAKE-128: 92ae75dc85b1e650e26ad62ec12f99d2f7022d009a92e777aadfa0b699c0856c436ba942ba260eedb0f6309c005d970431844d511dd5d9276de0ea22a4db24e442bbdfa34af68d2ab8dbb7c3213f46c4760485f53466429a29cd7090f6d2855e04d1da82d6faf148cbb1979f1fdc65e521b647ca887f71172a63d65b655d329e7f51f35e8815031e552a712f3384ace870e0208d016db0b11740c9b6d96793b182dbd1263aaa3dfb7590b3aa8748e0a937584c616f08e3f70e8eec4d60cee631f79a60368e8af7c45096879878618514f920e032122e3e2e2008adff08517f00661941643d31dfa621efb499555d61d699db59701018c09d6d03350420c73c3341b69d4a4fdec477776f00e263f93e13b4f38923fb6fe60ffee5b923741033f076a5e4c4bc0a3f456beeba26bf82b848873d76e04335fc9a26fb4c85a3a0bd746d1c5392dffd1efeef80817b3e75584b4a1b243a65503b99d72660a9613037c89fcca111d1a4df557faf7c38632b8e4e52a62f97052262f25b6d60007b87a65a3818baa67ee8753c502b1ec22c32a84d969624730f34c3546230581ecaf61f412ce3b42f0b914d02e4383b48d41322098b78f1ff861a9ab62833f12ca4d6abbdb7364bb4eb84532071e994389f15ea75d1f8c6fd757b4cdae707f03d40f55582206da322882d28d6de3cc50b94f8b8a5d3a519d2f4cabf98ecd16dae074413aa +SHAKE-256: 8ec70bb9e6f48d76afdbc6bb651e542eb47fe2928153875a1fb545c0280d4216209bd03b859decc682b63252370dd281dca24ab5519e6062369a771b0b20f64f829984ac9b3f2931585e27b9932fae886bacd3b84a4c881b36b503edc73b9d17c3eed65fd869f2a78907381c904e24d7ffa4178d17cb694f6513b1af8465607a4fa7fd5bd515c4ff2015a657f8308058657adc7d011180aa75416d360f8d59ecccbcaa1712b6923d15ba0f75779f5388cff62aea482e229b79818ce27c51f50393e1e241249f4818170d2ee6f155bdb4173fccdefe55c1f7d3f59ffa12ff39244a377349459571dc5cf15c61fc132e5ad15103d9dfc5e54771cadd2f94243c339ba3366475c4e5fa9f3a34028137b2174ccbd44edadab19e3e4283996e1ef78d17bf4e4ee36a8e0cf7b82070a35511b84e662286fbd7cb34bdfe052dd6e53052bf05cb26077cfd1902c449dad47597bbef5f21d0803bbbfdc3580301971a6ac6c7bbf670f381e33a45a069e9c88f48738fe51895469b5d9b9e52f925890783996a83ab24f5feca6b6aba004eedd8a1411cccf9e5818b49738d7c8f4760d28814dedafeaa8e49ce30eda364842de59200ff1984e2da1590e6915c6f70b0c7502dafc8b6808379eeb1fe8d55b3338b267a5d4c7b5b594ca51311a36844f7c55373cb2946988358202e1d0488cc4800408f539d65c2d3be1c2049d604679695e8b9 + +Input: 754bb305e4c0083af28fb4630de1fcd54e929f7492aad462bd1bc6cb88d1b32085eaaaf98a34ab4a449c9d6255ad1be1d4c8ed9bc950f9a880ca4afb2eca23194095c969d3c729e6cab72e73aa21c7ce3e708c3d5d9654fb0080f41064b35dfa51d89b4841783171ddbc432eac5f19de93f529a9d15230074eb09607a9a935b76e791adf835abf5f2b09fb73a9 +SHA3-256: fc9ac6ca53a4252b178a12663e10c408af3079f20da1c5c988aaebb3791e2e42 +SHA3-512: da56a010ac693468f18ea04fa5b8da64402aa8e7cafbd9fb2010f0a1b95992aceea0a6f24cdf31b8908eb2e53f8915e2df36410816c426f79d8622155070f591 +SHAKE-128: ea16fa5bd9bcca32c0e9f25265c5a9472052c1213b2255162a10b24f739869beac1c355864f60cd8bb358f45bf3bba2d1d7cbc4d6ee4f1fc3c51808621cd17d9bf71c1b48c7b2a2825a4585cea0c2a39799b9da05e5c79bf6ea0351190884064dd10ca978057bb464c906f465272e53b0b24ef3f28d4b4bc0e8adedf0c24c899ba2560c022b4cdb6301d7df35271b8f4204e7c8a74f8863cc3e5c238f561d711ca99452d4666e95a44128dfebf2e68be9d5b46b847d55d2d3376f56c58f22b8d0368b8d84bc4f8430df78c6423bed93d2d9b6c4e82f77a9eeb80da72dafbfa06072d28829406b003560ede2524522dc9dca69cbb1a2ab3296a31635a43180114013ecfac65df2b85eedfa0c97784e59d569358445485a5bae39078a7388b61aade3f6c522f729839daaa2f68d793a9094bace118465061d46e3ab7ff291c6f9eac3d92b0b454ae10a3a56dfb0ed3e0cb8bb9ba7f22979c56080c8ace18e1a109d66d8f89b00776f1650223aecce264d5230d245cff9d61fbbf8f028ce0a73c5c6a828181f70aa4dc2ee0533aa297b74c012ee21584503d917d7fd7f40c981f12d071bd3c4d3298b945abd10d3fe79acda62368dedb5d015faf0e2dc4f16e8f43e4bda08c04216a76101de9323028a346e98c8547dfec0a40203a7799fa85eef13ea90a9dbf922ca0d5ba0bec3e9799e868e4d7ae556e95dec6b7023c035aff8f +SHAKE-256: fb6fdb1f26ff572ec71a2a8a75d488fd0cc56a38367d95337958abd255f67c3cad20ceeb86bb4d5f4a375cfa7acad29cea0cf2256d98f9e9e3ec583a109afaef0980c1af57ea7810fa06db689bdf91b6546ebf52c41fa9c6c329da6cc7b369c0469bb15a764e163d86673ceb9b1ed0d1a7ae2bb721e44f3b5c387d436c058c4947dc9a8e1a9b5403b0f028e18110d22eafd7c5aa0ec6b0135a06183a9774aaf05421fa85e6b435bc5cd7c09b4af89b2a3904236bef556496c0970bb2f76b5b34a4139d8a26e3577d7a13fb5e205df73e69c0dce8aa0d06f4ee2ac4694eeae8ed25f30538ad5330c208efd5e1381cabb72b10782d9b9a7695f73e204fd0d5c2f45ee81bb3fdf77ecd0c3ff4ecceb9de0fc7cb10135faed8474a66aa13e9a80af6f7ea1b3d43ec9efc4f51cbf773d8edc3efe28bd2254555c585333c7a604fde018e26b0479acabd4e2cb796de5ecd5a9ec618ce4d15e5976f0930c0c349b89d7701a3bd4d5a8c958b82771faf5d28e86509989a766f092825133641a6e3c408e9791d52d315da274d4d5cdd6220eb4b041fded55ada3cdd160f56e420a01b0151a4444014c5dcb2352534eba5e3763ed66ee96d8a6a9edbdc9c718b294051f4fb4dd2b10571a2e1e6ff5c880cff90a0c9207545c4d0dc9ec4d3e2d4fc2fab5c725af654c7e0f62b118268e103065e2edabc3ee9d00d8f41ba2ba0e14a22f9c1bb + +Input: e49bd01f8d90e8a5aeb9521a12dace12e4cb34016b32339546f500c8949d75a8dd6111f045ec4a931345481633cf2e3a7db98d425bfb15f415e5d6c1a7326327879fc47821726de011938cbb0d2eb2d3609f605c6ceef11ef4e6c98b2a735cc13c0eb3846cc6a1e058c472b5849abcaea45196cd6589ad8e9366d6eb51b83e423e0339252acd0b68dd6b94a1c8fc +SHA3-256: 557dbde517d3c35e876be9cb5706ad05bbe5d67e4e302183819c9d499deca61c +SHA3-512: e46020bff1403deca609c8d18bc5396e51a4f04aa2126e35fc4597271f0e0cee1e9452b541db7c85d1f9507272df7021418976a5a062f90f1a3481e5a79cd30f +SHAKE-128: 86d7caa339b2d9233ddaea7761ef45ab97f8db74e317886ed38b11537a49fd311af04b50f7bdda49796dd7194f9a6273ecaed5bb8c3f58836cafe2b5e8fde2da3471a0a06e34d532d8b69d4a99bfbd0fcd426115888e802460061ac80e040d687015e39cbaa70d885c3910e3832444f43c63bfdde4f13202d25ef7a39b2360183048c4caf3486c1353efb7db1cceea5857db77cd6fd5a3aba60e105aa7cbf5b843f69b68a863472b318d0086a8d1a28a298d962f67dc73a1e18808a2876a64d028b6a0a1b63f1d7ec91aa7cfeb6ff431f1c0da8a2da0c48e04f6fd4ae7ed2d60cda983168c4f2e7cb822593f03840159ed5f6f4bbbe393a063efca65cdfc61aeb2b8f08556d405dec87165932a93c11cb5df6f9b7e696b2e3b25f5bd6d119f09f4e652039b98454ac81d14306a7a05f7739d139c93cd4c1f0750625f5e106875fd6756efb8ba0a8d8886d84bc8375d3986b20ff76c7e9d0e4aef402d799e23c59cf84e7f679743da5b0e0a1b0b256a8811ae903cc5b420998cef594d04d389f7e09136374d386376860e26bca990b3621706877d71d2c93780305ab113e1dff4d75b3f1f96dd992b8613868c0190ee2b4f86ff57ba7b741cb1a5a9f1f71746e94111029db9159c13267f35b819ba0d82abdde9c3a7271b619d19e0491e43e3db2eff5e2a2f49ba61fbaf8a055dd311a6b905a886de1d436f312d6cfb592e0fa7 +SHAKE-256: b3a4dad43666556c7cb808c7f688980eb80e69615eb8d433b38bf4306b0e032554065160b072694c488c4b2fe6601d0a9d2c08b8c6055e8c67326aae61a9c883ba0e6c482e687b5070a287951b1c9cfd37c6f78bbb2ddb74456a06c64a1314410d7f5f6f9c9f7010c293e43c225a52b4ed6ff977d9f8d217c3e63e0d9f2a1778c99eca77e66d372e41fcc9c54ab2cd6a5f9aa90501a56f980311386ee32e499577c21557950cd1e30407f74ca6e0ef8cf28be46b848224d4eb794bf3003e9f084da03bec00bf45a32b4b05d09ef023fc3acb55f70f74d98ba7e6ced8a9a71dd1fb73281510ff337c1b2723897e06d13f52c956af7036997ca12cd6110292470f6aa59343cb42095d17db96e829fe6d4222a178d0e6296235c8aa6998306402594da052c6f543fca291088842b232f6e27580a7187b18870dda45c845687d2c1e1edd89a0ca3f33713cef7a5199a4d6d2e1c9481ba070f846c57d3dddf8ba4166138e3ef3241af7465a87c32f2e2c7b77ffb6a2ea4bb2d8c26195b409b4fd65a93aee773b8a1c09483ef8e3db4e706c37786d53f6726a0c2a012462edb6c3032e8b30529be7dac69a7b7ae3089c4bcc0155b643310bbd210989d67a6245a882215c490a25356e89ad49771f0de382e0261c2048cdd183db9cf7c0f48c6cc567115b9bc2ecfc78271d9a2f3e147f2ce26f5c7aaeda0c5d85bcaefcb7d80e2b0687 + +Input: 3bebcd15df24f642aad40235464943398ff055a6d452133906e41e6bb3daff888e59dbaa3f17b3aee06d2e9fbe5c79c59bb6c0e4869573e7ae911cda0e48f538a01098941a014474469c9fe49702eae2faec703b065c76ce9db3af23b5f888119623d88e575820f63de9f15a85ce64a9faf966c723276b1627b43bd19c8ce0bf807edb1f649b45e70bba8934db1404 +SHA3-256: dd3dc79b9c86179a2ff43e25162473e451f315ce3a738218208797863b9559f3 +SHA3-512: 19ab1d72caff241fcd19a144f9080405eddd79d271936f0dabe226ec2632667c6a7677e50f3fcb6421e6e184d442d41dcf51028d7eb44f7976a0edd7303fc950 +SHAKE-128: 64fb41be037d3a07bff254815879a610f6f0cf08bac74e565f5fdcaf802fa4bac02f149ad415ebd3e55332bc4513086f981d06aec103741bf1fd1a4fbb75bc65e13604052f2b609b3d35bc5ba9e49d658fa9a6f187f3447ec4012a035ffae106e0cae6aa3b62d16ccb355d60e20d6a1b8e592e27a26f34689adc07bb9c60085578bdd7fd78f2b009c614793b89955b23a59a08b0fa75c1e4c349eb678f2f17cb1f1d842139bdc00b0731aca52d2079ca95c08c06b8bc1f31a97745c8ec76aa4a1d601a630109c4621ad0af6d7e7127a6391f3ed2fda51aa179bd9ef20fea5537bf7d0b6d1d1eeeec303b11164e64965e8725d66879584eb20739a0266f1c6b5f4e15c274bcaabfd5c4724d31527d7ea296ff22a9ac5253cc2b6432a16d971d30962d15c411c86e19aedc3b8c3cb0191e966e2e842c30afd278bdecb03728b0a3c6edf92297a282bfa2fb327d4474522e18fa2e4cb1074ad32acf420219aca25fe0a6c1b77ee795fe2d8eab6b9bbd8734db10d0d4b7683faf547e7847e581088e9f080da1b29a0a3bebfa0ca82dd83839cfbf9e934831233010552dd3fec78d17760cfddb9aaf291616b3bb70ccf88953404227db99e80f2fb1d41200b5c29ccc64edba5e6a89e1ed37809df8227b882623e7879ff9d3d5b3304d0096f1e51fc00ff41721311e53acbb0ce395cf14f56244958883f8c75fb2d0da623210e47f57 +SHAKE-256: ae15c81213c4be30d1ed0469281ae6a936e9375c9ee02810fa6ace01670aea3189a2db8d4bd36b5691589b2e1eda3ccd252b682c5b77bc3d0c259a01e5562765491e3a36c3f09edad4b3158c6e936d622c1161bb0194b9f383bad4df489bba081e7b8aa402ae8991513627ca7101f8feb1568081482892d3db678b419e9d6a0db024b306953096cb429e84f75a11f71b865b991d6ae0dff00756897a314916003de63335bd7dfd9d5b80e2f0d135a3ea5bd12b5ed24a37949cb7496d201734caab74b66e17ad8ec7be561e48bae5110711ccefaae8ff18c1a03e5f231eb84f4e6ded68a0303a72cf979e2055f706d4c25de36dae79bf20c213e0ed8c7071e9830b9f4820a1b701977866831e3413252e7f81de1d900336bc2d8af7decb118128a0542e9d40fa91214e350645964cd49ade226a2d9c66b1732b3f18e02a0a7139386da5181e0008c09e0e24dcca3c4345bb11e82f67db50d6b9863c25f93203e6cda204d6c91993f2d1af3b5ea3714553713f75922a412ac46de21e08d21473f74497575fab23fe851112ad73bb6f9b965941084b7134b7f4ee0c5e30797a5be3c29314968e0c63357046c9fdefee12baac4e682a64085f9f66fa3b0a97e708643cece0df24e7e3f10fc4cb6e1ae3421b1ec673e14e3eea2f3d6f3d3b179b8d8ae2a5ba510b2bf8db36adbec59e1a6dfe9780950f230e21764f721ee0bcad7ffe + +Input: 436278a48d2717ac56515f09c4623ed1c33c579b72419af9b3d8e6fd380cd4f46a3fa518d5b1d3da56b66a553a6d5debc52dc7a3d239eee86f2803849f5db90d75c2066f3bf5bf7f73277f318f11d3c7c210de83a0611cf22fb061f5901c1ab13f92e49396a2aeebf5ea29319b81dc6e2c53c21bf4502389d4a87232d7c2ac861172fe0d6fc2060a95eee7c827b95f61 +SHA3-256: 7b409270acbe161680ca010d72c01312b33da9076e97835bda0e17779501bdbc +SHA3-512: cbfe1ac87b1d33cfc72ecd580c3da7fc1c95a009542e193d2313d21a959be6b921d58e36f2d95326a02529d197c621da49e1873627c16cb31ea36e8047d996d0 +SHAKE-128: 46a400681e308fefa626563b7f7bb5ac43413c358b1e9fe35a78d491ccff8950ed5bbeff790fafbe1c916d81c595bfa4c23da23632a2cd17ccfebbe68f009488a26663f66ecf86f3bf047cafddfcab0ced8685dbd2660cdb16b73dc46904448b51b07b35ca44323f419cff42232aefb484c631e80af5acab434e67908ebef79ba03cd65b1b4f68d2b6212bf855e0f6198ed12ef209ea127d2a07cedfe9c72590523b1b2255ec8dac9d87dd7df30b70405c3365360a5e6adab1a8c2a6dfa5a4bd4877b54d5e3d1c332bb9bda148d5997d531d3af4fe9a57dc4df78aed48e8b35121428a15d014096300c4523c61dda3938b32712582f5c504b31cad13ef03146ae9777da3c6c6da80cfadc1e8e91a8511a5e93ee9366bd7736b6feea881da84ec031280da7ccbae961e54ddaaace474196119356e35d486fc12f181a1c327e5ff7b62919c3b8e6be2650ff28bfc4cca9c53600832a34d9e7ad5e705d603458026be452647176a71bdd5889e684297c6d404b10d7f39d4415010538a9d0e2bbf710ab27988c53310144ff39353cc3ec642f48c0d3f12d9821647450a10611ee8bef64e99ce874f30f1c8f847a71f32085e8df095222d4bc4675e4f28a4cf73103563b665b3701ca8dfc8d10dd5f7e8b4f6f2f85cd6230f4bf4eed65488be11ad4c3fb1709ae0d004e91c441575b49bf67317f6f317ed779d72ba452ae6ed008b19 +SHAKE-256: 15b5b7ff73a99d95070c6117c80ce615b26b30fe5a0f5dcb5e0faedf6cad60d8af3b7c6d53964503362a1b380f9f4214f431fc1ade26a9994bf0b569af2ea1ca2840f5291ad5eaa883b9a67660920519b5a4e63c751be9a7a93f0f9e64b26f0f083d074ec011c5c17883189ae1da7015b31c306c6db82c264cb02cdb935cef36f4e585e532d8501c7005894422607bdddae21d9a137b84763cc31cc7f94ed8b0fe27621677dfc4da010dd86f33e23e0ff8d5fc25d4e620c56a695f4b8c217fe3c3ea8be07184249eb9c00b7d7debe9754678fbbebba0da4366f8ba8065cd1b71d37b7e65c990ac09b9051a9f35605b9b68d9585fa786464a02de0eca25d168278506b6f932f96263031e1d196e50f413a9265bcffbde5624a502ee7175e01378878006961c918bd0fc2449ead1bcf2b6b89b75c5452bfbeeed8ef6f8137ab64be6f26744311da048746e9888248bd9937bdf182c3ac7c91298cc6cd5d67b3a1b4abc57cfaf3ea3983558882425f780bb17b247ee261c6e3b2d0eac470c3c3597fa7e66571dc8474e2c02fa8278518d3fee2b2650a5630a48bbb2719cc60e2237ac83534f5f1e6ce63874405c6379a5735b887f402a101c465a05294a6cb205a864d52a52069efc5c5dd552a02e97b512849d43ecdc012f8a2f382199052da3e0eb966ff2f2ff3831dd884cf984731bd8f75fe03d74250d8968e658ae18e41aa7 + +Input: 862661c7b5a80248c37ae669cbae89ae8c2d47da1fe00df5c27de11522f15208c4a00e203f871884dbc42e04be13949ee1cd1ce6287bb176f1da4585b6f0e88e361e2dd722d1abf2aaf784a73bdce7fe4e10f3fb05e79c8f6f7df7884f07326936bc26ff680e673666fe173756ef50dd1f5a9fd745aabe6005534addd0cdb51a79ed52fa1e13776461d74df3f9ac91ff40 +SHA3-256: 830a289a025059f716ef1a16a5f1c43c11bde0b0e9bfce3d0bcaccba1bb89c44 +SHA3-512: c15fde5ba7c52645394022804079508fb289206325032ecaf59630afd792c203c271cf23fe16130cfcfde647fda910f018f4db075b864f80a6a22c1f7d7ed668 +SHAKE-128: bffd9b727eed80ad000788b50f2a6064bd0e2b76564edabf0c1e9cc1bd56441b395b71dab926dad74fc2ab4e8ef42a20273d3efada68da22cd5f3586e870e96c779e67785cf57afca75089c69d919fe1e5576a687708a35626360f0019b3055b2ddf4a1435d13b755009e785d2a62f8a94d0a7cbcfeaecad36210dc109849993ddf6e28e9d1b47d300cef027db6972b19865533c1b5d2fab1ff9bd910661f7c5c0992f447a6bed46ac6e6d0c44419f5f572a3308168491aea3237bbed226c645ebb2e6f7e3bfdcdfb22b96c94c86980f7fa71b40fceb9d74b0109d5deaa0ba6d5bac774ae57dfca6b593b7cc89ad68098c96cead070c2bb896ec14ff66bf77b5ee5688895de5cd13acfc6b964ede34039ead09975595d9c57c3f9fc782f52d2d7fe5b5eb3fb1885df0f0b1c36e83311d5b4cd9754f83c530b98b02be398ab31f6daf0895c48badeb6dcba95fc4b7c8e47e916d7f60edfedcb7d361c1205f491b36655d53baa84c6d3fd43ce8044757e4f247467176aaa4e45d4ef9d63169c9fc72ec77f9d458f7c0d79d48ffd5782e306a9b835baf75d3325c5231a73a3982ac5dedb7c0d18d1c38cf96007376522646b3d0fe7ce28f20a269892aa446084653f81b29eac9a1cfee7b444115bcf9e5dc33a9f0e32e2edc777b470146cc821ab67575997b40b4cf1b39b66f7f34a1839dd8a6f062305542a9ce2aff836efb23a3 +SHAKE-256: cd6d528ce17f45c66f805e0912742c2617c79f544e0fe01c42eafdb84466d54c5c1f5a67d99651e1cc1a4ef725f94f45b64a34a4d9960e735be2f4ad339eaf712846fcdef1ae50eb896fb562f7891e96c9169cd36a25c0e6cbf04db6c9e0ab77ba2e8af76fd9b3cc3b0daf966e0edb5a46b5b800238eccd0aac8daa3dcf622834463d4cd3ca375e3d28f1b9a6f084213f6d92667a55448a60826f878dcae71cb485157f701c16e44911aa0d17d780de607b87660702b295151b2f7b01c655142298d74f8ce76a8694907a2e2a928f8b59d61057bc18bebb6a93fab80815ec9f067a94b57133c1845c7006dca811ef4b7a356b1fc5f0d6e56f80491cc3bff9a1175c90b6de39bc11a3e1517273eb1f46b971d9fc58183c72c7dff3f51349f8d7dd9e8b4c255ce9f717637e3d4d7eb3222d9d638c3ae1aa1315c8ff89ae17f39949f31e10ae8011017f021dd9aa6e6118b40a15b52d54f2caa8c6290219e0860db1155830126d295cc23e87710a15e653c440da05527ff148d4fed5a07b478de38b52e4005d486b915b7d55f3439bcdf64411486500bbcc54a1f4c0b41f079972a69d842ce9365221694764a80e243007d2ca54e1c75ea4493e81e0aa91274bb202e1beedc6bc17611e4b1d8244090635ec2e6362a0fa4d019cd4afc08939c5d7ef8f624c1eb391e1f200c3a2bbc60bb0fbbfd34b04374c4f45ea0c047e6a9ee31 + +Input: b7b074ae22a8165ca192939041c6292dd677a30fd134b9f0cc6ff0e932250bb05b797f9ad84893991ce199fa0df598dc92576d560836c722d8fd00fac679669ec2ff4d0338dec1a57d162aeb1c6de23abe54219f2200da49b8329098ebf2f90eeaecc15bea6d1135267d21bbe399995e395a028cc8a22cf59981d9cd3dc0560701ddc2f0fe94e0e9e898c1c80553f80db164 +SHA3-256: 966f1d61d277b5d3447abf39fb7ae5218ae86849c66ce3d88fd60f964aa6b562 +SHA3-512: 05c16b8daadad5a78c645873625e99fd5c1e746a616272c442d63a2cfdc1da5645b3f0e01c283abedf749ad12603a0475205879525cf069089a2cd6814a4424f +SHAKE-128: 512b2037cf1d0edc5c2dc08650210e3811f1536021fabb2ae6ae0f61924ecdc2de92cef47811d6bf52190ff00e0af0e5e4d279a1585d77d7f304d19b6692bf8bebcf4f50f17a236c1df31598bfbd81d2e32d19a9a8ec24e785a35018bffd8028060037ee22ae0f210f5458b8736ecff7d4fd66870f362f59ba6b623b2c9865bd9b6fda62b7909d5e3e4e5d9d0f7b95bf2d0c6fee2a95869787ce851eab1289d8dd2cdda42d104366f1cdac430284296fe313bc4c5eb517b53484491e3841628a41409ff9088eee50a5da5b6cff95f9d6ef96e9e14cbef71b6fa2c9ca70b10e02962d212d2a9e09195aa0090fa5094cf09b7e2dd2b021746bd09a8a5252ad25eebfadd2356c5189a4d0444b085690a369c1aeab72594e6fb321174abb78d7192370f08e437c558ed38bfb687363274a7435133bff9b4ebf074932981f7d2d4b7a44ee0d1baca1cda3fecd068e0f8deb98bd7db1c78468fa86649e7c941736de175b6869481040c8fc444f09499bd0d10ffbd44b7aab9aa1bea52168f5c0071b6c7094d05fbb7ee170e676b40c611aeef58ba4e7afd9a7ff859374d5d06afa1d5447be97e0b164106173d7cc984d9944693d2118466ce53088ad1891d367301f5e8acf022418443c5958202a1caaeb6e66adc1131bc92c4f4149a511e9ffdd3b3cab032b56654af2e98973440153a3015ff74dc355a5190ec1507667725c8da8f2 +SHAKE-256: 582be104657ef9626697e3c4b0bd7121ef9bf6fbbcf8d530078a8cc215095b6340d91a4201c938536c6864648380a0d35d1ccaf6824ba630d69816b6495baed2f53ebc5c5ab060d29d0bcc1fb357c0e4e05cc14ee8ef79702f731ff3c4f7ce99483136cb3364c75e5773210607c406a50ed179cda0251db5a61c414977e8f0641d683891712c15f39c4c019b87b6c9d1ba4e639d0fce2c7fe01561cfd9733484d95d4ad81ad55ef1ede87ae4aa787c9ecef4faa94d95f57a66285aef7a3a73b147d7c7dee2eda9cde286c276b514b4321fab0f13bc0ee0305864a39228071ac7ad64e34f21183dc23ed02db09e21740a975ab1d5a322e1037f8df1ebcc288c2653254ff30d0fd19bbea66c35623f8b257e7893e4242b3c484d3b1549e5cbfaa76c79e513d268bea9bae4fc8b47722b5ba6aea21b49bfe89c7ffd76bcb8502e4403263424e1a5a0ab256d24d3d76b01c6daca5f3ee63ab2e09087a849b216282c05a20068981f917f507856dcad0f866aa730dc868f01fa7882dde5106e6df5c551db39dd5298b78061837755d2dd57bc9dbab55225e50c85922726664cd7ff09707445066f0bc1395ee8d7117f3ddfdb5a601875fa5979d05f61f7b4d2eda04ddbc1bd2c8713f8a4535cf58cccf1cfcd520360774ceea818d91dc2d306d32cdf40b9e48a1df19482241d8fbe749d340bd3baeb9689a8cb4bc8e342bf0ce71fc7 + +Input: a787860b2baf999c69ad656b5029960e26db921db866d0571adf893af4fc5f1b0c58472b6ad40ff846c5a3329165d358d5cdd6d7fd959495014849985fe04f1bdaa779c355d3eef94085bd6a5030cc53f642ff30c5486506cc98d31fc68d4fec981d210c9ce82c5ff4c6aa734dbb10c371b5f539ac0c761d8c69c15c706cbd4b46f0c665ddca0eef70ddf165d653194d45c97e +SHA3-256: 90c0e278302e94fa6037f32077e14d69f79989403d7aeba87cb26e72a56e1c0b +SHA3-512: a996ea958c6877000766c53fd9d32e5e3da2d4c586b67736a74c60b6740906c32d3720591ef01c6a9b569535c9bf80358138b4d4f60e7f430393a6332dc19334 +SHAKE-128: 9e41c99b513c9849aafac7492f91aa30c497d2fb78b983a7bb12aecaeedd4421479333523ea57a8f43f2b6a54fc9b3ef657fbc70514959aff9ca7cfe20c1b7fbcbbf1c9756f4ba29a249e80f7a0449c596ee6a32756c9e1993ae2faadfc8777d6548b62477fdca9a6a77db6921e1f96309afc0ba854eb7d0c98d94f94e0674d950b75ca831d6bec4d715221e76dda56fad5c560f5d9c184e4480fd536c93818ff26104b86b6c310ca40e7024222c667aa8746d284054562348bb162bed26a94bc1c492893b36a62bcdd48d7c233a6dc23c732e73a33048a7623ae06cd13b1374157b4ed844bbc99557122a6bec13b4a49e1240d97392f0bff67daf1663411c4dd459b0e77c211bbe2152482b963a11f76993af10c8948bb8d1c66e2073b270a7dea9479c640412e09133c5cbd5247063ca0a477427b92e92ac05407d812c8aa5d1f41e6d6ff5bc679c6095b73e4123d9926a16386b07b1da2001498b19306a0f26108b3ac901a0d272ead091da310b076127072296eb8fb80a814d01df92cce4464ea2e66c71a51382af584cfb3730d1b9148940763d6a3f5dbd0f1ac133bcacf8f2471f1bca4f433459a73c491ea98f79fd90a26e3aee2c58cef867ebf1720f8d18e05ff2bb34db6779eb43e6af9e375730fbf5466a6592d68a3d3df8b5f415d6d9806958407239fd69bfe5f5f41eaf65f2b7c220c54a12caea91beba1938bb +SHAKE-256: be5fb571eb55597da3427f9b72ed6929ca1fcc640ec6dcc6088376e5eed7a37e30c0daad625149ed922ddaf9ce1072ec9f04eb494bb324ea843834038ef3dad457773b04a5303445ff83ebe059a83e77a8acefbf1ab636c6d7ce78e0833414f9e3ce52c76d41dfa776d9c3e356f208012a7957247e399acac92e84efdfdab26f63fd3cc90156d45ea476a70111f45b4fd3011c637185d313d5889419a9c34734ae939c5deb3f644a960b52498c4a72b774d2f2d83d7ba1a05c16a2147a39bf23511fb6f1799855f0513d8bc4adcea5bb15448e6a36bc4bed64a6377f57a1590949fd8f0a7aaa7c355fd9df78736b7f800544a53af8a09f82e1cccd0b468f761fa8da081faa1fb4cd7901dc424ba80fda7585deaf6592e831aa7ec7bc91730bcd08f668023594f5bd4a2b7fc6a5014839f1eea5861118039bbe773d546c1342e5fee7d962c84cef8ca52ab434374370f4c10239a9c19423b993d4bc7a72d983c753677e79c0eec47be32c22d024e2ae0910b123cabc1af6afd75dde1d09b9d768d8d954d102bd5964177e4c285a0358dbbbf556bbdd084e4c603ce7a3748932ca46ba4c1f69afe3ad15f24587cc546eab9ab5a3b7dce241b4201b7446b0ccdb586671f9b0041853d55bb15fb03cdb512f35a128999cd20e89b0436d8b2787ba546483ccc37aca57ea977bc7549057265eae412049716d6868e6704c1d8975d99f + +Input: f5b906b363138f76039f9985be0bbc469ecb722dba87a62c4c354de2859a994dd838f67fbaedf0525c147b91e8761e593552f1bb5386c19096a11056f04c52aff42bd1a01d9d1ce3de36e33938f78b97b55fc2a08f0600e9768f67ea518e126312b780dea9b2285b8a7fc34d2c407847f8fa49301ce7877bebebf637841186cb57e576c1bd545eb41cfc4cc9b86cca71e6dcff38 +SHA3-256: 9b940581359d1c3dfff159f988db2babecccacbe743e1a0d262343ed8074cbbd +SHA3-512: 84cc0b6fa46dc0d6500a3be0e00c0cd8f75285fafb4518c0138df8f0cfcba8a96731b5f04563d461dccad95cc1bbe1c0343692e7e14b8e11812db2029c9f897c +SHAKE-128: a4ef49bc1019c2f8429d58c1bce29d396dcee8b51983ff507499696fb83015af7382768ce81922f73bee8013d028adc29b1a4517673318f3cc3eb25b4d3298e9875f9267ff4bcb1266a7fefa505059d0b1896e0faba538fd3293d1563b8eb291bcd2a2d19a30c4f9403f7df61e9b4f55a2edfc80eaf50e38243b95c02bf1d64c0b52c6d5f2a7cdf25bae5006e4ea1051b958eb4ee08fce6eb1c0a6dfac28a23da7e3d569dc8b84fd4f86964e7e5953eb245a2518c45fd5a1121457abd3a5b35ea727cfc652962ad38c6d5f1320fc05aea0a0cb7e1c9a52fddbe6c4349b698ae805649cac370cabe7b0b0e1224e42a32c8bfa15b7ce76280cbcdd6116928295ff6e7093917833d9d72562c3b142daaf361d258f2b88459a530bdb6c44b274a803af725a9c316088fabf4d3ccca681b48205fb78054c89927febd19e0581f230101f13c321ea14eadd08ded31ff0c2038085d29c7f0f79c24695c9c13b9dbea65a7b09baa97c694c0bf27c905b556282973e95364507f4a236ba354f435d8d20fff4d52fda21d37462119c70f85354a2f61606b142660d3d95ed71d03a530a1f3c9bfb19a228d7e5db517aa79385ea458bc41ddfeb80654ccf4aa2d580ff2100622740dfc81530e8c896c3b4c6e48b6463db386ee9b166304ff217482c73851142251b304d63419da3d7cdf7a063a576b411a272503592a24cafd185d3183e3f84 +SHAKE-256: 716899a6b4b0155eef7ed13045e16a9c08a024d0ef35415026af87c73053a5ca4238b68ca752f2b76b3c9228a2120d0cae8a5e0b7f2ec25aef0b6a1c46870206360aae3df1c8803da7df17a0fe968a617e141670bafaf41147c089c8a0625d028c5a5ff8eca6c3c96ef088a910a06147ea642388a108baa0e7e1cae341a105e5bad7b36d82e4a5dfcace410eb677edd947ee3161794d3e55688a66598cc7da1cea67aa653749e2030a8056e7c6eee08e35fb6bdf6a2e8056529d44ff7a27b5ca9d886a61c3c51f90be0133be773c47c6f8098197455f891e574825468002bce02636d3006ef759a44dcefa93b2c5050d96e8280f41c570a7e671bc812d2b967945244363c86c45f60421dcad2079c16e7bcc173f9fb1db85395a0e73bb38f2fc6d4b71c15782ac8a93b3f963bee1d0dcf4e7de26e0c2f1ae3d7c094381d9da942496e7272bc710285f7bb88003f07440d9b693b5edaa6791791241cfa8651c95a31838ba32fe97fad00a7096561151c621d31b05f5ff7d6f77e5bc3e2fe10dcd31f60412b832d7ebd37024e6cc50a55bb6a73c0c4016b3dd917cb04bd0cdf2e426d511311ba47dc6e1e624b43e28828dcfd52ccff40b9712f3f7289ef0d16be669053970b0112401d3fbf6e1744fd0a030e96849d5cf59c316dd7faabce40700869191c624a0b6214db054fc847d96899d542973c20ded7e804f0b082dd4a2de + +Input: 48f33080e7a0c33c3c0c8ec1690e7ae61e0a617e327f56a66fb90117913e2ca3cb23fc2eeb65ea4307df72c7dc0c53ad619a1fe6d47a6d1b26004080c46fc99ae167e4068474fe1ea7e0d5f342d7fc305fa1674f0f1c4e4822293bbf31c590004db13ac252fe59333f40fbe2c846bb729a42a452a271ebb0f7b728daef0ffe3d400077e117f1ef59596f23906d2ee0275ad971143a +SHA3-256: 49e997e97a28f2799a78c486f62dde3766d9fee27979c40372a6f31ba0d3a62f +SHA3-512: b3e97e1aec2743e3e9b614aab190bac86046d0fdbdd5821a6e113a847cf1e92baa618d87edf6fff3e8b50b3241f04e67bab7a71e626a05cb4d4b071fa67cee4a +SHAKE-128: 7fa3835b2309d1f9f7cbc689b786d4534c2c98daf606931f55b14fc9c6ce49e2ce8531617724a48b6e8f3ec622bb4c8574273a2197992a7d8268433e0108f00f4e185ae2dacb92fc6f77aef2446d67c1e00d94ea4899329e29f0d855af34f8801193db04c663e8a841cd441732931164476c2e24c4acaf288bc38cc1300d4b3f9277f88a83799f61bbdbacff500242c8cbf250e7264d242450d7d4fa1a3f590a6cc0b49a9e8c6eb7e4c0dca2014b04b5e45bd3a58655b25d746a222cecc8bde9a476e49d3c104cc6244f0695dbf0e9ee3e3d0537fbfe77052bfbfa6d67e396179b6b84be1e86edf8ea006ca2f2232ab75295aabf73c26cad47c42cdf3a191ba42c766bc158a7f937a8a72a11a1ca161076379236b640458fd745bda16177d546eb786d2b02fc983eabe3ecf485f30e2cdac07d804b9677aa5d9716e6482b5d53bced26ffb77e67c45ccb93288e05804c5bc27f4e5396a17536538f3df6bfb7993a0513129072b3ca2a49310fb5e0b2d3da3b391ba0458f46c9b0a8fb20bc06d8222e912cc8adc61260801422c07fd892de65ea70987704d66b01570f8e06dd9b5921622450c9fa45259c887a94d4baf31f5f33805541989a8bad38ec3551cf58fbcbdbd8c0bb2bbc645264f124feda1913dd35d319434c21c7a32bcab8b2de67ccfe825bbbe90979a991f41b5c1d305e944c2bb8860bdfcea731636c4772c683 +SHAKE-256: d3f7831590ff5c71cd88a0f60d414fa7f9e288acbf6eb9e6b8d8c09ff5d8c65bf211b49c22944007302b2af8513819dea9e88947ba9c5730821ecc0a1ae5d7e98e86f4b1848f766d203418a941a1f4d93db7601a5d840bbde04072d9799762a921b3bf6ebf21e5cdec7aab3210062375795c252ea0530dc5fb21b44ed0a7915930592dad84ffdb3419a6eb9c82cf7482c1abbc415bb932d66667384ff37e2836e766fd0ad8bb12860c8cfbbbcc144c746257058de6b86e2f44e92b79c434ee037d55a5600d432632102596c5bc34d3aa23510cdd7f6f4eafac50ff00e5fa6d890512159c9f3c5bfd654ce3c2ba2805b5078ecb3514e594d8ec04ea4010eb2a7f9fac8033246f4ef0eef8ae9cb68b151f8a4452b168a08378244131fe65948989504b175ef37e5b7a18bf56ee731da001970686f71ca2fa40e4cee78073bc192a2de02d789f4e97bf45fb4966f7f2de6e6de3adc61a708c6dfb0bc2aec974047088933af77fda400d709135b550e74b1913d3ed232ee1409208033dba7a383d8d90bae1278f9e965f8175a179c4fbae606ed3c869989989bbc6fec554bbbb9b45c4e68d2cbd13a01ff14d6d4aafeaa9bd78a1363886a53be408f6efdc6cc54d820354eb2d193bedd9778f9ccbce112824ed0c35c9003081651925a5541f8d6868fba65518aafa3f1ca2f0202f28c444fae0ab1e497b0287601a3cf40170211d61 + +Input: 247fe03400387c9c3909237cf28ce2ecbd0f83443c45fd09a3702884a823e69a4be63406a974d7c20609e7d89a92a41e1edc9240d643d5188446bf42ff24f2776c8eb4c1110049d12a50ddab7deec9bc155c2ef1b5127f2a786eb7be727bb73f24e4cc538fb463f0850f9650606fadc202b8ade8f2f06aade4e1c0eb2ff8b9f37f50074c7f1f3d76ebb03c37e75e73bb952f1982643e +SHA3-256: fc7d39a32c55e27680f05dd430f456a618152afc83f71ba1718efb8dfa3cb6ba +SHA3-512: 50d37fd99da73abc79b09c8307994a645a36ff220e5c65437546d368ad4fb645ffb0321c46eb7b6f231a743ffa9fd1473ace4c979219bc0aaa1509fec5698d1a +SHAKE-128: 91507e989e6becca4af0ad1828084424b8aaaedaf2a2fe5626b21cdc56422df1d3903f857afeb9dd04b87eb24c057eda91c70cfc48e63b42b5c4535b5e81b23e69326a0ad3495f501a4c5581ec7eed6b64ff3b6782255f6baa1508c8993b273f0d67229e67b9d2ff6960613ba2d14ad1abff090c0237bfad2e19453ff4f1fefe419abe56e68093eb7c5a89f468e8dbf398301791e8282a89cf7bdab7c908e5dacb00785eb47a6d1780c246645c64b3e91a424815240473e2632b6c8f76408670093d506df210406cc30d9d32902cacd0ed5f2b98cbbad43df9e0a64052586cad0745f450b0b450396215ac34ce12eec2e49f8da26f5de850a91e913cc1bd3f9e3fc3af5fe884edd13d5c3689e37393f1a49ace6238a9993ff229c16d809f6526f9085f9950219dbab322fc86ad7cadaf7e799c29cbfb0c1d05f734553cb0082c3fa13d03a176e0e29365d98aa3a8f52dc1e5e51cb93588baf6436c99a68e3be995c0c3db573131d369f9133c45e1208d5c9930b2e1226c27f06e9fe949f660c0688cdc40c8cc5ae31f0cc73a789f3b445a8bc4dd51dbdca532f14002d82d42f51a2aa10006322dbbc1a20e380a47b5a378119d06ac39cde78006ca178363bf6bacd9b14ee07fd73c9b2b0ee8c67c8fb48a8c0f036efa69bba0d042bd6f7a54f1694a50a5c6dfcace66b9ea33f99955cf1c0bb8202d682a83a636591aaea4b7f4 +SHAKE-256: 9ec781e87ca22957775f553c8d506f7dce73ff58b8ffb983ed2d77da511303c77d3c30b333388dd224146ee6d7d0b0e4131cd163c5be4c261867dab7d9cb5947c8ebaf8c988a83558027ddcbbbde3f25b25bd7556de8d3ffadbd486806b4a38869bda6cee1dc6792addbdf3d1440650b2dd67dae8aa103ac0def296e6639bd32786921aa484701ad7278dce57a585894b768a63870911d90851f281bf8dbcd161aa17b496df28fc92bd930376403a2a87657bc81de35eb454daf5c788290464af783e8fb771cfd401026b9a4819667570b3069fc72ff3e261eac2b7371fedf0711985c194f8d3ce41869de9678b3a8ea32f34ddd3f3c5a1a3710a4b8624b2e773076c5a31dfc671df1fac10d5b79ed382af460cd0ec6df03a7aa3596e94e10a68881a8e7fdda720c5638af4d921f302d129ac3b607a8e4f9e1647deb8433f6404aa7ede0462bcfeb1974f01c7966541e602a91987dd8e0f88b6fe5e05b4fc2206b665f51e9d6618d51cdd2061fe98e8d9061b5882708fce29e323148fa2c8cb24512f5a7ae504a9ded4df5d53419f96b8bceb070f8c8dec0be547f716b3061b4f798001e95fbd8b4dfa93dfedd911ebe5a709e226bf1c361cda9076fb87f75b5eac39a4ff1d2da41a400d7450a01b2ab3a8b74e59338ca23ed0232a732c2d505340da6c98a17dac1238388e871590911e14b24a3cc733bffa167d0dfbd7f2ec5 + +Input: a42ce79f9061418d9d982fbae68275f7417303a9620bdc51b880f4eb317857816d0140b2368b44ee6a3c3c6e91c5f2dd74dfb0a2726e13db6ddfaf302a146d75dc0f80721fff2b18a2968e2c29c0284437867971464173c7e52d5d8276d45de965475a18a6d52fb21ee19684bc8e853bd3d31d8de7a7b1dfc59912685c039c9be94a0686be363f683827a673367996ed3026d0dc44c0d8 +SHA3-256: 832c07f71e0f306f230d52ea3cbf23785ac3eb5a3c386333c2e80dd262b7f6b5 +SHA3-512: 95026f63a483169bf87f78dfcf86c16d0478c07f647c78f7174a747a4648c9832627d372412f6cc132274e5fc84b43eed0e4dc20e904e43cbc0bfb1b40f66d7e +SHAKE-128: 09d8d39dd0f6a7793849bec520d9cf26e1c646b6d731582edfbf5536165d1465c7e0188284a1d61e39351c97bf1d1a10944f972d8365bcd553cbf77a2b6021b1942d4c778ccb1e607404093508211b050f0314c2af9316e762f42d1b01c0d39ea96f9115d5d9099004b43aea243b73fadc264ebb782c8bb1f1bfd81382b11ace026284ff9a9e411e2b2328fbdead95a5b8e06c57148c658261250eb4c0a2a2c0a725512b7eb81788cea6ad55bf9d183804603570d684f33c4a5f8ca47bd251c2d7c6bece14f254e75a41e500d948544ca8e162f62783c8252351c6dfcecb2a10fd5638afa64f050a450cb16baea345942bf48dd8d3d767b27adfd7a368199594c8e704217dd9b785e4c6d86e94bce4480b76f43a5a5c33849b453810b902f887227be7c2c369b2734a388c9f4964203fa28a896b998cd591623bcd2cf56fd947eafc7559877de0549890ad80bdac11b40ce99b0455c761339223f99b7688d997d5e8b9615c0b1b939a9984e87880438f0933d8b069d898f678da0e57f405a1cab27c6e4b3376d1a76b4f38b8d7e51a48692b48deaf7261669b4be4e04fd2e1b817569ec9115aa77eb5078c138f47eb1607a5891a19a45fd495c0df3772e2f8e28a3fd64ce76df2535670cb402c0a809d2d3b1160a10192a1fad610b82ed3d0593372e044c779f6a724208013c6aa8f274099ac2dbbb3d7276e8b4c7536dcbd9c +SHAKE-256: 0c3b5d478174301a17f80e6199af3302fb7fbdcf9bb98119b732a1f15dad35de3996a280148c62675573df8033291b372d3f4eebcdac776d650b993ec947527be91a8705952e85acbd14ea5632c28371a73f4e357873f0690c57229e51af4ba8cb7a1812fadbcda00c6cfce01701d50f939a6a6179635a49be0256d97cc3d3d628acb8538df67138f478ba7b5af8571fd467dc221a371c6eb4e70c68410d6d66344a43ab7e95cd301926a5a9eb9e7a66a6efd9b7b415815fc7db4493f5048646c4b84c88fc0da21e6f95a25cbdb652cec045cc85063989f658404100624b04109aa94282e01e0b11f777d95757514c1bfd79d98d08cdb80b87326850bcdef3cade9880dffd08513943c4ef09b9388e29f82c4e2a95d64ee143921e8c985423d2368e188c0a5b7a413fe9877cf9d3936605a911aaa5571c5d9b603d54070d7eeeeca7e2b67e182cae96f41482cf63ade802080a6280855eba2d93b5b72316d5976b5461905680dc1a9e53eb8e8c2b14c9239376bf3c5dd48ae9ca4a5ffb5142466261145acb175c14353151c034b3b185f267ccbb8534a3f839309d561a7bd49ebb213f7ecb5ad28e6592bc161e72f9d0be9b6d40f13046d3f28741d12480c6e95cf1fd1e561caa13180de30232506c0a8fb787b61361f409b24a39ce4e17360ae407a96c3bdfd1fa00d1001c19dad187c9cd47bf5ef08dc5cd7ee5575f247857 + +Input: e62b5cfaeaea9c668eccb72b1bbf32a0bbd4c4c4606e1b9dd9917ebf57487716e0dda9cbbf88f961a32c4fa8df3634748ae00853a9645ccdb9a614d9cef20042d55afd848726867a361ad285703733f7bd491d140d1b1d865aa285656f8a71ce5d6a7b1830126dc7fb806396b5e23854ab78587e34238f550537b15c077d0923a3028f47900b662fee92813ea4b5819c7c927ee6d58c3189 +SHA3-256: 6d2ac2302e83cddadfe560c936ef24434ba76828b68c16deda3ba5a26ff4a002 +SHA3-512: d19f4dc21bebfe50d0558345795165a73a543babca5c20b9edd1c5fcffc22ee08866679e42e8efe7af902a02289e012c3e0b043e42fdde0a96feddc80c5befb4 +SHAKE-128: ec6730ea185da580acb15f5505f5b26c66c350f98570107d6c05162145f46f82918c2c58b5c71018d21f7bf561e2845d52ee2710f56d7f3d795088fb3b49eb8d7ef71dbe3a01b1bdec3470e544a35a385840c9d99ccc1942051432500d0a256d48b1f30a314cc5b460b5e6b27c34fc9cdb9740f723c15f7db38a2a88e49d2cb8146e80ae8451d56754260bdce5e46c22bd3f12cf584b6cd1a3298b29f88725a262daab75c0e955db3281a28d2da54bc70796a302828afe737193c155866020475681186f688529203a7aea245f5c7861b724c936e1c98760a913fd1abf07ce66e63964213b4594fee49516eb69d36ffdf01f6f7a7c2012624e254d525fbd06d329d9a3c1cd5dd03a3cb371c5bdc9c60bb9294069c1bd344966204fd38da660aa2eb33176d7743463a3c184b0bb219bbc8fefb1b2656d6fb4e699c425624aa2911cf210a021439f192ee988e863e334bd6a1403b5de35a4bb8615d08467db00a22e048be4d2c26d736a2a11a065d53b27ecf1c6ad4267063442fdfc5af6c14bd112ecc677ce47fc44aab4fb27ef19de45877a18eae13189b81088536bf4220c24215b19dcf706a95706b96e036aa0cbcecc91378233fd483daf9ec66f23f9e6363fcf87249df7cb789859254ada1569d15015c3994966de8d59ec0d7d372c7b963699a4eb7c749cef4c8fb5512a710f30ac9bb9d577331bdd22eb3bbb33920802 +SHAKE-256: e8f4799b265bbcc50d08a465eb2092d7577437ddfdca62531d65c78b464cda8c77d9a87e3425a94edd5145964ffedb150d82cc5ce559c517bb999cef0afc704d15d43f322f92e79ab9acae741aee93d59f2869b0c2336312288473e91ab419a2ba4f3165f6120e0b293399e0c7eeda25c4fb27c5a871a7e08cb6f91e9d2ff4d2795427237db3a43b881bed35ec50d2db66c6927fc7939f75fd64c7edd56fa09c378c5929ef6e3555e280ce19e93f0477af7c16e4bb616ff2f58d2baddb532555c732cf2be1585b95d3633c7b979bfba7f2cef7892eb06d97e483236d283cc37486dde7a52eef103bf9a4206681f0472fae73081d355cb021f4dc40a6a368a6a75a2209dd810665dc08c333fcf04992b8caba046e249957f57dc75289d1e52c772c05ddc1553033e11121572caec891ad564110392c77382ff10ae7a33192973eab86c4b47d0de9eea9d1a74ad281683841a68bde477aad68b7018c290f10d98fa8958d0750ee557b76ce9d45cbd410af17bdb62aafbffcf0070a05078c34cb704c894b04133c3b50e9265c2a395ffc233e383af4a164973d35cd090ac6679c0cae6092b4569e0d052b15c327ca6f2b567bc81cb0b2023a61043b23319c0beaf58d1e0da2c4e28fedceb340b98a724287e74cfdfb053d8bcfbb748dfb5c0b7349fc06e84ebf90ab635f4b168de59ae23ef3aa140bee37da3f5f12561078d5e2fb + +Input: 7a3894b2109c12af5f60769f9d2b2e44f271ecd14647316b845e750c6585d78834a8153f6d7ce6596a4b310119e780d472f704d270c383cbe6f44152df8d8191131ff2ea0a040d8e73f4668064eb979d1a5135ea3d308bff354afc6b8efcadb5c0d306c044379a7582289232928fd7797775d00db9eb85b4d863bd4450274c8b05af96ca709b1728e0f585e7ff3cd1c163913f98aec7cb2198 +SHA3-256: facd784c40a25a3fb5b1b51f6e0e5ef1906c63f8f4455abddadd79a42c77cacf +SHA3-512: 9c32b907e2fd6554a2278a750d5a3dec55ce7448c791ca161c1ab412f6bbc1fd297b5145d182de77bbb622223be0051ba3b1f8f071454514a7fe5855d85626e4 +SHAKE-128: a089e91575fa125985439592cbeffcd6ee5681359f830fbd998bfa0a3deeeefd0b35e4a35f664fc60231bf1760b04794fdd967369f83a1f04575ace493e65a1a4254b728856f2ebbb53cd134c79b0d0b193ccd963bfd770e26e607feb14c1d06737651222b5d09dec0f059d062f0f60b47d1f1474c70d1f0a41f04b2a2fb698977ffa1125f692e581f60d0ddf09fb269c3bad87bb84f20f2e19bd40c93d6655fdf3c46bee2ed29d77c7773d137950af90b7da9ac7b50cd7a2d9e0408a7cd9f936d8ad07f9774607bc9dc4898c0dff645ceb6b2a58646f6ba1dd038f8df03e852544e924d721767f2d105d21d8f2c6af7ad7b498a786a858b2439e23755626c8f8b32499b3c442e77776871f983d7d1f26bcb6b05e1890e63ac0f1b0e399d7e24a23431b05630a409e31a42a83ea7b0e285bb35344dc5aeb42ea4128172e8d20d882f5fc8c478f263dabd424dbfe3fcd32d9221c95cb26f3361d97ec7a55b61b28a84dbe47b2190c0561014fda0b11a09e0ccbb3074d266432788eb619111582546b44dcd1dd5c35e60d8cdb09cbfa752442850f9a1e67b622503b737eefdaabcb4819c18c82e8d0bb5e0db5921b8daf7277024b531eac3a70bbfd66ec952f463b34a9711d78d126573e0cedd622bd5151389474d7a4d0c1ea6b892ed317781b6e3a279453d17acd60e0fd79f7b3c1fbe84e3055d856309d33f15bce964334b2d +SHAKE-256: 3d0ce4523bff664820f88f906b165624869e89fc8a2c2d859cfdc1a4017aa8d90444d20fb87f27aeb2914c6e9ac8e52ac8c69bf62a6afd8159b6661387d108c6ed4a5b256e16b87cf19485741548eaa5cb14640c6b4841311e51f7e8297961168b0e628421e5f7c34955727c9404c18c37363f89ea8591251d3c979f7bd0bbc56f91bb469040faa4bcb53bd908a3aa80049c7d0ff7fd9ac9a696e2617c62d3d0178fbe28b4911590e889459fee6543f2f4f0768a116791e1bda3a4de6a843f0ae0acee745c118093d5023c8913fef5705c0f2a97294c48bbd6b430d879110881d751a446cdbf2eafff1a4b139e4af3fc592471d175ffda6275f96719feb371cef4c83fe24053b0e71a4b6ce075ade17d5206a1cc47a01a9b410da06bcf7a6f2a9fa16d9e19930da51efe6a303b12f3a645101484d1519f2c1b8b27b3ac81b8a5469aa72715e0bca0d298d037a72f8e0fcadf4c8e69ba692adeecfac90c0b2a04def3dad7e6c3a15857349849d2a0042969f6940b0088500928c3fb2840d8315eb57950f6ac56b2b855d83a8ea8cfb7f3e83603627c2e524b0bfb27d349586dae91cbd6b1d35a10471f3d55f5fcaa787de0d7795194744d6fbb95956fe6d137be982941b09e6226094066689f6cc59ba3912f0f90b2ec0f0f0deb77304d6e64e7f0689c46c19172343b9dbcc14c32647bfb8611a345029f080efa9c0274352225 + +Input: 2563dcaec9dc8d3904ffea5b2fbdabeba986d682649d187403ca9dd615debc638d65674367ce67186c5cbaf59ad6c60f2d86a66c4dab971c2726bc33c13678f50064a9b53eb6510f600f222f5fd9a25d3018f803df52ea8ba2a46e6ea2c17c8ecc4d01b6fc0ed4807c701386415c23025464715e0f60e4ae22a464e8487d9eee8b72e73fcc0b9d402244d5a3600501d56a9ac6c9ce4ab1c8c97f +SHA3-256: be795dcad8126ecd55561156ffc61946f204dd6e4ff393fbeb4146ada363f2ac +SHA3-512: 7ee78e3bd508831e983b9a5f77867083a1bfc2cbe7c393ce791cda27b705d69913332bca7faff5a10599f11e8c6a6bcd08e8456b37b6affe4382d73611d47b35 +SHAKE-128: 13773a6b9d48d6e4e5430555250d2c922b945d8d8ed2d7c79c63037b5aac43a4e8994a937e5abb3046d374d91f728a61c0bed7d7b3fa3b3d4a37e694b1f7c8a7887a88ec3c32dd25d61bdcf2b041644d39421e40ebbd67b98470417961fd18c096385fe2f3c743ab5279d61cc7e9336e32b6709835815cc5b7357abb465000e2c4fccb7db341bebce3e3aa78590385d05b017f1c280cf388789bc147c2ebb40492fae19e327baf1495ec9f61de4a18166671cde605b7c0dcd505bccc679e0531970adb446ca0f8d2dd9b954101b0c7b2aeb584c8073e8de7f33c54adb2ba1b5906500543baa9e6e433813b74eddf0a579035da0f1cbddfb820b5a44eb98a65a727949f84d27db29f39c5254584d88ce767214424b89dcc654de869dbab1f7b00a1a4540594475078c857f7c640bc9a6933ee0fecf232604e6e0a4e73cc0e2ea84b891a11b715aed48f685fc62e794e211e6b357684e070ec25645582fd510709d8a450f3f34a60bd83a18349ded0bb3a040041c6ec6bcdf4b79738da38e85d6f5502136272aa4c68b2dab8b814fe6598a2f2ed7169ad5ce91588a60cfe392fbe347878f2d7cb0b614f6af31ff59d42a3002021fb91df8c8b12f94bbd529fe9870b8a6db42332122f94a14c777c50dd247070476f81e6482d3ac17fcda0226b81fd6858dc2d1d88f72977134533f8b3125add87631e2321ae49d73e4115aa273f +SHAKE-256: 197721df9ae3c5c7d634171e876b89f252af6762cdeebedcb86a632a9fb8c684fd5927a48510f52c779ad3befc42c5d2c1337c7314e3102bc677a9f1f696845774d4790060f1fbb1feff3c0999056274ee1de70cde86a252265367e5e7aec28b58354610d31d6417254620413067d60a60f927ab176463210a8475760bd0e24e0a8360ca12edcb3be4ee2786c51026f2b97ca8aba13ad8299b1ad3a91658b619426ec3b9c64dcfc1c4c429885d274e32f4cdfb544e2c5ae80a1381c59b57fd2a38734db3a10bf2f1c26d857fa0440ddd6c98d71155662c51bf48cc0db943f60878b206bd0db334129dfe4c39b808bf9087fc74869ad22946cbaeb6be9a471a67464ae5f893d3023c0e8854ce0683a3920b5196fc72ad8a8b801f7c984d42ea6a44ffc29e8090d978e051fda030e0d584d4e4dd9b020ecbc67cfebf0568c3aa450fa160b3741709ccc687e3662bee8c7c4298843bfa6ec20b8b7f95707c3815ae23cfc661db287f204e15faf93c3b0c4fa083ba9f52cfd9a38e2a7fd6fa7cf14d17aaa5962b9d47119ee3426cf05e3a675000cdae24d44efb599c048db238381a4973b9f0f5312cac73df673e3f271fd470d8f68f599e61cc4bde7b272415772043e6548855c1c27c40972a6a339259d3f000dad2081b1be702cbbc441c14f2a9a7177cdff288e2faabbd13ebecc3c94881835b1dd751fbecd2acac910fbc662c + +Input: b6f0a0e84b48212cdb93c601ed0a9c095d72760cd3fd219a8670434869f50851ecf1893ce6f26c88de2393175f32bf1adf97cca55370bfad357e40226c5aa694928fd812a6a4afe5732171f037586e75b380d9c1126d9c89ae644179e802db2c8d7b02c9e4c0eda1b9304ce615f410bb57835d458e18e987e2c25076ba708d8f7d9fc881a5082eb30dcb24335f592d094b23eecbf1f539f0d0c28c +SHA3-256: 5911b99b1d2043a881b097cf71dd1bef9bf3dc83ccdb7fa9a1cc9a43581edb5c +SHA3-512: 82b33e1e8ae66a51fee64c7f7ba7cb5a374b389f5144c59887d60e0df3c848c3686b1a880d5540b61cec51570bc5992856e99a42beb5e46d38787158acca6c1d +SHAKE-128: 677ffbc2228fae92542d15fa5291dcb4d101fb66d6b21398cf92ae902bdbb17a351f45802974c85710c37d8407e25cf0f1a4a99d67eeb097cc98426d016bf4702d7b5dfb8a9a36bc3b05d54a3df7aba54909f88fd6b00ea2ce9859e4f2b570b82f067f6c7e1fa16e9345c41b615647b6184f62207f0949110279b003cee9444a820f2ab13ac47876440943058b8ed84c090d7d24d83e9a39b5ba89443b76d7584671628a1bfa72de0654eb0ae621bd7d4efe27b561dd26f77e298f840576bb7590ffb7cda87fc5ae1d73e5803dca18bd11cde7e63c5690bc867e33a983c71fb1d2cdab3e6fdc56c5db8806b4afa396aac11e2844aba5e3e2bbedd4dfd1ccdc55424192db776f54df48595626ab7e1fb1892a4b764d0fafb204ac01070d025968145f663a9b9cc7efc9ed1a381b8b19b9b6c39e94d73c6e3672dd63c1490c7c805cff8a9bcd7edea23e4699b2514b9407f31366044a213c34680e375f9071325ef77602498e4543abadefe82afcab8682e71ddd8b0f404ffb081764a8f44a9d05309b3fadbf63ba73d54ec6c8cbe70d7795be5bbbaa841b191d97d6d7e2f5d740af1345da4844c497218e2ea5470b5eecdeeb470ed66eb95f1477eaedbd4eeddd81fbebaa388f91a2454bdd5b121cf9a1b55a9f8585f490dc22e8d70280cdbf99f7a4b9152c5922cba6af93af5906bb1a417375f25caa9c710f635a8685eceabf +SHAKE-256: 7a36bfc26cb42040fc90910530fbd70327da2b8de96d379bcdbcfd2dcab1555441c25109302bdaf0952c5092b574323e5d905036119099841125ea3987a5962c6958b941fc5645e2ccce9870a7312a40a081335fcab33dc20e4dfc8ba0287069364857c22b8d87157c5357383e751f24207d289c0f993a4f062ce69008371ee1d3f32ef57a0ddffc47b1488afb6a35779be4e07d3ebf0e70daf5af367139a53fda153ee060299784b91c268d1afebb2203b9c990d48097c147740261d3f88a6f4e15ffab071fbd79b9ea0a914d8c55ef6af95858c621e1c0bea40574b1ad22ba1a323de794d15d1478d74ab833a427ed8f0e50fc35ecddace1291d197273692cd1e76dcaef9b0b80a16242dbf2af961e2ba2fab9eaa20dbb1e10b8cb12f168a3b325aebd3ff6fb5fd42b4afa32daabbb8ce4e29774898a1e91a525b753b58af8b39600ce2d734ca56b5c114e8aec72e978d6ed82a7930ac0230a2b22d23f1652ab9785b9b6f3a1988fad39d8e48720f6fedab49699d85e1fe0c1b2104b77fd685756fce1150baea7126526df284112e681f81904db283f22851f975c342d3b881902dc042752f8c3a42072e9ebbd82065dc83e7cb076ba667f628336fe67256fe1b3a492ef54bdac253bafc8fd79cf3de38e3fcf01c900056b79ee9273fd02e93b0905bd4032f150cc0ad96605a835102dedd557b703a131fce768845e2652dc + +Input: cc61a58994e771b0cdbe9a57cf0c6efe2a9ef9cda62d09a9759435b1aad540f544f2375601dda12644c89a7da988b62ab2f3f40b1f6bf5439b0213efcd81cbe8d26de3dca53956fad3816d419ff90e3f1fed477fbb5125589b84c94892750276b6dd19112936caf6fba99e3ded4488a2759b14ef1075ba8a113783254d934f2f945cf1fa0b57b8d354c9a83cb884449718914944711d2fa3f7a0df4e +SHA3-256: 95b9474239e8a2ad55ff1c63fc01d1bcb00e5caaab973cebc6b3ab754afbfa12 +SHA3-512: 6032a1622cebccdade3e3a1dc6af6e1fe12640484e14a19de6ea03a21e6d386023f9d7ac9265f276eae062bccdb135641849ab311e0ab0b8344b51e8eaf22d38 +SHAKE-128: 73c8dd4b073e5444b43bee40bc73dd712407b4f893630283178644d6887916d9369d8ab7d58ce0a106c6c7d9ce5e4ed042ad78450cb6fe19cf78cb1741546cee5095f40bd520d9d7b209a6a3ce1824db116f0fb87546a5ffbdba9695e948317b6b0c2ebec36ca01cb2665cb16da80373919761b7c84fd40476ba888f3f2a0ebe64275c761d2ff42e726d0ba1b884a936a11b24935f34dcd3c3183c22726409a6a671e4e735ed95ef6b1c22e53deddc5281410c4fd44a528e79b89e034e593590ca75713c490f2df26d5f1c26d1a9490d2f93fb087869eff5fae4aa755857bf5ecca6a40b964b6fdaf6b1b1c4c6f61be830bcd9a540bcafec08cf59bc099b7e8fe658e5239d62a34f3bb9a9c6a140a99f09fda5e7625ebe3017ebfc6746edaf024e27581c503f7f5428b1e48145db58c52c44566d7d61adbee783056bec7eb24a9fb6d48f2727f83ab424f690ad953625b2d3bb4431796c96706e1e799cb5e422c3a94a4796a92471b6637a2591b62dba79fa672a3678cf36894196a0d7679ce411bad614e634321c44bc613eca7311b551b3a7e20710daf9228fa7ca753fbeed873f8731c3f849ff4e9e873301ed9d1c7d61caf8f3bd61e592e244519b144259b1b51eee4082aa64417c3cfa78ed0d2673661574cbe40f611cb1c8c41d7b38204a5564c7d527c09c9c932b31970048610ec0a25a9778b1d0efeee6050f2d2a8e +SHAKE-256: 08385409ba4686e09b70739881a247fd3327bc9839fba89fc735f08ff201ea5a4c3e315945d6302a1ac2e444bcdb2447ce2c3c77716a76ec1f3dcf7abf1274ec9d6d7764c067a466f1d07604767f1f8004dd7bf403b82933e18596ebd96bd494a5072c4273088d46dff31a88d70650bdf013876771e7ab9c2725edad57d6ade43189217c1902fe41ef42baf1ca880d36da7d25e3da7b16c1c9af72b2452fbe74b2649209ffd3ee734f1ffcec027079cae8fc9eb5cce3683a5a5071a2ecc76abbfc5b1e1261542dce007f6f98bd11838fce9e60317949f6a277d6b49867da1159d5e0067fca3aa9c209e48466852ec83a8ba042d81558dbe8913cfb0badf3becaf7694aef9eeb7baec2127d533ca04ae51a8a7d4b3fce5081897ee1ce2a4db0ae11f4915026db2708b8c8d93c8fbcc7c66ef1a89bad7e14534f01a66a0f5e3bf32e508ab57b4c2d817b1549dfba49eb311a1ea89af6f5efd85747461a72f0d57f723e0bf8561ad07a69cfff674dd28a0a781146dd2fde450308dcc0688dfad3f905f757edcc879d4354f4666e8a89d3afd857c4b7724f023e82c056beaf2b91eea0ac11eb10fa82a6708148bc4f1dd5c528e92fc087e9cbfd13260956048b053908ad16a31835f81e456054a88109ca3c01e0d6fe863b2958d0ba5c4fb1078135eabe0dbd7fd36dc8d5dc594eced50c757f1cfc8c5e7051c586a886af755ba107 + +Input: e9ab089ec94a9031078225e0cb5b0bcd6210212c164cd1a8828fba919c57454b8b5194bfbc919d92f986d9cacf335e81b2c94f53919ba2e07bc1e409ce472acb6255b17c4595d2543fc88cff7e6dce778ec821a9d7c03c493d8df88a2b1f857018422cb42f437fd8e4b56dd8ce5dd051fae21a50169f560edcfbdb353ab6e5a76ef4336488a4e455884b63ac717a8d5a923d119d8f7cb72c5b02a947c7 +SHA3-256: ba7ecbf0baf1ae6d66446512b122fda0f7390f8464515a8fa94a162737c8f512 +SHA3-512: 1d76714b2c5d53a10023adf248733f3ccda9c9ace16ec633f21e834275c6bc8146304d874b2d1a4fe2cc3bd816d5cd7e838ac32c3a6bb220e717b5cd7c8135ed +SHAKE-128: 4a10ef9999d8a4f149d63db1a4fdca6f7825214cae1567e4c9b9db2d9891499ccb4affbd76553746c9c7acd507b2a61f22c3c4e8558205ea8f090cc6bd96136e5f306e7c8730389c1c3c2576fb508625c0132a0ecbb3a8fb17286e8b4f993790b25c96769481b3758aa581921540462c45689305fc3937c5955d88283f8cc856610837f8190061daf69407d34c9370b840584c669961d4b1b1000ec0e1a19c72cd7d956703f43181fd79f52a01cbbe9ac9c00ab4d96dee77865aff2eed26b17443cd26f3e5d4bdc73d1d21dde905663da923e5b378b48b0e78552d96dc76e726b5510fa067d80ee45f4bf666a7026a032a96bded1745032847a63eb5f6a6010f3033185afb514b282bcfdeb328af735820ec6554aaf3220d6713c5a1012e0b0be5e5f28e88d4a8aac6402a9c1ce9019639137dff42c43f37f7478e014c7edf8aee9f57d08e4add5c990826b866bd38a93d615b85cf982f7ab9043cf7af5a115ead4ce3aded10373dedc8b3f5bd5abf0ef3c029ecea9092abd521ed17ef47ec43c7df389e381ff80d06a3521679be60bdfd65da288b629a32498cf65327655e1386700c61db566fc9ca31660bad598240b04c0086a897949372f36e4d4a962fda0325c2bdcb85389a5e09ed83e56f7016d35f825812c233f680be2a025214b76a51a58e0117bb9e1d2eec599587dc8a393a3738bf62f130c276ffd8968394b904 +SHAKE-256: 300cb8a792161c14dbc080c38137a257c355be9b87206b19cd77c3f3d0135e2e30049b23920bb7525869cec8d9789d909bf3c7707325a885bb00931c5d97b47a28ddcb0614ac6d616db79b4a41c38bb1b5d3562baf9154c42d21961f5fcc174a1a0d3b0b148fb5634772b45df564c8608fdd4c4b6cfae4a2f65b543f2e3332663986ac147b5ee7bb8526bf795605f02a2a3eadcfbf19bd2e7711ec7947a1213b567279d821abfe0a730d1b8ee50bc2262c7b84a6c9ccfba901ea80f002c7542096c6efcc3bdbfb94f7bf35b10e77599c05582e4ca1aeb25f2097eca5989dd235bcb7374412aa3d7d72a7ba47eab1daea8d6fa6de5f201572f8575e8cdac34868a8d39f8ea4d8cefa4cf42d46112feac6ad59624db355433018a9776df91a1bef841d74b3c4672d524d6cd5751b780a3a43ec02e5ca8f610fa41500c7f02dbb597a542a5109de728854c06a9d0c969d47ed75f9c3f370d4fd507e0632d32da16158279557e36ef03e71df430205db6d9f90b2b1d30455b10d390da559b087e0e230d53086143fdba0d894fb42119eb567363578ad8a3191ec97c2b343cbde2a371abd50a2d1d7ed26f5166d0e0fb649711fadad192ed3df06be0919dd12f54c1c370b3cd6e85fa8338fc16dd37160137ca75a5d94f1afe6618f69149f127864a783f3d19c5753176b8c39465b054f48ca4cdff8ce7fedd63d2a68c7d970759182 + +Input: 7e4bb35b8328ebfe88865646060dd1317744f433481c713f0ecfb545f59ed289686c08fd72bbeb05657be92eed9daa5e3722a84cc70d1f76d6eb8d72312de8d226e82ec1b3c70f274a42d48431cd8c250256f27e8a996a4ef55b9c0bff8b743e007ff7113d01e467912c105fd797d871d34ced922ac744ceac5c0368157346c34e2348366815e6e07b7c363010ceae303e4cf731359ef9414bff1274fa23 +SHA3-256: 182d71a067aafd086f57a60067f6a44461ba53237a629cc3f933c261f3c7d6c6 +SHA3-512: 91aeefc4a9c2021a324680c763caac179f71c5beb7bd4d64a885e4858e30ed1647a727563423084ab16cb00cd820eebe1f91fd17c58db901dcf62ed1379ef2ca +SHAKE-128: 73767c89b554764516ae5c69551a8eb988e1d09ccc078eb20c24f964bdf6aa508a7b99e63b83a3fdd6eb688175659395b61c2a3097a30d0b1dcdfb028d80c22a06a6e0796878d83616c1272399811c335e38bb1df0033cdba3971c8bd72d49d1edcdcbede24ca79dea9dd76ca26e755e8c43e4bf4c55467c2ab3c47ac590130b988bc866d2591297a052d759037b4c144addf27582bf69fc66c03e5b42385b3f8b789b6797b268e4e1ca0ee57c7d2c4f89ab8209d27dd04c0b536a699c17c9778cadeea33cc5c16293ed80b655b480b868dc049c9337412730725826124c619ca6f073e64071b9234e5a5685a87b202ace64e946c61e570cb2a72d6f7432fc5d849a316d537b9426a11488f80c87735ddfb71fda0e4966070b9e05a2a75399efdc572aff98ddef686642c7511544d79057b43773230aa22982aafa90a95d3bc06932f1dc39469480c4d9e8339b78fde08800e448d2573d6767b833b58cb43155659978a724bd511f61931ffd33d5f938259fc84467ac15758f07c76a3ba046f3e5f67f539bd322943572d69547ca77f77272bc6e6c21debed2810cd404603e1148b2c7583bcd1d2096648cc278e5142feb72c8514a915a4ee5c90c9e386049ec0b13b2b076f99d3f98a8498ecd4ac0187d3f2d3b5d7f0bb95a65ec7dfab84e3785edce8eb17fed84224cf17f5985a48992c543fdec4b5801ce6cda6dd3db47af +SHAKE-256: 6bf110f1a992782fe40bb45c884c97592cace7ce0bbb4eca05cc8ab9151f22f8bbc2e40046b39ce4cd85c17a8dd7b4dca39938ae5071e2708d4ac4a3c2f3f8443fe07a17801f7e763ee059b587b994fb7e6086f2fac4254c576d732d14fa191135370af6d46a8d024ebab2e596e8e2500f0c455b4975a08364e6f1108c35c9208f948cd169d713027c3dafeafa3f8d9c85ef4a2e1b656f6decce48ddb1b84bdb90f3c7cc7747ca15b2da26eaec6ba66a12fbcf129f405fa3e1b8ebae0e44c36bcffe7d316452fdace06f2bf7f56578d06a7fe09c163ef94692ecb61b0f2d74a7d7c6522df5768c423595c97ff91545e84b9b87c81ca8b0127135cf7afe3482c078bc0ec5dcae15e2184aba00e06abddc41c15bab15e2a0d7a12c53a6b472d53f9d8325a9e8f489bc9883cacb3195c5587ca4b3f1139108d0686c6b1552bd328ce352f2d39d244b2c8a84508692419be682895c6bc4962d956dd7b512aceb5212c4f4509a2bfac6ccef094ecb8dee50bff1ea609f21a25fc2163768af3e5e061435d376ff120e408a9471265548259fa102a4bfa0cf544b74a399b972a069732ef69053e8e8d5818b077d136e5be9c5b615b23319a9b033d5d810b225b8c7788a2a6dceb7410daf71dfdd76b0f870363315e11898d994a797b472993cc9660658aa48a0dc3e8aaa2b11f51a1495c4b26d11bf85a1bcf1757fca2bf0fe71293662 + +Input: d1fe4c78f1f7dc376abf4845629fc9905e6f5428b92d689392c81a292dec6c98c3d1bf86b5466c7df2131dc98bef5e80dc3ebd1819da22a7f1f3bf3abea76472907162383866879f0d2cd918bbe3755439118e093750a8d8d3ccef925445c443f96065600a3142a8ed7c568bbd48f0b2805882aa0e19c5a261c7daead4c5eb907ddde1a4f2286f7d0f76c5969e4246372e13cf65f0a29d5b3c136bc30d2132 +SHA3-256: ab562ffd46c2727f91a75f91d7a8a4c0b3e5754a721f9e6002c1eae51079da08 +SHA3-512: 2f42ebb2ac54ad9290e3e4b559add7336119e30bf30c31e6a588abb31f92f80caef6e2c49b2df1bb9b47668fec09a55aca69564986699b30fa201bfd8b7162a2 +SHAKE-128: 85ee6e19087561f67df9bc810835e6dcfb116551fcbbf2e9792208830b8200813019a68be93a16e9066fd8c36f012ab406fa82ed956d419d68b5252c8bd26cd5e87217accdd573671d47025f6bb1c580f94a5c68d39ed11d05cc85a224124c840d23d42fc941a950b3e6db9d543efb9aecce47660735b40d4dfca037752445af7e979d0d8ea89779ca68a7535e817dab03d90fdbaf058adcddc62971898c60d723b5121ddf3da39d3d1bcf73018dd8d677a7c4a98ed60f73fa14e21e5078ecb2f36e7bd1b1c140c096e194997a5d03473f9afb6cd9e87eee5feab1088a71fe809eb303feb7004e437ac67ae0b0b4b31e2eec7230caf474906972537fa05193028eb957639d04a745684a404c172a0bc7868628a07169ff12417473b7a07bc71c7618ee12494287955ce4382833ead9e1d50ee15fb30b0b91d816299f6e65d74acd6c5f01efe7934dcab624926c2d53981e5a82dd22b69bc2bb72f8aa41ed9890072178642d2fa1d84c3a7a58d15accc9de8b5732bcfa65bac170bde985fd076698976bd3ce1ecfef8a03c4f81ad2611dbe3d70f75ae928ce61c670c76f9d22c809eeb0a98f3973a98c4e39edebfa0a756c8c01a82d0c9744f5f7ff1e723cec17e63721f45d83c6b06f7afb22e38c421ec2d4d3b5dda280f5d06ebf8e548e817ced6d3d35c6402ae13caf276f63bae87614be1799533f6c30b1d1e17fcb88a7c9 +SHAKE-256: 2d4d2ea5593cb0bcc7726a7928036036920b031b14359fd15390d27fb4ce5d8ed59d28d0710044cb2a8c25e2b491170dad1d31a362a6abe79b253859ddb9fecd000e3242ce29e11df34e730bc487be6fededfb9701f643d933d7057f46e0f9abcb9ad1409bac576cb417e2dd6ff5a8204d3daae317ee82f42c79cab4083a1b27e6d03b5007134dc9b9e961e0aee97f45d29ecb94ecb7a1a5540005d7a744284713301084c2ec13909b3a4a0718811797bb47bdb42c90ac0c8d21a5653d7dd882894be34e81c66f372814cf4b94f1d8a7742107f74450f82bcdb531d4e8bcee06715e1055cec7356d0c07cc6abc1747a9d60fc1553c9ae7d7698eb53a1d4cd3b2995f4990f8c514db87d6b6571dca7d9d7a3b0483fbd4b9578e353ab333e9cf11ae9008b48979187d4d5ab642d0073efe84bbd8fa29df402bf1ffc00d662cbae14de7d2891ed4d77725cae74367a763fccaf8099a7ee97b6a559583c35d1fa2ed6f0f1989a83fe356dc3c33d1b5f64bc75369ab5f2a24653ce928b0f783bdbc19d31305b702af2282da3d2e8a4adac2affa5932e23b927ab85d81190e4efe7dce69e1796f161f1bf9566cd19750349fab0261627d1a5cd98cee62425640d4d8141c05eee7f913b3adf280581053b4e6afbad678c44bb21532afe4b9609032542c2c0ce4187502ec1121c2564ee7f286ff96620f5c8f7a358933827002583a54ed + +Input: e87af3414bbcd9f741692901c14dff358a3a27a14ead780291816a287ef93f597153c2d26bbf19ed0de9a81627e33b2b2b2337565a38da60eaf580c54bb0e05961cccba98042bf1c6b6477e7aa799b8bc49efaf6cbbc98bb5f02eccff7a1736aca4079076fd49f1291cdf3e5a8536bf8489cac8f1d44a663cf72a923d276ee5579ff86e2f9d59ca59fc6c42c792a54e11584d1f176f605394f93953c82167ef0 +SHA3-256: 24008ffdd3b5d2a93e226b145b865f6a5ecd9b6e528ab23f7e75da13984691dd +SHA3-512: a0d70ca46c115396fba0e10ce55e58472ab813d65561216d7a51d2144d8f318c2cc4102bd36b71f1570f455bf821c332b898846809a5ed0f98c25f490bb9f806 +SHAKE-128: c93ffecadc392eeaae2130067523719ef75bcce8a57c4d45c3b54c8ad1bf8cb0ee8c5a7374ea7d9b25101fb508c3a4b1ec061df7aa357168b94fa1b888f74eee46e06c157c50b4cbcbc0531f15b22b893d733b0d4d755cf4a08d9bcebc8a1246c7b1d5ba6833de9d641bcfaf009a5660849021bf02aa1560aa46e5ae35ea7dff61aae6124d8e7acb5f7b79c67990a9e4f6cb7ea047d9fb0d58442f8e8b84009d853cc3a7f1ffd9173d56ca74f844fec1e3fe90b105389445b3e9e734dcae38306d6fa82c1302bed06a9d9e9c94adb4d759164d74de1e3baa5732ea7c090b273b1fd2347797f092e7801b35758882e9235fea5cbaade88200ef9d3ae839e8ec989d5ee2acdf68d996543000446c15816cea5ccd2330c7ee617009e2cd6807e2257d4f15d09dee07e6dc1ac2cc0ea941d22c0e9ea4d3450e76bacc08031dcce4454894afa20400d69f7713d23b416abbbc90c2f07e923055f62f5712fb69fe255b13f2b53b2494eeb5313618e53c1be10afb6401587e764c402f1962ac3886c3c44b023dd88f1671840f5598b1a13356b5848bc59efc00d59090cf83f769a5cde297a91e548c1111c9696ae2632f7da9a086505eb760d85d242128ef56ff49736b4a7caea885504d0c974931e1154500458000e1ba03112cb356957d311461018442dc5f90f9043c8474f03087ecb4636922db777bda1e56d772f6fe281f0eea21 +SHAKE-256: 7cf6634545790e7e64f15e3a156b62629433903968cf3754e99117fd5afae7413d2bb56bc1563f0f0c78643536d39135a9eefd23aa8206cdb9008c6d9ad169e0aed69fb060c449175ba706e17b1b4452c337ee8ffb2b078518804b01964af84aa1a5c812d7e885dcf935088d4ae2ebca1587f365e467fd5be8959f300aade8c4b1996aba14c90f773cb31253dc6691af6f0c1dde9427679b48eb22a8a26e8cbd3152a8bb8cf5b61d870bdb122ed8099fd18b3d5c710398ad83e52291a6b11c10a516a13fb11bd129aae4e6c89a1189a977556da02e563c012713a573480d6fea0caf7ebe8b6521a417ba4eda0b8578d0327320d1449f9defd6cba5fd299b47f2f3cf014a00fb592e955d556de45803d5a079e2ca719a9d0464bcf19322b5a8d598b2decab8b4f85b516ffae0eefe0b0011a4c0e6417b9c8d25fb5942106f8c7c8b9fd141fc89c8ac98c416448adb108c62339b408ac5ade418e3a58a5bc454567ec15ce9c2fe38e6cc6f1c3e81dc4dba38793312933a43a620e63a192a05275db146d06fdabadca5512c57da9c082437b1b57816956a938ff709e110753c7be6fcf937e06e60e9cf61eba19dfe9c80f96782fb73b1359c591c2e6647902c18c0eac2fe0cb43745c93ca7fef34c1316e1320bcac080557862fd438bda3e7034d04a2dfe67e7309fc53bcaf46d7330a25710c61bd17394ba8ce5aebcd4190e03fd + +Input: f2789fb6d04fcbbefb1db6ff38c0d198f440eec808740b4a73c1b733e0637804beb35128261e7cfe8543242ba4918ca7b6cb545c21adca84cd3115bb85ffdd0240e99f47cc1052a26698488a0868ab6952f91e9822a69d1db0b2221dbd1ab4b635c3fa08437efdf813440db82f0c47fe087ca87dc747586dc8067d89749929490856a760072c5fb0f386733a794e80caa391278851c8e2bdea574b8d47a143799a +SHA3-256: b095951d8d3e0a77243f696035f79db2cd0047cf9d7779b825f0bbfd223083e1 +SHA3-512: aa3de4e05b22c4d7306c072e664422cad7c866e0291abcf3537d62ee4d5f9825fb788a823da4429603507870527f66eb87005d57ca0feab0f66ca1025b2b5895 +SHAKE-128: 79c849d27a5c454d539960000335861cf49de47d45539523b84499b6eb121d727fa5b5d8bbbf69ba1d0256ad2b99650f64e0532fbf511c763f70ba7a064c5ca0a03cca6f5adbae24200ac3c2e5f224bc7319c5fa2d49e5c91c735202374bc0e113a41c81bfee4f098e192c496e81c19a7569a757a2b1d48b6bfbb7b13ac178ada062c04eb1e010370f8b45c0d9a3ec55a61e1823f56dae26e416483eb138f06265f0d44f7cad5e48da584be3eb76d9a17bd7218609b76eeb6efdc0ba1f3e88419c921bb84421d966cb0884750237b3a2cf4a8ff2b6aa5da6c57a39eadd6aa606c7e312e14a7ca4c6afd035d51c1edaee39f9b6d6bf1cf2a5cc0a5d944ba3ee92b4ab18dac7bcf11db689126e57efe254a9cd179b463b4b0b1e584ecda8ad000ad5eed56f57f9014282dfcd8074f7fe617383a1e87558c42456404315aa23266b0696a8714df811faaf8e7b623288a49bfcfccdeadb7cb0691ae1b7bf2cd7111786d1f52084cfbf4bc82fffa49f732b806866f8e3acb97c15fbeda83d6dc1dc76ef64900d336599e357cc8def03c419a8aeac087958dc2e0686f664133e758d6031b90a962ede5c6e1e70b3843bc6c7ac4c7eb781381fc01b2a5a720ab0653a0df3dfe995117a3b40b8dff547183a11bcc9c3787519093fc95ff0603cb75c8a808dbc016f516012bb651fb7dda970fff4c72bf7587f30402509c209dca0f89570 +SHAKE-256: c9c0ef0a1f642b0a05e969d1bc9310359b958e3cfd5f6bc6bec4dd662bfc4a6c4a2ca497811edf0d6c2bc138c7c2ae40e7d31ec5fe2c50987a284d3e537274ad77e0a02137bb3ba85c71f9e78bd6e5667fb4dfdf34cf4c3d4d32a5e40fb52b5fa896cfe7948f32381c70520f8580489a7698979148ef969ac0af5ef0cdd92ca4ca214de6df914fa4e9188d514d313fb0d9ceb225ee8b009e9ecc3712903004277b9b62e4e9fc2dd6d4b0803acdc70b27c4f03e8828d079620c1766d4d1093618eb77b3024de0f71f1991375ca91d035027cd2569b076633ad87efb3d102beb39ac18963da9dcce8c2b965edf35476cde6a452ecb07500481679c493814c0c3d93d6f35b70f51d87e7e0797a2adffd4cd81996d5606e48186a384a4f3956aa34991f41d1dfb6b8dc60bec8971e443ef2618ddb68f2132b9b3855ef012a91a60553d9d9d5f5cbc4d8b9810eb0b2d00985b8c292ac0819d5332084fb3f5bdd689aacfaf39f15f82e7caa3176973fce4ac4a8c716eed8cdaf016f259c47d7139ec9edf9aa8c6e7dce1d2fd958a72d6a2618b7a38bacf98155972490b57f994d391cfa03ba2270e43716deec550526a8513f442cde101762241add510cee2b5b5fcea5c745787e84fdfaefa2a4023ffc6894f049c555f1e01b5fac5ff0619b4430272eaaf453dd997794fdb98b1139e8f152334c816db3d051e50693bc6dbfc8f9fcd + +Input: 848d5fc2c126072764e27f29ebdf1fa244626ebf8022dd147f6c6721e34efc075ef71df27347e268aa84c270914f97d1d47b4f9d21dabda8ef6568fec89872ace42719c6e9e6dd84249944f4ee4141181f4f8e67eff691de0a983f151f3ad25e12ba9fa1a18ba1ce7271c30a87de57f251a02ffc1b38b68d6dd501f6b077589faaf5087d00b6072e19fe1ef47257eed2bf1c35acfa4e61cc09e0d9abbb169aacf15a +SHA3-256: 73c860e8fb1a9872dfbf999c14d26e432a921b99e4d3702ac9670397087679fb +SHA3-512: 0d723fea7923b4170183443c36afbf3a13668d01761ec72fd2560cefa38e314e68bef8d3d2607362aa3cd1066a05a541d09bdb53fe3157a1759542e3e0343783 +SHAKE-128: 016779419eb48c2d1403e167293d9905e99633d4a69066d6f89cde2888591e30cf8384f51ebdd3eb8d4d3bc059bbab6b8d2aa93bd9edc504855b8e7406afd22292e0ddb88507081f985d00b838ce6d9614505879b131c1d87862499306792a3ec46310da6360a51f2b48093f89847f74e9fd9d953c3cd4770f8295d40b4e66c5d92162ce733afddefdda4858a1717de83ba0b407d3172cdf1e2106dde5379459e67cc3803ec28e6923710e9bd23f6e17d64243ee3abf0cfbe4432f9895b019dee6043c57e89baecf588ce14b98b0745c2d675cdb9ab269e3d33a9e56f9dd932dcbd7d908f5a64e0ec6b808a57cc3c56e371f2cdbd3aaae7c229c89a9926d7b4cbada16832d6c7a6d4c9428deb93d569932683904e029cb578bb12415d0ca9d334a8edfa1245aa68709dc6a23110777bd660f32e92f0591ed7d94982fc3ecc4bb92a5392513571388d06b6641286faa5ae9b2684bbb713a133982c4ed792169707ca20e5869ea2a2ddea1a1b7f1ec761339e44cefaa0ac5adbe9e07ae669137d17a074ca810756f04a8cd8888359b313fb81f74fe9eab0b1d3594d5878baaed653d6630bb4c08e9900cd560f4b30b4a5dc14146b140a4e3b15861cfca47c661d1a1cda7e13c467c7873f782fa5bd5bac6a0172657af2d6cdde6cbde20bfa25d2071d10f2cedb808330cdd360d732791ea40eee037e51bc6bd9943112bb2c50a0c +SHAKE-256: 11a40cee10e05f702c723eace5c5daac6f67d579b2f7157dda16dd48074288e00f23b5ee7cbe1c0cd27e06aefe80c2515b5c0cef84505c32520358a2499c69aac428fb94d6df9d6395837b4f1bcadd5812fde5cc87436183568d75c078b1f350698e1bfd681f6273191353c52c32b00aab4e78fb7a82801776c064d53199f2e7b448ed203b8fd2612747de9c007acda3da1cea87da270caac3b3474932543e159e25235a4e509c7cdd666bfb0b7a04e9c9c17f0517a6b25d2f74eefbce53a9f606d80de7c4537b5ff5feba24f572f5e35de71e9cd5ee929c8f74b5022d3fffb4a2e422d37663e010dd2957c681dad0a7656739017583c556d40224a1a8daedc7299cbb8cac833c789ea3cb126aa82cf2cd8f033190edde93421050d74245883c2191b0b24dc6224e12a604a9093c493ca6918da37d3af94d6f0cb4e040d28739414b40f20ee7c3ef0c0436f6340ab3caa752c761cc6382bd6a13a8f891e7ddf39126215752650918cdf9f3bdf405739e5ada97b96113ee33d2dc2c6136e385adb2889050c4177651b3fc8b9bc3664bb64ea332a3c9d826977bb0c7421dffe2869c9417a217765b32e7b59ccd2207e2d199eeb77f56aec5a5f44f872b113c5f1e229746ab4be91f0cd7ac2ef9dcdd5a6bb5568197af6bc795e60c50dd13dea0f79b3db23038e01e2f72b3fb65f8fee68c8e60d7506b9d4cff4aed6f16a2f46cf7 + +Input: 83501fc9032d8acf59d621b715ce019d203f06c4f55201e594c22d038653146aca9bf0e4eb9a69a2c093c3ac7aba01a2bcd6ec9389da2ba4cb8b9ea0581e74e25c41b2391182ee5b0c567ce7f4820ad3dbbb99743038a3ab2568358007a97c3f68592806cdbd89d4b7073cb40f410fc14a8b3c20d3c00b8c694e068b80e20a963257c300010524cf4e66a8fcbf6aaf6ceb8039582db1c81843359afc5054f298a975a1 +SHA3-256: ec2619261c286a2e0d784c509bf1b11aebc1b50ce5fc1451382a747fb09e268e +SHA3-512: dc9bdd4cf49dac650945f0b1f3c5e087cf253ccc529580b60ef0cb201e48f8d589b04ff10b8095b4f700f0fb18920a0bdd7406babb42016d0582a31abb75bc9b +SHAKE-128: 7c18516ccf2ffe4136bdb96a2b436be2e4e8d3bafb7e39ed24b361ae7db71fc4a3b13a9427f6192a8238829d4065a4293923908917df53ab92b4034cfc147b82c3acce25218cd584bd1362c92acbc36e6af8b1cd9eebc4252172129f3cb9e49547889f9b3f4566b9618a448eb894b3d9fbf032fd6f9b99743586c49e59aae8d0d877d92d47b9bb26ed6c526226823e1b2f6d79dddea178cabde0219a20db2bfd60845726254ba2e519815bfe4ce7c11a9dbe363d140f000a95cf12ce843cc7fbdd23e6bc62596afe0301056e9567951f3a371f887f3a4cd38a208657e31a8db28ea309f914ee7398ccace75564a1b35b75befa9a5e74b1b758bfd290ac232b0b8ceac38b261bf1f7e8b42ff72268c83ed71d380b3af85e81afb3f28013997500c9183274d7926c28e543feeed77da4120e8fdac0adb439f9dd363ea3f103e606c35aa725d9df9ba3948b58eb0b3bd00719a360f5332e165926bd1c88505ef61819590a57834ae4c8f77d343bcb4506aa63db51629f890af8c792614f4d5aca3d92cb8d9afb8b7475f3e6170197ba5995d9e163cfd93a50a3c42d47fe10ee7c0e65e68b646885ec98fb92b578ee5801e06452cfc50ea77ea87d41bc50e7f6b44685caef9865912019df05d256c0704f206cc383807fe2c769d02a990bc79b624c0dd98057204b10b887715d04a1d17a36e8c741dad282c95102213da7488c2739 +SHAKE-256: 119754489bb54651c5c1c305570b30b09d9d220ebbb60047ecf0bada89613bade48d4cbe1f6973f9508725b7df1a59fe3766d74d9ebd4fcf355737624095520f5b4b1a39c7f382f69b21b621029a64f892d94c7bf305136d60e9b2af4c5d845a3d608c745411767c50f6716ef6927271f39b2985a26196761e6d342b38428edab738e4a32f9208d6388e19a187e7a2edc056308b64ee17a53d4e736af01bae3cbd81ef3d5cda4ad5de8b4e239e312079109c6b5d49a5871439e020eb449ba945455117ca6457d1959f142ecca866f8f9c383a523a33b8bc90210473cefb2d06a51fda1e564321f10faab67ca70fdfa461a7d631daf621b3a4a1244cc7767b4901ed814eb3ac9fa6f99183e404101e747e52a0d5634bb0dcdaf9edb04016f1c5afb6988fe7aa7d299c058a41cd2ed884fb4064707ca4d4089a725cff2a61abf7037bb65f392aa4d0c2ffff3945f2962959d8b0c6566915ccd19abfbaf78482ed8157c4a8c0ebe62030b7ee07161568a4fe52a4ef2bcbeb738df0133c410f01d24f0c1564926346d558ee47955470cee58dc78d1a8a4be207a0118aa91e911588ef2085e4ca90aab257c4990dffa7c743c13346cdad1703bf29305dae008c8be89878f91d93a849b34863ae19eb31bee1a8b26eaab31c26453a68ce2b243340589c29680e86436f19bf3ee47e85fdb367d4669b7a199eb0bd54d697555f949cacf + +Input: b9b9e7892cb52e97e0f283fd7220a0e42bf94d95935e90e9f7e0ba0ab1a709d8da33a4b5f0a72cb50178d14f617c1f106d9af0008032b8a4ad30344253382328427c47a5cb3f88db09a6dd7ab5d1f11c1ab3441db386ee4daf6dc09ba86d13d9f9f67711b2d8d77daf786bcf1e5f69945f1343b11d66564ed8cb1845adee2f2013b3c4f0c0d66667d5d60cb594aaf3cbc71f6fa6819f5bfe4dd43d77db108b12259ff10c +SHA3-256: b27c5a57455ce51df39940d85f76b5a662743c57441d8384848f3967952b2141 +SHA3-512: 2b68cae4a177e817d050679503179bf2674f8a70dacf0759d6316fcd421abfc019c367c6bdc69fab96593b2c6f4c6ae3be28a5695ddfbfa3bdf45c36b3208040 +SHAKE-128: 740cad4c5aad97ecc4c1638f93d11ba9826a18a21f1224632c04b3ca9bf4e70c6db5b2df228797e0f68e245592afcbdccf908525db502c3384569949da2220177825c6ee2d9df792fbf603d9a4695ed034d02d94d41579deed46c1f97b59cbbdfb84c8bb1b54f8f423da5fda83c20e5f9913f7cb2c027c3520f1fbc2c8a1bba9bfdff3126656cbab4c2cc852349e454266c392d29166a7a602c5f0a3bf34de0ef6e310172bfa36fcda31d2feb28a197090e2e38967110be72456f6f9030e8e1eedecebf8d9b157bf7809342b5cffa68277e3a236993340305fcbfb9cd06cddbfc078835daa30e7c3d9e3fe77ffa1266fd1ceee51e320aa5531cd4e7112700ca84651cb7f8e60080c2875077577838540783810d0fbf30d6b844c62db4cfa2d89ee776b1f91b9d363701c1d71b59afe7874ecc0a21bbeb4061af730daecb6a361c4eb759f7310fa5e8bcdec9ce569ed4d20a7626ca4de768727c938d00632982cdca044a2f835f7283fc8dd1f0880e30aa17d83a240e72b3e99edf5bae01fbcb44adfe189b5ad15d8dc543c40f1e3d10093d250d62387c289de93c2ae987aa3deeea142165134eaba8a7aae19feee51d9bf47757e23b31be47a41c1a33eb6da831557416d955cd76e64e9cd69ab8df45c34f0632da14ae921436a48a4307eb49d1f7e8ac20691a5f7a776745a7fdf397b3690d26a04f96e4b44b9371190d6e5ef +SHAKE-256: 40edeeb03068cc292c20588a1e046b0f8853ad28280b984832a8bae24c1103c980f994098964ec36ea15a3f4d87a819785b80c9f3d792cd6e2dee4db370837c7ca5928da817ffa546e1665f5ac1672594249c2243cd25110ed1dbfe7c16b6b81b746bb9f67297f08c6394c040badef763f5238486804efef080213f7b5bb739104f3a3efa75be7f378fc53954a4f31b125f3faf061bbed5e0d019dc01c4b82b5c77861ee021d81f2508533df4af9e5accfd29daba0231c2a7b76facd1b8aaea25f0dca2566f96b023a3bc810d6067c3b9b5a1fc60001af1c102f4c90f6850455df2029038e0f841b94f1cf78d8c4a589ac0d1d250f8ad8682dcbdf401e4e282f11e96d7f826704947e52f0aaba17ae73ec7fadd15764fa18cc888923ee5233fbe9dd8ec5e548839a093a5693d3375aa7977c2e71cadc6a31d3b967b1d57b0ed073181d7f72b23db161decd93e360193e372f95a2ecda55a4a76ad573d6ca7df7c912a1218ffb14523e44d131837c31aef09c45d0eff172f0c2d26ceb74e6a7607a0e1bcfb5e6cb8fec42d1496c7690f4872f98e7ab4f183cb278b1b4e76d2f9c05d046a452eb9116df276f383a6903f41ec8723bc54ed051391defd2a693dfd82db2e0c9786e9654e3a06f9dd5a0054b6b6a5f9e9828ae8704224d7e62e8e88244c1dce41d5cd62f092b6accb858a57f3f362c57675531d8e9a6129378577b97 + +Input: b4aaaf6f9c39082760a3520a09d5095f3ac27212875907adaef193cc2165d5e9bd85d4e622577984fe563b63f225db6162cac5486eb228693530be75e454f52c6034b7b02a49a80eea1674ae5d7647bade2a32042dce560c8361daf26455de5106b332bf4c0e7c3b0b9749d5ae36920bffa1bd9bbc69f656f18b3337f2eb1c3b7a599dcd3aff6cbfe8d857b8a31f549d59930de178da85c3a62502ca8190638af946b9c33d +SHA3-256: 823738f36e3efa6f1d2a590d6dcb8903dc3a2dbc1716df61945404dde53d1d62 +SHA3-512: 1387e43d7c3a6913334f8a0c9ec8dc8395df3bc78e2031f1cc6421f05ce3321eea99f6b6b252c3581b1f539d7b63d01f4a6e34cdb77f735c099c5d4d3738a70f +SHAKE-128: 3f852b8a272a3a9cf80aa70ca6c979ac623ddff272f7a0d5f5dcdfc50993681d2f1a09c7e9af9e7736278fb49d6e8959a702b955397373f104ee423d4337d4e12a3ff8923be9fd5bd227d2e496a8ccfa9f737e787b795e3627088f5c918cda6dd8aafd31b731b8b5aef911e4c91f9538b426f62110913ae14284d8a83c4c3b8fd6e10976f5f63e2d585fdf2410e5f1c1b6ed3565002261652c3bc2a67082830bec3df9fd778898ecac252686eca2e4cd4d62204436b186397bd3a6fa874de73114f3c8576ec6aabf1617ecaf3d518283cf7706caccdcd90e0d1a2cc19e1cd36a2910af3f6f29a13a9b79e4122a584517690df370067f36138b47bf7816ef5140dee01c19ec085013867a502e6e0c538cb4dffb107f4ebe215cc5b69cb72fb57d3c21d3a5c2b32f9e80fcc41a0438874aca2364851bbb2078f16a4171dc74dcbd80855fda41544ccc5921c5d7f29b5cea11cc5c153485d3952fc39174f0ddb432970a1cd26b805054ed387a9421998c3662e16b30a75cc7fd4b942aa6379e7cf8edd5b193feedb6a213d7120643fe40bb118515de6c6949f901426f1c87b6aab524cd65bfab7ea95c06fe6b7ae7730226feefaa4eac8fcdc511b9ef2970eba8297d2e9bf1b5adfb2066580e3f2d171a76bfdadab2e1b43b8b2eb0db2743263adaefd3bc41661f3ab8df5db258a9b2f3a69373250e57e6e1377120af3438741425 +SHAKE-256: 457647b9eef14442838f4fa1ed79947cc5c2f4197a631f81b70bf51341d33f528fed1cb8524d29005b326e09b9e2caee29f2c459bfa283a316da7db6950796e154d6e1a6454c9eb3d0c8562a91dd29da5b0aa6fc0d71f844a85a55f4bee6194e33e796f6cdf1c43d05c9159c3fbad2f453fb4ad86e3c5f0ac39c48da7468d93a34ae7a36a2c9fc1178c987f34902fce8931a1142ee1a9b0b71eb28aa77f54f159073e207fd467d312c1bcc94881168f65a89e05590833842d44724bbb2cc2683c5775e976980b5ca887896590de7812554f4e3ec4dd392092ce214f411d1427516c94f835cfd68a6e8f8904dca04805b10eeab8c20746a9671c46f76b8c49bcc8df5b776b2531f7472b60cdabf6e70135d4a43c7ea8ad8649663b684c1f72b768562dd156cc2c4fed3084d4180588a65de8c5909b580220a11401ce3404798856cbb7aff796aa7ee62b5dab8aa367cbdbd0cb0edb8e08400d16e4f3ac8b683a317e58790af3417b89e8559fefe7d8d30f054c1119e9a0320562f8b8b4e619328b47a05753f613c35d2dd0772fba3bb98dc00a2065ad59c6c617c7e787571273920f457685abe5e2dd14a7ff712353b39b8f2dff1a9a67fedcd64ebcf12d72e12e2b3836e5256b4bba424cd7f754121a7cd5603dec1592eeffa9c4e60da3758b9a9863c2b2cc287b866fe94f936d1742a395b7323bf9058c197cf85e3a1d5b1f5 + +Input: 830386eb7a344f9fe631785f1d4d4608d3e93549633e95676a3b81a62f86fd1f4dafd97065094ca3cc721101c9ccf95656b9ba49ab3ae44f68649aa310e94c137197a7f7318c73e42b831855362fa32b47ef9bb97425ee31516292e8b81ade54937e359ec20ab4c5fd2962c1daf97c78c093050c1fc828b6e7c1791fad61d90d19f7d8a67c3942fec74de8323ff9f40088544109297d63edde884526450199cab2d440fe0dd4 +SHA3-256: 8a1fdee075f3d5e5b7847613b9ee7d527538308ed50cd8468c653e751902fe19 +SHA3-512: 03250f2a2ee20159ebc6be53e0d861f6eb3369efa5e416fed9cf04bef009e0f0b05c8d1833ec52e7439aa46de761529895fd055e46acafd19203d18a6f78d040 +SHAKE-128: fadd40e24b35e8be2af90aa7b41b68972912137aef1eda45d912aa3417f7fbe8d2b990656c8640e3c5b8dc435e86b6c3074218f32c8fd3dca13c4c738791f0989ecaaf7d37e3657bd7e7662c45037a7f088bc9cf5831cc2ac7b3594641a1cd4f3d7fd2dc1ae49aa0b321ffd76ec342352683c7dab46d752f7c9b308e519c19b2307a03f565701df47a4cf3eb8e32fe59dfdbe046b3b4e989996e1b47a2f6131ff4db301e31cd51d706dd6457ca8950cb69ff4038e6a369c82edf972466fe1346aa80a1f5f03fdbbde4e6c068da782c6ccd97f4ed5b3a089a2491746aa1b493e389b56442c2e0c0496b25c0536d346d69954d1dbf796069d06141f77b4be2bc78425a8c5fba4f814e8c36c0a439cd9e7fff0c55f9ae0ccb44e8f49665406f9101cd72d8afdf1fc7fed89ee0b983ebe6b6bb35040d072fff50b08e13cbaa501675480d847b69cb791e93c5222b3090615ceb66ff3dd169c2b1ce802e2be78adcb5e1aa8896ea3a6112c6b744d8596bed5b076e1065810e51037a4592c788c1fdf131cec6f3a6759686cce4d5d2a0b7f293fc042d4ab79cb498e1193a3dc90db2bc9e80be0bb9f314c06bebb3434da76bf57f98a0258e951d180b13bd69d78c59fc4c13a0f6ac820563cb65c15687941300c790e0a3f7515c368662f8fdc14aad64b20f0d92f15f9d2f6bf39832b3fa485196cda5fb8cda8d16723688af667f686b +SHAKE-256: 018c8ab358a7ba3f03c01042bdddd3a006c79a955044b605831a401bd5cc15cf43360b19b9160fc2dc539a61236c29a8af6d28ed6b1fd067b8fb1ca400ecc0e646d5bfef6ce67f7545400b9ed1ad3ab477f848d725404a77124a1a1df747810ab637508e7c7d02099e225fe9391a2da056700a920e819da75199f256ab27a21f8d10747657c302aa90f2bfba7db39840b79c9a95ed2927aa4e4fec2b671dd789ff432eb16e1b8020e6d19208ef559aa468ef47865b2233f9edb70fb29f2f2c84a436c92de3f9b216976b9ab797829531c39a55662b21bd31b95f4c9efbe383aef4bac096e36c38136f5d707d5288c37ca5760fdd3bde2088d9def233bef062794b4c383f0b93f995b61cbe9b0013f69bbbb0d06b5471f20585d98aac770a03cd47e83077b18fc92767d64100d8988aa9ce4186cb3e44e4bab4305a58c88be97667e7a67e671b9afe60edfd63712235a20c60c21d0455ca724c5c117771fbdaff071173b387a02726975d865dade539983a4ac9b791eac16c8de51ec53a3af5c319eccb2c6ebc2087578cee7605da9ef41a3d816a9acf859d7a822b0d3a2e6284e50aab45bea3158faf444d57eea33c9873dde12a5cc80d172d2414aa902c507ab22777b025af79ed410c54ea61a87b56e019116da8682accce6247d098e2e372ae73300c0edd14819df3201682bb898fba4e4dfc0cf4b6efca5370fa1dbc5531 + +Input: 8183466420f4a3d6dc3bc05dbf2bc0f54bc9c96a83e4d054d3549ca49d3c9f7f559d992b1f151d31d2ccf61cb279cbc1122b71df0880c4b07400bcbde5eb0448ca62079db6182709f2e44d5a7b927afa4909105c0eae0582fe14ea915218d8f2726f93cd1c288451483e4b074389806fd8f2d39c74ea00d77f8d73c91df00e1e27a40038d5e7423172ead9226f492cfde73cdf020a233df2268ea15c8960d19b95ff2bd7a9db25 +SHA3-256: e6588b31ea9e43f1c26c07924577018917c1709a9373c9ffab06c6db3e9ca6cf +SHA3-512: 4e0bc9f85b50426febf28034b22a42dac17e002c897f583ee5efcbd1a304fd825c7a202f26a5fca79f0303b0d11ee171ccac5e2e1a929e3da80c578291e60f5d +SHAKE-128: f93181a0b2741264db275e23c5ff9fce536e748dd483662399159d6bf56737014a3cca4e34fd44f328dbc3e0d7f8885e0cec26e70c3bf62c79b1f10da480ea03e4551f70f9a835c0ac46f32763d3cdc561963b5530662c3c6db007070f40284322738fcb4d1d15d9bb10079747a5e8fd6e4b90fbfec332faf25bd180cd91d5a0c339e80fd959931b7468a903dc9b4630e799c322b6c3edc9a755b7da28d3667efff0f971f243da5af81dc560d62c8480ff2a4e01c43f3c52e1379e8d7f68276ea5ea58a07266419b0d13fd43dd7185434eba711420d1e84253425a09b4ce31902a4e36d6044a1e539613ea3231754e491b516e6e7dc4603f2ec9255261f1014efc2414a7ad6007c05a5b245fed6a3bd1fc842230667a91a40a8e9a16b6b3d2d6096c6382f4d92080abedae2601c6bd1ee0541b4946b73d52ded19d74270abed03aa9dc7be910048cd9d5ab007e28877d6d506328ee9b2f389e29a31f21f2a1d44184ee3e3ccdfb4b0643845952218c41e3eb9c6e7534d82d014668fa14a4a9af3047da861327ca06e20328418719b67de3d8005b574a49977aa6284b8b36df5f74508c21b37d57616da181c0f434abf9310d92f94ab1f2096fecbb05fa86caffc766757838419d2fdffcdbd02c11e4ea70da9268a03048ad280d2a8904a8c61a6740ca6e4f779ec0a543a0ef042d88a9b9acc055e7fbcb1047034d818a4b521a +SHAKE-256: 41f7cb8f32b08edeff63cf18d16b67ca9af194067971fa7cb547c60bf1524c29d29e27cd5f90b6daf1bce08d46e0579bb10c5be737d199a3e08f3ff0b95fc337bf7d7de5b5aff097c90aebb7ec52b0e4acc48faab31a2f1f3221ed312ecefd557e09555dd6a4fa2ffe41925a087872977d3ca069d3be5af8d1779e89c340d07453844b9e3634e1cf8d9562c11fdca3217a56b31522bf5ec5125983373296220dca5efe9a112a690ddb5eaaf35724f8b44793ab1caa2731176000db1dbce57f1c3120707c137881ad6987267ddc18d6dde15b00bc6ee1771b67f8da82d789fced735df382bcba4e315e8b25d438ead60af99130e2f8cc70d189217723b2d99956f347a0339f43eba17addeaa48d603973ead2cf6a84ee01047d852eb54c3404330aa5f1e66c51685fa5654c480c7ff81361a7f1757736184b2211352451c01dd3c82afa8b9fa5b0903fee8d7bdc2c3c242823e93ec7dc6c5a46ded7f20cea10f50f309718622148cc4afe07be108d2375ce4d0b93cb7a6c802d11693d55c711a9ebeb18c77454de7fb321ede260f9fa9667ed8835e9d570b8961e724619247201a0072564eecd17d6947147a4207952874af051e649c3a9e81cdb21fafa93067c599cea9ae22cb4ddbaf7ec2566c771f081f1c46e1848e02d42649bced38b679d26ffeadefd270e374f56a011d2ee37424bc84c84f40d695be35713e24905d311 + +Input: aedd7d4df058d05a0867fda243970257c72f928cce917389cf957a993c28782b9df48f28a1dd8b8785d070112235499894dd5dc6b839bc0da9861a693d2086e829b4d6dafc10f6b5137aaef9ab98fe1cd6e4c6961533828462ec9fb5e33b0cfdc2b3f6f8c0ac0e4331a412222e0ece93cf6de718a42369240e9d4a54316eeb710014daa8dd2c20bdbf7c77a9a6b1f1256fa6267d165074284b3858f534fcc97d01a1e6e0e9fd9acc +SHA3-256: 487233319467b1b0e245d8b6eef7e3d9c5ea8c2df6acdd672753065dafbf348f +SHA3-512: bb40831416904fd1129acd036743bf930ac23b7e7901cbe1a484348d5b5c1fdf8b6ff9d4b8790e7ed1b9744958efbed650987180b54371447f33a48eaa8aa675 +SHAKE-128: 2fbaf54f36c514d2531c1e2dd265dec281698cb02db571cfe9bc090bdf7fef737332a9fde52a75a81071d584abe02c78e911291791167395298fabdfb16c1961a54aaa8546fe6dcc2968f44add402243e0253defd0cd051b2d2c2ffe4eb49f17ba274a7e5870536f30f9d929906edb0de8fe6cd746fc32415ce46db6379dbf2fa190becee381fe278201515ccd0468482d0b5d919fa1fec0f74a9ca0e8b06662fef2605e652afe0cef70bf58900adb2a2459cfaf1a9732023ee4612a4f088b77d290f7307aabe3423bbbfae30ac4297cd72cb1a3ab580bf72f73b9aab1de234956d2d1bf2b86b497b361e410ef491166ee0f303a713ee79916bf2f048c9c101d7c109010b3506309b79dcca9ca7e91f4588c2455614a099da776dba61edb3bba76b74bfb5acd1a0adbf4763961aa8f4bd06b366dc39edb1db48f2206895aeafce9df2ce50f96b84047b5976922b692ac00604418634b1d7ec4ed55d2409539d1757ab391d1bc7dbb2253a35569f3fbb51daaf6c87d6c018543dc5911ba1370a6fd1bc6039b9e849d693006c34055320d9f44e5e63b9143c0dc088cdaf15357dd6f98d5588c154ec3734484dd601b7d643329cc7bce2c498c74e02e53474d246037bad29040a33e313e02c40b4fa8e5f9ea6e3f5ebf6a4f463f27379bba2625c577c6ddc22873643d3ac5c693d96fe0777de4fd1054d8ecf845098f4097a54c52 +SHAKE-256: 49f6bbd89b7412a5681996ae7658bae49f658c561ead09b1119abee5fa1d63e445b9a47cc3b28d419d313f6c24b3a765e3376059d5020cc1669ec6e1f4b5a1a3881e4adf2fe28b79d0cd93aecdf7749f2850d7aa3a584e638e58d185a17324671f7d0b3f175ddb3f9b5ad96f01099c1c05939b8fa91609fec435a533b548e96bb10a9fc4864cdafb67c8019d292f8499c3fd456b80f7ec3f2658cc704c21232f2718a6ca0cdf39caf6771b104e40fbe2f5798ac9c3e19db0747069ea5d867b9374eb7106ac88f29b5f3a2db824a2c2637a85dbbcb7c97f649a3629d27e832a64fc601a68082882575ddf396c49901d58d098108380a8bf6810e5f1ec5e02036f6338416016fce4fb9d65e518c5cf44062b3fcce9d72d7463be36203097b8ab9d12ddd467e98890c51afc3086936869b4c1b7281e13986cf8a4899070dfe4ca7ce5725a3aabd753608d46f5cc3c106a0b1c2338f62b9ebbeececadc262d7e20681b7d1be367c067fd38930f7e7c87d680641c8361f4973096e9841f07e7c7ff2609ac0dcdb47eef34fe4e8f0c182ad70d8ac3d9a1cb9445c7892c422ce2dd444decb0cf95ba3cd44bca9e02d7168550e5c5a991b492d9c83d49d1fd8e33ebe9d341dc42fa0e76edc5529acde710a99ac0484b8803dd0d9bf80d1bfba7be3fb23ff4be8fb8fe7d8ab602bb46406fdd436209b3f2ed4faa594e8f4e18c1bd7041ed + +Input: 4c4b43f7e229b8d72a178ae73a741c66e891f78316adb994ffec7421724efc2b66e50261233374c6e48e895c7c2f4ee6bbcb62eb489d9e3fda40aeab8d12f50338c24ca5179fbd367db6411add8f7136c7e7d5c194100dfd1f5763b4df3db5d4482f82e5e80b7f23fb9d3c2c686ad60254b0a55f1a533fd5a6c6b810e28c8f807abc079b1ee45c759ac8345fe42c89afe8b0114bf4e77b8fe35d25e7b40c5d91d123e5d85a6ba247bb +SHA3-256: 0e78a059156dce37cc7a95babdd1e151df37452bb5e57cab0fe4d47d9a5309f6 +SHA3-512: 5447bc790e138847f01f89d8ca25a0b21927b9ed409798f7bf7b9b4ad33790b41d4bc55c588f780159ecd6791d2677ad4669ad9de00decebcedd89a108a19ea9 +SHAKE-128: acb70a1c594f0faa4366b8c31d4d3228b0249bfa5282cc9fac98dc59b7c030df4de5b7b236f85cbef6beb2059975aa678e3ae2c24a2f2c4f0825a8c0997eae244278a3ad118a8b677e4ffca33fb1530ef5ce7fd4d2e1f7a49e45afc18e393c5769a6a45d9b6eb2a8d773ede48ca9b893c8e30e65cd3febe6a8229fb696d94aeaa81a0574a4ac1a1f54de7e12753694f5355a129d150b4a5967b7c33c5ccc39063fdbadd19aa08faa851f6401529e09d0d94ee811dd14b3635bf3bc84e21f498c6881f6beea96135b474094f4606ee977bff1a6522b2411f7713a33bcf5ff9fa119b8d0ed12efc764c453fcc0d03cc76450f8c1454be07e169f75895bba90bea5b075231d665df6d23f51930e0b123fc403ee0db707ff6b35ecbfb3d7bbccadd6159810e4f134491014d7bad4e33d476e364caa899c950b08a774e3cbcb7414c0b1b9112152357e435f58d068014fb0c7a79ca2d1817dbfcfa2874244af3865e96d561de3da655c23e9603c425eeee2ae2f2b859711ad1da17f33cb24a08454c6b9614c1d522130838ea18c9038190855fabd1f772691ef3d8a86b9cf00c30fb70ff95261b729247dbb17fae214068dbf4ed27038361c025dba667d82d973dd356dc23d27f8fdbe176a6d2462b24b7c6be47fec15fb970691499e704fb50eddce149e8eb8fe5a0f440989c376893186c8fe1dc265ae1f0a23eb45eff8366f7535 +SHAKE-256: de216774cb6335fe4ff892842f8922adaf89e84fd018fcf6cd86575005775a88230093d33df85465f68821b253165ec47610efee13d6f42377412de0c53ab1a648488b1e78bc6db4cc3fa0d722c01e7f96870a5197ac43a3ad7f8a76c41b86b36c1c644f1e55be8584cce096cdce8cc0e13113fa9a58cae588ef85d6de320c00d1bb87f204ade26fed7e9243ba457dedbcc7b8d80b9c9ce089565bd7f6126ff108281b3cfa2e35f3bf19adcbf1184c3c684f54f5eeb23eb4ee64277e0c8515ac1dc28e5840510e6b1bb980bd61bc2b225e8a3c969a332f6a8504709b3c7ec0da7e132f32fe2bb46e3d40a16c77ca94e1d342db530dd0b6c4d9db47ea52d3317d85abc155183ed9f757a7073674d71904807f2392d7c87e0bb7c99ac089b447a8f8e89d9e4641441fe5d4338b90b2968cbecff082f92f777c4ad3d9ba600614730a8c8f8b676864c5359ed09b874b1c5fbfe8854d86995da1c494314209bf9333726d39374a7c3007a41fbe463d1906dbb0025690b7a752b99c8ad2e878cd508158bb082f22f85ab29a2e1542343a1db7a478906e11728e268d53401482464ce10f0b1470c5c577aed70803612abd93e0b3f09b0b44d8e40ffc4b9495cfcadc05ddcc5e456483b59ffc4c19232b500f1ba2722bc6511797fc508d5b79ad862701c6e3112349574da0c85ddc2192e9ec63dfeab75b5e153cae1eacaea2a4e5e46d + +Input: e8f183c01f3623c1923c8c5e8a74948ab2e867e3aaff927e27311377f0fae7483a6a944d5feafd1e2dae3f510c1294bae6f09f21f80d5210cad26e0847e11aa6767e1f1f05cdb3af3376f7f2e1cb43a70000dc4cc5096cbbafdae46d2aa9a3acb973a8cc26811a93b07d83796a3e8629e376e5ddf21e007a1f70567b5970188ebf4e8a0253361998cfb5815ab675c4f82e50997d17035c85f55ea10501e6831fc6854c444527d02fc26a +SHA3-256: d88106076b2895c1af4bc69da719172151439a03d104dc9d333994919f072fe0 +SHA3-512: 54d3e50231730eaaecc10ee186eda740b582c4c35315a5f2cf4a41e7e95c96850ae162b84b7c7dbd2dc00bd723884e0d9a287b3a81762ddd5dbd9f13385a7ef8 +SHAKE-128: 38be45bf3060ea5c38e5d7ed1733606b3af9398c360fd8b81bd78e98a13cfb4cec7c4fcf103c852a1285edc61c3177ed24558951d2d9e0c2c6f6f8736e4635cc2d989c62fdc7b4d0e94ab92c9958f9c93384f82d90adb5c0177e8d9e3bac8ab0371ff311204f04a78c87e25a9c81288174880683e7dbb30a90193a55253fe98c100ce3cbdc1e4aac38fca40320d0c3a22552c7cc79c40d92e8ff0b9f3596961bcc8794a4b8e2e85c325debb4813effba6748f68fa572298a5eb16498d358898b184f9f83a55cbe48b20cc9316e0afff58e3e9a5f73ab20e550b99393be931f5efc61ff099e335784bac9ea3170f43f9f336cd21fb419e5546f37a7cccd3bfab8bdf03d2c22062c9bb0dd528bfa6d34708e558f6e46c7e6c29e2ae366841a9b85a64ffccd7276b564203c3fc490ee9fcbc67dbc275e4bc764b90fd833fd80e8fc6d46c3bdcfbf1b00fff9ddeb61c3b85c614590800d995359491656e0f8b9dde5418f44ee9131ff0fe622608efdd5d56f3055b87c03a18ccb40a89022cff383a057d8537f126de0335fe326d29c510ac72e1b16fe8627fa3b9e2c83c7c1d96e10ad5a4183e5c3e6c56cc2959b59ded9fbaa1c0a840edfdc2ebc93ede5eb40e7abec36044c0707b13af59307309368a9ba936865b69110f3b52752ac7836db9e72ccef9da71473e127169bf8647d3f33b3c33c55465e2948aa2d3fced0878817b3 +SHAKE-256: 5a1c61aa8f02ead397be6f4add999c5f28804888427e7a71ff326ca6341d76ddb69e4753088feaa3781e109eecab2cd683e9449d71d32ea4a387ab1f761be7c8660d780252ea5d87d1c8a2d531a9a41d8b4f27451b2632d9a4d2ae28972fa436c51a3a430a825dd1c5f56179f31fb7f2d4e31aaf93252feaaa8948f6554408eb625d0dc85662c6a5d3bb1fe663263b3420bd787f5680c262d24fe21df845ec395601be00b4736ea5e40a4505f1683f70210718db8fab038a0a1f0764aadb5c16d842bc609c3ef4e9129389055a6064dc7ffa877dfc004b47b737cb60194ae9f362e76d78b22b2dc257d5603f905fe626f113520581bdfec3ac96c3fa9e739ddb6e0b8bc087b8c3e5d546779351e14d0145d65989512f23b59e7e62977639f946c9a97ae2d8008135860ddbd6fa1b94f73958666106aa73960ccdf5ee2998cd53de05870ac5eddce34d91e257eaae2b764404737f9a63fbd4796c32405986b8d234893d805646eeafe7dd20b99b3379d2e3dffbf22777a418013caea431d022f470ab7e5097b336fe98b7ad3c08e960403f21359fc37ddb4df95210b197125802b7075fa86138170ccfacb8de97603fe6575696c4842c9bad9252a449f7d5173ca60d297477da9b601d68ee864bc122675362043621198d6b818753c05ac8da433936f7ce3cd0cdeaa2450297ed464697bfa5d8734ee78a03ca813aa995f8dda1 + +Input: b5cab4ba5c48b493cff3d50cedd742411712669bf07b133954baffc52d5c24c88ed86814c381a0aae8bea807bca098da5168887ac9d08b278f6f9be9a27c66ba7d485412a61249c99c76cbffb876965df46993ccb4afb0a34e16e9131bf9003067524bedfa1a42ff1b86edb35d6e0c9a669c2e0c5d08da98750a798c5829c05b5dca67be375789e29d4da842044beecbe8eb5015f3c5b1d1a289a43079b4886c260032ddf012cce0d437c2 +SHA3-256: 5905df34c6e01596d1eba439061ba1732f6190cfd3c9c78b53cfa8f974c358e0 +SHA3-512: ae3d1fd93c3dfc5bbdc52a33ea6962ba9c22b2e4e65ed87055d53defe0069ca00d2ee420de827d9731230f0497bddf69b4dd419b5367e713827e179ef25fb88c +SHAKE-128: 0fd86ea32ccef48e530aa3e9af51f6c86671375ff1852e4f71af38c7eba874ef05834478a1426fb4cf87a3fb17dc16bd71cc84adb3a17adfb696433c328de22447c93f00cdea4aee2a80a0e441c3da531ad8277b40e8a07ee183fdd3237ccfa7b885bba6d93b85df5a25f1812bce8235ff5a6af0ea98dd5ee574a7da7813a32551a0438cd69b31cebfd3b5a357a8e817ec6c03f8048bbb450b607f6f423aff89424c62ddf0b615863b15f71e1c6d7dba058c4afe8f67ac6bcadfb0d4804c32e9a9d99b1d6900fc73ee87298dff88d5a59013888fded3d46a6e7e7dbf2207738642af13f6742d384d534b7ab31a04ae5983c80cd68d740745ae5a65fb7545bf57d30e62200b253d2d93282de12fc5540be5f51af99d40f36c77a0d85fb96d6c211e54799702af65a1b391f9c3dc3a9e17597b677ccc3d00ea19b481c1e990d923f440288813d21b5b99f9f646152345ba2b5514482d8ababf1b5b8ec05b4cc7fc0bbb14cbde9b702d84604f92ab195a41bb1e8010aa82a44f657cfdbd2f3d0025116635ea11c7738c4859aeea55edad84dd840cbe8f53e533503ec97a8eaa334cb738c26e62edeb2f9e4085a13a0c0378de984877c0c0e7957c0f301aa8ca1ef2ef5ac474fdfe523a64194dffd39cd99a68cb6a85d0a5374b8a84eca1e5c8009754cdebf81cd197019f9fbd78380931ddf1654820b585d18d827f506d66b7d466 +SHAKE-256: 66c1b1d6376717563dd22084d8b9f914e6775e4c34e34760c1c756f412e5dd664055d14390b8fee10c30ba1daa884563890d60b5625ba65e58f492096bf57e6b23180eb3f4f7f05e9cf517c39c1c8415671d8345892560ae7150cd11e4d987e69a2377c6394aecbcf351f0c3c3e58f049e80871e41f12cdbba1e54079aa30ce107c6049c7fafbeb19188f2fcd0fb8f3cbeaf13315372a2942383175bdb0c2c9b8d88154dca88596693e145d045201b1717dc713b290962da25d5f5cf803c6aaa7447a6bd8a4e2e55f3ca6fe9016fb05ec50ba5f80c7c7e9da67493f426d90771fbff118ad2a361c266ebb1435a6e5058c2bcae9dca8c3ef82d7055629b074b1b04cff78126bcaf2cc433e2a7ffca51832b18c14835e9f9b68109808f79fa9ac89af0b4bde25324f478c2e2b3544608504d860cefa373d2b63b0ea5eb337a2ee8af5a770c993e379aa5172a40f80f0a25777ab62222d1e08d1643fb7c3e768d95df19b32b4416c73e937103e9d78c5ffdc2b13490ab2b5bc944601436c9e35a95e34a5abccce7a2a93d434a458c8931809370aa7476e112c0d21c348d3f00a46a29aa47050baf080022e6a62963ee1e27e3b6c5e47194c360efd99ed1702b962d3bfa8f2b570f53fc30d2630b20b2b61f951033ea0940958401ee2051d3c98c78afe006de30bf303618bc457e95e8f11c459a3d8cccd9c903c6a7931a4a162e57 + +Input: 58e174ac05d115b8e660032175b78922ea3561748ac654914baa1a7e60fd34cd943b5da31e7aa8230a6d1fc91bc1f4af820705eef1e2b55a708c103ba70d000b3ced3b35e3ed5abf46aae2b1cafe4f860be5324f3231d2d2e8b2ee0b6d4aacecfbac9abae9c6eef8028e3ea339229e927a779460424e046b8f5d5d1343ea1b26e00b591766654587248ad1602492a0b09c882f14fccdf588a4787beb1a5b1df973b1ffedafbb58dea875fc60 +SHA3-256: b2d84cc786d713989c086844baf173df63ddaf9aa5c8c77953d907e945a260fa +SHA3-512: 87cae8a216e2be1b499dd25678777e57dd7271c924fb26df3167d0355f78bf58fde4da97d5a0d75e997fe84cd127dd4df3ea5aeb9093f90e0600ec47b5805c45 +SHAKE-128: 2a49aad1ea47e7b2cfff1f481ae652050d7b28a07f1339fcc01d27c31dd7087425bbdadeb5714d284b10a67e94b3af2bd3d27e4e50cae9f40ac1c40878e8287fd236acfcc1fe23d6c6517a2cb4a51a7a83c4501f3eb64346c0fe05930c17488e78a4453d4f32e41bf86e1bc5cdc44f08e64ad65d9efa8b23913aa97cb89f440cc9ddcb4f0be5c5baab3832ee45f2787bb1fe02f82cb7126bd77191033f2a51a033c2d5dbc5cef0271e4d4aee344826eada9af3f8dac18ed163efc3395cdbd5d32957df1822ea26e791044ccc9b03b8a5bca2c2ac1b439485cd9063b3bc51f590ee74b3842d80b9aebec0e6f29d5ed3f10addda8b2c2b3bae6281f77505c1941fbe8a964a080ab8f5f33b5d5d5c43b8becb0435a165480ae03b44c55d7876e1455955dab7643b3673356d404c33f2ca143c6cc95b97f6618f31ba3d32a71695507305fcc62d325e5048e8fa6bbeec1fd8ca8bf0a0c123d3fdcf326ebc48ef2855d1a93888a22bc0ce2cfcc93606e0b1b3c76962e22f598ab2879a3949fdf10cb458a915be42ede4b49d98d968512d54516b339d96dea2b26baca5d6fa23dd536bd0c7b90e62a1d85ceccd3fea8dd69a947b5c3264da6ebc8446d7b50f2c8a2a242bd42f1cc29be3ff679a71698b6623c09a90e43bb10ebb89b7530e45d95e6f54da6a9d4438d129d9d3d0416ad4c8f440d8a451a567c9bd6deafdc1b60068e7be +SHAKE-256: 85a7e209bbff0a77e310316b1a8ce7f46b821ae0c05980816cfc033e7a91f5b88d70b5f287f261f617ddf9b00c3500d7b643082e24cb0979b6c15ecb51f180123c22c28c41729b534f386b5ec7abb81754921eab9275182acd8dc758449d1b1ee2aa0760cae42e2dd2e8ebb2f05901292168a10f7ab9f343e968171213262b80f4119276e345336879c7921aebaec6e4b2242169157364395f834ed128b455aed203abb91582f179b00e5abea1bcbe0b69f0074fd36f15e2df15a433c3c10271cf32f12c8a85bac7f35a4016d280c1e224559e46a39fd7f42b13920ed24596e2b58f5fb7ea69779bab8a16a51a2ed54359c29ae6301407c5d05e8033f91cef989e1e964a7c86a5694e2cde01ef03182a5e8bace013210517dbd6e2ee734ef2fdd1eb1068e42f0ddc8e18212d6aad7ec41058b98dbbcca25c4852c846cbc7d8e17a140bd30f330f626d664d392b7754dcb328f7c5db4025387beaac9c24d3e912c5b3a9e664d6b54679b81ce296fce8b2f0f8f1ee84e0da350f5b634fb4f87d36bbd4eae62c096a623dddb8ba34cfb6d1754b6af40a2a6dbd957f7abb73325a0838fac0be9c3530626378f3a167cce054b4eebf84b443fa6997be567f45c1bdd86fe0184c5528225c970289ad12c7acc9d94891fcb8e155dfabddc9b2fe5172e364f175b5e838db337f63af139f6ededf128730fcec0a7ee2271ef98088e453da + +Input: c674c4c0a01ce902897948b940dd050fbcc1f6cc3e5ae9fed88caa89411c9ef89e6ed4afc2c63efaac6ff1b34b5df500ba9f369d87e4a15302467288ce11448ba202626e9fbf6d304f8b83a822d940173e73a806a5026c36f6e6c3d96484f10bd3786d88e28a41b9b1819093968a4e09110d55d6adf622ebefd1078bc92bcc39223a4d3f2935a226bf5db2d68bb318eb8bc0e91916695c0247eae09587424ffd99676cff05d0ccba8ee3748f00 +SHA3-256: eff718cb0f608d383ba22d44a591e57f66b486fa538167ac3df84bdc1327017e +SHA3-512: 5fda98fc2a87dba3b244cc6aae9d508f48642390578eede05fdbb4f6b051db033092bfacb92facb1efe56af660971f4653327e08cd7105adf16f2dd4a04b32a2 +SHAKE-128: 85cf5ba604b240cbf7ddc4a7ed25475b3bd9b0e635b0ad57120f9be14c7586d0d18b3b299fe7b153f2f9c52cac26f2674b990641a8583abc03ae6910c2bbf97de086f7fd6ef522700adc4d447cf7287dd4d74d312d769e9b48ce38b3948fce49957e28c7f6dc5c8cc5a2c7564c2550a25ebe70b76bbb377457d3c6e62531391f86216448153fa814210628e1cf1d59442cfc0ccab5ee5c56078e035c56fb1f6e33b71c412064680851e7b1b07bc4f50f1dfe50cb3665923a0cca226dd7bd286acdc4b2672260456651ac0e4eec5dd4c0b60d3975eae33ba13afecdbdc6561e1bdcbf5a3eb529971fa4cefc0692e4b36c94e31f256f097e544f41519b06581735f8cea09961b0210dd78c8a8611bdff3110ff97c30adff6d2d65058ce1b1d01e82158fa657ad5fff7d2596364ee60bd2f851df294eff5ac46e8c63d8166955c611d74b6ec2da727d389caaa31f1431d1b6db0dd793ba92389f123ede93d0e2aba26afe2cdabc172738e3912e73d40249e77876a281ac9ad0b46963a2feae931a03669e1ac4dadce917adb49290661d402bb53174d8d446a7dd9a62b8d1b632e88c8d7179f3b74decba2af7e17b7a7969c24147c6f763f93aa84a3804b108842d4736f27895d95a54b405cd6e008b3216cc97f7b87ee9b8e4dbf38ef5627294a3d3414d03070b3dbf9d2412bd40918fff3dad5771685160cb6140efe6d32b6edd2 +SHAKE-256: f2fb71fe9a5132674ea710cf40f7e3192cda6bbc3548a9c5136ca4789fd8e640f389e0f9105217f36a971526c2c00b71b8a8b019a6535427aec6831589da13ca264d71b48e4beb11b991409dea107bea517fe426720cbcc974fc8bb0eecbab87820d57a88d245b25690f2659b0b884e8285a3958c88c802a144af75ec06fcee31c54c415f8406d55b54f7d1bde5743814936a59a3cc51f318c876dc1d4b18b363779c58be71b2ee9b7138b42e05488369a286f6363c340d45d72c84af4849722acb992a262aeeb6afa965b31b481a6c4dae1bc49a4237132afd3568a1a130284ff5773e0b5424dc15bb12fafb9454102e0d48ee4310d09e204af705f3ee361dd93f5de5253d6d6438a5df45d2ae93be8eea8236ff22ea43e50eb1d06310e8e72fb5a8726ca2b3ef069edf4c4612037fd4edc4315ea1253fdaf830153fba34d55d1c89f0b7482ef7ebf72dc3da1bae5523c3f3151d2553292adbf9b22eb421992d152832f439476658dde2df2fad0af3eda103c4d6c2ac1ab3fd2b2498c6285a6a71a171aa46d84a92d0f51e94b12c620abdae702bd31bd05da8c4a6918c4d88b04cc4003770c415d0c29232fc8a0d03479f88940d911230ede1adbc6a4f44677bccfb4a0d7a2c6abebb97abd53619b02d9475ef7a7decc9730b16209eb73d50a5fb10d7a4d0515a72f3ec93de415e722ce4e30c3b47f6e152c5122374ee4406f + +Input: 82b9f0fbe4711d1846e60c5b3c1ec2f63c7b01177b48e520e16ef37072ae1164470f133b2814dd28eb52c0830aed25ce3f1b1531998ba8d8fcefe0b44adcc6495e0a95560869b6e39b4e733e5c80d794f22406f0e25f57f55cc14bd692949826f3fcac476a9e88ba047ff463e7d510baa3931df940a3cf0837c1f9e78ef37730c02a0ebe354b4a0a37d0936d0887b618282e826c6fff0977db37cafba12bea152dc86945fff2448fabe3b44c113f +SHA3-256: 0b661bbae63e82189d1529c9475ccb12d76fef0e827b8b9be6c5f83c73a99c14 +SHA3-512: 84315f3a5b75a11133828fc979eca14210adefa648c61efcfcf2ee7f139031987fb7091e50c9d0d480a016d26de95b825a3ae98a86b42e3f6e1316833e11541a +SHAKE-128: 52f8bd2add8fb7f5ef797da7b82232998b69adba3f9a8766959c3863d87084ddbc29681d1a544bcf90d686bef33203752146d3800b3cccd40e653317d0cacaf08f3a5778c95eb69d748ea5838577c14f13705f8a28957d57183e8f242da54fdbbb16c578f62a683dc51c342f2d654733781ad7acb56f57ead896b2be4599e706a0f3aca492ee90d143bb2dcb76fdd55989d1b536e54c8311fc2500747e824c9cb762af7f67e02a4ab83eb1757a77981d82146f0f4dc70ee45732a5f3debd776c4db983014df468a1efa8271c4a14309d6786fcdb6f7357d2bdd8c46c1c3dd89d645526761635435948b14fa783bb3479d5bdae5283e5318c4a970f0fa91782d49f7c028d0cdf5e21248c433b7e862c11452973f580b6357eda684e705392bf2a983a8072266c65340133e2585ed44241edd27e7abc0b8ab04cbbdff3ebaa403bbae95bf8ec303e46cdc6f03cbaaf45b7cd8816efc6976f8a5fc4a966fbdc26f5dea675ac16af50ed8d62b367744be87a3b4f9378db2e9f651d622cfcbc82f7733face16eb6f3b3ed53f76391d7c349813eadf05b6f484eb1357954980403b704f386adbcff5ed5f261d48f1395518cc0c7fb2a8b6ed19a8ef32834f83261ef8cb7b2113bf7cef1ebeb7909a364c1d4124fcf832344f52759fe32a6e802ab17177bc520362c25fe7a4ab85c4e7f4a8bc306ee8155ab49a888ecfce73efed1d890 +SHAKE-256: 9d32ae154bb184722863cd13d26da91faebc024d68563fbe1f5eb1d4af44cb12dd186fdeb1215e02fe1f432f3e152d0bae159b11703ade7595e350aeacbc033304433d7aeea3ffc71ee28991f54e9480dd48686c0417f5ee781ab17c79bb87f1d61d11561307cf504fdca996f3e40d08f98edfd961a447429df97d5d6bcf5bf704fc184c4362d5c482638db7bacc133accec8059d5e7243994d68a1db0d460b959b9a930119ed927742dc222dde6401dcdbf261e094c2057cc5fdb701810d526dde60f5782f988d17719d5f36a29aa20a646a85822da515764d84e877d87f1171ab3398a331c08223b44192a30093cf41d415d54f5a7d31dc02929d3df19258f3e6198358642f5425852f1551d1e95f95abcc1c6989345684defacbab74cc883aa247deaf5650e0529fc3ce53478ca31ab0367bdc7d1b74ae2c23cb6140a0c6b0b62130266d9686e32cb09766fd4321c028a3c619fb04354639b33396267a3f32ba3ba9073ae180788f4eaf06419779b05aaba1f49840315604e71809788e33dfc6cdf0987e62c3442c335d1c53c993686cdd496c90c88484271b19dcf3f2044ec9edf79eefb0648aa96b83c590621b85da48dbf181d4e3e2332f494346a909526c576faa39c462dbe7dfd2ee9368bce3ed9bdfecb8169f1216c26349bb8f130e51301fdc584a88c0815a4347ad400872abc58174fac1aaf8c44e76829fd7422 + +Input: 229d67d2e720320832bd8a8eba769b2757f4a23ea415c7e69320bf37f9465a67c8986e7060d95415b700483c649d5f2a5f4f869ff7d4ebc316348b8c9fe89ff448f8bfe373f7e5af707217cc4402ebf169393eaa9fb47f11ac1f81c01d420d01987700e6aa3478e9c7cf314eb28096a2b02e096e1d75370ea9d322e27b89510480e1497e7e09c9393b6e1b29b9e0a5adc85e8efea304de235d2774062785193ae092975f393d1d50fe228cae559fe9 +SHA3-256: 933e9545a9bd73860e50ddda563948df811f83b8912c2945b147d3a156ec6585 +SHA3-512: 7db8d3073439ca04b90ddd662a85f22350b53c5303844ba777c409b409eb5fe9bdb0593ef0d724cbc2440f2a36d94775cdd4c2709630b4519d8047f5c6bd17bc +SHAKE-128: a1125656eeb8988e7ce91810136be6d53fa8bba277ab6a6a5000999dbfce8a5592d8d56a86c0e04cc56c186a5b780ae60398d0aae2a39df417c227844ae496d0c2007116af56631b8835d9017228d3745e9eb82cab60dec5eb39ee755961babebf8ba70dbea00c66c582544b1a5f3cb695ef1eb2115a2225ef02df930be7a55e6491684ddf4948a89c12aef4fe0bc7776758a6efebf133c8266e768d02b56c2dc2b0653c71c57ce4b4a61ceeaf147f4367d39987d3ac6a966da5c48adf9971d257698e8fc4d7d84fe7a303e0c738e1ae8231f604219783a232a6bbf24008cea4a7e0660f27eb74afddb309e409efb1a9945605c3f2f589c0241717b9412b2d079ab89cd61f9f3b00b85624e50eba49edf49f4760c8685e113087b4d61d51628659b3996edc61f393fbe8463040594998c8fe6a865955e961fc4e83b80e46a2c9e42e9e1846ace9e68b96f373c3a1a7d0b319bde7d3481cc5c140a84fae676a61caa988530ec61502d4d58c27a42a50acb2abf6508cc667ff48aeaed6c42e1bd7133a174ea66684907a3752a1fa343f3ffd2ce175703af007eebbfd404cab92534cf1f8982bdbd18221f6ccfef116a1f57268640b525975e22368fe5adac7937e6f9dfe954fbf009b4d6074146105c85b90b85d01ccc048778ebfee215ebb285a26db85cea94fd329d3a4698ae75f7b09aef3da6cf2537b369be11f5b718fa881 +SHAKE-256: 33650e8e339406fca9e400132973ad43066d5e299750af7ca3036a310b47dbd19bb78f8ceef327b0eed1055b2413a5028a0fbd1d1d885dca3bbac06d25901e32119e1fb0d73d443fe8aa991fa764851d79f8c8e96ed6a24765f6aa0e7342729014b5d81ce1197d586c36efd04c783676d350669bd9d270828927e23edcdf85390fe86f4c020f4e4740a17042f275bd92b697e421558679b3289e26b381e0c0bdb9c4ecad034f77e43edcce59b02fb6b46ec025f44e60369386568c6696f5ba999c79be17ecf98965f585f17bc2ea76d1ef90718977a67a5e224a696efa59e94994b49b9ad1d6f94508b9aedf1ed27dadc4cd4e06e5fd40bf5cf3a20dc932535a863a59d6d960df058fea44bfdd8a58fab24064faf3052e4d83b26bf4cf5ba7fbdb93a836487cde2a0b848600e0517424fa6ffe5c6bd90a98d59f3c061387ba591b5758ba2218dc9ab604dd942c130f20096b646501879a2ad827dbddfa8feb3f6a91db15f6452227da96879efd9a74ed7d21c4f1bdcdf4d324d2f327a0fcdbebf2fc5bc1b9dbd00b9ce4e95c0390ea8763f3eca88f22199ae15ed67a5f6012fad9ebd905773e11db3f89d3a07c504d2f9fff17f5e4f57cfafcd30d809a23d6a596b918c549b6ab7a419bf06ae51d7b3b6a3c1ea8064cbf89b106f56f601b9a80ee2c1fba804e446a20e89c1b7e634469b9d59a90a321a5d9c4622c704b59ad14 + +Input: 8e8569fe543eca14ee94cd8e94a404b5c38c29c2cb832608070777fe656ef1fd452480483f08fcf1c1eec3b2601595f47b9355289a2bf413e99cd4dba6cb956e2c1dd786cacaeca1a20d9caa087765b66ee2194c005f1c77b501b2add7bc903344398a079a63861dc45a0fd631d48d52264c2990a015a316e7ff0ed1b191e46bed17e0aba5c735d908470c9adc07517dbcf3094cf988d2abd36ee866af28c0bb0e9d4eaeb290ac01bfde337848170021 +SHA3-256: 3886ce31c37138062860ac38b59844c6617bb82134b4943d4eaa0ddc37f8967e +SHA3-512: 3535b31251e1cefc2b718c7d745fc611a2ad198807638177a97dbfe0860a1cd0f9acca2b115d719da8ee493d8f5a16c31464dcb17ff26cbc752fdaeda76bd5fa +SHAKE-128: 2aa87718c4a09ffcac7388442f7b55b3cdeccd0a001f2ab5b8177b2d4184abe962e59a0f29060b27b824986ef33eef9a34a1df4a2eb2be942d125f7049811e00ff92b50789caccf5e8b87065bb0332e3845c21bbb92c0fcb590cbfb7d18d028e5f73694ea8789f848ed22a05b76711330865ffe43e58df1b45519a33a6af86d2624882beecb78860d19ae673f6091bcbb2e57a5e5821056a240cbd68a32bf055990c3cab9067e1d35f48e77b1eea6cab5750940d969d4eaab5b46ce2417ebbdddd2403e53f2ce59870341bd9ea8f63b1fbf365459cc3d60f88efa89d056c1aa7a5129064f51251ce625c70ed270bd87699692f0d910a6050ffbbf9274a0d7794ed7cb181852137a026d8d7a46c6a8f35364b52d081f4b45c1c15613669a86f762bf251834a8121b7db714e0d5b662346a76204ba5b84551c7273bc0cdaee394130a86487b3ca8ab86bf2472ea0bdf811f882c5143b363d355708d8b210ca593adb64427fa0ef069cd830f034db22f5f7cdad5fc9a53e5b5e38be677749d5ea17c38b23e0e7783963e4f8dede1cf40eceab4e9476f349e8f5135c1fb8bbdea628e6337f46d48f54d3c13fc2e90fa8916b9f2c50490d6fa0e8dddc671d609d629549291d157d0afee1564b69677184ae4d6770199e162f02e3c270d3a374c3c07a6a32efc6770b78d19ce136b15dfa015f12a4c18996302009d3e063a43da7204f +SHAKE-256: 0af00798718f40e2c67f35b3aac0fb3a645d824747088500d366d709a12d6d2e9adee072a1770a7f647e4ed71192fb42eedca087d973ab0df1ed192a34f3d973ab16668a2032fd105e02e2cb6d98f278ab4469fbab5db5be34dfe2daf4de664ad7a29b6dea74957393e0b81d21f5ae6af86e2f06e229df28bc72f559f4dd9be95b956cb22d3f21debdcd7c33adea4d8f08d60276a230f13df4bd09e09f5c3056e6a8639d572ce4c62d462cafa340a2d853a329b30e4a22708f5de73af2e0d861041be97eb5e17bcb78528d4478ad5eec694b12a8e343c9c1c92aa65c7c27ec502281d4f9e2f66ea19817cc3e47caeb1651b03ef9c4fb4aa4c607eb0d1d840cf70054dd6171ca9812e722087b2e6a9af30a94e2d3e383a6ffed950c05ef97de38b9f54ab3e356ab663bbce12d80b50148442b2bf5e2a20b91df1506985829a3005005b53281b0756bc794cb698ea3bfd8f97353f84f65312a90bbbd6d628da6d03526b8f6d6e048b0fd6f5b03e10c68475723fc2c27839c229abbabd2bdf8f5988b25124fd3181d586957336b7823b47b3e896fa45d3d36d76fd1379b8b3e611b5b52945e7d09b5529d3d1f856746f54c7d2582aff5606632d2f6efa8c83ad16d9d7577828cc846bee0967ab5738129d1f40f02bb858d1f36e54b6e4213c98e07b34079733ada34cafdf9eba88497da60a023e36d1f0d06eee2b86c5a4b3a258e + +Input: 3f976ed3b2e33c3496029398f70306c73298f0ee4ffca82a4ea762b6aaf7d5b4137b2b6b56220be349872022f8de4d2644cfed242f206dde96312a06afb5c82873fd21e2c308a60cbf9a50ed125def2995b84a5b34c4fa85bd7c67df00a9cf37cdf45177d1ccb0f6d4b044c817f965ccf39b6218be6224515823d420eec5691681ec8297d63166f3bc8c71ade757e550a5c2e7796bd3c20d8203006e12ac5dd055aeca6ba7e42d76df8aa0a598fd1a85e9 +SHA3-256: d088920b352d864d9608f485e20777a2eefa2222d0ad60847295ef1e1834d49f +SHA3-512: eb58ced3c5bdb0bb88130a9c41d9a8445283534916cab4984d6991055efb82d1d88e13c9dde3d6da05eea81e0e38e2b780e1a9f5aad74c5933dc481276b84d94 +SHAKE-128: ab3b544c0132d1d8ef68e9d250662ec91d691e2a7f07d9a6992e0d4ff617c65ad661fdfc9cd4afc7587499ededa82cac5121daa60b00b1a2252d350c5a32fa11be97c26e2a7330bd850de06d38675742e9bf5169be58497ba79c60f3fed2b82a0e9de0b2100180d8c77733fc38770f0043027e49f7167ab3098cfcc3193ccf38d29572f90e6d120c2f7cce54b74f8765d8de95f004b73739968dab94730e70149ecf653f157ea6a660f9e524a89f2c9a5f7829ee26fbd2fc15d8e38146431f629effc5cc331ec9118efbda80d416462d819daef64596b262ff7f60a901cb4111c733a1974bc55c306dbe8670b7f34141ea55aed9f7616adb64ec84094a5d20e1d4826eb107e786035ff774bad3feb41ec4bd81e1cde427e3008d0c5e0705ef6c476937c6d861c938f055452165050a5979897e347e68fd2c02c75340feea1f26a1b0b4d8cb57981f97f44a96ed6b80cd95c7f7107514eceb5cde552f5f8d525814650b5804188dcb032a2b02088cbb42e00bdbc9e589062899be5054074100b03b765e04d6b328c0c027fdbf03a850a654cdffad2b7490c1fe5b2fe432238cbdda3bd0964120660d0908184f2044fbf5685fb0b8ce58a39a2afb156254e3b13d3725aaa6670175957a459045ce7605e015250314cc24efea383500358dc7fcea33542e367cbb335b486c897774c2a72aa6ac6fefeb5c35499c000416f5a229a5 +SHAKE-256: 79272b225a7dea2658a0346db65301fbd76e0bb45eb564c12839913fec0073d1f9c534c685925e5ffe89d30dc74e74c7850119f05d6ab0f7322d9eab8a053088b866170b5858b5058c26c90eb01956b7a11e5e19e0af77d4436e95ab147bf6afa84b9d3b08e0555d8f8007efad525033f6bdb0162683d20daace190d0587254cc0265c25fbe8f31ad160ac49486117438852a50a6e4fd229589229deee1a8775e8533adfe35355c46ab28a6e4b7b513265e2b25dfa90c7b3b0c916c986dc0673dd13eab7f81fd396c8ba521e9281d24dd51626c83806841e001c51c54b6bc042b59f1745da58fc1d87712fdcd70400eb971b4f9d153b627b19a0a45177ecd1942772aa04a97c6943b91ade2761e20712bff4ea9ae4daadd53d05e555cdf5aaac059006670e8c6d2b74c44ad38c9edad19128cb74496085f15bc5b672b5e1ced999eec93e73b570a2110f70ce8bf724ea45c37c9bbbe7fc6474b50aad4b2005fa8852361ebac5f54950af5ec588ea0be69cbce04686d57ce14b42cd5d7b1d04925962cb12849a3cdc4d827d78b7e78efc4bc57251a06736a083c4e0a187f3a7407dd735b8ce27feca4e8d83e49572c3c27b2f5f6a531bbc6de39371d872c6bf2ec1fda21539d01acfde4c829dda8d98f2d207a04ae12ec5d54b798339b1531e1c85263ad2fddfc850fe6f6dddf9ed0763635745f3229167ca0a3c7119663effd4 + +Input: 8cb29bf522b10e53d1f587842591b370f6163cc7539d7786e6f39eba7f4e0620d0b57536409a0433d42f0e00e7d9d10eaad2fe6613bbe101fe03744115dc9d84b2b5e99e3a46082144a3563a0d6064c5ab61e19ff4946b90792e19a50cb867af96ea242bb68d663f380c66eebe008a62f77a1b6dd8cfc6fbd766131d57780d3562977ea6f257131761b2ac21385f365a11f436bc1e19a3b15483e19659c078dd4e44e4b34cd1a5df3c965a9c831ef4acb183 +SHA3-256: 87a20cb399be95d62e9b06512ed474ccb044d7587a8c975c20b7c5479d320476 +SHA3-512: e7032658df09f179ffbb5e3ce7c8aab30b7a10d048690bc02c81dd932ecf9dca8a15a2af9e7e4963c8e3f758d806357012fe124ab0fa031a5022410e9ac63605 +SHAKE-128: 0c5def25a2ec1ee0c49fc531d70d145c5d97405c5fe84bc8be6bf6118980d54ff938b9b0b7ce5a8ebf09a9cd96b1237bb276c1a098b1969de379938b685e603399db27749bbd5763b0dadba5899e7e145b84643e1e01aeb8f2b8fab6c8270f4de12959410dc246f45a45f1c04e78077199d346d35f0460db388f3aacbdc295032a9a292cf7ae737b615f82627f997a857d34f6cd006b9a7fe3ec3b414209c7843f1b44fac569ad4ccd20a1daa22a655a3c0111fd915841b82bfe5274e8b696d3c432fc0dd6bc883ed218e72a79ccfcea51665af0762d25dfa2f0ed118a7acfd8365eb8d1cd619e47876323cf18a2bdc327a917bae4ad083fc86a6c6d5eb1d514702aec1c42ae2c6bdc2d973cfd8385f1147543447ba5d01decfb4a7039149f3b4cc728918d43e91e414f70e073d90496b468f14c002b11192cd06353e403af089ef8c08f18d8881b594049b104b6fa080c16792cbcfe5eb078d0be5269cc147aa60b688c8634cfc6d502adac378abec595bfa30c9af908d264a86ab5654c4e1cbe2b0dea6d9e60a9e96e608afe422f458fdeb2eea9b58ea7b059b070d30a4d16be78bf54e5c1beaee4719d48b1b3349c78afa2ef3ad912c5c2bd0e6708c9645754fb8d288a940b90deeec8828aecc013a50970383029724ad795b30c666d3c9bc3292071ee1dcb3e1ae754b546303d047edc0c174eabc3dd8cd0f0badd1bde8d +SHAKE-256: 1cfc42f75e63eb90860bbba7ce5e05e28465374acedfe76768f61f5e4a615c0fe3cfa5c84fa7440905631ecd70b3e8fb324837e4cfb5142490c08fe3a365447ea059fe8c59b7f77e712be25163b1cc03d1f90ac9d2dffad743bb0e874e25879f1584107ff84c1c458a3771b60f4cd2d7636b4451e0aa7bfc306121a1669231b3b5b94fcf92f805e044ac7270e46878e10268d05037714934e2bb10d8393e5605c41d8a3c36651b9b15d201eb5613338926f55426fb02bc749eca60141f2030eda12fd961f6cf6f16031cc597ab92aa212416a3db41f4fb96f97cefad45a2cc67839238a965119f9319b0830d483a4ba4ec1af8741ae43973238cc14316f4f9ee78947296890d1b8ea8b7067e458692f89112ba75d0054076e2faf6bd8f2e69698a522faadba489eead7f5cce6f4fe49545b0a4e3a9652397a79234b47e18ba072e1721521b5366d4e6749882d4ee9143411bfd526717e2980610e020f7c6da0020d76552084a144ddcc2f8f07c30edeca92683ff6b0ddc143f3b66fc4aa10ba97e964022c51616caec3cf2d4318146d18794b9fce0412698ec2e424b00708f7ee5fa573fcdd325f1678cf147483c6ceedf4c76a81da472dcef61777fae750f2fd04e2cc01aec52d2c0333fa485533e293b2412e3c04773073681723e4ed3e14513eb28a7120f9f28fb70cc807664d3502cc7e0991a12667cfd5b9496fc5fe393 + +Input: 4f05e3d1fda79905776f720083eacfebf90982344329caf2861193f1e448336e698be1b1089cf0b8762e844a967962db476d342a5fe91c04d7ec11bdb8a1467fa83123129371bef9bcfd4265e9a3d0c9964e8960baaf2020de60b4c78f6e6bef9b20a6fe3c6b5767e12a29bd34cbbb8c7048e0a69c3625dda19bee68245f9547b139891ad8862c90576b6c7a1511fa8ffba69706db51fc763c6e1528311c26e88482c800e82d3c58ed3d43173bff35fe2e3f66 +SHA3-256: 3f486ee1fd646ce1d6dde03f9766d73b49a6336d148f69582ec11e00e3b68c0b +SHA3-512: cb282f421d786a80783c28593b25fb4b9be6b0e6fb8220af62d8b3139ee49be8e06ecc9796f20ac5f2c5857d05c700701367dbc17d69a76f615b61c2281a114f +SHAKE-128: 5bd94a54eeab2680f30473e4aa94588174b2121462d6470c6003b6a2a063a5c4aca9065d90cbfc79077ee39cdd17e9736c6e47a4c735bd56f7c32c77fa6124090a5ae798941c4090c10447c04912678b0d0b2db1f4dc8d4a617c1479eb2250b6f288fca4e5dabc51d6136ec415c6230e11a43d16a03200d936a02e19cc280ecc11c6738c0c1ac34846f72cc85c61a16e87edfd66cc0f8d4630a9a811da15d97cc41dbd0866cbb86dd8bf8fb1b9c49c04c29914fb0ddb08fa5b29c4b48400a3908527faccf12055a9a2a459e9b1994e9f89adec5c4b91832c9e5fb7f995aeca46c4e4de78a57958f661f7ca9bb6287727f0f929b5bde833706532ec9cd33d6226f31769d48c397174cab2232f1f84415ef6978b48778d24bc78833c2590c1b367bb525ca55a16b0afc1294d77c30d2c22801c4150f56114ba1621b3bed9b0c1c0f129c0329da9ff6d3d05ae5261a20f81e92e1b3c1a4a9420900aee9c59a77ff07dfaaf94a409f2671f7325b57c398e8d59ffe765b876516682f6fd3d79a6d7c9e3928ffaaafb227cab60adb8f0f9abb45d0b33b92c60595153513a18bef8fa1b8d8e496a127b84f20f7d6622e5aafea52ac688ed3a74c05396babcc524509289307d8e040024578ffdf02512dc30cc71309510cec06537e52c312c42d618e7ae493cdb8623893377abbb1196e26e38247bcb61f8dd40e6bcbdbb6d23e67cf286 +SHAKE-256: 6fecbf25e09f5ab63dc7b6fca2df42b32344ee9abefa1ad6a27de86e479fea0c9f99e488819fb1c4f17c3b3cd93c46c5fb650c264d5d3f9c63e9b48e97fc8a83aa08bc063456ffa927ff236db4ef4bca28505cb32ce224398b5b7f4c979e446147b15c05705a8e664ea92a701f1e77ccdfc86254ca0ac2b093f6a22379e470235d63430b87f91224a1750c010617b72bd5353507cd7b44b7a021e49141424eec58c35883664a9e1e529ed9436b8d3676d97351ea69328b8bafee7af18013335c5ec0048c868715c770f7abd1748ad9db284d849ee5bd9b5f295c66a837c200e68d4f545c8f138fb4ddbe7e0ec8fd7db1b7f8a31e20577ef177a3cb81666af2cd43c354a09b6f8a619a2211edf571fe138e0799d0f9517304e6427cdbbdb7e203d4a346557562a9e4530722e74e1502269431ef92060db0bf2da17cfa21531879f0722febce5224f60686649da3631f82cdc6fc4a3af11dd34ace425000938663f0119ab44a9167038a1643ead8af53754fad0d1fdf91b9a1587d4116050a143272fb7562482f66537271d3ce6d5deca4590a3f7b706b97a9dc0f48c294b898bc34a0b5fadb266ac8c1646689f53cb01ebb2bbf53fb7e1edbbafac8dd199c43b8c01951207522d2399a1858b03bd260f899a1f1b81950d4d2bd7bcd46e793053d1b0aa5b54c86dd309ccff16eb943dc18763bed8d6f8da828fa913eb030ed05f3 + +Input: d5ad3a11d0db8c2e1641e32baa34ad2bd897f8bf1d3d2a333fc3f23b7fc4dc0f3eac71067216552ccd7c9a0a36cf4588796b77197305117101b31dba5a89700aafe4712774abed029941f7fb16f01d2e7f5177b196749ac6ee52b36ce5c17031617f966d5d187d85e2009c8a8e49eb95fa82fbad549b96ce701d2e820cbab85a61fe0e41cba39cb87e0277e5e3a595db9eab3b3152739fd97a1e3eef1a8de2196611781dc2d9633814bb6308aee0e376eae6cfdf +SHA3-256: 14d424191429ca7f805dccd891875bd1de21a46d9417cff39cae89f1be23c673 +SHA3-512: e286dd38273d8656f2b26ec2bca0bc9f1dd429e03b1ae4456702e6be7cd9c6afd2ca4a6b61ff0cad39df21aa63dbbf8b43f8780abcfe0a56f95aa3fec8ac96b1 +SHAKE-128: 81dbca4e597486d06663cf38f884212c4c5893ede6dc97dad40b6b30ab2217530ae8a0986796ffa740a61dd4896e77f4f6b7ee12ca5325f9d8bf2983583305318ee5e75fc7cb79c638c736386f309f7df56b9a538a3968b4418e05cdc83bb49c651c6f4c2da393285861e664ceb9cb4eb3b4ae9147ee9c480f1a6be0e74155a473d76bbdf2fcdb3f586a17c36a6f895429e4f4bdcf6a7cd38219c298b1c7467636835eeaa82723740828c49372158b6cb99f9e55153c8c7e468173ad80ab355b6d35f82d68f43607e7239373e85eb45121e777ac0183d8a3740e43e499eb1618a2aeb8e2b052d3e229d02c72b02900c0fefd524c6e88a21b1396346dd9e330aeba23f2992ade32892c2581ff087428291e51de25dbebefac8c273ca4f34dafcbf399774689f0e7c98ea5570aab2c5a60921ac656439aa12a4b694dd9655b754ee4d87df7e97dfcf767f08e67ec3a37b8e59be8c57cf65d9b167225af1761de3f5eb89372ba7b67b3475e638c9ea74d48e87fe5139678b297b28785007707919827958cf55dde194ff1996ea51e48dc143ac15fa7853e1ac7c15530623b382d1bcb7778fffcdd9ebf6c43c3e066107fd5f87e543fd146e9d5e34eb4cb59254f394973bd038fa33a05e4fcfba93482172acc47364cc164a5c781346fc3affa8f52d4896e509861b29e5be633490e67eda716055bd9f3a8297f6072d4a22da6c499 +SHAKE-256: a8eee335b744e1cdd6cd72108d31d8ca2bdcb748f754e94d25470812599ea696bd72a7bd1c7d0b203051981fe3d2cbe7ab6366600742842cd4819d91fa5e28e890d6272b344575307f8d092fe5ef98412d074fb55af565e2bcc627684bae2f65623e52f0701dd57ff927bebf77ba098aa1943578d5abadffc9964ea12e3cd298ef39e6a433bc6a23b70087222c64b0d9ac2a10e7bd040ee9af8de79f912a7ef690dc56d23f8e5075afe248bae70313f6fa1322ac557ddb14cbe913522c2e25be9c4edcba912d96dfa16fbd209934e477c907fc7b9506472f5ec28f41bfedeedbcb30cec621135192120cec7d5a8cf3e64b25ebe751b62ebf757b42de5fa19c65db00e477deb873143f6a30e2363338ef8577dc24c03f23d034e60ce8f3f0edb8f7de4ebf9257ce7684c831a0e860ac309fc7007944fd5aa4746dbdea020ee04f4dfb938de3c52cd4b0ecae955b96c232a7e3b021e0e0e330a079286991a1ed03a7fc2cc0c5648704ca7099c07d89efb2c5535433eda4f509171b3b23e8ec6f451253676aab9548950b67604f114bf866471e82b147ff2836cb853baf6993f61c7d005ad03a4f2b6cc3ba1a8489c7baef9b733496584288866583d421ba252586e3ed207903ef4e6ae0adc6eb1f5f3c342ceef1b167ad783a8ea4f0a4d17ee64d86bf96096d757ddc8b8c4d1d3f5de2534ef10dbe85921b5dc313b35cf6c546d0 + +Input: b311beab9189e433b5f36012c574bb089698428c1e65cc12c9a770587133aaffb5c75f4c41d3abb1430c39778804f29d8ae0c941d5514ecd25f7f932c331cf9437e32e95d990cc623f00224fd0cfa60ab597932fa077423082e44bbe460435ce1dc414af62d1f09c2d66e79a53634e5c7962e85b9c2e63b2f0f7e6f3a9efe93edd9e38a80824bf7f8446d984a6e9162ef7d0930dce9aed280f42446eb94d90693d567185309618059f5899b6a07d91dfa80f407c2e +SHA3-256: 7b75f592961399841e599bc15181a2e338a750360371dd278c36a16b8798434b +SHA3-512: 84a92cba77aecd59633c70445ada4ccf72321fc52440dd9d0205896e674f557d146a632446ecf106db474b647cc552fb555dc5384f90b94d6840b0d271056099 +SHAKE-128: 4c19b4e38e9bd2d6ffb0d932d4c7203ff4805c4c3d07177b40def0f35d86f8f6dc2a2213d8e63c9de300da1b75b2d3ef62b6b32c4890f5d5b8154a0213dad5c5991dfe07f480cb6e4b522906b29bcd97f1fdddc00c8157f64928abc8a45d399264bee8a2086bcf80579c4c7e3a9b5b123cda61c06169020ccad3f8977f1536d4d6388f85487b967f831c25d0a5125a8b5ebbd1b62decd7ef8c1479feaeed21238e47cdabc2fe5c72d70cfba8ae3869591ab808edb943069157fe59c7640871cf6f1a26b9846168af1a96918c7f515b6509ce8e96eea13d8a021dbd74573e1c6913e2a0f4aa413e46c4b7ccd29accb86319899f3104861f1270a64c0228046667419c31dccb0f815a14e51596dc7504aa1f5112d9096dcb2d5a4127824788d5d844636941c6d29e17dc2768e057dbf0505d2889a63cc146f150bec8af0ce81f69d60d8411e05a89167c3615ed1ea596a7bd20156503c23ab5273a857465b180821091173cfa7c62693b07ab35ee5bf246639a29b202b8205429620e00a4383a247aba394d1415aae2753618ae5b33be1e9a59ed88f63d8625a4895ead2987a31b507dedb44212ebc46fcc6f9e27527f784f49a53d3e1bcb1483ffd385589ef79a475b51acef440887bdb46d6f535a60094ed94bfd837efed006f56bb978eb2ef7122878d69ac754356cee6f34f9eb6df6e7917fe8c2fa9f4fb18468c59b6763e1 +SHAKE-256: 5397a1594abc5a6686c993058da61dd1704ad2624a1bfe90d12ac01e85afc128c3bde57b2e0f733302ab3ba9265c764e547f759767ff8f532a41394d32a8eaa8086526fd67a6c7c990ee4d295f01b5f85a709069d5405536a5e10021359c63603b9a86661150942b35cffcdbe4c799fff97aeef213dc3e6a156b101e6d39dd88f7635f0939c5b7190bba11efdf9d7e04206eeac182e246c29e7404259e60fcaedfaf2085b1e7995650dbe06a8cbdab7ce2a2518aed962ce72ca94760e34563a0ccd8b0584017894c46aa667582c2a3121fec9213b4fd376d040571b58856dc862da9f070c51848a6be1a0fb049995f8351816b78190a43f4378e475b84bc83aedb651605c1bb31133a2ff4dab6593689a457d66e00d35e4711307a160d1cd71d3d40f6dc154332635180881d78b2dc23731abf42c72f30d5baf13c95434c6eab161440e4bac4c83c2a61b98641bdbe2ad0b7027c6c3716eea667380fe191ff54e583709e05ff475b45a255ab58bd29fd2bc57999abd2169edcc332d5a15a64443a2f51a0828b136da0dfe49faa508647b919ea8143c46370476e86914a66e60437ad6af6347ac67c3693e25daffd69dc7337117b4606255ef1942845ae590079d90d2b4b407f3dff0d779eebc5124b65d4e0dfcb1c04869e94ba0b874786b83b957b367c68d3fb84382bd610143f5c7e81a46e8672cb9a3d3f9c001b6627e007 + +Input: 64f53e8b0c26f733dbb4e1d99c1aa22427c265c403a50d01fc3b05f01a55f28b31ecf737332c28a7904c806148dd1500dcac41fde02fd7fcc48ad018727b4e05ca92157ca101a371a346005a3e009c5a0e415233898a67a136d67121a4413ddbac9c63e27083ec255ef84a355c350164883f5c1d0f6869100ff89023c4acb15b46d76e55cb0b0f454d0d970e4632650dd2a1fe45b223611f23e3a22be288bf4572b6b3b737671e026bdd29979718f29a706fbad97b35 +SHA3-256: 3c555f81234412706c6a642486711571f45ac023d67568a8c2505eabb3a61ea4 +SHA3-512: 7b2b1fd3c323f37175b42fc72519a0017a595db6dd2fd52b8c1fa595ac0392f9d2dcdf0b0af88b988085a855f60b95a74d1164a88994ec121595ee3c3ece990a +SHAKE-128: eeba189a4cfc05a319e337bbfe5ec76a27ddb9710bfbdc64cded7adc86a5c439002ec66913caeb0ec2aa3e57114da49b29f7e799176d1928eef03025e3a89abbe24d4d0ee538a771b17eee6fb20ee12f4b101691e756709c57d3f10c95aa26e6d9f665da0d20d8fd28486e623f0a7ddd79b4881a25f6160f9c59787f48a8ea895032ffd8debde3a6527f62902cffb2cba60540080e6c34d0503883ee2d522e8164d4c784eb0b40a5c07a86dfe38a5913df6fb136579c12c81177c80113ef9dc5223fd879dfe63fa40714ecf4bb7a64a43a7f448f838af04316845602b8cc763c7c6479f758c6630922318c288d9bc9ce735a3636853c19b1cef1b12235a48db6e489466c53ba2ecdbf7eb1d13a09d8e0a728d961f6c41fe31422da3f4da7e941e0e2ab8ce3367a72aa0a281e53e0519611cc1948fb67e285b4fea57ea92b0fb724cf0cdc0a15f99c8e4119e72f51eb4ff080b5ee482ae8b6adb6682ce34ce60a2394dab11e85a60405075723d424ce7e95efe3ff3f476c98f18f1dc1344746f9701c2a0d35e193eaa0b68f81527e76b206922d6fe3b84d8953d7a89563eff2a64d0216dcd17d790c5fcfc20b2ec6a6145b37c2c44743965a68a999354c37ff753c079cce193542a4813433c62e8e0659ef8c0655a43c9e5cbed8632477b7e6969a493f792381e49cf6e3bec40303c4e8f6bb640c3e678dcb5b58df5c095f94ba +SHAKE-256: af0e49f8121ba44cde5fcb938a1d930ad867ae2cfecebfe0ab0d55ea64ab17072b59e542824290f1b46341f6b9f9988113bc8d7edd15cda6fcd07737bd61adb542bab0b7452ddfeff252e229a84289921f839014d3d8e2d8b986624fd8a1fbcc93699837e9b8db2df639fc8e37b5aefe0bc722d294f5f728964c693846834ce1973c33247d178c8acb27e61abbb877311f0c5026e29eddcac2cf8567c209ea56c8f65ca26b20b1ae7199bff57de8734e2fddf63be338e48bb6fd815158b006a939f64a33413051420691e52512100aaf0da1498817dc708d3b69a3f4091c2620da22a9cab6d4de21b5b75f67c37e83301d15171771ffcd4847cf8e66e0e996cc90b9e7fa9bc0b32dc795678cc7af93ed289eb0685f0b71637544c3e4701c7b427cc843e7b96fd67397af22a5f1c54428a010e5a89827fc52c8448d43f1477d7dce13ce2e417f9108b8b36448ae56610b6bdbba1c17ffea622ce6d87fc62a97340546c705a36b1be299599844a07585e89c8b1f319d0a960aad8767a6d0fd23896736527120b495e312c2f47710535f30e9b6e9f5213a25b2bfc4d7fc324a0bec9814c3bbc98433fc8bfbe04ca4a964b31fe171c4f883647e25295c26f2e201794e24e844b89631aa2969dca0bc648fa27e88877a9c42d0b197a08a9eb896c6eb621440f0230d15cac102ff805d865b99d82b9d01f6e95160d2223c4443b59124 + +Input: 5d7510e7be21619db024dae6c38fddc7917f9f8652482acb209bfb08244252c8d90291184444210f6ee6c4b2f99e338562b54b0ebc410c4aef6fc2766f6866321a1747cb3f82e0c1224ae799b36a54b48b0c27a57c74b609be5a9b9b8d8eeee15466f15cdd30ca79666d47b97d9514c0c4bc06ede23b5a5cdf0eb3cb9722cc95f44143ebc576d768d072afa213bac03ad4a8344f454de99ad946940962ae19401f1726775ea717a8a7494ed2ca16b3314bfd183c3e06df +SHA3-256: bb71743dd5b9daf494a937e3e3bae49454da4a616e2254786ffb59a5631199ec +SHA3-512: 5f4d2e65fe7c5a347d4d457262fbb938942e3eb48e25459ca6727613c1b1c0a30362e7ba8961c4edae127b8e74775e9748c5235d01661026c0ab69fb7db060c1 +SHAKE-128: f1cdadb6e3c24c467ec0ab4784f78806d7ccfe9ab6570fc9bd0ac2d31361de2a851544c743e3d1c2a16c94898e4c1bb107e7b5bed2a8820ca80f81a26556ff41c637fd87dd053be51b8e06badfc42a003c307f9fa11903014e7855b56470d073b2b086b0c901ea9e0faf38864c211d0316661631c5592b65c78bb53bdadcd3e9bc26286389d4cecc9528a238549c99fb47f2981769ba46ccd0a08fdfa3690a069beb882fc10e5d0ab7f326a1f08ae0dc34eb0b43d549773f90279cfc95dccdb1785ac4df52c0fe1c91e8b3a83e9307ef064ae0898f189e3202668cdd1455660449c7f897d101047c90309c0a9c0095276b9e17ad177e76516868ba14ef88cf76969aabdafc266b9e66171b80a5b16b47dabbc46c0b6cdbffa0f61fff9fdefbff9b444b136eca9375b810b545ebbb52aebab5275da1c4c375f68baaf7757c82e80be61da7dda8680a8fffc2632d9ce96343205ab914af428075c84cd2bac03f5f250f01cc65a62c14388b8370d4d3f5aba516f86f2c5b014562849c39c32278a438602a4ebe2e300d1ec7ed6f093b5fae5d889f6c7e69a779ebf9318ec9dc1c66730b2f0c02ec5246f51fa1798f0db667b566be4b6a1af75f62fe97f22516863c2f24a3968a1b0290923158ae893fb56e87b8377c5e491173e2ff1662ad5e88ea27965d93ce19e508ec773626da451bb811d292a6b2e5091d61ebfb874cd9050a +SHAKE-256: 7e624b901f762185deb5a89ec175328291e87ccd2c2be59cdf77100cfd2fe4dc59a05df16cb243c240002c3cf009d1ff78d3b0c7e83d75935359bb8e93a4c78b532eed90ffa731f2a199b8adfaf55140ed849c0d121d74a26402d309eef1a43721d59a87083f0e628ddf86b909e46bc43e8d44bfa876d17dc84e11eb88ccbe94f17183f7466e5361544fcec1a875fd34e844d361dd399ad9f822920d4ea59033a8e1ef10befd133a6939ca0d58dff578fd78e96f9ea82241491c67323030d1c5b04165314bf840da1f3e6685260f8927bf2a3526e1845d41e0bed2ad1efbaf655bbebac6ed06d1a956f04febd0a057a73759510b986f9fb5e380b2acc01359742a693def50972c0ee5b3b4aaa7137658986b90efc489e56eec2692694a21df5e0b1aac3d34cb4a146d492c9484153fcf13dc9dfa9a5ae315e62b4351ef810f3c5c2e153593e5673657e66f6d2e4abf47d6101af045f2211e49294dce570378fa004c5cd3073af8ca9fe1b33cbcd59bda96b2dbc8bba24e2e92ca7f8b208be46cd0a4136375033185046102aca9cbcdb88ed2329db4ddeb63186cd0f0b9dd17176f144e0bbdbedffa422c5bd04ed1fcad081b18d963f78105d5d1e1215316825640d4835205fe1c8b2a66e966635b3591a3c57b149129d93214a5cc8c5e62f714091198ba6a61d762fe80e95d6e399e14bc9103fcdfca4eb342b7a0d6a4cb092e + +Input: 0480d8e4e6202d22e84bf28798183c07f692bd7c8ce76e5f66093fae2c4d179d54fe7d3dd251b1c93de0ab50919a01712727cfcab8cabb2c9a3083ddbff95087af6eab9ca6ccc27e7dacfb1b57ac3c568ce36db4e08729577887f74d32deff6c29c800555bc53cc48c877d5b38235633267de3e588f12c02cb4219463c9fc82ee3c1e1a0f9eb3631f9ee5995cf7daebe79e05389221fbc17f1d0a6b1776b9ce1565a306c962f485b0af40e98b7e8240a205f39d4705ef0e5 +SHA3-256: 10436fb5992891c6f9626abd77d551ea3dec782af6b2262264d8ca5b2046f398 +SHA3-512: 81e96dc335a200272752595c2de1088e1516b49c3417e9b72df9c07ba272eb954e488e8cb85a0430f541c590b2dccf4730108c1bb2835337d411d22144d1d384 +SHAKE-128: 48c68319fc0c649d0fb5d76d688c49022699dcbd3ab3487d15774a79b4f4a7a221a347d1c6b79d67aae611570a29795b0a94f9d667df9dbc736a0a5626ff830e6904573e24ec4e51494edd347b061f65aad4b12c2ff02e4e196bdf32e1d26fa342fe5c792ca45b6e5ee9b6e0a77f4e4b79922ed559e3b739ab9aa1a994edb4c232520af0429cbe00f9efc58de23b15e747a066b711a736b36c767c05137d23568e46f90d100d6da899dc25551a4a487359364bbc304984a1ec19c2f6f06a508a0e22076de5c0823fd05d5d67e79672729c07e70696e47fdef7e73982bb4ce5128fc0bbac8714dad3b66b46c5995fc84a328f8acd69066b9d129fb6dd2c805e8d19a5e798914d6374070bd097ee52d62aebd78076a0a7a6650dcebb089a8bcc66f21324d2a66e525dc0e77be3152be626641e0e61ee07df14a7566fec71cfbcef764328095c874477029c9f6def16c27c89fc2ea17b364246fed07e72db07dfc4f3e20e360652df75f36b471ed6c89f8764664edf30030f5fc2daf5a67b78b198df0452bd92f005302f9735df90b8e3b57e9c51af6026fd143ed7042d98c5094d7e36b1f216c12d56aefd5f197a6c6e7c9ab7fe060aaa81699d69ff240084962b1218fe004a2fdce7f614c42362131395f6cabab626066d7fd2e8b214c30568ce8c0e132664409cdcddbd3377dfbba7516a07343d31321745629329fa8ba1676d +SHAKE-256: 117fd223d35f349d1c17c017067f17d4b28fc156693349543a841c31d8df2251bdd057081379aee01f5bf5c49c8e076732ccf51a2e6cfb4ddec8d88e6833dfbacc11c4c5cc01c0d9e8facb07017f71f9f306834e95415a9f16894d5cc8363adc271a8b981b3193d8d9d2de747ed3c52a3aeb5b2e7cb21a999692f21c2fbd6c8cf10a040fbda51d1650eb0d644c72a5f7b9ad19483f7504780e6b2a391ff59131d88402cbc59066740794221dd4ae0d62fb156dee172ecb965f81f9e49c14069502d60d32a6394c7cbd9681e7285df4b98d5311633e5cbefa49fc66d1912ba8b516993f773124923373d8d1250c31892732965fa8e06cb52b6d56538b38cf141c69db0d16e5625650c33c19c93930f3c1fc08c94147d94488a80aeffe29d4ea0513cc0d95d03381caa872ec764b29dd651f1d2165ec1efb4ca1765dc530bbf1949f25cd22b04cd1dbc7df7c4c86bd919241093464a5ed3fbcc8939b6e4ee50e543ad1a33cca6722d9fc221220e1fd313c48e3cce6a0d1dca7542a48df5c7d5bf8d4d279a2d9ddeffcdd773fd038511fea8b04f1ff025e48e9e716fc30a92409545d488164cbe649004b4cee5d09359551b6d92f8565823b7243650e7685ed55e9fb4eb4c35ec6d3c95a35abd8a5f6515279a0722c635629c77ca0d1cd81f32e23db9a3be0a9fe7964c39e4cddcf9da8e0eb1861ad54535ed9ce1c02ad6f2ffc74 + +Input: 340cc17657ad9cfd9fc068f434104e8f30b1be119d754ce3c35f7064f58a684d7450654aaabd8fb8b67e659922ac17c64de89253ac9d1c5aa07357b64d6bb5ca84c440d3ae603eb4adb5ee48c4a4137da87b509e5c9ff8b2ca2b9eb4fa6327e3fa2f9aa0d68c668bc5d09f4894803a5d34da6e38f1ea59017344e93b8462a117095bbadfed798e63a39228c050f2bf8677d9da8b29708cbb6ebb9258277f061e0c90965fa424bcdc9c0a76d414498b3737d7b3907c60b3b11e +SHA3-256: 59ba4fe549e9cc8ca818c6770ebc28687121db19b31fba4eb58dbac05b233a2d +SHA3-512: a6dc43ab6a1f6b7ef078a8c5a61138e8fc45baceed1ffa888db039c04d506f614f00d0a8c06491804760d7693a0b6882b292b0308ebabd8deeb516a78c4d2d13 +SHAKE-128: 250e6c56999abae263738f6e0fca59eddc7246cc88672e8b44c125d9ddb1f019da35aaa457ed5d634f2cf2edba12e5dbdc4e0a466af863990e22b6577ddfc47362e08c97ff42a40b8045c556ba88a2b9ee9e03de419bea4c6f1e0f2c7fe600264803a79cade405638423d232e6b42aded9b32a0e8121c56ab530f0bfeaba0addf4ae84377ec0eafb7bdfb04b0b4450886236dfff991df9793b87d3e015e3fc3394b04800df741ff0e28afeebabe66b86b5f4dc0371e528dac627a7f705401d3bf7b85834caaf61db3a7befe983d7064e081d40685b09816df13a5d03fb6edefd13880388a28a1b57940184c3f8bfe2bb81b33df3d4b5386ddc3b93cdb8a32b94c74d715074675671ee852a1577aad1c06eb83c827efe97cc503e4648a0034497dc6fb8944eabf72cca3078cd4c830d8ebf7d0fd5cf04d290275479910945d08511a3c34f18eecf76aa023a136ca5664c05d2693408ca595fbd1eae82268924fc01dfcd9e314d15bb3366135efac60d09e6ae92f0926a1112385d3f93383ba50d81ce9c6cb3ea5203d0cd6cf392832f747ad5e5c438edb7e6c15d0edee3407be4959f93f96aca896cded3d1c6e4f7f9a924e387827e80fcc4efa7c8929c0a96d1f80674fc80f0abe54f89360e681378139031dabd3e0c9ee899e6650100ce074fbd4685737206c5cff537bc0a88ad7c7138e118ec86a18dae00d68c719c0e0ecf +SHAKE-256: 9c2451bf232ac42a93a225cdddb3d30cdc99362573fbfcbe85417841906ad972789d40cd4d6a85180b3944f7796e46218647cbdc848231bb7314b4be60a3b3ce945a7d2c021f2baaec3ad6d0800df797244c9d26410b42aae41bb995b4401a35d128fc3bd6105a296a13d5137d94c80688f80bc2e6c30c7d3d17f3b773885bce40424e29c1e67bed88d34b6fc88b4d902ca2d574c134084cfd4e70c44f4f29b09f47f84131181e0f72988c9ac00ea78f7e1ed842bdce795d83e8e4846966211aaef35ec19950ff6ede86f9670e4b953cf9eb351ca746a6c9f3837ed16635d07b5e67b8273df63393712c115d76fa632156c4ecabb7ad3eea63405a45661585778111e9dfa7b53e1d65121f7953eeaa4bf8b6f08ef8ea503b6437b512cbea6b34afccf693a84f031e7e5945fde5fcc74d296adc54e97ccd32b47567090ed1e8a525691006ce044eafed4e11338b7804d265ae87cd21d42304bda2d75f302e58f7c92c653d27d731e10110162a988a550237f95e19951b00d23516c85a05ac82e11760e323609c1e09121ccd9ceb5ac14ff409c6645bc032ff2151337ae89354dce7fbeb59a763cabf2a0789362f9dc6938d006dda2011bb15426d73b0b9fa9c014cc152dce090489bb6845bc0f65b475b36c1c0b62b7856fd988091fb24134797bfcc0b5317c7e9b1aa98ff2560a7398bec93a54652abc37daa276eba01bef7fb + +Input: 3315ab6d10e6ff08959fa1ca33fb4b5e81b6c1d7941f285d01ab092ce0a3c4815342ba7f50a4e4db438e06ea2890a944ac5a124d8174c7aba3c5aa68fbdda9e705651611c88417ce53ca3a08c4c8b8fd7277957693614689b2aaf399133e660a730323a4ed2bab3da7af92e2a806b5bd114c238e00bda13e9dedb76965ab70e2a96a958ba4ee4c9b944a14582f401d08b1bc509dd9a218421e074248aa458fb2bb7c0dad165b84aec421b779ef22b5895d0f7a7f3f835c9636c2 +SHA3-256: 987e2578028279245d4e8c6e16d3714359e62626936b50f5e0a4fee9b971da24 +SHA3-512: e56e83351322e87a8022569ef1a8baf85cd2e408db5b9553571e0ea11823d5760b0f0665c570094f358a178df9e263713c24548c6560f8e5fae4078c5f0966ba +SHAKE-128: 639cfbdecf1538bcd0215ba263e2ea8f3008e9e5e5eca6130967d0e1023c8856fd7165d9a28d46c4693afcd3c4e12ecbb70d7618ae0465ee8e8816466e3ceb12d569774e23f3f71d83fe556968d84af09a45361b0696f3840e5eb5067c7e604c457be57f9d44ae425773194d6b738c0d316401a89ab87d4226a4fe4b30cccc7952880c72fa82bf0ab95b9d456683c42ba3f999703377aeb6e07554b7e7bbfad5909125f6625c158cddbac04379db9455a881f9c4d18537b9f0401a264ed175eabec10c4e0047e39a63537df47df473c0f19d842e39e339aba0207833f1c08425cf2fa9c6bc45e89c6e31def4271da9c753daa337f961a14ce9142596307cf0857365fc6928ff0e34c5b682f5dce2f3996a47e577319875eb1371e9e58f72d718b4a3f7ebdd692382a45f0bfec3adef716c2928aac120956ba2879961efea21d2d498307c9141b98ec14a1c7d8e4e577fc2e523b8f05d83b3dd6df01e3b146f85f11932a74109bc649e71da6933f4edd006c90b1e1a3c0416d0ef05cf319f3a6f241317381f3dcc0902697f0917583f39b0ac0a2ad008fc05d400fa69898082c2adeeafb680d07371c590e8110c9c74d8187919aa005c40ea2bee78161acc40c15f16a5f137c39d9a567bac0326a2568255b052526212eafee82d69900aad5dc64c289bbb2bc79d40bc682ba2a6283f481c72c66b0a9d5d5b4a25bb9ee57b57d0 +SHAKE-256: 54e665758035a69dd73a86b529933384c8f64867fd765b8960da0477932f7ac849a74839b43c29c526eaa94e4b2c261a1627e4c49173432aab830923da2065502f839c70d36fad2aef4b59e929f3efed557e6a47ab19685485aaeaab88f31941f5a3a38c1a291158b84a60c838c40f57a3fa9692e456dd945fde95514c962c0fcb37f06507ce06101c3e0530f6ae73f60b87c17bb9808611306ec96f8d0b44a301d43f35ba018d108af0e91a4d804899a35220864c3532126cd18a9b42dea59739e16a2d34419bf437989be85c7418b4fed943be8ceef18ae9338db4ccc91974740c91e191e83d27ae7091ffc54bbccb96c78f94544e3724376588c9a12e41aab5f29cf94ab961f711043f15d351e8daf2a0ddfafd1f4b4518c94b62c40bc1599c15f99a15552e23c02c3363bb42b59460601f5fb9c9865f0fb5e2409435c66dbca608c7fbb58d15932ce9a2f02095e1494de7035c59c0494d8e3139040b8d8800ccddfa7bef5feb493a96db3302bacf7b01bfd548fc6911c60e4f3c44ade04cbb86e392ee7e56fbd6cf0238cac3e5837ce1d756a3493e2808cc7260a3916c38bbeb0afad7f479b39270289487a30706201300649e966b4bef2683a73d1c6a21ae910dfed87585ce8db5b12873fd2aa8d3fe189857179cd5acbea005cb64eea533c3c36063cffe566e980b990c7141993c21e785d7cd5ec569b278fe8c5358ac + +Input: 5d1cdc61eb7d731d1af0d9bae8d72a3997989230e60a9fdfed7a5692b3bcfbd6040e1df5124c04a35fedde8b326563fbab8f8a8b0d4e96e0bc29016b8d14698148829a27c605272ac02dba1f1b2876bbe76be347a05f22e2266fd9766dbff7681b018cdda77651b9be1e56a2dcaf8cf797116f53d14cf32b84ad69ee0f41106db3b21dc7384814bbc0d9f02fba76e0e0a951c8017358eca97fda2d639c0ea185a1a3d14525a6604e380a4d83e284e6b43ee8ffd7cbc752d8530a60 +SHA3-256: 79afd4b3cc3ceb346a08ac539bd1b29dbf00ffafbeeaca42607fada575bbaa16 +SHA3-512: 311d7fd554a93654947c74bda7a63defeeb24bb41e52d6f100eff06d2e09419199d834e0efb5f6d4615b6cb9f2301e66df2103aadfa2dd421cdade628137edc0 +SHAKE-128: 95894766e8ae5db0e2d8a070adc47025f275939ab5d4831ed2245ccb14eeba771cf628788081c2f718808ab602b1b7ea8b8bc68b4c89a961cc285ed9b0111f345cb25cc4be2c8a632864a4ce1cf8a8fc2e951d71f3b06435618f496fe7c2cd26e89eba0f3aafa5d44ac8f837d0edc9a383e3640123207341bfe1efd3fee75a90c7e6f9651c359315473e2f7b1fb259a935b13bac91dd720eda28bdf90f992525bf0f445e4a3acb05bee4366c267c077c1d18e4099c54891ee6df589193f62d7169c139a4e9f643c2bd6d0e0ab9a1ae8d0572fa9b86ee40322756c47c4c0e71be958180197834d3ba235ff485689083cf578853816e6ff4c4a4bf51fc8c75fa2dc771dbaeaed95b010d3cb38fb6737397a70682728a33e50ef57d348eb16adcf8c10f3b0d0221db46dc1c8c4440cd10dbadd87056ceadf4b5e9c59f5122bf525b1a984fc11212ca12a027aedcc2a8957708993205bcf307c0ca27b559edadafcdc77215425331ab149d6182beb9bc8c4211633c5e019aa859b2bf474f59e0635a3d30d494bccd58468365f1d77815c62e5bcef5d9d96e43b07290c29d1f56965378126282dd2b8f98ca09c6548b1add53bf7fe9fcc93965583a5b08f7f26d745ab92e5c8eaada3d73682305f9568322f842eba482a5cf7fd10edc4c9785b205bc0a31e30297f7ffd46d4df666ef67110e942a6d2e04edee805e9c7c00b32ef691 +SHAKE-256: 23e636c76235e2c58f3c3da086b60dfd0c38ae901e93f1443dbc2f93f8df9b910b8d09b11e834093d9c61c4d667e7410958e47c31dfa8855ce758416151b8db235d8793a9820c04a2c56280d35b6dc1a5b627750f3869d15833c643b7f7b8738cb5591fedf97ec938abd1447ccf57656d2494c6ae179d3b1dad96ba44ec88aa5ccaf6173ceeae8260da816fe57368a08bd532de350d8e2d6aab313c6d27fae3feffee068533e15d87c1cb1ebaba3cba32d292bfe4e164ddcab62f820d386ebaaa780365578b4932952268ae0d5d74ea5974bb8daef045e7fa13665681970603154f15eb8d90b340ffab7b012f2aaa77820a6992cf886bdd4684b12686448028475cc0371042a144285c638b4a7624d0956b6826797994d2b6a488888b8ccc757a2ccc5a79c0f012e7698495e0ed8aa20dbc687db6ba1804e969087c829e260fea8c5ee29d7610c121b379e493bed9de9bc021849447ed19086e0ecb3598cd96221b72ad09487a0e72b27313b1f0f7a90b3a095ce0d6f8bcd7ffa22e9331273f3bd6c1887f1bb1b49fa7b068b93f66cd30e3b34bc70a9c226449eba4458a89f249d0b033f084597da885bcf46e5c2e548b28e051989ae16b15e0fd3c26b0aa4b1e041a94173009e825c5d570e8eb8d6dcc1735f621cc1346818cbe0974253db4979f98380a7d72f04f4cad91777b710641940ed36af6d63d905e1ae1a2191dad3 + +Input: c84eccf5fc441aa65c63f41307d182ce1e43127bf9433fd2bc167de2b5896553e1fee73440d9f04dadd9ca3eac5827572100fdead72e7d26efb4d66daab0850385a5d5982dbb82200cfbda0f31b872b2d941482746c21d8b9e94df2804f6a66872d8f57c76855de32423feb5dfe1ea264261ab09b7d0c1ddc5be80f5a2008eb01cde3e122522523b71165d960554a27206b7c760140efb1f243878fcbb06ed3c30c1af2f2bef99ca8ee939d08a6c7e456c7e88aaae00ca42a1e818ee +SHA3-256: 4dc6da3998004a3cc7f94ccc45d5e301df170d986ee86c8fe6547ee8b6887e65 +SHA3-512: 155927f7187b9cdb9e031f2c2dbad1d89e0f42a9187c68d30c4a77fc49cd7c6484424b1583c33983ae24edb4cf2f5279685ffe2c964fc2c26676d915381e95df +SHAKE-128: ce593821733d37980c561e4b1e806842b496b0435c272fac7bf6e728b6a8c61b871887eeca33419e7ceb9470567a52fca419c4772562776ca48d03640eed5b1c351f5b7642df5425bfa6d875eaea582ccb129504045eb7320dfa6db51b2075c1675f06feedb4ccbaccad9c56a0ba81135ab3bf6a3244557e53e0967f991a44c6715c4dcf437cd3480a390795b89cfe25b3186dfff0ffe64103f2b6e5fb113a857b1fca1a7825b49bd0c2bb66a84b5f25d4f5f9cc86b5544ef785c0ffff341f9082c6cb3c0f3e562e412c7dcd8d43a1a9da1d8c8472b22c5584f51a89705d7a5fbd3613048ce5aebfc0826c400645a49a4743ff1e924cbf7dce0b7d52c52308b95c49976b74e194883ab407c51f5d20c22ae3635638b60e86e15cdb981ea8c9a301a57dceb8e89ea47b281f52a796c5be5d23194758f2d73bf9326f47f23dafbcce4cffbadebd923b032461b2e0a636fc5342bfc161c3540d044067d348758d18baf71211a6ec4f7fb721a5d6831d41821a77a6d29527a102f91cac997092d85a866e5a1513ab5dd886725728a3a9bcf8fd1a9947dc25bc3eee8598c4bd0b5214b5f5f4547b712ea02e85ba3f8a00e71f24636ab81e6db0c2a4d82efa6b2cd34e257e161213d855861e53b01abe6ec4e09f00dc0c951f5d26832eb6474450beae292b1da11c32bd3d7bdb04522d0ee3abedacd7ac8de31b4e536aebcdb411b7f1 +SHAKE-256: 4d0d50729f2e72fd138bc54bc277a0a447584062d5cb44aef576c36129d54b200d5c3c43e15afd2b67ed5304f5409f1bea4f659f40de7c52bfb34d9451d0622301eddd1759b8ad0649193f30f8ce0307a564cceb881d5d01567ed2b25b1de660aefff643756ff14dc07bd6a727db7c0c1b01137aae560cc8d083a767e58dd7a50f7060eb45f8ff08cc23f423727d877a2d85ff8b5bd7186ec15c078bd2ba6b4fdc43a441474523f05cd2a517b8f781ef9a269d9fecf514582e5c5500dacca703f7d8ab981212009525c5df93e2682f477f2cf43a52e01243768cc398aa7fe30e263db8fe4533d0dd5d5a460291038c47530573082ecf4d7ec827962e34ef1e0d8e03fca1f8138540b0a60b0036da671e8a12c91b5259bcc995756f4a99d6578a1c319d64dc55b0f08136e3e2c4280f2b92cda736526d832b70f29c973351aa79328dc886edf5acaa38282b48ec47ff0f3075da26490c938eebc95c8b78906f6550e309144053f41812d25ebb89ee7defb7742b02dc8f31ab9697fb3e4606d6b823cb242df76fb0522076eb881d18e6169ba3f6d45350559ab1803d8a7a42b00dc055d9eaea01782f02e460876a72ec6de5fd5c274b3dd6b8ece1ccc4ef6c7f26e6142d9945e0d6c3eec0419a4597527602b7f9b33e217808fd082086269b04f8e0e975334200451be5de9af5111f6e976775b738f8e7d5bafc2aeee9dfc8b9b1 + +Input: 9bd4ad22d52d95f819478eca86905c813851d4dfe2991ef9b887d25dacfb38ce036a1db2c908a6fc74331e7b8121181f4e370d8cad59319f4aea346b297f7ffede19d2a8a4b1c4b3ea810fc490b3ba888d31025e4201919101b42b77386b71bd547006ec1d25b5a99a60a5bcbff7ac2b3c347a7c20028f67e9d04b98a297c9bb42e2ee1c4cbc206cc965b559f62bf3f41fb4a7d7d76ae4c3f7324a4a0a11b153605cf319616aba1192c9b66045af9508cdd0a1fa526f60356ecabbb885 +SHA3-256: 83514eb64d7aca8ff061434e68f680f07566d4423f1309b35f84133e9bc5077f +SHA3-512: 18827f4e197bc959507390dd493a885f3984f708816179ff56c15817a406504df1c4ff9a2928394c67d781712e5f56faa7847be7d962a5cbe08e19308fc81e2b +SHAKE-128: 16928826fb11e8f339563747eb27ad42dc5f225b11896af5e6513c8b94f405f2c0e7a71338c50be4fecc2d0186428d229d1d2e469a89389466ab212fcc536d19262e59ac05bf52510d4ea71be29fea88660f1d5273c9afbfd7df446c96ff787f164a6c9315c7d6f0bfd5255b60ec4eb0563f20b3bd1a8071acaea3d0c53babc4d2ff5d8c51f4a321c7676782dddfed0169533786f757fe32d3caa93520b51cf6407c1b080468e60513c515bb570d826a8950468a81d2977166da5f35d3e5d9419288fa0c868b22ad57ac4ccc1ba20db135e58d63939a4ddf31bb9c8b85db874b5f83690c236ff4e27aa73fa35f24059618f59e5ae5c7f22dce445dc69b35de52e431d00b333eab11b2041b2e0e1496fa359f1c1d9c56498fbd244dbc30605cd0ee4abe9f200e6c8fca40c155012d844160e129787ac5bb9c82b77ff74d9f329f118acafe5c16efbf0dd81eb2a3c40fa229a2f58d253fbdd7904f783c9940f00660c3de71083146e338797be79039e9459fd42110fccfa7f60e54002c9151b725f460d2e662c22e219f862b6fa7fd736486a6974eb4b128ed829bfa695ebd862ee17bfffaccbba23bed046ba64af780b2e63d2d000c82fed6e3e357eb61c9cb04b520abebc538815fd29fa21b4be702ff977a0f9075143610b949d9f5f9a08a6e3041293da8792a2687d6b9c2fefa0061d3929a3300a18ef254d90bc9809bf744 +SHAKE-256: e91c973c45fb542b66a06a8f7e090d3826845279c250c871761b428ecc3cb042e159c508f8c28b1fd7add9c62deb795d9f6cd0988d4da1b6811c416c9d372b99983d71a3074a1d4444365ec02b56621046735dc293a7b3901926bc3cfb70f4abfd972618d9a68b1a1ffddbaacf7750a1ad050eb2985439fe62713abf3509f11dc7019421bf6999737f42d1f4f9a20137e2d183b7d50a991f8f644beb2448c617b59a3af8788c4642befda934181a901a27d2e734dc22cbb6b49401a9f7b3e6d6aaadc6caec527f6989901a9cfc2b247a55a72435ccc9afaef1a74cea19224f019619539ca7d7dddbcff016feb100d32d96ae277dab24ef6150bfe2d0e7e75e695821cb02283b7749f5ee0e24bcd4ca467b8ceff070705c75ad3be927418896af9b7e0367173c447f6ec2f22bffe14fe1892e68b10c5dee7a3f953dcf93f3d31aa718f68f2a3bc790a966aaf8e9fd1717ca9786d09ac64a11aeca68cef2d251ce2d027cd5730811c85f7f2a14e15c8fab90f3f9b89df5493c8a34ad31db67c41eba229fc4523cfe4d610ed02c2882fcc9fd420fe2a6d6425abf9dc0074246c4b8d647eeddc3fbe4fda6ecb8f35bba7e31b884ef5f5f7c0febf59112d6fa0e1ad8de95244eec9d0b97ecf4eddede6396d40c28bc3c1fe2fd9dcd8ff0fc3fd6be90b48c7013ae629782b73159663a45c3a5c656753f9a2acbaa8810ae63e7d53355 + +Input: 674a7b538c33c83a093dba209a806ee911ff31fae5728ab14e47d72d585aebaf1271af7d14ca5e657609cf1012c07e87599bb1ae3efafba75b2b919850fdd75f6b6bada522680a1ededf5fbf06e27029e11ad4dc7436752f3229d11c23a8036515bfffc37f8e52bac3659cb32e3a405416ce39abbcbc3f7baaddbfe0242039e8b27ed162986a00cd62087c4add0dc7092ed5a8b1b4e079705648713b7decd02b50b1d21ec1f49ec416f96b1c39ad0524c3d590c404b05045988a4721f21d +SHA3-256: c1a327802b8842312d372bd4fdfe36a23d93c67a21bab53367e3328cd6276e27 +SHA3-512: f5bd53aeb146644923f2577529a31e2379e867baf4f4031408f8e592ce8e21563a2fe90aa69aa9bfc9d5326012de7e3cc208b6519ee6716b21757988f74a85f7 +SHAKE-128: 4ae5b2a348f34b30cd626c634b776ec4e24004551d7c1d885fea59bfb8deb4e644e145077777b35e48e73a1e002b31284bbf1d9efff50b676e162929b453c55000a810fb66180787666df6d2822204504ca1345129b4869fc31e7cec3237f81be4e7be03b7301b6501cc17d0eeba3f9cf06b2a4047ce8855c750b32a447e38e4cbfe2a12b643ae6f20965e5c745e4fa396e28b9635b62f20f03c3504ce02405931e5f8056d2e79f8e4fbc554aec14a861b51e448cea1a6edda2c1f8c97e95a9319fc5992148721d924bee3eb52b4446e7a408d777f063f9e2462cee9df124261ba9377ab06accd7799aa8bc9e6aa338f8cacfc10cae29d042570fd40ac697f097d22b6d5d43e3cc19d1da9e08d3721c8382cb4fffb36e373ee25f6048b38376bfdad6e95fbfd4f09f2632f54d7e23fad375876362bb3394961a76d2a6877f728362f7216c28c028705cf5dc747a445226e6948d1de56bb5397afc3347c253e5e10d84a63501bdfeea429c9e9cbff10a9b719de6a924e8d3d9b1b56734e60ab60207f97fdc132ca65a95d9b161507f024e64687e1fcd1ba03ab11637f7f45301b85a802d88ee66d2f28ffde63710b2b35f0f3fb71851864b6eaa5b2318ee6859a5fb65ee3521cc9754a91123072f4506680055db83e06f2a5887fe673cf29b9d9af72718cdab01382243ff6fed32d611354d68026713aed015a94d8b53975775c +SHAKE-256: 2292020122b147b72755c99df4775654ab12911b28dfaa5864d8eeb4bf712dd20f8b6be52aa4fd3e36a16aa76db2b911b7643338235bc97856667dc0616066cbdebc670b5ab90d9404b1c13feb7db477964c6ae5cdcfe153b838038b606227b89899a623518348bb46d04d70fb65ab73d344f40d3688ccbea76f21486a699ab72aa13ce3272dc654f735a3e999a22814059dc9827c92e1eedea60de1a3fa4d9b261cd7b5ac435d00b5de802b776063c677f75b34f4c63dfc8a575183834932b1983b3b39538fe35fec6fafe73ff74cd58c91218e8470c5248fac7ae24e3ebdebf247e88e175f2bbaa6da71efe798a7ad90bb2f9a83db39af7c50dd2319b0028590a8702f19ca63144271ed40e88265bd1144b56c3aabf44aedfb90de7cf6910a8364ec7179b3e002d88ebba922d177782ff969c6d3402727cfaf352021ca95fdefad4b654b2fadaa6f5d3e399afc7208727c859af5519a6ac0d67a761aa24e808c18b64a0e0fef0465185f1d95a52da41816b560060721e58f6557d422ddedc0806a257ea81963f5473f3334700b90107351cd04a400678b6425b63b83e2c070d91050c710ffa807f294e7a5c9ae966929abc5b71e4a2a38a5cee33cbc5f8cd829672e409fb4139dc531e184897fbc41223da081cd41b0ac329c6f3dd1a543671e30ccdb6a534d7166267fcb5be918d94b62d929b7a86ff87e59328019816a52 + +Input: d172b60b6c13417e1605198979133d24a636cb686a1bfa126f966ff02df82d02c96b29144ecfeff01f5fc3e3996e98e114816f834d1b20ee74df1d5f3680ab0d99639f535744d28ac1a27eb6c4e6a399940ac097493548cf9462e0cb158e97af356c2f8bd134c9f51f9512aee84a3db7462511d137628ecabeec9a5e67d07eeb0da65643fe91fe7d08b60fa7380a52cd22f511cea0ff4f1459cb269fae822f59004d6a82613af530c94763a9c889d52dbd0f796d5e79068c01fad17c743aff +SHA3-256: afe3a346fdc9ae99d087d7a2d2ba0c31aedb5ea4709741baadeb456943e78c5c +SHA3-512: ec3e05642437d6264012d404a787108ca9db0ec8afb635e26836f4ab0d5190f081477af44bbb0a5c9bfebf3b6ec3a90a79c01f53f569124370d7091ef9658f0d +SHAKE-128: 7ec216bfafaa313a07b2a5d6cb82b06d95cc3c667f0fc5566209e651814dd29b3e20021a5c43f9499622fee2665e95fbe6cdc9d3ad3f53d934a471a892baef1d1df700e5cdaacadc4b094906e141c4741923c2f037611261e0ecbeaabd08075d1b16c9f58741902b59032a7fe22db57e4fac696b30d664b60a054e3abf101183493b574c393040a01ad99f0847acf1fe68d34cd30e240220fb607bd1ec385cead614a8afaab724f67893ef642a76fbca3f629e476fa568be21d16125b1e791caf5449182855a012b648c4d30abf1bf1a78063a0b7f7b4f128f22e0f8973701573d3ae5069fe37430bf17cd494afc0d3e0153d75455fe50b2369d59ab908035cfabc09aad04105e22d3c940bb70bb41d695f6591310b0ecf1504b0a7a304186ae222af252995c1c9b969399ba95fade42c65d7f6653e41c3bbec4594dd44136a351e2d61385d3e1b469c9d431c9039b4446465512cb44738fa77386f001567d2d0ef96ed9ee4ff68084a9d54eb7359413aaefdbceef4f149b5bb4a53e1e84c52dc5192e2ff35b443b18672137d71fe4e2baa70db7eece73c6de8488c83acc042607ef93f8690f119bb1d20c1b044641b59789480726226784e01a66f097f18e07f0a26cb1f75d010d2c1417e0b06e3107f12a0c70b54faa138a08324f97f7a016d5b3361fe98a6d3a34b86c4dda027f5048337f54a35ef26117c67b3d16f6f0fc +SHAKE-256: 781df09c7e135b95df6efd9e61982e670c4b0ef6ea4163ee6c7acb86efcbf4d852e05100bd11e20b82d0b6cc71ce5c953d22ad23ac3659d4513f5acbed7d75e30e78baf13c154d8458a1e50f41341332915d930f4a254d5a6d5cb80856561359b1ecb63962ab8e4d91c3730a19761234f0069d9690cf92353d4fec5f7f82f91850eda38d6cb16495113204abd689040a45710dc21fbbecfa78fb47cc960487f7f4e036877c91116c479fa27ab9685d3b3da1d059bfe102f242179815ea4a6633e5dce845db1fec42ecb7253c5846eba73eb7927d91052eb05b73648674cccef307cf8340321bbbb1cfba40f4e60e759e99b91c72734fef050e1558c7262a344c53ff2aeccff4357985da726c650eac46a161ba87cdb7cd74be67096b14f7a653634d9361d466b749c168f88d41219bd5f2d49b66892fd3d0905050059544c3e93875401844fecbfce82c06d2f5b2c1d9643c9bd2388c9ecf0892cece5bbbfadfd4f5d00bc70310456a3578b89979642f1487331359e2897303b49abe4380006c504d85cf0f5cde019f1b2edf6859a9b70c174a2fd7a2b65b66e744b70f18d7e5e43987f70286d42e9bdc0d8212dad21093245f08c2876b78d765683a38f4f72042c5098f9d8ef3f7a04025915b9e5318cf0b8ac7beddcd910d03d8633ee994386684c4321e84802684c4359fcf467d3587c26eecc5a0034842e25c2b0788da4d + +Input: 63fcca6282e49cffc903e625ac18a37855c8297a5af2a9bd868e3d20eb154e9834c3224d04762721ea817d6b5a47a0b2004c44109d0cf6f854192b5531ffbcf2e3b07b2d4113f3a2e3caa75ec289e871f298cb1b58a055b1f22a862b828e846c023ad0aa0575cb217d3acea86ceaa3a71bdcf8db0d43e64a9fd562268f22a47f2e9ae77e05df26dd16b32bd0516bb316b31f68923737ecf622cf2b7168413c8a2f6b5e62e935e3dad7a2962d93c65700950bc6d624e12143f2e92ab31e9a69fb +SHA3-256: d1d52860fea19f75fb1c218e84e80afe19443c72b9941f58a7e2b2481ced1ecb +SHA3-512: f48fe8493d9753cd69c5096a73a4957d4290dbb62dd938dd7d999517de4042ee29a3c64753737fb21aaa858929855cb383e471a15581d92d6ac6e75338e93d85 +SHAKE-128: a2ac830e8184fcdc8996c88f71464eac054c6298f90bfcd7368b7d2a3afe255d40a70626b0e3ef65c7c0a8975272dd28e434e473a9b379a00b1cbefb36901e0cec8d186a05cd26af343f564f36e55fb3f563e0a58f14519d19f6939c6c3717040965714ac569551211fff0176ca54d69db1f9cb34b7b3a6a452b3442092891357fc5657c337735f3c50a4512e4c2f66f33463a4d8e30d22b5d461ba3fdb8a4cc1633aa2bc9ee1da84f561a0331ac6e25e5d0daba51697e011869d74ca67de5a6d49c743fca08b5408844cee70e1fada3bf4d3f242eb563eda3fd68f43d75cb2df7459f997a5584c4e7c05c24d35c465fc82ef59972c79a41ebf2583bf069cdb06c1410e903f5118770783f84a9d4ee28493b9be3341f306e2d5aa754e7b8d944c8fc947fafba07cce9469cf1abd6393b92f0cd70ec405efc438f853d8cd4b2bdb0aa1417c2b6e7713dcd7486ff622d11dd284c182dab58b2bdc8ac6b05560d15b557cab60f49415981533c98a1c61c209d9df4e28d94cc119939cc60c649078fcd3ae7756e9864b01f5747ee72af89b686bbadd8ef880d330df2e8ed2bcfa4dc940550877dc4116132ca1304db8e05d75c2fe067fa58d4802dc750c6dcb7f359e3d9ee1eaf061fc23a7e92c8949eb7ecb135b70f4d52624d0569320e4a68157b66e14bdbc00360fa2790b27d1481c51e24fd19a14658598bc5c212fea4455412 +SHAKE-256: 00a1e9cba6c159baf3055b37dd53a7d4f72808e55545ae5d7ff2f77f1695445520056008ad8d4e69392b196d6c656b768ba074ce07b80790c873b47cf90a515f096cfd488ab4fdf01177f3c2960018e672b33ad11431e792d4c6b38f3d894bd041fbd4fdd6187f21e16df7f552840816a1f20b867b4b22d51dba353ad1e5a313eea1dc199c548c74ea37829360b5336944994088a8a50ba8e801f56189bab8e7e7a3a485cd2bbd988c902962e51cd7740508314aff19385db79c2c98daddbe82c980fdeb664ba24c78f26c71b8b1b257b0089bc1edf9c30bd3e1610395e731ddd5f2fa7fab62fd1d5684ec4d42c45929bf7dd87fdbbbc3fadd71158cd8429f5a007dae2291c35dba14ffafd2f920bf9ef5923024ee98687f8fe5d977e75247256145898c31b3b5b4f62074f8701b4d4e3ddf66ba3a103ba54e0de58dcb821da0a1a6b5c08805f3aa1f8370d5769e51acaecd59b1df02bf4001b2fe1afe8e1ba3ddc073ae34632cf587df5ba694ac548596c34d3b02d4d9563713409c506d66895d58bddcd93433b26f3e32e9ca9dcb62d280bc8650dea0e7bb468ac6d181b6d86f2dca92219891f39a9d27577a43b5c86d47ebb2f4ae31aa47dba0584757e53350cff2d146864c608e7247e76e7fd12a3f0b7b3cf28c22fd712247e9630ce26d6bf6bb80057725c12cf1289b318402ffd52a48c2badd1f13fde48fd09d08130d + +Input: 6b5f5951ace32dfa396b6184930db09c48761707b7efdf7a1f0218355da12985f589b91020017c79c3d1c55e29f6312fcb832934e36ba150d268cb4538b235908aed661f656aa0cbbe1583624c54909abf1dd07ec4b65629e34ee0697f0bc679e11b83daedb8ae05f8ac02c2311c2add15a8c679d5d84ccd0c98bde65c37915532035822885f1837104d666179ae95a3e957bc37919bf128054ad27c1470b8e62bb266c643fe9d49eb99acbc13232fa075d2ab390ed340158aa1e3c763822964e7 +SHA3-256: 0cadb85c05c1ec988b5f2f3e3bdd9d5efe9cdfde128652e87f5d98d96d27685b +SHA3-512: 0a38a72febad51c48c6b693cd2604791ecf08daa515f175a5e568a1a85b0efd080593ce90305fdda185b594c68d348ce97655aa0762a59554dce423ff35cffa4 +SHAKE-128: e430074882fc908b090366b479342a759c71a692a528412d3ee74a59c27396766d6a93d9915ba35e539d0d202f4ae9dd98178db40a0fa6a884829487aa2edcafa150c456f55b2fd802b5d858ad79da14a0b048a0b731ebf0f728a66bbc82c24d2ece77d3b64fbc6e9aaee4a8f57c943c7e1e4b607f88f8ea2037db704dbe3b385552886218460e89255fb34db1888e8b044e153af7403dfbdad6d0cd8a71d8ac93fc3d79982093e66c21143ef4e5275c199d79243ad9e77d7f3075c36370acb468eb2ccffe38d9d4462cf9acf612c8d80279cd8ab28882afb233dade14d376f5600e1ac1bc2daaecdf681d96f739888f685171122d660f70a60fde6e55e6758143d2cda792949d0c2e284f96ec33190579b533acf17c089ab6c267794a36b1923654d568c8cfe6ba2287809045a0bf9a6731322b99aa418f2dcc9cea5d675b10e686264f20afa1e604edcf63ba9641f29ada0a6085f03e7414126225bda49310926cba864d2e26c08166994677b48ada633229de4806b677cfe5c5c022767389a1b622aba845db90484976497c5a6cbca75242fb53828e765fdd8fa3bfb0c4b38b195e4692e8cc50fce6ac0ffa8231a5b58b3eb2d87cbbb2fa52b9a12b51b96e1a7e5fe339dd2991415f94d1a9e1b18db2e30b8cd839dfaaace55547a3f37a8bccb716376543ec24c6916992e22ab86c88a4f468f357767c49734bc96bc3a65f +SHAKE-256: 65d7ba4ec10a109da4f0c3c497d93ab828af47114be3909ced793287c78fd509923775c11abfe1efd55d0f97cb574dfbac7213624162798d17a5608b2cbd6c5ed678f63556cda0f6aaf1d0bd17308d1b64bfe46d23bf597800b8db890a320b0b04748d9e411c504656fd9a59230c618554594919277c9540c007bd7c739abbc9649f4dac08924da16cdda44f1e7438e5db45be387d4582dbf8bd0c3d69d733f4e449fb3927d4c92bcd83a7dbc3d5ab947a7cc4af764c87a8eab5c6a4e4269d609f754c33ece1e6605091a5a256fcf857e26a32aa5a966aec319215d0e657feb4eebb371d94614cfba129fb1a5ce4e6628cf5d23cf8e4b82a391d7791631f19cf14892a46269ca0403fb443ad69c8ebddb3d632287a13fd3061cd949b101251a0606ba2765eec3efc69ff773d647c1d46fd9b58427c5ccd869f3ad69cf01f33219bfcbaf0f4045616103eb85a2b1e22151a976581413d74906a02ed8e55af49f02baaefa899296c029cbe6d0f9eedd889098956dd3ca35418306fc84a9849a443680e68737ff42a773b5df926af978e47efe347b9dd4298dc754543b01da825080f5dc8dba3e11a35b0fda36295d83aad35c029bbd8207832653d283f9672121f0505cfec8490262c1440cfcc76a083560ff990704e5ff290ed7e13ae76a1a2b86ba99fd2ca04355f056bf2df863f6cd972c690601c67d7d0a004500a088b6c35 + +Input: 813f41dfd4c9156162d12ba613b5fd841b5dc1d8e10a1c788053caf1296b9ee8921bf5f88faa60b181433339e8e7d9678c1966169eafbc6bd0bc9c1effa9a626b31989b00b271aefdcfe39072811982fdb8c0056f36382034c77e0b08c684e52cbeb9ccb809e1391ebdc437d8dd35f3d2c58278f6fe74bd9a27c874f8e6da38283bc2ec684c1bb704d319fd18b93d74532f1e0267a2006c85e8708063c989591da493c6f02e3c9e0f0c651b80863ff9acb69fc62d035af13968328a2743a79c9c9ea +SHA3-256: 5148058f32fb9c1fcb6089d066b51b6c00f7b83f77962cd8724517b2fdee452b +SHA3-512: 8cb913db601532a5c94adcd4014b8e322b8633a0194bd3a3ddbdcdd2e98e65c46f84e6a46ab37f208c5b77eb698ce928d95da69127991d80b5eda9e4d740034b +SHAKE-128: df8cbb80b70498dce78715761d85418c253cb7690e35635aefc3d90694b1237078e76ed0e31941f2a9d487cc3c7603f688f025cfed8f5f4ccad01534c0ee32f7abf15df3a3ef5f7cce027f69e2e2514868a20de044548e4dff4f8e58d01db1d69698b7d194c85d22641544084d40f01876db496a17578ff8587ae0df691651bd54c53451e5d238aeeea3ee5f26a18415e91585548600e5db45749e8149949721ea1cef62269e145c974c29169004a09ccf477431c86ab0c2d5d65a72f3e6f66099f65c27a2eab3eaf7dd71ae111e3689ad8bc6534ea9b50d772f11a84912e01bc2307e2453758af9facd3edf567b27e34041fd1c5c4d60f42a33d2194ffe2f290ce0d40ed950e2f23b8b10955123a22980bd62ddc2dd60104529e98d4377871eff0a4d41a156a36d7a60502c42bcf2159bb8e3f9514e7d621793dcffcd52133539e87b361095b3d35d3a8efcbebb3469cecedfefd04f74269e1c0bbb45974a8f20f739e071a57f68dd7c4ec97f2d73e7761b8b98c323ecf317df1ccf2aaacfbbd48df14ebcf6f3731168d0835d8a1978ab0a2fcee4f05dd4598925b3ad3b4d4f833b411ac94f77cd0ce8c7d20f5bacc5e58ef3acc4771e8adad34f9f8d0fb4e9eb21147f6036451686971a685657f66a6050c8521f9bd63bf95a3411f391f194455f995e63a6cc64cb6e6079773fb8c5b76e69e67f839e90b0cb43ed2b161d64 +SHAKE-256: 3aa310d6eef897603bb83da327ba5a17d1c1f25cab676b44716b0616e2b952bf7e75bc6fb6e0d35cdd5c069f4958f49765471351c22b8c8364d2d4904d401017a1979e62a6f3fceea2fa5010bb6a58f09119e22221d7a17836b2959f352ef0caf31e40fceed17c0b44ed073e6e3a9f93d3bd62d506952c6e74a4b0625ff87827d90735786a9bc1c49c91a3f40b0128e067d9d629c8d0d57a54de59477be1e3d1ce65fb7bb347588092c76bda804f9859cff36d3e38fbcf14e600754911aedc632633e72d08be81066805fc21095c1f23b8f1b971353d833de5d26ab303be71d8c24aab64b4a9e277b50c9a638e6b2d76ba062d7843704770ed8c9d65e721776a4769cfb5a5f913aebd9e51baddf47558c358737b2432c01dc139887e03c95432670ec8e08fea374a2dc09a75ccadeedf1b05e3e36243ce439f13bfb55a967f6475387cfa4e2d700081e39d851a22ed3d3ac64243348abb6dba8702d5e65afcfc19c01c74a7390c7d7c468def7702ef3b6cc53fff88da90d3fe103fc2cc6eef36a6dc42fdd3dbbf8c5856a29a011e169bf0671f149999783f946fe59bb2041784c5cd76cd1e5b4dbd56cd28bc74f24d0017ffe4b4d9a665f934072a9590dc853db6ddfd9051d6e529fc2353f1f2191ad8359dd659ff602f4d5765d8d94e1e96c338b11b12e5fdf887dc8a54fab4b42b6b3dfcfd220e65edc21e729d0f801e8445 + +Input: 1e083d8503d7c48db022d51740a43180f75c4dbb323ed3716572238015d37933194493a66df59ee752fe895be09df7034b1f292604f536cddd6ea6a2069324964d8b3e90281fc746023dd309bde17ce32f71ffd765bede2731bd595313039df06787ddb0511d6f19f811be6210abe5fbd3171fd03eaea4bf80c5c2f6550db01b9ad43e9da1fee5e68d7ff8e6af51ef5c25a078b4c9dc5cd42202fe7d86124b332091325149addb5db19a0604fb3a53da2d61c21c05a4c01dfd27e4be4868e4c4e26a4c +SHA3-256: 5274a8c26b5b6a43db390ce6b66e77d397276e8fb847293d96413afba9ab7576 +SHA3-512: ee422e7c3db2373246c91977eca12506fa2087e7e326cb77aeb399e301309ea3d0050278092f940c5a8f735e72811649bae58b0375a373b3451740bcc082ea43 +SHAKE-128: 5b061da038e8ad8a306e6b0f1714373502cb44ea52e902b435900b754a9ac5d189b4fd9c0c93dea178cd9606a5f41f17f44459027cb0a1bc3300262c10b661588ed627b3a61320adc06b1eba37abd1eca8df5f42c57928dd4cb3c1e12723eac718be310184155709d2c2eca08d6769717ae2412013e5b93fff39329f28e2fa8244a573024c2fe46cede32a708ed32460ff87f921340f9ed1ad1ec5ed21bd83c7c23786840b86da8823f1882e9e3aadc4580170afd824270510869c6f977b5841f2bf7fdd12574327f5153f579ad0b7c6f2138110cc7b1ca3b0677d630a1c2eef63840b8eeeae20a892561e7a01c1f9a8a7cd148c0c37f1857e7b7abe308fbc09202acefe351ca5cda325fb211ef4f92f1ffa23ea6394bcac2468865cb79b19a857405bfad4f9584d3eeb74d1c1aad61eb59586fe2c1bee6a450baecd455614a30daf0039c3e3ef478a0531702ad3de38d1fc24a5757275a3c47911728d283191507f3d10c1cb858d7ab4546401b1d90570001a70b25ddd651ce0b27486eabc9d79d9024584f7f1ba4f04e134623a5826aa0e5e3872e7528341e8191ae501cfb66a7b5c6ed9ce69502f91b9e7b56fb7f71059cc1ac1502665bb2df8af37f06b1c13c89a2270e46be8b932c6e6bb628786b235dc5d00d89d163b04dfb46fc6f820203b5a0876707860c5ee968931742108023697df25a0f175842c807404e08c82 +SHAKE-256: ef2c4f70fd8ad613a8600cc3cc4bcb69869931718174eaee73c9e3143569281da433c3ae41e9c07ea1fed115ac69532b5420766ec8c6143f9069721e86be50972018c53a5dca28e454a968a144aca08c48a29bfd400cce5996d68fbb40ae50b93aa746d8523dec0ea27bc3d75b3becbdbd567a0c0ad56c9b20e02f92b3136276ffd6390e6582de5c747692111ef82428f7d928ca1f03eba7c8f2acfd66ab6cc1f72fd0195c1fb13e179d78e9b0755a7bce3b3012d95bf27f6eb9e6139b43774a063809c85ff46f2557b82777c7ee5a4b0c56ec9e07bfc65446b0c90d1e47125858bc3e6ec7f5f20d81e54ae840b0b3f914b2402f42ea382a6f7e02323ebb9cc6cb69f71741375bd8dc875e1052dea88122a04d7d1fc834898a715d12da44e9a96f374be029a51b458d6fbfa2dfb5e3f9ebb54bc91fd587f207435ab47b7aadb04f8db88b4638833459be0bde209c739c516eec99d3a88560274156052fde5d7ba0ae8e22fa32f0105506ec2cc63cb09c5620aa29dc38afc5fa67fc1f41e70019411e224decec579b7eac231d944a5798801a29331e3d7bfcd7dee35a08207c971bbdd8ff53ab7634247ab7a1220e43b241f046b4e33a39de6caec6c6c5d53a3204cc4ee0e4409236d4b218d7d3b13fb6d4565f503fd0596a6466b070a3fdbdd9202a8335c476dbef48c0b0be4461350bb6c31090dce45692437d7395d592fad0 + +Input: e0482cd9637b3ecb98689bafbe4902bcf68349266024ed6977c7c384261cefbf7ab8b3dbff48bd113da9a0b8233b4bab053b3cbde0011581475e08af5851270e3059129352bf9847be41a2ebbbeb39de41b03dbf6def201f2bb85617c898aaf9826311b60978d3b85473db52c5fb98a5d5c21bf205049613578588d9a918fdabb9ba86eb1ea5b864ceeab4e74fcd57de08c622201a6d1fbe8196d81f10a0bc24a3f1d0a46a6b372f5aab739de0480b6ca4229f8228398a47342423937af2506b25d8c933 +SHA3-256: 46d65b033ed9052ddfcb83d7156fc6ae508eb34866f913d700d15e63c820843f +SHA3-512: 574c34b762deb6fe975c85dd0b3bedf6f2fef4564c9d6de70b8b068a7b261e279276a25c0e8a477c7ef5af725b5b561fb32b5d1527666943dfc3f6a5e250e122 +SHAKE-128: 9fc51aa88f7cb3ec83772870dd237a645042d6df2aabd204be6dc35cc97d01518a5e6bff843e25d7336d666c3d1f6dd1ac24ffc588f3fd730f500d2b744cfbd28adf97c7b0bcd467f89998bf71b18e3b57018d094b3ad7495176e5b1d9a14e35c20bfec25cae782692437662e00b912fd68faff13ed01f235a2fe27e54ee24532efd10f4181985964238422336f9fdd87f5391b45d8071dfe045e172795c2e191a529c701373af035988c0322a4dac427d9c742f4140dc53f43be72d3598d4bedceb409763de8173ead4318dd0290064a5bc024044812d08a9d005ec2db5f85ff2aa7c88037d47a3ec7998806675a99d0a55b0160ced62eb1eadc9081e60e37458e282a6ac71c19641000a8b105c14bac5658a0bbb468d5e3705f4641b602f7d6da8b85ff42a148ac5624becfee049db00294c742b86d231f86d45cf12ce3858604a656d583f7e1f941a0be8abffb6fe0fd512c849e302c4356aea943cbd0c0a68be3222a6f01ff3e99973bd0dbad75bd686a593c0b3babf32e1866721e06f394cc2073d69871ba3f7b6476f080bb084eee55232a43f710dd38b216099100f178b4fbe4e391e52087002f0681b70432cc1fe2cb59aa892ddbe8c6c84c9f91074efd314ceb4eb6224d8f5296d05259ac6a9069b5fe70799406ba45ac66c44907e6980e295496ebecde98b933650674a97e2c6b055f33e22b362b757895c08785f +SHAKE-256: 35857596d7f139e1823a4051220a58ab8e64de02be60795f79d3c63b24eae8f4b3eb9e0f2b11639478e37492b2151a753e546888436bbfa88654984da03a8b884d23a367712ee3b48fa3ca3a9a1c12e24021cd8dcad7e80a212d1417eedc95e0b57269e88793faf1fa7828c7c4b51519eb7d1a8fa376c2f25999bef8c3e094c53b08cf8e7565a041754f6738451facbbaf271d8864f76deb374888163ebf38173d9559e52bdd9b8537f008a50782ca660a8045cbdd1cf77c50c8ce0bbc839f2ddfba0fdbe650313a38fd95d2530aaa00b981c883bd1906a816039e6aaad2c457fb6e2a53db73de99b2e02f318ccd06ce3a503ee8b1f616b82f5a01653c9db9fb9ab69c53e1381e5f814abfea7a14dc93893579b1d8c372b049fbb49cbb81353f7f74f34eb741edda6db638748ee0f89628c169274dd33222a457dbd24a9fcf6b37a0a414057881a2de713b49450637b3c99be6509e65ec15073c4e0531bdc57a0879172d49d8b427efc8c8d53b43cb151d90955ac28c9050777cbad83208e4795434c3f7445a35752314a245fad4ef1bbe768b4ca527ad7b8f5249c8e6675214e904831fbc954801b5fa3f884659a66107105215d76652a0c6b6384700df259ac81fecd0ec463da7a96f02077bdf2c3e41fe6e09ccabb68474c06c9632d49a5ec46996860df1d171b06dc4084be93587d6c6061de2994bf91df3fb1d2fe6521f + +Input: da354b5b145fe8d279ef57c1ffc190e54ae3386c41f79f685927451de567ce3da8a89a5ff9a29e85cceddfa48b095d9908accd00169afe739ab8131e6c7bef7fb6f2c9380aa2e35533e8d2cfc12b3f3972d47407af698148015c4b9e86de7dcc0a345d2017ad132415f9635c269c03a15e1f2c82960b153777cf332991ec4f00b1c73a482ca248798b3afbb3e9d267527b5ad8d78eeda259c629c8690a074bba24ad70be6aae3fd7ffd216ef38d929bc266e5d8f3f49f4bd195262fc7f315be312cdbaf6d1 +SHA3-256: 97a98967e5c1bf185f61bedcf054a33383213388b711b1fe0217e8bb8aeaa662 +SHA3-512: 64e27f30872dcc56c84a60a711905bf04f27dd83e460e16e8c4fe738155b1d227fae358b35a60bb91cb82841b337407ff82cae312bae306707357de765110068 +SHAKE-128: b4c955488c9c70f4ccde66fa6d1e1f4c32e6cecbbe40c8a655c5fd7be3d9361de91a629a9e3ec56106e4448ee19986f4d3a272f00db7455a238cd5b7812b3c642677b9dceb2ec47407b47a6921867da026dc162cd22586b435d5bd2d92a53040cd59adba14a283d594de2949d88dcd7656154141cd2148f7d79b039a8033341150f738eb9850df5e0459128565f2bc7a34939c0863348b5559c747c1fbb30d3c825486d3a6499eb82d2d9035b0c861edafe0c9985a6c6e6ebcb0cc8e878af93f2d900e3def53c5adc1e8cd45d7c9851b6dbdf290838190219f7fbda2445fc739eb343d09b2095bc65022b760448d957a09eed88c8a8e3ca1c432df353958ffa65b400d0a6714c84f29fd915d9e68ea8117984ec4671bb3389ecc3878187d7a5cd7ff8b6983639264c0db436113c2bc5b5b999d0479fb8d77cd2c9d75e05503cfe2a16b3312c61196cdf5909bdad3828932ce271f6ebbd3856a9241109e5d70fb326fcb495b809991bf8777fb52a2298923fdd981d276c1091a87b1a2f7ef87305177c64545663e568c06729a818e636c9f68a9ef6c1b4adaceb00a6d0927f775dabda4d553ba8ce92b49f080f20b486d3db1e03fbbc97dfc892be248d6dc2ec0190d9fe575554c1f617d40a3cc7671b8bb7e1adb1ab981b702dd50ae396496918d91a69e4d978b471aee8a4c8f2e346f144d50c0807532efb8faac48e62c178e +SHAKE-256: b0d33f40659610fdd9da3481e49bd6d85676983df84ca10015c683fa41c5c4987064c14efeea5365f0d3c1db4a4b1d190ad9ccfbab976954f199c297ec9e111ad423adae6c60ffab04ca6aa2623f87c1f3c5f5771a50b24f730fb95e27c4537af0b277718fd5087d24a005d32af1c177c1c387f516277a5104b9170efdd940495a4f505af4aa9d20d83a7ed20a113e422869515d643c905771bbf1fbc66057b119f1c0015898b77c2d68c0c6e0d4ae400c7377eb9e105929f6a697b59fb047121a08727ad4071d66143de9f7525f66e6f218dbe4943d382de82e025e49120c3eb672036332ef3946cafb534f0b3a61371cc60f3a247aa559b388947c364de10083f9292d38a2c77107550003e32c10ed783db383487873e95bb33c30c93756a2f2675fbc865c1b1f21c83247f1b87deae3f54171a23e515f1a4ddd25d1ea6a239325956c256529ac8b23b8e163a42c780150e10cab3f372de24b8cea3679076d02a6c4f63050846d7e486192fec2ff476ccc077ad3df342f5b4f6dcc470884ffb6ab30d2c6bd9a140e20f2c2073cd8bdea4d32286af4171ead433a5d8b9232975bfdb17967619cda8a6a7e04415a53c6311d7ebecf907328c550a3e476a4bc19167607871b6a7fad12fcf6844950608a0d2da8e02a69372566e307c11e771c7919633d3cd3f11af57e11b9220ea52d2c498bf44faeb0f4a95b0a8e1c5e216176 + +Input: 9eee7ec7995143ab91f18a10856de919ab0c8e4351ff526602cddf5d1290f1170ed5dfe380f2fae2530fa3d7a364863b8a28f098e5effa1f5b4c037385bed19fd2f7eaa89c7ec5dd1a17072e54fd1ca08383b82832767595f0cd17f9c4c82144f8aa15819a7b6b717c68f4769184a11759e43676d7962ca908f890cd97212e528e803b4ad3b32d75770648183ff09a66bd61d2042476d8daa8146bc9e2056ca0bcd88e5500f3b2a4f203f4793a67a1adfed7017b377bcbb7ea83b75b5b55aef32c344c3b439c +SHA3-256: 24d80d86bc71d691260d314fabe74d79abb479895038516fb8444f0f26d035ed +SHA3-512: 108c1fff5e4868b72c93b566fd6a7c820b13429f4fdde4b8e471db26fa77678bce206f86e563e3349e6b71f5e0dc4c5845a910157557fb37aace562e6594b177 +SHAKE-128: 88513577e4d5149257bf04b88a44e7e54e8b411838f0f5cd464815e21eefa4ea3969e9c603f84750e015e34f000cfa9cb5e9f684aafb31f472fde44a6fca8a37097826fe3db0479c9e210a9a945ae8d25f7b57b3ba1a622da1346faf118e76d0939cf1bafe5bbd01742e710ea31200d67a10a9d174eb7e9823de02f94878daaed0ed4f1ac7c83c663eaaffd0dc3ccec83e9cd88e8f5c54d3042022fa380e1f8a06a37f31cb1b44044d29cb6a25269eb87bb4454aad79929e574b170ba0198ec48584f9937c77d33debea9e7b1770bba7cd3b2eab070030c808998b165c80c4d0f2360d38b95bd79fbd351cd2fa8c7c51d9d8231ca4ff9a4212a1106843bcbccf5c6a92d21cc5d12ed5f99b04187f1fa127ab7580056deb155ca8bb01c4582eb7cc31a38dcc2e458f4920ccb824036344b4f7346b10aad5cfbe2357947ad4bc201b7162f7f1a6ef9cb35c498bbb662b4554bd598fc49da51bd5c3bc6b7fd5136c28a2a0fc6dc4deffd29d06145992e8004a68b43954d299ba126ee8fad2bfa42fac521dfe776471f6d536fd7b4727abfd2fc3856c8184cde6b50e6b73283d952a2a29ecc32987935aff1571864dd304bc67ed6d00b8311ddc3a452c686f551ce7c74800ccf4d8813c0d4dafdc5f5af91e5080b709cbfb89083e5a413ceb0e70c7498032a91072cac643be57b4d8c5ff4bf864dd24d1c2caa581f95740c61fc9c1 +SHAKE-256: fb5b8ecddf4c95c106426713d89b464a66595021ed53fd17fe012a9c37eb8e7d54f997858b557d094ce8e1d18663e7c2ff124e594dfa050403345e99be4e0e8cb3c713da892b3b8754802504619489000311bf067702c1a21a44261a701b21b6ef182d7920e81f2c76cbec15ca9740708596eaf7b1b878d58d6c1be1db248bbcdfbd996c2d86e5ca779b1b72d0e0265d76ebd9f5779779e7e986e177a803272ea9039e2153ea8d6087eb984f83a63a1a1a180257250c3a5566e0a2ed4aaecb04e0c1dfdd9e8684e7366ac1cac6825d96e2ff5a5c8f5a365d09bf081dfb8848f96e33ec3183e308313635ece78cc1dbc1c869f0cc0bcabd09b8ba6fde3ac36b5ef20583f45c9439a98012728a97db2d65e182bf4c26de201b557ab92d041d2747d805f2416d5c911885d84cb3b12b27b38837f923945c36530f7ad3591872dd01231c23923bb5c2f31aa0d1c8c9252aa7276bd53784d93a9ab2804964a5170b238892ba4343c82623ab20f7eae286f8a379c4039a254f15c9b1955af20e6f5a2364d170b9524a51e91458a073677ad318f35e5653e94dfebb18c9be6a5c07588740578c93bad4a499a1f6a593b4e486e961e1107879bac965d23975c58d4cddd0c8fe31ca6fd88c95edc7bf3ea719b973583d546139639ac44336851d2a527013ad8f4f1e623c77841d803f6d0a40ec6007cce49ccfe4f72863a5694fb9db5f6f + +Input: 1dfe1b84fa65da0aa11f623559ab798a9f4db7e5eb30bc5f60be34992c82db2c3187387140a75ea2808c04bfb844ba804b595eee1fdefff58a896fcbc2d09304bbf8649bfc7546ea5573dbd20757bbd15834f3c54d7535d9d190d9db705996575f31c59486950a7971cdb657f3f41b307de24275244278a183b6472e3300795569572874bb9d4f7671c04eab276ee65bc83505fcb0a207db459b0e6cc47741b0ff2bf60e8cdfad5c557662a6b2e34a395d817185e007087e3875d73a9375d8528e06ac677cc7d8 +SHA3-256: 555e373ca90834513542b22d2e8b3db8877e485d749c7f73fa40cbcaf10b7ae0 +SHA3-512: 035bf9b5af6c98f72961f939963278fbe547ec06689c6ee9adf9bc7a8a2d66c501dca0cd5cc990653e96acd7fe580d06815f880b3fe467b6cbe892647ebcc62c +SHAKE-128: 1251095f90fb3b5069aacf203606b628867505de921077a0184ed4cb954cd6ba7a801178b1f0a524d878456007737a1506f582b4f369b45b656556b4f4c7e72d07db9485c0c9ffbd30064a5e4701f72dc078cc43afda6fcf74bca6e1fc611b542b48c67905f551ca2371da1bdaf84be20f23c89d5b10a3987d5eb110e9389b9953420a4c48d846b19f21e38cb0f089e92e859c3d2fa6e7c2e09f52b9d0e24f8f4773469321116de360ed43b6f4e24f7ffef7e6a38d9e7c9cdb54d6b523b1c1eab75270e313e5bd954a363c47b6b7df69cc9f0b36ff1a944f032f1499b00e138ff21785ea68db3afbb00280d9f11accd7178a9739b5030371652feaa0bdf51cdb5db7321735626f55bc2f6daf6b7bb1d2bf586aede1da4adbf7affaa946774869bb6ba66fffa7d30a11317299ba26aabee664614e000ad0ff2c6abdcc3354fdae8cc3708efad5db14270475642cb45ac91c99478c98ae094197becaa7765c6377df1b5a51f633feb4b630fbc09dee1122e18b72c5abb4d0c3666816f9712c0506f52cae9cbd8435536c0f0c5c803c656de90ccad6efa872050182a5c838d45c98245ca10887df2f05eccd820b3e0987af792acb1a90b1be3c52dfe1a6c720966f54a42eb4acb8aa7fd81873062fcb38538895416819817ab0f4eafa2f6da4ddb4e78dfee3fb9d5cfedb0336892ebf89b7525d578ab6e66b94a4d0e9e56c369eeb +SHAKE-256: 81fc1f79ecf5f5d228abe7bc20670e477bc9a1e4cb65d168e114debb0a0831b2750cb4603410ac58a77312ee24a77174a2b8592a2763cea9ae3c6c714d1c989446bcc612b8ac296aecdc9080e62509ac614dcff0d806e0b9e855214e1df18166a2f1146e4c4a1ba475ebdbe6affa66561bac4a69ab35fb645332d58ce3473c822892bae426af896234ff66d18e512682cbb953c63cde1fee6760ece353aef70f4961c3240d4739f830133153f6945333ec87dace6eaa2589e1c541eaaf787ea42fdf34dbdc90273cef52df7debc482587a23f2e300305246ecdbe2543bf7c3cdcddb1c0b85f324470e7d6976db3c17a36e7197fa5e7106e189f1f4c34784686e51fa2bb42dd7ea78a6cba5ee7cc8136151ce24a3a376a91509ac6244648fe5e1926151a5a2bd0a90c1978a529a31f5b5dc3dfa21b02c34f1a4ace5ff4048613b5ad40ab7cade27e1cb2d9240e3a49b1f26acbb652977f19e1acd7e8db9b4deb174e941d55dcb23e277b9423bfa92408702159edb40a173d134a501267fd4412320a0a71cd5c633d4d9a9366372ca0b966b3b0cb260f3049a7bf969eb8d1501b4d9c2aa210c227ae4e6ac30c41407a9823c18ff5b9fd3308fc14b6c3209dbd9cf45ee35bde165031fa3c72d652b3c218631a82a78cd1e835caf917f7ca1f4b03136b2388de081ca80ade58d6d6102c5d8ee75c15a6739798fcc02411f3cc5fe82 + +Input: c11927c2ade33bfac955afb6dd1338a45396a761979a1d3e932ecd62073b121d7007956a12a4ee09701864c6c781a834278e0923fc0449cc14316fa7c89876261e37898bcd39852b8a78ad233947cb0e62e414cdf786ad89d028bcfd6e1a53ca0e197ba139e15d811769b0206696897b489ab154aa9fd0306577104f8fb631f398970c945b7dfcad247d6aa18564144f27ef7c13955a63dc24794fe8600fd2880a21b29aa55d42a0db2347bb9ce54578a4b023d98c7933cd921c3b7161f6daa802ff721641d0fe12 +SHA3-256: 70064735defa8642da9cd774773c55463b81733d850125e67c2aeb08244ddb85 +SHA3-512: e4fc0b3041f7298f695893d173d94c595e2c028fb7b23492991a20c3623b2d37f244d92e27e639a7385d714c3a158f86a191672e01c35ca1bf5dbb731edf4bd9 +SHAKE-128: af57c891100aa0089ba5d96dca42c084eb3b02ffcdfff0bcef8642b5000f2f4cd2021d76790baa1203da690a02f7de4cae0fe95944273834d11ac6bdcd002d3e3fd4121ae98bea396298e6ef991ac9516b4511b57f92137e528b991fb81db14d58ccf257c3d37e21bfea541f490edcb0bf6e928b3385306e70de9dee67ddf099d1f2a2a15f5c96a3b968ed88f50380eb874ef1ceff02d2e358f40a2175ada198f8ce1f0d08f53b7f06f2bee6c789da385696ddd986d14211fe3c44e877978f6fbfd4fbabf0bb80b222cee8c3085709961827756a2d6f1c0201cb3cbb834999f3e862d9f5ad035b943f77cc23603b72627f9bb29c6fa637792cf50721d6d0cf434dfd973de2ab35fa530fa7066db37562b97a7ac6dd107b9678072db2a0ceb728e95e8b480bce123e43d5f2af554de1a4aafe3a6d31c26734338d75dc8fe8123b5f8a81105f53e06431034cdd5a2ea7e7d8cc641730a865a0b4dc507e3fd80517f0516c764ecb5b614735b3bfa0fa5d04a047589719852d34241d62278725e5138741c2c9de6a125be04d5221d747a259c4ba0a5f235f35fef1db358d5558d37c6f9999d894dcb123991ae5721809ee14fba97d30845b256a9901d7931e907888b9c175340eae9a787144220433178e48e7e808f8d34392674fb4ee6a2cb31912f7e1c020ef1ae906e8d2de77db4d4a477b50ccb245faef6769c940c7ad7d13eb +SHAKE-256: fa1c24dd4017c58cf695e7a3af75856547d7607d2c965239e5e8d206458a9754eb637dbdb6b48d9443972d2f51834e6435c892a64f883741b5f865e9d60137f2386c75076c02992bbab60d1031f35c9e7ef6e3708d5633fb2f14efe2b4488e0996c0a45a736bf89b217ad835e9f0819fe9bbc70eb067930a3c6123e53504a8e2ddea81757784a8d80f9c3f184740ae825c11ebbc9b80ae3b6b4bbf993949ef8ce6acb1f32a6a76ab2de4e89d0c4a789d9c54bf8fa6a8725bf5ea5094951cf5a82820e830cff670bf54b92053b4949d5e10d5449d2fd61cdca8750399caa0dd4a169e1b00206c813400ce4f9ab0bba5814c601d70907bbc6b50b843997a71f2a22ff28e005d5825d50f92fdf29125e27b6e135c5991326a3aec15866db6375dabdd89167838ba577e38cedd0dc3c8928d25161bc263843fba41803dfc4c3932804654b47ef01c54deec99d2e5f2f24b7d2bd1aeb7bc31cc57745341fc7035d802a5e5a09b0ee292c108d37cc63550ea1e418d57e4f0a90f275325b2b61476580fe8f3ba8c00a7fc77f8a10d702e7a399fd47cbb0e29471cb1ea549a4f7c99493883cd01feae1b30d640969a3eed8e960ef9ac59a1c3f61d99a019e5a9eb3bbf0e85ab700d536846b1c683bfbf59359b02e911dd667c461802a303b995e39ab16b03b209898b65c58897d96467d7a2898a23032b9850027f6ba1cce19e1e540580 + +Input: 3ddbef8224fac0a3af319645757f8bb76d06d8d4375dadc9266f15049ff28b2bc14aeebbabf0ccd4b2900a1ffaf7d3091a17bcd7c0f9e862547d9d664ca5a06073c21145d865f8b7a23de1104739b2d0c621fd6702e247f53184983bf91ef5e11bc3093e697409b59c90981e3ec8414277ad7cc145e4d425e5ff04ea76f6501f5dcfac2075c46b77209eb16e02f323bb9036d0ba48ffce32f7e3c8563da166690fc67ba1719949809be9e8db9a4cab38ebfc9bb2877626d50630e901def90ee9de4babb76e6ef58834 +SHA3-256: cfb5a1a201ce6c46ae2f6d6d952ad0a9324a731bd22a7661d3f90dfb70bce7f0 +SHA3-512: ebb6bcb1e163a448513b4b071ba0c1b5e803b3f127fb3a826aef9ad3896fad5e328aeba88cccc04f004f7e9612f964cbd69601033a0b4db574b888c87c83005c +SHAKE-128: da74c87906763c794c091913c641a50c9d6e2fcf130122dc871792043084ab9f294f98df4d830c863e975f46fd59f699e847eb4bc03f2ed497e884a35b97930c1bf6afdc4f7e48cbb6ef5f0bb79dd3d573894ef4412f2a77595c00ea7ee450a1add6a9bd2dafbd49870b4fd27b03183ef2aea104649a6c7b8b9dbddbcf72c9ebefb50befbcdb806c2aeedd720960e51e72149f58107c75ad1a1cde245cd6f26c5d6ceb1ee2ff215b714009ad4b9ea54c25f912e5c4c59e03dddcad67b5ec0ce1c1069bdad4fda097bc354d88c99b888aa2097dde3d07ed5177385614ab3c696d3e72ac8be12fce9411b4d56e99fa4e44609135c5e38b6ee2f19e328fba3c6168e849c51c948a005906ea4d0392a3b7408fa7278e7f81699337d787e252b64b701fe4bb95c86749b6d7ab60cb5cbf90ae04e8ca24cd4771bcab5c95a5fa4088fd57bdb2b195c01fcb52cfe2649800ccfc6183ea8cea887142189f77f6273ecc164c452d885cc3e937fa72f9d56891d1db0291be75d7545a76c79f74b943d527f7a7d94d33e0462483cc0175e1cc785aa1f3cff67e0822d7ea0d38ba863e7101410b6cab3a7459834622d7391576307722d7ccc92cd4a63f04aaf5793bf6c59465315d66abe2cea88e197196e6587df6841c489ec1eef137c0fd2225d235ceadea3fcf848acab3a0296c7c4b85048ddd3594ac95cb7983e6136af8dbca72a0c73e +SHAKE-256: 3e6ff49cf6311f87846ee961a2ee2ed2b8807690da2371493c39af4de9bd3ad79f44860c2d8441fcef8dda45215de8211ea00c1d55b63ea359d141366991142b9719ac417617dddb93af36f8ab53442513f3ac7da455c516c3174acd05170f4ebcf919d579fb526750ebf93db79436ccd87111d07a367c66fcd5a5dcfe197cb257af736938169e102406bca21f595cce3e8ac626048619b0591fbc8251a7a8f4381a9e2c7a9e5104c6ac675f7893b096708f969f66e6e308067f746d4b3e6a2085390731c70bb6f48fbcd8b5cbaa239c8149ac4de8fbeed8c4b4108cdfd615161815b0e2443b958f1e8d22c2294eb6cfe72545f1a6c85fb25057ed6f7c178f89b37f962b5f43a343fad9f2103977fd00f2ed5586bd6e5495c7d79e0b65356d9e2334992d6b665a3f6d179dd8ddf238189d0248bd2c179192e07ee1eab5d146840ce4963767b3eb9bd5a3cd97016c7a367058781a81d6e46438b8789327b36295cdc7f3eaad4595c77d1a6c471c525fa074ce97b6503046ea81a0e0c9d42bdb7a44e3622d3a78ee8f6eb5456eadeb267c7cfb031ac2002494b4b431b96ee36058dfad76473b864f02d2b4574710d931c852f9cc83aef2c3d02959d614ae40738bbe4a41c60eb267a2fb3a8d50aea90f7342efc658897019edc441e611fe573f920fea4cf93f291d2ca90a36fa4c9301c6ef45e68ed11c7b861553712cd2cd4be7 + +Input: 1552163018398990dbaaeb57388d99b163d50f37ee846e5bc1f6eb8e7c22b0c2e2f7e8fa93194a8c5620cf711a7395a5f27deaf8fead08984ac2c06f4b7dca2e131ffa137b8cff98c116a333c0832c8745c8704780eb11b7bd0a418dab3729ab15641fe6a379b967e9ed04e127b1e3bf8f9a20d14d4942530638f9a98c40b4d65d85b9a48b3260adf1b87508e46501590322c86b5fe8502d33fd43bc53563942bce57696ca83b5478525056d18130ba9fd3a08d5f8159e3ed608a2d2ebbbb397fd1f35fe11a8f2d98dd8 +SHA3-256: c07bea7da35c1c005911c5c44271fb322a0ce939b2a76204ac5a2e6430a216f4 +SHA3-512: b1e985157bfa9a886bc7420b478567f08770eaeedfec0a7db27fec6c7ccf2fc6fd83fb652e8b4ff3abae6adc8f4e6788dd1b772c6ae40219979f1447386fa682 +SHAKE-128: 831b543331de5abee4ca3fe2b6af5f96ce136c6b2c82d7138f51bd00339d1fff001a9fa6c0731831116ba5b6970d4b80b3223f99f311baa35ac8417569a35e9e48c844d598e11a6de2fd1cf693291a44be35c5ed86dceddd0d5c69e6f40d24509ccee1080cef50697277a3e32fd720b454915b8f77f1e9ecb274887140df62a715bf35b32895f3524eabd70742fc2c6ed863520117c3d5efa7af1dc2c92035c647f29487d0ff6712c91b5a55fe1206a2f3eed6445bf77838fb0360201d4707312681f166dc7cd35d3e3bef4232d6cff9ead031ec349fd7baf7bcf6605b4560fff7689dd72bc85b4dc8cd62c594cea068a4d1660386ee50ce13f5237e196912eb4e17e883a26f8b9d4ea5264ec5d4e13e9a6305460bb9f398fda9465ad2067d1dce5f91a0abfeb6fddd2483fe613c339ada084f177d0978421b5300b616c5506a57d4802c19e6d09b598ce9e48b8e1a4a7273c1e70f9c16ad833b32c3bea2452bc2714e9f9c8fa61fb9ec1f78544bba00f5e31e0aad09938b14b8a88227c7204055fc4a93f7bd3b718520576a90ceb3702ccdece515e08d4865a80f3a27d01830858f860f195dc0ef551ac474840539208157becb8da58110b668a32d8f074eee8d713f67619ceab693414b2867a338f20a4efc3351af77704819292726d8612a2923ebc2477c749fd31e78f78255e805d23eb75364b5925015aa3e152e4e3ff5 +SHAKE-256: 6124bed8a30fbb5b4078a27326a068dc9bb6761af1c08d88041e3203223a2c84b005cb470bd0ac9a8ed2e93220e0ec1164a078b1832a546713c1afb525b263664d78d3bc501d3a9c629eb9fa1d28d42e88801b8fa59cbe5ce76368729900f770d9eba4aeaf4e259691c01f5d1deea9ad47a3f1b7d54709c14a1521ffaf77a721dddd2dd737ac6455c9f006368c40deb09f560ca5eb5f0a3f08ff0f71896c75c6d7502792f807c3947aeae86fe9c99e9402e520777be3a8a561b33ffad60ca318ea4f8a537a60e86832514af902f34c01a11f63490ce1f1eb0b1a8253666179347fb063d6ef222bbbdc57a219aa305fd11f329a1cd4d182fac70b238a35f250a7159dd5a6cfa1271a1784beea67f8537a883da8f53d72a1556676167e906e24978e1f19cb5d3e3bc3a961943d0b5bcf211184ae2ef157b0e4519d3320a36000412c3215f04c7df5ecf6ffa29899c8169be7451e69f48d4ecf042337a6c084fa96f732d87c7369590f5211e98f2de5c63353482dd315374ac0ff73886e8837f1f79229ba02e9631ff7fcfe85bc768382100a10c5602f8b498f5e1159692087058d922507abf6255ace5b3296d66f1e1cf9f08661c7f8373224b1eba70222b8f467ee479d25683f6ec766e475a35e49d633af2776417de0b3205bc8810ec5f49c9f628fa0a9f3dfde39bb576d5c50c95392a4fcdf801ddbf70ba84a263ac3cffe47 + +Input: c11136c92b8d9aa938de9cc269696f4b56b0d5969756532cf84b34bb3e33b4a06a732bbe5a9533df3fe2531aedf773d864676ca0ff78bd62f49525a843064a59754d94dc22f7437ed9aae4c82f44f8501c0ac57646d031791b13f445d1dd42e38af3d0997d8795fc23de60184e86bb6dac77a05648523592d34d71f03a1e506e3eb1ecd3ad9162e65ec2f999c4c5360558923cade2540e1271b8c6396c21ff7c1114819e83d2ca25542cedd5ee9213172cf0fc9a4219632c007601b40b29043cac6d45763f57ef22c8ce1a +SHA3-256: a9500bbd85da11e66772d62d977238050139447a7620b540666230293edbc633 +SHA3-512: 1bf23364b4726e869242885352977179efeb38ca4bd01ec966edab3b2fc8fc7addb21a6f3ef1c85531b43f11d1f5ef22850b660878a5c5f9ecdb2ad72e09377b +SHAKE-128: 3ad5230641499a0bd303cfd43c8f5486a25ceb986f695c2487cf2822dd4016d863da65718be13ac3c3b5c255d041a8e7b38ba5e5fe0febba7134fd5f80be3e2d36fda40edb2f97c3762506b6ace923265e63e18d8e060eb4a481e870151ce20b6833880d3d0d1662c6804b1ae67ad64ba02388106a55eb93595ca69ab280b74694ae9a64cd3b5a981b85385d1c9f276b5f49021c0058a5b80be785889db3b77f387cfdd62856be020ae5c9538be2c20cb78eed3bc121602d4e61d4dda3ee12b912fc3ddc5f4b731292eff10bf62d2ab5afbfe92505b0f64cbdca8e7e2b58db85ffaa44797c4a87c32320465d5ade18d188d88e47cd970340dbc2130a38c3017287f705033c9d05949225277c4c12e057de6419c97ce053c767fe4526921c6a906e57ecbbc8a3e09ef489c824a411a6dc5d508cac57bb56e34e1f1f9bbf6865c60cb913d78cb1e5b20f9960bb86bcac7d62e39f7041f0776b23912f9a5de52eb3ab9ba7bc8b116549ccdbf9187ff5a49dcb805dc2e30a90f9c12d801aa34e31f50b3ee20f3962956a057abe903c69a4a417da7e9c7d72e03f41f2bfc68304b22d2c1f2224ddac0d35df43c816a23c229c1861a10c7e3d7b963ebdb03ec615208e11edd9f9e7fb72acce10394a40e0a9a4245ba256eeb29559a3af31583cfd4534d08b15f0dad0f9c86c809b2ae6b5f87e71ef9fe334bf935b8f0b983064c2f05e +SHAKE-256: 31698056280c2e57e4a420a83ba172fedf4105b31eff4f8c58a5d6fe9e1aaea459a86db294e8465276167bcf5518d315e976e9416da8eb713dfaf7a6f358acd2e57da6fe2ddf5703fd609e728e133d2baea917b41dcde4160db3f66d1f7f4fb2cd4afd8c9906966f62e0ec2e811c2cdbfb02dd57a1020ad5759079efc76df6802c2a39533edbdcc637c50609fb634f652f50d9d3cb550891d224b89247112d8618a1c43472029780236dc8c0ccc329a75959e97e3db96b256b3a70bae39a296624e45ec68a6f07d1f35a2b475e5820b927ddc3d366be7bdb15cf3fccc3a2b5f870d9505fc0a0fb1f7b4c4609470feb6eca4d4b572942112b098f79f023e512288d0acb55e3cd8206f81fe81e2eaa8996148bb3001353f539619b3954c0bf9392ad2066eebaa15ec451d92cf301b4c436132751bd43be225a62afe08666ab8c77ce9cd8b225f4df16346e2b3a6cae699a99c0ac98757de3c542d22d15021da522a65eda0414f4d58d02e62a29f22af040e0b3fad88a9c31dc168e3769b928d960fc4f560601a41b8a500f7897b496372f5c613ffa180d9f1f1c46a5253001d6d9d6478ce799311bc79f8d5ace15127bb06745ab2d56fc3b9c86e97ac268fbaa9fb73f22555837fccc7bf7189e648b60d3e6a6b1620ab5d5addfa756608f74c9e2c57b38c1e30311c0f92d12dc3b3368178b66318624d7668e6ffc613a6eef1569 + +Input: dcdb25ca178fc0bca1048cd3535960af79e886bb5bd18f9d2bb06303b891b02c57f442325e1756c303d66afd8ff8898cc724d2ebf82702377afdd42ea4463ea14cafa13f74de1a74da0b80dd8b0b13b77dafbc92da60146049f2474a9ff2f2b19c0e7b3a87ac095ba2ba3d8b57006510c7009fcb758e975410fc08f60a74c92bddd67d70574958d229c2b4d1697f85168e4bf2c1cb9fc7968b5a07cc944f933815bf4459353739d2b57e3feea5cea858c339f8f8a8ea7d9d8cecdb579fbed48a6f6f6cef538ec3ea4c9cf5f3 +SHA3-256: 089ff30b624db854f7b1b68813a85d4ab4de42a9700a086a99ee98d3e1ef302f +SHA3-512: 17ca2d9091a0de2115deb30de29fc4b1099167d6bb514a975a91b85ff2dc89b5736db54f0363497625924e61de83fe84e9ae27428fc181818489fdbec0ec4910 +SHAKE-128: fe8848fda456484b74f009c900032f96ecf8456ec7c56cf7c866c23a2c8cd23440d337215072cd579be4ce4d7d0bd6835106a125144a25ef90062b48ac934743a78d20bacec0ec3f718696dcbf6f3a89bc27bdef366786d5c5af6901d8d7c06d53db921b394289e6e01e8d66519a8a54a9410269de54534165f563a51725c66735a200327a19bdec691ebde7708631399e7e145d9399fa36437090518ed5825572ab4be61daeff9abd8e1a50d844c5bbe852776cea4e009179ab846b8d6e83a92ec2c3fdafedd6279c7d941c9629de52473244fd90d11314deccdf6d62c805d67a8750c07f9dd03bb0a407949b79356d89af5e262be5b47d749891063bc12fd36593f2a757ecfa430a875b7731b829e73874d6b83897731bca0f540bda0e813e7fbdbf8b21b001fde843e35578309ee93d61591a693f615d29e91a70acc8086b73c55e28dfeec361b0ff89d99a95c3284fd26e3605fe96d7805f5f67899fdbaa1921783ff4aaa2d2c073b885b8b96cd92a1e14b910f735dd82decc039b09aaf6de6f3db559d383788b63442bcea94ddac3b5861732422e961a177626b4c8786e8565825752a5697fb629f50026524a7452344eebfbdd31ee14543e6c84138a9407580da7f335467bd3c33a60db2e06e260d6c23b4c62fdb2f85a466cf29eef8ec8b32153b8543c6e809962ff4a6b970a209f0c51606c7ae69d02751f39072366 +SHAKE-256: 2fc48c6f95072d0e0d9e1b2aa9249befe1450f160d0cf975cc0204349c94a40913877efe8571482553435671f6905f530a72ad9b0a44c7d144d86b91c99a8c612c41a744d3ffbd08cfc828bcbd039e1ffc737d70627c02fdfee4ea93dff9cf70e64c096ab43efb39757e60999373e3b15b6dd7a35b638e7848a0ff168ddaa419034a058c9d16fe3593838c7b6d79c21c8aefb97d6bf94379cc09c27ed8f8c8274847bed48f5fd8bdfc702905041eb6855922d85c47e5904fa19356835c246278687bbc919e334dc81ce5a2fae0a58baa7445d005f338dc1ea4707d0d04721807c4f9e84e1ea9c64d95ceb0e8078836d1f7a732bbd1d0ddabcec2ccb76ec6c5ab4fc02b1b69ee86d30a970abe6f53e0cc69833259c9d5def0dbac653885a8fd2a7b55be9c9510465f9deb9204d08051bce870d0bc00d3a24d67826fdae6f29ad2984a119dfcccb41b008ae190f89de4da96b596b896f2a9b0764af0b3cd2b1c44db4b91ef1f13874528e1638b40cddd6c9b09a72cf901bf48f92917e977e1441f5488a0b13775f45fee7ad406e757dc3ba0463a2203463c7159d82eb96f03eec2eddfdf9ca6da3c3fb54cebc8fe1dac05f5a495e0b21c97c69dd83c9d5cd6ce881d51019dc93f7682c63dfa9d3bf3e0a770782edf4b9d0d0a323dab9725c28094c228b60c31c5dd207f05706f08b8fc4871d9e6c58a575467d4b46fb7ff84a803 + +Input: acd70a34f0426bf20d0264be87d453efa82054898d070f5e400b52bd53aacfd9509becdd9e415d3d25439257ed8748675e86ecf9376b4036b41f89a3e2bb93c939a95db0c24c27728a395e99ffa3ba5127e0697e9465ce4bd1aee082e5930cea524e4f954b581d6cf8dbcc2968b66fccebe2f6b106f43683b97bde945f9a860a705806c44abeb87994925ff4888ccb17a83bbac11ea47a4ec9a40bc94104b65c2d9808b92f698e567559019f8a570377fb92abc085d09c0bb437163dcbf6aead14f89f59d5726f239b73ab96fb +SHA3-256: 0f93d7248c3b4776724f006bfb74f9fff34ab623e25cee949d53d8b3474d6dff +SHA3-512: c393d5a07a89aae37f4486c09fa28fc0eed76b002b8915a1eec3dab0e5d2b3cdc03bea45f8fe8e4c178d49ddb160944ead326b9b927d0b44dac858cde941acec +SHAKE-128: 6550cd8a150961cff12964b0ed5bf155503f5102e9327523750cded86cdf1a6b44c1a7649d39565e382eb595de1b79db564cacce9501bbfe33c17a4716916170158096c86725baad6aa3ac05763c389064f7be14bbe317d09fe00a667bb7e7aa3a6c81524f759c1f83918212670b678b8ff6d4c5d4b36a1a237f7794afcbcc7b071ffb39fa86434a67aa2ee294b78bd4502953574261198ca1bfe6027adc8f4473ea3e36b58c7e2d1e575be5aeb407226dd513976dae33ba6c5c0949f5e6036981eef16fdeca37184cac62282537a7fd7f07d5fa355fe335b07579c3f1efb71353d2d863f497f68b5a86b69cc2000250fd4df82597a33f8220c61aaff387b5b11087b872cca579d2c0c5796a450e7203c2587a1e4758b5536c39141366de4bf77411c1f4b1208722389fb79df1d40dc8358f9a6826a46310cfd43eee217f48bec498abf8ac00f0775e397fecfc96eebd01359a23c619234a22e5efd05dfe1effd7dc7c3606250d8da7d7dd1d5d52f9412f05a42d14c7151ed143db5fdcfcb64c7dcaaeb6b2d9935eb2880721e00997c1251260287fb7d2856db1da9a4a65291b8906d4645039266b156377a67328c1a854ec8d038af8617a1006d97925389e3fcd9b3ac312fde75868b4ebabc1f1580d04e86402e98195adea28c8ea57c30666b219fe93bbbbbac9b4d2baa6c0f44659810b8b8cdabee92661ea36513bb96013 +SHAKE-256: 36406e60d22f0e0be92207cd18bf12878b7d7e8ba803386b3a6b4849ef5cd679d3832b74509c2b14169018aed9c37349f0457526b4d7e2aa8d2d160827ae749e4bd435c66a928f2a69d576048c3869bb9d862a6a824f6ec79abb6882f9a41df000840cfbc00bba2a5355691a49db965f962926a8cb3c86f58cefa346467da937b0b7f7d2cd9a5eda831b6b4c6fcb9d0502cf1ad4d2e805631ce51a324d959521ee91500082ce818cc93e1016575dcdcad08872308a208de121a77843ce75c208c484cb8e9421e87161458f3f3fbf15adb4640602065d95355d7531764cb22458f12cd60899fd9b14c698609b32d165d74ce85473766bece15cf80d0acafedf7fde0235ffbdb2129ef16391a8eb81843a99543436f1f03e0bfad68cbdf141455bf0d3f505a4ba0c563b3a8bdd5d8273bd0d19c3ba959639549d381f9f0c065cb6d0e0265c2851acfa82485e5b73ec858d559805daa56b3e70a83ae79fc2ceb6ecbbec06a8004dffc835d41b2a7d8b6624567baf02c0ec27a635362b54882fa718168cfe6c5c4b1f77b0b4e25a4a547e076be2c7fbc341a1a1a9b22d2589fc9e52930c6fd27f7a1d10df4e740d0ae7e15f0b8d261d35fec3b02b35fd2d2c85a6819c8f53c6b1102fae799a116715b8a925e5e240be1829bcbce46b4916221dbb9d0db764b33e99f0c5048f75d9ea1b8f01af8b83559e2ccdcad2e0f7bcc79c7b36 + +Input: 4e90ce8969b68ffeefcfadc432a86bcdc39098dd92bfb2cd5e9b1acbebb385e70f4092aa4cd02dce0d8369f2b57a3614e66ca2dbecdbbf6df226ed245853db753d21d8577b66fe9ca963e88d4ff30b6d936c58908ae792500175d8bd45febf480001201481672158acfad3f14c008f3db542c16d4b71d5586e2606f9170a50dcfc33ea50081647736fec46c4a1547ea7cea95f51330e83be02fdb895f7ce8ff7e62e41fd5bd70c6f2b48750293ce00666f1ceb0deaff16b5b43e40b039faef53466332b46429224244cd9482ac18 +SHA3-256: 7667dd06622391280d854179a1bdbec9249227eeaf8f82b971a16133058da242 +SHA3-512: de169250b9488399bf464a6b73263ecb5007d1a5ab1e786ef1fba3118d6ab91027e20a3c9f57e10f69ac4e4c83620ba6b917e910d826a6840b11882e55b7794a +SHAKE-128: c4f61f778edae5db2b8b51ceded98dfb645490247b4419ed439f438da83f9bf521c12574b12770e9c38437c9c0d948223f4b09f665a619fdd250c111a9b99f000224ece192e85ba46085c1197b03442d5a9cdd04b6796fa0280348fc7c3bad357688640dd60348086a34a11cfec642491c98ab19bf582f80969e4a72e76415e587962edd6f9d42d25954eb47bab82d1fed71056745f63f704d71779dc75969b0e9c7f855d2d7fa2af544d2d99ecf73c60df1cb85d8573a28e5bca8be490a9907174577ce0c8357cb149462aefab83c64f9a67236c62c2b8a8dbfddc56c445c472798a77a539c216762c6be7e2221d4e969a86ded0d84f2460a954118c3b0dc73cf312a351f9d0d10c158c5df11f300bcf3564942a72fe80c24ff85203ca7149f1c678dbb75721fcde5e0e72ff964c114af2f38185b7936b6d8beb20b6df294852aa7e8cd8caaecbf8a203d0bfe5b5f864556fb87c18f15194128e740a99a4cd651a915e0443a03b9991d7186cc5770187fe34161054abe22975233af49ebb768ec9bee5fdcee98dee114c11cbad23686e2f9ab6667861dcbaa88c6cfe66c27d1eeae16270bb15fa4bcc803844f7b966f7e739a9ba1398f4819f1181f2d125b35e31897d0117f91afddd3c3dde7b22fda5038a3b00a0ce545a0dcddcc032f991923b7ae5584eb1463933e40cc114e147e01039b3df0473094585b00e7412fcfb3 +SHAKE-256: 984160c1135c12fb386376f00c871459da09ffbcd6b47a5f73402446fd4aca2ae233affbe811adc5fb1d1453a2d3a5b4afdfb2b2565a71333b94a4b8321b4c93d1a7d83fb5b8b533980b440c69ab0b4e90bd842d2f13d1e2ad8998465a451bb0d9b7ad1134c8e55d55bac3b4d5f9050bd5a8f59425a7490935e83de62169b649900bbca4d3660a34f31b5c98200db06109937cddfba5fcb92d50f7cc33d1aefcb0136578d4ed8af65efc8169c15584fb026361b324c90e3d1fe2a75d27209c74331212aa3a774402bcd9696d326d15e87f0d84b893b3064bcd81f88a0bb902a3ae6b444adc2c7199ac6bedba376b0f3cdb0399b6835057828c7884fab41da2b23bbd046ef0ccacb36e51d29e501f31b65fafb88071e3e5847c1026b54ca2fa36bbf4cb2315a22e742b5cf8bdf2f323e0e323b4446adc72851b31d9078af86ea5f5f91cc7351b5bfe77607fdb3bd9e42d8e1b861904d58e5940c446ad262bbf82e8dedcc04103d28b5f68b12a62f3ae8c94607526200e91ef216033ccfc411b0ec426024f22de5252e3cc9708508c1087e7eb77535c358dcbd517afa9d275365c653fb9850abc0ce4643012dfe11a77d2fbcaa0326654f2406e1f20a45c5920fff90b1fbe8b76825a69ea4e111f22e7a3352015a3e297140a319debc126b343eda2a89667a1b38324c17166341d00eb415a2591c583e6e37960e3427059a73de8 + +Input: bbdc660f4d4f05909906dc3e2af5711b7bac1605829b0d99ce886941abeba0141b42b350cb259d93e727b8850732c5fc520feaab8672369d4736fb363f9122f9d186d30725ea4e41e55e99a6173cd2dcdcd2c1e6cf94e4ee066de7bb4deb2de3635eba7dbc35f019a7b4cd7434faf3bb009c34e6352317c810112d69c36f6295de0e09af838d120efc52178323cf143377bf4c5241f2cc4866e5875f97112f031affd5fbedeac99bc2a8b63788cc71e7ca1e14750341f147f538947d2924e29f5aa8beec1a0cff67615d143ec689c8 +SHA3-256: 2d4e60f35bbdf7b2f461681e4a675a7c810babd9df333b592e90848f40861577 +SHA3-512: 7d86a661dd0b356c9c379223da7619e5032845e37e1817a6c03ccb8c34e2984bc5c70429f9cae97d417951a074e84dfb643d2944f29f488a61cac0ae1a24bd74 +SHAKE-128: c3c3941a0d0d96a7ed96f15f6fec7b9036047b66b8e8a1ca6761a636584e3865703da9af9093904166f4ae81bb1f23492ab523e1a2b3387b83a9b1c04c99469895952184f57db3ecd71ed89794953fc9c6415293f51fd83b22e3917e8d59f4dc28414bd121d18a35f025250f1feded15d92849602f5650f5f83aee160fe69a40bec54e9f4a38508ad4665ea8dba41232e652166ba4885ea336223e407d3ab5ba5356fa94d7cb3cf12bb21caa7116abd1cdba9699e08bbcad22ad7769d9a28e75faf3fd3ef7a4ee92cb1b513e0f371ee3642f47ed56a79d101693d4a06fc45fa9b9a4f2914a7a7df3ced212593379b629e5df989e97af9f2d5aa10b4dac4e5eb1e298ed39789cfde0927b576efc338e251df95483128a3f77f63b85e5670e831e1e2fc13d872ad6536dc5e35501235d27e275e710b703699937b9ef286e7455a5f42a6629105ec845e8d2ec8f4bb4a8a29498973d8e07443c93fc9ee9950e6548c25940056b1daa514bf9c6704c4d39584654bd17d0e0e8c5c67c50ff858609e23d3fbdba32ba8fca1984f4806642718fb1fb191e6582f703a7f51b10fa1a3b40f4ec62bd1537ec81770194b067d203a5260261b179c0fd21125dd9a4e699efd1907c4cfda88affb0e5604e573e25fad3ee5b2ff124204db084b2c5ccf7e8909405a5067e0a7796a3acdabe57b3a476d0f5d6ce6d8a475051ea1e3228178fe9f1 +SHAKE-256: 427aeb11a5e42d436b2775b900229b0d23394ed8320b0e30be2481fae8606684d0c7bb942aad80925f734506c2bae78ff0c359cf6c460d705f17caa07ee99addd5476a8308f2427337302dd1aa9059d15d5081565b71b7ef56ce5311de63c73f8931103c469f5c1420ce2741db80fabdf41d6b425fbdff26e7d5a81a279de41bf4b1db2aa69f7175867e46cf7c3ce8903c09f1a999ee25d049260e933e66f8afb47840a4ecd112a3e591fc9d92908c905c0a37a7660ce79ee0eeba623ce40408a10bfe7cb1cf6e0cfca5bc59f828bc7a5f0dbf49ed736bcb6e1ddaec3114d51a33c24ea46e22a552fda1148271e25a00ecc39612b4fb4c54ba559bd544d8c201757b572353a55b1d670e1d985b808fd70fca1c0a9251c5160f7eac3f5964caa72a2dc305967676d037ebfb35166515c5fa0e48ee4137957c664e886a39ae9f7cc2271a5e18717129e33476c2228a954b26d7b61bcb772cee560a6c5f7a4712b45dd5c31037869eb50ee42d3cf09a9c2f9f32b1789517ac0482ded78b36139ec9f679f178a4423db4aa27294c31a388c0d20cd94bded6518739396d689be98143d3c1c1bec3310afc18e9fe0da94cc84635ae4e71b4f645b94d8b5aefaf14ad22b091899e838468432510c11f53de255ea59f5d33656a62ea5b266756626011b5dabcfaf0b68440542a2c06860ffecfa70ef918370474f08dba34f54ad39b8b65 + +Input: 2b420bd1578ec9a8f78571e63c7dfbc33e2176cb3a2d3d34569b287b948f188814719b59292a05c1bee2b575299194aa5a6d693c9c5a55cd9d29c94abeb348f6d1272b98d086a9ebe6fc10896c55db72e25636c3fdf82e00b8fb4be0dd0123bb82fa0fd8e6b5e8b47517b7ee3a099400c3422c1d8d74d872f58abce230d4199ed0bd5d4b291f27662e5bfb1797abfe67c46fe4ca1f35770ec99b447e26a0e1a99a244880c034593a755501c94c4e1d1cbc26c5d0b18e2b557e3fda2a630b3af17f3462a8ba8165c43f94e60459008bd8 +SHA3-256: 5fb4b601cfb32de59b058a012775c904ffef06823bc10b81e8ee395204dea3c2 +SHA3-512: 608a5e8495564eda5490f740608aba2470f4e985ea1e996d76c33a41ebe0d612ff0e5f5e16d3149e6ac921d9a623910dbf23f7b9bf56c649c91736e6903b3475 +SHAKE-128: e66c647b296a772bdb0e6a5580d164b41949671b4bb7366bab9c159fa0aa2bac0e43147776e44d0ea679af0722b6736cb5b0e3be8f51b2ad56096ede4561fa762539cb654d43169832858c69beada116954b74012b796811d0171b1165ad702570cfa1e2487b10b228fe1836f7791eec22b219792f1a207af0ce1b346b02350f8e8153295c6b000b2a2404ee170f2a150832a8bbfe8f8584723e5848f056281c12cab129d4eacf053a32e7a81476744703de736528382190b1c0cb745389e7a031e4b3949cc1f5f8e576f654d7907d001fd5a64e43353bf277e96936aedc1f5448a8078cf4ff0b2806b5b6a3cbac76b09e2acc8246b3a87a708451c03711776d0cf19c16ecfcbe1543e90e77af3d9d0d9272bb93162cc2dd18d3250d56cabf4137d44edfa0872d96934be2bbb3d089fae510fc3055b3aab40ccc19ddba125df48810ac67c5fc0d14788cb38e5b4d6911c5ca49ecc7ffda8b52dfe0e99e7b18acef7895326755d430efb09b247f1713206a281a71fc7fb2e516417c29b65f6fc813b4ca3c4af93ca424e50d19a076eb19cef3517af288ad04ec82f7d9f757062ce0560c5b05c9f367d45988f9915aa142c11541687d997cd0edf75c4c38535c1956c3c9f8d1af653628abe20fac029149302f74c783c155ec7324c7b4f0921cb8a33391a3e0b8095f6cf55ca0ef75ef322963e6d5283eedad991c532332549fdd +SHAKE-256: bd71c50339cfbb3b06f3637f1603e328bac90c65c38297fc8fd4668072620209bff08e719ffc2c261009cdb441285dc5a7764ea90a0c39c275b069ea86f83029c42bc95095ad9cffb88a1604b44bef0066ee82271b0c928eb0932222c83b0707e1c44d2ddfdd3edebe2e8103a6961644a8c3e53327c52582bb73bc1ca73901bce43bb6a9f619cbc4dc83817d98530d473140dde9b3c85659c425cf00e2cec3aa31862b2532321d9be19671dddcd0513c70d046c9cf0c7f014cebd8431777c559f73577094a0fce970e4cde1854e43812b8e38c1a5051736391f5504d6a1802e3f21a1f3aace9222fe64e50b93cea4f6db87be0b4754f626c49380cefa771334670c03a729477b8fcdd4bab8cbe065d0e183ee2cd379d243040e49ecaa22e36319ce6f9166e95d9ab51a75af78281cd6abf3b103e0f650572ae99147fd8b13e845afd77d927306cb3d814dee5bf7968498886b93568e624dfc494e607437d5f9d0dd27eea25c0517659eaa42ef0c3720a96119abaeaeae3e89a867789d1767967cad91e721205c86e320de55c72f3ff6580382bf80ff22fc696f5b77a87ca0f4ba7d5bb4e4175af10ef2b584d13123c3f9435964d79175070e8582de4734a802303c48dd28728a1ace5b1607fa27a86b7ccfe4abe08056ac5c23cfe0ff771630bc0d186159b58e7e28259655f2c89c5cae65800f4af81ed96394bf479ea48fdb6 + +Input: 09db368902f22864867fea5747c106a94a1c7d925c0f6e7bb28145631a44721eff1fdb083cbff4a5c0743eb770307c7d71ce9a07c354a392b86ef7cc9bb2bea3c2540eea28bd81c95d9688e775ad0beb75ce94af73cb7864cecc440250e70708e76594f6d288883b509447d0e07233ad7f92c3f3f7ef82b5b2f33d8a5ad2bdc4c88dd236f445c0042b3580db00d18e8bea780a3459180081a2b1bf4649bb5d324dc4bdcfd06152e110d18db1b032b1c9c32fd39d87ac0313bb44f726e15caa2284817c97d79a7f3df4e00c5c1d2fda1cee +SHA3-256: b2a43faa19667dd60ba88c20c2b48427c2ac0be5e5f301fb626545ba2afc2ec3 +SHA3-512: 5fb4b8c0153c49a15909ffc47588bcdb4ce085beb1e12c543725cc07976b36f4479608a80ee9dac9800d1f603200b44cc3ad2883792450170b223cfdb030539c +SHAKE-128: d4e830197699a840469fab0c7900b63e95977ff9d421f9da1a18b12bfe60556108ddb034e9bb6bb1fef35f4d2aa1ba71588fab8b427c661b632506c3a04879bdf33e826056d2513a40138d3993a92764d8b4c3650a9d1c2c3c4496a0c0496871d237ac46c2eb5f08c580026c6d4753232fd89278acc924027573140e61e65493de13427c06805652cfb05ac77594d860ff44ba258952d0b3e08470abf2402869378c19012e32261580e2241be21b5fdc0d5cd050daec32810bf7d85964f8678955f884506d17958071201679113dac879a31313e1a3a544785b1038f0f6f4f32b9201d71f5a6064ea42cd3897c1a1079ccea8caec84070f37fd022a1a7653824d1f0bc34fe3e6408572eec91ef48d3e661bfc231e185164be55310b651e196424a241c3943e610bea691752b2f661c1c538b9f4d763adbb3e3945578f2aee085677c2aa45a59b1383a8a72248fe2f0b25a5aa0a93636447de562af1f5f0285906a3fc801a1fb4abca14a8cf43a108bb22917b7c384c64b385f69df5502ba91107ec6fe61084c5818a97136096dd8d221cac4539fa1501d88c5abb8607bf480e5b785e7ee21f7da3d85c71211e69580abcdf8f7402830a20c408f8f90fedb9771a56dfacc4704eb35ef8a37786b3470832b9635dc778c0e3ddab16422d7e362dc555b9d2460d3b62a5a460d40fdbebd571ddf67f8e0a4b184c016f0e78f71c0fb +SHAKE-256: ece3a63bfbcb413d1f1f6ee7b4360260cc12b66d0be70fe58865c6477d49ba9dd8d4b8cfabd9a970af41362aea07e22ac39d9822d493d2b72fac966f5eb7092e82daa9ac68b738ac8cb6b3517a1ee6969f93dd235a0b31fd63154f4c5d394b6a8d89f5a0c5d1baa81a458d340abe829b4b18ff84344ceca0ee22e02fec2ab19cb1f5b6875997c362473f32cfccaf8a5876e99ea30f557128dab24978ec8ea605a0c99f261bc0b6e870cf7c98ad135fd67c0debebfe0f7958062334aae3beef348df51bad6c1b41db9e895ed41c26035993f46bcce82e1ae64e7f79807adf53d4441cba657e0fc0f39ce33094d0e35b81001ab40c431d7674f8abb3d22b2c747ca0587b55970a0bb1786d71bdeaf39c220c430b4c86db31a9c740fa7da712269a700a8560b030f884bc60891a911048fc6b73a4f7fcb2e43d592fa7dbd5b7a2e4ae76aea7d430bbed8fd787bc82f5ceee452dd86dcfa97b05105dd16ee306875ff5e522396c14360aa76453beb66aa63241e697dc115e7655c4b0f7c790e5875bc8130c12e0051f0d7f55b477e127bef95b41070137d76107aac05d9e0bfb0fe2d3c5c6eb9a80d19d143a260f21266bc608a23bacbf1d198eea6de89b10488c178111f80b6b276ccb4d6922570e7b320f97b7d48c4d7273aafa07716e0792c5ed1da6574aa047fedf43ff03fe4e52ad535c33c6dc15910c7c9d55b1a2a43f7f8e + +Input: 93d6a4c02ac1b643e634aaefbc6987e7e9f79ae924acbf8cf095904b5178ca060b27a23b12b3c6d3a49faf8abe4fbfa6d56cba95d9e67475edf7afa89dc4f0ac00201739b281ccee5d4d5981949eda4d107d71b44b141e9edf3f8f83049debcaf2053f37a01a10e90f30ba3d87b8ab8e16a507d44e36825fc8f3495bd541f76f6156fc649a365e9a5effe8eedfc8deba18f2883611e2d0570dcb230de857582fdf128c77d0efcf821fba537cf257ef340e529cb4a8bed0a77137ca77b4f2526ebc12f0cb6776963a18a435891c9d9f060c0f +SHA3-256: 492bc6e0939e66e0e5d0d2f80adef3fd304928bd85b7eca3119fafaae6377c46 +SHA3-512: 9d4683b3ccdbae21d017feb6c91aa456b6c11b538bb910dbf5f9a79d5f2fbd5dd0c078b39e33c93116bccd7ac2dd78be028a5cf71115d896be3d5deeccfb5f69 +SHAKE-128: a635dc8c8e048e477d9cc0cf7aca2ec5304915a81623f665b68735985be6f30d358e2eccbe9f905014b4db0bf350bdb19bf2ea20c3d530dfe9c6d77b0f383fdb208a02d23857c89fa6d20e2fb7a71bf21a5fc476f6a201edf48fa16aff8f6279563eb3bed87fd0404252bdaf8a2318aada49a9ecd7ce96233e6962706a9ad2a44f3678ce73d76648c9739e2fc26d1fc06b98a79239072bea5470e4c9b8837323c4c02c7b940407ef384ec155d13c726c5289221cb6a2bdaaac574125906a0729d0c62efa92f5265777e5b030131d9a681134af97e645de33ec89b1c6fc07b6827bb6b5b02f7c525eb15d9be220a17bc4da9d82c1ad8982b0ba08d80cdfdf3a710622584d74e30ad5599ee79eba4758700046dd55ee8ab9a3f8e35122bbcc0238d213ce527f13b12c948c1d13065ad88df31a27f8cc8bf593c4525a3f77f216f27b511cf999b0f343907c74c774514a0b36a3b95e4ab651ed53acb8fafb89b74494520ceaddef9eb62e4de7424e0d6ca949e91b70ea7983448ce335887307f78f6bcd19b966f460b5b281840e4809fba896c757248ab58f639d6bcbfcf530a40596e1ca424896beadf4ebba639d14737e3d5ad166d86b4f8fd501ed0a313ea71562691b0abb66e2f573e8cf699ecf44b9418c4d9a5d07ec09ab65092116e9a4e0c638351c708704661799429b0861c6c86e47e5e2bc97435230186b91727f9f5e +SHAKE-256: 029310a46583a192e2690cbb46944b555b52a2a392ed7d407ed44fc3412deebcb912db3caad2c84066ae6764f55634035383bde90c010d1ce2b8340ac66931fbb9c68910b1532f30aebd1a08b7d3edab0940f35b1eec6e24fbffc50cfc6f874814952f0c95c9f8ceaa5e36e9740f88dbfdacf6d0aebdce6714957a65520eca9861a94cf87516cad310e060d1ba05aa56d95892d072cd636bf11f022552b185201c076e0cbc7443da18ebc9db8a74efb45e510638cb1febc214dd3a2e83012af8de900b7f2035c3f16b980589389e624f811e227c2aebca9222008270ad36302da27d19de0856cfda823b645c1b568becf1c222e5585015f6fbd74b593aabc523f9b3a63256f9241f16e4f1e7c88360ed4d898e18a4feefa0d4c88204856722cc36b3f24025435d9223ee1256101c64ac2c03b30529e1144be8c495a6c41ae5ea43ce9da9c152562607d00260408a20bfbb9c1c625119fbca843a02b58d7c4622973d2c4e352410d628eaa9547fe33a0552deb928612485f14e7d77af9085086e91cfa4c3eb4f4364f29fbd2ec53fa5c78a152b0148e17620f4b9500ea50c0c22f79cdc624a1e03c4ce19616519b83d90ef57b43498d0225bdde5077c6bf021019c62db3f7085603ffc2b9aac61a2243c8c71a7a5358c97f2dfa1997cf3000542bf3df140919d77662dbb3f410879c6b85fd9759fa1a6ffc0214ff841b7a9534c + +Input: cbe425b719fcaa750b36e13732b9bda0897ea1bd0203c5618571cf4bc63246099d70153bc5a733e49dc25b99c895066533c5899a2a2298e734e781a20ee672fab24deee3f4e569dfe19739debce3ee4c6b2c4f67a4c93a1b7c7d679c341c3c454cb77584e46769e616ad723e3b1a4b84fc4b429901b564c80b1562d523740787a06d91909bbe57d91720f9b3c62d56e045bd5f7b4ebcd871c5c7c9c1efd0e97764ec4224fcb1d99a553fd433862e579891e2436138d308af4759dc4848e6a13cf8f7df271dd3b41676ce186f7bf69c05ba5885 +SHA3-256: cd7878c09d4728b60595f65fe496395a14073a9ac7e0f9235652be99be010efc +SHA3-512: f356f3811f5c05fc964243267b616103b2caa8d51096b76a21a8c7e5f30144102d84b21220df058e7794877c5e5de41e3816fe6d4b46b068bb45549918fe362b +SHAKE-128: da0c9497bb24e6468389e6b9a7d9f99b930f0f3527f4b2a406b17cc842cdde0e66e8c54d3d3afcdea7e8da8b31e844dc088f60ea368ba228bfc78e82aa4a704275a1790f264e205e7cd0cb8fa0523db312d4a8e78e43420e7a231c976c71ebc4924d4789db991e8f48f8ee25b7a9fd55baedae8c71bc86174cd130bde53552dbd75549f060a2cebff89dcba11a4d82826c70fd014d5e06a3f1bce0fd83f3717641d9fe2f356d38b543ca53bdb3ace94cac764bcfaa81d61a69c4ef52e89ed4cb3510f642261bb847f6a1c49316ed6b97f9dd85421af39eec5b12e4244fcbbb7e705383e3976ff969b6235d24a8c8f7aeb82fbc2dc9713ec06d2cf3b8ce238460d890273c3e3e2d9f45e78a30aa5e388bc6bb79989aedcb48699d7f9bdc542b3f4c3b93320eecb5f14691ea1a5463d298d5b428e9cc37bca32f0d02292823a48528a8fea188ba859c60116710dc8f0d646c1c12207d6ffe302ba012b8f9667c336edcdb7f38bc8979ae7b8fcf5da023ea408f5cb162c9b5b2db9db81372a2d09d6204624833f5333e5b9f5d72d6d861f0daafb9c71fb5991fd1eeece9c52a2af1ae924ac0416e09d79b0226bf7f21a391f7256680b1317e279273f97cf9da8676e2db95ac6b03596a1b1be0187f6d37b00e4735302840df45d7a6df5795c9bce5851b6b39018f7623938eb147b7ab802b8fa78684508b9ef99fc38cbc38905d60 +SHAKE-256: e20f5898dc17b81629a66bce66e5ab9411c3818a7dd8320bc621bbda40be68579e2dd56d7fb69c7a8de445f31d93a17e83842c3ac4a7ed96950e8273ffdf19d4307be2daf1a9f5e50b91219ab74a4e98a69ba151b83f4c79218bad035a23fec3070e8c1f61b464bbc85028e35d893983ab24789aed54a37b20ac1b966316f6890b497bae7f1b752da7f1da68fcdd82cbf84ea8ef6cf95a36cb627d1d5c3e18380117df8fb880879ebac2326d1c2af593ed6fbc1fbd453eab0e4627c20c2f050df3a67610a4c16b4f2e98666357154a58a28e6d4b648c160a0daf293a7af693dbf941a51b2d8f907c5fbb3078abd17ba81dbf671b7e7ef48a28d43718e54c382e895bd51b8fb8325e43d97342b7bde1ec691db4b2b7d9fc78c8f6d3b29470d3ec1ef66552b252f4d4eebf9ff6774cadcbfc2d59321d3eaaec31e4be764856e2fae0983ee262c7bc00791d69fa278c038b32fe52b34b1550bc300ddc3992b0ee92b53c467a4e6cf6fe2e07feba9037881c208e7adf83e4987623fbd645208ab78606a714b71024b305a9af08be91f639eb7da807f98861eeb497f26ecc7e0f151efb6e6a6aca2da7bb86bb833aafeb902f9e33b04c92cd4811fc0a6589a1502771809932f1bb7130f1198b6c322290c1338a54e70941c7c902e457e81d74c19b4c67b1e211f72178d8636f8021c1abd6e7f8ecfbfd79c7cdbbbcc1fee153128e17 + +Input: 22a566913439a1cc544ac6214a73aa37a764838aed132b00dbcb9070c4392f6e0d2a2772cf26068a7de54c0a2f01ec72a931fe6483d0c887166f8c6d7f6a2d41dec5f6c89fe6aa1e5f46b88e5ce6fd922d1b3fd6e383a1ad1d0bbecad10f923610488e197f59c6517f15003f0d689e9676b32643234ff87af5e676ca87c2075f60d071c336414b9ac429a5781bf75187c56e7405e4417a6b9e0a9dbfd01074cf48972037d41a217c3c3cf78108f08f7d102f82d10e8c9d051a48736e734ff4ee9034f4e69c9d852ec38723c17a9672416247dea7 +SHA3-256: 50e91f74ed444610d26f624eeedef897825b335900baa5e0a1fcf604fdb5e954 +SHA3-512: c0e1a3224dd81e1f4c62244da4916316fab96d8c90ac8e23aa4cc6660e399eb86e167e7a6dca99157453a285f6bfab5ba6d0d252ff4e1886390179838a63d33d +SHAKE-128: 5b711a629dd16bff3d3a19d5daa7621b175e773a6f7fec44fd0684855077064eb99de18cd73d83e486d49e6bea23666a708fe9e769fba7f03cefa84b9a0999ee8dd1b7c28f3494ea01366d904e7536797e8cb43e63a8bb9c3cd417fb3a74106b8a71632b4a3cd0096aaa22dadad462fdca816c89b23be70bce3057269c718b4b8ca88b3d794cb27bdda62aa41093c2d6ae217998144213bf3be91e1aae8e2ce39823a52313230221a415c2e9373961cecf36b62cbb262b5dd0bf009f80894213c1223fdce3cd4bff87527193cbb7f8fb4f90203dba54b29668f54272d1df2e335d58bee3db916ff7100601f3267689e9cfa65055483cd185e8ab41c01d7a4009d46d6aa43583755f8069f9f41e1399761652051d5aa7a1013730cf78c5a380135f431037727c47bc29e85528b7ac969949d7f437524cfe5cef13b2a33cea10118580895cac032376b7214b02fd34634c2ab8f81e9cc80c04d01f64c4100392f6bdaf9d14609a40a7f7da444bf24c25089c46f227d6fe800223db819d2dc0f156e88f7f98fc7ded88d824975739018800a45f1a0083f5a48e60402b1f1d8e8878e9671abfcba1f286e4c680c4451ba650e2962fec3a9c0178053925eca3d10e7369236f69ae1b8cf7ae5fc2ed37723cedc0a44168617aa14e7064805df76e5231c923448aeffc80d1031d118c5eff8b9cf8d2a0a7f46db2fee07a3387aa55f5b6 +SHAKE-256: d97ab52c8790b430f6e0636b3c4a20c89cb865f972f015456ed8c6b1a1626f0486d5bf39a8681e661662afb242caa05d798529e99f5414bb1914f1966d9c8d5a53a2e623f752b57651233e02404c80ff477ccd29a1e79797336438508025e41e73cf684994f062d72710f5e60728717e93361940cebcec21e2fa87b54691c1d0849cf4e80763edc2d41a7e43870e20906f7578e7b72e13d5dfd853c75e832d1d78f818ee1626b167cce0edd057766c4429b56b510760b29bc707318ffc41b5ffa830f6349a1dcce35a99da4aa78ca50d22d27bc837f8f729cd2445bec48811b83da5d39959849dfd04ee3f26e87304ce52683792b7830b4cef1be6e87cfc05f9ebfd452ad31a235c287f6c45afc4e697186e743c5c9a8bc29581e8eea24728e72edc7fecbcc31b48baaa0f9d2262d45a68f0657d3afb40c1fee3f5f433c46e8068faf1e4be26539231415e272b94c7d8f5eac9cf7e6520dca93c79e3eec03b42193d8f7d185482e640c076232a9089e392db2993bf0a6bfa8c206662824f36a0481ba9c4f50d49b27b3c407c53a44d7f9df989b301edf70ec7b35017d65abf1a0c1c82cab5f6ae4c84b39754b0e703abbb84f0958caecb71a77164998c85f9be100b5be13e0c46d71b855bc64b0fe2a4f6558183a3da984d027ede651b066bf577e361f60974fd3aeb5ce9441fb2f76881614b932712eec9bab2ab43eb485337 + +Input: a81d8d736d05998869b433919635086d12b932d426881ce5322ae82f1666778f0e02c0c66e97b82cd97a280ecc4d0a8a6558db94f95032273bdac795b0a11e96533e86539d9fa27e1651a2ffbd5aae385f51d5729e04f36ff42e34e8ce955c8252df2b1b118f04d7db6183e099db0f036d124c35ede217821c4c81c0ae88b5ecbf8cbbf9cb615b6dd0e3aad6851c91fda893249d84be9dcde847ba9f70262235304b0b45828376cc070d8ff20615388cf87c254e4e663efa6fb26a2cfe691a08f4cb253caf8f39ce2054e6de6cf81729be8f3a5b96 +SHA3-256: 533538ead5ef0ed276c3b81d1a87da46b5db06406e21f18047a241baf785f4c0 +SHA3-512: f64ab8734afa332b8fc58db60c55cfd27ed07b658207424338211a1bd35d593dbe22e468b72c7c032efd1e20e96515a27645cdf358c608f1e687cf2cb8c6ba32 +SHAKE-128: 8acea12ca3575333a36780322c30350192841766986b76be4403a47a49859c2ef35dc9f634573a27f58407f3e9e8f2a356b9f61d7409415d412593283f71e10507d0c0841a2ce0a451b5b1b5efdad6365a38f214c97f6a307b068f7754bfb81796492d89b39aa8240a88a510fada2147f890c795a536831e308885a94483cd39b3283487661492d4d0600685eeb02b2a294a8f9fa528a4e7b46accb59ed0bbf43d2942ad7902ea77528f1f32d0ab9fb55cab71e6d1ff6d4d09b192b6e22a95c192a52e27800df3e7c19a37bb86e66dc44ff73b1cb92f4d7ceea2da6c0f06d9a53cb1335217a2c7a5677869d1237151af7bb62465620d3e2fbbeb0562620fa1f319f1e2a148edb62e68fe24fcd4dcd5615ef3a03bd2f0ef288af0a04d73b00965af172c252e2853901368bdc964130ebb57b35324026a0b7eaf9775d55217c8928888cec8d4023d4bd9af8ce7a220ccbc7e19389acc4a788884ddb506f5a1f6ae9a217873d32e0db61f05e97481f44ceaf085d6a6b8464de87af7c9505cb836e4934387aacc0fbbb89c10b793d805a61c8d70e2f9cb42682557b9871c5dd83eec669e5093d3ca02b626739d514d9c4806ca760fb11fcc7860c860386578620df563b5831a62952164326c2cf0293b46c90d005297e67ac0d3bd2e08ff1f91b0fceb3ca278522548492cd0c4f241fcd7c53ed74f7f4a32f97522f517ef292002f0 +SHAKE-256: 14a7f241068c58a3ed8596696529160a745faec6da26524ea647182c4fb6502c95e3a8bf01f9bbd9dbedc93e7a0c451b1d3d538c70e782da43772f0f9ddbeae416bdc5947bb243168af5ebf5d58b7e1fb45013740b90ddb2f26a190ae53f8666e979098ff85a98b9dc5526de63324713e4959b863d028becaad9e8dc8071bf1d80480d303248772d517095c749850ad32e3c96321628c064781fc94bf213795a678bc479ffe1970160d11c2af509b556c1692b185168744fe44db8af6d880ca5ae6c4554904258b039e1d0887870b3bcb37e998c8221860d1d63f7b6a47004b789add08814f5e491dff693958e66598fff1f557d55c8c3c89263acc0aeeb42c2ecfbe7654e083a7964472e4bc66cb17aeeb7c4872d1e6acdcaa7841f2f701fe31ce6f255747633e9b78632a83752fba7da9c90ca095e628cd81d903b78c1cc2a279868de62fb95c4834c8181c2367fb0659d8819f3c4ff105890db0486dd319e8f86cda288d8510782de1ab736a0f5ffdd4c79c85a7294153557c8027682ac5a61c6a42a503ee2ffe66b5f5b213ae846735b0e97ca3a3623bb03f4b1c2e99419aee280cf1c29df2003231bac5a76edb03dc4086b6c1e75403abee7900908be371d23a38121079a3abac1d7084b4ca955507980cd64e748253fbe6a7f00db600b5ec5076031ca9634afdfb85dc10f18e4f3f4e071509ae94c92a02bcc00772ae7 + +Input: 0235e74095c1f7afdbda35e82495ef58468d8a96ebf121fca9c131d307b937bee22b7d8d78fca6f6e6a099b7ecee7ae95a7bec727671583b4a564b95764eb132656fcc7f552f2b97581c15308b46ef706691ad6af5ae3e04a38dd7934c2032c4e18228207e15659c7bcc9d72ab5500e369da631d4ff70b50d5869ad82dfdc6820d9928b65fd2a980ffd9d07cdc3ecf27231a3f17260a21cadd8b5d2f436a6c7ed4ff4b298ee33071f0f11317a2ee5198e78ee0644d2e7515074c278a6ea62d203bea97fd3415c5f28650775fa04b35b1bb5d893c4589 +SHA3-256: 3195f01c24e02c4fdc230de122a0814a805c1e18a0b6d03408c8288f1fb25055 +SHA3-512: 49ea7e1fe6523de95362126020148597179842a22726b60c17c19b95b1860728699ea8d8995cc47dfbed9b616b23f852eb6a4e5370416c30e3cac5bf22f751e0 +SHAKE-128: 6d0825fa739da0a8e0c106a5def62f5562e5a85b21afe097122447c2afe48127be19fb55bd08119cd82e2b23a1e90c3e12588da357883e92b46ad9c5c87639c9b8ab03bcd61a097841599cd05416071f5d44267d3b5f279827556948bdab80c7942bf500ba4f221931a78fbed0ff0a422d35201c0b55f2625e7efb535803a9c0b93ef1d9e08ce75787f4ad3952b1f10a53802e0583924c244114e8f34531dc47777a723eda12f9b757b8c4f937bd249e48f42448d49bd95370d4b4ec9a2fcba1f2a010c686de43061d12027782fa217c9dfc4ec1017ea387ad818f6e836a855ac6d7407790a3907c80367e5eaddf9b6ae2de7ff55b7f81a394f1b027852acbac9bca617de8ae7100816b674b79e4894b1ead0323a017d50623beb6105ff2b7cfaa802c3ac0b060cacc1a6c0616d1cab67b2c9a62100301f6d5a41f45bed437ebb9b6705884848bd85d058472f5b2bba61efd3e224194bbdd67bf372d06af12837de5713782ced8e81301ad8fcd5adb466f3fe5c8c6049dd0a963c8d62c08e7b367f495cb0e4a0bbb0391a7650b765e5bc5ffc28be436a8b17f1f26293860230ec3d727f7ada2f626eeded96c2c596436c69d53a8d79c4fbd406c3d68c0bb7cd9c7bc603464fe6389e9e334c99a4b4617d206a2c86855f536f18db4abb28b190e8035a660ade9060e521721966df35560227509bc0fc11359f1f417bc1a68fb29 +SHAKE-256: 994daba1eeebf4a1e4ec15c3a24d7cade2adccf9c9c0ad68387499086124ba52fe9693ad367916cb7fb26c6708c820886c3a2a7cecfb6dadec3cd91910f32fea86728e79138542a33745bf409599a67fa70ac08e522f2332da986f4dffa7b3ff18137c81c32cf8f99647df868ead4e155fd2e8cef91841f22a95a57c646029e5608a35a74998c17c6eb83d2940bc72562682e0316327dd78fae9e637d95349025305eab4622dcaa410368cef15cb0de9d4778d9eab32f41c4be276a37f20ebbffabb88eda81cd5f037a2cfc68d7e4bcbaea8c8776491cbcc43c1e4779dd775ae5f006badf99a3ac546d86450b7d6c86ad7861f8b041c1ebb3360d1a083c690a36c83bbff012426aa5caa5c9096e20ff934c20c8dfcf89266aaf15332dff625b4f80ee76617d36ebd52df22f1d5e764f603dab45a980dbe6ce05ee08a73fb75aacc24a9173d67a0c63fe4c4870211073cda5b88313c998a286804a286884f5d9135e6111756256a5a71c450f9718643487a286650c1311256c2ecdf313ba0f8938f71a7a003c806e9ad56c6a82285571ba7170745dfe328e5bb9244fa797c8bf1dacff678648311b1c6145976616890d121e7e624a3312865e554b4524b09b5afb6bcf1c9b2ef84b21a6ffbacd89d148bcf2ccc10a7af51edc9d56f4b8d3543365f5cac39883e18d76401422427612d3162e72e6b4f19b5c71fa68e0c3347975c + +Input: 609548bf5732c9ee6c9c4176dd5b5fe771626a67a2458ab99cad4e922e6206b87dec5273428a96f1742bd10b3394175a553fa505e8671e0b5f0a2a892b63f85ffd58c63e757fd70076ad7fd19195645d7aab288277f9550e91531dbb0847dd33f6c449568e799cee21c4c828d33d4ae9f5c32bb5e6c47474c4a10c49909ddf54ef5a5be86235006bbd6b696078e09aabff60fdd64a8a7d945f7359551f4c061669bccd789761658d957ae657d3ac87f45f6457c24fac2e314a48072d80e3990c8d756f5a89604178843c904f53cf8724fc5bd80448653d +SHA3-256: 966182c2624dd280816d4b003e440c6a23ed205346df56732ad58f6cc68c6220 +SHA3-512: f6782fee83e1edbd129ef5a949e0f5e550268d63512c3e3f3117324bf9c53aef76c7e2f63a12c3f93223c2ea62cdb428e3e12bb65e5315840f3c761665d78cd5 +SHAKE-128: aa55dbcd0251ebe3061a183c450e0e4158863a77264ca64b0975994cfa3c8836d6102a3262fa1411f0bed71c84bec486bfc017d7497c0cc0d19f439a278f7e947936acde2c73c33ca630eeaac2e789f8b6a0ab83b676370430ed9b5fde9e165b37ab997214b42ce01523a2ce4fe03a4e7f17bdc01d29d5e48dc1d6191d40a25ec1cb0bb2d61b127a939aa855e92951251087f0da9e2dea8c719465186e97118f51ad393ac98427c6f2b39478dc89772e44c11c9f1e14baea90923ce267a606eb354987c90d46b5706c6881245dad1ed81f26be755cbf582fb88bb4818cb026f07bf54a3b9c472fe4605b3be1af110e9b8160e73006415f5d39dc7ddd211174e8c7c9a42ba260379d727b3a8b0c2cb5556ae23440002c07bfbc473b6e2e643e89d7b780144cbd4afadac509169658f4d5b5b48e6278d9b85a5bb3a0f5fd239a0542a384966046646f2b18f1c8d3d4459e6821eaaa456df0215394c8c476ffec183aea0a0a9c8f82e488855b01d9474ff2c3ec118a681da31c35954fed11c91080bfbcd159905d808bb65ff118c97fa1c3052c1641c5b526bfd5615e3c96aa6d169031a34f63401e443c0f7eb392fe1bb7203b7710b33dfca3646a195d74438c4a0ec2118f45cdd82081282d7a7b78d0c0d1d71aa682fcafb90b3a8bf1963fd255ceeb2b291a0e2b5d025a5323db27df963a973da3d30ffffb594d68f88090ba16 +SHAKE-256: 7b2181bae5266455d7d76b1d83dcf5e570787713cdb77121e6b5bedab1c45a30910c598aea76d1043b46518cc8f1916bf8f73e83e1fb4fee3979a5cb9f36bf1b6000e241e0aea1fe42ee6ad41afdbeb8faecb60fe748f61a33fb2581bca7aba15e9baf3316b309684b8bb314ea1e0055cb39ef5adb88baf4405bd4835bc99cd7f22785c2d279edfd10b92961b27b035c21dd9f0099225a126ffaa051d8c6e9cc4a6d813e8329053eecb9a7290fefc1e9b0905fb6e134fa0d3f4a5cd23a08eccce3dbca55f17b044091fe10e17a4bcad76d27415846e5212aaeede1a150c3f7ef31ba2f07c17585280fee8671903e97a2fc8eef29200bafac3916ed4074c48f15afef6830f8286438371ae7723985733e02bbc285c724cdf349bd104700102af17004ea15ddd5310d1519471690f654168480176d6db31e6d3f41838ffcbf5be1ec916fe9cb4e01dc8332883d50acbb0e01d4cc3bed03fe34405da6d085faa069ce82019f7eea68371272c33d6fa9386aaf86386b9a2daf23feba59d5aa3b1cec5c8f0176590108c58ce34a3ba8bfdd92d03c05bf3cd0c7130a37f16f033e8cf945d9d4c59ee27d7652d5a404cbaf19701d59245120772c7d314b9ad7a21b5200dd627cec95951cd5100579eb1ede03ab2e81b54cbe77847086ab645d1a825a2b3d0f06e84abf82c559dddfd646c433e880c6066a0c884a148f15fe6cf70a7d77 + +Input: 41d99f01e7d7e6f3694d07b0cabb3ca98b5cdb4e59d515e7dc9e1e1488dfa1786211b5fc3f6e63687a7de307caa0c34363ba9a57bc013f191f22536ae08cf2b3a10fb20fc338f4642c71dd1f8d146ef9565fcc2ad04e77c8c0ab1db65b5fb5a0f4cdd619cbea99d0f8a7daad6ea76cfb586db7fbc93b266d5409df496097b0a539d044a280beda20abcfada4eebe6905ddad66ba023e8e88cd5aa8e1c77700bdb2a28b06bccb28f10a2f87b0a65f8b1ae9cfc47068f08917d893d7e10af77f9e3f671cb44122d69ddd0709deaeff359be83d1c20b4779eb8 +SHA3-256: 9c38de43851c9792a9cb56665e078848e6f5cacc246f8a021474331cc8ae2a3e +SHA3-512: 0e68ddd8f8530c79444daaeb859efaf72eef56f0a34f399f6a0a43cf63a9f205d8e3157699c5ea1c95044478f9463fedecbe78e4242b6ade685991dc6b3c73b2 +SHAKE-128: 6f9f09f01222ee6960536416ea6f10b7148c2648d81d0e70d59c8645a619d817462bd6adfc277d4963a1d81bbea2a198ba7d19c109171724d302f7e02e93455fb4ae9be4e792a83038307884e83ababff795988eaf787ed00832eab0079b86efd04b47c597d17a56622945870431205f414ce4314eeca3671cc8906ff1186abcbb8c667ef60ffe5c4a9e652fa4ca68a066f3b6ddea7146a1769aa161cb5cd1fb70ef2592d6644eccb317eecfa4dcda0143b6d80d75a975314916cd2535c3ba60941ad6a657cfff6ef8f8b056cdf02cbe01129ab2c374a9ba4345d6df444d484cc68408afb329e4b0924bc5847e2ba1d62d46cb624276023deb151dd38c67f95b907199c8263ff1911d5402ef4d71e548b59501fac54e86666035ea010cc7afc950433e4950d657384e7dced343f586c8f0b072dfaa6189215faabc29f6bfdc7e2fa64022e5ed2f3228bc585e9e0fbe11340d7723a048c49de57df6f2dd7be350850a1ccabe23ba7cae77ae3e6db782efaab1b6795cac09e88114cb36c6efb1e57d9e30fd350e4cbe7ac8ceb3ac109aa833caf1213e5085dc7d946f0cbbeeeab441821e97b611ae70cec4b09fc2584ae558fe55648606115e01ec1a313026b0237748bec0bfbb85ed4aeb38be3a2e2b56d57246df7203ac406ed653ebf61ae121fd7fdbaf959ba77bcb2a9caf8985b5d9ae1bd02919e2a2a77a00d2154e8e96d8 +SHAKE-256: 62306405fb3ffd2ab01bf74d35175cdca8a61ba0566562c1c8e28883bbfd21385909d7a4d04081ce82d053bac643e638d155ab54866e34ac4c36623e9d9ef84829dcf36debcb99c9006b43a2d2915705393e8192d8fde4b8aa7666417f437ab5c8b9412f973ae0c1631df624f096fd5ed704ce97ce65378e43e6d1a6282df18972fa4d9369b1f1570e7dac02680179b708249e01784a75d9b5d2963ca40acae0372024f30dc52ba76c6064d295962315a1932c718a4bd07594c1a7478eef9398d152ad1969ed20cecd8a8ed92aeb8b751217430d13572ac89ea95cbb0e955bded246eadd33365941f0b3b726eff18d551cc79d905f02f2ce103ed874681f585e7a4a1cb267df38c613c76e9abbefa8d6db010680d53212ec3130950b5e66ff0008f7dba6ae211ccbc88c1ce135a34cc918afb838ce8d080c93407b3b94507c65a5c2f6dad1d78cd307dff49701f4e73969f0fb13ce07f2ff2138cd5b79c10a43c2303f52751d22b1215e8e721cf41e0765a37a6e4a910d293c269d832c2fe298cb3d7fd7dc24fa41677665192dc4e48d62236b1ed77ce75a31fbc19ce893ac450ceb097d74ed6fea7b565d6d045418ef613fc73980416afb3ae92eeeda07dbd97caa0a3ea6d4f123d434cad43b79b03b18facf5dcbf5e6ab6c833d1e09db6399beb71e76277d3b06b35f3fa10184cd114b4693bb9c9d17512eca1fea3933b00e + +Input: aac9d8468d782c1029c1646feddbe8f187cbb7e59b1405ac309180ea0cae539da6dc56041a4e13bcbdd1fd1b9aa116bd037cbe3160cc0bd45787299fe53045288c9009d9a8b6f3d9c4678f3ec6c5361437139e096106d28be25f8a9864f6008386dc19485719301c601479cb95d3e2f5ff85142554dedce436850cfeeaf835e75971c6a1218bdaf57dafedd431a14fc2ad80b360729fc40e9f8ab2a9b5e8c45956d9034d2e12ead756e0940a52fecf93e64717c2e4a1ce7e8246864fe78301b79acd02b5a7f73b458b80ecdbec8f03d6136d95773162c6b804 +SHA3-256: 7861c031072137ae2fc055f1c5572fcfffd909b447c9dd3caaae7123c42c1fcf +SHA3-512: a40b37484717f4d51416185d420f7b2e91d40bb4b90b1afedc12b94bed535b51f5d6daf8335e31af1d7fedc3fa8d41a38b3e18c200df7d0baa81d604686b2687 +SHAKE-128: 03d55219b56cd5f7f7de66ea8d7d01dcedd48b55e92008996e0200c5e7995961a7e1b105b3c1b8233cbaefb715068e530de79f911910a0c013c4d26d56c9ff268681833fff4a9bec9758380441abeef49500c69e975e9b670b968dbfe26687bd5c4cf54437471484b9eff9ad5ed097a53d561be1df496b7b7a158f5d684643a3c88efac5574b48b8d232b7afc063e3dfc79047011d0dbb63250e2bf7d375bdf280a861bf45cf9e168e3becd856592581d4a44c1a7e9558e4f94dd9020b1028095cd6526fcfec07eaa718564d3fd3cf7e28d7aeee5649e79a613d50269fd3de041110955c6126fa9de595ad296cf3dfe376a04806797c6fa613dd9197099dc3380bb7d2e00277a3ff90f664ff18ced9fa58e5d7a179217a593a5e11be423a2c9a20a8a248282085eb8d0478815019eafd5f6d8480378db4b118b42aab24872214533ddd5fd70c0aa3c405c1a1814c9b648353f526c731f9cc3717271ac70027a080180316b10fa1dd63cd74d210c382b363cfb95c6e665d3372f46f1b11cd044e1918e3eff8c1b00f48ba8d5b623be6501b2642c4560e361a25ddcc215629bd9d9c47353ed9e326166a89b41bb107c2e5616d1a0bb42dba1f3dc4ec20db3394d257add7e28eab9c5366e4d1d4c8c29d2d8420fb9f15edf44ecb0e3f4f6c8f5418ed3dbc4a1cc9ecf319a0cc53db51186af313bc1e3fdc04cfc066677311680a2e +SHAKE-256: 828e32cbc9ec44b90a1f69b962ab915067d0e7555bc93e3df136079905ef0a8aabfef471359b68e21bb31cba9e6de95f49da647162b45d6b3df3ae920d283a28ae922d3b1142578fcdcfbd7779fe76d89c13482793f1deb8dbc4f972ba4ddf70e34603645f4426df2c237db899b785d823394d40cc44fd581bf8a0526d21fd70c4b8624256c877598a0faa70c1ac6ae705e69987c4f76142ab17f87e3605d5b747d76474dc4cbaefad7ab9257c13f16446a69172252788588cb433e628a35d77d76e0ee3fd37895501666cbb5084ef76283f214922fb36e1994a3d64e8b2846a04366a90c476226dfbbeae51c3b548b53dbb69db42b1b98f08e49e899a21b4f74448f235cf60e71635f2a1ed2a65e328860b50e216c6b0c0c23961a83302b67ac539827d1bdac10bf3cb04e0363934f17c9b8a169282ddc37e4790639a3acca0a80d6041a78843cf172a261149c50781bf68c7506bb885bb5aa232426e6e318027d0e8e46046e2c4a00a7fb4d7c724faa42bb55f253b58e97d800c66091fffb7fd383a066337833093c0301985afcf238de7ed721b05fbefc3393ad2862cb30bc0de7b85424e6d8347d1be3134dd58f270b3da126f8075d8eaeaff767bf9932c4c27d3bc1acffa6b4e0a3a53fb5a78b8a419fd78a5a8a495aa34ea09a0bf0016de798c7afee7c1e1716155359813e94cb4ec41710bf7befe481f13466db293bd + +Input: c1deb23ed9ad14c11d26a61491bd2e36a887fb7125c84b4cb0a9f178b911d88ed8d1b375c96eb710d16038d3b950a4d22f465a00a001d9174b1cafd708abe6dee4e5a6d2cadd9e20db051f026aeca367e213471f9c6541a929aeed89737e8895faf17f5c922b5c13f8906422c17ea3be3859c70af54f5b97be733411891195c504030012dc62133b8e01d42871d4c12c5570635e4331a7be29fc52f46858e52b884fe48f1b1c642f5dfd2489d8a41c2501222c97890985b8adc392fea0a5841ca492ecd59c06f653570c48de37eb7530425cafb28fbc32f89e61 +SHA3-256: a679b7ab4e57b9c237ac40a2583340c2316ee359d6233438159f921c6737843e +SHA3-512: 933c36017785179b2f83477c2407bd7026ce7f9342b823a7ca23efdb9d56c5bfe758b37b7a2f9940786b84e542fcb5c8ab07c3c29114797df63073a84e443e63 +SHAKE-128: c9fa3d355427be6cb07d8be10c99499c3c98f4333ad0023ddefdd1e7233f8fe72c9982cf54c8acaac966e24cb26a15943906e3dfa8939e367944fac0e4a4771c0b453054b1425b3fa5a33ef5a8ef10f2f358d6a55a6e3ef95c14c2618a79f7802f3b2c75605a1503ae71545934bb34a5640694b959db2ca8ab09233e2ad0e0adf740c34250df4b49ef0316cda03bb02ce2a55f09ba32459350ccebd08298a9700b1f6b8be5f653d6e1d9bdec26c07a9131b1f716e9f0441fd7ba4cbc65149fde64acce8dfc9a9680db50200d8173783f1a8782c7e9936a35ee0e9c1d0b78123225c3b18eb63ad1041bb6acf7d9efb9af396052981c686cb02f68dfef54badceaa8c23a4a26ce1c7b4f0fdf8a6551284f5d1e5e81640ebbaa1242619c5a7048bd9436a1a92cb94cee5e907db506b078cf902f00bd7cae72e3f68803c1689ac96a0edafc8549649b3b2a3caa554953ac724eb7f67163d8b9315aba9b43ed78814b05f122ee1997fcc5a39cde4e2f4e5016e5c380313796f6cffde2dc362cbb26d9db40b04f09cabacc214f9c25351c5f05d0519a2a3f39eeedc621641d232918e5aab90825a362558f59af2b08c07df8432d7abb597588a43424c867b4025214136df26c03e9daa05970e5233acaecb8ae32bf300b356ebd834694b2c897a80144f2cc4ba9b3f1440ffab0c2ead1df8eb968f338b0c4cc007b44a589f6a794d082 +SHAKE-256: 4ed9ed12efbe6226c03961a3b9387d15ef35988a2d45eff78f10b4614a3cf7846b7cc992e3b262f0753ee61367bde2edf82429b1a05bf3effab11186715dfe6e48f3f630235fdd78e322425c9a022574315aef589bb780cc73193018201dbd8125447900f0b59c2de5b34c42a0ac133e390f21f3ebdd22857f9eb0224c83b7cf7a501322ba0a1bf0592497dac4fed59f1eea428c9ea66fa7d27b65724f90699912bdb59c9c9399bd3eeee1fdc490b9ead67bda5fa6980ea002efbe181f47c82a5c4e052132809d58cef049f7506de8a0a7c81878ba6f4becbda51f43693257595596df690a8a98971591f37864a8e8b3681efae642dde95fc136c5b265785df37b2bc06018ba445f54b698afb410aab251353f90df8d3c037fec0c0c7605eb0ee99b7b8a5df828f9f89977f1c0e96b0ec726de3e7e877ed4e3d56f4f67fa0b56acb499dd92df70cc5639f6c2de0f5dcd036b22ff758382eb9ffa3c3e8c26a0f5d47ab0608da5f59ee14382ad5d1bdb4243aef088129dfbe9c7ad274e063ca6d556d51bb3aa86fcb64cab8a2b198fcf259723105a9b6373f298248a2578f390e59870b871f794f6e6c9b14ea3b5369ac498c562cc00a71e8248751a1170b6e13d1a9a65f161e6e99d9b964815bd7466698eab2dec2db4a8415dcd9e9599ba7cb686b0068ffd4ae95fbe1ee89c7ffc08310c4ee04da7ce52723c781ea5e2405df1 + +Input: 628bf044592032786b2c93abb2bd628f789f06095f8d863b9a140288e98b7a734f1ad312458eb6061d6a68c3bb7d02161c94161888c7d5650645cb365b63b7e46f658528dde878c769975406048748d09d767aa1cb65be4364f2653ed87b68908db11f3391392602089a2939f024c392cf7db8b2bb0e68472ba341ab4a26c64d6269e724211f167e59122d147f37d0015d598b00fcb5aa77634555eda050cff084b9d26c5acc41e1dd140ddfdc68376a162a861d29ba35001dc328f5a061d59a0413d62a0fea13a952738610f616ac3393d080d95a5aa95accba3b +SHA3-256: e1fc64b830104377e8263ae597251311b255ee3b9ff42ed4ab9d0a7fb8b2d213 +SHA3-512: 94e673412bd29879e0d4b773bc59a7d9299400aee79d7550fe37a3b87bd23a6d6fb93b895cae469110532d5a8c57d97216d3482d4636d136bb5ab342b3402517 +SHAKE-128: 4bcc5d9461d393e726e684afbe1d7b38b67694ced3db48b442982dd8c84a903d1c5ae06b4f21a5cd0957feb8a3a6f519e22971b608e1319dfb42603352178fbae31e3e73bd2ec19672c2aef2633b6d7f300fa6cc30c3d6d727794fbeac14bbaf7d0c3ba8df5808f2a1a6b16c86d50d5739c6693bce44c21a5381b6c594c177e180c9945d5bedfe6350108aadb752f835a38d48d025c51648adde215fa4e5ac9e3f18fe97269534a2803fc2e7cf35b2201ba3d2d1318b6fe941bf98dc150d11d435574ba79337bf679f1c063c9f57d05c2832f9b5b3eee0246cb6dc6bf6ec257b1c29bb636d149d0aab208ec842c1ca287dfdaecc0338e4de524f70a1558e94476325ffcf0a31f610149cfd50da56b7b39b3097e961a1308f3be28f8a0e8167735d6623677e7847b6c696a4ee1e698a06a0a35a64d986d9669613b6a848fa7f3e38cd7b4bf13362412b5c2f47ff78fda644af41ae90c23017a328b4a4e70d16b439b811f7cf27e54d33b84674c95d10e91ffc474b7fc44fc7cb77e690f4cabfd0de1f84e47a3f9adf07d1c5c2237122be88fc0ceb7ff1d50c27a4aaf978822c6e9e1e35148af68bf5c59608d00a13e95f847e816d79b14c9b6a4079b91c55bb83f8a4850b334e561bef46a11caa690c354295206406595d1914edcc8d083d29052f65ed564aede4933ad3a9037211fc9b0e4c57ccc1285d2c7640ab326d9bbebc +SHAKE-256: c0c8c55bd784873bc31502ac7e2f273479be35a07be01c8aa5ee724f18aa73f30c535ed0846f6bfa37412da13817b99461b614c0667e7ebeaee1231afda97ca02a01e563f57cfe8529cb765c4368218ca634bd2a16658366a845f851e4801d8d98bdcad550d550b8149bb6421fff709e15bc1fe9c66b056469d8d20453570c52ecefacc426183ce780ad5035917cdd188dd5952bf02e109b9f2405922043deb1fcea2c65cac1b9c6fff9f40a22960215ae96536dd64b9d7432a05452dc9242b2df5d51d355cc64d42549d82f465272a4868790c8bbaeeff120eeb6755efad86d4d9d18af1270e568471410370429be7810cdb094accc8ab7f7827f30cb9893948d30ca77f9262c4f808c662f4594e9d3f08ffaf04de673e2469b985421da59198abfea7a42f474f46bfeb0535eebc732cd0adbc69439969d5aea72179c425bd6f8ef1f87ced51f26d8141fd8a9ffdb2866a9430982fdf47501377aff7b4b4dc57017da84b27a90dec14a3ca07f943407addf8d2a7b1752b6c723f6cca355dec12cc7d3b894a2a64b3d5e7df75675abe78d5fdb4b6f49bafefe50272a4d82e780cd0742338837293b37d4491b3042a403a4595c4a452b101ef7cc4c99a1194e04a0207faffde2a701b169bd7190d8b5ffb599b76065997671f9fab50afe1bbe89bb432fdff403627869896684a2e99684b22213e362be0e3b8c56f9826b66f95f + +Input: 6fa131373bddcb6e92a473b561e7eb356222c32e95dbdcae284584693dd6a65fa73a9a7f15396cf1c80af39fe90d559f2cfe584c6d20fd706665dbbfd1f1afdc3ecc019b8e916929a7d3294910371c130a236696ddf7308bc159c7fc77ddd95c29f424c3d34c52e6cb179c8463db9c37eea4d52980abecfcfb88cdd36984dda323a6f161d842b400d43d7f310855307e18c800801ab25eed9e5020bc0a26145b1b46eebfd3042f39fa60d6a1ff7f252756bc1a32aa5008f7ec108c6ea13d7c02b09c6e56ba436140cad7cacbbf1e72498daec6063a9e808e2e5c5b72 +SHA3-256: fd2c3f9cdac7f91078a10d355476826d6bbf6d02a405d2352bd26606e44774cb +SHA3-512: 7ed204ec21bdab22f614feb76d5dfe346db0f9d9e80c60c1c3ae389068a8a46458a89bb40cf6612bcdd5b4288f88ffb7f272e6340ba22fd77b2b20501b515047 +SHAKE-128: b95d0619405d42fe90685f69b72142597bcaf22ec65570e9aadffd04703948e080cc49d0174bfe41fa6f13f11a5119b7749f44bf888c22fc59c6b37346026707e291e425aa1679e99ae7961a4be4704bec2594693e4a7f61904ef63b71f64cb15b9e5bb60673d09bfbf1cece80c1719ea40fa4c53b392e5330477cdeef1018866525573d369d6a80482cd8715748aeadabd098bee76c078593e41bbd005d105de305da19988eb25dfccaf184d7a4bf64c746fabbc364f7b7311dd487e58b487bf65b6f71cb910d19e7fb39e65277fed62fc9b643e4acc407860f03d30984bbfba3fc6582c9764acc71ec085dd60afef98a26f3b197ca350a51f060d0fb41791d26b75d2abbb56e4f2a66cd52a17927567d96add00ad670188e37483f0a979186737c1d0ef2cee2d069263f4cda24e1ee854f72a04b6e4f143d38aca1ce59c15db9b685051018f8da6af676e575aba73b72fb8f003afed3914e94a909f777d14275917d93e379b935aa85e244bfd393603e97684de938a238cf313a10d2bf1a685f8e160e5b07965a3134b9d8edb45be0144e15935c298178c9ac99a454c7e15675166598fc92f748fd1b5628b78c272464a918d4b8457802613ca5bc5c625840b9c0d31402703ee690a54a108744227469485ab9077e67ad601273b927e49d3a3765a11b05151433d55b90952f60fe85ebc3316019cad8a26ade71c3e1343be0 +SHAKE-256: 1e9cc160c14608841adf8d1e4ac624d21d78d32a328afd902ab47f4de60d4e2e59ef9a02164a0c154cfc8a28c7f04dd2a9d64231b5e3d4cd9771188a713506baa5b19624a695d9961cb0933e3b47ebac81bfdcbeec31a11f1210b7013cf283e72630459dbd5fbd2aa8a6385fdffa5dad56b7465c6ce60d55f1c84580af7bde5572fea4427a845fe0901588455ef0aa25844deadcf97d7de3a3425cf13044fdc1a07336d0894780564afaa51e611736540a120cadc9da3773b6b42da3f7f41a320a34f87f8d3b64965744fbfeadd54e7e14721e6854a20162e73ad12dd822373451719986a9b00a91c937e3a4b43ce004e3d96e4fbcc33da504359969de5d77d248a8507190f4ff549fe8d226f05109e7f9b3bcdb566c7dcbda6d5d2a232fc10831cdd75c16360b08a4de3c2ea6d91423af8857807d6d157d6400a867705c5be7f81a0768be2cc23ee571d2d3471ff098e4947d52bcd3f5517373f90281119a64ef8a1237e171d1be6efce5ad4c3900ec3bd8692fadc2532fa19a3cb99e9abbad977972b4fcdc7936b123f46f3a85fa5b09c6317c22e75c1b9fe5543a6c07b3783d26bf405990548a79b5c69259e2e6ce04c8adccd55a03a0a31e0d8f8308ea8341c4aa85ea55ffe842ac70c8729c9d01aa9dcc821385369931ae2e60059e333a93c29a95028529f1c6bf029880448a75647075dd5c3376685ceb30e8f490cc04 + +Input: b9e1022cb42a3684e1aec794f8a8f756a64c587f1316251cf1916f771cf8a362dad0375d2fa6e261c03fec8e9585957665833369f17366494aa73aa82d6f44edfe57b100279588c78d479e997b4a204f5a111cb1c2cd2c9279aa77c1032efe91331b1cd624e5f1e77d8e852ca17d75343abfe974025222b84ef6771b5bcd25570784aa92e4b3bf9016742d0bea2b0369fcfa8512deb4706a456bee23396de4b0df197c76e2f41a14ee60144571e6c2f934555337d7da5c766758d5c999b1ac28912d0832d85a5e8b440b76cb5c27400dc8b5a31e8b92625863f923c68b +SHA3-256: efb0890babf7a400b83eb935027ffd1bd2df4eeb5baec091e9eb44ab51a9b8fc +SHA3-512: edb5550e2b8b3b40d5aefce96584b96785ef1c28229083b71f54c976e476322500e226d785b9ab077e5093bc0b9d082415469ca1e38a820c2a5de174bd1186bd +SHAKE-128: a22f4268a32b5b4b44c86ec91681783ebc1eb4804383dd4810f337a593679e4ecf08dcaada1241873933a317eebca8555452668d08354d574e4c08fe4649a114bb93b95dc1a6f2059eb2bdb128eb4edbb28e0abe9864123ecfb58a021b277245288b347c5c893e887f82ca586619014324dd48c9632344db7c1210bd1d727883c3f0ba6330ff35743bb57eb63e221c4679c8b420a7e02ef1d135fe6df87800450ecb4934157b8be0fcffda26b41b5305f7b6fea7649fd2b8b9bd23e7593f76f607c9d43d601904536191a86ff6a04897b07b2795b65dc5bf32e961bf63ad90956e10ae1a7637fbd65d6ae3ec96f76262111441dc03ae5f462390982a8a25366be832f17410af15b1fa0bd6a3c5a0979a197d0cc0d517ee4e2d4156326476ce36925290595ce768ebec59a4fa663aaef28972485595dab6af269c101dc5a29c88334aa6df15ab98c1ebc29b4cbb8ae8b2129f9e104345224b8645956812e12cf311dd9aa20a7b3819c65a357f8c449954b38aef6530c5fa1412bbd7d96e9c48408b1e656a6019287cf915d306b9a08da3f809fcb2f418b4542590bf8c0faeec9a9b23f07ed46d6ada2193b25b2d962c2680f2e7ae4f0bfc22f6662a968e6e3246ac7a190e4a0c2d18ce86cf8d89ca492c319cc6b930c66001b46ef9592c95f28bc39db35c7ab3c1df4b0f35310c4b5402cea6a367644979001d98d271f3728923 +SHAKE-256: 5b0b619f4326d8ab07f2d3409eb2a60a9f64e4c9d0528ff62bcfe11d6ef1a10f10dec37310652fcb850d3810f14a4c935377f2a6f337dce0435a98fe2cfee2aac478857c122f4c00642775a4181e571b42bb5adb26c6e9ef3a47d8c022637aaee69dd1df7f38edcad32992a32f8c60f4b8857a834a6eb915f95c71e0a4f2059e7124e128108c4298abf7ca7e0c5e3e1dbe50f46909155e3459b6870c54963ab7cd05cc32cd7811058fe36d0d530e3a35613bc9e142d84c79aa3c9837fd71fbbb139a275596dd9ca11708e6af3bd585d1b7c4724c512cfb9fc27d1b7aae8536d2375ddf0878ccc567ec1dbec1cb45f714d11795e2f3ef7ba4849d3afbcc8db5080bdb0290a08ed432abe6f6f855f156b3fde73cbe5dab64ad6ba23675e3e1e1cd09ada4a9ff3791cba9f8c0e7d55ea04360ea2a6c16119f8aa3d174623e82cd3a3a252ef41439a1bf5007ed46d56fcc86ab79be4ffeff432e02075fead36a4ae122e82d99aae98740f63f2a1947123100340176fc7e95e27a18cd4a267cd36990d48c40e6286022d9ed15c4312788326b4d8178e2a3fd29c1653fdf3d682cd1c632e83628522f93e62fb0d9271a0fcf5ff3cf5f2ba2e77a7a0fec43cadf9759c507fe320b63f4d0e275b67729c9a44e2df3e8c772bd613f3f67673686b05c4507f4ed658bae79c3ffe0f6fcbe6ecee2e3dd18818bd9a2b478d900c55cc4d587a1 + +Input: d2e7b64a739968d0ff4bc510384c1595cb05c116d395d6a33c5cfdb63e32309a3c1215903253e98c7750ab96dff0ff67ecdaa646d819f529741a5840cf3f9705b99c23c2675e4a9b8ab6ff203bbd0d728669b74a0a972604efc3a4749573a4e3817e0f1fab98b3f284a786f74bd3820108507e52869c91b13ec0ea35a78c1607c108333b5e361f83d62d6739952a42c69e8b13cecbf79058e2d2a0893c0c9b5b95c89befc4f3bda93fb384619641518d0a9a0959bbface9c812919f7d164f00c3c83f63a378e344739f85cb051e7585838a6efe702995488c9563fbd5db7 +SHA3-256: e6c1394d221492fd974a0d23ef338106fd00da3fbc5387fdc65aa65fcfac5ab3 +SHA3-512: de58b8b6b934fa8b0a0265152fd27ca21238881ec63df087cba563ac8004381e6914e10fbd9923809c4bd4774d81bf7210ea4f6a31b12882e2ec9209deb95494 +SHAKE-128: 5f0f4622976141b865d9e3ad87e183d9fe9b05e1273eaaed54ee0c0a67e0372eddb57f15222dbaaa6fef3874fd1d12add2996d6330a456bc7f5c2fa2b7f6978abf95e039e71511f9fe1796ec4b62c88b61126f14419109e3952af405ec201407b4419c0c22115ac446c408a4478f2aaccbedc57498079dd09ecd04d112ec281f325b9963432d81daf36a6d86b47c411fa6a36bda6c30775996d7cd088fbe2457762a97b0220d3e5c9ea17aeb98da74030d4e20aeb3fa0de06c817a76ee5b43bc1b0c148ef307bdc8de41bb7817c9441d995f7051810ff0a35fde819ba1216bd7438830a7e55df1c9740c5445a5feee2c189b279362d361ca77077602765936474487e21670fd4bff6998480d65f4b25166cad1d1af18ac0a25bcbdb1ea8d1234b314ba89794484515199c2ba0da2c7b146123528769e8d20ff44bedd3eca08ad8c44b549457ee1f3d5a2a82b182c4f086f1dfaaea9c85b20292fc751ab5aa722b15aba228f7e8e8a9db65648e26ce8fcfad64996789e92dd630f54c7e52aa23b0ceb87d0b23a195f5d5f8c7c5995f2dc7f9a66e4f2632039a30e2eebadeacc49d9cf8f55382c0b68c4e15247a0db9bf74c2546b059397cbd0eab35d0059880d7b1bcb401f3c6df52f2c85dfd75c59832df53875176455a982de055e778a3d3808118ec3fb7c9844904a8c2cec582d46e402155ce5043e911655fc1bfd489de3e +SHAKE-256: 4d3c69d1ada62993b92c4fdb50ae2d7ca5f713a14140aa07bec80366bf55bc77128bb4303afa639d048882fa791fbe2b7b7d45ea00b56ccc0e7669862deef45de9506660cb4b947090b7999bff417c9dfb819a64e4d0f2c70aef7c247c99563d5eb10da60ead138c1e6a22f8495b46d351ad7679f485434e6cde0631ac0530af7fcc621c1f3fbb9a83426982e5b0d3090b1c7828ae6440330a7ef824ab181f83ef49e397820139cffbed2a10b95a73d7903e20d4edc3617d155f5796de67f046406a9f991a0befc595460ba44118e05c1ae99dc5ed27ac7a368c5bdba7d0dca03b1b8f32ef42ce5622febff0d3f1681c5938a9afaf112479724efa1fe5a2603a048ccf7e4111df7f97e2b841dd57388ff7d7ea014c31c9554eae3d124f2083d88d3a4df9463f4b14977f3772aa377cf23f6fbf4175d2112c4d82550b11bab7d151d1563adee205ce369d83dbb6277d97d33e2bd679a8b7323451c48fb2348f702ab45f5cfedc8e7010d4543f769ea65785548b7c9743dbc3d7138a623ec8e0debb341f279b45642034c6718d3c4c89ef52246a85a396a1a7099a48182c2b05b2af7bf95cd9c92e611655b64292363876d1196db97bbeddc0273cdd86d6440eb253208f497334f9c1d24ac2e0513269e8b9ff518b27ff2158d24aeb177af62d070c50728e923dc714ddd144753e20db67843c9d74c2456a2cab9a332b9e3adc74 + +Input: 2094674dd7119005d478da6e45f2671d525a49ac99ae92a3c7f9ab8219a04491862aa67295d5913ac10b6f0d98a1f03064374e64c5988713726960f60d8f2bcfcbf429a963b7c93fe94b7b7226cdbf661004f5a450fbea217b4ac5c26be0cdebbe42956a95a8b8906d9ae441129daaaf78536789810c42d02929c4a36a74bb5b1ae5e215e4a50ac80d6dae62c43fee51a10b6931ca30bc1ef311ed0a275a876f089597dd8aacf4550274ac74f3452fa0e50e2c36f479142fdcf92245b3b7debfb06b264ca1402a22326f74fd3e41daeea7c79a2b6cd0a0d4cc8b1c8acc47b2 +SHA3-256: 7eceeea660220975f1578f3956d9c11098496c586b300273c7afb3e2282947fe +SHA3-512: 59a6b782809cff21fae5e6aa532b5e77e23fbe54d608d4af5846dde24a153b2aedb9171ab3fc1cd0a29dfd49bdcfb207fb9d0957767a8992949206b17d183820 +SHAKE-128: 8c3549380e57a3d8f22df7e3f4805865ecdeb8123d0f8a245e27fc4d24c4ba357b25fd6b30b86f98a136bfc6915f0a03f7d0b4e10ed8c087005d18367448e0fe33ae3398502d0763ab2580fbd3dce177a0b060523585606ca5e39604b8189c7ccc8678c90a94319bc0481151cabfb2cc5a75f58adb50cc5d74a46394c285fd534339cffa0705da3e98e707dbb49ce825ae1fe06e0d67b0f16657fd1eea9c098f8f58a2582c6b5e373318256e14eb8cae459cf65d6a3f8406f20115e30fbf93b4218afab25ce4e6b9ec3e0ca1da5f8c7508693c3bf5251bb144d3d99151505b736abfc3fbb9334f153476aa061d505011c1400a61d2efe1f614624051ca3110916df5c528005a5dc620a17450c1fb38d2c259c072976869c26971b227dbac11ccd6f252a7e46a0712f0d4c21f932541c13475e8bfc38309dd9b7965c6ee4afa215f615111f91bc7c20dd36e7cda9002790ae74d6596c50b0362802da7bac3c1e2216aa6ffa6204cb63398a31ca85efe33738c56f24509ba2a5103fb0b2f3871594a9388bbf525f621e37014bc18d22799c7d0605cc22eca7e868cab468ddd148f8be75b176161c4415bd2eea507bb0a07376c1b6a98b49c3117ee13dbbeadf165cf7578b0f6483d046b71887424799bee3aadef378c0eafb8a17869469ec7fe636cb4bc9fb906ee52efe895a9bb877f672bc0274807a78ecb93b2ce1979e3f6eb +SHAKE-256: 355b08122a2be5abf4df4645dd14aea16fa1918cc3ed40d4c90a3a357ee8e9f21cd5fb8fe964b3809657bba88e071ab7bf283e63fcfbe3e74d3a4037426e9dea2d2f485c5cb2d947f8bdfadeb2b10427f2c85e5523f8c3349e87ab844c70f6d5628140447db1799805987044613990036c42adb6e5ba05fec30f684e4627cba7f1a479e1c0db38fabb9942021aecb532592b0c2315d3a2b240afa80eba76da0ed51310c9ddaab22f35cb5496ce433b88b691e4c1e535629832a943c5012b6ef41f6b2e4a0a2e9240758671ce5fb0b98e60c6abd58c0c2f6137c4eaec12937208a6e8072ba5574b01707facb770fd46d610d496d44f6c354402264ca2b7cdcc8585959852d5d4bab036cf45b21de6fa975640bcf7852181e102f80e5865332bb1299e9be8df2fcd7f28167891fef04aac71eadd5febe3d463ca3393ab559cdc2a09859aba73a4fdb01bb7aa5197a0791d973596a3e1e78293e95dbc6ecd6e40f69c2677e7930c2608d01375039ccced676c8e4c273ef6bf51e705048fbeb7414a266e92d80fcf3de0fb4c3c4d3d1015bc88d75926d1265f2f818ff93d2fb4d2442b2688b7bc92bbe47125ff93fc32114a82069399146973aa3b28f829f6e63029303ac6a3eca672b759f5c571ed58df2c280ce4d47213769d14f2a831f88d3dab6b42a0f2d553ff0f1dcae10f8f31f650ebb275b78c03f6a9928972252482a4e4 + +Input: e73e07075122a733ce1ee9c612ebcd05343bf8a3b21dae3654fe35517710bfe48237cc74ec93ce6f6009e8c02592520dd301029d6698cddcb60b9dc89810ddbc5d6f3a1ad58611aad8f03e7dcef01581b8158cfae6f8de0ef67c07144c35ce0264ba68e382f06ed0b547a057d0f2c17436e94dfcfd1562998fcdeeae1184a57912b50c38d5f4c1c81ae3aaeefc7726eb8acd7fc96cc103f6e16907cb9d8866ad487e986ce13983d9671b7eb249ff2ea341bc2cfd723ea6b386ea2003d8ee1f7b6da85369a1072a789bba58f331709ab77ef98f36419a2f363975c362b5f779ce +SHA3-256: be4a321e0ca25e0bd52dcb9958fa95458daf8035a3c1ae3918f4b266e892130c +SHA3-512: fa62af07d9164309ffe3d5af24689ec1dfe173bfd840b13ad9cad29447be6fcc87f54b11d2e057c878ef05eeb35fc564447696835194aaf78e9b82ddfa6f3169 +SHAKE-128: 2dd8651cd1299041d6714883669dac82cc18686d18415c551b45b85f0fc87a4137cbfb973962be0c36ed388ca1907eba070198a3d9b45a4133bf112ebb44add9deeb41a66d15fcf2ea7b78467e7d9c3e3c068924bb507d64484019087197a2b72c52dbbef11bef6fec3005f11a4093b72d4aed1eb379f931a85f6413b431d452fa4bb251041451e6ae39195be4588e96cc3d05fdf08d5abd46b49fc6e1d6f011c9b55b71ed135e599d1135c28f237a8baac0f22eab26e65a39fd8e2bdcb133917386f13fba6e6d62705d52add49769572f1a7cd1d311a4df1f730ac3495c938157c0fb607d30a1a7c062a2327fd57eaf3bce8e54b8f00d010dbac6bab6f9158f7ba7d42a7451886dc84b35d08bdbe35e07d000653face42e2f0e86d95e9055929a968ffa292adf5e08f24318e76be64329a1b1771866686cddf24c16e413ef86797e9bd850e75c8224ab2099aa581a8f2010eb730b24e1894e063f793d4c314876d5f1544476e371ca49bb1d1b8948844932590cb91c1b3172691a7a0c1b2ba1c97607c1979b0f0458861ffc81a6d145f0f55c01b6f62252ddacb917f7502da29fc3bc829c759ac5b3ca506d61beeb1d60de4fb59ee2adc7420a956dc93916c0cd582e7370b46484b9dff822b25914cbbc8d6fcab14bf31c78f33a2f0b654d10f554a23f0b4763e0ef3a1bd151c242a32e5b56ca62737fc1dccf4bc48f5cc5d1 +SHAKE-256: 807fc779a3f5d69eb1d86039ce80eb8e2fa49a1afc85968322acbde10de1d3a73ed5d445e0ad12e53d302275d4af9646e2a5dd034aeba787a8ae4bc7311f9d723c00a231d98fc2c4ee9d615e92643e0e731cc92ed0d81e8f27fc66be870441b7bdf62125c56bf5fc1bd3c667417a7d290588ce8908f9450dc1604d5ddaa448d3aeb0a99a5b53157d2660b000646c098e5f3ed92e0623551274d5c24896f77e513ffadfd04b1621ebaef5d68e51f0d08232c4ee837d0d4a5941e5d92e043a0868b5ae7da8ef1252c7fa6c6fbb5cb82979dcf7ded7e2744d6c0c03e6d2f3ac66d3bcb33937239026fb65861a1a7584e0fbc9eebb578e67795bff259432018b69c47041fb7e1449c4753078d4a6c305fbd6298fa3562c0c132492e45b84851bbf65f445887ef7242ed03fea674d6eae4866588904fc97f4eb42d83cfe589ee88d1f69d2a17529733771b3da7997adfcb994e37ac88ab63c37bbf2e34824ad9c84c9accbefc5f0b6837964dce191adba8ebbc28af0fa69aa2863c03622f7d88f98ef1d08cda19d986d5050c28041cea7a90bdda726ac80ca314879d1bc1115f95c747abb923bf6cff4b0e395742754cd9c454eac925c7c71a3f97ce529b2c47f987cd00186efa82c8fe9e0c5a63669ae1c63c51062a067da99d8591a8e7f4c4fcab2e63c08d543183f33abc29fc833b64aa5d468d295c120f30e1e5179af8b2ebd4f + +Input: cd1fed9185894cc0b898af43a82e4ba2438e25ebde851b74e8ad73046fe2fc64c8c6e1e0b0cb4ca030aecbb2daf9374734cd610545dea0dabd9de9a7f9b00523e73dc571be43de0bd4b0672a3eeab52ed078055764fbcf62e428f0ab0ed025ea1a8d385c550c2028c0a790c96a97350c29084d5d5103a17484b686fb87506aa0a66fc772bf16265d55c42994039c04df6bc8f34597fdfccad61736fceb61797ee6d967d371fc9f440d18cd203bcecdb68c1572a80478e52e1bb497c683e4c30f4429a6186cb547ea5e20a51534053cb9841cedb43c00e4a0940319e1987e357f36 +SHA3-256: f06aa9a208ebc715bddb0d95ce54c5db83f6fd047acbb8fc79f655e8fa052edb +SHA3-512: 3b7aa9b35135296bb540ff7598163a5cbfa2c89b32244586758249ad2d42fe4072b2337e2bd03d168f01b3bd7ed38e4257240fd9600bc1f7126a7079d6536862 +SHAKE-128: 11877b7bb55a6a18cc0831d63f728e0d8d905d671cb76dba34957d80e996754cd43bc79970487f3ab854e7f4fdf4fc7494b1db4fff800ac58fff7b7b3dc4979a813eba74a33cda86b2e435dca8cf7837f45ec03c0415193e3d8be306daae69ea8496f02d1b7372d43b1b72b511a942d2b446889e6af442d6dafd811256447715f40bf5251fe049beacdb234bbd04e2285c49148a1be827b2f78baf4794ab234c059b3415a8885e2b7a1f3b7640fcd0ab5086e8e27ecc681e6212af4b6c415734076c9601bbe45376458641df6ce334c0ce6da0c2c52719275886fd9fcff2abfa8f8cca6f8890d7db14833699417ec14f7a0f965b72ce1cfa8df14391a3fb4c6cccb85a0bcf842e81ed8d72b8579b97fe03e7ad05ba5be5ccd931ff1767db75ab0f2276b0dcbac3ec726fd7e5921c672a71a643c845ff07731ecfc4df29e18a88ed9cb2d15616f312e27355cfb02a4fd7ed8fe3ab47e02296552965237bf3a438459282e9b22248fe59ec738f5421821c94badecb1a2189f7f0564882253a0a413b9827ab7c2c667fb79ab4fad9e90f379d7e908072f67bbec26e617ec0dd30bf711f6a06bb374d43c2e8d73348f146b7b8110508b2ef9db3fc952be48080158d8bb9c283deb5dc99569c557e9d34ad63648eb98145b14071e879211b7613c0ddabe81158b656254630f7c41e1f52eb2366d52a21e574baa590810143a68bab97 +SHAKE-256: 40eff28bbf2903924dc849be6b9771532cfa3b161dacfcd9498c41a9079cc2060cd3bf08ff59935d8f5db4f90697d10baa8b198cadfc220ad9fe98cf283a6fbd4e2ea969f3c57921657f7b06246155cf5ee8c342a3e8ae84b790093028e5fafbbdcbe9c67ee429ba46e60d46e987b6f0244850629844cdb5ab50622d9950a2d8a4e13f0fd5bd49374c8c437676bda33d74d9064b5f53309bb9a33e97c62cb4cc142707b7cfa41aea84a5d2030835b1a6f5abd7537ef1b4258f7630b7c7b9c136aac3b52bace1de79b8f35c5ef58d0134145ea531f3d68350d47ecc4f3f1728462c5732c8be5e52bbf3e2f980853af28da947e2f2db359975c1b562f4fe92494e00405627cd86728dd2bdbe054181cbcafc2a35a31c915691c1f3ecd5d1013c2ec39356cc3d021c328b93db7180321bf7205548609767f176db2f75e94cb4f453928154f2581ff3ddbd490d6a20a354c05950e48584ffb13c3290a62bfe1d01c9327eb3573fa454ae7826ddf241a3b066b748c0bad8700a997a87024f7846562da8bf417871704c2dd5bce52ee9de74038e7cb6a325648cd3365a43cc56df27b00fa86ec73b7e941a19c601825bc6341fae4e4d1facd20851850f75de764b360618a186edc16088b42389ed720443c21589df73baffff947d22abe451f6587e94818a8da7909bd540fcb76dcb649ec42ffe04ef4b11b5bca526192f3b5ea394da + +Input: 1fc72a8bb1cec04d3a339fbb52abdbd836feb9767a08e64b4e9d58d009672ff8894da74bebdb712f7aad1bed506422d7e8462a0282415d2c54d73de320866801b066ab53090c5c01478465c9126e55443a8bc15103091fb5e9ae3c415fb458ab992bc6efabeffff1c0cc75ee707fcdd895ca1506d08dd4816e69c9afeb06da6c373ced598db76292514f4b2a9f2df6371d3b4a835dcbf8a1782c679bc2f36ee57ca6a11b9dba1f697698b5cb7a3256fc7ba3a914c72387a673d33e0ae8da86b8f6d335c44bd5d428ce627d008404a7aa167a3f58bb5c49bc8a5953898eb2eb2a2786 +SHA3-256: d2386e10efb3242941654e4689d834ec59aab61b206ef63604e26ec12e0af924 +SHA3-512: a3726541bb21a573fecd0a8a97cd98f9479fe825515f637b3eb643045eae9462818b0588bad1ddb68ee0aeaee128c4bd374a907ae34b4b5b32621228939a331b +SHAKE-128: d5f964e616bb9c72dd5b7e7d556c072bf209f26aee132c4ea6e60c4d694649a3407d0373a77b97661ea19d9ad295e1ba5cc9fc7bea95d1e9c2a7b75834206386d176fd80a6e59512423da1264335f7058fc7cdbf2511d0cf5943d3455ef208e39ae6b8fbfe3fab43ef37c109fad914494d769c0c7ba2d134082aaad131d04a60aa3b09f08b95d0ad14ec00068f2684aabacbdccf1fca5b04a9faf6e176b2a853c2a4fb123ae0ebf6cee4143a5556e2926b101c25482889df3e378d19fe785354a890998c98434754414ab22d9a5171fd19b691fede3651eff98619c176fe77c6796a2a14da4001319948f501028dc8fc33d344963c760a05aea218a7c599221cde73a4afed589a8cb3fa7d96b30c3e75dc76f9d9eaf35becafb09b221a38af21e3c3fc9b065ca8e9e8d29251382650064c6fb1301b513a0a33057f5415851110bdb5086faf2e359f98455309309eb4f0bffc550e14edb9c2980ee9409493edf531fd05fb65a8d14cae4cb3ca64a02a217003d5d1e4284f28d494a9dc6718165c95fe71926e53cae299f3a23787d022dbd00d0836e3d002de66bbcc03c34f039b10495273a0eaea61840040fb7ddfccc44c6ac886e27e58c8103177b8260a88c2b48b9d6aa089beef1f638d08e48cf1292e469f8b3f5f70c0b66c486eff552b586feeed84c347ab68f8537db7d640435c394a5d607114dfa7401348942b0eaa51 +SHAKE-256: b7c3409ad333b73e68465aa9570430a479904b715d5a0080ffb7860e9a45afdab76c8085bcde027ed84ae86688f739c1f43a998902259f1e6f66d692c9886a5fef9f992b2ddb44c9cd900366d42f7326d73e4984a2734fb2fd1b6ad9a8878a93b1bed8ed48d3d59a19d54c28d7d91c3b8e49137212e37533ea67d50e64f239e54b6ba1107e61198211260c98d4c57900c8f859280efa10a71a26f1831a64425658d33d1991f3845c21cf7faf05aebea84f48a3b25501eec17f79a1bc59a4ada9efec85908c7810847d4eb9f2bc361cba3560539d2c7c9c05b866178d84dba73ccda44fd28350cbe49f5db53449cb34779df5fe8fc2ddabe3cb9b22d6678db2c072aaca0e9642035b28655eaf9553cbc52c333723b6fe86fa378ddc8f587c5071a07f198fb75d6495180952cee3cd4e4f4e8af616ac3df77dd1801db4ae94166c325c5c81c5b7430bb26910be607a2d312aac29c84615a038b024d3ee8b55ec5baa16a42ae6586b84ebb2c0a9d9faf52922f056c0301796338887306be47772884c44785fc908c9b3a6208eac5012df811567be0ae322fec748367219e235670c092729a9f1eba45fbdecb6cedd7f286b0d810199e20090b9b386718944394d66000d57b539e6ceb45f9a62379d4e2cdf603af5af7608e5c6e6ca8758b42a4e0203cbd2f7b95fb10fb7c4d05cb0fc1b8ae02c16e9a159d9f4e07607e41a7c2b6d + +Input: 70d04e8dc1e06770b25942b7186becbcc0ffb4e8a13f2766b6c2ccd3b6401ffa5ba5b665b8148b1f19018d5a26d5c71836b440e9aee504a93929b18c2fa208a3bce013b0a47d60ff083e73f24088d331a18155ef8fe0ea2870df271600f25e9b4d2ee33c8c84286c7b5ab9e1a2330c337d9012979e77d0ea1ab73474b84e535d7de9dfd9d93573665129abc71daef1f2c927f06f1bbe949cdb3df0233ae3cf347d7cec3cac84659832c43de9bae20b3238984faadba07759186ff5f42635180e85f20cd500bd6f0db358972cb6fe33d0ae1a755200e851deea582561f73dbcb99a6f1c +SHA3-256: 703f307f54c11ed6d0c78a1a0bc01029018a30eedc44c73fcaad5caedad1254e +SHA3-512: 9ade73c7c87619441fcbae921ce91fa216f23e069e472efed144e482d98450104e3a32d97e523b2041601b643baf40d8f72959c67616716a40a2a5d56c020f94 +SHAKE-128: bfaa2b064b5fb2e34f0fa5c756a3aad82d31e66e48953795d8e45cca69c91d93062a6559eff09cecb3a2c43a4486a034d66132f78a6c391351a9870eebd1e735d51f94f0f48cd76ca9d4378249bd05978cab5066453596f63b641ba4747ba05f09ecd88e457e908360c8a42266a34a38f4654a572e48463197dbec3c441e5466c7e369ab7995f4406626139083ef8c4c4a93da9acf5dfd45aae9cad7326cac634fb1736d1042ddd47e09e21610aee7543a03f22d449911f2c31597f76294c320edb30efb61a398b33fcef5ec7e96fff7fa808471d11576507c59b98c22d76a0d0bd51981dddf33999a288982f27168da573763c01ceca70a0cc839ef1054e042af22a4a7f74192fa918056be04e3c9f23a6da2c7b2247bfb2117576126b7d5e12eb9a3255bed0e6f577fe16bbe7951f5535468f38cbf9c4c756d1a367c05a156d41877dbe4a18307eaeeca046d8839536c9fc3fc65931c9d8b5c7532ed01653a318fe34c2ce76ce8d3bf74fbb50335236686917b0afab7db8fb2e969379ae9f74afcdba9544762021c12227b9200aaa531ec0bd31b4df2dcfb3fe799e314f73abaa6ea09e6b24fb4efc15a658386e04d708ba422ee92bea57404a1812ce543973e594974441a85d0644639c339cad04fc3d49d0d1dec72135d51df26bc536a0dbdf5dc298fc7a51d110b9b3c080855f4b1d63b27a2f846c46eabfc10e2456110 +SHAKE-256: 49bb833777715a6494e67abe3418635d56a7fad04fa5f5a3dd783be8afc5a370b546d4214f200e2eac6eeb87a582f9221dca350d8f982892c610e58039824d29432fa0979fea554035f28e837d780dd353462adc7ded030985a8ea71a204668e4c625645d1a0444ab66bdbee5d3ec8eb4f736cdf2e2227e94080fb0c9b9195ca7cd1157d097f045a458eb020163683af8aad2e5c4da4cb86a0cb7a286a577d2d14527bc9b16319d71e89cc109b0515246032fd2770db3e3583b718cc97c58aea39bbf3b57be9e0c15aa029350e4e6d2baf41a229b76f88096296eac0998d5b15c031d3cad4ffaede1d8cd61bcaa32cd8354b2cb672bfad25919f279ab34577c607fde97ef3b46b00f7521380931508dd5da6ab7d3487c37932b38e57b4efad36f6b420e0928e658cdfffcb72fc85719511ec4092fafd7269ad0d53d37d29ba9b5e08ab2b0f8f4e47db27f5640b28d246e07e4f9306b43bb10e78324192aad60422846d340a4a5b1d696658d866f7b426fbfa430d337a609777d994575e44f67d37501d68fd182167eba82902e98ae174d38bf9d8e209b65e6317136c2b08e80b91947c6ddac565e5a371bed59be36cb266324e6a12e9db7479c980ddda8fed2e34713ecad65c54587b72a18089d73a2460c53bbcb93ca303761ef1c63071727679554fac3fe0629df21de72e11fefa25cd6b018b29913ed7f4f7ea2cf3dc4de7 + +Input: ad2714ee315407195082a3536522a2e842bec353e84fe6e582fc554fd18d202245827626530256457df1fe2de6f3598e9b9adc9b28d4b4df3356fdf5823050acd63a25a54a99f4cc5757ed6caef879edfdd8710191581121384ed1beb5b164333ec52d9b464fca768c4c2c3b63a8f41cbbf025d3ef84fafe788fbdece9f5397bd66493de3a37b8c0ae921cd401a903f70e995cc42db68e30981cae1853632df17b87845029726aea09666ad52c96170c1eb445e107f156d679b009cb22aaaa9578abe32fb6646a94e560097ae9a47116132fd4138765bf212588d8a3d46b929ad16a4adc +SHA3-256: 1bd9c2f03353de7628ea44b5bef95aeba9a21dd4c90bb5baa6e4a3a18409916c +SHA3-512: 17ad20dd30200047a91e41b7dfe5aa064d08bad5aeae8d9f016fbe9b45476199d60a778b51f1678a84f55184ffd5a6230f3f18a0ee2a04f8ba60629d2a5dcd67 +SHAKE-128: 42bc67410a1a9166b9ea6973f2648c12d7a79261e07f54e5f1426924ce222d042583c672f0d145b32900c01c804108bca8c49643f11cc0f9ff2f9499aaa411302f067b61edeaa49226d7c60f1a55d1a48e0b356f1f183f84746a290a418ba99555ba2dbdca7f64cf61c23577202f843928607f0b513446967a17bcd48cb58ee8bcb7893f07d28d0530f24c4e80e8c0918b8b9983c5a886dbc0ee5fda2b36156cadc431b3a16d1e331d7057d75051ef5d27f6e503fc7c3153f3f633ff33222d166d423761d504af6c719552e402537103472f5863a6a6e51798411ea6b8c45be99e814992900689d1e896a5f56ae1be23c7403672a457bd3618be91d1b205ffed5f977de87721e74da04d479cc48afe57a12f3b31de749863d13cdba19f31f17601b84216d78df3eaf969430c7d5b1c6650807b50eec170ad507155fd468ff52b704a9ce7b67fc7d590efe25221dcd731896453678a2161baff4ef1b3ee14bfb7a38a52a7fdb5ca40ecde4aff429daab193de993139335bfb6affa4d915e151e0f7740cf608b322120b349747e2754522fae30d60eec4204e9dec55707fee9e1306e65908808fc185cfb8dfa8f730dae96cfe5b41fad61f9371d5725d8f48cd48ad3aedbeb8a4313c7d05c70a8c0f5fe8aaa65bb1d1458bdbcff795a34f15e0f2dfacd6de4063f22c19319702da0e31c935b0bc2814196d50ba76129bf77a25e1 +SHAKE-256: 3950c98e24fb4c5cdd6c408edbd9e25db4570e886800a4a1dd2cfc91f309e8118d5069f3e157a46509640406f92a3e4fb0138044f2be2f0433b1aab73df399bde2b74c04bc4a81fd123f122961ad6659080169fb70e95bca29cb90894035b4035a0439f17a99bb3bed637fccd6c2573085d73c6b7c312afaa20a044ec681b4c6ac3a2ce511eeb7274ddbebd97a7b49b3a4e356ecffcb3a7d3a4db7205a22318a9e0bd6c4c9712da89b9c47cc9e6d6ba23366b98d06074346b842698b9728dcce804b291ebe17b389707d6c2fec9f7f096e98ccdaf6a59f3e4cca0ed293a373ebc794d7d981be6987c565234f187296ed2edd3b0495713eebceb324c3a6405e9c4dbe7a71db01e31d1ff6ff042bfd3604c3c03a8e065867a3179d4989ae4887a70c89e05a746159c589cf4fb63eca84e13887d77822cbfe946a4cfaa0712f051ff2442b71e2057313c0952ca45a676d62e88fde29be01fa9d455db7fc3bd59a55e03d4cd04de3591355542b8ebf9ed1d2d3b9aa980deb0541e7bf8a00f2aac59956ce81dec930a848efb3cf45644b122937f489c4c92d90efdfc2c61a03e9d5f2cf4797e3480c6b5d4feb5965d62c40e055519826d78e94260b21eb73cb3b1e010def722c2487ed1a64492e8e7aeae6eff6743bfe4e75fd7193f9f739c543560611cb89a2ad9837b1db1c25098169bfc024610da32fb4e0ff3bfbac8929da107e + +Input: a2c824a11f6ccd3426a1f3fe6179749b3466cadf1e724d0da3007567c41ab47279bed7882bfec231e2952e2ee7f192bea8ac1a2440dc1caae0b02c40979130e356737e842d1fd21e3a87385228ff7f5609d7fedce7244940c612ea528ec8d441444f10707b5ad3a8a199bc3f795e1a250a59eb9bfffb7c4807d4270405f73eaa5b32725ce82cf86fca0d253b0e73031d3063973fe46ef1bc7b729237e0efa7cd2878aa6ff6b95dc4f52d0c2437fd35456b8dd2f6ed4470f709e8cd46700a0518d9761f3b8fbb039445f0153f0e782a63c1b623cb958926fcc1c6cf01e6b80aa204809435e9 +SHA3-256: df7ca5feb6d2ae7f7df2fea79402ee137b9e0cfc530acdf91051c47f6910b0cd +SHA3-512: fd58e6f16154ff640736467bc3edf239ed3d1953d47aa580c5ada30b66713737be1e4576668a4b5a11afd2c06f30a5cfd24a513ea0ebcd2a58b9da1de24f478a +SHAKE-128: 8cff2a722350ea98908e931ea11ee7ab3fabea4c775518bb8c4a558bcec9551a6304a3b454280a51c88a7449d0de0dd5d712e2272f0a39a66403a0b96acf8fa361ae3ee963b17965642bea6b06b77d9f9140e05d9c125660146eaf769e82ffa268234d362eb398962d99e83664ef3b850ca5fc9d696eafead038edf5e59c2ed95d2c5b2db4525664254b38895e110ee7fee96ac2fb0572b1207400cbb652de80d2c8f4b2204df7474fd65ceafec5d3af9b3e935f90b9e7053686d1283025eb2b4daa7381fbb403141f868a634b3943f25ec77fcc8b713211cd5b3a9d09b53fb249e43d230f992f2f9563caa657c63a1642f1de2f9da9eecc2307ad5270875821dc451bbca6a9159ed90d56047bf93b202f0428472ae763c9d2515cb3f54d70e57a98db95fc0dbb6261f1b1841f761a98c3bcc3d4e25cac62c5521102d8895e2018e6a49d46ad8759d442fa3cb5f9c2ab2cd5e1a5424ffe0107cf043593acba6500b0adf2d77fbc2eadabb14ef22c14ab1bcdcc35b8ef702b5f8d79da6b99204fa3771dec691da24d332e7ca3c7cd7bb7efc6872625d0ca42f8c737e1966dc376b589b6a937caeaa12e43094fc64a66dadf2b823f422cabce34b44f965097c15303712dd348d95b6a12da5c2b20a2fca05ab0a61910a8b423c4f952901ce09e6e1708ff42f664bf489290df22af6b46f212b54769d04e0383578a513a5ba6f522 +SHAKE-256: eafcfe6b85db69f2574ea0aef9ad40d2ffacdc7dff546f1fc1cc9c085887a2bfd4bc5a155035339c6c484ac98c9585d25fc4fb6a00164dfe48c27c33474538e5faba8d797533e4fa9960fa821de4636bbef413777ebe5ddb98a64acef648f136f94e3440576ab2aa331d46ed378bd2142ba2606b09f5281d887e351aea8f6a40f54e494a586e6ad47791a9e41e455b884ca610437fa9ccefa0c91060ae885c9ce83bc14e5bc7dd6b77fd9e09d650ccfe18cbd84d44e0d0d296fd698b117122ec8e343990bcafdf4558ccec74ed6e67aa0fcf83bf6b104ba23ca8c997737afdeb0d2a90aa033e6035d5cf9e4ca1f7cc8f604a0a508eee1399d922a8ddb5c89b4a68d5d4dcc5092cc19885c706bf8aca8b1d4747bd42cfdb14cecb075575994e6ff674670641c16f1487a423d39429b95b27a3009e1a1f5e068830856a4c14e24e7e292f195accd8abf7754699fd699f61f801a2fecee713f148504b0a31a75849cfd02eb13f3bc2cefab03757bce4f5afa07e3bfc701946b088e52e3290409bfd091940d00309ebea1b3481672168179cbc8983d38ec76e392cdc2dc19c742be1cdd89eb3d13ea620527ac0f09d7681edfadd8b83dbb308e5ef13438520d7459b1f836f00fcb68199a88f0e016d20b16e80ecc14ea8db369134e580118df9e5058d5f1a155e80f9a06deb871ae8d0c2495625e2388f5b6077bbecfc5b03c95326 + +Input: 1e516cb62bd6ad8ec887ef837fdffa0d91ddc85331bb24998b85601be2458231caa87da5b6571199b8149e166e7ef6acb5dc2d4cc00ca8f98758ae4fa342eeb8c9d097412c64898266c7cb7baeada32c01ea6d9970e6774d50622b94d8b559285e6889d3e10dbbd68b3fe6580fababfceab42ccf9c6815929b14e589d54de96ce09fb7e0f4baa5d9e7632cc642597465f6078d61914dacf3194f51dd796264e9c9f8115afb05ccf39b3bd800790468ff2ab9bcc05855eff48532e3f9b2f2ab1aa72323291cc3a86583353e509d26f1f4919a25f830da4d0aed8440d4dcbb5323bd3538ad9167 +SHA3-256: 4a68ee4e6a66e6bfa419bc3ceebac6682622419a4644cc7968f4aef766d43317 +SHA3-512: b7c38a6acfc5f290c3903889ecfd36a27277f19644d3d996fd17fc87f6fa2cd157d8f1be5cc2de80331867fbbe5bc6223fb7faed10971e46921903f1027770ba +SHAKE-128: 81fe3cef85559441ab5f821dce0b3ad7d64b2e731b2020e80e53e6989308344ad92aee14474092f00b64170a8eeace79c34d56d68eed7b73b3cde7884c878b17bc264b63c26556c0fbe0bf11fb8ecd4b4f8242b287cd75380db567df401f7d6308e4b611332a9f807c8ae99cea6106f30c22613d057a0b236efb7ef32de40e9a909ef7ed4560ef09d5a469cd77ec153baad98e9430a4a3fc0069d38b4eb841b81a64cc51d3a64227e5b4625dbd3b993dcc46ea0df6fa270965c5976ae8c24a3a9dc2436b7ff1091cc7332d17fe714a7e96dca4a8fb8a449ea8f27a46dd26a6d43d9a5c8d3d1f8af81a7ecb7813f5d488df3421993097d32dd7e80b1d3f1ed6ac073bc912c7df8237de1cf68a70e1732b71dad9596818117843545c88415336634988cb130670f7a92094e6aca6629cc74c7265d86d65f13cc0df895adfae2f7dd437b63e183738164098dc1970f186964183f9ad479c0c43d7a080360e51f16084a0280311e75ee62c2206ff42cc6d7e49c44ab3ccdf895ec2b4af2f05a8f2579e938f98c4cbe244523a7b74cababb8ba20af459e603eac6ef04e95064fce2baaf8e655b011f1e9c80c99cce4b9e386717b949faf9f7ad437dfa06f57ae96b6cb21f29f18f32cce94eb7ad45af041da3d6907397e787384676ff93e01cc295344ce8f523f44085c43aa305f97d392fca80e04e455a08152fa56057c4bc5a9b99 +SHAKE-256: 227bf6d099e53606dfe403f5abd87355b2c029daaecc55727543eba3575817ce10e5c3f0667b6eb3b008e9f60fd9f145097aca1381be7f06a3f13085fa2d62016136ce410ecf0f207b0a4523e88e5f3b4c8b814ff136f1248f206382c279d4ffa97d678e7cd9db52f5a2eff30daa414cab2cc4938586467ef85c78940ae78d6c40792055c8765c68a5b5f3b4d32806b1d1cedcd09c8df374dc97f9e57cd53633eedb4a9a2c05c7a71a2d5c7b2f2db3ac8a9451ed63d6b77384c1bac6223e26e9589974c6216d9edf79df139942363680295a18ff3cb2a694d18fc5a9bcb2b7993ff0acd39f1df026c19f7a3fe747c93de6faf7c62c3ffabeb6bec1be4bfbbbc83aa6da92f5a0d7f2b9c53e183c9a965824fd3070224ab01f48acd9cf6a1fec3ff48d1def254196ae5bcafa112ff96e83982798bede8d5f1a70ae901c1ac93103a1828d57da018a024e3de86e51d60f6cd322fb030a22007285b9145ed54c0c51ce711975207a4b5be0d1fb29650fc52ee8b8c82b2886cb4b594916de568a9e06064d479eb4a0b1aaeaafbc014c363b5a4593567480b24fa931fafd91279af2a71c636eb0de227134df65d364ab9ddbc38038d15c378d1cdefad04647332bff2adfeaf8854439f0da106daa77aac4df5ca5db19ed31bdc74ceee48eca06dc9b45db8eff7bbf8ec94e1ffa09579fb56ea974eeee091c9841cda629f3386efdc80b + +Input: 96ed40755a680da2e163c74eae0856f1435ad63e76a740a217bba48ba77f8387b4aeaca18037afe3f7a6b2fc27d04879c9e3e17a43612afc4a7f375a19c284d3999d81b5a55af26606582c0219479d37ad1458c3b62e458e572808859c2310db02441b5a90155d30faf0e9400c7093cdd4c43dbabcf6d54ded5adec2b11c9c83a12c314a154938479addc567d17599718a4df761bb7445b843a51cec9b8db24e11902e9216d9726efb72fbcc3bf5ce4eafda8952ee7bf47c1842b7c45107e9f6b3c08abd345b01ed4959532a4193266898ebfec430f58cd7e5b402e6c5307aed21e835be7fd587 +SHA3-256: 38a0f7c991a68615e43aad7f7113b6b226804c69fc95f80c185abb7f415b6037 +SHA3-512: 9273679e29bd1f463031883fb3511f16a99e143030491a404b98acf53d2bc5419e653f5fab9e05399c7e6e281a4441c34ae39c6b5e33047cac9348c77372c1ee +SHAKE-128: d38b3f24182a17e05bf408bb3e7f5d3cc92ff319ed295fdf2baeec860e95bc10426acc995b69c34a97bfa9dcb477b401a38b11f1955f8f7f403c1f0f8002a04d95c65ef267cfb3efa279103a0193729a8958ccdd6323691116cf9420f8b711d2abf51aeaddd18f588274191c21469b1a48aec40db903033cbf988dad24d8435ae7524f932c936e1e276dad5d80431838c228bdfa9d165160df9d41e98b130acc9c079ac4d3fc51386446e7c5c5372fc1ebc2d2ae430cb3418882f3ca73b5ea34396e0c1d8c00158a2b1f440ce2d9ed5449de7aeb9272ccc3fc8ee3a4058db676c2c7e8477fd7ff3e2e1cf618cc35650ad6862a66d60773d3c238757b573bacd1f48294068ab61c5f5f90c8166690b9b467f195b1abd8e53601a922bdb9dc0fab32c77d03e334c241febddd494bfdada46b772e62b12693960959c80b6d83c00aefe9d556531756699080fd813b4273c650094cb0eb3c6509bde4058abe10f25890c634f342d20d2d02d0292e5c23789ab5218956c0274d888386667329801eee01e4119984aee457209a9decebe578c12b76ca852ee06c1280974b42613c7f685735bdfe56ff5eeb44e0dc8e93f4a6b477a279dd78f5993c2c3b3b7f4e0c6a2deddcd599a8b9ee0b88918be8bfd2c68e1f58443f2046433dc37198126c9d5d08f54649646e77202292c4d90a70dc756990d7125b475cd8ceba8c0613347f6ecb +SHAKE-256: 16547da68d8251d8af605ce2963f41dff3db32f4b127ede06a714301adbd217c37b47877edf5a4ebb374477f6f23ae98771b9b0adfdfb0a41b8698c0bd79eee4c1eab7da1ee4270f7d90a44a67fcbbb1b3746ef6281b52c8c27f304734a34d3e93906a46c6ca94048f5263e7e624184b13526e004efbede02c803f7dac90ef1f64511eaa8a7a37406928471289e970a86086e3ef3ad96f0c307c65c4ca96b886d96a8b4da146ca22c1a8149616c1201e27ca53838a54122dbcfb79a5612b38730d95249a84dab2705486af77ea1b36dadca36aef39028387e806736fc6f7aaa3129b19cd0cb5ebe775a6fe5532d82d05fcf53363d26a22786dd957373d6028110b8abf6c7ef2ff2c59248f54ffcef09c9756678cf0e9da20f3c10b1d30c592640c7336ffe170d279aa5639cc64deb693ca72060abcd447405944ee3b9ca8b6099cb76219146be5efdf68a84d64ab5daccff2295780b32f6466b9e45ca19fbe6d6fdda973eff1f66de7412ca4ef3ebe9ea390558457dc33460d9d5a3ad48e23b889ce648b9a5c01016439ff2971972113d57af57ddeb44f47b92cf02daa3c1d309bcf3e5fa3b3e4f0daf9d4247ddd314694581276eaced7e6dd084d5c3a666ace58f75c9ffe74e16368929975b291dfae535cb17a65aa7d80a46018116a08d468a8d97cdc7f54a45a3e58364cd64cb5d8202ca4a8a36fcec5aff5e90b251fa281 + +Input: db15cd3afb2e55685fdaff2935d9f9e2f5706baf34afd5fec6e9c26ed0b1cb824354e4f967ba1be63ca22deae8eddad24cbd1d0f14f882499546d4b1f8e83db655a934a9de1d9cdd1791c3e2251ca475d91b5cf558232c865af118bccc4a8d8f2cf10e55124c6547da721c3594ccc2423ca586f1e1347ee9eadb7cb62e2982fac8592a1290fb15ca13658f609edd8b874f2beda2ec903a5990e49700b81d66d82797bfc29ebef9ab159590f06ac66f1d398a8f1e697bb25de0a79cc73f793c5438c2bdec00a6e4ff7121ec22a527e18d840e9c7e7277fc9476efc35c75c13bb92750aae504fbef3f +SHA3-256: b89eefc201611ae8700d37fa699f2b8f9a7e9e9986a5488d143b0176aa3ef8db +SHA3-512: 4d7920a5471d827f6c6fb9047b6897ae3f4b2464d5663b085820d142e86109f61f59cc1b6b7a0b1f5ea99be0fc5dcc4f7ec6eb9b24e2795b2b724a2a5388295d +SHAKE-128: 079367fd274e01e889d411ada1c1790246a281e4bed95bc4fc09518efec0265788c6bff213d39653412b7d1302afa4ff892a3e1d758dc77c7969502be3f94b90aee1b0838fd67cfe0cb11753d70ff08b989c197cfbf6d695e23bba737a2273447b4702971ea54ce4eff8e1e6cac8e2c8899ddb97a192e469ebf073b1e4fbea18552b2b429d0943b936dd29e82dc9b0d5326e012cc933a7b5575d9d431561272f7c31a1de8a344c9dab43805fff7b39031dc75cc4cdd0a6c4c9f9c22314e5e3ddbd827e952f6f954ea7f4f0b4eeab5440f469c1c4b4ee289d04db002b52bfda59732879c5acf0869710d61e3899119c748e51e618ae72a78257bbe658d1ad866382eacb3a8d98e9f810dd606cfd5642708d9297236ee6c9744445c90f4e8fda6910a374df53f7cfb7e07902008b68cd62c83f2a7a2b7eae7c377b3e3f5ed843e519518e3ae4fca1df1cbae79111eb83439a88df8dcc535cfac89ca2bbe59d9bdab9193ab7c66b0c2edb98045d368b4cc41bb5c8fcec6f92909cdbf13b2e400d74a08e29808ec4fed36b71d0d31fd2fefa0778d284ec87b42961f8d330a31ec01591000ddb5c6dd7b515102db87f1b2d806233b5887fd25fa097e7fb67695d5012a2cfc8a0871bd2c23b9429a64bbbd3515add00cb54ee4d34c32743f835e9657297edb4535f17000092f0f2a45ece17da2d7dde2bde11f5121f7d8e5c4cf59561 +SHAKE-256: 0b1be090a5183fdd96ce9da4ed8c3ec255ddc07841d304cb70dd04b040bfd36083284d992f8670e8933ab00c78c93d53f6cdeee87c9eeaa8de3c8cd8f922be8bfa31c8e12abf75d1f76f1da74c1c443f60f5e5bff9092137ad0a57cfac083dba6e4d4045bb5a778eb94e126bcb00a81959e9d44de4585ece3e190fc2602c47175ab643d2c0c978e887f78ef6fc78d5a51b99d7bd200be56a578df9e8cd4b99be0e1b6629abf957e7ab4586224b6fef45305ad8d87875fac4f127aa141f6d0406e97cf1aac2399f94e48551d11c9d2de4c03dba28584bf58071ea158673801c0f0afcd0264c6fea1d4f388074d587690ef9a74c6fca81fb944d3ec0aab290f742f6d4923c1225ad2acc483eaae7e96dcd047911b203c78275e7111f04c0cf4e6ec152b18ffb3149481999e67090d7d37767e0df6931b85f1684399e3d033ffd5d9746360b8814517c7e74ee9e24dd549505f6e6c25febc09ffe92f1d91fedd244a343c46841ecf855b0056288e863e1bc1a95bc5d756c8c6a6ed9433df51f324d4c0a7b53beecaf0ba4db30d5f4196ed08490211d2b8045abc733689c7a298c4d88a79dbabe5df13dce5dac9240963fcbaa8437413cb7e38ebbf9b394b24f6acca822f3230184d21a1831a887c5656620e9c54f4e6d3dd95eaa8309dc27bae6bbc038dcaf3cc15b8bb2d0a49c09152ed22a17f33582c65b207fd1bdc3a20cbe45 + +Input: d6f0f213a270fbe037dffebbc2edfcd261bb4b64538931b3340253b7538cb2079532f2676257fecea12fd2730fb4d033345493884fbe5c90c642e67972f7210e625341fe5cb210eb91e718c63110ae3c81ce769ada43e7f9a3282d49e7c28f3615bc76ca601e2dc4d3c450cc92ef53c0a2a37c70048ebadaa372b948fdf45652171f16bdb9e9fd45aa70482f86d4cba0aa30f2a0e1b9508a002376e54438ef91eaa4a0005d7558996f8bba0f7111e8ce0f3334d29abe98d1c74d7daa589d17b250a3154d83050b564de1acac041d15584f657bd85f1c1ff73508afbe856ff007e8be0a1ecfa8e42f12 +SHA3-256: 1549bfcc9a635830ed84d6e7e31cef1487f32b0576b21091b4aaec3ea8eac986 +SHA3-512: 62988baf7b9cdf62db7e8f54d256e2faad8528c85441ef849e471bbee965cdd97a0e656b013f01057a1b468d5bd6f7c994819f7147de20d7dd98ad4655742c37 +SHAKE-128: bd08a0add6c1c09788d5e8429999d33384a6c4aa1fa6d6341c7006ef1ddca379ba3107d5e653d2d1d2e86e933cb6f4b0fb6133dcd86edb64df2f6b043daa414fbe6157fca7d06b02ab687c2c3020cd0236e516814aae52d3d86cf209d799497cd8f2eb19ad52c1266f3d1393176d53f2975e8eb330188c1e7266d66ca10df1c683a8f56d3a2f76345d1ccc5cf1059189c11bda6d8ef73f7d60b9f0ecad3ca8d65c1298a61f5de9af8a1553bdfc5f1e92dd00cf5be35e8a2de2bc620937b23e487d0ed815ff0374cfae003f979581d811186c25f84b9209d15ba46d4f77ac2fc5e3690980338a0935261c812864e6801fe600191ed9e2a093edb1dc2ce5632176677b9b780a725b47cb2122e7f4b681b1c99dc6e524ac15d4bf9d11e3685fbdfb32fb04269b9b8002cad4ab80f9d3b2828677fc5f9c850ee31b2fab898f8a9615da85e6b84eeb32b05d72a3c0cff3f319f113a29e837295a006de2f554511451e58c912373372dd81aa62b1d3c23d29e6bb52ed82a740c8fe48afe55f3a2ade8f3d605f47154dd36b4977a7c6e3bca7e729bbaef09ef517434245702e5c351f0df4c3527192e4766b23c3b53675bada568d56dfc4f6d0274886705a2177419965ca8edbb2574ae5c1a326629b0cae7a500d41037053305d507ef336e4d5f0ca4013a71213652c166a0a43ef275a9fb3f381c6b6d15eaf20a709c4ba2bf0ce03ad +SHAKE-256: a484c816ac9a9e54ef2b627c79bfd27b5f3b9e55908059650eceafadb78942ab8e16ed4a462abc8f868ad4b655a7fee7a58b404946de490616b9da8688bab38e66edaafcf068ce08afb6ddbd04805c28a8ed9ce50c2374a6971dee70528a83a22159ee623262b450559c9a46b2b23bf38180fce9d9eae76ac12232da5baca18b521f4e92fbc2b3e79f7d9588d4f2a674285c50a0285719a45c31d922f09783940b6a4aaa96a60e77046980267ec0b57d48bd6ef89b2410d73276e1d498d05f10bac90cd876674cb2b3e9481d1d1f5ad609aa8781b0f29fc36ae699bc02a95c67825ed3f04c1accf2fba00b0758be16e713334dd6298451c24fe8a8a00bee8b0735cea40615dde37d4d354f811cc8c9f615d5ada1be10640d6476f173875b42d4459dc43d6b7af31c7e239192ea1878fa3c03a0bb7147faf2765621e5fd71573dd5759a29377761d01d6ba34e40c599a9c6ae5a44d19e71aae040c2bb488fe3d11e18e43e1262e867635b31a42687990e9a8846020ae5d065a98bf17764ffef8d81ac2ab73d22fda9aabb09f0c18be346be08b23eefaa083f0716ab6eb6c14c8cf1cdda941b1e1b8a54729cb0e3f1c180502bd328676470cf8907a61378e94b64c2c8fc4a7ef866d8f807688f4f57908b16566a24d519969a5e79b5a2ea45c51b319ee8c8aa4dd5e7e56bf9e778a44c3acd6d47419d0478d601f95808a86879a9 + +Input: 9b808f69ef76934d895beebd9f538309920c0a93adadb72158e60ef4ea1a432371005761eb2ed02d324c47d633506428b5e25a5d20184b20ebcea0879e3012ae6d394970608c84cf73bedfe2f238f17632b635f275293dbc2570821fe6eb07088f4cab9673fde0396001bd85e4477ed57da0e6c5123f96ace2b0bb6d3c89c11dafeb65c3d797d40150b2900f7a60924a523c0e8a827c90e7fdd6623a30dd62ecc7eed3de8079e5f019ec87a89670784b34758f2d68979952710fdbbcb498022c73aff78fc5addcc3ff8a3a00e10a62e84e1546d48e6ca2fa5e739ce20f2058bfff57fe9f49cdb6ba081f +SHA3-256: f067fe731683c0e032b4ce8d159d5b9dd12dfe3fac6b84025c4bcf960bfc3187 +SHA3-512: c1a77b916593865b2293acc821b7e5a9ab8b877c378d30f462f4804d84d7736e5d373bac9ad40a7abb3a0fa42ba7d4e4109b9a0b8606a691211e5c38f61e6300 +SHAKE-128: 29ecd8a675d969063a997d70d63e86c7052607d69f6f8c57f9a6025a29f827e6d0f620651be9999b44a9c817148b2223a652e8a1b68a7a43bbf4f843592de2ddf0ed2287cddd44006e53d65790a68550d7eb2189fa0568648546192814899418f80dbe7e08ea4dca298a7416d8d7b6bd7b47fc3cde9fe701c164903b194e8fd72ad1608f25d356d2531fcbc8191979ec92656bf350fe19a0db704c318849a46d68dfc38eab207d81152111ac5b6f8b6698b6795369129001cf883bef8c7f5c34f9bff4d352cdcde64299ef333ddba9627ea6ab2dbc435bc9af33447c25a604e9148d8a4cea1c8479c1abc29413937a168116919163fb4db8f0498e13bfbb3710ed60b3e2874800bd60d1c52460fb5b294705de0062fc5b4d6ec7c4717b96882f8e434c910ad568cac7ad2e35310dbb6dbacb8565222da6c8d74df81cdf87c39000427bf7bc74b419bce98fc4b5b4f919968b9d2f78bca2ab47eff2b26a60d95463398e0b03d7a40696ac7ae7ce653aeac4e33524384594ba8b35d0d9f47493c22621296b8d00616dc738cbee67627d906b9de10ba59e5abb1962d201f9babd2f062aca79117db765e2e10f9922259750818f5fde2f8d97fd6e5b6d82beb4978755bbea7e5bbada8b61732cd50d33aa836c0b6a67349569899335f4f35551e22f561f22b75fa1e793a1140b62b2658c6e9ced86100382fea65a7ab5c563920f8d +SHAKE-256: 8c206096975cb1b79abf539ea773802fc7d4236dad945eabdb9d0ecb392b98753486a8fc6298fc096f9284bb795b2fda9afa6e33b0d86e356e48216cb68d6dd6cba6fdfdf0d093a534360628f61604f2186de471026cdc01f4fbf75fe0a7885d0a1589ff6dc64e5898b1738758fc3c864fd42461c11c5b59a3ffcddbc1d0bfd77d25661794e0692e114d65c4d102ba41b4401b9599304d5514ae68d8342f33d71ea34a4ffd78cec311177920fd1fcd2e95f57cff718deb65c76db03a3455627851df43b1e452546dfb0a99d2d49a3bd8fec9e335c0d869f72c69bbeec8965edbfad5a62ec59027b8d953851ea75d228f41dda11c80707ba7a8bf62505c1824d50faef1bf3423b56e1697cf6b644f263e50d12264b8bbc51ff8291c913a19e8cc4fd41649cb8c0d94b74fce4138874b0c8d49078249bfd74547c2d1d4afdcdd7dd4aa6129f9d20bf24e6cdafebf9fb842a3b89870eaf990b90b3a51bf11e57dfaea6f0b58899826dd433a8709507b65bce671819b42544fcfb6a830b87b74a28f6ae923b2e183e0a0e47fbc9fec1f2c0002766fcb255eb1b03658d69760ad1ffd48bc1bcd4c54fec976ee18bfcd49a513dd04140bb83bf0acbc255537051fa8ebbef24d4fb130a1e2572b151a1c2e17b5a335e4151a7bc07e67f26ef8200bae33c110e1de7fda307b8fa16c4e6dde43aa03f3976f8ac93066757918f983f8826a + +Input: 104397edbe2f576576c028925fcd36fc8266bc5af5467bc3348d3bf652bbf7b8460c437f16909faa311e78e90fb853855f734b99be6e18b0b85c834a79180b4f69528c1db786166ad76e724b982072c55cad2833c0544739a95242ebf62f1dbc45c47b86a4c113037e517c9da405b47ec43334758390c2b78594269a783813d409f75b9d7d0a51b36e9163a3b7c3a09fc57ea9a632be44abab445f5aec387032e97641d372353348c600fd57c54405ba8e5f3614ff7618ace965d2fe17de87fa66a19707b9139b3a22847deecc4f6c2171aabbc3263d24b4d78a8c4d66049d47126e2555d693cabd0939db +SHA3-256: 6df06abb6e7676e3b6931457938dd74ad4e776b3a7c70a33a926e2c6c81e3547 +SHA3-512: 179a089371fb87869bb015ee07e39fab9bc9dad3ecb393cd17c0d0ced4eb08ae17b5aa01446e0567501bbc0aa22c8cebaf0c73020408fbdd216537596888eab3 +SHAKE-128: e2b17619f731ed8d52c09cbba6f0ef14cebe0c25ee74ac28a4efc08fe7052b5e7e0e6a95f84dcaa247763215cf155060d57f84cec434213f08e0937661defb4f74876b4ce2345a0474173b9edd878ca3842508623a8d3049b8bde19fc3ca1b099a790039f1a718e93596cdd96293bdaeb7e2ac7d03d228e778e88d1ae8d774a14a0b4db44773531c2e4b65fb99697f833dc033e0698acbc3cd5859c3237e7f87c734fd3c5a93b438debff9a858aacc22e10525f12a9b25ed8b0d435016ac33a3bd6b83c556fb689796026db662093402e46a75427441afdec588bcbf01bb0ca4511b7a152c43fb35958a3f118cf77e04b4d58ede58461fc76559dd2c1acfd3cea1eb58af1eda1cc4802e88ed5c66c344aacb4c0b61d851c2d17fb3fdf59983b2b8a84c6f40a95ce7315d038874bed6e86d1f96736fc7ddb2ee8f5024a0516370bd10dd3bb8ba9f0ad77f84070f869376976ada1c1717551ffde4b8bef925403fea1826712a7e041ef611956a0face1f8ee6a6f1f6a0aaad7e302ee6046cfa53258de33f04d4d1f2afa7e57b3840df9b20c9b69c8abf1fd0328094a2f5866a36902177a876351b249347978c65e6bc9fd0e52145bdd4413809a5e06f37c2ed8ff29dab976fd16ec911bd07346d10bf5de623511ad67e989498e85ac7811289fd70e50e761c575199c3857776c2c7a9aa3267f7439bcf558cb54fc97c7e84ec3b9 +SHAKE-256: f19fb2fd71e08497fdf497a33d077564f357b7e630c2a6452514fb194abf0caae43e2e86da3fb080c218a4a5d12ffc1d727100a86f5cd8e582b1d548679af7aecad42310abd22e62aefa2671ee7ac70bc6d5a3c5c5ec038c1e5e0c8800d8447365f3ecd538a13dcc8477fe6a1e5ddd0a5455d09186945dc123b8b498f2eb97a2736921f708319fabc51fa53b3413222667ce583a9a44804f5b450dd60588df3978b127a38569e887fb1bd190d672f3e608966626f30733047d90f9e334c71edd5cfda174fa27d9c2ffb91947714fc31d976be9557369d7c369b5d1f9c65758dfc6c9d21b36d094cd668c906384b72c181458089e9aefa91932d54c7da2f5c91ddcc6e3d85c6161e9a3f322db5efa9f4388908b083fb20e5329a2376f07d3b7e78072d7d53d6b022ab335d315565189ec47de473f882bbc0eb602ea9bb712c604c23df84cbe82872dd1f5512ebaedb01bc3656162d7756b656f022c51dd1c839e3e38b394d0b1f63faf389cc31776f9b0d83a1d9447a35657b592a8be30220d4ed9bbf4212dfcfaffd6eee1f441951c09f2e05dab7ea39172e1f3e0d27c852d762ae384ce5a0d413f5530b1d03a3fc3eb382cafa4f0edd07714c1d559720903294f7ab2ab95269dc36831f365af8efced43bf0a0464bdcf8d058c0e5a935aa1fe94af6d069aaeed99bd46912d86f9201d19d1941106f2530a59aa4d5756bc11b6 + +Input: 4387f289c912c2f3ccba165cd5c8e0cfbe12b19e1b422ea74d6df97a374c04b58f030a40afa3264c673b5ecdc3f2aed201d5721b91d8e4739db26697caabb9b30ae04cb67be82492e34a663375962bb663f3aa8a6f1551e42b59b8763599da4cd4af0d398973d0f4cc9063fc3aff12a1edd69714bc5e8e0ffd7e0e963567bdce817a9ed833593a47d79f6ae59c3ef7d23abf0af3ac6963223a08d1badd23fd4e3ef629123c61e0850e548ff74ce6cb732f9f19837ae5ed239aed78307fb58d9a4861773fa0d28612dff5ec6ff72530e22cd3899358ccbd5349fa37bba12acb84c257e757568ad99635a0eed9 +SHA3-256: 3d72262de24abb59cf024bdeade1e8fa5d46022e7662b3ad6da69fba023fda6d +SHA3-512: b766933cfd728793a01c71d3faa9ecd8ac9b8428e7f297f4e44ea5c15e9649e85b8b30a856c97945ad690c50b29eeffa6c5449ea59d54b092698238aa559c5f6 +SHAKE-128: 6e58f6120d3d352fd4b2b464ce1e2bd1c5daadc1ce069ed947e5f47d25262b34a1ebeb2688283693dd40536c545bbf18468b509675d8fa79a50aa927be67c14dd8c20f16b119580fda29758abca5b3b8db715776f80f6edd722ae16755fd4df51ebab193dbb7289f7546a0e08b735d4f9a46a0c20256531680fbd5bc1467949b698b314b2cd9d8fe246939ab8b4464e37cde9aa9bab0d3628bc224c7783d3916dd84d99e8443156640f906d57b82df31537fb3eefc4046b1cb7da3643ad8654ce12e7dcddb26a61d017e218b12e45944bd589e1671ede96b5a4a215ace8af0bb9ff3664cdcadac965128c0ffc706e7fad3f7798b20eb49ef20d0c3f57df04c26525e1ecbfedea0ff3811440a15ecd610943149f7bc896be6360505e3b3733299b14114f2b574e13880e60c02799206278d6bfb30c1194d4de187652cc6bb5936b2861590de33704178e9de3ce56c8b77ab991fe5888fdaf5720f6bb9c7e6ded2589ec057445541f71e39649cb82fa8b419ebc57225c2f415a468102e5c4a221a40289f066e27701a62be8da8c5b6609ab20dca4d75d536a965fb243d2a90211614ed92834ebd94eb877432acd0e1fccbdc2337f8fe4b4208831be25f4e320c6514d3ea1c5fefe4e1a06f634eb6af0d99e25c8388e17dc6c645ec4d9b34a432f3aad922c0850ece5986f5bf1e81c8c4733f9805cd7e2e804da1af52a5c8c97fc0 +SHAKE-256: 7ba865766bb4eae18222e21845ef08d74763500e946c6ea1999ce04ece7be33489fc1e6b88784fe06c0b1c4fcecfda9e06544e0fc45f38a65262264d8118f6113d0956b0ae68859465c61c63d74e725077bed988eeeafabaf40d92d725934a8dca2942e427ecc34ec1df6756cd3045e5e99a2b232f0cdfa3e92be8b2784e5db3fd93fd6c72c581c67de7032ab30bcc23a02b8c1ea1fe6293ff596f604fcad9c0f602a1faf170e178a2cf6cf983d02090cf363c25ad5cd00357d5d259cc7aecf3e94e87a8af915bf9ed5fca7201266db5ef4f007e301b920f8ecf563378b626944c4e7052cd95d348b86b8a2e2a11ef765ad008d18e3bb0ffb68c32def3ba773868b0bb9cb3eaf6ea2bc69e86b38b3e7667c1da2694fb15887738ebf5c68fb002be3a0ec74adc87b2ce30b628fb0c31e5735a0cc24e8ca63d9532256bca9b29798ef33a97878f646ea9acf39d430b6e2ee7a58d1c707ba1ebb940ce7340f03af9271c8244101ec0bbe500fb86d6ef3f2953f7f1515b9034ffa9f041f31c45be281257ca59d3ccacba947c1d403eb70676bf2c6bb9c4e6afc3905e959e72c4b129be147d99ed227253143ebb88ff004bb1f97f0f0ff3ed7bd575ce675dcd1c2bf7e723c81157fcae1455e0881724f3ea3f0ea711661e3fee85d1b7b90ad192213183bed450d9db5ece4cad2d303a5342c4738f5da0dba171f41453f93f86053150 + +Input: db23781ee6638dfa2726105dc8b855e5a1007e882bd4f19f996e3121b03414968028d2df5eaebe660c39831184111b960d6b94b2f73a4ad53e489a60201c365e2d7c86f29dd4f76f6c8738b0e275cbefc77463182b541e436f8f33b61cd28eaf69dbf80ea6c133ca28e140ef31946fb2258360ccf700e455e3b1f0d9ed905cababddb3c460d5111367d925cd21eed9df4f1ad7b2ebf1a4985c8e5ae25561d4f1c419de6d0671e385b2e356009703a97cb2aecb989ad677933cab43d4e2bb1232738f1d8de109f418fdcf1878b0754929cb78d283d8ec4d54251dd1af46a639f98e9ac89b61ca40cae11b8d0c3d +SHA3-256: 5847c5f55d5a69ef026351c95fa4922b254fd21de714b371df2e570983a5ec2b +SHA3-512: 4016fba6114b05b831b9e3c578473f6e33196d7800f80abe992af21ff36ef4e9803674b26fd6ac1eb33d9c275a622ff64d7077bcbb9f4bd28caf3be8a4caff4c +SHAKE-128: a249c1fd840e47fa937351342f21b6bb7e7bd3855bf13d86843538a2c822503e0fa3fd3d71e1cb895b8dcac6b5145c9c02e3b0b9ac25fd94ca5b6492dd8c895164da68c62c56887aaf6a88e80272f43574df46946a79626ad566b5d1c95c46178ab042aeb8648844cf5209b361bc93053beb61489471018c95edd5163125f62e28aeea4af296fa3645efcd10d29e4209034ecc98af0ee038d209b483e3a9a791062bb26633448b94545bc3283ee607178b595c3e9057ced171dc1f0c7959d782bfc9d78807c2403bbd70fe26315260904fd2fc194d45557ff12bce96da005fd1464cadc9c9eb8e3c69928cc7787beb98de3e73f61dccb6784583fff61e34ca364cc55df3a1af610b5a0961458ad555356b064ea1fa69ca5848937bedcf5149cc292237cc8f7e038dc774c4264fefd410f315b3ae852db82729de69cffa9bef31da86631297cbd934f232fd7b0a75bf1da03acba0ebd39831815b294319ecea8d736a081f2939fd495dfca181586442c7ffc0d9eb20c900c8cb6b3db89036917ee7af09229be2c201c02c57f6eaaa63e45aeae95c42048ed455b9e1f905ff671423ddc2cc03ea21707850d9a046a0f0a89f75e8236d3f5959133fcb7b374b6596be4a6ec0d8f60bafa3e14997729a72747996e7f8221def9933e6793d53dd34ce52a764d28214ea25827027dce609743eaac578683ecb94483b40a25fc0155a2f +SHAKE-256: f92dc1fd8947a773fd36ad1bd62a90f490e9d9a777b1ff1f60a673ccacca16fa6e096a7ad6dd979099b8b8c6416d16f997a003470224d42b75190c38f8f4b5880633999b7cc0b6278bb954aa6e70e66955204723bb4d7b69fcba898c05b704a3b0606ad1be18cbced6d84f2e1167a37b60ea01688f81720668a45dc46871f54e5c1f9f45be6b1e34e2515def14137a349e4c50f21d6e21018a1a9825a31e450b3e319fa1b9b05964cd3e7ef7202dcd64687c7e9fd95b767cb39991eb17ec7c56b26f0afa8b4df22c6398b2230ecd34393c1507fd50bde15086e118f10f9e5cc81eaa3c63afda27bb998f960c8d3bb85ee7de1a1c9e8c0aeff5eba4a3b20ba620be939616097b42362bb2cf81f0c436580078e2ff975602d793e7b15d3a6409ce5aee341993100d34a5c77f1d68dc84333cbf2428b9ab509e853225100441017b171fccacc321778a1bae6f0ad08ed223815b5ab2aeee5f117eebbfca21ba26c3b420fcf97c4de9132e193ac16391b52fecd9651629ece5f20465e95b93ce264b0134f5ec4724da024876ba1f2f4402c45e6a9ba8da82db370a4677ea57c9e0f24fc22985f7a466b059ee8898a4c059442b298cb2d3e382363735db9b51ee34bc06b202b596b2e2bd53adaa9b096fb555f579835ed23af4acebcc6274b05cbed172f7774c584323d50e8f093fc7497ebcbdc433394f084a005718d4c585f6782c + +Input: 3a9c58c10c1131bafd9ee70b9a3b440ebd90ac1b24e319f6c046b6572ec30df62f88c24d1583fd3df4ea9b4eece02cfb681e24add0526f66d5c1cac417956115a4b90fbddf88fa8ccffb12ad393cb2bd64ee633ade7525ebdd2b48be5b6502492eeb451cf021f3b9e109ed8004a2a789c999c8c000997301da8010358ede8fa0b6a6d4675e371ffd409ff42c25e5e9c163c440f6870cb9d422b37799f66f14ca136dfaf24049b1cefe0f65db9326146cb1c51137c37b0cd0b71f29946ab17b863c04f7fd92e8fa6f5596910838b6376cde2763af573206e8b563d621a0218dae3558d777ea465d14ea3774c01328 +SHA3-256: 279ac0a223dd22b939866cb544e5f3f96f7cd101093c8ad2b6c3528ad91028ba +SHA3-512: 909fb3f4b8f99768622d26670d4a66787f5f2b67ee7b92efda1ed906a34b476a99638e5a2951e619d74367695f7cace34d36c1c47989d50719aa2e52a60e06cf +SHAKE-128: 4fce6fc03da3b5cf1569b9f073297cd9f1983096e376d78dc3cd042aeee1293f0aaf8667bed005be25264e524eba485fc2c692685d5ca4e4290ffec33d90e11dc134a070796e247722625dac694949f525948c61325d2e8148cd16683c01b683fc639557ab77791c07d284f9f16835f13009eeaf07f4557978a6730f03caad982ce89affdf1bb37af56d274b7071e369db3bda3435ee0942d24655b71671bbd6a656cf76ce2c668ebb377b7f9f355bc4f8ca6cc4cfe4ad06539d02b73b7d05db91069ba7e98a18522921c213dc16a6a13a1b611d1ec505e8a461ce99d1786a1394d2bf0a614cf5d61cd0db03bb023f21008fcc71480d3f886bd58a63352c2afad5dcf9b8791bbea40d2f76ba3daae4c103f45c61d6469339ac1757362509906236cbb10b302eeb25b560a86a617af89a0837758dfa88002df2061c1165962bb5afd8c3d1e566be384add9a048e0274383318e62c5fa17c7b85d0f7093111613de15f596fe69fd37dd836c6f435aaa5b91f736a9f3f5efcd48369eae8f25e13d146093e04e9a9bae58a56499a4717de51c667482073b8e1d95bc45e294d7b444f2b8fe141b8eb36cd1e61ac86ae49b2d0e1b7ee2b3cec061ca519303344e3a3d656136bc8ac6d2e097f9862540023f05d5e59f5b49c4d153810c581f3c3fe6cca3cd547d1ef5838db1f1b55c7688232222e5043d3c95c6a211778b51e39840dda +SHAKE-256: af298797ca68f772dabeca721d602df61d312bcd9d472db83aba1ea84980d6e7315a195255d7edab15e542dbe8ae5b330bd61a5c855d4a9bf45f0351323477b4be3c24fe29ba7e897cfe4872f16e9fe641860499716b954beee0687d0b26340c3aa31039aa71f1f250b4b81e9f1cb3b45b100bf0301d755d8614f28bd9ab5373fb86fa51ca4a51fb91371d4d4284122e6d6a25ecdd28e88b579b5f6cebd76f5acb6e022bb65d40ce9f7d32e02cc66e488caa6ae6b34c4bf222023653ddb71aef339f78b1e33697343b998ee9d75ccbbdcbe9862f258f7b18df2e7be379401fa574218cf8c5d58ca52d01985cbd2daa761cde4b6b9db6f635c6aa1f8ccada6d000019bc2130266a7c500ae42652eb96e778fc41d73e30e25770849266827a04634e959f838df3a9dd7c75515e47424cc70f5f37c7f1cd5f486fdcaac4de1b0e5c285696da79529a112f034f43273ae201053ead1b45c26c2afa3e06bb2baefe0dbadcf826aafc6c01e3fa32e5b0d145fd01d914bbcbc9b7af506ca567af21df730ae5b2f9cbab8b939d961e4703128f4c9979cf810fb0b0d465173f924740a764d6230c5c72704ba9b1ed8b6b73cb8b12c4da960bd7904cdc39ce7bd35d24b55a6942f234eb53fe58775d7b29c8c73dcc6ee11c8e680da1c43710fa466cb3d151b90e991ff10a46977b48c12629c29d750f8fdf3d5bc851357492dc610d0a5f43 + +Input: 49066d0a4ef8dd84451ec290349774ca7b9dddcfeb12badb2119a05e2006ec80794cb680022cd6e31e41b418cc69c6a4a427b0dc1fc6e084f006349ccca756752ed8b7a8ed511f77d3b96ce33e3293355ac1c2f6e18e95a13beef946dd7727a1a5159a50ba054049adbb4b767a651bc1544b7f812fe3efb63f48359f2ecd58a4dfdf45bec9c035cc50ebb3676dcbd06222db837e2b837605c022c03e2ba318eb03451f6e94540964523f04c17d41710c30b51677c71e05124621b196f0c325edd3c601f2913022a83ec272d210af2be1e139b581b6032b48473b0521c1be691486437817c723a3a3b4a65fea0afb3d +SHA3-256: 5944144da3149c34e15ee77ae83446d36e3c1c89cce66fbdea798751f3f7b42d +SHA3-512: 6a31150580d30dabed6661249e779b03f22bfd5df06774737b1787c5af3ff2d18ee1acc9c3fe84251c7e86020daa083557583956df3a53ddc71ec9759eeedfc8 +SHAKE-128: 9ecd5341bd1092c94a0e95630218829b014028d83628e093bf3ff5bc970b2913bb44bc90c54b6d3930372b53a804c946b56b5a468ec7cd152a2fa01eeb52b4a3ffc8ca76f715ec5ed2f036924b1e9c24b3044a7d2740146eff4a6533ea32464373d8b5960d8cc359d99c086576c42f68edae77ab3406f861009346bd387b3e89514210193c7fc0f516e2850b78ef5307ec2cf97a0a4c0b984e0f4f6a8626d10d0d24647d22b7f73ea45a7aa356a6503af4aace66fca136cdc94fe02460c03d8d8712c4e14e5287a9af9b549310d4543791e21468f25d044c401c9112bcc63c659c2823b826cebfbb730b14bf6c98876e54907bf2859266679de48b81374ed590c3f6ee5ce84e7bf901ab547e89e8c9e4417b69f2c72e41a255a0c46474bf994e7d4e2b327eed8e3bae63586a6d985a82c0b02da2856cb78494f647fc6a96672261fbaa5c8ed7ce8c185241a2d716b5826b8ffcaf91d7d3149c18c453524b3087236e8ca7140a558de8237b6ce7bff0ecfc8bcb54bb618f11d730bf5e4d46c028b9ac28beb09c17ea0f0122064bd66f6ac29c74ffb68c41c7b2b5820bdb56e43922e4527aba17d71d44aabdb1ce5a0824f775727c8647d6227fd735a8a57df0c32ef655a8dd8adebbc0b9a2aa2f4ecb7cfd16224b9983d3712c6dedcf0fe9d5ce470d5ec32d626172d83f70097b95f397082aa47b7e21887ed137ff8db2b63882 +SHAKE-256: f23ba659df103e91dbd958e3de3654ce680b666c5d9654cf8ce6391357e4559a2355151c1f5b7a1b586646e59052b2aae37a51180500af9ac72a2ffa93778cbb991fc1c4b0789dc4d373dc1c0fe59fb36ce4ce2a1bd1230abeb8be5ec0653905dce67bd5e198c080c0459cd060c566d41f736b54f6fc33ef6fb6f169264634c3420f2b34fa778a85809a47bb6bd620b881f977eeb634e4586a3b965b03c57b9606de8bef492c8312e4f1ac6bf22fed5296968528b0c632e07a90dd1e63cee356bb86a00b3bc492dab48829cf7726787be741a6014779205540f286e1bb45afbd0cd0ad7147341cf6fa5a16014b376b2d00a3d040c8d8264781f00a145b31e371f12d6631804dd6fea14321cf7ba5e4a8295ece64831a120b775ef3f01eaba8493a5189768912ec487a2834f421dbb5e988c8a11a8bf9762a851ac2d2c4728ac6caf3b23014a951d65d0c4e1118f859ad0a4dd091761cb44cfed6f857a945086829f2f0a01ce54eb9a6bfc2cafa5a2427db50bcae7c03873dd9a3936b9686fa44e8bf14031d5cfbbbbe6b83c5e3300414f7ebba9d1283e4e2811dc1908e7b6ae4d52513c22d6503efaf165247f5949506afe9eec55a266b8b4537b21981aa4533e532673e822453f3dfa195634f65b8794a85d421b701236e50fa59567d2b6899534fb5d1a42b712ed3e18b742a61deb5eeb4d129b452b104a6ff0de09ccc0797 + +Input: d0d3a2f121c9f6c2f52266f520dc693228c47a5ce36a2b136024c6cd38da94f9c1b69d50381d56ddab1a71f64a0c526ca70000a8dbc34e1022bb5e83e8eec8955ebb66542ba2d6d471d8897d55825ae3d2cbe6612baa6c3f7ed0483a7e7048970797a70e76622cf7f38399f39e533a30bf7b5d1e65012c63c99d413b2b1a52c7e8ddcbf417df9b5bd6ee9ea07d2a66bd81905df3615098e8bd252ced871ee2a619822f1efe412fb2b6c511b62b06953630c089f33d26af1a3bfa8289a3638f5ddfd3d7d9e94ab83eeb85b6d08bff61a04f0dbecd7ca0f629459a2405c9bcef33fa980953585f68ec14ddb89ccd7c0793 +SHA3-256: d43b6e294a5eecd1f48b65e321e232c2368b5f43ec79469eb134498d9fd6c6a1 +SHA3-512: 2b71298b796db056378bcfdb178cc21c15be4fb689e8af1f29296b11f377f361dc292fc8f87efa10bbc7f4b513591f468a33688c82ed458d0d5079a15045eb0a +SHAKE-128: 2cbd12780dd57efd0dfdfe40300913c5d060035c1cd3a05fcf8a078cdba32fdf5b45aa757d340d068cd1ea22596a9ad764b65d95836b0cd93fac228a28b6dd51d15b9c7ae3d308cb63d6c060832506ddb11c28cc4456850d78520a444a9df772206e79a92220251240421b323fd7eabddad1331ee02aa64c191a9560ccf70bc885481a8d3d6128090930ff3c35c6e8accef653d987428cc6016fb1540573f12a14f62228b3fb10a7f32260c4453d34e7fa2f1bf038614b22561d19abdec8637094a65cedc9fae494a6e30d812c5465b557f20197448d56aefcae31cab49ef76f4e36c13a1c550729189a138489def8e8644296224b2a3fbe9c79ea6e76c68807f1e9537f81b3691f73bf608de157ed264679781ba21bf8d00709e1e8c9810f7390cdb09eeb115e12312c9d7aa1f1a29d85476de6402279249bf8c44dc16b7b4f408b70a2e14411b95848d5f6b6fbfd7fcf3394f4d7b95c8cd8e26e6c7487eef6d18b39345b3862d58d8dc6f837ef8b2a9fc76dca76fd3d74d217f7d7025bfb5116c9918075b1418d15511a81bb996052c43ece5edbf2898f95e5adeed0c97cc0b6879a86ad5aee463d3f234a6547534a5d4491b6475a8507775c8aa8a59c5e9dc2f70db11d47da6553701a4244c387e9afa83a77085d51cbd102f4a299167dbb071e917ae38e494fbbb1cd2acac6e9ed6a1f1b9364e859dd7ba4e59a6eefbf99 +SHAKE-256: 1c2d70ffa422b262552d32390d01d0c4ed5d1e1060bae165d4904e8f4782ed84830cd63771255ac2314d4d791d686ac952b41cb7d246dcbbcb834bc8105512b1840e32ad4f34b5ea0e6a8bfb63a7f2b28a1fe35d3f5fd975dd3cb3e2e61fdbad2fd7d42ef393c249d87b708329189b2ebb056a3679dfebe4502152cfeb53433ee769a0909ff947c45f839439cfedcd2e193a24bd07d249c30f2247ac0d27ca558a2e9e5426395a393287c7e6e5749796cc74d779ee004d1ce1dd8b25a156b3be5859a6754c23e41a9e785bd597c90860a5828db0ab225f7403077481da3b196ca4610989cb0becda4551e0d2747a7eaf26c3b3c82fc0a980f6a93d3a807c65a4b1e098019e55b528dd74a4985dd09e3dc74bade7a5ec35333963f7a159b5aa4b5b4c230d80b534b53f2f62744dec9062bf94ae0474d0a9666305a17698d467aacb8c2b7967b60355615614b90a54512d564619c533cc3fcdc4eb9afcd012b591019c699807b465ff68b413fcbdd60792996685f3ffea5bda8cedf86e3620a74af659d90235f919c924ce126f16667d8067c3e8c377c2b1689258da35544ff3645d360b12a8273bf25c39b2258ff0e1491a18c03c846815f0d5dc880843c10045b03c73400efecdef0c5324b7288668911ef812fd51d74bd23a40f7b52be19c35ca036d53ad5843ac50d126e5f4ee7492bb9f7670a7d0a5439802561aafa29b78 + +Input: b5ab7ddc91c7088f13afa6c026aa6aed5bd44ba3a1cf5e2393bba0827925b3f4dbb724208d6fd5c1d9137611551644b813daade29bd252e1d2a6a01aaf9c7040eb26ddaea710869a86e2a7e996ed56205cac0bfd6bd27b9831a390cb07d016f61ef8af0f58d90df565f2dbee82e8b7822e9962c1acf8c33cf291094cd25b276d7f8c0b442ff64028772daed26f3564eb0a4b5815323622cd6d5625a4702b324cd7f377a407350ded517a12fe827c036c9d023d36ade34a5c00db7b9aa711f5a202fd224c1b42a31bd9a922d7f106434f49445e1c1b98205e79ccf36d6342d3ce8a6257e9338f2bdee61b9c748d08312f28 +SHA3-256: a287e2a273a2259e003671e81ff0c9b8f9de868e61ea69ac5fa3526adb61d2b4 +SHA3-512: 11bb74976190429701f29d5ea1cbc7a0fb4c5292bb49c2e3b730a1a2691e4f4536ec2689508bcbe83f4a4439dec497d33b4f164f720f822f74656fb024486aff +SHAKE-128: 5cc7d226995a96da1d8fcb5954b191da6c0abeaf09fc61386c7e43a92b7ae846d9a1c2d5b41874c052df9dd51920d0ed93ba758e27caac91f6614693fe376adb9e8a42dc49350fa8da57ce6e7f715fdd9927849a137e70754376197ce14a5747a85ff2282b5ddf897b444026fd5a4d661a82df4759a253a45223b281d1cb0b052a78303bd42ed042f502f409a3af66b08676ffd479189e494583853326a1ac810d0dfeaeb6bfd8dcfc4f2ffb6e4bd925e9bb61fa20ee8a35becc0687a1142e179527ae8535537c9e1b0b20321378957f8e3f84d3fe889bb37fccc49807f65b3a0785e103efdbf4a4da7de4fed08177b0ec1dab6d5b387b592d4bdadc196f1d4276aa92c842ad02be03f06e0630f7082ba9e3be7b5e56fec7b9d9ab31c7842c82b933c7ce3ee4cabb5d751fb5d8e4180fbc50ae07ed5382005dbbece1246ea6e30fbb7d7089f8c885435633e0fb0c8b56a4e79d3fd7d8a7d0a59a82e646bdd9c02f8d53588a265a1e895a6b3d62574f72b48ec7474347168a393df46042ed40cd4094115755ddf4d460911d4f32b917d5b21552071bd22592375658ce9a4aa44db70cf8f8d7cc3f1a3fb7f8c138be8d857b30e0f2011b43e6730bde5af5ced016e69bf94dc74a10f2b55b9d944f2b3601888ab6900d87a77f638cb3e1cf2b443941f0c29932c5685a61911bb6dd66fce8368ba6ad7b7271867d763e6974fc4e62 +SHAKE-256: 9959147bcaf01d7706ba5413f2a4b61f11b7bc3b1bbeebfedd473d6d4ce8fc63fff53819eaca4ab276689ded2a95b4b086d7c02de5c6a83303fdf3e318117d98460b679b864a661b394c1915f4c4b98fd5ffa458a37340f948481c01310c680d5d46793b74dec11e738f0e3f84b0fbc79c9b925461b7a0938571abe0fbdf4fbcdcb6e97cfae07c20732345b21d3a24bd373d14f636a0421a62e12b1df1e04968bb8573023fe34f310f487deecd6b149752aa5e9f42513f9f0df59622823f5c957ffda8f0e9a521c1ede963e4cd63acad8a21bd49da05db44d806a8644b0cd330fb4401d9d5d5a98b27a988495ba2b75a45e178610903b373982df532eb39370f640d35e8a8476d036c53195ac247e30c3d4b3a0eebc12a658031ac1c3eb969bc47c0324fdb71cec67780eb460d1476bccd476cc07a3dc5fadb6133059019d7873b4906ce5a9117cc12dceb16fa164af024afd301beede87309f82f6d7c361534074cdff3c73250ba565a170455937b41949ac446ace264430cdb554686ced220b47a5ee953cedf051a910d2bf7e6105cffd6bc0cf1cd79f1bc647cead649bf672a89c2b74dc2a58b8473943669f3e40abc864d4494d7c34ac40f7b7035741b70cb704c30aeacd8846c07b8d2de527d9853fd8d206551927245ec1b9652765696bb282df1329522550fbcbb46226ca307348075a249757671c1a697213b73069f + +Input: 45346d9d8260afaf991963dd54ca4e6c26490f339cb82fefcf97f12abc520e1f41e1273490fa737ae407c4763667cf0d9085bf14ae0b8c0f1e1e6693e7004deb9eac4435c8a5b9bae44d3c30d45f1287228f7fc5bb8f66031b01c17be0a05b759a4eef5633c6407f691796de08d5598519b3501c64f70f0cc27227045e72560ec2c64f65a1ce3ebb55892c273a14aff82aef8579cc96553d27d27b56978fed66679893cf94421d5965c90ceb38c3e21da3eb0bf610fd0e736d8fb17d71bda2fbbfb9e124f4e98169a70a74acaba91d96a0b38bcbab4e4bf456dd04cc9062760b32d05183aa60911ef61844b44989acc465e8 +SHA3-256: 0dc42a6c64871139c14db5f429b5828164a678afa84108da99c5ef294712aacf +SHA3-512: c6d0dde725c42081097f77960625b79bbf96a5972bb045847ba1c64553265e8e9a9a6231993370cb54084cd35f6e036e377c1eb7cc340800764a0798b013d7cc +SHAKE-128: c8f243bf07357e67eee9167cae9b936995ab62ff28db3595119b190d9d400c178de5e26ba5aa67f3556c434e9f3649e8b96030d8f5949fd5a7ee9a9c726e39e96f789ed537801d1983ffb132d9b73bf384b3e706877d112c3186d78da182cf94400e28c7cd2c42191c6b510f833173d63a862e1faadf1db38478beb57528f6d3ea06de37bdb08615e2d8719b49014441ce26b53d502aa727a75daba39afcfb677ee1939760179c198ade6df425c07726dc386346d589c7d2d8160429f0740f4fba4ca9b127b0284287c4b76fb26710da87ee73f9aaf23fd58a1887f37312e2d18d4e92c967e8d4cd4a40fb18028b4f531fb837999c7a2d46ab4b8244ce807dcccd6673afe00184e4b5be27681719abfb5e5dba814e31c81e1289ddd0decfa208fd801442ae9fc39725d26d9c224ad83e28f6cca2155a3df57ad6e770c6ccaec2c51a4ad45c7c97b62bf52066a0034a56f6da8adba228a35b381a143d012363a3eb1b11480791715c83190e74dc5d0113582ea265f3a5d21f87870c825d4cb7064091eb1a6c23427c80aeefd00204a939f0814bcead0d4c1748f92c952b67d727d3a63c16f840e1e7133c8237df0db215b58d68c20b38a162967c67d646ef2ae3f7cb2379d6747d9769c6b7fb1b4794449998afce373d8c5cac060f4a347cb58978a365486ee2242ffb61eca5916ace2ac44eb72d4c48f30142814b4644847917 +SHAKE-256: b8c44d49842a93238c6491a9f3921e523a6dbcb7482f02f912b2a59a8d1892013aae90c27e723507729d397c593177bb10a453b35c4b5a66977f57ecc75f4783a863917896a7da96e81910b44d5586d504b4b8c1c292354b93046e7f4da928450a3978e530184d3113d3736106e2611504dbf1c3b0013ade7d804c0a0cf07a94af710887f31d822e007a297122ad6bc119f4396f6b94a8de8967d5308890afe25aa9d35dc47bfc36731df789ad0ec22229087f37e4d16aa801a0f2cee8a574da627a0c7c0fef65077aa39010218bf85e3f5ad58588b0bc15ca7c13394c2ed7530d7b4f7815150b243e3bdcff9523411590a5a44ab87ec18081ae003b439e5d95f5ff19c2608e4d4f79b61884dab52159b20ea29de4a2c7c76c34e993e8b93807583c7981af71a5c94d488b914c02b19ab4eb73842ca2319fa6cd846ca5e079c85e23226a84427ca6994c36ab5f5f2ba159b37e1e6a563db5a950abc6e0aa1351ed3b948f848acdce2ecb99e3e23d17cf38c06ee8e85e57bcb524c9cefaa6e823660ffebd25b0448165d33b5a16533900949ff2fde756db95f8be4d787fff7395dec325983a3cac486a4cba452a29738364f8c635ec72254e52c8451153fa63a5c7247e5753071848046e5bab1f02af381f9e43736e4fe6e3271b1706c969a73965ad3ac779926fca1e9f82a49066d95c35ffe4f620eda766d40bb4c6f7dea11c + +Input: 5ca2d0318a1decf3514e71290636ee4bcf7be5cc6053a1a3aec37665ff3e1ddaed8e0e8640f328d9e9b09bc50367b09871b578728e43e0107ca4928854535680b4906c16c93536411234d2f8fd18a93da84fb41da5428fd94171e3e0c0b5aa8b079d7559cfdcacd3e60253b794aecdb796c6b83815f1597e7f38259eea795ea360fc44ccefa47cc1adf030a1ab5af42b2372030b96e579f7eac976425085060e347a6881c75316a6cacc20538203353149188138673b2539d91ae2f13005b5b1e0fc9a3be94777d4763be0fdc871beeb1fad082dbb2074da4cf56e0af1135b93ed3c8f7d9cb13f76d41fb3d4674ff4595f03cb +SHA3-256: 93e74cc55d3f3141db30ce96b011b25c2779951930ea7482078cb65a68679fd3 +SHA3-512: 2dd6935955c05eae9336bf57342a3c339e9fd4fee60ec886c0752f46631284cf4ccff919917926802bfd7318de1f7f064aa08b1f264238ead74b9af5c7dcde61 +SHAKE-128: cd9915836c0122da2bdb4b98496665e1c01627f96c558583decbfb41982a6ca0d756cd41be3276db4cf10b0bec1e0ed2e665ba926125748016e90a008b2da8415196e1b53fbe794c67d0bd555d09e16c73d222723e8eea594c6af31d1691869b68bd69e3d27724851cc474aa818616e44205c1499790eb944b8e3493174e0c7cc9d9573ea8aae6123f86bc0abf8a8ac1cf202c4d244b839263eb3ab18a0ff679cff4d4e1a92947d853e05d8990ec00e3972e01c0f6fdcb630004fc85d51300fc2bc74206c617088803eeb302d1ab437338b9b98859da91e9999562489c333188d4ef123b1bfbab33d9b99631ceafd95b447159df4a6850f9d16ed95af249895343cf67cb6affa321bed8a4c12a907213f042be11b8d9415add079dd83a764bb6786764ea813559cac299aab158b087c413c199b037b9b7681864f102d55dc762841a7a93269dde3a23b1ab2d971a145e8acba071a70b4aa5817561d54def6402b1c7c995307ec4f7870d15cb18b3d4979e28431a511a6c2b1d08e38e0bdd5d063f1af09f73e24d80d22f2f1c2e8bea5025e9a3367d4d3244d678ce100b2a56a653e8110daf44118d2495a336cb24afcb2aa4f507f8722f2f8f3f0a3dfe8c006a03efa193323d5dbc1c6950335ffbdb0f1de27e8a4620b243dc5c1109fc5091abee42750f0cfd3a767bc7996f651121e5183c0d605fed9da74f4c7a1ec1fb53bb +SHAKE-256: 6ef5278bf8d6d30e0316a67246913d9c921a8a12c4c71586b85ec0e201b487dbd7e104001c1c263cffb4c137af7b7b0bdcaf82167d2435344b960e5bac3b66f72a6d0edfbe868f6d77d3cf234df6d86a7a33a2da7b38a88ca2329864937614cb008ad53ee37c654fe27c9c515bf50adbf95f16a9bae7a93a2a2029fa1af9a0365184a6f7c1db31b31c1cc4ab732d0a7590c13273cf962f24902b2719b22ad32a26233b570669bc7d7fded6b7d16ed94b3e24e1f6fdf4b7012081468976e34ff09368d3bb8aa7e1fc2aaa16c017e58ffed34445dede4ee3a5c92bf92380cfe3db4c11843b1eba9b923e216fd895c5b78f4804450ef7478aec89ed3eeba580e70f577df791ca65953de0717e31ff9088ff51db34370b909ad3e8227153de574a5ed3d9e754b6d4d86334fd24f7b19e939b9cd02eae5e1f890b0faa93f2c586c6db0c0c09155c443d8f74f156bae728c38eb357cf3f18f4d1f165b74093eb0d69afe3704931a048d3a90c0683dcac9084eab4da0e7554cf2116161d31a79af7f01bf0a680269405d2222ddd511490038a9c2e21921735ed2d12f5be19684dbe48dd002f163041b63501b7995063ab41da29c1d1924a559e0f9f68e6109bb1486543e9c5ad964661603a4308e937b88b88193af2c8cf479552b3673261fe2d5b5da2af9ea9b5930ad3f21f0ae76f5313005297ea202de032a614cdf4b6765efd7f99 + +Input: fc902b11d00a27cc0a1dd7ef8ba6dde671c896fb2a4ef5811d6f1f38c2ec7472c4885addc3d688f45d3b8c30109df4ab40d1080f0483b6d56f1ff1c71b3fdd04beddd4d2359fa1a9986d9b3d28e150a14a83e4470985203181bcf6a2ab389bb100fdf4fd80e17da69f9853c781edcf56c9d7f8b5db107ee42432e777fd6949a2a252ae586ec5b5643a878571246fe3d6334f8b43238fa34c85b0d370c334024f471c21a06f7b5c8cc61fdfd1835a00a324a5e370b1954a35a9afea993475d7d79ec29c21d13314bd90e1c3932b06ec6eeb83548c616b61ed35ed98dcf94bae97a9d535fa8dee9542a85c9ea464109732c36910f1 +SHA3-256: 4cbefd4fd2add01f4ffeabe0c7c2aae0d3942f38ebacd202ad80768c5bfe337b +SHA3-512: 32e2aa3facbb9798deaa2ae54de23e8b7f8d8e21a03a7f1bf6c41bf1b633ec4820ad6635cc58ba7a6b8a281506c433780b4e8eedaa11cdb63bf0ed7de9019016 +SHAKE-128: 7d9a1f990c42f654061fc4b24474f7d32f4e0a5d05b560e11666a7594db494600c1e9645025be3827d9c5a49702dd826b32ee41d610eca594ff820055a664648d4bc0ba86b11d3b76a661d2e82033a1fd9176bb2c832cf405138e8e793c6b3a8848a82842f83e8379eed1fb130f8d537d680c511fc1d2abc62fe16a320f91851d19bcc0f500ef94824b45271c13726c2004cce2691944a4072062fe94e36b23f2cba8393a19fffd343e211a2d2fafa31c29726421d0c007619f0ef9a8feff763172c3024f2bbb3ea13d6da8295c079ce23b93f62bbb5bddf00670806bbcd058171e25d2e076300f1ac1f5fca2c6291b93b29356eb442f50247d89d23cfe2f4e64b498293bf3d7598044f25e5d353a87f4127d06f3a74c792a7faaecc13aa4b76794a020d863a6fa12f911408b3a0e34d71abb9dab9527064aaa2995378cdea84f6bf89bf6c3ca30725552c42ef36488c4024289ef5581324afe03f1fca7f5f05cc000ad3aaee6c583791cfa2549fd8eaebaa3d5d61163f2e1c229ccff4b3286b88666888e598946f8795ed4acf9279ac0b4fcc35ee7b1de130d714bcd6b7db41b29ed72efabcccef04ad1669c76030f79918c3b08f9d7a37254bc2c7df7eba4264a89f7dbca4e80db787b5dc6eb3c62c85379cf06b15782401c276a710d2f9b1e356bf1ebf5be572a077613611958975cd81c857bda283a80c5bb26855cde1b7 +SHAKE-256: af2eae5e9d4e5a3b03044285d2370983b179a56c1fb69a64bab96ca5a365a87a973f14887b7f5fa64b0478cec273e0c834e41a409053d704db6adbaa8c9ca957e0943be08b285c0bb383123bcb954f1ac87a9b17dd017dbe84cc2fb425ecb7e19b13dc53eda4363051927e9cda6af4c2f6c7e234a542d41f942978ddb61febfbb7c3a874eb58cab96f7e83d7080aedece9f427288bc7547e5992370c4c859ee632a5b04f5707c1cbce35dee36260a5f961f7a74f71ac9cb4534739b0ea1835ff4ff92b24dd1a01a45cfe2684760007ceb6d69c3f33511632803fce9115190eb4603dacc23030a85b41357605e15d457704488a71aba01aef0fd1fec8c889acb2cf6c49c31f3f0c41c6bd98e5585dfec9885ef2bb9f4f5659f6f78d910497498c14489b82b5af2f8ff1e874ff43f3e5e55f94f58d40f9b58ec3e640268bd20fddeaa8b37f0bd94cb8bad407434d63107591cd73ecbb6cc06a448d4bc6c79d26bf7ca8be8a433b508e73b1c5a50a93f1b6aebd823c012f7568167f3c49314a1997ad61eb48ab7914321e734b3c8c993c6303e358222dac99781706d863aecca70cb7f83513ba833a26ab7f79ef65858c4927e17b9f2e8eb1d05923ff2496aff0b0a7f9dd82a6d4e7b6882c7bfd70dad5dd8689e012454e2f3895ca9d638d4be9f05574b4405c7397bda3b0d49b281dc66d568b56d8045d0afdbe2b9568e0870fc9 + +Input: 7b436a5f837151816c3764b2ed1706a9f0c9bb99f0643d9910e6338ce4ac2e22fab42e99493737d4f54b471c4d93cd7c86577a1237e16debcb5980579a8c198bdfa1cdc3d6f6dfc32d61b3182ccfd58ac94e900edf3adda2ee7fa37b56b279f46352c638cb901ac0d4af218d8e84aeb5c4a1289550154e3a8554ec552b3c34952e9cffc0378654940b4b6d53ccd8b94960501cd293c076ab0c7342666c293b9bb24c9432b9f5cebfbe42f7a0b30c2a6b7abb0aad7e42f24c81110a9cb109f6d2543dd05bf4640513586926470ec51d145a58ffefd82df091fe79329f5a456adbb0646220af1d30c6b2718dd3b4a0acd6505102f53e +SHA3-256: 2e1aec5a18335a7425916a7183e853e1135d26fa62b6fa04678ad78656b5ff03 +SHA3-512: 3d8b5603b6dda2b0f509741eda0047c79970199b4a024729925abdfe5b3f9fc8866c31a3b3e47cf9167661842f6b39cac711e9c899d402310ad66b1ed8b14303 +SHAKE-128: aa46207ddc3ef07ad7bd317508525b50b47fb4fcc1dfe9c03d10cb271c07a9d3a366a09766a5651292eb45863371f1bf888f82c335ab2dde8e24b995decc1ec5385dfc5ec6871ae9607425cfc8770d800d53520820405a5cc93344d658d3eb7b5832c58022d2519600e8aa6016060da4ae0d91f6535c101e57b72fc49a4176655ba3129c4229a00a55c4ed2a815ebd5c345de58e2506d03c123fabebf369449ffad797c90e36112114a6ffe20c0c00d0175f84e6540dd30de12e0f4ccad0f78f7bf2d57a157706a82cd6659a0aabdeefd5b2aaef3d29631b72963df0f193819acbb65b31656f79c93e260aafe9973a28092b45bc43824e0f3c8ea5a9226dd4fce175ae3e79e19fba520e895556555ad0ade34a39eba04352c2d0ac62c835f6c406a22e9067da6d6663761d1f6ea9fb37642d327a244efc16e4e52b9cdf1e1b1210f6d8c10e58aa3d6720013867564aac6d3efe389980a96fdb3c952d58472b8d89371ae283e87e4c70658149ab05647d862e23686487ce9685cd0aaf0c037775f918419df6e469b2ae122c9464f1a50deba8b222383bf29a264cd1cca83a258839d5bdf02dcfcbe37273c9ee1aab3e55f781d24c6b639f1f5554d443db76c813e2f80e15fea3c1b1946cf02aeadd08ffccc936252e472a72500511d1e1772502a04da08b7ade5630c7ff8913c2febd7082e42391db9df71ba6bafbbd9b0c7fb5 +SHAKE-256: 77b2cc5c13aec5aa5dd7867a7b3cbfa630682c5e67ddeceeb6d38bfcd23c3b7459686ee68f940235d34dc2a29d09503cbbf4253b2070621d9c8996e3df592c8b32322baea145c782ec01f30e861071e7ce926a494753079c4b9ba88214f414b44bdf08198ff24866ada5b768889e306ab4f8634f4a3b92c5b297992860b7b5f44f31fb56bdd083171f6aa57ac0b5d683ae69f71e2667abd72f1b17c593457771e07697ee10556527cb1d3faa01d408d799778d1b4c6c102800db386a9383c74b61877dd99dcae9e5910d2ff5d9dcfa7ea2f09ae3329b7bb32518e130fe234599f277cf446e816eafbbc89d323a9d5eb1ad442a83f4efff7d647311f2cf49f2698828798e0e33c1433324529ced6c876c2bd5293fd5c6e46cd72c0a4e1676ddad8c76734ecf4818b616ac29c683cb9bb0926d864c72c79b04053ebab0386132c5783064f7bd48dfdb84e2985a1dd7437a91491a807c89a2bac41160a70ea40f12ac25a64ef3d57d1703b39710c0e1b46531157e33511f2b3d7867a1a36033fab525ec11a5df97f3f25d76a1b482d09fe5dcf0c36220d7cff29998dd07cb2eedb119187d620705eeb9014ec1fb269b1315c7b0de82cdbe8ffd6c1ef9be561802386daf7acdf5e6610a79c9c4a6acc8b25396beb14eae775a9f20c87349c43868bee9b86292aa9dda0f53a5c3d085d4d4199ec0edcc4773667687497f77db6bd03b + +Input: fa16ccbbcdd640bd6d184700b0b940af437acf958f75f8269a8120963ccd5c45eea0da9142b6699c85edfcca4ffc3f70b902152512fb2313229601bacbdb4c07716bb0ec2bd85efd4a28fa1ce314c42cfbde207a8af84c386d635118c66696b83543037a7bffed4f4d6a01ef5ef996f0f289094dd7a753307ba203975d3f19b1eb2ac131317af9c1e9de45694bebcb5d2e6ab09013f6af579d0bee8de772b5f351c3f462db3833645aeee0263717d58553854a76662dd878bd0b70c504f5afadf9857ed263139ddbcb3f5f7b13249429c9670736605e9beb9fb7cc674878abc594905fff3fdf05158dfddba27cf72e051de0bbc57a88 +SHA3-256: 572545f609a8e5288c343e2a6aa19f86aa5457088d0231814c7def9e7f36b6b6 +SHA3-512: e16ca96f553bb20f0cbb758cdcc3086825a922096736a1105101b8ef9e103c88a1f5b0867c7882bcebe21cbb8aa9d04ef3b1dd3f137a060d92a1842aca898de9 +SHAKE-128: 81afa606496fdefb580763e228951c71d42c80a09ce3db05add69f9b28e5df3a78eaf07d67e30603c9d577538e5cdcf1bd20fc853aca5713d1fa76b0f1b2436348651b65079162338078e20f932eb7d645e1dd0e77c0cc529bbe2dc9962c57f6a4e79ef2dfca7eec816eedeedf90c77e50f55bd578cc6c5fc34c085a82350bf8c17e1f076cb8f661a9711cb5ecb92bda1a2b5629730dc510b530cabcd589fb2c84ff87176f1223402f4e6acd27077b4e8e4e9bda127069efa76c1ac16f09b6b2a0c1bbef4294b79dd41f795f31b1895219c55b92efacd3cafbd4d949c271b99b04bf428bec63c9197f9524e8e0163ac47b3518b95c816d005196da4d9bcb3ec1ab2b98f19d8406f529265119d99e7319499726b6bf96e3dd2928f87dae20eb5d3cc1a07dace145355ab0821c91685dba7674aee048d8a24434910f5f5febd1bf68fe5c3c18668f14b567cddf0364b6064fe374fe00f56160549b39a9d9b290f231f91f68700ede93c297ad7a188a1dac604576d2d173e200d1060923253f543432081675638f82714705bba9e2732b25707f1029a8c6626f4abe2892b603e17d4ce8492aeddd796e12d3a7be3607d8a8d3987e6efac9475bd5ec2a02d2518aa5843ac8e48148357af79936621882daa2c419e3259145afffa2db1fd71adc24eb0bf948da619e38f91e7d0e7d5fc03000232f51deaa119577d8dfe59c73e5f3de +SHAKE-256: 5ca44972424792c3af77789c3bd0218b3dd3caff0f7c4d03ed94ecc6a2e9d71ba33adf9fb95b0325ed9fc66fe9ab6a2a65960df377ccaa8200a977fcc2c8dbe33b4ece1ba560467a1999b8eba51741a64714002944d696da6e48c55ef37022a1ca70aba8c7f1410e6db44bbd2d70707f7437d339804f942ef0f816f084e7230b92f3e04b9a5e4e15db519a71a037a80201206d6321e7195898ee40da56fbdf9e738adfdb85a185377dc54417e885aa6910790f5bf0b9d66d91609d6eed9f315d4a7426e196cbc2820fb96c2e407a9d5c49a561402be8f6a81aa70307e52c7664cd62554d0a75fa9800fc6ed1fb0c80f32d11c390e01b198a28b432522a98e6da062c4b704f4773690578f88621b6b52e446ca1373eb161fb55d17b8e90e71140eb355510874982720f58b3192178376373597a521f38afa90db1215139540d3bc1c1df15ebf640271b1abd90e2a4ea14af77663763e24fb52968945d9ee19b5d650989e2d292bf2c7b0a96fd36926b519ad47faba140a22c22484dca08551d5cd4519144a969f0ab49a0570b01ccc623fbce38b0fc26de2cee47ba3600757e8a5510c92686a1806cbbc65a703e24925ac1bf76c3ee04b6fecb4761674089a5326022d0a72a80be9523db8b3507a81359ca65ce0fe5967ea2bdaa98f8baadc682f2f1a1a966bafc833a147f8a88e55661e57acdb640f7cebb1e290cbebaa0c0b2 + +Input: 7e5a413e596e9abe4ded3274cb0be8ba6d0db2689f5e1b974b69329d02b1fe1f9c9a1c15c79634d45b296bbcea48d43d05e2ca805ded57e0f2709af2eef2e45a9efaed722b7fef97d1be96fb167cdda764f795554063cf46b1c907d9ebbd6b6c728df9bb872ac6f32ea10a8af0c1aca22ce0c7a6b0ddf5eeebdc43cb978434292fa5e64bfdc13c4531349583f0e73b4d8b23a9b97a7067560cff1c28f4a0999536ad36fcd93d859b6a04eb81df54924303eb9bf79b472a06dc87bb7e35451b0b4c17cf05508cf9ea5d6fd2bc03f2141f86b91a7207050ae956b04d970e8005ffa11b265e8a95107e651538be175703fbf1650b099c56c0 +SHA3-256: 1d0af0539c811337644f75fe8bcf724bfa567befcaa33765bcc2c3cc76480444 +SHA3-512: 3856b6e0b2f5b5122545948416b6a54de802511a3e3c46cdb718068e29217dcfc046d2ea00da6deb9028035530b118e4939a703ed5cb36cc605ec1470dafa639 +SHAKE-128: 5f3a24215f7ec7ba7faf3a85899dab79c5bb3b7ed7b10ae95fa39f5279ad81353a14b93c0792d7b7725cd69a0af90fc5c8c008fbb5c340a406c1fb82bdf95f02be7ce906f6da3e0f50b57d6975e5eed21d8edd1b010b322a45df3e738d3660d781a7b85376648514166f7401600c239063bb56d2f24869a0f0159b65c0468beaa4b25199d374a33aaa74764931c698b5ddd9d865639acf287beb059a6ea6eebfc6ec610a578598c3c86e026b72110e0287e6b2e07a0666829560ac9d764c16459c1b78da661c7cde053edf9e597289340f92cdc11aa10f83df4d1db4b2aff202bf07cce6edf62f0a7d60ccff7f2b1f2b5abbe8cb42746c067f107714f94dd7f4b90da2f1a57851cda0c950fbe32e0b5726c9e658a93782e8700da09c84189a3d0fd27d6c8ea08f05625c6e87413e9bf32ecff6f4b70b4434403ce53cb5c8c3c40932e571b17d65e0a2ff95efd8bcc02e7a272a40ec8fb18482e93222ec3a3a449f2fdb8847f3eaa03c5bfbd843ba82963f250783db893a45f6cf89b83b24c33a60a2180b9bfaeac9295fcfc2ec3c1c24c61a09363c0ba6134c3ad1fcaed5ecb623543f039bfa3ac69b1d029bef8bb92a730c1c9d19989e1f6c0b69d64f90e278a5f44877b0689b21e3b77b348c4fdadf86514c35d4154c0f5f590c738d655f7f3ab6bba5bbe092699b40677f1a73fc4edddc482015f020ed5c609cddf30afd1f +SHAKE-256: 02da9db12829427a7b9af05f87aa60e04ee0a6b7a334a2a1c6ba0da35d7a42024e6fa8cc78a88cc17acec14f84be09d01f7901d676b760d0243e11e78b13e981f25c591242ad4d00ffe4b22106fa587fd56752ab8f7e224aaa182f89b71885a1a080d3e51272f6f5d139e27aed6d2497fa5db15c6df8e4c237888d8c2b46131e972ccaaf3dec1e5e215b75a6f78885610fcc7bedd6fab84f5ab03bbf1e7d3966b63fbe94f346bc8b087b433532ae36731635c7ab8162396de6d333dd913cf9f63f92b52f5eaa39ffffbb9da34e79cede493a5019d6687bd944ef6a8a637786de9d49da917976598245c66441157841dbb198f303366fda8293053ebdaa17d94e1a58e819e11630f617e78f3abe3139fdd908437053ae3243f9b66c63b55824889f49e43aa079512a2e8a9db76139c6727682f80be0513015894facfccd5ae4c984b588c0d98ed22989fa9b98073a051834bfa6cbcc3002f908dc99e977fa082da2c28fd78361f15406f670ff1fc0c13ebf89c18e69a3eb66bcb22704a0eb9a59db1674be5f35a29fb7951fab67e58016648abf0accaa7e7e20093d766e2d9a4916008bab2ee70903efcc422cbcaec9002655ce6900567ee028135aaedd98f607aa1220cce44d31a4ff3ae5c7ce2c9dafbee3aaedb5e285037559ced5dfd87ee25f37b621a5c5b4b6a64b66213d8b3fb54dbf76134aaea5a1836109098dcd668c + +Input: 3d3a40750a0a257f7e8ca3e13d73a4511f8fa77393735393ed3cc70ac1e363c590a4e1d3bcc087f1f56f1f8f3262dc9d6d5812b9901a4d222ccf34b4b58939a3cf798bb86009a1257989f790e3d8256ce38003a1943debf28d3c68a47960bb1189db6bb77550b8bbbdb8fc3e596fef06d271d8f301f01eef8dee16a7aea18d34f46a884fa953e062a9301f11fd380b11bce89cec1b29416acd03a239a6846415a68b6385204052471af4529cd392ca23a42badbd371ce6fcba7dae3bfe7e7830b706f3ae0308fa5a804eb1c8f54da827dda83a7f76bad549b96613927274cebd4c6c91d8e078e977e69c30b4c3f3e62c433099708597ffe7 +SHA3-256: c83c94de4617dcb74566f95c705db05f6a707c3664430b834a9081cd346b6007 +SHA3-512: e9e0cde8a75d95f89c9cfbfa0868e07ac565f43468cc51359cee795babeee301e68524df756483a2ce2d4878a611b549f3d23a26d65a2a4659c82b823d78ed79 +SHAKE-128: 371b356a3938b8aad9c13a669ea3f0fbc344247ce40f76ef4dc9cce1210ea37d081b836d4cd9fb061ed005158bc13a42ac9aedd8164b23236085c2ce6c41317cb5fa9c7a09ebf857ecde30a296de72b8f20aaecd415b73751510655dd3c2b5420bfb0225761ceef95124ab5fe630bb5b0686c40ed9b2436868f26d9d8a67a884a109dfb34619abfb63be473e78d09de5a7b433fb33636a7bd6dd1faa93e3fb20e853c52a2ba502b13ea05f564cf1dfcae5ea5be88290003e6eeba424918777cce480d3792cc492ae110c9713f37e06aa740ae49eb635e36bb6b080c1a145b3eb38da9e2b2f6158596e2c8db8fc2c5a1d2e8c19b06a81bb041e72d35c1e91e2b96bd4f06e3a7dfd2c86d057b4952e93351b08c48520414928c9abab7bbfb6b5cdbabfce0cbb0e8589645576bb2ebd4c2b287e15be87836f3f392475514be8b4030b6da2d267e2c06e49ea8b5a017380e3ffffcd0785ea170146e4be5724bcdd51a22a7d568e22ff87a717f5dcc4afec22744d3a41be4c3f577ee7208f47f20c024d2e801549b0b1067d9041c572410635a39d14f5b0894bd11ea73ff19417b08615535b664e6cab2ae3142838ea3c61af0e2dd9c5fa5aa4e8c3d074c2d02dac1b527e6b8274a08c039492392df95da9180120dd5d6d277b326337d8703c6118b729bf0c8d1417b18663b41d52e5cd8085900798d63ade2292d4bf98a50e6103b0 +SHAKE-256: b9b977a5212a43a5e4312d12c551d3b34d16a43c646cc7769a87d69b6cfbaf074470e0f430b200acc9fd06a5b129b4e888734ced070c05e514dbdfba557c5038ab0dc115f8e7c60990b6a741ecb032d50f90e3f7fc1722da652325c3c8a06c16caf2045dbf43ea07e8a3ca481d4711557d7e7929b8988dee3ca74776f596b566928b37c10a1573dea9c652dc2a754ffaacde9970ee9aba0edbda5221935259388fa6bd2766c89044017799a1376ecea92749ddd30ee6e2c81bb8c35f26274f267e85273e1e695303865ca29b4dd96a689b939da1c0ee2bb6095f867b089235c3972b738a3dd6bf8214df431051192e5f2086188341bd76152b90c741dfe9fe0056ec463a27bd8603e4ac30b71538f946137c9a30939bc42024af0f574e6a433da16dfb88822b90053e19d18cdd39e39028165efdbb2e75a7d8f69f01b900caecce0ca182047861dc918ddde65dac2d187aa48ff1cd1baba076ade5bd811b1d2a3c0466b6f8918f9d82a384a8cd73a1c39cdc16a520b0950141fdb4cb0f1e5a5015fa12c4d19dc08e9403488d233aa40de546991612fb6fa7178ef5436df14bf9b6f6d0f2d7751d5526e6d910f183782b9fdabba6f16651055e6bac189e2d93dba80413aee6d6d5b22bdfe88e864481abc56705693bbd11e274cda1c49d24fc37919b009b0d8e634c120ede55741c93c2f3ec62b93634638896b0505d937679b2 + +Input: cd9593c7a88e370ede4ff38540dd9c1cbec6631090a289d4297740769e5b9ab97eec2098bf7e6437dca5d88f84d731340471e816268d78c0f5bd1d9557b10aea9010c1a4b21b436c5c7be89d6c6f5d2db901d962801945979cdaea30d0828020daaaa88d48e3ad69916172a5d5b76c34a7833dbf3e7fe33aaa2ec8cf9f584dc03a97a1f9e00b32bc631de9900b7b8cd7b7dd0e0afaaf2b8683cfc6905b3dd4e793b4fea9de70dc1ce4d062eafdf814fc1aa7e6575d54224e988c6cd04fed9ec0d211a7c4c18d7ccc9cf59a644386dfed5d30571f514d428e3c1659c8d0a667d8082039e6a01c434dd423a64b4fe1ae5212df63d326a0886f84 +SHA3-256: cf0e45dda9abbd1769c38fe0ba2d2c64e49e9dbaae6368d6677ebe7ca10cdaaa +SHA3-512: cdd7edace2d1253900f634afcc1f449525360e9334de7193ebde8174126f462875aee6e5fa291076e3f296c3e66581eb0db81abee45f9398be9eb730d08f6d96 +SHAKE-128: 94268739f55403c877585ee64db08557fab4965cdbf25a9c3e2a41f044322f36d6c8da14bda3ee1461c5712f7fb283ce9bd6daa028b5209c730b9d7accdc930d978695f6a158a62c7f8ff708e33c5dee6bc388d5ac1419f809e8f0877e69097a593fd5569b42d1914a3ee1ef33f7535be1f7305d3b9b74c039ce1760d671f81186c1d516e9e780a0b316994f57e4b3a64c6d0706add4e6e3918d75ffe5051a0db1e031ad2018dc4baa769cf1aae47a758d8c663341861acf6fb027867ef63c653fff860b4efa1c567cef24fa9dcccc4bc9d77e576c511ae0d8ca7442d3ee5990ead1c4d0b6cd9d5a7e10b2305b537a01a3bdcf2242015b6145e8f2f4156b944dfe31bcfabdb8c29b35770d63c87791e82294089d0ce57a033b112005860795c32d732f04ba609991d7eea086dbe1b4c3b6e7599f9cdad2252bdb19fd91da4036d002277a7ea0ae5b90402fa98831b898a58fad96d01205955fc799c00097196e8b4a69c7ad86ffbd7a8531cec11e51d7c0d0e6dba59e3c2fa28143971e53265b3898a9f555d16c9db921904c71e7400b508ee6617804bfdda35dc64eee7dc8d80f4acf0c1d26f37ad442616551109ab5c6761cc1913862fbc557610ca6c2e9551ba367a08e051b983486c3bbee3da7abe0020eb4abdb82d89e04b207b4bafb4e9053981d5cdeed2e5399c8c342d90878ba8e74e9619a900d5837306ae427d3af +SHAKE-256: bb87c5e0601f3ae9ebf4be3be8485443477388d9476a417180514e372b03e09f44c3ed7ea6d050e839068a8911f91fc1f3348d2562770745da35b05a44a1a253badcc64a0a4e562c8746fb06aac65b447aa88ff5bf42654bf2ea6ce48ad3f353d11c5db3e7aa0c034fa0fa65151f7d8246efe1c61f48acfbc07e5d9fe8818d02bdce1abeab5f71e82c80ddcde85206d475e54cbb93c5aac0a2198f562393906d0ae9ac2d8059aadfd6844cc8dd28b10cbf4273dec30c58485ff020a910298e2de13ecf4a002c7619f27712120509f2de5a0883033ddb2fe3b5c087d272b20c51141706ca599db10d565434889555f0634fb061625455371ec8cfa652441e46460469621d686f06f54d3e9c4796a0064d9a9c9efca9f532c03dcad578ed3875788a9ff0e53b91b55ef66e4d4c96a9cb34bf0f998cc42a7ae5cc31516d90823a91b433fccd6dfecae10375e8eb41b21ddea417ace683fe9fef086b40c03b3dab50518c7a106d64ac0bf229a3ee70c2eba56084b855f9caf2a87ec5799cdc3b2b3d1e2ac8f09ed48e21d1831a7728b991ac9fc03184c3a78eb4da978064ba16d8d6ac799fcb3880ead2d495ac4638dc4f8fbbde5d4564c99504be1c7a3a0c418ef03fa7938287482fdc985c325e9a152e3c5ddcc52342d6134b450615cecdbdcef1bc11583022381407019d1ca777d613882745fdcf0e010a89c2620794c8644d71 + +Input: 770147d755e99b638c1614141cfaf6fe6860899d7d3749cb4b0ced7b0886d59fbe4c508854e457a0d382f9b4173694ee62240fe0a146897deaeb5bf2d7cd533a5ed1030b84db4e4edcceb777830714e8d9cc3b77a62778207d5f190b31ad4434c5de2f24da24f59f50f36100bbd2730deffd2b0fd00dad16e184c7ad0f4ee2fd78eaef211a7eb9c2ec6436a135650a3bbeb2ec0a5c52ad29478104873576e13b9a097f8f207d4f38a007ada015ffea07df4501180487caba5f238079059386488e0f726f2f8c045d9321624a786cd0cd11e964d5a3532413820c56cbb415bab1130db499b8469953904dde523ae030892908e46e3f4a2340591a +SHA3-256: 75f58015984714da7cb6f034729b4a5047cdcc42301405bff9eca9ae747b8557 +SHA3-512: 211b84361d13d66cfb9fc4fc06d8ff12ac21c805d820b17ec02dbd98a79020141ad481fd1ae524db6a2c04a0c66e6ca95c33618ef773712edad9f1ad90d5c5ca +SHAKE-128: 93d46e1ee210edbb595b865dc8ab89deb2aa4270ebf348eb24352d633a22df07dfb75819847f5d8de9d2e9b4ec54cb79b5d6e42d8e1e547d1728c041d8637406eb01064914bf4fee3796cda94bfd15bc0788aa3eb57ca81d67902e435e2307084332a268d301578f51c3989f4ee6d46203545157954e6b7991fca84eecbcfec4476667c0d64315ea62643c214f147eaaff4923b8fb1a3fa6dce7fd3defb6b2b69635e3729b4cba49335d8ccb9318a87b2cea70fa584072d159fb675c2dc37df2cfe6d11203b312e7fce2cd29cfa7abe5c6896d64947903fdf93b0e89d95bd01e4d42cff457ad3961ac4d64703062b346653692371a9e03ce710cfc05335022128fe07cd7a9e894fd6fadfc78ebac8d4f62a3231cb18e0184e0df2bfd0d9221ffdafb7fb204b87c509361a65446b900c882306b681625f6a69893a7100e67754048a226144b08190a4fce7f7ca4d2e58809a9dd13ee120d72db84f58c121a021c6d34c435cacf876e741ae1a85df50cb05a6658919f61f8d4bef8fdcab5fa5632a2023fb8818cbbb7de0001b65affb80cae76c1221eab8fb2b54e7511c8f4b8ba68f75b20d952790afd71f6719e84eaa6eb0b0922cb4921cf2e8b78d5ba34ac6ec3790a2984426af0036ea19ba45a5c4fd00dc2b40c52444db7f3ac05f103b6a949858187b103597340296ea70c56d7f05de6bec86a4a206247fa771cf6fec10b +SHAKE-256: 097954ad208cbd10fd2b46800c0d2e13be2ea589e0d2b928b09ad8f0df5dd922a3f06f9f123342409d60fa8c3c75a25f5e885d456b763c243a3e3428178ed1f86bae5200213a5a51ff60865e16071a3f60bbad4572dae5af92b8b2c66f065a89344eed7570018da8e1727e8f96bff2f0b4869221e7af96e5f0a65151eabdaaab8ddfb11328d6d1437de79a1789a38ee66469694974b1d5475c776c0bd70fbce6552ba7dd9ce5ae281b647bfe801effeeb68380abeaab6a718c2df308634cd3cdd09cec319b4e4ede6d01f18b6e43af83b24acceeeb22cf01dcc2ad96237d39e2c4355115a4b4c1d30bf58f7fad4f175292eb8154535d3776c20fb6dbf513b1fdb635613d5060029195b23ada730a705624605ac63887b158bd16bb062426de571cceab89fc5e3f9791edb468be8cc114886ae136489973f5cf15a14448027d090dd73a6565f39341c2657c20201b329dfc3227a8c650ea1c176efd74dac4dbb6aefebb16cf0698d58874d5f50c74d7dcfb894da9fa529aa5f414a500f05ea928017eb09eb703400cbcd49a915862f4002963145aac657716e51eeec01a865f372e9fffb0ba9ea13fbfaf4ff26e2c646b00f2ddfd5842de82634a724213a73d77a6c510a5ef3c2c82449806ae84953f043cc9ab7bad0fec9be8c54ada98596a6ab188cafa14951d1b64cbbbea1f03588d5ef77c7529a24f5b42f1df0c072682fa + +Input: 74ec44258aede674de36afe98af9776327fdd1d387badd03e79cef9e7894fb291b59cf81a1a255a6be6b291bac8aea7a800f0a70d08f8de4675a18891d3390e7ce3ce0841f403ab0d15c3b877018649c30e1d2efb9b39497e1c708a0288e5cd8c1abda692b015c97674fba882673e0aff596eca3c3e05e2630fd187928e8f92c24207eb7c74368405311461650f9e40e6704f797f856fec29f0d3af5896c7750cfebdd5e5d522209cf3fcde9f1a4923e0bbaca43b416c8543348fd54d3e19ed0a534dd3d37e24faf80aad3b52aebeaf7c9796cc9af663d53a771b74e627352e2dc5f842580f075f027e9f1b0b4884b738ccc49fbf8d0556786c5b0 +SHA3-256: ba3bbe144ca628741fdce3c48bb83342524f7de5b9f95839fb822955240d6cec +SHA3-512: f57dfc7f0d05ad4df05edd0139e23b11732160775944752cc982e4a0009c4dd17ae82065ff5b85b885aa7f913d3283d9ec009686b3b60108a979b50781a61317 +SHAKE-128: ccfb862462889fbd2320277f6a5470909a27adf3a05e93087ce481c8e35a47d909837079fd97e2909d1c89b247a82e8b77943160bd0291be559254fd31e21a77e95577222d450949cc4a1373b3b022cd0a357e4e14e95b61f9c7f4c4ef85f6e7a0a28d02541e1cdf3d520d817af8269d197386b1036dcdb42846a4886316d4fad98819b27ea40bc5924523f11dcf0340aab54c2119648e87c7fd2059356eba822520f54f075b463d8e85a758b407f39a7a73efbd3534fcd24debf8a3d836df7be992a2f6ef6c323dc348c8d3283ad02d3ea9f72c697b37c367e3830d415751db218bf92801a52487f9e2128c3cb21931bc07042339aad4534bf1f7b60d75a81b79bc5628835da5cfaf85f2c96b4ba95f8987e7b2ed6b7d5aeedc371aede18c50bfefc3ac0fbe9a942bf9a90871a55e14b80b9745e84ac052c2a5ad85a7e101ac65bef43af1c15fe733e4eb1a294b459abd377fce1409ac7de99031df7e35f7118a533a804c37613fd07984910ccdc0529d5eae51c377020b369fb42889884e9a8e745e600799c6907acbae19cfcbf8a41a2f41741a50824331654d1cbfc5a318bc6e69644549d0055855999fd203bcd478fbe2137a007c096bdf82e22c9edf101d3f4b9f3a4fe6ff5aa6e4d7d228ffaa58c376617c920ed162004d59d01aea4dbd2c242f2f2f454bdf4318ea9ef705bf7abc4b43cb234bb20152ad21dcbade52 +SHAKE-256: 312685bde5aeefe566b0d29d301fb58245881e685909e234e3a665bd85996c49cfbae1cb9c154cf82b92b3a66506be5ccefdcb4b041caf2024c1e2bc855b81fd7c41de25d59d22eff79d1287ca7ce0b2d89de1ee248ec0e5a38cbb90ce5afc893853e5e8ad5b5428720d06182574876cc12516c4d708c7989cb48d02e57daa34fadd4d34cde1c033442366164695297267ac0c5e11e660038156930ef0096b750b83d161f3bd2ca3022b382ba64973aadc62c0ac24facdb75e2c0d71cf1298e3eb5a728dbfa5309116ec851499ff2eb60458960e17c702c8b356f9d13020ad6f3ff5c5acd5a2ef229d7554f6a8c400d6d04b5a542161bcf28126b4b0ea40c6a87e81a469ac8be1913d627f677a758a1b1420facf770840f9dcbbe8dbc9db686b61895f7051c5b47d6f0f389a8fd8021215fe2aab363fa2ed0bf91d7b69f65c0bf066a5ba43a4c592ad78e28ba59a2fc97be8ee1b9b175915b0b5fe747741462d7ae26950253f6145d8b77ac58b8777af00620499c59993fbfe51de0e09019d6005e568b1dff976a8eb026084c33647bfd4f5b56588ebbb40cfbd4b0c1fc2c7b12d8cf6f74e64ed0747209791226fc2487907be4d452a50c9151bedc9ce2055b864f66fb95674540fdc049a78cb287f93114e0333e8adb7a2e435c7bd5d11e33cc255e03556af393f03251b526525fce5fae2c5caedd268f5c0cad025b5227884 + +Input: f26edf116fd5f08edda64c345d74f45d72e658c26459f71eb20194cf4d26ef40cf6dfd2b4a3b6b5bace715f6670cd9a3216735347a5c0b521d2923ed3f2759ff015e0610780406c3543e9c6c41afde980ce5b1932685ec4f358e6cc6036fce1de5b8333c928ffc34501e2884a433b01ed43f7037a60e325d85a4bb98e016b6b3ddbe76925daf591eb52aba7205093d8ba2c202170d6d7831b97406d34d1445a17648798b95f4c9d6ce99e91515828c14e2103d955795a3f8e14b88c3242d9540dc054c9616d127dcd0a950562e8308a628d0cb890651ae55eac994d770181496cb5dbbe6b8c412390476c68aa28b0226976134e19297701600a5a9b1 +SHA3-256: c2e9da9b01d7897ad357de03be0afcb8b2b42a2ca322ab8950ac011d596feca7 +SHA3-512: 326fe696e978af9f289fe8f7d704f08793d446dd990a167822e97cf3d2a9161a2191b4ee49b44c45eae2442f7bae3c638713919dbc53c75b8f9d8ee82ad177a0 +SHAKE-128: e5c6ee339e658f364509fb90d481569d2d5ef98f21b8322a5a4a76be9998f03c4a7600b1597d977f0bee3e7adce79518fc4b620d7eeb2939cf5016b55a047e8826a2fdb7f7e07a1141d050e69dac08ff2e6110fc351e183d104a137284946e423aa085517a8121861cd5f16d996aba1ab1d4b2d7691c61a4a9374df4bf88bd64a77108949386ada16e948cab361feb81b9b6b6ec55447f71605223533425e7d19f95c0487632fbcaebc53cca2f6f60962a61fe3d7e4fd534888f65c143f775b7f8b0d21b9d6f27941b85c2cfff751622b4d5bf8986cd8bea2953a95c74c58e8a58543817095b2dd889af6612a09a75deab17934aa19d2261bf84ea3a15cd0f78e983d0a710b4b50ccb15c1c1c87b9f5abd35167c3233340d706322c57d4058f9ec1b9daa8855a18b711219d365e8f356ebe79287c652e1675b84732d218e434a36d6ecd58671251a1be5407c88e6ffd0d35f90e44dfcc501fc39859b0b5a82bad6806224fdcc8cc332da4f422d0588023dc0c28491e4f8f16e98bed1fdad371c43809d18216388eb0c7c016bd206379b8b3305d32525bb7054178e31ab34f6198a4733caf8f0a1e15f63fdccce563ce94bbe1c1004a87d8d2e18c95a473a0b95d980b3bf6045f88c94544529208cea83692d532ae12dc6bbbe727ab73ddca7e94dbf72170d6429bc108cdce9122e2c64ec19853e08c8ce6207a66745dc1ffdf5 +SHAKE-256: 9046e8aa3d0e7f9eeeda0fdc6ee6ee899f0be53cdc2fed363dbc1d7f71de2db1d07f15e7f0c7d56fd58094b817017d2e2653b949612134f8d79a863f5c8f5d0b3f14a9601fb2969aa1e10e0b6508127fcd9ac001baccb435f74330589a3b6ef31c1a60edc51884e8236c6ec6c6c13f66dc8c282342c17e1880e9d38590061b5aab0307c7b188eb768b719b1b5cef955c56f503af264f7e116b78febbc9aaa37abc344448b766153b566a44d784e2668d6bc6c78f6fcfb2f9985c8932633242b73ed5c2a8d52e837b7ab31e931c81b487f9bdf533dc29f207a19d433de191aea95277813049c7e8d0cc7a33c4cb1a7015da38f051f3bc6df10e15bcf5be130ff96e97930bd1e384eb25463203119ac4ca628f76f8d66abcd884be33b02907d2e498c36e35f2cb870fe54eeedc4b8919bf413192e4d42b972c824a11a6ab2ca15e8cd83f0fb9212b6a54e514a32c1919c50db35c25bee771d990d4f54e3c01f198d2baa70bd178ba96b93ed7e920488cd79f57ef019fb0151abcec631d9f6e843aa93463b8789e8428fc37141cc891f8870ab6dc8ccc497a9ea47445aac1b542fdc899e9db0c6e1060ec73508ab1591bf6b6eb64e85ed6b2557a14c849cfa4079eef975ebb054c21257336a4fa920bcb39da17ff22226515dab38750ef7344e37b23cf0e6a20171c2a8bccd50ee43c1e0f3c745352a9e28a7532cb2bb27d4ad691 + +Input: 5701e38a6369652b54987fbb64e9da48449eb6dda5ffdf18e9f758e621997e3fd366f24e5ae264f9a99a89983a7393369d910996656418deb583a17d5b831fd161cbc6cdfa04633908582e919e8e4187708303edc01e5b7a52d7c626453a569fddb393b6533f96f0a2c7efb1c12579145ab20093f6155f92e314223ac06493d306976b635cdbd8800e49c9b02ab4fecccdccd9f710c0a2d23fc41b1128cba023071ff7d6ce7ec91b27f1ef3a6eec51beba4cd9e09378f828e4bb16841bfeac6c44dd49078d12a5594a18dba78abdfe3e097d12698c74051adb9f4b7d8a9893e9b62a216a04835e7243b7528edec3a2a8a54f9f14db607b0a2e611a78e4 +SHA3-256: 7f6162b07425a5ec070dee4142698ed731d57c2aae9f8a41f8946f2d803f58cf +SHA3-512: 4390bdc2cee3ed8e64e5783e6465607e0f62bd99fd1a87b1c83071ce1b8f81028141506164d64697b9142a4fe061f7096f37f4e85b5bf37b247f976950f8c730 +SHAKE-128: 7f4e4f6f10ed93e866e1213cc7a5e7049cdb8b89e92997689948e48f579574a28cfc37154c95a294c6c76223dcc2528f7d91a6f220fead24ecd4efac5daa98b47e14758afb2050bada8c31c99569821ccf572a03da20c8ff2447ca33ed80598821811e61007cd97232d13f23ea5790e2e91d9d951d2892fc76397b7f14fb5666868b050e119a95b1c49ace699ef0b34d31018a83cb368833f73844d776bd41246a77785c7e91ba4f86f8b38874e4eef0428b05d5007f699a1fb1786c486fcad99a844ab39ad3318c53c8fc865f2506a4407075dd55c0b523393d054765ca72381b4bc8a9d3144bef5f1288401bded3edcd53e6526414780d4936a793ddc58e10bc495537632f532d6b04d1ec30ff88e65a80aea1741fb6345c4feb055712ba7966fe88dbc4c40a59c89146457e13f3634ec1d3b58a47c37663fd285137a298073e99fddc948a68c4816af2eb09462be53d7687eb00fa77f8e971dc6d2ba4a58cbfb1564a9e49d9d7a047c0c1adaaf077682915343dfe399fd5ff868838ac239c3ef2ac46eb47477ca508be40b27a53cd8c7f2a3b4f9cab1fd131aca498c54dbc85e61c6b203030cddcbfe74db7764415e1172c2a206a26db9dd7d323d62320700267f9aa20bf44d95aa444a021d08d2658f477d357846e4e3eaaef817cb00523831d6ef7e30c255d96728f5a752d506a00024fd9543cd26ae4c46b93613f5946 +SHAKE-256: 373c1f4f8d4ea40a39226e46e8cb27ca28eed2c9509520211c7c3ffe0e6ae77bfdc3c10f3fa3e020b27fd171ddc2e6ea98e2939a980407c565265c92b120b6a807c100f35d560e1b3a564683819ef4deecf638afaf19ea4f748472e28b231b4a02fe9b68dfeec8b931d58c461153f741dfe50513c0b7bac95daf02b3bb85a94bf79f0ae35d6aff1b85a80b96596783b8e591956d161ba0fb38efd515b5e40017da800d5502460fb2f0755a203ac70053fe5477096587c5582da64afdac60a5b25e5fda154b0f50439d09592541cb7d75aad8c34a80d0c99d3868835db18ef2ae09940cb95de5e8fb5db9858968792258f44190ec88a276967fd04b46623662f0974aedc4e7d9173556ef5d5c50cbb13ce8a2b7d06400bef2899348fa136bb40159a3f40a0de1b41b44a87943df74f550416d17e08c1ae831bde3527e8d9b6d78f926aba2dcad0931529a532872121398436914546aca57c977c2ac8f0d429b0510327b4991a091499c66cd8d387a7a68f1a0fbe5d720ff8ab18691db9bf2deb7f12a187768373e933b9d8625426413d09d25db96165be394255bf3b3dcec457b48a94a8a53bdc70c31be514d302e1784d47d3784bf2098daca58b78bb30a175ea465b83a1dfeed6b2622ea66fae70e73de1c075e01cd6b3142c44d0d55346755ca3823aead2fa73bced19bf4cc08520e7473099564a337fd2768aa3eda16aabf + +Input: ea10ae25b93ca6aff7926230c0b7ada7a6642bc5bd39d133c721560afab1109553880e7c6cd1051a1b9877059dc71df622fd8c4e0e36ce63b0adf618126086cd87ee283aec6be53905b279e36bf4b7093ff87667b65949a3fce3a118d07f96d5e2aff5d00f7c2e061a0a3cd642c4756476b782fb6e75abdf9f970429c22f82c470e754ae89967310fee93fef21f46b579dcc558b495ff9a9f0f13e592c2c2afca05ad1b59089a82072030af001dd9ed78cf69cc25f2e11f0b52ac95e15a0faa2afdf0e59c01ce7b7f6391a9bcf9ea1aae15f1f4728a89caeedad0dc84804911bb09e3101cbac38232dcfc77a09261693c1ea9668eb57b05b7011e9fe6659 +SHA3-256: f49ff4f90481e06f062f4a22154a3e8a7f07567d7cb6f9b60d7efb8bf2e907e1 +SHA3-512: 64e23641d232ebfd883e75ef28a654583ebedb6000031ff9275c616cd888d01f8ae90f91313e6f74405db8633dc2f8be21122479f7c79986cab3ef24953e08ec +SHAKE-128: f62c711b81f53b8734f364945c1fab1644f3a8d099f61940d90d348072cb98431696e146265aabec37183f84546ba8fb3245b3d163e14ff68917388070ca7701e7c7e23a3c109a7b78b8159feafc0a7c57536175599c872a1c9344f0d49dd6bc9808f2086c103078223204931a97e0380c9b18f29fbf37ebec5cdf489c95ae7a1c3db010bceb8756edc090e5a1caedd8ce3770de0d7ca3b358f465986ef35247495f49d31a9b7ff70c2b04fcdd73642070befb7df4ee49687a90d619c65f2afc6cd531d45615bf81ed0cec421d7fa7ed25eb4fdf0036715fd56baa51e90c5a2ec4eef4d270cac8c5c42872629480511e298de5c4d3600f6ff556d038e8c453669ebaaccb0d2a8c7d28d61c8cbe8323020d21a789b5e64e06c3637a2a591af10c7f8ce1f4be7593018f03c275103336d6cd99f5124c12b6e72fc560f6f43d1254ec7787a41628fb731fff82099290d9a8b86468d263fc215ddbce6008bd159069fc3126701b9db7492ec6262b47f733712a88ba5edd440343cba5718c851036f5e96696f8ae2e11471b4c5c568dc1f80cd8aff995cafcaed76ed49595f135dd57d2fe23bb10440a4f26ad6f61097cade4176354c3b4a1e5dd29cbe7d8b2169cab6704f42110badd380220a1822cd921e2b88b148f083924b9a0f579f8f5ee11a2632390d0104cac6d379c905618f5def16ee5fac507756fedb618972d5d112d64 +SHAKE-256: c992070f51b6219403ef463e43d5ebcbd597f9b45d696558a743db1c985632fe1fd9c8eb8d1a19352769e3d256545936f0546a0e61f2540fbdfa90b02c9bb68e6869be0c09b16120dfd8f608fa8f003b4b519b3cc56763148df0d51c897b9a376fc31511104a90b4773470f7d64018f8e83ddc64967fe14c20a99ed886b9e63989e6384090287a8b0939a0c16ad030c6688b4c40f5ba4c8d53ab1d8e9b54773ef43d99e21bcace73a94a0f27de6ffed43f9cfb6012de532214cf56adfd315c6abc379b7f60bc67f2ed181743b042db7bc2207e68db8875a77ae5e8b739c848696d68512a03654313def86641456d0b3b7281852ea909eb1bf4eacef383e128a7963b3fa6ef56a75a0c9212cb994f821f1606b4c5010aaf26c9e15cea40082e4d1bd46e53f1a5a0d0fea1fe322d8a7a9e89afe646d5be3623c7774e6d2962bbb03642df081ef1f6776e947d399fa8446fdd48c4d2a87e2c0d441e046c8f7a27d5391b6a5d0e75d365f984c4b576ac28d7218e9b699b3a9fb77fc3d282ba6458de58306142f8013486bb9dc795b2728f502c1bb56066e3d838ec4a790e7468d0a8daf13438c9286610953d61895e23efa338054a7f90439833050012f04f637857db6332827518abec34db8fbc614d7198185009e19869abaeef4014cd3174121b8e3a77613bcb3090ff9eac5eeeebda2087bdd3db19550355e8f2b2223fd124fc + +Input: 4360c70baecdcbcfb6a94057584e0fa4f1f2185785d344065e5f0b507db3434774a04907b66f32ef5f40a06ecf9b3e976e17fb0c4e3588027d3d60e3f48f42fd25fc13ad1a4ddb8220136cd67c89a5c04dfc531d253fddc0dba1f69ce13225f13570ffe34bd6ca40f15e73bd8bbdfe61873441d967f6933a2659fb88eb4dd74c461686d026f0337d160a485e18349198d47b512a867aac6bdab019eee08f4c7dee03f64881c56af8ac3b6167e93c94cdf65fdc94e43ee4b4c689c3c0d022cf62d0705af1d8e82e76762f6b0c2cb5d87b27df52d0558b7f87b92a12c232ead1b282a5db3221b6d1003a61e2d26a60b2ec0c9cd9c07122afde1c47f31fd6793c +SHA3-256: 3c7ddf0a7615c2fdcb7528a266ea2be84d433798f8eb84e70dd018db916f091e +SHA3-512: 0f649286e8d8897b7069c72e6d47abf3f5d093e4d3c2b3653de43f825a1df62927ccd0eb283903d23e8f8a44435553e88d131c108ea663939f04bf7be4a6edc9 +SHAKE-128: d214ac64f919f0397013beefd269bc2ab3b2d0480a02e2f2f7b988d024aba052a81d5b564a858a4ca9ba4689efa57697de94a51094b9b9ef1681e9c3f4f728a4257f7f2aadbbc07fd6b8d67c633e28ebbef2fc72847a27317ea760fbdd1d82cc2c5ed88cd4613cb024f8f157ec9267d2801794b972ce93efc90608dfd73406f35a7812fce1351a17fef6f0fd884415f1f2c6d3492c4041be18e5b2459e6521892709625004a22824634e6ebcd8dbd042b78dc2b57b86f5107f07fde558a5c0f53dc83c42a7a8214561931dbdbbb315efa239de9751fbacf8c7adcaae002dbc209ef14141545b9ca1ee93044e1664e636700385e6f3dcd109c88a4b91ab090721015ed6b6d0430ff4469ccfe423e57d6b1fb02f7a1555c3fbc192c96f1bed089f480a62b0d45702bb37cc71188fe1592591f8ea2736954e353dd511d59ea06251b3c19d1db0e9516897b9116be3b30b993575a3915004aa2760af56fe69cb4f1ee3c0b9bcd872a3f7f2eabb305aeb2339e7f8436fbc82bbc215953410f3701d79893e5f0efb6ae77c7f48240e30234dfa96e373bee4f8d0c005b78122a4f17d316a695d0e98879f107fdb0041925d5ed812c598ce71d5ceef3f004856948a3723adccce4ed29c8bd12ebdf28cb86fd5498fc8d316c086f276b9163f7077c0cfaa7c3ea75944143b6e501f59fbfeee5922ff629ca601918ef6c2206d27e11945fa +SHAKE-256: 5444c7034a69919b8f03e043b4b91141c8d61106cb37b88991a5c721d9248fcf67d048e05f70b812f7e984fbdb82f4780a1623fb971fa450b977b23c0249648fb4fc9102f08d9b89b4277067cede46391d4aadb5ff81bb019edc96579fb2eb1b778914109294b5c69d8206f6255fe4966b742ac22ed3cfb9f51b201594c5a02707660226b98ff36e0322b8d6a152018b55fee2aed13647ce8fb38fad547f2776aeb1418dab99aab59ec62ce5126031054709bda2d44f9f5887f28e64692050ca7140a127cfce16ae93e3fdb1aef76d8c63c4e06bb2b262d980dde6289cb7735bf118b27f6559fafea65cfd15087ee0ca7e7718f9be93a45f1508d5b6a37aa2d1e10c340cbff858a7710300b1a116f61e94bb3dd06cd3c47a4a0f970ea2db13fe6cedd326ff9824268eb07c932b71ffab2f3362e78c6db75f2a189545f40ea779aff61f2f9ab88eddef2ef369a65a6d29adf986c5fc3b7b810c654a130583c424629245630941ec8e269e29924d63595ee01c6e55d78fa8a8de3d263aee09c351b894caaf525d3ee5eb323d1ca18344aa0187efc9579ba555f9002cad6a3dd790844f9def49dcd3777b2d27f05a52c7f51e65800e0a063e5e792160af492f787160cd1db9e26b8740459816db1de14803b3f79be6c8782b2ba131c76c96a877f175e36e412c7b19007f11fd0f0084e2d0743b19ce0b8bf2e926732a00cebff936 + +Input: e88a8bd3c73597ba608159428ad3dc5e595379e968c65450879775b013d6ea4be59163e55af894e2c3580b9187a666822c794a5947ba06e4deffab1b11fe50665b3ce6d993b5a6951d64e3d0019cb2096bb735bf1c70f75195d17509f76b81c9bce24788d7767822d6d0fd8eb19b4158e703108b77e331b81c30225e8a6fc276cc4b3574297616a0d810a3faf4d4cac185b4021cfba57b5ff20c24cd3f6cd05786fecff5eb26b2b6f75ec05183413852f07238db7a55c6c4f5ef4d4cff40dd0317e62b59470cb30845b9a509c132796625ca7a4f6b0b836f333375458b70de86525f5d633997c6a79c9d006d1ebf521eeeb73afe25107a54251b9fa7daeba654 +SHA3-256: 2900f7bd32b47390b6dcd7a1487b7ab097051ef7a8ca57b1e2c0acf5aa916c30 +SHA3-512: f570e175c9bae8cc1279e005c4023542cf1f2e8e79090405c94ebce9e3bb86365f59fa1d3d68707bdc9018988e3df4f5867e9679382f04fb4f95c3f79c138039 +SHAKE-128: 017dc84e802a7921ab5e4f25fe620f1c166afa0a0c28ed2e92ef0d98bf8118a2e3024a9c67cced51ddbf243da84dfd4c912b2bc78a2f0179c5aa16777f5049097dd93862d0491409f0bcf13b544af28778a3458fc4d748cd5a969c60d9932b0731ad808556a56162d07fa9afbc7279d8b27990ee8dfd19437da66e2de145cc1a8f78bc49e49f2460b2b80e173ace079203e84d991f39c9f2d1067f2d26072d3d538de5c5f022f18a007cce18b48d944dc8701b63ffd4ca5eced6e1dc3b7ebc33003035faa05a72bba1b20afa27d2d607619d692156e0e394edf6de120f3df7ccb38dc58e565de8220f7caf49b9983a62172a78ab31d317a2a22a53e6fcecd32e900d88af44d43ffbb7e8084e73d8afe6c7d527d706f4f8677870f92a91ace791c16405f98ac6a974b0589a377933ea8efef9b1c897191f8fff39a5c877e25b155cae39fcdc9732c32e67932e46bb11bd71942c7fb326f7e756943327645da8ad22dde91e9d397a5e3f42e0ee710c2b5b3d7d01aafffbe689e4c2e4925eb66543742a11e8e79d7fd128313bd02daba45074acc5088aa60bb5482ca57ed9af5a9b5bb40f8889edaf2a52341b965ce6793f4d87da1016c304da98dc769aace3fc7b1ccdfbb2e76c2800d42f1d9cbda1f944a183d25b8340132361620e50c848b268c015b1d43a85100f1b448308d34e647c91893a0049779bc4f3d5d05fcae3630a +SHAKE-256: d69a619cb21f01fd900efc0890fdcac0e2509ae1843a68ffc33d724e143f648989d139d5cc69cd4f753e8a5bf7c92b4a73762f1e054c4ddd3a5ce0cbb1263f63e9f835f59b33931cc7570873e332037f755a24d8d398206b3cfa007854a555d6a83006891b46b96720ee4aa1e6a8e805a2e7662a4d3f49609f05ca40e21ad8163ee2bf6ff6e317d8afff19463e999a20397b5e9ce728dc5061d79c336ce5bc4428d656c417470c388374d17aabc34c686c954c80c9c04b4d69b66b8c19e292a1cb5124cdaebb8d5e4faa05b08e4c4c0a86bd1ebb9977b57be22b1b9c50afbee96a284ac02fed354832ef77dd2f664b1669aa8d0ffe7835249331a3a1139049b609997c4258cab0dc82d88a3744213ff6d667ecb26769acedaab1098537d040ed32b37457f7540bee59fec5befdd192c7250de2fc4465dda267de48719eb9c27779d0b56972a157b95c1be15c22ef46eee607baa97035646d8ff7ad3bbe4245eee457ec74518a343d1cb45e471a0925607d12a2e6158bc8a7632d6ac6aa0c2067b1488d414f75ebaaffd6c63ba667ccd8a710bfb6172bbbd0021166c0e831cb703d574bd60f507956b1bf62cde153fb6710155ac2a304f7df20fb17983a558fd960db1fbd1485c3ff802468ba6db3d06e5244a219b72934082885f566c59b273e039dc925ec103fc04052bc0c643d94f4569322a09c6259bfb51b8eb9c7d2e1c6 + +Input: 2cac1abf6c76a7e3450fadd914e6f52a97a2de95d01bb708f9cf6b821dc642e031e38b019cadaccc92955563f9e9720f57785b3ed7d8ae80bb629abf1a83b4c69ad1f77acbed9b248bc1166bed38d5e33fd834aa32a0f9889c31e07a4d8cbbfd1c537317497b3c86006841e179685d49a5d692e9ebf0bc9fceac563b735f8cfc0a73fde96810cca92845def17ed59da35b11fdf2e0366b09e228d64b98d1b726a14c5c5806676f5d4039ea5e47004a26d862e1fdbc9bd8bec58b682b274f9819c443f72dd213acb4cd2d1e9b8305481f86e173090ef922ba2e7ff42f8c52faa97f67ef1b13f7006e92ad0b233b82ae39d9af3c01e117119edafe6a3253f4474281 +SHA3-256: 14764f8bde01e3f03004e2bae672d44ebb1d88fd722ed8b9da8952ee790bd860 +SHA3-512: 7ea1680988ff41ff8d7c0523883525bca467f139c213c9da4098f30dc4fbd558bd9a90ee4eef42c669a9bbb109d3b6d0b09abb3353e4cd9c7794f88d4e232386 +SHAKE-128: 87ce49eae21ee9843e34779b739effa4a685a599b9e1144c6b02a725e497ec2173fcf043dac731b7d15b971c471bbf69965959e164c83016594067983567042afcdc7eeef3440a6ca8412dc9e8eba1a59587879a4e47fe7ffe5d232290d990db639cd4247699137ce9dae8e531c4cb859463b92942e69c2b60efe7922ed288614e024473baf81473959d5b8b1b04b7b77b3d2c5342f43768332da54e586acc765714e6c68034d559fde7ca60eca31a39a397bc47eca2004a08059b8a8194297f40544feee115d282366bbe6ee3de859be6d98041d3d50471a0b74fd8da152af5fdf7ce100a42fb38e23a93c802009d3951cb0c97857b5ec5adac967f4f5175b84b4314e04f4e03a0a09ff0508bf19accfe2ce03abe0f4cc8a89c519a84886f574f770115010f4a6dadc63fd8bf590e4fa4e75a0aaa60d836681e1c2ac2b5e3f411a3dcca70e4c21dcb606e9d62acb0603334b2a0a619f177f20cc48f0fd4d215786e35724a84fd9af85dfa6e21f2ba41b5decf58e42d476e7eceaa5ad3c1a7455f01df614d38c1ce68dad0172b88d696aeca8748eac16b27ff4681d9d867758579a83e2df2a0ed3b17405c61e30f80cdbdc445c6e84f5738820bb99e5683e1aec5f84043854568829a6a0d65d28a0d53c398ad1ff45cdf6e7f6d5c6782c124be1eb1216189799681f154606a6d182323e94384702fa95a5fa9f84bf1e9dd8556 +SHAKE-256: 50861d074d5c375937bda7b0cfcdb63d2cfe3feb0a48fe463ac45699ae9c0dd0c843394cac4e63cae1f8fe86fcb3f8e42c69d49af6e854f91e57f7004fa1a39e05b5429b0bc219765b0d0f5105b95babf3bbb4382b1fe2e9969841150b791e02877827c9ebd833ee8050ab5098a9b7ac62f9f1b5921285dc1aa6d237c3dbea7259b972f5eba5ed6f0d399066b6eca67cbe66493cfebdb6deaed459e546554dc783d3f1c68dc5303bf2d96020b2f2db9217756ecbc53670e7b704c5717525e3890e7cd3baeb508ff3ee5a36ba2574ea7831927395cfb4680632026f7c1bf41c29b9ca3b03b983f48ada3f4a251c64304742f2a868ed0c081dcde6d227e62a6456ddfc3b13def5d4d2b9dae596c5b08ca11db82dc51c69054d78a2bc6ccff5070442127b6bed1c4799e0324f2f0272e9f50e698e73de70a7f65bd3845c6f77718853d6c095254d2f1529894f7c10582156fa7cfedf5320d4cd06423aef0a397fea5a2bec0db12cfbc3ee431614ad40a4382bd9fe98d49ea0e6bd5c2de9fc3e40e9201615b59cebedf3aa8f325f1b43d2af859ca9f3d90d09f0824eca37b8519033ed55f34407b6d5b12639818c98f1d488e917ba5c6958496db22eae39b7d32004f5afbf7bf2a32bd117c64d324b8437fc724f2c51086386972fe3769089eeaf6025fc10186425f1b56db0961d6275e09880f4b6270e8dcd210fe3040850549d03 + +Input: 372e38b1bfe43597a45b5ecfaa290b7d699112f0a7c7b6a6da75f4c6cf36e28b500a835e9ef3f1d1a37e45f1bcf2ea9458de4cf1e8241a39d5dde527fcb3bd6100f8effa6970ea6369cc07afa21a18dd21cbbfe096b1260187d062d4c7bef630fc3a0d23a485df7c244d3d20aaa9d60713e25ca30edaea1650b715de51cd6378b4d1197085c0d3563ce880c0acffcfb26ca79a3d3ee8eab4d759e3cbf2b791c096b8a222eee30e109904e1ac0e503bf81cfe1cfb6dea2bd5de9ec73746b45e39623659a02842b0e434fce12aa9f031aeaa478dab30946c4550cabd3232b0529173eb9cbcbecb261233b420fd24c0bd7c24923e14263c0cbcc392c7cbe326b6587c95 +SHA3-256: 7f372aac3ae216bcd2a4fad5ae7bc83f23c031bb5308dd5babcbede1e885a9db +SHA3-512: ae1da5eb3a351c42e8e00237374afa065a1aa5e3507b283c88c366969253b1839d28bb19ea6ef76474250f594a5ada641ac8ca4f3dc619cf304b454187aa5487 +SHAKE-128: 1435eb767d0ffde116e111741fb9af48e6e847fe8c5b95639f7f5881937c6bdf1a9483f7f32f95cee3e1cb73a8c3f0e38c81e3cc6a0e34279fda784f7bac2bbe0c1f652c5b6e9da138c4a318dbb3e02ca09fce6b394eeb4232694af4b169fe983802d75e5b2b59e6bc606cd15643a85cceaae5184af607dadc7b82374090941a9df5f4adfcaf321b7a6191871841d6a974da68f18bf8f3af265ac35579c606c619c1df502ad978f229e53dd092cc3a6e5dff9df191f3735ba493966e3c7b5a1b81af45f51e97deed96336b39f9881801ee89c0802ab5a9808598695f64d94cebc4db9e022005636dcbefc274105bda301b14056a12deceb75ed0e1c8acf9945950d205cb0c82f234829e53e96ad7cbc4dfd199fcef21ed333ab26774ac9fa83143b741569b5c664c4af4322f8fadab866d21dc4f0fb4741b45d7c4752a56832377a53c245a6857495cd396901218cc22781e72245feefe2084e77111532c1d0a2ee02a7399e77fcf3d20b68c796a650d1f3b3bde693d4e10e1f4be19dda99048fe06f41adafde18878220d74ab7cc4c4c9c1f79454340f4417d81e064f378037b9075427f53e40395cb1ca879e829b7e24bad9ab3be66a505494423f956611d7ac42969fa1196204fae1598d46dc52472a6c7efdafd948d60fbbc44ca793f0138b0351b4a14d3b410bdc9e9a32cc7f44fb3b5ac62b760e65307f8c6b303d19f9 +SHAKE-256: 6ff5891efd350de99e5fedb237a718d1d4e5d5bb2ff0b75de1bef60a91145ad9d3069b9eb2b0e0df058d5b18bd80a1f55763bd30b1fa06e4fc4147b7862427680ccdde7b45d66323dde0bd3372532d4ee08d0add32d73394dedf8e5b7be358e85fd1549c7bd68be27bd365369bacfe69c85bc7ec50f6abbcf1cc52610b715e9cfefe14e6bae138750acd176dc61da6599518e9caf530f52c4da2859b1ef2b4f08c67ebf44ccdc884fcb0bad23ce790344f1935ff9bc49441803bf2b3404c1029fd7497ac0c3ffe11307cf5c565ae218ce383128ff0318edbc96a4dd4fdd03164bd4caf43e29afb254b2e1c16850dd7511bc4b845fc2149ded1935f2e262ef3b4f4f451f3e94ab94a4c2ccd12ce50651e4f20ca854164d28cba30a9291c29d28ebb728115775e103c1403518c78167ca54c9cf9c492dea414decd1d610a605adff7fc80f34376c1dd5e71250b6150c5f961f8008c0d764f87d9b2278fc081a3390ad07766bee11c867606b5eca91aaef192c525987abfffa45c7b14d48cd5c36a6573a181c7b33412deb9327d994d604726e9cf8ae5a0708591c86e9481d95358f232a166419fb28dcfe2e94dba3efe926ac122ac423a05229aa5d0bd06b67143533457fdaffd643473ec5184d09b273eaf2480dcdf3b594ee0ba11832d69d1e003101b25ac58e58c0c592ac023228541607f213af18517ed4ab62f0de796f9ca + +Input: b64032bccc18e4778b836f9925d83f96c6e9ff00f7ea1d48a356010ebaeb1080ae628e2fccab9b0ae65fb3c096896cd8e48c9cfb1693a2410fad9e08b8757411f0a186178baead3bb25dc26cbced479d2dbc57e963258ac60106e00062ccb596a3ac38c574aace0331f5bd342194ed3422f01b7ae14ccee79a74ce8c836dd38d44602ba8bdc7172e705400ff68cb0c16daaf8613eaf45fca09f7c43a830898e24523bc72fe4bc3518083fc5239388433e9a880f1ff813491634dc024a72cfaf03921b03db8e8e24c11c4b2cd0fc8756cb61b337826619a9c55adf8ab925ea51f014ddbf968cbbc4a6bea8b278cdaad6dce2aeebdae5c3e364cea8ade2c8eb201b1ef1d +SHA3-256: 537cdd7fb96636ece72a599024deb36607b0964a47053ba68d34e7e4f4d41da7 +SHA3-512: 0f0f54f8b5e82d8cbd93bb6ed419300657cfa2bf41a5c1bf4757739df0e2371e1f69563474cb66603558fe55d5d923aa98b05f9ed48d8ac6bc1550bddba21608 +SHAKE-128: 4793ea2b020f54fd4e6d132ac229fc81934e5f615c522ee6c6815a093b6cb756fa3b945a79b8f2ed76f318e029f1e2159257c504749c84696504c0386c0f3a2a97675fc9083338d1e1ca377e1db74718f3a609f472896f83e321d7407aa675a762e7043456bf2a6c0728e2ca9e81946338b1b53ac9f6dd44c24894b6462842be2f8d892b24758ad4fcef8eef4eda27424f76e9a7ba46b4f269c703088bfd6892353dc9b6eb26ab62dd8a226c86bd2a96a5d9bd660ccea0de506c8e84ffccf797db27b22d2086926667c69eeac3051cd4b19edd1454bca98eda48208f390119d69bbd8fcc93195fcc97a1619bca3a01b18e7e56198e9fcf77ec211d45d5f97a3642c1860ff6620954f2c1edfd48ff9676364834c33d843b404e6b4c38e9d82b0c19130a54d19d701e298fbb498c2df341a5b4acfb6fece92fd77c7f19633add19f3e2abef828a91fbf19d663ca76719daa466d44bf6077fa888b7623c739d715f8ee260eff698edf2bd51058b315e68c5e7710c5ca6931e11cb7bf29fb29b8325fc60d265ab05e68597f62679e4f48757f8407f18b57f6451a1f00f49228a335301da4f939a3c26005db2a80c00068dc7db20cce1e9ce31239163c6c8125d4bd2f7a49a3cc88fd628be4f720ec80837f380a188c911f19be69a25b5dd188d0df1e21d73d0bd38c2e649d76d6806ffb633fe165691f2f64861ba5ae63fc9a73777 +SHAKE-256: 11336a7e6657409ef191555b7feafc4c09ef34ecc4155500a19809362ff0a265ce7f7fa92147bfebfbacd4aef86c80ea64c32f165759b9271dbf85b6e0dedd3d4dfcdf9ac7f060f5bbffaa06a7306608e8703b21338a386b23a556daf150112d75143804a9ac129c55f1780a228cac0d5fd522d074d362d53e4b80bcadcd045b934a8f950ffc0e9b0495a540c9ea853c69877aac60d740242be1412473d271b59e5e295816034ab133a4cb36b5a2b78cd227ef3914ceed0acbc86f8a806eb94050ea177eb280796f84c8f03a3e09cea625edd2267c8238f03937d71267e1279c7eea9aa43fe0e9b59732a26ae1ab1db2d7697fa8c30baa13774407de8a3b708c6f15d995623969ce684e2ef109e6864b53d6c0790dfffc1f7678cebe749c4afeeaf35d9419816e892479b32fca9a3c70fc0c5b5881ea35df79669683b19d64fd0cb6cdd7bc8ef2c9d1d71675bc8b5aaba6f4cd2892cc393583b26f16380abcd1e6ee3863d44b00994e459bab128b08e9940787242840c2bcbc0590da09c6bf001ec4943470b8f5bf808cf6504fddd0bd3b18b0f53c66035940dedf81ac5fe7bb472bf1448a1a6d81f89c90bab567f01c07c6d9143b20692412053f51d6c59c9f9ce1c5eafd031e061bc91d579cba76523d6eda947b31fb86dc12116b9ec0a6eb5e8e85f632e5895a3e9cb0c61be67c24ae113d23b706091dae1d1becdb4fad95 + +Input: f97714080ea30c7afbca0dc407110c2748cc16f55e8046dc98c3e0b683049141f541d223f3ba53f1bd566bc583f338625f449769f582eb705e754016f1a09397458982951ca67d55312647d0dbda6e30de43c66aba4d7d67ffcba1b9cabaae8eb853c43046c740ba6c2bec18b41fcab944c10e434e913714e3dab11a993733d85a6ea60a4c1821decd84ffe953224ef5a3f9f7e1ca46254e6b1bde25adebb6b11d564b8c3a06b22a317340380e2e7bb14682608dcb7f2a65033af4fa6e0687600bd608dc270cf6b6d5bbb70bf57f298aa833947476b68f7873363e342620ec2ac419da6d5272c0cc7ade9aeeded2837bd851d7c89c63bbfeb35a43ff9db6b86912e5f510 +SHA3-256: d32656bd369c791d043f53633885bff8ea2d12f2b6061f7fd9b5f263541527fa +SHA3-512: b63a1c499396a86b55b030de972fb6f0cd8e1aa354dd31a7d4848cd9b092576244fe5d317e2ecbbd2a5ee59a51a7623a5ae7d1d8e89be3acfe68e298e4edbc65 +SHAKE-128: cdb8e6b07a17804a36b18bffe1ebaf30359033d8fdf0ef71a16ad2b68f89a7291b6116b7e8bcad5513f1228e2543f5992ae4aa51f4fbe9534f0bccd8dad0520e9a05c7ef6cfadf8b9af7ef3f046e026a0fdc27da387c1f93d3f6e46083879ad08e550085f9b3faa74fa95aaa55499732c85952a972f102a62aff0e534de1cebbf828d357b8af0d5de0fbb6f84eeff42d7ec579a92714b7c5cf7a34486e98f24e54b2e5554718eba33ae517728f0d6cf48908a7d7bd0c4af9190f102bc6d56e3a4fd0d52e5d88f091963338f5412c07fb1df31b25646e8e0f84870744108b300cee3360ecccf657f7a8ee1d1472167aa191208c377b779947cc94847432f8c8fc1f64f5aa845ed65c132e5aca6ca5b705b15f97ea430091358a76a38249d9622c59cf3396e0b7fcbdf5687e5d8e66a4a76365bf1ce61a26cc9f6ba450876c0a608004bf5698371179d374f42eec3dc81542389070e8b78f91fe46c4192b355e6f858ae2d62a639b5c44c123d4703ebc4d2c3b0c36ba0ec7847954ef120cbc6429d561280e95b242cfb30e3bbf082c2c2ea5ca3d859a43d51194a566255a6f89301a79c285f592ffb04d163a09943c202d8bd1abbe81e6b77e90edf2c1fd3a195380d00fca26d04649e341737cdf31a0abe444258d03a632624b881de45d2fb88b3cc63b1317d61bf7bca7cfc5ccbe3b05d46e8b09876d38ce293494cbb96408c7 +SHAKE-256: dc836a3e48b065ef9f86a4ed6b6a09d975d399dbd9a195000bfb4b97c1d4f0e70251ecc69259b22303dba9d967a903085dba660efb6ec5ec925e57fb6156fbb34e89bbc6f61cf20ce3a091f8aa2541b36038e672b785b0d5db2091b42a3d9c6e211a5b9b9645245f16b3898b80da3bb441f04c3a9247c58c9af6f390dc042eb2e58830b0ffffe12b399b7c9b1d5c77ee0404c43d43be71f8dc6f586fba7aa90c0d2773b99eb4ca61baad1771c3f9984a1224e4f2974013751396f5cd9367d3fe14c2aed6bcf54ec2de36281b043c4c75819f4cd0de3991050e3c7fd546f359ea139fe1e615bd516450a6f9ba694fd2a906bb9679f872bc413a725e68552859ae56fb091734b5f5dbf9a1f30e470fd1e16c5b37767cc39c00df0dd6fb1d118ff94a84f4b66a7cd22b658149e26c4cb8c71b382296776771d30118ed1d3943ac3fd6c2b6026a0eb06869d666cabf0b225117d38d470d5bac7d1fa8ac00610ae2e8983945c0c7b1db4dd9715d26a0b040a7924840b14b569f5a8093ddd4008a077f7def482f7044d4fdc505622c8c236a5accfd300756ba25a865ccd2d5c6c746b1894f4fe71190698168b39b31ba52d36598722580479f4271d37b06c1148f7c7744de0710098d2627b411e4491dd7e5c63bc06851187711cb1a298710d1a993e42e21c6d791c4cdd298635aa3b78576e5fe80fa9f11303f7560a1b3ee104755fb + +Input: 860b94ae766975e4e2021bf79d312862f657a91b718a2a73e3131d289a0264f5c0c781c0d49268f91d65301e558f5d90af55e2b4f1f9dc6cc9aeb2dafd7c1b576a5352816540350a2ddce7c7486c2cfbd55a37846711d91a3e341638f535593fc50aa4543df7d12dbcdd5fb2ce31a829ff66c11096ad9e43bc32700f7d3bebbb100c41ea38bc9d729d0717fa09f23b1a37867cd1a50ebca36947d552f3e1c0a9e4cf56989b46866336727ce1bbe7ad206e49157bfeaa8a45cf0df032bbe2fb3a6dc43381dd8f70a0b700fae4472252642610f5765ca864474d6211081446946e57244d25ea4287622d0fe698fb3a2d26093d333a59dc2e05ca827c7342e565232dc2b0f677 +SHA3-256: 679d204c34d48a235f50173336b3c04529128927cf736579c9e66495a103d666 +SHA3-512: b51b8977882e708b58a655afbaefdca9426d9d2d080490b79b7863e2c9c48cb362d63f3624d38371e381658d04b6351d08a67139431961a277044cf3c19508d4 +SHAKE-128: c27b9a9c98f3cb2117aea392026cdd78cd77ce56912b474a6eb963703112f2f8d3fdaba277952c9bea4aa834d2b3489b8bec81149035c3b87e4ee11b3b99fb9d251acb079ecd306005140a5f3bb393f364be252e717e6b7c3191d0e550d6c255b037f42bd2bc8036786a5977ef53058dacc14ce83938d07259dbc6c585f80a69de5b4f0ced20f17d1f0d8fe5715c2192afaf5be37809dd456f8c47bc8cc7de9d62779404a047bac8dc60beb7f5c09a53de5e623c5bc124a77e64eec1d6309a444f72e4d662bfd2f82c47f88514ae8a8d7ce9d78eba16b48256bcb9b07700458e48c0d35fc4b864c5f2871ff2f7242c63db0f8c4a58ff2314b49b5a0c68e3a868b4d3011aa2c0f46858a8f78b3e5e9c6cb24582f74949884f92c72afc4895e5c05982d067150268ebf01a9905bf7ae373cad050eaf89f462c790ef13bc80fc622a3245493f5fb09dddd3fab9ccf8bbbfe4d61dacb23b67b8c92715d0971dcaf885604de100ff3af5ba4d204576e784c57c423e434d2e5e26f30e14e9d456cd74d26083c37382249ca363e4a496152db430de29c873b8ef8cb267e80eb5ad09645732dededde8f261f68fb6ddbe6a5d212051bcfeb75c116e15accbec86528977ffcc629d4f388d69ccb1e5b24021d2530b983c0290f18223afe8426a039906165933121d39bcda9cd1aef578b5ee0d9611f7be2ce2f6afe260f7986c1a7a9814d +SHAKE-256: 8b0cef8360d30689d77bc874e903ad2be47a6dae4f51bf0efecb41eaf44c48fcb2977c3ba7867358685d57bd3858ef2acf760e73a5e04b306ff1b8a80030985d4ec5725e9ab55b8d75d5877c6b882b2f8552a5a2eecdad5d1ffe5486777870a902c57b3b3d6de658c439d5368aaaec49d774ffd9e139caacdda9c99cfbf6ba12739a0cedf02650de2baa9268e818767e47c8b9d6aaddcc4e207d7cfb5dd1365c0aede37f9239790175126261a6bac7b149ceb64e02c3f96011e2330d37ffd2c6a767d548b7f6e5aa6c10e2c5d8422ce3afff13fede3986e61f764dd986ec884b1cfa68d34ecd727c8d9ce04c809b559f94c3db19ce3df274903ad8e5d4c8e23c25d2fd42f6a6a5882bf6b915805566e61e2ec786242add8876ef081cd58ea732e3cd9d94815527c099708826114a8976e65ac5f6a009780b926bd937d950968a5052f351a0913a21e6bfebc65e6e62f7b97059b787a5150a19569c30ae6125ccfd2f21178e6cbef9f8244fed1aa8697edd104a8e0fd9340915ca0c67b2d001533858b384da324fcc711c558dead233b02ceadf4a9e8b8d6d1fc9da00904123db64c667faf8864edfed0dbdf1452fd471dc17ef5866097c7630ad1aa1be680a9aa722e2ab42d7be2b8cecb4a89009486d2ac6164068797b2369e593653284216911dbf270e1adaca7e9104f6bba02e9d79f932f1cb666c395866c8bd2666deb78 + +Input: ecc4fca85d6ae5f6bdbe2e411f0964fb143209726445ef2df21ab4b0644abe4a6d6bfbcaa765b547f70fd5c370706711df64243232e63a680c9176034d1375988e0c139df06c1a4d1174e36c6c9f6e837bbd4903683d41e298645c88d6c406619514736d73d8fba7f171780aaafb5c1f6d6340fdb341a8fa15afb95da511c88c63622628b373c882f45fb7ec8c5d0640bfdd609ef6f0fe2769656c07b289e22cca6326879742fe68ef6b781f1aef435a805f2a4912810d57803c4bb78d239e82ef52def50a86605185a85c668c533095254d7c156dd32a6c7d40b440df46afb30a395aa60ac634a18264f742c194006defa4bba52321d28b28527817d2baccc3dee13db0806e +SHA3-256: 6e624080602612de7a5802939448416871eb39399beedf01998d696c38af16a9 +SHA3-512: 404190b936d6ab530f63a61c5dcce09990134c0f5cb89dbea7e2b5775da0170f686e7928b4c77843f6a1a015d5b228015c95ea41c539d61b7b8069ed745a88a6 +SHAKE-128: 99a1fbb0b208f1db63ccf3b312a74f472592424f35dad8af2384e47ef2763639bcb2fd692f5857598b36f6d5df8325a066a3998e444a45123d0c740823dbc987c1573c62a5aad1a8724d248a1cea893e6b70929b23c7d1c1089ec9a6af13264f9bc921c274ec2183a9c5f564ee0fe36b6fdfa6760d06659e54d1f07c58c50b746ecfdfd26de12d590f5c34326362c79909d09a21765df6d1bb1b5fd8924031f9035bbaec88a29c446fc148b2bf0949c425b69d565333577343aef2854399e48d7dd97897bbd8173dc30d4e630a2c6e7b5d12df5cef1909301b9744692898431ae7d4b8c1f65d7cb771614e9e12e392e50dd9e41f730f271bcdf5918e487ed6a2630e0fce0cb68943f63621f254e7d8e901fc75ded54d92616161cc4dc24520f38bb9fac314d99ff6577c8b979388d197ed5c9b2989cb9108cd4159c12007c10a11787008e0e25d51fcd1f5712f875079c7a03af3593b97e7b919cb7f63102a9fb47bd3959a182041a97b4ff6a08d4632060ae6a3497c537af27527bf82797d42e8f4bfc995de5035c2583b1c8aa9ee1ad6d17fae1a8e9962b2cd12a05d0f8613ac710abe6f369ae15f7aa1db66acb4f6f22dda5076fcaac7f90a9b9b9f33b75a412974df359af73a7534004f2e9e3b1f9702cd96931b144f93b93efdacea9f8d13b09a1b982d74e2f4e720e18fafe3681b7934dd26a2000d0ac1eb5f7250f437 +SHAKE-256: d43c9b6aacff1221a97e3a6a12ef2de2c03cd827385ddb0eaff3278c659f5d45f57d68a7f37cf9d3d6d0037a3814ff1b58479141636a15fa58be794047ad0ce1266d2f3028f979384ad14dc2c2d54ff37fed0c6381cd31d4330f3f1aea362e8ddebb376d1adf1d3d73ba772a594d21b4e960d103e6dc2b36b468855c683db0a2762b1daf73f0a82920eeeaff3af4acdec41f6b131b7376ce432b2227b351e4673d2563ddde8d778897dc25f9bd1eed68c407f913168e0853c22a3e3aef3a64a58b34119b0d847d76e88df6efc530884e143b97ed4cc0d2f725760b9226223008c53aebfc7f865a88da69be3b7f52d1ddc914908e54cb19e41064fbe6a41f46900eb2545de6e88b44ecc62fc87fe6e8aa1a9fb927c5053d73b7489da48672ae0cdbc0c8d741881c3b477937d9f7260028a23cc2db5f5363dae3410f2d337a60044e17a40689fde2ea30d0e67faaed2b50b402f05fb09c4287b799d0b002e2108ff7909900fc7ff141a0c67b20110f77822ffe5d433d60fdeff5a12350b346696dd482757090b106d2d2d8394ea74031b95275a333773d1c7081a99f2c6e58c986412921a44742ebba8983425155e46c5e0ff13485743b12d1b54772b177a21f5a63b0478d8a3fedf314e939ec97e322aa34f62f85d5ed6006d4fcc0adc94e5ab918f593d5e585636db3e65e65f579355fa87758f672b4c381e1d8149cd314bc45 + +Input: ea3abd219495e92ccf6cd69d87b07c67413510c19ec7f2f73f758db43481889160d66abf22b4640fb3d2b992bba945e7da20cc40e8f3f91de66327403a7d6af2c2e3db5f79c4918e9b7c48d772733ab0df94720b03233b367911df37ac43d63289891db8493a2f60ae69de9ecb226a58e3c9c2b2d433b7712ad4c17f0907f1fd1cb22cd8f961c6b7e82df2ae015226f1ef618958b789904f6e99e1c4e783ef3dd836cf6bece8f1a36fcdd0033716ff4049a6b457157eab9dfdae074724978f2a8af40ecafe399c4ddc7a2a9f3301cf554d5cff2e84af074c8c4e4a0508139a6fc71ce5124f375127abb21de9bbe9ca795a8fe5e1df19170d5b049359a4be663c53c31f17809104 +SHA3-256: dddbe45be0dea9e93e5c1a17730146786ac63fe32fc89dbf90cf18ad3e88ce06 +SHA3-512: cd985dadf6842700b8e504e021e4f366d2ae71afdd60b0f1660d6602b47450dfcc517d666c8f438f1e4292fe8449dec3ec46e28a99a315782535d0ce38c3d47e +SHAKE-128: 022b80a570ba8be5d3693c8487a318083b5fd44c775e74172dcaa3d9db38dc86c7f7d2bac24adceb87fb831ef61b1ba93cdd1699807d3a923d937108acfa42265d935804bf10707c7c543bca94d98854f8ad05edaa8a5bbfa5562ddba3cd41ba6f57ab438d4c5967bbd8bd0ec0152c36d8bd0d40d3c9488bc9a77f9b928d3fa560f7abc8be7b7d48a53df8da0157ed51ce13727eb2f0de1c2093819eedba9f85b2289833ce7f737dff0093aab8cdf5c79d77a526693419a5bb431d60bcbadb833379ec1c9c9b10f1e4027bf479f128069e5f1c2e048e773e458039f9091051eb9347cf89b2adb7d965fcd9d433dc7e19c8d559f3c61502d98d9b211fcbb045d536892918b9a535765420dc554ee6e009d3fc0783a24d22fd65cba8805f9bf42572efc871f7051a2f3e576dd46bda87a126bc50b1a2030ccb1238290f259a9e52227c931ceb3c30402e330a12972da384f0505955d30d10714d35d59e2eb6590911ac9e9b4d42519ccc253cb15b445547f6112d734f2c3d7bbc4d95472fda503d84bd3951b2b22943ca7a5b0ccddc67d79dbfcda61a3c2e7636c333d50a40ca0ddc3358f896700b352a4c0003c2a4c17a13ebe9d6c517cc38e40b6743f8a98b0a4e4af51117d3a38b727505d688098e95a45cfb6eab878569d2b5e0a64670f1b580b6bed3cee9d59ececd65ac51838b79d7bcc1f9edd61d70939eb68609ce5b97 +SHAKE-256: 6d5ace1d431e06c8b9881fe5da99ecf08233bbaf7b5e6574b481eaa0c95906b4c346869e2f824854fa1ac7904dbe9d29833188acc4d1f6417f2431ee66b8523f7ab6f4f6f635af061aa95425a04abb43b930d28afe5231675fdc8d30c904e30ee7e747987e033d0d47babd6ffd628ec3f2475003428e31db37ea528fa530ebeb261fdb97bd5bc3f04d4e26a96b675849045a48189314edbfecc3f7fff325c0cb8fa11a9a530b85eabffcc4c1673e5e0ed31e27c1ba3a58a2c6666cd8321d9e59014d6551d381da4ffd6f04d26fd950cb9500bebd5cc89408cbe6a2386e79906875b7f9006acc7e655d5b5b8057e7df427ad467deb56264d40e1962aa1389cb2362efa2027930767fa02686aaac08b69a3d98a88673da188929ab2dfcc0601ecf77e04043e7bfc5f453a3ed2b304740e36fbad84b8969242bcbf8a155a68afba2a72d1266f8f4c42f248d3cf91b3235c6831adc473529c6d7a06d097bfa05ed38237bf896bafe060a089a4583429f7147c12e6b5952cfff3256c332310ac520bf78603efadd5bdadcd2497d30ac2b2891d10843840881a7a0d4aded692710ac242e20b8ab4e031113654d0cde8dd3fdd97902fba1017d9ed0adb5a34439830968e9af7c199af54358aabe0ce99ee58de9194a1f2d2bb2c1a8c6ecdcae0ea14874702e79b13dd26feb9ecd4a94624876b7c2bf0edc30ba1fda8c4889637d870138 + +Input: 3e0453d46201d0530ecd4132f04d72e17976bbd7cb28c4f95fb59d5160fbe71d9ca146631f230d0193e5ad11214d5a1e806ea19afa74fa42b9991b3dab38c64e30cc91bb2ff14fcfc8d84038534f3b33496dac0001e673ca73b6d99de69734ccbde5ce13ac201084948db5b4aea01bd835067c4a6cf08ed6611a6c97180eda5244f738d2ca18ed3e10c2ca2895127301666e53928b68a521f336dc0709433cca9f471f3b82a1a72f6ebde86f057d1dedcb8d67ff334bed59b320858dc3fa9e95f7abb18a50eec6d8b1a20dd1369b9d3ba969163bf4879f3933ad185e687c1fb004c5532ebf8b8375ccba949dadc6796ae5fb0c7b97672d32bb64954d46840604cd76294138421868 +SHA3-256: 8af8afd04bbde31fca8c2f0a885a463363d50f578a4f589cc91997b4b2755d74 +SHA3-512: 863f1dcefe4aebaf65bce38a8f2b67ce41ae6ed391a0860c952b458311b64346d944810d7bf694c577ad888e21ef5c1e5ea122030a465b129fc5597fb8054bda +SHAKE-128: 2b44dbbeda1344b28fb2929c2dff8972283ea15c3f4428fbc3b8c4b6acd30d6e1a3f50701ed132cd111f51e5e7816919708505366b2065cc5e509bffe42c4b6b7de4878c5a897f08b3092ee754a537eb2874ea16b881e7202192b42b95a09299bdd49c0a63d711341cbecab39b76a68e35e1f4d15499be370ef46fa9957be5c5dae88ac05f5652140c77ba6303767834c02eed401868fafc5dee7544bd60bd2615e415668100c84d0f65d69adeafc9f360793eb5d959091b750f76ff678ba35e1fe3198ad06bdb055744fbf60070c9da32022c939a43b104b19af6e80909500f34bbeef18ade683b0eb84ffa683728cc9886fc91eb8ec9049aea84944f4044eba4957eddad1ce201e5df78259a987aa74df0dd56166bf0115d15619d5fbbaf1a220372d031fed4d03de366d5b27d5d123ef90c7af9fb7d1e93a52fed8bb841da570ddd6578786e8248b02139f5a7675b82ccd6e7769991264e1d3daa82e7e294746bdb7dcb9518119a6312efedf51ca1eab17053eb4bdb90de326768449ec4891a87c3cbf4fd82a5b8bb940c108fbf66e874627e1ab9d275aa76c77f294a23f1eb3dabf9e9ab0a4c9f5024eb745845a5a824bfc534db97da4633f6f5445157a720d10c505d23c54c35c268c3e4453e12dad27d6428dfeedbe8825805359004a83fc972cf5e6a38e3c29002e747f65c77640f1480ea1c04af6dd05ae0c863d2b2 +SHAKE-256: 299cb0887b20324eb9ce6589899d81e4f4086f73c563d9a4eae5bc4f05202678b970b3916c65dc2f04f8e47dd5fe33c0c4395b1c15a92b1ebd3dc06a7c8117cbaf05a3d609a368c82e9128ea571c2db826b1e36038179923e7358cebdde430d58f3a43b54b881ae3da85480ef55f224ac35a848fda0b6224d51cb776cfa69235cf8a7f712897e51199e910d46fe32acb339b5d3f6fe1e9649ea235be8531d612129f2b9323d8bb775484aa7e312d6cbce781e0f183686e0df3477846ed5bf3e0d5a16626080f7152896a33ba935bc6142090c225cd325078c0e3a7d13ecbbe28434068a1b24336a7c80e12ed0080b9377d36a08d9f117ad1f38ca56e0aedf14b7f22f4154e6fb7e6d0f4898dc54e6deb6392f889b716effb663c8abe4b2abcd4139509060201901a2ff35f42de38942f5ea7f70dd39eea8a641afd3fc678d3204c594f17c411ea80847f2d3493fc7afc382b3c89f466e6e7b75b6fee482d62be054811babc56a8e524f144c48a50f3ffd6437644d621e7850946a2ec2ac5b7d71b91c6e96b498186c80e2e0535adc4793d493f7ae857747174777552604adb4246a1d0f7a52cf2174a0ab8bebc37ae12eee67384c72ec6b6bdeaf6c85f850029e4165111c572792abcd5f1711f8b219c9dcbf4679af2d25cebb1ac3418c15a3521eee3c221f6b58e15af00079347d00ba1bea06674f5b2a0d99848d60fdb6c3d + +Input: 2280b52c769b3b0f66f7c8f8f8a042a2939ab120bfe2cb64b7e92c39683acbaa3089e3969e508696690400f2bfe874755e6a93c7d0896316949503c6b91524b4234f77ff24091aa72951bf087684678894417acc0f04be79f891ae73aa2b709dd95ca11897d420a0d3ca403522798f27a5ba246c5747293ece752fd360a86a0df0cefc0c51e9b4af95fdd939eb6d1fe0d1792a40f8d6fe5312d6e46bb388521966b44e3d93adb43abac0b4c8b572413bce1bad3e6c75aa61828d479ebd8bc75a1de0fc9107eb83f0904274a2ec9cc08310335efa6f27b65c9252997a5fba04b309bee9e186282869594cdd927cb93ad64b9bf896287465e0cf08ed909383423823d11aa9fb496c7399 +SHA3-256: 50b238c33b1ed91bdc92d23e564a1fa387f04f17debe51ddb9f28d94f09906ec +SHA3-512: 11042e74d21db4fa61e08ca79db16192bce7c8007f9ceba467ccc423d76939e2913f34ae4d074823014e6e8e078424a5f677f32e6e238f0440c68fd5f8b2b757 +SHAKE-128: 1880e87365c4f6029cb8aaa52013e6b64f86fcdfc351e1ec36fa11ff596633a36332768424f40a43c431945664fb8ec2aa70b611196edbb8af2051d3421b65a24d9cc4e2a113cc5edc4bc117e6bcdc6ef52ed2e9fc59faaad035a229c2084ff8f1f8ee794f7e951b12bbd2068194e37837da43ee7779d46fd8cf1aaf1ca9fce433e053a469dd1a67f29bc0e595b8d2064717d2a4342a1b4528fa20d28ff742c78379432f0fcea52e8d8761f4098ea9aa14642538d2afa42645da5186a49267516437ce3e63710c54771832986b2575792478c9b715d6e98baab0bddbd9ff6c029a16f695d4bed7b9c46ea3169df7cc4e664020d69bead36ecce65b8f0669caee20f1182c1278f74d99728c8b9a632702bc3abbfa3709b3222a8ac041425c70f8b2473389cdfd3c25b02438cadf78a25205b890b3b85f76bd12f2b7e690f07bd57b0759f98e78e597242b18df95077556dbc0d86a88dc95fc079ddc30e9d5648af62edb88498764edc0fa882ad49fb1b6da2a3fa27275626a50a88378d835d1399e63f1f9818a3e03d3e4b6462ec4f8e39b242267fb26f05ebbaae97f32a732348d8fc2c685730b1ec9cc91d59be4aab6536bd07a15959c6dac2d56284974506b6be8d5608dc5f89bec743137a0dcde1a70b89120b0efcf94a75e3e9d7bbfd2c2cdcee2127b0ebfff7d4c9663e78215cb4d25b3bdec6a7b808f8a2d2ac20fe085 +SHAKE-256: 6581507caaf26debb329f9f912f82058d9fd2f94e86c380c466e135205477cc20eedbe601fafe327ed55485f806b8f68ea34e21fb10bfe90a91ecc3186e77838fc7b2a084e200c99f455b022b5c0f281d8216d72f0b52837f848745747db8dd5b6b75357d2a63bbdae03831897c624ca3fe4fecf774bf6e125067cbbdea226c6f96b3c08d9a5a45ee74e2c0a746a61e236deac32c0a3b1ac4c343cbbcf89b3721f28c153afd36209d43f3f4770c7d7fd619abdaaa0674f695a7ac209bae34851fc1caa5248c13b89b1266ed08ad39859613e1c072b5d2fcbec8e95e3e9f2cd0df7cce8fef2bb75b38fe6d498c0963188ca56c2ecd8c60ac49e0fa935fa07c19710a532bf8f869fe97115dd5c04dfdcb8594d20f2ab3e050e673e354a6f4b97a835590e3367c9c07b63c88a3ea86135982269f660bb7dc9a612be6defbdd5e115b711af1e17ddd70aadbe346f31585233a5473d46bbdd0cb5a77af5e499989ee4b479ac30801836b1e00f43f8929245d42cfe2ab8feb54fdb9b643187fc20b2f4b7fb1c077737ef914bd251956d767eab53424c0b0337582ba36b5d3801b7953db65251a6624aaf1cd8e8bf46c3bb4dac37acaf9acbb4da1a047011e732073ec56ce360de3e62ce605d868e8469c79f8e97e05e0edd699a9c16255c0628129774a8678c724fa8781bdb91a8d628d571772001f5a60d3d95b2f8afd2c4a97b1291 + +Input: db13b7a10e784182cf192c757990c3dc2e53eb4bf9e4c62dae0eaf851ce12b2c119a6df26295941fade477eaecc72d3a927704db69d44eacc6d057c6998d35d7ce53b03e4bffe6d7d025c018b8116fc510da09fdae3a3e25fa51f8e7e9fb370e4d2a01fec526b225004888596fa12244b02c945a529b21633993de3ec646fa8091c156f866f2a5e3c2449c0cfb3b8d6821ad7edb283d1a71910cd53ffeee57a3d9421b0ca8e45959ee63a38efd823d41d92c937945b275027038630484845e85f674dd05714832459824d2ba821bb6ab1851cacab5531c18ae324e9d5f57185048ee18422713eacdb63f5174f3882fedef967212b514c15b23514e1369340142465bde575a843dc234f6 +SHA3-256: c76dcaeeff89e3ccd39e92b58e50de06fd760147e130ce01a8bb8da74066a06b +SHA3-512: 55b31d8af2131a459465339d2f03b07ce47afd131df616c8391189b4f2545d8143339d07671e8f53895fada7d17dcb55ac74d2c97912676298609f0515689042 +SHAKE-128: f92622f229e5025c85589e5cea3d1a78d228c75b6169e6c667e3960dd6a15c5b392e4c73ea31d036d4df99401f30697310373392cc6777f846bab94f80f241190be0f24536ae9f0a02d2ce57b9b4528975a156c03c795556a9febf69ea295fb3ebe06cb1ec9276bc601b367dc79de47c12c1720530adb85e2cba055920fcee3c48fdf28ca3bdec7b3649df218437a6ee32ed76bcbbdaba19d0c6b84c0b860d78bc12313ef1382c5afec61baee174cbc0870b0707f1344a5d314fd109da6d287ec1f82e91a02e6e1a33169ae923ed902d9b08e2a77fff309cf0d32b1f79169d8983f9bb8193071d526f7c35ad0f73b5a3e5d5a5b271e1139363865b95a40544aff37878662eded46ff036492a4961add068565ec8bc218255074f199e629897498a8fbe941df1e7d6ba8331192dfd37b3f85716640f8bb253987854050a558f75eaf9f5643216d2a76dc328a4ccbfbffb9a92f62bb48b273288b7036853aa7f81f28832efaadb1932d64d62fa3a9db48f387c80afb634f6e8710232039edb469fd877dcb8d9eff8ff59e7f9bd15baebdfc09cd6a1ab0dbd2d2ef6b660b3d814bead3eb1b5e35c8d33484b8bc2d38994fe44503020ab738c6de2f971d8ccff05bd6e77de9c71531fd616ed526118a56f54f9c7b70ab01ef884c8ecf347b6e3ad23b8852bc778e3cdfc081777f86eaae791a8ca6d4276c586659bed8f83d32a8097 +SHAKE-256: b6b95881fc769f27799517de1c29137654c1b5ba60466789fffb3299a9a8f2f66de8908dd5d0891c70a3355093e729f30acbeec68a6fcd3cb00c63e3cc5168dbd56ddc88c88fb9315670cbf44a3d4233f2230d83971537288759a9b270059250ade14b776214d01bb0bc2552bd08913e1f9b038276660110a66dcffc77f8af37943f96c5423654ec48a069bca0519827e54be4750fafa618d6a61dcaabe320eb3daa19651f4785b6b572c4eabed1bc4898953aa1ad9e7a61dd19da6c89f7e5231be40b011a9f160aaa64404eaaef358f1ae0745f3f5d67b7424ca9017b6cf278b2872dc2326f5d321a541654260b72713ea393d2155f57217d4781923da3436f05afb18fdb90e182011c36bdbb0af600e613057e6412083cd357b5036b76169084c61dc6112a28c781b3f60d8e283cc92e4603d86d96f3f146ccd2b93b5a03ed851cb3a2b13f9c8fed06068046c131fe4acc558397860a55f06e20c735ad1cff57a8ab59a2e4bee7f69e1b7312345b5a0431b5ac8aff3b54b34ced32798c9e2fcce3ac3f245b1242983d83c4b7e8a7b80b662538c4aff286c691244ffda9726b6e524eaa32705d75cb7b863040fa47316dfdf84609f062512d3104f3eb42af2d6cc2d78162deb1dab8954716d42fe98a488af0bc94645403ac0c88b34eb8612396d1e3b5a9ac0fd328a8ccb7c43378d79615ddd3333db6ff129b31e49ab09942 + +Input: 1f8c348b67021f6fcde33f05cfc9987dcee56a056783cdc2a3025952930ac0c6a649240059928dfda0f4fb1db368c41f65e3c191207ecd1d550506b808d996f8729deffe56904c7b6b14fad2bb48d575e7ff847ba7522d160d009c15021f891275351e4326171ac6ca83794438515de6788f99ef3120ffdd0fe4d0d11a492efa59a1cabf6a3250702ee2af51a22707d995743eca05f70090f2ca4e0fcc4b875a9af8b594ad1d19a1a7982732ae6d01233941d87c9725c122e02e6b83a5c12422ba688c285eacf8fad6225d63bd2ef2b12be2b3f353b62adc090f311f241ec2cb5f62e8ba473ad15369833cec5bfa8f52e0951e36a7bbb3e9d7fd6edaac76d1e7fe84811449c5427e5d39aa +SHA3-256: fe373d6d0ac1567978d60afd6f91e756e6ef18b86c742ca9f174e058db5485be +SHA3-512: 748ede4afd133aabc2b2c3e171b4a9adca376c94aa153c4551a047690f6392bf6b82eaf7384e46286556fa1453e683377013b4bb5a001478df8ad94f566a2044 +SHAKE-128: 0b9e23ae52fe34da3012a88592243463adbbb76026cd202f7a2ca2c54cccc81b97a844c2c9accdb9d6e748c12ec3ad1333c1952062ad9c1dceb590ce2afd0a943a1f08555103c38a45df28c94162319bd40605e5aa8a71c47d00731ae12f3b493c635cdacfe96073f09355d0967c727a309efcb1a1baac208ff48b49fcb65aa3815fd9b02383d3f52eea0f211b2a34f1f45368a7ce63a597d84f82113fec18648f6715c49f20cc3ad8e831d850c3e004e50c08760d6ba05f0f0cd2dcf5aef3a0e58b2b340484ff7fab486017adb000f3624338f5bd0f7be7718d24fe66de45a19c51b39e571cf7de8cc2b4f7bd739d1f94a1f01d71c588c093cec21cc8eae0bb5aa1ed76d662e3776b5e19f6ba1aa2fc7b3a9fd5a781c4ef722394164a92c14dae810f4d6304c7e4712b9d2222795b1237f3e00fab25139d9b1a53f89f7b216d1c008e350f23b5033fc1b8517cf5d0e79e94329b42ca1013041fd380d6f9d38025c419cb9b843f8b78f3637d3a42cc8be8f9fed94dc2af0df35da7a7f36d7ac0120743273812c0f2c41b5f25808309cffe6cf8a92d63ae89a93d8c184c96833023efc041dc0f98dc250469af37cb5ef39074a171445f2fe9ff7c91f4bc22e12a86cfdae248d146c0d9ca09cebd77f7b8d02e2a0bed8a1c7b44fcd1590cc3da849202be31fbe28e4719ea9ccefc5b7350fe3b2a2c0b9b3b0a40f9660a28be5e1f +SHAKE-256: 70d864b0dc5e18a1cbe34ac9f2c15f369a05b8bc49d58453fd85c01f294a662872893e0512650aeacf61d22389f6b02d789369a47f7c097bfbdfcdf66710fde6530bd2771f8e742bca8db9acd9448413a0192317c49013bf7cc80ae457c482085a7cf73fa6d0d5621897b7940de8b7f847c189284db259a8dc7c1b07bbdaf2af3f8040266e369dc7b9c10edceefddff0c9d99e97c227b95297b80e3860f76bfb71956dcf93daf939a7102107883674fafb30cadfb0e42af83e834ff688421e867bb835ea79952235beb9ee75259b1e0db81751cfc728229a101e0a1aa51a1957f5682065c49754ed91865182f680864f063f7949fe64f2ddb3ae30a7c86e0e5ff7166860469de45b67e11e623c6206e650a10314da5ce52fa9185f1953dd3f05f73cc1b211910ba35556938b3e18287e940358197e3803f1c20045c5d55509fa2f4a886e70c298cb6b0b38589906b51c86d82d5e91943ac14b99e36c621097333fe584956f6a3d532b8f252087ac676918b57851a3f81ebe5f008443a8faab5912c8e1005dbce9196bc14ea90707cc50dba0af06323b39633edcc48fd5c4668afe2c65609a98fbaf7ad4a4e952952227280eb7842646e8c71ff5a6867d9aa2ca56958a793dcc9742923b2fed6fc9bccaa23a58509b6b0d408d0695fc7266cb3b613ebd6d2e3fa84ee0452f59cb8ee8c76caa0ad8fd282060bebd81d6c2ff008a + +Input: 729d8fc64fe6db8e048f6a37bfb54f5f069996a36a420e5f99cd9fdec2413391c44d780d65456bc74b3d40e20ccf8e8c6bd3b59074585ecdad26a824d2bc787b09ad0a44f06e54397f98e623da375cb8de601b9b5c6e9c035f2e8852ff1932daa35b4c78f9eb1c2ec1d6f289ea53c62878ee46ea5d89d71b97110b8efced657ac3a673bd4d1d1dee6de938d18591774d34bb6a689ba15a920869ba591301fce0b3764f78262c54df9b8304a7044fdda881fc63c652e484995635f214ac3067e1d42c4e1c81d899423405dc3e194b3c4cf2c0581984a72886d897bbe0a7cd1336b0acd355faa84f1aebbf19adbfe0e50141a779f1a610e773188caee1fef93f5fef77b62ae49b6a0c2e391399 +SHA3-256: b88e3a3413adf80069c982e91a8d1dc79aa60e0360bc7800797ba4cd9ad5d161 +SHA3-512: 41dd08a05fa731ca2b9c931ce8dc1e3733975bf8ecf907a80f0881d18063f19daa846c9d304ccae6f83f89f255f1dc0f757a62f2e81172ed91673757f85f0db9 +SHAKE-128: 1271c691206fa9b251e30079c7ee149158b8afdede5630bf2bb223a306d7b32f98e118139859bd223622806c1a450ed368bc7d2ba95716324f1e09c27526c7591b42e94eb79d8d8555b94bb5b6260d0c3faadaff1ba771ad707b66603180e3133e92d576c8d8d09f163502ced3835b761f798bfecbacd0cc9f890dbe59107fda82c4addb5230d24ec6c1bc8a8cc5cdb9b21e8f7551b4e026ef5e24469399796abba0e08990ed466ea3efc2ead7b57a2221dbac3b431b7c8ef8332c4c240497b48fd845188b63d0558a6054890fca64195e8808628345ea0dd6244094780230af73941256ceb18b29b006ae00e3e40be33d50c6e506773e823146bf7c30d3568747ec2cd3744249b49e701c6d44fb4a8302842c92bdb233770b063edeb383af3c6386b49233d7934d55aba009e57a88bf18aa1070c4f13c076429b9e186ab0ec76bd60dbf7503f8684b50c7bf20ad0c4a62dffacc57fce7a6f80ca06e97cf85a8ca3e5704fa18d7375a3c717d50a014d1d7db39c6820c2d33a59688c4458db99a8b518e4f3b464d28901fedb51a98d92cac850573f2a4db4366a8d28ed68eed5d19aad1f8c74c411f7877804941db9e9cf21945732e131855625ec63d00f810900a36315a21e83c6aeb507530ef093945d903e012c16a60f81c5ef6eb2e2660b85553dc540e56e35c75f29cae6cecd034126f78f32d1f81394ddcc88417aba3a7 +SHAKE-256: 4921d30144351ba6c0756c47ea7212aa0acb53d8dec565b208cbe24c22c702bb810b9eef414f2f9e8b89b415c039008130ca97e4df3908a0bc94ca76bbd25804e19462f77783d6386ff5f22388c7ba6df626c87b9318681860cf01c35390d86134f8e99cdf9d5773dac5577f9d5295df194af564721e6309b27fb1cc1ba2bd84b2782fbb7f021e13c97ec84b616f41d205260c571bb7317022d9ff37d4e164acd291ce97e8b791f4c834b8aa641378fc3a698698d98a258ef4d81d90d6b80ffc70e1d4b5d1cd9bff8c8d57a77c5f85fb244fd05a30b1d4c39898bc258cb5c113691ff20bac89826c77d6daccdd9163863fb69775b427c9f860f5934c9a4f3ce291e3881ccefdee5f8cde1c840bff04100ebcdb45149dc7a6d6474c5cda3b2987c7a9c4b2df04b5921fb9fc661a12c3eafb2bb850c02dc767288f34a12e7f7d600f8e1af4cf6aeaf430f20ffc8dd27e95a1c0499a40389b5f8314ae580d740d4ff5295bf6a354ba1625af2adc0488e381fd864ba3496be98cb1c0a9e199dceb499cf47c143f7316a130d2237011eb490186464513c20402cf8c38dfeb9b75abee7062628f8259d439cd4a2b012a1f5cb1cd7e48fbbd1dd7a27b95a1cfbeff782090fe5a68f4a7c49fa8aeae1b5bf605a9fd618a92048d6a486bcd631787a45348587bae0237433b095bbcf82cc0891b57a75504d13943fc7a80460607ae04df1d + +Input: ac5d1dd5b325cc1704539bfb4b17f085985f358909600113f5e169922e7045f9c59f6ff70fd9d4832037c39728cf2933ebb087f40516c9d1c99a83f61f2416cffcd92f6cec5f681fa61d7eb4d12ec6005b3327c9574f1f5ab79229987ae1a3acecd0e207f371a22512696ed680f4e598847be3ed32b5183277735f1c54b8a996f74cb2e943ec67ae4b57225d310c6d4cd412b54d81e3bcd4d6999668dd94aac0683519c4e53b853651953774915d519e0e3ff9c70710e888b0f358de65a1571cf7366c64c8fd782bf3d3708a64e4eae8552a7456cec1b0301533aafcc34ee0702e8535ca6d0d0c89960611bc92fb536d63836eb3ea86332597e08f51d47a311f5401bd4ac1fd37a6a65a54df9b +SHA3-256: 7693a6c5cda6c7e3c1bc7b13368664411cc13bdfe6f654d2f1816d83fe3c06c5 +SHA3-512: 8200f00e1b76f2a568b6252d64bd00dc7aa48bf434e63982074e72938588ad805078ff31509e2d210362e7603c6be1141bce80cf8c32cbd52b6f48e6f2dc37c9 +SHAKE-128: 8759aae658c0f4515e9651e4ced886d43ee9310aac44dc8a20264098be04e0431aae39818e09f4d4c631af823bd608f638e30417e8d032b2be885707c1750bf70314dc80f1bed99ace14ac691d8152885c2e63b52c3adeda7f44fc30ec03f5cb906518c205c6d1d1c2b1e3f02a765691156ccf9b9d1591491878278c51379f41434312d14a4c3503a21053e26e6e68ce3cdadd9c58fd0581bd9b3fd5d60d882e8569824be4f0b71ba7195f7e195ed0218d3e0e2efec064831312c4f7f14704af49ed969481cfbf5fdb29d03663964e5a93b8bac338f2bb061510b59bd85250247ddec693b7f910eda27f675bea89a8e6c4975eab527fac47fdd794847b98f15ec6ff71e38802171ee6bb51d684e752a018fc3b11114a99909f38755fb4b8824b7934b31aa9ff482c0862de142b1a735bde8c6fd009e2d6a6db98d2ee09835134df83d8744b0a5164ddac3e6bcddf2f0399dd08b16e91c6e24bb2bd07968cc6e3f91c8c0d668e0464dd7a57cc9b7b74cff82a87b7df53c792db353fbd6d00760b53e577584da643c7b9bc1bc4ad5f99d1e0b889b959198b47f3730e4a38b6aff25166c741d80e3e73bb876510bfcbda4b029af129338de2b31e870101b5a537fecf8021886945f88653d3563bc07461384c0b81df2ced4d67e58e62b4ce80c1071fc66a261264714c3d89a87e8f5566578c87791ed998f2d1533be06231d94e77 +SHAKE-256: 0ede8fa394fe81524fa2e05cf7a1b20a6a48c3e328c1409f2191e20dd4a1d6d9119c8548a7fc52192141c69df2f4336671e46cae068163d72d37315c00434234d2022cd27e69d2ae1ce1664e79a5d0f84477c8a03975f0de22bb013038da57113bde84e7ce292ec5ae0b7e83d0759b412d50cd0ae4f700bd0b2706b59611e67de5c05ce7611024f5fa2b822d43e380f30a22387955a4f33c675a004db855b336945ed9c7f8550529918850c481297d0207bd3cee6878a8a66f7e7ef857235785ee776bb145f564c466c133a294bb00b0fdce3e58bf877a7d940291448421547873898b85942da2fd36cdbb77f057d4c7f32eb0cd9a7198ac147e918c77de6625e64fb5acf342c76a49505db257094b5f614d5d3a2f49dadf556f267eb947125a75f488e463f6bbd2a8cf11cb9ce3b772f57db15b9ebd7e4b4f09113e8977bc0f5f7a1bf0fdf59a92f1e1380b88abdc0f81dae22c54f38a3939bcc54dff1001fefd4cbc505c816fba2d66c96fb85a60bd8fcd5779437ba68dbbed2a31ac90198bc25a78f8c6e0198623a1e68baf4a4b2a1d433590bf4218e7d065c873f8ba5f1526e22b7686f6d324d3096f8c89829151b1f9e7cf9ae377dce8df64f7fb33a53e9a17918560fa42258e3253ac4240260699a8c92682870a524a959164bde4ea8124f4cf78d4954a5b5a7d84c8c02cbbdbedb58e1cdc9455f5b5766e294b83eb42 + +Input: 51bfabadcce5073b71abb3ab9fced89b7d455ad5edc895291a018ef2a5e18b2d644f92c4b53aef2b35d2861e62ba215096e0e3ac800b9bb749db92015cb1b80877ff69b7927d4327cb3b3540595e34053d588948e362f366aec7923a7b3e8bb6869150f2c2ffb4adf97ffc0ea9f17e1d37ada168c92d1ee82e11af361b4439ff24fa2db7caa2aaac67a5ba27bf0e0677e3d55dcdd6a5bb61e804b69466a04cc335bede90b56c0b7dd4d1b126c3d32e5faf0990df1ba046fa1cdb1082f5041e9e4fc0e7c833f0fdc01322d20a2373a0036cb0b12abde86d0d3d18a1fcbd687ef19ab395eb99f22621842eb0d99a1da6e6d73ac58d128061fc1e870c048b3d94ed0f558b82e709c62a374e98b767f8 +SHA3-256: a6a4f49aa81c7a7b1a24fa2f0610056444def10ba30e015ada592698eedf5438 +SHA3-512: 30cdbacda93a4f02c2be2272fa371148b4294aae6046a11179d9a9712fd8d85c52e57711682155bbdb80f2cb66af0491d351ad7253412a4eb1ee01cfaee21ed2 +SHAKE-128: 8a8da0ee68e4f36c7a54a7512aeeb94559b236138662e987a03ab61d39a80c6d14cb7ea2baefb027ad1d9170dd791b6adc03a84503a0d4abf1f7c42f29d18638e1f41b687a32c38f26fe74f5d55f296fa044fcc6fac5df42c877d53f6600c2f16b59b1f60e532995ebfae4bedcda5e77325ad6a475843c1d6d65a4c237d9ce9891a9b2e23b3819b3d8aa2349fe3a8a05822638d4f7c44a2556c68f185414b8ca03f0a81189e3dcd4c712ab90fcfb5fc2cb40defed7f4cf0f2ddf3168a8de7aeb62b55635596c750a89116f34f911250b0e322dedaf856cbcf5feb14e037b985499bfbe59ee3cee0d2d628700756b2034ab112b61c9c0fbab3a1e112147d3d73ba95973d5af662c35713a04a9061c083fac6e3359ff78f181fbea8bf2faf31c6699547f009f55491725eca85a08290330776bbda3c968f23e234c16b1927d243467ddfddb14844b0dee257c3367411f78a39bada30223779845c5ce048d5ee206d7317325dac57ff3edd77c69add101a6296de4dcde65548925a8c9dde7ce93db6e59651598a0ed8bf58d7c288ff255a29d2964297f67b7f28464b6b25533e44aa1a41c26fb3699f460d034857d778b0c20d0634735307f584e7a1e955731dcd39215862a0cd6502517beccfb6900582c9a1f416536ce311f3455aeffa9b825c03443d9ca1b1340ecf3ce15a0387c92688ea6d2cd34101e5f48ab3d1da18de3b0 +SHAKE-256: 1c78972f04a35672df49244baea1c234c6c080c2cc06b14ff315f9b91d6bf9d836411a5f5f6c67e204b392550ac75fe6dfd60b8d0a99f06a34228d0cad4cadf3a4aa01b86ce2482149794e96dcd7dec875908fafc81636eb5d4319ab8ae36621abed573b8d9dea93b92fb6a8cdf6fcfb6a0dc8a46c43436d03e9a534468e6d5df627c2d617b48d985e93d3ef39c9e5b2dddd2cb81d99054a95fd4e2cfa9d50e8f0b81adffd7c8d7251eedee1256e3c1e94bdee107be9520ab5789dc4afe0e90197a145fb7fc981abe0c5281e7be51b934a467d0f556657e14826bb72886e245d7c0763350a23a86acb7ce46979575895a198c642e89d5c4a4e9acad9cf8b209d5310fd3e8e46a3d3a723c02c95e4e6d5cbaaee1a74a47c37cfd78643d3bfcbbc1901dd37ba79989c2d3b7deb48130ab1b7cd6707304a30da572437f38dc5af762b342baeb93c55c60dc914372a31225863ac63c0c38287e5c41c1a05cd54577d8ada22d16bf17bb60a551ff07851b67ed2ac78b0878826f0b144e46c723d296c5085503be0a5ee8793a17b9a0dfc381e0f9e012ff1ed712e772d78e969068c6308c357e136c9030d1e7dd07d50b343e9c1009d15448fdb85d90f3aa28b752f0fdaf31098a7148270af2c9f27056837dbab666aa91e2a08b9600c2f72cba22025f595d4fea56ec53fc1d85ed71a1404b10d6146440071f55015780ac7859a4a7e + +Input: 27e80655514f4d34afa7deaaace16c8f88eb2997e9a9a7872d22f3035c83537f9054e6cd6a1623102001bd8b41328a1209391e590f757b38a8198671b8a5e6bae498b6b4f8c12604a960353d38941c0ccd4448a6e8251cd78f01660da55f655e64764888a2bcd8fe9cb65f14a150d816b3d4ff49c8a23ab00e926fabbae463e035c8308b95b54d88c13b5d8abc357a5cb712dccb7c2604758e52974acf8e17933a186e170ccf803590711d7989b4d28c5d34b3a2097c1263cd30c19a168e804b6d3836f98ce97f2c53534038842f0dc3256c3298b187f43540fc851669d5de77c75f05462cf47255bf42219c05cd5f6bc1f148f8f4750550808d3eb97b148f1f2aab693b5c29b73e641888b856f0b5 +SHA3-256: 1632a3c8bd62e72448d84e6c5b7860769d0284b3ff349cf1c46eba85131df913 +SHA3-512: a4dc46b171853a7e74304e8637e4c12bdbd956d4942a336fe2efd47b96988e194dea70c2f1f49d279bc45f5323ce7e729313956e503cfa9a4929a7d47942c64c +SHAKE-128: 8ccfc4b2e3e6c0a4843347e3dcfc69195c089a60226f9807390aa0847dd33e1b24c1a6087a47051a37689c1354d8451563fb2ceff75659a9ad1ad4a3b707688672addd53e37011ec2007429a594aa7d19c960700481ac1e75575db628054ddc670ea865b63f9fcf6bddeeeab17c1669b0718042fa5734338fb726b339d213dea2cea9517fe008b36b6cd46042b8682c76e6177e12ae2574bd94d47eb627f12f4aeef6a9e6a3d7338b279c9da51c0a7d0463f313e798509ce743d377a7bc9330bed0bd127cb64aeed7c2e7c03995f8752e68670eba6a4b6f6b18de4d564d87880817fc084ad8ac5745b6423e8ae1886f99110b72580698f4a7c1677e35a5955e7bd3c632a65d502154e538ded346a423e475e83926522a8ee56155fd69ce41944be412deaf6da50d20d683b3e094875e9e0ed901133e48be40881861e3cad178e0c351876592d5384bd5edd64f1663f854ae2a7ff1c52d9f51db6e42b93bd1ff13007b2bdc8ca4fb6196cdf7e06da9ede4242220736b92c45211ce3b896f9d37402393d6ac1b63f299b00d96c96813855991d76dab1d9406cb6065b82fdfe33f1d4a5afc070ef39a267f479016207e722e58c08c5af97a449ebe3079a00643e891243fe9a6a1ab4d53c1c3ebdf5e498a7fee657dc77919dc5751e38915a5230c3fa424ad8029e15ce47e6679e255612e2d5e286129c225e923ba33107971cf4a0 +SHAKE-256: 7f062ac778722f8f390c0dc94976c491952a9fbdd1f6f194eaada7c546d66ebfce9cdfb5b165caa25e50791292a3870014ff66f885a1f5636200006a588e93211ce4530b75434c553d32d685925885827eefa7ebe92000fcc35cf9dd4c8c471bfc0027aff5f2ed6ef539786e832f8806700605cd18baceae1cd244e91d8937a2b265af66ee23ccc5afe28000e4f6e4906aff767b7094e29ddf411f9085dcd25aeb42286cef644b14d0330927afbafa9fa665883bade60e9856fb640621f36cf4e49f981fa4aabe106e7a0d42eaa8791f4202b962ef0031f4b968d56be2f8df32d3865022eccc36c5937117529c7da51ed4a594d9d5ec6ad29cad82a6826e98e3a6558a1ba2561c8706ea045fc109dbb2a72992e26d62ceb4cbcb6a845b17cd2e61b49053baed9a45978da226a2027c8d4fb9a44208a35a6f9d105e5115f0dd8cf9362d199c05c4c33b2b15099772b34cd4da011867409ce0df29c02de7b1af15f63f8144a3f3da53973c98919965e81cfe12d62e111b1f5590c5034cf940497ef337adf658e0b8b58183fbc2e24ee1816c1ef78c23dcd6361f8e7164389e93faa48332e9d2862ca5dd6f53b38498a5e651de3c86cf346a15484cc6dd49afd2d615b4925606d061f8ae72b54a2214d6256cc4d61016b9ad6483edb8c266490b5425aaa5ecec28ed008fbc3d15ff6d3f1802ad7cdddfebfb3a9007a8fba7a2ffb1 + +Input: 8365730dab7edb5392d48dc72d9f80ae437f98feaeece8c783761bd93ca9da3d2fdda4e0b36b9fda88322dee0c15f9d095d96864b889ad720655a49dca5f90ee9f1c2f726484d6881108aed840ad6aa70571aca09b14b7f86524d008efe5620a5f143cc14422bbcf389aaa802859b2d383ca19dd2f2918f281862107586fcd3c5715b7c150c5977a40f925e0e81ab7ecb82a48c6308ccfc64e4b31958edb46e4dd82b5eb0d57ac965d1c4d565c8c8f8052c27c6aa7a4021a3bf9cd1b5a5d3fdf03038caa922c7ce36ee1b6211517d694fb096a6bb5cb01963da45571f543c5e525f7dca5d7d9bf40ae0155391b9f6cd6c3f13ff767995f9cca17d7e9bc28c139334070382c908f58c7e4490d3f3e68f5 +SHA3-256: d7c468e0f3e3ce5ecb5e385ca0bcd9c3741bcaf28d717ca1a4661fac7f6f902c +SHA3-512: 5c4429344973338b31dcd6abad2886fe0d3f185171b13d24f6be2fc576bc69ffad69655bfcc666f20975c889f2b9ff64cc574080a9a05dcee2726e1e8a407500 +SHAKE-128: 2036e57ce4f1a440307b35dbd8899db94f21a196e3cb9ffec5abf02ffdef2dbdaa57ea850b2178760b7a966983fbee99c7a411322d8a57ccdfd7628c8d9d6d7449fff9b759618213f6f7ddeef1812329dfd7c95a8f0bd1c3497ca4e91959fabd9b21b723559cb30b931c5d48208bbbe6b9e66c2049d5825df3e04312cf0938ee29af767e9a9d902987c44375cdb682e9a58734f3aebfb429dca31d2380d15614e2f9e7a4527181069fbcf9f4457f3ea1da2acbd5158741acbf9ea784cd1ccb75636c60742eac4e313889a29870da993d9b1fe957821838cfcfa7d3dc4dfcae6b4337fc5d8d20c5873625d18236ffba499285fbc09da88345d22b83b089a9e3bf8a6d12e58d62a4b24d4375d4cb020cf3987c982edf78111f4b23a91ea10e5609667b42e41a22e3750fece2485b284737fbf7f063fd8d9facc2b268a7615a006c0ac316f52689ea36ab922b33709f42476dc96ab9913a92a6aa93822b42ac5a6e5c6b32bd03ad80720d4764f414d19ea2fcb247865d4badad0ad4fe826ee9939f2eab178b214ad3243e862964ae0f5b0c42e288560cd3692a9209024f9a861b3e7ae110bbd103da7cc27c3a6311263b081cfa5082fd6fb07b66ff7c35132e89661079ed2e44524cba97de759fe2c029ef117fd88217e0a10268499ce12b38f67229b5b897213558ccb040d14962bb6a5cd1842d48de9548821c8f6076d77dffbd +SHAKE-256: 9d8839facf48aff8c787828163f6f4527a6905fc8999285c6747d24423a30aa213d74d71849e74d7f0724aad32df07666846d82dcd2bd1f5724dc13c9cba6bb8cd7e2d39a6e834ebf187e962b40855d3af41adb0dd51433687f4bc7e96f793e0d893596328ff9ddef2882b84ce89ec0c766b5fdc48253df15d3ad0e051698ce23b91e0293d3a3832077c17a0c990f602bb087f3359b5754c9fb11b44546fc0a8a951ac885300dcf7ffe2e1af3ffffc7bcb46c3d9ea7a1777bc4e5cbe241281dbc171be331e260831d6aadafadf40ab077417c3b21937b6fef599086c3a5537b4835de6368d09ac3ba0a3a0e5cd4a22c84ec7328a8fe06fddf6ea9d4dff9eeb70340dd6f24131e07b8ba73d57bd6927fce114f6e245c87f451ed67dd74e4f4cf2bc7638f330606e3b4a1bda722f31e70a0d7469b224cc40877bbdcdb6c51c5b8871c519767df0dfc2be481bb476b86c4895162f2fe6f64e5423e1de59b1e4fdfbe9a9e4e536232a3a359c0090c1149a77114caf52d8fbc80f85c27d917a46e9ba14b49ff5628cb003e13ede80e782f56009bc794de06ec4ef007f9fe5dace44e5294ab2f14ee9c763e2422137ed574a116e08417fb90d1490d38e7595abbd7e98d00397838836993b324216ab4e53b49a5090e5a62c3ff38f74c68221df05b59d295394a3ca45ca75abf45ca953aa8ac2ffde1e7ebcdbd5120213fc6a1ccbad24 + +Input: efdf3904ed2d8e8ed5383a45fad8cf8d6276457a3ba36e4ea8cd925dbdb0f4d346b24ff2ca50402b250dc0814d07a9e604f58298b650ca31e3a5ffa050438a5c28dc35f3dc7478760a3000c1f2b6676b77a46f3fe67453a938bf05396f227aac55527f5d41acd14bbaeb7980389a779ca14d37ddbbba43cf9d0750ae5e9a2cdea286a20cb4777c7d15a8cc407da234be4a010875a5db3eace974e8d9fb44e3a6ee771f2b2592b490f5447fda431a807853dff8fef5cdcc01c43775ea387a3cfb6952e58350a21db037734121395b637f00b31e001bd1e8bfabfcdaff243556a076942b056317f9057b58b0b2089bed9018706c379acda9b5f30e359e6e7af427f33d9af59435bf9d76d135a1f4e5cdd091 +SHA3-256: c505f38539d0a6dbbc2c755ab14f9c3d609abe5343dd0e692698e6c37b155fad +SHA3-512: b00f201360dd2933c4b4644b65d46a895ece6d84cdc6224efb323d930372b42454d5b614bcaba111d14bde4ee2cc8f2ad6bbf5c170977468333943635636bb8c +SHAKE-128: 28af2cc9df157765e199f6380119d577ee962fe88530c06a8c58f63e3d0e6282eb9be1ef4b89ab2a087c988fed833be0a689ab4e58fc8693405949c5ff3811ed4c1fdf7ef698fdc5aff0ec7148d4c71ce5622b760956522242847b4e4a71f414309b36b78dfdf8493b758612263d31346db5ad29f47d56dbd3795faf8426c781a8836d578245f4692d464540aeeec1f3cd1c5e1809f06612e3c8ae0a01264378f05afb825a5490d1390c07f0fb07e61b02075a20b387e948b9892d4f848de289dba430affc2871b3e6e2f7a324ce23408012a7efedc320dbb3a9d567c65033a8fe04d308f150c57910ab36c3dc09efd8e190738369540ddbe8478f6dd64d7ae9d502901595bbf392af40c9dc1f0002f3981c86e0699d06fc99f045ebe6621cd47b6664ed1f8d2cd8be89310b01541ed236a7caa06c966c9873b44103773e5136206da8ec97a1b093d6b6297e6c1e3f546990adebec1131c1c848f3c381c9d6505dca07fc58e8c9cd141e65f18879107461e5238e2669fbe182f5b33720c0513cdc731062d36566ed3727269a83991f45d616e9e74603ce9bb6f4fe52f7011348ee9883bf3162e6be76ab5020dca295da20ebdd89b34aaa6ca986860dabd7130895a5780c3545202aeec547ac9866bc8f950ad48f70836943faa59c34fc256a131b6dadf8497c847b6561236ad5af44991ef8d2b260dd6f425d28908ea3422fb9 +SHAKE-256: 20100a3a892cf2c23c400516918d548b7b879aa379471020cce08cc008163dc9f7cbf888193ce0e41aa49753169caa07dc56fb2c7dc1eede64b05df544ea0672dfb54ad604aecabd57deefea29794f439090ca37856575eb66f7afaad66be78d4fa5966c0ba9899820954bb59e3645c3fb8475c7e4e11a06b6902abcd262e463c3c216568787d86fa99503aa2bcd3af2c689c1d46ef15756fa41539479faab2e46a3ef7f61fadda259201bdc00657c406b086822997dfa546b64b9ab2d6a28c7735e67076b455a2cbbe3b7f5ed903dd77a7609f182cc5998c301d3b14d704d858e3baaa146cf6a490d1c7e5fbc718237ea57944096c24103e383cd2c8ddb6fc6a23cb5431050df778c54e3af004b9386d4df09a491ac9fdb65dd74005d4d32a38c42f0af8132d1b84468663d1c2c44604179d4675620eff93619467f29f5a1e0dbb8c53c8ebde6a647da5c75fb851aaf953b94788aa688bc17fa02627bbec1c2f68fcd412846034089a1edc87613f12b48ac0e9d33d105ebd36bf950d6dc89b99e33cd9d06c3c56bb4d09c8853690796bafae2b92936ff469ccf0e056ed3391c51be2946fe390309eaa0a82192fb6a53245f52eae636b86fd4d22a4654be808024b86a8621564d1765aacee342cc444a830e17f87a821a20f5f722c6506d9e2af06588deb873c8567768e3b3a2b672016f5a4e84d94b2b7e1fe174be1d49cce6 + +Input: e002c0e6546046f772574f11e60d385bd7a0090a65b5bd526ef68cb5e2a8b853c6e58bf9532fb86c6fdc719033b8b954fce7504997d53e213dccc208b2198f69843c30b33c7250867e6485c6a13df1553b50482012d637727bf1d351a22e385bd7d2baff5cdfca6d42ed798b9179c96ab90a8a2362ebc30e45b5c986a9443594732804924e387f04a813fc9d4537e4fd372eb64fefdc5ed2b141b1c179acf39188307817652f1b5144c93e551b7f7bf2819c67b770b70da64f0191e4908bae62bf909727c87e8ba41d16e517f5a1f5134018fa8d816e643ec141b436e7b8dd0a682141eaa4730ea30c8f1b8877de923354cfb8578872732bca19e7d215fad4bb7fec9af756b75b85b79e4ba6d142becf9e83 +SHA3-256: f046ae10437a8a95473a42fe343ef4524ac43eba64a0929c03e5837da9423b44 +SHA3-512: d6da2264164eb59f4a509eef9339f59615239c66337c86b5ee9694f335ca719d35fce4a810a452e96fb3be179991cb0d566a425d813f3bfbe14f4e2025d5edeb +SHAKE-128: e46c31d487e6159638e6fd8431dc1c9fcb7dc9f03fb8816088e2a931eb1c366a0537836931a1760a83aa2db59bc0d885f354cef0bc1eab7ba13bbf5321fc939af996ffe6a17a8ce2653d835f4ae4282292a463816cfaa38fbb8e6c02e3ae7b912d942300b5393448b1a8a5b25dce9f6f4e0ce003851db73d4c731f6ec4f327e2dedc12992ba0443c0dbfb4a6ed4de162b527175348f0c197760870f4bffb8d23eb0dfad744c4b298462f5518d396cec44d99ec161e1a9828be84cb140b4350ee3a59463b597eb529efa078ab54501ebff4ae8a8f7e9049d808624aa932015a9bcd6b79766ea3ef9327a72581d4e73282d822c7b6e77be3641f468c0107af5a3b47095cf2c51908b5dc72e1ed6b53f960c3042d70707f427b961b722ceb6f6f57ba45b66e178e2fe83924a40ca42cee25eb37a48ee4cab26958fe6812ac1b9ce257d69a9f9cb4d6af615a607e15c079d301709edf097192dae3ef6db996f14af57a5316d00578790e41064fd87e522ee9af0cbbd10765cdf9dfaee3373f747bb83ad77c416e4df81463b1fcb3a3fa8ad087b721cdb7bd86851a458ac08df9ec2b42133d0bcc316987413f6107ea48af2492e60f8c3b6c0386ea0e92fec3c5945055795d8fb2e1ade1348a7a2b62cb46ea2c453707687b43c1ec4c4e5b00dea642c604b48995adbe31888cbf6b0fc86d188712d45947001c707392356627b1c5f4 +SHAKE-256: 21a88906d79bd3154ab5f420587074ccbf18a0ec54aa7a6341cf30d1caea5fa342359d1eebbbc6e343d2c799f5fba27fbc2db4f2df13d73a6ae75fe6f9f04b6571c3c08aa5afb4d1b586abb02018d9049285a6fad0a35dda2004a3e8c34d66e6093841dbb1c71770b637cb0c51d501e7a64edc6ea20db914429ffc1ebdedafcae2aa164aeef6cc41ab2a2119c8deb790d686df2f6bf9ad4dd32a22fa753fd6d278b3844e5ea670c2444aa877cfa08fdeab1adc90991c74292735e66a138a559199b49fc5f1889605b21f89e180a9e932919755efd9397106caff728b6ebecd979fa490a552b419c2ac6b64e476e2a81016e4e1bc650a75e42714b391b3793fb57cc2ed005b239eac5f8506e2b96c22583c8760dceea6128440736af864c1fb7f5930368b7ed82b5dd5ad383e724e90e61e9fcc90cacde0093c0fdbff30006ca57c2fff6025ed537e9c1d1e7d4dfd1e36025002770420ff10ed2c6d35ca36f2ea876ac71c1f973bc296369800babf8c1b1bd76f08b0e850259711d4ea0945ca86630afced62093c686c4f7f9b8c55c9f94c7d348691ebf03d2b46677330e8adaeebdb11490cc0845ce731bdda1d815fecb7314251ccc6ce27ca9c919bc685014d8488d8db061741ba31e95f76e1551b6a1a9dcfe51bdf3ee7d2390f45eeacc0b5f212d1df81c5475c4be2efa6d531a1bc3a6c5a9d5f608520cdcdaa3bf7bb5c2b + +Input: 54692a55b780a31f2bcd6c2032f6c4464caede26d332e1f2d000abc15f03042bc70f391d26c762dc0a8f688096bc156718069c826b20f1f737b81378794bbaa290a8ee99d7c533ca34cad2257047f14b471a95ec00d1a8235547db2d384c49bf7b0ac5a85bd7bf56d02e6ac8ba2d79bcb9911ceef7d9feae1a8a0f5a09740d8a4fddc789d70c0c7cb42d33d301319705c8b00f9136776366ae8f101d6359a6d4e7eb09049365b982db0e166f5509bb88dfb21c11de3396e8a445429d809e654d8d655f9e80b5baa17285c4e6ccc7e89972b939e185a4fcda700005fc1bcc975da39dbabadb3373f4c58416f9909cfb77bc683ca38f29cd93a906a93a395d5ba7911ecf3bd1fa0d954998ec7de43f506594a6c0 +SHA3-256: 7d4025081a99f0ae878d4fb71e9e1407bce9b75e8febcfc361308c71e939f2f4 +SHA3-512: bb51b8311d20f2f3ea60445f7dcbb1b76363ddede4804195e8c614c72dbed42daa2e9330b04f9957e26303d5f756c0115efd63a3ddc241e564cd841df6201892 +SHAKE-128: 3807ea489c34221e708ee43219b1307f4e618021f23b75db41ea11739c9302d455e01335ae2edf4292a8c411c2973c8357409ca19c5d8dc6297039baa0ad50b034ada0f7a041c9310f350befbb286f46b93a1f1e9df5da4db23f6898871b1536965b25a934c309857dda1a40acb9af60ca233b577be6347ce999158bd91a4d151c39fa13fcf074b3f499e2f61f73463eac049b908e9c457c3107808d9beb4bb8f0a9f76f6748f17650b11b51fdd02e1ced83627a9d39344dca8191541391d81a08e99b3681094f480e482fc6af12a506bc9d5c0f9aa3954d0252ff8d7188dfda785dc39992b2bcb9dee5574028fb940ad7b44be65ff981254e4ee941fa820a02fe85121f855644fefc1ada6fe1052c3eb41d607ad7620b64f715dcb2fba8f7a40b04cea7e0aa847b0e21ae14dbfee7d77faca84a5bb9339847c8d7500877e4eab8f333da4a59c99d0d77e5b73aa6bbe3deb3e1de3e11a88839e4ef5f67dd5c183d2c7fb80a72f7c13ca4a1560cbf89b8b27c1130f10f1c224a1ac82c8691ec5451d13d859cd9850ae17231956f061ee9fc383722eea5e49c7f6e792500de8477763a8a96aad37f0b08ae74dd31837184f5636f3a35c302c33ca980ba11fabb6c85c322b47fabb348faa083aee27e8b2ed171f374f89f86c398cc71b1df60cb1219f1acdf4c6c7cf55a14f6acbf8c7eef845f7010b121ee895b0c0acc3320e699 +SHAKE-256: 8ab322740e5b1a6958a66b33194596ebd1971150a8a2db6e33325c80c82741ab5e9e63723135d433364fee464a13386349031e30dc993551afda1fff6c95451ac8ba3e172698f73194b6a88f2f8d7b449654431ebea20caf531be620a791179568265870a63063b0506bdd836e0bb1b0ea18c8d6496e5c603c0969c2c3c52811f5e27148b830f4199601e8a741aba23cc3760e13152f7939b2b2246d3fd4299a314f3796448d4caf1beb721d044e9d5b1d5e4bfe610b085503fe80750a94eca1fd83a8ba2bc3170e42e074bae8917558500976b5d92adf3437ba63260fe688f8feea501d4ed3960dafc359b21341be3ae01173c9547b7d8439b0a498118f6772bf1903ec50a4cae2a7242c7b4f58f0f494da97c18fc0dc198f28c6740f8a06f7239e9bd2ebf48c07e29cc6d4a28f53a33947f2549e4c7e49094b993c4e508b29dda9c9b41a4d4d2a3a48869f53e2aa3e5a47a7aea543a129caf341810b30650ea57328676331c24a434c2696ea9338202780a21192b261c5a8561740023f217f88cd4adbf15cab4f488f8c76bb8b395f07423f2e57e26bc3d1c1df1de72d0be66ec8a25ba6dcd8a418aac224674dc395cd44f249d72219f6aba16e5d881f5f1fca2c20bb1b3ac33f5c4d69a370547ddabdf64f12b94f71a71e93153afbe3ae71529df3f42665444720bb147c8aece34eb7e286f002d09fdefdacc05ba8829a5a + +Input: 1535ef658c408bc2fe4a0655f00e966902066a2f2bb303cc589edc73f61d30023ae50e9f510cb6fe4ea7ded57049831cb9b02a5c6c647d7bcfeab0dfe18b65d80f9dd1c835c3abc478aa0a89b4bb39bcd97a2caa6d0181b27799a9e3254fd81e9b12b1e498b60027cddd292f852af47926e57835f771f1c2c0cfefb22dfce57a1352aead03270c6d778fe33454f2e4f9af5b40ad0f1d12d2a4fb822b082b115cd8c11b0974c1fa8f01c7788766e8e2ce63f60b6d79474d0fccfc5fa80aa613c85b6649acc3a80896a0733f0f6ef8d32b4bc5ea186ce5f004450880b1c1d127a364df1939c185dc063c1d7c65198abbd6d59bc5395059ae517e30dd7dc2a20f77baebd0d84c47e0ea8a44d9ddc22efd4d4c4f9f35 +SHA3-256: d2caffa0459f318d664c5da6ef39bc475a0bd3cc8375e9249301f4577a898087 +SHA3-512: 13cf6cb40e4bed9b0ff94ef19683608c106975f0d84e1e107280c2661d6b74bad24d70fbf844e01488bcd272ffefbdd36c7edc367895a3a51975a38ff868b59f +SHAKE-128: a5552994843726e3bb834938a7e7884d6e07f2358158aa52f98491c1e408f6f1a8f8d227b2bf8cf857f540fcbe3425110476faf6985238803baa272f34d181324961e52d987e9858a8422e73581d83ee58963dab02c3b614877cab4b6e7e98a623f82ac5fb688584e1199e1521921ba67e6ad5835d0e7b5846be96e1383f802ff2fdcb473e1e0394574aaafbeb8c256decff577770c83e7a9a0fbb6a9cfbfb777ae4edbbd0e7f1feef0f6301eb36adc3d6139d412ad221b3cf5242bbf45fcc61f7de7f791464aec259b911aefcc1f0a6ce1cc6e706c5f8066ce2db240c7337db1156be3ed55bac93cda4ac28ed34d7956f619dcadd030243d1f1bbf2471c1f362098560326f26ca56b0933c2dfc812167cc6aad5ba68a407770c84fab02dd5ae37ac47ec86d03f22318563926f036baf7bcfb7f6f786b1d8e7cf5dfeaa4d4b81307f81aee797d2b107081703fc19fa82d0db7403cfb62829bd8d57bd0de9523551ebe1a2dc4f7562c1fe95e2e00dece3f2aeca58063a72b2a3db4640de783a404e8ecd187681e0f8b6d8db04dd5b7d438d61b323a836663eb511cb8e2264166c272dafc69e0c12172aa3d3b25e08142d7c888f4d24dc64f305843ad90d5ad6524196cb6f805104e6b813d2353cd94f95b6c5f81685dbee579a6545efb088ed28cc52d8deddc6a82a8b087440f23f5256faf54bd17665d2d7553e7feebd63bae4 +SHAKE-256: 681426d30e8d72a1a53471d0c05ed752dd27a098b5cba22757eb99b8af2005770b010c3e8a04aecffe2899804214873bae21904c04926d727721a3b3c3596a995044be04f73e77c24d357453865bedcbec30697dcc3d9a7c1596c0f5c98f4abebd6ba27437d6d82283d03ac92ee7d3dc05564c15c201cf88b4b21468349e1c8f33e3895ea01d443617639664e9f021d55ca018617e12089ffe7bdfe208169c2b79b9fb35f4b269ba8969c134f81dfd90d5769a5cfd8ec1af4c48855e8e483405b55f0d3e811a7b902efdd0b706301ff2286c23a769d65555bfcac138aa6e3e175d27a8d4b21f01b6b760998b80c2190f1d21130f23568928ca7b10614091dae4742256bed806433815cd1893a9b1ada7bbd953b87f7bcacdb24392f83db348ced8850b321ec6bbb9b0605c26d36cf968d69834032ff83bd4f1e21f9261a770d950f4d1c1cc26f8fc231d93e984cb2ec181c6e3f517071663dee12cc0a8b7dc4053dc4465a86b12bf851067121185a5a62fe22ef9d9f8e7aaa1cbc538fac04bddb5bb601d428e30b043661b7edfc96b44d75b57349ab4ca22bef60ce90bfc34fa7baeb3355d09029889a62e8fbb2c416adc3e4a1a9afe2b44f3e872543b840d0a9d512e5580659b2d6e6738860720e2be7f7358c4853cf5528fc4623cabb04dc28c00feee35697a4f9373b454b87f59992d74a519582aa49b528c4d3686c06884 + +Input: 90b9879dbc421177d7be19cdee515dd09f62f6d712b5211e48d3e56a51c9230513d59032ebfdf060b53b8fac74c8a297a950afbd7f51beed8c072cf6f3ddfece1f8e8e8175a158ae6f3a9d275179a3f8194d5fa47ab977d244f1e51ed01b497196d66cb2efe5b47998a824906d5bbdb8ddcf6ae175b116ece27cca213ba32e89a272b9e724362cdac508b1540f46c1d593b25d69f387949ab208b7dc1836aec2e3a86af4f5ca5b1ef751693e70d23caea348d025d9c86f456f1c353b5fc67878901db08732ba5fd3352b648533dd13c67f30cb7b90969e05c78fff80103227fb56fc30a8e41589427fc66c475e3a5ac3e2468dac136ce46adfc5c85a96127e32dc7734c5c2a0a6e6629453f2531ac48342aede8f95 +SHA3-256: cdc39b97a1f24eb7ad02cd34a7ae02ab6ba2caa174b85cfcedf4002857c467f8 +SHA3-512: c08684aa7c3b43707e688ab7a7e88a607baba3f2ef6f27700d9d6bbec028cb35b651ff4ecc873af264b1ad445c4382f003645aebcdce0e9acaa38ebe5b6e3d8a +SHAKE-128: 464545e0eee1b6a5441917053e967bc7c11025b1d36ebf3ff37031be6554c5dcf743d8bf66be6923f0e4c92f728facf74bba01dc8fa70cf36f33eab6d7334b2e4699569f2b3ca5ea129b0517f2db562fb090e6c4c3fe6e06c9ad1922f0808412f49d4d7e292cf591f3bf5f6694fd8f770c456b0fc5a5cd14869f73aac278c447d3793b5e92355b886a2b0e41e9d4e7ac4007207c5c15deeab218e4e4200445068ca6e981702261e7a318f39040a75227be8a4f760a91b85e379df3c4ece2cf21c2813cbceda206d246f4355f038fd631b66758f23a56afe01a52e9e5830aca65200400e59ea501807d0b3f0302a2816cebdc9dcefeaf5fe07e0c0b6d969f25a7e8974acf6771829cd2e3ecfe158eea2268d731922677bf2ecd74d46c66ba159603ea93c1b1a7acf468a8bd5c126375cca2394698edfe5d797e86923b67fda053f40b76f56ca45c516ed62516ea3a379930db7cccc60f60a7718fda472a299b5fd7a844332af0781825ec424a246034827445dd9e0b83306e9fdc1ede7b31bad5e3c3b3e4cce93810506767b526659473b97c4b7cfcf42b31d90a0c40a9c374ba02f191f58c5754aa2ebbc80a77b76622275c3b12d04fe729a2bdafe4d7c696e642cbf1434b81ac7babfb7efc18728c62d4d9f625d5d62cf5422f6a7a3880e8111ef6ebd9c5b798149930f93b765a7f95569340fddcc1974644c733b88789cb25 +SHAKE-256: 7073c700ea2653cbb3b30a49e0c862420e2b8653d0bafbb8afd537b06e044eaa241668753fb87573321205fc0553c85eea20e17c53338186d707edac2131e81517cfcf5c9f6b7f86a7e49e131b78b479192f16945655bbf8afc2ab126436169c699701badcb1c6d744095b20894789b13743e5cf4b7dd221e0929332ef4b583cb1c4d825a2036189670c9564f90eb2dd5cec9abf425868bf0ef5fa0e1b2bd7b4cf0df3b07df0b0f011e85d3c9605fbd78feb0869147fc825b443145a0cc1045eaf1d7ab3398fdd3e4ef2a95edd659d434757f68932f8acdff7eb0fdb20f91a13d3834ee696d418182fc93414bf4f04f4949bc4457010246332a157bf10a53a7c8a244d973b04e9bda80f28ffc88a6631000921533f7bc1e34e5710554e294adbbe09803a073a639d30b974c91b56771f128c8d1ff11028b469b9847e729c4186401a85c63d7ec12ffecf1af1a7f496cc058072490556731f62cadae959a024a49314260dcc78f13ce030bfb9e3b04d5d2069e95b4cafca7e2b6d4defee75e086824971ac8774c569cd6163cc0bfd83b6df0eeac1bdb139c1e205e91cf8859b21db639af4cae76f1c265449f8ec556e62d2fc7b6f9b4abc3f109bc9f2f96e51e2058e5f7808f3b00aea72813a789f8b38f79313cf5e594556422c62ce54e410ce136120eb05d3536a710b3e995270b20c496048b6ce7987ced61f8d56112d8f5d + +Input: 81d5e31ef3c329fb6b03231af5a2bcc4d22a551d23defe54db9dd7b2c2c6d47cbfbdae2f766201694b7723ebc6b0ac18e595be42f74dbe65460e8ecb3abedb904ede81a0d847c09910314344d9e368ad9da3cb5e62c3e606c55139ce65281d0b822fc6b23335da2eba23392a43b2eb4145d48b34128b5ee1a3158ea78c39c38d04f2383bdb41a1f1005f5b7d5b86bda127b964eef40160c669aba8bbcad2ffaa2c3c0288003b82051df80fd86fbec2d4b6adadb19329fe968ed1d40af932fc9c8c90b6b7558f5370f6e69c44b898d9a7c189804a330b2ced2ee313a0b2f44d9851e38d43efdc98e0ab307eb176be17c70262f780d2bd994e5373acab89ee9e101539e038c717eb9d7a6215207bab2a1bca0fefe23cc6 +SHA3-256: 8b609669303e3c4c23139fd4e4c706516cf38d890961e1bf706a60d63c384d01 +SHA3-512: 91ad72d6100448d8ea2549765b6efed6fa73e063046ea586830f58cf2c2474f1b8edf6233d135ba1dab9462aefbcf5c5fc64062939b00fbf5306905ab9953a67 +SHAKE-128: 193ac16aecf1a57f263ce027a583e23724ec095f7690b9b475898e78e0558bd7e7982381298c02d7800205039d1b18751ff7e17dc3e3c170b884ac2a4f552a9ae77c5e6d60ec048eb445ebf8726d55f17ce0c18ce9b79c8c426ccb0c37c3edce5bb6884335a191b9bae0ef9be7ad130db8bdf66bec1cf15c76817d7409c56fa54c806cbc97b5cba71ab178e7742b4bcd659a829005775b4aa454d8c84ebec84f407713f0028501e10842d1a8809ad510adb4e6d0c4fb02f9fbe59481e8e1527028432766602c4263b57cfa552225c99615a9a50c90fae91dc30d22529614a43b72ad57e735b4b329cd9066873712466aafba1af439bfbbfe794f15aa4233705216b6c0575bd08c98e14d0d36246196a990926bc328504b0938bb27c0a307b739e09261f78678c8d070babc32c9d44a0f765c03ab1647b39260ac9196cd8b31e30dfdf9ca36d6d9b4807e89c2ba0001461eb35d7afff07dfc97675e068da86b5bd92198a99e18b0feb672f88f663762f65e0ffc5fd6f9b97ffad3dfd12c5f6ca0c5062a14a3473a178e9647772600f8b51aab8da43453a7c1ebc03563ca4982202c35467a0612c823b8a3882ac79dfdaa0d8ff8e6e4b462847d7f4ff989b7a5aac03cb76452f26fba02493bf57d5822d4ce43d41afecf1755406dd053113dd77e3109f1ed2c12bb9335ea5280485fac2935fa130ccc2407df565a7d7d142174bd +SHAKE-256: 2966fda3b1471db641149a3be0e0771454acd15a5da691ab3ee3315a0ee8b763b036210789dfa0db39b79efad9185b4e2b62f16efeed96ee40bf27bd0877ebb4edc9924f9313694d9f86353c819f88f0edc50853db5d1c9d4de91b7dcbc9d647d5897918c5ebcf9849348c7f850e5c64af64cb326d4aec23554660417b85066c7bfe2a9bbb9cb0c2ae731d7767a6b701344e7470e181202dff18a5b61e1ae069610fc24a7b04ff4fe1cc78f8bac1ef4703ea2c968aacbb696fa29e778ebfc2127ea27a201623ea38804e9b66ac9434b162335d806d48eff66772f901470f99843b50ada91ee3fe8a881a5217b4c177ba7683ddeec1344e8059c91d649cba678815d6eb78f7c70c843ed6149400a0e78b249da170dad15782600d7968c35bc45193f37d56d260ede5cc073a0c650b9dd65f28e55bd16fa4d6bc6055d4eac00ca57a4b1f9755bec079be39b2af5296bc42b961853a38d2c9de452f0d87ecfef48708f3c554bf3ddcc731c6880087da91af067eaac7662db150cde24f5ca23d708298a6f54c23a8bbf2760ae9e83a5fcccaf6f43c9263a81d9aa3493c1e40dd2809a1ddd8c60f1ef2180db89bcb5fb47e8f97ca1ad5695d6dd80c923a4224b22893064ab93b3d7e75af646cfd47ba181343ecbdefa13a8c4d7c42daa7e6477828d2d75b47c7f6fbf6b40a58cb5998e355a709f9ba20ac10e6461bb9162828ee60d1 + +Input: dc4a9ee194de6c75bbdd2666ff40460c797ef348c9e1ab50dc458876e489ac1818da76c06e67e47ef6b338d3c23afca82a6807857a05177f0ed02b87fb342668324eaddde742772274e3b138f11bbc7bba97faf60c35f6b46ed3ece039503fb758b117b54ae6d143643198cdedbbd3756654ae444084518c82382e9be84bab8f9b3bceb0734186f29774e590942b48669e366330d84a1d9b7cd2f50479f4db632d5e76a2dd24d84a44f935c6dca0741c7ef29934aa6c1ec27352203d8dd6a49f3f7695bd2ce2ff85a4ac29520fb0ee8dc4f58c5b266409e7378a6424bfa72937dc5c71d6acfba507ee962dd98c3fd905e20ae503ac83b7b0e23592136046afe32905a657253e5b9368c3a484953daf3c1c3e2d79930e80 +SHA3-256: f569ad0fb31ea98fd72c24f17d0ad66cd1dff65342e2a6fad2260af5816170cc +SHA3-512: 0576a47027d545b43cb7dc6e7dea9027a3645beb00c161c9967fb01dd374290cb822c2f78f6f2deb16af9eef18f1f98dde644d71b73bfe02759f46b4d6b9c215 +SHAKE-128: e2a1e76e3b3c11c5734d94a968625ec28a413cd4fa98e5a86f2db3e1f8cd45b943a399129fb65c0706f0b059ab874449785fac5fc5a548c04bb1d493dbd7c12a964e2603bbcb6d08b0b9378b3ca85c6627893edd55f8ac33d40fc5d521446626c46c53db8e78ec67b1b5c2452bb7d2ec303516a7fc1baad537b46aa8e347d449f99fb125ec0856bf4b71df8489847b0dc389ae995d78f4a2b94b8ecbb68b190de0d697915d2aaa44405a4b3c70561cc62569b6c731bac93dce35759cb23a62e8c82a7ea1d50622cba0e14ca43974b0e3cae09bfc9ed5f689ed1d1c57046ec84f4685612909315f97784394a44bc177a47263be69fe1eb5f6bd8fba5522dfc946fc382793a4bf83505d648aa0afa19a393d8470c87b22faac8f86653ed46846b7531257c354fa996a3ca3d945f82b807056cd09554aafb10309bb124b00e04db325603fe9cc58a2d23ea7feb764b10b7f5fab4f4f212ed90201ba9868598e27a2ffd39e3c089afc74461816b8ecabc535277b3845a7937fc5f356fa573d8ec600f46b108b035432bd582d838dcd2163b37b5224c6d93b77f3ce12a196c773d2d28807b4f4eee5f993ace341a3128dc37d49b99256834c5d23b56b8fd2d0e6c08b9cd728949fc8be6b697016b5eb95fcf7a492325788059fd2e3040a03912885bcb2f3c5eb8a13cb615c2478f7c75404c32c9263ca814421212e2a66e4e1ccb19c +SHAKE-256: 485165582c06bbd80607e83f429c3fcb145dc350c37833a52b455e2e7b6731834e422cc98c9885ff2029b3470d23bb670b543179e8af239c5856661f63ab7b4cac6e8f961702323d8e485e934a26e44ba336e27a0efdb48831db9780f69470594bb9a9c79f2b2a7e16d8fbdce3fd6b0eaa08ead854dbdfff13e4bae5403a91065242be572f0f6e771ab4ef2dbc7301dcbd506c79c48b1be983b3e8fa4c963b31f22d7059bf556dea05332feef6823b8b70bcb2c65e42bcb3a05e80c01646efe6e9f79a362bde977438c7d94cbb468874cd885bf14fa2987388acdbbd1d79dcd7e5ee9e356d8373b42878bde9e39b3fc273781e02e0ea8674e4ff3e734429df701cea95dbcd266c33aaf01382ce370e77ade2508bd157006de1ff6b0a412c79d43fec2a01fd578931c38149aea3bba5da580f61b146ba887ec2e8204204bcf9cc60cc33f524c79969d4875cc91c0b9593929066210e54b3d1f2b79ea612b9d64ef16c69a30a018fb9efaa940f804f7b4b4590f92624282c1b21618d16bfc6a8b77371f5967dd0bd117fc420455a672df7ac482d0119c196b44801612a5121b7ad7329d8d1e6a853017d57fb826eee6ee3b97ec47a485b85f725274606d1003ab6ca411fb1a5f77bf2cff86cfa2157b0d1f791f874e7de92ea62a1d32288f2f92cfb309759c011de3a70ccb9671c683dbb060bb47d0919ee12e012d7ef8f785f2b + +Input: efc3af5126fac87f8b4245b2ba4638761f115e969d32f3599151356ea2de3fde638d36ec4e869d4cf6ed5dd3dca76ec37fad19c19e26517aad60e0085c1c30b8732ec150247494ebae5663bee8c63e987d2d7b123a75e95c4eac8b37f77596a22ba86a9b90ee00fc96c09c9257c2daf7f504ea7dec6ecb6aa369801de3763d29c1521b04cf12cf5dbe5e2c8f5215081186f2a7b8076070b21b9d2083f2c89f66851ffa9470aef3b400d3172d3d7404bed12400ba80da86b07475b6ceda17d48a402a679476a74ca3575fbbeb0ca5f2e81e2b5b75c780a75ff972802a9c655e9898586edff5bd2ab61abd795882abd91a0ea3d47733074cc762ecdbeb139e9e5d8af39ecd38027fa9585143684989677b192565bb02d9d398 +SHA3-256: 4624d4a1f65a104d93279ce2659363f63101171e0161bb0fa3f1f70e33b430bc +SHA3-512: 667193d3ddb9b25ef76f269ffdb2f3c7c4eb0445f7d07c6343d65a91c4941b1d6e656e41441c93c8cc1fd12870c1ce4aa9b5eac80347cb09aa16cb5c1e33a1c9 +SHAKE-128: fd661201b20a53745d320c2384d4b9084051bb602522788126e39ea94b3f9abc2987805eb45d34fc7c9de1205701e812edd0eeca111c26bfaeaf0572bd9d7090ceca8ccb7b719af1ae84366ab68a34fc36bb1d1df90e6887c66a8d31fc03c5e07cfa5f6a77dd4b1a7080663b018cfaf4b0adadfc9e60366dbdbfa38ebb529492ee472eb2797b79e3784c2d55a9e9ee72a87ce97e5f779211804112c81a24b9ff157186f91ab057eb49d1e788908b40c7a77e6edb1d36667987f322ab32ea27a4363224eb361d06e4f927fd5ee820572fad366574298c1a8c116a25a051a8834bd243bb7a4752d625dacf3eb6ff5f287d36a2f0323246e7a7e07fa9fa84d16c5de8667c3e9b032ec2fa1adc9ce327d981ea5bab8ba6d3dcb2767d8f2c00f14ec24f7352b1d5f8fdf7682554dc15ae9a99990b837f692f159526aaee63d089b7f51b1c0518634413998f3950ee44252cd7484d61442aa1b74efc040a9c4c011da6bbf4d4b59ff4f798118c95905e10af4719db31c22e051ad491795e168f967fe3a817ec0e43180e318bd9a65394632ff9745f812237f2db623a6b97a4c66242c6d395da1637c89dc242ff6cc9f575cb98962469a5a2bfded2f09f910cfc7538aed13ee3ef1424d69b1d4444253e9b8e9d5710320265a901258beb66a434f7ae013ca8996c83f84690aa7bacf5610879cb00a187c0dd9427dd1b04de958c09da8d +SHAKE-256: 33d8950a0fc29cf0d7a4bd55b1d6c1fe240beafbed647d2fe50b4d6b90066ecc0a9b87de9461d65e4e749f7f1adc11b99dc573846c2d3d6a69cebd479b83b2706081a7cc90befd49a0f0ada6bd527dd0ca7d3fb6a3dcb0a57cad89025f1b26b75661a6740a20364c22236a327f050203360632f0a7046b618892d9f2cd9f98078e652a19e766fb764c1623e2b207da66eb618560c90320b2668d5033a5cae5cc3a84c62d1dbc84b1e27ae2a69b4cbb0cdf3a2058845014749d1fda1f7f617c05bfbd66d8d458a9aba85a9bdf664b39623beafdf5e13f4126915251f1b70b05e30020c1ca240b1db33b78febbffd7ff1eb53ea04edc666b56a717b972171bd23f42ad78a9545cb2b48bd072988477cc09bf72a351e6e443f042f63bb249a27cd2e0099055de4fb3f2a7b6205410f4ced3bde016b58e43946b4bc35d16b8efcc6abb422ede02a15e3bae41b0f0711bd0ee684ac3b04c76580e87350a8676f060dcbf3d24b7e41c9bd1ee27c5302b21ea8ee678e939e3fe806e8457829902330f9728cdc857a7a6433ced084621d5f1686a8b1bd9834e62e505b77f59f6ec4e41bb0d8596f5667b0f38e858bd28d326d3e6044ee60aeac5f1e5d449202c05180cf5768066e057ceeeb9d00d730ad31a4b3e642c19507bbb55db0198f6d58edbb8c30c6d24ef25a4ea8e8d3d66d9c1ad3a231707a734cf5313dedb3117fac53dd1ad + +Input: 982d52f8db5b4508e8189d045b135ce76e82265ac654c124126b97385eecf167170a8e2af284747b8353933b00ad8822dd5ba238d4b7cd11ae11078b575a2159ceee555d65462d57c86506da009ed5f28616d6c079856f5715619bc750692a26c3640756180a497b19ba43922b2910ba8c2fef0c3d8580442539d7a410b4a653121845d90efd990c348d40ba2254f9ebabe44908ce316f5eff8433fa63e28007cad4fd404a7f2252be45906a62e8962e7eaad9bb0344940096eb1bbd13bfe22d45599d7d1b4687bc30786c0cc3cb179d59359983f2734a36bbcca50034a44946ccaa2e978d35e42679bead2711db6e2cc1f1f792fc1fc57323405fa2454c55a51af38a51b9c296619222efadce9998f9bec8611de668e12b5d +SHA3-256: ad5f76deece42299d761cd7e7381cc5372fca0de6ef2cdfdeab1a820acf22232 +SHA3-512: fe9dff2529251a4e420f6441c6e2b1c57138053e991477549ee70abc6e9c4e7cd7462bc3ceb290b7778ad9d7b674221cf51330b5fe87f45d39d9b38f4f91330e +SHAKE-128: cccbf15a2d7024e27be1696fb0acb73eb939abbcc65b6b2e0e9a72e1c1a84cb8e74da7fc78891ac5bc6b3a1055c7198eedf8101bd6b980d19c89099e37987258a5cf832886a18a68b3768ee286613ee9c754f047b218ba44e2fb85f327e695c633c3c74b08c7a8eb9cb4d78c01fb0ed1d9d23e177bc942c9e2db2ab64bc2589b9c5e49795e5536ff179ee83bbe3f996f27f459607dd8e0050b43063da9a75d600d92bc003da2dbfffa316470ae9776221ba227eb5bddb7b5bc6dfd9f07f9cca7ac4e78fcf8c414bae8b8c408fafe701665fc8cc30a3b91230ac66554487bc5feec9e64b26e203e6e48ede876af8ed22f1ad0b9a5e160e1638f26b52ea8e860082ae285d4f67b8786bf2fd4ed80e4fd437f94b2df623299ebbef97ccc4fd7249257099cd4a93486307ab5527ee5661149a123284fe8b3bd96a1b0c475187142eb29f7cf56d5701d47f72d30f0942146c138fdd073a2a619787448b10303e965107bbf4615605802fa95e91024a1e4701e7b17969f3112a16cf562d488bd4de95f0e1c7a20a18766834c3cd58ec7c1fe49414077e4ec24caa6434d219569ccb54efab5367da75ffd7ce3571a1437a0dbee1e8d4d2f2cd1d87d917ecfb09d33a03238a3d6f19e50bcb2fd173bb7f45f0846cb6cebee818e62740b20edd3aa47cc0dad3c908c581b59e49f26c57e4204c87fa4ea2ff1ebc861b979fe5985938ac149 +SHAKE-256: 101cfe9bacd2831a4b3a6158f72fab1f17db9ed21b8990b11b36ad0d8e34678dda69fe9bb3cc8cd51d0c492d9763b1bb6318da9d5b3a4ef4b915e421cf41f0fec3da01da8dd6fd2a7329fc3fe95f951ca191000c2173507ad7f98c119a4add043d5e41ed1439506da87e51e3c4991e0a86cb1f6ef93770b30522c131b4aba3ddf5f46fa507f869c9226e89d94d3315c60ac89cecfd1e493dd4c0d3fbac64483396c3c5dad300226924b8c6f9949845b7a24133ffb42e165ab76215205c0c8f3e36fc4e1997205b09f3008029f60820a28f21d8f08fc9e5b26f20b67fbca1e0de1c0c97bc48e7eda9e43c6dcc7eec7b6edec93081b7ebfcab874f6b4678c36c7299e279cdde7388556ed4a6bbc601034bad84637eed67417bab5632a6d8e6a0647dead8d68096fe5963d4fc30f8090a900ebaee2f50c5ab2badfe28247073676620c606bdfcff216d5d37f8df956a546e63104791156bdba748ce7ddc4da82bd7eed66112b86dc8f49b4ed64e723edd6fd3f5ae97a614310c9043c1d3345c3ce6fbd35d91782408db5dce39c43115be349683e8a461045d1a0479ad4d729fa01b8d782f04f585a6537e3a9704fdf92dd7d9f1a9b848524c32c8ddb12c800872413c9e88c78926512a0b2d3c5507adb77525dc2e974eb62b05402262def7d86f6b45c93ad8ad87eac2c82f9bc507be4fdb58f49b3ac0bf99ad93b55d06d6d15ed8 + +Input: cdc7d095efca120d007355a2895b66875c9cc22441804351f2fb09d7d90b9edfd967c35cebcb29d6c1bbbaa8dc69af061693717562151afe071522cedf04fde0f1c9eb3f28eac894b73dcee5f779bf9596920419b5b78209e318149469da41959cdc8f2150f76c846b41702295410a63816592cbc7c08845d44711417494e102b9efeab8a43d8e32eabd73db46470002a4ba6eff8a76e23986ac333739529e4bcb33b065c6886610030ef777efb1593df7394f8e0813a03c107b23f455a34fd1db3c82386be2f885931d8b71c39f206fc657709040fd7e799339e934bf671099efaf6db4633fd6c7422d66995f27b48642a528a7b7829286b683613c74f240cf7cd01607ce58cbb7be61a548bc0df1dbfab32f95e9037fd16a14 +SHA3-256: 0b48ddf496d546e2e26ca3872a026073de4acab887a09cec2ddc2d2d5ae83f73 +SHA3-512: f0efc092d8483f54518ac283350d0e3c7a99847345fa541a1c6cd0e49224c7326c77abed931c6240228c5c6ebb75789a746f0d20afa368256c0c9474173bdebe +SHAKE-128: 67174861230db049a88681bc7be757f2216fe519a04574d5bc822f18c2e82e677356509bf3f541e1e5a1a29767cdd19d815dca663303f39c9daa8598e85f7100b98c041102d2ce2fb0ef17233ee5b0aee6260899a32900ef7e328853a136d27af732f2bb051947fcc529391016eb12def1fa8ab82dc3c4757b703840f7765b49b7fe66df5fd4f200e619158ae78201dd5c5d9eeb1b0283618bf8a54a39432ca6445ff593006ca5222c0e8f16454dd10b8e80f943e279cbc4bcbca73930340f7b523b71c33800b46332097cb05c751e2f7ffd125c3f5acc0972318b849df72ca2da1f4d3265ae1cd7e40bbcac57cbecb9a91bbc8ac67f87fa52dcd789e69a44efe0158f67f6599b5675949aa1d1e9e821e31211fde863ea6e5b71b36f5cd927e081a36dceb5a178cc67a89cccdef82543d2de8bc64d70c479667a12273f0ac5814090fcca026679258d83d9218202f86ce94b4593aaccf34afb1d3d805be2f1ed37b0163aa87bbdba93881ecea6e124036f8aa9eb4c07962bedda4e87c0a2b9951a6516906a1721ff7c316bce5858c072753e8854ba5e653919143188a0004f296da05d5975e7270c77d689d4f18f9f2801d6c5c344000d9a7b5c91d3f357c7369488d1c7d1f1029e9523e20e4ef36adee0346cc8efff55826fec0c693b5018b0ab190577e2d44e8ae09d02b17f057d16ce3651b9493ed1898f7669ad23d462cf +SHAKE-256: ed7a69ccb1d8d51e984d8212ceda3572fbbbddc118d26d862f74675eba3876bbf3fe7d3f858dfdcfe90a343372eb6f378d7b725c15e183b82f1ce7d1257a36e135130fc765dd8d17ca9c1dafaedadb7a76452721e13338a1595e8cfe37963f4636f3bfe72bb4ce37afb1ddbf9d783bceb5c1d97fdfb9c24da3ec7df488fcd05f3d805c3b7e7f5662aaa5f41e686545020431b2aa5695f097ba83b9e8c62ddd622bdd64888d4887521450e4967dde86646a3e9b1a5ce0e83f7acd27c078a1e33cd771301727e497910afb8e4542c4f842830830fb707646a2a039ad5c084e63fc36cffc2923c13f89c987b92d0e4903c31b629daecfeb7b2ba7f752392d2ed9ba2300787daf30b6ea57a9e1fe828dff5ac320e050dd28ab51342f624126ff2a735f2ce35fcb02f0183acfa28457873d2b42986528d3aa03d1652d4d3ede3bb733f6b0f51e9ec3727d492cc370af58cf7d8aba4d2b5e7d5ca15f18824321bb7213e441ff1180fae23c9005f9590a7bb874183b6b8680fb77f30cf98f5448da12aec7ddf921659c7bbabfc4853e8c50a8240f6e8265099e9c199a6f29c6b1bcf7053c36e43e980ae4f66a252636e1a87e4ff4f7677e5d25a2d89fab0911e4e21e12249aeb8a3f291179dcf8d3a5e52eee1119b6a67235370ad0baf9bd48d5fadde24b95b7d84909a21cce4300d7ec045daba4bc49b7b7deedddfcef9a0d76079008 + +Input: da4b2b8d854d4b7d4ca5d5a6e1b37b6536e365560466405ae17d37cc9b66eb6b93ddd0de81847bb438db1db4467296e3769ce81f409d8bc451e1c131baa4a284a5ac15a96f2750089315e0bbcbe1c8b222fd6c1f918d0b0b2bc4a0240f9283cfa7feb83d7c1412ee348816167bea1ba0529f89632cf176509cc7a418819f128dbb6eefaa61726d1027d71704f9f8e63e7255e7fa444e5acc18ec0569947eb6bd6feae20514d702ad6f3d5b7b0830ecf11fcbfcfb0c2a4dcbe8cd996cb4df23a4b15bce66dad00f1d8296b272415bdb9a49000e903d35d9def2b9b70ed3bdf7ede3bc62724360c792b689de1d897812227cd63f70b157f690c1a887e32177b6df15e06c6d1848951dcb8c86102a7b246a84799186f15c39ed2e26e7 +SHA3-256: 97e0a7596c47a989c1238b775085b0662ac68853b34b8867202dfc48baf63d6c +SHA3-512: 4d2ff7f2dc60b947c8d6df387c14888ed3e44f883dddae2ad42bbdb2146c3cfa0dd8b7508937aaff71038980abab46ccde72f0d6f3c81183798a5ee3464a97fb +SHAKE-128: b683ec0f6237484a26ebcccf7641b49fa5812c67d53d508bf97e58d044cab18a044db3b827e986e479ea1d2ca67660ad9ffae59d106de4554e47e26190a3ed626783b4d07e28d52140be785218c2e7b854bda8800a1111da9ec96b809027dda6763d4f0d08288a648afd8377dd6d91f553fc9595c056870887dfd2f1ca31d46415d0ff3b4518578961a79038b93bdf0d687499a1db051a26c9900767d204a5f9bfd70ba343b0b86b872fbf17124a9c1b997ffe4c2aa2a8f5eda4239933d435a45ab529c6ace427658ba083c81cc023138a0cae2c107f8b0308eba0706cef0b62eaa336db00b3e8f3bfa5b148c642246990611701e4a3f39ff09dccfcfe43b23178ebe863a5a96e7d21a9fcf9b55bf59dea794bcf70e3267470e2736746ff39de186c26af9194a672ad79218c40db5a37bfef7eee3b7927bb7126ddee867bc727a64b92a7b59cc972d10881377d97f9779977ffb3f6c2aaa6aeebdb990933c654dfbaba599479c1ced6529f01de2cc630634af8a262cf9cac590f904027862d358692c8496be501086fcd5dbce19989066e3f61210046edb60040492979306b545747d3684818dd8f4a833f149bc37a37d894d212df80a645db9a15a74dc12da632c14ab090698d88592c8cabb4fb5283944fb7f08537b3a06028b8249e8ef67f1d37525feb42d61c40332e3852d134df8c5c921bb1e16bbed5147025c998107b +SHAKE-256: d2c92915a0488edfc3b4582030ad111b03906d374b0e22b9cc3de998e093bdc35539afbcaaf9893d211d2a73e817bce981cae26028f4db5a20b294f63f149ed0816bb3d28434b01d3eb7a5852097d4b06f830d7700b50d63e8450f40ea07a83bd24fa597bc23307167182bd3c87635ed386a7aeaeaeeaeddd7c032d3ec0fc00bb2bb7e190ac791a310e3758e6d92f14a6178bb5737c3dce0d77ec51da09b8642c51d5b5ff69922a0414a83baf4f7429d4342b9e9f284a356d2644c43ebb9fad6b27a6fee942c0e618fb645e109548b2376eb058e3a42ebcb530755ace8ed32cfa966b903f75b439feeeacf44bba3c28c9b4e2ef016ebcb884cb056a34023b3e50fec85a3dbe7a756aa15eda6d57a9e427b95e78420a00266ba5a50e1a8433bc1eb2a9d9445cd5d156377b766fef3b106e04ace461c9754c1dbfdfb969cf6536dcbead8bfba49d1c53dd61f7a060c9ed49a9efa8c3e1e6be41b2cd6a54ff4b43165cb07e254fa3168d4c485c67418a1eb63cf5989a96ec232d3d7a71da26dc3d1b0ab4aa5acebe22fe6696e9eafa030c860ae63330ebf58c5acb03500f7c0ac9e3a3da7fdb97b9f417478edb40d267532f233cb31f40823391c6ca20dd7d58873b8c00e4393ea471c791d9c168016bd4c7ea9de4402cbc6a9909115dc6921e19f8990880e28f01076d6cd1f25efdac70d44682bab317a9b723c4320c0a983fee9 + +Input: 40857ab5b4749e0637ebdae9e087d5e8f126904f8cb613d10c5b1023b9d6d6e4508af1033566a0fd75b3107e0806ee13b31659fb287633ac093d19cd58480e7273a84a5a59ea1966088e0b8f6bfadb2384730028804121896a9ca5749438bf71c44cb1b585033c43f9c6797620cf890ac7834d10318e41c531a26b786c3fb1ddc3cace2ac8e73680d1336e1041450d48972d7db2294f79f03917ccc60ef6be063d92863b283a0707f1b78d8edb7c27812e5a0e42a252e2be578123cb870be64a49305a323891434f79c4aa1d342a167c88722fb3037f72dedf5db95b0e6fe337c6f84a0d829511ee574a190e97b5ea01bb1ee9b9d9375255939aef09c6a1ab9e7574f35a801f4c557f00641bd01ecd4c30488e43ddb7bc07af39610e +SHA3-256: 426af9ed8ec779b7f7d1ec165b29c6405e79e5bf8072116f45518cc1477fa055 +SHA3-512: afcb19b3acadf18ac91be9eeadc2e819f359e4e485e42ae3d52e90487b66a13c0e7d694573e32a815874d258c6e26d593576c149fa36f45a608f716604210511 +SHAKE-128: dbfd0ae4fc3a6684023c5bd87a05d5c14f94a589a443d83ea08a6dee44310464bfda51b5e4e3beae037e6e877f568b3267d91bd6c6f0743a1eee48dbd8f2fbd6b495ee82ce8d621477fa5ebfd21de7807ac68ce700acbd34922a575490aa4cfac6c97ede9d900336f06bf34e81275819933f151cb8f6b5a6a1b0548fdb3775e4e5c032a8747c588efc940ded5b052eee71723f843f2fcac53f15a897bac1528a10e63eab401b794de3cf4c4fbe8da585e41bbaf89e8fc019eff0aeabf69f3db26f0cfe180ce4aaf86ec3e1671a7d54a1db658edbb6a4932c20c34f523a0e59adb9d8df3beaabfdbd4b02369e3e7ed51cbd1aa8024c0d91f421ca6080ac2c78667e5924a3bfa81a75b1e5769beaed658572438220f54cfa2c857c434082209a5b570f05341eebad97afaeeb93e3851a5fdf52652df4a4381c37019f79c59c7bb52e497175b3f1423f27b37a4d0c046094fc5088a328f3889029540515253508f20aaebef0c5c652f19d5a45f0e9822b56a746a2941b58026fc06917a76bb7c515edbdc9a4882cd78822ce84f5545205f97ff3c0c74438dd6381c3e7b8c6dae0cbf63212fa978cdb981cde0402ddbbf694a94d6d1fca014608680142a2404cb4f869e9183ee83c2956720fdb27058106fc8b06fb24eb726ae310f26295c3e5192404eade63f20115c8c01cc06b2f5400b1cb7c5f953aa0ad10fce525a4a3a3e5f1 +SHAKE-256: 8b7d0782814c8d5d918d7b21fd6a8df0c47e7c607c7b55507bfa7f59282585d138d6bd4d0e39b38c5549038d0ec22cba09251a9d32cbd28aa9aa5bd559ca62a7b57a5ca5d4bd46eb1cbf990e4583c048876b00bdb21d979fc91cbcf5fa8a48d1b1f051bef726ed5ac6ea369eb6f7433eb09f6d58959091496f5966dae57e8ad3e8a6aa890e903978cfe163b40fb1b378a472866fb41bfcdf8f6f64c01a3c350f868db8d5d1c0e42a886cb526d081c0f91c932c36428ada7aa9254d530909c7af414b818e06a553cd5102f8c910dbc3578edb07dab74630956a546a6ff7203b374692dae40aeb0b402a7990b3406cb81b8b85bb98fdd491767c2876fee5ea2dd3b4795d159abc049e9d2763c07623026c2425a86dcced67fe86947db44986f59de69cf38a6344fe75bd002a4a8a5ade2743aabea92306f5ad1e81d590bc53190789655fa60e6530ede5c69b100b10a393f7763b46c24c60a19eb503fe79634a4301023389ac1f875e0736a4638b56edc73629d1c45fb67947e3cf2450bad1c7034a3caa4c8970cb1b4741856b5ef3c021ab5570c90aee5edf72ad86bb3b2ffd8f706341df08e4e38812a821eb3fce9e0693217406ce5ed992997d0ff0d529385cd15c6f689c3b0b24f850e19876d04604af386f72a644678eac55b1f8fff7802d07dbc56af17c292fdf6afbf71042486d1691172aa1bb463c089f231c6298bece + +Input: fc9087e76eb6d3d084e801aa83231e60687b9c3fa6d04eff6945480a7458fe660fc0612ce552c72f0090ce99083043b43390a63b351a081c0e2f089a8fd290b9e4586cd199cf9c90f1b86acb9be31eaa78ae32661e2e1921b7cc3c7977840bf36e1ee9bba0f797dfe456a7bf82267ec396212651931949b05b81895e76135219f9bb1aed88c71495427eda3fafc1dc4ddccaf7be43043e82ad524402f88fe2b925524a84da14a99ff1624dd351f8eba7b188e6f354048972f72ee5f3600da9db3c1f573c27fa1d95a7e5c2c9b233e61202be878e3789abb1c0a5d62182497c417d1ebc153edfc0d3ba3ca28be8e0e8597d3a56adc1c96ab8af4af3eeca441e8799a3b85691af7f29144cc8adbf391f800e71ba926a575151d24c898f6d +SHA3-256: 429a35c46b9446e852b2ab200a426ad3c83001608badf0cea48e67c066e44001 +SHA3-512: f70f4d8286e548bc52b4c0b1dbda597bc35cc4af0b9a89afa82956daa1f617c9db9c913891f9bfda8360a2bf9fdb458c274463526e42ddc36c36aa916987e9a5 +SHAKE-128: 5b015f3568c2cf39f7da83058b6b89b96379e94101674d6c6370e2db5dcc86c6ae862b8ac8cd675274604c796770c25ee632b3790e15793bf66f0f92c2af18ac92ca2a3d648303eb74b9fe7b42454756dd213a0ebc14c4d9f157441c15e8cb1cc253a7e2810428097c310f9a7e052a9cad45e0f2dccfcb388c3a534fea7e3a9be6c9729eef9f2e1d7ea6e1b3345eebe4f8821d246ce252035ff4352c8640adc948d7f83771aba70fbf4baadb0d3ae6d88e1da3496d4ce1d53d89e52e3eea46af04d01d809c3ca5d0aab7f671063a75d02df91a77113c3011d108a2601bbe88856e9da62cccf7e7f3db66aed7cdb4c462b4afd4e65288b5a8a182eb7af82491d1e8042e617c93f847aa3d86e55a3bbed77c8fa4813f82a6c705d42b82017e466964b2ab5da536d92a7248971f497fda6531d36d0a7c2065a600ad7803b2643367d90e976ea54f4be0cea31655c5fd88b0bb842b9c7d287b3230e1b3e1c70ca32dc56130ab095ec3d1bc7a13d2a9d1a5feb0f699670dc741bcdf8c5481731c5867eb13a2878c3d90b7405266da0a02cff2180ad3cbb9d716fdbf9e5dd03ff10c02bd6f2a3734bed3d9b41ae1b90761594e906debabcbc5eb559e6bf14c00d842c3614c6cb5bbf50e73b3b1fc169cff836eadf82632cc98b3bdf0c5fc064f66e833a224d6d68b343d746fb285aa8a99ab42000be32745c7696bfb583db4db36ed06 +SHAKE-256: a0c8d9acb9bb4a7be8bf16b3c009635d4acf76f69c5b1395b8ab5fc72ce0a275c5f019eb82f87cf48e99f75f5a74d77a1c78f9089df1737995f5541bfa410e489e54c81da3157cafa62388315bb001fadd90f851c83d92cdd40b9da3e509fd2c7b04f4fa51f3037d593fea5a87a46e2c58e4704434e45fa54091f7340aa5728047a451febf82075d03697b26e57eb9818bbb84d621eaff263b28330340a71f0cf1dc69f122f590bd61e8d35b89dfa0064519654d13029244c7588d9426320792628538b238672ab10d1ca55bcd27823a3a11ece42c7bd63e74664e4b9a6848357789228e98eb5b5aea74391c999202fae5196bc3e04b17cddbfedecdcbaf3a647d1948d12f98f717182300787f4774e1e78e8a705d9f2bb20d43fedb7ce7c7227046e36f51c8b191e8bab7b8fba1d38dd4a7c292c49f072b64692cabd90a3dc78697813e8087a974f4c516d39f15f02d9a0a97fd02b7cf3ab708ef99985f9858eaeb0a7b8036a76717a135334deb07da45be251d2105ccf4f654d4e9295b2e1ee0d25baa23d43a4eba396d5f9f89d243b6bf13aa01ef629c87336bd7fe3fc4d0ee5360b4cb4b531d4bc15c3876bdd502a234a811278c76e0fbb8e739190f51410b41aa3c48b4cf8dab173ab00e1fb8b313afcf33f09d7f2dd5b86d04bfb8f7b82017b236d2146bf54390cad78727f10229a8e2fb942ff672c98e39304c17fdf3 + +Input: 7fe6cdecb3fbf75172db7a52a8cc6ed24b110147b62cb74433d44398fbdc24e392f1f6f33fdbce5a09c7eaf37c1f5d2dcaac0b7e291a3fc334a3536dce351a7f137e7251363da73c0e8361f3381ab7da0b9e0d21802ba80c24630f20207c9d89b775d54b8956e4da37dbf6b2523aa0af71fcc59cc9e85a6c15d1e1e746688dbb2636caaddb1b01ecfbea34dbd3162eff996f84c364866fe1a0624fb5274d6ab7769c6dd97e7c5cfa054c9711812a605cdea5d4a821f90f3f7e1b672d725035c0c1e3c21a3d75a13d90edc7db5f8e7f1893d31251059788d3191c8b1f9c430dea210d298d8721c61eb9d3f5cb77f9fdf0870d154d51a03d6b3e997e0ddb7c6bc6738265a659ae9cc24e5d59b5d60e9af04ceefb31c6751efe3703fdd3bddc +SHA3-256: 6d48c9735c7361c018094d02a70c28ae7497d2c7865163555a61011c90f1365e +SHA3-512: 901e829d81ad9506b7d0d4f41ecf450d2f36033c733ace8c57b8b88760c14ba489190894ded1721292bff6e830c906cc5c228436effc2d08995bca9bb0a13da4 +SHAKE-128: d55b433a0722b64ecd9c1475985eff90dad60bbce50cdf7be42c565b9cd3152a32ec459bfeddcee895004bf3de4152f578217686c1ef0644f76ed32f3a501bac1389b884637c4920e5bf045e8dc2b0ef60cd335d6f0622e66ab1f51cee1cb393a91f4628ca8eb7a71e6754c593bdfc5ac00c78111dabd1963c39e55c1907bdc47ebdb0ba3ab4c48af868a4f8aced18237cc04f46e6d37545d1cd8d86742dc317fd80b79bf34359c5038fbd61ef88c2e648584c1e9400634c5a59f61241eb0ccfd7c61d85da6dafec56839984ac9e802f0df559c405b72fced4d50678e7ac7d08ef9137c393ccea0b93e1ea55f5d6ae7f030d75344ece4c00e047e237309088f7c50a84d7d57aec96cf071b7837275411865eabb41969ce51e16fe5a0640584842ec2c9243d20b7f91d6cc0367a1f481cb77a9ebce97555ad1e879bf2c98d2f20767dff1e673774f8602912bf465bca7440457f664de5c8f7e89271d15e909bd07f3fa3e9dc3c25e05f95342f578217f434b61b051a4f8e3ca97713d1895a03d5ba520a1eda249a5be025b03ef9f18ed2c12d4b2dddac1b04be8aefd3d49f3582d959fdce4ee98338cc434c656d8e0cc7f28f6f7b0e8dbd1f3ea0e7aba39336ae24e4a5998d760e01b54db06d3debb49de377b0ab94177cf16f1b633e58e415acc5c56d8eb6615af5b4331f702cf52bf2ea77664cea34210f2ce5da08eb1eed5b +SHAKE-256: a07c5aeda940a08a4e96330be1874c1f67f641ac17366357d3b8a3d1a0652f314033e1dd80eacc56fb1a0ea366700fc4c3ab30d243d731f83295f19d79dd7a317bbcfdb37c0a8f770200b39c22e1da549b54e4264e00f837b85cc222b4814bcff6cef68779b95f0fb71d3ddbdda9d875f24f8cee66c9bdbfb53a05c2efcc110f019749a860a06fa654b68028a950d9535ea0e53888753a32737625e74ed15d9c099b55794517caae103664abc8efed099f551d2e46e7da9ac89660ae3ab4edb27eeddec4a8bcd13ee871d16fc9b1368a000164375c725f8d2a2b71e03486e2407d2752f469b25f6bde0c65901f5027e2ff2350cd726a0e454572864c926476e3a84db2dad891d786a86784f7fe3353849b90eb39b96a098fe573016a13cf91ed90a79dd0054a854b0ff372b959bef00656fe039b4baa8b07f2ef8c7211072760cac73cb1c26b98c7b84109a36bf1c86d9fc228b8c6a432b1e4d855796a652966648334426462cbaca3fe52ba8d427c2ad1ae522036856cb1085d70435d1ecf8ff7ef7cc4dc813caf3246db578b432c41fe5a942ff16212c7bc276b23e90dfcce1a72ae539dba88003f5eca8012dda32b987a7f536098244c16098b2d1985fc5324a106e5b28a0890b47dd63a089b991e8a2e981ceb726707249d75263892944928db895aeeab269f31ab4e8e1dc1799425ba16426a583b90f115dedf5d89a2c1 + +Input: 541735f7a612b7b762d13e10506604068c646d932a6bfbc79d74b7c632df52ff02e3d43a1d964bbacd132233d7151399baee44ef347371450a5ad45f50c74dddb758a64eaf6b58fbb5475160712c74443de884aaf394353aa5fdfae73b29c9a7017287d9ef9f04ac06c0f21b1f512806743017213bcc8596beb7030548defab3e4865ffc54cbe6af0c65cda66c9002a827ada24d58ac28dfddad903376da8811b5ffe672b2d0308a8a002f189ef80f6988731318e4dbdbce7d532cdcf7fe5241bc13f984d85c0d730da52751005503baf3529dc5812d193c4bbe6b6fd5542c5888184293e2b01976f03b4bc359eb6fa4ac07283b4e913059b7517152d35672c9a233ef06824318a1e8aea302988c5ee9ad40d09dea6a844824c2b705e75b6c +SHA3-256: f54283a1af3836885fcde8d2d1edeefa408d44aec0a3b0219c33c3631cfa56d9 +SHA3-512: a00c4337d8281751f7ac9e836025e283b5ae918cd9fbbb6cae2c08f89e66aca9c36d82047936e9803260ddba07137c6481c8f324793f3424a36f6f2105f35902 +SHAKE-128: b8462bf2ec877be1dcc9825bf265dd18ecde6a861986df0287a1c4380bb611e0f9b222852b4a56f33d04cbb2de9d93efc27d5888b1fa896a53d50c0db34b0fde830f1f35d8349884010f110519dda082e9cd7442e037bc28e34661dc3186c451e356125b70cc4a2ca1ecb2d348c6281d50391c108366d4d5b7326c765dd4d8517321a333491bae1898bfae6963fcde71b5e2f951bd00bc03e94c27d8e93f954c577cf247076e75a6138a6b586bb1379dbe45b842444d5c681b15028e0f20d507b927473604829816fb54beace47d9a0fce6c6a5b66515a682141b333347cd491d0782b7efcd476f9c57d6c1152af294d63a810419c51fe9a07af44a0d3dcb1235334ae954a7d6e4b3d61ef972a2a7dd9fd787e3dd4c794036c887530f4bffcd9549a02622725dccc5d04f91d08bc117d5c76ee6fbd9c1e93f6161d9dddaeae4cb622144592dd8746caf2e34866309288be9d4976b70770d06fdfd94fa3406e064e71f582176f5f92bf5e1af95c45d96a7f9ec3e952b190a8e5f87a2273a62d7b3841d07da0498f5ec5bdc3e3114d2a538ab5d5d61dc739af54cd3465c9b0c5333fa72087857b902928208fc9a110a65ea21b0d63c8d48343fe41ae45dd558ea98238ad6a954825143ad2295ac5073e360f1e5f8be1f9463fca9ba66aab5e375f929911938d949a0df8a8c2b64a7bbedb8acbcf02d5c09bb57177e9e685a99091 +SHAKE-256: 132a4aab2cb18814c7fffa1764aef7505ee0f55262020968f4e71ed1392f0ab38ff5dea14aedfb871a8dd886a778d05af4664af0e8a1bb86b3157b49080d5140c0adb05bb957db8b440e1b3a51b060a942cdc488120096e5a75126b738eb129e05eb17abb4db8106bfff35947769a7a7d0a01277a68ce0ddbd06890aab4424b56c1648b09148871491027c17f766b4ce0c8cc264cafa3f94c120f4b23d94013ed67a73c10d1f185b8dba3af99d8ac7ea46f0cadf033c42bf05ee1a37d88ce8c85c248307759e7fb67e3799c7435f8fe4cf899011d816b3a9a3047df72c55ef3e700f0540625a6e347cf215e99f09e517a59e9e74bcfdd5faf7533e4b449d000ade92f49c6e506be1712677712f867b21b0d0c84bb385d61c7632da9f39efbcb2d6938bba4e9960d759683e42f7ca623abcb8dd1088c91af109b46caf3a0b2299eab60f260c4acb4079ac72c409e00b1f3bdea96b31b72a0507de49772623422ef3095bcd9f6866fb2d4b9abfa4cebc4e2c3e43a410c3357662fb450d3a538de3cfd60f7c77419b055e345fe55f532f73f25285b63ef971b01ccc723a6ff3a360dcadcaf5c9f91bc3e7cca5f5c61429fb27dd53640beb9701d986b5407d2b81ec741fd3f7faa1dcb461b3a9a27235205f9d3403b03b08c2236897c6962cdd29dcd92f418208bf1427cd93316e8c04edda363f7b7fcd4dbaf2ebdaf1cb093fb558 + +Input: 910526b51d4c23f3f31adf694bbbd88dbdfcc6c4dca7cf4c24a49912ad21554271414dd4cde50c4707fb8e04e8a80ec9f0de4f38a3691eb9c1f57a26b441f029c966b9444cd0403456e3f22aaec0d0624ea64881dd9a28de405a312ed7c26620034177ab74043ab4c556c46e3b7f1330f3660c9a9ac1aee46bea25471b64e8cd064c09f62262f297d823cdd7c9f7ae863902c040ad6e494ded161cce4a488cf40252338f4bf0ad6c6d0bbb9824462dbcd29509232d3f71299c69444bd60c3268ae2befc2483efa5e6cd2dc6185e7522b5506f60886fc139175f71c6e3234a0d62ca2a8770497f44800e35057ef4d128893f3bdd58f42edd31fc6dbe5f252614932c266520575363ea7ad55e6464ff32eb55908b4cdf23ed2abf8e889d9b2592c +SHA3-256: c4f13f0158115f4a9dfa7662e2c65d2789f0f5fa986df308dfdbac62199e17c9 +SHA3-512: 03831e79a6e484e0d1ed5a8bf62dbd092cabdad379dcae48d58c04dd73ea7541e6a1d0bd9ec6a71bb8774314f35f515a6f38ea8f11bbd9d4cb894be05df2f0b9 +SHAKE-128: e15041bfcc45eead31440e66ebf30ee2178f73da36cec16063aece4cd93d3e55de07b45bcf2a1067e721e33d2bf62317a6177427b323c241b6300dcaaccae7f3fb901fc7046a1c18e3446c7bdcc23d0e0983d875c05c265637c2a552e39ac4c7c8f165e1bb4ce6a33ea30aeb9155a229ce40623731b464c7c4dc8ba0bddcd0e357952214508640a3e5316c0c70d948e8cebf604ccb4362ac59d78c623df06a74f08cd157295cb8b86d60ac9fd2a4ad7e5f22fde5b1e779c773e7f41d99af984e04916153d6512afd24da3c33247b254872fcfc82ecbce777056622d176113d761e9faaa4d3c14ee7affeb0b71c25473f2bad4b8978d8402ab9b049ac96db48a51167dd5ae452d97b2a98b9b01434ffa79ef39b46aa67c724dae1786dd7e4a78ee2539464e7fe5edd3e45fa4790159fd4ab0a87a800e244f21d9e40ae666199190e0c3c5d6b4b205245dc7f7a098f07d346067a2e2fb000864df0b0b58db6c8361db940145ed8e648fb619b9b0251886c9c73c34c2f9e1b1c2aebf32429635893b24d2c84a8d82173555120d7d6f10c5bec680a38d375790418d5af6e25ebb89ad8bd6551d294e5e7112d5283d8d63539bf2873612317e4b82bdfbbec15aed5d3f0388302a13adc764c5ca0d6d3447a5038dc8584ccf231ce97996501d8a0a660732025906c6d5af85eeffab39affea62fcefdd538719f0ff9061e0b1942a20dc +SHAKE-256: 291ce7950a62b19123512740d9501c5ed03872de11d1dc46a6d45e4c41286335589869c05ee8e48e6502bb3b86e2d7ebab17167a6acf714fecd94ae25a38e0c8ffd2bee4a3a97db197c514aca41ba15d278469b8e3252d4bed5681f5550e151698b821cfc2c2fd88d17d30baa930df00ea26245bfc02c64cb59b98adfcb57a56471355cc9d3da822d4a34b166865315af37422fef77b882e4048ecd915281a6b48ce057f303a9b5ab447c82381c5f64976cc32eab0c7c3a2d8d83f5ad3025a40c96cd7b90fe5692fa9a0e15a1711fc0a3f021a8544e731a08fa33648a9331ff6d09f7d624c299f68105eab112079cee143c45e8bf5f2f8b1748d82f951c0603ddc2107bb1582b8daae88096cb1955e006743f95f7b6c3cdf338c5426f693ae7d372981b8a99688f2baead3bbc52dfe3b63d552e8d51fda2d77390adcf5c38d8794232faed18cc6102caa68a64e5bdb7e6257b7b48dc09ef7820e8b59760b3ba41f5d099d04f154cd77ee846a2ac14b9ab7d27493f35fb2387626693b6e8017ab8730da1077071ccb754a87f548498aefdea820ad80640d5294bb6afcbbd4701f279e3c7a1c49d58e598a2f61b90bd81d3007730add991968ffcb4e9b9587bcad5955c1d5dab585ed24e29ef6b7c8170907ad1638c711db9d68d1f99366c58025816604eea42d2272fee53224b65c11fbeaa1068bca9a9c7e3f9d6f584e03a9f1 + +Input: 7d05094a1f3da2ea13d015df2e188f69fb77b86143e36e2b8c690c29306e04e3c27734efdd2da418a0e63bf4a03a3d3be49ca2658c4b8486bc01420a31112226ff4a8f17957e1a6d3eedf6778cdd88f786a6c07b0ad2a316f38b82c5858dbceca7d80d4c8992c10a858b7ba1db88fa0b9c276e7e5cf647f2336125c0114e77082952484c73a15ba0ae74dab3abc7717b51f14c72ec97811e5b6d3a7cbc832d2e186ef869f8ed9edccfb2052352b77e9a59fcbcb7972bfef66d3d3548d961dbb5a066be89956ebfa1a4c60a78fec5d42b21e98cb9b75db1f7b491393818a593004166647aeca294f34c1aa3d6e1585fa75bd0d549a81bd202938192b3ae58a6cd872159c62dbd93ef94e7c54462fcd99dc52b716768f508477023c69ecfe455f585 +SHA3-256: d4626138d0ffba7b61806c35351a35c206158ec43e0a6793d8e5e17953c9e573 +SHA3-512: 5f5c6773353c716be2c12aaefad8ebfc5cbfc1df3a7544fb7eede6e18e5a4aec4be35eaedcc8b2377eb88a7acf12966d60feaa41a29268ac2cac749e0afff414 +SHAKE-128: 1030cc4c9e3b8871b32584aeb457b0cb97c259e9c8028e5916e7dff492593deb7f4ae35c10df4290bec9b23d9f88589caa36f3b280996faae28702cbf150fd7def3d556280b5a232b91e1f1bfb4b81e9dd76d7940468f4b5964876091c2ecdcb1c6b0025851f6539e3ed81b57ecf9a0c434d917393b273c2134bab757fbbe4aa669f82570de80273ec5cfebbac0fcd465bb6ff99710aaa6ee4b1836d4575ae56a56086e834e8f268a0bffcbe67f2da11a3a2dfd20c1e5ef6212a19ebecaac5a173ae60d71d4e5b8446c6358a408b46c19ad01d7d9b7ab3907230f72971c0b3a97d8dfbbe565b2ad6c61d54401c27e7b52a20233f01179ed7e1d71e7ec438e3c8e81a2fa1ed9e4a9bad05b1419f5fb52801afb66ac14b28e3cf35c309a2f699f51e13bf19a25fede71b9b0f20b5ea638b865706bead8a317c90cef42c493e5146cd617d7c36b56c563f374485550dce7298b12ad84e6fb96269c61abcf0a40ecf89341fc30b77963275f4d3f5e97c289db9318aed42e78b54bdafdd47ac88e7af9c11ad675e7371e91e4edcb16bfc763d7a0c953ff05d99e230ade52d2a795cb80988df705c3b31e0628cc885b120bb318436aba8fb4b58141742315d6702588f4cb9251fbc596d199c3a26ac0789505c65f49b0c104f0373ed18ef576b346da92b7f368cbe15114ec92cc5458f516295560ebeff56b6a1515928d67de3bd0f8a +SHAKE-256: 2b79d4d4dc9303aa37dc85a51ec0b76f7dba9a05dd7e25f56704b012427b73c8861a7083e57c09ea89eda306f914e827210b7301a4f91b7f90e438aff0769521ce4ee9cd684de307e93130683701d14733dbde1419280b3b6d15501b282be0acc2fb42895bdfebb4cf64dcb13bdfe26d05e7f6c38191b131e34fad47747ebc790042157e33178fcdf85f29c56d0a09b6d5b971e9145fcc8952a0f477e7bac152a7492092df7ecee94b49c187e36471eaf4278a5af77b1cea7bc863a82a89fbd3d8c3b561b39a70fbcb4afc35f2b1620617c544e788b16b81f809b2746d982308b9e1ab5250ca7640160aef30c6d293f847f058cdc7f46ee422f95b8094e1af02702fae9b47b6f7846217b076b981fc52ff4648a36be0b69c15f3b9f52980c06b89cef0ccf80d9bbec46e97e32d591623c66207517cc609cfbef954d9d88c88f625816dfe32fdc5a5eac769471e64224d98f73fd533e6a4ddb525de1bd9c5a5c785cabb2151b796cd114e8cec334ff22bd9915bdcdf711daf1eb9b967d9c830b40651bf402fdcba20164407c08292e50ab3e53b4dfdbaf2d0b7794dfca04d360ada347ccc2a7ca10b60043558305a44ab94e94e77e4f4eae89f758b29fbbec98afe91cfb6b4cd082773f02f03481ac35f5a2a6d67047ec6f1a4cf9da509db9d03e9ba3b1b5b9cfc95a3b62e9298a4b59c572f48899a9e7bd94968d49171ec5569 + +Input: 8d37257bc1ce2a74f53802fc071c83faf2a1cda4916cf647473872e5167adce5afad92706f092ec11bfd40f44394e3d3c5607f3d1aa6258603937ccc85126a5b284bb11ae06211756c53c752ab31377a224d27d46033758dc533d731e4f49ca6c19f8d4f07cf7627b99699255bd1bb44aaf6075b36ac48eb884cf09eb5ad25a6b1b5afe5a065fc31d2cc54bdbd209b2df28a92e0427e30e2471df570777d47bcb4e5443b031ba7f4f564e85dddeb7112af4111c34cbacc97e7b4963b564c28bc9a966f31c63263f12b6108519325696b2a8520fd51ecf9555509a19d448ab202feab4398b44f78172d11e0bebe09a3cf2253ac7fe1f216765b0119dcbf95dd68825df51384f36bdef2bbbc3dd45e01e8de39b1d28365c0506026908dee93ba13d9e4 +SHA3-256: 461b8958af44435623aa915394b898b2ec876baa9683807d646c0ab3e3363940 +SHA3-512: 38c6b98977513c984dee185bf0565867e4295e2714917135edccc65a02102115831b60a30c1ab1fea81b3d28b5dbe009373db9fe4bf9c15b6f3231e82e4df58f +SHAKE-128: 838dfb304b91679daa626a2e5ea75d64ba50318c3adfb4b05ba4b9f232ae3a2bcd3f5082cec9db146350d1672f136a415730b2adbae96241ed65d858dc52bcf0a1049e1715f24c5275c514423330db10650486c0940a7851ca6d38244fcde265c15845635c355255d0ec80e38ae3a27a9616f9ee2e3e8f62235fe457dc3ebd3f88db51ce3bacb32d5b4dd4ca06f9162c93139e10e99189d5407225c898fcdfd14f1e8b7b154769a3bed3fe1a2e4cc5baac9bcdfcfd02beb217b66a0c7ae1d6558ed2138dcb9c392250d312c307e8702cb60e3e3514157e0720715d6a0cd0a71d246b78a8e5536eb81017b0642a643d97fb0c84ac6b7a6761c1dc7153eb235d7e2c9c30149e820dc8556f50e7baea5448fa9a317e1921a37fdfe62567e4df3e471fd31463f4df66a651b4aa5a1bc652d8e17f0ea069fa93933a306289c5b9d42652e9c99503e05563d947ebbc19e7f60f7d9e7ca131f9400dd16eb8aab40ecf30b9e14693df9c91d5f5073fab6e2b5dab702f537d7fe8583294d04e306f13a57f070a8fa353bff58c6a8b48f57787f98d244e22e600165b09904d773b2b742237d26f4291538b398945a7bea2bd400bad0530bb5d5836970ee318cc3f5566b63b0899c4ecb9fc78f807781f68f8655682bc16aa3721354caa80a043fede006fb2ece3f8fce692d2d8a91fa784b490033ecf7cdf5eb4aa05d520007401a8869a48 +SHAKE-256: 967db108d8c66c43d77d997bdd5c6a550392b5f79a7ce4b8cadd7c20fb5416be483f50bfd8ba39e69994d2b7c5b96f24f66fdcf98377e21b7d177a1884a6fac76f4a1f689ea7e566a23176c88f70757a69c9eac9975e4bd790a7b5e640879b61eb0f39a7089f6b6a1a74d14eeed179b82b533edefe0ac449f6b35cb36a9ce22135d2563b9b6c459b6cab9850df05fcf1be408aaa4a04bab8e5070e24b34f174ef20248a910fb06bafbcba5d23fdb84cdc0b3ff3368e968e1accdb2405400c0aa7b40cf972339aabc29b6b45af1ee9ab6c5fa896155f7f92fa90da168eb6be1d4c68aab2eb164c1e3aa18bc2759a3986e4251f528d365b677a9d11b73537bf63568ec616f6facdf6847c1ae90563d7d2828ac5499f63cb4254626a66251eb5bceb5cf883bc92f47b4f434405a088aa1ba367f8ff7fb0764216344c0f04472330b7e88b498ca0dfcae0d20a83158eec3f7ed7aac0cd8f6f20103f4b3800bed34c533b97cabfbeef485a4638745ead5953d1be0e01102dfc1fe37d9fe19a41ee82ca2e9e195de5ef29b2c035d44164bfd1162f104b2e35cc77b79918acf2ed5224e00e55a83d1aee05dbdcb50750af44c83b3595fcc8e5d523bec1ff505e3a744860760d798d1ee51a8b29bfcc79a21c4ff58b65c7a7c47852167a94b2feb094358bd337d5fb1d546f62f265ac50f816a3c4b15b34c0297346732c93ba978d4f0e6 + +Input: 7133a3246b8d09db79f615a42a178641080ed43077904d495567bfb196d35a116f847bddcea64a5366d4b9589d0e22f3ccc925553024e2badcf495642efad5ad50fb792a998b59730f75e4468144a8de793dd177fc7b89912a604059837968a62bb034691af0504cf480e698398b2691024a3a4e6cac8b3c23f88eb2c9fe3f53bb27c21c6c5fa60c1c423e8e426318b98e51e5cc14219bd7ea3864adf19624079811fd5b7c6e466290ae2993e046081af5bf3c5c7870772539ebb9fa4e6f19b364e68e2344072a15599ca9262702c7b8b76d96c0f67ac5cbc081a76e9ec12783ac31ecaac05fdc9bf671cdeda45ae85ce339f5ce1ead05535caf77d18ff25e179c2d4d344688f178e7cd802db25a44dc3b3113cfd5837a6c690bf010a3ae4328baed76 +SHA3-256: 509c07e9a9ce88e71aa7688fdf2a39c353576c59079259797edfbc3f46d961b9 +SHA3-512: a209eef30f43b43a97e1a5e33d3cd0444ba7fcf371eb9715b2d3f072f901e2246293e52fa31436bfd3a25d46b8e906fb24d95543bfc9a7c6b1055c355d8333aa +SHAKE-128: 3767771efc54ff5da5ebee484d4a0e43450ba9e219e5ae4075c3338407589c86e875dd828bedcf960628b04bf0614c9b3d56ed824b5b47b144b49eb464b9fec1e8c61d2b411325672d5ef937440b9b5aaf85c99c720490a763bfb43b46780c90d6dbe0a6219aa0f6a7b35ce2d1e209088da03aec22bd580bbed5a15d78c7bc25084ea438773e1ff291d164a77d84e34c7411a5645d8866dc24a3df7778c2ed9aafbcab1cb70188b86c76d4614fda66074febd711dc0a775259289922705382944fb75c2977445ceef2d052d9fd8e96e04e6598bb4013d9203f5b2cdea5e1a7b8ba226eb42061a4ad9b584881a7d5e0f16fc52f1da018416c4a734a2375bffd90f6c7e0d36835c8336480fb35577de2a07673b733e2b224805d279f12c9830c373c6fd75a376bfc886a56d84f0b06674edea6fc48c19cf482bdfc3f54b1a731606b0ef35a347639edf356be510db50a4ecd655f562b65ee56a67596d0d2193de5caf473716fe6bb9df02a65505081bb15bad3ba5073119065f6ccf73973eed639c028c41730425a419c59d480c62d913ec07c98a63821729ad363867bc5083f2aac901297e8496c428a2598f57a9c84aad12ef95421264e83c68505b6daf9d785c743c124947dc7193b1667153dcef5b6cf32d5a932884b5d1b23806ae00a9d2e0dfdd2f79612a9f0e368885924bd3f9bc9e729cc3f579f72460003d935c868ed +SHAKE-256: 8a3cb1139c7149d4dfe924f55ec0c8e6dbe30afc48dba519cb71e5231a0d7cb75f90ec1650c6bcd6ab3116f2b3f83054bf8b0918090538234f550162e809cbe31b7037f0fe1485dab815764753b7831f0dced16822a7a73f692e2361977906d0be716756c9b7e3d1627351113c7822b5f3deebc98585c07267793eec06dfa49be61cccb5ed27bb9def097e0c13c94afb31c8442697773a4d4866db8dfdb029766fbd954d579522d65375b3b1411f10a8eecc22c51a53d9c5ca4c2c38ae366fa33b784194dac64613830e2b2d97845502c3767bb10352204094af6c3f5f03819d6c7fd51a6ff037e15e7e3579caf4c1066f04c5079b2f808b44fc9984af94cd845dd80788116c9b107e4fdd93d624bfba6eaa2334f833a2c5956a3dde48ca31754188a40bc82efa2a2b5441316d705811b0c646b4c0bbd04c6fa9da836284c5de6bd0b1d7de409b46cb2e92e297a7966a0fc766fc5d81ac530e02f22092407318185ebef5fa86d4d6b3b7885c05b6d43b95afd9e6cf11c5ab03465b8924e84ba6ce6e657db0c560054b116004ce3bb616b545f1f8501880f4f2d852c2cf568a115250392b37d4d6bf65ca98fb2a9b287bf027519a3ca2f386da5b89954c2911017e444b1b61135103effaebd857c0ec8d138c88aecc67278e58dff9e92b32128c103750785fcebbaed0c3552d85afd62396acfc479acccf1566d970658ced9dc1 + +Input: 6cc39693d1f5a982ac02825641aaefa2a3a1d62aa83017283392dc4a606be266027c4186c4b46c92f3b41d8bf693f549008c5724cda01659641be6f595ca3ba66f4b381708dc59663c8ec0bdd5cdabbb072797311f663f653ab1ad95399f0abaf6b8004719e5bef2bf703325a49bd129451117db95cc80a4514b2bf81763e3dac6c4667277eb3af6880b99875b608a525a69092fe3fa35724a1e0c5e3259df0f0a7866be3b629e13c4ab18ef80feda0c99de436ef818b04894f479725eaec614d6326d5bf10528a244848debfffe377113f0c1bb7b4b306dba6e17a3c02a490376769b4d498b4ac355b5c97f587e043ce001736cf4039f6c460ce90198d724478d78c8186e0cf5a33d1ecc6d7203b0e77f096cc8f8b5146704c4784392d22a3fe9712592 +SHA3-256: aac5bb80f7a750c76ca439b6fab24b369631b1b2dc7a21ce8a22af7a4c8847b3 +SHA3-512: 3068be89026edd05e7260f384d68301c2ed854d5c3fe5c370aa887175c68b2365bfd1db3b4bbf43c777b6eaba45a7f125b3ce6b0ae62e01311cb71729a994e2b +SHAKE-128: 43453dc6a35904378c3fa336d7f422458f6c689ff7c07a2c218c5a5d51a14923f8c1d169b9547c1d82b0f54391dec847e64e1ab77bedf047f685ea938f63313ddc8066b35d630b93e8029f0ac97a0ca8a8179558e64da635b614a75e24a7fb941f19332b4b441c1635cb96e615ea157bd6c7d94cadbd3d0e8279947c332c8ab93b314d2053fa5af27585934137e1ef662e571f0d445249780b916b05a9c17b39e5d0d9dda4d98934c02ed66d02247a76c5af2b152bcb92472370a439892711b312eb347c7a67395d76bd214b841394b8a66cc818e5cca1e1a92eafc74f10133954a6650c2cc5f55add16812ede14c6b26c19aac442c45f7ff4ffae42f30a8007fcbae47a35644f158a06bfd0c7d5eb0d6f4071f7232f4310b5991a59498610de0ac05ba6e152bc280a7219c744871e05c962a33e304c027c7687b0ec63783a9c994dfd99b89dbe7e2dfdca51f32fd7d4908ae1533f4c757468db189838af840b8c493ef30d6a6c0507882c81b04b8ed1dc3e98f14a47e67d080ea4baac90a5abfc5f7eb868640867319867e6b8d5f99bcd919e560e3d3c43a190df288b95528244e6cf9da15bd7a4e57fa1010a74575b3b2d2ee19c70485843bf1b4db7ee88ba9d7b0aac28e1f88af06bd5414c91d86c43ff88e26105875d2d1d0bd9526db31b67c2507b903c511dd2675f3615f727874894efb5355fa211b593a2c625e62c2a +SHAKE-256: 0bd333376747586ba078b85f6932b4af6629a82489395ea56131fb75f6bd98b18bd95af63eda085e7c9d481871101e139b4bf6d2a899bca2db32e3dfffd458136ddcb2fcdf00590cfb19a3379134f9c145f3c31d4f26eabe5b5401e3b9408bfb1b5049d3ae480e88688f8f1d765e126e26a39bf6c61ed2226a26b53ce531fefa9fad54ea0f54dc64192d7591150edf002af3759cefa4d1b9f1ed71a20da717e5db71c740f8dc232b6ab1bc767de11ad319f8d58ae3f955a1969da7693cc12a2f92dafd2d6f9d8513c1ca1e6d8e3f7509530088a05f52e53713556505bde02cd951d448d01b382b8b2401c7addd2f93aa6292523a6993135e4e736efe4cd75b1ed847507875b5c5e54d0b3e0b4e30fcf57bf1c5f6bbab18d70bf6e92e32eb633287dea548078427edcad3b4f4194027963ed61469189838fe2a94ab26d8fb0ab0dba83dec29ef66a006651becbd5a5dfa49e02ee10cb438101a7079e0933148cb5baa47fa20daeab642d0b4f38572f21b7dffb0fd475140b94cd959d5a2177c6939c63120781e6537cb0304451136749968cfd58b6187d8673c10e74b5fb213b5860557c80bf7d3e62c8bbc55e87d47a226ccceaafe13f65a09854ea7c8ee719856c163cc2b717e5beb74708d5645cec8c98a8dfc6981686b5e274fbd7cf6ed6959343ab99e34324f25641def45e840946ed6f02f4d194270f6e862c7407db238 + +Input: 2e091266dc58ed4ed872ab83511dd33590228e19ed751fd83a576c4f21008bf585bbe4e5fa412d6ff63ec28eec09df4a3b341701e3782fae10ca2f4c68e0f4dcbe6a21139eb0f3d4e6a1d343a20494c5ab5facb52c3c0fa2c3cc0a5052576373833f029a6369433f4f01c21922eb474f8b28e3777a30e9e5fa1d9470c67dd6ee1f78289d18d55c1868054669a5191792a958d12b5147f689a0783be95a468338f18f44bee2a3d24df384bcaf2b0a5217c3060f94e196655fbf891e596d35129c519f0a042083c3ec8898e8bace89d1ce5914bd5f7297aee1c681f75d2e88fefcd36de8fae97e07112e3a591f6de023cd04d8b0f6f4cc9059c41ee4a6d34f2b8b5ce552edbc608c2ae6e826ab3428e01e6cf7609290ff49bb09ed813baa8d161f1f2413ca1f +SHA3-256: 5c7fb6397b81c1dc62f37308b4812dde363dec91733d9095db89c8cf57de393b +SHA3-512: a7d9f2bba59e4abbd0d40459897a16d3d3240ff6d545390f0650e83190e81fed0f27104ae4f846a7df822952ed096c21d7929ab2e4cd6284355d598c86a330d7 +SHAKE-128: 1e0d2d42d96b0829611d3e276e6b697ef015e30ca8d6de9b9a838136249e7aae2489d4e768585181468e11674df4e4fe45ff29c5b99d2986b42208eea2a92b8ab9b2c9dfbabfd6738d751d254297056111d8030855f1a965cbd41b1703cc3d31f23572224d7a12fef503ad33c21f59d1a931cd77a2f9f15c35c7f4c5a23dc9213cd3eb7f195d7791ada722ee757f4ba023ac9b0d20ad1e757465c80e02c60d44e5df7a52038b642ca57a6763ac44915ded5c0ff252b3b10ebf865c91ba1054573ae72aa7975687e71e611ad91085deb038cf34bd71e33d4610d4ce67f3798fad0ad07cd60f99aeb76b92cc8c80540f5884c2396f273a4a1d7f1eece38b068a5b9c11ab0a3c8f5add2d78d977d4886649a3e3fc1df27842eb7a61d819acbf5b130d9c7e1e79a65f19986f00316dc960563fef757b7a54d6091696f6cd264032f57c8fa83f2e5d9d35d60adbfb8369958dc74e114ad65d8a11fa6206527cefd72d46b789aadd19e3e55bea8f529b695630b9fb49511a85d7ca761da072fdc0a832169f4d8a4fcdab47405c86817b0226faa882ccbd3bb99e9c9abe6c721f6f07595c8d64447dd19c578df8dd84b8e6bd41a8f2d0d9d13bf3c6ca4ac259af09cf99c156d2f904a218ae2f388023d094ae427c9bee1a0c7688aee56c7182fba40e007bcf7028382bcd0aef557f440ff64a5808119cf8d0aa64cb310c1947c8d55ec0 +SHAKE-256: 13bf2a73747f0cd365150e08c10bdcc8e65fab0a179281f6a1db4551310e602af1e01769c983a8292a4747d95730cbd374390775f2d8897e49a88a6a1f4ed3cc67d75a843e0d7fc310697696bf9ff693071e51d737734b2949e96d6d65593b4715ede9dda2e877b4a4a5eb808bf3728dba02ae1f1e29c87fe808b008ce8e135193763e2666b2f67ae19232c53e06f11fd7b79711cc0ec963c5fe0f42f3e3d6dcbcb08686785aafabac481f5de7944204f8e32f01f0907328cba07ec3c292d1f0693a93376b264bbaaff2f2c5240c6aae861a7b943662293ddb5fbe2bc0db61a8b3743ce4b4fbf9af85672fb9cfe33610bcc015a4c7ef91bc1afd51eecef9511cf970f68f4dc3348ca768ccfa73b48eebd1e50f3a8df78686b6a77e4da73849b964f7ab21e225781704380196baf87c3bc7cb702973d0cbab4012df1cd9370dc747976b01fb3c6e7c70bfe074f57185b925972be69c9a557896e63adb4ee68cd51cf2f60c6c5350b9a98befb9503363b6424443e04b5ab620acd055a5521533b5298a23b9400e3e31b41e4399d0927b4b5d321810508cd91af3cf1e978fdd63fba1a781444219bf9dc2cbb2e4733d54534bdcb67542580b104b784508b3b9c22a2cad8d6593a2a999aff702e7ced2349a4d142951a0ee582672d4359acf4522dd24e29ed43edd40f3cd44eccf1e49370a0d7611c873364aae01e0abb768147ce2 + +Input: 43614220cfae0a3685e87c195f61c5b12a2d070bb7558d9897cc20d3a602b741deb33f5c535841c17b995df026d3db768dc88563aa0cf39aef33fd8c3e60e55d3d4e2b81ed7e93fd7f297a66d2eb9e1a31e5feae0b4ab682dd8d2cac27fbfa964c33eea0107d2fe07c45f28e1a3fdf9fe380f104f37f91853a15733ae6730d477bbc2961edf7d6df740fa45e14bd83f64b6f8af30cb68ba0a4a2737f23df17fdf9c98bc8ad1dc00656cbb425813c0bcf8d02f2cfafdccbe6a6d1455a539eae03bb5bb166d42a42819051bb8e4793c11d148098311de5f039ac340329d05021aa474ac390e5f84cca678b510f361e117275c41370ef50f8f6540ae81d94fce654491c29f2e6aae67b385354871ec1cf0a18231c81b11f3075f78ab54ed39a69a3585e40540c9b +SHA3-256: acacbfc98bd8dec52209b78df4b250f93f8ed6128a4315f0f3119d9bb1268a7a +SHA3-512: 8cfc482fc57ff764e6eee05700262335c09a25031d8d59d7885b8a3bc5ddd866859cafb569c7ce4406d40278bd3f5bd2f072fc3c5118869591fdb8ba70c46ff2 +SHAKE-128: 411fc4a93b655c3e89c450141216430739cdbc6792f64e0d92305c6acd431c66e997861eeda284472bf644798cad315ce8ced4b594f0a9766811ea8426e7fd7017ed807f283514f73ccd3aeb2eedd4e5d301ed7bf1916acd09f823cda85bcbef286164116007d3fb35229202be189742294f3087f429d082a295eb4704c51fea8934522755cccdb66678b5c17845eb72f4da5434c49178ad395c6789ab14b374e64a0ad3b6836ad982c1da1fcf9753d248a32b0cd542bcb2dbd6354dfa1c1bcd3f7fe75dee13e2a2e73222a1ed8f946b85cf8c533eebb399812682f976732d4c3ad73d02e8a93e0d4bb7c73642bcf810065f69c4908b5c6ffafa6d2e4bc1c482f7eb17b323e1c0ef0f2856732ea634c02e47b01767b8645b958eb95e7772d38f271bfc7ca4f767569012a1747ec7971c75edaeabdb1cf6859a3ff260dd106a562bc90bd95bc9faea7293d766c58c7aa21031fbab9a27a907e4c8253fffc5955ec5b166fa09cb418ee50711d65554844e7b92ea770cc7c8b875c7c7728fc16cd1918e865be45e489c0a0606f7a4e86f4d45e24d6ce3594e80dc12182a4b8d4b1e93156c94f1e1837ae67609ec27aed58673ecbd98c3fcbfe098776922be5d7e74ade47286d94868cadbfd0017a929529f607078629d3bfdae736d3ada155999468d928af05fd584b501c5c348f9352f3a720b8c353798177d6da9a7be1621d56f +SHAKE-256: 86eca51958c53d0233fa71e953b2b7928ba4bef3a9498631aa58ab0bbb604bc602c24957d6e5d388e347c7d8794f09bd166a16613208a412bb2130db9b5cf34cf303d28b26cfc10f57fb803ac4ab428492fc91d41c0f024ff2429912fb0eda894af8f2957333733e6c515b766b275efb0d5f88f90926409d6655eca9cbd33f315e2bcffda86120e8c19de45e45ca54155d10696ef7ecfa3e7059eb36bd3eb80b5eb576b6a2a970fe9d989e2276ed8011bc31641496bf418cc38bae347f0f5afcb16371d5efa5842fb73ae4f69496155c3129035afc5f8d79c61abd4ec1617d58be6cd0afe7f8e32f3b997abbdbf3372a36011bade2f6318ce2e1e6c85c8d467ad9467261e1b4ea1485f89d20ed1558bdd7699a1820438dba1178b7009020b245b9e47e38442fbc1cc436f9e4ef101af3b4642571b1931c4bf116122149545c572a0904a4d8566a099ba5c6c8930ebafb217dce0eb6c67c9020caae65109b8b2cd28a1ee35b03afa369bee1345a38736f8037e7c3be9c831743125c865958b842b9e728c911398b706ec2f764421189f021e1c035b756d7ab8e6daadb5480fc15558716645b2b9cb7177aff1e6b98a8da4f4d85d2d66f8792aa2af6ddaae4e5f15ef9fc50d23e29eb5797ae7579a58448f84ca303884472d7ba1822436cbf01d908c39f1173ef88b94bafed42686e702ebf52cdccce87fcfe621ed1f1aec3ade9 + +Input: 1e9fa05f3a81e19f6b4b3c02c72bf86b674eaf60da30a14690b3d6b23decf5e4a8b809b8f7a1c51d1796b8a4dcb4ac55b35eba33591b60081bb98b615a66f88d1e170f6ba3ebb9cd5cb448fe021755257459270e8a7e4095694a066b29b60e4b54efeda117d662ce11fe10103c512fb2e07ddc0266ff728dc289c4950c7ce92b2d8d3a779e295f37724008952eff71f4d2078fa96063abf899e3605262100c1b7ba63a7821e031897ec01e331a37515f870d24394c5372bdd6ddb91c8b78a595707055d5ed4fbb1ca7f3d6ec7f4d17c73dfa334bc1eec08e17868d8ee1ff3ff11221847d0428a568dcea25667270d8e348c5be84bf635471b0b6aa53f26648488f2d844151f1726f969d46584d3882de80d182ac3f930d2c27b3482193c4af56a27180f26b2e6a +SHA3-256: 7fa2ca6171e3b25f6ee47469fe5d43bc7781cc88f1132cd6bbf92687dfa3f714 +SHA3-512: 82761db19b644b8afecb00c3a856b7a37a42faf347da64820cf6289ed636e4efc7d5a8218d3fac27121a5128142d3c71be068dd91218abe979444898eeda97af +SHAKE-128: c1885b7e95d4f7a362df1613e5e4b733fc5800faf05647fe0d11d24955c2e1bd29c871ba9190f3b7f28fd959dfb7d75e06d82ac38b145a341bdf87492315db9e53749f00c60d6644add1875f7dd90e52747f4b2ad1155c0b2a261b116d17c59e93b840dc77c0f2e7e06ab9de699f0bab43d2332b40a33f7ed1c440803687860b4df6bfba631cc3f732a4286dbf6f2a9c817bf411defa632ed688b2372661e23594d55df293f5f32f00d71f476ccc5aae145bf945f2f2126bbd8b2d7272a6f16d37ce6bf474ceab967ca376b9a447f3f70e2853a5cdaeb1139cf95fcb1cf7fec0077572d15a616599883d4ade6db261675d9e2139bb41867926fa7a1ec8b4da1a32e64565438bd6695f6f3286e8c310bacd82a0a0c7e504b69f1a2410891503c949bff9a4db57398c12f8dd731dfe8915b7d8c27e52b1c9400b9839d0b99821311503f25cc4bbce93d0730c9a83d8853ff8252cee82fb7f272f1ef0dcb99d14bc15ee6ee8f94e8fa21fd74a1ef89b672671b18e9faec66fe56f75259539477e6b7b348f7bac2d0bd1e9b3726789bf33d59db7101c40b2300aad6ec8f7a6d4ecd057e3517f10c203cc3556d9e3ebaeef4808c60df0536d9dca9639931650b2b7989a3dbb8b94b6d2c850a89d72d96cbb4227373edcc65595f084b0e71cdadfa9fbf867232ad98eac88d96aeef7854f2de9b285c44810e15ac03242bc191a4b3e06 +SHAKE-256: 9f0c0cfe644345268197b53c0dd84c0df1058e9b33fa0873735361e8ce6550db807f40b06dbcfd60cf95c67520e0ca83c996313a71b3254838958390273ba4c9b2e46c337b4b0bff507a36231d0038e44d2df89b2a734c3212900afdad94c6978ce1be521d27d6116337a2405261389414259e644294a55db78ba5ecd4e12840601380932146d3695d0b3576adb8ec1a89f331033d52faa90917efebad9c48fef16d30394c04324e8dd9dcd9348b30c10190ec4fb97c6a35ba975f1562c4d73d958ff153a3641f502fb60ad5b26e2802b74a9936607470d820fd5cf6618685bd7d88c675ed185bfe6cf916e7919826918735f84e95517038ff9ac6d49cb5a798b3bf6b174d51ceff5639342cb6288bfcfd142d118caedbb64ec389564e191c5563895682a76f902b7345c0dea07e1523f882bacb8e857d486804da057123ae0a1dc02ddd857cf5d79b637ad27de2252c53b0c3878477e0dee16416ea4245d652a5dc231b8225441764f40c82fd66d34aadbf8b442a04f1ff1c52041043c4ccaf266969dde9a905907970263b1026440a4d3538f6ccf6b5f4a84098266a9dba4f01b23cf3c5ad00e88bbd2ff90c9d679090e854e3bd8e28e98f3ca7bdc972b7aa477c242aa3753b16896e8a16bf55048336adc31c3f849799b8b15aef01d6595992a147e22596794c044a781f7651c01faabd3bb2644d5710ec2c1caba620e324 + +Input: 2f1e14aa04ca1258a1196ec625faa4459260315e38c3882a574b188bf9f5309ddfb90e5a5825d539c22c8507de8b0baeb93d47b7ab45740e4299fd775e3035dfac8cfb91cbdf19e35f460011e9d317641140ead2c33c94e052eeb449781d16a4f088eb358ac98f7afb8e7f82815557b26f34a2db6de558e2b83d3c9afef99f67ddbe195a77b9176d571ad9bc3e39ec318cc5e81c302ba3924278aab8f0fc88a0ddd27b062980606ea7ec7211089e0cf0607904f78e0f5f196a2a86f21c03c58106716cb3d0e52ceb4caacfbeb5b9cfc28a1aec2165680dfb9b5d65bbc539f7f71f34fdcb915e37d9e8c350bf9f210a78d137084e088604411e37ea03185241a40681a62a9ad6efc5810768dbac7ef784502805c20a2b95854ca10675a94a059796dddcf9f4ca5307 +SHA3-256: c908f1db42869889f717fd076c41b7ef56407e1440ef1330b0f777b60ff1e82c +SHA3-512: 17e8aafff553b9249946e4d36d11d076d334c88336ce082ba648f099639e0bc67459116ec56aac9e723351f37e5b34fbc2b1b5d71050a777ed19bbd664c290d2 +SHAKE-128: 93eeffac6b784f9158868ec84843afbea9c173ccd788ca01b40ec634998a9971f136e6230eb55cbc54905cee83b5b38fa70909107556596ef0556d814b79a2799399d0ab32251b38a5def76d8cd5c1729532c59f51dc9d34bbd71e105ede6e5343398138c47fac478b32e23711e644ccd8dc61df74e11e788985b0ee5056e62b16d5d67f588752fb7e70bc613d31440977674865895b1658370255b259cffcf0ace81a5ebba2f180c6c67b04275bc0bb1fa8f1ec9dedecbb0e511c1bb628e2dd637916f75dcdea4c13f6afd58d3b82390ea0422250ee186c031b8ccd31cfe0e4a147745b0685cef777eb91a096c3d85b7f7fbc32e4217e932ab3969e753d60a3c39500df53ecb7a69fa41a9e67da32d26b13b467a89a9bc4c2a42834993f9956cc6201fbb226855115caee449ae6de01bd43e1ac6f06b921232af1cd6659101a1d57b3981dddc101f877a80fbdd5dd1b22996d5cde9a730401f37c878b294020f1a48d398dd92506f31caff4bca5f9a4ddf7691e6ad08ed5295129c75381ac99f8bdc9e93cc5cb1f92f6dfc95e03b7e9ed358ab12b50c3dca219f2e9c8aac80da03c67a7a857caacf5843a60dde480674efb88f1c3a1a73e086dd068594636fe4e1441e940610d4eea868aff8228e207014b18750377703a2cbe1603508233133f533cdf65456b07a328ca49e0e91f23a66191939ac037ea7264980a14436f2a +SHAKE-256: 2cae19c70236bd522c48a9dcc88bbe4ac08e05857fd0f91600e5c559dea5e7de19ad6a13c5fe2c73de2b0957e9e8e1b1e390080513d1df15a1bb7190fdd474e0df00fc642bcc4d7c3c15f14a3b49ec5575674d252608755c318b02a86e3cbffc54d9d959b98c6f99eea492030ed84d26a485511b860d55ae8901dc80d46a836d1b2babfce8647cfa39680367320c8723a013252c0b1f394e37658e7b7069b4af225aa6c4fa6657b8144a6a38c95c8c730a76fe678b915dc5bbd15d4c60636adac39c203b49a003fe79afdc6575c37746b8f6a85904911209b154d5e5c9cd62d637b6dfa3800543c97cbfc97a3743345c40ef132073ac0462155fbc327bb78c26adda7a71ea833d111097101a5b5a215dcd6ca4d920781dfdefdbc36d458ef356cf358cb5e73532608c34dc1c620ed8d79fe304b64ff012008c838d25ab5d64aaea9387b36dc43380ae04638fa200a8a790be0d6e77ddbb9d0e973689b973aaf075a01e6694fa361a100be3885ce223d1a32f552751d8fbd0a34653f6efe16dfb033e11805fbaf7a4189abaff53741c446df67df89f03a364c73b6c843395c92d6321f18d3013b2c541bd7dbf01d8e0c0636822c916909a1f66318a723fe7283f8c6ae3076d5aaf20ed8fd24ed74a27d13e1c09144d1d3ef108638a18589c71950cdea949df2c8d2a4a2160f43017a663712c02fc4dce826f9c206050ad0f839d + +Input: aba2b00372a2377221221e7777fbc229c674e22eb29063fd32412718aeb535eb31b9f28c6ed3f50517fedeb107db7f6a8380e7bd825cfd518334a3d15077fa1ddb7f999c56f2d19347100533c7ede669faf2fd95a54170a4f48b5166a2ce6b0940ae96e02fddd2532c036b5ad18992a989869b41fcc298f2a9545c5a2f89673cb66ac673f8655a59bd800bd322c3da9b07a49153578d2255f0651ceb5d3ba69427e7d0eb8fe981b7708f5c15638d2c3d70d938abe6044ca85c4cc90d530912fb6d325732a30b1c875d7c4f8d8b74af7da72d351b900a26e7ebba29f36b8c039c2c6625519386a0a49a3669fc2e98f37d51069e4958c94b7b233a23af619a35fa7a3227c2e17bb80b2bd36927c1a12a68d7d3665b6f6ade370a4c9a40061506d39a2039d75bf136b9d7 +SHA3-256: 80c741a26edcb20597c59bc1664d9a6c2401b152aa6e3c06d24bd94f3862c98f +SHA3-512: ce2d2f13dfcd8e9f36c8d7ff2be33537d123f7099ce8e305f194de73e3c020bdf6d75b31aa1b607b7c9c17f18532c515eb3a53d5b58c05367dc0f706f956e967 +SHAKE-128: c8145279fd37619ea59853a4859a498465a36b5f38dab2b455ea83a7add23ed9662093d55c058d9a0a1dab4e090481f39352ba7b8c9eb422264626fe645a4b293d59694f0ef0cac28b0d0fe4f943b7265b39faf58d7dd6b00b2f2ff40cf485b5c95433fcc512e87346d0a28aa4f5be6880c6cc3996168854647fe808e510bf1b738d0b79f9580175e797be6f19a5121c079388b87505d70d7a0c9bd5dc882e18b39adcf08362c2af6f22effd560fd141bd1f1220bed3ac565beb4f3e3a4b77f354dccbe4871596c05cf2155620b4d6b034a5dd8d089b5ac59ebf8c0f2bb51ae2adb9ed5346aacad7af606e5a73efe092b910a270f9485dd6b4caeac0bad1dc405b54c94b5dd94f0cc5f3bf1258cf0c46e5c92ddf672871da94638b18a4641f45a249c49da32fe8c2514e14c7732e0f5c685878e9ee0a5d5fc9be848fe09ea85fffd54d97562846fe79502920da5d6f85bb94e647cd81f70c00d26c6b2184367a9d58a475c4771739a645b816bc6770008b4c4776abafd05ca1de95a6e1a2ddd2a11a7ede8fbf2ef900db2329de8c741c2372201a538fb7f84fbd9b21436247eb736895a75fc7adceb955f471fb8b697703cecf5b78dc28e2d0a364e6d4f680d7fb8726349e207ca8a5b3e8376156a92406611f941cf4b55b89630c666a36ec0c463dc5e1225eff8b1ab847044e148130caf98034839dc24f5b8b838f52b3a261 +SHAKE-256: 0c04096ead8e3f6584b575e7c31791fa539667a0501860d4db2e5b55f1dc068b2e1142e3f411491878e69672ba30f5c84f2a105245ef37e4744887d9e4cb20a7501da7758816bd126746e4547983cb6a61680cbb8fefc65349b55ffbf15ee50b213ab8863564505bd7edf0acffd425351973214b749b4ea87379d96560fee85b332aaef3a10fbb638495a29ff47b64f439137e3c1f66b75a5ae36d6d0f119d0b762e257977407b28472d9a9e98d4f243f2d2e4765b7b3ea32953e282716c115b81293d26589cea0408be53b73574c6140fc5be1be24490a7250af07d0713cc34ad531e619a42fc27f863d5fb34878ea892e3299b3ab66b8005a814afbfd288198cc5539397288abe18f7683c8f4a46b4fd5f8f5f51c77a18c13c1e66b55b97d52a1c708dce66d3001e720d9004d7b675ebd1d02de3f787f331847ccce0b4d3c13adc14d091e63174d95578b4d3436c94cb325014cf87b7e38cc7b1ce9180a621a865b1960e2e9333a747df0899985cec144ff692ccdb7ae91996451906d5f6d44bb6dd05ea2d348a8c8aaf8dd43069b5a4d6933dc4b1edfaa1aff849c3278060d6795a299cb9cebc413bb4f161700596f856b0f60b9f9abe31be4898680729fb8e848c60e81c9f66fa9006a42e02a8b282998f6344c0d9ad01405c7eac9956cfe2618c0b16db9a44261d391fa69b76377c48a1f324f289939064ce29294445ae + +Input: 21bfe9a3283cd9488467a326919a01b8e49317883c418493757bc2eda84dab6ad706f277b34cec155822952ede0f72eac7ff96f51113d24b1992356809bb5d1fec918e3497348476d2eb48334a3e0ee82de3d8b3804fc48a107c2fe02c2ac42a689717a03004f2702c1a1db7e864dec1e1e1bb653a5358606d3f03f5411a3757a0cd5f70c98d16b95ccf0f239cc664206002270a0863db71ae33959b9bf139e280cab2752369d13094cdd7912d00060ee95b7595fcc1360da8d3a2fb9552eaafdf9b15419c9bf59a7dd52dc7a4aa573eb7848123eb6ffe63cfe482896882e284882ddac1d3552319a7f22164bf760b2995dce5baede14014e6217124572fa7c6c370c086df34c5c828d4915b8cb9c19da85b6486ba90b510137ec818621699399ae177f7f37f6b310753 +SHA3-256: 8d5243be42532d5c5d97cbee1159e4a1f68e1d1761841ccdb7685038f123c8d1 +SHA3-512: 95104c36f15ba132fa0210f2ab405385fc9bb2965e98cd572cdceba168a8eb11b5927c5e8bdda2bf295b63eeaddd4185137aad6cc74f28552313e211b05c77ff +SHAKE-128: 6b97ce384af6302990cff8844b93204a49b4919276161bef3824ff1483d2b195b1bc5187580e2ddf261c5f018ee7c47ba9ea547143e07cb40dc1cc05a24a3bf58b44a7d84a66eb4c6f250a65760d11ad302aaccb1f17ec7240ccf3ba14a8af133bf4b81654701ba44fd8b3103153cce4807ef31fc72b8d3a0b0cb31ce1ad9e6cf997120b1ff1425cc1430c633d135bf1dffbb0189c01417745014ee5d3a38840015bf9421edc70a22086ce4388e62d439994b101585bcd4371ccbd25caecde59ca884bb7fd3a1b860b712b0ea69dcd52ef5be119062afd34e54567ae3251a5df66eece67d641babd3adf4f3b60b65ae364e79e21f0f1f99674729cc15870fba39c91f555f587b99cd6a80ab44983693db813b16724ba77a13e2f12e112e5a817da90b81299918bc0c6ad2b93f0f57e1aba7552780591a475011be85b07952e4ba397b2bc576e3ee6869fc157d63fdc789e21760a93777524e8862adab611fb8ce1587a77f223e206e6d1e576789b33171c6ad174ac3bfcfec29acdd24cd99396b6e59585c984720dd935585ce4e688aaf165873b31fc0a53c8a9633245f6c2b4e57a98106e1a28266ddb89533071562d16a30befaccb98628a63b4ca836a9f8826dd792eaad40a4173ae95b0edee779a1989577fa2fea219c2efe6d4fdd53ff707fd436350a50d7dcf2bc7eb64e045255a9cea9cf2fb9c1170ff4bf21a41dfaa +SHAKE-256: d2b0764085e191b9d61201d8f4bf6626df7da70d3b8de99094eecf693b7f12a931f14ced221a5fa33d193c9692e460cbf7013e46279f84ca28b0ccba8c96fdc823567776743129cb8ae7abb62228adcce85149b16a9ed672734496fbce6c3c8c373d29832e063e72eeebcfe1fb6d06fff079212770ff00661d928965f0d1fd50b681e418dc59747365a8fb6143d90202d4732205189d5520079bb5ac3d87629043382df4bdee6ad21b40d4306a986d78860cbf5490f90ee8522cb83352d9335bb6151dbe8dae17bf42545795146e9844dc9309d08d069e84b6cf516a4c5680980289f07ed5fe17bf3514ac729845e754e3faad21d84d876505594b5fa36e551db52b0f6e92f4843dbdb2ee25f6e939454db595bc2a227dc7a16101b962cbeb3c3e05ae576d1bb63f19da02beec972657f6a04d5f0bf44161481a4b72ae7b1f5da588172364cae626403fe31588a0d8406c06b963529e81738b34438cc069e35a2ec79e34262bcdc2355c421cee11cd7c444170fe67bc31a3d45b08e54521c2d74a48edcfb863884eea6aa1454e30949d5b1bcfe95b9b118cab25dc89c893211507f214e3e460c53e35be5a0824289ad9133be685300f23ac1f6ef14c549b6f03f4ca37d27c7e9e502c11be9bf16c0d16f9d3393def71aa3914e6ec83caf7b8adfba3b0ce06ae1b1ec35e187464ed44e7a85136fe16c5ff24dba33685c3a5ebb3 + +Input: c48c06708042f2931962dd35deccacd30652474dd382839e3d464b5f220a38c3e742f6867876f32f73b97ebc812876f55cf0fc85d778705647ffefba3aa0fe02c1788b5de8db887ddab1e071c24fabfd5a9fbd5883ab856b1f9922497e7c8cf6cd5780d2a68b1c6bccb9335cf5467f6a1480f5beda6cbd022f0f41030f7dd55aa45a461be66090270429d94471e9a9db418bd6b8fdc05b2125c7ca3119ebd6394692df1a1ea66bb4b699d7e75cc85186b11689c685d078b5d00af83531840d3b42b59e8a38e044e9cc02c89fcd6fc5f292c761a83bd6d9765911b89f5429422aea40c25b108e12d599ad0e7243f5145c6488c5c51ef1bb899aa9e6efa8bd0ff06b88800fb1d74d0bb09437659e0681f95f9ba3393be81464ae3296d68efc31c638ac2ce00621544158a041 +SHA3-256: c635158da5d13129282e21f73e61d24ab97ad8216b4565a9c8983b757ae4a143 +SHA3-512: 15c317f655521e98a2ef97b1a8c3ad298dcc754f1e8d0a4f00e034672df32733acdbf32dc43607f685738feadbc6263e6ec1b404d50f9f0281a00d1aac090467 +SHAKE-128: e2f2f86c0009a79595f6e7727f9692153b4335c9afc23ac915ca1b4ca57072a6cbf955112adc1a38d73013b969663d1067eefdc5f6b58e96e77593f05d0ebd31849afb330366682014df3e7085569b93eac45a12112d8839073c59a0eabafd161ca1f0d2cdeb61255e2d991026a7c241d57b5ac63c6b335f67cbb6de15e8112ff763e5aa76d65cc5866d693e918d134c53f94a7713f5f0cf997726595db4fac6a74c20d8ec69e6ac45a929af7fc924e607bb86a9d39e69337b7b763fecb6bb897b888f6aad033f4cca246bd559e83820efbad12354ceedc6c2967aa82cf0adb888eb8258801395640c0463069a261b8db9a68b0cbe9c92e8df9eea0541cfb390c1573a953f07d49e15e2c99185a70500a670ad809443ffa76a079d5d8914e2bd7229aa90f08af87231d446874bccde508c656b2c2c10f52d616c876f5a9419d3840546bc2189cedba321fcd402da64d897c14e1c6c1518e0b0d720175fd31546632629d042d2b05ba8a2d2abe71592ad8ec8f82f9f9c35518a4b84ac8a68e2e54c4605d01b4fb476cca7cb852f5e84f9d3b9b2c7fb164ebc01013c815ec40633097d41dedf30da5a147e622800cad61fa708d02f546d0415e981ccd4b921d64f7bc679fa8cdb9fe5f9acb5d36ca26c232df5a6a2cab2ce9e8edf32520bd798df8e7db350b732815c7eee1019ae29b5da4d2e28b2eb10b7b9a685548f46728095 +SHAKE-256: 41e93039a891da92b19e8578425ca7e94b95077c13a788b6bcaa6e8b39f8c48ac7b96a430bfa67fec7d8b605575dc85ea6b56e942fa86f03fcb0f097123a2fed6edce65f8f57b40ef2a4f77c194c8dd55c407962b21367c86a1aa402d8011df5b568ae0a5f7e9440a6bc721cd04b6cb18a1088c659d10119973915b7fbf1ee1796ed2130207d36330f0df7d5f4da0d6a1440b6468e09acf1a139d10a6bbc40984461f42e6f8c4549133e33930308cd5d4c05cfafa8ff1739d56034c48d36d1b4b37fb7a767e95d97161b762e2a72802016e268ea9fad70133505465d6e573732e4e767696b57b32c8bc0fae5527032aa6110502f5b648006dab9440367426514e307d694b3d93ce7ccd739a5bb9f99effcbc8878956873f3dc841e4e381dcfd433c2e7b93fd7fb534782eff9d58f14a1ab8dd3f5a95f265cd457241f0b99e4c5203917ad7b9b3d9ab914e91daf4a7b6150e1633c4d7a4abe84e8892d5c4013604314429e4388ef19607bc326f25e81547d8844b928e4afba64c1ed9f744e9230db1ade44b111fe1b4ce05a05586aa667f7b4d94462e1dc9373dfcd3f55729bbd5b8cda9c01c0f4d3fb8efb7ea5dd6269e2ffd89ffc46ab001c0cd157481ffe0fbc64de8c724c0bbc4ae6dfe84b53034a00000a03988bdc982a08b6054daa9f3b72d8b283545fb12ec98e0ac71dd64126d2e668ce3ca1c896a490aeab5b70b943 + +Input: 0c99f027e947bd1408fe151f72951f2136fddeefae90351b5874c4e5aafde8f5f458b4d042466f2133548fd647e631e623473f851d72b0afdb0b99aba93bc9fcdcecb907dda4cb5fae6b7c06fda702a83b54bde81062f650a626af9b5284846a977e838c472968c5e61fc0f0f49bffcede0743edb2f9cd026a04235d956530061029e97a7fa6108f0b58df5a803eb0f80c314767399a0fd66dbe531e220b2dce94088a973fe7c3c3cc522f640f5210954db192ab61f0af2a7918f66264bbaf74eb853ade1778b33b2ba975997c54463286332baf2cc162aace8d505c42dbab48e24b5a36d41835c3f20328bf0a1dc9beb08d710d0bacbc686ed979f12ce8a1b77edbd84311f07c8064488ec1b1e515bffc14427b62a2d97d1b99a8fd9f3f60ccecf85057000cc0bcd42c29ba +SHA3-256: f0e795d921e549dcfe208b8996a0acdfc73a9c6e4cf9f1a0702f2735b1f45faf +SHA3-512: 4bd4c0c3981741e016b6464a3d13b42a536124a6c6d74aac0f3e541cc7855f922c53e4f79f24a0b0cef31b7cfd39aae5cdcbbc87bb0e85ed4e7ccf77aaff5e02 +SHAKE-128: 255ab1fd554fc789595cdf9f95e4cd9369adc16791ab706ed626542206d6c7adb11eeba24a9cf32976d21bf99cc0c73f03fb7aea369de8e22095df32af9933ad8f3874375ba2d6a0eb11d7facdda7baca3886bfedb77589e4b9a20741da2d7979b29c494a3b8f790f8b47d4629b6643ad5cee0ba50856878327ab9514e7d367a649716081984e444de6bb10165f8b64d83101a1eca55ea012c6e29fb98c63cf6415e1bca81e32d185388b44e56ef2f302489f41d962889ddbf9f21f1a2b4c0e3f3d4c4205804563da057e4e03ada500de57f9775927f296622e94eb00756eab89676f9b960ebac35f14d92552eff3ecef853a620824515e436a6c366da3c7e6d7b6fbff9d7e5932c0433dc129506422f944fb9a52398671e8f432a892243927fffc6067fa9eee3c087e47a2360b1d19744974cda866880fbc4091ae6f3172e4b34f143f717e96d8232fab89ec65b5f6d4cdaffd814bbe19b669174790a1c33f2f1141255424bfaf1867546f9e929b65d4ae533bd44acd62be8147cc937eb2ea0321058a91fd83706f658b17746628058346204a94d10f9d63da2188defd65bbdbd3448d53587313cc0058f7130f2088f77da8f25a740cb3bf6d83a9f4fe6b6693fc9672b626eb3f9f8ec6a65d32cfd6a8a9d0298a2e6b8e76c566d8d4dbf83f43fed469c9b746f759ff99167c9acf439a908c27f73d0ee38b91dc579e81100c6 +SHAKE-256: 8f1f8b3e9fbca86320b40f2d5dc5f91cf5b3c0f08cae8817a0e5eee3c2399cf86ba7da59ab286ed5be296beb8dc23a215656b812dbb35277ae758f7297541b4225684d61c27a623eed9098f530c4a4b3f932de4c7d6805f1f96dbb91bc8b51ca8f7795b26afaae10b38e15f45ac32b13d0c4115996f3e63ac4a5bc8406323c407858f2b38bfb69a005a34664be565c0065deda78b2b860c6b5e4755b5d7cbde7c5752c861b66e8d7c11f82bbac2812e81708f08e6f8ace16ce23723ff0f3ad27802973dad283141c52e54a174d2c87874d9ab15a43ba8a9e67c1a5417426fc0f94dacdc272650a746228d69e0fb49b29f33e69b775bdacfe6d762d9609a373bac4adc95c538d1048d7ab753e876ebfaf94979cc50221c4fdd33e045b98ee4dd7eabde4c03a7a59ff5f848e60e1fa3ed5f01b9d6adda34e01cab2db45444d8f8200d40955ab883e0cfd1e7c36895a285f00b29fc3818de076198f707a45d7f820a0ddddc986d461f24c8720c926542c4b34d32dfe224693d5b99ff5bdb5365c79a84dc2035fc00ceb34fe8888fbc4cd659c23bf1a6803d4c4c0406d1a0039b9a57bf209a5504986eb0a705fa4ac90e827079711246b598e87c846afd9634d2958dc6384ab1e7b58c356569197a8cb29bc992f0925c7932ebaafe2e0badd8d361de607068929bf029abc650f0c114fa402183bdaa5a756b96552fbd978491e5a07 + +Input: d81404135b4e3d22f64935ae6670f51508f8f747290ce379436cd3e2921ae0be598dc8630d418eb2cf0210e5f763a31975d9c91664bae9843b6994f4b12a59b2dc0ef279ad23b5358e8429a3e53b9b4775913758c5068e27c67724528f44b818e37dadd3d4db39aa5c6494156bee3f5936a631a4c275f7e51c831ddc6f22367d530a6fa6db7d930634627326f825cef0a587675b31a31b5f3cbd72a0bad7c274d01d216ada8aa7441afa1fc5f43e6e9c5fcac25fbaaa33002188ae22a571b8a716f5f4443b9d620168a3f32cbd0190b9113a98d87df5fe85544b9b96dba4ea7a3184eed9c188178ed4434b92c64bec103539632fc0d02654c82a605d74da9892a5e1c74ea37b39ef4ecbc0abb5109f5a072e3deb515cbc2a22d85ca29327ce694f2d2eb640b746de04b1159684 +SHA3-256: 68399793d9d001f947cb2ed112e86f21e6783db0b20f5270334d7a958c309f89 +SHA3-512: 5ef7258f80f3cc8c204f28d17e943b724213332ba5178c9fa3eb25fa837ee07488d8d4be55f108420ceb4987337a608f9f0a31095d2f6680b35349c0916c9895 +SHAKE-128: 4e9f4b8cacdb5111718b75d4cbab35c21e98080d6d13e82cbacfb27860463e2f82ec59e8b603963e1b47ae2ecace8e568c6f5d296c431addef9f544aaf6eec4842ba1a2a1df55775a842026d15aedca1cc0de299a42de8182ece32846782fcc48b88ea341b4620dfa1677749dedb543c950c1ef64ef014feec9dad24d142bb5aee88884833bd28b70490ae005427f107f077a6a1225888bd402daaaa0d292f3ab44b11df93991b0754188fc0982602b3c31b459baf1c7d7fe04c9a692953668da98529c2a2a0b3b42c1859d8191aec4a9ec35933ccfea44212676d732b43ea032233fb0349bc1efe16d84aab8e9f448c6cb4398fe0d6678b129c6d5a042698dcb1de9711e262f0042927fae0ca04192a28a887376162ca65d45a9d7bdbb5be0665892ef0285836fefbcee3b0eefd90ee505b70382a3334189a6c56c0caa0585273c777cc11a5233652c5d3c60a6d01672080c07b97d560e72a09db8840f9164bd5f834315bd08f173e4e757cbbb05cb7c5d27149c3b3e2fe7fb7ae4c9081d704c6cd7daaf176baacca5aea448cc8d3ddb4077bd4a7588918f9c4b7e56c7d6d3a1dde34583d23250bdb8c953ed4100a95c7933784d8d6bdc65322e5a1aa99bbb87b02a75c275467d1b5053831ec252ee2c43261df8fdaecfe6441ffdb2d251936f7e83f8166d6fb635a9afbd2ecb9cf04bc8960a1077f972d0973f157331f445d +SHAKE-256: cceda327ba6ccb72d91d870ac94b0cfdf7ec88bf92acaea18d4a7376994b1617799eed29a6f52828d3e22fe0f40b097f9a56c06750f173e98491f83dab1ee4814d13286541ddbdfbdf2820fb0b56e859db0d2a99673c7e9528c96f5a03b671b4e23e6579b23c5ea5137f69fdaf74ece3d5b22174bf27f2f74679d473327da25fc25acea68ded49d1550527fa85448dbb32b4254bcaf5e8fd0363092ab1219ff42bcbcc3a1904fa2014252a2966dd029eaa16154597b69d56aec09afba11b092ed12b5cc5200e849cb056d23fc4753dab2aed05dd61eb681631a89337329f0a7a4cd7beb7f54f254e67c1f8fe91099d20020e86e49aa6c11574b175679fd978b23d776b85b3ec58b403862ed11c5350db58df924306a07b6477c6b395c02889752a185f8f215b6e8823e012af422caa0d31d92cf55545743c2321c5f0311877d1cacbc840941ee8af5d149fcb0e0433dbda6408726c3b58d1adf38990f1daf104899bd6c286ea3227dfac1a5bdcf308ea8a7149664273dc21cfb3d03c9ba595e14dfda33443a09e7f10fe57ddaf26cc3eceb2264aad815b294484def86b5de126a0beda10811e29284a93810a2bd617216e7f1db9546cfcee280c555d208520ff93fd37052dbe586f89bd2367ecf4795af027a3a3f79605fa62822de1eb71257b209e7e274623542e84b5962fb7bdf2b24a9df91fdfb928ac3cffa4ff82cefda6 + +Input: 56e1170b5215235cc8d04a0f9dc7a7ccb8ebeeacbf57fde85d3e48e4b27d8f8875d78378bfc4090e8ef412cd7ba5726c2036232b68808b890f2a5426c405d95530fdb7e48323a0bd38a81f2b311929158014ce84defcece71adf7f7a1b88f90cd69db82d32c7ce8a2c3fddd3647077c39b9c772f771b6992ed430196c840a4f0a3bb15382bb7e7bf852fc0ce79a0d3faeb1c6b6b4a872036104eef06baa13dfc19e75c575292d56a924f55b664ef2845d1422bc3b966b106bf60d6d3cc2e08ef548d838392451e9a34944e22af61d0a1056c37afd5357ebf6137a40142ac76e00dd8b4a31812ba559524c68770808dccb477dad7d0a7e84080d85b4d991b310e67313b6c948670e36b17a3176be2b7c93d0eac6f0407f10d0ff1906bd7caae57df621b7e9bc95a8e3fade6213e8a +SHA3-256: a48b35ccc7427b7a0da7c2c7b4e255095ca57f0fa5828b42f8e272e6d3c746ce +SHA3-512: 62bb63f7905f2555799a06a5bff681e31e69b2eab72466ded7a15fb453a64d324e8936e348c81e4c5ebf60ca8862241b60cbc5a251196dfe1e26c7e21eef2928 +SHAKE-128: 1b7a20ea2a6f95cc95de593fbd99a8ca79aadb5908b50e0014b1d2faaefcd9a6a4ecbcfc1109542719a28c4ab2abd4eb88b7bc700d592dfb736afb75a115d023351321c89bcd834ac24acf6d8b2c02f5204b168851d919308ea080574493e432a914df9269d2e2bd58ab515fb6cadee5482d7b5910bc3026541c35d216a8e8956d73dcdefc5199d141812d21f206b323f9ed602346557d4a092375c7d614668d67c61c3a15451bb814e48bc555dceeb107fdeb488cfcb4394878fb0b88ff5e0f408529125382f3de1879a3465f7f0e3252c1ce58a1b4ebb85f35b95dc0f3470c855403471c789027bc6c23f371d7a53d38f1fed2af644af7399add6d3ca6ab66a13d18028fd52fb90afbe3bfdf08f4aca16620740b60516020c5ab8a17a7ba1b6f267b41610f43ab5941a3ec94f74ebab67ab3b0f5158b7517ae7fffd30395b0fe3a41083f0711be3688859a8340bbe596144688aee4ac4f636050df93bc9b68934c6cd0b8a9b011605d53135d22e27dd9699d9b02df1578845c0e217a5322182acc3014fca4002399c854c5ddf50daa7548dc3fc65bcb96b9e09e402b97e1253792894bd8edab1345bbfc348682f6566059a9fff5464e88b28c0ceed1d5eaadcf55fb4359523ffc136b71148fde7a0b159f3bd4ca3d0fc4833ae3fae55c9e061f07639ee5eb13da7ee2e66c05eb1ed508c8faf4703a7b51747102a3efb6bb91 +SHAKE-256: a0e67a267d4b46f495525b7d1aeb4393259e7b7534d065083aea9aa5feba6874947b25a5fb19db5d398eb571c90e9d0efe900df181c3fc7ab9967cb73cac88f8d46126f9862c713fbab358cff4a84a7833a9bced274675bd89faaeb3660951a7812b80c24a65d4e2536a5e8bb24b99d45f458c04e3fb0203d148ffe03ee5a340dc358dedd0bbff09c4d14fafff489698b1cc0178ba74e1b8028a80a9cd10c1086bebeaad3bbd98dc885e440629640d3eca48db39c6af2064ca8ecb7a6d52f5e3c28e9ac9237658181a5d62954bbdc0325abc9337a502591d66b46368ca206aaa5a21bf1bdedf5dac276a1ae7f21d02f79a892e0ec3d0e249ed43b77a68ddb04fa14b67ed87e144bfcd6e182a7adbaceb77d7a12e352bc65370f1f320ae537d8f14db27901667d9cb28e58a96e7d73b2a939c01c1f888e3cb9ed4602dcd2ca9039301452f4543817dd7666a0ac8a0c7c4c082ef8fbdd5589bf923e8ef54007908242478b173b40277fcc6f3f8c9af2408426c6fe561b6d78568077fe3e39a7163b39295766081aaa8dc1fca8438a20fe2349c8d5a26449d3f7cff99665802a54bb0c8a34d6cf66fb335f5f92c392e8178626c9953c5f04fd1d241b35569423bba91e97c11f245649f71eb478a0fcc551bbfd6f3317912a8aaa26a6cf09a11c72ffa287745faf645ff268055bcb6569214759408f280aea774256b52d9a93b4406 + +Input: df11694153ce690b03478f30f41c6fef1346785b807762203650674d50163edf2b14d7663fa58b0e309f63a34acda80d640a6dd553364c6695c1874709819c3d468739e14e287dbd54a8c0c7b0190a044bda36bf215ad11e22e4fffa8e469cfd8e5378b5924f61dddfdd70167ec2bb8ed88437965f0c40a65d3cc4e21ec387226b085c123d54f29dc8146ae1a121d4d66812de29910e3c72f31d28109385ba2c9fa0715f686e856cccbecb6e7bf7fe7a133e517f59ce613113e79748f8fc87d9bc793dd16e5c7198e3ab70dffa143b3413b9a8dc79abd44c5d96a59b1b7199a97f0b8d45d6f32101e0a8c2fdb6bc2731ad1a482e48e5f61275770083776b3d70f449fbb12c8a0bba43a243972c9b0dae93e4f7d9b1dfd0edc9a687dad656edf579a84e5674ab4b3813f7bdc8f5e791 +SHA3-256: e0badee6b1666f94de06ed4b5b480f14bf1a9d68136655c86a657a9cf7e7fa51 +SHA3-512: 50087056808d631eaac97401eee467dcfba5faa819b988b41a40e3f6b440f1d5c67a3e9159deeef676dc5c110a035e96dd531b4951b69964ee71cd35c82fb6a1 +SHAKE-128: 003e1cf09cdadd457887a56eb2138cfb8475b3307e1c7b494da2298daf94722e33e3ffba04a3d621ff4817d9cc6adc5229eaf9a7a9a57bb39cf554171348f779ef53d4e8662dd8a9e3ba77593ae19d5147120d5c5f559fa1ffc1a2ea4cf4bc91f5fc579d8b3cbd181221f4d03549021c9a68f8c9a912ee09ba2cea394bd050d971ceee8bf77586d45ddab5eb3db35dd09d3f8fe8032826d53fb264c946f2eed8aebd670e6abe76abd8bcfb17c4b8554179f16bae1208bb387fbdd6d3783f5c76019ae43fb3693071625b328a2c055cfd6d72e2be532a73272c57263154e5cdde2657acfc48cfd2f0376a69402ed4555fc7a2a51fa2e8e1a7977caf05590ced902fe4946bf2156d21f00ddbda1c356ff57f9fcda5f06db28d8868abdf30a98709a85c9d0ff4792ec2cd88e4d19d99a78966d46222756247227fdb7b1cf9b8e3a855522956133dc5bc5321d1669b82dc53634e8c61056848a641941a861bf2f6bdfcf574e2bdd888be4cff5a8f42038bf763528e0db130b71820da35be1447975ee0e1bbf4f62ffc395254b48fbc97ce30f6205650b630014fe68f68bc9a5c2732db51055bba608e9c54fa6e7b3c5b0e6ca54a53c78c856bcacdb43ffd60edd40114195765c9a98dc61b13ab2dbf27322dcd5489b7b2138bea34de2f7635991c113f015413fdc9082198e944a7467c66d0fd191c2187f661edded4e836ddb7baf8 +SHAKE-256: 0861b8e77f6e1877e336374694d35f81ebf2382ce959ba6c59d0f2ce6a19379bac5e4f0db97496c2d6176a7644b6b2bc12d651f842f7d9f46d8fe89d5d18c21750aa70d86907f1df85907a2161839c16f7bfb2ad87cba4b46ea7e393fa405a663fe0157ebb43e6fe06602190f1f1d0750539c9e661dd6fc413f254b0de8fc64176206a532da402578d8c1ff1a4b0a31e58def3d2920ef8e4069e28597e175416a965545f402954247b7858fbfaacc3ec994c670e21d1e2b8d9c3eaa4d08e420d7ad975da66ce698aee4437073f93818d95b92b8fec0dabcd8489a63fecc556cbabda2601369703dc4a8e3095aa0ddee0bf13325e38dd0c9df2932ed86262a7a1ecdd374937dc3b2a606a8a97b83b12967ac7737f24fd9ea4b10917be4eef337b4235fbe4c92ab069931c0a0993bb7ad0d9da23c657bf9eb6a4621646e028085545d5a93561cd7f33b65752f1e50f7ec5dacf896061657ffaf525fc441340e60c7ecc6bd593e95342fb8d5eba6db314780bf44f724df877e0bafbda6207d9986758ae96e8a63375a5812aae28c10fc75a4956600f3bcd8a1a3c3cb89cb80da9ac2a878e531741d217d4a1eb7466c200a6f9a5ef98142a0a6a6d81d76376f7a48bf36e8693bb12648be58e9c31081c86a929be6597d001f4ece5c5b8ceb0e6dadc58e46a06d0edae4175f3ab07a62030fa3b1c2ffff51213d424c2e4db59c4a07b + +Input: f37516016bb9b67587f6518b2e19d04ca307170111b9744ef895b208c62aa576b86a40e7933f3f1c0a8abd79074802d9bb0589db4dad5997220d3cd712d16c6ecade2d72fdfc77bfdf6bf402ffb9642db1ef17a5d70dbaa4b874c170a256fa23f298257bf63a2b39b4a523bbdb5adca54bc8ceb3a1d45bc61ac9fc71b0790d6db5c4eb952fb25fe8fb464011df75698cd22fb644058807a9cb1d43eaa57153b23507c94b1c380955eae106e56d365efdb9a67e5af132a7662a4c947cad2a41e0e32fd701d660b7246d972fe48e96db0f4ca686c3366134f5445c31c3206e2a4a2a9db2a939d775c08bef8238f93cf17d787a483273b05e2eb7dbc7d1a32aff8c8b1582ae91cab2a5fbff6ab61626b067471919fa94ef678329cc734c76450b2bb1cd25782da077e2e49d7334aede1204 +SHA3-256: ed116a22632a8b54a6f6667811d5467f5f902007861c7961b00517afe2aef3e2 +SHA3-512: be77b550f7c1bef8a8a0833d0c5516d726cf7ba24aec15c9000e8fbdae807487070e1c46659ada850e70230b09ecb9304848ad091e12b996da839d66706912fa +SHAKE-128: 40fa9a1ce9f50c3f97300c73c30ccef4349cc73800b9bb307d78a85da4cc9cf072d9d3bcfea0f36bd5a67d3ba408344b49a23d33c05e06fae1aadaa16401a3a2c04eea1551f84a8ecf9af84356629ae12ac0644468f3d516921eadc30ed9435371609945c313bce96997f07c34b9adfa77e4cd9daa7b8e5204878468371c2aa32dc193431d2916f81379361dce1164ece6ff222aceb48c20738ca732ca46670191ff614531928ec815a88e4b1b2ff3609778868d19605a0a7f02fa94c6ea5b97e17ebea252e1a83d317419cc9eb3b979415d0a627622b9c1383c997752f228d7f91e6d53f44b31ef00350d1dc3703b2e0a4964ee55963ef635df9983f3a0f9944cf564bbff83ca8454d917a1e7e09442665f662572b4e6070f3f36cceda076a3bb8cc1ac6b6a2ac2e99eda1c04f351272d77e3b02ace7efc6ebc95e8d732cb9cf655eda636647499f0e3e7a19364da118b7294ae9aaa0e0f1c265c42f9fcdd3e6d31420dd3c3c63818c07940286f2fd007a290588ed12e68a0a5d5d280bc89feee1696727c06c3e81a87c16e42279a5df55c975b0865fb33740a2c47000d3adbfec7c98077594d5d1ce5f5ecf5f57d27e568dbd7d5ff96632b4b8a7e708fe2506fbbd390801e39fdfd843e3f27f6acd7041ed05b3762b3d975b83cf960288bc678adca9750b4a027c10d4f6370278bcc4eeff4cfdc0d6a46abf160ff48e5ca7e +SHAKE-256: 65afe99cf9ccc48b1cc743681aa8e693800cebe8a84e59e1427e0efe3fc383b4be164d139140e793a02f871aefa7d0e147623116cfa9e8ca7f6d13418857a31afe779ce7ec0836544789d5786a6c1781021e2a1b313c05ccbb0b75568b9c8480e69d3594e029543726351d35981725801ae82816a6bc20609cb12f6473a8d119d5f3d0149a3ff57e90ac3aa414898eb1de44ed55489d54aa93216517218305c4673cf7f66fce48108f24d83eb4b4934911cf6abfc4186a564790aec4a24788a26646cd344e3bd9ea84227162030ba5c27fba205c35fa8393e590423136536cf6d07ca31652b1b3d25be100246f1e41d1ea2ad28c6ed7b2b040df31033a819aec2f507e242ddf9e695ea3f6d1f64fc7c4bd6841fced22d512f6123c5224b4017c4ffd250f483371eaea7b4f6d39e30948007539697284a5b6e8d0e384115a985c9c75f178e34f72dc328b93df95471dfb7ff7704a52aff53e07b9fe106a25d1b807c21af9aa0f29a2fb6ecfbb87c4bea000b34d972aa8be60c7af6a9dfaf73e9fead417df0fdeadfee97fb297842710485f6ec05d663fd5063e3eb47f041a0db0166e6993b4082edf94dcc86c470ab7e4628629bda799c13c4b691b7673a6a6aab49c4a583d59917cf6a01a605a6390af53fbeb8ff2a1ca1348ab2c788b099273ca36717385cb8f834f3db669ee20677cba90b118d818af6e9a8b39732566b40e + +Input: 81becbda93498502a81d61d6a92d028b8cdb474d679565581a3bfe8e8f2693739a1312d03edaacfc565a97376c807cc94d1fd010859a197a942cfc58168e1327120579ded3cc24fe84778fbc7680e3956a5f1745533e2129cf5fafe4a5c6355c752ba0948b329150e94ea99eb88069a34065cb02e299f307684cd072945347104fe4a856296dba9cfaf18d64dc1baf907d792d1efc1a58ae08251e418f1d9d74f3f5c9db0455fa888eb5675ee7596a611065bb779c8eabe6dd27947f4bb8275289632295ec54cac1f906581b9fbdc98e8d283a4ad96e7f514cc0e2e2c9aed4d737759e02c633acc2e18240e3d958eb37dafa959b0f79a4f1f8881f72e7655ca226c46c962eb905d33edd5d79120525a6e1fb0b0870c8d90a73a6c1831c010b277ef5ba56e8f72a87d5685ae150eab893c9 +SHA3-256: 5659d1214b4a59ec8a18495848d78d0b80da4e05da29436f08a87ab7fad67c72 +SHA3-512: 18ff6ef11161cf1ec6c7d787828fb8935476955b1b484534884bdfc3fa80093b57736f1814c2f7b9a0e287367e1ecc3692a55f2dbf9d85461e6393ca53790231 +SHAKE-128: 798ab31d47271a183bf8cbcf098959d5a2112bdef2ae2aa335f85d8b771cdb81851d9ea66fb7a0895efa095155ac416b2708944291e0bda2a3c520285072ad10984c17f471f5d2fb740f7d35c51f9746140e6920b4abc43653cdc48150dc56f1ae5ce3871bd241bde4d51a74e8e26439b9590901009f908bafdc21d743fbed9bb804a95d17d8991e1c67e5aa5b1f766e9dfad1469777327145c63f5b83d79a784ca399d7924db0f602b98d4fde28d68e57b0d566c2252083c99f39d86a0497f7ab2537bb6c4f040c551a127590fe4f76ca46041273e90179eaa589c49792ee3b7d83ba2c812ffad719faeda527288f159c813c7bd398821c04c959830c8141b0ec50090f3a743ec273d47edbcda9dfab0fbc0716c6a02bd809128fc6ec3156d7b90fc312f814778a524a91c65360a998cc62bbe7cbba984cbc027dbf145938cda6124f090d51e1e907d7ef0251b069c0e4e93d47c7f1022274e3aa46f10bdc35ff4221f4e8ca111f11e5b2376ef2463e6ac28c19ec3b8c0a7c2b7b61a60cf2475c9222e02fa1b33ec7ba674b3a4820eb1d6be05e09da2a7ef80337492f45f01048153dea63c36e236488bf0177f9f776b240c5a98770e1e7c8439c16644daf530f0609a16d9d0e4ded59d6a74086ce45346bd9f6a8f340fe3961472d09019bdd8d8e800f2a4e18a93c8b9485ac35e7de3af82a25b608c3c7280b336e1ae0f739 +SHAKE-256: 2a58e4ed7c82856574cdce494e183b943a2a73bdfb6d54d3fdadd7bd9791cdb24c5e49395545c3f0712c1320894753ca739a1edf2a810bb8f0efff45218537b064afbb2fe269cd6138ecf2b467547cf0f7a7d654007bc7019f43f11633e979f1391e1e0240b6baac485e49135ffe8c97da60c0f349d2021b3f69f0f9e8d12fbf5d0b733d89ddf09102c93635da5660ed705f6e24ec49591c5fa5c9c91d0c2f22c594f1e292d263fe76676a4778c803a15c7902b5984cab8ece4f6f088cce45056c283c60751c34416a58d9bdb33c5350290d6fb325b0a276aaa7400a6c7f60e6bd6d81a4bb9824ec1417798961508d2201daa8139640d641b8103401e403f4e04f3277ba64c5215c72895e93692ca9400b43c6a01da9c4940b9d30807060ea5a80fbd043675de7e977f2ec3a117a0c6e4130cd5481cfcc7d38e309dd996d0d0ea510f8bbd0ac8f10c70fcb8ba321293dc6010eba9d3b867f6578b6ca2bccef080c8d9236dd3b3d985a50f8b0b9ebf7c9c910dc407afb1f6725748e9372cea88b6358a44a483381ca71137d60fa69a05d91d701cf5e4b65cfe2cf28fbc126863cf34913c983775454601f5236162b0945b0f9725d360f68ba48f5ce1a8d9181f92c2833ea4f57171e3515b8e50f2ab558cb3b47b4f14e10dc00cc1ba3584f2c7dd2e97cb67f25530449a042b2287bbae48f74074d11104fa2b8436804a0d0ad27 + +Input: ca4315c46acd97c37b76970d61050102e7ddb1e4f95db0c81fc9d55612a1afe71a2b036c64ad864c4550fb6b9377a7bf95165df87afed684c58ca205a2b39292b28a0838ddcb9f2385aa6c09f1e3b6bfe1f2a01178db8bcf9173faf88c47f725f0abe9e2e821c5c855bc309331bb77e4dd1065950cf25b8b80d59ae78ba07ac2edcfe8b47fce1bae3c3855c4c886fac4f4408e65053e6384ecc55ff3d596977d4d7210d08694023b6dd813f3662aaddaadb507485093801ef03af9c81325f57dbcd06e6967dd1d81502453f91021dd8e07d19eb85e25cca18ab58a3e90d4cdda237eb34fc2522c6fc6409ceb06d4fc80e9f1f73f9a5879f120ec265a4df75e9620df5d3086aab7f7917098d746bacb9c6bbf500ff5ebe8625e97253fa74ddf65a29365f760c60db718fa6df6e61125297e45 +SHA3-256: 04a8f7204bcefb506b572dd5c8538b287046e43e5066815151bb3c6e6dbcb253 +SHA3-512: ccc71224fb9dd702111fdb9dd7a593077024992650021cdfed0a4ff7e2f3ab655e94e85646a507cb3de4dfefbb013d220100cf325f33e628c33d66705d1b5537 +SHAKE-128: 989c604d033bd74c50b8261446a699799f856cfb1f6d3a936262692a822cc1d5d64bd8e510332b65f7fd4ef492fd3a21f3641a83527e8a44ad7122256a8733c01baff7e9bf34fff86458dffcc27bb3ec41fe266ef1459e98bfe7dd900838e93705c2e75d762ee58d24a21882a5b0ae4631480fc23ab203db612073fc4f30d60b949394cf9a02eee44a57fefe9733b5ff103b280862300e824e532edbe53088612152412d982e0625a33d4f5bcf34ed45d6f92ba489e73f06a684c4bc2016a6e2cf591a18f9c0464140ada6efb5d70ddf91fd0572c468cbe583bd455cb7f8f644fc68df1688fa57e066101185b59e0c3b970b4bc17bfdcce7741e8b4dad8e144fdc34471d8cbc7a446c5bd73e074fec09292631473ff17b9b140be876a403e1e13cbcb6dd0d8dc9c70354bd097d0cd511d48eb7dc1ad1de42bf20fb03e4f853f86fea6e8c8ff5d20bfbb7d6dc89260f86794253dfc719a876b5ae64f1fde3c374f6611f6f9e1bf439016f79025b7b76a6faab937538764f35d6f746f5f6e89adda68249d4e35fc8744fa165cb3c18c5b78c8db48ba710d156e9ffee11bbaa063e86e7d073d0e03a5be5f3d2b82465f3407d4009f10d331d0730b95fb17e13726d628991c277d023c1bc9b7f78e7d0f279da39aa89df6a83baaea4a2cc2169252385bd6d33e23e2b837dd3d88deddddd238ce620087af8548556020e2d0c937638 +SHAKE-256: 87886ccaa45a414cd7226cccba707a264804e0dbd539afed16e020a4a68527f19eb0ecd269f69755ed7723f5e2403b63bc7c58061605b55892b714b2c3ecadc0aa2103311be3e0c25b4307b314e0e518d083c4ab42e3fcfab9a1791beb188d3e7040a254ce8b69b08dc94375790b143caaff270e1278c63ec914186d8169dc0b680bdc906b75595dcc59cd8acc2b2adfbe736bd0147f3578e5438ab3458c19f8731cc23ea1a0fc1b69f0d3aafb6f2269fd6bdde52bd14409d245df5f6cb13b88f601db75a884200eba9c4094ed81785ed35fd95e43d4eb4ff786b28d9bd02e576c01b62f8e751004e8810ecf5878364b24e960467f643142b24f1b7fbbd89a93e8ec653cb67d7111ba52635d6967db0bb16fcfc96fe06715cfbf7bba1bed5072a7be2aaedf3ef7a97b6fd97e5d07043764af8d6726e7e583190bf357751ebb2aac644d30c53fca9a8a3da5cb6a812c45bb2e6b060dbab51c04c3272572a03122f47fbfb3def82c301cfa386282b997e18392aa4a07f051ad348f37a16c506828e32e75574425604c52b185c6e8895f02c6ab56b292856be9ca033bfed6cd183d51166e4c93eed9569b621fff08231fbbb95d6238f3e20be4d99ddc2d4f9c7215e619d9208895d1aa321c2f28b20c32dd750cb76a2dc1a004985d30b3a15ad57a16e69e70494a7b5dadc0cc4f10e272c4d1a822c2fe6bab6a05a4c4826078a353 + +Input: aeb5fcc949ee6cd5ecc0aa6bc5d9f1aa6e87894fb4c44ea73a17256b9066a32b6dc94a7c3013e4e27d925b7b702ef867b071345dd3238796118b980be568aadde3ee973096e5c8881bd4f466818d523a7202b6b4c8da3f9bb8d751a101595f68874533d59ec7eaedff2820853d1bb8a62b92ab924d80e6468bfbce3b7629953e3e1dc147bc98038694ce4f5af655541fb493f855f62e0031a7e52541c9f085bee4c6d12b5f8299245251102ec255d9090641e29d4cafb947bd81d1c73e689a7594c0e00fac67cf0c4e9aa8a5ab059478e77d4c9207a5eab82ac15046d139419aa12bf0bbde8eec6ac57658dd9261f78e9eaa06aa945f606ec342422922ab04e511aa13861f84249e9734b38154ee647cb277560aa2ce7dace4484b1001155d790d8084edac135a8255274638af773139e5c509 +SHA3-256: a96105072cf5b42026579dd80baec04ebfd7a536d9a8f37265eb69c585ae0934 +SHA3-512: c57adbe65452a3b420c9b851c0293de9a891bbad2de7877580a772a6364620bd69f3fcd2fb7e7347c52db8a5b5c003662a32c7f3f4a5b31e80b05603d47ecd9e +SHAKE-128: 7dba93f35ddd5b5bdfd0afe5740e2160590db05925fa1342696a2f2e14a9b8722f6a10ef9a77f90f363814f0a61dd4f40d66a9112480fb7fa44d9b58f08ab2d0972e406347c89ba77892c13bbf0803d3d0577b3a5058144f42478b06dbb25395ba5fbd788a24eb963e8cba502b93cac69e0f5f0a187570361eb1319ed5e3d56f6cbcab89d12405deeee2a4a14353465e1c767be01e5f21bd40bd71d77cc1ab1d1a8b0df40769812e98b63f0ea9bb69c939acdec5c8ccbe3e19dc0318daf63331ab86be40c622f743619eafa9fe284f92f8ed283313e372f30c69a75d1420fc2b3cc8b1759f3ab57b48d2eaeaef88f4a2f44eb4aad86a95e3d8dbacac9797ae9eeb37cf1a6407af72e89bd6ccc32ec972f2172499652b5bc525e7e634e1a4a07b7addd8e59024fc6dcd8d9841274e80ea898da517ea03728ed48ad53d8c84e3d4db4b73d2f680cd57a667d0a00d07198c1b7d29b8d7c683c4e34dd380afe03d2b5ae4a807500fb67d37f33591b2210d07d1cf52f2bdc62dc3eeac6a9a71f6c7180cc02aa92da26e9becf2a6e6fdbe25a91159d62ffbcbf4ad64b1eab0cbdf3aa64e809250d3d57c317f4ba48c4ce56f02a8d214b7fad6404c75e8ed0f387ab9b72997619f624823ab3c40dae2b2735565829f5f30ff5a4b496f53860dd764c01e18fa53d97970bfcb0c40c292e639a1dc638bc232913db2a90e9e6af7dea852c7 +SHAKE-256: e3319fbf8e3a1d2e32b7a8bf40b969db5f3f6e2de978a06eba27007a9c03f0a6d32643b9db01296a4ccf984d4791a8793660ddb5a366d2970bffbf31622e3a9245082f5b8bcdd64a11ae49d92f4ed52ffc5cff64d2e093aaa495e9426d5825021776db47424b8970461fd8518185083d2e36eac7375b84655da44f49efccd35502fedd3495af29d2d4448bb4a74eb05857a7c3d9d9cda121c93f705be58f82855ec9917a52e131d6578094cebc46c02c76c6074f6f736546e47047ecf3fb6b68aff99204baf80fbbffee85a58cde71c4db782591f45607f7213d2b00b4d29c2c15d9893c6be0e63681cc720bcbe8b14cd32c0821bbc950882145646d0c8637c44d74d9a6e933660f7b44239d53b88d7707942c7dd78791808c43faa51e720989e5303f966b4234363afe34fda0ad1bc7d2742acdf0c12b50de2d794696103852c3900526c35d842098f7b5b31339304769637c9aa7fadb716a476ad2777ace5a8e1a96bca143c770cf524474a2c3f43614b09b9daf227e9cdbc0413bef32d4c6eee4b63289f89bd7fd31b3798d7b5026592e75d55bdb8ceef3459f747b27e0292dd8f27bd43fac59cc01a9e8db04d0dd636b71832f875769bf7d926ae198cea4333ef768cf8b895c6ff7083126e1d8908ec8096b24679def39db34cf0dc7040f102ba09dc09bd576c5e830cf7e45ad25bcf1aa6e5c1a19448b3c756aa703bcbb + +Input: d4b2636cecb58dc9b609f23176e1610734ccc3aeefd2d33c1a8a40850c0dd908b587cd6d03099bbf9e5983b4f83757c7c1c276af01ac1f30a5391dd7ebf8cdc6b248974c77ee5ef11e4e73e447814331b644ef53a13c47ecb01bdb62298e6294c85cf28ff027009fcfcf68579d7a7b20aaba88bef69db0861e285269b7eeb43b9b8f379b1ae94ac0a7e82150012060aa74d4145e50bbf202da20a7ecd3cb5cee3a80d797af95875f0fe11d92fe1e9293ce81cd637d47792a0462a123b6ab5ae50ac3cbe737f3f17c65d5748abde58d2d18642a09531f11820393c74fe327c885d8061b0e1d29e4392c2ae227d6d0b0e19e432c78f329569d2f9aa4a68f7f19e259e5c26806955202c21a4d833a91f2dfc9dae0134aa441c656696b1c1c77443f2271891e2016c9f68747992c932a500ae6124e8d +SHA3-256: bf62b289e163f452a2fa2192aac373ec0af03104f2415b5c424e0452261dc28a +SHA3-512: 94bcd370a29f9dfc5234f8f715562004822facad148c1fc2bdcd8b42888d33551052c16d80f6f96836aab079b9ee45208c2f5f04bbf923bb23714b8597bbeea4 +SHAKE-128: 92f4a04bc9021340e60c55efc5f816abae9580fdba462be1a5e68c465360b52fc386594161c8ea486609bc48cc53713f607e994b9b5d05e14308b20c3801b72ace6dbee33612a05dda6ab8bc4e407e53b3e125225e52b1fd6a817e05efcc41270879a9dc7bca0428ccf083b986d65b2f6b8b22ca09d6fb664d18aaabd1e31a6b8465d7ad76cd4aebe42eeded7588318eb9790fc4cf7ac041b7d3c28c707987ea2df80cb927d0cd52718643af358133ad4fb2341554a64d6f35ffe714aac14524ee7f9a4fa5c233d62d6b4560014718c9d2b4bfc6f48cb38543e283e99b95d285593d06cb39f1b9801c4f80efb68bf5d4d89c103501259a2ad9a4939b7296273d7da5b4813929e1a5d13e2e2382dcb586d5e252191a30ebae9c42b3a286324ca2a88d22fe8bf44f5d6fe072ceb5e18df8213e93c9fe4128e2a5fdc8a845b883b1d89d85a944aaecdb6f13480e0882e1ad09fc5a08e10d53a18c5e46bf9143cdf3d35aac197298793851a72250284392edf2436e49d79b81688ddb3da42e580a474db679e7837f11cde308586e2b27f65be0ae5ca80c7167b46f8ad5636b3d8dd9b5f2bbf67b196964f0e9d36d62c7497b276243a694a355c2930d81b04ef395b7a252d1ec48d8b9f9f2292c3424eab4cfe66feec42004b6787477c33cec6dcbcf6ccb40f3645c9ae2b85a2b2a35df6f9b21ac956a1b9d25ae77d79cc178d122b1 +SHAKE-256: e688a2b9bd422c5bb54703a949f8d54214c3bf32c73f2765daf19486443ff8254f609fe973c742bcf23bbbbc3bad967a209ea6a52d28034d20c9890587b3ba8631cd8ced9cb363b31349308c01459efa1f2025b097fef3ddeb565f8f1d50653ada6334c069c59974b7b87f5fe4d3d2ce11630923a26ac1aea5a67d469577ffdc3f6b7353e08d8599a5d1f5539189163cfb9ebfa2b651bd9edf3121a36e2f791d6d589ef4fb0a8d389e8f9bbec689fadd9dc7a224b27c9f2465353efe5606e3b02ab4947bc59af41228713ffa8ce130b059100cc5423242099a4d2cceda23a399e6619e245166da0918cf37f2a80d50b173150536edd7aaaf75aa3f76f26004eb510dd08135e9b3faef8aaec0086fc4dc27a6505de254115be72a81592359c3c9ce6b664bc80a7ec7197393014d4ab312b5d0d9e2d0feaa2e5e750c16ddb5722000dbfc98dcf90a414a26454f2bc47811f615a0024c214ed3937fc784471c20c5b6f30e9f807be33c917059f2099696a279d2b24cb36752262af828ece6f43c7d112441b00a88ddedee244ab76b49d95143b499a82b8a102e02d14e1d27695602b5111d91e170272fa7a5acc3d89bda2c0224ac667421e4d694b5c9bb2d766f0046689938fd829ee6c9fe09f4343691e06e3b2855560232771eb2f9ab9091016ba7b9169005b7540e0065c717e9f6aa63d2a0cbb5e6dbaf632d193b54e7a69f3e + +Input: 8714c209c0aa593f0705a04d8e1bc75a0e40dd7108897ad56d6ded5d43865c43cf03e9bf9f0b289603cb4c68eda72756e1e21665a309e8ae196cc25d448f189c2ce0da87a2ec91f3838698c97c38b613a8501c7549ab6c12a6fc6694db8cda928974c0bdf57acffdcad0b3ec1e25223d8f802d0edeeb63565799dc4599ce7c246b955d9a10c32aa8b8ae662a6fe5e7b28c7b8d038e542722813e86937f986a593ecc0ad73839e68caedf8b6e5b874143cbaa2d56130cd1636441c7a4d9379086af32456e7f6e7b37237487b4aca56ca9a8b1d778102db398d5bbd799c59fb23c6ee521fa14de662e80cd42d0ae1037147fd25a4a50e648d5c2d09c44b00e748136a55ed0890a186331d2cf5f46b5b53128bdd90125591494d1ca12e55eeefc435096a36dcd12e8e9eba69e7f77cd2593f963e34f3c +SHA3-256: 81c54e87445e06e4570baa37a8265f09d2cdeeb0c56f1f7d7080a93dea98aacb +SHA3-512: 11ae6931acd2050cba25c5cbb4e1b1b069167ecd2a15e957643b7c591a73150c3d9fdbb62d837740be8fa9a2898a649c41b3ea18b417ee2a73c56695d8cedbc2 +SHAKE-128: dfb24270828d067dc43e48a4d591bf864e4334370353754b7abf959a86de9b7ace18489c5ccde0b27c1f4d8ab280512f625e64de3a9a26e1502b60ce37e8fc32f92780d59a8e5d2a54241f7d90a7fdd596cb0954fe6d1c4e26decce70113f086f8916dd2e311a87f24d07a0cfb4b305ae0fd655075f5b575c4d2ab2d3c29979c68cf9ccb224fcd6554b062877777d2e649576ca205b7fc846ac8173942d55fa2e5261836dd153907c99ec5a02fb0c0dcbab6fbb0363e7369509f30868eeb948c384279dd6adeea1945c1b4234d4108f503a54768d90b4f966382304c7bb64b8f16ed6d2c0e32a59c2dd69273c6c74a240b1fdb779e72ab708d8da1e9107a2c3fdb98f0ec1aa298c2daed3f76025b71bfa647d94abb60e30296669d9c229da64a6229b8dca15b690c98ddc1a8f33d6819fbfb48e44209fb238bd0ff8255e314760eed6d6ee9796128cf94b37c0c19723250143aaa177bda71a03c9ada47575faacaed10f8f4fbca035db31efde36c30fdbe5375298f0b89fc3d3c6a75f9781e3e382946c56a520d2e15966ed0b0f94da33e642dbfa98f155c724c5879967705b3b126152245e264916bad5ece113e3942b17e7eda61c6fc6544c58bf0d217aa8060dbe4290542ccd8ac2197cf5e4dd1ba4ccfbc32d97752e3b5824504b530d3383cffb730a560ed985c8a0f7472bd7dd69286f7102b51aecba24d2b2dce913ac5 +SHAKE-256: a10c45b31c5e7325938672f39f054f2710d321dba546a45f9d28b4a7c76ec4a1e4773c44da280d1cfa6145335af265eb40267f59047b35981628326a520258aa98592d8ab77c5f9053b9900a1b95ed30438a10f72ea5397258b15d718381fad4bf26552a79edc931a5a20266da3fbf7c796cc58e6c824162d80ee4e5fdd03a3c49a149fb4dcf5d08090f9a01c8043428f523f10c78522223cbf63be2495632e9bd704ca81429310abfe25990067ec213c1a01223133b86e3ae3393339a33ac5ced8a1617640c4ea7216b43d2eb24de9a4b5187ad90c3742f0d81bda5e93a967f5c7e1cac8203ef00748bfee124a91481bc5975195933867968cd0c71bcf880a901037b74281ef4e6500867f246e67c3a3635c407c01a739ab61328b2e69a7a22cf0104cd81524eeaecab8e16961bd7c91ac061f4833e7dfb808c549961768c4ff2cbcc56160549c895175a77e72dbdc0245845594876c8a051cee9f1aa329b2df3393810fd34ccd23ab626c0e067f74b05fe63144c270ce96efdf645b8e8dd789d9daecaa7207b506bbdf49c60ed29d5417aaa8d1168542744f61ae8d26cbd41c426abab0acfcdd7967adf3ab002f740d0349111e82e601ffe5fc3ac8330b66ee4a52a5910c34df7f0dda3074d9852a91ea47ae36ce7f597cf733ae9890b37c318b42e20e65b710dd317135f004e7292784edb394456e92c2f6e3c47f9994d8c + +Input: e54321a971715c43d925a82e5b645dbd387b5f0e349b2d52269766e3040c95b1808bb6233f9a51ab5217a09fef77be9a67e15c13552f614c0855e8b0caefbd6e077449bc6a047d452b15d6ab8f308867355b6f47c9b1ef3f900a5ed1511cf2139db7cc34cbd72a2c2d0c209d7f2b2cf2cd81bd25937fb68d5662a61dba638381f61db2886fc47481f421307a237f27f164f243065b6621c38b57b4a018a8d1ea8bc75f6a3fe71dfea4369d42354bc172d55ffde7292f28b175bb935d2fd7cbc98d4b94957717951b5b593ec04ecc4f7eeb5de374c8b91473dcbc70cab2b3fa0c8fd0702e1c26a1fe3e8dbc11c8c93af23650f68fdf4a05106f706155e58cdb6618452f16e6a94db0acd71cf8af9ee87bc5ba0c79838e1a4f9470f5270bfbe04be5b34d1a20c81402e151f3b7ff34d7d0974609aa2eff +SHA3-256: fdf566636c4f16c36e30e1be3ac463f14cd82db3741e425655c823a77690aaff +SHA3-512: 6b68d0e5f9a6f9a27572a24e1741cb401e2289f2d2d136b355ffbf1ed182c4f1116557245e6265c8b17d109b2dc598d345008950819a1944fce2d57791d4e4d3 +SHAKE-128: 091a11385245197de133305bdfc7a131524a5305b98fc301ec405fc6a70e497a9e4a4325d9c8e620bd0939105346ef8978fa147bf6e739a69416ff44936dc379ae1567e3e3b16ec180985501be9f7b1ff858d257d213d832f19628f1e2f67ef088723b5c3506fbd883c996e354fe9d598da95796ad8986da1f4b9d2cca268b7e3c9310456a1b768730a4b3bdc750fb963f5d4e4d9b5d5379e11129cf8cc4c980de97979df6b0fb343b096288238a39f55cc78d16a732fc92ed95cee8f3eddcde6b4335d68537d565623945c2797bec030938813b7ff3472f33e41884d0dd9ec216fa725b0bd9f9d2d4a75eae78878765e8f72273c3d13621958c95c3b0bd90bcd7651fd9b454e608f06a2b7b549275b78993be6ebd4d1fc3b8fef839cc0d0fd6bfe99b388dd0ef3546cf411b9be870eb29387c86edce90ee0b83a39866f337ac59c72803cf0148005818fc7273bb1aa39d18196db789eb9de9e71e6a753e8136b57bda12f953d1d0a22f86c401aae71fde12d908f90ddf6be3d76913912906c0cf59b5b0ddeec54f5ae1d1308632bab9875bd27a710fdab47f43aebcd94061cfbdbbcb8325e991bcc74d635c18f478efa1bde3af0dcce40c11bdcb06cc8135b61a60faab0e4571d861bfa2cb8487a1d9982cc3024fb5cd78e08665b66f701d06da4fe589671faf133259d50e26efa689d6b72715d29c543de3261c6d457261b1 +SHAKE-256: 44b660a5a4df9bb7c7777ef04804d6ff315ee50ea68f7ff62ff8218d063991f75f4d63bbbaf131a32d36245a397c33563a4f721d8c17ff2d28570442cece41cc63928581e23ec493ed7c8e2fa7e90f19a3d6531c19cebdd1ec3ee2d8c751488b99b00155dc4b6052496332ea9730d9b327b5da9c6954cfc971e239824e6588e0f2a2f7169994e231e0b84d81a17425cac347956737e5b1a793e3907ae4559ba1a0ccb9df030637d0a7dd43b2a7661e992931bbc7acb67552a8661ae27dfb379d8383190a6c6ee65f49001494ed95b86b92e6c71126745702e28d462a3df6e218a36f2699546f269e9817c03e41efc86786c88fa6d2f7c9a8bc216328b42c13d6434199c686c652a65a61e4675616d1b9bb3e373b1e67f1e2f682e3294b2d8fcfbfe6af56fc082610dc0f5f7438946f27136c2575d6cd71891471f8c091c8da4831a4ac683b7b3f5ff89088e41ae29172a74e841ef32ab507d3431bd052de6457b3ba531c8dfdfba5c76ee961045e497f35e4e165ea952f95030d5a8f9473721720e3dd28d1822695a0bec894adeda611e384b86d2d8ec893a723cb5ce176019250da8cd64e9edcba8f927e211d5564f77642e41e09d6fd22e11b48d48fb9b19ea7d5e06868ed450720f55e8bfcded2505d91be002ffbc748fe70542cdfacbe7eec921b4deaf9ff66386f94eace732d49b0a61e376ce4d5be23a278c538447ec8 + +Input: d9a389d68743a155209f4699c94d3b1aef9320bc29386bd6ba49a86b575ae386220c03d04470f8ef149b5c46b75fcff237ea98ac264802dc1ba1c8830091793e5a1e104fea96bf467cbdbf8fbed2ec7eae1a34edd16d96a65ccedb8ed178686beeb5a582ee57bdf7661e29a644aa464a60068ac4ac137ba91e668eb91fc29023106101be77a2cd77173c7cfdb2e010e6a2a494eabc1fa9c1672c5fd5418792e44f359a8bf59da29bfd167e94e5d93bd98268ea145a530821175ecaf05f4d1ec79c13c461cea3eeca48c05b570f47a1879adcfb75645ddf80feb56302400614edb9c810b11c010df854c9b42670172244e6d7df5e892fa0adcad17c7ea57c9398263475a9a8e02576841c46b892044bccea5ad61ba753ebc437ca800dab72cb5b2c31b38653b2bddd817561acaf27504e8912cb2323dd49 +SHA3-256: 09d138cc642814ff6ffa408c0a146997255b3b1b28fbf2dc56cc4343dad3324c +SHA3-512: db06ec9ddc3f5aabed07918360e3e8e7e246bc2e6a307d32bd1ab3165a787a1b41b623e5536ddaeaf7d4ab272587c19348b6ae4ea1718bafc59ca018df6676a8 +SHAKE-128: 88ce7827185232203589eabbc4adac928941bd99de5f75bb8f6813405cdd52919fba4c5be7aa45f832504ed4d4e3a7a8b3a16fd6e05e037940a8acdaadda831985eb87cc9811a7706129001a107670f7dd2568f79a90c0f61db2a4a0b4920f179f782d21f8aff1e966ee18cbbfc0743d25ed703cc793d032302f3bc867927343473b8981339ea112eeabd3d6c6674b8a28839bf866ce7581304686d2b49ddc8442ddf7ea5abd90d1f07424da33765f8d61e0364703f0065201f1cf7a70c6f02b05dec67f3264e510249a6d4e4b230ae0c0999e9e7b1948a516fa5e9fbc36fca0b74e4124488d0d5c43e2732f9e993ddad4bdd8eb8d4a27285dac8d8c915a6da10a64deb12bf001c12d9d249ca4a98b10a5f925b3442c2dc4763902c839a01da6d98633f8fdc9a15476d4dd1a5942cbbebd461dfbe756d67cc3808206ead0171227a6f31d25d6a6970ab734e679793b3f03bab1006bd433fc6531808e5956f081485e2c436caa0a51226a0d13ec31b97aeb4acf00ff5f50141eaa8cfd8c02bb9255b709588940d691539b99dc139295ec37e5b14b23cdf17c8785a3029942304260727068ee29f83143ee4e323ea48ae5c0691f1e61a961bbca2e280404b879bbf0e9af985a3fdaa9ad77cabd3873733c2d0c60c1187cfbb9cf96be9cd3105d28c917da0484fcfe334221d279e7b25d2c10a3dbc5114742ee94729864cc40a606 +SHAKE-256: d188d7c137813ecd13ebf55158ec570498c73d47db79a9277223dcb1b9cd6a194105bc42043fab0298a305e5894fcee9064bdf0cc240ff8ea30dd1ca928c3ecb8353d859f8d7a777be1eec1240fc58334bbda98dd0a386fc23634658780b63d774b1fdb93a34be669c02b4b1df9ee56caa43affa77f5ed0876dcc7f8a7f88d6acae92cd06373f36e33afae7965364b5c4b77096b4d95bf02f9659832811485198056ec0c6770ecdf5be6738111489414e3508385548392890b24ab902093e2df5442e50b36186bf2fa7339a61818cd77fecd098d8b95407a5d0ef20da61374928b79fca15be0764cb3ad2d9634340b79a61773944aa811c0da50195c5dc7e4d5f5bdf7d0b4af9deb9a8dea16eb7238f93414139698225914e44334e5407ee1c5d7906999e6b9db11fa1ee3afa5455432a0e374ed4b97b1ca7422898bff78906f0562a925b6a800fbb962337d107e326b35aa78ef4eeb2619035628c11d4309f7d031c9ec46214b0def7b414cbdd1cc36783ae59c8490861d6d7717e814b2a05e947d2aefb045ae666b316428a028b0d4416b1db852ab8c6db04fcee5545d90fe0b794ddec1cfd1b1956df674fccc70166582a62d9d158ba0e2b8e3f9db6a857214fdb02ee7913fcd3d40864ade5798a4726c6a0b9f8c61f8256e8d99160e6c9ac034280c33418236add15d20dd880cd276579aea0b89e1c1f4f983b71d75fe03 + +Input: 6bad96dca5417396cb5c4ddfe0e00c030e426614156f168ffd76c1bd5f6dc538ac9a7e506e60a73adf4e714cd354ffd4a0a2cc1ad0ccc41f70769f585873897500c93278f17a0b3213ed6bd349bcd086adef33b862d06ed915fb9fa133c55cb163b6778b2eeab8aaea424e817a378b72b9cdd653467061bd73210ec193c16d1a5797fee0bed814039f0345775692e2c5648a519d5ed3a495735b9c734f2f897b54bb3bb76dff2f1a1631690367b5204224c0547704a521d1dc8ea60159ae932529d338a8f426c7f0aaba6e95fd714a9edf14b553db7eeecea3b8b5f6f922e87b6de89600fb93a5057fefcc8a0f5c5889b0d77ed8ca2580c346853b1709986c213f7b07f38f761696255eb078824e9acad96a512c256a5c4d51da603335e2b6f5d56b23d0f9248da480bff90ae12cd7464dc0dae24a922def +SHA3-256: 38c9e3f7b75b45c66ae876dd5b5a7671711c7fa9d701b46d2c652affa08dd290 +SHA3-512: 9c2b4c6599c2629b28e02d0b9a18367f87519bc52dd9ecb5d8f6b1b5febd2cf76076fe11199cb566979f8f57e0a27d0b6042b246f7280c98d23e30f27426d49b +SHAKE-128: 1498428a1c414799c34789378a04c56df8d3c84a388c2cc269de9e786344f00465161c9f1cbbb74b4fd4637b7ffad021ddde4d13ecdf61253b0c73add21c7422ab20ac566e60e57888d354acb5ad14b2e1128f22e117dc536d08c0befb739bec986af8d981dfe75675fbec6bad8fb74741fb9fe3dd6f3b618754e97cf7e976198c82ed473d878e676e8a674c148df163b8817ed1236114eee37c0bdfc8ab2e835b9cdb27afccb5716d08d6c189f5e43b96fbc8daf7bca181562ed2f7b0fd7d767d9d4542652a5858bc87ffa1e7e18b0df4283de82e9f5b3f4ea71ea2a293b2de824cdc22e3a71cb8f41e360dd7c49297ae9213521481a972c71a5e95c9ecd3e589f62ba3d2263065d739d3c983faffdb3769bf8f491fdb11a0251c1b03c155ebee5b7198081f801328baff3751d8663391784ce5ba53fffb8fb3de4109ec3d574e8c11d9cf7cfc50aecdebf4ad96ab486e52acc34ca900efe056db93cc75db4208e1a28098ad649a7db418f9a28e4956815f47c9aadcb98193fbe46e44f10153076b56e575134968d956a04ac2753f70bc0a805078be3c6fd1dc48a9c60f043ad9f86d12efa4677d1056e5394b69691b2eeb1f79148192fc48a059b7e38ac55dd5e88f16bb3c8f472ab597730bc6cc945d8d63046bbdc840bd2e718bf3b37f76ca41d0723767010bf64653aad718b473ffc625c2273161ae0a3dc7e808c180bc +SHAKE-256: 769f91c5c69eafe94fe1215cbe20013bb3cab93318bc99866f3b98ccf44fc23f41f9c8d5a924d002bfa169253ac39d4fe061d1b161a6661201a6c019285dd2b82a0dfcceede72b52c8344b6689d6752a4a605b926b6701c59b448b163c501066cfe32562dcdca5999ed7fea7ad967cf43c58c975aeb447ccade5c4330eed18779b76c192ea5aa43e3ce2e0dd6f1df23cb3b9c23cafcd7d21611c2ae34d64d5cd5813f33f862ca2a90189a1e472e3bbd6b0d6766df3e17163367b2246a63efe166605a9cf326b83b533ef875fc3b0efa8069e214e64f72d5253db7ad40f6135d29620bc8e5f348f4477bb5b8f4739844145a63b2faa801a5ff0c13e1816f180bfcd52e2015d30aaaa1623eef7c482fdaa0f2496a367b50e868b06c3dc0cd970faddf375b289f4f668f6727db2240c096f2128a1f3ad7d99158d4750f05e587674808869b90e43bccbab7ac5663f9bc9ae335298359f7bccb811d8f8cf8cecc45369420d94b4bf28b20bf190c9d77f6ce0e3c6359fcb064d8d96549c3d53ed4b535a4e9ff2e9b969af0462a9104e09652dd595d4a74f524648cb609d4f989af9f7dd252f39a76d0263b92a19b4f71d5c369b185ebce68af8dbe6edac4ec055845926503d738f551b6cfce644d029786cd3e1c1cb936d85c31ef2b7b9a95e1edadfbafc87e94ad8e63c5c878aec95fb9d7db6cda3d74f5a1d8a889fcc19ca2571eb + +Input: b99808da3159c373e4dad25aae5d599d088154c987b8d392d468d6ca73e307bf68e7345a29e53e4b698dfe77fd65534cae0385fa05018ba7550e1f9a6bdff905c5d2aa8810b663dd285ed46585e3f479c54512fe7eba0e48dd5a155e55f93a776846c451904a7b4945c78208e7ce8cbf5c7559fe8005cfaf71907ba7406b9ebb64946a31ab54d33e392a026891ab8fbac692d68cb7f9159504f38dde2082e7eee031c583f450815a44df1b1d503ef4f07cc3c050b7ba83f3f9fd45bc36ab517b7465dc1c9114b1a808d269c981e951cced579a92d9ae97d3f2dc5dbe86303495a33facbf9c41fc24796e4d4a647cf80424cbfc6f4f6ac721670ee0acdb24e89728042b2f73a07774d02ea45dc262330ef0d530f8cf6b1e485b0c6d2169b47df8467b162cd9f43bb54e073001d7d1e867fce7e8311da713b26c +SHA3-256: d2238ca83e972cc8d2469786c91d34264ab4f0d6c72b84a0f4ea3ab73782b6e7 +SHA3-512: cc0970ce14fe16d1f0a157d87b46a90d9230b07b76073ad55379827255916304a2e4e1152ea74a9c17dc86b4f4986bc7b4b4c9bf72b827a8fa49511bf6f733e8 +SHAKE-128: 648203c584c7f1e42e3c2a7fe05e2d64876166841db2dbd9d3c3b6f219ba7a8dd796d56b6694a5f292568f473be42b5cbcbcdd38f62dd27821689cf1b02673ff1750f5101afbe8b6593b00f4bd38e703dcb7a5ff3d1294b25405caa33442f087912e63fea44ede5e86dc09003ac81eeaad1f8d29f64d18ed2942b550c189538946dbb0b01224b03ce23c2e03c12c9317858c7871eeb3a32ea3cdb08f1c8f4e365eb0843ee1204a7f99db3538daa7701e2806c1e606bada0ee51c847f7ec9995fed45fad4628f23c50f040378c50434f31abea134e391154af09e55d3c7bcfb9c97404e7a5cc7f647245951e405add7f52578ecf449e8d183535cde35f9ecbc8710f2168721d5570e583345fc9a71559775d9848172a1560a8f7695f2e98ac2814866936cecad49a6a7a5062d645b58b6e2c98d280f0f402241746ebb9e8098f853ae09a14d687c18282aa2000a6c9930b6e1aec29ceee5f6d0d4b067ca4162c6713f428904dbcaa869509aa561d98b9ef764deaa6de897c148abb71cd5d2175c9581188dfc558e0e09e6ade67fd2e64a30fb843016e9c0942bacafc0d096fc2a4ba9f26ebae6e4954af3cb2b0eb119fc762ce14b0204b7ef68af0ad30eed8ac8a3cebb208a62b4433fa3ac0ccedea417f996f084cdd200641e17ace4fc607c0b47212af5f65d621d9ea0c4d3dcfe02e999b41110e5eb7477d47d7254c57dc515 +SHAKE-256: 35d24f9a1aefdd3db9561472319a324e96c39c046fd5ec6c0c0f9ce5697e31d00a880d479f225d348af1926c9517bd913690e715e151566fa84fe2d4029a27f344a9723503e18030b81680c7031dd974bf5f6b8394dee6e7340a231a775e08e123bb5d127638502bdb19d5e095e340af3c553bbf327f5fcb87cc5791a3a2aba1f10b6568e9dc1e7b9b15486d6023d081710c59cefe16af1795c1dce0784a3e361fad18bae98f106b235538bf472f47ee3fab87aad20f85f92966035f6f2181247bb06601ba078fb5fe60f14e8754005e92b5c7c3eebfe695d6f5bb09f43893be07cb7f2be74b2be8790887ced636a913fa6efb0b0e3cd27eea2acfc43cf04a252568c738944031af4688831bf22a0c7511261ea9a64db6c42f39ee772f8dd3f706b3ab66b815a44f184a8b01916762ee67337aec72757f55731089d9c85e266aa2aa4c9272cc8eb6de93beb18bc7c6904393da52251afa012d40ef0abea0307645267b22b4c888777ed7b8073044db1e16d63774d9ff0dcfba968ccc6ed03c775f0463ff7747fda63bb7ecaa05f581bbeedfa1db2fa5b4317726eada34a1c3cacf5266e12f7d27885128bba02d8871fe4926e79ef9139ace761075cc48497264ee5a7c510fc77e722062a5dc76758d60c4d84a8dccc72f333d18f4d0e78285ef25ef4ff5560b70b7f0cf623a518ec46f6e276b29eadec55eba269dec2c71a64e + +Input: 8fe8cf22930d048ee93c3c585d7654b67e0eb0458a2d0674d2a2408761afef3f07660ce28154b90df842d1244fe556735a4a9064976d7f40d4b57a04d55771693f358cb34baae75e54069829eb7befde872baa217e927693babb741002c9e7684bf878bd00672caad92e7dd9a45bfb49f53b661903a4ca3050798c3373cfb4facd94b1602099d1e4cb9f9c653d25f5c8b569f75b85584ba30b63b73e9b1a6f886c68ba696a181a5092eb64c1af3f3e6aa0c31d23588c6c403e424dbca91bfab2e76ed1dc794a175ede57a5be96fb71772a3a74400c49abc6e12066f9a6830b31f145ce19b19102db50c61614384856069e31cd8ce6812967d0ecaad4a99d5b6bf6a6fe3e3b8def473a1f19faf8e028774f449123aad86244c5305426365d15743fb85a83f628716ec022c30e335aefd3f2ad37d516bead903628 +SHA3-256: b13ceba57c11e33f271df456d85cfcd5f0f226c056072e81dc1fca5d4bac6dde +SHA3-512: 0b8504ae37902477e7fdc3d86fef18b985377e3bc90f67f785a1689376dbb963cd4c374b5f57cb4591f7cf49de340c3c3de406be4b36c02513bacd0ac46ac476 +SHAKE-128: c403e558fe846e2ea705f57763e935930e3e7eab279bb47e5f94ea07220c3f3d7606fa6a385fe01056092e1d1fa277141c12e4034be01cd59fe651d9e4bba201217452b723879e33e6b9f63a15326de8c1fb895c5dcaff0500a34319cf151d30d4f085f71e0f7c38bbb86a0e528c4438403461a3da44762268ec1502bc7227825148c4ed5d50158de1dbbdca72c74fef8788ed88ba2bbbc40385ebd29638aef0bb22b61b84caa98068c640d8d1c43842717fb15b9343c051c52a89a37b53f640e058cb3fb6007caf634e987e1ebfcdcd1a483e9629e60d9e8f5882e6328fd2cd5f55b645b3c8f5b4a9c429dd1338ce036faafcef4e1ae32d7c5cacb139fcba5db298e4674b141bd31b76d58864f224c4d2b311dafe3709fd961fbbbf0454da10f1aaa3fd5063c9bfda15d372f1697f8609f9aee77c84de485c363b8099cd2e73f328c8737b2cfff5fddb30cf80d359dbbfcb798b88196edaf5cfd1c6d704b15ee9a53cb1381d96b881f8c722b0b1d5839fc3317f3a3f894ff2f1c95f774af8b82bc4c67114de2591535ebb079c7cbb1cd6223de355439d4e93e3f500a2496161b44f7e44ef021faebcd07ff1f22d7688deb1bdac9f01174f1c9c01a2711d67f6eb73c6327ac9468ab7575b2daa25ac1b448c79164080aa672e53fc2ac3367ce645ffdd9e98c881d7855ea89c1bd87dd7d6b5b731b0723af247720c376f2befd7 +SHAKE-256: 87e86f6cf7d58db4602ad24aba1bd9b1f94f4ea55a0df8d610c01174b1b50d1d6996123abda5334f76a7fd491330f42b9c46a693ef87bfe187bb299c1e3026d7cb26e2ba74a46cb17448b415113eb5dccfb46c1c77c5bd4f102be5a5a8f41c696a35ae6fcfcdec6d98a5af77e7aef93218dd9638159f4d4dc6a5f24d42206d6da6db02c1bf6d38eb7a3ffc5169982bbd586a7591c1891e615166fa6c4c42c32da04ab584891afa389e0b720416362304532d15efc7a13770a329be9faef33e6f67ec03b73dc1fa09e501145497e7978d44bdf2f16f625458afa3c51fd1b46e6c0fb997e57e29777b9ad1f55a5ffdb3d5c95c2f7420f888f7189cf85ae3c6246372777d8dd74075d2beec37354421e535aa7178ff5137c16f12aa1bb6393fdbf2abfe5a2976c0dcaf8a98a5ac3577170f022eeba9db26da608076998517eeb5265db21518b9096d457f94046b383e1cf6ca63104ea6cebd26c8fbdbd8ed864d8940cd21fcd78fbbbc1bae5bc183a65836a86d914cea3d6dda09765fc7d8c222207415223959774e391bd29423c0e869a20f954f22cdcb321d4a1a0253ee89f572b65c347a7215645fae6c8ccfd011fc46e1b7d8ce5e1a4b280974ef968da2224f3934fe6ae335e547b78d8ad7a841c7e7986abc577f0d71354ec67ad4ad6383efa13e4b74b38f4a92f5b94e561166260c8b407a727395884d66fe2af1006451f1 + +Input: 9df00118a5c3c9455f6546453c37ddf03ed59d02e5f4cf124f4d80b1f8a9d4dbe1c4fbc277f6d7e4a3e69980773daeac66fbd37fc7795583758e8088018abd191010b6e0ba027318f556585bc13310cfc35bd63517c892f107f1dc669f636cf392ed8cb84f78a46a9888417b71b25c2786afb5be30b959cdb5f7956bf11d6f43b6374f83a29015b0dbcee939e77d5ecf046fce2acd74c89ec52d8853ae6154fd108e3add8668fa61388979a610ef23dd8802c08cb6e259aa9da6a581abe6f4e4f3d4084e81b34db9eff85ebd089c44de87521c3c5f642d5196873b8e7f2bd835dc8b38c8cf9245898723864fe6ebf8bb1b06446bb45bec6053403ceaf198c76e425e3b5cee74d80073eda8dd809af637f4d5810eb50a82eeb4fdd8b7f98ceca10bc991331e47d15d2bb594c60b696da2aca2399b7718284fb2a91a +SHA3-256: 4b9e404695956c371e0c13addaa068de61adc35d265789575d9cbf64a99dd3d3 +SHA3-512: 7cfb3a25018d3028239c0e0908d34b117703fac0160725f924d2a7d749b9a7bfd2671b712c91fd5e2a5ad022b9aa0521c8bc9968c58da335de921e5b7e76e21f +SHAKE-128: eb8815d17ca5c61af9d168774e4ca07ecdb384ab11754a4dca861a0049bb786e77bef74796a5ff13b7e9792561e1966b8c9922553c8cb98f761ec14fe672e2bd1e3baf00d9a92b8fd24deab10b59ab48882d64beb6f0529f2628a8fb06a7aa62a7b0e992d1723bf022ec74b32eb5a89bf34faa5cf2be217e522b7da4df4962346fc22558267c59f0e618f5af05e807cc5b5c29aaa7e6a7898b4eb86b57c38bb4bf05e4238e4b2675eadc2eceab6cb04af3086d715d361f69f09c38b538f787b30b1def66295e552cf4a289fa2c762f68e5445baf8b794f11a9074d8da62a32d0f385bcf3f4f18cd405f5e202fccaa1ea33f406b2662629c3808dfec990a35a5562d249046e8ba6904852c4eb893f1ca7512d227c703e8eb44df872955db3f0a0e3662703b3544a1c91ea276d5c90f283eb1b9c32b9afd75b19671a152828dc8c196bd95753dd61fe69ea21be445abae03d3fcb1ed01853985994240540e4ea092b67472f0c16ef0242610bcce937a43a7311c1eb66750da616b6ebe7ab0785407f7b566d144f539c175f4beb51ce819301586fb0b01edc4fca83a7c96dd1b94eb2fa122fc987c613606c1ea22bcd62758e41a22346021b1648838110d6101cc4d16b85314c667ec7debaa03f8e12e33a3710b1d9772f83efbffc5ec7b3047c43f9bc8e912bf282e07e879c83c355f3a2c6f1301add4211ecdfd4c5517084da87 +SHAKE-256: a84296c85f7aea4c1db0130a2699f4b68c15179becfecd669bf86bec711897b00e3e65911f5d1586b3f976023eb30c9f57fdb1284b3a1a52923ec9dc162e2c9cbb2ab7d111d6512d0b0629d30989ae9c4d94a0c5aab33e73f6d83badbd1de26891961e76069e00d8b7dc8a4908d9e310dac62a4e01f81f858eab667f91426f0e906acaa515a4ba9fc24af2fec6a686e75df935cc21a479ba051c7d25924a2f2e40100ce3b0029f586dcc659364d095ac06cb7cd7ca18c350c57258cd2ad640cb5576bb070ce47e65005c59790d308b4b9281f6d6a1e1d13dca5da6ad45751e1436aeca834162f66e06f0741704853ce7fe39b6cbdbcb1bf67719ec84e1b0f91ab6b6db2a040a95161d407b8e30508abed7fa534def132bb0851a70cce493d53cc8b0aaf650f995c28021e17d2a5afe4549a8039e1a74092251d946e76d51eae5071eb5213bf418031af6abebe988de6a40b878a205f3ae7a33f950c13fe5fc5cdca1437d4b11872ef54aca2f1f06e53a7cb139aeaa831e73b4d13b4dc993af013aa096e7086b73d41998eb7db0634339da06c445b7e7244e752f485d2df7cf702eb4a8de7482e90824126312ba2ffd27ffa31035aa65e9be6f08b0fd0fccadcdc88f0142b6b2e57dd5662b94966e100796a0a0001ebe8899c264c718f9644633189ff9b146f0acaec225bffb9a283c92a5b8f9cae684e20facfd1774ce70f90b + +Input: 9b44c937570b27e211f2c80c079ce567edad47178e17bca5f086288f6e7d152fad509b733e758fc4e00227ddaf94a35034f48210cec809ba5d1762ef3d38a6a7098402b41d6dccbea3d8e564d9864ff20fdbe86fb653adb21c25256f5b073fb1515355bb28244ce2e9c9e2965032cd02d3303108de4a3af987624c0aad8150e71a32c437b34e639f117dd64000aea7fd2f726bbf36dd6b67399c85b476a0245b89f51c0983e4a16b739e4470b012c9fc675b8c18701a6fa0895860171d34e17cda32fe3018d76f0305de5e867440a666b51a5a3381ba4720579dc336784c22206b1997fb9d66c4f4bd5fcd25f265c0ba2130c2e080c54761c10053ffcf9e3d708a838f904282ffd5acb2eb18c9285c1d449d705154974c61eb35c88b43819aa6a31e85161b848a204f3ebdc0072a492e43c31e1f37c22152df95411a +SHA3-256: c01856797c37129f6c58f5ef88157deb317443f76d25bdc414ca22ee4e60a873 +SHA3-512: ac34622e1629fdf2bc56a1dfdf7d5080d7c658b16570d3b18c401c5e3a6e9c12716bf29341f514a38d330f23f54d8e5aa1ce9a81500a7d6834ee8aa4159d0a38 +SHAKE-128: fb92345a618193607c846f6e63e1333f90ce9312cf4f8024b6433b309d59ac0e5497a1f146c4b2c962ac1b70d92e383608be07b0385e4da1393b1d927ad40590388920b02669a6c7435b3955a2ebb9d37ce60f2bcca0a1c4089d88310bfad7cae96cc712295ca03ed2238882961a9a0a567cb06847b480c830dad807bd61e2051c79e834dc24acc189e343975ac64ca34f40029e3f407e2187d28365e6e974e314a3c988270d2cb8073e44d724f46beabac9012e957630050bdea1c532009601cc0d8b0c6e3ac47e2a9423dfac95df5079d025b56c823a4b3579566f2e7d1911ffde7288109f20a2589019ade05251939d5c909b6334441b793c081725f303a7687734e61d9aab3d8db5148ce260d9a9baad1525c477b41ae89c4d33b54af9f6c6e0a06813b930fdeb8051cd99a0b05e9910dea0633e9f80577f47edfc0bb577d439176d9d60b69df0ac05d7b09b68c3fb54008f199c34d3fb666bbc2d06c56bd7aaa168faeba4c29213cda25fc1a2b4e38a621e22d913ae997b8157148b42f6058f2cf29f3852081fe1088099d32d7ca31a09702f6779b55aede41512761786f200cf0b1f1ad23d74a0f09f60d2bfdedc3ef853cdf01c06b877fef6780f72804591830a8dfa52d692386096ad6f3775f254f2eac22ee4fce509a48252402a6bf438e6afe244c9c92b03b84e6e089639be0606419953a72de096afdfd29b61a3 +SHAKE-256: bb362533402466933a4075dc8f574f357c2e25d02c1b742b575c0b9c593ae3b735d2c2796c905aae60839bcdc2cd1d5a3c22e6bbbdcb4419d62220d05870fd34de5ec3a9d45d4891a3820f313a3f19122bf088555cf13b8de8d0a8c4c689ca98b7d521265101fc119d4ff9f305026c1ef3d90f3b1028cfe3d6c92a628bfb25e7e93dd79a91d8e200c6ebcd7188904316a683e09d7aa1945fcf3d523c7ec0d09265e3dde034f2c7504cccc59159bc59528a3d9feff631043c211d165f1f9dc874df2ecdca72a3c3b087be283a9d942fb3611cf7e3f6d5fe049a1710c177f8e5234515047d01c851c11283efb04a11fb3de3b4ecb2318c4c8d8c91d991fd8c96d0240331572d9fe4d375b01c07f60f6305a2d45a3d9851843fe887c3233f6a3ca200ca9e24d1e39da736591dbf04a363c383e73400fd12cc1a8150656eb1031cc3e8d4d5f0506427ed7df188c1caa2a7c13343cdc9e3713c1ce537e049169a0c1b821b512ad1b6df2484c73f4f896310c7f70210e4c3ee816fee0daddd53182a5c64fe745f9a485cf9403b39aab5fd754f5e66301793dff664b1cf2cc725e3b58bcf783650c2f44f7c4566bed60cc62e1305a836c7214dd18bf07ef7448fd4d09e9ccaa93d89ffade4a7ea68828f0dd2c53162b04b9d1ce74c183a41fab1599087d5fdcb5f9f6a92de75e6de5787025fac1730474780a756b6ca4105f5888ba730 + +Input: 45e27c743224de404140198a911595b73014ace8ebd92ecd8d3f6194593f969d6f97e5014f3a1eb378390382ec7ada25e26267ba8c3025e45e2f5d8ef663024a8f4aff3d467a013d3fa04f4cbf7f3e68fe0acf590215c15e12d0332e825a0bdadc934e743f8ea86e10c0892de1f4a3970c73086ac1de92dd122ccdf80d3577ba08cd685c3737bf68a2ee7b72e536762de46e6e424d099c8a4012994a66766e539d7eb715ac5400571c6c097be4ad138313d003487c96d6504ba34e0739669d6a1b7ffddbc34d20acadea939ba0adf634ba78b4ef128271f0f6034ecf341341bce8a8dfc43a1e42b0a02cac126f3bcc900526c901865a5016cc7f79bf901a9ebdd5a08ea91efb982430ea9566204cba48673d6f1280ca9a0107204737e50f864b48fa32d50bd6a346e325131bcf92e8f8f6c9704cdae3a87895a696ea1c +SHA3-256: b50801337648e2da983d3a3457a659d64f2522accf5291e0f58f4e59794f5a4a +SHA3-512: 61d93d672e12215fd3ca1bae1793867402de110d04e5ad39067cc65386f974dad09dc022976cd2a78fd7fad65b32cb10c6334406279a87cfc355b9101cf66158 +SHAKE-128: b851f014c1d9012151b4dab6e0a8ed83ccde0d88242132b1ea7a88f0f4f5a5d120ade9cc420a9e604a6d69e8155fd534e4bc1514aa2663daa026605a67cff8fcc6c4a41c91e834c4545a0c5bbccba5219c8174fb088945f2c1537f7830764c25a64169a4495503018a64bbae725b077e3fb74e8f6c07e946d86f90b6293ea790e72f3cca991929f68456a5e9211d2e8408d3565d4663201223bdbe5e6191e907aac86272dfa9eb92a0ca78799312fbafc0d85e136111de478ca66d1d17c6c52eee0acd83b5a311aee9996ddf4d44c7b54b455a9d181e8799889970ac9c09204856399f53bdbf1865ae301fc8b0e4956b5e18ac6b5ca66379cb8c5298c1e32715eac89354786be3d90269b1ac38e7b3fed7cd230edb20c4ed7b44a8dd0221ce9afe1e510ec82541d333d82e66192dae242af4f8a0c026d7a606532c6d0dc650a4ea51059ffbc2920cdbe69e8133457b0e3d743d3dd877167f12dc7159b40f64fa1ac706003aafb1e827aeaa0ede298c6e834dc28df11fc3f4f3bcffc7ba9c2c273e54952ebfffd51fb3c0b138695f1342f49ee03d4b01e4d244f38fe6fa0201af319994269e96d8dd3626a575185ea0e5cf6bb59caf82cb7b19a5c21aaddceca056842f348b59fe541a1e2526690c80ec00d4e6d7a15db50900d3b394aafc37a13550e7efd1a3039ce4a01b2f7d2604f6cce262672f0e7fbc25f2cee7d1d4b115 +SHAKE-256: c34e5e3e61907050bc12e4b57a944a8bcd33fa09f498a056df5e01bf8f4c155e4d78f0bbbce005ad783843ceb570791594ab3d41472f0a265b4a2c31bc7e06111cf40a8c89aa539de6f08b48a98fa237c1ca09f673f27ce8c5d479afd12bf504a6963c13b9fb11129bbe01e88c6d395acad53e604aba28d54a219f777fdaa2fa901b50c29e0ce1edf907b61c81cd6fabd13831ed1894b9a0da1ccad21d3926144cb4e4b174c13b2f32a9b36ce725af711b6339aca3b0e2bd4cd306de85c96b1c72dc134c9afb59b7163405b4e0a09926eb509d2f0cc45cf5154cd8fabaf810807b1c844d543e663e94a62156285fd0a441eb5ca0e2008cf65ed7aeb872e3eb0ef49d7778a631020e0d63db2a8512f5da4da5e22566dada1068bdde628b7229669a5df039eccfe4d9cd871d4fbf29dc64291fc9dcc558f5ccba9e3ca9808f3b0c00e96863963d46cfecd4dbbc1ffe222842662939e311b07a787b77b7742046a1156d88df45c78fe65f9701a384cf54c37c434029b2c948aa45858bb9c7b40158de7ecc3918957c5d51007ed338ed24ca5c00b75d4f8e893a917c70fb0e5077d92bbb9a7a6901a7bbf4d6190d25a66f100fe23423f9bfeb4d0df2da83853687209055f11e125df5f78a3d6d3824ad68dcbf697a3912fe4cbea82ce766bbb4eab99aaf7c975ae976b4175f90e9f9ff855426ea8fc75d1a773b5160c4d4a7c47a88 + +Input: a46f56604a8f25aa1c4e76d261307831e5dcdc8adcf2a1e782012c5e9edc375d086e09e7c1f3a9fc204e59da6ab9808f647421987397993a5d6e27eace5b7c88136c528086b7d182eed370fd3a654434726d33a799f93f064e8ae930ad649a892027182782e11b3da4ac3d07e3f4967251039690e520cb0086aca6b3fe500a42bf4b38a199307b9d0ae6f1a95462072e1c8387036d676faab028296857b864e2c614df8551627ef24740760f84c8d47f345a8320675638f646fd21853dd9b2ca3693cd3b4138ff225b4571616cddb7a84df38d6e6438611523a9d4a4f4f68a0a71295b37ce117652395b4d390b0ef820994f1435aa776f840032b0fdb9b97f2b5cc8f4e4178da166937e97116888915ab9d433d3009d3b8259fa6657861244b32090f3de3d0b9d93c8607733e8487524b867b5e581895d971b879441f371 +SHA3-256: 55701b60ad86cba2ed462aa098b49ad5d3ecf76f993c549c7d282ccf2592e988 +SHA3-512: 14e5469f2f6a883d903b8f242f0e1e945d66f687f8f464cb4828a2a8354e3ce568ae2a5f508d9301b2b408d9c87c923d284b25b7e85eef57214debaef7b84302 +SHAKE-128: 5df425eb8d79d46049c78cad4273502a2c5068eb7e23e86d43fe4ed061f8e2a99533d7c61c20c053f127dd9d477281eba860ba978ee336045d66a5a30e00308ae0b2076057ef8c716d3623e1ac44d41fb65686511e13f2622e13ab911f84f5c0201518ad131f0bcffcacb86fd5a9601119e88f30fa87ad7faf705932aa46944e358922133b27b3634caec10d0b90a64b676d733aa99424c9cb78cc2322efe0fd7c3ac0ed5937f6d54b864fd36291000c9801ea76d63518f1d6ccb32e550df74c88972b4e2c1e1b23c6937fbbd7b3b997800dcaebc039709127960e39dddc6a438f6cc561277b940296a8caad85ee23c379459940b1e1ae952939df6c4b7fee4db3567c4f5f76a1e43883965a63e5b01aa13e7fc192b139fa7c5d20ae0e0304670de5c5fee472124e3ddc17987bfb20a5975253080b1d9ebd54cce2be7b446c6beb934185bf425fbe6c9ccb0cea49b05181353e2231fb18e632311de280d49d93f9c3400b47edbb5de69c546962c3da64d19e70bd0b41f5259324af8597d3ef5fcaf8a3f9c287d375d954261e24ecdcf0364dc40d3b8508468875b8024a329b2fcf0041f7ad382b6ae30718ddb866d28f21990411bf40d89fc362862e90e5d3b9cba1f84eb45b1a172b826b32e901e1778fcf6f094aa89fd982950a6bc5be11f50392dd9d497f49904b20dcecc44d9d709f8f49ffbc90be1647356ce10e3f07f7 +SHAKE-256: c686aa69a931481c9b937887e6f47e2813726598eea8ce77c60b9bc6d5fcabb44331bd9a1711ffd7ff2f1b268d81ee2e0f680deccaf350d538ba493adae683bbfe2642aaf98bf90235f22f18d1a34761a42b00f998e2e7927507d74169e8ae09427c4c26fab84287e36bfc0ec4ea86450e7f5bf57ab34765a5bbe69215ca7e19c738e9d61756ff6201be7674ac9750d750ef84569d7d7fde5afc45deece687e87a5d24095d3659f247552735e6f42ca56d27425800f175e8bff14ec2ad28cdaaeb317a5fe0bd55161aaaabd333a2c84d98b56cfe865b0a1a8815c7c2e8abdd749215a52cb51b9e9ef6af8bcdeda440383cbee1f622031cc2ddd5a32657017b5347a1a2aa53331686c8080608dce2d0fbf60b94bd4dcb4e919a02d1b05c48eea4aa161d632417f32e50105dbe45d3ac686fcec29bbc75c527ca4cbf3aae250a82c160b3ff74cce836a4015ab6b175ed7c6fae887725b2dbb73902bcb7407218caa942a7baf1a01f6f414650c804d896a5b7bab178b1e454d261e4663525aefcd8be574a19da1b1d7dd2ef832363d78ee06b69bace7716d6c042061fe91cfb0170e07471eb51cd421f410981fd3ea3b795c6b6068787dd7b97885656f997268ab34356c8e5c67e0c47482d3020227892b1a0f8b6d59f545a64980b9dd3e318dcdfd2030bf154947ea90c1ce1f3f3fa61cc4aec8bc3c94dfb16d2c65040d370a2b3 + +Input: e6429ca3e0b6e7408032053d69ad8cf3f084e22a54d09b80bb24861f299d54af930f5dfc0d5e3d63ee4c97213f04ddb26d9f08da682ae7670c01052eaec1a172dc2a25672398e45f108c17af12f6dbd86259b5c28ef885563cb3d4351863e0e039da8ffe88d45c376e37c0624806409a2b7da8328466ee15dab370b37f1eac7dc738a529eb44ffa2d9cd87289aaf4d46e8fd70d6ebbaeb288f1b89dede246285d96895dbb7e1885f1c98303f0a59feae0355229537a14b756401913d7480b258e6f72693bdd1f987de5cdfaa5257f1bc85881c211064f0ef4db176d4b2a9c57e65a4fdb15b5958000b2c46fbaca61b863b20cba2e1c51ec729c026157b74f2d75c782d5bee2ebc01994c29178e3c0377c1988b2a371cb8c8cbc49ab8fbf2f0fdc08554bd26383330a84ba717b6db41d67f7ae9266b279d981ce3b434a1262d +SHA3-256: f3dbc7fd4f3292f03c0ef3eb2a2c3b089b10f4511664cc1703927ea83a8d6e9a +SHA3-512: 065a113523c73fa3be0fb7f167eb1c1ec4565f9175615acf75802c1d276b15611f09bfa4db26b4d542905a67bb339ed6dd8f7a8337d771faa55e8bf277c8e29c +SHAKE-128: 0bc2513c5ba5c3318542bffe844e4d3acf7520ba768f84e7fd7083e582d8bfd6be59f5e27d2813823fbb0cf1ba494e259ac0ea051992f1f8c1ec9d536edbb2583c9954f8d8d50e35ba5bc2fbaf146e1a529190d862b491af62d450ff1443a750fefe978b635dcc6ef6d42db2cb000b0d27301019cbe9d19cf85ee5e59e4331e6260447019ddc7d4529c14ddca33830a413b9466fc8655a55f0f8d0ec12d23242b4cb2dac872f4f211ad0468c49a719217a5071f5f44ad43047d17dca115acd35feb95b392c167f21060cd0b652f2641b772d4f9aaadd95a4501826124d69c1105ec05bbfed861b7a8caba9fc4552a9571ee8a4e636688715a14ff482cb02eb188ed9bb2bcd57c9f51d58538533359ee6b1ba93b8bd6ff7dffe6b3d9973217c4d0a15448c9e06bb1df5005d0fc710e4963f13003187f187225a3dfc75ed28735ebccff5a920fdf3a0b460b59ac3031c0488bfbc5289eb932ee173342d359a1821c410289352ba8b557c71cd3ec25c721f048a74c2ca07c5e7e9222435951a5f423b86053736a2674acde90cc2fd889ffb01a9ed4de731a87a9120d85d508df4e77d51973dafac5154f95b446598ef976f3695af9d147a0a54de5f44f9cf9c7befcbb9052f72c828a16c068f0454a4a51f3ec2c3bc44a32f858f1df49da48df0980a0e8a13a0ec60c6f626865c19cb4028601582b810df0e228710f8844e961c66 +SHAKE-256: 4df8d47b8b214f229791290bca0d195029394cf6257233a4839493d48d961da20cab8a3db88d626dfb857a22133cbd0b413459401d2009e84912cd333690d495cb0565b83c95d691c3505682cd53879a2de7b95e24713516ce0bb8c57af11bd2a857d9f5dd069269aa2b6f0f4f40d339977ac9dfcece2a9d9f919fd4253346671bd8972854e54051347a4d448b1b842fb0b55df5913e3c4030718481dbc616727621a8ccaa91330de43aa43962f2bcc5e82bc5b41df7576fb82bcf350ccb21d15866a653ef2b14f5024721e22d75aa8546d72478cc3dfc0865e0af1330347b6e2bc345bbcd12f4e888cc0d5ec65290d1202d8baf41a32f4b1ce03e160714c26f65756f27775a855d65ce2fac045d897ce43a9ab303a70ce2044db79b7501fe82348c5f011d5ae621c979a13f39bec59644f6d0bea7b731304ea5f36ec60094414168bbfbdd3aeb181e378bb70e1000458003eee64ccbc8b6c4c3ebb4e930c23e0da6c9d12ca27058cfb5f0942616f1ae9d3104c4269cdfe7833622109e75a3e14ddf5d027c01f7ea591285ece202503815b39b36041a8fba78c7162e3a10be251e399fb3b9be564a7068852c68a6498b6f2c1af0ffbde6f2f3cf158b71522c470f999f4453b4249e41627dfd5e21235ac9b0a5c393cd420699b5911b9fde689941250fcf32eb31e7bcc9dc174f137752a65ecc68b154d95978d440b4cb1ac04b + +Input: af4a227cfd0c3cc80b62f1c597708f0c32e33230e4cd60dd0474167627b7af7411a5c0e7ceff72208841f8b40016ba3fe927d49b481895a1ec7337adf256424e4156901fad0915b07b17d7168c79688b5178ad4554dc8c880b75c8142108b5d0822751f539ed18477087d1a2e39b723b89c8a457e527c71f148a17c8a8ac98b7e73388b0149a6f354f5ab7f11aa8371d0d64b1f275aecde5d593e5cfcbad41441f2b613123155c06c19414288b4c84fbed747675dd0c2da40c5f2d8db159802fa40a3d51bfcfdc0a18e59e7b6fdf5faf6c02b55df9310a150b7c6ca75258c47f3dcb636b0fae3470b2b21cb4fab96b990b23b2e4e92d967bddeff3235930b0420ddef93aa52e444496ba7ed267a92fd70bf33f2435cfcf39786f495078266be2cc310c37b0abc1ffed3fece6b0b3134a2c8e166b74d0d65c16b09a15721d7502 +SHA3-256: 95989a5d9831d69cd1f9acadf9f0d15de6e3f7d51ac230a82e5c90dece7a0e91 +SHA3-512: feefc975f20a6798be6e184223babde6eacf98c770a1e6ad7e8fda13f757676a4e5a57f56197887d596f539e48000f1af180239bed9a921973b65fdbb1fbd2c1 +SHAKE-128: 2b64d5f5663be93dc8dabdc3f4c989cd09c4d56d10435befb2a1f0f2c566b78624e58d493536f49c8ac638d88cee70de16ad1e5b1e0f0250d7c6855ec017aefc238b15220efde08c37a9cc3d7b8e2ec09f1d701c10766ed19abd31049533a5156cf0d185d71ccf75008de5b90db1152f97cfc4951989cdced5bd2fc0c3eeeca194605d26183d42909475530931235ce770992e67ad0111898df271e3ecf4c4c332b8de3a28aafb3afe55c8e2b9ae8860f1b93ce53e713a55ca6fb6c1a80329626a5a915f1894d03195018fba3e157b23a2195edffdc8065d83753b9c52d1d60508ec42b46337a0e6a8f2627bd154b469fd12c785d8deeef7d2777043245bde18ab32da568be9022c5565e8e004d28a38e224380e6375000d0cb7cebe710516dc866469a0c1262954dd46542390e2fa8d53eaf95d0be60d23f484822bb16e8dcdada4fa242d2282218f311e3b74ce8d461b9477271b704c69e8868078923df97c7f17ac3d9b42ab17e254b3c8eb82f9f9ce87e1edcec58af9ee16f0ef2c704b8fdda09266014f5df11beed3dfe02891f89818b443ec1f7894863bb9ea8da94de0f9c09ce79871a3e0fd55334e9833d8a6308a6a79921c2dc7df21d2b0408e1d36d303fb289cab52b686dc2622e72746be6557368690d670ceea842ffb37d34e62cfb8ad1ead7c47e362137a95dcce178fc270c66fcbe5abbcd2d61dc02fe4ca95 +SHAKE-256: 6f315854e87c5d2c10511da5c4404c6b8881b0c84fcaf2e81ce901ed39ac2ead17b1c60d662f9c9ed309338bbd72aa9ad6b558bcd63d252e0d190fc46a5e342f8beb36d16dfc95a40ec18352060653001af4030f60f33c1bf9071b61238a27a5f031e8e4ae51250289535ee3f52e14043a3c0826f4af377762c3d10eec4ce608be1288f8bc633f1911f3cce3cc1655b68a56eb58cd6f2d171c928404e67ff1b76c3b312002360469606ebd2acfe9602b22f2e3364e901f7575052da8ca75d69ec0bd492265c1c750051f3b9264df6254bfb4fa2545e48736c7a765060837a68cadb1f6dc2932b3814d4537587cec0f99740a88abb90456d405a425b735c9b02a4e7acb8f847c07a6fd649ca392b6f88eaa69a766feacb72bb0eb33a24009dc204c15f0241c22710d2e57b601e7273ebb943eb9268819f4d24b910121c2b8c8b77d5cf60bfe322552a874f3fde02b217fbace61d0959d7b426438c2bb5241b13c8abb18961156c40f90d7cf4c0f9b54d4d3e64722ed70f4bf47c2a6b8f0e2badd0cb4d59a0c75e969d9d33eec7044a6d1ae59319842e11e4cb190042ac09a9b7b2b022a66c651d7ee7f06a66974894a9d726fa6532880bfda63d270acf744187a2e58a634b2bfdb1fa9d5fe5b057bfa27dc7c1cfb7570235e5871fcfa01ff1389b5e1ad9aeba2be0d6a047e4b2e8019553dc0449ca166eaf9891d18b4f17616f9 + +Input: a018d8ec56744e59e336fecabd7627f3ce395dec1fca04c22584987fdbf96201a12e2842491946bcb35254d9b5fe378e84cf921d869433b5da45c0fb5c9d0b1bfa42bf287ecfde5c605232efd3d2bc57205f4d02030ea815fd27d1a8b4c38f144b1eb94933240b937b9b603342a25a51de3c438c90e46625ea91867934117bac436820dfa7ae1ad39715a9069418590d2281984eb4a9be6d4bc5f178dee734b784156d500c42e960966b75e302fec66c135f4b672fed463236f3e4df40c4da84cc8ee888a301e5156f297ff3da05173b203ffe3c32e8340fa26f4c4dcebe02e17f9ce4fa07431333d85d5b991efb1284add5b4bfcd523f8342525c669bd872a77ecf2c80e9c472f49639183d6698e6612da9cb52d8b14fe16369a79fe91a06d735247c356b7fe46bc4fe3b6c135ca5059f4476b1d016850ef1254f37f5f761ac40 +SHA3-256: 0e183959177dfcb9903a42f8d20ed0d777df75cebb7feac72b8c57783b9a794f +SHA3-512: 11dbc2c3ae9a959d1fadf9ef3f71834b8575332ab9647a899ed734413de795e575cf0d608b2f38b4b67b8b417865ada1b86e9bcf241c2394c0cb8bba974125ad +SHAKE-128: 37916bdcc9072faacfc245e5279fa702341f26336d15c1521545aff459e5ba06556c3b03bb0e3a11e7d777a71b95bb68d95b05e74a40e072d0b40be79688e9eedbcca3bc8a304dc16aaaa4d20bac5c39194b7ca6c0502dca7185b47aa6d7533269fff14b49c4e7d4190a1e0d6de3e7d7ffee5c6afdf7c7437536e5d0654064ca3ec22ad1ffceb02a366dfdbf3931cf7da6ee98992d228f3bcde786e217a13221ddfc9922e89eb47f00693c227557320d7026cdc65a83f5a1667b9950ef17466083a50a7a038e213434c9ae23ca5d1e1bfc4ae3774d15c9bfdb9914638969cd27a08650732f8acc80c0dd437437690407fb9a724603f41f260d88ad355fa8165941799e2cc7f07399bc9a5b6dda42f7245a4895004c7b1380d5ddda1356bab9d22626e5d08081472e0ea24f94a3d4f82d92bd11a12f8000ab629ba31d548b9cebbd0891f5291dffdba42e10a592f5cd85e766088d7b85cba6429f461163a9f6477ee9ec9779218bcf7dad043ab294d6bdbf0a0b5fc2e0344d0c0d8d67b4e6d95bb0547df6773e2e7246ee0eb60a6059b17b040939081fa70d6d927c0111629816834824b07d8f4db8568e81a4d5e28c903a407cacb6f0aff2f0e6846dc53d2b1dceb8e66881b1e558407001153a4be7980839d30729de66908b14619db1dcec0d8367337f9ec5739da12ee7e5f487944b21895641a9e16542352ddef361948461 +SHAKE-256: 57d7a2abf4fb4a97e529c1cf1ff58e49fadf11bb69e0c578ea425fc2cfdef11de9619558a27d9d8bcc0915a9425cfc378e1ef1391884b124cb8950d6179c29b355594cd0e295283f76b4b37f15af42a0e347501afdc31be810fbf49103db05184c3fce4baeacca1f53419e35fa8146c41339e34e757b1c8e21715375b670717bd79da568673b44f86de3187f56fa0423f2d14c8d2170706931f4c9ec98a1dae49ecde4f68114dd4d2af9037964b9096f8d73474f914552b1ca976e72d71fa9394d71f1b143399d34e5783ef841d606bc42855f9fc65d2a4b5e6d29c01ed83ddc9edf7525b0d23e9c178f5938b02462bb5598600a9f6d7e8905562408cadec2b562440ba5dfd872c4b9f90ddace9c16f4e59618c3580be7c79830d24732daa5f1f7f760cbc655ea479994dff4aea5dd6ecca3b13eb627f5aa99baa367c1816a167763a286840ee97e30065b1b935f4dc41ab6f55cdcd48ed6beb51c0a134914b323a4a58bfaebc7b96e63bd99b6e2c52744b93774b52d4eadad08610f161c1c0eb90bf1b5d4be223905748b2a4b8f9926c95f196147433fd609dbc8006c2dbda01f24cf76c81f5c83f2f5018963143a6c815884af1088846a439d3c9998558b3b6c230f725ffdf38a76778c90ef28ca0740aacb0b3beeb86ca933786bc70f53cce46976604311f66e5999ea024cfac381b2f024562e4c0e9816bfa8d1ab5522b8 + +Input: 2057111c545a7272101fd5df1b90951a0cb10710ad1a63ed4d6b642616f5c4e9030786b5b4f267f6786684b6d9b86287f2153012dad420fa69c8a4138547e94c0b45d7a3b424dbc4ab01e2e5f735211208a1190a01998f35b894b64f479ddeebf2d440e39ba6b74bf8ccc2fa469046067a8e50bffe07bee0216713ef10d1d5d4d8d67added24ebcfb1b758fea52037e5afd6f4703da888a6e709061f5c0190df59d58d89e7d46dd44e4199b46c7b9614d59f194148b96aebed08ef495a6ed42e1212cfc87f0d93c953f437f34840f5ac178c448154261acf05117d1a76f5375cfd81f6814d9386b22eaa48fa04fcfd2ba524585c418b42c41d60f0ee7842d4c5ab255cfcb64e70a12c2db98dd7afc701d216d25cf63c18ac52c496e320265e0e9dae306bba88f5883b3403aceaf5b0d9807da9871b224736afc0ca09f7174f1090d3 +SHA3-256: f82c53ea32e9f46ddfe3ac965e9337455d312d3d6bb0fd0aec5d56b6e91e6c8a +SHA3-512: 9d8cbbf1efd85a37d8f013d82692f6f371273139daccc60f17db41ed180a445e9de9602b908934ca633ccf6b178c9996134919dc4d20f7b117f8463568829225 +SHAKE-128: 623ca9f49358bae591f10acd5d172ade9681d63a2354038effb3172620b1a3b1add45a52961d64b371e8060da82804ac77150449fffab06a3ad2e53aa939c4014851f7b9e4a143d89c6551d1fe32aed6db46e2b3a32ee6ff60c17fab1bdb4cf64ba3347d8daf941eca04b958eb801c48c4a087919ca5888f75ee20b9855f59a7cefaaf829470dae7250e42996c18b24dee38690b7b5881f847ca2c7ac86f057dc461e557783758ec30a3fe4153859fd2b8df225ccc9d2af94cac57c72c598ea3ece349e06b5479c2feb05ed9a95894e9e4aafe907e1eeec9f014249f949380a62662b17c02946dcfa1eeefbd0528328421a3a63f365ec20319547a46f1c1a8fd3cd877f8f88610d70c6cd40f9cc5bcbd2f6cb436281ba361ebb87b7e76344623612035d411906cb9d4a99dfd65c6c19ca4bf03fe56643c3f0d2cbecf77ac1d382b793e8a284525f677f6c8a0fb1d26af603c4b016c1ae416b9b8b6c2d372eb7dbeb08db8b1915e9c101e875b80400b2c53a5142e0d03bf8fae6bc9eb98f58526b8996b1f1fcdf1b919899ab455de3211ffa4437b701aa08808cbc7ce58f7822978511f38a12115348168321838343fcbc6925e1b2958353a82b0c7235a45ae7327d6a718ed260fe577b721e4844027a027b961c0e23d4602aa2387bb5433b1a2b8fb82b5e2560baa9845e78ac892514eb93809e9f9a2d4be016b4995522f60db +SHAKE-256: 7ff8ff6248323b630fa3bdf30291ad972dd0626c19bac5a86ffbe034dad1f73e8762436ec095ea2ef919ec427c07d0559b8e64c45f6579ea61291ac9bde55f4082bb5994d22981632800444bf2aa5168ffe1a2ce470a7f35ec63ed1298642e940e818d2540a58511d1662e4a4d14397a5ea8757c7ed7f54b4f8406d54bc2e293fc4f16bf7099826f589bfe0f546389870de935febde9371d0445b3e6c0acddba0594cee53d2b6fe3da2da26e7c57a68963690ada2aa0582669480f676d9ab75dad30b979476943c6740986b1e09a1c8a81495a8863c06807464d7c2bcf0839b5be5b2286471ca1b30a35034d6e9dcea540080e2d20858d76081aa99c80a2f8973ac740bcd98f0bfce9a2540d7e41ffa1c02f4b3c134ef279db927e777837efb6640925db9905cad3bf49e92dac18017d43e0e9d16e3fb8d0fb1343d4b427befd30a701e9353c3f27099a0fffc18d8716ef4fa10581253c9397f2e7278f4976cf2f25dd75e4fcef1e297266b68516840de5f75358395bf5474ec6562e2e15f3b4bea73578fad3eba139a48e4fb8b6fe3c947465e6acde70cdf029690c75ac10720200727bc6d142c00bd642f057256842e83364712195f3ad203bfd490f2e4a0920700cf2d673e7a02e6c2160afe05edb9a9e9460f906a46b31118202bec3fedc5df6659ca1a7ff526d79f4c727ec27ecfc2fc088bfb6506b286417b5d044ad1a + +Input: f57450d357c9081cdf91f2ba01ebb06a5230550feee2f909725bf6a2f9e10ccd73daf7a9e8e52897e1f94817f5d6c38ad9ec81ad695b0919d24b3c321f3c627436a07ff5fa75e5138839495b5030b5efff2869eb9289f35ec7eba4b0b4b183e263b4fd4cfa5e6cc44947b3b7000b173b48938a3cbf9510421bbe9bc0afc18f1f20a8ebb48df70b8db1b6c9e0ced33d93c58b101d865c33d4ff74c5e411e312f4747c68b7bccc583d2a0d9d861bff8cd3238b2d28e54bdccd3d74e11b1750aca705f1ff3e2f7602d5350253846216a2d34a286faba9be11f3fcbd9f2ba67d52af2454743bc10f36325e2c67cc584f1c6668a5c286a4c98a98c29075296a92fdc9f637eba477dd38440b8c185b825d30f190f4243516d751286097335b808fdce18392f7c8ded84d8f3f19fac8e7cd6551f17933694312f3cb6fd241d72de8c9ca3d0195 +SHA3-256: 369259a1170e535ded5fabb2309dc934d31f93479c24eafad85266ce0fa44f8a +SHA3-512: 93828c471b3072ef0d251f6ee604598b1993aa056878ee43c4eb93112ffab60ead95c766a9cd070b6287da5375446a52e3d2360657de617a533246ffa698d11b +SHAKE-128: e03fcab6097fb52ac1782a485030815c5ee19ac80a5eda8b743be46fc0a7847bf69c2be0a526d14352e639b1eb22f5ed8b18a710ce776c15bf39b015f7295381f98ee18f301da56c7cc35bcb387efd5b5c90122b2413cc64754e3d21f5bd48f69039c2ffd557f8db7c269a02cba9b48c6932c22bd834e3b7a9499bd5cbea8beca7684baf14ce21aaa2bc5ae534831e2d5bf2c35adf7e4273f8cc280df1312d7981ef37d3af0a47c79e33b629e01aba1640d69e5d0071a05d78d0d7eb7b27237af7672fbd703ae52d3b44b4f346b342a01fef9aec20f998b9498da06aaabf9b0a900e7bbc9cf04a250754955e9a477aff1b1aea342871f40c0b246e2f5e0b2e6b90adebc2eb3439545e9a015902e18d2bab8a42a5f459a1e76e46a457de9fc2141aed7cf57990ebc69fee8e267074003e19ccbdb902a571ad6be46449a2e3721580648c8c7ffe8655f37e804b2f2779560996695b838c19d61b36a66e580c8d8cd7be03cc35d34927477e1b84f50c7ec9a2301414575cb7cff30ce32621d7e347784ab3d56d7e9f7fbea7ca3c8fe9c47af39c59cda9828a21e12b2d55fc9719d8766f96f78e45a01d9110272be1eca0df9f30cbeb4e18b6ff2c689fb8c7fa0a49c720344eb703815b93e48b9cd5b513e8214713815f52480fca592ec506175d54ab06564941fa0a77f6f490b62e622c18181af1cde3d265e07d3361727000ee17 +SHAKE-256: 67475e645aac0dd794abacf223928b4e53ce795a2b2751fbd11ea3fd688bf7960d5531c5ab16ec58b784caf73dae768f9a184d68533a9c5608029fabde14ac85db94306713d88f4a0f332bda92029893cb9f59ca7155b283294fcc7214ce38c57e54e09a44683990949a57222df7d25a487c1f802f6a64b4f226abde3018e057f449812c3741307d7868a8f448a128309a6551e6b3c5062ae8e63b3b123325bc953d55ea0b68d7e3454d67d83e0bfa5287e8cb1562977b406045ab391e1ea89d26d66aab3294f42e003ca7ba1fbf21e42c2ba955257dc49c8fd2076d707a4b2c4533537c8f7de290361ca15517ade864a4e8fe12791ec6f803b17ebfc17c58a2cd4c47d98083751f1d5d2b851f5827d1697c3429aab3aaff67da0d098cd6df66deea37652a4de78d6a350436d9977993bc42facc6a4e9d4b4ac835c5a4af6d642d64bda567c321364a6805bd3dd2a54229f83d32ccbbee94eee4cf164b41468f20ebd7bb77493c02f963fc4eb44900ce9ca9f0e92932f77cd0eb1fb1a8ded7d4fbfb78b5ebf326c0c75388435047779eae04aa09b3b0d294fa19c62c199206f81d5e46810c308cc138a01b821a4af7f7a7a4f4f65b4fe87f0b4b59f138443029ab9960a92304e269fa99c66d5657249347a67b6287d5f7b11149c440e2d0f5ca047155764e8c9a5f071da2b2616ec8ddd4740cba2aae2f253bb86c8619ed0b88 + +Input: 66a566fa4c8f5565bce3aa5bb0dab1093da688ca9b682113c67e1601aeaf3cc6c8cc83327c41203870604a4c7660aea2a37ad754f8d0510c275e55f62f8013cc72edce3d8ee3276a07ec71206afce1f5b86f64ff855b6e6a3387a6d64cd6f20b3d64147925fbea5042ebcc8f2fd4be9c3022adc32bad52a240cdef00446244fd7c866e287b40c4228fa12209145873942e825a96fc95166540948a22179cdd694e5bd61ab45594e71ada5cbab4c6a3e13c9f52666e0078b53a16eb882bbb19639db55ca23c93209e9db368cb244a79e741133c3fdf43deb7e3856b57403f4dfcf0d2c2f0a4602c75db48a09397cde2d4014d74a3b0be004aa7b91c4038c6570629fe6793801b9a15a9fc72a16c76cf9443205d5fdfb5eda33345b1c3e9c6ab4fc68b95c754678c6239e2aabd61af26dcc84789ab5305eeec24fc12673e62212ebb8408b7 +SHA3-256: 647aeab6095d50d15b90b53187903909c65d0e926fe2f42b173598c2b86f42b1 +SHA3-512: 2d6ce550321ca2b7a21ad059bf7eb32681ac7b74d584ca579f5a3c95cc5211a19fc5ce198f92bdab92c6406b34611a64a50c39fcc93b24648bd9f8762da18d5d +SHAKE-128: 72c936b2a615e8cf43cd7f3d6d3f31a8a35832b8dde7b3656b4670c0e28a382dd432ac77d47f6afe00e4e157e047a2b79b9de437bf166e9ff7561742d04ff3dca18ad11f2e1d7594435bbec2021db63ffd74193c618ca6f464bdd4e50ddd1256636d6b32879ef965f7893619489ad99bdf0735d8d130553b247437af1f50cf1e73c2e1581df6b5c9b66621b4812a27c3894828476607895d6eced756211df606531854d5ecd2d569c7a411388c8a34dc034d5bf53b54705199e4357bdf27b6fc1b31285875c90cee1f91e937472e1f038b4ea26f293bbc4dfb458d3a951d5cde73236f9c6c3bb3cd0b4524a31e82a60b1641848d2a9906561c926b35dbd29312f47264611d7cfef2b544a49416c4200fee03f82d5520500363a95e3eb509d43eb7a22fccd59daa9c91b2c5bd667c02e7cda424b25798717b8e91d4bc192364267b0fd795bc30c3a8302fc59d237ee40e219d3afc1d680efd0a5cbbd4206b2190713930ac9994c0e570747c4db10f49e917b5c01291e7787809bec13fcea6fed818e489e1070d0ea6caf8f72157ea76286d0fb999f3deabbd0f29d4b5f519fd43c4dc4178d4c73b8dbb820ec038026cb36c4d015987f3c45c2e3103964367c0c2b2c3b63412ebc42758c8133242661eda82fea4f89f0a0eff08dbec889f18dadcb50bb67b0fc97ac6a6a755b7046ab68c2659967525250b5ad9a168bd0585a964 +SHAKE-256: 6c3d87c88af787e6e8e6ae8cbb75ccd707f776ebf97d63b4b5c6e458ddb508825aba04d3a7d1e48c8ad054afb00ba0746c387eaadbbc628f0c83cbe9d7ec74b2f6b5c7b1123f0cb5b0b904c7530b387bef7f3e267d33cd4ccd53af007aaba8e31321a8a96a2d3dac954440463a2de4e8cf43499298d80c646699e31c9c806745640b57f6d0ff9fa842eda35459e76802da75ef568b0a13d9778f94cd59303e6329949ab14988be629eae251584d646088f7c0663e31b2d4313c7a710b8626d3d6c79f7c4887a0ae42209c4556d30998a67d7f7931e010f257ec44630c9a74e520a77b528f1e32ef9312aaa22685dcbcf7b3e519031711051bb52b3f5c6cc6524f2fb58f9d9e00627be494b71c0c1d021b5272595b9726aad043ba4642d0ad9f425ea6429fae990f80e9de6bf23dbf645042fa694b2664e77760e86880900cf085c573327f4b21bb5f4bcfa730ba959bf29c1472ad6b42882729c39c796bada7f93f8b403e9c57c13172190a491d57d97722b53ebeb717c1029308ed09e5d7b76e6537ec8707c61c4f4094468b26e7ee32d6fa6a1b6cbbfc358a3b769550d3ad670c77b27a08bc01d937099cc826e8a6693d07279b56de45b0833bee803583706c6e3e77108c643944417a1f2cdee89369d5d209523278335e470f362e584fbc9af47e23b7735173793a41fa5e6cecc5a6a2a3b8cdf150a93fc5a3b51ebc3ea39 + +Input: cdc6d3436ff6eb8e6c5a96d2412e564b93649fe237ccd6ed16f291cdbae408f3987dc5f6c2e3e73b9dbd659571ceab9169fa948aee45b86efe9eadfb2ccabd7e1c307d4e4a9d93f89ac14d5f5aec0c66e0f146cfa2da23fc3cfc884fe72bd91932b111641b784d9fa3303c32c021286b3d2285fe1805473b2a836dd8f131c0505544fe859b85a1ca53cc5d702c30c32964638971ebb90e7613904e403ea38b6790c75fde92760a8292a8559755c707c432cd30b7938d54bc191d3156b41d5ee2b43c130e74101b0e6dfab5827ce17c710e28b76a122b1199a4118d8fd4c9020cf2e25f7fe79c1d43ab64ef16b78acd258fdc465b9c91f851ad0d980b9f84b732b7c73070b1d959a896bd2e494744854d84d7d7e41e50c768d6acb9bdb9d6eaa2049804932a6d1990673c3eb97d66d07074a9cf05bd79845c4424be6a716184b88c14a3ff07 +SHA3-256: f4c31390dec66465595ca8b20028c8d988cf69687088ec892ae21781f3a58fc3 +SHA3-512: 61f0307106075b44e9128789692880872156ca6ab50fb7c26547c2f8b33c5bbe1da545c570df79297e3a1df4c79a447d27b1fbd0dc732c3cc0014fe0cd683208 +SHAKE-128: fb0fd31dd6f4d26cb36ff2ed22df3b56089e83a68e9369b3cf061522f34ca524099b9fb5f28d36bd71964d63789ee6f56b3983a17523c6ca6fbb59cffdb06a529fd9a8304952a8daadbf7913f5896217e863394f88b2c0b56b3ff190a59b3b46e4b8695055ed438bf110f8506b08521a1b5ae30091cc554604c68a6fbe7e5d69b62cc1c63ef2ba81fcc44d8973309db2295bff72f3d4df8d30a7586204f98ae3cbd450cef65243b01e399416f6e3bf7773474ab8684da592951827d907eadbcdac5691adfa96331704baf2779c0382cdcce1c3a33e3cb374c80629aac700f263f0ce92926447289ed41ec964b9fc41bef6db375e7b9aa1171758a757668e285d59edf6312d1cf67b180f3239ef5766e908ca62a864451b6e1a46eb152ea1b424d02197687f76a935da25452f1ee5494f04402db6a7573558412e92f707e521faca362abeae3873574a8224952d22dc8644f89fbc68f80dd2d87060d84bdafb656a79f125ddcbb1a7b109d239e77c0296ea6c2771d37c1301be4477d9ae106795f954c9fdddeda4b6a8257ef658b9007035029e08c7e2027cf79fc0fb2aad001f495d0adb442aee372fd40631768852ac03ef7e9f92ec13dbcb5411ea554784b9b8d132dd2ab916a07339cf7344e4bcdc9fbb7d4119b64cb46c08bd5a70e19c2e86d3621fa72cd2c87b9cadc8c7d0a930c9c6c13b8b82519cfe17abe774365619 +SHAKE-256: c4cd4f87185905edef10016b570a26bdad24dcee8f6c3c72d42f293eb7f9592e4aec73b08f74611ec6124665969ba641ea8fc79e7f5465b7ee88d2a3a8e75d5362830c3867b1f3ff600a6128eee98faa67b35249f9af1b7a9480c05d4c777f6b4e1085b8146ef37bcec59c72ae9d710ecc32ed4198e44fdddf85e848742e919575e891884ea7bab296045f10b773a8cefb2cafbefe539ac1968c8770d70cfb632051df88d0c7dac5fc10bff79fc79850f16352b45b80ed064d9dbfcc32cf02f384792fd7f6ce5b65374de3256f44f58f1983678f724f45d2b0d14e958edcd2b1809a60ad293a6a22741afdc94379ce5b79360527ffbc4403a9dd096488b4ca52e15db4594308e7e04ebf170bd08a3cf5264f84c57231626cf971d6a0698ad53211bc103f5866f9ded1cbdc6dd1aaab98bb27169548125bba7a48819f49a703455a799b38f1e13e395425ef4c72161dcc0ec544c0d9a515b969117fecef313ca5dfd2ac90b323cb5a634f5c3eb4a6c9f2b97245b16f75cdf3f4626ebf7f1ab6ffa57bdc0578a7df46ff5f2c7519b9b456f016447c4d3e32f7dacd760e0451b295288b0d31ee4f664b98d455e9eb15e2e0a9efa32b0d47007273c36e329b56e31af0998554ddd035c306aa563760cebf6ff757de573155985f7be4306a2ca30b3eee56b5757da7d818035a511aed45d1dea004885e39a2c7b6554cacc317b8804f + +Input: bd7144dd6b8872d12d4de7c059bdd66e35aa72f722867ca1eab8e3c745bce32809892d7e2f0e9e60eed5f2fb6cea7ec6a37d1b9aadc6b920786941bc8305799371458c7382877352d72fa11b71f100d92f6370cf748afb2c0ee479608cbfee8d449a3d5ebfc164544a57c35fc764b9c4d5bd94be96b270d9fd64058f7137fe73682f63fb98ad8e79298140b2b526afffc22a471c896b8437c0c91193a07caef3a905a0ba86f7809951505def5c0f19f540c84237a7a550fb5f93b87438f5492176324e3e8fa02936bd0c1bb1beb2c020447940ff6dca9bf81024dc4a28ae34e4763757a993836819e12c2fca5c684f8c2c46707d9a8135569394ae60e714bc91ec48d568156ec485072d15963395dc440fda3f87685274b15701ad6b1f99482f70b9551b745c3acbc9a48eb70f37c4d65ba57091e3d02a38dae050a15ccf6ef3eb88b7da720a +SHA3-256: 909fdac5664d90125ef601247c5d312432cbcaa1300fa96078d536f043db7cf6 +SHA3-512: b74f867914709c952c1824223c26e23cf2796f7f07bdf38468a8235629ea35555fc3a74799f5d425e5878dd0e7b430bb7c15e3d81ed67f871f7f323ecd185927 +SHAKE-128: 62596bd8813457538fe54d5bc53cfec3a501a87558bb0b83d9a5b73b6da5d7cf1a2c245fefc8356b408df3f6262afee9ffa161911e41c89f0fecd4a0bcfcb6201e7abf412a7a4898f3217fe296b507ef89785285b820c5b62db87621ef1272a36a09ca8f38293cc385b3293a7fff14290a12f8f7a13343c5998b15fd185fa1ba705ff653c52efe5d24d7b01163f920ef9300c20c645fd0ed71074b18587c582c6a871fd72b9c35cba4eb4876ee7dafed6981a08a4e80758dab149bc943883d88ab845bf26d869bf887f8403a5208af1d9150a6ef7d772c857482a4a7785d876a3759db1a62e353dba106ad3dc3949841f459ed093d65e8f0f5f598b9e49807c033347ea825253f42e15941f7aacf91aef9761cfd8f896217b5e9cee969907b1057865ee28023f8b9a1a989b17229f0657a9780e67f22c9b37b8fa5556603bc767268b4744d5eb3e151394056f360039eb341deab1a9e84a4c09e1ac8deb5a33b15a16479aa41240dbb4d5cce24b1ddea0ab879e09795a070f0f25e880707fa3e408280f664f5bd363d46fc33bc31507d973454476ea22419c65d59c980c0cb6cf272e481affd93a74c1c78e0fab128e5e52dc89f68026bf5689aa90f9a35166973cd96d92ec3ed850ae92942aa888e4b0d6407ca89d9b45827eb1ea7d1a9aefe6d36a52fcf898b09c530139d95c395b4c693f296eb936c6174f4edf4f3577826 +SHAKE-256: 4e5360c5316f1e8cee69513b72e2868733045e4f4a0a48f894b6f0c08b963e507ab5e872d55635d8f18afc1dd5de27ef3a79852a5fc3c24098a040a79f2884d443161a7c0d95759b77ae086ceafce427a9273b1b87db74456c184b07dd9df50187f0d2676118e9862c8c8c63fb1f7c1074fe76dbf4430c2493363d11b96a2c308c1f0ee9a885be05d2903395ade15fd71edc60e6ebff2a3a8a84ca5457a0e260a66c829770240002dae1ea490fdbf50003519271932475402ac7f30202d109edc5acb4cd12f4debe4910907d1dd64d21fe5d147c98d4e2568fcd82179b4227b588060c3d9df6dcf6781ce4357e324c2d5aa6087a7541cff561e8ae4334721910bc2736c74a3a8a28e6f7cc8982ebfc9530734975d19f96f8329e7e6a6fc4b5d125d39f206a02676bd6c75f57aaa3f41b50887da7c40d69f385ec67c8948e55cdc71ef8be77f4f1415117a628fd8a98e5606396ab6722d690d2777d5dc25334e73aad0a66ff286b93bc8eac44218d28ccd3fe07b646d1f6805627e33c7999079ba611f6c067649af2db730709160086cf703c6ca9dd9698276e67dcd98cbb87186dd06b47fd40a43b6fdcda5aaba3fed0e74dda14cdb39e9e627c3673e5861ade9dc5880b8874506d1f6ca40a9a16d68f5b63c3c41c6770b94eefa15286ceafe83a2f545f29bb7e4d51c9c23090c66ecf04ca94d1a58ae26cb27a44a40e76d864 + +Input: ab2cda3a61d4ec27dea999c7f0dc114d878162dda0032751c240ee4c26c6d1e0b7160d5685bc2ed8e94ba5c10a135c02d68d017d97e0317e967169516d076cc3dacca636eea86d743cf59ab24715e7beda94fb78190fc0c0f9fa85e9ac5b50799df52a3729c5d56e1048dd0b390a80afb11e6844d3f3d623e8653db52d0d583ba48621c19afd04eb33da9be01b49affd2e2cc429e29db4f6982e52965e962ecc2787afebb862acad36151c8e2332e80e9bd5c49db3f19de5d13ee7aaa9e794e8a9fd723cc7435c22cbbb4b4cbe3377260e03ad8c4a5d3996e0aa9f08c66231e58032ec3c6335e7c48422b855aed98064e59fe378d6483e98014bda431ba7d82ae4bb93995d1994377a37097be92d4b0d448f863ac691a5d81efafd7db31e41dae27f1ce629972d696e27c6a8b9299bb3b6ea4b5e7d8cc5585c92fb0552fdf14a3c2e56a5417ab9 +SHA3-256: 369ae7933c3923f0fc40fcbe0a8f5a61daf5cbc245e4e87eab1ae892319c9cbc +SHA3-512: 3dd9661a91a8b678fc8f7d89a8ff28f8f0fe29ad0ec1b9e4ea78be46e5704bc56febd6b62348888cb21cc3e5f92bfb7a02d53fbad714d62ec6e688038f832214 +SHAKE-128: fa130dfe3b262931dfb09bbd4f2d6bba50398d9f84a50a234932deca342fdfbb2f877288239ab8b8ce775ac22b48c3099e642fa50b0a0f850be332699c58c2382f9cff7ac04162e29b300a855629bf3f29593454e6fafb23b17a174cedbebc699d803f492707efa2acd26a728a5e43eef4215c2e19501f69be3408ce053b6d9bc09419e34b89816b674915ca763b743a68a7d9c24311349df6370ff4a3563676c4dd7118dbf1cc7808dc0db19db025adb62dfebb81c938ae57d6cbbba9a296469ac07de2d00eb44ed14808014565563cea6be1561c42c5ad1aca52403b8cfcd18064194878020691390dcc65a929bd691036cd3594da4935d0dd46871e97eb149ac3bd9970918f3aeaf5bb1a1da294bb3fff082a63a34860e467bed8a6936d15710acfaeccd00228cdc5eaae13ddfab763f712d05c65e7e222065770c6722edd91df3216c62000ea0553e06a7c9003756eeeb7e8c2931078b93d00c06c5304e50d3015e6ba831d8c03020584ee0758aabbb91883ab28f835acb9ea7c7425b45aa89f1f5b52fb413b566994d0fc8a464848415f7bee5edabbc4c6de58ff567cc38e898abce0d0ecb0f11d6b8366a4566bcfcfc85a0ad61cda2c329d86732400546c40b579f701b140de27fdc43b4e581fd7b98d31e557f814e1ee2ca1ae7ee89b7acfc8ef4e0e7fd8aefe3d74f8d7b6be7da2735589638a664a2719e7a5e08925 +SHAKE-256: b18336b251cdb716cecca025b0f72312945f45ce5cd48ad94580a20d52890f88c8f19fa363c39878a45ec9bc6a56203ec837b8f601e720d41cdaf962e10cf6c2fe4675a3a5bdad2b87a4e0f8de92aa9f624e8d0716aba96ddddabe09e0fd6b8cef5e8804e98ac8c39bd7e868d5ebd75de7b9206ef9ffb83a3393c38d3038b86011e377ccb83d397c1bad1ad85204eb2466a5a3054b8e9f06e33f3bd84f1b8390e039026a92916fb2f38023423246a8afbbfc6c5309f2052635eef84e01aa4cff80ef15259fb6210e7e55c9fe1aa73950f2982c9a5de76e08f192f4c463a442d4fe080c832ff0957443bf6cb67c63ae417b4fc5ade69f9581a1eb4e98cc6229f65be8899b52e69da6b6e888ed6a17190598aed49887117cdc44697387b2a9b0a0492fe10f802916dddb030ffaa30aa57fb74faac41660501f015ca20584046879dc1def80443ecc3dd3e67b092996e4979ddf001897c2cffae0e8f667ff4e099fd194e71e8e9d0f64191f23d97e9837e794193d97f4369d3a11b383999987df07306ab9b421bb04a05c8c7d74e93a9fd191c9242b33f30e6d81aef5006f0559afd96df43a4ea0abba52193b7967a702c72c653458fe9fb3ab5072f6b53c6b5c45aceb770ef11b446e00db690636820f79fe935ab6f6490d06180ee6464d038df41ca80a6c3cd0e9d46793d86e79ca4ce2b1ce9a0de7001c7767afbaa122037fb0 + +Input: bb17a22648ea1f9c6fc8e88b2441a5186e5af524ff9df72bd67619d36bab891426e4af724ef43e8aa3e04071a618aeb415b382648595251a055f031e16500998de321f6daccd3c35eff60520d0aa0d372efd4a465d8000fb98c8fb51c432f4935cff0cd26e64c02b994ee0b314ed34b8e3bbcc0569b9f9e2cd5aead1ed938636fa64ec93dcd22b935fb3f054c5d92e16c2152dcd135579c66f7d3ef4a6c7aded48a97f220c44c7576b14993db62b5e80fecee665ded906a52d88f071a7821d42f0fd0a97c0c502854e1d96e33839c3d8f0008546754216b007e76f3cb61e8f279c0d5ac219854cd2d529e59b08f4007605b09b0001c7d9338443826b39243954db13fc68e2f6770a9374dbdd6be63c020e3982c13a06a926aca153181c6833da7327d5c7e52b5c088bee8efa6cd312359f47f0df0389bb44b87e1633e306a88727c41ed79fcb6db5 +SHA3-256: 022702776c5473bdf62dd6ba76af1b02efabf782cdc2c32751f5efd82207f4b6 +SHA3-512: 2dd892ab5fb7fae8f4622f775c06f0be69628bb36cde9c91a4c664fc2680ce00b3416ce4fb4c2d6c76a92d4d0e4c0b67165151d886e651bf0b8ab8a8e3d9fc7c +SHAKE-128: dc9ba7180b3ed55c177fd1a80b6fa972e5aa05845cc3a0dfe5479bcb4bd92ca591b07e61f010bf61724f65eb786139d244f8d9e9b89ada2542b400c9ad22a0b4b1780adc05dbfe247e62e2691333a33117e0b411aef2f8e0b5320d992bf5b682a56b25bb6cf905b3733e61b1dd04c1da85069daafdcf590aeb0c61f5d384e6ad67092fb99e85b09b03f7da607f5eb93e03b409f69ef14474486966319bdfe98f2fb71c75dec6c908652c03a73e06358db0d2cfdf11f9a192fc71cee548bc4f86a2f883c105f1f5bb180a5b20cee3434f4de9051c9d309170b7a86903b04a2b7eb2452fef6208adbb0a22e24ec150c4075b4d19fd375bfd820bc1ad6197af53ab50d20ceecdae600fc7e19c87fa67fbcf0b96fc2de66ddd9a2e6c0b383d8d7f216e54b4cfedfaf9a1bd8af8d45d03b802cf5f1a4718536bfa774f6a10f39bf8eedcabae1c05fb59066b838b2d717a884b2464c469a0e040662471723422ea1be7ccb16a24975542a41e77a61b58afd89c725d2ff4cfb8c4ec946fbe24e85c3334461bde680a2c41de8d6f98cd79fe296c50343e1630baba7c9e3d859b900b7a136704ca0a73704abbe97e3636c538fe3936ad225844c281e3105a0ea61c8feae6db351d408b51d0db782b784280bdace171efc0362940f6ff400800a9e2071b9d605cbc30afc256a5f34fe77a1313fbdd7c06166ac905d1c70314122a7c70bf80 +SHAKE-256: a2b5558a4a6530697639ca8869d62d9fcbacb00679b3f51c73c8934f951c389a9e36e1d088a02aa29a01768aa1241e45e50df6ffb49c4df396d494861df3b24eaee148bbd5d5d1cd737dc371189b4d5b867b6ea0abc389f4d56ff30e23b72493a5de8027ce52d5f9d5921b12f6dd9df5ce70d81d895ce0823c7ac42e853a2a94559fa0e01dafcd12a8bc045525662d884b034739bf0a96f6c4688195167013126449811ed21c36cbe66a1460d97f73c21b4a775481be6e6efc7aa3d6f2c0411dd548e66bc5a44ca7291bd9bba97ef952b558d9d17aeeab92d733061586ae3c9c4d597249d3997bcbef327d9cca51ec1aa6ecdfaf1bbf7b35c2bc339d59f71a68dae42ade74279d06bfba6e1751fd85030964ac336bb3336cb57e6ba1699050f62de9ee09ef0a3e84f63beb3d6a3ff73d9544ac6d947032ea7d07d60a0ebed0d107cb61ed96d80a9e901b86291c14ef681ac9884270cbf998ca00557ee3f76c02d3008cca44c4989277cea4c7b9cc36453b912120b87ad3751541bdb87650e04c2d4ad9ba080e4d167efb00ee2b92b5b5c90c9b5daf68b1130187403c8e5b67a781955290a4a8529d2ad6946f8d99399c1d032ae632a0be0f2f7bac96c710e8a744288811f69cc1d17c74b3b426e6062b69fbc9145992c1d7416ef1e0cb33218c13d23b841b5d6d03b3c21b322c547f562ccdf0b84a2b447b130b9a14643606e7 + +Input: 1429133e292264a7a6575b185cdafe44abd33cb2c1f1760d54233d37815fbab30e9241bc874844eb5d92b7500ba59fdc1e4174656a6779d2110e02b4bb0d55de77b73e2637a0ea91ff7d574850628e629739255cbbf1121442d4484b17c0efd0b1bc523ca13d9698943973f13d19cdd3e14415f7b33439d14fe3a0e2bf0ca36855d06ac2dbe304c7ae6a888f998f0fb05cf39a8a8204f37ded23069c23ae26d4d1eb3eb9baad24e384e155f1b4e91e03db08e61755ad7ef90f47a038f4777a568aaba59e0c5824ee759d7f4fb0dcd6299a8e5bd24c5211ff8340385020b4e802085922b064233a7dda883731650d3f4e551ce52ae04744c9599244ba75c253865e5256ff5c9c472627a790ca1eb93adff4c3b62a8d94bf2e5088df1be176cc5abad45ecd38c55cee58a57cbab3218d671f695d67a70b1309802766f9fe7dd8a3898f1e976c32e8bfba +SHA3-256: 7381db34d2f4af61898478629579627f4e1b387c394befc924a680706eb71551 +SHA3-512: e3874e6fb88df8461277cd502d81ab678bfc16752400d0825d7d37020dd1f568e0d0e480c247426b05ce938879b459fb56a47235bfb4c968132b773014fda224 +SHAKE-128: e9ffa7d78d45d2cc0b758a623b2cd0feffd0d3cae7d46f659c33cf0cb75b94a329d1f63cd037e341df9e0a8d2d84b065b985094d06f5f9d40fcd03fea68a969310029cc8cb7ec086808057fec0179a6a66bd6a1050124c594c8f919abdecce6da48be9c0e943c4034a788be6963ea0ee668ffecc6729494ba17bc528851c18ecfc977ddaeeb611a234406cca83cc3f61a7bae5a33dfaab32363c8decef81619e56390be9689e98e2bc60a4b60d5568e62fcbacddfab5e7673b6ade49a63fdf7d2d73db401802df0a7937d89acddb00c0d403aa75cb17bbeca61c31a369e71d47e24e08e64a9898cb0868f175d30e989fd640e565fb15caf06a420bd0a725658063c77d2aaaf64b2dbbd12e6e26be4f5afc745f60efedbdd8b0983156443684e3cb358c2952850535e3f4a512a355bdaa1b25058f798690d4ee052c4b6ea9c243a9df886c973f47311df4852b62442ead15173610fd0970330f893e1ef410ae5df740cf2e18c9ef4b7f907078aaef82e6eda84c964896dded21bee68ade27e70aab5fed626ed1ba299b7f0eab4d3e75d8c3c1c143e406507069ed7fa81dacfccf663e1c2423f7cffc215f7eeba4d720f2fa7de3064255fa4d3749b79f991e6850c4d92adb9d6f5deb3846efc1980a49f69873d8eb489e6d99e6546af3354e769bd01d110de7b33e9477334b7f413e3c118767c7d0693fbe7ba3695090f0c27c21 +SHAKE-256: d47e404a0be71c17348b23d79b913aea6d459755b6d2ed687ab65c8afce7cf5b327f2abd3394cda2dba9cff176e9e8e590ffc60495714f65198c35a865e2dc289fed1f7ccbc7dbff846272d5f5e17b10018209b9fdee7293ecd86ba33bed88a8dfa0aa45435250a32cbc2a2662d2e974718053ec02714b0b57dfd6a668c4c9637f97a4c2e907ec197e4480fd03ec84d1fe23e4f0d24f73fbbe1b5919ab42db7318f074c9b7a42e71b39beb077c32be1bd44d6648e22ae300f7bf6e327367fea2d13b7a8c6799ece5634a58b84189050700982131f48a84221919860cf299f5339cc5f10c95bef0174f5bd1b448a100677daa8bf8d0fa829fd2174ae43030c4d62f2287ab5a2c0254c0562b851d94ec275b33c4251470c5f1f5b529b00d3303b5d52d400b3ac1e7688802c38bd9ace7b676221287adb1513ccde68fa50f69d34516583f9cd957ea093e587b70e55eba01e946532c0ab044e7c5db59941431f2b31e55e96102bf7d64f0d1ad873dfed97e7e9fca95997d326fe44c73a6ecfed093f6779a165957bddedfd5df62b3157003d8a359ac3bc116bee166a0631e583804dbbac0b3088763b7bf13d095a4190245f1899ff32a141e855f34a31409201b361689cfcde0f2ab081743b9fe63c7b7d9a1e643783fdc67842fb005670490759aa354b5b7d4dacf5189abd87fc237184656ae8155e58ff3e0ba8f7abc894b9a95 + +Input: e927507afb8c2a233fbc171ce6faa51669cf6017b7336416660edcf5f9c9c88ae19bff34383c525189d27fee3a4888bf123b587004e20868521d8f45569450d22b6a9e18c1d97621e0286e83cae407833bdfbe9674864672ac52eb7f12a81adcf0049bbc20fb4b3cb423629690ca8434f8f3e9495f7ca70c6eea6deb02049310a7e94411e739fc1f5a9d39486de6b35b19b59eeb98fb43f4b9701d593952547fc3788c0b85b5c0bf2038ef236907b9f435a4158eb619668bcce8d5c417b5ffc959ef96f674c6ea2a01b7e0f9f35a4f67ce92d59c514c633d7d0d66388ab7660524cde4541ea8e966c356931d70c4b0ba32412c694c9de13f7584beaf1a40ef542fec56acf435ef6e6fffb817933c8d85cbf6a5367ad4dc7188439a717f5e9bd18d62570faec9fa41ed8efbc126512bbcbe33b447b7d214560287c1add94b7524985d92c4b8d7a376f65f +SHA3-256: 044a7a86cc56aab6cddda2968fb158965db849035cf90f4ef66ae30c9296e4ae +SHA3-512: e67d1dc102917d0b894bcb761c7eb753963e0d376ef21592327dedf6c73454cf0e6a732681d950535b35ae4ad9952b23c684f42d818ff5ae8fe7d9cd04973bf4 +SHAKE-128: 041ce95b9fb726d7274617b76f063f227c9aaad53d1d07d011b09d76c1deb971f82890c358ed4ad729b098920629e32db1a9098b151f5410c49dbb8876f6e921e24368b04f99461c0ad28a7397aa70c9cf4db1297c61320e69067d6b05ae2b207892b0374bfa9e7c1a0572015069079d4b84ef81eecbf96eef3d51879af02d0797e1c33f2bd92fdc2b811126416bea1ff9d4eecd9ec59b0ae4f53d15498c6ae58179eeb59211630e7198e85e3e421f51fb21ecb889421202ee270783c83d1d7501a2e1eee81a778fb0daa770859deea9a523467baf0555237d25e6f791e3ba01ab01fea1f1b0b599785d383ad439c8c330fc71806eea12e1e6f43e9375dd7e884d6ffb6ecb6a38c3c537bae7fd2a96a09c3c785fd015e93a1e7d56d844c5bca2ba28acf36364975e6fdf12ea24fe0b6614a7100318f69fdb13d428137f596980f0820716077e79036a1645f599a7d9510e9557f6c4f18c94f7fca6c2f9bf8ddd2ccc7d825c806140a8b14fdf6b2752a87cc4cc94001960da1b8949ab18a03ac0bb916b60ada763bcc92a4e0c542751070e2a9931f7512624b521e98f627da159cc16cc10747b58f86bc67fd7d763ac766888402c04a73a5437972714d75e5050b9b708380f4c32719bcd01ba2e6fa0fea5b0a2d5ca6368e506c9827c4c7ed49870b6705ad12570bc83c1eed8138162bde9708ac4a089ea3170776ffe1772fd54 +SHAKE-256: 909dbe8405a6158ad0cb05c3a17f4ce9cbec209fb93c61d53f06d4a682c3c20d47b43a3986a820441684452a42311e81dde785872e6570faf0b4576ebe025dacd5a31235cac9a94e3c400b1be0ceab53225bcadcd703fc38719f645ffa52c43d1a194c2ee067f5d7bd568d03b75daedcef50a15022e2430a5d7f5bb641c100ecf04f7cdf6b809d310d4bb663603fbaf1e2fea606a66fbc3900058051dd83b672d0d822600c82b3949be4d42bf28b5d66e8958114bc9ac8b9bf27ea1c93af295416df45683b0cb8a035d97827ba1648ee0473ac107a8a97ba705e1397fc092b82cf6d2f54c814e6c1cb22db8e3963ad48fc8178b02248ce311d8ee3510d0769e2eb3f8795d905df5b668990225f12562091c6742eab8a3a3c9872981d1a11d8bc158375869905b9100bea9140424dba109aaf8fa508cfd10795ec3c45940b796f73d27e121b0473f97aacdfe81b508f675e7d567a5ba6c0a0d703e0f8a99b81db89601d44caf4551fc13d646aa426ace2b2a8f3d94df76696729a0a49703f3d5ab1ecd3d09692765aab203ca13735ba96f577b72d64a5538338a7d440bcb2f697981949f8a0b82c149ad3dd171d92ff0d340616cb4ddcf02dd401a1083c1a97de15f83b1b7a166058bb96da0f82057beb915a2fd5ca776329bfeead55086765c041d4569b1ea20b16dc29ac0e4ade06cf2d93af463b5f5674dd686341e4fb5652 + +Input: eaf5406334eea177923921cb60824c02ed687f9fd449b18ccdf2f9a4578159a3b4881e4a22ff0156f561c59d61b3469bd3150e88784a58c38838a95fd9c672bc35c3079f81b8802e25a142bbc087cf5bd21a78f12a8e0965d6c9a7a5c3f11bfed6c1dcfaf82e06a455f6fed7ec3e2defee27c65156f53b52731c309876590aee58d7e3f2cca78254c2f05b3e5be33d0336f9f1e031e50dabc3baa21dcbc55ceee876f7f60bbc28443d18118379d0febcd78b0f2fb6d19cfcc6e9d00240aabb505919d07423cfe87ad5daf5c5012a046e7734b29ece5f8d336439b5df22cf764ac75372a6512c856e7e86f35e3841986e75cf635fb0dcf983d8f5917197f591c04eda703f1ebcb3cdf6fd9a309e17a1a9bb366b53fe13f1c9620917ae11c8a39e7ae03d985122c7e09f833c79742fb1c4c01f8dca920d9e514bb732093daade421f971de4fa912d16340fd3 +SHA3-256: 73b4846f84ca7b3438ec7e8bf8cf03e8e84b6e33fd84d7921e1659dd4f6a3369 +SHA3-512: b1b3e1ffee4856dc021a654a9454934f3aee82f540dacd9dfb0dda52647fc66c14f05a43209a9a4ee18d487ffae6dcd12ef60d0ca750a28dce8df6593a3331fa +SHAKE-128: 87bbe0e9b60d0480a3f2b5a9f6f8156ad6c09defcae79f69c5c20e055a0602f0134c92af4bcf269fff5dc1c95bac87fe0b64d37ba71f4bb51dc4fff15c2d6e0881cb63461895438d0f077dbb964417f7bf8f9e76afd952f3d12ee38184858feaa18a88e70695689930df502b2a863e115b32247673dfda4e8711c76e96c15b896794d09d0137f1590d53220538a624fbbf646c521b51f78e10fbf236f4e7d9d3586c52c12f948747efd2c128bc47c1c4b9f4845387291938df49cc2c15edd96e7d61e5e6bc01fb986ba0be821acf2be1d8b27a16ec9b5a1978ecf44adae3a80080baff5530d7e7682f7bbffc1dd004c3099beb86c2d2abf458a56f56b0abdb02c8deaaf0d0e30957342a1b9c7c0b3557321906d6e220127c4dde1c221c75e8e61c6447af19f61509d742cafa3f26226e6006253d963949a3334e9746ae028339e9b9886c306d11acd52569dadbfd65c67c363318d412b042e908479c3ad85b64267ca700908169894e98ebcf43ce0fbc0c75516bbe893108717a12e0c6f402dd8454ed3a043b55dd3918dc38140e73434a80f4e3ae913110c4cd7ed32b156f96e4c158776ef9a37c4491c60aaefb4b9800e36c0da115e8faa4b718d2855cdf64f80e7ae1d028349843142bcc0a3dbde4af3e006fe536bc52f84e3e9fb3658d2ba7f81d3a10b6f93b99b427be35dcc91c762878f73f356a4d2f18230b4121c91c +SHAKE-256: 663e6f5d60e357677b27b3f6f340db9de8bb750cf2d3733f2ceb9fb76f6fbc5818de159cb1b58062d994b6bc4ff5ad84d2f506320464c28e8613356705252cbadb2428058d1e181c4c61c99aac478767a30cd27705710afc03af7fd1fa3f0c30b9f282eee67d569f487e345de2fcc20c70be9ac6d827d0073dcb4acf1aa7397e433911478a68df7fb79e93d343e387c475b013ada4153ca75ce365d3f233fd53ad30d672b4eef590f5a0519c60a06f8fb8036b301630c713ddfbe1f8839519a22afd8f3a0b29099abe55167dd0aa47b765172d64d968843cea0725b820c86fb63c594e46144aae53d2ae7d08ac4922ee1c8086189ab40289278efe3677018fde0c1a27b4613089fc6ffde5d221c74cacbd1784b4a0173df4fa7af73a53db449b1bfac9b0aefea0373e3937a0e9d208277e8e695d0a93deec9484a655af994a476ec9e6381d28ef6d37fa98917ea993b61adc22bf2280259b6e0f7cb3724b5a6376c1419aae0b9fea6e628d2746334a9beb6d68de061d438c0db0af4d49326261cc50eef580b98220fb1fd2ac8363bc88b6cea24584371def90389202e0f9072fbcfc029e420672d754366bb1c840e4b4c94a512aa30c5742b9b4092a7008e591d73ff0e1af74b6d61724e774cdcb65a0d64578b2120858cb968f0ffa0f3d4b8e443d124b84a5d3f2ceabcff867e7cae062dc9b03dbda62fa0a0292385066bd1a + +Input: c908eb43c3e7f6195880987da3ccfe7fcd3f5204b6da156d0d67f1d26ca0fb8cf20d2fa729b7812935761943c28d148690c039f49a9ccf5d2a2311fdf7c63d69115ecbdbc1de01d7646a6d34afe4b4f4a64f2730a5b28cdf105d9919e2a336212a3de5b199d58cf67f058a5cb038f0612858435f2e709a81deeb0663cad1bf562aea8b83c334190fd7cb4598eac8a089cc1dba78c0117aef25870c6f662ea2dfa55a709b7db4372629df9e12ce81bb2c41c02737400dcef1be604cc1c41fc67c9190e5d8017da4605f1a39a37d848548ba98c17fd767fa0ab147d0a011a8ff12d0268fe01ebe014397d1cf9379f8d4ff7f74b5029017a9d05b59aead9fc7965827a233c004d10c1bb355d847f88e525af942cb091bc0defb2676c5db34b1ce619fde8af3c1fd7cfb3c2b96fc1bbd688699c230795a535bc5a6c5d76c4bdb7ddac7da2814e4de4d001c4f2210 +SHA3-256: 89a35b7ad236d5f54a93541dd9c07d5c063da7f5a83d9d97bfbf25cf969eb372 +SHA3-512: b6418e570f5397b7c698af8d0bba10502d280a5e4394db97666999a2ecc2374d40195983d66c95b580bdaa89b25d2c1175fea57662dd5b582f673cc283e6d2f5 +SHAKE-128: c98c1bb3f77198bc003ed30ff222a35c30c77e4f28ca59b1cd1ef8728b77e0d69e1e5c39fb16acfc3c1f9dee63acda843dd7fb2c2c6d75ca2e9f4d7aff8995a27a7e68d4fd29fce5556694930630b503f52d9159b78047cbdb168f959889ac961ac7cb9bae581910cc3d78c6c3840251c7e0caf186fd6cbfea58b00b57edc3d622e934a489aed19e9c2e4f5adee86dac332f8b01f4f6e8ca5ba250a15301d3a0b093df33c7a738b573bc39aaf794dc1bc3be3a33106197f0fe17c36b1a11eee6acd016dc27aa1f4f9cf44d9fe61c99095becef58e6c6e1dcc2d5b8a80229bc89a49c780912bbdc98082936fe234c4e93e5ff6e019827b69a9309acf78552ea2a0a7743103d9dcdc609949e82929992b0b55bc4c1d9b3fc86ca7be91b88ae5d163d7990ea14d99b070fa9da4df2a5a19ed943e625676ea83adce42fb3c5320e6a36d6a7c980f37e6f36f97002e729a3193bcb68f32109c424c6896a93923ddfd23b69b119c2e1323ec8275013cf47b99a641c0e21e58a0314bc2ab8e5afa5f15c075e3e97b8b208c3051d69cd4be5a4be08ffb851163ae017b99129b0690b27331cf3c756b60d5f085fc8122e91c50ec143376cd56015729c7a6fdf6fbbfbd8add78f7c58309a42f62f958fc93694381c2e0d85cf3b63612b7d1892abdf0756dd4350bbaf103c08cfb4029e55cf72f046b08ba1202080ffdcfd8125b93b2239e4 +SHAKE-256: c5e41d4e3b73dc0f379048f57a41602b98885a859d62394c446888817e694d68f6b59f3213a902648e0701b9f2c88e5804c6ec54849783ae41250439c6740a710f4f25e6f03a6a6e654ab1cab8d14dd61e69adf8d1c060b349b69c581c9d888d9208fd5c0f8b48e48878458330de27de687fee780bd17a40205819c576f87e9f580a3f802cb3f793a85c6d22011f4a6a57a3ce92761af6a8dfb0bd6505aa38f1610aef0980932aa4a4f5eb8c7e0f7d6dc09d0326cbf53527e4bae49cb5d4464775bd37edf89852769031a989bf22d6c6c0c65242a10fca2275fbed4f53496114473c98d9ed1bb6e1bfa9634ed9b2e26614f3b2798f184b7189ee911e52af8508a1d20a40a4a3846cf25bf2a9a3a521b53dbc6b17b021c36ecef22048d0f62f08dfb0e2f34b498ff094d4baa8716f6d2e117cf02eb36355508ceb98fe66e7e56121ed7c26af4dd6dbec9ae983c3e14b6b4b78091b1a782997143093436967d631baaf1fbf8abd074fbf9bfda48769a5967fb3911071a1d1aa649d8da7d0a2ed914c5862a88b305392f0beac7e11529882f89d2cefab476373b4a6e52e798931d9044716743e495a05d7742af43e35d2f7b8b0a058b1a838c6258e505ee748d8f6e43695cf0bc681adf2737c0268cbc23015224d4da38a97948f10f986f811eeab62542d060daf0d66595290c3f89618d6f195b446cb3090c0aa73e8e620c1b3c6 + +Input: a730475ee0a5d4d5dc2fd3f47c5432cb01ff205fd500d26c584eb689e5c87ce8c1e2529d0dc425077acb634b11efd86632c6dbc2614551d80783989451597612dca10a72f025a0aca512c90e4100936707daa7e424789391a566330749b61550d009763a1c0225fdf8eb4663094e3df79dad4883a2bc814bb2b3d1704528bfb00ffd0cded220e5fb3da7cd383522a7791b7e18f6377d44a2b77d52dcf2d222724b7eb2a4208819600ae05615933b2f5091a7dc3cf4bd2bd9636d93129fedee883eef65681d281fdad16aee6d0d0531f642a38f901c852b708a76bb6111c7e747162bb309484dc8f12296a81bcbf9ec91a48c9d4b5b96b6144806aeb3d9c91b2e25a3d6dffb73770a971281abdb105d6748436111d592e0398f705b6ab49b598c9611db1b6953231c6b70d7b2adfbc506baf780a60cc34d097863e52fc722b67859130876ada3e856e0b409040f +SHA3-256: f005141ea2fb7fbf533a5d4498559f87166e367cf78a381a108b88934d058b80 +SHA3-512: 1b06721251bc6a6257a8b63fcb04c1c2c6f64de644f6cceff44146007771f3a959f4ada77d91ccf4e20b5555ed059ae429f064fae1acf74c8c13f0e80e360fcb +SHAKE-128: 8dac834f5daecf2ef5d75c7827f4de4e5e3e1a7fdf6b1274a5ccb295f03cfbd49016d1ab4c9d16f28950f28803e4f9993f5f3bdd2a03173d727c4052111ee65a0f35effd3c492e09ff0730954ef6c46721380fcb39d2bb127b197a30b61da9413b0c4ae60dd2e34595e6cab6c68f5673d648e0631120ad4c34c1517d9c74bbd4ece0efa47a1be36dc3481481112d69f554552ded14766a4d0bad8dddec9debaa57cabfa88049dd432d59d230046925411c050b6901b9869ce2c4882e74702efddfdac1fe2a48d93dd62ebd3756fe92aaafa7a0bb880ef32e4691904628dc3bd0e6d9e028b10df3c31a9583888c1276b196cc5cbd74d6cfca7fb9ff4461de549b2cea752bbc43faba439ec8720525e87c2470e48e1d224ac168ec221794684720b3dfeee648d79a0b4fa3450b1b681b1a0f4d4b4eb69f68bee8e743a140736b90871dc612888a45d0bb0053917783a3dec5008eb97d748393dcc728b4e1ccc99ccb319a35dd795e1362de1d76c3bbc8d9fe23b15724e197f064cb2231df3fc493eb61f38f3fde7d12d3b73f25d0d0f873441d831af51d2f1a55db090eeb721b94d6b1bcb5e7001f247c66d4997f767b9e0af59baa3465e0994942d35ecbe22f1794bee6ab1dc3ff0dbcb90a41515824c3c96eade061aa79931b2a854815150632bd64af00646505048e3691da15923816d7a6bb73ab881536435a40c020c43c58 +SHAKE-256: 48b0055293cd80c3b268af7384392ccd65193efffbc3e242209868e487ca83d5d550dee8c6b8da28f35b2b889eb1cfc1f881b15037958804cb1005a60ccab44c7d2207598fb7026056812649056cf2f9e3bd8d7cb437d5d5a97138d55ef16a6554ceeb95719777dd0dcc36e6250ac9f4b38882c175d738ef7bd25a77939374ba9290f2669ec80b5f33576ef5f3d525dba4814951f2137edd118535b8f2531822776d117ca0fb15e3f4a69d17a23c59435a6363b871d08986b3e5f6b918244f58d826aff7e84432ce776264f04b005471eb28bdcad53216835bacd603eac0fe26e5aceab0ce399706189d659b6935fea38de2ab7831350ec4aa087eab4d44bf2c7d52cc7c00191bca347e91ae3f195703ceece8170aea872bedf1a6cc0565d105ce243699b18580ae0bcad58efc748b6eed3c0b7d0a7fe6c4e9263fcb3949baa912622eeb68cc6d168dd734e49df7171ac50df238da732cb9f025273197e582cfd4a057cef85684e4d7c82efc78b45ef5d6c052d97d7b82d18221a6c4471300c54a50b72f52fcce3ffb7c1c6b42f4d7b25439f7c3f8e23f12cc629f02758f603d1601f6a3dad29f9ff956bc5be5c7e3f1c822cc800ba2f16fe43666b763c0b8838968801484b7049977c15a368e4c9d47ae08b8750cb61d69e3e8b533f1792506262376cd3b452dd8bc65dac42e75697976ddb1f083d554b7dd68cef6774cbc4d + +Input: be7e8e93ae33e329a9028a9faaad626c586ab01e6bd5bc6ea7050786f45a66fd21a904420aaf5107015eabc321dce3917da8c9d74814cde5cadddc7d94014d5a9e7f30d109956ed0be68e9bf88db79210ccf9dc2c5180483fa3ab3fe64866bfe1f14086baa6872dfee2b05589c92ef036ca6216aec13268b4fa4972ec2965cf1dee400f7933494260c6ec19d0b2e8a2e3b271813f0314b386105d8637e0ec8e789e653611fdd4d62cf8a262fd0328d43c1613932963586ad86986828320f2c0b6a9e02bf9bfd42059708019163c8fe1688b950c9ab6812a7f1c1deb414ae8be4aaf5c52d86f1da93610d2091b046cd609a81f51e5b4571d3d0f3172388827c7cf201624b59e77f223e15adf974b75892b9fa6af730dbe0720a3b955d9bfacbbb9e39891bb65d6ba845ded585ad6899e651521817fd320ca280c92b97c70ae64ea1c382feb320c89fc6543dc414c3 +SHA3-256: 611febc0e4d8b92ed1e9562fb493fcffba7a9887703c7cd57df9657b725c4b6f +SHA3-512: 8e352cca86bc3fa6256d9cb3668af6bac0e791b66d82018ef7c18b5e01496cd6d638281f7490529db2ebccf3179cf2815c9f0685ab2ec9a66b81b44d596a1d1b +SHAKE-128: ff7b104861e2fa4a7135cf8d4f65706dd00dd8062ba78dcc3a417757c47f2d67017e67181ac4a319bedb98704549218d78bbbd7c71a719c4e5941059d0ee70923e052a3f02272fde73ea2f1b7d2789175ae6aa63ee98b75678be432a7e1d89456e56265d4fbe4f0a931117da35f815a25ef7bb44c5e263ab70184dd1e36afeb5e150d7ac5176aa43b37db47a8aeeb3d4402e848ffdba1495d83dde57b673cd5a530cd7b735d46cb67a6d2e8df95b5bc2e6a1580317dd03019f5ea9b6943bc7cacc8bc54db8ab7f1339631cf10b3669c7fe35b6de3c3c67d0dc99366cbe908b51cbcfd7b875346a9cd6f5e7ebd8a2efe8910f9a979fe58df47e45c9ebb3c78f98c5b96a8bfef7a8142e98e78f57031cab96937003103a0364fd7550a61facf79b8a0f218413bc6b594f5cb006cb433c002451cc2917a827e6e8283dd3dcf7375ae8303b8173904194fbb6294c0e4899fc7686f16a1e0027c95a649905d31f3c4508f71b91b72ee0a32cdb1f5773c2042f39b209e4f79469a65e04505ee15852b899f40645377d90c9aab6a7637ec153e685db63b69b914524759aca3d2d3e6f4b725f293e22f79c04de6d53780d96fd4368bae0dd74152e7ad7e3dd3e9d58a5d4c782dc2fb371745d1a458d26cd9d9271d1111604d8f5d616ed4e7e3b58b2f900af7699127cca640beea28a19d11f60e1ddbbf1f65ed2423644e1826187a5b3a7 +SHAKE-256: 58b93d4752a53f308c45571c4655cb2c013e1642208f0a7ff6eadefb992ef4153631d02c123484bd86dfceeafc8718a36a8b72f2da23c6fbcd94707c72eafe32667716b72e480689a91f48ab1e20aa2811b4e5149f457d4d9fff79c452ccc52223599384bf1c28539149ed6af8865bc3cf8e137d68bed2d0089a0d0a85eb968e85f012c358bcc0575c1f28bca1449bd67f68e27367518eeed469d70cbb9facfec6a5e1197b1900aaceda1ac121acf9beeb6e38e4597165c26834a9919682edc543ddd414e21b358e07aa55b565fb76bb2adfe44c91e8a50da5ced0f61a7200e12e1ca5f3954c7fa508d9cdda4918bb5d6adf3c4db06764426ddecec431f2a04a685c5203b050830bdf9312650d94b2c730b2d4c02ab37f85dac727177187b1db9d6acf3a559dce2cf81ea6013174704bd53a9447ae9951ab919b7bd73f0ba22071b982e0ce5082007baa1f818f0c4869ee6a2a3319bf3a5403cabe0241c360cfe605e80f10023edcf13e206f7bdcb97722c5b0077b6a7786c01164fa17226377613d1f3edbbd46abc4b0023f0a5df66555331ac098ae0f89df9b33ffd9a3a60521f5028abac8002f0110c7f26f8f3fa594147d5b37c5268164c30e752befab2900c380d703314f28649142c43e173fe0f01c8fb33ff79653f63b17258dc363a2e76f54d359798575c6fa3478df4c1203547c92f21b1af903f61783e935c5c316 + +Input: 90d292ed54b063d1b606f02e330b185e3b59b97e0a3e49f0d78a66d927e5793e86921332d3cca0a4950d12d37ff6d472be4cbe50f01eb9395c333992c9c666a913cc752f0d8a59644f04f561826cc46a60a6b642c5550eab049029a62ca701beb96984b8687713ee0423e7aeb1d60e4571c7d78b58a94f474027f43943c00ca20b4d30291ead1bbdc720131af90add629aea2d75738bd7f16a9b14bb361bca3a415585071293df4bc8519b2324f5ce9253664e9db842d2af24b3a03494479107e77eecc00bd5941f00efc77f2035a47496837dda84f2f137e9e9e5126433c65cbf55a607216f8bdb0869b3e47f52df96a090f9255611297d7670210e94291f22300f0c3f6988c6d0819fd422931127cf166414c900150040e4685ac95606aa5698d66c3064ba1c501e32f6426649722cfa3e292508d73c269e2bc7ec67069600abdd5e5e922c2bb7d060f3a2701f7c +SHA3-256: 882816d458de6b518b20b38357c978482313345c9a4b15a5ac857aec73de2d94 +SHA3-512: 13d1f2a2c33416897a12a09754d21be97078a96e442cfcb1a0ecb4d54856f8a3f400b510d5a23d50bab154353fd20fdf16d4cd70d0e241d4f5418b7ac2c07cfc +SHAKE-128: 1a91f5ba5464187228ace9ab85604b601dc21604f4c7fbd6feaf8e40aa1e22241c875801c0dd24d1e942a994277df86c06e8b72013a1a35d30c850c3f28e8e1151a36f6bf9afbf8ee4997a50b28b6e0a17d705bf3106d2e25549b35a25523ebea2dc0eec4c8a2471e71b41e7ef224a836daeb2f95034dd97199e5ca03c62a7be05228ce67a800f3fd64a6fc38aeecd81b9784061e3f1742a455ae0554aa301f7d5c2c37ca56c8f36184c3847aeee0e6f7b0593bbc94a16f01d1bead64825e9bde2bed095ac48a4b48b91f509d9baeb851e07240781cb40e6cb160afff2800ed0912f64bdf90a9c3d8db9a3f457c64617fc0ca22d3beda6f56397bdda3a0bafbdb632e66596a33601022a3fad38ebafc1d7098df6250cebbeeac5c83e489edb38bde4dbd6a7c99f87c01e7d2067e36d6c76c3cfdbf334d5873ecf7b486f1e14d9b167627264105e6d5c115b7f5a95818915a6d92cab455a2555cc99d9f9a66b98979b282eb5a18622e5eb81e36c91cc8162a0ae90d4ae91178599c5216ec2a8731880b070c24899897e2f5459d7607c38e9df7f2ab5f1abb458d071057333d4259a2a03c2f75b14801f264caa7eadd86ccaccdfc275b66b7b7e7583866b1ac9f6c4f2018eb320f1ea1df77b0b79d66971cd87c8eb78b62bb6232d850ff4077422dc8aaf84c9c21acd7ec87a3dce87c97187f801d8adabf2946b2849f89c90ec59 +SHAKE-256: cdbc00ac59bb7f5a3debaf3a28842d0bed85287a4d835a179e84c32c9a04fb24f0cc018764850eb26838d00353cb7c94798d83b8cc97878dae9bbfe6690968bae614cf4094597ed25c622f926cda65557bca43fc2b11d5bdb1bc853a332d9837cb86d4334583010ad9610f87adb03634bed2077fc27ecdb2aababbfec0c71047455c50bad87aef23bd87616dbefed3af6c55fd73167baccf1cfaf8996d80b43068ec9902a085a34251d318f2302a8d0180115da333d1c82fbe7dfe33216443e8e8b5449f24bf6b788945a295ea03d4adbf2a313a72500f779666e5955a77004cc4b10179e70fb15bb9b51973568340dabcfef59f07917909e6b32b8be9be6ef8aef04f5bb1a36c25a41f9c44498eaa400a55e2f1d61791167c5ae21f762d905127cffe8a27cc3354564d7c48575e3d860113da9ed643fa7c85cab7a9f484919a82b5f61c520f2364652223902f8b2658673186548eb705639ed9bb21e8b3f5283839d958f570cc6f5c31507c3cac22177244f241235aaaf9383fda56bbf438c12ab31975ebfef8055f18c9d01866289fe5769beffcc5a6bf7ef943c3e7524bb8a6bc98964a8aa6d53c071f587759a93128c3c40dfeefdfccbd4e6f283bb98eacdcfa6f63ae214ac116ec5943b6105b878373703c62cba5777bbba3686459392be84dfc5f7dd8778d239879ea3d00181f83a5b6668d8d5492fd4f9d7c7fb00d80 + +Input: 95a6fbfe81a870d114546048f04f143c205511d36c7e85dfe8297e0777069e5c94b6b591456db0b07198546fc10e7ba44714bba7a2f43bf606491b6e2c61edd71d8cdcd035be76e8f11263100d6cee4109472226b08cec9d68e384f3d86b205466bbf1a95373a32e8665016c376bcd94dbcf1ab75195abbc08fd1d2971a0fdc4b70be9bd2a1b0f6eb283c277bcb6bf29a9d7252730b76dbbfab62854b24e1e2fae393da84050ff98184637c4772fe7dda52d7babc215297aa43ee155459b1500f1a56029e3769f93b72e20fe861e59411947ca0a44eaa91b413575f58312f4223380939cd742bbf346da7939338e0a3293e982e8b988c7995e1c3353efb2de93ba02d313e0d6f16e7624c98287631dcc130072944d79836a2f3cf4c95bedd81303b530cbda8914f168ed93f74a16a7ff3ab6df6cd354427203892dcf33098b8bb17a807fe14ac0e3946fefa9caaf9d09 +SHA3-256: 7ea96818cbcaff6e7f9a3307b1a051a16e1b4be242c0d7660f24c4a9dea4b5db +SHA3-512: f45b206fd2111bb8f9aa316d659d54f6a4d9b882527132a03938b6457888dc3ad7af4f838c9461c1a5b3004899f8b17ee58123cb9fffb8eed8e282b421ee1c00 +SHAKE-128: 35fb2070e824ffe85b5c52b49711e6324c4078ae11ae5c6af95c1ebe21f7726e72bb378c66fb1e6feb08254884f598a6a4fc2f5aa471efc26c3fd320e1b1ff6ab7da88384467003fb56799c783f512ff2069a9817b1f9067056481a053d0d199497e29e4d6e99592b1d9ff3970e16a47902565636f1d049b47bfe6c247f4d9636b41336feaa6983a737dd901617961f1cd4f3fe9af5d0b38716f9d9f5d2539755ea06cb5cb8737560ecb3526dbfce41a6fca9533fd26895d855a1df5351ed5d0b45df176f7eeaf5949362ec987cc13627bda9a89916571984acebb0329cd06bd92c4b1d453b3607c24c9136f50b404838b1815f9c6b700600d9078a9576b4494d9462016409754bc3bcd682068c169b1419a3ca86a15a000439ee7ecc7f5975f88935d139689654218e44b5957952c3f3a9d983ad06143dc3fad7c38d00a003556104623d89d9816b54a14ff2942f46b97203bb8be485bc967d774dee58c9fd295fec98867ebc45240daff66425e2b4cd671d2f0f6932bfdc9fba5f590fe56144f76f669903fcd79cd2e6b6dd5ffe3031716415a1226dd873429ec5a44f2af7af5a425ce8e729359c48a07a096b6d552747cb06fa1acb66afd69035f89a44a0bc846af2f208ab1a35d79af22f1894770e3516db7dc51587c8e1e216ec3e194e7828fae258330ca182250782d0d1d3061927bf78acfb4276c8b8bc8548f123d8d +SHAKE-256: 153deecfb74084cc75d54714ab2438a33d067e943f9df46cb868697d9dce1fab762427806d2a73aef78dee77e410bebe21d5669223e8c6d6ac209b8d17f81f4578fc1af7e94b7c29848b0d21d53589f9fba93b317a522a278856b6512c742579e59079c705c833d7f61561f1b5bed4bbc6cf0f0c28e1a59d5e93513f860adce944a9d060ea3eb1de4aacdf1e519a507cc9abb116f56af00d57fffd2bb480106e9347ca42c4bacfb5799b6c8219b4f158630834728e003337944831a5d04f6e11101a3461a32af2cc15dde808b100fec839759b569f412e77a095dcbc9825ff45861576e8ab1cd5f9dfb906296ad713259e67150a62b46182f3372e5ed16a4ad0551a344398f8fcae9268a95c6683e0b317aa6ac6648861f74366885ba05d8a546ecc219397148791925c603985d3aa911e221966dcdf2f53ac3379ed2f0d5a614d1143a2dd0ee6f1ff96fbc4cc89dcfacaa070186c21a1e3b570572ba4dd8bbfd38f2756266b95d22dd2fca8f9cf8ec4ab84fd3ebb4c97435934afc2a9237e7d86ee37741ea07adf3a2259a027c6d037d0d1a16d0c4405e9453b366b8b55b69be857329bcf3c4f694654398d4794c26e047f2f2ad1d5088b4067e1f42bacc5a28bc8de2fbc584ca17eea4a5f2464b3821fb69f1d70cbe4280f59bae8ea827cb2224330022a1e1ff153e36fcabdd43ac2acfef3f1b82bfad11f80d13d05e5bbba + +Input: c7a0713f693eb301685dbc245b22fb5eca34681d54909847f950b7fa45d42301f9d61b97d6a40cfea74b3b3f255f208068e87e8a18295f854aeacd264cfa7b3b495204075798b48ec1cb5c29211a77dfd75537efe03fc65267ee819eb0d766e72667d50c38764ab07ec67bdd21a9736a6bbe0cb9d5a8f87d73b0dee330ed8614e4f4955a408d490bf182d5eb6fbb5b041635769c40246a86272b85f5d64429b7067252643c7cb438e0a6bf4c0b5a1369879e2a27aa79ac660b524aed776f404b451faf1d3a32b2507fa34f875021e7ba96ed1c3a1130b91c553a3cd4080c725690e732fe8bb86db55b194197dc6d3276a6f1fec02b177b2414a769d87fbf4ea1fb2c3c597848d2d1e33aa5b4f55f8e33b37b0a28d963cbecffa41d2138db191411e7b6af9408ae59a77386e2581fc1e9b196a1505d82766b5bed1b1793f54af13fce56bb7d091076efd884270b18f9c144 +SHA3-256: d9fbdfd7c7c8eb34c094a5385e92fdaa230e017f7e9dcaf97ae4d08efba3dff1 +SHA3-512: d94d058cc3702832704ee2e258c2e9b19dd60654b53ab174249425aefae37233b358148da09bfb0a7fbd219b1df2f1aea55f66e9fb2f6d4c66c105823fc2029d +SHAKE-128: 74cf31f7b34ef2bebc394b8c0b8ceaa0498787dc455b7f8679a1cbed8fe3b45ef84e349e0becba371a0d18d32b6120a0492b37b4669add7b04e50f8e10b69e765cc6562662248c523ffc330e77d92754e92e204e3e5cfcc6c95c359dd5cad459be0b4b2d3dc6de446df55be27077276d1727b89f2cf3d6fd9fb1edd2328f15ef7d7e17c654f51d8b0f01731120fd66a669ae8216b32e861f5995e0ccf54d174b1ab71ca0dab30f217413e15c500541d409e9ec3c375c15c91b3ead06a16a64d8ce70ae7e0a8de82e51118243e5b02a9b5953bfd4f85f57eb4edf00eff6ed2a90a5265a0f5980e924711f77c61b80378c89ee1a944296a1efcf8029e8d35fb82c56ecb6646cd6709c57fc88288a3c1843167cfe61ec1a26b4c565240a3fdfa36ed8cc1c64c77c4e4640b938865c06973cff99b981baffafc112b4a3adebce1cf4d17a8bca9669756ff3f4e3a353cc383428894fe707c38c39823886e0db165f696ac78a3aef49fe655b08b51928c1bfec35da79ee7f8cbac35cd819335ed41b0000ea9388641900d8f973858292688af25402db491f32d0e97c20b4392523e6ee6ebf3ec65f80bf447c3a4dcf3735507fa5fdb2b741dd864ec4d25ac1a954e38b19141fd49445e5f9c1604a671a83c98aff842c69711eb4c7429dce2210005a844d2d364995a84e7ba4e6339e545cf073ec4713f5d9d1b59ee52c3bace58071f0 +SHAKE-256: 5452d3653a1e86c95efe73edbd75518aaa3887a68dbe2e3cbf13fbf44ea51ec58a9a273d3d53d4aec5096b599a56c0fb00faae80a3a08e16aaa98e72251f638360bc0793404d54be7375db7ea46494b8b073a204a2187d9cdef127992e936c6c60ef12152141c48eedcc421ff0daf26a85248c0c99e7f39d01c36df837ee40e086a9facdd3a04bfdddd45e681948e028efe31886cb86c7a155127cafbccc44b51f9522f6b5663c77d9e9489877aa840a2f649e535d07d103c0767b10618ac5efec3a2502640c5482915748c3aadc71c72974f41681de30722ba12cc20f11ca4217928b5f887f36cf073fe4076d65adda37abbbbbbc90b401a4e8c37163579b88831e77c8e43a301f95918ab70d1b2a7b80737c1eb9651321aaa9344e9184f125bc2792773fe397cc48dbf795b89c82e9ebd60a80b4367d63c16709622bb90484c84f9155b707e38906aed6522d4991e834ad89c446cdd0094a736419f3917ac91b0bd606042e8462fac53277f19a5eb425274466cb4e7e6cc3c540333267e16145d93d59046de08ded93b3662bb49446ab35c8d4cf236251ce4335be9bf7f57a3ed4bdb736289b5e30f4cc4e33dafb7ac113534fe8b68df69c5a5b092572481cf1ae758972494f1f2702f475c375cd91c7ee589e1cf4a32199e7653cd2191b3ba4a69ef5d82d265faf03ed8d0b26b794365cc4d6c5c14c99aa5b4630806a89a0 + +Input: 7794f72543ac73011f9e65ba1a4330643ceaa90bcb5cdbbd9d3770d05250fa82c982ad38c33bae338c7e34d813934fad5dc5fc626eebc149ac95ca5ae7e2320cbd41227e2ce010096d1c00764955e029ccc2665997b1b5b3a39ef90400766c2b4b3b42c9952fcff6471445328f1404dc05c021896f5dc59b71eefdc593e62f9066f3b2247e88cafec228d49c111fffbc8162f9f3528a7ac4101a7eaa117f247f8a564b91c85126619795c781ce0496a17ffd04b8db0cb579c7e60cc590619ddfe6c113a129df815697498c9c6f753549a795858cee7f46b1064eff5a53a15dcdbc3cdfc457968070988382b56c4570f6f761f56d2576c270eb2eeab5f9727fd60ebf48850a1206da02c0624c519e472b6cb139431167fe6d6fddfb517ce84de1e5991bc697a2bd2da3beb037884d3f48ce130eeef37f8b857fb32003683ee25d51a8cc88a14b2a270eee8611e0ebe687aea1 +SHA3-256: 54b41aab4506ebf41442c4413ecae5719f2b9e6c1eeb6d31104ce96935c84cd4 +SHA3-512: 565008baa6f93bfa782a23c0b29572429a569e4fa4c9c909d400253b6e6de47d35f0065330a25722127933a2183b42389081c576e823088d9dcaec91e0ca0781 +SHAKE-128: 1243c718671c6908324b8d30894b8f2730f9f060f17472ffdea4ad2da52f8fdcff08670cf45180caa8719b474d2c5d4b201df9768537684a5a6b5d1eab5eb710ea7c169d8c82ab7f54219e5ad1c5350abc98d2a21c6af0514ac28bea776f97c4015d2fc8440be3a7d4f9a8cdbeb74926ae7b3464e0d72292f88e15c6006ffb42bbc3b858a7e7e8f20cce405d75ae42a94a2cf12bd3af4dbbc87d0be235e87cf5c6a6f0216b82bd75e66ec46b1a6c8bf07431485523d8f95e590845f4f8a7ecc977c4f25733189d0e03a7ef77c1255e2bf82753773742501ee2256c14992aba8fba7b417db7f12faf719ac23271f0c3c719fdceae827de3867b87d61a36d5cc1617bb4fb77714fc4a74e7a271256d33bcb0c32a8514a163ad093a996497f5333daf23980db72eacfda73a763ddfb5b1efb621c0553382e54220c61a3e6d8eed9cfa850d8791e3883101ccfeccf24ad26fbfc98b608b79685a8d2ddb81d6fbe823458d79798e69f2336ce9b8e2f03ef7f5b98e31a26c1d03aa35e264d199de5c2701040fe01ffb3b766956afec1e8114432c463656f8c35ba6da9c5c4fce14be134ecf5522482045016341cc57e4ee85a03fc48a9ce78c29c28435455b2a7eb55d9810fea1dd783898c786a1bd38b2cd7602e712ce221558a749bc707c28a912eb8f16d672c07a125dc46999a046d1db6a83202919cb9bc4176437498514c2170a +SHAKE-256: fcbe62a68cf8b5dd36068152fbc6625d14f825fb3f2a4aa863ebb216d1cb384f6e560907edbd30586d90de49f97a6aab13424b0d78c34c307932aac6c8b0e2870c1bb2055e583d7e1cf8c5fa8704bf81aef81ccf0b236322cf6e9fd81afc55747199446aa2ede7cb9572a516a92b81e149868dec06c2803e93dd9b68d8c4f64d969fa77ac2985b6ee0411c2caf19753e10ff44293dbdb7ab03a6681927759c553c477fc0e0dacbff82dd1a2c8efff1d90e5297d95717d590595070ddb61855e9531a4797d600a735fbb4401e7400cf5b16c179a57190e295d59ad541d22ac993624f6c477cb4de764c7a921b71e35c0350227d5425613d9bda3ee35045cc3b7ad7d0131ee96e277668566a60b55709f063dace907db8bdb75560c61e7186ec9e5e6f0fb672a904510bc178f84251cf372ea26f25d5d4b979c22eccba9e6d45feb38f7762706abfd15b6fb45f05cb72e0f2556dd10598d65e75be6089c1fa1ab2f17c379e49de8429c34186284e3abeb0482b5681e441423416e84db3f7e2fc881fa491733906bdcf891aad460db85eefe3b3782a803c6269675951661060673ca2dea5d1ea9eab42d10822410f6e7ad0246ca195c167bba159bea2f1703484acd05b88e41534a572dec23e112be55ee5f6fa657bc391b4947415bd3cc2fdeec39d9db2722699b531494ee3d6f61af6b3a8ac5bfbe4281eca6e97d3948f35eb3a + +Input: fb7b0094f50c281b81a2651e6c66c915dc467e179ad5670981cbf1db39dbb1beb62450106db2c0f472369fc8ddbc0322625ab4771d7f702b0c8b641c7538692c631f1037aabe1f74c25ecdde0702c9723130c624fc2d11ec5bd04680f950a9747c2709e685814a9b8fa28c256f1a2df6120c0fb08c08716bd53454390b9e3e90c28bfa0fd4fa69bf5e61a9249ea265d365905b797c104bc3e829d5fcd3197d62a389ba0cbadab422f5d2c32e9b61ba9147143925f668dad1477e1bcb7ac7d48f1cee162e53965b5623ffaa97b180deb0a274be11cdf59e7bc25377ece1811322d2943626ae4cb9a7ef303e59fa98593a30d1759e84c2f7ba0cc374dd46208b42e9f1264923ad2199a85a2766a9a0c14a5929d337b5f59e1bd4a87f477922db0eade993889f1b8ca64f570b29438db7f4cd385de432c038bb8622111e6da91ae2a24cb84044c54c68d19ce2cb083df06561274a +SHA3-256: cde2fff0d26c119b17be046fb7b34a89effd445d6c6dcd072e040609805e3a0a +SHA3-512: 534be649085cf9fa56c0a6407aa8cbc75163695ec693c871560bdf365c2ca37f82ea543d5f504f7b696a8f4330b739d14bba2321b18bc3b4835305301bc2c559 +SHAKE-128: 61c0fdcb6c331b110e8ab65fb664a7f3080a031251b1bfbc2648603c1368f6ca36a999a3b328a260b4295cbdf995747fe7a696474d8a241fd76b535e538ea1d1f98e92d7175a8b6983a6aaa3ea9304eecc60b111871c8a4dc1ad0df6f4c7ec8b2501b7b206265bb367466a161b2524dc39d5097df8ac84d74566e3059dc64c945baef1f358fb4e391674cc6008e966536d4add5a5e34a967101720471a1b87b18386aed4c633e46e6d3e6c123e9a8e3d860d6063cf0856073fedd29d502f983c502bc3fce558d0c62b15960ddf43aaad8cb7a6c8abc28cefa32e56f2550513fb6139176fb7446281a01c4f14eb3a80be9002410af6447f8e88c1c3f58f9e9682baa441977bcd3b78e070046fd5fd161f52eb3294d379fddce657ec4cf61d4aa6d55b956a84624a027d1e18b3d5259a1a8710f0ae65255f909640605e0bf91ab2f747f1db1a38bca9979a525f54ddbc0f8dbcf6660c654401476a5a5bbf63f3e800eabfea871b56f57df6324431c96bf970da44ce24c29cbfecea256c430937e6d8786e3cbdb2bc7e4660640a71577c0bfea1de1528ab0fd757c4dedc2dad94dbd056f1b3f09a40fd9d041b9e7a94776908c12527c9cde1a4db520bb49cfa8f17cb8535582303083e2ed85064ffb9f90d878c64824c6c145bbafac8886147d50b9125adb7592dbf646d8e74e38c38e5ac6807dbeb93690af629777d22007eaae7 +SHAKE-256: 94e9f65be1266f0a6c4b98dfbf9f9a960a792bf570e500a7184c6bc78385b1cbae8eec915eb9bfc319109b8f378f01e06ad1ed7999580f813957a157fec005e95099c5bd8a0ee0bda386188cfb0fa4f12473b45a5721ef285f608a47d667e08888d245638cf2f8f88d668f50b9d41da8f085802d1d31881b725205f73ce31029593d96d875bd00e5d981bf559e44fda90b16d49c7f5ce18baf605666667e813bbf0fdd0d26ea1a6d6f490ae213392c443290122c36471045399650266ecc90b57e8704259834e92ebedef651393bb9087b3439445eda22649bf9f74307649935822c3bc246090b539a50f1f4f46bdb5c480bec961dd6781f2d7ef8ec71299d89d87fa61798f491ff6699014ef3166f592932c3eaaf979774da00170c2a90d7bd2ac132678a46ebbe6d96f7329d51109bee6aa76121d5f3a1348d1cc81aa972c19ae914c7c0de62f3673a22ef6080afca08691f5e5e3c84e6e6bf1aed01dea503e857bf8cfa006e672d7f866c7af7b7d2d9ed51f1db40b90b62a25ecbc27b1174fe5eff37fd8544b8ec3d63bcbb862ec1bd7a77116ef5ee433a1448e6649b8b580b06d5a1675608fb5b89e4495e7175881a5aed0e3c4869db2e04076258b3a7aed5a529dba5420054213b355afc7cf0a3f39b0aa3bd2329d81961fe6921ca02dd68494d57ca5a51ab849230486368594f64a253c1bd2f0e0911031c15d4fcc3ee + +Input: af4291ff05cd1dbe1b80cf378325d5c62a53872ade8480a991c641b3076d291fd46f34349045f606d40769cd10e113d4c7583a8c12000110ba91945ee6805df957ef782565f313a299eff9c7a780666c9c42551af910f68c24beee6e74a8bfed6706584a73a482b54ebab1dba45c742e1af40dc296b7eba66278f853f081452284e29183dd1bc4efaf07d1dd9676344c72cbfa4be91dd22fa88f6befb96756b750718f22f74e9ba996b3dba0f7889be697e34d098183cdc7aec1fcc3d6f6600089bf290d6ddfbb59d3b4443a85a6970df51a6e2a4374f90a54d7f99e6df4663cc7de789149d5aae272203e0819a28b43099035638a080ae2938c7fa8700680bcc72c8360b7288b131fa04e87f5feb07ebb254a17f0fce26cc3d191cf1457e7e50d09b4143f652b1e69aab0f1257e5d9155b2959bda4692f2ff8ee8c9ce0eaa6d4044afac2ee01137fcd4903adb21597d2fd17012 +SHA3-256: 577065e0783e4bb3328af3ff6241da6d88ad94b43906081d518c67ff4fa5b70b +SHA3-512: 7bf542c6d00529907e5d789ad098d166a0d15fb5c46d7913314e30c2ffa968f9edb2c7d140caaa4ccf22f5e5915e6021831740b4aa45b39ed6abe8e38518e73e +SHAKE-128: dd9964cc58d88c6cf3889833af45d068f4f940a7e75ea7c3b976e642a21010ec73b6d8b0cb9950988265ba0556e13090bc578add588b79e4651183dbaa92695b3d3023c6590ad019afb07a72d33b0358f88b3eb460b9927e935a2a211b6a0ab2cb700c3a66be415d03b7babbb3642cf9ad4e0421092fd7d8e435f30f781dba9af30e76735d116de9fc96d7db1c03e8bc8dbb1de50986a396c62b4914287adf0000b652a0bb9e7aa82add02e9b9bd57c202791b44b1348d05bcf99c89a04b1c31a6ca1a24e59721596551362076407ae8cfb37fc860ad7374792d892e41fe590fdfef40e693b2cb9235973ebe2c71d57672e177eef20a7e60852f77cf00e37c7af070e2a00aa9188e833205cfae4507980066aecef01c53a0e80c070f5d1e84802db4565c03f8afd3b1d2d91803ae995019b16aac2d7fb108a9ecba8626be6bfa4e9fe77586e12558a22c8398075035a6f758d449b44d44f6a7f85c9a881fe93078726f5cd3098268e506838f0112cca4ae455ba209704510a8f02cec7f970470c220425720f19d225b5182665e40330a2351647ef9728f0af679bbce0cf81825676b4dabbf8ae95756af1909feb0e813478f56f5f40c8314629ad29f86fe9dad63cc9b0dfc8bfde915b2f91768fe3dae7a46bd6495433ed4394a85507d70b0bdd0cccc569e130134ea598c1c32247b2eea2fc799e24b228729a1c1354e0ff2d7 +SHAKE-256: be08144a3fabd93c6262924da03b1866a5751560af0eb21501fff4423bf9a5e94de42b9eb95eccab1169c88430ea9f60f05fa2b81c277cffcec815462990baf5266e64cc93b02b167941ee5ede5e507de05f3ba58508e47bb7c6260ffa089bc7b5ede76dc389f731585dad489a6f805597365acdfcb03a1b119559ebc1543233172ede172e3ae91d76bb65a72beb8cb75768f4e2f40eae585b677c3c24812f7176e508be999d038615e3d01706b9e6341618e574b4c453f9f2ff64a59425ebbb617aa5361aa4b2b50704051b69934de8f016cc6de064f4567c38dc20ee24b9948aa1a20eb57ce0b01876bba3037c325ce9e8d472a977026660087ee44019f2e9f93c9c139f855f2e72f58f8b4b03a441e6f8c731af826185a837c4690cba2871cc284a1098d296715dc1fc3144cb30d3f4fba2f54e12b38345695d822465da406ece9a0d0e35db02493c55831e7938cacc1864f78102f0794548156d70cca48bf7eb831cfdc4cdd4f43ac1c5f13d8516c5de5c2f3677686e5b598f448721cb7e301096c0014e5e57bc2db3d4676f9ce366e2c57ceb3beac22b59606610caf134f84a8e5f4c83d3e591bbde4e7ff03c045b883b035a7b003eb8b586cb06ca070dc67b0d3266235a4eacb76211f383551564d143fc142010ba8364f354fbfac8b24edc7355a6410059cfb2eb16c3022406a8a9c2b95d7e6e1df42abe50900e3ba4 + +Input: b927f3edddc9724152a3419828b43eea97fe0f7a523db33e217c5cc898c1b48979ac36a97d9d0f3feaeaf776252377a0f9e1e3460581442a23b737dc36acf704ae098d02a32e021e0379abe4056cf3630d97c95e457f00b334f4e1f90dbb3cf6aaca8cbf865cdafc4a8de021017477fac4f09813e553a8d853b4c86dfdbacc2c955051148248e06ce9b48c8259c4d747b094cccc28142d7668c69e88844a0f45ac6cda78d5a3ed8432ccff2e2c944067318e7d21af0ab4115a62a5cc89183f1088ea4d15024ea93629e3bcad347be8e1691aaa76c52f9c0582eb71ef8d6eee2bf03987c5725e58b4ec0ec91823019815c61309de1b30c64f8cdc0092224c395fc827657be3f48647acb2c4423e58b9f9c985f62decce7f19f7bb67e737ac88ad513dba8f876df1b6a6f9ab6b34fb8b5438bee59cc9342473ae35063978d008a8a90d3b04d35ebf5db7da5e990b88156db3d5b10e37 +SHA3-256: 87f9b8463964bfc3a30ad91ec1c8858dd356a1cb9d8c14e2b71da6f9eb599d40 +SHA3-512: c37aa982b40c25a6f0082ebcbb88bb7a3ed098c3697d4efb7623260417e4a84025f9905189b36b69081646fa89c6b9168e89e1f2a25d123f77b4ac163f5dcc0c +SHAKE-128: 391deae3b6da5ffd593319a700e2e517fe6b6a690c5f1739f18b9f39244118cddf02bdb8cf27c6125015facfe5118fd32bdefdbfd7b572e0e59a842a05a75da0b84265fce402a7f34c0e8e951793e9fa7d9616252f45897c4c264ba8acd7ffa54fb0802926f331899c18e9dbde6122fb441636fb63ad25d275f8aa2a4b84e62e2ccc60f3c3a11db2e1aa2d63a249907701795e49d82b3983dac7ddc5cddc567e421091a6715b1a8d763b964a7f2c1566392fdf44d00f59a5902d13b62605e75a1c9ba8559c1bed7500870ef4dd0b35678fcb932e2063052dc6c6c4b512e9c0815ff7e184add20103776d8cb67e1a208022e357e7caa5a88fc1f041294c160a9d4bb418872f6f9dec402071d4b19051a30459ce1f8ef768cf5190682d12b83af766a69812872ffd326afd7152a0f794b55b173d12111bb609c0a40b30447050dec34cc6adb6c1513268f7c466bf8610c5c4737a2b54c92404a6cc36475fa3b0da139e67b840b5ce46eac7c21dcac6f6926af5cbae75a6c3babdfb7e0b4109d893a01a99cbd518bfaf14eb90122cdfa51d573e33c39720e9c5e5fa6c7853750bcec32f2ab87c6303f417a320b41d1bb1db1b663778de06cf7c72e00e42b2229df4ec14b79167e69c78027f0f861904aef240f5e47ea4742249b4784818075ad464df562d12df5003b8a53a2aabcca2936db08e17c5351590aca4af1f961abb1317 +SHAKE-256: 220ff2fd6589543431cc7f5120e94e9d1f59368b6eba1893b6f737d63fcf264739628a403cea4fad44466f75bbc3b60b218d3a65f2cc821281ba090adeb2699275bb699521ba298f53a16193be9d55e7f12105d17e403bdada98086c37ba2be92c33032745403104c3b52c7da70b6700b5274f42ac392404a6d1c3729f64c88a608f129480dcf7f784d1b83f0b832b975b34109fa1edda8b70f4acf38b6cd307e2bb6de8d16351400a98038c4b36f6487454a5b0c6c2d7796f432021c345f41c77407d515e103cc777f6be9769fa33b9901e0b4e951e64008317ec7207aef10c240f36fb6b466a953f8d208f470fed19206dd02af12c4fe996b25f47b69689f3397b25e8fb5adf220cabcb4f0de96446995fb7834cc6ea390f3ee8996d7cd156171adce25bcc8de56dcaea7bc551ac40b1277ae94a27717b1f0c42048c26f902f604f2d9e1b6efae38c135474cd89789f1e46e595ff3af2c2c075b52a6e09f19b0db9afce4431f99046f69137ad1e21642fb425596ca5e17c5a4dc0d43db7878873868ee9ad0ee9eff229302965c215c539cb2045f9fe2e16a5912e20ecd9a9e51e97cf9caf238104b037398009726331467f1290c746f7b5361ed6a439fb8572dc3ad893dfed025e977c482f2888e59b312754cdc74213b0aae29608f06bfd6ea397c254cefb4dff4b21942ca5d7bacf867e4bf0cbf3eebd3bc0842e4904cf9 + +Input: a0d634a847faa5539ba5d8a6fbaa9bb08764a7ed9867f25593032b1318757a5a69e53e412c3d3b600728df9de025a0d07317c40fde0df05c7ae67a98e3623540aa49c07a7afe070be3d3e5ecf59a4ff04a06696ea79c231eb7d9f89a66b2d180c5cb7afec32a7c4911d8e9992ab89f443548acc2b6fbcd96fce368be49cdac2eb66d2ceaf5e44895d494e30a452d83efbdb33dc983c109972a612b861f03678a1b3a4b33e2dbd6eae1c60641daac3b68589330efa1f0476bb886c04f7766c2ed2f49a9d6951f0feb6b2c6c09f91f8950dc622d821b235d6460cda6ad1b8ae87da7e2ec32f1d750ccb5013a424514271eb92d0bc91ec86533abb422a0701ca829fc04cf6a35dd961f40bc3f1ff24de6912acaf9cf8fcc533f6c8a1919be011f50f5610f7410a794628b2cd96001e124aa0ccb405996ac5c7224e7b11c9da82807d534f7cac2743e467490ba697b3a975d25f1b869e099 +SHA3-256: 410227df0e70469fa7cd6c1c154e49eed3237fe0fbee7337c02ad9f1d92d3932 +SHA3-512: 8a450f2b8647e89f59717b45748c5858ddd1f33575940d561ae812feeb3e7577b973e2f330731f22b631d410602070fcff7ea5cd94c10df2d3986b878ac2fdbf +SHAKE-128: 04e575cc692a2177232b99ddc65824cbd21b5edab084cc054292800a02bc94ed420c0231aa9e9ef911e3df2a37ce201e120bec879785da304975bcdcd6f44675cee82f58b97eb2198d5b299df7f7e6e1cfc95034a844080a6980c0bb0f3bebf355af30b7366c7e52b3ba93b335cf6162493e7e071866a95fbc7fd4229d2b03f22d47c75c23d94b18cd939f2f96a542bca08deeaed2b7fe25d7f3bdf62914ba2f920701ceadc111f9b310a551256f927048393ce57e60fcd880850f8ef2f93e4c6e348f335967de41c31ba4183acb4dcc18f606ad22d6889375fe614e8f8a7c35896f2997812440f6075ab0c8ea28c6420f5bb55770ba56f29fb4841129ffe5e589bde701d5e93c5c7a79c8a2762d1436191c7c59518ec67bcb52190dd4ea5fb5d42d0260e67cfa9e35066447f5a91c8c9106d5a1e78323c34714263fc051ae2488a316b4bd2e2871c30f7e5ec7261d6ee244473f296bd12e62008e6aaf0b97fac882a3ecd44a31c126d10310b4d7218132b823fd6c439f1a84958f2f5a51f7f233b45dced977de853a00f31418db6996cbf29acd2c16744975092dd3302ba26b4660ae46ae1cf65b59f765ab3bd5322ca678493df56a5d8552838e164af681004d1fb4615ca57d0c7326d48e0c025b830c0a8c536657f517fb28cacea09c020f3e34d7b5634f8710e59bb917fccf75d6e2de1f892f1a2c7f92936193dda48474 +SHAKE-256: 0415c21f8079a4a81bd64a78d1306dc682bed6af53fa431fc44db1097024a503dc2f2f842595ee6fda2ab47d26aedad809bb7a8787cb5c7e999ccbc6ff1b0087707eb01a567b357384971e62a350cf6facf6fee335e3b999c36ecb4f9130d9534000b6dc6da3addb8f4e93fa4f09429b52689ed83aed9d46df0c2202c39a6520784132c02e6e5333541e1a16e0462a8ec257e0428fcc9fb4347a24ac7c10b6db1ad1e08c32e5519a170cbb78c25dcd0e21b3423c1268ce39055a79ddd7ed9fb63066fa160034461554b349276ae667851a8cd9e322be5da4eddbc1a312679076c46c19ad2c9399026479ac11a589da2b33ecf073121c1e2aec87baa6824e443183da038e3039beb3beccc33f3cdef375990f7896693b8e7508ce68c2ba8d0de867151fdf9af940f5a35e10dbaf41a8b7f66157206d474938b66bb80939872497aa52686f48bb189754039f68881f965834050f971b24d7e11b6a050eaea4bd7dadb8aca75d0e88ed6545cb645674e7f0dbb542a65086cf09cc76e44b36fe3736b07cf796159965e2825a99bd7fd709cc232696c4a9c8b4a74650537429ef13d7712d6bb3209f822d7a7849508e339f3f4fa57855f970fa01b0c58a3f50ceeb7473dd829d5badee3e9b0c6f8ff3c7a2605bd663d43cf80a236caf245eaa43676342de7561e22fb9b40cc9de41ed6aafbc3b6fdc807ea481ab7a14b9440cfb991a + +Input: f121fe4fe376ce93491f66c13ef89f95a247363033e055bc49c371a3e5ebc3108177457b06c095cc6b09768133e9659bf11e21bae40a1716620fbbb612e912efc24d2cfcdacdb4bd5d199ca040967ead8d5e816b5f71d9428b613a2fa870e6356a6fb201cfae0b3e1116e88317a35da80739c6f9f1f07b9ebacbe5c6cfa8f1f94fcb696bd8c8cd45989b66b4e61cab86a5f2fb106deae2b526ba0f2fbad01b456ff543f48c4639875eaaa287b5f0d6f963a1e312f66f3188f8f43bb983af0467422421c96d6806f1b188af1336813d44b595d91dadc013f891dca69b390374ed76be354fa46179786e95aedb549feb89aff468f0603e8d3ca50972e1f5d5065d1ef79d511d82df0c740adb9ce419713e561b6c4a7b3fa94b72234fd194c2db42a7a10e68cbd2de23fa9c1bf94aa5e477f1a2489b67cb2dcb4cbfab465e8a3e0a1d0b3ea742377308e347a840a036bca7861b7cd5b37732 +SHA3-256: 6818a2f2f72fc5737806eadee03f9ee133dfa6d0ce8bc8d4c9def4d73422eaae +SHA3-512: ec7b479dabc10c94e0c0722b5004163f0efd15359aa1f2d56bff4b7e5e8a2f1808f974e4de24029439a3c8b99e99ea1dd92dc2d1d8c32a7f6fc416edf2fe5cd7 +SHAKE-128: 8ef9e9b8dad444121b088b27cbaf83999bb232f406049a39c4a4fd3481d7458c370e211cdafeb74a688fc613f62291c598626cb7f477040d2f375fac6eced66c2e7bae633f0ffc3a18ceb32416790873a8a34bbe4761bc40d44e69125361de9e5b396d35f6809b52bb643f8a010d8b8591fd3a0405d052f8a0484165ef5c81837ca44941e4f3f0d820b1b44ed8a628630ddf7c15ca49347ec8309d49cd9f9dd4ec63bf97aed04111fa50286ed897587338613d5ab88c6a8f4f474a5453eb092ae279685fbf4f52fb68abd005bf0586e1a2edec09ea7e70cd4006b02c6256a00d47b7f644dc8a591d8731d77fa116b0045cccc247496b687309334b35db7a905f2ecc67001081d76708ab8ebfcdecbf1a8c77a64e4bf9ffcf6d19f4ea9200ff19193f8aecdb73c2a11fe6da875a3e14d2e3b44566cbeaad3d1f2eef16eb0b168103b30306f0fbaeb942eb67182723a333bfd05dfc2a2994ed42c9a39eaffa210f7d2bb46425881687b08733310b4dad5a3244f4cf29a13497ee6a8913f901756bddd1f4f0193df644a99052c7d14f32a94558f10d4979493cdea21021ec930118119ea3e122b34e7ecdab755c34a690f7f77b3bc6f2f03552a8fb66bd794d617ce00e0f0675394718d60e80e9fca97d2b22b66fce6a7ee94dc25478477a2bd914d5d3789d8c99d98ef6480d82939465f2ab0b5d69d13e9e58361d3a078d4d23ee +SHAKE-256: 0f290efd94d212b9e9368840055cf65f235554ae86c848d926f6e133a84d672f180d4ccb2652d34484a018ab9b6861d13e663c45ca139daca7869599765b0ca5c6960bab022f81ab316dc98b00a1636c240ea4a40bc9924a187e7bdd99624b72fbc1b2c194fa8a54f83116b41732c1c75ec51947cbddc5bd0d6c787d0bb29879794cbd0f1d59b19075adf47e2c877c3c3786d86b66d2509f71f1585597b37c8949434642694313f3bc7c0f90732662e62bd73663848c274403f55862acb3eef31a5e13d8b73aee88686a2d4c8bf4c40b5e8c08cf7d04ff157b133e63a7097ae6c38fd470d698eb326b8290d6cad0e6d7e26d28d75a59e4336892c5a3661f08fb3549949854a0e48b0582695d16fec512a74257b5f49b1e8f57c414685d495528b50674605d65cb22515d545964c810318cf2aaf591f6edbd5937927f1acc7e7b1522eee7178963ce0b49fab472b039f5668d7c3e5327bf5395991c777a77485176ce414aa307aab79817f26bec5f71bb874e54842597f347d0801bd90463bd27b45bb3763678b06a6016e6b0b1b37990f68e71d6a3173ff5f7927b4d2822d82a372e1544c019683cdbf13a78a71cf87e9c388ee22a5ddbca42187951ae886786b76a2139c8ccc39ecbf7a7c185926828dd5edfa72739dd0d796e2f04bf1c0e98a4908501ea612393ee9bb88fcdbbddc2661bdbce17c84ac5a398b79fa100e350 + +Input: cc1b0b75acf83c3c8f8085f81bcb986ad336d5295b599490180e0bb8deacd47c990a65e698830348aa42727e5dbf7f7162bb4d31b4fa3331b111ed278d3c59d3f669d646ca7e419393e856b1bd13bf8cd7695d45ef410b69bd53d3f1179510d1b3fa207f31b2f35e1354ccf2072669e030cc8d57a2937c3dffc29fa4452fd99cb149573d7a821a67d748b8428cdad11c9599f493860abbb50bf86594c1b51b5d8ad9864a154220fbfdf063eaae765a98851d38c22e645dedd58d9c2753e47812110a375a07786f4a3c1d81f36bb2e9d176aaef75cb6c2179474ce64f06090047dc41ff58feab7af81b06ad73afcec22dea22d3ec706ac3cf4a47d089db6130f0b05893e5347759f082d8e026652f2cd5813446bbf502b8a6ec0f4db255006ab9cd7a659dfa33f370805667bc2cfa690a0b868e3751731c9c45963f510b6f53121d2df953e21d8d9dc65d5a7b090815117f902cf0e593e152 +SHA3-256: e12f07905f5b8504c566dabe6ba77b117a437a2753fc77bca439adf622d923e1 +SHA3-512: 94588ce33c8a3c769c1895a2edd627e1b07d4dcda1c7a6ff677a994c265c690f5acc6fff57ec75cb5f688fa0ea99bc6057c3ff9a2b91185558fbba9b731cb9ed +SHAKE-128: 95481d3c6846424774cd3788cbd2ff4cf0168d32e496044a1ece2438c3440c4c190794a9428403f672ad66184c806a6e6d9489844121c13785f72aa7c4e1b6a9d0bfe281d9f4fba252fd9fd106988b89ddd913934bf44fd38576b97daedfe6427f3a8e1d568b488a85a60c248e10e4b135175db98f1bb297d11fed7aa7c532c443f6abd1cc42455a51466b6cd2a3a70b0a66e0050254f3639eb2c18562052fc8d2b3b1c0ad06c5428b8743343768e31451790e8facefcd6cef67e38aa9cb58c787e1709f6a48b7bc9e8f891b2ce20448442dff774b61d41541c7e99176a0b585f7d4b0e719e148eddf3fab19640f0fb4f86e04649364304ee1e232301864679c0121a6f1e9909c42a568b6a142b2b53c4b43b6e72189ddbdfdbc475b005e992287118058b949aa76a55d6e28b6cff834bfb65c913b98cec5667480edae4c087f0e21ff6ced1e3f5fee96c9e1418010471f3d66f28e5001f6ac33855e75466501cebcd602955b8b35a583e4a671f81d19ec9691f6fdfd1ffb9c86d7d153b0a1b7700df4fa5edcf2b3fa56a8e472606b62dca396c6d9e50fe3fcbce2543488cbd52ee61d8047b7072df428e6f0e27e472ba4bcd9f857fc21ab694ec1cd4ea1dd61f9bb3cf4b118a8c5aec6eb19aa0e3157803cd9a04d0b59eeae97dfa09997432baad9b5fd91d7c4f128fc0825e7c8a289e01b190ca63350cc12ddc2e89c61db15 +SHAKE-256: 33830802b3bc62b49ecd126d89a6098b4aa7dbd87acb98ccece093d279f5a148b23ebcfe1f7842bfc1708a0572f014872a1c1d63601dd9043057f3145c7f62b9cfa3c7a2c12d23f93dab722d1d9a3881e6cd588b6e5303e375bf5561d2048111f4d27eaf38ae572bbac4aa707ce66335c5085b553346beac077f79c97310c6e70f8e019e8a35ae9b55c2060f2e1b0b3a51691833f9e396526f8d3861e21ec4aec7340350eadd0d754b577c790e03452ff1e86908cba523273c5ec7b0f9337c8d0a5f1075aa24249fd6a253681fdc472fdd14d78e5dc33b95881507cdf3ff2b2d2bb0ef8828457d22d3b3656390b7db27814068820f5b51100ed11acf643a943242a19eea8d57cca19cb67f1fe5463660c1178852e676d2283528906798b5cedf23c063cc135d67362f46d05c7ea46787eb5a280ddfed3a23f2c51a3787a504ee9bd70e11e9bd0d7db3bc9eb0938b8d4798b335d8b1ae1d21c8a6b1a4c676c0a0f017332e7b40ec5118edff781c5f6bd67d2cc2f3f1fd71b51f2aa52bf8881fb96662b82f938cc5f8083697c67fd959c21fdaa2e1b918fe281ad6de128f97db2c3376972453ac96d1d79bbed9262c1bded2c16dbd35bc150603fe3d668cc416730375f71945e95f20b29aa569648e41dc156ee555a5a5e33fffe340733d1eab6758cef9ebcbaa0e55dd8452708d4505127ef04940a77a54f55620c1000c86d00e + +Input: 125cd8bee8999a8cebbd56d484cfef419c45f0be7a2a8cec88be1eecc4fe3e8e8c03f44568f77b685711a5524bf51e36c960ca3410e0dbc480c0e337c5641d7de1a980b4cb7a0bf5583481d1956aa9b1400576f63db36fb680c40b48c5ae20b46e9d53e02d6d04ae6927cab02d288d2adf0eeacbb20d2a04b9755f2a7832915175a4d9d173c7b559c0456e3f8325a73371798b5fcd38e549b3a314a88a72679913da5fdc33584f1c98200c378d2c36b12bdfc7a41a10e18c80288f9b2984b187221a6464416dbcaad066bb42ce2238fece8207e73600497c4d5f09d576e3c1a0143b6f09798063b0ef62be972a7cc830d64fd8296f86b4078bcd192a418c7b26a6ecfd4c10cd52f28f160b38180c9ea664ffc97510cbbda56606b909206a351ebb91622213c6fd8accdb594ff08abb8477bc3d309e1ea938d964a9669ff2a3d3cbeeed786a89784670524dbbc52feb8c5a097bdf57dc558985 +SHA3-256: b9b22675b1335cb5c2ac6d544d4bdf3f7badc3030f1d851625c3e2a61323ee5d +SHA3-512: d672cfd599b708760aa020015ec70bd5fb9d1887b1644d9b6a41234025362388613b3cf712f8df244ab574cb4912e7aeb7086cd8dd9ed29280f1f84cf2fb7739 +SHAKE-128: 9be70a6fda7c801fd98a965b96db2d41d8db3bed27c2fe62585219921bf92b371a0d3d658c609f4f307ccb72fa647213b847fed8a098cceee08dc4781cfa3a8933af123645e2a90eecd7b7fb6c49e8ca712d98c1ea1286edd40ad72a709255ef5dbebad715aa2c34536ea7e5db974ab20d8a57e6e4a3a5d73ce5e950c094506e5c85a9cb3d514ff0df4d6e595fc597a846b00012723cf37a17f6ed3ead84e4df2763a8f3c7c9f2b39c68820fd2ede9c6c525acf9ee0264184a13128dcdc8abcdefc1d4ee488200c5838d1f6d1756e064f456ec6601970fbe524e031db70a79bb218455f3803146be1e6adba12499d57604022aeb1fe40baad7737c33c9e52639d5335d23faa1a441c28f3cd41e53282169707f360c74de40dee0723d9fe589f9c6923d89ac3037a4c4dee49df9e40afcbe5c14df3d4ee23b1bd90b05f3152f98a1a6b86379eb64838ea330fec186c8cbfd8c1567b34aba708dc0634bc51f7b0e747b0b81ef08759bd58e291a0378e2dc86e99a9b083900ff7fea473e2aa324f0b12b86804a062f49d79794493b2821e09ecd9ebc69565422d503a7ad84036929c998f0ff6c8dc5046a44ed2eee8bb486177c08be59551728d9ec9edc67076abbd50ac6a108d97b368f850a718b2012e239aec93a36f1b95c27952cb1909c689b927eb285ed2ad427d79a5f7068e2df00ebaa9a8548d247530ddb99bdb5c4bbe9 +SHAKE-256: 2f6e5988df1acface9078c0c38821d3fd3371455147ad63fa974e0fdc841f6f0a1c7aca5590e81486c8137213801b1ab012954db996926e034db89b15837adb8f8a58cce2fb6ecf94006b66ce7c338776cad9c45a2761511b11659d3176b7086a16c892d86fc0df96f19a17c4ee538486c3b0ef0542963f699026a727d4bd928b6eb9c457e7290a9a7eb03791f15eb788793608949898fec95d3d69023243cc206c33b41108ede8256ed99065faee258dacc1627e8acba7d7c3bf4380fe3df358739e5520ecfa69d0cf05c31be52b150b90c0fa9e483e68da2f802e2626264780e2b964eb84db89816652255382720101b78317e6be050cb835c70dbe08a424e0877f3c0110e9c7aac09a26d6c586f11cde9f7b274074305b4cbcc0e455d11acb5adadbd40bd10d59a3025ef20f6bede88009d32afde65b35c6246b2f8102f7c25555e061a88aa0353a5aa252c81fe0f51cf59a53b332eed34ec1e5f6bead8a898e1c8ae117adf374efc975033c4b5a86a2a84277c8a1712149097419891155933042cf273266e00362c6a1f0050b0cc17d20a75225c2a5023982e1db75c23219b203131414694890cc7bd476433044293381b46a1e2f8dd63f4700f539df9214380685769b44db28579673140bb8f6a54e74dbbb723f05b5fdf02aa85d0cb9ddce76d03817630b7ad7061aed590b984d50ac31efc8eba46f217941010547e67 + +Input: 9e5340932eab438def4b1be4431a35401676c4144028fc0949ba1b18cb40354b6caf36ef31e4301efb00be59c06ce307c5d8575bc6eb6e632c788277b0eab86a4e1d97054c6b21735349d69e3084e2d90ae641c84007f5d9e02510ff43a72cfdcd3e9b57a0771490ae08debd6bcf38995d6ebd0fd1bd40273ce6d37bc3e396c06e44e52bb4f2f4e378122a1b2ed8c41ffbdd8db259d7b7cd582b3dc1fd3437aca8ed1d5fcac096fc22d75c71e7e2bfc0eaaa01ed915f90eaf8cfe873cf552615bae30e00e698690bd765b02ad2f92404a4e03c8aa55fcf6e78e513a7e4c7d03cf3dc3ef15b363af41456587d5eadafbd9c42e821985f391b11216438e31e236429f936a53a74638b39f62c83c59e4291491d3acff11922b06721ce17941797ba40d73cf8cfa2b9b3c2473d41c59f432668bc13ef5ef699da1297994efff8ffcabd696cefc1731a90d8dbe3f92326bdcda25e4db687acc5417935 +SHA3-256: 17eb0e9237549b8af61407ca9a4b7380d8ccb53aa322a93a2bb5f6a53c685580 +SHA3-512: 9b08ba4dbd66f71976094c54e91b4e9b25ba9f8b1ae2c53edfd35bac1d43b24681dcc4e35881a5a8f880edbfb147ef0da27d122b4acb31a5d87ec5e411ccd33f +SHAKE-128: ae2b528b64485616e75adcc02675cbd00af6318b6a40e5a780f1c70c614bd9fbfec01d6237dac8a76c74d826e67373b247bbfa74f3b5c981f9dfaa4bd2d8345d42e6c67f046900fbe767e52ed0264b14c87d11e67aadcd08b102ceb2bafbe614afd5bade7d217262951aa4d7d104524444f6ab5e90f07848ca0d28867f978628a5e302769982ec21fd7d0982ef9300316f41cc734de23273ffc912b5de1a436798839efa69020f7a698889edc60ddc8db27fca1e0e031d1513fafbc9ede7812aff3164fb68e2dab6cdfd9764d10e0841c1c624f2d42997fa44a59b61855caf077e448e87bf181c5d7f98d1b61448fb3c1159217fc3500c748f8fbb13eb5b17a4238d8b1f1f26fcd9f5a5e0d1245be804347345d1ad8757ca14d1aa691da6048848f3a30cfa67790feccb59fdebaa1e861997f77cc12e532ffda9560fc4c7288439d1ffce99c8fa3148adca61da9e4da3d0e3cdecea405561d74ba043a7fae0f2b32ae4ad2273e9706241ca6745575bd8f809043c77e3a2f1912e967ee29c25d2fef76565555891441f3f6290583c97166fbbab8b972d30bc4c51295a6d3aeef8545e0bdd236761587d9a458d5a0438cf5a2bb7a314f671fc40cce494484da8ebd24777f8a4cb816878770b86643cd2f56b24a2ede571b281d157d37f3fa83d1023fa0715d6cf353d3efcf3faff0d8b06c4a3410ea44e68a8ea31ab49cf9931ce +SHAKE-256: 33ab9c33f4562ee349d7513c48df0866c9278af2dbad73c8a66c4c99bfd09ec32ad4db52f0854d83adef7e8e39eb834d702a4bf76beae7dfbc685860ab38f6d315891370d6934731ec6e384bbb83b868a84022526c12b24666b4051ba256b5eb47ce0cc594751a81cbbee82806cc33b9f5510719c1c6a01ff6933b87b8550c91e6d7bdd2bc73f2baab48aa054981e7f85449cdb28bf679748bb106eea35fdf3fef3f08d4729742f34afda8166a1d99843219a3b44d3e7a38b0acfb0e130012505cf32d3d83d7f761ce8d4f019abf507069a1a4c21dde5cd5791a73a025e81b1fb57323c9c72b2f62f4b5a651e43e7658d558a0191680a2f31a13c9a5b64a79e24485b594908ac9574759ab2a5e30532167b8f5c55fe7510a718966af96c3ef3e4809e8af4631323d903c018210836de61f0557aa01072c16c876f72a767d2a0d67ab4e7b7b999582cb4e012966a177ec52b8316501ad3139962143246863c0249d3bc5db8fd9a57546687fd15598ca35539237ca4ca4c8ea806489d74fc5d40f65f7e96b9f8dd5947ee7b1eea13f5041b738d7e7fdc6a8b498f5098296e5405a96e8570fd1f06dfe99764573d3ee07761cd44f643e326a5acfc8643a128994af133598c82f2e0c4b5efb43a978d2e0d0cc67a19f463b206dc17837d432d56f6a0113ed5a34de08519a73c50b55b093d5d1bc20a9113701cee277f4b915d92dd1 + +Input: a0fea55c8c9358f0504ac76bb29fedc52604222ab181f79b710e21471e907de6e9439243b6ebb8aab87b25a3443a884b457b6c4126223f2cbc6f91ed47e25c7f5d35944a8c128b385aad820f8ca5a997a086463fcd8f4504c42409dbdc23ac5dd17c8b3f48004e64e093727b6506f8fae804d983267e7322c20b88bac687db7fb22bcc6221f01ec565666d5ed01be89f45f809f5dca87443bc2ad1bb2f60ad58a88b55ba5033221a6e1974f8ea017b728c6f2957a30c594a8c25bc94d046fb27bff766da92730b5e7e3b7196c51c17ad4d9ee8e64ce14afba226d5bfd3c638d3cb8ad0079b3f3fcf6007b2776af0edbfe43b82352c892a1b202744d4e7224ec6938ccb0af6558cf46e19075d09806ed7a3ef949b00bc00e10539dc78e3dbdb9ec38a87b7bbb10e4d28bb15ee7073c50c93a3cb8052471f2e7eab3159849c794691a55714c408f851795124a5c3dde4e3d524b81c254b7f8b39c9bf +SHA3-256: 833b10d5871ba809385ab2ea77eb9fa944f22c22c5c6c50cba6d841b7a9ce2c0 +SHA3-512: bab2dcff692037fb334dad4d1325e5e504ad1a2ba94e07fb7ba8946856e97926118cfcaaf8c207e1bf843eec656692762aecbfcbfda51556268cf3fe17b7f261 +SHAKE-128: 8f562ac719aeb4a7375b2ff3446684235487669cfab0b4554daa738bba7934d2a84eede036e839fee7c7acdf7cbe0e1bc1828d22049e7c99f8d3e2e39ce9d66e0d875780475faf79e0f85ca5e80473387b98baeb6664aa675359fa77d70f84919a5725990d5d7e84a4b238284dfbf4305897a9921f1edfb9a7971d136ba8d45f44c6ccfdd7625ec3ef472fd8c660fb44f27a0d17b2f9116efd5d3ed7a0b6b8839127e524fa0caff6029accb09818a22b0ab793ee5b87667c36bd68f9b2e82a1b63d4042fbf8336d4c9770e7666285ff85000f7841bb27eb5240e8250efda646f2baf649c1a1bd526ccf8f1758ef0b30517c0a918295924bbf6764eb519f54477cd7a2613b52d4b1bc794802bcd25b77dbf24cb58e0cbee2064f29d37c6f99b151468e38102aa55d0579fcea9f7601fb8e8d1a2beeca49761f48cb201613b9969a795ca3feeb81b7dcd082a2b36f79acc409be6f6e49305e9f63094255441780d2884302e140227a39796891082352d61c12a27a1823e2301b8ef93aa26b87842c1d2e86373947bda0e7bc67befaa157fc3f6e173c076f0bab5c06417a39c0a12b496b20fad4eb0ad254569758b56d9ffa05b286321074389f4becc628e9a60dcdec3164062b1747659bee21e855d34d5fc671010a25808e44033da4ba7876fd087c0b9ad09052afba21d8ce73b8806abd0571ca8bfe9dcd8a8a3d4a49dd16408 +SHAKE-256: d64f944c7c4bc92f1c13134d3bc8a994a605d7e72fe02e4d4fcb70d7c4a6d33f4b18c3142e28fc615248611a46716ca123dc09c7e8ddcddf6cbeb42fe93322ef46ddfd2550be8bc2271345589b0827aa7d554ccc42e813fdf23a72c95132495054b541d44de4499419a15b61ae4be502c45a9f979856a01de316fe9e69e58e259ca67c988647e745a75a0c9063b9432c68b37707ffc178cc5ceb59c830c2df6bf052390618f7b9ccb79b2194bd5cee6bafab75d695742a6a22289719132d3ff98cdec60b295dad8d2cca19c540c191f37b871a74a170fb9d5483384d6fa88d8d5d9de4e73c4d0b3b507fcddeb116fe149082dffbf9555e72b85aca9d9a9f6cdee157569d59778ad3227f1558a0984002373f7222526db5a633ea165367ebb8a70bf92bdc12aeab9534d9b09d37d0512af7861c4981272dc93dbaf519ea5f83b91fb3e166caa4e131ea93cdd41594f8d705ce5dad261a77af1c25d94787846dd2c207ade42a98fef07e168982fa4e52b8ab8679d0cc8056870e89cbe1033e741a8bdbb7abb43f38e86d0601ebf627d08346091baeca085bd9fdcd0ce1a626391d68cb1ef35e286921f5694e0c50e3b6c4ae2966595e9054247339a000459fbcab447d9f461398bc0150d40f6f17eaccc524ea9789fead23783de6c8b9e8d2ddff51b84adfe2b116bf206cf672bfd21a7807f4ba98313f329d29cd5f2f507312c7 + +Input: 33bdc66ba51f023f843db1a400176d2a36171869e248428df9fca11a4c8d282380472de2e7c45342ba75a8b6556e3f1e62272ba962dbcf9eb4b83acc7e00e382636d037dc3ac24121de155dc638f952b1c3ca8c9665d256f5aa3c865c00dd29ff136bb8700843f66a847f2ae0d625285a01d85664d8551363b1511156c852e0de2033894fd33a7efcd5661ff55551a18ebd82f7ddfc4474e456298076781f725065682efd7e3547286ee1f62d5c924ee8c6bbd9f0cebfdce64b50315d1766e438814b9d3ff99136e9873ffc6990da89c9c2912e0b158e9623e6a0448aba1db0b0d569ffecec93da04c477417624ea24fc896137029830fded5fdc319b554206f008a4e477c07b71fc89ad03a086d7e3ee56ac3bd9c7677599c354834ca2d9b3c7c8e9ab1829e5ebcd315bcd0b52535f04aa6d166bcfdadb802bd3ee4c865995ff5882fdf76ec41e3a117d8218f90af86fb1ea9c2fe94c0c6a684c6a5 +SHA3-256: a3121fe7e8a0b90d4f68586755956a3ce1ffe49a2a03f57783e16549a831e0df +SHA3-512: 55a55365afe00794d34888535d340270ed9a6f7231f5ed4193432c49ae1c338966603b3dc74228ff9ce8fde3c42404c57f8313c5aa32547212a6e858bdab0f25 +SHAKE-128: 472d9d57e2040ae9fdc9ca5f62a545e1eb746e43fcd04df66d60cc2eae07f158eed84735024c5233b7291272bce8393e10a39899684d96b8f85e7336ec174790122d7f83f046f4bae3b02cefb520ceea668084f4fa7d50fd86a6efad4a7aab4db3f7a0d4e0c3cc28d4626f4a65be44f1ad9d1b0dab9ffeffecf7243b5a03d04bb9473df57a05d86a276765dc775a09e85c09bba99584c3d8a09ba07db273bde63d4d243fecf068c494cb73b78794af7fb3527fbf2bff5b68a807598e067b01f6ae78867b7f9ab1bb66504caf0fd1ce3c2a305a7b3480e35dd3d4cf0c39350d711f6f35e441a3269cc10edd89602329a57d89612d9c931c7d6a5da18dd83f26cd4aeec3bf75a8df62974aafb76c21c2b61c6cc90fb16219c9bb1894e48c80073abf392056830f2e6d77a9809f598582e94498257b78f48f9c64edfa707b66021279485f181fa3eea3335bf5c96730f56fff52f4674c18c6cffce4b5bc82873c615fa5ac972d1d6dfcfb631fd6a9fcd1584d5ea79d29876ba9ecb593adcc003d0b4c102b81b939f46f5043c4772d4562af3ef37f15f11a019e3846d6ab545cba6693dcb8fcb4486b7553fd5a60123ee6033b863d557ebfaa496bddaba54c09a02b8097dc86a463facda6d6e37d945e3249507b6d2a866b1de9de85cefd7161ce4b6985b26ce544ef1ffadb46bae7d5d99f15b26bd4a375274fa38ef66910ea60f2 +SHAKE-256: e4512c4c293c86f677286b26feb6b553441facd3b943aa8938f10f77eadc5da395b6e224532154c938b14759cf3bf79881255ed58d96c880b9fa9294e2eed57f3e13a87ba31b95189c8a696aba82954f0b00a8f159f4628caaeac10f943c81fb5b02d2bafdae52058b72d86cdc0722910d254a19ef0d107deb6446e47c7a6330d8ae774c2a16047eb9f325c284cbfc4e8ea82186ddc60435d2db23675fa2105845a53086a59d49b57e80cd9159d58cc0e0b2a1ca1263291eed50e631383d68df9aafb19a675790ce2bf00f2295e2bae649910419ed037c17141d45613af6675a24e1f2c3bfcdbb5b153a62c404039e7e879b9decb1aed8e078cd9355ee669e90720174618e3cdc7cd3df51198d9a2b9c13fab76a33296693ff7d82fbce6b1f3608f16ae8461e3c343e59e143b8be635e6e96e1592cb21676fb7028c7f44f86d3585fedd9d8ecc892616ee7f79370da979b5645ca2c4644c3b21ac04a3733d53a08d1623bd9465fff1de423e183b27ce99b33074423d1d8b533bc74a26afc5e6e271b1289e008342626722ac81bd7834dfd5317c481f622ed028c38def8f3933bdd4648e19b8621aebe0473e932d6f84e7017f506d9d6c8d14293d6826d09c55e7d536f9f728c54a71703ef83f2e7c7df49ac56a38bdc534a98c926cc47cefd191d654ded63ec3753222a2205d01e659cc5b0bc3150e7f184a8bcfd732c04b069 + +Input: da359e0a3ec24ee762d7513c5805568593f6b0e0906435c7204e426928c885d71a762d686ebf660034d83aa1b73519517976e8539d5e1ea19caf9689234d0e25c30a4dd1de556604d69da9fefb47c05525f83074f863438d15792f2e2386a762b609ea001473c3c4f8af55991bf9b31d55b88d1b28e97bad74c713ad40adaabd825257b487b0f9f0fef2f0f79ad80212beaca5cafae6d3fcf13c0165dde79006797a507a70526d1a235464bad101d18a1e1092ddb65da8e39b760b992ecedb0643487ea7b253bab2548160bd673db399055da70753be94b438705adf9fbe681a45ed72223125611733c0dfd249f494ca2923ced53949a51775caf4e05d9232292066d6d4c883667a34cf2e81416ae2ac6e672d258d08c5162b3d16b8f5eea92c99bec546a0c35a346d1c0add0e7b10a064d3c6691d7000a422659e25b6a4775b7fdee5cbb74945183ddfd9ddef216dc3d165d8243fbf6c9db7a954c600 +SHA3-256: 1a49c1fba7ad52c2c2c646a2c0ba5205f744fa407f7d50971213d99ea94a1d56 +SHA3-512: 98ea655a0f357d4d053804955a745d1871a7849e3fe504a32bd367eabdbfb000590c99e7a012d929086dc50eba6ca98d2bbd3cd17647e6cf247d3bb846608158 +SHAKE-128: 955c845d27c001b82de66136413f01dd36036d97d14b63371fb374ed4f738e6bdaa38560dafad203c9714c2341605315811698417dc2ee647885e1942a23a0ba1b2c6bdc1e0f36d20e3dd2ec1c2fc22ec0c8281439ccac015cd37079e799762fc83b9278436046194a80bad1824ac5ff9ce5158f8d5e073aa536227e60658d9ba5fdf4bcc7f6ed5e1512db9840b834eebef03cd0cafdf62865545789ee64360bea8f04d1200e2042361faf3ef569ab45f4128a6abe932d39b54fa9a557cfcbbfd18ee0d35903b4b9c245ad3f894e091051a982d4fae4998e7d4eed69de9327db1e604c48b49f4eca04e72d3ecc9304904feec9d813f9172c04843a31b2897b9f2fccfc75e8580bd2ef7f0454bbbd8374c22cc1aa0fdd73054f299d639d104f0a4dffd0fcf5788812bec374b9a4146b802cb14641e804f37d61c1efc2cb585a78c220bb6b06184a0a4e69a254020536d010dd7aa563d835fa6202b1b2a1aabe9ccfb2d48affbc7a36c58df8198c17fb7e4551733668af8bcffd04f5841769167908a37f6ede10e9fddbe6ed86c341d340306f18c1fde7314ca3ebaaa786d54be6ef264575b44e7e208fff9a8bd6c6e08d81b6f93595e447be96f27064ab364f4df3c415ccc45d6b5294fc830bab56ce85f48862eca3b4a1cd58a334d5aa8a6aecdf43b11db5f690c8ea985dff5df7fd0fc298af2288fb19568b51500edd26ebe7 +SHAKE-256: a469a827dca3fdffc1c1170872161d8453e643603b2f750af934b5469da9aca47628a15ad1fbbd52c7a9091d2dae407144e439fd4d48719d40b330d979628eee99b29f688fc2c007ca15174547f81dc41c2b2f0802d6a74723debdd0eba2c6c92504167173e7a5651a822004e7da7b6cab52065ab6109def151a19fce5de8bbeacbaf72441bccfd141c51821a365df31c4bfd36042a2ef3c6d144a110d718eb55df74d8a2f999998d2225964697114ec878ff3d26e7dd54071d3b4ccbe911b4ba7cfa52e2f16d80f9d98bdfe416fc6b0551b94cb5243f8da446bc69467ea8cf3fdef442e003e0941c340e2aa6904426ff1f72cb8e6b939ec06914d9afbb24a9b35d3f4538bd913589bda6248d1e66bb703a807ba3e33382400559e83cda61e32c4de5d40a6dd179350a47a4c7de4e7046dd4309f1b649d92d8e374c49b9bac9184e1265b4a32d3b6120b1aea391b4f0d5618471458834120cc398fecb996e977a7cf71023d5e5157ad6cd75845a3fda1bbf27938df6818ef3a9424c7f740150c9975daca01be972c6591472236cd69de621ac501c31ead5701c9477ce9823290d73e5970976803099559287a4bc53e56dec0f4d6e2e2fbf6a94b64a3104632b0ee541898823aa3f035afbec4ce444be3044febb57dbe89bd6ff3384957ba589249904b1d660b734caecc37bdad86d2aec9dc41ef4dcdfb36bbee9b5ebe34344a + +Input: 2ed8edf286c81aee2b8d34f163c0fba7cc99ec284b9ff789ef214a86aa3f2530593324be5b42046e39568d4bc7ec04430fe07d98ff75e0e4da7d2f0b8157073bb643216d1c1f771c687c9a05ee9ad0c7ed3bb878daeefc979e9e22c41e2ce31b17a8436b328344309a1a1f047f39cf45829d2eef6fb84cfedefe3b7c2c848f3341c7896ecc5c5d30df84ed72ccbde5ea61607b68758ac8c63dd63a72a421642d5305fe97dd68a08aa8ceda5869a376fc37995598231c496061243d87451204c917ae3d731ab58c06f92518c5e0ef7f43bf3ed689c652e7dd1ca4a85aa0ed01a315c561c435dfdd9263a4e438d1b381394ed2c98525a6962263b68ac0296932b58ffcf807e496bd3489596887eb471eca94ea961b1863254e28f2833b9f5af5869787d01ae7e626274f17a00ffaf70bb376e9244dc9ccad3efe51d5e8d33a6c7a3dc6f6187e0ae8c65bd7c634e0828e7a5efb53cb4e235f487f8687e2c5fd +SHA3-256: 614efad7e4b514984a66ca18fc336f9abe95e12ce959c61a85cdd5a79df53fb4 +SHA3-512: 2e88584f07f95dbb50ff26d31d6824db259a4170afb8ccb3919bf795a5c460e2bc97208d20e94659629f9d2b565141e2b485a63505f92cf1f8ef719e976ad876 +SHAKE-128: 2b4b84b7036d23d51961b48554cbcee7695ae56cfb7712877d7e284f53627d81d813d4afbb5f3548a543d96c03615e453358b7c2c68616a7720d082cca5f250124c78ede98ede0041ea655386d0c2c4bff30860c8c8ec8127d3f01df90d5ec53c5e9ce099477a253cc8b1da84dd2b575703422a0cfaa1a97d5e9dad67b7a54afbe8c2ae8b8895bc65a8a2574a336e27140a5caa6185edf42a7fc66dd40f1768e650b6429ed19a78a9361f06f75565ab4ae475d1a539a1c7388b127fa948b0c32eb0ccada4f0c782ebce2f647e692445150cba6b07c33264f7b5a99b7a951f5db0feb01edb0ac2b3f9da8a1f4e3ffdcc87e5c96e259e7fa0c2dbe0c64f970db40a8fbd35402434333826d7d65a23f1ee185a256c1d4ecb221bc1d91ccf997fbef4b18a5af1b4d6a1519d93e225815b37a6ae3100eae5aef8a1af40ab026c772012dafd503c361d495bc0ade18ce03082f7297a162a6983a79cce2cdd04b082833d96ba607b51049c7c709b5da309c1d9fe833dd7be5acb5954453cc584230fce145d209396fbee1227657cd51e9799046001040b5a4a9cc4404fe232f2c87896e0222108e55ca1525c00a54e9777f271cf60044c4a2ba046007fc5b3f87f736ef13670cf6d1ba4de92661c1269b3109769def4e4b74ac44144462ac756cb613b786bbbbbdfcfdcc467070db8da5a66b8a463a24de9da2b38414efabe8d2f5353d +SHAKE-256: 8104bbe785add3a91033acf96261e4759560471eca4e2cf4cda0fa1cdb456062870962b5da1a7ebf0c271d8f1722363ab7c7b93040b8b814de97cad6ae38241a431b0d5d882ba552c9dfb55f0d35734411d5bd31e6f93e5779c3595b7200a9786f7f341ec0910c9f0bae2e0cad2e68869459e728dbd7553a5c100b37faefc9edfb75a3ed3118c259f51fdf66c486cbf8e52a4b7f54081893c63de1bfc94186f38a128c2f53fbbd40a904c7f0646aa59900bb7a7b11c6e010b3fda5a6bde05bc2b16fa4e716642d6cb582d0dd0c7b0afc33a285996e633e5e9e3da8498927a6fdc422ee3ce5a2481dcef74e779da0d9b54b3d5a39bb280c6c8f494d9169f185be6614758d950cdc0d78ba1d8b6a89d65e0a28cd56c0dc8529296c6de753036d2bf1e2041968f0089ef8b58cfb6e8ab69c8226b0fedd87d44be98244f3a10e4cc4796ff34d740b4accea27bd5afb9c914e7912bc02ef4d57b67cb511d4688d7c69bff546bfdc73f4c1c977c61d700f6a1d5553a091c911013d764d2215bae06ba1e7f822f77ba130a1fdcd4465a9db47b5b7b5e4fb75d49a230c1a4df9d3a3502a38a1b8e78604b5de719323cab05ab0e21086a7d20066a8014a00e9a2f75e91b201aa1fd177e9a087e0ad8acb056af60482b400975ff0d4ef6480830b18e874fef81b7fbd3e17ea5234910ccb1a10a5eddc6d725cb82d16f24050c7404fd6cc29 + +Input: 6ec3f40af6cbfba4ac92898cc7c5949d5ddc13e6398b40c38c9168e5dcae0ffdeff3f08a1f59336b06baf238d5b6c9add52c7d94f5ba79b9a1e66e7165ac683568783c402f114019c222e0c39eaf54951e32f1ba8bcc71b6ddd3c1fc24fb2972b16dd74e7aa551caad666b708d0bea5412649d82a1ad578f08e5e4b42644cef8115a4a4e9e4da1f42be26d91390a52492f01e5d7763e29f50602e1ce8c1cfa6d52ed89641c853053921bafc5904cc31ef022425c10bbbc16e6387070c7e4d6abcb3392510f4b5c92148273ed3f6df409a26751c61745147a617715a454144d66a424d0ecb98ef1731ba821fc205b53f6e7db27b3840df0b8cf87aa1279d4880adcc4cf427ace3cb9fb8f1bdc48b30674a77692c6934ab4f06df45c3c9bf6bf00fd777055fa225ac3b676851cecefd00528e37f3a59245ebee18acc3a971842a3be1e88f379be9a942c81eab139c91d3ba43a59eab5a6c21d4481567aa096a8 +SHA3-256: 7fb6948d5fb8cb19ab6b7677ebe107406adae052417c5fb257fd388c7fd85e07 +SHA3-512: c5af4fd05b88e2b06ba270de6faef8cb95227bd98e14ad6485438adb94166a237a185916f478ab3e244985110bfdf42106592980557655cb53b8bb673350d2ca +SHAKE-128: 9a9d3e15b3a82f9b01fa4979a3b396061349d140eabdb2a2365da249e5d317a18ee3394755e4d5e3d13c237635c4877740eb15b73ec7216dbb9c2dcc434b65a8e939450af48f43b79f02129ead63b9a9a396921c871fb13966c85f28065e8e411bfc075d3eb86f9a455d253306186b24b155c83b63aad3119f328e21086fd36f07f2c95bc19c6f5e08c10483dbde1c6835833512cb59478dfded32f429e71c433b280bd3e30d8c25c5af7ca4519d88b68c059302f5690d0e9e5bff64f8b0181c18eade66bbb43739e6231281bd7a463f2c97487454e509e19dd3a7ad5116dcea8fd148919e9a75f82a81f39be0cbd441d23ea349a30c6f2d687accb27848168fa5b3ddc9649977cc1fe6a79dbe51c8c5f37d86a0162fab3224b65e685cb6560b5f7035e3e460fedb4874c2922279ebbdc67964d9fee88932911adbb33f88d604cdc994c495cf9ecf4bfdcf5247f4b5f67709c577f49203ff6cf36126f3feadc4fe2a9d046ddfe6d2a4ee2b8b198c7d1623f085a33b8a3e6b552f641b2639409ec4471c30e1515d9ceb43382ca7edf2c8eafc7e455e699e86c2e92bf9b70ef176c294ebef125de0ccf348aa4ebf2c6e5f06bd2afc91ace8f54a8ebec34e7a4ab6d8c611682b5b9b53a2fb0a354bfe51b7030af6ccf710ddd51e11069f689c01fe3c7bebedccd4096c2a0d567d40cb3a223ceb69746f5f7ed10c8c8b926d850b2c +SHAKE-256: 5b043c9ecd94df6e419aa3e20a6c3d30132ba3c9aeb96966c117abed336eea02f9374b0d6f8bbd23a8615f9067491520fcffbfd17913010112cbcf58ceee837536617acc96e1f4fd338f32bef92662dc36208349c1de66f6679c8db6545507fbecb4afebc963c455dde414e7b2d0ee25e03fb0d6aefd80238ee2b94d38c8720d1959783e71015cafa7a41d38f0ef49dcfa0e07e7fb159e07f4ce8a4ba542379e5e970275677d080d7d7e4d7a241aaefa702958d5d5f3791e5adb5349ff2db5085cd32e4a75d2fe431ec372ac5699690098b44af947e27b20b480173e9551a6dbd6b8044f05a3325a1e5cacbb79c514a8a8805df21bdd0ae98af551c57103ceb236608c37e008861acdddb9eb630d5af02352dc70e9503b30354f30a9c853752e7b660a5405910864f38ad90645ccdd31d0fa713d541be2a9a36c3ca57f0541dc7746a1bf38408fca0a6546f21bce523f6fb7cf4e4087ac63cb58eeac0d96cec813386c012023046355323cc21a4a6c4204cd5287253e30e6aeeb2ee2af100c176970bc41020328dc81285b26b59619e6bf30be59d5c9a3774b86dd9cdf5077b1a0eba6dba28d860104ce1a227f7eaad68f5e5c64309428b0ba837e78bdeb0ba0c5de87f61f0865896d39d1d27f6341a6bd8de49b4c52c42dccaee911149923146804f9a259d4c0975f0b6385aeeb3b24b63dfce6c1c3d2c3bbcd891e00d3684d + +Input: 5ed5d5440af752724d74c5c57512757eb0f8e42b662100504d7bde40b688311292d297d2ee1a2e7627444c103e41f992e3df428263e9727bb728789bdf8904ffea0301317026524758905d262c23a07964fb7b4e20d9355ae0218b8e5b26020589e1db3b77d5c7953459e0672ee133511ff487cc36e5baff1d40a92e70d944b80d09434a5334d5a4c9806a11fd54c1924ee9f2d6ec57486b41b38f2f5919fa0426f4556df91db5064eb929ce539186b65251338ee7b32596f3805b286854d958460777b5131ff03a817c221cbc1dd1d6fe12b33b3f0fd08a853453a763c7ed00a33425851a25d32896ff2afa7af279c4e8bd1d3b6d78be1bc9f85359debcce83813438c0a763ca9617c54285f8365fc511fe9b006d310f83f0bed2bdbc378137d9782fc870fd64bfa6cdbda4fdaf9888759e0ba63394c666fa383be16ae65c16676bcc55e16656d1a423bd9ed0a3316f3c095c5ae3db9a357ab6319f9b2cb920 +SHA3-256: 36af2f74ad55a72062ff75c6a1b498916fc5bb04b52b1ae6952549d21101f8a4 +SHA3-512: 3b3a26019213edf69901f5e8052340ccbb4418f7ffe0cdea27925d176d59304a020d38f5b157ee0410d76a94d7bd50a85da53fd7fe970986496d4f2392544146 +SHAKE-128: f761c91c1a89dc1aa58f42ce0e69d42186855d4523d9ccc59e67d2cd7581574b1975436eb430cec0db2e8ed5b936a2adf884ed462b3deec8d959ec03efac0d997418cf194176f387b8c849973e0186877107d9ff9b2b0783cef0a8a8a52fcecca2e193c8181352edcb2b296e0c61cc6ce220576ba536b14d4f7c6dc9fd08813ed6f3495256f4b7e40251fc3ba98b0fcabad06b564209c7b96ffa6e445cf6e314ea7fa1b62c42b3b34b9d3260ae3d5548689897ccd6500941f6ee06ef216933fabeb2dc6414a7288a3d6eec78776b38a9b99b0a2b81bb05c58dfafd1d6107b6f149a513485972fcc22205765f649bd019fbafe8402f140caeeb46132b5fbf7ad5f0911033229590103abea38ffab1dffc9ebdf3ebea5301edbc574c135cf36162d2d975fbf598a488d97839b8ce40976fb962ec397fe0768da8046f1e270722ed7616f7c59cdc0c427ea26deda94d394456c7a2a1fa25664323ceef80de2e037d8c0aa160cb03b536e71a749a3246277f9b6305a94b2c0708b45f6b75da9afbe269826b0e6401550b86742ec082a188b147df07828bfa31aa8e2be6a0d4accbf4fc0de68a1378a8b2ea5550b581a82d6367f413ea07119a309af667bd466b5bd049b2647e74416f415ec9cd60600552df7396baa1b4f3735c0efe0198e0823fa9fff3a71b223bff34c92e15e7f0670a728b258d8e2062fc9672995fa54e077025 +SHAKE-256: 23751e41c4b31d226a7df123ee6316910b13c60bf7f9037814e6ca27535b65cd2f99c4a938c32c78f7a5008fa4f816baacd437f039170a7e593af9ec1740899f5847afc542e7c2f8394db0caee1222d3b1b3d8625d806c7e3093dfa89c6534e375432d6417bfc42408827b24dba2f7dfaf785811d55cfe8c3713bdb46690da76503f71da9ade3fb2a8981745931e2a4fc5ff9fd54ff031627850b14f058fe86e6272cecb1d82f78479fbc2b07fabb3a1be1a42f14bfbba184029cc6be5e719153dc4058a30930ff9182d6869121a8dfc3b9241dfa050c990904ae35f15c435407def57bfdd022aefccdd0159a33ec1b8e974b617c77aaa2730a959e80ba4df1f45186065aad5521b00f7936b7246b17fd38cb735b500d9ea2f98655829b6c0d8f9efce3ff04fb6eb69eb27d97385693a6e238f4058b345242f3d6707b7b5daec8e9e4f462609c332304c507495190cd267f58454c55f05f3eafea74cb4ee9e60c2976d62322c65ab03d6a18048e9400fcf51f11fec5c3f6581d78b84d538dd34619eabbdc184cdb91501183939391c0063e1fed6b06099fb4883551ba4d949ff87a9e52f877e94bd2213a1ed3e30ccaa0a12053bcbca0329f2919d64a66333243088afdc8ce65f58609ef748b9cff44f3b4af5bb2742b69189bfe823daf7cb28529fc5eac6615e5beb3df1cf395acc0aed81070843cd5112444a05edff0377be + +Input: 93c220e7af9a04d2b69c2a8321aaca20196c841d124240ca09c2a6342dc52ca088945afda0d33ed6ce3b5de2de8701f98b3927bfeb7d9aad128ca5d0723e2e013c3f96810ba9480c0b9a004011ca4ff4e5b81a444d63361118d49e956f1dec08a97c398a503397b5167efbcbf78714d5d4bc9d273f3fab3c46a6d2a43634d88cf43fa2841a18e158d2bef053400f3f5782b13323a96f7b80464d38bee3e737f95ee510a0b8a39bc3c561d5c48e99b5fda6299ede49d1d8d53a952640bf86d9c5df5dfd24e46b93822ef976602496924951516afeb560ed8e8731b72efa1b387619e5902e33cc3f0c40b4ce4b4be9312f391e9fa9f9c330a6cfc625ee40452eeef53198235f67ba2a2e25b83f5f29dfac216c6ac7cb8117acf8499dacd9e84048c7ac901be429c797a1cc04da1dc6cabe950d8638616fba422c8701a999729e0433c5dafc2883912ff272b78a531ed35c06f1060892d0e1b8563a040b99057584b6 +SHA3-256: 39a6f825155d913beff3039213712e0e6a8bd1b3f4baa9dabe1681e28437fb04 +SHA3-512: a0a0437ee9ebfd657500052e09c1abadeb1ee68d9d249837d94f7e8532cf73ed42d7ce3667f655cbeb9ab89a95424473338d0162ff657e53c3b9ae834f7ff438 +SHAKE-128: 3e1d1555943005f60e03b53dd7950926dc9c841f6514206091109eef603ef923145ea788c2471db33a66655c24b2f6404cd2f9a3a223e3fcf7aba5171219e5c3f120eb7a8345b9b50610fc66107d9420daa8c9d8c522036109e96b0b0cf89ab1638c4360eb4859d50a3722bc26132012f4395c919bd215b847528a0bf39152aef3e896e414a8cff7becce02e52dbcaaa90c2b8f227eb1eaef551ee73c3b64feef7515882ae6fb189fd06d42c5b440bdc067711c59775408d476bb104589b2fe293a2e101268cd6063c5b7d4375e0698be17c4ea7693a9afaeae48267d703b24bbdeeec0f48dccb3068e38e01bac05af092defe69f62c969acb7315f0bd77c326cfe6b1a5ccfc2dabd308345186e85615654a88456d5055fb11fe1458a66437a2d188c8c51a833f8a60ca4f8744d3ddcbf47781173a3e22a23a1b6fc4b3f771633d1fbd12a999b53c26995c9290873a2d822be77f2ef27bbda4c83763088d46ba11f05644b828bdbc6e879d5a483eb986bf560b9e9c6c81b689c4f9ca1e54febb3681237a0f0b674f49b27e7d12d937e369e82e1992d8fcb2a8db916f91d789f343e079c1275edba2b4221d0f40b9f6ee5a6c58e0618a58eea28d781239f342fbc0c30bef0d2fc1e97d45800bdf66f2b6a364710014dbe6b89520196a58c9771824f3d28980213e9fe9b0b2c18d8f564a13cded86289c8d495d0f37efc00d74c5 +SHAKE-256: 637750aebfb4952c7396bcf29030a91363656b175c34e215c59fc17beba45a8811616950211b510ae6a15d8a2930661d11b250c1f58103c1ca5f9fd693cdd36e44bc629d5dc455202f9d99e676321ccaf51cea7599d729d4b9f01edff6c66593ce24fa98044000f5aa02f4fbd3c881887dcc96b6a3472a058791197c43d8eb63cdd5195a7fa19b9452cf99a917f85241d48d1bb32b8b68c5ee84322987654a95080f3f685542d561f440971be3ad08686a786b52a39c5b9f782899fbb1fba82011eeed10f1866fc448f80932aa6c1d738020c953e119ef7f253a0f348960cd7c46a2f37477d05e3ac15f9e78fab88a8e5f6de8ebdfd60a545ff612781680f725f2926ec06ece14f63e4cc41d0ed1c90831f4a247f91d15eba6a2a40f2c773b44a583e125cb1064a5af1b46c65b65e368d5771525d59a152f7bb364cdbcd57777314b1bf4f0348cde83c61ce0cdd88b4ce90eb7b8ea5e8925e963e383d955972392e81aeb675bf3e50d89416c4991b31bc1abc1e2260bfd17f451adc26dbde1a5dc1ef92113ef48acb1e2fd9a822edba525306b6fae6e6845a382b87d2c5bc4150e46e9a17bcf8f048f849e36e9aac877310048ce73dcab0a95b433a2b289c638a2b5ad33e428c32e7576d1e0a8ab732b08d3a71b753cf1854ba48b1469d8dc84bf2f78ef59d1140a154731426bee4a1310d9037f314348d86199cbe50c302e9a + +Input: 0d60c256b55376b40c60fb0e2cf3f84255259c94f3a4eb95837b4f191a135f0f070397ec6c20d535f9cdff9f9895d9e076fc4fa594461a15976f648ee62b7de5388709ca06c701b9b3e53a2ff27c1c6763225e6688f2ebb26cfad57f4de8a946c44fae70e272fea31750c9a24b8384231becb45f64de07b0abee34fb89ded50cd9501f23536fcf30083532d3bbb925c8f7dab79e6dbdf10f4ea018f4cdf3644f933637f7960b3790f8c0871bf01baff1308c19db30f53586d886c8a7bcd45206d050b9c0d510b740b2fb92244f4ec0e7d98c51c1643fa4e94b48e1c976be1abdc418b3aa3d7b883c713be366a5704a710389b0b876fa50acdfed20053e2a8e5828695b06c093f1d5889ecfdbf4d9f560f9991ed91fd6b21066b1342712acf99bb9615ee48346fdce7e2ddf069d4cfb3facef6634b7bfa422a18c85121baadf15f621f801d6531a74a5883b112c55802c8c67d973e9ee9bc8f48d695ce1c2c3d14b24 +SHA3-256: 1a096dc2cb1c41dff0e48c9016c3fe99fbd616a9f0bb2354fdd20645f8c69a6b +SHA3-512: 8cee6944c0bcef0003d725b2bc312c21a9d67efd6a9abc19573d9c80394792cfab726b16a55c898555de8e95d7a9da1b2842778531fad8c12a95134afc162bf6 +SHAKE-128: 71d09897b0abc35aa7603501ac64c289be15ae573f671d9f10baa0d6465652d6801e55ca88d8e39b4c6481ea7fd6d6c53d261c3762e1516570a575036608c66e11fecc0f8d283d38d568549ebbe1fd77c96df45ff39a263798329cce832bddb683fb2a6f8f5d5d585ea6695893961475c6c91f600d3fadda2b00130f74e5c71daf815425aae6f07f57f99ded8cc669cc6ddea5f9d22adb6eef67d6f4fe2fabb9dff4ca537cabfc188386e65ef69a5ba38ea932290e1e28dd5b99c6fae3cb7447db6e519884f7e56191a93efa6096c60a14c5d74bb9ee6eae2b7d74cc0a20561bf4f98615fa6fa95b2c47c5920e96a5a7eae8efa73bf4ad35b514f239ec8a7fc36612230a912a954a8104461c9c5e059852e7002536b3264eed1a693888898b476fba9a67408b150b3405d58a7d03365a499ef31f00356e237b0704af62ad81dd8ac0295401577de712cb8d22f0b20e98bd4c02777e9d98495f067118f5a9ec51c4a0a7740e4c0116a37c5527d559503f604759af91b10d38521992532a226a1d565664e52f0e17f5106c4b31a4c3cf2c9907e06858483beb8616e646a59109947c478445dc2faeb89b717be8805e3643f2bf61e3a142495e441531012be2f47b958d2afe8cb23fb94ca127b3fe36a2035d006ebe88b8aa838962e7d96bb407f74d329e6a8f3bc85243777a4f4e11bd78cc406272f36641203f5205aae07ab934 +SHAKE-256: f861ec157f5055854b59fd718de43da6605aee5b1fd7584ad0a0522afeb15a87aac83079e1f7cce049198642657abeee98b980f78f02d632f1ffae56b7e6dcbbe9030de8e1a0229194090904942782f6891c5ae450b547aa8ed3c95bb4d8ca340db79fb9f57ceb50a3ece65078aeab7846f38151ab24c22b0f9146847144e53a5813704a3669d743bc8f67422c8c894cf3a1878681c1e5cdf7bfba756b28466cbee7b61246cff6abf5c38114746c20078c7f727fdbb97e2d23e27e154e7b817c3d3b4f7f2b44a94e062faa449b5ccd818f01a65feb0614a4240e63183fb08dc6966eecec0f70a33d7b8355059f7efb7b5d13a6b9a59d443bb49d877cf827cddfc32b6ef6725908496b79e7fecd41b075b4c5f752c1fa234931ef45703ab659e1c83a2df8f6e24ef7cc86ef0c3dea431bcdd52760a66126a987f08278aaf53b9e0b60f75376097870813cf5c873e8679204c15f7dcf4719f28d8b938394bc782aef4f4539d77e682a41d756d69ef52c4540d55e0edab6c3b27cba379456c9d738eeb2be1614fcb7558158c2d32126578b6f81c500a02a8f8bb0880fd3678307688287b19bd166f9a90761f9d0f45c1e16fdaaf1e2f9d588f1b6925eb89806442d69d8059a45765c5bc3d66a7529606e11b940a22888349d59cc368ce8a241481e0622c0187a30a50cd3e1c71c62f340dd82e8e74b373725d7900337f69ea0cbc9 + +Input: 710ed4d47ac42ca31de8b41d698d765f1855ae15cb28ee45645c394dc3ea00bf4b7687ce75e3b7209ae49d79d4790f40fb3dbb85823a96c8ad9ca51d54d076bd58141fc75a48d1967b23d68d46435859d3fddb8486faa014a52c26a10be47b6070e160e81757b0e45db408937dab52bdfdb95d805638a0ce9d95728ae7989054f9e39c7decb29ca904874f246b090555b39a55b59dcea6cb9611d79ffb4343e407b10ed7c3ffa7efee7d134019936011a2141d1cf81eca4d7add18c06e62dff1e6741ff596782940334ed74cefb349736933dcb00d1cd7084f60906c045dceeb354a5121ff867827f04a85947135038f6b8fbed7614ef04366193ddfbfd071461b1dff32e638e1cb5d3e0eec19e4bcbd2c37b666c68fdc32fd7567e552c169f208fcd8e6f406ff5f1c5d4b92d3bb1393d510649e286b698a65f4c4b433a0b07e0edb2c87edccb7476d3662ff05a96b3198dabce88f9533984cc1d35ec5fcefa9fc766b +SHA3-256: 5d700f858524da4969719d5adf2c3de464ea4e8dc9629aa861c609ad5c972575 +SHA3-512: 1d6a1265dba173c7a37e6c7c456b694e5b3c246ed5160d93ff11acd6a73b4cd0ce5c6dedfb317dc391b886ad84c5489b5f55ed98bf19eef9f8569b19d821faaa +SHAKE-128: 0c3ddffca4cd31e8cb41f7665c86ef00abbfddbe1d43944350511bcd02a18a5202966e75322a99ad90185a4a0969a1907ec185787718625d4806b7f790ca80719b23d2144b2724b202429269d0c44723a2bcc056515399be9dee894fdaa73633c9ee557954e59b90fcf0b958cc933768399a23ef30d424d7e1740b3e649ecbac510dcca8fe7ecb19f4a279c9e7ae98cdac41ed0e45769632c80297a7f5c8839aeb415da421a19e3bf5d55d83929419cc3c14788fe68368a51dcca927a924a1b7e728eefc21ea17c091575d6f7a1db391486dce78ad6e9a1e6a7c8a566e92a6ed59cf806d3428ba57137219b07e7e1db22ac5ff6cd64c7dcd2842d8c36ea35b045793040042f0f08c92fdfccb2bb104fe52fda607093f6e318df3bce6e413ef55321bdb467e80c8a65654fa399dedb9794662394fcddd19bb0953dfac1f4c9a6b92b12ef04dab1d6f973691c4781d56669cc8c57fe2b43997de80740fdc02013b0708b5ad079f7444b1690d4fe76ca697ea0aa470cd982d59fc555932a55607f6bccac0c336a75f7058abb7bf82a8694b32f4533edaaec6d2786c5c4a65faa393d6b7df66796a052d2b773f6f5fd430c0cf53bf5835a33becb51fba9f0197be5ba5bd09073c07931bd85353534b44358860b95aea96a22f0370951d48029b42f05c81adc97084fe9f41ce52ccff1db3990eb726616154a58c0a809de5f2465ddb +SHAKE-256: 5d873df505a5041ea0d6eb21eab4ee8c36a8be5e127b055b2e27f774a38fc7c6df53a8d55c5b4cef24f3a40e2736a9b283cc29b065fa15e083b693cf37c62f2311915fbcd6204045af8b9fb70030a1fa6a0f12fbdc70d730e7a67ae5bf2407d21a294917e83077e0c80f62375c783ff6599690a42d9831a5d34c0b86597355dd98d8c12fb2da5c62cf0684fc22f68d9ae0a80539bcd4f24e5ddd202378efc2d68e821115ac3a7ea42d5d4fbd6d627599ad592c1f655d6d55252e9233e6a0c11d3a187aee930a304ac0f812beb1351c16fb4774f13aba4db4b83b875e4d7516c5ae93265993fa96947c96d5c6749c0ae34602ca79c6f8ee15240c2c41cdf72116e894935ace36ba87b2ce255537dc1fe4c0d05c923f77015af8ded25cf064af7f76bb70cf089b9c43cf35bdf46a828bb1ca83f533ba3539a5cc29a4c74d161beaab72d4141ed8f5aece792e3b496b402f76523e6c3920ab5056614c4442ff25f7777706a9ef82485541ad2b1150613ca01bb95da5fbbb7db497d08f68dc58bb92472fb12b54e7bcdf3f29bdd00762ed02a7ad753975131a1557b15110d039da5aeb35203902dd80e96f2923ea6ad43046019d19e4433d374b21150c5a453f588e47f242bc5738a58151919e3a7c60dc9d28a1cd3d70760b3028c65aeb5941ef457b9b23c849789abfb483c8e543f2869f56b0dcaf9988359bf4855dfa082618c2 + +Input: 3413a6119b3cf2932f471cd4f4d7936140968842d7c1945a7b48dc3e0571b93a728f1ef4251a03140274c7a2af32227f7e2713d588b803b4fdb865d4396a0a760bcd888d964fda507b173cb79185d50ea844a51e182a59c677e3e0b08fb4dddaf3fb23bad8896181b84e162d32dbf083027f08618a58598aaaa3f498ef4f1f8ee5af145be8ec2b35c3a633845601bfc66c1787f088e17daa5992b31d6493337c856da11c26cc3d29ffce2c11a0034923483df5f8a9f7d5955f40d1ea9ac51c1d8344869133cd875d8c076d914b03317dbcbd6f4eed72145819f2757f4d955ae2cd38adb19b85dc0500aa712e6945460a8cd4d3f09edc83398553f601d9e7a19e0b8a08c4648a0f3fabc94422ace8501bfc602859e4191d70dee72ca3bffa9c2febd08df3b2e43f17c4dd5b8324d2052d11c126a37fa46494864a6a2cd618c22610ac3dc27d1839443be8699683c8c358b0c3c5b25b213bf28de404be0b383e3a1749887c +SHA3-256: c1cf289ce40c80b9d33ce479fd6ac984409d45bdc95a72c4900f88e05e80fa68 +SHA3-512: b0153258f3f4c196d85d7c0f89a5896f61edb621fbd83db8275042a7d36aa46248732c70fec94505a222cd2934a0562257e05e3874963cfb9d38a1f07fe5d239 +SHAKE-128: b7ba7f37e38e200b8e917df97b3eece431d9417f2c51e0d211b09fd5722fd66bd21e2331b72fa80d08694c2da3c32754aa08f928a41b9a34f02e41b71e1dfd0a13b69790cbbf6d90809e09f52d5d616e86064fbb3d76b110bb0b382e0d3c17407e1bb9017104220b13c03cd58c1d6be9628c1522e22507ee6986a1c59485735787e91c3f6a840d36514bc5a5fad34500b69bd37e74ab1ac61b23f74b11a4d36451d28d1c523c8eca3cccb2cfbbfcd2942251db3fee7dd32f54c9bc81669885e24484ad7191fdc794f9a93b661be32bc32e5e427442fbd2277dc35a3dd0f7c2e94bf0f34e064af36b9939d7ba186e44bf765366f8a81125d32f3d09a340d673647268de56be3f313271220dc3bda75199ba3bea60a41e9a8ad100f840755553e894ddb2ccccac2b90d69c855e15385744008875af5b7387698c0d08f9d03545d22a494cf0782e501b904d9e84596c1fbd638bb28156afe7d15d79aaf4baab9b01ce9e27bbacebe61765a88f658bce51fec2d0d46da99a51ee7f26c2670211f821e0e797b0b97155e2b859aa02fc3dc1a95e1fe186c1110b98725fea83f7589223e3cf6391d184f7f0151fd8b0ed3f3c8a8fdca9c35a71463f0fe1329cea13b69d313b97afd5653f7f297ec7dce072b05897980fca0978d672b265c5a55ffa051fe772e521496b6d5661cfc70729a8ce48b473bb3885e90e381373fcc9aaa77d73 +SHAKE-256: 7b07eecaca4d33d2d6f0ac5adb4bea8f5ee4c9e7638f769c3da5b34735aeeedecbeff302f6bed4ad7fb61951778251dbe5301e569733a25c645e50e2d0e724b07af3030ddd8db30b32ed595cd4f3464202614689b2110a726cf29660ca72ac619c7772e560be61e972d4acee2eca344cfb3dccb766f26478728a8136c43182344608cb7324113fca15b27967bd5f779d0654ce7e07fc318ad8e1dbc2d1219f912b73662a5ded0553415af1f280d8102968f1480f8934debcd2d0a27e1f58d029a41c16269d3bad5ef8b7c42b2942f2d9aa991b8975c3dd26d7b7a527dd8fc0250fe3ff1e4c3564194d95f4d755b2ff667912d158611e988420fed197c918bccd23c074a010772583f9a902d592fd84bba2fb81b3b3e6b43e1b4aa7b0a75f516535af277c8ea3fd7d9bdf03d332ef101fb67ac8603ba5aa9114ba1c82580b1c54fb5814de43024e5db9d330b98ed82a9db0d63bdf36ab722f895614d6dedcd398d046c7165b212adbc20cc66f04e0a0e7dca87e82fc10d2ebce13a94dc24a7b013885f49524ebde6ef7b4aec0849541f99970660b4595f75ba61e8afe14bc7e4ebf52f9ef60f89bad7541692f102ba9087007ef360f7e0207666827539256b90da0a69b1b83e5450723b9c589c8b2895e1fe759aac5f34c957ee4457c5f9cbc97b29d9268f30d8eaa8e4b6b5c6d386fee22a0f3930bf307524a1e727ba5d2dd52 + +Input: 1e83e1b93f89eb5f1d1c2d578b1da7ef19779ee3d0452889ad4c162618c5c3f6f6fb2586b10cc14ff2b8b884ad28636191788ae02befa11cfc5a6f19fce541fa15cd5323a9a06bf28680c2126be3227fc9e8edfc59d2e30439989f5007e6571708522d9cec452e623994ca40413aa0d5d64d534743b666556f2ba57d0735f63b90d35bd50b4277876709742b17b80263e3447c95760981d82939c2cf0cb0de9b32aa977ae600ab2e604365fa96aeb5e94a49645ec1d76d4a75c9f05ce2e7b67a1c4aa00db1d9c35f751a152cb1bd555c3b00b01bb9fac137b3488eea241374721b3d3d9a5b62879a74299bcff2557c8c2f92f36972fa545f1a04a9a60f5ab54fe72a28a3f5b36225320ca07fc86963243789cef12db8fe7c78e4d751e9dbe08f5d1a2de4a49affb60f23c7837c19c13d931cf630dddfc6f8d334967e0b88fe92bf9f17340a33b08605fced634e0f6e54027a4a7664d5d29475e6ce738b3e6a8c2bf43d6a2c +SHA3-256: a18b0c0f20c5ab16ae8ea8f7ba5d207113a37cb9128f1c20eee97029141c5a6b +SHA3-512: e46cd8cd24b625b760cb748e30ce10636c7d6a673c3578a6b1e5c94c7cf63d5a771ba2065d347a249b44498f045d8c55288bfcc7dbfcef516809a135d59fb40e +SHAKE-128: 6268ade4d2edba105002b96290e93d0aba4d6286c67c2d113c679146c746296a9318e6036561291e99a771eb956a7b6fa0dc35fefe40e6382dd0b8ca4e64430bc3d50e7361ed3f04f3986692958ed6424b41bf17272203c3a7b90fa9f919ff28a5c71143fd290a546b08bf71ec29ca70aed60e4bc751c88aa132e68739781295a29b5ba091210211c4d4933a438ba0964bfd0732177f14424f22e817ed568a88d6aba4cf775af168edcd4b9ab06ea4fdb2c4ef876cbc0324b8da3abcf94e42e98993472793eb9e98d3c153992391bf58fcadc46993a423b8b42812e6ba9b6306116c1452d78465b055acdc96549b6d82b06b5721be08711fcef226335980eaaa83cc152b513bef3b8efbd0a7a851dda835ef80f6cd73c5084a15f965dd4782cdbafc112baf732cce5e1669dd4f3fd51d0db2fb3369a7fe2671cf80bc677274a54653da2773adb72dcdc933592fdd290e8d5d701fde5e34cd9b4599f66ec658af0f92edc8d4c31375434008d1333de530eb7395267b45ecffcc300ec01982ac3a8faf1623df28e4b14b0d975c2fcba23eb1fca6fbd9ae1ded5ad4fb6fb9722a9a54ce014daddb7a90d23ef966900c58604243f6b0dbeaa144dcc192eff378ec33c8776596c05a005023845b53b260076ea140a969f1f6974680797ab054a86e37d06ecf7152a16f41488079261fd916ea5579c35ada6809e96b4d8cf6f0e755ee +SHAKE-256: 7b98def75be857c276f6069b4ed0a02fc93df15136073dd1ef1d4b4abc6e1e02dbcd88e837bc97410c84ce40d82a392545eb00685ce520aa8f5e34ff4a50d66b330368794eb06166ec4441e518a288aa1710e337b6d3619a99345e1c2489522c5c9da8e28be9e1fda40c4dacc9dc70545eb02050fdb8bc29338fe6ab87c48a215b773b12bd76cda4050f3cc91c0176860b12b6c18fd0e7591e9d18d29aaca522af45c59f45b3cb65b8884682a567df0b7e106dea403c04f722f6c8e70e6d247a6b759c060d1122a3c226e7975a9bd897cea98c038a889402f6c677548c49958dd8de7ac2756d62ee39b78a029dd8012cd53e55f570cd788cc4d602bc38a7a043460e25b14b96fc80556c993c71d2a5f1c26942c780240918add13d413f435edba8162f06559e0809aa2dda45c005f0acd384b647a575c2fa920a5376f39aa4d8ebf2ce8a843a4aca30edcb7226569905833e0db266c01fe61ad43d9ef92111c2324bd6f9ac85cde8d8b6199ab35a451299680f834d9c5747d7b9eb4c1dae2fdf1c82466f7a796a15afa5b43e12f40cdd042326f5ce5d34a9e17303a0e0bdfc1da87b697dc132cc0d8e821b928a41d97dd6482057ae47be210039294725446c3051d6fd174fdbb99e53f20b675d0d558d0e06f9c10213f125f72371a549711198db0d817a26f5fd7d98ad3b90caf1af18f8b2fd1f5c83eb0b9d29800c1fa1d8b1 + +Input: b49994a979589e7364a90c3168a499d3cca99d33a2f02c33815b412aaee7c7e8d78675d6a93c5f41505f02577763967c2c536f93e140d475ce1515350b52de1266e84f0d9b54681c0971965cf0baec5da4a01cb72f7981de8eaf98da7f13ca7aabcc1b61dc00292833bd8e27da1d5f1a85e97b48c02241b6f9bbaa0cfd343485b318da4bbe96adbf7f42ca4a5b907e57edc7f168c3d42dd6e6e58450c08e2c25d7a17535ff6601345d0752406bdd0929e02bf461e69aeea4ef55804995bd1d117eb98e6fcdabddb5d58360c5d10051e057c533b59a2d04a79b0747f0249c03258fc4a1b39a91f54e67a093e47e5f1920b5ba00d9c5472977bdeaf9e7e3e61cd2546a7d9368eeccfeb21edefe9601c6464af4fa073a59833b39cbd3686ce1e55e6b6962a0bc039de97b37f1d1e3117dd2a8352f25374c98b900e332011aa2dd17aad7963d1b3388861bde7ab57d5eb8f52931133c37833cfc56cac80e8b1d1e4ebc8fb70e5443 +SHA3-256: 6ff2d8b2e81283f01758814d7a37fc6de58a0428e89f7f4cd56e72b4dc7adefa +SHA3-512: f4076fd679aae1c3ac4af58400872fda0d6349244b830bf2033a5187993099f29055d87f0216f8cbfaa24836271d823066ad030210362368a86c3322273a9994 +SHAKE-128: 32f719f88333daf261eade9b59e570d93424a002dc813ead1cc9a20699e6c805c36c6a68321bd9bc808586e560c49b2aaacb82e6bd54990d1e059c9801ee492d9df9fd07afd91ac035b1364cb03f7719f200567dcca86a6adc40a28c5b9b13879ae355ed16c3c4cbdfd3bebcdacc9239c33ed0ee5db7b7b02e40ef4e7437007d42f247e8ac20c117ba8f4fb25c9bb491ce2c9ce8045d09d3ac2ed153af5f0739e5b2cdf10d2a6e2bf479d9a2e6474757bce303e4eb2a541126a12528baca0920d1d14872163a0abdbff13b8a12678c9244f96025ea7c97f2ec33057a6e9081394a7dc62d72b0ebdc0fc32e1c81037ca0c08c815f8a6598a2fba5d4379da1189f987887c9a01270e449d4cb85a5d1874709cb7e8fe3ed7cc23112aa51cd27df17fd92b9fe2fd8887310e2268f8b54ff72de81c0299ff984baea5ce8590be3067648fde25f4b144a1770a9197ec798cba4d092f847af804cf6a87a581ac48ed42610fa0f8e4cb4f6e02b4cf7c3de7ab500ceaec645f9cd8c58e6cc2e30b657c11a9d518023b86ef39411cfaf2482bcdc445af154371b4be5c33a3e9f28c57bb8241956b6a0cd058f75c763edf3badbdda75d5d917d18570448ffa51401e7e8a44acf217d901e60ba371e0a82402b661b77762af2cd60e833e6d49b55b45cc050cc0249718736370d3616c7825a2a2828444f6d596635e7e34aeee15dcb828aa077 +SHAKE-256: db9861bf49e41992811a0a671f68dae0f3da94ee063b2c2f3a26d729302312a8a7871c7215f400ddb8008c083644e7ba96d19c381a4d354f1965313a28d0cf93ba3dfff44aab2123ce3a79b1705b98c0d3511fe4de1d3f0e76ac9d155a25ca607af61ab1c63cf5538947616ef5bf4a6aa3ba6465bba54df46b2ac14ff64725ee3636c3bea7056c06eee23d67d15d88e437c94671b01e1ecea55e9c3ac35bdb79eb5cdc147d9be87ff5e9fb52f7b7d3a5bc86048390fbaf8837f575fb5ce8b55bee040c1c1f90fd1f389a802da596133d83bd33fed6818408fc5e722da4179cc34cbd822f09c80e6a3fd263c098ec7d71dc99bbfc7cb9b542e3b6d558e1f7ba16dc14d8f6675f94409675d6bf669818856f64f30ee4425fa3fa39f43792456bfc47d2e82ff6e4327df384246abfa397033dbb6fda454562075f1f3646d8d5f1680146cffaab0af88d93a130668148509b807940f6eadf50476e829f168b1ab968414bf1b6ed8b824fe09b43a5b51ef5ef05bdf35da1c86be978789f1108bc151f3231f3f82ca7f13c03ae216c360b605582fbf1d8a87954b074ea2c6d906ab506a3c49fc3846535532059520dcf99600c82d8472430507a5c81c0c2b631c3952363793b9c55767b8057df4b1b7847ba69c11b3b7ea9400ca2a1792da759796d61b0299397ace012d0c37eede54d14c45b894d3c7839c30a59e15fcdb2ace1f553 + +Input: 6b84528e3c91b21a0d393d7040cebcaada8d1f73be40b2bf8309b41e25210b5a3013f4d09531571317aeaa1eafd266b603b5a356ae42ef4d59f5d91436dabe4ff01a68abbd9e729eb1c1d712c9ff1df783961b3d098aa3c5b83dc5a2c952dc9b9a8d97fad618240e7b7118025c6694abad6cfb42855245a3c15a5408697a38bed4827abb63a9e32edfa7be42455dbb720903af6c4a27d371d85421f2032f0bca5084004dc4e4c1489f28aa97da9577be4522a0b357b2f3794ee755e209562e9ff33677fc56fb19e7896a71f8cb99274ecc1fa909d480d67e4b1112d48aff704b42f06eaf9d248b61c71dee5fedfd57d382ece853404167642dd70718d75bacaa5ad87c9f0ffd11e5980af896c242d6eeb840ef07a4e5ca854ef270b2e4e7222a00c05d455d43188029b7b5c02b3593b3d44e58a2107aa36ddf63c8700ce9b9155b8ca99b981c2211ba770d7216879030c333bb268b29340cb23121df7609914da0b24199acf7d4 +SHA3-256: 41fbb99b0a5dd5c5d6fa9fa8cabd19188f69c58965ed05f1f319025df3c52d49 +SHA3-512: 9594002b41e7de3c70e12a97b3d33396a9c056b869137cd5048522205276b3f4adfcadb677984803e039a79feef8ab6b4c26768caf903a3aa8b21c907072ad8a +SHAKE-128: eeb112de75aa7847cd1a8b5c28dce7364c36820209a75d05dae6b2b8144710df7a858ee2514f3b9f7c9fe179c2a3fc9b7e21c1cbc0e20b2b5e9fa35dbd610dc79645e90ac071ab6d32f2c711bc1dabf03f25f095ddd7761004c014ee12b76a6d963004d5ddee6d49dc75ef2e33f7b42a5bd4a0ca62ef10ecc8c4a4ec578b4a9c54a4f22f781e8ec32107be43e3b7187cdd1e9f49f21f1f78ada8e979d162fb33c05cca3306c5967a7b3e4d19a5aaf0affa88042f70ff4b75c8d3ca93a1930a6124b26e7fa17c07ff44b02d1053297e139a19b41556379b4166acbc2b41d4fc572753fde2a47ca7b46f152a927dc1ab167ae00bab215c8684a9ae46c06d237399ddb6749d3e198f692c9def055a4e5671c067bbbe359ec9e49ade22b8191760e709cc35ee8546fc1b1fef3fcd7f704261e5b57ab3f6d0d6753ea43e82abff2a3f6e2ddd09d23608413b0b508f290902018c3782d870b98379bc70a5e9647cfe15d67b2d25ecb986b7dba880ad9ba748eeb7840f3d30fe0e0770dc7f77b6232041846e5bad154b1002adffcf893b3ae68398f1f1546bae803e35432915317b82616f0ac7c4c864a173295704353b8b39b94ae2fdf11f9fa1b182ba0790e7bf842b23bc901afa2e4277153b3af80fb6c411e6013d4d47e1cc03598d5a2b8ad79788f27d7ca33dd9fb34319dab8aff50b329d63040570b6737cd1f7b5635bd583c89 +SHAKE-256: 2c69dabf55635955c472e1a560c5826d802da7ee59e31dab55a550734e3ac69ea78ee59a60bb8da7d003a541b0d8de0ad34c13bb244654d4563462b1b97f77f5969cbf30ca21b75896854269eec6a792f5d1bd4058a571916db8ff196f4b525d304fe9356d6f4885d19be09f0422d2a140e340fe2c3a7674ed97d5bca83bdd52397c0cc0f42a992da1078cf68a9837e9ac2094c29403ad52e10bf82824a830be6e1eb54ce690cc0bb069b37052aa23cc0960f42c29107e2a64b7faef3412d6e40d5e5fd7ace4577e104c89743be94f9fcc68cdf1d87abe27334815aa0498c33a96a503fea0344a9c01c93dbd4c72e6d59a899359bac8aaf794ecf9d88ad9ebb1f3ee0f2355fbfaa6883eae0c5fb5de6adef78fa7e86499a4b8ea2352a256cda01fc02be095e854cf68964d8daa002e2093ec29e85f13b08df39548f51bcd78e158bf7f0973a0f7db3e572a93fd116e48070e193d499d93ddca7abd1c467eb4d6b517b9eb39fef87b60e3b08df1d5de8c283fb860f51db60dbb57e9ca95ce7925ec1464e203c7a3be44d86ebe3ecbea49a5d535e8c756f2d3a6e5f77e61b02aeb1aaed06859073f2f3538ba7db6002ec89cefba0529dbfb421e70d0958dc67b18bf742295e722abeae7a23f1521339c7ac137dcaaa5899d65b641c331b09d02da7a22582de1659d2ddb0a81fa26f7999ec3ad8c3c92e0cf1d95decb67247ed846 + +Input: 2055e246530f6e1780cd77b476baa6020c585da2daab1ccd9e41179f5b5d9a1911c3630a0dc074874c2e96459a8e62a7ee86054d9c8a466867c0a00d76c1f2bf57fd3e5c18d9490c7616295b94ae18e7561b61419bd4a1fd6bd67269f08773e455e85664567e541d1e97577e7ec9373764fdca2373a073a9aa12bc54bece937c853c2aaa3ccb2fbb46f9033335d8cbbfd04800692dadf44972e212c142bdddd5ea949b213303037e335e2a9e57c4a1827953439021ac2d3b7462aaad99b378f9de0a8a6770d511e17128a885b7cc90a2e41bef5e9173da7a5cb964e35e914cf4169412bb68c6db8c12a8df1db1908a10c0445ab0e60f3ffafb9db4eee91330c45fe713372ffa648f3345cb9229787e0c355f6923646a5f4edb88d0c39a104bdfba1430e1c06f7cef1ef0086f84622e38f774f05c6b672bca06c9335efe0a17dd3441a58044597ccf5402fb580ee0e2a36ec41802444dcd8fa555a463996ffd8f44df76bbf0dc85ec +SHA3-256: 7341ff19f7b0c2afa7c66a0ef9cbe0d734cb20fef053908c06a2e8a28227be94 +SHA3-512: da146795e82b046d736dbe86b3e5cb18ccb1f06fc10e2a07feb667339b7067136e8612797bf90f7d76020865c41c12a826498d672cd2c635742ed980282d23cb +SHAKE-128: ec0891253a89d47dd76848bbd00705021fa87baf9800419d31a643247479afb49a7833367caed5a65fdb53e8ca87699ad590c353c5cd895f5fb93ce615136d62e815cda143fc04ea9a8694eb6d3e710b7bb0dccf152193bee1d6268e6eb437cc9eb80301a02fe7aa313d2c2346646d3081ba7cc2bcfa94dd0025f9367fdcc9bf9a8efdad7c197e6dd96086c13ca763f4ce1835f10601ee158975f7c0a397ff26cd79f4c754b9cfa3680c79ccf111aedde065c700cb71694e7f101ed6d33c2b6bec8df0b0e0b6bc1a8d6cfec5904173d5432615e7ac57331b764caa4b564774db2da78dd4f762835232ef50c5aadd66a13edc3d523113671a13ceec767d8185c39e957e5a9dda2d9b65fa68d63c46d7b907fb5b0275d2720bc95e4d01577b7ea72b7148a0d030ce1e3d31024bff631876c0625788fd2718e1b5122c5b91fdfe28fd3bc753c02c298a3df522df12a49cded49ee283685cac5377faf99a2cae0521c823af47914c08fc68344cce1b1979ffa07a65cf456f1a365dbf46c4d4e9d4b3b69dda19c7145f0903f64c5b11ef9634b1d4750569ba5e2ee0eb24bf0a546d9c04e21061b9c04ae894616c89ba7b3d8ad616fbbb441ff04eeb71cea0b6cac70b089eefe95e2caba70f2ab7cdbca20e49b426f074e6fb0f876a209fec8602b34dab5cc7c82a3ca91b66881a28f015eb85711ec0d91ffe8dabfa10f6c4c4a1994c +SHAKE-256: 4f75025e677295e39e8fb9a9e4b53d231ce1ffdcf723f49ea6989deaf8feab166244193bd4291e469feed9443065aa478401f3e8c2705ca7ffee6fd96920050fdcd40e80b002ad9902db7a9bec1e8aee0b8087bfad05036d5f2f5763cab58b1df1b00f11afe28fb0fe2eb3231bc375d19b246cdf0d6afc864cec1513556ffb71ad74c9de657a9013f9303a571d70abb516e264d587d8a95bd87c690a57a60a4118f49d31ee5a4f4d11dfed677a29c7281eaac90ba98fc6d1b50c0168fa74ec2ceb297158650169c264bf4429735131ca3b48cc40ebf2e3fd947c6928b27df5607604ca8bb0fcbca15638f090d3fdada71303ce2ae5e84a1f4af14c552c541ab9354647d85bbc196384bb26271a138d138619e8136dd0d22e4a0287274b2258e5bd5e2a9958de70a26d97e7b69876f125527e07579c7720ffdcd08c068fbc69027e33a5e1b210f787477d46bdb7a3734d9c404afe9c034f5b734d24ad608da2669c42cf58ea2700ffd60ee80a9b0f35e8fe8eb64e1358f7ff4751cfee4bd49c9ae51021dcd8d721e1768db00d4526fba42ce2d2929bdf346b3749c833df2ff48c85405cec843ee3785daac3e519b63b9473919d50811e827044eacdc174e35891e6c917b0f06ac4db65f5f6331a2f457c52ef0085ec4ed1b2dc085267f87c93be7a518f7758d983d5a9b1a6458288425497076d8c46c4835378c12bb7c408bebe + +Input: 0d437fe03c456e85b1c31127b9ee903c63e740138fff16625030d3da087ac11f10bfa1b5110a201c5409d1ebda8b2f44a8a156c27fe6d6d7871e7eb89934d80b43ac2d0c8d525f034aaa7fcc1f0b989eb27b2144dfd7623db1180bffbfd3b51dd4c66f33f0003210a5c19a52e0b6184dc1e49a8d6187d32150cc5cf42d0dbbe2a16369c5e2324f711e889489e40757e1855f36a1d2a3689cc9a1df9198c9e7095f12c56e2c7149845d9eec980e2ee3c2909f9755aafadfd54b188342d19f4d61615238ff8d3f978695b44251726cf6f12c6da231ba64b12fc5f23bb9354db9717dcc9a9c26e19798e74dffbe9030cac53979bdad59ad48f39961e4793fe8617f8cca31e18d33d10a69586e2f4ab59b2f7677b88355dfd53419cf9c333b57788b2b9e2f44edc16bd11072f99bab25e89bd10243dd4090eb0000be3fef96ecb98339e75ab3228a7580ec5e2bb1c72d8fc0fb7e0f16e42fed547d37bc0357058d07c8945bea1a30d70fbd +SHA3-256: 6c0be55984a5c555d7fb89e5b2ba06077423adc324d3685b88eb58a9ca10358b +SHA3-512: e16fd08c234fd6d6cf07aeed8b75e5425080bf8b40259446d21c12a2d8f2549aa4fac70888af9fcb09e3bed2345295d03439aaf7df5e8a95cb87bfa719666026 +SHAKE-128: a8ea6c5a4131950f85a08f4d02006b141a4f4f43454b405de523810f001b32fe5ccb76294aeb5cda44ff89aa10cba14bb22507e11b8e252881123e83c937a5703900bf2d764a4f221e90c170d326b66f42628b929cbe9d263a4a36fb9e659354a413ce782b5785eb1fb3b5a60ae67c02e7da620bc3438f2a3dc44fd56181f797c0aaf9eae1ce637f11ff2e276cd004f5bd51f9077deabf7c01906440456447baf45c7860ac71433d24adae1056b0b375e099a6f6e7e19f99c14a5416ef875a46685c1148146298c40f5c4bbbbb38b188b371728f2c96d0e0a1ede3e0bc71972e5162657947783bed3de8c682453553fea584f2626004d0e6510c9aefb9d76a0b1757217bac4b2e86fad318d5f69ba3dd8c495869ae986615955f95b367cec7b7ccb81b1b434d08e77f9b64bbd5c0acad1337bc40fbddcec249b9eed8ac76875fc584f6aef4042bf06c58bff3bef785681bc174481e24a36e9d8f7a5599063af7fb09364eb8d3f25b6b9833424360ec7fee723f752130ed7634093ab5c20a9ff67b42c876bdde372bea60c08052a91dd77a206a2801a729b650dfd54edce5107dbb227ef789c653cee3ace3513f1d1e2146ad02e28f9dd642d5bfee96d3c8df12e643f6151568e553b50adce04c4ae412b1ef04a3411602c8f6bf9598a5f45e72b73c9769b57b9f228c07fd4798148c98cc0b1238da9abe3d62fb097e681fa971 +SHAKE-256: e43c6da216e6581b9f0ee8af42fbc7fa5cdf47fa339073bc4082a9b4b15c358d9c3d14420c8c0baafcb27babaf717d64b41ae739b1f13b024d09f48008a47d2c07fe3b6b78b93c11283d329f70d06702de0fdb88957e60ab253fdda6d2c5b1b731d82826e4597a1b396453bf25b5be65216c4057e8bc8d8b241091f2606a4723eb957c20e0bc451787899052046835a4a6482a21587130a70c9fc6eecda90a13efe798fe114c64d38c6d63a60ecaf7c1e945ce827335343a50e33914c7e5537e4e9382960a6a040b62c2b88f45d832328e7fe91df0a8c760371a148d2c1c755c65a812d03ef588acd909cf7b301a24f353bcc38a234c5837d8b38bfd4e7b6ed091e8e21f540e89f829842ddc21e79112fef481a19319e7063e5344ff7640b43465246d4afe665186eb1de796b07b3325a7567dedb43580efad9856b7e7eaa31040f1ee5299acd7d258b18def9602bfba9c1bb5499c33544b7e71056070d36cb15a778d75cf947e89813256be883b1d6deaa9fc11cae4ed4071ac5347c813462be871e81b6df4b11122fb21e63d691c3c854206d7f2365b904b170456125f9494b1e183d6206181124280550943dd042ae1f501e7f21a44114952186deab362a907126392c2b6b136f7231f697ad8b500ec1954a5106f4f75ea4e1ab282048139526f31f7a64932d2956db7854f1cf33b4782927275e819aee4e02a0689b1108d + +Input: 710cd512217036b40fccb877745314cc01b77cebccae192f35e14ec76e58deba05acc816701d64308a210f782c7b4c648acaf56c7024e73fa1a504c1faebec3fac199e3af7f391602bc0bf57a3dbf2dd97757e34cde6629cb6ecd9213e02964e481bb8a7637f6f3a07832e8974b4969a32b06590661def82619c453fd1f53aaf75701e011f4366184f599f009a3642c8c43fd9b8dfce4c6f7ca309a86b663418010adbd6f8ffe53b6ed7294c76f611f321b631d05f533dc5a8abbbc1db382f1aea39c02afc432452484b55cc1a17ba2adca738ee4eb3b3d30f2739923ba010daa78aba4a88da976e01782fd1bca66cba4dc33eeae4100daf2d4465711f5854301159b322d73b86d5aad66f6ba90ce0aaed8c86fa09eae004c7362814cbe55188cf8c4f7c44bcaca56b9a3f5139ab5455d3d26dd237898d6f5b83aa930a6fc9819ece36884700862a59ff06cc4dc03f66a1be2bcd2fa6ab0a2a919f1e3f41f9768e4c8d3d4a2fae1a8f9b +SHA3-256: 357d8f0b537e0e1392ef6f5f3aba661a1ac06ba11dae7cabdb72d6f866e1b893 +SHA3-512: 52b6f1015d222103016acc3d27262e069bcb6d06aa84814fc8787d081e2dd69e92b662e21032d28ad87ae966e41a0da916084bd3096fe4a6118b48c38ecb1c4f +SHAKE-128: f750d174e4b7eb8c650ad3fcfdf1c3d61a049f36a77e02984ca2bfd2a78d9692e3d2f965d84f70dfe88f42e7c043cdd8f9c4918febe1eea1ea6030a92802f7227f8cb07f962d23b0a56bff3eaa1d072b437a074470e1845a8d8b37d4c1a6841a00881a75455067ce3e679d4442d7f51787caeb4b5fab9677a9213d014ec0c69ea3ebb8b4d55b3ee78860e34b199f45e5a548c81bfc689507efb997a8fdbb814fcbbeeae7bf4d099d72e0d7a996ff1e875004e364a2bf7bb66a1ff1af2e63327c320fcb9d185f9ed9c8e45b67f7f127826462f042cb8fb8b8533583b75f0a54c7761711fedcc593633cc1de75a1144353de183d280a89842b31be1fb70752bbcdd53f557c7cd003bb492ae54b0a3a865c7e4f3c159be652dd76a805af1b70db479c0a5a71eabfdf3ed7902506715c1cc981bc67fbd26eaa92270d274e043cec5d00909c8d283effd2c755adb4afc03da248a92bd6fa22177007104b1860a2cda30aef3b551da3fd65f76dc0e3628105980200612a2a41616a82a1710940e7539494909471ed5dbc2e54213328abe4e1559c54ec452d95c88584162919cb8df3d965db11a9d9b2d44dfb3ac07278292708b00a4a01ae22f7b422283de8349337e5f90a296d3e1e444f2e45c33267c8cab487b982f944b1d589380629870616773f77ee2a9f2c0fea2f2a6b0dfee5bffc4d1611bea08a30eda090b2424bdec88671 +SHAKE-256: ae3db5e77b79c338dd2174fd7024b70ff326c33b5e03867969685a6c52a89ea3d416a63617b8776c37852cf900e36f4a30b82f866dd5286252f35a323b21b3edea52e5590726d73bb38c5a3ff3263eed114e6d801307948e4a1a99c08e0438ad15f435c4cc2c7c35a017fe7b74a3837331e5fb2a2ea67d6d8e55f0155e36f694c028623b0c3b469eac9f6f44e8bbc4749e912057a1b9c222a8b65b35244998dfc9f14ac0593d3a90376aa74000c1dd115cfa8f3ac2aeeaa1cbff060467cdc8118d69e195dc232e3c34084698ece4738aa52d330648282fa7533b7f8f1602d1218a93ed5dc45b571f2d59ad77ed4ffcbce0ba518526e7b5037d410bf93a46905ac39776e28d32bd62a0bd959ec17cb0088da53ebb8c64f5517d83155c2c69a78a9362720becc8ec69ce6fced9078db433db12745be27f351ad5972e97bad4e4a5dfd83beed239a3a74a30b2ce47bd24b478e37423bd9468294714484db1c69d89ae18346b1670931874486d1c93ac9f24dfc41e1bd6b5b576cc5692b6e9ee90593ef03755ad163106cd071589f44d1f4b893cec2e2e3995adcb8d58bf763fb0ca91a775f8c6ab274ee9f8f17e2309c561a75745a0247bd3fa4aef52d1bfe42379db6c2e1d2de4b15a2c0a9996bcb7ecc46e99da0b99f9ac082dec4889c5754fefebf0a74cf1dc072ef314b5537f142ea22bce2a603ee76844759c4a500a3258e5 + +Input: b4932cbf47ae4e31784c9d2e0d343d53b62ba90377da1d758d938413b14298939673cb43866d99b901cca9a2f11b40e427e01eb037e58a3849e880e62bc6f868439689cefda8ac14d3396d967e43a77ffde594abcc96fb5f15a1fc752583c273d111db508076c3a07dba67d5bdc07e2790070f2233c221294d8b61a20c68fde27182ece43b9bf55d7dc018e158388443497dd01f486e47923b7130c79f6d49392f9273831a465d07d35e2bed7237ccd8f28a648e8a2f52e2855bb14be998934e8afee14f48f8b6489cf8bfaae8216e9aaa0348171e6435cc1ce517c233f1edd3ba472e817e35fd23a93dd63a5fa02075022070c7819bb3cf66d008f6fe67e2cda14d836419b5749a4d4bed6938a045d7062ef4a75d19f5f3336b799cd3b2f3f2b04050a6e83d7f683f5b5c57ab63288f8f3316a37a70a6324f6726289dfcb933fca1953b02d13205e1b37766702d472ed3bf7592f846372c0ac9719d09ad181445b7bbd04a74f31c9e36c9 +SHA3-256: 59be679aa585afb04d991db4ee1bae6ee47f2db092a82c3187b75d56ca2309fa +SHA3-512: b31d536705b711d66befa70dcfda750a121da6ad752c7974b8bce4b06508843e959548a16adb3ebbb940c8d2bb6af9f77d93fd4e4cb8b917bd0ec1079a4aea3a +SHAKE-128: ed5035f02232f4342b101654142f57fa8f062b16272204667287965f1e2ce47a587e9aafec851d71f7ba2efda0a9f862b3375475347410a246f1eacffac53228334eb429d659ca817158bdd430b44e2fc74d42c0763bf32f0c66e78a9b695c8c4c4900968757f2c2b9ca08263ffa37aba31de0579ef6a2a5445877dd1090996db7819a2b5e165d20fdf825a9c6665e73b1f9f60eb96a9b66e0234f93a9d0e7171d0992e955bab8a9ea08499b199d52afa1f30970f969a97701d470147309139d3aa0ba49afc927d06f72d3e6d79e201c1885ce934c930b53c86a552ce1147cea3208ade1f36a9b27f63be4c2be46f9f1b5112fff79dab5b3697df09ec4c56614cfd28e0c435a0c07fc50c450ca9a65fd06be9ae90c0eb87c4fb8ce45dc687b784579093cb59d8e30535fa605fb6de84a2981622a19ff5898aed7ce82d56644e86426e5458c6ba64a40726a705eb51e16a150e2dd4dcc7c16c3c432ceeaff86ea6c4ffb61678d3e558b96d84b2c69d3f98eeddb55418fc654bf43fe04c84822a9d5fc1e150a407f692a43aeccf29f58460bfc9aab92c78229f5bc95fb201dddcffd87591f1d9d2b146310382e6a7af24794ff1d16a88ecb28fb837157031fb7fffdedecd1e0602a0dd1e701e29e8ae3a083e85030c6200a57ff1829d64bde316e6231b2d9e3a27d36116d286c78cf1beb2e2039534c33268d97a2441ee8b08380 +SHAKE-256: 592d0b0dda85fdabdce70eae293c587755c716722ad29039d2710e9a62edc9a35f36f77d3b5e298e0e795d22af1fea2820934a4bca5758998851970f01dc089a74c1dc1ec551e0fe8a2bf2883d6e1770d2531469ad6fcc938b59ece406516031cd8343cb21aeb68600bbb55ea3e7ba428a89669c20b03d607e70daaf24f59f343704488f8cc1bad59dac442a955fcd0e21a49fa697230e2fe546f57e1140c7e34486ddf971617d2f89f3e265ae19bc354babe871a0465ab1583195eebf5ce5f6428720f10270647c7823cbc0db102995031c99ca5226c206786c277e6e3ec5d36fbd605dfa81d9050cc725d045c9a0ec796c30bfa4e6e5abf588ccff47f2bf570fb87e194c84b58e501502bab04844cacd545261c010fc25f397205382b3d345496fe13e6a8084be0b1f3a6b850b0c703d6ee40c63c7e9733897f69e8af1c33db3cb524faab13162ff48a981a17fc32d8e900b6b0f1015c009d1c3f5862291712734be9c2dc5754d62284b372ab6e0417122254191e6d83d981714401914eea4ff5a920ef2ff41b8a61d10b2bfac36079a336cd2ba85614462bbf1d188a8bbe4484100b83375d7708a2e2088c0f4fd43746ece2f8753ee4e1e5c795367fef072876a70dd15027bb0b2b8763ea4d3a6579c55ea58e030a73c1997133758e23d259e50b94a0e975074a6cb29ba1e97fa4aab6242d9788c50f8f552fb444cfc9728 + +Input: ff41e7ceefe8067419d94ee62d81548b71d4d4b79e096a1cae13efd163fc4767fa0f54a9c63ece8608e9852036bd5538a27fc475cc0a15f04d95cf553123df2668dd67dab79cc77f32266966ff1eacbd180d79830d78864d7fae65427fe57b2330f64c7a6bafad7db0a90ac8774fbd3118555b18552f0006dffc490afd2c3d96012724e3bc5b059c4a9115fb70740626045dd2759443db5a871d6aa9204aa4b3cf4f823d00f428efdac01000d60c9bc5e2185ed6f1e95b37466674d9334371fd0a454d1ca98ff6e9a602998d6abbd2c8945af77ad696d6d0f9276b69dcad3995136849f323d7ecaecd1733cf949e35076221144998bc07e42cdd91d587882d23f4b424377e52f960ec74aae61fdec839e13fd598c5883837539506e65890b434975714b939b9b113656f8af65ef142f22ec74255748c0ca1d68e7335935af3bb90bb6fc4ba1a56b145114f869020ed9a6cc9463908b8ae6424b3e82db1975c83123672fa273f846deebcbf48 +SHA3-256: ddb885156da787ca133561b8c5b7cdd6cf60de2b63d10cdaea679ab05dae1a41 +SHA3-512: ece1d6a1f4a8bd44ca1fc1bdb1707c9cb0ddcf230a6dd85040a2c277b6102c44e3a5da362d3bbb7693c3f2d1c51881fbb5f92cb833c0463a5838af4253d326ee +SHAKE-128: 83bdb49701ad3d050d0be5e45e97d7980c345fd7118ff2c7260d2be63247bba70a23dd8a460af5cff0092a9e0515025e1e249094fee81d17ea69d927d87dff6f2a5f88e51008a016883529a3f9b8503c49b65af545bb699e34d790044e754885201422339d4f9b86049b2d9d0281d7b0a07d2ed110536fd34a2d474682977a68e9cf6a031d7c9ba9a41e985e47b6842374d0df17be3f2ab8ff1c362922d1aca0b84744d1aa195a97d2ef9e61ba9b7cf7e316dcd1297b510537230692fe0bd836ec261f1057343a7efdd734e4f5f7a5d8a9d0d3b7d7da0cb40734e3f88bc5db0c736ef5ed5ba3f722f8c22782ffcdaa4a3a88d1a1196610bbcafbe2969cf9b5e84ab281fba2d9e62f03a12c2354bbd589becab5441c41a6d058bbd6e22de69748de0faa7ac21da1549295505f282cffd53f88578220fad3fc3b4e04f49ecc2ec919596a26b9f44ed8559c9d5a58c4a436112f009a43e3c7137b6a3929126e501a2293c13a861db9da45f758a772aace2e993a6ee5f308aa948a96b2a2f2bbe8c5c57f881348f6d6d357f49ce6b5972007c78fedc77d50bfbeb01c9dfb95d436dbd3b5db712aa56aa81fc99487f11bfabbbc080e40a2720e37938952ba4ac90f3e6e049fede15990fe1d56555bfc0144dc54b30607e3d02f017c0f3756b497a61d87924776c1d88f132e72deb4b10edb7cdcbbacf946f891b24af2e1496533e4c9 +SHAKE-256: a94d06cc13940fbc4b3eaa011c4a2f5723f784194dac0b23aa62300c21e00b9403656713c5cfa08d03e971aaef3cd9320dc319602472eb3ade45c75173a3d4a1861e82529e8ef03a8941752739ad52c4af01b3b07877d5ad6866053e45ddff6e0c8c3aa5ac5c71a4052622338742f817d59a1e788d467def5c55fc9d2d00e3337ba40561d39701b96f9d6c77ec6090a12577298c09731c65274c875ebac30663edadb30ad8a301f87f2ea99a131789272f9a630a47a9060ab5079b9f7bc1351f4bf1a078f61d9007500ce4da0f2fede68a3afdc95241087ac68ac84a1eb5796196cdd32366c48bef950f95f5c0cc4dc61df7112e0144ca76c9789ce46f9915765ba409fa5c27da958c55763a0eba2f32e7a606f912b7cd95d6bc7a8e248fbb140ba3bb3e6641dd2026888ce9ec5222d2afa9112a1975882a147cbc3a19bb887f15cd9257e3972974e6f3f56972e50ff02470ca39bd8401ba8c316d436ab4723b371548d966a7e880b5e486135c22047d21d6ed60905f029457655b925483617a9d98469c8137e55cfe94e97d1e9aa8a588cee3a022a60472332829527ac7d547e4cf9453eb50dacd1dc0810acf30a14e367ae5e0d04932de3f44282f5d760c8dbdb4b51aac9b502c3ec21c7b24bca50426bc7a95b43a01fbe06438505e6c81b256288595bdf81fb9dc4758c0cde7a8a7702f6dd7c12fc6004d5b4dc641747edd + +Input: 8472676e0e14f5171388c1698e46e2a32ab37708f201e7b5246f28d2da088e7574bd6913384fd861981154c584f639ab4d209d7299d9e161afc733b32da761c58cbc7c8a3ec18ce24ec49593a5c9a1c54e074ed9ead07bea7ebe2d551ce41f96ec32b3f70875d4c3375985be67365ace8961b03a2a641bcd139e9bb5aeb6f6d67d3a122a1aa2c1a2e4437d01d38d1ffe35364f89424103a496eae3ea6140253256b9ece36ba074e8d95793c03e188fe5a0163d48e9d05abfcc0b5dbf237bf263f47fce34644160bb3b3d6d5fba371e651d270970a71c4c29f3dad250ca021384148d07fcad0922671872268f085fa185a8918c12ec35a34525a31975c9c0504849678347be37ec37141e39424a45b10dc311ca2b1df3cc762f60949ab1e4f75c3b313ac15db02982ea4ed04de69ef97729173e55d9759cc7397a0a999fa7a5c9603693ebc6545edfc0f3239e7f8474e6f72794431de14b83f37b04dcdd2b40fbb9b51d9190f7a6ac8f817a539b +SHA3-256: 468b2515d935d0869521b3104c926199a780d34f30f56505291bd92f890e79d0 +SHA3-512: e41e1634754e107dd270669ad30f717ed119930f26528ed8c5acce82c261b8905ef24510a8f112486a730565bf2aa5fcf26fc9c735731fe05e31af49ff808ee2 +SHAKE-128: ec40140cf78c90a2ec2ba14d9b357ecebffa4244e59c6ed5132c803245ac0f8a722e42ab92222e5ac1302cd7ce4c3d2f7d40810a7713a22157668c95125f87d0b942ef27c814799046b1220e9e9847a9ba0fcdfec75ab7409cbd21aefee7c2753747784fab0e183719d177cd3de93c425f229264f5ea60544be0fcfe7ae450b5da9adcbb9bbe8f0f670aa7ba6529cfc51b6393718fac8f4cae53194c2ebaffbf9269467bae6684b8892b8799abd1674162b3ea264b2beb83a4db4bf3dd45a73ed51100701bff8ea2fdc658805b55eaf35333b4d82867bff6b9fe186fe5132128eb5a92497d0389d70533a5f215d34a22c62d1054b9668d68f671f49beb7d47905d1f5ff1c6c43007779188ff95280a7c3af927099d463baadb7690d9979abbf522890960c2c3f4ea70307ac19af6e6cab88f0b1d3124d7e44dfdf5df8787e651e396dc49fb6a49edf75a14dc46e57b9570280e01814fdcbb352a4d4cbae4ca70d63f446c5829caff791b26c38e8d945536c81600ad35baf4542f3fbabd20770e888857483d97f364cc9585898cb05ce186fcdeb27024694d830a179eb723bb14bb263b9e422b86f976bc6f33ce532a7ce719cd40f74c77f0f73b6bd89cc639da53e4c1f8bb5be8fdbdf78f2cae130d2f27ac3ebbdd22ffe7e99d8d96a66ca96bb66c1c636429a2313f6797bf1c5d71ddd5f83de434e5a86c6fde1b73a7b87316 +SHAKE-256: 01e5119b2f6058a2ec0a4ad9c431708242851d44fee1238fdf5f7e5a20774e649c56bf4dd5948d856c863de621f46a84616cbdb20b191749c2f0413ef4108c5045dc9d1fb01f0bb480505f2fc2b5751a4bf6f167a268507d605c2ce8a8167cea7984907087755d095de2892258fcd3e6dd25ace4359958d1320fca906fada17f7a592e63d44617f4776091b10955b1d5402ccbf8e11c623f8d72089fd5872b32e63962d1b4254993612c7c07739c689cfac0f838346bafc453e49f95ff6854e5a281ca71719f7a7b1ba92e993e23d955887bfa617fba7a1b0c4f139e25ab4622ea13a98435800f457619835e5a7d7a769fb3ff8c7195af28a9407bb53a29bd469bd54bb39d48225d47ce09e8cdbd2a0a5ee705ab77b50a6f7686c19f27c4a40eac29c8a610b2991ea81e0d25c1798a97ef15ecf5c2ea84b5a4dfe7d75f1abc14a1a4e96303021a7b15353dd16e32b5f246b73235260758909e4ddf8f9f7ae0d90b9390832f9e5172e5c98d8c2049f2e86702a2d0c0d45bb52b1a82e35b48399b332f93934f1e7bd57de9611dd24add5dcb4344ccf942e361e41b3e4e002e6238e02130e005fa30cff8d822deea166f0e36dd9c4aa0dae10fb7b59f291562e0f7a9dc81830b34319217e6771699a58226dba67efe76166218501ece0b67ef55676c04d88f292d39b45bfca9c7916cd7e1187485801f5e7164dba27168ef6ea187 + +Input: 3d5543f7d2bd5a24d45d961345899c0b75295e3c4b9c66d0be3cf28e4a020d39eb00b228ab324014d7067802d8ebbd9f8f9df193e87ea48ad6cc115971aa00c78f1a5de4118ffb45b0796c51a3fdc155674f8c88cadf2ac33ecfff1256e1d4cb92dc58180fa77c52a3ac6ea594dac94ef95d29efb5f998e5e687294d7752cc6c59d5c003854618915f0e398577fae58c7aa1538d586f263e90ad0daf2b5ccfb9e1a0eec6fd59b4b9994749b3e4d33be8e78d9b12975872b447a14a2cbcb7f59a57cb5942bc96b8163d6c738f2c86b436b221b9b6b6368f4af519909fdd0ae3dd1c1862911926725bb61efd57815b09fe980759edb2b9f02d73cc4f6ca8510cd3e5c01c09bc15b6141f76dfecabdcb60db8c99f017dbcce8c406da45b75909a75f9b6716f20fe474afc56cce5c6e20ccf1e09e5516b17a3168b1a4e664c09c92fb7837b21c964995b38c303d788e03ee7391a38e6bbd27fd3cf1d41c0e5afbb9e47cc928f0673dc8fbd27888874d1 +SHA3-256: ae38b8caf9a9b6e8b6e9ebc1fce9e5126ae0642d372a57bc05b7ff2edd1e91e1 +SHA3-512: 188cd44ee8aa6052d0350d7511e16ddcf1c8e062f43e8796f3c896570fdcdb8a0f021bb98707fddd77578998f3ab45509a241ac809a922509fe99685729874fe +SHAKE-128: 34831ff6905375401e4f122ddca2c05536a8a4a79c382b179ccd4b5b97db244ca69d513543d2eed6a6be5fefc79a5ac3098c4c375b9f9c27e8c5cb6fa5b9ecd0d9103e92b0c1d8d4c9cc733992261be1116f5fd89b8d3f60bb5c58a0a34146e0285da2717a730f5bf7ec17d5826fb7376f6a58eff6a8c6a6aa6348a6e735a671aae388a1111cf888a017d619bbdf067a6eaa056690691b85435c5a42016aac9502ca314316724f7cd9db25dff452b2d9010558ff563a4aff7faee31a7bb681d59f285e29da0a3c864eb72dad54ec6c3aec23bad69d5534d3c9ba52f617867728f705dba937ab1707c1a886e8e983b0469a4db18f65cb47df07c2bcd0c2fed91c50a11e8aaf7a61c5feb9a6debe89d31d11c70e3138962529ab4351d1bc70042ae3fcaddc5b5fe711c1ad6d4d1b28ba808f3e7db91764e19ef231a9defe3573b2792a75e13ec0bebf35c1ed94b9901c9c62b5a8561150c870287167843ee0b69ee4226c8acff503454a24c957eaafd4e94d5cb201c4dede7027f55f718667baadfe3007ef87d134b5e499268cbd05bfce752c0d7c2d6c535e9d17171421eef1b00f7dfedd864f1a496dc0a40ca0c074f58ca944769a2c0b0d6363d88621f1b5a2e24990cfbea603f840a30c96c4c83b9823f4069d3dc4d45db3bf384574f281b4cfa8a58c1718ee348643fdddbc1fae6028cfb0cf91a8c5c25eeee07a8617a119 +SHAKE-256: b869f7ae351b87711367a931334a1065067a601482cc016d2399c5d64e33c1fc406f367dab48425e0e882f15a1f26ad82fae56aee337066705529cc9955e7147d269be2309d17c4975c0fce1d9a91b13e667616411205bb8188136e4ed627203c893bb519b8aade93007a30bbd1e7b2c1237f70ce35929801318b71a73f16848c5c7c0e456670931a6306b96951c8b3bbfb5e657643e91858903fbccd9a6b80911cda820960ab77a245172fed854f7571595c09a498e57840e65114e88348a5b510f02ab371c4e36c20f9bef1964c5a720a599f8f05df1221bede09603243ab961098a6ef728f101b8fb84ac8e72725c1bac9ce7edb4ddde99f1d1e427c5d7af473459762ea919a288289c3b4e16ad5bc57c2d65813cf9b5efaed09a42d8820333c7178a1ebdd03213a5e597f2027ff020497a21bf8b58657ed08090a61dae2ac862a562fdb35b572062d9b7726edf0ee465645d5f18db7e2c026beb9b12144911985a5445508a2c1fe6afda935c6b3c953dec3f13b31b9dbb6d37e3b530cf4d729a1fff281e6bf6c67d7644b0b047ec299e62dd328503ab12dc1e5c217d8580ab4b9d2b54b5327ad574af736d2be6506c5ae45bf417d3f25621389eaa4b4b5f5118aefb318de74a548ea8016e8df4f8eb009459b7faae98932b78d57607abb33248b64e43fe30f11882ac4c06be7efddda89e4d1da5f7e180a1838d68ac06fd + +Input: 7f093c2929fa050470e227343eb4a8274a92d42155940d85fbd4fcd1fdf8f1d01e50e43cfa21f7d46e14de288a73fc3553d6b1f201715b817754874af0878ef56a519a37d9abae25508b8db113914664be0492a2f0b68956cdf416b3007015804bdea660d45e505bda44a72126d00680cd3628f6085158edba7ac195c7e4f5bb8d680386c45c5730ce400b1973f523c8f49dcc4c5fadad50b639e92ae64f0d332300bd57aee67d623ef0deb964d80a64f64ea6ea6fe79bfd419a724c5314da0a43dc44423cb308957e9913ace45dfd14fcc25dd37c8af696609b52be9506361e325506ada208a6c61d8729b41ef8eca78c9040262d3f002ab6fc260bb66cf44c25e752f5e7f5d84537b6c96bd6a8579c435027652199c639551703802366739ec5033626e15057d3867608198fd1c190678afbc72e2f7b0bcd2541e9bd9ffa0664544a1f61653e9b06bee3b623309d5fa85cf398fb13246f30d6dfbe22ac94639541192df91b18c1296feddbb8b131 +SHA3-256: d9549743cdb94a921e60f3329856f19492c41f59b7da8e5f48db5c82e2871b94 +SHA3-512: bc09c36b30a5eef73dc56302bbc8729e708ee78e3e7aae2acd5f01e33c6a1cf32220db2b9c56de23f60ef73f47e51f0fdfdcc990bca23a5ce9152299128993a3 +SHAKE-128: 1e703a44d498b273ae99e8dc83267cd30c0fa04d759c8e6df0c3ab9291c2a32b1259892ec59cffdcede0cb2a817c9d5be473618d012e76cbbed9bbb60e750b3d292800c015ef8bae84088044be61dec55c53af6edd24f2b2ff77509e374c23757477348d9989f2becf275dc1e78bb93d6342cc2bba49a3e61ade2a65bd4242e3595db783f0c905542ffc2674336f7249f05eac7df5fe34396feb9f081e4dc33b92788101eaea79052cb7f580d3c77c4344b9fc1d5ca53f1233311a164ae9669eb02d71a64ee27b9574f727e6115f94255257473385efc02c40f513424052630fd50b30e76ef81d93d36ac5f579f38b65a932ceef0efa1316fda43660471024d03b4d95228a1014b1a7023308204c26800abf014f6f6127b0847155706eaefcf2f3c3332216cde3c1d921f34675c9c095bf5d0ff6bd89dbbe96f4067f1854422a1e3d7ce410f5b79c7e6129941da8df125efbf3da5f6ad5bfc408d8b16ad6efbfaf21ac0f0b0b48714e9d45b00d7691da76f42ad5cc94e04e4609dd416f5024296a5fee0c626b58e4ac3ea6f935f03071572bd30411ccaae53b940337594366a0bc1cb55204236ad08ae39825c5b482a3271fd1a1efa430fc3d2af87c212adaaa20c3b20dd9fe4cce80485a6e83dc79d1dc9eb4739e8a7989136e4679de327f46b7b5d29d8b0dad9ea06f59c80935b204ec7b10d78e9ec1ae5ab25c0e5619dbfc +SHAKE-256: 8e169144ac47b224d1d78e54ed095417ecda2307d0cc15770a5d3366ad86b6087d624abae8c62a9cad80fa19bff132f8dc8f586e3009af4a28ec4fe4ddf72f00ca1acb66b00b9f6504ef2be037725fb269449c91ad1d0b8ae5b905dc073f2454c11d41c8cc990bf001c874318378fa967397ba2449c5d01012354237d3145f64e9a8a01354036f5e113eafcdc85881e038b0d16a0f21bc35c18382c7d5544a9880219a354aaaf348d21844d8dd771d6e5b48cf3d514d1a55e6e456cab28a1fddf4d8c42366d9dad236d75f5373e54fc70edccb595d5fad5aec724e607262bdcf2d0ba51585450cb0b3c0602cf612f224a21d4b9a503e1506b52633a5baec5324818dfb2bd46582b11e742784f268948c7d33bc0940060fb7255c39d533d853406815968d7432c5c529a8540e998ccdfab1f5eb58ce3e808fb722d6f3758582f5d2ad4638eaec3b7b9587f633d7c05c79eae629f00e5c31a6b67f0462331c128f5a8c6f6ea5676e4e7a0b2d5949802b4a07e08bcf93f2a8b426238d230e08889ca04e491c28820ac6825a33deb6146cd04466954a713ff8af4d4a1d1c8a9d873fd78bb8bacdcc2cddf776c7983eaad111e1e370662251fa0df1d5c72ba8a39168810bdddaf0a4037dd4fe0709bfcdc6b1d8a1cf24544502417c7a7a96cd8c2c0eee3a49397feaf1655c42ec5cd40ff9cf2a325f78f6a28b98d37bfdecdb652317 + +Input: 79f55736f6eb47a4f6f08c34f6bea1ebaf3054ba3a80692ae16a33af62b72a963c2a47339f57df99cf4b3f2b41d78ea21ed13d110fc097f3aa53aaa665b2e5be83fd22f5c62b63f9ee7f34f399322b5508571c18e37fedb6865dfe8c23be63ff12f117f5d18bf1b370afa431fbfe12edd271d22c30775141f7ecc47502a9f8871d5001ca73c15e2bdc628746c61696aaf3df4dbd6efca1a25014582683ef1d6941c6d8996f710c2711d86304abc7ba96528f57706b31dcfff89b2e127e56582159de8ef5a63def90b9825f5bc5797f7cb5919d5d451110a7cb6d17fe58e676e3b6a2f3089e686af728fc1ab62cce004e228a04f7912558838f90b1ea358394ca872d12f1dbe43be383308478c51628299a99906ba6d879ae8231f2966bfa035f17f4a566a9245e5f48a971458c2b439854d1a0183c3d9e9a5a9c03beda15f4dd66d3e832004221c2f516c2fd857a3e263b442419a9ea7ad3171bdf55865169cfb18dedc221ae11b4f04fa5f074105311 +SHA3-256: 350fc2df4d21bccfe57d4b3fa5ebb4895b34de715e360d299e39f76149a80870 +SHA3-512: 3b2cadc5fcc078f3d246ed4919799b35da619cf8db35ac731e9e6a2ae36ef8061c080bc44e62e7e657618df83607f651c5227c6992f727486788c22ebcc4736f +SHAKE-128: e1d159ed87c02a784fa248b430fcf6a26b7f984046c83c16579b6b3fb2f14b1273a80fdb7d07187e2a935b8b121c389b92f647ce49f2481f944b6d61d763bc961369553e4230d6570693ab95e41deef5d2f67a80b3413425e71767c1853ee25c2ac02cc14844024ea2fef7d55a6c345b646b9a29d81aa9d3dac9e5ddd0efdfddc732b3cf2cb4f603cc99fa8a7fdddcea891aa9fd5e78afa5972502e9e351f200a67ae30e76982482dc05f2aaebb2d42f188ddb38ad27ed177d38af420f48be91cd3b99e228089e83354ea30654b17b13b7cc141bc3d732597f4e74b0e7f74afd9b8a0410a1f82257f548da8b5f41e87fbf820cb8fb585ae62e63b280959c2952bde1c8ae816264f7673ffdc39d2a215aecd3edc47cc15e8cd3290cb26c39e7f75ae57beb8823c1336dae6879c528e7e5cb72b97bd8fb5553b0722544e1aafc74afdbd511ee698366a42e9aee9a51a93c3893e5b16f05da5aa2c758ba0218a54a1f837cac8bc358ea077cdee3aa50056de3854fc9aded4d9ae647e9cf3cc152c7c41c556b08d9d094c109d64a831c7f956926c2fe456aa58952df717721a2ed3b17f0fdff5bdec760ba091b9aec694ce2c1eff2207df7f3831bf22f8385ab2fa70afc78eaa7b2054b37f324bc1284cfd89d56dc693d8c81a2f620b94e894b1f281cbd90602ccb87b36a257a63755829eac9053c36b6a710fae4486a76688feaad +SHAKE-256: bdee6aa7b2eee31398991b9aaf2a0f660917dd34bab28d653fdb005e983ebefb571ae6f056399a43a6af2577fb0a69d5809448067c94dd5e7bb44f80764ea84f02c454057702b5d47ab209224a05facf2fa9b3285f23f413c4f21a877644baf4be368d391d5b63763192561e924f426850ec2e5257e6547d3f0955b607b98e58e8a3ed0ef7d096429a5f5dedcda71d1966e8d23c2e3e6002754c99e612fb719fe0e08b4ab2cd48539be6fdbc4bcc2f3c5ded25e09b5726c2646a553a7693ef8747242118080bcc8b82d839977369ae3e09f26c212cef8b453b995ae4a27b4b2cd555860ed05cac5681efd7458ea70bfe04a75446c72b2f1e489de672a22f285afe519838a6640c241ac49780a4113ea314b25c644f6a603a3d6068e94a896d6d876c05691556f8f6e042386c12f43ba701c5e4329331954613a44bc743a4a456a389dabdb9f4db2291c1491d8b1d822f5a5768f2d2da7af7b3681b29610f60a5ff32ccd68a82e47e6948b4f2a2eabfce99ae6a6981deb09101e13c676dff4deb9790f240fa2661688a3e2d7996636e47c0f7a96533df69a2f07f76f5c9bb0f4293679a45b8239a9a5145554d960a7c3370c3ad2d102d85d90f96fb8139eb060a36de622aecf8776d390d80ac0d93a1ff81ca43800aae57886f187bc680b53aa24c1244ba4d92c64752144b21f4cb4499c6992e3ac11e0dee92fe5d8fb41a35ab + +Input: 3e7a0fda6a530ac6a79b6645f5b04e28e8f27f17274b0eab84c27f0f7a9521ac3644007e3c7ede7f4140966fe107763b1f1d92f623115ffc066213a937b7a527adf708a5e5134115b0d5ee592197dfc9b401e22a4ff79f9316d8689bdbd240fc7ecebd015188a0e2b084dc20607dcd88c5b739da22f0ea862c362fac742068f5506711cf225809538553b5c3c7cc03554dce500aa08f720d58d56b81245ec830de792c3c418f3b091720b2996a668ba187e1119253e8c64478ab988cae8b216caa90256d27a55971e2daf78b49db7f62862005e5588772617b1120d40c48f358f3b2d02ce6201274e3c0308d4e7b64e6ae76b4e9a3d899c87e9d04691ff52461d4ad660c9d582e95cc56ce5a24c50f19d88138005f5ca1d5e1b086065b885933f05848b09c2ea12e65c10b69e821097f0b0b2c0a5eb627e7b14b0976cb67ae52ceafc25b97309c64f7b65f82e3f1c61dd781eb6c26915b907a8aee14669b7350a8e7628e82b633e419fc7a614803e1f256 +SHA3-256: 1c0b5de0794087103a9320d6aa49834db340addbd6adabdb257dc5e9edb29bd2 +SHA3-512: b4d63529d9bf830a5b001ab4ae8fbf7af5228dc07b07c2b7b98e8a21b89700418d5ae22c9182b118078a27c80ee81ddee3fb5b907d56b60031dc9ed12615c3bc +SHAKE-128: dc57451c5cf77e85ad4d2bf4ae79a810708bc252ba6ffca1b1b586320759d11ac55c7ea5d555f4acdcb74bb4c6ca91722c61a4a873046c8f018a15c4a4ae0920b289734e5a3b44976495f2ba4ee97bf65b8e9e42f3412809b8ff12f0f4b9b989de40ee79ad429fbefe6b81f2606d2ef250c0d50ffd2ac8a3be3761f702468acf9af0c2a12890592d66536cc908b5a34a768ea29c57d3e63a395f4efcd4c76b4c188f1ee621a67184d38e7b5ee6d390adac0ef0075afc5b3230bb9c6a17d3797f713014c02b6b9060889bc21b3021e946a5d1978b7ff1fc418679b4f3451608f1cb1aba35d94f078094aee5c89d3c61a782899a6f8fca313de96f7df42b106a87ece413bf7a54df5ab916540e21346afa83a4e78779b2bd86f07d7487af3eb8e6445398ea05375d4d7be10cffb64675d5e1993997beb9e53e8bf555e92d06324ea7c3d10b79b32de2a43a39740cc3aa68b667d8eead4fae011dd54329f8033348f9455d16d9482d266032b4c5d818f2b2460748e7316e943497c927a18a686a21d202790f0efcdb8741cdf4cc0fa6498ebbe5a4943087b94038c398b0c0070bbb010ccfe7b67c6582e54d342536394eac1bcb1d0a11e9e7ec7cbfdfd9ae0305c4b6a36c386f1bed3120b5f7a36f153bafdb6280a88554c329bb25dcb2dcb91c8a63fba7fa9627bec86cbc513ad6a65b42e58a4dddb6655b9a71d51ca6cdf37ced +SHAKE-256: faf1b5d5e774524da28933c3239f1c1f17ab48ce5e5ae28038cc492768589c7651ad97029bed08eab761eb06f6efbe8fbec3a789bc9adf91a9a8055cf480b448cf3284f588c84b36bf93aaa0e0cbf7967ae1b55d30b7d49a9b126fcf38d25873c4264d83fbbb908b8c59c9041eb70a2d90364c018858b8c178baef18da38f4e2136260ee9bf16c6fde1d18164dddbd74bb70c75e6ba24b9a532e3b4bf58497b20b0392ea27fb150d86dd9c66e5d9605621122e6ecf45bf7e5685a1be5d870249b22c19be13699c50b07d8a43d90cf535985c8bb4393cd2ef64907a443ab71751931bba92e7aa0e88323a67fccfdc6292061a39b9ba8c08d1840e078859619363d28ed3f36d3232281e3c3c100db8cb739397470c9a3e7302aa54fdf3f378c58a5a7deb52048c364e16ab08079bbd20d3834ef473f259330df12b69e0e8538661d440e84e5680aa679b65217694174fc81b7a502b4b33245a7b22f7e3d562f7e17ebd170efdf5634fa970d3a94d3590ba7d54ed3b5ed07e8d3bc6b527e89fd0cc6d9b1dc29e3203a18363cb170f6848b1ddb91ca66083f1763b61388655c4607c583f4e34d6f7bc753297fc921a7bcc602635818c8954ba92a8d491a405dae236c33c9d44e487d5827613160f7fe0a5cbd8c8f55e98ee645d4d63c32efcf387ec2fb272f3b09a2a510e61fc8f0d53c4731e9beacfaa2e86e6cde3b0fdef146383 + +Input: 53051b8b4fc5a89ab0c20e27f9f718c47ace170b6123797b82f83d65506aff8aeb2f8217b074310eb2d37d2b8846166ae91713aaab668606253c79f6192a48f0c241175ea161f5078f7c595c481c6c2aa9ab64186cc1e23fb3e5a5ed4291bfc90951b4d501a874656302d3b79a9bd5c913d8a9e58161a09a2c6987b629d1d5caa18e023a8cd2525e4d23f960d74a732f64650837a8a496cf3c5f9b7362fb15c14f86ee30d7f9f4bc91554255bfb83f4c8e866949e42a154f9958d9d549b2f347b332ca54d61a88c22ebc3c8f3db75896bfae01ae250e2c03e9c4ceb9c9fef26947175394b3bb0ba80a27e6ef6aeaf4ed20d5c7657f6928d2e5157d3a6d35038aeb70956859d11a2c5cbe7e98342284e0ece2cfd33f110753a3e7fa914e74d85395235258276d105000903d6b86c2c4a45c42d63343cda1ea676ef0b800932f23f180dca17d1b2a291ea5dc2978cbd060fb1c55f5fe099ab871f318faf296681d65470b4de026e00e7fbafc5a6575bd7ddd02 +SHA3-256: 07fab39d0e356808aecd2c9de72528d3f867ef599e7fb8cbb94051c6385a726e +SHA3-512: 7f863b5ebf33ada96fc5919bc92bf9a65ebd37cb6fa51cb1abf832116a9a5d577d608a45683e0d829cbe36c23c8d30e9c4a1482359de9b932ccd74cc34b74fdd +SHAKE-128: ab93269839b28a7a7fda05d4ff918745f06538bee7caa2ececc062e0eba70c635d4d3dee9ddf76894dad964af32619c2047afd4bff765628814aa711b5c14a4d4d8626a83c70ecd9c13dfc0bacdae25c74183456b19a743fb4b6da6aa4f85266ce807109b73f2bca62f0a5014be736e1a408cadebd8b73c5e2532485a7477e63aa45cd124029172fa2f3925aa5178e18c32674d487524fd9a765f986015ee18c9e1d202f8bc1637862ce57698b89429af882ee687c140b8af60cd1bbd6e5678b58218d4dd4129e7f664fda82a93f2f68624c2eeea319feb934407b5a7d428007154875a63abd0f8645d2fcb12fa776ed9200c4e8c1ac3ffbb165e7138fe6ca9eb181266cb0e98d1773c1c31055c0c356bda45185205f2016f0dbfd4d5f47c9c9cb733568f6ef3752b0fb622ac902b19b635790a3ab32e401fba8c91a1426f8b11a26de92b6ee475678f63a27e59b58f91dc03f80457bcb987a4698fe04c1705ba17dae89096db3f55433de4d88c943ff9df0ade0d568a658ad392105cccfd69d62513f91a4ccae08cbfa07074718717b9777a7105ab8f58a7ee26a63035af912fb6268a1a2bff91e3e4928a75de118fea3a35194b44ff7979722bdbdf12741c1aa213dd6dcc4d714364fac0a07dc9278b2470c69de469698717f541eabcbb2957899fce17fb34b98112e1edc8048155ff5f66ca72b974412cce156b69f8ac8c1 +SHAKE-256: 8dd6e97ce78d1f9157aa7a45bb308a3cf873f6194459454c04d7b58608d472d71444597de1a9319055bbdf499776fb70e9cd1302832f78c3a1e565b91fa3d18d867e6cb76251aece710a1532057de929f1c795a04a098f66ccf047d8e31b75f983b4c8f73cae36d33688556c70a19e7bbcfe4d76cc9a14fdc5ff166f7e0ed34c7f0f8c99c8d08b960ecf4e3a7339191a87df0b97c87488b2019f03375bbf1a39c6f867008e364e417b4a8fa394276e34bc6ebf3a0f784b14fade577016620fa655ddc9aeaf2ecba970c9cbd1f88dbdf1e3ff1c703a2774ce2a5083881ce7e5a4262f38cb263f665d9478efbb5147ea902b2bfecff75fb24947822aaa27fcf1d14eaabefcd9e0da31a2f330bc3eba770c6699133667807f5e99ed800aa3a7aa5d271646c083debd9f6f3f903b81f3ba15773cfe01c3194fe2c6813cda2cbee02e71bfe3f4b1a7689eded73ecfbd4cca9a8bb75ec25566804ed74f97914f96c418ac8e3315994dc17452964783c904a8043e3cd09ec7cce5e4b86ced213c51bb69b37901a61208821ba37721d6a0cf559ca0ab2e25f22f12f4577ddc9265bf91cb5d3dd5a3453b5d5d626bc0c76af20c8ea16c31d5543f5eed64f3cad4d96ce103d1f093e5fcd51bc38bcf0bd12f092e4f2f904a575153c98306269a583c4d3e772574279e717a8aa41a0ee1ad74b1fc04558fefb2d68243c72d4b8ea49139c5f7 + +Input: 1db4d3cfafb94e067507938858fa4573864709efccda1af4ed62250a1a7c9d70c6c30b1e3524e961fc4dcc131b37de34fe623678a39879dec86515ead0683ad4a6a423dcec529465be9024459a097522ba904f1437f01da34bed989a2b7b82b9e9983ff17d241ddb707ac653900f2f9263975ad6e94b30d4678c6b00ac809ac9e5a40b6b0c96ab1e27c5bd0bb8cbe05cb979a340e5f46e501e2a55d096ff4a878d9720ad136d93f6aeeb8b98918843a859bda5a65c73cf38bf9733a56c523bd22eb7005f0679a3c5bd0ad776563bb2e0a4fab8af45c60664dbbad70c3f4f3f6a3a443f85a67c96a475d131f95c3adfff2babed90a5677ea2c8fe6c66bcc06d83bbb8b4006704d5a7ea1173baef6042a826d150e7fb0b8986223afcb3148ee208e670d0485439d8e3355298f545cac093660fae653b72bf3a4aaa6c17d80eeeb289b3c1a93e3ff8e596d589cfbcb5f2869b7cad1dbd3a9e434f51e72aff6ae2e2f10253d333085d99e89e3d3d264627128a064a +SHA3-256: d4e05ef94ddb47885e96aeabf65bc9c53ebbe65d9c85ea76cdb6b7eeb9656b41 +SHA3-512: 4fc7ca976cf3ea1836c15f4e81b7c85031833f4781b4a32eec1287daa92636462bd1547f767257619e4248bbc0a683af687018a3e0e3aa883a339ae93e0bd636 +SHAKE-128: af93ea7701c49591fd65b0dcc4a2f728072728b8e7dce8c06173f481f451a62a8a5054b56e4daebef18a40308b8849e556d646f4cca015ad87cf09ac9dcf7659b1c281ffe7c058f80339a4879146ee9063cd1b3bd65835540b1cba47667e358bce6551761c15374f651dd4eb4a6c04d3c3e544fa6f92911a8f77382d96a0b25ce9f4b91ce245084d699b6032fdace30a1ba21f1123a625a09c5ddcc3e9dd00784f9bc2d8a85798e4c6d51012df6d013b6132e51d030bf85623119889b1dfad4935e1bce70f34db6590dce4b06d264b4c411ae5b17794f1997aca3a982bfbcd8608106c0447d37cac40408212b351aee54a9c502658771b8782cd0c3ecf53b8501f9eb5af4b2cc1b7cbb4f7d949e26cad2ddc9bfe7319ea4ffd4642df066dd7678058222ae76708fbdd12159e8d4a797d7477bee9e88cfbc938c17d148a836827c99edaf3b2450350038d42b68dd8b691082941edc6d5767c720491d647872094063964365f9174b4d03e0407a91398461db6263b49c49745f868a615eeb53712624b342d2d55170293a925bac930463c58ea51622a7023bbfae5d3cd0cf5051ca5fa0d46b73e8c7bddbecebeead3f4d0bcb4468bdbc5e5afad2ab384aab6357e071417b955afeea3af494d6a16acc7cc13a93cf496a0f4491751d340f98f3a2e7eb54332b6e18cc4ee5fb3198cd1830f32702275643df6ab26ce5049c695c746 +SHAKE-256: ed886bba79a7b38bc05c22197b3490fe46c12bdd2488084ad0942a0752375fc4da8df0ce393cbda431f15ea02abd514a1ca2eaf21ebba072ced38a17f2c39a8881f013ceced1b6fa05db38e7be395d0a569b68edff474890ec8f125afb9dfdec83e910179d93362ec483ad30a498ca198f3e84125f1e4adc81b8bad82b951e948b4e8f84aa1d0cf7a32c0d44d40933ce587d923c943fbdbe7c22386a7a65630566dbe8d3a129ee2d8778f87c9ac5e11f083e3f4ae3c92df2ea1b29e1a5356bd0a9c0270a86b8022d480282c17e0e23c9ffb8cbe74cba309f6bc151c607bdf3e55a4d4be7ed2f23f84d3cff1d3a422cb514fb14e15deb3be31adc3a3c0e7c2a70799c4e7339b181b86cff1ae6b04b9952fdfdc1a29aded29a2cc44941bda0c38b98b26f1a0f42d47e4e1bd2891a1dbbd343c332ced96031d9ea91048c504cc3b6f89fce428e3c7865e96718eece7d60d037ff1c7317eb0fcb12a27a05739c50aeb84caf7b609ff2ed638494cb1b65294a817e0fb33ef5daca7260ed770121a8f20ddc54a426c0ff9d996a23400a038b90a1f7b31658e6b15ada3417741e9f21c4767a0fd6e3f212e2af1ec14be99ac6a56f3c1d0d0cf57a8fc9519bd059324d85badf85caeb4d4363cba6f3fb11558ac1757c867c450f40fdbb6dd9d5c7a74ae1294d2f95cdf2d31fd169149220b243b15181f9481fe58412e3266f3c77613d14 + +Input: 063db239fd48d35b4cf24be7205b004e04595611e82560e49dbb5dfc3d84edf8fc34eef2663cc6c1fecb4888e020c587cf0584b5fed5aa657e879dbd26aa04ee8ece8969b3ab2037e5d6525ddabf44dd65de734edc59bcbb729f40cb1e093125ddd035a9f65c6bab5311ea5012de54fb851b52face08e9ac16869bc7c03297c1013facc2c5e41e44e8514ef0cfc5853e64d1ee4868900f8b4dedd19e0b5670dc040c985dd131a2605f4168909479bbb3cd3af92a77ce7b2603a221d898b46a1c9b4ad696cbed1da544d3ea45c2375db6c4855d8be80ed5ad0a4b392de08477de3015a9a591ffc1f9cbf29606771ead53779de65531d74f7993355fddc00cf49a1f4365a0c8a31c318538fc75a254dbb9fcc51664a27174f9382952f0791c753bfd404940cf200283807afb7168c3340407103c756d400cf171efa84ffa3d2e59ef4cae152effcccdf874144815a8bcc9f9e2129306c759da903e512ecb61fcc43c23facee1c8129403d98897f5854d1cd28d9f39 +SHA3-256: 553d970562ffe3b686c6f9af1453aa2c0b2b91ffe9f668e07fdb4211e0938984 +SHA3-512: 117af462be8ab8e8b5d88504208761c7aac4a8e0e66e3bee6516c87b40dc279ed08b14b6ab241fbb7d2fb025150b30da31600b8f485657a9acede8272653def3 +SHAKE-128: e6c75ac15183be41f6f582d60353ada52365ffb43f6cbc9669ac59409e720025adf5d410feefdded9b34ff65f85739ff362cd55d7da2218e1b46d6d484b549f8541c5933eaf470a67f6b4bba6fdcf1e3bf929410fbf8316f13ca8072f03af9d364cddc763826a3c8876555413a008517b91302fa3380bf15a34b3f904fbb153660788954f8cc31cf9a67c10aebb710713f3580fa9d2f2a7e3476d468855c8eb5c60b5604d8abb210330842d40c77294c275fd05af821778b71446ccbd2e00dfcbf2ebf21d31d84fc5eac3725304cfc9841c1a276a9b637f0481d2770b89d69c574cb9e558e6b163182e13a9a1f2125ec84343799a45dd3a3d49ca27ed7a0095eeaac6189a41016e8e2a07bca96320ddbb90138c68af46c9ab23d4a4e27a09a6b6795c4f36121ca7041dab7cb2d573c5bd2780fa74b9af1e7509afcfb9b8202615481f1b7cd28a29d486cd16c04c6bbb499a3788c66fad80bf83b7a2f6dcd636ab343dcce189509de8997ca43150ffcb216b2db81e0303c6710a69fd9732921372daa21e96f0c29c4e406cccc119d6a8776ae02c49b0851af603832d77a9f341b22d5de05c80f3e7e91717b6eef311ac39b1ea4a2722e018e07ec5180b6cd8a63690b84011204993bc3202775935cc263342fc2ba56cbc60eaab55e054d5354bd7daa00199f37e3d218ea39a067bfdfbd922aa264e60d6cced3a85cbc1b9cd950 +SHAKE-256: d4a76ba47fc4495f0e925d79415c7c693a9a0a0148a9d83a7ae9e1da36284780272dceb6d1c4c08878bd1aed15ae6876d3267c4f7aae224485308a687e4b710db5f8d6beba864259c1382626992b4767d016f363425048d3e06b054655dc9b9dd625c5664421279151815176279060bc391635d7f838b998f6f7d69e14f1dd930822751c98d4d217a1840f87532a414f0733bede11d727cae37db0d71d6e734bd1e68363209a518e29cfff65978d11990d0f264fd46c23b4109721ec87d387db320c3582ad254bbd618db27fed5c13c1c46fdc6e8667f5f4ddba233f098c7640b48b05fef4a33bb2a3abc8515e21bcae94ba856857d325dd24bca610e33a87883e2b9c34fc628e95d0e936b0082cfbde06bdadbbd70f11d05792aceeed87e91138bc05e0fda08c49e7f5320d6b8058d40e48a54364f2499f19a2ce4892909c0917f04cad80ccdd95bb702d60666102718f56b606b5759622f0ee9ccedf9978c8ea91137c0f4dc6bcdfb82dd9e8b711a094029cac9b44eb1db64f203b3c0d61392b3b65562e64baf3c1033122bc980ff6f0e7006e67d24d4f383bf5f66d0306c510ba8c6c80e91eb8ae291df7237e9eef366bc23926b8bcc7a02622c8c2f56606a6a6817fcbd618d69549a4aae4a06f29e55fb590f96ff930f83724c1dcc3780f37bde595ed3c476775012e7a6c4e42f050def7c3f31e5c6d3dd49d034f515c24 + +Input: 273af4b52cb785e584f5626ef0c2693b5f6ca3f1ed3e533259ec2a41908af89026647c1a548248a96637c4f4bb965164780bf94c7e19658d6708ac350186a5b9a622369c49926ab3bd52eeccdea6ee373947b71beda633a7d073ca00925a968016de2fa0cdf93c845dedcd860db0b2d0713ff4867706d2131589da3dd075d12f9f4cc0718c3e0e6df3043b7f58350063fe741fa5db4d1cfe618cf6e2f2c1deb46d67b9acf1081eebe8b941f90500180fa90f8fad24143338c46a06b16195a634c92d5b5d80a19fafaa2dd74fde5decfe76722013252496bdf51ca2e098c1a41a9e9f1aff12827e548d37776f38aac556e60ef18dda9a8c3f3bd41b87f8300430c455b6ca321920fb6848e1156cad7eef650be77c28d67752ef80753fbfcdf5ea694f37704544383ff55208f22914adee265e5628f785e66831759787169eedb08bb0f8da8dbcb0860eefaa53eab0cdc4a07312f33ef830e3d0ea54887397f62a4451ee9c164d0cfa544be3cf05c18ea4ef8673da5f +SHA3-256: 415b8161c4bb6c4819ec92468ffd5f51456742a1dfe9bb521480f2f66d83eb47 +SHA3-512: ac3a70eba484017b27826d1b4a244e51e183e25adef57ce868f0d40607a9fbe1aeecbb6d14c4f43b8b4e61ae23daaef16445ca26a014f9ba9ca745e892fef13e +SHAKE-128: 5e14083b9161d5ff585c5a726772814d9178e63d4a3fb18df5c2fb8ddf7a4792b5d5aa6b5f3db662a1a9870e5afa78c8a885b1e9ae260c8a3c97ffe3324f03ba8b8bf9774b8061fa4d425e25c0b265de94d93c9c3f5b645516531c69a29390f930903c988f4f53f6dc40e4c58b6c665e0a8559640faa99509df7c97b9d8e6cb2e33ee5fec3f6bbc00d92f38830684643ee652580d75dc434f43c60c63bb63fd1f7817901b718f149038199322d646796e2fe3ca358e3c57fd521a96f375180762dda5160bd7224c35ddd1fb074a910ba637484f991245fbb1aa4a39504bdac30bb08472216a3c56b146209ffd13c2cf2e14dda96d09bb05c20a815e0da8a5cca12a6f4966668b06eff7571449c54f8143d05c5d711377f9dd7828df1f6f73769f1ec9f0d04b5dbd93f0bfe9353e0be5c93f80be106c708fd949f94af1559fc6131f8b34ccb8e0df5fb21203ed94f9fc05a5d8436f2ff6c7597759b4452f76485e9b5c1b79a38302ddefa58bdc05156010fb6cc1530aae6cb64f7e7d65f5ac4cd05bb0b9a9c73888e643bb8ece017d1e9cdabc9d2d35d8a40007a51ff039803ee6d32eb1e0636be5425269d7bdbbf4cb0ff09efd74cddb3ada1fe2ffce90b91650ac1fa46a8436163d69fb23a591d31eb89e8e0b2f0097dd535444c71568496b5aaedd1000dad3f69f4ecc6eb5d88e939f1048af55bece64871ed1cacd2a28921 +SHAKE-256: 9b30baaa96a20fa770686ff337a11538d18c84d34e0f44d3c12c19f5bcf3bda5cf767909d46b3329cfde7f8018e146691f64d4a7854a6566f233d8a3fd85eb0b31f2cf3c652b741a857803823519afa6b94289dd85a2efa92133320ccf4bbfff1f2b0061b25c47e8e924ac3c99aca1f64f3346087d8545b921234f96edd09b7dc7f6acb3742b70fef7f64a4f1d8dd75e47b5bd802957f1369d99a3884b197e1fa16e82035b49132083876e6c78cfdca3a20f5ea008a529434d37be7c198dfcc60ba7edfac3b4dfc02c0f2c065175455188d633232aa3e060752a8b7fd0e0df58a5dcef5e85aa0b90ffd68b1856d41b74af252c3a840e78451b395bbc50948d7a2299779b97ba312d9dedd893c0aad0b9f59f6f0618c007bb3a9de18df4b9ad0a5a6b759f5f4b99034ca6928e5f3c6666d1dfeaf038751eace2a8ada6602533b20cd4e11b77d1bbe74fdeeecbfe51fd7435b3644110e6a3e2b35eaa21a06cd16731d5515db9354b4efe2a2c7828b0235a623d2c334c8c70f6d196a798cfbe2df2af5203ba8ea0ad4d9bc72327031113885a4edd0bf15a244c6ff774464e01561caf1689092d0adfa719d150478339ed8e927aa9515858bba9e696877e492bc832a601b4d16d51da4a2aa2e0850f8291cda4678671ec600f3c68e83d5bf39eec7bb03b5648b0fbfb58c1b24522b10748151da559cd5b7352e6ef23810a4df5d914 + +Input: f233dfeddc26b55516a7279418ca04fee102752e7fcb74d1a7def07d60cee3d52edc13921a5126895a6777ef439d31902edadc9f5352decb95912b44828694402b2ef67816e36c0a4c4c3bbe909ebb467c4408b2c2ff9ee6d620290e484255d2e0ec68d5c46cbe9897a468319dc02309a32d6c9f827a79265d43568bf439b655b9993d50fe74cd4b931424e0741a99ff72b3fe2d8cebe266060612b26693fc6f2dcd58a7d34d42469f742add897179934eadfa7af8b198a57bc36748a74c374a3ba8d224dfad4a2d5dadadfafdc4e1e2f99e9d4d5b2d60823a861ad4b5abf85fe6a4bb16e2d505e4329ecf422627a717fad1f97128f35534cd318a162c56613a4197406e109d2bc5565d79a1914b406466f3562e0e519f1ec4959ee69602534cbf3889250ff91d3ffd1dba1af06995903fb7cdcd443d0b4428786cced5912099eabb156bf8b53850c92ecd44a3258c2d598eb004421de65a7287ab80aceaec46ff859bdae0164fa91110fdee6ae2f6f6caf633d62a21 +SHA3-256: e9fa38cf69a8afa25a7473bdb07ea88833912173e112167d2353e8a85c3399de +SHA3-512: 350532d93a5326e845b9615ad5c7df5e37732e2c4243dd54f697566778d157a89c5b578cacbe7162c58ccadab4c7e645f1fd345efe3ca648054cc564f6d669b1 +SHAKE-128: 029893aed5ba190c9bfa2d5257c27c05278bd53f1fa9aed898cba91fb62b50baca41146b3dfe0bad9bea6442f7302157e3f0e1ae553d3f20fe7ae0af5eae1d04ab5c649df00ee7c7e81593ef7c590a3be261f8b8f757c7e3e0aeba511351a42ac63aa848b0d1c17e6505153eb3a580b56d0d0db9a7e6f2747d9ebec9cd1e6183dde2433f40223ce79997fc435c3d8cc7f73ae0ddef427f23c7e665378861e904e56ad4bda8c4f614ed1aef37c506e091f1d24f4cf5ac4dbd289180dfaf95deb1c1949c62dc42788e50c135c5334be1a50bb81bfa228caeb45061ff1d96b1850dfe438187daef7f4ca5db676fb4cdca4717d7af3b8ae235dfcba287f950153daffa1ad2782e7f2bf7539f451d398758b1ddeddc20a156029ba4e1f225b3ed0d5e2cf86b36a4c52ce8233fed771053315e40f0d6ae8433c0208042b6200752d91d214b8ae6fe5bcf7eaefbe00edf2b5757fab27bf7cf79bcbc6dcbf52144c9084db89a8dbf8d729a2b72eeda6b95b7fd2ab95cada881c42edaf03f971080332d0a9196182d3781f61564efd482057e8bade64b83f29a503a32abae813764933f889436da8e8f1ac19e8c91521d095fbbb1ac20c9e9cfadf4172a6bc26c211442b26055c557d04120261a5248688297fd2dc034133bfb8cb28b559cb023439224c92ab693cac388c12d0a59ab0f8408529ba7775e10829c44359666f0d259fc854c +SHAKE-256: 2ef6f572076dc81fc29646f53f39fa9f1e581a79e08ef72293f1c53a66b0e52fe3edd90fdc732b294901286f5dfa3e5001c9d3e9aea7bf186203693eb9c0517735b6c51ad6ecd02c1b6252c187f658feec33eaf65f325e6080343aa66a9425ceb0098a5a882bab968b259c7f1be04ac65f72c098995b1ba55f38049461ca17253009acbd75b6ce028cb29db87747417c8bed508f170ee71956ea5aad3bcc1b9a5713a6bfa7c06cb98ed769e976cc9214e185c748d7177db989d718aa1ca476fc2a41660bd9c92802a3352a55154217a2a44fa4082474421f40bc52a6ee8e468ae0ee05d9264a9327c628391d90e77512b81d5427c2fc380e38876713084a3ea46f0e622e7943bada9835c2f6082e6831e7c316f37628fd1230cdcb0394aad6d2d4be0f7075824f375a4b446359035514c9f5ec9dadc58050e396b80154b026477573256be53d86e7cefe387062410ab766c67213f7d3d37ccddedab30cf6c022826680b66e4bf304859a74e3b2e2bb361577a6060912f0fe1cc394b1e8cacb8c35132d998a7ec336908a07c052b061040b1d8c4c99a5cefc71e338096acccf1a309289fa2b65b201778ab252983e2e713a3719950549c64a9bf794940f0b8ddb032de080fef7de10752de2cdde8fba483fcc52b592a97c89e289814d1d674bce5b95e5999e179ddbd8b03fa04cc9cc2342b849855b486cf2003c1140bf238701 + +Input: 6466b51f6591e479624e49209e2fbd595678cff62cfd4a5af9e2f26077396d602f4d0356bf8ad612f9b700111a5128e6a86b10bebb56238992a98867d2f93f8bc4bd8dcd928201f51ff85f200400e19d77d643a9948793e2d1044f608e25315930f8cbb09c79e08e06eeac0d6ff30f44cc781cf1c84a4049609d6e1d447797ea110c561525a74249f999b6fc58e863aa3a514dbbb6350455395a1e766a936e00259c773256bcc1f6fe6ff0b3b3919812932234839926032397473ccf185fc45c112dfa5c0f467fee251260c42a8cb60e50332c273b07f3893c7974f524116b6c44054d704706a829394678f38d06fc7613bd6418de1e83e8d3260647bea6f4d21e111ccb33f9b6bdcecf04ff47d006e31eeec3574cc9b9a8441515296bbb5d5ea08e74f4603ec4f38d98b9b98c57774bf8b3838239f21a21f235bfbeeacffed08bdb517cad9ef8bbc3f285f5956b8e21f1d2844698618c3e4033e1a2d2c4166c3413bdded6b8a30e2278719f9a159527e0aaf34f459cba +SHA3-256: 63518e03bfd81240756a96a681514b0f6bd6742986fe0e92b47b570c15f7a821 +SHA3-512: a7e1f722fbb84ffedd05ceec49c812f8e80909e02e0416be0cdaae37d3470d41bfed8c1118410b397b0e27b01e453bd9ca1cb391fe4e2e0424f242e9852cbdc7 +SHAKE-128: 7134614fc9f7fa355f3983ef4a72fd3682afe10084e71503f0856b37a8ebe18471351d15c271fcae8107b4bfd45d15c30f030ad3c50e119bf20868ba24df8f8538d05fca103401617bd083ab015521c8594a76b368753b0a379d7db7923271127530d11554a389cc0a7d45e708f0dc774d94cea84ab6129b9a28fc9c44b526cfe0082da8fb0b60e83c538158a43c32741326362aeb0dbdbbde5303848ba320f6fce8166cf2a25dccf9a81d69a879eea8e8f0d564e09e3c56c72f0a6f03c9a286ec9981c58b33677df399cc866c79c435dfbd77338d0de0034e14553f85b8c9f0dac710a4c0f137a23fb5f371b7f260923752e8855a9b8ccb9a6523d87574180a57db35f22b69bcda7cfceed087345d4927fd065fae4d303ad8f642fdee9419b492733e84c1bc2202e5cf746989f5cd2f3ba6860835950d0906cc5e8b2e6f2076e15b474361aabdf8bde41c6ff1a48c79ce18d7902c8058f3e1dd277071eaf6d0b3d42023450191b8895fcceda16d7d32b043f8c5d25e8e99ec6d63dca9c38f9f914f096febd752512c93c6d6eedc94ce6b72ad1e84c6f58e069d44b58accdaef9b72a64770683e365e70759b635722d71091a012782f8fa60e7ded07e2e43966f0463ff50f1586a659731999bc8253ad74209f65acbfa004961cebdc0e64257891eaa00172b27db638e5c8e7900c3d2b175f2cbd8a3068a3b59240f28ab65370 +SHAKE-256: 226c7c529756b8ad6a9e4a751bdc8b140b6de02d76a0a859974e919fde99d1f78f379b9f49ab65c636ce7bfc096d5df12cfdd211f8a7b51ba472dd79f8eae9df7313945ad153dd193f7690fa27c2bc9c7d23e944ca4a2a92c6c062b891c4f409fe8b9bc54f91b65b82686b3441a12eb8041beb9780647be7e630772636e5e19a0d84735bc1264129d6da469cc120104ba2c44a471c77dbe37f7fefc01757dc0a2140bab536bf4e43c9f8e60b7135a48de9e2c943f38b2a972cfcca12933eeaa06e370c4159535aa55e8f43c01c92c16dda07e8c10e28035b66334e60c3830e6bb4e225f4f925b9be300bbbfc79e09cf24a59167aef3c2e2bca8303727becf04da307076700cc65765339a24c4d9a2b269cb169c27d1fae981d8963b87a810cc6af1882c2ca19a79e72430be434c6fc7441139237db1cd19edfb64c123b1d78a71f2ef47181752def7187a4347af8953c64d38991fdd6d6aaf80cf02489870e4bc76a6c5bae96a6d4732d42e0a767d99e08c268ea3f2daf34bf1c9da7901bab831a6d51818892adcf8c7409a3691396e1a4993d1039292387cba62311079b3445bafad5b82a8be877078dfd46587464b197a2fbd441e49f0000163232bebd5cea9e3de74287cb8e87b85f6f919e9e2229863ce2f48ebfb4134b967f8ff0c5aff536d10237ceca8c02436706c09dc2063deb3aec39c02abdfe477e42a8aae02e90 + +Input: a3f013605c12ef3625c8eb8b5c22dc37e11ac67d9aeb9005361f3d75df76e850df0175abba89663b215ceaed3c52aa9c0055555ac07ed266b985f39ace2d4e978494678daf3b0b3f00dbdc90288e03668b976d9accf74656f0ef1c6003fce1ac40e7647049788ea01b9dc82dd9b2c0106d1d38d3bef72d2d36577c310a7d7ae3b878c8838d023162c53de11e2c2401e07580066e16ac496adbd10705f848980ea7c8b2d3786b643afbf7b28b2cf432043cc8efc2d4351feb0d44dc26eb3884c399cb5eb6bea6f02ad3334e50ddc30fde9e98418f3e52edb53bddc8f15a447994dd1bbf8f1f36aabfb11ced082888757688b9cb2971f06f297afb68a414cd86a2768fc52cbb6a003808aa989a83e577e0398bcc218cd5844841d5e0348baaf7a1a36dbbd7f84634c27d6ae3a47b3ed4a692adc3b937d11739912c2d2e6d8f4b5c296cc1d2821d65f3456ec12be74d348226ac04fdfeda810f3484c3d3c4fae840ed77fc5cebda2231bea73f21dc0d0a426d1d9550d4de40a4 +SHA3-256: 48bae6a8effd7de8a539b361c3ddc763d04fb4094b7f267040cad37dfa83d854 +SHA3-512: f0e4538b0e0973f072348352e9b9143ee109a8ddb51761ca597ce9f5fa8778d37694e6effd97a65eb782920120a28208b15a2bde181eb5d7627834606363a31a +SHAKE-128: 0f09fb53fcd7742616acbeaa6bc4f633e9899c3ee11a4e0b69529b9366be341851480e7729932994c4a5f0df728e130d3c1e439d2fa3b6b2d25e264bc05ac37b4e4bc85eca32f78ed0f8a4b89290ee587402497172a4f4b27e0567b7a5e4cc6876c042b37381fdacb52688c232e4062a2d6b7bcb63212511f055149cd8bba6d88d547005a963126a362bcb143be51faf068ad6cec569fb705406124693b391caf90871c0c0f828adbb12c1434193421b30bfbc3af46d4e9e645db6675365cc8b222726616101395a4aa0fd22b4c5036714f7de18226aaa7c2bee9fb0630ad63c80442bda67645400568e80809215f739ca4141eb696da726853af41089691da6b5bf57411443da571859ee2401f25985b49a8532546261758ae72d37ffc2c9bbd3b29273672ca72d06ee84968da5f66e22afc03e460e68021b3e193e9fb18baa04fded22f2366ce444a2658d137bf6c71148dace3e3daba821bb79aee050aee6087903461cccb14ca6f7038791d3ead6b37e1bcb8f93f241d1ffe9a8c1e7cd53502d92445a174b468de13cff04b82cc8f2a372397ef3d4e02902366361f9ef2e80c942f25c8f83cc70ba2cb5f2ccea050a88ec5a36aa69cf291e5e0ac263ae9e57c6e7462567a7d24aa295dd3cf43f5e4a6cbe0c9a1fb418465c75ecabb15da54bcfbcd0cc5a264b45d08d08b33ede8dfe22ee836b51f8fa59517c50b93ff131 +SHAKE-256: dee56ccf964425b5bc52bb6143a06fd786ea401f5342bf453bede8f8baa42b3cdff4e63d636726d05854099cdad117112a93f18a2601968eba0bf60794e824f8a90f67c16750fcf931f1d40df040aea62e030fe567542cc813efa9be7b299399a499fbe25c28b2a2bbd884abf1cd7f9d1fdd7c6656f5a6ccdab04e12597364dbf536239042628ea618a63bf5bc7470d27d67e77611c0ccef7d28580c213f901e254630b09ebfc3d17084ad7236a546b5e821ce804ce59209fdfd61a8a04de07ff2df29c4648625303df7a34d26c0ab857cbd2ad8047981cb8a03fa688c4e107433e552d04df07ca3ade2505a19aab14ee7c77d617402c30a06ee33bbacbec35e5b01f7163fa8f801d63a741068d2a324ffcc54064ab00963eeeb55931de38b7837181cb5f784cd1fda72cd7add58b4e06ba8dff08ff42782e851b7119b0c69a68abd186be8ed8ef40cf2913eaed9a9fb7b3e6189e8d309c39d37890d465d466a77f66ccf155efc84bcc23799170e7da83d4a467a663e51a8ffbc78e3ea27e7b24968da59eda37b03b700197847ca38ab0837c134265048cce0eb0cd3335e587455ee3a5ca7144d49b42081781df32372eddd70166c4087d1f92bb1d98f25938ea62de81c99d25106162ac7f0e33195308cb733c7d9beaed748f7428edca5554ec13e4be9d0c043fe0683b7db1638be2f06c470a922303f08c3c918eb6cabc187 + +Input: d7e1f14b8bc81a0719044f3d66cced791958c6dcc78f2994dd572e6d506eedd89b03a1fff42f558a0d9e41d17fba11de88be029ed34cad29036c9da599fb4c4868ea777a23a0f6017fe342831299380b5dcc2e1b3b9ca4dae523058f0f624edc7720d02fbffaef7d1e155295671978e7ac8799daa328151c439c37eb4a21a9bd17e697e4314d804ba51a39e5d487eee5eb1020b51fcf56997d7dc3bdc2d65c6f441dd0baa0e729f8d353d4f5850bb03d5f5bd6e0c7c26d0c7612960b41e15acad0b19b1636ac9d8e9dd6336b41c0cb782cb281bc09f927f523b3a67feeb19886b6e8979c568f0983b22666193657ee5c26a71d4c18da0288e5995673755afa2555c41d7de38ebac02628ddcc84c4d5face88aa1e7f6c04c8c0fac4f9b86ead615af1689c3eb7be46657e7eef3ebf59e5ede53da1b197d6e884400ad78e88453145d5de8050dede4d524155aa5eb12a9a9238977e084b9b30e4f662e2298946718a742f79a205d614eae8785e70f49e9b2029ad47661acb8495 +SHA3-256: e48e245ef0cdde3e372bf40bc5f77dde9870b7b67d6d8812928851bc952c6456 +SHA3-512: 9a6584142ab2c3a76d1ddd49fe5d38319a234e22788528f22fc1535a21c95c23127f68b238cda504a5f3395ce0251968b1a3a50b3918f3facfa5e15e7f49f81f +SHAKE-128: 9a00d6a91c3c5c566482db22ffbe6fe498a8275a1158cd50fff33e6b4fac3248f34df65955a01df0dc1548f8e97e3b75cd4e3a24dff94574e70b90664f002f5d99f29e5ef78b7cdebe7e50b6197d980e422d1048fa7539b1defe20b69290f28ed27b92cb2d7c272c52b020e1fa9c0d393c465b0d9c98f0e98682063c5a3dc03996353646170be1268f580c59099c0fc65ccb1faae5eb09438ff8d01d6370d09ebd02bd25f48eb7dcee717bb007313cf176f38fc0aa528612883a617792f4ac25f50ed094cc3ddebd22ac4ccc008ece7ad943f008aa7394881e36d65b60d96b069182339044f60e2794b04fd047809d3a33631cc4fa15e46d6c2296998277087351bda0aa30e9801c35fbeaaa78b2ce410231f10a76602062d416b44d62a075bdb1ff723e707a42c3e322c20708630dc1f79408ccba8bb05b72a4eaee44baba9383343b391aefd79ed5c08afef24cfe9e8e0cc3ab627e87ec4eddbc59c808aaab5633c40c9e184681e1f8e81917d9baebdb9103fc673da7d3ff037a1ac566c87a457868dd3d64755cb19e9a5d13dd7297f0e5aa3ae157688d571d68aae34ad14f309a6b762edc74b06eb8efe84735ea65d24bb45b935339c45bf1fc402d9cc484964cd22f06bd31173c1c0907d3a6320beee230e1b02ef40d7cbfeac938f3ea46feab31b9b8a74ba93ff927b8fd2ec70dd8d01892c5fca43bc553f34b5f42bfaa +SHAKE-256: cb98ddc5707de770fd616a7b78e3e6fd33fdfce0f8b164032cdc42bd957e0f90a65792052df20b47f1a2073b1636265c122cc8e19f4a592fcf4cdf25d81b244ed21dc06968dbbbc9b0e4791b9e9dd07390989511e1edd305bb75feb975c8a6a1d76da649bc0ec8f75d316100fc584aabd550ace25a64520f17d7a7b2c510baf99eefe32c177433cff1779aa7fbf6ea8a852a743ff8a3078799e82cf26dbe8cc3343104046c2ec7aa144f0d6856243e9507b4acd70aeb77e540eb8aa475a8de379c1e804de9b631dbae1107a0195803d8c8ed4d904e4e5327a5c250debf65e56efa1ae3fcfdcceec17e25bb2b9b4f050d5de7741665f7d362681d86fc31a692acdda00eafe1eb927ccc6472497f5f49cac64980a9ad959764fdb08777340796781cdc9d4b0aa4c482598d4b51de2a91280c2d1a474a6ebfffe770e932a3785abb7f9f94203399b26eafb4ab61f4e5edf74bec771eb1e0c19b0bd03f4f9c7bfbff35295b7c575a79729d1935f71aca546dca1cdbca00f1109d454a3d5c74178c5f457786730031beedb703ed6cc2b976f0b328e06a4f4e19f76c53fd4f8105b5de3a37c73a1b5b5777c2ac71bc88dc93979fb54d04afdb11782c081824beb5c11225f8b6fdee81df9f85459d11a2fe1bcff4c33877a19cac842787ba5c568595561ecde9c58f5c0e748e143adc63d717d5dedb81eebfd2c979d889fc970baf02b2 + +Input: 6a7d45a2d32335609831a01256e6db34c163fd108d382e1004350aeffe77c5bb9c03e949d9e5f68c99de869149eaa8a3a6f76c746cb308264a6b737826a04d7901598c159981343d32c7aede076b1b39c06ce4c7e5398d40b2da05ff51946d73de923b69894a4c416b1d80b8c6a08da79597af31918cff619baefc935ade9a02d590f93f277ca95ffeff465f54bb11073bb8ae2fc915b3532c29f8545182bc8555c00772d86f55347c501870c771fee37e360ba6da3d310ca8f62fcc46d8ef0e21e42ff093f54ef500019f4d4e570acc168fbf083030c0fa955d6820c542ddae8a3b330663f89986cbe668a6cb09bba6a53033f0fd43b0ae780e222d4bb586f083e1c8e89f13c37428b63d8531244aca664b1673698c6a85875bf239ba9d2024cacf893b70785a27fc061f7d9d840692b5e1707f42951f12f35f60726798c9b3a8c05a5cc0ca7a48cdc959cf5e8ce5d9d70996e4e3a2c91e111340266c5745d8c5084cfc411ccea0e8d234b84b454df98353356b56482fad429a +SHA3-256: 2e6c67afec7ee6e031268fbe1d2cc893f408d2057b1707de5d8f526ce5741a07 +SHA3-512: 86ad882feb50b573bd9abe7b63751b30c422cd622f503318c84be34f75d6352b72ffdcdf10aef6cd72b99da24ee72767683c3b004d2a238f0d1e6646bf0b640b +SHAKE-128: 649053433d2da70c980b5112e31c0395beef3781ce9fcdc009143e9064df49f2f2853dd08d621057bef14f7edfe36038dd5481b64842bb759206662f224f5e4d79f8bd8b2999320715766c83a75f362805e4b6f63017b3b918f823d7b422d0854b0728d3dee04d8537c34835deb800baf6bfa7ebf02400e4241dff4e7ce1e1a8a85ff898944897fde6923ee50695206f07badac48564311a533d9b467f9f5defe88480767389d10fcef02832bdfbb7391d25c83f2d62849f0c4f6e65bc18e27de05dcbb8ef7decfb48610d5a62028da1b2abade742a2ff59b61161a238751f48d3adf73b246f7e4f56cc82df2754d2ff1d280e3d62b6c450bff71102522376c49f517913478108d45c9e57f005c7523a9a85ba3e0b138146d038c4c78065da6573ec4bf975e5db9e9405836853c45e2f2c39fd3739d1e9a37932ed7c6765ed31fcc7da3808ef3faeb526085432ae85e616cfb5194e6c458c1a8143ca2421450d935b43110843ff6876d6dc09f98dc6afa42c716656446e3e5379a9ca7c94ce8a6dc64a7f25fb62b7a18ba3ec8f3d7d7e49d5145dd8ba026b441973251c7a71382b09e2123918d6cb2a1eb4efbd6108bfd495d621f02621b3c447ccf177f4915200aa287f0deb871b750c2c6dccc4b037f141c9eb1437c2f6878374f557c13283568669de258d24de9713eab06daa923d56bc58f2b60657ff56a7f1ceb07f6fe9 +SHAKE-256: 9f877e6ff3ba10a62587c356289815fbed3f956d2b6b50a32297db8748776dd1381102fc6e09a19faf73a70fa74533b2532ffe3bf1766eccba7b8feb038bf0a1b993f0049fda18820c11e564806194e585ddc8ff0b826007b09f1dc47d8fb0b652fbb2df2c6bdf31a9130a072d2a2f4cfd31851fd7275e0b7caff67c3ed879d3b443baa2dfc99efd9f93e6739e6afe09e0fd9c6be78d4939f86b3b73f1990b189f60a8730d8885b43a6fe79f7b59a2e8ac3d9f637b268a621a33b90917595e98b56cc2e91bd48571aa50577123baafc76b95ab9e8203199cc34a8b90a8605fd9d563a572d80a574f81bf2b40df34c7632b0cfc2aab34c29e641f54e64176cd18d1502a9201d453d1c6c287fb784729080dc9705de7b90e85386839b08f07a42f606f4b828f757d68d1e4eb33b421a09523bdef1b41f5b4fafef5371f216a15cffce8d36186c1eb3eb7343d480d9dca3a282098c1690c2eddf9ea6416ee6700576137bbd1dd396baa3533c46d0b0cdc5afe1ef46621d4f68ddf1aab5e62c5e8b8cd4b5c9f11cbc41c54b05d735d6c51c36d6b0be28369e248dc32fd901aa8b813c29bcda8b96d3a05116b749938c37b9b5d949ce2794319bcfa696b11e42ecbae993554530a6a404139970270b515ba66779a1848a68e94480689d4bd008d3a386dc9f22af347dc8640f6d0b51d0762a7d43b0ef186811a30a8ab218b618b6739 + +Input: e31ad7bbb43ce2961c0e604e05e8d2f40419a2c9fea01f3b8eb559507ea58e8a13065c0406b4d75cf16863bb94e1811d6e99e8ef8f6f406405ac3342dbee725a5a2dadfe482a94f2a17a20923c6bc5538f587a6c5c6d60907c3704d6aa6c8751df99d6319216a133abfb421d782132a71cde6bb6e4dae7473adf060f3420c6d2e18bc433ac88dc9e3b2338c72f870134638b26eed220a9da5fdc1ef059970709076eb1375e670945900a679720d23ee5c35f033f915e27339240c722dfe88b7c1e17ee676ec1d3095ee9556f39fbd1e6f5634a974a7bfd4de9bd333ea24a9ffb89ef8c5b5b57c229b747fa3a69c53eec0572ac560b86528c964e9c6dc6969f76815584e25250b6c33bd4947449d66de617bed688ed37e982c6f0710d6df76b6fd9a7745ef21a5bd010291f288766323b881a231de8671919c33c5f70705c158ed85376d24198ea9f69f915efc334637e851048779e302fc4044448a3a614fad0849d43efe44d2f07b82455267d59ca3ef6ce7bff2cbfd13bdb3a65 +SHA3-256: 3d66d13a8b691114c9e3ff869d47c8ead189d70000d460a0529ae71d875a1720 +SHA3-512: eba2b4a9678d1ef7c75cb634f8a913e077493e626ba07a83cb0952d914eea5ad6a8547fe650b23f92581d0f273891da6d040eae3db46914320b50e7311d2cc7f +SHAKE-128: 2af04af8d4a578c4db3ad42443c98246790d4ea41cdd53260758ca04b0238dc63d59eef7b661cecf5323d3d215d9d5719be5e758f16496ee5e6a06902a968ab7c19c273440d430630378f95767f9afae7df7fe3245ed7d297233b5f184b771edb2c54d8b347f77bcc96b448ee4dccc16522e9651a279fbf6deaa33dd9de9970ae624dc913bad3a9a572ace599779558e6ab5ea816bb2612c618a900046f5cd4d69ae78588fd4f07fbc1d8fa808cf2aa343e660a69f83a5ee788e84c8fc9daec2f80e4ce4a09665225d8e5741f90b0b33279adf189b09519ca057c1398a33718d7e4409a178971cb2e541e651682126cf0b7989798297140ce86ad669f71c076253f01e9e02baa22e0161171da06146bc5a22c90dbda967a93f4415fa00906625cbb34ce22f2242f75c37fd063f76f619654b91641428af5981c932d10d994d55c21c2a1d7ecd73fe15e2f85f02f49f9f69097035046d42ea604e0ab336ad6c64e6243feb6459a54356badb02c9975d2ee8ec588af761b44bdccfc3f595ff7f2abb35781f1a6fc22131d452f46980a77625a3acb2f1b2d279b26c929dd85b88e0c29bade32137d7c65096f15b6c1b18f2ab7b68053032f3334190a4b94b6a497ac0ad0eae1c953072a0cacf5ee99f0b8c34148da5fb6ad5e92dfa309cf699df58617e0ff07a3cc6ebaf02f8c77e150b57424110c0a24d9ff2d9857f31481819b2 +SHAKE-256: 85721e53c19cc2f3f3543580d56593945cfb88b55534249f81c11c96015b7beb8919ac98beac721fc35195c95e3f54c9a3523a087419a02fe8991c8de03cdf99f9a8197c1e789eaa6fca7e7a2cd89660f3809127f0c9f0522c1a4691cc720868e07adf8a21d7e1434bb7062fdf9ce7fb4fbc4474c83eba1282367fe9fe5a63a4a383988d55f9a8f1106302a70410e2c69688d01b514c5f7647cb002ff4b07a6a1de3c5552faba22a6b0c87ca3fc1ca06f58a5bf24bb0606aabfc7023a4cefe295aa7a5a4ee661d97695776f79d82a505b645ee1f5074102b64dee4fe38858a1cedada98b86940c8fb1779f5890e46c30339d2d663e680bcd588a714f18aeb5fd61190dba98170b60cdcf9a2e9f710c47c47438b848e14a0437dec2c70ea9d49187d2ffe027164e986db0aff2a0f24fe5e8b45c11b490e2eae8b9f196adacb8f5c0260f1483211e8ea9d564a90171ae564760d00dd77861bb44623c564fba2934dfc02094d9fbd215d9106e59386525d45bffbcb02d4324a5d1f4b45d553eb3efb17308a1014b93c7ab2d9d5dbc2b442c3bc597073f7ae247c2d69a75184da4a3eaa4592ad199c9601b883f74beb39560002ffadf33f3e21010fb1658c284ed9ddc27b2ab22c08f79d9cf7dcdbf2856085975e088ad0f5f1d4f0c3a1763c4e9dde06eab2b8b2eb4dfd9425b51f8471960fee2f101b93e527b79c63be7e4cf4bff + +Input: 7f40559970c22945901fab05555988c6c320091a9480ba748c9f03110952ef71fc4ae9225136bcc96a7ef04eeae9e7644733d15ff7d2347669646bc184669eaf50ff6283883e28c9032030c89029a9bed2fd1c3663b83fc15825b8b50cc1eab74fa6c9d4e089fbec75d744d0aa21a99733b71b4be494771dfb9f60ab7f684e582d7eda0761b2daa7d5a696af8b92d0af4dc08fd7adda0d00297eb54cd727185b9255ac0b9bfae7fb3570197a06c8f53f7f5e7d6e138de72b291d37bf8c1d3f1effa1ac383236175eb69c601b6d297ec9bc7f434c120b24a3c616109b19222598304522d9ff812c6738214fa977d4edcc17980a66a5c40baf7bdfbeefe4797f51e938adc9667840f32cec404a621a34143627e8b8c30121a47bb21157664e5e5b8edffda5fd91cd8adcbe789b07bdd74701544d158873c5baadd54490ee45cda3d442ec519e0744927e0defa092b5bcb5025ac69476a73129476edd14f82598fcb386605ff826b3295c9ed8120cb6761489fbe6e111bb493c5f0d521f +SHA3-256: ccbf6d6a9b4327b709cc6a1686d82da72ef585a424eaed5bda2dfe56ac8174a8 +SHA3-512: 6913b7c1798b71b2587a6100cdc0dfbda6ea5341fbd99f0ae0bf34bd33a137d48f145472ba435569bbf235f5232ea37f0b0dd89e126285d60ae0f9527214aeff +SHAKE-128: d14a615e8b1addf13b0a2801565d11a9f7afb89ec1148f7df09552755ba234558adbe31506ebf56c51325b59a18e2d4b88109a1861063745ee36f8cff7d54975342d4460fbb4fcec2fb8c60e53c9a96ee4c645531a055d4f94cc187a4f16281a0d48d91fd180a5350f30ac50ecd08ab510e247181f9f2af3d51a0b0019235a82b93fb6fba56a6f948cd911b1c449bb54080ebf88f59a3e52723eef6db8ec859770cbe7cae788fab23eb156e1b65d08e71a41d38aee6a14ba278153fbf50a1e7e810d1d7c8fec1145c6280a96b18b93d033e8894f8d576a035d34376bdd591fba70ea48de838ce9db91b7359e0b087b802235e91980b5c5b7ff7c02317adf3c0ab6ffa09f2e31f93dacbc0679bf8671009a8c1c63ffc8b3b9b5a2ac61dc46cf31cd43116b650ba1116aa7477b5bff7d2fb388b097853e95e35f2896aab8876276d89b69394a0dc7b93fa5843da4069341ef20ab5257bec3609e3d8f7b014fbb014ab62cee207fcf699a4dfa66c874e7144a87c289ec3cee5538652a5bd8a7accbca91b0dd5f93643aad49075965736906f2718cef80f5d8fc63605cb9d68996139f58d5bd51411c9bdb6136b984f647068250064930ebc818dbd6d2941c0774d2491e71d08b0d34e42ec4b723e36d9c158038c0a15a99478e2da6714b600666c2e6298d95960ec58f987c2c55a80c9ca255a198df0c73b00971d903ad9602b87f +SHAKE-256: f25d1615ae6931adaa58cac66b0ccc1d2c984b53cdb776ff1dd3227d03e1bb6ff1ac47f99d01d293581c85bd6175cdf02eee17c1e57b4c270709237ea67f97dd871bef897cf3be3f1dad5dd48facd6f1c778a92bf0355af3f24ed93586e5b82798398f1f29f5a34c1b7ac3eabddd1aa5fe607126c8c693e409840ffe968fdee5e3a360737137ddea1e3e29491adb548b1b255d8f85f4943b3a2029ae46d4cce1e14f3bf49c4f3ba7c7de3c062266a0fc0a7c88864392f3d542e1548d7f7c4c67ac19c06f37481313db09adce6b98a826c066c24c6ae015f892bc4b85a90bd2fc74c4ac80b30ad32f4b9b4dcc771198886a1485c621b55be680e2b2385a1a89dd48d7bae87ddf3ddbd12534c74188392902918857cccf5f19ad08b519c061a86241789f3423880c6d61129b6d768811d8ddd88384bc32605511e10b835158d546e1657de9e3a9271194814392217689ea6f2645a1a68b12671854140beb80a1403b8b3ffd27e5d367f10e7dfd5a03fe2a94e2f9c4980b40607bd68195f6583702c04615226cb5aba8e1e0fa251550e45acd6077b1e6226a8f5e50c6a242ac144838af611b6e07b23913110f8456fb4f185126620dcdd1eca962d99ed20fd70ca37574a88396325353ba25f171d08fcc2712d70ad0cf73c82f31f0b51ff74c4611bf86d4a3bbfa429c79372ef5ae01c4df093405fb56200c503ffbd817029b5530 + +Input: 8c389da24d19a880bb42a7085a65cdce736f7dd4f3f5d1bd21a96ad5b73939b3eee5ff3f39b8bfac77c1ce03455650bb41908ff01a7ac5d31be98f7aef9983c36db7ed882ca99be7adbad9924bb1b86599072cae8c3b14a4308c3797c26306f3f2a6ae42668aa9f57b8933d666ac0f0ce7cb1d2762ba1a2db12314a562134a98b56fa9b0d1ae1911cedf45e5b2484ed992346e4de646f7599dea8ebb0edd13ef839aa261ca69fdbcb68004f8784c5900ce31b157010786e96fbd74702c510f1bb11000b46598cff063eeb10b7821b86d84ada623664412858abbd3b10b2399837fb78e014af556eea94a4721286145dbe79f4093ddf499dbe5dfe6ca8383997474f73a3faa7e57e8e9d16329c9719901d65b98cd696913ca5b63ab7726a66fdb966a5a4fa850c245d10687c596af4c272d65fbd460a9dfb7ee14b8430f51a29323e35f4d5d3dcc4e2593b01ca73330701aedae4d4450ef2c09d9021af9fe76fc1e13ba9302c319d6c7064c7a06deba906df9399dd18e14ed8ef9c09c44 +SHA3-256: e470674845cfa5ecfb3bd85eb91825a897f9f6b3d4600a7732854e69e80ca423 +SHA3-512: 5168aa57304d56728dac134c325fd27b8df58c8f4d3dfcab4214eff6e4e203883aa26d8c20dfce3677a99d4f25376a34225fe091765a21ae2f31e6e8cc282606 +SHAKE-128: cf5393b8b011a3a69993f1bcec86f627e4ccbaafdede01d9b387d14240463a57e876004c6b68892b3c7939a193f113cf7f52dc9ddb4f8e538ca2ce7872a373f952ed380d2b51b6d04bba0d0c84d29c7a0116b7d11590a25b81abc9a77407829d3d6697994a650bc0b56221e70826709911a2f0dd9fef45cb2585b2b8571d88a14c8b5a241519d21207399babfaa6b187a9960fb71fc65ddc31d3fd15a11f5022c33a5400aab3cb91a8fb9ead3df4d46d321a4465599200c4f6feaf12f0adef7e34f3d27b198aeb05ae9ea20a53aa4aebcea2aa0fc0673faa1df65228e8e284332cafcd79cc027e67659f11cbc591193d98f05d3c4e512f3bcb790a7a4501d7b08aedd750443789bd79a10458a880ed5bd7c45075a620bb15655fe938a6e7e9fe5feed3066ec05abe53db3ce04d53a6cd7e46f064c6861484c6e26a8f722339d184438d45150657f051323564fc75af91b25b12828a397d3f33ae33615188d4971a459050d4c43e0ededf2ad7142f570e133b7b473228eb4ed0b17ca9496ab7f17c61fd42050d95d95e1130dc70f35497c1cee24ef50e82d16e2f603ce6490f1ff7e5671f4c4b956565f96044658bddee1aae4822e2d74bddc014a71cfd2072f782863f1eecf40ae6a849fcc695225551e81c654ee888e7468645c3ba735d314974b40dfdea55d7ac31efe5fbe38c0a1b577f63fd64f4b086c9d383e8d2085452 +SHAKE-256: bbd43da18bd641c6dcce368753e484a4036d124c1e78d5e9b8d6c63217e6f20f163256427158434f3785884116ed2eebed3d7011121bdc8873876570665269e950472da4e603041b23867ef87b39346382c49b4247779c412ebe5cab7b1ef12e3b4dc4cdb13ea6eafd21990a9beb179e1cdbcc3b97218e30ceb8cc9252f4de7aac1cb0d35f51ca8c517fe1b32a9ab400c9c96f3c76b458ae66395f61115b8f6ea76ddcf1ad69dd5f5331dc304c113c5ad95dad8a48396323f83bcc445407c5aca3c0274389c12957815456a94114d75dab65eb41a283e66284055a9f591cb29578aa5729e0e9b8593db079ad57f5aad8d2c95ebdbc4dbf57f8617ca246320af0617a0f1200faf7e73541178a45a7dee65a14941cd0664e03632e73fbd2e234aff217a1bcb30750ce67e5f7dcea38cc2f75d34d31a2b01ac810265b375ed9d490812c4d64fd655554fa1f29f2778728f4b53b9793d313e90e0f0a2341939db88f410694326bbedc282e2fa137a200b9ae3b1beb6225c3486583533623e777297c69a5737ff24cce06aaeae19a37892f472d772e105c5fee6aec6664988702cb7da6e65ca982e4857bfd01505b1ad86bcd8c2205b9dd051fc7fbd85702c0c1060a58dbd3587003127e55e6db5f3754498ee587e1591c5ced6cc1bccc7153661d0c18e953d4cc2572651efd25627a547f67ecb991200626cf0e33b2b11e5860b4e1 + +Input: 16cba47718e34add507dd192af933afe28338dcfce13e944f3743da80c2bc1754a389eee1949b4fb17f326dc85495ff30994539859b537d163b3d24c75d80469e9ba9b1cb6ffd8631b04a0479c64a6d9bf8b2f65ad5753728c61a48c509cc6d969bdfb5f35223081a874218fb4ef3ff43635cb6e487c945ad990ba2439e4ca5f8e1a6e802163aa3da6426ded594bfa48dc42c364437552982ae5cdfea9a3f6d1c9a90439fd5d514d2941e362cc6d7e767d001dcdf0b05accb9441d9e5140a041e629a16893b7c4b22c2684ff37dee8b5c61a24b0c9385b0f31b7a4567ce1d0303d3e3e13c8a35e047ae7848821624b9f32bed0f818c16b573b9f83bdc412f8a4b682c1879811585b0342db1caa70e6a7f527c83a693a5efc8fd027f21b03d5d4716926be5922714a0c11e1479800f6838a0e0ccb797ac837838cfe8d68f426f95bff50e2fce90b41463a739407ce336ffb6359964317164af107052e998024bb4c8b17eb59d972c1a5248e9f86fe1715ebc020bdf506592a0b0e6dbcbb1c +SHA3-256: 6a513ba574bf90b759f32924f95c19db0a19fe6b2aa51d27e5c935bfc2edba06 +SHA3-512: 417f38d3d5e1185b53ed0f7ac24bdd24d1311b6e5b865fa69b8fd1ad4fbf81ab1fb2001bea3ac8b324cfbf51406ff3e61bc187bf1df8e973a9d23f1586c725c0 +SHAKE-128: 6aec166190764fc462e38c0d9b4f81511ad59e8763ef7b1101afbc718a7f145a06fd9495a9bfc2d5109605a2430cad89e2c2676610fed22fa3ede665451223334b387763580463741d045ef327c91ad9f085ea33ad0bd6e3915b91af3554c11fff65ca38416201206d09e3fe595267a63ec52487feaa9a21382ec818f43e6309c12b424eeec47321ef261f8a4ad85e54ce8ec7a5c0eb3fa60eb4fcf2d5a0347879cb7953da6d53ede146d1525a81e41b5f21e34408f1321360cdba4f4799eb8350698e6d3f26dc8b9de8e5b382b074f56e210bb583ff1e06263743bd8b208ddd6d42ef074dbc55d28297640a25679665f2f09132f737c83139de12fdc0d5e84ab7e0d8943af1c38ba81ac5ecb66ac86fe78d7e69c0f70a48298926981c53a5a4359823fed8aa7c159f5f778c077bd7c44e02ddfe3532657b85210baba709a61bf456e410057e561702ef67da0a93460a5c181b5b948295f7db0264176d289bd555d7e9a509bd491efb0a27329da668e180ba22b84ea3638b7c8141f57e15080b05217a0f94b17791f0613d449b839b55e0c1dbca66df3f6b6a853a4d61fc0679e9ca2aad0a1d82e5702c3450445968f2c8abb9f5da26f0ec1ccd948e0f318b0788e947258ff6ca96486808c049777c8fcd72692612fb9412ac3c46e9229e17db38abdaef3f9d18e991334287068ec59c557a04a0fcf7fe3693e9a87533ce3e7c +SHAKE-256: 1e80473ed498ab1b6689fcdfe5fb11ece7e87af92cedfe1b0f6fe76facfbedc30f563645584d39398c9d809bc5eed39781ebb438991c32482f74a3afa0ac88d86223de301e6d3fb0c664173250d5a50231c09bf6a6a1567b9b372120132519aab643f5349df970d00d5b0eb965f421a91e3e850f0081c6435a6ce5a44f8d2828bc291f2204b9c05b9e58be222c3c99dd61413828a854332593188f5bfccd669a17226d703bacd1bc1d896a4a13c35d02f17b34cc38b1881db6fad9b2e07a9003b8b7e5002eae75471ad867129e3215624bc2f85fdb2377033d9b74bfdc71538fe4659d81c3c4e22100fa7b403a275c02455f32ca08074e44838eff84aaa1ba4ae1217bd4b06e19d7cc69bb7edad16f279121137385959fede1f872ce30bacb6349ca3b5b057e6c8a021d21f20e1c532a417aad6e17faff0dd603f0ef55c5855f976e102cbe17a551efc3d6444f7555f9b35a5f5b83649cfd6993f105d577dcc25d4d1f093a2a15ffe80a37372523992492972aba05459674946e16ca28f690c1d61db4a29f778a55daef66a776161f533361585f34a96f6a502547e0e7dce008b538873a3b6c91c9a61e46e28f450df7e05ff77afdd36968f7cbcb859801ff415240ea6b5b57ccc04e53277e3688e9136ae0a9a3f175b9cc3d9207a419fe93393a18ca02c4c46d25c4abb47659ec413fd8555b7fdf5cd8072823fe80079f3eb7 + +Input: 13626e24e7f6cb73475e1703a0492abde215f508da99c10118a8ffe4a1522a4878a0cff4b1b84c978da82f76412f4cb66d070d8bf510909a7622edab9e6a567d98631e8a51c3b9018c6bb142f5c10b8a18e5b1b97a5092e4042f938e3b45851c6d16bee021444460536f7126ed90b0a3bc0f0b66a5b52ff6688595fbd60fb0ff7201d55287f124baafc39ef6a4fa97cd933f8bdfd4d8ae20e34c72940f04c061ca52f0d883c174ac2537312b2b833c54e7a0acbaba23fb26da34a29541742463d0ac7d0a55685549e494cf5c4eca7fdbc502fc3323c758a744215d9a3bac9aa8a85582b3865e2ed7dac142e248e7f10d0e5a0bc4c1cf630a031c4be58435c0995638ecdbc4de34ffc7679b451298407396b5700f3eb26c665fdff6e4e72fd36c6b5c52473841c3ed23cf5145ffa231e790f8c965c142fa2f09e321e352eeda1447fdff1376d1653d20b4e71b51b892c939badb9fbd186e8dcbaf5c63bc1e46f59c2b0b90fc9d94c14e410b2e27b0c5de5c5180750b0ba5d52154fa756a94bc +SHA3-256: 31afe991728b1d1f659bb611fe00ef10217c00dc1badb90a1f7505c43ebdb1f2 +SHA3-512: d0c77f45a5993348d744dea2e222ec582902d2e73bfdca7c6e9b56abcd0385fe0ce7f96dee837094e1f4392e01d96e1ef10131d45a50dc97b56147fc37ba69e5 +SHAKE-128: a48aa632d6bd9aa57d037a5b3392beb909e8b73e4ed2ff18c6297939b7bb44c633c79cc9d37c3d85fdd1a0f58b8c77174e71d198569431656bbd03fc500f3bb970048ba6cea7fc9a757cf0dc3fd2ed7428c7fa694c30ea77f3956e0f50cbe5aa4656ffc73be2321b20a6502294964246e13e01fe774cd1f9b2b163950a288bfd719dac09b0133c7d30041654728109b66b76ddf7134745e0cbcf741cd834111d18d39fe9c0f3d147afa853aeb415c91fa5b46ac83d767b97a3da147348ad334231c9d64174642554408e28a1cf45527adca992c44788208776c75e066c3a9c3858e56955c7112bb092cb62fafa4489f6834c650d78c4bf19715687646007597a24c35f985c79bb78d6d1bc7b93b8d039a017e597510c2dd60be032fe9f9d18663727ebb75cf9fbc49fa2e5c1d76c00f23f75ddde8d7ece33fa979bb24cb6e581fc5dd76807784e846987adaae31339a99e4a6f88a952d2b5ae5a352660a43e4b9f6257ef077e35387b0e5dea3d2f4c94d4ee70801f523166e215a91c1296763a96ee813c81f245637f8df158fb6f31ca063e70b13edc8d45b3226f832bf2fe626c2540643ac119150727975c064b09ae935d54c28d500aa1a1fde56374d91ca270c2134e5f058e75752f73d9ad22adff44b0046b219408f36007e1b23c2f5d46566f3d0bc04c8bc50ac4c2dd2e6ca3532ba5d7a61e0cdd018b6e0ea441c26822 +SHAKE-256: a9b7f03341bf9354a485e20201c4bce4c1d8c76f5440c74f8f136af53f3fcc03954b152a735e42690058a60af90875e6f075db1e485b5d06821c1c31e2e85d63fb24cfd734b75e63e0615d0b9db3dd1429d210399a36d3b84091fe89195fc68f2e15f66d354562c72a93a543a128f52409e1c3c2a01bc28bac078f2cfc34a659db28a6f7a890a9eb165a31535a2e20ef647c081676be72a136760471ba29c07b20912f1e917a67e4ff2b52edd641bb5c0ce1d857e4b584f8ca5e38ba9aeb9d2c767f11f43b949557972d8b8f0f7b1c49091052d43ec824af44039b63da0ca00857b14090c7a522a7974b0c4e8b58bbc624e2141c3170242764f9b8da4a92713f9472600bfb1a074cdc7e4f834097f023f78e370aa15075370076728fed196d78ea4279c098cb34562c84c047901b8d84922564523f3f2b94dee2425559abc601a9293a0a4a094852736cfd9addb7c4fce42161c2bd31e42b096d4e1fafa89d052a244b9e4f435d8c6a8f8c0b5a184d78d48d5118d64f8c26253e42a81f178d9877b27a47258aaa3641b6bddd8b470771a82fe9f814088d3c3a1d754eb5b3ce1215e94392b23686c9976ae4619b3ccfcb6d68d6edc96c1e22bf1c82569c64e6f2d3243546b2b5cc7662cceb0d177d10cbf5c381347e0775c2fcce6488063fa36a9ee376ba062fed0120143c702a55d86a6eb0e62a1e49bf2866098dea103f01a4 + +Input: d4faec5b5388b6fcf211d9e2f9029edc54a8abf16caf4cc20fff48b7cf314de06433d76ca88f500ce93a0921838a2918322e82244c21fef69196d897edaf25e0f47d430c7f3a9d4b7f24e3037e1580fc390833eb0b872aa202cec873618ba1b329aeef3e7c97361eecdd35aa0719607c761b465725505087699237f5b508993ff6e4e4c252358c26ff9ad12b17709548a685e71857b580e286a86ed8f35834926cbca6dad1915fdb46ba315da0b20fe34be0feda2332fbf47c751f9a026e5b7c895e07fa834cf69bdb83c5677fc2b40c68a2d1f5e5bda92c68fbb0d33597da93a638048d79de0a428c0a4845e007db2659b3d7758e9a59ea45919aa58f9040e9ea1bca94e1a3e6094d5f335470bd9b18b2d7d2ec4755fbea06a01ad043c90e13f07afeb1b571045c050b5c66d08eeedd3c68a38aa5f97d0246186ba93b623a806f0cfad913acefa8117e349aaf894e92fc4c61f0fbc846a504bd0d522cf1d6944006d091e83e9637143c608047cbc0e1f8c20fcd63c426320c5fea65e62460e3 +SHA3-256: f84fa47b820bf7b6d334a37fde581607a86cb80971a8217841e9a704fcc916ac +SHA3-512: df221d43584736e871d43c72fd1aaad6fc00b2af108c07826eb6fdd88e1f9a136444c7c211ba50e70c009a58d925324d2a1f1b7534310ef49f03ad3c265cbe12 +SHAKE-128: 7004ba7b2a6e45deb95e33516a9734a96220c6fefe9d43abbada5265a867e47d46d12eb821d3a389066d3a30d4b794e16297d16147556bdc6767f8aaefb74fd88f5086b097b6d39c5a1da8716e545effda1ba4d369c85422609ac854bde1b2b7cfe9e3f119651825628c9efa9b63f6368d485a4c5a2385eb83c9b6363def370b1c7969946dae468034f09a5688176534592a0c9c7f1f05cd999e015f76cdb23b085d90c77dee43896251574af8e900d3c2612dd7f281ad58978e390e4de1dce4cb9420417d5d4d319b4e78dac86ce302399a05c69179f6e06188e68d45eb6fb864499f395b172915e464064764e71c0faafbf765c5fb1ee253f82b378f4e37410b7a5523f0b622400abaae73955d389ca47ca2f7fccf1b87ebd77e46286d993938808a0244780072bcd2cf849e27a5bc8d8e5e78bbc25d6f963f1d8f23be407b7abc085b14847d4f47357dee77a9c428d609cf8f9f6ddbe61ece39dd8f252a534c401562ee77cdc947fcada36b9658f99f91d1fc48b946af467113c568368d8bd8f3d14990ddc7c370844f7d9740fbc63c6c00e3fb1e5b29831a743f6840ea3adaba0b0fccc0c5622f9d947e9066d4284fe2c185b3900b70ac056b7238d2101d76d05db48be56e9262bdd1b27c651c8931bb7b026bf6bd8d36353d2fc53ef287bfdcb296e3c8d011d79ffab1de2b85879157a7f2d2a9b93029095ae1fc24b82f +SHAKE-256: e9b1f94a4b6e08fc50a7f4cf71ba630a6fef2790b81234658e4e2aedd9848c28f2c2857994bfb8eb7acac04616819216b7eed04d7d6272e5aa8cd0581d005560e418b1fce61d32d6744230a19a59c30163f2999cb49f6b078cdc271a1549a590b713d97a773bcfa654846835f64e2e940a5edcfa11b4b40cdcf730524bdfc40fc5af459cdf497ff888553de6367283ec0ee9ff670b590591cc41d4d8d6bf27072c6c314213c6179facc677bf2d0d3cb4a23e76a98507ea15f463fdcf860648e05c3b1566dd539b7bdd9e7f13f898161c7639c7e6652c1618a3e781c38691306c82686b85602a4f79522de823c1385926d9dc2fd8b5a909f6e0a2443ff412bc78a2a1d96ea97ccf7d730f8e732fa7033659d2fcdb2615aa6aaf604585a604ba7d276ae16c4d541fe42d5a19a17e24326695befcdc4e38ac7c229e870dc7053dbde7cf44d408e046011204bdf6aaa3db198cff29401082ead099dd38551cd83ea72fc8559040449e73c40eee930fb11f2aae85ae60f10bf24a8beebdf71862c8aeb9d8880ca54e97e4fa3bcee97d9cf7659bed111be1000cbbfb1ba4325e50b26b1e46eaa84c0a5943499408dc4722593e76992aadca6ac2443a8d2c138b2ea428e72e214619601a38ba52ba4af291e1b513703f2cfa02acda2b6700f8cb4e3ea54b8c3166591ef3331671ee7d9b07160fba395fc302a306e25aed15ac9081b84b + +Input: 5a1b17620c248080924d42e5a5d0017363f033b148addab4d056fd5528cd6050100fdb0bee151c750782dacfbe25a2cc030a765f9239d60893c569c7e11f0322c7c3f04ad66c15cb1522f0f99de091467ca4c0a62588d2fd328572933950dde840a55218b6240482959cb1c5268a8f103f0821c7cd2d4dd6d40641400566519cd53a56ff44a4fbc6f59475bc06d06a4977767e839eac40227bc420bdb768d370e2d586575453386b7b320d16719376e8eeab38c6c9f2e5063c791e5879cb91e5c3687cff7e8820bd6c4e8ea7a3f18056f02a756a39ca77f101be573d81f626b58c09eff76b307e16441203b40b921c2f82eadcabbd1559b34ba51c10104df9093513292ef1426da6067453cf29e3d24898175735e6f64b93237243e448ccfb5863b8da81877bb0247d0f2fcf13bea01e8ce047c9761b46ffa9144a0edba748551b062d85abb0810e54c2102aee69d1e1d3a79d5ed3b1b61e97822216f338dbc3ce815bb07eb71d2db43894a936350b22a6d56c171aa385ed5187ffe953177fb846 +SHA3-256: 3a89712ca3e44f5453524009158731822e39f6d7b08896faa8ec3ff222a5f5f1 +SHA3-512: f3ce3370b8dc903e093156319b3f248e9230be20a31c8f38b983e42dff057ccbe08a1c88776b1c9e8ec0225e47f0dec7e6943e8efbda7dba552579483e57333b +SHAKE-128: dd5b047fbbf9916b4c2ad5f76eb4efd94a78585776ec72e7aad5a47f78ba19f99b7454bae2ed240a2708ab20dd84a6c1697f6e3a4b87bfa7a49d193de7d8179c5e476913c1d375e52d4329cd3b526fc5102da95de2b38b94c7c10facb2ef9bd4f50492cb1bb81b214820702b8545ab039e416cd684dceccd6778ec66569f4fea6de6061cf8c320c0629ac23b7a3b727cf7e0fc89734fc1f35eaa4c63e215a49b4e50d62e6404235f4416cdbd128c8167401b9644aa6fedf9be19e946678e5d5999e37062c64e834ba0a32688502d9529a33e181b8f489cf38327cd9c834a08204875f0785024ded83f0198def6f892539f93084d078cbf48ead7ec598f42d619d6dbf5d0381c0e4ba8f3a05c75dbd0a1ad9b0a0151c2cab8b594a0fedac4e97268635905b040cb8431677212ce4587c2e42d16656834ad97886eb46db7f18ff4460aee767961e0f5efe625a9c8185bf5655f1f4ab031544dd727f26415eb895c11a0f8d210426a363bac633c5beec765a070455d436e1f21ee94549d06244e0e81a59344bf5732629fed54577a7dd0d9b935df06ce229e711ff48c70fe460544daa110eb5657f9c187dc30c385f35d9553480b5e815d79ca56a786e684b69afceae4fabc4f04652e4f64ad81f178061e490c09ceddac7030190f42538b1b94174ac29be6e04949df0eef20116a4140f911c1f3d3d2122048286d24cfefa82305 +SHAKE-256: cfc83be8cd4d81d74eefbded58e0641ac2827c9310d37863fc14549019f4d2165b4460849260558a5be85ee371c60e46704691b08333b5f748e1f170c85872333ad04bd9f6683852fb1ecc5d0f8fc8e8fdc3ddf3bedd3260df0b235cc0ae74781b4c14c6583067ddceaf6b8ca84b06cae0c9cbff52a5270cfa6a96522c43fcbf24fe71f1a29300218c017c47aea87d076274c2f8f6718e5cbf980d04ef39899114e65d705d38e606e665ceee590996b577be3df02da2927a31b2411f075b01fb7d1dfd139cd21c31d172101118b03d843259c033fe044105aa5a2ee7f9f2f56c85a1eeea7a89dea243cc371bad692aebafb1b858adcaaa2c75bc63e33914149afd2fcf24f5546c854a00fb4ca2029d818056d1dce1f4a3d3403057c49d4961e5e89623e1603447a7d9a95504a6c428adca322f50b044ccd052fa08d36e1d8f6a8a8d16280275c8e2b1bf2a1a12bd165cf820d12d6e177a17cc0951b31819fd0e0d05280a7e4903d44cc22f59a66c57e9896f93e429ff9111195f40c22acaf4b7c090ca94ac0d0ea6e80848eef9dc3089a00c086e7d7292f24ca3a8c89669aff9a627c85d8e5a22e139037f7ba5c562180a2bba5f8966760f0e647274c67340e84bf2c0a4a7dfd41c6d58b274d52141d33de2e7338ae60bcd8bc76c1fcc7d9cb3f4ee208bb369a8917f95b36d6c2a7d6f7d2a9dba19f57accdcd24f54325a49db + +Input: 2db39a02f3662414fa04be05f1c1b1539df2b65525cf2688c51a9ce9089e36ff11fdc01a141e096635e27449213df1c0db794321ff3fcb0399394b5859fdca055eca580e74d130b7cbb0de1aa48b43f3ea40fbbdfde79e3460eba3cefe7c2ece380f6fc967c4ebc7476a84e165ff4bc346ebdf66cbb436aa4ea90b55a4491a73861081fa8a4b3816b615b2fe5029c736d213f84628e55052baab0e2d0c423eae220815634ca7154f61dc1cac59c56b1ecd4555dd1429b34aad48dce477e1bf2441991851772dc695e2feacd66d2c182080dfe4cd0992be60605bca8b4a178b1460fb298cd4fd2404291d0ddcae8627736e0530c3a4cb24e700d90a88a2a75d55cf7917a578ff359077f3933cb00908c14502de54efb2a16c6980feec94435b4ba147ed08910153c2851a114c38757f273add752779568152242b031a968ff25d0e3bf823177eaf68d7524d18dba88cff446f48a0ca9a6c8775f754d328ff3d60eebcb98bce415fab1bf6f26c4b404fb80980f34701d9956f4b9fbfa8e125b43d95e1 +SHA3-256: 19e6a3959284aa4d0d99eeab4b5028a19d504af3ae6bb0fadd4c879bc23470e7 +SHA3-512: 6f3d322b73e366c9e2e116fbfe2df5c97eabe702dab4ff2e58ba8e98ab2be776a0df3cb8bdece3deddb4ee8860bf6a8f9f91d9b3e3009502381a52527b0fceca +SHAKE-128: 8d4e06233d8edec173ab3da4861d240c4e051e76f52acf0e636f7837622ee7bd54c5a0ee72a266ec9d437f07dcfe4f8b3f062b3bcf242c6ba506f777116f92b80ce336cbe43b35e8533fc8fa112b4c788b50fa10b33f3afccc182484dd6beee11d39fa5614e55ecdd17d7e17a69ebdb071e7ce846efc36e752880a6788094fea6403dec3af98b49ddd7b9170edf8119b1e1807cdeee5630c7651db4da2b33e5432bdba0512b02a0b60008b29347de95315e6784dd07e7d7042b47b5709aff29d2f9ae5e9b37f9d4a42dbf276bc078bfc738ef4f33cf8d15655cbb45e8813f5e3f3b2de438a6bb2da2a52630b228f500bbafbf649686dd6a13efea325080440e4f2f059df7528a5c16bf4f1ccd45a2d53ebebec9cc33e060c385052bfb3db1e620503dd8f608629e03e338436bc742f9d8e3a570e1b4753201d7de14def010af5c8d091f27a3d332c3301f96b30df94f90dada1607829c372492768e69cfb9a92cdda1bf56f5d220aeba8e27a121342d4ed7c6ac98a7920cef07f088aab6b3348f9d34b6f330b063fece96ac04b4574c8208479e57bad1e69fb4977a177830587b0b140736bd7ed930e1b2331da9bddeba2edf2bbe111fe07d44b43ae76a684709ef41bee692d55e2c2afb10497dd8b071274dc5387b8a077e85bd7463d8dee6c8bf4d08026ed099ae1d7f92b8db28e6f6aa33a5492cfcd752c64c236086aed20 +SHAKE-256: c6c7d668d23b4b6fe38a2ddbcd7b5f896c9808857bbc1961f80d36ae69e01301727fd719488c980ea81eae6190ff47ad611e2ef7af8a88401909eae014be578b47b7b541bb19af9668baca24716eabec884f1076639a41321378d64162ba31fe0df463b01af01ba8ef7f43faf1a1ca16283ee232190fd8e5504aa7d4c59c4cf191e2401ff17ab605b8da096e5b2ae6f9682963eaedc5c32cb39bae0df1e84d15707f19a737cb80da87e1abff0348984f6218f487b69f0daf78f2f9b132592d256048e9b92bfd8dcdf89d7f5e39b5b4bf8dbc0168ffb39ad793a4ea6924fbdd5525c38a8c5d5ab54d2e5d9c909f634c205be79f01bf1ef25107b7e25861965e183757243b2dd80baab3d247e2fca959d6d12980330f02ee88818e3b37f02be7ec15803472f24a635de68244eadb8259c824c7e390b85ecbaa5e78aed43236b80f45bfaef5a148fb4bd2ac7005e4a4fbefe4662491f3de237e08fd03ef024e46d81dc3d333682e7af14163569446969d5f7f579af23297389d05842024ddc826204cbefab077d1a43aff458095843a8011c20f2f9b4973d7aea9960574f4fe1acec98cd70481fc2bd3bf4c2f79160fbe3b5edd606b63364fa0198e3c0d5d9a3afc78e2ae274343f035ca81c8251e0485285d07205e8d27cbcdb8596283612bc1ea22ccd7aa889dcf28fbfaceb98edb4aba6521583c8aed4edd62f794afe53b3072 + +Input: 06dea577b3a09d8fcae0f83eb084e448c9037b97230c56a0d7c2bfa9c0f02aef3ad17e9440a74e6eeb79a7dc09b44c06ed6e9e84c3077dc6c20faebad1c67567bc198e78f192fa5015585111284c6dc31627f6a344995218415d6e5aab5016f22c96755076c9ea7897c7b801811cab662494dc58ad0fb2ce461665541af52f845055e22c9ee92aa657dbca5250e8c4aab6aa839f0f9740a042218393f4e424e79f06b8bf33fa45e65d753bb596bd088d0c9ebc1fba36b985670db21df1d05bd7efb1ec140ecbd5ecda88e1de275a75ba96146dc6175891cdf0ccb8ac88df6d666e19b901fee624321c7af73cbadf0673a9e4bb518ac2303fb5baef2ea37602c2b27073d14665c9138c951d68157d297ba491f42afabfbd488edb80484e8c920c75b4d9264475cf7a999379ea3823ad9e4c66d871ca9bba1efe8d7457102b18ffd6057a74509490bc189af17348140c88d2049c8ebf75215bbe2a6ae99d2d1e0efc913b1cb8b2b9ca670a2d268369ea57a95890e841e559184b4348fcdb673b10214c4a +SHA3-256: 3ee10b6c9bde66fd26760edc830d24b23a12c9ee90fb845e2e66b61039531fa3 +SHA3-512: f123d185a90bd97b04563709be0b59becdad03eafd4e121f4b49df3ed25e03774e3c61666bc4133fef5779c0b52796041b41db1ab66d18ce7053f4399d6a6e89 +SHAKE-128: c41bf9fe4d41a7608f9affb7c7b08327f7007110a0d254885db22bc973bd50b9a5b4f4033bf8bc9abda0a202571a35033850ce01c6a283a260617a93739ba98d5f88327d0e8128ecd5996d5d47a8f866ecab19e1eb53d10e3cf8c531206d229964bfbcde6c4fdc38cc1086e6f70d1f2c0df0345e4e3eb7608eb398bfc4c68b99723e94109e605b43b2928c2bf0cbd222e1907e1f92bb09d84288d4c9a4a603ba3d14543bab5229cc5ab6bf4a6a75359d5973663b9bb868431de709f4fcdd4db1eff7aa4b1a575c0ada85aacc24e5064a3da89e82eb807643c6b66f3e6570f2e40a7d97e4c73f41fadf0c26794fba6d673adc936bd1c75b9a0be0f426a604f31a55c6ad2a65bd7f149ac8c971f5d6fd74f13f741f5d29fd36d318a021c8d34e4fbadae9256deafc3080d3b73c64eb1c32f73bd9a720ae4d3a6a64a9905e01936e44e8c0f882390d40fc9d3ef644c793ce5e642a8f0ff7eab75f214bea46062d0afdbcabb950d108c4b10f098196ad5621785805a44af9816e619acecc0c6498080988c9a6f830cad1a7877f6f7324af0fbdc6d479c5cd3f33418d8cd85d769cc85b3a9d0110ffca11ad532ec8d23d656e55eab03a5a9b57741943c63b3e7ee4c4728508c8bdff4966d420d0a58c3a3f73b92f0a3b009ae1fb8a8f9538d2a96aba99bf421d73e2d51f27819b22e0548257540af4fa4d31e5dac0dfa80ddf0adf43 +SHAKE-256: 78a94d55c5220197bbe4a86240d2d71d30ea3f89e47ad03a6a106a0e08d1be4006cdc1face4629a7c262c9b7497f0b78cf7abd8243d6e2b743f910b303350a3f446883b632873a1bd3357e533aef68cfa3b26b6839c922053f3b3c8330529fb5374017bfc8c4e28a2addd8a10ba87547df0031481fa808366bb85cd3446d50113fc0e7c5ccf349f08e525fe683a03b0379cfca6a366c5697479cbaa1602cac302570eb7580a7336011d2e9654b2e62d1a8324eb720ffbfc5c6bd3a139e95d574daa0aa2ec52892e651eb2b64e7f8e10b698a929c1458d78d44a92b45d45ebb7a81c160b88c9f656cca11564e7457abbc46e7d5087145e9e37d2df9278778c2c4699982ad709cef3a6b749d2ad750bac745a0ad455fdcc33fb89dce513cfba2df4c7664f068da8130a380ad0fd3c9295d4d54b3e46dd02de87ff87dd35f946b05dc105c15288dff0f113cd555c5ccfd3fadd3210aa728f265f15cc52af6220876901cc65eb0284e58b4e225c133e3a729d8af9876cb02bd71e526507bfe487f9812c1510c18d2446e66214e7a6e3867e7e6f7f7ef49cf6e9a1fbb3413a04d2a20fcb3ed8185b74b9421543aa44985ceb5cc6c15b7b10f142f3697a806bb784a4fbc228a4059bd53b3bb3af32f557d19e4cf9ad197c692c13b394c85f2690cc98da0cb82851a00c31a477f76f7275dd707be101710af87946107c34815091654c1 + +Input: 29b61423f55b91d6ae44c7bc4e30fcd28b2e7cafef586a2f18680a00f16c9a8aadcd6c068bc955e82646f7acf00a3e13e15b609553137391f31443b65974d9644afe0173d75f57d3d797b7b9e41832b652e5f4225eecdec3ed6142f900b8b840dba5a807462df1e06a46f347ef54d6b0f0ab7c162d04b1f120fedc4926b77f799fdd821683cde4bbcee95479df0985333d7408baddac4c98052e01e7b90dd33cc963b66501b8cb2772698ae4fdca4e0f28a73894210c1cdcb388130de2ab8088e41920fb1b966cc8b9ed5f3f880bb69a40ae9d47f0d871d790ec7828536964781830eb37981b4af8f7a78a9aebacc95ab96e75e93e817e1878759fde4fec88f4d8c1bf4f113c43bb73f9fee95f1ce0e5fe79511e7f7d29621607b11b91df1f4a27617b323891d3368281dabc8056c20bd0d822eae2d03c799cba783545aa9d9d505ea0ea3a2795ee617519b0b9d0f3f0c92b57fbb8b021fc07b68db1b2a3365442caf9ebf8fa85ff4f2719b936c83dce87a47604baaf5ef80c7865d3ae08ab6f60e32ba7 +SHA3-256: c45293b38ab6c1081ec876a7763ca2aca46394f9f64014884ee77fc206cebe80 +SHA3-512: 6def2f0f59595193d82c0cba8d6f3572656de5657ef333d26e476e86c89b218954fd9b4e4c5afcf306383e4c28a48fab71b7a9e6ea3d2f14056b048bfaa8b9a2 +SHAKE-128: a76a5901740448662e918d04e4123c07bc2e5b089e5a87de357cfaf0fd0040f0933ac8796a0f79281e83fb8368aa88747b4468debe75f4b3401e3b21df60f9279b04941afdef4f62d0106875b77da75e1449cdeb3dd88c2f204503c9a9009607cca17929a164eb6e164e131aaff091f628e92ecbe439a1c7cf3ad6536dbd71e79294cbbfcfc3410a420ebf05ada8e5c59cc0bb52a6d543418821c8fdcc89416ca5d18a0da5e2799928bca94cfe100111553a0dddfd4bd632b1ebe77ffbf63a9d4ae9c82fc4df4b47920307380ee8e057c4433eb7e71ae60334fb02c4e930bcd03d442074d5c18b8a92b2808043711605a4b874811e6af646b40eef437fb39fb8f0ccb0fdd2d2525b29d2083f58724a69acc20386ed1d0b6741c0c81b98dc6a4f73c7d69b666f3bffa2e8061bfc9de2190d6ab6036d2000f7000951c491cf7c5e6a52d7b2c6c435dd26a82fed355edfe99ee0938d784a7a6e80e2e725d106e950765a323b6d343c65c1fa666963f8fe12120ecf95f9cee360339120107cdb8228c47581669925b0ce8b7367c39fee035a811b7387f93067cb4350f1cff09be4c7b63e7003b950fa9aeef604d5ffd6e0acf5d1ee368d0b206876c34303064d7e7539f27779e3e62a4022200b8eb9dc45813d6e9dd012decf24446961608a5baf636d9c520dacf13158ed3f30da40b97810b0fb1fba1d59004c3654b2aab4e64338 +SHAKE-256: 3b1b004d076ac315a34b3c73fa9fc634a4786ef0f2a0f667957c88592214df3fe3f6a1cc1e0c5afa2e6f400845e2c06f5aaf1fa6739f3c104e96af1358874bbd787066ded75eb1c300acae90820828347f29e9e9da85f35f6b618e43c6787e5889c33c5d112d68d579b3d5f72bcb5fa14713fc9a968b2372bc8fa330b8da5cb300c32bf7d1576aadb0e2743ccf73e097f8771ddb8598d1906101062f78e2274a4c14b028b2849f014f9f8c7d625cb29f09fca2c8dd04fc7b5d2845be47986106b901b9543358c6d21148a360b5900f984508de24f18a206699c1eaf0dd31d59a04a09322e3321c9892df5c07a9e60e5aba66990ee5baeee317919e2b735b358ba7a6380482f0c25bd2d215733d1e4151c21964fbd5710ac456fc508f264ace4c02bdd06308ba9fbcc38d937e586e28dcd70146ca53f26c1af8e1d094a6d37c2f98cf62f0cbf130d69e984a339e0642422f4e7628c8dff4532a2ea7d66f92a9d32084239bd5bf5f9c9e08077b440a1fc6d68547e25f3c27ee015d1ea1b07888aaa1800f7e1853a83de0b882de3a554813acdb9f5d0176b8384da80828632f83a5e7a33b1765fa8c1ea015a11b68d0a9d68ff9ce953fe28c91d99a2b33e7cead83be3acb38cc7cc299c5b4243cd0a495ba276d0f1786ab710ff6d8b168f841d623c5eb83c44f9730cd2d6a7415aa4a865f46953070054d6ae9f87977d03cad4d1c + +Input: ae3948274283d3acd981ec5a74b76847c269e21bde741b6a0f1799a2039a78f030af8af0a24ca2dfc7e89ce5ea0131a39ba729c813cbeb4b8e45f39caca2169813d95e0d3d94dd0a4ce273828ffeff0e46c1dc27bd6d8135fc1016076c1fd38b4f59086da29c8e244905ec7fe216404f8416306fa613f156ca1d7a5576733f12a35fa83dbb4ba3c56b59bddf2066581d62f3bba622a3f20b6775de3cb23a8b1b8ab0976d020cbe2a4d24d0bdc9146f31f5272036a5055e07613d042c1017333847ad38c372fe562aeef9bbbd0e882d482b6744375f741d68bea2ac83b9d125caeadaa730e36d2d261ca87ef9c238c468e2ce2ab41e0a265bac6b7bcb65fb2123b562c1eeef50f9d172fde0d3de38b5fd996612985b83deed0264819eac16173bf588e545585f87e86256ac536a0ab68c6df54b9a985ceab91eb798bf8c413e3864e85ee2ed19dbd8bd3551e0ea7079cd0751d7c82077a711be3a3f778ab8d06b6fc8d90a2e543ab230df8ea663fbae161e667af9708e8a6158af2d625cbd5fbfdd0f82665e +SHA3-256: edd26b4304aa09e02164092a1824e45e059d610898f269d4cb555743f98a86aa +SHA3-512: f5883158090d2281f70c5d71b4c285769f7c480c9dc530bab91f2a3913713d8124f6717de07810f7bcee2e47c4faa9ca77a9ef7b828a88c0e507a58c9eda1703 +SHAKE-128: 706f1444cedf1593b7d726776d7f8ecb8818b8a51617a3bfb12357e9829ed1dfc658ce22e8f51bf9139d81cf1296029c1a424167a63c8fccb84b1388564a26667d7701bdbd64916e794ac3950eb798cb190bde9da15194cbadc767c1cb5a705037332c4ddec5b98d52c177e9b3e921614ac399fd37a9ff9f7aafb2bd7eb8b578caadfb1494e37868a8f4958362f873d0b6dc674ec1e4206bf6c4eb7e80478710b3aa5c0459094b42dd7db7a531ca4471f9f3bb213ffa44443271db1da878ccc2891d467fb67c560e3b8dea46742a5d9c9c1dde648fab63e63073fd1ed6e751b6046e96d99f9fb8978ee1330c3a85d3e041ff6451df51d81ec4a7415c6bda6dc541ea3ef1aa3c44890d77dbfc67f76d1704dc1941894ab19d4b88fd0c7b5ba8a16bad50499f48fa4e28b441e6ecbae79e0155774785ed9815ae7d11703ac6ff267ab30e1ac42a8ae140d5cfcb365089114113a05d258068b09fedd35ee5d0174c24b5cf40dc95736500811df0f62cd46fa505b304d3a93b24753ef0008e09d2bbc0c5be9f6385c4f0d939f89e3196e7d889c2421b1befdb571d903bf7d0e32063dedcc2ce88f24028880f7108bca816fba966df6b2b3ce3d02be2ccd45d53e19b63e5fbba02e1f426bd3cb775a391ef1bbcfa98eeee705e41927f7fee08650be63cbc3d65d03e9f92965e9bca43eee85af9b5667742254f3d4b0ffbeb4787ca3e +SHAKE-256: ea93a4746a7361ee436d5a5b1550173f628ace591a984a937225a6f349861a5cf14d2e15b141fadb4b99f8a5d18c3b06caf103a6e273d70b31ce7770b4906a12367189054a21b1f0f2123f25d5a100c7fcb25135bee2924bf74d3302f982053f32ccf775563241569f9719e426ad9cb795b208dd4997966e3c50470ef031fea50c2640fb686db00b877f67b5890f75fbd11eafc7139aa6975092b08da934297c3ed22301ff408e12054b79606e8d579a8e30509d7d5bbda9b43ddeb85cc20d5a2dda7b31d0f34d853b984952992b90d87c11780d4cfd8565a033e54a44ca655771f4a6aac16c80302dde578688520f50e5fbc044cb36529a23bd71c74baf6f758237bc45c84cc65e38972fd523e1c05ac365a43968bbf3fc2c340bdcb52d2ef74070c7e6dbad586d5023c9edb34b3a22452292813cb1a328c8942128bd3ba41abbe8034bf80a3c50142f964d047559762171f9d0d99e2069d56d11708ba65dbfcd4bfb914c489017589ff137ad9e53a9b12530df89e5b7284da2ebf381f3d1f15784c9a53d92e9e394fb11638498c8643deaad4a197a377857243ddb5718a6860a75858c3d4adda906bf0cf935d54c3f2ed894e90bb3b17e1377c99c5edbf00a2b970767a729507a55c7a6291e13570859d3089d66537f4561890663124e2b23b020572746b4bd7b328c28ba5850fd18c96af7908a98e34a341f65a2ec036596 + +Input: 68edaa7ebbcf5989c64e4f9a346cfce5eba91736de01a15186a44245570a166c13149cf6d8883434a0f0f0a2d8d82964913d1ec4ad13db7f9ba7fa59c0224d2297ee9015defae2a925506fdd7090b0cb94315b2f4044977348aca9e0fa56a0a0b204ca670cd8108de0e6031eddb2120b6dd8069332e4698ec29d4da1aa8c4d573aa2476fc8d544585d2fd5aa8634d1b0683bc4c9dcf5aad05c88d20f25af6910cb2475dde1d27e3cd81b3532a5e06853580f57404983e290415f0c7515294ad83623b5122d83470022485c297ee1614b2997173947ac14d19927893fc698ca9024c66aa839bcd193e1f812beb62fee038107c5940d1af3a6c40a2907b64b77fa18083911ae828513ede25d0a1bf783dfc678f0bdbf2b75792c931e3a6345809e2dac76c417bd195912e3c40b8020fc2721f3c961f40de14b0195cdac0243d2c858eba9b34b737ef98f9a7a73d7193234a969a919e41949c3aed2672a6a20d3d4f5cac333cf1668cef051b162a4f5862555cd4b42b66f0e83c35b52ce6bcb3b726928321acca8 +SHA3-256: 16229285931b32299f0554a9b27ea21607724bfe2c36c79abc421aacd5a4c285 +SHA3-512: a7a5a052c72cd4ee39667d51deefb383fca8742cb573cca6a9053756d7b391f88053effe1c1e9a5bd0ff19d2f8e0256e2f87e2373076a69e217d4c34c32e8d11 +SHAKE-128: df0f102c9e046b38022aa3823792162106ab28a86b31175b7060a81733ba14be5d5341c3ff42a387f2434cc73097988cb54378cf3ace6277145662b37e2662a421b5d6edc08fc5c8cf68a322e6440f65551289e669aabddc84ed8bf18a28830ffee571a1585124dd0f392c159a385ab784c273f0d0dd1b7b7b718116ab461fc191232f1205c9723063a46343f4e50c5ce128cf19f5907a67b8a1ecde245a9c5027a9198c393193577ff566978fee0434236b7de46ad7ef5b975119e99562036601c9178a07d5fe63b40385cb638e3d594dcdd171ee28f1267ad0e1ef5d3414e672a6a24df4f9e8e07af17fbf57abc5735d61c2f5467e8ca34abc6f73669707a6c33f76230c8f285d7319403369908e85f138b4e768b7836a0cc1b3a5ff4b71f65c47a7e77b0ecdcc1ff05dba5a0c52e4f8af4a3e9832df5ab2937275e06e47d2522be1fe2613ef55db04154016cad7d3ff87d781cbe46a077d5dc25ecdfd194dd156f57ea2f33a398a3f08970b802e5647a89f66d139b864646e6e14cfadd8876cdccd9ecdefe32b0ff944fc457c7e2044f512f72c533706811c758bc8203483fd5f36eed3834458ddb69cebcdf78bb6302c1b2f02306906931d68203ea123ce3b63a8b4e429fa36fcbf64cb26a50ae5fc87b3de63cb7e830aa1de9caa0ce3c46bb3eed7f7db4e1b1bd0e5575174d195cad6b005f7ceea9af0754b09f556a677 +SHAKE-256: be29d1621d863d606dfaf2b4dfd027ae1dc0b0d737c97fc3b80bfcad5a2d374a46da96e7d50c2a2f0045ab05756b2438276ee15fac7c403e349578732eaa99d354f5cb426120387f60da60a3f0695d620b8e07458d1f6f21ef05022ed0f8af81ea3722ec7724113972d4a256437ffbca9842c582be98957aaf8acfee2e3e67a4fa2f02c4e1c5f92fe50dda5976ece38830976510bf8c395be03f5ff4f7cd9295af202e8cc263820548f9233615d348a4d2a14d079dfba3c51fad5006805bb287437c10787f7ea8d6969b0a75410b8dd5c055e4eef7d029e757d5a372dbb432836b4667724864354b2c2ed29eb8615f35a617b5e589835049de622952304ee72b2daf4c3d6527c9f73835905590758d9c7a78f0721f0a5a3643887bae5f8d94a22bd0d42befb2b1d49db1eb03b3bcaf1cc63f96cab0549142a9c3fa79ea6ed736a1ce1b956bf2331389d22738fcc1be763acc520138f6b788241c0bf3a83f0c006139e2d09d155996cca21db5a6587935bc59b62f88cb18d494da0ea0122d5fb77b6ababec457b2bf3c7909bf0cf5136505b6d02dd3bbce7de8db94918ba89426ac266158728af6838ab82b1ba1addade600476074775fb544a0692ab397aba7af2263679d8d5c870f92c2790b0b1223309d49d2e58019601e22b8a03c0f27cb2987139698ac61b7c5ab86ae2377689ca8a019d8902477a7a9f6ac0d6634107f4 + +Input: 7a147b6569e0de1e98b7d27f86e794a0315bc9dcfacf0489917f3853b4e31963e0c585737af058f76112d96f10dd73c26cd124c383e161e45f31a3bd0921feb4e9d91c61d3c7fcde1f799b6a4b7d1382eae55fa7ca797f2a2ca666c9fa07f4507f81777c8b095014c77e782eb6dfb6b7040d378a7c83454e73a27dabf87e476fb767db3a04973eeaf3fcab6e4af85c1f37208147410624b488fb5e64c1ab1bcd39638e3234922b9d9d6d26b515db2ff12761cfff3913edd72fb9e50704582bac13cfe67e62d7fda45bafc5059950b221837c19d661aba5dc58250f800457581cb7601bf256f02815583dc8d2f6a797725697ee66c0ca2515c2ff6e42bfeb1dbc5dd750c9f2b1284ca2d65d7618f9b13ca150ca0631c34b64cde5702981316e427945207b1a0eb3d688fc4b541a2a168fb9bf3669e76b7ce1e767373ca31b97197ab6bb27aa94913ac0598eb1effef781151e4ec49786ca78545b6c8421930bb6ae1dd7160dad5144c5083b347042c1761c25e788933e8cd04b46b2119bf4ed549e0741c1df18de +SHA3-256: 0945695bee2d7c9fd9287b526174e27a0575d01db79e7c9a30feb5ab2884e18f +SHA3-512: 4d4d793e946c2f70b0418ffe97a5325d94eb4a70e619d833339fd9ce10d8fab09cc8a3b537168478ec4fac7b15e122735567f7ffddcd8bbabfb2f60f8106cb3e +SHAKE-128: b1935ad6de79d96fabec45770dfab1f1e000cdf05e8280c6138df24997eec2b8778a41addbe3503f4fe4221217716287c6d1bda4c5e7b042f9d951bf498ea19f7eb96828d59eb0e1920874d0e92b01baab48e9c901ba32a1cc1d2dbe391d86e0955d981fbc6329092716a94c5ddc1b411591245209fb9a9c043c590b204cc662675788adc8145f0517718554af37312e84751ef5613f16c00f8f91dc085bd1df939763bbf8e03d7e771b7bedc1fc428c9eed059b28684588425f4a4a84bc56dd585c0fd184a8b32bfb756b5d1af9ce55013ac5c266f941c74f3ee0e4a34d2ae024f3ac9ddc9d127c89ada33c7db0a5af4c5fe72824cb0966eed3562c16d83247e2004566d114dd436d4c703557d2c7976211ac31f1cde308d622160b22ec3918d48d2d699f94e5008906be3e6cf1104143756805889dabb2398fe2c7ffce2cd4bf00bdeb163603db6896313274afb37508ff9b051bc2ca2a514f0d92f31c6ae1cc37395081325f9d1b8e49f123ef4cdac8cb9aa1e6c728ebedae716c8e7081b350ba7927e2ff0f67ae5239abcf29a3b7dd87df2cf261590bd9e1c771f855e84354387035b8ac11d7a22365f64b9ed54fff51f3e5958a140eef8ceb11775f8a0ee7716af0fa01eac64b40b89772b995d3a29037170928550cf585e2df8c38066b30b419c05520bccd8e19e979947fd2ac17d096377ca831eb03bdd47ca2fbeef4 +SHAKE-256: 8c56e33df32f944f0f6d1f2a7bfc5348f9c76b03aab9f2b8c3a932aa40c6a0cc6870d06f37a49f24da6bb9be56261c6150679507f9bb6bea6025dff9b2abb6e36f513c192d289c1249bced411e31b4694328f0da2fd9dd0801ebd6f8f8c280ec1dd04b6702088fb0372f8cde7e5b7e18aebb5f99e4b7848cfa2132098a39a7ea3734c6bb4967544fcb7a37195db546ed3f1fda095e05d1bf972763e040aa2b27a3a1ee6f32cb4f21860f1f2b0cc6face83dd949554ddbbc60a3be7db0beff2b24c62a7bdee44198c8290c6e7fb44f0519127618fd573ec481537e959518cbe592e6dff4548def7c0333404eedbd61ab6716d69201618f53ef342606dce96494b1ee53eb6128605499afd84de233a6ceb6c1beef543227afceb451e5969c7458cda48f9ab7b23691b1e0f8bd3a9189f587198d03d68af187553d6c3b653c6d3c70b3268aacee367897d82bd5aa10fc9b09744a473869b145e39a68ccc2ce5d586fc4bdb87a117aa6089b7ee4b6627bb5da27e1f4e14fb751ed86c313b4954e740454927e530cceff0e15a6fe4ff5e59578b0db0081e6b928ee06f5b26b6d41c2165fdacaf7965cf54ab0d7354508fdd0a71c446b5a3d5aa732cf19d6446a5200aba4151e8f863770fd677cc96511c0c5e3be434f5b05556777498529e2424d43cfb02e752276880d8b55d69c1479a6e5ad9557d822b856dce37f326a944e19f1a + +Input: 8b62ed2276bb3c7f6f6aa4345bfdb2b1ef66bc89faa8c1bb5175516269a751af57626dfc9f9087aa6348058b0fa302933a0a6971e2ec09b18c8ad573b402a296d4b7fda0a4a8da0d02bd411179ceb1259656da22babc9bac18ce42409cc6e4390c0e249b67b886602338cb4191e5e51f331196f07e4c425fa0cda51da56f13bad1d1fcefcf4bff8a3d1a3d84035a82f629d73b8a9a5a8e4d684d53423923753f336ed7c67b88c44e78d124b8846caa4a0b10e99df571c5668c74136ee6c9741fac0c2a47dd8f56fac58e2c77ad78f18dddeb5258d575110210411c6887b41c94b1e446c55adf40ff11570f5740226386e4fad63ade9f510640b662bfef09481b6f4e8eb19efbd12ac2143f1a5f58ac7fc44255b101da94cb5676d75ca1fc04c7aadbe83ead268887369a5be872b063c1d76d5a09b7aeb8eb4f301e3882c88f638396b7cda0e2890cb7c439e4ad59e476c73cddbbba5a12fc26e0e7cb51e7aebba96a0c563387238b13be75deb5d135af0ffdb45e4c58f0704e792906641586d2ca235febe82fa363 +SHA3-256: ccc1dcedb1d8aee5bd47e37e181b96f3f9d3dfc9649178ea5cbe7ba4065ca160 +SHA3-512: 532f1a7f2bc4fa2b0e8797676c0b2851abaf2416cdb7ae063097b209db308ad3501f15e79fb2d5744e8c1601ec06f0b408f0f29dda11473330d2d30dbd616d6a +SHAKE-128: fa7434808fd360a1a46f22527c2393c9d922b63d956a1f5b0b3825a603dd08d2b1ea063d768fd0a5088ffa2e841190eb4c264859f90b64a0725ce70c609155b0abfe22699e3f8e2e79955f180dfc93818d535343d50f2f7967634dc6b8db5add13abb4ee2115e8bdbf1a77ec812afb12f79d3c639b29768706f5281814465541498387284f867ece49185f7f7bf0279d0f5de3e359760cdfdcda6ed19cf572535d225093a8519896da5ad56ea73c43a4d52a87e16864c7cfac130bf4cea147e030ec3d05e34aceea3c8371f66de73dccbc99c1b5dff9c70f43c65b24030559b052001cbae3515ff4128dee6e9b7979de0167fb24c12a785eb3b6b425f8a93cd9ab83a3a0eb8758fa6d4056740ca222f5c3ca4377dc25d1d531e662b293ad46992121af84c5823542990a05aec0a9ff7c3689284d40ab5365b96fe73109067e9067262dd6606777155db16528cd31b5f460420c92550e6bb22068e552adc6f14088aa84b15c6ef8cdf27ac542ba2d0e430f88a70317c6dc82bce2628b12629f07f32c9ec86b2613db7a5a4e5406cde885d5fa229981b1b193562fad324a9eaace9ab9e9cb9d273bfd9f96ee8681f72f7dde28fbac236921ff1d388540a19932a5418756b360eea52beb68afa6fcfba73f5ea9b5873b7a90ad67ef9818a06b8d841dd9da654236c77bc7090fccf2a4672e8cc968816e9ae9b767fae24f74b55eb2 +SHAKE-256: 8d5917d846f8ee3b1f2ca19a963890bb04d25d6cafec48a0b1f1a739c725c838b1bbb94d8a4c51195f7894e82d0ccef822c98c5160818e2ef6614a2a75ec05e326d5eb1adf7b7fae6e838864dba71a78da10b9d72aafeb3634d41cf7aaac5e196e20eda168b528cc19a5cceb47c0566b2e002e7ba5f2922b88943c8947c2cfa3b0ee18025d492cfa971454d15ffce6aeffc3c301bda9c0a1e6d5b397feb0f39cc524bdbfccfe7894d4dc7bb8a50d63222e2c8589813123247cf6e0cc9c1b24fb15c51e89d4f321f268ccdf59d1240ecd99527afc2f404f902c8296dae07e4cb89caf21afecafb8e6b0f545822b8fabf386a1505712834b760ddda16aa8dce7a262a717760404944cf3f03fb50eca8ba58f265ede70eba9a0c9c69372c071af54ecbb9456d8d23cefa2c9fd9800c492d1424f3559488c8e3963049e07dc6f9092588cdc6864a592f638ce3354a4ac5a04e1fe8e0e20e1054ed0901d04193f9c688d0c8c08eabf521eb9490050383f72bb3af75159d8623f2438a3717b53af826fce325baf312de817b403c7b5db5290706cc4ff4228bd59011989096e6d08654d1db51ca3b1357e6d949f20df94cd1b8481af6be42702d92a96d8bbb72994105a0ac10cb90475a0b80d829a5b851a7f405340cdda82842fe438b9d449680496c50b6748e1db1409c119d9b92e628563c8c3479b2edaebbfc6a462d2c5a0962a9d + +Input: 3df71463db0f76c708f21cc1a9c05420a0480c1150d4e0e7621b2c1adea238bad6e57dbd51ada652612e18195ac88012e21644104588c83ff3a99a1104870af1d6e9cf81626841eaab3a738fe420384dfb77f416f1cba702bdaf4dd9afcc492c71e9b0fdab4bf228b4d79ebeaad54b5b7b77eb52331930bea8258ac89033e1074f8f29e4b4a4cfaf5c7ecd46a81d93b79df5a9861ad7f19cdc985417bca0ee99a972d2e486df93e8c90229ac0c2fe37ff4125405e8b7ae3082ec18dfbfabb490f96c2bba32bf9fa7c59d9549686a9479f5ccc63c580fcc01e323ef84c809255edc625613f07b178449610587b655b38abb072eb5d12ef3b985ced2a9228cc1346c0b0558ab21306cc20f2f7958e4f12d9c75be15ce7c5fb0bf967b841f1059cd89d3e16b521c6ad84dc1eef512aa7e888ebdeae092bae3d56d11c3bdfcd8491e3b37dc76cd5d92f0bb126e7e39c0d1092f870d2c54ca02a94536e5c27e0f3d4561e929d4c202ec79120953e67788f973f1f43359ef257113e84067b266767c207dbed5b3e9e1f079ac +SHA3-256: 8132cbef7fd40a14293be6518899994f5bab57284dafbc15b635c49b1b2a26b0 +SHA3-512: 81d5f661663a713609e8c549ef8a1cb304d38a34b61267777887fdef1da5dd9c2773890c58a7c0a10c248413b7438774fd2f0773f23d690c45797bd8168447ff +SHAKE-128: 6e0f49cbc22af8874eb98b2aa49595033e53aa3eca638509450e682ed6410d5977c5ff1ead2adb2fa4eb6db02822f4d48346c24f272d41da3238b2312bd2b9d5c09426be39bd1b42ebb19f3c2fba6f8b912070b92d2e1b128c53b592c9e460d80ae5e6193124f4cf2f1be0ea33e36abb59f93a99dea952f653f3019afd6bd9161367d0bd9db79039abd5751af07a47379b07d3741f9a2178cb0640e0a13a43fd5fac407fb57a105685bd771e9f0d55ac86cdc4402a4c2eae1515bc05f05e9bf3ee13014ff1c4e465ea06ada61f1a73dc34842f1272018ec70f47cf39026e1e158f419b3989fb98a54e3070fe65c16846dda18ba77932647151382719f6b2db07f841cba2ff2374c271d6258e067f88cf1e9c86a8f3a63249bbcc9065a2dede4758e48c9ed13a0a64a78697af9a574adb5438aa9408d5a70e9223296f24acd6852cb5b20020963ee7af954f66bf9734c0490e269b3d116553bb3238a7b16a76e2860470f7092bdcfc28244fe6a043ea41590cd202bc3c717b9458e75b1a1cffb81b78d2d008347c14ee60871771678f2164b136992408fff07322fb9943191f1c92a05487720a1c5cf343a2c88ce3ae6cdde0911109c62f7f54e55957ff273dfd731c93a3218fb4cad35ccb5a9a7bf6a7307e76cf1c8390f93610ff545f87986c9abbc4414fc6d186b3218cadbdc3867159a9b97ede724fd8b965c2f9463d1c7e +SHAKE-256: c540a118c334ab0f74a1713ad4492d34a685f745af92e8da0edf65853ae53fb0820ea6d0d224772b23a141798f3bb6e61dc4ec944979aa4df6b5cf91b68891767787405ec9a088342feccb479dc9ab88faa5417bb189d08cb1fee811a9ddd8f46d7302cc845261f9765bf0ba444c566bc9c0120097b5e759c1940e0fb857ea5e03ba27cd7d738ba1ff3af7004a12bfaa967e5808573bcf60f71db7f84455c799a89ed23f3951c47d9b874a9da8bd085a18392036fe6ded6c75f81b819e8a015006af2b53a5b5e9e57900e542816f15633af74b17dcfc3d49edbb5a8ad7314fcf1070b76048a100208688a70438d48e71a3cf5af54d43608c891a91c43ead9c2a2e9107207c4c032206041194702b688cf2413ec14094599b7b87cf0a9056453ccbe7f5d44b9c790b6c8c303b5e95d69def684c4a0209b6e4e420b4e289f8dfac69e5d6ed07aba81c53408021b5da75c5d5d9d14a90bd3f4cd5080464ecac030f973ca026d7b0bc4d082ccc070794b27a542dcc7a3f804f6388e505543945bd19a402cab12f8542a3c0f4b6aa5e0716faae18c286b51d43b6b94594e23e15101bab6456da5304719b08628a6b65229b1daeecc9cc3fa1d6e4390731a0d7c69f00263581707f124a21a88da8cabb5fca4f81605de1c231fd95a2bafdf1e88bfb7178334eff60f919ecb60865689db475c609f1b28cda0e268b8119cc4426dbdcd1 + +Input: f5a1887af9b02fabd048594d5c5649cc3c077e34a4eff9677146fbb84e8d14609f5315d440c1ce246f8f8a0a33f58db6e0fe2a31d66a1d2e2b82279d8d38b0e0b2381af396f1642d9140a31702ddc36d6a5a3b36ce510dec9d85fac0a707ff022f8126c18d56bc5fed4e61b1acb10d7cd642db58f7a2c1b1aa0266b47725942c97ff08204129fda483e63e8dea31660afd31327b340eafc56a88e47ae34ea759c0dfbb506d13929f0693f7a73513bb16e1e48b77e4132dd62aca4b3a408f77476aa34189de868ae6bb3872634317a0286c798d0d32f450db7017c431683480259151c86594032d0e2a181e4ec45e0c717efbb48b8e486c85c76ea90dd3024c45742c8672efabe56a3eb6521b4207f55f71d6a7945185a559f16e748e46a09644bdd1f70a7329170341e670d2554852243032745d73195a38cf57808bfd2ef669f0923446df7f2a7fb22a56344c2f89844ba2e5fa9353b571bfc2cf1728d1fa25e9ff49c49749d40a86227b066c616b6040a3660a8b51a48817462c7e21b2b873e6e4c32ecfa54c502753 +SHA3-256: cfe20a5670ad6f19fd605aa16fd9c191e5fb1241f83d9839400dad1a823da402 +SHA3-512: 7441d090bb6ab910a7e69630cb736b3d7154f3814545754acf3a3a7304169c0c23224c98055cd1294704d3b979cc1aae8ec5fbf2b3344dfee0caff0e54951abc +SHAKE-128: 81a346f66504e143f7ae9ff8a9774ec95d9dc74cd183272f4e129a9da361508d261449586c0c61af7badf9bfb0099128e04b879d6fc585db274cf4158f7cb73176dacfa17b267676cd9b4c658c6c5175f5611b29b9920b136688abcbd4bc5f846e82bfb46d882465fcfa6b56b21597b49d4596d987a856dfd9317a39cf13a355e7cb2e221bda0f2220f10e5e8d5c16291f85fbac2f67a4ad383a9b00f340cd58a254df35e395559558d096bb52e54ab9edbf97ad682083101c6a78245883426d92bc21b25e1354b18cdbac3119f76757cc78542aa7658e61f4b846c4711018234e9ce093037fe09ae7b094f084e072bae634bc6e8bd7b720f12d1935005d9b14b513cb9559ae84b521bb7705084965e29ef1771f9c243f3aa821864651a8f777d7fcde6d068adaca7132d00d9f769e1e5353fd2418774375b7c5a95da7bd3723b417e41956e3e42c3d19facfb4a5affbbc9db692d010cec5c97776756803fb02a6ad4729a7f701316fa459ce5064278a40154e2b7fd10f0868426b4dbcda2efed9c4cd621ca0a87b226692cc7170e1bf482907165cd35503935cfb6362c41e30e30b32076a7c1a17fb6a84cdfe0a4429f776b76414e89c477c5cff16004821d4b5326bea81fa182733b2db6cb9831437646e9dc1995044f5a5e503b8b5c947e88983c5bb3fc093d7efa428c8637460694605833d5788c5a4f4d5972757556016 +SHAKE-256: 87848c358ef2fd8372c76ff942aa2c1ede06eda00cd442715c5aef0e86b6ca35949e7cc3a763440d771c24847dcbb1bd97007f048756008d81b462762e5f222c45b3b657b50ce6c5b703dfad5b5eef13edd31f486927c93bf4d0b360c81aeb9d8826831c2ee2155797198d375a78057e71d6bc333fc81808cf26bad65e6aad9f97e12fac281199d0a5886f85089b07e71a42909172a56cd29834c465fdd11d224756688e85fb6dbb4af5561e7824b69e066ad8475b632ce17f48dbea3f3c65808dfd16036e2e525b5fbe5a506e36f6f40bb7c7922b38d462fa6463199d6742ad9ab83e45b672354f93aa975ca7859ae93e391d231dbbdacca6a9cda16e59c2110cb02c21264252f47ed1ea62a543694db156fc97433c1cd688eb644aa63e05fc56a2b2ed158cecf349a37c6ad1c122bd2a63edfe63d83323475cb754a4010a01d7d43177c80060fb01b87ffd05c8f804b1f9f059f7dbe667c5d7147500dd003da0d9db71541a8cf210f610048098b6b686fac3cb6dc8e120d63ed2e1e8c249efe1f1035c240c74bf34ac4e96b47fc3cd75ae73872045beab116441e0e468db5a9f519adf93e68a7677bb22da09c571deae23bd80c681b54aba86c7ef917e3226773267afdc69892ce358a8bdaf31826de17cc648e62e9a7b0e2b81263c867b1227c68529d3acb7bd41de2a072ab740aaac9fb538be7a0a2f2f59061ea69fe706 + +Input: 3a4af0a5292741a7c97d2ea3715107ac96445154b9d3e863fc6f90ee70d717dbc42e9892c361ce0f913385bb4e4ef33a632ad07acad91a289f0d49de7e27625e95a72d28d53fbfb94d3a2e24f21575d0361e160e92b2ce9aea4aeae7a343e7597022e198fb9e58f8e2688df21fc655e7224abf06c20462776d3f0a5ed1aee49b5231d267856a623ed9c1fecbe4e136a9ee7fa6b23a2f8b7e8cd8beefcc9c04001cfc89dba50ed610e43363223d3bfb3cb67ac04c3516e63e13b6e68bacdd482aa02336b7062795abb043951ba0a608ca94d5521da3fc90b4804d3d9094882e3f4d15278ecc7e0945045e3d7f51193528791c9302f16e105914dc94b0e5d927f4f2df0254df91a93b1319dfa04311296e9afe19f233209c444574f310d6de16d7d8c0c289b8461fd599ceb0647b7dae6858db52ace9c6c4c80735b417fba412b32b6ac02a684eb09242cb423cde29faa45249ea0e2e5c92d195ea5f7ba9292e46b0a20acfd4f880eb72f9f9edae95abcf03114e1a53ddc10974428291688b8261727e6f58212e9893ea3b52 +SHA3-256: 1376e9249aed022502d6536cb99091ab4038a82b5efe05deab15146ae395fe94 +SHA3-512: e0df690af3d6a3dcf9d18f78f04b17179cc9ee8ccca98f37e827d74dbc52292e429290bb9060e6d942c910f2db3fd09562dcd14cc896d9e7cf5276432525d364 +SHAKE-128: 957b5de6f3a27a14fa51b20ab9059c7fcec15bad0c364aea964417c25f88a7e2f7813a0e35f0c7e6b23be94f2802ca25299e48c1369cba05e92ff6a30b427e76de21abf575baced63c2cc19c3b4b6aec41aaf47fb65b923fc3251481bd4a025a0c70fe70ac0865f1b705a449c7b646e807d29f88a5a9aaccd3b350d016c4408f6ba2a89c5685db8dc98a595de1d02fc4d4a03e10e8d7b4d11a5ca0c3c811d895b986fdbf5ba1acaaede703c66f3b77c8979431252009cea2210541f4073bdd9f9c0a4bbcbbf1d9a2145fded61d50121c8fa78841aa8a946c94cf6815d10cf9935e250f3ca3cf05986bedb32060adab9d9b88a43d0d1f2acbe3a7094768a34c485c281195237492b6bfa52500fd83da8dfadd3c53fb4e1c4437cd302ced0c44ee83a1f026d0b064ec62f745362fe3dae0bcd1ef23e48037fc2d499310a45c860242dc1f5e483b3d618c8cbf141b81986a82c9109852a579863d3d46f402300e655641b5eb40be3257834dde08929ecf662217dc58da062d9d29bae5b88e74ed7bcc846583a53e87b99071406c359b973052634ace5457445f227c5b602cef699a71771fc02545aa638238a2e81dc6c30043f4a5929a636caa197369959e44215e6ab298a524d11607652ab6a9712e1ae7236df7487e5e4b30447e8c75299658e5563bf8538a78db187cccbe975baf8dffa636340947325ed5ac9900ee4a87db04 +SHAKE-256: bf6bbd0eedce120a22173f54aa61fdf3bc75683d125ac416baae9ae722f772a361dacf5b599ef047888f1c3d6c4d47bcad970bec1ab80eb18cd15cbda54b2ce65178dc9fe4358730971fdc908429344ef219dde2ad69e599a3726f7e0a308c584eba43ed7f4d683e1dee30fcd189de586fbb450f2f5e2299919ffb6a59f3ac0ee20414a6a2dc5e919ce5e754415bfd9c6f719cbf4ad1ccd5e5c861c6d8c5e37e1fd80edb66657cec0237a6cb45724b7e9db2afd8532c6e022846c74861c01d9fb5674814f70fdf97baadbe05d56fa3425e2f896f5a2e5c73238d6fb11934f88ed382a4bdc835f827af74c32d0bf1f0fc4861be3e02671253977a3e30fcb76caa1d99a76a3e3b25691ecbf8ddc3c1edb8c844d47ecca35cf231eb08fd6b641fd053f434dc1e52bd07552eb92c78130d4af356b2e792896c6e93e0aee758ea012437296ff3bafa607e2ffc69c4c3afc67c18240d58f0c27699acdafbbfaf6f81c0b60acaddc0d2dc0be7a144f4fa8194c6f33995d3c15fe3b63bcc3186dc80ef74f5b405c36a50a15ac37cb7d5766e77590c91153caf53e4e7f2fecc53f5fe1aa990a8bcbeac9c03afc13b41a293359089d9c1402e29033c8e409fbb2f56f5df77c2892b095ee9b4ecf1ecf9973c93e8f3c9df67dfc513da9b6b06bc34ffc5e7c4c19b396397d31dbe0ec494eb1a70a0a1c6e5ee472f92203e1bad6d23681e49dc + +Input: e1c921c68d41c7933a21823335f625b4e86c3ec6ed83ea9c74acbd0b9fe5ae40ae187e5024cb785bf9ab1be9ae16fb35c5626dd103c05012c4d8103a5fdc3bfc16d1d04679620c630fea30ed2a3133ba21a21472cb49cf8881bee184e5acf63470575169829479004f0782c414d5d492c259cdb7d7931db3e48eeba0ddf5ddee9bfca0e516672a7f738d3dd983c7123a5118cf4108628343234d6a46e72c1f692057b9998ce1bb85d0e409f2f2ecc4db9bc2a83bda86ba89f9f17014e27e6b5cd123c2c61878df96494da43690c813c6271c3ce22e8339a5d4af5a8016878c8c44423c26e6c69b03ba065cdd498ec8555501c71af6670805aa40e4a91eb458d2f91266b2a8cb42d64f293e4085b340ca0ca3ce9df77b41366ff9e66c1752e9caad9f9a2e327abac28fc822cc61fd656baea3bee892ce70eb9bd975c090c22d6d73294f4a1bb9caf63c197acbeaa1b9420b05966356caf9f8920bbd1ed4d4c584876caa8af7e5e803788e28bb6a7303db743071245c3a79f22f88e6d415e39009b5e88ff71aed406eb51417a6 +SHA3-256: 58945aec00f1bc845a8a8f2cc1917b811ae46a692170480e04c289f508c5a7ae +SHA3-512: 9499a0fedef7d0016467a1a68efc9aa27e6a5b8a917391dd29f6aa2c94f792186d60488b712308a116a19f945aa0ee626e3009aed2b5aaaffda25fbf38736fad +SHAKE-128: b596dd197274982a211fbbba8cc31ec3f58e7a34699bc9e0013098b500845c074ac7cc993e618ac158797afe81978c28a5002a9cff10f5115d2d414cb4e2eef593264f127e62cbd03f7b1c83f6f57ffa0f744ba2742385844458367579c48786f6fb08d5f0f9e6625bb0c5653ab429d49503d5ce18b67242654b18ef3988d14abaf889d8f9b39a6c04cd48ed71878eb91a8f1ecff0d732d316e4c7e76c0fcd3b73ac1fc4b0888ad296fae87d0c8ffd27a59f482da043c0ec84632c249b26e3b9edfd18eb7aba8c2d72602cf569ab924a9fa3fcd0d9be8e8e30c06d9e455f278960099305069ddbe28e187e27a28e468441274555754ea714d6aa67f6f9c53756b71a3c8da0b4b34a68783825cf7cf1b5c9e703bd4c92d4927ba3fc12e3baefa812af098fa65cce43fa1174e06e6fab579c9d872e5f75c14e547417a67a0ba26e735d96d536668a3903c6e326403929c558a9c89d994d7d6c722a77194d2c4c6e1a8f5c03bf59896486e6be433b408501c37f8cc32a46b043a745691670d95d99cdbd122863fed07d94abbc3dfb3e71838089b5af5442e466c1873d0e40555928eab4c0bad383974251c920460a69d568750b7dd3fe5a5a955832efc4900af6ffdbe2a7cd5061753b89014c1443f6169af0a9bb50283fec33dc1c85b53c612c00ccea6ffd4d2c0301baa8c645c6957963665539d51a4496d92592e038932f7d30 +SHAKE-256: d14ce4ea407aaa340432dcd6644392dfdf1be881950fcc12463c63434e5526016250793933da08dd0d23f17b49419072ecb216947ca11a01c02c8c7848ccc047d29ccdb50c9d9bc6e4ae86aaf95089363833e6718fdb83c99cdd38fa4c5ba25ae1ccf6f3b26a02c4c0a968cd54a92a6fd9c50d439138a3d189038a0d9e64079517bcdaa104f157f9e16c137a5ae0e09cb6547ba0a09202ac2416df1ee662b13319055c1c2db2d9103096b7f6293a46f98f3a79f587bb50ea575aa3637f57ee99c5e613895b249f198c0c5a40898c16adf44542df020f4e8df430198ad05f31aadb8a3d30bf0564cf57c29f56f4cf6074aceb9198639ff1e273d28329cc18eacc481e8126a6a6214f88715667fedbad0f1d9eef2980e49136dfb0d0ff2c3101a6d24e6d2cc38cba98d8564d189d526ee627e78fb8e1de90383bb4909785fc5942b3cfc763b237982769a63bffa130b05e8bf40fe63f1a2bfa12cfd4736d8c836b7dd11f00f43691b5b6b20ced161b2797dbe2dac4afe793999bca208c2725148b302ff6737bb3fa5d877d4f43a88ec59ec266cf16a8e25e202434381d477f1261e4df88c8be6d061b0a8253339cc6d0bccc515cba38ec99416522ac01e41933bf6b67fbd2855faee4bba9cdde0a758f67aebff44620a2bcd6d8e62ca7289890b938e77831c3252441a9238f52ad263f4b57a85b17f34b0394ad1221c1d7617bcd + +Input: 2d7e340c5992de30a18da9d500d4c7791cb7917265846db7a1a368d86a3dab6d6d9018c64403961e0d59289d8403f498d5978bf2e11ab8084d79f9d243d7dd7521c065515bcd41a4e897411347f18780406d554fb1abb57bacb586ba3ef8aced462a59fb74e2503f8aab7182bcae6714e7d3c6e1e28890b418ff63870223c915cf8c375c2107dff152a3616300463f40cb74ce101c8a0839bb88fb000f1ddeb76d80121dd79e8cd8e0decbc8d0444e2e649b56aea12e569269dfd431ef2a6a16332994feaab30956948776325f58d1e74eaaa408974d248278c02c5fcb94e17451841fd69aecd8f06a4262d4c6b03ed96746adfda38b476c9e7750a1536964601fa6625c68f70d384c28d4aab6d63436637c69440dab709602fa082bc1cdaa59b8a73eff70261c6e361648ddf8a5f6288449a1065c2bfe4760c921a677643224a08afea4ee8e971e2fc4ac1295839ef51ea37b0e8add666a7ce51a9205035289bf7382953704368c36ee9ce77e3dde31b7c06f4b5fe1b746608beabe0015dcbce640afcaed5ad017bf6941cfaa +SHA3-256: 74f8761d31c8139b13469557e5da3af8b577762d39fc47d4192f1eed0ee3b92c +SHA3-512: 7d68a5cb8d26c2c6f45319c15264d51d69f6d42f578ba4a8946dee1dd9e77860c7bc30b7e5618907b2d62b1597cffbc427f53564bf32a2daa1071fcb9f3158f1 +SHAKE-128: f73f5f368d86f9a1a4de508dfdaffcc872f144c67566d53e36895311c056f79e729bc6098dfb910df952a84fe915107f326e958714d1823d027433b17e7cb5a8130c41458e2b243a8be147b84932ff47a6a1d7d300d377d6bbbb2d9376291133b588fa9ea960f22177e4db7994abb87f444016decd8404369a55a154a9d73bebc339b3a6e098551ec02940d6dcb63e0c9c34cbf16737558f2a138f60d5aab4baaf3528f0208848f609d7ed8f857ec8a34cdc08c88d93f145e7d42553f6496c021e258fc329bde7870d278ac7761d99d17e967e9547dfcdd679fdcacf6c163ddf50aeb5c8fa7f2b8961b1ba3465cd1ef49998f576227bda7455b2129ba037efd22046e9b6daf92d484cb19c60935a101270c1fda39d0aeba436ccd6c7ed9cc687a878858224f9bffd9fd074039967b2029cad5930a90c52e30bd3b14c379cfb385c3ea7ba5e43374fd8aad3a5bc1c641c3364ab8ccb33b44acd6c3ae631f688b9da82001194c9d60bb260f117a1eb9e17af78ce5aa72508710cc5626aeed2c7a43c35cdce4ddbb397c46c36fd973263211c8664b87ca0be17c652f2c0bba662bf99628d1c28f07f11de1a28d49d594bcb64182f72f918612105a790ad0bb056455c6889a9a07b465266be1a87b6b4405f2e0687e46e7f0f62020d15a2f93caacc692f558bb46baa3ca58bced76ce2d0dc71be1dfa9c3ace9a47c618e9fb33f248 +SHAKE-256: fb187b473b897d866196e18f88150f2b96581caa25aea585f1927107ba353bc1fe8fb1f1e6a09828fd88824d47d2b5f2bf5cd756f51211c770a7d0e1d89391cad07b8b56884d38650a2f695ca36ee8374cfdcc961664edcff246756c6360ad5ee3851a4030f5881a7632218c6f607ffe4b88cd3b9dc4ffbf5ad71c85718dfa9ede0404e3ce9308142c77d9f0994b1764ae3445e37f3ec34d9380c0c9b7d7c18dd8969ab3174970d48148ce1bb2e6a53b37c3852d4e32088198e507c6702c0612fbaedcde2ebd134186b91da935c243ef3579089b362659540f9d7846ff2d597ba209753a5975a1ee2b6cf229bf22309c4dbd10d2c75d4836b943797a7dcd9887c14590fb37e185e7eb32c19a476f1b7488828becdef7fc323d53acb7a125367625032f6db439f1626156e9513372a0557b79384e303cb7c4ea527adc08005a2fb8637ad079255300d3f788a77a29000c9547e6927bc109dfdd9803eac4e67be32194415c0c2c1f5042a51fcfa3de15182b0720bcaf47f743fe81a97b2fca5c5b525e693e5a1bd295a006fbb9b58fa238678c4d8e83063a15ef2f02a7b080d24842771d191bdf52533e89f1663d3735aaae542a82295e0134d4cccd95315b669975d248cdc5e8e64525f0a02ab51a303f8bcc8d9f47526237dbda29cb4e16f13b5119d244452695caca1c5a2fa02f09c4fde43668f8f2c1999b28cf86a5c08a73 + +Input: 4644288aed84ffc12c24383a71339aac98e775dbfd43482524a8df3dd99e5df181f23aea9cbae39f780b05c823b2f0474483eaf5fbeee87704eff7081817b14d93b617d9bd7726a34261eea5a8a6fa64e9d9f0a7501ab543e2c1fd60a74ee5bfc55f2a432cde8c6865822d1a2f59681a0c7de93f96cc39517ee0c3a13f1f873ed53c902eb0dd554752c9da20e21179afacd203f325f994436557783ef98707ebadb30af2dc7a0aaa120031ae52ecbccd3838027f38a223a18f285bad78e4bd5a050b17c90a1ea3f2442987678762ca8a57f9b5d406f0e0f0e626939612208efcbbd3df3463094c88dcd712947310b2ca8cdaadf7b5192725ccd4d593240c7fa320eda5685ff83732abe1bcfa16f644568d50ea886e951f291b9c57fca8cd5a2d86ae6470fb2a2f141d8f40d3a54fbcc09d76a57677f963ee58109284b238f0f3f421120a26dfacc9cbd0a4cfb2bb2516f053d692539465a2725af6e7d5e5ce1cd15d8079ac78105c18ef3f55229f5629eebd375d5367f108ccc64b788e4c13c9e7be2505e915297defd8a1b39e90 +SHA3-256: 393f4d54c7bc96b2790fa959333d584215507463265d0b513de5fd6b456f727f +SHA3-512: e7db0a035bdd41f85366951dd5add7e67605df7a0ca23ac3be177e71b5c9ac936bd6c01a0491a97b7c3e02e234aa672f70853df9c768ace9c5aaee2eaeafa002 +SHAKE-128: b1fc316bd98d531694e45eacf146451cbdeb42f42aebad24c64979c079950490919196d95adcd7710d90a5ed16200b72434d4c2fd169e97b3fb5092bbbda3d41f7d19fc8e84ffd922760f62fdccd18978b3ba9d25404c8408e2cfebab86238081315c678597323955baf89fe3e496da16cf064818a8c0b4a515f66c3b6f174282910901f10f042b57e02ef06ae38b2a3fb2cb44cdee923c545d31ca60e739e6a3138fefa862fcc9ba021e96d6f8e2174d6c6da898439612e0483f2d12ce5f1addc5416923d6a572be2c85878705cf1bb3b782ae93c8b28c43ec132c13b5e606372e797ed27f7fef54fc5b691a4d9b698b797439718307af9ddca256441f25215e86c2f8e5758998d43427a8cfd034a26511c07ae534f1de841cea6e69c0963539b416dcee0c573c6debb4dc6fbcd2ae634d4cfbd59ddddd6fe5d6b6cc2396a030f0aa901eb5cee3c2af6d7f6af0907dd461deeb729913b5663d3fce09021e18c6e3d82a503f5d51cd5f26aee454c9310b1a7d1de6707058073b567d59e8b83d27384690c6954aaefc7b44e4ce0d7cd110f4e9ecd3b77a835b0a4ab097428f3b4a1f60c7f241078c9fd8c54db2fddff59b25d254c860c9fa5ee8197481f2b672678f0e287e2f435d6d31d3610b284fbaa8f7d5375ff51712d63cdc7653f14c54027568709054417837e7fcf218bbb6497cd80520233cbb99d618dd545752e79ad +SHAKE-256: cbea31fbea071dd2df595a77674baea79f636bb090de0bed63f7d58a2d5ef29c9e95f9711aa15169e6152db8f64cbb7afc341a587f955410e99f83f4a3b25608778f6c4e3d6c01dbd5558c6810348b838dbdb338a996bd0f8ab824c9b47e5d039be845d1df1f28f8c0f69f2561774cfd12a2ce8654f7d393748ed5230969534bc6a2b2dab21a658b87f031521a7543a0da9912662fbbad5b9049ebad3b1aeb8cdacb4658c39d739f57c7424372f52d772264d102200703d2b507b5c0b4cf57c6cf182d200539dea6b4eb30a17c82b73446f5f3e47536542f2ee5f5b40e95c848993e286c688ec4ce243cbe3f2c1b3dd3fee022bd0584c856bc33abce447d423765ff69fb0511e25a94abbece5af5a12de12e6614b32c79c4dc6fc2f599ef5947ec682d890c74c9f1019fa8acf12c0851f06212864b70205027c23df3c23ec96c52db218bd5cbde63b132417d061df9d1acebcc97e323e0cf3354f53bd336559f8783fc7d0785f24f87bbff15226a584f4d0d640d2b22fc75c464dd3fa3fd9e9e18d12d0a7a0bf1a584827db98ade4ef93532da6b664a5ede2bb865b8a501b4a703e88ff138a26081ee37a736c9b68bb014e033da050c87534269535f5d2c67da854a144ec9032e31da45bb9a76ebc480c3b267db63fd1a0586fd58ce345ef39f0717103d46dc703b09449bbd386c82a48a39528134579bf6efccbf552df12cd6 + +Input: d7e9eaab91857a014ec93e8a44a61c454ec8051f541e4fd3e99c7a1f70ad423b87dc79987e4336f2868da8bdf939ded0858c0fd94dae0fa495b2d36a82e029a258657d4049f4250d76842f4d3782e3e53d54ca0d533b6a0d7b4f5cf09fedf4713d7e7fb8f1387e2bafa66e384b10fee52716f3e1e6f2580392ad3e5c11c2ed0a686633279a32de81e41aa7a304621c8f1290ec35ad0d6ec64b3d4b8fc3a43dfe67d5272b048c1702002271f670646bc64256d9335ff7a437733e3cc810df1528ad130ffa815db46f6a7d08e3e2e61196286c99c73917d1756ee87d4c3ea66ca35917c1189f160d789aa19cf64ac7c2a7b5a738245683177f6bdb434aa0b0f674b78e2396e216ac6d14081ada8d7f62403cc4791bb75c511495c024e93b1ed81d7914845a635af1db74b4f58d9c12e0ca48fbbc4c85cf1941f76f9511ab5657b26e4a8e2cf21c1aad74bcc4b9200f85931ff842ae8aba372604d9283617f41723588779e798dbc056cf2620b3dbc3b40a1e7d24b214d6fda2ff273f58056cab4c2e9a858f8ca300a176ec7fa84b28f4 +SHA3-256: 507743309af4f6a4ed517f43157d5e3adae25e03612037927a5746167fb15076 +SHA3-512: 21eed916f6bd9fb6ae9fa1ca8d425ce6ffdf310cfc44c63c23c2e330b8ef48b4b1a33fb10f69a235fc97e8d46d5111e4feaceb2b9205a7087850d5137b8521de +SHAKE-128: 193568837006f0675e8ad7211594c6f6d80c609ad801e958d3cde45dd2b4c9e5837cbfaa4bf3165ca93f012a27e20fc5294dab4faae771e0fa38bc9c511c20f75abe4befe0229230fe94b691d1871baa7c790b6d620d727b33c9b407907c10734b25af0cd2eba4cfb28ac736e7fd89403b505756bd710b4211cfe3a61d231eb379b5a805e7a02648054dae0c3ddc3d163358128244e159424c9402c555a5a66fc98ad3f2c946410df452f72f69351513301239a65effc505e3c3a77cec236db034c4116b9fb3c3288db78fd97f672cfd6d3aba98960ff735683bdd67bfc2d8ff61c31aecf10c395a3a31968f79da366d510bac55eb7fd750c127b58d16ee4f3d1b1598add0bc26dd60021370948e09c500a0ef3d0935ddddd1a5077be84bf1eaf559f720d5e2adbfec9fc6d58cf40922328a3b2649d254f2a25c498a0e40b3a84abeeb7b15c1deb73a561ffca0692ab759955fc77ab163d2ffcf7252d2113e18a870327d1d8288854abcabf167d05fda1334c163d4171b9ade74a32a07a12e70b494a180277933eb13773b646fcffc10501370c6373d34b2b33c32bdbaca61d0d0e829373c010da71faf1c17196b1024bb4c5a28428f53f229f04297b56e53f6ebd70564020be8e3f25739de5990dea115199782025e37ae6e9e799be46b763a1cb629c19e13dc95e96f67ba0757adf4cbf0ff081a7abd0d738b1899244e94a2 +SHAKE-256: 7745eca85db88e37dc2b5231b1673c4cc7c71c35e3d0b9efc3b238e3ad7fb9826a9b6987f1a7d28d4b613c7b11788bb3cb128ecbff69b50109769c6881d1ed64560d051ef5026de1e57fc46979f8826e874cb6a809e4301eab2e2fa4935e6bc76b9e80419c99f3402a8fc6f21985428db6aeb6dd9ca66161dcf4cdb111f1bf9ce62d2ee5c31aa30ebe13603d01ed887dc60b1f5156e972056c7527688362348f1e677235dcd87c1ff122d99c0202762c8b5c1548287aaf53fe5d07d42882af0988cda148c59b71429597f3b179ca53caa94f4a0c064a8b5cdb72249b9e60a796f433081bde0d95a2b7d7e50010f99760194a2ff5e1f14c2b1b6db7ec71fc22a49f389c41552472b8e198624cbb6ee6d0717c5144c7b215937c8db5ab048db97921d8b0dab9753539cff30277808a79dc0d9fe067795b07ed3b4a1dbcfbc5b39c37850971e5b1e478446783901f52cb048abf937867e849188a721b08918be4509a24503808206f11aea662286e26f2c0b4345edd1edb84291e4ef68b822e367da6927cf58abc32d822af609bd9be3378411d8b85ff191783e9ee1c1210497a56e0c6bb69e74f2bca54a62cb0676496ed1d25d0319a54804acc8b191e8d7aa4f4eae575ec41f4600ac3e04499703865b27713e31865771bf11e87eef8cb546e95ffb2898dbfa0e3ac1afa8bed65fbbf74e7a11b632e6e7de004bcf131537f8e50 + +Input: 90da290aeb99300dd78467fdc2c04d1ed87e7665af71c4ebf052c54d37a68bd59d21bf9c59efa78b0a1bad7c6a5e4025727868fdb4e0283ce7881620e42737ae9c9781d60fc651e6988c6715de14a681bcc3d0407a9f9fe30d3c9721b2093bc6c129df5933f90973bc408edd963c3f542db7e6b4f9ca91c0b4b7f79a3dbe913ce52f6c24d071d5f52a0a373f6487c85154fa04327034cca8bf88fefd908d9440c94f742ad6ef40885bf99e75513a61a4d489410ebe91a724f7c397498df52770f2091c88b7c2e9e8f9b30fb31cb3ad5240ea9c8e4b0ac5aef022755bee74946843fc57e899d336e974fa90ba5bc9fdf171ec5d5638f3a6199d9cd31ccaecf2c4ac7878cd0e889b196aee9c3c12a5554868ee09314773509a287fb81383eee61fa986ace0976cbe945d0534e57c3f0839673611b19917f1b5d15f9290d25ea0d0a9d70cdc12dab14ee1bdcb0c9d60424d88c225b1d205f8911458c5896a41e5c2e30ee8d4841c032c301a614acb9343d15427bf5cd7e83c5264ddf3be4f119ee78833831f6ede94c6a3c86016acc7db9b +SHA3-256: 5935affc9b15ad7fe488e3f724a5783e52d33b863feb22ce0971aee053d461ae +SHA3-512: 8de4c52bf9bb9da481a55983973a44ca62a270185eb076f54307c5191a153c459310d6df0858248599a8dd3f320f5aa7f38fd8dff9b41250f38a4ef3a2a2b031 +SHAKE-128: f806eb93ab809535ce73a70fb759d03f8c1c510c75215a79c239ede31e7f36b90aff05a6e524110c53cee00789bb9d72381007a0d9966c59d722b5e79d060b32cc289fdc7f4fcb1ff2ddadf81084013a1a1ad2583e955772aa28f416f4863a03c45e592a6a923b828320f73fc4d567b1812d1233408b10e22ac8b12d3981d717dba4d5c70bd6083a3b96cf772659a4b75d367c6800f7ce7e8359a3c1178403592d3a5d1aeee5a3d3851d41ac8f9e112c57ccfc8c8bc36a7d1f3dd719f762ae8d5dc016d3a447abbfadd9e0681466d3ac9013b75b6c3c847840c792a6baa5e92b7088ff25ae7d8869a6b3e4b705e184e885b00dd077d2a317ba2c492fa41fd039f06d62082a57586d5fb82cd140cc362b98435ff0844074cc1541a702e9fa78e85eea0cb144bc0e8f5d2292195c19b2b66bd1583960319f66bbcc6e9a7bf1433344862e8ddb6a15cafc71a399f7480e5c1a4663372488e6b1a963db63a29e80e5d79a18a4bb5b3536aa7c6a7e1b679de3214b93aa40c0bb3cf6c4371864322eee5e63f84a1aba45c04fc78d913b5a5a9ca5e406106ae6ac3940b6b54162debb6b1089d9ee5971720b32c70b7ca3ebf37e195be28f3bc0c7ae35859aa514c398e7ab429fc6676847b6cbb4698dfe77d58b14bb5c065356d7de985f5c49fedcd6147ca0d612b2daa6391c89aafb158368339c72fda9a90b736f32c209a118895882 +SHAKE-256: b55bc28a85c43b96addd5c61410f04ee0ff0e6b50b5d9517cf3b30f609052bb2e3c826c70dedbcd67f852af0fa2794552a790e0475e7765456016ad56a1195d5d1b3bb8760ddcf5ba17fb3e4a88c4740bbcfbfe2ae16c53a5350b526e5f9b28828ddb4e7ab0b8afbb722124d7b62204ea4a5a8ad57c1bdb13014021a19392eb697505b65b148affba2888223af60e12003a1cce6245e5224cb174a0e761808c265258c07d32186966968fd38d042377b7bb758df5348c24ddaaad0d855d59daf5c58a6ea196aea5a827232993c02858c79c15fec83a9cb26fe8627a419b05872a17c981879a5bb0500191cf943522c5bd11327493f8c59c82f093d7eda78584d0508d94f93fb5e7dec2273144c2fb8e74518fe76c69c543d0fc165a6e68e2cd6186462b5153f5927e65f59eafc2cdcf6d50b50dc91b39406b9f44b907df780367addda8c038708a2776ad69512c8219f7dd764ceae804678a922dd2a1f034885d7298d775104593be12d56ff303e658464cbe1991059f62ed0162f9ef3fe28ac8cb3512f51fe9857c88f90824692fa382f24a36f1c629824d2c34fb3a4925211cb2466501b91fa79f6c76098f3df25f1b114667af6b308c8f6c1dc5eab56b12a4fa672cf20fb15f1f2520b47301a35a40613c2ff797c8d3350526c02646730c840a5e36f46ffd174c3a203d4e34ce7b70e1bf7203199453b393154882a89b519 + +Input: 7b3390819c7586e7a59a64bdc529e5c3bec452b1f1d9130482463c45686dc2368b0481bae88c5d80c34adad229497a8d3c6b3982102697116c444e4de964d8eb1375fb785e33232d40fcb020aed7f2528025cd803b89d0acd5f6115a9eedf34cdc0e213fc067043492dd63c413d17e07fec07e7b16df8761545af478352fabb07b7fc8950a9d4cdcff52beb0646b319d9ffb614f14fa675b06aedffe7c6b3acdf9b8a969552d81fba94ea99f19b969496ed75d86ac196b7ba1829c421e8f6c0256783a8813c25362039c3ca4c18d255fb004305043a2b0ec7aead4aa1245c43c7722589586601193762735c50e603a5d7edab6c717ad1b3fd253385bb76b118275fe83a70db915f49dc35ec0ac3d87c8bb02aed4f1653c101e0b7362b6134a9c6b2b7f2265c8af2f0cd677df886ac9e1420b945f00776e1080791c5ca993852c6e260092eadeebc879b00efdc01cc051e54a48171ea09539657028f743bfecea77a4c8b981d86ba447d9cefb69860a7087515365921ad8a80afe314196e298fec17d92ee4ec7cb0b0a5f0f3894aa9164c4 +SHA3-256: 3450d6c22cbdd680a07f45518cf25a3fef46601667c45f1257885b53d5c52db1 +SHA3-512: cb8612ddadab8ee26d9fb128c89c23567adfacf11d551770a29db1cf37646acf078efbcf665e99d1adeeaf5156a07a968669236f994129dfeef634f644a741d0 +SHAKE-128: a4784e1abad8b37bed79c22a3939b997d0dbe41ec73e60da140d168db305e9d1b95bdffce3f1357cbf22e6eccc1ebef9e7e589171643adbf5fb09eafff3b272d784172f557431f2ea21b0ba60bda2a9495548db20a98394fe0cee66b9ef80938dfe342bc5724eab3b3f9cf23fbec89def20daaf601e247be67332a64dcd9ab97b73f8340f3337929e12f2c505c34f16cde182992f81295e7ea0b6ab05f0c4b776b50882113646981a950f50b793a24cf9164fa483c3cee5277aee76c54abcbc90fdd3246e831b516f94f4712bef1067939f04c2c7ed189aeeb269edf104a0aa5a54d6cb30b984be31b00ff41e43b24378a129275117cec82e458b5be09b0dd2f504e188057766d7cdea894349ba1c8c1a590d3f7e3e9992c13f29b8e6f31c53a45b852045c931c8342780f8d780887dd5a07f1f621d5a41f3c9e1a6386c0f8c0c40376e4cde308c2b691ae13abac2b9d1a6f909058487682be1c91a63430a65e878628dfe312731d78b027dd4551e67baeeb2d9a68c2fdc16adbd3d981c37be546b1a23ad327cbd4c75dc732ef4586174c1854dd90d260ceb9d750708b5b488ee12f352ca5829695d721e5849cd615f6dee85cc6d6038037e216dd5b0ac21170d6e9718971d7bd1f1d89ae657b47a735974ce69213220aeb7e8ce4446e8c12cf8cfa3744ac1ea4efaaae18b98ee704b314b7a541f01afce7ff5e5d50b4528990 +SHAKE-256: a3f7b68bc0e6d6c8e6097b3549979fc3d1617c7fd3788b86a86caceaf6b887c02c06bc15da0a16c3b1de93a9a57b6562d98cab0049fd440b844f856ef90f1c20f7279c35de73a28b8e896c857dc13931909ed1c4f04361e0f2809794535c81159899a20d5369a14dab4ad9925881aca6a65cf13de7ef3ef16710815b3e1ef55be129c0990d2edd501e9020247ce0652f5b5c59db0e16fe5aabec161db8129812d0bbf5df0a3c343451393c8e76b96277814f9d483205dff9dcc35a3401e2b540804b4201d4cb94b6c514eece1b43e1af7ccec6eac26b40d96896bb4a70463b3cedd630a228eff16790910caa18a8973e6108177d8b176763506c566afe8c1a59d3aa7beb82c76313fff62df4638b2a1c529b79bd1610827fe5ccddc906611a3e482c0b9be99a074c87d1c013f72efc36e697327326ee3e171e5a3e63c676896e52ac29c9f39e1befb7d12afec3c8326ae430ff33f07020c6977b29b5728fa1c19214fc2838405157e4198bf6652500d6f734120aecab83c16af242fd67a50b971802be8f26fe7311d380c33a061872092224e7cf18344569a3bcdd7c8c2e7faeab97de6d4638ba74ccb25e0ed353e190dadd1a3cb5873b7374c631cd198292851084c68c5b2250759e12973210acb3545c05199e4f7557d025b5f2a5d357a5f28ae4a0cdbbd3954db1b884301f989513b0e454ae9ec4f0c1bb5713bf8c59ecb0 + +Input: bb3f53459778f0c0f5a9192868e735f5e2126bdad7840a7053a8be2c62f178a731a800088ffec0142b0294b8b04fb8c4f170635e458ae5a985d940e2a4e6b7a10e4eb69a638f4ac842ad78d1ccf14a4de413ceb53dd201d3eec40fc110dc3f4cbbecfd1eb8679cbe6dbe62a804f8c82e0f9a76dffc9b125c3be7f7e2674fc6790b2808001de6584145c7ee97ff7493d818a7d9642c8015643035c0b5609917f0e8089150382cc37cd23485ae8e856fec49ddcfecda688c984e4df605dbd56a85d7788e266ff8c76b0fc296f25cc1b64358022e62a203eb959b5c2af094df102b26ff6e83a9f76755bb00756f9cea94de0b4e402c56b5285405f7180c267f942d2db4a0737cc27872babe5aba80625d262e04c424d224490a4f944f2897e97201afc130953b427aa5e985a5dfc98d64d4678cab62b808db9d65685aa8ac82ccb35a0b232c42e218c794c6ebbb101e6100d7e87fa060f461831e8b332e5d5dc3bdae93ce823b55324b5afef37860220cfdafa8f36fc062f088219174db851e0a34989b437361a2caf408753b9eb05d42ba2253 +SHA3-256: 0f969141037ce87637c5ce8b1932e5465a0f6bf9c1b6ff91a37f92b2fef957a0 +SHA3-512: cda666dd5fe282dbf592d99a797a5ef8d189446e7ce1cb9bf7f114115b810602b327ca4c6c347a8fd49fb49dd82017d1c6fc32ff26a5e40664a6580930a6aaac +SHAKE-128: f6dd532d02a69224c95e8d3bfe65219b919fa5adae83410dfef4204b0609f2d1ffd402eb24551cca9300d23b62689efee929cbb799647da89230ed210b71e787dbb6d003b4e9adc8eab57103a9cb82bbfa6175441f7cd5e71f37a3e8d4d5da7d32b4371ec8da53264330fa458b3e07ae56081e8580c4d1e56082ef1806aeb46421639391d4795d28f0ebf635d99ffd7acbfdc457d88b41b268743f20972bcbf1eaccff81cf9dcef9ba9ae7f087972885f0ff391fca6ce1dad088f81bcb7ddb0e6b49c54d91b0bff7980aa56d11f61b2d84af26acac246c00756f64cedf090428298cf89880beb96da45d6a4c03788004a02915873fecf5b8c60494573ddc87770526d279057741568e51654fdf702a08a8ae6815f6824555799592c6d601b18ed0a816f7d3bee88776d265e0444b1cb01eb40a445eefbac3c4a0622adba07dc1a735c96e3ff330ea7a3501f1d5f0709f4f815497ee1587a9d154e2d8d59a52be7f8e789e51801ff06e919566b6381e502f29b96baa32666e14798d141f396554175253d5170461ce655d958262d0788b14706b42fd6b847c5c2be18c10f954a670b4abcfa68263ecd2310004cf875576363ab54773f8fb989f55d6f3e54d554825503327400dc981fcfa4727cbdf6e0ab4650ff76abf4d8714c16ae2e494b2e7c74a30cf8aa98b93c4367b1953d55176d7eae938720d9f80151742f480ab09f8 +SHAKE-256: a0a8cf47ef7c53541b0579893f86fedca88b43de5f4b78ced9cdf2e6b282a6e171fe93c98b6e2a53447f1712700fce05eb32309634a368e1d1b2d91381eb88b5c25cb47aeaa31d5da36e1e225a8bb2f54ae2328bcbca872727766894574fe93ad32829ed91c9d6a4c0871eaedf03a8e731a3c6f47e7d19470337bfa4d02b2724448123273e443b44cc8c5bb8b0766cb2dc31d477a14a4b870bf6ab41e5beab3ff7fa57e90be6cbd6e250e67bb4bb09f438c615e976ba6a5a67cc222edc71f5874abf82f30bf29d53b16719132c19ef29a1b7d1ccb56df4c2a8a0483de32936d7e23635dfa4ca6ef4c2ff6ba5d3c2a7e40d58c533641d7ea5252c84973efb1fd18d1ee9722908312da864d02dd9459515390f92e2b1052f64c80bd344c77218339b56d371bf0cbe4cfdd7c4e94018e631138d201c6c488192481d6c636e14a62cab74f0b6798fc447c6635fa444e91dd6aa5d0a88cad66c9a1593037f0c9022b4d170d95a5de385403c5a38a422ccde6ad755c33257a323bfe75aa331e249ccad5c7d4c7a96d14b625e5c9162b6de58e7bf60944caae0398f49643379cb7c5c75cf1ffc3e14fdae6d6598034b685717e1514abde8148e0799158ea418492c1f069be98e1cee64c7fd6ebd1cd8b2fb79bf7a1c175e555d0b316610d36f33f37072f6511e402fc38e13b829369ccf34c097066ecc6a92e1e0918a36ca79255c07b3 + +Input: 727401beb5fd6523dc357b50461ca505802b9644963d18bccc0e608a1bf03c6bdde33d231f35dd658f20400bfc82e0478275b82cd49f1a1d4965c09a5accd42987a978ed8764861fa26deee8f8777891483b42df7c517b98d3454f4d2d47fb699f01f10b8785d8ffde092c64ef24348392a5c4b3ca4cc88f697e5e365abd8ab353c6af866d19b067b77927e8e67066f1462e0d0df7ea073319a848597fa79c8f320d46f07b88975f7f78783a6cb1820a6bfa8a49703a43c7fc2d2da5685229ea2f319f252c66e683d4a05de9a3f6a5b980a592302d3dcb137090b91dca04b08dd273d34976ac5f0157e27da7b4037f4afc2885033efde528ab36dafd664daa83ef388bbfa60ad82280d3e060530741420b80d8f4470abdaf5a3f9371cb033cc66aa02573fe7a5e6d19c33278d5d5e196700bcb4c7a662ba09f7f6f56dd4971ed7c267844ec126b3a55682e9b532f1e7c12980416f9049efb9948babfde102c024e7a5245b4c9fb342854c5cfc7c54ad0fc9bbc2c4c56abdd9ed8e6349af809c5ce75ecf886410a6675ea2366958535400e9283 +SHA3-256: df931008b451441679dc01ab884772b527f4b3f73a98c816e0c95112f531d0b4 +SHA3-512: ae7669dba36065ca0ed7bc6d4e5e4190246f97b75b3e71e3ddadff44289aed85100fe7401bf176980674e22affbd73b2ff48721fee62f45b91fad2b33128aaa5 +SHAKE-128: dcded048919499dc0eecb6c1e3eaa087944e70ad8e2b5c9cd0f9f7bc45444d3051290bf7927d26f271c006c72a71d3ecda9b9963ca48767bd6539c14cfae69ab1e611a8309f0d4b7851143a547df716c53512540171f9e3743a24a0ec2c971dfade93c2f2dc8277f2dc96aa56810825fb31c452c0fcb14e6a1e07f9dd5854b0c4da97c2cbac2c8abaa6b807559ff13f3c8bb4b124dd53ce185c6e66059675a84e46464207fc007d89ec99787b70b09342f5c55fb081f7f01bd7d0b822a9af68511996603fbfd15c15e85697c2ebf3cafb8189ee99a0621bd9f23f7426890f6e1368f927ac8e646c86550ae665fb7eacd096caa7179da374d2a01cf319d9700c09af0c9f0cab01ab1b98318ea997a072dac975363a390c2ede4401817c94fd330ca1fc9aa58dc88d0707463779d4f49d3b32dfe7d78ca0ae63c9c54258721ea44dad31bb225031b104e4a18915512fe0db3e4effd4e5c7e7343a3b046088d615a32509fb9fce1eab12e14e3168a9d3552257935716b0c75ee0f3b72b5ed8e4cff158f6d8abe3ab5a5ba1898919501877d040efc223b679240001fa8d1506b34c1fc7b3dfc32b14a5468ffb04783f4c2f1e981227628e48c3d370c186765bfd2b53760d944ce0454810c39b344f82ad9b2128d859a2697844315f3ed780e7e7ca38d1a0b48e3424ebaa64ee384f2a7f39c7e887219f8f2e9ac90ed0912c3a1f75b +SHAKE-256: 30ade12f1fc32c8626893b8bc6e7c14c78078a28bc0e9ccd3456cd877c68adfe79abf3ffc4ecf3e297d042d6ef957e65af407d1778362881ccbea52c3ff04937a4e3f8f383d94561f35ac8287004039d9baefcd082afc55e8850d674b56812b5050fae36f1796114938b74f98aecccba0da42a02929cf8be958ea39042dbe2996f1b81b3464c6d168b43d6ad2accf4388c3043ccc156fe2c0cfaa5ea534ff8cdaf30c39b389628a969b4bdd1c15eb2425d50145e22bef574c86537f06fa4409823f954776765569aab2071be1351354442695c93b08a9466a7ba7d888b1210efae148e5e71e82f5c7f74061617bd1e833e3d44e984694fe3bf71dac1e20e68cbe40852fdaef0cddc710af1ef8b30a98bbca82912db70fdd3f204b1c63125c7bfd8a46efbd508437e8f50e1d7a0f7b076913ac8d104815e6424f822bb77dd7194f44dba1f1745190fe5ff33c7e5dc3c0dbe357eebcd6c3ff67265604a6999c22dd106d829ab123cda3a161ac03b00c66109d84c5d49380d1866148889da29b0fff9652f3a5c9db0b3a8b93813ae332d46264e04ba1d5305c1b0af95b33675ce097b4346ac1a20aa72dc8b1d3d67f14e4752f1228a2eca95e8990861abacb6d9303286a77c2b7bdd84bccf433118de4cbf5bd46c0a1cdbb6f8e2ec8d279a8e177d049c47ac1735b6a9802fdc8730a50822cef834a6174f443f850c5a8be7cd9105 + +Input: 963c9e70e33b9333313674a0efba110168fc0ef24ac99aac92cc139859188d1f76dcdd354ddea15cee383e461128c6df5feec317f5558b48839256783c47bc25483964e80ec7a4b521e179c3dedd4927c32e6b3dc19a5a1bd8826daf73f88d66c32d9c1845088830d0b2aa2c4a4c66bb5c55cc668332056c70678ff77e036a66ec497a07675fb15afc747596938c168d1a2f75aabd2cc2c1c271aca7e4cb79cf22285ea5125728d0eab0cf08c02a96d16cb653dfd8144ab48b89603148d24fb85fa4c430cc3190fc5783e9908667aa1b172f617d625559c7216dea1f109c8eddf2b86021ab98199a76b3864e02c56ccab7d49113de2e396c5a93391c16e349434d72cc84e1d91670758affb458d6f7e09eb30c4f79e6609986ead0b28c8ec07bbe8e700d96dff2afba2f6c0cf6e87d77d62e8426455bc5336ef393dc106731306a73be705c263e3cd1d2af38673da4fdbca3539cd5df79982639d8f2dc793bdc11a40e02d19e655b7daf044e9305ae127434868c31abe8fa2d540e2f2641d1b54580fba89f8ee4c518b1d229e509283689d8d6ae +SHA3-256: 8692828f27f1bd0340acc1669b4529e59e3ad5fa77730c334c7e3be3df59df41 +SHA3-512: 54a4604aab4e58928f415ba83712b0d706c196a9737862740cd9dc82c5ce14b78d1ca90ced845ee879785639680c582de84c1f5da78009f7d9fbfe95fe99aee4 +SHAKE-128: ee46ef0e314b7010c45e20fec89941671ff212c518df641958950a0bb980a8150d2147e3eadae106d5a48d5135283e871d133b44212b03459cba3180de65b9372ad19df4c5f1e8d534a7a7f369e241231cb5778e7637f51efe4be8c1950ea91e09f49b0a7cd340d54f825c4a5e89e5c3a1431db42e89f8856808a7ac76cc1c75e76c327c2b1618509e2cf9e3ca905d86630038f36ec9d0a814f8087ece586c2d10b273588579143c34f6943b61c07bc746d66740813387e739bb4685dc1290f2b210883b9869ca1090d644d9f054f7cbc5d36f39369ebd800745b560af2fc76d513ff0ba297da5a1f8643eb0a3c28356f8353ddc57836e5bc35c4b4ffcd799c6b37726c8211132bc5b9936d98eec999d69ec1dc3f345e3b94711caca41a5827f0148a0f3546247bb2012c6b48898287cf9542cf506d9cb6c77b1418cedc689526016ac6b9123fdb1b1739bba7bdede043e4753b67997030fb2f041996d0de13b0f82910035ca05e9e5ca8169578b8542f1c22d11ffafb811b4bc72327f0a6bb1bc320183b0203f09956cc75b0f3fa615d56aa994333643b52866979c9ff3d22fc92abff6199bed4aba9b3c4d57661ec1763cae9f9dbeeed902c68db0bd80a752a9bf99a2fa00444f39d8b014871a54af8240f90af917ba32fa0446440a054bb3476a1629362e97565654f790832a43186ca6af7a4379da368e965105a2cd22ec +SHAKE-256: b0e9a8742568151ba97dfe777331b20448b2858322ee3e41f860b2fe8ace4de66363d82118bd08b1a758d145a80df1947a95ca86b54f9cac41231882ba3db484a0cc1f294500460a009dbdb79be0bc839d13ed4af69e98afdceef2fb1c7215e3c51fa94ee41bf9a358ee9a9f9e1c51ec5218328c7d6a684814d88de729076ecb2d1a7f2db39fcab62893c7910d032494bfaf43ffd0564032a16c228b9242b59ea716bc1d809536493ec0bf125384cbdeccf40efa0ae264821d8bc3d4e65f4c8e6daa114f69b8ee186cfb6e080ad1d8d7e4b91540ca49687b664d967596a7b41a75025dce1c4d49c0db801ca62e670392967ce6d9a1cbb80139f3ac81e9d4db80525091aeb85bde25e7246566d87f55dca1a8b837cd81d1a5e6fdab04a031337a4ce824d9d321d957968b8d4bc5037379befb4905ba77afc7447fbb866cc39d311a3d0e797995dc5825976183d66f7c15c6776b88da1d06ddc1b052cbe16da1afc3278e906b1fe759feea7775c5556de4aae8c4a2670403499b4eee9b957545802dc0afea7eae3588cccc2fc502ace0213c57350470f43f9fa01a9225716ff4b338ee1b0271d6cf76c95e7cf27eea8c35a2f98206d79861cbcc72f25949e623947ad03da3515bb5ac5dcd748444ae82e878474818c4895c93a31f8e3719ffe1d406eec826d00b059dc3fed1dd9948c5c39b2e9eadc38de7d6c9a8e6cac4774cbc + +Input: 2b11c2ceb444c272b33656e7669b6ce9f8545f78a943ceb71a28d647cd53780e355aefbd2516314808795baa461f3c2efbe55ff892ef70620604841cb22c3a346d284a1c1e547c38b58a203ee02d178d50bf2048f45eb36c55a63c1fb464c2d9752b1a7ced1fa407456708bfb09bb958627aa266265f07662d3b222a51c7ec1adb5aff21d98cf4fc03475f16af1a7b88a9bfd667abbf6b863aec616b785046389a682219bfe32304a3cf8c1c33dcec579937963ee0939e276d5d5189cf0ad30e7332b17f4bba3b97132c44ff2612d6758a3c582c38a6bc6f4e590e4fbddc8cbcae08b53fedceda95c1ed78ce13e35c073e800b7a18d2820675da236577c1723904a79c4ee78b0e4ddaa20ade85303b0238e698294db892115feed7e29c8d1e34957ba2bbea7b966b54988f9f29e6cb9d29b078b18fa2d56a01a2d02af23c712a998a56f8c9d6feaa58989a5e2893d17dad4301de0a79496004abceab08a1e96690d401dcfcede9d3ff4ded49cbbf16419fb71a8373674c553c8f5834aa000976768f446f24534e9cfc48db6294617dfdd6601ab367 +SHA3-256: 366f11d73ed7009975be072246592395897a248e6e9475fcc629fd613f89872d +SHA3-512: 2286ada9d9e37e601aebfe2c19f3da6bec427ef276cdb01fb13025d3eda6078617a22a657a0daa3958df9f12cae18087bd947d6f1af1ada470d8df13f3c01382 +SHAKE-128: 7f8c7b74963cf9c17fd173765ee6570ab1bc1eccb5de390282d3068875a065c3556cba432f2d7b4677669f7f48a3187bc944f41c8acd61ccdc7fbfdb5d61dbf8fd34a060b82099ba81823ad64f1cbb5800463403e506fd7c426e71d9cca0c00670940cae04ad9e4e7ed492112185fe95c04d2028c9ef8d6917615786c20e92f5666a80e930a49516dd126e39fd3b9cc75da4999ebd0fe19d6c62cb21fc648e8b3adea6f84e65f5ab6b90f450b13256bc075c29c7353c2584cedf08a82d290527199550371e061d42687ac8fc1b48560fc02d531c1f0950ae8b388c505362a3661b212518241f329618fdc19170b778977c96baf833dc694678d3fb51f448ce9632a0e710448018ed885dcfe883a1ea1d6dc287c32ebb5fa5096cf43973d36657c895988de482a4521c974d0f04ae8634d5975fe0e24dba39bc54ce50a96214e37c9b749cbf2b0bfdfde942544038073bd6498498e21faec1c102a7a80e16cb4b50a2fc2d76b678f38a0980f883d814d9e13ab1f82ae7a8855a45b03c1d46224f96cc111430692cd58bec1c99fdcce05828034b76ab04d535c18aada18e94ffea96b970d71e60b7bccb59fe60f0aceee22f4826b32b7cbfe780b1eeb666438f4a0dbf90f49b34a7cecb7cc0c162936e15d4351467e40ca823f04b0ce65f1490d614ea8abc7dc91ef3ac70059bf58683b065fb2f0d5e64ccfe3ac90ab34bc52e0a +SHAKE-256: 6c75b70f0b05133dbb5b87b91864652024416dec1b005ca29b68ed87aa5e8f032ad60950ae23645566a35f48bb6b721f17598c3ca97dabd2f9b4ca969fb4bbdb6496d5540987d4ea45edf850c83d484037df8a93f83b5d2aa17d272aa2897f77d498d5cc9389e878bdf37970fbfd99f28695c1b8a751d567294f04bdba83ecabd3437658e769882783d7db6da8c6c82c960191258b4db4b689d4b714f72c5cbbe078f20d409c52e6e46807d2a335f549f297fa73a7fa2744d5357f051a8a1dd8020b951707792ada69fe9aa521bb2faed61845e65c7a65807dccb063c1fcf77a01770fd8357beaf7838b854e3805717b0fb8c45be08466d21330f341dd055a5cdfa9e148efab483ff6426252d5ad9d365a0867dfdfa2a504f667c89a825a87a0c75a6c1d97dc35406d28ebf8b01f246c18783d3e049702b621f4812af3b8c588fc546c2e05b316a944095e2e5beda94ceabffa9e48168bc7488c13084b33a02e6b355174f638dea84d5b54a46da18ed85de654ca6bb0bbb0631b8b51235e73c65ac7fa43420055f74c7ec5f7f8ae0c2019e052ffd85d46aba5b0aa3d8ab1dec94897897564afb02913adbe08e26820640958c51ffeb3e9f038d31ccd562955b990a2b3d6290b78ccc6d1650a690a6963d23bb8142b884d91e60c704f242a7ed2cf84e13c28d6808be384ac8d9202dfe41160af5d165a8218064f852e4f32261f + +Input: bb466809914a71891f2b8ff50d924a38937391bce04dbaab19e05e087b46bc1fe9e29289129fb1442ffe54cffa4146474b63880483ddcb8492294ce7607706472721ca75f1bedf6579db6871350270e9ab01f29ecd3dc3b2faf504ec9f5bc38a74ee9811d7bb76f1e4d256c17f686cf59480ea1698e3684737e2efe8f57f1c51445bef8018c8e7567d89530dde74781c7ba109811c001f48be2ee5a52e687842d42d50103d48d6ab00c5dd9ffd50108a85672ca8f26cf52831f0290995996308e32909408913b44a8fc5b60f8d36b7b3e87f983f0506ea0582ae87ca6b64e7facdbe1a9f3d862d86dcea1749e6afa7a70bcce167a68badd51f2d91576bcb7e573371debecda1587e369389be8b7de232e22e394ccfb24c9cf2e8f70f718f69ee6c6dda7302200302ba941279533cfed1278dd6b515f12fc128ffb2d6645cc069d773d156cd1aeb0e0722c3d5c375588b777020ea59ecbbcb0c1ea0ad6f8183a0c128667ed5d4ae699a29280f7eada6984cf5ab177993ae07d47d984b3155dc3c03f22898b9172aaa93ba249c20cd31ce76b1d7e3332f +SHA3-256: 6bc6167a14be9b2e70d1f3de36f67ae1138f7626005df0578bd401da6ce74d44 +SHA3-512: aa9cb684035e0f5b3318b8f59cd5da821127f7f53da319f5c861ff7d428d5add9fe09672447ca35d12d022da8dae019c823b36a19f35b89dccd70edf738906b2 +SHAKE-128: ce282d1b666a89c2bc07176e776bd113c6969c7ac0da76168bce22a81169633d71301dd47bbd5bdd77320a0e8e48c7a56d30c6185fbfbc53afe43794b3b69649083c716c3fdbfdbdf801514bf99889fa163c101a6b30b92b50f1e0951f23a3877c52f543568ee9a1f723d9b5471fc29dd24fdde1455b9f0100be456969372628b0d74d3caa9277a984aa6639b82f98f33c14ebd17b60480953f9dd1c0e6c6c337da940b04508187b8a7f0c09c2e1f9e3a7f044d5a36433144f3784633936d93208045ad74b3fa7f2edd5065eb5e4dcd781f4a7a7da490d534294e6e36102bb05f326917e813cb8e55d1b6d554a9706feb6b3bbe6d279844a47ce51e39114d51adf555be6a8da4f33599723e078120e3a013590cc38b8fc377ec794d23c72e585e4dc974e1eb71111fd330b83a4ca9c398baaa6170d2906c408e34e03582c1a80e1d28f54776d89dbe5c1661a272a2cc04a03f1142d8f2b9049d88bf8e547981053d0d2082d8ddb01de2a312843cfd82900584551aa36c03193e51e00d4020c313cda3ba5d0ad5234681ca2a2b8e63a1203a2bd80e9eb36f28dc1b573b128d1dd190df1da13137cea1c054f977c8a6fde73d14c8fa43832eddfd6ec4c5beca4759b3d463dff1922f7d1092275b05ccbab1340537671f5057aceacbc74e848d8cfc0eadbfee5b360a02f4e8de481b3aaf11f180ba205bff44d6aa97b2d8f00c40c +SHAKE-256: c5e08b5a5d70317f03605d0b0da4ea872e06ac695d79ce59cb09e1b95938eff075e03676523428e14d59d937012f453b5b3b20185cfeb7d317326bddded47e9862c1b62a6ddb72967fe17e07df75116b0d810928a7181160742774550ed55ce80b7758201410ff573639ac9695c16ca169e1504a93eb584bf69803bbf69ad81affe96408e1e1e60624837396d47ccc2b83446b0ba0088ba8e7303dc1ae17da9136589fba5b8b6f3373516d1c14a901b53d9a2cf3f9af118c974525aab8cc2fa70f8686de38c63685f6aa985e10255867ab2f62f6aa87773e36b24a2a3c89ef1b52935d6027a7433c30dcfd392194bd4adca2cd0973d72bf3d77f781729efd75fcfa499cdd8b978d572efd6ac4eafb5559a0121646f89f88db6782deecc22f7f58e0e0de0a00f06caab4be8dc4479f8da643db347e1dd2a0a3acaa7c1eb7c1417cec47725fd82c41d69ee25c05fd2c31319abfad032669c11260f16664c94df8293ac3729e63116f1494e35d251bb711e88107b81dc221b95eb1d9e8cc9fa3a9b9f9d878d99db4f9463c881aa4e7fb6b411f373c16fcf7a0a71e9908576fe79fd4e6037f8b4237f52a94f09413f387b3f363e398f0e54e7f214f9e2fdc01ca76b8f884068ace3c40892fe1d7e26d766242bbd3da7b3964860c25958842852bfdfa93038de82c90531020efa67d03f1c4c7e46c9207ec1bed93d9e1d972ab30eba + +Input: 96458ec8017a325f62a35b19fa2c1427af5d3fcf6dc3879f3df98ae0318a301ff0d29dcc79a1b78a30b7595f7e88c0f7e249c88d6a1d68070cab0ca74225ace9104ad50367908b84989073b1662af944e9f6dea4471e66227f209d2fddcb6b18b9f66584036b1a1c4bc67fadc89bd359cd7869c171cb43ea4aa1882158525db6b468d40ed53eb1c4d52b5a737daf5845a9405323cd4ead0d9af59d4754af163b9d186850c9fa105cfdc3e8f9f6e1dbec8ed40c83cecf8e2cc936d869004ebd54874ffada48eb351dfdf1de6e9bbd0dc6712514da109fa48cc6b7c11d9f6a0f87e4353209abb7059dcb13128b89589af01ec8708dec2ee23f35034856c24662d41ee2bfa36d3ed3a71c0e154bd8b18144eef7d864a95bee86645f4fee4adf889b422296b2f96f65187a753314a89d631dcb21630c47f74eed3e2113dcff457085fb82902ccccd418590e848e4cb86fc43cd5bf55c870855834f9fae48a783bb3e2071064d82b700f7c1af098a3a8399a07742aca0d7220318ae7b10be4a0078f72457a0eca0fa4d35128728a5b53e1060357fe2e29be969 +SHA3-256: debb9387c9ba69a1344f17ba1ee850830b1a432c37e9bcd7e9bad62a6b1cf4b6 +SHA3-512: 0d850be39cf0f3562d6d014932a059bc28c33e7f45e0cb3bd192bcded763cde34063bb35a858496f8a5b5f5edfc076248660004594a419a52dee728c3db99cbd +SHAKE-128: 87dbff9eb43e65151be75a03c75e6777f0344515678cb4090cf45f747cc9d5d471dce7abb7777c344bc5e858975c49cd50097f3757037326434c025d1f71991474bc1f545fd18f02ba6cee1e2b93844a50449f1445b234a65097b1b578af4f1cab23d7219036d32650bdc59575539e786db7856149882676ce859e84826a49a04644b4d50810c147eb165a23d3247e50a64404870f943a7a09e04f2d3578709674edd0cb664817faab06773617e25c40d5b235206d4c0df034284388daf60b4de0971bc2dac65d7eb2e109212efcf524663839ce0b93d377273876433e0b6083781445bd0dc7c6ed3b7d2f4ed48993027a0ffa0232f21006d76b078ebe9db1824428fb52055806c0ab99dc46b4be6b9b7b1ca8430977bdc84a84567fc47d14a153e8319224fbcbaaeb5940572b910beb067d41f6649afb5eed9f32f70e11f3ac181ed1b814cbcac5e4dee7220546ad923df5f2eb4fe9929673231ae86465d0148b86963480ba34cde2e1c31e248f31417e1f7886f136ee422fed1ceaa588a8b2906956954e1ff8ad8a83de816d9578fa6838c5c9cbd4b33274c5a87f917f1dfc20879a7d8b883a1ce767934990ad40ca428f90738769e62616c8bc3ce0a28d38ed0fcd87964af8d2b004c738623eabc6204e13edcbb2a93740ad24f093f7026c80dc126e78b54e0c7e4fed955edfaadeb5e8744394dc99f8f64b3719e643750d +SHAKE-256: 2a8ad41db153b2e8699685d82cce057f2d6c557a464ce76b8124c8137fdf886057bd39d8e4f9bef43a60060aae7d66de892b5a1d85a1a426349a66a12f6a1a13b71aee1881c2f0be302644a4624712c3ef7919ed93dd53b20d69e5eaebc6a46a4e34b27dc2f234470003b2542c4ae85173511005ddc444c4db971232e21876127df1fdeb2c102a1308f268800f4b3214ec582986a79d047bd1dff647a1d707593d803e92c231c38aed6baffcbede78df215413cbab9d294d3db6a80f174645efcfffc4f6c7c211c1d698a6f043f18010436ace0a9d13a580c40996f02bf3bd9a420e5187596fe676d9fb78d1c371ffe92686882247666297e1d52f2f1fc9cfb098aa3e29be3003dafb03a16d505a40f2cab5725107738986bd00b2709aa4d7164b9203dd65c2b7da0a6fa50941900a89e046099043a4f7a6b36fc865a4f51c6368925c90bcf4b0dc14dedd4a549794cd889a3ed96f2840fb6f8a7ffa34a8e097c8dc1de11a34efb7984d826332a1403d4f751b5122513f2a45313f336cf105aeed881b921e960dda136c6387afa3650285623e52ac29da124f1df0275b6da83b1c7f69cbc2c88d9a7ea5591ae9ae767c24ca0994dcf932e0a09e2064e713d7eeb9341c206a2c7a0ff0756629e637074adcda2d473a5572806a12a1f99a00b85ffac52d3c702e4779b2e54ea8dcf8441f421847f8bc10a8bd413afcbd018be000 + +Input: 32332960ac977c40fd4cb279e27e87aef962907b44c227d2f7e794f699961acf44c0684c980eab060c9319d2b2e53629e0ee08acf195a6a6fab0b57367178afb7ec3bb4dd6d3f74f747f7455333723272123f46bf8d7267f5e84dd4938f23d8058e27fd8bda33ecce74272f6c40185b19b7e4e3d3792f6a1429ba55c686a8a919b6384ec0d92a27b75b9fcdec38c17541a1f55caa0d6259fdac8c1270a5f3d427c0ccb488163d4b0b275dd604e8559440337b027268c06c6fd5d764e7176bccfbefe08d5e3245022f389babb456e1f7882b60e26be4c777fc25e83cb99b452667b9beda8331524cd3910944be9b1d163f8f825abff6fba9179591254fb3eb32b53ff4da0c5c810669e67bc094d860595c853ad13a3fa9a072b8b9e347cff8fb6aa6adc45a293c4628a0533db02d5bbaecd2d917a09fd07127e83792495d59c3854e9b455377711966841f55f402331c3fe1c974989791f27bc28b3d64dcec9f7bec62b0d7540f195746fbd5facb9de28ba7612958f654ade3222334aeb9a3c48c7d7aec831dc8aaaa4387353475a8131969a8628444852d8 +SHA3-256: d7e8d71c6238cdc86022b0557cff83b5ead376078eab2ad8a49fea2662298ed8 +SHA3-512: 425cd15a11290fa0c991a1b68f65118b01596b3dcc72b23a92c9c5057f77a3d8bddfa50db0809a7a775217eb2ef84a25fca539dc3fa45c6fbdd515667aa9ef7a +SHAKE-128: 54dd37fef98056417213cff89f4b09ccea479dc62ed564fb820adf4f27eaa54c7b3476295524321d97a1d2df61f88c6495ef5def5d51986b13ae79c2c87ffa37e365c955fb2077a7f0bf2e4cac4675e5decf6a4816b74c5ba7057e1aa3d19da2aa6f66dcd0d9a4ec4b30617f4c5bf24bd67cb0f47c535fa9623d829941bd3af4e1829a6aa54d04802776c73a8a563cf8c6046c144d12ae79b980e778dd4ba29c6ecd83f6451f2e321e9f28fe836342904733d542fc134821a34380756a980149aba1795490de7f546044c422f9ecb89722690ba7e35067b8ef2b0f7be86d3921e8b2d77af3d2d98eed5bb69f73b65cb68ed37d179dcd853f2238a3c35cc1edb94506cd128f5e5c3921e4856da4d2dd5e1645e3bb1143c46d342acc0524f404a112fa1a60a03489a52980eb846520411b7421f4706273cde9ef5a81bcd009ad736ab6b8f64a162c4cc6b4c8aeeb346a82bfd33991fb1e504a311f63cb514abffd8d9b6b6c4ae324830980ba09251357cb1f590e3341ef09a365e54fbc24e7014bdd22c6d7a72b7205a72c9c3e39ab4ee746c0bed97b2d35d24a093163d3dd23d94c3d5ce9db1ab039bc9e1ddc6e8d0292cfd0c1405b5f015ea6af8c514d175665627df4ab42e4ee09bdf5dab0e0f75f84accee99faa5c463e7d0a698c2c8253d4e0442c7e51011d0221cd905f42c122a513644564d8b24e74f0b0dac5d68a8cf4 +SHAKE-256: 44d047d50ed1ca7a78ae36e65d298d976cac0109355409a02bda73f2676c14769dbbb144ffb8a9ca71b27d36f92c2201b3bc46b5b346301072d314aa260ab4712564c4b18f07d190f2009cb685e07d5bc1019edd98c7324fb37b7001d85682dba601563cbedb44dec6aa56c266e8d9a3d94481e6f842dab82c3e0bf62fde577b462cc2bbe00b84f3a06ac38ac8593c293f49ed4dcbd08c195962a9c2b8437cc6bca326d0d74cf5871161f5bf9a2baa2ff40a8272d8851421c5d95ff00ed5b163ca56dbf484dbabbd005234db894621ba2f2698b86b6abe9271ed1745c877d0b9c4ab1d8b74536c6d4ed2a20011dba517c74021596594e45c689233403fc55260056649215635a65e3090a49912e14e191434afbab82b51081660b37378e5f2e9130098a2be19854eea7d8de6c2eeca9977dbf614fc80e6e99235697e2b4f1505480027b81f32dc530efd9af6856115c5b0be1d4190ad1e89b1bcd40cf6f7ea4dd3a32126a9fb6b740f7cbb96b2ab0f1cec3ec12e0f85effdc3987d3f378ee25ce084c7690e6826c4e27d83513aff4a0f0c5693ca83f702edc4cb12a93599505bee6624ecc4506a6b07ba481dd4557677fa57f155bd255a7b9c2f3552e17d4e081a27ddd3a7ab5f28a93daadde0f58d652bb986e7e02700fdbedb4478e5414458518c306011b8762c75ed7e1efa79dcafacca76b61a27236804fc9535e2e5ad80 + +Input: 68c42229bbcf98149581222e8dbb0746c175c4642334938e85a46296585ddff2c42a1fcf7089498c1d909308fce58aeecccdc82cce95cd03001331bbecf2cfb6736ec39ecaad60e8075e525374e028cf2cb60e99c9fc3dca8ef09e9da84e060066815ad42c2d77e04bd090755acdc2b74d5e437be962af782920f5ea4db2ae2a56fd33fd77150d2550a24d45b69c0cc239f3e33ee32d2e580f31b6cf86929868e1f29d29c810a991f6f9d16eddc38c601a3f8355de7ddf39bfb94985e87f37534dbc9e6b135738b8693e27aa81571b1e8c120c62967efb1e92285e37914fbccb0e342ab7174666561a492fe51f8ecbf32108f8ef8963704cc9017b99456ff9b9039bb098f24e599c0957b3c704474dffd786b590d3c05d36a8eeff31bf8ce0a29420f6a23609b748477ade61acbd39f6986cf7e9315407551238cc6e22d100a30caf27a8be863f9a605ee43abefa1d85e002c4b6c8afc31615e188215d64e0dd3e262ea306ed818c8c5999cd8815cb460547f7d3f5bc7ca62715fe83a5b11cce7de5ef33401f94884b4da649fe150e6e3187f850fdbe47f01f +SHA3-256: 0ea78c17b67afbe1ab8a2b9535464587838b1bf9915d4247a59fcb4716e89ec5 +SHA3-512: aee5e60abb9a7e2f333a9c671cb68c7fddb6a98760ab7b115cf63ba52365a5d73be0cbaba238050ae2492ef8c7cfd590928b10d719ffe33a0adf0ff89fb59e2a +SHAKE-128: 6d97249295c33bec0997c97171e3231fa7719ce6ba1c45d692e0a3a8080f2df4d543392ead22f5d635e676b8ef67fc929500bc537573d557194ed230cab42399c8f88d445db223c7cc396e98ab948c8b854b201b61219376e8b1530b28a0bf4bce4f175fbe710c36f149ea1838f3e221b86c2be685c29ea88dbfa41320ddc2020daa2dd41201eca0efc63898df74a21f0dff80130e51188196950c770ad6a389042a88e6ef224baab14808764da421877a9337c3f5d674e89aadf6edc23743f7a1d9bbabd7e9bf2850aa54c842196b8766af14ea71cae7dde8a75131b0c70550c6eac8db33552afe8b918383621afa8c77fac3938889d762066e86049933240e44e61dfdf55e2c65468d54ff8ab73564d81512fe2ff3d17bdb8a2559e2bb21da45dcdeae988fa8f73431fd2cc77ef8ecca1152a3b69f9b49b3fd660fe7e15de89c443c983f19167fd01bdcce280faa992bfce496c1517aac5286b34f5e9b6374cbcfbdfbb9d2280ac03331d4938186d927d8255e59e55df50c2301fa42c8ad9c858b52f477d3c4ee3295c5ac136d873b2f5d3498c486e08268a9fd70cb9366647294831e3a7c74811be502ead64b968a967c15069a1531d90a1abcd5799b6d9fb0c7453920cebf6f93e9b998bf0e4ccacdd74ebda205fec03f50f35877b6c121b5d5440b17ed697f611d55978151bf61eda1210950e5ac96b8aa02cf2abc1c53 +SHAKE-256: 33e97ed04cbf7dd7ad46bfca996ee8fbda1fedf3d52af18b8c29cb717843e265f91410211a0436365b2fe094ea4e2876ecbe08079c5029383e85b6bf2d3ab014c504689df79afd827a6be92669635f3b18a8bcc32f31fd014840148c2f389e0cf571e6bc0da85e0cce8d5224ab433a54de9b78c5c682c5446e5077d6afd744804df78d42123fd8e4ee11b602b91fc8eaaeb2330d8b166ca43799526f8a2f9faee7eb37fa170ee3e567107d7635367a76a3227288b7f62186791d91a0f88a898de6123a98e73e0e0751a463eb042eecb5ac7fc4ed36fe3b4ddeaa81864197bf0251408bf6f5b7152c802687964d36f388474b6c4eeb302e38a64aaf45ae9d425d166f16e99d8e5a6f52926c499c78adb9bd206a33da301c9e71e76f0e617c1f37a473a4c5fa8875f2269b070957d160f886ada548b7fd9d7e13c72237f6065d39d9f92808cf39e320c9f493ce02f6cbe58c79c9c04c3d9ff89d06156f797ffe3d6312c901ebdbdb596c0afb7795caaab8c5a8af2008e48fa80799fca8a8374ec813e05ddb85dfb0342309b43d3cee673f64214b1005062fca8112e34d6650b1d84d8be2de72a2f6aae52f100bfa235bcb19754d5726909b0eea17e4dec05454f78181a6556c952979b7fbd06857c368b901f73d4e7cc629dc5d2e05dda4617d52bbdab3ea11af07f6c40c2d85d1d6d804477e3bdb2f2f28cacc75a10a7dc53381 + +Input: c53297613290998ef167af4ce2c703397b13fa5222efa686da768268f2143f51b4bf0f7c58637749242641627a266458ad0a53ad7185ee2ac17e9c8a5dee4cf3c35376fcd9d41c41801384e631be727128a9b7b944424aa209f4356ccaee36537893135631b389d7b06af047bf13855b8c3fb94c15fd9d0ac759e578fde22e7d3486c51f2290252d5f624a1910a37c8ceae62fd6e833a9694af66abcb9a5c1caf153347fef720140e20905293a6faba3317d345bc73f17c790007ae373ef8098dd348564fb63d7bb4116d529f91a9f73befb0623c533721b9c56772a80bab10d197b45dd3ba9db1e207db7854fd95b711f6f150768ed9482ec070f706c5eb2a0a1b4c19a4a24a001dd741cfbd94e6c690cd66544f0ca81b67aebf677682f69534e47d4b4cd8fa1cfc7a33ac319a42dd853f76e2b3e2aafcf36eb41c54ba26532a8dbf20089503c81cf4a2125c6b16ad24aae0d8de4a5567bd4d233290b7ecd83d874105a35e2dcdab6d95c04dbf587c62cff9a6fcda531fe5ff021e55e9b6ea0f315120f0cb8e604dcdfe22a3e0939ea835c2d3a7f0378e14da5 +SHA3-256: 3988c97fc7ee15a8eeed62ba29f80a5cf9bc3ac1eaa0a2df6623f857bc405960 +SHA3-512: 30a2d6491ddd7ceceb51616c3a47bbbaa44bb86e249e65b864d0f84860e71377f5562a25488e96b3b1aa0615c6810f91ae1a439689555488f34b554a774542e3 +SHAKE-128: c16b9eeca6f28fc0ca38092774621f4765c6bf1062b4cc23dc37384f6e9cf62369f54bc729eada9844cb54701cb2e03d639c5e26774e541a434fd05578f8dff690129363b7011c8cc5349249e059c22c6e781b33420e03ca455a6530b5dff682a7e91ff0455cbde928750fa88fa2584a45a0006233367285423c0e1861df4381e67752aba12336712c823f3264d3ca928ea7b9e2e5fc7edb2f3d46b5b68affbcf4f4a14e292ef4179918d33481fdb3a972943b5541172bd50ea0895cf3470c6c4954a6fffc1370dce365e6c3427af3a01923be7a89c11a348a0512e287455598fe899b34cb7b2aa82558930c656ee2ce2e1265d0f7b7fbd6f79b1353f82d7b058335402f7c5b6f932aea6752cccf689991910379055741d237074f7882ffa991c9b5ac06550da118c839d79301a1c3037b2d9de8c5492a12bb5a6092e60b3e204c73ffb82c9499dd7b5e8397ca4f6e685811ef46de3647906bca388237d3c310c558ff4c3fed41e91c9642e307981dab26ce24b271e4352c6ba7968be1f6e65e19371bf67ad75b357b028cdc1589411733327ddf15cc33e9b2441fd37c341dc3c256545ffe62ab793151af45caf6c482c2f4aeed0efca3a27c4f8171f20b8bd8925db37c33245a471e285e4b741ac6d95a143becff081a249856a20dc51be008bb96388bedab5ed002b98c23195a343264b0b247da04a7025315d81dfed50b1e +SHAKE-256: a8ce4ec902d789c79532f5ef1978803ac0117c3e4eca7586ff2b0ea83b53250487fd30c13301c631dae3c0583e2c8e8214180f27aaf1611d5eff0d3474ca2a119357b8cd7a983c6efe4d5568174a3ed9a39f297b68c991e25efa5016e105f9b33e073ba5a5414d5ac8d4d9c14a6faa84d43e5379de9cdfd86dab5a25ac1025c6898aeb8135611a19c78d3cffa3e0d55b689fcd3f66fb8e7066e8da8ca78d6de8b56139564524af229527960dee4264ff2228db594d40dd670d23476fe075904079b79205be6346d82a80b24708368de59ecae12381f7857bcf5019bf5eae34dc53a6067dd71219d7d15b089d84a69fdc50ab7ddba714b5d998af456d5f29af10b41f11261ca266f668fe5744a11f9603d48493fdf57430e440315f12b6c0c6c8eb9c4f38c19bd555053df2a44f38afc26fbace2e5870ef26da593be72f10129b3deb35025d2c7a91e88f81f59930c221199a9a33cebb68911f52fb1a3e665d54bc49fd91f09d57f6e4fe514656019823e35b6fdb3ec3fe20974e5587922775250f313dd71d7e53e3b59fedb2bb249de1d6c57b97c7271586f97755fe154c6236cb86cfa42b831bd60b10daa91faa13f7a1ce464d5efb2d48e2c5d6c494bce340d69abc82a44d52d80ac099dc72b71a7774161ac74671827a5d4b30abf411553d502bbc9c4b098c851a49cf8c00b0e429eb88bd6413720b766139743e3dc2a189 + +Input: 6711ee7af398dc352a63f5b3c6294145fe61812a20e316ff516f5f20ba7e41c0abe38d941246fdb423160c34a6dd03491782b626d65236969a75a84337149c2c561eea967718f70d282c4d0a15c7730d4b5e9c5b15ed9b0c6f050489f1c163c4c87e6fe21f42a529e93250a7772ffac722e87aeeb0c541860703fd36abd376d838898689517c1cfed85feb3e37735a7ef27944801b77caed05c06b586d9e846c56b8c86758e1196acb0e86fa4f92eef797ab504b031eef29f7c40ba1a4f1d247a122964b9d86fa9706225c3c88aa81fe337b4d3c5493226b4d02ef15e399307ddf391332aac0d0da5e1b4109d03f06833ac09c6957c39f9a1516d9c1376ced36feab8b3561913ea4671006fedc676b186a926503bc183c7817c6a76616e85900516b5f2d518e56c03e22008b0df3ddf9092f0e6baa69aefd5c15747f29a42de0aed892f86e4d19293794c424b9b8ea73e8e1af6186e9a928fbfc61e7c8c3ba3a7ed37577ba1e834fbefaa605dc2783f73b0d2ecf9ba413688f5f60a660ef69b00a986c6421f8a4015cffc12d4ca50b810fb80c0c210cd719c19a6b +SHA3-256: 1724f0eb5b4550ddab7009f91a3f95f686f2e849b64d0ca64485a91e00647dd4 +SHA3-512: 229476d2266f428b243810b3e54229e207f224d7b584d5999d166a2f5c65a09a8018b7d2a39ddab27ec44d19c0e05fb7077f72932d0984f905138ca615dc60f6 +SHAKE-128: 571a5546a84d0f34c8ae0f3a6babc56068ef0e0b3103f04d3a4b0dffe28925b71fb09b602d8b310ee9563cac5bcd7863392a5b8db7c1620937450e8d71bcbb59f8c86446ff26a48b505a6c7ea4749fc9e35ceafea833fca45ae94f661995669758a831c668979aeec71d4ca9200af675716058beb1b2fbcb6d157edd53bd2f9d90311ee9b5aa70390808f9b5fde991c07b21757464cf8736a2a547ccc1b54436f4729ebf4668f48b3edaad4a2cca8decca60fa22550e23a078bd385ae597e5f9639169ededf01cf695d67244181d39057f0d65071bdb64a7545b9b0f81eab779fff3ee33840aac6a07555175c8441e8f3f85672dc68e2fb8f6ffb634116737a83f7b895b2693f3bc3fc53755aab6baf8f0742e5240fde38b13be9852ac3311454523863d583f7fee11ee486caaae000330c85a8b944df2692bd935f12ef024605c9a187395a9bee971126f58a52cf833932158e9ba230d71f108de9aa93b84e4788d9933804868f38c69a5a307cc4bf0ce9191cf4c9b36115ff69a5125cfcb2824f0c26759ed63bef9b5772d00ac7b6c322e71e8cb1e9daae248c32b47630730238ec56343d09a2eeb41f4b89d27ac617218d9bd52d6d6c9cb4eb3e8de74a0c491fd6ed15399b917adbd5448707d66751cc2721c3b665c41d94bf5a9dbd454582fe9c2dac7e867c25a16580ead40077d4841023dc3e1437192da49b4b00042dc +SHAKE-256: 93ef903e54fbca753813c9694f430c43cc2d8b9740bf1a634a0c8a7161debe4e1726a27ef5580beeeaf925a3244fb7b2fe819af741822f218ed568d6ce673f0acd11c9258c593f7a00d920e2457c8fe5d70e2eef5e8c7834877ac3d240a160b0e44b338961491d8991e40ca9e10c522b5d64f02c4365dd1719ed801498610e99b2b4dd9e6dec092204bd8bb32cc17617858f4881125e5da68cccd3f6e41ed45a7cf4300d3db773458b1e3c5d9438d9b36c29a7f658995468dbf898a38fa1f6d6dff973571617d5ddd6c29e5734712c0c15656db1215f59f083a7bbda54e13fe497d9dac8f3cec86494a8449180edc7d86795a3ee78d91962b493c516e79e67cfb80a6ee9e925b918e0dc4b7a7b1df10989ca9e6dea67a058b6452ffdc90ffae85df1b42a94898016a6463cdae58691252cf4a88184f2a10e809c72da5118ee7c154a70ae1db2d035decd5e86cbd31ca7ae810fa788f7646167e1def5e07a6d3def1f84a8320106dcebf530905ea10b760e4073b08f41a316b5eb1446e0b11a26124ccd3b3dee0bb3c242280a1a4a7565bd1411fb6113b7cc53adde6752bcf54b4cc599e4b1a5b2eff6b0978cd32b1dc080ecca63a33ca62972c164afc8ed8f99f0083809059d2533914c6cb5fe19267e43a61d57caf0b30d2b35e88f75d0b9a7023ac10272e5b47fff37ec26ba4590a77640c4cc73335bb3825395abe9503a12 + +Input: f31eeb779c2e04d9066406bb29b5758a1b83b37dbbb3ef41b4f258156c10712dcc62ded7209d9a67146ffe54f0683c40a734298b826b9cba047b10233a5ace48943303e06cd844b2eae22003a7dce8219d94ad43a647c4b4718a1b6853c295da10447eb72969c356b90a2acfa8de5f2481bf30b1836facd2d42a90cbb1e0d6daafb2f57b7381d8ce162cf671bb7814f074657e6743257e5d1e79958a2c5b595cb6eadb824465388da3438f0853a0821cf09604fc9d1b06d5f74883743a1340e62fe211eb6df59ffdf79769ab296e815012004cd2e48c6f6cdcbafef07afd178efda2e92041346b94cd12d7c8c399c2ced624a24ada583966e023448d1cbf455a236893f6ec20003c617b461315184c7f3d9146d62143178fa96c7f43ab94ff31a1f7f23123be65358296893cbdadd55520cc3568a7166b100985ad81c78e76e0cfe66593dd43cedc4fcf023b1072b0e187ad465f58afd179bd9eb846f0f63c0e90f4eec574aa9b37f952f6b8b7d8cb883c9addffdfe45dc608bee71125be8ff2869a5d66c2f060c3e1c6134d407b21409d8def871b4b42db9537e13d +SHA3-256: f0b3b09fc6d8ea4560098af7e4f3c707aedafc19285f92e1e4a2597355161337 +SHA3-512: c04a2969decf073a1509347dbbd457958cda16a2fff67a9b0d97169f95a4ee8a4471a5f45a8921a95093ab31155668058b450ba9b219c88c711abbd039f9f11f +SHAKE-128: 279ac45ac06a34d2ab754760e71d96b1da5db5b575a778f13e4c1b84c7582062bef51b3e0e6ee3512ee3636f8c6f19ad0d425f28fe8a7c3eca61c13edbeddd115065ea85cbc9fb430fa261f8ac5b258e3c033389ec649a5e3eaee776fba0f0f08812cf6142eec8935f43484eea8e7c39b833bc927e43ca1552168121dbe187ee8de6fcec95dc6b28fc7ed341787b819d09b94d9821825f72dd5285bc69e32f2c82fb84cb9464c459f0841d443de66a0b7373adb037c550aad875fdf1d2be18797c53dac18127c95b21e423526b0868d4520139ffbc88a7cd1a4d337fe44395f1f015a13fbf7c5f6950e46ff9c7ae98883a7b17a7ee7cca934157e6135a632238ca61d5c09e973d5987028af876bd0773e6dd3e7131fd26b3d4537d6d2ef7d79ce165d308fa6a8866a0e24a113bd0fa27a633f07dd10217427f55491feeb8e0faaa208be4d4bd4543c905507b6d2dd9e00452a82f491b476ed7d6057f5d93f4fb0395e598cae8920cbcb23e4adf40dccccfa971ff54dc794f70efd6f307e6e409136d08b8ad063bdd22c7186a011806fe1b2821f8ec83803b9f6b823ffa49ae4c0634bb500ebd8dbfe9dfacd265b9baa531c68fa1cf2e6cb7f6c096cfd97e675f5f51615338c44c5019520104729e56efb56e64c61b8aadb671d7efa72da288a8406cd5904c1c831144d5c8035d48ddbdfae84da9489487de3ed7283ea86a563a +SHAKE-256: 6fa458b61a50ac9a3151b8f3910dd719372ab02b8821f2706b0fe94a78af744d0942cf2ba7fe1b581249407ac755bc474b331ab241d1e9aca565fe6da3dfceb8e0866a70c0410f5e0c4193375aaaa53a05c9316cd573c6682a2138f4c9fec4912a2479549cab015b2a80ccdffe8207715af239759c37fc6a60809f77076252ed03b0719a7ca1b8b77fffc2bbfe5b0787f2fed45481e3b43b6ac29460d8699bbe1cd5d339f995b9b24c0203c10c55ebd94e8a15bf5e264a6759096f089a1ae7fbc3a6fdb76a2093b2c0cfba50b729414d49e6f82de4b3091b8bbd63ae10e5dfe419bc187455e0e16094bf3e3d0342db3a42deb0e23d37a7ac165edc9a70ca1cbd26ef002dce86495e91249dce436eb3f4bdeb098324a081ff2d6d4d7839a72ce8100a1d070bacb07f244955db010cd7859ded35220b9a409d689709b1aeb47bec01aa2e2bd48ee531560ed257d43c504d76564cec1eaff3b4db3692518dc9be8091d8d09f63cb08e1ee1d45f9f3962467fd1ef2692b7c907e706309b7722bd15fe5452c61ee9eb5037a29f8f39e058d2cb5e1bb198305838db79f43d1fe61ebbba3e132a32edc00262fb7bac58b23ec985c4266cd1ba24ada0b0bc70b9d10413e2ad46343faf71675d2c0a3414282292ba8c6fa0be4ea8f47b3ac2cf2e5580ab8473ab46feb2dfff994bf256374a169599585565f1bcc93a6db3d70bcbf81dfb1 + +Input: 6bad07e5691286a34c97c05406f328a0973c3fd40ad1304542ffcb1d08913974982bf0c0b885dc29c59c2b05d8aad112cccdcd9743db2cbf4266794dc609167f5b53b5abb39093467f8e2496ee1cc4b80b861a98276646aae80f7112ec4e4aeaa5d5ffae7a250091f703f0eaf3db9e26ab9f870009471680ea341daa5b0aa34f4746003a56504f7e3e7d61efcad17cc37e74ee09406ec55639530738f9870ef8cf2f8203ab416658ed5a3a46f10aab3a376e529d755fb70c60c1fd90f0e8918499624715520f3f136b4eda78e976c1a62f5dda7374d1d74f7008086f51413539ca41f25be42ea6f79cd230e72f5e60f2680be0a877fe35312d84c70063885c4e7490b173c595b41ea6d1ec17db0a444d78d3640d591796d7f171250a7a030a6c3bf67b4e9b08c3e2413938a66f2befa04068b752cb5ef050b1e98735d1a51257e7a0c58199502c3e445f96075944457eb7754710b9ec6a5ff2d82836e65e5a73a245da58cba09714959107cdb278b48ae467da762c09de12cfd70d40439e1601be318f4e67644cff8695edb64eca73be3e3420e170f3df5e2a8216f209 +SHA3-256: bedbb5b67337d5991c73efafb9c8f8993fc3c62766e9beeaaa00864d699826c4 +SHA3-512: c8e644c52aabe55bf86c396aefd32c79abb0bc0634969bbc148d0b32cb834d873cfb1a07d98229f9b582642f1ad28bcc9d345967273f6d6c213d96ac2c7f0515 +SHAKE-128: d614d1497c4ec81a5f759b62447ba59de7f69fc92de4d897a1f20fb3051975442e711ee6733c2e20e8507be76d113ed5af57a8f336be9d7fb85acb474c25b40688004c4954277e7440db45400b6a73843fa6335c522be4968547c821a3191fcfa93201d26dd349bfb54c26fe6e46b6adc16d30100cf37dbbd76b4dec04e63f8f00e35da8d80fd59442b17e740e76de5964eec244cc871d6a275aedeeaa34368c437ee1d9f2e5de7220bbf13c1c28e65772e9801d7586e0d891b6ca62179ea16f8d454efade89dfa6e4ae42c84f592380034eb6287e57817384bae7133925a99f37d8e0db693998a34861cb96483bec4b6a78f2e7dc3191ece7dea24c2b6ee78a75665c2acc76433a231d0458c49415b1e065fb8a6eb0a989a2fe23c2ea9f571681d322840592d2e10a0cf1a832eb0914108c7aabed8e0b6dfea22bc9398f5087fee6eb49e4b78b24a9beabb4d9c8cb23bbfb617f1ed3b3df6e698095138c735b127922d4a5d6d01c7180bf03fd72e7590df65ec2018a16d6a95dfbc5084dc26d39ab979a75ec7260064d025b9d38e216147210fce4cc3205bb5bf5aa3a61aef9e8a3e49093dd09e16639b4c1e72a5d4962a8e3f6a8fbed675bf866a60beeee1c2bdecf831bae515568549d4c3592316bcb87d704071dd25f8904f4a84805ea82514c88691176dcae96157f492386aeabdcaaf865cebcd5c155aad0fdc364e2ad +SHAKE-256: d565b339c8d24f416eb905a77a2721bdbb7934c73f94f727208cb5dff34d24c1f0797fa15523c18040e586e9315ec04f531a1ccf9690b5231406742f0792273013f1f161f98b1462fea06c3d8c7b478bcef749673848904fcd9854d04e830096675543d83dafa0502ea1db1c77e2a26f6e83b2d272f9413a1e5b95b0050c42b4d95f871d673fa761e4bee369244a97e0c4b4721f1bd2e2def0f8c01cdd4765599ce14bffd45e99c03dd5c5ff506d25246b252b5a780f7845f12c2e74cb86bd008a01cf5ead6c8ee8d58e7c2265eaa7656016b4429f773c3117b06f934fe3cf65f8f65d92ae7e5adc5182124d93fe910e2478c499ae10a5fd11b3c15e14e487fe9ca333cf6624b766e95f5e0ec55b8330177bcd73ca3e497ff6dd4fecadf20ebd9bbe234bdf8c8ec353af2c2b00802d712515ea466fda06d6863e251b22f49b0c47fb17b04f49936da1ed00b6bf5b55d294058080d9b9c2dd918f960290d883163aad71e2f597272bf05cfe127ec695f4b5652c68296a97f9d903c69364c38f27dcabd5bdec15a42e368a87304f1c952d75edee9973afe9ec1c227d9fd76c50242947be5f42261734fb449f9f1c5598698a8142e4a36333304dae7c8da6afe9e85255c6811523557854b4106d67a69e888cecf3a5231ff41d30d429084d7019eac4f94a90e6a55aa67b3f97fb4e3d0d4aa7928745c00d9d5f801c99e2f717a631 + +Input: 039a364b092ce5c609fe0fccfb0e299c777146fae04ace31b88c8751bfa80467fe77e44258f1a688f193b172bd9a68e28076e1ce57c62646149ff98f1bcf96d5355621037bd8524e4411ab8f4465b0324af81e04a8801f1cade7c9ad30cfbcbfd386e1ee01937445807725e55fc152683d1c93860050883495c6b22dd651a2b8ec16fb91d64aec69a5db8f2e94ac25e01492c3a1f66d156534a9d021f2d8c5428e9f54974414c0043a0cc3639d75101dca40ed4313634f3add07cc159bac217454e2370b228abb5a71013533324410341e617f48e48d3a27b611e7a4e50a2eb96206af273e3b75c64228b9b78c6062bd5022ff766e101d95d27facb81a39fd8e5b06290331bcd008407633c7b8153b7f6b313715826d0866452c777d9d629de29c0017e8b286d81ff092a09b0ef29fb01348e092f27330c5990c329e1d9f410a0c60088c3819eb24e2b66f98d79c0a46b36d86532f9ef18e358841fafd6048ff8ec96ea75dfdb10b790296061bac6d44c4e9234e6178321a704ffa0823d5ceaad3be08b50fa355d9f241c6060079705d2ac8c9c93f07e74ac2d3d810c3a9 +SHA3-256: a62dd10a971d1622d7d0201ff0b4814ca996f169b1b24a5f6f28a3763d2d4aa2 +SHA3-512: d1714bb1ce7efdeedfe215e3f44481ed2a58655d89d1c227b74c652ed48effdc338f6a2693ce60b4d8ebf6470d27b60cb633502dee784b3faa2d37f168d911ea +SHAKE-128: 9d58334addf61a8921a3ba567edbaed6668f2db1d48121aff85165d63456ce66593779dc529923d7e8aca6e6273cd252e67e32f7eedf879111544ee6f3ac247f2df7c6fc25383ce0b91817432b0036b06bd66e77bf7c33d9b331745ac5a413c4ef675b97d261d9db69f106ec087239a54ab310b28a69d74af57b86314c3659fac12ff02ab4a976964368f5c4c5fa8370fe7666cacfdff280869536057f7d806279ea5ce142820f1ad1a0c5dccc3f0503f0262f29c5124feb8c6d183965c2ccb8657ac66bd7469293d8984c452e2026b389665b607f1d18de7467fe5be7932ccae7160c894e48cc5fa4285dc1f6c298f7afc7dd28564e7823d0117d84641159671694c9a290084e56399976c8373d4970ee9da6f1eeddb35f5394bd9a7584ea9c9abf78630b41166af358b67ecafe02af14126ad866a16fbd1194929e6847a074c8435ec976b91f483f11a273fd81e437ea5c1eed3eddc3a24720c91689296af78b14cc5424a234c0db9f20bc2dcb82b70e699ac8e057761702eca61bbe9ff67b137cf6bef7ff7dbacc5f61fd5e21a0d0d19b9e333a9b7ba39dd9306842c5c9c91dfabde8c32ae9a520578c7fe144b77a45cbcd9d49adb855bebb7fb01f250a0e9f904ff948838fa3cdc1dda5258ac994b3f7cc546b1f33c416dbf0d9c310924a5cd44668183c373a47897fdb49b899167bf04ada7033ad36faa675ea64267cdb +SHAKE-256: 64048987391f68e1402b5c9cc1ff7199f00fbca1b364fb552d1ea132ff8939033994e39eb053a09f9bbbf1fe7f5b5e27df55854b5a4dff204bbdc0d540c8380c2b229bf051991e025839de3f747d49f78153ca95dee6e94468c1199ba902cdf5b2dd2524508663a9a4b74fd0e10b9464f19b1d7491231c0dc63629b23a7ca6ad131ee098c7048e2b9d2b51427696d7c6727c54dd57e2d999fba587a7eac79e0e5b4577d5d9d36af98da0312f46be08145d704ddee75ce923e21f179956c7a577b75a61556e11eac6c02d3cb97fb37b1e3b51f465474d24d1b9a66c5e6cbaf0cdf597bb2ea6966533f5091d8280f3d84849cfa58b8fc40a6b9e7c047f89bfe8f0c65b37f12e3605b09401f4367700e66d6cfc83006dbc6cd7da4493d1a46cb821fb88d397050714b79a0f6f785b2ff91da9fbf2b7a76ddfc290a5eb4f9066b9dd0b7ef3362fc7c243ea0b34901b0fdb86dd947ed421ce2231521f17436a9f278850cc3f8c001238dec6613674c078236cdaaf204ca79dd965d59fb60c7032a415957563cc91dbe20db150ce936755d7d0b1d1dbb9c63ffbaf60e2223ab3b6d33917e551aac6184ce9fa720ba0e08f7e481248453fd218593aad0c9d3e9dcd30ed8fae3509b2c65fd617300ed3b78565d860989abde9858ee3413139f5dfd22f9d8e1f914c1fd8bb1981f3554343650f101f6bf4ddb8d0a08b9b4189fbe37c065f + +Input: 0d1f2dd3b88b91f69af010ac33b8e7749a7cc92c1e5c2191867a90ced8f1721eb968ce3c46018fdc070b822b366ce4baf6ff559359fdea062e12913afdb5778ad945e307e12da0e4d9e01aa585970452732e7db315b185da83707d51108e35faa10ba7a16e2fd0d27e52bce42d134cbc1385f3976ddf2e66f5849c9a8e7640468f46b48dec7ceb53d19abab2682d01795c64517b369a0e6c32ad800bc96cf47c8246bd09ed88feca2e19990d671abb640d02c233e5a7e17a03bf5733c19deccb34fd96a48042d124af1260edfe4da2e6f335cd220022b9d815ddcd63f51de77218eb794a2c1fe620331cc89ef2e57a98ba7f01b4affdbab762f6ce29b617b518e8ce187bd30324993e2a8cd5d50af572f58052e3eccd8a70d84e6b44f73f7b32a69d164d6755acda600cf0e5a7ea2caf8eb364c6ead615a0bb65320ba26ed1f6cc7df9e296fd703fe8c85b6d273fffdd583aebafa5aead47573af5d3d8a50a4ca24dedb8f38317af4aedd63b4c7a4fb2cd71bbf479408ff46cb54f7843e1e820da9418f29c62861d6965440233c8d014f8ac690a2e49784c6037e284e2ae12 +SHA3-256: 5d8c1023b3bb0536be62e334d9e0787bd4acef8bd629d0c1cde2db71df0ff3b9 +SHA3-512: ba3a06c4b754b7065e68b369cc558d5c94929e5076269bd9cee3d7fb41603bd093d8f38571c7a753c8dbead75670b56e3a728dbe3c050ed58225c5e5917f20cd +SHAKE-128: 02639386680ca2dd24a295130e02911f5f4d4010f0f7e85e02d40fabb402156c6f69c7840c76f5bf7be6e6fc9ee2834f8fb8565e375b52c101571ddf765aae99bc3c73cde175bcd2905a9b1010032fe847cdc2b7b405bbb5724a600d92b35f2f78ee1c22a7b5a795f4c10335767ea79f0a2617684af3a7ecba4a0690798e4a41568ff6031c06fe75aea6e4ca792fe1e06d8fa158ae7d3f7da5281f8c09b3257aba529961f569273b1d3f00d694bb8adccb3f3d7fa8cecc8d07f743f89770e00fb730a93eb7b428ead5f4116f4dc88a69d21bc06a2a08cd4a08974bffcd5714005bfe1373eb02454687be7bf88030cab462650163f112f6b4b33ea14dfd8cd3975a19d7312d497c48076a6304ba167d44b70e3cb62a7a0bafc66e25338f56b5d574941fbf488916d7441a3947b94362f0906899a8f8fa896088df91519991f5ff7940d02dcce2c223e8929e2fd767d56384d58de03cb7d3d3d4c540b63071189618b98f330b2c7293c0a0f9c6ea1a06c8bf9d9a6fde75f7946e9e17d72c5779519e18e2df3aba20cb7fd403bd6aa5a21d07430ed6df3c82d8501da548846dbfaaa5a2d4f309da62ec22490a1678f283b50f37ec309d4fc69e8d9f3ddf7cdc0f4fa895118c775effdc6fb958648475eb6c9024250f7cdace5516733c1e2d34f70a9b26c1e6ddec01708a29f27743f015722108a1f3719639a6de6feb3646147ee1 +SHAKE-256: 4ce1d4304be042443ca67feb700e4bd8b7413f4a1e3183c56f4553714ba9b095e403f741596bdeb0bb0e1de0fb5014cad9c0fbd7816cac6e1e7435465d5e5f49f7a25bd1e7e7fa8869622aec233e85d6a93fef721976f1c4138a1c023464d6db9cbe714658a3bfa0c62c6a858775bd9c444af4269a71612f53f73b551ed1cc0705938a8d925b2fd3d1c1343ec16c0a60a0fdb31d5e56592be5aadd03f2a01df036e443c2e04fb8c54534f1237dcebbc90f76f9af11b24db7b957abbe9b5e8c82f3a59c38845ed1a88b2e58e74485ba3e2cf6ddc104501798d5e6f2bdcd5dc582a18adb81b737f502645d85e90b2b4811616dbc49b175a3cc84b03966e8fcbcc3e2e68a3d16c6d8f1ed725a977ec1ed60f05bcdef007301b3673687a686e28da4a4baaeda3fbcf4f822e7d9001ebc1f92efd8cc65bb8d93f3fdbd596394eb6513093a81216da249b8c86c4f91bf118176f13bed383b5f775b7bcdbadd61d0cbff284848a85901ff1f81e9b9f49d0c14cfc63337778a1dc1a2d72dd1572acd441ac8816abc6de6138adea4e37b70584b1418a25a90b3e98ca354ba525857f7a63081cd3a2e84044ede0b3e7c9978e0493afe372959f694d94aaf95eaa33a33dbca5e3aed81001ac04fe6a6d2347523ab8944cd85495782a96d670e76aea121cf941ddb5dcd58341ef9551241c274a2432773e301000096c0d285f341cffbd32a2f + +Input: aca91804ffb5e632751397c297bf629503da0113cbc2c2c21d1b206e4ba2b8c58531253c89e33993387f81d43476ec850322b49ed85d4fdaa683dcea0d19aa0d00f56ed126689828738fa125ef8634e37272d657c82c3dc0da8b7c2e423e9024561b0757a7cd310fb0c9bedc2ac79375950033ab9afc8a003194a1875f3369a83305c6ce13626faf7f6d0caec2327a5475b46ddadeab98bfbb33105d38e63dd487c191bfa94b228f6ed8fd074b958a11455c75439e370b51ffdee328a3efdf103d999d604a974317a2b10b69c2485877931d04e0869488b128ce33d52f091926bfc7c89edb56349eb17b029952505bacb331c800f773fb001244379643f073d91d28ed861a5fab461835bc1ac0f655be509a49a305969ca477137ac1274d519c6e15ac9d53ad4545c27c11876082d6550abd417f71cb68d92e0b0857fc451b5fb619ba0b44c0222d4e2b829de6a6fdabc0c2fc44bc624b2ffad83ec3c889a037bf9d78a35f02d0d764f0de212ab1554a343cc725444736e839fe2864479044ae0c9c69f3f488dd2ab7c8b4733d3967856410b49e1e9a3e851e29b4e3fe857f56 +SHA3-256: 1c2f5a4ae08d3330af63c8b2c59284f555bda28df434d9f704b01d4cc53aa18e +SHA3-512: 7ccf3c62fa32ddf18092835aa6b19835755a655244208bf6378a644b114fe957d658661c4f7faf2bb805e9c7e8907581e625a7347548c821f4a16262d3e7189e +SHAKE-128: 81393ea475aafcacc9ab2143d9af3315bb0aa878ae651af268f6dfe9120cbf666bef635a32fa4d766861e4ae603fb0b431ea4a3def9313615cde9bc9b81e525eb009ae4f6bfdd2cb4abac7d4ac274eafce1309caffce625172c3624d1085121ea28813be51fb74107b0c17172c332316823d298d3a733c8a3f9a1a4cb7c5f8fe1272a0a0fdf6b4677708488d94cde7d8900336877c79ef427160acde082c30bb76fc6ba4dbfbf5dff9e705b0f17563f7ff20cb7ae220f1f2596c4ec14eb2470891d4efd6ab94a301d7b701726740562df43fc3890bda88169bc4e0a9a1df93c6e6b06a455e6e6142078a2fc116d005340977c124eea6425838d3c03b2dd750a9be2b9eadce477362ec84be98d058c8ee140b6d4e927c9eadc08ca920e363e3678145b08a6d379c7bc6c5751f9a0e1d7ab5adba7807597d0baa20d18c87fad29fcfa3d238e7b41cc45df68a5fadc0c14a6953c4390a61c00ab0d59084e00f1a766ad42033c24ac11edbf891a488cbd5edbdd03a3eaf1abb2662018dea84a621587ec1f5738a159199f6625999dcca685340d306b92be682ee3f40ff4a893955a84c6774f6bf62072886664d4afa9883f4e0d76a6e7acf1c752749cd918383e9bea87a90afe3211f34f1b7b00c3114d83d0717898d333caa02c5b07528a97937a1801c34825da9a78c62f88e89617a00b95cd5c7260ff981a3cff762e2b74a4a5e +SHAKE-256: 8e4fdca33b1c7eaeaa3e503addae4bb150ee8518a9aca3b95887d984a7f9cbf746f96c55cbf9530c962f9e795bb19c9ed574d6a6645fa1ed082c55a833f95d9215bf97102736175ce68eaba6d73528c2969be977e73d7f0440b1e7e357d04797e7ceec0b681b1fb6d36e72f851809857f142dbc09f3638025ea3d8ebd27fa4e4a0e19858fafec28333a73cef0bd75ccc8cef39c064925717a13672f4e252f5d3e23153544354d9dbea3447c8f8cf33890b44d1bb791e0e3f9349bc886a2bdf64ef49b5b5d7f62074cd81499331600f280e6d78ff8a293cfacd3a582e777aedc7f58fe0d4eb40dd126c7ac578fd4364796f33288ff3a725ea969c18db0fef752f6f09d61bd5bc94843e9df898d25b3e30cb2cf12668752106882c4b2e14bbb4ce1b57c5e048079983d07b918f0d7ea15811cbafa31bd003899ddddbb89c30b54f118053901fbe9c248aacbb9b4260f3e6df9d065cb7aa15c41bf69097429f8644b01dc890ed935d7fd44eaac9feb879e8755c657c84acfd2680798c78c60e24fb62e9a87fc264d52876edb748dbcfb034e9e78dc8429e234d2b141ca3e31abde1838ea2a36a608e67caf5847f043f753b3625b8b0004f47d792d07a7f03a555b740cf3bb5302d3021c5ca3845ab74d0c3ec6a7412e81e7ab0fa4150b5c04300480f92654b2a0bdff673b46752b108c73ecc6868299b879bacbc39d39e50bc1b68 + +Input: ac779185cacddc70d7471ea7f4170171cdbaeb3e1d29d1b7c8fdbd7e78394a3d4dfdc02183a8b309cf32e307ec1505ff7ee8d5657eb86348ce118638d3a9acd91fc26c6f790bd283e652a131f97df6419274c7076ab7a35e467bbe5914ca6fda67d217c2aae68308015d9dfe91547a4fd87c1f20a90e2f13246160dc658fd37e69fc3a17c84d0d1733f8541f05b017ea12a4919a5102773c47eebf9ae60a9022b0c0edb92cdfe1f4147a703c53434c399d4d34b0e05ccd0641d6c9c4bd04c3010524c829f5333e0da3470f78fa831021749572e3597a31034a018c18842c662a81d3a5dfa10b632171f2a672df2964da7985c2173cfb70375a3b4213157f2ea5bb26f2f9c4af9376fbd8dd18049e2c06422c774078260188b39db7057e3e695887a3e2b6a173395fc1470ff9a3830a1b48868921853544c6e412b29810e375d4078f77955fc1144e1edca7bfd66dbaf1ad12a6de25b87331bbafecf8274b5d577adedce96472ddd02441ab3d24e139517db3b43d14785d5e5c033f964c0551e3e915f3529379b4f739e640a667a3c65337d483434c5f959b2c282595e8ac3e2d6d +SHA3-256: f2fdc56a3580e7c38625ef220d7a52883796764d75b1a114df9ffa16ccef7ab4 +SHA3-512: 6a83da096c828b943f0545676e5c8fcee3abccec5fcd2c1db96a7a4ba65ea049a288f4d2610e34e018bae9294e62175701c17919aaa8f0108cbbe587a61c75bd +SHAKE-128: c7e42cbcdb8b8520fe4eaa878f2dea695c3fa5148304a93f8bd1decc7d3458aa4c0d346fbb87277362566a1761a64cf7942d94f0d5c8a7577ce44eb7db364cbb0a52add20ff7de71051bfeb0c21097db4454d5678adbe9378c78413a70307217f7517eb43482ae758a5d76c9016993a72d1c4aa5887d1bfc6c3ed05e50db5919512022fad0acb74c2aec16a56b47e6d79995afb8ee77b1236649f023fa3ac19bd55382aa36d131dba9054bbfb5ea9bc86d03c4c37193b9aded95ec06f9ccdab9431f1d1768228edce655c5b79bc71bdde39ef1cc8d63dba44c7eb132ee5cd2cd26e8df751e400e42165983f8ece7e45a44640947c13fd55631292a39f7dc88caf822ea71918ff7886d3286572aa38be92844ba70d5dd9d6a005a0a1c19ccfe885b636f12ae2bd62b914d3c46bb092d8f8495dba085248a83e461fdc2a5cc92939e221ce54724ce19fdf4856010c97341a18440cfa6db25dc6661ecc624c20fe6c368c0f49e5763f095ff7b1bba2ef032e3c92943d39fc32fe1ab786273ab8c90f2d22eb6757e5a472ce43e96cfbebd880aec4d33a52308beb0396c8435a6466cf35796f7419e47460f84937f344dd22f49041a4ae9e026052b1a7b9e32356aefd746847ae47c600667cb59b74c1ddd38385340a5cd44aa53ca1930ec70d0263b0dd90632c3dce4a994a3b56fb4f89b0b8fbd61f27ba49d0ebbd67ecbfa28fbbb +SHAKE-256: 7e75746cca99fff240baf2703c63212f2596bdeea6df3a05ecf5d5cd6a012dc6fdb52f76e2149b83bc9637383740e692d664ac6389d97f5098b94b70409625d3d8e84e9672070ce6f170fe25af2c6366eee75b49c27ed2f92bce3e7e6881da793cdfe31db232d94cb9936a455fb5714854b570f7bac86bd670490c3ba5f304efa71e276a876a8ab96ab926bf792ede9139e53d7e4e0742941fe3fb919f9730c38ea88947b18d761a8f7eab48a7f205c2143206f52109552cd47606df20c12a14a1dbd8fcf31207066055feb25080e8c66c17dcb952d8e7440c7c2afe63c7aa19ebac1075ee5b2ea87b5ad2cda204998390db7d78aef74ec02a6fbddf5bf240bd01923f8602e5792ac57b691363aac95a886147086a7a231395f8eb4ca575638dc4304e3653f8e237e4ce57a72513c877fbf361488b09452058ff92c17c007fc41dfb50b6b6d6ebd2e24db6fd94bcc318d3fdb051a49ab9703184d2977eb77448450918a4bf5260046dd28ea6694255954d7efc84ec05ae1cbaeecd71e158ef6856b631c1b7ed779b7d36db8b50094ef5a3041ed23c13b9f56537135dea7a1a0a8e6ea30139b0badbcd4116fecddcca54de5744c8fc24042f79a3b88c576a1d4562fcd8e1642f181d74483ec2cd0efdd0165a1ddb46436d5a1a9658457ae47207647aa24de5a23a50e7423473ee0e1aa9c4325af9e8590fa9200ce3258a8ca3e3 + +Input: 0b91d48b6c7c659c54aaa1ad689ac3638019d5d02eca22f3c26a077f7e9dd5aee23dadf0a8ce0db1cc488b4ed2e5e8d40adb3620f8a1c367bf489536bd906c68084828a44a87b8c893e8b08d6e1d1cf6de9809084be87401c1d3407595c60cf9c0e6083bf2af180c9ddaba7220866cfa49f604a3eabb53072382f3fefb234f0fb554cdb8320f7b0425449705e16d2f0cd231db2494458b21e86e0b1dc409067744d328017c821cabe47f4550201f76bc8a7d1b52c3cde48a81dd045c0f78821b1468e46149b2c212b7ed0f356188a9494ab0a230daafb86b01916b667653553493a54d41a132281223838dbd3ba4df99a9ebbb013fd41309c8ea05797153d6eeb5cccf6ecd0dc54a1f2c5b7114ef6b9813326bc141a6dd8a119723f3298dac104db5184665e1b59eca01d1e32898566fd7e1dc2042b0b827d7f3737dd7b141d88b8d54cb53755f87f09e0a7fb3f8977c10bfc961b5f6285e5375ad1e46d3b7c93265c10795a3cf6fc0a503c042b2e084a85be1031f1161f0e975dddb2fd56f5ece1ebdb84b83edf6120dc3ad93d0d4979fc275fa40dfcb3e1900e4b770d1d8b82f07 +SHA3-256: deb888acae19d49c07813c91349b64ab0d5e497993734149bb9407e075ed38bc +SHA3-512: 715ff279185a66adcd81f2ae5f80373926806528f030dd289d6c012601dab62dc15deb6e34ebf2f0677badff8d24c820b0b798236b1a9cdc8c2246c74f9f6fb1 +SHAKE-128: f10c539e4328b7653ff8d143b41d067e802e7316eaac2980cc4b1075c58b0b919655edbaafe7d6eb71a8e8373b4d3e87b43a965830f8830f238ea3ac9e8facfb8c367c588f96519e9023a74301a16f36d9c740695949f816c0d925722dfc86f1aaae0727e1cab835e68c0a79fe83f2413e854e3f3f039e348fdf4ebc73a1a4b06dec1ea3f9a3295f7a2b2bed410ee657df076708182db3d03e856e180c1cc49afee2d1ac9c709d5eb0e770bf88db3f9c7e087b9fd2d7b0850c46e3bd57cd93197f2bd924063179d4f410c270eac979ad7f0f22601ff78e38223bb73f83111fb92708e28296252c90c6a2853e3c5300eefe8dee84feca04890f208e1bee306f9f7067f1d8a5de753b0d734d165c1ef41ec1e08df20f360a4de3d2069d656aaa4b9e76cbdb2eda0b757b4795d94ef2a686a34cfdb691400e3e5b6572069a4554ad28b810f6e7ce5b3d8ee3c43297027e5306ece40ed51707595ba743b3fdcfd0a0b8eabfcd7708c7fc863d6ba9b8d4e77d8044d32311bca388c2b3203e8c7f822740e257056c01501c982d0ecc6cfb70bcaf2751c1f5c73c6a676de7dbfcbf2b53ad66c4ec3fb349d63c70703ec346e6aca12ac8f82ddbcb83d787e074897240a11c0b6cd3c865ce89dc4a4e107f67925a142ee5dc81d49fa437b9f47d7fa6300ac5c7024a4719cfab4b7c9db2e849359b2c23c2b6be9f2547e621b68a968436ef +SHAKE-256: d6773bc5f6381930f215c14323e7b3140de74927cc5ea5af9f64270be8cd5dc86237300fd4ef802b537b766a628975de67c47476670613f8599cfabbfb4e0f273c4120a8d7b1f28584447b66b6b77289bb0448973fade5a7de7fbcaf69fd0e09a0faaf0b2e410b3c3e08f469f3574d360d7278de0f9f4d089c01577ecb93f851c0b9659613747f350201198a37e361abdc08bdc6fc5d85bbb9c25abea178b6003f14d2d120d913b1f91f9962f3e1625223227ddecff671655743c44a165800a0a68141160260f628cf20a9a39af9db1f89da96cb0eb038eff318208b8dec164255df289c769f1f221feabf4fe0a69a1a9841ea684f2f1ab8fd532927127cce67948e8d60aebd7c6a50378c420d5c7b2660c1465f45f7d26e9a0eafd6b5390f4b75e9c12e1965bd0c5d0be2729017e2299410aecda7f5597beb1b6e18bda7c7b629a150133f14673ff8ffd30d49600d6d864ca598433a656bf4d0d37b5a11759e837ec39d11288c91123fda7b017dc9a811fc0f235f5344acf3620daec68ab21d9d7c6ff986b6a7ac1f69c29c858309e59fc3bec48af5f434c99e05ddf394e63cf86e276deb19d861b83e6f1e093498fcb3be0dda172c432af7584750fd50f19418670e854b7a4190af60e0f896b386f21e394591536e254866f9ff086ce677a96e2360b5e19572929928e8b2bdfc023391e50bac81fbfa1bed99d1fe30079325 + +Input: 49c723bce35f180aa15b854e5de2843b55cf685c7187439dc33010befe018f8231437c614cb64e9237d6e4d0e659f833b00d28268cb7375bf62faa33899214c105c580a7201a27abc6fd77c8110ce0d1973eeee8a55daca1c82025194769130d53cfda1e18e7bfab03a977e8c1ff6e59b87cbe1afbea9777cef76a4f58563756f5081eac70152846527422b0b9bea7c8b5352a5b7c33cf369c763a73e711d6f3e26e0ff653d6a9c7d1841747179df158a14d2bed01147d1f435a2657a82c3365f6974f0a02fbdb111e6b376757c77b8dac35d7da4eed6d749f161c120314f7cfec1f60fe14f1d2d0a1f0d0a92b16767497baa817681ecfcd1ccc49823d8a071d59d074cfafed535c646c0bfe2b0659b09651931fdabcc3cb1b830860e0036b6ce3db43f0d45096181fae2e52b5f3a49dd6a78c1d52bfafa8d0df7cdd9838e0edbb33588895bc20c226a2cfea7356ccfbebcfa9ed0227fc5c2b2b12235aae05a10fdaca3d42ef6f509e707470b58c9ede50b20eb1f0c08f0c7c50ac1aaf884019850475842fe852bed676ebdd14f936871d7f376bb5ce38962fdd3b4adce6375c669084 +SHA3-256: 7a744fe808527b4d3ae4fce7726a3cded3c7697b391d867a145afb7514a80f56 +SHA3-512: fbb46380983033c4bf6b1b028ef47530bb13af9e58baa5005d95c9ee067e5330fbd971ebd0c5b2feac23168ebfb97e2ff0bebf6bde89fa9d8d7c8104c328098e +SHAKE-128: 45d53a551d17cbd6924a35e47ea7c2d07ce236bbb0915cf8cd06a71aeb589b888297298b9dcb4e91828f44f0583b90cbd61316c1be7792e047b88d308493d2438b30d41b752b07789852a83a2577420f9d909cedf4d272f44a99bd9e49d157d493286e2e55e80a7e214f304809f608e438a9373e4a9f1b39bcd33b615d700665032c7dcda0241cab2adae5157daa9b111a8a090c256c4d1ab8b3e85469004baa8687a326025085f68355424ab20c8eb5c8d91305f7ab7ddbfa8a2891d4b2f663bf7a454befdebe15d31c6db833006d3535e063c34d45e1c37c0e64b69958a46b7768f543c2fe767719c15b33e89ce25b034ec1c0370d2a52c9240cc5d92b448f2686c5570722cd6fab5a8cc3b007f5dde0f13571bd056978c9a3a1bae8dde4a09f98e79464553f39fe071cfbca5be869a353ebddc37efc8f0868516f5ea07049838d87e1893e6ad3a54534ad20e153a84faed659ac59171ebc01eb9ceaecdfb4f94ac627619f9943f63e8e2428a59c11fcef5c2e7fa4de691e072b83fe45eb0b0ef557808496209bb66d0c2a8523a5f303ecc4cf846f1b30fabb48400578e74d98d3dbc42f6ff3012e5de6da38c2d69d45e49d0a634efbacfa849d63ba7b8ada19520a671b166e906d3f7d73d05ca62e5bcb7e4dc672f0e3ba4600c131ed5e40ee41f049934616bdbfc560c28338919d05ade9ee2805797e855f36ba5d67b7cc +SHAKE-256: 6c16cb83647687de388033a8cfdcbe46e15738ac0a97c8cb63b4d946ff16f95857d050375f29e739e4967cdbece077cbf650dc4f163880842b2d6cdb7b92aca7a304f1478971ac563a80e25c2564f524fbec79a33262cbbf2b3129a815950e4a929ad698abd0a74820d26eeae419cf5507a95cadde12b587b66178126095873bd7719d0f4986214105822cb822be451f866f8608be9ebf6c66963093985f0e60b6b65f38485f0fbdab08322d04db380b3b88eecb0496bf7457551df80830346517c307b67d0252e22542c2930dec1da4e536d7c803d1fdaf400fec2a3fae2c4e38fabf5f0d8f278a7e7c5f9df81447f0ccd9553ce32b7d56a4484bd782bf1bcbff2411c8277b3a043eccf4714c3dd2a3cf96ea55f9ed59fd994e99298d5e22368287fcd55068a65e583cc5033f891dde03637163cf31203658ce1437604d61950a2ed486a64a99ccb2e38640f178386ae33191e4ebbf753d2622914e8f7c8183feb68da87c546c329bf10c4adad1f22a069859635e6842128add6c3a0631ef8fed2d13b51387c9ced1320e6b0cb4607178e494b25c93fa34110b4b339d9d1ff5df5f8fa4fe7b98b9889c1cef2f08b3494a16badc164811678cd268bda3f380ac04735a3bee8b4d671558857eea0a69aaec01f4151a68e5faa3b9e162d47a4392da4d30a44b4bba92dc003df012a452d157053c3ccc8a669e44e65cfbce0c6d7a + +Input: 0cfa36fae999c6b1a2ad65b67a149621401f1bdd69412d269252be5feb17a42a60683e103e2b66de2dfa72ebc5ef72f9b1b74af1f8e0e6863a7b27d92300e45a5317826f670e4366999f6cd911af9f6a09a20e23db34d30231a96e0fe962967217823f6498598d6909acae11d4ab201a26616426d2818dcc86a49154fff5e1bb7fa733ccb300e8b9841195841a877adc77722b196eebd86f77c6dc9aabe4176a8f987bad20d9dd05a72630fc5411aa90a9796fcb587a112ea782606efe1f896611863bb6b413f0edbf5e352146c7c57f9f3714fb8172437bf720847d9106f72260e49cc50c25c9b3b88bc2597c1f33120d532396fad5ad5adabde8cc0f129f6a0a9b4defb56c4b922f53e4b76bd82d00eeac869d7af62794c659d510a4bf0e9a5ab01f7d9bfb30ed9ecd9577d56b2f27c3eb21b9c453399d54cd64962c8e10b7faa86d161b316795e1751a24c195b1a97dc327ce117cea1f1c07bc29d3072f66e021a1fbafb238e8b838586b386f3519e45ee3ce5e4c4b176b53703f964dce2cac85ba9fb580947b47af85ea89e91336a7eed173b990cba9bf753229fa6c8326dda46203 +SHA3-256: 4afbbba791ffc182e5d09a8cdf3f3712146b888b74243997c88896ae20244824 +SHA3-512: dcfe6234dfafd5c8df0f3fbe1e61c3c68e02733103aa3372a0503c3ec7eaa44ca452539a2dc84a5ea3855d25238551af70fb44a1b6d20575ba54c88fe765fb0f +SHAKE-128: c5d20bea850e301474da64b94d2f05eec0f9c5e322495731c588d8414a92e4565e8fdc7e1ee63737d871daf10e111f362d2429e171c8e23f8f5bf4f7280142d1894b46418acf25b1380af1010cad2328511896f4f2a68e7d0643dc70b04d3feb13eed857bb003ddb7d1ad24c36f1f13c975055092fcdf3cc00fd043789643688d2cae534d157af1c3810d57e392d617ac530ec18d025253b817b78f4eb9baf859ed427184ce0f0379955a0bc07e4ff9d1c44b7a130c4ec37a43c0484a30c5c5e977ed315667cf8da119432398497756da5618e257f5f816413fc48c07b755d378999d7b7177bff80500cc70025e4d7ea0bc24a7caa31c8d7ff864c219cbc79a3cf652a86bd91f54a8a021af057ee1ae859cd67ecb08f8df0b1b12077aff14ee716272b0ecc8931d3c4e8bb7e55f79c741779c38751c846ff7cdd4b2b761d830d4dc8e0d4e37936647ebe44cfcc1ae90b53421a0b68e8545003e045cbd07732e9790a90d2deebd4c2b77633cda8bf3a568dd9d79bec46dfcf857b01045072bf82a1cc2a40593bee9251191583abc79e644daa3809dafbf90c36b2706dc34b512c59435809852c3ec44669457b4d5640c10adcd4068770cfc71d63ee68a1b8273f99c72a4cfdb2f5db4fcd47d25da46c80a0c40f34682e0324cb5772315c38d20b621adb23090d2b33582c4ada8cf4434e0635648b079613753d4868153fc314bb +SHAKE-256: 3458e94784777d96d124270d80289091eda36f05d550d0629405f88e6cd2285604a2f4584802d7bb9f5394ac6c0756a91f1126dcc02581a3bb6d38f1871f5e7ce835a123ba715ba9c74e76df0a6553970dbffa2129aca71e660ae5d0252b1b313b444dcb142bcc93077f9c66fbc0db9c6fe3b2adb155fffefb328abaf5bb487ed81ba6bc8942b70d40335a0d218f84ad204d239712ea9117cbaa9d69ae82d5849b7392843cce19c0bb76af4de276072ad476c6201c40634f9c9958668a939c11f3da19ab025f5cbeb32a7481b31742d78840b9c446521c8e0d5056ee38700843c647b287c509f3b439be1863858520b54bc19a7e63a840f892c2a11097bbc0c670fe47c9670249b35d71f6f5ec912bd4ec97efa0184d74e3c8b03a520c1353889b62c16377d0f0a1b845000f310bd501cd2bcad6db9e5474bb283a916a1ce771c32c1b7fe5c2cae272f98ff172a61009a7bd9ea1f30f5d4e2ef17341bf3ab4b2e161f73a3350de45cbd11a7f4c1307ddf7b3eb5c17c73570bb308ffb46a7784a854a33e9794a06521bb13897e83c168472356674bfef974755e0fced417012afee215ec3be12229e8732446f3e12439ad4648adba74519ae01cbe057ce9fbae0476cb3bb8ef913fff6e261fd5c09c744641096085241d52b330ac94ca757fe72713944f47338a25a288ec4bf00c9cf15801b0e8bcbec0da68ddcc655efd4668e + +Input: c43f520822ab87a54f2517e5db9e68dcb3a5e5007ca78fb6504fe98ef0e920a0a304571278c7624a81255f1210a7e3290884ec9c7dade4c502654bf721a5e10bdcf9be9ada5ea077128129e37d4d870bcd19808340c9bfb88a7b29247e7684585b62f50ff76e3a5b15de5fd57696120cc5b81c25020b2e5972bae29c8ba9a26cdce3d2835d8cb16d09ff73c1f0f20ce82ee7c222f2d6ba9891c3cc062ae110ecf796e2771902c692f4f1afd93d3423d72dc503bd28b1d6b9cd143537a0a4de86be389038502395179d9a706e35b15579465576a7f5b30dc4bc2f8d0ac75e5b82146eea01003dae4850eafd7284078c36fe1365bc7b5f3d71e97e10dcf493745e8b78547535122a9b9ecc7918c822e62476aa84eab6fef203e6dbbe61b1fdc07112d62a01b8b24842e414a080ca7abf7bdeb50b04a42ccb39562d57ff19629832b2bf3e72d74c45122de7a640e6d08b6ef7703fc05466320b547569b0109ad950bacf69fde2b600bd7c71a693b00ce16091e7aaa6287b9e51b12c1a8057da5b76fe01f40226d23219031e18bcd3bf8fcb4b39ad75026fdb7cb186dd1910dc7d28bfc9bd1d2a +SHA3-256: 6e16dbf8b15d67da697114dca2b6f97c116edbb2c0e985be9ad2b9e3d6f00494 +SHA3-512: 89e3bfdd95b46cd5d67461d7e1108df41ce7fe96eef08d800d2f64df48296ce200694b91f640d4236572ef5e63298667948e4ef7d46912a2c5f2cac5cb4d965b +SHAKE-128: 0c3ac08518a14a12dcbc3969dfe14bf2425f8f16235b3d38d5edc2f72e9a6c32f70467d6da172cf5fd0269d5a0393c6fb625ea2896cc60becb21b7e38b8ad2ca14b1149d7defc7e4e60625be6adbced3ef33e9f7e84fc7c3ef9f8fc9608a1379d21405b3f3305f13221f175f26f6df977c078d5ad215d4714d6b35a1c73308578973d291c8e619af12663511c0fd708d374ac6534b82cdfe188bba303ffa231b9f9793371b15b833f167b8f93d8977240456b2afe159576a19fe5a43c83ed798ebefae338f1faa7c3c9bb80dcd5eb1291c85a900d44b59befdca580347f9ab1e6097fb6316e084a22a77d71fae60202a6b8bae6ef5dbad640cf9c9bbc87365f68a3e529a6dc13cff56674cff0c37105123a6f3f23d5a9d307a9c5ae871895659d2bf877dd86099fa2bdf6a6d25f12d2a575c97f268decac6622b81a48bf0fb9ce0248061cb61dca3a784807720ae10c1e6c316771b2cfec7db6372814a0c37d9837773d8524156c259f8c1644593214c6989eece5de1403b63b9039717c872fe0a8db17ba6b2581e0bac110c72cbaee53011bfc5fa7dd6b3ced0565736bd9bf0a734790cfe7f7d47766c4842ed129e57134cfffb188a1702ecad627cfd804ed9a8f195e4be7411361d747054de2c4f61a37dea7bf0ffb60f552ff4ba3d7f983161716c1cd617e922cebdf4a96a6994311b7f8b9edddf579194b5d325def71128 +SHAKE-256: ba163ca09a10ec8387298f8528803e43495b2cb3ce8c4ff9237792d97b1e2ab05a111936022be2cfa0b489bde68bfdf1d9b1df03f963602be77df4974e6420f914a0536510cc1d796c9bdd3cb16649c9f4846e1197f77275fe71bd138cce3abd76c76d183d3eaa9e75bf354a828e82bf0502a2b80a0cdd1691911eb3ba28c62bbe4d236243cde1cb6fc3b51950b68a35f7d9b8704acc6323151ffb9d8caf2e71dfdef3e66580d29b9fe07f4cfe289eecae45dbf3bec49ee17eb3dcc67be63fa19b0f0638feaa5ad2eaafd89657270fb08de9adc136eacefa2143af9855bd22296d230862d28cd6e3a2c4669bfe71e5470e39cdd493ea530e9b839cd505d97b3e0d8b1c9d04c9c216189366595fc949881eedc7952983d16d619c6839ed08075f904642598e9efb55bd915562d45c415c2174528a5f3b304becda752d09eb598ff3504749296f71b57ab89e291c84ca06e7d3e699714bc6182d3cd30d009c8e6488c937e6994abb51fcc338d74cd96020481540315531142e3ce306362f12f787139ac3be2efefb25a81de16b500b298ded2fdc3a44cf1255537433296e7a684360abcb81db4afab90a2fe779215cc600235fd430245ad07e6cad71b5ffb70657a925ae0b76b56d35094ef631b8feabad41b1e4d280719d4cecae6f62a4b2c4a16d9492110727ab637e8134cd3907ca9b3ee430b3616064a7e9d13709dfca5833 + +Input: 44f4551dc63fdc076a1d6bde17ba40ac91146fbce81952d451837019183fdf5e01abae7677ec03e2357d5d1523d2941651f2911b8b91dd580e0f599c7c6a9c00681cddf714157b04338a90a0a8de87bcc30b4643d6c39e42e2356ec18d181d7d6516a11108cc682799552e7b3f230117cc5e0867f2ebf43b64acc48e31157f53ddfc58c1bf35340f0d5e7cf23ea61f53ed0cff4dc626a42bb9aa9ffb53635c21a04b588312b309d20a5d5d22909cc7a7bdbca030fb70781d80d03466791db1c1571ddf44a61b63ad0b091267e8f721cb232efc3d581442ca41d952504dd149d6ba507600747b90a0387c722d793cabc16be6dd3fba8036b7e54bf303f0d68fd1b1396acbc2c06e237c0ff6d3041c7b4fd6df1b8f930a70f837a0f7e389d025577f515db0a8a2a8ba8d5636539324ac823d9ad5af68012a0980376c298412ee4017318af9d4dfc5d212d718ddc6b88ade6ffc85e9e9b2d5983f9934d419e9b057e1bc3260099392f00639f802f5a285a7267bb1c7ec356814121cacdb21343f538a2454cf0617e2b38709def8d7f7f7d098b7f50fdaeb842bc1372bdd8551db65c3256179dc05 +SHA3-256: 7de3302e7ede529e874ff916b62f49f5180fc3254ebeb4fc0721bfd24b79951e +SHA3-512: 66d12b130527f05859ee256a582d373d0bde28af93069b763e6fd1cb1b512d4fe3834b3f4d0f92f06a9afd757d421615acf546e938c6068a972a878e40b880c9 +SHAKE-128: eaa733a8820d87f297293a88a9e0fd7564146ffd750948ff5cbd89b7a98bd48b3d53074fc47739a7bad78c2365a6cbcc62357173bd2b3b54b0ce3659d20f123c8009d928c84eb9cd3e7672979dde3ed956670de3a31793ba8af0a143decfc924f4a9d8f293081be593abffe53701982ac5dcfdd3e4f639d6193532da879f88088e86a65bbcd492deb8954b05eb140bb1b1bd02f70bdb29e3d0f8af55165609e8b431a75f266731a6ca990e48616dc1eeb48ae2811426397cac99ec9bf2ea76c5cce2dcac0f6283f77810b0f690b9785fec55419dde20f06e25cd0913c7bbd734d21b57f1df1c660bb555c8d713810ea5e1a12c61d82922b9fcd5b43fa67ff43acf5f0f6d33c119da097b5fcd7324a3c7de6c46a170c484cb29dcfeb53c9c48da8448c19f5ec577923edc0e55874f5d67ad70a3408cbb48c09c6fc865966520acd6499feefeff4fa94c86459a227bdd39694d14392ab7a54fc2b42e345d723724cdf0e289f8223e69ef9eaff8645af4788312605d6a7a94d0f863d97bd06815289e4c1cc36ba5f2b6996c93a3593acb8d60f757891f850fe674a3d4caf1280bdb2c764e8b37868c9e75a12f474adb8a0d8cb601a04a2c2b588ab678c05b82d39dd62a9db4f1ec5a9e9fbaa613a100da47d6deb984bbe451d83b906d647fea81267948ad972cdb85dcac26f9f7a79f1f43838f47c8fbab0e03e70e3bfc919150be +SHAKE-256: 35fa173d7b2d4547c3b1f768f42f336b4b24be3e616d774dccbaa09ba49aaeeebae23f44d3e8c5532991ad8855846ec7b32adbc5a503d06c8a6e0a311528bbe6e4d8fca7f99e2773d8fabd5154c5ebff1f829287a253adc2c8bd766548ed38ce396e3052222f192e61dfa06210145d67fefd8b259f79484d6ad4098d6a74fc16010b2cd6ac3ba88efcd82cdbe21b86527dde79dc836deaba94a9ea30d74db94d359bac8082a59d900d2a7d5785fc01c26fcdc37505973f181bfff933ef5e78a5e7c9785ec832cf5f198bdc1dbfde5cb02cdb68c0f31d0b7a05cc93411fe075ccc84313ee1c03acc001f533f590cc190b72e737e8c01e2acd7a2b0156f0df5f246e0eaa4f16c7fd1bc2042c2c204b7831d5eac8a043301de21c6e9cfc40d876c299c1bd1f5a5a8f8834c0712ea9a395ace6b75b7f4b2483cc744c7dc159c0d1a691d70072a2e5a0733dd6d7fde7477d182147588d5a574313ef075bc29c1a320307652ece6b7967a1a41abc42887d87a40dacc68dbc8a9b20ccecd1785c9bc175d5d7cde6bcccba0c51931a32041c49333120d1f4352f5a1a301226fdfbd0987346ac32241e82106ad272c1fa6a02afd4fb30f9a54f311bcc9b87f5516741adc8d1d80267c4a89e05761cbab8d5697cd0e22a78c3be1ad869cebac27dd821fd72f786aefd7efd5b1bf5c1af22f5f05f4b10a4f7ed653809529c060f41a5cdba68 + +Input: 354b48f32d73667f253909bbff35cd20eb3c6a2f6a3709212ab9c0a2ec49fb423b9175283b4cffd1d836ef20a63faea00103dc7f18b116efd4c49f5834dacd81882341684074728267535a675a6415a536a05376cc278677aa438286ed0ace57c4d5d646741537bfb2f376a0b327080cda767dca1a30464c4d81fff416fb7e4ecb625ffc95ea1c2f592725253a872f3c84e5880705e78ce0ce40635566363c03f99e9b01b31bad4791a1c6573bd0dbf12e23271d2b70ad6c1951415bebb24de93814751b3c5a0069aab1a442dd201f1b983a99917b5ceb9d0c97896c0400a1c548e2dbc8ac63c2f401a2b6688a76b1cb6a563f32270c93334d6bdd50312443afa70846042784a401651c549d1398478c0704c6e6b72f8662a5ed38e65d03253c339113dc429c182f8c15bc83c54318c273b7019a25cf0b1eb9251d31092cede1f8dee316a8710ced8be21f37f1bf7b2b5616bc96a1a07cdf5d931f06b47c017217c5596eaa2374d3eb3f3bbe77b5b4e1259ca025575d612d90dc81f6cd128a1502790284ff21e6ef5acebce822961369b7a7a55b6a61cd75336e3d99f80c3b8220e385465cfbe8 +SHA3-256: 9e957b526f12da94e773f67533798a52b25938dbbdd38b8c2bc85c2aaee28991 +SHA3-512: c9cb6899f2ee9193dd89ed856d8488e95082ce9ecc20ec40b16c019ea0c69de83cad7a4b079459d5f3b3463470094aad76afd6b73a1e4d1b50d48828726c7d9f +SHAKE-128: 24014841c302eb1aa4f4b8f7386a0d66b62506df18edb7fc6170348b6491ac88ee60a9dd957c05e538fa947f7d1ecb09983843729be68086af94f4c8be1c12d08433cbc5a767e822fc236b06c70110306e38919046a5356a0a2092c045913082bb692896da625659f265c5da91ea4595d244a95fee0bb8ab24887db39fb845893d7a39c2a23d9631ebf44eb02b861fa263fe2f9f452770f177195e90633f78799fa2edb3a4ca6546e7ad14f8211e7c524cc2f6d3b7a3f0e4f55708f5f3a9ac943d80f26825da5d2dfacbed1bbe61ea662b55242ef36be18a823a5581e54b24049a55b1a2f17cdf91c74141f84923e6ea7b884b02c348569c461389f9eba1bd78d9d487ac429968ef8a7ee7a86f17beb6ddd2c6feee03bff5b0f2a21bdeff33c875ef38471b44fdd9a34b73f93d2983d10dad5f3b57581534ddc1b7e7850b3e9be653f099eb8a216e530cbde318a5a3f36d8524d02a8aa8d33a2e31d5da795481cf3c668c5b76886209bd9fbd021378a7d0b66ed6d97c1679fba6b9def8bcbd194e4fc798cb1c665e87cc7bd2fc1d48df6b7820766ea730976c063b4bf43eefd26831dfbcb117f7bdd1afa7222c72e748014f8d05a75197c41582edec03b467c252492cb071c278c019050b43b48a329ab63e0e06fdaa5bb4fcaec63bb06bcfd3d48b22b9538cdc15ca543722a204ad13e226e80305a435ef9db8423082b4258d +SHAKE-256: ef1776a55335888a90c93226a41ed99743ce812c2615ae439c1a299b1d8143bcc984b45990c7ecccccc45b5b6ac1ee978833d6fedad9f1ab7d5ed7abcf72eb078c571646d803bf467dbbaa775d080328e79804e0adcf5ad621de4e8c35b1b20852dd39f56e0de5bd7fb7732696bae4fe2a660ca4477684bdd21634573fb6ee59e37b1703df5b23fddaf9b535d0f8c8ec1688c514e47dc83fafc9ab81882833edd9ca13aadb2dac2ea2d2c4fb8745e4928eddade1e1372db3639bd183d47865153277c70b102c1453f69e8aa5c9a906f52a27e220abb152700578d31b583c5f9d98abc867c9cd8938dbbfc3984f390d4ffdefb01cd920f3e6d5357d9cdc4d462918ba0c2ee94cc07929a56ce71595aee3008ae1edd6f4c98b27ed54930febfab292d58a4db7b6653d7ee5e541dc7e4d9732a05c895f895a5e2316855e36b6f0854817f2bdce7b6d83aa114054516ac49e52d9c3f1ffc53d63184675134c01d498f193479c3b334c2dd8d52c2f1a02659b778a531646ef01d78373477a6cab883559bab262046497dc9706465b8edd992e496cdca9f788184337b16da85dd25a9e1b16063463915289d7322c2728f99c276353548da0eb062bad21cc692a1451fa16d99ce03564f5eb2c69050e6c3f59246fce019c57e54e1572962215ea3e51a04bb8f4965c1f4da15b3930bb51e12d0bb83763982b9178cf861cb1e6fcc499e0 + +Input: 5c8a2f14262524075398ea143b7fbe4d1970cf5ffca912e4cd10b4b1859a66f93701fdc2982238a451f121a1bdb8fd83cabdf242e9030d2730b19428b194b6505ff255029063764ef746af5e658554a906586b9500da95313ea39edf1a77d594c88cb76f81f871421efa018ad43c2192b348dadba73be803bce1b993c6e49f13f428c1a30000225ba0442a57e67ef57c7ec6302b55d7863667ebc71269c890c0fdd305c68156b3e7d47e669118262e58abd9da7e2ecf9fb0156fdf0f0bcb38b043ef751b598bb4766fb5b32edca7393dacb78b4f58a2d10e9ceadb80b589be66eb12359f8481e3f7860bb1b56edd26ac0411fb5b8bbf26ae630706b5b851b35df22b5847a9dc79346224ca64cc568a61ad8a56791899848169efebbb3adf51d6874715da4739a7caed1101696ed2911a871e92105da3b5e97a4fc5ab76085a997b7bd44dc5bb832133952980bfb7e0407c4a0bd249e8c1b0c2e1dace1303e3a9465296d054187614b9cb729312a56f8206d832bc74223d6824a26bbc710a70b8dc4fb57af530dd3c16b6200f3e402adb45a6161cc0370f0315cc5e2e7c2753e1f69884676a65bd8f +SHA3-256: 3065f947ec1582653b36acbda534a62e06254c18122f4f976a1c8b8647ae84fb +SHA3-512: 0f6932287b85df833d7afabaeb10fce24c02b6899ac0e4190e12743135580fa9e40c6b9c1e3cbb123762ffba78871c5778eccbf8f08d2289318090dbed013624 +SHAKE-128: 299000aff5bbcdb24b3ada77e32de9a88748966fac85c971b4d7f51a6d3645f8495e4eea9bb2a4ebcb0cdf9bedccfadf0ff6c52e6d5cf9d75408526e8557517f532fb51e1b906a2a80642e47e60ee862482f14ed426c20ea9352521f49c6df81f2662bfc98f7f969acf0a0915147a4555b2db2e756a91bc25d2d6e5c536ef8990cade7af4996ff617df43499c5ec5e287ef8636549bd66b14a5a162d436f978ec150fc8f9a40ec12cf92a38b0e065c611a28ddbb8cb635fae07238e90e7a3a7a56f2c4a9a53f0975ec01642074d0ed4864593eccfdaaf371e70bc1f2a4acc6bbc0b480704c7d16bbd7ab7fcee3ab6b461c9e73e2c720139a4411688685ce6a2333aae453701e5d007e34fd7d2e0b8f2eb511fe2d3bc3ec60ed9c691172cde3b82c1d9d8ebac70b13b1f372784380edeb7ec9f3e22b5ee5d9b683368909e07a214f2b4670b6359c8d33f547e039c3e28e3208b2879f6427537d4d1e3d052ccccf9f82228f068619b840bcc44d8d385fdf483fb45a8159f13446d74ff4fda4681fd4f8dfa0c166c0a0d6d0c67c8202e38c85903dc0591cbd7989e7a5396379772f271e2cf75e8f320cc29b058a2cc2d010cda7e89eb89ef5a568c3e655a6a192c099d5b8274f28888270c7ef255178a9979af61d8650396151c74e37615e9a6e65209561b519d3f39dd06551098a9547f9a17e1fb1cdb1137c2febb98cea8dd92d +SHAKE-256: fc2f48467e634022b2a9c0bec100328efb92fff7ee18b8bfc25fce6cdf8935bc4020562e0763ba31a8414452d0a691b589dd2431cde60e30bae070aae6783fc3f7200c78fb4015d01ccdcbd5a10780fea8680b127605f0ba7d4c81e86eec20c010536429232f81c443b5c87575f5c2f4b2a20d87f0693ae6eec60256ad51769d9b91cb3a281dccd09db1cdd8768ac0df997687d45dcb8b8cceab2b4c2262255e43d46403fe7332bb9eda695134dee92b8b9116f35b0a9da251361516dd3d3e69a9681224223fba585d55d3f9d228f1718e3fe112002337725a2663aa3a9a63b49ac52247ff235f04ba32286be13ab2574caa7bdeffa699014d72f38b7bd9cc02c5f79276006f0617ceb6e8674d01c9022d25071ca4f02a4cbdfe30821f68c516eb2daa0256811e57a9df9799221a07cfa1c040f39112b8cdb48a7d0596c0b3909370a8146f95a8d4ba4cd22179357e9e6fe94bbc7c4cd29db286bd0f9dd82af491a234f8816fa7cd9e68e3b7e2bf525b6cdfbd7e651380c22cf2d4616b0baeda283502bc622a4962b2f47b15699f6c517f213f0f99a4566cabf63e5850458e13b25b40cb42688b6a2357293c80e552cb8ddba6686e965b79d2b2935447648b6a9e8d3ad6b7f15fd9f8f2d247df8fd3d822edf3c1743f04b7d8cea638d0a42241a1f1effe9d2ec53e31ba032298da0b5232020b95bbe25fafafd9db04ad912d1b + +Input: 89c80913c88a49213f5289e3d62145846237847f80b451d6c0827030820c8ae12321e9327af53a67e6ea74ce5d16700fe764bac7388aa0d7bf75e4da97309f3d75958c1075a5761c9da6b52494deddee12ef14306fbc61fdef716ee3738f8ee217ed9cd24bb160c3f336cd7c107f59480ad4acd79d1bdea407254de5c86579f4b8421c3f47d6b78e2e6a42e3aa6736923df757ea5ee3252eb78bd20fb43a2833d8689aa2f8f6a01074c2b3ac585f9adfb769679dca94691052dfa5ae8433519f6453d1ed64264a0683f5ebe3e3bb3a0c7fd5e6af2f4a628ba8b07a993e004e038453cc1f6db6bcbfee73feb56da9e8b412844bf63c108af1fb0d7998da45082eb802f76953eb56cf1dfd4a3b011718ea326946079ee933b34f73038eb41831e065f8dd084685ed07b4015c6a9f0e003610aeb396cc1cdaa1e02e1b6c634980567a19241c676b50d5e0d207eac23bad586d63122b985bb638a3e6fcec319c5a73abd4245fc88c537b446ee532df0a3c2a9ea218646eecd0edb48fe5fe8d19f508de275244964e5e995e62d941ad26f5ad8b8f43c8b3729e25a7d89383558f89a33cfb0f874cf33cde70 +SHA3-256: 7d5df8d8a47ee90d5292bbef5ab0ae9eef1c8cfbca900730085abdc5d80a23c1 +SHA3-512: c924f7d2e2369e2c06a899232ecde93d79af57bd5069c5f611aa8c85b0fb9be61890d41ad634fcc11fcff1eceb270e22363872b4913e49c8eb19f8f0fd1f5b28 +SHAKE-128: 12e040c9e52e643d8522ea9f3aa9629fe90e98bf179bfb90b62b8245b3c5967b4a27a72586037dc36cb0915dfae3285bce2184cf8349e3542c7e853358e11ae78ad9e8ef8506fab0f33684cda340da1c17163609968ef57edf40213bd4d993706ff2890b7ee7c6e527a7949ff8233ac271c8e439b16e639b2e9213ad3d1c7e5dd06f40b11222d519dd99e9ad398ffbe787a0eb207ce8e96d40d29358aecc9940726eeaeb16dc6208f713c8d4c0df2faae04c1950d82306d274ccc055a033e41745b569fcbd54f5fca9531c955d269961607c5d83afdff3c085a2443adedb0443f52e128c705153d6179eb440a886d59d6453ff5b0cdb7aac9047d00f70aa8ca8a3de9e69d92e82601d849d57f42d8cae07590b7be47a6563ba803ccd2dc14e0a1f468d8502eff5f7fbad81a09f918d3294a63a7786a5244732231ac631c95ecd4c7ea759ade5aa2113535f87b96eedb37f46d25f9c963c65f7160d5b4780d602741ffb904a0ab874bec1b85ce5e05505e95e7e7651a93f72c4eacfed251ea5d166f9cde88ed061a70b72b36d4f61271a08c3166f7c0a64a5073fa23cedd79c92695036e468ff50281cdb7661b25f8e65105930616b5a68f514ddbbc34423c330410ad8fdc739c1f381bdd96e782571b017d63ff0044e3cd971cdf3eab577bf0849334944201949d2adb48f913a8f11b9cc5afea54b7187c7bea2a0459f17cbd4 +SHAKE-256: 3de8ed18b7c353ed4a2ded25673257829c3e71720f2364c8a73c19e96dc86322cd6adea19c092d65c63a8da6205ae695dabc29a622f48c5fa89d8b70c6812c1b9cc612cf8c2f1cee80893ab2b9347d713a242d13dcf958c6b809d6ffacf8c7aa6b28f7ca158b9197df969e82fde88a9be38796b58f4d49c7e8a1b6b1e53c15278cc08ceedc681f7ee0d1e06302c1c53d7f590777b81ade9f35de189d9d04fdcd876ae92f6616821bbb3b52898b262390f29b136639d88b993e51a20e49534081721d5aacebb13dd6cd0a1a6bb3fb3f2045b7472601bd1035ef245cc6d8172d31738272d9405f4cd33c136da97cda8baee54df25696a8ab2636f32313f9dff3395b58ef524d5d0e411231959577d00ba58e00579681269b283ce4dbb624532d103243781e9004dab956303cdac60a6544ece128ca0ad5a213735c351efe0c87e07dceb41edbdf451c5ebe283403dcb267d6f7b784fcb3d7c21ab8c501d6f46ef97431e4139820fea354737bf51c95dfa71ac70cfcad901c980b91eb12d891c8410d1e58d363439a43f7553baf30e39a76bdb06a70bb4c59c98c03666652f13d4e3545160749f43ac836f5c94b67ef61478ddea6fd8c835af0ff1171ed4348e9a040d74d8e9a7d25e5d2127d656d2ae5a5b8b5c353a6f28e7b7d4bee7bd6aa05c3e3aaf973159f7264b0b7d4f47528ddd38b9c6ae05703c4c81a86ab6f29b4dab3 + +Input: 5a0dba9fdf3100e85d36bba331998a60babd4d82f143b8fd56230668215b4634a99b53c67f1e92288499ca9347177ef7f37d5b62f100aa7abad76cb1dbcaab11479829a73fcb99343a04ba1ba0e496e3748903fec7bf19d7541740720406b1c7b8121685a19d291606fc547fb5f7d18868e11635147071ad35a81d57ce06a5a2b81ab92822cf13efcc24764a2025bcc767bd3dc8d202f07bb1f4ef2a318155d286bb0f7ad2a457cecf322d605ded739806ab0d2a1760ba0565631bec92dfbf61348f55727cdfa778def2660772b9f9fbfc91356e9ef942adcf13ae0d6f4a9f3913089cde7db5b55a6dcd7c9010592db7973b764967d1c039ad90244592f1388576dd8cab6389aa468ee46ac2afecd35ec3e1717a51ebc2730c0829b5b68474ceb6a650dc063f200b29b35d68dff5645113d82a01faf82540dd9fd1aae68ce542b5d0ba6e53d7f82a42fb2b7760eeab6a5c473cfa35f4fddbfe18c2ce560829c5b5ac0de9dfe5d4aac01d218c8887183bfe0e9e091db8496e2b66658741d02cfad2b6df5f1cea4c0f974478349c3f0be6ba07c6f07c2c3a5cb3691cf246e19f285741ac470c20df56749a +SHA3-256: af9b698b84926b7704c9e92f914e3b97cf41a719d62d52fbf557cedea6283e1d +SHA3-512: 15436abcd8e668b73edcd56fee1f4da5a9976e85831bbcc9ad8883eccaa913b06ea02b2ee73072b5059fac062a596c85a17ff45ee57dcaf8092a88cab0497fff +SHAKE-128: e45388c924e13d8c2b89cbf6b3fd12e352dc5fe59ae24132e56a50aceaad4b2638adcf48b4138ba113d6894473e8cb983f90a7bac70a0d31d4213335e80cee15a41a8a6ecdac3054719a2e273e90b6306c76a8ee7f76f55e89eaf368a64bc5a231ee01e70a35788591eb355ba66bf1ae2ced2292a58de60efedcc68c16aab2bc112f34a7a9298594c189d25c10cbf6550bb58d64055d05aa57b506b46d50dde7e5c8f1b8797940d4050a720a3fc41fd03789b76b0f9662e95ad77d49aabc134fd7c187ce129d3543a680f8937a04e185bf599aa6cb35f66f8ab8ac7f3e21a3a38c246529e50af65fef76865e110967c21e18ff5761d4d98ac6d771fd9c15d67fc66c83abd9b63e9c9617a8bec15501c31c9d587250c70f4200f1e0b5fc2b7fb379d3ad5cf85e068d54bfd816c56418daa952ab7b0631ad097ad20e940f6ab2204721b18edfb192ad43d73c91ba72185e8b058d43acc3c6b78a0fb1ccc9a39354a96a1aea43e81ad2c70e10c1df1b88df6c2b6f69acb27a0744233195df1652fc81cba76c80c84f2dc66cc1888452f902ab730904a87e8581753b78105823a686a81176ac0fab5898ce99cf9192c4f7af1958e9dd70d659f31b046d2721f6b3fc9b99ff990c4f4ddd2e8f8d69f3bb746c1804a761d8957c8db56166d7bc2fd5b96c3aaff2955c14be81f56300a8f13c8a92c58d0acdcaa1326f6ff63956463351 +SHAKE-256: ffba04f89d1d0aa4cc5ceb95135cdf885ffceeb6bb4b7d5f93bdaff851d7369db750d1162555f59fc8d97799dc3a051a6eea6bd4d77b41785f37dc268c1a4527fa622a5ce758436819a3925a39652c6bc6cb7761d7f57b2bdf3e3d56db1e52207095c509125ce17cba2b5bc48b2f853ff8395b5df0a50923c507da886cf5ac05719e6c6d51097185d3ec3360aecaf173f0965207fa969fa4016f0c39f35f2462652287b4d0b517d473a386a1fee56d2a31d37a444238aed88eba4d8a9ae2e056811122498e60b3061c132954a176d1ebfb342015453f1d2b6b0a3576731aaa27642b1819a391588e9016561c08b1a27f59c3c951484292cddfca9ca7ec3810ce2daff43325044ad172d675d3263597f6c80dc4f3971928befd40bcbdb7b0c9f91e9798e7aad5af5916c58ee898174facb870d1b4bea6ba2d80aa1d5dde3e110f4a7fca4305fac5ee43fc5a7c5682d6b013c8159e364241523d01717d896fd9cfb8cd46f50d42dfe662ce86055b1ec9d64f6b71df59297977b8c5d83c8699ccd542a7c919afaf6df01417c9694ca52a15862db185bf7009f5d6e7eb9301a075545baae2e4ad5670047e4b4aaeb6056f00f08b6dbc15ba8a4aafaaa55ac8116234cecfd4785185e88babbf8d1fcbe84f952aa8a0495d011a4e8daddc23d635f1220f180002d41d63d635cb013eb9ed3382698a65b2cb3c009353133b8a6bb4bd37 + +Input: d8bab2e9f53bcd4364ce17e304ff93aaac343696e1e4acffcfaeeef6bb15921beeec489be47ec6c6742fe30c70b76d807da97f5c3151be9fd12789b721c8bed05c509d2ff9edaff67c5686318f6931c81e99a9c4ae3deca14285acf11af75312f14518e0f82dfdb8ccbed2a5809390c7b94fba3b6d6383cee702b752f4e811c0165a160e856b1458b67346ab44b71533426e88c1ab2a45e1e8002499c2e092bd9a7ff6ac6887216d8c061a1ef898264cd0eec46bd2e91f0dbebfa2fed254f2f1a39079353d4b02765131f764b3e02d4672a00287f04909d762f0a8e95b1bd6a25f6dc628c0628ec9524868c643e973471e21dc1b0519a926faacd060e56b630ac97be03afe1555155479dc8e31353a73751a8a274cabb7dc079798d4e49f79e23696a4c39842b5be9635e0acfb5cfd70ae09bf2a587ee6866cbdefebd36c54871f597e5d9e02a3639baba06e34ce02aabcdaf83858f308bbe92eaa2d469c4f81a2453221a728f2f77b020287dbbdaf4c95e57220af7058b548fd275d384e6a6c76ad258591e670154fa3003b454016463656997832b628229fd73b4bfb4c56ebb5af3711431f372f742cdb +SHA3-256: ba24cf1c46972822e1e8886ee87a8cf62f3d26314d43b412c3c759fc44c3190e +SHA3-512: 4a91ab97d4ff35b53dc42d8a5140f72548f6c45ef7e7d1df787af5f5176838ab1ff3f4e389bec99bb57348a7b945b326aae1914bf30dadace641df2735e7b2a3 +SHAKE-128: 4c5585b63a5ca3019c8b5556339cac8e7402d617fcc9e459edc9e5dbb48e582d6afb9d7000674818cff94e8c3bcd0c824b1e7167537274c6b96fd8f0cd67ff687d7fc3ac99db3b4d59e0d88514a49597a36c81376596c0b072bd25122d91907eb066823495cf0cf0fbb420edd55f490ef94ab9bbe0460296421ce2da179d5e45bbc51dff7fc4d826ec5c942a622a0e82aafe2ac8bf4cad4e4a355764f688c972ceb79468f288151fc5382672195bcd48e3400b16118ddd137c263ffd503b658afe32a71a8b2052b2bfa2b15fd5ae36fbd552b3691d4529e89723191126fc74735a979e14032a42cb26333951f3e0fcb405a15db656790d9aa74bee907201a4719f26956740ae889e808dd3c6d02f5ced3f4a9ce1546ae5f8ed6b5340921f41cde7f2234d635826c14b8617c0ca239eee241555120ebc11902eac8dfcfca2dfcfa0ec328d407afa3b3a6ac16ff472c6571796a8e14d1133bf77aa3f9aba20f0e4be26be1006ac4c6ff5eff00f1ef438412d0d0908dbefac4767579f3b25cdc565ee71bf766a9367a8676a696fab13216e0a75dad1effb45151f3aacde6749db420fa08b441f7b91c3fc1875e0fd23425f6c2aad01a086f7d7a7d6899f2700da8151803315eb29bd3ae86b330934415689c5b24911a01ea8ae94f8b44dfa2508b14a3e697e24dfda2cb290e5b655ed12b7f3cdc9652d988519afd49c417f470ebf +SHAKE-256: 099824826a71d14430e6312abb787a210abcb38ebf3d6e98184c82834bce862fa69559fca5c11d5627e84f9c7762609cb9e98132eb828bd514a564d8ebec8c99f89f9b4a4ba78db967fb44a35be514ad11e0df2cc2f217e3a493c347ce2556a65d77cfe7ecec8330e0e83cf252fe30bce19da1d636596fc80e3735f162e49e2442250677a8d94be272b2c722ba4e88a9549ee6033e92da9643eeee50c38231228acb99b3bc3ef56f2b181451ff089b8202cf8211686cadd649a166d4f606fe9d25feb9f098fd885cbfc66aa65ab6b8f1374368f43cd37bb66879c65851acd30dbb5b6aa5935a2ed4fd3d5f8531220de8bc9d13c2448314273dac0c4e23333024e265b29f4d9bfaf50576e8dfefa667a156c6557345a418351b0156b5d92f70be0367cf459115901a30cbd663a42a19b9e24423ecf9da36f4cbd2b246bce56ce286d8de8a4901f4e26dc4bee6b1a2d4b9d6529f0c7f5c15d963d9bee8d22155922b3c90ded69883a038fd5067b8c9aa42c5fb8dc6100f33f7ef0a229ffc925a7e8b2bf75e80398793168acf0d57c5dd5fc1a2cba5a0aec63de8421857cc5bf94c7435b2937add60eb751e3bdac86015eb48ebfbe99922447574eea8c2b5c3f4d7ddb7df461f4fb92312e1f2dfe232e047c2bcf159e6e471a1b2a0867463e121effae07e28d4cd64b1e0bced4b727a9ca07944ca704f9de009f5d8d7c1a909efcf + +Input: 11c79b87032c20cd7f3da817b74b67092215884f681f117a3ac67fd20efee642986ea8db9f738c5e3f37d8b86f6f572c7cd9e9286b5c44908569d4d28746746abed61c119eb741c727cb8e7dea2745d646bb81eaa732f5f8e52b3ee58b921342e260df3437162dee31ba9eee39ee540aba185172d0581b0c4a85819f0bfff6f306607ecd3ef2d013f0ac4e81b9da5ef12e45fde08f9ed8d0003a4cd1be0fa25550804f35e1db218ebc5396e32f9cfe1aac115abd19864a2a2c03cfb16740dc83c91107c2bf4a7999f00414b5fa585a6e9b2080d69f59877872d77d426d3271f2c9d5d924f17b7b01feafaf574f42c00cda69822794ba6d285a50fd2c022ab7eb0c63a4bab21417de5d6b3c5916fbc14f746608a03ebf112bc7b728a9e8f8f284c7ce84864d59b1afba11b67fc4cc3337566917f0c38cfc7d5bbfd2cc01d2761723bc118407e8f2696c320a6b714374d22b5fdf355717f5ad5f44d28a287617c0418789912cb9ff6667b4052c32cab61f0b2b5a5848fe731d5120f6578a19ead99c8d2b5bac2defbeb8ef8aa0bf2a625a25ba7f0cb5c892752cc02c196ce648d57e205a0b4e83dba29956169c +SHA3-256: 46f61e0c3fb514f2ffa27c02e90d6f217ac778d1cd0a75753fd0a5f38157ed82 +SHA3-512: b76fbe28d4432ef367b9a8eb89a4c2aa6d34ebd09660f6ec8c92d1b844567329b71c13887047e688efea82d6e9c54377b0a0890db67f12f14b1b9dce165b7ff9 +SHAKE-128: 99206001d54279a2e911a83bbf32bcac933f62792a2a790d1b87b3475249d42ebc4e43d25e8995207f229bef6e2d26a18e9fdf671b62adf8edeb20c3e65c4247ef8d3cd093336741c5955ae0ef098203128870453cfbd5b5324224d50dfb2b379c8d8c4e4f364b5cf80e4c839a36e09461e70050621359667cadc5e035dd691e7f5a94ee1f5ceb994e8727547f5dd6776dba8d1bbe5ae2271e2334bfc1bfeb4f69dffeb2fd0e59cca0ebe40ceb409ebd63ce87212ea09908b934a92326ae1d88dfcc517bacf277ff999ce470c9cc42b0de9f81308df63973bfac35ec0ad3f288ff00714592543c2ac91e637591e07b56b080de67e3cda882a113ce9f60e6f0451cad63a8397cb299fa2c669b561f7650fe18e5b19afbec54b2c8b6aa9389cbb170baa533e712a9b01ea4f59b41c95082361cdab5f776542154ab545a781b9d14fe879be376533325d1c091b433c23b76ca21dadbb4f8adeac0bbd1fc59faa2624a3bf039880d971d16c091c28c6d09ac419c97951fd6892498287a4c32048bbd188f955873ff1eab07613ed041d60782995759fd5d03c95d8c15a633f3b488e1b554057d54fba9f8c418fe898a84c5b135c501fa6521f317ce65ffa1b54bfdec9cc2d0d0600f050ce593726ef6c96d90a38db4559945a0423a615e6f44b21c645f4eb1e1f7f709f3fea9e4d2bcd1e7034b5cc15aec2931a61eda7b4ccbc4fe60 +SHAKE-256: ad3a7249942329ca43dafab636fee31329aadf277a86210a58d2d0c2c991bef9e7294b4b50cf129482faf5d97a1c508c2e291879125e25e4862707f6320103300b30b171a0b6bed9f124ba9aab188b186f02a77469b46ed0277fed513331ff0107d92db83330a2f8505e824316b842c948ca4fba6510e9072e4569f0fe77bf234fe60e8202df85f41b925b9f98adb4a9600193d0d81fe0222bd9cf65ea7dedcea0df2b9fd5203eecac9578481614d48e297b9e4f371ffd153b11dccb3254cee91677fcc42fdc4373e0201414342be7f8f5018a1697490a3333df6c52200bfec5f3471a0b8bfc5a777e4682e4e8fc4965ef78fe42c86bb563014ece248b805452a0a570fd972cb03bb65d93d6f43021f42180a07049afc21e449af6afc5d6539d0e4c6b3e54abfcdc4abd7827f09037c2ff09f6aa19374cfb88a54090a8cb93bb46a8b395233520ebe1fa655731cbe9f334446734adc29ec762f2989f500085a3fbec5a4ca27c3b097d7e576a1eb6d22c36a69f98cc81c338db2d11c8ca16f276d0fb20aff7ca066e9172eba8e3b13ffe8c1f22802bc5e5c234228e25a780288db5d897c665bc62154cf6511f7ed0091228f9404bec1e49cd83c78fa0f051238fa67dd89a812d1caea71fb20161d63afc7f9019ef123818da33921ee53695b254f240277d1adf6ed89c1074a5d1b581d6eb684dcc0517c8294ef3346ae8dcffc4 + +Input: 5483f59fe603c8a309c9db96ddbdd5b782ae878036a09c50afba4091cfb3e4174f547868f5c0339ae0eb6590470ab07bcca5277c8d6a9b8ac63fe616c322827b75fd8b6180b21274c3a8580f1dd826ea746999fbe37940ab39bee5c3c8f7c9a1565163ef2cff32d3112c004e22bd960b8e3c74cabf7b82ccb3f8068a163511fd4db5758c3ccc546d206de924e885c4d27f75efbc55e34bb89e4805b42cda2afaf80c0b6f0eb2a97bbd78a399d4f5c528aef2ebe2566a36d369c5732476f8b051b28755cb76671625bb3090880a31dd26a9f431ea4839eec3d13b974b9119eacaea7f7fe464f7228db452e2664a3919a6a7d4eccb73900190b77d11dd816a31ae56da367309f606745d4303c135f868af5f77e0dd955f1d66a8d17ee865483bc4b832e68af892a8168eb2e2cbb3f7d369be4dd992e8608842ac895306e830e6fe68019a60bf22a6876e35098a628ea210d752e67cadc360955a4c21965326a5458c01623eb60dda8192bb5752a437edaaf049da567d4c378f342755c3116f0fa4bcdbae9d9f6e1c1d063a7ea41e0c8f4b084f9805a507c541487bb672faf461a446964f40801f473fca133658c7 +SHA3-256: 46d72950c6e5563a5d7e7e80cac515b464e96508a1b392bbd572ebdcb0dfa301 +SHA3-512: 447604c5a058c93b71cf5d714a34813335e0ff2be6236927328c825fd42d1d5611ab8905d839b2aa27fcc788035797ce80f50234331d4a86df2ba807ade68afb +SHAKE-128: fd5ae52623cd254721a6e1ad38b4e0ca84774f0d19869c361ea68f4c6eb8e1e915cec793facb4791b2d59ad6d79ec49b831ad33dd5c894f344be2b0ecfa78966021e008e4cb858ae3a72467dbcafb19fb3243fc47031f57f72569238a8c0bf9ca583accb2c44ef892e33717d9607c690214e222de04adef490d05e6ab948fd2732be828056d77b6275c74a46ddeb05a023933b387863b7f2002ce7c1e69cb0e123c9d34314bbf87a0c6e6c49eb4b385ea93bc1c2c1024b6ab50a2985661ba6381257ab9ec0d0802eeba83582aa7271d09063260d9e06a3043f1cc319ef7c3d07455852c629cc1feb197afab8fefb458b79045d0165cd231795816655ed1a9bf2f6684d191ef389cbd729314955d7447c4c4355213b21cf075ed992f9afca765c47f6dba333085d48084268ca144640ca7b3b00e540966936e52a0845f4063ac739f5feb1463b3e14eefb62e882f708b2532175ad5ab64ff9c8bf9b4b941ef57a8e9dab350db8e59f6a67592228210fd3f2ab57156091d7a4f294a74738c356fff49df7ab4bc8ebd0506a64fb4b1794421376cdbff6e75ba216e5d41777471501a13aa425891a708e27f1b8b9318a0f2ddd3b9718d548d727aab9ba4e143ac451426bd968fe7e84f4a73f6c469cef0ba4c74fc19b27f965e8080fa6f1c681f8f8073da572e42730c32cefb4d9664c823836349666589e9f3b228598c45ba93eb4 +SHAKE-256: 51dbf26ee171b9fac8a762ea8371362b599ea851849e0bb3dd6140a43842c2fae6869944be86f4f21982e08ba04cef730da705cd920662bf81c39f61a8cfc6f570dc01756b3bf4f131780bd847d9cf63e461bc5b7ef1aaae4821813897da55e4fbf38b1d3433f22429a8b08ca39933821e105a6fe9ece4ced6ae3576a14b1915f3825a932b18cd3657048816744bd8a9bfd3de4e903e97614a3518f1d480903a9894ea9e41055790621b144631f185fde79dcaaa382ccd31bf88f36430d9a7a2d7b2e358c9d3e74e97c870c06eca058e0b3e654d2207a2778de2c373f024a336ef2f798d25d7408b3843c861b8be1e3290419efcb3e5c02b3c3ecbdb00dc7f7171638490ae3b59b8b024ec96ace522b6f236c7f2aef6b02445ff09422b7075a29425b5c5ff3dc5dfb2ee951daf6a8b6a18eae8c95a3ca3f24304aa6719e24eaf17c558a90fb2141b2f76ec9fc6deab914e6a8b6bea73cca420c96fb0f59e6dea89408a7c6fc87a3639082ad0ab075df67a22fbf681c16c6209c0d26e0b9ac249a043ba15b9af2c8b04c81cc70f4d793b044fbe2fc87cb2ac56e9128e5d718c167a5fb784d82ed883e1c6f7b52b0356c84c9c7aa48930ab74497b40915efeda37a8de37b1d741649e3fd0e5f5301f26221ac8a83efa12aedf0f6f74e097662343f1a4728bfd4f730a154fecd3baea2c9bbfdb1d2ec43238263a8c3445ecd56aa5 + +Input: 311f729d490d2d2a1301551e2004f61084e3c8cad08d57fd80408603ce6772ee1f89303079baaf36b6be884be33501d57266c63fb556967e989e6c496b27f1a93d0e85540adc16ab85c552b73e4e14c51d081807e8763849b3f61011991965e6b46e0aa644a8d3e131b724954d72a0a3e9eeaaf6e34790c48175e597b7689d8255ad030d9a2567e10c1e896f93d5329975515f49ecd288f4ca84a88b2833ba07206d08272e42285fba5149a13582f392870f11d254a515b6af13ca17664036523525084c26acbd59dafe8324c12b3ca4ffa722af9de00ef08a2ac1b8707a778bd768379798b1233e14e50473fb0a6fc37e8379597330812355d0a9b8dbb43aa915cb3fa97d97e871987113277b36b9f6094db893015dda8eff8b2470e82913e52a82c769f84872f9737e59231270bcdf55ac8d84ebd9157966971bc91a9a0e2b5d1b9b6b3380b2c50440b1a627a8b2914e76fcbed0cf73687ba0a85029e4cb1ebeac4c1a22aa4c3c31835436b73d87eb8b8a34d4f919f4831230a6bdc93db5fade4ad066aa3f413faf58215cc51a1c56525efe4031cb7f77c29616660a36e1f4bf28d7d9395d6d4dc839e09cbda9 +SHA3-256: 2ad16246e73b208c52726f78a621a137a26bf994c5e85f9acaed209bd6fe29da +SHA3-512: efcf452757b25af2af7c5d078a6ee4c5f9153df85a3659511ee0b298b940de4694705b585de505011ef1f285b4b3bd6bdc828efd0298694abb9e4c676cb79821 +SHAKE-128: 0f95dbb3bf82ea2b1e9d651a4eb888f4260ba9ab8040bf7fc9723407e0231684dea0ce263f6cc5cffd826f08bc2c3eacef4a13b7ee4b0654645352136be9553e73473f3f8292f74309693fbca1f8dde8833d9528125f40da5dde47367b972d6a7b71efd95d415c926ddc0dce2433d054fbbc2088cbd58e3f335760b562a269505dd043789addefcc8fe7048a9e890f20f5a2eca48241563475bf63535c01ae54b4cad00e7dd4640157c834089f8110ffc13ba41bfda600e9ae9bf879588d7d2217c35645781d8fed66719d604080aca9c08e693a2eaf37f349aa7def8bfa4c9c21320235cbf19872d7f9bbb97905487fe2713e3b2871cdc26bf67900261fa83f0fd21cea450155fd125614b0675cec3c50f07bd714ea64ff9e18fc564954cd14ecf5bf136b17b3813a32f88c064a22ad9f14203723c3d029af1265c7295a1807d7322e70e883eacfd3726b555fa87e8aa41ed570a818a8570473ab3d12a26ebb18b9eab20f8f3283f20b69d60b9f8c2eb817e73a6ca7a65fbcd63ec4e83c02ac386392a94e84fce80fa7940e030d2736fc160ae9463e86f562820d003075b32be9a74f6dbe8228819223217d9fc5965d1ce4f979647219ddcace0f244378b8ccc3d200836aaefc7a32895f763c6a106321ca6b55e66b5c05acd8c5cbbf310de9f99b73746a9cc9c41de4ab9496e24007a234a495755b04e130fe568db9289bfd +SHAKE-256: fcf8f7a9363387f9132262031c42d0937b21c574943927da732ec62623687c6efde62e1ffce359a27403385930b3761951e4bdf34905108c16145c3f9ec868d42a5e0ff438d26392e43b435ff286608c3b003bcf2c181babedc206d2239cd018b322c43860af3fb09cc136e0f460e1d7a9f95b3f4a0e0500fd005e8b3ce5c3b349ad0f0877815e8a8c9822685c489c3fd72e708000d737ea80cb213d5080c5403bec71393bc26423984612c6c0b7d4ad9038f5a89f839bbca2a15509d7be42fd7c3de3f5b60fbc7cf122b5e2a9bceced23630d543346d882b6fffad68efc9dbccba48ab87dc0ae1ac50075ca71dae039b39d9773aae6979320705e4418ba761d471b5c2cbc0ff00f0540cf3bd62256897da29a6454c1aab67aa5e845d02e7915e755f442dcd125a48ec6813639648cbbd993fb39a45f663bd8986d6917b59b6a8773c5510e76ac353ce8c6d62abc25674752aab11a68e0fa5f8df29d6372ac50776a2ca6259a423c3fbea61e303ff9a34391bab1c2417f1c3b215b0d0cf70fdc1ecc3ca4079c6e01a6863ce07668df53fa4c5d8e5bdfd020a39622e76bfe36f053e5c4df3f293e6fa423d102ea05fd4bdd7f8941ee4433cf0d2116f585e9fe27351b49ac49c3c3d34c7e139215a213981d06ba4b52c128a121ecae8531913f77a996a8fda1475a4dc5bc3aa514e3a7710341fcf4f1e70cc7a466192648d23475 + +Input: 6e10ae04b1539b6dceaa726e36637b772d993f8ba06de646913106c086ec436ccb8e353fb8e7f0dc31124c8e938e4075216c5fc3da4f7bbd77804bfac1d36c478b759a37070b8c48bfa7d1bf38f493e4c32b9c710357f1411eacab7afd66474fb7a3f70c13e8c53f2cbd04ff35b5bbf11a7e2c1884b7a74cef2c45f23a2ed47d8b5c71170e22537022d334c1acfc6a0c1e1158174776706cf874e118903eb445c4a680bbd40ec789b7dc6f74be6c2353f695cdb2ff23b07f55fd8b1fec265ff48d179adb52ef83fae6545e2d67370e9106a8147cdb14b0fd4cd75de794c5fefaa5a9b56087d3b69dcc706a53ab931c924faec3cf78f2a44c0739317e3638139e7679edc84e9adde4a779893cf577a33d370b8a48d07b1837b59f5fb83815451ce2d139de4f9fadc82ab82d8b997c9104361cf3ba7ebb8e001de40eeae35035f36d813b978581b6404f6e3ca6d282b407fe6761f570d8167f6311deec586722bb4d9fef66ee146b092d4c1c74fa37c6221c7839109fc10033ab4c00a1be8518973fcf5cc274336330139121c4fb386f343b00337864088ac5ef3220125394345bc90c4957688085aa8295893dbf1986 +SHA3-256: e29f57c73fc4d589acaec784664ea420dac6f881097c0e6cb45ad365a2ef4734 +SHA3-512: 6c19bf7aaffc9a6f28c305acbb827736b688f65dc407c830d2fc5d66d7b88ce70b6416408ae797bf4c1896dfdbc3614a37ecb27d0467cdd15ff4a31da607db71 +SHAKE-128: 1ca1b3440309fa17cc879fbb89b609dc8fa95bf0fe7f1968f91d7f7d2c36661bb8e5aeb2126169dcea1411e0cf052ea47db60cbdd68a1c76e14e58cda263399228aab409e71ce0bd4740e19a6fc7fdd336cd19c8b7e2a818ade1532a4f32dad85f680cd06c8feb1a47c30ffc83c48798848b5940341eeabf20567ac3f405568e6ea2dcbafc17a60268f906f2d0180d9aa4baa4f346726ae53d08032fac2b1e2ef40f76dd040481c83ef88dde8cb03a650498b93a6fbfb8360a385089c3528929a3d8df4df1424f49f386f179ac3a0d7b926b5a9f9c490b7b9070335d507aa77406728905c7f4a9edaeae90e8a0b27a885e727b3f05c1dd31934911a24b4923ec8d9d17d4a7369fe88b8712544fee0777a72a02e99136cdfe8e652eab772f49a0cef2abc9a3845ef39890146337fa3c644ea8a1e758e6a7a7a168f64860b38f6e93126f33abd46b4197cd41defc203c69e8a2cf078227cc1d3f229d747442b30e9598da06ee281c8f1c88751dec0897b9c15bf9f8578d3d73925eebdfe1275849326f63ab68466fb4b3b4a0c7bfe0118638bdd05da217a78bdb3636e8609e6e395e3ab2d63f575d24885884039c4b1699dea3d7afb317676b3f71ed06adbe30847e4fe5efd29d5888986e82f020e7c252cb8c887c8b80b01c487028eee83a0521112a4440fd6cefd071fbbb5939a6be73b45c9e6504c28fb6cd78df9fbaa3a298 +SHAKE-256: 4feefd54e510007102ec356043d442aed1704ee12402f29ad2cf653c2f1f1d92ee32e31c8db9ef73fc21eb3f0c0bc25727e0c7fdaf79fa051be3979dc12d0584e96c12bc222a6b6df4ff468e792f15d6701be48d0e8a1d1916183ff8d4c95ef4e5ce7852f22ea8e82e59c0964b1310d6e48548b5fb66df8211b31ed7c963bf5b03a86d04137e9272bad48696465c26af0e0a0324fcb5c8bf425d2a33db827ae7cd17554b01cd848b45fcda62e3b5f4ddda2abe20ad8d421cb9b2eb9154d937172f523e540fbda545228b47dcdbdf8d661066f674cdd8005a5dad917d2de0e27572c1b934da5cd36642739c84e2bd2e3ee54ac0a700df72bd1f8fe13158794c36d1762ff395a3ff83c1f64b95617fa0b0e4a66a0dc92679fc4023580d25f0e525c4bf4ee76a5712cd21c0a2b77500f5b423b0a0959e97fc7cc0ac3c71f1d3bf69895412f83547073248c2a601f890708075fb561276dc10d2388443fc2e1df7836a8252fcf10bd59ba692e5b9e39b9b53a812f78cb09b4cfe2dacea1e48ef7675c75c3ec64ab053209fb365ccac3593444b234633b3c6147fa27871bf0b3056af6fdb1c30e6551e4c0357408c49f8d7f02c3551e576b897761c120c8d24148f2c448350aeb504b834bbd08c05ee40d9003bc873d3a6f9ae28171ef098e4172b4e154b4982073c24aacde5b84b15e0144c1bf674b35eb897ea8ddd2f3da69aafba + +Input: 890817ec343f0b3675336ba8089083822d5767bbbeef6ab7905b3a910b582c03f64dbe36cdfadde5c20705fb1553687ac193e22f5cb953d47456fce75bbf8c0bc48f89b57a875eb69aed9abd676ada7be12a04d169e96e75fd3defee9528dc000edae4c99e1f1f2d122222563cdf3f9c17fa61d455cd6afca6afc80a35a7569c677fee4becfbdc1c8a4b627421857b05d5d9d647367d533582373f5d6bb1d7f625f342fb6f2649bac416a4e5686d0b0e3e6273b3bed5d21322007517fd890c4f27947d4ad53b64e884e9b17f5b69fbc92b3af06f949c0de27ffaa63a27d349916e4f9d85761756c86986aa02f8a72f55ad0ad833b517471af562c1fb393ab7a1e84aa7354dcbe55d93c43b72aa3c5bb484e5aaa789ea71c5cb77fe1de0e53c0e50ae64339aaf68056b0c7d86e263a5c2874dde7f1fb69f278537a18f121ce9d5e2fc6c548635229ed62d22b09cb02c19a38931533ff0958077134125b8a85b452f0046b239aa95872f9bea0ed05010ca72a6782e911a7f87f5b6f3993914156220699ca8262b024b3a0c8a3de59c6accae895e9f79b4c518c22c22b22f1ee35f6594a1972fa76a5fa31dfbde28314c1f +SHA3-256: 2a92f178990c4d600d414f3c0b9c9ca1701c4bdc106e54e7006913e8ecca8106 +SHA3-512: 470f2c86ed49a7400257f7482aae0ba1b2be238e79b18d809d41fa0d8730cb2aff01720d1e971bdf6b9fbc489e005df8e50a3e6134b368c93e7b64d1fc8ba7d7 +SHAKE-128: 051a637a633f36e5d219447f55f1ea0522658a26a968be5889adc0d936e560748e86e8c0b45e4aed240fe152b85dd1e28b52ffbcf3ee177c89cca8c15fa9b381e95538b26be54d92bf148b6fb07d54bc551022664c701ab78cbfb42c916f3c7f06ade83bb7b85c0f53987ec5c44b8912d0997814d8316fac2e0593cc53bafebe4f798171d488159002a455b85adda65ca3a83fbe6b9d3f173a100669ee4d9ddd47ce8cedc940faad1fed6ffa18e011502f5f6dd517f4648f4016c1956889d4faf3b46d58dd51717316fae114541fd534bda877b222cf9e55eddfa89b80afa709c6d85c071963e257e6a6fcb8dfaf54ce3c775330b9ad8b129c63e802896a498e5c01bce8b2f71a9bda5fd8c915494bcde4a612e3428a045dfd57647dbdad12c7ac8aadde673c4b43b75eda8ad27ae954b2524f475dbe520a08a696c48f2ca24c769aabdbe3525cc99a38049da3c8ae230203d564701354219da356a844ee9b0bda9c90ba9ee7ae26066acc7134d5b8afcea4ad0458f4bce739f451cacdb18bf8a306c3045f3bf268981db5f4deef42770f58ad20699f53bb043bd222c8d3b484d61e4ea3bd8b6297edd36dfb7fc5e3d0fdfa115a5fd52c4041179adc5fc6d75eb63cc0c8b4b33f984b1d0f72accabb7d3a1595cc86087f9d1636b8dd3edec1a22432f81d99858810892e739e76cf477c7fef889d96c60cf953f3b1d00f5f2583 +SHAKE-256: ebaa5415440491f02d5a8b055e1c7914f9d091c6178ab00979e544c5cc69500a8bdf3fb582e9caa1cc1e50173838283384272bf8a65d770318a7f6b12a08d3464e9951ecf3ab7a5d62bbec6ad7176c8cf8f18325da3a9f3b89139413b640a58cb793936fe2578a98b51d1f75520a81185c0b42c7ceab32e0cce63c8bd4e7c9953a9ca0c384efac3a219acf1cde839c29dd90eb67cf7b251c9af897b525990b6cbf6a7d7e76f8fb46c20ffbc9efdc9b5e149e78b871aedfb31bb633b7489b31972365d7fc4a32e1f0b5c50fe11039e0833f445efc1a05c9651677672d35df9bb240a9a27656f04de652540d1051bddd7b19a58d128c16c14fd76f38be3130a2680262bb9cabf8daa3c54dc0cbce905f2cb72a9ba009d6e1c86a09ed613bf9990a9439d1146c988aeec4bd614a66024ade5b865ec59f47717233bf9c0712d7f2ab8e2efe3a8b59e4987e05b31ab7e75a135096e0306c3f46eacd114f38b4c694bb64b6f860bd3749e5ab5aebdbe14d0e7c0ad4f0e152006c5e2dfc48483a13515488e4c462abf8949e5ece3d0ec983ecff798e8ff29a78bdbccb5fdb90060d20608f2c8a51dc7469485201cae1e9c2175d9471c704553e0d3b6d3d11e6ee281731d85851e8b110f4cf67f43be731a13999392f3ce206406f250d39eb5ebee8c4b363b6eaaeb1f67ca512a988ce736f47e3b9c888c8ea5cfe73ee88d9aab32bacec + +Input: 325fc965eede4b0c81171f6418f5dc2f9264f6bb4d2a84800abb21d30e454d2372e5d3cd65daca73dc115d1ca06c2fa96f7fb70399aaeea6f70cefbfcffa16227116fd0677d7d8f0851871ab0eb820d4075f1b7c5c11b1e7584a4a7840af3af00b3ddfc25a43410266237ecb05930f295b7165a576a5a1f726875f22e88c96d272844bb63ca117a4fdaf1528ed93066e66bea38ef207285eaf1bbab01f02e842b2231b8f12ab139cdd2fd1f98af698b936fca5d7cd622f8eace4ad276b47a2620caa8c6a8726202c9923ccdffa27cff3d4a1f8d3425d727a5160ae3b1076f694ac683477e841b737c14fc4759b3f3fdd13b2f4c22632d79e598a44093b0d434ed97fd810764fb26672ab24402def8b49b035cf0e0b6b059451ae4c330ca54aa7e8070a6b196cec620577f4eb6707635a0fe0373b36a25c4a53702438879408c90ac34622e74677041eed7418e904d7dd6d709e14400e660b459f75c1a1b1c3e1fdcd4955d2fdf676ddb8131085165b94e2ae4a9bd0707495deffcb2116ca3f8e54969f8361b51122926077a6230ecf69c02e28a25aba96bbb43accdc92549d09b9b42c849f4af85e526d50968eecc16aa8 +SHA3-256: 7eb14d40ae231c9535b0205caa479140d126b9efe6e85a31a7f78ee015d12052 +SHA3-512: 340de0b738b6bfa44f1405745c5b686318f13cfa39f7d50eca45b0ef636d46f57b96a162567d9b026ce4fd35f631ed0cc3742b702044854049e8066c4bfe362b +SHAKE-128: 45315b0a7518ea8e35e79b6453abad02c731bb3ea27e2d508cd7cd4a604c37345e18842280a26fc328e7af89464686b133167691eda3bea6cfb9d1e639e0ff46087d12b0b6ef2816f909b8f52ecb22018ae70bfef7b4782487cb187e46699555eaac43a2aa2e1c0f50cb515a7524d1116fa98df741b1a6dd741fbafe116052f7998bc77018dc18ed16eaef5fa0fa95caf9b399f36d12fd592c8d125029d57e3f2920ae91b8165484d4d7ff76ba874833896af7973338db93201ff5cad2d623ee8c739ac2a5a39598c7b49cd347e491b203911ebc3948d351239e0d122787d5507ef5d5df33b49a7b39fc2ffcab20d860e4aaba9b3bcd6e78818cda1b073f641f1b4b8417d5506c10bfa2304f38059a32da330a5d902da1f8b365cf50ea54b740b1fb60dee60da0af2c1be06a1665125ffe227be6fdba3b818db1f36a6a43970bb17d3482184dec43b26277bfe4cae980d6afc5c3f754f17b510d5e570876cb7009c13630faa9967a8b6edfb9cdf537fc65d2a5c0f20f42dc0f157bb94492268e13dae8be28de6a01bede3edff3c6662e4495aeca3158e9912607bba5feb39267a1689435ae9a20ec914b76eac50b91c62de7cdf236fbe9643e78ee17ab130f2b7ba88a0ab2550a086d2b4457b51ba0da1929370bdc17ff8deeed17afdc7779fcb0319dce077ef52e14d875d1ed20fe1440e4d50572dc05401d0b65f180aae5b5 +SHAKE-256: 64d8011e69a13f5be2841050b63ffc3263a39ef7f896d79965e1b201a6f3b172760dc23d644ce822a0dd3e3a1a5dd6ddcdb5278d2923416640b3502e46545fc643c50cbb37a0d8ccbd93667fc093bfeccf04e42aa183e3d26c99a8a97ae8787dd07884a327baa49fe59ed93797ade9eb9de3a5823183a33c50de24188c90914efd654598798279b615d6319607a247bde4c9dbf1842e7eeec429cb3f534aa8a0ddcfc21fb32d4c5356de361a38ccb3bfd37902064d5d0626d37abe11a50ed56bb0ba1e77fe0483582a96bf816ceffc62989fae306c0dda7bd3bb5b6f83725a4c27a871a7dcd2257c5af5dadac6ad125f915c166e75f8ba469d1aedbb72ee3a49fd33dbadfeb40e124e1745d5cec8c2af94fc1902164648ccf8a2add8f672d222ea0d3d35580d919918bcfe5a8738ba820557efd754688c4bd342fa4a4f920b62b8deae395edec3173660cc2ccf9b5003312fdf4244585a68ba152de1c421c39319ec28c1c735d3009b10cf07812744f4582fb2cdf1c7349156e617a11be74672f6fb80c47387d88b70fe3c94e3016222a2d27aafa6cb80d8db90701b17d48a1b0fc6abc6230fadfe1d0bb23c1fef1de23453b73d2429761da2a70b5e784b4bbad30769e8559f5d265f542853285733e33a88831237f728bcc776afd30c97d3a1055a525c771d85682d1cd3c696449693d1d3792a404c3c213e87cea9ca969098 + +Input: 53da1f33b72ad028900877332f0512f80be8e7cf565557e2de58be31bf976143a00028069fd437db4f402013ccb9ce7e9157ac8f39509e0b27fed3ade62088e188bc26af0a75ad0bf99937d6bd8f68631d011fd956c8512a41e512bdde86329903ef9542a0cdf6de92d07a5abdbd5cbdee63ce5a63ab109535edcb3dd5890e92d3e44e79e94d1cd9c9328b0507f32c5503332b4816bacbb38e7d6acc7ba81215236597b9fe2652cd4d25820908621032213f4e68b88cb32e98e10fc4d243c0d57bd252caf12ededfd9a283c3fe84ed25638346fb0878090c35e29f807535fb4b74006262c586d98043fcfacce1515327585d3d071e76021846544cc54e1807580b1c1fa2c86692e34a04a74d169478b02464cd911d7fcb928e0cdf941785cce46dae566451687cf4c3a8a9e41d14a07861f51c552269162f959b22fbd6b32ec7cd10b0308167bd0c714c50bf7d2be0f1512a2c06a6697efb65435b2e939771d519c12a11b57622fe40a3f08bbb8fe176e56bb58d9e33f905b8aec2c65af5635da70ab54952d89bb9c993c1d6fa2b417ab7ce8cb700c94ad61fedec4a85f173f896db043fcb2abb8b8a911deb64e276c5c735 +SHA3-256: a05f5a917194140f132b32f9b3469cd80277fa919ccea96879486ba5ee91085b +SHA3-512: 8cc041d8129100c884e407453be22bb26f76fb40948d9a9db301ff1ad7d3be77a8998715cd76fc6545d5572962eb8305f8af3c0421175d23ddafeda7bb6cd3ae +SHAKE-128: 6e84a8bb06acbfafca75faabe11fff24c6070a0b82cd420c1d92fdd935a0f047b94e26648be69c632bdf3aa0d0f52f88e1eefa8199255ceb3b13d15a0fbaba74aaec8abe278950e7a72f9f482141798f003093ee648d58c464495519595407c67d9c198b974c55392493d217dfefe8337d5d4c2013f958b3521d13233fe11ac66e7a77bd81cc4f26cc6f4fe8473e3fb92d7fefd1faa20adaa4559ecca22f84a99ad97b68e9be3513257f47615a64aa6924f2401d051989eec4452a8add1d05ee1ba8a345358119f1570b210ffb453b9cf201b166e76843bd5677b146ca49405e8d8554cde1763a1d7f9d38caf9093880f940fccb1996465c648f63fcd4dd3c41e6a2fdfd69f86d3440d7da0229a9b6a61c7b0b4a329204a35813b37def776639e466fa7f63055dc61e9af53821953874122971ec62ffeab67f769718eecb24517473d0a17fb25cd98604bf6f708eb0a93ff4275328d97a65017b97d3b824399b7769e5fb10162c33983bbafebba282779e962205ae3ed57b892dfd0b66ee3b8ff47f404073b5bdad2e42a12f66860aa78db2bce8a18e34431cb23af0ce599b340cbd764b90af2df856072b9465ee26c9630bda052b0133160bc7d52308504022425fe08844a18e285d28e7622f4f121ad69214184d792a5789cd4d3bd20b55d6b26cb3c6a4d9e223f9ccc848379843474a67e65011334b70a4dd9569820b2994 +SHAKE-256: d0a79b4f8f2e670ffe564b4ec2eab465f70a8f9b0f8c721c1a55501442968d64fd79e2424c1d275eda288d90eb0115098bc57297dc38d7035ebc6e699dc33c3827682b8379e2e0ded3d7711384c17f07d7746efb21c81764acc6ce4bc9373374c01249c920677960be72a45b795fe22b7efaebe9608f8e161de62ba9187d6cd40c9645f01e3b85b12f6b4855e9b3ab0cf34af38ea7741ed389794c972cd2935caecc62d4802bb619aa629c3458f8d78c3f911497fb3dc6ab71831745c25ef2ce2e2c27492da7d8b1a8dd1ab5e580fbe1a07aacdd9e705e6555228a4988dab17b51843b849fb132a3256f5437b75f6e3d8ffa6be220586446a53b6aedd3cad131aaa1960331a034332465f7a02dc16b82dd61620fb4d02bd42f0f913e579fd57bfff1b089109067306d6e6d874ad44eeaf5bf72ed4eeafb235703b8386748363a89411d18e549ba39072fcc64151397f5dd0ad9e6518d9072d539aea79b4cd9af1f4a7050502149bb9091833d383e0eb0a254356308d0c7bef497dcae2b0dd9abe4590d480e3958bf976ebf877c4c4bcd10a609a705a00ed4fb0c64651c749fe0ccce0c487e420ffe19939facaeb24e303e595ac7a67a7938fbd47b1e554f5ded74ef5dd91f813a57385cabc8fa47eed53b4eedc8fa13daef08e11d8834d85a990129be5864dde91f04da38c25d3d58470a7bdea02ac0f6195e5e0983c367a3d5 + +Input: 004a5ebcfe6a71c234a240fb9c60144cb978168f95a34b4f9b5753d46a6e7953323621525d7854e1041690fd5a1a57ab5e430a6e608edf2f9b0ed6626468bd937249d7d79922db43a935af1bc850a038cb7ac44eec40f87708136f114646d78650133fb3a259bbd8ae2836059f7f750ce73b3de6f819d7f9f7cf945b9f791a96cb88f78c46c2c64e368f4f3518e8b5f0a801a909697cce8a57c4d337c33a99b1dc9628c743ef435fbd374da935a6706524e6c646f197d2d2487abc37f4534cd0797f94421cdbea6fac2470be362a30497e0bf11c3e2561347dc20ce7ed6e3707a048defd1ceb0ac1bfdb853bddf1f2b7c23c4ef4bd4ff3ddb0054fe64b573ddf5988329cfbc492326022a9df41c7c7ce7bc52a6bd859a2a96001677ab8dc35addc43bb2217bcb8d31fb7621bcf81edfd45627141f494ac6ae9e5328e57bf2af3c1ecf3ad77563ce4ebb46b6b7557e0e85418b441c94a891af67cc1fa7d28a59afcb5baf806eb38586b5eae7c5e6dbdea7fabc92cbfdf1a1b981d57b415541676c3ef54c261212e461845ec02c12253f7a1145706c89d08d80806358f6886bbfac89a3c3135b08f20998becb8acb220ec177201 +SHA3-256: ae875684cb784c3575bbfa9e01203dfabef996c66db5729061e86189385c6312 +SHA3-512: 92a50e4dd0eb994ba3fc0961d7d4d854e24446f2af7632dea049a39b3d144d412e258e4167803623680fa62b05950ffd5cd8eefc6a1ca84409c7e8bb154f0b91 +SHAKE-128: 7e6e968e35494e96b881901745f70d04ed9790f9d30aec498a9f3fd5c1b22fcf18099ca4feabef3bcf5dbbdda252a8af8dbe72aa0ea90d5e01b889867e4895ae2f0d958618ad531dc3da5e76d672b1d74d915c2e48b0b58d23f16b3e2f0609a2972ddd0af3796dbe5ef12b5d3cb215d48725fc658cfac56b9148a508dfbbabc601c06013074f389026e52afd7becf49fa2304b3cc818fae59df0b4b17de7330b217f137f84ffdb11c590dc417b0a2bc9faeee3146d436e3e06bd5565c636cad692d39c51f8b104d126e0220846e2904f4b293df93cf0d835e848d1f3d00bbe743401c19f6fec5c9611721304b8dff84e4b6a9c1ca3a8e75f4212bfe7263c9432729bc7e50dac8fa91aae038ef2e01063c8aacf23414876956aa7c09563542a66d80830dd560ae9a7051a66c3e8d3d9a3011157733ddb61eefc423a7a51c0f8066b0b02aa1e285908f1197b69ee6878d7eaed509063549f3a4efc532a1b53f5123418348c4d85f2a5319bc382d59a3225af9102b943a7b65082c70e6a194eace5abff0ff58350229b97c3a1a6e69caf67769bb2b9b29a7056d5147e3d440f396ef6941f0b4c308c43deadc1826061e78501d6eef28ae1fdf0ab9462c0c5e77d9d966c54cc70072d4a5d2d3f1fe3ac6cb74c4d852dee97fa013c7280066d39d840c8aba68365040643766aa7a5663bf41671d36d207ce74cd23b71dae234310a42 +SHAKE-256: 76357e53eb1a19edbd8a0ef55405ac50351168ff237fbd99c0887d15f4dee3ee21ee794bd5cb3edfcb33ebfd59e42c3ba86aaf00492d6563f50a94ece8d23c58a66eb69aab50337abaf7eab70d453f8c513a1a6c7006fb7ecc10cbc23c47f92a66043c512384e9d9547ac3431355cd62ce3b5dc1fbf00a89193e8d470ec6797456186f7072d7712e87a37ff4d56fc2098bf05ef1345f2527864c632379fc471877eac9d88e8b8be4d184b43fd34c39de01de99ab46fd466662eeb3af89d22b27c2e7254a5bf7271c57e8cda7dbf4e82aa8f196d021013eb25d0e00f04a4bc95a206b469877558972efeaf3bb23fda409205756f7c878d6c30c97fc5630aa8decce0b52f33caefb27780a2693234f5c70b3f903db53c974cbe21cb03df67bbccb39e773cad484fc7b7261be3c107ca1fa4eab64cfad80135707c2f5571c1dcc80bbc7df802cc2557d0155337457f851e1e9948161d738b322458c727fdbd5758fc3fedba1840a1b7789aef44209fcf8a1b96f9579aaeb34c8bf5299dbc85e635712a1df6e8b3010b1f67625813efe49c2da28e3f4c634e2fd92925d780caad0b3bc38124aa1f8ab6c2646efb6ef774c66bd8e47155c457921d5fc4e9d119c0315065e449273fe5cda8c8495f608d8e5a880e3b03f1488adba72a7a314bf749736d3e6ef2edbc793c63b16c574bde1736d2535f24acbcab5e8be65486aaddcf782 + +Input: 70692ec1adfaaaa9d1233a75464edb1835c26dac0fd2279724dd528945d80c0806f1d50dcdc2f761066a4ce19599cdf25ccf7aed12662a4c0613ed57dda5cfeb9cc12be86c233bb09b3ab5aee3374eae76b4de4824fa27924b9dbbdc025eefdcbeba5893c9d4ed62836cb6c8dd2c38278109f74c2f665895b485f3b5cc4673657210c44688e89360bb6ecbb341998214281f898ed65702b6f768cfd4b57aadff3b7f7ee548b7f72d8f878b61dc4efa5bb977ed08076a8d49d3ec0e26683e5789f95a7ef882f90c6b93e02fe5cec7a71dd9061998472888e3b68841ada4ec2e8bc60765cdacf3e2acbf4dcff2bfe505f0adb6f6f98320af17488579b54fc40d2664bca96e193d240a8efb99c189e18dc3806cf4add5b3cf29c31689c2d91bb98b8d5ce274db285ee99b36feb49bc350b00deeed5aceaffbf211a9b40e70333e61571b21b5d76eac5bec93ac3b51ad90de10bfbf8884ce6c21f6acd75a7d9de8bad028cda496a5cc94e136de32d1a66b5eaf2fdc2a3dfeb775569ddcaeffdcbf7ed201cf131550fcfbcf811918042ad827666beb4eaeb4722005140c3de4e8988fe24d429d6326adac8dd1cd6b614ed9de084a49bf +SHA3-256: f45cacd1f4e2b4a16f695e8f84f98415c9fc4d075a59d4a3301e9eda1fb11243 +SHA3-512: 50526d671c985252fd9a31db60b0ad496e0845a0024db1797aff00db53cbad30072732c14bc488dfeca4f29bb1b38d2df740370f2a69abb59a437048e8a3dd42 +SHAKE-128: 964b0be34277f268dea4554c573b5c7962404dbc1e02689b406ba22b8b7a947d9d9fd80da4e06ca625128dfa7acd1c26f05665fd5e40bca1758b3a332b643dd8218b0e2b3e19ed3cd768ed49cbc134090adfe874ed559a93cdd3a9cee42c8c4605df10f71ae4ee58c4e7e91aeca5ee6b41ad76c7eb74068cf2fe3eac82e85682e1e0396ec48389399ac6dc4aa60984f35b739f427a010282bf0de38c590b8a39f6603feeacfd6334e80efda7a8ca05456cb038c63f6a323ea04e3cfab621fc948c898116253888c9b97b39e63c5d88104eecd273eed1cf6641937a86926d7102fab775c706cdeb21bfe6fbda66e43e154816d53ad58dface799141c5d7d143f561f8f43bb8e41c19a806deff2272be65a75841218ffce79b4d0ff1c250c678cb017e367e037016c5cfca2ffe118e6ee0df3dae6bc816927f950f8956df14c038ebcd687313757d6a8adddf4438e3f02667cd391a12372591d1140aaeb95450a34d777bff276d80d748af96cdf84a55a6f4a69ec053317f69fddb5afec6286027495419e371a0c2c69357b2fdab6e9e8bc592f351143825a752276bcb237178b92b9b562a7efcb6275fb8421dd74ea43001b8392a464d37508b755529e8fc101851b8d7a57269c979ef70047e874b67b196110f253c18f10faa52edea796f5d3ef54ba664fa74230416d668789dddbd66b03b2d1b49b7d92b9278e77d825d8500 +SHAKE-256: 3174c2beedf485f0e7de3d4afa71c2ea92207dcd3b29c76626328fbf15a0c8ea0121a143c3b5d6edb12aba1c3af20f2ecdfd475c5e27e9b998b33e1fce1751c39df17a7d43eabbb230a51bef18c553ea70238616e1da15c5ee1cc8f21fb4f45b018d549f750c890ed5147e4a2b1f4c4d403ede330f86fa83bf0ea0fceff1c5abe56ca51d818381e6f4c631f449cf7fe3a73ad1e98d1d7453720e64ae4f0b9009a8ecd8520d8b3f07703ad83fd6bf681b43494c8b1bef85e131df76df174588f093ceeffde9b642955412c0f9fa59a7d4abd32aeffcf0d8779effd7835e2842393da0dd519f14d0d89e10ed8d098570cc6b0d90f04b4a90a1a18d5f07f70fc1e1166917806d493cf9178ad5f5800f919bf0d0fa5f986d477007bed3f68c018b48df819fb1fce1924b7f728e482234a0d679a8c3ef3eb2da7f6ee2784b477571bbbd14fd198145f1e9a29a120ad6dff8027395f8693b7d7a0b6b0eedb78808fb69d593b310054ee44b87eddc2c51501c5d97788d67baf137379f75c5b32fb97e20a44aaac66490c6fb83aea56cb8b815fe5b956b7012aa90cbf23768a839041c50e64d80f5b86011b8860b7ccfaa71c71126dbda5c946841807e498ad1007dea49a0145ade669195d3aaecdb04d741e55c990821caa362ed261f901b7485fcdccd5d3b552d1d52d9ee814eb443d9cf101c5bbc051d0c29dc433630e32de86fb041 + +Input: be261c10e37bf8ab2071e613db09d1c5dd1a4715169b89af024885b226c45ad6b731917d33cfa1119c553a3928e6d766db8145db612516ab8c61697a68bf3071178aca1355b2d4e3feafd5005674ba02c80b3fcd5fa4397e96db04e37e982690ccf4a944d29e0f72f130c5b4e9fe0c7ceb9a4bc119369792d49ccb75e2f821dc57801bc8da8d2a16bd09f0fca911bd7c39dc08b334384670031d568b80ae8002f27b3ca1eb99d8674ca01ed6289f037c3f57f67cf15cebf765ee6a2bcd1e702c26f2052ffcd681d693188cdcfbe951e29dc5530a2a1cd3344fbc6122d8a62a6a97dc0a1e57c76f0336b90c3cf17a60ce28aacce8810c37af1302e8d5aeb153adb65bdf4fcf930aedfc9482212bc7e20a6c5107897948cb777757668d8e1a6d06bb93102047320ddb29cff39c3f65ecca631630cce06e493d32d8c2a7976b08977e570838fb7309a8c0df6081781592b3588aaa6f25c9e4ccd8f62652af271514d0058cf93c2dd3e30c6f0dc6a8fd32acc669eeac9a8ae918144e282b10cefd7db1ceac539b2779f737ae2cf0da8a65a51c95a6560336444e7d43e9b22ef7b2d18b54bb91cb26b660f137bed1f369e0f5c08db62b14 +SHA3-256: c521790a233a269a553bcf72a94fd6dec012a6bde55d977660d302a4118a8ec8 +SHA3-512: de5701c82e392cf977dc580ab7bf0bcbf88f32f3397fcf0fec6f5b99abc4b4eafb33b2e1738c74e6d4322c3154ed286584c21839e65ab36c5ca2a01e22aeae94 +SHAKE-128: 7cae177adf11eabf6d460a5da6e4ec8a875f153bf8e74367d0085c13e7ca560db7d979e2852077a23ef526f20916ce1aa4bd10f18406e7c820ddb3b892551729e27d8ad47b2e86475cdcf798076bd6707d9b4df80f21cef6d1d0c61d36e7127b4b23f1c264f39fee2c2e3b828c94c04785e9a5744ce65a6670ae2c25dcdd258702c1eecd39a3d142f0c4e353f9df97a3d52d04c6a855a9b75ce8a73669cd017dc2590f6f3c630f86a20087bc5b1dee352f3ee2bc5159197451087bacf0a282ea211a337dbf5a9938577cb864d2a21b4c36b191fa36a63091cb0bfdc3967525ec5668d026400c331713ffbfac027a24d6472f7dc0e2008820c20f65c083aa2fc24658f9bfb57d865a6e7eb4fa8aff3d91e8544b219b0b4455382f34ceea089e9ee899b7ab301a02c1d5ac3efb2e7f3d4a2ba0639dc12e4e0362070753c6c5d6f71cc50a8dfe2ff6800eb8a9ec521e9faa191acd5ed6dd0bee129aaeee1797c3718292dc5fcb8a08d15030e83cf9b0f3d9c1d5ae6d7785a10c5bef64f2dbae674f0efea5cd107043198e8daa6634f5dc4482df34d00d259d09ffab0ad695a5347166059f7d643d5dc1467d9c3fbb8e77cf43d669d59129a1ffb88676a0f4c05303e2bc881efe65d4538c92395e24da69e1e6fa893d7389ca05c95763b5bf071f1e07f362846f00bc01e873e732945897d4652af835e33bb83dd2287af9b03d6562 +SHAKE-256: 8cb418f1b9ca1c8af122c9ea1ddfbc73881e384e2b4b3acb3d7dc9adcd7568bdf42a744add5a579eae523f109374eb55ed95193df22430591fa59e1faba2ea09c0c101dbcf1ad587dc71c82bfeaefd1f68093085978fcbfae52c9dc221d146496c8d9c08e06e485d879fa71ea535e8b7874f9b633859f8893e97235f9a83ca1f1336449c05477fb82f32c6d4defa811ce55c6b0b7f57c57c0122474f0c906a37488597390b208b5ad9f14296e6111090940ef0f2796d6d5c1cca86b83c1324989f4d22baf99d30f17fa19e795798660b8f70f54a9d7b5414c3cecc5ee9e6be9d7c78a5ed296627bc8e436658c7c0a3644dce286afc4b2f7c3e436fab862f101ec904f6784ffc4b8ea8c993ec53d245a57a7bb7bd633fb2217bf5dc6ed8ffe1b79bf2aaa7f7dcd2c1adcd8e007e34ef6420237941f07a9ba825b9b07ba3c4b47bcf8df1c270b35b9876a1233f55a06579dfda0ed3f7742eeb572cf9668e7898da202ee50869f26809e18fffc59673e11d901a918c0c09973baaec956f88436e566f1075d60264c1b0c247c9cef6b2842fd6c15e1bafbe390fa9e8d312343e9014854eb82ec7299cf5689d64b31de3fa18acc6090e011d8236176fa79da74a9078fe37538070c655c6b1c95b50edd4647054fb0320a63a6f820001ca05c89ee639251232ba1e207d3388780458f85b22cd9f4861c22a79a00d3202d6278b3c08d6 + +Input: 23ae66fdc58f09f355bc24ad89a041a9d88d3c2ac77496d18ec3b404690254012e7243da11328ff50b40d6a1cf84911797b67ee52de8ef306261092caf9f361e75c75043ac3dd429a040f9c21923d9bbb9281b5f8ca38cada35bd10bd1ec7d032a3a11d1a33a47c5eff3fd7fbd65b02a5f3a0572ef5df26185ace8a9a5714952b8653989154a692f0325b418baa08e6d617674ce14d9955a68625b63f9e4e0f75364a81b97fba0ebf738a65ed6c3847b9216a5e8dbd52418d9c568d7bfdbfbb3f2951199ecfb57dbd95b6669ab6ee92e448aeee48fadd3ea6a2ab5d1c4ec032299522c37f0cb493b8a1c72fe561af4961626d654c9ace39f1d89828ce783f62408c66a01ef069c8ca23830e0788b6d5065b082ae3784308e92b773cf8624188cba79424745cc5bc5e2c18b24f562dc7da40a1d3621e182b3e8b190004f78088e35faedb88791e7efe20255a1a3812080a66a6f6937733c7766e0d14d4d3bd98e2579b046204daa9a51ed517921d4894020b7d824ac9b0afe268352747dc5ffbabbe1d244bf77dc36b8d50e7bf00e8285be9d6042d71e82b432bf8f03d80ac46fbdae7172053250eea2ba01d045f7e30ca56b86c1346e +SHA3-256: 78c2349e5e301a27982af0e09d74bc220f01d8b52e4169d2dad2729eb082a98f +SHA3-512: f630fd47dec8ccf3a88edd9989808f8efc4aada7e7d585a8ec7c854d074573313a3e4b8ebd5100c0e3f05ac756ffd87cf3df906862b4200cc1f88320ce2ec50a +SHAKE-128: dd8d67406cda912483a6dea5a787c3348d4cb3d0f78100cdbf14d82612cd3bef69661c9ff61fa4df77a269d4f194595efd20d654be78e6acdd1b303b7c2c4f64150194aaee2b0c5d9436d2ead3b2333faac703d6157d1c5ad34e502d6f1cb424ed914ff0df59eb0fa58e6e99542ec612d4d7ddda81ebddf9289b5ea649a00bf749987b25673a012c1a6c83cb95e983fbccb8fb65aa2c7694563513dcb218f3e3d88dbfaa17f331201a1399e1c895bdb66b4b20273280863156fba39441c4a04798bfd493f2bb6f94a448f03d4639407f39e191015e77a477c08dd3f35456d132e2b15603115412fcbcbe0e4693e0ac211b64fea24d356ad57aff1ac1199d1b2e81d6fe689988caa28516cee8b28bdb7f7b9fbe97c1609815cb5ae221624dae5d46a2fce58f68c5aefb156c0ba4285c8f054d05731abcc5b2b3ab688cfaafe26349afacc8b605f67a014688df0bf1ba9e55eddbf0061a76ec34fef6aea92229cc4f9be78b590071c2756230098e753d947a8bd767b5a23ffac4a696cd65533aa327d66383470025fd3f66f317eba56effbacb6e72f02da58cf9be98d1892b4d375fb59920ece36b7a34350f4145347d346625933a477a5a3ee9a80abb26454ec3e9532326c28bc4ae6d8aad8443f9ede5e285a3a5513fa84a1e77a2b9bbfe18766fe0eaec501154667ed0b45089d1c481a2bce76932f402f94b497b614f9e8983 +SHAKE-256: 8cf0e5e86015febf37b834f370e036bd9d54c3e94b9974016509139e1e1d955f146d7e5dba35a7f5b6aaec02009123855b3d2d575968c8a6789152a6cfd3051dfb2a33e1fad0f533a8957ce7bcfe248cb29d87f74809cbdccb6b97bd4ca44d95f970969bbdec03319c7b91a7439f4a3aaab033c592a258ad02c76241afeff1883387263d6ced88e23ee562cee255a6682347d14cd46c5ae3f66c195e9069d668b4cea6f5d46bf745f363f2840c99e466ca0e715341cc6c2113a1a38910781dfb8666093dd507409cac67562e047f586e2e3ebd8eb0a7d58af523b2ceeae5240916de9b231e06f964b73bad27edfaddd0aefdc4ee29a6614dd51323e0e9500e4bf249202a2582bd0ca2cd318b92faa3e36ba37c6370c6b9618c50502b116b11fc10ae23462b6584e19c348761db86c44d5ec477f0c7532b7e33c067b5458f3e2481ba494f3c7b834c1bb052222437300f4133f123d2c754b66c54aa16c97370e81d6df72a6e6b065090f893fcb05eaf374113dfe83ab66a4c58244cccdd30b6f7b56e3fc069b872302a838d67b2b57c6d3692797d70de34652221924f57a4bbf283882d6e7a27342a990f5e64308135047b9742fab5d544808b7c86bd5b6a378a373d6a51a23e8a0212ae555230183308bd85a8327ab6e0d943164f90da8787f6977805ba7254f0470477130549b4250c78ed875319a1088a979c54b8489cc9b2 + +Input: edf9747313f2c3806c5128a863a10bb789f28c721ba4ea92bfb58d187c561628ad16301872bbdff47cece5a3239480e94b7da2a3548465d41f56dde5a3b358d28acc96bd7aa7aa88e688ce78cb01b690301678352c225f46543c8424b51e070e315e4995c74a644cae867ab5c437d844d7b307eba5cb40dc35d3e74ff6e07c4785c730f14b71b8c4e637da4b79a77a8f2c04a81175f866cd1f2ff61cee1bf46d4523d01c6351399c18157a8f15d9275a14a480bd493df357dc0d6db31670a5a275adf68832053614c0006405155f6c75710e1a4b2c61de403b6f09d7873bbf6f0012f65b5de4963c02b589c5400e7223f569b8fa537d1f25fbd78935ca3e960b7452c347de4b284d993cf386e517c3b7c6a40115377fb9ed3c862c110748d08020c69aeb94478a94becb20cbc1844666f8fd3b64723dd8326c5b9fa96610a4f493be226d5885c9482c9d26ccf266e8e3c0d2f4ab64f83ab6d1e6c2ea6626ed3ce262212906a7a29df55fbeb295bd3d0f63da06f87ce437ff897305eeb6cce11cd2d01d0c8760b73b25482d3f49ecd97d3b3fe5134d92c3527e2f2a53064e58ac8d6f9a1ed7c59196bdea7eb969575b7db3e1be4953a7d3 +SHA3-256: 3706da52cb41e2484ceea804c58139a79224f1d0ba646684f20f2966481a96e0 +SHA3-512: 57adfc4219c7616e79a0f9eda39f5a7a158990bc6674096427f47c09f862873ad0a8fcd5f3ca7b9c7fec5e269934c54f8134aa52c48cf1aada8f861e7ac07878 +SHAKE-128: 6ba1955103f2fb72b10e9ae41594ac8aa1126490ac0bb931e9670f6a2109f8471555b08e0a11edf5ac9429f47434b31470f607916ddd0b80fafb0eac1def563ce1bbf0c6e6ef082ee8f7dd04e15cee283a4767b2808ed1cfdf952bf5c763a5b412fb50a091bd3735c41147c880334b5ad6aa8d6cd78e67a103b55311d7fc671d92781f35782d0fb111e98536814cb480d5179b027788f4db08181a9eb61ad91507dbaabfb8fdd40b162fe7be5c00b9353dbde207430c8a6e0c603825efa716f54c6c13552c7dd8d6439eff408b464ea0ca54642b914f06f16e1189b172ce95a55f9c53c8fc502e565331d20a5a451aac4ba03b9db5cedf240e8d1f95090673bd1d969a7f075f1a559af34b025b80540dea6ba3c67401994564da3f2c0d257f664299822a6b829f70b7ead43a284ef2f5f047bb51af118fa2d09878872b4727847d9574d27aa066dc4a2eae41164e64b848ff2fc18a2e402170c39d6da5242eb6fb0da764ea405f9da6eec392fc6d871ca9396e7de5c18308386217e909cd1e6f82b4849cefe52aaacb01c41c0c2322d9e04f9f400aef3b8375c372cf04b92c3df974c40a446180a00630bbf520211ac0aedf26218c1470de1f9fd771d3b505f898b32b94152fda6a4f6492d66f2c1c7c98c71671983e892f0523b7ccd042afe7b1829d97ec8e9348f14fc7af1e3e24104e9a9f1ad977c8d97c529453d1c84757 +SHAKE-256: d738002fa6d2c752218e200d3f6aadba0d709e050d84de5ba946bbb81591bfd6b52bbf6a76dbbb5d9c6814d95ea4c22c1400227509bdef6ee359a589a16404af8529e536e62a3ab59010139488dff67a24b8c4cc1de82de846356788ba2d4d5b3b48d0f5f9c3c3ecf6ca5b21e21bd629fe93643a88a70d070cfe64efbfbd1ce71f30d56248b458a5c162d2e6d79f07983a7a74299824b92f95318c614a3205aacdea0ffed60da121eb903c2a0f86d4ba741c9ffbe8d271dd5c6fc488eb56cfe0b652e8d1b2460a34471b9bd608f46f3f50c5c50029dc70e6d27ceda7e9764a2cc10c601228def86fee915f9b613e8de18c04a221095154821363ed9c10b9ab2fbbcc1adf0858be0240f75ae9581773fbec4f57f156127131cfbbabf6651dc7e066187bdc1bb9642aab31cc480692387ed52513b982518d0c0fe00381b014cbf8a773f6b088639826d5f75825a846a6829559512e324fc36216e2c2d0974e31375913921b7a022ae3f1ed1e5404227eb0a6f7fa3114361c9769d4e3f60a2416999b2266f5ac60051738119ec7b62f02a61099676f4c80385458e50b4ae40705b9aa07b46e8859b28cdb3768b8c42c385eb03e7442d2c7293b67224dbbd888f18c14d61bf0af1a10ccc9ef62e4b94f3b64ee5b5ba9ba8b1f73f13264744ae10990d215151554363f16754d278ad374f0f8e70c0ce1d2ce7bb21609fa508adb3c09 + +Input: ae5307b02bfcd20bb27df1245c1a9dcdd5f8eb4a1611cec4ca707aa105a463ba4cea37539ba05936d18f42370e7a2ea2e429d728164c71e1352fe5faffba43ca0d68d063c941127fb05ccb123ff4969010d6374fcc7e156cca94b496192486866505ac00ace5b06d3a83d0c186d91177b99dfb66b8f755f5a00ac97866eec91ccee4be20b1172f0635534cbe3c3162e3f2a9949196600bf49bb801d2c12a7458f3d059dea0bc4aa963507907f5f211199d815a93cde1b053a80a49762211707a37b199e933fb3977ff687b60653e381f3263edc09035d8451011af9c8a1e9344efb610237a8ad679b161b664658616be1ab2ca95ca44fe6c347093c9c2387569e50b8ace4e9d44a2aed43c26e29ad66f5d58c4a61b5c1c234dd5a992b36eaa7f0bd622a9d23e092801a1bea185d1dedb8a16c71a8e7783fe4a745cf1c6c3df7141fa6ed4c5f79423e45d1013e74be6f6b4d4fc004c34faadf02d2ff04235b77a9dbb9a411d12f68a16fa3e97170720b9127f37909e4bfc00f18d105c61a8bfb04bd2ebad12471da4ce24afe3b56ada3e1c4c384c7b29ea27424aa6a30766e453df17c12696bfa5c71fea1ae79f5e6f4e96ff1bc5be6243e1 +SHA3-256: a40e491bc1fb9ad904c97303954c62aa4debf654e2faf181efc52348de93bd75 +SHA3-512: 33ff01249d71f5edf556df68b91896fdf3f5009f808a062b95fadfb32abf788b1ff9ac855f44d534d1a4d3ca02d2c5da271695233c4dc50c6756722389ad3f1a +SHAKE-128: 6282228b63bc113b1a7b0e674ab90a9163e66e84e09064bbfedb1aa636555777bddc29c5e3b7de4967babdea07d4788dd53983c505636d81562297c318009d923a0dc706015726b8a6327f5233ed0657ae0689d65b2e26eaf5d6351ea3c784e5cdab81b341aa5b30757b4ce93c7aaad815579f5e739d369d5e4af1e2056659cfd859033479eac2217d7aa0da1d7006403ae8358e0a886f46315ddf21d887b965fb66dc634a4026f58d3a6d31aeb19688d03e9abad4947603113c7287936da359404499f05235685dfacca61b0e445b8b8b44733b3dc0c85a45ed09f8241e6ff3458bb97804774ef59017918ed42cd64bc6c0b6a77e00eb9a107abd441192b03ddcbf5751514fe81fa55358eac1c57855f3acdfc68ab16b5c1032106fc385d11db2c72f2e741b336980aefa57b3a3e18897a7eea584b3029a3ba19de0582f65bd58d5e7332714e417a490c9d5d59188927feee4d2827590dedf37aa04ac37df0072afe4d352fcfa36908628db8bcfe257d052f5a01f21ba42ab8365a78eaa0906860bd40f3ab8808ca2eb3b2dcbe717811f05439e7d20c3122f4fd88c9131db84ae97d41eea07160d65025583d79340073bc17331e5f93716d6346d423380ea177c4021442f150e5fb25939598366baa0e47d1a1bf38cb4af5c9e97280382aab68854f7c9d18b61a7a81dedef248fd021feab2e3bfddf8cf3ba92f888cd80c714 +SHAKE-256: 956855d896c57ae00e3c967b0807127f67c1188862f62b2d0433643634e08f0cdf1b9c90ef8d9e5cc11cf142bf9c49deb88be641554a10ba8ccee2e70fa73c08174c77d7ed9443ea3505964779180f27cdb638027f8e869964bd5e10774f0e1028bfd520998509576d6f11f23c6f383fd6a7fc2added81364fe5db1fdba26c316f0e984ebf813c0bfde49c2b08c3415166308c881a1f831d921aeab9fd383eedf117ab5dd4742c495637256e4995dfa148be6c99fc78d69d2a240e7b2367deb5f33b75f1c903475eb50767a213a48e8fc9b35c0ff9fed4a714dd834b88b35466c28233bcf7b3985478bfde28c49cd86aad2d2bf2ecdce7da0dfb4da3cebf5ae3ed71fe1b70b74c62407004d63b12380ddd1fac5e2ca7afe632dbdba5bb0d8afe9b120bd3ceecb92559706736bbf9941b2f3143a2fda8a89fb7894a04b5bb2a02070232b0e85191e0f790971715d88fd1b74b324dc014a72a3d9d1cd57d6ab1a07b883b6083126151f01a20b23ae65c151003dfe1c9d8efa2415e1a2d4ad0b10196c6ef11b3b65523a305de016b0337ba8747fadbd7df01ca4ea96b9bc55e61fce818bc58c6d7b76131480f6d3d75607b2e535b3399246c46f7117eea9958ed4337c152ee7d4aafe7e24da828fdb041832cfd5a35e9e6a995e6a1c9b6fcadc4a8ae1437380d043ec41dc86fc88d0582ef0ee00c31771bbafe3b259c5a265ffd48 + +Input: 51bc633773828121ca25772b64776580199b042cbd6a8827f3e9224c942451082ab226d16ce4ae3a3946fa349431341cdc82f7d60a2831df09ab672335df4ba1c4c1572880d103db966bf255c96b5616fe9914afd0ccfba27d9c12dd962214743b111de96b9f6aa5983176d2af9b4fabcafdca98e4188421b2d0458eae4818484415e8009a1443fe0d411e6f5688469b8cfa9b6f5976114ce142477f9d93b23558138e7e1f0c591ea95a0e26fe30234a2ae66c8a7042978b4116614bde53068d929a9346ffa06a60fd0c3a7b688e21c1a8c631cd22b81e6208d028e23d89f78b9b85ef8bb314a8628366cdff9c31c35cadfb7d3d1fa76aba25314b5e7259356d8bb871c0cbf5df060e3c1965551307fb28571e550da2c2ec751152e7377e1b74222e18043c2cfb48ec6d404339d843e5d708045f80f53869209b5e4892c870a65fd7282970c22b99af43c63753f1f0224c7807829bd7b1faf5d7766baf537be4ac933e07cb474657ffa24625562c73724d3e5ce86732d80e65a0a7d0fcc8ce60e774e99347dd0609fd726390eb017ebdb6e00fcc21b7cf137d74c53f04796b14482a54d25559acb149c673c2077cef58310658e87ab47bd928 +SHA3-256: 17da9d43100fbe33617e152b83d6e012066e17a109cb450a9d64999ba7e99fc3 +SHA3-512: dce0819a549331a65b8f123f28c7de613eccb0da5b7e1dc8d264b10415636e60263e524a01df6c427eb905f10710ca60cc07bbcfa8b268c54e9d445acc5ae752 +SHAKE-128: a5bf7e5b90c788e3ff10ec648d8072840ceb3276791f2ec64d49767b109bd9c5e51a7862d4aca292472d14addec93ba39dc0154ae93c049b21484a11a62fe47416ff8948fcbc3074a6a289477e4f0731714a5d394feaef09531cceae6428e98dcbffe3335908e2f38db702aeb306850c67b9370153cbb4412127dbe39947a3b39283a3111a5d4de2c29d014afaff85e0e3b2625a15110ac03b598a877c58c52ed25c1e6dd9750410186fb869d0e2fa93eaa7fe9af3624fc4bd9077ee59a7da192a092d3243f41cf354fc95fe23c8282395e3535ebd3df32174fde653b6b1af4545325a96b9c1fc3dc9202e61ef03cc5357ad25946b62485468e80620904c31cb9b9dd071f0f3eb5ad2a3c3693bea2a4c3232f680d2cf1cfc8a5fca1a7af40360b2c22c373b558fa276e87692670b48cb0f3cea2d6b69cf3d33f415c606a8667b7d6868b578c53a59ad57d666ac78b920edefc195e180be072c1ad3f534f3c29fb7fa2563af16a34506b1c6f035c3222f84dc27b2027c04c5fb9838ccf54be3d18f4a86082b238e5c3001db5546f853b453ae09f141543f1135b23d1e626bef604c56b07651d371687a7e2c426e7c28db0e92d12d5e5a9c191a487f167de1d496504e802e7b9ef61a01a2d1e879a3b08c5f58b32b422dd87dde855c8b8cfc57cbee2e7d51537a3ed9b2875800e46b267264a35d31a1da53bb309649fa570a89ca +SHAKE-256: e778e94f133a1860eb78b8cb7aa90b359f95a531efce829cc42bf7f107a06255c8bae3e1260495adf3aa5bdd632d9856bbb7463f67aae6cc848083803dbe54db72041b94f7b6617328a67277656a0cee832058a4d65c925b4a6c4c0573b2d56ac7ba4d47524026d7cdba1437c10a2190a7bbfb550a224636dd6062483ac0dd1cbb29aabedb99d9398bf9d7ac93a45f88216873c452cc2f1ca2771f9f76ff287b0aed4af8ca0fc0a33b320b39fb345186826840fe1bed065ecf6331515bb04456919aa26d8415768c10201ac68e5fb234785eaed2df2fcab1e858def4848d698773352eda6c4d7975f2677c13efef0451f280eab71a00a8f669ff177d1e0a06ec0760eb2dd75bfc0482505ddfe9560a28455a4674da8431fea9e1fa2f86eff4b8ff3533a1ad986b1f9572c0aa9aa829acae00ee223383f8ed4aaa6771ba638e89bb5caf7a3473e4e676cfe6a30ab387af0489fe458d79d25a0dd2e1c337e7deb9e642159721c639a68bc315c58df800024a8f232fe783461248e8458ca741567795d6052c61ef9d3d8bd83fa947010e4ed3513ea81ca990d1c3bcea63ad7671a23558da7600ac1e7acbd92a95e706078259ff544f7491f2f14fd168677c74c5030d8495ad15991b57282aa9af7695577e8e18062ac99d4edc28c6a1fc4c030c5e8e065b45d114939405e20b2daac1b996a187a13a025f0a7f62b63e1c76672635 + +Input: 6a80c9539de86884846cbb32adf2a4d486e45f15541fc5f0ddb4e2612c0537ae899eee562cc9ca1042b58f3ab94a42533ff45da686260738b72e19373ce5b30dc7f9ecf54042a5e2274ee02f591a629a12022fde8267ce14031241b27c20992a833e72c16657ae23b1e390c88e918bce80f38b61c48fbda39e5391e7cf1c1897ce02e5fa368095bd8e73b18437bae9501c13f1311472d135e2bac0380a112ed99ded2edb914149a0610e1da0cfd70f4bce82ae5ff5c36717ec565904e7cabecec569ed17aae19a1ec19d8ef4403fd4617b407b9f2bd6eb6702b0425c9a81babff6b0fd0f3ffe645bfd0cd024765cbf932ddde8489642888dddba163bc6098e7e81f64cd130a89f6e41f2ca393fc26579dbdfe3716884652115ad2bce855d4da2aa411998f675baed3257b8d46ad2010d4552798992b66ae480fb0a8516e03ae972ef92b78ee0a687c062bf1908b0425702f0803518da80b4c297ebb9a1130962dddc367f2d556d5b1600da7ac667126278bcf08b8c0a85d312e51f3c030e897ad0125f6c107b32ea566d57dc8c1e1687f3d78a5ceec32ffac1967e609aa9913a78057b734df163e20a00e712a75900415b9e69cc63445dbb9fc8 +SHA3-256: f759ff0023bb3864383dd9a2bcc23c378fca02b44f4e569f4716447dcf01a7ce +SHA3-512: 64cb03171b17e4d19558e95417ebf015e44a7ee630c07c3b77725330744df4eef3ae02833879c0e8dff2c8dd9bdea79276147275e80d999c15fc44a67bef5844 +SHAKE-128: 5628a948da4d76fdadc0b0a5b282bd4447f0f5e805f6894e40c04e095e3af8e88950dded116524b5cd085d1fabdef72abb3b52dadbaa2020fdc756775cd1b7f0976fdde0d80ffd3e4a2d4f3bdfa7aa0fa163480379f378bc3b9cbca2712a6da77c2168aa04ec4eabfc3d6a55422c9a54123341a0bf1fc76c5dc2cf0de005f39d88189af920324143a931b172c26cde384516a5f0559c9fd9b2d94a12b8f0e604320cc8d7c5870650f3845132d93f183ff77ac7cf6ba0a2efe42f0ace47e9fdfdb922d186dd7bf58faf81fb5b2aef387555ea204bf37e921f43fdcf808e836cc4653b69f49b1a61a613169db0cd0b4c126852839fab173cd5a7c7a789e0f63ff204d4958e6a588b69077aed2a17270209bc637234ff605915d6c3d5fd7aca3df80de543dfada3fed60e22cb6a29f931121901d88e9b484d9f0320430686107fa2f38e550d6cafb7fa90562a83f1fb12c9d7ef5cfcbdd3d20e254e98865c78782d867e5a3c4be6ac7fb5f309ca90f7b795aff1a30b561a07ae7a131d8039e15b4e21ca23638f66914bbe9b39bafd98d0b04cca3d3daaac396d409d1830d3023b7e2a849c9f6f6bc60c29b6b7542d32c625d981e126248beb31851d418fd8dab7890fb3cda9a89a9270fa91d051b4cceba63f2da05b3910945ea25ece17e654e278b125fcddaa1d4b28bb48cf91d884059acee0c15a8ca3c48d115440625f8715a1 +SHAKE-256: 3233fb431761f72724e30d79dab4eb7f79fa588a7391c6ab41ad0cd3fe87096469d5fca2e755c5f899ba15b5de8e10d2e16a44c0cf93c0c561d8e136ec94247ea5729befd55119934b18b146acbdb8f29478b5f958268a06ba6d1d0982f8e55340ea2181861b3b09d41be39553ce802a54b54a48935d17d833aacbd1f6448f6973111991e529171b2710edc972b2932de56fff0c055ea2a93616b6f9b8dc7e821dafedef6a26d0e1827d093c020e57ec0e1ab18c538e21fa8a40d99071294706d3deb945b508b39628de52193796b5f74c6ae0280c09dc43ab76fc70ce9d7da79ca70c24574264de15cb22cb5a9d8138b24877d96bdd58bd53bf68d31fe9676bc1337cca18cfb5ad91e9288b808cc6f665514ef2a1308a901ff5121d65e3d05a7a8bab5f0b3cdd1a0d0bc92afba079da60d6a3b570f279ee083bf9176754af52da85baabb646fe7afc661c4c34bcd3eb426f229a451f2ebccdc62891a9575f6c5b3e061d002254af5abae1aa86a2d2fe3a533f52341c0f3131aac3ffddaaebda72889919c00b6da40ced07b9db81c51979fe5044c9ec6e83bb241d1e5ee5de081704b265a348830b2dedabfcf4e99a4979c06243935391262a204bc1d2ea416cd99d941604bb1fca41d9e95d913f920fcc18778d179c2d9de1ef1073d307a2a21d962311c7176bdc47b4078e7299f04bed09381c0dae467bc2dec6a695efa3c0 + +Input: 0e1a026018e6dd62aa6b7b445dbaa8100543923842c276186501c56b00e88615aadb5edbb289248a9a76247ebb00d49774cf806d0850a6125a42cb9ec36b9978a3195c11db9609ebd65077cb0b09b52aa0d72cd5159288923275dc04005f2c1bfa313206e43862dfe555e5debcddc304c845f3bbf02d3912df37e2e356e863ed6cee6eba07581eaa3eb0968c5fc036bfb1226e6c08b7652a96af40cb8eca74a3941eb901c738c439df002d7071c544a1f0eaecff21a28e2a41c6fc3442c78834ee023fa7a074f2c1a0eb71bb905fe187136e24ad4aa8a2a948e1f48c39bf7593f21cfdc712dbe4824d9501df5cc7273df92d59079a04f1b9a03ca31272ba5e9cc3a47228208417e0cb02d0de546ad645366afd78e2bcc2b3f1eefe55a1db513d3bdb550ca093f2d7929f7b7b095af18aec1da9a2c79463a433dae73f1d420f8a0f30218a1a9e1e93fb3f04c3094a4bae8481bb4b2d0483016587db4c5be2cf5004af9f52e1e141aac586829dd6271e4d572ed9e40f5a9e80f37b4d647b2e9d818f536218cc5609377d9b04bbffeea66e3b5d3c9ca76da4aa392629881833b3ae58f50eed8557a0463fe94e351e4b39cb5abda7aeac0bbb9f113a29 +SHA3-256: 7f63be8aa0814505869404a1126f6602be2c00832732cca64e327e8021cbbdc4 +SHA3-512: 57f13c2d767a5672bb82011d28da74b996bbe0b8523fbf1a2c4a6bae31aee8d6586b7af4d4522938bb6cb97e8e8dad248719be9db1b6d19b1745d6f19b70b587 +SHAKE-128: 168a0b4ee05a49e2d94fb6c052a9cabaf4ace827efda993390e97cb39cb4e04774185c3fc952948b60b81eec7ab4f78aed97437fa4294787a2fd90a228a8faaf8a5acbfa8c8765315ff280cd1c2a8dd3c7849b66163e2026a29899869dfbc149eed3f418dda3516396c8026ce59636a75897539120a2f57fae589f4112b192a75741db1d722a931001c13af6021f1bc73a694ef99c9733fa130922354b035c6ef438eee1f860b33d65c7a0ef94a3dc2b48d23f2d413315b89cbb38fac22c00d33a84b2f7eb28cedeb7e1d333adf3e5da3d95b049ad1606fe1bf030a98235d31f75a988fdc43a548e938b02b57a575d33b8fde3fb5da1b63e647f8c26723d352a406d3fcedb74e11cf0d5c55bad86b450646dc10afdc6f3c175d577f6ed7077b42dbc6001b92c4679520f7c49ed21d6824880ab80c43eb829dc11aaf5a536abeb65b9b8622ec0559399639041194935346ab9a7c5dbb2614d387199cae01fcc3724d7a9983a6765a0d2db2458f563e97075e768141528896dd5d694d1b401492f8600f350fc73689a94ac2180d75b48f25971e2206d80bfabe00d72854afffa7f2b265cdba47e84dd3d309ed69cd9ca00da61c5a25a990f6a61e5acede343016901f34b731b04c1d83967bec2c3df00bfcea9257034eae086b9a036de6f97cd30b8fd56643219a231634e5b5e6491dc0cb92d77c9a855c21956fd4924947c09a4 +SHAKE-256: 994702c59f3226a1336ae531054ba669642272577229208771ac1ddff8eb75a979f049ebb279eff2b3e2c6f3d34ff4bbbd7cacea6b3c43f56d42149424969251bd96913470f6bb5c1c9968a085409738d6ebe9963deceb0be4ef4f9f79c00d588b35528cd8bab75fe4593bcf2d317b7413ae8c296d54d29576ba258cbf08e4acd3d96995266634fb994bc4f0e7634fb6f48f824a839c5e6a4bcd7f661046c8727ebfdc3137fcab7dfd558dc7471c5a06a76e98d84396f58a4613b3dd5b14b9823bb06a2085c38617b41f5974bf5eb4f32697ab1a92e8a91722fc1e59a008b6f3a4114b460b0fd94c9fd3af851d9469596f7a46a37a11dff948fe1b3998cbe74e98707e7d2e014f604d7ecb8cb93d4974852ef146f04d3f2ab9666786cfee4b20fa73afef503554774d2b4bd14e140ba57484364263f495402ec48cc31d4721be6fc1452bf3de05c4d0f1a1cf794ffd32a4492551ccb181d46e0ceff878425eb4ff337f5dceb849f38f9fc937823615d47ff965b858a7e3764c17782f3f4c67c2905067f5649257ebcdda334b818f984f7dd09494e52335399a1de64c31a2757fec7122404cedcbb2dc9ee583f6cdae740cf97497391ff75bd3c404b2a2d9eb25c6cc3138df4a70b843b66d8140a40303739495d614937da6620adc4eb69751ddc91a712b40ff22ad11448721b32357d1dd0569cdae2cafe16b183caecd242036 + +Input: 63b2c3b447a8a0b39fb643dd48648a28f61ac2e3834a3db1608ab1220592f633a1797b588ff7378a0a1a7367646db5d458398b48ce88c8f378f89ec7e70d6dffd378d1921cb25247977531935db30a6500a79a3b01ad1f107f4fe02fa06514ca6aac7442ac802278f60a43414f4844869b5f186f8f7bdff8fe368823fd737deae0f1a85961d5fd458113568a7091d432e64c9f2d245643e254793901ddc8bbcd4fc95b8c8e82437b5f54457e789f7839e68c6333888e6862e5092534ae26ab3ccc73e474877330cc4176a10b0f225263ffd32ffdda3670384599e3e0318088d9edaf0d6ea1473c5c16855ec59a7e4a22f2af481541d28296bfe6765b3a477075fd5d8d049e9de3f1dfad750bf1567cd56778fc4676c4e83c17bf25017ffe90f63caf2ab46e8b249aa7d3bf8afd88e5ec181757627ccfc2fca618ba072b64f0fa0ead1470d90de28cd022e8b5dcfbb0c0c2ee14143b3da7c85e6a830af1a4eabcd77b5518f25e7d7489c2d188d011e91455e06676698731f779708486622e6e0c41b151b530772c880daf482e1436662e0525936e02622d92d6f8a7cd39486931fe36c22198384959b1bf0608c5945e62acd5d53869d06e0dd6f80c98 +SHA3-256: 1fe96fbd2736177cb5ec675cf6e6f265a7d0e87448ee7d42b60161fdcb845304 +SHA3-512: 025ca502631b3f1090baa7c690d8bafbc28652a30ac36672546bf1ffa1d92b68f5b27f7f3c1fa161310438ad4968b213216e186a69b9c83f05391a6d0547a4dc +SHAKE-128: 89c039aa97e0cb41adff3a914556e55c857b9f8461633ddbf0f2bfc02d110624f94d47e56f3477896bd2399d6b29d8d29c9144ecb79f91781b7d0a133148ec229e1f626472418cf170198a26f16636eea9a4a570c8de820498eb05d9e56261505c6cf250616ad9ab3162c3c275ed45c52fccbd3c4c2f220b52018f2f4c52104ec5165751d48f0238faddfb05267d909ce1c3d72846fb9712d81664c0b478166f97239762e4ce57fbcbfc1092004ec834e3aebce327eb7c646cd2c2ae7b38ce1f19c1bf668a6d50c6c6403f406f69a9c3a277fd5b4bd3a0dd743437719bb9e257221eb74323a25ae8055877dd0145393ea9f01916f8f87551b53bd274ab4787a9c1ecf974d570f256ef776cab8f93b07aa7f5199e502d9a4123787e5aaa798cf854d1fabd9b1d24a38133693eb4f59748e34155cb78448df69359273ffcaeb8e014b830ecda68a2fa0b53fb752ea0952757069a7d2930d2108d712dda67fe0fbedff7aaec416da7e172258fde30942f38e34bc607f8d3df7a73eb584b26e26694a6f178617b19f3753c948e9810de379bcca332849a562e02b32d1ebdddac8b986cf6610c11c7ecaaa559cea8ce160e0f962ba600619c799e4e601861be2554be0abdadecbbb6e278bb73b75fe911235bcbe524ffa363bc75d20bcde05ba6c544a3fc3094b9bcf056e3e8fa428784c860f53ecc447ed3ffc6a300a89d1b712715 +SHAKE-256: 3effa44e398f72cb86a1c010cd54aaf973d8b670af1e7d41a01e2846ba6f6b3fea2c63d5fdba2bae0586f212cf5041e5f082aed2a6fac98f52828ac864781a3ad1f85e160e13666912bb71c5b43fc806160ab1be0e48f0fb1d5105aea5bd9c8ee287535275c818b7c1e6ab1fbda7ae7e710802f3ad2bc0cd031769edbb45dfc1199e4bdc3c74ee875f4dab3b880152a5aa802e5f7a2d0d8c7e694c9cf4ba68b0d2d12ce730b67e0e03c3c6cf22f254333991e07aedaf4e335d1d2d85567d8e6163b7ec9bc78783b3aa2bafe69d93d66a1e0e4b0e7cda4b1a9ce695227b2f822cf87e7971d2429b1a9191cadb8698073036680c9b0aa37713ad1e2e009e005a4352e4c55bd18878b8bc99be0bdcdcbc468ee9b7d5474aad7375fd57196a6cb564eb3bc8c3b51d5ff1a0fdaf2fcdbfd6b68d3106181ca73972008f8f576a1bafaf42d8931ff097229351ba59e8221f0a36214012f16d5dc59e5d5fb9f92fe7704ba9641063c363d2d476329d73ff9253fcd637c906517ae60bea83033f0e23aa3806b6fc6214e15ce85a5b13398e03514f48d468aeb6256d274536f116724ed2a600669d663047198ad436f1bc9dddd55c33a061e8ee40b4395c2f5930cf51206d502e0ca5ff84dc65b57aed2e3c91db185779b55134548bea4fedaaf51b9d4160b578de2772dd1ed7789ff6fb4e8740c95070191e654b9d21e013ce438852428a + +Input: 1ef95bb0ad9777ca5111ad9e30842022583c6114ae17ac533b6f3fe73bd4943bd556670e01be8e5b85fc977ffa959043228d5661f804f37e075e708247774e64cdedff198f2914113ed851e32b78284b2e5dac156315ac10bed5771d1100784d09aa73cba29351581d5f829e914e0ff1d0f49bf2c4efd416eba1f0ec8337ce9238d2c84a3205ca05b2d0f14ca65cc8a8d898d26306a14f43fb9cd4f29bbfe97ac41abee098c4a49ba3bf31b2e1fc2942dfe9a9b6a41f1b3ea0979df23865aaf3c27f2d7e1a8a11606d8fce6b3085807bde5a6d40102cbf138517c1a7f623e18204bf54a6c59c0358ef139ebd7bd0dee3fa0db93ec20d3db30ab6120f1c9c58af934e7718c78a4e8f71f7a8e95cfe74740f74f5de8cfc586b601d28921822b8746f0487cfd56f0a97a77ad484182241df7efc3c86390df198c3a1b8981239677c7dd3d96b70aa7df2f9b2ad2e4496f77a2671eac2b4c873b9ef1fcbeb3d9100b1ca4c98b2a34c6676688dcb90f5d91192885b0b5c4a8da568cc832c22bae20ada7f2afd4ff8202c79da40b319134e83eeb113cb090bad29b5b3e4305ecfa83bde4b7e48a98179b4e6e44d4e0b32ac28d5a978904fb0f50be40cc97d10e7 +SHA3-256: 0c354026a9cb8d105deb5169d9c2dbce9537af04fb52d8c74d8683570d1a5efc +SHA3-512: ff3572eaae59c95fb0dead2005db00be219fb2ddbce474f6c5095423ee0ca499d89718e4ea8a968e21f35090ce5f76e935d7873df04bb4ee0cbb3353ea8efcfe +SHAKE-128: 55bfe102d691cfb12b15aec793bd977c234753250ce08a54bd124155aef6df0259dcb20ac53babe14086b8904ba6649bd6168fea876ef7c59d65d4227128a0004a0b5e40b8f0fdcbdbd6c7f74cf2aa0e74297727631db3da2e1d14da54f0c1d05cbe511390b898a63dc689695474d69ec9bd5d050e6881deaefcf124cd35dc59c78a2ae8bb246b51fdfb8d8bac48b2a1966badd7bb64c4bc5ec4e69cce3a5e001b8e332b8b03ba619687ce038cb50e820dbed14767a8404e3b9ddd3d32060204362c36430e0c2ca87749bbd3b3bc9d7f5b948f9d9c113717ab0fa9c4150c2365a2225567380aea8e2bbb2fa31e91e3f2751b42ee971405714f1e9fd3ae3614c6ade0148259f9e8f6fbc27d322d43420670d4550347a52de3a43f9f73709140391c1151f8a7821574a07703d78fb1ff745015d1443f77aa1246b9d53625f55700bd3b9869a6d063d958e94e7a391e9857551e2e5c511e1e79821c2bcdf7eb262174ab07a115f7274b8d1f7dd8bba9dfefdbbdc3d9a82108471ebd188521ea2c94cd9326f484bfe03e9fbc00c96acdaef2f825d04c64aade7ecff37c3e409033c3a8625462c2949467520bc5a8b9893e7481f64070f30cb52bd6e90a55e24f08bb74f5cb1b395bc9b89790fb1a3fc90d6ba1df4e450fc3a9f0702ab37dc841a4ee73486ab6d8f692a80bd581b0c6c9d6e7f7c31c2179f0c31a0e0826ecaae8a150 +SHAKE-256: 4d10efa75cda8081f2013b67b6aa6f10d3d3c9076a0f9148c3cdacbf047d708d8291de7d0208deb94d87432325a992f7d90e862d00cc4eebb1856931958768d08201f1ec88af7800b99d221dc845d700aa3d4518a6018a84486cb834e003e8d787a2023c32a34ba8986055cac903808fd2a08bc3249eb62ce6e72f9a9c43d44ac101e37915aac92614619d005dd9750071535a57bbc608befc0cb4042fbf898488a78315fea10a91748493a52c1a629c08130bad8057dfa6df85da465916944db967a7ca7b5a2b4f19e2d2dad1f1b45a7ccfe988cb8cd5008d6c5328a94caad2f242785a02e4ff4c5797daf4c05060b02cf75f0a550015782ea0bc382391075083ba66382bf371f5649a184844e2e444f3d7e57543e41432ecbc34d27f939987364884111e134ce73bea9f43147760ba4128eda8cec8e9ab8c8f930236a200dd7e7f7f4158d8270ef9c47c88782b68a883ead8b4becb595b4ea1fb462877796548b83a89c2c0bc47f192b90df6817c1a80ea3b3a18afdccc7ceb63c8e005e29df159e395c17172f4e26b067c6fbfcff1889027e228c2f39da24ac0320faf8ee29d2eaadc8a04c758ce499411f72f1098b8b4f5f0275ef6c927784c9a5438ea41bb221a05e073fc08828a0000fcf5170faa5f56b202f8da6e26db03fbb9a72fdd8754eccaf26d10553d8d1a7e2b6006bb297373953c76a257e4038f831cedfe21 + +Input: c6152e58ba1b4260d33e5a433fc2d80ecfcd95646d680db7c5f6890b3ce8daf0e6201dd2622c68618a8431a005a7aa651f4459dd740edac0abebccc0da4e1d311b569b8005fd43f31ad79e56a8ac8312ce10786c111a7c25bbe31284e0ddf8e9c622f114facd7ea27b02bf4243d29689c1465bc643740e34de2e2e243fe0e9c35283674d3b856b1fdca1232a54d3cf3883216aa75155a42a161c89a26c7d6e35504d8eae0013c5fc055c8f1a773c043daa9fda127106ef8c8aec9a5789c114dfed6cff32420a50019ad9611cca164acbb508a470a2d5c19943d2777f00cc891e863d200f8d4bdb2fec48b0539d44de06755d4d4a11aa9f12f001b7c3f8db33c808927f51b71b862e9112f755c5562ff19328854fb07ff3870efd8e71a6883ba50e71b14ba8276785dac4a0b65a48cb3ebb52f9437ca5000c27113ca863cb75225e930ae5947474fe33cb5d1a0e496e177123b9709869c000efbe241dbea3a0d64ce7da69d894fad2f9dc62b9cae800dbd5c7d3047c8d703ae36894d77a21e0a47bbfe851f16a24b87ae4632bfbb7c6e4aad64e9c3a3adfbe51d512478e10afb374992f538f0b33790cfca53f829a5c18222019e6b78236f14538822ea66a +SHA3-256: e497dc9a15c8364734c858571abf283d684efdbffe4b9676fd3d3c6b149ae0bb +SHA3-512: acd7ef2fc2be672ebc4891066ff4240f1f6dba3d59161959f41355e89bc013b4db30d17a4f2c294879a52266f50e75234f20c72c7b1fb81af950ffdb17e5a1cd +SHAKE-128: 55e1c01c18d54398473d5badeb5ff69f94036044d2504496244c55973b195e30023fa926fcc8b7ea9bf96a3df929bc7da544fadebd61384338f1a86695cef6b80e06af2f0d6d052eb3873770626e2342d5c891bcecb120d36354c58be59d4829cc1ded8e1f9c96f681085b227fb1ca24b3672d1a8a398f306e11e223ccb28de6aa802209ca8d3323d26ee32bc800d8509b2a4db1345b81e50187e69c16e657d76cd8676af515a6ca65fa0a5986f626740df7da44b51b4d9e6a181fbc745035a454fafe94a2021076702a69a2574a2eac8d4634e8e5ab02b7661f060dcde99664518f929f5dfeff301a73dd23547b51dc41020523a7fdb905018a55116becfe2eb4b5de94bd32a0fe903a1e9145e2c39c80689ba4476da2d978938285cc5004bbbc9a2642840b58f7c6e0a9307bbcf7bed212bf0db2fcaee36dd78663b66c2c1191e2757a51ba0b42fbc9a3eab4e900dd896530aa93cd242df821468263c433af070bab3ce07081437dbbaacea8899b3417eff0c3938f5795ec0326d8a40dc337cafbe8f14acd411b89581b15e1f50ecc25ff09935ff75a7e3c11f808c09f2c9e61d9ceb714bbfd5fe3765414f3c22f1ca042568b367e2c2c66ec8e4fc33e211cc4e7ebea0b9066f431f18d5a1cf103f02a8bc4495ad39ed65a9b696c011032966d0d4b59fa29cfea5f0e09d833e97af6291d394f330b4947e85b71bafe5ea87c +SHAKE-256: 8a6462552f57ba125fdaa54602b4e6633f469c81cdc05919e6db3da791ece7dc295676bc8c031dd2d205c8e949f92bd7898ea26a6e67563dd8718d5f2cd5e3d571d2781fed1af260df3ca99b25a6314328c833961dd41b8075a793d78aab1edc2754881062ac93b7df1b171b74795879e2080282b46b11c07273f7fe03df6157dc676a72b43d6cedba6476fb0ec7c3e071e35c662d43eb0d792a276941a1a049611977cbe77e3224d81f711d4106b3ce66255b73563f86b97ce8b535dc4f99d1a9f13987bfda1404170546ca1219616bbd54898a8f359c765870c3d78e605a27b4a8a216e03e5aabe2eaf629a7b66082e2ec07f7846352a30bd8ca5c3c0ac43e477c8fbe5415746939d41adcf361f03fd1b006429fec42a24598b7575414c9c407e2ca326e32fbe6b703e086ea5870c5fbb794202c4a8d000f928de4e42a8acd69916b86e5dfa95e74651275a1ffcfb20ae93b8e40d8b7705f99fded92ad25dc4cc848ef40dc82395c654bf8fe7b4f1ed70f4a828186a0b228741b357d1c72dac45b2073a5ce58fb7247012f60fab823ea4a3fb44d22052a384da777c14a437777e136fae7d2ec3c0857d53a4f1ab1ac04756fc3f8ca1b372c4d062b2a0eb36a07d7ce5c22fa53da8beb4d3eab8b2af1fe1954919e9b50739d055ab52af7bb9b59914a33d7db9ab28c3fa11e0ebf09e9545ea63877651ab9c7bda0bc040aaa66 + +Input: ff68813224de5bf57ab7adfb9d7bf349a2ffc4694b169a0b14280ab400b9d7882195a61f5dd42dcbf95c7fd238cd0867325f3c51ecf0b30e14c5826fd5175c661f99e8c3fd31cbd253d165ae37bba3346e1f2cd8547dfa93a0d68eb87db41169a40e0d5471f90a65f71933e556eaead5d85935efc32e133c640b666d4f6db028aaa1b3025476d13c8c2cc7e905b9bce6f052506273833af1efc89b792b812828aecea2e563f7cf6c29edbfc498e47aee745a8aef2f2871b1742d807895f3a6df86df1ea25e0bb018bd969d731d23c2c5c9b9b751970e36e62101a952db5f631da4d52a7d0b5f540e32361300974a2fb71a6adf1e9f8b402643d3b4d7fec6abe8fe4fde18c419f6eb4156474adf3cd3219ace00fe5acb23bf8795382dd7c4f800d0e41b99f3f5e6abe8e35b794249e4fd34e03f2368d9f098fe2bf92334d6cff0d785ebfe0f8e217079f04bd69d889046f7385ba609a0428e988e1e6ea72acb3f0197bd376562682b69f2592a502c6947a148b8e7cdd1a2d2a6a787cbaecee097148142a7275372985cb7611605544ec3a127e3f471be77abb9c1ee5a1e35a4e433da91f2922187ace997a664b7a1fae99a1c1fcc4c4587017044bfbff38264 +SHA3-256: 348111b988064d39d8393cfa6bf5a9691a78d76c7f6e3d1210f33da4606dd33b +SHA3-512: d4bc58e9aeb2df4c61ea6cab58c3afa8b78c55d822522c89d42c65fadf71eb4e5c02d5a74f5660acae0ef6ae893d0afdc0d46b9304e1e40253312eb642ff98c5 +SHAKE-128: 6394c24043e6127ca844f7d70f4966027878f615baa125beafc3d3a7afe93a6f9951b74358d9961cdb765fe6fe3ca37cda56dad0db789e718a161ec0295f43334405cd9771e93d1f8f9b5d781efa00e97b62bd2b56847644a6b4a187bbbcbf0eebff4d8c7b42f42310a2290374b82c4e3c3f631a93ae516efd94c957f9173092319ee912df99dbed55a9246e0e6490eea008ac96f95e2936b311219bfa285f8e8d5aca2e9e64c70c1e5ef7ac6313a02cd9ad1c2dd0ee0de333827d2220009ed7ac1502a1d6c03daf66a36fe4e280f949a4a8f7542843a9a5b15f32d55eb715c0388a80d73b10e88b376fee0e0ca0d0e3d323818bc755a11e7bd031be78361ba0031814ae02177add644f3d27c7281e38ea497b16ab99a4e4500787d1cba55d530893c4aeade98f52c7d66ceb20543313b4fac9249c8be1057e640a84df9a718cea034aef725cec062391fb72dab5f382e32dde8421259346f6393921d2b7ace108428fc34c69fc0495b6d7de233fcf8284bd6b5a16991a7faa93f2bb8a5a20e82a16203b5d3a906c12363f11e52354a4e83db9346daca7373361824735677ebf01bcf8f9e0e2354ecfcedb631f6f41f80aa8875f550d7142d5698ffdb20238e1a73f6584a38d443360e5b4f8baf570cfc2a0242255998090f736d3b2035574f8d09e8a4fdc7235bde513396bda0a28fd1bd8c73953485fc66d6c99e1a8421791 +SHAKE-256: 0131a264608f1e1be72c2e9c3c88d3b8857a04d6cafcea749998be7b597890f779a9a68c994ec04ef97280dee0e0267314b572cf75bb8f041e9695bf233fa4533e66a590edac1e44c280c4e249b7a5582443a0b8080c6ee136f7e0850e8e18449aeb81879b5f5df2db9634400687719b3cc92aecb61e58ab2718f048a043680b1b135fd0bdbaf15ae24d1d2fc94c40848b32faeb42da803484505e80980ca77e5268a74ff18d2e4fbbbc8c3c8081396983d8ca03df66fc37719ef54aa17aee3429dab07f815cbac81ed38cc7982d90cee75c15fc01b19144d420079b2d37242621263f2870a18b792f38bbbe80534f9e7348a81881f6f0b32b3f7b7f092f028fb0105b87a6d61ad0097e6968fe6e7385df1c42c24a47cfc0c863b819908504b70cdbd3529603727302bcbd68685a1f5d6ce1c33d35bb72982aeb853dcc1c134ffe81de92ca956349cd0702646dc6001190b6f970edb8091837c4171e609df2d6f8174be054271001dd06f332a9f8f5d0eac4c70ff878300d7587f2b61ea3cc6f0a4d0dba3e7113424829ae7d1f89a28ddf81549a3a4586b37a721d6295498eb8512b84de6cc13bc175f0a7d894f4f337e23edf71365370d8312bcd3162991263f6584161ccac70c4dbd3e84f03609a7a82018eb8f2a922e33cbfef8bfda563d392e6609c6982fafddae6be81f701188789a12d5bb4abd638a49a327a660985cd + +Input: 468b8fbc5ac0237f5de28a0af810e401fdae51efda3c31b54150ceb50613d783d8ad76ae3c466da04f84c02658a69e70b198a46b5534c118e51662db4ee1ab17fed6c1b15bdb8cbfa0f0b7125c35d2d14df3edc935ab49a716573b36993304e95712cf2bb7c6eaf7c14ce36269a9c9e81b4e6915bfa214d51416c8a2241c37d03f34ad17a3ceae51fd60fd902bd1be24a472923daa6676c89b1539424c4623bcb89a5950c645f88c19b2591fa2538ffe366ee6434080fb1e00ad33eb4923d75cdd9a666c91fd1c46beecc438d25ae295dc567ff8297dda94f7c5045f13cfdf1aade9ac51b0dc9416f904ad2a15501e0a85b4f6c93f97c96d1743bb8461eff4a5cd7f90fc4f4180672f57e54afd70c9dbe53d6f339426fa4561e60908ef9ae4aa54c6d29905585bfe0d225bb881909ed9cb3c901d0f66eb7da6b80148cfd38feda9e802f92c2bb3b30fd88024d6f8396e8606e83101634a46291607b7a0d611e2d255bcaea1bd44cf42f0877e04e187c9f8de798d9b3cd1b7757856ea99ebbfb89e65b32f8dbbd86d18ecd3a7cdd20ff9883c72c60ee298732d0ba752502865687e77879cd5202aef6e30ce722564724895dcfe6196a01408e727cdbdc9db956f +SHA3-256: 633e61e6b5472eb51ce3d034c2b0b14b05cdfd9ba4bfaefddba1d11a495126d9 +SHA3-512: b1bc7a489b407991ed622219995348f9d272439f9ca68e9e5b789f1a63efcc34e4cf312c2cd683a728f9891309dcb4989c042643c484f22139787215eb89e6f2 +SHAKE-128: fd0e96a07a88869855a1ab7751f3f1ea90e7e4a629ffa81ccd6d0101279423ee28449b59deb6fc0bb69111bda90485bbf6d801c257c9989f9265dd32205185439e52b7be436825315ad4ac2e196569b89859acb2c2fb8aac3c61a4aae5c0f4a935e8bb9785f2c4e9690185e4b71d1c62fc4c426ad0ba6912038c521980103acf514cdd72505eedfdff52b8821738eddb29d9063d0a247d71aad0a1d681a5874de41654198950c00ef4af7538f4373e74fcc958988306b0f143aacd8e99bcc60152c5136625387fe5223c594d213959ff9154b3c443993d9d5a11b8b46657f1170c31c883e01ebe6b35dc367c516b6c4040c8be2c1ea3618eaec5fd818fce3f0a9ddbdb3d6deeed719b91c087ea6e4dcee20742f0fc0ddf9fcc556b20773e82f86ca0531eddeb0c2dfb6d63e293ebfa8f678c421b5322f64f101a91ded899836ce7be5956c08d058b0906beac8e9117b6dcf84cf9afd53e6e16436022bfd8e60bc2d79569ee2fd7afcf69afcde7a6ab42d4c87ea7a403443a3f9e4cfc4fb5fa11346a612da288d152091c94789b06254fc86c3577c45c4bfc85315a00fe03e36afc564fd1888a2265121f856cd8460fca9eabc58395425a106c4c9dea5ca967e6a5af0f081c90558be7534979f50abb52ac5b7643d67e3dbf603ac5cbec38162318d147ce8d88e3e0ca6157f94d2f3a93ae1676e1d2255a53ef7de49ea885683b +SHAKE-256: 45784c867676350f8e3a670fe301d265b7ac811dfb61452b3b73d3792df48b9e5b0c1988690c1d43099baeb739988fcf40b60759d1dbefbc29bc1c03f641d0d82e914627aa6063d0ed11cb91fa6b1834dc66db50062d67e06df0df5efdc770687af22731f3bace387f831f96b8066afcb10a8b51420cb8da48dacd25c2fcab37ea10322b4cabaeb53bd8e8d5cee7d802dba1fc32ad01a955cbed57159d3aff0ce58bfdd41ebc8727a630a158dc261820d21470a43f3baa67e6728134f02e7b0e60bd75f7f1ee0917704658163c2e50fca94f5de7781d13c6e7af0a56e79e83e8a50fa17017c67a463d9035f1275166033c6d478247a755ad2e2d4bb89fb7be9f38b3cafefe85873e9ad7bbdf5ec800ae1fb5820a3dbf95112dd5adcf54ebb26e6f6b374cd8be7c0d9ab23084ea2d9e5f269bd3afc7f1344b329f95daf841d7633f798c0a330b7031c7a69bfd97a9285ca2accf3549ec1b5769bb968b7d8bf785292441fcab4ef3ffb493d0219cb7f212df125aacb978ed7311dace3792cd74fa96bf95e97e411645181a600bed008e4fb268fb4a2d28356ff11561dfe6d38f1a5f9611d7882a0bfdab091c83c6b66ca6a8f08da253fbe60dad2c72f31c171d090338df27e9c688f5ed5697cae800694aa0bb9462bb923dede6a80c458560e0217dc70afb37ae9f8f56349da900ae531cdc6b82cdb1a7d923e6e4b8c4016c6b1a + +Input: 0f52bda5ec59345973e39247ad2ff5c15b81c91016aea5db9f50a81e38e7bb8f404aeeb5bb2cf470d048dbf6eb27a30a115ba3dabd2d37fa64288501f5c1c6ed2b8e9841e59dad2197e9b31381fa133c79566b3251686b5be5c513aa0f1ce9689498574cd9aff42e66c8e9f3d9e127676c2d8eed4541312eac1a83026a107329d0befa3510d9bf2dfe498cbd4f1070bace8777c67cc141428580ce167532e6c199abd44f5d6d4abded7374a9da9ad962e96651469f12ee19c660c3e044ccf1bf2786b0a85420e6e43cb6addc6e603ebd41683136dba08ef4aec7467943d5e348990cf2572c0ebeb1cefd3b8490800c38d55a7ff1ae2359410a5f2c613816844c26e1f84de3e6d823fe4c58ed0cea50c6e0c21623fd31336bae5e0cf53b7d4819c3e4ca1a2bc31bc42372db7eab08aebd42be2e1731c8f9eae28374746681ff1f2e5bdedffe0f356099b5306a7e6d562da9b678ff7dec4731710e691147a6960f476b5313d1e9041d574015cf80e0af0946a552d0cb9d4472d7bb2c353df4da0b37aff9069e38ef3080adae82ae62372090478c26a02e08f0180d359d361cafcb834b620d7b31c141bac4c95c630787c0e3b951b1b14351a068efd60f2279c54a13 +SHA3-256: 80015db0f4b39ce678af8349f337a1e9e25424998dcc9a3a0f07cf8b857f0646 +SHA3-512: deb57dc06f8c0275eb88c0ef221fc01502b397daf89be24c1accc61ea3ac4275ebf2b1e66e8981b30a031a8b7d16ddd5d2a8a443541304a28be85540213fe348 +SHAKE-128: 7d2269c6f98ed440570db0be876e1252a59a6b63c4324329277aa3e1744c288d107ab0c0521dd7ae2a6b820d12618d67f3cb38cd75ab49723831aa094229880cda1d107020f397cdb4fb73e3b5c246fe66d73b5e8e3b94fb7f5e1dc1c663a247bdcc6c75cabe067105c1b9b93effa4b8821151a50081df466ecbaef31479cc7f3364c9f8528caebb8ac700a7a6d7d6646e24b59fd7bff83608c96b93c8ad4d3ca50889aa5eed9fb69981403c26acf527176aaeb5c4f3afbebed3aee659d1f68e9e2368e18dd19c3e24042b3a118fd81c465357f102d06fb00f62d62a10b8654c35e6fb9980e4308c0cef1cac378c4b9fd9ba77e3f6f6ff613e1f159436935b9b344cfa8f32dc05776682503618f7d303a115e923528d61839d34a715bbf5b76410d0dd1d158d374dd40423d19be908c1d5ce6472be01bc4a1194b7c1df964d02fd1b0e2a079b8faad0d6ca44240c3f9ef40898f5096fe9bbd77b322a3a61757a6d9d1e8f674db6d5889a358e6625bf2082069f73afd4e007d9a75c794a8493ed0c474fae298e885de45ba85adfd13553b9444623c9a85cb3a3d7d4c55f5d53517408df63b469816d3f40541eb5f64b4d2410fdf34b73ca9c5a0cb8d781c2583532a042cb8cb423a1bf3bd2a1023fe19d622aa1e0a8f072d57ab313ec9a5ae0fa0f2ef506b1142687894b702457ad8d11afdb7717919e1b39a08d86c2fe57494e +SHAKE-256: 742db097c802137221f46888528642b9da80368a6982122fc05c7e61592ad1ad00e2354bd7d723b60751a1bb3168f8f93540568951a08eba6d8c04929b1abbfc767597cd4ad684141c2e0174e14906294c9c60cdd9078041de790c37ee6d0ae2e18f603896d0149ce75f18d543016f19421d254b4530e9ca7cb3d3bf44590d33793771d5c395e87a32a13a78a56351ec218ae611938d2e2e550aeef2e6b4a4bbda6e6aa8b6ef3693d84b92088485b231bf443adbcbe8025adfdb6519b62541bb247cc33b73b9a5339cc6d0c2295b7def59a21ede3aee7b3da889f1cb1e1db6e993fdf6adfdd81d3fb846b83a4ce58c3ee539003c31c42c85ac53fcda3e4c1f8cdf3c296ab2ec143feceab1bb9e7057e73b95258798d40510d40d9841832ba02319e9080d5f3ab24841f646538eaa115862b319ad6b55b1c99abc0d25f012b5f499461c3754d06d13f4ec59e43544b40654a4eaf643829ed0eafec95e5a202f5d8b0b301bcf9b92657283fc9133e0cf3b9b1b7541b049776317c514b543613ded0e159770da3611167a0b7821e20589a95a0fa1bf3a5ee983a23ca03348cd686ec341754932ff31fd3c9c52f8fd0524e3cd2c4fcb17267ea18b66cc8a1431895cfc7f5ed6fb5c52e48a5dcb8ed45811d2cc1095f6f9bcc5893cd47bf587a2c86e11b6d4cf6c448543e355698fd12971ea148e28c3ede3e598dfeceebf5b7f49b9 + +Input: 6ac8be4cc9f0ba7223f8348fb9292b0a08900d8de0446191b2bcceac3ae530a1ac7013e558f61dc65e879ba97434874d6633087bc13b42062f932469ff98942fbe8c3f133624eaa8a94833033d6c68a0b163f9ad95b060a4d67bd4e4b1331138ea605ceb6d2781041845af4b4f795c057b905b8d1fcca232a8b615fad972352b281e6c3c2b3dc9be6d45e0321e0d0e77c75597766de5172ac180e334fd6bb61a59589f07e61fbd26a297849e985426c8a1b118ffc7c9d7bdfed57642cbc7dba1b4998d4cdb9aeba2a4c06d136726e36d4a74a3d4488b3cbf246b6bf1a55a0d3725aca4d1f98c939f8f355c0cc4356bf8a347884d5290689b3dd8da95a629f860271b1d41e8e9c0a6f04ae3102d56058e2bdeaaa0607960b2ec3f8af58cef56d7522df4d6c45ddd17f39e8349de0decd83bcfb55435e6a479e1a937e7b941be2c54854f8c1a0ca271005dd5bf284db4383d43543c12998190a2eec6d4386ab8ac8ab57db96ea3332cc4b2afd1e8d31016d47933ea2f690921d8475759c1a7c15f74c945f50d53cbe74b61ac7cc6909245802c7710591c475e2fde02a4923ba51f81f3170e57c273e91f279853febfe6e37c2aad643ebf9fabae00ad6be2dea23bcf4b +SHA3-256: f51935d013780f423a687d98271999ce3c44850127fdcdcd3181ef729828f4d7 +SHA3-512: 98d002c797ee5bc35a5867dfed873ceb1950e0f712ee932d7c0dd17494e2ac8402bd5a39f48bd610ad0d2ce53498b52f53347da870367746c4ce70a66bd22ca7 +SHAKE-128: 470bad7c154059faefd5b6373baa71fea7779975e30a6f84164369785d65cb5241db3adb97fd1f74cbbf3b602e98baacb75cc34e6c60d02c73ae1ffb861363f71a084e50696c1f4a68e768c66a7b560dbee500d5cc9757f126be83a40c215af182550a1f93bb33a9e32f6fd5cf4df6c75e5faa185491be869cf232dc643e0869eb40ebb79cd721d4e429ee4985d91eb4d90ce2ce89326d26f6e0f892540fd8b3811f28c5327e9e7a097a32c91d0aa6b4400b17468c17d72eb44e72fdfbb52307c25b02c1ca6de77e2e3449226b63443a13695aa55588fc39bba98545e75c7ec4f6b51c74a4bb5eccf1f01f6c2ec40731a651b30e15c740f7d18cc26cddccb56bf96f08b614d16f15fff826de9f45dca568d14290ec9c5f60d829ec7852b6e899109b48a0c50ce43353dbc11d82d6c4e254990eea3e7e6cff5f6b58dd41c45438d6f8ed929bc503820a87afddfbc6580250ca47ddd1a410f35aa671c52237a790d3adc0f612e1f8e4c4f17d93800289bee58dafffbefe4bd5cca13ab8581163ea08e115a665c63ce65aec9843d64d7c5b2afbb802055b80fa16c2f4bb4726f91a1c09f974838e6dab3b5af07c53805dcbfa78a9b971e12692b93227eca01645f50768e00b6381f81577e341b4e21ef41709302736e399ca7027430c7384984dc68c9531aeefc267e25ad3779c2091a35fd1cc52f310ced71434bfb81544077af1 +SHAKE-256: b1dfc6b0e7f81ceda9bd58f3b75ea9b4946dc86a7fbd07e7a13ecb9bb104e34574f6cb3853c4a0653ae88095cab5f5f3f7bef8a103f690c16e9b62b8188b2e7d64c72bf5e6f30ea5867f722d395fb2dbf34c09dd3df0640529d9ffffd089479f9765b9c40fbebf6ff27c95cfa37ef8be0b24a57d8a6370eef95710d89e88e7b5e6bb905c0ee02b0cff8d9c7d91ace6daf38fb9776a043ac7979346de7a9548011db12e7985f0bdc9f1875a6fe05ca0a8db692ead9288bfd71d161221017d3ac4a29804ebd68cf11160bebbde892c2bd6030261f2caaa35ea3aea4c18722668b516ce1bdb0ba9d9d727ce8a1254af7f80c247e3e40da5fa4a10fa69f1382524ab4e84a43605735e8acca64420bf6bf1e1dbe0f813d3d3cb914e1e396cf0afd433cd6ea056ef772e0acbfb407c3ce0efcd092fa4e65abc83d04fc46754b2f4ed81396a25e8ba2816a8553221d48f10c0c5dee6b6ed46c07ef118403880f3771603f52c49130bed02f61f06e277ff2fc2b0cde0f6a1fc217a464ad4a3506bed074a2331149e645252ede565d65150e1fe10e47ce63a08d175881e2b5cbf6439cd02acb209be15615087cafea57e5bf52e80be96fdbf1a30c232d68826acda45b75278d0226471fde1ab0dd61abe93ba20aa050ed919bf9977b0997ce40322eb02ab8c9cfaf4f876842886713f461ff6e2008f5d8ce95c40172a177c5c87eb91bcc7 + +Input: e468c626abb0002058871b228b678f1519d032ed77afdca657c579d58099e8abce35fc6576d8adf69040fa6007ddcb7b947deff1c0c6f83bea834647c682dc129c05620802e17b5d0d68febf5ff47fbb2f92c7ec8589f1a40e967855b57bdfdf16f4be402ad404025688ac86a90ec497670491b7430eb008900f58d4237f6c38f99943c25af57c1c7df1645c3eacb2508ab374b268a17bf7a20e8c857177086b96766201612b3c68e415a09882997ec7dfed968ca644fb8765766514cd8366ec464013eb3dacbb62ec0b920b61c27b1dece0aa277622ba34f2e7c24d603213ba2bd831b8bab8afb26c9a7193a7bd194f0a0488e60056835b440024714c18d60328df29aaf5c9f28783c9d7ebf12e86c942e2079e69b84ed6be99969d0c5b13546ba73eef1bfbf00b0f6a7c847043e992b4d8fffb83859a4b4ed9485de068557545300c095826fe30a280c9575dbeb92668c90d7e8be7715abe9ef1a2e6ece8b526be6afc9c7eac98b5f52e1fae70ec9bd2cc026ed040b31dd7ad675ea670cd3fdda43927bded41e4312382f08d2f845ab8e1f1242892e3268dc48c0741150628ccdc22b201f523f46ae579b23ca845235eb5c5848621b597387c90ded7266851bda30a +SHA3-256: d5b5046879c90cdb052aea7369912f75b67c8c2cdd7d6195485551fae67bf48f +SHA3-512: f4d7c5eb8016bf36cf2c239c735d133c1c900d7456a15c75206097c869a2c37cd25468fba909bdcc5ae7a6869b75ef7a4eb0d5cac978547576bd8fa5b9f1bdff +SHAKE-128: afe3b36802cf8a75d83f89a05dc1fb268c4f767da17e5a223859d91f3a0be30dc425b469b23e001a2f2531c7c767e4075c33a19cfe128e2ca1849cfe5dc35b16573e7f416a53291dd7da4858b5e67a219f5ba148fb13b32e81a61f6d323810e7af353e74b430da60b388bb05ffac59a7e4d0b62585c196e7ec3285549a9235f27cc2c310e493b9572bd520d976f05c80e85e485523f6dd9f005d59cc547729e23c14ea41eccd0fd4d98313b4b51d42c71e759e6f1f5349e77d97eb2e802eacdf9d0bc8fd684b2ec1bf162f320f46fad3cd98b7d59af61af90921a41956ea63faacc2045e58cf6b296d5627c43063fe9300aad29e2f9a1479dc2f73b7fad9b3b9e952fb19e04cc8d88c51bb71bc0b5d9dca52f0c3d5579b91df051c9115e1c6503a10e4d8dfce74fad92567d950723a636af4883b27f275c18610c5c096f8666e8de9121177e222eddebd8c4869e353b0900dc015075f58449ac89d9577fb9fbb31677b017a9a0e9ba87043f444aecaaeea4cbea37d4c7a722ccce6b7aae41f4e5c617a49b2ebf58877d41d452d7732ced4f33ec3eb70ffde826ffe3b2755e23ac43026a1fbdadcd434fc151bf23e8ffe7fc146ff8e0f4a1cbfbbb9ca85f9bada6784f8f016088acd3d2b77c1dec04c2abb5c12f62db95d04c70f8828d041e4ab62e3bc1a536321bce3643c46c852922f5285f61d82a35f92c75926d21c0a852e +SHAKE-256: 500d6e374bdcb9f850189e5b877f7bd72a0e24546923c9e7683a45f29940fa0a23a4b7b7e0ddf1e5174cb41f1f76e427caecc37da78d07bfeefa70da7a91a75e246810c165fb9b06de8e612793a8838f7f1d591c4b17533e846891d107cafd4b6f7ea3231d7f41e09f5733af146d27fb7e9b6a818a1c33b41d8112269bf04dc610427644f13d74fdca39223132b166c8101ab78e1019725be8a1cf5423fc5d3e1e73d6da809c9cdbe5ec31137e47dfa9324889d48fa885d1007eca4aebb0dab2eb5afd03bd01bc8ce0a3a27076ee366c3d56c6e52faa9c597d490d5b8086142d26da66dbfbaa327b585afe378536fcfe1ad7efe85018c8cbd0b3252057d39099faf979070a11f12e1a64b4eef61735b66be4bd3365b14ad8f44b2f06ab8de9bfa47de972bd629b584879708b186bc90a246236fa00707afe3cd2170a9fb899c9775516cd2fb9b64d3184240642e2fa4c8b0b7b3cbcc4233bee37a96dbae228a4f472ec36b9ec1d52166e8cb63251e8f97d3183940c033279e88e9625661584908b81699329c9c8e0df8e79e6633c54100baa6f169a1d77fd3d81c30f39aae60f3366ddd8ac9520f41121e7f652d125736d407488278850561517148d2bc6adef0f51158200ec7945d95e4349e2e7d5ad7e15bbab9c7ff729e4b108ba7b7c6a50df53aecfaea3111be12f80ee6ac559b9197c91c92c41dae1018c024a3366f353 + +Input: 052878741c9792dd4a3a3d70585bfaa39c50cf0a5b6a0b6ea8b2418a626b3a2577ecb35bb60548bafc34d9c6f73e29509f4056c5ee0dcda369368def73b783fef9e0652c0659955fccd98d8e85a77a73770f2628aa5bceae000e859b6329e5e60becbfa5062613ed5085bcca86a27b5ca057b09c89fa0d46e448e1ec95099a3627ac1ce21dc23206ee2aedc08b7225ccd35652e2ff78633d0a675e07f9fac333beb9dcf6971cd5286728f29b1c16f3e834309227a8b292db144f6df525b8ceca57d02eec80e805e8f801d5071503bf8475dcbf42b419f18f42fc2ba54a028f5415fdc56d7cc2be1d37e46b6d562c5672c40d529826f7d9b9c47d132e75ff0d4ada99cb08a532dd50bb900253bcf13b74ba5901ce61e685099e2b4983c639d9ea830be05555001c9c9a2e0558f0596c3f1bb47a3653171d41fb7cff088491fbc71d5a2fe659bb791be5f432b075b4d23887e045541fba3914cb4dd9c16bc2a452896d30e07841d487b09daacfd1ef84a44b51e17d6c2ef2e66ba2fa3134d76d93f42e9ac4049693d9b507a5aabf08be27939a67d373d7f38651bf6187de0e63cc1eb0605f363f380f3ec6fbc1dc063c2cd4d39e1f2c1d510e416b52a128259babf6ec601f +SHA3-256: 8a86803345ff71baa2898b7ec8ae970fd287de6ad70e5c82f793d3d7515d1963 +SHA3-512: 86d28f50241437b73f009e0df6f3ab85c985b562def3bb6590c3dff88ec2d8bc614b280eaace69dcfab15b1966735429cb555e6d0e613034d6509f8b18c68637 +SHAKE-128: d976b96fb0cc072fe5b01e7db382063cb5f2df303330d59c272efa45d024e8217b529384c7bc7e573bb5f8f09df40b3ff4544d8b12a69990e1ce5bc19b559f466b33fb62efb5197dca06a58186885065600f191d0f8b6fce6d91f39502ccf9911b2020150db96ec20976956544ceab630b8092feb7974de5fcce1e821962b6fda4993bdfb05300d7b123e5ad2d4b99ee650ed5b017368fbe64429e47892bfe148d1d4452cc91c774d0b1ac2280e16cb6c1264bd380cc6dc1396ab1c02b2e98be685c8a201a869cdd927bbd8b7897208374f5d4202fb701a05f9c16b3ba54e5670fcf664149243a2c4aea369456a9b919ff0749014bf8301570bfa715979a0fdfd6d075d15af69f71157a835c898737a5fde47368abea2a58c28436cb59a520f85d08a419ff4db58506f8bd219330c671cbfa833f99bcfc294e8fc8d4b30c4de71779adb66215cf6b15880e08c2a037e4338a2ffb29cbc93222e1bc810531040987df13d0b2411df31c62e682dd82f72a1b43d546eceea8e9c7b4932b277117f74ba610e2d30a3faca7d4e9c822979407f829a3bad622b6e96c9d00a9e826972112f838a4890def023c2651537539e95495b5a5583d584c3cae8e67935f7499177fa6b48cd2ca77f90bd01797dfef190ed86a132c6536b1ce8becc88cd8b1fa8889532fd223b2b7ef4f975c26902c4018f10b2e386d21da96df065a06b15ce7a1 +SHAKE-256: d5f7a76cb4a5ca5993275efccbb1309fbd2e54282fd5af683503493a112131e38d41b6425fbd0e6c8dd7f061e4db7f7eafde5e2661e7b72f6bceff59dc6486995d020308c264585a13b2777689429a25d83064c9279e21abab43c58012498441121db738bcd7a6e065ddb87b5787cf29900500cebb6914fc3c099c69dfdbe2d7874dbd447672087f4d78a84e1c16c713173ac2fb47fdfff1ddbe466fe9d2fdf483f609347aef9c94ad335233045ba6aeb2f434e1218164d9873531ba5d5ad8e4558da26c3e58625e3b12842b3311eec20e635c9a15fb470ccb45b5b080022a980a9fff64960b9bddd4ee849bab07bfa0142d5d7d89a448420255b42fe3517988b290b5a63073a2fb57fd0791e59ddbfb4a63d24adba2dfcf01a3ef3fbc53c0f95f127ac221d50f8918ba8e1a7e6c042fe89fe958b3f693b61f43e0f6f6b8f3a1c224942f133d02783091ae8249e57c6d0ad253bfd9c8cafefedc45990474ca9bb2249baa0ca1f3beb805464962694293cb8b905f0aff13390831078333d33ff5cf980d9b184c2de7c1b3e4cbd0daad29e564385ff66a17d9bfcfe71b1a9a44c7d8800d49552135fbc7d24fe01ad59bf4714230e66ed87dc0366db4d77c177d7a58b320baac4ff94f6ee183126c691e6ad7afc4f21e1982316510e7688a0ef07798c0e67cc27da5f5706d569c6f5f2434574c71e7a2ff6aa7e41f85444a06cb4e + +Input: 588b18d22a0948d96a5f947d33f1999d970c558a219755d9de014379724c654f2054d55be3f8136ce1e7901fd35eb5a0ca7b85960fd0ebb3eac2924b02affa731ae6ecd2310b70eb0d1b49414373d086adb330d172513817998c2db2e187c08b582553b10505e3c75fe93b8fe4cbeaae9015d099ba6971e640139d87a154496f24dd2bf6c0d5afbbde4b60535147b35392aafd0f0e446f72600aa2953cd400e46e0414194007d585298382d9cb88d97abe5e538506181830356c0007b5bfff0ac4094c7a95a6b939f833bec3963b4d37da40378d35b2303deae5b6cf8320af0d62690dc6fffe7c8308aca9f5a5365dee5ed9b8fd5058c141e657cdb59c1330263629e896cdba9b82bdc559583ab1b3fa2155e4093d28df570374024a9361e929e2cb1b1572cdb8a2c884041f02cb9b266fca72ab7a4efedb548794cb13ee6c5a20a7bd9bdb14b8c2f7b9eede4078f42478346649b1ccd317f8d6666e2fa8d3aa8eaedfc0d5fea2dbc9c7b0d14b989f211b955418da9ad74c7b6918d7491005a618f86a9e8e90e438573391766faa3c88a6b1f5dd57e958e33edb31b53b836d75cba64b0aa16f2f75501452e296952519b83e0c1971a4adf291228aabf2ec818cd4281be5aa +SHA3-256: fb7b91941328b746ca65f49cf1a5b15ae9e2044c8c0a92254e43ac24c96a8772 +SHA3-512: eb3d3fce17ba663fab1681635f964032e2a41609dbee234df4e0eb8fabeae981ecaaf9c5684d4e3d0ca075a0a4dee849ea6828901d5ca39d8275808c71a623d8 +SHAKE-128: 8451689339f873b86d8a27e3e56323ff0b313f6342c15afd55ff9593d1131d5f4f8c192bf426c9fe754ad1b8deb9fdfdae9241c8097f65abe9876df0ebc07a3877cc4265ab7aa641f98fe49102626347d40e35db8a531d8687433f83ffbe85e8f7fb33e098e88e18bd1fbc61e82641b74b7cc8a7b27ae1b1cac28c3c2e70299d7545a6c9aced78783809bdb10272accb8e706601a4cc0307050591ef20189fc7fe5888f575d10668975115d53cb1b157601dc4724fd31810758af8863341a4bdf2bdc5a9f663c07710b71e7ac3f588bc7ea342fed331f87462da288ccd1b5f7d2c7213c8094af58fe7f2e03c601eb7ecb1252ae39b24b376597217a8aad6124d1bdf385d6b34201a62f6902ab4b695819444aa38b80b31b50862bf02c72e57cfcc73e179f75ca3637ac4dc18ea5cfedd0aad7e017c5d439949341a5b34519196fc3793afc505c17803016d03cd939a852c5fb2d4a5bd10238bfebfcbeff8e540e4e64aceaedce7251a41b5b08a5eeb85e539592bd5d5a7260dbde4a86ffef72102564ccee65cda58590ddad3f3a2d9e16046ae0591cfda8ff280b12f398d51a69db32e1b23ab356c748f3d9d02051990b0420cd49d79884afd46957dc2c404a64cc7b16c189c2f8c0f989762087edcab14bf00cb09faa1dbd03aa70d73e2975ebadcd64fce79d37931cfeccb66b52a81e968c91bb8a8f57af62e78f74bc3ec31 +SHAKE-256: 4546c8bf6a7146f38555999ae79ccb6735fbddff3d6fcf0272bb3e7c41d26baf96f1ffde9709813c9610372cbf40d7fc7d0617be61ef1579811ac1fadda1304d00ca30388e04a1dfeeb12d27fe05e503182420a84c36420b3d133270f3fdbc84535ebe8500a57dbb11070713b8f4adc63c04a4819155d4d4a8238d24a2d3cd5afb37b609c6105c21ad3abc6f798758573c3b728d9dfb2b2d8ae04f9a061a27c6db7080c389f1563eb9e1de028850b06d920fff426ba81b6ace384208556d896fe09a5152e6363ab91f47d3b4747b175f68a0d3d0b5eb4cfd589f8263d535e61d41e4a73bd8282faba90c4332fab362982bc3eb35ec8da0a6237d5d5fdd12d56ce58b445c465307c8011c34c4e39eb1e4a7622272bab7e0c541368a8c499493c69439a6126bc45c35a74db4be1ceb5cdf8a8486e4f7be2487c5d8c7b9044adcb788a7a434d3de5c98332273aa440ab698a01b59bfbcd9d476ad7d299c38a79975fc6fd867d454c65fadcc894fb31e31bcebe9e53b18e0b6b9f68138064cfdf2cb7dd89383628ec148557ad96da6994c23f7da0171855284dbb74dbcc35fbad615daf132e257b024d8b413eee89e954cdfa4cf171764a529cd7bbc618d143d9aa760d19c41382a169f776db783e68187bbd7b17ce1eeee3931312f6c77740e2c8d8877f07b254756bdd38bd278008034f652ccf8491c16c88fb6546ed9b996d789 + +Input: 2a356c464f2b73e17155a58472d9c72d3e9c3827247a708a04c61d231467594acdbd29db8646f3df025548bad45ed31c33e4138ece4fdc1df5e1b973b1c2e66bf9f5c8f7c851470a514b52c8c8f9e7f11eee03e7249783ef0e4e0ebff7119db94abc7f667843aecd14854aca39419a7d1676a85035fb1a5a83769143a9c2589ff1a6558427fd031585ce7deb0a6810e3a381dac5c8a4ec651bd5027365d5c1bf31b3fdc147dd3648dfd45cfd0d015217220f0a0e59787a9d57bc677fbe2204f5325918e55b2a92670ae2fff1a573b78d3396d28be544b4ae75a78ef9944f4565a788d63fb810887c24c1adc16fd6a5b50e3edcba4149f0e959f3cc54873e910fd8e49b7522aed9fc07ef06a171c780d6b19601ce3f1014995b8ba9f868f733a87f74bc148312b2741f89cb559772d3a6ddaf3d83d01ebbd2a06646c228105d44e0eea9398b907a54851eb626f78c0962ae5faee81dd75dbeda907a0ad25157f4186e0d05fefffb840ecd8214fff883e5d8a2bcb6e14d789b50c48bd37dad86922c0d6f5b21d563a9e99525b076010c5e52feef576732a414f5c11e3653c9df212dd2b359cdb1e7e5663bc67be88715ee5e7da6253b5aff1d9619a19f574d257e17c4a1075ba0 +SHA3-256: 2024a961aab0cf91adb92ba9d8926ab0cf953b1398336b3ac73fd337ec8e261a +SHA3-512: be0de68286aa9cf357ca3bc6d0e8479a512faf1ae14f858576be7b6bf6c619a922f47a68fbf61ec5d8021ca4ce28f08e433beaee1d9467dab6f6f3b48789bb15 +SHAKE-128: 7838792577c9b2a2f67d9d6be15bb7c136d13b5d7a0ee2472c394ebcd05c56f461b5f5e64c8af796086df97124255c8ca89d70da080d7e41e2a22ea883b6bb4857c5d377425cd447372e3276cae78537fd39628f4ea14a195434eeeb69f1d551d1bcb47e2ea0cde0b5765dfc421ca584b7e190abeeb564525695b144fcbf14f4b94972f7ae7036f128e46f7d8a6eedbc75b65f74de4b3ac70c16a5f565f7ae9d0ca8040a1db830580fe44bd37d8a5f62490a9dc1899a5013919cf57bbe18a9b43f18fa6260d5a2b6748e06d5104108f7a8f46ed1d33696bcff3ed1ea6498cdde4ca714021ba244c46f38c47564e9f34f42bcb7a9dfa6a3b4aad78c078942b5ddda196d42c13f5915d39aacbf682b60505f5d8f5e50d828a64f3a41e3e9ac1d0303aad6a49916d4f233ba0a9c81594dd62295252a14ce42703d18e2fcb6d86f2faa779e988ff5593d2d20d848287d932004d9cbd735b1a9b38f5e48ca970fa735451dbeb51c3084f427cb92b060b57aafa1118366a68278bf69bc5a178cd109a3ee51361fb309fcb21e825acade58cb9434631ea53d4e18c0882d4c7b9d36c0530291100259ee9cf86b99047eb9b793a55bd0ccf4aaffb62623ac1e66f775f43187a38f2630c181a324e9a6935654070fe2cfbf5b5f7eda238f7ab22c94d20b7ebc947263173a6725c9b322ac4448c466810d23a9326cfe0eb4d11071c327d108 +SHAKE-256: 16b3d2929093d3c744614a10e6497809e304dfc99fc5e8f8b4a76ef1795dd72664d6ee13db3efeee6b1cf5319b08e3dcc449157e8cce46ce5363b671b7c7b15681421e74c844bddf62af115435eb84eef836026c868d22c60b2c098714b47498f0a2d9c7fa9d18f521aba37288dc3521c1b6847f3680d79bae22052b069be765c05c8ebf7e32ea9c2a1268f96553037d7125bd98bb31e9fbf2f2ee32c642006661418812fc45167c3a66e9d0f47b6c338774792249663bbf0751e90371aa6c1b3b64c21d6f7bea5e84d611e3cbffdbad44f0d42a1d0655f736d4e9fe928642ab50f4f8e7a0b8e0d7ddda046d5c2ef638163a1c6e8792e4ad4b46b1a7a5c6353aae320339dbad56b15008882e67cccc52b130dadc07b344769e5bba8f00e408e39f34fb140943357892765b40fd3067623b135d622a75ae861f4f785718f7109b716a9d9f0750bcc1784c32def14ac857c297e1f9244fd82eca9730da297e9901b6cc0f033369012c53a431d41b87c3a1260fe6ad339396767a1a8effca8402b99d436ea6d7310ee04b5fadfb87475f99210577587a00853341e20dfbd6c53e78e9d39ee6f9776e7951151969f9f125d0a6ed91a5fd249c1a8a4dd183371c2bd81ce4a2fe95f8c5f37a20c8e25e24de9325ad531fde70e80607074afd3d12af0450defa40011dbe70e78f34aeabc2cd169281420fe4109ff72ef1073ed706ae54 + +Input: 388ab05d656084264bd2b47820184eb2a3f546a13335dec58c79c3d8b604abf6402b3c5d4d483d43f02637504e388d297085090b7f9e5d48515c54d7cda11fcd4ad5823d7a387c08debc38990d859ef0e879bcba73450aa54f45ac86093f5d998fff522395f3825dac12f3cfdbccf99f5dea304f7ab975b634b50d6dfdd51f7560d46005cf6bb735d35cb56776b06014e560131d8474e4184199770e514b4395e2a979cc9d51c832e9014a6cd467a5a49738521918b944a2cf95cd4e0b3ef6e98687c2c10a51eacb3ccee278b66a93b3208b2c8a73ef7b19fad8e454593804d9dbc27023e26bff8e7cf9cc8d85102a79d2da54ba7a1c51dcf8774ad77a6880247411b5446a0821050eb27f354da38a727c059c0d9e350e7cc604edd10e5335f98954b364fc41a752e7842e66d9e32991d4aedc2bf6b34b87fd914f726e0954ad8eabae101b866ecff885d6105b095a3dd5508db9cca7f7c688febf82a6f7ca9f340e237d47ab74303293f51e776f1328b0df5b660d5bc2e4cc78d70db73c80fe9fbc8cf656417ec6a4a702bcb42358f6af705bebd74f26c7d80abd90d022df7f10e66355cb2d5fb4b1bcdd3b15b9bf58eb49f3a9242bd7434b8966adf3545ece427c2b7859a1c1 +SHA3-256: 44a1bb69a67aeef6ca70ab777b18f0760d9f888381d6f54ee581afe4a3fdc087 +SHA3-512: dabd8f52ca31877f26414ca538443fe8c7d60822c068806485a5fbc46eaa351b04c017a20bbecf60a88af9c8de3139e836d1bb322b8a5868daa6e2c88e2cc0fb +SHAKE-128: 0e5b7f88db52a81fa6cbccd1d45e5170494efcf8f5ae136a12fc9dee14364fbe751804741cf6f7b6cd6c20cce8e5c15f4849a9c117e5b9a81b2b04d868b47b64d07cb3f1274c9b80a322eaa95828d5396c5b758cbd6f446911337b5ab9384abf8a29651ebd1de01a91a9acc11ecf32e86d6d864547afcbad7be937f5fca42b5696ae5ba6ec46bc97fb5941fa066055f5d72cb33a14b07e68be6c551f013324c8508b55a300944ecbc59633a1be655e35314a5759bfc663a82c1c7e543a2a3f89b5466bcca97f9bc00a6ebe0170c35e56dc3981a0dc8bca151c724f8db573c58b19ecf6c1b2ab8b0ec7bacf14f862b12df0a15940338e45bc2ac950144c232e2a763667d8dd8515c641f2306a3e0fd90bf1eee68fb7d166c40539fe64cf7e166083a33481b7306ab21bff9ca1cbb97e0ed7a51c77451187285e0ce4407b4dc01c76f5a08e95e1a946764e39e5ccefc1543c30a84cf93f82813c6ebf889bcf5819054b7a4be4c3104a448504683f80f1ab6ff6e1d01ec8e57652ae62bfdde7e3dfd4b71f840c0e25a6aba24d24cacd74dd92e06f79625c43d68aa2f05952e51a85496c5364c229eee0296b9a461cce9c4c18df65138ff639b3e58504d83cd7583655bdab578205424e6cf27f54136f02c5a9daee21097e04dfc9111a558999ca5a819abe461705be70a10def9e6246a365ef01b206751ea0297fc8fd7b8f9c81ed +SHAKE-256: c3fdab9ae16e2bd8057205208a91b2a62d0eb303ce6eb5be949a94357a2b31d4c048ef4c3a6f0f7a4ee8fe2606de1a3525caf1985ff343253928655c41606fe6aba604c2906f4a73ada8e64d0a325089569428df784c8e4a3e6885d24078acb12018fb26842697823350a003d9944c30c0a93f4c75ac3f7c097b01d5217cb08e2bf98ff928d744aaa3843d21a091be0d8e3353b3a397e166c2b575f4af8355c9dd8ffd20efc53841ca3866c9250a9ab58abdc24707f104d26463786c28b63d21c1d8fa371208b30bbc45a31ace2b3ee843f93f9f101bf25ba2a304615b1711e4504f582acc6178a12022b9502f6e7d625f363068ea57fb428eea84d2673e5e69a53c7d57fdec4aad8402888c33433e0437ededf20704e881a7ce9effc7b97aba2efad3ccd1ea8654ba2d2ab1d9382f966e2972862b3a8f8221cd51062e7b6b7b8a552954d3eadffffeb916a9bdbb1c7ffe5d8759158e358ef7af1666f4c0cb4162425c46d2b657217ef156ca87d82ef06361d19889c46ca3f01df997d9aa791c584ec26615b7ad0ee94059185f371afbebacfa2f682c680c6f0fd6dfe4b5132f6bb85bba0968fce37ecb99938e811eb54af9e671c9e335edac7051d8dae33aa3827f0763f231880ddf35a9fb05321c1788b31917ed7bf91abcdc03d39576916969c235e7e4112f4a75a7d55fc59f28352cbf9117d46754bb3b7da05cdb7810c8 + +Input: 426fc389980b3e9eb00a56347fce308335a170aa49ed46bba21b81e4f493bfe95bbc24343ea7fa6062657eee750cc62694ecea335a7ba5a9deb388f9560d84b51ed84668090dd1d95cc7795e04f0c3e69e5c2387447170fe42c36217ae1359fa5151965c50f15e79cd0dd4503d6ccd5153ba2459cfba4e9141ba4c972e1539c260e0b8bcfd5875dde0e61c6da5890d4ceef9d600be5cf7a3585421ff34a45ad1a5ec05bb8cece330dfcce6f8d9c0ba8dd210f65d9ebfa0584a30b5aca028b492c9e71d5fcfb9a2ac31e866e94814e4efd122209593084c10bf2984a0eab13236210c729140bc0c042c3d4ca4c8814039f799139023979914712afed7b713ad8e3cdcc54730e1e73f2dc7210360e3ba4a66b3751e10209bb777636ae45f960de2b66b801826f569834f3a26d66ef5f238efd38afa4eb9f3f89c43fa7c00c427de8a1a9fd1b036379b01e00fdf9edc5f1409dc0b24fb6b7326f60b148d241ebfb3fbfb37e315c8a8d5855ca3873c2ec12c43c3a08cc74c880b8574cee52a6ac902abb7d802463475b7ef994a40c8851d911e6335a6cbec3efca12478e388d3aafc61914762ad71c7a67f10f498d3788bc1031b9679d3ae7a2e3f4e7ee25c08d09bd6c95668f5cd99d0 +SHA3-256: f0b87945ea36d101fcb0dbdce3a0e17542a6f73c3d28bf1b405ab03c98780da6 +SHA3-512: bdecb75db800eb32bdde34d37daa8c6ef6e37014639c418bb63ee4f803c79b984920cba983143e9c7cd96b5169e1990b56116fc5bfcb0c9a2885461aae4b90ce +SHAKE-128: 667efb50210cf97456c693c4c5afa0db8c6306e1a02b1cf77368fd2afcf89dd3341484022f7f8533378750372ea07d03743b2e6e0e08185546135110fd0683b092e283cc96c9a99c9dc11284b6f73dbd230611c0f1f29a9a74054ac5b2512c97e6835ac06c385a9af2fa6d6c3de82d5e29cec9d8f9159fef886adbb02eea392025c5b94be6bcb106cb61f5da5fdc10942c11563f80c6cee973874a881c585d6c7c60c839f97730b07020246f88c18e65000d7b635e327aa71513b7f84095403743659b074fd254af80a4fd75ad850f9c6eea73c7849eefdca6649ee5c67884296c7a2c051bfe8d66c5c6d3b31ee254dbaea758f23b13e956cfab5fbd28f3d49e733b1c0fb935e2d86662c30afe413815826ae275e2b8fea40a95d2cc864af89b093f31dbad7d4ab3dac9484e76bb4a83170ed1b0d3df08f6eb5c679ac53feb9811b4c697ab97ba4cc2c86d0154a207f256477a01ab96137741e9fcd66e448c08da3a03890f54961bc4db29b33aa20251b9f041749848d0d72a770038aede59b6843258a67595a6c86706f824eecb6c36ef4f5596858a295cfd85e1b88f62aa9e354f69561c0facac07f979fe8e75495fba1636350b8a3fb1a09a07c11be7867bd525a278e527a56228f311427ea1bf7f3e28b27fc36c01ae93abe7d35b6206f9e313b6e37d163ae42815e02493c19e5c2f87e0d74b0d46e366fbc3fa53fe6c6d +SHAKE-256: 0713124a25756b723ea120e8582714e96c5ea0fbfdad350cefd9ee2025a2d2dee859d51dc1d773cdada1113c53a59ce7172d1187610155a13926966c6a1821cb1c5b2484267b92b7da5a6b5a6446cad7a881284a97f2ab25b15b21d53e1964d1bf049cec6904e0fb9cd8b0e835f4d7bf0402f0a568875a02912a9c866547a714057e9734aa1cdf9c42265bcca3465df3144421ad08af4c112b724735dfa068506796631b8f4c9975c578626b98ac9d5e4d292a5e980cf8b4dd206d8f3109b625ea99607bd131ba067dbabc8f9b8c27d95c5de5c8376555317a1e747703cc29b41730fadb1b37307d4ac548152334f384a55d27e35707f925a0d304a1602b047ba5d1dbb79df0978118532f77a548e54d554948967804298f52652fc86a81f2764202114b97da359b1d9e1de99c2f228098d176b65abfd6ddfdc0aa04490f68e9f111c27b4515b1cfeeb8962b5842d194490bded19be7f082f16ad6f8ac16def2803986e1d3052d0d21bb1a06128f691c31df699a4380e09b7c4009b2eca22c1b6a7f393a3f3828e3b25fef6bb48119b648be015f1c245ad4220d633c89d4b4c68b403863ff9f6fced1dc7594487d31bdb478c2176f73ed68d2fbb1388da171792496f69e0671b31745086fdd5bef77de398d89345aa57d62e068e754522608c202e8a2a54d493c5b998c565e26fe83a23daf82193aae68b2409f3ae461e09a7c + +Input: e35f594f413c5d5f7760f76061605ef51611a860b386552f95272836a9216b8bb4d9080a0ec13dba44837ac907a9d34b14791a7ed36f9d1d691647f1208d50b9f9383bafba9899e5a2a6610aaaa5967d432535a3bd7c3aa94be2ae1e469c90922d0796698fbab7104bb045906a73f7340528b86b14dad90f1ca1d37c5d28945329d0d0bb4b70ef501471ae48765703e961c1f5b25a73ab7312cf9c3f95817b041c9917187d22a7239ce56d5e990b135898b809e77dc443119b5dc611448c6e55e42b13882465c50fd026fa598e0f392e5551c64e9a09d94933c59455664febaf3e77f1c8c9ee86a95e6b345a1be493f2847d2abdd98e459fc7d4a52ce44c3f3cd0216ee2432cd563a2f621cc9f743c6cad55239f02d3610b4b20b5e012398011b3bbc0be7b1d5399c1abf3824f696e1da03078dc9ab095f3608d92c748fb895d73e3913d19b4a6a826d964c85835dfc72630cb2faff4a5f445bac39998e49306db56d88a5619cdbcb94b43eb6c1f5a406f00dd860570d403a06a4521d00cd4bb6494fcfa34bbb980fb5ab6c773ad834ed452c2ac302c8726228a384a2f34d941723ae192507062e12b1dca5adec3879e760acc3bb1a30947a842cd0af75fcf3f14d8631a5dea98247f +SHA3-256: f0371ced8b1d53c83d79f0c12f9c7eb51ff3395cf8193818728a1f834629d422 +SHA3-512: 8dff95fb245f204f3778895d9f907fb04f71c2d218fd4fceb8f3f7de52ac3c18486a9d95cca8b0dd60f3e11fb23d60be7a1f7255b51e0ff39455b2a94e2f6497 +SHAKE-128: be7f6404f94f2a45680a25a14975f5e48568cbe119f1038f1b4aaeedd62dddc6ea206dfbd81fc31f70ab83b563cb1441521cd42c850e134f9d6a2fb2d9d24d99603a891a94af8e43985c64bf8ac8de3d19d7fa28ab5a92682c1ba4c3d81ef758b6f603daba26edb5298e98d86b879701a1db43520884ecfcc1cd8fad12982a0fb2b3e1ada57ed383429318e1d884de8bf76b75742463ac30b35e85abd977d12b2960c59cb27fa1e3060a23e5e5f430b417bc0a36a5c04f8cc12f1dc24bf8ecb5ec3fa96ba3ca20531aba82baa6abc5d3c69874e121db16412ec8a55f1cd42004981c71e6dbe0723cb8b6a0b499973fb5f2424cdda52335d3b25d7a5eb04c3e33c3889226948b6a41861d54062c00a3224205123761ddeec38fcb11ee8e99107f02cedffbce42f796bf9b381ed00969cf37ecea9d27bf42baab6efa55602236c5e50e38a8e3b0b34a5ca039609bc6222eb15d0b878c68a417136ff4080867a5e1544c5c3be5b659761851473df014c2b585783a9005d02ee9da7643560081f3a4814623a67b4cf5d611bbf76e2424025457c8f84c85883656744977bdd8a1e666790de33b1bdf0166946eb3b566dab45d588bb7bf35ac5c284ba380717d25a4cffe13d1dd741ddadca4ca208af993ceb324705cc9b8e96a19daabcf8a849cbe56c46b9b047d9338c3daaedd16f3afa58a35c0f9de7a0912ec1228b412f139e66a +SHAKE-256: f14c26049f0c918d86f5810cf50ece65307b20cf8e10413b231982663695f8ffca09b09c504d7c76798b2f28688ca005e055bfcf34fc6f5d8d0d71a4ea550f3eec2d67d51483e4b6c9d9a5f9dca6632284fd9c99929b8357dc96356f6bc393743b6b6d9f67781f45ae44425941f57bdea2f69f20f25224b2192dcb37cece2c367416893c5e604f3c70a9f68dc0edd617f2cb2c0062509e52998afeee66aac9d27a0fafbe65641e50a585acdb618051912c8d3bfdd1a83beb9d5c6da945734a3877e6d9551e63ab4af42b575373402528d582129799e3079e6c0d8ba52899eae277d1ca574c351d4f3d0b03c808b8cc26724137eeb6242ec86168f7bc6298f487c81fe3456e4d59cf70f6d4133dbb62c45f5a939f137c91bcfbe98e174992b77418536b9e63b5a2b4200233d0c25f6828117907349af38bfb52feafe30a3098b9d5c73f5851df4982698eeca17ed1922925beccc26c195f57f174de9ce17ce889018b8c7fb143327089c73eb561b1f6b263e8911f099e771c43bc73f8da1c86fb819c4a184eb66da3ff1b5e10f78b8fe715e7c34c44b5d07e526733175de01eea3fd20b5753a2b528b0f769ba9a4dcf6abe137474ccec5191e42a99903e75d51adb5348de0626d4d614620ac71a7e8e26c5b28c7e94e23d08b6ceeb31ae91d9a2aaff4ef6416fbd9c4c128d86c9ce16ac2f2ef2ba18df0210cbfccade94dcc795 + +Input: 288a40d07d085180723f0abd3fcb73eccc8bc076e7e168cfe0ede84ba86a8229bf3f1456adae9e1c3a57408da430ec2491761c1c114da67a3e6368dc06b86edc8b748c6f85442b3f191ad0924248fa7542c7d02231ae85c90da5ce64a6bd7740a621d7b9c1f106293210bb166edc2a6039d180bf4ab9b33f32e1faf5b09908c8c7f43f74e0497f9b36e360fce7a8bae824f83cd57547a8206d305d522b7de3ea011f1f986c73ed83528bf3ad52600ed1f4434f61cd2f9a5971defbb25d62ed27940ed97df7b05ec7b3b2f23d474544716c726cb3adab3f8123400fcef6cb0fcd9b00c1954b178101bed74c15b0fcce850c43a4516f66721b70798d538ad85706126e46194b6ad5e991f4dab682d9cc8b8c2f8bba387e1575dbe5d39d573d6e07424214c6e74b09e5533ba6d88fcaefc996abf0f43bbbee17f8466a22cc324316a550501a8dace6a64fc1c9c10e6e56e79b9d905fcba7cc50bb6c079fda5f3c2596398087b83b0f74751f97a88c12110c5a703d1a3239ba8e3a148128bd96dd949d516a06ac196a36c491dfc78953362d9a613c32f737f62168c194e90e7bc0624914f7e771cfc6f8def06e4156ea1a319c76362a930e30762faf6babcfb07329b5297aa64cd4a15caa45 +SHA3-256: 6cfcdf957ec0fc26f60b5f9aef850dd936b24f029a1d99c8a84dcfef062839ff +SHA3-512: d4de60d90ce1aee11d30b91ecd1d9f9b35992d7b6773a1637d13b03e0a08eaa3a80f2aadfe10810de47d963ad35447d765915d3b4b48ff8ec49c2e2dd262214a +SHAKE-128: a3b6057d5ba8860dcb588eb85543cbb7a0577fb988f2eb73ce8818c29f7e086c9398827c0e95112f9e4ccc19cea74bd40c49fc519af53b3316cfffee883e6a854894405ecc08a11cf2c3e2856bb325c9491f68747792326f5a09c41d1e5b0d016843f4b5b701209abecf9067edca5bd50391f70016935d8bf97c34b4f00243b955a96d3cbfb1c1e8e6b32a795c8b08350f434783b71384f17abdc0de51733786eb05de0de423859537f4b493889806ac91d9a14d460cd695ec2eac29fa8efd2894630ccbfc69935a82c876757117301d6d0094f47db76e73f8614f4f679ebde50d656cfa1e90cfe06ff653826c18e2e3659cd019f12ddb9d88a97701cbda1a59abf11fe2e354833210f3e372c21239989b515c22ba3b4bfb5222b4b5107e4069f09f6c3a2d5537e41ca07799df231b7281f499aa223dbfde90969a510690db1e5b8552487e01ca3f1722d8c304fe873eca1ad567ac6b47b73a872002177db538733b435e1fd67d134b647d3016132d5f7fa0698b539c368187f25890a6e88dd3bd94c5b5e8768d906605ee6cffa18a5ebdc36169f8874113c0a43d78cd72751f127960bd6812f85884a1445907b0bb9284f9f0d59f60f31deb4c16425d9e23d3030f748e7760007ab10487890cd1e7d8cd1762a6aaaba3957d323e7401e07e190543a7bc00bd9966ee705da7fa343ff547ab2cee6095e8c36b05b378e1d636c6 +SHAKE-256: cf33f3e93bc45406aebdbe80c989c03c4a9615830fe84534f4352e6565e124ae40186cabc1025df9bf8637c0107329341dd9f6bcb542e3453d3ebd6c2e060c79fa13a01587a95870ee1bc35aa5726c47e830c0eb619ecda12e3eff8a2b012e62ba7107a8f1a3250bc47d5fc43a2437df8d2f5d8a1e4dd8c36b9429c620c323e8dc80f2bef5f197e5792fa5936dafd4c7b76df72b68489faa3df46dc5985c3756a79ebf636f7886ab56d9581e1e30353cfc7de57442597af7e6de26a419cd44a7833f063faff6a71f9008221e332a57e83ec64ef2c43b5c6e1fafd83152c2ce79508298d9698503d585c46ed7536e684b99898cb5c04b3532e364e9dfafd0796c1313c6341e4b798eddc69b6231009fb21425561ca63746cb1d089415c1c24320fab89cf039fc25a1dc1d8c60a1deb126c43c0b49dcd468388e015404fe002d97dced216034a04c489b03896450d53249afd87e7036102f8fcd86306e835de2b51d722faa4d6086cf67c313b87eed6763d16e0c6a635bd0e1e8f4c06dab55c4134991be23b971b4eb823bc899180f197992b1592e107a40bf6c042554f064887f519fa97962b6f7783134853b76fc874299986899648d7d8c41ccabf2ed0566bcbd4938c728485b65346530ec170d3694e1fc662967cb51304bd5744efdc94b6dd0c817bb0ed3ad40ca1ca9000e11acf5fd2667304d69f80b8878dfe0c82e3d6d + +Input: e4b274d4f3ebad86c87de7b19c1131ef6bc5c9d9c550304843edeaac354957e70b34bb36ca1f82a134875de9ccb9a9b6f16942e0def4da2e8e845dbd0e1875db2f88735c9cf54eebc9333f8fe3f4607504a9c372a442f3c420418856a375d90a84a98a74f9a584a8741b205b7a7b6fc352e7f2efeeefb2d2c40ed1112fe39309e44c6147668494cb36cfd8642d543183ec56a4b0e353f8bb95612a28b839683708c1103bd6b58720fc350c7cd5eff548b28a8373388419acf7ef3b415de028b68465244a7b13fa406c9265a5d400196ae6d51c541f1e78c2a02c133ddd667074d7faf9ac39a360022e53714bc76c12e3d1d1e7ab97530ddcc5ee85289bb050a68a0cddc169bd9fe2350eed179acfb93c6016688614497049d223be3c50f028b7c8670ded12926f303e28eb6f8dbb2d20b0ee9d0533edde7cb726585fc071420dc6a7d96615f819427f6f247724f2b2a389fd665fa3a8ba40a0ae49dd3877f398167103fdfed635bc0b322d261fb9fc8b7cbdd6306f995717189e24cb5723ac43592636900591b28ccfa3cf6d9db1876ccec1a69fcf387a1200ef5be417c8a59eb95b7b70f54a03021786d3b3085f931721b2ae6ff44b2c2cc6cbd1c1b708eac510fd2974a0b6075198fbc5 +SHA3-256: ee5e44a25b7ec7d217ef5a9c6dcde7a7c9c1a61d4b1bcf8e3e9915d3e3bccfed +SHA3-512: b18075b727382eb32c795e08f62626ad485486a38e924b646ac3ae690a79b1ce5d892e79af3ca23b343936438858ab9127a7d006266faa32f44d0546fcca4b3a +SHAKE-128: 5e43c51f407bfbf17ef552e753e48689943b094fcdc371c4a72e044c91e48e2a5a543e1fb1ed217415960069d80ce58270ef7a14d57f8781c942e407279871cb5d55db4cb5af1a0a289400b1394a4acccc2bed94f9ec0ebdbd76d7137326909b1361e660f8c1e1cf3a672a41bf77b8c6d364477815249d98826cbf9604567684e5817639e10ffb83ba43e8d84254a033b1995b3ece9ab2a868e76c43451dce269b9a86cd1a093baaf3d8b2903b17398e74cc3f6790cb2cb145f73997b05f796fd2a725f070670a662ebb18f83763c3d60fd95374fa95a26ac0b39976e655644f900454d1bf13835068724571c6ef73fb08279da77df8743ee23455846173fae0655d903af8bc56ef191449ccfb30a6b91173f171a645aed023c4a9b31e144faabf1189b255a787aa5a071a22733afcedb61b094b9c726ea29c5bf1d0909736e4f6778bf895992d8bd0ad7bb1d1e742c76df08c2981fe7db97188531eba0f60bdced89ed592076e31257037747bff8f3afba99122fbcd509006cb4f6e03987487dc0a8426888d0616935e15d9c8ef4ec234eac61d9413bfc518f0616fed59408df29819ad0634cd1786a68ee1b3e17f58db943126eca1758d65ef6d06f7f69a75f1fcf8d98f0f154dceb20a3847534d238ca755b48e40b227ba2dca29df64ce326e29f311e6150c0169ac87120d179f3c0de7a080fcd33224e87a5be064486b88 +SHAKE-256: 6577c5b08b205263f0817ba9a0143737788ab67057fce0a05ff49fd0b203c299e36a4b9160663d687e11c2758b704698294de430f1fc2307f63e5d253d9de57d48c4df90f3b02d93ca678800cbc4198c42fe9a1fafc2634b115ee1657cbc8412bae9ff48da59261e0435a7705298e7246e815478ff597f2cf4a3b653130f487766f5f9380dd4e4adfe731bbce10bcdab8cfa1c4355ca2688cfcefc816822e08eff1e71188d83f5681e6ea2d6e1d582a2d7cb587926072634910930eaca5d16d76614cbd8ed42bd9976d7f4c72242eb7c0fcae81ac72c2315fa7c9b2842ee387fcceb47ddfd94ecab2e4f81a336c9872c7ba7165a62a4dd6594986b59f37c379b138c27ab3b9d928ce3e5df1d09828493ab9238ea1f36e4d386701cd154a219b9357d130456dadf0dfd5f65a0b0eefaea42be9770a3d5ed24c31e956dd7ed9391dc054555c13b2b869eeda2a9c5eb6383adea7093edaf08f16bc4fa34f656393563b13cee635f773c3ed96bdb66cc4aa64da86553fd44e35c7aa3c128891bb0914c9ba88fd64df3992d01205a0b9dba6763fe70dec3f444df22b97c86fcca2da530538a1fd557893a73ad3d51b1df8db19467b2c8737b61a409a2e4bd46e1cefed8b4859eb64902bb10d4913c067b40d9f714f1e2848e2ca6031e5c5489d2c98bbd65e74e1623196d5d84161c0b8362d9db14c5c89e41790da53f52964ec6969b + +Input: 64b6dc4bf2d25c2ada9d1ff1728fcc2a678c5482e0fcba6a7fde65aa76d3b4792971495fe8c8741795aef6a3f4e2bad3e16fa65d93a9daf1c7628949891ee4235fcf0eb166627821beadb497318c5f5e6bf52411d3e79b7d2bd5d16ee38cd7ce4e993d25ab47da4302bcabafe15e651ce51390dd96140911cd07c990f7055f8b2a873327a79190de7b88c7e10916e7fa8d0efae70018d704e8ce25484946c17813e9554f3c2bf1ac49083e285ca7afde4b0a4df520ffdde63e5db38ede6ccfeed1e817715fec0c6f7117e629ca74bdf8a75b57915ea8f71c352f78b9ece13ce82a32ffc535c8690eb9456e72c171f3d304ded2beeee1ed98d4013373226e3da825b3d1d2e42aadd97296b7057c9ba840a0b9f1c97f055c57aacd3e1c948aec7dc826794e6503b5a91a0bb7c62744f61b2836bdcc39b5b42edf689b21dd90fb0329142283a9856344c5da5c0996f52e028dce487f3fc177bbaf1155f4c0bfc9722769d30888c0bdcacc59eb6ebeca4bab7418a16fa8600f6cc6b14bdbf9e616fd6f59e7cd773388c998fc7f40729a34eaef96d44869b7a0eea7cb64ca3eac02efe08c9584d2611d7ffc00bced356572ca8f594d7c80396cd03dbc32525c250aea66a05d67ce0134d0462a6021 +SHA3-256: 2ac590e219987d88a7f00fb0dc30077c62ded8fed2fb88467de0070189929a0c +SHA3-512: 9c30f5080adbb2426b59e701484c519445ca4caed469eebb98bbff06109fa331f663b9bcb65390c744271c25c83bbd9f2c989e5cf502383cd2dbffb00e2a9ce1 +SHAKE-128: 77ec7bdca874afd0d205ae9f5371c295d91c9114982a98e77be26cd868b13401c815fba5e0bec8d8bc38b060161eb2cb7ff8a18a5807f486a85ddc133aa97d0e3ba5ea28b9f5da9b01c751cec820cbc8bededfd69513eb09f26931b31b4e2e77fe6056987c8ea72154067b0e1a511c4bc61c20cc6f90b4997f703dc292d3d6e5c6ddd5c3b48df190941b385337102fedca82fec425ab1ceb7f9972f6146d913660453a9dff075a34a14e9cb565cfdbb30e2c51dc3e81bb7a8fd173d1b7e2407fca7ce2829cdb669945af40f58336a6470d628a806f657342f9feedaaa54364cd2d223d7fe6f55e03fdcb51043422aabf12e7fa20a82ce49c70e8d7c816f96c9a1f8033dff4366bad9297d61a367ade20ab324be71547506fb6f099e376532a3a5673909e8e2b975d3ef01657c1317de8d6f2fbfc8e47663c50c2aaa02a668cc507e00f6f6ab130574f92a9eef856628259b4a7ccbd051b1bea67fd2f51e207792a5ca7ebc7a5d4c72a010ce45acd9baa4a64b24c2278712df153bbb2f330a87df36da2ffa1030c0a149f69ab076e9abd932be47428016125129669e11cc370ec10514ce6455d297260758303437ac00235ef6ff0d1833c8fc4e981db9a12dba7bb5fdc3ca18d396950fde003449e42a2e303ce70d41f627a3ae57b370cf13f9e6dfae93b454b7bcb6e81c7ddc42a71dba7116c8df79b75ba92c5a88748ca2241 +SHAKE-256: fe82e0b1a041795c12ba5c783151d289ca558f6a4286051a60588d268c64c84245b3bab5782464b612d4ab573ed361c9b186f31e37a7a6a65e3131b925bc84a554406b3e8c6cac71751bf80f22985df6bbcc54f5ca84727fac183b55b096682721b36ba2f460a6701a9a604f984afc01c94040ab2fdb319ff552fd8f1767aa52fd97b4fa18fe380f11b99055c41298f394faee39872c9cf140ecc8b208c086f3e4bc45689bf25bb4caebaa44ebc3878d59a22bff45548f2f9494294551c250f22156b076b65197b6f12011319db3387ebf8d0a42025e4de6df24aeb16c94b668c6e4c638e0df82ff171e5a6881358f79d95b7bf589e4c7e1936cccf0419e5bbf9e91736faf915ae68fe6b3a37483f493bf9beac17475009755002ceb8620de5c6ef9c2010383f5266371c218b208dcb28f55f49fe3895c1f009106c80ed39feb04886d23a76c8280e29b41d53f22562329f5128f7891ef7e634a860d6db15d8258d0ec68439077b84c652c62c132eae6f3afa871792ca956ca83b21c2ac1366bd76cecdff9333701bdf49e8e92147b9d0e9e199fb2f0ff160fbc78ef3c3f46de64c8b0b475f98a0d01c5b851a1a6d998274fce9ddd8fdbbb50ed9aa1283d0855cc85e6097ae32270c801c47c67a0923023070768a081b06129057c29d2c3238697a750bef11d132b59a484a0d27d3c03a94e9ef1b1106fe1c39e6f9c9f6fc2cc + +Input: 2a9ea0a0d6a008b539a51fc68e19071ce0658d13c12f5c5a2c05a7097d52b4466c21d3428c2bbc63561bb4c156e2474b25c03441fac38339916c0fd8dbdd8fe7092e19e1582b958a55bfba6b0fce9130302cad3431d0e4fa948ad65cf968168c9ed8a9a9e3aad2f6b4bfdb14403cbcdea75a61386e624eb4c87c2cd581c9026d9ff26c152596ffd84b3581c3bd6a9e797f8e292276cc97f43c1d62c27008984709ed1aa22459d0d58c52266a2b1b37a152970ac910e886a41fa9455a6665bcd524b48935ddf844d0ba72a86f3f4cea4e01ec613d02ca8b4c050e8dafa516e0881808d13fa187efd5558a5e7a7aa3247145363bdbbbb5116aff0f437105c898b570610230a308fbfb96146148e0ced4ba0a62990fa2d605e19d4c9afce44bc2a55cb94683010984b19473b42b40f712977912402e7ba6abf4d951768a2b73107307f6654f9d530cbb85976d7dd3808bc8887b0268b12a59b59b21dd12e0a274dd673cfdaacbab2aef8692f846d7b8a4ec080dc1eda7a2c1581d92d7cf0b9d076097808aad44010d9241cf2af3f8d8bb68507e611dfc2471eb7fb4ad339cbcc79d813d4155e3486a18d83344926dafda9e1aec526e9a3e09b9d1eb8d7e46109a9d6d49a25fac7f085feaed1f6cb1 +SHA3-256: f9539896bbcc99c791ad0f7f079f6266cdb1b65e07d73f88b52f6c62b5890dd5 +SHA3-512: dc5a65e2a9d7204fbf39680da247a5a944d2e1406dd768da20a9eebb31fe6dd80f958a6d39c02deea5481bed65055ac28734923c33d230159d82bb34c54be6e7 +SHAKE-128: bb9a450532b66310b6312e096bf8ec3e91023a8ff39c70d2d89ec2a8cfa6553209f782526e4b0ccfa3f3805e64b70cab396406f560d92c8e86dd5445ae6af09598cd80bd19e471b232d3daaa58007ecf2f603375f556495ed88f9815dc1bb27aa5348c7d76e58d9769a8218b555048322d630b84ce6cea75cf0fd9ada0328f727bd9cecf537720654c5fb437e504ea5469e388cfa5ad424a97bd3435dd56d6de591d234d5687c024e0a6688879b2b355007a6cf05eeae3778d934771d14dbfe55ac5bf370f4e0e6864244ea25dc7d4ce5a7f498287930d2586e1374969201cc1cf00f7c19cae65d2cb94e5f551ed20d0690f3ab06630703c8af2bb76362d0b598a81ee86ab7d7fa9657147b7923cb4ab626579807eb532a75c261badcb37c2947098f9b3fd236ff194dbf25d40566e936054ecbbe97071f2c60e2a5d73d5809de539d502624c88577ac717b2b32b3b55c484839fdf365ee6a49b9166d14c49da1532b5af317db3eb889ca31e92cfbe3ee4f0008d7408fa05f4b8c646ed055a90f7e21f441dc1826fe3ad13fc54df118f0ae3007d729f6c4297214463101dfc50e0a37077e4acfbdfdc56f68761fb6d69dcbc87da1f6f68d6d89b8ab8d614ee651f626dbbfc0d643d2f72c8de72ced39a958d776e09cec356b5eba79fc4e1aca23f508aae0d8f7c7af7295df9150eafe8450fbc46f1b71183e95255d3e1a651d5 +SHAKE-256: 8e1af05970eecee9362a559c92e26657949e0e4fe2e982c915d2cdac45f2995502160dcc1a885aacda75d587956460cf2d906c149d644e70bfdd441ae8cdd75041be16e749efc8921d606245b89ae68d4a27ee363c301c6fc375406def225645d0ca19d4df05c08bd59f7a871f458daa573ef32568345b47aa68504a05479b924d0da241839ebb77da7bf62ea9d2e3ea518c0273ec533b3d6660254e7099b9f93b44dafb70aec536e2c0fbebc545e01f1f1cb6fba6801153f445693c0b768046f60851da80a15a4a7964ec6a21c3c0a3250cfdfa050bfc5457e43b37306ae417f0342671abd315c00be43d083e1bd5bab3b1a5f65983942c558e71e9a6443aee953d7d5a6779dca7d3ab20cf7e0d38beb1ad43fec3c4ddf995c32f80e453d96433849c3d76941f83c4ecf6b2315df9b98a8c219502b3e456a544d56fb5803ecf0685856a5f35e3d151613ad42f7430d50bd8457c7f02eaed813dda2ae4c16ca5b9ed89cb9ae231ccc5c93e9cb3b995b9624aa39a594d1d647a5d8193c7da86a5f73330fd15dfce3265b5ed7072fdb19005fca2d6e0b7951c5e884b73e88e0cccd98e3187830d2ddeb9a8fc242e7a8f479219c41f1e1e0ab9468fe1f3359fba9d18b4a16de3b51f63d43f5ace991791822e6a07d467f0833fc9a8af530eff5db603e907fdf23bd7f120a53d244bd1538fefd208b37476f5a931875571135a74c9 + +Input: 145d013efdf7e5cb918483548e447d67b558c4145908135ba3d06fad6cff12f6ba3ca91757fbf56f6824e0c4fdeb6bf652e6d65090f2a3bfb81636c99c884978886bf64e40aaee1d7f4e7e0aa5688d588dc78cee316f00f85144c68d67855c72b074cfcee11bdafcd92fc1e00b9928724be807e66dd156c251db3e2b5f1be71b415de1af8e26fce6df7ed467284d56726d75a26f0463d25e6b8db8723050ff7819efb43b90ea258db523de9b1bb907a7164495f6d75fdcbd8cce9349f060ca9f709883a98a98cb55e4320e97c9da1a4a777ba354369812a48e556501d1ad77b90fc694dca644b0a4e7a52f31477e71b85eac27fc4cead7a1fc959b6621cb7822e466c935c99d4f0d2cafd1886109706d5639a206ae8a7ae6d3d476b05d1102593172a36cbfc450e53b1952fac35cbab5d3f0d9d6a862a0199ab699e69556034f74f7ec62bc71d3b329ce7d3c151619633faf385470e1a023cfe49ea3ad3d0564af5bcc3a279c2b73c5909bb1cb0b976570f02edbe4ad4fd04395dd9c501e4b4062519e61a6d2e97b0b59b8f81c049936db4de3ed197959b4f3f913d7dc5e945f57f1a01b3ec76fcb504d55df5fd22521d01378560ffe141108a01fb2d182bc1f812eb6608b226294f8c647bc8aa0 +SHA3-256: 074d8a98959349ba18b39dd4bf552d1b7588296359c08963599990e7a058a29c +SHA3-512: 9bc5462fcefe134155d97174fff1313a8103dba8dbde0bd54895c7e74642c257ac33b78fd12c713155f62a4b8aab0177c86440badb526c1f2b493a687bd68482 +SHAKE-128: 93304f4f9535213ad7b6e640511f54badb95a3e2349797ce067037455836ccf407091f602a0a8452a1280e5a6571745b58772ef876830c37fc86497d684d04017f8794e0d4fb553b39a563631a2d5299d34c82e0879f3597b353602fae106a2d96d034bf85655036bf2a875a4739f5933744030804b8d52a2f68c7a87bd4e1fda95e4231859a7c63613304eca34f9b7fa9b3f04768f28a3e1a8dc6194e7b30f5690a9665220975daa5d2ac827b110cc275618a5a6130a0ef7dda08b2263eb761f4c918facb00b16ae03d839e89e5d7f0399469cfc68ed2f08f30dd4978b34251c6c4c26c4985b41c6be1b995429b08e640f76cf98d627ce6125597f1259055df01716c7b0b7ee61132a1d82fe2e0facdb7799b5f87aa304c52c50c7f32fdd3f9e66c83b71bf5696c179c14482a6d2f50c103d68d714f77b87536f0918adee40b752ba42852b9b51acbfdebe1ce5d9e73afd3ee3d85d5aee27c543bff1153406d2726f79c119b9d445e89393c4932e4f2950fb691c1f709e357e80a87cd25ec3fc9fff5c377cd953021ebcbef71fc92f4713583f72a13aa6ea2f7fba1f76c238affbfc6fe4996ed586febb4b2261b53358477b9337746f7494d2ae2a6f04ee7b630e7aea179acb21874c0be1c21f45ec0fa15442b944a8d82e83121aec55eae10250cae4465132b1f9166faf00a391be338f06060ddb2c649e989db169b21b037 +SHAKE-256: 5ae546f8d4f48b2897f50c322fc83f0036583a5240aff3a8ec33bdd6c4018fd8399cfcf214540a05d1f97bc04e0b9a586073532f88ade6cb6fa01564f6aae87358f0c2c8ce8b8cde37a9b4bc66e78666a6da84768a86e2c291cfee3e115836c6f74c2cfdb722f9eef81c30260c4d5a2802c2dc108755ca6783e9f647e2a6819c22790111a186e1f87be5a54afa353ccc28e4b57b2f597d2e055d2974898128bc6c8d1f055f368fb88959d5a43bd27b2c85cff5bf888e4f448da37157ad79f9932877f57e7467a86675ee9dfb353bb0075a8b587a696294c44bbfc4deecf73c225b757a212bc034fde13da2eca725f6d8a5512f32b485f94ec94c656fdfc78d73133f04c9334fd7a29c31ac1e9744fb1f93b04b1130f692b09e00b16ec6a92aac5e1182244f1e2c7bdd86b8e5d6128f30075978ea3cc156aebab64ccd2ab03f48dc7f7976e77b251e664d16d278919677ccd5d0dd01203dba88242384983129b8e4e167100502be0785240184efa81388b05cf2cbca05582e877409317dc55d73cf25c4daf821517a3120ed10150bfd2a02026e468b241538b8453cd87829a6dd9685ed53172fdeb51cc7b18d79a324b5d31f88fb10fe6bc01b3230a1f12e75823f64d71a5507ed6d8b8c5e056addc26e404c6d23ef5b48284c2a80fba15c47a1a64a9796d057a94d44a10391a4dca530b2d25bb37ec8f2087ddc51090f67087c + +Input: ec21f38a415500dcb8c79bd6d403fbaeb911cdc5b871b63d40593da6b45018c52e417b8c3a157a54ce5f9a3de4adb147f2fb3465a73f5037ec6d4b6011f9a0ce702e262afc95a0b26e11cb685b9229bd10ab01352a2488f01d93dbadf715fe9990a8c694e5f8517cc3762fae63918d8491f2409ee0a9a7d8c4d3f77e60d36191da8a27fd6b53d7481285a5eacd98ef3a57d6a1a853d6addbdd531a5e012c10de75d146303c313488d2e5843329e188c8a786ad4191e36eebdfcd76cde4379d4dd92b7cbb54675bbeec1419d23d958bc7d4a1238262997a0dc987f2908a4a17bf18de5945418d819e70d9fee7a62f97c8a9cb8f0161730858ea8b4ce1739ee1f1695413efb9dff0ea9ac870a049df605405f256ca9a9811dd8aafb9f4e4579843704cf0811a33012531c200db5ca4745c7e0f295fda9ccf15b24dfd14b373d68793e6b74c98607c2cb9c207a94bdef140d8427a56dc6cbea1e9d8a6f47f8630c7cbaa56de2416e29ea199473542cf1ed6615d8f8973edcfb3632dcc7e4e548b5ac890d32f50bf791537c4c08a162b966e5c9e712c80696b33105df9d4fcbd0e05528a46c0e0d6fa2f8f46b98a382808475789d1bb9717e692eb19df285d63b36c2a57dcd7f3d49bd3d26fb8d1263925 +SHA3-256: 1c31808c320a186ed73424518009491b2c6ad4d9fe239636c2ad583850d4a12d +SHA3-512: 21b95d358d179167c8cda19a8a43643617b747a674213750dd21240a5ed8c430cf68b0baf4b8658baa719e29639a5034e2c26394f6da33dad78c72967c5e9343 +SHAKE-128: aa827e953de6714b5aa46f67fd593c9427f4dba19847272f0e5c4856b50ee4171b7b0196d72e41add6b4e6e5abfa30ac13e36f3178b59e78e4b668d636ab08b9ad5963422cbd3c70fdc272f178d5f8fd493c64f002342b2339fec057ebd5a257af82ee1390db3f899f5d063a6368c21ba47dc614ef47f77c0e38d59cd6f6e76d08a62f906161cc5a0ac0db4185de75df00f0ca5ae497ff9a43fb634dd2bc86862e36f27571d02545587bde93ac1a2525ec233b8d7f0af12c12503425046d52c804b49d9a497bcbc45934d60241a57cf449e9dac692aa04f2f8f72f3737bb3b0eec51e2a57cf2ca770ac500b2a61e6fe09c6ae837bb67aa2ec91ec8c75f84c7eaceebe7fc68a27de0390c07f27234b7f02734218d852e835a9cd54f66dfc83677f5ab346e12d02adc1c4dcda3d619194e6644d37ac7f403579da795ef0bd85564b049dfd0df014ceadc7848b9b98ba4a5c988fa19de73c2b220c00be277414e732a577316ddce6c682c869c4feb2bc69792db8c48fb1b6f890816ae29a7c11862e55839fde5c19efec661d925ce59df2b1278e4b63f3ffd6035fb943a32b2657a528c28495af0b4e57f90156d8f3b3d011e88cc5936b781ed80510536ffe42233ccdb7642cd1f35ab066dc8dad716f1ed0594ee89625805ed00e985833981018877404812498f3a819c05903abc77e5465f781d9eb18dd1489b65c4ee9e5503a6 +SHAKE-256: 7326368cf444ded99231985d5ff9834504232f244c96028f8738eb9fec0c1ad180f3bcdd53d7f38cf8783c77f8bb25f9dc295296e90d5dcef8919b587bfe9ab58ff86e68abc6e107b74f7a678a0997b99c8cb5c692f2dc3643ef9676287825db1174e26faf690ceaecf8ab209a615e7ca425ebfa1356d999efb6abf622b9a5e4fa5f7faf98d56247e1b52a4972c5e10acc5a9ebd23643b708a945928362622afce08166658741569d441655401f48a37c40308fe834e69a2934d3ef235c61089b65fd409005ae7bd7af60491baf9630e9537ccc1ed91cc2a245df1094e7dec09f06b298ac9c65cb0b25c8292d6286e5f77e47ed544be9d35520793544794733030b4ec515e144cbc1790e4adade58ec37bcda16e82860c92498962635af6d4adc42dcc83a62067eef4addd0e303238953134de74d9fb76b3189f2238fd1780aa9edb1bf8c4db7c80348e001a4314268911b6bb004766d55ccb1d73c1903b7f73017ad9f89613ccef9658bb5355ebe5cfb89d37514459c15b04c3e0dafe6614534742e319ce7e95ad7483dff0f28caed6da3c0642c9c8fd7ff403243110fb15c04ed2d2d48a2825430914b7e4d7a5464a2c880cbdaff03eb308d21804f8d6f1e0a00fffa8e82ed31afdcc7475768dc188b8d608dd9ccfe7652726acf9d6726494eee23b188abfd2c785c25b089c84fbeaf27f76e7b204f61ed734eeaced43d19b + +Input: db2e181b97e326fa029d9638262363cef9fcc402a095d9688c6ee0e108edfeb956f3d053a18c790092c88abfff57210e14ea0c57f50263cbe009695aedebc98b90144ad5bcb3f0e5556395d7ac1bb8dae064219e0d382f1474feff369e1c4b602d78522a5c4aacec4bca5257189dcd7d9bda457eb2bac45a6002fad410547a01ed6e39104faeb6fbe61e1f6547904891ff8db37e157a44c03d61efd3713bc43c1417f2d1b5a92f6facd6f00afed08a0292fccd7f72b7a6110bda4469fa04bf66879f428b91a6fc7b4f3cb2124b6468078843695593d30141dcdfb30177f0148d42fa0c59fecea55b7dc7f09f2176412219f9c99861cdf13a92a87613291c8c76db09569d5f6268037f2bd77ab901e4c980c717d4e347941c46ebedcfed897c10c48aee0fd5a9559e16f231a717f97450c857ca5d00a551061b4074bc5d8552a78e8569ec6283f1508ea7488b8d42c6548612c227dc033f5622e5f6bd1708b12b06af753d464a6a5d5cd5a1180263814d67a2c75aacee98cd42c95be7abbb172692dcc006ff4bc57e0d3f281c2c3a2c496b0842c90070fc881a7e990992359b51f6878a18be628e5334959ee6aa625403ec0ad7c12d0ad0df8f5fcc3839e92b3aabfb3e750012fc4c8ec7c40fe6a399af +SHA3-256: 27bc8d95be9bb63598d858e827a248733109efcce307bbf7f6028b596bcca6e6 +SHA3-512: 2f7be32705e48d0b6f947101d66d15b85d43241d56b43a8aa6eaea306a72bf343ed1af5816df70c5a16da7db5a11f6950be1a0912944277d79724dbdc2fed972 +SHAKE-128: 8d55c09fcc76ebf9a3d76b6b4d093778267d3712c7b538cd7f1f5ebeda8a8169a8b69abddac802f3b2ef8e616e6863f1112032aaaf49ec0199426f325a0c02aadd51522f4464c2d4824e85446111788e4096dfd3522ebb944e10e57fd4d5085ab3fdf2345d26cbc36654e35f502a2a39e86521ebce7f1c0c1eec453137191f5da67e821c69401890f0c33137aaf25a8d1a7e9f668ed8a86351324a0b80c6b605f3b743e963f5e6c9915c53d6e32207d9c65da2ec89afee1f83030d5d37a2356a75e2a9c55ac45c80bb6f13c27f5d5374db2c53f4d28c6f0ba3e87d4401661ef2b8fde5b4e5efe089b73816bff94ecb15b7badcddc3eb44dcb8540d318e53d6faa89ed62dda63f03256fca62871ce4ed41bf3696ec7b371dede5a12d9cb34a6a9b06bc9149d805f0f1b304ceaf0d3457d428344fec3243652f44791b152adcf6baf24014cd56ba6b1d75aa67bef8dad484b2e173530a97f47f39704c1564090d6795f0b5732c17c22ef5f634931c40fd2b91d07581e29351811c6bae1e443ddad6c9c2f2941b18425111c2265ae70fa2f5decbb279f38c6878aa153693ba35f4a60e0aecbd6050feae62600cc720b07b6de0be4729ef34d9bd67b8df96d50c0de07190db430edf954c9f06fb9b04ad9f980df3b8f9a6a1931f40a177f362bb09049766c01bdd233c09e09b48b1da2252310fcc65192842d4f943c1f5fdb32082a +SHAKE-256: 9e6ac3fcc9383e77aebd6e41770e2f782cefcc8d1e6ca052b38e1a956d386c6a556dc12f9103376175a3094dee1430551cd8a04cc4e755c5f1d94b8c75ef725b41524ca9ca7ef2307765e0d5dc11af310dcdeb621fc987a88f946559ba2e2e755120762b98b22a37c51b67cabe721aa8ab2bc113e2fd48485475d32b97513776cf6e3cd3c99ee2fb8a6341aeb03854270f97f781c3ec1b57e7e71db682117b019037bd44e0057de0ffbef4e1fba03e36772261e59602d5aab49df483580e63e1e0b341eb8d72643d50d04f133e3abaa9a398b1c3666e8123f88ecd67fcbf1d284e9f871eb8ce48eb842f5cb345a9cc1b4f97f6fdb04c71c73790c58c92b293c801c037724d1267fda60dd0d6d05018b48be62551c4f213e65532ca41ab0007a6e9e4989980660c836505f06e86d3420fa27fc069902fa4f4d455613018c6eaa70b4cf8203495e8505eccf78b58c419969c53fd2569ed865a8115ffdc649923e0b7ea33e2c830bcfecaf849c7867135519b094be7a2cf5912e9058ce012a69ed0f4c810ad97b5bc32fdb2fa4628441c4856e9e881563a6bce8e45cb709418c0bc9a6e80be2126631ce03d87ad911ddad8cafec733c1948384b4f849ea89a42c593d79d55be99ab8f9e1c37a0ef5c09df3183a8f133151b8ac14f5d8adf9568daf7e77bb998b6a5f23c814b28cad376629a211c77f118c44d309925f72d372da7a + +Input: 93744fd07d7d39b791d691fc1c8671156a1b0335163cc7dacdd241dbdcd18cc1e05860be9032a027fc04840a7c43e3f16011e49e25fd14bb578f49e858d402bae3195f09a2e4ec41e62e4184bd8f949e918b7d4c92ed2e9df16272dbd218b90e4a4a2e979de1f4fb9f79c1a5d890fac89f7b58441d2ca1c6f4543dd155686eb2c3328866fbda83880fb7f0803c7103668310189611aba43e04bc01b8b20802e8bb168df71bbb91f75d7b5ff4f6d6f597cd457e3237bd1ea50b436042b6928ba16e4ebebe199917931c58ee3244d4eeae164b2c3f77c23924c58c667d27f3583fe5d5a9b752ada13b488c7b239070e4f96a68ddb2a93dbb6e1e2925df3db39f43f8578662af31d7e9f1e610a06276beb08cda42d6b1e946242a57580f5798e28f0a51e606c21a9207df275f367b63fc3d32e28edb8e519cac87590a9563ed4e3b7c945054bb587f063db61376099d6f887b5b48c877614b0d37f46c9bb50352554e5402dc017163c326cb2ad965f2521f41946905118d29c97c9c0f2c2d58b7587c4de77e217ac0dc40b9784796a33ae45c701437f68f60b7a5b0d804a41d6285ce6d5f6aa8346649a420cc2ec9fa6545f6424ac8b7a2a67e8b462985700a5f397e77c8e6fa181c3250bfab8a99e23fdeda +SHA3-256: 21b5d21ff563ed8a29a0c0141ac43f5cc26243faff158f2f33be84e0bf49bb54 +SHA3-512: 2f85d2fe4fa4314948dbac0e03c9d399df6ef93b7c9903b774665cc7f255d985b4f3c6f8f75d49884d4dde58af039fed474b11954d0b976d4ebd71a137a07636 +SHAKE-128: 0b95726ad716961daa6de1a85b9b0c5872b7716e5589df1869a24b5f04d828134bcc2c11fe62a45d1902d02fe19a32c17704feb1f893e52625373e05bf06329758ba91f1f9ebbdba6346ba60d94ae7b687b3bb51c6d05daa0c61b97192c77fba834a2d133a6695d44436747ae4e114bf601030c5f21ac4e2ac6ba7cafa393a7edae93c49719af6a10919bfecbf4028c325285fb0fc02509944506d474a814bb7ff191ccc639311e3aeb65a6e5e2a1f63a0519f5f46cbac947c67dc0dc9305ec942917aa90e6a4aefccda50bd011b43a1f408c17980c45e424712de7ce676f4afbd127de4f35b71a976fdfd37e2126cbb09a6a47194342449b65a4bdc70f54b76bf15c362eb70eac8e7e7f5f264ed4b658a2a02383a1bd618e313e28c690c807f8618c2b49ac5f8bdf2746ce8ed73dec21d6df347d28190b418c6300d010d3995feba5e8065de1947d0c3c617271134749e4134c9d59442c165f5a891fb34cbe4d7c395b634dc07af4543631c0d057b5fa0aeea4a7aceb9eeef5d06cdfa18109ddd15062ecd453e5a369bfee6296ef6214dff0c5065b34ae3271765802938fec36333b9b59c98de92ce476055ba42ee84761730682c22db5a92a90a8bb11f3bbd14bbeeb0921e3a29ebd31af8639385874a57b4048d5394695c6d44be47e6f18e156d59ee45735458b6dab61ce4ca68b286253e9140772eae53842c90f1c724d5 +SHAKE-256: d70bbe8013888eecd27eb7b3123ad98c01308fd51603ed876a4561c51b7d7c43f280d8f893b1902bc1601df797b3c45f2f4400b6dd99d9501b797a42234adfe6a31337f92092550651919c47ad0e060eaad6551cc8726ff89be253a96df4e9d6a63fb166658eab7b15ece3dce3559c970560aa767c69c2de00bc1d4bd08c23125db6406ccac19254e6129c4b81e90edd0a1985717414722a20114c327ff3509bd774b755a31ccbdcfd044242cc6d1e16465dc02c1dbac47b078e3d3d72cf9edaf5d84f62442c7d41c2c81ea5cc271bc73127823c4ac7c513ea0cbccf68a0e85d581846767782cbf7239a3e556f85ebe46d9408d1f8d659881489cfbe2924c4b01f825bc19a7ef3caaae4fd83d25e719cc524bd4a132f54e815e7b45760379d0f8feb83277b07ff65d4b0a698e3376b623b99b66e96a23707a344add4a7dc304529fa207485b1ce338f0245ff413bf1fb1b51853980fc067517b262510f1b063b9b8d8bf353f207b42fc056cd9bd48e78a94659e99b3bb24463cafc05abe46765bc1d8d1d931c828bdd4760ded7cd1963a7b952a0fdafdf99c5fb9c9ecd4d6b60263157adfab30344754b7db359eb7dfa3457ab4643fb4d2b90fdd1678693775c5f56bc533b5c7ce2229c58a1531b410f4cf0dc44cb2d8710ca3b85ec47daebf70e59fea0cdb213dfc4a0b8fcb53aab05d1ba36ba63c3e1a00ea611f02bcce5ce + +Input: 0a4eeef7f587d37bd13805a5834468009794d9998fbe6b50121007cf87754557e5c69793658e18aae9ca2563ba5c7fe7e444f7746fa8dfaad5adc88970853040f482117a0e466a976944c4fdd83a0095ebf717d1b7939781b18a56aa9fdb2bf55d108fdfe0e67d5200751a59b1c3ead6e7a77c9de569679f084e06b97e358c50f0274a969287c11c90f25d3fc04ee0bf70fa6eb5760222ae18fc2357ca33f9638441790fb0dce725eee36bce6e00b09368d3a4de48c12c365b575fa9f711ba69f1f5fb647705edc3c42fb8e4ed48496e5434b850929d073f62f52886f88c6d1dac2c703c8c017e2f32ef18085b962774159b7637b1c578b53b3f93a53c00b09a61556d92f434b691e86c9078c940db83d54d2dd459959934cce2c7bd3d45339941d93ee4f0b8228822b0a37879979430dddbc05baea980ef8c64c2d928f6828e6177a638d425f35aef61c50168c36d06f649cc56d6064e39bc6100aadda3c5c64204867aaa728830a9eb45c0c84fa341794d7e89ffaafe2451d841c73153aa138b95b088a729ab47fe1727a6cc26a3aaf71f9d6254b43928d51cf7603ecd101a00ddd9877d9c7de9d8323e38ed2313f57826c1ffb7f8625bd625ab785707a4f632903ba8c90e6dae616d55930d0ef00fdc85 +SHA3-256: 5df5e7ee932de137117767158d9989ba42bb91a6b8fc4b6a5d9215600b8f9b11 +SHA3-512: c6ae1871a09e8d0314cd40ed331dc4f5e77984c2824ba1893c310c8d26f7e7fdb34cd0730f3006be5791a149fd89a0a11bae13cb37b26800b46359e7bb83b87c +SHAKE-128: 1e489988215545383c0fb2db73c9bdce6abd7365459958abe206279c1846d272636c50133c1440a8b18a78a5214b4d05c85166bb475a19744bfaebb358c7108d38ab17651bf41e0c8a6fedacfaad00b65a19e1836763bd89b5a32c9b2a21b7c0264d4bf688e902de31c75d6ab8b1beebada0d8ed843f7d67239bae1070e2a7460de448dff5761455427d356a368be999d1be0b3675b767d27daa1abb2826e20816339d45b8ef1896e0b81a39afe294869db3d541f12dcda2f094a710a55c03bbc94b363e9f30fc2a60472026d0662c7f96916dab736f9f80f458c6af3a2374fa661cf375893e90fbee301604b62d15ca68b75c29f84f17458f615ece52b03690cbfecb71e2c91d84ac8607f3ea9e644edf6976cca86cabeb833b33957a84c23b64410bebb266fe88f55742931834b2e418518ba9974b5531f5ff17362ae45c3895511b0b0597515787b9018ddfa1b91d0e4cc19660808638332ad8e1581b0d6ab5fd9d7d749114063a6d41527f322f06b4c5069b80a5c70f218e5cf8f8e31959d0c4c8de9b471e8079bc7bde6e2fa12fe21a374137acf8667bcb8e8f5ed5edab83b6342bc12b3b33cc74b0b56d3584f28cb6cb085b240044f220c782932c33a1dc5cd45e9bf8b365c97695742c5bd46f4dadc313cfddcb7898175e811001c74d7d6e7105a3ca283ab31854a1a0652eaff69db7cb5e6b9b32baebf42bbe2e4dd8 +SHAKE-256: edc1f99bcd012a1984cbebfca245e208706ea771f80f273b349575244cf60101f0eed45d7f1f42f9ead69c9f0017b263d93ec7057d731ae6992bc659d629f3681d079e085d33e9952fb662292b28a6731a518f5bb223a4b8ddf391d2ce6fef87f6dfcd97a956b93d740d2398617f24b29aff3ec3ff49fa65967008e0d9be30ed01eacf5923ceb2f9cfe9a48087bc7608a931abdb5d557daf3eaca13b7f2e5eb3ffb7a26c3769cb318546430e48df773d502cb7faa031bfffe9b8685a014f8917c695893ea292176049bb5f26314cdbcfe9933958d5a40cab34f10ac4c2c051a19338530ca5c2ce7eaa493ac9e0a58a10cba24db76b2662a6afb2676913ad2d349c2c03bff3be4a3f39435248a1f2c24c0ad47c61f9550e4830cb06b21ac8c2e65d8958ab8e6d484be9cbe6354559ec912c327bdd866d9e183a08c8f79d87d7ce1be2b5d14db90eec1fb457e3f9b814c29fc47f38b2b42323f4654ecfff8b04e7003faa261203a5d6148da0fa1291096c7c942de68b42b0d343bb8d423d3624787d88e581768b8354a219d6f31f4949190b1c9b48b71d3e0c9ec75579a0db23789661b594eac56c4e342d1d96b2bb8c24faf5ab3ec932d768e6ea7b9a6cbae0e4d859b847b51ff90c5989cc42a99f8750d4c400a6a3fe861ce6976b6abd25e7271fd8b54f80cea1a6ee66503788f640be2f09aade1bd3a6132c15f5d5ef337800 + +Input: f58897f11205f51551cda59ef98b60239f7ad45c5c2ab42779795288226ad6a1363927279642424ba817e397b504ac4f5ced35fc936cee2c348b4c4c3c470a23fc21c0078e3914ffb34e8d726b482ef88da1ac1c0ff3bdcd99377589d55dad3362e194b7bde63d26d1217fa442b56c2931438197eca0071381c891bae734a95b3678e6dc5efa596dfa2a9ec6d2cebb495f51117bcc47458bd555e2c91c4bff2de629693fba30d20501959df6cda4e55e472bc46480237bb86d336651f8346a8c6e01a1f4c3b6f0da59f24181b94791ce6718d57aa3c0c8330abd0ebd85a0a2bc5bd1d3564ef265d0a3d4025ec2ebbbbf8a13fb5e177bdec54a69eb582fdc683a5e9a20b43ad5a13070e035d6cfe5820c0295320798f215a66c5b05f366d26d2f1f5f64668f476efb95bb9bf4c69d4c2bca09851f2bcbd3ee37f9618eacec75050be52fb1dd3bf5d8d1c0ca329b2dcc54c9d8e5cac8b81f75508c209eb121e760187a09f53191fe557ad598fd9245acd2751aea3bba2df26ef0cdcf9d3e53f028b86c8926e8f94b17b63160be71a6b963e4d6036893f16308abcc2644479b3dd7767a4721dea8e8fa76985061e88dd74a9fb6a9dd8071c391229fcba2cdcbd07b78554321382a8818a3267f40d73b791699ded5 +SHA3-256: ae8de1405cf8b05bdf368aca6c71092b9191b9d05cecd1e6cf165fb59245e712 +SHA3-512: 492312fe6b0becb235e8b9ef8a0e52c78fc8fc71c21a146343e76139215c48bf00a2136d72a6d14fddc718c238896d4a8e631b3ddb5b0fa3933b3d936672e9e6 +SHAKE-128: 089164a8cabd81dc48c86874caf9d6753dac5819db322dacf6c83145f78deadecd68de8c43dc748b97b3b83b34d11ed4b033f3a4d01f93d2087d0aa14dcb9d9a3191afcafcb12f80d8bb5c7ac4275d66bc50f58e67941dc9f5dc0245826f9a5b970d38a57a1cac206e0561203b29406901e9d435a81ffd453f817f5a75f5d65d0cba23e743369e9cbc72fca1c79b6415e6ed168fbb5f478cefcbc7c25f02ed600f71754da022c1aa2ac687c9f6d154a52f7642f370f85759d5d36fe2c0974ed086c2cfe2ad2be11e651fcdc74217250def92c7459e9b0c6a3c7221fc5997cc9db2703f5f1218a83dc16bdab40e6335ccf52478ad5df54540fee1045da44bda33e9a58452793abfe0c1c3dfce2ac08cee37878064ab02551284053c7b06883d6d5d332c2eabc7fdc59d9b5d7ff88b1b8cefb006ea49a9d0d95083225d590ee74f1b1b3f3ccae0433e5a364e7368de029a1404ec7f3370aaaadb1f455f2896720198a78118ce27ef3c04d2584535fddc1030f7604737fa9ff153c2bb9677309fa6b33cc74ef2fb423dd0f00d99fd6aa12f4d4d52de922cdc6ae727ed748f15f829b3630ae4210daf92ee57379d3cb9c7924f1d0788329fa9e4a8669fef546dd78bf35d8ee8080b1ad7a29b2d3370c8e680aa28e4e637df8205c89988810350bdc4351c9e264ac79950691e0ccdcf7c31dbdc855801c6104bb873a6d9b746ce420b +SHAKE-256: d9fc5139b5d52885d56239d990b4c97de3f29a5f9000104de75ed01fc5aad78a89447b37736aa9b87c49cd1433d567037f1fce3518098ef5064c6ea579e7cdb86c0b3eee38a5f7f99177f1c591f77f9524d141b896eb4368b703d0da74e3cbeef04c85ca4a15cb8510855f9834a4121a3f7c273caba338b87e8333fbbd9548c089da39d4d47e976aac16879c236b4d5ff2b1ee63fa51f44fc8cb52d622cfd60aeb06b573b1462780d4ade1b10f06f2a8ae56ef78cd6f84259b759115525731ff45592c5d9268ec7c9c640639d72d408f2941446fdfd61d527c56dbd64891610e1909e850a02bc6cb5c9feeefeba88cafceb244b180ec9be49a2d9f274df03cc9c5821a1fa906fe8730602318526210f5ab397a9a1a99ea597be291e65b0d377c5582ce1e8a530896ccd8e9bdd0c4bf171f7d131217d2f033f788042c17367d124b4e5b53cde3c1a8116821a74063bf6a2b70cbfaab3a7da1598ba3fd8094294134cea16b1a0d6aa5d07b2cf3f6659695a4887ea630f7af440fcf73c02d310bd9676c1b62aa56d4e1e7763dbd96ca4323be53c8482c1f7b4897e1855044fe5d9990899420565fdfcd6f62f2708828b1877f01c18e54efb005746274f212cbc134c5df741a763f55429f98b071fad1afb4418b8de457b8acaebe66ff5bd836a16b5d7aac967875c48cb576c227a9d0cc810da49108da85cd8b9bcbf6342b0394ce + +Input: e1448c56e1745fb3e57a55b833d91b019aaac1fa6a4d6d4ac6591dcd432f8ede40af8bca870baa4d1a80d66559bb631c0fe70e06c63fec8d39bba8036ab66caff5ff5c235d91cbd9aa505786e6ec28f1ed76230e068db928fde799f4dfaa37aac325f8222e4ed69273046fdf3d4b3d8938fe7ee4b9ca43100a932c3e053c477e2852da88d535842805baea37096398abcec20f974d7787b73ed82df49069ec39a5206c97bcf46c8f6e7a49041093d4af8101d3a7c796d148cee3cb6e389a4f7efdb44085fb735d61523715c38228ba83add965dc6fa4c07961bd0b843377c90e172292be69fd5b814274b484f1e5f3462b3cfd3ac3ab9e36fa5e1f274c74185936b3bc341e0a499338abc0e6a48340588cd69558d18897c5896bc5ec5c5978d43c14e6f483b70a16119ef49684500c4d787648003fc4bd23d7f687cb69de85ac28da723c34e27e478a611b707b99b2b217ad5555dfb2ed6700170aa452593fb76c6db747c84da6e3162164b14c569653dce6505b86b64b3e3265df875b259a141f2c98fd61b187ef8e8e99fcfb0c3786340701b2b600744d25da4ddef940487d8105f60296f2fc49cd4c31dcdc81265401e83c568a5b3c945e0a6bbf03700fa2b8ef6cc28df9d2ee428abd229ec19a90c7c3d44d +SHA3-256: 10cceada33309f79509c42b4bc162a8e3fca667dde693ec4d497f484771331dc +SHA3-512: dc1843bbdfe0772395bfe9de0929b7c426cf97843d940658af2dd0ca7193931d77bab8aa401ea04c914a0d063d1b231dbd04ba12c9683edb5d337c620674ad99 +SHAKE-128: f91b1e584908a6642b756d23103e7f02c55c1a2ce02a484f82c6e6707fb15b326523bb094f78f511e87e46eba362f790db4ed0193c240c3277cac62ec8833402a9b5517ea6e290c770edb85c7ab534bddb2708455f61bbfd5fe9b4dbeed817b09fc566a8c3061a4442d1f8706d7afc42712deb5331b5c1adac716c3227e3de8118dfa7e44633a2c893a2a5ff11f75fd884ed04d996ac1c8ad228714c6db8b3dd6b2def1ab060937200ee3a5a97704be6bb0a276b93fb025a4f759a736f9fc1270f157bd401570f62e90b05a6d2e7227494bfe8f404e921eb7c1278f9826f703824b542ee9b357a0d1fb7dbd2cd82a092a040f5e7cf968b47309fec8e335601a0cfe611789a161d552a13dcc335b12edd935dfb36856b865f257a9175c84cdda317ca30bc60df8a72254c1372bea1869997505db62d894ff7be0916f3e17972767155c134b65949a254b280d0b1cbae2f0702e3261c570ba57e8b10e16a22fbbab84fbb02865aaeff0c0854c230c2fb90aaa4939b5f58181bec077b7c8ecb05a10a46d6f625dc8e0174cc3a2810bc44686c72ecc60ec655b79064cef00bdbf6714b3635a65ac56dda0efe1bc0e9a2831ff69226119204970e850e92187c88234e62241ca1971402937f8abd9a3cc1b8aa308e35023158412daf5cca2000f02ac4442cc7c0a60070b50cbefafb8d8e94b0bcc2f767875d0dffe97bdb00328c76b9 +SHAKE-256: 7c58f3121ab3a48a587f25af2e132ef50fd869eab9952ce9c06cff6b799e7a174a8666f9362e4873074164557a5979451823b7b0d1ee30fc24c27dcbe491dab96f4af28e08fa55e7049e539eb75b9dc7472bb70cb1dd548f1404350d378457352e9cfac79b53606400dcf58866af8aedd55bf916b8fbb4d239d158bf407ac64ce8e9dd6800a9fcbc3b29f246cc1d537ba0a3c89b26495c451acc46c35f7480ba7774d72f5d1e2a1d1526a049b4aa8eba30cb0e23263b93913aae1a36e63b7c582bd7deb189e55b10c8f8c487a128bad5f212952bb2caadcf33faef2854dacb5a745ebfdd661c2b54eef5d2f9d71cd46e1c443bcb413a51eb66288ebca054d7a820574852b8fa56c22d077f9a220894bb0863b6ba3c120ffb38988330a8b837523c9cb4e1cfe4e03f3d61b4e15c049b175b7e5286f5433b5846719246a0ed9f055ed93eb4ae461d902d860d164162f5abbf6aa1ce33e3a2788072c6b5d66c4061388cc39aeba1a98f7c6bdd8f19a91efe7fcdace4c69578981586ea089c4e7f1e62859f07f582a21fde18618717f3e4d2db651468a54a1fcccc27dcd03c423145942db0fb3c5bfb1166ac90ea5aeb34a7f34c5a8987ddb23ab33e391dd512ac4ba5426ad4e672b65a21c5de3548b3e5aa51921ed765571f41bc72e9a86581744982a4c804c357cd7cb5064fb7d8556dbf92ff9735c3d103a76bca9872af40a4a4 + +Input: 7e2611292b81669b9ccd37ca0de1a45856160d2db246f8c2bfd717f346566b87046d1e4a41b131403f6e730b3c7a7daa412fb2e55eb912886d871d4dab186654eac9b5e3843ee76ca8e4dee167977cdf27dbde4094e770ad97aab1ed1a9be485dce2eac76c38187778e1de0db67b8fdf7ab83984b00089302f15d84a7c34c7614b47ddccc9ccfa13bb24082d5fa3f90a79fecc647498f242f7ae5811a746d2b1c93994981e089953ec284d669c1a9eca9d879888b2354fe1ca439568e7477071c37ec6bdb31a3fd562455d15beff2ccefb59a911d6189f74b18c593cee487e063bd7ec32a29492aa400fc974a86d0e7109bd2717f4ded25636c8a08de051b572aae7e8842f0b11b8d0aab5c753e9b7994a3c7966ebe070610f8be21008740574344cd01e9e6ef66e22b2e5f68f7eb259eede3b4a277083988505aaabf7116bf90c7efff7836f8aa9afd2e9cb9766d28f6bcbd27354172e6a8f5f7f6bb5b6c5731771a0395ee4cf3dc5a15936c6c07c47e8915f673e6991acfa488eb1624a53d72951be550c4817b42121181e56107d6875ec4c40f1efed48acdf91c65026881e0cb0aec2387a3340f327ebe940b41f637e2f23e2a6c50affda87a42557539d3dc752277d806bee8d3240577d4b797a28c607d027ed +SHA3-256: 6551ed29edf7f4cbc452631a954245d031b78a21f5dee6155e2fda5545c75f8b +SHA3-512: 7bb64b19057191f5a1dc109407b78e69ff24e2b45cb054e353d93b76382d2df6e620a238d0df346aad68806ab6375a4116b27b12c7bc23d5b67e7d4353a150e9 +SHAKE-128: e21fd71ca9971a8d84d7563f4192855fc45bde06197ada772374a4fe003778dc5c3cf62ca96211df6694085db8ea36e08da72a88e131cd58862b2bb6bdf62497c6a032a908f19f4a466c212fa0f535b2cc6ff333d7f75ff89af957dd08afe526526f96acf8d56cd1b10ba735948b4239275b04eeec6541ef069d565ef63d4e277f5c1019edd03c410049795866e67a8c213d9e0a0c02ff3530604fa36d55720a1e893545645cfae92a89a34f12e12be738143efae5a013754a7a84bc6f7a2cc1ae9f819b70c087c2f633915760959079365bf7042c6711d7ad11d5b7c171ff780ba60ed52805677f8f95d92aa8b0492a778fedf9361f49a842de249b3b62863efebce1e1a7faa1bb6579132513a3df64b02f25eafbeec1f28396c398b70f03af5178c4733842193421c4ef6ab63296a1d062d743552f281059b0320085a12e4d64c8dbd42a9852975d66a7b8c61f96dcb83eb9f6a38941dac4577058f27bdfc26b6728cac8f7b1fe450f930de5ef9acd8ed641d11b683bdc3e72be6555874be2b921969632cacf9b1ee6e1e4ecaa8bbb492608a00a2047ce2eec40931463c4245e47e7f0eae72fefb8fee337bec96ba7d27f1d3e178826164f1d2c36a5f40c59d18a2d1e184b58547bfa5ff93b271be5760c0c0069def021957f8724350e08687dffe0386570a401118b884dcd3df5634d0f84890cc07fad2ef94f542167752e +SHAKE-256: bef00eeab6ec2dc691ab95ddf71b4bcdfa2706c7b7d76c3142c28e98c434e6c98b979c81f17c09588393a8088fb6f468022c1b299247fcddb4eb1cc132dee0be837882a388830124fe0b6986ab96c3ce24732a2f9d55d7f1c09671f9d25606d50d5c9782b48f44c6f0ca1852941108d3cd97ab7e9e924450c64067f1b2403afc1cf94d87612b4657372009919a8c4721b33926f281adeb0f4e40a36a636c0031a25290d8ce1df26580cffbadc4b96426be3d98dbb0607e10d818ca1414f512e28dfbd87f01e905a19a89424140d054945ff9e9f5fd43af2eb77addd43bfb3a6ccd5ae032edf73cfef80830275f2bd84a848c5731ef0dfdc08866e813d0f05efd31b158e84d45b7786066367551aa1fa0b32379d4aebd56a3ca4153ea7d8513256d01b0c5f1431e9a4d57190c63973b0e6bbddff2acf105c6d0b7c129636841b81e1df005bb4d805a75e1bff081c07d743ba94ab0cb85feb03d3440a92bd81225c8042fc5f9ed18de0b3bd901066aa53eaee9a052cfb47de80e5ce899ba315a6729df9d22789eb2709ef3e5bf88f3867708c7e14c47080d55f4e35f87738d78fadf5bf848fdcce61677328d7099dba84a86aeda31891eb3b651ec0ff3642edb4f9ff0ebc4216bc94ce2d629ef867bc90405ba4072445e7de0390342c97273cca1c4913f9342ba98ced643e43c3fcc04b9259b2e27d220476b4b404b3915838ef4 + +Input: d79305431715aeb9f49b1965f42a4f115fc057c5e7de542a473452554a602d7eef7b0cf3e635d0de3a86cbcd93c9bb4e64a51d0b1591b8c1a6e8adf5d7ae16e75a92d26ce664ba3288747c64276597f347051eb811a5f2ad35b52bd424d9841d534da1a37f3719a9fbef9432f872fab3e82def2226d823002d14f7f7a37985561eadcca23fa0196626c2de248d1c124fd9ba9d1ab753eb572f11712f518fc10876324dc44f3a01a5ffbe1912838e6be2ab6a685c1a029d10cb6ac109f1d7c0ef91ab17af72f170b062814446ae36675d678e16bcfb3af79007b2f559b4f44aab2657d8807435722981702b067e1cde8b431cdd09a84be1661937003f2a826554a54ce58c021011272ca5e63ded90ff6090c546e443313640a23faa8297a2154ce38e2cc0fc6e386101d09789f7f8dcddb004052d7c4150176da8c085cab0718959a04d1972f3b9367fc2d4d79437923a05a229eb08d062be956405f7978b6d2d4184d6454e6fe1815e3a46e7d957cdd735b4b4439577c37eea5ce5a716cb54acbc8d840e60b67fff52d4ce130342acc06864e93b29964803be4751931619860b79b02c2bd6e10e4850b07212d356a113526065d1922ef4bafc48fa6b65a4e5af5605a2d146d0e0d0afdc8d0bea6576a64f17fa5fe290 +SHA3-256: 9cfecd7a040ae0794a394e8950e7b84745758ba85118788ccab2aa676e303c09 +SHA3-512: ebd88a0043b7c70b8a5cd9636b1892bace25b292e982e921b0237d4f06f3a1df8598a71594130d1b1bf7acb4e1cbff71b97a9184d443277824cfe4ceb9d1d686 +SHAKE-128: 5b00d7a8e5055e288fc558230afacc23074f2d75b498cc13b40672ed0d2913710c84c99206be27e646d785f34f2355c56ce78a17e90b71e54b9cd7ddb90464249475b95ee67eef6468c7880cd32deed707c77c29e57215e0d1d04ca21e7f03d4e75bfe94a675b4cb32c630f7572d432e2dcd97081a6e9896a551bae648803bbe71048a4d356521383545a741a91483fbf356d752914371cd4768bdc035d795272c7888c00a0a4077ba1bba13e7dbb5e5add5fc31665bec333486227421e117b12b8ef65040b9739a3a24ef382b66fd064564a53be12ff11cee76f624650c0a3e55cf14c8e03725ac158ba13971856780008d016ceb777e37cec8778f08682dcf8a9b48b7d02d97f1119b4b161be7172708ddd16d396b9cb6ecd3d159bd338558779dd996d8f721830c5280af737e9a5c0dcd8c9a32de26a34524f563a68c99b4ff4974ecdb9fbd1cf3d15a4b4e9b7776ce864ddeef464c8b9f9e8096052203053ebed168630d00465c27b9534ad82570fb9db4edc5b95fe4ecb90e91a768a196a3b241b0f27b27bd5ebc0e6e7ff1bc0a2dfe3c7e340da66f967ee428b5f77e8c1a606f036c0a1bfaae24e77f05e63dbb5e5f755d49ba8d14fcf39ad7922f8c5bd5905a5b055efb46ae9b5c583babc56fc8b8ff191f7436fab26d66a8ad9149c795c9052b6cad9b86c224a68c5028a4add4ccc58c3c373f2d06fcc6eedeceddfc +SHAKE-256: b40cd7e20c8e8f1dca5debdd31cfe76ad476b40e146591c2403e02ad45335cfedf43295f08c0ff95af59ff7c663031692f47c7d9c18947bfc13d42e9d46dad2f748e6ecd5770def84706a44922076e9be2a978ef83f80f92f639ca8dbe5ae6dccd69bd83b8b92606bd0afc370f78babe901fd2815cdb87709bae449a8306eb2a05c4c1f3622ed49908d651e45674496831fca97bbd1df45d9095ed39833b2586c9204c10961fc9e8955ae6b133dd6848ec349d8690ecd180580c3ff8b15a3734183bc906375a03d565c018617cb4c0772479f06751b226bf1e127f485504ac818c0b626e9ce64837b2190a6fb72bd54e5c7becb9b0c2045cfd7bba6fad457a257ce90123c66f1de5c9f5e637adf1ee00f927ad185ef57097116e02ef5231e29fed0d680937883c57cf9f404a9b03bc465fa2451ee849a72b886623ad4634ea661c30eccae577ba9a1cfcfce216d310cbfcb5355b450f7ce9a114af4fd558e44a584cbe65e2fc90cf6560135502ded17a27b3f89b8b58d0d3d603b240a12b170ccf10c35378648f8e7875d51a14047926c020e5dc8f3940836fb29422f5667e27eab27cc26fad67603ff86a9fcb7d8206f12176a805ef0218614d986abce39a3b932fcf37dd13ac0a64bd4409a2a2ac7b6c12e7ee3de5e8077ee8cba33e093a4bf0b6fe9640454ccdb9b00cc2d0fb4d18485e274701e3f98f0f816831f39f46aa + +Input: 27307e40885857ca1eb7de738aeec72e358524d4a0a9e16100f0ab8064d8f43d5d4eded3a147c3f5e83457093181dab376d491c8c87b82ba9d7f40549bffac7ed567da7380dbc842061e16a680865074060687aebdf100af5f91b67e60dbed6697e809c1381563656280461d615b99de65711d9178fae6056f64cdc3a467c4f44ae4f354e7b3df767d16ecd7e517497ba6eadd3fa567fc3eb8bb195a94782f9e58209280381dacfbd16e37ab5ad1be7fb53c4417ff002cb8de720c3db80e920dfe6ebbd4e61138b91dbe8cdc2d28affe4933827c4963afa25c78929bcb5c47b8a0cc4a64d0a96105b1c906a106d4e00e3bb68c1b00d509e69f88e09b2710249f9c1a0fbc7580ad6a597aedd004c21e9a33d1447721004f8c73f4c840f2d068019905bf6e256a3eb7f0d12fa7ef1f167c21bfb9cc6fb4ced073276f4272cb36603013e4f58cb7ee6bd41bd33ec73c8750aa76fd8a5ba137ef4e010688ce3f4a90d9c98594ab6902a16db6c680ac2c129efc3e5e73dd7e27722f23a00ddeea7287a37e7eaa5eb9ea9efe7b256b89d51a87a5ad2935845317e475671810bab7a983ff88bdf04b24b07e96baf57dcadf4eec641dd770eaef7c9bfa0cf340160884a12adff657cb8023869169f3e82f483dddc8d7c265a5ce59 +SHA3-256: 0f8a4b9d5ce645edd4b7b15553f6bab89afb5da329dab255394260e61d3bf16a +SHA3-512: cffb14381196c3809a5db4f458af1f9878ea5c388b8d75cbb95243d70199ddeefdb5a6012736f34626e11bcc975e161535bf7727a951f3787ded8e881481fb99 +SHAKE-128: fc532547f135988c2a888b33290f6c2e5728a5e0bb6c3b147bb0529afe86f2c1cfcdcda00d4553edee763a3138c9ba32aa6ae866eebd5ed77fb028c1038ca0265cc61d97367ab1dd3b0e48a86dd9b952568d8b8919c1a0e3b2b9ac0b5e9ef597439601ea12464bcc23e0425e018cce33924346c6aa52c2ab52c7f7d837776d82c42913e55a24a3fd405ceaa682afd4b82855886e599f1d6634d5f1b2dde8495142144de6e61a81ff64d6ffb6c2c8939d9741c79f92d1fbd1db59c4669b0e478df98aeb9d2403de2f124354ce4172697a7322d13a8ec3a38810a1e9d548b4144fc805a4278476a8accd61b1a3c28a107b3abc9693a1d3bf729962e11df7560b2ec8d4fce98a10e651077e05128e7232c9dd111f6fc508876bf9f3b3ccbbd650c9ae609a2d424c550d4d90486af30097e6541b2ad3eadb5dc952e46bd389055b3ff6979f0ac43fdd598c0183ab6fc172a20f9a62c2a3f921e244a619c367503e8038bee73e2473280699fa775bef5728f48df836adf3fc0a97eef252bb0681139e84f99df2d79f4ad739edc26229dab01c813180be86c47218fae684eed0673e4d16a4678da148882f39da47f237a44bb85bd72d0825a7f086403b113069da98849dbcd5bd7a0c303e7c05c787e4d5d5edc4269c377092ffc93f87adaf322f0d0b56386d8f02ca2cac86508a1b986c9d2968ce32c4436c3aa29ebba06c1a124846 +SHAKE-256: 48b282bf43c4d4e8059f9afa77e7ee6bea9fb84b58bb15bf040ffa244d4bcff81fa7677159885c86c862fd0510357d0f63691f0c583b924052770a0359c5fde45ab4ff7aae727e5ad4560f8b6afa36a70d69acfa3d22cb12fc4f9b6d295d5cf02f7198821c39eaa23052d90dbde6b79e54b9a54efea90bdab219e1ff9aa5d6ae6e5931e419fa0d1a2fe8d595a631346b7bcaacddd831fcee981ca9ce9a5f1c98904ada4030a1039be0463eee273b15c0541dc39664e5704a046b1d1f0b72a7ca35233bfa14e7860578416403d2de9c6627f5afa93477252244cb911cc3a1ce212c20cf9d2bb66bfb940c3b7fd99df8db2df718d7e68f1050bfd5457ae0d289b8e13c4e2fbbca659e79e40b9bf0213391815ba7b69f9730c6000290ab3a670b7255df123700bb8a3dfedbd4dfba063956fd3f02d247a6cc648116063d28de81376d0835722fd5c8e76bd3d4774623c94319ae968f29bf8ae2f99d4aea602ab81aedcb3b70fb807a4591cd992d0de6fd8ee39459ad11636530d7554cbba85fb3f974386392e37286aa2372c106d20baa8d7b8e217cb101e03ef9f75f7c5ccbeb10214797de0b477cb38ddcc4b2ac2f33f176038cd4c6db34e204ae0451ff0766d2cc630fe7c85076c95f26a457f93fc34624a1d27bac4006c041d4bf0ebb3bb5ff4bccab659f557f5926fdf54ea5d12e3e990131bba12eebb4be96796752305c06 + +Input: e61d3bebe9f35801eab9e3057e10817a37f87c4ca137c10dbfe957ca3f89fbd97716fa6f6dc8e7c5084fa76a637fa12826dca88ca430c99e06ec1a8877b3065f694eccad8ddf20d70b6daa6679ab18f68156eeefaf2c779c2f7264e50a36fb26567f762ca102378dc27cab4f2e4cc94a035c8b2f1a5f378c74acc6e2b5edd89a447e690437666c3e010abe4284a4dbeaf8fb9534297e5e8a2f3388abd329d2375a036dcdb8ad121c9af6c3f0a8f4fc376cc8f722c2de3f847db74c0c9b2d98c799c55865bfea378ec8b1ca00455b8dd06331e2559083c16400c51f591dc282d66ca4635b4ac4330de455d4a7af027cf274dd0c962370b6e26f199249a3e8445a22534b5819a2dce26a7958f645c6a713e92fdc16dd52223e5c1e0e1ccfc2840dfa7c2b49bb23d0ac65ebb5ad143a5f591c6de3f094f448fd2e0a74da2f7cdcda360743de7f0ee30ff38ec8a0ffffad137044b8b93c30ac308f64c97a9377d900fe07a530fc7e23486575346b725413b1e9af902fc083d7d68d268a8eb4a39c19d8a93db8f2ab910dd7b060f875d68e851fe1b69a8e75a64fbaa49c342c7111144c95511454d626fcf689a3e764629b15af5bdb6958a23f3e58ed4ba66ca3fa6777f2695ef2d69c24aa92748fcdcb588d48452c0c924175b6 +SHA3-256: 187d3e3331d3157198ed7e910c4d95a1c187504468383e607baa5548d7e6a5c2 +SHA3-512: bca0154b4a797cfde18ea0d2fe1ccb90181df22f85e86fe3f50660b936d42840b51078fd7a2b2009fcc4268b8b363c1595d1a21c6fe536bba793cef8cd7fd7af +SHAKE-128: 27ba1160e90da4382273490ccc1c381f044a82d11dd9bbbf0268d764d192959dbb498d9045fa4e005b991b30c31e8b12cc7ed90a7414bfb12ef92b0716a2282e072584681877ed1869ed5ff30ae788ea06aa561fef372adbbfafcaf7dec30ac0356b3571515a421728a9c9b6316ebd3db2038b658f2936fdb65ef22fc349632e4c29eadca4cd6e12e3b66bafd8abc46ac24f230685614bde3872b3b21200f6398e0d143a5ecb4a169872b0969e44692531d0124642e48cd4d0968d9e0041ea297511305f6b4976e6a34368ed26b65108830a6b439aecb5fa964edc54a8cec99f9100c1f101d5d98367ec04df399f714accc7111a8019f8a857d3ec1741847c96e23e1be330d67f7e0eac246511424b5ef41cb18649b202e23b41e43f991a2e49f507fe437cda923371717db33a5a6a056a00aa2d861ce2e1352cafa7e529e478d00c2994cefbb2d14ec74568d1df7f8c0f8ea24dcb05f3d0f98b30f36a60605d1d3d7be55c5d8fcb1a380ac2eb1abbbb25f28304e17ddce15ab163f5aeca5f12c25a908231ba485207e4471f6105f3894e9470bf8711bef0925e49ec58a48ee869ad8e60b4317215321e07161c713970ae692a008e7304ef6c17ef4e248238c62f357240f1065b35a907c326d528c8529b703a382bfea504eea9b390a522d45d1645f3f5e7d47f2ebf152fcbf352bf6f48f9ac2cbaa6d067bf072c89caea152b +SHAKE-256: a20f0ecfa25a0dc4ea3ee9f192bd368420558864cc242d76e168ab5f54eb9df8fdfb4a00a69a4e96610488a42902b1b5aa5e4f72a9f343dbe45515bb27dfd76c7f968c08b3e91695f69f736195d49fe7ea36627402c4c2b2b5e954354c8991412c6e8deb561bfa796a07d507b298182e1f6a19f52d98adf5f00e3f7a3312b3b7fe28b58aa4c303166ef926e4634b8743a92a8e1f089f313fe860dd59fd9a53f9b897f8be65737e7f8e2ff89545b734db4c349b3a00219e45ecd54fbb0c8090607ccad6aff0c571dc7abf198d5d1bb45a0167c284be46f2000d7af794a06bc25faa9be1776a99a93afde9e6f70b5157b049c9231ed94b9365712de8ff0b0d2534f5df92be0e913285e6aef03deec9718b039f4e35cb9fe54e727e2671e71f7df4f5873abaf8f994736d73dac6047702bdc7af7f66f6673199573baf06f8ac552be4d78f4db1ba8189f2dd230f47f6b14c974e12ebda61eefba1400a987d17524c4060c7f42729b5e6005d9c00ee503d1ad851d091df1ec302813f33fd4e9da4136059c1ebdee6d33f0e350d553e25390b03a13bbbe4dfc88a0068a039320f27f18aa460c9e5577431699387b75c2bd536c0fb000370f0e1ca131630f733b1a7b7a1dab67573ba9462f18f927f3bbdbb334911144f6d4a6f1063b18a4da596e7eb225309aaa547b364a3520b36ffb93654ff8ce165e02fcdd942b247aede4c7e5a + +Input: e8e220ccbe1cbb8d069b01c77d9d46eacc61c2473c3a2b802264506c86fa8c971288546efc6ac8fe14ba9c1a9ce46c28cf87d07c4c380ad342b35b975706b9306d133d1db83b4e517362bd00472a0a5eb06520cd23f039c43c7ac627163836681ca6b6e2e733eb0f6ea0d152ee23172834236fabee5d9914340bd743a458cf3daa0e937e229ac6425781db7378db711df0a6be6512f489822772f252ebbadfb1ffe0db369589f4d1b26f74e02363f1b837db130722d24a34be760d8bec1cdf6dbc9f924be8d6e2e40043298ece5aeab2331375f7bcb7f42fb25cdf6b5f8a0f520e3ed8081cbb5dbf6b61afab36f51769c395305717ca9e842d5b4ded265444491ab58765557375d0aef1e29739ff1e9d381e0aee4aafa8ae706dc52dfa0dfca098816e23c4bff7e83ddcfc1c3ca2f7c5530cc171bc1bc28692c51d4e917979f738674dcbf1da5d22e849255faaeb44ed2e0204fae65010037904090127f7afa2ac977050e516fd4436a8fa6fbfd8dc5463e229d7f3a0569cf89ff11253cae61aba47c3d67eaacfcea4139605dd495d72e91edb5e5f5aae9de4cbeada7393489cd7e222b14d20a9f42db0e7c4b7f0637a57def3686f786cf8b49d1d1719e90ab742bc84fd9c49eb40d952046a911eeb5f5032cb7961d788c8b4 +SHA3-256: 51f97563623fc8bdc42706eb06ae40614c916b9580fc86242db6cdf7f7c4f4b9 +SHA3-512: 41dba5e136c6c3d49a8fd76006b00f4aaedee5c378ad68027e221311017d4ef688c411d03d51112f5e7c059a01dd74a838f4bb2af38f752c76360f0b92792a83 +SHAKE-128: 2baedc8c5fa56a99a4f345d3beefcf7a40682da91b13246e1eacaa1dfd05b3097a7d9b411d769e37e674fe15844eb41a1ad154a136d4c113c29bf9c2ecee2f498805c50914b150a39a741236bd23e3109021638a305dba6325a9c349dbcb150296f3f3f5ce7ffe226b4cf99a41be170426624ed8816df7411d655beb7c4a785c375f865faae2c55dc9f84980c889845e474f915cb15c12ae43cb2631dce2f1d0e865b9072cc8727414a6d00bbe4b916164f25d64764aab0a70094534bc55c641c9402b88c7d03408874b665be20fff58fa5e021fed2c279f1ee7859ead7ee173f44a3e104d481ce2c718d86e2fb6a9bee0c535cafa12ddf47ea272d12066ad6ec8539ca474a7dae60de64abfe5bd5a2a2141bc4cf5c2b4d1f6b2ee3f5bb9cc700da11a57fdd00fdeb649c43745af6f0903e911a3388b25b7daba5499a958c306654e2b71c27bdec2ca306c9fc16ecb65a37947e2b7364a8b138c7f5c59ffa22b5e02929606a30b2c2c9ee8b96bc5793a7bf8d3a13ec669f472c4a052b37a24ca866bbca5689927cd8d6f373618a7c5d4e38e82055d906f47c4e121a7d56fa4ca953864cf4cb36621eec3229853235f0d651ee63ebfe393dca0f9d8bc2462b39001d8ba22b4201b3abeeead01905011cadda624280ac8a8e821b70dd04359bd658d3cd838059bede2853f63ecedcfece37b566b45722f2a7cf1ff9527a577c777 +SHAKE-256: 6745d503ff3e061f782928500ca062e6d4381884d00886c492c62a6c5899b0cac187c5bbe3f593bea2afb52e9a58934050e9e988ca149f2037578d76cd31728b1e901ce7281d32641fc0309841693b69c3659c558f16a1a8b46483f3076962bfbe599845115e4752216d5dc341212bfbfa14ce742dedcc99114c7b9e47c4a4e0c5cbd482bb920ff351937bb4ce6d1fc09e0915c6005f09312bc7465e0ab3fd2ea3c8f199628d761617c2cad4eb1f09b83e62270f57ca105666a40f8fda376e95c9917de5a090049c50be5efa6bb369aa19a8c099abec64b330d3b04ea8056f25a2851a7290e00295017560158ef1f7a3b7d3eab841faa77b64c9541e8675a56a3f5a694aef70946c1ed2c8e05791793d52521b0bc8896782ecec4bca6e584536bcd7b2c21365b101fd71bda6384ca2fde1819e1d21eee07e58dc46066ee30b1fba34437c7db373c60b8fed2e0c8185076f0fe777b4039f2c05a909c014c7f7517d2d8cb2291e068571fcd1611307b2c48128d7506704cd89b526f55aa77cad3ba367969b8a5478b9160ae15898526dc4d5685a2184c6252597e27aa9c2c6a90892e9608e11160a69c8afa3f0fb4522f394e613dc3ae03c5667a7c0e690fa0cc1996c1e434fd2ff185ecc8caae1887de628d71900d02c6b1aba83eca54ff04203d9bc097f4928db55608d0559941a810ba7e79faef70f0cbd36efc84791eae393 + +Input: b4d3022bcb91f04ac30fee0d98424251bf4d3da3a56bb59586a4e8fa371504532be89a2dd8755644050ba116906b81ad3b8a8cc3dce0eef3a1d92cfabf64f18ffe8ae728e0dd574deca6212fe8d81e9e6e483a8a2c834c9dbfeffc83ac2d40a3dbaa1b474136a33a069898cf8659e7685275a6814ed123ca9ff8070f2ddb94d8d3c4fdfa4c93fdc3504bc41de38e554e82f8d00b6b42962a3d11c8fb392652d97dc25f0f541723f54739149777704feec6763954f209a70b3f767719b5b4dd95ccd665d4587588fca31023abc70e0fbc6ce0040ab11a61a18b38e58967e4669e0891f20241e3d5e1331a80a4387564d59abe6027cd587f0c9abd0aaaeb2428de74708b6faca5f92d08d9e6ae2cea3a82193e240b27d455364e3d32fc7fd7620393e071305684c089c524d8c5949fefc7a65b814c161207130ae2d43473394446724fd98ce6b1ee179493f979b72c9ad244da0487792efb8d5693ea0f4eeb3fb94d6e609b3e343b2e9598f6afaf4960bb65cc659c23d2d725e25fa2e2fc4ffc79a89fbf65334c575704b27af7db94c9be07b2ce90c8201ac831ae365c6212f1a99852950432c54d2daa8c2608639d30e80ece969124adb23a29239288aa60081e3c1975aac27ab6c83e2318452c2d9a13d048e4d1bf113064020e +SHA3-256: a6e3f8528c0d781ad16f0a513371748381399d670f1fa7bb0a4f1461157a36fb +SHA3-512: 881bea53700f2b432ca4b905253737d54f9d59e6ca2bc312538f6c3b435869a386e717a6b8eb5aba6e1ed1b038eff85ccbf87670dd7c455fe0caef41d1d8f472 +SHAKE-128: 422a2bae7876bbf45c6d237fef8abf5f7d0cd5a58f4e013638cb57fd9a2053233bc5334c6f4c3116d83f84f0fda902a4152d56009dedd89ec45f3d870dcc92531351e2ae4da7d92426a31e86a45ce937c1c1a8c69768ec019341fa3c681a72307cfd218e12716bb668d39eb75e295bf3c7d1454fc8df0777f4673eec1016b5c9050745712ea5a8d95271b96ea18490918a5b6acbdfb8cbf23f6526a932059415829dd57c79d96932af942218c9014d96c4108610b7618026528b06ba363de76cdf9548084c55c38535acdc25b6a1bfb97004bbd817b3a3df3d22f81b75447116d1ca91c1f7822350ed1762344b796919c568b7fe053aa2ec9df921e32c4179281c36c03feb87ca4d09cdb2bd120e0e6dcb0cccb8e54d4555286a10023584530de28c14f580420e90b7b8eb634b527c9dc0d3cea0c4858922ab2032426523e3bfd954d2c6fd87b33e51951cf957a388254886407e161a83b9688383168475a87f196e0a5e33737b2944cb42d175efe5693f2de0289555f573de0f58f9dcb851787cfe79a11ef9913fb198d342d80faf1d44ac39a0af5a3d30445dde667f268cbe2f6e2f43d3e43a81259f0761f54dd8d22b3ecc88699069bb6c339d4ccbe58dba76405ea841548bfdf124485cf99ae94d766249dc8d1b05dcea4d82b0084dade144007cd58f748eb10f7f2e51dbabaa57eb77f55f93c2f494894fa8dd98929233 +SHAKE-256: c5f9e06a5b94001e4d3069e6169880baf40a710120cfdf186f931be3961d5a3c2fb19cb4e0282f22ce5c23d14fdc4efeca833af354c692fcf821b8a7a83fb2b8e6740968ee24f33e37be74226cac135f7370c024c1558b974bdb0e00c1b92aab705c33cbb0ca15e302d987dd45c28417341d5ee66d66b884353d5689126f10371b667d7fa9032082f2bd0c443e778d5c1b375b007e809a9013ea5c74b74e666ef44221756df4bc6f4829a39ad2b36ff1c5794b5b45ab279f39955a1c0a98ef0d7082b56ec2b3b81ca6b68f574146dc489ee2e46b6a9fd9120b0579d26d90723560b86f1b3e53c5302843a46f17ebfc4a89ae0406ca5c665f1400fecbf90f3b8926accff86b9eb3c3917cccfd3e715d3e2521ce1061b08cc0dce16c94fc82d3a708f9520e17c02862ec57ac8c47799d944a93591c18f6da7e38fbad41f559a8bf0a1f572caa22b1ee4684abaaa26ccead04db40457cb4ad3a58f694e22968f50a3b18b87ba570e229d6dae7633a36d8104835c7ff48197aabe22328db88e9f986c5ef138ce16b362d0f80fe2d4455efd718c3de382d2bd0ac91a7c03119db65751610266fe586094ed0203864b5ef04f95d2b5cb4e1fc1fe572373442c2f1d197d17aa3ae5f9e65a8996dad8720b9ab00dd52a643525c627c93d77fbba03befd6a3785c01ac6b400f9d558999fd40d70741079a76321b8c576aff70f60b6eaeaf + +Input: 6507dfc3a836e0675fe761c5ec3ac804211cdbbd3bd79786fac74bfcd17dbd6a15514c818390b773288bc0235b31c6c99e272d31fcaef739fdf9894de347930cd1f21a78ba34c3216a48987c85dcea8a6a231f109786f46096279a0ca179940d724811b7f14d43bd91e9baffbfde07f61902e2d9581af09cf8dac29a4ae4566872f93e9aa33ab3bb119a618684a2fd5a64f5bc5c9552ae2434f6a3c421a1ecfd1dfa3f100dc3df71987b3c4ebe6ba4cfadbe229c11936690a581c48a7e52b5028b0d489ae5b2cd0eb95f140617aefef344f585616aaf76361c3bb0428fa6ff42a30c0f41d7a2247d0da38172b9f05ab80356ff7bfdb5a44f2256a490d01df9dbbb1608bcbadec05a79934dab1d8f400ae92a90919d8b4f9f3ee8a23b6cae3cfe5da3b2a0b45c624d0ccf42de72b012897e5a2eb0eabbf4576542f6cab3aeb95cfcd9f38b3d169d37213c4cc5319a24b48eb12f54aa993268f3334497ad9f36bc9e91cb4076704160c3a23641ef2afaa88fc7850b2455008a80380bc34f87c211f57fa012af7155b5bc15e9061797a6647407fd73a53197a941bb6e15b2196bf2d911d4f404c586d2991d1c8bccde3b3d6949642602ccf209aecbcb69163e08213efe54015b12f19b7b4f308159c79821e97b84d99315fc8612c77f +SHA3-256: 206ec7dd35fde1b697ec2d7bb53008656188f8c111b24aaa86fe9723efe3cc6d +SHA3-512: 2ea140d263ecad9532762093bdb93b772b3ec8e384784f15464993c31cf00794b86ec1a264efef890727666b7d51506ab529483b58215f3cd21d3ca1d41892df +SHAKE-128: 5f72193815db9df9c95b07326f619c68b6c268f26136e6b1898bfe5556e1001a823742c8f1bce28e37052e7a7d1d3d8dbc0acd8f4d6ba30f59cd60c29ff3ba3fb022168225e00e57448cf950631a035b2563703963d4a080e5c1bf5c5778f8e200db6e5a172faef2cd403fb9e0722f9d32e57b4a967a22c61fc3db3e0a7d17142232b8f031cb483bb2c83b630061ce19c284814cee08fa1e3bf060861353b89053b1f9bf08de00255dd52789d99b395f02b2251500776300f6ab10557b932b770d5d5e7021a5cf0a071d023cd9c8e07c6adb68ca880acde116f016c8de9a6bc65497015705447f3b0ec746f01ae86cbf3aafec45cd41b3984a5c4ee8af8fe205af5b511709798894b2566efbb9c54ae86b9c43d10181bc47511ca209657af1378591eadcbfb0238471f41e016c8d671eb31cecc4ec7aa9ff55015d79fe2de2dce7399f6583e54382777ebe553aa4661ee7bc501b4611e2fd2b9da10e9b02907a6cb170239cb81bd78939794f800d22ab3a396b6f90b1a6217499e8f937560841d960fc2ef9415a0c7f045b24c5ee901425dc2664c136964e24d10ba8a47c26b2a3463422a5dd50faddd1c43f26f1f0d82e7f5f1ef35315dddd2b60280b64c4cd62adda1210f8616ee51bb3b743b67b47f05dd7832587035ba27c030f003afda3bd5028a4520c7c901a69dab456b314aa6d92fc530fac25f643ac7fd0351175ac +SHAKE-256: ebce28395b88df2f0a52b0acc1c6ade85e947da14d5266bdda229c64f098a15c228c46ee1d15298f25a91a7ad8995f44c1b3e53277cf21da3a4182768ead635b32613cbc2084cfaf0841306c09984b3f70ae28473b59fe65d78cc16e04ef4efd26acf70c1a67f85b784da2a779d6dfa5e0d2b8806e1dbb5069e0b52bf722b672c28c62c247258bbc7ce44a718f4007ce67a24d58a8cf2b430bc07ab17735f77cecd14fe1223a06a985d00ee06533f1270d349c089600f5b8ee99a46cb7400e8aa552c43c632c05f911bb86cb36d35511c9893ee1a3d635a83e35482e5d542fbe16d4a30ecd3c9ad53ea7b83fe4a970098f4e6a3cba363502c99b872ef08cb92b3366df4d380e16f402e811e2d9b7b61a9d0a162ba2437f35f1066c65da8fe0e861ea8c41587a18296094aa1853da201dee36e56c6cd0ae52e37ccd4fc3dce7ac1cc3c2a28d0e2b73f543b5a8bb967f272aee2da2b8426074081549a467fb4535b0377f96eac1fc9ee1f56314d52204c595651450443770ba5dae7b6ef7765007d314e50020fa7f7f404e12406673a52b3e46672826d603dddbe4d9ad1f5e91e84d23a729efdb4e73c26bfd6e2f69600a2ecc39097a5a7e4f1c7e60f9f050ccf2b91c6af4a9e9f4ab44e8d77bd1a2a8261803891ac60e91b605cd26835d0babb0e8e9ab0ad04be943cbb325b47966e133e59f6838e40beaacd4cb1ea3b0cd3ce3 + +Input: 3b7c8825d72798ed1f7bf71bbbd2ad0150df742ce34ccca2c7151a83df603e1af8dfdceacf17080f9c8bf6d33be1272c650fceca0b18c629d8715cf43ec53062014ae84616acae8b4e9154adb7d025f3094d45850da71bc91ca4f10d2e18a8e1da42e71723fc6103ae442776050a89dc84476a268e6e7a1fb4e01500a83eab7668b698fdc1648612771714cdf3a16e11d3d24f710a43c947cc39d7d218569e684031018e53894b94c0a1f76395904e966ef04a3ebec0d192452a1adcf30f7659ff70b0d8f24f1239b677037151f7cc4048bc7d76a24df2ce19d5dc7d76c0e6c096df79370bbb1c16331100527816c1f6dc440396a2570a9f4dcccbe637fc3ad1e0a9bb32e20030992e600190049190cbc6d503ae69a5c11fe92db46841ae26fd6de8cf0231eaeb11e90eae7aef0cc8ea98d0c58f3681bfe7332adfd1814c11bfe40787f74d67de3ae5076e0374295ab431c5a6461605942a6e076378521b1f9aa9320c21193f8ceb759c9667ad12f475a2efc062b3ae09b83b1a0072956f6390b2514278515e05939821bbdee89f2be1b607bd330146d6a18027c897916bd791bca24e91aedc4b1c9bd30fb46dea0a9b239b105c7f73efd6c06b063ee16d69781390e8383bac7dc86768c01630fc83013725f1bfe9c6c5e06134c3e1 +SHA3-256: f00a604f8ecc7f4943953fde9ce30cb7d803f1a657c891240ea154a5cff2bdb2 +SHA3-512: e5ae1d5ef3ad03b50fe21911ce08619ac70dd0f91bacd7bb5a85ffbc959ad7aeea872f69903f64fa29ee455ef5a55ec70499861b93f8d07ef6e46ed71569e89d +SHAKE-128: 461053fca799a61779fdcff5c8035cba9293933d51a3c60560d795aab4081d670a01dec137f14e3228997b77ee44d717952fcbcda0a1f5ce648fc83fa20121fcd536b1d4159dc80b81f1c62e027a813afb501e1e12709dc9c9572bf12ec3f860fef95ad73f9a9f8178080233f0e2403dfa688234711762d981652db87004457bc415a6f16deff2006eaa1d5e0f085b9e25e4b8b5d659782e9be818254be4c5cfcfba105fae37158698e952b28f7d2026c224813969385dc81482d22c5d3ada6cad7ebbafedbda1c638a93b43c2137e05e38deb2d6818518727c6a4523b4c8e51cd1085872cb900065408eee415d3c1744fa9db57b7b894c6a0c01a0ab5672a836614432cbeaea67fe2e03ea9715147306701b376060f320edb23aacd47d824df93b845bba783708eac2aebb541847e21a350806002635faf4346047498080018321e7ebc6dc6a8be04b6c1bff980d37c4efe6a0570a94e5a530788bb9e472c2a8984d140b1081b77fb5aed7ac41b81e29ce2821341355897d6494148afc4158ba7735a6159d1744fafa6c99c584f3ebc56c91d3279da26b6ae7adb293e36a55237c223d2c4ab470b80a095edc22fb70a0aea3726a50188f8d3cb2edfc7ce67934ac6703010ed4f48ae05ee4e9c8e80126df2ec67d42898108b3ada796614cdf3a0ae2d13d4c5895f91adbae13ca99b5521e44ada1aed666c9c0fdc099c41a58a +SHAKE-256: 56048699a68219c711552ec2fed9de656e52c501e5ecc925bdbfcfd7c48dd8740bb8761c5fc94a92433d6a0e39b0f5280cd43af26144c356d4bf96d8feb14f3ba6ea484a9ba01235e6330f6a15f1fb22ab57c9f44b67561651e2a745a7ae061c9035e1d50cf3f83a190c3d5e214c48d198b6a7f1f30ed7858cb864747525fc7661b462c49b90919b8bae8f184288a0520230e57717471b892428a396c652b708310764d20e81e17b4eef3479d3922716deb08b2767d7507b13caeff05d157443d678d96e086f4d01ad608216e75bb9e0750b27c934b4a4b8e02c6c4fb044aa20f4b02b2c3bf09cd0b60a98d248d1a5d967fc0c7e20085282e2ce4bfb4da0413ba7530b45485355b7556ff2e95606d8b75bc2522dff1ec283c22c8925f532537a67f830cf5fa14d95d3dc971e7c3497733cf31b6014eb8dab1b4fdb6c035a50a930f5c813b1b6267370c344eef2a39131e64b10a032bbad808182c4aa5f0532888a45ec37f1a3734c8756cb701ff16c5326d6ab131f11df9c8169f0f9d0f1e8576c9bb0b89e6666a0013baeede8357d5e502452de29beaeda345001f810cc43679905a043838b1b76d85797033b8c6e03ddc4fa384d87f99cf10b44316029c1b94693b9bc9cd18ea86726d6f0055527fdd92c278a10ce4ca4aa44161fdafab463b6b483be6c8b0824ef998cafa2447aad4e595f5dc53215f4c126031729e2fc79 + +Input: f7f4b8e8433607a927480cab21d263b1a7fcbd9f58c26b76e9a60ff99e34423a2642b561fee9331a2b34d59895226fe9ccb1c6d6bf32919f7139539d57477796f7ef8cb20392a137db19df15afaae54b4af2d58f143a364b85b92135762e1f04c6099c3e5ee05610c6b78d71c733fc9cdc89e7cf45de71bc7f3b24a073f7bf4ea7e7db1dd995cf8e067647ab386040ac9b14d5c796bd4617c7c4e95ec76e2750e8fd0718a82fc0bd2a2f671cc1e8cdab4d9f48ab76aa49bf1797d87c167ecf89477306eb4ef9d3abd96e1d9d99418ef4f14b8d8ed6a79eb14b2c71cb16ba6bf94ebc1e64a4324b344362941508d785d7f3d710b41d0564bbea58f0f6e843661ab6e187c15aa0cc0d6d09fbf56ecd2b5ad54781b74488bc69dbb90e5f06de6ff5e020ca7db54ac52648b76e47b68e17f35cf32c22ed16cd88c27e6d54e5a2bdb00c8450cf85a332f6221eb02bf049d09182254a32caaf37b697c69ad841d374a0ee779b13d709386530f506fa3593968250e61f06e4fad62889cec65d4f65aaafca7de615af08e59270cf3722c0ed03edf170c10f47ebed651a74a42d9deb17fb3e0dc9f860d78edff5597694baf6e928f20c2c1be2c157518fa2bef37d72d1e5dd4f03e63e4364d31333ff7b0d9d1a231e3e4c4871aa77baaf4c1fae9d +SHA3-256: adc72d265b2c6e016cdd026027804a2665c86a758e123dfafbd9067ef91a8252 +SHA3-512: aae4be63b00bbbb7f4d595ce7dcb4cdac179c4e406701473b16a7a3903cb15fb13ad1549eb31d04a52b60e21ab0e7eb5d2d9fe2d6874c37029702eae81420fe2 +SHAKE-128: d880037936802bc555f4bf20964c36a015069fee4911d2ee65e32fbb8ed4e22ef1eafc82ce60d60faf1626c8b136e01a7adc9201394d0dbf6d9f0556110cd40e9d24903027af8687d911ac5018fad88613d54be0b4bd5b36be75ffc923cad4844a6ece04c5bb166a491dd326fa9e204f7ee4450b78b691c9f99083df89ce937d6249f8b8f9f74f2ba04d20731289b62be217b25bd8e5786eeb0272fc04b52364425b51e50d817b1572d5066b44b5ced71a0193ab20675e8718680d5668d351d71154940cebf3ef8d9d0cceed0ed432ccccbaab1f47b85ed82964c3e05829fb08811e104566e0dfbca7a5586fcf29b3265c82e25d3f5c703855b5228bcdab8520e52289fda23050785f63c72cfc899530d5bb5a9b509fddaff02588d71316abac9724032be8b4c8e0068738d610571625027f016b5b1e5f4f7034dbafb22b4d01ade389b0e8dab57ed2c25dc4f91ddd5135e35882c15f47d776407f40e0bec98bc04534a5fc535617f3cf372b4f5682991666607c42ba9ea5155e79d35c0133b92cf192bec37d8eab47c307ce18a288880687027e553d48f9910a045ec301482d877d1e34911635e906770e06c7786065489216ba4a9145980252ca0ca9ec93f1d7893e7a9da24164aead6bfa60c2c69a771f7340ff70fce5f176bc64be040a0c237a0fcb7ba09b84d52c8cc7ec1cf43e2fa0171b555ab6d3be0998ddb591590c +SHAKE-256: 5680a78f8f098956eb6f18310fd7275a1961d3dbb1dda3a800f0393c6294faf8378d6bd8d38ad1a4cae117ca4723a72306f68c6fb9b2e66a3f4d474d0466b0f1210c8cd0fe055738f75de6b3e875bc2d65a4da807e7d053c4a37863cc49cfb909f33551b29fbc8b83ee496a5a674ccf64bdd99967ff2103028495de93d6b3588c439363e77888823ad3a7e4bac0ddb0673d31a5a49a258b34d8817f15857b169a85aa4ec4ab12875f9a351bdf25b5a03569d020e32c674fbf58b111ea87494bbe02a735ac8cb469dc29cd99f11b0152bd26cbf9f6eccbb28c87cf4757ea02458b9aaed1a95cacdb4326bb51de46568b40ba2d31b93214a7bbd14cebb764c342a54accb361c67037c16e89c93d6280e1f49df2cbe3dd69d0c523dcdab18cdd9ed3ee2efbcd3454aa09dd89465e1c2e4063d825d71c5f75dfe2032d8d1ae22b5f2ef0df5cae38a88436f3b577bac1695f7a37acec0e132c25dea78f5547240b678df27d74323fc2104769c90f6f59b0b8416873d700d7e52de7b78bc8f680195271f3cf277e53955a976f4588f66b8307cf27e79f3d98b09e5af787a6ff97fc123fb34a9ce8f5fe93231746cfec223f9a0a0214c5ea31d949ff59c6bb0cc0b31a4d5e7dc5669b95f1a4d2657b7411b812cf249b4145b9b435a45e5cc6341f9603388398123f2d3e460c9276451ef15c7d234c283b92225633c7dc32ddf7ac8383c + +Input: 35f0e1c9f8f94d8d2b83a6c2cc4cbd573d340a6b515183d57a7aaf9aead1728045d63ecb759a774b8a7ecb2a17dddd010b2c188b56058e88e4ec5ea81492f7919a2410190019fd27b7d9d2a8049015e601f722b536455ad914b1e8fbad9cebf8a0d3b1f670b98b23eb6a66ce1410cab59169e08b2a1d21fafcafac2d52e54951c63594d512e289490086c2ee3ab43c0d8c0d20d6c431ef94cc907f83878937a7a6d8fa884ebbe09c7d251a10d9de550506a34a4e09f0123aa3a26a891a43c36adbc258ca114b24c607acc0e95443e60183d9c02c8982c3dbba8687b587d2fc3a92f8026946559ac088e74401a05d76f47f7590181615e68c2da9cc8b595add1565df8dac95577e3db486f4324889e08be7e3a82c61d207fac5b90802334c904824181bdd0f063eca26405ac4122cd5ad65a0ddfe3804c3649cb8fb8e3fdb6f74b7f73674ce2efa2515a93d19f83168aa1b00f4d9aaa919521511f568db45e6d8bba52e65e55ed54400eff089a4b2e7b1df322203590089aafa40a22cd456a1e0d41e5e4ba43292c5a1313c0ccbddf48c79786a513fcd1b0317260f9c28d7245ca53cac7e62752e1874d39cffac75c2c867d8b6ff01e83852dac1378140d0e3be14d35df05a2cf31fc0ed8aed910da71e4c18597d439c409b5858a13c7baa +SHA3-256: 11567ac107402f32d9faa4946450a53dce3e633d09fe1296a2403736147db02e +SHA3-512: fe35e2c4e06f2872065da653f5077662f725efa1a064df04454110518a05a471226685de6acb008e738f961183659d030388fb974b3dfb194fd64d83515660fa +SHAKE-128: e3214d0fb863d585b1517f2a8c68851abb518637b2e8e49f6e998fd1f98d95f74854ff0c1e9acff971cbd7a6785da89b0b9f75398576b1120b3cd1a79a88bfe7a6b7763ec4f4d7f970a55a651a9fc4c4edcf149cbd5fb9d420914527eba3e49e8a55727b2e36535568daefbb7da1e3e62898b084d92bb8127b6ce59fe0d99f884fd16690499f5994660380693d625975ce1e6d3f31b2c534b4a4506903f871e4b1036dd5f376e4b37dd4b1faf3cdeab01c0a866864b4a9d1f5065cfe13afb1f5a58fa76d89feebfd0c62a50a717bb298d94c8b8a84eb69b8b8502c620c649340c5725aeccdbcbd54d0dd006b2b456f0f98314a372c5ec03af52a3c31a4de5276b048f5f8074d51cfa7c96c818243ec5430edbf2b9248a7c6f57fe027bd445762dac5f8b4922b349910d4452ed00031e1c1da31dff0e711dc682bce9164a79c2a177db529c269ee4576f16a67e2a50d77b67d2b9a0f3aca584764d6df89259e3179d266e0972c1a06f678205ba63e7427ff5e0766c5b945a3453021adbecf371e8cc439e7802887dc2aca633c414c91ad6312dbfa6187b42fa7bfb1206c39665d45e8ee82ce2a86c8ccb525d762f743341392f2eaaec03194d3f19745edee016cec5f3085871b7a6bb2feef2dc773fd46d8a88e73959b7587c117402024491330c5c76ba6cd9255bc1182d4eb88eed52e42ac315f4ece90dd297eb92803021692 +SHAKE-256: c2f1d20d1102c7afbf81ba2a618f00afcfb52a19efd912d298f3541439296576973ff83fc6eb1927573a9b341fef3ad7dee77d97401623e18a69d7772781646c4fe676a832e17a7b9535fac06147fc06fa5940dbdddc52fb08afcd363febbeb956b1358d75918ecee991636d2c5d381bde250bda6ed8e1b541be791d88cde6ec0fa7d9ff3c8e17295978ecc3ffe9914de749c13b5729fee92b5ba20396699cf09b886cb30fdf5ec533bee21f5fe58d1b125f6498445e3153eec27c05651f2033c9805fbb4c84ef648ba76d405d65c3380c5aba8301ab739642b6bbb2507b10b54cff5945a12995d384eae25a2307f2705147b04d069500898e9f3236c686342f9d959acd30fe45bcb3b8253df9ee028609a5c390d5303478f4b9bec783c1ef372b34e04f56eb18a195dce1be36cdb9e9f492441efac0f791e3e4560d9a347bd4803f38aff1a556b117c41ef3e2bd26032d1ecfde94c2704541b68914af6ee55e4843a9ef41e1cbcc5bf3dc442e5f524cf6306072d18574b571a84ec504c954215ea1898071953cef4a15b18e7ed5daa4aff763687fa63376f893df940a1afb66553c9f90bcb2b30a2d26728d0b7d1a8842dd6e10b808a49611b72f64198d5680865902a3fc3ceaaa3adb252281e2c506997c1c0a7a515318b56c0a668ee703ca647e5e1c25581ab60727f99de09c46a53122918a7600575614b9ca644881f1b7 + +Input: ac540ae54964328e9d7c2d579ea72dff9182ce3fff95e90ee61460fb7ae2599a30da7b1b33e5d9bfbed7436c021cc7f72552a44961d63dbdb0732f384e51611f910f4a8382291160654cb780bb40b0b8ec0c7c87629c5305d19fa34b70639304242583ea35338e49db05b97d3e12e2084df72edc49fc5c401b674e70f45d213f020578896638df2ca15eb28f6d1886739c43f48128f2ebdc1f59c825ab3f683739e7e2bccff2a7e825140730036ce9e16386bc0a785b2245b799e713a633342a598ee08c81016d49af45b39b1da8e38d0b77775d84f9ab77423ccdd97b67bfa2139490becb6f52819a32d80fd285d3dc0aef383bef34c14aca50319100cf92fc044d7ee66563f32c048475f5464525d5bdc36427c88caea6eb886a98c6117da0a368dddcbe691d1e220231c8434d055a1f23f6f87380fa5d621cd456d26bcc3286d7daa56ce005a88c149082c9255fe2c5c899a578f4bfe5ef6ed48556a3ee910a4729f37192fa544bfc8e44b816b92baf6abd2a05d48395c36fa41103257e9f44a14ef8dc2d9dfc1712ab465c9675ccc84964fec56d22035a64106ffc300664a64298f3cecd519af3d1ee85000310f48473eafd82bbf3b053ca18714d6810c65bac4eeb01239a8d342fa28c4a3252e1059bde687e092b198d7be08ff8d9f4 +SHA3-256: aed4f59acee7d7d2f985faf2190e3964fc94bf9a4be10bc16706e52d508cc4e7 +SHA3-512: 070debad718d8baacaf6eb6d545f0a2de4d0568b4c28510b729b90bad9db7c1713c98130f1fb7b1a2891907f73ce7bd1eb9078cb7fc8409983293406224673a8 +SHAKE-128: ad1e4c9ef1602b6a30abb2cbf36517127f770b570689d3193e0f4c31355437792e86c7498d3876c5f527cc2f82ea17f688f01cee8d31d43a7c6d8f89978979496638a655c06be486322ce978c13bcac09e0142275a66b624d6c06ea5a6887862c2846147049fb35dcd1f37519eea308a7f10fa635c6633ece682a830c1bad99d1814591eaa3a97595ae6c6bc1c37c8891e6793e182681631c61bd4e087c0b309177b06739496a1b042c46cb504eca3ca79231ad12f7ae69660fbadf476ebf470441348b15dea01dc89b03e8f65f5d034b1229c1817363cb681d473b43ce9d299133b7199f20b838fc4383ecbb6c4d87530f9e8ea36cfae0086017786615109f2a0eba2353b7e502afbf74db86e7879adc6c06351634407d1f46cfbfc2d5a55342786ab8b11b1cca0a6c79914789f38ac64448a5ecf7e5a4c6d887772086c598bd3e8585bf525e5de7350c3917a07549c848c3eb2ecdc291463b23a77e088e3d78882ce75c703cec3878090245ae4ce08c65b183eaa08a93235a78e6ccb489b3177d3dfb3419ceef89aa837482f2f92b5b81e9074fe10fb548926ba6a85e5e906b1840694a86e9db206fb35cce798c4d9948f80fa2598541d95f6e95765db37c6681ba2df8bebe7a2f633aa25c021549576f47b0b0bc49059bd55422dcd8e5d879afe7e225aeb9e039885b7563303bb51c520f993003941157bd1faf3c51101be +SHAKE-256: 58ef9ef2d82d263e3a1e33f9ba0670a7bda43c9a5f9073d12830092bb2edba799dbf79edf37803a27ae45fb274db7ae3e8dbde30174875b744375b42608c899e9e815595ee1a0ae8da04069fae2d58c1d91faeae91f0580efa9e5149f83ee3f1c594701b81aba9dc6e0c2e94777569f52c073888f56d76cd6cc76cdbba840626b0756e9e393a02976d3107519624ac0d73fc40e93e30c33e9abc2301c02e73ec905d6067f538d35598fe5ef345d64091ba2184d75ae82c31d0355f90df778d6d4afc0bdb213b0e159c89b6b458dc4e9ba5d19f4fc59c61c1419336d2dc2ce44ecac1f911d188215e0866893f7289467f01555773db06154eb0e177e9a0c368cef88c952559ece865401e8ac4e0c387e3dd59d7a1a9e78f4470e607a9db21694de8b3d85d6b526b13675fbf2856682a40677c6fbba1af50cb362e22ad9020cbe3b974e8e056c3bad61029cc4f83ffae42c5b7349523cc5cfe64fb5351c874a91e465e001820be70c7a0d76837ae264dd6b11687c497961673358681d0ed5b7f03d8202c41d7210cbeb54f41f57a314baef7dbdbfcc6a0e33984590b72725280ce6f75a437867465a52f77e8961bb6cc4dff4b5bcd5d6aedcae9b5d69909eb7f8d38b94ee369b09c133b1d5176fd2ce80101694f3686e057c003638fa575cbc0341820ef3e4f9a9476e3795ab6eeca3e59b815f0245afa9bfd9ba3c8e03366f896 + +Input: d605f0dbb7cc90761c57f304000512f95e402c12ba319581cb3cea7cebcef2c5b15cd9dbdcf62a5b323c589c119ca492758cbcfc191e6e066eab4d76edff3e2d74471df29651ad1bbfb86b67b9ecfdad35349c81354b6400fdb625f71d22cbfa0afd52e767e12b0e8ecbaf14faaf252f22c940fd2859c43a3e37d8be70f3415fe928b03754cd64a2e1ac8ab7e49df941586df72a86e3d1c122a2e54941160dd7fc2414caa4b66c0aa0f5cc71d60511bb8f5e0849c3e93b5a6945ce9760eadc725a87a43ac5668791e74bd6c879997073d3d65d4222a8500214b14c9c299c0b629417e408af6f552a598209c3256cab73f95c9bddfca0e915cb19cec4830fb4916efcae57d64ddd8964dea61c0248a6d10937445bcbbfbb7d47746b97da1cadfa0fcbda7dcd6cd8e4a36d003a5739d9536be6aedc13e68a7415163ec1efd0cbcd86fa27a394fcf3cf58da9671ff0d1ad7502510788137a01d1042c91b253b1e41569e0693ca4374ed24c0342c238456343843eb205c8a5e99b20bcdf329c0d3084b00327032569fcd8c0aa53bf28f69e4e82c26a34a83a5bb256fcad2c9a64126f4f5b26e96cfcb530a9612af917d6802791f958075f600c49212f669a6379831b4c8aa0be2cce523c0f6520d2d15ac03a6b7d5a8eb371bef970797fb1791c368 +SHA3-256: 7a65748249de6e690b4ef7428126186b7aa3680900be69f86d9cba4f9841dddb +SHA3-512: 355b3de93c86b9e8fb4908accd21c0e6324b9948a38fb3b92bc5f0faf95c6bd980f5abaffb843eab04b34149561c11da4d669038d5bc655864ca2e4c208812b1 +SHAKE-128: a2423729cb67210f0d0b01d538225b7590f42a92fe5b5c82a126195c7d74c3fc0363398dec5cdaa1bf8fffe4aeb3d705b11f77e9362033c49a6dbea3deff887d591b1dec433c329c9b46efcaa59ff4edaf91a4edde9a636eabc16e21a46a05886a073eaaf84cbddcbc2dec51ae9f9e1055f226422dcefd9d3b32c12aed03cee89bbecc48bdd6ee814e9ee3433b0dcb85f5ba70d1721d3b2d916ca2b4c44dc1867187eef39e38c4044fc888404f62ee8d724401f417ffa1c29033c806c9a535debe9ca67e1e59ca996afb4c1541bb114937e30ad03bbd07c5bfc04c496d784e9948a5ea7aa9e20fd978b4d73ef8c0c8aeb10453002bec0f61f00e15de15f3fad8135fb46aeeb6c63bcad09f1fddbf9c8784aba8247b124cfd60c2eb0e2d52eb5cbefa377efb83efd42cec4a215802676afb301cdb065f1a996dd728b4d52f9f07c2e89db3859f163bdeae380e61095412f3e000ac33c4218f039fd716d4d74acf920202da3f67b2d93db4ab39671975b50c586866b5fd00fe480ab445957965a290c3041f170041121e70cf8859579b486b97957f935637ac05060a412788b9fe80819a125fd513c707cdf5af326760645538d975c76579d01de86df903223da8c72f68756bf3e42505f33311fd90d3cc1a2c1d795862bfc01c53a8bc9d18888de192d151d05d00965f83cd675527ac92271bf4b4c5f5c1edb43374fcc6ada6b0 +SHAKE-256: 5cbb11585987298de72fa2e909c0daa303ee8212aadfacfa3072efd3c3848fd2d9a336f07efa6c927f241340fedf06a2ffbc6a1898f9aaa4afed4e7fe2aef93efd215c07327d035bb07a7c1297e2680404734275a0d41730b90b403ec6978cdc181d9dbec2422a12caf0420c5bc516fdb9df8b39b2087bde474c44a9b2e02068fe1a3b810358c80a5987ad636065c61d635cbd1e78baed4c346ca48750dfc3329d5de73c0cbe53e193735b84676feeeeb519ae30a33141fa1c0c8625659beb2d786f6ee484e51b71da1ef9b777fb6a5f1e2bdf717641951d45a4db637200f300c0484e342bfcd69831ce8403df60b3061adf15c27007805132fad3ca24e252fdb006ef1ef32eeb576d5c967cd93487cb3709246cb23a0dafbd9fe333a8d9d1de30fa9bdfa13725a7df51fc1219205915256693ee071830b26549cad2c14eb04c11a6435ebfe7e91afe11c6c91bc70c800accecbd855eea25e938104a5be78bbdb878391bffd9b6258541cf1b773a73801e9bb1b740078853a978e921c87826fc5950dd38ccdf053daf79f3ea33dbc2f571a92c1030b55719397489f986d69ef37ae99b0b1e24c5e48f7c102ad84592b7838f6599dc881dfdabd743ab551476c569b79273e08a76ba7126ca1e297c5be17fced1fbf692c441451acdb09d2271a29e38f15a9965000aa286c975d8482b77b033124558554b3ea44162166c08a8db + +Input: 82da51641b8b2f30614e0c50343be97cabd51998c60ac0a46509db3f31376e76917bd0b631acbaab3b06daecd3ff1ccf7cb5718d655fb34ab0e9a9cab568d50cb2af8ef36959d20c6c9b414e8050d03fa50c9143de657dcf4173fa6ccb627872c7c19e2a14980f9d13117c85b2b54e30450e0af2ff880151c4713a3cce448b0be584a785036643ccf9033f123baea6ea464a3d5e23654d8bbcb4388a99caf23d53a7209adc3ccfbf597abd0d569314464caa75cc5fa7b507c405e16024c7c3a45b6c491fcdfd2cb9233f62dd4d7a282e38177b1cd7f6f90b2f2561199a01d76e0b8be8fe970acc03442ae93d69c03d0b3d1a996efd43c30b6ebdaa08ca8e35ea9b7fa7597da537dbcc86158bd33d60f210228f231707eff34d3e93660352af01383bdaf0ca498d5e12cb08262259f2769e02bf34eb10c6160a9fe747c7265953733baf8915f2344747e2a4038c332e7402cf868ebb822bde475e334cd0a4516fcd5fcb00f86a865113fdb5a931fbddb5022bdc302aaa4fb2dc6c68e89ef1f70a6d4051d5ebc8a4d1ba748b2dc915f37b006a439b4e5d81ea54014493dea3ab02b71c6541821383bd7ceaa78ef6f45fff54a83989e8f4b72ef0e5741706cdeded70dcad1075e234d4604b29f1a7366384c506ee1ff8fbea418ea97cb0f8321bab6e +SHA3-256: 4585ec2e46a070090485c6aa2ad1ca508f2783b254f91bbc3125bde031813ee2 +SHA3-512: dbacd8b4978ff05bca77ab1ab02da90ccd804f0f4ec65907b8ea08c52a8e1e9999052e5f58ce2f08265133d573501979b365d7ceafda59446193323761d05374 +SHAKE-128: 8199ffedc66359278e4204d5cbc01c77c1ec7f26c649f0cd5e8ebf92418a2f087dc05427da9aa277ea212728c3d52e3d4741e97093d4a92cae158e405e5c7f6f4cf1e664fabb9573a2d269494ae27fb4b954a1dff8512eb2602933ff7bbf61f5d6ff99ea8211c21a4e1ad46d0d443c0d5294f531ff50581f3f813915d226224a5dbdd2c42adae80728d508630f23b701be79e094699e20f575f9c43295f6a1d76010fa299fb6559df6fc5d236c4d9e388356fe5ab0e860e3abebe4cfe5f80ce1360e6342874c4c1206a9ad3978e6e5dbbbad7839f70bedf6f0c7a240d0f510ad7eda05c1f9dc9de462fb023f548b1d401ca304d571568496f083e33a1401d23465696068e085529a4448656c07487fab20907cb8ca64404283711ea6ff0e97cb81869dc6600184a2502a82018003ad5fd525c5e404d1d69cec0d4dd5730a0920d83a0b5df68cca51a7972fc5cce05945f49b6aedcaa9d3c9f3b99a681fa34cc21fc89050d5e052f8bdfad23db4a1d6823f1fba6bf834bee4ccac8a1f92ff68c058f5e0a6e0375c99e416a3a95a7f997a45ba0a52a262aa84b95ad4e5b25cc54c648b38dc2d1a02cf757464d1a1564171944fb216047d31490f8f6fa182ab36ac776b75ed1ed2ca81b1452be59f9ca7352428ef72b4c410f13e313224551bf111ebbedbdec260ade059b1fdde65562ed09c81cac23f3c74630bb078365a42a4f4 +SHAKE-256: 2b2a758a6fe977633f784de8f7747db37a5b58950136799255c4ea7997fd45f40bc787dbd44633291d1b181e647d59ac5d0d4269b67d53a101725b76a33e12ee91d83e58bc0644e19f38895b687df7f22b12bae0c8d20057b82b2da5a954acee114ec940d5ce7e884aea3f9e2b70480a0afe517a59f3b767cf72774003025f2b858596bb3b3111fd270a69c1c6edb6a6bbc1653b6e06616f69e9f4f4ce3da768f415cde5f4151caa204e1f5b51733e8bf1de00969d64abd66d6e30dfd75ce0e0f6e086f7fa787e14068fc87129fe179df55e80bc13a0222375edfa2ca523c4c95420065a7996c69343af9aed2df1188117913b6af358251d5903f6b4000100c64f68140345d3b4dc56248a2f7bd17d18b93870a81120d34b6331c8a300c2e88de8b0a7a3b08a3128d63948fb7116fa1c27b1199385ca2308f5c2e851e84b061cb19b84137ab041cd0a8beacaec4ddfc28a49ed8ae94b8c803ad8425001f29ad1c0fe351c640fd9578d941c0edb216d22108ec587307f5fb3d73a3106eb33ef66476e76d0e8be4d4c9eb8a9e6e2e364d6d26cc054582b7dc666fa9c046830f609a044089f8415edbbac2d8dd2b350258c64a59b49435e2cb987ea07cda531a7b7a73fc39e58abc2b22c11f0d27419f906c1b8fb556c80f051e77b5c36d6e9452d534da4127e543174654ff8060c362694325e723ddd0b531e8c9a234c2cc45ada + +Input: 0eb2246571fd8b80a04e368c17a107daf2c9aac6b90d5c2c27f1bccc03ca28a869bcbbbdcd27bd8df68870581d27e838fb6e4ad509ec9238c19c69496b0cc1b10acf095418342d0acb64c44e0e0f61cb51e5cf7c388c10fe4c30b21e36bb6670da7752e4fb9f81844f0cc1ffe5efd1b463e235234e863e2be4249de94ab85e5295dad965f7e2e65a4cbb080e69cf9c67d6a4c7c3884646e577ba55cc4fa47147e5a94ec1115a33f16b609f8f5944aac3eaca2d150492265681abc5dee66e27c87ab6cd16e847d63d5f771d809ce295d116f32ac8bd83f1616dc9664973cba09e9936f6a8d038139de4c18c350d293a75a6fbe43086ed7f75603a29f73dc69c6ba397e86ef05d576c3e26faa1586673d7df62915cb76d5f10ded811ecb952e91206088df1eb533d8f18199799b65554d372a6c4e9e357e7b2a1593368e05f85579efb81bd7ccaa08c7875b7fa80d34929a4634a3212c8faa1c27011106d038699419384b939891bc9dcd5b63ef55673ff2954302cf5b0d24e78a7aec363d4f3ce9532f8f7b4c40a8db58d6ae0f1e5105741d1b45417d54861de4ef84279c9769b8d539951112f21afb35bea7053912a02c92eb003173a1b8a36913341f59b961994dcbcfcef87a849766de0945295c3886831e4836974029fe1b82a9e0413d95170a9 +SHA3-256: 128f6788865299758445df5ea69187447722563bdf5a63d0e265d086ec3c8eac +SHA3-512: a07fd478ae89da38d4e81704acdf1e2652917ec041af628962572b202fe2db9ca50dc03c9a2f33f49b06faad75c4397b50db2548b37f11536ca0725eceb3d34a +SHAKE-128: 730d6d42e751971608b5c5694db129734614072b6d35fa9a1d517d4ad5dcb2577bf3180ef854231ff29cd0a4603af5e1c9b0bd14168f9879557af4c008cc44a62ff5bf893e4919653653f2dbafe83df22bc0ebcefe8b7889a3fc1c86704edf4657d2c9523e5be0736f1938277f39fd1a7c3615c12a9759118dedddd4ef3eb5b4a9ddf741b29a265d1416b6275c678a0c3921b188f9bce89624990baef69e2d74084d040600c003b8001375fe3aa6414b90d29810e0b9e92f70abbf28e75b1bdc2693d2dc70ecb87af49c62c3ad8c6fe4627e490af6a8e0b700bd29a6e124d5d9b7fa8f7978a93a7c5beef7968f3fa224038235e7a1aee5e1994618cde9c927a140f338f89719436e9e250d2c871fd2e0db88c6a38f5b38fb5eed1e1aa53507d33673742069f3913d5998beb32e5afd866f46b58f99250840693d2f141186750020dd5dbb903500daafbe2aaafea5ed737e2b1b53a602561da91de6ab8810fa49c1b699105dfa9c353562f01930a135116fb90ae48eaf4ee400e04b0c54ba90b42921a0f9a95420c678c0230e80630a411abe1de1298d7a2882efd27bc5d5699ed7e12d3a8160d2c52a2e813f0ed91e41d59f7ff7c9ca188822c2d81bd4926dfa1632a8e357f6169a7314c7b52e76a9ea3e6b3dcc7347b67be62a18372e85380f7f3c2aaea8bb371e645f371c18bbf169813baaf024465ce4fdaff3d8e7ba7db5 +SHAKE-256: 2da6159c24dea9d9cd98b9bb2de6a02ac832902bb204624e33d6fe03206ac0899871e930f70ca6d0dd9c1b709e62c3598ae77570ebeb393672756e47b6f20d035b7fe86b69087a8e9a6ff905a83efd5760c094fd993b6e707746439625c36d8bea9a3ee5b2ff69f645c505551bb511b7f96898878d3fc555bcc6153e17177fd5150ec6025e22b6b73bb94ebfb578c3110ec9b74d6a9a32e0543b201e7ddffcc41d2784dbc08a4bbafac64015256fe0d2acac9c60058cc3511ed1373d77e8d09e80dcfa510fcf674e56e5bbfdf2bad4909288289c7067aa233553ac6294debaba3bda6a462736cc049d4c9784047eb32d0f36829f4b1ab66c45b70318b89328804e712419a55a3005f38023a863a527d0990f5f00c9ee5078ac2ed3dbbfe6da3d6ff1d9186ad6c7bde61defe85ad28588c84a4cb1382f160069c0598136a66d7ea0e7fdbf3797c96d4f52e3df200b381553f91e6fbc24eb07751bd41d10170cdc2b14ab12d470fd82a66d084e5d54ff22fe414bcf085d6551cf66a6671dcbe1a7fc7ccf6497e21ee2dba9f1d7d17ff812f05592240973837b68f2d8d95680522f764fda3c57bde42b3ec62fdb89647aed1028130a76be8a42757882faebb9f8e3732265ec574d671e6f046bd3802f70b315cb2020b4e9453862b6a2217ea271031af1367a9713d49f73f681ded9ddb9ff32a8a6a1118d1453c131c0d62297d166 + +Input: aeba8d24c903ca7915df945ad8c8f723357d3f6fcac1899d4c9d134de762da51052f6ce2cc34ce99a225f08876f2c8cc9a336d1abb02f8203160a80d23880d4b5ef1b56ef554189c058cbf3f33798d5fef6412f0faba1e7620588c5be4dcab6f1806f9094d2531a75a57ee398b340a49dbb223ee932951b8b46f18174fdeb0e8143a15c1c09834f2277ba02926946172d09c508569a50b5149557c99c85b3bd907199ef8d2c3df8f3686233c6aa14bb2fa57df32c0e77b689d3aab80ae7c1ae74630911735f3ba2d5f5e2eb66025aa5cbacd49a256929e045910af6bfb3d7bdd102e8260294d7510fa8985853c4a5ad638e69aa645e902f67e697f85b58ca36487c2c7584620757418a39cfd40d4be1070e20b8c4e4979ecf04fa9282f474569521655d7b88fae5a75531df38a4ee30d59a89807e30e99bd02d49e97577ba1d7f03f12cf05685c622854c51e1467d2aec1fd9768b737d4b3479864cd6d2048291736871dc0ef13c8870105c1ea9fcec9637c9ae62709251c47bd4a073bd9722854b9aa1cb721b97817b87485a825e9d8d0a77124efa406453cab6c9bacfd7548dc4ad56b458a1c796d05e428159d06a169292871cae3068f1f4d2ba3b74036166157c92afd6ef5afeace0925bb5b13e57060ae2a8303d8d8486533288901b42940a5c5 +SHA3-256: 4ac7008d9906ed41b2185218f24c8fd3d9a0fc741380ee0039ff052d7aff0902 +SHA3-512: 8ad40fd770d7da8772069bc2c2ed44f715e85948339bcf2dd2a708310b3f0b150990f2fe27c496883d6406d384a94f7d530212012fe1b332e4dfd01eb0b0b89e +SHAKE-128: 0a3ccbbc987d24b0fa3cc365eccdd4ba35fe9b4fedf37640218619d533c94bfd0609603294d078d8953d5c022ebee8c4bf7a2b02feee80ec8e2247014d4f3c3294fcd767409f9965d2aeb9c2abb8e4dd12670bf76282f6e1f784956b9080ba8dfea9d2099d7067d0751c1ed233bc1c45a092ae8fbf7308fcfa545132a0c6808987a83ba99aea158d72e5315fe7d8e0735b13c9c7df00e6785f8b341c5081c4225bacc0b5cd10d3344af8fea1bc25cce480f0b59826a6cc97a07bfd73015ed6694307c7a511481a8fccf58e694e2d3a0c8dd48fa7f31c89720d52e438accb4ae799af7e276e24e60e93bbbd5e8b7b5306f4c824ecf20e9255f85ae7abfebbeb4e975c250b8cc55f092c80a0788ee4e14ca553d22e3c521a8bf2fe318124ca26bd6ab870c2292b7c1ba2e1282d703fba4e4fbbb834de11d1c7ca172a0455a33fd1fad679d2a519a814c89377ca8accdd709fabf26288242111813815cbc54df14ceaff4c208d276f0c07fa3af4d447df1fd353e5416e5acb66bbe93e4a889c98a77fddeefa7fa1462e5ec5319c97bef63307e10d7c1bb6e2d306f094bca77091ae8d32332860d58b88ccf2086bc712eec1dab1bcb0b50928ea9967dfb48a46ace9237a76cb9b43831bd3be827e4d56d09ec2c014903a8a89181207f663dc24e4b0fc025a0cde4497ffefe5c1695e83a35ff649c3b56e30fe02d970d37cbb78d6c4 +SHAKE-256: c366e8ea62850ff418d3990da96e0e8aceeee05885cab6240ed66d13b410b673b5bc9e0ae320ea01c2bd87688bb0ea7272944af26d9112db77a8a435e6f31000820c0dfd29a85ebb3b92f2b43bb79b2b938597b42d83bf8e92d61e47343374b91902eca1d054930e79ae15c7ab939b339505d9d8ffab1f43ce9ed4426ff7583716159ab0f4fc618c175e2372ca10588c0b6eca5db29942aa7fc3934128625264fbefbc52d19d9919f4ab72cbf1e755469939a3f15bf80b3f0f061c04b6127cc4e6ed76aa6628f41cca91281d17b07e1fce3474a4c8ea6e7b5636689fd63e5b571266a0000b4d7fef5d05f6ca23d52eb4f52170eeb3e7cec492891e8b273d521aa3d2d99913a201dad216382650c74927c863a45180c267e7615aedc1b7bcbefda94cf5a7f36a17d7c1f9205e64cb69614a7be4f6a06c6b1fb1a4d217cb4178b1be70f89609712ac1f50ca396f0b54ed4fddea6ca105c4c9ff4319492b9cec6347ca141ecf39aa639a7ef9cf4b47b253476409e30a3c78a793ab0d87e7d0b6ff0e21b126a14b55957d41778dce4615b1771504ffe34ad88c1cea286deb239454c54109440a85da12054b79bba1198e2f86eca4e4751d409db543a513c5d53afaeb2ca32d12f679a9ac1e2d8948334c47e8e38c951f640d3a10d2274f2b29179588d9f2b497338946f3d8992a191eeca6a4d747e54c0f46d698765f07f4f5a9946 + +Input: 0473d44b87d10450e16255624312eda73ba0dd45317a77e94cc9bbd51799c557c6221c95f5a35346a7a050bfc8817069b814392946a2e5e2f81e103de1122c02c8fc5e7e713700b3660d93337e6d29a7a53da92d9459d4364578d0eeb4585bf1bed47135ac01993160bc9bfc78f662daa4f7852248b3e9a64bf2af201215adf7a15028960375883879af6842f206aa419e8cc7d070fbfbdc2a4751c880ac7e2084e2aa68d570f33592695f45af53e66f121d2a77af281a4480ba68f510e11c030c97b6b8ffb8b46243b696af5e336607614a70eda2deac4d427a92769cd4b66b3efde13db5bfd5495ee2edaf28b7991e8d6e0cd440d3743a6b66b0e73d1d06e70970d2ddd15f8e23baf17253fdf27b5174700eca757056938a728edcd1ab652ce7b4277afeafe19638a2accef0fdf9c5f1eb8441ddfac7b390464678fbe4b646398ffe7fe1855976bd7f97497f151d4576fa947553fc0869eab75583c88485c831d32c5bc39887ac2f50615dab81733b5fa333cf16113f55df43a53b905b03644e2d5322dd8c1a00d430f316528cad65603490fe6a5312c06d33cc46958fb56621d047cc7c0792e956a1db2c283d710fdf7754871143c678be50477e139ff69f4bf3b14f7c1889e8dac6f5457798e621be2a4a1eba2fa70b00697637765995cb224e6bd2 +SHA3-256: 92847f825dbbcd0a108d88579e10daec823c47436aecb6eb4cfdee12f1911ba8 +SHA3-512: 7a2bafc05a49494fe94c95b8d7f1ba052420247ac0872e3ac4638be4fe0bb32c4729ec2b9e30962ac70bb9b81d7c80ed5c70d4448c6dede24caf8a6f5ff9ce4b +SHAKE-128: 8eff8182df1d72b749c3a514353941ac1e970d1071f199ce7920680fb97ea21e7c5c222f1721e0af8cc2ccf8f53e79a9826c391671f580f2c438a166b050786c19f592e7461f82705d400872d9f02e816cedb6f21a2b0c251b5e093a694c1fc0f742b96df6ef24d6b7ce443a4c3693c6c552bad2249435427d5bf9ecf876a940eebcdb857be0bdd324dd6304d3e8a6e0d38ef068d05865bbc8d2093695bc563b5ee67ebd4aa57da73a23e32b018ba1eb486dab1a0815c78a09264cb27bfeff7276920084d7f0544171b13c3f8fb72d7e6bc63c0655e5556c5bb1212efb93a259fd562d269b5630fd328c365887c10fa15c3f100eec0a60e8a515471bdc658cd165108f8c021c89cf3c804e17ca57388c5936dc06e58c5e65ee9f577ecbdf3e0fbdf48b03f0b07726f14d0b5d3b1566b09295ce114e29ad50f4c7639b94aaa7da379453ac45cd872fb782c78fa1a2047daffbff864e041c97d5b1f0b27fb685b14100572b8e5bad1253072f928000ca4b58baf5e858753a95a4453b3dacfe4f22fcde1a2a972114afb09f6334945404d230ed994fad0bab55f07ef2e7623c45e4161ad04ecada1e7e9411d99672a74536bca6cf6311855e498fd41d005d354a20836d7576a7e366c34ed531e84e35d8466cc1ea0ee7715b25a2b80afad12a9b6b93baebf71bba00932778d09ed335fe53bf1478cd59cbe328643ba23cdbed9fc9 +SHAKE-256: f06e1e7082ae6e9a87c4ed227a5360a7919973a5f5cfe931eb190fb8a6995652ca2dbb123525fb1f8fc5b11985cdf3579fad61949f991d8ecce71ea99511d889e59c5262fcbf4adbcb2980fe87fb2e64273782d34c1dbb8f07ac513d7f7b08bb13a1922f6f62ca64b08012e89bbe3582615e323e7dc398239662a862c607d0e71dd7f9d3e8b4d481323acc5277ab66541b60009fde285522588fbac6abe7edb3b3e746d13aac141f4e67332abd19ea97569079ead4435b98e4490326b116d87434292ba1926c3d02c47829c8e949e9c130003d9a657abbcf1ffd80fef50f95b6f09bdb82f0c8be1caffa2f77c1fedd951e4880222590feb5755fed551b1b4977c2c353e663bc8773a503ff3e4f6dd7eff9406b46cc56d72543313caa1514511a21aa7beeeefb47e8e6289c43900f808614f39ab2d66312869bf3c360005393c0e1909c6225e1351d92087c7adf676ba13c42f1218a0cff0a8f5838881c8500399b9abc78f9eb918be530e108340c9606c99d1708996a4f9580ca91be9c82ad1b1814c62dff9bb8d6e187198e4aefd56049e56d240ce25dfc63a4e3f0fa7aeaf157f8f1a4bc02ab52a2555c2688acdacfb29e49a97462f9c5f8c81ee272032a99de1a2530e9cc7bb72c4483eb885ab0a1071658699bcafa49d392933d1550274b4175ecd6ea3c6835cd0ce82c9235bcde60b19aab6f3656ce9e46f760e9e9b324 + +Input: 9fc04a07048c65a4619816326be35244268d362f6acad6cbc0256d9ab4aa09ff1bd390919c16bee0981cc16ea7414d0ed2d8a24cbf6cdd5f41534eee23addbd0686988d2a7faff38197bc9e1067f00270768a2dbaf76e9533487567a7d5d067a1fb4c3dde070bb4d06e34ff9184147aa4b1a777db972df23163ce5ef3e2baf0a43255ac1f5493472ea12186e785c9c4f1b52ebbf49398a6cc1d09615c56c1f19be314ef17cb1255dc3895fca0615f63fe14478c7ef5f37882f5af11925299d5081e58e60a91cd94327ca680dbb8574f4b2284b81af5b6e568681c3d3f54587b5228fc80d448337dd5b5e07ab56382c04d03e15b709d84880396afe5e02f67263412a933a19eae24523f231a6977b2702feafe8a5b51e45ba37e26cda1b21d85f1cab5ae719f971a2a21b21e32f72a4adcdb8f1fa5271aab422fbaecb1cb6bae439abeececa66d59c561a9cc4ec088e523b44336f0ec4ae04f48bd695fa78b69d1cbaac64d24e9306550ee03c52b3dbf201fc490064cb0a0f996f1b3245b3f2550612ca313503dae7e6297c3c43836d8eba978ebe42accd974ada78a47b596780856fd9a242c9bd7a0fc1763eceb328dbed4218979aec58fe3011806480725a76f07277b292a6e5f9e642d02ff5ceeae100564437f923ebdfc3fa74d07e56f4efccb4880c7c +SHA3-256: 7c66d831914b7a863cc52c3d0bd25396ac9643a57fead237f93e63f9030966bc +SHA3-512: a210ed0ea54e8f96d28a985a5d1a5b9d6543f57b706c8e6c419b2a32f27b57c6657a430d8a370b6c4fc1f814ce6f6524b4b4113793765e2b9b4f287c8283077d +SHAKE-128: c5c455900de6ee39a99756b926b1762f96a101acb9602a55901409fabe6d6010d4e2f366365a101fbba90afdd7f6ae837e9ae4557d8ea7f85dc3a18551e952445a37807136783f4201f1d456b61c4760e3ed1df8d6f1d5de2b571269534019a3251658fd898159e6bc55890065fcb3d17c03401babe42357a075caa71083fa817a6ae59ec35bbe6897ff5266f9207856fd7e8872c8ed34f3f72861168919b2f8f82c15704384c968a8104dd7fd567f5b9d06556a81cf676a3f8b56a8eda55c7a8d96351a2a9494d1cc5988b215b8702386beba21c1e11531b98e6ff21ad67b7530f7b4496f700689ef3fb0361bb792483942929deec18abcb7d2a1de761ab027258c44b5a56fd28d24226cb84a04795226b53fc72045f2bd22d5b2b7d6437a2c4a301831f410942877993eca3506aae97690e21fa1da0c3b86e733b31c405cab33fb0f1f635d2a59b71d62b939f32010e011565e0ce6e83350bb17dc0a2ad1a69ec26a62d8ae2968020a984cfc57580946094b7dc8929f5216fc1654b29739478165cb065cd44ad7ccad9db5915d32ef26efa111853f0c256265898ac6536440e1055012f4771d7c3339fa7d188cbc5be4698421cf0df83a2c4d31cc84ed73eb9d7683cd9e79eca1456174a6c6553079bc34ab0e25a28f9be7643d4b36c691617c5461324a5c4b5ecf5559819f10d85bfd6b8c54113c23a640d3c97128ef0c2d +SHAKE-256: e3492d1862a62fd28703c638442341c4469109276d81d5fc13f765b26b30ed73ae841b2faed11a48742b651e65964315a059bf5c7a5323893b250d9a0acf7247bddb73cc081a73ccb246cbf60a51549392216b046a7c73ecccafec57054f7f455e8bdb360ebcd09b59a7d39cd0594f998849e18e122897491b01f8c6f9497bda3214fac8abf5195664b4566f9a09cb02166c8f5492fb5aa04e78376aaddb8bd3841aa2ca403350c77f8f6b6cf5a5f69493390dc56d7c6ce549f08670f4b0efd405452b870b8135df5af01e00c9644989a83e39d0144cc9b70e1c2be455dc48b65683e55b4f3876c109f851b80092ccc23d5a98be1d1ac91982c25fad7b8403f07d1b9d96dcf3fedd569f2bd8d90cba0372c8ce846a2ae95a56fc979bf59391255959e42b9d52416f4ff2eea67c9589c39f79d3f2a1780426974aa4beab11f75004ad19896ea05853d3b6df417ce8a3d73660f8c421911b2f6d4f1da746a3cf63affd6e347e0cdd3bc4018220193408b7c68fd3f1bb50057b9a5b84223edb5c45d95e94f0eb868f87cb39bc8feef57de6abf6712e6efbb2b202823d53a4b69b02f19ca20744c375c3dc50918225d96c3732726c4f095d0abdcac08d7c3cd2ed1c1c5a1c1835bb2792ad5d5bdddafa0b3af9ad59e7a620f281b0de0135091a1c30b41438762cd788ee13ba19640985cde2e28f6a8d6f19850d9fa41ff754016ff4 + +Input: 195d73e25d45c48a6a226d9ef7a8832c4997e6670ca350d306cf6174ba993198da0d985b1651db1cf01e2d06f6c727dc0a6841e7377219822d3654018032206bd30b4161e6c603586754d664895097364943f3e58610702f54f015b09f99de3d91e5ab645afca772d8bda8ab484685f0cb639e2d84b4cd55597522e9f00258ae8b01a73bc169e3c7b4c30c694b0df484e2417d9bb53c089f08906e5425ec2029db360ca252918d65a1f60f562c5985108a6e1dab4e765b99d0358a49423c5cdd4daeabc337509e477bc372210e4ea6ac88b9de337dfcf55f8f2d8c423d07a3247497072b00cc513c7688f2b81bc5bd65fe8dcbced9737115cf8733f40c6604b78a15f27c949fdb99a522d1741de7901efb08c815ca6e0c35928c8c2feeeeaf3c1718148dd32cc217cee422c8d681b5e547b56169ff648a436e94b78f7db8056a7d0e51ef67db368e3c5318652e651a5f09c4526dfff12ca79d1bf72bf413e0ec3e15de88e438f9932c3b6202710414e56d6cf865b39ca6fc4b251874727e2e8e1875dbd4590df601deecd14fb3841dd4d2311b1ed6dac775f43c0ce85aa6099c3e654a4a7505acf6662cf1cb96b4179617d56230e754dfabf5811b58f6e5804e42ec641748066c6b3b227db2d796a83885271281b318e46500701f73fa02e32e9bc31676c8a8 +SHA3-256: fa5a9dd432a8d176b0dcf2d89bdaadcc31387f7e08db879321504d0e4e1c930a +SHA3-512: c61d4df6539a4c004584b21ad6fe2fe540a4aab3460e4863015b693f71591c79f25d240dab0965ac5591214d14ab4e40a75c2bcbe1a9ca3e590c0c8c3718b1e4 +SHAKE-128: 3581ab15527df1a2912d14427ada7f31ce1f2e006dc6d283f6f6a058eab27a456e0d37ee36c307d9ed5247e02c37338a974de9bfe208e05670eb93012bed8c2d19f2966b5d484a840d68c263bfb075dc1b6f051f3b0825e80251c466497f65405d14fa97270d3fde2c5a5449a60a1c405385304cb42b323bdc06796b36d4082c7584aa7e302d19dfa3ad4f5ad5aa4c08ad58a022d81a1ef6225f11ead51b787dc5a1cf78861a1979731da29021ba649b28b0f9b44ec7b6c124748ccdd78dd064d38b9ad6aadd669d44c142379bee7b86ec4b9a46e316168b0156a4c377779c6e48bde3b77b5525f5243c9250dd7602bc09127a03aebf4d8e0a2ed8aa93e26edc95f7d67fe53aa80f151b697439967778045ac2671c231c408e93e519770ab4e82b98cc999518cf9e78712a0b8664b81faf194fe27d6e0115f4152068304078d5534d3d394ed17be2e284c6c320b340e50effc8b3340c228d6300a221643632332d3e0dde8cea147894239806a8b6f7135d0df551457f99c86b6fb6fff833f8df3898949ff392fb9dfc20c4fe6895a4daa1837e6695bcb7c54f8ad5c0680af27dc46abfb5021b019f40e2c17c904cc16ae442991d70eb3720e19193594c53424d6a2df49d51a12ea8a37f43ff2d7e8aeee58577a0fb83c33ed013e6190c2da5b1b99575b858cce8231f697efb6e36a9dfce380a06838486648673089c642ddd25 +SHAKE-256: 007e33e4acc6ef715fcc507787cc9ba354e9dd0d7e59197c7ebf8e0f5d83ba828b9ece360fddddb44104a995c7b6f8dc54cc8fb37cdf0d4ae5d1f95fa1d785c9726d9d41331073ae6066be726e845654ed412c1691f2b32794fdc1a26f24ccc7b125e8e26d173a1d197569813c7a99ec44e60ee522b3527bb1cc23cbdf879936c18584de78ebad380d66593cd03164fef2fa19ed936c8518142076f1e8d312b3c2702d2861964be690196e0f38f0aeb5fe47c06e751c483e23cd424ddde8fefd65c609d9517a93b012565f8b305c4b2307919691567ba41a19a27273c384055243a02c7d60237760886e54adb84f153c87e903592bf6a5b06ce794f32ce14a7eaa774930e2c7441a579db9eef00ec097dedc8935a08cafd88961f8e2301be396f215b77c06f3036dfa91ad5e5f4604418d353c3fffb2e39c3570de8214d1e844515fe252d39e2b16671d565aec91279c3d89bff0ba10c720d4d57075f741ac564b83b922183982170ac3b8d1b4c74ec98987683a732922e37b7c722c6d719e0db2a6fba17de844f75917be065d5d9cd0a427031166627ff0651edb52fd3f53f21c1cf3f0ac5eb2e34a0c036491a80eafa1971ea4afa55ff897b53a4387bfb8ea0f870500a6ca9e0fb06c4ef675b21d9204455b052622df887a01b4bb166dd03ff66bdbad796b2fe0cd48e049e5c5b2dd89e3478b5b9067c4420c3de890179ed3 + +Input: 7f69e890580b4066084957d70d053503c658419c49e31125ec3be95e55afcc689f557cf19b4beb7ece0a7edb4790e37a1888801eb5b3cb5479bbbb88bfca174c3fe559cdde9277c36968bb32ed15bd3fc968209740c1c0d1b3d3a454814c91f14f5c592198ee1c70ba63ec919e823a801537f8591e7d806a168bfa65de9b124f9061ffae003bb07cd9c98e22b348b57545ef0d43aafc71c24316d092cf719f38079e0dce6446bf075f1a110ddeb0b86e86fd38acdb2be1a0a030562e15c5c4bd0a122b151bb6a1f48827380550ef220f74e0f820379c6be4819fe272183fadcab8a3a6eaef2bb0730ae11ac0e7690382593740fdf6eba7ead222c476ee4384961eed3f75a8b394da5151b4a923a6a70d296cf41f1a59ef02b2796b5863c6d9c6101591e5adb3b33b1e3a65d3c5ea4c03cf51a2c251631145ebc10557625596907c94160fd4ff606babd731131c77872fca3738d3ae017af237809c467bc2acf518b78c3c36c25173796bcf5a8b4e0fdc8178ceb2db36fdc1aaf8d6d5bf012fb65bbaf4fabc174c78460af3f92f8b0833b6b4c7605b84a3c1208b34de93a99bbece9a4946c9efcf6130aa9cae34a24938f5d94e0ee52b56c0c65a910d798e713c6226ba73b943ecd1bd65cf8907a88d5ec612c5f3dfb8dde648bd146acf64db8b5c9ada3b5b125d +SHA3-256: 3383ea99ea45979a53440ff476b0dc801dd56c1d47e6cedc017aadc379e0aca9 +SHA3-512: 4de378e4215c6d91c4eab7395b74c9b91967f0b1c09db62bad6cc97ee3dd69ebd2cc73403ee8e05e207ceb76e288055c340c2351c2330ce0d6c36e6631bf1c8d +SHAKE-128: 2f9f1fdeba81ca8a9ba1d9a853ce30278c6c54b21aa7d9f10113a6a9dfabcd3c7052d74b07a7463b7798c112bfeb87976e269a929feeb44ca6f1c1495ba07ba2eda6ef1d1ea2f5cc90b4721c8e28412b92104db6d465e9d02f6a78902914542024c88075f3e6607224acd1270b7b8f4d303ded37eecfcfbc5a4e21037c23f30de84e45681267f6ec7aab5009bcc3ed3604b5e315b8f08436d97dbd43039b2098a8224fcd59300524d30d16e547d1066e74af19b1cfa2afbe3bc9b4c9302b5ce7519c7ee7acc4f6b2fbf4fabbf009ca0d7e2da3e9f97fac6e83123c0d550fa3e87b588bd20425d0bc2d771edd666ab2a295b4782321c317d2f2b0adeb801dd7d1b5d5b6635d69672f58711ac2f95b719b1c05e031fc0fc261b32d665bc88e15fa074b6b92160fcd28829e2c6756b4699d7d25bffc7a9ae5535db5ef21bfca757b57bc4c4af7bb32b095b18a00b7eba74af0cb85b64777ac86e1e58a2c4b8a2dce9382a4ee2a11e8869a00ae17879dee3580de3d1da46bf33eba1a79dbd579f9b74da02d54c91c9fa20c44c27f4c449d3fc158240a30bb978ed060a0c153917e604c31ffe8dbaba5525f8cf514e0094458b0f724e3253bddabed21cdc3dacca7e04e21a3e270d6f0af2a48db66df7c9e93ff8ce5b1f540a8f26e8cd2a5056c1bb2833878cf0d9605a001c568bef9ed97d0a8bf7df4d30eb441a2ceb1ece475b816 +SHAKE-256: 05ae2864eb1d84bc243b9b07303f786cfc092975df77e71c342b3552b4fbbee16038c55844966415ff522d93c094c7a74ad093e63fb8f747a4b23eaf80be56fe85f38f20ea4b1a9d72e176e501d5ddd893cb69608113bb11e58a949b1db3d14b0087fd5ead9a9e8531272d7a4fc0c88b1373f88aa15a309d45e6559acbdaefe9c237d5689c05ce683923417b8f25babade353fb8bd7c1efea4ae658744f060f7ee635d817df98ebf7ec1ef8f00a9f7e823c8f8b72018de66264cc9395935a2549cbc0709524e563f234d48ff810b2957d30f015da424b47222270448304081924ab672729c333b7b6076bfaed3ff15f7d550fa2f5a6eaab9078bee6cd791d1283bb76d93c5e852078f5958566d8f0a08c92d7ddfdc9ab01ecbc73e920d19fde326836f403fa3830c454427ea5bdb68f07beb62e203d5d51e459d9d112618a2774c5e6a3243b6769fcc98b9e4a833eca1138367ef89af7e1b30d0cd1cdbc822c77c6120380c9be53ca19b48e1f5a2c0182bfbbc9e019dd0ca0a3d4f6cc6f9a82b2fb3cfbb11e9aa5c92d79f4611657912d477de40d184f39d521b474cde739f238e9a8c709c687b8daeaa70d45bc9ca9feb3849f7ed27ca8fbd8b6231a70818b092ab2661b5be5c31c5a3dfb8fac398022d74ebd976277ebcf21a959c7e481e57915a8c79d3c7a9787721218e98303cfd8bee9ef8b483e596922dff47e068489f + +Input: 5a50d46b1a16027efe85e9778227f0034cb7eb688db5896870a8cf19d95c42c962ee2f36943d5761a665f2532a8407a38700272abb54d6aaf105364f102fb5b2f90b59be713f2b179c307443985e0c13b13e4eaf6751bdef677924e7f1253cc25784fc09c93046d0d89854280f498797c8e7f9830ad8c3cd6c40c3192e03ee8426db13ac0a9112a5abb5297c3f5f723606abc2e329df978369daaac3e1e69017a04a6980c740ba150f95031c316ade1bf9fb5efb9db5087395aab8387351f826631f77648a0de18f8f13f5ff6f36c422a71b3ac6ad07f252205e981dcea720ff6b90b1b4a53a998b50b28f6a8b6cb66a3e8ad898f839013cf40eb873cd09813de8daf6dcc8ee8076f26b59e61e585f103ae28634d61aa11ac65beb5995bca509ce55021924d166df1cf38484066ac91ec5ca7f994916993e3058fbaa780e92a5a9f49aa0a107f2d84d4c12f277ddb2b0249c7ae666f2938c046fb1ca02c7c8fef3535fcdfff3456192e9b51524d6563b81be9e6b406bca87f49282f71666cacf6c5f72e56fd274f7f5e10caeec7738d2b998834ccf2a50105cd1c2eda8f3befa9d6ddc1129f3b90cc719958b57b798bc7714f2e9a4058fb91381fd27b9423309b158adc1935880a499439a6de102756e5a62c224b1615bdc5353bde6522ddf8a9c5b7ce3057fb57e +SHA3-256: a6d5fdfc60c037a0e8251eae5c401f14628ce51170797ccab4cf13f530db6d00 +SHA3-512: da1393d798a4edd0456f166da6b054ad588e6b1ad5fcfcc2d8ef5c3cbdad5debec8636ce292a144028f457b3bbb73bfab2d801525a16efe043a9f525e7f58312 +SHAKE-128: d58ee3e6c1229a6c8bcb32d01c5a876bf5df62341edda962a2fde26554103a8787374d6e04a21d28453042d58db0f8a7134bb954838db71d3c24370500d2eefa0de21800357d82031ed405a938b037f4c496168bf76f6dd4e485a8992c0aeb64ac3ec5939ffe4d9fb307cf6e8041feb2be0ae0fc7ccff5c0063c1aa0a40c7d755e92171279df4e1acf1236d6e82b39d224e262e81d4f35aa8133f4c17e0854be76d63728ee40aba5c8b7936bf3147cdde7c09258ad2f8806a63d5e7283e669e9a6b20708272038b52b8928e195703a390c4fbbb39f4454bf237c0231b091724da7ef31cffdf70ba66e2dc2c54e92882775003a62591116391eaf99aa0c40c2c65a79827a42bce775ceb46c7c40630b9c1c6275626631aa7ddac83531ff67e614fb88c95338b8aeb041324601d0e280d50ae739f37545a2148697524da4e939b3c644a17e2563e4403e6bebb3c452bbda8d7d7bad4289797a2a7bddf07726592fa93e4bc27c756f39eb3a036a023741e8809ab96acfd6e988af3af6da0cbca69b08247b2c02f35809b74ec94b0f0068918ef955ee1b2a2b74f58b3de20ca4a0f8bb2d85e803b95f63fe1e8f57639bcfc2f4ac86f9cef34620c410bc0a9b31c28551c7ed4c2a6002287b34d789cbff8fef5451be3ac930bc2e07687577a0fe4860135e186f0575bcf3732c0b40532ee358358c57378f102c52ce822a69e371c9d8 +SHAKE-256: 40aef5f901adea15115ed69537122f493a372a6b5b33c041548bee53e12f0858af90a9a1b28a6ea767575038a40e07fc35a2f220e53a1d260d7d56ee5fc64c0e9c05fc42410434a1c0812b8d1105f10149b6da2830afcdb7472b9770849e9a606a6f1f22ce750ebfa0c6745e2b7bd6a5106b41df3ff7825068e663f26cf28eb9c739bdf18cd534fe3d44a5362689c7b09ceb21dbaf9652a49e93f47a48019ce42af3eed4125f151733431fe1499e7118dd95d7b57493a83d66f9c827b3ae484c1fd5ba3af7042631ccd785a5ae313f129e5ff6b011c4024a6104820528d60dd1bf9d9ae3f3f64165c80a375610ed7264c390bac7b97902d3ddc35c89284cefa23ed21a1cbb5991f95aa89f1257a7e037d80f10ef32ff45680acc5749cc9bf55a22c346d99a7c528fd206fcf68826b569c740d47a0033b44e8a63df685f3d3a84cb000973c4770b8dab6fbfd981665b9eb5d8eee43bd482310e8f60bc30c1ff578c4178a51848c568a1c97b911cd89c0f4d9812175f77756533a11e6d4d6c15ed0192822b423e3b94f98b0a5d7be514473fc0227493a2269add03f530ccdf314a12b478c8cc6e5f14a3da2a15fe5bda85fee8594472c0478fa007a2d4e199f619bec484e2b8ddd18376dc7107ec0842025b73589ad171914a5dd396fe6d03a4fd6a24fe696dcaf43c1f7deaf9f3f7392058b602efe0a8adfa37dbec92385b2f05 + +Input: 8a5832b140a0b4f9e16187431277e4bf655a7b1965840bc640af05baeb217d01f06d1754c24d988da25d4cd2b85ccc3d8a3b999fdd1262ce70cbe99d92b120446370b42874a549470ba2fc9bcfe1f8dc607ce72aa48ea094e17f5554f909941e55d76bac6bd09a1e32aef0143077394d880d6ea04a1569aea30054ba6cd722e14aceb121ddf0faeea9dc994db6e390e5b34f4170c76504310911d40de4707b16c016a7b41bc6a070524b205381355f872528e4b3a5789e446aa3e885903b39eae839d1988a452a39f0c6aef7e977db2f20e62ca70bc4c35c76d3b19a9e708d139477f2cb462cba4c1857a232472afd209f9ad26c16a475daf79b40318fbc178d77c2131928daef168e2298729c89c72a55a2a0041951d2dc115db4cc8f7a954c547fdae0db6da2819d472fa9d5a3c8605116eac775a62a5d4d1d7eda8056cf6d5b2778fe8e0e8006181761c249d62b1c8fa01543e4c09fb5f7b0a92f90a7178d627d3223e67a86acb9798e866c8ceaa1a80970dc0304f733ef5b10cfe4ba6b5b3ae8bbbba1cc417c4df85ec3e5296ce2d6b7a33f050da72602ff7d5a5cc5f76d040b7cc4ed3b5aa656bcf0e712dee027f57a37b1ece91dbbe6e933418941f3ca56743f061fb1d2b369f1bfefa7a94cc6bb628a651079e2e84b502ad3b1fd2a7cd26d8e04c83224994a +SHA3-256: ac68c97c2a33bcd2321ca540a4334ebaf75797b1e1ffe44e9d7c0df0e93caacd +SHA3-512: 2ad65c80ff36b61007e2bfbc158bd4074e2ece850b8564f0d83e184df93a31948bbf66e67a1a77bf56b9b272ce8b9e3151fc138275c9c861578ea5753b75bbf1 +SHAKE-128: cdf93e66a56665e61e899a8730d632784539a587a7609675c2d86445b4ebc5509c380a1ba1247834f59119420df7dfd405a53a48bd6d928158f70a67222f6c0262e16faf25ad813ce9ab81711c1df5697fbcdfaad834f0f81fbe915830ad7ef1c7e5c67a1bca8ee0e4478699a8cb89428e183cd655d0b8b2baac0920b6d20bac028a7cab2751e94288ea7f433b286717096fd277e23c44b2205551b21c583ef2ce41012df93445cabbd5b97bb0f40b37d33e1837a73c2aa9aeaa801e114eba466c9d0be67742b53d0b015e840cbca74427e9e22490a2ca0132e578a25a113028628e6c818dd7cff3f47fc81055a431613d978e2257ab1be5032c67d20ca1a7d53830041a7b5058678f7be3e18e10664bc7715f01d09eeb688a5f6d2dac013f636ff09e6c281f2b5877687c3161c0f23da3b5b69d591b6b16303930953d79c3650b6d12d6f52285918e83d2de6a01f6edbda58cbe97b6b362ad119f8023ac3a29abaa230b4f608f3d2fdd511c14e1042ff2633cfbe0be8205618f4f56f872ff49650de7d99cde36c1eac6db82d41ed5ae9cb24f5065a0338b80bba1100cd6e4147dc1c59e0fec7a563681ee94f0f282db8024539b2a3e56850be7b9c072c9bf1d5dbbe1108e0506c49d06cdacf2420366ce69e4b877d8f9c4d5a1df49eaf43736714f70e972411a305233e955a936572de8f35856ebe898c3ce2a5afebbebdb82 +SHAKE-256: 325dc516738feb5036e51f5d38da498ceb01c94286a79b18c0d25b23cabe37a7387b6a5777457ffc552771a54e0e4a92b431174a5b72878357aa2efae7d18b66b5a65cf4f1c67a2e3a402c57b52147e72b35e405e9f3a45650d6acee8a7e22b40cf35b1712b14fc3fe0a1e8fd212dd6375eb9b198559fee2930b665166b4cd467134218b6e8ae309258099ec82f31a06b96820176ac107965c499ca47a42f1cfba33eb3dd21618b6168c4745ad5cfe753990f50d41202fd2187a221e6642ff9eab167326a2326941de85085f9aec347d963f7c529219b4a4aaba96ccda1e95d9a18210d031fbf7502301099134cb8d0e17c10391e3421b0eac44eaf0d51009dbdaaadfe4f96292ab616679ea488c2a21aae8650138795646557a46d451f724e864898b3038e5ea7717b8ea2ac5bfecbd809c8a5da871172602bc96afca7225665e8f948a5f2ac431d4dd3501ef05b3fff73e5079b4917608e7f4201dc85ac38331c11d78ff6456441330e6e5206cfa7796f5381d46d812f3851bea398b2b4523b2dc6d051f5a1bf4d6a97574c2bf076a5bca356fb94a1ff47f5b18ff6b42f85c70da9b25a8ade373a46bd2af4577d47944a01452ecd65d84f1131a9cd9e0304d22176283057eddd42d576fa4769929b37c695c5fe045fe8857d43dfb24c1d7807a487751fe89d0def5418fff3a8801c3d1cb720b6c33af92cc05ba38ef68b88a + +Input: 4d764821b45265a1d2cdc821e8bbc17ea9594281430d8b400652384dba2b6d91bf1e4b4e527fb3e76c714f41c91d34c2f3358c81b75e87244a05ae0fe6de5c6dbcb015a45578582b1e1cb225e920b3aac2a8f334c0125eb945bc36757cad0ff47c6e932fb0491d4f4811136b6ca38a6d5f8d276b4f523c12c4b4c0fa2d5acf1a38c4aadd69efd9168cee911278abb9c7be76faa83b6589a35ddee26569ce12c54ad8e86f6d2ad2e06b6fbdfbd343a0ddcbbb3b12e2063814f3a18f8244d1cfca80c78c48a9715c11b25eafc90d4022520d798fb25649585efca51c5639353508059719309ff2ef28135d00931b7059f31563d798100f9504a263d9743ec7757b70b5edb3e2c2ff5669e29dd670f4ba1234be8077183ee6909571af06cfeed84e508bb6d8c9f46330894eeb353f5ce5ab6e8dcb9c3bd5be1ef33953283fb0a7c7c6829d73e90c7f6c0d9e830adb9058830166913d32feb7a156258331659a0dc03ce5c22cb954036099c944132d7611a67df1e61ffd53bb581b4b1307c3846e238584f122893711b028d92897d43bb5cc8c34d558e49fc53cbb013dc9443cc2c8b9f858d70a65ee2c0603e1576d79c17cc6e00dbf20f5efe3333fe611a5bd94761837ed763f9a8f1165b4ae4127cf79ea6522359b06233cefa46d79f7735be0c5134df34bd04d2b535ef5 +SHA3-256: 949d2beba17b67f17643ed62a3fe9cb7d16d45f533a7caa5e5b6c60b943d5d8c +SHA3-512: a987f642449a1c666202e4ea7e799f3ca657dfbbe2d310519ff300f04c62d2d796b69d4d3930fad15e4d1ba240d58f5cab9551e592cd48c3b3571ddbf65f4c28 +SHAKE-128: 1c5fdaf827897f33e600502555071e7f4513567d8fbbbd8e0c989dfbcf8314cefcaae1164c9e0b1d57aab3c56aea11178d0f4a3026c614ba8d938734bba8bd43300af05b370294cd46752fb8bf4ade52b60fcf92ec7aea7efba09ccdef8fa849383665207fb01de3d853044f0fd942692d6c51aa11c932240d680618065eb9cd4db7fd46e97f13e75af787df8729650aa183251cf1da89d283e56814cdd0d9b036af7319439d66dc568a3910254d3927610c14c92ad8fccaa5cc6171c24d2957e7fdf8c357f92614098298d3ea541ffc3b0a67e2a126d3625ef9f3ac56d75cccd151f5fc6d15a489c7105010475178093b82a40ae6a7d08057d567f87afab53a24c0d1f5789f41f29b841d7c42b6ec158ec8494c056d5214100684879a5ecf15ee09fda6f05b640c3640902688061a38608084d6731c6ad979c1c41c61a20a40b0cf6076490fca9f0605bbffc0e40e36c5172d69b79a5c4da1e8b7e6b09a142334318177447546df26f0c3ea65810c73f5e2efdfc00f1af8797fbb5f423caf100d7c93e54917c1a2ff8b88999a673c3774f703c53d86bb1d0e2ad578ddbb385d329e5e6b2ed23db161651272f79347daf2529667af869fa8e2d0333ad9306e7c8c5b013918fbc97236d47522a36dfd4ff01a80bc82c3ca613246d3e712a44f59bce3a562028a4dd57ed1d6be72a7cb365ee250d83322c1fdd43f7a26058b152b +SHAKE-256: 54bf4c4cb0bb89a8aaf0275fac735252c1f456c81d128127ced9f03ee0d2b612f317cd6343a7c18104a6ca59ce2388077a8ac1a09c8aa01d9e5dfe37ce0b3967d945edd63a976c503aec34cd12b2ca33909af211d114a86a3bbaab14c9a702262f31eb41428b68666305e66e59ecf930135c50836199392a1bfcec83a97409d34ae347161ffa6eb2282f2e53799568957018c7b7b1aec268601fb3f28a145fedfe8903c670c8ce17d56a7af0d97629c11f55df1d4e813473a86270d40c3e66bc038cd3a0af4af01e57561bbc096b8e91b0138706af8e8f6be33a2b6c19d95f691d806d4884894daf811346a4995f3720e010cf9a0aecbc66d260984a7dbd2d4e83796f75f691ed8f95c9342e39b906fa54744c566b4c7bd9a905ff3231d48c702db715737f8a073253fcadd92882c7e1e0607c6e743d93c514a1245be9ebe76cdcc4f7475c4cadb389e043c9184a87d8573dd291dfd18b743a73de225d4798b620462de14ad99384620148205e1248a7a09c4f2dc24c485689dde826fd0d39d5491164aa3146b29a3c275e3b7d55ff32e9e31afee49f1a5136afb24bde581926d31a030105b7f7aca58d00b847362fdc9025ae367fc439b7cfcc0e8cdf1f5d377a7b295ecaa6b33dda5a555f0fee77abf2d9c828b37edfc3877a007836594505f84bc075343cfe2e055b97e4160454f324c9431901d780cb3e4b33d96fe04803 + +Input: 4885a9ac08a9c5d3f089f9b55e350ca3e6e44207eeeabe16a83496da7e5ec640b0b671959b24beb855997f5148646404894e87edcdeabca90c79d110212d99e260a298d4e7e778f2a932eb5246622110cd6cdb6cc85161c120512766d6e32a38950dcc84035fb92665f8c0f217c42fbf680438c225071091437c3932c7f551465e37774e70afd7cbcd9a1ac05581df96bc939233ed027fe1e428591c78223d292325a0d17ae2094c72dc443353991a7760952ad4a19b7195c847918e2cc0d3d4fef21b4fe5dfe1e96f3e7f0bd96833edd5a88fdc74ec2040a3c28be4359248f44317caf9cdba34273376774feb42ede9335ecdd4023a8e21b4e571a60a1d505b00bf74d983980430a737cd7c485689b82a7e16983eb90176861357ac44a3591cf0494cb5eca095e8ad86eca2ca9873972f4e17f9a4a1285e337ee529a28785808c6ba4837d306ac194b95efa3c5a4ace64abdee18e6971d838eae8bc3e949ce8465317471be8f968d6cf725b151826f606070e68bc649926995814093ac991e6278b07f9b398da4a3e9cd0b322ed698ea53aeabe36794a14fd5664551afba1ac3cf6716171d7d05ad7e7b92320ffa6d5abd96bc3c1f437f006fd103c620aa01bbc0cb3baa49201ff1aed515b9096c1cdcccaa28a02b107cde08ea659f7ceb8e31f6f54031c71139fce4ce6 +SHA3-256: 999a61642bf1df03511445233e02dd1e866d2e09aed23a633f10369dd803dc93 +SHA3-512: c72699d962d7dfaafe0446cdacd21724ecf262dd1ce84b503eb09c9278ee72acbf605d6044014b29bee7b47415a143a90155a549fc22d9507647673b0fe7adf2 +SHAKE-128: 0ab92e2c6e0f1a32c99b652fc061757c6cdbcfc3eee9544fcb9f60b0d2b41436c0b7c2215da80881cd08f146456abbbef106de4e93057b9b46a2e1e60ac09ab9b04b04aa54428d710a04ea836f2d302cde80592ed9db9fcfb71584b163d20df8c33cf42fc80f1c456fe0197a22147a80f01ad5a5b2e9c4995325388704e1b888132ec40286d859046155d1d2414c05c9e4e30f1c1aa72551d6810d4f4b92acf352edc50f27b23a79d59b7e88b4fa8d2f038051cccbb36e9e52632d78567e7f102387b23ef0ded677d9858cc53e634296a1d3628e0edee6390a40bbc2a3df2ae96c89f45d61a9d0124df93d0a16e8d16a27df40a0eee37edd3b78aa9b780035fdb0e59c863444200ea53c3c92f130c9b88311b02243c5bd520273ed07072acf2b7b09bd302d6e85c41528dce2da011229943e09237a76b4495c1cbd499cf9691e3696aeacbe686340181265b894b82445eea7e146d8696da89c2740957af901226d34b04841d9bef9a8966fc023771da9daf793a73bf9801f92f7c88d4485b512c1c44fef1e529d86db1384e3318df32348b781fa3c39878f2e1d53ebb009b28aca2ac8f58cb8974059572feab389ca0583603640e48be659208095da0a4725ba34b69a3a13914263903247fa3720992877385b1a03f11de0c683839a2dd64b51ac2165dd746259fafdfd552dcd4782968abed092c6a3df8f866b148918ccdc5f +SHAKE-256: bf8f991bd25c67ce1a338d9f5a992ec2f75570f057ccaaad365030e6a585f5a54021a4aaa8ca34c8a3dad353b78cd6780534f06720016761158924c422edce93286967c003f117ce4801e8ec3aa94250e6812b04954c70ecbcf7d60b90ea631c93588d9fd8c7fd7d163a64b42d88c58248a60c52cf37901ccea4af669034096534e10dddc978d2bd5cfcdb02dee3ec943765a28ad6776b38b7246485b0a2f575adacfe74e8198bbbe0dcb9933b2fb9b4cc83386be5b0430bd69b9d65e7872481232a7a3715499d07e14d34cf5814508258b13eb386f57c7ea4c94f04f1e19e9d7a62135cd6955ea1d89c2c9457c15358630f43c092ea19e9886698cac59e38a054d188c1545492e0626064df3dc0a167380309346045e417f563628e63cda6f3c5948dabfefd2ef597e9d7a4f5dea2a6dc915247baf76ae4fdd91521490c48a45bd67f1224a99a7afe2d880c8e3d98dd6796f2912439b7175aabd18192424998e5831c661cfb4567559de5e0a47ff6cd18e306c57a026189fbd4e5122b9a2db3a279ba3900aabed4f660c9c722883e205fb7590dafc5f50b3788a414e825e9a12bb630843d6a247597829e227bb6c6dbc16652678fe7ac033a29ebdf35a5aa9e4194dc945b316d6c53850c500ed86b757d4d327b7eab12519ee89634d26a0c0cfeb677966683224d8b2edb0828bfd317045fcdcb2034f28391f62faa8e28ea4c + +Input: 23ec41c5e5ffc5a5ee4d7150f9e38763b007f7216c527462f89b81964241d55e78a17ad6b5c522a5de9050944353ae6f7ed70428f86f52fc0a0f285231f5e95e4daf93b31c2fdd71cccb649bed14ca36b7a07643142f4280082ec296f8cb1f7f55ce476896ad8422499b5572462c35c0fb9e2c66bf3a90b7f4ef6c1ae61bd738ede61aa4d78b38b22f230d9987a1be7b3ec7c4317759a244eb2b0ccd4d47daf746881f64fff748bc18fcd85976b7608d574f54aa9674bb8ba43a96fb78bdea09dba871366e5419805bdfa6e7ba969464c57e4bc40afb408d300aaa33f890190b7ec33207973198054700a65cfa2175ab878c61bdc3ff19c103481cf814c70c4c25a14355c3bc8891efd557bd8b5c20685c86cfb8a43f2a68c6b6dd1a6f0f18ad708cff3113c38a78a1a0c9f0cb7e9a5320e4ed6cbc07c9d9c32f65b20a169ba8b217562b47db42f08d0a286e376aca5fcb4a6b125e129aeb5e9f210b5307fe819d9434e46f02d916467373edd2be2c33f73275d8d8bc0a5bccdbee633272c7150af3fb8ff1a35081370b5b83ce285bd229b1d38b6018ce1e7f0ef8302e007c16289f5f98d1abc77112be69a3c0c191496393e0bb33d417e4a01804e41a359f50e19842e650ef01a36393e4a33481b8dd6397e4dedeffcb259d8297cebc2247e959be7cb63a3ae71cfb6fde83 +SHA3-256: 22240d5a5104d8a5a87d0d9a4e99ae19c3a8a7220544dbca32d4140004d966a3 +SHA3-512: 5786f7a0ff1d2c988a4e766538a1241b4ee94cedbd6ee576ace0c507edbe0b284e8d20ff547edf1a7d73165000fbf2b140925d812ccc39fd6663041b59ddcc7c +SHAKE-128: cc7db292a3d7692de8d2094172e4cdb4369c4c69baca3c0d810a705e00ee309c7b544d63e01652663b2cea5301715e53962511125cc43062dd8f354f231c3b96778e7545516c68794952d9403b20e85d9e5b588e9d59b898de7b0af24c71323f7570f83596bb4e865dd74790db3cbf154a2db396d3c5dc6db59f6e54355b333cfad65280201ee8c085462b7c0fda0e557edc801ee3de192db70ae6fbb098fd71bdca71aedcf9f945536968862cede646ce9929cc47382f08801956871bfe4f7a4318c43d16218097ea00cb52a3e236c8299e4f6c1623ad878454af1e8fd8cee926b812c79b5ff7a1e5dfda80f788921264ceeff4a82f5a4a88183ff5d3c6575e5845062ba91f62c13948e4fb418f67e2ed38ef7dfef118e8cb1d7043aa3a589accb6b12b0d08be63377a133e9c14fb5acc7b8f8e301c409dcb7b39f04584a11f69c415e8ce03253565dde95371aa628490fdfc16d31fdc232fac46595d45887249339b322faca0621fe071dde3d09644d6117b6f4101eb9f6cc7baa86e9dc00fe5e41a632740ac3e0427d1308a8358f3fa90bb1f26144483d61f5dc54c44d39181b3ab3ecdb5ac64adfa9dbbb5f0531405492995e489de675f176bc4b801f9dcae9b3fefe067162e45c1e71a9b6ff929273b9ae5b254d137ec2f58a9b0e3be12d82b175f500f66b6aea185affbe9107783bfde009fb680b1fcba52434b7de941 +SHAKE-256: 748236d04f3f2b362769624c4487b786e584cb1eacbd8b6eae352778a2b01211f0e7c6dde7fc86fe74225e863f7a9be872797418c4359e4712431a9c09caf146059aa0f2ab5626e18e255cf93e3a34b77571328fdcbda20b4c0b81aa4b7d35aad8018d10e730685d33793f5d0fa62d3da1bc3310880054d4ef36732f8dc13b7e765a812dbde59a8d6bd4cd275265f5d802966d2177b555a610706b4b261c2c76005612cec244a52562059e3533d0536b49051626cde31262d9fb27941bb985a8372fe011dfe6a3f88c9bf0d8b732c139ecd9446bccfa0c2b3745438079ffc5f997578899e0bf364574b486c8d327d14eddc05954d3b158fdfa67769907fab6e2282acd5a936bb1ab74ae3123f5a73e4cf9eef10b4bb6f96b971d02be9194d087928fbf1ee6845376bcca257cbbcb92b33e83e769772f8c446759c1fbc4a0bda3cf2dc818de9d41d5e8efaf8313a28d4b7d60ddfe2df2cfc5414de608ce4b6fd3b3f2e881889dcc7f2927f568c1e655a41c3c800a2d4c1ba85a79c2ed9f06583f58d8e14414da4af2a0c7141575ac83e6c9fe865c4fde899627212424a2ec76a87b9dcc4323aac400539bfd72b10e8c979ae897f9b6c817437ee3d387c79f1c4445a37209e81ae42ce88b04e8295b99a55b8a40cbc735f8661eed7273c8c5cf494f91f105128ae2f9f6e573519365496e442c86a6adce8c9d5cd72ff621cc5e2d + +Input: 151c273dcde140224b47bd9aba66db7db5be99b261e30506970922d9b9bf8a35c3a142cd76b31bf2bd0081e2600f0dc01b0fd25df18004d680de5f963d2f59074a49313f310abcecf216ecae0384ab97188cea4f5d5a6015bc020b2574ee21848d574a3078493b19633c657105cf354065ee3d9302292bd6097f740516de65165c5e057dc8dc57a327444bcbce4098b7c3b88415bdb82806987c9de9145808ab2468d323bdf4f38bcf8ef0a259f9fc9553455e910d988e0694fdd65cefdc2c2ea79b6d6f734f0b68c049e41926682fa423075a339ea0ef5cb619ba5b22afda01d93caeace7410ab64e87ac7c7f3ee866b97fc0b89a3680adf77a2bd41bf0456d8a99ed666ffa2fda5657451387846dd777dd0e5489d309d7ee6631c8aa3356a19afa1d10e59e47bdcea001920576b1f9a8afa69dac1a2afd6b4a3ebffbd9954f4842d80d9209900aa841bf0453bb5b04e54812743c311305488c43758704a2eb2fdd8d7175f05b56cf38a2366e9e4a3734c3c0cb6c11bfea681c505d3e9222f07ef8ec306e02665fdbafa4fc6290f91cf18e2d1ce24d9d52376e9fa653c9c4c96550ee985408050719236c9aa32e76977282060a7769b92938cdf46508d875286dab65a270adc7a6fc06d7cc2da50b8c80c9ef03ef606d65acbad80b883e3e49d0b8c2479045211d93f54e2c27 +SHA3-256: ac3b241f1c4418393c1664e533ffd4eb09dfcc471dec3349f596329d5f4c5f18 +SHA3-512: 2f0318f0a43a0033efa0a8d274bcd7063c4c163fa2e421ee207f18fe001bb72d878265eb24e401d6902b58ed06d37f7801019dd0a5e48110dc22f721d9883348 +SHAKE-128: 53e1ae887fd4533ebade5b227a26d3fe2477a30063f3a2e3f84c948f08026433c8deefb9377179834a68366043403241e43779a13010cee2eb8d244163e889f71733c72759841e0a77f67b0a3f5bec4d1c66be7cbbf6d2fca7f43044ebaee5ce2762a46d172bea460c64026cb47ddf689dad38a94c4b6ae3fa4ce47bed3b1ce2d5ae62337a9d14f3301ea1262ae5b38ce27ec29e9b4812073fffae3109ac25723da5a401a08552654f4f818f781f600b7151da8685233b7bb637b9ad9823d179f28735ee5a5f39c959933b393aae3d808d38330d2133bca4c32330efbdaf16e46732d54d87b3e2d01c0b3abd95b51545e273b2e262a371f55170d2e953732e3b0662bb4c594f1ccee9102c1ce322626fd1f592026c42b514e8bb25649d6a5c13d564f3ef1fe72069b73804e80f2d9d925e0ab58897a7ebf84e1007b200f620e427813c3adbdd499f04d374bbe33ec918d82e648c19ef012c3c0938269cc6430b7dad864a1f6f24bc36693fd82ac6004fa5487f4f732bd5c103a652bcf825f732d84bfca58c4116c426b6da9a4d768ba1b5b537084874b3183ece9688d5e7e6990d2020c1165e789f89626a84aaf57a4dc1c297020e09b6b7cc1f7e49f8b4dedcea9cbd525e6b042b7ce39ce2d37297f6d4a10ca80db9aef1259f6a3186d7a46c2a1bf2d7ced78da80543925369c6a96d4de7019990c21fd69d3b9b58eb713707 +SHAKE-256: 3d1b00236145b77fd516ae0f045b66981ea1eeb1ff24f0d89126624f78e92c3e00c6d40dd0c7cfaef3a08f98b432d7a43e784ec289012015908484477383630bf12ee05701f3137acca3a2e0fa24dc3e5b3db0d54460b480cc5a339068c06ee978b150c73e2432ee8e9e76ab71b8ac7c5c562e4c2d7a1ba28d1b6e882cdbbbb2e013eeded0104cff2f58da9f523efee2d5a9c34d3f57757a49553080fcd67934f501c9623114a6ea005a7ad0216e5509d97dfe88351b1a8cc15bfcd65af521e17108de786726152c478c08c15844654bcf38b2f96e60519de368090a07215805040aef0fbb74358799bed00f428f30d9aa770fd760070e8f6859d4af3ab0f11cdc608d761e04628e402b873ee6fdab7cdd55168933fa7a5219d8fa62532c0ff7e3f89c336d8cb26338d818276bccb4b7d2da34cc438462887210c4b88dbeadc70dbf4c7423925309ab0fc3109a885ea3c8fafe4d6891ea44824862102f206deb6867f3e89a93712363d3aadcbb5c5ecc58bbb5692f001ce434a84df1b2ac748abaf17eb64dd50e16898deced602afda1bbbe89e1d4b8637e232dcd7791d17bae13d73fbb42d657320551fe1470c5d267558833580cc6d6b7010c52ebb7195dd790bb8de4ea91a2b7e63f90117a21162da7a924c9311e67292ef763b6526f5586c96d367d6c95b1edd8cc7e50a456fa8ad5d6ed0626b3cdb360ee7809e72e433f + +Input: d837f35aa29b5d29d2696b1eefb39d441f81103ea4a7cc3133b50b96fa6bc33360bb2e4b02525c63fe614aa4b44c1c9120e1770833af0ae442d4bab0567f0c34c8fc0b32d71eec0b4e925dba8df9c310b86a16c449b3776cde4e42e928242e8b945df4bc513a91c83d7c97e64a2e833b20bf534f4aa49a92d3d7c373756f9dde47312e4ba1d0f83c1b18149c5c1cfa5ab0e72d88a7e3ce61c411d48f4e1d1be22b13d42dbef018e633c02c0f8c251b3aecc59de13bc329a8c377590599ca986b87c70783f7e1bdbcaa4d05269ad6daf10422211a9babdd0d26d0144a00c50f2cbdfa9bc5fb3573c3b9b80cdabe25df84d9f923b612c16c412ffb5bd3b5ed667bde177ec9a2c6df066ec48447dd01bef2d2fea693f67b7150b91d9a46c3f97a00f4b9230466079bc876256fdcaba7a208cf2eac2573d366a24ce151ca0845635e1407f289744df564c8ffca7a96c5162f973176da11147265862aa179b2ca34d18287d9c6d2f1156da6a8048838370047e9db697cfbdc96bb739487b706c835e5f88a3e3be301c662f8cb08277e5e676c377421e132066ce855d9b89185a7803c55a2f152e349d211d4c831970fc44897bf2bc5d66bb93361588e8e8ea176d0dd3ab422b5bfde43161c5d777d5304f4329aa1bf9ce9e1cd3085eabd26af0bb66beb32a910c4850000ca365e046704 +SHA3-256: bb703f84a7bb4eeed9bc15d9ace7a408042c34476c32cabd3fa11f3e53d80799 +SHA3-512: 37f01652957316a4165e5899d21eec034a5ba772f18da009b81fee5a1d742995bfda878b8197ecba4816b598a8a06e034766b0051b558504e6a6fdaffc753ada +SHAKE-128: e230b219642791b5c6188be2bf4a9fad9c357a64869d1157d7973793b98501d8b14079118bf4cc7787828512f5218234d2207c2c58e708631780eb03d0f2fd1a8b5d8b8ad26bbb66793a89fad1e6827eb72524f841214c43e192ac91e0cb4007574356fe864cc383545b9eed4d9ee99007ea0b9f6de7495a7a4270130b7b4994231a1c6bd03df8e2537bb7be8ea89c461af0147b872cb3295118dc215218eaaf4f3c482a1dba0878c7301439181adfac5c0de5e3c1674cb3364e640db0921e1a926002ddd5e3713ca1b60297bd68811549e25625ad98a5af5b1eb9c7c7b8b7529811d874a6cf0a20f9398e2d2bf60bf9335dd734424c43f6d4568c2697a53ac2a48ae3d7aa9b154feead9e9b47b64695937985531e48acbf2688d7e78f6f15fd7ee7f9c369955495695f3f4d9122068a9cd5bf99ef9252398beeb35de7b58875656d271adf2eac0fc021ed1eb15bc0dc2609f497939ca459d53a49e9c7d4bd533ffeac5b041ac513de97c06c462fcb534d1b5daad6432c005b9620a6d859636b43a071862a96d808b6f35909bde4fe445028306d626fee9649de6fc56b77410907d530722336c659274b01a1a520bf9da4de9e1e36b395d3f25ace1091f8f9c5232dd4ed1404139a8bdb8a23226cbb0e080f56df21bf82bc023149c04d0def8ae97fe96515d821cef2f63b34f135c1c4da74f35c0cef932eb6ce4e152b24587e +SHAKE-256: 9b943f24d6804fe5cedcb0628ad40c4ed5d0da5e4fd2895d82a3762c65e84bd5f8620711861a46252b8873bb09c35bcd1cdcbd5ac0634e29cf3169dc948061d86969ecf3ec8231655c8ad0d029a9660b7040b94d355e2aa83a4093b6534b7bd6bfd66a9b22ccb57a6ff72422c0de5b9489af20d5ce0502469ae8ea2d6ff86903f4bc5b85fda8396286ed9cd870b4b1668cfba24fe693b1d87d2149a89c4087a81797b25901966b1fa2f76b1f5bdae0309b294e0090c45aaf7974d0159858393ba870d70ab65544246f8ab6e9c8cb59f1ae954306998156ee4abde4854a2b938122d34ba0e3caa4753f73b0c9b0de3cda80960b1e1c91a47eb5fceb8b78713cdb96a8da99aa4375378f9bc58eb1ef4962ec74bfbe7f89a64496d30f42f5b078e048606e84f3d58c3a3e8b027ce76c30c1f94da232c04f6f5d3a5e29ea302d330407060c3d5ba920c9a68aabaa3c4375a4a578c88974eeee1278175e555c8a71f5b807fa5d6784043359f27e418d882bacca03e79a3311cce3c8ff2b5cd2bd98ceb5b5de2ab87ecdf150f87266ac71c29e058d078749057fea88e6dfb8fa22693aad82d267711e8abb1cc3452e2437c7d79b75c0ac082b34040671da7b0a9274465c18d2c3414fac6e8483751c54cc3c08cf60a75fe0ae1dc447a1e3d7b020dbc2742ad8eac592903d7a7442b036c3efd211f97d06ffe983ffd5b59b66f03ad6b5 + +Input: c903acc9c8e70f62d031db284ed6b52e4de1eff957e4493715f77c4cce415f8799a50d91a82e57aaddbefa599b007b2b9de9f68e77f537dbc194d0fc8e65a7b4fbba4f1a248ec927a346c71eae57830928d069af934c1203497937b2c80548f2f83632b4fade2fdf2d0fe1d5fe3266cc558af64a459f77ad18feb0ab0a3c0ed012e6848c0858d48dc910043f73106546162dfa881750e65c9cdd9d4bc3942730077244b83208835fb2ed927cc2eecf8b0fd7049bfd19491dc539c85ecd1ec625d389518cf99a73b8582a74df9bd15fa0a7971a4c618858a84fc1ee561a0828c84355dcf7911789f371ba9c62b70eff6ce67ff511feb3abd900ec0cc648c1ae40c64e62a1ab3b98d99f492efc4fc35236c544dd7706165b33b9db94dc9d0a33093c6198826b7d0725a7a2cf62e6357cf951bc97e4a9ae7f89208048724d8202d1316657a9123d79d954bb3a4d0362d264ab4edcd534b338698d8f60f2ccc71be6e5f4ce0dc7916ad047a74f5753205db19f5be21aaabe9de5737f2352731586a871597c41fbd30061437dfdb312f56782666cb32169f5e61112f9d54153cc48a5c4089b9298666892583e34ccad14186e96efbd4a8fb2a7ead6741ad88ab55e864e744ab6056aeff3ec5ddb992c021f7dd24bd30f7d19b5e07120f840845bc9da9b096c90e85ce79c85e219aae04cef +SHA3-256: 05f0e21170e704990cd04297c9fdf2a67a23e36b19c21518b2bd72003c832964 +SHA3-512: 5e9fd833f5540423bf38938efc8bb3dd498c79ab05ed3f25f4fc776ec77bd7108129bbe23f4bd1d4816dfc3099219bbf13387804499c93b9fab8f1a8214c48f6 +SHAKE-128: 7fd81239edfb41b2192b97899ea438884ed419e493607067e8373673cf7a8380a8949d9191c50d827a5a5fbebe69b7c3ed3a2ecda963238400cb0e32bf3099d1fb44aec1099ca8fb3a86a29e8dfa8e705ba2b24b9c87de1b9ebcb46d9ba62399131910f3cb900a57d3f8f97ebd3f39b701e2015911427ff180b537db1e92347c5e41922930bb82eb88458022693e52231fe7f89d033109d3d2831c96bd8f4d8a6804e3fb3f1fb0b9c0ba2fdecc7d1f040fd08b75602fb73f0be09c77f1f5b3cb99438374e0ce48cc88845890a21934c1b5dae99a70db74fcaf0654e36202a6a383656cd752cd3c659ab8b8b622546e9f7db04f2b04a341b0113117548b258257b54ce95898eb90ef0a7325ce04f93045d3aae50c58c76273459b67a6249bb30a17750de55557accd20f6237360d3bd0545832a9a31415770924c223ae58a030d116f6ecd4ac826131d0763d3619b7061cc075fca92f83e8a44615106f8fecdd6045832779fb71af496504aca984e7c48a9dcae1f59d6081f74c9e68c7835fe5b51bb71d82f2302bae5df4966e319313bd7ce724f2ac510cc6ada4fbf5efab7fc93a849221f12e7234ad37dd1aaecf981e0a764322248425a0cf4c39d7ecce6ab2b25efb037e4c11d1b3a51a2f9d3cc1ce616c1431e017ab2b16741c59b8145a18031123d8aba9bf72787f04f13d0ae77fbf5a179e7488f794f447147f252788d +SHAKE-256: 15e5b441d9724b771874f838772667a10f7e2e97991c3348f6f72ffc44333f9bd343a90a2f8d08da401864e9af262cbd4f293bff29a3039aaa846c593540abd438f0e6f9c15c8c99a8adb5dbcbbfdd332ff412369fbbb3f44a5cbda7127f0125755559c185418076270ea615574826141bfe0bc35fafbc69d2468ac00f92fd140fcd832036330cede2c958fdca17c3fdef32ea0f3330507dd7f4878b2d16ae31d81f0e0b8f089b1422944eb99c5425f5807d93e000eca437daa00a4b2ef6bd8fb07fee249a836eaa404ee6005b65dc1717bc5aa40b310feace10f37a63e1ab84745f71bd255b800ec8bf0af961632232803557288d564e19eae047975fab8e23f666dbb03e3751dca21ae3044280ae9fd35c0fe78b10f73cc64657a9194ad9be9809526cfb780b944cd9fcecdbe5afa0560cc4f35de130abe60441e98a3115c255ec01e5e268125adbc8dd3579c05c280b8af00c3eadcd7dda49c7f8a489c1cbc5d34a5726fcde141eca29245cf36ced0b5cbbb20a3c0dc6e46833099bf2cbc5efa1fb98ffb9b1bd5317388568d34eff2474bafae0f62250255dbc25d3af66e915642e398754626ae669707cf471980854a495e90ab0fdd860d63b13ad3789efe02713ce528423e41af6c8dd201a16939ac881f2560fb913dc46e49b25c2232226584e2f83dda1d8d148ae7913e98835a4c2df9eeb015b6da5ca5fc68695f214 + +Input: 5fe2a2c792290da77a7676ed43b0a6f5f51326392133640362f60e0474f88da751f8de22e6dfecc479d635560c8f28b6675f5350cee9906fd296916547f83d1b24b937cdb0900acaee1e3ef0b2e617445f5ca7011311e93d78c33af2875bd8fc69cca9573ef45053a3fc7e2e8728b4de2dd4b272ad52e49ffc03c9f3965715c71f219d088c2eea59603ea6fc99da1a008e48e2f5e4779f07142baca179bcfc8c726c9297ea01c482b6c9e84a8e93508ac20c92f6e34b4124b4e348c83072595ff6d6de5d55964e2dc4201eaedca65928daba4c8d4804142989a40ad60965f131a0e841d115faa50ba0eeb226a34116554b4e31303af0b84e748e098ff8f45cfad0a42cfb61e2fc3a0c2c5198a4590790357512cc0595fbc05cc1159579319d8e553721f3047b79f0febbd6863d6f55b98d0f7ef6731115297c5216f8ff07168a22e0c49f4011284718e6abe213dd5a11171956203084f76a676e34c088f21de2ad4f51aa5bde9f56710bc7488816d0a5b74f7d9c1c297721012f13d9e96a80dc203439e53b8bfc980ce538acb88aaf3c4d69d4ef0530abd5693153d4ca4394af423ebf36cd72913b5390fba24f749973a97f99ef455bbe53f29b88250df5de5174e9c45ab4c710986f216a3b87c6ff97970042ea4491d661e6c62950513d6c6c6f7228feda462219997019a26b8053f5 +SHA3-256: d4afa593a790ae763e5ae2c8bd171558eb1ce7f43de59684ce789bb4d8cf1cc5 +SHA3-512: 95df45078879e3a1089841a519cd244d6bfd77e40d9cd9902ba02e394f694187e914b33a2eb8a798db471de99dfcb1e84f8bfc93a8730d8bd2091e42c214c426 +SHAKE-128: a5560d5e5407f00cf5cbbaad95e47903886886e42f280a203e9f58c7732c56daad4ecfbab84beef2f44b75fafc8de823d99e596ba4a9cc22bd3d032ad5db829047647af0dab8ea29a24f280f9210bc292b981e7be99aca6be5930eeef8766adc5c8cc70513b60efb893a684d4abba3ab3fc4fd3f643601e46639a0f75b5bf666d28c6e216071fdab9f04f3b2c5e43946f758bfb2cb108ef24969d5ae7b4ae089ec3452d3d359a921d7f449d0de4b16e637182e1cd2a2c13a17e4abaa79617292fc3a0b7d6db489573091fca826603d0f6b4b4dad2d3e1a1bc2537903c45d71b316e81c38009ed5cac8a3ee33542e8a010f50a98c8dd3d94e3231f00e980a32cd0e618b4038f262ca285cc7b7f9ade1051d30cf28135eb6caf1c85df4272dfd90e8fdb831c227fed3a05f811031de8fc201441f1b45368a6a3c36c9b2ae759d251496de732a6356689b2a187fcceb7f6c7efc0ae95ecfcad9550002b8800e72db2c022a1dd390db7f0cce400d6913b20998245b71fee51a0133f50dc3cf259c4b2c6507acbb61ee4d8104da861baad135e719724d414b6cc3f5ac88fdd03e444adcaad1290086696f7362ab15442373c44893e21dba407abc941b7549b8ad821ff95434d3c1e860e9d46469e46db0f85956bda355b762ff2c00ef021f81a7f439f5178ff3d5b86dce5c9b8d4095609afbe22dc1a84d8b3818b0c67ce70370b2a6 +SHAKE-256: 982a433a86ed8d3c6e4695f56ccdd077addae57fa06f65f71cf007f50005f5efb2f5d3c4825f988c6d4b6692d27c1849d8e8d85cf975cf97ce2d1d3165ecac29d77330b6bdd77a155ae7a9afe2eff7a37c62d4bb9b94fcd47cb27d3a88aff28b08476724a129a31e4367e3bcf6dce3562f74380ad1a9187d0685173d0e69a085ae27054611f62064bdf14ea9e2da7ab2e00e6c85566f2357f224aa9794aea29d6b9b159b73693d6d94c6c7d1be9089a1df3a13c1999bea7b942b27138770a64d27e70d8a57c047d962de3cef865d529a484bcdb710927d1eee089959a41e685bbf916414ee4d2c4f6c6d4eea8357f15a4bffe5059bd3d6d17396808845654684376907b7450f934934598389da4cfe5e52889e87083e913622c92d25f0714478724b2744a1a82dbac8eb5fd41c25050370785ccf23b347bf721c54b9ed93b66cbdfbdcebab0e7868528fc9950c76cefc0b155dfbef081610eb20a19c651f6076f7c4b025df0b7ac5f877cd3825467f59dd1942d092dc02f0e2381ce2cda3d35df157f2dc87852ce0b2b9c0a0af5cb1ead0386b47271c59927afa2170126450b7d5e401df5b72d6e0bce057db855e774360ee9cff52eef822cf4d17a42283dfb8bba59a0326582eae2aa767b3c78c7150417163e04e4f232cf4f245e5f376e579985006d2f5e2f2096ddb01338efb1404b2d9a4ac440092a137ebdec353747043 + +Input: ca3437b491242dff86f942aadecc8af47f2a9a33aa6b40b1338651677b060c3f9074379196b6e7061c78eafb1f433e0f86366b2a7f7ea1a6c209d161d55cbb0e568ce2d9a0860deb6057501ea1982b5a9c908c355ec0ff1b6ed7f4676d4a44db0da9506c767d8c158438dd8d24739b40afec846a08027a8ecd61b66d71423db740d21e1776607d541c693637b3700744a38ec15bc569ffc1579fca30ae1eab77ea1bd93ec0f67a9c9594ee7da13aa850a5d2e99eab99de41cb22ab6d314f4dc3968da253a8fe818b9d38b288c764c7815ee4d66f179c011e9af6c8a11ef8d3bc9b71ada4aa24157ff55f05adfcb81e8fab0aaae122189d72ce4862c3ccae2009bfb0416f5803623f7acf3b0b31b2e2af5c943ad3fce71f0264eb14ebac40346c46ef6a4d5c87fffe6f9714562353619ece1bedda2c5c6362ce6845750c29ab51c724e41194cb8b22cc03a8f22da8a819703fd2272b99739581f234a5cda2bed1b925a2529bf451e03102d196bedd985cdf67d84beb4d5fdcb1cfd42eab6a1ac51bc1248e5109ce56ad75dea4b55bb652a99558b51bc466eb0f91abceccaeb53baefe9e4b121ade4d9489af7c7ad67003cf1f2076a19b30b0e35e766a98085eca79e6c6d75252f6bd8dbc39672ddbf58b26cd7cc4ea85a5a2248679aab3db70e620ec56d6381b65cef71d15cbc98a19b73b +SHA3-256: 49373db0fa11e4b92a98e09b5513a63857ed21cb90a7aa49d654698c71fdf61d +SHA3-512: ed0d27cdd0c7f90edf081014f9e3252acb36f67820ca834cd49f8f7aa382e6605acfeac3c72f7c2f2f260c3cfded17dd5e2657cd84529a48e51d7ed548e64c8f +SHAKE-128: c34298256ebc1e895030e4f94e39514f66a3ffa2f10b3c782360bf8f00b387d2bc072dc763b87db0332a732685498479c6d4bd62ee3eef411d7648a0571e5857aa06f07470f8521a3a1010b1ccf3c28e2b8b2641dabfd7bbe685e4096b63477c6aff6eed9c00b5c9567222afe1195749ef037c3947d626041e07c8efb37e28a47a6f1e73a1724083b9e50377c14a60119d3890969dbf3c907cd35bea3c335966dbaca201925640e37d6e4e5df580c78b63f4dd4db1158c95028855dd681d12b1b0afbd6f2d621d4c9a11ea0ba07d58565b5e3527d68f57f277c6bf873e47bdf4eee5d9008c2518534876e0fe668e4a715f442a5562c8ee9720dbfb2969c229e92c55f0bbfa73f4e53eed76e076be0dbce8f594e762a574764b78364cba7cdc912ca6f12f5fc885f8daadb8c4d241d8bf977e8d8aa515fcac096bcaf33a9f9e5d2111d24e26b12195ea53c1ab6fda1b2ff413947df5fda99a6c046e49c46af02b3357fecb633f3716d0435a4a3ccdbf12273d461a360f933c81ab378e5bf3903fbcef160f38ac482433334373c62218c13aa0e8e7bf77a7fc50078efcdb82d1f1e756a664cc5d19ee6cc7c3a124f9282b89f2ac731c1c4d14de4caea7aa90cd8713e7235d322d5e38e6fbe269f70aba8d4e1c23cee935fdf9db9b7b7b0680aa023f39d2728219dcb99536478ad1d48bd4e3a43e6313d3bdc48fca7c7d55a89947 +SHAKE-256: a15cbc896549a6756ec090a4a4ad94f7ea6ffcd472e49d0309444e38d26b937aed0646c0d7806266ba751feb8c48f7478b6dd1e580d92a38fa3261a723c0c2be4efbcb3acb4710c7a5c45df662e8c8b6a697bff5b003809a4b092dd6b7defa981621bfd5054a2993b73985063119058a54ddaf430632267ad057267128703d2e63424af04c003bf5ee129b06e8dc1b07e99c40c28951f5964f9560ffc42a6bec112bddf32f804b43b549b828206ebc2822aab16dc6a433baa1f18c74025285efe455577fad01152e1dd817db762a44854f373f68f1217f366817ad9bd50ae95870e0b386f69f65aecd5cdb3f976cb6312b96f343f1ee887a690a897c771a2a0ee564c9c2a3823dbb96b12e5552c42d5601cea96931f05b05e4bb714ba8665ab17f0d5b107fe9a58cb54fc457204b1dfb4c1059cada467585b95fd190de69ecffa5c00d7f2d8b39777ab281a178e9bb2ee4a43ee3265c1f0cf255f445f4be171858ecdc9a35b55d82eddc56700e7c54143295a16085069d1ffa8f2fe5bf11b40c60452e793fe009406176b0beee4745bb27a7a6d6bfcd7770a811f027ca0daa4f77331fea2124e9bc188ef1fe0d07001ac457bd21beb7356630a444cc0ecfa248faef242ccf760dbc69db80d6211ccbfc5f021ffa2b5f7f691d6d005920d1d4fe5685ec8e8b66d0a07142bdda860c4b5fe3fedee88dca3ba36f7f91aaf32f4cc4 + +Input: 87d5145e9edb4232cebac82af76781eff02e70c017fdbe97bcbc0acec6e43447cd9d5fb768b44d9a9572e542ce9ec7bf401f6be835d811fe3dbe9bb95e5ec304877ca003516de7f2f260cefa6895a7d0b1b5700a91a4228ec5af756153b1fbbbb76dfaa5ccd65f7202a2fdfa3c6e2d34c066248bca0772a172534ebab6a312cd1b61c19e140fef7021332c6a40dcf353134610a62fdbb39178f91ccb856728aaec318e7d18a1e84e604efddd4424d78206bfe5d2326a3f36810188e07e6e096585e6c913febcedf92a8bbd7a1a46d02d3c1412a8160ab5060a2ce8e1beba8214e69e635652c030bf854c541d4d260707db4b2626b24e5ec8e122fd16a14b8310f9feff9fff7e3ffea94fced8f9002f8440c7f5e2519d47c472f6ed92f87e702f95c1062069ebd986d106446370ed5e3bb0eadeecd33fe1056fca6157b8fc799017a44d0a1db95d0c27e3f41a3cfcc2d06f4f5821c384bc1eda9858f9ec3007dcd6e9dcb8e83aa2950619c0c4815aab7d8a44935f3bcc16802e6620231a55eb600306d90d25e8d47f871d241055b3efabbe183dd478e0d71b0e473fbd041108b109100897f2a78156355406581675985d20f7c6a7c34266e761d71436daa7b1803158550af05d78bbd9b3181e88002a482d9b34054ce597aa251f2601ffa23df2fc89c723b4b6a7e895636af16c84754c3855 +SHA3-256: 6503854b971f2b20a65833bf89c243a9c17c2bc90e9df3c87c519ee2c63c954d +SHA3-512: 6b3b182dd3f5aa16824df4a53a217bf7d6347f4c65ff3cb71ace5d7755782c2f6f5ee496785591c86b1215c30df55c86a40a8222dfbd1f94cd07d57058c845a7 +SHAKE-128: ef1162090d27b7c9e70beb3e08278f41c7ea02e028d60989f6e444f867196c7bd2537e0c1aa19d204f607e448929c3fba1f44af108e3a4c8472352d88ce19086069230b8b3149055635afe83e803c8fe8023d6106ac164a151f8f45bf95811a6ca3a198e7704ac128a6bb44529e7af50818cac6f72dad906f198432035f998e7eb15f843448c7bd177e7649ca9b42edf5ca1d62e82d8ad3ded7dee30a2522368f8944b70cdc66ceb52021b8fce6b6094ba3b111459a14ad3d1bcdde649fa69e3fcce39d4dd7fad61ef60f0ea540c16015fea2955db239f3c88ed7ab9e18c2e2e0cea4680a409179dd9c8441b4f5f170f7df5cf4d0d4e62e6fe902b7b0fb92ca2f0f875ae04c97aaa0112326ed2677d58492b8dd37b92d6df1efd86ceb791f3ca0d66b8dff08d9e10469c06574e00c1375846d5b30c21c128e7647a8db6c248d81d2dcfae00c0deddeb994440ea59ddd0fe9a2f7359d525f4252c9996b6b0f052492fc06c8ec7e11d4339fcb22296b74765d099bdac6b687e6c20ae51d16e5a4519482adde530a028314e9fbd7a79514252d3b057ec1fd49682e9d5a2bf3f6ce908491b5ec918b15665953f9357b885e0ac178ce3685b48d1542ebb9b6727ef4a443d8af2cdb3ee276d2925b4f1736d6e14b303392a6da20442b3232df0d23c6ca347769b57f4d08094a2f7ce24b48dc657d79d5c137108541a7755ef13185420 +SHAKE-256: 697c09b7790392eae5848cd1d929a39bca91ac656e143054a5f61233c6ebfea2fe865915f4ffb90f250eb219341785405ea04d7e9cf20f8e01a6709e88eeaa0415605441f226878e081705eab84479e9b87cbf8b2509d46ef708742fe36695b8a74d1476145ac4d2e1f8cd2452d34f7de1d3a250c098fb9f0db00f4c0001d4a64309a4a14ac1af9ebe342a9e967650b26f0f048279919fb7a053832ac2d6f5d6f69a9c59eb66a2143fd17697f6aeea088b60ffab30c1ef3935fb54f61b5d3b9fb3d3dd4ed6e81324e83c50811f1e1477adceb4c5d93f80d9aa4356f9568b93fe8b887f580c1371c96d9a92f899709dccb0c009a579b8cbf595debefc836c661f2c9fa2aabd549a7887403e750b0a3feca28ea8073f8ba6f682bb243975c3e61651a8864c80101d0999bea4294cfba0e800fa65e12f3c79931ad6b6e0c1197f97dae28a66d14ef2b0169fbf104ac66a943bb95ca3757e93c5326375fb596ccd3e7a24cf4939578158d885ab878057f7fce6a8538457e303486a3c7e88bd93ab8d83b42aff1e5bb0feeb1293ba9d17eec73b708aca7af2ca9d56295c330e639882abd3182837fc5a47f56ad0cbdac1f2ffec871d63f38865825c1fa8eae5ff41eb71b104085fdb2be95d0cb08cbc87cf27d9b43de4e0af647c576d85e1889dc3026388351100afbdb9b49c374d3a536e77cbf86dc32016fc895884f2544f8d8208 + +Input: 1bd6693335cc1ddc0d9f0052e7972e3d3d020ef74f7cf13af3a3304c0f5021f204cb5dee866fe2675b97cd8aad3e4289e16470799dcbf54fd70b730720c7cbdb50928a767a906a55d07f671482fccbefb88c4f7af627c834ed23838405d0269f7b508e43e72466e82f0a3561beac3c5b13495f1caa55cf4b96a1191f2afe14dc09026bc165b1c0e22533c54febdfb39b5501f3ce88ebe5caac0ef8d2662c25827e81899a12fb64a8e0eaff518916e3c3b08e2bace2022e59062564ea08127078c50efdddb31716268fe989ac61ca5bc80222b6b5d85463d7e4b4fd499d738b4f196936714d09589a4ceb4eb29781880555d69deaea676dd3db57f663660fa7cf3c52ddb9547ae8e492bbc9b0393868be34bfb9579481825db989af212020f72e3c1d0d890b454b0f3c7dc1b37b5f86e9454a9597626b7f11e35b22cb727734bb844245304f11dd535c3ba3aec24966aaf190494a156ddb6c0ea0c4a9fbaaaf54d535e52e97e9b1c4eb6a82694eb6e07db800daf598f9fab6833f080c56dde7fd4614f6ac0b7a071704a368045dde1792e7fcee161ac76d92246d71655df405efb9df9c7bd0478580b64ad23efd4ab3eb4d625f0d5452bb127fdd8ce457efeefbe956d975df820f3aa51832a968f022fab0fae6f121c806c17066dce1689bcddfaef15ce9f467289aa71191933d3ae85dfda16c +SHA3-256: a06c83b440d4db63152a5b83f8ba7af7e9e48836f05b261ee7cc8147c376f3fa +SHA3-512: cfc881f1b2d0a43d537366cdf90195ae7fc14ecdcf906ebad08c9c82c1521b517ca6c14d1a746edaf0debb933b1c3788e641e4a44ee186d605087473934104b7 +SHAKE-128: 329ee513dd00becf467a23e58e2181095316166049a5a05c1466c5f497a903115ad369ebe9118751f58086efd2e0f6db15401b48a48b49fc4128febfa761ab4550a8d0509938a3bb748ae1d5aacf81047790a3f7419a405e02a2c7259c1f278e99c0089e67d59c0c21817e93236984fc636fe56e98cb60460443a6258dcbd53c2b4b6b3669b36f05c4820c29817d0949f2112d3f5fdc205a9644adf65e8fd547b4adf716da212d7da1f4c571a1b95e18e97345870f45e70962dd926423c8a4709acd788f9aff5f80e1d963462a035321c5f63a261ed23d0e3d3450a67cfe1c71a746c8ac8d99481a27b71c14cba8031f53aa7445336dfa39a47d962c06214e062ccc433c5db155b258d359be496dd35d04feaa8a4838f871fc653cca89c2d069db1f7480aa5b657d055aac0cedc05f4f61de2d10e00d03d58d214f748a9c18bd6492684ea2817d4a2ce698bfa0b31aeffa15a43103d947ccac497c8ea6df0aa05687382132f4b62518ad23888c65a7ca0c9d663410590f401f6c0c7d34728c7e74ee212a5b4b905b5999aadee6699fb77a8b4ef6c4700520b693dacf4985c44f634ec3701c7dfc349b22eaf07707ca739648030c10b16bb6fbce796ec7f2fd1952b71e5e2c3398c36710456cec54bcb513801de144eab800ff85193f6ea48ce99708fe5dd9d3e83242a83717d7ba2edb8554410afc4e6c51e42b2a94d82cac68 +SHAKE-256: c58ec045195f7d4c6457692abea9e4f796a960031557b254987c8fc2c3fcc1d31a8a60e93c1fb52b058678b73a5757a0f34c3c5c6fe4d4488b81b3927d1a83cb979e11573fe23f3bfa540428383b6b4f0e35b163a88cbb7391f246025fb64c61ac0f69ee2e9ef68a3e95ddc2d2a6549f67fcd932d58f867e79b41a140c2358c888d5176d085f72c855b79e565d776cf82d8d9c91a32899403f7d08b9d9f877ebb814c09084e0d8434bfe278ee7f9c25ea2791d22446cea89e59ca06e258d375d4e499aa072f6cb5ec5c387b97595b2abae64b57d10627be128650ce01fba1266856a7d4b08423269a3a2c4045cd587ee4b7a29035ea08dd7f4448aa34c12fcac5d8f4978aa097e01741cebaed63dd365a558ac86fb5a276b6a380d948be1c81fdc3c0ea1129a54eab5919ab4f950a65d9280d5901e2960ed9c6ed55c5c324cb00d7a5ef4001b9fc36422010656f50d5068c54335ab066a5ce5220bcd6b3e1a2651bf9cfe178b6f511c938d1e52213b6beda4c20ea276ac8bc7cb5c256f1258dd363a4043cceef0870da9283ca5f57e240fc58c945810c559c655f5268898746dc53a7ef1b86b31e34e5d10864b2567165f97d5f6ae980d9af977cc955984c2d969cbb9f202d2cd3094b47c288cdc480b70344f2b2d0db4b9f548df782aa08aef35062c633a751b7001f01c1707e714318b59b823a0229ce783467bc1c2a551d8 + +Input: d0ee7213ea0cd34f99e8278c24b0063d416e64da5aee9639a18194e3956b5fc84ebb17f592c2ef45f9ec9b75c648c808dc4369a74215ba8940d640b3d002dfb5aed7c63884ba6e52278b657f70de0510ce8865faca5531d422a8374975add8cfa79c058a942d55f32dd761daeccfb8c52861045d4f69a9176b0909d928ef71f91eb181866200bf0fc3017a9802440a9bdf78a23a8d086963aa9f3f33113bac5eccd08f4b2b34da4c7a6461bd5c1f1b4e29338d211b87fada3f486a13017485db83395f22d4f92aca953453df165b0abfef9babadb16ee76ac46843d9c976f860e6ffa960c3451162f64815475b9c91f3c98c60c33c6f0306a8c2c230aa6981205d74facf69b298b0b96e29a024a9b2a48cd5f3da5a6171969f9adf4a798f36ebf61f3e4018f81ff90ffd9ce26d638428f7be4249b6a28148e4c6e9d3d61f68be103e6d430c151a0250de138b5770293a977fa9bf5f5208b38a9ff99d08363b9dc9cc65f266b968cdf708fc31598baa3c10f3ce7a50b3b20a35acb424dca404cdf99fdebba60ee19b76aca124bd90bee9a4d54efa30b7144913c52e84837637938f2d27135119ef06d0df74180ca6d99cc1aaa6654e93f54f9e92d12e18a047f30fe5319ffacc1d46e5cbcc5653ab24fac1c2342e8981f97f44835eda8801526b2d7d1b9c15984087467b6c391eb0acaf98da311d +SHA3-256: 29ff7168680bff0b61b64812435b9423f279284c4b1ea34af5b670f018370a58 +SHA3-512: 38f54d2abaed9e343f8b33049fd21153d9901936e7857bffcb40d71565b5a9e3a80c6a8a8487b03d1b19dc71a91d78f4e8b110e485188af6d33db3a3515422f4 +SHAKE-128: 402e4968ee3f9a3efc6002652cee0fa90ed21f76ced9bb5fdaa69a654ba09f564ab7927ca77b4888bef312bdb8f9a6892350f594c81ade8d90d3000a45e6604e3bafd7232bdc48203ee131f80922dfed863880f74d0d180bb41f3ab3d4925a53c02bbf118b07b4e03d8810ff0f695e7f0f27595df7b79d4d7eca27da5de3c2723b95f324beac863d0d6532443a29c977cd529b57f9c2f910be6a604893237fd83bed46dbbda4cd72112faba11441b047019d7d7afe18ac2a90c8b15fe7f07db0ffbecadb062076b4d90b1f025b9c2c45835e642529f208d6d44f04b7d604df49530d9c80a5df306bfb553d0789ed831612544647cd47445678d391d50aabce700d18a14cdf78427d545840e9ad7045286b62eb51ec49e3b100499da650b092e29aaf5cfd6d6289da9d4914d534aa4126af728da9b6f579a0360e57f5b9e37cdc9cfc8a696a9c2ad9fdc334e79970af8d655119f9ae86d40a5f47e9bf1d059ea329973a43142ea3481e40c6f67f8a26ed9b27982d27a561d9f6a61355d8b4735ecf7b0885748242110f01ccc32ada45478487a2a541c0e187c5ee1dd257bc7c810242b7f63a3ab14ee7c457d3bf6def869046bf4b82e99f5b4062a99c11fcd77939f62a44e83d0b7a19eb9287d55dcd35fe89b82584f0fcfc470edcb75ff8e88b13a71453cfd4eb259f9e0d0461ae9a440e678590ed0e2a5f4cd9d7be946164dc +SHAKE-256: 6b701d95b48da589eade36f621fd249b859c7125d26330be02eeabb57e139234275f7805865d1c74d3b522791680ab2971a72852c8f0246ef2a4157aee78ba5d75586c3149de3229bfb321f6b8bd0ac7641b159221027b51d3b38a573afaa90e79f4b7cc0aec99816c7861a97b6fb545a2a6c012ce0b95580f250ab3398714b88c2afb87916a096e6d1ad6c399abd32d4ab22b22b95a701e93d7917fbd16e9431ed36844604fe0c36aa9d105d81bfab8ea7bcf82b12c420c176e96d6e5d0bd1d7f6636314844605d0d690023e4cc728409d2d34f4763cbc31950aa5769bf5a0865f8e1bde0ebed596eb9ee8c58e40a43cc38391f28adab3a5cae5c6b23d0194981a8978c5917b3841177ff3319b6a9a9a48c2f0fb9b312a30f8984d4c49feb27a661349a2a2cc53f45cce6ad2fa3167b42da34aea858c1e3f9d5effc64bcb6ad6a7117092106806a19b60a1bb9e0f54387e4847e5f09de9731dc9fe8d8dc1d6b01fa1ed0111f8b288ec14d4f32272d7c4ac23c8598f2a45a5aaa1fac35efca816bf2cb833397b7468e992748bc0f85acc2c73158111e88d6c68ead22a83fb61628cc284a054f4e526ab2e14b57c79aa43a00b55b1be2ddf32ff8e7f4c50a8a7ec490b1c64acd669ee98ade150716e7dc2316b3b2e04b949dec9f506b7050b2b0121146164eb6602283276c7662b3b78391d7103fbf7a3b395df9501d0546a0e7 + +Input: 9692c57e41855a52af7534adba0fd2f515206cd8fe0aff5e5db74e26a41c54f29afc2f1dfa20dab39d37be3f04aa4f92ec17580648c87171e8268200c0130174a967d8718e1f0ed71c13f08079daff46f38392d6943ba1a1e38840251a49dd6a7205ee5302638806f573e7885af7b4f18cb19e838025d1e54f15a294ac32e82250211dda15b056e0f4d3cdefa75902e1ea7a26938fa9045f701cd72aac354c15e0e0b82eb937ac9c5e4e2460b3e46b399c8194c58177149074f1f99aadbeb58702f5e63c90b90d251bcea5319b01ee5d304d762b7da1b7d837f96abb1b256b310bff212a0bd1c59ff945aea4c460a9207e080b969db08fbeaf98fd7db1640e79dd0ee2212ea55a41f290088f76ad1a602fe82e997c3bee41d2fc0608a1a5d5f5ad08bd9e54383cb95e80e5d1c3ea2c0da5691e1a16d7e3b72604f107b3285e6807c027aa211179741d9daa420e4e7abfdb58deb68188caa85165aa3d04fc66bb779552ba5f9ceb0872e671cefef1c08a59d4c034129ab1b120ac5052230d8956eb6922025d86e894dfd918cef4a5fa3bf137294999e6a2712b6dafcfc29b103b8a9ad038c585b4e3feed3918a41bcc3f75812de6f806c68ed7dadfc38436396eaf17f1f7886fb642c53112d8b8ad5b7a2c803ab08241dc848a55a0481a3962e207c715dfda054c24e33de9e2b6874fd26041bb7721 +SHA3-256: a3e4ab92b72c4bed1f761848062617e049491a9fca84de0cd741c4e7742a30fc +SHA3-512: 366bd209232fec57fa420e30fe19ec7b68e9e39171d1f1415666a07a9c876d92eac1734e63b17e3c150c5be977a466c723008de7c6e42d4a342021c7f81b92b6 +SHAKE-128: 9175a94e2f1be42af73175989d44014e135ce01d263d90d5f44826e4135043c0411401b822a0478a1889f3fe0b24d56ebe1364f2a291cd0b9b6dfc04d46c029d911a07ce3a220d1fe7844404742f43471261c822d9788bfb84de077329f1383f41dcbf9eb8634a4a852e8458c1b77d76f3dd36baa28d1bc5ca396f4ee6a78c2adc2c73061d707f86ad4119f85d43d2e044153e6c1fda5ad44bd7dcae23b3aafd184053de4a06111858ae11e3ae0d99349698bb789f476ef294ac8db418b7c30a2cdc69c9842ce621b6ab4452b606619a027138085ce17a06e543e55e3b7e60062715ef8db4e19f25b5e53e6fa764bedba52ee840bc1aec3d3d4fe9423db4cac8818160b8b3ec250f9719f109f3a4c221be5adbaedfc6d01eafc52f633530c3ba5f122c611c25f1e3c1b633b258f3731c74ec17313509d9d3d7f63ef803f3d31569cfd8f9bafd026c8cdf353dfe62abac149b560b853a9ad433198cbf818e213fa5d653f10b29f3835e770f6dadfc870880ac0d2d2df94b0a301f869b6222370385287f003a68269ef723b95fcac9992da6e3c3d472145b759cfc7555e9c50de6361a8c65cfb6ab96afaed426c915ddb560eb26190f8ae4bff48291d99e513a420562420246bc586e7ab80425c2dfe6a122e9c9ab075b1f31e7b4618a92021e0cc6dfdf4a776a7b4106825a676822a23224fef5375d537365d9f19112c4610363 +SHAKE-256: 572bb428cd35738d3ecd8cafc1ab9e7e04004137e1d60fb967801a8fd13ae7d42880ec1a7d8353f45b80c13ffada53deccbb2965df68f97eb0e39a85145bdc201b4fdb066cbe6844e74da0af581024925e60c36642d87efc25e4848fc5fc1990d4cc1446fde98328805147bd6dcad79e18a1f260f24d2be7ee1bd11db56a46a926f3165daaf6064e09d7a91b691efd7bf7c38f861fff8f349b858222a83cf8121f9c33a85599d491b0f9bd187afed6475f7ea637705e6599f7f7cac9c9b356055693b35307182a4f23b9f6e57b51164157650328ca47fe5f95883fd03d7b6f6e959478991445b91a1de4a6611163aa8729b7716f08d202dc37b31184e7fccc8c30169872181d1d6cccdd9ba57b10f60f228e6716dbcfa999bc1f1b29a3c15f1db1f7e427cccc5936f300033cf1c04e076c8e8323c7adb5fd8b2627634a747b054b4a78196c2fdd957c3a0c558f0a5f8c6acf691eb1a3ebc6c9b8b0212321bd2c8bf1eae8d8ee3ec75e2bf9f83c1afbeffd120653252db09b1c4e5481b4faf46b455e06fab3623e0feb64f31ab21620d1d951b68609ebf71b926979b397c8b3c683b27f429d044ea8d8d5778ea8739f2701ca90e979c8493194c04cab546a2af91d2f3f7ebfa33af5a2991bf1dac74a92699dc814258d6ee90b4fff5144cae1c2431aa6424088b6bc3d6e39ccd799a4f0fe4d78d623567b0032b68a34cb06543b + +Input: e4abad8b782eda8e41d4be6f206c6a1c5eb96ac16e92d310c7fa14acba27cbd8d501a6100089e1b61bc14c0a4665a3d60f4896d9d6e34d201beea69a755de878d723807039aee0ae656b1001fe4fc8cbe9deb2bc4579345b5a0788fb0061880c45027d0b51556c50949f9df998bd4b37a6da1bcb7cf9d10e1c5736b32c6b585dbcca436e6c523c41c530f254e3925bcb2fb7b29ceca077b013d694e9a254eb699e4b63557de363aa08535c58c0853de6ac5b448b7f0bcbc6ace4abb5400995808439c0e96c02db715113cfe80e1b6d5ee757ed3b73a1594bce25c0346288c6c5a547dd18bd2af623ebef49ac90949dcb9447d7e59fbbfa06bcd12dd98a12f2598a1c2168b72a2b4f693c8f25f99464d34edb2546cfb098e1275a3506fcc1c3522b843f241b945a166bb271183e432e72d66593741b4119971544eca7e81de64641b6d363f1ff0b8639f9ff4f225ab40df92849bf5f9c54d6776c6c88c402e80da0ee1062bbd4245612a4f937ea340efe6305993812880ea3ee294d81bfd7e5ddaedc26c3b5d18dd79aa18e0afcdfb5bf47253437b0225db795519ae4354ae280abe5e0c38760a11dd42f6510f2ddc24746089fe4e38081d32617f836b687c26d53fed8af7a1ebf6b00e5c471cc4a609d14f443c888696d2da39f80dd018bf9f92641f71fbd95f6ee714770e2c34882681ff3e7bf3617 +SHA3-256: 7499a373ecc73c30a4056b4e90c2f3d2edee9f022d05a9e6d2ec973bb4a3f206 +SHA3-512: f1e4668add81334f73758b1d0b3192cafa8accbe8b0bbaa0af689c7bd0b52e17df2b065da4bb2455c8da64f21b2bf38b2529c5a2f05a733d1562974c0a1644b3 +SHAKE-128: 20adb1ac501c5d6ba9a32eb336ab477e2aa0ab19014d5087cbfeca11996b4cb12c61c3e2c340a7380756d01f282f71ab68eb83b9aa440f5e53ac028fcbb73921e6ff9c0abd2a5b01829759f46d60e75963e70590a7da9f0fea310766582bbe3363422fb83283c1d83b1707b5f4f16615c311055edb5d498f6d01f32647fe0de6eb00328284dd2361171b1aff5928d6d73d901979d165e1b7229dcf62bd908995c3c588b868ac080739f7ef9b34c4e83063eb0d85b30952c2d774b9122141cb94a3aa51f9b04f5d55c2b4de8f60df428b4bd98d1275688124864dd907fc240e7eedcc4ad4ff211c4baad20c7f0e428151b7a6f64b3f78b1387d2c4e41c9db963a9fece7e844f5a3711aff16be8f54fdeec193f56333a56c16c522aa54f0be268bb6f102f5ed3cffc3e77bef0dc345ce95c90b3c1ea0514b3d4016b3d66132fe4ff52d22fc0b3ba24c671530d18c4762be8c88cef3b1ae57729675f31d45c52c224227d77f9d21dd903213ab5eb82c07054783835100a044dddfb2e3e83aca2d937dc6fa538afd7d5dea92a66611ce0ffee444aba4bed490d367159ead08155b3dd76dcb032dcc3a10a3353ab6b66afc4f47e99e8afe8aed0b789562a11a62ab9731f6d08ade4dda30cce5936697448ce0871015feb798ae538c833cca96dd50339123b4624f3beb0a0b8fbb7053c98b1c5d50a8d2d7e30f685db4510bd82730cf +SHAKE-256: 65c1abec801bf90cbef825e8372c6cdfe87dc64ae4b928adaf661e7680d21b6599ce812555716f6c2450404dfd2077394e83d73e7e6ff74a74a83bf96b3f04509901e95931565e786f687e6988194cedbc3548fab8184c27fcab09980ddd69da99f9510001b837c812a7bc8df06a2f382ed2b1d5799d455af60cebddfecd1f098109a947afedccb0dc0c597d31a81faecb9f11959bde953865816936c4ad6cc5b3b1f431bc1430c1d4bce94bf9b142ba1d484567a11f14c712c3384d0de62aee76e3319f5ff14067c97b8eb05c573672f86cb9c0b9d6352b9d13dddd6e192b38f78f48acc36f84a68d5cb12d0b7ef73f7a2b640cb039426f8b1fdd9b84cc5ae699d1a58bffacc7b37e04de4423ac734662bc4990dc5cfa55e99fe1e977dad92adc12b6f3c9bae33046872c223556415a0874e6b352a056ea639cc6bf8452cc3d4d9abd0faab31603b3efc5c3d9ef37b97c0f6acac441a5e5a3387d09c3b1c123cbc4067ef52b266e1360bb4913d0ac12b99fe1590eff42c5d2d0f2ab9f7f08dcbd5af9ae12dbfbfd3d02e7e53ee14ba442c8e30f70aff3dfe77bd333b13c9beb37ab1a3cde94d12dfc6632725d8713c3b1a6b13b28a7d8856f14ba625fa402acc5889fd5b53f6b0605b8c0ce3e8ce948c4c5f79ba6a073b795119f6c110fbf4331551f48003495ccbc708249127be84ab4ea7051309861551a28fd022aea5e64 + +Input: 8bc2e1eb09c9226d50467e94827719f05763aee14151304c4ecc4cae42c5f4a2a82bc431428454aa12d05747c4f8ad55b759057080d1453dddf10d12c1ee474390732145fc1be2ace3edb0645b1b65263ead2480a2467572c296941b5b43ebd6acfd004ca93a0de6ef1d41180f6c064eec92644c5ad151f3968ac14d3ba9fe064115ee06fb5e2957b228d2fcda4608f9a1a7336b87a1c47116f7305a11abf20bcd20e1ba79f3055661a8fdef4d1cdbc4c2eedb3c0caf76826846dc9f7e3768c524fe8c1c8bf38f20183b9767d04f222dac4f9ffba6985652639b8da5f4ae02b870a67199555af3af8555b05f090e0d7bc73bfbe6562f1318fb7aed6a734d852f6dc3ae6574bd605d592aa6aa0334c0b69069f39d4e3b3763addba7d9d2223ce90711ca75c613e3c4fc6ad90b929d5350c6c5aa55f4f201971df06cae9bafa72318e61151027843bccc47d192a43b44db8ca099b002ad7ff9e9cc8485bdbff78cb836e0b551bd177f17606ee3bd9abe4991ed6fccaec9709ac1457c46d4b80c36b73899a4c6e37c879b0c25f411e79c512d2007d99bbef35656049145af903a12e1eae95ccd920f77e2f9b2fd108e1a106d902009061e0fe876176d93728ad5cca8c776979d3de83ab97b47e38f824f55f3b9a6da98c97e0e556cbca29d4c3f5c9d902661ef17d159ffb157064244f084a4d6ed4c9662f1 +SHA3-256: 93835c31955d85cd4c09cec6a02b7f1d2f644268d61f2ebf1d30dac9daa967f8 +SHA3-512: d80bcd984ee9bb21e6bbc038e8959795580efbd21ae29dff4b1b92f942e494188df2d05aed15aab3b1c8133246acb77eda80e1b6b817666a2e9e7273cfc239fb +SHAKE-128: 242b87650552a1b768dbd89e41dc84fb35968646f058c54b2ebcf6bea79bfc3356abe8b4fcc21444789fe817926a6cbd46be0c79b1789698245cf48cd138898d9ff45f84704962efaa66c3c700b32ae685e2f269f5a189cae21cdeb4ce65e9b49472b41fcc098bd6a3b9549feafbb9b6e181d5f12ed0e36b360a1fa4fbfdcfcf1272ff6563c57001ceadb78db6b636ad015f015281027f31fba15d576848d11b71e2c5d8fc274ef32a12820978dbaf3d21e452b9e7cf1a81c508d4a035251ceed8e35b3af3839ae8eba848def4c30c2672fa1b5235db421e6eb5138110f4b9b98e95f12c6d340657bf1767ff6971ba9aaf37dd5aa38ce360684d6d2d2874db5516e508e3d17efd1c8823c70979efebd340aec40895693d09c4f5ee9cb442b3a57299823c519d5cb37d5e27ee03a2969f9eb6548f4fbbfa85dffe075ac40b7fa7f79ec4600cb8ae3a0d5d2e5f7f852395e71eb60e9c637500a764abe5deb8c0bef9d1f8d3e4191fa2062fcf2945016f9c25087536d49cf3ce1f284762ac49fa52aed90db61ed07bcb1e5816494de22b691172df391a8e4a0685aa12690e668aa0b54dcf1b11e770111f84969d1d317c09fcc461d0ed2e414d125040ad7ebd052203531a53090fd1d1f294d08daf942cc01b53d56cbe0e348191b53c3bbef9abd1453e7ed4102785fb0a25859263501bc102568cf9b9a2870f87e0342afff10478 +SHAKE-256: 9fa085eb108049fa49ea8bc4dcbb234ae57233fa3d58185e2910afc3f719f42e09a247b74d14a9317d45a8d669894039109d1c000284d53b6c086d45524cd114ef2f1c799e8baa7d2a5f3efd4c3cd059e7d645eb004740d3d2bd03b4d1eeb859ff4b30b17ab9f945949197bca2eb14bb217c4d55575c794fe16131526e65052741154005f173e37f1c82eb1e704d53c5157e2ca4483356f51b887fa1436b16cb047bcf2da930dd4097193a4f0bcaffd3f027c88abfe9226fa4e056e37f9d6461aeb0e6aba4aa968ed073193138c70696c83243dd5fa5f61469617e06250fcc21095ce2001f14cbbdd41e96e48aa22baa0b3603fd7ad01efe4960e143660544e933959c05565058e259b1e137a35154a5fb1c3ad5cc8b7928c60644265491f213df275ae8a70e48710ce273ba0652306d35222f1a0280e98982d27d93deb4cf4937bbebb610f58030955babbe43d67329e67f5d21bf9f509345a0414760f25ab8ab156003339de8181dab492253afda0628e86987954ae09e73fd1e65c36be0f08d2a562aba4f4e520a31368857f24bb0b75ec2dcbb03b01130d68681f857d40b77345e13d6eeb5dc4d5d01865c099d977fbd1aec9901cb4f13c004e60e003e3b41bf9807f4ce02352d32a7cb43b7ef8250d74efcffff6cde8841bfcbc8eb821ba54e1605b8ce31cad4080adf123ca70ece922ee718b5ff0e32720cfc58d137af + +Input: e1484acd138e7652f55c68dee2c28ad909ea255f9948e0ae2c42756e37369aef566b9d62938cbe4a3162d83774699edcb8e54262b73dfabfc881d4bff6d613d63338359d17e9a66fe0e4148df4fd7f830a0d1cf6961339ba4d59d41adb5b92e891825f1b45c26e68ffa72cf463e5eb2253f3037b842e2b1c82f3ef6e50892016e68b30a2f43adc26d54b5dab245c8488756958b3c4d6d0b1ed0b2b5a7e15114458e6f3760d50999aee832a974bf56a46e52582499811d54364e75e746f6a4d08f1ec8d1e54cff686c8cad76a5cdbd8d1313fa4830720529d89aaaa662515d0eda6b103a4ffb51ee9c70a507e9007db8546f26e71cd9a6c9f1aba926346dc8090a76cf390bdb01aba5047de1ca45adb2b5a743b2cb19f711212eff5b435084d0683c835806c96fdffc211255a6e6ec90527c7b019c0a5c438c8947b59cd4167ba77ff9a81a8df16eef6cb83afb49f8de4c0b1426ed850488836a60c8c2f71fb3c9888496ca348148c9750687796920711452ceb41e92a5f6cf72d7038614770494ed3861e3aee391d86856102b213ec75db26bcd0c578b8fc3719ec6274f1211fe232db1ae2b07968a81065bb67964341452eb16d2b328e7f072669a2d8e326a45438f0669a2b8c5638db049e97d576b0a1cfc8d5268eb674966edd95e3595dfc6eb889ff1a83222990be0dc6dc3434d578eb8e10099c4397 +SHA3-256: a4a5884de3234d48f426f4d5248ab57b9979d68066aee931dda0c9a178786bc4 +SHA3-512: 18d1384402d2d906474b6ac5c5e036ece3f245934c5c50c7c1b471ccc84a575a2b8bf87aef910058bc409067c760aa7575998a305bee684d21e4e8ac5b55614e +SHAKE-128: 46028906bf9b0829b5822428b41b3a3c5937de851e12f7a13e27d3dedf726394aac924dcf316e51e9d08e7e315b589dfcd84dfbb8f6588ce5af31c54755dc78abf71b66aa51000afb5535b61ce0e1b55748697fe8a4f5ac8ffebf5f431cecc72a74ad768c62d851dc685518e6252491070af8889a78b43c430975e6e5681b1082389ec92a0a9f4fa0db46d5f9ea93a1611a432d9f91c04e093cf2b811e8373f60b8ad5903a56d88ac0567c55be8173c103b844859281d93d42e6667f05e0dc2587fad938bb75ff9b6d213bc4ff89af1d0ae498d6b56227958bc55ea99824e7c97dde8a7c0c6c9c441d4dfba58404b32ec5a3278faa0dc4fda2b21fdcab91eefadc6a6b0ee5d111bc110967f6bebfc20978f4c70cf101c6debed3bb7204c1d67779a52e1679e6a57cce9e04940f3cbdd281a26160d2c084559fbf5658f7022ac14234b7228015a3bc75c233232739daaa418a8445bb6b96f97ad4f6682f240d1b3bfa7b0f2885e5c9a89ed0e0a83f581bced3b3f329cea06aaaa29807c5f9004e9fab0d8176e2ffd79306f79970f59dd7bf67783ca98661f373dd1c58a1546799f11d65807d11620fb460d175c8e922f792495a75557707e63afcbac78c5b1e6ea8db3248401b3aaa102475d01304d6e659253ce3876c8712cbd2728201fbac19f4dcbb8c0b7d3e5f84ecfaa65ae0971ce95159c671b215b4b7692f3cdd9a3d93 +SHAKE-256: 4880c42d64c60a4ec23b185a0f79d139777e449a59a0186476439cf87780fa5b68c65c19836ec5e37cd793f1057a1eef7746ab32a711c2aedd47d1b0bb95178fbe61ad8401fb712e6d8310879d324ff35f17db3d1ebb6298ac64a33f43f904de8cbf7dc623b62a859ec86bdeb546f46f568637ca4785817b5b0ae550ca8490edfaf1ef1fc222a78fb0b0da2df7593cadd1809bcb0bfd0b59ef15c9312c8b2fb6b209fcfe66354b2577a175f274d4c731e50808844a22dcf0eb1b9e4d73bcc8a0f03c13cf9bfc911922d62fbf5ec2d44a78b0520864ee93d9feaa94bba269af0849e80c7e545e6580082b6c62b0843cdfa51f7a7351d06d40be1b333760c427f5e49c032b9de9d046ae8ce94625178d161d9c72bc33c8cffe75eceb875180c9763403ff6d1206f5217aa3f498b33f35aa600867a798790e79549fd2481880dcec0533bb984d513e60ed7c21289fb19150082b6f2b083dac2b3cc1484d5cbafcc8716ec85d7373234fbe3aee32c0ad4ec343d37c42be5ae943f0077c396110c1cbd71a2e4756ea0d0654611197705c212311cce6caf35c76e8c90d45e5395bbf94698fdeaeb6afcef34b107b6b39193ec0432a8d02162694a008eee35fa198c4083ade7736c65fb2f461ebd6c897411af2ad28e47a83b3699fa491358d3f11e0e9ba830796a94eaf6a0ad43b74aae42774f99e61bb93657aff57f8a8556d7fbb17 + +Input: 76c47f5f4aee787cd2bff758c2555ce66eecc08654f7ab5ba90c3faa20ca0c85093e79c3b689bb2cbd8d485f7a4c386077ec101747e355d1296bae5a381f4a43ee160307c7003e992a7dd8bceb6e400cac72a1b8ac7c2a7b87764208476d36ffdafbfd0e89429343e5e6b775b61eacce1d85ec91660e43416c2237b4d20e3829549e3a5398647aa5df7c2477da200bf52a4fd0d135a0196cd60cf85526a1cf1580efd008301d6b973f7e943cfb7f1a47b0704914788332f7a9fab775291a20992c9a0c8f5af4c8b4c00af8136eebab9b449289326211e53e0960b73ca8039bccc23b92fb54e340c350a17f8bdb11b7398a509f826b2dcd1ed41b036ab0039944ffc0c246ab73748b20623c69f6d3e9904ed1146d5345be5e73afc56ed8672965ea684cff2685cf84c91f90763b3eb95ef9b15c35efb95aadccc6c6d76bf3544d849637de7f78f6fb971a1396bde6cd63b521b05922876a34f927dc8f35b0cb41726db51dfbfca773e7acd374dbaeaee03f62f31b0f52f883fbf5b2e925c9b65f659827dd364cdfbc9a41396e3eb46d1bd14ea9f5e9b588207ece3aba1a47b7b6bea78a577dce68ed5d4e09de7f38d0bdea6f4c959e583904018a1a38c8f892e08e834320863463b2948c833e14092235fa5f44c3ad4fa52345f80817108fdb5ca3d3be03945d0300d94e41bb50ebd06669be7149ba1bf9ed28 +SHA3-256: f569276d41918a004b784087cc6db0612a4f92571c498b29b66d4c15478f5795 +SHA3-512: 0a25f1cd6de6ca6dc2474ad38090e3ccdc9a58cb3af850734a70007ee18b54fde56f0655d4f248ae7ea9f5d4f1a8945d0157170b7c2e22a7b9de5e09917bbc52 +SHAKE-128: b7a89fdff826619c52ff1977548dd18bb8eeb09f16ad9f01b8a558ecd245b96e427e1db0b6106acd2c911f0855f558509eae1a092ca4465bc00606d29f16fa69a6722f8d16ca5a08e89bb31e63f183e07adbcf0179be8aa0c62b1af012eca0e961e800fde6aab1790b27b5caf89178a8fb0da37b7953273011fe1cb8052a8c69e7a8f07c4f44d4deedf26e6e202a9b73216f52cb1f3af5398dd3a95beacd124dedd94f5504b45550a90593d6e8ed80911f8c52c58b2bcfe63ea390f31aeda2f01526919051122ebabce99403b3ee1e1f11aae1b38d5a08004bcb4d736e7f5b1bde1e12f2c4b79a74e54e85de0da41847ad225e50a2e2543459a56a7b55c29d1ed95c6629e33a9e0b454d74bd1128db791e8b90fd8054018eb67c936af9f99fb3e92d09c036016a70f81e180b43dff206fab5395326b64dfa3a7bcb35464e3bb879c5940c03e4f31fd0432d7e39ce733e7e2940340c7409a998f9e5e7e6d70540fd6fceba48cd0bbee1f4a76d66dcb3ac8bf12cfd71b9888af2407942a3cae3831e87638e5279fe11c0aed09a6f8385cda47a4a80abd5d0d0e215fcf2a8889c5e4c4177a88fc0c99df6ba383ecfdfc04bf895c412cf2f564b91ad7bff243919db0b9ac10b10189098d33a0927739e937d9b0624d4fb2aea00fbe4d30e208235cea9ab0f4f063f5af92525402cbe7f28b26769b648bbe48984ba712de587d650c1 +SHAKE-256: 34eb9386312120558cbf34d22d3aa996bb015bae890cbd67afe975e777c26e4409eafa2f0525c4b22903e1345ddf88eb5e7573d5a9273b9e64dc35ce46e5e1d06f44f86ae84bcfdc9aa2c8a0bfb0cd86d479cee2b54bf9b5c588be9245d5a28cc7922b7cf9cd06f19e3a6cd35f754386f23d5fba1a7e406b239b709fe104623600e0caf87acf242574f6656c6f5b117a1df05c0f7b7fd60319fb44df93dec4a59a9785ac63276e90b6c87f920a0cec601548cdd50efe3adb3f4ea03958ff2bd4c1fdd8edf5301396008f93f84b9e0b2c5f0eff48f7be8240584a41bc54812a8a9ae9aecb2a0dbd0f596a43f3fd5314a5053b8b05662d4498d75c1f9e2fdcbf4f67cfc929cf1aa6b31dde5db4a33e1d4baee4ef850ea3194a597d28dd014aea57034cbdd278bfaad22bcfdc8d6ca59c86c28aa721751bc70b0b0e8d1035247e9a07910240539e77e17dabb8c4c7c8d92a8a0a86e3f797173939778561356c42ddb2847a7f6317ac020eea673e34d566a99cc8fd037ae46a399dacd60b8732ccf7e610c9d3f34a599025974d7ee28bf8f550e744ee6bc1421b29cbf5ccfd0298d870b399d878de8d7334bbef21fef4e728fb6699ae28ff90bd5850e0f37010ae9c5181e8f66d57b9b6a3dcc3748b0367e197954f404f74b040a4ca4fd5a67b9101dcc65ddc76707d9b798008de1e525438a46ce69f11d0da92eb447a70b6881816 + +Input: 8caad50e95b807f91bf02b052805e6cf09a412c35c39de0b00ac54409c4bea9177af23861d1a74efbdba1c90642268c487056d3d0c133b33b9c896ea9e39aa903bce7c64751ec1ebc67381093010faa0b0334fd932ca08d9705a3cf4bba85048a565127072238168dac7298115fcdbc969eceef673a5091211a544c23e5dc9e7351f37a6679f4b49166b55743414769fb782359ed5c25b11054bca3537b91b9b177f5896f37e7a16cef2d707b4ef27e68cf56983474242a5b37243082ae96501f91d0450759608c06525fa806e4ed33dff4ccba0c4244ac63500e5c09520deab693358b697ac5884b122bee86e9a2863a1a7cf52df0f8fe1fd43b5c1da9148c552efa02baf536431dfc3b2393a60e24f0d93f77c3a7f95320b44a29f194c804341345cc32caaaa1f78e3219a16c35939ca79a80c954eae5e236755ae6549d8d1484f5e14c3f5c6fc9da8333ba96fd022e931f418d299958e2985ca4899cd7fedb0189018c04680d26dcf8b831db06fb27267eba1290b696d3e03809374690f82ddc661c8331466f6ad4cf9ea21acf4bb55cf92e95ef988e65a64223ec1d0bf91b36f9d5ee58ea964de85b62ede7814a63b296191688083f087abdba9f77f5b5659effcbf07ee969305b2db8379e5288117d4f7b1f0d29d5f6d26409b4912587076ea7633d1c2a3585cdcd5926b48de9b788a43f6ec8c6971fe1e +SHA3-256: 36c413524d1d21120963a2a8e066cc52e34739806ddb1aa09873a9d20e7274c5 +SHA3-512: 079e76bbc9f9123188729fccb49b46c1216c501416683443b9ace7a70391c1f29fe6c7dea23b788c3386a7587a24eeb2be2d1a28643697156369b7ee0eefd72f +SHAKE-128: 3ba84f080f5868f6033761086b6994e51d26b37d9948c3d0b946b82a7622dda5a19affc6929da3b4ae298c269fe3fc49bd3802d42f535370d3418b17d2ec23d5f33dadd8d5a4077453680ce13c9342a7c50d02683d769866b921b47929faf7cff605d4569f71ea51a084e7a156db2e300bfd0a39ef8780e68713d48278c902a41a97f131dfa08d5f3a955d52bd99b4042ef778887a1eff558ddee2d63c4015126068d64f758c635586edf24a1b15f6120eb6894432ab97d5aa3580a1941093a100b337aa2a1398c92e592a39f9fb84aa50ece2b39d3ba8bea4867bff7b6a985ac7b4958029699076b38b7219f8bc09d2e90de438c01a56e33092c582fd94f0d4bdcd2937d68fdc45a7891572d0ef6682825496fca7326acb779bb831e953143e431db2dde49cf69d00d493cf8e8265278ef90e0bb59848b74de75e57d0d7825a9b69742199b37376b281e66b105725ea95c86392436b5944e33fe6892627e85dfcb0612d7707cfac59e4aa631af5c4f31b719e1b27a4e53e9e68e8d7aaafc639095e4434368427d55db137a75e46d5c04428a76c64633efaf3fea2d40725fc0e80396358ccd678508c3bb63571b5e196b13ad4fc9dd17227358c174082b3e9c939154e08fa79626fbbeb51cf22e2b0defbbd34a062b1b6f1b11ce8a2452389357c38790f678e55e6dea6aae7d48494e46afc47a285e6b8a2d240e4d26cf5c52d +SHAKE-256: 443636b286aafe10736cc300e90a42ecfa08df05691d2371c3bf193bcba18ffe27ef1a1909ea09e939d686f1c9bdeaee42c2f1eead2be16cfdf7f6df63c54a7fb83cbcc0df5920f3df96e8387066cc202878ef129fa0f1bb0fb5587261032d02ad02ed40e95f8fbcc81a6aa34f9a7fdd7ab11440873892e8307f11e9c37388c976914e764cf48ac4432233c960afa17b9c0df5961096df69d321b7bca434b6b30b243ae50c7aef8c2f5d0ae3107faeb4a56fd56d5d4edd39dfbbd660f51e844826fa533ece800ba086f04e6bc6fdf4ac4de73f1678fd918d12328d8f25c1b4de44381242f218e5a80043e09573b0ba9acd49d783fdbed33feba1c954bc80dd941d956c1b059b71cfc54ec45847d0310885d6a954abaaa7e5a17f7829685eeecadc98912aa5ae747d6e29283640bbfc7f4d4af46b273a62edf2a1dd9a359c0c0436fe84276b467f600bb7120a1b6ad85219093c3f5aa11e22e96fb35a4e2bac0fa45ca6cbd1b6a2b75e75dbf24ec871b212f42a3dc4fd6a683a4295e68c4be6cc506eb956ae68e9b54a57a30caeb2f5453e22786b50703517dbcc9756b03a2289dd0059093bf8852686b9bed16ee734eb9892164e944b7df74cce7b4f2783d867a7d564b564a5a203c764f93e3c17e76b12f8b115f10aaf417d8fa6b2e095832073a81cf3177980fe48ce15bb46d3aa0238c9dc6962f3403011a7cf552d677c98 + +Input: d0889c94ac0b7203acaab8d75d2cecb09e67623caab5bb3bfac8f83dc03771c7434af638e53a1ceecc4a6c560b040eb3b6613220878a5333c1aa6fa087d04dca91fb4cdd6efa90de2289247fa834b541e638638de816aabe92b6a84b8ef4f952149758ae0e50c27c304a2c918a757504fabc261b69a300f295dede54d77d645665126542386808510a7369155ad5d6fd4a428a0ea5b2eb8eaf08a1a624ace709ad14baaf3e1a0dc0c09be39c97b2c24543c8fca8bcc105dd6eeed36e034e52f680578011e2a5a5caf7624c192dd6b052829a560eb0e6200caf861c9431f768b4ba0357ba7bba8b43e9181e175fb87819928b5ae801704794b17464b0327c4fe84f6d030fe7c21d851a873861567113efe0573dad95a972afc079c4dfbb7ec178df324a77e77324608312c778d7b356156d59e1f4329e5ca7b06013c98f198ded33f0ab7ed6d4e6abf23dd28a40cb2ae613e7435d084376c4459ac47246598ca438de09ac9c6eb1e7a7c3466c43a0c3bb178b1d255863e048084d05d9b2b404a0fee8fc687c7cdac702a93067dead5f3d0d4b5f480eb3410504dde6e639bf7e106b4d6a8e2478bf906beacb8670a5a86d2e2e5314c87969f08de9b4c7e55883623f4f5b20a36288b41216bdfdcceb0d1e77a069a05e909446de064b07053b9b2fcb8192838f5805ddb90d0f25496b8ce7f432aca7e5e4abd133d733 +SHA3-256: 96de1882dcb62dc049e8b7a1ae6bf22d2502fd0e6fa8324a745880afe02d40c3 +SHA3-512: 523091240dbd8675d09dfeb0a8c5948cc408968744152b3267a54c242550e5a57d708e2e1858b34d9e6a9f7e90f3f73aa8742162217c9f8e754f01318feded74 +SHAKE-128: 97c03041d4a7e029e1f65537d2ec53a14af4f4df7ae2a8dd6f9d517a3735cd7a734683f2663da6d51f83d6524b8ade4984216cb9ac08723de2554b2f9087124bcf052cb82088c9a81b1bcfb47d17b991c2a308fabc2d80f8a6f3f87973e13fe0923d620aa4966251e88736f30ecb71518778eae9c948ce36317a77356af3ec9a4f4d2240fef0ad5c8af418fdc980ea21525fb31e120229597ddfbdf976d0b21f535da5ca2c4d9ce4dd4af9115f28b327114d4f7d6828fa11f4cd54cfb895c86b83b6633e0ece422a1cf1d00c016a76db9fbce2bdb718917f658f50c48f3daf657dd40188a2751dc6b06029da0f053dcff6b48479e5e2fbcdf0629abfcd243109201b67ad8d7725e0a30d6acfeb31852ea2289bf481962ce4709e995fcc2d38064a109a02b2284ff3cfb48fc4b2904d20e9040c23520f67ae83db1848e75a38c3bb1dc2125d91d11f60ac9a75835ff072505e5e54ffa64ab8dfdede00e8e9d2496c85a091024014a7cac4944a44a894af9f7abb0d7e0da47900ead144947dd8949c2104162307de9a926c891de5f7a405210774d150a6a62dee7b9ce9fbab792582940255f78b501632f9755d1696d5cbed21087570218d6d14e764575337c377e858fd0cc4f219b321c32d1a5c5eaa6ebcf5e3a25e08116c8f5d52236778738ba9a24c65dca537a1ed0ff1832fc6720125fd6ede4af19107e7f4ac6488ff2a82 +SHAKE-256: b27c92e87da4a91875e27eb7142e50854bed565dfa8d9dd9985557f181ae32392aadb641e83688a4143693bb64018e65703109a856df42f2afb651e5a87b176ed0a93efdb6830a7752e1453c6ed80252159994e900334745849938e08435cfa38fd5fd2df2ee65b0b204a3c190c8cf8b644e5cc58102952bb9147c12abcfd9a787e80870e90642d8f92319847050551e48b93dcc5d6c276f61cccdabdc3204a687dfdbb506a926e4c9b5aeea8b14d8d000382433449c4986514967d7287dc754d3dd35eb22ac8439af244687fea193a08fa1ef3d85ab0127b5d3cd696c6379319c30f36c7ca6a7ab8a9ced2312f5e0deef075a12fec60351698f9ebe4e8c2912e9a08317ca0fc13606337fe94a8c0e9b3b4ef70e40722ce96e0e33ef92cf8a7206b81cdd2140bbedebf4043c550368d0da222c5b91300648e816b4ce0a1b0716b4c6b895ad4681f0d4c345101973e1798bcdb150db2d5d6485bc99d06843960360322e6aa78b2e44de2db6acdf340144d077623e9352935c7ae4ef94e072db685fe7bff7a9ab1754f3654e53f7b4fcac58ca200a5fdcff9f3dd651fff961158e98c48459c04784c83066ce1443f22a4ee641b547755049ad42572ff5ed96f29b76472aa26bdc9009b28cb51ece42b155479019a2a0e24e9799da923ad41a4d665565765e7ae4f2d42f0d175e26a4d3d849d10299acd6318c62f74e388a052e9b + +Input: 41029e77d71d9d2fc348d79bb41f4445f9cb45fa77f553f37a03cd14776780102e89ca63a6e8246947722aa29faff22b8e39056171c86e418ffc65db776f429230a4ad1a1c93322bb0c4f5a73b0da4f4e81e7b7ded078c9e66156800024f7c37af75a0b9c6411cfdd5ac572901c4504c6ef6c481919fcb86be5b43f512ec0fe7cd13b4ec12322b8bc5b2fe113e1ce65ea04da9f425cc688b43ba1eec4e9bc4d9a9d97e03182e4deed853d7215f9b4e5a1ef229408fa2729c9e090db013554b0395e72febb608e5f9005b0e72949d379e85900dabf3c1906420074811defde645d4e44c314e9aca5532d52f71864092b2692f73fc4197a7c612f3085d88cfdd8a99f7c7d05c5552d53b89a529d21e4524e0103ef4ea7fab1bfaedc0477c03cb984ee9c62816a27185ba6d61d1874f47b24e7b993676d79d07e874e19a646d543dbb96aa722551b58ee7219542638252f216cb7c228c1a5434515e6de0573632441ed135cccbf6ed5e510cb728a931a69f9320cdec5fccad066701bdd348981438e24615768f686046bcf1002f19444c271243b6f0659b049545f705ea635ee61f9dfb6d44eb258c9ea2a4f50b3307746f2f61b97fb73b05784fcee419d8982662a30c02a38014a8864ddaf350036765f9bbb60d8ba0667777d66642fe9c85fea0fe41ed243c21026c76291d75154357fca56e90f3c746e60c8013ad64 +SHA3-256: 5c239f911cc201bfb5274dc8e474831a8b211122767f70321507302b1b6c038b +SHA3-512: 28622f0532258185f6dc49f785e9a2cd20ac871e15ce9e44f18924ab3e1409a8e4e25e21caca23b3de9439893e2dea3d15540328d1d3d14eb4398d0edd82ef0f +SHAKE-128: ad5012e0b759cb8c445cd4f5d0f98c0787dbc5ad72810d0b27bae565cabc2205d8ec43fb9db2ef58540090007d9ac641578b40fa02b2b002f1c0d941a13aff1134975a6d34413c00182521f7a87cc1074d6355caa81c6fbdae2cb35271ce93ab835bb9c9d27166a7cad28fa74a90d1152e536c3fcdaea086cb341beab282f4599b8b2c50fa2fc2acba17e37df1c370fce369acb4bb1ead3875d0f3e93f57f74302d4fab11947b20b15e57e7942d0ede2884f83b10ccebc7d667dc0fecc9190ebdced1696c0c6a50dcb35491a663ec1845a9306afd9794082fdd485913e451173b871da7999e5b5300e8a0083887ec4d5e46246ba98eabf56976d7614460f940297fe903c8217d95a0b8737e93b62171af650b8c3adddd58a098db38f4df53d1cd26e0acea92fa5bd75d37880c6a9313d85a306a2d97cd45d5aef6c5c97444aaef7c93918732e08e6ed9df241abe8762492f50e5d85e656c872fbbbf30648004ac2bc402ca370f13511c6a984ee5f2cc5010936e2b2fd4be1b948c8eaf8ad790679e08cca0065a849da5e4038166eb9fff0301b44db645206c3c76252515f0b3e19b0ffa690db8e431296760afd4589f292bf5aed03115f92acac150b71a3470f4dd3d33f8784e1cf0a6d7e19439361ec1de96fc0858350ba3b04a2a798de4b67098b5e4b4ef00c8a22e458617ca36ffc8d59ec0906250958bd3c8bbc5870e718 +SHAKE-256: cc8caf92486e7f9720e735eda0af34c606f65b854129692e7ee6a8231b520925adb5b9f5d599e5721a4ca4dac74f2bd1a9cd066ce827f90c6d35bb4e83432f441885b84b909e70c10f19da5688425f076cb8deda4233e99566becb205101710d9a3f10de9104b124fa974e0ed0b4503d2205bae8ea06ba8635078f5e2ccf93c10d2c7c608d74cc9cf1b4334631304ff1de23ff14b2750512c99e597b55e22510afeac209e412bb0a2bcfea62f5497263ca413516290d1a2081662b612a0305a1cd60285ab92786b82839711a19fa79a48bb3fd4022d565cb3255204e3654a7f2e61c53ee54a8b865ccea6bf6d2e30ebe9c30f5bd948ccfd636304ac3fe29656992e510b8a0ff0c3d6b1433faaf7049b959b65393dc8eeaab26ff16d836d53ec14a248b548cef84cd328fa8fe53c69611c5e2ab1b6c6f0c8beffcfd66ec4b7f8defe7ee6690e5411398305eb5a26a52c73b75643bda05871c88ae5f0272fdbe7ec40806071549bb2c19434cd518a1cb8ec5dc3f3d8f28e6ed5503c89fac6e4a4429d4478ba64ea54fda56f35623bc877a761ed926fbb32891c231f41577e11ed983b6b34f3a2df95ee35059c58285ca85a31c9928b72e08c95af3862cb22fdc69322153ce1d35462d4b0b2c45ec955b46e8a83e594e4bf84152ef6d64030965051062608de8681d147b0b4db6168022cf17cef7e1f037535bdc576d346a43b49a + +Input: f5e94186ea504a9c836d32f9ea85e61afe9646c2093e5387944d626e213be9b839c136ea24e2dddc1f4ad0e64f8892213698493a067efc5d5461b8a1d78029e7d7c8430fd32d701d19a4a7b35f360f3299eb3f8577ec4aa6f34c130b02d6f8bb7d86566864210634b5c1d6b73096cd297809407871aa531b68be0124b001045fb2cf6cd458b5fdf769dcefadb1082453692ba8fa940e7599693164a2f4d174f258462cef379ebe5f68c0e98fc1f12173744ec759541f03ff501c5d4a704cf4acf6df5050e524c28a550db9e40c642be26c430eed401f9a8327f3aa875b6f13edec522c257a487cbc6cce036cd83773c4f4f86963216b1389bf7479b4a09190f82b5ac677db1c3b63b67b863924c5371fd881ccd8814ae9b9a1c9f6297c73c03b2bc5cd6d6f9794d8c232a6018c3a98ae10b6517749fa131d096cba733748d4f5ff3a78f58556408f735978657c0629d31dfb29a05ef1d06bd3248d6d5a33962794440ce986d79e4fa031c35a918101c58951d86d561611644ba49cf9e121cb95ff82b2655b7e313349121c2784a3f8098ea0e1749e9f403c90bd74ded17c952cae1b8f353552fb7e47b97b7a4de139c6d5d2403f955c2d1db9f495aa5f2e1155713263ed42d7c96e8dfc37c85b7e89f4fe86c0daf5cfe0db50bc9208b2a179da1035f20b033588f2b2b963815eb118c2419b77fb106f47e7361afefdbe +SHA3-256: f2ba8762e9507a75f6935cf46fdebde3d4d2023312c08fa951334b7e2fa00bd8 +SHA3-512: 66549e37d7287d0c76d39a3a8ac2c5f073cf45bfd8f70936ec1580120184b397584b7b6f5f666839208fca4667207f5538442f545bb2de01ada69268afd3a90a +SHAKE-128: 8ce25ea63e76d706951716b09c58bd5e79f73d6b858c7219f16bee3850ab85573de91de627a0596490ad980edc8053537b35fb46c0d2ace6f517a61181d99c0560e8105d982b1897a396a125e7f239c129344706085c356d29d7984f63a056c01c80df283580262b90a492ff1eabddd503c2c77edb550cb45637a649e4b3a5fb2945a10ffaa840788635df8df6647e5960af7757a15303cf75769c21cee9d49b5feb7c8184ad2833ed849da20626ed938d6f0bc8789caecf6337250eac570bc22ab1ffa67d5954eab9b1657d10546fd30f0265169a0284416fd9d2700de8a0b68485912ba6e30ed09dc5aa049b3fada66de1f04a20a99b0001551a7330e02afb77e627e8855241a43f93314b658d5c00c1b97a1c3560353d439de842ea93d15bb494faf3c820063ccb0ec2edd9d03fad936bc0b4c49f005d0b6d1bc7ec730d74baccc803a4b8fbccaeedbbe2e78c3974be9cd712bafad361d47dd57fa3519b9f02e1cf41a1bed523ac9452bb6d0f0d94d34838df8a70b0e8326a077196ea3eca112ad2d8e0c6318a077f79ae13f7500d985e9e4881989e2b29c6ebffc4b0f52d97ad27f4f378ad1771b34faa74954c3475c6b5dc344ccc9e085c3dc84d33dce337371b34796491226b7ec6ddd0bb8ec010980becd3655ebd4934afce487e6e642b4547aa85ba60241f56e9779a1cdacc4814e43d900189438ab13fbf159619c5 +SHAKE-256: 74f527fb3fb0d239e0a615ea9492886faff24db03ab73a060344c30a8480ddd8a71a1143c30b38387002e973119b7b6118a1c1a1f052ea4c92e6a270f34c04274ff667b3a01632ce688d12d70f61ab01f5511839b8fe8574682077f1593f3e5eb08757b4e245a69748e450b543a1b3ed5aba6781c5acc383081312f74818d5dd796172ab6a22041ccde168158798dab8891db9095e50d78b53469057f37f04b10fe4a0982653211fc7e18ab45119e018150ac51496747d478941b247e661911d71424c51b16647e14dff8b77d7f0b6f4e7cc483a161f84874a142b58f17f6b56e133a353bf9ff4ee7c76baf061a09736a682e715c6f718366df0373083bee6fba709de9ee29432774d871a12b11348e15ab75d6a7c539aae95241cd7484c7eed382df0ec5a89a6304f02ce3fb58150f012c7463d76c0e182bd31e870f78138ee1db9f301a80ad6a0a0966fd712796ff95ff6f5feaedadb44fa3506c238d49e025bd8ffdf842724ba5ccbf1e42c1bf6c3401dbd97cd1325e92e1ab6a678199b9f42b7a6983016b0cf492aa3a82a0a271f69b927382fbeb5f84aebe8fb5f2077a7d81a3949506b306032cdd0b12c59272df703130b0751799cffb1121672afb40ad3b3fdab88b0ab370d37967b382e129b48ad6df7bc0f88b94057b33f8d9c7d61862c05e24f67e29642b38eb2cc702c8de41256fcf761a010e250daf3095691d4 + +Input: 0b747b5621a882829c350b45c0e4462eb367fc185a22faef6ce92ff203a42c253e039fbda10251a52c93afd5679fad1cfa4b084c0655cd4912f9a98e794f520d726858a6ebc0db4cb0cb381952a3fedd4df80c9b6dfc37e2259ae1ba6e2bc124227fd4e8cb49f3404fbdd4490b05013908def280ce882b4d85d48bcafa97b3c41802a7d40e0df359f98f59c6a5129579f3ce5123125a1e7ebe28ae9642ed9f463b034c9adf8d70b25a3ea7696e0435f8b7e7c8c0be0549762e5de6e142751470a161571790874130829def39f4144b40b9043652af8f547914e497fa2806745e11e22ab19bca735b497d5a8856596a37899d6b3c08c7e9cb7e3b65422266bc9741da457180eb1559f737fe50824634280a24e05400a32f4cc1f13b211b21a799d2915682b4ba84cde34cb5cd1531ef05827356a0a92e04c3a4a85f38461815b9d008bf6071aebf952adc0867871a4923032e6565dde803740de02e0edfb0c9b2c8f56ed6b4a8b504e33bc6d84c6f747b4c83a8b60b07fae5b15c53bdfa14d18f8eb335beb0bd28ea0baba23b7903c9f27a83420904a9a2884f74094d2650a9f1d5139fa434b7097767041bcacb74c01f25276b5cbe707e98ff3e29c833ec58a3f3659b7f0eec8d506c6da3432aee90faa5b3e4c8876b385310c01d56a586b89c02a036a3ba8da4bf4af7642e912788166e03cb326482b4ed43dbe2995598 +SHA3-256: e35cb485992a4bcd27f71af043b8bb16c7c1e3a36a4d1160980d51e49b650a15 +SHA3-512: df7918b9094bde46e50778d46c268249517b674252251cc8dc0b6bd27d3d7e4017463f57c78ca57e048361b406321adf020fab26ca2a75a977281a06f4c012b6 +SHAKE-128: c6b9414d60943abb0344b486ea62d6b34dc6b6167882601fb0863566235197c38f414e906f7624a1e7276d83537c50521a033a436578dc21a7f9f30847d75d22cdfffaa04bc867030f4582149bde9c5d14748e7162251628abd5e9c2d406284dcdf03cd0fae773669f27febb86bcfc835193f0f72ad2346387588541c2437174fbf0fb3c268b675b2763545fdee92ee0c9c357e761caea60b1ed77f26781b60e41b47c87e54b22c7b67b8c99fe49005552b85d02b7183988f03d9610fad3e44342dd97efecff9b7ae9850af873af31ad067fe7b80bafc1f0076971247eea57e28b6dfecaf3b15c559305bd06527bbb00eeef112b0c16b9845b80385a5f2656cf3c90acfb01c511fb355ce63ef7aa35fb004d876867c737cb493e6a9e85e2683aebb95621eb19968a6c0d63930b4bf902a6b8e3b6131974b273f2a49c4bb452d453b68915d35c28ea2945d11fbf2f109086da7a1af9e944bea9c182ee4e74d742a31ee7a32406d72345245a1434cf6d9f52f7dbc8dc87d2f84825bbf72dbfcd8dc9c6c30f90b0b1e269350f69dbfb5739d05b965c26d38838de8dd5fa041a81eb3253f3123a3cacf51cc14d5abe46db1492b2bfbc427853d5b4d4fb9f548b17fe5bda87d08ff5fc06b8c817143ce8f0acc7bdb8f9a42523d0c407398c2958a95701d8c29efd8303e93e0500dac15df31ad06375a0f6ddf63436a9b2ddb1c6ddbd +SHAKE-256: 1fc37824fb86b751a3cd26aac6235c445ea5cd0a7c1f7ced0fc8af41a985c830fd6dca5aae34eb3c0bdffcacca58d0a8bfe677c8799854902111a1c4cb86b518acc0013b65cdd146cc4aac42cb3959a17aac1ef686bd4bc62f3ce778df22b89f12476ea5e5f63d8266e16f0f0ca816fe816407a4d742c59801ff91ec5271c6ac3382e3b5c9ec913c0bb796c11e2156edb601a9150e5ec16c5a0ab100efd1cf1e3fd2a9da5ce4c07815575364fd2a361aaa42b7dee815511f45b42777bfc5fc8873d0d47b9b83ff66e4ada9f0531738956a7e00bf956a111655e9085b792dbe76ad34ac93cba7b8fcd7b4f61de067a7c32d1e5528dd71bb0ba804b499584bf99a1b76bb5c5fe4eda28b7d45f9101f82703054ca260f3fcbd9070d71ad55f9e4fc69a624904982e7c937691776978de3878eb2ed65a122ca0dac09b55b8b28276121a9c301c18e1797c0cf7b573ba97eeace1c808fa5c24819cbbcd0fc3d5b8826505d4bb84eb1f820419e088c45f8787539ef0a6ebdcaae8f18d33df73696e50486c6311d9c31f5353a609f1420708376d483c00e1353432bd8b4799fd1d99ca201138a2de110fe54b4647f5b63d77f5c6d4dbf85bba533c296ef17ade3713d5509390d10b6ac860cfdf2b0a6872c9c9a7d08e89e1a5972ea58a6685788e4613a44fa3ae0a52fd3331e4a7bf4103691197ea3537f8e307b9f2f4fb9def21a96f8 + +Input: a98d5c71ed25e354f9df148a2819ec43a5bba6f469040675282c43b91253a23460e7595520449cc8d4cd4da5ae259ca696d0e4164a170fb10344fef80770dcd8894e22eb41af07183a5238d0f7dc30b1c9fcd7b64f91c75f419f3f05b6de81fb57ed9318690ea57e95f95815e9eccf2217b8d89ba81874d671b5b00b0706407b6a127ba6ab142cd9fa83345224e3cfe82105533c87511396e00bb4f6c34a9aa18694a0965b4acb3ee8320b6c8f106979142cb2549e4e2e489cefc7747a7d31285a7570b0edf02c63e3babe9eda1f2f14d11185e19b11dd5950f7e51270ae007e5b059ac03bda1767587882223be12c6af2db6aa7187a2516975cba5134825c315099514c9180625095be91e92d8a1ae9320cc37668f3ddcaea46cfe99414b59ee4d284db7773b21e6e33123225c6039a6707e17c3373a5814c5f2d8f5e34cb4c1a9742fb79ef0ab315c3a6cfa1b60e1c9e346461087410cd84369e141c86ea1cb82520b27d65a9155afded16c8f78bc70be88976323ceaf5ee0e57c54103da79327d2fe767821051cc96e64ffa6f3a5ae7d7ae05b23719301575a68c352f8cdebce533e4ef85b5fc48d34133deb606db8522fbb87310ae0296e77b0d69d1391175ef21733f0b655a554485a1ce98232297ae6e9cdb2905eb4cda87aa949d0dd86b0cd63086078a2451c8baebdefcfa03a0e4c7ce9974020411549d1b7a151f +SHA3-256: 9379fc3379d734aa4bc9462dffe1ef4d6a0990dd2b7f7c962c80de66096c255a +SHA3-512: b07e25de63d2a244b8bdb473a551dd44a6c5e41da72061062a42a44a7278c6aa678b8c127312ac265eaecf354b0a0243144d2de65356a885d29ceddb7951cf89 +SHAKE-128: 77f56c76c4f40d6a51f7b4e3d19b34e358e8a1ffb14cca68f23f1608c95358e1e64581d297a7a062c06db103f547486932c1c43fd95cda0e17168afc0a703993e52d0e0251f09c0a04438c84613bd9806fa8777112fd6d6df5ce97db1c68e58164bf1a764c1a192ee27c97eb313b822d5a5fdc0b8a911208ec051d76395d7756784c23ab7e0e98a21b00123afa74371b9482ad80378419b9214e3b4ba49bc5bddc24aaf175e6c678a86eb42e1f3a12deef554481cdca0b0032dfe55749fbdd09d3eb9f792df57357f2cdc3aa215f01031db33598efcbe183a52e4b4dccaf19e2d79ff220d075af9fd5f16bf73f783754b75110268919041969e7bcf6be326695aa4bd786c94bb22873c3f99061f932710c9b66f9403470a4ee8a4489199162817eb72b5ae3b457c35dc973c6a33aa3e5feba69108e98cbd67270e507f6558d8c973be74ee782d4b0b91714ecb55ffbb7b13dfa60f02fe4ceebb535814449048f4c260e98e8b80e5002b46b3e7c752e43f1616b8fef82b50f894182061e91cf06cfd42ee23bbaffceb8d2ba93acfe242f68dc980e857ac1d71f25d7fd7622fb50e6a8c39f5de9c70f4e2d0cda35a8b4713d4ce7aa96437032c5a2569be19e7ef87405b14ee0107ab71f731a2bc014c2691af1d8f2ccf456505c3d42d6eb1af75168b1cb4db9a35d29c9b2ca7fa5c444bcf8035c816354f6a4aee63e0cae8c7c3f +SHAKE-256: 83158939de50f9c0bef1c8270affb75cb13f23b84742f6e61d36961e9c1596fbb1b2fabeaa7e42db160befeaa74f82374cac494070a355ea2ef4b2c51ccaba715040214530f6ae3403fd3e999bc7bb57d5af3e1fc1248576a055cdd0c57d6774e6100ce42cc94e874896b9acacec248082715229acf1989a8f7cd7bae1e6cf0b1934a6a8a7b867fe269531157468de1005205e6cf7f749fbbc7d7cbc84e938e276828430b2e42a4726b990d63198d93a8f2854100de586e3d0af355f24895e3754cc2b24b80b2be9c8c33f269ba7159e2c85f6dc32c4436343f226a8983926db9c62bf5a45e61ee518564e431d685d139fcc2511bce799af60c7119de67bd7eaa6bfe58bf1e056305ebf10f737b3970bf4a72a12b9d560f0d0989cf981525f8756d297ea7fb40dca79bf695736e2a97cacc943cf8ff1cb1513bd2f585746932011e92d477a7a923ef31da315ad3908058d16d3ba1e7f87914c8625866cc23ce891e01b5066178f5eb19354c5149807c555d7d4839ecdd5b24fbc2aa3a0ad0801aebbeff872d2de5af1bd39e780ecc883fe070a2ef42308fbef4bc031b763cccfe108d3509d1f8b115019586fe711d0f76435d2e560e50542da472cb32423ff71b754e4b993fbc6213adcf729e4d4c6c725c0defd22e666c7ec6a66ece8e555d0f332b640ab5f5146a697c24f46c7dfe4288143c8024813f1e678d30d54630909 diff --git a/third_party/boringssl/kit/src/crypto/kyber/kyber.c b/third_party/boringssl/kit/src/crypto/kyber/kyber.c new file mode 100644 index 00000000..98c70e6e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/kyber.c @@ -0,0 +1,834 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +// See +// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf + +#define DEGREE 256 +#define RANK 3 + +static const size_t kBarrettMultiplier = 5039; +static const unsigned kBarrettShift = 24; +static const uint16_t kPrime = 3329; +static const int kLog2Prime = 12; +static const uint16_t kHalfPrime = (/*kPrime=*/3329 - 1) / 2; +static const int kDU = 10; +static const int kDV = 4; +// kInverseDegree is 128^-1 mod 3329; 128 because kPrime does not have a 512th +// root of unity. +static const uint16_t kInverseDegree = 3303; +static const size_t kEncodedVectorSize = + (/*kLog2Prime=*/12 * DEGREE / 8) * RANK; +static const size_t kCompressedVectorSize = /*kDU=*/10 * RANK * DEGREE / 8; + +typedef struct scalar { + // On every function entry and exit, 0 <= c < kPrime. + uint16_t c[DEGREE]; +} scalar; + +typedef struct vector { + scalar v[RANK]; +} vector; + +typedef struct matrix { + scalar v[RANK][RANK]; +} matrix; + +// This bit of Python will be referenced in some of the following comments: +// +// p = 3329 +// +// def bitreverse(i): +// ret = 0 +// for n in range(7): +// bit = i & 1 +// ret <<= 1 +// ret |= bit +// i >>= 1 +// return ret + +// kNTTRoots = [pow(17, bitreverse(i), p) for i in range(128)] +static const uint16_t kNTTRoots[128] = { + 1, 1729, 2580, 3289, 2642, 630, 1897, 848, 1062, 1919, 193, 797, + 2786, 3260, 569, 1746, 296, 2447, 1339, 1476, 3046, 56, 2240, 1333, + 1426, 2094, 535, 2882, 2393, 2879, 1974, 821, 289, 331, 3253, 1756, + 1197, 2304, 2277, 2055, 650, 1977, 2513, 632, 2865, 33, 1320, 1915, + 2319, 1435, 807, 452, 1438, 2868, 1534, 2402, 2647, 2617, 1481, 648, + 2474, 3110, 1227, 910, 17, 2761, 583, 2649, 1637, 723, 2288, 1100, + 1409, 2662, 3281, 233, 756, 2156, 3015, 3050, 1703, 1651, 2789, 1789, + 1847, 952, 1461, 2687, 939, 2308, 2437, 2388, 733, 2337, 268, 641, + 1584, 2298, 2037, 3220, 375, 2549, 2090, 1645, 1063, 319, 2773, 757, + 2099, 561, 2466, 2594, 2804, 1092, 403, 1026, 1143, 2150, 2775, 886, + 1722, 1212, 1874, 1029, 2110, 2935, 885, 2154, +}; + +// kInverseNTTRoots = [pow(17, -bitreverse(i), p) for i in range(128)] +static const uint16_t kInverseNTTRoots[128] = { + 1, 1600, 40, 749, 2481, 1432, 2699, 687, 1583, 2760, 69, 543, + 2532, 3136, 1410, 2267, 2508, 1355, 450, 936, 447, 2794, 1235, 1903, + 1996, 1089, 3273, 283, 1853, 1990, 882, 3033, 2419, 2102, 219, 855, + 2681, 1848, 712, 682, 927, 1795, 461, 1891, 2877, 2522, 1894, 1010, + 1414, 2009, 3296, 464, 2697, 816, 1352, 2679, 1274, 1052, 1025, 2132, + 1573, 76, 2998, 3040, 1175, 2444, 394, 1219, 2300, 1455, 2117, 1607, + 2443, 554, 1179, 2186, 2303, 2926, 2237, 525, 735, 863, 2768, 1230, + 2572, 556, 3010, 2266, 1684, 1239, 780, 2954, 109, 1292, 1031, 1745, + 2688, 3061, 992, 2596, 941, 892, 1021, 2390, 642, 1868, 2377, 1482, + 1540, 540, 1678, 1626, 279, 314, 1173, 2573, 3096, 48, 667, 1920, + 2229, 1041, 2606, 1692, 680, 2746, 568, 3312, +}; + +// kModRoots = [pow(17, 2*bitreverse(i) + 1, p) for i in range(128)] +static const uint16_t kModRoots[128] = { + 17, 3312, 2761, 568, 583, 2746, 2649, 680, 1637, 1692, 723, 2606, + 2288, 1041, 1100, 2229, 1409, 1920, 2662, 667, 3281, 48, 233, 3096, + 756, 2573, 2156, 1173, 3015, 314, 3050, 279, 1703, 1626, 1651, 1678, + 2789, 540, 1789, 1540, 1847, 1482, 952, 2377, 1461, 1868, 2687, 642, + 939, 2390, 2308, 1021, 2437, 892, 2388, 941, 733, 2596, 2337, 992, + 268, 3061, 641, 2688, 1584, 1745, 2298, 1031, 2037, 1292, 3220, 109, + 375, 2954, 2549, 780, 2090, 1239, 1645, 1684, 1063, 2266, 319, 3010, + 2773, 556, 757, 2572, 2099, 1230, 561, 2768, 2466, 863, 2594, 735, + 2804, 525, 1092, 2237, 403, 2926, 1026, 2303, 1143, 2186, 2150, 1179, + 2775, 554, 886, 2443, 1722, 1607, 1212, 2117, 1874, 1455, 1029, 2300, + 2110, 1219, 2935, 394, 885, 2444, 2154, 1175, +}; + +// reduce_once reduces 0 <= x < 2*kPrime, mod kPrime. +static uint16_t reduce_once(uint16_t x) { + assert(x < 2 * kPrime); + const uint16_t subtracted = x - kPrime; + uint16_t mask = 0u - (subtracted >> 15); + // On Aarch64, omitting a |value_barrier_u16| results in a 2x speedup of Kyber + // overall and Clang still produces constant-time code using `csel`. On other + // platforms & compilers on godbolt that we care about, this code also + // produces constant-time output. + return (mask & x) | (~mask & subtracted); +} + +// constant time reduce x mod kPrime using Barrett reduction. x must be less +// than kPrime + 2×kPrime². +static uint16_t reduce(uint32_t x) { + assert(x < kPrime + 2u * kPrime * kPrime); + uint64_t product = (uint64_t)x * kBarrettMultiplier; + uint32_t quotient = (uint32_t)(product >> kBarrettShift); + uint32_t remainder = x - quotient * kPrime; + return reduce_once(remainder); +} + +static void scalar_zero(scalar *out) { OPENSSL_memset(out, 0, sizeof(*out)); } + +static void vector_zero(vector *out) { OPENSSL_memset(out, 0, sizeof(*out)); } + +// In place number theoretic transform of a given scalar. +// Note that Kyber's kPrime 3329 does not have a 512th root of unity, so this +// transform leaves off the last iteration of the usual FFT code, with the 128 +// relevant roots of unity being stored in |kNTTRoots|. This means the output +// should be seen as 128 elements in GF(3329^2), with the coefficients of the +// elements being consecutive entries in |s->c|. +static void scalar_ntt(scalar *s) { + int offset = DEGREE; + // `int` is used here because using `size_t` throughout caused a ~5% slowdown + // with Clang 14 on Aarch64. + for (int step = 1; step < DEGREE / 2; step <<= 1) { + offset >>= 1; + int k = 0; + for (int i = 0; i < step; i++) { + const uint32_t step_root = kNTTRoots[i + step]; + for (int j = k; j < k + offset; j++) { + uint16_t odd = reduce(step_root * s->c[j + offset]); + uint16_t even = s->c[j]; + s->c[j] = reduce_once(odd + even); + s->c[j + offset] = reduce_once(even - odd + kPrime); + } + k += 2 * offset; + } + } +} + +static void vector_ntt(vector *a) { + for (int i = 0; i < RANK; i++) { + scalar_ntt(&a->v[i]); + } +} + +// In place inverse number theoretic transform of a given scalar, with pairs of +// entries of s->v being interpreted as elements of GF(3329^2). Just as with the +// number theoretic transform, this leaves off the first step of the normal iFFT +// to account for the fact that 3329 does not have a 512th root of unity, using +// the precomputed 128 roots of unity stored in |kInverseNTTRoots|. +static void scalar_inverse_ntt(scalar *s) { + int step = DEGREE / 2; + // `int` is used here because using `size_t` throughout caused a ~5% slowdown + // with Clang 14 on Aarch64. + for (int offset = 2; offset < DEGREE; offset <<= 1) { + step >>= 1; + int k = 0; + for (int i = 0; i < step; i++) { + uint32_t step_root = kInverseNTTRoots[i + step]; + for (int j = k; j < k + offset; j++) { + uint16_t odd = s->c[j + offset]; + uint16_t even = s->c[j]; + s->c[j] = reduce_once(odd + even); + s->c[j + offset] = reduce(step_root * (even - odd + kPrime)); + } + k += 2 * offset; + } + } + for (int i = 0; i < DEGREE; i++) { + s->c[i] = reduce(s->c[i] * kInverseDegree); + } +} + +static void vector_inverse_ntt(vector *a) { + for (int i = 0; i < RANK; i++) { + scalar_inverse_ntt(&a->v[i]); + } +} + +static void scalar_add(scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE; i++) { + lhs->c[i] = reduce_once(lhs->c[i] + rhs->c[i]); + } +} + +static void scalar_sub(scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE; i++) { + lhs->c[i] = reduce_once(lhs->c[i] - rhs->c[i] + kPrime); + } +} + +// Multiplying two scalars in the number theoretically transformed state. Since +// 3329 does not have a 512th root of unity, this means we have to interpret +// the 2*ith and (2*i+1)th entries of the scalar as elements of GF(3329)[X]/(X^2 +// - 17^(2*bitreverse(i)+1)) The value of 17^(2*bitreverse(i)+1) mod 3329 is +// stored in the precomputed |kModRoots| table. Note that our Barrett transform +// only allows us to multipy two reduced numbers together, so we need some +// intermediate reduction steps, even if an uint64_t could hold 3 multiplied +// numbers. +static void scalar_mult(scalar *out, const scalar *lhs, const scalar *rhs) { + for (int i = 0; i < DEGREE / 2; i++) { + uint32_t real_real = (uint32_t)lhs->c[2 * i] * rhs->c[2 * i]; + uint32_t img_img = (uint32_t)lhs->c[2 * i + 1] * rhs->c[2 * i + 1]; + uint32_t real_img = (uint32_t)lhs->c[2 * i] * rhs->c[2 * i + 1]; + uint32_t img_real = (uint32_t)lhs->c[2 * i + 1] * rhs->c[2 * i]; + out->c[2 * i] = + reduce(real_real + (uint32_t)reduce(img_img) * kModRoots[i]); + out->c[2 * i + 1] = reduce(img_real + real_img); + } +} + +static void vector_add(vector *lhs, const vector *rhs) { + for (int i = 0; i < RANK; i++) { + scalar_add(&lhs->v[i], &rhs->v[i]); + } +} + +static void matrix_mult(vector *out, const matrix *m, const vector *a) { + vector_zero(out); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + scalar product; + scalar_mult(&product, &m->v[i][j], &a->v[j]); + scalar_add(&out->v[i], &product); + } + } +} + +static void matrix_mult_transpose(vector *out, const matrix *m, + const vector *a) { + vector_zero(out); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + scalar product; + scalar_mult(&product, &m->v[j][i], &a->v[j]); + scalar_add(&out->v[i], &product); + } + } +} + +static void scalar_inner_product(scalar *out, const vector *lhs, + const vector *rhs) { + scalar_zero(out); + for (int i = 0; i < RANK; i++) { + scalar product; + scalar_mult(&product, &lhs->v[i], &rhs->v[i]); + scalar_add(out, &product); + } +} + +// Algorithm 1 of the Kyber spec. Rejection samples a Keccak stream to get +// uniformly distributed elements. This is used for matrix expansion and only +// operates on public inputs. +static void scalar_from_keccak_vartime(scalar *out, + struct BORINGSSL_keccak_st *keccak_ctx) { + assert(keccak_ctx->offset == 0); + assert(keccak_ctx->rate_bytes == 168); + static_assert(168 % 3 == 0, "block and coefficient boundaries do not align"); + + int done = 0; + while (done < DEGREE) { + uint8_t block[168]; + BORINGSSL_keccak_squeeze(keccak_ctx, block, sizeof(block)); + for (size_t i = 0; i < sizeof(block) && done < DEGREE; i += 3) { + uint16_t d1 = block[i] + 256 * (block[i + 1] % 16); + uint16_t d2 = block[i + 1] / 16 + 16 * block[i + 2]; + if (d1 < kPrime) { + out->c[done++] = d1; + } + if (d2 < kPrime && done < DEGREE) { + out->c[done++] = d2; + } + } + } +} + +// Algorithm 2 of the Kyber spec, with eta fixed to two and the PRF call +// included. Creates binominally distributed elements by sampling 2*|eta| bits, +// and setting the coefficient to the count of the first bits minus the count of +// the second bits, resulting in a centered binomial distribution. Since eta is +// two this gives -2/2 with a probability of 1/16, -1/1 with probability 1/4, +// and 0 with probability 3/8. +static void scalar_centered_binomial_distribution_eta_2_with_prf( + scalar *out, const uint8_t input[33]) { + uint8_t entropy[128]; + static_assert(sizeof(entropy) == 2 * /*kEta=*/2 * DEGREE / 8, ""); + BORINGSSL_keccak(entropy, sizeof(entropy), input, 33, boringssl_shake256); + + for (int i = 0; i < DEGREE; i += 2) { + uint8_t byte = entropy[i / 2]; + + uint16_t value = kPrime; + value += (byte & 1) + ((byte >> 1) & 1); + value -= ((byte >> 2) & 1) + ((byte >> 3) & 1); + out->c[i] = reduce_once(value); + + byte >>= 4; + value = kPrime; + value += (byte & 1) + ((byte >> 1) & 1); + value -= ((byte >> 2) & 1) + ((byte >> 3) & 1); + out->c[i + 1] = reduce_once(value); + } +} + +// Generates a secret vector by using +// |scalar_centered_binomial_distribution_eta_2_with_prf|, using the given seed +// appending and incrementing |counter| for entry of the vector. +static void vector_generate_secret_eta_2(vector *out, uint8_t *counter, + const uint8_t seed[32]) { + uint8_t input[33]; + OPENSSL_memcpy(input, seed, 32); + for (int i = 0; i < RANK; i++) { + input[32] = (*counter)++; + scalar_centered_binomial_distribution_eta_2_with_prf(&out->v[i], input); + } +} + +// Expands the matrix of a seed for key generation and for encaps-CPA. +static void matrix_expand(matrix *out, const uint8_t rho[32]) { + uint8_t input[34]; + OPENSSL_memcpy(input, rho, 32); + for (int i = 0; i < RANK; i++) { + for (int j = 0; j < RANK; j++) { + input[32] = i; + input[33] = j; + struct BORINGSSL_keccak_st keccak_ctx; + BORINGSSL_keccak_init(&keccak_ctx, input, sizeof(input), + boringssl_shake128); + scalar_from_keccak_vartime(&out->v[i][j], &keccak_ctx); + } + } +} + +static const uint8_t kMasks[8] = {0x01, 0x03, 0x07, 0x0f, + 0x1f, 0x3f, 0x7f, 0xff}; + +static void scalar_encode(uint8_t *out, const scalar *s, int bits) { + assert(bits <= (int)sizeof(*s->c) * 8 && bits != 1); + + uint8_t out_byte = 0; + int out_byte_bits = 0; + + for (int i = 0; i < DEGREE; i++) { + uint16_t element = s->c[i]; + int element_bits_done = 0; + + while (element_bits_done < bits) { + int chunk_bits = bits - element_bits_done; + int out_bits_remaining = 8 - out_byte_bits; + if (chunk_bits >= out_bits_remaining) { + chunk_bits = out_bits_remaining; + out_byte |= (element & kMasks[chunk_bits - 1]) << out_byte_bits; + *out = out_byte; + out++; + out_byte_bits = 0; + out_byte = 0; + } else { + out_byte |= (element & kMasks[chunk_bits - 1]) << out_byte_bits; + out_byte_bits += chunk_bits; + } + + element_bits_done += chunk_bits; + element >>= chunk_bits; + } + } + + if (out_byte_bits > 0) { + *out = out_byte; + } +} + +// scalar_encode_1 is |scalar_encode| specialised for |bits| == 1. +static void scalar_encode_1(uint8_t out[32], const scalar *s) { + for (int i = 0; i < DEGREE; i += 8) { + uint8_t out_byte = 0; + for (int j = 0; j < 8; j++) { + out_byte |= (s->c[i + j] & 1) << j; + } + *out = out_byte; + out++; + } +} + +// Encodes an entire vector into 32*|RANK|*|bits| bytes. Note that since 256 +// (DEGREE) is divisible by 8, the individual vector entries will always fill a +// whole number of bytes, so we do not need to worry about bit packing here. +static void vector_encode(uint8_t *out, const vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_encode(out + i * bits * DEGREE / 8, &a->v[i], bits); + } +} + +// scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in +// |out|. It returns one on success and zero if any parsed value is >= +// |kPrime|. +static int scalar_decode(scalar *out, const uint8_t *in, int bits) { + assert(bits <= (int)sizeof(*out->c) * 8 && bits != 1); + + uint8_t in_byte = 0; + int in_byte_bits_left = 0; + + for (int i = 0; i < DEGREE; i++) { + uint16_t element = 0; + int element_bits_done = 0; + + while (element_bits_done < bits) { + if (in_byte_bits_left == 0) { + in_byte = *in; + in++; + in_byte_bits_left = 8; + } + + int chunk_bits = bits - element_bits_done; + if (chunk_bits > in_byte_bits_left) { + chunk_bits = in_byte_bits_left; + } + + element |= (in_byte & kMasks[chunk_bits - 1]) << element_bits_done; + in_byte_bits_left -= chunk_bits; + in_byte >>= chunk_bits; + + element_bits_done += chunk_bits; + } + + if (element >= kPrime) { + return 0; + } + out->c[i] = element; + } + + return 1; +} + +// scalar_decode_1 is |scalar_decode| specialised for |bits| == 1. +static void scalar_decode_1(scalar *out, const uint8_t in[32]) { + for (int i = 0; i < DEGREE; i += 8) { + uint8_t in_byte = *in; + in++; + for (int j = 0; j < 8; j++) { + out->c[i + j] = in_byte & 1; + in_byte >>= 1; + } + } +} + +// Decodes 32*|RANK|*|bits| bytes from |in| into |out|. It returns one on +// success or zero if any parsed value is >= |kPrime|. +static int vector_decode(vector *out, const uint8_t *in, int bits) { + for (int i = 0; i < RANK; i++) { + if (!scalar_decode(&out->v[i], in + i * bits * DEGREE / 8, bits)) { + return 0; + } + } + return 1; +} + +// Compresses (lossily) an input |x| mod 3329 into |bits| many bits by grouping +// numbers close to each other together. The formula used is +// round(2^|bits|/kPrime*x) mod 2^|bits|. +// Uses Barrett reduction to achieve constant time. Since we need both the +// remainder (for rounding) and the quotient (as the result), we cannot use +// |reduce| here, but need to do the Barrett reduction directly. +static uint16_t compress(uint16_t x, int bits) { + uint32_t shifted = (uint32_t)x << bits; + uint64_t product = (uint64_t)shifted * kBarrettMultiplier; + uint32_t quotient = (uint32_t)(product >> kBarrettShift); + uint32_t remainder = shifted - quotient * kPrime; + + // Adjust the quotient to round correctly: + // 0 <= remainder <= kHalfPrime round to 0 + // kHalfPrime < remainder <= kPrime + kHalfPrime round to 1 + // kPrime + kHalfPrime < remainder < 2 * kPrime round to 2 + assert(remainder < 2u * kPrime); + quotient += 1 & constant_time_lt_w(kHalfPrime, remainder); + quotient += 1 & constant_time_lt_w(kPrime + kHalfPrime, remainder); + return quotient & ((1 << bits) - 1); +} + +// Decompresses |x| by using an equi-distant representative. The formula is +// round(kPrime/2^|bits|*x). Note that 2^|bits| being the divisor allows us to +// implement this logic using only bit operations. +static uint16_t decompress(uint16_t x, int bits) { + uint32_t product = (uint32_t)x * kPrime; + uint32_t power = 1 << bits; + // This is |product| % power, since |power| is a power of 2. + uint32_t remainder = product & (power - 1); + // This is |product| / power, since |power| is a power of 2. + uint32_t lower = product >> bits; + // The rounding logic works since the first half of numbers mod |power| have a + // 0 as first bit, and the second half has a 1 as first bit, since |power| is + // a power of 2. As a 12 bit number, |remainder| is always positive, so we + // will shift in 0s for a right shift. + return lower + (remainder >> (bits - 1)); +} + +static void scalar_compress(scalar *s, int bits) { + for (int i = 0; i < DEGREE; i++) { + s->c[i] = compress(s->c[i], bits); + } +} + +static void scalar_decompress(scalar *s, int bits) { + for (int i = 0; i < DEGREE; i++) { + s->c[i] = decompress(s->c[i], bits); + } +} + +static void vector_compress(vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_compress(&a->v[i], bits); + } +} + +static void vector_decompress(vector *a, int bits) { + for (int i = 0; i < RANK; i++) { + scalar_decompress(&a->v[i], bits); + } +} + +struct public_key { + vector t; + uint8_t rho[32]; + uint8_t public_key_hash[32]; + matrix m; +}; + +static struct public_key *public_key_from_external( + const struct KYBER_public_key *external) { + static_assert(sizeof(struct KYBER_public_key) >= sizeof(struct public_key), + "Kyber public key is too small"); + static_assert(alignof(struct KYBER_public_key) >= alignof(struct public_key), + "Kyber public key align incorrect"); + return (struct public_key *)external; +} + +struct private_key { + struct public_key pub; + vector s; + uint8_t fo_failure_secret[32]; +}; + +static struct private_key *private_key_from_external( + const struct KYBER_private_key *external) { + static_assert(sizeof(struct KYBER_private_key) >= sizeof(struct private_key), + "Kyber private key too small"); + static_assert( + alignof(struct KYBER_private_key) >= alignof(struct private_key), + "Kyber private key align incorrect"); + return (struct private_key *)external; +} + +// Calls |KYBER_generate_key_external_entropy| with random bytes from +// |RAND_bytes|. +void KYBER_generate_key(uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key) { + uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]; + RAND_bytes(entropy, sizeof(entropy)); + KYBER_generate_key_external_entropy(out_encoded_public_key, out_private_key, + entropy); +} + +static int kyber_marshal_public_key(CBB *out, const struct public_key *pub) { + uint8_t *vector_output; + if (!CBB_add_space(out, &vector_output, kEncodedVectorSize)) { + return 0; + } + vector_encode(vector_output, &pub->t, kLog2Prime); + if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) { + return 0; + } + return 1; +} + +// Algorithms 4 and 7 of the Kyber spec. Algorithms are combined since key +// generation is not part of the FO transform, and the spec uses Algorithm 7 to +// specify the actual key format. +void KYBER_generate_key_external_entropy( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key, + const uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]) { + struct private_key *priv = private_key_from_external(out_private_key); + uint8_t hashed[64]; + BORINGSSL_keccak(hashed, sizeof(hashed), entropy, 32, boringssl_sha3_512); + const uint8_t *const rho = hashed; + const uint8_t *const sigma = hashed + 32; + OPENSSL_memcpy(priv->pub.rho, hashed, sizeof(priv->pub.rho)); + matrix_expand(&priv->pub.m, rho); + uint8_t counter = 0; + vector_generate_secret_eta_2(&priv->s, &counter, sigma); + vector_ntt(&priv->s); + vector error; + vector_generate_secret_eta_2(&error, &counter, sigma); + vector_ntt(&error); + matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); + vector_add(&priv->pub.t, &error); + + CBB cbb; + CBB_init_fixed(&cbb, out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES); + if (!kyber_marshal_public_key(&cbb, &priv->pub)) { + abort(); + } + + BORINGSSL_keccak(priv->pub.public_key_hash, sizeof(priv->pub.public_key_hash), + out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES, + boringssl_sha3_256); + OPENSSL_memcpy(priv->fo_failure_secret, entropy + 32, 32); +} + +void KYBER_public_from_private(struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key) { + struct public_key *const pub = public_key_from_external(out_public_key); + const struct private_key *const priv = private_key_from_external(private_key); + *pub = priv->pub; +} + +// Algorithm 5 of the Kyber spec. Encrypts a message with given randomness to +// the ciphertext in |out|. Without applying the Fujisaki-Okamoto transform this +// would not result in a CCA secure scheme, since lattice schemes are vulnerable +// to decryption failure oracles. +static void encrypt_cpa(uint8_t out[KYBER_CIPHERTEXT_BYTES], + const struct public_key *pub, const uint8_t message[32], + const uint8_t randomness[32]) { + uint8_t counter = 0; + vector secret; + vector_generate_secret_eta_2(&secret, &counter, randomness); + vector_ntt(&secret); + vector error; + vector_generate_secret_eta_2(&error, &counter, randomness); + uint8_t input[33]; + OPENSSL_memcpy(input, randomness, 32); + input[32] = counter; + scalar scalar_error; + scalar_centered_binomial_distribution_eta_2_with_prf(&scalar_error, input); + vector u; + matrix_mult(&u, &pub->m, &secret); + vector_inverse_ntt(&u); + vector_add(&u, &error); + scalar v; + scalar_inner_product(&v, &pub->t, &secret); + scalar_inverse_ntt(&v); + scalar_add(&v, &scalar_error); + scalar expanded_message; + scalar_decode_1(&expanded_message, message); + scalar_decompress(&expanded_message, 1); + scalar_add(&v, &expanded_message); + vector_compress(&u, kDU); + vector_encode(out, &u, kDU); + scalar_compress(&v, kDV); + scalar_encode(out + kCompressedVectorSize, &v, kDV); +} + +// Calls KYBER_encap_external_entropy| with random bytes from |RAND_bytes| +void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t *out_shared_secret, size_t out_shared_secret_len, + const struct KYBER_public_key *public_key) { + uint8_t entropy[KYBER_ENCAP_ENTROPY]; + RAND_bytes(entropy, KYBER_ENCAP_ENTROPY); + KYBER_encap_external_entropy(out_ciphertext, out_shared_secret, + out_shared_secret_len, public_key, entropy); +} + +// Algorithm 8 of the Kyber spec, safe for line 2 of the spec. The spec there +// hashes the output of the system's random number generator, since the FO +// transform will reveal it to the decrypting party. There is no reason to do +// this when a secure random number generator is used. When an insecure random +// number generator is used, the caller should switch to a secure one before +// calling this method. +void KYBER_encap_external_entropy( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], uint8_t *out_shared_secret, + size_t out_shared_secret_len, const struct KYBER_public_key *public_key, + const uint8_t entropy[KYBER_ENCAP_ENTROPY]) { + const struct public_key *pub = public_key_from_external(public_key); + uint8_t input[64]; + OPENSSL_memcpy(input, entropy, KYBER_ENCAP_ENTROPY); + OPENSSL_memcpy(input + KYBER_ENCAP_ENTROPY, pub->public_key_hash, + sizeof(input) - KYBER_ENCAP_ENTROPY); + uint8_t prekey_and_randomness[64]; + BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness), input, + sizeof(input), boringssl_sha3_512); + encrypt_cpa(out_ciphertext, pub, entropy, prekey_and_randomness + 32); + BORINGSSL_keccak(prekey_and_randomness + 32, 32, out_ciphertext, + KYBER_CIPHERTEXT_BYTES, boringssl_sha3_256); + BORINGSSL_keccak(out_shared_secret, out_shared_secret_len, + prekey_and_randomness, sizeof(prekey_and_randomness), + boringssl_shake256); +} + +// Algorithm 6 of the Kyber spec. +static void decrypt_cpa(uint8_t out[32], const struct private_key *priv, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES]) { + vector u; + vector_decode(&u, ciphertext, kDU); + vector_decompress(&u, kDU); + vector_ntt(&u); + scalar v; + scalar_decode(&v, ciphertext + kCompressedVectorSize, kDV); + scalar_decompress(&v, kDV); + scalar mask; + scalar_inner_product(&mask, &priv->s, &u); + scalar_inverse_ntt(&mask); + scalar_sub(&v, &mask); + scalar_compress(&v, 1); + scalar_encode_1(out, &v); +} + +// Algorithm 9 of the Kyber spec, performing the FO transform by running +// encrypt_cpa on the decrypted message. The spec does not allow the decryption +// failure to be passed on to the caller, and instead returns a result that is +// deterministic but unpredictable to anyone without knowledge of the private +// key. +void KYBER_decap(uint8_t *out_shared_secret, size_t out_shared_secret_len, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key) { + const struct private_key *priv = private_key_from_external(private_key); + uint8_t decrypted[64]; + decrypt_cpa(decrypted, priv, ciphertext); + OPENSSL_memcpy(decrypted + 32, priv->pub.public_key_hash, + sizeof(decrypted) - 32); + uint8_t prekey_and_randomness[64]; + BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness), + decrypted, sizeof(decrypted), boringssl_sha3_512); + uint8_t expected_ciphertext[KYBER_CIPHERTEXT_BYTES]; + encrypt_cpa(expected_ciphertext, &priv->pub, decrypted, + prekey_and_randomness + 32); + uint8_t mask = + constant_time_eq_int_8(CRYPTO_memcmp(ciphertext, expected_ciphertext, + sizeof(expected_ciphertext)), + 0); + uint8_t input[64]; + for (int i = 0; i < 32; i++) { + input[i] = constant_time_select_8(mask, prekey_and_randomness[i], + priv->fo_failure_secret[i]); + } + BORINGSSL_keccak(input + 32, 32, ciphertext, KYBER_CIPHERTEXT_BYTES, + boringssl_sha3_256); + BORINGSSL_keccak(out_shared_secret, out_shared_secret_len, input, + sizeof(input), boringssl_shake256); +} + +int KYBER_marshal_public_key(CBB *out, + const struct KYBER_public_key *public_key) { + return kyber_marshal_public_key(out, public_key_from_external(public_key)); +} + +// kyber_parse_public_key_no_hash parses |in| into |pub| but doesn't calculate +// the value of |pub->public_key_hash|. +static int kyber_parse_public_key_no_hash(struct public_key *pub, CBS *in) { + CBS t_bytes; + if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize) || + !vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime) || + !CBS_copy_bytes(in, pub->rho, sizeof(pub->rho))) { + return 0; + } + matrix_expand(&pub->m, pub->rho); + return 1; +} + +int KYBER_parse_public_key(struct KYBER_public_key *public_key, CBS *in) { + struct public_key *pub = public_key_from_external(public_key); + CBS orig_in = *in; + if (!kyber_parse_public_key_no_hash(pub, in) || // + CBS_len(in) != 0) { + return 0; + } + BORINGSSL_keccak(pub->public_key_hash, sizeof(pub->public_key_hash), + CBS_data(&orig_in), CBS_len(&orig_in), boringssl_sha3_256); + return 1; +} + +int KYBER_marshal_private_key(CBB *out, + const struct KYBER_private_key *private_key) { + const struct private_key *const priv = private_key_from_external(private_key); + uint8_t *s_output; + if (!CBB_add_space(out, &s_output, kEncodedVectorSize)) { + return 0; + } + vector_encode(s_output, &priv->s, kLog2Prime); + if (!kyber_marshal_public_key(out, &priv->pub) || + !CBB_add_bytes(out, priv->pub.public_key_hash, + sizeof(priv->pub.public_key_hash)) || + !CBB_add_bytes(out, priv->fo_failure_secret, + sizeof(priv->fo_failure_secret))) { + return 0; + } + return 1; +} + +int KYBER_parse_private_key(struct KYBER_private_key *out_private_key, + CBS *in) { + struct private_key *const priv = private_key_from_external(out_private_key); + + CBS s_bytes; + if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || + !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || + !kyber_parse_public_key_no_hash(&priv->pub, in) || + !CBS_copy_bytes(in, priv->pub.public_key_hash, + sizeof(priv->pub.public_key_hash)) || + !CBS_copy_bytes(in, priv->fo_failure_secret, + sizeof(priv->fo_failure_secret)) || + CBS_len(in) != 0) { + return 0; + } + return 1; +} diff --git a/third_party/boringssl/kit/src/crypto/kyber/kyber_test.cc b/third_party/boringssl/kit/src/crypto/kyber/kyber_test.cc new file mode 100644 index 00000000..eb76b5bd --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/kyber_test.cc @@ -0,0 +1,229 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include + +#include +#include +#include + +#include "../test/file_test.h" +#include "../test/test_util.h" +#include "./internal.h" + + +static void KeccakFileTest(FileTest *t) { + std::vector input, sha3_256_expected, sha3_512_expected, + shake128_expected, shake256_expected; + ASSERT_TRUE(t->GetBytes(&input, "Input")); + ASSERT_TRUE(t->GetBytes(&sha3_256_expected, "SHA3-256")); + ASSERT_TRUE(t->GetBytes(&sha3_512_expected, "SHA3-512")); + ASSERT_TRUE(t->GetBytes(&shake128_expected, "SHAKE-128")); + ASSERT_TRUE(t->GetBytes(&shake256_expected, "SHAKE-256")); + + uint8_t sha3_256_digest[32]; + BORINGSSL_keccak(sha3_256_digest, sizeof(sha3_256_digest), input.data(), + input.size(), boringssl_sha3_256); + uint8_t sha3_512_digest[64]; + BORINGSSL_keccak(sha3_512_digest, sizeof(sha3_512_digest), input.data(), + input.size(), boringssl_sha3_512); + uint8_t shake128_output[512]; + BORINGSSL_keccak(shake128_output, sizeof(shake128_output), input.data(), + input.size(), boringssl_shake128); + uint8_t shake256_output[512]; + BORINGSSL_keccak(shake256_output, sizeof(shake256_output), input.data(), + input.size(), boringssl_shake256); + + EXPECT_EQ(Bytes(sha3_256_expected), Bytes(sha3_256_digest)); + EXPECT_EQ(Bytes(sha3_512_expected), Bytes(sha3_512_digest)); + EXPECT_EQ(Bytes(shake128_expected), Bytes(shake128_output)); + EXPECT_EQ(Bytes(shake256_expected), Bytes(shake256_output)); + + struct BORINGSSL_keccak_st ctx; + + BORINGSSL_keccak_init(&ctx, input.data(), input.size(), boringssl_shake128); + for (size_t i = 0; i < sizeof(shake128_output); i++) { + BORINGSSL_keccak_squeeze(&ctx, &shake128_output[i], 1); + } + EXPECT_EQ(Bytes(shake128_expected), Bytes(shake128_output)); + + BORINGSSL_keccak_init(&ctx, input.data(), input.size(), boringssl_shake256); + for (size_t i = 0; i < sizeof(shake256_output); i++) { + BORINGSSL_keccak_squeeze(&ctx, &shake256_output[i], 1); + } + EXPECT_EQ(Bytes(shake256_expected), Bytes(shake256_output)); +} + +TEST(KyberTest, KeccakTestVectors) { + FileTestGTest("crypto/kyber/keccak_tests.txt", KeccakFileTest); +} + +template +static std::vector Marshal(int (*marshal_func)(CBB *, const T *), + const T *t) { + bssl::ScopedCBB cbb; + uint8_t *encoded; + size_t encoded_len; + if (!CBB_init(cbb.get(), 1) || // + !marshal_func(cbb.get(), t) || // + !CBB_finish(cbb.get(), &encoded, &encoded_len)) { + abort(); + } + + std::vector ret(encoded, encoded + encoded_len); + OPENSSL_free(encoded); + return ret; +} + +TEST(KyberTest, Basic) { + uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES]; + KYBER_private_key priv; + KYBER_generate_key(encoded_public_key, &priv); + + uint8_t first_two_bytes[2]; + OPENSSL_memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes)); + OPENSSL_memset(encoded_public_key, 0xff, sizeof(first_two_bytes)); + CBS encoded_public_key_cbs; + CBS_init(&encoded_public_key_cbs, encoded_public_key, + sizeof(encoded_public_key)); + KYBER_public_key pub; + // Parsing should fail because the first coefficient is >= kPrime; + ASSERT_FALSE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs)); + + OPENSSL_memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes)); + CBS_init(&encoded_public_key_cbs, encoded_public_key, + sizeof(encoded_public_key)); + ASSERT_TRUE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs)); + EXPECT_EQ(CBS_len(&encoded_public_key_cbs), 0u); + + EXPECT_EQ(Bytes(encoded_public_key), + Bytes(Marshal(KYBER_marshal_public_key, &pub))); + + KYBER_public_key pub2; + KYBER_public_from_private(&pub2, &priv); + EXPECT_EQ(Bytes(encoded_public_key), + Bytes(Marshal(KYBER_marshal_public_key, &pub2))); + + std::vector encoded_private_key( + Marshal(KYBER_marshal_private_key, &priv)); + EXPECT_EQ(encoded_private_key.size(), size_t{KYBER_PRIVATE_KEY_BYTES}); + + OPENSSL_memcpy(first_two_bytes, encoded_private_key.data(), + sizeof(first_two_bytes)); + OPENSSL_memset(encoded_private_key.data(), 0xff, sizeof(first_two_bytes)); + CBS cbs; + CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size()); + KYBER_private_key priv2; + // Parsing should fail because the first coefficient is >= kPrime. + ASSERT_FALSE(KYBER_parse_private_key(&priv2, &cbs)); + + OPENSSL_memcpy(encoded_private_key.data(), first_two_bytes, + sizeof(first_two_bytes)); + CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size()); + ASSERT_TRUE(KYBER_parse_private_key(&priv2, &cbs)); + EXPECT_EQ(Bytes(encoded_private_key), + Bytes(Marshal(KYBER_marshal_private_key, &priv2))); + + uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES]; + uint8_t shared_secret1[64]; + uint8_t shared_secret2[sizeof(shared_secret1)]; + KYBER_encap(ciphertext, shared_secret1, sizeof(shared_secret1), &pub); + KYBER_decap(shared_secret2, sizeof(shared_secret2), ciphertext, &priv); + EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2)); + KYBER_decap(shared_secret2, sizeof(shared_secret2), ciphertext, &priv2); + EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2)); +} + +static void KyberFileTest(FileTest *t) { + std::vector seed, public_key_expected, private_key_expected, + ciphertext_expected, shared_secret_expected, given_generate_entropy, + given_encap_entropy_pre_hash; + t->IgnoreAttribute("count"); + ASSERT_TRUE(t->GetBytes(&seed, "seed")); + ASSERT_TRUE(t->GetBytes(&public_key_expected, "pk")); + ASSERT_TRUE(t->GetBytes(&private_key_expected, "sk")); + ASSERT_TRUE(t->GetBytes(&ciphertext_expected, "ct")); + ASSERT_TRUE(t->GetBytes(&shared_secret_expected, "ss")); + ASSERT_TRUE(t->GetBytes(&given_generate_entropy, "generateEntropy")); + ASSERT_TRUE( + t->GetBytes(&given_encap_entropy_pre_hash, "encapEntropyPreHash")); + + KYBER_private_key priv; + uint8_t encoded_private_key[KYBER_PRIVATE_KEY_BYTES]; + KYBER_public_key pub; + uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES]; + uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES]; + uint8_t gen_key_entropy[KYBER_GENERATE_KEY_ENTROPY]; + uint8_t encap_entropy[KYBER_ENCAP_ENTROPY]; + uint8_t encapsulated_key[32]; + uint8_t decapsulated_key[32]; + // The test vectors provide a CTR-DRBG seed which is used to generate the + // input entropy. + ASSERT_EQ(seed.size(), size_t{CTR_DRBG_ENTROPY_LEN}); + { + bssl::UniquePtr state( + CTR_DRBG_new(seed.data(), nullptr, 0)); + ASSERT_TRUE(state); + ASSERT_TRUE( + CTR_DRBG_generate(state.get(), gen_key_entropy, 32, nullptr, 0)); + ASSERT_TRUE( + CTR_DRBG_generate(state.get(), gen_key_entropy + 32, 32, nullptr, 0)); + ASSERT_TRUE(CTR_DRBG_generate(state.get(), encap_entropy, + KYBER_ENCAP_ENTROPY, nullptr, 0)); + } + + EXPECT_EQ(Bytes(gen_key_entropy), Bytes(given_generate_entropy)); + EXPECT_EQ(Bytes(encap_entropy), Bytes(given_encap_entropy_pre_hash)); + + BORINGSSL_keccak(encap_entropy, sizeof(encap_entropy), encap_entropy, + sizeof(encap_entropy), boringssl_sha3_256); + + KYBER_generate_key_external_entropy(encoded_public_key, &priv, + gen_key_entropy); + CBB cbb; + CBB_init_fixed(&cbb, encoded_private_key, sizeof(encoded_private_key)); + ASSERT_TRUE(KYBER_marshal_private_key(&cbb, &priv)); + CBS encoded_public_key_cbs; + CBS_init(&encoded_public_key_cbs, encoded_public_key, + sizeof(encoded_public_key)); + ASSERT_TRUE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs)); + KYBER_encap_external_entropy(ciphertext, encapsulated_key, + sizeof(encapsulated_key), &pub, encap_entropy); + KYBER_decap(decapsulated_key, sizeof(decapsulated_key), ciphertext, &priv); + + EXPECT_EQ(Bytes(encapsulated_key), Bytes(decapsulated_key)); + EXPECT_EQ(Bytes(private_key_expected), Bytes(encoded_private_key)); + EXPECT_EQ(Bytes(public_key_expected), Bytes(encoded_public_key)); + EXPECT_EQ(Bytes(ciphertext_expected), Bytes(ciphertext)); + EXPECT_EQ(Bytes(shared_secret_expected), Bytes(encapsulated_key)); + + uint8_t corrupted_ciphertext[KYBER_CIPHERTEXT_BYTES]; + OPENSSL_memcpy(corrupted_ciphertext, ciphertext, KYBER_CIPHERTEXT_BYTES); + corrupted_ciphertext[3] ^= 0x40; + uint8_t corrupted_decapsulated_key[32]; + KYBER_decap(corrupted_decapsulated_key, sizeof(corrupted_decapsulated_key), + corrupted_ciphertext, &priv); + // It would be nice to have actual test vectors for the failure case, but the + // NIST submission currently does not include those, so we are just testing + // for inequality. + EXPECT_NE(Bytes(encapsulated_key), Bytes(corrupted_decapsulated_key)); +} + +TEST(KyberTest, TestVectors) { + FileTestGTest("crypto/kyber/kyber_tests.txt", KyberFileTest); +} diff --git a/third_party/boringssl/kit/src/crypto/kyber/kyber_tests.txt b/third_party/boringssl/kit/src/crypto/kyber/kyber_tests.txt new file mode 100644 index 00000000..486b163e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/kyber/kyber_tests.txt @@ -0,0 +1,905 @@ +# Kyber768 +# From the NIST round three submission package. +# +# https://pq-crystals.org/kyber/data/kyber-submission-nist-round3.zip +# NIST-PQ-Submission-Kyber-20201001/KAT/kyber768/PQCkemKAT_2400.rsp + +count = 0 +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +generateEntropy = 7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +encapEntropyPreHash = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +pk = A72C2D9C843EE9F8313ECC7F86D6294D59159D9A879A542E260922ADF999051CC45200C9FFDB60449C49465979272367C083A7D6267A3ED7A7FD47957C219327F7CA73A4007E1627F00B11CC80573C15AEE6640FB8562DFA6B240CA0AD351AC4AC155B96C14C8AB13DD262CDFD51C4BB5572FD616553D17BDD430ACBEA3E95F0B698D66990AB51E5D03783A8B3D278A5720454CF9695CFDCA08485BA099C51CD92A7EA7587C1D15C28E609A81852601B0604010679AA482D51261EC36E36B8719676217FD74C54786488F4B4969C05A8BA27CA3A77CCE73B965923CA554E422B9B61F4754641608AC16C9B8587A32C1C5DD788F88B36B717A46965635DEB67F45B129B99070909C93EB80B42C2B3F3F70343A7CF37E8520E7BCFC416ACA4F18C7981262BA2BFC756AE03278F0EC66DC2057696824BA6769865A601D7148EF6F54E5AF5686AA2906F994CE38A5E0B938F239007003022C03392DF3401B1E4A3A7EBC6161449F73374C8B0140369343D9295FDF511845C4A46EBAAB6CA5492F6800B98C0CC803653A4B1D6E6AAED1932BACC5FEFAA818BA502859BA5494C5F5402C8536A9C4C1888150617F80098F6B2A99C39BC5DC7CF3B5900A21329AB59053ABAA64ED163E859A8B3B3CA3359B750CCC3E710C7AC43C8191CB5D68870C06391C0CB8AEC72B897AC6BE7FBAACC676ED66314C83630E89448C88A1DF04ACEB23ABF2E409EF333C622289C18A2134E650C45257E47475FA33AA537A5A8F7680214716C50D470E3284963CA64F54677AEC54B5272162BF52BC8142E1D4183FC017454A6B5A496831759064024745978CBD51A6CEDC8955DE4CC6D363670A47466E82BE5C23603A17BF22ACDB7CC984AF08C87E14E27753CF587A8EC3447E62C649E887A67C36C9CE98721B697213275646B194F36758673A8ED11284455AFC7A8529F69C97A3C2D7B8C636C0BA55614B768E624E712930F776169B01715725351BC74B47395ED52B25A1313C95164814C34C979CBDFAB85954662CAB485E75087A98CC74BB82CA2D1B5BF2803238480638C40E90B43C7460E7AA917F010151FAB1169987B372ABB59271F7006C24E60236B84B9DDD600623704254617FB498D89E58B0368BCB2103E79353EB587860C1422E476162E425BC2381DB82C6592737E1DD602864B0167A71EC1F223305C02FE25052AF2B3B5A55A0D7A2022D9A798DC0C5874A98702AAF4054C5D80338A5248B5B7BD09C53B5E2A084B047D277A861B1A73BB51488DE04EF573C85230A0470B73175C9FA50594F66A5F50B4150054C93B68186F8B5CBC49316C8548A642B2B36A1D454C7489AC33B2D2CE6668096782A2C1E0866D21A65E16B585E7AF8618BDF3184C1986878508917277B93E10706B1614972B2A94C7310FE9C708C231A1A8AC8D9314A529A97F469BF64962D820648443099A076D55D4CEA824A58304844F99497C10A25148618A315D72CA857D1B04D575B94F85C01D19BEF211BF0AA3362E7041FD16596D808E867B44C4C00D1CDA3418967717F147D0EB21B42AAEE74AC35D0B92414B958531AADF463EC6305AE5ECAF79174002F26DDECC813BF32672E8529D95A4E730A7AB4A3E8F8A8AF979A665EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922 +sk = 07638FB69868F3D320E5862BD96933FEB311B362093C9B5D50170BCED43F1B536D9A204BB1F22695950BA1F2A9E8EB828B284488760B3FC84FABA04275D5628E39C5B2471374283C503299C0AB49B66B8BBB56A4186624F919A2BA59BB08D8551880C2BEFC4F87F25F59AB587A79C327D792D54C974A69262FF8A78938289E9A87B688B083E0595FE218B6BB1505941CE2E81A5A64C5AAC60417256985349EE47A52420A5F97477B7236AC76BC70E8288729287EE3E34A3DBC3683C0B7B10029FC203418537E7466BA6385A8FF301EE12708F82AAA1E380FC7A88F8F205AB7E88D7E95952A55BA20D09B79A47141D62BF6EB7DD307B08ECA13A5BC5F6B68581C6865B27BBCDDAB142F4B2CBFF488C8A22705FAA98A2B9EEA3530C76662335CC7EA3A00777725EBCCCD2A4636B2D9122FF3AB77123CE0883C1911115E50C9E8A94194E48DD0D09CFFB3ADCD2C1E92430903D07ADBF00532031575AA7F9E7B5A1F3362DEC936D4043C05F2476C07578BC9CBAF2AB4E382727AD41686A96B2548820BB03B32F11B2811AD62F489E951632ABA0D1DF89680CC8A8B53B481D92A68D70B4EA1C3A6A561C0692882B5CA8CC942A8D495AFCB06DE89498FB935B775908FE7A03E324D54CC19D4E1AABD3593B38B19EE1388FE492B43127E5A504253786A0D69AD32601C28E2C88504A5BA599706023A61363E17C6B9BB59BDC697452CD059451983D738CA3FD034E3F5988854CA05031DB09611498988197C6B30D258DFE26265541C89A4B31D6864E9389B03CB74F7EC4323FB9421A4B9790A26D17B0398A26767350909F84D57B6694DF830664CA8B3C3C03ED2AE67B89006868A68527CCD666459AB7F056671000C6164D3A7F266A14D97CBD7004D6C92CACA770B844A4FA9B182E7B18CA885082AC5646FCB4A14E1685FEB0C9CE3372AB95365C04FD83084F80A23FF10A05BF15F7FA5ACC6C0CB462C33CA524FA6B8BB359043BA68609EAA2536E81D08463B19653B5435BA946C9ADDEB202B04B031CC960DCC12E4518D428B32B257A4FC7313D3A7980D80082E934F9D95C32B0A0191A23604384DD9E079BBBAA266D14C3F756B9F2133107433A4E83FA7187282A809203A4FAF841851833D121AC383843A5E55BC2381425E16C7DB4CC9AB5C1B0D91A47E2B8DE0E582C86B6B0D907BB360B97F40AB5D038F6B75C814B27D9B968D419832BC8C2BEE605EF6E5059D33100D90485D378450014221736C07407CAC260408AA64926619788B8601C2A752D1A6CBF820D7C7A04716203225B3895B9342D147A8185CFC1BB65BA06B4142339903C0AC4651385B45D98A8B19D28CD6BAB088787F7EE1B12461766B43CBCCB96434427D93C065550688F6948ED1B5475A425F1B85209D061C08B56C1CC069F6C0A7C6F29358CAB911087732A649D27C9B98F9A48879387D9B00C25959A71654D6F6A946164513E47A75D005986C2363C09F6B537ECA78B9303A5FA457608A586A653A347DB04DFCC19175B3A301172536062A658A95277570C8852CA8973F4AE123A334047DD711C8927A634A03388A527B034BF7A8170FA702C1F7C23EC32D18A2374890BE9C787A9409C82D192C4BB705A2F996CE405DA72C2D9C843EE9F8313ECC7F86D6294D59159D9A879A542E260922ADF999051CC45200C9FFDB60449C49465979272367C083A7D6267A3ED7A7FD47957C219327F7CA73A4007E1627F00B11CC80573C15AEE6640FB8562DFA6B240CA0AD351AC4AC155B96C14C8AB13DD262CDFD51C4BB5572FD616553D17BDD430ACBEA3E95F0B698D66990AB51E5D03783A8B3D278A5720454CF9695CFDCA08485BA099C51CD92A7EA7587C1D15C28E609A81852601B0604010679AA482D51261EC36E36B8719676217FD74C54786488F4B4969C05A8BA27CA3A77CCE73B965923CA554E422B9B61F4754641608AC16C9B8587A32C1C5DD788F88B36B717A46965635DEB67F45B129B99070909C93EB80B42C2B3F3F70343A7CF37E8520E7BCFC416ACA4F18C7981262BA2BFC756AE03278F0EC66DC2057696824BA6769865A601D7148EF6F54E5AF5686AA2906F994CE38A5E0B938F239007003022C03392DF3401B1E4A3A7EBC6161449F73374C8B0140369343D9295FDF511845C4A46EBAAB6CA5492F6800B98C0CC803653A4B1D6E6AAED1932BACC5FEFAA818BA502859BA5494C5F5402C8536A9C4C1888150617F80098F6B2A99C39BC5DC7CF3B5900A21329AB59053ABAA64ED163E859A8B3B3CA3359B750CCC3E710C7AC43C8191CB5D68870C06391C0CB8AEC72B897AC6BE7FBAACC676ED66314C83630E89448C88A1DF04ACEB23ABF2E409EF333C622289C18A2134E650C45257E47475FA33AA537A5A8F7680214716C50D470E3284963CA64F54677AEC54B5272162BF52BC8142E1D4183FC017454A6B5A496831759064024745978CBD51A6CEDC8955DE4CC6D363670A47466E82BE5C23603A17BF22ACDB7CC984AF08C87E14E27753CF587A8EC3447E62C649E887A67C36C9CE98721B697213275646B194F36758673A8ED11284455AFC7A8529F69C97A3C2D7B8C636C0BA55614B768E624E712930F776169B01715725351BC74B47395ED52B25A1313C95164814C34C979CBDFAB85954662CAB485E75087A98CC74BB82CA2D1B5BF2803238480638C40E90B43C7460E7AA917F010151FAB1169987B372ABB59271F7006C24E60236B84B9DDD600623704254617FB498D89E58B0368BCB2103E79353EB587860C1422E476162E425BC2381DB82C6592737E1DD602864B0167A71EC1F223305C02FE25052AF2B3B5A55A0D7A2022D9A798DC0C5874A98702AAF4054C5D80338A5248B5B7BD09C53B5E2A084B047D277A861B1A73BB51488DE04EF573C85230A0470B73175C9FA50594F66A5F50B4150054C93B68186F8B5CBC49316C8548A642B2B36A1D454C7489AC33B2D2CE6668096782A2C1E0866D21A65E16B585E7AF8618BDF3184C1986878508917277B93E10706B1614972B2A94C7310FE9C708C231A1A8AC8D9314A529A97F469BF64962D820648443099A076D55D4CEA824A58304844F99497C10A25148618A315D72CA857D1B04D575B94F85C01D19BEF211BF0AA3362E7041FD16596D808E867B44C4C00D1CDA3418967717F147D0EB21B42AAEE74AC35D0B92414B958531AADF463EC6305AE5ECAF79174002F26DDECC813BF32672E8529D95A4E730A7AB4A3E8F8A8AF979A665EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922D4EC143B50F01423B177895EDEE22BB739F647ECF85F50BC25EF7B5A725DEE868626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F +ct = B52C56B92A4B7CE9E4CB7C5B1B163167A8A1675B2FDEF84A5B67CA15DB694C9F11BD027C30AE22EC921A1D911599AF0585E48D20DA70DF9F39E32EF95D4C8F44BFEFDAA5DA64F1054631D04D6D3CFD0A540DD7BA3886E4B5F13E878788604C95C096EAB3919F427521419A946C26CC041475D7124CDC01D0373E5B09C7A70603CFDB4FB3405023F2264DC3F983C4FC02A2D1B268F2208A1F6E2A6209BFF12F6F465F0B069C3A7F84F606D8A94064003D6EC114C8E808D3053884C1D5A142FBF20112EB360FDA3F0F28B172AE50F5E7D83801FB3F0064B687187074BD7FE30EDDAA334CF8FC04FA8CED899CEADE4B4F28B68372BAF98FF482A415B731155B75CEB976BE0EA0285BA01A27F1857A8FB377A3AE0C23B2AA9A079BFABFF0D5B2F1CD9B718BEA03C42F343A39B4F142D01AD8ACBB50E38853CF9A50C8B44C3CF671A4A9043B26DDBB24959AD6715C08521855C79A23B9C3D6471749C40725BDD5C2776D43AED20204BAA141EFB3304917474B7F9F7A4B08B1A93DAED98C67495359D37D67F7438BEE5E43585634B26C6B3810D7CDCBC0F6EB877A6087E68ACB8480D3A8CF6900447E49B417F15A53B607A0E216B855970D37406870B4568722DA77A4084703816784E2F16BED18996532C5D8B7F5D214464E5F3F6E905867B0CE119E252A66713253544685D208E1723908A0CE97834652E08AE7BDC881A131B73C71E84D20D68FDEFF4F5D70CD1AF57B78E3491A9865942321800A203C05ED1FEEB5A28E584E19F6535E7F84E4A24F84A72DCAF5648B4A4235DD664464482F03176E888C28BFC6C1CB238CFFA35A321E71791D9EA8ED0878C61121BF8D2A4AB2C1A5E120BC40ABB1892D1715090A0EE48252CA297A99AA0E510CF26B1ADD06CA543E1C5D6BDCD3B9C585C8538045DB5C252EC3C8C3C954D9BE5907094A894E60EAB43538CFEE82E8FFC0791B0D0F43AC1627830A61D56DAD96C62958B0DE780B78BD47A604550DAB83FFF227C324049471F35248CFB849B25724FF704D5277AA352D550958BE3B237DFF473EC2ADBAEA48CA2658AEFCC77BBD4264AB374D70EAE5B964416CE8226A7E3255A0F8D7E2ADCA062BCD6D78D60D1B32E11405BE54B66EF0FDDD567702A3BCCFEDE3C584701269ED14809F06F8968356BB9267FE86E514252E88BB5C30A7ECB3D0E621021EE0FBF7871B09342BF84F55C97EAF86C48189C7FF4DF389F077E2806E5FA73B3E9458A16C7E275F4F602275580EB7B7135FB537FA0CD95D6EA58C108CD8943D70C1643111F4F01CA8A8276A902666ED81B78D168B006F16AAA3D8E4CE4F4D0FB0997E41AEFFB5B3DAA838732F357349447F387776C793C0479DE9E99498CC356FDB0075A703F23C55D47B550EC89B02ADE89329086A50843456FEDC3788AC8D97233C54560467EE1D0F024B18428F0D73B30E19F5C63B9ABF11415BEA4D0170130BAABD33C05E6524E5FB5581B22B0433342248266D0F1053B245CC2462DC44D34965102482A8ED9E4E964D5683E5D45D0C8269 +ss = 914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29 + +count = 1 +seed = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F +generateEntropy = d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +encapEntropyPreHash = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +pk = 6DD406B49B9CA035467FD26C6C0B824BEA310F435FBE8BBBD3430B5C39889E6B117E994E2F08823A33789FF858B72715323C6204A241D9835EC0DA85C5884A8A96210219099C8C383C182632280356C1B4F298405258A170E81624E861FC1082D31867A9037E3B90B0AEEAA064D27020DA7BA79398FA92A963A8A294E7720BD4CD9EA213F08063079C4D55B094BEBC4E979444F462B967972E61206FCC80337911B02C7396BC64405FFC0B77CCCD2EBC121A734037CB90B77846B2359C30A451BEB20A6D72C238284E5DF2AD1CC1A33FD5A104965C86251A596360D541240A4828231A827A0168B6D8AC7E27328173886453A9C91498765C2BD9EA9F666BB4A1D60F992538A1A746DF845574F99ADAD23B9744AFA81C7FB79A32B175706454438F46B8985132B8E1CCA10C2B0FA011EAB2428B88CFEF9378A5228E55D7463DFA5022C998ABD6354118B5116B3BC1004F0008134B85A1CF2A9F409A10E14B6D06C26D8E355864C35BC71B60D5CAC33A513EFDF6B9BB83BC880983682C8FB8A81B6927CA52E93835956795488181A8CD82B1A50DD18A25F35E2643CDD76C282E7018BB99624F031418FBC8052C4179B43A5998BE9A20CD2D8A883B313EC282598202ADD6471971C88CD9607D3A8052519930BC5BC71CA4652352B4D02620B8D983B9849CE8B8935F1A4DECC3250DE7B0CFCB49EB7B74E0B5792AE97633B092081C3C6BF58F1B242CA07610C3387098AC3F0F9043901C614590C4EBBC64CE1971E824694A999CBCC430AE923A1432B6A4911162213C429481394A27006B9D48C0AB5801823D756BFD8C6919502D613594AEC81F5669BD4E8495292606959292467CCAC7F688333B3F48A39FCE5C42C9C2653886A5ADF4747CC943B2416348F46DF5B58E4916BA64E9664A4BAAA3E0A9652408C8E5076C226C3A7932C42A846949A2A26B4E2C452F86CACFE5C201AE1321AB5C2CABDA557648A849241F077A799EDBA3582202CB27763047219F5546CF18819322B9C63974B322B949BAA491D97C70F20545886C87086721D3CA2AEAB441264B516975ED0C6044A425853528424532E4D721E85CB0BF65C26082C790765B062916FAC4A0DCECBC2E900C6F600270838E2DF20EE0A907E3613DCEE049C445640362C980A292F123C6C9B5918F21443C996016C44D2A124C5925A8E0C48E89BB167A129FCBF67ADB89903E1249F6028BC176BACC722366139858E583EB582ADA714E79B5AD1BC1A6F18754E100624620968D0702E080BEFEC425BC16B650A307802004C57590897C87E65347F32C324569051D798BEBDB421EB28B2D1A0C662444C7DB32BF97845D7225C7539F457894EB87606FA85B5E804053FB6ECDEA773566C006E540EE65101D99BF314181D666680985C78B103DD00A040DC69CFF389FEA7C18E48A363B943FF042B476DC86BE953A5925076CF749A62A77A9406165D31DACDC3A677B9114D8BF84B43F59F647FA4023535140FDE04285921184809C5F193A7DF45F62187854061A4D6754DA528F3B71A134AA487D9B5F7CFC6838108B8B95B51F5540C9EA5F29990F7BE07EFD502461033F103723093A16DD96C098977F81330249183CF35A636841BD1A9B9796F13F56BE785D942D7EAB011805CF3504FCE325B6A5EF1AAADBBB11C662B9D2 +sk = 94B49EA42526935245C45A7D580B6AEFF8BBE0F5342BB8BD2550212AD5935F45CBA7CAA6DF914007FBA79E9946C9433A86A2C4202BBDCEA008AF78975E6619D3582787530DBB7318A530B7B5A27D24258C7CCAAAF505CA92CB853A5818D4269BE812BECF169A05E71EB957557787C2F3B72315281DBA87476B157A06095A30D52B388AC22840755B43440A931DF8A709DC435B415A7BABBB04CCD93CDA00CA1FB090646B1D6514813368A794D38C907163B5917496B018C519B160C5144D6424495626E3A5AB9FFB8D8D3168D77599A88A1D12C07D86498D88DC1AF7FA7DE15073FD4B62801C1A902B215E7CC3EAC350BB63ADEAF9C7594844795A9A6274AA3ECA0CD10891F05795A77B30ADD76B6B1A35338B8156690CA2EA1C9C3B602B23324925314F726535B36DFB355225D37E7C85BE15A5976A8A6AD4E2C35D4C45ACC954368BA6DF88A47DBB8C782336F7EA507A6C2D26D952DC03B4BFB89872644084783AB493CD72D3BEFC2C803B692729638AF69B03E6DB9B82E678A42969FBE770FEF65723F77DA6437C20B203601C884A9B9E08C0B1DDBBC1A66517DCFC76B3F125F7795E5DDABEF0CB00119778575513E05AC38A7901A0E8C8794685C0F274050097BC50168818A74ABA5D71980F5C76279EC0214CD51EFA8A21391567FA052E6DC0CF9BF216CFF9287C80693645A53D71B3D7509F6A432D51B2B0AAD129B594278DA74FFACBB713357D735A744B7C65E482B7E172C67A5B4EDABAAE11222B8BB6B4564AB4FB20C28B4981614B69BB188DB6056607E089F64803D89210C7E604266B00548A2AE27996196A6D6F762C27B22731F7942543CCEF3856EDF9AD1B1B1652A33C3E038DD9B2CD9A4612CE174315E67B26DAC767E50E68508D104BBAE1A2B89B78266D27B109F90BCE1581A8B8888C90C1C4EA5FC1F009D5073780CB4545087C88026B9B9ABDDAB923DB52620713C8B5AC3301E8715AC39D13084926E841FAE41A7BBB7912E10680A78C0C363A251720B2D69467B6CAC5D894F862595072A7C9B14BFEFAA2FDCC75CC42892CEC6184B52962B9B73D663B7D76C1EA499D538BB45A4CAECEE0C8EB93BBA5EC1A8C936156382B10102E3211B2DC15663412805F60590EC33DBAB80D2A3BC05FA8AF5145644F712E004C20F799650159C40DC952C9A54C27E816C3A6A95EFBAB24A31F6C402300F9BAF88A46644B4DF8A24979E80DC30425B9E75A753A36510B87C5FA95CBF36E19A12245876003B54D4E008EF7AB9D83C5A2406014B5CC33B6167F4C452AF45084B7412EC19556D82B0A6A90C1AEA60A72312D8A7A8E5060189717094FF950AF2B503988964F0AA227C523487471D3BC905B6672BE20BC714729B7A71478B07A19F777DEC546C624723AF7B5F6C142274AC5652A7C2D7ABBF1171F2BDB12F1ECC876681A600806D6FC229E6A8F6424419187BD22E49B8F27486DB25371C169B3F61E81131B57659B1030A959790BA5D6424580B1F588326DB9CD01A260B21B8C42062B883854FB173EA7613764D41DD6B89468C7BA6C4236D1A0436B945B8B340983023139293FC48C07659B955453BBA07B0EB4E2A91F594232A47C65C66E1C5C8279F179925C55EE3A0B6DD406B49B9CA035467FD26C6C0B824BEA310F435FBE8BBBD3430B5C39889E6B117E994E2F08823A33789FF858B72715323C6204A241D9835EC0DA85C5884A8A96210219099C8C383C182632280356C1B4F298405258A170E81624E861FC1082D31867A9037E3B90B0AEEAA064D27020DA7BA79398FA92A963A8A294E7720BD4CD9EA213F08063079C4D55B094BEBC4E979444F462B967972E61206FCC80337911B02C7396BC64405FFC0B77CCCD2EBC121A734037CB90B77846B2359C30A451BEB20A6D72C238284E5DF2AD1CC1A33FD5A104965C86251A596360D541240A4828231A827A0168B6D8AC7E27328173886453A9C91498765C2BD9EA9F666BB4A1D60F992538A1A746DF845574F99ADAD23B9744AFA81C7FB79A32B175706454438F46B8985132B8E1CCA10C2B0FA011EAB2428B88CFEF9378A5228E55D7463DFA5022C998ABD6354118B5116B3BC1004F0008134B85A1CF2A9F409A10E14B6D06C26D8E355864C35BC71B60D5CAC33A513EFDF6B9BB83BC880983682C8FB8A81B6927CA52E93835956795488181A8CD82B1A50DD18A25F35E2643CDD76C282E7018BB99624F031418FBC8052C4179B43A5998BE9A20CD2D8A883B313EC282598202ADD6471971C88CD9607D3A8052519930BC5BC71CA4652352B4D02620B8D983B9849CE8B8935F1A4DECC3250DE7B0CFCB49EB7B74E0B5792AE97633B092081C3C6BF58F1B242CA07610C3387098AC3F0F9043901C614590C4EBBC64CE1971E824694A999CBCC430AE923A1432B6A4911162213C429481394A27006B9D48C0AB5801823D756BFD8C6919502D613594AEC81F5669BD4E8495292606959292467CCAC7F688333B3F48A39FCE5C42C9C2653886A5ADF4747CC943B2416348F46DF5B58E4916BA64E9664A4BAAA3E0A9652408C8E5076C226C3A7932C42A846949A2A26B4E2C452F86CACFE5C201AE1321AB5C2CABDA557648A849241F077A799EDBA3582202CB27763047219F5546CF18819322B9C63974B322B949BAA491D97C70F20545886C87086721D3CA2AEAB441264B516975ED0C6044A425853528424532E4D721E85CB0BF65C26082C790765B062916FAC4A0DCECBC2E900C6F600270838E2DF20EE0A907E3613DCEE049C445640362C980A292F123C6C9B5918F21443C996016C44D2A124C5925A8E0C48E89BB167A129FCBF67ADB89903E1249F6028BC176BACC722366139858E583EB582ADA714E79B5AD1BC1A6F18754E100624620968D0702E080BEFEC425BC16B650A307802004C57590897C87E65347F32C324569051D798BEBDB421EB28B2D1A0C662444C7DB32BF97845D7225C7539F457894EB87606FA85B5E804053FB6ECDEA773566C006E540EE65101D99BF314181D666680985C78B103DD00A040DC69CFF389FEA7C18E48A363B943FF042B476DC86BE953A5925076CF749A62A77A9406165D31DACDC3A677B9114D8BF84B43F59F647FA4023535140FDE04285921184809C5F193A7DF45F62187854061A4D6754DA528F3B71A134AA487D9B5F7CFC6838108B8B95B51F5540C9EA5F29990F7BE07EFD502461033F103723093A16DD96C098977F81330249183CF35A636841BD1A9B9796F13F56BE785D942D7EAB011805CF3504FCE325B6A5EF1AAADBBB11C662B9D22CEDAD700B675E98641BEA57B936BD8BEFCE2D5161E0EF4EF8406E70F1E2C27C003271531CF27285B8721ED5CB46853043B346A66CBA6CF765F1B0EAA40BF672 +ct = 68F11F4A8D07DBA08EAD094A93BF00141CED64E2CB3E68A59987CA3298E259ACEBB820650F861C6AF5FA565920825AE4A61A5395CEA7DDC6806E7D15D42635C8177E17A9B7110118C3FBCED5B2A73EA79B86D5B41D92C14C0302B6B1B9DB25CC2F923B32CCAA054C7B07E58EA2ECFE4F0B17C97E4E5571E04ABF67468B6DF3B64AA545B7E348E45DFB18BD186C7A17C7A3EC326E65BF7BB025D7D23B14F733698FDB79CA9CFDB85AD40F35170D98289DA8190F50A25FAC16043377736664411767C28978664444A2DA6F630D0FA54230F0DA6CCD158C5986921A356A3BF528C996A767A44FF765967A06773C4F392CE9209CBA2CE05DC63A43D1AE40C2E86DAA0F56237962B058E0D40DCE5EFF7AA165B6A9D1DFAC0D19BBC0A94466EC53DD1E28A8B01722E28C761E8AC0B97ADE7CAA0447465C40A54BA799F8A011EC1BB0E7DA7D4362215F5FAB54373791102FBCB77480A805008A5E89E6A74B15257B38BFD906841A841A475F47720AD19F34409ED6BD37C2BCD7DE06E4E04181116D0BB2050F9C60F635FEE337DCCAAEB870BA7494CB2CA590570720DE061BDD6B522EB09313EBB927BFFC920E649D98E5A4A86C2C5E3815E777F302802D98B6C616E6FCB784A16D6BF8C8AAE9BA44EC43DE816084C4C3BB1B02A603680A64FF1AB5CD8AF48774C5B5057D6682CFF3E265A63E551A20633DBF5BFEDAE646CCB99E872274C71BD61E1A518E8A2657B1FFB37701BA26B1AA36B109D75E399AF0F07D321A8E839812E6CF8EA29E95CBA3E6737F6F2113D8990ED939F86082CF5A3877144A8EF89FB5C0FD726A88DA00E986782C53D313212A9A2D20D012794E9A89866367C10EDE99EB8B03F30C376B50E7009A51F2F44082DBB62C4AC91F53399838BFBFF7ABB851C969E9003AF3FEFD138D7C5C4862F524FD97F95F9E6B5CF8CE949F748239F6DFF3535D24BB704EDF896AA06515DCA4FE776B987FE7C742CBB2DE50CDA6A2BC99455CF741F58B094BB832F2B645112F11050E1A8CB2F770709ED3D58A284012C9084CE6DE8372246CF4B4861D2E43516483E7B66F6EAB1A6AC61EA0B85F7103D9FDDA34AF13C5674ADB690EECE71CB7EDE7B02CEFDC8B052F2C8905D60D57B58576C8E9CEE41D00B7C51F8A97237716617CFC3D554D56EB2AAEB13E018C334B6D0D7A68B3294D475B910E860F17E9BAAAF7FC85FFACB18BCCA3230507AFB91620061F2FF221EA8614BFE77E64838411D7988745BF103D37F93D3E48C9B93577F1B709D58F386D110979B954B41095D58CC25E8343B1CC03C5A103B39433C844154CA9D0EF7D5E8004A44F4500BD06481DC6B8073085657AE915A3322E6CD27016B1091BA8D78EFBC32C70CCBFB8E63827D5D875302006A4554F6655D9C2104189733BF3FC5388B978304A23248D24FBCEE7BBCC9501479AA0BC19DD5C4FA6580993F4EDF4438CC7EECCD8622231C4925BE40E9FF57DAE6617BDCA8E964AAD894267DE70B45C414280F643F6F23ACC9D142CDDE71F624D69238D45B5FE54 +ss = FE8AAA6558FD8087DD7CAB54B4BCE50FC625A369ECACE58B2EC36F3BC5BB4F5A + +count = 2 +seed = 64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868 +generateEntropy = 4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +encapEntropyPreHash = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +pk = F5A35B4EC7538B62289DD1204DB91AC492B610538C93EB5F2637AD97DC88F0035FF3CB735CEBAC9BE7CA78A4149CF10B6D93283050167E737596B711A9F32A0F6909975055CE6632F4B42CF9A2361CF69047B5BDE1868DD745A82CF473EBB30D86A71793364F70B1255B1C2003F166683C936A7977DF156A84051E69B95E02616DD3090DD38086EF3BC12353BAD25377618965C2810FCA929DFBF46F20360FC847818CF90DBC044EED16B3B9052C5C70A5A430441E53A5527A689F49B35CE82B84D6057C5269FB60C710C5731F431A970B86431125910277FA7C310A2285117B47B95054E4174A1EB11DA3E3C26AC25619D36712B11B2EF7405BCB943DBA10D50C0436B50DE5B04D96488A38F53DF37895AC20C10D959D81A29FE1F319FF871831D93C54654172A02E65599F9D820AB037438E62714BE6C7D868B66AC03C31C8753A062318CA36B6E59D340B9696D47C38F115104765865353A05C8FBC4B0A62A96577E94C17094DE259006F169E75B8919BB4C37DF6787B59BEC8FAC999A90B73123A5CC8772AD67585C879EBE05B5C06AFDB440ADFBC4AD400D0E634822A843E9B165F2F0BB748E231C0E0CEECA8806046B5DEA7CAC614A5E2CCA3767556448785DBC739CAA9C58FAC291A0BBE96E9AD36A4A1D9C96939603BCD76A81C040FBA27A5A39A1C387CAC9D1B086E512468D378E96039AAE2622FE5483673850D411AB64B892F2C29853822EAE76FEAF5716A660B55C2020DD3323A150CEEF9AB79925D2BC09CC6FAA31727A5912A7F5E9051F8B94D8866C4DA173D3F2A388E6C44218338CB85702CBA2F602C24E1788158B0129E7C15DCF2CC6ED55C54B456CACC07D179B432A5AA63E8AC59F0B6979A833D99C13AA0C56CB65928032E2F30583FA6C038748CEB77A91C631DD09B575F13126F1447CAB00BC9C85FC7601DA44AC5FEA5ADCBB599A409BB1A67B24EF438D750BF87A8814DF22449C9256DA1286DC623E81546C283B80CC88C48F003678AB35380A6DA551AC7041CD5112D59D15A80032C28B61A1BB3B8A7267ADF4662B5963468B3BC5918418F980CD7DB3946C5A67F864DC1F3ADEA12142FB71FDA590E070007662B5C3B8B31AF169A092A2E466AA01AE879641BC4D1D62523CCAA3ED436CC089B2621456114215D1A9EEFD1016DC81D5320956FD942BDDA40F3A033E5170CA6A2C57CE17EAFC97AA0959CF37B92E789636F159FAA827DDB895553540D52A61EDC1B3DCEB22A7231C48037CC78594718902333D0BC4FE6B29352991E2BA5D31217457007057B9D3C07C39B7C7EEECC222D4415D6D9272EC50B81520BC607592947C86D2612E434C22513235536CD08F10022B97675B89F1DE58130EB6797380F6B68773DFBBA0664BB7CAAC84F7B06711587C6ECAA383505F62751C8346BDD502A58E9326E4A0D2D29226F794AD0064B2CF0A56E6A67C18B331F5537D2FC6C3AEB52A5C3313118CB7D159B8372158C1A7BFDCB65D426458EDBCF8797383E272D3B18BEE68C4D74E25751AB1CE4567D66B714CD62A8E9B886BAA812A9F50739E30F296791414727D55003BCB52AB6BB74CAB215B348AD06F974192CBD61576BAFFC815999AB8556583024CDBD1C4398F4A4AC60E8CB68627382A145F91BE9D78FD51BA5E3FCBC3155B62BC07751DD +sk = 72408D44C2BE6E83C803DA2846D852DEC1848EE41504B5C91F774F6E512B51F71DD1520203C486F63240BAB4C1DBB212299753B8627F9BF2117CD6A83BE4075A385782AB804A420972EB25BC553EB981AAE7D7A715111338529F6116C10B10BBC20B31C3161D4BC1A5F050220B5584ABD6A546AB51A9A10120ECC131220502697E9D61BDBAD346FC43824135692204B49B5B377B870B7B28C86946077A215ACAA11ABD851ECA479988BC69CCC9975EB42A33523C525434BC594217912123957DCDC18E410A6D6A811BED8A0B4135B56F4562F343AAEC34396BB0556D7962679A76934B016B4B4BACC14650C55C3AEC9BC2E85B548B5D3EB891B6596F0C44009BD0982D98BF81AC77C8DA98264A719CD8568E48279DF9C8E9552B94AA773B43A70742C75F041915752551347F00447D72D934BEC553BF1014F4276015E0B4DB77CDF8C546AF05861804A5B7D92838744511AC6C8BE55E883ACB7775B98C4B4C9C8789AEE317F8F02B4127A6AE879D02C13772A003928041C53351D8D70CE59B14CAB5CA31D717F69129C8FABE46582CA5298ED156209C25BC57870EEA34255CE1B4C426211F957D74876DEC169C4C516C8716B3DDEC6C3E610C31F0C52E13650F0B1C70124DEE27111A76ABEF82C8FD3172D554121E6A87E9D3B58E11379CB812B7F4B95D46104934CE75C715771204D7C46AA9439836453BDA709CEF3BC1C9341994F25C48B5C80FCC8A67E316C431BD302B20904456B3283E9BA1BDDE494CE9F8A3F0B432DCA69D0BA9C43C703E1616272CD6B904D5B6279C55A539B7E46A601B28493E38A2CD9BA66D997C8C5C3B7631822C529FA48835F8A08F322615E96B9087C71C9F262B68851F00486489D25C92221C2759C89440CE733614B8C7A06F26B374CB4F8A6A7D67DA521EBA7232C0A4C066886B8450755896CFF77A369BC8FD4B3B5B0731452A908ACC68366B8EDBA66D09F212C9330C83990AB2DB7095D708B6C3589BF929FEA31534646537D2AB023887FC286F00F46F8A360476998E4FE7315F03C234929247BBA2A05297A5E01AA9CC6158458E2302513274A2E3359D66126F5FD44D348BA2B634642EA26C6CB616F64A2D2C819ABAA48BC565CA0AB67E6CFAB1129A0144C10A003B44BD3879B4E62E0AD3A58BD86A7030BE34309F3309642B017B0AA03FFAB4012B36ADC49A95DDBA67CD81306EF6BB20B546BCC55EAC2B815FB38BAE991D6AE7AA87D42ECBC740CC816A3EF42E9D204CA0177CDB30CDCB870386C320FF51B137578B029125BA518A5B887D7B9050DFF113468608F6335EA81A59B87CB753724ED0E159FA4709AC018A31194247A6A9C65443A35AC36E11BFA6A8559CF20E50116EE5FB3780FA03DCAA77846B18C04894E50486ACFC3B8FEABB8CF860D79C2734A700AB731739244580653699B51B7FC440B8CB1D6BB1360291BDA5B11AEDA3C77A25B40F96763A372512561E0D52848FD6A3A8241DEA49C4C24692CB43AA22067072FAC2DFF7898F298CBAE17F9CA68A132321932295161A1F31C178932004D17854D7D9C69F6640EE216747102280191A5695433763B6CF3B86756AAE22A37F9F6920C361C2AC68A7E11C8F5505AF2100651595BFF5A35B4EC7538B62289DD1204DB91AC492B610538C93EB5F2637AD97DC88F0035FF3CB735CEBAC9BE7CA78A4149CF10B6D93283050167E737596B711A9F32A0F6909975055CE6632F4B42CF9A2361CF69047B5BDE1868DD745A82CF473EBB30D86A71793364F70B1255B1C2003F166683C936A7977DF156A84051E69B95E02616DD3090DD38086EF3BC12353BAD25377618965C2810FCA929DFBF46F20360FC847818CF90DBC044EED16B3B9052C5C70A5A430441E53A5527A689F49B35CE82B84D6057C5269FB60C710C5731F431A970B86431125910277FA7C310A2285117B47B95054E4174A1EB11DA3E3C26AC25619D36712B11B2EF7405BCB943DBA10D50C0436B50DE5B04D96488A38F53DF37895AC20C10D959D81A29FE1F319FF871831D93C54654172A02E65599F9D820AB037438E62714BE6C7D868B66AC03C31C8753A062318CA36B6E59D340B9696D47C38F115104765865353A05C8FBC4B0A62A96577E94C17094DE259006F169E75B8919BB4C37DF6787B59BEC8FAC999A90B73123A5CC8772AD67585C879EBE05B5C06AFDB440ADFBC4AD400D0E634822A843E9B165F2F0BB748E231C0E0CEECA8806046B5DEA7CAC614A5E2CCA3767556448785DBC739CAA9C58FAC291A0BBE96E9AD36A4A1D9C96939603BCD76A81C040FBA27A5A39A1C387CAC9D1B086E512468D378E96039AAE2622FE5483673850D411AB64B892F2C29853822EAE76FEAF5716A660B55C2020DD3323A150CEEF9AB79925D2BC09CC6FAA31727A5912A7F5E9051F8B94D8866C4DA173D3F2A388E6C44218338CB85702CBA2F602C24E1788158B0129E7C15DCF2CC6ED55C54B456CACC07D179B432A5AA63E8AC59F0B6979A833D99C13AA0C56CB65928032E2F30583FA6C038748CEB77A91C631DD09B575F13126F1447CAB00BC9C85FC7601DA44AC5FEA5ADCBB599A409BB1A67B24EF438D750BF87A8814DF22449C9256DA1286DC623E81546C283B80CC88C48F003678AB35380A6DA551AC7041CD5112D59D15A80032C28B61A1BB3B8A7267ADF4662B5963468B3BC5918418F980CD7DB3946C5A67F864DC1F3ADEA12142FB71FDA590E070007662B5C3B8B31AF169A092A2E466AA01AE879641BC4D1D62523CCAA3ED436CC089B2621456114215D1A9EEFD1016DC81D5320956FD942BDDA40F3A033E5170CA6A2C57CE17EAFC97AA0959CF37B92E789636F159FAA827DDB895553540D52A61EDC1B3DCEB22A7231C48037CC78594718902333D0BC4FE6B29352991E2BA5D31217457007057B9D3C07C39B7C7EEECC222D4415D6D9272EC50B81520BC607592947C86D2612E434C22513235536CD08F10022B97675B89F1DE58130EB6797380F6B68773DFBBA0664BB7CAAC84F7B06711587C6ECAA383505F62751C8346BDD502A58E9326E4A0D2D29226F794AD0064B2CF0A56E6A67C18B331F5537D2FC6C3AEB52A5C3313118CB7D159B8372158C1A7BFDCB65D426458EDBCF8797383E272D3B18BEE68C4D74E25751AB1CE4567D66B714CD62A8E9B886BAA812A9F50739E30F296791414727D55003BCB52AB6BB74CAB215B348AD06F974192CBD61576BAFFC815999AB8556583024CDBD1C4398F4A4AC60E8CB68627382A145F91BE9D78FD51BA5E3FCBC3155B62BC07751DD3DBC65B722A8982D058E27D409F04F744551ECDE9015B62607CF67BB8ECECBB8E82FCC97CA60CCB27BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219ADE +ct = 972B0906D175A187EA54286F9929EAEBE5A4F147DDD71CEE94EDC0FE2672884EABE2E09DCF524EE839A08CE037E6DB27B0E232172C0B0B02784C57E13B52CF29C7F38D60CFCC0032A48C1198B02B8FBC01BEABB54378FACD94ABB9CB8BC488735CB826944AB2919CE853DA9B9B3CB99829611802EBABCC6CDBEFCD6EB5F65C9CF5871CA093214EAC807904DEB63B700CBE68D54B676B7FB489A04B050585591E4B2A921194DDE55684DDBB86AC1B52ED882DD0C93EE672C692FD94D8CFB0030201DF1D34E227A4EA150174E0FCB6A0FAFBDCA499306C752E8CE6521591F7CAC0BFE6BC77F8284BDFD36166F46526584B78FA94F645C805B7DCB561574237F2340836BFDBF367B2FFBCEDC2FBC6C974F157D99393AB842E1106F2ACBDD660EFD1082D016DA6C4D1260029DE92A37AC87E3A1CA207650644193335847BCF48A4074E6306F5FC2EA28E0379E844F6B5C00B9ED56E7E4EA35D7123254695A2670C5FC465AE5CA630BC1DBF187CFC3BF5F855ACF2855026A53790FC1EDA0195F6E32DEF74C34D0404FB51990B5AC709068BB55E1C4B3D30F8150263DBB9978C8B194A5DF5B8FBBDF4BD1E68A032ECD3F2ECD94EC3245AA702196E357BB30CED0EFC42B425E00D206817AD467EEDB156F23FA760C1B7A156E1A37A4AD95450A193DD1183BE571AAF14AE7529C534A7F6149BC8FE1567563D33CF153480A990C44383EC362276FEA37431AA3DA830EF0273591C526D9A0604E1672936E157E4E646DFDC5A13EF2AD14284BD8AC344565DAB3B45C9858EC2F3A8CCD445A4610D80C5263234D2E6F57DC7490D621566DDC0145488253E22DA3061E7645773BC2F95BBCCF7628822C3A861B8829F0F85AE2CEB1C4B4CE87A50365F9369BE6BFF74556644BC131B7A062B94D6AA662651625735689E70E19407E68F3AF50A4506A8FB345F84C81C0330516496E5940565D148975FF03FA4AEBA113080861FF63F9153200635362022418C9E28AECCED7021FB8E650D07A8639FBC0A84B5AD21914BC4C4475AD4C8F8A127C024DDDA9102FEA90187A6235E3B689A31403D0CDE12F6D7AAE4D1DFDA6CA09F9D78FE141DFF66C483C6028A22DBE6BCEFE54E07D9F58B4EED7515AE2E1032F6CC01E8C2AB9E417FFB3123ECA3EB0665935CEDA2426BCBD93F8386EB0B7457DDE5834483BE7BE3F25B133D76B2FA823BBD4A0356AE6AB87BDA1F807A00EBDDCFF68FED900A3145C3EB368EFE091BF271FC7488166F34EB62961FD9806AB91F15C726BF7B436B47047A5A6DFAD40451C59FBCFB45BDB2C25569A4C58AA277AD195F6A2A16DE0A11454BEDB867A93F53F8A0B8E395A37EABDF045B5665E7998D4477D4F611F3BCCB1F5C289EA5E1AFDA0DDFCF620B782FB019DC29BC376C2AAE914B721D5F6D6E32FFACBE67FFE15F2796FD95110EF9A46B358799B6E53869D6E326DF9AA607FDCB657F060B6ED8703E928F03BFE658A8105D7114D941A7CF108072E97CC1BE3345E43A541F7D5B7113804F5075B033475DB3AF0684 +ss = 86435AB2AFF9CEA1DC653CE819721A56933841F29330869B63E36604A6CEAFF2 + +count = 3 +seed = 225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A +generateEntropy = 050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +encapEntropyPreHash = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +pk = 25949FAEA67E908040A25908A7E33199D586F22A3CF5A7AC49EA41BF83452528C7F12118E0685B09D30947AC76F4F72E89BBB7579BBA13D3CD4E262FCD385EECA8B780D7B6D3343CA7EC1958569C49808B97586C263903989928AB9B63EFAC00B27037637897556B8AAB33198C144D226AB9284541400138E03A31F10CBF1CC4BF633C3AD70C65218C1B18770C91D139971574DD90317A421B8BDC56C02C2564B2496793A27A12009ECCA141AA337E911F0B448D913394EC1ABBB46A568BA749F0FB0A2C4562637A220225A0AFAC0E9A53CA4F506391D7483932814DEA886C89879237A95C03684CC0C2D2701B40E5B3A340316159CBC56BAE84130F2FA830501257F8A8948F482AD194CCD4F6BA6C01BACC4C1B9C3188C3D002F8F18F62393B373396F6C510308B6754B8CA81F53D5A1512FFC3428A6C2A543A61FE1193A86B97B260339FB43A9F0375B1C2C62DDB4C1F6629DB701B2D2A50577CC7D5D55A30766400842938D83A6818A128310D16648614A6B6DF6B5D8D9A8D0EA4A127F4233B9A50BA539F5F01B62513A5C7BB8EAD8463C0A346252C94F753A34751B078A06DD785AC6532C2730CAEF7249515514F8E18713C2A72D8949DE781C698E708DEB35448CA1DF99B8E09AC4FAF694CA71B7BD41BB7024C0435424831424F680A77F13506A56C97B6966AFAC4B90FE60BF5E7507E6A7093C47B5F8CA47D86C767455D645C502D82CF5B1CCD8880758BEA855DC71B1C98494862030202C06B935125654EE498A7E7F37254084AA1795484FA77926C8B438592F4D7BAAB58978329CF12F461B1F93AACC7117980774E12355AF27E506A2AC63C4ABFE585B2123E2404B9EA9753FA101604663D07E153C07B743B23C56B86A91CA34111803A1F5865E47807C012A81885104495499884B495EA3F457A2AE1363221B2A94BE84E27CC9E8BCA44F8FBB92746821782B3B92B1BFE87127F34076BD4ACABF60E4F9B97A8F63008B584D0221AF927C67D616BB9933BE9486E38D7BEFDA11A27175F670600041A6DBF0C9A4364B3FFD28ECEEB0C8077C3ABA19C6123A20CA72C0776AA8E21A582168591C7C1EB146BA820C9EA1AA3374625C8744612BCAB37250FFB34A89D305C35169660DC9B09F7C960A4C4450B1A2E56088E8605FD75A35EB620C3C90B93FB001E03C006A15B67136EC1C354D405A61014821FA9590DD212CC6095DD011BD8801A10F08F15DA21C14CACFDE606CA02B7E2E1483E3514CC6BC88C2987587458D77851E476AEA14A94C176A4EAF865D58C033BA2280EC0521BC53DCC3772D48258593A5A1F9974228652B8CB4A08296EEAE869C733A316D926D400CBB09A2DAF532DA06522DA9694CEC2A29CD4C87F6A6C837C6EF6182A30548AFDB807BF447953A3827DB3122BCC7E33576A33A943492A61F3625DCF412793996C664A4664B3666C154F90B40C3EC514C4B1A2D265A23B897177342B76C69637D52E356620F468480472923313A658683566DC8F8FC1079F248F9D8AC67D4CA703339AE28A86EDB4BC21DB231DFA970249AEB1E2138BD4791352151520A73B0792A0E77D4967BC8B46740CF5599D4056F382C9006B79938825DFE2806CB6AFE7523D940792782D978970256C691434F939B02C14F42B1874087EA68917C2F3E31315E22581 +sk = 548A01803A231CA63843872ABF16B2C4B9AB7407A093B354F8882C6775BACF2931DE0A501C5A7EA7EA5C3BAA067290B9FCA059D69CC6DE9B772CC058470544B64B11ABB77F490746384B83283740F0702E17D046759B61E75030F187C2283045B22B4F9E222CA44980DCD0A42E5704504BB3E097CDF93A99F057AB21E3AC305666710C3B4C1B750AA3AC0F00A6F592770D8082F6157ADDB170A956456C7616C856657835970578B35FA87D8F79C2AE54AD36823C6A13A4207453FF324F17D13D43A400A2102B6F6224E6F2132BB14A32FA3F10A446D7944428B66E0E0A04B204C5993C03C294927C60540F836572793C8825376332B64D109BB7273147A878FF0B0BD2808B62104515D0824C90A4E249B4EC8C0F6B572BB621B7A74089DE4B49EAC5A3CFB61A5D6B420779A29E1C5AE98AB30E01A0B45538C9A14CE61C4DFFA27A4E462757A3BDF00C0206C5BF5233132C47B7111771DAAC633E22132AE82CBD616EC92B4E9D1C88E7285B84D9A12E14897A020C06832E9CAB42102AB999838A93A77141D12FF068AC13DC4C685328C7036CCFC2087BD92CA5A675CFE40AE4C32B28EB770DA04234A456EB889EF92A93A0D3ADA8061599D99CD8A96880A2B5E440766A9C81E7A24F14C295283C333A0576B49C569C99450F8714160C4CC49828090BC2CA390094E14BD6A3011A5C038F0927FB4BAD38440EA9F96FEE99141C564A91F9C86DC72498F89D05B047461699FBBA62EC28698E273E2B8436A6EB8C9C094D3404853A45137881C691352F6240ABD2298488299331CC03B1A3106F242D2871525587888E448D0F45A61480BD7E377DD5B63E143093FCC8BDAA563264BAA458649CE7FA5826E4B9B49159E7541D432143C5093A2A5BC5B835535FE7395EC556BD467A10975CE26304BB892D056A6EA4C5CE08D033E9334CF7F6750CB62209BA21F6B147AC875C3F1195D9D991E333C7C25465176B8A566A71451B8305F35D831A36C57C64B664C707F3BF08B54FF3847F1EF0AC4B32BA7D563AF40228B2957B8A95063A65BAFAF86609B4BFE1127C029C2EB224465E1C178C74CB5DB4C0C2AA46456761EC4A528AB2BB8F92C120A1B78A9517A29C8EE408AE7FAB4FDFB1941CBBAE4C3630F407A2C23C4D10A58A8E64546727153D61766D0242C5132236F637B7323905F4A7811C1B8019A808946C11A54F8CA6C16E06AD9A685EDB094616A80383A79E482C611760C249988547194266000722743346D13C80F72117C25CBB48490E05789C6A5E85ECBFBC73669F249C10A12ECA037DFD15994CBC450EB40868ABC2FEA05B5058429B6B04DCE2C4E2630A13DBA2BEC9BE9C30B9F90B45A97040A1F227200CCB4A4413C8B0C5B169830D451BC7993EB3D5B4D914A02C3183B7423D61101B0E3AC0A2A18673126F69511F27EC55E28B975E22A8CE800C37473CAC71788A42CD39C26C176C9C255C4355A62C0B84CDA33819A1AB6C07BBC4F2847AA23A600829CD516485DFF565DE9C392791B84BDB4580326F5128556D160100622AFFA2756E1CBD0A0A1F217A0C198A6DC043B1C50813BCFB3C2488A5C02C79393B65F39990B610274FA77B814BA93784562E0794C179549EA0927D9B4A25949FAEA67E908040A25908A7E33199D586F22A3CF5A7AC49EA41BF83452528C7F12118E0685B09D30947AC76F4F72E89BBB7579BBA13D3CD4E262FCD385EECA8B780D7B6D3343CA7EC1958569C49808B97586C263903989928AB9B63EFAC00B27037637897556B8AAB33198C144D226AB9284541400138E03A31F10CBF1CC4BF633C3AD70C65218C1B18770C91D139971574DD90317A421B8BDC56C02C2564B2496793A27A12009ECCA141AA337E911F0B448D913394EC1ABBB46A568BA749F0FB0A2C4562637A220225A0AFAC0E9A53CA4F506391D7483932814DEA886C89879237A95C03684CC0C2D2701B40E5B3A340316159CBC56BAE84130F2FA830501257F8A8948F482AD194CCD4F6BA6C01BACC4C1B9C3188C3D002F8F18F62393B373396F6C510308B6754B8CA81F53D5A1512FFC3428A6C2A543A61FE1193A86B97B260339FB43A9F0375B1C2C62DDB4C1F6629DB701B2D2A50577CC7D5D55A30766400842938D83A6818A128310D16648614A6B6DF6B5D8D9A8D0EA4A127F4233B9A50BA539F5F01B62513A5C7BB8EAD8463C0A346252C94F753A34751B078A06DD785AC6532C2730CAEF7249515514F8E18713C2A72D8949DE781C698E708DEB35448CA1DF99B8E09AC4FAF694CA71B7BD41BB7024C0435424831424F680A77F13506A56C97B6966AFAC4B90FE60BF5E7507E6A7093C47B5F8CA47D86C767455D645C502D82CF5B1CCD8880758BEA855DC71B1C98494862030202C06B935125654EE498A7E7F37254084AA1795484FA77926C8B438592F4D7BAAB58978329CF12F461B1F93AACC7117980774E12355AF27E506A2AC63C4ABFE585B2123E2404B9EA9753FA101604663D07E153C07B743B23C56B86A91CA34111803A1F5865E47807C012A81885104495499884B495EA3F457A2AE1363221B2A94BE84E27CC9E8BCA44F8FBB92746821782B3B92B1BFE87127F34076BD4ACABF60E4F9B97A8F63008B584D0221AF927C67D616BB9933BE9486E38D7BEFDA11A27175F670600041A6DBF0C9A4364B3FFD28ECEEB0C8077C3ABA19C6123A20CA72C0776AA8E21A582168591C7C1EB146BA820C9EA1AA3374625C8744612BCAB37250FFB34A89D305C35169660DC9B09F7C960A4C4450B1A2E56088E8605FD75A35EB620C3C90B93FB001E03C006A15B67136EC1C354D405A61014821FA9590DD212CC6095DD011BD8801A10F08F15DA21C14CACFDE606CA02B7E2E1483E3514CC6BC88C2987587458D77851E476AEA14A94C176A4EAF865D58C033BA2280EC0521BC53DCC3772D48258593A5A1F9974228652B8CB4A08296EEAE869C733A316D926D400CBB09A2DAF532DA06522DA9694CEC2A29CD4C87F6A6C837C6EF6182A30548AFDB807BF447953A3827DB3122BCC7E33576A33A943492A61F3625DCF412793996C664A4664B3666C154F90B40C3EC514C4B1A2D265A23B897177342B76C69637D52E356620F468480472923313A658683566DC8F8FC1079F248F9D8AC67D4CA703339AE28A86EDB4BC21DB231DFA970249AEB1E2138BD4791352151520A73B0792A0E77D4967BC8B46740CF5599D4056F382C9006B79938825DFE2806CB6AFE7523D940792782D978970256C691434F939B02C14F42B1874087EA68917C2F3E31315E2258194391B7A41175A41C15CD995EBC69C83B29E4BCEA6C186611DC4A79578E37F4CDE950541FD53A8A47AAA8CDFE80D928262A5EF7F8129EC3EF92F78D7CC32EF60 +ct = 82A0E7AFF4A571BCADC4F8379F16660071EA01B9DB2E2F8B4792A099532461E924BE531A9334D56A47380A66DCF49A91B7CCA99B6522CD273326FBA64569CD2543C488E95CCF27E9CCAE17B14ECF68C13A94DD7901F7AE15A92E1C7B499DD79DAD5DF3B789CEC56581B33A190C6EA00964BD9812EC9B06DDFF1FEEC5797320D98EEBD856A42B87FA94C0971B62A79AE6CD1900A706417CE9F47B8DF31E055ACD1D852E6305E607DDFF39092864D9D39D456ABA08A104ECFDB3E5ABC9A75A3072D72C59625984F38C63ADF8E617CAA5E4E45CADEA8339A9F8FA6C8302FBA5F20B51CEF477B56F537C0FC750526A1EAFB2A424A727945DCBE1809D14544856A28702046E319F5F8159694EC2FB9BC545BA1DD6CBFA514A196F556C4884030AA2E7C5445987073A882BB053DDD48FA3A4C7EE0787F15A3E175976688E75358460BAF148118336E54C34052CEAB04C1CDE9A177C655777E403AF016A147A4236E2715F8D03639EE81F57B318D458DF85DE4DA2F8DEF589A7691220593692C12EE7CEECAD2AA996845889978C7BF0475F72BFD8A8DBEBBE2702AC7F60AF6C40ABEB30DE0ADAA583F62978E085954362A98CA1D905C7C8BBAE08346C6B5EAD4DC3E37146C75C8F546B14F52EA0CBCB26E3945F4925C54EEC227F8DC4F1DBB1A3332C47FE9CC04F7BF87F0971193B12325B72F8ADF3246C3AB847C2F2F84161B773B5600CAE25A4B624BCCDF9F889FEA70142880B15047674EBD974C6442C13CF0CBDD9868F8EF0AF7C0DE183EDBEB49D56ECC26620E6F100068F303F949A8280E370BB81F5A31E3141D3005E67BDBE3AF409B898039CA038EA1478ADB3C95ECF88ADC1F9FE9251AC07BA4214EF8E6B25312D7267FCD612C893CA8D32C0F07D6BD929815D399E13CBFED2745D31D2C783019CABCAE85CA659F68498E4D0BCFF75804958C1BE7C86F102D12C0F05C56F59646DD1C0DBEDFC65BBF8900ACE1861D98AD20E87A2E1599F6CD768385C85ED30867A43F44DDED91F2593E25AA9D8481318C3546875C8E95EBC8DD29E3112293127D02D2921F30FD2C377BE89087E4222EEE4D793D1D9925BF28981EF52AD688516251A2EF7AA3DDF34B6AFDCF2C92BBB197FC7C4882015F836E99C9BBA1E310E25009C1FAB7137312DEAE24EE1609D59B46DDC4FE5C13202AABFAFC92B8BD5AAFD6EE9FF7BFC6A5E36F0AC30E5884A84B6DCF601B4BFAB2948EFEEEBC9DE0C90FFCE407923ABF2407643D6C1B1860B796986BAB3759E08A42208E96F179555FC97B933C4F759F38F2B648276A31BCDB7FF698CA966B5B182CA6C29C2EF20DAEC7B510EB8C79FD20E33770E6192941B6084B7A7A7FB254C332F3337BBBD6979B5DAA682D36F707EFA44785098B775F38F1DA67686EAD81EE659F211C4D547DB678729B223CFF0F487F7042BA788F9ADD7DAA2122A939D76203472AF237F81BD047D6D9449E57A5AB8C3CD62FF88DAB360D8B2B3813FA36DE70F69129E112DB46CE8CE8A59241CCA8F207C4686EB27DBAA22B901 +ss = F9A2D73F0A81B5829E7C7CAD8FCF5F1AD55B384B2427C288BFBF4C29540F1DB6 + +count = 4 +seed = EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9 +generateEntropy = 66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +encapEntropyPreHash = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +pk = EB14CBCB226951857BE4B3BC2A1B578B148E824A2414412A3D57C8213793C418BF2E0803DE4A16EB9C8B5D53718D38AE40299B89793F14741792BB10D9C21D5F06633AA3CF1CC78D0DC99983076F8756B2F96B2095E0B812160FBB9494038A88057671DC692F14A956D5E6565FF752D28237C70B8F8528CB1A04CFE5E6495BD3B46A3264FD7364E0D54F2AD27DD27B022EFB3D3A632A7F99551BC3317250207F2658F363164A9631A34B468E9B3C9B34B27A3A02FCBACC516469F69B3A51554B93E05FD6DCB098E8AF8A3681CE89548CA311E2F5421CA1496A532366435CFD56A26A245BA68655DB99CD113C1AD1170BAB16A22BB3399E45C6A9BA45B5DC5DA04A426C635C844744C557AF7E49CA12437CF455B302C037BAB4954627A2363020C4AB5CEEF5AAF2E352DED62FD6A52ACB70C84723A527BA34F179204B26AC10692822AC66CC56BFECEBA65C33295FB805C596A48A0C59477405C21AC3EDD2C27E56C19BC84D710584ADE48647C681746038AC74AB73591FDE872CCDFBC3CB1218FE12ACBFEC9248C00E19424B1FBCA70FC5193151AAE1415416BA2D7FAA6A2C745CDEDB94295438BB182DADB77182B2BE5BD1CE0CC028B7EB71BA8CAC8585CBA3CA01620B63FC91BF3C210F67C65C92F893FC616158C104A5799720AB0FD907798F0678746475C8502029865DD653209A39C0C362258A266B1B244A4F42B4ADC1C6BF602FE61125C3B989C018C0A0E0C73E35ABC97C9EE695CD265909AF82548B865EB4238376A6AB53A6BAEF185799489F64E200FB542EC3D1B42E8B3960E02730936D620360FF4570B4079B369A83629B599E7B27FF48C37F727A4F93BBB2D4B7E1C73FC0D6668E53C1EFE0A0B547B1F38C51F4001654F45BF0E5766CA1C662F2CB99A6BD42A17F89C80A4DB03C990A81AE9487E1A52C13720266083E152061AA08C03A7A703DE58251F129546A42282515A3E27195CA97CEB39B00566CF4ACADAF320D5C88C75FF310F10BB5AD738D38AA47C945235E1730B6CC227A194DCB04CE046A22C37319D910060B594BF8A64F2C4B8F26000031948046721E6546893A341ED2C32804149954E3788EA5054C51A43DA89F9C789EDA6727BDD4BE32B15D47B9C327EC68422813B00950BD73C96C7175274A5EA8BC128A7C0993031B4E8A5D3C074D2D1ABDE8239D5AF58C06509B24109C84297E3FEB447FB3926DC19F39211119C4597711A222B341CDECB0698580E422A951DB2305D4A7A871967DB945A60439DE206955C371EA52452F865DA438130D2B8EAB3669A97911258B08931A2E36C6C390B6845E8076A0D621D7692971BA71BDA0B8AAF7BA0AD3C4F05AC23621A146C68BBC501854062B924C3A64916A1B9B19CE5B466F8672EDE621EA987F83495106DAC22FFAB6F4A5CCA797587126CE50589F68A2084875BBB505C7FF46922EB496DA260E3719CDB2F23950455DC8D36E3932518BC11BFCC067AC533360B86550B6AD09E93DBB092BE410721D48BF56B3594B93CBECFC785A5852B598425E4C4CDCC7CAE1907ADEA5772276B2929B9507DB5C06041E5F9846506055417C6FA091652A4A424BF6396D46365BB40601E3A55801B93A1CCF39126BA7F025A2467F6D44DE229C527F6E4E7071CB826CFE76FEA483D9163EAA84F6AFAC495A +sk = 944AB695C2345BB67894D451EA2A5C92561A5467C769352379950879899C9CAC9D05E89CB2729B2BB47724923FCA357623C69643569D66912B2F9B3249908090D4C5F68388A6141163C931DF430D70290950B07DE410AF913C0E5A215C3059785EF05B824545ABA0B95E7279D1C5726B59890B82131D5C62E8B3BE33B8016BA0C321C248A5293C71ECA570C9536F958B84663B1DD5BB6F272C3E201F014AA3AE05640ED92200274D45D9BF4410CE8EA72D680ACE1EEB04CD8B002DE72795DB60681BC9ECD387FCEA796FF7726FB29877F895E6832EB7EB179A5956499CA3BCF3283FC8489D494A88668E6614B1F49824F12A448B31A42861190CE3A9F73C6FFA25622D7A504E0694BB7C75EE71CC8E718CE9D57AC86A11721721E6181F157C333AE098F8A6823F765B60F0300F4733CF65240C779569620213B8A331731A7B31937104BECC0995EF57255261AD9B246009F855CA82AF2001B256760C1543074D70B3C578279B35137E16AC2089A4C60038B8671D308964B68A2211187154746C27F59C8105981C8C7D0AD58717978C01A66B5EE1697188BFAAC9B927822C940C5380409F38459F5B302CF7DC9D6BD823A0308B0DA45C35D541D2346BAE4173FB0C677EEC26A94C4158B28D4D7B4B0F62A4AB06BAE0B42208B099A174BB4C482C7C321AACA49C4A517114A5CF408750E8588545134F83A67769CC6E0B413BB800C04093184625A7EE24134A721D5FB1571CD82DD1D7C5F9103E0C2C4416CB775AA28DF48643084B391DD2CAF39278E9A31D2254871B170AE1B60A4E39B1F5A8473F580C7153CAA1369D8E9CA381660A57CA8D2523202816767CA8CAC0914C16F1CEC8EA4EA5DA930E0403E7A876C390BA31FA250D946A2EEAA479888011DB7942F7676A120338357BCA38C4C95088A4A0884B8B4C14E9C09E831F8AA658ED77CC164124CB281F61856BD6C965B6B6CD60B1B1034888F3970555443F0F5CC29C800F578806BEEB4730AB9AF4B9BEB89502AB48761E188CB9AA95BA06B28CF4B89C200B2145A4339A53406B6790A518F54902EBA0230A8C2A45447125B7330F12645D935E00651CB4996E395543B7E643137ABF3DF59E042ABD6FA11927062D73D0A107BA6FEA0908FF6759A972C11E864EE7393254051BDA558D4B272E6CB2C337747A7EF46F5AC872D5D5238521C09E21495EF98B59C22961E5A4967370EFC4865F06A72A41464D37CE4DD1803BC117888B681D35195C857A47B764C6799A86E27327EB0403931E29F90FEE8628AA43B333615BC0F251707024AD41A24E3C4F15B99E72F536DD989C0325225DC682E3611640D99C1552506E687E18A883F90882056C14385BC08BE82616D811A4FB2DC93670945B7EFA17593C4B7BFFB76F9A805F5230C50B065DC77B409CA8CC0B7190AA61614C528AF2D1AC130C19E4362E85A40693A87C00935A887B9B58699777453D8278C445BBC8D225412BDA6FDF026207E3B207613D2ED74C085707EDD555FE4C00B40B2A83AA219CD643F1D83EC0FC21BCF94FBA6A8262D959C9FB345F2221082C40A1501C46C55082DB2709230B04090558CB6D6815173525725D8CC0BC93C881C99A16041757D6A05AC71A15E887EB14CBCB226951857BE4B3BC2A1B578B148E824A2414412A3D57C8213793C418BF2E0803DE4A16EB9C8B5D53718D38AE40299B89793F14741792BB10D9C21D5F06633AA3CF1CC78D0DC99983076F8756B2F96B2095E0B812160FBB9494038A88057671DC692F14A956D5E6565FF752D28237C70B8F8528CB1A04CFE5E6495BD3B46A3264FD7364E0D54F2AD27DD27B022EFB3D3A632A7F99551BC3317250207F2658F363164A9631A34B468E9B3C9B34B27A3A02FCBACC516469F69B3A51554B93E05FD6DCB098E8AF8A3681CE89548CA311E2F5421CA1496A532366435CFD56A26A245BA68655DB99CD113C1AD1170BAB16A22BB3399E45C6A9BA45B5DC5DA04A426C635C844744C557AF7E49CA12437CF455B302C037BAB4954627A2363020C4AB5CEEF5AAF2E352DED62FD6A52ACB70C84723A527BA34F179204B26AC10692822AC66CC56BFECEBA65C33295FB805C596A48A0C59477405C21AC3EDD2C27E56C19BC84D710584ADE48647C681746038AC74AB73591FDE872CCDFBC3CB1218FE12ACBFEC9248C00E19424B1FBCA70FC5193151AAE1415416BA2D7FAA6A2C745CDEDB94295438BB182DADB77182B2BE5BD1CE0CC028B7EB71BA8CAC8585CBA3CA01620B63FC91BF3C210F67C65C92F893FC616158C104A5799720AB0FD907798F0678746475C8502029865DD653209A39C0C362258A266B1B244A4F42B4ADC1C6BF602FE61125C3B989C018C0A0E0C73E35ABC97C9EE695CD265909AF82548B865EB4238376A6AB53A6BAEF185799489F64E200FB542EC3D1B42E8B3960E02730936D620360FF4570B4079B369A83629B599E7B27FF48C37F727A4F93BBB2D4B7E1C73FC0D6668E53C1EFE0A0B547B1F38C51F4001654F45BF0E5766CA1C662F2CB99A6BD42A17F89C80A4DB03C990A81AE9487E1A52C13720266083E152061AA08C03A7A703DE58251F129546A42282515A3E27195CA97CEB39B00566CF4ACADAF320D5C88C75FF310F10BB5AD738D38AA47C945235E1730B6CC227A194DCB04CE046A22C37319D910060B594BF8A64F2C4B8F26000031948046721E6546893A341ED2C32804149954E3788EA5054C51A43DA89F9C789EDA6727BDD4BE32B15D47B9C327EC68422813B00950BD73C96C7175274A5EA8BC128A7C0993031B4E8A5D3C074D2D1ABDE8239D5AF58C06509B24109C84297E3FEB447FB3926DC19F39211119C4597711A222B341CDECB0698580E422A951DB2305D4A7A871967DB945A60439DE206955C371EA52452F865DA438130D2B8EAB3669A97911258B08931A2E36C6C390B6845E8076A0D621D7692971BA71BDA0B8AAF7BA0AD3C4F05AC23621A146C68BBC501854062B924C3A64916A1B9B19CE5B466F8672EDE621EA987F83495106DAC22FFAB6F4A5CCA797587126CE50589F68A2084875BBB505C7FF46922EB496DA260E3719CDB2F23950455DC8D36E3932518BC11BFCC067AC533360B86550B6AD09E93DBB092BE410721D48BF56B3594B93CBECFC785A5852B598425E4C4CDCC7CAE1907ADEA5772276B2929B9507DB5C06041E5F9846506055417C6FA091652A4A424BF6396D46365BB40601E3A55801B93A1CCF39126BA7F025A2467F6D44DE229C527F6E4E7071CB826CFE76FEA483D9163EAA84F6AFAC495AC5DBD68B3A8C148B2E7AC049BB986E14DD1CEBFA1CBF3EDD6BAE85A4D2DDA082BE2D3C64D38269A1EE8660B9A2BEAEB9F5AC022E8F0A357FEEBFD13B06813854 +ct = 99CAF6EAD87C4258D41204468930F6669BE4D28877F95B4E4E7F15F975E3F8F7CBFCD8D24FE79C7CC43154878BB576F31C5E59077DA847B648FA8EA91A309CC32508B3D6A2A7FFE37B38901D15B489689D71EF0E5ADFB052AABE970525ACDBC79DC95AC0A62B7B151AE209BC92FFB4CD40002CD061E9EC8CC7B6D82B0340D798BEEE0C4FF22888A5E7F90D2782FBB07F4D980CC0126D7CCCA78358C86D9E399625AA7E67CF6E9935D3B02948AF9D4E02422985E5F067218B0682F576C3DBCF7143AC7452391C899C31F7BC2369CD4158AF829A6F8ADE7BC59C727244FE9EEB85FC20ABC87B82B1A8233CDCAE93D51BF7DD544F8324BACFDE234DDC364909AA9451B8452A2F959DDEFD14E055D3F09E8B9B34F43CF5F61227896C85EBCB76C25F66D78F2C9BD9A1B9ECC209030EC7A494C909337D3196B11E0FF8EC06AF26F82B8FE3D95CC5EFCD7A620C410358896D7AE138C5A35E4A7F56C2E1766D9CEE5E3A883217DFB6AC66B014354384BE3B8B36B29945755418558DF46BBF07172F778128668449D0D42092E24CB530F77BCCDBF9A732EA3D68623847A1A377B2D0CF9AB3E61440453516C76B7F8477EED10CE40F0C10D5FDE3BE9E20CF629D232F85D6744B76F8801E691BA9CDE389BEDB87C5683F47C031DF57D17A0241707650BD78A753570A1DF4FB30E952B000239A0ECCBF75954FB6053E509AA61FF4607204175BF10F500735611053633A2E77E1E073C5B5DA9C41C56DB9A368A6F9B2FCBFAAC2B899A487FB9653FEF223A24D788DAB079C88B47B08C7B300EEFE66BA4A95CE44FB719B495C3F1530BB1B4D8EF0E940603D142A6DF06DA11C9CD06A983BCF834A1253D472BD5A344694CF01CB3A7A75A3954B6DA6AA69F700FBB5A9C6D21C29D9DA5622640E730D44DAE3CBA7269C9F7B5A822069FACF10EC7710C89D56D92C56DD9E5048C898CD1A1AE0658DB7530A27C9AF44E55030EADB9B1CE92EB8129E5CCFB5AE7E3A3ABBEF6F441ADC3BBA1FB94AFFBD154B4E6FE014EEF5863DBB3C0764D0F4808EB19F2E6249B809E1BB558EB8A7DB7EF4CABF353B331F8F1A85160BE83D34DCA53FBF0C654D2BF2FB594BB2B26F9E6BC875542306CDD623638D8F36CCD98A4357C84C06CB8594FFF92ECDBBA23BC3FFB3743344C347B29106FF5014354011062CA7A1F7B2F0B4229AE5857A769B6C83E3423C6EA10605A168DBCE3F5FF5ACC77A17CD0C91E50787290AE26BC68F4C9F9DCC961AFBB3F875A77F5DCC7393B818859FD9F41F1BC1C1AFB814B0EB7BAC59EA36A9BEEEA70524795CCF733A315618818C165EE31D93C198257DD17D36F7F5531F58EBBD0D195068F0BC0E559BB658A49572FD0F0D6E587D9D8D3D5B838C11019D7D306A1A6BD88C1155DB8498FE0E7262FE683448C6C44B83A416E9FB99149674F93663B119076CBD2EF018A485084676DF141E7373E3F96BA2D4FC23D175FEBD6AC4A63BD910ACB190EA203F9408DF92413FBA0CFBEF9AC0098A0B40FADC42531EBDDFD3B8E5095D2C +ss = 83E562482FCF5157C75D3D2F0A35DA861689A1009104A071A7BFB10BC4D8CD02 + +count = 5 +seed = AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA +generateEntropy = 7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +encapEntropyPreHash = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +pk = 86B5C9A75157E73CCC2E138518EA98A246145DFB6BAC9B2FFC333C0BA5806047CA9BA8AB797937000270E773C9863709E59786F8EC948ED27660AA3758E33F59140E527787FA74A2CE22A4A8F3037A26903665CBFE8A0677EC273F590D64C97F69F396DB78448535746B43296BFA2BF0A251BF986A524074C1F96077F5219CFA9124D1458520993F627AA8B7B6A0F191683233E0BA6BDE24561A666FD10151B0C52C9982C301E0970C3363DE27825A5BAB078848AA5CB75A90C1CBD24CF67A68F3417780CCA947131E4573934F9959787B6320A4B47BB311048289E2C915E35344E3A144E2708893138A15A03FCE3816945464C229C587093B5CBBB519767FC65C078D6C684B8B81C1F9CC2B3BA749FB3074623E3C9124A8E1A513510357656B37087BFD02773FB59157EB885E1501740483F3EC070BD492DFC217D7DB99CD7C9D57B937297634C3494DEB585B8C93CD4EAB1865F8A9C8BB15DFE583C7DC0427274F8DF3C693FC351289964A89A3C745967231261D949552E0809BA9B7C5D258AF579A4515981E991D93154BCAA170491B06752415B1D52BC2A98B7F39C5B91A87EB759A9A4537218156746930A347A5026911ADC0412F10A7A7C200A1514D500805C10A276C327E4899AA3F9B95D1BA2347E0140184B1235A719E6C4A3011576235215D77084034771129C33199B70774B2130898A0C69D8F39C3A50B273C665DCD8031B4454D144A4356B9C2B16641311856CB65466991B06D1A8A74A5AAD6B5B935B65DBA8374EE690CD1C701A5A28B41732B5F88A9AD919A7FA563BAFB529885488F544E1240B3CD673F94EBBC91B4757444A302578AA953161993CC918216BC56BA53EA17664BC5B543A38C3516D4063C35695791D8821240BB749CAF98896C4718A9DB33C1A7E9B91B9B6D06FBAA58E507F8A105E2F71F6095621E354B3DEC1F9C979ED7B3AAB56B4741110FDA601FAC78C2EDC386669118A425C634157875F61ADF10C43D2184D3252EDEB11A61EB67A349405EC74B9FD307558A887EFBBB46C904F9469DB491605A3582BE433BED57363426055CC4852ACC0317F24D89903A918875C949556A6A458FA3CFB5797D6A3A68EE9991D97A38E16B9A727C5B2E7B5E5A0029C1513D5A1A98EAE78713785BD4322261D90109A0806E565EBD9308849CC6708B536C83A2FA35995C819D99B850251C1D50EA902A053C7CA31FAAC37BCB1B40D6123CC4D52002909D0AC566F7D75DC89998036AABB267C5AA70184AB4CFFEAB018F195F62879BE0A51B42B843CAF7C494C181C2F06866CB2287A00349EBB136747DA52A3C4A3C581798C413929CE3E698FA594F019579AE329A22D4AF66F27B46453F22E61AA6EC5D7D854FF6D3C3D4117BE2145B5C2BA7A57AC968A5CA43B461F808167FB5A76A942C95145098B95CD46439669C00366960E2162AB613C5ECB151359B093C27C04AB230FA7C0074684996F44939C81FC31373C8231BD0B6679991A32A031002B257B2F31101317B3E2B6B28B8911E3991479444C6086110B7A70125CA71C6659C970F94D0942124C17CE3AD50D5A7019146BF51B012D1CFA0F59B220A795DC6B3D7896AAC680ADAD383EC46762B669D35909A47C12DC8EE619E1A0C8915822D574A243F67E14104D4F021CF95BF33271C9BC9 +sk = AC65AF9FC8B905D09638374E58C551DA08AC4EF86A8FF04489BA462841A85D907ED0C70E1A790297AB2DF7D6CDFC5C6AF513144DA105DDA2C75F00736DD91564A79668E335FBDCA1C9D31592E73D60066B959A2FCBF55474F9C21BF058F021457586766FDA4FAD521F64940D4932B07AD8CA7E1A06662730EA6C15AA1C2F9662552313176AF04FA4A98962101492566ADB8BBC3EC04F9CAB9EBFE5860F886D57A2C73FA050A3607A8C0998754B417C9C5AE2FC3F829CC3A2EBB1E927AE87B68C6DB355F4C661CD000D10D6BC31CA1C249A9B3931A4D1C57904DC6DF923839D9A90AA2B93A87C44B5F82E6A925D22E679428064FFCB9621067B75477FB7D51A1D3B9D9DE4051CF874CCEC12976562752CBFCFC59F56C2C60B8B4610A9BB36E9019B974502407D57289726AB8A38D7A6C880074A5686619ABFFFA5757DC79E1449408851502BEB8196F493F4A724B9D681645A07B193586C5C05D8D10E2C968BD251B88691C368DC18CF8270DAD3C22BF5093DB4CF05668F8C6315C0EA3F55495E784CCD6055AC451363FD77A91686AD77C5AF53141EB5E7534FAC4DE481741E48B414302E4743789E250C39C45C0A15CF42E7B3631B6A8C0971C8A34B8200BBFE11004AB06BFC5949C3615B02947C73E7A0717C6B60F2679DAA21AFE4C55768A08E70105868AA6AB4AAA848C79BF125883907B9DAABE367AFCE273E2C168AAB02ACD27855E2944B67B938170A9258F67397770136E466758C260CCB7DA226B5A95692514727FD48953C62959C88C8784A8A52131C4BA5A6D757B4311048B602B554E8AD509B0C12B0A64553CD4270CA92F36CEC227E16A217C769A2BC1AA6C356A5A39C69F4963BA6273DB9232F1D8A28CE65B5B9058F1B8A164AB0380C42A8EDDB6C2B8B19F26B557C387E4DB9AEB92C4D7D0A2CA1E35F97E05CF590BC511AC5EFB2357E70525BD027B36C6781C4B86B0069E7B89C8CA643FB9990ECAB2CC5A8A5A5B2B0441076CE934D96BCA9FFC10EB6E7BB093675E97B68894BB030581D89123642C1118364115A76AD1C181EED4B691BBC15DF182DCDE00C71F8685B71883A184396D3475CBBCB674360DC14C42DD6461514479C85557194A97A654C4BE7620FA84C59DB5057A0886D760460CC4A3A713F4FD4BDEBAA93B943C48E6348053703ED818FDD9CBD62E246C0B69A265AA381822D6A474C5AA530AA5306A0C8572C413718A278194367405789E1F749AB4A02AF87B362067F3DA12EC01A83ACEC26A390CB5419B351BC95E08C7338FB933B81476EA950881275A186C9E9F99DAB63634E6B7314188BFD686D74EC203B71542B62B1C0C7712745940F7B9237551467470E5B1BA2F8E34CF585ADBAF980317C9DB1147382946C12223C3A45973B879A523855BEF121151BCE620216DEDC6C3457CA03951FF45B662F79A1A7A5CEFE9A846DD5774C7C2A22F842E4E465A94314E036BB55A2787A1A0F0F111143872DAE74AF706A369CA54259B80578BACD497700871842B98CAE2AC3B572F98F145CBAAF54569779B616242060B30B2A482DAF335C9A502CD318296958C696F7080C7A3926C7B62F36A5DBFB87EA0518358155E8E94390B6C0F808B91C166577037D86B5C9A75157E73CCC2E138518EA98A246145DFB6BAC9B2FFC333C0BA5806047CA9BA8AB797937000270E773C9863709E59786F8EC948ED27660AA3758E33F59140E527787FA74A2CE22A4A8F3037A26903665CBFE8A0677EC273F590D64C97F69F396DB78448535746B43296BFA2BF0A251BF986A524074C1F96077F5219CFA9124D1458520993F627AA8B7B6A0F191683233E0BA6BDE24561A666FD10151B0C52C9982C301E0970C3363DE27825A5BAB078848AA5CB75A90C1CBD24CF67A68F3417780CCA947131E4573934F9959787B6320A4B47BB311048289E2C915E35344E3A144E2708893138A15A03FCE3816945464C229C587093B5CBBB519767FC65C078D6C684B8B81C1F9CC2B3BA749FB3074623E3C9124A8E1A513510357656B37087BFD02773FB59157EB885E1501740483F3EC070BD492DFC217D7DB99CD7C9D57B937297634C3494DEB585B8C93CD4EAB1865F8A9C8BB15DFE583C7DC0427274F8DF3C693FC351289964A89A3C745967231261D949552E0809BA9B7C5D258AF579A4515981E991D93154BCAA170491B06752415B1D52BC2A98B7F39C5B91A87EB759A9A4537218156746930A347A5026911ADC0412F10A7A7C200A1514D500805C10A276C327E4899AA3F9B95D1BA2347E0140184B1235A719E6C4A3011576235215D77084034771129C33199B70774B2130898A0C69D8F39C3A50B273C665DCD8031B4454D144A4356B9C2B16641311856CB65466991B06D1A8A74A5AAD6B5B935B65DBA8374EE690CD1C701A5A28B41732B5F88A9AD919A7FA563BAFB529885488F544E1240B3CD673F94EBBC91B4757444A302578AA953161993CC918216BC56BA53EA17664BC5B543A38C3516D4063C35695791D8821240BB749CAF98896C4718A9DB33C1A7E9B91B9B6D06FBAA58E507F8A105E2F71F6095621E354B3DEC1F9C979ED7B3AAB56B4741110FDA601FAC78C2EDC386669118A425C634157875F61ADF10C43D2184D3252EDEB11A61EB67A349405EC74B9FD307558A887EFBBB46C904F9469DB491605A3582BE433BED57363426055CC4852ACC0317F24D89903A918875C949556A6A458FA3CFB5797D6A3A68EE9991D97A38E16B9A727C5B2E7B5E5A0029C1513D5A1A98EAE78713785BD4322261D90109A0806E565EBD9308849CC6708B536C83A2FA35995C819D99B850251C1D50EA902A053C7CA31FAAC37BCB1B40D6123CC4D52002909D0AC566F7D75DC89998036AABB267C5AA70184AB4CFFEAB018F195F62879BE0A51B42B843CAF7C494C181C2F06866CB2287A00349EBB136747DA52A3C4A3C581798C413929CE3E698FA594F019579AE329A22D4AF66F27B46453F22E61AA6EC5D7D854FF6D3C3D4117BE2145B5C2BA7A57AC968A5CA43B461F808167FB5A76A942C95145098B95CD46439669C00366960E2162AB613C5ECB151359B093C27C04AB230FA7C0074684996F44939C81FC31373C8231BD0B6679991A32A031002B257B2F31101317B3E2B6B28B8911E3991479444C6086110B7A70125CA71C6659C970F94D0942124C17CE3AD50D5A7019146BF51B012D1CFA0F59B220A795DC6B3D7896AAC680ADAD383EC46762B669D35909A47C12DC8EE619E1A0C8915822D574A243F67E14104D4F021CF95BF33271C9BC962E0447F7B5AE8A806B741CA5C302230B555C3786C11F3EB43894A8F45E3F7B1A08CCF451B049FD51D7A9AD77AE14A81569DF8C9BD3A8F1EBEA86FDCFB823082 +ct = D4BCE18C62FB15E635B2061B99A2D1BFF919EE09A76A8598F64C8F52272CE533DA3180B71A5F1A710EE5D924B1725834D24EC3166E3A2D6C0EBEF6B4AA2DCB9AA3CF2BC0E3AD19590AB3520B3145CBD5F36E207AD97C9AA2276F0FAB6A5918F9C0D67616FD45B4F8BE0C461488F17F57ACDE6432D8B36541ED62783DD590B6AC71FCF01805EEE76EDC2583CF0A0626CA4B0D6AB6535E2251CA533992336ECAE5B26B0E06525F08D53D04A9E0CAA603381E6C033F26661427063E3B6C84A4F82B9120BF58A3560D7B7234F1C6E7A5A4E320C8C8DF4F6433F646951F7A719A79B9D22A663A2E33A39CBDD054D870F447C9F3053795F96134DF95B277CD95B6D7580225F919E5119FB5C2C75704DF380CBECF276D28FFED759C8BB7252E24A39A1A9AB3FE42204727A50508ADF6C274B6D4976DBD6B7DDE7753A9E58CF8FFC6E31BD3DCACF9CA083B3C482F561CAB1C0DE32293D35DBB69368E8A62765AC4E6945D8D982435545F2DA7DA1875350BBC242611DFA2BB9F36B407E70C27A7A0AE0EE2371C33BBD7B958F4A233ED13BCFA73161DD89E559EDF03845A0F8513A865ACEF4DC5EE33E40793284DCB5226FCEC925A4F1195884A72993F34457073365E35A1346F6453DA6262B137EBFD7EF78711CD1319D23493888BE93C75522F3645E5F83E10843C4F688BDE241537249926FC901E9BE192A126FBD910194D0B3B26325D59831BB82D9A2F357ADD6C823D46E3DB51646E09C22F750F95237CDA8A00071BFDEB8CED9863B89019155EFFBD27337099E08CB72293CEF964F28FA1DCC644B7D022050900524B2A1F7AFB0347FCC6E8402011217FA77E3A6EEFE5C4A63F775EE2DFA5EFA3F9CCC2E70366B88F5AD9C0B73CF81616B32D38D30B2741A04DC6AC179B90FE61CB66EF31024EC35093BC140EE79BCCFA149FC69B846EEB3717BF18A2358FC9C56EE28A7E384A82EA0D830123A49698E63A17D70C1C9F1169F1B62A409C5A64FF6D73372F419E12201D8AAE01D09BE2C3D26E8D651884A31F6B2456410DCFCB79684B00A163ACACC2E247476CF53DD66DFDF3646322971E918C0B9096F86A8EAD17558D6736F4C52B1684F952CD93BD39CE4A4D67EE2D7470C710F86D1688AC90BB1CE23C6E500B6EF99FFF1102BB23FCA16D96D30DE29B4AC4BA252063DFD14F7834234274A49BBC5E78B01914272F1A84BE414AA871A7B5072183CEC33EFD9C3FC702FBFEC2CA3762D22722B98575CB874219FBF0F82C3F768878AE2AEB9D3FCA8A8877CB3B78B9A9E34DDBCEB6659E3D632B37F6402D734E545BDA4027562089993DA8D4E8F388243E1D8EF9504F52DFC668E69BE634797EEE05C6C2CBCA705FA1A088E9A8A2CBFF0C9F8827310FFA1DA6E75B0BD776B4437A6CDE2A9683374910FD5E5218353AF004F1D1060B6BAA31B3460D01B3E7675261DF6C409009100E70A4391F146F04839F0C175837DFB4E6B9DFD402032380236627093C9BE3F8EAD7F81BEBB8F8853C549C875AB0EE4BAAAC49B73FA3D410EA646E +ss = 445B60A142D4853702A102F9CC37FDFB1D0B14A9A7E210C7D290F9402F0A2F40 + +count = 6 +seed = 2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049 +generateEntropy = c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +encapEntropyPreHash = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +pk = 05EB362461C4A2E81885084505C3862C3B647D181805205EF3E4CA5C30C46A0C21EB97700B70C2BEE78D862B3E19DC1E0CEC0AE6998A7B3C4FDAC39A950027FB2A3BEE027A8E54B4A5B981BBA01BADC0B5BA6A36A2913F1C1A046036960790CE2CF2583E6C62A778290F242B49606ECF24B3A0DC023B22AD8945A0B8DBCCC9356475B36B2A990D7435B12E1536A21079FB7802B998488E690F763646C3B66ADFBC8161855B20EA18AFD87229D05E60372694E4C4C6215344DA04173559D7954B029555E6CA4356F6CBE325A39431A64DF06E75C63ED0E40BB0CBA6ED68BC7211B02F1165C370ADA1E0ACF4AB61C87CC32F7017B4A26FF8CC0784F76047316AF6398DDECC0C62E9A37FC4CA685017B33AACF597767312192CD330B2F3A84E0BB858480A63A607295A39F61510DC2C6998614013F45D319858DA8228FE5BB6EAF3B03AA60F4B721A3F046D3088671930672C61C92D6005254372D8081BE322CCEAD06CDD472CC5A481EE385096A5B8CE64B57781CBFC4457E917162DA007BD7BAD8E3803E05B08876842D9E6A0A545407A5067EDE3510CCC4478C040310AAF46051454D855D1A5521E2514AF676846650E0043BEBF453E7488B6DB8AAEFCC16E26A75C52BC0EF3C80DA3BB39F73B9852B54D9C606363438C45DAC4FF1A1913D81B9A80544177BA7DB6503A04A5405299F80A83FB7135FDE04F8CECC0962461C0E80298D219531C9CBF00A3BB5B84908B5A807739A63485128512C0478084C8964F9064CD4514CE92C30454AC25B48919B719C5A853010A2EB712B80975660456562C4C448C39162CA63AED14AF7F28875149857F9B8965BC1D04CB8EE2E67C14A493A3822FCD0A2DBA2677E719B8F2C8BD09431B82BA56007584BEEACAA1F081D244B0D771BDB0C8033B18CA9597443FF8CDF754569DCC2DC4D4C212E2BBEE88925CE73034E19167CC7AC46059CD3B9EBBF6BC3A476F08438C61971AF139A248821002480F42C2B9C0979AD3BC6868565CA3FCBC124A7548D53F56B51C9F8AA387B59B07638C7AA45704420B3C24642035A7884CB42F877260C29697809AA7482E3FC356D8CA061C1C443CF24C4535BDECCB02C3E3B8B1D90E5B47BD11615CAF849DA5811AA743B9BD7810C470187E81AF9BDB4D1307303F615ACE2A58E7ECB3BE260E9F7C1E10EB3A84F207D2E75A30C7C741EA45FB04A9473C1425F80A9186A7F2625EA6ABB4AAEA3BB50602DF23ACF8E452CC01A909EC9034ACB47B969D904213F0A79EDB7766D0290005C954A1DA0155F7318BE854FDB038D019C1904B714F0514AC331C3813BD703B45076365BE4B47EC510A9F585907BC0F461A6BEFE13A2667593E12134A86AC139777A50CCDAD16B6891A0871621B387684B5226368400164B29109328F672CADADF7648377CD11C9232094165BB1CF12F694F940C3CD784C84925BA74C8A49DC27CDA4C553C85334A860A8A55D8A75969977AD1F505B9B20CEECEB24A262C707843310F39434390EA5315A67491F0592BF722A1C2658C8A720991B26561E14B178C3A1028003CAB8B69F60828F47B876D43D3F193C3820804068A5CAE76DC3F27F5F1323E6A2797B9A13C86713A83BA9C161899CF295CFB4A4AA443F32D16B72616A0DB4D3849FC41A7A6BA87F4AF757A0AB1956518F +sk = 67A93BB27ACD00C9B95AA03552809C38A08480DBAA67A9584A460345E20E5F381C9A82710EF1709CA51393F916345719BD3144B3121A8608C0A48017963387F7A31C5FEBC6B6749E6BD9BE3C58A9A77B53D7762F5854A3467A85941CA2C03873C0458B940275E5AB85B83A5C2027894B92246DD8632D68A310FBC6D214381128528B375FBB8C3C7923AC6A8C7F9E37C2EA4C6B72E3451922761AC274B5CC8569CCB93917A748E93C190320E3F1381E08CCCCA70903975AE25689C12709C8E9096B16A26E4439C2552A088194368B36EFE3871A6A1CD54CA0C70974AC936E45DCA01DE296A14C7D20652999E61841DCBA6C0171FCB406E14A95B0C02517447BB9370996176BFDC5BEB4316C0ED34A13431E34AB27D9DCCD3DDAA49D314659BB8D89325099D0B06931796CE65C0628C817393BB1870F19A10CFE3546D8BBC2509058327626F490A1BBCA6FBB653EE1C3555203353509AB14B64CF8A29C32B17096805B8D751848DC4494279266F2CC474228B2B703CFF81F0F29152F4570151517995262D705AFFFC08DD413C12F37B605BC32ECC1292B9AC99E4A34F911C8DB990ECC9A3DFB37517446908B91B1172A3D4F547B3AA642709BA40C3939734545DDB6B45C66A1A3E58C6D1929E5721BFC6A6021A635D86C8378D4A0BA68CE385B6B7FB983EC4A95C8B20B3EC750B082BF2CEC89A6F8C2881650E5B71A0135C865BB3FB12A4C2C3C917D655A2997984C8557ECF1943436A9FECC5C84808E38701CC26A251F458334F59BD40BB0D8F82E74071A5AE3C9439541AEE59C6E46A5852834CE5712B3665018154C5339467D606AF189CCF20C68C583C96D969815109CD3ECAD4F5AB0A8BB8A7B68359B0319078A7405821C2709A615864422BA0A3970C8EA138FFC1522B1A53ED1C71D396A0ED6B782C6552C70216679BB4761A600634276D553CD703897C6943A859112CAF9A7AC99517C23CE6457AA069B6FD2775EFB262DBC27B02FE6923D14B047A25CDC6B86D20A55D85108FF276F121A352E098E5D4CC3EF92B3A1C4A38244621B055D5F812189F6941B492330FB1AB0A442A656655455B38B522DED5640CC4136DF6CBF4C4B0651531CD8C95280E2AF13FC57C977BBD1A8BDD253096EA98C3AB33A516448A8301A4B141AE213BAD2F640B2D5846C99A25884360F604333197816BA9DD1D0C427C5B8D3A6B434207B8539CE5092CCDA67A755D6A6D7E8BB6BB02AF1CA7283E797F24A1042D29B64262F29B0482B840BD70A3D6D54205DF412DD6490E3DC38C1236758F65E461B11CA480B476875C692508E7BB90C430797E1917041642D88506C07255AA92EA32508462C2F4A1661C05114C9361F651B7C5FF70B42659FFEE71F58CB79E445536B8948142CB4EC16CFE5B21DA659C2DCE452346323F1632C37F128A6525F40E03D6C073E05476252B2B0483C4B87C1C1FD8C972CF651EB9684FAFBA3F862C8619C089F01277C14BE7CF7790712CA1E8877A48909EFA31D814C1C21F4A151B886076840546419A1C8B6CA4466389A3F6DBB69E8494D7B25A4E9B234A8D928A26B946FF305B8A33B0BF8B3EB992D68C312B4074788E69D1A5A211C3B55F8C654AE778FBADA1D75FB2305EB362461C4A2E81885084505C3862C3B647D181805205EF3E4CA5C30C46A0C21EB97700B70C2BEE78D862B3E19DC1E0CEC0AE6998A7B3C4FDAC39A950027FB2A3BEE027A8E54B4A5B981BBA01BADC0B5BA6A36A2913F1C1A046036960790CE2CF2583E6C62A778290F242B49606ECF24B3A0DC023B22AD8945A0B8DBCCC9356475B36B2A990D7435B12E1536A21079FB7802B998488E690F763646C3B66ADFBC8161855B20EA18AFD87229D05E60372694E4C4C6215344DA04173559D7954B029555E6CA4356F6CBE325A39431A64DF06E75C63ED0E40BB0CBA6ED68BC7211B02F1165C370ADA1E0ACF4AB61C87CC32F7017B4A26FF8CC0784F76047316AF6398DDECC0C62E9A37FC4CA685017B33AACF597767312192CD330B2F3A84E0BB858480A63A607295A39F61510DC2C6998614013F45D319858DA8228FE5BB6EAF3B03AA60F4B721A3F046D3088671930672C61C92D6005254372D8081BE322CCEAD06CDD472CC5A481EE385096A5B8CE64B57781CBFC4457E917162DA007BD7BAD8E3803E05B08876842D9E6A0A545407A5067EDE3510CCC4478C040310AAF46051454D855D1A5521E2514AF676846650E0043BEBF453E7488B6DB8AAEFCC16E26A75C52BC0EF3C80DA3BB39F73B9852B54D9C606363438C45DAC4FF1A1913D81B9A80544177BA7DB6503A04A5405299F80A83FB7135FDE04F8CECC0962461C0E80298D219531C9CBF00A3BB5B84908B5A807739A63485128512C0478084C8964F9064CD4514CE92C30454AC25B48919B719C5A853010A2EB712B80975660456562C4C448C39162CA63AED14AF7F28875149857F9B8965BC1D04CB8EE2E67C14A493A3822FCD0A2DBA2677E719B8F2C8BD09431B82BA56007584BEEACAA1F081D244B0D771BDB0C8033B18CA9597443FF8CDF754569DCC2DC4D4C212E2BBEE88925CE73034E19167CC7AC46059CD3B9EBBF6BC3A476F08438C61971AF139A248821002480F42C2B9C0979AD3BC6868565CA3FCBC124A7548D53F56B51C9F8AA387B59B07638C7AA45704420B3C24642035A7884CB42F877260C29697809AA7482E3FC356D8CA061C1C443CF24C4535BDECCB02C3E3B8B1D90E5B47BD11615CAF849DA5811AA743B9BD7810C470187E81AF9BDB4D1307303F615ACE2A58E7ECB3BE260E9F7C1E10EB3A84F207D2E75A30C7C741EA45FB04A9473C1425F80A9186A7F2625EA6ABB4AAEA3BB50602DF23ACF8E452CC01A909EC9034ACB47B969D904213F0A79EDB7766D0290005C954A1DA0155F7318BE854FDB038D019C1904B714F0514AC331C3813BD703B45076365BE4B47EC510A9F585907BC0F461A6BEFE13A2667593E12134A86AC139777A50CCDAD16B6891A0871621B387684B5226368400164B29109328F672CADADF7648377CD11C9232094165BB1CF12F694F940C3CD784C84925BA74C8A49DC27CDA4C553C85334A860A8A55D8A75969977AD1F505B9B20CEECEB24A262C707843310F39434390EA5315A67491F0592BF722A1C2658C8A720991B26561E14B178C3A1028003CAB8B69F60828F47B876D43D3F193C3820804068A5CAE76DC3F27F5F1323E6A2797B9A13C86713A83BA9C161899CF295CFB4A4AA443F32D16B72616A0DB4D3849FC41A7A6BA87F4AF757A0AB1956518F0C1D832AF7B7282D8BD81A2237107EE60D81E28EB64D6A153AE0EAA1A25797C284EF52DB5EAA6DF8EC3A0BC5FFA730DB0DDE8C5F38F266D5C680A78D264A7B96 +ct = 7E2B3F001C83AFB604595634A841E0D71327502B46D289E4D5DD27ABBD0400206BC1CC315DAE0F8F9BB8C69676B5FD0DFAD5DD4D05609B5AC327F77EECED6D72139E4529574CBE4EFC1A796033DCE9DFF2436E18A627FF4B30748002AA858BF6B9F12ACCCA22088B727D74C1C3EF565956ED029B661FFAC19F00C54CDDE3D86EB59725EF82FAA2AB55BF3ABF0789E037CB95F233E93C7B73471EDCAC5CA8D5D94968EEC87E0D9CEA8F2ED79C3BFD8456FBB1727E576371264B22334CA4492D0EAE431AD6AEA4524F22C08F8C3928B703D7D7C23481622968AD7CC52D10E38F0B164C45F3742238555806283C1D781E8714030BF60D3CF414D00FA1C46F5528DB038618E918E98A6A36D7C092575E1EC5A6961485368147A38F52BEA70089244EE06DA2A814F0478299AE34896089EE6A7A2701512443E492E9FCFDE204B45965CCE878355E23A670779B140DEB556DBAC7448CAE69A90BF2359F8D6A8023233BFF39C195B16754CD1A43567B449742E643F16BADD4907922F9C7E3B333AE55F2B28D3FF896E83AD412ACE77AA18D76A50FFD417BBF2F5CAB1E23AE417E855F697E4937E988C0040DEA224BF0F99D3521252A4F8EA00F1311ADF4A61706610BB2A84D761A294806B03DE026096681A0D249BFFF4226F1CEE5164C3D54180E7123D2069663505014B0B445CC0ABF27AB73209E89A1FDE1BFC0229A6D2E9FCD9562B7BDC5D4E63A7955EA8CC5BB8FC0C2AA23E1D576269E4CC0696DF1A404BB9E6821BF0B541E1BC2EB643691EE390E662A8A8AF177DA61720336183CFE8B5963EFFBFB97CF9A12DF2B6FE59A613E693D25A672FFE633575D5A2E5B6F97C122D7E1823A299DC87956C0CC6E35F055BA9F08916E163D3D0609EF7225C9C507B8C3021A6FEDE3E48DF94B21E235A38A6A506C9436EB83B19B33EAD5649012CC3EB866493965E55B09024910DF0E45962E46C33DBFC7E1F7B854BB30197BEBE2956108F67243D52DAAEDF84AA65AF71373B8BFE221C70EF833ED27B2CAA2FA744B322A4AA7EDC1854ECB932BC4008A284F4C06EB87592068123E6A137F4D5FC216DE6B17C5C6F9819928C9ACB9E9054B101C320DF769B12D9ED4E0D1579781B91F9C97D2D55C34CF4309C33E26D7D616A3B52E3D3C59938BCF11F6BCD70FB420A6590A4BE120630ECD6C2368BCFD7632B522854947C0251ED4906BA4BDA3292019F1730A17003802A43562469E6EAA1C23E41CF88D2FE7AE803E4FBE44968EEBD1B714E25DA525349E941EB7B651AA391596E47AD9F3E298D1A748348FB6A322716DF3A027050501E5ADFAF41FCAC0D5F22AC5360A049F3638B0C90FF249FF1A6A1208BAA375DD19E79A6DCFC33BD9920D854C8EB12AD4C8806E3DE032A3751F005F59377D51D5E70012D318D553AF10162674DDCB19F11C1A9C07DFB948C700EC50F87802A9A18C8FCD5239CA762350CF436AC84CF467003035638D9D8B9B145F2D7F35BEE3BD00C59D6119B634111E1896DE86F5FBF359E9C86BACD73F9F432ABBBA +ss = 71156980B8970FED7F2213594630CA825EA8EADE58CC8225DF8111460412B762 + +count = 7 +seed = AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB +generateEntropy = d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +encapEntropyPreHash = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +pk = 89C28969078E11664CA1554ECA81B9542BAE2EA8CC12B44E81B3354818141AF0B494543D4674160A086F7E8755A87258E7E6A6AEB96955286924B42636E04583F74184133D8ACB9067925F4969642F274085F70FC12361FF96C3130B143E23797F2A3A6CC757C97454CC8AA5D9C062F9254F4CC7335B44CB66DC712B4677C290CCBBA08CFC3948C535BE29F44736A23B4C8CCB3978404E419A08A67AA555BECB48BCC161CBC5492B55E3498E74BB515C28A7A44A3AFA0148EC3411D82A1AE103513074A13938A5FC17DFABAD006D90455B4B5E45079D7BBE956C7A18A8BEC9A64C1DB72544CB00C6997D545AC7E3BC5C6565885536AF486417E728CC99C78CFA12A1F7697F1AD26EFEB7262800AC4E0121E766AA9BF0A74AE635074C62FB6CA79975761419B12A985ED7A2C8788C9020462FB5764C087681BE1595A5EA4EE7234AA2D22F4119B559A536E0DA0E8D0B2E493C2B5BD576459994ACD684A81A0955684818E1B88E348446A22C9143A4EEFC7D8EC678624763D4548FE2451F078582C93C986B0417E1AABABDD76DC0532E252B59E47370E81951EF75AD48C223316A40237152E3508EC164C7375594F73B5F0483C560F52F250AAEF28431E9D1B2B9DC650D2371BBB7C8360C72369755BD8696FC5C83FCA76A7FC02EFF54CA60579CAEF6341385AEEE34C7182445BFDB549BC59F70B76368DA88D47386F75968ABA093E8F42DD3C7CD68C8028A90CB0C93CB44D42EF9D15E6CA978ED5B88914C4E20768028F2C927A33433D33C5E6A45A6C5AE8C252A83E68EC121347B025865F26912B89A9DA7472B75B9ABA75581852B97D27EA7C9C5C7E8BEBC0094C01947F43A2C6501C97E43231310167ECCBC4C3A2022839584A12AD5B51B4CD308C94302E58C70EFF7B24FAA051CF548B5A73AB4254179EAA038EC95D4D4182D2971084CB33A6CA1106076DFA76EC0C4B3BB5C7266A481001CAD07D12051A77E31603BF47C62DBF959C89774587111DB1B038AE834E0A08C27F2B772A967179A9BADA1AC12BCB8FD3B06CA44B3F11A6762AB51A9A0B67FB83DEF8C9A712A1469B719F2557E5A03C6BAC808D0E0AA304955A3E961618920D0BC2347C74AD6725A9A855D1D8456D2C26ADDD849E59B7CE7C85765064ED6D63039E368E9F18D4FA11E16F8CC88BB3FFB40B4C6269996DA8A6B5586365292B5B1C78BF4161C171E2FC7A6A8293A96D61D683275EAFCADFED74473E30A1026809076A1025398B745BE723A78E008C85B558D2B76392F5015D1024C171C0FC6C7C0C0E631BEF57166E660269231C3216FB08B6CFF0A420AA413EC1285B7B5AE9FBB15F9FA6B8AF29EC061996A7612DE524C7E0724766BB51E1264AB50C3A095815645B1D1021060B90C96555E8A001044D16CFFD7719858065EFCA6C2654EA25506F0541FAE242DBB154E420C0DD4E13A79053B431B7C00768BF0F781810A0832A2B814C5517AA1A0949523E12AA35893912256A7370BCD9FAA30788B631B87731CC5C831A26E8F48AD7CF9C935301AA8CB006AC59FD2EA5BDC1736B2A5523FF3C4D8F429DC037292E863A087BB29CC2732BA30BF11490DBB1F3ADB3448D6110A774B25D242602C250999CE69D1B32AD3702602E6D28FDACDBD2A03546764C4FC1C62C0EFB3462C7C88AB8D94E20B +sk = 0FCBAC2FD83A9EEACE0215C784E20260F0991B225897E94ECF93368B79565B478731537EAC74550CD599D5268E03A25CF327606686AB8864677907A3C3555018B478FBE125498652D5259A31C2B4649C14C89BBC5758A9B53C64E95BC9CE30C306372D431CBC642C0D60E25136C3919F3BB48B280B9D5CA0B21BB4E1510AC49AABDF02C9FD66420B475D0731918A4A5D3C7A963A468FB7A86C128988EC36C34F475F2B87791F5604863BA6DCA297EE29238BA79EEEC5096E9B336CF0B24DBCC9FEB8BFD77AC888554472D7732E7492C231302A073680C684870B86A05592355BAF2620B51DDC7B17C9328D7A74DA6367D9EC2B87E9221C297B5398CFB55C10E8A68323AABBED806C2272C192FB180E7A5B958A02DCA5C55654A43C74216B192522BC2A2DC05BF865062CF56839831EBB837A3ED8C7368C15933730667B7463AB7026848BC9BA14616B2E88E17ACA4109B5DB56510B408465523307619FCA752919B947EB40E5E8C19A7B4A9099734D648DAAC8C81C1C628C895400E245DF8A324899273EFB441B564305EC48AB305C69D37E846AC9B77A2917915E82286DDB397936769BE7E37FA7F27A003090C7F2B9B395A41370B5A38C07C2D8314627267FA06BFC416D8AC1155DF645C6150BEE70C4CAD8C6A5C564BA2571C9BC9BFAF0C2D12578C8198D49E1414CBA5749D712556A537A4131F3F085F9047735482E23342B218101AD30122113060CCA4196F778C77CAD2EE58B6F23071A85B79C1215F0A7C8745ABCDB768C3C26042D09A9A0355A5C45745D1ACF52C205B949ACF581AB75CAC74F2364406A43A74269645166FE167642900D169A1E84929DA4CB361E80C42DC702A79364F1D664528B6CEC667BF230078AF06A0B48466DC90B34EA7101512E37D8BA3A351D7023AEE652351AE514B8D217FAF09A07654B0CBA1850041D7206CECB05C8F6703F762C97DBF82255DAAFCC3608E8891E3AD8B3D4E18DBCF6A1C2E74CDEB87D15236D70943DAA722481692890A548D7C69A14FCC1155202CA4941C3900B57A452F281091A94781C64A9583C8D302C21484CC6159B88A931AEDC4291E097982EEB0528C152A43B97DEA2A0B36922FC60C226B61068C792F377B9F655940D73702D41BC515086E8F9266C53A4C15A35907CB2FC2A2F19BC5F974034677A33B648322CC9BFCC6B947B5346DF2044249623E53430895295327C9B35F59ECD4A9521F4B93A4C031A624C12F40BA17B9F36908E462B928AD452EC74B84F9B5C1C69660038C85D6743F8A5A65B3787B5640D683B7A45009A1EFCB5E50A35244C9431F21F1B6826311673832CCBC1794FEA917268F5323726698F67BDB41BCC012218929649C972149393845DCBAC7FB58582964405D4ADEB814037A39E512C3FCF72A22AB70E21FBA3822B493DF9983866412F0439E1A613914042C982739031949B2780D8133E13E632FC4281DE567A333C5D8AD458B848CCD65BC87A8B6B29134556A6780EB7B02E4437AE69C09E304210D5CCE3CA3DFEF261A809BC5DC44787A20AFFF49F3E0156E7B428AE1CBD3292C9D818844D4767342708E4016EB9BB0F7099876C26729F443E7CB3B9666441DBA01C8397953F586E3DA45789C28969078E11664CA1554ECA81B9542BAE2EA8CC12B44E81B3354818141AF0B494543D4674160A086F7E8755A87258E7E6A6AEB96955286924B42636E04583F74184133D8ACB9067925F4969642F274085F70FC12361FF96C3130B143E23797F2A3A6CC757C97454CC8AA5D9C062F9254F4CC7335B44CB66DC712B4677C290CCBBA08CFC3948C535BE29F44736A23B4C8CCB3978404E419A08A67AA555BECB48BCC161CBC5492B55E3498E74BB515C28A7A44A3AFA0148EC3411D82A1AE103513074A13938A5FC17DFABAD006D90455B4B5E45079D7BBE956C7A18A8BEC9A64C1DB72544CB00C6997D545AC7E3BC5C6565885536AF486417E728CC99C78CFA12A1F7697F1AD26EFEB7262800AC4E0121E766AA9BF0A74AE635074C62FB6CA79975761419B12A985ED7A2C8788C9020462FB5764C087681BE1595A5EA4EE7234AA2D22F4119B559A536E0DA0E8D0B2E493C2B5BD576459994ACD684A81A0955684818E1B88E348446A22C9143A4EEFC7D8EC678624763D4548FE2451F078582C93C986B0417E1AABABDD76DC0532E252B59E47370E81951EF75AD48C223316A40237152E3508EC164C7375594F73B5F0483C560F52F250AAEF28431E9D1B2B9DC650D2371BBB7C8360C72369755BD8696FC5C83FCA76A7FC02EFF54CA60579CAEF6341385AEEE34C7182445BFDB549BC59F70B76368DA88D47386F75968ABA093E8F42DD3C7CD68C8028A90CB0C93CB44D42EF9D15E6CA978ED5B88914C4E20768028F2C927A33433D33C5E6A45A6C5AE8C252A83E68EC121347B025865F26912B89A9DA7472B75B9ABA75581852B97D27EA7C9C5C7E8BEBC0094C01947F43A2C6501C97E43231310167ECCBC4C3A2022839584A12AD5B51B4CD308C94302E58C70EFF7B24FAA051CF548B5A73AB4254179EAA038EC95D4D4182D2971084CB33A6CA1106076DFA76EC0C4B3BB5C7266A481001CAD07D12051A77E31603BF47C62DBF959C89774587111DB1B038AE834E0A08C27F2B772A967179A9BADA1AC12BCB8FD3B06CA44B3F11A6762AB51A9A0B67FB83DEF8C9A712A1469B719F2557E5A03C6BAC808D0E0AA304955A3E961618920D0BC2347C74AD6725A9A855D1D8456D2C26ADDD849E59B7CE7C85765064ED6D63039E368E9F18D4FA11E16F8CC88BB3FFB40B4C6269996DA8A6B5586365292B5B1C78BF4161C171E2FC7A6A8293A96D61D683275EAFCADFED74473E30A1026809076A1025398B745BE723A78E008C85B558D2B76392F5015D1024C171C0FC6C7C0C0E631BEF57166E660269231C3216FB08B6CFF0A420AA413EC1285B7B5AE9FBB15F9FA6B8AF29EC061996A7612DE524C7E0724766BB51E1264AB50C3A095815645B1D1021060B90C96555E8A001044D16CFFD7719858065EFCA6C2654EA25506F0541FAE242DBB154E420C0DD4E13A79053B431B7C00768BF0F781810A0832A2B814C5517AA1A0949523E12AA35893912256A7370BCD9FAA30788B631B87731CC5C831A26E8F48AD7CF9C935301AA8CB006AC59FD2EA5BDC1736B2A5523FF3C4D8F429DC037292E863A087BB29CC2732BA30BF11490DBB1F3ADB3448D6110A774B25D242602C250999CE69D1B32AD3702602E6D28FDACDBD2A03546764C4FC1C62C0EFB3462C7C88AB8D94E20B2B757AC0425152BEF72ED852AB1EB44F4359499407BB6A020FF843A31657C5FE99DAF37400CFE59841AFC412EC97F2929DC84A6F3C36F378EE84CE3E46CD1209 +ct = 269412479F44C884A094A5B259F76D28CDCA0361BA64C402491F98789F0D46B7E31E7E93B17E8931AA3F83E3D6B6DF59B1DEC49C1532EFACC9718247529E38856FC982E92AF949AE1BDEDA805E8C43E05D2D8C305E2A753F322098483616C9D48568BB341C3818A7316EE7D19145238C38CD3E04DC1CC6E7934783D3979C0827D0BFA69E5BF8F8A8F3B0299090F7468E1094DDDB0A231E5A516AE2F38275D2F125F850D7B3C6137F0DA50BF680F13BD7F001E978A54C06BFECE1401039215753BEBCCF7B1B99F219E4D562E235BF48976CC59F3A3AB470ECC89B426787AD39C326CFC2E53DDD55FE02D0863C0F9BF1B1E1EF0D397990F9C13A6993D63E140A7F936B8048DECC487576DF2722A00335ED4C620452188C5FE9356169D8C48EAB7E2AC66471A7E35BED338DEA11333B190DA230D8A8063CE734D208141C9EF622F30E5CBC1424488B708F955B5FD1A0E613580BBA1866C1A027CFB83DEF2CC92063693EAAF7C087ADCBAED63F891E2A9CB295659E2B72B0C3CE8C6DB44B9DEC84A0AE491D07DBEBF355C4C05FD2940B30774DDAB5E0E448245D39E13634C1B49450B0E77F9F22F76C053884882C4F32B34748140A4A3DC3A296E6577F84CD047563067ACBB315961278D667E6FB67325F3987A37149F463F2F43416DADC28679A0EB3F1D20C36AF04DA09384DA537AAD03BDD880AD06A606CA720A42C4034801E5DCA8E250140B3C09B9F7EE28E242915E8B23C936529CEBE9C887095B5AD25798C10B474E4D2D682E3C5E7C83CB2B4ADE983AF27636A9C2882DE397DBAF486EFB4464D19F72AA8C6436EC561F9387E4B44B9831405B2462D8293A954688804E2BC620BF767CA7468F5A0431C4A871D521C416A36C8C0039D02CAA91A633838B83B6AE7879E2E9EACA55C1792D9DC0C098B243406A773B79BD7AE46A377341766A1FB173D38A32AF97C75F395248402899ECB0AE883A6E96EC34677E8B14293E8E5F67CF4ED94D4A7EF45B7C3DF12647D3D9DF00A6FCEF8221050E861D539A86438D7694474449DA409589205A7B513C434B95563AEE108FFACDCCD8CD54505F55E086BC615D15328BA7E72C81737E1A2E8B6DC14746B21CAD2273818CCFAA1C9B01B22D347554533FAF1524BCB2AE638DFDE9955F74CCA13A9FF82FD9EADC556704626214E2C928DB464CE895819A4A12D4C4317FB840E8444EABA4C412805D63AD74EDDE6F7A9770FE679FBB028485F210725D0DB99EB221AB67F60EDE0C6EFF26B914B7D887A97F80C752C0035D632D903D2D7351EBFD0B07B50935AC4054787D83B2B98E23C1C8E03E6284B83569C177194FC2B85E9A2FF15FCCB4CCB66D7AA53DE89167036DF23E4DCEB6113407E6C14DF4847ADFAC1628464327F59A37DD26D60E433D4DAA8BFE4124F225E339D91CB9D2A57FCB5968488C29514CCED169E8DABB400B26EC2377D0EA71C1FB3958E4927EDE45DFCB024AD7C16550C69187FBF6DFD055322725160F8C32D8F48DE48E0A52872058A7C6B380510E028260CAE +ss = EFF5E4CE44FE0D0B77CF8109D46C8A888399D1608AD9E2248181BD205A0B23D9 + +count = 8 +seed = CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41 +generateEntropy = 0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +encapEntropyPreHash = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +pk = 764B51D1DABF923518DE898C5E7CB5E0066FD69522F5889DC05C41A472C983583333132052A1C93A464120B325764B8665CA42555B98D8D6A93C88A0A383AB51280F52873F2BE26E12C131677027C616711D478342CB424B0463C88161ED84BF6E869ABE9CB915D13534D2756DD72343359E9911624DC7C6E828B19D6CB178C43A5CEB9360D2939DF2744ACCB4DFE8AA5ECA35BF87C6BA265FB4AB7C4888516EC91E52C4030F5453E6BC9103B9C19CD83E69048272855B11B8AF3EDC09B04AB31179BEE59ABC76726FBE9612D271B7010844F62535F2F30D8417C35F17C1619B055FAB6A0F5458568C753310299FCB335A7697E7CBC9B9EB1B14AC2D0DDB765B266B6D68BDB5B0236895328540B20F91BBD2910625E674B33A4F8B6C1B4F66C4130C2E973AB72D809282CA63EDAB71268C02A9D020BFC805410AAE2DD4B699448A56049D1E9A58C5FC2ABE159DEC69C5027099A3B57D3A2560CE24A6F5017D32E00F3078B792309384421878CCA555B7065D57537C804E10BAC052788769B7C1121A78911A153FB56A365A2F97B070D7B61724D0C4D14C295D78BE57A8AADB873D3AF6B74D020B8654CF48543DE8CA22371A48DED585B7073ECEE0C44EEC27C85B5A68F6B454B0CB10692039CC68EC2C2BF892804520C71BE5B7BADB807B4059A3D87D32548BA3E4B698CA150D784A8C2C35A67A8C92C68AC0037888B65A4C9800BA7A1EC050627AF648FB61C87CC55B8243545AA514CBC550A8804C8598CD35786EB8C6B06077A1E2D4344E4A6BAA789C305B6326E0BBD4402DBE26CEC08A7C1A19457BC2677F15B984A74FBC52CDCE48618D50C47400011B392908AC2CF08A579783A80FB2990CEA90EEE90B7DD81E6CC9C961372D8C720D7EB223D5A6A16D4571C1A93213B32289934F7B30A63527C6399920086940B7696503E623E63A050F4B69810B6E6F6729E5782B572221F596A09A1879BBB46A62A955043A30A2AA3E62E02CE1AB6F3D03693A8CB653E361D8783FFA37274AE06A3F2292F1A6557182006E493FF2653437A64DBEA950BF6A8CA8836407FB489D42A6F6257770310F28715BC6411C81486CEF3CB9AB500558F070F4A15817F8C177D63CAFB176CAF3B2B1CB7B7254C18FE15111FCAB9E9A9682F41C9FD247EC532CCEF514860A3FED330255323DAFE46EED198041D732538C9424D43FE2F5481650470F08906791B2BFE65A445BB26AC87D9BD04AA648A54DC13A137B60E5C2779FE4B5A866620DC2829D42384AEA9AB1552FCA920F8929B7BAA059DEA53E6A5B3E492A6E45B5AE11F6AD24D035D4246A0CD53436687A0204A1DE29AAD2C8B53AD4B938A57C2E29555219544FF64115CBA2668B54C6EA8779146980B58A2E669124A81ED4420C87B0601DE23E3CCBA915FAAD0C2B47EF6238DBA9449274C64CCCCD85E91712470E8F9A2866720059A8501C7762C0883CF9827BFD62BDC0882EE03B457BE2B2794B8BECF74EC0DA4684282200A294C13C8A9FF376C1187911121BDD886F27514846F740B72AAD5544CBD97A7E208635480ACDDF404FC067C82A45B5C97829F06ABCA5201429E9A516F66E65D07075CBC0C60C2A9734BAADD68F421617FBF9515B569FD08BF3AEF948095DE1AFE74BBC3BDBB45FD8F92EDDBF0C682C81A98F930F6165 +sk = A5C7981510819EA27D27A945A0F6619D730DD196B6F3A158A4C48ACFB82D1C348540160B0CC665C43C4C0E4567B46867CED06D2CF228D0B64706227593DB7392395B7EA95360105C1BB05472787430654AA03B6E894C2ADD2A0467EA51B9486F3DF18274C0A2079459DF3B9AEAB15D203B466EA426911572251B0C8FB51A31AA142BDC4142E393D3C527C841A03F796E0CF7CC71DACB47456FDD386527BCCF6E43013EEB755924A22E3A55F74A8974B38E06908349FB3DA5887D1A041C8ACC6F07A75198462353942267D7600D5243095BB012D2A70BE0A3FB2BB599832F8AA68652846BA501BAB3AA574AD08BC991C8B86717B87A45041657D0264F35F0C2B70324EAC43D591202CFDB9A7D357489F70F86D6308D3382CF9139106CB28D947AE3BC389EF18B728C1568436B3EF80644009A80F01EF550C794011E44F2812EF507BD55820A872B90E797626B8EF2D94012B4CF639BC5C8A7B87306753F93CB12E46A66C4B2053C037B87C51436CC83B884F7634A6950C419684AF3B78D41006467105F753194144539DF45AC7FA46E71815F53D2304B474A434B02517B083B058AED078DCF86746313BD8108148EA34658613560CA722A126DDA147AF8C5733705BC8343331BACC5B5B80E424CCF6114955056329A68A2A6403D65197C21DA02A390C41EF713A814A798A434145B9E3A5C31A9614CDAC8A8BCAB6B5274490F5C45B2A307F492C28FF40EE39C2068A5826E8466542559E9409FF11B463E9A4EBA0A2172EC8EA6332D3A5BB66531B670C52CC2F8B651B513E60A9E64795369E0C2CF56A9921669299B6B5399537E112AC358112810ABC6945BDE69AADA92552A10219A630E26E4AC7D9B5C7469A960AC64A6D127971296C53A15DF4C847D061E69CC030B9CABC6E58903C5ADC88882CAC147F2888263ECB6AE97A9B2AA245F131E2E2939F5C8BB8FFC012CB578B9BABF90DB062502B1923CA88B35C424FC6524128FD1D7B5CA719F5A9A538A51A97ABABCE07B006EB701AD8490B74462F93648FC39A2004DB6E951B4C8219CE49395891594353B92B6B496D09376FB28711D87221851A5FDAB80CC52A6352C062F06C80F891DA2A07573B42BF0F6CD5D6B63FD4B1C5BF2572FC8460385A642E6290FB79A9B1CB18CBCB34BD87F7EB595F0598C67709D72011FBDD07A0EB6616A88B8E33571BFA7597BE4CBD6976B93E32C2C088DE3AB59DCF2234E553A5B2AB143C46DF13211E816AED6D02BF6C13FA7F8B282237F249AAEDBD3A6FE8771014C1B811C05FE86102C0B0E7E9B961C1000C82408D8A8AA381552920803418C49E1662C7ED8C3D35763C510585A78664EA0012A8A02F34B2BD7E96EE5C298DC296537C985577CAC3E310568353EC2CA8EEAB4BB1EE2393D5B3CDD25305B148FD8AB11F60B5871E9C9359A46A5DA003E98B61D82C51CD9262764301C86268DB87FA6273F9FA3C35B1C1FD822AAF2F74EDF73AB5AF9175070BDD7D5CC7600A516726C3E49348D138D19836391A54954AC4A0C029B1441C37965422019C2CA49CFCA81317A211E22EA2297B865DA163A0AE2A9DC25701E71847A05754CB733620A824F090D591C51C345420E226B8F3B846FD356E78B87764B51D1DABF923518DE898C5E7CB5E0066FD69522F5889DC05C41A472C983583333132052A1C93A464120B325764B8665CA42555B98D8D6A93C88A0A383AB51280F52873F2BE26E12C131677027C616711D478342CB424B0463C88161ED84BF6E869ABE9CB915D13534D2756DD72343359E9911624DC7C6E828B19D6CB178C43A5CEB9360D2939DF2744ACCB4DFE8AA5ECA35BF87C6BA265FB4AB7C4888516EC91E52C4030F5453E6BC9103B9C19CD83E69048272855B11B8AF3EDC09B04AB31179BEE59ABC76726FBE9612D271B7010844F62535F2F30D8417C35F17C1619B055FAB6A0F5458568C753310299FCB335A7697E7CBC9B9EB1B14AC2D0DDB765B266B6D68BDB5B0236895328540B20F91BBD2910625E674B33A4F8B6C1B4F66C4130C2E973AB72D809282CA63EDAB71268C02A9D020BFC805410AAE2DD4B699448A56049D1E9A58C5FC2ABE159DEC69C5027099A3B57D3A2560CE24A6F5017D32E00F3078B792309384421878CCA555B7065D57537C804E10BAC052788769B7C1121A78911A153FB56A365A2F97B070D7B61724D0C4D14C295D78BE57A8AADB873D3AF6B74D020B8654CF48543DE8CA22371A48DED585B7073ECEE0C44EEC27C85B5A68F6B454B0CB10692039CC68EC2C2BF892804520C71BE5B7BADB807B4059A3D87D32548BA3E4B698CA150D784A8C2C35A67A8C92C68AC0037888B65A4C9800BA7A1EC050627AF648FB61C87CC55B8243545AA514CBC550A8804C8598CD35786EB8C6B06077A1E2D4344E4A6BAA789C305B6326E0BBD4402DBE26CEC08A7C1A19457BC2677F15B984A74FBC52CDCE48618D50C47400011B392908AC2CF08A579783A80FB2990CEA90EEE90B7DD81E6CC9C961372D8C720D7EB223D5A6A16D4571C1A93213B32289934F7B30A63527C6399920086940B7696503E623E63A050F4B69810B6E6F6729E5782B572221F596A09A1879BBB46A62A955043A30A2AA3E62E02CE1AB6F3D03693A8CB653E361D8783FFA37274AE06A3F2292F1A6557182006E493FF2653437A64DBEA950BF6A8CA8836407FB489D42A6F6257770310F28715BC6411C81486CEF3CB9AB500558F070F4A15817F8C177D63CAFB176CAF3B2B1CB7B7254C18FE15111FCAB9E9A9682F41C9FD247EC532CCEF514860A3FED330255323DAFE46EED198041D732538C9424D43FE2F5481650470F08906791B2BFE65A445BB26AC87D9BD04AA648A54DC13A137B60E5C2779FE4B5A866620DC2829D42384AEA9AB1552FCA920F8929B7BAA059DEA53E6A5B3E492A6E45B5AE11F6AD24D035D4246A0CD53436687A0204A1DE29AAD2C8B53AD4B938A57C2E29555219544FF64115CBA2668B54C6EA8779146980B58A2E669124A81ED4420C87B0601DE23E3CCBA915FAAD0C2B47EF6238DBA9449274C64CCCCD85E91712470E8F9A2866720059A8501C7762C0883CF9827BFD62BDC0882EE03B457BE2B2794B8BECF74EC0DA4684282200A294C13C8A9FF376C1187911121BDD886F27514846F740B72AAD5544CBD97A7E208635480ACDDF404FC067C82A45B5C97829F06ABCA5201429E9A516F66E65D07075CBC0C60C2A9734BAADD68F421617FBF9515B569FD08BF3AEF948095DE1AFE74BBC3BDBB45FD8F92EDDBF0C682C81A98F930F616553B9D62E64F9069D9FB94EA2C0806459B201531F4FDDD708D162981CC1FB3757DA1804DDB5AA9B1C6A47A98F8505A49BAE2AFFDE5FE75E69E828E546A6771004 +ct = 106849C5DA689EF3A848336B4AB6542F621C0B9B5E8C5AC0B06D3BDD7336EFFB87DAF2DB0ABA609ACB904FB291FFF9B6CA74BCFDBF7C563B16C0553E608E8D094B8C195BCD2B2D58FE731D4A4660F4743DFF2A16267490F7F00AF42946D0981C7AC0394AC78A44EA1D4CE07751E064A27D8B223ED37A2AE3B74E831CD66855545AB08B7D28473A031A33BD606F0DEABBB62A06812CA11D9D1C33A70C5D214F42BA16C5CCF7D0E9F2B23C76F4E9ECD8D9D80CA64BD04E473A308539570D5959937D0B7670D8554D82AC97E8A0AE8497FFAE014DDBB6A138B37C08B75E8110F2F9BD372153CDAAF3379E88070C16F177D96CB115E14863C098AB2B3B207FECB96122ACDBD207FCEFDEF90AB813AC6D5E1362903875D5B6DA35276069C5C0D3BF1F0261AEF6719EE0861B3E2C5938DDE47860352D02E354C363CAC9D0CD944BAC7C61000BA976B20516998672EBA11E68785C8B8603C1BECDACC1DB883430DEB8501638959D489D8F51BA28BD299BCD46E9188031A906C06D0F54873A8D065900822372D46C9365CE129173201FF301AA423EA13D35896D8CE6491B7BE61190A803F9C53847C22205D011504E1B4C4E98EA395DAC99193B9F44273EC4E0F4CD6468371CABC76708831DE5201ACDE1C5A3A10F51BF5F986E038F26471A1FDC7803762EE240994CFA3C2E9A5C12C4954FEEDDBF49EA264645BAD8BEBC1FF536B02BB4207F2FD1B2E70B3FBB6C23CBDA0DEDACBB1F090E5CDD5210B650990E862F0A6AB2625871FF91650D09D7EA4DA7DBF6CB166AEED23AEE7ADF2379267C708FC5D22BD2C12F22B3B944E04A79C10FFF474A982B6CBF699DECE2104DEC8EA7F6B4D9E486CBD748CD9CE83E76F3F05111753F021D1629D62CD16B0FC4A39128B8B398179F1B33D94017DBDCEA084A9508AABEAE589E6365D48111E849D1656560D13844FC4AD7A2D0157E706B0BDEA00D60240DF2C5D70C223162241EEA92CCA23969CBFB3BE7BA4FD278D831EDD8DC941F74D21E7B296456303D82D4B3E6E5058220804158E23EACA8068354676B94577505D6414A27DE9FA178AE851346FE3254A5F9490917ADB080F332C2F9169D313DAAB26C034502E311685CD57EB66277685EC7AD6C5D53A02909128A348E097F5E0F7B75A7622B88818F8971C0840FA7592D245E32ED9B4A958370EAA14010A0BD92D28220E0F9CD7EFB0C0A296C46DEA9819C6AD0861164C39E7BF6F1B7AFB0DF2D290E233A30B1D6C27B74D2A4F4DD6B3953ADA3A7C0E4E3A4F4F07DDF2DB4F7460204761F717FD5C69F156C15E8206E93CEB426FE89FDEB4282BFE746F50D0B4BF9E5950CE8F03ABAB8B211BC619F580678EBBF9AEB439578BD3F9ABCB44F2C53B7B84495C876B2E1911F9F1ABFAD34122B8B7B660F5D2E84DE2AC504A59AF5E0C722A9265B83B8440B73B9CD130576F3EAE5525F757E23396A755619349E5B168EF891BD742367FF2EE5C5628245E7FC0D0D03FADCF651B4AA7C33C69C3E1F580DECDFE50263200D5085E0D8F19C2AB6 +ss = 25C35F5858D03291C0132C970E6E072D8A7B33419B984B391A12891F878D981F + +count = 9 +seed = B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846 +generateEntropy = d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +encapEntropyPreHash = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +pk = 5A1278BF11B37FBAB1DB212359473012F3B545301DDC833C69A75AFE16744557B5E28BC0EE895DA16C2C5DD34FE6783949D555E580C1BE7994BB008DAF27A47F554932B87222E82EC670490CA5139FF49D5ED896218825056A8639B31D3AC8550356A408A01404C6AA9C2B7284E7C7C27036256B7902445DDE00630D81930F4CCC518B9EFD8AB24FC16A365B8068C90F7E09BBD23C2A6AB12792D245551A9894F704042501C8FC49EEAA0132701E29A3C97834530A7C61F1B8440822CD1BB6B11DCA2A5951B4DEB0B1268C2F5AA8CF76A6BD0BE3013A37CA1A903AC634405ECB3714BC54610BAA63BACF0A263D8CB018B03B0A286083998A7E8B2A573E570179712130A19F9EBC2337D43926F9C96460996CC03199D81A0E19259DA696FECCA7906931A787A5C264826099A3E03339295B587E7A4EFEC6A11AAAAB057AA8689473F1F211C6D85499C46746BB00BA687A17877E6650C678D13861337FAAA7045A16B8EB7173E7C08B6394B5F2B99EA3083BA175C55D350FD61B73AA790CA6F479FD4B01282B6BAEFA00A1946F6DFB855CE7BD50389D42856823301E01A228AC754CB65A0E323A0943B75741CB498CC499C8649B6BF87E991507194983AAD1B57994B7D79BBCF2EB3B5F8734CCF3CEA2662E95D486989144AEA22C94C363571AC7DCD81F577645CF19B313F849B422AFED963CDB701395020C2D18601A40A42429896AA9B0B1C10C4876928AEAC59862414E143722A0B94746ABD157343D15BB9FE500763B18C61B184407449B1B5BA8FB1554E4BB58AB99FAAAC9CDC3B698E64179B089B786204BF95EDA86474EE799440478348989C91C3462446724340CD2376C682907EDB58C85A4CE3EF46CC5D0CA345590AB14844B224735DC05E0E66EDE94258F395FE867AB9D8C1B0FA80743002A15DA197614295DC358F40758C9CC05E45BBC659B93ED611AA58845D94ACC7AA75DEBA56D4D83C640C252975BC3165254C92957B78C9583B370AD785F2C16CD5CB9913839939C7293E6B956E23CC5D14CB3AB2A2E94F179BB076355157920085236F60B84449D43AC89C2B46DAFA6B784438F3510BFC48357A5681043BA7428583BB5E912B08786562579DF58A41BDB82114344B3EA3574B997F8564248210D4E50AB2277100B9A5423178B1F138E9D427762253CFFC3CD095CB53A776F4FE015B5168B1A9759AC4ACC77F90C69B307192B7B866753872A69813B1BCAAB5CBB8126D8998E78D99F5A527992B89495A28E3FA83E75337CA2B896172AC244AB7E30761C8E3A00890046E5F599EEAB65BF1A4CDEB5791CC10ADE7197FB5BC754233F3B10C9BA2240ADFC61C05231C36A6CF71AA752AB3C95C3756EF9373B677105D11F86E68036348BDD181F27407E344BCD297CB02BC44F077976ED588D6A846C2F839BC9BC4872617BDC17A7BAA97AF9A9322FF015956678E8D622CFB1A11ED929F29BB1F094C17F49417C09C1C443369123CAF8701199C43BFF97034EFC6999424144C9395D9063BB153C0ED82B1C5659BFB23D4CD2C758A26B6C448525060F686BB14873CBF5046B3A3033C5C8081027BF5E3C51F6FB6A1D54A77C46B0EA4299A9DA4AB03B95F9D3601F553D46800F661E2C9A7E548CA42E385CC6A0678F9E9D268FFCE02C4B465A46773432109A75 +sk = B04C33B257B199352A85B55624F1A1A42B2AB72C4810B839B2BB2F51A502CD498AA258373EB3BD43E03973D129E4FCB61DF58986809EC4EA4333659F03DC0FAB236CD4E815D3F9524E90A28A3A0AF869735B362FED9837855429700CB815C43A6E650E54D6267A832DC0385696274E1E73A12B5960A8409A4B4564DE909B797771B4839782526FD69ABF516A73F9EB8130F41CD6103A6E67C6724186D1C709D3D90141B1BC1C028E28324DE4846BCC6837FC243C54DBA144C40FCC6223FD19B8F54C11BC0982FFD366530ABAD387946E1495A3C05D9CFBB62B28778905AB7D576610A74B3DAAC9767A051B153AF7C6BF0177A4074397BE410411CB33DDCB895091990DFB85AEE15E9F288D01EC5628034A4ADB01DA09283493BAFFD36D224B1EFE096289A2AFD427B82F8B04EA44319F4A16BB07BD21026F2EF550B919AD01CB3744B37103EB54E62400E03367001510776698E28B4FC367A77F1B4690CC2916E8CCF1FA55AA3495014724F1E66EF7CA8283D917B501C931274D9808A8103004176BB69783C094BBBBECD5B90EA14E7CDB9768498B22332283F6A079991988AC6A85BB591EF299BC57027B0CA9932A41C14C193467374F133BB8539C2D5164EF11B70B4A2CFCDACDF6841CD835C4F4E174BE3C26B55770ACF4137666A431D669FD5775A71749922C0B223ABE36284FC880C3AA2A41F45A4A299C647D6738585287F7A47B88EA1C6C088C6207646D99CEF5F56A2E02CD3EA85202C7725DFC99D04B2D52600F0F89366A3A83F8DC74E4A27FC58A622061A6332403AE8CBD0179149B841F5E0BA193EC237AC57A4CD5528C10545CB75E35A20C3CE63950C09A7B0810B84124F3A00C9EBB67BDA9B2AB42113E631123B4A85897160637A32EB856D55C2905F7C655D40C84E92E773056D2392D43E33C4F9256DBFC7AA0683802D04D218139F829AE362C1F48096FE47B09756C36873CADC5300CEA8094E6F8925C1B81ADE69FEE5420B7E94555286CDB596E08CAA81F758022B3A949059AE91AA9B78A825703CD53D1235800681DBC7657A777BC267637CA2954C09344110A05E2BB90A83F95990986FB559BB1282778933631701393B705A5C122EC3645C1B364367C83444D30FA438EB3A478A0BAE14270CD49556399085C566D9E6C467DCA66A3F36370693AD5F86A9932773AE5064E9BC73FF7979A5510C88198BEEA7EE2AA494EB046E4D70A3F9CA0F88B234F6918F7EB41DB97A327654836510276E0154E7A4DFA088B8ACC5F02F598D1494BFBD07C3132C5EF6C3B466606B3D93DA2E69C96744095435FCACC2D24C3016002B5C4B988877CCDB9233C490A8B121BA7821B529DE85E638168B0565D50F735D1CB54CBA91CFC1B9EFF882A643121E877C43B6147A2A8266196346859CE53340208253CA419276B884DBB3B7A30AC3DE983C75AD73995A0B62DE7563EC9A4A715BCDF376DFB6433DE691C54E660F4AAA4B184015026B6189415E66C90DD32C0B015AEE63B5D8B3CB9EA206E45AB4938BC86FC54C7598C6553C29AC34B2213B90AFD144C8B4629A560382778B28D666667CAAAD49633A8F985730318EB033374B5CBEBACC7F453CCD8E77C5A9ABC12DA1BC1733E5A1278BF11B37FBAB1DB212359473012F3B545301DDC833C69A75AFE16744557B5E28BC0EE895DA16C2C5DD34FE6783949D555E580C1BE7994BB008DAF27A47F554932B87222E82EC670490CA5139FF49D5ED896218825056A8639B31D3AC8550356A408A01404C6AA9C2B7284E7C7C27036256B7902445DDE00630D81930F4CCC518B9EFD8AB24FC16A365B8068C90F7E09BBD23C2A6AB12792D245551A9894F704042501C8FC49EEAA0132701E29A3C97834530A7C61F1B8440822CD1BB6B11DCA2A5951B4DEB0B1268C2F5AA8CF76A6BD0BE3013A37CA1A903AC634405ECB3714BC54610BAA63BACF0A263D8CB018B03B0A286083998A7E8B2A573E570179712130A19F9EBC2337D43926F9C96460996CC03199D81A0E19259DA696FECCA7906931A787A5C264826099A3E03339295B587E7A4EFEC6A11AAAAB057AA8689473F1F211C6D85499C46746BB00BA687A17877E6650C678D13861337FAAA7045A16B8EB7173E7C08B6394B5F2B99EA3083BA175C55D350FD61B73AA790CA6F479FD4B01282B6BAEFA00A1946F6DFB855CE7BD50389D42856823301E01A228AC754CB65A0E323A0943B75741CB498CC499C8649B6BF87E991507194983AAD1B57994B7D79BBCF2EB3B5F8734CCF3CEA2662E95D486989144AEA22C94C363571AC7DCD81F577645CF19B313F849B422AFED963CDB701395020C2D18601A40A42429896AA9B0B1C10C4876928AEAC59862414E143722A0B94746ABD157343D15BB9FE500763B18C61B184407449B1B5BA8FB1554E4BB58AB99FAAAC9CDC3B698E64179B089B786204BF95EDA86474EE799440478348989C91C3462446724340CD2376C682907EDB58C85A4CE3EF46CC5D0CA345590AB14844B224735DC05E0E66EDE94258F395FE867AB9D8C1B0FA80743002A15DA197614295DC358F40758C9CC05E45BBC659B93ED611AA58845D94ACC7AA75DEBA56D4D83C640C252975BC3165254C92957B78C9583B370AD785F2C16CD5CB9913839939C7293E6B956E23CC5D14CB3AB2A2E94F179BB076355157920085236F60B84449D43AC89C2B46DAFA6B784438F3510BFC48357A5681043BA7428583BB5E912B08786562579DF58A41BDB82114344B3EA3574B997F8564248210D4E50AB2277100B9A5423178B1F138E9D427762253CFFC3CD095CB53A776F4FE015B5168B1A9759AC4ACC77F90C69B307192B7B866753872A69813B1BCAAB5CBB8126D8998E78D99F5A527992B89495A28E3FA83E75337CA2B896172AC244AB7E30761C8E3A00890046E5F599EEAB65BF1A4CDEB5791CC10ADE7197FB5BC754233F3B10C9BA2240ADFC61C05231C36A6CF71AA752AB3C95C3756EF9373B677105D11F86E68036348BDD181F27407E344BCD297CB02BC44F077976ED588D6A846C2F839BC9BC4872617BDC17A7BAA97AF9A9322FF015956678E8D622CFB1A11ED929F29BB1F094C17F49417C09C1C443369123CAF8701199C43BFF97034EFC6999424144C9395D9063BB153C0ED82B1C5659BFB23D4CD2C758A26B6C448525060F686BB14873CBF5046B3A3033C5C8081027BF5E3C51F6FB6A1D54A77C46B0EA4299A9DA4AB03B95F9D3601F553D46800F661E2C9A7E548CA42E385CC6A0678F9E9D268FFCE02C4B465A46773432109A759CFECA12DFE978BF0B7AD7271487CF61B2B8F7C60F389F33FC18439A95BCBB6356047447B810CC094D400AB204CF9AE71E3AFA68B88586ECB6498C68AC0E51B9 +ct = FCA7E41C5BB5460CE12E4A40CFB3E7E7DBF18E2D9D386396586475AF17A830D3A738237C05105735E9B4DCA87D114F017B50484BD0381873A5F4DA24C420B6D56EFEC00891BABC52AB22554B68A0E3D3AADFED71D3BFD75FEDBF946C55EC3FE0C050C623636FD486192DDE50EBAA7D12DD8B80418FDD64A5F7979CD660090C05893E3CE334B1F489149012C00F8868BE07AA3FF50B2C255F43040DB1F603C00C5B3C5DD56DECED7B510B96B9A1B31CDEB0E5A73CBABFA0742631D816CFC2A701EA64DCC435578512073E3BC1C78D5EFC68772A971AACDC89448B1E0BCD2B558CF709A513866CD0609A4C314BECA92E894630822C324FC3AB177DFF0EC1C89C92C49292AC28859FEADEC5BF5BDF3FC8C806F2145D0E9B3E9981C40AAEDE9ECA94747EB32DA509D089FED91578E6F7B012F91521974D722416C5EE640DC2F8E46FF56077E1370270839FC131D89C22BCC4107A1CB65E6714A9503F46988EC651E222970372B462314183D54ED825ADDA32C1B807DAB5EEFA2CBF1F910E4B2532377DA539280C9808504EEC2D43F6A24623374D4A9DD50A1F3DD250BE40B20B23CD84B7F1EE317D7D937185528EE1ED4482DCD6F93CDEE40E2469853FECAD614627CA7410E690B3BD2F0736A5C5FE53B14C3DAA2A12B2790D41FBA12E39FA647823831979042878A70313B4CAF8AC0C4FF9005BBA914B636EA375D3259D21F8ACE9D3D5D963ED085FBA924EAADB6EDEC0488CA9E9A629FC3D46D987B8CBC473E8C1EA5B85E00F03AF99F8451DBBB5B8EC72AA7D91F8F6C9B4FA03965D04D2FC652F5F76991D95463EF0D79D5238ACE1A1D6A3452ED8E6A2B482F8B0AB3C9FAB41929B104B18E23F5F49616B704EE79E8B893C998A88D88BBB3A22305EFE28A9BC526D2A8DC6B4D820130F2288469D9D8DFF20673492C6C5F3AE967BFC74162DE3502BFDF498F038F34309FF4FDBFE5DF00B0E568F49562051E24FB2ACF1489615B00DAD14627F04E2BD5B63020A77B0901336A905F8BF20BA788898C4E6754E2788D80BD4B8CE013A3173B5E7EF84F63116833631FE8AC3AF8A0B47BA535C9A88F522AEE02FA077EB056D3AD2DC2A70B22E81A8A4CDB2DC27D3DC92F28024EDAAAF133BCBF691D7F5F28C48207302FD0CB11CF8C8A7EB862243A045D3AFC6FA9E64443A1E598FB6AB325DCD4CB7CDD6E24D0B970DC6667FCD9D448B30DD33BFF1924880C4C42A59F035E9C619EB00E3E0761F994ECA9EA469479CBFB6E1F18447AE8A6C0639774B428E642BB39ABCA7A6F1624A68A810F6482C1B6634EE4A6FFFACB99E28029340EF8AE8C2B456F5D73F79DD704645FBFAAA61897047F5C3297837BABFC16970B88BC1B73E33F17B3D3E8BC7980FD98CF7CE13C3944C8F0B4049E9C281709F990B45EE22628ED9DB89ACB02E01A058E6038F1417F83A4B295238123775D87141E2A5DAA476318015EA84445FDE78A40376486F4DE25B7925B0BD3A163D8785D7C50FBDD9C5038B9A6006ADF424426567AE19AD69F09C6825923BE7 +ss = F9EB1C87813C712CC3054109ACB5F219FC1E29DB10FF33D093A5CD67DF995015 + +count = 10 +seed = 980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3 +generateEntropy = 2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +encapEntropyPreHash = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +pk = C4A90087866B29244C3641310E94B8311A1303465975649288713E79CA67A9085C8F7449C0BB9A6AB196245B0DA028CC1765A8BA0501D5E360CB3064E11554F3FC2914F1260509073B67B4A0570D7F708CA7C435EA987762F2A5A23CAE53907FC9DB26942136D72202D0A0BB10B65D422091ABAA1C21D152DAD59C25D20C016237634741DEF8CA26B9CCE3097FFD896F1BF08300282FCB7000C7E1956673223902AE5B43BC63B6806C469A4EBB8BD34B057B375E725B07EE856FCC0453379B96F89888D21A7BD5EC91F837B90A2C334A97AD70D87BDCC12892D588D06655F6103E033547CF5933EC237B21B2956E5921CF10A0C55A70E4A24A57B93F6FCAAB2A44BB079987EBA57223B4B9DEB60EC6464FAA4058283B8CBA6956C792AE8FF9184E93C2E2152823C15412C102518462C2691DB1C64412EB1EC6D75D47C82FC5A9214670B3297067E30C6D9CE0CF3EB314CC1A4CF35342AE419513EC2BD47182C4EA52626A56F7831DBDC5719F532A5A421A7BD5A115C2195D0532E7C1C0FFE40166404137A5B45D7B2CD31752E1646588021508293FB881123F61034318700EEAC429500905179B283162ED0B69590541EBA0848DECC94BD18C888170A4C030A89305FE97A2B0292390A3B1FD6AA22909CF0134A2754728B6FB5180276B7D65C2FD530B4FF48CC7C7093DFC2B418B97762C42BB0980C7F41D9651C69387173A6718038010F50B79B233187BC3A0F7C770E50ABC62E8ACBE297C58C58055387BC7711473D81CA97B6A6E6504870C0DE1D806E3603ED0B04D01DC62529434014C5068C3AB3D4A909A079947127A8A2746CC8126F0212E21A0318EF273D5E0BE16253848413C5CEA22853C6E63B675CFAC1D6590004A2BB3BB4974E79ACA0DD927607A71D4B4C9980A86E5A2B5A84BCD2E694190491060411B332AA7E7766A4C693B00EB9D68F34E5B0564DE24377D3A6D45F72D82EC24FB268537C07B81AA79B5B28EF5A657E0F8B6B2F3A4279ABCF06CA2A79401312943D1D1086D91B1AD3030D0C0BB21806CB87B56ED391E6BC6AAD974034664B4902336D6E45A7449CB656207D59367F2B142746636E44726F111603B28670F47113D28CE6BB11F464B181CB3205FEBC13CC70D3FB35924A641A1117DF5CB65FD9A69C71BB800FC22A6BC47E52756C23533A3A494733B74D9689D64A849D048A2FFAA62B24BA53CC76CE8489D7515834AD3A2EA920E4F2275F4F7BB361866647C04C573BF47E6B54CD31810C7814AB5CD27DA1905FC5976286B781787D2DB606C036A2616AF7946935713CE2C7AC3FC4972ABAA2229C4C294E7A70F97BB6D119BE54553EEBAB1C80C8DA7459258E44A234357A1C9CC46412794116123D21DB27455063672245460EBC8B6B1116B34F2401169ACE16A514534154E798AE3155809B651CA963F854BA501407920765A14F826DCFA4BC4F21766B05BCEAC55E6854F1AD080D9B2538848A8DC7857F10C4C843C46B172ADECE3707E01C03059313BB96BB144996B127A16006DB4063CA1251F550836E167ADEA545B3A0C55C0AC5DE3FCAB6E8242C2C5C09313646117A95EF46536DC74D869301335A2F9040484FB0C9CB85A3D034D55B03C66725D000C47537E0D5AE249EB884B67DADB110119F1D0A5EA38CDF9F2E0E27C75A43A +sk = A5019E7B82405CAC3C8F45BEC4E70E20590BD7E543D465BA702CB1447C0F114CC44F404A31B091C638347CF5A464106A2F92A0B4E600A3D86AB9F57EFFF088D1887865C695C3AA29BA08356DA1B4042146E8817F2BD56BC014071B896D5B2CBA9FA124CBA45E294A0F30FA01E4EB18262059CC987C64F9185AAA12D7EA1F2780308A91A3B2F171D9C41D166872BC7B070D44AF8556A356B631A6EB2E804CC09C531EECA476ADC8143EEBA767298BF29C19FB2496E0C573938BABCD749EE2D02E9817A3EE5A687F9324E7E1082892142C04AE9715C4A6980D73C6A54C16BEEA97A659DA476E49C1DD1B8292E04321783E0A66A36267673E92C2C7463668B1742987405C1621F94B87CE88AEBAEB7BFD787116B30A5B64A7E8956321463B351A9753A0389937B7AED431A5028D309CBED2D8AE67F859CE371CD1B3CB11A8A70D3B9B92E15530A260D1874118EC505FD451897712AE4104E67B1D2BB2676589AA4E8833E03B017AEB2666464C87BA809F2BA29106B49647666FC58C712B5B8127882DF3723E74A9B9E4B0E5A96BB325144111C75E96A13B5566E8258E36D34A76096F9B013236B3036BDA5E3D431AAD3CA33E9A0916D8CEDCD3466C75C1B5603A3E724C60A796E0844CC0D79686F086C510CA0CB11C2E936ECABA446560AAF0931C6A82298BDC7FA82AA6A0B32D361B3335CB83DDA38417720E9E745BB9CA008908CF6931AB2B4A7B78036704153359DC4FDB5742AB3C39A346005374CF3107B95CB771FF1C9592D59C810A93E3593169AB26DE85077DD79A3B3AA03C332A9D177D7EF88624C285A90099D1D0209A0BB0C425CE6AE9221613B2CD596AA77BA2BB98A385D2898D504D68117ED06233E69C43B541438B3274B579C1A5C27B0D85159836AA48907F768C97B6B2B19F475655022691182B2D9C80AEC12ECA0890C9E47BF764684FF1A94D1083D85905212431AFE09342004B44A090CD71357D2431C923B3CE08BC836B3EDB82AB2FA3C508867EAE87BF2768AD61D4894B123B6F861DB52B9B3EB77A8C99839E9108704C907E258F8D8001567078037AA1AB87B03A46AD3A0A30C753B8BD790923B7454F84C67AB6BBBCC105EDC36AB6AB67C28C1D3A54BD06F9C09C12CAC8483E015301DB6650CA3228ABB8353D2B3D95FA5D99E96BCAB65B37DC8A1E958F7395391BCBB4A944AA955BC2176AA6600A0D40489D0534423776184C85057AE00E9636BFBFA76C2D329625747968F53D1EB26CF4F95D6CCA45C60B2DA0F1899A7A1FC651C12BC2C3A2CA16D8ABA4E05C0CBCBB2B72C48EF55403462AB49CF6576D8C358A865DE1F795CC0629F4B13837B6B1704250B8E97F7A116FB63A0DBC12C955B49A67094CFEEB0E8C7B23ABE4BDABB787D3E45EAD108A96D3206A4977AA128866E596DFCA9D68996D82021A4380C0991561AE40A96BF490DD5538F0718098479A5763787939453A7A87A359643885BC5D6149EA048B5EF1ADC65C78E4A9C917160BDC625352596034B3558F98637B33061F769CBE341F9C764238318882CAA978996D1C321A92838D109C187011BF84D17FEFA0271EAC7D5EC90743130234E79089F5B9A6F0267813939B5A3B22321376FB1792D8BCC4A90087866B29244C3641310E94B8311A1303465975649288713E79CA67A9085C8F7449C0BB9A6AB196245B0DA028CC1765A8BA0501D5E360CB3064E11554F3FC2914F1260509073B67B4A0570D7F708CA7C435EA987762F2A5A23CAE53907FC9DB26942136D72202D0A0BB10B65D422091ABAA1C21D152DAD59C25D20C016237634741DEF8CA26B9CCE3097FFD896F1BF08300282FCB7000C7E1956673223902AE5B43BC63B6806C469A4EBB8BD34B057B375E725B07EE856FCC0453379B96F89888D21A7BD5EC91F837B90A2C334A97AD70D87BDCC12892D588D06655F6103E033547CF5933EC237B21B2956E5921CF10A0C55A70E4A24A57B93F6FCAAB2A44BB079987EBA57223B4B9DEB60EC6464FAA4058283B8CBA6956C792AE8FF9184E93C2E2152823C15412C102518462C2691DB1C64412EB1EC6D75D47C82FC5A9214670B3297067E30C6D9CE0CF3EB314CC1A4CF35342AE419513EC2BD47182C4EA52626A56F7831DBDC5719F532A5A421A7BD5A115C2195D0532E7C1C0FFE40166404137A5B45D7B2CD31752E1646588021508293FB881123F61034318700EEAC429500905179B283162ED0B69590541EBA0848DECC94BD18C888170A4C030A89305FE97A2B0292390A3B1FD6AA22909CF0134A2754728B6FB5180276B7D65C2FD530B4FF48CC7C7093DFC2B418B97762C42BB0980C7F41D9651C69387173A6718038010F50B79B233187BC3A0F7C770E50ABC62E8ACBE297C58C58055387BC7711473D81CA97B6A6E6504870C0DE1D806E3603ED0B04D01DC62529434014C5068C3AB3D4A909A079947127A8A2746CC8126F0212E21A0318EF273D5E0BE16253848413C5CEA22853C6E63B675CFAC1D6590004A2BB3BB4974E79ACA0DD927607A71D4B4C9980A86E5A2B5A84BCD2E694190491060411B332AA7E7766A4C693B00EB9D68F34E5B0564DE24377D3A6D45F72D82EC24FB268537C07B81AA79B5B28EF5A657E0F8B6B2F3A4279ABCF06CA2A79401312943D1D1086D91B1AD3030D0C0BB21806CB87B56ED391E6BC6AAD974034664B4902336D6E45A7449CB656207D59367F2B142746636E44726F111603B28670F47113D28CE6BB11F464B181CB3205FEBC13CC70D3FB35924A641A1117DF5CB65FD9A69C71BB800FC22A6BC47E52756C23533A3A494733B74D9689D64A849D048A2FFAA62B24BA53CC76CE8489D7515834AD3A2EA920E4F2275F4F7BB361866647C04C573BF47E6B54CD31810C7814AB5CD27DA1905FC5976286B781787D2DB606C036A2616AF7946935713CE2C7AC3FC4972ABAA2229C4C294E7A70F97BB6D119BE54553EEBAB1C80C8DA7459258E44A234357A1C9CC46412794116123D21DB27455063672245460EBC8B6B1116B34F2401169ACE16A514534154E798AE3155809B651CA963F854BA501407920765A14F826DCFA4BC4F21766B05BCEAC55E6854F1AD080D9B2538848A8DC7857F10C4C843C46B172ADECE3707E01C03059313BB96BB144996B127A16006DB4063CA1251F550836E167ADEA545B3A0C55C0AC5DE3FCAB6E8242C2C5C09313646117A95EF46536DC74D869301335A2F9040484FB0C9CB85A3D034D55B03C66725D000C47537E0D5AE249EB884B67DADB110119F1D0A5EA38CDF9F2E0E27C75A43A9AA64A30BED5AA8300772066EF577F79BF4813E3315A15F2C28B2665E4DC7E2F8D6C42E7270EE2B77B6045385F3D175984A0E260363166C73B0C70C971644363 +ct = 3639A304E4F743B4E62271BDA171EFD8912E067073B2F05FC8253F82733FC36C76FF5B6C5F17C40CB86F33D033BE899B7995251F678DED9E6CDF423FBA7C5E7014854818E08378459ED5723597AE428125C299356F6621D62F204AF4C3BB80A20B80772443CBCE224A0C0AB0FA5EE004CB11908619E40DBE2772C02E03A2A6D3C7F9A0BB5FB931A6C99F2342432CD7B13DAD5263AB489AD70500F6A855FF44D89C43073BF12F6A21D92C514B0BC4A5A839870E74D83C5B20DE67A88A01E959E587F74EEB2A9F53D05F5EF61022821B554D267A44395494453EBDD237223906F6253C3998F4271D3F1CF95DB10C8EBF18A0DAA2068CB945FA42CCEB8B0C335EB6E7991B57C153CFAF9AF85F243866E44470D32010DC7680826A9B7C85439A69571550C4AC82DECCA718C069BA2D99E832BE9A36EA810F02F82DB81DF7D449DAD5C157B0F10FD01F2BD589313F7CB3042E62912800DACA907D72D967E1DE39EF7258FAFF4EF6A8744B40F2ECEF0FFC151C78C215F98B106BD9577AEC1A3E323E705A202D4A855A0979EF439F8A27320E09F7347B316A24AADA46040B3B49426413565C0A7AA8B471F5FAAF88C9AF1375A7395B006F834D9EBE9EBF178B16A115C8346D31FEAA9E6B04719E9F35ECF7621AC1EBEAEF3EAC0EE7431CEC9E06D7A65CEBE7E6297113FF1D151F02C56C83E7DE1DF7FD00DDE7F91EDC126FBE07CB6CB888C1A2F8FAA35AFDEB10AF14A2F8A8B080891E8BEE23A5AFD86A4D749F97DCC6A3B98DBFC5DF4591A16927C33B9FE08AAEAE00979D178A1882FC1AF0E65D8B6F33DFFB235DD06BCF574D55A3074F8BA607A2178E34C76C72AFC1B8E1CB9F482F0162BDD550078655B0F95B3092B132164358A72A6A48C9550553FE9BC874980404955F481C6A614923B925931337F7E2502880A443CEC707B7238AC1ED70B4B94501EA74EA9BCD989B50B360B891D97FFC786A46E53EAAD2F5D714546A80FF90070F281C16A7BA543EF9A0CEFAD3217FBD2133CDC4F7AAEEC5AE444AAF015614D6625471790F714B68E881C0D6ADEF3A6D6E8FC9E273374FB2CC1C9D6D406B4812653DF1276171BF253AD4B80D7B5F8DE0B4BBEB50E2E2607A4CACE04698D7D0EDFE5AFB900C661A5020B7CB88DF34712FF4325D362435BB45D5A9D352BC13EB66BC599C4A07677103A1D7B40F0AE8393E42315BB62D6AC8CF953B8051516807451033B5404BCB12BE7ABFCC9F6CFB8C9ECCC4998CFED0653808463188AC22961BFDDF8F1AA97AA067DF0E9E9954F79547998759FD08542D0A71CBDD32E6EDEFB11331CAD655408CE2F5DEF7AED94B37E8A4B8B75946A677030C3903A4B201C1F3D2DFA65A06BAB8982A4DCE33418D0ED98E29A94E556F0B4C3AEDB44D887DE5BAA0374EF291C8552F0AECD7DC5BB3CFBE79FC92F0A73020489474C8279CD8044BEC179C7E5A1430965B9BF130314A35F9DE2DDBA517D28ADB3D253EFDE18BADABD6512D516C8147E91BACF3CD43CE5E244767ACDAAE8C2AC56A72E1F0089100 +ss = A2B1D4028AF3777BE109A51FAB5B7014681B0BE94A7C06E8C2100565667F21A7 + +count = 11 +seed = 6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC +generateEntropy = 31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +encapEntropyPreHash = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +pk = E9718A491B3262D206BE72A9CEB000E81B6BE6668D14A124BB49BE524ABB09B91942A60ED38B1974E36376A7724DDC7E5A993EA9C25F40B80C766CC57E807BD5932603403458B84703CA58F8E57C451227128654DF4537FCE6A57BD1BD6FD8C5BE1135B2C82CBFA4B96D577575406F92538034D22D6198A9CD000FC8DC8988F95608C1974C4359ADA14F7DD4870C63BF79886AB2D4CAD1C89A8FE232FC1C8C515B7D2AA9CC35759EF583244EA767916478F8415FDF7B1CF85A80F4D6960298B977A7ABF380709EF904C1706EE3F51ABF415028321E4FC79FB2E15454C47B3572BC09C62C0DC466EFAA759F116E8BA4717F91220F125656BA7C52338AB1FACB0FA6A75CE61F3135911D5714FCDA7A5A271205547018CC0607C5AA7104A4A77266C0525579F054ECC6C62522068E79352AE7A1C3265413459939764A4421CAA937C8F9B2B276A2C77CE7814FE9034783B8AEC29881E2563A63780CBABBCBE72501D68F1B72C6EF3C5D84A4BD7CF4A84686682FE36A151BCB3BB76CE5FA67AE545C9621BED149BE06AA2E72F72D1B24B086836B525915B93A49D90CB3C45877C54204A605CC27F1828DE6CA1E95056938A6C9651EB3B4A9B09C5AA9FC4401215D9EA9015A996F9A7B898CEA466CA14F0065A5B1F374D422B4A277A011F3B3E8143B053507BEE829E582528DCB3C9E950F39D17AD0A849C701779D070E34CC606C84A596650B7776A468659344446BC19186B43CBF042516A7B133065393C83B85313C53B71A5BC4421A91694BEEB39760806D3B910AA8EA546F53763B656C99EA50A179986DC3786A554B819317FB58564DD69428BB1D7BC45A642A8AB9CC013F932A67222D1FD42B455930B8147D6175C66330217246C400C4B619B922182101B2D8165F93BEE58757C14CBFC958552137B904009FCF845321841F8648B8F9E58D1572119B11CBCD59480246A46E255ADCC1649817A052736ED9C18A262C36F7C37918DB789AB177ED39ADD0850A509319888073B54BC3ED81000C780FC87AC5C302235A959B1164B491001B92811D4AA76876065E841B276A27B868822FD1DA7C3FD1831D88C9F5D891FF610CAF264FBC9280B8D4085251774EE20C23576ACE6215B3EB8C1610CA2405115E89421418A7610C05BB526FFA39918E9558C6CB2618A612B6D38BF8A2569B4C3AE902A4AC744ED4BCA8ED783C4EBA450470AEF5EC5370B87DAA419145298170D64CAAFC2EDA7C989645B9285A3FBD16C16E0C1E3FE085A6BC05248426EF106E7F6012E80882682660CD05CE49520785EA66325078F9A91E5FFC3BA0833DE333326FECBCD8878F286064CD1B672F210133E30D106C61AF9A75A7FC64FB5B1E1A1649FAB356C0F26B9062C5DCEAA7CEE502C750A93187A21C11B1B7FCAA45F8B857D38E18287B1E878C7EE59E07966F3619BEE70253D77065C02926BFD9B031260B5AF95846573AD09C42573C8338609FD3E5C0B50092B17A83128A4A9F1A6A232252884504846B3B7DF82981DBB036F6A57C5C19136789AF9690A978145EA6ADB74132EC55840965083F388877A93FC01B006FE4CDE4012A1814B327A12CCA8991CD18027F4485B4025B5583747FBB37916585261ABFEA163B617347ACAF453AE235166CDD8AFBFFDAAAB9919F0CFFDC75D8796FCC28 +sk = 7EC737EBF52EB7905DA8B3C58508928DD74462E8968A1265BB3B9780649210C8202E2950AC11863BD78AF3123AE9899CEFF1992608CF5BD1B4EB0AC1C13CCAAB4CA89A869424BC1AF777CFC7D90A071273F5AA5DF310493FAB17CE5B6477C773D8CC81D995509FF3A40CE80E734A9E8968B7FBE79A9900AB85F7B442077A890688DCBA0BD5E64AE491CE5D39B554E6B82B7602A149A686C19FCEE21B8E3B1792E7529F2307505C77ED84A63A68258E832BF0F118BC05C91A6B216EBCC051B90143B9748B365EC841B6098C4EECE8AA8231BC24B03E732A0EC55AA5B0E3231EFB7C7F0AB21E2544072C22B6B4075049B63FBA05C68A936989BAA2E55AD1846FD1E335568B01D4ACC869E710357708BDC25DB545447E41727224545CA8C16BCA5458EB24D746A12E170EF191CC8DD840E26910CD9484B4E40D0C7446959A521618B9BC472C8001AD0D1C8428C43C0FB3230FA9B17694284375A0E1563FDAEAB6CAD367C9949C4723802D6931F0C212B03004675652B958518D31C8D4B06DFD99820702319E668DFFB5C88622170B0C0EABA56EE7B77EF5D7600B9C0BBBEA5B99E05A9443BB81A68C22C7904A1755D4C80A47AC148ED13C3981C6BF4122A7880FDD597429A32D6046981146743AE85CC8C0CCB715937F29C933D63AB475C2C5483CE07ACC5B8BB4C7456398A9236D02BED9B951F6D43A67EA06F7FB803ACC33E9552E7150C34003A2E2E11BFC0BADFC537EB2B69122352FFB62B285B6CB0935ADFA0385DDA074F7A63ADB76BCF4A80AA83A1C32F87BE3A786537ACAA32178B136C8BF817AC1CB1E25B44654266F4B2B14F33358B9B75A2D916D78E89D3CEC68B782734FE052449598D847B2A02C3056A64E72C5A3B34685E9FB2C0037736E0A21DF39A356310777A36FCE908C243A4A50216B6199CD63C7BDB18B95FBE4615E9799757176FA4A88C93459BC3030E09889EDE148890CC221362472586E3C026B0DC10BA5A823F07ACC1C693E9BF31518B90359B7AAEC54473552835B3590174109337B6171EAC38DE29BDEF8095DA13A8F7014B3F531FC152CA5EB19859673D52067E28C7513141245376BAF368B07627FB1B844FC033361994FFB3B39822A2A2DE17597D16601329866F42C3697A6F5132DCEA2140B871480E50523C3C5227537A5089FB6742CBFCA55BA9C307A321ABE440241E34151B2C2AAB6AD55817B115330C0B15891FA35BF344BE7D93AD44BB27962101982902427242F5B06F85204E738AEC7A333A15001252004B21B5E6FA95A41A4456F74C9522657A9A40F8C4A162F4951CD5BB8A4F334F45A3A73266E1C386CAED53AB52B9A4DFA173B96869FBA6C72987F4B328A0E56A08C96A00D78854D6762EA2394C2A102162143CD40192749CFBC5031739711F1EA8C37DB5B635BCFE9B6396E2902D56BB135EB8975E1B0A171258D39A7AE84AABD46BAF4DC2A6FF18FB6002CE232B7A45A532DD54D3DA8C580D6CEA4209098930477D207622A7CDEDC2E72C24EAF5787D4B2B461889D23AB93A4BA327C371EFF58CFF7F65738886ABD046895834AA06A6CB57973F1011353FCC1452B015A324C406515E9290AFF4356FB393B57F4066077B2152819B6A69DE9718A491B3262D206BE72A9CEB000E81B6BE6668D14A124BB49BE524ABB09B91942A60ED38B1974E36376A7724DDC7E5A993EA9C25F40B80C766CC57E807BD5932603403458B84703CA58F8E57C451227128654DF4537FCE6A57BD1BD6FD8C5BE1135B2C82CBFA4B96D577575406F92538034D22D6198A9CD000FC8DC8988F95608C1974C4359ADA14F7DD4870C63BF79886AB2D4CAD1C89A8FE232FC1C8C515B7D2AA9CC35759EF583244EA767916478F8415FDF7B1CF85A80F4D6960298B977A7ABF380709EF904C1706EE3F51ABF415028321E4FC79FB2E15454C47B3572BC09C62C0DC466EFAA759F116E8BA4717F91220F125656BA7C52338AB1FACB0FA6A75CE61F3135911D5714FCDA7A5A271205547018CC0607C5AA7104A4A77266C0525579F054ECC6C62522068E79352AE7A1C3265413459939764A4421CAA937C8F9B2B276A2C77CE7814FE9034783B8AEC29881E2563A63780CBABBCBE72501D68F1B72C6EF3C5D84A4BD7CF4A84686682FE36A151BCB3BB76CE5FA67AE545C9621BED149BE06AA2E72F72D1B24B086836B525915B93A49D90CB3C45877C54204A605CC27F1828DE6CA1E95056938A6C9651EB3B4A9B09C5AA9FC4401215D9EA9015A996F9A7B898CEA466CA14F0065A5B1F374D422B4A277A011F3B3E8143B053507BEE829E582528DCB3C9E950F39D17AD0A849C701779D070E34CC606C84A596650B7776A468659344446BC19186B43CBF042516A7B133065393C83B85313C53B71A5BC4421A91694BEEB39760806D3B910AA8EA546F53763B656C99EA50A179986DC3786A554B819317FB58564DD69428BB1D7BC45A642A8AB9CC013F932A67222D1FD42B455930B8147D6175C66330217246C400C4B619B922182101B2D8165F93BEE58757C14CBFC958552137B904009FCF845321841F8648B8F9E58D1572119B11CBCD59480246A46E255ADCC1649817A052736ED9C18A262C36F7C37918DB789AB177ED39ADD0850A509319888073B54BC3ED81000C780FC87AC5C302235A959B1164B491001B92811D4AA76876065E841B276A27B868822FD1DA7C3FD1831D88C9F5D891FF610CAF264FBC9280B8D4085251774EE20C23576ACE6215B3EB8C1610CA2405115E89421418A7610C05BB526FFA39918E9558C6CB2618A612B6D38BF8A2569B4C3AE902A4AC744ED4BCA8ED783C4EBA450470AEF5EC5370B87DAA419145298170D64CAAFC2EDA7C989645B9285A3FBD16C16E0C1E3FE085A6BC05248426EF106E7F6012E80882682660CD05CE49520785EA66325078F9A91E5FFC3BA0833DE333326FECBCD8878F286064CD1B672F210133E30D106C61AF9A75A7FC64FB5B1E1A1649FAB356C0F26B9062C5DCEAA7CEE502C750A93187A21C11B1B7FCAA45F8B857D38E18287B1E878C7EE59E07966F3619BEE70253D77065C02926BFD9B031260B5AF95846573AD09C42573C8338609FD3E5C0B50092B17A83128A4A9F1A6A232252884504846B3B7DF82981DBB036F6A57C5C19136789AF9690A978145EA6ADB74132EC55840965083F388877A93FC01B006FE4CDE4012A1814B327A12CCA8991CD18027F4485B4025B5583747FBB37916585261ABFEA163B617347ACAF453AE235166CDD8AFBFFDAAAB9919F0CFFDC75D8796FCC28241E5C7B836862D7482D507973AE3FD8DAE96EEC4ECEBCEDB68FBDA75E04B401812083BFA3B670E3EAF9B443702FB6DB16AC1197656BBD61A8E25ED523B8D1E5 +ct = 6B0D9B262990276B654A5AA1A91DDB9EF72225CB2CF1FAE1108671F4F44BE627C6285ACEDA812207FAB12B6CA0A147C2B36D08818DDFD16AF799F9873EE7DAF236F33A607744147A944790B2917D381435B626003C8DF54967B99786D3B610E449DBE49840355A179E6273FF2B3164B50A0E818AEE095807855641772B2B158B5CDA1EB09BDCB98D3E124C0AB285E105E0573A5A6C7256D3455CF59227D0B421FDBB7399F851E910CAF0FF6D96A4BE8A74C7EEB54261DA68024237EB7E561386EB4EA13C56CCDBA633CAF6CAEADE2657A50EF4E0ECF611C18D2B46AF6E993F7279ACE11439D9C8EB857ED097C9D1208757CE7898CC980DE4635988F398758681307B42F64C86867F5F3177022BAC3C4D8EBDE5960BC9095591DAB21CE23D799FDA79C97095CBADDBC43E2324B8DEB736E43374EA884055E4741508554B309D946FF719006C99DEAFB7154BFCAD158A76D8858817BB0EDD928D9C56E972C8DD3D5E806DA47A0C855D23931D1412A5B801B42121EEF3522A8FCA12575703865DC2350CA616ECC39D1E9AFAF9A87D638F72E1861FC8386ECDA284AC0C220DA5E3BB55895F82186DFE69569EFAF2F4A7346348099704B11E5EDB304C42B78853F376A4C4DFAE3E32F1BEACF3D5C2F1744E02F819EB22927013407D82D9687F83757D3D944524E5957E6AB542C83840F5A2F9B31CD9678C7A589DAB33785F06A94C1B71E4AFD3460F85C2A7C6ED7F83CFC009BD88F1241981AD098D1521C0A09348B816E1458291E58314C10371CCDABF96EF994D2C6685A4C781D4CF8263865A18BA57711269449E509BF8460EC4C1CE7C9788816A31F8F91D3FAD6F27B4F351210FF5C41C11E5B0029E66BB655ED20E8011BD16AFAF2F02CE2BC5188B2A2C34AB074515CC85477FA4B541D4C61611A1DF6AE7D1782A311BEBAC32A28DF255263E308E2B659150ABF2DFB955F7A2D7FAD7EED45E18796D9BAEA414F9F66252A4A7CD833E54F1010585865A66FB23F8B781FBF1E1BEF7771C6E73DDE8A059A0ED5837B9DCB9B5A037A3D77F6DE09F3922C5F7C715B00E1ACB1DFC91C934AE04932888192875A126AF8DF70B21D64CB22D430F64FD4CB836C3B8967063E22C647435421C4D0601A3A6D54E7051C84CBC4BCC6455D19B4CE18E79813B33A562F3780A92AC9160A1CB7A22C79A7B8B67BA7824A914E713BE0C889DC6BB420101506FDA42B2448970A11B3C482CA873EFE65856B1DC7C8FA50A6412B8DA94235488DC67AF11B0C8E988FC844B7F0E6AEB685E4B63DC7C0C0184830410C486E6BC03F87129D99CB6464EA70B6C2B01D58EA3F18DA93B4933567A95472556152FEEADB88C9DE0D5A69D6FEF8EDDA08A34B39BFC5D5138A403E3E2D5E6A15A020E8E463B71F8D90A53FB36A91A825E43CBA2433BAE0F17569D3A83EE793EE99D44EBA560C7EB57341AFF091654DC3FD0E24461962CE9D50F1B8BEEE9BC4A23F232BEBEC8B61236D78309B16DD5B4690E8BC495EE43574398D01A62B0CD0F57CD4EE0B64ACAD4 +ss = 4A2BAC4D2A30597AA5B528D0E20B1630B20A36E8D747B5EC41EEB57950375A5D + +count = 12 +seed = DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F +generateEntropy = cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +encapEntropyPreHash = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +pk = 14345D52853184AAAB60195152259D9B643D864C4EC5FC4978C657C3365EA81212EB91339AAA4BFA87A197A04D46A7B666837F55DB6F16C095DB449E9BAA879AE14016EA4F8BA975DA26CFCF59401237ACCB908EFD17146E9439B1473BAFA07703F2932D5C598276B59B419402D681D87111F70C20D2710E10A407634AB216907D7363AF0BC4647DBA208F9C6744D71A8A1C1A99082A3BD8A843E4CE581412F04877EDB1709D1A9623C3C428EB111A1189073C9A3D34AD16AA1F1551A07E6880147360E60888DDD5B0956036951021AF4699C96382CC0C16B3F0B960135391C6692B0C556A5B9AD2F8A5ED0CB0BAEA2406868AC6F7A5A44B722721535E098FE832C9AF148AE027604C47CE4D3214A1BC974675289AC7BFB9A644DB30235A664417C57A8A46A86E18A10F81B87F4B4727F7234017088F447F28680B0600AD1DD672F0EA19E38A39FCF964CCCC64528C97FA474EF3AA6777676B3DB443D0A2042C744555049C48B2BC2577738A698BC58910F55B0EDE555B171838F6086CA365AED981AA5354561411990707BD3305CF4D10161FD3124156691DAA5CF3795653E2AEE1C4BA021B0EDD0809B14905E46C2CD0BB1E165C8AA428B180EA394E6C92BD6873E12328E5E1916C94C81393172DF3815127B937B9646A783524671FBD8B5F01395178C6A9FF42C47D8B25FB37A2D1DA975F69C7A8286504FAAA6AD5B05307C2D20B4F27640FE59B1EF407110A317CD72023828192B131CB9AF96899A69B0F51125B2828F29493A997A33023661BB7811C4593E4E579F8B17D0CBB6037D9273932AF4EB235F7D01DD398B70752A925968ADBF56CF132B85680ABFFB937C35425C244345E805BDB608CB0666984775AC1852690908CF2A60214F6A888004AA41A44831537E55A5DFAE7B2A4448FE6C562EA66764DFB5FA508B6738C4F52F10D4A852D38F5354981CDFB7A851A675C5A01C2FBE886192582D1F08AB37753BBD81BA6D848949731C99BA92278A2833CC11AC3BF603512BD6557F9684EB980C7588424DB0C1E2BB2BD09196A7DA29D79208DA50C4A0C839284A44D8861706E991EDD099E0B1467B88948C89778787C26DD4436FBC4BFD12B0ACC00AB4D85B613BBA4F928BBFCB04E2EAA51B81845C3A710BBC8458027A4F055061D0B39AD28482646AEBC5458D0E70D396C99A0B456837376110488F49A83F48372327467AB87870D11B3C1E6C112AB3D6D486A99BC2B9B368A0695C6C6251D6BEA5B56FCB96FC23475719B8CC82806875CAD772E4716332FFB02189438E27097E565159E4B1790558273CA887FCA2A6E7226C53879ADBBC07AC1072E6AAFDD2A1DD89677842041F33C447204A3FB91C1E4935111AC739CDC9FD6F2BA8C0C66DFF5552F3B2BDFDB19D4F65CB3B23777292CF97CC54BFBC41ED041E53318386173D229B9288C5D68E87D0CE2032D481C46B646EF71940D97AF370732533260C6AC943272866BB2BC90EC64424C67B1C877F5D2B35C39656957BBE40C53ED88C4124764B726A5E24ABA7B0C866A52385C85C241677F75487D4156C85DB639AD741E0412438BDBCEB6092FA14501FE1C5E95D90833332DEBC0441554A8CB5A8F7826B047882B415B78A0C2E966AC7C67B03EF5106F0A751017B67CC52A3D0E1586C74513D2B5F13260 +sk = D62C6CE5E7594BE682A8167743106A44482E3A79CE257635773513F0B0BF77A161C8274A705B93D2EAA899D8C0126AC8ADB7B3BBB5891711380DA1A9DE0541E4160DCCABC13A165B5C54178DA95B919457C684B9CEF81E97637C73F22A3CE9295DE79BEDD83C3FF871087B9412301863E291B04779457807ABE4687368C84B3408E26AA30BF58BBE4BBDED32ADB03607598714464222524B3C2CD4C15F98A2E6695463257BB8FA9A84131A64D45A57B9A539094B5E957496B79008878396D3B9B2EC41CCA75B66FA6D069A51AF611D4BC03E20CB12A216072D7834D996AE99E1CC6522A42B48C54282CD0AE8CFDD1B874FBB4EC17434AD584AF5B4561BC1597AAB63390B60FE7C052E57846E1A8C4F6C6758798B70503507554946382FA6E2004A616A40DBC2B0C596C2CB2873C38E6FF82FF159BA93563D23671DFC433949D3705F398B3752680169657623937A8C357864C39D82C16DA5C1EE407FC7FAB357C0B114965E89815409964CCDC54CD8D5B17039AA9283A59E746A45A2800E4806064683C292B425C18F73AA2F720A6521A050C5196BDABC9B094895B9527759C1A7210958E11A3411B05E67097FCE2C11ED024A85A22684B51EDD652DED89C23E1440CA5616BB754361C549776222B8B297F8F4BB7F818D3B29B16C369CC8BA9D91E6012BF006999C7057AA2A44C30237314079B2A55C63990C3AB657CB80D41022651097ED680D200195BE82A9B9D08B24F039BFFC42C66459B0C8889DDA6714B63762494A5E6106F34223990772B1CC12DC660F5BE62EB0A15C16D4A0303773D768C7DDA7B749711F7C12720C150D30EC6B625624E3F94861483BE03271D8B05780AB62E0294A8CB193238530B49455718C872428BEA1D84955F54A3BB619DADC6106EA3EF27094A085634624377312648AC46559D7A7DD902497AA9F22879D131A08B9223A05E5B76A00807225B304480F6105CBEC8A11CEA18E8910A9BBA691047C95676C9E2DC7AB76537691DBBEE397738C613E1FB00A79F06698C10EC26C97DC00B82A54AF572A02801AAC20983311F42BCA18699A2684E4B5AED83C7AD89A1705F1605A87CABEFAC499A56058D8B02BD597743524A90C3686D9405E33C3D70880B6449D41A76F83E23759664F1F301D3935998D690A7167AFA11A59CF8B87624283A738C0D221B1B55453504AB64FB89824351A49EBBCC291465AF92F50D7B53874C1190A766DAC5E70706F88097BE4500942534DF5E5887C48B234C11992F32BF3F2867CC055D7D6C3A4D25D2A141BE7D706BC1203814667552888E3BB13221A10DC3A4157D811A7CA23088BA5AA1A3FD60C0C6AF29B3B52AA6DA319D8E359D842C6DC65C29ECCC0523115D15B19A7B90D1090C5949CC66A004F0A0513132640A284A87384C7ED06782607584BF5CDD8F099ACB0229CC9588B024B0F3B5BA80B962218B3BCE4C0F542BAC9E8C235362E33EA30D789094FE82FBF64569907755ED7BFD00C3F6F446DEB00A27B37BB92E454AAAACB69DC854532C718C85508AC8742C7180EA805A78999111915BD414275E92D75C1953C10968C802E4AA6429ECA0A5EF49FB4046ED2C93914400B0D882B67C275C483037E859C8C015114345D52853184AAAB60195152259D9B643D864C4EC5FC4978C657C3365EA81212EB91339AAA4BFA87A197A04D46A7B666837F55DB6F16C095DB449E9BAA879AE14016EA4F8BA975DA26CFCF59401237ACCB908EFD17146E9439B1473BAFA07703F2932D5C598276B59B419402D681D87111F70C20D2710E10A407634AB216907D7363AF0BC4647DBA208F9C6744D71A8A1C1A99082A3BD8A843E4CE581412F04877EDB1709D1A9623C3C428EB111A1189073C9A3D34AD16AA1F1551A07E6880147360E60888DDD5B0956036951021AF4699C96382CC0C16B3F0B960135391C6692B0C556A5B9AD2F8A5ED0CB0BAEA2406868AC6F7A5A44B722721535E098FE832C9AF148AE027604C47CE4D3214A1BC974675289AC7BFB9A644DB30235A664417C57A8A46A86E18A10F81B87F4B4727F7234017088F447F28680B0600AD1DD672F0EA19E38A39FCF964CCCC64528C97FA474EF3AA6777676B3DB443D0A2042C744555049C48B2BC2577738A698BC58910F55B0EDE555B171838F6086CA365AED981AA5354561411990707BD3305CF4D10161FD3124156691DAA5CF3795653E2AEE1C4BA021B0EDD0809B14905E46C2CD0BB1E165C8AA428B180EA394E6C92BD6873E12328E5E1916C94C81393172DF3815127B937B9646A783524671FBD8B5F01395178C6A9FF42C47D8B25FB37A2D1DA975F69C7A8286504FAAA6AD5B05307C2D20B4F27640FE59B1EF407110A317CD72023828192B131CB9AF96899A69B0F51125B2828F29493A997A33023661BB7811C4593E4E579F8B17D0CBB6037D9273932AF4EB235F7D01DD398B70752A925968ADBF56CF132B85680ABFFB937C35425C244345E805BDB608CB0666984775AC1852690908CF2A60214F6A888004AA41A44831537E55A5DFAE7B2A4448FE6C562EA66764DFB5FA508B6738C4F52F10D4A852D38F5354981CDFB7A851A675C5A01C2FBE886192582D1F08AB37753BBD81BA6D848949731C99BA92278A2833CC11AC3BF603512BD6557F9684EB980C7588424DB0C1E2BB2BD09196A7DA29D79208DA50C4A0C839284A44D8861706E991EDD099E0B1467B88948C89778787C26DD4436FBC4BFD12B0ACC00AB4D85B613BBA4F928BBFCB04E2EAA51B81845C3A710BBC8458027A4F055061D0B39AD28482646AEBC5458D0E70D396C99A0B456837376110488F49A83F48372327467AB87870D11B3C1E6C112AB3D6D486A99BC2B9B368A0695C6C6251D6BEA5B56FCB96FC23475719B8CC82806875CAD772E4716332FFB02189438E27097E565159E4B1790558273CA887FCA2A6E7226C53879ADBBC07AC1072E6AAFDD2A1DD89677842041F33C447204A3FB91C1E4935111AC739CDC9FD6F2BA8C0C66DFF5552F3B2BDFDB19D4F65CB3B23777292CF97CC54BFBC41ED041E53318386173D229B9288C5D68E87D0CE2032D481C46B646EF71940D97AF370732533260C6AC943272866BB2BC90EC64424C67B1C877F5D2B35C39656957BBE40C53ED88C4124764B726A5E24ABA7B0C866A52385C85C241677F75487D4156C85DB639AD741E0412438BDBCEB6092FA14501FE1C5E95D90833332DEBC0441554A8CB5A8F7826B047882B415B78A0C2E966AC7C67B03EF5106F0A751017B67CC52A3D0E1586C74513D2B5F132606AD1D739F1598A16C608A240CD13DFAF8263D74866315E2898A3431CF19E46858E9A30597E4B52FFA87A54B83C91D12A5E9C2CD90FCAC2C11B3A348240411A4C +ct = 3ACCE62A918EBD3D80860DD2AAA93B594682527418B4DB700CFFEE66A66C30C228F2566A4F717C8505DD17CB7CC71990AAA00BF04EEEB254154BA0D20025E02D0F476B445E3ECD9E90904695236BB7D6345AA360308AF8A9698A46FF10DABBFDD4537CD96EE0054FB3E7E53DC2D72DD642E079CFA964B8EE9A7E9806A5724C4D659D24AF5EE2669AB399AFC6DF41F1E8CEEEEC0F5910C83CC40A9287F0E44C22CA0CD3ACE7BA56DA39C29402331C3DCA0F6DF27EEC203225C5F2100944516BAC3AAF3470F793966CB9B4DE1A9581A6412CFAF5E058AC21FAB447B5045804AF6D75C27E24C48B4DFAA3B48EBF59B9AFF804BD24B98DA9D29556BC95362E207E662855D927015C92C69034CF0DF2FFB8FE3052713C74843D3BF90516D8627213E1D52167D13BC9C47387D57C8843AD16A102026E9AB2E430B70BD5EDDD8898A5E62E7D6CE8650B18805996118BB95CA0AC22A43FD92D3EEC07D5BEBFE80A7ED737921061ACBB42FC009C59A409EB3327C2931C642207145B826EECF2377374973219834C3E36E31F459793D644475E207AB0DB525649F05873E811988186DEE8A0E07AC3CEA66F3635F531988D9798F0503FDFBA624A350C299C1339435811620FD6B75EA11CFF36B300E6F2C79F5F0B10FC07E1E9E6A9ACAEF599F95DC8ED5C43E95617D407120C5F9A5A7DD2A804682B8214BC5C913A4984FB69DF0CAB7C0B3146592E43FB9869A526CE58148AAAA39E70A378CAB1648F982C0C668675E3522AD1C8647F3925F7DB726B1E50F352234E5CB67F9B55954831E819BDDF6628935A807A468E9724AA2917A2FF8E84D30DF3643275897BE01A2D9B2CD296B4289A4D84C2A5EC6AC1669EA42D9A19294CFD8AD9B9E4F76DF7879D564429BC55459421026CA3ECBA1CCFB04E41546DA705D6B27D193B86A695746FD2A8DE6D39B616B04C468469F69C23E1FE2BB7A554D70086DFE50F5B9F0A12114AF80D146BBC6A6E1E745905E05443F9177C36002C26FF322DEAA7D27074ADE6860B4EEA93755F00E35BBA8A721ED9CEC554A9ECE670C9D8EFE4B31DDD0565F2C18ECEA9326D3A5F8A1D7CC208247CE5F45A75E23FD5A4FE1CA5A20B661A48E2C6E29D847DDFA12EE226310D65D10E3F461998B4A7480F6F200181E6A003FA671010B87EBEF9FC8A2C14352102E1153816ED9B10B3E2F370EC7F8FEAE82282AF5FEC46A5D2B8697A59D1FC354F3854A1344DB6F6FA91C78844B3A414D3FF02BCD1333A88AFC9D55947237A743BAF81F0AFC37A10EAAC892EAECD15B1265A6B37AC075A778FE2466E1D3A7C1D9C1677AE5FA8737DDF4040D7C3D76118540D244CDA0A7AD5C9E4D7DDC377C15E57697F6F9EC14689C085E986F16BDE6884B2978F217C51ECAA2AA9C8FCA9CF6E9ADE1E39BECAAFF2019B5691B70C06286341DCAA4F21B87B38622C1BC996A38BC0428731AD3EB3C7BB0D08EC4B4950DC5EA20095088F317C43C073D2E2CD61B361EFE2CC13B12F1BFA59A309D620F4F8FD58B3A8F32ED9DED4BE8CED +ss = E09C8D7E5D104C0A42B47F031EFE22A79BA1008EFDFB80FFC7532F40FC9B3A94 + +count = 13 +seed = BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418 +generateEntropy = 4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +encapEntropyPreHash = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +pk = 8BD98BE4597242C95C9641B194A093A928B8D3B30F33C10BA326943A8B704C09A6DFA55F700C488C38A3334716CCEB6585008A853162E40A544C0A16878328F47C4E67B5AAD276A2DEC4C320047E2EAB345CC14982B96D1D13566DA409E93072377A1729546117A04CE291A2090B60030A35D5B360F9F871CAD52F37E63954DA0E0A8675ABCC3717972F89469978730607293267CAC89E3C96A98576C2351D8756429722A1278A173A75114BAA4F0EEC6A12B09CAFDC99FEE2C1AF7ACDAE3C747B94B06517464F654ADAE25888A15CB4C5017076C9D3FAC3B1560DD9112D88B2BCF31B15AC420FE5A698D52AB41EF33FA6CA8D8CB9B94D58648F39A138974E8016A972308C7B040D2FA32BFD1096503A3A0E84B9941188A6720E06E6641B896D365190369766995826B72122D780477581BD69B348BB6C5C8F65B4D84AC3F0768EF6645E422B3ED7E38D0A423409C285D0E21BBCA97BE6707557BB0027E755F9A81912D04B9EBB374BD79411B2C283068670431F2DE58D346BB525D192F128C9316742115275E9214DEF7A61DA509B5848013B304216F783D77C3F57B76FB8DC984F05AB557709DAE4691B519C44D41813E4B61E6664AF5C970AE7A810714217745AF087BB00575B18081921A854B7D953E29CB1DE704E6578283292168EA73A03E2082B8B641C819649270011861A7B301DCEF74E9B116A86F717E30BA6C5398E34390072E20C82F570FCFAA2BD8847A7187052E6B9D0D9BC9FEC0217373BCC7B8D38245E40A1597077BB00A408E9EB2BB451C31A746D2AA07FD6432CF176382B6665D45343CF32731817023EE046577ABC342BBE25416DAEE417F2971A8ED4C839126E996A8DB40A55BD424C0E534CAB677FA1C6B692D2B7E322A331305F75289A1ED102ED604722737E76501C7E7ACC69842D6FFB2D31D1003C3B3BD8F4458D93B0270CBA21DB21A7D16E22E18584E68EA5B890EE839DE75B68D60B25D5452BBB91658F3220AAAB200EE7A8F070A5B5AA7FA30A768275970012324FE01910E8647945AE6F8B3A17D08E5C36AF468A7F6308751C4141439B567EAB03D72538DDF71DEBD2AEC5DB13537A2B0130B4C2F6662182BD08EB750EB681FCE77981A3012102C45642BB8A44AD5CB27CDA8369EC28190F64987EB600101ACEAE7A807158CC8100555A82644B3B513D7CB283A363C70A4EA090241C8A96AC562E7FB3C38F3515C3A68FECB271713729FB77A1A68695FCF995855749C1F0AE09F90741EC332E7602CADB69E55438B9D8CCC213119627410488145777907D280DDB7391D2EC9F27371277C266BB1B14F6EB8D46B2C8BCCB0C68F3BEB2D87B07044904D5B08E84305B0686F923985A49ACDCB1A662D1A08948C9B8D95883518D0AD3933976C464A41C18351216D84066D71164A32D41886A153703C584B747555EEFE8309F0810D49C0DF8C5512B245F637C9448C47E1456995E922460B8210C7AC1063047C3764077288A1345C23EE0C8FA6865FDD52ACB49614207285D241C14114DB55CC0C92049F3537ABFF81B8A30A02E5AB013741B36D92191691B3197CCE8D2328BBB6FF61932434899AE01412B231B0EFA18D8381555866091C77981E753F8A2B95E8095765EF7A13BD38F9FED3BF36477916CB802690A213C83F6624A067A5E2C +sk = 212393FA68C40D1153EC29801F4472DB30B8E6516647CCCC6A160BDAC4299D515717D46BB4248673D11558D8AF5A6373720A9C96A4C51BF12AC506CBE51B560AB742EC684DDF86CB08121BDD412E2476842D051E3182C415C49B7184C9322242F70B63A960576296A8AF5451F5D474019C47E1822E2B1503D30CB8EA20B3CEC334A2114FC2381D910A98E633716EF9CA2F7939C7033BAB756371D6C2E906061DF822113C57DD5992C8826ADECBC9AE381931473558AC94FE8A19C9C4BEA3DC40DEFBCBDE234A211623F8D80BDEFC74F657A797098EBBE2B6B57438C2253F89D13BCBD5C0C4204DEF79BB37859E36E920768CA7D0651A7EC9BB63336698ACBFB6C9A384084DEFC1BF5D9C050087B691D40344E107BEF0241BD99463532A05B795F820213392CB16D668605CA86DF134C03C4A7DF581F8CA7DAF732F5AA75146457163C3ABFA9C655F966A607A69AA1234FD1CA2A97213F280A10E84C4AAD26C0EA2CBA6773D63B39EF7350F6D284830EC3275E5BB9A318B03F87CD3F3BBA41632C0F9A1E65989B74B91B23A82BCC22D617AAF8B14C10D0037AB970B8CEBBEC0CB866BE5057964B7CAE6C9B3084A696602A25961DC53558C065D6D8B25248ABA262B1B635322BB82165A8CBEDE60BBF6B72459D47B64A964B3C32CA563BA5AEABA8ED912D81B2E733B4B4587A99AE5037DD21DFC9ACA5D869596E36547C0336AE774B8BA637622A597C05DCD43B092D938429886C708448B24A45A701CE9FB9DB54C67BB531BCFB82EBC15C127409B02A3350D6168F1296784B86F7310B9160681F0133A66356843401B9C0414D7F687AAE41A36857CCD3B26BF8C11DEF30769E30630169365AA3C3B53CC89D9CF47C2CC6C166F197C9E5C5B2408B03C41B0613703CC4872BE78DCC4B28089D7118CA1186BAEAC1355D5B9D4E45515897AE233A26810356A373DCBF6CD5F02CDDE8C468BE006DBC67E60A69908D1171D4A5EC1643B87059CAC80C259788EAF195F4FBCCFC4C0284BE822F94C2978FA119371291657B927F8B332124D61D17E21A36485D2C3F2893865F305589A8D048B06FBA7BB9F087F96D5785678A7F2D16C892CBB2273677ED0CB70F5729AF0A0403B0BF0608ACEC1CE32F2924535C16E8423BE0C8854E439EA395DD792399DC98AEEB7493B64965858BE35977DC053B3C0B3788FB4244CD3B49E40934F90B454C983DA38B2B5C88521347788F832E9C64A6CD012511234275C9F6C251442A87B496743333A161D8C04E3D78BE3097942AACCEDE09B9CB673E1FA261BE71DBEB5C4E1049B2B2A00311ACAD4470F8AFC85172476B949AEFBC0110A261461291B5FF7A74697C88AD40C82770FCCF68B9AD5382125879E637B7CEBC1AAE95B03219CF2488B2E3B2E51480C8CD8022C2092470236FE6042DCEBCA24CB9EE9379386D80E54C232DEC93B99B694E99AB5E41CC8CFB8928D5C08EDC7A707044B49B8A131986A3F37BCDBCAB5255B64B4905A93A719D01A32384A87543B6BA1A22DB75C9BAAD257BC8B9D8B78641B394C7AE064087454CFB17B307BC35A97CCCB842602990747D60F30D220ED3171FFD7A2B77049DC210E2377607B817F24C011DD736D7918874AEA4B8BD98BE4597242C95C9641B194A093A928B8D3B30F33C10BA326943A8B704C09A6DFA55F700C488C38A3334716CCEB6585008A853162E40A544C0A16878328F47C4E67B5AAD276A2DEC4C320047E2EAB345CC14982B96D1D13566DA409E93072377A1729546117A04CE291A2090B60030A35D5B360F9F871CAD52F37E63954DA0E0A8675ABCC3717972F89469978730607293267CAC89E3C96A98576C2351D8756429722A1278A173A75114BAA4F0EEC6A12B09CAFDC99FEE2C1AF7ACDAE3C747B94B06517464F654ADAE25888A15CB4C5017076C9D3FAC3B1560DD9112D88B2BCF31B15AC420FE5A698D52AB41EF33FA6CA8D8CB9B94D58648F39A138974E8016A972308C7B040D2FA32BFD1096503A3A0E84B9941188A6720E06E6641B896D365190369766995826B72122D780477581BD69B348BB6C5C8F65B4D84AC3F0768EF6645E422B3ED7E38D0A423409C285D0E21BBCA97BE6707557BB0027E755F9A81912D04B9EBB374BD79411B2C283068670431F2DE58D346BB525D192F128C9316742115275E9214DEF7A61DA509B5848013B304216F783D77C3F57B76FB8DC984F05AB557709DAE4691B519C44D41813E4B61E6664AF5C970AE7A810714217745AF087BB00575B18081921A854B7D953E29CB1DE704E6578283292168EA73A03E2082B8B641C819649270011861A7B301DCEF74E9B116A86F717E30BA6C5398E34390072E20C82F570FCFAA2BD8847A7187052E6B9D0D9BC9FEC0217373BCC7B8D38245E40A1597077BB00A408E9EB2BB451C31A746D2AA07FD6432CF176382B6665D45343CF32731817023EE046577ABC342BBE25416DAEE417F2971A8ED4C839126E996A8DB40A55BD424C0E534CAB677FA1C6B692D2B7E322A331305F75289A1ED102ED604722737E76501C7E7ACC69842D6FFB2D31D1003C3B3BD8F4458D93B0270CBA21DB21A7D16E22E18584E68EA5B890EE839DE75B68D60B25D5452BBB91658F3220AAAB200EE7A8F070A5B5AA7FA30A768275970012324FE01910E8647945AE6F8B3A17D08E5C36AF468A7F6308751C4141439B567EAB03D72538DDF71DEBD2AEC5DB13537A2B0130B4C2F6662182BD08EB750EB681FCE77981A3012102C45642BB8A44AD5CB27CDA8369EC28190F64987EB600101ACEAE7A807158CC8100555A82644B3B513D7CB283A363C70A4EA090241C8A96AC562E7FB3C38F3515C3A68FECB271713729FB77A1A68695FCF995855749C1F0AE09F90741EC332E7602CADB69E55438B9D8CCC213119627410488145777907D280DDB7391D2EC9F27371277C266BB1B14F6EB8D46B2C8BCCB0C68F3BEB2D87B07044904D5B08E84305B0686F923985A49ACDCB1A662D1A08948C9B8D95883518D0AD3933976C464A41C18351216D84066D71164A32D41886A153703C584B747555EEFE8309F0810D49C0DF8C5512B245F637C9448C47E1456995E922460B8210C7AC1063047C3764077288A1345C23EE0C8FA6865FDD52ACB49614207285D241C14114DB55CC0C92049F3537ABFF81B8A30A02E5AB013741B36D92191691B3197CCE8D2328BBB6FF61932434899AE01412B231B0EFA18D8381555866091C77981E753F8A2B95E8095765EF7A13BD38F9FED3BF36477916CB802690A213C83F6624A067A5E2C9510A2A0B4FCBD414FC61AFF04A8DF579660D14B13C40EC0470C45F639B65A588AEC87A9A79204CEE2986867A2906EB851B734B8B22B91D6749B1A5F07C44E3B +ct = 9DC66C77C56800C40A5E71DC3CF139A83AC4308527DF4ADFBD930307EF72D020AEE3E44C3D548C67CAD24E04C21FDCFB69EF121985A565CC897A06CD2C7F4CDD767A5FF8F9353FFAED3363CF5F315ED386AF41BB5A3B0E395DBF12DD24FDAD29FBCD6056FBBC6D354739710EF74B1F4F7C212785F1451D3FA18443EA1F8E4357B7D0368C086C395B4FE548240F7F085DB4A361490412D034363F3514ACDA224E4F72FD7AC410FEC9D7E194FC9F074E8435D4A2049F9FA8663773D1087AC0721AF6665C1057AF23C2B5F3C478F16DAF711BFD0FA253DC1185F008FB8604568EE21C8B93CD1C0BE2CF4D7869C9DFBB94F4B7A1C038F834EF1B45144E8C1C4F3A7587CC0F9BFE3C6A2CF22AE9B835EE38B6D6CF89AB32316D307DE771DF9444B6B23E7054182CCF799CA0D0D0D3034DF22AB6FC27C507782E8196CEA3550A76B3246DDD1B9EB68AA110955C3F3FE19EF762CE5EBDA48A0B59DCE90550293AA4D550CBE5AC94E5FD79901D11B7C5BB261C598CF0C49AEEF25ED8ADB9042791B7377035C41638BB4D06551D80472D159A33854BCFA31555D95506466D118E6B2051E900EB7BA9B6DF3CB9E7D51BA93271DF965F274C4370266F8D0E1EE346D046250486173F96FFE819C231AE3E08EA12BDB2EE3B47434E6F68E19DF6043465D145AB978860DB6918995DC8E995069773ABB5F033EBC58DE26E6C4214177F1CEAAD65FF523FEED2761BDA7ACBA7340077FC0CDE9A938D3B333333FD32B9618459A180D55A34892E6B569810ACE45421980D9A1A2489BADC1E617F4E5A8B3B628DB737AB8668BF047598FC79FC74DD21FC783DF41833E033688CF3915F8328D557C1F482FC78EDE767EC705EE6767D25691DFAEF3A1EF7D076480CA1621888C6282FFD037FFA0128769A30530D92EB7FF4C4E1C86C0D5EA911C7AA2F2B37F1019B061CD6D6BF0F70E76E8139131EE149AA4197D2F2F284CAE33B96B5FE8C5F846D277C59F04DABA036DA670B821A4E5FB0532D0FE03F90AB8E223F06EE5FE9D982047DEEBFB69A02B145E703DC60AB95918971CA3A25DF7C32DCCEA0019F19D83E245F532F5207F8ED19D9A2F7F94F22FA60B1FB666DC21CCDEF046215C50095301D2902FC0D4882908A16B810FB44409B9A23D8228D7CCD0D510051256E4879395FAABECC95542C07E8A07458FCE35D1D882606B41794BC69481E22C53F7BAE8B5BF6492BA14AC16F8E80918360C3C7BE0F2E6985A2C32CDFD36EEEA99B2C5C140CD56E1AC51ACA07DFB53D58D8DB395A28057AB62EB16DE9DA139DA54D4934DD7E5E0997F35FA77FCF0E9C6387E854DE1D9DF06950FE039719B5F278FAB8BB81882EDAD67369D0D0FB1ED57BF36B00D961D87BDE080787729753A9ECF0A48F5B92A369FD71F8347E97170CD0F0A9CED646A120F73A414D6CB8217583BE56255628CBBB91F088C2CA1B1C0E0A302D573CE50D13F22D76AD4DD03908B9A84F4EDC74A234C16CD210E4A7D4880F96A43AC6C003D011CAA39CE78EFB2F8731FDEF17B6B4 +ss = 1F8D087B541B57A9D85F0737C39E73FDE01DB5BBE539834D8F918426A57DF9E5 + +count = 14 +seed = E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260 +generateEntropy = 38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +encapEntropyPreHash = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +pk = A6BB3B93C181B651918A25235E22779CF052E1D30E6852557CA32AAF841834B423A9E61CC24B5231D7590F863E814AA19F123C0CBA97CB3773740871AC23868731748355A85F03B275B3273486142153BE4920BC9EE77AB5C05D2B96228906586EC831EBE8CF6F9BAC3631B7CC904DFC768B1A717274B33F70D08B6A79C4AEC3597E1C9664C9472B6C100C1601F27BC0AED37152E20B327B5D32646F2980BD780C8F476715AC04BF1E03C2D4A31DA23B14DC0233C1A2C2D983627BBC845F023E349CA59626A99EEBA5DCC12E8B82076EF2295238667308451C2052C6F9B127778A3C656213A23DC7E25660443183298753475BCAF667A9483192C6BF553B7E50B44A84A4B881B0365FE513FC661A03689581E045D2F921444C6A76E6344ED8A335B6681CCBC7B42B50B9B03558C64DA65088F60B136882012135A8A659355503918BA25DA1C167B9FB9F771B5727493C921338C1ACCCEFA80201039D28C968AA3A40C2A28835F63BDE23B9722A245EE3C859997F45E10A11F1906C1485B0B51093F51819963393A692ECDB1DDA2C88A6133F69F401B124CAD796217C818152A528F7D073BFCB9EACCC6CC8825AC4612533126C1CCC736DB53F648201FF29A6C3F77B41E01DE2087986F237200014E5FA540735513400004B5925CF64B0FFE9575E27AC19AC5644F355231BCDD70348C4507C80780F1D51ABF6AC4C5E2957A94325A3F64E83A0A192516F6CBB40B8ABBA5F8B85BF2AA60E44B46585BF009A723FE1A44FC97543F269F670C593935BDF87A52A1A31CD2B9AD92807407B5851B49EB1A2318611CACAA7710B6764A7E57F8962BC3FC483A8393640E602CA55526EB1BE56F2C61CE802B9592F24C14AAA75AA4B002AC9B81FC1327B2A93AA889C9EB178BEBDC91579CA7BD30796CC324447892558D2C052308946A451CA49816C06AAD39603DD3841EF03CCC1075DF164739FEB342ADCCE87AA12F550200CE94765EB4F291A5152941B4EEABA91C3A59257C03017C0B7E0003B07657BA60B4256A8A4B205D7646813246385B348EC157DC6EB3BE4546D7EB85C29512840018968743D2CE147F071C8F96C7436596337D69F5074485BF4A288833F2855787F8A18D874C5A2A41422157F65B62B5E581C2181A7023698FDC1AC60A8340A34B29F81B03DC35DA2B453FA61293070B1C6DB57F3040C3AF7766C69B84D624DBA1163FEB0C71FAB6582473F93C8753D67B0259A2EEE1C847B1B8A73455A74FA10C3A4C21A35AD20FC36D563BE9BC55350F565E4076670F0C77B3C4AA2A06F7BF2AD1BFC4FC8721618454D640189A6F8B3D6C71086DBA68B213F4C51100A6037E717147893CDAE20A97759204B2C684D8206FDCB10DF575799AAA3DE388CEAD4446DCBA8E14368F7202520C71E453B41CCE426BE6C1E29AC475C45742DDACF7C520DA15780A9056183900559129E5E3CBB3FEAA288B25B6FC69BB8B164C1DB8E24391172A8C23859545E98A13725130E45C3D1CBB5D6F5C0DC275608163916013E6E466C29502902C97D3BC33DD006ABAAF2AACC40C046E55951D744E31887155A3FA880058A8767B35684445982767C697540CE339A0F4C29C2AE42B5DAC5047C12C22BCC155A63A8610DB945708CB5425CE0C3C651532A43D32473F236519D54FDFE0A815D +sk = 69E774DB244D05192A2E064257F3A7B9B08941A2018ACA28C610B8BFAB59176BAD88B9A7781222CB03AABE6A4C2937BE24645A28C3A7931240503769EDD1865F72B44C4842114980BA64A59A647438C5476A700D0DC4A63277C4DC73A3DC9B59BFEB0DDF0817612AB73AB14378E93FA4982D15131C5016B36A639E4F689E9B6B2D2BB2501E130EEDF72AFE4861AE7CBE7E717B4C4001B78BAC719C6AFD40969392CFB1D918794B4988A7C03A23C8C5A751ED2C39D3E18474B43CF8B7814A5932224141FD543871AC102BB0A349153EB4A13AD57AC06602BFC6C1B4425284EAD058572A1C7C0CAFDC6756555B2033D2CE67F9155B16726625928EA26D13E2C0C0A66988EAB99643B4CF23AC68724CE635188DD8B3F2F421E8E8A9F838B707A16FBF27445A7555CFC052982CB002130CA3500CC428AEF14281564997D5F37D0A1C411CF73D3D2082E4C26C3BB7BEB9FBA2D9EC631F8953B3D03075318B4B720B4FB5B177D43C11E8979C640639136FA20B718C0846404B2F0604C55CA82F519241D811A697000DBCE1C743410E92922E83446410A93150178A4A2B52123174DB128B2EB97DF4E8A617D5876AB9977DAA8B7845537DB0A2B6E0599C0CC165438329D1251D6AA09D5B30F27040082A135C2B831B7722C416072C655C4D511E1FDC0284932849126D49B5A03B3593894BCA250B0D198601A02900C9406D8F5B69BEDA735A3512BD355DAD587BCA7330364031573B44EB9C2BD103BAFB7283C1B923AC3A41F0607D4B7B7E1E681AAC9B4090538B6B7975B9C5C64C6196577B7861CC88ED6C3365AABCC9B97A6A318A39A2BA8B17376509A563B58DFBF4584E6B00D56BBBEC309164982D1B906635A146C04BAD613C02C8E2C2D0597FC285779C628F3E290A84D8710745C444410F129A140358991D601FDC787FAF4506C6003E2130C2E03B3FFED39CA3B9BBAAA34ABAE794D4266E59A80EFB44528B2B234D70025767A5DEA09032767722C61E53423417458DE9E809A42257A27001E9C8AD43B775BC853D8475ABDAC86811D568E9E38747618AFF0B0901283A3913B6595CB2A85B6D42101DCBC90146AB85EA5449850BC9D8B1356F820EF365731F176EC0A0A5B7F35D9848C426F32D6A37046574A93CFCC043614E8708026621A06AC00582DA7B64421D4F50AAAC1BB10D6BBAEA31808712B891344B7B865243614CD706C2DC098B0A069FCEDB89ECD67DE8319C92F3AA0A9B92A1FA256302587A5859408B5CAB563EF1814CEA386BECD756DB669FDF87A003EA1E7654CAB281220B21CB234AC1C4B459EE48517BC838082191DE35B265D5264119C05CB500A05307C806AE8246128A8194F61024F5B2B7C410689150C0A8F68E1B3A51DFAA834B7C8ED989B351E683AF7BA73DD91E9733282FA2559AC53AA2819811190B5827000D98433241A3DA2B77F4E588B0088E3D3318CFD049C4777F7B08678144618E2406B9B6B72698888C4529B7E3B272E92620BB36792266C3DA4C9C403D1D49650B5530BE017C3B99C068890F2705702440AA0BFCA823059822C18981A03B16670E127386265487665ACA4C171E023621A853965A629757148E37833D31E453DC9B20191C94230833A6BB3B93C181B651918A25235E22779CF052E1D30E6852557CA32AAF841834B423A9E61CC24B5231D7590F863E814AA19F123C0CBA97CB3773740871AC23868731748355A85F03B275B3273486142153BE4920BC9EE77AB5C05D2B96228906586EC831EBE8CF6F9BAC3631B7CC904DFC768B1A717274B33F70D08B6A79C4AEC3597E1C9664C9472B6C100C1601F27BC0AED37152E20B327B5D32646F2980BD780C8F476715AC04BF1E03C2D4A31DA23B14DC0233C1A2C2D983627BBC845F023E349CA59626A99EEBA5DCC12E8B82076EF2295238667308451C2052C6F9B127778A3C656213A23DC7E25660443183298753475BCAF667A9483192C6BF553B7E50B44A84A4B881B0365FE513FC661A03689581E045D2F921444C6A76E6344ED8A335B6681CCBC7B42B50B9B03558C64DA65088F60B136882012135A8A659355503918BA25DA1C167B9FB9F771B5727493C921338C1ACCCEFA80201039D28C968AA3A40C2A28835F63BDE23B9722A245EE3C859997F45E10A11F1906C1485B0B51093F51819963393A692ECDB1DDA2C88A6133F69F401B124CAD796217C818152A528F7D073BFCB9EACCC6CC8825AC4612533126C1CCC736DB53F648201FF29A6C3F77B41E01DE2087986F237200014E5FA540735513400004B5925CF64B0FFE9575E27AC19AC5644F355231BCDD70348C4507C80780F1D51ABF6AC4C5E2957A94325A3F64E83A0A192516F6CBB40B8ABBA5F8B85BF2AA60E44B46585BF009A723FE1A44FC97543F269F670C593935BDF87A52A1A31CD2B9AD92807407B5851B49EB1A2318611CACAA7710B6764A7E57F8962BC3FC483A8393640E602CA55526EB1BE56F2C61CE802B9592F24C14AAA75AA4B002AC9B81FC1327B2A93AA889C9EB178BEBDC91579CA7BD30796CC324447892558D2C052308946A451CA49816C06AAD39603DD3841EF03CCC1075DF164739FEB342ADCCE87AA12F550200CE94765EB4F291A5152941B4EEABA91C3A59257C03017C0B7E0003B07657BA60B4256A8A4B205D7646813246385B348EC157DC6EB3BE4546D7EB85C29512840018968743D2CE147F071C8F96C7436596337D69F5074485BF4A288833F2855787F8A18D874C5A2A41422157F65B62B5E581C2181A7023698FDC1AC60A8340A34B29F81B03DC35DA2B453FA61293070B1C6DB57F3040C3AF7766C69B84D624DBA1163FEB0C71FAB6582473F93C8753D67B0259A2EEE1C847B1B8A73455A74FA10C3A4C21A35AD20FC36D563BE9BC55350F565E4076670F0C77B3C4AA2A06F7BF2AD1BFC4FC8721618454D640189A6F8B3D6C71086DBA68B213F4C51100A6037E717147893CDAE20A97759204B2C684D8206FDCB10DF575799AAA3DE388CEAD4446DCBA8E14368F7202520C71E453B41CCE426BE6C1E29AC475C45742DDACF7C520DA15780A9056183900559129E5E3CBB3FEAA288B25B6FC69BB8B164C1DB8E24391172A8C23859545E98A13725130E45C3D1CBB5D6F5C0DC275608163916013E6E466C29502902C97D3BC33DD006ABAAF2AACC40C046E55951D744E31887155A3FA880058A8767B35684445982767C697540CE339A0F4C29C2AE42B5DAC5047C12C22BCC155A63A8610DB945708CB5425CE0C3C651532A43D32473F236519D54FDFE0A815DCFBE9649D9D1C384BAAD67B91B2F3E21F2FADD6BB582A0B9CB016051DD82C75AA2ACF359556DF4A2ABAEB9DCEE945829BEB71185B4D6BD18B76E5668F253383A +ct = 438BD56B10F4813575D7CB4D4F502AF16B0CB43BABB8B636088AB627CADAFAC7FA8A3B3AC3E8903C6F72A6A060ECFB81F2F86974E324BFC5A6EECA115AC1F632BD83BE1741204499997E1255C547E3F6F4D2B4C92D8671FB3342C1DF8C0B1B927E33477D589F74732BD047DD9898CFE6293D1F6108F74924D68215CA691552AC1CA07487FC7099DB19BD26B16B4474873D352384ADC22AAFA0C36CDFE4A5A486372398E2117A894C3FF3DF86F724553A419362BD1AADBA1730A85EFE908BEEBC4AEA15C83A02E0C5424CB39261697E3BD534652DA23B6E64118DB7A355438BDEB1D3D895D281F0B095871EC4B108354DDA84D252C819019FD3C0469014EDE38B16FAF69F12688FC7A17FF074414A6157E4FE4C9F92699D3B57D00D31232FC8BA2A05B4253CAF6E9F550FF9DDD063B4D2939A5431021450DE80538614DF20CD2C21C644DAE73C1621B6B7DE5CD08EA474383A9F842E69EC29C37BDBAB43012313C984D8EBDB386DDAD5429467F6E3CA94D1EEE89F77783724ADE7D1D375C6DFF1F483D6849BA5CD09C6EB8740CB1BC463F0D4C9441B6F248C029D8E94F994DB46E892C2B546C1DD3C1B71C78BB5B4C4D15F3F3382DC075E8CF29AA3D4700DDCEC71BF6C836CF84FDFBC60C145DBDCCC49929CC989A206E104A72A6967ADC2B1CF682BB4AEDA52475851DFC72EF76A33231DE8F44266C13CF3323FE8142D73FA5A6D021D31C15FB95DC3998BA113154ADB6CA2370B9627F7C15A8E858C15BA769AFC33339DC55F783322C41FDCE25EFD438879EEAB6293A1E47C5089C1CFECE5F194740567B2488998F7B10D0C63B5212F556B2C0B1F300A22A54185AA8431FA20F2C59B898339C6A9A2462EF5330C9CA2CCABD333666689753440882152E7CD74F965111BD75AB4A1B9D50F8F09C8E63268CCE09BE63C293E875C3CCD5518C2B9665226825FA269D8D5C078F50ED5FA2B0278E75E7AB2444FBF4C4B33E3C2E9FF7EA7D720208A582399D0A381CB3EB087BEC172F99F76948ACD97D7CABEEA2D2EF4859C087DF9F8216B904CA595993D81CB21FADB7E5DD1BA854DFE16B4E4818A2A4C7BFEF3FF1F499D30CF53ADF2E9DFAA03147931760A359213F58A8ACE9BE58E50B888F85CA6F022F7D1C152743E341B68BD6DF17CA099FF891A5F702E8AD845F092C8DA5A5F584FEBEFBCD0280473A7F4AEEDF0701D7F69BF8B94311D87F1C03222EA9698ADEFC602D7C4FB8ACD59008AF4FDD75B5A930323B742887A0D91CA209063754E55E21E8894FCAF8944675002244D0134A41E43270A9E918753C1224D2992B34CD5E0B8C1E79EAAEB74B70A215C7B75E9298C7AFD0F4B26CEC3EBD13D7462FE0569BE3145AEB4393B3BB1F5D13281C7FC4214168E062F76D7EB2A7B7D16A1EFBE155025CB0085DFC4A706E79C0670CBFAE9BC7A8390C6DDDDF1FD4E83D56D242AF36DED7B0C38BF82081C631A3905EE477F70165BCBE327658768EDAAA49548CF446AA574B7C97071EE2D0063A8D8D2FEE0092D2687F60E005BF0 +ss = 0DA3B9B56FA25F4CA356D3206B99AC83FE84A09CF7FD55A33268C122A8FB51AB + +count = 15 +seed = 669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488 +generateEntropy = 97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +encapEntropyPreHash = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +pk = 8452A77401C4E343BDCBDC985B70189EA976E3D65C47649593C9CFC112A4292238302253118CAB8EC52060305392E6A131F0445A0BB4E11A1A8D7465E704B3134C3807D9BE9F8B2ABD57A00758685392592FA0B01E116410706A669A0EC5ACB524D1561A265E307C24068B12897568490458121C572C2CC43B2464F2703212641202A40B27A41FAFC4B24BEA9F26711F28B1050645A38757708AD607FF6763F14C15A2CAADFC2BC4D23C576E5CAE6A20B10CC9CF610A5931AB4C59ECBE67EA079BC3911A96B24B86A0D6B99CF85AA44094B0F6C55924776C4E1BC9CFC88A127B8195145DA3515288F933DA602F1A2747A6856657B2102774BC1946163B534D02A1CE2E641CD9FC7F7D48B6F643AB53045BC690A249433553845B34A5953C873C1C686C83BA46ACEC4E91046F9E7590196C9C24A747C6D986B4B414C223A52A6C88475405232C78AB3AAE8861A45A817EBB16C3A3070B8E842527E965013244FE50907BAC3883122393340B1E06728FA0400791B1DC3BA103C8AADB6CB0328B5EFBC85694164D0934C207B63614CCA28ECA71E5F63A58604599EB6D1D248A37EBCB17335713C4C9A0500FBF893DF475CF7C19792FD56FE0A7505DE0158F34603E0071B2AA0BDC8A12376A1313F571D33686D505660C4BACE8EA40820918E05BC15B381B90D9B31BF52E1B18C422C3935D04140170542829CDCFC883BC344606E75A2EE7AF469C5A81DAA1071771FFF275F2358472B409B1EC31EC887FD6E76CEEC6812D40BA4469B3EEB028A0A6875A19B7ACA51465CC3FE78566A3EB1B98C621EB3BBDA4E7BEB5F2344B64013EC233FB5714BC68B767DA8B60A6B0FFC8565369C19877C16D7C70F17B85F7A228D28A5936968915D026CF683C762714830C1742AB4DFF789F1F43782622A070A4AB52633EFC52693B695DAB939BC24944733905AE86801C4577324C625159B141C5A1014A6E458B71A959001839C461E17A3AC46DA47AB687D2342FF63B83D3331510C98AC484F44B7FB6A31F6926CF047982C400008BB3B0D1EBBA3CB2345613680531B0708A64B937C88B2985C01A10EEA22FE5022912F9AD2BC667CEA16B0A091F3FA9BBB9B8C30160717B21CEF9D74458241BEEDC215D44900CF40709F6671F221D39C804EB6756C812364DF0503355B8B01102574AC3F07234BBB1B658EA822D52A452545DA3544C041C3A3F89BA30005A992B432178BFBA078686A07971601F8B12C22B23B69C05A89ADC2469287F052A6D4F58798E10A464DB4AA71AB30A94854D1B8C16893B432A8DC2859C66A168C8C5AD4D04559056C4588B0A8755013E378545B47EFBE90CA97552C9B8711D3281CC7B9057F78A68A59D5AA642D1E9233DE093DF5705D8639D702097F0DBC98451A46905AE72D876E1243546590599FC5923B37B4CF0A3F7CB47DFE8AF00F6A999127A256681A5705BF5100D7096713C49149C7C561C0783E048CC3444776BF8997671970535C2CAC5360C9B53E0D952AF348A28E4826DB9810F07110A48771C2C9B21DA3CA719C7A5407B92020AAA0180B4D6B3AE42A1C09CA38FA59D1ED02A3A0079F2E922D0B36D9795C1FA42354CA51DDC11A315515A45BC7E1E21BCD3287E18BB0AC3F8119A88D1FBCE1D3419BEF67B6694D9FA1BB309CC61C819176964DC +sk = 48C78CB714B9CF88A8B317A6FBB681B8F47D56524122156503823B600236D3726EDD9087504705CB4698A1515DC0D80B3F87C63D575170F45D121A848D897C3C0063DFE9B2D616A96552384FB72D6226A193F90E15B364AE667C34BA27FDD0AC0DEBCF450578C6D182DA365D40786522C37B54E0126ED7B3C6BCCF28F40770F23736B394210B67EBFA72F6B27799FB1F6E48CB7407261A86884621C529974635B35F5B4C530E68BEE8CC213387B66A4127D01223180067A2EC24B2EBB579F74BFD5417FE995BBF816737722912B5B4DBB4C938D0686D1C2A44880FA7231944C195FBD67C67E60861D169DDC41F8150B52A68C14425190BE2ABBCF5BABB734AA03538899678D4290738CC63EEE611E4344EA73B9C41F36C712A4C6C72422000CB93E144F3C588A2299D5704CB347B90B2905CBF69CF1DC5C670909C478094E88C01BB3B3E4FE246F8DC3C62DA37BB13B6E2046911D85D5790869FA4A54FF16794620480919C0DD74B9887BB5C125C34D76B3527A42A46B689FC4C57571AF13C44B7D30A041028E97C0A1E50621567374DE7A4207ACD4CB18417C7984645CF4F2B5A5434BE8F119798C0760229301E14431B0B652C643C0EA0CCAA13CBC6FA6DC8D348B908B78343978FD5A0EEE90CA5104184F33F107837B3EC667EB207000570DD33856939BC8BA671B3731EDB2A94596A8F2F37BBBF5048087091FD2AB164F5C6A8F92F65239F08844ED4F605E3BC1BF780877EEB3F4C85BF696C691F85A947461331AA33B15973AB4923F429C7913731BC025539232217F801EC7078E2F0AF3EC7494684BFC40B4FF31798467746F60BC9BCCB5B1E397DFC6165773A965E55034DD1094966694D7806F2F505CEBC3B3DC307405431FCA21614089C633B522510A5FCA73462B32FD69200DC614C5E88454F181D845B19B8866259A2372BB3361B9ABD5AA278B1773057E26108BB020A9610BC19AF13454DF46B4FB5A68C3E7ABA6E7197AD63439C7252CF9507E32072E437296883C93902250165A1AEE8BE0CE6ACC2029E10E97536EB958B691AE3E3AA9996986805C6D1F6356D26C1E63C550381B292FB1B95E183CA933D5BE1BAF6294C4B248B4264724712B2A2816ED3D09042287EB8A17AD6C86255AC492F53A21EBCC19B3C8BB1E78F58BA98BC8AA77F6A5CB90C0456E1CD663137E11185536B02D8708644539701B193BA52258064B289D053404BC78A397AB86895BAF1934E8B2F6CC3AE48869BE7422E581A6FF748519BC30BC96C716B0A24A02679ACD5151CB2A0FA127C81EA513C3CCC3B84A34025522486CE424BC04C860EDC5758AA990FED372DB324614FE91589D78ACC88C43C2643D540A509F090EBFA6214832C76CA982FAA1CA4465F9C14AB4E6459F072558946CEBA113B5FC7024A364970C72933331A6A4B0D4196B9E6219595E229F3E28FB2D5C6C4C041DB226AB611B04C3A80FB5A7F15E08DF3347DEF02663AA39409AC4E8C8BB0934B46B6A8816CC70C8C0B11A7EC1CCE57BF5BAA30E69207D7E59C9E386D5CF7863C133BA1B510F5E06C4876BA7849611BACC369B039EFE173DF6B8A22469E1F200F2AA53FF84390B88302D9F9915C4B8257754B3423097E7C6B8452A77401C4E343BDCBDC985B70189EA976E3D65C47649593C9CFC112A4292238302253118CAB8EC52060305392E6A131F0445A0BB4E11A1A8D7465E704B3134C3807D9BE9F8B2ABD57A00758685392592FA0B01E116410706A669A0EC5ACB524D1561A265E307C24068B12897568490458121C572C2CC43B2464F2703212641202A40B27A41FAFC4B24BEA9F26711F28B1050645A38757708AD607FF6763F14C15A2CAADFC2BC4D23C576E5CAE6A20B10CC9CF610A5931AB4C59ECBE67EA079BC3911A96B24B86A0D6B99CF85AA44094B0F6C55924776C4E1BC9CFC88A127B8195145DA3515288F933DA602F1A2747A6856657B2102774BC1946163B534D02A1CE2E641CD9FC7F7D48B6F643AB53045BC690A249433553845B34A5953C873C1C686C83BA46ACEC4E91046F9E7590196C9C24A747C6D986B4B414C223A52A6C88475405232C78AB3AAE8861A45A817EBB16C3A3070B8E842527E965013244FE50907BAC3883122393340B1E06728FA0400791B1DC3BA103C8AADB6CB0328B5EFBC85694164D0934C207B63614CCA28ECA71E5F63A58604599EB6D1D248A37EBCB17335713C4C9A0500FBF893DF475CF7C19792FD56FE0A7505DE0158F34603E0071B2AA0BDC8A12376A1313F571D33686D505660C4BACE8EA40820918E05BC15B381B90D9B31BF52E1B18C422C3935D04140170542829CDCFC883BC344606E75A2EE7AF469C5A81DAA1071771FFF275F2358472B409B1EC31EC887FD6E76CEEC6812D40BA4469B3EEB028A0A6875A19B7ACA51465CC3FE78566A3EB1B98C621EB3BBDA4E7BEB5F2344B64013EC233FB5714BC68B767DA8B60A6B0FFC8565369C19877C16D7C70F17B85F7A228D28A5936968915D026CF683C762714830C1742AB4DFF789F1F43782622A070A4AB52633EFC52693B695DAB939BC24944733905AE86801C4577324C625159B141C5A1014A6E458B71A959001839C461E17A3AC46DA47AB687D2342FF63B83D3331510C98AC484F44B7FB6A31F6926CF047982C400008BB3B0D1EBBA3CB2345613680531B0708A64B937C88B2985C01A10EEA22FE5022912F9AD2BC667CEA16B0A091F3FA9BBB9B8C30160717B21CEF9D74458241BEEDC215D44900CF40709F6671F221D39C804EB6756C812364DF0503355B8B01102574AC3F07234BBB1B658EA822D52A452545DA3544C041C3A3F89BA30005A992B432178BFBA078686A07971601F8B12C22B23B69C05A89ADC2469287F052A6D4F58798E10A464DB4AA71AB30A94854D1B8C16893B432A8DC2859C66A168C8C5AD4D04559056C4588B0A8755013E378545B47EFBE90CA97552C9B8711D3281CC7B9057F78A68A59D5AA642D1E9233DE093DF5705D8639D702097F0DBC98451A46905AE72D876E1243546590599FC5923B37B4CF0A3F7CB47DFE8AF00F6A999127A256681A5705BF5100D7096713C49149C7C561C0783E048CC3444776BF8997671970535C2CAC5360C9B53E0D952AF348A28E4826DB9810F07110A48771C2C9B21DA3CA719C7A5407B92020AAA0180B4D6B3AE42A1C09CA38FA59D1ED02A3A0079F2E922D0B36D9795C1FA42354CA51DDC11A315515A45BC7E1E21BCD3287E18BB0AC3F8119A88D1FBCE1D3419BEF67B6694D9FA1BB309CC61C819176964DCA19C2C9C907B129D01CC44A95949121C39534CC98B6D105E60FE519A000CC2AEDF05318B5F655EFE36F1B678CF4B875108A18DB2FA312261CAF839F84BD956C5 +ct = 38E00521B95D89079394AEE0B444233F135FB37AB4337A575430DAAFA341059049A49D1E7D3B6EC52EF44F73154A6827BF791A2986309C7D88A855A3E278F42880B35260C340E913FA227D0ABCA526065DECA1837ADA0ECB4D4911BDE561E6F3624AC6F4601CCBFB5851DC74A80B5C3DAC2C3B3E4FB0B1D53653C9FFC4440025F70D09EDB2EC62AE4330A85B0E1D1936E9EF2E82A7E7C3C61E74252A997F4D5B0A5C9070D3DFF6855455C94D22498583016B9C108F8EC0D80BAD19272D982A85BC2688736D50FE7BEDC3D1DB893D42331A60658A4FF202C46450D24A2F1F5BB90342D26904B0E07A3E5D23DC9CA9E8901FEA9CCC49914549A913D8CFB3F0ACE306176E377624DF734967FCBA76FE125BB1B7D9FCE809617114B0F761B4A8381F28F20B5B53DA07B0B31A644D7B11FE444B9B59E4110589CAF921488E176A830DFAE522DE3C651A0E17AE0C42CC9981E906534CF95A013653636A655EB564B89ECFA9C538CD3C6D8AE6D1DD541538CEC73669356E18F2D7D1B668C5A7BB9B9F6F96A590E31FF19EA85FA9AB51418BFE7ADDB99D627645152AEF8E518C625EB3B49F22F93E827784EB5272F9D04826A04D89589F52E16C7B1B48C4C5625E76F2DC8CE6E1F092F9CB9157766E15286149513BA24F9F64016B165E6441F97137629526343520FFC30BC48B4523FE68813885103D0289501275238B7E9F5832E5A0299804A00E3AFA2F1F3D0A247DB2AE9D58D3B8FE09763AD0C5EA658820C540026D4CC5A1528C63BAB66AB97CA8E4F1C81CAADE9491DAAACEF0940866756CBBD61047D882E3150AC1E47DFF9AB68D4B0C282887AB37E2EABE5B265B9BF3910C3C24B8125752F4006F9625918D2DF1FFBEEFEAE895C5B31D865F16EFC9FCDFEEABD6EB1A688FC45D197FE5D4CC8CAACFA1E264A203234375D8A4F141E25FB263A63EE1FAA6842BE1B935956494775B379D91D828E9981013A7E6CD049EDE515D4EE4BA74976C9D68417A27FFB03BB3E2A0FFBD8C801C4AC78C41E9CAE33EA6BC1F9A8ED736724F9EDA52E3E2BDC8BC11E67DEC594FF4AE3DEFB5B643CC5C607102270AEEFF76238D7B5FC858F7FAFF305F300D99EA7989E3141DEA159C32D622B693939F100E8F5B4A633C7BC6E3255ABFD45DD80C7AEB51896813864FFC75CEB576B681F8967C14C720E01950B6DC7AAC1C845EC01E21F378A8B4512119B3DAF1EF9DD5FAEADA667F599C953C0BA321B3C2D03987F3B169C3E5BB4ACDA824921759E557DCCDF82EBE520EFDB1D3A3F082AB063B51ABF1CAF89057B807591A977BB89C659C14A2BF12154956FB3EF13486130272BD8B8655BFAF83A304B85F38D07CA0E5D5854191F0B21B59296A9377E83972F665763D405CF4C01D03104E4855D3B8573961446FD1F5199A6DA97AFDDB8F4B0822C4A1E9F668D04DDCE81D0192F32BF8D0B94AC57895F3209E616D3449309832DF9FAD95233FDD4B3036AC0075E3DC2A25D70C1B922FC9925F20C296A93F307E5933B4C62AE1947EE2D35EAF6389 +ss = 806390146332DAF2AC2CE5499D2ABEC128137CF7DB02C27FB457663C18A0D7B0 + +count = 16 +seed = 9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048 +generateEntropy = ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +encapEntropyPreHash = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +pk = A16730C3D8A8484295A1D995716A3BF93C7270671AFB7886F397AF65F5BAC1B1A1A49084D1A672A1F98BCA762287E90410AB01098C74869B42479C2CAE5906AB354970C05CD256514F5C2E763230B6770884E7B700544977993DF1F57969E0265FAC4F474B76648B36F5711163638069820232B8A64F16BDE83557B0540405D7987CC39069923DFA984CA4045999A77483E04FE6EB0BE954A74C13CFCEA79ED0D8124B01B740A26ED961B2BC496CBDC539A10B8151E0078F66751FE78D2F3A5100761C8BEB514923A7B4F3AE208766FD852222DC31FC1A59A883C401459DC73468EB35AF61D28EC1DA147C882CC7F5AD5204BD8DA270E4C91DC37BAAE1811CFF4CBF8605BB48AC8585094327A8C17527BF5B3968AA268E152B6896A288A9722183E199F608CD7A412CA949113E87A956E4AD12737D53C3BE4752533BC755F7A1C4B07661E988210AC72131B4496941893A9C6F1180BA622436EEB02F3A3A090C00B1FFD310E811A7A8B87984D275D76B0F99ABBFA45CC5096A1562A375F0599D9698B18012A84A0628601C731CE1CE6824907F1B16878A75418C2FB0751202FCC988779BE2326E2E5228C9493A0E628441B13D58B3C79DF34B7B53C7BE816CC7368F2F31C380296250B33269158C4F9706D75B3B5536ADFE5B0BCF514899287B4B637BB4249DB25A0413533D628597DDD745A7F5270D136763E48A517CA62E116913350E7361580CF77BCDB5B607B38D49E1581654A61AD9602F4415F484BCCBD833255A29D2E76262B401F7FA5A1E68BB136771C41B29333B653602B79A2ABA21004E8A257DF7362163B6512EDA4E1376ABA1FACF04D1AA56C814000D718B5B504F1B9D2E627B8A678D0294C5E3B186A67C082B90ABB1C839232912C39C3E02717A65E24A185A5D96E99851EB538A4AB872148C2D7BC52EC4270F708690D0678D43C783CA194B4AAEB6F2156297355D7823E0F80890608768C65073E04E7E5B45ACBB1CB6446483E7C315A0A0C2066F080A53818A4EC0E4973F630F6822A437F6684FC9431F20A306A055F9906435172699B3CD0D46457BE26560F692864A97F80B493093270B5225980287F1F5711B355F9CCC018D670ED8BA64F10BA98B0068E7714074E14736087819EC2CBC960FE6939A4E9A4DE2045B53E81FBB845B0E546DE6B34EE9E91ECF0C9F74C569DEC949D3EA11785639126BBD45137021E9670735488E46A325342A2B4A959297816D1AC731CB501D628BC09083AB5C4DAFC09A36C7C70F2885A6622BB7162AA2C999927A1FB749BAE280237DB21418E2CEC419990288B813E80765B47E4C314171B849E570C7533CC5BB77CB9F10272926C382FC0796F39924B6971FE6B54638C4CF25318E146AA02769E64C47E4DA2D5264B282B32933D8C74242AA73C15875934E99D6C570572E03C54E47726E3B0416D3737A29624169778970E99DE64BC2B16039AE97C7472A41C9A6C6FD45BD7738CB662505BB26A307A2CFB9680F5CAC086F9BBF7799263C0B5367032196F1BD842534601094668A33BD339DB59746D63BA6007887AB750F5887453E02B22C3148BF6C48C806A94CB7BF23568789A1260C87AF0548C71881401C565268317756A211B6955ED03C49E0BEB46C4EA9FF7BE444932E61D464966BFFC96BEC0647AB34F2 +sk = 953B6E6F452FFAB6B9E27B707F600992E228F5FAC92680AAF31300154B218AE51A012A4CF53840CFD714CB63CB4C7AA0E8EA6E50803CA370BB38C7205D9365448B38308868C83348ACC365BE62B4FA763ECC5112A48558E57230D92B5869D77D99A5C0BEF49819500B333300910117E05B082D15368AE529923C6BC9D3594AB33C91B81549829A2EE55AD152493E80AA80399F770899EC05417A698E6493AA647691FEDC92854C23702CAAFC8AB3A3194CE8437B8E2A7F69454ADF3170C282972ABB93CF152DD85587F6272B0B71590C81B3A9F680D19445FFF0C395310A17F55272CC3E1364A9AEA7A67AF4561CF10043B7B7EB4AB0791A8D62814F4B6536CFA69CA0493FEC1A53D58709FBAB9C87578D83C9441D62C267E7AA4EF0AFC7106C9F834A5A13206C4B58D7378AF90B85F7E05237559D6D7819F455AA01D68BC297A8DD760A0DF971542919979218B4861A49E45AAB12BE67080D197C25CA53483D781BA27893D23BAECD393DD1643DC2A53275C84A19900B364CCC94A8BA3B5768F8DBBE08A7B08FD2746BEC62C98C5E5198695B12048BA5C98753AABA88BFBBC6C8DE490AFAA8343D334AAEB72532C63D60667079B41B6A287B04C797458ACD9104C94E96BF18137B0868737DC00A8E2164E0980B9B2135DC7C0E80E1B930C22874FC2CDBE0B5542732E8FA80E407A1A6E5AF0AA3168A963587379AA3E6A2B082A8A35604BAD827BD6AA1FEA76A608100DDC40B17283EDDAB2335B8796DC1BB57887787A4273C4185867368BE581F6E5767BBF0580F07B003556ECFFC3AE336260FA0A80A2C9E4C9914144551C89A9D68373ED9C7AFA83C75C6B8AFFB54187D3B46ABDC61D9E070B5584BE7564F932985EA4C739CC906732A7CF79A65F0F7B0682CAA5D2070B3E0699B1BB3AC0B38CAF22CA4DB9472D06B02954E36C0A3D8890473588C77E43990DA1C7103985761CA711109BEC0B805607D732A36BAF897E93C6D9A988B94C67A4592B7583126FD452FF0B45A033824983715C60478685B9C2D013D41B47EB342A05FB76232554DF30990D6F1B37EA9172020C66FAC8F415615EBE07833A2588EF622034074B214CCD9395648071821D1109DAA87C0E00CD9573254538EC3B8459CE56578C09CA66A508E88C4DBF6183A268B86FA4B7733A8CC89AC81619AF8F56D8ADB1F665A7AC413005BE730AA41CEF2B06A7FBA535552C8CEF73E90A8584A8B799C323F61FAAD4B8C25D06CB883493147069EB1C9C8FB262B699693D0601262E9CE5B383A0D27C1572C49547BC908C003490827343A690859A15B20119975C35AA991183052F117B53D06C5F4683D19CA5BA6F5595B8B269D96C1B3524CC8FC6EEC750CA33B5518603F59B50741D246642BB88EF61A8BD4C54F48AF3F573D4CDC5143ECBDDAB5A281400721544E16E35EA7A05F161003A6C3ADAF690189BCB074F546BC2033B1E8B00D56CF32E0733DC81D05EB358D148A91FACA963B814A9C5FDFDB4DE79B729DFC26C3D9B48A4730337B0BAC8C2A3628268159979F6B10AA9AB90ADAB98B9C0928FC4E3570AB01F02D5A64C5F605596E3498EA532472760F61CB2EB734C174E48237C656636645886B65C566BF95D927A16730C3D8A8484295A1D995716A3BF93C7270671AFB7886F397AF65F5BAC1B1A1A49084D1A672A1F98BCA762287E90410AB01098C74869B42479C2CAE5906AB354970C05CD256514F5C2E763230B6770884E7B700544977993DF1F57969E0265FAC4F474B76648B36F5711163638069820232B8A64F16BDE83557B0540405D7987CC39069923DFA984CA4045999A77483E04FE6EB0BE954A74C13CFCEA79ED0D8124B01B740A26ED961B2BC496CBDC539A10B8151E0078F66751FE78D2F3A5100761C8BEB514923A7B4F3AE208766FD852222DC31FC1A59A883C401459DC73468EB35AF61D28EC1DA147C882CC7F5AD5204BD8DA270E4C91DC37BAAE1811CFF4CBF8605BB48AC8585094327A8C17527BF5B3968AA268E152B6896A288A9722183E199F608CD7A412CA949113E87A956E4AD12737D53C3BE4752533BC755F7A1C4B07661E988210AC72131B4496941893A9C6F1180BA622436EEB02F3A3A090C00B1FFD310E811A7A8B87984D275D76B0F99ABBFA45CC5096A1562A375F0599D9698B18012A84A0628601C731CE1CE6824907F1B16878A75418C2FB0751202FCC988779BE2326E2E5228C9493A0E628441B13D58B3C79DF34B7B53C7BE816CC7368F2F31C380296250B33269158C4F9706D75B3B5536ADFE5B0BCF514899287B4B637BB4249DB25A0413533D628597DDD745A7F5270D136763E48A517CA62E116913350E7361580CF77BCDB5B607B38D49E1581654A61AD9602F4415F484BCCBD833255A29D2E76262B401F7FA5A1E68BB136771C41B29333B653602B79A2ABA21004E8A257DF7362163B6512EDA4E1376ABA1FACF04D1AA56C814000D718B5B504F1B9D2E627B8A678D0294C5E3B186A67C082B90ABB1C839232912C39C3E02717A65E24A185A5D96E99851EB538A4AB872148C2D7BC52EC4270F708690D0678D43C783CA194B4AAEB6F2156297355D7823E0F80890608768C65073E04E7E5B45ACBB1CB6446483E7C315A0A0C2066F080A53818A4EC0E4973F630F6822A437F6684FC9431F20A306A055F9906435172699B3CD0D46457BE26560F692864A97F80B493093270B5225980287F1F5711B355F9CCC018D670ED8BA64F10BA98B0068E7714074E14736087819EC2CBC960FE6939A4E9A4DE2045B53E81FBB845B0E546DE6B34EE9E91ECF0C9F74C569DEC949D3EA11785639126BBD45137021E9670735488E46A325342A2B4A959297816D1AC731CB501D628BC09083AB5C4DAFC09A36C7C70F2885A6622BB7162AA2C999927A1FB749BAE280237DB21418E2CEC419990288B813E80765B47E4C314171B849E570C7533CC5BB77CB9F10272926C382FC0796F39924B6971FE6B54638C4CF25318E146AA02769E64C47E4DA2D5264B282B32933D8C74242AA73C15875934E99D6C570572E03C54E47726E3B0416D3737A29624169778970E99DE64BC2B16039AE97C7472A41C9A6C6FD45BD7738CB662505BB26A307A2CFB9680F5CAC086F9BBF7799263C0B5367032196F1BD842534601094668A33BD339DB59746D63BA6007887AB750F5887453E02B22C3148BF6C48C806A94CB7BF23568789A1260C87AF0548C71881401C565268317756A211B6955ED03C49E0BEB46C4EA9FF7BE444932E61D464966BFFC96BEC0647AB34F2E4174B6E7542FBE80AB2BC06DFB802F691AFF147FF90332D5EA739216C18D872DF7D92DDA83E6B2EF4CCE08C9134563063068A196D7B1A1A13623E48AE12528E +ct = 7678F9F69052E083A490965D779518878DF36A286624797D9A00D562D4BC7072292A63B24C01A747DBF24822CA2EBC078EC3BAAB0DB9DEAFB0F3CBD655AFF659514016EF3D93E8B52340A850089E5FB8292F72C86A879485387B190ACC8E9277AB4A8EAFC7BE2F32138504BB7B67ACDFD9B912D66E76DFC7F66F6E46231FAA4D01FEB97E1913B602477DA05EEA0158C4D33C2E701986411F9EE8B8518B8187EB0A98484800A2FF2C483CFD811A64D3A9412EA798996C87801F1227C19CE8139A53F42DA6E5BD508B429ABE96AC93147FD660B431FD2E146017C037DFEB89F8C5419DC721018B1979044A20FCAACB9D7D2F77FA0A370D469E253B89E58A1EB7DAA6BFD983642E45D746ABB642E0736D20595E8A4E67583D9366D66CC8DAE93E0F579BCA7989C97D9EC0A175194AD55E54ADB1988803B208322041A6F3CE5DA12C0279909CDD937DA9E4CB781E98DB46FC57733F8DA3DE1F86E5DB7103AE7D385F1F0980A669360D67DFA4F91E7F415B545E46D6F0D702A838BA8F248B3A86E18366B6EC489AA8F4196BE731C8FF811A079242640A5FBBD2622253525AC11E74237727BE9F94F376C81755303629D34DDA91F4C0157FE10FC7FB7D9D3E86F6B7646A0332D09EC2A8DE94F6530D3C93A85CFEFBD7BBA955BD41B433158EA148EDFE6F9441D1969DCA81E0319FA2CFDFA528C6B0846EA08C9C36D786D164C80E6938B8CC8BACF096A4E196A601DC1DFA5F85EF588752700215E4DE5A6E7D312EC9EA6704CB5E57EF64CDEC044539D536E5CDCA0F288864EEFF859A9444A078913942EA0A909B4BC3A9F4669C45C242150711DA385AFEE36C2C9B4186D74059E54C111682FD5E75B46CE6A971E9AB0263EED4BF29522E2D60F9599D594ACE2B5F528E2EBDA0C32045F2A90361AEA23733479749F168539DE860146FB9687EF7D0F2AC8C5DF48A3C4A5D44CA2F464B92BBA5756503672184A48A6CE33D5336BE21DBBF177DAC7F70230DE92EF9AC6E510537F7966FBABEC20CFE0E3A7009C8BB54E07AD7B3B4320ACB6D9425467F83D1C9C263627835685A3B2637C1D199ECB1B4C6C2094FB338D4A9BF78F599A533F0B115A4EDB9F58D5ED0FF59B8B2FFB02D1B7F44119D7F0DF89B05BC1772E85555E8CA00D38F95F62298455B6EBBC502ED3C5EC0FC7051C58317B3ECD7C1B6F1DDF9203C98F901423F337C81FB02663D06161271247F139944D6C38C5EC86EA82A542657838EFF141A1CC0BD88511D57709F751F7B2CE7CA6CCF57C9BEE805B81E553C9322348DC35D9C09AD45F167694ED753FFC8D9D0FA4DA6EEDC97BDADC4F0360687299975F9798F70F8E47D40B94039CB416A08FBEBEA26FA87D32621CC509472C19E8A7D83A00C82F00A6A1962CCBBC6612C8CA884DD88F3B0112CEEC63EF74138E53FD14DBA053B7BB39DA8B0D43313D18F75F5E6AE20895BEEA14E7FF3E94C504D5795162CAC8B168A2DBDE89F3AA874F4F9287DBD34252BCA7B3557C00E191ACDD44AB8ADF8931FAF6E6336E4441045 +ss = 5C32A0ECC8FD7E70C1B389FE25C91899C37CE4CE672E299A41C7732F4F0D03B2 + +count = 17 +seed = 8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A +generateEntropy = b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +encapEntropyPreHash = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +pk = AD735E9E838DA63AC7A3E1CD3E574DB17C2601D3927CC2A9D228A05F5C1E51A63634383FF5E03151F43C66A07BE9E992AA65CA4CA17B1E021E06B261CCAA89B12A4916A5A4E39826A94C86BCBA9FC7D65FF04549DB70B300B1CB280B3A41E82B6C8B0A4A3C5E40EBA59FD18F004CA3E4C15BEDF22E099C99A3D114EB0C5988BA02873B9581107A23E54A8E51AE62375A887929F7333D4D763E23B20A246785E07700BB16C531692531433EB6A6594D1464BCA7348022C1D4219CD8AA6614862C42376C3A0C4674181983F2A2CE8B7F32659AE87ACCAB6023938592E188A3C1015E98720EACC9AA837A49C4617A850C89E1212478F3C6BBA51C30A64A8A1C225274C92EA953872342A96CA3235CA7A9467BE55250796126B30694F71B2F75B56D84AC89C4B635118145C7B8967DE515ECC719E35804194B7EA9304636283CBF72339474CE1DA00106110A596725574747DC07B3F0C7C527ACA703CB23BAA080BB7A4CFC1009B3E5AA89659121E365FD6CB6FD15AFED70779A978B3FF50F915B6C16A350141721EFD61085189C3265530C1A17491B317031B4E4667EB8314AD34CB7DAA50566A9812377CF24076FC3DC748FD58865B1B02DBB831B25B7B7383579376FDAA6C8A5323230025A4BC66977F6A458374FAEB14E47F70E654C42C94A5FC5E386A57ABDE3F29349623E4DE92F900527C165870FCC26A2F95FA1850F2C940FB7B87686E253DD54B6706A84A0C70E3AB04CA8446EFB77609E9815A261AF5A135836064D44A485B5E850F10153653838E5874B76568516E847A2A9B186E8A50C34C2D2B0839EE58024211018B0A13FC781623CC313B30C26A258106941A66B3CD9481ACA7C7E3CE3202F098746C42C58F4C7DBE52FB5F606FBF31B9B5022E691CBEF1464F6942AA503147EBA081817AE28581ECDD867A96195DB320BD2D91C36DB01ADE9AFFB6B00F86C13E2E252C988300B05AFCD007470CC3022E96AF0768DBEBBCF62B53345B213C1544491F1BC75BA96BD73BE57A2CD6874511B44BF2DD27F4FC87C167815FEC59F7A043F699BA4D23400886A7214160C23DC96056BBCC7007A0049435C534B66971E6E5C90EFFA6645C45031C0C905B9887700181565B53165BAB605A51BCACA0DD0C308A46432794C38F21E04172005F4348211C63A40CFFD7C32BCD57FDE852FEC793CB7013E74504721F6BFB7637F73319F75B08E3C25777C969C6EA000C9B79D6F16A00CC4B00AD7CA4F8704B2E54D9D27524F6B80A6D51F85447B22C29AF0036C6BA486862C8B4FB03F26042A0E195A3E91BC303770AC844E77805E41EC6ACA920FF3A1A3ABE81B598C193723B20C8685590131DA89C0ACE08A592489791911C92C7E6ED55F642CAF918173F190B2FB8CC0CB2139FB6CAA259B5A4634CFD0A532B719903E32831489A2D390B4C5A5066B4AB5A3316441B162407096A0BC0342599804752FD4F21C45923705A7A04012AE4A900C01D584F9F41676C36681994C2F4037BDFB84A69A81FA561E5BE05777B571922988EAC714FF249926FC9CC4E93666E198308A434DF74DFF3C5A440948437A7C500582124574AE225F52D322D0909B5E946A5E22AC8F774F69C48B7874417BB1C0B93CC0A90D2A9640377808CCC2673495C4839FDA0D1038B27BEFE3D22E2B727A +sk = 87C0B4D44CC9EB48C126C5877FF87929B08485FB81E479139C3299C70C43C3FC8C238A81D4E61E62A33DB2499C866B7107D116B7FCB1B0530A7E758A8D487D11575079265B3158302A23732BD07330071BD7CB7199476C39B583A2446109E99FD5C95BE21A292CF37490906E84A82605B8455825C82ECA4B7E218644460CE581214C78AC4473688BD6A9A826217490AD791B7835A85935782847981CA97B6DFE88B63701CFBE3929A2DBAB1628155506C353639D153656B90C5AFF36BAEDF1B87DA5BCE2A108FB6C3B29E77DAE803A0DCBA48AC6882F6C1194E88387F30A47C27D02C37D988346A2A29584A55CB5D3C44C05A18619A4FD412BABC31A046221B3994C8F22CE272C9E6E948C3D043295F413349796C38911F8DCADEAE47351C15E9A1743EB65BDC7471F37FCC93CEC867CD4808ECB281FC17EFD004DD64AB432D664864B43F8A9B1E763529AE2C413ABBCF30A4A478A30A0104D802037C4A8AF01B534DD600E31A1630FF13B2F730924CB790166AF3B7322BAF4409CBBA500C1BB32894E65445F04E4B4B4933DE51267635037FAA44E2775CAA4212F4E0600E51069ABA662C86145E2117347BB1748D63E412550C004237CF02B02AABB18D8533D19B1A879A079B31D529AACBF5258483C80738B380C83119C12B23CDCBC7D027506F3705CE1316DD24594A4BD32D10382F8AB47478F23763898398D7430264203A76B0C4455237F3E765EA5516388595CE9E2BCE2DC2258B5B96C782865FB5354427A2D7806123B0CCA782B1C329411C6C133934BA4A959DA88A072BC6E2D63A007572E36B82C5643564BEC47BC8953D4AAABD146AB5EB36E33F825FB9CA01E223253C320F76C98F810CA52A2C604622F7A60378809A59B19680AA69EED2003E272B8A1F3C8A55BCA129640C5A00D187BCAF465204C73CEE66A2FEEA414F02859C9988356D26665196674D25E64CC5689965CFDB2C0E47A531CE32B3DAA9C649954342A3F62253FDF826AAFCA7DC85A7A8E15161435212D7A4A3BD4B57A2CCCA3506999D407D9B6ABCC97209FA97454B0974DC2C7CF3C3FA40306CD6239DC450536974A8AB773374504B9889CB42BCE4EF4606BDAA559346F18D087BF8B7F0D9B21B0C9B75B5903194B0744A1C47483488EB4C1CA2C83D8198CC6A523D9329F6582863CAC2951268C01770A8081C1C26587D7610088E6068E020E10472C825C395AC6783F074EFA8597FEAC3734399BFA247E4E1531EAC70FE49355E44B3BA5439EA1E65EDA94485FB710124BB968490F1C8B68E87A4C4682156FC06A33275B6B202AA0D508B3789AACA627F0F0C19026CEC38A95F7547D936B255BE7A7525C97AB4282714C32A23C4723A82298F2CE90FCB4761B9EEE869E4D3484BA2B222DC28BC612B1F41607CF57781990009F29617549C0B2179705A34916DB154AA3747867C3EF6A0693BBA5C1D42E14B3247B41059F92607A60AFCDECC1C6F3839DB943F5EBC4D340AABE21269095B3F7D9BDE9EBC21DE788794B63E1098CC2903A83CA2027E8BCB78B855FD56FCF16B45E47994AAC71FC815C521AC1A1B697A18569AC2816F52640CF9059C4EB95E6FA1B32B77BD7CBCB6AB384DE74B6A2708400E980AD735E9E838DA63AC7A3E1CD3E574DB17C2601D3927CC2A9D228A05F5C1E51A63634383FF5E03151F43C66A07BE9E992AA65CA4CA17B1E021E06B261CCAA89B12A4916A5A4E39826A94C86BCBA9FC7D65FF04549DB70B300B1CB280B3A41E82B6C8B0A4A3C5E40EBA59FD18F004CA3E4C15BEDF22E099C99A3D114EB0C5988BA02873B9581107A23E54A8E51AE62375A887929F7333D4D763E23B20A246785E07700BB16C531692531433EB6A6594D1464BCA7348022C1D4219CD8AA6614862C42376C3A0C4674181983F2A2CE8B7F32659AE87ACCAB6023938592E188A3C1015E98720EACC9AA837A49C4617A850C89E1212478F3C6BBA51C30A64A8A1C225274C92EA953872342A96CA3235CA7A9467BE55250796126B30694F71B2F75B56D84AC89C4B635118145C7B8967DE515ECC719E35804194B7EA9304636283CBF72339474CE1DA00106110A596725574747DC07B3F0C7C527ACA703CB23BAA080BB7A4CFC1009B3E5AA89659121E365FD6CB6FD15AFED70779A978B3FF50F915B6C16A350141721EFD61085189C3265530C1A17491B317031B4E4667EB8314AD34CB7DAA50566A9812377CF24076FC3DC748FD58865B1B02DBB831B25B7B7383579376FDAA6C8A5323230025A4BC66977F6A458374FAEB14E47F70E654C42C94A5FC5E386A57ABDE3F29349623E4DE92F900527C165870FCC26A2F95FA1850F2C940FB7B87686E253DD54B6706A84A0C70E3AB04CA8446EFB77609E9815A261AF5A135836064D44A485B5E850F10153653838E5874B76568516E847A2A9B186E8A50C34C2D2B0839EE58024211018B0A13FC781623CC313B30C26A258106941A66B3CD9481ACA7C7E3CE3202F098746C42C58F4C7DBE52FB5F606FBF31B9B5022E691CBEF1464F6942AA503147EBA081817AE28581ECDD867A96195DB320BD2D91C36DB01ADE9AFFB6B00F86C13E2E252C988300B05AFCD007470CC3022E96AF0768DBEBBCF62B53345B213C1544491F1BC75BA96BD73BE57A2CD6874511B44BF2DD27F4FC87C167815FEC59F7A043F699BA4D23400886A7214160C23DC96056BBCC7007A0049435C534B66971E6E5C90EFFA6645C45031C0C905B9887700181565B53165BAB605A51BCACA0DD0C308A46432794C38F21E04172005F4348211C63A40CFFD7C32BCD57FDE852FEC793CB7013E74504721F6BFB7637F73319F75B08E3C25777C969C6EA000C9B79D6F16A00CC4B00AD7CA4F8704B2E54D9D27524F6B80A6D51F85447B22C29AF0036C6BA486862C8B4FB03F26042A0E195A3E91BC303770AC844E77805E41EC6ACA920FF3A1A3ABE81B598C193723B20C8685590131DA89C0ACE08A592489791911C92C7E6ED55F642CAF918173F190B2FB8CC0CB2139FB6CAA259B5A4634CFD0A532B719903E32831489A2D390B4C5A5066B4AB5A3316441B162407096A0BC0342599804752FD4F21C45923705A7A04012AE4A900C01D584F9F41676C36681994C2F4037BDFB84A69A81FA561E5BE05777B571922988EAC714FF249926FC9CC4E93666E198308A434DF74DFF3C5A440948437A7C500582124574AE225F52D322D0909B5E946A5E22AC8F774F69C48B7874417BB1C0B93CC0A90D2A9640377808CCC2673495C4839FDA0D1038B27BEFE3D22E2B727A2006A70FA33FF4A65B00553734C5BD8CCA0A65EB3A115D96B8AA90F8FDC5F8F40F6AA3E88F7FA8A96067F8CDAECEEAC90C2D0B5E277E56E9C405EC9420C30252 +ct = 8B6066F2A728AE7D0BC110336DCCC3FE0F6357DCE815FF647B494FE508C69A7ED6E55C11453DB91AEE3BA1C211216EDC8DB6A45EE71552A75B6B168FEB3FB85EC871C7DB796DE7BAAF09511EBDB584EA318A07A7121B1F2DE7A99A08A0F9CFEF11900FC897DC8B315BC62DF134D054E053777E39436DFFCFCCC673DBF48440276467329301CAC24DB50EB48BDEA5085D50E40E7D2D34E0D193419D423DFA565B0B8278718EDC2839B764F97C796EE6C719285BF2CAEDA377845382E29B614CE12D31702D98B0BF73CE2B695D407BEFCC62B69634CB5BB3803251697C1660B1411C475C62AAB58F5AB9BC4C8DEC50921FC21452E08B27095A8D87FCD581CC81C223A5AA2DD679CD19F87127065C1368C8B29454A9351A0B17A85873BABA9132D4F905DB6A15BE3EA0E61DD4BDB7C506E7014137EEB3943794F5AC765103C9F2C596401CF443D0979557D15F930580D34DB141403E278E2B79E4E2BEE3CB69F1187326D55A584DA85C98A300931E0DEBED6CB3C200ADD1CE524CC7230AF50A93EDAD2707E452DCACF7F81CFBCFD47CD9457A6A713E1FD9B8F8DAAB5440A7BF30E10A244238D02EBCED353667C1F5EDED23E1816DFC8999E46C7E1CFB910BDC06388D12B9C7F32D3611A7F7E38AF8EDB14E2E80EA10E9DDD676FE4D921B4E24DD175CA69D82EA6896820F5311447AD8A37774AD535781AF80F98B89F982C3600EF2101C8527F0B1DC2EB39F47D21DC7112D9F6E96D6D74FFDDA89F3E1B0CC0CD09C2D1061D0E2725A30F88EC62D95633F40303811458954A0178BFA7F7F9D44FAD3607D96475B0BE47E3182216E561C2CA147298D1EE0F23884E658AE146DAE13AE35B8C4BCB6006279955088AA34E0E31284A39AFC316E5F83B05D2271FC3AA5172DC29B751AEB2E854691E5942012B87C2A5C7A0D97551D77927610C01D60CEDE43C4489650A3C4BF1817B12C61DB829386EC110431DD09CC9127EABAF96673B8795C8AE2BD97DAFBEDC4E4D726E90207D43402A761D754DC0C0FEF6403C23F0F8249E8AB153C768B1A42EA982433C45141853A4755D93B62A9DE2C29D83FE8262B1D8D0D6E7E918FF2C8E88CF20705701C8A86A9986E4BAE2C697F45D4DBCFAAC1F11F11A2A1A728F44D70D31F85CE8BBA588C095ED854DBCE17C6751BFB2EE1A86713A796D968BB0271293C9210B420CE454D329EEEA558DD60052466B051477D25152F6BEA1E04C521FAB8D00BE3B0C5CC166FEA82BA49773BBDAA958C5C7E8F50BFB5E345C29801024C39E597F66AC08FA1510FCED31E21F599097F5FCB604B88E3FF893FFFFF9F81AF2D5E1CE0FD4BDAB7A541FF7DC9B55D0EB4D54EADDE6C5A9D688A3C2851976FF51FA915DB037155BBE715F0998C17CB2539AB0300CDA62A0F84817259B2D64DF12AE065CBEF43648F5181ACDCE5B434877F4F90E95E19D5ABC106F568F1B4C48305EAD8A35EDDBD35404E2D46C8ADDD2CC4DA632F2BACF96A0529BB37EE7530739154E01F50116476333D4D0EF1CBA1A85E4338896B +ss = 4FC71B4D0A7CD5D80824E137B93F8356AEDA6A13A55C0515AA74EEF21447CACA + +count = 18 +seed = D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856 +generateEntropy = 9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +encapEntropyPreHash = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +pk = E0B9190B548BC164BB826874C1800980DAB529866B951C01C20CB4AD363C681336B13105FC338B1788AFBFF321BD981974C33D98A35666EAABE3612E61839D6AD65490D71AE992111719AACF12A060648667E34D09343D93DB88ABC69E0E098A63749BDAD39F8C6B93D75990B0731621CC04E6E2061E93CC4B51209EC92ABB303BC638C52AB2AE40D746CFCC43B7576A240540BF410C14744F80A442D0555D474192BCD9B187A56691B63965973C7793668682852F91CFBCE70D6D4832A1855CC4B83A847734C24019C508B2D29539FD1A114F787285E197B51BC092F80B559446F1076F02E984A1B27CAE7AA1D0B50967939AAC74CF2335AD421021E3225D94FA3B09148E60C20E8454C68A8022043206B7BB1E799C9B69286509A188DB29A9EBB078420A0844C858CF4B11F9B4959934002BE0229E714350451B9C2775A5CC8C45B07E121290EEE32A73D46F8D7C55311A8C29027356139F153CB405FA14064C5C31060D7A964B33D76BCD4809D21B34A2F7806486BD2835B7F871164AE496D4264F89FB4EB15B7E5A7232B6C68B11351A41B09BB0C92C8437534D2B4C0CA2538023B29DF93D93C98136780FF6F82846CC2868664322AB28DCD7279F68994BA5A5ED406D4D717D16C14DFDDA58DB1524F7C53F3CB170D45A411B07CD64F001DAA0AD1BF63A11550C0C154D20F5096DB44D1AB0A1C9D66581891A9314C18F778330A0936E7A2F3E19C18F7BC87CF078627770DFC5A2FE71B27EB8276863C3295C11E08703EF4A4FF6B3A1871C7B42C43A6EEB6BD1526AA95B7DCD6B38EDC207C630BED1768CE9505544E9053E5C8CBF6A181A1A0F48C8A98B59C3ADEBCC3A5C99E61588834024CFC71C9DFAB1DF558711B311404A739F79B45B1A8A7633081A27A08C3C16478C9D24C1229723ADDCEA225D39BDE7851345B18B1B08254181B01623347A9A57F5D902290B10476083949556663309059815626C3CCB5302B978B2CE82AF231934FFC7732352B990B21B69210F2ACC048387B95C346974C2181148078154416E08564D664DB3045DBA82C9A7934DE51AB5C1D7346A391BACA48209C8C7235309943C1CB9CAB4771C7EAF59321B510D430C88473AB16F54AE461A5DC613C6FEC61A5E899552E835EFF57FC34B7992755D178A0365C52B3F020AB40020CE21B45717654634606DFB2917FCC266193E2E5B2C4559CC5652AAD1121CCA0711E26C23EB33C1F7D389F2D742F384725D3268F8159F8C463585998289E58369FBB883CAAE21B87139E52D7EBB92B011CBE6426390458247C45F06F2519AB35B35675BF93325351617AD3AC470F73D3D3985E10277A647C96A6C56CC2346563CC496DB232FD742AEA3ADCFBC506CA8CBADA7B040A04F6E329FCEA77BEC0683E1A87C396113639159D9CA52A5A5484D2839869A2E80557A6BF7CE2EE295A464AAF835C542457D021C65C2B2A457C771FCC47F8B1056C8B7AA61D1843A40C4C9B083269B2E89FA3BA5959F89972805FA4B46E35ABEF0C57D875C54804DE77071F1219195BC8B4F7C18A19A7953573E7F4157CA03BE2852461A784E736110157BA3F83A6947AAA09E9BCAE730B9B212BB837627293A485ED6B42CA1CF26792676C1F4BEF1609E71524B877F53FD3133BF71AB13912BF37C2CD7A359EAB035CD +sk = 4DBA785B32456E16A8E9A20FA7536F1B4555A9B403A09738657A148361788D3C358A7BABA8B4C58AC979C4F786E588AE245CB0C12C284F848B89585F76892FD65CB906D39B385A04D2F5B2154ABD1E77AD9501ABAC73237780B33C601FAC50BA3FC07E8525819593B7D7E69FDEA46F14F1128A475E4784AF38985501DCA6D20BC8DC1C5C7740B33804358F71B6E97B2A0E7350F7608321736083DC54E0253C6E5C5665D0B7E68355D4E98DAA753C1ABC1429B397DA773B043459E5AABD093A5B0210502BC2CAB250041997861286924AA0A190307431719588CC2E6FB68711C964FC20393C73B7C967C603120A3CC11B2EFCA3DD6616D0E2C835FA92946A40C4CC2F4655301ECB09424286B3C7A07AD3C6EA37BF6132AAE2D9A335E34B6C816D93CC7EDE020AB723B272B70F494834CCD93BD7800BC39919DEA4BE4C585F827A4351E233026760DC83377329CCBFF180A562AC50833C0F861E795C00EE74B584F693222B28EEFCB445F19B06154ABD0110C6A017ED525B5FA30C64E60663573B8691BA68E2BC580157F1C66EBE388AA2747C50919AF644ACD903A801A5C04A6A2EAC686C89835CF59A791AD5642274A0F78244491670C66C9BCE24BA5CF6B86967AEFE6728DCE8973FD29045DB844DC80022297CF530C8ECA4808F603A90A840AD70A803E6A0BFB44B38616816073C5D7BA26A64048F81A3BAD3A0C9CB0672C7466E38824529298A7C0D82940540C312F429411B403F64E419CF720E1F73026184CEE538B27CFB91F16186DCD3904BA6A34254155B3CB3157937D5618568F46F283C7C0E88696324A4FD77C3E6FA5B5DC0A13116274E5792FED69EABA973730A79878103BF63934D179143DC23ED39585D40C06A99AEE0F4462F123B8A6B539DEA9E05117B08338DD6754398E7496F612B4D892CA54A13EC9B2DC7022CF779668809AD6DB97A6E8B15FF0A862E664D292C4AF549195A23C19E2B9FCDB9B4A5B9AE517873CCC644993196DE5C2716D58D50E7CF11558F44A16580C980654C8CA581671121CB2F8CC6F90529C9754CF0700B30943EEA1A7B05F0BC8FDC1CF776B0CF2C2EAB927DC83197A4071DABFC07F983BF4D2C613E087976ECCAAC031B88420CECEB6DF0350F04BA61AB39CAD4C6B2B32503D773A34514B7D5BBB9D5E7BB6DD9AB5BDB8F34A9880C49AB5C40970C435508E26CBA50705C6538686249D344BDB7C820A5C8869B371B8FE13922A5AF390BBB7B809C392266541671C75CC2B7A7248D0234FCA16DA64265E5C70257D770D2E9982D5A1C6D19BF0BA48B53AB900FC8280C754C14774939B83C63592A12F35D198194679942EC227B46CC8F353A0547E929175C3585107239AAAFCA151DF3C835E770921E5C9B134CA7E27A18C7656BFD6A4FD2431CE1743576E575DBBA8905F4CC38108E3CDCBF0155B5300A100958AA99940BCB473EF64B05BAF55E91952C46851D313B0990EBCF2148CF28130CF49C8D080841FB81384E73367C792A11099F5B898416946826714E252457B23A3A1E33A36EE2612372CB2C04030840A87F96A31913A428CCCDD2817B38372DA4637F46044F2218C28D525A57D9C0CD2864FD43AA5C9A003A09A35BA786A7520CE0B9190B548BC164BB826874C1800980DAB529866B951C01C20CB4AD363C681336B13105FC338B1788AFBFF321BD981974C33D98A35666EAABE3612E61839D6AD65490D71AE992111719AACF12A060648667E34D09343D93DB88ABC69E0E098A63749BDAD39F8C6B93D75990B0731621CC04E6E2061E93CC4B51209EC92ABB303BC638C52AB2AE40D746CFCC43B7576A240540BF410C14744F80A442D0555D474192BCD9B187A56691B63965973C7793668682852F91CFBCE70D6D4832A1855CC4B83A847734C24019C508B2D29539FD1A114F787285E197B51BC092F80B559446F1076F02E984A1B27CAE7AA1D0B50967939AAC74CF2335AD421021E3225D94FA3B09148E60C20E8454C68A8022043206B7BB1E799C9B69286509A188DB29A9EBB078420A0844C858CF4B11F9B4959934002BE0229E714350451B9C2775A5CC8C45B07E121290EEE32A73D46F8D7C55311A8C29027356139F153CB405FA14064C5C31060D7A964B33D76BCD4809D21B34A2F7806486BD2835B7F871164AE496D4264F89FB4EB15B7E5A7232B6C68B11351A41B09BB0C92C8437534D2B4C0CA2538023B29DF93D93C98136780FF6F82846CC2868664322AB28DCD7279F68994BA5A5ED406D4D717D16C14DFDDA58DB1524F7C53F3CB170D45A411B07CD64F001DAA0AD1BF63A11550C0C154D20F5096DB44D1AB0A1C9D66581891A9314C18F778330A0936E7A2F3E19C18F7BC87CF078627770DFC5A2FE71B27EB8276863C3295C11E08703EF4A4FF6B3A1871C7B42C43A6EEB6BD1526AA95B7DCD6B38EDC207C630BED1768CE9505544E9053E5C8CBF6A181A1A0F48C8A98B59C3ADEBCC3A5C99E61588834024CFC71C9DFAB1DF558711B311404A739F79B45B1A8A7633081A27A08C3C16478C9D24C1229723ADDCEA225D39BDE7851345B18B1B08254181B01623347A9A57F5D902290B10476083949556663309059815626C3CCB5302B978B2CE82AF231934FFC7732352B990B21B69210F2ACC048387B95C346974C2181148078154416E08564D664DB3045DBA82C9A7934DE51AB5C1D7346A391BACA48209C8C7235309943C1CB9CAB4771C7EAF59321B510D430C88473AB16F54AE461A5DC613C6FEC61A5E899552E835EFF57FC34B7992755D178A0365C52B3F020AB40020CE21B45717654634606DFB2917FCC266193E2E5B2C4559CC5652AAD1121CCA0711E26C23EB33C1F7D389F2D742F384725D3268F8159F8C463585998289E58369FBB883CAAE21B87139E52D7EBB92B011CBE6426390458247C45F06F2519AB35B35675BF93325351617AD3AC470F73D3D3985E10277A647C96A6C56CC2346563CC496DB232FD742AEA3ADCFBC506CA8CBADA7B040A04F6E329FCEA77BEC0683E1A87C396113639159D9CA52A5A5484D2839869A2E80557A6BF7CE2EE295A464AAF835C542457D021C65C2B2A457C771FCC47F8B1056C8B7AA61D1843A40C4C9B083269B2E89FA3BA5959F89972805FA4B46E35ABEF0C57D875C54804DE77071F1219195BC8B4F7C18A19A7953573E7F4157CA03BE2852461A784E736110157BA3F83A6947AAA09E9BCAE730B9B212BB837627293A485ED6B42CA1CF26792676C1F4BEF1609E71524B877F53FD3133BF71AB13912BF37C2CD7A359EAB035CD631E1DE2556AE65D57E600C21E8E355A4ED586D667177CA0B7545CB5A23D669F4F3029E1BE4E1C0258C3A22FF5B50B2674CC094BA7018DA2A61569845C17D26F +ct = 35B5A9E583FD8BAA2044FC15E93BE2D0D1B199196F10BDD90D274C4C56C3DAF791A9CBAE48772EF76AF0C325C7DD84029B2D44B4676558A5A409F6E64D3538E9C7F6C39A19CD737916A1C4DB7DF79AE1850A0F3EA6DF53A956C93BBB5AB3D5384AAC5030AAA99111B17AD156A9307004AB9C3B1C7ADDB735A16699C0A7FD69CE08C244B6258CE70285F56875AC2343A18868A93061DDA2CFE9E6AA2C0CAF7FD0EFC593D9D06A4F6861E0643ABBC0A91E71CF244384F45E7D3DD88A27887AE4695572E98506DA6E32DAA744AD32F0A44A7679F3F0DC7C868207AED7BCD90F62F36CD695B6B4786C5290D74CAC91A28A0D3EC3D6CA53A7DCDD4353476E54FCDAD93E21C4F9CA58B069BF5BBD9BA268B058875FEA449E68B3F93839C1B6FFC1B095BD0AA6BCF24BC5AB14FB4C8B975E701CA0190F9381FC6D47207A53F3C281CCCC0145748222390F364F6F5444614325AB382B3F7EB659EB61CF2360270269B93EBE68825EEE071273BC880751548C281AE9D94EAA1764CE70FE1857E4315C610D776BE9DDC12E6848E09192E5A7AABE46BF12A268614D138557630737ABE83ABCFBBA6F886F5DBA7D1090854432BAFCFB1A61054A1F7DED94A9B1E6C1DA0E6ED87DA24ABFD24A61339F8241C87C7AA8927744137EAC239190267B338FEA6F3F564B0E30F0C08AC24D8D17C6A7C748695957680E775F494CA2472614E5F6B6B6C703673DD9C93FAE721292981A45C714E9E50FC0FCB173D5A92D52167695E4F659A5BBD6920F61F5FFC6B63E0608689D85A919E1544EFAEE4E2525B4A20B1B89FB4D5A20F2B2FA389196EADA7F12EC01901828EA8D726EAFC62420BBD9074E753559361A9CFB371D459AFCAA3F11D893B5907688A12A99FCCBD8F390EA00E4ACAFC5BA86BA6D735045CCE689CEB35B3DA81D6F21CD8E6BFBE2ECB870DF4B3AEA67948FE7426471D3325A39BB041A0974C8768D832398B0EE9273F1F488A0D8829454E17AEBDCA048B7B3014C5C3E93E5BC15317DEFDAA4DE18094523B0491A3537896689027F57436557F65D70A5440AC28681FA0224DE0958B60DED0A4A6846316B8DC836BFE99855AFAAFF6A4EFC9A5149610D0E1C3D8FD8AE4E7B489734444258A30F14681D5DD3179F530E9C0A5FF42100AA851707E3216FDF5B5DC42C0DE6EC2031E9DF703A6BBE7385396C711218B445CCC15B83C1FC1E19AACD8507A60034BE48C59C23C71EF836A7F4F05A07DD953B6DEFD09A7ADD8697097123A4DF8EF6ABDCFB74F9711E8F2719033585D63386F32CA50F72F833FED12EB70F2C1C34DC7F26205149D68652468B7D156C3B957F64BE1272766FD82725BD00BEEFC5AB6F52E0740F7E37FCFBF0D0988EE07435B41BB58DCDEC0D8B0C90C43DB5130A153DB8994A1E54EA218668CDB2C42380FE4AD204A910F0AD61777CA661B8A68F43808235C01187E6101131A32DFACF091021F9107B4964A55A3F19CD55218611AA5C479107A4EF33D76B68B9809D4CA773C4CE0347C64D13100B44A837AC87CFDA +ss = 5A864018C4C8C17C01C5EF38D7154668D9099994D92ED2EF55F02CF6B3623FD1 + +count = 19 +seed = 822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827 +generateEntropy = 851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +encapEntropyPreHash = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +pk = F1390E49F3B488AC39D0E43292B70042C52355EB48B841887EA256055A688FCAC5A71C896414CE75F57BBA12967215C50D4B5BE692B6DCD1AD2190A3D785C19E283F87F784A03C8F52A23E150734FDD7BEA2AB6D122C928606BFB60570BD696D9676397AC3AA1D062EE1AB3922A2C9B5B02D14557164149C62E8029B139E6950B3F8ACC9E8C30274B69926C1658F7836F479C8CC70138B829848C7698B179643B7550E9193D6FA87350503C2B69136B08CC298B5C335B1AB95054D13C9260625E34C6C2FB8186E1916C137AD9907C8B2AC9D88FAAAA0375236751A47918F96477B7EC01819F8AE1D72951E21608C87532A9428BDF4CB5658440CB025CE3B271652961BD935624B9EB70047E63184B9503ADCD057B6744FE42908CFA325E401B9D0DB5ADA201F5D64350D392C4FB842823895E15720DD7785C7F5986F15CC2565A71F6CA11B854A293C9CE6C9A1F4AA3917130308F2A2ACA964790BAF960AA12DE3334D146E64DB81EF09563C9667381424C809441EE989EEC93597E7C5B558A89DFAA976F6934CD18B8EACB6F2F54E8F748E4BDB69B0764FD59352575066DC242DC0F1356FAB4467C8064FD23F8823148B77A4ACC642EB2C181FD5CA251B323561191CB15F2FF0784900A15F67014B518453C4C3663528FFB53271E195C27533FEC8C3B159AC1BF39C6FDC69DD5A5FE5872FFB6B2271A09966A5C738C48E63E141D65315051610F0F5588AC97F14100027B144AA23774F199D0D9A122953ACA8782A4136820FFBCC1F2692BB919B674AA1F4D679E8418E8597C74D60C5C287CDE6D44492411222636B03CB661AD66FB442193690A5F1D6B80A947442A46BDD239FE3989E6DA86949474E395056A5E6CB42B25343A7C73B650D843527444243852518A9034B9EFA7A6BB8505BF605EC238FFBC08CBEE35A94845D7319144B381819D0928C27023B727656EA843140649C03098FE74C717AABE91948EA7698DB0A86D34296B5E50DC0A9949C8BA07F64CE60DA2B6E62458DA229D52C08B9B696A124A8CBB791C0D255D3E4A69ED2C242000DC6476B4555552DEAB63EC19FE8783151DAAF78E561E1844886D4418E7510BD025299B1C83C7BA22F63335B9823043336DA897A44FC6A28B44C68A49B436B0DFA406BE642A5BD303BB0D633685364D80440CD7189B6B34F6535101979BA9D251474FC91BF2497670BAD0DA78AB3C13EEAAC864572A2F919546A57C719BCABC9DC8215B492D53118C2D379E879234A700638370A530577700982C4334673AA5D71DB98627384E8CA876E24B5A31575EA3C334D3C7D3ABB6D8891B4904B8F5DB93D0531CAFF25BE53E28C45C94758E309B83ABC2BA66D98D3BDBC53B7D06592F2712663C777DB60AFF496A217E82D8272C3A218AD8C8B04AE7C66BE35C08E3A955FBC18EDD07E8E68A806FC3FE218B87F87BC332B86C2625D8FF01C9FF6214B75A20CC465F847511030B47EA664A75B3D4ED9038A9C747C6872DE0A57F3B76C60585ADE64570A21CF8548A5BE4996BC22B3D16A7BBBD20149034764B820892B9394581697E39F9B35077EAAADB06702968A5E5418983110A97D4749D3160DDB2B9C587767FB56B9ED9BB3D91CBEAE141769C2128E0ACADBAFD72FCA96AED457CAAFAF51DC8C30CEAC70CB4621CD4D7B4C +sk = ED55584416844E1CB3C75ACFB3771013D1AAF1FB3CA8A5B718A8CE02A15AE26BACC7534F8B084A665B0608780E532A161686B07FAA83884C6A0EFB490A8A3FCABB50ADD21F58AC43EF4355246B1A661C5937562FA6067E7AA66978E4B36EA1431ED41E4E4282D4003D5BBC06CDF7AF225B6560C44F43A278677ABBA8C6B79741B3CE7C0D0769AB407C9B39C032F0E42D1866ADDF2115E2F3336384C61CE9319CC92AC1350B264CBC4059B94372631C8241CA376AA6F76111537018C01D1346019D628F1F00CDF828B48C47CBF958989B846ED893BB0B6444BC2A35C6443F77D757A0CC957716373460A7A94151CC548F0C78AA5A323581C192D00B4D96219806A04B1A0AC829002B7FCBC8CBF8A8E3ABAFD3DC2164D03A24C19D50133E967C7668AA8B81977B400067FAD2CA802A76716B95E3D28BE5603E4977C33D3BA5DF2446F6265827464641204ED972286B58567BA129BEC0CD6F1644C4032EDD6239309AAA259A3D997B1ECC535F17D773AB1C5350E3C82C600175269700A56B0D4211DD02C13D4BC7C54238F40163441702613A1DE34BA9B0B42EF0A29300098667E8003588577E64B031139DD2180DB113623FC4B74E946EEF86A1A6BB52764C6C12911765E37A685400888AA9140A3ADFC48712688435258D56337FB8D8A9E1F34BD2E818AE3B7480F500FB6BB03BD50019C33BD37B060BC2C45E8A2267D18927C0AF66076619889FF6B1769FE59E5F131F5FE40DB2815BB6886B7BCA9DA659935DB493DED9A808157E4151B04C153E673333424B7AA939559E4CA973F7644A813B8D9C1DB8C87CAC6365C0E008E329403C69490976CD3F006F3138114A6B3E6B3C4F054451E5BBCB7D232F285A2EF5202B81740053512F8E4B33FDA87EA61042D1F9736ED58E9047C8744735A728B636DBA7ABC33B2DE0B1572A28B23C25A8668CEF9291990A499BC8935F955E1CF0301A65BE870B7F01F06099192431F3436AA5AA6564C4689C1D2E11540355138C91BA6E0182B6DABA0E7A177FF320C6B04977D47DA0D51672EB96CA054AD2D4A0F72930061775592AA40E9C9418CA611893044460495D8A46B242201886CB52E38D91D25D7FA8262290628D91323DD2A51F8C7A33487232F4934133117699028381751D8594FD94910EE4115389C57262BA579220567A7B5B42441A641FD6630D7BC06802878C76BB9EA576965EE45ACB90BA549A01B6E873A1D8C741662067A116E64C8897E83204170C9BF2676EF60C20F3450804C7A1B80725DA17F9DB18F715B7894CCBB53321CF01755D168D19A96356EC07EFC62D9A8C3A8FFB15500433F915137AC42A474B8E43F283BDB2B46CD62D509A5AEE8CBE23B74CD48079D82293BFC9CD931289A0AA27D8A930BEB2000ACC2019E3CCE107A18E9C4408C516FBE19E45459ED77231851B88B6B73156EC820A4C097072C2FD61C83D23413AD510662894DAEB238992138F98185042B53A637AEFA83378B026FA7BC314516B25D343F0E0AA7772CD2DA27F8B39A8BECB44923792A7D586631B2AB963AE537768E45961F5F96CB42320E75738A964168B9403D5B3591AC5679A61857C818B2A486BB299019C7B03BEB50D2D40A17E84712AAC01F1390E49F3B488AC39D0E43292B70042C52355EB48B841887EA256055A688FCAC5A71C896414CE75F57BBA12967215C50D4B5BE692B6DCD1AD2190A3D785C19E283F87F784A03C8F52A23E150734FDD7BEA2AB6D122C928606BFB60570BD696D9676397AC3AA1D062EE1AB3922A2C9B5B02D14557164149C62E8029B139E6950B3F8ACC9E8C30274B69926C1658F7836F479C8CC70138B829848C7698B179643B7550E9193D6FA87350503C2B69136B08CC298B5C335B1AB95054D13C9260625E34C6C2FB8186E1916C137AD9907C8B2AC9D88FAAAA0375236751A47918F96477B7EC01819F8AE1D72951E21608C87532A9428BDF4CB5658440CB025CE3B271652961BD935624B9EB70047E63184B9503ADCD057B6744FE42908CFA325E401B9D0DB5ADA201F5D64350D392C4FB842823895E15720DD7785C7F5986F15CC2565A71F6CA11B854A293C9CE6C9A1F4AA3917130308F2A2ACA964790BAF960AA12DE3334D146E64DB81EF09563C9667381424C809441EE989EEC93597E7C5B558A89DFAA976F6934CD18B8EACB6F2F54E8F748E4BDB69B0764FD59352575066DC242DC0F1356FAB4467C8064FD23F8823148B77A4ACC642EB2C181FD5CA251B323561191CB15F2FF0784900A15F67014B518453C4C3663528FFB53271E195C27533FEC8C3B159AC1BF39C6FDC69DD5A5FE5872FFB6B2271A09966A5C738C48E63E141D65315051610F0F5588AC97F14100027B144AA23774F199D0D9A122953ACA8782A4136820FFBCC1F2692BB919B674AA1F4D679E8418E8597C74D60C5C287CDE6D44492411222636B03CB661AD66FB442193690A5F1D6B80A947442A46BDD239FE3989E6DA86949474E395056A5E6CB42B25343A7C73B650D843527444243852518A9034B9EFA7A6BB8505BF605EC238FFBC08CBEE35A94845D7319144B381819D0928C27023B727656EA843140649C03098FE74C717AABE91948EA7698DB0A86D34296B5E50DC0A9949C8BA07F64CE60DA2B6E62458DA229D52C08B9B696A124A8CBB791C0D255D3E4A69ED2C242000DC6476B4555552DEAB63EC19FE8783151DAAF78E561E1844886D4418E7510BD025299B1C83C7BA22F63335B9823043336DA897A44FC6A28B44C68A49B436B0DFA406BE642A5BD303BB0D633685364D80440CD7189B6B34F6535101979BA9D251474FC91BF2497670BAD0DA78AB3C13EEAAC864572A2F919546A57C719BCABC9DC8215B492D53118C2D379E879234A700638370A530577700982C4334673AA5D71DB98627384E8CA876E24B5A31575EA3C334D3C7D3ABB6D8891B4904B8F5DB93D0531CAFF25BE53E28C45C94758E309B83ABC2BA66D98D3BDBC53B7D06592F2712663C777DB60AFF496A217E82D8272C3A218AD8C8B04AE7C66BE35C08E3A955FBC18EDD07E8E68A806FC3FE218B87F87BC332B86C2625D8FF01C9FF6214B75A20CC465F847511030B47EA664A75B3D4ED9038A9C747C6872DE0A57F3B76C60585ADE64570A21CF8548A5BE4996BC22B3D16A7BBBD20149034764B820892B9394581697E39F9B35077EAAADB06702968A5E5418983110A97D4749D3160DDB2B9C587767FB56B9ED9BB3D91CBEAE141769C2128E0ACADBAFD72FCA96AED457CAAFAF51DC8C30CEAC70CB4621CD4D7B4C87F3829EFF562789B3E19FAFEC92E4B5F95B45F3786F12D9C24915CA484A49CE1C0EC046899A777655233E4E1B5CA44E9AFBDC67964BFD5D5E3DBB45E60D03CF +ct = 8AC0D6E2C157FB04C753D97F8EA4C0415FFC46D2406D65B51E3991A286A66A87FD7E7F5DF13F446F0DEBA8D783CCD9164EEC2CF4AB002DC6DE315F3F6A3BBEF9E2A0CBC833E12F1097D11158D73C579836B41DC1C0186844E2CA224855F8A2ED24F31B92827F0A3125EAF79140612ECE54F5A9DA73BF775D8112220FEDE4B590C32B08F4A7B91B7497739C3EC80E64F2165E7F032D5A583F0AD2D7AF369F903913114A2829C8DBE77B460B06ABC23D184A7ABCF6853283828623E89286CCD3E4866C57F28146203100665792E128AD7E105DF6F283ACC30A1BAAB1E84A78E86C3B49D0950F93E1B88E655DD6B3C689988EF7E2517812006D38EE0F9FFD7969A789AE2D8ABFDE2A8F1423D628737DE52AEFF8362218317968163A5A562BE757C3E9F806AC7F8A0E5B5465841016A694861AA1DF8637A345D25EF933EEA840C5CD37E67E7489F48914A07C3D6E8118ADC55CB436E8F283ECF5CD46084B41F24430A80C6FC1099FCEB3C05CBCFFAFE17F129CCE938C0DFDDA9A440E1BA6FBA8391F84020E7BC29ECEFB06AEED4272FCFD947C689EBC9FF59848EC8D5D8F69360F74DE5CC384CC547B31249D06EC288A013BA2E07C05AC634FB3BCBC284268458D441C42545F823C546AEEA8E2DB8832D683709B06B7E6BE4D68EAF8A5EC172EC63E625576E32A5865E2F124FBF6A513FAE2AE5DEF871E89BAC25AA35D026E7121D4D2DE17DCFEF4F021AAA8AFB7B5CB9B5A424652320468E658AE8AB9141F66C35EFC4C1E46D7A8145D9CA9D57D0D5BE1723E7B13585F16919988F7F4FAEFFA4E9FBFAC36968E96B3DDA7F6F922337B15BC910C25CD3ABDDFC4938B21519D914EB51479ECC5ADFAAD5E844BDC958659F38E2A31BAE0F1894FC5A39446FAE1EEDB445CB1ECE0B0FEB796AF4124F60A318E5D52F59995478AE1CA6433A1338B132DC236366CE44D63C1930CD3BCE9EAB66A911EB0E25512631C96D7B45F53BE8C0D0E9D37987167B2FEBFEC0ACCDE2D31FF4A83150674DC11863CBAFC2BDDDF72232287A7C9D05221FBC916D6AF6A9043575BE8BC086795504DF62C50B859FE9443A08322F943EC913B2C3A3CEFF992480590BA4FBA1A956301125F7F1EE6FD5A78356554E5123C4587C4CBE4D4ACE2A00B847494CE8F88C60ABF6D4F86EA6C3FD05A01678E212734911A1F1EB0FB94FBB5F10003342E8DABD2C6FDD670652B77A8CAB31ED4E15DCA52421EA6328DFEEBB387B64BC3474A53D0CE7BAD442ACD0C6C9A615B32C1795DB075D9B25AAA48D32219FFB7BCAAF2B5B53F03CF4BAC5FDC6F0045067DD9F55D8C0B4DA63A91B8C40CE5BFF3E6E6BF71943A67FF828FB69E7C1A0EC4E10099F1EB76371DD43044F0007A22AB9F9EE22F663CCFD1E0F2E5849913C89808E7609F594E14A7135C94B4088F726A0A3BDE5CEDF9BE2F7402BE553D1A5BF8A15B90E711EB5BD84454F0219BF7DB0F9E031F93175BBDEAD918BEF03C68D279368FC8DE7818811EE6D5B09F4B773BB3100B688FDD6DE7C8A5B3218D4B53 +ss = C8B9932975C3EF329424392DA29B103F367FFF38CF402B40A0299BCD2CF10FCA + +count = 20 +seed = 81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8 +generateEntropy = d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +encapEntropyPreHash = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +pk = 2D7B0180596BE297A4631ABE0D48A046DCC99C8912B8255FC45592A2A61230652BC7C450A674CCC3ABB27395738D177E7579AFDCC30E74E7C7B5AC5DC235176343CFC4920ED8D9472E13C9B36A6D38BB44756BC31FBAB62893656DA065901303700A14B2F785D98896AE97953BA358FD53091012B97498CD7516B0E1898E2F6803C5A13D70F5BEC346917249940BA35E3EA954F6CA13C343A09CFC02D8E66852C1AE0FF8B22E7424F53B1897EA11268A6B866C09EFE8694031754ED1A2A147C0086283284133AA6C324E0B0570469F09E0901F25213FF9B113147990B54CB241268E0B6C7A3A90C638B7C483C71AC1344BD65C988736C4756E0B71111BF5B810FB3CC4187363A94EFA020DE1C3CB9A005CF472BEC5685322FAAD5BD1CB0F240458B56FCC5A6167F22577565DAC1BA9B984C33C348BABB70506B87926540547389B805BA01E4443B5D60B9A407F8B060FCD96C4B717BAAEB72400EAAA9853B962E8A0C8D966458CC4CFF31E960C447C6B205629419478360CDC945D6B9A55504D853C1E51364E7A9AAD82B64FC37A02E4139B9E6C392DC83C04005F6D1299D990A89ED68ACC31B5D1D224F2C8B3CD5280A12C6E088CC2F9D3C59AFCB9FEE458AF5135C9B4B477D878F34723E3912189D2764F9366AB8752C9248A5684296ED46F404A1739BA72D5D652C614860D41898E45B72BF66D587089FCF49E3B94CD26999D7539C32BDBAC0139B20988CC7B578ED880048885355F193DDB1690B9092AA2A86AF03A41797120BE84334EF25C2E70BFE8E0A658F03435B65787F38BC9452DDC584162955F8B8560991C407FA0C12D770E80FA4A2CF7B853708BEF2A44F959B9D05B6FAEF83F6F41A2454257B0157C55047AE7D0CC17079E118C8A4EE3358D877251970EAF86684EC70858A94BBAA4BD2FD1895C2223320CCADCE636C2156471B76C48D53E6A6C12A1317C39C48BF3A0AA0DBC8AFC034B43398B9F1C56D407A4B7C2BAC134024DF6AE9800B230E2592F529F79F0AB048867A349684B242BC4D2284A6106DBA36DE7B3A114B6353B479D014A69E33ACF5C465CED6669B22027D6657F12379ABBD248C6967834239E2D3A0211B73A77D681B61892877B7E102A53CB4602E3DC1704EC92A9E260D9817C6393062BF520F7A845FFF19123A1662FD241090AC81EE1748EEA878D53969FEA20FB95688FCB3D235910F154BD09A75556D890409CCE0A20C6CD2A59664BC4ECCA3D4725910D210DB0C848CE7242CCA945F1568561BB90D9A4C3DFBA83074A16FB3AC934C865DCEBAF6FD90D5B458C22542DED5111E77C12D8656908557649E9155A8472D5213B46F739F095B5FD4A2418074EF7DB9385F19D6630AA29B28881AA3474B7AC352C5DFBFB20FD7B8A0B87CF3933547CD498256A9E17733AD6967D7B9C7ADC64A951EC5C8ECB75B9190064F3A862D10CB5707215F456CAA10A2C240619925A140B6CBA878A0D40283EFB9E1562C227D716D2935E8D96649C06AE9465AEBF552D68DA1E7991BF987A4DFF4371049A0DC9E56F110779D562959F278B069B3C7712AF29027AAD6109BB0C3201565C0B0892A62AA74CA7BD6B48039066A95DBCA4E76A3A323612269546B18BA1BDA19C123C24504ECDF72189DFA1CD24EBF011A3BB66D35F78633E1EE7B249FF +sk = FFD8874D8B37C946409D69CB03529B7D1A43DDB24792D4773CC723643567671B8E0FC2B903D302679A530118AC453B0541A2389C46B38F317B43130972271D8146A66593B8FE659DB570C941F1ABB4F295493085A85277062C3D4DB168E466015EA506B5B8A805A435EF6812A6B68AFA9372776717C1042E24E7A10A842182E7C40C4CC547B98FE007A1D98804AC5BC3C31B6511425A558C73E5B1935C7A664EE224955B6D67CA54D47B04E1622716A27B21F12A2EB27C16D26A541CB0C1BA5A1A8629B7F2222B84CDFED9CB6F666B41C92FD0B074F42B5D2EE72E8C5443F34C5DC2920DA165558AF074E3CCAE84C1CBF1F70624E1A3A30A7DB045A2C4A79BB1A4B0F01187BBD8B29A8C60B07068A72264D9B305B5E391521BB945D53CE1D65436441932EC5867549408B47F28D3BF37D7AF0DF432CCFC3667F4ACE969542CD626637B570FD84210B3AB5456B23B8B339F4885E9A96BB17CCF1CA4A962C5667D0C3DFB356146C04BB8391197D54D0F4202F160824D900B27B36BF8ABC7876CA331C2C3A8A161D98523ADFC1EF9D538C9203A6729CFCF6089F7D72F57093EA3A34113749F23EC21C051AB2C836679B0210A549F2678C7187691DE949994A25769D4647FD992BE411E24E302C07569CF26C11F3942CA505391A794D42C77DA0A324B05908AEB9C70B88B38A95F371B1902E06D071457BBCB382AE4C36F14AB3A747A30CB7E9D35791879873A0333B3FAB967770465A056DE9C4420662C046AA8CA32093AE23ABD80406FE60BDCD1725DAAB0E50931C575A0C9137FA61442B1101B05686D398A6FDC0BBBBB25A073E99C3702B9268CA91420A1198B5C54501A03C878B6827E6D586AB42C2FA47258D1255711654968FC80E1364886F18E98FC10EB85645B399788DC225B1A233FE564604A86397A4483C102203188DF667961BAC9EF19B99432475C0A2C9978C81CF5314A2B2AB37479549B14C8D70ED8F0C6625938CA4A92BEE5A7AADB286E507EE8890772C3353E35C2DE8696041BCC8B81997F8C7800417C91C32E9B8B34B62A25E5C2AF2854CF902269C3C5B50A5209DC1C63F8835B3A73137D855C69F9335FC66EFB985933F4A66B084AA58909E658998A15AE8B087120F59A00426CF9A327DD48467F8C12CFBAACEA7BCA7407060C42950CF9543CAC1EDF9C296D978A2C36AAD92B665D6C9513B59278AC1CC781204E555E27F81E976A74D3055A48035203472960E596C7C4C2D0158A006D884F40681C6610F1124574EB9FF5323E10480D0E306F1E398AD1E6CF8057024D072DEF4719E3A6BE9AEAA07B56077BE495A635C67066A2945376C9836EBF4C413A05A9B1348C31329884BC7D820A6BAD7A63BD62518878A97FB525332433573973DF74A00EC02D50198A2B1306005335E6A51191505FB244999CC333BCFA4E7845B766B050CF66607982014D28548A4454F86A06E9321C82781478CB938C709EC5CC81EA1A9269543DC8EBC6D253BE1698990C81C587D7263E7445BAF53316C23EB8863D151A4E5659928AD704C1C7B2BD2A1987907A05CCBD2F0C78232A10653452E3DABB7598CA83D37166791EF11A2524F371180984BF72A6E2291301606B7351A284A1A62D7B0180596BE297A4631ABE0D48A046DCC99C8912B8255FC45592A2A61230652BC7C450A674CCC3ABB27395738D177E7579AFDCC30E74E7C7B5AC5DC235176343CFC4920ED8D9472E13C9B36A6D38BB44756BC31FBAB62893656DA065901303700A14B2F785D98896AE97953BA358FD53091012B97498CD7516B0E1898E2F6803C5A13D70F5BEC346917249940BA35E3EA954F6CA13C343A09CFC02D8E66852C1AE0FF8B22E7424F53B1897EA11268A6B866C09EFE8694031754ED1A2A147C0086283284133AA6C324E0B0570469F09E0901F25213FF9B113147990B54CB241268E0B6C7A3A90C638B7C483C71AC1344BD65C988736C4756E0B71111BF5B810FB3CC4187363A94EFA020DE1C3CB9A005CF472BEC5685322FAAD5BD1CB0F240458B56FCC5A6167F22577565DAC1BA9B984C33C348BABB70506B87926540547389B805BA01E4443B5D60B9A407F8B060FCD96C4B717BAAEB72400EAAA9853B962E8A0C8D966458CC4CFF31E960C447C6B205629419478360CDC945D6B9A55504D853C1E51364E7A9AAD82B64FC37A02E4139B9E6C392DC83C04005F6D1299D990A89ED68ACC31B5D1D224F2C8B3CD5280A12C6E088CC2F9D3C59AFCB9FEE458AF5135C9B4B477D878F34723E3912189D2764F9366AB8752C9248A5684296ED46F404A1739BA72D5D652C614860D41898E45B72BF66D587089FCF49E3B94CD26999D7539C32BDBAC0139B20988CC7B578ED880048885355F193DDB1690B9092AA2A86AF03A41797120BE84334EF25C2E70BFE8E0A658F03435B65787F38BC9452DDC584162955F8B8560991C407FA0C12D770E80FA4A2CF7B853708BEF2A44F959B9D05B6FAEF83F6F41A2454257B0157C55047AE7D0CC17079E118C8A4EE3358D877251970EAF86684EC70858A94BBAA4BD2FD1895C2223320CCADCE636C2156471B76C48D53E6A6C12A1317C39C48BF3A0AA0DBC8AFC034B43398B9F1C56D407A4B7C2BAC134024DF6AE9800B230E2592F529F79F0AB048867A349684B242BC4D2284A6106DBA36DE7B3A114B6353B479D014A69E33ACF5C465CED6669B22027D6657F12379ABBD248C6967834239E2D3A0211B73A77D681B61892877B7E102A53CB4602E3DC1704EC92A9E260D9817C6393062BF520F7A845FFF19123A1662FD241090AC81EE1748EEA878D53969FEA20FB95688FCB3D235910F154BD09A75556D890409CCE0A20C6CD2A59664BC4ECCA3D4725910D210DB0C848CE7242CCA945F1568561BB90D9A4C3DFBA83074A16FB3AC934C865DCEBAF6FD90D5B458C22542DED5111E77C12D8656908557649E9155A8472D5213B46F739F095B5FD4A2418074EF7DB9385F19D6630AA29B28881AA3474B7AC352C5DFBFB20FD7B8A0B87CF3933547CD498256A9E17733AD6967D7B9C7ADC64A951EC5C8ECB75B9190064F3A862D10CB5707215F456CAA10A2C240619925A140B6CBA878A0D40283EFB9E1562C227D716D2935E8D96649C06AE9465AEBF552D68DA1E7991BF987A4DFF4371049A0DC9E56F110779D562959F278B069B3C7712AF29027AAD6109BB0C3201565C0B0892A62AA74CA7BD6B48039066A95DBCA4E76A3A323612269546B18BA1BDA19C123C24504ECDF72189DFA1CD24EBF011A3BB66D35F78633E1EE7B249FF699FB2F061A75F111F4A7A60195D9045DC01716B6502CC107CBCEDF122E8F6196590A2E5C7ED86CF2C5C2A898662BC9A81418720BBB632EF9CF0B845ED052D73 +ct = 88BA446E3DACEFE9158DDF1619C9B1C6BC274B8E8F819342BDECCE593F705B29EDC21B69F1B65EC4674F71CEBE673D7FCB0CE2FF757F8EE5D5A5F8F5035A58E1D75713EDE33F0E7B98056F1EEFC0C692DEF07029C0EF3A857D6972723C7F49B79855703461A3F83857AC0F2331E7F8B3889FACDF6373F8CC49DFB5408B57DF0CB0484862970993C5DA712D87335F7F7D8C4B818E8B96FEDDDC435E131F47DEFF13919A470B25332F346A8317F0D3F8B13CD16A12C63FF17F7943275E2B4BC0B3F4AD52B67EED6A0F499DB79AEEF56964029E1FC686B78631FE0AC8162E2D3C3D36E2958DD95312FBD18ECE60716E398627437655603D1428771F24D2F39FE6D1B759A46E303BA9ACD68866F2729CA6FFCD91FFBA30D8DA6433383DC8755772C94975A6A1AB6B5A2105901363C8B94A20A48618311E4E59975C87E46AB0687D30A7BCA3E13EDCB560706405FD83184F98784EDB59535CC3CDFCDE98EE989DA0990BE3FAFF402220AC0070FB31CCF352E26727B06F253F8A5E47C10F95456705FEA41AA9A41AF7BB1A5E3DB02F9E1DFB406FD4F27FD78C25E86D9C04FA5B0C6B2D6A6D43D760F2D1D01D1AEEEA971A9BA64A95FD63C9A95B0EA5B4A83282C920E0E395110AB2DBC59C8FCE8307B6106AACB58AFB4C38A868B4D20D7772810E9DA53A5AAEFB991CFEEAE0D54A1A4934A22BE3F8F33D945F66F79AAF3B88A6D18963660D8F1E8EB23644E487E4EA68897C34628F30FF3EACDEE3353269D87B2FE2FD837FE2A6EC7B1EF99341E470AA67004DDE57EC6A2B334A2B1B90291D73D8C1BD43C38FA82E088893ED5D2149F568BA80A68E08131CEAB491A61FCAF07DBCFDE77C530C60BAFDCF55DC8BA1F9478B28D9C6A53BB9DDF4491026B754AC31214D5E774075DDED90B670181300190F9A5B3F47CB3CAA6AC0233E7AFC708DEEB1590266DD8FBA964B32880AF48EED81534B9D47F63A7195CF60EB827D2A0D94D84EEACE28C34711D116D011074B118C655380F6B2E3106ABEECECF7186B2D45A324452BFFF6EB37DD17C4CB034DE10D5F24963EA898B5F19641BF1177B64F6832331678EAF080B9A65F93636D2D4F5DCEEC96DDE5C1E8C7EB505D4638A6ACF4746AFF7EC6456E1DFD2035CA2CE87FE16EE3E69F5C06CDC5BAC084F9605AC9F07BE61787B1057C1CF5F7E3AF45064BF8920596522EC0A48E73F385EA60A256ADFAB1EED0E08104FE20AA1EEA2CC466E0B64E4F94AB0378605B7A2C38BE7FD606229C74B5D3A35B2BD5F46A3A4F180111E6F35594BA9A754C4D00E57B0C62BBC3D326DF497DEB7BD50401CE2E5AF6F75CCD6781BB944922329AB94BDA5557869E28133AE070669BD9818397C5E5A1229C145BDC17B95834BDFE9A2FC672F091C8F71735499E4A032D34906FFEF9D297AE68DA67C76770E2E9EC362B6DCF520B9338E170BCD1DC4BB9F94C564264D5B6439CC128AD54FDF6CFE5CA16AABBC65415B91485CEB77120E03B56C558D4899952F64CC140BEDDC8B3AF3BF805C12D21F6BA22C2 +ss = 578E4E308F2B426A7B1ED7D80C72396A914CE77A4A7A6D16B26E4AF3D59B491B + +count = 21 +seed = 30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994 +generateEntropy = 89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +encapEntropyPreHash = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +pk = F3576FF861541032094855B18CF574D868B0EB783CE9011F28FC14C486B122CC80093897BFC8AC1082421F99767BC42B0FF41B22DC7B50D5556041338E6C4368AB190E92608F6CC69D8B33F1AB04DE68CF96D9C5882C97CF28C30B86924AA57849954369C5427C876A9B1CA341E8522E1357E60A4450B69F150658715403D1E1C957E5A914B9A3BC4C45489053306329C7984E76F169C8639DE4080DB1671ED01A24724A101DF89E45B5B385CA2EF663586AE58D9B33ADE9738F84482E6E28909E7641AA673AD772B125161A316166E1717FDBDC8D02B2B2B6DC21805619D4FACC40E9A21BCCA9D4DA71220A4631E95B25E960192A22A39B904BBB02F1184B79A97B3CC16B5E4B5EAF278913B7A195F3107342A77A68CAC90C1B5A3CA9B354A6095C29C09C5AC2B44C6CB28A250834D5F2A307EA3434977D0087017CA2692B79008640B770B41EE2C2C77BCC2605F1857368C8E12983AFA8633C870115A3818D6BCBCEE864A8DB694F4B77BCF63A8AEC407A45716AF6358065C30B77B68C2198B2FB558F463A7477B9FA7680F1E65706A888B8740A87CC7E7949156F896C182B53E464721E46A258820201887CE9B83D43250B63E2AB29900A115084A6E66584F767853B2E684C547D97266B36B6838AABA73298DAB79C58C88F1B51113EE752736B7566EB5759CC4DBC37551135BB3C87B1A6C83AC5A38DBD78106EC0C5E9967A6D81139CD516027C25AFBB6C47E3802D56079E6265C4F21F1315A96AB994597214B814CC53E8566330CD51FB4045F605DF1C7C9C255166651DE6041B7FD85C7E376E28076AD352051C65494A1054C30930621C53EE8947DCE3C55BD686F186CD5AA21AFC17664D36A2D7F5008AE83950B93AE510847552A5C2F761207B0F478C73C4D6313C8ACC25B13EA64A72EE3334013CBC0A855B55E88EA17466534786B6176B9053CA9D0494C6B4A940B70B68F40BF570C461F11795952E69F21EC4562DEC99448263188EF44E71A1681D626CAC69C6B56AB51AE656BE1CA028672D97D044E43577F26329D50851B0F8A4A1B6C2B673AC6418CCD58005AD400C27D274DD4732E56B5D7C0B6EE731A99E15229F7295C153AA3A873C20C23A35B6137C824F6FB021A0E28F98BB3BE8DC07A5B038DC89944952913AF7A39A9B00F1A038A628686A735DBD4C45E0B8BCDC1C1A902CC4D0571CBD589F507A0C0DCB81BD39811E723358D6320A3049BCC90D776562EB34877978C9929548286A85EFB85F7C6C76FF255F13A0CF5E70304F1CC838FA398FB34E26CA662759C8F3657125DC2AACDC4615653EF074A784500EC60980BE4AAC94B0C7A9012DBE73CDBF1687A684AC63526778926654A4AE4CC779A600A836E3273ACB95A802051F18AF32683F52363572583FDFE30287B2632874CB04832F55E0944712C86D37420137C56F6251A1352AE37A0C3FDB885CB561E63A493A15BEB5E3B123ACA6B6B7294D8002E7EC758AD2C22D336AAE3C067703821842CBA2DC0B1B7A45CC0A48202A002F927122C040F84A884C1334C1E17347108B91C055D331C0B170C6F06048B40CA0BED838AD963FB8747CA714CF1D3267B701132046699798421ACC06A3BC1ADE172FC62123235C2D8DBFE40DD56CE5DE6756CC4B6AFDF64050DA2EECD9953E893C53BF7FFB +sk = D32CBC1116AC88219F9AF2C33BEB59BB94B372F97815278F0FAB2C690C94B8F209DD1575BD7C0BC7F48AA133BFA068CF1AF1612C3325B8D08963BBC66D938F46843FEE424357E535C2259ED958A75CA6203286190BE53A9B46373F8B41CB38C1CAE2BCB91898669A872F1A8D9CD21227E42ED655569202CC6B494CC6A6BDB08731CDE417F48B86554CCAF953B8FB70AEC727085510CDBAA7CD2A0BA853928886332FB1E3A419C49B34EC90FD31B716252ACCE7A79D05CC04074D69AB3CC9809102261A2191A086231DC70AA583E86912E5BEB2C1A22E841F39DB531D5C26CC333834A20480D6B1CCF19A654149045791D33B414696375DC3C7B0644626E8822C5325D52BA764F2361D853D244416CB9A5BC0540E1238CCB53438C90A196A45571F743894F060F6031FD623ABEBB4AFEA05190DD9452C981352A78E09579F05E24DB2033AACFB10D9335986E8542D9480BF5603FA932D2D0878C3753E6524A809324AD6F169D7FB6D9C0264423A632996ABF297707D8412A6B86160B69980E18ADD1C372FAA406F540C00ED0A75C3544811759C3B5026E6C19102B7160883ED002DE5807B5933934FA01559C4A790230EE93C215BD75AFF117D0F170B4FEB7AEF5B007ACA616E688161FC00CB037C8232CF2DCA569F01A2E1DC2AF7ECB6111181F2EBCB1DF27C6EA84251D8A2B6B6582EF915E2B8C7F8FB6BE8844478FC570B8054A067B34120B47FC6AC68125CCA8514DB4540B7796C9FD05523E7014DB34B8EC94D5EB66C9F5CAE2F838191D2234F43C72262A18DEBA17AB495B7F0529D89B8E1E407BD5A185EAA2444D20C6C9566526B8707B13BB0CC8D9589773DB90952A5CD78E43BDC68CFA4401D7912618F456EB4F97AC1B49AB948592976233F962B1916531FD1672BB69BE320A2985B38B80279572488C5F86BF3D55FB9FB90449B66FC874B94292000466786FB7E393765C7057051999711D234B4D277419320E0046EC0925B41D6B89C62133BD2734E296DCFE90BF6344219A6A22D2CB50C75BC02B07FD0DA11FE0A0A0B9AAD76001D5D7C8FEDE065DDE87D5D47821E756A926638395883879A91B94C6164A40895476269917CAEB12944DC956174B6CC5154944571A6F6553F604D3212728FB08AF6E8C0EA00265AC0C5464595B31A9131871D79298867AAB426D009480C0BEFC08ACE14991399079CB62DE9E6BC80C88C3339640FC667EC837B691C3DA4556A952B3E63C162EC911101C5A49B35475AE68634A7B0CEFCCFBEE608CD4C43C8EBA7A8F957DB595645C64ECF08B50C7438BFBB415C27A45AE940AD077E5A533825D998A9095A735B5D23887B0048AF49CA85F18395C7D3CD06BB687C92CDA9AC9C03A9333A866A9639803C76B5B189294A269F389ABB5010789D410B88215C554008CB10274F781ED6B0BE3903576CD16934C4B6B65296C477AA174043F06792F3944EFD0206E34042D827CAFFD2989B936B91694825C4BD8B10C0777B11971CC1EFB93EC1B3674AFB4FD07568FFE89C707B5785C140D51B433B7942D88A6EF9BC9D091472833004005AA803A050CE03B2BB551F62FB1FAC6649D3E14F0141B2EACA73B700489B73A8D840834A7802A96864610B10F3576FF861541032094855B18CF574D868B0EB783CE9011F28FC14C486B122CC80093897BFC8AC1082421F99767BC42B0FF41B22DC7B50D5556041338E6C4368AB190E92608F6CC69D8B33F1AB04DE68CF96D9C5882C97CF28C30B86924AA57849954369C5427C876A9B1CA341E8522E1357E60A4450B69F150658715403D1E1C957E5A914B9A3BC4C45489053306329C7984E76F169C8639DE4080DB1671ED01A24724A101DF89E45B5B385CA2EF663586AE58D9B33ADE9738F84482E6E28909E7641AA673AD772B125161A316166E1717FDBDC8D02B2B2B6DC21805619D4FACC40E9A21BCCA9D4DA71220A4631E95B25E960192A22A39B904BBB02F1184B79A97B3CC16B5E4B5EAF278913B7A195F3107342A77A68CAC90C1B5A3CA9B354A6095C29C09C5AC2B44C6CB28A250834D5F2A307EA3434977D0087017CA2692B79008640B770B41EE2C2C77BCC2605F1857368C8E12983AFA8633C870115A3818D6BCBCEE864A8DB694F4B77BCF63A8AEC407A45716AF6358065C30B77B68C2198B2FB558F463A7477B9FA7680F1E65706A888B8740A87CC7E7949156F896C182B53E464721E46A258820201887CE9B83D43250B63E2AB29900A115084A6E66584F767853B2E684C547D97266B36B6838AABA73298DAB79C58C88F1B51113EE752736B7566EB5759CC4DBC37551135BB3C87B1A6C83AC5A38DBD78106EC0C5E9967A6D81139CD516027C25AFBB6C47E3802D56079E6265C4F21F1315A96AB994597214B814CC53E8566330CD51FB4045F605DF1C7C9C255166651DE6041B7FD85C7E376E28076AD352051C65494A1054C30930621C53EE8947DCE3C55BD686F186CD5AA21AFC17664D36A2D7F5008AE83950B93AE510847552A5C2F761207B0F478C73C4D6313C8ACC25B13EA64A72EE3334013CBC0A855B55E88EA17466534786B6176B9053CA9D0494C6B4A940B70B68F40BF570C461F11795952E69F21EC4562DEC99448263188EF44E71A1681D626CAC69C6B56AB51AE656BE1CA028672D97D044E43577F26329D50851B0F8A4A1B6C2B673AC6418CCD58005AD400C27D274DD4732E56B5D7C0B6EE731A99E15229F7295C153AA3A873C20C23A35B6137C824F6FB021A0E28F98BB3BE8DC07A5B038DC89944952913AF7A39A9B00F1A038A628686A735DBD4C45E0B8BCDC1C1A902CC4D0571CBD589F507A0C0DCB81BD39811E723358D6320A3049BCC90D776562EB34877978C9929548286A85EFB85F7C6C76FF255F13A0CF5E70304F1CC838FA398FB34E26CA662759C8F3657125DC2AACDC4615653EF074A784500EC60980BE4AAC94B0C7A9012DBE73CDBF1687A684AC63526778926654A4AE4CC779A600A836E3273ACB95A802051F18AF32683F52363572583FDFE30287B2632874CB04832F55E0944712C86D37420137C56F6251A1352AE37A0C3FDB885CB561E63A493A15BEB5E3B123ACA6B6B7294D8002E7EC758AD2C22D336AAE3C067703821842CBA2DC0B1B7A45CC0A48202A002F927122C040F84A884C1334C1E17347108B91C055D331C0B170C6F06048B40CA0BED838AD963FB8747CA714CF1D3267B701132046699798421ACC06A3BC1ADE172FC62123235C2D8DBFE40DD56CE5DE6756CC4B6AFDF64050DA2EECD9953E893C53BF7FFBD3413880D082F26986FCF452A84A8DA934ED06198B290ADA1789E74D9081A9E7B6591121E25D64010C25A18676033E1D7278AC5F2D0B43A31F3A4156AE710465 +ct = F33AA44E8B475A3E664A1585C8A1058B26E2849754F17E4FECB0414D2EF214AE903CC1B8436B302A06BAFB52754F9908496F00B79C8EA49C3FF6B3CA9F7AB4FE2DAB7B915958CCE56FC53EA3F168E79898C06E99B2A5C7F39987D21084317FD5B99BD6B1121A1E2F719B64E54A40C1766A8A0487133272801A7D9B589119104886E2914356BC14C7B9A1DD2B424599A059AFFC963B5866A7EC744C20166B0CEB632ADB3722CF0DD49C85165B6FC05D5B20847A416482472A567A33B8653CC9E455291ABB5E65C83D051EAE887C946DF46D00CEFA7313406674FF748EB33C6351E3A18821801CF0379FC77DF7A3291515AAA7BD5538C7C5DC49EB8CB61463984A3BF34ECDEDFEB5FDDB630BFA20EB3AB4BDBAE85AC6A15162C6D27833F50D9B00DB134601B7D3B32A4D1A6220B98966E51CC1D59926DFACD2EA8EEBD5B9C1B0581F16E5E79389A7F716B0C07E353BCEF084778A9C61491456DE86AC155309583B512F719B6D2C74549009AE11583099812486239A69AFDD7571AD30C622AC4BE434F25A4D70A7EEBEDA51085A918B0E3BCD20C1E1421A527D62046AF8CDB6EAE295E10DC25C4DED82E9067CA0E1B0B289D1DD14866CE32F6D12EE0EAA215FDFBA68DF0B0C5808B76A2C24AA00AA92B08AC4C0ED48A573841D265FD079EE835925A224D2055639BD642ADFC9D5AAE4885B0F7C17163A53D0CE55246DFA31943BF03B6B1D90A7CD2AB06B099EBB67A3C28661789A9D7DAB10F29E1D4BC4D3C6102667018935BD9EAF14CC8501F9A84BFB0868B922C16417B227B2C149BD3D176C429147112AB1DA57ABBCB07D85D936E62053F4EC915792080BEB2CC142BDEC7AF12919CA448074A601BD3AA1235B499B96FC9FEB8C5B3108AF77BB1D0931F92E527ADA040A1FBEAE4A7AD92CABA96F5DE69C0FD78DB39DC2BE90F81F2BE00B4949BEE566B80B7881905B59A824506852BA8DD37E44C4A534A7A6A790D9A243439CC5A548B9B07AB0D4050676EDBC6DD4B84823E7B8DCF4EF8021D5F6FDFCC470DFC8FCB717C2FCD5CF26AA1EC03CB72FEB58A50B831C5E36B63E6A5AD7C8D57B6DF835F414D3B2D0A86ADE0F85E76E5F3B770345D3A2DF2370BF8E994E4A5116D5AA3E2C2BCEF9D1D268781453FB3D1E9BAE21595BAFAEBF72B1B4FCCD32C84897D712B720DD962C5ED46803DED0AD4FC417647DB85C22970EDED391F065143A7CB8BA660FFCA69327C2CCFDDAC83C0215818712332A79881ACA7321098AEE4F733D44F31F3A79BD78CA4B932B1EBCCFEF5C3C987FF95485F6239DFD607E3F68BF6A746F17CF0F4F438020BFDA627C5C01C65E0049914C822ED9463B6FE957847722F659621BAAF475014FCE9CF5B1A11D7392DD286CCC616EDABE08C80E56E77A41584261DC2F09D7E55A8BAE0B0D3354A1C00A6CE7D3C65BF61F3B45D81C75BBE8A0C3780CBEB6C5CCE34CCD76318017215ECED1C686224D322C3239A0E3ED6D007195207DB057125ABB40CCADE2ADA3C09ABA1F66AEFFC81F119EFA0828FA3D +ss = 70080E3BAAB3FA55E8A308E84FE9ABAE780BE8C09E211651F6EBF6053F8F264E + +count = 22 +seed = E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F +generateEntropy = d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +encapEntropyPreHash = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +pk = 4C376BA98C3A0415A3BFB0AB42D0A3D68CB171109C5F83147C33ADDA2CB07C62A9025B44523B0AE4CB8A8BEA5E550B717CA6C8271997CFD6C5ED76AA44E43DA2A02D35610787F22966298FFBB45FD78A8D36EAB454675D6951A70472CAF06640BC1B97D6760E74B41C577855BC0756ABE528EB4894E8776F1E739DA45A9F84C9BF3C72B43262525B547F75176AB2E12D8EA808D3B0355766BD69D964EB3B450A96C835D7B238220FEBD62443B03985731333C54382D20200E30E4CBB2B607AC998F20DEF865BDF47CE78AC3DBC1ABE33245D6FA7583B31B6FE7B6EDE7A8EC776B20F7BBE7E376578F0933B761BB0952161123D61282CD6C80CDC8A85F9632ABA1A8EF5925E410BB80BEABC67735D07E4ABDD587827745A3220A24A7B3902416BEFAB3073C2CB1FA76FF04315B653B3E7C18343391F92015939829DABD0289B5AABC4CB5335D963AB842865BB7C38106EB1274ECCD0140B415901279E8719C0415517B5101394F78A48F565317909371A3154D291698B0BEDE17052F30786DC2D46E71EDC438C288CBD44445F993926BFF0A8CA1A033B656C2362A659EABBCF37B2CB5916940AA9B3E850E51039C08C8588347E1099A0D8380CCC4B8CD0C87218BC24F09126A82A3D530A75500254510AC765CC1DE612A4CEB14DB78A7141109F947B4329158F87E4C8B41A92AFCCC9EB749D66A71159DB90E7A36642636AF22CC0D541CE52DB7AB44BAF30560691A637C93193A11A00EFEC075289953FDC9DF3EC3390342AEE44C08D661632FB0303681E1F89CE1300B0C1A36E63E5A45886A4C76534FA78B87A75CF96AC66205C28766BA5EEF7062363C19091C61C543D5C1B8A547372515722EE515E8EF52BF8E089D93377E2C8458E626D3391953D658CDB05C7A40077F4E19DC0B132BE719014C12B0CC242466112E94809630B63FAD12C99D271DBD38E5AFA54C894542B940415354203A0C8A785AB94200EE0CB976991C642257D9AF6998B61BA27B236FDFAB86F834FB2D47CC0904B9D6ACD2F8311F0D4B8AD81A24F712D92272587220E8023A8BC13BD17572D38851778F319607752466CB0DE7C5C12103FAE4C57D953B96BE93262BA9CB05405A5D2A9E012B21A22A2EF33A385C898C80AA9663565B63241A1B206F3379ABE8262CFA49BA05C3B43E9485E60CD38D66EAED114EF81AFD66B2594BAA361D3C3B02069B1A164BC387632E24C82A91BE2CA390EB585E900173699A8B26B8916E52BD643645D3225DF38BA50A50EA013B4B2A86EE1F76278E27F5A4142F034004B567F309C52ACCA3C7530162ED744A67481CA338861CCC3E8331E1C67886023743719493CC3CAEA51438E28AC4EA06B906789A65220E3C7407C874C6322BE1F9B627386081753AD618A8DCC013395F20F5017AE2B57BA908617490460D5A67FAE2660A56C4C4D97BABDA0BAE0F494260877F7077AF2536B2CA46E297C61DD8422BBE515519210DABC02E7047B13F16607AC15E4950574C43BF8C39A2528ADDFA2782506635E5626967A1F30C02FA3442FA93250571A8173999A88DC27B43C476468A6A4739972DC1B68493413A2743B9B563283CC886916ECA5887796A4F833AAED6639B9D531EFE5CADF9225573A23664C9CEA086428DCD19FF40A06186A41FEC0723953781475F648 +sk = 818B55FA5AC30A81891F3A3643924B2B046FEB6765A61CC81C9059D1F82F6A0067A102825C88A530D15F0DD95F0B4742D29ABE7044C62D45A05BDAC46130305E3C3417D67F60B92EDEB6B2A398119AD160EE3CB0FB52144435A5BB5412C0512DC6121BF6E72D0F87A3834AB5338196FDC950A3CB1B7354C4E50369BD4364CEE9066A221DFCD580F1B914C0C335F547748BB19264B7879F206A9C610573B8676BD0BDFD777A2A0CA5EC891A1317C5289784DE114E84C53B983778BF8933805256C9A9BD05A11AF8F5AC271AC3F1E635EB9A8263C855BB230F58EA3B7E8287D76258AA57646B97560E593944C4CB3567A2C382A795C991F69BC2DF2CBA8837C9A3B58A9DAC5E4D84B50722A144737EA38B14BE51C41CC55C53340ED158AB4A0B0F0A2612962B89CC2AA8B29198F2E04B0F0CB586F271C6414F31A71A45ECCDA8C597C38415D262571BF0A7BFA17115E0C7731C70C2D01C492C85DE16C511102C5A96973C724F3B58B504EB65F56116AA7779B76B2554736D9D6176DFC6BA007A590A311D4B86A7A6251FFFE6086AB3319DB48C4DCB91FE680F45A9480241242E4AC9861B62860837CC813FADF00751C8021F7A1C4D7A1E5F13BC3E8462F372CD7498197D172EFF98B1F8BBC37974B025295A80E3525D282FBA8467F8079D78FA6068E23BDBB3349A31506E474EA228C3927A554D7747BD3621A0343CB155BC786075C3015C3692C0FC65B194A12152A14153A03D5147B0CDB423A3B50ED6461813F9AE1FD63AB7A53031DAC2D0F87CACD1CB81461C8C08BF367C4CCAE7626343469D417ACC705546293498035195240387FB1F2E7C005DE000E530B9E21CC7DBE463E7D24ADEAC1127026843B87CF6FC1BB94674399B0636506B1ACAB72F623ADEF866F883762B5B4509CBB2BE142C5C550046E10D29FA431F9B7D977253928A8D2D4C33ADD899AD736B40CB4FC656BE02D90BF8D393D632A1AB509C432511F1CA16B01139CB0627F6503BBA75440414AF97A04BC5239567C060EF94C9BA7221D4612EAA640BDBB8B72E32A4668401AA79421BA68115261A8D94878C90A0468510B247968B7463FF49A0578044C5E9147F0739F6A17B18828BDCF56966B1CAA125CDE7BA6DCE939E56D350E896CA6219A6B8947E3909361754593FB8A85E742CACB74E1D45704FA4CFC91C142453BA5C08558DE1321AD6A6A2804769A0BF69770A1264BA5148B40A3A9BE3C513A382CFA3C244C9A138EA9CB8DA7627B350CFF87AB064A079876893D893250EF59F369C41F9EA40DAA5A5984C19CE06CF9BEC2947932133A4157BB8CC3C72A1FD25715962A9C88026C018B7202885224019466540C9EB5482A87E665157BE7722BC64133C827C20B97D9E692342F23FDB1B75AB2CCB6FA5973820B92EF1BB45C2B5ED1330C1417CCFB39FC6301B8A749D3613B3803A6ABBA20990151305CB32BA6A5B558265C2E27D8D49AEF3E91819920DB20360355919D5F641922233A1C24C0045172CB10F9564A029F07578A48A4D215248F3AC7A912EF8E56E366B03C567AB978C750D85454C68A5806AC38B7B3395F19FE78A001C5867D3E90E9B54BD63954761AB7F4A57B1FA32B65F285742C1207AA0684C376BA98C3A0415A3BFB0AB42D0A3D68CB171109C5F83147C33ADDA2CB07C62A9025B44523B0AE4CB8A8BEA5E550B717CA6C8271997CFD6C5ED76AA44E43DA2A02D35610787F22966298FFBB45FD78A8D36EAB454675D6951A70472CAF06640BC1B97D6760E74B41C577855BC0756ABE528EB4894E8776F1E739DA45A9F84C9BF3C72B43262525B547F75176AB2E12D8EA808D3B0355766BD69D964EB3B450A96C835D7B238220FEBD62443B03985731333C54382D20200E30E4CBB2B607AC998F20DEF865BDF47CE78AC3DBC1ABE33245D6FA7583B31B6FE7B6EDE7A8EC776B20F7BBE7E376578F0933B761BB0952161123D61282CD6C80CDC8A85F9632ABA1A8EF5925E410BB80BEABC67735D07E4ABDD587827745A3220A24A7B3902416BEFAB3073C2CB1FA76FF04315B653B3E7C18343391F92015939829DABD0289B5AABC4CB5335D963AB842865BB7C38106EB1274ECCD0140B415901279E8719C0415517B5101394F78A48F565317909371A3154D291698B0BEDE17052F30786DC2D46E71EDC438C288CBD44445F993926BFF0A8CA1A033B656C2362A659EABBCF37B2CB5916940AA9B3E850E51039C08C8588347E1099A0D8380CCC4B8CD0C87218BC24F09126A82A3D530A75500254510AC765CC1DE612A4CEB14DB78A7141109F947B4329158F87E4C8B41A92AFCCC9EB749D66A71159DB90E7A36642636AF22CC0D541CE52DB7AB44BAF30560691A637C93193A11A00EFEC075289953FDC9DF3EC3390342AEE44C08D661632FB0303681E1F89CE1300B0C1A36E63E5A45886A4C76534FA78B87A75CF96AC66205C28766BA5EEF7062363C19091C61C543D5C1B8A547372515722EE515E8EF52BF8E089D93377E2C8458E626D3391953D658CDB05C7A40077F4E19DC0B132BE719014C12B0CC242466112E94809630B63FAD12C99D271DBD38E5AFA54C894542B940415354203A0C8A785AB94200EE0CB976991C642257D9AF6998B61BA27B236FDFAB86F834FB2D47CC0904B9D6ACD2F8311F0D4B8AD81A24F712D92272587220E8023A8BC13BD17572D38851778F319607752466CB0DE7C5C12103FAE4C57D953B96BE93262BA9CB05405A5D2A9E012B21A22A2EF33A385C898C80AA9663565B63241A1B206F3379ABE8262CFA49BA05C3B43E9485E60CD38D66EAED114EF81AFD66B2594BAA361D3C3B02069B1A164BC387632E24C82A91BE2CA390EB585E900173699A8B26B8916E52BD643645D3225DF38BA50A50EA013B4B2A86EE1F76278E27F5A4142F034004B567F309C52ACCA3C7530162ED744A67481CA338861CCC3E8331E1C67886023743719493CC3CAEA51438E28AC4EA06B906789A65220E3C7407C874C6322BE1F9B627386081753AD618A8DCC013395F20F5017AE2B57BA908617490460D5A67FAE2660A56C4C4D97BABDA0BAE0F494260877F7077AF2536B2CA46E297C61DD8422BBE515519210DABC02E7047B13F16607AC15E4950574C43BF8C39A2528ADDFA2782506635E5626967A1F30C02FA3442FA93250571A8173999A88DC27B43C476468A6A4739972DC1B68493413A2743B9B563283CC886916ECA5887796A4F833AAED6639B9D531EFE5CADF9225573A23664C9CEA086428DCD19FF40A06186A41FEC0723953781475F648E6EEC2929FEAC2A86C9DACFA6214E2E353FDA2D547C3829F5678025FF8418A1A76EAE84D11C4528382828F7A689A0D5CFF87B8CA0BBA97FEACB39B935A8788CB +ct = A91F16FAFFAD2674D7E14B4CA55F230D862469E3FD04E9FFBAD5683615ADE14CCE1B9C911004C7B3D9B934A6C9294544D6CD1D3B97FDAC0D5BEFB7303F349FA70739A9C9017A0EBA508367B01D14733BB3C7DC8334EB2177FC553B7423BC340412E57BFBFC622E45D32E2715C37CDF1C856173CB214673A4CC53C79AFCFE81535D66F2A60F1272ADA087AEBD39E86E820CEA4D94E9271A1962127E4B9FC49FA67F9F3BD931373BF8B10B813917A339848AEE8DD118182E5C2D9CAE2C3FC1421474B78C108804AB7B3B546F46B7862D65BB28D33E260CAEDC91583EFB84B0535BD17C6CB4461E05253945700716E1C40CB829E729136E5073B0B86364934E26F25BABBE1D1F1F0D9E625DF872E6C136832E1D4CCEE3EC60126ED28841BB39A390A6F9289B4878224E3E857B1BECB231099822F337EE5A69577D3522174F7FB4E6B539CAA67734ED07BD8F73ABE46EFB903B5B9965FB414720CE5A8BB43DC13D441D4C62F10D4AFD7FC574DC802E15156C7FC4C76551C11CE3D2C7ADEFBA4ABD98586577BF0A9B54B0A433093B9AF348AF3C5F8E4FEF6C07C0A0DE1866F4BA1244DC4B815909FBD5397F0872079DEF58563D5E044066D898A9D738D8E5F4979980ADA72855E3C8994BE26C8670B8A4ECFCCCEA8809AF9B692FA184376C739A99CB46A050C825DF16039B92AFCE8D9F8894895A189BB544130A11096ABB902EA8924A13C81E00C7927C0D28B4EAD8E859CEC719FE9C914B0DDE9B36AB400135AD3A21382FCFAAD250A6609B971867A5EECAFF42A8AE051BCE111C4A154F15C3FAFCD92657A65F179E0FB050B2E4DB6E8CECAAAC4DE222FEF1B502B55F327A0E2E17059073E03C1AFB260B2242BC90BFC0ED6A035BCC5C8A56C36CAB2F12AB315F174750B6CA4FC7E9C1734B652D3FD97A1EF442B7BA7353FAF2BAA855EBFA3E329A4901D3B82A23B49513550D432D29B4098D31874E9772CEC94B208AC079ACCD959A4D71979B57A7AD48B7CA2E06545CC85293F7ED2F6CF474DBBAA31EFE9F09B2191076DB3B691E3CC790E35D249D2F37B3AA045EEE5D2D15E953BFA0A7AD6442D87C3D51F319A0E9B69F0D6C1869216348A033ED2331D9AE51E2F5BD0491EC12739BB567436F5F1D425FAA076565D868E7BA2E60C30E61C3DC9158C8245EA97CA49C5697A721FB0CC21C069D1064BAB42B1FAEB337FEC21416FA7456743A7FF7D523B3455035B590B2CB39ADAD6A290723837EC393D468721DBD5FCC116022F7DF742353863675DB7D83EB7AE2E71CDE3623B0ABE8C7BC8AA50C5E875F158802E3E3B115A3BB4728E111E09CA5226AACD911C70B737D7839C9FA2393734D06AC51E1DC80166ED17BA95A10B20E65494289598CA8EBFD57FE8290F7AB7CA8942FBEEB8D017FE52823F2BB7263C2C029E445375B0523CA565BE10EC0C7BBCC14EEB49AB97A382E315495F496672F8A8B293622AF02C74D4DB911C735EA9EAD60ED4427DC68E45E8449C0196355A593E6B84E42717F32C9ED2404E72B508F447E87 +ss = F804333E26C5981EB749E8E9FECBE8F8886E493CF8013A6760A1BF5D4A37200E + +count = 23 +seed = FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D +generateEntropy = 5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +encapEntropyPreHash = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +pk = C8735813347C3C7C05F81A176264A5FF791D9801AF88047574008C870635457126B4069071242C24DC0977A8C13D43B889D27F08984D9EA657D241922BB12AA28A1408825B02663B970778BF669D585A975ABBA6BCF8513C11BC73A0C33897991C3428A5CB4DFED155B9A2909E6597DD8CAC1AD62F9CFBCB27088860512859761885C5B6C5D89FD6B18F9E324EE8F80B4C507626762A22F4CB7F4527527896AAA97A69B8AA4FB09B16CBAFD73A667E9CB085F7CA36067D4F740694E6C83C671071762FBBA26A640C86422197894CAF01B0AF66960651998073BA7FCCD3189148187BA22DD2661262766399A6B8BB943AEDC590FA048816D1B9D827CA80935D30E1830C8115B18B754F20ACD7A376272C119CC8210C9AA112D604B2022326F51AD674AA1579C081F12DF04A9A2B4571FC1C21A8A4AE2C701EB2EBB0CE65CD2FC22FEE530FB3DAA6D82B3D46E33E9C918F6D33ABAEC34F45391245453EF4D128C4C068227A6511800D69F6A31A1421E2D322F897145961ABEA377C9393ACBFA72AB3C3AAF7F04DDAD50077E7C36AC46E083075265C58DB4B7B47DA253B8A9361C08A1248B53098C6B797622E228939F110ECE18C02AC613E00B624C61EFF4524F92C1EA632553D9B90CD886FD2C364B25C877459BA6DE0AC8CC2A8B0F2C6D71A051F8727C2892D1934857EB995A8D728B9739872EA472E6602F2C39484D290109BA924933D6AE52C30EB4D80935F0D2C87D4DABF07582CAE3C2F21692F0825C079EA6700065A6086B197582B76CAC90A58451D7479965475AC8A6AF662C7D23055C404246264C97BD23D280B43CDEB59BE0CB31E04474CACC4A1453FA10A9E1E4050F97CA3E9AB31E561AB18CB3AF721570380023A9349ED6BBC5DF66BB243928DD3A4B5E113A0F99725C9C8BF673818B89030DB28EDC536C9620A1625C8A647BD3D7055039753E11C4B1BE3AE79EB565E6367690B5338C554CFDA9369E9B1BA75651A0234D2325ED82369BCD415089692547B325EF28189482714C80DCDC5BFF72A6152B70AC2F16707C63A42830DD6CB88EE646D882338D3DCB202408FC5210C71D1A8BA02B8C2AB7E06E43CCD85CE39A215E67914369C749C3978778592D9E34B7671283DC787446B5B70A32C4C1CA4613B01A5D0BFE55016B897130D1BCFB49BB5F08C5DF9F15B6D531B06C53A389500675AAFCA9700FBC310FFF968300360AB631AD95649F0BB47E55B90B2593D9A60BB0477BA848C0DB9F8BF6C774CF8348C65695B31B921E4439E976B4306A47069C25E4A7515866C0BD77B44C7881121025CD2F28430383600E4BA0BD28074B7BBF2A2A3BD62A73BA240D644AB1F89ACE0C8A83AE62F642237DE265765458D6744273E4372ADD9CF5215BD39FA516575BAD72034288CA3E0D3BE57DBC7ADA731F5F13FC0252BC5A9213F502C342A451B933D3060A2AD8A9C13013E3D93455327C187547809FA57FAA299A843A251F8368A715508C32AA57A42F9551520433F9675ADD0359C5997C341464264986FCF67261D16B7A6989EE33730754A2CA0F66B6C98CB421C8E4B36002561B1A5550B93B144D5552AFEE236357C8093932829F864963159A8E7CA992B8FAE006190B55C6A4FC08AD10190D2A178865ABFA35607E1A88B47EC8EA71B102D7F1567BED46A +sk = 91C087E623025864C3C5D9049E865C6226CDD2B39F8A1578EB69A864CCB2FA155DB32702DEF5B50E973495997E18C6C21756568802A4BBB86C5018016FCB0655B09E6A4B39A8BA2D70E32BBB255BDD296C998A21F5716D49968DD02A9C4F4CB9DC72C874C232011225F8E8840F7589C2D285C1E72C8588C0A33A502A385D0527186CC6809185408E9C7FE6262725528A439332F93A5BA2943E6DD7B30D79A25939A4C0802BF57C755A5A0EBBDC8390F8AEE407A541C46CB1530FE1642215556D20AB942DDBCD1627826648ACC3FA1367DB0B45075470196B46697D9EC6974F477EDA553F80B701E853398C69A6E4970A746534928631E6B811E533A4D1E89CDD6969BFE0C861D2CEC3E16D0035BB50573ED61B5DBD45C8C5B223CEF4266C5A6DAF104949EABD27D3319BF12A7AAA4E5F636732B28E902A1098972977D98C00A267225B84AF1C8C404A52472B8D1A793E370B17A9935EE590331256620E302E390474DD6A17D17A50291B6BB940BC43F89FDD22109A72C8ECF9ACB1E67EF6A423396225E6ACBFF2880C35673135C5183BA37DF968330CE992DAE04E9455267A195A41893194BC51C67393251A11ED3C0829D99A3D23CEAA387208E00974E73178459BDA539BCBE89F5EEB05EE21BE3B1159018A3262120C21D4972ABA1A1350231D3A646BA70FA5B641EBEA1B130470A5EC7C40627035B03D15696BE1313B458CC9AC8460CF281A6976A9D2CCAEB9FB157300B4289A55ECA386D3D8A7D16C21102AACF361578010042C3A6397E2CB2EA5224141A1D451B38FAC14D7B64BD7B72DB17408B0A8906CEC108BB926DF54299261B6B5C6A636B395ACB651CE6B6018EA9C92C1525DE1624B5570F7000466CC09A909CF36F34687265B61DB6BF2882514705FB37346385CBF4DF33B98686E0189BDDEA7268F598DB1B6CC7B32792D5546E242A807E760ECE7080392823004453048C6F743B87C1670C6D10E3001008A24590294BC9AC899BD588197530FEF9C2B85AC66520A195C77A7AFF61672C8CB74C07D43A2BAB7A764E750663091A005C9AF8CC4B55D502169D4293E79B365F60085B1CC2F4900541588819B5EDCAA3B80253178639F63A3091701C7E7B04E95435BDD2114BBD3ABEFB23355591B0FF102BC94B56B338083B82328712733F2762C5B1D0845073CB3B46AA28CE2CB282A4347F2118A6E062D7E8524147545488A01378A853D489C03EB0C6527307FB0CA5F7AAB6C328438D33CEDC10733AB8A68C7AB88E0B06FC51C92C557FD59488B6245796B7DC291728121BC7643AA5D56C483186CB55086D7E8654691CD5EB97580F0A553A2613C486C0B9566A6F05F9D2B82B57345AEEC1368CC126AC53B9E794BE471C16A498B743C1848A14D53478FC341A0ADA42BC2E0717FB6965737876468515195050D64079D624DA1596F88819FDF95653B8217F9885D151821A9529420AC95DD928FC429674025882C9758226194615304F1F5CAAA456182C1BB11F0A02B6C758EEC4AB6441879A42450A024559697C4494D8AAC2F7045342234CD8081C0077C9232E66838460EA26274329988AF3A82B898C4EFB033FF4101F302A898E84BCEDCC45E369CD1BB7F3517280D6655C8735813347C3C7C05F81A176264A5FF791D9801AF88047574008C870635457126B4069071242C24DC0977A8C13D43B889D27F08984D9EA657D241922BB12AA28A1408825B02663B970778BF669D585A975ABBA6BCF8513C11BC73A0C33897991C3428A5CB4DFED155B9A2909E6597DD8CAC1AD62F9CFBCB27088860512859761885C5B6C5D89FD6B18F9E324EE8F80B4C507626762A22F4CB7F4527527896AAA97A69B8AA4FB09B16CBAFD73A667E9CB085F7CA36067D4F740694E6C83C671071762FBBA26A640C86422197894CAF01B0AF66960651998073BA7FCCD3189148187BA22DD2661262766399A6B8BB943AEDC590FA048816D1B9D827CA80935D30E1830C8115B18B754F20ACD7A376272C119CC8210C9AA112D604B2022326F51AD674AA1579C081F12DF04A9A2B4571FC1C21A8A4AE2C701EB2EBB0CE65CD2FC22FEE530FB3DAA6D82B3D46E33E9C918F6D33ABAEC34F45391245453EF4D128C4C068227A6511800D69F6A31A1421E2D322F897145961ABEA377C9393ACBFA72AB3C3AAF7F04DDAD50077E7C36AC46E083075265C58DB4B7B47DA253B8A9361C08A1248B53098C6B797622E228939F110ECE18C02AC613E00B624C61EFF4524F92C1EA632553D9B90CD886FD2C364B25C877459BA6DE0AC8CC2A8B0F2C6D71A051F8727C2892D1934857EB995A8D728B9739872EA472E6602F2C39484D290109BA924933D6AE52C30EB4D80935F0D2C87D4DABF07582CAE3C2F21692F0825C079EA6700065A6086B197582B76CAC90A58451D7479965475AC8A6AF662C7D23055C404246264C97BD23D280B43CDEB59BE0CB31E04474CACC4A1453FA10A9E1E4050F97CA3E9AB31E561AB18CB3AF721570380023A9349ED6BBC5DF66BB243928DD3A4B5E113A0F99725C9C8BF673818B89030DB28EDC536C9620A1625C8A647BD3D7055039753E11C4B1BE3AE79EB565E6367690B5338C554CFDA9369E9B1BA75651A0234D2325ED82369BCD415089692547B325EF28189482714C80DCDC5BFF72A6152B70AC2F16707C63A42830DD6CB88EE646D882338D3DCB202408FC5210C71D1A8BA02B8C2AB7E06E43CCD85CE39A215E67914369C749C3978778592D9E34B7671283DC787446B5B70A32C4C1CA4613B01A5D0BFE55016B897130D1BCFB49BB5F08C5DF9F15B6D531B06C53A389500675AAFCA9700FBC310FFF968300360AB631AD95649F0BB47E55B90B2593D9A60BB0477BA848C0DB9F8BF6C774CF8348C65695B31B921E4439E976B4306A47069C25E4A7515866C0BD77B44C7881121025CD2F28430383600E4BA0BD28074B7BBF2A2A3BD62A73BA240D644AB1F89ACE0C8A83AE62F642237DE265765458D6744273E4372ADD9CF5215BD39FA516575BAD72034288CA3E0D3BE57DBC7ADA731F5F13FC0252BC5A9213F502C342A451B933D3060A2AD8A9C13013E3D93455327C187547809FA57FAA299A843A251F8368A715508C32AA57A42F9551520433F9675ADD0359C5997C341464264986FCF67261D16B7A6989EE33730754A2CA0F66B6C98CB421C8E4B36002561B1A5550B93B144D5552AFEE236357C8093932829F864963159A8E7CA992B8FAE006190B55C6A4FC08AD10190D2A178865ABFA35607E1A88B47EC8EA71B102D7F1567BED46AC74F3B7FA6E2EF8CE99508C89CF3C71D666AB065A262581A5FB01B2C9B9444FAFC9EBBE336DC464489861DB8253606971BD0A9008A433ED17752D04023781552 +ct = EEDF2D6926813F52F9128C8EC075ED6B5D0B8B0BBEF802E11D302B47A3E53FFB33C246E79CEC593AED58A77B29C69DAC0E76B0A2B69C596ACA154034AEDF3DE6BEC9F7A0A3D1EF7B4E05EFB0789670E0575FD82A042E35EA81B9AF40546B266B42828439E1BAA4A58D3DBBEB1935578A5D6556F48A839311218F47B18E99CF20E406D968F446C575128E4AEFA43943F9804B6AAFE944AA03682F5FCA2DB078B6CFF32834828FBF0DAD0DDCB41D20AC649A65E009666644B0D3337FBF8D0CE4A95BCDB22AA816BC8037F5DD83AD82CF49E2A9089B778691EFBD5688B2F544CD67D419B6F230CC008FB0AB871C2825EA97EE31D4D72F2970D95276E5F3E156021C595CF1D522B8AB8CD3AE352519A3C733F7EB6A35564D8722725E5CAFB40CD178E3C680F6D531FDF024C0253BD0B9F2613662A35673F68BD1A9C322229C5804E594B7A5BF0EF05E10DA09DDA2AE2CAF143279A60586E9FBC920CF6ADE5B03842EB71BD4F38107C065642F0D80CD10BB866C9C2E422B6B506277C7F87E4A2957A0AF81C276A3FA84FDCAF11C50D708C798B1B136895FE50528D14DF38E74B173823750F7C1EFD787402F9C67D5CDA236AF22D2E189CCE0AFDCC1B6F96163C2C4DD65891E2E39683F5472FDADBD3D4EDF0AC320FD157C0BA236E98B6002E58B42AB9010E27028625D9DBF17EB8DE52AE9928C6390D7EAD758E62C21367AA2D24F07302C6FBA6B5E220467EF632CB331353F62D13C385CCBAE56DCD7B5C7A915855F24C41107B3E512572C31FF5CA29DD7CAC21A831EC1076D7DEBEAE0E51471DABEC57758EAA84903CFCB4710188287C07E5E87FF678D5CE229EDC40F532983FFBDFABFDB0DC4B14C74170B4A2B575C1E929C9466633FB78DD1CF72A42EE3D9BA4E0366FEEA959DD1056E38E18FA56B7B4C6AD7722048D8F3E639823BF26CE29333E60088B7C7C097229D784ABD1326B2C65DF4143CE50579BE5DF3F66FFA725346F0508EC94A4611AD088DB7C3F7825D5A8D0C7CF5E90FC9AAC1000D62F3366CE0EC54836FFBAE061A5CEFD72946D356FFEC1D2047B7F269ECE849A1473E83AC86BBC3F705C0980F380FAEDE71D5AA64A64C0F3372AA3B0F03B4850E1A1D17715D0B546A0D1959F739D520E330627BFEB52519B209255DCC60D6C7F25D0A256E15CF932FC98A392FC390CAF61FD3855F2E9D871E163E08E9D70A895BFE95EDF93432B98E330C7B228708DC2947B13FB3757A9BE1BDEDD859EFE809650D92BEE40D6C4029AC4B41C8F55188E56BFCB5EF665A11FCF62ACEDBC0AD627B46ACBB9444725AAD4A6DC8EB45AC1099F48E451CBEF50C71E10149D91467BB04582CBF7B7B3F26899E22DB449FD5C53DBFF4BCEF470F622C50F133611D7F3F9F8EEE66F1142CC8218580BB42F84AA7E6083C3EBC0DF6571A0425B2DCE8D1F83A5A2C97F055479DED547B8836B7BEDE8177818EAA65CB9286172D9C9E5AC9C7F01AAC5421F6826147DD0EFBCFD92BB4156B03D2B3AD62A0EBBD28B879FE5E6F43881000C521 +ss = EB9B44605E6B8FF3A59E567C1C16C6F96B6079F8E2C4D70F706D30DF82F09902 + +count = 24 +seed = 7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813 +generateEntropy = 293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +encapEntropyPreHash = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +pk = 04A592C364AACB2C89689106ABA29029C58DDF7050A2C78787358571AA506570288E747A4204C43E8C6020AA3E2D77B36C3440A618C55F3CAE6D43B979786E6A181D4107CB723BB6D0729CE3EB98E7A979CAEA9508563D5A0B7A7BA55B8985B71F3C489B370D37A66CE048A9DD27AD17B38C66880491985B2AF8916C547E9C6CB16B506170F29304C4393E8274EE254A3F13C6B0E31105442BF92799F21774BE9A0F64970E6AB581626115A1AA3EE4DA7936504D036B75BE6046E5778F58CABA93F8640BDB24982C17BA3445F2AB983B685644B596EF66ACF739039AD0A3CD61BB80B000F7E8BF53F60EBE235C0BF22C7873AECC6B3AE2F3B2CC3BB47D1B88423A188393C43C4999C32A886807CC4262BCD5A588C5E1BF8ED6A6EA9910C19A6042679926F314E7C7C85BF550482735E7FA088C857AC1578560A1A2F7E831223CBDE33A46632B7E24D400A82A8C7307C23D6CA25075B58E727673D7CB5554042CFB9B7F95B11A55A9FD63B1B9F0B60F6931A0BA1AD28B485753446B0005E8710D7189BF438407B8BA36A1687A48E550FA37CF4C6B591AFCB0AF6B8D2EA5A97B6C1729E7AE22E28F2082A5E653B5BABB0D147A8748F2606DDCC7847C24F0D32771B910CCBA85BEFCBD2B89C5035B2062E6B9BB40828902B82E12B752D48D52B7A6599AC014731E8DA091CB30186C849B61954DFF867899E5BF27428229376AC7D97FA03996160964ABE56D3D0278F9F91FEC6BC821FC822949AD5EC8A9D728B95B19052AD9442FA0527B3935F4697CFA3C7413CA2E81B32A57F69479E89760A46D710032EFBB662F9467F0D03C806B619B9228135076FA235D502230E56669E2354C1B412ECFD01A429B5C76B17AE2AB99C73B4110957AA38C22C8FA39C00261C78AA571B953D868690761655FF700803A477917AC8A6105CBFC220A30A0CC1466D7598B2058B3899C567A71A66D5C9DA75085686AA4AD4015100360C6102C84C336C13B229FF599DEE4CB2C90A1516682330722DA110F42F7C0A4F23A2089ADD65438DC66246671BE41E7766641B4C9139777E08CB4D5B953E602931A7DB3E1CE70D765516242AE8987454B898F19C5103BAD39207BB16771B5D4191ABBBDCA9B5BEA711081CA6521149B60975E02CC2250A355897960A8E203BA148F8BE76452420D2134B607976F7809CE97597D8CA57337FBBD6748C03227607FA082195B49753C43047B95A020C7D195B01DD3CDDC4C091916C37E447ACB606F2D232C37C9871831C1FB9A8D00717762F18E62E7995A7393E0A82617DA4674078D8F10065A28649E53377A88BB0F996D84FC83E9496564344D65B73AB96C4E887107D6C14488E604DFA15E55004FDA8B65AE19006EA7C8A7471B354A4E746703D5C79857A02EC222B78B966ECF161D97BA7CF39B37FE173485A0156C3712A6ECB14E629899DA9163709B672A243D1B87E15C0AD611419D85522252BB5A02AB725CB5EAEA5BDA73976D534A881B8C32C5328D117306FC5217AAB89CF51C6174489AD241D1CB261D449F24A235FCD46FC19A8D14A4281906236738A060061A494947BD91604431B1A2871080616EE2E915863B2BF2D9CD86743B0CC12A5D21C6C745B34247C17F9447579FCB9BD38AF3B64CC94782E299E1D98E68F8BCEFA20D1E8DB8552516 +sk = 817471E55466B5BABF92A2AD879C9C951BA60D230ADD630984B2528F9AA07FF755D7D79A2F9AB53D8986FD90895D5401DD97AD3F7A922516279B5858F2087E6491B7BC42B8A52A5952F23622D5603A0A3152990CFD6AB9CD863345D8BE5E295C06B79332B0AC89282E61E5534FE0AAC95ACA140398B64175235B94417B8799A4B6D6933A8B815BFBDCCF886664E7B8C5CB0B999BDCB2BDB288D569666C421E2A950D198158C0D36CED3A74D9032AB7A2B9F276BE025296A773266E516826480E520B844EB69710120373A94705F9030CA200A7F85A94DB1F55D46081570925A476099C3EBDB32C532A6D8F16BE4DE6416D0C30D450808CD3C08131A92551985B92255282BE6087703F182156A13CD144ACA3924FD15492DFD253EE5C9E78853590930521E843A0E37A26994197B3161EE1A60861C344720286B6566796787B05CB8FD76A419C364F1830FE2BCD3A2970E2DAC1DBBB3803F8053591B29BF64C2DC660EA9938200738E2C0C318B77FF86749C43C72F9667D80D462D549BDFEA30CB0D9641B29308A461DF72914B4B40213B62E68B161F83224C1A45472B5464F97C6D6371C69CA0D520426DB8C1E938A934D50AE0B03BE706B74CB8C674EA955A4D8AE1F6C0B56263041FCA1871A5799921C45D9BBF13C01F0A9C5D973086B33ACF923A2721C8B2FA7B058BB2E64F43BD80260B6BB19F26A4F55D53E7CCB1BFE3AA424976132C3B4B3A00908E722557A3657D285C8580EF45B76A207CB31A71402BA1EF280048378B80DC3312F78A74065B2DC873B22D37990E465E425B992722A25009A93A7A005D91B9460AB7C2336BD303883A151E829234C964265E42FBF8252CB89858D590CF0830E59C54021B83DA94884A173BE6BC454AD5A719252BEB52A4F7544A7FBC03CE9091E9ACC0568306E5BEC2ED942B39A8455FA341B84571AC3FCA43C14563F91395D117AB021C8F141A4EC7364BA4ABDD8896BC6B281C751A66C767AC960AB52058335E14E7FD8A4E1D44DE2670F9BBC67F682A0657530EBA11C31381897D989BD392FAE02D0AFBAA5AFA1748A80847AF4B326F970C6161E15B212A1C66003A4317348374E66B29FE87F36D01AF5F1C75BE11BFEA21DD8626765C46F0C153D0555B419227D50DA5232810D8517B1A5E4147A52AD07012D8DA23829F39A40C70D565937C58A11B1A25B27C8207246C4E1B40230E39E4F089D43D562EF954F332B7EA6B36EA28A9D26EB251AB562C0E44BD238874E93A4D3B900A4B2B08A0B68C2B82C0CB56325548DA3316279672913D2021D742C3619823C4391E64112B5B77E8D707F9C1A37D3464CD5F96543F720A0CC6C9631458CD9CEDEA7B6FCAA76D1E60C44F74B986A772CF593AE712214E21179519C39FA533A724FE8177EA59B1123E831E1DC561543A7E559697572157B60499C4C615D02099D34B0738581061A85B2DCAAF13556208B3E5AF388392490FC338DBC55BBF7D25F49F61BD7363CBE3841AAFAB88524B0CA3381F5B22DC84C6A112979C3C39E45157C0749C04B022F83F53733A21E1F1842E0E72F78C6AE1E337B53215AE8563B16D99EBD6225766185A0D92F9A28BBF4E2B444B7C8225148F601D014BBB8839B4B04A592C364AACB2C89689106ABA29029C58DDF7050A2C78787358571AA506570288E747A4204C43E8C6020AA3E2D77B36C3440A618C55F3CAE6D43B979786E6A181D4107CB723BB6D0729CE3EB98E7A979CAEA9508563D5A0B7A7BA55B8985B71F3C489B370D37A66CE048A9DD27AD17B38C66880491985B2AF8916C547E9C6CB16B506170F29304C4393E8274EE254A3F13C6B0E31105442BF92799F21774BE9A0F64970E6AB581626115A1AA3EE4DA7936504D036B75BE6046E5778F58CABA93F8640BDB24982C17BA3445F2AB983B685644B596EF66ACF739039AD0A3CD61BB80B000F7E8BF53F60EBE235C0BF22C7873AECC6B3AE2F3B2CC3BB47D1B88423A188393C43C4999C32A886807CC4262BCD5A588C5E1BF8ED6A6EA9910C19A6042679926F314E7C7C85BF550482735E7FA088C857AC1578560A1A2F7E831223CBDE33A46632B7E24D400A82A8C7307C23D6CA25075B58E727673D7CB5554042CFB9B7F95B11A55A9FD63B1B9F0B60F6931A0BA1AD28B485753446B0005E8710D7189BF438407B8BA36A1687A48E550FA37CF4C6B591AFCB0AF6B8D2EA5A97B6C1729E7AE22E28F2082A5E653B5BABB0D147A8748F2606DDCC7847C24F0D32771B910CCBA85BEFCBD2B89C5035B2062E6B9BB40828902B82E12B752D48D52B7A6599AC014731E8DA091CB30186C849B61954DFF867899E5BF27428229376AC7D97FA03996160964ABE56D3D0278F9F91FEC6BC821FC822949AD5EC8A9D728B95B19052AD9442FA0527B3935F4697CFA3C7413CA2E81B32A57F69479E89760A46D710032EFBB662F9467F0D03C806B619B9228135076FA235D502230E56669E2354C1B412ECFD01A429B5C76B17AE2AB99C73B4110957AA38C22C8FA39C00261C78AA571B953D868690761655FF700803A477917AC8A6105CBFC220A30A0CC1466D7598B2058B3899C567A71A66D5C9DA75085686AA4AD4015100360C6102C84C336C13B229FF599DEE4CB2C90A1516682330722DA110F42F7C0A4F23A2089ADD65438DC66246671BE41E7766641B4C9139777E08CB4D5B953E602931A7DB3E1CE70D765516242AE8987454B898F19C5103BAD39207BB16771B5D4191ABBBDCA9B5BEA711081CA6521149B60975E02CC2250A355897960A8E203BA148F8BE76452420D2134B607976F7809CE97597D8CA57337FBBD6748C03227607FA082195B49753C43047B95A020C7D195B01DD3CDDC4C091916C37E447ACB606F2D232C37C9871831C1FB9A8D00717762F18E62E7995A7393E0A82617DA4674078D8F10065A28649E53377A88BB0F996D84FC83E9496564344D65B73AB96C4E887107D6C14488E604DFA15E55004FDA8B65AE19006EA7C8A7471B354A4E746703D5C79857A02EC222B78B966ECF161D97BA7CF39B37FE173485A0156C3712A6ECB14E629899DA9163709B672A243D1B87E15C0AD611419D85522252BB5A02AB725CB5EAEA5BDA73976D534A881B8C32C5328D117306FC5217AAB89CF51C6174489AD241D1CB261D449F24A235FCD46FC19A8D14A4281906236738A060061A494947BD91604431B1A2871080616EE2E915863B2BF2D9CD86743B0CC12A5D21C6C745B34247C17F9447579FCB9BD38AF3B64CC94782E299E1D98E68F8BCEFA20D1E8DB85525167378EF967195C977D43A50D03205044006715A6A8A8263D717F40170B49E6BD0FF8563038AAD865A817CAB9CE98846BA75BE9363718ECF5FEA538AEA90B2A558 +ct = B36A4CFD44E71ACB92C3E25C36178609188A91E88AE7096874ABCA6C47E37ADF762D028541985915FFB85F3417B024C47B9C0C2BBF682E76C04F6B69EFAB7E2B4DD0B1E72E9408BBB61C0200272F02A8DE1E7ACAAF9E6A7EF4A4C54C224CB35C7782A503C0DA7577D4696C491870ED05F930E0E93C1A16441B603E76E125AAB09BF1EE9152158C9BE7AACAE8688BA2FCCB23E5932A818EE089566F8D0A3EFE3E59AB73F73972679215710E92235219692F27FCDF08699E5D1AE5CC07F9508512EFAAEBB86D86E29C6368184C7B4EDFA14901274EB3E19E0D3B542550F03D3E8CB752376FB9A23E467C4DD8062ED6FB10B53433A9A122F52621D4138AF03F48D3CCD10F701C33D0324A3341595433215E00AC76959255332DC35EE687045FF208ADD581F3AD9BDB7C7D435954CB437F995EF3BF22C0A475979D97BE46A91F9C3934170505037A79B29112A2D3F3AFBDA3188BC43E3C3B746647E8D722455D0844957557B355F424AF2909E46B9DDC68F4B287CF7CABDFB703D92DEA065623E9A3B7F4622E7C5365C04D667D04D172FC2E9E82A2A526441EA71B524DCEF1844746B06CBF7D083C09A020268F8FBEB92491B8556813781F74F32985267CD7457619FFE986AF32254F5538329904CFD8E438C248FB005A085B81448C45FF17BA45223E2B47246FB6B1B4A2444505FB372388ED77F4A8CE7AA2B9145E2CBD7DA00663E58300C919AB354C77E29A276E2D6DFF26594DACB12F56562447BADD8DEC8476F56567A65C44B791BED29E50AFDCE15FCCF57A5531D7614ECFE51AF936F6E4182B281B1B39DA59C20B3B0807A770DE434A8B72BEBA95D2FDFBF08AB29DE3E1C417DA199F98EADB3EAD1F25B40762D7E7487A3DA02E3072E0A15A33DBEDB5209C3E32CF9B19FE4825FAEABEAB1E2E63DC8E8B4E5A50575DF7103F7B58E4CC1307553ACDA05172787CA52BA594824AD90FE1CC702263C8BAB4AD690E11ACBA025BDCD9A299FCC1F801199272FFB5A39A6137F127B83B98DF5B19D940BE257FB0844804107F6D5A7D1089F17C8DAC90D59035C28297DAF136600C18515DBEF0036CDCBDCAF8BE6C4AEB1179E389AA345CB5DF024F9907342435657D5599FA424E51AAC32CDC57E025B672DDB87658DC23C3C54BD8DFC916863829E3F7DEE39B28B93B2001B8434EF90D1E5FE0BEDFF2D31B5AF01FE5F996951F31AD0D6F173F50CDCD5A7333E7B3908D8B626E3F08FB1D9EEDCC360E6ECC4B74BC33834AAABC355CD4432B09C40C011CF7AA90AD8A756340D30B3D7A3E465C9A19173B58245B1A8F42C875F96336D39CF60F1BB341680177D31724E6ADBE668AF76720C2E398A5B42C3C2C84384EADB951914398C1CB092B870449C8AE1BB844CB5DC7B32B8F661CAB9B298E8F90CD4B4ABC63B590A6D6D183DE03B3F61D5C266DA83C14847F71E5E344441CE178DB44B2CD4C644EEE4371E7B9793343F86361E13D1F8664FE439217241ECF8C68467941F48939485046BD833A3ED8582B9415F25C2C7650EA1E51 +ss = 5635FED1A43168075134D0E6DD4C9CFF6E85F3860B3E9F1CAC06B249D62892DE + +count = 25 +seed = AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4 +generateEntropy = 74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +encapEntropyPreHash = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +pk = BFD11FC259A2115806F9F68AB15859A763A49D169D615B4999714D550707E8A0C0A93C8DB2FB5E4DE7C93111206F052A7D7A5E0B5632D94C7A87596D24E950B361A185F065FA96435F312745164693FAB8D3A741C56C6F10D8BE52C06A5D83CB1BD327E5B28DB12291D907A2888136B6FA3A20A48990C6B6C81499DE2BB12D19B591234D55C4549A3861626167C5A17CC2A4CC9F668DF0707D26795DE7F771BC614B994B574FA309A1E1C8B4A0A4AD6240286BB78BA701ECC430269A37843149E1F1AAB731523359C735694F09298E2A1A08C6EC273B4A1D57118B20524FDA18190C2029DA4095EAD53212F609A76A343D5C68FF17CE6B92B340DBB8CC6C03AE4B29DF243B93233AF6B95EB5A7A8B8643B0CF5A8114152B8EA54F0E3668511CEFF536D888BAEF85A62299C641769023B7B92088546F338448C1977804B71781A554BCA5F13C0480B42C5A6626904516139ABAA54B429E7A0502B17A5A2727A7F230D63C5764DD497F164B24E5BA3A626785AD1B917A6B77B175E64323783C9791832A7C442B895EB338E6A29EF671D4D7C0230668C14BC794CF11340229AC905891CF1C51EF62B6A4A0553331F7F581054DA45C370BF606126B39492E4A3B8592BBE0359BC017557379471EF922367D82635D8494C88BD38A7720669A1F9145367A92090FC5DF15C034B82CDD9B7CB9CA76E74B2069C36987556012BF0746424677F60ADE29C9CB52C6D9CC2052394691D7306952C65EF498DA41279EEABCCC66B3A41747A8B447D7EE81116EABC04F4B776923C93A28FFE888652FC34415BAAEB6854D4732745A4BD5BA61C35678780063ED874C81823CEAE41B9684A05410266F7ECAFFBFCB5285472E5B02FB8C15D126410F0BA3BA8536CFDB65D23797414A55F2620BE653A98F33C95690714FBD3418C6893F8693908D41D6D69A744E63B2B0C190E3B1696A5C8B1CBBAA4719A0BD184F896C9D8F926DC933BA81B2785C05A51B22A95191F43DC23B42C050DC9133DE2B003A5B6F1A5730F490454C58AF291CD8D46ACDE69842DF79353670A54E2C88CC693745516EE64C2AFEBB95DF25EC0608AE4AA9C89215D471BBF68DC6530FC0FEE495FDFA09E98BA8D37F9636B270BD1102579EB7F1BF0B911CB79F03537168867EAF60D77D48BE27BC935B02662929DBF2263270670E0601E5E43008BCC07F06451E54755FCAB421D584BB603008C9909CAA61CF99A4B43A93EA8A3440991BA402C9A8FC51F90584C55EAA450B7A600342E98420D728A8B6344659F2A0263140E69AB86BDC6B20B3AA0920B90C70C0108358C8A92B27635154AF9A0A76080EE593CE3D37E40FA33D0C654AA77171F822E0082C95CB60B54A6A26099443F671E863889F35A0B9597B3442A71FA704F164834FC9C8E2C63847C9992CD73C1BFE7ABD3D75448D21926DA0938F92B9133A92E426DFD2634A677878EA9820F5C26A2382FDB1C4B8ED59DB74B4490B87B0DFC35F5B22112E5110D494E53C50D3FD6C64CB485BF5AB37F7A1B709122C7086D3FA56FDDC966DB2C53E09B976F986A334290DD8C3C7E6582C4EAAB182766FF70503B03B4E68261CD0303F7A83732795CBF84A04D78A541A0929691C94A094B7B8F92C5D5A3BC95122A6A7968DBB1334A712823D470766B3B9E7B55672D02AE +sk = 60E93BEB5544294BBD612141956430CFF041E0F969E954A48298C7B5F321B9E1B70B7C796A753CC5BB93722B20380ABD6B8AAC4F0B102DDAB380B88AB9DC040FCAA8B775882A673864FB757A3453273627DF0690C90000B54112DCA50235BA14FEA59A764736A018A091B822A636AE7934A33BC5C15A7B77E1E53289C9757EC75CBBB792645325D6755D79B972AE993C9E3413AC040B3BCC85C4F98A2E185BF4EA1D19A4737DC78547847B7EF385D2A07BFE272764CC873BE8CB1286A0E7C83539D2B9BAD5A17F0893CCF41E2B5CAB8F66706955C5E168A99E9820A8402CB25A434F1A149F0148761014D32A51BC73A8CDBCB104C29BE554B2724107EF314C25D082C7252E0CE68833A47A619A611B08394960A64D8C22C25AA1121A8033605C9BF35221730B15E6269CC25FEBCB8E3336870B3C1C9D3A89DE4A9042758F517B55F85133B403C501590A0F53542239118F93874B319BE0D063AD82144ECA6156051424235D785C92AC00C412F8AC0FF5B88F056142F8A0934734B09BA14C00089BBA136279A5FE462082AB4B0709A6DB3279F8E9544F3909FF78B264399C2ED129C803B341D816EAE96BC531952D55059EF0233B0C18E1F7AEE5498FF6F11DBE801DFE193BB61B870008AE57483DAEB8CA7CCB460193C68A509E8DC738FF227FDA89B21EBA0053992A4D3A1F8767C0D3F3419838C8C7A2C0B3D68E737BA77221C68A8570948A322A143E5A03888C08A1BB7C42E9DB9111819ED94523848BC32781A881A468D26AA7FA4ACB926AB8695B24A094B8CCB0423192CEA88C1FAC818A6B0CA19E423B7AFCB51B121D48EA44037963EC1A325DC0BF7555977F468FEB49B8346338DB983E512B2FDEB35A300495F437CBA88C36D01536F7A56BC9DABD1000B77751031102CABA7182E2C440919435A14BC1AE1B354499324862885C9C301B7258FAF778CD0A4721F26EE32C5DCC7A7283DC10E3CB04713255D0044BF1D9234F5180F32483F7079B2C0558B95C622DB01BE885B2580931FC8617B6940DDFD54CB327712DA02F90A6A8DDB6BA17A31FB1D7231D94CAC2FAB88A43B0F56968FE2B724FC8A97E1A371C96A9A17A94FDA08897BA1EDF959F37029A84E707EF676B89FCB5E94B8997D95542E26CBD28A7D01B1FEF76B1C91AC327874C04F01B2D6280FDC60CEAD3587BC0AA6EC76F064B3263B2419BF3120AA7791053BFA6E089F6CB8BB020B5C5E2517D4B2F34EC3C4237AF98DAB3F4D44AE161773ED53F391A689D7B38F01155FCD080869656E15BAF9A2A6419B38C2EC39112B4216FBC5D94771FCC4369EB90AACCF3A752020E24F97C30C4C67632180E9B928A0941C23C03CE588F7D841AAB91B74B7959BFD8B5B042294EBB094B523DFC425E9EF70BD2E2BCB2937EEDBA0AD018737BA91A3691030C1A6E54C0BD4336A4BBB7C5DC79057EF5C574C04DFCF9C8407CAC999A54975B1A45519075CA167B8285B2D554EB81702E30626897413051AA546BC63A42723BB95F0DCC525944C967D7A5793C34C7638EE59608C8680F2418B648B7450B09C31BEBAABB956E1203BFB3D377373B5483C93378F15DCF2959D0E02A15E2277B7AB78CB2BA78703F13DAB307BA1B663C86BFD11FC259A2115806F9F68AB15859A763A49D169D615B4999714D550707E8A0C0A93C8DB2FB5E4DE7C93111206F052A7D7A5E0B5632D94C7A87596D24E950B361A185F065FA96435F312745164693FAB8D3A741C56C6F10D8BE52C06A5D83CB1BD327E5B28DB12291D907A2888136B6FA3A20A48990C6B6C81499DE2BB12D19B591234D55C4549A3861626167C5A17CC2A4CC9F668DF0707D26795DE7F771BC614B994B574FA309A1E1C8B4A0A4AD6240286BB78BA701ECC430269A37843149E1F1AAB731523359C735694F09298E2A1A08C6EC273B4A1D57118B20524FDA18190C2029DA4095EAD53212F609A76A343D5C68FF17CE6B92B340DBB8CC6C03AE4B29DF243B93233AF6B95EB5A7A8B8643B0CF5A8114152B8EA54F0E3668511CEFF536D888BAEF85A62299C641769023B7B92088546F338448C1977804B71781A554BCA5F13C0480B42C5A6626904516139ABAA54B429E7A0502B17A5A2727A7F230D63C5764DD497F164B24E5BA3A626785AD1B917A6B77B175E64323783C9791832A7C442B895EB338E6A29EF671D4D7C0230668C14BC794CF11340229AC905891CF1C51EF62B6A4A0553331F7F581054DA45C370BF606126B39492E4A3B8592BBE0359BC017557379471EF922367D82635D8494C88BD38A7720669A1F9145367A92090FC5DF15C034B82CDD9B7CB9CA76E74B2069C36987556012BF0746424677F60ADE29C9CB52C6D9CC2052394691D7306952C65EF498DA41279EEABCCC66B3A41747A8B447D7EE81116EABC04F4B776923C93A28FFE888652FC34415BAAEB6854D4732745A4BD5BA61C35678780063ED874C81823CEAE41B9684A05410266F7ECAFFBFCB5285472E5B02FB8C15D126410F0BA3BA8536CFDB65D23797414A55F2620BE653A98F33C95690714FBD3418C6893F8693908D41D6D69A744E63B2B0C190E3B1696A5C8B1CBBAA4719A0BD184F896C9D8F926DC933BA81B2785C05A51B22A95191F43DC23B42C050DC9133DE2B003A5B6F1A5730F490454C58AF291CD8D46ACDE69842DF79353670A54E2C88CC693745516EE64C2AFEBB95DF25EC0608AE4AA9C89215D471BBF68DC6530FC0FEE495FDFA09E98BA8D37F9636B270BD1102579EB7F1BF0B911CB79F03537168867EAF60D77D48BE27BC935B02662929DBF2263270670E0601E5E43008BCC07F06451E54755FCAB421D584BB603008C9909CAA61CF99A4B43A93EA8A3440991BA402C9A8FC51F90584C55EAA450B7A600342E98420D728A8B6344659F2A0263140E69AB86BDC6B20B3AA0920B90C70C0108358C8A92B27635154AF9A0A76080EE593CE3D37E40FA33D0C654AA77171F822E0082C95CB60B54A6A26099443F671E863889F35A0B9597B3442A71FA704F164834FC9C8E2C63847C9992CD73C1BFE7ABD3D75448D21926DA0938F92B9133A92E426DFD2634A677878EA9820F5C26A2382FDB1C4B8ED59DB74B4490B87B0DFC35F5B22112E5110D494E53C50D3FD6C64CB485BF5AB37F7A1B709122C7086D3FA56FDDC966DB2C53E09B976F986A334290DD8C3C7E6582C4EAAB182766FF70503B03B4E68261CD0303F7A83732795CBF84A04D78A541A0929691C94A094B7B8F92C5D5A3BC95122A6A7968DBB1334A712823D470766B3B9E7B55672D02AE16FE956BE4601573D72306A251F69BC2181253E2417E178341FD6553303AC189E1FB7456AC0AA1B97068F452CBA64EBDC138BCF5D36B0A0FADA2A3B374141EB9 +ct = 535A002076557FC2CA495E8000B26F513DC41524C6E04F786763FF14F915D56BD6BE3F26729E41FC2E43456CC5F70DD25EC772E9030FF80A81A16E352CE7B6FFB5BA34DE56290D1EA1578A56B8D17A0CB5AFAE7987D15CE029516D88ABB555AE84B9F626960FD8DA732BF8F1A650307030316B8623B0596DC6CD8C72354584FC806DA654B0ADF1313ED3DD6A4B8F81A5C2600E36C57F28AC00AD18A48C00C8CFF0CEA1F8A53D227E89D78D533834816ED9B2A9EF48F6C5FF4D572EEDF497342ED6EBBA80EAD83EE6764F84DD09C5F372F263CD7195A50DD5695CB9B09C8E996994D7C94A19966FE74FED01139D2658AD75AFE22E0ED321D12D271CE2DEC1099E77573A3983574A63BFDFC9EA559A220135C9D8FC22F4C7A3A0506D649BD4EDC66D67A398B4B1B6040284AB0BDC60EA62F0B67D42F5CB6F5A3C6AB38EB3B2BFF6D7385143F40EC5CBDDAE52DC941235D980E4DDD79059790897FE235C11BF88A92EBA7E6EF524A4AEB827C057B75E802539BCCFCB33B5BC5B00DA2731B8F4A5A42A7AE901EB8B7783A017128C3765AA8A3BBF92EEBADC48D983BA16FA0043499302781AE46E2F066C312DE84EF0C0A837E8B6F9F633F8D2C2190A129D9A00A18E04B2DBBA18A0590BD6B50B31E470D85C803FBD35ADE162982AB659D7A627811B76217435A104860173AED6865A3E1967939BC8465D4F3E5D3C88091D1013FE12A2110E6FA39EEAB39A9EE545DE65263E1BC956BBC5ACEB6D6EE2FC0F1C4EF945C21C36CD76DBDBEAC43D440C1128A30A0CD581F434B2E5F45AD26B4C59CB6B003D945343F8413681B590C6627B12058D671B220DF6A0270DB87F1A81F01ADF0E33AFB686E76DC414684023455EF3465E26208E66F4A4C5C4C685B415DE1182DA6782DBA4CE1370D00E411CD2709D3596B337788F40574B43691F6A13741A75C8A973C626FE6B5595DEE15F997594C873605E8DD3F0137D358A2A5B1BBA8A9AF285E1C02D05944041CD7082BA247C24810140E5E9AF32D010196EF97CC40B95F5040469FE88E7557EB30F2E638647CCA2DC1845E582416345F9DE6DBBC6A007DD368F1827E7B29E296123FDDB818D9A25FDB429D45CBC59D0D74D5380E582EA7C73EBDBA8A4CDA6582B68FC07A402FC1EF8F24C1473661C091A942E4F316602470F779067D74B1B6BC61B8133ADF1E5FBD374DB3EAF8CE169E02DFD2162AF1718E7F21CFEFB86EB5AB879615408A91B0EDF44281A5693FEBB6C229A0203E66E6746747AE342EDD2C3F7B528EA2A86140E8041F7FE6D671C999DAA5A50C5B01B3CCC35CA43ACC3DABF6A1ACADB4208D83CF49DBAA37843C51A55765E5F5AF141DAF67D3D5AE31A72F7A4756AD27BEBDA0B7B5AA204C8A8E726B42FCE4633DDE43EE434029D60938A3C4C3AAF119E2B3116D5299B6B7C80F9D49D17389101E7CBD668A038C223E7B820FB057543F8EFD37760006006F61035D41ACB177BD95AA8F44CCD4EA8DCD8309D795945ADE186EF9BC22D9921DC2843BCB627C2F865B1A56E +ss = A920DF59AB127D563D7E7E96AFE8075D8A7242B0AD88D72F367545FAC6DAA4C5 + +count = 26 +seed = 7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46 +generateEntropy = 013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +encapEntropyPreHash = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +pk = 12422CEA108045D2888E2C29CE0BCD454B95C09730D6C4698E779987523DE0E972332544C34350D29C7BC030BB6273B9F1C98C3A63170ABB2641C54DAD64790E83387C51AAC922814F834C4745409273AB00051B2A819EEFC9A048F222626409FA7B3F8D27A0DD754F9372AA37EB92F6454FDBE3116D406B571203DC05201C31A52BA8B2B95B191A7B7B55E743C4CCB80A710863AB741B727F176224012C539AF2BD062BA6BE7A42EAC08C5B6B420BECBB41B55454EC1F41347CCD984F11767BFC82665286A56DD31598834B37CA6EE93658999798EAD094298160B7E6C76978370DB3180273401532315168A161E087D4C6086846A3B60B80103C1AD814843BCA7AB329C7914982ED32BF16507B3024A16F231281A732D3D155FA60260064919C484C1741874BA96CFD91AEBE5C314E407A66D7CC4C846176D759618654AC2A52FE69C69A375ECF625E2889ABEBF395FA20561BA6300A72A2091356FCF197C866AB5468A3AF7BB3DE755836D9784F7C0949445D83B3358721C7DB3C09B5120F7F757BFE3366AE4365B677255EA680F27C310F768E56F1AAB8792259340BD6B984406148A254BB605A291C0946C83B1E9C5BB3F879A787B9106F98809E94BDC23C062D592318F9854DF04BCC343D64387BAF398599BB352F82B1F0A5B530E824CFD69D7A4A15CB5624F70CBEFE1C61302B8FCA337D70D1900DC817837619FA893208DA873C350F02892097708CC637093EB25BFB4B3C793331F0FC73C5446CB11276824CBE419378A224A683FA0D17C671FB8C4BDAF18C20C53A21A4BB8FBA9AB7A1B7ECCC81946BB5FCB15E1D08ADA7761A55D503DBA912B73765FF93A6AB642B5FB72ED4F16657AC448A1957413CAE547CCD76D9936C860C70C5635C28754421AF13448959D67CDEA3997EE923AA326129B5397C15AB90F95832F263E080A42460CF9F081152AA59CF17263D008ACBF146F34A7808257689A3148E58A0A0117FBB47BCA97810A42A7E0F734C0A17745AFC6ADE752080B39F3267399C20B1FDFA195437B83EF5125405ABA8D2CA42040371C541A5FC339772948A21B7EFC30C909C7938779BD012642441083150118CE431BAA72E989425210945A7C47479F4873E3C3CA6698ECB2A050415066D0BBE5E240222A2884B3CC17BACC14164BE0D21330456A279547579F8A4E9443D913A154210A3FD1A1A263186445A8E1B884BBE8B54D0196AFFDC47544C8D10A69378FA139BC8A422C44C5568555F9080F170BC6E97284F448E6C23885D603A732C469B376A762B5068E29E80B74F994588D9822F3E81BA6FFC273A9C905D0910062BBE94AA1E0C8C3424303845779F8C9B515DFA0864578A66DA8AD7B56DA2810C11E1A2888B88BB55B8C096A145B62AD9D2C98E003658C9729D7B82550527411A9C0B981F3479251C1774014749D211687DDA83626C6BFCD5B08F8075954BC10F48623838A736E38C1143B9472B4DF5D30D37F0BD7C727A2F16A3CBE0015DAB5A12E27A63F7AEDB841D6D9BB1A79A5C3E903C9E374DA62A298C549B9842B77C33AAB6B4939AEB55704CB610D084950C41B746AFD7157613618F6F1574BA51B36F7828AF0AA4F79C0840EA3D679013DF619046E935E0BD96EC59643250A0B38F9779B0142A9E546EB525E72AD204D1EB31A6 +sk = 3A756D6DD157ABA65D60721C41EB4EDBEC38834C22E9AC88F03119B472BDA0961D1F5C3268EC6492F92D5D066DCBA69CE9C20311E1C15FA81FA5014C6C956F88055FC2D35E6B295D05D6167E4375BFF23257BA72C0F97F452B609F22B57F7C27F71A4F259938B5AA18097399A0D32C3602203BB6769015495B4BB7317C9E99C966215C58D3455EFCD36003826C2C7B1BB437A66A968DCBA35DAD7098FCE9133110A109C2B91764719CA25866C98550082E88F29E78B38B40A53C4D626FE63390A290B54389624C597909D79FD6A658E2166704C386EB1C8E951B4C7619B7B79349C3F59505809B1095405949CC55C109A1108649552D5F83A970083BFFEB6550893B5C5106417B0CF1E44B6B05A9F9093E386C9D43F14D4CFBABD3B17EFB49AA2C571AE99197D2E4B7D58775962570D528B8EBB8032E8065BDCAA391837D483A27239A4A8C0B8F13013F4AAA6BAC0CA86E532523D9620BF9C2C3E2AED2365E90A1699A4CBF454C4D2E2C4273E93456142F737C8B3697B9821039142C3E25B346D020C829850D6CE2649087AB762C25BAA2639C8C7A852BC76D456EE69747FE561E267844A7E51AE05C5820F0C2B880B05CC935A3BBADE2C6A4881CAC21938A304C4CD2C1CC1BFABD932B777CC459BAE4BE75389862464367C6318A0521DD62C5F070A139A95522D10D2E4134C06522CF52834562A208B22A95431014934F51EC49F5EC087D1435DB935BB5223C3EC87BB7F7427A458232474AD9CC222B422149977C7F366F48B0B14AB260BD0A8C04623F9B12091AE049725064D0BB4A249075816AA249718F1A7768C3469AAC7182D2F01D6373038D7C4CA24802693A354C19C66DBA1C05EB180AD04C1FB095B42947D16B66139384C71206BD0BA9AD9BBB5DD7593D08616C214FD9013E792A5B4930122D1C571F1315D235562C167D7546C8EF7536A929982F6A55CE7209B0D5735F69AC6C52A824E508D2481A5BE01075C54D8743BCD76767B69B5E350989E629C97AC1982A75806126245FA692DEF22B15A29499C82EF7F993EB3472F850527D900DA2F513A9366A4FA978038B9E46752DBB8084FB12CBC591008D692544078343E9AD67909DBD77C18BF18F02607210F4A0F5DC749F8B0BF371309027968968678B0135AF65138C5544ABD57ED8A646409224D32052BB14BAB4D51DAC981CCD838B4A513A36A351B81A0785CA281D7106872583B8BABBD62A5787BAB8EC9019C7009130EC6BE4E25D9992AA1DD13DA9C1A7F1CA27FD78968741436003789B8C781C599C98D2465C7513CFE85154D7A655216E5B3B800DEAA6B9DC7C0D998B9CE2B99DA6AFC27A5EF6C152EB16184D91CD038CBA69835AB3500AC2E87368F37888BA90F219CE9DA24109F0B3E1894DB5F640A17B0E705195A350A61EC62B2C7A216231C530F557D4C5605346A6500B7C1484012FC87DD4526823C447B71A726D65753716B30C212565DAC474CA3ACEE664218285A5C4A726F681E98619E2A289D08895BEA26BD6A3BFF3A5C5C1EA894CB6440D075004F879B41A14EBB82B74AB0131D0B3348742DB7244E750AE2B7BB57F8A95379502827880F8A50ECB1394DB2553C07627C113A300078DB1BAC7B5007812422CEA108045D2888E2C29CE0BCD454B95C09730D6C4698E779987523DE0E972332544C34350D29C7BC030BB6273B9F1C98C3A63170ABB2641C54DAD64790E83387C51AAC922814F834C4745409273AB00051B2A819EEFC9A048F222626409FA7B3F8D27A0DD754F9372AA37EB92F6454FDBE3116D406B571203DC05201C31A52BA8B2B95B191A7B7B55E743C4CCB80A710863AB741B727F176224012C539AF2BD062BA6BE7A42EAC08C5B6B420BECBB41B55454EC1F41347CCD984F11767BFC82665286A56DD31598834B37CA6EE93658999798EAD094298160B7E6C76978370DB3180273401532315168A161E087D4C6086846A3B60B80103C1AD814843BCA7AB329C7914982ED32BF16507B3024A16F231281A732D3D155FA60260064919C484C1741874BA96CFD91AEBE5C314E407A66D7CC4C846176D759618654AC2A52FE69C69A375ECF625E2889ABEBF395FA20561BA6300A72A2091356FCF197C866AB5468A3AF7BB3DE755836D9784F7C0949445D83B3358721C7DB3C09B5120F7F757BFE3366AE4365B677255EA680F27C310F768E56F1AAB8792259340BD6B984406148A254BB605A291C0946C83B1E9C5BB3F879A787B9106F98809E94BDC23C062D592318F9854DF04BCC343D64387BAF398599BB352F82B1F0A5B530E824CFD69D7A4A15CB5624F70CBEFE1C61302B8FCA337D70D1900DC817837619FA893208DA873C350F02892097708CC637093EB25BFB4B3C793331F0FC73C5446CB11276824CBE419378A224A683FA0D17C671FB8C4BDAF18C20C53A21A4BB8FBA9AB7A1B7ECCC81946BB5FCB15E1D08ADA7761A55D503DBA912B73765FF93A6AB642B5FB72ED4F16657AC448A1957413CAE547CCD76D9936C860C70C5635C28754421AF13448959D67CDEA3997EE923AA326129B5397C15AB90F95832F263E080A42460CF9F081152AA59CF17263D008ACBF146F34A7808257689A3148E58A0A0117FBB47BCA97810A42A7E0F734C0A17745AFC6ADE752080B39F3267399C20B1FDFA195437B83EF5125405ABA8D2CA42040371C541A5FC339772948A21B7EFC30C909C7938779BD012642441083150118CE431BAA72E989425210945A7C47479F4873E3C3CA6698ECB2A050415066D0BBE5E240222A2884B3CC17BACC14164BE0D21330456A279547579F8A4E9443D913A154210A3FD1A1A263186445A8E1B884BBE8B54D0196AFFDC47544C8D10A69378FA139BC8A422C44C5568555F9080F170BC6E97284F448E6C23885D603A732C469B376A762B5068E29E80B74F994588D9822F3E81BA6FFC273A9C905D0910062BBE94AA1E0C8C3424303845779F8C9B515DFA0864578A66DA8AD7B56DA2810C11E1A2888B88BB55B8C096A145B62AD9D2C98E003658C9729D7B82550527411A9C0B981F3479251C1774014749D211687DDA83626C6BFCD5B08F8075954BC10F48623838A736E38C1143B9472B4DF5D30D37F0BD7C727A2F16A3CBE0015DAB5A12E27A63F7AEDB841D6D9BB1A79A5C3E903C9E374DA62A298C549B9842B77C33AAB6B4939AEB55704CB610D084950C41B746AFD7157613618F6F1574BA51B36F7828AF0AA4F79C0840EA3D679013DF619046E935E0BD96EC59643250A0B38F9779B0142A9E546EB525E72AD204D1EB31A6633BEE89571E8FC16151491EA71234AB83289426559F90C67903A36E4AFAA6F49DA0C5DA5F195B80FBB99C2E8B06926074F3F604B3F6195B5A5B9737876BBA72 +ct = 66290E0ECE573C5EE5C15E6FED6DAC0FEED44F3A2C6FDF910F5816097505979D8822228DF92F10708F9AD6C9AD71F52BF21068B9E7FC986358C5E7D9B822A359976B5C5D8DC2EA584FF47B3CD97BF8DED0318564BD8263FD6E48FA68BE689DAB249B21B7F4DD81C7B5985260689EC56179975E3CA1597A76B35423172DA506967C0017CECA7977BB31A607B6040A7C92AB6F028A6FB641A2CB4496C25630604095EBBD767465CAB5B39AB0CD296E910AD218B8114BA81EB02E19B317AF3CE56856C8C24176125FE51A0ABDE9CBC44CEB3A5F40B24B6AF0AD28C238BB6D24BEE9A584C368F916DE89F7089B80BE3582B0152E5D775195E643DE9B9947AEBA9E2626CA018476087E35299083E937CB7CEF1B4AE0D42ECCF9A65D12959AB715B0361553C124708EB86F91A986BDF98E1338B692E2B2EE1EE862E6956E6B03E6340A6DC7799A0928EAB7F34DF2F39B990D4E5B7E2E6004642A2B97B9E927AD7668A0C7E56AD51E24DA07FE4139B2876A6C9C22CCA399E2C288C6A9A72F2AEA27410CD58B6216BEEC4D0EAC3220B019CC1D9CA094B73B57C487E8852467D0F3EF354F49AEE5971000B7058F69C6D470BA6DCE6DE957004F1835DF92EAF70FD4F0B9B6C83082D24859DB13547C93B3C3C235BE12ADA95897BC6C151B2147579135B69516CACD5D65AB08726698B7BE6FCC8C0631A3BD7FBF0EA06EBB09999A33A9C6183FFBA9789318A8CCAF16DF3078AFB5CC2C2767D32ECC24A562290F9C1C803F8DA15547E59C38C10673894407930D1F6062D805CAA53DDFB271FF4D7E70DDB921261549478C97E0FE218C319377C9266C518675C53D68E7D2A8705F88A6DB7159D7E4B79BB134098539AD9746B080BBCBC89F7B95B664F3BBE078C24C4BDF833FFA4BF22261D48C4E23B08E330EB523C5E62C15713C07A52183E6D4B539FF789216D39C8C6D5CAFC1C956AEC2931AB89D852AE9C89C74DE09E4052D5955A1CABD0995E1CA0779699BF12511D822CC06CD8B6C225E2B4C8ADEE2F56F0DF582674361FC457117780D60E5A33EB00B609239AD032904A85031A1A9F493904DDFEC5DF8F7B660893650D40C103F9912FE2AF880A7C29817B5BB59A3C5378558152461936A0EFF233B3896DCDED4EB0ACB36246B0B474996C147F7DC2150C5AEEEE1D36C96D0BBA1085A0554E7A4FFC2D7BAFCE6D5353A38C312FBEEADC5D41281ADE8198062A49AAC73FB69E0F657F536418B71A16F04C33C6348025BB2CA8D2544413C6D371B3C7A87C1D8ABC6A1B4DC32C39FBEEDE611AF4F651B536E82468736AF4EC3AE521AAB2FBBE823E76A4A3CCF8853E310E644999528A8D0F4CD434A5B1559367B87FE108FABF95905D98BAE6046F29D3C7EEC102B93072EF8003F2AF04522A5C03FD0B60CCDF3AA7069BD1C6D4E05C964305F6B7065905FF650411B017634D3C0D843F0C1266E7FE6D2F4FE86851F9158936C7038BCB584B1D73F4457EE50D4C491E86BEB7F03815F86484A3A8C106C45B1F665B2ED341789D10E53070B +ss = 462F8AE0143A9173E7FB5A0B476ADAC03F2600FFF5779CC1DF9DCAD9B1E7AB84 + +count = 27 +seed = 54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5 +generateEntropy = ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +encapEntropyPreHash = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +pk = ACE2AF54375D684A6CB1FB38BD9C803A158483F91175263779E75B6D42734DC72FA02BC3B09630A0F79E2F95CB067C7DABF42F409A9635D55106E91E32341AAA4808DF6528C3BA98886184E0195E3CA09D9CC525980CB5A2E9027C6A88E9042BF77653B9DC02AD3CBB04F594BAE08DA4683DFC960708D85E39A28AD6E6A7DC81A2F0F8167633901298628B695CC1868756A97D80B1AFEBB71EBA5969A1086DE4D611F737AF56A83C7378C6E5E04E79A8967514CC668BC8FB7C7A1A671E29D55068E34D883A8320438AE7A44F01DB1D4DD07304081D684796A9257154381EC44562A8D005F3DC4C94D5CE9E36705132ACC8876142194DA54934095C2D5725A10E376432B17BF7D1B085D342CB3C633A085E950248CCC9C7FF350EFC341D07D0CA06E6BEC943353C479506691F2347A29CCB34AD09C929692ED98640E6B8560529CB17030EBFA4C769FC7707C75D86C234EDD78E7B3010FE86BF71748CC1C5B00023944774200B2163B403B8207093DFC959B6AA09FE6B98F6E83F972A50ABF113E9DA2FB9FA10D0D05789CCAF05C448854249BA8973A19C537DD69D3F39744DA89DEBB58705EC90EA56CDF428087D8333B16B1A9E59794D49A40B513B50867979230243B27F3D784932E1CAADF8B58FE11BBEA62DA4875D004A73FBCC90B566AB998A45099194D449CC60B0562570648AD588B213CB99A01283706878287930A71B68B43F87023D2F49829ABCBDE6A37A941182B78B8CC1B93982C7A24457A9E1683D2BCC97B4259518E0102760100E1C26CDD85022A04A91168486BA3413613DDD6C42CCB563379A08096B287B41A011FC9594D132E33957F2A5BC1DB4C57B4C8D9D3135476095DED35B2FDC09D8F996E332BAF7939EFB1032E529606677BB1144374C41C08807C9C0868B0C32772F18B755D7BC5C5B12F8EB9CA9DAB589185553B74408301062C90B2D68504F0718D42A1989F050F9097889AACDC175CD7E6768D626A8C9AA1B0CD6CBE91B10AF1A3E507575B47B6AC8C2B7C801A81985A81AD4AC04B32D0DD880D43B3D36857738369B7898B231B24CE6E9944526B9EF370354E21E38F6AAEFACBDA63497A85327A2112A5DB95179C5285D805698209F2A1B67A7730405B02B3507B4E4B65298734F5EB1B66BCB68F9369ABC01C7E4545568D432A685A6E038122253987EDC55EFAA3D926413DBDC43F9908DF1925031F45D28712734FBCEC3724653B019F7D5698DA7B0C3C90EECE1A1BE3567A253A143723B9550C8F7333DDAE88208667353A6184853A85A99C0C463189EB5763FE59D678349F536C56D014CD92B56ED2AA6B0518F1221A49FD6588650057FF00AA29B93F182B3437386F1F846D2A3C60CD900559425B2B7A5FF88CFABE24BEDCC825552577B5C12E4856DDCD91B0713526098B5FA555F105A0F1219110347AF9016254951C3CB5C7EBE602564242276399B0048AD8D370B544B1CB9789694C7753EF2CD4AB51513CB33F38BBB10C83C9A1A5FD1489D97476D9BB314849581D688C3DBA01662B539C50B0DB8E889A4654E6AF708A64910FC503CFA0ABC21B8ABC233AB978965059C41D1123A4BB90306AA09263B25BE885F4DB186D0E720E97524464C7F1B57E338A864D6C447ED4E29D88C30BAC7D2D0CDBAC43E9F4176F0078C715ACC +sk = 0BAA531A985251B6B10153C8FCE6938A280E93F9ACE7A56DC7F44FA8BB2F88C09290888DA8134A0FC43CCBB75B50B6A724D6812183ACF876036DC252FC893419280314C7611750875821B2F3AC4F1C20B06365709BC07AD4161C94C41930568996F8CCA58C4A0536CD5668488715593E66621F96C87A2178A36438DD4C390CA0532D30B88DB712CD3C50D30BAA91C98CF0BACF32C60C81468307CA35B47ABFE59174E53467CF7B1D376758F1A5926FE225F0078FF288AE24D23241709E471624285C4FBD35A333088DD643CF6CB0AB6B27C8B679792ECB8BA4C28CD8B09677F0A7EBB692ECA6777922C4ED6C20402533CBB9A3F1E0C10250209EF128A626B763B30B5E49C4C4691E3A13C2C2601B6666ABA1D099987990BD1BB00AB5806390CE8088CAE30A5B20567295ACA7F0191CBDB4795E78BF150C7954F9A49880C218C23E59014620E18F18C536DA0B7807B0C9E11B1E341C2E7E5BA799653FC669C1032AA014CB79769361B01091B5E000CBE100933C6D05714481F491B2355E72638831D0C4F4DAA18C6B4AE6E825E688CB812490FA13B43D306E5BC857FBC18A61923F6B685E5FBB5BE9C1871A9822FF07CAEFF40318482144143CECC5B0C579C84FC949EF359F0B24B20FC0A9F3300A3217A8058469C78B7998744024E275CD1C70A96A75FD86019CA031FEC081DBDB796A56186D9A1DF8C098940527D34A1DF2DB50B5136B6737829F0CB1DA3B131AB238207A011F02BCD346A0A7138EBE3CA2D78646D7F98D5A886A24B83F8FE84AE81627011A2633F1C159C3870F7C69126B3C31F50D356888F9077FC207168CB075E0940FB7A0BECC556DE78089ED512A39A6ADCDA9C3C5126D874B50C163BA7B091656E52F9813CB318C87ABAB12A3F8996A4CB446D0793055CA177A1BF455CB956443E56C160F4788CDC6B008C086403BC910332D3E3274F9825E9964484D7A52C91C275E153A496801C0E6C8084B25B53C8EBA77A9412291DF78BD39895DFED82FD3C92947A1BEAB598D33DA8344C88A9E073E28549FC939CF5C6978B6F74CCB23675616899FB69C5ECA0C6B68090A338EAB57A222FBB5A482837C097BD40141659A2A71D81E3BD38D60D0A903592B768B0CE60A7044350A75FB02F19482138603A9D8CB89BA6A32D37A15549548AACE4636047D66CA4DE6CF7643C2A5939478A39873820578150172F965D4DC6CC6D7ADFC360568A53C97D268900B7B20122E50CC5E460304927333BEB7BF73446064D76C3AF1274B503203804774B00F02534772CCB83CAA8475651460B156A7238DA2A9847D445F55687A84BAA06DD69D4A637EFCC1C09F81BB97B541FD77A96883869731AC776913ED6C02EF03183B27B4655639509B1E8BBA74837375628152814448F270B6DD865C888180AA071A2AB42740E93F05B32A9C85A069420BE2ECC5335738F9D46C90C5AF1625779F3A329DD693706618AFB300B5C7099C220126C8398FBB8F32A2A35888BCAA187950365F022585C2E08243F53122B6C5EE9A95B84151AFD10B2110135C2A940BB8370565BCD8739609C44F4AAA7C5C266C6EF7CAB87B351236702E327B3E53555E24ABB670CA6E505DF0E0AECF7513F7E36374988DACE2AF54375D684A6CB1FB38BD9C803A158483F91175263779E75B6D42734DC72FA02BC3B09630A0F79E2F95CB067C7DABF42F409A9635D55106E91E32341AAA4808DF6528C3BA98886184E0195E3CA09D9CC525980CB5A2E9027C6A88E9042BF77653B9DC02AD3CBB04F594BAE08DA4683DFC960708D85E39A28AD6E6A7DC81A2F0F8167633901298628B695CC1868756A97D80B1AFEBB71EBA5969A1086DE4D611F737AF56A83C7378C6E5E04E79A8967514CC668BC8FB7C7A1A671E29D55068E34D883A8320438AE7A44F01DB1D4DD07304081D684796A9257154381EC44562A8D005F3DC4C94D5CE9E36705132ACC8876142194DA54934095C2D5725A10E376432B17BF7D1B085D342CB3C633A085E950248CCC9C7FF350EFC341D07D0CA06E6BEC943353C479506691F2347A29CCB34AD09C929692ED98640E6B8560529CB17030EBFA4C769FC7707C75D86C234EDD78E7B3010FE86BF71748CC1C5B00023944774200B2163B403B8207093DFC959B6AA09FE6B98F6E83F972A50ABF113E9DA2FB9FA10D0D05789CCAF05C448854249BA8973A19C537DD69D3F39744DA89DEBB58705EC90EA56CDF428087D8333B16B1A9E59794D49A40B513B50867979230243B27F3D784932E1CAADF8B58FE11BBEA62DA4875D004A73FBCC90B566AB998A45099194D449CC60B0562570648AD588B213CB99A01283706878287930A71B68B43F87023D2F49829ABCBDE6A37A941182B78B8CC1B93982C7A24457A9E1683D2BCC97B4259518E0102760100E1C26CDD85022A04A91168486BA3413613DDD6C42CCB563379A08096B287B41A011FC9594D132E33957F2A5BC1DB4C57B4C8D9D3135476095DED35B2FDC09D8F996E332BAF7939EFB1032E529606677BB1144374C41C08807C9C0868B0C32772F18B755D7BC5C5B12F8EB9CA9DAB589185553B74408301062C90B2D68504F0718D42A1989F050F9097889AACDC175CD7E6768D626A8C9AA1B0CD6CBE91B10AF1A3E507575B47B6AC8C2B7C801A81985A81AD4AC04B32D0DD880D43B3D36857738369B7898B231B24CE6E9944526B9EF370354E21E38F6AAEFACBDA63497A85327A2112A5DB95179C5285D805698209F2A1B67A7730405B02B3507B4E4B65298734F5EB1B66BCB68F9369ABC01C7E4545568D432A685A6E038122253987EDC55EFAA3D926413DBDC43F9908DF1925031F45D28712734FBCEC3724653B019F7D5698DA7B0C3C90EECE1A1BE3567A253A143723B9550C8F7333DDAE88208667353A6184853A85A99C0C463189EB5763FE59D678349F536C56D014CD92B56ED2AA6B0518F1221A49FD6588650057FF00AA29B93F182B3437386F1F846D2A3C60CD900559425B2B7A5FF88CFABE24BEDCC825552577B5C12E4856DDCD91B0713526098B5FA555F105A0F1219110347AF9016254951C3CB5C7EBE602564242276399B0048AD8D370B544B1CB9789694C7753EF2CD4AB51513CB33F38BBB10C83C9A1A5FD1489D97476D9BB314849581D688C3DBA01662B539C50B0DB8E889A4654E6AF708A64910FC503CFA0ABC21B8ABC233AB978965059C41D1123A4BB90306AA09263B25BE885F4DB186D0E720E97524464C7F1B57E338A864D6C447ED4E29D88C30BAC7D2D0CDBAC43E9F4176F0078C715ACC3217D034B472A846CD317681C0F36FEEA187BD40E546DC4AD69C2E67FD9D830371600A8982C350DF524CDE514431DED7AEC23576530894BCBF0EC0BFEF0BB64F +ct = 7613DDA749B9B371C3430BA4A29B0E4BE5CA55287B1A1D0C760939DA3C998C7D88B2C8FD7D43F1F2C5B573EF16B48D339738D0D3AA0CE094D5F1077E23EDA6E6E8189C6CA76A7517FFED4C3C59184E8D96E74C0B284E8D21076426FDCE05C3A4115CD8ADFC0EC21EB5B86059D415D515287E44EE2E733EC27D6AB5945DBCA92B9BA4339DEE417428ABFE9F113D5E13C602AB11AE380E54421C4F713F0AF28C9C97B430A3B6DD7113EF98A93752F5F7FE4C763D3D7EAA53C8DEC6A796A37D97CFF28ADD820D317AC023DD3202C072303D5F172492AEEEF6B1486399E45167D8CFCB35011BFA166DAC078F10B49A776F9A00A227531E4B1390E3C9EBFA49C1C80046A093CCE478E1C91F0AABEA97BC0042330B26D01BA19C07355FF5612BCE097E351D891184725F2D1F95B544E615020DAC8691365149E5AED1E387B68B0E7914BF8E3E94267C5E1E525D8994221401A4048ACA3AB586B352FCAC09D41609012683B748661B5F60FF64C95F410D4163B07225E9D429A22B3DE3A8E391352331216C3D229DFCCA782F832DC7D0A830ACA4B9B1ED37AF42E6D9746286AB161A719F02B4A241CC65156E5A05359AEA4FEB750DB28B6799523CD42D70A1F84EFBD98D5F02229A97071D9105948C372AA52E9F132DD96D4AD3391599D155DEC585DC0C423B4175F5DB53BCC6DFBE384CE6705416C64F8D60A8704822E20AA05BF226C512B0AAD25D5D038E1D33FEB4376364CBAA41116D9B79D061DD61F8EC03E6D731574C83BB05EEA5AB730E51C31F7CAC2FD4F675824031AB5ECFD784AC57871092FC3CAD566E460856F77308424C7418FB6F9C4E9F3EAA8F3F2A5AB544C18579DEBB41B02347294E6816A873171F8C2A6E4C529205B98C1D77638FE2DB105CBCED66817051DAA83E89ABFBA25DDFD1D10620C94245645265A1094B8BBD75851925448629673BBC222B93A2DBAEF4B58A370204752CD993F3A10D6CF379A17DEC1A909DB1AD047F84BB50B244D15742543F097CA97E2597E2EF03DA5E50F054B8B439059EF9E82852A6E9A22C6DC6782333F858CD4D6B07C3BFA8ACAB2271E32D13297235934F4272969F5CFFC744CAB9BA3584AE869B52E97FDA0D77C11D255046CEC3D57E2408EB5AAEFE91E541C03247E28E96905997372D9ED7A31378351A4433F1624CE6A1AE1CA2A7B27DC2F41E126B776C3B72DB38CE2D7C1AB8E3CE8E7006D0E98EE2B9F3CFEB5697F302E5AA5B59064FB5CC2BA5C688B7056ADC0D204578EE44DFE1D113310BDB08CB49051363D8BFE16F2F782FB3BB992E3815E84F3EB3268A21A356178D09F4770AD6BB62CC8F82A29BD18A854F05E2F3135AD8BB60B752A8460DC53C869D4695E44B6BFEE3AF8920113DA5BA5747EB35BE4D5DF27DB9A77C6181143F0831410B50A487F918BA58A30FDE87ACAA561E662D31AEAE4672894E7EF8382027FDBF019893503209352FB63446C8E851AFC0DC22D62DBEEE29F43BC40E49B66DA3AE7D1E2ED93E760BC94BBA7FD1F47CF4D41C9E7A3C7AB2 +ss = BAD63432A274BEC85E9C361191A3431D6F211F1FCC69173B9FB00C0517AC3B3C + +count = 28 +seed = CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387 +generateEntropy = 2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +encapEntropyPreHash = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +pk = A9C823EFC5C946DAB44B5B2068D61F00E7B0D87CA67706343927BFE4C12D20D69C4A5BA892F97EEEAB7B5A45742CC4AC4D37219AD72AC312051D31B8385CA2293415A13BB8983B8457B8AF9DCCA9E6322094CA68399AB77DBB9F6AA7CED5F224641C3FA07507DA9A08E0D180D52585DFB3B2FC95CDC733A573A888D403CBBB71C120BAAE2A195278370BF33299B9B2684ACCC5288A3CBA1277FD3999839A6ED29BB91D71A528BB2E4F953778BA23341CBA4B9B3C17F9A8366212AF3B722397419E24874B163470B3B2B7F24AE62258983B6161C6773B5AC90969C03D01CF4669B9D1F46E05705D4F676D464264D7549E1E2C3290C9B2BF5A71132057531714BEDBC7A91BC0AD56254D298908D33D588951333B3CB7924ABF14B0D70652C45AA62CC3062D851E45C866C6200DF4E74A9E559B9E6AB738F2B0DA9693CCEC3D968A866F0220CA95B7C6E8B04EC41D39C17EAFAB77444AAD4CA3A9D6B5B5D4611A6C074FDFB01F7DF68AD2440EFC5588F3B4A5C4106EFA3B9B6BB35C327465C7B656D1C1C6409993FD91CC20172E53190DAD63CE02691AC326904CBB6424C906BD091312C1BFE6969BA6AABEF954B5C8D439DA5064A248C92988961FD2254479946DEC829C76CBA61690E3C541648228B59805D7FB2ADB6AABA70718985279452A2FB1414E4704AC3DC84D3EB767101C8F4FEB24BC8148316609BF963AFA826A9B87638424052067CE8FB393D9AC579AB1080D1C549FD5103312A1FF9988DFE7805ED906FE9228E25942D49484A4510E0FF9A4A54A22CBA6BE945126EBE461C5940A74E1517C60603B2651E8371973DA7051EB7197713F5583BA51B92A9EB3179B45A8A8A5099B40C29F59146F25A563291364F236038C79B784BF09524FC6810F91B777BAE252E5B723E8059C06157653E335549784A15553FF9A7A29407D87725AA6B7A2A2669CC776BB810672967CB5B8B9A9BA751A9E69A8DDF796B1F324348712FF0C23F49A1DEBF210C027995B8A7CC5B288C4C74218E5086112237128CC57F4BFEDDC21ED23BAD00C58D835B5A3F0C8FDF1001E0AB26C2CAD47D5CAF2252CAFD3520E36AE21119E56FB456F277132059CA18623BFD994878C794545BA4A04436D804231F430B12808FB01647FA15D94B975BB6798AB7C3F6355B9BD50BC1CA00EE76342C8609BE0BC893DEB398B65A453BA08BEF83B805B61945229D98422F59C27E86022DA5620D737867828540C20B097076BC6C03E5435AEE1B9AF19958A7DFB921DA414280429DA389EEFE23FC9578B714B4F2E5B19B792903FF45ACA045BEC0B3D83C204747A2E24971B440C10119941D9316F45A87C4AB2AC0F7C4BDE9BC8EF73A7F42513BE3420C56720DDB984CB173587462AED9996D2A848D11344EAC02351E6C5A18CC7AE813BFDC50D5B143F4D07AC72A213A0577F9802043A585D95031D017B319358A24B06B7C2EA19F22B6634146CC0A123A8051C51E6AD6A956B1A935FFE00BC65C44A60534D1375570BC036EDFBCE66255F523BB377B2256C29B870DA2C870868299828F6FBBD8E0A109386B8D743A6E7A38384D5933E64565A037B9F520ECF8466F2073EEAF03D1B606F947CA2D2CA49E4B41DE9011FFBD23920C0D2D0CB20E3A9C63BFF3E047504A8965639E8FD0DB690FFA1E791FD +sk = E0C2121F06048FBC565FDAA305202D439AB3A81B31FA257AA6F4273547C1465610AE51C2C1C8603AA36D1575754A86C9194B1CC6A9B8C9F77CE6484C5198A193EA4369293798943F7918142F849C8D7479EB0588E6E6B4ABC4CE81A406642414EB4137C2DA905CE4AD2B750E7D966D34A3B1BFA8CA5C8070456B1F6D5B71E582C9E1E2BF9DC37AB60A09E797A43F66B27B04C13C034FA6F594264C9D7DA884C762B159D775F7750A1862216E8BC992C9B2E0D18513F409DF8B0811EA89D2A69B66D34E59BC93F5C7BDE25140A976A3195541EE22A7EDFB7F9D647616B31399B6C924022F036225AF7C34E6D221213AB5F7A20B908325835266DA1B456F5649B895BB032142FC5C700CFAC4C2A44CF1F96D57B8BA1EF2C9332A612E8BB9043559B5567090873D3F9450F37670B473A96F812CE1D71892E43C9FE61FA594601A27A98EC817DD822C625B98E0FA8F2D5A311A87A6C23B4DFDF44D7511373E64A4A18A833D654A946B0DA9694329023086013A919971CC4C8A45916901B45C25C28EB6051600644660796935E65A4700496BC32204201D5C8708FDECCBFE949D1339947C6BAABCC67EC901659D220FA4D1A3DA1A4ADC2B1B323BC4CABB6065D9032CCCA3DD3C8689C9A35810BCB30B99B3F55CF2AC8258C5B85C696A372C7AAB5B0DD62ABA06804466FA4C22B2CA0E09B7D47C4644898AACF6899C79B5321110F010CD40253E40C5920DB980A57C01B55C506A6662BE1253FF171412820272613940704F63E70340414322B69B60B50BBB4459C1D6A0F25065DA032455598EDF678505F54B51713209565FC4812AD5F8A05A926340FC3853719146D049017475A09A1FD2D47B35371D715C455DEBB3A40A8A0E83247B6B8FFC05B2E857B5D8B201E56C109DC155B720B2528301C49237F7A629234231FBA25C75D600BD360796A68991BC68CAFB5B0B7C748AB7039D8C4FD1B3B4DE76C193123E50109BA70956B9556F245CCD4330B888D43A84714E8CF17E5713B5AE5A9FC3A331718C227EF4BDCE131F31028D68529F06A218AC32317E9B7634C572513974DA2BC3DDC4C07F2C6B8D3AAF5734B5D9E691D790B0FA67CBCF36C0372C056C268E0C243132DB5DE7365310F5732151B80BC98A2BB76F9E8C616FB1C90A5B83CA5738BFA9CF1FB96242998A44D667A57B517A834834AC0F2AC00E91B32E4E7AAB452249D31575BC96C8652CA8E4C3C0D3277A60F5CA7BEB80B563391A3B8E1A1A97C85823928877954C28D052A2C116BDC325B687D26D1CCB3386CAC9BD4C10C3AC381E056F9060C89E25A910C78E677964D153B74554C8F38939F881543F820B6F11989589302EAC53111A45F7664616999D7A64AA26E4CD74539DD496A1F0FC530415B16FAA4AC86341C5400CB1BBCFFD2707BE12C31ACC9B5C94B806B71DAFAB1EAAA087EFC1419CD2978EC1B973336D27B69AF2FA85F6C33B73770C0F6B85D855938ED8758E6AA5724B8C0D457B29A9394A3528DE99CBD7A875BB5B299C8A6DFE416104A59AA9E958E3828D3C651B5A9A7E81D7738374692033C4C68254D5170204F83A9B8520016466FD9189EFBACAA23AB8F962AF7D66AEC2E27E468B9C326711673839541262A9C823EFC5C946DAB44B5B2068D61F00E7B0D87CA67706343927BFE4C12D20D69C4A5BA892F97EEEAB7B5A45742CC4AC4D37219AD72AC312051D31B8385CA2293415A13BB8983B8457B8AF9DCCA9E6322094CA68399AB77DBB9F6AA7CED5F224641C3FA07507DA9A08E0D180D52585DFB3B2FC95CDC733A573A888D403CBBB71C120BAAE2A195278370BF33299B9B2684ACCC5288A3CBA1277FD3999839A6ED29BB91D71A528BB2E4F953778BA23341CBA4B9B3C17F9A8366212AF3B722397419E24874B163470B3B2B7F24AE62258983B6161C6773B5AC90969C03D01CF4669B9D1F46E05705D4F676D464264D7549E1E2C3290C9B2BF5A71132057531714BEDBC7A91BC0AD56254D298908D33D588951333B3CB7924ABF14B0D70652C45AA62CC3062D851E45C866C6200DF4E74A9E559B9E6AB738F2B0DA9693CCEC3D968A866F0220CA95B7C6E8B04EC41D39C17EAFAB77444AAD4CA3A9D6B5B5D4611A6C074FDFB01F7DF68AD2440EFC5588F3B4A5C4106EFA3B9B6BB35C327465C7B656D1C1C6409993FD91CC20172E53190DAD63CE02691AC326904CBB6424C906BD091312C1BFE6969BA6AABEF954B5C8D439DA5064A248C92988961FD2254479946DEC829C76CBA61690E3C541648228B59805D7FB2ADB6AABA70718985279452A2FB1414E4704AC3DC84D3EB767101C8F4FEB24BC8148316609BF963AFA826A9B87638424052067CE8FB393D9AC579AB1080D1C549FD5103312A1FF9988DFE7805ED906FE9228E25942D49484A4510E0FF9A4A54A22CBA6BE945126EBE461C5940A74E1517C60603B2651E8371973DA7051EB7197713F5583BA51B92A9EB3179B45A8A8A5099B40C29F59146F25A563291364F236038C79B784BF09524FC6810F91B777BAE252E5B723E8059C06157653E335549784A15553FF9A7A29407D87725AA6B7A2A2669CC776BB810672967CB5B8B9A9BA751A9E69A8DDF796B1F324348712FF0C23F49A1DEBF210C027995B8A7CC5B288C4C74218E5086112237128CC57F4BFEDDC21ED23BAD00C58D835B5A3F0C8FDF1001E0AB26C2CAD47D5CAF2252CAFD3520E36AE21119E56FB456F277132059CA18623BFD994878C794545BA4A04436D804231F430B12808FB01647FA15D94B975BB6798AB7C3F6355B9BD50BC1CA00EE76342C8609BE0BC893DEB398B65A453BA08BEF83B805B61945229D98422F59C27E86022DA5620D737867828540C20B097076BC6C03E5435AEE1B9AF19958A7DFB921DA414280429DA389EEFE23FC9578B714B4F2E5B19B792903FF45ACA045BEC0B3D83C204747A2E24971B440C10119941D9316F45A87C4AB2AC0F7C4BDE9BC8EF73A7F42513BE3420C56720DDB984CB173587462AED9996D2A848D11344EAC02351E6C5A18CC7AE813BFDC50D5B143F4D07AC72A213A0577F9802043A585D95031D017B319358A24B06B7C2EA19F22B6634146CC0A123A8051C51E6AD6A956B1A935FFE00BC65C44A60534D1375570BC036EDFBCE66255F523BB377B2256C29B870DA2C870868299828F6FBBD8E0A109386B8D743A6E7A38384D5933E64565A037B9F520ECF8466F2073EEAF03D1B606F947CA2D2CA49E4B41DE9011FFBD23920C0D2D0CB20E3A9C63BFF3E047504A8965639E8FD0DB690FFA1E791FDD1756ECFAEB695001AC490F36C4638151BEE98D367FB7ADF0E06A470844068AF0E145E44AAE52CFC609E6F47FD7A6F6AF877190FF52256D0AC5B05B89C3F449F +ct = 626889818F1C1732EBE9F4D16EB41D7A7BC195CF1B20D4CE5EF88D7AB66480D993C7C4D9F5538A0B6CD7789EF1483F18727C32165CC2A482D33EDA191877544F8ABD849EFF8F3F7C7032D95B34E8D8D4307FFF26CE4E02F031FE8DAE875A5CED281B114EC35BA6569FAEB5DED0A3B945E4B249154EC199732DD0C86487A3B9CC8F7867C5D10976413D5A78A8C7AC92312E1F47A33BEE8352389776ECE26A02926CC9E7992E40BEC9BCBB4206E498C27999567F421BFBC4471CC7C3C4E34521694C67465B0902910DCCC207056203790DC3D11D42BA445D0C9038B727DB8D7C0649CB7217E362020F3552071D50AA00BB05C1799841DB2D9625A6F9F2E3EEF16D5374BB46F839AB64A1314ACF5780F6E5894AB344A257894A2AB5CEDCEF54A5248040A2093639A63FE91F2FF779767270188DB6FAB919181633EE0E2D0F93EE0D5F9792BC0B73A1E3C40DC04DF30EB2B1752DC1B620E683619A0CB3C3B9620DF3FC2E517EBF7B457E5B4F331A1E5D54C107AFF06909040D1773842B44CCC74923C997F8AB0901542CA97C4C74DE7310B50F091ED8664A6DB07FADFFD1E815C3258753B0BDBF652BA5FA35D128B786804F7C7AA54DCF8A50ACA2B1924A95C8567F597934BEBDB6268EE2D4B95500203E17CE616CBDC69A379B2F26A4948899EEB69852442B2CA1F447E27FB865E64952CA9F80E7CC2A4FC734FFDBEBA2EA5D4D4BE1E36F39991F63AC0664399FFF6FE09F35BBFB6F4C15FF925FCDFB633B9D66BFFDF5EEBDE9BD1A00878E12142C3E49278B3BB6385E421E5DCF42432E5FAC086A270CEA48C475C0F9539DA658A7F4144F3B751666B93975A2E590923ABC30E02C068A3F11999626DC3DD49CFDD5CB076CD683F18880BB2651CAC442C45B4121ACE9E0AD70C3EF99C0E76ECDEA7C038A8E168B31A13D3F54710062B88BA7397DCCF6E433F463B6E9E587EDFDD1AE54EA1773496AC41CD6DF262B79F607396C9A3BC94944E8C5CA41CDEAE9CCC5B27ECD6E3FE10995AC59886B74C2C5E0B9D7C95375327B22FF6B713091E740E3B8DA20C07AAC0115A7706D753A0EC5EAA337054A63E089A0855ECC74061CE44F5D8BBB229F19A5C772C40D362A0EFBFAFFFBB9D71BC0B52AC16DDC02541086A411E45EA131AB12D6D7EBC007374D3C916FEFD01557699E7A713DADB5B4C385CE17FBE90F04844BC9F496520DC3DB1FEE0CD89D3F5C9F71342CAF8688BD0DC6860F581512AD1E7B32CE166C78430A9BB7B83F3FBA095330CA3E5CD0707C436B0A065E5208C448EFAAD85F246695039518CFB88DA79843B95DD1186CA5D71CD4B80ABA89ED704CDC93072632AD6B8075ED8F211F7F193F4A8DD4505F6FB8AFC9FD1F5F6DD086F2DBB314E1FA14DB5D7FBC4706D09688495EAD12EA3C331B4E13589CA3D4BB63499DC54B4893F838C103B01BA7C49FEB8B9202E3D86A06F80C932FD182A1CAD2615B1DF729D00E9F6C3D881A6CB6A837ECC400452C015F8E263BABA09C258B293576F2EAFD79A60D308CC0DCE6B145 +ss = 50CD9D6042E7708F347B3D187430D070F0D8712E0BF68350AB47F4B50F04962E + +count = 29 +seed = 265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222 +generateEntropy = 174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +encapEntropyPreHash = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +pk = E71B4FF986BEE57636F904C856AC93E0C18775864B7B932AF200251B0328F5B3CAA38116C5A187305622B4A152CA337ED7A3690C31161862447B847F5639C5851133F627B5980572023B4ACC37C32F6B70B3555E0EC4C5809C9582407A0E59A866991564CA55B21A48EE530676A435D26B749C1264F9E58C3FC619D1A23EF5F6300E96665EAB70E7350852115F5859BBF1A8308977648AE5CF5A55C9FB42801ACA4F0592254461A632A94A9C3A7CCD05C8B7C3B09666BE54F072CDC58D8CBA687D609D1F021115085C340153CE63A37750ACBDA01A6944A46CD16CAD098464A109BBB611A83346CE6B59A5F4CA3CBB4394DACA06E5708459CC777534EB80A620C308DD779B074C11F31679AE98AE569BBE79CB04BB127208E24BA008BEA28C5DB5EC18F31C50712171E27042651701C3004E057A6865D54763843D27873220C174C57154C9A9705DA162E8685A035B34E15C411FD1B7220C57265C2BA7579F4BD9AB1461650E8027C0BA79F2BA3F14093CAB6015D8CC092905A6B8F09DBFD5743818489ADA2BEDF88CE592396074A79824457F7CAEFE334FC84869FF43641821AD60E80407649EDAA8BDC2FA877ECCACCAAB8A1F35A1573546AC382222C193BDDB31275B84374CB4679A5FFD803EFF07987ED085FBD43E45752DD9A32F5EC03E7B74567ED9674E1070B026801E99CA27EBC0ED24742530507E19B97A09877A1B511DA3B9835268AC35AE44187EA14B996DD96C35686EB98A81F1B2AD90A80D0C989B12813E7DF2B34573B876289E7C79481C7247E637A60F9B2D3FC129C379A759756408636048565CBEB24C2186A875606A43D20BDDD8B9D70781B1848BE54A075FE978A3E112A567223D21BEB3395921D1A100C578E7EA0455949B7B420B6494688AEAC00697AE1914084EAB375D86243B50A948874DC973B7670C8F9173228B64647E58761442A2CC90165B188B58025F8EBA65CC654575A1BB3823A1A29633AAEA1763F24486AACAFD611C28774C98D89B3CE8A696E29F62775B5D5C50847C3AD4BB968C441086AA070097508DA888B5B202E5A3B5DB579943F0861A5B6E2D58415019182262C444FABB77679E019CCED4E0A3854507FCD0935BF81B0E8500DC6C0B3C154ECBA94D166407C5DCC67BFA6AEA8B4EF0C53859BA4416D5C1975C1FEB6BCAD8076E6B020A62B077F0141DEB5AB5986B386D51CB7E8C779654AF5E5485A969467012C572F62DAF788D1F58BF9DDB4BC6E04B00218CB671CE8B2515B072B76CF253A4006AC5437C107A077F162A3984586978CEB3752B1FA1A2B525961F96C63D7207ECC4C0268A354AFB00231B1CB6EB4E4A694524448E7A043C22A5BC1094B23D3C5D0A9641F909A778EB64BAB84FEEC3A53730405C92130F756050771999E469CF07CC8C308ECE9B827D7558BF882630556150A602D9400E3D4ABB229A9D8B8132A7F0C0C5475BB852000B63228C490472B42488AAC0ED647B1E834F248534FE2195ADF6952B83B6705593A1E53F0315613D2596AAD44E27A26D632B9C71E9C9E5A6AB733C7E81E54DB3437D894A19B4710A3CD5075602B176EC369F5116638775574C74425789154B0BDE48BAD6E52C91C451C87B48EC406674A75B0CD39D1173C3F411AD1EFDD8BF4BE2AFEA69C2327BD070CD1432C8D219 +sk = 25933617206AE881C4DE291B4F269F2E51897FF29D3C6803E1A4C58E53051E879F1AF333393C75B366CFE2E84CF9CC930D1928298897480571D7050751601BC119B1071412EFE8873AD325BC00420D13A752D33087BB6F884628DEF98F4FD21D01113219203F93419875C91CD33C7976B7A45F510F70E6002957AC49B862CD35640CE84E6B989201A74EB76422F88B31C94ACFA811605A32634199BE1639A50B709E89683C5CB0C975D627B76223EA48A2352C8BCC254ABC60812A6A5AB7747CA82073D1D31FEF708866A9801AD067A6DA0D848C409861C350DB559A0AB1D91C9BE0C149D6C241A13849D9EB2DA4B9B9B30B348217491449A43EA4544467824FF954C4869C8DC0B2BA2744C8D38BA584CB78EA6F6188BCD090267BA46882F16964AA003E2C60105415F937CF13B9CD00456D3545BC5E48B6DDF61A14ECCBAC23BB1D071BB14361B4C9ACB7B48805B7890C3676B550238391B388260CB0E2567F725B0382C7174440D82BA8A6D226D325CDD1C26ABD510ABB195B73D203F9DB7DB44ABBA87581A3C57F079B44A9455E3FA16EC87A0CC14368569B35517272220BA7760A8A0508BF0033031D42763FE89B611366B8B93D2D523D5C872BB99BBB099515A5911F1182404B7B4CCEA91462C6A5ABC16C64F55AB38A763A03BA48E0268819B6DF8BA88704AB4C7BCD8F8A150CA434AB0632ADC522A49C0E45997375D69901416792F845FCBC1A18789B22870401D6872374B15C851ABA4C3CF5A8930D34C74FD444A2C87F90D9353CD77361E26C99C8027B50504BC5B3F2BC27F3978822113E13D71E19E3915A9A4F0646AEF6D513E155B41237B2AB08BDF38322BF4C00706C0F22854D080BB8ECF58CC9B75D19A0185412A74B3C7D61A04DD8CB07BB37156C46221A7183BEB9321C58A924048AB86032F54815DA1BB33AD4312391C1A6778D9070B1A4542AAE231AAC97BB5E1A1CF42792C9921313C07ABA3A8C15DB5D1BE417C3888A2E0921A7AA1926044AB865935A2738B4378484B44471DA250E41925E976BEECA9F93D191B0C85B487BADFCEC4BE7C7683C508412E096AE888BAFB97CEBD3266EF7397004CC56741F53683034FC3160522E6BDABAD190C51F31926AA94B2F2A4506D69705623E3047176B46169AB8A715B84848BB4FB9830BE744CAD7591DD8D128C1A40F8A5B2829A92177D73CB1F319C0F45557A69AD790C87A6B8314E618444081C221C07C4BA5C1C450B8080DB278770A0C110DC386FB8411D4B983503964F7B6AFA10AC5154CCEA9E6222B4A70E5175F125B0A83010474311F8EF84FDF3AAB6D508B313A93C29675ABE12CDE50BD4B5B7E13C7228D9AC9DF569CC1BBC995EAACBC2290B0293A2BBA70AE8757C5A7CE84386093E02B3201573C56BCC368A7DD404371453C38823BA4752EDB663E5FB99C5E91CA9BA94CAEBC9D60A6318CF62168A86C0C419CAD1BC4FE514A745BB2C81701B89BA371CC1F10B50D95086D99778383108DFED849A1F74696464AA1D67F7F40BBC69C1FD907696D6227CF20750D68A3D36C600448C91A523A16E5C84B40819BBB2BFABB2CB03B658FD0656F410752F52BFC9BBA4A3A8D09D5835B1540F5DC673DF71540F560E71B4FF986BEE57636F904C856AC93E0C18775864B7B932AF200251B0328F5B3CAA38116C5A187305622B4A152CA337ED7A3690C31161862447B847F5639C5851133F627B5980572023B4ACC37C32F6B70B3555E0EC4C5809C9582407A0E59A866991564CA55B21A48EE530676A435D26B749C1264F9E58C3FC619D1A23EF5F6300E96665EAB70E7350852115F5859BBF1A8308977648AE5CF5A55C9FB42801ACA4F0592254461A632A94A9C3A7CCD05C8B7C3B09666BE54F072CDC58D8CBA687D609D1F021115085C340153CE63A37750ACBDA01A6944A46CD16CAD098464A109BBB611A83346CE6B59A5F4CA3CBB4394DACA06E5708459CC777534EB80A620C308DD779B074C11F31679AE98AE569BBE79CB04BB127208E24BA008BEA28C5DB5EC18F31C50712171E27042651701C3004E057A6865D54763843D27873220C174C57154C9A9705DA162E8685A035B34E15C411FD1B7220C57265C2BA7579F4BD9AB1461650E8027C0BA79F2BA3F14093CAB6015D8CC092905A6B8F09DBFD5743818489ADA2BEDF88CE592396074A79824457F7CAEFE334FC84869FF43641821AD60E80407649EDAA8BDC2FA877ECCACCAAB8A1F35A1573546AC382222C193BDDB31275B84374CB4679A5FFD803EFF07987ED085FBD43E45752DD9A32F5EC03E7B74567ED9674E1070B026801E99CA27EBC0ED24742530507E19B97A09877A1B511DA3B9835268AC35AE44187EA14B996DD96C35686EB98A81F1B2AD90A80D0C989B12813E7DF2B34573B876289E7C79481C7247E637A60F9B2D3FC129C379A759756408636048565CBEB24C2186A875606A43D20BDDD8B9D70781B1848BE54A075FE978A3E112A567223D21BEB3395921D1A100C578E7EA0455949B7B420B6494688AEAC00697AE1914084EAB375D86243B50A948874DC973B7670C8F9173228B64647E58761442A2CC90165B188B58025F8EBA65CC654575A1BB3823A1A29633AAEA1763F24486AACAFD611C28774C98D89B3CE8A696E29F62775B5D5C50847C3AD4BB968C441086AA070097508DA888B5B202E5A3B5DB579943F0861A5B6E2D58415019182262C444FABB77679E019CCED4E0A3854507FCD0935BF81B0E8500DC6C0B3C154ECBA94D166407C5DCC67BFA6AEA8B4EF0C53859BA4416D5C1975C1FEB6BCAD8076E6B020A62B077F0141DEB5AB5986B386D51CB7E8C779654AF5E5485A969467012C572F62DAF788D1F58BF9DDB4BC6E04B00218CB671CE8B2515B072B76CF253A4006AC5437C107A077F162A3984586978CEB3752B1FA1A2B525961F96C63D7207ECC4C0268A354AFB00231B1CB6EB4E4A694524448E7A043C22A5BC1094B23D3C5D0A9641F909A778EB64BAB84FEEC3A53730405C92130F756050771999E469CF07CC8C308ECE9B827D7558BF882630556150A602D9400E3D4ABB229A9D8B8132A7F0C0C5475BB852000B63228C490472B42488AAC0ED647B1E834F248534FE2195ADF6952B83B6705593A1E53F0315613D2596AAD44E27A26D632B9C71E9C9E5A6AB733C7E81E54DB3437D894A19B4710A3CD5075602B176EC369F5116638775574C74425789154B0BDE48BAD6E52C91C451C87B48EC406674A75B0CD39D1173C3F411AD1EFDD8BF4BE2AFEA69C2327BD070CD1432C8D2191B1B0A8682CAF72DF2E0A48513A7358EDBC77A615D6BE6FE2A7145BE66B7C50950A7A2354F7E5CEFA6F4A4E9A1C411EB9364506E9E1204A8ACB3CB77FBD2C4ED +ct = 589B45383FD87E438A2036E96032F3FF220B23EB53244CA47E77379D46C333F3BED4F24D0582E9949DDB32AF9EDA732E6DC529FA9250D635E160316F7585A473BD3B59B0084122EC07E73CA921080AD90729565C5297B624315ABCFC027253642C6972EC426833EFA33FED5399F768B422259857F40D0A11C3C2CFA2920DE96CE3DB945DB087C39F0D97C041457C21B0E9FEF68927ADBF34195CF17871515357CE6B72BEC5D3D77D10E1D1A3CE3740600841B3E58CAF96C4C3F86E60502B8618FC918118E14699060E5E87851990EA933B0E60A7F750FE7947F449442C24F5FDA9E39B68BB51EF9AFE2D2A786388921A01F5C228783DAE97CB91CAF9C5D21C64098CD3B290C77462131BCF46DA587267354478647083BEE9110A9DCAB4EF3B2AE080E8F991C7B641DD7A0F0DCFA5F133636658853C52BA1F36F23C6EEBDF9FE230819F77B39086313F6A96FEEE877D9855D24A8582BC2D38E05384043FC23800CB0447DC2708AAC562A39889EC6C341F88EFFE499F970E0AC8BD3636EFF3DD5919C679680DF277CAA89829E03BB0D01D0D1BF2904BF8734D45AA1A5483762CF3704B1A756357179473D4D6DDD30FF0D180843C3A9C6CA2E9C8CC7BECCA7BF76663C7F0483207423F30FB219F330073787D8C6928499657B9B17208B0C4A37E5BED81E166B69E708A0388C2ED1EE4892A9B48D0CD1DE52C747ECF25694F2B909D368D5AEC537A0EFBB10F770D2C444BAF1B25AB0C1DB0EBAD0A5BA111443010393B330898B2C4251C9E682B1AD66D4E58B9C898A77AB6AA0D9E60DA99D80188580A7D50DC8EB976F3E1C75FDFB51866D7FAAECE97D56A440C96398E76BECE663FFC53D2B06EE6D11062805F7AABAAEB65568BCC6510E26DBF3C8C66C7BDB2E70264AD2B68D6D066304C15D2228ACCECC8CC0ED3FB8DE863F56930DE5DC94D80CEFA1EF24C0746FD78A5FEE6FFEB6FD1DF1E20A0F21875CD22081B12C68B73E7BE9FE7125D503D0BA57F8F4D210FA0E39668509E841F8664D52C65413E8FDD715BF34C852988C9E1857977A503A6FD5ED158BE6371CB29E4A2A13DE00006062C56F160704E1AF1B79E0EC175E11FF0F705291BAA1825FFBFFF4384D2003B726D794EFA99B8E9061C0D20381A892A67ED2B0155ED494D8FFDAD329E9B4B610FCF34183DF518C681F8CA2D7E36561C9A7271B9DD4A18A71949F9991EE0F6F43F5DD5D44DBE793FC512F13B7463BEA6682CEC42713A725E1E71F06550435963C9AE8D7D908DD9B5F99555E4A668CC9355FC2D931E1B68001A6B3E20B4594304DABFDFE9BE0EA26F92627820A849B6A1E2C68F97EAE111EE4786F1908F268A56053C739E44F7DF80EF8A85B86ED0CEEFD7B0FCA38A91DCB1CEFCCD1034097A0FAE6127A0C47F1FFD2D044F808BE041B5968291FE4BA63444CAF4DA65B7182C654F1DD45771B464302D9B0EE14FF0AD361DB76FCE8C808049C884DEAAD6D4EC8A201B99BF31CD1DC9A8C1716EFC01ACABD5965FA97371274E385DBD75E47D5A61A9E56E +ss = 2E610015C6B440280D6F28D5E3CED35CBF65A70A171151363C4CC882D7899E0E + +count = 30 +seed = 806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA +generateEntropy = 351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +encapEntropyPreHash = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +pk = 8518C8D8DBAB01F270C3131AC1586BB783B35DB82F3C24AE2B767E2C4A7D15C2A86EB19FDFC41113A7501367CD70D73D0F63705487AC4E0BB1C84001FE6657610C7D64FA3DF4538BB6069128C4597EC9B291938EA5D7CD46897AC2179B52F1CAC91B6C36F37A59780E454C50C5DC354B56A43040804DE2394BEA14C2D385E082C5F181228D62307F5A6A1AAA1EABB84F90F34310844DF95A4E6D423D8C993FA7F390E6984E482024C2968254B54B7D3418D6F859E295665262246E1BC8CD6C9B726581CEE69140F85C02024C5B59AA0711813D66433AA384B2A4A3447939378A1E6A98936BF04AD075981D93C53E9635B5E285F96755F8689B5CE5429142AF6FA02EDEB1A719B272F6B0A6211A5B9807CE6FF368739B51D4D9480BD884C8B456569027B08A3CB928645D450C6264C5FCE2A2DE2B241F965034A08716649A3C71020A6986FBC8BFB5B4A2CB162749264CC1E44BD66223F3DB1B9BD2C68744B52ED7BBA0B9773DF128883110D2CC4757DACAF7F4C90FE02884E1A581D89AF687AC79444C9D801D156325590A3A24441B7C2C893B777386198C16374329E640B6A439FE5BC71AB3AE195575A71CBAB773AE6F0B5AB2D750D222A5D36B86EA2AA2006C54940A5F843AB708D19D5937643309C12D522DD479C3B2D57DD5696D25615ABBB573FDB62EEE5C6A6546CB1FB188F356800FF4177C69B636CBBF9EE9A7C7D512CA156490C96B347A5BC2CB257A061452DAB5FD15BDF5026677F14967B6C825D03EB782CD0422BD1078B7781624DC318A33B0C437D6C35997A22E30496E876762BA5DCF5146C5188DDE6C684C265A8F05031904572F7554123832C78767FF4B5FF525680C773AB3BA1A93776897D57B0D507B9391712344326F090B3D964DF8C293B6638FA36815C7CB9B7962956F903F62C4CE3D7646EBC1A8EC04A815191CB4BB085EC8693F2188F490731C087C23A8BC7CFB32FC019D106934B2D17706526CC6F787BE424BCE5B26329591C47402D57548110CCB42955C422323ADDB4987FB0F3441558964BF14021A54277BA14C5773A10B81C1427F51173F5C6CBE1B7575A4B6766AC355BC443E479A2953A51F7010F7B04B23E0CA93D08836432E3AE5A1A6BB62F5476C07914F88532CECD00CEB340588AB675F93C286E7288DA1C6CA3621AD6A4AE1FC64AA15B27A7C3EABC120E7460737585B5773AB18E23EE185C900ECC3B765983CB807E2F7047E6C999C6716E26801EA938302ABC312AA797535358196B63309846675BCF1B33343BC3D4D172DB81947643A84FD2173FCB0477AB87B57B55899A308D51311C9BA6916F15947D707D88B9228D0488DDACCB25455CF782B7A18264E55C9B6798F39A53F53240C82FBAF461364CD5202C5C94CDFF23E0F731624E69310E5B47964B2BFD3A59A5B0D55A026E260731DE346F74938ABC607B4F579B8B200ECEBB633614A46983E60E442A4914C93FA62219025E4A99D71032F0B00906126365C467E0A235570A544A7640F23800CD5F2A825479A632343F20801F1774F0E8B7DB96A860FD40A43CB7ABAE76039C6BC80B94EC315AD49E9904908A20CB444BFE219452C464EEB2914EC19031152CACAA00DD541FDE81ECAF1F339E468BE45459E708BFB464D0C480A1BECDBC021A06AF7AAC4772545EB +sk = 719950ED1960FF6C2D7D59BBECB83AABE1CCB569B76CD9B053389C552CB6BF847CF4FC1F18A03E66F02CDB284C15D656151644F78CAEEAFA8B12CB7C616256C032CE6112735A74285D66A90F3A745ED8733C195F6B1B9B272897520A02FAFCB958A9669990B73420BCCE373ACF5A1C86A555C3C48F78166C0FBB023C49608592261060884B408C9FDB1F4B023506D3516956B02637AF26FC7B1D9345F8B54B5AF96997D39FA32C01AB64A6AB7491D50303B4E8A134086110D220462395B9D89D9651205AEA9E1B88BC80C4C8BAC44AF4F1886EA788A0B259DDA78116051059853D2CD073ED8CADAD9AB04F7175D57C3224E953509588E788713D5A6714D0AA48E972F4FA55F16579D9BC6988F562CCF1286E87AA785929BF8266D7E340022C0221736C3CB372B85723042382092545A45032EB727BDC750449C786145ACF42B85D4618B0D6F009D0224A816620F1DB67F59713090B0849559A51B9589532CE2DC25DF8F09AEBDA932073A2AC2115B12C5F94C64750220D645B34C14AC1B2208565377D61426D7F2A25CBD969A2705EA330B676EA6EEFCBBC6CD40DA9C0716D147B398B7D469A919D83BAACCA80F0E41414382804B0A321362E14E766DB2450F599963CC2899E1048D839754858910D12C23F99158A9A3149362690A9C5540133E5F217A7B66B0D627321C810F7D1639CCA948D708616047F85BA41CEE9211DF72731AC0986D1C3149854B71683FAF68179799B12C031A2A84574B9A67C96A708355F7A86BFABE63DDB94B6C048359481CA7A45CBAECBCF34407D8E378733F812926599DF5C156A94945FC7911DB26BEF17074470A7BD6B60F771CC3F396E847195CE26444B641F91B468FA1670D0184942472667AA76E42976FAC48E78DA72EF0C207FC7400F92699B46345E4C9972A35DAEA31ADBE87980438DE4F211B005C8DCEC1A6EECB56D891677F9006C49385E8AB20A19B74325A9A95083BC711537480DB30719815352616B2C5721979BD4267FB134188A75B9CB303215A76A246D8F69ACBD173D069B2B99B727829AA5469A0212C006A88AA4A6B614674674FA75500AA294711C178B741B0275280BDA27813647A5DCAC3A258991DB4BF436C23F37C697115143A2755FDC199FF32B19209D7FF904FEAABFF7383884C1BAE3C0CC20D019066653B99C1CAFE366567C9238785B0F0B4D1432A9E02CA2D9A3B37D84646B157684D7AC720727AF4533749A9FF99BAD8F3877DBE5CFF9C75B38C4002178CE30773EE36A14F1497AB386CB36420F04D85C8312CE25B357D3108226925F6B85C7A3729064F81AA66336163C00506BBFC82030F4F33A5BE7330926BB3F849D1DCB09F5CB814BA8A722506D0A037E6EB26216AA3C4D4C05D5CBCF0358501936AD2BEB3563C341E2315DE6D68404ACAB0149BAFA84491AB67A2DD82972220B0DF528DA7C4D441C8CDAF508CFA2C0224932E7E5215572AA433C9212022899E43A93CC7C8F4AAC6ED5ACBD0162E4DA4B897B7BDCD72A0B2A2354F61A6C211089C11E476715F3369859C3021584B6593B5784344D53B40DA0725A90804C45D02F6EB7670071660478C53281B5E290BFC77AC46602B530B1300628A7A4F20CE227688518C8D8DBAB01F270C3131AC1586BB783B35DB82F3C24AE2B767E2C4A7D15C2A86EB19FDFC41113A7501367CD70D73D0F63705487AC4E0BB1C84001FE6657610C7D64FA3DF4538BB6069128C4597EC9B291938EA5D7CD46897AC2179B52F1CAC91B6C36F37A59780E454C50C5DC354B56A43040804DE2394BEA14C2D385E082C5F181228D62307F5A6A1AAA1EABB84F90F34310844DF95A4E6D423D8C993FA7F390E6984E482024C2968254B54B7D3418D6F859E295665262246E1BC8CD6C9B726581CEE69140F85C02024C5B59AA0711813D66433AA384B2A4A3447939378A1E6A98936BF04AD075981D93C53E9635B5E285F96755F8689B5CE5429142AF6FA02EDEB1A719B272F6B0A6211A5B9807CE6FF368739B51D4D9480BD884C8B456569027B08A3CB928645D450C6264C5FCE2A2DE2B241F965034A08716649A3C71020A6986FBC8BFB5B4A2CB162749264CC1E44BD66223F3DB1B9BD2C68744B52ED7BBA0B9773DF128883110D2CC4757DACAF7F4C90FE02884E1A581D89AF687AC79444C9D801D156325590A3A24441B7C2C893B777386198C16374329E640B6A439FE5BC71AB3AE195575A71CBAB773AE6F0B5AB2D750D222A5D36B86EA2AA2006C54940A5F843AB708D19D5937643309C12D522DD479C3B2D57DD5696D25615ABBB573FDB62EEE5C6A6546CB1FB188F356800FF4177C69B636CBBF9EE9A7C7D512CA156490C96B347A5BC2CB257A061452DAB5FD15BDF5026677F14967B6C825D03EB782CD0422BD1078B7781624DC318A33B0C437D6C35997A22E30496E876762BA5DCF5146C5188DDE6C684C265A8F05031904572F7554123832C78767FF4B5FF525680C773AB3BA1A93776897D57B0D507B9391712344326F090B3D964DF8C293B6638FA36815C7CB9B7962956F903F62C4CE3D7646EBC1A8EC04A815191CB4BB085EC8693F2188F490731C087C23A8BC7CFB32FC019D106934B2D17706526CC6F787BE424BCE5B26329591C47402D57548110CCB42955C422323ADDB4987FB0F3441558964BF14021A54277BA14C5773A10B81C1427F51173F5C6CBE1B7575A4B6766AC355BC443E479A2953A51F7010F7B04B23E0CA93D08836432E3AE5A1A6BB62F5476C07914F88532CECD00CEB340588AB675F93C286E7288DA1C6CA3621AD6A4AE1FC64AA15B27A7C3EABC120E7460737585B5773AB18E23EE185C900ECC3B765983CB807E2F7047E6C999C6716E26801EA938302ABC312AA797535358196B63309846675BCF1B33343BC3D4D172DB81947643A84FD2173FCB0477AB87B57B55899A308D51311C9BA6916F15947D707D88B9228D0488DDACCB25455CF782B7A18264E55C9B6798F39A53F53240C82FBAF461364CD5202C5C94CDFF23E0F731624E69310E5B47964B2BFD3A59A5B0D55A026E260731DE346F74938ABC607B4F579B8B200ECEBB633614A46983E60E442A4914C93FA62219025E4A99D71032F0B00906126365C467E0A235570A544A7640F23800CD5F2A825479A632343F20801F1774F0E8B7DB96A860FD40A43CB7ABAE76039C6BC80B94EC315AD49E9904908A20CB444BFE219452C464EEB2914EC19031152CACAA00DD541FDE81ECAF1F339E468BE45459E708BFB464D0C480A1BECDBC021A06AF7AAC4772545EB2C54DF6E9020E1E44B11B471DEA97A382A2FE8D1042565BCD51EF21CC0884D68F072D9B5A99F9C7A0A011E4DC10F6B600D611F40BBA75071E7BEE61D23FD5EDA +ct = F3F451B8F76002C10A67C10AEE76209E067B1B997C3B476373F7726B3F631BAF10D274224E86AF9D333D26522A951F3FBD36C72C6A261059016FBE4B3949DA0616205FC724ACFE2946C4D694AD1999CBEFDA3F0167D1CFCBD8BBD51A630687014AE826305E48D6E3AD6E68AD5542C3358CAE7141494821DA7A3BEE623096A5128C6DE1AB616DA91BE228BE402990D81F73031BFFF794DB1F8954738115649492B630FF50DA5F06FEF7D712B3BADBD175E290FB78351C1F408B5ADABAB395BFC0A5D5D2414C2131B4014592E2D5583E81286E677FA1F858EDA8708B2BF25147887433BF56D523636605F91629FB49B1CEE98CBCE6C6C9E76C587F50FC8B56821479BF3B97ABCA13804F08DFF1EE164AA269F6DB96DF267FA32F5B2EBFB3ADB3029859B5C802B0049B05CEF0A9BA390C49D38B6E11483B255856E0B2BB23685AF3843F5A6685FAE0A3D7424DA52B061DAA81390BC1335A841990C94EE87FD4AC9F2C56136BB755460F2698822D1152E33BB2294DBDEDD3A6630699655723B99B285A3707E194F2A7E53CACE9D4B4A60D78B6A8C74DB6F47E50C3B46E589D59F7EA24A051C143884FEF1C0A1B5DB65CB2C9982B86AF978BD6416617544AEAC67220B85746C4A304DA347636A23780DDAC9A5E79BE26BE127B0D3EB11E8372561C13A998B4B2123EFC24150048E8516CF1A2C6E7FF77090E472CBA93CE350C858B5104E8440CFBACA0D765FC95D7225E37475D048F89E6245A2147207475772F65399EBEBB920569137ACEC2AB035DE7C661B25356F5AE0DD99F016EE6460D999402641503CF6DF3E6F3380719A13A76C6FF6E54DFDB33D454C8E42E0A7B482BC8FB8E12A13E2E8105E876E1AFC9B9E5F28CA61E280D714224F835D8434401979B7635996627125EBDFD40EEEF5DA6D249A7FF15FAC662C9A3044C0D95D2B5029DAFBB535EC065EE675F4B76847F54BA66135126FC0B95D69D6C484ABAA11F60441E50863C7B27306283E58BF97E43E73164CFC143673940E2E723864488E48451F891C687F33BB24E4464ECC4CCDA8813947B54E22C3C368D97670980038BD6A6CAD485CDB8DADE3856069476E6F7D54E772BE8FB2E7B4C6019AD2EBC84DB2BF3D680385A93C7802B1F7534777A8E9C5E060C5F2148A5159140DF4BB35600344863E9F1E86F70BA9815D3051D865C7E6456D624113E6C76521884B1C2B59E6C2EFE4575E125A7E22776A80A756BFE25B0C0A5942C450AEF71AB8ED5CA425A09DF67670908FBB6F3BC4C7E8F4D3B9298E796D6BE36106F22FC6FFC0C9BD4BF1761B6859377EEBFCD5646A3D4B044D3424A743DA85116521A3FFE3C39C898591E669E204DC317928A7EB77DFA7B915FF832E7D7D9F1DA40AC7926F5B8733D661A4205228F0CE968FA3AD4EB5707D184EC4E72A9D6783A3641637957A2B6B22EA8BE95414DC06685CD7DC06BFF16479F490017DC78CE2D2DAD427DCDBBED163AFA58E2539C410BD8599A2DFC66D0C14DF9255A86B928F17094BDDC4A8BE4A202B36CB4 +ss = 91961EFE34B53285433FA9F780A04B8E47261E7A6EF77D46658E7671D800E2F2 + +count = 31 +seed = AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809 +generateEntropy = 9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +encapEntropyPreHash = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +pk = 5E55633267468551B3EE117792C80C1A802230AC805F769807976C06399B97B3C93FB83BDC136CB3CBA70BB4AB5F11602E977ED051115508668C244A44E09569A13507D4009AB72B16CC3BC615C12ADA7C56D50BA6307D00801BEDF8526F0A9366869A4830314D162F63AB8F51996663C1138641275E164DDF60C7708A75376BC235E16D5C22033DE1A149153D1868679E1825F638967BECAB5B9644A6E201906771A703B7844CB5CAB61748D202D38B5B8F03CC45626027895E23D0C1C1B526C6D519620436ED593B58732164A39639C813F6032EB902B05DB15C5D8825C8B11815768D29522536698A751BC1F9964DC579358ADC57EB83A0D2201B9B9354B1B39C6E7008D5F3189902964973AF9A9C694EEC1298D68D3372783D34700B0280D692998B49A9BB76293D7A95363B317670352A71822F415B1C97742934713C5995FE5CA9642C3AC18B73C43357D4D497B3905DF7F58C6566621EEB25DDA29D97B598970684C5780F665243FEB854F9F566177200F9331CE353CD1A23CCE8AA4529BB667D1B9E59B1A312A7C6FF08871CD95C6934419F475C1C08395CE1A3AFF83DD14784303B4BA7751054AA59F5710E4AC6039F3168C1B601A5278562B525ABB11E66193DC9D34446BBCC8163578CB8065F89B9F43407F79246CAD2B6B8B40F16B839A060A95B76855237BAB2FA315DB48E40842F8306125FB04145356BC50B00E3389DCCA26FF048AF5A730AC573B5B80331D2597C4188227682075BC0000186B8FD26A383E1BCE5C19F13B18CB21602F2160DAB202BB07B63D925B71708095DAA662CF25DCBECC99395400A79842F5C40E79B46B5384CE730439F537BBC8A8608F61520E120EA9843456118A0A4CF36384832B12076044C65F06C8F8CC31752469C8A1E33DC529AC05485548A6E075F46A089AA8446C0D465BD43CDF0343ACC9668FBA2A7F7191A9D29BE7E9300CEF33D13A11EDB2B409DE297F30B8A7B077FD4CA4D1AC74B31092ADED0503CCB5818D1834A734E15B74D3FE550EE49773A800D86F129B4E0250EA1C43DA3A3B802B0757C6401EA090F98A28291621341A9D98C67BB001E46E89973F40C1C4950B0E34F07772BA6379FB6A93ECB57369B48B3ACA26EF815C615B4A97AC2190FD2B15E83AA10545FB859635D084A57B0268FF085D9EA4B7EE1763B914E67B33DC46037F39815A1F8C58663C88662B91BAB0DB6758288C682372A269C64CF3AB5C46DE2C8F0F1B7780A068948B9480C6AF10251453C1FE213855D74675CACC7B162917730AE74EC7A8E7673A7D0887EDC175791309AB28E6CCC629BF79C6D69B19269A19488B7B88A45A199841916BA4A2A1C2456A108A5CB4DE1B15356CA737369668B0B5C7BC10E22377D6B5FEF7515B4F348015872E3518C2676079B8A06DE8B53BD189EC9766C04C084E74C6E747C783FF3A99B930547A72FC3A179CBD62B52D46207E79E37D65C9F3C4839D1AFC167AE4041671E2C1BF3324D875B78615067DFE11653E6BD4DD5414579AD8C942081DB4F1A10B0E1054FA3D79AF6A285F2107D4232700676B8A007057D15C923A7889F115762B4C242392CE7C4438C68C6C3FBCCCAE4A071E404C24274F5066DEAF5359EB3382EDA6D6338F166ACD09E376826299B77B781250C2224486EF23D424BDD +sk = 4DA026F053C3EC1712C7F294DC891E26196894A1B620F97429574EDEE9568E113FEB564D89A1883D5A0329929CA57AC001925C8D616791842DCD291627D61C7C2C3F842B547F074F46F082A06BB4282323A291C3CC07904079125CD5A854168D83BA8AB6B160B5E1881D25403B297C73048E3298287F51529A8BA2DEDA6B4D7665A373171B03B1C0BAAB6482C50CA3A028D485CA8491B1B73767EC9EF8874A54D4CA414895D2E49FB2AC0CC80C9D248B97DDC51D00A10CA3324FA8A6373A99C5DC1BB7A389CD9A3C6931FC7BEE05ABCBA579251B742F46383AFB48FAA514319B8F9A0491F9212DA443ACF9B9CE5B29A6E723A4EAFBA5C1A7B3E017870FB35DBA8A69F1F7995EF2AFF817907DE5C66899824889A760CA4A38A57B3AFA880A3524E138B37487B2EE7332D2689F99A5A3748020FBCA43ED6045A5ABA65F6C67783CB74C217BA987AD381938B4A651B6908FA4F18E6D073A6992160438BA3C9547E4557E1E724192414C912648D25907BD8B069C845465616969161C483927F5D610C815638E242323465839D36A8149BAD494B71F1336A3F0A954369D4265B6CAB935F06694C482B500CB77BB32C4D805A295A692648A31611B206D06C2E86C61675577053A747BD3A748F452B480028EDCBECA8A10EB843EA8A71E21E9B822D80860764D8C5A77EF0222F8004C902C832F1A344758776EEB99C3EC8B24CCBC03F5BCBE59027FB424E6C580CC3B41C041984EA552BDD6396D52867887430A2534A44BA544A0B285C061D7D6618C76945A5C3B29BBBB09A724B1AC53E5954F66708C8C0B2D7DA57C62FC8B80E73D737741F9141F7164B4EAC08822A4C340B5B74CB5C2D407B9D63365C55C14C5E6AB43A8BC68908C34074A9BF4816E000DDB464656C379FDD829B6961C22E5345674243CA64705212D52E616664587F90947FEEB4366A7ABA98B76D9F79A1ECC4BF50571A07CC57E0CB1AF828BB26263A8A898BF3B7B0ED07988E82DBE3C0405D46B1CDC37600570FC37AD9B2237E3032BAB1A0AE420B6F011A653987305AACC8876AC4D014B7E619227B8B35BA2616C9575506870FAD2585549A2F902B185D7A61139C027912EE2A00EE460328B16CCEEB259149A0881F8152D563BC0243302D29FB98CC57A45369517640BF0BF63A555A900269878C4BA567F8D376176D6941D34957E1373B7520483394C3606089D14AEE0917059227BD848BB22E088DEF4194BFCB36EAA81D4DA713E37BE79E52F51BA2C32F05D06405947838625E49F5F6BCDA5E683D014A12FCC0C81601B52F80C39B6659606A8FEA82C62E061A939CB4451869922083268561E16381B026152170104E11F30B2399F4097B94078ADC66F23F85BA6651E861237700BCB1AE92E2BC652CBF19BC0FCA0D7F7577C9C96DBC9B8B07B917F258C15661DA17621DB1287EBAA7714A54052FA660F034F227198EA14C2467B46CF9877F4E0C29962992B560A7DB93C8EC13343F734D86BC548246A57473D1285463D0942F288245D933DDAB7A09766A9F8C178EF539F9CE9A0E97364CAC0366B5B08B4C1B081E01D198C2AA5288617A50019EB3A40A300AF538119D733F2544D18B9094F387A3F4C17BAF01523F1455E55633267468551B3EE117792C80C1A802230AC805F769807976C06399B97B3C93FB83BDC136CB3CBA70BB4AB5F11602E977ED051115508668C244A44E09569A13507D4009AB72B16CC3BC615C12ADA7C56D50BA6307D00801BEDF8526F0A9366869A4830314D162F63AB8F51996663C1138641275E164DDF60C7708A75376BC235E16D5C22033DE1A149153D1868679E1825F638967BECAB5B9644A6E201906771A703B7844CB5CAB61748D202D38B5B8F03CC45626027895E23D0C1C1B526C6D519620436ED593B58732164A39639C813F6032EB902B05DB15C5D8825C8B11815768D29522536698A751BC1F9964DC579358ADC57EB83A0D2201B9B9354B1B39C6E7008D5F3189902964973AF9A9C694EEC1298D68D3372783D34700B0280D692998B49A9BB76293D7A95363B317670352A71822F415B1C97742934713C5995FE5CA9642C3AC18B73C43357D4D497B3905DF7F58C6566621EEB25DDA29D97B598970684C5780F665243FEB854F9F566177200F9331CE353CD1A23CCE8AA4529BB667D1B9E59B1A312A7C6FF08871CD95C6934419F475C1C08395CE1A3AFF83DD14784303B4BA7751054AA59F5710E4AC6039F3168C1B601A5278562B525ABB11E66193DC9D34446BBCC8163578CB8065F89B9F43407F79246CAD2B6B8B40F16B839A060A95B76855237BAB2FA315DB48E40842F8306125FB04145356BC50B00E3389DCCA26FF048AF5A730AC573B5B80331D2597C4188227682075BC0000186B8FD26A383E1BCE5C19F13B18CB21602F2160DAB202BB07B63D925B71708095DAA662CF25DCBECC99395400A79842F5C40E79B46B5384CE730439F537BBC8A8608F61520E120EA9843456118A0A4CF36384832B12076044C65F06C8F8CC31752469C8A1E33DC529AC05485548A6E075F46A089AA8446C0D465BD43CDF0343ACC9668FBA2A7F7191A9D29BE7E9300CEF33D13A11EDB2B409DE297F30B8A7B077FD4CA4D1AC74B31092ADED0503CCB5818D1834A734E15B74D3FE550EE49773A800D86F129B4E0250EA1C43DA3A3B802B0757C6401EA090F98A28291621341A9D98C67BB001E46E89973F40C1C4950B0E34F07772BA6379FB6A93ECB57369B48B3ACA26EF815C615B4A97AC2190FD2B15E83AA10545FB859635D084A57B0268FF085D9EA4B7EE1763B914E67B33DC46037F39815A1F8C58663C88662B91BAB0DB6758288C682372A269C64CF3AB5C46DE2C8F0F1B7780A068948B9480C6AF10251453C1FE213855D74675CACC7B162917730AE74EC7A8E7673A7D0887EDC175791309AB28E6CCC629BF79C6D69B19269A19488B7B88A45A199841916BA4A2A1C2456A108A5CB4DE1B15356CA737369668B0B5C7BC10E22377D6B5FEF7515B4F348015872E3518C2676079B8A06DE8B53BD189EC9766C04C084E74C6E747C783FF3A99B930547A72FC3A179CBD62B52D46207E79E37D65C9F3C4839D1AFC167AE4041671E2C1BF3324D875B78615067DFE11653E6BD4DD5414579AD8C942081DB4F1A10B0E1054FA3D79AF6A285F2107D4232700676B8A007057D15C923A7889F115762B4C242392CE7C4438C68C6C3FBCCCAE4A071E404C24274F5066DEAF5359EB3382EDA6D6338F166ACD09E376826299B77B781250C2224486EF23D424BDDBDCAF7B417DA8B8933279B33068F6FDA313826C2EEC500B224CBE046ABEB37A75A4D0A8A41C4F666854E9B13673071CEB2FD61DEF9A850C211E7C50071B1DDAD +ct = CC162C96F45C1BFE20D4EC4930FA6BABCC176B7B28948F6B3723F9A652AED6B8814C7C2F2BF11BE0321AE217EF12836547C0DA7CA4E7881AFA5C13B089F00249746D4EF05731B7F0A9189F6D092D267F88BD6064B820C0A995D27EFEC31FEDEFFA29BD61E16F35564627B8C07FD5100CF4512AF33689E215D92635278ED6E6135E14ACB1C167C8C3E4B843F4DBF0549468FB047C837125E8E80D453E39C44FF524119149C55AA31C7CACB5088EEFE93B7D493809A85330A67AE11F188EED63821340FAB8A7E9321F53FA389635E800BA2F6209D36F79EB7099F43B98B484730E95B58CEF65DC8A751FF3CC07B7644C99C243F6A3F314B239233E458A2BCBB6FA612B764EB5051A8DF7343267A7FDEE9EAC48E9577AC389B7ADF2653791184B69942B6191918BB3D6F88B80E208261C8D393002979026E954559634DAA1700FB328327DAAE0FDB1097837E91263AF9EC3C1864B509D98E039B666C875BD5CD390B7219ABB32ADB52EA6C3FD81C52F1A31A3A77366F7A44EBC666F912FBC898EC79B7FE554753B7EA41E0EB5EA366A329CEBB3EEBD449639EB8E2ADE3E5E92C44A587CBCA397077A4B756EA4FD425E2B780CBB3C8104D5CC5DFFC7A38318506BB8993979E0F00897F5F3319526F049470A37C9BCF52B0426332B9717D6336B4E277C363186D1A8F58B6107E382C77B5E25141EB6F5DAF19DCFA95676D2037524772E804D3BEB87E75FFF624CA9F5BB6098E3239BCEC265A88D2D7870560888CDB6805E68177489C21C8B3A2FF9949764F1A8D9D80F91F27C180245A7046717917650FD6F550296D8655F4E546E0780036FD90652C02786910F230A5E2C6467E6EC1687FB6AAC12C06451FAF6B7B2AB3C8C0C1885451E04FD54E05956D2174099E5F691D690A48BF5DE1E67BB5D84288415E429184ADCE1DD7B00EB94C33ABF63F5AE80AF202E772EAA576CD65E65B63ECB1F98FCD96DA6C58D4985021A1EB5A953AA105C73CF9391AD3633919BA794A26F2052878E4607D4489AC7E084009A582731990E8CC087A459470042ACC5BF481DEEFF132C86615A5FB41E47C8D7D18C8CE3A478EF621F965099A1554597BC32FB119367C25DC0373739B8E228DBE85F688B005C9CE688E12142D51D4D06DAC00690C1076702D8BBDF608127F7745BBCCEEDA28CF9A067CF6235742A230506C5DD4B9FB38CB9EFFDB2E97C07316131F7A47FAB847EC5BC93C88275DCE4F1781590043208A838884778A58EC5296C1935DB4F8F32F11C209A697B40726293D18AA908D4D7BFC8C4258F4535295708DC80DAA68ADABED79FC459956E1A7BC277789FA94DFB5CB69EADCA03A0B9C0A21BD5A7DE051FF255D6DF229F306E75A8095A2A511DC372EF601AE9D8A4575A4043380ADDAFD25AC1D044A73722C0255974939D9FFC2B2658C5FFD7F1E7E0F33AC809A1B1648527AB57EE858109D30FD29356D74C79087CBD2FC436DB8DE5179483CF4CCF6511C2CB58FA7C5431C25D1EF9CE8C75891449D738BAF2457E1F8753485E38 +ss = E4983D6021D6C10E71F474D76650F7B5E23E02805F755F57A1012882DAA77ABE + +count = 32 +seed = 288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7 +generateEntropy = d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +encapEntropyPreHash = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +pk = 420A3005A17C7B4A08178B83F8540601145B102970B3FC29F30A4CA1A8A5BC4164051931ED68A59EFB2B50D549BDC1A65E9909F5AA690B0235D32B1C6B2886CE2959FA189E2CE24224E99255863E6D964D4F422C02646A461BB5ABF86F4B4C0975765A5B0CA01081677334AF26C3467DA771CDF40EC4293608801CAD9C61D5F80839774EAFF772B139051BEAA65632120F00171AD020276A1FBF23517582149AD2C73450B11315CA4B244E7218800350AEB5808DA774030635BC247508144740634AC4A078A5AF2816E9206A645287DE06263277242DBA12AF2A82CE13BA6787C5AC3020E5D30CBB92452985AE41027056F492BB1A5E23332698240B5038302E552C5ACC0443A8795804126E15369AE96CEBD7C9765233982458AD6520550BAAD77BC74296BADCD4CC37240D0163CAF8C806A0CCC3F4125A0874CDC1C67E4626C9C753453FA37B208CAF5F523388D6308248B7688C80F6C925895670A1397880933AF0152DA1E54F7A7B512AA87499F7A718E62A7CC5BF5687ADD09060426B0D3CD292AB9B8372083EE462182872815CD740FD69ACDD24615110BB618CA1EF662715F028864BA0872B8C199ABE40F35F91906A821B8CE0742F931C661C65AA2445371A300E68F23B767382F3701CE685CEA5F59C50E82E45234169C3BBAC814AB9D68F83842C513A8FAF475590B3BAC2E3A4685B8F71208357D221AE41310E8454D315670C3A3409A2A95258B9057B42DEF7A7C6F588F6DA61183ACFB18A7CEDF138C7984B50A940F17C687E5A2F83451D94398F4C82C93A375BE195B4B219232E9A766E77040D3B9125E70FA4097D807A6D25323342508F2490A59702575D64AF146088F59802AA2CAB3537A8B4E92A10EC447BD89F9FE738D92A5F83C2861628601E42BB427B87C2153D4BC44B19413B79BAA5EF55325BA8A42E1A88548155D03AB116E47EE0455F0E5A71BAE3A03EF476F77A9A9CC6526DF1ADBEA64930B6995F60181544356C0982E957C5E5186F321B9467D05DD5970A96E226C89673E50A056E7C0A8027ACA8A5CD93723353CA1991730DFEA1AEE943CB0D62537CB5AD88C14F52A78CB6228EF4750EB7DB0AA831A4202B178EF47446A06A17E7CAF5274F384B36832A07AE0A66069BC59FE439F7B6005F064D865B550505210768BD636C61F0E7A1BDCB3C3065908D51302EE234A3FA113A1A1A2A618750075A6EC277CBDAC535FC1524A62E3C0601AAD1C46026AB6B8495C1B7093F776F9E6B3B533267AB99801E83BD18570166387F14ECB4D279B86CFBBAF90649E5C514E432561F850497D47C2BDA1BC2C398B306751991392C399DF6F408FF836F989C41CF76234B9445D9F81F4AAA987C1721C0C726EFE44C311A589ABB5E0AFBC4ADD9BFF6F87597A52E16A53D6C3551B7E6BE0A1958A89A739E0717F0A86BE0385C5CA433B68AB9506BA3A6E00DEBEB1AD0519E228B5B2D9AA3C9B4A2BFC8B35BF0A04B5A9D0154AEF1A9478DF4C8A0354F8878331F76C8CB6851940C996109113446367497CC73D395B34A9C7DD9621C9BB277BBACA6D976C3E65FC3FB4588643AB523BB35F551F1F30D0CD1C40D14B09429215E0C5325BB2B069B85C9E0BD9FA841771AA7C9709046B442990CF89513930F122152632A3C3D7C15C8018E1C23AA33CB89AD +sk = 1F83902BBB77A97B032277079CD0CA70D09D57385CE5C1B3C08B80ED95B2BBE70C101CC1912B71B29B87DD08254B593D616A31FF4957C7C0C325F82024F6A7B125B0FF799FFF47AFA6A9A7055382BCA08CBFBA71EA1B530BDA5A4548922C90C6DE8927494370EFA6C96780086BF585AE6534DC05344DC1941EF793EAE214312A371ECCCEA680C1A166BA97E128064748269922C9A19CEE4B8A669ABD146491ABE31A57B724F3A173740269A33309F651C934E09A564627896150ADDB8BA181CF2503256512B0DD5588F4372781F35CFC0328C0DAC842A1B3F418B6E8C567F410568F2C6BE8EAC9BAB558DEB08389BA08BBAA50E1EC5DCE044EFE5830743402402A167A9369E1D281D37713EB656662600840409C4FB971C0FA7771BA53B6C13EBFFCBB85AAB3316A3A99A9CED8BC4596932B3D052FBB13A5CBFB762AD7A08CA4AAF33862B6325BADDB0E56D395E8F92EBC7347E847956B471695C978DC2431EF7286C0E0A880F7871BB05160209900C0C403DA599B988A8EF0A716A9535B71002B3BCDADE60053F5A8BC66419FC907F1EA718B7BAD6BB76FD3F710E6778587C36BA5E4C2D7796185BB72C5FBB839B6C91119AE6C954E9B66C3EDB500D884428BE2C7CB6A6C86B807A6059739E23F70433D8A7A4AA768975AA6B0C3924CC8827CFC731A464121090A685820068019197F489315A2274A7133422B2968830271FC94B1C775C5A21E3B07BCE543B32F00B7250CABD0D04A2529347848830C975261A54717324533EBC0EC627F2064BA693A9BF9A16FCE87A8D7270759A06C00EAAB71A5CC25034120445334A39D63BAA2AB3254D77A921209750F6869E6971D05DA1E1BB29CEC9CB7B4962370E5C139BA472A75114B28BBB8E7069C5A8201B730DB571C1EE0B10E1C42B4A97FB7F7AE54670D12859D68199443157DDEA85760445895E7175EF8BB919C7213F427301C4F6561AFFFB0B03CF1AD05613C52DC5CA71A74545ABE77D239576303BC9678272873D9B28F4A4AACFDB46940F59B0A82A75642A0CD794D63D03D43F65E753A6AA2B58E0CC664A48CA3D8A3B18C7B05CF8293D3E23FDFDA93506C831455B648E2017FD866C87683AB307C6FD9CF24212509D777F34B0618776864EBAE9FA5318E739692C5AA86648D49778B67F81347B434CCFA990EE9A79DE94C94054E6E4A8A152B5F4757B89F075A27AC464CD1801D02AB64BBBA4F932C0003458FF73011282BF444961C54C5275408C4F79C3C553424AA4AA13A53D59B1B785C0FFB686FDA185D5438AF5C494D98B80381C821C493BC0E7797CD1995DB681EC9E18859A9229C497CC251AF12D9CFEBC6A19C599C9D364E587C7D32245145A60CEEB54CC7EC5B541B71DAE959C800A747EAAB53F8CD24365C91F53B7B0B9D3630361D41ADE4C82C85E04D8BA243763B3F9DD65D60921F962337A3421051D36889253A423939ABEB0AD962CE1E1A9931C960D9F4948723CA17A731ADFB4834615693F622470225CFA7B036B931A2240564CC35E59A7ACAE48707491576CC1410A304E0885534F577692C5A237344A5F674EC7C45BDA3242D70B004D5AB620CA2B1AC0A56C0CD5B942529B054E0F840E3C1837E0053539B4A420A3005A17C7B4A08178B83F8540601145B102970B3FC29F30A4CA1A8A5BC4164051931ED68A59EFB2B50D549BDC1A65E9909F5AA690B0235D32B1C6B2886CE2959FA189E2CE24224E99255863E6D964D4F422C02646A461BB5ABF86F4B4C0975765A5B0CA01081677334AF26C3467DA771CDF40EC4293608801CAD9C61D5F80839774EAFF772B139051BEAA65632120F00171AD020276A1FBF23517582149AD2C73450B11315CA4B244E7218800350AEB5808DA774030635BC247508144740634AC4A078A5AF2816E9206A645287DE06263277242DBA12AF2A82CE13BA6787C5AC3020E5D30CBB92452985AE41027056F492BB1A5E23332698240B5038302E552C5ACC0443A8795804126E15369AE96CEBD7C9765233982458AD6520550BAAD77BC74296BADCD4CC37240D0163CAF8C806A0CCC3F4125A0874CDC1C67E4626C9C753453FA37B208CAF5F523388D6308248B7688C80F6C925895670A1397880933AF0152DA1E54F7A7B512AA87499F7A718E62A7CC5BF5687ADD09060426B0D3CD292AB9B8372083EE462182872815CD740FD69ACDD24615110BB618CA1EF662715F028864BA0872B8C199ABE40F35F91906A821B8CE0742F931C661C65AA2445371A300E68F23B767382F3701CE685CEA5F59C50E82E45234169C3BBAC814AB9D68F83842C513A8FAF475590B3BAC2E3A4685B8F71208357D221AE41310E8454D315670C3A3409A2A95258B9057B42DEF7A7C6F588F6DA61183ACFB18A7CEDF138C7984B50A940F17C687E5A2F83451D94398F4C82C93A375BE195B4B219232E9A766E77040D3B9125E70FA4097D807A6D25323342508F2490A59702575D64AF146088F59802AA2CAB3537A8B4E92A10EC447BD89F9FE738D92A5F83C2861628601E42BB427B87C2153D4BC44B19413B79BAA5EF55325BA8A42E1A88548155D03AB116E47EE0455F0E5A71BAE3A03EF476F77A9A9CC6526DF1ADBEA64930B6995F60181544356C0982E957C5E5186F321B9467D05DD5970A96E226C89673E50A056E7C0A8027ACA8A5CD93723353CA1991730DFEA1AEE943CB0D62537CB5AD88C14F52A78CB6228EF4750EB7DB0AA831A4202B178EF47446A06A17E7CAF5274F384B36832A07AE0A66069BC59FE439F7B6005F064D865B550505210768BD636C61F0E7A1BDCB3C3065908D51302EE234A3FA113A1A1A2A618750075A6EC277CBDAC535FC1524A62E3C0601AAD1C46026AB6B8495C1B7093F776F9E6B3B533267AB99801E83BD18570166387F14ECB4D279B86CFBBAF90649E5C514E432561F850497D47C2BDA1BC2C398B306751991392C399DF6F408FF836F989C41CF76234B9445D9F81F4AAA987C1721C0C726EFE44C311A589ABB5E0AFBC4ADD9BFF6F87597A52E16A53D6C3551B7E6BE0A1958A89A739E0717F0A86BE0385C5CA433B68AB9506BA3A6E00DEBEB1AD0519E228B5B2D9AA3C9B4A2BFC8B35BF0A04B5A9D0154AEF1A9478DF4C8A0354F8878331F76C8CB6851940C996109113446367497CC73D395B34A9C7DD9621C9BB277BBACA6D976C3E65FC3FB4588643AB523BB35F551F1F30D0CD1C40D14B09429215E0C5325BB2B069B85C9E0BD9FA841771AA7C9709046B442990CF89513930F122152632A3C3D7C15C8018E1C23AA33CB89AD61E27E954728E2E2E230C94FF009417D7372938E2C29C38AF22184EED530FA1F36B817736CBC5F7B1DD6EEF5FE6332FB1A598F3871E5470D440FD2EA631DA28A +ct = 6EECD129797B2891B41E176111251FC114AF2179FD711D4D4C6F0E825AF1251C686757EF29970B63D621AD3FD6087CAAE604D416E06F444465245F34272980672E099F0BE19818760FE474F0E299AAFFFAA6551A0592EEC262000456377E54AFBF5E217F39D7C8C9B19E03B472EE47947580481B451B535486C28E3C61E983BE8A5802469CC95AC9CE38BBC371BD45F9783D0DA21253A478A042427D490F0247C8542648488416970BB58F7F0849502361149DCAD935AF84987BED520EE79D3FDB1B6D478652C892ED1BE4BE91601554D092F0EA15889D4D6B3D8BC38D0A2AB98B19A2213BB688B92325236CBE248B183A6C94FBC22E89250286ECF018AAF17416196F3D1598B63A6A3A780147197895CE6A814C130984CE05A9FE30870395E4289144B529B1D1E04ED3207B0130EE490CE86C49966DC6F0B58DD651D9E650D7F6F7B6F2B6B398CB3DEC5DBCBEEDF1D448892FED8C9EF32D681608E5ADA2958C3D47B0749AAFA33B95B1DCA91E6975EF842F1702777937450157C1B7739EE03B73B7601DB13747C4762AE8245D90D706636BEC3EFAC18F88FFFF3E2068BE9E18FCCBFE34FF834D937BE6413AC20A3E49C9CAD9E7E5B7B7E64D10A99C8BD916E2F3691706A2F64592CEFBE5563B68425ABA971D80A2D7428C623D42099F1B37B679F0EF039528374FA8F7A3D6D4C0A6FE7A110F72636B6C2668ADEF2261530BAB8FB057D26551D97A491E735FA3AD4845ACB832EF4EFBA71D565962AA94E46E17849FAEF065C888912AAE678C0C3314C8A05F2007F3AE1DB1AA4AFB1DFB3F74E937530953FF48B280C389CB13A42AB31F275318885801195B92FD167D17A46FC897E4EFEE985279195889E58C88F88C9F907B9315FC66F9BCFF1D2F0B2EFB7D4ACD7EBA6AD108B5220A1EC22D7EA83E85E5280D2BC06C62FE7615635EBB5C2C25507E46FFCF32E19A3E662AFC952511B2F0AC509CE93910D995A26AC5534CF2B181D624CEC786B86AF927D4BC1BDF396EA99F6DB7F259E30059595A654B2381CE1419E75A5B175455E127E7F1AEAC0B8903CE4F0CC6F26C72A40C358AEDF833AAE85B975F1B4EFB40D7C4A1708574CF0E98A2E787B9C68E568B465A53A0CF492BE54BF76E0C804BF51A5B74981593F3088367829CA08683986EFD8C9D777816158139E8EB22B6EDD93030F3F279E80D958C5592B0E39BB831AB6826A7923D8A2208B6C2D2BD8CD32604DE47722AFC0AB9E5D7FCCA2CA1391AE4AF8E43A5A878229D54EC256A6E42BB89750E97FBF3679F9FBDE1EC3D901B82CC45330BB2CAFB861665542A4FD34317A12CF9C75F6D9ED49FA081FC31212874E74D2F6514040C69A70CB56453618A4F983E63DA0ADE52BE5840A9508EA3BDCF70313173F018485209DC8DD229E36F854C778095C2C85D3B5B2F8E23EC88608362AA183D028F8988C18EF88373DB13CED999479A325FE49E9DA01844E1CF37D5BA098AF7B8005F1F1921B850B4CFE545E7F0441F24548DCEE473BD11846F0B6EB9CC412672CDB0EE +ss = 807703887AD9601806D0BFD5F9D9B6CB01BEE01F82500F525CF4CCA6E4B21FD6 + +count = 33 +seed = 4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44 +generateEntropy = 684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +encapEntropyPreHash = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +pk = 63992E0D6A8F811B3F0D30807456C84C8BBB008D3B126A31424954CBC6CDBCE91E25B19928F4A41B1371447BA3D173915580BBD7899E9ADCA37B4B5A21E715101717710BC7EEC56EC2E58002127D1898BC55F8A3BE385D607B3BA6561991AC6F0913617303830DA25F0CF0AC14E67ABB8097D17B0AD1EA8C6C267ADF51A15A9A363D7AA5C8EA535A89115C984AC5D6BFA922C6FC44A3B35CB667F939FA6B2676BA212C17BCD25C82E8172F6A7506E8B77D82CB21D7066DA93A7EB3CAB8E881A24C7592BC6B656E459AF33A06FC2846D71221F1DA641004B68BD65DC28A59036CA678508614B15A93E74F89B8AF58200D50E718DAB1C41C4556CD47B43F14092CA47397243983406E12E423233C90CFEB661A32CE65AB464DB58C922BB693F56553961868B064E17A11162A7F0E3AB0B0AA76B8494BA394C902C598C23721DC16C51D46B8258C635763776B922FCAC747985B94C006696F18BA49D0C5EB0525CAD1349745691320969B6BCFF69C30851B41E66AAC3353C6894AB0097B4EC49783CFE4960D61A6F94B317D488D2D04A8B42C7FB7D89D52D89B2DE30336333C50895348870BBC311611F27845C7775128A9CC831966FCCC06292D86B582A18C6AB2FB3CCE03701BA91047227A9FCBC6F16130710756C5DC288BA92402B5B7DC90C39193737C206F3F8230261852F1694258D47C469C7452156E70634384825BC52B03E90720066B609A4102862433E2621987E23AF51121BED807810501200B776F847FF615C0F594420DC29CA6573276559C1C84B0723569DC2A76728909D9D1279A8C240A3979B0B44003687A412389581B8EBF0CCB06C797F7F5815CCBB434132ED5F1340E2C669430B13A709F7D1612AF876454F06CCB7841F84C60F3806D5E423CB34B23BBA90AB630403A46783329707388A1F4232785D4723C993CC62284D0E35242E52CFD6981268B86F598B11472900F83333C48627D402ABBA59C6740B4A40ABC3200B5D9E13010FB4DD6BB503548C777256E0729905A89BB386459E0B885B6E3017C94BA93C7518F017695F5BF5B99214C8555BDA863FDD11D40053C0D652696286D2BA14D569915E4532132527CE1B88122640AD668A20964476DB20AFCA5CA663C6C17156AB3CC8E4B723B3A5209D2D10767DA52B2443764F91A7F3AABB35137EE18A1F744562E22385716892CA77D518C4BEC578E0F1145B3241C1831BF782C760F9081A1191812790531648954163B10E6A1F02B2B9E17CDD439C6707AAB0DF09236BA33D9B271196A398FF0B2C9521E57B6C8833489C5328F4866C14D2CC1CE037400DC610B28CD99150404A175662102F9617205C1CBC24B5716C7B9B0E8635BF960BE5B632A976156C64078CBB23EB86B7BE9A2D3E12F5B56406CC51796C66A6E871DEB601CC767C0B8E45744346DE60BB160808210506C5779BC275940E000314F30555677689F23009A583CD6F9779C83530E5B2A5A0A771BF1376F0091C627AFECAC104FB2BA251C074E359E5FC44DEC244CCB78423532A7EB27C8313A341DC1431035162838835C85C677A420B67C847DC6605821587C8064E0BC2F4FE6A6B22113E73519125B92B3A66F15564666023EA99273D0D5657CFE1B1B3BBF85039A8189076A3752784E23D8A802023FD0743EB03D989A6968 +sk = 8B78635AC351C94BB6B1D2B861E4914DCBA415F66CCC465B370578E136330A2C5CB0CA2857E1CB733A75E5CC4FCDF7A12580017F1C0FF484401CB23318A98000637B3D065608678103940D8BA75CCBE58206C130ED62BBC0132317B6556A9C2AE8F71A43712002D795CA52007782652D291DFE535F75034B0D624277527A6EF623168AACFBF721A9E8753195B82EB9855467322AAB0AB1701546C470AD139944B6736E1C97C9768370846B45693AAED9C80A7B53B863830DF61FE9600AD5717BFA2C8E59E30C8A20179B27B59341C855677880330AFD1A227B6C6313E17C46E87D109A4AEC4C1795908DB6046598483159907A667378F80BCB84472D5A748043B1BAC10BA5BCF61B07A2B13B12C347F3253E26C25EF0AF6A003A67B0BEE98A7C5A489C9EC9AC1F042C6F2BC7585CB01BB4B55496A93DE903EC974398E277CA7CC25E3265A879420EA0BD8451716AC21F1BB806C12B3488D408EBF18B89B79B1F8C09EACA235F1C165F9504FF987139590F9977513EE037249B4E25E51A296526BA76CD3295895A571CAC279BC65642CBA501C8F131EB52B5C7CB73B17757440B1EE4E9295D404177E542BD744AA587738BFAC0EF3C1FA0F19B0A5C5E28B53C2340C7FA061AD354C85AD26993087B61AC2002795D5ADA7A3E6747AB8110367C824988CA705B818D7A921DBA33371405AD235B18E463A8AC88180C88F071579FA5AB6D904A2F53B03F7C7EC39C473632369F984F8CC66DBD1924206A6376706CA36601BE7B16EDD17E93CB9A0437B3615374329B0712794F5058790D88182BE4863293133A83AA00E07C8E79C6F12C33FA9437ED984A1392903DA89BD43184DB6C8DACE3789AF5CBBA092010B889CA98AF99E5B0B3D4399BF61266E833A55A85E11784708B98EFAB223A27AEA1A16E76A73C2027759FD97A7DB870F9FC79AFC89435D092DB556E0A738C133B259F86C98D78A43A49744F306DA8CC6C9098A5A9CB091C9BAD94970F03B543D669A9AA4944E0C08DDFCC1D7D485FA414B0765A88F175AB6C94B12A2177DCD4998E6AA263EC3FD5BAA2466CA04568869466887F7BCF636C7A1F084277532841F51C3EDC5C1873BCE0F07A8871740C4AA82BB5AB164916082B795EB0660BE32DA9972840C927B7BB4061343D56757258BA4C91624F21DA11CB265B00B9AAFBB1665679C86EABBDA12B74F1C5917101D0EA2BB293C71AD5B556369378A8D5B7297C9731705DD4493DBB173AD01458686A93287B6DA0A6923B913989B69612A915A03A0962379BBC466A03F5517AAA0C0B030C6CA420636B2EE8821916E9C7F2BA228BB2AEABBC292F6C07AD85C6F43CA90D42629759536046394936C3AC5AB979D5CEC1A1CC19B5C17EDB47B0F47F34D616027B29A12725BF14B62FBAC4F2CC6EECE89CA0467D4868C11C17299373687B657D132C55785080F5B87F0E3C1504673825B98E8A0AA35F2C8D84F41B060AB43A930E7BE1C9D04746169BB4AB403ED8C74AACB868B4A93F1DC55144738E2736749AC64170CA7D0F0348A9550EE494466A49617B541068F2C57AD4108AB813DB58526C7647D55C1CB657CCD1143343AAA8421C23BD0C822F763B6A82B7D0041648A143BCC43163992E0D6A8F811B3F0D30807456C84C8BBB008D3B126A31424954CBC6CDBCE91E25B19928F4A41B1371447BA3D173915580BBD7899E9ADCA37B4B5A21E715101717710BC7EEC56EC2E58002127D1898BC55F8A3BE385D607B3BA6561991AC6F0913617303830DA25F0CF0AC14E67ABB8097D17B0AD1EA8C6C267ADF51A15A9A363D7AA5C8EA535A89115C984AC5D6BFA922C6FC44A3B35CB667F939FA6B2676BA212C17BCD25C82E8172F6A7506E8B77D82CB21D7066DA93A7EB3CAB8E881A24C7592BC6B656E459AF33A06FC2846D71221F1DA641004B68BD65DC28A59036CA678508614B15A93E74F89B8AF58200D50E718DAB1C41C4556CD47B43F14092CA47397243983406E12E423233C90CFEB661A32CE65AB464DB58C922BB693F56553961868B064E17A11162A7F0E3AB0B0AA76B8494BA394C902C598C23721DC16C51D46B8258C635763776B922FCAC747985B94C006696F18BA49D0C5EB0525CAD1349745691320969B6BCFF69C30851B41E66AAC3353C6894AB0097B4EC49783CFE4960D61A6F94B317D488D2D04A8B42C7FB7D89D52D89B2DE30336333C50895348870BBC311611F27845C7775128A9CC831966FCCC06292D86B582A18C6AB2FB3CCE03701BA91047227A9FCBC6F16130710756C5DC288BA92402B5B7DC90C39193737C206F3F8230261852F1694258D47C469C7452156E70634384825BC52B03E90720066B609A4102862433E2621987E23AF51121BED807810501200B776F847FF615C0F594420DC29CA6573276559C1C84B0723569DC2A76728909D9D1279A8C240A3979B0B44003687A412389581B8EBF0CCB06C797F7F5815CCBB434132ED5F1340E2C669430B13A709F7D1612AF876454F06CCB7841F84C60F3806D5E423CB34B23BBA90AB630403A46783329707388A1F4232785D4723C993CC62284D0E35242E52CFD6981268B86F598B11472900F83333C48627D402ABBA59C6740B4A40ABC3200B5D9E13010FB4DD6BB503548C777256E0729905A89BB386459E0B885B6E3017C94BA93C7518F017695F5BF5B99214C8555BDA863FDD11D40053C0D652696286D2BA14D569915E4532132527CE1B88122640AD668A20964476DB20AFCA5CA663C6C17156AB3CC8E4B723B3A5209D2D10767DA52B2443764F91A7F3AABB35137EE18A1F744562E22385716892CA77D518C4BEC578E0F1145B3241C1831BF782C760F9081A1191812790531648954163B10E6A1F02B2B9E17CDD439C6707AAB0DF09236BA33D9B271196A398FF0B2C9521E57B6C8833489C5328F4866C14D2CC1CE037400DC610B28CD99150404A175662102F9617205C1CBC24B5716C7B9B0E8635BF960BE5B632A976156C64078CBB23EB86B7BE9A2D3E12F5B56406CC51796C66A6E871DEB601CC767C0B8E45744346DE60BB160808210506C5779BC275940E000314F30555677689F23009A583CD6F9779C83530E5B2A5A0A771BF1376F0091C627AFECAC104FB2BA251C074E359E5FC44DEC244CCB78423532A7EB27C8313A341DC1431035162838835C85C677A420B67C847DC6605821587C8064E0BC2F4FE6A6B22113E73519125B92B3A66F15564666023EA99273D0D5657CFE1B1B3BBF85039A8189076A3752784E23D8A802023FD0743EB03D989A6968672E53B28D579974D268132187E7BD72238639C6F2CA154D50D98C74096EC33075D12195EC32A8686D0600E45D4A7F54219B0D7A3826D193A51B9156ECF2EDD6 +ct = F145A8D9CE4F94ED02E2693AA6A5458962997E212A3DCC11C56BAF8DE75A68F67C69EBD87B212596C90201BEEAB5E2A0DD8FB0F9C3308EA0B0797A6921E7B7A036047A78F254ED699393FFC4B904EA2E00C7CE3D149BCA5D763C2CCDDD386EFA74DE0D1E42E1F7E96B1B92C346F5610612E30E970360DCDC541435974C33976B13B069270DC5D78072E9CBC434E92D7B30CE2459812D5A25D33AAC97D3DBA1A4ADBDD08DA548DDFC83D22EDCC5015B09AB361DF9AEE747572A4229E6BB5F5FA85579BF47DF4525880A6BE4D871D38E0354DB9FDD331F8A1591566938C747F14F388395043FEBA7678FFE17D712BF651D544E6F307E30DE4AA7022ED3B758D306C8D526C29048BE699A9E5D77EE1CFA5961AFDD94C867B46D74FFD16EE258E6E8D3F4BFCA7D810796A2BBF456CB5D00ED9C736286B2E57D10633227BF7B91BE1B08361C90A57D6D4AEF79271B1AC6E2295797671B7F0C7DBB5830D2EDDB2B7AF062BB73967964C0D740F7BF562648634B40E5F2DA69260FA4DF1CB9A99247157A8911B8C2916E6307CB684CED9FD738C05179931992BD64F7541699F8DB7DCDFF73085E9BA500FC1E7130CEA36E4C67183179654913E33D9C47D76A3FC74F553BF32CC2B0167C4D3357A7C5CB26428FDA06A3BFF9CEBA276F2A412B21E04216A052BC4C201E5D36BB704DE258D30E5CE1112D9AC8E0940C4035789A1C3C2194A3FDCCEA8F4FF9CFECC01CFFAE1334013113ABDBA5D6574167D1AAA2B95257AFE1DAA39B8EA30F7F3843CCBD2B0DD373E9CBC9CE254BDBAF462A0486CF38EB7F90B5A7FA77D007636641639C7BAAC4563CD27B44D9B104C04990EB0D45B9FEFB05D987B64A5FE8916F906720628961490A91252DBB44972B7FD2BD5C11292F40B6C92317BA3641B4DA563FAAC61972FB552553CC006945311B8C79F88F7A59103306565447ED94AF5C2D1C10DF6D5BA6754932FCB98F3AD1D47D39394AAA810739E1E326AF312D94605198FE30E7174EDAB76391D4956ED0E4C2AB6954D38E00DBD02E76F2357C350F7E93C1974D2C1CBB3C638604DBCAD41790E7E402B80261405A52C2A0F9F0CE637A769CEF5BD800CFFC976598869C24FD9F8C83C55AD840BEB08EABB33877C2CAF3F8328C2DB2E575254E4F129A1E969D91EA02C77000ACDBEC1CF6B1003CA9C8AF77B22F6F9E8E831E4196585450B61E0E9AB6ED12B703C990FAF295FEB56FE39AF4B9DBCB2447B250FF4C13078FAD781A6CD5703FB4DC4A49FFA0FCC342E3638C6FC407602818E0F3C557EA1E9455272929E63B6BF746882769C5C482A413901F04623DD386186392922E0CC3B051F87C4783A90702B0FF33DD37AA924A2557E7461652444C9DFCE842DED51BBE97336FFF712974A3B60344FD9A7898FDF1F5BCF9AA6F0F28EA66FF64A76EE2D6080AA47C8829E1E8292185DB9921A4F4B3FE28786AFA28B25E87BBD63087A08A9234C6F12351B7F622A00F81E46462882936219FD8434CEE7B5EC0F18ACA21B13B5C995918B13B852121 +ss = 9D28091B20946B5507AE42BC4355A71ACD2B5EAD20D4181B22A5031EC53CA00F + +count = 34 +seed = 5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE +generateEntropy = d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +encapEntropyPreHash = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +pk = 192042D43A4271E44D1546306137A4427130C86A2025BCC297EB36D3C44E7CD4B0B1C22005FA702AC12569BCCCCAF6AC9256A1693C8B677C5CA243B9C8556CB3A268165596FD0470400CCF5E3B56714792F7A87B9E03019751425695AD70E4CE0B2769571901C6C2003B58152FA9757922BD28A094771B0CB1DCC73741B14B402E8AB86DC0F647525C131E9AA1A9729075EBB3CDEA4D31F6C3B23A5BCBF74A3C653D4C015CE5F65FD1042A137453462B8710704BEA463204C463273BB71056378850AD28F37EDE664E38514DD735BF9AB9B95D367C54D84FF085650AD33EBBC982A329C6FE3A516EF387BD0A0417C2655A5476F51A68CBDB4AEBC53F00C11E78E5BA6692A516C076330C20D0A09F167BBFE1C956A619825A8305D1AA9AC5736E6D24145924B2409A8688B41F33A181A9E4858325140A797F2BA81D50F21AF88650CD0BA8E662077708551A947C97C0A3355852A77576CA5B054D3B0B9FD973DADA618BD02FFF1CB59EB56B12C71B24BB1F02E27282D21281493AC7D07A20B124AAC30B7BCB8C2FF24B2C927D3D62ADE0357BBF7C1281FC94DA2B21D10A5E5EE07A3FD9CF93E34615B871C8DA7DB5441020D0522C12711E1963BE54739BD43949999083115988A09C6020CA88124B35C34EBFB0743B494B2666CCF5B5235968275FABCF9A054EF92833D8EC816D68C07FC53634A02CA192A411C87DD1F17FFEA094B6868638716CF593B33483591E4049E4E7C65C8618B242B17D6021BF0A70C7C59BC81C34F5441B063B9A1D95481E6529602B95F874BF1C649D95A072E70A52E9252E1DD1BCCDF64332345355F7CC48EB7DD1AA2F2C31AD1FD58B8B3A711D113C270A90AA2C5C79958F3907AE3BA071AA6144B88BA6C5575BDCF5331729A65D8ACF3DB97ACA4191B72A2BC1433FB3483EFFF09698C291DD868275DC5A86D06D97305BA596515E434A8D956B2B73B3C00821BA055AA7541E4F35896113ACFD9320FA91585F3212CFD5B023A77D7C5C0CEB746723C2C7D7417BFB740E4BFB2299B29F987698EDFC1B8D7B33DE2C80D0CBCB44F05B1DDBC667005B6E4335751AC281022CBCFAC0A55226FA69CFF845007B9A16D2B6BAB3135B325B12C263A81FD423120A6FA639910159B693406411A289863736557A028BBAA23E0C984F04543E61916D9BCEB4F64FD48823A4B13E4F83B43D443F62ECC72FD304F71772CCE318C1DA9A57A67502A1119313B93C4A66D03C2316C2CC5C2285B1E80C413B2F29C447DC975923D9100BEC9DB958ACD7850AB0777D82814929121BB87A6F4F07880510331EE6171797BDF23850D5FC1802E432B2F51B3CBC37631C9729892B6A09BAF6717E6EC39EC2B3489B33BAF257C35B9CBEFFDC1A1334380FC35DF386116BAA9BAD3A0A8381C4FDFC4B1B98836F23AB923175EAF72C59D9C500E10944FB0FD701BA5142B3CC358BFAF2732D643D0B135C8F991B0C73789C465A7E1B3EA6804B5AB9AB2E42CA1E91158019306855A5767893BCD17E92A41470D721F6432448FBC370C64C3E330D83987F3A9479F000C75320A296393E253A68E0E1C05969784F5612ADBAA2662459B09638202B74D8D5CBD2B01A915AB2AD06B08670546D8B76877B8B2EAA1ABB3132E55D8BD5B08678BFA4243430BB4D059B58A4B0CF0FD26E +sk = BDDB6A1BB704F8B530860B719752402098C84AE4809B01C8EC7583A66A3F4BC290BF2173ABB41868225606D54991F5B547C2254C74391717045997A57BA534A97B3605E1AD9F7C6446AC08BBFB1999179BB8F67731A63CE1C717F30B57FD17BC00605E8E14127EB0C26E324AABD45138484A51A15DD2464440178CA7E966D4D58383F6BF9BB2A971729074781A8D978965F9A51EB2729BA8C308474D56089F2CC869B523C41C409507A671F0F3621E057662454D49C49A398343D64CCA74B7822D773373D5185426B7B3951256154A7B78CB1F5049DF0371B840AB21B83944FB383CC84AD9E24FF42B2731276C1D26B6120534438B029C4AC7C0739453C2860D32ACD75229C63A23A7201C303032BC0A410319035D38A3C9802D41A56A8C6C2496DB10441A2BCD13A81F90CDA2564CC9E4020A47595A30994888B383E996115AA282EAC3E3594447110C2D07774F9312D796C6B74A7634B6C0DA2291458A35D3022BEE048483461CFEB152E1D2CA9195AFD1F9AA82131804D35E739299C539B913C54A0C58683259B3137AA464B9C6E03B0EB751999B6C5354D6171C78CBBEF1B456EC4C88199764A5761D18C0849C1B0A263EA401B86CBA549C712E4A251830F7B6EE16B2BFABCA3CE018C3833BB881385C272DEE151AC35A2C9561B3C1266855219B0C6B485E669FCBC49B24C50C6C3237AA6B116085085405115E0422D956BEAFF9360B58BF915654B9B887AD9733F425A5C6990B3F0223D8099BC0E95C6A5702CF5667209ACE08FB4697D02DC45CACA8074185F54EC4641B35BACD2F0B770FC215FDC171C98BAA7AB6C0450BA6E47A838575A528F7BE221C3C91F02734269A9425A2EDB76CB6D077ED76040A716D39C9C87A58AD8867954C752367A905AA158E0A9019DDA50A6213C260F7BD8A0A6E8CF581FB74CB17283F3A1A8AA9A0418C79A948199365A6A1045238104280AC704B33791E156A2377BC83E9B9C86D0A3D2AA3287272BE6431BB4E598232312D10D03BCB13B4D838A9A624566C6A25FA44A0934AB6CC333E6D52AF3EC26A6FB97615CC3C77102D1A315486BC69C555A3E8271660222A406022E8D97251308A90A15F748153C1168CB133593C1641E164C8A06CC008059C55449413C2B28667B99122AC42B8BFFBC15FE395003249C676DB7589D2896E7405BEF8AC510782FF204454C8A0390C332CEB7A5A3123EB1A1AD0470096058358BA779DF70106E24990DA77AAF09705110993F16A2320A941D8865B387236CB8528BABBF2D9196C15898BF71040D3BA500CB7B1AC85DF11003A058D838C2652D4577306023C756AE9715136E91B20699FEF425E48953FECE15BAF27489D929876803EB0B5764E6338BF5970C2F35D1E815BB5B0B1BAB630138859B729923343C3D24922A8522E38E19868B8A4585ACF14B795FF3A609D93B1A5CCAB08F877C5B71EA78C2819113FB3632D5D995B02926663F2AB8E3A73DD6AB93503192E0243F2593618E3A809684BB6A31674E77802828FEFEA3A50FCAEB1088F7EDC036CB84329C988D965071E97C1311643BB1CA2B43CC57C84CD5EA9109AE36DE2801CBDCA3BB6F977959578954AC17D303841D5726631663F12816EDAB5192042D43A4271E44D1546306137A4427130C86A2025BCC297EB36D3C44E7CD4B0B1C22005FA702AC12569BCCCCAF6AC9256A1693C8B677C5CA243B9C8556CB3A268165596FD0470400CCF5E3B56714792F7A87B9E03019751425695AD70E4CE0B2769571901C6C2003B58152FA9757922BD28A094771B0CB1DCC73741B14B402E8AB86DC0F647525C131E9AA1A9729075EBB3CDEA4D31F6C3B23A5BCBF74A3C653D4C015CE5F65FD1042A137453462B8710704BEA463204C463273BB71056378850AD28F37EDE664E38514DD735BF9AB9B95D367C54D84FF085650AD33EBBC982A329C6FE3A516EF387BD0A0417C2655A5476F51A68CBDB4AEBC53F00C11E78E5BA6692A516C076330C20D0A09F167BBFE1C956A619825A8305D1AA9AC5736E6D24145924B2409A8688B41F33A181A9E4858325140A797F2BA81D50F21AF88650CD0BA8E662077708551A947C97C0A3355852A77576CA5B054D3B0B9FD973DADA618BD02FFF1CB59EB56B12C71B24BB1F02E27282D21281493AC7D07A20B124AAC30B7BCB8C2FF24B2C927D3D62ADE0357BBF7C1281FC94DA2B21D10A5E5EE07A3FD9CF93E34615B871C8DA7DB5441020D0522C12711E1963BE54739BD43949999083115988A09C6020CA88124B35C34EBFB0743B494B2666CCF5B5235968275FABCF9A054EF92833D8EC816D68C07FC53634A02CA192A411C87DD1F17FFEA094B6868638716CF593B33483591E4049E4E7C65C8618B242B17D6021BF0A70C7C59BC81C34F5441B063B9A1D95481E6529602B95F874BF1C649D95A072E70A52E9252E1DD1BCCDF64332345355F7CC48EB7DD1AA2F2C31AD1FD58B8B3A711D113C270A90AA2C5C79958F3907AE3BA071AA6144B88BA6C5575BDCF5331729A65D8ACF3DB97ACA4191B72A2BC1433FB3483EFFF09698C291DD868275DC5A86D06D97305BA596515E434A8D956B2B73B3C00821BA055AA7541E4F35896113ACFD9320FA91585F3212CFD5B023A77D7C5C0CEB746723C2C7D7417BFB740E4BFB2299B29F987698EDFC1B8D7B33DE2C80D0CBCB44F05B1DDBC667005B6E4335751AC281022CBCFAC0A55226FA69CFF845007B9A16D2B6BAB3135B325B12C263A81FD423120A6FA639910159B693406411A289863736557A028BBAA23E0C984F04543E61916D9BCEB4F64FD48823A4B13E4F83B43D443F62ECC72FD304F71772CCE318C1DA9A57A67502A1119313B93C4A66D03C2316C2CC5C2285B1E80C413B2F29C447DC975923D9100BEC9DB958ACD7850AB0777D82814929121BB87A6F4F07880510331EE6171797BDF23850D5FC1802E432B2F51B3CBC37631C9729892B6A09BAF6717E6EC39EC2B3489B33BAF257C35B9CBEFFDC1A1334380FC35DF386116BAA9BAD3A0A8381C4FDFC4B1B98836F23AB923175EAF72C59D9C500E10944FB0FD701BA5142B3CC358BFAF2732D643D0B135C8F991B0C73789C465A7E1B3EA6804B5AB9AB2E42CA1E91158019306855A5767893BCD17E92A41470D721F6432448FBC370C64C3E330D83987F3A9479F000C75320A296393E253A68E0E1C05969784F5612ADBAA2662459B09638202B74D8D5CBD2B01A915AB2AD06B08670546D8B76877B8B2EAA1ABB3132E55D8BD5B08678BFA4243430BB4D059B58A4B0CF0FD26EB86D5B13BB8B72A9FB81245AB712F0D10F0E2E09B222143C420E3F2C3ACEA27B248C0A21EA0BB6D6F56F12300E8584D8E9A34E0E6F52227281151AE4C305FB8F +ct = 62CF02A7A2D09168AD13B88990D97D6A9B0490491EE43B8234B585382834B03FBA539DB1958800624B86051987EEAF09091C288F6564383E1AA98094850CD37C2A695D8AD8548B12FDC9FE827C63A360135EAC409C76D0A8B2390A64F012161A2DD3AE0DA8F626E2F5E053520C6DEDE4EC8D64B045B278B1E140988B3A13DA6ED4DE14513E04FF00EE7B07A05A79CE27FC8A183582F2F987B44B95770083CBA46A2E2DC384754D0ACAD94FA54EBF73568552318EE862C87D22315A7BB4126B2ED7D9E190456EDA589994EAF5991253A191FE3D7156BEE8FCB9A02213A477339507BF4A1CEEB0C64AB07D1B9F3A492437269FD8E932077C80EA7E3701F6AAE89718C2C96D6C46244A3A1E760D0E758A47A5547D403DEE7135E876345D0B725E2218A9A004C567F5BB00905A00039C3B6850CF5C8EDDE3FC1A4118118EF1EE524D312BF82C3F9A089DABAD769C4D459C414F06BA28DDD48B86E079367FC77285AD70D0ED6E46BE65DCAE0FC2A68312397B8E2771EDA4911E4C09E88D0F3055D01DB4B3B1ABC968EA78D8784CC0A0A429490E862B3A6FA629CC335873B55E88E5A0F320125BB16C621C4CA6ED3C69DC3B190D595EBF8685E7A22CC63451209D29413E7260DA471B602F9C7203877D69FB0DB331BA950F0AAF45C8697704A3A641CC04999907D70BE17EB56D316D6F196941E130AF65B0C1E4555BBA7A2C69676AB4AC7CF9FCBE9B498C46998A396A5175F06D31887DD119C92A02788909AF9997FAF43D148E4B00751249B6D569D16758503EFE6B808C5909DF65485AE901A32000D0023F034CF9A20729A7901049EE12DF1A1611F609F060DA51B0016A988054F5805D37920BB7DF00E5E7B99C19299567CF93CA8A9C13516C7B8CE59E0A71B6BDEE58290911D9B44A26D1C48400DE5C246AA5FA3159324BF31DFA3D1F223FB2472FCC0674D6FC19B0B730F2BA7DDAD33428A78E087F751061C7E21AF59F3945151DA4F97BA65064E8D4792FDB1A29D9B9ADA763A0F743CEE9A535A19A2260258BA86F21F0874A8782F5F36883369A655CB3D622C8F828EE4ACFE15B534B8D81775E0CF0C77625A2965C8820D1EAE140D940C1ACB3AC9C216DA291588C8414B91DA8E08F5B192CF007CED7F1B1110670F877B4F8132E6E53B3D47B4147129407BD14AECC4250BC5F054E3C25B255B1F15583B4DA510347A6BFCC5C0C25200D9DB9ACDF58B1E2B7EF968D1D18DE9C67D05BDF49C28D8FB4845CF634E490DE1E99D8398123C9730FE0CFC63B5E34B3E7D73A970A1AD1C963E442B9528D8530DD38A6DEE6FD64C24093BB650E1D6A9C79C05A9282025185DC4A08BBC50F1E335931490638283EFCC4618F2023F06407F70F076B30A7C3A3799967CD707E578A2EE156CFD9249852E5EDC08CC27A1AAB18A0846D066E61596B928BB6C994CEAED604C0ED5B42F9AE38756E8AEF19C47CECBBA7A56FC7EE51E394D0B8AD32DCECD50031C047C519CCDE7EB20E61D8944D5AFF66626541982FF2DA65F211D85F5E89D8BA +ss = 98498206D1F4D3C94A054C3C3A6087760B210D2F3628C71CCF3F0ADE9694ED7A + +count = 35 +seed = 4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4 +generateEntropy = b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +encapEntropyPreHash = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +pk = 38E84DF3C6A2DC2389897C3745183E08C1681B5B9F57C16AA2C12778528510868964122C1747662CF97D8B0353BF23693A70B3B2A7C8CD5C5508A227261CB7C3022058E318D3DC39E320770724351AD78010EB423FFBAE6714999226895AC23735A9119622BBC0811516D617353C7F769628925BBD49629FE0AA333D1909A16C5C27604B7DB0B4E602AB27987DF23C3718630BA4C2846444B83FE914D840CC8ED79A85B645A32809CA069FFBB8B3201131CB129DB9282B73174F8D4A14A37393552B109D2271EDDA8D968AC3FF67AA3374A2355C2EC895441873325DB71C91020E91F19347D965F1410F606862F69643216B869673B5A70583FD1218639B5036CC11D051A13D219F3969C817326D2B60BA5C13CD8CBC9313AAB478833D73716A2A48438FC529084C241BCB4FD67179D1F5494B4BAC2B05A5767B9647EC8829A500D1365BCA7B8CE7B75BFEA0C68F8A28EDB7BC4A3817C0D32C4E10169832B9ABE271CB0B473AAC2C3DD39CE895551A297A61F47162D97C41F051D48B62E5A8882DA62FCEE16EACFB89B98A12AB626E69D77CEB3B6B02878CE346AE5CF754C3F6097E0B5EB7AC80B9B8CCD9418F63E545D01C7D17A71E45EA3A6D927484D4976CA936FE392CF2052535C201DE9464008C932617CAD94085C5816AA41973A8D21610430AC4B3080DD480169258E65B53E340759BFB70D68B15B868C4098847901A6B255938ECD15D5EA94232B2971E3BCD56205FC6F0425F50AB880821F56C7B25F51F2412CD7FA023852CAD04F2704D4103D4362E965473ADD3563D9B36E5097C982506865454BA30AF132BC17C807309723847257C697C525E27CC570A88A1688134F4193DB67EFF018F54751E578483A77A119210106FD03066C403B3303CE54B39493323C4334D4A7A20AAE04D8EF529A15CB7D0900FBC4236C717310246C9CBA14D6874BEAC61B566593B5EC5887272B914EA655D254D595824288A666F10C7DA583F933052F43B0B0FA59248B0584F193AD548A12A845FDF14A73A0A37ADFB4D1845AFE6B56EA50B00A5503CB542C254A26F456AA3286B0126350272638EF0B4A3ABC56FC8D0AEA2F7396D97B64C56817D58C32103996DB88345D377FB7B2644FC99A24258C50730045B897AC908F7FCCB81BC2B51C286899C8C499C1757C6B0A6AC0A8482159D564CDB746037A1224CA72177F79ED19A398040426664ABFBBB7B7BA99906E7982B665A551881E0F02A97409A3E2ACD37FA96A4F9293F786A11B21E1F0BB22CF400DA06081BF68111A9BB64469487D4CBC10578106B381B8B054EE29339E1830DD613E19A9BAF9A81C2B9AD1D121A47D40234BC9D4B79C2F5F165BAB5A2DB68C59C0737E0E4786990A92476AEA44105F3C77FEEFC342B458E4310B9B110A8B2C01593B512F069944828A3F6A219354BBDBB1C344F24AA0784160CA704BFD89C4933B6123C4434CB9A6CE16D3F042F1FC571DB728119F6A33E4A9F6981193D60BE6AB916818B8E1FF9A1D1A59DE8824F808043A1949A5520B675D8834EF65C1D47AFDE2710C6B63998D43AB47A681F0A856D166C24494081E076D5FC05B541145D3155E232A5AF0AB96ECC0B09C2C41E285D350500A4F8BB32E99B4B05D558EA7918A7881BCF516457AD2C3AB72EF2E04E3A4ACB85A987C2 +sk = C6389F081CA0932AB66F658046C1278B38BC42B5C4E1A7C7A51B09D8A159773B67AAE1C2AA8666000C6E6A014B5C0369DFF147688AC6FD48C73D783E3025C92D782A479ACBDE8A7548384B763A868C46178345A773A9852016B9FE765DB0BBABA5751E8056B7564C53FEE8040D3C0125115D323C62A3F0A2B518330B6CC4ABCA84F62C792D07C1E1A0BBBD7C5B9A698CB683981F8828EE69912600311A0281DBF9C6C9E69DAA26A446D136E8B0310F236D7A5A49B2BC616FD346C3462AB09544998C8D5EF641E7B48C35BA7A68F25414F703FB02B501C69C58A9B798C8C76923272ED9BF432208BAB30F2DB45E1CDC56F6EC11792A33EC1A62B3FC992441527E63328A46003DB49B7DC07F73F705CA0220DE94BEA4967213D612B5A03B2C16A9BD4C66E0AC893263169A87AEAE67843944628E6374B5518BF40919840B8E6C64172BE3A35EE5A29777C035463380203072EA50E7DAA4F906D01C502560621137B91649C97417CC2D3E1677006226D4621073CB1AA213525199BBBFA78F1899A53CB2B8D00819869867A41B2F48C615EFE2C8DA15A4E6965BEF0C4207A499A2156EBFB611478182D85A71C9F8776D28051D1A6E4A104E54615992E0595CA9B0CB2A0AB0159575863F3145B3401498949502B2EA4392C77728215F8700C93F5846A1A8126EB6B72248BD1047BBE62AA58737268428509E53575F945735E75B42DB2BA2F21B24C990A847241D2C3533B10D50847C85D98143FBB2EB5138ACCB055A8B8BCEC8AFD7B5697306165AF982190821A14301EF0A90C3D829ED9035430725A99C67745CA415600D10D7C29B228998D7402EFC1F0D0476C4D74C34754AF9A1AA1213C9A0198065378DE2D023EB73B3A4BC5801D98213AB7040CB63318B8395DBAD6C7C604760CA679B301AB08EF1A948A5A83DEBB39651310B368C736A56977F78AF0916364F278A4E3973374213F7A28BA70296D1916FC65CAD3B33C4E1597F818CBC489BA970680999C373DBC246740C07D97C5E1EA5AA1D627757F4467E84AB9C5BAFD9BA484F1212706788CF5AC1829C7FF0A66F26C30AAE327BB7E167BDE95FB5829340B187162A5FDE3A7CC6A0A05FDB6F26902BDB0C6C4F75692E67AB1C8B1B46A40E53FC901DD892A3E612AFD1CB2CD52BC5B0C3191137E602B0A5872D3A961EF7168990B634F438B744375D75995943CAAA47E3CC5DC634432B6CF2DB29B637A5E22559A59971BE46004FE2A40F7C330610377A5B0EACF79D85F3C86223A4C90C31C2495314748601431FA1F49ABFF2575410AF33F7367C5540084B75D6736ECAA010290839EE2456EE16BBCB57C601F26AA104916254A689C24CAE98296E4BCEF8770ED7485511F55A46C75592C88D6F76005356C397EB1E61CAA04BF55A05C8409E644055759A7E60C1C8210221FB97780B92C2C8AAFB6B94C259A9CE6291E18A801A82456B93C221A625129A1720328F11574A5C35C3650A7B57619C61F47ED6319329F118F4C31358A26A7E9191CAB61012A71B27B47FA13CB0B2C959D913A2F4BBB3D106AB695A4C13D41256A0B442F0428DE78F90609A11B8CBB475083712539E1AB034903C30F6B73BB8229ED50F901B142A597E7FE48B38E84DF3C6A2DC2389897C3745183E08C1681B5B9F57C16AA2C12778528510868964122C1747662CF97D8B0353BF23693A70B3B2A7C8CD5C5508A227261CB7C3022058E318D3DC39E320770724351AD78010EB423FFBAE6714999226895AC23735A9119622BBC0811516D617353C7F769628925BBD49629FE0AA333D1909A16C5C27604B7DB0B4E602AB27987DF23C3718630BA4C2846444B83FE914D840CC8ED79A85B645A32809CA069FFBB8B3201131CB129DB9282B73174F8D4A14A37393552B109D2271EDDA8D968AC3FF67AA3374A2355C2EC895441873325DB71C91020E91F19347D965F1410F606862F69643216B869673B5A70583FD1218639B5036CC11D051A13D219F3969C817326D2B60BA5C13CD8CBC9313AAB478833D73716A2A48438FC529084C241BCB4FD67179D1F5494B4BAC2B05A5767B9647EC8829A500D1365BCA7B8CE7B75BFEA0C68F8A28EDB7BC4A3817C0D32C4E10169832B9ABE271CB0B473AAC2C3DD39CE895551A297A61F47162D97C41F051D48B62E5A8882DA62FCEE16EACFB89B98A12AB626E69D77CEB3B6B02878CE346AE5CF754C3F6097E0B5EB7AC80B9B8CCD9418F63E545D01C7D17A71E45EA3A6D927484D4976CA936FE392CF2052535C201DE9464008C932617CAD94085C5816AA41973A8D21610430AC4B3080DD480169258E65B53E340759BFB70D68B15B868C4098847901A6B255938ECD15D5EA94232B2971E3BCD56205FC6F0425F50AB880821F56C7B25F51F2412CD7FA023852CAD04F2704D4103D4362E965473ADD3563D9B36E5097C982506865454BA30AF132BC17C807309723847257C697C525E27CC570A88A1688134F4193DB67EFF018F54751E578483A77A119210106FD03066C403B3303CE54B39493323C4334D4A7A20AAE04D8EF529A15CB7D0900FBC4236C717310246C9CBA14D6874BEAC61B566593B5EC5887272B914EA655D254D595824288A666F10C7DA583F933052F43B0B0FA59248B0584F193AD548A12A845FDF14A73A0A37ADFB4D1845AFE6B56EA50B00A5503CB542C254A26F456AA3286B0126350272638EF0B4A3ABC56FC8D0AEA2F7396D97B64C56817D58C32103996DB88345D377FB7B2644FC99A24258C50730045B897AC908F7FCCB81BC2B51C286899C8C499C1757C6B0A6AC0A8482159D564CDB746037A1224CA72177F79ED19A398040426664ABFBBB7B7BA99906E7982B665A551881E0F02A97409A3E2ACD37FA96A4F9293F786A11B21E1F0BB22CF400DA06081BF68111A9BB64469487D4CBC10578106B381B8B054EE29339E1830DD613E19A9BAF9A81C2B9AD1D121A47D40234BC9D4B79C2F5F165BAB5A2DB68C59C0737E0E4786990A92476AEA44105F3C77FEEFC342B458E4310B9B110A8B2C01593B512F069944828A3F6A219354BBDBB1C344F24AA0784160CA704BFD89C4933B6123C4434CB9A6CE16D3F042F1FC571DB728119F6A33E4A9F6981193D60BE6AB916818B8E1FF9A1D1A59DE8824F808043A1949A5520B675D8834EF65C1D47AFDE2710C6B63998D43AB47A681F0A856D166C24494081E076D5FC05B541145D3155E232A5AF0AB96ECC0B09C2C41E285D350500A4F8BB32E99B4B05D558EA7918A7881BCF516457AD2C3AB72EF2E04E3A4ACB85A987C285441CBD71C18717E9DE7359B920A9A3BB7F32E619806F4E4718C585085BE6241646460817A0FCE5836BDFE124A7448E7ADF7B8ECC2652AC6D280E986682DF71 +ct = 47F3F5F8E8ADECA6F32B9692FD13D7E042FD9C7612634D5E3886871D5B18006B8BCAD0E4B8E91BF063FECEC9E54D10A2980C24369FF8ABC2753EC4E45BFB30FBE64CF5BD5B53F3101913B558DFEFC745D3C5CC96C1D71607A933E98314C340330BAA8EF4A08916E3A2A98177D4C1FF6C499BE66949A14D44361383E6A6C23A5E2A99856126BA269BF386889B8493CDB375D27AF17ED20B504E74F2A9FE4C00DE019EBEDD147591F8A53266C56A9ACE2DF3DF3CF0182596D78B07A67FDB0745CB0B6457F4467A7C9563947B2BD0B112819AD2471B8019C3AEA82ACB84954717CA91FB62099AEFF49F81226704B8D268177FC77A422CC951F1CB68D25028C94203686F3A43DC95611AE78FB30BDC987992B9BD810C362E29C8F8C4C50B94A4DD640C70BBAF28A2C77643400848B0EE5E4991CEAE312F0EFE2FA0B90205E170F44F8708CA30446F83DD743989575425F5960F30CB8A2A36EA62E9D2FBA6F13E555366191B0EBC79C0F8D0CD0E2F25EA617370675CCE484125C7B6699F3A83B265F43FFB29C72499A9BE90AD58660FC69435EFDEE5C5EA405106C09B00EA849FD9CF7AB0F4B55D12690C1E65C4F5369F32D337E319BFAC00D8D8EE8FC4697A5248C096FA4CCF6D95203D85D9E2AB4EB1F4953B761DFE76DB5D987EB0167A535C43AC756A68E3D08B99E71182F2FA3D13212671393DC33DEBCC3F080F03317128ED38CE785C3ED0772CF86FC7411BDC840AD1C754AD6E871EEB8ED6927EEF33148D31DE4B4B3EF5A7F0885B4E9792677480F518C250172D985981CECA7117B79EE38C99092BBEA8FA1B0036FC35BA1DDC545130BC23DE8EDE4EC7A2908A1C8D3FEBD0C1EB811CDC90B74BE2C0A4AB7F2D75828D0BB7F4DDDA80813D381016795F49045F31C0AEC4FCAE74134F5E799C2528DB055C1CB3C748ACD9DEA26B07A817594B902A76DF4AD66F641C65A609514BDC608103609387DD7BD80937B791EE7D14928EC937C6438D62E7C05EFC089D3FF646E8C04A03BF00094E3B04DEE0B81EFA2660392F03DF2CA7DA4231EBEC0CEA1C57599FF84617E3458D40A762BCA1DD3C777BC790B7C366980B8D2FB4183FB71B7472E448878D7F50BE104657302EA90FF27AF7CE9AEA771D7201C8AB3EE0754F77452E8056D96D4CDDCB69C1458A5117713DF0FB210E98B8270F378BA4C551CB469B10014422CF48009AA936A5E0E63847235214AC5D62FF0C4628793D7C4B9659967450ED3E1365F946A7A0445590D260FA87CFEAB8DE4F2BE784738DD534D0C6EEA04691C21396A406FFB15006D4E5A19C137D0776B63FC37AFE8618D4E10208823DABFFF3C80BDD953B758B89E81108AC146D05547C2E3139ECF4E2F3FE41125AB7D5BE50CDB427D46C2768EAD3940D3F4CB701EB41DDE06A191629A3E94082F203B2736F6DF03E206D2937860235B6E4DD1F8AAA4BD95586CFE18BF5FE4522D5F85E77C0FCB472ADAB84DF092C4CEA53D14E0FE7703F3FF8787827555697CEA6A8011E4E525B8BAF1ABB6E216DC617 +ss = C93350D1F27F771801B7C3E03A2E7672146809D37F33BA262E9E0CE7809B2187 + +count = 36 +seed = EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074 +generateEntropy = 056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +encapEntropyPreHash = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +pk = BE390596BAB505E51B3FC147AF616E0F94506635A758964B3E7CC067B80827DB21DC87450FE1415EE41FCA8A2B56B355FFF13616622FD1A19A7CD98F5084610D1AC9F1B8A6E78CAD9281A0AFA5A7C2A9A87916710EC9C5B3544B76B4808D01399F219B745962536026C79841F11961B63C10C99074EDBCB4ED786F7E8C3826609533E5BB4CB80F3E515299EB757C217DA2806D26664F154C0CC2B4A644B224933502ADF5A66F5B54CD45A71589219AAC65BE0623CF5B4C0DF17E72CAB64B91BFBD903D75E164E2A0C9E2C997F36A0B432177DE617F5E6746BD82984BB9375B4A0A12E96D06045A3A984667D03D8C08CD980B59CB2B0983B13F9C53790FD43653E78255882F9B0C980EF6B062789332A6B67B2B78E9E370B78181531846B9980A8AF905FEF403F47B891A6B440EE71CC5D6BF3BA5C7B087A31123AB61EC9F2D0C89E1EAA7DAC36613A15F147938D32673402164B001975D9C4A8BA5CE84D20B47F26EBA5909183C6FE1343D062389B9B99CEDD21E30D5841FB68F3450A47F4C4BE5E8C413C37EA4D5AD629141D7430938158CD04492BBA8AEDF7477ED13A0B97C8217A300DFCB22DE05449547626D21409F491098162D7AB477E3EBAF0E15124F449F08E47D8EC6847A0AC839BC5D237B3D509A8B5C44C8FB6705A467A3D4D9102FF2B6ED976CA9D856E9F257D5D586C7D8A4C2617DCA73AAA65719A21538D9E6997C5637DF8C5A2AB98A169A5BA8F708BBA55F2C0A9463C9B4EF0C9822FA64ECC72C8BDA4030157BDE5073FAE6A6E6F036121125DFC5A9DCA1504A1225E6DA9DB4D0665F6413386153AE25BE78B3410369BBDBD84A86C6C7BC924DD70005BEC0C54E07B4ADFA2DAEB8265DD98BCB8968A2F683A3B07633AAA0290550665C01FDEB22398ABA31140FA7494FD6A0087194673F51AC7D759D649A2FA4D7520FC67138F445287B681F5C3D1678B497129BC6624163E3515C8381E85C173D6A4CC0038DFC2064A213C557931E2E7138FA1A6BC3EABA08965BD803BD5759332CB1BBC4C41337BCCCA153905990970C261CF63A53204B6F8CB228D4234F08837425A82F1DA9BE43775DF88A20A0381F70044C76B3524B437CF365CB131BAA14EA6F24502336762C8E126AFD009E1997B8B3BC20C246070DF7B33BC9A7BDFA8CCD576925968915F186CA4A5A4934528DC75282E246B0824EF7118D39DC1F07449A218836D47CBB7365B677EC7D6222ABAF33068B5730D9E674CC008125226CBC5382A76A9823DB1B42976C5C90C23BC02EB7B874DFF93699E6035A838B22A7126AA42D62682505F9BBC77143DCA061F5C38E99652FC2E28E30CA8D62127AF02186BD9C95602992E20BAA636AB050AB870B11C52DA19B3A68B7A07A8CFBE7BB016A2537E50464265FF6F065D7A8C30F659998A35D79032F887B4629D07BB2DC895F09AC0387CCA9C5CD1AEBC08A687798721F24CA43C2C5AD42D1B6641838EFC2A72EF210BAD10218846F25DA336A4C00C4A29EAC8A608F2261B8C76B18F10B7ABA755771376DC7B876152F9FBA5370262919511D4AD50D76AA5CD6566C29225DABB3B668608D9DE5BAC08320CFC3570A0AC8DEB4BBF3D941F9325AAF546FC368AF005CAAB7AC6A7DD70D90506DDBB5F53A83079ABA0927BD52A68E278D3F01AC19EBA6BD +sk = F75196A57024BE817EDC544DBD552F6B42BA121C2B8EA95E55017856A10C5905A8BB2590E63B449364802C6B438FC19EEFC875017ACF652A8F0D6AB0F7F5ACA1F1833ED3551D37419D906D2B55123EC14D5F109ABCD9382E990628BB30D882CCA8665957346C3A08553C870D32F77E66348CA9DC321960B7D50B09DE64178411439C021899F2B8C583762043A4508C3160544ED2264735C600A6AB43C8515532130583298A11450AE3B7C99FF559A1D33115DC2D2489934518BD52FBA1CB9A019D918464B59CC90941599253957364DCCA9F95A08035F8BE5BD36DB6B19F1F191A6E4B7FCD493B7A41C90BC76FE882AA0F3B39B6F454785C5DD1D106C80960BBE5846D90BCDE837CD277A039DC22427B86A6658F97A60101665F3F69125445647F3BB2D3125C80D89AAE6096A01C24902321933909A8A2925FAA1E7407B3C90C8A53D958C1C83465E557AB620E53509EE8C960B3C547FEA08D4FFA215742113ED9661B57AE1B30BA5768645C632DE76B96161A9B6C34B8DA48B75D176C2C849AAD55C6680BD0863273C345C4C7379CF3F873FA5953F53B9A026A4DC120C96E279085566C7D090EBA276A0928693E639B5564A59C08AEAFD25915F5478DD86E938A11529BB9A2B0B83487C696E79F1FD034EF000FA502328184BE42B8959D9C0683F3BC20E71902423AB14A4744E162F6A2B474DBC4A6F21FC0432CA7422CFB253D0F952BE9C13125458DF8753F5D551CAA38BCCA1625B533051C5226C8768335854E7477064320CB765AB9EB311A1859B4B5A006D918BD8508A971205E6902897CF95E0B652E09030794B46FCF7A784560C0A18B8E6334A57EC177BA56A8BB9A857013C6B9998975379BB04B540015A14A76C658F856BECCA363CB37997BB85B185AA0104063696F1020BD1B443419989798826E141A24A3533494391FA233CF848451CBD609D014508FE137534C42D6F22ED2CB82363C847865AA243CA993B14992572CBF5535845CC708BB09A1E8A7834C200D8036768755AFAB53ABA85813EB859EE83EFEA7563EE4BC158599F0CB04033393C829AEDBDA289ED852E1EB1FEDA9484777051F967E048041BA3C313A1414D463CF3EC36801AAA1AA540DEAB122AB530ECACA30101A1089087311972B338B045A1637189020C3030E63F707FEEA9AF844C7E1B20B4A5348C1A432F341BB9F598B8C0C2F6F55C4D2C2C22B187430748F82842DABA92283DBC4BD20636B6754B20A7127F01FCFD4013A1155E4746DBF3CA1F34991FE7C39ED99BDF5760D39DB8E6C428F2DE8157BE0139415AEA96BCF6FAB633F2257B582312D3C7ACAF6A5F8E55AD699672160CA01246545059E58502E28199CD0F5505ADCB91900A283F0B059F33D1A8B352010A3C815717FB3A9482C946DF0C74A526353D5C9ECD2590C5050996393A02286841580AB599BFBC8838A53301BB11D5FD492AF40BA26224505969D88F6B193EA42B0348954180E17124EC2C64B962A92AA9C3FE2D72F94301531C4AAF847243702BC8F9C37D64B54F20AC003B844C52417E1436D2E75AC09C313C83B8575E791A7C95D0412CC61521A6826997561485DEC26AD7BAA8E065E9A279ADD7301C5C74C5B95C1B6915EBE390596BAB505E51B3FC147AF616E0F94506635A758964B3E7CC067B80827DB21DC87450FE1415EE41FCA8A2B56B355FFF13616622FD1A19A7CD98F5084610D1AC9F1B8A6E78CAD9281A0AFA5A7C2A9A87916710EC9C5B3544B76B4808D01399F219B745962536026C79841F11961B63C10C99074EDBCB4ED786F7E8C3826609533E5BB4CB80F3E515299EB757C217DA2806D26664F154C0CC2B4A644B224933502ADF5A66F5B54CD45A71589219AAC65BE0623CF5B4C0DF17E72CAB64B91BFBD903D75E164E2A0C9E2C997F36A0B432177DE617F5E6746BD82984BB9375B4A0A12E96D06045A3A984667D03D8C08CD980B59CB2B0983B13F9C53790FD43653E78255882F9B0C980EF6B062789332A6B67B2B78E9E370B78181531846B9980A8AF905FEF403F47B891A6B440EE71CC5D6BF3BA5C7B087A31123AB61EC9F2D0C89E1EAA7DAC36613A15F147938D32673402164B001975D9C4A8BA5CE84D20B47F26EBA5909183C6FE1343D062389B9B99CEDD21E30D5841FB68F3450A47F4C4BE5E8C413C37EA4D5AD629141D7430938158CD04492BBA8AEDF7477ED13A0B97C8217A300DFCB22DE05449547626D21409F491098162D7AB477E3EBAF0E15124F449F08E47D8EC6847A0AC839BC5D237B3D509A8B5C44C8FB6705A467A3D4D9102FF2B6ED976CA9D856E9F257D5D586C7D8A4C2617DCA73AAA65719A21538D9E6997C5637DF8C5A2AB98A169A5BA8F708BBA55F2C0A9463C9B4EF0C9822FA64ECC72C8BDA4030157BDE5073FAE6A6E6F036121125DFC5A9DCA1504A1225E6DA9DB4D0665F6413386153AE25BE78B3410369BBDBD84A86C6C7BC924DD70005BEC0C54E07B4ADFA2DAEB8265DD98BCB8968A2F683A3B07633AAA0290550665C01FDEB22398ABA31140FA7494FD6A0087194673F51AC7D759D649A2FA4D7520FC67138F445287B681F5C3D1678B497129BC6624163E3515C8381E85C173D6A4CC0038DFC2064A213C557931E2E7138FA1A6BC3EABA08965BD803BD5759332CB1BBC4C41337BCCCA153905990970C261CF63A53204B6F8CB228D4234F08837425A82F1DA9BE43775DF88A20A0381F70044C76B3524B437CF365CB131BAA14EA6F24502336762C8E126AFD009E1997B8B3BC20C246070DF7B33BC9A7BDFA8CCD576925968915F186CA4A5A4934528DC75282E246B0824EF7118D39DC1F07449A218836D47CBB7365B677EC7D6222ABAF33068B5730D9E674CC008125226CBC5382A76A9823DB1B42976C5C90C23BC02EB7B874DFF93699E6035A838B22A7126AA42D62682505F9BBC77143DCA061F5C38E99652FC2E28E30CA8D62127AF02186BD9C95602992E20BAA636AB050AB870B11C52DA19B3A68B7A07A8CFBE7BB016A2537E50464265FF6F065D7A8C30F659998A35D79032F887B4629D07BB2DC895F09AC0387CCA9C5CD1AEBC08A687798721F24CA43C2C5AD42D1B6641838EFC2A72EF210BAD10218846F25DA336A4C00C4A29EAC8A608F2261B8C76B18F10B7ABA755771376DC7B876152F9FBA5370262919511D4AD50D76AA5CD6566C29225DABB3B668608D9DE5BAC08320CFC3570A0AC8DEB4BBF3D941F9325AAF546FC368AF005CAAB7AC6A7DD70D90506DDBB5F53A83079ABA0927BD52A68E278D3F01AC19EBA6BD065FB6156ACAAC591F1BF3CE71C4A046BE8C6C55EB9A84D29569BD2B144C73E279238A80DCFD7C992D84B2DFFA67493E669243D4FA38C46B090BDF86BC548411 +ct = 8E4B06F53205ECA407728FC67D6329388825377114DA064425E780EE4F23C8CC01EB544DC02C70950C6F2193FBB7959E5459325514D1E76FEC98ADFDA3CD84A8FF0AB0AAC32A0E6C0D184D6B6AE5B020F3BCFA7612A8A8469E3B97CFDA17BFA20080B493451DBC852E9B59055381C382C12B1D8CE94AF1207408F2909E2BFF4C38F7D244182441DEF635C7B46721161597105271DEFFB3EB435F596D88D3B60BF26EEC93DAC19BB52DC05605668D9789EED2CC785112ED45B098D7CB1E26FEB3582FD505D933AF94265B100C998A7850F3A58937E6B3EC8FA19F229021C5441B93FE82B7D20B23EFACB18DB8208A141844386DAA9CE61BE318B0B410AD2C3FEE8B448C649908E282F9D172E62A507F26D1ABE910D98EDAEA3E8429CE1144522BFB938BF0509EF0454DCC4DB999AEB0F9AD283A3FDB5EC6BEC935182FAEE081F8DC6D42CF9DEF8296F2C30A691A2ED84E759A8EE4F3AC8BC3498AD3F7B96C9140647E81339107F1614E0DA2B0F53E0309F19E5FE6584C37F2931BB1BCF93B9FFBEB1A10B0835B27AB81672B2C2E65FE7D1B7F2C75B4247A8FD03F5BB18B0B45693495C5DFA4DC3C50FBCA60347AA9463333AD7CF27743FEE4E0C50D439834192E4F62CB29B3BF7C0CF222403149796916D4067F82BD26F00ACEDFF40458FA66DCBEA64A0C1F885812F505B120292487294D531C077C376D90489B70D51984E35B687C5DA6A153564A31515CFB9E484EE16F2B0EE8910AEFC2CF34E9328BA1DA84F5FA671C4E043BBBC19C032E7A871A74A9BD5F2F3A9722465861E19646E6ADCEEE098FD3356B6A7E356DA59052C2DDA1462CC1711C9B3162243E47E3BF45930D6F3313994FB1CDA44C60C0871AA424C9796AF27505D0B743D7AA1E2D5EA502301116FB607DAF2039FD6DDB1A5FE4D5A6D53A32E7AADC7C7AE0E8EE23F8F55A8643EAAC5A8FA38C1C631DC65F0EC02D3226A85092847AACB7C03A412BF89FB046606CB3B0C2AF16712286FE4EDAE49FC7A0526B2BE181C0074E62E2021A1F80651EC53A24E5B48F5FD20058EEAD3706E40FD8D9F9FE81212550425F2FBC3D2049035B267617696DE3EE56A11B4F6B7D9BC0EE61D570799F7BDA55065BDA83A15A252B1F587628F9D082D9F969A776DED5EAE9364BD9628C1FBD70CD288E515614ADF9DB015387AC8CF37DDB74C05080D993786642243B04F9DC44DEE0EC2C396478F8A6BDF08A0174DE3086A39FB0E555E159E862C997CEFBF359395D4D1EF80002EAB509144A619DE33307411919A90E35168AE2953054E0D2CB5805653BD6A9DE76CDEA4078B46BF6BB631CFAAFF55186F612F4A04B2A9884C9D15D5CE6964DDB3671F63059A5D38DD5E75DB1606057A9FA272263AA2CFD17D7D09989CDA1DCA94B94B1FDC691E6E51D7AE2DFBBAA8D82CDA242A98A78E84F4E3B5D8D9FE10D2503E25B9B3C6E0D9206310B7698EA3435B3A6AADAC0795B5302A653AEF8ABE079E412A2B2182883F4B80B76EA49402D966ADD85D72F1DEC212AA890D4CB7091 +ss = 387E023A733BBA407F35D4456A9EDEC3922B151C3B49C67BF3541BBEE5BDA18B + +count = 37 +seed = D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389 +generateEntropy = a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +encapEntropyPreHash = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +pk = 99315A88D083BF5196F65CCA4541BD4CE3526E514DCCAA8ED176BA58014BD0AC486056240CE06C6C182040606DD98978D6CBA367EB0EC18401ED348743780DDBD277F2BA22E1B34208F215F8F91A048CA497EC37A7663587AC85F221810E64ACF87478A101062535287250907D0854B93A9D4BB39CD5788BE361C00FAA87BBE078B26353A51B7BDBA58D17E5496EFB263DF826A59296A13535ABD799CB931FA5886E35476DFFF97E82870653D5C4BA09C2658A9A22838BA0C6AAA4AB7B19699B8B27243C42634045506762AB1817534F419591B04622C650B828B3D4A66D9B163D09847BD172BA8FF452759184C07B11183665C0185E0A089C957135DCE64BDA52338B6492A27A1238AA567F017DFFA796DE84532FD5BEC8FA800FF4C5E34791CC5AA02901B73885557CBA188F72AB5A35B489E98AB377691033934029118A34AF7D176A436139AAB3AC127A8F510C8719936E8676CAAC2211C8292A42F274C7FA85C542B21422C5790079F34A26F0678C005818BF4981A2B4C7DB780C0BD43AD55C0ACDF1AE0E0761D7527813076F3174A1D49C74659A453E09C2B4468DE6F185D5F3C04F2B7E59E05317586E743285E6817283CA11FAAB44271A4667912DF262C0C03843730ACC24E80E2EE0251CCA86A83853E6251E3036714576B1C171A112E7A15CA215F63039AAA7632EC77880B89EF8A45CB0B3746202ACE1D7221FC98AFB73A28A6AC2AE443F16E6072D6B3DA1A3BE5FAC533A9175A5F176FE131F021795F8880D320C6096AB63F53525D01B32A2CA90E1A9138E4CA72502785976BEE4E566DC0CC1F3827733B0A7D00CB58B6B89C5E26D2DA00429A2450E269DA77C46B5C954CEE6BDC0339BA357A9B9951802A255B74A4F4CA1297D124056147A0F8123EB903071546D2C22723367308601A22F199F9588734FE1241450A45FD7395DF965F46574A030581CC714A50C08DA03A51B367B524A2EE4E56752DB9B66D9C6B07702EC23BCEF798D68300859383C5BACA9D8F08B71409AE5552209B5237E697BA55328A1693AF7FA0BA27020DE2C35F643514DB292C061C8E2085D06C101644C94D17C07560811C093AFE61C6B4FFB970382CE9FD25F76C6728108842B3841DBBAC62504185EDC32DFB817C45878189A7AC02859ECA77AB445797E030E910243B121A859A05D8CAA3C32FA54D033714D20A771C7CCA73999F6D91D4DB4683A9543D3C978F1D56816D75590642CD4AA7D9E9C709C6CB5AEA8832D7C84C576AFBC837B6615B8290078E2C0AC9A8CCFA8338B36649B9F7C41D0064DCA53B8FA1793CBDC8F7B75306F19C4127A214E5532884274646B91F49A1E36A3B42CFB90B27425D2645C5ACC2482289D0B4B84A6359007F23B9F528718E6C499590D6BB2A5BB674E89561AB1A48E3988927AC41D05BA143799214701B2F6D708D365BE84BAA60DF8BF7D969A425C93452A0277F218790C80C60B4B59FC6131E7865D1135AC84A6655507C1D98F6665C932093D61FA578E7ACBFDF49F2E15C138BAB4152C005ECC44FEC299094A285FF50B09388B6AC3972911CFB8ECC9F0EA58761741ED23CE16FC02AF5A341F65043F0802C0353D987C718FB72D3D922CDC861BB6A8AE003197C8F9C878A367C021DB7E9273FE2E03A2716683DAB6CAED5C770F6E7984 +sk = F8FB5BA9D24C8681558CD13593F0CEBB335B6F65BD5DDA6DE6D19E09F15165051F981AC6472B263CEC43883A79149707093066FC129AE148B04F860C2DF119F8A51056EAA5DFD89BFC564226E56DC391ADE1CC2A1DF58EDD4572C5A147BBE21283B97F1B213BC276A471B63A7DF1CDC86C7A69A34ED17A425B37AEF969C1CD079529BA29A2E2C3412C5615E23523F3124C00C778752BB9B3677B90885CC21B0E257BB7F335FD53928B737D19DA3B3208219E6C898E96B45F801135A09A1425A0986C597E2B4042C1A4E6D7A4D0E30E729C73F2BBBE85B579C3C13A34344A7403B95D425936486C3B602804C08EF6F5AB22C400B9523EA3345ABFE666023BCE6A1B63A872C33E3AAF0CCAC2C40A4D5A48107D0C7AB09001EA67CA6F4C1FA7137D259C860D032C396BCBCB4177F82439852463B640855CE604F91C8F2E4A0899B2102C6059DC077D5EE6054355C546C2148077B8DEFBC313C71F1A420DACE126B16C21E40064E2522F9E224CC8E3526B1A99A2F4A81EFC2DD3609043246D461C7C1AF025B56A9C7E72ADEA57584CF044C2F0BB60352C32400D1631C034572EE46B71EDBC0334031AED7BC26AF543028C3918109DA52A6ABF3217A2219C0607BA9EDAB5B4DAAD5EC7948393C4A670C340688541AA713B596843E5CCB9616B54E92610539BFD39159FAB36D4928EE9CC8B1291AC0134257E242FAEB595100AC113AC416FF517866021B550B6D063512DC37477117D025964C95C13535C2F09A96740037FE1846EFEC4446EC03F93FA6B6FD8B539F0196444A61823B08CB74B7520618C08324F0667F142BEB3A34C2C5286B3D159FCE3B046079F07E558BA28A8893A8C94F9711C227FAC6900114C8BB6AA5369B059DBBCA008482A1843B62A1B06C68C6B2F40BAC6F02B6CAC1633055A178A396EF35F59F1A76543953D3B07E2B8BE217C5D5B1A82F9C080F4119D22275958026280BB8C96626C1D0BAEA6658A29546E09418AAF85A121F8647CB4789484BEE0189B9AB10852C397A2E25B9B15B71EF17440DC3554DB740289BA05111979614AEDCCA79699021F4BC3A4C68B39D0256D88CDD7A24E3AC31DAC35388720671A12A765D705F8429D0891C3E0D8062AD45A0B882BC53016DFB007D1C550998963D7E12FA51C7361D86156EA3A8AD7018C627A9EA18F9D3787AB3B88A27B3F9443AA87AB75EB1364A4C66C50E8170892A08FD15CF2913749D0C61305C4DE45A1BA2550009726A0873C70049705009DC8327BE3610F61F9BC60A26D14DC0C3E67CDAE4B5AC0D5A0638804D6C6B4CEB351F0C19F0974324CFA28FAB704B4677AA3F2BF65686C22100B74CB9AB5F7215452CBE8D6909754304573A9314B3C8362CFC34C6302B3CBD5DC482E76576FC5900B367016C03A860A88744928CAE55413231CA8A5008D210CD2E317D1BB6BC8624ECB83002E66092D8AA77FA0C6766532178A8CFB532C70F1114E5156E91486C3C7658E2A22CF0A77873C944A5A4BD70BA1686146E18B328D30813C9850C3003698C5AFA2082B3425C785200596592FBFD7B2AD5568F9D278FA24C523251BFC966A69CA882E707426563D2E099295305FE2E2A96F968A92E9423DC4A1F6662F68299899315A88D083BF5196F65CCA4541BD4CE3526E514DCCAA8ED176BA58014BD0AC486056240CE06C6C182040606DD98978D6CBA367EB0EC18401ED348743780DDBD277F2BA22E1B34208F215F8F91A048CA497EC37A7663587AC85F221810E64ACF87478A101062535287250907D0854B93A9D4BB39CD5788BE361C00FAA87BBE078B26353A51B7BDBA58D17E5496EFB263DF826A59296A13535ABD799CB931FA5886E35476DFFF97E82870653D5C4BA09C2658A9A22838BA0C6AAA4AB7B19699B8B27243C42634045506762AB1817534F419591B04622C650B828B3D4A66D9B163D09847BD172BA8FF452759184C07B11183665C0185E0A089C957135DCE64BDA52338B6492A27A1238AA567F017DFFA796DE84532FD5BEC8FA800FF4C5E34791CC5AA02901B73885557CBA188F72AB5A35B489E98AB377691033934029118A34AF7D176A436139AAB3AC127A8F510C8719936E8676CAAC2211C8292A42F274C7FA85C542B21422C5790079F34A26F0678C005818BF4981A2B4C7DB780C0BD43AD55C0ACDF1AE0E0761D7527813076F3174A1D49C74659A453E09C2B4468DE6F185D5F3C04F2B7E59E05317586E743285E6817283CA11FAAB44271A4667912DF262C0C03843730ACC24E80E2EE0251CCA86A83853E6251E3036714576B1C171A112E7A15CA215F63039AAA7632EC77880B89EF8A45CB0B3746202ACE1D7221FC98AFB73A28A6AC2AE443F16E6072D6B3DA1A3BE5FAC533A9175A5F176FE131F021795F8880D320C6096AB63F53525D01B32A2CA90E1A9138E4CA72502785976BEE4E566DC0CC1F3827733B0A7D00CB58B6B89C5E26D2DA00429A2450E269DA77C46B5C954CEE6BDC0339BA357A9B9951802A255B74A4F4CA1297D124056147A0F8123EB903071546D2C22723367308601A22F199F9588734FE1241450A45FD7395DF965F46574A030581CC714A50C08DA03A51B367B524A2EE4E56752DB9B66D9C6B07702EC23BCEF798D68300859383C5BACA9D8F08B71409AE5552209B5237E697BA55328A1693AF7FA0BA27020DE2C35F643514DB292C061C8E2085D06C101644C94D17C07560811C093AFE61C6B4FFB970382CE9FD25F76C6728108842B3841DBBAC62504185EDC32DFB817C45878189A7AC02859ECA77AB445797E030E910243B121A859A05D8CAA3C32FA54D033714D20A771C7CCA73999F6D91D4DB4683A9543D3C978F1D56816D75590642CD4AA7D9E9C709C6CB5AEA8832D7C84C576AFBC837B6615B8290078E2C0AC9A8CCFA8338B36649B9F7C41D0064DCA53B8FA1793CBDC8F7B75306F19C4127A214E5532884274646B91F49A1E36A3B42CFB90B27425D2645C5ACC2482289D0B4B84A6359007F23B9F528718E6C499590D6BB2A5BB674E89561AB1A48E3988927AC41D05BA143799214701B2F6D708D365BE84BAA60DF8BF7D969A425C93452A0277F218790C80C60B4B59FC6131E7865D1135AC84A6655507C1D98F6665C932093D61FA578E7ACBFDF49F2E15C138BAB4152C005ECC44FEC299094A285FF50B09388B6AC3972911CFB8ECC9F0EA58761741ED23CE16FC02AF5A341F65043F0802C0353D987C718FB72D3D922CDC861BB6A8AE003197C8F9C878A367C021DB7E9273FE2E03A2716683DAB6CAED5C770F6E7984CED77D358342759291C2BD225B0BD82D659D28A24BBC5EDA8F47975B780CD1291F135CF64B6403E103AFAE34DA038613E2853BBFC36BAAFA3C6A95347193F37C +ct = D3327E35289A936A09CDD9B5FA00BFD73B28FFCB330E1CB018EC9970FEB3CA6EC7FBA6F9F8EAECDDD84B38C52BB98519E52FD7F7B91249C091C7543C142F0898D489F811BCC6F6A8ECC355C1957FE73E8ADFAADEF10495AE5DAE171DEA5965C3F303D9B731A5579089B1C99EDB32BB02BEC73304CC2F3677571FDA0BE46A90D36CB6A2F3DCEBFD7041ACB2EE2110676ECCEEEBDF2EA834765D9984BB335AE06CAAD76DFCD95D385E91C63D18702989B8C739F59B129BBF421FBA018E04B96F5FF08E7C05498681E129A1D84C378DABBE83E9B7EEA55AE4BDD1FE7B5544F6328E82899777E2CF76A4B23B6DF71F76A8F0475B4A587D8A0B8D12FF0B76CB59BAA831F6F7901887FDE2CF58B0661016FAF6BA44CADA98AB984A7BCBE8448C86B1E7E1E21873B034E0ABBC0A9C77BEDD69FA62278C41A08C83AD8B3E3EFC601595860E6ED1A1E4EA6382CB92009CC15CEFE8095604250593032F1E4F4564FAA616191ECFD79F8DAE40E7831C7B23DB7789D9D3270ADA144CBA1938D6FDCB1EDB624D8DDE05CF82E13F422C05883B6EFD9E0EBE538E3D7D6348B205DB5D282AF9D77AAFA42152EE11F58E2773E2666CFB3582C24F86EB8B20353231F5C2A5E91FBE2E40351D48DF2C7207FF2E77AD345DF3A79371E8D5A0708967A979C9114A887D52AF199EC2445CD21478876D097A0CC4212136AA12099FC59D6E2296C4FAEC109516C8464889DE22CBA68DD230BAA33A544C8A01EE58CA60D3199E90B9E2E262C68FABB8E255CFF75DD4280AB779DED376751473DE107CD1499C85D2B5876A4E0284406140692B4F1620BC945F737557EF3ECC54CDF0833D7A7E5085FEDA3275C991B533DFB25603826C88DFB0EBA60A709D3AA4AA69B5C04D455257F9053CD2769161281D6B5C60EF7EF10D10A1D7BA229B667AA9FA7BECA9729EDB18A166D991B57B15B1139F63B25BDB1BEFF61B38ECEC8DCBDBC984CC164D92E6A418F625B59EE736B66C154F9ACDC5B30FC3105E87CB2FF8ACC4A85AAFB2042C0F34C1D04CEE54387251D89AAB11A12953BE99960A5FC9AC1D384FEE498FF315531F50A7D6D4EB58814E224569ADE954316EDA1C2EEA60A39A97361547F82D7971BF27D5EE092BA1ED514552361AE54616D1007C7688FBEAC04AD4E3B9DA9B96ABD4D3A5284E008779297A01234D8C2A51727D9C8CE9715882A948A3B93B87EFA6C9821D439ACCBE562D00EA6298B304795606DEC5AFF0590E55516C9A8BE95E5F2D9B5AB426B294D75A0F689F8CE080CF01080FA1F1712EC169508BB7C49BD8D3F65FB12028437C524C5BDB1A72062D7D4928595B55E86787469B81D4BEB8A0061150A7465D36EC838249AD80D55E6F7B5EB92C62D381093965BDFD3810050A43E7539D556FB4C835C5E4AC6156BCC5E97CA5F85617448822EB529FF1F794C8FDA9E5D222C1BE8A3B68AF5FAC61CDA9996EA1E6B4394E9F7BD74A70C7A766CDEAD893673F7C2B54D077BCBAFF31539CB9836792149C563E52B1D08EF2748515781237C8A6 +ss = 4D91655D2BD77339BB81F82916A1A77329071B3919CFB35CC1D1655C2DA5A2F7 + +count = 38 +seed = 6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC +generateEntropy = 952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +encapEntropyPreHash = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +pk = 2E7240107059C16C3EACF4A1A8342B73911DB6A51D3CF12BB168229A1B29F7C334D0D1AD99932F21BABFD8153BAE937FDD2393D9748518F12689CA7627A1041D868094AA7440C6724B4430EBD20776B602940C9D1FCB5A109978573434DA891962B645002508E46992C0C148F5A039609826BAF5834BA7271C443B69DC5110C4B7089068D16202CBAB2E1E4525738A19C8315FAE806FD139BE91F4C1E192A2C04983291340DAD4018A8A83C27A57C622408F933A51B7618148B16375A80E0A901F10AAF6E7803CB2A693ABCD4CA8BAFB942086F42F6B743937098E3D2A607F212F766603C9D89ACCF7AC584491F230BB1108B1465B865F824215D79FED2525D7E95C7976946E22A9E6510AFA2A9E8AF29DDB65C47BE8820561661050B70EF3B7BB249B7FD0CEDD688C37D7A3DE667626C2B389B38BE066089405703BD51FA32199E9C83D5265BD62A2AA2CE521B69973A18777E32151D3D5BA1983C8659A79AC978FFA15CEAB733B49EA8F7A853D4B06CAFDFC64C9D00E55D814536171496037036A078D026164D7B07E3277B7ECAA770B06DD291B9AD29241C3BB43553BCCF66A1DD81FE2E2BF79F1A21E1539D0BC517A9BA8EDE2C39DEAC4CDB7C65FF96048461BA2E350017095A35C1BFA25C242B000AFFC8AF29495A2D349133C343D680EEA815CDCD89C4FC283CD5136B89ABD473B4AEFE2228F4CBA5E0C10EC7A1083833735F081034AA7BBF20C11319CA263B52262096E505C45805E73619E2CEB242E559883D20DDDD4120F0C9E49F4995376284147CC2D2A96A046BDB3F56B6DC1889976AE1ED732EBA43AF5941831B2202D6091C16B680001A82D98CCCCEC212B79B5A884756C75CB2545316FC072D903C670864D5A13534E545D836276EE594D3A7841E5F91D6B738D97E73A7274671D6470CD2719B0515FDD67C6E4969AD213254502C5AC9BA23C264A375237369B46D0C45745041A20511459D3321EE9B395978F2C575EBE1C6CAED03AFC7027BC457E03F527B0CCBAEC71850E0955F0A2B54D9BCE69B6C8FBF90850168ADAC411AD5C973B578424C55CE01B3EC2825B0085232469968B8A96FE7B9F26846F789323A15AAE6397242A712CD26B0465BC038A4AA30DAC42C0036C062C21C3A4178A0C92B8992CBD54A6044B789D943F1EABB0BB24C3D0D4C067251779374579B27C84FB435E6C745334485FBA84676750A27C520F79366D008E4BE93FE8A958E8D06B8EC323BFD5BD01E86B1F13302EB17AA3AA8FDB3445AE5775111B2124E2A35021C04945661B2C510A29264AD855836C7D8EABC069011F8814934BB4B32176C0B59B04C5FB6CDBC8BC41B0BCFEF4423635C0C7AC43E4D5286C74920EF37C951266B92074D239B2BD0A0D6C096141FB6A718A213A3387D75B927CE176169738ABE0CFA6B68D3B064157C3CB03C5793A7400C1960351B059E43A7F1B28AE5073780CC606F7E40AEB458DBE95A31C23AF7E760001B0BD601647AD1805C4329E46F490575CA928FA908B5A30FD31520C61C9F1CC5EF18578B350A929164DE33B008338180CE41C45327152090A91B8C9B3928C2629A48D78ABD1992720E841A52CA91A15A1C7953D18B4BA1F990AF34CA408BA2D449F94385651C3B4C0503726CAFA118167110E848FBED995526B458D362061A1 +sk = 5B47B61CE23572623C431A498E378C6B71A5CDCCB58E225310217F6F2B1B7140B97349B965D9C95332A66D7A9879F24C479851A0EA485254755DB347BFF9A06D00502AE3A910C06771AACC0A51ADD07A291496AC10E2899B6562DCDA7B6B9B7EB516335D222C43498859D87A44CB8AD589A06E609FC5798CA06744051533D5C6154608C790A8ABD776CBD2984B57E1CF4E0638C77915DD89249D3C0775B45CC159B44BD32F49A51A1E398763E35DBF5C6CCB100929C9B91047A1AB98A140E00F77F5076310C33179A8C80449591C4156C244EB8C8B3009328139C18F8C59E1961A2B91C840D552C2E4B3897265B16C28DE6ABB72D218EF713A1D179CEA38561663C9BF21B68166AAA45748316877A9A5BED6F5230D3015193AA5A9E1B34DC6576B57692B543FFF321B14879A24728DE3D6A297C06AC6CB28EC3482DA708ABAB28FA815272624AF6E26A879F65C6432812470C52DE01EDCE20681DB43A967069DC9BB34F9C540A21B8D7322A3675FEE059F5F655CFC480BA31255E899C48A7C25588303D67055434702ECCA24D31A9D69796DF408328912ADA084AB122C6AC53C3C349C105270C9AEAC73923614EA9129CE4C9FD8D78BD33045D8557AD3D0A698B34A7C073B93783670662F8558375647747905402A6AABD1698D1D3B430CE8B5EE8665771A34CA73B2DEE04497C997C9E74044230690354B7AF23BD94AA02CF599554391095C0D53F5C1DB19AC33189B2B9AA3C48BC4E09BCDC5029BD3B45A370C59045ABCBFB257DDF30085DA053056C17DD0B5DDC6494524875AC189E6C7A7CD483288F03ABC155BC2022EB427B7D5093F4616C124B7C29A0043181C7BDED83DE7592511E3617A75652D4568D7C7B3AB2B7464C514CE6CCF54FA8D73E61834E534966620DC59196AB44B736151A27C02E065A000611542FC296A69A24989331EF980F708142D7274EA863669A52039B59D48B90BCC75CE4B434F5751CEF621CF3A29873C003A57276128E70BB4AA5DE581834946741A8134890491D37B6051959739FA8EB81C6947141704683124136C1C382760E13F00C59AB5BCBCEF98B973831B91BA87FEC02216619F012859FAA6B01B1649786B626348182398226CF794095681D1C25800B18BF33CC71123898AD2AEE46905A8118916BA8651328A051697F8041667789C874394E96A0EFCDA8998D420684217952496AE9117C6C618513C147148979F5C8BFEF8C7CA1836430C3CFB66B17CBCA63ED1A2157961CEE600617157AAD986B5021F4F69C3BEE6AE181A076C3CABF076903BD59814352F4EE2C04A138AE0EB018A2193CED58981CAA3BB032317499E6EC4BC5CFAB8B389467EF295DBE7305BD1CD099364D7596B1801008ED734D7775C5606AF0F1A2978733DD7F55556DBC5FBAACA5A95BBC287B6D3A43AA9B78AD10A025F46AF233512B126230CF928FAC14D753160BAD961BDCC4D5E1B4EDD241609A0ADC6B3C6CC9660E5371D6C1655B4465F16D535ADCC54F8376371B758CACB81D84A7B3E6B8754B430C0753982A89D5CA8B2F4244AABE0BF05F75ED0B092F332AA83808F897BA21906AF25E68A88B61A357A10ECE1977199203E465EF9BC020E145F6421ABD11B182E7240107059C16C3EACF4A1A8342B73911DB6A51D3CF12BB168229A1B29F7C334D0D1AD99932F21BABFD8153BAE937FDD2393D9748518F12689CA7627A1041D868094AA7440C6724B4430EBD20776B602940C9D1FCB5A109978573434DA891962B645002508E46992C0C148F5A039609826BAF5834BA7271C443B69DC5110C4B7089068D16202CBAB2E1E4525738A19C8315FAE806FD139BE91F4C1E192A2C04983291340DAD4018A8A83C27A57C622408F933A51B7618148B16375A80E0A901F10AAF6E7803CB2A693ABCD4CA8BAFB942086F42F6B743937098E3D2A607F212F766603C9D89ACCF7AC584491F230BB1108B1465B865F824215D79FED2525D7E95C7976946E22A9E6510AFA2A9E8AF29DDB65C47BE8820561661050B70EF3B7BB249B7FD0CEDD688C37D7A3DE667626C2B389B38BE066089405703BD51FA32199E9C83D5265BD62A2AA2CE521B69973A18777E32151D3D5BA1983C8659A79AC978FFA15CEAB733B49EA8F7A853D4B06CAFDFC64C9D00E55D814536171496037036A078D026164D7B07E3277B7ECAA770B06DD291B9AD29241C3BB43553BCCF66A1DD81FE2E2BF79F1A21E1539D0BC517A9BA8EDE2C39DEAC4CDB7C65FF96048461BA2E350017095A35C1BFA25C242B000AFFC8AF29495A2D349133C343D680EEA815CDCD89C4FC283CD5136B89ABD473B4AEFE2228F4CBA5E0C10EC7A1083833735F081034AA7BBF20C11319CA263B52262096E505C45805E73619E2CEB242E559883D20DDDD4120F0C9E49F4995376284147CC2D2A96A046BDB3F56B6DC1889976AE1ED732EBA43AF5941831B2202D6091C16B680001A82D98CCCCEC212B79B5A884756C75CB2545316FC072D903C670864D5A13534E545D836276EE594D3A7841E5F91D6B738D97E73A7274671D6470CD2719B0515FDD67C6E4969AD213254502C5AC9BA23C264A375237369B46D0C45745041A20511459D3321EE9B395978F2C575EBE1C6CAED03AFC7027BC457E03F527B0CCBAEC71850E0955F0A2B54D9BCE69B6C8FBF90850168ADAC411AD5C973B578424C55CE01B3EC2825B0085232469968B8A96FE7B9F26846F789323A15AAE6397242A712CD26B0465BC038A4AA30DAC42C0036C062C21C3A4178A0C92B8992CBD54A6044B789D943F1EABB0BB24C3D0D4C067251779374579B27C84FB435E6C745334485FBA84676750A27C520F79366D008E4BE93FE8A958E8D06B8EC323BFD5BD01E86B1F13302EB17AA3AA8FDB3445AE5775111B2124E2A35021C04945661B2C510A29264AD855836C7D8EABC069011F8814934BB4B32176C0B59B04C5FB6CDBC8BC41B0BCFEF4423635C0C7AC43E4D5286C74920EF37C951266B92074D239B2BD0A0D6C096141FB6A718A213A3387D75B927CE176169738ABE0CFA6B68D3B064157C3CB03C5793A7400C1960351B059E43A7F1B28AE5073780CC606F7E40AEB458DBE95A31C23AF7E760001B0BD601647AD1805C4329E46F490575CA928FA908B5A30FD31520C61C9F1CC5EF18578B350A929164DE33B008338180CE41C45327152090A91B8C9B3928C2629A48D78ABD1992720E841A52CA91A15A1C7953D18B4BA1F990AF34CA408BA2D449F94385651C3B4C0503726CAFA118167110E848FBED995526B458D362061A12FDB7C7E39CE1625C20A13A1C91AA5909D8B03B064D00877DCE2415020370C7262D7033947AE42CA53522A65FBAFE18D3BC3E0CB66164E9A094FE4B44D8977ED +ct = 1B064FBEEE1ED7023765654313B62170F23F4C7E4AA5F23C5498E7F5F82A8DB67780CA831E660289BEED5DEB0C8D6D49E8CA85AB1738EF7F0C487F61BB2535730041398D2FB4F2FEB04D4B238C3DF61784F226D31BBFD6D92FA486B344E713506F12F625653380D8CB3FBD2095E9CC32973194561D9F2B6966D17133936CA643105F9FF845760596BB95D12E7F9FBD5DFC36AAC052D64A7C08E26A641C938D83AE795977FD5D2757DFC9166B38687043CE1DE9AFDD799FA18A164269FDBAF52AC4B1DF518DEB9138D55D161018BD64B74E125943F42FF6548B2C673F647237ABB78CB3D87CC9B980C1D5F46B1E73AAAF600B628BAA2FD4D20A466DFD4B3F6EC33E91497280B782E5D4D94DC40907D0CD7A53B99948E8D39C1E059ECA344D697D009EA926E95957A10B401C436A95133A219DEED9BA76A8B87D2A9F6D0FC9CCFA183622F794A1CB29061EE4561796DA05659FCEF032A65613DAB8CFD117F5F1CEF02EEC44A13956FE83E796FC8E5F4C589B8574AE1E1E702A97C6268F34E809BE6ADA4BFA00D9EE7F890A8E54E1A6FD0F33C111BD835466EB64C1622CB349B1C15D648CE49C951391ADAE8380CAD2EF3D615DCCF177294072FFDD678F55AA814DF60B6FF875B28D2FBC3BFE3A2675A63E4CFC60634BA08E6602D449D76B29FBC7AEB54E97550A1995C6A9B47A48E6FF23CB62D35520BDC492F1AC12CCB9F18AF78C92494F22B56C684917C0A768D030426121321B1EA5B41442A791E7FD036F7010C25EB45FBC472F526C82C956F0D3AFCE7C16055FC470C61CC3CA1F05ADFDB3DF3724C5D38D9289E49D702E620ED0749D5C13376CCEC5666E8F46B60BE05D005E1F59DE58C70833172A0E0728A26C6658AADD56A9A1145E1C1FD6F3077E75DE450137166445DBC096733DFC8B8BDEDFD13F2E8FC53432F794BFDC09E9FE2070147A8EB260A4069B097CE368A7171628A6D06E5091A85CAA5D9819973ED338AD1FDF261E8A4C70DB6E78B6BE4B908D5CD3A875F321A24C4D1375AA6A97C76489D005E475ADD32524DE9B64E4468B44CD0F730B10219A0FD481800FA857C67ECDE250AF0EAFF95B43E377C32BE2F794ECA806F09E10EB4B0FB038E07535534CEE9816BB4E6EF0244043E49B2676F837079F2EE3CE9C29897202D75EB19322E6440C49D58E984DD441231A79D479851A0CA63D33E77E3191CCE8CA1C69CFBDF06D63AA52D1CEF72AB7B3F57C179B7C382F1CB7749C197C9BB0B501F97E96E893AC60336C8FA3E97631E770C3F2F544805767E3BA0FAB80020A42CF64858BC001D156ED33336F8207A439A82F07CBEA0D00F5D5942C1E9528034F60875422BA40F0AB503E32E61514ACB3D6F3F3F4AB1F9EB6AEA8BB6197E7EB0E143223532DE74B12834B889BE7DB31B93551CAA8F464E1F38F8F882A252682623459CA11DEFE125334FD0C0718974A3B6DCA46FEB0AA49D104ED96C301537A3174AB466DBB164AD68B59358F0CDF1D8A159CCFB9DAC867424F4504D3DE7BC0D686E24967A57B70 +ss = 3D0D1AD5E2825DB1F539515AF2392F0D212E8166B34F3D8CF2EBE97E51785EC0 + +count = 39 +seed = CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F +generateEntropy = 3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +encapEntropyPreHash = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +pk = 45FC2D1BB1872A743763F12D29D937F3F2A41D257531C1172AF59C90806C7E5A15972A8CB9DCA049BC92700A72B4FA5A739033437C946EE062AA86C12103B557822A08084BE63C4C74D1B92608C3B02C6520B2991F8499470114FB659F89A937A25897FABA6C0DD142D8D4868EE3C6483128241B287CBA0AE49430DD6A28D1339605A4B750E6029F73BAA1FA8CE6219C36A40E5542AB45CC781A613FDF416502743DF8CBB3C4B864D0B448A20C0B0942A829601F2B131FB038587A99B80EF44033061B2E4B8F9A12C3C03193506B62AA1C7AB08569C7D0A88C8A098F87061EE41000FD202E2C3AF4E625B34787BCE55F74AA58EEB9124DE7089E51A581893354B36FE035CE5FECAB74018EE6209B75FC2702429C932ABF71D89B8C82C047D77725CB6ED98608F2BA0B3462C1D428352C6376F6269D9869AFF4BC821870B63F2284D296677B6145683BA6282C12C72512EF015EB19BA86B3571BE7438F17311655C118A530266BBC6D9D10636B6347C630607864949DABFA558522C100F6C7941A076109253B5FFD76328C99590F48B3FC7AE7A5847CC958FA5523F540AB54EA0A302174E6C401341759C121B355C9280D2AB6A84F9028634BF7E3CA90679ACA188667D5086DF35B88D95B262E8478561A414B627F43B0FB8731D3BDA73C6396594694A9F7024CFD55D3AB88342516CB34A922E6835EB8C067BD35CE0B3711D7BAD2D7529464C493ADC40D8EC8679C903E8984850034EF4A828D3FABCAE9474F7278CBE79C8E5C1C948B94798D4C68DA8255237AD8B0B38CD4A8DFDE5ABF6B2CFAD98A677A8C40E208206774661490C3C212D23327A46A23DD6855275B78D29830B23900B13C638E31B4745A917D4FBA95A04956C371212E475271CCF94F6295346118806316EC01D08454B0CD922D6F1A3E4A651A7A931F380042A09244BB39973EC5872C28C8D41C4BCC72CA4409A363C49995C45C7909522128C03814612214A5EB01527B67BCE4463202CC14E31225B36A7D7D10E26966BEB389877AC0062F9172C0517CA8676F5A44A10106FE75A31A4AA86688C075918A4D8A7461DCC1EA1193913C259E3B44C2D976EC67613468358886A9108ACC7D0C6A25F5A991D7C53B8638C24A585F07AA074B5A2CB514BF7178E14112C8B31727A38BDD20A5AD087746768957F837179D50D25F6697F4A88D056451A593E385B74DE8A01CF0244E70AC9AE36B2D76CB91E5419165C6507D141148869D6676F28645653BC78C96B9E7F382CB0C6768E2968C513C7AB076928781A6530CD3AE3286B0C681743A58D9C524BE5120C880605BC139F672E30174095932A000800D58A926CF40873C44AE6096940A3BDB6E7966595BB3D23C9915BC7E29AAAC9F0344C9B6BBB25CB0AA084F616332197295163989E1448784082C327075DACBB7D912025E4786710B0C7452F827ACEDA11A73ADA09C3E54B404419DBF3A8F8B6096A73528DC50FCD230155A97A614663174683D1095D97B7C0E994764DF2095AB7BC029B7DDA3799E5A88ED825CF1674AEE01BB0C17A5C84B8AC1BA061302BA9CC20CD46F769E1021C03C43AB07BAB1BB0C7F3426D252A15ED5A27854CA7B177A6F79502789842E229637FD32A677F68DABFA371062D8B8CE9DFE0D90BF06044AC3A840CEB626B16E134 +sk = 2C021F19322A908456F1677D31DC8A4A2A734A2571D19C421C47AECC507C3C53A931113290B693AFD1B7FFECA87CC90B0419C48BC4359D64146D9932BEEC78766408F59216C692228FE59B768C92F4D5A3CCFA6A35599DA2695766D754C1F682AB13C8966997F37A74985551C36828224C177D3A3ADE3C2C20A907C830BC32906DF70B021B47C38C606EF951ACF7C1512AC15FC0D761C9057A7DB1AC6C56198F9A8ED2F67A0F159A5EE6612109254D57745736CC3CDB634F5658FB684D805888FEA8582135BD4890343A545E4E0A6F0C130B8539125AB06358F8BCC0A4B44A7A4903D018C960CA45779BB564A30CF1B340B4C317CB77DA50BF899C10B4676F3C295B90E93C2540A9E17C3BDE560F351C81C58B545306449585718E9199A6302E3B0CA1E737C07A4B7E21EC154604590D415F4B82778778905360CC2E49BE4B08C94A744995F18959D4492F0B7A3F53A98F9A8D914863B9583D866712FE583FD2677E8A3B8BA5341902178824F4C41BA21CBF7A4B666ACB413C31CFA744B9A5405EFC5B53A2C64481270484134753C1B0407E23B95850A8C026843643E42B329BCBB7422DF5CBB968B04F39210A4EC959E1B5C9CB32A180588B9BAA690F7459B1282D9E9200BD1A0E910A3EFD948C3BD0AF04D866EDC61C866B48D7AA22E6FB5025C6892C66116E271B998B888E0481ABDA592C8B36F7464704FC22C51B5BA995928FE03594A8073AD790798AA304579822255E61D11557092BC9B5BD4C94068C60B2940C180831C5167487B7538C9AB47DC268215C8C7F324563D3973FA73BBAF07C771B15070D880478D2693535425FCCAE0F8272CD7224F3795A70241D480425E4A74922309906E1C11C5107E9F34FAC3536354100F911234D55769B763CF2408B9812AA6B7C2601161953CABF0733CD3AF819F5158A136621FB159DB3DC6C3F3220ADB8ACAA8CCCB7CB2EE583B9909C903FF43612D178C568AA7E9217E345CF4DAA9AAF17CCA1B5A4A5A73CE9B0581E73BCC019BCE2B68C8C273DFE588BA0861C5A73A6EDD9BBDD66935AF04E5EA81A55D62C9A8C51B3E6A402587FF4F837C16380AEF5640F333DB08A6CDDB425CB4189ED773D8ADB91E2708F12B78A0105BFFEE30873C1B6D5D5469F6464705741EC4310A8185A1553372F6091C769109F19527E95A6802C2A49127077B21126E7531A5941298BAE199309CBE00D97513BDE1AC82292CA1A76957D20A306932F83994A00F21D89519E16138F0477667F338A67450E1248A682142A79D9AB6B58B88754362A32AF3402D062A554CA8A40DA0481BA721A9B023DA71987B744C6B9AB5E80830F8B7200241007F0EB72AE3694EE92814DF4B1DB269F4404CD0C77A844D2B751F5A0BD1CB93D61A628098D0EEBC941827F77139831575B98E47B7DC3676D887B56D0AD96BCAA1F280049776339CB3FEF6489DBD26205530CB08C53FB0839B49909864AB06B2C3FE15957DDA96CCDA90C51904DF02C6A1E5846F892A1683838B9760AB900664A1A039B6A1C75F9C4B05340EDE9881F48869DC881DA0191E24BB5AEC448EA052E57E69EDF254575FCA87A1B50E6D39520630688B04328A70CA1A871FFBCB0A8823DFD4747DC859B45FC2D1BB1872A743763F12D29D937F3F2A41D257531C1172AF59C90806C7E5A15972A8CB9DCA049BC92700A72B4FA5A739033437C946EE062AA86C12103B557822A08084BE63C4C74D1B92608C3B02C6520B2991F8499470114FB659F89A937A25897FABA6C0DD142D8D4868EE3C6483128241B287CBA0AE49430DD6A28D1339605A4B750E6029F73BAA1FA8CE6219C36A40E5542AB45CC781A613FDF416502743DF8CBB3C4B864D0B448A20C0B0942A829601F2B131FB038587A99B80EF44033061B2E4B8F9A12C3C03193506B62AA1C7AB08569C7D0A88C8A098F87061EE41000FD202E2C3AF4E625B34787BCE55F74AA58EEB9124DE7089E51A581893354B36FE035CE5FECAB74018EE6209B75FC2702429C932ABF71D89B8C82C047D77725CB6ED98608F2BA0B3462C1D428352C6376F6269D9869AFF4BC821870B63F2284D296677B6145683BA6282C12C72512EF015EB19BA86B3571BE7438F17311655C118A530266BBC6D9D10636B6347C630607864949DABFA558522C100F6C7941A076109253B5FFD76328C99590F48B3FC7AE7A5847CC958FA5523F540AB54EA0A302174E6C401341759C121B355C9280D2AB6A84F9028634BF7E3CA90679ACA188667D5086DF35B88D95B262E8478561A414B627F43B0FB8731D3BDA73C6396594694A9F7024CFD55D3AB88342516CB34A922E6835EB8C067BD35CE0B3711D7BAD2D7529464C493ADC40D8EC8679C903E8984850034EF4A828D3FABCAE9474F7278CBE79C8E5C1C948B94798D4C68DA8255237AD8B0B38CD4A8DFDE5ABF6B2CFAD98A677A8C40E208206774661490C3C212D23327A46A23DD6855275B78D29830B23900B13C638E31B4745A917D4FBA95A04956C371212E475271CCF94F6295346118806316EC01D08454B0CD922D6F1A3E4A651A7A931F380042A09244BB39973EC5872C28C8D41C4BCC72CA4409A363C49995C45C7909522128C03814612214A5EB01527B67BCE4463202CC14E31225B36A7D7D10E26966BEB389877AC0062F9172C0517CA8676F5A44A10106FE75A31A4AA86688C075918A4D8A7461DCC1EA1193913C259E3B44C2D976EC67613468358886A9108ACC7D0C6A25F5A991D7C53B8638C24A585F07AA074B5A2CB514BF7178E14112C8B31727A38BDD20A5AD087746768957F837179D50D25F6697F4A88D056451A593E385B74DE8A01CF0244E70AC9AE36B2D76CB91E5419165C6507D141148869D6676F28645653BC78C96B9E7F382CB0C6768E2968C513C7AB076928781A6530CD3AE3286B0C681743A58D9C524BE5120C880605BC139F672E30174095932A000800D58A926CF40873C44AE6096940A3BDB6E7966595BB3D23C9915BC7E29AAAC9F0344C9B6BBB25CB0AA084F616332197295163989E1448784082C327075DACBB7D912025E4786710B0C7452F827ACEDA11A73ADA09C3E54B404419DBF3A8F8B6096A73528DC50FCD230155A97A614663174683D1095D97B7C0E994764DF2095AB7BC029B7DDA3799E5A88ED825CF1674AEE01BB0C17A5C84B8AC1BA061302BA9CC20CD46F769E1021C03C43AB07BAB1BB0C7F3426D252A15ED5A27854CA7B177A6F79502789842E229637FD32A677F68DABFA371062D8B8CE9DFE0D90BF06044AC3A840CEB626B16E13486BB11E7D9C1368FBBA34CE3A2F169C2464EF5FBC11F73843C456467B6CDBD4E01C8E376FDB140EE343106C093AF7CB149B316BA79446CEB4E5E0CEDB9B164F9 +ct = A2877C3D4B092D4196F99FCAC16B38EA10D653E03446CB3BBD61252A938ABB30F3F4B32127ED8936F48A28B0A5202506E7D4CAAC4A073C5CB940B89711AD903E4C43EA9C783A0082F2A831B5FAB803D97723DB32CCB3C0793B1B858E6F71A39A1BFF4700953ECD249CD244AED4FF748110910313585D19F6562F2B5AD187A2FA5383A55E6ACD134A97DEA0AB34E464299DA2C7D5C25A06DC9728FC48DE1FA9A72CB51E08AC79D09D2266831F55AC5BED2A383E8FCA1E2B402C0AFF8AA8EEAB9E277F80C474F8017F8CAEFAEC1480E8FF37EF2DD6E3A8223CBC0AC6AB488084A257BA0F65137C9F9DFB573F9302168A77A8CD7EC9DF435D0CBE0AB9EBBA107FF2FB8ED9548F816DC367777BB2254F8821F22128B9F1624A6B45CC91BC76D5C57FEFC1BB567A2CDBD66CC9970E08BABA6F8C25C3FBE1AB9703BCBAD4EE3C0316738EEAE7488AC7081EB97B2C7F9B236344DB66692B9623384CC8F6E3A6247DE3A75890CA89C3C56F0CE28CD448CB17C4F4C19E727CB2B3724E2FECBCE57AB0BC80147E6B2032E876790A15933FB3822C89C891B8034B081AC74A68A7704BC9435E085B50260480435A6E9E87E12B81F64E75AB3753DF34BE96DB9AB2E49AD18774DD4B5AE0EA2C319DEDF6E0AF04AEE38CEA0B14BD58299AEECFE63FD818055854291C0E81C97EB485592CA06D1BA83A61010E5B6786A353EC7C7C46E658BF095D34A01F486D7CA278DCAA2D92FE3D13103F9241F7E949AB007F362B54C504C4B92C9A40C980E3EF925476E5354A2FCCCD8FBAE94CE8574B7B461632C56EE33FB2D7E2F41E7E759D0945D5A9DF0CC07D6B01059C71CB05AE9553AAF3B60266D422DB11AD1A01ED8757F1931968A16E7945A6EC9DFEA453322F9ACA9639F0CCDE621E95D01CA58FD21BA030E7EA518F601AE849796CC83B5D02E6152C2B9DA2394113DBCF0BE0F2781087370AD6F581D75AF5D6C979E1D3F43105E48E62F6EDF377203815DECB1690C914FE6B5C5BBCF1C4297A253BC2ED7D3E53E90C1FCD61CBD8C1640AA60CCA213CB8E58F137D6BB6FFBC30697AE85782F0A4AB4584FDD332BFCB4A2BF45B5059F9E87EE76EA451B5F684517BBC1407B06DA076AABC83CA7532650C45CA468A07CAE1161B4AA88BCF0816F4CFB0229CD993FFB428A9E5AFC8C0C94C922333692551890FFD307D87CFD4681ABA84FD82035ED32007B4B96E963324BEBAFE589C5D65552F379F1B8C4905A5D7C9F93B0880B9EBB7073A0DCC35E77A20D358115A9C0C9C007AB49B0BD78EC1936D301F39C976176B2B8DAB9CA040ADAAF26A85CB616002834D630D2DB28A48362C15A5637A2CB45DF5AFB1DD3C632219723F55F4F65D2EAEA810DC84A4C243D30BD49E0214BD97CFBD1968275351B0D1182F316067A9F43776F923A429E6EAF29E5E620CDA06008030735A1D3AAD5C47A0F12102C0F28269D7F2CB89E3DFF8D9B73A5AEE6C395CD9D6FE209134D46BA65A4F8AA59A5C37F180A5C287D8130678EFD51406C52858EE1FE24ED2B038 +ss = FF9A0D1AE64C97E4C51512B315D044C14CA34771DF320BA0C16C8531D6A40D78 + +count = 40 +seed = 197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F +generateEntropy = 588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +encapEntropyPreHash = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +pk = F6446774B30FEF5B426F563962CC29FF78ADE42B497DC3B970F1B848B1141D7A5F45A37C25B125AED61863F22732A06128BCA08EFC8CB176AB6343239B572E1C8C138D829810227AFAABB81CCA0A73131155377730A120558231E8F8A598A2B730578EDC7800B0D6C5627530EE92930EB2B40A9888CF648263B688F0A12E08F004F4BB449A25282029CFB73C32F8D31229D0A58E6AA08698517FBC5F619837AE3331CF763631D305E88C8F85413E9D5420CC282BAD24A783011184011A79A3B305DB5B3032B75C55907CA5C7F839320028305C439C39484895212B1E87925999681819416DCBC7EAD45AC2B1262154BCE16866C04561EBA2C9EC6022B07A57A67C7B901B5DA3BB8025C7585C86BDA0810C442C39374040236A82884199159729834663D3B1967DF9955DE3A387D93D50F5001924C4FE433D016BC2B6614F2D3BA72FDA226864AD6BA5B8C31681DC104348EC2B29C39FC9F567CAE17BDF1C6E215C92EFFC60E2D6A3A3106BCED0BF301B542F7987B582B0780B6D398631EB8559459B1DB01A0443100DCC731291C737499C2F86452394C0B6662401FB57A4DB232E40D1B0F2511EE1EB15DBF7B603E2A67808C064FC5103FA7C9C954FCD12BC619582F82590B323698A328CC14ACB87C217E39C309421C7E6EA15BA6C3BD8587126C5AA02C26308C9912D7262DBB91AC2C2CDBB9CB009A3AE10761771740B2E6558FAE775DEBA7A66086859270EC07B584334900C278002D8A47D01547DBA3036336616A8C12415B86A1423A6C9AAB5F085C7FABB6355B3DB4023E47C7917C10C284333110BC978B2C08E16512BA95A07237CC35C97BFA51BB1B25E30750E65664377BA49200AA6E935B4C7451E547859EDF03BCFC6904DF05220C02F5E576604A873EE82B7693B962853B5522A5B0986348DA63DF86A64671737C17201ED556E92ACB56F065EEBD31BEF43CA85DB1FEAC395E19110A2F0C5B90459838CBF779C27247709765569E5A649BF160301003169E4AC2BAAA4C4697F25869AB99179F9F792D9B19DF0C148DF7C6B9AA20E63426697D83A6E33B35F4C7E798175BFD73CE60A050146A3D893C4DC9B2FABF5960BD80FA0679433BB33BB91915E93C1EB2AA16CB13E0B9870FEF99835A674B1BB76946BC4064CAFDE3063498CA30AEB3983F5CDB3A6B9C4970459D969F4D8B6BA27755B6CA8FBCA178DEC28DFEB2AC03318BE7002A9A4CD7B1749A7FC7F09A6B560740DA89BAAB8130872510C99630F3B588069D50A9550C97F8198B7A46148FA7AC1580632DB1EF49528F9125784A5BB2757235FE44E74529A7CE88E91543B2FF81D9ED78E2647AA07033CF3422D34942E7830191B104C7ED56B8951A9C8706E4CB33CB0B918387B869084386420C13B09BE75D2A5E9276246B674E96BAC7782541E1CA441E53FF3B9C702CB95CEAB628D1617704A448EF743E8B811FE52C659CBAAE22377F28646C45642A9886628C9B73C510BBFB645D4077C1D8B954BDC8B707B7F6BC4701BB1AF0F28B88DD282B78B7EE96732521AA6180B6021AABB415839DC3A1F6F545C1320C58B965B62993ABF6A10C18A22CE6A45539685F297B1F04A130465845D189D17552E2F4917E924CC0D2DBC2DDC739F6B876472EB12CE233CCD402DDEF61523FD6FEE69A88F34A34C +sk = 47A7741316BE87861AEC518A9B38146B43AA54A98F47E242866B8D79F731D98C754B572A2A9170A7EB4B0D73B38D6665D1E43AF0B61AB95CB54879707805BD787913EE369D231C600B76949BF86366579AB62724CAA1BEABBB02FC945BF007CF57A225AFA67393CC58804A15016A12DFB90D5A52BE41F907B1F2C4FE93712F555B0AE896E85931020089642A23E4C38581D4C40A46AA8DDB3C26DB0E29FA5F7A12B6CA32CD2AB6B50327AD0DD8139AD83DCE676AB2DC0C2774C86A2C72A5FA2D4DCAB588A66D6551C040E91AE045698AC0A1DFB95048C545D08654C1B560384561AB07BD8C61182F99C79A2267C961AE66434321E8501D474AD84AA71286A948C5AD187232CF72576F167D63992F62D3423CE75577C2052EF84019404B0E1706BA704FE3D116A518293112B8B80708C094BDE829AC38E362A404BEB67026EA6782362035CAE099302C5660931CE31B93B665059633699EC44C28C2BD230B1942421F12388900081618BB29E315BEEAA090A06AC7FEDA567FD1A12D1A41EBA931C279ACDB875D9DDB7CD9A6ADBFB32239E843012A8CB91776775408316B056FBC42758772C1E53EC0344479C2791B837A6A34AA77710D35593A55E57572FA99711BBE5A83454BCA7990E834BA285A09AA11666CB2B2F39704904354687D0524888CF6461EF302139B042540138E322453619B3DD715B617230E08C4585478F9996798E9B47C712F82BA45857551EA4C79B4A0577938666403174E84585E684783D33F3B701420F66D48473FC6BB627B399E90697E760783A3E09D6531CC524568DEF8507F0437314488AF7376BF2A6BACF783B632197D8565F9456D04A8476DA8CD6C988D26A56D29479A2DBB85AFC18DC81A8611BC4ADAAAAA440471B530053ADB874DB67102B6A64FFCA8BF8487E18B2F7582B71FD78D85F819C24B892741A83E67585B6B1AE5AB6AD1F5CC02AB78D0ECBE01087F46AC9BFCA464A4B9CA817C3A1AF5CB0A6A3F1DD3A2EC06774E805E001B44C8194660A280D0D59BFEB35EBE9C943E626B98E488F8984275401BDC4959993345C38BC801B95D56BBB47A2B23F5F1223D5A0E2A827D4578948CFC5432627C9586275679202E3C970FCC980AF56757912080072A4AF234DD030EC481A6ED8030921691D6126839635C6B270497CA4A87D4BEF47CAC60752383712636752A4AA18AF13BB36EF445FE653628704E4DC2CADD62839F9842F9B2C264AB4FF648C59D15708F55AE4A396D5F4BC75D20603C03CDEC4252FACC579A0CBD1F64A734E8350F03ACEAA2734DE2B486F6B93C36AC11803E564070ABA97D2309078FB43768F98EF5D03B09FA10FFBB0BEB3B5FE01310065508100206A640B93DE87BD94A634907730E30800803B233B95D1CC7CCE49C08AB143734347F3459A5BE0230F9481D50B4B835A91736D6A7B351C8082A4D080967B43B0553835BF52943A380051F48C27823C5AA0B20B7B733DCB004B2A7819BEBA4B3FCB1F991789C2C57CA01B50523214AF309FDF421187492C411C14128744BF4A83599A30B86194473C2BC9222FB4BA34108689AA8065AA24FF3559A76F759768C81A8CC5AA2A6792F3033B2437B05068BED096475D9280BF349F6446774B30FEF5B426F563962CC29FF78ADE42B497DC3B970F1B848B1141D7A5F45A37C25B125AED61863F22732A06128BCA08EFC8CB176AB6343239B572E1C8C138D829810227AFAABB81CCA0A73131155377730A120558231E8F8A598A2B730578EDC7800B0D6C5627530EE92930EB2B40A9888CF648263B688F0A12E08F004F4BB449A25282029CFB73C32F8D31229D0A58E6AA08698517FBC5F619837AE3331CF763631D305E88C8F85413E9D5420CC282BAD24A783011184011A79A3B305DB5B3032B75C55907CA5C7F839320028305C439C39484895212B1E87925999681819416DCBC7EAD45AC2B1262154BCE16866C04561EBA2C9EC6022B07A57A67C7B901B5DA3BB8025C7585C86BDA0810C442C39374040236A82884199159729834663D3B1967DF9955DE3A387D93D50F5001924C4FE433D016BC2B6614F2D3BA72FDA226864AD6BA5B8C31681DC104348EC2B29C39FC9F567CAE17BDF1C6E215C92EFFC60E2D6A3A3106BCED0BF301B542F7987B582B0780B6D398631EB8559459B1DB01A0443100DCC731291C737499C2F86452394C0B6662401FB57A4DB232E40D1B0F2511EE1EB15DBF7B603E2A67808C064FC5103FA7C9C954FCD12BC619582F82590B323698A328CC14ACB87C217E39C309421C7E6EA15BA6C3BD8587126C5AA02C26308C9912D7262DBB91AC2C2CDBB9CB009A3AE10761771740B2E6558FAE775DEBA7A66086859270EC07B584334900C278002D8A47D01547DBA3036336616A8C12415B86A1423A6C9AAB5F085C7FABB6355B3DB4023E47C7917C10C284333110BC978B2C08E16512BA95A07237CC35C97BFA51BB1B25E30750E65664377BA49200AA6E935B4C7451E547859EDF03BCFC6904DF05220C02F5E576604A873EE82B7693B962853B5522A5B0986348DA63DF86A64671737C17201ED556E92ACB56F065EEBD31BEF43CA85DB1FEAC395E19110A2F0C5B90459838CBF779C27247709765569E5A649BF160301003169E4AC2BAAA4C4697F25869AB99179F9F792D9B19DF0C148DF7C6B9AA20E63426697D83A6E33B35F4C7E798175BFD73CE60A050146A3D893C4DC9B2FABF5960BD80FA0679433BB33BB91915E93C1EB2AA16CB13E0B9870FEF99835A674B1BB76946BC4064CAFDE3063498CA30AEB3983F5CDB3A6B9C4970459D969F4D8B6BA27755B6CA8FBCA178DEC28DFEB2AC03318BE7002A9A4CD7B1749A7FC7F09A6B560740DA89BAAB8130872510C99630F3B588069D50A9550C97F8198B7A46148FA7AC1580632DB1EF49528F9125784A5BB2757235FE44E74529A7CE88E91543B2FF81D9ED78E2647AA07033CF3422D34942E7830191B104C7ED56B8951A9C8706E4CB33CB0B918387B869084386420C13B09BE75D2A5E9276246B674E96BAC7782541E1CA441E53FF3B9C702CB95CEAB628D1617704A448EF743E8B811FE52C659CBAAE22377F28646C45642A9886628C9B73C510BBFB645D4077C1D8B954BDC8B707B7F6BC4701BB1AF0F28B88DD282B78B7EE96732521AA6180B6021AABB415839DC3A1F6F545C1320C58B965B62993ABF6A10C18A22CE6A45539685F297B1F04A130465845D189D17552E2F4917E924CC0D2DBC2DDC739F6B876472EB12CE233CCD402DDEF61523FD6FEE69A88F34A34C29253478090CB4D580BC2A912645BC685061E5D4437B3811EDA69C865EA9923C0E860576285483BB5FD36E2F944D32C4317BEBC1E441470C1372046A790D79D4 +ct = EB55C9D3D46D32C021F0D7E61E5382C2B74BF1608E0C8F09E080C2820AB0CB10886E141A282A7C80B73CEA0272D08E16366F2C900DA1144039E5A8EF7031DC26A5CFCEE8F47C3F997C940A056D68D3507E7481E13835B911CDE8976F0E7494170D98386316AFE41F97B56FFB8B5C85C70048FF2B5E2508D19B06D8E03A91F6973DE1F903452D0A95F5E8FEC22D033669FEBCBB2E09904307FDD7BCF55BFF0C097D31B62B08D75A144E8064B7001DE832BD6AFD9FADBD00BA148A5DB0B0085FA6756AEED4E2D1CFF7E8BCDD3F8E6096FBE2EB19F10E1EE84678EC8E140CD4101D300FD0E110BB7ADFC580EC1EA5AF38CC6CF984DCBA6921230304DC19B38A1D3C9BE8C479FEAF98E097FAA5C45A957D8F33A2928C1692EA8E8B528B33D49460516DFD50FEE3F5D0590171ECC3DC287E4F63AC5FAAB29D1B6436195EE4F6F29AB15C9C3C27683554C44F0D9CFA94920E9000BFE9DA83AA15A605A6E2474D29460AFF929BA74A38C465FDC8988C7C2F02B5CFB44C16BEE8B9065B049FD6342F976CDE143BA0D48CE4AC03F2CCB0767F94FF4DE46DFF7077790B1F1FE14093034F8E021C2857A148C14FCAC87797E455F36472F3791073F5F47C5C02BC40063A6C0435958B9CE3B403051CFD6A538B05A63B924950EADA692FE82433DEE2F7BE1202B5E1DBE0D5D17E0532F09F7C3D2F815BDA7A6D6E61B6BB2E755C1A181EFD721444A928BAF9EEA4ABCFFFDE4A1053BE769077146B4487ED00B2F3CEF170FB7EB4A3B61BB19706AF4C6FD9B6A29EB698101835CB24FF1580E00C36274220FDD56200D74716053C38F7D4E3FB1D733F54DDABBB14F3CFAABE62507D50920FEDC87E5190BD84200C96C6967CAA3912C6126EE409DD4BDCF8859AEF9561E523A26B31F5632816FC9053DA5B9EFCD9CC05E6A1D81078D6ED3246A46E2CE4F0C09F11CBE1FB5994EFD758207F7B9E2AEDF2A8386F9175259325B9B7AFBC9C8B9715E973EFC1573526D6CAD3579BD57920172694C7A5A02B2CF3DA1C78CCE8C9E204A4D2605C510552836E2231841873F2153A60E77E381EA4345A0A4CB0622020CC5D3FC168D84EAFE1D38E0F2DC8B890D7843BAA29E2925D5F1BE93A9E266DCC99C00C5D6681190E07A833090AFB8575AADF55333E8B3F3D9FE2E7337A3C122DE1EC3264C61B47EEBAEFC7B1F276F8EBC1CC53DE806801A8EAE9FDA8BD5E7D2F83CEB6C072103D190ACA2AFE8313B43AE7083845B6FC26ADB1A7E3C17C0FDEE0A1590FA66127EA4423B6F7AFDFED7C7E2DAF1B7490F09DBAA9CE15E209E1405E71531D3ACEFCF6096B8B76EE28246697A41C6AC8E0CB4E0CD1CFD80997E19014F083167FA47BB4BEFCF207A369051C5F37477A2BEDEA8A65913D557F896EA0041D77182BE50BD355F7544245624F6DB4E918E1308BE489CAD3C7C430D707BF91B79763691EF5FC0DB233895B361CD85158250DCFD5BC90A3850B60118159B3EAF31B8AD3AECC555330D1E084C06033CE41EBF6A5A6928B624D308C48919BA8FBD6923E +ss = 0E40BEF57DC97B87EF89E5308F9DB94FFF59A475DC35EAD3F2D5B6B89D24CA2D + +count = 41 +seed = F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED +generateEntropy = 47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +encapEntropyPreHash = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +pk = 5FD557F7434FCB61B199E793C5E763764C48DF412ACB7C756E1370CD117F8C10CAFB39CBF0C8C3F5DC8DA1855203D02B39647856B55C38E944617B8348D16A8221962A42398FB61978F40328C83A0B49BC843060D1711E289434DB4B5B0838CD87949DF5AC0727D8A528B8B5BF30CCB9E37A6664050CC5880D34C13CA42C1779B8D098C5E0876627C17A79B6BAD44A9A38C56883D97CF2D2B114A1C4F1A502AB4A9B7B5398D9E73E543B860F87062E27A9FD1A2035185F0D98857B0759BF1C39A41984C8C1A1A9027944417F84CCA0DD4206E9133F6EB6A989075D004ACCD9F57CDC928CD455443F0222DCAB9A8890004C2596EFEB06903B5D0AF33A88F14FEC760FC074A3DCDC744E9864E7EBC608A56002E483E60B8202B31377DC7F5A486D5A060733FCA9836AAEEAE05909C6B6B0DB4531271FE4F3548BD5BFF1E92160321218F963081C518874C0CBB792FDA4513F7902BE6547745A0879BA6CCD7C0F73B123DC605BC7995BDD14B018D8278C8C3966AA87A24B4A4BD3ABAFE0C8173C028DF14DAAD39C288943EAC139210392BED70C38D7AF7439697BE96977D23A27CB6E7DE7B785673C9D1B33A081A9CD417129430C6C6300C496B04E1796C9C781E4211915162DE147501B7BC55F8913C66C5CBD209BA6D115F753BA739417C8EB182200113CE17C935A0622DCBC674553B9DABCDA17BDBFB4865D58143C149512CC2E74A2B508F67BE8058461252D95042F8B7641E1D85161521B81A616A02110D7EA3BCA4723D003A4DB1673D64273B34C9432AC981A0C01DC8B8C0ED5A05D20C5331831CE56014AB0732B301CA2F8569FC061DDAA95D63667B9ACC7A1EA656F821D55A31B41F32DFB3B66DDD5CD2155438DB6923069430B61C85AB309BF56B0ECD990427C1B7D93991E783A647B1DD66696659B5C926485E1642854F0839033138A3A54C349C138977275E71E0FE985493CB85E0923095804037462AE248780006D0778334F664262E88498FCBB22D46D4F4291BB90AFBBD40FBF2B302415CF195542DCF3375E78602FE1067638AB995B70E6DBAF7B75BC11701207E489F361512B590A860401A3FACC1EF1375D8B64E0E5C7F863786D3984710C2F55ECAC578C41170194D832929075671B814FABF45C6E2BCDF8C0CBE2954C5A414E3F8878AB68CA13189D97F316517ABB4C5187DBB03413DA654E650EC1CCA0BC9472BD4BCC60CA6FCDCB26E77A025EB70EC0E60E20B19D30FC261AD11D3C0C56ACE53DE82C6A38CA5D59E9C24568B7CD15A0531315DEC20D9CC957FCF8958E3747471A8D944A6678F6AC8A8763A1759B3DC83EDD18CEEDA5036C31A897B65612D2B176E9648352899BB2869F48B1E70C1FF04864487258526226A7DC64306B6838F4286B9A81A3193F5C9C711DFC5B9FE79BC6CC14C934591F93860B66511AAB061295AF186B8CEFF5772FE50DFFBA4F5256522B5C7C55A6BA9B13B615FB3B3BDC4B159A1C84C85D717824A0573CBF219FD9B2A32AB66BF8A498A04AA4E22509A5057997B74AB5A1B27B96656BC194AF08114551709A41142B715C6E167E5BA5945729BFA702C236073FDDDB4CEADA972810253D642EC094333C028B0AF40CE2E29993369EB7DDD07164969A62466B80918873A4EA56CD80A8E559FB30F6CCE44F1F8FE60A +sk = 35E4451348CFB9A06F1836296178B6AF41A1C0196F26525831C081EA779E6B8C4B3F150AFE2963AA756968358BFCD47D76415ED4294F02A843F89B87D6803BAD504A9165B9BEDB0C946058965B64BBF953E719160B53552C100D251CC9C111837E0A7C4C043BA0777E53B39F658B41B5F8900D4721268A8AB868B15A12C3B8F41316DCBE117AB3A027B8FC2CBF3566569A130D6DB132DDCCC5EED69A392BAE8E4A7BD6C9708A48BADEBAA79FA1AC1E729EEE0399803A374D3733AE501F1A846CD2F5166DC31B4D53750BCCCF937B1CA43C3A6CD5601EEAC251F9AAB8B2489E22CEFF436F1142CCD1BB17DFC75DB6125A1A433325A5599FD23B49BBC3D1B9195B984303735F9F2646EFD050097AB23A8AA5569AB744A934C2991BA046CB012467D39C3936EBA9CFEC4268E1A0EEA559980133B4121F9D5A603E092C199818C057B7C841A7DD00AF2C0AB3637878A9EA90BF377874FA38BF290FEA6131345340857A1A53D4BDD9201B99FB628D975A91001F907A2E9AD37C9B99B8AF915070339FDF76125D9556B1716CB74A9F18092AFD887880526FD82CB002CA49E879C50E33AF2E747104674EB1F30859E3C22F3AAEBFD30FD672B6AB855928C4085130488540C8CBDB832AE25249F46B7178AF9769A4B359664BA48DA4A746C215C58AC2752E43835B5C2A9EF0A3FCA159D29038CD60CD60F5BF508521D3D59C4F083653264776501B4FC62337FC37562973A1F9BD9532B4BDB25C21597A11E17096B155CD43C76874C44F25C1AA1BBCEA897367536ECF4124FEB6CDF2360CD5A082AC03B5E94232DFB44E1F124FDF65A4BD03B16ED729884065D77135F1F730A7A91FC2EB43271C0B2BFB8E615C07DF54041917A95B0544E8513E8C6060D14C0FB802C0F2680051341960654F3594C9972C08664B7BD30B2F031827307B95FC525A2632C2456041B1286D6F175BC0B41942E8B8BE69BB364A11AB4CC199F20AEB516CED1ACC1F4B2B91B860331677290C643BB9A00B4B65644592C5CA5BB19B25D2A7080CC32B08910C137946A3FAB6C8E31A1E97A4735A5C0A239B073C6E056053CD6498117497870718D35235019B3EE6050DCAAC31A27167FE35CE57586C364C13BCC7587CA066C6E05673E2BA0186281D94843DF10BB3A93C05025C0C691A0C41B229A55B7B506724026C4F1B48313788A212B0C951783EC9447E64314E878734AB59401923ADA0586225C7A5C00A5F97BB76632DEC47C15C06C7C20090C790404B3044136C79F46181CB1123A7D3CF969B72F6CABE063A35774A60863267B1BA34B93A5D3DB25FECE84A02429A9D142ED897320BFCC114391BCC097A078B04BD9356113B3CB993C19384886DF182E37BA659D5B8BEE24445411E318CBD092B8F8E53C63BFA3896A2CDBDC66E27F25C83FA85C260A34FD6CFE6872172F1361AA125E6C5C6C902CDEC68708C14C175E910CF002AD647A317F78F52F76BAE006A3AA51780D37A00AA20C6A532281719C5AC88641A9D15549088B5A4DDA23F443335ABFC5C2F7C5BE2A142740CBFD612A83AF271AF0AACB43833B56295B51A885D798825C3A2C04B399C528530CA24117B6E762C7B6527B0509B5963B68560015DB4D4895FD557F7434FCB61B199E793C5E763764C48DF412ACB7C756E1370CD117F8C10CAFB39CBF0C8C3F5DC8DA1855203D02B39647856B55C38E944617B8348D16A8221962A42398FB61978F40328C83A0B49BC843060D1711E289434DB4B5B0838CD87949DF5AC0727D8A528B8B5BF30CCB9E37A6664050CC5880D34C13CA42C1779B8D098C5E0876627C17A79B6BAD44A9A38C56883D97CF2D2B114A1C4F1A502AB4A9B7B5398D9E73E543B860F87062E27A9FD1A2035185F0D98857B0759BF1C39A41984C8C1A1A9027944417F84CCA0DD4206E9133F6EB6A989075D004ACCD9F57CDC928CD455443F0222DCAB9A8890004C2596EFEB06903B5D0AF33A88F14FEC760FC074A3DCDC744E9864E7EBC608A56002E483E60B8202B31377DC7F5A486D5A060733FCA9836AAEEAE05909C6B6B0DB4531271FE4F3548BD5BFF1E92160321218F963081C518874C0CBB792FDA4513F7902BE6547745A0879BA6CCD7C0F73B123DC605BC7995BDD14B018D8278C8C3966AA87A24B4A4BD3ABAFE0C8173C028DF14DAAD39C288943EAC139210392BED70C38D7AF7439697BE96977D23A27CB6E7DE7B785673C9D1B33A081A9CD417129430C6C6300C496B04E1796C9C781E4211915162DE147501B7BC55F8913C66C5CBD209BA6D115F753BA739417C8EB182200113CE17C935A0622DCBC674553B9DABCDA17BDBFB4865D58143C149512CC2E74A2B508F67BE8058461252D95042F8B7641E1D85161521B81A616A02110D7EA3BCA4723D003A4DB1673D64273B34C9432AC981A0C01DC8B8C0ED5A05D20C5331831CE56014AB0732B301CA2F8569FC061DDAA95D63667B9ACC7A1EA656F821D55A31B41F32DFB3B66DDD5CD2155438DB6923069430B61C85AB309BF56B0ECD990427C1B7D93991E783A647B1DD66696659B5C926485E1642854F0839033138A3A54C349C138977275E71E0FE985493CB85E0923095804037462AE248780006D0778334F664262E88498FCBB22D46D4F4291BB90AFBBD40FBF2B302415CF195542DCF3375E78602FE1067638AB995B70E6DBAF7B75BC11701207E489F361512B590A860401A3FACC1EF1375D8B64E0E5C7F863786D3984710C2F55ECAC578C41170194D832929075671B814FABF45C6E2BCDF8C0CBE2954C5A414E3F8878AB68CA13189D97F316517ABB4C5187DBB03413DA654E650EC1CCA0BC9472BD4BCC60CA6FCDCB26E77A025EB70EC0E60E20B19D30FC261AD11D3C0C56ACE53DE82C6A38CA5D59E9C24568B7CD15A0531315DEC20D9CC957FCF8958E3747471A8D944A6678F6AC8A8763A1759B3DC83EDD18CEEDA5036C31A897B65612D2B176E9648352899BB2869F48B1E70C1FF04864487258526226A7DC64306B6838F4286B9A81A3193F5C9C711DFC5B9FE79BC6CC14C934591F93860B66511AAB061295AF186B8CEFF5772FE50DFFBA4F5256522B5C7C55A6BA9B13B615FB3B3BDC4B159A1C84C85D717824A0573CBF219FD9B2A32AB66BF8A498A04AA4E22509A5057997B74AB5A1B27B96656BC194AF08114551709A41142B715C6E167E5BA5945729BFA702C236073FDDDB4CEADA972810253D642EC094333C028B0AF40CE2E29993369EB7DDD07164969A62466B80918873A4EA56CD80A8E559FB30F6CCE44F1F8FE60A286DE7DC142EFE935E84B0AEEBBD32D050FD9D8B008A94E59454B19EA401611DF89D7D99D5C3E0D10D6EF9AF054D842375F695ABB28E3B8EB495100F04306E92 +ct = 5DC80EE57203C2A3A593240F5C226FB63EA02A9289CA40186D14AF3D9A02094554F7B14EF4453AE4F183E307BF7B9278D01E0F2C3335BD69C14642ED5FF79C29C45AFE9B515675C913AC83BBED109F7EF75BA845F6595EBAC11A0E80AD13B284F035C25E9671D7BBF6D0D2C7552DA1888B61A5F011BDBD83C63C2B03C8979D3868E08B5582152F4D3127FCD9E587B08A1860DA14AB9D078769E7114A40D559754637E0141E3163215B30587E985329A2683BAED7523E46BF08AD415E8AFF8E92AF2815A8129BD516119E54815A2A529EC01565F1A6CDCE2D60343BCCD6B705A2FFF6EEAFC75B73B7187769B0AF07879775557278F537FE44DE5D57F4854C9E0A2E7E6B55435D801C5133D133089B15064F702583F228257D9A0CAD4162230596242AEF6A26E5E8C79F9B405B2F196EEAA922C464EAA9F3D312560DDFE0DE9650F53B07464EA6F28FDED35F78A351397E23FC38BC1A790E39DA5D41D33494DEFD5A5533834A5095ADBD2B03DB0E560DF6BD4C64B41C502309B89F73C0EE40B9C6AAE58D835D95E650EE2AD57CD0D393D76D5C9BF0B90915878942DBB05D8C5780734821937C929F1BA55C487FCE1C1831524BAFAAABF4D29472C82C105798A9BB324112E1B28490965C14A402E4E855DA0F3E83A2DF80F3F3BD8807112FE74907FDAAAF6C8D4DDF5C1E57DA71B4680F81BACE717B766A38C261CEED6245B9662530DAE047872C4B7655FCB0BA1A3290A34110BD31A97A51D92443F6E6540B0516B1164D783A610A3F87BDDF21593FB5EE66617E2BB370EDA0C1DA30268A6DA145003CFE65114FFEA6AC3AD209D9B3DA1F39CBB1E564D91A9AE448C23690B77E8C9292AB6820C793E767B26CBC2EEDACAC6B04F0F1F742D147FC0E2B898052E1E56BAD108335CB72B6D6AE792794F804DB1FFCE2B40C2C97048B5E8A1C6CE5FA34966FA6445ADCED31F6921D56A24CC323A4AD2AD53EBF4CD336998D06496724C1F9805C1B3A89B3511A143DEEBCBCAA4B76C8F28D9DDE856F35CC7BE4FF03D7C147486270B6FDBEFBB08C502225AED31489ECEEECAD5626A028F7A7E4535211B2E85CDFA40F1380C91AB7D6F6B544BAA8A1E6FD69001D0D47E2215C5158BEB50BFD8CBCDC828207C5027F39CDBB75FFB878AEBFB0D713DDAABD1872BF36775457BF5C2CB50B499CC3237AA4BA7AE6E62C69E317916B7548F14684CFB0DFCB1614F2D7F344BB8CC97014ACA7787A133C59EEF7EF6D010E9BA76367E0065BD41D9CE4D38C1A98838A43296B6CEF7C1FCD671537ADBC2F00AD206D742ABC670ED2A52793971A63F2678E37426A34616C69EF57430568F3BCFA11973ABC280FD527DCFFAC2FB7E612C168AD943F0AEC1A7945DD77109B18901A3DF62CDCBED7DC4F75D6AF7A1458D0FD1ECB7CBFBF09F94AE3B593BC4F842C3B2B42934A2B62963E8BF6AFF0CAAE36C1C887C97D2E5FB89572551DFE322593B2082CF2B37B807C2A60F23CF191FDEA019D05E39A36403D595F97F46910D2AD65D812481402CE51B810 +ss = 6134219801B78F6FA5A998377643F828C19AB6FEE69E7DBA03C7B8E20915DE13 + +count = 42 +seed = 44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE +generateEntropy = 610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +encapEntropyPreHash = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +pk = D5F135D06AA99635C9B53244E1F898D8494B681312BFD243C8EA5B7E71CCB7A5386E477D01FCA3EF4122A63934843450A446CAFF55184D052923A393FD887DF6B045659CC282D1424B19B17CC2A2384132EFF067A0347F88C6B392AA56A3519A440438D3F90F6941112124C91FC31187AB0CE6752D9B336A1E230F97837A657599E253B7798C912A66A48314447C352B84590941355C6BD1C0951374105858A46502EF39CBB58B8E63A64E2B99C4825912155695893A62AF6745E76058D551A946161F25F1B8FC045602344A7F342FACC50E9565C1D59A459D34233C1921CEAC6E0BD936B496C8FD6A619D8B0649EB458F8943EAC97293635092666688DB559D255CE9F280227755C3605D6ED007CA718527227FA1F40DBCD88792801D8DB6B2374A23178A72276C790F902D7E969F2686C9508186788905E77132DD909397F6B6BAD3CE77E8CD4C4A3B9686CAC35ABC86D57E911CB58B0C997C1935CA64918370809D3B1B70CB09641878E7C0A141573030AA2B687761BF43AC89A81E73376793ECB32DB53368EC9E079172E9AA482FD8652583B9155683DA3467E4546F26AC98371487527C37B6646CA582017892A188FB2440CA7240C3C22577230B59AB8EC038BB95CC49C2A2F59A4A22C0C482713544FBCA9D7404B3A6AD86E8764A601B7084289858BF62A2828D3091FF015089726CA23B1CA0F87195BA1ABF80B01F101F8584C15289196744500000B431A60267174F2CC56860BC5AB4EC20D19BA8ED47535EB42FE1D33F2980BA211805A3618F2FF64D1CC634CAA6B40FD23615538366DBAF41971D8B5857298C1E406A293C1B8B7F4A499A97BE8CC51B5382020EA9C7CF809FA7323134290FA461218F4A6F495CABA2D1511EA48B7E0905B0465F7A6711F2716B17DCBB4B9A1B31933D7D3622315C79F3F11A93C8058FBC01C4839A808A5D2D45B99F7918FAF52DB1D81D669C7988BA7EB8847187AC7B76404B1A139DC4E4917C9B4E29833FD9FBC36E4BBA96E25BDE691CE0C369ACE7183C762BD04785EFCC6B614165C014A0FC4B64B24B3B46418AC5B6B7BF69CBC75090B69AAE46B4A12FEABD4E134BCAF14922367B50F17976C6705E175FF34612CF7B086ED733DEAAB0CA815A53C99B2985963DB89BDC284D251340B0E3AE20990EE93344DEA18063DB6EF4374A331244EDE00B46676475937A9472C82E124B1751A9E4203BECC77ACE092B055ABF0892637B39C3A9A011219C88139277B8BB73B9508142421939380ACFC2B81523C72E923609A0505E2979E086AB85F9663E549F3350A694458CE7B02BD8716C0F8B8946A21D99D97632952BEE898989C1ADEB710E15BB25B0A22BE598A65465BF2B899719D00F9D16367E9436803BA8C17B6B3BF62A10A017C177125396BF6745163FE24C455319CEA69393CCBAE42508156167B28A1D1050BDEFA5A789BC389031BD86E72AF5F5BC80A215260737839654998295D5ABA8C11A5417B55D67201243393B7593400D46CCA1D321C027BFB09CB08A1738C88B7D47E876EF7517F8D96CC1C93B9E93B7062227A55996FA958A684AAEDA89587B015A6B336DFB610721298AC6AB713F3A2E37B2AA7B1CCD2A876F03C72546B861E351A73036F4B363137340EFA7764C439F68D3C8E0723683AA8254A66284F447 +sk = 03A941A829C025261F44172ACF806BEA5B216B58BAB845328C36CB925A5169D6B1FF141BA44010FF2C1A446113C443C6D98CA879E673CCCB84D5519067619EDF59C23798B9B6BBCDC0D49DF5F4B21563AE54E287DCCCBE4C53C62918A6A213C460EB8C92377CB57A1B6D6467D40297FB90C6907B6BE5B03DB314C3AD5B2F46999743EC7FF0B055AF2B2753695395C6157C60115E183DDA398D136806B7017BB4FB4F36B7653BD17CABD1BFFEECBAF2EAB65B853C710820818B05AFB86388F327FEA6C3562A027C610AFD9C0BBB23A571489120C2BAA0D7AEFFD196B2DC8B40D4016FDA16062512A64462FE806D5959C49DFC0C9B2955E6480B7AF0011EDB2D44C6A43D08B5F469656CB9396C9C640BB077CC24AC0F293BAB4CBADD998ECDBA31534408B74420CB432826CB5DC8224C48159626053096063841153F723761F83315629C945778A24F826A28A90A5854BA7E80C48E44929EECA17E28304BABCD0AF4198962A045292F09AB5B7197A685A67D07EC9769B69E64EA1457FB8E1A70B23AC4A797132B021244944143E936C6E5D840494B674FDC9AEE84A091175F8E3121150B1375E028D0AB6B709A443F14C56AB67E3A8721A4B698EAC9615FA12C0E5277E4A412508446ED4999687AC5AC626CCF5468F3E944B8D099FDC319337C85E5024A0798556CFABFD47A40146691D32C0F179B5BB3C3088F2CB29E2B961B630610D1528FAB952DC75D23339C26A38F68421C12C2360F369ABCE128CD64551CA29455E02AEC7C359CF9182F5642F1BAB42814AEA8F2844AF15670421E0E113063B4B8C614487F6B6236DCB21E48613C0635E5F6A6A6E070FB665756F98156C65A6F407E1014BD6540A92E8A09EF6C944DB876250B951D16332251C5BB6B79F88928ADF6BEF819A241068B08337136B8BDC33476FDDB0292B68EDE75490DB193E267BBF2F8459FABB17D10BEF7018AE895995200453065AD45457E3E86A12C554DB3617A99613767598031C86BD5815585444DFA41CBE068034FC0A1CC2636D010230870776D2645DB640B409A292ACC909AAA11D0D05A1B1469EA2673020BB7EBC7381190C271E2CF73D37F61F12C8389843B0540117C7AB924C140D1409F701AB0C0596103A1AEF3C93A2A79BE19C7870ABE83232A7DE265A1A1280D30490FF50C414A006D8A403C50948DA4B1054B18BE35A8F9252079C5ACB2104BD42CCB51617839E07380FB3A62B3A5080295BCCA410215AB5C30A89B727363185363027BB1A6B09FE83233D79E4527371ECC8B879C81A25B3E6E088D2E786976396EF8D6C383495B52EB69BB718DD7FACF5F120303EA259FB2BC32A5269AB45E6BD8AB9F9456A68B869A4C13A0B6C98DD1BF276572EFC9A31591ACB33B9945919FD20495DB284BD4BA7C66620754E58396C0A191F20304B545AA2279CBE62D08EB4C82E60569598147F9910EF70ABF792D375420BB999E4A9CC28DB0193A124D0CC78807A54D13933B25B350A16C842E4B31337BC7734104FE564C20F27ED6AB800717BAAC4A9C954C6EC5238BCDF309C6FC497A6A9B9E4973D7D44EA53B90DB26912AC7796C327D24D3705DB5BD0266B17B145FD8CA77624C8ECCAC1C209073B2A639D5F135D06AA99635C9B53244E1F898D8494B681312BFD243C8EA5B7E71CCB7A5386E477D01FCA3EF4122A63934843450A446CAFF55184D052923A393FD887DF6B045659CC282D1424B19B17CC2A2384132EFF067A0347F88C6B392AA56A3519A440438D3F90F6941112124C91FC31187AB0CE6752D9B336A1E230F97837A657599E253B7798C912A66A48314447C352B84590941355C6BD1C0951374105858A46502EF39CBB58B8E63A64E2B99C4825912155695893A62AF6745E76058D551A946161F25F1B8FC045602344A7F342FACC50E9565C1D59A459D34233C1921CEAC6E0BD936B496C8FD6A619D8B0649EB458F8943EAC97293635092666688DB559D255CE9F280227755C3605D6ED007CA718527227FA1F40DBCD88792801D8DB6B2374A23178A72276C790F902D7E969F2686C9508186788905E77132DD909397F6B6BAD3CE77E8CD4C4A3B9686CAC35ABC86D57E911CB58B0C997C1935CA64918370809D3B1B70CB09641878E7C0A141573030AA2B687761BF43AC89A81E73376793ECB32DB53368EC9E079172E9AA482FD8652583B9155683DA3467E4546F26AC98371487527C37B6646CA582017892A188FB2440CA7240C3C22577230B59AB8EC038BB95CC49C2A2F59A4A22C0C482713544FBCA9D7404B3A6AD86E8764A601B7084289858BF62A2828D3091FF015089726CA23B1CA0F87195BA1ABF80B01F101F8584C15289196744500000B431A60267174F2CC56860BC5AB4EC20D19BA8ED47535EB42FE1D33F2980BA211805A3618F2FF64D1CC634CAA6B40FD23615538366DBAF41971D8B5857298C1E406A293C1B8B7F4A499A97BE8CC51B5382020EA9C7CF809FA7323134290FA461218F4A6F495CABA2D1511EA48B7E0905B0465F7A6711F2716B17DCBB4B9A1B31933D7D3622315C79F3F11A93C8058FBC01C4839A808A5D2D45B99F7918FAF52DB1D81D669C7988BA7EB8847187AC7B76404B1A139DC4E4917C9B4E29833FD9FBC36E4BBA96E25BDE691CE0C369ACE7183C762BD04785EFCC6B614165C014A0FC4B64B24B3B46418AC5B6B7BF69CBC75090B69AAE46B4A12FEABD4E134BCAF14922367B50F17976C6705E175FF34612CF7B086ED733DEAAB0CA815A53C99B2985963DB89BDC284D251340B0E3AE20990EE93344DEA18063DB6EF4374A331244EDE00B46676475937A9472C82E124B1751A9E4203BECC77ACE092B055ABF0892637B39C3A9A011219C88139277B8BB73B9508142421939380ACFC2B81523C72E923609A0505E2979E086AB85F9663E549F3350A694458CE7B02BD8716C0F8B8946A21D99D97632952BEE898989C1ADEB710E15BB25B0A22BE598A65465BF2B899719D00F9D16367E9436803BA8C17B6B3BF62A10A017C177125396BF6745163FE24C455319CEA69393CCBAE42508156167B28A1D1050BDEFA5A789BC389031BD86E72AF5F5BC80A215260737839654998295D5ABA8C11A5417B55D67201243393B7593400D46CCA1D321C027BFB09CB08A1738C88B7D47E876EF7517F8D96CC1C93B9E93B7062227A55996FA958A684AAEDA89587B015A6B336DFB610721298AC6AB713F3A2E37B2AA7B1CCD2A876F03C72546B861E351A73036F4B363137340EFA7764C439F68D3C8E0723683AA8254A66284F447029A2E12C3E6AA668AFB5BE8A82576813FAC7B8E61C5A88AFF94ECC2770C585ECD292E4C5F9E1A55E0489BCEFFB204D672A6215F4F3980A646D9F880817C52DD +ct = B998B14D416FF33BFB8B90CEA80CC3B15F1B2B3904EB8BDF16AAF43944782D1158949BF229AC7DE3739AE24D00BE3C97354F87D52DB95D38DE1CCE5861C2C6B51879022ECB412C5A5F6B01968BA26073A2B4D50B3D5187EF0983EA79A5787BE6E23C148979E9AB236630819C8E115063514054590670E7FA6FF25913708DF4C7A30A193021311899BA6E7F33F749EC04679CCC6E24C23CBE59280213056D2C71F903BDB769B545CFC1BF53C9C9E825345AD6EBBC6A6086B19E160B1B11CCE7D76BE9F2E335E115A6FFBE367A3EDAB359216FA57C6DDAA927FE58D1A824EEA6BA19FB63C54BC9C25C83F24B51954E2772BCD80246776E5E5950A30F85E05664C54ECDCB55ABBEC7599ACDD9AC8FA721D6EF099C65E033D2CC319D9C6649D5491E0F7160DD4E7EB998442C45B28A6537B999952A77B908896560DE0DE523329C98E94E440814B9BCC1E3ED4103872EAC7DA049831DB43F643766B412BC417A18591AFCEF418F898B0E1CF9D7E8B3961718F3D8066C2A220F6323C68C2A208DC6503563EB2A0541CB98B50086DF84AD0807378360F0997D51C2A7F803CD3435758002F933A44D099A1D72E791D7B8753EE116D5B896A270C4D6559ABEC9EBDD1FD541073400208332D78934953F0C69C5AE9A3CF1E9855B54DD0080E1108CC38F83D6B4BFEEF37C49668B4AE5CFA7551A5FAA8C3660D92C8385CB64495E243423DADE733E03AF0A6E6513B4B272182BE4B5360673E68AE4999A25B090B063C956247AC6781A60BD0DCD72DA26186DB0597C7BD796C7676387B59148FC19280F6B125448600F19643A2B5C7B65DEEEBCE490928BB42C176D51A41650155B1A528CE6EE74B190032F7EF7D337A45ADB2E3BE9BBD0DDDAC77A1B9336B6560518D098BCC8E24C8CCC4C992B8E2ECFFC89B46794918D6AC78A29E9BCC724FA487CFE1EB6D23AF5F76CCEF6A497CE48A05548B19955174997961085133048F3CDFAF716B6097ACDD43CE2CA1CCC1ACD7FB02EBBA182837246D62C0D12195D8424BB998D093E6E578214FADC5CDEE3B41D11727677BFCB381E38F79731FBDBE585E4A5477225DF9730C5108CD0D4E199778168CA84233B35F362DC40DFDDC120C1E033C508A0673687461874F5FC402AF61A62E5DE21B4B62863557794A851DDDD094A20A59219748BF71D54D4D35A14EEE2098D90044A95B4ECE40A679CCF781214E8C85A5BBC8974206713C659A8915753434314117F9D46011C8C687A4BD867B81405E1B8C53D493FB2443514FFFAA6A11A02EE5EFB90C61F1B93BE985FCBE6189635A35F50F81B0457534FC5A76F541B67C2685BD06D9A00AC4A56DAE3AE6FD44841734F89D2E0B42C04F7CE9A4F0B5BA28BDFCCD378E60E2D6101FF560E379FDCDAA13EE79CCE316C4E4D4D4ADABCE0C1FD7D90FA81360B6DB61F8CA5192AFF6E174B227A2975EEC7CF1A01F6A4CA5488B1263C693F5208B36D21C484E205709D5569DA755E5818CE2D04A04B35063FC2A7AEA853AF1E1DB3550FC7B05BBBBEE59D94 +ss = 787ED075F818BE6A0EAE99B113DBA31002097E0B85A5480003C505A40793403F + +count = 43 +seed = 49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091 +generateEntropy = e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +encapEntropyPreHash = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +pk = 26AB73A3355199A1833A1268A37A087DDB57AB621046DB1F407C804C488E4196048CEB762B9024C2157E7DCCAA1A762881280715A1467E766DCCB159F4780A39BC4F4A59715700070318C2AE03706B639F79A8A81AF34FBF6C9ACE4843151AB5C3CC81AF08CE392335E4FA913052119904745EC68CF3502F4663BDA74522DDD61A318539E10A853BC90A5B06AA12018C6BAC4A8123719C567719CB723B420540EBCD84C2787F37A76C6C40FC983436C26F7FDB14DF17062BE752AF2C1F1CD1026856500F3831CCA75EFF7A08D4D9C819D295674550C1C951FF9A0155856C3CC143824556C09025D55B0DB7192D969926C18912BF5CA8629401B8C53E23832CEFDB369020583B360595541F48573BA1557FD0C1058A8CC5EA7CA7F092B7DC7B4B04490FA4E72A37AAC0E33B1746ACA327258D9D29ACF140C5F70B8F94A23195D60D30A498259C6F9D06BD69F82398953B4FD39ADECA972851431B59C9614B7867CB1228E2519AC130F003903D801F70BCCD776A9B916684CD89CD71723CA732A21FECBB90D547646B987155CF5425ABBB2406CDC1821AFA8DA120A540D1C3AF175032444E1FD85F43F47903665BE922636755B5E75A90931C66E89345F57CA4A032959BDB4521CB62BB1377DC5C99FBE36C71347B81A80B6B7251FAC3732475009A719F4374BD5FF01CCE4601E761A754E05756968F33FCAC4D6A540D93951D0BB4D0D838A3112872020C2DC67718888DBF408941B877EB6543432675C879AA85F102E608AEDF267E32D333CA9C3860F907F17B553580AEC75902EC304E6C7996EE34061B40A9F4F8BA2CCC55775490DC9C2A6D5C0134E809BD305D7445C9EBF7B89F9604146B2E55A1090597033BAB2A25A3886DC524F4908ADBE98DC2D74386806AD641712D9C23A19562E4AC7F57A86FC98663E455BD963C4E63D8471B504C14EB718D8BCD6475CC45687F55099F8FE2035F3812F081B6DF2A174999765CD69433E5312BE67698346FA1030A40943F8927B2CD8A1E2CF2514333BCE85A89A6A99D03C4A5C0B847550972F9D1448D1819B3582B99A50FF97C124398CFF30967013C4DC4D374379B4E8B037EB0E570AEC147A1C99CADBB651BFB576AD61BC5449C5737BC4BA4A01F24AAD80375ACBCBAAFEB564665A192211B4D6918260C1251EAA1014C6F41427465609310D8B665C6763639C71AD48019905CC0874BE438023936856017B5562A9EE79686BCB55E04A38EB9B3BBFC07ACD4865860A77AF3B5ACF7DB344F139F79D5953778124C2C92D29CBFEDC21678E54861ECA5CD350FA09B1365FB74435316F37386B9B510E2BC585DA30A71ECC7B9913921EC8D8FBA2DBC97807B693B1E306832507CAC90410E0576611BA79C1CA9C0B106D0147680790EC5051798592D3035AEF57A0174CBC70B435710C51695852841907D41A8180123A4D911787B674ACB513C84047BBD5851C3E83A8A046062C06BD84397858241C95B8D8D2A2C53038856247506065A70A5A29B701BAE1B488A68C2BF02472D86BCBFE263E7820902102C612747CD60344957A871C7774A0980B70B56F7BC45F8E2BD2085AF080CB923B55640BAB2AA2C30F206CCBAD17BC9F58C1CDA80399962268F2AE99C43BBC1FA7D8949CD772A745BD9AB018FD3F6ED02F32CD2BF845923 +sk = C842401604C8C4C78D8417C804C2723B14733044AA2755897F65987951218361A07AA84D6AF8A956454036B79E145C93B9D4B862146BD4DB824CABCB61FB91BC306F851C9E93AC266E3C9E9C939BE422B07E512D28503A6EFA9D3EA8861E39B1AD481B8AD1805A8C0D48179AA1203C2ED7BB59D5C8EF651281C77F83AC7B49EB997965B161DB025B47CE6E2C09EDD41F5EAB1C8B7B4D20783D60C90DBFE6AC387B629BE10351868186F6A0BF68905F8C1CF34303FB577C25212919533C7044697D9425BFB76BD9D367F43B2D3613351D95395F4C2BAE63B2A4608C69364F41E85D542A08F35B940FBC3B48F63360B50AA88259C7CB4634E5A34300C5957A3644F6AE381389B53210110329FC61519113C17E64782239941CFBB11A647B814372E313205844592CC3C17319B41FF21A0BDA3F5ACAC3F18BAD085C8F27B7758B7519316653BA9C253DC94CCAD37F98D00B9FE67E2A13662C77921E4A9A86C8089682811E53A60B1089A1038483E615E6EB109A3B7636E02A44C2C3A81B96D84336CF594D24172BE1BBB9C7B3685EA45E45B81D731B9B75CCADBFDB768119B20A0C346156CBCD5BB107A00A0E3C6E949B9DB0B4AE21026C915908C5F38413C648EDB20623F35B382B0CD5F4A8D7062BEBBBCC9E809BDBB5C84042BCE2E81BB0D795C6786AF95A7E7B0629F7978A03558F98709A86319570273BEA71986AA92560260D022569D4C98A85BB98AA198DEFF63DC6BCCD1E6032EBAB8CAEE5CF4717B17D89125C67A8A472C371153A4FC9045FD3304A74B983936060F42C80454A005342C1318A284BC5B9A71A39E748A94739536B517DAC1619C00DB64C81001ACBC2793F9F29B42214442FBA962F331D48C300DA2186D21A4DE61C4B5948C7EDD1B9FA5865CAF2280A81B9F7171137D6A678C92745B1AEB9DB686BA84D65F6BEABE332FF036BD113161FA068E74032CA5736D3EA3A01F1ACFE067DFE5A5B398575BB9B148EE6155BE2B4B67B348420CE758C5855102FD06A1FE8D347EF1B073F064F1F7926BE5B2343029E5B7468E93B8ABEC6BE231B6BEE714031E04ED23C6DA37032ECC00374706EFF7453DD931D80029382F17E82A85AD7A8B25EA97D1D2AA21238B25517008B0400281168328B02869889F7F142CBF1AE8DDBA5EF2713DE649AA9AC56229494DB211B90B96AE3B2829AE528C634110A3BCD355A243F3654295B0B79B9B7D43272321959B3632313AAC107C8B7AEB83172778B7B199E736307FDF5AC6AEB40CFE750B7227F46A00B9000880D405877B63FF6C616BF4A51CA11C863A79B0E099308B42CBB7997420008268A3B762B9A5E181DA14A4A92A5B55E7950268A9A83402889A98835CB9562A5A627750A5348B3398B39783009A081A058BBABCC7740AF00B8CDBB4E0842C7F14B47FF4CB424B6252CCCCEE30398023A9B50B4BB4A2C1FF0A007A0A54EAF421FC2113F0353C7A1DA6CBF3C7F5B448B86534FCE3B3B82C3B82C3420BCA7C865AA22461B3D95522E9792B37B78C5555A62A3439F3BA7646076111336079BB8352A286E542094BB58B07CB832E2B288021034ED4934469B1723E57E57E358942730196140F47658258A761EDCBDC046C08BB89726AB73A3355199A1833A1268A37A087DDB57AB621046DB1F407C804C488E4196048CEB762B9024C2157E7DCCAA1A762881280715A1467E766DCCB159F4780A39BC4F4A59715700070318C2AE03706B639F79A8A81AF34FBF6C9ACE4843151AB5C3CC81AF08CE392335E4FA913052119904745EC68CF3502F4663BDA74522DDD61A318539E10A853BC90A5B06AA12018C6BAC4A8123719C567719CB723B420540EBCD84C2787F37A76C6C40FC983436C26F7FDB14DF17062BE752AF2C1F1CD1026856500F3831CCA75EFF7A08D4D9C819D295674550C1C951FF9A0155856C3CC143824556C09025D55B0DB7192D969926C18912BF5CA8629401B8C53E23832CEFDB369020583B360595541F48573BA1557FD0C1058A8CC5EA7CA7F092B7DC7B4B04490FA4E72A37AAC0E33B1746ACA327258D9D29ACF140C5F70B8F94A23195D60D30A498259C6F9D06BD69F82398953B4FD39ADECA972851431B59C9614B7867CB1228E2519AC130F003903D801F70BCCD776A9B916684CD89CD71723CA732A21FECBB90D547646B987155CF5425ABBB2406CDC1821AFA8DA120A540D1C3AF175032444E1FD85F43F47903665BE922636755B5E75A90931C66E89345F57CA4A032959BDB4521CB62BB1377DC5C99FBE36C71347B81A80B6B7251FAC3732475009A719F4374BD5FF01CCE4601E761A754E05756968F33FCAC4D6A540D93951D0BB4D0D838A3112872020C2DC67718888DBF408941B877EB6543432675C879AA85F102E608AEDF267E32D333CA9C3860F907F17B553580AEC75902EC304E6C7996EE34061B40A9F4F8BA2CCC55775490DC9C2A6D5C0134E809BD305D7445C9EBF7B89F9604146B2E55A1090597033BAB2A25A3886DC524F4908ADBE98DC2D74386806AD641712D9C23A19562E4AC7F57A86FC98663E455BD963C4E63D8471B504C14EB718D8BCD6475CC45687F55099F8FE2035F3812F081B6DF2A174999765CD69433E5312BE67698346FA1030A40943F8927B2CD8A1E2CF2514333BCE85A89A6A99D03C4A5C0B847550972F9D1448D1819B3582B99A50FF97C124398CFF30967013C4DC4D374379B4E8B037EB0E570AEC147A1C99CADBB651BFB576AD61BC5449C5737BC4BA4A01F24AAD80375ACBCBAAFEB564665A192211B4D6918260C1251EAA1014C6F41427465609310D8B665C6763639C71AD48019905CC0874BE438023936856017B5562A9EE79686BCB55E04A38EB9B3BBFC07ACD4865860A77AF3B5ACF7DB344F139F79D5953778124C2C92D29CBFEDC21678E54861ECA5CD350FA09B1365FB74435316F37386B9B510E2BC585DA30A71ECC7B9913921EC8D8FBA2DBC97807B693B1E306832507CAC90410E0576611BA79C1CA9C0B106D0147680790EC5051798592D3035AEF57A0174CBC70B435710C51695852841907D41A8180123A4D911787B674ACB513C84047BBD5851C3E83A8A046062C06BD84397858241C95B8D8D2A2C53038856247506065A70A5A29B701BAE1B488A68C2BF02472D86BCBFE263E7820902102C612747CD60344957A871C7774A0980B70B56F7BC45F8E2BD2085AF080CB923B55640BAB2AA2C30F206CCBAD17BC9F58C1CDA80399962268F2AE99C43BBC1FA7D8949CD772A745BD9AB018FD3F6ED02F32CD2BF845923E3EC3671CC7675A321AF8584A0961101C04A432772431E77F5740BA3B2EF488D8C64C049C6DFC0F1476CFFD520B055756162F7EC94243DE6B14AC0B9E5FB366C +ct = 2CBE4AFF154B9B03FA6B19F8A1CF698078A1876ECAD645E7BF54C76787FB3A9E0E8C80574671A194238B8E9C7C42EEC9BD0A07618D33654F392C2E9D8C2A817A4F9F95232E603B9F047A379788EF8D0C548929544E393BEBBE5733ECD4BC716B0B6ED6073E30D93A064D5F714E697446821D182968FBF5A116D7E3BFE5B941A9ED42B6C5F9EFB7252529F8264200387B846AFBFBE670D72D00708B663262EC6E80308B0DF2EE80CC1320C091F8BF309F84FA5941CDAC43906E009C29A7F7B2D3D300B6DAC7DBC0551A50D449585737D7502C37A06C0297CD0AA7F49AC1CEAB3EA844EFC57851816CC01160AA0E62D5330464EBF8DD7A52A126B4CD8DE48E449749F61FCD56E786FBF8AE843FE7E68F050778BAA5C871EDD2DA3141C59C0C92A2EF8F7ABB6FF994843B77599DAFAA571A2AFDC0D5CCAEAAD4F9E025002D06F2BAA7EC5540D81D19E37A46D1DC4BF96F0F85963ECEAA0ADECE063B2730BD51C1D46A345F25E918ABF9E056F8B8D6AE34FD0E0D06120B3D91661DA17F8E4B3E68AF6915D33ABE1ED9FE8B81D7A6ADF08043F0622F5544FC9450D340E35A27B78272F70348F122D744691F5350AF7A3FB6508FAAD9EFC859FB712EF016964CC7D07940CA8B3F2581F29265369EB6D3F52B05CC82549B325CC3F8B2A4EB0A321700EFA8D86F575EB58C73199E02D04D106E0BFF79F65CEC84995DCB55FF4726B84957B25175A47F13368DE3806B386397DF10E64C365F2821B0C4C52AF2E9FB4BF0989F97D102FD70913E0B8E1E6A540710B62006EC62CFD7F907DAEDD28A7BA49BAD94F60698FDC0E6AEC63B3379D95BC84DF7916AB5A07647A777022BDA537F7E8622C642710CE2D3B0B5024E137D46080217BFB3B28EB4E58C4A9537745C88E5504AE10059B68E1FABF5AB7D3563AE2BB167530B9F9B59ABC5D9315A80318EF928CD0C785383B397F3D0244ABD0E53CC2C8E3ACE455964A66D79742C1EE9E871DEAFF22AB04DBA95BD5A5E41BF08CB7DEF3281E4D5DF9A1FAA70CF30ABECFC907A3FBC64FC3E18E8C86F4BEF19BDF096A311F0ABC76692730FA86C39EFF9451EBA149118DE84A70CD6EA2088F52EAAEC913214C79BEBFC6189E0BFEF3F058358C069A5C1CE7F55A00E951B72221BE1F324190D03F6F2005588BCB76B2BB2D5DAD1287D5E60FAC5A4C07331AF3213EF3AA063AE15A26A983490310AE8EC1F1B9B9C1495473207F0C399D4FE27DC56BE8BB7C8AF3AAC5344CEC1BCC14BCC15CFA9A8F2D58B4BCB5A6515E8FAB65EB21731A6465465A2F16D7672AB6E7BDC3F052727A2CCBB03F76F2444CECBC52B5C79E32D757DED4BD925625E3779BF3725402480F1134D707D9EA3D6A6A30D36B3033D3019D7A537B96EB47908007A396F85B5E20D2667149A3B09A3C87899B58FC1BA0C36A1FADC5D4CA07D435798E1C15D01695C40C6497020AC8BA979E11062957416CF08871AB93BFF007F86C771E3750F7E648C37C95161DD141A80D72F7D73200859FCF81D60A321962A5068CB33A8F31C +ss = B81E1EA69C6A6E1737C78FE18C36CFDCD26CEF62DEB805F22A92C49DF6596C0D + +count = 44 +seed = DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE +generateEntropy = c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +encapEntropyPreHash = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +pk = BAC16E6E3C5E5D9C8CA207A5C77C7883B917FE0463D3101962B802549A87BF39B9BC7A30A5B654C9C96B14BC61506371E4768429DB8F7C0A6204903B9BC9311C66B907C5825621B7EBFB52F6C7CF75C169C17129595631A2FA95920317AAD4CB338329ADC69C6795158558638C474710C78763E012240CBDC2E586ADF93C028522321A94CB766F9E983FB5110A10476ECBA92FC0C120CC83632409940DB249EC569ED5740471C86623B06962910307781349F342C759886F7C376CE708091019FC407EEAE76409387D151C97CF7270319143471A84994BB596F9B5E1A78D33428740FCBAB415C575E478DB4B4E30771802E409B8C1AD4ECC9CEC1B7396E664645CCE83A40D512684E0B2750D8445D2180BE5B4CFC09BC9FFFC8D6E49B49D68C4D849B584512CBB55283722CED5566149811545609A4C5459F523C1C76667859760E690385F65768331B7654C30B8C0B26F2B8089A3C5B4F21EED42179C54AE61D22736512FA3AAC6EB018946A47CD79ACD545719C829B304477541EA92B10A1CCAE8B36BA83D5AD83083FCB51DF653CE899227C52581699B7150456CFA1910212F7678056A33755DDC7D0648164AA297F196057060009DEA8D87E86B6ABC0106A5536D7C83933AB12E294B4F50870FA0BEA16AB49B88A60BA7790549CCC0E6571E81875D5632DD8A5627E48E0395BB4C243ED9D53CCE7B591949408D2C87A5E295E3C3231F4132E1117B835529456A53D3D748C16280F4D597573685B04780F611094C665C66164A1323C290BA8C8B1031B142A3B53062AD5C59D8D112F9926E5AA591ABA711EE2BA1509AA09B86C60A969020D74E238B849374BCAE7788FAE61296D5AC7AD0927EE30912C4287E3981B7851D5823295076365196BFBEE4A3CC189020254F31B06FD8D70C43A94CF380C01936465A334FA59B3D39296305DC8B775269EE204639BB3A30AC437936CBD734A5C6477B2A451EAA0159E571BB12473B77698621D5247EB5012F608C6F070A67551F6F63ABE87BA12A56B2B2DBA44BF72E01C9A2C490579D2C103CE91A841C4F4B3AAFDDAA0CC3D33D31EC3FFB4A3F9AB87F93494720D386BB13CC482A4ADAC46395479D1421AA91216BBF56BCECB89F11588B4085A62BA0A47EF9A184C2C9346525CE006CA4819857FAC8B1498C9CA1222175CA5B01B6BD502F69F8977A0B3B04987A1897A8F2F20DCDDB098AD070D15C15C099A5672C17087C6B58245BC25C382ED3BFD5BA9B8E48932A27546A089113F37E8C85971FA10D465970D61446F106CCA6200F85EB2DE2947BB4EC57E58C1F7BE6B6FBC025A4A41EB05C516578AE9BA4C197B692D20976116BA35660CC5B612B616269A837012230B65F2913E5D0362D0B510F1272716A4DD2832D3BACC914929FF33354C01217D8A0745C9263B5D80A4F497D99D98A4D895B59A59A1DC173CA6945FA54C398F351C8C3AB8D66CB8971A68157CE3CE82104094FC83C7306D242F1F0497180842BEB8E126988C5A830D2A39C2711B033490FE1D53E432C7A453B4CEB05A5644253797135231228F246BC6A1445EFC16B2F2BC674327A62EC32DBC209F2C4A5C600920D2856DC34549BC4656F7953E697CEA6F2891FD65321F89BF2D90CF3DFC681C2FD81792135E1938CA482EF3C253D8976201852444E +sk = 0C9C633FF39D1C6C29F8356AA02981DCF189D6535E2AC00750C30B111A88B21024E4823E7D543614F30112F7C78F1679DAB68B71AA992538658FD0C8E2984ABDC09647453B3FD99DD860238CF40C9112A7DCB57E06540148EA4AD6F97020474AFB65C5C67AB4FDB1515C6592941B1E38D4097155BD194B5324F464DBE678ECE9B5F8F57822F87ED7F3A6B470CA3FEA3314B4BB404CB66E3BBF8F2953F2682CDB65CFB47906B3962443775796564D75CBB4B9BB24A8A98D7723269E8204BA89782F974AE591808E97CB2468252C8539C2454041C9232F33B43ED8359DD6856C98BA4FC09E92F9A4AD497F8F1159E159B5AF795AB09C20AA753931F47764B6CBAB6968C7A779802B469ABB1E7F677A0A485FF5CAB2F028112EE8C35152703BB14127B33FB00A0CE21CC607E49A73544029BACA215A67091A9AD89A408794C4D2DA78557B1D31686C6B4C3749958EFC60891F12C9E0B7C19613823EEAB1D8F672089339E46C16DAF0C3B7D53727605C26A723518A2651D8762AC373817BBDDBEC1EBCA2CF91FA2A66896C55A4C946A791E5502FF19AA21CB132322BBFD127C10D87563028BC49B222E5401ACDC81991828E4C111A54566E5724B40A452C0F4632B7B85F0445C881938134D516113560B0065BEB409FCEB25F796C0BA0AB190FAC0214007916CA93C2ABB11BD88553AA34C3C518BFEC423728C86E529C300A1F70225F2F683911040FF9405614E1BAAC070E0E90337E134E3C93081514A937F9798EA7B57B3A3A0B829A2697B0778C802116C067A5C368576395C43D33882F97C770519C16426284E19BAC180A2A6CB85D65B1A115316B08541DC231C123C184E82C691F20749A4B92F2D1040D09519DF7678AC282FFF9CF5124ACBE04388CCAB61BF71B87AB3B830A3EF6700A68B06770012424031E89A895AE81C8ACA9169D6495CF01CD8BA0C27AE132C16AAB0EBC4B13ABB37D67CED10A0246E87BE1233FF09A6802F6371858972D21B48D410D8CF3A8A1E664F62028CF851A134037142C20E8EAAD7DE32581B39B5D93221CF72124A73DAA2B61F3D7C8F25A973A815B351206800BBCBA60AC8C2A86A7758B38339751C23EA5523D84EC982A260256C69AF739349D206CE9C9A70DBB0A950A0B63815994A6878711578BC22942914DF8489EC5A09258EBA796E8A6FF5483A71887E55783A94201E5B88898870E67D32EAAB132519624F4B28F22E80903E591331CA792C0CEF824BC62168BE6EB8F7BA299BC519B0C370509E38377F171761521F8FC882D1B8D0DB3C2109A43D1754F75529F7B071B7492B753688FEEF12FDA217CCBA484AB79192B7933781811986430BCC010B50A5621EC15DC7BB545CABC77C336892A0DF4436E732B905D70769865CDEE0A9906438E9D921F521862A3227BAB93202DA0CD19F6221BB68FDA8155AE38132CF2A30A4A5C3DC0B17DF0016FAC3BDD56CD9D06CC8F2C6B4AC41207FC1AEAD0CD87506CAF5C043941513F0A4ABF725818C7686F0745ECE93C23F2951EE263F51A3FB3630076DCA4EA80A156DC6B4248246F638024B8782C9757E076CEAF18CC27284C321BA91766454640AD32D97E65650B39C9B23FA80405F8CEC82ABF70EA4FBAC16E6E3C5E5D9C8CA207A5C77C7883B917FE0463D3101962B802549A87BF39B9BC7A30A5B654C9C96B14BC61506371E4768429DB8F7C0A6204903B9BC9311C66B907C5825621B7EBFB52F6C7CF75C169C17129595631A2FA95920317AAD4CB338329ADC69C6795158558638C474710C78763E012240CBDC2E586ADF93C028522321A94CB766F9E983FB5110A10476ECBA92FC0C120CC83632409940DB249EC569ED5740471C86623B06962910307781349F342C759886F7C376CE708091019FC407EEAE76409387D151C97CF7270319143471A84994BB596F9B5E1A78D33428740FCBAB415C575E478DB4B4E30771802E409B8C1AD4ECC9CEC1B7396E664645CCE83A40D512684E0B2750D8445D2180BE5B4CFC09BC9FFFC8D6E49B49D68C4D849B584512CBB55283722CED5566149811545609A4C5459F523C1C76667859760E690385F65768331B7654C30B8C0B26F2B8089A3C5B4F21EED42179C54AE61D22736512FA3AAC6EB018946A47CD79ACD545719C829B304477541EA92B10A1CCAE8B36BA83D5AD83083FCB51DF653CE899227C52581699B7150456CFA1910212F7678056A33755DDC7D0648164AA297F196057060009DEA8D87E86B6ABC0106A5536D7C83933AB12E294B4F50870FA0BEA16AB49B88A60BA7790549CCC0E6571E81875D5632DD8A5627E48E0395BB4C243ED9D53CCE7B591949408D2C87A5E295E3C3231F4132E1117B835529456A53D3D748C16280F4D597573685B04780F611094C665C66164A1323C290BA8C8B1031B142A3B53062AD5C59D8D112F9926E5AA591ABA711EE2BA1509AA09B86C60A969020D74E238B849374BCAE7788FAE61296D5AC7AD0927EE30912C4287E3981B7851D5823295076365196BFBEE4A3CC189020254F31B06FD8D70C43A94CF380C01936465A334FA59B3D39296305DC8B775269EE204639BB3A30AC437936CBD734A5C6477B2A451EAA0159E571BB12473B77698621D5247EB5012F608C6F070A67551F6F63ABE87BA12A56B2B2DBA44BF72E01C9A2C490579D2C103CE91A841C4F4B3AAFDDAA0CC3D33D31EC3FFB4A3F9AB87F93494720D386BB13CC482A4ADAC46395479D1421AA91216BBF56BCECB89F11588B4085A62BA0A47EF9A184C2C9346525CE006CA4819857FAC8B1498C9CA1222175CA5B01B6BD502F69F8977A0B3B04987A1897A8F2F20DCDDB098AD070D15C15C099A5672C17087C6B58245BC25C382ED3BFD5BA9B8E48932A27546A089113F37E8C85971FA10D465970D61446F106CCA6200F85EB2DE2947BB4EC57E58C1F7BE6B6FBC025A4A41EB05C516578AE9BA4C197B692D20976116BA35660CC5B612B616269A837012230B65F2913E5D0362D0B510F1272716A4DD2832D3BACC914929FF33354C01217D8A0745C9263B5D80A4F497D99D98A4D895B59A59A1DC173CA6945FA54C398F351C8C3AB8D66CB8971A68157CE3CE82104094FC83C7306D242F1F0497180842BEB8E126988C5A830D2A39C2711B033490FE1D53E432C7A453B4CEB05A5644253797135231228F246BC6A1445EFC16B2F2BC674327A62EC32DBC209F2C4A5C600920D2856DC34549BC4656F7953E697CEA6F2891FD65321F89BF2D90CF3DFC681C2FD81792135E1938CA482EF3C253D8976201852444E79836213A513BD4CFD42ED281304E3EE4560E4E0C60FA53781F83D5BD2BBEA52E40771856EB77E4633504899FCB86C6A3D433D0B8D60E26F07BD61F1D4ED69BD +ct = EB1E2D9E00EEC89D9C0133C36834B7704FCB880E87D28F6400D5B6FA85C9585518C29C860958C2B6B1A239BC55B212796ACACBC4A2657D67DD1B61E9C36EE9682FAFD6E2231883B27587CC5CD4C36B7BF29D982D729BDEDABDA928370989F0F3FCE00A44561EFCC2A5B77F16B4C982554783D43CED6A55BAAF9FAB462813A8BB2A98CF16478AB4F1E79D0120D753EC0BCE0B4884FB27E02FDB881F7B28023D91E23340A67DC9E61B64AB16AEC77D36DCD0CE1900A7C6F3758A49D36ACA01E8E24711171F756A3A01923D896BFA63763244794BA3D01710FE2EA4064B70702ED34DB2F715B2E59683EAC0E66B6BB392DC22FC398CCFEF06764CEA27A3E2FFC329DEF35F16F357FB9A7ED25066B6A6310EF657FD348C716B468EBA86594CE6A5314CFB9BFE3FA04F849ED485459980D0FAE670A2134908C38727021AC148D041B496A97D09EFC807F2EF9A2DBE5F1C3043D3082A9E8108C020CE7B7CA6777FB3275CD0C8F8299E8CE81C1972C079BA37BF2C8BA717DA95E26225F7CE0D32A96D42045A1163A384988DFBEB1C9C68F142F1DBE10BE93F0FE5B2A2E4235ADC8300DE98A6FDC2EC76D34C4EE15DCF33DC939E80AF2DDE285E72D33E4E49A6B7DA54E5E29A072C5D19BA548D714EB4C50C9E8FFAECF92CF0B66E2D365127836E4B0B6151F29F7B8081E7DA720AAE3C66EF3D7FF2AAF0693858403AAFB7C8CFBB4104FB2F1F286DBDFCDC9A9652C724CE3F46396DA21D18A8CAC249FB2C564C638A90A3BA10295A3995557E5A171626323B1D5248798E99C8A5E0AB96EFA39BFBB2774BEFDD5939B385F881FD60CF6F86697141738307F8D9EE27863B58D83DEE565FE12308D56887AAA93DFB8DAD892792E9D2E417C4AD98E93969182BE4EEBE50102B2DF3FA72A21D271913342283F679ED232C1CB519F152EF163E3CB85D2C3F7A5E0BD44106ECE5FEC8F7CF339C4ACAEF04A1CE520EF5AEA622D63738848D7E9AC753F95267D141F4369A1E2AD2117C57523342A32716FF775F332DEAA64B6038A4099A8AD44ECF7F38C1395DD2C45ECFD9CFD7F7E3565E48EEA8C90DAF62908C402E2A421613BD321D7DC3065B6825BA8A3ADD20EAE7A9BF762446023F2DBB70AF8722C9B1CB20B4622A79F442C548502DED82CE1762DF2131BBAA0A5384B8ACC0AADC823A0042B91A8A3D32E8B003794EFAF87F28FBA18DC7D4EF29016F59D952722CCF1CB27771E5DD17F395BBD1F1FAED18BBBB579E8FB8F5A704AB587BA645EF4B51EAF09D938C30F9B79C7D67D665A9824738A547FAAE4A6C0953A3C529209C175AC946F733C5606516725A1E0626BF684A4D3AF865FB95EBC5ECA314369D5FC97B53A76FF921371E0F161F1E8D32B471906174A0B667B9C16881442FA631A169061E6B545C2BC32528AC40370884F3E9F362B2CCA5461A92605B0D7D270176B68EF60645AEEE9948FBCC1E1F26F6100E82C1FBA412F5D5BFEE5158044416CD9D4C041B17503863815CAE0ED0792052318B288B5DA1CDEA8C0A49AC381376 +ss = 5D014FDCC992FCFCBDF3AF29E8DBC9E5024F2AC41E71A3EF0EA43A063BF44E79 + +count = 45 +seed = D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488 +generateEntropy = e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +encapEntropyPreHash = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +pk = B873B2397A7C7ADA2F4B0B589EBC97C50174E4317ED5D9CF2878C924937BD258BACBFC83283A218D443D8EE43F8CF3C64459B189E6B3AD100A6C6A3EDE9916F89B8BB67CAC332C0519F502A4C427F5C9AF1A16A59A2122521A0C624A20149765E986339ED63567CC29CFF15D7E8AC026C96F08D6AC4E057DB4E66361B18CCDC3BCFFC300A996AB7346232DB7310662C75B39AD7AA080B23763ECE54960397B8DE836071B8914D56F95A681ACCB8FCB9529E5E4CFC2EC0601F7B0B291524E180AA0A69FA74AC2F17AA88162C481F51543A5A527DA5C42B59F9A72B14DC91574B51E5806ACE3F022D1F19E3EB621560478BB70BEB8407719A01E16313D2F0C785E3B9886F679ACFA465BA974676C0689A149AC04996F4132DC4974F2FC322B56115A64B0B5DBB8DC71869CC655DD61390B032F062B024BB71505640A41CC6174B68870DA11EAEAC28AD061F3ABCCF4E12231655EAF9285B205251EA69371D90527793495835715AC005868A78B1CAE80025426848C4AE869B52034BB266E1B97480AAA7A31E384780442D9933FDB750EFAEAC0BFA802E5314D28A17D374CAA05B46121E16362E8341DD923A66872DF3C942177B58951C40AD1641F53A53D8708EBCC22AAC67EF262B6155007DC6880A1F45CAD3A5312B282055B1E0B181D9B396591FA78DFCCB9D6A92D5CF8189C14C68CF4238654716F0A1E4F2542CD35A7E4E2185814C1F5B16D8C423213C69D5958C46960B8DF589C185087EC5474DF3C5112B5BB6BBCC6AB7160ABDC2AB28801D775CAAFA049479A837CFC8847763559EA86239889385BAA43A2848B489087FB43AA20ACD7AC05606767798500F9271271E52032F21FC2A82D8D15BF774771B69C570EC488053743DC5398C4363AEB3932A5C54D16F45A033386DBE3B2D0A851116C2CD2FA4671B95CF7E60BDCB4976A2393647B714031870B1A6B2D486A5CF2A8093B7B948C9418F3A27F6296EA12336B8A6DD5A5715CE9A70DC6978038369A10332E3AB6C2971961D5C66441ABC3290113B21C46E96C509AAF09E658D9B77928935B9A122E42BBA23F920B58EA48F3F19A7924128669C09E135F772C275E55904400495153A691794A8D182EE1314446371501E87C41A944F850C9CD288CC2EA90A4E27864C79E554CC5924C4CA9A217DCA424EE8B76E49993AE4B085E9809EAE27401EB9C6C794A67A31705876243478F86D5B9F9CB3295422816526439950A412B4D1D28A70C6B9794C959BE155AADB39E00B418EFD0664B08843D20B71C547F1468C5FDD92B9D818336282F34F19B515946A7961B5A9319D9444CDC1ABA840CBB57272E4DA4AB20FACD5FE4958A57C3C812978FD772C2862DEA8B60B30A601B692DADAABA0F361CFF27C5C734A42265341641B861B7899CB311E7E0ACCE396BCE2809F24289C5361B91CBA88493991987C0ACA3B070411481E154104C15780ABAFE725DD3E1ADF00BB0EFF4A29298AC10C63FC0669DF6379294AABB4588AAD2087C9C16C9AFB654F0C9C213D79CEE1A843A84742D574DE252A4F24795E9AA631D5198F07511160300A2E02A402B4CF8AA556CE67BD341307CE5A1EB6609EFEA3F066379865489701783B2C95EE6967F0893D44D76104BF396577FD719D69EB306117F3ABD65385A87AF12D1BB6D0433 +sk = 2ECB7CAA911A2F615A13CB82E5A8BE85E1C2BCF06C71B9696682532639B57A91537E470E8514390949CFADC80B0E5C3EE3ECA869E22250560D8896B5F6EB0FC6EC0A6D01760C9108B7A26CD79039BCB3CF9EA0432FE0581626CFEDABC12F758B407C8E9DFA373F45C377FA6D41A7205A7322B737CDABC8114DF437E864C4ABBB3DD084964F971B36E24406A7A7544A260D917C0EF95CCF33B1833BB6D4232BFCE37B96004ED7779258FAAEDD9ABAEB5051D8F605EB85BE0F9599FF28B40587488FA376729685A8336C0DD213F55447E2C4895111B98E73BD783B2D08960ABCE22F6F894AE5456577A81156C66F6F1BBEBD9C04D1AC43B77936F13060D3305A3893A825781E47928FC492ADC16B31B2669882FCA10581603B400F297B7FE7525D20E82958099B2D118ED3A14A8A915731525C470B7852A9B0EF04B4A3B0B65B4C5D7D486366175540A91E752993BA979D8A446F94088C7C3A02FD5C051F900A141957E63CBD71AA012DB60A02B3872F3A623218A6B1F628FE8580E8725D9FB647F128C2519A8A0CD0649671616B462B83904CE621C95FF44697CA71CE930EAF0B28A6448A1C6B38C14800427683B71C954E49B6A3B978417B78DDB1A1B9729B89160B4C7BA49F312E23632460913D82D655D6E00B5B17A635827D8A0781E12A68C536AB40909F46A7173FA9CC9990371DCBC0B8A433436133AC123A73664A14E1409B4476AB001C17F26EBE968ED8C6A9D491B92F234499435E2DF615C849BE5F6422C8BC9DE8F148A7C0713D93642DC852B33652287010F02B1D7B77972C797ADD3A38651B4C11EA968CE53F10D38DF4160101FB0EE557BCF5B3328E12150A7C0D769812ABF2AD2C1C7661844E6B34B25E7A30EC64B6E7D4282F48344BFC6F33AB3C428C76705CB9B1E9637721C9EE60874017013374082892B4AF174749041C606B3F6690146BF1B0C8D2844F80594F265A8FB639E209C9B7FC418A230AAF340BBA34C1C66B7D570918ED6CAF8F62768620058CC7CB4FE1C762AA96A5015B82216E204C5821022CAA84AF9B12B9C9BC683747A2724C88E650539779742EDCA6A6A6C5F5D68FAAF73D4CC7AAB9B105F3A1B46CC96C915912E807AA6C841F6BE63812062ED1D07BC9164ECCEC7E6662056313CC32F63C6181CF3343ADC9073888D5756F508D65025BF6490A5F6B164A942466E60C4410C72AA69D2CA10459B890A4CB22A7613D44E70AC96ACA21169F932A6134D27A6C05582E830C0BA137DF060C6249B360831CC6B993E3D455C2E61694B11B520C64078BB552A65A3BAB407D46C0EE173BBB52A95C7CBD8612380FC0CF1655C8E691BB0493103EC80A5FC92B4951A0D78768504284AD52580F16247B3C44AF0A397F28CE3D0C0E4D34CC48B26B3998B060F2A9A013889685446B6281B3341C08E8300A013390A881A3A4937B412BF4745B069ACBF5315B9955AA4999BA827BCCBBF776829291A9067272059104522D69D1834886BDE76C078A6061305833FEFA710EBBC0DD0729493A285ACBCF2708CF93ECC76B85691E20BFA4379C8521420C231F68429BB5C76E69378F6EF3475FCA5760A5BE829C2B4FA955E0E0931423B0A615194C26225BC538E2DB29B873B2397A7C7ADA2F4B0B589EBC97C50174E4317ED5D9CF2878C924937BD258BACBFC83283A218D443D8EE43F8CF3C64459B189E6B3AD100A6C6A3EDE9916F89B8BB67CAC332C0519F502A4C427F5C9AF1A16A59A2122521A0C624A20149765E986339ED63567CC29CFF15D7E8AC026C96F08D6AC4E057DB4E66361B18CCDC3BCFFC300A996AB7346232DB7310662C75B39AD7AA080B23763ECE54960397B8DE836071B8914D56F95A681ACCB8FCB9529E5E4CFC2EC0601F7B0B291524E180AA0A69FA74AC2F17AA88162C481F51543A5A527DA5C42B59F9A72B14DC91574B51E5806ACE3F022D1F19E3EB621560478BB70BEB8407719A01E16313D2F0C785E3B9886F679ACFA465BA974676C0689A149AC04996F4132DC4974F2FC322B56115A64B0B5DBB8DC71869CC655DD61390B032F062B024BB71505640A41CC6174B68870DA11EAEAC28AD061F3ABCCF4E12231655EAF9285B205251EA69371D90527793495835715AC005868A78B1CAE80025426848C4AE869B52034BB266E1B97480AAA7A31E384780442D9933FDB750EFAEAC0BFA802E5314D28A17D374CAA05B46121E16362E8341DD923A66872DF3C942177B58951C40AD1641F53A53D8708EBCC22AAC67EF262B6155007DC6880A1F45CAD3A5312B282055B1E0B181D9B396591FA78DFCCB9D6A92D5CF8189C14C68CF4238654716F0A1E4F2542CD35A7E4E2185814C1F5B16D8C423213C69D5958C46960B8DF589C185087EC5474DF3C5112B5BB6BBCC6AB7160ABDC2AB28801D775CAAFA049479A837CFC8847763559EA86239889385BAA43A2848B489087FB43AA20ACD7AC05606767798500F9271271E52032F21FC2A82D8D15BF774771B69C570EC488053743DC5398C4363AEB3932A5C54D16F45A033386DBE3B2D0A851116C2CD2FA4671B95CF7E60BDCB4976A2393647B714031870B1A6B2D486A5CF2A8093B7B948C9418F3A27F6296EA12336B8A6DD5A5715CE9A70DC6978038369A10332E3AB6C2971961D5C66441ABC3290113B21C46E96C509AAF09E658D9B77928935B9A122E42BBA23F920B58EA48F3F19A7924128669C09E135F772C275E55904400495153A691794A8D182EE1314446371501E87C41A944F850C9CD288CC2EA90A4E27864C79E554CC5924C4CA9A217DCA424EE8B76E49993AE4B085E9809EAE27401EB9C6C794A67A31705876243478F86D5B9F9CB3295422816526439950A412B4D1D28A70C6B9794C959BE155AADB39E00B418EFD0664B08843D20B71C547F1468C5FDD92B9D818336282F34F19B515946A7961B5A9319D9444CDC1ABA840CBB57272E4DA4AB20FACD5FE4958A57C3C812978FD772C2862DEA8B60B30A601B692DADAABA0F361CFF27C5C734A42265341641B861B7899CB311E7E0ACCE396BCE2809F24289C5361B91CBA88493991987C0ACA3B070411481E154104C15780ABAFE725DD3E1ADF00BB0EFF4A29298AC10C63FC0669DF6379294AABB4588AAD2087C9C16C9AFB654F0C9C213D79CEE1A843A84742D574DE252A4F24795E9AA631D5198F07511160300A2E02A402B4CF8AA556CE67BD341307CE5A1EB6609EFEA3F066379865489701783B2C95EE6967F0893D44D76104BF396577FD719D69EB306117F3ABD65385A87AF12D1BB6D04330C2E803C2872400C49E1BB10232946AB939319E84FF32CD354DC15D082CDE5A3DED5EDAEC5DE3BF5B4D7C2F2E18E87F499C1968993EFF196753DB8045E2C8BA8 +ct = 388475CB89B7F408D2A18DD764070424C7598C459F203221847E08ECF1FDBD3B5F1878CB148EA1E42A1790BAA2432029C674916130A30AAD99DCA2ADC8AABE96C9437AAA361C0E28110A8B6BD9AAC047191B728D9C84EBEEBC7EA2154EDE6065F9313C47DDB6A05413FF5E3571F69BCA571770E9E217136038607BEF7F60CF079E766CACA7875DECF7BF7A8B54D688BCB63EF920586F4733AB3D86BBA18540A20D27C135119CBB7DB4E0F8896B0744557DFBB3C0F615130505E59FBA005B57A317FF4C87BE8906B54870A0C46136BC89E144502F41A2B4564DA200E0AB5A3FA91836F4858FF298456F0C475BB3B8BD057A63B6F9B5DAFDD76C2C111F7B3A933A2F3CE069427077C58EC94A158B6CB4C13FB027CFF9DF3FC7CAE5BDCCD31E3F6A3BC95E6EFAF8CA24F773056AF6C8D9B2798057E2366BDD54FF417B8BDCAD4FC0FF8E64C6D258438F98DD0682A716BA2FCBA64B4CB559630635D115DD846B7182DB50A7B92C73463673CB017EBE6CCE190700E73EF73A790FA85F04656D0085023F483F50DCD5BA9F0EEF8B3E5EDDCF0F4090BC2D243215321E606C4107FEA5564041C07705C545D7956A8E163B9B641C7CEA51AB67A2C29BFFE9C7CF0D3941C0E45664A40F2AB5031C2BDE8EE7E5AA4228685A845F4CBDE42DC3F9157F4FA03631299C84149206B7E087CD56A5809BE0A7CBE54509A29AAD8465BB737DF2631E86DCCC3ABF5ACEA6091813F1E9DC49D9F998C56E72972D9CD51A95A95B59B9AC98B8EB07957E59547FDB243F873FD5A3E77478A6F2368177BFBB95F2D8B2F7924655E271850A72680D2C7ED2CFE57ABB59BE1DB29A84C715828AD7E06E1928747CFE2E1351FD07534AB50855818EFF4CA87A60E86217F991C12380255CCCA0FEFF97C35C7214157F533AF3605B54902AC8300C8E4CD496033D3D05752B3AAA85F5CEFE81632B19263F944C637DCE318E55A8A4BC5AC296DE727708D86367970C17DAF3012DF0AF19A32169153E6C07C28379761B64CA1B87D7A1B8680B9749936D205DA28B2E8E9AFCDFA26C975914332538A54730D96037AE74439289AA97D76045103540230003A430A067C58C881BFBF224DF4DA5841D1B6781937F933267C32698908A6D31BC0402E3274657ADF416C3C9D7378338593442D4CCDCDF7ABC61A45C4EBA05C0737EF175C6F01CB7022A7905A365866961F7D45FAFF18455553012D1A79225A08871971D926D978B5ADFA1723314991467782B9CF2FD063CA70A49EDAFE31BAF3CE55016713CD15F8828A09FA4D6D093C29DE550EBB0BE37FCF1C5A4B6556153578587A0762054EC01E0A114AE186FBBD97BD83F30B411563B4E4369D7A24033ABDF1C0CDDF0958F2CA2272AD358F4C60EC7251E899C6C11B001E4025A6733B270A893F384EAA93DA2F6C4D8C2DD92A1B9305252BE65C3776F5B6DBD92EBDB9E12955C1358C011AFBA5FB7E52AC27D64FAEB290177CF6195658E6D2BE5D6040DE2D26677D47349FFC38123B576A6382ADF7816344D7E257EBD +ss = 80548D4687DA93177D06D98C1E2DEF33FE85E770F8B871D2F74CAE533F654692 + +count = 46 +seed = 6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493 +generateEntropy = c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +encapEntropyPreHash = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +pk = 0846C63E2C3018BC8733F05F8CE3B614088A787669205AC9889BCE2D3B523F366F4BF811F004666B2B654431B135D97A70A00FB9A3928C1A4A2C7285F6F7B19BB766BBE6B966B4013EC06833EC6F1118A772C2465D81B77BA740B7EA33129218542A41E2F1B10F42BB42396E9A6C5011351E783641AA692A982272D9544AC93580FA6A51B8C7B6A4B5B1CE3B58F1D901855BBB2B68B988953AB63607D988999ED96E5A4B963497A061AC69BD90C4EAB7C0DC17820B6963B0293D4CA30D82F5997A877A9AA71C5C7893C1D153AC6779D0A88190B13DF828BF3AFAC9D7EA392FEA899EF844535187AF673972399A5FA31034C02D70B57B97434ECBF3B1985C86EC75B23AC0AFAA67225F12A257B78341966BFD2569670680E012899C112AD3873AAAF26D2F4A5C8CC133C92B9A446530C169B6B87B118D03329374A71ADA1778A2035986CEAE200C763A12B6E2B2FDB672B4D58D8BE640E61576F2CAC617A5ADA5D1B874BBAC9D272EE4C881BBDCCA1C9A84626012B988395EB5A4A48BAB1E7551B6CB57EA7B627138C3AC252BDA1A83CCFAAD69E38CEDA6B149C1B3BA295FD5025C63225CE88CCDFBFA6B3950CBCDF96E14DC0962745A5FA32D10525F71D895A2085620C89024D922359741BE366CE9038AA3B260320A456858A7B8D01BCA12316E9C6D1782BEDCB590A1D2AD9ADA0C26D3818652CE6F3B6403C94DBCD1424D090E9DEAC559472C9AC19CBB26C16E8B27DB9140A1161EA96A171728689CD6B6BA0C8002BA6C46719A1A0C175638770CD088AE29A7FA958209788ADE14354A1B0880F05EF7C15A6786BE063B357FC7521973ABE4FCAC0A8C26F3EAA052959E2F973709C9C6BBF4C889C8B76C0AC81353B4A4DC81B7D316F75ACCDD1911DF10A7E838A7C2023EA1EB0A956ABB53FBA02C48396807229F492966796805E04AD62B8107493AAB264A5BEB32F5459C06AA6E7F79ACBF171899A911FA910DFA6687B2C28C1D419A4817ABCF656FF669B587B72374F3CC20B92858361D21BB85A3B9ABA157100875C993B54CCBC84DB2D72374BCAE29C5479CC95197E625DA047447EA5797551595853651912DAEC4891E68901BB67FAA98BC5050BB50E913645874FB7A0E51C816ACC88A7F8A4AD383170A583A2E17B0D5766E12DCC827386BA8D868EE16B2FB892ACA3941CDFA7A487C13AF9787A309779B759CDC037C13E839314803BB10A3AB19B7FAE477C8C322BF05BD3AD9CFB0B241371C85FFCB607748CB518A6C896830B191737BA289B15288AB59869E22637C57019818801EF9A6B7160AC1B5B4D7519B41905E6687B3FA7230EB88A3C9530813561308B68BD2B740E7AA08CA72CD6468C008CCAB34AB99B6773C533B3914B19B2B80BF7E783E7BD9366C8962E7F3410F34651EE606EB737E6C9C5F6D306AF7348CE955228CF02D15B8ABAED16994B56260221BEB1A29BE5596E204B9CE111127989BD2AB49CF27C976F74AA7B084FA6B8400A25F3C36213F7C2D160045D865C75AA14542F5A4E4D1459B5676491C6A3FA0A2F0319CA1A63A401C9C3A14C94F0016A9A69E64C522AEE93E8B96B4F6691322242B20353E0D8B995A6A9129E961AE7349F92C92A90B833E82B9FAE1AD459AD417635C409C28F9EF936AE28D221563E30F83162CEF01B482889E +sk = F3AC3178BC3E6B8002EB20046EE3288F9CC63C1ABD0B14A118D52E2C9A998D4C67E2014415084F520945F55B985ADAC8C503079789AECC491EB7BA540F32BE8823A4A837786BE140D260CFF5D46186588F4FE2419E0C4BA1B619567B9D8206B53AB1289640520F2259F5D6854871498B23696A321813D7A544E77FB3100B34C89AF2C63856FB43BB0A74A6073958D1199B4098386984847962B353B4D81AAF4CF65349C8197DB8C1B29A91FDE5AF1F9749A96B3B82C567207A81A163347919AEA565304B4820369799D352CE72415CF1C692537A48AB603B9DC741A08A66D874BF46DAAD570B6F1F4133067A1D900CA87CC25E91C4CE1C84B46D3C5BAAD46FED227268F1A9DBA968EFF27249B3C6E4C7C19E8A13046A2B45BC24F4304A80C09D37AC289F924F33E97181B8393EAA82A6FA54F2E76DD88791B5C3773707046C362D94EA547C3050AB251953464F4E540764B08103A88E448446F6B82375C15E3CA9A98798639B83638ADA857BDC1E3C6705471975C51B8087A26348BABEFD234D27D6C055D3AAB7560B28DCC13D343A79530AC868B5F6AC83AF04B8D7A20B64DABE9DE32A5C1B2C2ACACCC4588C1BA26F5462AAA5C1BDBC36467F346A1AB5C5840A07BD33CEB44093659BB0451C4C87CA4852172DC0BC3674B4275078CD2B9A3AFD61BFE454107D092E5840C4968C547ADC723C1970CFE705C5D33E3A4533F0028655C6BA44AB22C2A4C85A82B4B6DCC09765124E43C985459CB2AB1519DB1EC6F348D017A785484802D90E0222CA2313B4FBC465DEC0CD4F3A5675E33CF0DB79145867D5F0B8F340526C8A744929728CECCD146B6E66D03F660AA4E2E15D200B5960F3A03B571BB2E59160048E498C15379027E07987DDD841BDACA79764BCAA1C9843FCCC65B53695335D9D4CC789E062571665DA99B4E10368467AA551775C39C7C9DFE7624E8940F294C8655503F2F970071B40F6BA3544C64C41887184828BE6057A9E972631604901A7870733580C6AB8D4AA18B49CB4D567577AA8B0CA2490EDC68B168583B8B38415D32F5558996CC911A9470951430C36F71712F1C579A12327C41C441C980C286B71A31748EA54DF2A557FD1701C3173944B7B40117EF9CB08A7D03D45531B8DE4C753F697EC4B4303448C260B0783C81ED599425D9B16806828BF795C8CF65A95F366BB90110CC75D3E6064BEE17CF1497F36C48E68B46EC07417B2A876CB556C705C7DDC387D74F2B0AEEC9070D227AF09A324495F551680A474328D379AAC253A6F4C42C865A183D7C2F4F8CA94A92388B1AFBB5408CB1C0FCD3C945E2923ACDB7E16A45C03EC3298B3C44E9C1E75D049B2EBBCF2F29A2D3B7FC68644530010E052A0D357809009CD786604A39898B385B70AD7B3BE011EA83B93D4426F4F20A3D0836FC6FB532FA14536285013050C16D01C5752884E49A82A4A0BDBC8BC2C7598D548278703AB4C607A16B1BAB64052F40A06D3915CD03825F12C069D956F2A5662E05804183932B5216CA66274214ACF5C01A7F4C77EBF522DB776068F94151F7AC33831259B53BC48E99C50B260FAEC0B7BD3CD4FA9B5A5C2588CF098FCE5AAEEB15FE651355537953D9B8580313B56336F0846C63E2C3018BC8733F05F8CE3B614088A787669205AC9889BCE2D3B523F366F4BF811F004666B2B654431B135D97A70A00FB9A3928C1A4A2C7285F6F7B19BB766BBE6B966B4013EC06833EC6F1118A772C2465D81B77BA740B7EA33129218542A41E2F1B10F42BB42396E9A6C5011351E783641AA692A982272D9544AC93580FA6A51B8C7B6A4B5B1CE3B58F1D901855BBB2B68B988953AB63607D988999ED96E5A4B963497A061AC69BD90C4EAB7C0DC17820B6963B0293D4CA30D82F5997A877A9AA71C5C7893C1D153AC6779D0A88190B13DF828BF3AFAC9D7EA392FEA899EF844535187AF673972399A5FA31034C02D70B57B97434ECBF3B1985C86EC75B23AC0AFAA67225F12A257B78341966BFD2569670680E012899C112AD3873AAAF26D2F4A5C8CC133C92B9A446530C169B6B87B118D03329374A71ADA1778A2035986CEAE200C763A12B6E2B2FDB672B4D58D8BE640E61576F2CAC617A5ADA5D1B874BBAC9D272EE4C881BBDCCA1C9A84626012B988395EB5A4A48BAB1E7551B6CB57EA7B627138C3AC252BDA1A83CCFAAD69E38CEDA6B149C1B3BA295FD5025C63225CE88CCDFBFA6B3950CBCDF96E14DC0962745A5FA32D10525F71D895A2085620C89024D922359741BE366CE9038AA3B260320A456858A7B8D01BCA12316E9C6D1782BEDCB590A1D2AD9ADA0C26D3818652CE6F3B6403C94DBCD1424D090E9DEAC559472C9AC19CBB26C16E8B27DB9140A1161EA96A171728689CD6B6BA0C8002BA6C46719A1A0C175638770CD088AE29A7FA958209788ADE14354A1B0880F05EF7C15A6786BE063B357FC7521973ABE4FCAC0A8C26F3EAA052959E2F973709C9C6BBF4C889C8B76C0AC81353B4A4DC81B7D316F75ACCDD1911DF10A7E838A7C2023EA1EB0A956ABB53FBA02C48396807229F492966796805E04AD62B8107493AAB264A5BEB32F5459C06AA6E7F79ACBF171899A911FA910DFA6687B2C28C1D419A4817ABCF656FF669B587B72374F3CC20B92858361D21BB85A3B9ABA157100875C993B54CCBC84DB2D72374BCAE29C5479CC95197E625DA047447EA5797551595853651912DAEC4891E68901BB67FAA98BC5050BB50E913645874FB7A0E51C816ACC88A7F8A4AD383170A583A2E17B0D5766E12DCC827386BA8D868EE16B2FB892ACA3941CDFA7A487C13AF9787A309779B759CDC037C13E839314803BB10A3AB19B7FAE477C8C322BF05BD3AD9CFB0B241371C85FFCB607748CB518A6C896830B191737BA289B15288AB59869E22637C57019818801EF9A6B7160AC1B5B4D7519B41905E6687B3FA7230EB88A3C9530813561308B68BD2B740E7AA08CA72CD6468C008CCAB34AB99B6773C533B3914B19B2B80BF7E783E7BD9366C8962E7F3410F34651EE606EB737E6C9C5F6D306AF7348CE955228CF02D15B8ABAED16994B56260221BEB1A29BE5596E204B9CE111127989BD2AB49CF27C976F74AA7B084FA6B8400A25F3C36213F7C2D160045D865C75AA14542F5A4E4D1459B5676491C6A3FA0A2F0319CA1A63A401C9C3A14C94F0016A9A69E64C522AEE93E8B96B4F6691322242B20353E0D8B995A6A9129E961AE7349F92C92A90B833E82B9FAE1AD459AD417635C409C28F9EF936AE28D221563E30F83162CEF01B482889E5818AC8D7A38C781E3A0BC43D088E6D391D1D67D9639B260BB6F58A19A57150D1C96249919CEDC2369D8D739AB125E0D2CCB82DFEBCD90240A545CDFE07511F2 +ct = AF94CC0284B48C7858A08B77AE1161A30C07A30D48FADFC030089988BF1B24FF5607C9B5C714AE299658BC5E8801AF51E8876908120917B00751B558FFB7F54E875B71D91E02FB9C218EA63F2BAEB28A16F912896652D7A20861311BEDCB97846CA5F5C43EFC5E09BEC6B699C2EFC6D634F6C310E97793F0FA496970E2B9A3F74B35F96890468FAAB476C179AD7F0D3C601CD54D583C6763DE4A839B7855E68F3BA4756A2AA1EC59FECDEB1D7FAC0B9EB71184240AEEB740A9579BA6350F8F6B930A8AC33D3BFCD3D28DE47430FC34248EE1B292B94BB27BDDC9D9B1A6CDD7B5AAB7FA324295E1B80AC76E04465A50310E0F3DEE3A8414C1927CA2AC9921A50E970A48571C8B73D07C54F58E7D3CDA82BC4A609A9840F3FFEBFD7EC71E52D875712EE5CA94A500E28F5D3193A3EC22C83A2159DEF810FB3640440BDC870295C70CE4D45B9FC902D5F8590C0E1B45A5BC150D379053F277E3D8368EFA67D333031A2B131B8FAB6522D6701BD119E5493C5E6B4862535D4C119265FDF2682A7949BBC1D4BEF0893D979E35719F0D418317D0A828BE60E9F81A35DBA44FF1C286DB5D7BCD3734576C6F5C8A7BAC8DD8364465378557237BF26F539FF9D68FA86244BDB364FB1F6C893CFEF73A9D312037F161482CE9480ABF28809B05318F7A4749983E3577CA3F19E60492BE75DE65171FB51A87301DB5DF692FBB49906696842636B85D6DD6DD020C5B67FEEE25B7FDC68B0FC389B76DC02DAD17C2B58A1B3DD2C7FB17848442F49A674ABE74838095A97949F664F474DAAC1E708F9BAEDD23A32A2A5556F42AF0F2FF57C487E7C97B5CC6E4CCD3E923976E5101AE7C4AE8EEB07FA20CC7BC1EE39F26B002AA0149B84AA7E868ECEC02C304ECF5AEFA03B98F613738D23C09903901481D8F14160BD18DFC0686DA00595C7178DFFEE5A4A9A1F4B8F27B563C4EE84B8BF033EEE964277944D86E416D67F663AD2200922762F1900CB0F65A81EEEE4F758BB20962A85D2FA0155296ED38AC8A4A642E6BDF4E772B7309F4E0280552DB9FDF107D2C3ADED893A015764069D3D6D5E689F1DFAF26A8FDC8628F6B33E8B5D209AB3F3CC4960409486C52D539E32D27687C2BA004201CCFAA17DEECF6533D47CEF4DDF9B6CC8E25F3648BCE3298423485045762E4CD4B85E28B5FBE22C332EE0BC587B2C31AF7B98FD97E95CA1FBC9A57E654BD8B5E54C9D1B3FB59527B1C8F9736E95293BB74613708721281C0E80B79C73E1DB9DBC4B1378A18174D068C5A2B6CFB4F2020EDD74A40FA308D5E60174696E8DF28063198F58605B5DDCD759B6BFB1C0C2CFC9F31FD5E041F047EC94A716758BF66782127771FCE174DC0F141E866241573D48AB0EFA04497686BB3948C785A3F3381BA34E44090E02F5911FFF19570341A7AD12D3E7A487865950462C7DB9F7290E8453981EA4DB3F39619F27DE8B68866BE3A2C1BB6901A646A180E152802831D12FB305CF084DD64C5ADA579BE82A7C55846B550FCD3F4C3274297F08AE37C4C2B61 +ss = 2F2F58E23DBA54D8A44BA11AA4546EE3F1819C6243E986249B7102019DE3A777 + +count = 47 +seed = 730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3 +generateEntropy = ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +encapEntropyPreHash = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +pk = 964435FC16BE2CD2276B7BC78EE8B5C963AF2AF4673A93940B429131663CC124BE5A706BFF5C157DC17DC5CBC2A11418DC4B8A28C841C5A831B1A2BA989A20FDD17DD06706CEABC0D20714D5595D54216E9FB6824E3272DE0A1E262AA246494152B1CFD95C970F38AA35FC0337B26E76C77A0A76BC2C57B80757550B11807A423B85E32DDB537AB6D4694CB8B9ED58B11C9A6ACC746749C21011A66DBD7896329C3A31D0A7E1E78EFC93574CB7B051D79188EA4981DC6299EB9BD1BC1A133A41565305CD4A09FBB10934E7A3D132BB0EB83559C484EBC92F7CF93E445020B7187E2705A2D1A8386C008EC7F22FE172088360CD3FD160E7020B6D0C747CCBBEDDB1B84FA7549F625DBC064621FC2E13F720188C200C1AC1F10394FE4117018B9640632FBED570C942575FF61A7149A51F9993B90827EA2A08C32A330747CA27ECAE452154CE1A6A67A8B63676998AF929E8A7A9D2AB709E2162A2E0BC0721BFC7E49C5B2C9BA975B3BD881AA3782391F5CEE4CC1835C83732C84F54B373EB18869B2C90E9F986A0EA345CBB020333893B463671C95E6AA07193D06F7E62BF4361CD0009B1E528C85D147D0E650CEA7B0C67F1B4FB754BF2F1A7B9CC621D4C34682A6195776BBB9B2CC866CFA94C368A2B4B346C75A2A6BFE946CEF09416AEF21B15D3C72B7CB408141608C058E506271380841656963174C70E09C1F593ACDFB9BF4A3A9387B693F882495149C62A77595574C0BC745B51BA8338C6361A293402E74DF74A7A70B49FAA1AC4D66B89FB6C31DAE59F318B610F00BF4F4A282F752A070582F2F3C141E168F6FA037F23945893766215B9EE9A3A1DE662060A5B1FD34BC8DAC56C0875A6F82ECF8863C1692DC2073CF517CBED3C362A853BEEF1A8CF2247000CC4CD8176CE980D683B8AD89B3EABA3B962624F5AB3695FA10A88055DDD664A2BA0749E439A39C6999496999BE3BA7BBA2FFE06388B1A6C83068AE70A1C6F8A36E788B8AA148933C896EDA61EFC86CBB7D5C9CC96C9F137C6A9210347289010979BC1E16700A610C7C990D685550F537AB0C45B2BC57E5EF4C08B2220961C6E17E95E2E4482A4A94DA2E17B6854CE57C263D69429E1566BAB646FDB216E0444CD8FCB7DF4168AE66223A0CCAD971583B5917C4805271A17B4A1E17462815CB39332699AC447332A3F7ACEDC03541E93A822A96089D6A1F47A7DF35CC9B659CF419BCD2131B98AACA67343CDBAFA3DB35661C38C0BA1E18043A4C945067ADEE46E428A16011ABFEB58C1BC8B2330288B57CC319389921857C9D015A0471128C34CBC13417DB24B91A3567AC299CFA6D4C2F1123661A3CE0996111D340D9613B966955C6A758FA7F3556F6716E5AC7AD3A93174B2032A983CC0C73C0DE302F9F83A0DE89A1FB576CD3B41505B5BA712C387730C45399B8CF0B0E548CBED984E7BB5095CF7263B05CBA437AC6FC369EBCA85E0211715133BCC314723D79C9B93ABAC57AD3D3A5E77F2986A3539EB795A5B4967AC7753115B916236A97900870B658B9D4B3E35827E1AA9ADC3500FD9BA18FC6B03465903858C61C1259CF485338CB700EB731F31643B469BB259210CEC78C158E3290573C5228518E4697F19171D8F1A3A633448FE9C83BD28097BB29A168DB5AF1D1B354B6881A2CE509B +sk = 37F7089480382622AC6687B4B15BBDBC1A9AD7467E8FF4CF44F0614DE74B9591B9C5410D2D7084BB57AC27963AAFAC148DE80DDA6232F4A0C634D677A80C226FE67063191C05A54AFC026080877538F63DF93CC6FDECBBC0A9A0A4215488DA1A2F7B1EA8F8B917F32F397B94C80170BCD423C1F1BA4C736449F84BAFD6711B0070DAE72DE1EA3923435FE15A4FB35AC98D6379F0A44C200A37704B5B269BA3A555961ACA5E2CC1518FA4BAD3C23438E06952C9317D198B0C112D79A89560DC3361F5732F820CE4D16ED448AC2ED221C8EA3601602C27F640DCC394A7ECB5079978CF52B80DE15C3015839A44B9EE36837866C5C8E9579849B331E53DBC049E46DBB524C2090A54BA793C845420A7C2C29E78A9B8C83C310D780F74127C02A59AB68C1B29952DFF1196D0940EDC338DF3E1C1C8E34FD0DAC4D5596F97A2AFA98B1E8BE46BC0A96DF412639AE5B52229086229B5BC79AC020B61A56C04091C10CF9940F798A9C50BA1F5FB30BFA947F20B62A60215C5A88D23B70C0E299C53F49A1ED511AC5812558133D9F195E1FB5D77314559EA79E63A88E781C4224155ABB5CA91F089C0C609CECCA32E549B0CBA167D9307A3A64681A815A69C5D7E787751162483E7701437034F0864D8D53201FAB9763C7921ECA6F11247E7EA364298C1C3AB893549572BEC45C1A8C3B88659CFD526810B23F2095AA6C1424C7178187109F83063B52547B9C731F9933622A33C7A8B927A50191593488F9A0D12331017919159C7A027C3956FE109393A167A6475CEBB49224736847319D161490EC52396D7BABFB638BDEA29F50C9CE37314FC858455F63FCC70CFCB751DF12274FEEB45A124AB1B997C917A550C3469A0C185EB0238FFCB4DCBF751E12CA17A71B807B1446EA7180EE302E6998EF8D12A857C84FFC377F5E42FD41238A54345229916A715977025B3B4A6060F778DE7D426A2F95927335CB202BF4080B8510CC0DA12C4EAEC4BBFA42997E21504B8C5D32604F1D66E8D55B50C393F973ACD37A236DB595E3EF08239C42FB5E9243D967181B9B94F4521C104A8AA726DEC057ABD419BC8C6CF350C91ACB78B0832144F409F78992652E30EED7BA2375B3245D877C8E8B873F0427071C956633495381A2C642B15282B9945C758910FE469CD091B4458218105DA96A479BE0AC6B3BA155D359B2815916E93E9BAD3D431945B852E519DF0129174B24A32CC9FB8A62DE96733D153A799CB8FBA3C86B9101CF3D4A97BD3B699467991A57129607C27274D3224CD1848C17F1550BE47B71A119873045E215BB817CB92C12A7BDC6347DF8B64DD686873D800B4672AADE8AF56D2995546CC37C06F9212A54745C5597184EA85CEDCA7B980386FB91B8AE677A035A4547B5848879C2567C8CD6AC285F6F2460DBC0B73F5AE0993C988418C234895380C556042ACD15A6C015A13EBE16CDEA4BE38528A9D244230A0AB053C568E31C64D06A3D7BCA0E5207B7669811A3512F8AC6887137B0B7627D2401CCD604AE786753FB6568CB522B28712211208C1849D1F75CC4FB951D2AA081ADA952998B0B0E938B77359233A76C135897E91059CC5639E978C12C6BBFB735FEF4BCB1D60180DF21D964435FC16BE2CD2276B7BC78EE8B5C963AF2AF4673A93940B429131663CC124BE5A706BFF5C157DC17DC5CBC2A11418DC4B8A28C841C5A831B1A2BA989A20FDD17DD06706CEABC0D20714D5595D54216E9FB6824E3272DE0A1E262AA246494152B1CFD95C970F38AA35FC0337B26E76C77A0A76BC2C57B80757550B11807A423B85E32DDB537AB6D4694CB8B9ED58B11C9A6ACC746749C21011A66DBD7896329C3A31D0A7E1E78EFC93574CB7B051D79188EA4981DC6299EB9BD1BC1A133A41565305CD4A09FBB10934E7A3D132BB0EB83559C484EBC92F7CF93E445020B7187E2705A2D1A8386C008EC7F22FE172088360CD3FD160E7020B6D0C747CCBBEDDB1B84FA7549F625DBC064621FC2E13F720188C200C1AC1F10394FE4117018B9640632FBED570C942575FF61A7149A51F9993B90827EA2A08C32A330747CA27ECAE452154CE1A6A67A8B63676998AF929E8A7A9D2AB709E2162A2E0BC0721BFC7E49C5B2C9BA975B3BD881AA3782391F5CEE4CC1835C83732C84F54B373EB18869B2C90E9F986A0EA345CBB020333893B463671C95E6AA07193D06F7E62BF4361CD0009B1E528C85D147D0E650CEA7B0C67F1B4FB754BF2F1A7B9CC621D4C34682A6195776BBB9B2CC866CFA94C368A2B4B346C75A2A6BFE946CEF09416AEF21B15D3C72B7CB408141608C058E506271380841656963174C70E09C1F593ACDFB9BF4A3A9387B693F882495149C62A77595574C0BC745B51BA8338C6361A293402E74DF74A7A70B49FAA1AC4D66B89FB6C31DAE59F318B610F00BF4F4A282F752A070582F2F3C141E168F6FA037F23945893766215B9EE9A3A1DE662060A5B1FD34BC8DAC56C0875A6F82ECF8863C1692DC2073CF517CBED3C362A853BEEF1A8CF2247000CC4CD8176CE980D683B8AD89B3EABA3B962624F5AB3695FA10A88055DDD664A2BA0749E439A39C6999496999BE3BA7BBA2FFE06388B1A6C83068AE70A1C6F8A36E788B8AA148933C896EDA61EFC86CBB7D5C9CC96C9F137C6A9210347289010979BC1E16700A610C7C990D685550F537AB0C45B2BC57E5EF4C08B2220961C6E17E95E2E4482A4A94DA2E17B6854CE57C263D69429E1566BAB646FDB216E0444CD8FCB7DF4168AE66223A0CCAD971583B5917C4805271A17B4A1E17462815CB39332699AC447332A3F7ACEDC03541E93A822A96089D6A1F47A7DF35CC9B659CF419BCD2131B98AACA67343CDBAFA3DB35661C38C0BA1E18043A4C945067ADEE46E428A16011ABFEB58C1BC8B2330288B57CC319389921857C9D015A0471128C34CBC13417DB24B91A3567AC299CFA6D4C2F1123661A3CE0996111D340D9613B966955C6A758FA7F3556F6716E5AC7AD3A93174B2032A983CC0C73C0DE302F9F83A0DE89A1FB576CD3B41505B5BA712C387730C45399B8CF0B0E548CBED984E7BB5095CF7263B05CBA437AC6FC369EBCA85E0211715133BCC314723D79C9B93ABAC57AD3D3A5E77F2986A3539EB795A5B4967AC7753115B916236A97900870B658B9D4B3E35827E1AA9ADC3500FD9BA18FC6B03465903858C61C1259CF485338CB700EB731F31643B469BB259210CEC78C158E3290573C5228518E4697F19171D8F1A3A633448FE9C83BD28097BB29A168DB5AF1D1B354B6881A2CE509B172CF4F8DACE8A96B8F70DA966080A5E3F132873CA7544343377A99B65E8147FBDC370460375A778D1A31D01C42B66367ED8D9E8F84551002F552F0E52102B5D +ct = 2E1DD8799B0911BAD860CF08F4A53162A559277EF400A1120A024C0B0BA064D1746AB3926225882CBDAF2B01013FCFF1AF978C02CF3650866AF47564DDDDAB692292F6A1233B0BC4C296DD98FC24FF962E8F3A8336729268EC7FC97D30EFCFC45C2D77AC5FFAA428E1D3BA6087F0CED8406F9C86F1A2119B0539CE5B3251C9A0C0836EF690DFADF37F16040DA580814B865777882332591977D4181320BE97A091E8281ED130A15FC6AD629EC1103CFA0AF8FE257F3C3DBF737231C023C1314484A582F2599BC1249BDB7C5C9088B60E760F57621F4D04D9F32C8B5B354F8943D8917C68030CB263B78C4DA1BAD57C67B07DED2BAF8B52D3F864380DBBB0DFF30152C11F86A0529B29C78E97F91E3DD901676F97E6E1EB3756B213BC19D90DEBDD774F805B30E00AAD86956014C64C09B816B149EA939232B4CBB96F0DA9A9FB422F1154314171BFD2DE10F69767834B90AB15099D30415D66F8442589B8855ED001CCC2DBD6A633AE846D25BCC754838F8316DABD1A58A61C6E7EB763611BDC4CAEA5FAB7A19EC95BD168A4742308A07E8A0E0214C1173FC7D2386E33D187F2D2E5ECCEC18A3180025129065644A8E917554DE34A1CCEE3E9509F9DE89FD35345A9465D02D25704318D5E6EDA8CA7F6A6FBAEEE2D519929DF566062F672825F8BFD3370FCCC384571A1C82575BD9F6B3B4173E255446A5A3F2E2143565C11F12D8FF48FB8105E2E19518CCB1B60F04E7988C58DFC76AD3D1E3FA107A7193AF691D80D3DB1F940CC2E5F50F02D5BBAE18E1F598DF690E82E7BAE5334936B8D1C194663391D3F819CD2FAC47D185192EB9596DDA35B0A8DB158C025961CE2F570F7097D076384F9A548A1B774624C5ED3BF042A06E50FA6E24D7796F813F5C63DDDC70A1BBC85E730ADA2A2FADEBBA236CD0A9BE983FA40166823E52218F729ABFACE09D7AA6F6CFBF6BA25DE959A779CDF2E385A83B2666B5E0CD8A049428B18786D93A125832AF72A6C3202DB30D83E34DB9C2E127B1D7E027A0D8F30AE69C90A5CFD4D3BD610F77751940536174247CDB7A9DD7DF9A010E28E8BF22E346A3AED521FC8B7E3891847F27B7EA06157FF21F14CA7F474D7DF1CCDB371DD9155F8A8958D391A934072EFA43625244B1A79FF2C29753053C42378F338D11D722C283D1436D87FBD38AED972EB4BCCBDD3DFFB9F6F7B2CC2B1EC58F199E0E09ADA57200031E3B26F0556AF815A04112A784E5762AD828737F7F26B55969FF023BF853E4FFCCCFA3A6E3E5D7363B039C2AFEF6A5114E7D2D28405091E258CFE54C3B991A5AED242DBC60430A95EA07776314140BE80C633DD3E2171B2E9121F16FF37548E52650F6241960E6A6C23EB18EC2C6FAEA35B8E3AEE9CC2F7CB0E3DBA2FAD334255CE1E92F684A2E1F8281CEB9EC7A497C41ED0362F9D25281064AE282E8947ECA454E3ECEE228B0F219C243BCEFE589ECA239EA619B152606EED03F788E9824226E2FB390207DFBE953AC99FFB9BEDF0C0F602F0968490BFDDF86E7D0F0E +ss = 0936224EF45E29DFE9263C6237A22798E94E81A932796174271CECCB78188554 + +count = 48 +seed = 5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17 +generateEntropy = bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +encapEntropyPreHash = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +pk = 58718343322DB0162D26965D5E946B700AB88D702FD5A1376920B5BE702297AACDE28588DA91C719D40C1FAB0AF109742AC26C456961338C44C93C83AB58581635499545CCA66160E15A35BA4931E2B91FEE68A8734ACBF72755E8D452D17215457161284435EB6A7A2933C8D146A12679143B80740F68AE052087EEB988771A8FB43B34D6EC79868A0670551BDD19CB5313892BCAC9E4FB500D3375AE471A3ED551B2D9C76142B22607615454A910F8578E44B448AA9200D805CF4C15EB635013BB80A65593FF578C794066F05ABDDB850FF976C74ED6ACB4C41064FB5EEAB479A13BA57DCACF7F02421603194A3CB549F08C0D700790809EE0E585DCE4088F96A740320C57D5A632C8BF5DC173F0F841173AA47CA42004B808EBC2A6A1770AD9DC06027557F80420DB47B0158A1D1FF32007FC058875C4F5D21FABB67BFE8909E10B51BB35C76D0605D0E6A97E56CB93DCC58F722D95F33008B0A237B711420A20269A7097396A4A98BE20B8226E103CB1136EA3FA39D438B305B63FA049C420CC378392B9F911BD7800BBAAF2BDD7586780C7078DEA622DF51C7190841585BB16BAB9A0D83625D55826E3949AE018E7C4703CA082466B9A078393C30A4F6B7B1FC775C9DFF7CFB5909CAFBC66EA946E6F098F881B3039C251FD3AC142029E8728082F838A202CC3586672CB6285B021C41E3C16F5787CE6E319D849483FE40D989C246F7C36C11A991234AE7FEA68770C79D8290AAE3BB72BA014AA1279FD13977A49B0CDD494CA00C610CC2306059B695686399C1590F274F735142639425DD88026F8BE0F260CD66672A12B5C7B5C7323408A2711677F062625EB8F3541098D079C13208415DCCF3FF72D1999721DB3C271F7521DFB0F129B3CB6885310A0689166A3B97B09610347CEEA5579650720DB621DB20EEEC24EEC2144FB523ED2D30F64B9C6655928B3D06E1FD9B088AC8B7C964213E5674757C7BD48A3D066355F0249A50548F430C55A6CA0471953EB7C67E140AAF6322B7741225931622DB114ED46B9EA997974C9AE2F54B87125CE79E8621D712688B50C7A49877D52091643A4A43148550135F27BB30EA131521583F5B79255309465F4B9F2233027855CC0E7C93BB33705136C88392CCA717254640C540573D3A20032C9B297EB5B02C954C744C4C6143A56EB48F1D15439F885803BA5ACB524F3D54BED37145CD9173ED92A00F724273787CF1B89C788184DE0905BEA74FB331DDBA00CDA70C1547C634C706A8447145489752B0633628BA4F5286851E1B5FFB8A7FA2BBAD3F92C542ACE74E67AA07B467E70B6A7D3056592B36A7A37C6C7114C610721E9C6EA933742E43609C41F6F3803E99A8D5A27B069BB73C892BF07524A8B2989633C96CCF33791BA29F3D575F249C640093046D1684FBC701AC633381BB349BB7D351230A8BB1A22223DE3850258AC7043B887770A307C3746002CADA2826E47F7694EF51F94FB9E3645AECE6273298592BF00C0FDF14C07D8C9FCA401FF351D2E35491AEB55AED9B1B0EBC2424CC729AC7EB07630B8B11D0E47C323D6B3C0BA12DC235D5C310CE2C7BC1F0A8467D627568A185855750E12717760355A0B8A756468E95406D375F6A1289B8CDBFED9F6518D7031C57FD3455D4544735CF52680424C90F14F +sk = 5E43BFE8EA443466AB6B087DEADC672E7AADC85521D549B978B054A9B8949E519E3FC3A653607D794491341039713037D31C9824EACE39E7127A974403441E25B714FAFBA4B98041E85B2FD8D8ACC2A69AEA9C80930306B46BAF5245A505D48E293A77AA4174D1C095B0B4A45754A4A94BCB01D4543BF7C7DEF2AE2009408725C58BC76BDE03ABEF3C4EE0831D3C6B2632609707B3B861F093E857902D52A2A48619B1EC20DDE7A923412F79C22389601473076965959B2AA3C79DD31B98CA9847731C89B0929EF5174CC6B92972CE2C07C8139A62C901216245CFC92B2DA158079E1C93C8E08FF438A02DDCA4CA948F47A106D40AB6A5B0AFAF52052F237E44F0765B3436271421308611845785E257CAE691C39FB8C80BBC1C5FD687A547B7E8E3AA1D7C15A918984B6B359CD24711CBBBB95716EA54A8D3511C5DC983FA1B019E0B0D7DE90C3C0A9E7652C18E72CAD6F9C510E64F0CDA8CBD86502A5880EE1536EDD16AB36BCFD859CE879B3F5D6A0D90630668B7385C8599ECB1849A4942D87A91497129E196309156C9AB245F4C637080C963F9648FB2BA6F32D2566F88BCE680203DFB827438295F8670C9BCC34A98497851BDB0E631EA06ACCC26373809986DA62FA714012D2579D5D61443330E3B882C800B6C9D02C98E9859A4022DB4A09510FC91A3B95BCBF73B3A09311CD13E52B61733E02DBB400E8A54A30668311AC02FAE2B55FE05C95AC43875D92F3C2ACB3D4A6B53D363D5D75A697061055A3A788BCDFA051EDF97C3515CA920EBAC9E7A998BB598B8436BDB63550E416D2AEA5057562A901B609B129D92B27536E02C26EC6A3B2C5F6B733D0529330E9A89600B089DD30A0BB52530A3062BE741B09818A78B4FB9F274B7262CA23B3F2A40542CAA64FE38A6ED06BEB5498733A38A7FD0B5AEC2673ACA2B07E00909E68D40AA207FB179CF7A60A9E13719635A15CB221D1CC88B921E950C94CEE17D60F80CA5B4A656F501D7136D1245207479A1DA42C26C48664297562A0BAE0E7906E9D853FC7C490E4078B5B3B226B37101A31B5D05A26F1CA1F231A853F23F59D86A3FD269A0256EEBD02CC0C6B77F1B1C613114E1084D8D1CBABD0C7702F43D2EE01DB985382C562F1B7885A7015EDF59BD8988B5BCEA1CB04639BBF5B119E6293F908245455070DA3013D2B6E2116776694B44E3A7E433407099A51940870B336F547677665C7066E181CE266FF0E508268731BD13AFA2ECB4546276A5DC50772A6FA38541AF968AE5C59E2D04C3B6002C7120A6A970ADA2671590411552E48E7119C7B7F7AC97429E9B7CC0B5242DF277CC10E7C48976266643A9B2308CF1799324780743F95E65851C03599FEA7129D5552B86AC35AED10B5F00058A8742C02A3E4F6CBF5DF61C66143EBE933060C98A4BB55318566184601BB395625FC86E4BD47377B54459B45E50C145596B9178D57D01BBBAA9A63BF444889FC810F1E40E07D289E0B04A58F84348463B9FCA3176AAAE6C1C119CF679BACC6EB685B9F443C2A9E304BBA0ADF3888B42698AC1F68F1626439E796E1967C7BEF581DBABB6C22C9C16029E18D8493A524FC2A41738A25E735C665E79AC423ACA37B5222D970358718343322DB0162D26965D5E946B700AB88D702FD5A1376920B5BE702297AACDE28588DA91C719D40C1FAB0AF109742AC26C456961338C44C93C83AB58581635499545CCA66160E15A35BA4931E2B91FEE68A8734ACBF72755E8D452D17215457161284435EB6A7A2933C8D146A12679143B80740F68AE052087EEB988771A8FB43B34D6EC79868A0670551BDD19CB5313892BCAC9E4FB500D3375AE471A3ED551B2D9C76142B22607615454A910F8578E44B448AA9200D805CF4C15EB635013BB80A65593FF578C794066F05ABDDB850FF976C74ED6ACB4C41064FB5EEAB479A13BA57DCACF7F02421603194A3CB549F08C0D700790809EE0E585DCE4088F96A740320C57D5A632C8BF5DC173F0F841173AA47CA42004B808EBC2A6A1770AD9DC06027557F80420DB47B0158A1D1FF32007FC058875C4F5D21FABB67BFE8909E10B51BB35C76D0605D0E6A97E56CB93DCC58F722D95F33008B0A237B711420A20269A7097396A4A98BE20B8226E103CB1136EA3FA39D438B305B63FA049C420CC378392B9F911BD7800BBAAF2BDD7586780C7078DEA622DF51C7190841585BB16BAB9A0D83625D55826E3949AE018E7C4703CA082466B9A078393C30A4F6B7B1FC775C9DFF7CFB5909CAFBC66EA946E6F098F881B3039C251FD3AC142029E8728082F838A202CC3586672CB6285B021C41E3C16F5787CE6E319D849483FE40D989C246F7C36C11A991234AE7FEA68770C79D8290AAE3BB72BA014AA1279FD13977A49B0CDD494CA00C610CC2306059B695686399C1590F274F735142639425DD88026F8BE0F260CD66672A12B5C7B5C7323408A2711677F062625EB8F3541098D079C13208415DCCF3FF72D1999721DB3C271F7521DFB0F129B3CB6885310A0689166A3B97B09610347CEEA5579650720DB621DB20EEEC24EEC2144FB523ED2D30F64B9C6655928B3D06E1FD9B088AC8B7C964213E5674757C7BD48A3D066355F0249A50548F430C55A6CA0471953EB7C67E140AAF6322B7741225931622DB114ED46B9EA997974C9AE2F54B87125CE79E8621D712688B50C7A49877D52091643A4A43148550135F27BB30EA131521583F5B79255309465F4B9F2233027855CC0E7C93BB33705136C88392CCA717254640C540573D3A20032C9B297EB5B02C954C744C4C6143A56EB48F1D15439F885803BA5ACB524F3D54BED37145CD9173ED92A00F724273787CF1B89C788184DE0905BEA74FB331DDBA00CDA70C1547C634C706A8447145489752B0633628BA4F5286851E1B5FFB8A7FA2BBAD3F92C542ACE74E67AA07B467E70B6A7D3056592B36A7A37C6C7114C610721E9C6EA933742E43609C41F6F3803E99A8D5A27B069BB73C892BF07524A8B2989633C96CCF33791BA29F3D575F249C640093046D1684FBC701AC633381BB349BB7D351230A8BB1A22223DE3850258AC7043B887770A307C3746002CADA2826E47F7694EF51F94FB9E3645AECE6273298592BF00C0FDF14C07D8C9FCA401FF351D2E35491AEB55AED9B1B0EBC2424CC729AC7EB07630B8B11D0E47C323D6B3C0BA12DC235D5C310CE2C7BC1F0A8467D627568A185855750E12717760355A0B8A756468E95406D375F6A1289B8CDBFED9F6518D7031C57FD3455D4544735CF52680424C90F14F268B6356F92C57DA6DD34494B927E8764ADF0AD519612EF0D1B8951E50966C2FFD5A08F656A6EB8CD20679930A31CAA6A6331C4B133A6838C223EF9F769F6246 +ct = 19444F1E4399BA6307612AC8FF6794B0708DDCC06538D89BB5F49FC3B8AF7C2F31C965417CC17555AA48A9C17445580F27AD4C825937FD7068EFBCBCF3B5AB055DD0D772E5A801935F475D45A63541A9CC892C87AB0CA912731819E4F270564F50BE11E0EEFEB954EB6F4042C4ABA4595AC8EEC5896AEBD7D66C0D1B8E34ADA6F6C4903986D9E0C17E8ADB7A4AB87917B9584C6D43FFD09318D867710CB41112FFBB8D888A536E3A4AFF8CC1896C7AEA3700B501FC468126D0EB82519A336EFC13BBBACAF4C1F48D187CE71BCB2B8F95CA66468485C445629EE33A3EC1C4EC34A193F68C752DB1701D07A9CF6D815CA93C93C6E4FCF4B21F8B0523DB993D25F581C91C5DD94B594EDCA516D6046354B4309CD9EC53BE0F9FF210213DEE06C0066665D325A10C5D2491DA37498644907FDF719515EC507217DCECF16D4B3CD45EAB811684198C48567BFBD65D831ADF41FF4612E9FFFA0587B7B3FC9F2B726DB5D4FD1DCD3D4BD06E309EFB1007C39401FD0A98B2BD6E3D354FFB8FB556F289E858A1244A602CC1D0A41055087A714EABCB42AA85F484F2F27548831B2F32D883A488B74D1C7BB28A8F735F161F2086B346CF0C45153354C690C92D68FE943D723F7E243D0AAC615AD54C3FA336B7E43262E14C850E9EB89978AA10EA10507230209E255192A3695D6FA3CB55EFD7BC69174A44EA0A2C15FD17A22856E571C39A519E94A5A022B04DF98E6C84FCC6D5A5AE3980E651731753517FB87333C02044C12531730F3445AFC02CD54A0A8460F7146F98187CDA6555A8EDF2CBDF6CE301950EA5204DFEADAF64952BC871F7F01517ADADB0A1AC33C34EEF75B7DCC1F64AE20A9101AE95AE24020D8AF3242AE911B3604284D93DF937E74DF3F74F26275D7413CB6D07ED995AB853E180A50F8D0EA305528DDE43F5413F927289CBCFA6B426B615320D635B85B63FFC640E7EC4B121AC71E85811815EC5DF1B9A5A2DC7F79C8A7E6380CA7D49CB3D7901BC28D1E249BCC86EC54EBC31D92D5324A0663222FBE93EA2CB0BD9BFC5AB43D63C8DA12051A4157C210DC10E737B37962C1DE186E286944E1C588B570766F81E944850FB4269491E0FC23F86602CAA9968CDA290D83E7B2EE9917693E47951EFB86F6CFF49CDB80CB04774E51DED7A184BA8E2656861ECC8A90795DE698D70AA85216FD715A11AD8E1D5D07C16A1F10C22DAC064F011D1829826D34C242F8D0DC853DF36D4DA431489785373C8E050EB8A34CE55C6F2FC1745DE58BE0B903C9CC25392A9378A379F6353F04C52DC5AEB80048BB0F13DC7DC9548266729B410C7B809C10116F30A6204AE7F46F7CC68F5ED8202832FF90E1C482B3AF44E85AE6E44A131BF9789147C21B1D5658493CE4CE3BADF7458C26870392494A65AE4F53CFCDD337D07C801A6AC90443A8F78DAD7A7E3ECD7DE8448809FD38B533A3F41512FE7011425E6FD360395F62687EA7E66977B0C3AC4FEDCD1C91F1026E216FA754A4D64F0265B0AAC854C8AEC1F25EC93F70A10E3 +ss = 2073CEA69B598292F44EBF4AF3F7035E1738AFB7203AD67531A7140150176E5E + +count = 49 +seed = 1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB +generateEntropy = 447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +encapEntropyPreHash = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +pk = D8279F9A0681CB98BC38CB551320031F46262799C182B0355EEC82CDB58D750596A4E6BF1213490810415A4B347E13C9E8514890A0995843936BE342E81C7F4971BF9B75925D61AC8C961492A85D83FA8E33C12FA37BA08D7C681C521ED4060481F58BE673007A081321E01E21419E232283A01CB1A4481550DBADE263382EB93B7E42470B265027A933C480CDA340A9A4065B4BC47990833786456AAAB5A81C0A46E0076B91BA5BB4D4ABE21C6AB193B3A3671C18479DB082A706768A63109D2C4224D71C7C95755CA24B056C355E9C22CF5006662B3218EDD4B317B19962CB514AF123245B152EAC41391CB432C6CAF9295C66DA4E5737AE3D60023F46AA7A604C64A6C403306CA4B96FC2929AED5B4CE7E6C631B473D7D61CBCD19826AB82C0C58880D77CE8F9BCDBF59D645424BAACCCE334809B43ACB99248BBD966C88793A273AE857946902649F97B5516FA2EA2A84FCFBC054653852D8421B6B78C289B49080C8EFAF85DF195AB5562A03E7099C43C439A25AB41390B86DB4F57188F002129F3EA1FFDBB9E9C688EBBB26E0D7AC6EEA395B698A134F70F98480E87313B79444963557CEE82534E9C1CF10B74718CAEDE3BCBD98A68D9956FACD8A45E2184C16B14048B9D28E8BFBF5AB43D1B650EE8CF13148CAF451CFB144656052CBAF82E2F765C8C9C66C23B0CBAE0257D6000F247200AB87F93B5167478A27B42AD7681B6919529BB1430DFCC809E171A334B33A0527A1D9519C18130971C55F6EC172B86248059830FC57C7356C9BD8263F7D571D0F7BD87D2A1686A7C41DB9306558CBDF39F0176959A188B4D457B40C152B7EA09F6860D4D945E78C45EB68B579D48774EB26AD43BC1BE3C0AC327C80B4C1115C2CB58BBC24A18146470ABC223AD51FA10EEFC311F1AC02AF4C7432210233A4ABC408B1DB484E7885D239C0C2B9C4952E577A8EBC3D6A7684E711E12DB96E1F988DF423A395301D2C15FE2F1ABF708BC64147A30E2717F7868FF602D50FA9A3D0B3A0097259AC52057DCC14319C438E113DA967F6DFBA4279245B72CC86CF724C81769DAE271E18C0B6CFA84B916AC89B12A1F8B05D88527AD40346775CC832713146806A2B2884E35628169BC12F67811B507BEE3BBEBCA81AB93B5D700AA92898B3F5CB6E9D345483CA3743457FAD8CC5BEC2A8E7A22A41BA8B67641AB181D42ABAF94D0055206B648C81361F8486408B610BB3552299316B5C0B7D301D9F1C3D55621859AB2EE922C59B11EA9F2A1EFE277C534128F2CAE6B598C0FA059EFC2C24E8A0C2337BC2C57A0BC64A7FCE190C656B529D21244EB66A900288B5C484BB033020B9B9BA3019B72387F2746B3B893A1427882BC3135F0A17F8271F9C8480EB60732672D44336B32F851A283224144C480AA302C05836EDC1AC4569A6020130B341466322D17811229441C4513A2E8041C85E035113992F16799DFE8C1EEF3AFF8CA2F341628808A81E8B66EE5BA47AD0863C735A904565F036A85FB1203058137AAD2206C303F22D3027E732542A342CAF3376D6B065A745E31E865FC2243DA31CE08EABBF8183B4294700BF8928DA8CA78BC08490810C39747FD3851211B22F26451F6772E0C75659133E8D8C063CD3044DA1719855FBBD9796314B11DF8459EBD2D92B7FDC94C4C +sk = 469963001D4D93DA7CBAAC0ACDFC833C47601AE334DCC0022A9220138C16B9ECA73AD1863431A34F593ADDCA4F0EA393FC4595D22A7CADD0A8D89827086A955400ABAD84226541114CFCB3E3A240FB600DD6C0960A7976175C56B0B48C66721E13882E3AA5784E12869F0C8518037955F876997975D27A7C92D4CF005AB859590504C768B02576A94263C87C4BBFE1AFB09B8C0A5C067776A0D96A5D12925B44AB3D3E57C6971B0A86617F65A16C7E9B42C283577219409E1CA4DE08A92DC5B4E8E87051680C1B24068DDA801FE871E0B28AB0611BBB97CD49BCBF159B7785830BC9D302C0A61AD138277AFC2374AA64E983506BD11288F4A20376B50AE1C1233A1ACF30AF1DA67301A5A420AA826DB58322DC1C7AD8BFD25C3B21025B565C357B4A0802E615A35A384F1794A0612E030228A865A0390197E7C27F45A4258FE26082C850170CAE86721BB5C68CB32153B9934DE4CB11528C570AF363925AB0FEDAC79748B3489B7180E81FF6DB702D5A100336955EC02FD2B9C86C2CC001833B0BA1B7DBC9699C6556B448324D29B0F6A4028BF48A49B1CF60B4A9F91321AA64CA849848CEE2BE0A29219F783008417DA307710F87CAFA2603FD206E5698177E81470AF4C608A6128908541183A5B4769E74166349E55B4D2A2A84600EF712C2D1F13F4FB3C91BCA8CAD209CB5BA0FF578BD6E29A0CF07A972D262A2EA3C4DD44A5D55446C174B345B96871076FCF785CCA68545EB6BE64BC9BE17A7D5914D8A50B286D3A2A8E1A53FAA53815ACF0237B8BF204C34766E97883071E56539361BBDF29187C180414C83D9C09E30983995AA4850A6B2358AA6240642CB9B0FDB739FA5A93EC60C11061AA8B5E71316A517BE2BAEA2F74BAEE32EEAA0A75D2030F5E8BBE1B517F56511FD8AA499621A9EF6C88B96A9F33B2B3CF04381B5C97B743063A6286751AD9EE14903C4674B308DD5E28BC700134C43C788B04460DB78A0E795E24698553722B4C3A095784828960672CBCAFC11AF32C918ACE0580D5BCEAA574409854051A2419F148809147133866F9B651A38622F21E0614F10139BA53724831FF312157146169EA29293D2A3F1250AB9CC877D448ECB53139E6C5487DC2931D45B4A74C34BBA11CBB965E1E664ECFCA54DB7BFE7E61DB2382E50076A70A9AA028670A354013C894B729945830B1125AA53F4D352BFF33FDBE7C64BF70A4C3ACFF3680976FB26368693D928122ED5707B453A1DD714FA9C5A8E6534D45B53A2BA464E217DC0461BE31C5763715BB66B6F3A4C0E7A3A4CC107602CC3B67487A7D162422468B5CF33C8E5A63F801C2016B15C40398F914CBCDAC9664B7601680346FDD3A499D89B5CDB7E77CC8A1215661AA34737149BD0734F7BE6A0C20BB94E6A89DFB9B0A9D6C4BFB86408922FDC9650DF7577E5A89215C8636D5C376F4596C329158964084200C91AF4A7699018C6D139F521204BC521110AA222203774DB88AC0AC94CB97720A71411EABEE0B2863C35607A617E761298825ACD91C73685198BE96B84A98AC7295142F6C19BAB0082C53A8A50A3A39EEC2A34E859CFA2C88C9CBC77B1BDB5377981F61C1FC394D70820336BAF21820D44C0956E09A5D8279F9A0681CB98BC38CB551320031F46262799C182B0355EEC82CDB58D750596A4E6BF1213490810415A4B347E13C9E8514890A0995843936BE342E81C7F4971BF9B75925D61AC8C961492A85D83FA8E33C12FA37BA08D7C681C521ED4060481F58BE673007A081321E01E21419E232283A01CB1A4481550DBADE263382EB93B7E42470B265027A933C480CDA340A9A4065B4BC47990833786456AAAB5A81C0A46E0076B91BA5BB4D4ABE21C6AB193B3A3671C18479DB082A706768A63109D2C4224D71C7C95755CA24B056C355E9C22CF5006662B3218EDD4B317B19962CB514AF123245B152EAC41391CB432C6CAF9295C66DA4E5737AE3D60023F46AA7A604C64A6C403306CA4B96FC2929AED5B4CE7E6C631B473D7D61CBCD19826AB82C0C58880D77CE8F9BCDBF59D645424BAACCCE334809B43ACB99248BBD966C88793A273AE857946902649F97B5516FA2EA2A84FCFBC054653852D8421B6B78C289B49080C8EFAF85DF195AB5562A03E7099C43C439A25AB41390B86DB4F57188F002129F3EA1FFDBB9E9C688EBBB26E0D7AC6EEA395B698A134F70F98480E87313B79444963557CEE82534E9C1CF10B74718CAEDE3BCBD98A68D9956FACD8A45E2184C16B14048B9D28E8BFBF5AB43D1B650EE8CF13148CAF451CFB144656052CBAF82E2F765C8C9C66C23B0CBAE0257D6000F247200AB87F93B5167478A27B42AD7681B6919529BB1430DFCC809E171A334B33A0527A1D9519C18130971C55F6EC172B86248059830FC57C7356C9BD8263F7D571D0F7BD87D2A1686A7C41DB9306558CBDF39F0176959A188B4D457B40C152B7EA09F6860D4D945E78C45EB68B579D48774EB26AD43BC1BE3C0AC327C80B4C1115C2CB58BBC24A18146470ABC223AD51FA10EEFC311F1AC02AF4C7432210233A4ABC408B1DB484E7885D239C0C2B9C4952E577A8EBC3D6A7684E711E12DB96E1F988DF423A395301D2C15FE2F1ABF708BC64147A30E2717F7868FF602D50FA9A3D0B3A0097259AC52057DCC14319C438E113DA967F6DFBA4279245B72CC86CF724C81769DAE271E18C0B6CFA84B916AC89B12A1F8B05D88527AD40346775CC832713146806A2B2884E35628169BC12F67811B507BEE3BBEBCA81AB93B5D700AA92898B3F5CB6E9D345483CA3743457FAD8CC5BEC2A8E7A22A41BA8B67641AB181D42ABAF94D0055206B648C81361F8486408B610BB3552299316B5C0B7D301D9F1C3D55621859AB2EE922C59B11EA9F2A1EFE277C534128F2CAE6B598C0FA059EFC2C24E8A0C2337BC2C57A0BC64A7FCE190C656B529D21244EB66A900288B5C484BB033020B9B9BA3019B72387F2746B3B893A1427882BC3135F0A17F8271F9C8480EB60732672D44336B32F851A283224144C480AA302C05836EDC1AC4569A6020130B341466322D17811229441C4513A2E8041C85E035113992F16799DFE8C1EEF3AFF8CA2F341628808A81E8B66EE5BA47AD0863C735A904565F036A85FB1203058137AAD2206C303F22D3027E732542A342CAF3376D6B065A745E31E865FC2243DA31CE08EABBF8183B4294700BF8928DA8CA78BC08490810C39747FD3851211B22F26451F6772E0C75659133E8D8C063CD3044DA1719855FBBD9796314B11DF8459EBD2D92B7FDC94C4C4C6D304E0494D88D83B5E3AA5761DF3B299551A24F28994D2747B2B08945BEAD20A7237801F470FCC2BD9FD7BEA8322859B850F7882D362947432913DD068C01 +ct = A95AC6C09FB64C6D773EEF1690F3B87550BC37513FD8AFD9B1BD88B7B51BDAF9EC20EF1E5B2F7856C02211A7936FECD414F991C098A77F7C2652B0BF095D368F02A2A293F6300932BAA5AF1311D05EE3C4EF967003DDBE06DAF30277636292E5F435DF449904A9C47597DEEE95152D0296F0DB4013609A986A27FB8C50C453A76906D8494416434B048A2B411D25AAE800469B2ECB73592A2BBAAD4E392F3C5367B7FFF2C9A4DBF65C296873230782E4CBBB2C613FBE8E5892ED04524F353F97B6A83CBAA6ECA393BE675AA3FADC2615FB5A2DDF89745F36C83C1FC204580B7E4CE24029E0273DB147666A6550DE9364BED46F3C20E80F42CC013196FFE4E06CA8FB9FC421C798B6A287189861CAA148EE2B6B4326D73F51B9FFC2B97132EC6F4C0D52DDECAB76ADE333C6A53E090759AC5D8B43779911FD98C080463938E0FB7DC6F69FB35F71919179D82DEF20AB425CB56554893541CDCE3652BE623D49052EE9DEAFB39549B85DB84CDDF45F3D113E815CC0D32B3F180E59FF69415DD50B756624C84579071DE883E2187FEF0A63189EE9D342679FF0DCB98A2E963B490BCA4D60A309D08FB6C31A1CACBDA0D004B6D666676725EAEEA9D31F7205D3C02D12939C3926EF259429642A9D9C375D77F51B8356CFC1F504858BD56E445F05CCFF5109F73B89560788EC833AB196A51E877C751B70A67357C70CEE24DAA81BE2C666BA20D1B7DF9818CF9900D2CBD83FF74E47F999689D2F5BB178E9A6D4B4D49538706136F4096A919469B4006766D5279453735B84D2066389FDE6F600B49D4DE09BE55E09E7C462F314C921F225E0168342DC4D306DDE23B39139627E6AEF656E1F803EC3DB9697A8FA5772994C7F5A0E6E23F71B025D007FB106E81E76C3D9C718930A1A33767DD2B24B3DCBB2728E9746429625330006CC71604950F1A5124C3A820AD98ACC2DCADB4A1FE4EE3B04FFA3FE7305700AD11C06183AA4864FC8A254D9B6319D3C8C42BE03DB71EB74E585EF4A8D8066FC9D6C5D4FBAB3345D8241A9E6F960E238007F8897A50C6FD1EE62EB24AA67EDD962A2F2A9286A365282333932BE877227D0F5E77767CD69FBC6001CE647F29D89E145A91A16D477DF0424F73C6D310C68897E50F3DF553008DE313D9F9ED621E3C43617FFEB5E969C015DFC361A06E9E649195ADF7C4E9BB6AAB204256F1D7F6D0B080E2981932281937175940EA11583F862D7A001BC33A0E142AFD918CFF3764E99E52D3E920591A0030B3AA55C88589C0AAF243EAEBC6F08E2E3B3083E6A41E500150B90C0172F534B597C958B0430AF44204165344E218FD84BFABF8F580489F89748103B451FD9F5462288A03FA317FC72BF986EE03CD87709B646C4C611143536FFE596DA2BF049EDF32F8E40B0C465B24EB81FA09D775C7C5A99F5ACF2C6F24BD13616E6D7E27CF2DC938CF5BC17D8F4EA78549377747A23E341F19455B7C95764A8476AA41F1D33B2344938BC3FDA480F646DC973321108BFB7638767660FDE1FADC387EF +ss = 633D9672D83A112A260B9D4C17812359B5591900A3B80424B3590B403A5DFBA9 + +count = 50 +seed = 027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09 +generateEntropy = 2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +encapEntropyPreHash = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +pk = 41AA7B69158362A41767486EC3DA09AB4335FE2A25DD6C07366478CDA91C691C5ED9264F771124C1F3693050802F480F5DF89D5BE189DA765337A69C5C838488A0A4BA7880E91871FE346CF3ABB0AAEBADB211B5ACD3B773C9146CF97920E509DC202F79B14734C9777A567CD44A43500B5EB8005BF4C5A387701286639E6D9AC2574B33F2432B3A787039E34B2AE511A27825CBA7A8E09B401CFC6123D3B4C42318E7B032331230DA960A09F61A6A196DC185BB8BF1C1A6B691A06CB57F12BE1E45269C56490E256A83C13352A878C724242FF0681881160ED03166612D69894951D65B95E690DB46129D149AFBA2C835D3B138036931423D2F84CA51179466A1028D1601D5C397CC81B1B5E468869185B25095A0E5B5DD6A421B5C7ECEB58C4CF97B7FEB114FBC435C78857C65098D3017FF8A58F5927E5EE7712FA0C2962939B9D8C84BB6428B3902881188DF17479EC01E4709B7840235CCD77ACB0BB3A05995693781FB711D61F2883827A96DDACE29A9CD43EC6ABD4691BE1A758B72A629F6AAE1C795981C0D8BF8160BFB3B8F5047E1A410CDD49C6A42ADF0BCAFED1B21EEB95D504B1A48B1ACE228BB5E1508BF05128F0CB63F5597851B9DF4CAA5B6AC10F7F6188DC41B02761F840CAA42871C55205CD09771AC9125D6265DDC56A466249FBD774EE53756035349CA12A48237221BD53D7FF1AC18242442935BA818A3B50007A3FC14A2FA3ABE437FF14705DF0CB5AF97561A608A3FEA42A809A7A7D5491453C849DAB7ACD99636931C007A70D01655C7302F9A26012C494DE47839C1EA2951A87FF73968DAE83A86F392F021873BE4C75D2B0700A3B540F50CF6FB664A4627DDA9C75394032F434655755D12D4C781E2324AE00DD61744CEF6C5EC9680F379A26284BF9590A33350905E080E9B70547AC1CF3AD888F30232FDEA7BD2C184F9E1A9B6835401E737204C5EBF2B28F2B58EDD399F873C7849CBA8064B8A20C9C391841875B4963BBA2097B958D752739383BF26787E64EC215974B45848185F44B8780C0714B9651A7685E673CD1B6230C5D6639EA5629C20659802BC6F2B95DF274836241165A524EA99A941312FEFC7CDD2FA8016D69B652C3E94E73C70C97F65B3ADF14BBA2D31916522701D80252E9C7FBD7A17D306A4E1E02CDA405F3F07B38EB65824D5C9D8B91F7013784FBA0DF0348F21B00EF5A325C745A829714A5B9ABA16ACBDF029771D5415E867590CC5A57360A8969407F0749AB8A08A65E37E70146FC1B7BC40D789EAE83761E77749A07859BBC046B5A87E3A92A5368251127F12D27789318F8B9C3C1F79211922C852A0B0E10BBB631599190B49A66937920B3F113185D89C6E37DA5F7CE9C12D37C12CC24741CB9A79446606EABE8C9AB06D8963C959955F198E03A0BD127242DBF2A2180281A7B65F54C28EC9C6CAFE64881D6456C07607CDFB89E2CA2FB3BA8F8357720051C30952734932B08B508402A6A2F4F9C76B053C12A267618928032B5D9E41990A18C2C04BA7C2868AD9F4538FF1B494707EB9DA6B81374D7F9731F9A26089D7033A8C24600944D65871D313387B4101C0AAA27AE19D978653638577BCF4CAF48083EEEB57F401544D4DA3B73DC1C5C4A047B0A5EA85EDAC7BEC66F4D87FD2FE422E7DBCD02D1455 +sk = 3C14BDD913CDA0F267ABAA8B0A30A5EAA527638C01926623B0BC2BA55B0B596A92BAD72E92845828E8050F4C2F40873918E4524CEA8505208D345783F71202496721E361A582C5445FA31FB662A64941ABF9FC203AB4A741C9214C1B80B4CA617C4976C819794F53CACDB3509978A6DF5900016278388234CC1A09B804679F36718255B2DB60A7EEE5BC3BC78BCEEA8060354B54031C4C76B30A1A8B1EBB697FF8606CE408FBA72DBF0856E5B53B1E4A4ECC746CDFC77545B46060974C8A788A1D59529A9AAA571B895BE01ED5C23A0D22707D89467A5B9C662767A0D77D5C49ADCA983CE7401F34526DAB1CB9FE744BDE8C54C230705548B9ED00B9F4EA055466CDE77019324C0A7C9BA404B641A6530AE64A964EA47E6E80AAA4652C9A8B66061103F385479E50A780249A909C92B7913329A478880162D8857D58FA39D3283F5A2A7F8FF6ABFFE2463DB40728D06166627E9C92283FA57A2E46190AB869B6C21FBEAC86911284153B259BD2A442070D1CC581FDD333E5990F84AC67F47491DF01128F0959ADA0891C236E0ACA87755289C0E6C8FB136974C97DBB1B8871A4C70AA001FC950F0CBB3ACE4AC44F800252F5BD76FC1DC09A3D2F8860385A4BF8D765B49C5379140E0A2801DAC947C23803AB6B467F2BB1B019B9D53771418312F51B28DB18BE216794A0467D79AC8ABAF2C90F4B1B3474C168BCBCC1E6AE59C5781296467F2B8D63D5842D67935DD429BF8319BC0B8199CCA9D3F78C483B8E0771622EA764FA610EE13C1A188C56D0B5C17094C1B7A45321BB69D99A666A7963268A1D0A0491B8B5CB700A7D86AB9039330EDD8BB17CF1AC79355A82166458D2323E070AC109C98D201358F22BF9A3B513B8BBA43905D1A790A7B1A11F682583AB4FE0A82F3E316B7C70AFDD823C8FB7ACFD330B22F378E8597CA5357454A71197CB4039E9A81D7995D14587B479657584407B281886D6A7FE9B6170A056D2003BF898027C275B7C1C3D1D0C157145BA52D264699B969D60AA3873A9606041C20B17C90055B8016EA703539638CFF8AA0A219542BF51B68CF153A86149881C087D898EF9C3A089CC70A8656117131AA3F233C73CBF439022D224422920501C07243432AEB925C4023185D3F897A79A983D857C6D1422F9B22234005E00882F77C7704CC74ADEA4C8F3971E7964BA1A530C1F722EF696828C46946F0B329D909A47B83353330630359EB8E9B7E78ABC50FCA8C3AA9AF967C89F464430C815D1959A21A226A966A6434301FA600A4D129886826803EC49A54A34ACD62B50E33FD782937571816421341CD76A3570C17AC9C338E4AC4C51077650B98AE445D236904DA694F755C1A5B288275B517B4C9B896C49BBC18933E52D34969B6AD8ADD604B526488C6397842A54B6657B93386B0ED7D36FD2F448EFE43B0A144C33F729DF530C8B6340CD61897B3C50B0D8BA81228604F7A4BCD120CD2A7BBBA3B4818177C435A2B0C3AD838C6D9BD3903D64B32B8A8DA5D93589021251D14C920328C4063C2AF3C8C41228355527ADF41037E1AC6AA69A427A55354CA9D54025306C16F93154776B4A7AF9C9EF2298DBA9B669C40BD0601ABD410357B8940511BEB6C96541AA7B69158362A41767486EC3DA09AB4335FE2A25DD6C07366478CDA91C691C5ED9264F771124C1F3693050802F480F5DF89D5BE189DA765337A69C5C838488A0A4BA7880E91871FE346CF3ABB0AAEBADB211B5ACD3B773C9146CF97920E509DC202F79B14734C9777A567CD44A43500B5EB8005BF4C5A387701286639E6D9AC2574B33F2432B3A787039E34B2AE511A27825CBA7A8E09B401CFC6123D3B4C42318E7B032331230DA960A09F61A6A196DC185BB8BF1C1A6B691A06CB57F12BE1E45269C56490E256A83C13352A878C724242FF0681881160ED03166612D69894951D65B95E690DB46129D149AFBA2C835D3B138036931423D2F84CA51179466A1028D1601D5C397CC81B1B5E468869185B25095A0E5B5DD6A421B5C7ECEB58C4CF97B7FEB114FBC435C78857C65098D3017FF8A58F5927E5EE7712FA0C2962939B9D8C84BB6428B3902881188DF17479EC01E4709B7840235CCD77ACB0BB3A05995693781FB711D61F2883827A96DDACE29A9CD43EC6ABD4691BE1A758B72A629F6AAE1C795981C0D8BF8160BFB3B8F5047E1A410CDD49C6A42ADF0BCAFED1B21EEB95D504B1A48B1ACE228BB5E1508BF05128F0CB63F5597851B9DF4CAA5B6AC10F7F6188DC41B02761F840CAA42871C55205CD09771AC9125D6265DDC56A466249FBD774EE53756035349CA12A48237221BD53D7FF1AC18242442935BA818A3B50007A3FC14A2FA3ABE437FF14705DF0CB5AF97561A608A3FEA42A809A7A7D5491453C849DAB7ACD99636931C007A70D01655C7302F9A26012C494DE47839C1EA2951A87FF73968DAE83A86F392F021873BE4C75D2B0700A3B540F50CF6FB664A4627DDA9C75394032F434655755D12D4C781E2324AE00DD61744CEF6C5EC9680F379A26284BF9590A33350905E080E9B70547AC1CF3AD888F30232FDEA7BD2C184F9E1A9B6835401E737204C5EBF2B28F2B58EDD399F873C7849CBA8064B8A20C9C391841875B4963BBA2097B958D752739383BF26787E64EC215974B45848185F44B8780C0714B9651A7685E673CD1B6230C5D6639EA5629C20659802BC6F2B95DF274836241165A524EA99A941312FEFC7CDD2FA8016D69B652C3E94E73C70C97F65B3ADF14BBA2D31916522701D80252E9C7FBD7A17D306A4E1E02CDA405F3F07B38EB65824D5C9D8B91F7013784FBA0DF0348F21B00EF5A325C745A829714A5B9ABA16ACBDF029771D5415E867590CC5A57360A8969407F0749AB8A08A65E37E70146FC1B7BC40D789EAE83761E77749A07859BBC046B5A87E3A92A5368251127F12D27789318F8B9C3C1F79211922C852A0B0E10BBB631599190B49A66937920B3F113185D89C6E37DA5F7CE9C12D37C12CC24741CB9A79446606EABE8C9AB06D8963C959955F198E03A0BD127242DBF2A2180281A7B65F54C28EC9C6CAFE64881D6456C07607CDFB89E2CA2FB3BA8F8357720051C30952734932B08B508402A6A2F4F9C76B053C12A267618928032B5D9E41990A18C2C04BA7C2868AD9F4538FF1B494707EB9DA6B81374D7F9731F9A26089D7033A8C24600944D65871D313387B4101C0AAA27AE19D978653638577BCF4CAF48083EEEB57F401544D4DA3B73DC1C5C4A047B0A5EA85EDAC7BEC66F4D87FD2FE422E7DBCD02D145572BE2F5CD569E6229F00014854633F7B278E90AF4EA593411909467A03E29CFB7B534537ADDABA4ECF14F02AB317D36CB9F0F50222CED7CF029DFF8A0D3D2FD9 +ct = 90606786779293D177977750726975F4EB4D2843F8F693800A1DD52AFBE25A79C5E48D83D02E9CDA1E3909D1C23DB2E382ED3DE92FBEAF611F326DD2A34E597CE9695E211FF7590CEA226B588A5BF394E8AEA1AA959B45E32E7AF8DC01500F950F9AF77878B8F280E917579650DD9ADD147D1879F249FFA2B48E170B5172B97DDD0BE9BECA1843BE63C7532F7BA2B85E508A600B1592759EFFB657EED4162855ED6B6BD143A91523A3D033BF5F6199F8D1BC7021A37ABFBB82886777797EAE296F9D5748FFC0A1276575FCDFA8056030AF0DC936AD79D24E68228F9C50F3F406CF0DCFC8C7767285B67EB6BAEAD90391D8DD18781752FE025407B96C6F042D251556B610755D1BDF36A806230A11C2852827A048E835875239F99BC4A31455E13ED565961E1EC56AC4719993F2D02CC08F03941F9FE37A7E18A66DCB2E5EF5A591FC5A4C5128EFB1435FB97A2A396B749F911160CB4078F5D34FCC42572B95E4BC5929302E1C77F5E13F633CAC285A61C2DE38877D8CB44D9110FB415C4B7B7132A04050890602D7ECFCC1747600E8F2CC27CE59C9389B227AE001B1133BA633D0B332EFB1D2E1E6CBFEFBD162CC62002A9603CC2F0B580AE0C541D4DBE47E527BE1095112855F97CFE206A38583EC34D7B87CD37824206D7EA069FE35A9C8AD0F14C45E5324A28013C1A2D705364B67D710FE03EB273218CC5EF9DE14243B6F097E7129D90D770B7515E214DBFE7BBB53D816EFF35714CA0B940027145B80598A2031180251C5B508B52970C98DB719F53C11A16E4E8161FD9341AD76EEDCB6AE20B6FF1C0AFF2E78E538515B8819BA6110ED4BE125037533489E0C76E52231A0EC0569DB5EF47F6492B7D6ADA2276F93AD2D53B08E45E8872378AD44710C2254556435483D4BABBA906E60EBEA08D652C17DACB971FF31350EC86E61B655D106D0A7D8BB8D224687C77D9BF70FF94E55D658CBA09EE778ABE08D01FFB05252F98B378DB8467CF5254CE62269C1D42DA233FC59D032B7E69FDCCB57B568BFC40A1050FD73D9E04D29BE0B4E63FB7A817DB603EE7CDBE280E772F7D18B4C2E3805F6EFEA65F1FA09A9F3175F4104C2642B0867DD997AA26D55428F41B522B8CDD48206FBFB97DA0E7CAD7BAB9215B7850B6AD4389148CFAC1F9DF17D1F6B8F629BF5AB4409E99B24016EC0F425ED4EFAC98FAA2166C6B6CD39022BFA01B3FD57D30EDF1F2298601420DC2CF757E3702E34B7EBD285D2DC6BD0FD07967EF1BB9447DAF0F0B5F52F2C61DB0E7849FF02D03C50703961A5C03FA23807218A04FAB9466633563B8833784DAC8E23B11A0D895A5EEDDAB644C23F6332735FDB0AF36345DB18EBA4E5FB4F4A30000DA7AAB1860853103792D4C32FE13B8EADE1451F6537212DDE6D0B1160A151BC4F33725698930774D5E26FF1B57FEE3D2C19A5E5AD0FB0A0093C4875159947DC8B7D915AE10FBDBE2FD73ED5342BAE093D764C26ABD30271EA1AAE78FFBB55B2CCF97CB8D75FC6438147718B4E844D14EFA5965BD6 +ss = 7EFDC40486793DCBC7C030273F8EDB4178075955EDBFBBF0F21B793206A172D4 + +count = 51 +seed = 450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88 +generateEntropy = 25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +encapEntropyPreHash = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +pk = 32B6C92F059443501427AC964FA569CBB074C71053F179BF1963AC704489EBB9936E23950E51AB7E26A98D6031C652701FA4AC59AA7C15D88C0337A067257B8D916DB0456FAD9622F44A928DF6CCE84A3E6634C9CACA246208920C487B9A666342ABC389C14C499785BCB91A95DC868FA20D25B08AC0E48C72E9B486151F21B11731D1BF049174ADF279F9020AA98C38372877299C4F54A4493A3B20F8BC71CBC490B363C4162055CF3A5C13650DB1154687462FC01B5E5B78C9F603255A24189B808358E17E01B9CF736A77D78A32520B6DDC9C1DD65A00E84B562B607B6AB472D5173AB53A97DB08B322E95CB3378D5D088CD3CA6FA4739C6633A27D686ABF040DCAA766BCC18D6B8A2F91E51ED6D49AA37AA44531BD9DFA25C116A842E50F53A68BF1617245E8B7DA778EB3343D3F2575EA84627C640A6509133F4C5D78151A6695245659955CD3824F264A7DF58EC87C8AA3066ECD1B68D848CB758487E647223C0154388912ED028AE364A9FA9A018D8558C3E9B179B66F2488C2BE8792B1849FAC0401A9756F209889FA637CF7ECC4F2C0249EB5C6F7E0219FAA2A9433759AC70DABC7BAAB623C2023CF7EC869B75BCE953CA3316B7A6FA685BDC7C8D467273268A0797B8D6FE57DDFDB03FFF7AD3D5B9C80DC1939720EE8810933A04F51B78262910D7E28C0EAB06B91980B65056472A293F2361183125670AC2426E514790B945D6B09C9EC354FE7C895A30231D95794F89EE60761AC9B2AAA9A75EF168C0950AFB498915B2518E010C3800764BC5A65C0C54B2AF686B7D954E77BC4CF8137AB398FE93429DD0AB80FC846D4CC8DB2B9B2B4BB36D4C4121639C1E74622E59250701302301B4DF96B2FA62736B29CAF0866096F842898B2C6012B93B5AC23D1F39E192002FF0B9005FBB8CFEB8930562A4E0AAE7A40C5032B8B33D0760D96C7C203920E2439D3EA02372C7F5D80B92259349076BA20C3AD4FD21752A3963CC5126342A963A363C1157F33189732F7243E465B14969F1CA199AF45B50851266742151A235A8BA9A595534BD6AA31CCF52B8C5885D571A93D2577C57057E2CAAE68C9C84F565C72681FB15056A345236B02A1E5B13289388F035A2F8E03402F8B0A44259179A904C94725319ACACD28AC1E449B87E8916091940E33861A4A35A8600267F04FFC6A3E06C60858D578BEC60EE7716FD4B0225E5CCEB5FC5437387522200F66FC880E0C874119C71F462CB4EAA24E67BE77CA67278344199B27E2A55B50F372B65345122225D7324CA9504CE4D12BC101639E93B331E3B60E1B520E03C9703A69F54C2B1A52254AC44B86F310A711263A5A9B87A7116EC5654F7297EA76B63F939C1F49CE99D52BC58876160401558193AD98C7C8F4B6822712429679214BB2B6E8B324B58E1F57695DC8968BCA7EC3717DF12C1279408183B49679B349E2E45686E722C3A57BD9547A65656CBC79AEC1D3B129837D84A6975D018C7AB04C88775E9C68839955775FD66AB02AAD69B76307F51DB2AB33915ACA61969AEFF14674A557C322AF6997B1A8D9C51445884779227EE742986446EA1719808996049038E0D9AECEE828BA054417CC3A683A7295066AAEE9CB429C4740531990744A987152DCA2388BA27E3769C8BF287E54E41CBC0ECCA95CE621F2 +sk = 2D149D32C41889573CCB5166C597C3FE207CB806BD13A8A7BDF86267A93DA7110A31F22221A17A5381C367EB1B9CD00810189C1F12358B59ADBFF2060ED6AC6712C660B51B553402D406BCC1D2444A863B6FF261E17AAFFFD01BAA2B05CD83050AB460CED09BC7C0C2963784B7F9798D837BBC0483001539F0EA65A0574B46785645019B25130095725FB71556ADD2832EA245E250973F504DC58A4BA3C45CC8259E7906588D688F4F4CC79A1A955EE31E0FE931D16CC9DA767C3A48BAD09874F7730FA74C349D2163638AADFB59A462E904C5530A0B485541E391B6037041EC6A0560563F186BE2AB97A42520A7DACEABF1216E16870437CF012A6B6D082BBB23349628AF4DD8CA9EA986498A80EDFCC2418C3F5A627BA8BAADF3739B3C578B2F193F57B72DC2827A2DC379AA31B6127C65352338C012CFCCE0AF1B33150D488CF47134E06B5EBAF0432C172090FA6671670BF7B66002E135E7C43D938343D5729E22E5597A06209E0793E65417DE945B5E1AAEB2740FB1B350C902C1390A97586564FA94120CF7538B21AACC0AC0831B477E37C9E984B73EC91ED88705EF4CAFD2F15A50227C0E4C0627D2A6D7875E9605AFEC339799690BB6F0A5B01141A6976FD51AA7A079827D37CA89726686BA95D6F275A59341FA229B4C163C260C4DBC4587C50AB8F0AC777849B5F700209F17C15251854C35AA23C20D486122EC8145565966F4A067251B96461950AC2171F1996E94517610338B88C091C356804CC691922449DB0645A404AE4A641D1482B58E6230C7965C23605D66E96C8F0418AD786801D7530CFA2B5B757E06ABC10518B274E3992E538922B717866C7EEF827D2BB4C05FFA3322981CD8069DFE028D878A8B7A002472D302253A83AB84ADF5530CC5F4671BF5219FE600BA97ABD2555C52857ABB76CCF4760ADB30346C55AA5340B189E1968F72999E64C0B76297D232412B3C9384783457B83309BA7EF74ABD50D16EA1C32A2362AAEBD02DA7790FB8827FF368261CEC14F3A2095323502446703783CA9B6AA595D690031297C59B25414455C155924A47896716AC45330CE7069D131B75A57769FD4B4CA1990170A3570160CDBEF1C930063D56E3546F09B1CD913C82057C0BB89111E6B1BBA88EB8CBCD72078FCBF5059FE25C84BB5607D7B20BD0733FD96DBAE2ABD9531DDBE3CDD89A926361BB56EA0E5F9181B2C8C1532312F3F9005135C07DC211B824B1E63AC96E64845C35C41E0313511A5D429663796ABF2443908D353766D40F47A910FD04A710BA5D6A5B301832A5B6016338D8858B220E8219512B643B8B60CA2A9347EC39638B787FDB44CE72408DCD2504DE24AF91130ABC09B2E7C9BB26B3393EE06FD77019ED3466E019AC92A416C9683DA22CAFB1A9AD3475AF17A15EE9F97446096647578F77FA02E79904FCC008FE509425446CA2A4C1DFF32CDFA4CE120230BB5CC9CB49A2E2841BF69A1C49A762EC171698CA0445201C485A15FEF2562EACABAD3259119C9BA4185677E03AA0470CA848709C4BA0C8E5814416C5678033C819773DB36E7A90C65FA82FFDF6921C38285122163BC0744DE5C5363C9A973428A6DAAD20E5A62D37017B464DA7637D32B6C92F059443501427AC964FA569CBB074C71053F179BF1963AC704489EBB9936E23950E51AB7E26A98D6031C652701FA4AC59AA7C15D88C0337A067257B8D916DB0456FAD9622F44A928DF6CCE84A3E6634C9CACA246208920C487B9A666342ABC389C14C499785BCB91A95DC868FA20D25B08AC0E48C72E9B486151F21B11731D1BF049174ADF279F9020AA98C38372877299C4F54A4493A3B20F8BC71CBC490B363C4162055CF3A5C13650DB1154687462FC01B5E5B78C9F603255A24189B808358E17E01B9CF736A77D78A32520B6DDC9C1DD65A00E84B562B607B6AB472D5173AB53A97DB08B322E95CB3378D5D088CD3CA6FA4739C6633A27D686ABF040DCAA766BCC18D6B8A2F91E51ED6D49AA37AA44531BD9DFA25C116A842E50F53A68BF1617245E8B7DA778EB3343D3F2575EA84627C640A6509133F4C5D78151A6695245659955CD3824F264A7DF58EC87C8AA3066ECD1B68D848CB758487E647223C0154388912ED028AE364A9FA9A018D8558C3E9B179B66F2488C2BE8792B1849FAC0401A9756F209889FA637CF7ECC4F2C0249EB5C6F7E0219FAA2A9433759AC70DABC7BAAB623C2023CF7EC869B75BCE953CA3316B7A6FA685BDC7C8D467273268A0797B8D6FE57DDFDB03FFF7AD3D5B9C80DC1939720EE8810933A04F51B78262910D7E28C0EAB06B91980B65056472A293F2361183125670AC2426E514790B945D6B09C9EC354FE7C895A30231D95794F89EE60761AC9B2AAA9A75EF168C0950AFB498915B2518E010C3800764BC5A65C0C54B2AF686B7D954E77BC4CF8137AB398FE93429DD0AB80FC846D4CC8DB2B9B2B4BB36D4C4121639C1E74622E59250701302301B4DF96B2FA62736B29CAF0866096F842898B2C6012B93B5AC23D1F39E192002FF0B9005FBB8CFEB8930562A4E0AAE7A40C5032B8B33D0760D96C7C203920E2439D3EA02372C7F5D80B92259349076BA20C3AD4FD21752A3963CC5126342A963A363C1157F33189732F7243E465B14969F1CA199AF45B50851266742151A235A8BA9A595534BD6AA31CCF52B8C5885D571A93D2577C57057E2CAAE68C9C84F565C72681FB15056A345236B02A1E5B13289388F035A2F8E03402F8B0A44259179A904C94725319ACACD28AC1E449B87E8916091940E33861A4A35A8600267F04FFC6A3E06C60858D578BEC60EE7716FD4B0225E5CCEB5FC5437387522200F66FC880E0C874119C71F462CB4EAA24E67BE77CA67278344199B27E2A55B50F372B65345122225D7324CA9504CE4D12BC101639E93B331E3B60E1B520E03C9703A69F54C2B1A52254AC44B86F310A711263A5A9B87A7116EC5654F7297EA76B63F939C1F49CE99D52BC58876160401558193AD98C7C8F4B6822712429679214BB2B6E8B324B58E1F57695DC8968BCA7EC3717DF12C1279408183B49679B349E2E45686E722C3A57BD9547A65656CBC79AEC1D3B129837D84A6975D018C7AB04C88775E9C68839955775FD66AB02AAD69B76307F51DB2AB33915ACA61969AEFF14674A557C322AF6997B1A8D9C51445884779227EE742986446EA1719808996049038E0D9AECEE828BA054417CC3A683A7295066AAEE9CB429C4740531990744A987152DCA2388BA27E3769C8BF287E54E41CBC0ECCA95CE621F20831C75B153FA17D336A79FF6E88DDF485DAF7B1B0BCF39D8DF15319D52AC67EF48A9254DD40B117941FA35A66BB50296327B725525DEEF70E128CA8045EC451 +ct = EAC0E656E53BD64C8F7B2BE3647A96712E4F83B04FA4555F1D3B8F9B796B9841C2D239956674CB51CA6DD945F2B9C40CB3341881E883A6A4B356538CC01E6E42B72DE8754BF38C4363C5F39C9661C13B207DC92767B34AE07C3D38BDE0BE4910E4AD5DDADCD4AFD41C5B6B8A00D537ABA8F5796F940B892EA5B797D2A19021168CF55F0054B6C6C7D43B192632F3DAAAF4DC99C2157EC5035E8039809A95126DA22408AAD3558C2C52528B46F313B32D8730CD5C5EFAC4F58F539CB7DDDF931C6EB9AE718BAD5B5F10561A922D4C0EFE6531FA7012568E5A372F6380D5C31A5F722768B2E9395B8D66768E4D8305DE645927D91BF7627977E9739563761581F438E05A50ABEE8178065406D40CE6818EDC2ED16FBF346DE6B40FF715CE1621FB2D55357E359FC3B67D1010FB65A732F4AB7C7BA83F4A9F8C294C7D96DA285B931F78AE792AACC355B8527FF2CBA6EE903B666691DD4F6ADFBD58F21EC2143571E061F6049B61AAF0A56885B34559DF49BCDC71B1D2DF11EFD96BBE1EC331C8483AF5D9EDFCA14F3955CDED0A2AD957759DDCDB02A93C5876FAF55EB8A32B74975D5ECFD3296B00694EA1DADEBD5932B306307943680AB5A2B25CAD113A22AADFBB9DD8F4C462FD6EFEC2560EB8BA20A0B2BFDEEC2193E8D8EEB70F759E32B3F07BB3F7F5AAFEFB74C5C54D7AA8369D8BE515EA5ACEF7FFBE63BE3AFFDCFF6144FF59BB0E4EBC711A9F001E05D3A4BB4971377462E695FFCB41D81AB63ECB228D47049367504E279E5CEC3D1CBEEE4B1B9AFD9EEEB8565CF6AE4FCC0F62F40686DFFBC7E9A4148EB3AFF9B876987E7D67756FC83DF5B69CF46FD3AB096E5B58F16756DD1EFFF6B898CCA1BF81E19B364C3854420DC8570CC2C5B0E9CEF31180712BC4CFE866465409433B57577EE869F77A3D713BF983195B53D825D6B3A6F1DA471ABC964FDAF6A9CD64D21C979C4609FF77339EF560C793DECC75A6C78D01A8A5A6D1071708FEBE38C7DD95CBFAA4685B5C8E22FB0A17849AD8BD0EE1A613CB2A3C6D1EF0A4D32BC535E45FB5C4022B870F7C410C9D93157D13C47E8C4A89DD9742EAF9603AA98E98020B0EA05E9C6D21752CFBB0D77995DCA48E0CDAD479364AAF3ACB4A99204A006EA3BE92B9819FE611FFC3C9C73F240B147C038151BA94CD1DC0E78EB7EEC32ED7B1D2DECDFC6751664B80EAFBA4600737FC2939413ABC36D14100DDB3F67EDAC9317ACDCF043006FC01FD97FDEF6ECCE4400B542A4AD2BDC4107D975DFB762761739ACEFC9A6B2EC26AB9C80F24059B46CB52DB1EBC929ED159497989131A7B67BDF78E141D8BCAE3DCBA7948CF843C2E1409830B2234EA1638C378B40C87907B1557A81044A5D4407CECEF5AB2DD55A28CF30AD06E741BF47A5652E56DD44AE96FB93E57259542F4EF268EB9221D714E472B4C633D2F4194BBAA72B629B83C7108AD2DDE0122B3A31F5D028C911DE14F1E80E23001FFAC0E8434226A1F0834CF5A5E0CA419D46759CB8D9A7236EF949A9CCACF70DFB4 +ss = A33BBCFF1EC8C4D3E3229AEC78463FFEAD5B96C6C1FA857921F8907A9180AF07 + +count = 52 +seed = 5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F +generateEntropy = e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +encapEntropyPreHash = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +pk = 7C6B065EF3308AFBA0CF3607B2C98D83F76F7C058262B55F7C0746B3C22437F00DE9D7CB69F40AFD60AE74B0506AFB96E30669F51C464A27B4F177666F92459B293DC208A0DAC5654A8058A8FABC2D1853009743A598BAB2C248068750F01227BE5A4F7C4C6948F9167E88894D43B5AA44687FF177DE837E2F0537F708A8F73A11FE6632DC285C9026BB23424AC2D1CBCE39AC6A0A7686F088D617B096436C9F773E7CC50CEA1C08DB20C2949A7878D18E7372CAE746B04558A8FBE97DF0B9A69090449A507E6E1C07A35680412033127037607B2F0502690B47BD300A84C041650DC748AC2C060260C933A0B81847243FB3267F3CC8DBEA4CEA40790F37CD0373A71EC00634BB3B3B087A82CCB1E1DAB77300156D8094A1D61D1F1BB3F977B749C938AB8092D71C93394856ED133075E2BBDD3CC0F27C2A2D34BC0F633F5E55C0A6C989B1E277EE9132F8779923EB2E22F78A1502BA5E55B6D53A05137867C10536E672C7336A3EA1F237263A6046F260ED3871F1D479BE589744361A0D819439779075CC47A5A33E18326615134D9F09B68B6873C6CCB682F6B75662CECDF5432C37189AE09FAF36735EA01C12F9CE64F4116D509C70E0072A242FF126710D178DAAE86539226C92D090D9B60DC63539F51B46DBF24CC8D54EDA255E0AC19B03D34F5A270B6FDA6D6408BCF1D2A46824B5290B8A26A8131402C9AEA052D0101759345F86A66A4D238A20C6531D792170C52DEED889AC3050FF87C659524337830C205622A989736B788092101933C0073C0B686106A9B88C17958A8711D272392AC448B01507634DF4A23846AA9D594C80BCA99F17505AC1793F2877BAB4F1B211D2985842795C4C1B9FC018DD15B510556EF89B687E6B01701CBCE0B56159A90F7B2C6FC1039AA38449A596C087A62B2EE5A7C3799F5A601BFAF8B9C598834FA115AE010F71167FD41B5CCCC45146009752F380CDC56453E554CC779604F976FDC34E9F135261EABFFBF00AFC514F2699AA6A5ABA0638542891C6858C7F6C6C4A12E4CE2D89B50B04C33EF262EE8B0D9A7777D3C56C85B1BAFAC7052FDBAED24303C843110C1892381887EB351134798B9745BC229208B277C2C999570075903DEB530BF22F7906B75DB35C3B24B04751BF6ED41724058C70988952D86B48519264D25EC2B817894AC370BC081362C841EBAEFCD7625A67A48E3CA492D63BB9036A5B9A35D21470586510ACF76FCC683035B18C05ECA7D0702E0453AE00A8144779117D7C19CFFB568A3C0959193D689A6ADBAC13DF43907FD45FBF3313D49425D32AB9D81C6BD9B3486C3636E6E0015152C1CC78C809F3A3FFBC6F0628609B996980B3C43294C0E293940CD65A34BAC8FCF020CC611E3E2C8E52F5AE886B8D9480551D012885318E5E6C1ECEE0A3D75B342667C691D19F34FC7946E7A7047097F7938516CBB6C7F3ABDB85B15E302A5547198AC0B89E7C2BFBF74050970E8DC746CF16BEE6147076BB89C5124A89E070A785427CEA590301CEA7AB28ADA228EE7BC7FCC17074063358A706989C8D6C82677287905722CCA0A24FF91958C44A3044787EAB3599EAF241EADB932B06B151A1A02BA8B244E9262B96144302124DDDB5584ADF5FEF6BDE5872A551B6840E3A082A8AA6DFB7232A6813367038CC +sk = 85B01A4A587BAE308D39792B47F71997FC55FDC2746F881DDF7BC215145C56D399C6447ADA39230866384BB718ADA160A7349747867CF695CCCDB8A4F1FBB3E573ADE85CCF38924F36482BACB9798D481521A0CAE103CC9FC9675184490F281D3516CBEE910287758A4C374C0A4313F1C29251B1655522936DC329F540A1FD887F0C775823436DF736C367AA3013341E66854FB39A9EB90B23CAEC3E84690AD531141F39914A77A767A47B60F2868CF11311AAC9DA94C72E9624D21814CDC99C89A4B35E1C4C63CBB3EDEA06888162E180503CFC6616B24D270601D0D275C03109DD9486220B66D523A8111B4DE5B99D236586A09A4F77A240CACB4A737C770BC4915F55B609075EE68499654BAF90622647052A8369872A93114C80C60FCA1345E20114552119669A0D3A7188D3326017CE92112F0B715C26B40851683478E5C719C11088F00AAC577F5A8763D4A76E3CD00CD9061F021672847BA0D4785EA7B1B28FA364E64C4FB7F718D2352B1FC26858B6552419A4D8E1B22F8C7992E3B5373183D040948777C356D514FDFB2D0C5A636BC5416A799270E5C975C0A62F3A76FB134646B333B75582F7F2C51CF4BD37835C3FDB2CE1EA86306362F8216D27E40CA43A45EDC9554F08C604624659AA10EBD29E59A60F7BD66EEE447F4398ADDC73387579148BC4A26B6749C961926FD34296DB3044CB0D2D1312CA6A6755EC48C46865A36A6330A9AA5D39167C6062EF1A7C82CA5C0AC1B163B85E43C278312C4304AA127D66576E7218C2D0C850108076109919AC6931264DC2E919FF441875E607A97772FEB45F14881FBCB37B4D00B45F416CF56C9501C6598FF9425249740EACCA49D92E31D679A4F16C3CCB4384DB45E47621719C6C585CCC03355216D43625C08760254AE3CC4AEB1287CD5C3F0911641B05C7036C9BB360C72902325830BD25EACB5A88ABDC926E0F205EE857AA66C8C47E434D8BB4A6CFABBD8B681C427846F0E18A2762152B170063B489A3E6B8BA06B00F14A3F2E6AC00725E5724CB629B7A312B3A1221C9460917C07637B71050BB644A38A8192270C857D43EA9304495206BF62B1C4C11B04A817AAA996B2A266CEB8A80AA46674F16207B61BFB484AF461B6DAD9A9E6C22C56F81BB355A6705310E921239497809012159E78A8A249796C155A9DC7CBFE7384DD092239C29773F6610E536A77B879EEF054C5E539A381043C1B53D69566A96D1931B166C6F066CF0EC81E7492A200876D42007724AC916460A1266AB77A327EF1282479685BC43A2718C93A806C3DE3A0CB918C7A734CB04759341C5B1496679987AA5DB93B70F903A5F4024C3DA6FE8BB2EBC27182E1179611C61F8F6214069AB83C7165A46CAA74BBCE0897FABEA9B6B58CD34E7535B0297B4359960D23E4A498CF7610601D92AF2FB6163C4B2761615121B62A7900B08D61065C83A69D51253D48399FC665962AD36275ED3774F114A079F13B8BCE420B44638CFA6CE6018B58BEA422A8287A6680EB21C75456592E8B24CB6C26EC3D3C1DC4A19CA16888E9B7FEA1A863B7A0143307530B533269A8B692CB4522AC1AA27B01D38603FD009E1C02017BBB36DA2049A2C5045A63081266D7C6B065EF3308AFBA0CF3607B2C98D83F76F7C058262B55F7C0746B3C22437F00DE9D7CB69F40AFD60AE74B0506AFB96E30669F51C464A27B4F177666F92459B293DC208A0DAC5654A8058A8FABC2D1853009743A598BAB2C248068750F01227BE5A4F7C4C6948F9167E88894D43B5AA44687FF177DE837E2F0537F708A8F73A11FE6632DC285C9026BB23424AC2D1CBCE39AC6A0A7686F088D617B096436C9F773E7CC50CEA1C08DB20C2949A7878D18E7372CAE746B04558A8FBE97DF0B9A69090449A507E6E1C07A35680412033127037607B2F0502690B47BD300A84C041650DC748AC2C060260C933A0B81847243FB3267F3CC8DBEA4CEA40790F37CD0373A71EC00634BB3B3B087A82CCB1E1DAB77300156D8094A1D61D1F1BB3F977B749C938AB8092D71C93394856ED133075E2BBDD3CC0F27C2A2D34BC0F633F5E55C0A6C989B1E277EE9132F8779923EB2E22F78A1502BA5E55B6D53A05137867C10536E672C7336A3EA1F237263A6046F260ED3871F1D479BE589744361A0D819439779075CC47A5A33E18326615134D9F09B68B6873C6CCB682F6B75662CECDF5432C37189AE09FAF36735EA01C12F9CE64F4116D509C70E0072A242FF126710D178DAAE86539226C92D090D9B60DC63539F51B46DBF24CC8D54EDA255E0AC19B03D34F5A270B6FDA6D6408BCF1D2A46824B5290B8A26A8131402C9AEA052D0101759345F86A66A4D238A20C6531D792170C52DEED889AC3050FF87C659524337830C205622A989736B788092101933C0073C0B686106A9B88C17958A8711D272392AC448B01507634DF4A23846AA9D594C80BCA99F17505AC1793F2877BAB4F1B211D2985842795C4C1B9FC018DD15B510556EF89B687E6B01701CBCE0B56159A90F7B2C6FC1039AA38449A596C087A62B2EE5A7C3799F5A601BFAF8B9C598834FA115AE010F71167FD41B5CCCC45146009752F380CDC56453E554CC779604F976FDC34E9F135261EABFFBF00AFC514F2699AA6A5ABA0638542891C6858C7F6C6C4A12E4CE2D89B50B04C33EF262EE8B0D9A7777D3C56C85B1BAFAC7052FDBAED24303C843110C1892381887EB351134798B9745BC229208B277C2C999570075903DEB530BF22F7906B75DB35C3B24B04751BF6ED41724058C70988952D86B48519264D25EC2B817894AC370BC081362C841EBAEFCD7625A67A48E3CA492D63BB9036A5B9A35D21470586510ACF76FCC683035B18C05ECA7D0702E0453AE00A8144779117D7C19CFFB568A3C0959193D689A6ADBAC13DF43907FD45FBF3313D49425D32AB9D81C6BD9B3486C3636E6E0015152C1CC78C809F3A3FFBC6F0628609B996980B3C43294C0E293940CD65A34BAC8FCF020CC611E3E2C8E52F5AE886B8D9480551D012885318E5E6C1ECEE0A3D75B342667C691D19F34FC7946E7A7047097F7938516CBB6C7F3ABDB85B15E302A5547198AC0B89E7C2BFBF74050970E8DC746CF16BEE6147076BB89C5124A89E070A785427CEA590301CEA7AB28ADA228EE7BC7FCC17074063358A706989C8D6C82677287905722CCA0A24FF91958C44A3044787EAB3599EAF241EADB932B06B151A1A02BA8B244E9262B96144302124DDDB5584ADF5FEF6BDE5872A551B6840E3A082A8AA6DFB7232A6813367038CCB30CEDC4316B63D75B641FBAD2F33241A3FC47AB8B3EE1A3ED597E5B04F77C68E6C45C7FC62329B13C8D29844405DB8FF6860DE474BF727ECD19E54E6E1A141B +ct = 3EE8CAA61756787B200AD5EC90EF835F55359F55AE04C8CAE6D2FA90CC2E32ED38349B52E4A6BA4ABA658A972B95EB04BDF9D9F007FF1DB61055B41052095687D07626DDAE5F9C2D2E7931C6C45250F5604EBD6D6C4044D18C0A193C9CFDCB212393510F1E966377F0BF34DA89597CDA14FAE339D2A82D3415C7652A4B95945AD0BCB12992472766699FD0F5876F728681AF0EE76D6FD4E45563DCD52AA7C2E5E783CF2A6DEAFEEC004C87EE47B2B3DCC98D59486341ED9B282AF0705B69EC8D498517D0CCC5847D6431677A8FB7B5DF6BEA0E5821CAF8D14A81A0AC674089953179A3DD7C0198A9CE8732663261530C138EA09466E68F2A485A492D5875736D590C6BF0AF9238752EA3949593CD15AECDCD783DA5934BA69B70E1D9AE7C56B8885A3AB409098C17A4820CE2BFC365644A8180735EF122F41ECDB5387E87CE5EAFA8AB1414D48C7B57F52F3338AE5E5758E83E560178DE13676A49D69EA415622CED3C09A42F354B3E48205937A660EF1F9053CA4A1FDAB50FB5E83898B6E5FC8A11D6DDC1B06A29EAC43A5F47F2F70FCB085BCDA559BB3CA3B035E119970ECA86B5F373ADF2BA9CF6B5755445FDB574A40650D7E75D7E36F90CD7C96343446A87882AD03464E8ED40797EDCD84DF74FCFAA83584E8A75774DEA67C74F8C5CAFC18F3BE9B2C11EE6EC6E89CE7452D0A98C64C8F6DFA6198D9CA561E86A1631BA17A6FD6D4181186ACDC327E71FB300A9397DB532B88823D8D310ABE4FDABDFEBA7521C939BBF7413BB5199AB40DAE9A8B7EDDCE3C38293D30D6A5F18FFCB12EA2E8ECF1A942E20F8310825BC6960CDD7041BD9186F723743C8C98432536EF35E69F0E7D8E0A0E05F3E40199EB1F2F7A41B18B0E7F2245FC7BBA28B83A3A4F0CEC6CB919D0CB7B66745200FC4074C510795982665FC880D3F6E3820D4CE2333C717D94DDD36C4341F01819002E21C41B12EC7E1184A1F7E3E6FCA6A18971B1C438C773A7124DE94320443C7D80C727237890CB13825436CF0ECE3FCB867A86F8C2BECD314E2274B9BDFEB3971EBE1730BD44E26B587C464E86404B8A18E35C6FC427C7160C4079C394D11CC93F473153967A394D126DDB344441AE12729464DA5E813E5461439B6FB0925A97B726A2D724850829EC1D6E1F3881199CE47E93101D99439304B00FAB1E6875EC82E4D8766912505121628AB17BF0A5094649E8D5803A59CB35999D8E9A2A7D14646A26F9DB4BF0FDAE3527CAE7CD04DD9EC949DDBB122616881AFCAD30959D5022DEFB1A2F86903CC0B1A63DC1D21D477319DF95E7B39322B69F8E3260B0F52D1EBFE21D0754A2076AD4BE30E2E47165EA3EEB054465AA4B5DCDEE133EC90A4D9C9326F153FCDE75D9E3A3351041D13EF0B9117098F2E266EDF666A3F333D8FD17C514A4A351CD2CFCB044FBF406E1DD5C99809731B988458055EB888E00665F3B2EFC0E4E16F81AAA6F28F1C87495B078B236971CFF1148C71C374D52AC1C5E68CEF548A30B0D6223E995D7216F6604409101D7B +ss = BBC0B0A4782E2BB9EB19257F5B80338D1E239AA6A08710CBCBA0ADB974D7DC64 + +count = 53 +seed = D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E +generateEntropy = cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +encapEntropyPreHash = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +pk = 9E686B49D538CF32A05AB82372F7525DF40085B3413F078226B97C234B815EC615B2683F1D9AB32DC0314C6CCE6E9620C8E73B1DC85BED5205CDE5A44F40427865A62356CE44751C7278A3B236BC2D208C7B383129661810A6A2962496D058CA4875AD234C2DF951612E665984BBAE791C279EE835B105202D4751F1A330DC6B0BDCC38FDD6458B0CA7A9BDA026BD64E80868B87B58CCF2A37CA94CB06279EE77A6731E847487142561863B5F38C5AA4C0158AC28E95012C10A8B8E99EF7DB12C05009311A74791C6C8B355E4A861DD3CB6FA085884D7A7E8CD270F656CE29F9BF3B91B798032C16B00F8CD722A1CABFBB25C3002324C56B66DF87182504581A76297EE1181CF05A6D89698CC94021B16574264435F2CB137A7A667A4548C96F835CBBCF27805AE37448674AA998818CF26D15A63689777A9B98219AC3B9ECF84203826EAE294800F5A07FFA886CC86E7D095F42C471C121A69A1972A7906ABBD31003F6C8C0D07EF481B55FE185811084D9A472CCBCC586B6A9A6F24D269AB36126A3F0381B29532D027C2D5E21CC5B9C6EC8303E4B388A6B7216B3E581C0566558107C8B94C599F09C2ECC4B7A824FA3DB9A29722317D5BC5D43827F4BC6D3A91F65DCA56BC26DE9D40BF2F69263CB010A9A24A749C931631EC2D13EA4D5136AA8A97EE019AE1291EA34B0807886FFA323AD3B0F83F82E5D9A2D748945A3CA34B9535D0460A6F734BBEEB66A4E3C257BB079F5D80F6DEB0DBEC130FE4A182FDB16291403F37A191C381723965C3FD90D9F2B67C36CA3AC141030AB516A01453532AA06B73A91B5BA7D1A308E286FCED38F2858801022A453320A857B564179C55F0436B25CB191865DE69877B47041D9D0C2C9BC42CA513F207A72EA9A5CC48B573FB402BA8B5AE6D73F2E0B044B8CA67C1031577099B9975FAD7103C7F6BF80099BB51138D8A7AF7BB509B761A9C6407DD9826B7FF87879098248D779D6F26AA0215084F286AC77C50849AD19F29A32B07EF517000FF71799D6BE1D177508BB969D9479C6C037A5A18BF4302720E240DFA603B7F8745144906BB88522505B19336BEE5572188853A47B4F8ED8A040B251307299BE642E086317E1504784990F2149CB2D89B1A8542E4A19CFAFD57ADE9A234545142AFCB3E544B49DF75B0CC78F5AAB935752746EE7A7F7936777330A66C1063C50BECC4286A3DB4AA66CB602553849B5BAAF83965AC6BDB19A9E5DB8251DE0267EA3C0EEC342B51505469AA7FE936A5829463892645438A3A182859DA136E033B926695421A1891610816E136DBBE36ADC08CF00E4B44649410B2A11EF254144C27787E54CC5A533E8E54F11EA94F7E9C2009D25A6248321F04A53C31787C12ACA9CC78FCC06B161701852215BC6C29D1779F5C183152CACB583A90399746F75C5BB337F1B580B9029B112579884F792EA5A52187A109F547CDA89B7FBBA90C66065A33423DA4515D13BB5FFA074AADB0C55119065A51239511BB33288F994B121DA8913992B979A59BBD64036968621E76AE336096FD6125CDAC4F767A883E6448B078DC04B1F2B7AA49A1180C0F3BC65D2A93458291982652063419A9CB7F1042C38F483C4A90E17ACA78E9FE10B44687F9AA606CAE8888E4C21AB0F7B85EB3D3A2A3D2FE8ED883D1DE0 +sk = CE732E28B21F42F2BBD1B049E6B80264B218B581CBAB8C9186E325F7617895E6320FE5C697FC3B82546681B3CA5F4A52F1F7501B652F86D35CCB9756E869795C166362FAC89C7B5AD41C7C74C596E2A7458E419CD10C10C890C94FD3564AA25F1EC3A3282607D8B1864022CDCCEBB1B1E48961207E29264A9CA86C94B71D5382C9C6B8004C818F51A52006706285BB3281618A157C80C2C00905C33316516C17F04460124FD79A1C330417984220334C84D96A66FC8A5556814C58F7826EE86F17319DA3F504F0124C3F06CA50792C1E1800FEEA8A8E8805A54BCB90C52ECA144677327F5058CCA151617F443DABBA304B353F4A5CAABF0C179A772582711C033B3F3C1225F191B887D8294FD18914850DE6B194B91C250374963BDC7215B07CDAA8001372A21F0C3845979386C27949E0BBEDC0B004258866A01EC5CB82FC751BA2F4510E514A3FA09B6AEA7E5E45762076B81D781C2BA91DD6F40CF13C91E947A7D7ABC2A2AA91A1404D87462B42AA71EB15209A9B0D4990C2265B051163CD2BA8319576758237482F500F7E94B3FF099616225737A766C10B6AEB213B5B073EFF93C3AC91BBF2B93FF47C84D7CA2E794990E2DB4A7E9AB19CB50CD522427E6A935CE3976490B21792CCE5E4B971668C4793CA4954B477703730411DF1F5AD2557CAEF78C914D0C223D836C407936EC58825F3B2A1925A5164B097A94A13D8AD3A27BF1FFB0C08C72B92215CB1B67C7D2C4A7BC7A6A8A054D2A34DE69C78195BB149E4B4CEBAB78F41612DB19540385F2F74757C662C2DA3C7B03A34A9524E2AB90F5CC21FC0D2AD84BB996E6C73426770FFC1C9942CC22AA2934D97A66037A18760C51B0236CA1B1880A2286EE5241FFC220A4C6EC0E296090874B3CA751DD701086A15F419C67EB4514744047D7848980C036107586D36818E74AD98989C8C02AFAB4134EE0B545ED707876A613FFA10BE7C3F10B758B215827ADA9FA1C83B129C6BDC5B621D3A5DA7F396D6E29B184A38D8091B6A2C288EE2CAE833A68A3CB6B30BAC5AD7567C788D8C803A7B622FBD8A253B274B93593115B5B7A5282EAF93706C88C178BAB897B7198C23B844219852A60410E8AFA85C902EDCB9A5E87A31CA84AC6B89A75830566062BC159CB129277AF0645D5817C8822E384040F1621D66D41643897DF21C1013CB1B426A703F120F21C780C67BB011FB3E8CB746C0B14C9F847DC1235F72E6BDFDA1C55BD26E377395C4B17B764A41E0F7312782BF71820DD379BEFE58901A011FADAC1EFAE549E5933AA9F9C64CE2273C486B56251674D56212C0AD7637854C7B8447A135FB960FFC435AC7553DFE935CAA98BF32186817B5ADB42375E96C30D0A96DF39658EDE95912946813CB75CC32B395AA73A916514533857B4C3405FC32C2946CF4F4251B2091B6CBB00CE296459C45E558B5048B79CC4CB8AA01BD7E82320637A62E2038D5B3C0593B42D32A38BE8312AB022EBB496A5FC4A991A1BAEB660A23988FBA329A79DC7144D20B5246466F25AF4AD971014970EBE2B36316B86B3585F6B0753711A0BF3952C688B4CF6C8A24C0964CDC1F5C1C34B3C28359BA232840063AC30BDDA83F0611042FD8B7C2BB439E686B49D538CF32A05AB82372F7525DF40085B3413F078226B97C234B815EC615B2683F1D9AB32DC0314C6CCE6E9620C8E73B1DC85BED5205CDE5A44F40427865A62356CE44751C7278A3B236BC2D208C7B383129661810A6A2962496D058CA4875AD234C2DF951612E665984BBAE791C279EE835B105202D4751F1A330DC6B0BDCC38FDD6458B0CA7A9BDA026BD64E80868B87B58CCF2A37CA94CB06279EE77A6731E847487142561863B5F38C5AA4C0158AC28E95012C10A8B8E99EF7DB12C05009311A74791C6C8B355E4A861DD3CB6FA085884D7A7E8CD270F656CE29F9BF3B91B798032C16B00F8CD722A1CABFBB25C3002324C56B66DF87182504581A76297EE1181CF05A6D89698CC94021B16574264435F2CB137A7A667A4548C96F835CBBCF27805AE37448674AA998818CF26D15A63689777A9B98219AC3B9ECF84203826EAE294800F5A07FFA886CC86E7D095F42C471C121A69A1972A7906ABBD31003F6C8C0D07EF481B55FE185811084D9A472CCBCC586B6A9A6F24D269AB36126A3F0381B29532D027C2D5E21CC5B9C6EC8303E4B388A6B7216B3E581C0566558107C8B94C599F09C2ECC4B7A824FA3DB9A29722317D5BC5D43827F4BC6D3A91F65DCA56BC26DE9D40BF2F69263CB010A9A24A749C931631EC2D13EA4D5136AA8A97EE019AE1291EA34B0807886FFA323AD3B0F83F82E5D9A2D748945A3CA34B9535D0460A6F734BBEEB66A4E3C257BB079F5D80F6DEB0DBEC130FE4A182FDB16291403F37A191C381723965C3FD90D9F2B67C36CA3AC141030AB516A01453532AA06B73A91B5BA7D1A308E286FCED38F2858801022A453320A857B564179C55F0436B25CB191865DE69877B47041D9D0C2C9BC42CA513F207A72EA9A5CC48B573FB402BA8B5AE6D73F2E0B044B8CA67C1031577099B9975FAD7103C7F6BF80099BB51138D8A7AF7BB509B761A9C6407DD9826B7FF87879098248D779D6F26AA0215084F286AC77C50849AD19F29A32B07EF517000FF71799D6BE1D177508BB969D9479C6C037A5A18BF4302720E240DFA603B7F8745144906BB88522505B19336BEE5572188853A47B4F8ED8A040B251307299BE642E086317E1504784990F2149CB2D89B1A8542E4A19CFAFD57ADE9A234545142AFCB3E544B49DF75B0CC78F5AAB935752746EE7A7F7936777330A66C1063C50BECC4286A3DB4AA66CB602553849B5BAAF83965AC6BDB19A9E5DB8251DE0267EA3C0EEC342B51505469AA7FE936A5829463892645438A3A182859DA136E033B926695421A1891610816E136DBBE36ADC08CF00E4B44649410B2A11EF254144C27787E54CC5A533E8E54F11EA94F7E9C2009D25A6248321F04A53C31787C12ACA9CC78FCC06B161701852215BC6C29D1779F5C183152CACB583A90399746F75C5BB337F1B580B9029B112579884F792EA5A52187A109F547CDA89B7FBBA90C66065A33423DA4515D13BB5FFA074AADB0C55119065A51239511BB33288F994B121DA8913992B979A59BBD64036968621E76AE336096FD6125CDAC4F767A883E6448B078DC04B1F2B7AA49A1180C0F3BC65D2A93458291982652063419A9CB7F1042C38F483C4A90E17ACA78E9FE10B44687F9AA606CAE8888E4C21AB0F7B85EB3D3A2A3D2FE8ED883D1DE0EE044DBDF6787FF038DBF9C133557169C62FC1CE2580739369AA87DF00B496485A3407F591791A5DB4578B5972093A95BEC3B8E70C1D542C9B5C9789729F8922 +ct = AB24A548B90EF59F7595D625B44E8A9B3CB8EE09A1AC6213B709B1CC1833B6D3E3ED145524647D33C527F0E7052DF7FD94C2B1EBD99577600DDD3266100218ACE8C5AEFBBBB3C045C5440AED44856616C5A4456D28A304D3D00B51EA20ABFF1E0A1C671BADE1E8BE2E3BB9A41F1C73612803DB0FF713B5C717B9BB751F750C1FF6310DDC3B25A012F3902A6BEF8F2E7C3B0EFEB6C8B267E1BC9152D48F53591CBBB2010E5D40E778368B9E7E8ABBF52BCFD5B61E4B2E84E8CEDE9FE87CC14DF8890FBA78466246888DD36D71742050C8271261BED8199B5D4C7C341F5E34673E47E58F42AA3F9D28CCDB1DE32A7C6E6AE11C346DDC6D7A9B4E1384E85A466711B2F5A5FFCEB0D00C4F10C8B656A878CDAC8D1738B73E003DC44FAD15AA4E30819C98DE28883E02E501BECCCBA97019D18EBB0565CDE8784F0210A9E6199C55A60AE87559A6104662CB9631BFDFD6E3A7F9FE3D7D542C1D01520984455947052C0C9E8C985C0F247CE9FB8C0D8F2E5EBE09BC6D06D1A1EEB2C97CAD3F557CFD8723D2C3D036F1EC38CDBAD6006A6B0002DEFC9E0599D9950157324A3045DC616786ADE0A56E6378793938485C69411EB7AD38267C02E44DD902E8C242C139DCC336997DA91D1659C4582ED0021B4E14A4E77DEE7803B927B8C12383911461794718355C74F366968EE72289A8AEBCD3BF800F9E91C83F22F6D59D372134CE5154E29385CA973E9BBA04CB674F8C87D4DC29386144F577D6B177791CB28DE72CC33226B9003E42EB040C635C80305996A303F8AA82B6DA9BEA52FD11618F9D04B00D5A1540D836829FB363AD62F63ACF4EE550B09F665A62CBA6AFAA9509E5AB22C02ACC0470B144A110A1D497EE5D2A764CAD986F7F96F3BBB4156C7713784D5D7F343F9D4FBB9E7F75114E5C60EFA58DB8499CEB533B4B9E50522364BA540AA3071C80E5FD3139C64DB8279058BDAA72E1515E483609B537A5D524A766E2914F45875D08F7BE6CDBCC08C9357FF06F897FC3A17DB8341C8E2B1D63DE212E512A51D60129A1375FC9261FBF5D8CEC9252331D75F7A4D180219EA5A6BC18E8A612042639A8B33879F2F8073C23A5B8A983B131193B734B66547426541ADABE13990035BC87A780141972ABD4F98559A6D92B9A605D7AD4F00B8D96F3A4EEA619D9F45D4C2F834A00064CDF2C58B51A9ADB542CF8051B73455BE9881E5097CA9D6F81B0240012A4E55369A056DE74C277B5A0915417A5EBA7A572A9B81121B4057F9A50C94191A446844225860096BFFEDF8B7AEA605F193CD60CCD0A2697D8F8DEA9262A3C5D89E8E94E2721A359364FE1B08245EBD344040746665FA6EC5D2B9D113EEAB5CC42450B5330A232D928FE674D53166416E0E8179100E421341DDFAC2E0E5A80FE51A6C6E8F044DF8EB5596809774CCAC4C255710EFDFF2D4614CEB463BCCF6013A74E1F22760A68AD214A1F5B6952E1935DBCCE1811EE19C2CDF8FCD3D38F7B6C6533DD9DE19B67D917BAE686BD9A9A30FEF043FC8C9055AC8B6DCF +ss = 3EEA7528610DAE3539F5F81EFD9BEEDDA4D45EF0B9FF91D3D4F3561B4981D286 + +count = 54 +seed = A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7 +generateEntropy = 6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +encapEntropyPreHash = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +pk = ECD4C65CEC93A9B26EFE3B667405482E3AA37D48AEEA67C1698008DA4B68683697DFD34FD72A6F39EC0AA0806EA5C59B4554182F6034B9C5B7CB438E21A14774D58AFAB0099E478A4BA8568E192C71DB7C208B7115D29BF649BFB3D23C2D70599682C549EA28DC16597A43AA6E65C77C432F554B067A64AD62AB71492A1AAD6045677C74E3E8773FB8665259ABD821BF07D2157C09199435BF41992628534DAAE814EE4AC64AD89FFA1547442B8CF6F54664C550DA5CAD0D828174805DA5D66F01E584789992BF0A4036D770B6C5B3E21B78F5DA2467DB42479B478F0570D48071F028110F555857E4ACB555B9C7D5B5D913B75D5B393BD4B9B2C12D34027AEDE4A22FD80ABE26A9C93C938C6B1348708D1BDA7FE6C55BF66981695487AB81362F50B7376C6A52CC39769B921F575E5D7A9666ABC2DD9459A5595E3AD631A0C638C3A2181B649704748141394053849B4F996F9B8A68567B73227B8C9E4588EE4A13B75379D2776A7510ABB21941C2B36357E8248686A5D973B946B82E40802290651A073636B367671C9C001AC91AD03B9D6E83721AE1247CC188FC05B0249571656A276EEA09B6D3376C208335618B1FC2748655CEEF805C39165D0CE9BFED062ADD0C0A50E43167C80E5301A076C9CDC1F13852A5987AA3CEF5E5864A706B3DE947D2AC8E8CEA0C3F83745BF3185BAC9FD0162510F70BD20129D7C5215026114C4B5EF044A8A29A3F01FA02A0A3CE928A65CE8CB566848110994E7CE20EA5C30304D6CCBC7477BB78B3EC527758B7828B836DBB2742AF6095A0BB882C2C9D8E162618029C1FB5AAF4B963FCC4A35AB78B0D9942FBDB53D4684CA85218DC27678719CA0D4A8CD8E9BCAEB944B7C0670AB171927C56C35034AD92BB3E6714D0F7C137C2B9A1FC5B72367C35C55D5FEB93D1274B88BC558158C5D478C34B68240AD193E95C0311AA501B3C1C44B20AB6CA2D2DE1C56B65618CA53F0E91550851BFBC289206D1406B27047FE610EC01A86E8BA94516AA926B99879836DBB27A7056C4D54BBD19A44096D1B3F3E9956CAC29E7AB95F175B9D9A0078DA633F10A6FEE899F400533F0F77102DA19FB02610003674828758E23B5EC724C6829B95B8A6750F1988F431E7537CA9D05701AC8AE2034688082C5C20A122C6349DB27AB958504FDB4C527B223B2420DB7246A4A69B58085A3C1E6997DB19FE17A2BC23BCD60B924CC393EBFCA864DA054BA38BB733B00FDF57AB147B922278FB132C5F5774BFE368DC2B66583790D30D282A248B7E9D43A562BA1892A985B75A7AFF961762A05FB35B9420905BB8C4DE00A3846E38CA7D71411E89F9E2C9489C597834C7A5315080130648F5347639184F315BFF2D580FFD0227C9185ADF9203ED50BAA43A9174A7AE9B5655F2245A15C30F877BB7DCB2EC184138792738113895A980DCA31BAF6B5261E10A1D98AB660C066BCB05AC25429775C3BD1550D4A823FC96442CB2770751C812CE67613E48BFBE66A0FDBA909317513220EBC3C55FA1364F318812199009AF24F9F70C36F81B22B20BE53208F0DC44DD3B6ABB7236E1FD37C53FB1EE8C86810863A86B0029A58955DC73EC8A436112B5C3A75CEEC356BBD91355E4C3941A07E45AD3ECB9AE67E7527F70F6E07A757BD112947074D5120A1F2A1 +sk = F76C7D8002B7CA65BFE6A59AA3645A8E51AFE5FB80145241134CC072A60AD4B72D80C2BCBE1630EEDA661CB62E01B0798203A1A287C4B8F725DD422BEEE6627C864149EBABD84280739193067A2348F2861DBB7F1A0914BA2BB3AC6C80D5CA1F483C8B86C1CF5A2C3BF8F6728555799381A1B1F3CD02E445CBE798AC0361E15335380051294667B9149F38D85A1839AE43D331BF14091C4ACCBB24C8E8105A9D1185BA880B7E13CD3563AA235B899E7509525280A37162C043B089D5A0BD48B225EBB2D0538F49C8AC3C3B0677D8093CF70B3404016B4686D653CE4715A85953171BB937F5A1916271AD53318E8155269DBA4D0A520D057963E70CC01E680FE8408D03D3275C95A2C528190924749BC32DC31B21B58C6F5E4B59C157CAB7653C0D146DEC9A3F94E241993B09BD62446F35AD7772279E116464FB316DB8449A3AB7525B3E89B12B54F14FB19057C39510B072894831A5747782D404487926AD756B1BF81CB416D94265DCACEA475FCDAA727D0B5F01B376250B123F717FBB0B1976B7704FE5AE5AC10CD17B87FA8BBD3D824D3B91B567B5C20243677D741AE2CB1C1D049A842B7F9DA9CECE8931851BB35776CAED97C27D395108E42661AA60CC181ABB2774C67773FB29B445F3554D386C87D489D895A43EF268AF0C81F6065E57E744F719120323B013D35801E26BAC2700968566512106F5161EE8528372D45A42B41022239FB0B3CD23C4251927B355719A1F2A0689A4ABC508660DBC282706B765CA4BC1887FD064CF8285B1155863E15B112BCBB1962255B362CE8FA4C51C97CFCEA7004DAA9F746766F2F5487C93B99EE9825CB78AB0A98BF6863A083758E9279245E495AD0A5B86724C1ADC3E67D756C1C8647FB4BA32B75A6DA3A05A870FC1E12CD279666CA046E064A74625530E742EFC72C1D5F959C9D256389C4C63609FA11A8FB5E70E1E2256C8164D80C69FB8F4008A647AF7F3AD960265F55CB786E8726B65689A6A751FE045B7D45AECF50605D135A44793AD2C6BBA5A59D293528BD94D65F54BAE4798EBA5B26DE8B225728EB8836AD1F373F66A2134B8B429A8457B600C5A3274B0157F66F091EC88436D5667802A15749B4C9C499A36C58FC5A7CCC10A604ED00DE74BBF433502C02AB0ED949F5DA8B9EFB83C4A2395E49413A7030F4F95901E8AA2716A3EBB09AAF61C9384586021301DE0F8C085421460A10FDD176C68B4C115C91DAC04121924213855AC22E8C98E3643C3D7C3B6C6C4CA964308510525C5AA00C32AD9BA258BC44A9F521A2873BEDAF7C56BFC26A320C0FE95CFBE12C0038C1A65B62C18C37E61A2B9194C9EC1DB8B9FD036C7C3A620B5C661D8AB0B46A6CD3391E53218E40CBDB082C2207630C2715541B10E3C395BF2A5A15AE8B506880DDE937432ECB150F9B3C136881058A750024D9B247232B7289BD07462C051B7BA599C985C6EB08C7AC22135C99E85930113554C59AC06AE298D5935658F513644B01132B4C1AB84677E342A1F4A8A9D5C6A44659805CC8898E563823C8286D54A1CB4B8DB866A8F5C74F782784E4B6FBAD380C5131FCAE11D4EC89DF82490B4F1BABD4673D7417B9CF04513718F2CD0CFC29707145034ECD4C65CEC93A9B26EFE3B667405482E3AA37D48AEEA67C1698008DA4B68683697DFD34FD72A6F39EC0AA0806EA5C59B4554182F6034B9C5B7CB438E21A14774D58AFAB0099E478A4BA8568E192C71DB7C208B7115D29BF649BFB3D23C2D70599682C549EA28DC16597A43AA6E65C77C432F554B067A64AD62AB71492A1AAD6045677C74E3E8773FB8665259ABD821BF07D2157C09199435BF41992628534DAAE814EE4AC64AD89FFA1547442B8CF6F54664C550DA5CAD0D828174805DA5D66F01E584789992BF0A4036D770B6C5B3E21B78F5DA2467DB42479B478F0570D48071F028110F555857E4ACB555B9C7D5B5D913B75D5B393BD4B9B2C12D34027AEDE4A22FD80ABE26A9C93C938C6B1348708D1BDA7FE6C55BF66981695487AB81362F50B7376C6A52CC39769B921F575E5D7A9666ABC2DD9459A5595E3AD631A0C638C3A2181B649704748141394053849B4F996F9B8A68567B73227B8C9E4588EE4A13B75379D2776A7510ABB21941C2B36357E8248686A5D973B946B82E40802290651A073636B367671C9C001AC91AD03B9D6E83721AE1247CC188FC05B0249571656A276EEA09B6D3376C208335618B1FC2748655CEEF805C39165D0CE9BFED062ADD0C0A50E43167C80E5301A076C9CDC1F13852A5987AA3CEF5E5864A706B3DE947D2AC8E8CEA0C3F83745BF3185BAC9FD0162510F70BD20129D7C5215026114C4B5EF044A8A29A3F01FA02A0A3CE928A65CE8CB566848110994E7CE20EA5C30304D6CCBC7477BB78B3EC527758B7828B836DBB2742AF6095A0BB882C2C9D8E162618029C1FB5AAF4B963FCC4A35AB78B0D9942FBDB53D4684CA85218DC27678719CA0D4A8CD8E9BCAEB944B7C0670AB171927C56C35034AD92BB3E6714D0F7C137C2B9A1FC5B72367C35C55D5FEB93D1274B88BC558158C5D478C34B68240AD193E95C0311AA501B3C1C44B20AB6CA2D2DE1C56B65618CA53F0E91550851BFBC289206D1406B27047FE610EC01A86E8BA94516AA926B99879836DBB27A7056C4D54BBD19A44096D1B3F3E9956CAC29E7AB95F175B9D9A0078DA633F10A6FEE899F400533F0F77102DA19FB02610003674828758E23B5EC724C6829B95B8A6750F1988F431E7537CA9D05701AC8AE2034688082C5C20A122C6349DB27AB958504FDB4C527B223B2420DB7246A4A69B58085A3C1E6997DB19FE17A2BC23BCD60B924CC393EBFCA864DA054BA38BB733B00FDF57AB147B922278FB132C5F5774BFE368DC2B66583790D30D282A248B7E9D43A562BA1892A985B75A7AFF961762A05FB35B9420905BB8C4DE00A3846E38CA7D71411E89F9E2C9489C597834C7A5315080130648F5347639184F315BFF2D580FFD0227C9185ADF9203ED50BAA43A9174A7AE9B5655F2245A15C30F877BB7DCB2EC184138792738113895A980DCA31BAF6B5261E10A1D98AB660C066BCB05AC25429775C3BD1550D4A823FC96442CB2770751C812CE67613E48BFBE66A0FDBA909317513220EBC3C55FA1364F318812199009AF24F9F70C36F81B22B20BE53208F0DC44DD3B6ABB7236E1FD37C53FB1EE8C86810863A86B0029A58955DC73EC8A436112B5C3A75CEEC356BBD91355E4C3941A07E45AD3ECB9AE67E7527F70F6E07A757BD112947074D5120A1F2A1E965AC6995D525E324E8252D8E2C2DA909A29B24BACA8B68DAA5122CB539A474B9402BF02481CE4B27A52E87FEB92C4399C7F2988D40E942E7496AD15AD2AA88 +ct = 9D503732B866FD6CC6482F203FE35AECECBDD76BA5AF3887AF66020597E9ED58EEE4577F0A07623C03124574A8F263775C83DF468839D2E5F17D5B21E811E0A80B0CBFEA3E370762AC0C47E741C234B5A24E803A60C532B92B658D5E46244F96224B989E6EC2BE14FD13A384EF64977D370B06040AD74D11EF41D126BB07CBBB5CB3CC1BE087F8FD7F61B8B8935F515207A26EBDB29DCAD93ED2159926093097F402EB6A2D4DCC96B7F354D3B46C514CAD7230D0A03AE48FF492CEA84B35F5086A2BAB86E37BE1080950674FACDAE004CE59858E2A2D9DF1D83A3E8719D057848A081BC262559DE7F0D30FD2193788CABA528CD3145465F3F1703D1955F87A896F114213752F389170D6B9E3B45BC4D8CC25A09D35D8C182766A97419302ACB59B18959F68CBE30572CD507D32280B9B3DD03E08F7F912DCCDF6465541FC1776B76E884EA1A1F0B6E7B44326F1C984972AB1FD82D1A095D3F8703F26D15A8FDE507E99100FC4204322D4DAAF774CA4CE9A470D560AFD097745AAE98402B1E8E5C0485620F2996E4369EA9B7D91D66A29AB0E8980AB477E6732F267EFAB52F24D1D19119B82FB1FFE9DBF3D77A0CC9CE84729CCDCD5B27D4321B23B1E9FC40F443AD753C0B876507BBA1DD7755914FD861E3006504D7E406BD8FE652E226D3B21CB7510F570CD1EB1BFE43555886E29AE1389C0791ADBC762EFFCA02553D7026A3820DC6C0DE0808FCED176BC010B0B91DEDE1A6770833AFCFE359E4228D04920870E20DD9892D0A5340C93C2EE86115244A43635DB46D28AE4982C3CB8705C250026C3A18DA5DC2DE6320DC4A4E40962FF78AA98B1C17F2BD49495663282E019982423DB6388C972B4540D7F4C26FC3037356011C090EB5AED0706336AABF252B879799BDC529CF75D748413BC2A499354D0CA2E47957E3F032C1C9B6F398C80468A03CBE6E1857C1EC3E6C046BCCEB9D8417FD3E1C7BCCA9A0ADDCACDA0BCA99966994F6234380B5E58163AF74255D6A9FF8397493DD2987633A4A6C5BA61B00FF125C06A1615F993F660EB8CE966551586BB30794CCDEC762C67843A68A84EE658E629AED04191C8BCE6DBD7A112FFBC6A483AF6D0A3F297340E6E9EBDE6D73F39F4DEB96FE0326A8D25CA7335938F502BA77EC126D5A2CA584C838B2166AA0DD926F645F7B4570AFBBC7345F4FFAC34588B54776A35F24474FF2AE8BE60D7A31A415FA32F194875A0D2792DF994E054378BF15D8502F8E2887DACBA3FBC3FD17C7657DE1D099F4FFA8250CCC9C6EFF5C517B90B7C7035017732AA964A4A2941557391836624F8AFE0D5482143B009A633092829612E6024254F1EF8BBB15B5A6B3644C9142B148C4C7337EFDED7A5246674E2739E5823C785A16EF4254B97F86EC3EBBC28B4A1161A66CDC07D3FF5A3FD1DE52F00AC6EE6258821854943FC73B357B27FD154EAD141B187F3B8A7AF61C80D3F324C341F92DCF9F4962C6EB1AE5B0F0711FCCB3E5AEB439E8A7C8F20A580AE50C1EFB1F27923ABCC8F2DF1DF +ss = C5E2F0C1EE4F13FA8FBF2D09A78B04A5E2069AAFA978598F96424ACBCF41AD44 + +count = 55 +seed = 467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91 +generateEntropy = 2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +encapEntropyPreHash = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +pk = 8C5785417B65B2E4235CC67947D7B214627D326AC1ADEBCCC3A64017E004499A8887C4A649E443E74720F0B1BEDD52B1A8EB78B3AC2D5516B7A3233BE9448575209675F4A813120422684191D6771EF2B44D92B2CA3BCDD5F5AC20A63EFC237FF9D99BB4F5094AFC187EBBAD39B8B9CE75902190741640BABF653886162645A84262A24B1885C626403F23136707816ACF28950BF181742C98347022CD5941B7B69E21B5CFC2B4C6C5F301BD32A2E7882A1E1A9CD94743FC86AF0CD26B51B3512003CBE8628D299663DA40BAEF443677033DA8B8C21E0A0F12FB93F4D63809375FC877866394A1A5409E2F13B3E5011A2A5877732415281B7B19991E6EE0A470561B6BCB46D87B4086F18CA29C5FDCD622F4315DCFB11DB2C6CF136B7B0A870AE89669AD1011477899B8F679E5C9A8413959CA0CBFB3B54AD58C98B94760058C6F1F499435118D9143723DA05BA8F13E5CCA1813F91CE01092917BA1D798BA3481121026713BE1889B58375E5C4F9BB0BCC5FA808E2C00A36CA575C68B1D232778F71BF0927C5F2092D0629588826D02005DB9BC0DCE456E2B928EC9FB9C7A138E7B1065A2B660C287C3D062144CCA71E5C1294442073AD48AFC555767F1BEBAF550D520659496AF9237A22C27670A080F8A461778AA42C6CA9A954C28A658C73847A586FC3EF266562240ACB6978E026152B1149B8D426AEFE37BBD263A00DA05DF48375E53BACF9C4C11D4BBB055666AD008736B9C323A9974661215495E032AAEC611AF0E6A9244C2BFB6F3195D5121EDC3C0719C3FC1365C2BFC70D5C6140E6A383714A0931CCDFF946ADCF73993AA113C90AEF03374E251ACE73770A350428EC32A9DDB4AED8832526968412863966228644B9AF9842C2E967957F10D350A3499876F25D157BB2812501C8DC95365F83BC64B6340FA6CB4C2816B31824D028726DE0112AA9CCC9E0B6869099D310AA6E5B79609487E7A20A56BA75C45986F92F5A4D1672F3D99927A1193BA15BF5DF2586E823292593C49321BAC9044E4844A7A6BCB08309E2520B6ACF20E73BA5B05931E29BA43B2000A48C72A5DF05EF715CD8865CF16A835A83C271402071D1068A426839CA424CB666545664EA5E7461AF147B9D84583285EA1A05A02732031BB0BA40B14C828BB0E82807FC57882B31D9CF509BE7B712F56994721B55DA921EEE8AD45C8B4E99931C9B71B473A89A2D4821213A1ACFC453A41784D35B522E93C2D994D083674C71583782128476B04FEC71F17CCC65B9C83F52C207B08ADB10824A505B6DA8A78D4C599A5B09979D9491E1383EA155576730614FCBDEC1A8C801B94083A0FB55790B136BC5F37B752F3A6C636481DEBC5DA8892AC1B04AC7447953015E7251838ACBB6E24B508578B62D7450C46C76272806AC407112B73F7946D9654A45E943B406776E057C22E669B34A39D92F87928F8689CB8363B5B07B861BE5A750BEDB4A909605E6E26A489A5A4D9FA7BE3976479F8ABAB955200C479E75983BE821E79682FFB18553B72CF0797B2D2117ADD5AC0ABC71CF0E4CA83C26D218295AEC75872BA3A8B3CA22A2AB83404A046355FD394BF35D66DF46A6124D18B9A4606305A5968C4CCDF6B77A5EF23C5D54C68389E610B30DE122C2B2CDCEA30B3C780612FB9992721E26273 +sk = AB150A2298917B1707AF1AC0941ACC5B6B259D1AAE8F878BB0A37089B845991B203EE4C8F1A58CF9D2CC0059ADE2DB131BDC5FE3049E17F350A805C6F30479BE91B12A36190A5332ECA4737DF5A32FD60CCE222B592060ADD75A62F88D5BF6426FB18A944195F1ECB1BABAC1DCF20C39339ED45AC8C3AB582382480851107683102FA1914E753731964FDFF686F0A354703858C15C99F30A19D9C281AE93004C718D1CA5452FE58183D806DD666792DA7A76B0927DC77793396E4508200EF5097E45095A33AF5683A4DD1A5F6878C1E6FA85771A990EA16F7A28034A897855769DB8E4A9A425860FEC7031D09E96B665F57662B2BB86E362C3F9A706E354C12423AC6CDC74973A0767D73E75F5739747433C3451F8E5B85E5311B6E009F79C00CC07BA26B74D512520496B1998A4445C19249729225044CFFD51679B495511223417B2BAC86CC242241F2B70966E9A7A03C3CC0AB526ABF857DC1A140AD85825757D2B5A59B97B7F8C5015DA02159D013C1F15491FF4CF64C564E50C389F6C85B7C060F98011A4518CD3B48C2DF68C67F3497F439C11F8504E577CF49ACFAE704A2B093238520292602CC2138762D87536F6285C001D6975A242654DDECB5663AC44228BBE5BD58D9B90426C66802B466B21DC8D7A23893A953033874D0A93626C00B6A4FA3FE9EB0DFEBA2F3E789AAD8103CA153FBD7218B95547DE700CA526AED4F159639C59A7699296486188C3CA111479DDAA747F99AC825C7593911D6261683CE92EE8AABB77F82AB14838DB54149194B12791C4991181C66BCF05C67E19F05DCB658D8DFAB09C180967311F4E2AA03D9B8218889F87C5A5680299A7459AFDD69DB27302D9761DAA20BE37900B971694D3B6AEA8C6B5D53A686BEAA478F2ABC17C1C461807597148719925590C1E482AA05BB73077C017C1010EA576BFB5A63031875A23B0A019D608D64A30D0DCB39D750099D1C7583C34AB1CB1DD99A115547E3E4CCDF2A872E821B2330A5F6B30918226B7FCFC9FB4F37D8103437DB12EE073A49D29A7359316F8D922F783797E49B8C2B6146F76C7F8A66838C86364A788D3C4AE67D02CA09391E8547EDFE86CA1D131C5B96CAF479D9562688D1238C6196526B17844B475149AC3A76865C94993E518941A63A2E4559E81A46C8A99AFD2A73B36C633DDC6B32B14723F04A83AF89A420A3D04810311A28880247236A3761236B068A9A4EDF55317E8841218441EB1137342977215992BA99C1EEA7DBEA33AA83382B909BF1EAA9030B4386F8BAAEA643E41531204BC0DF8243F81367F4D979BF0125B84EB5D5DF53318463102938A85214AD7355960300DB40719A2ACAB9297381A6708391C78A8D4029487C324291A7E4A0945A806E0F24368C7A2AF91B8BB155D04C557759228673B548B6A4FEB8944B7334BCCBAB144C84344457B8B794A3D3B4DFC2357BE9227F9C4CE8B98003452C1D8D19C7A8332403A41308086346129D3F929B847BAB1AA5D88935D816A708C6A5E41023BCD4252569CBC724A53DF1B88909267A932186C751339863C8DD49CBE200797186924C26EDB976DE613CC2C46BEB06B39F5C264716A76E67831E4198822D77386592C777A088C5785417B65B2E4235CC67947D7B214627D326AC1ADEBCCC3A64017E004499A8887C4A649E443E74720F0B1BEDD52B1A8EB78B3AC2D5516B7A3233BE9448575209675F4A813120422684191D6771EF2B44D92B2CA3BCDD5F5AC20A63EFC237FF9D99BB4F5094AFC187EBBAD39B8B9CE75902190741640BABF653886162645A84262A24B1885C626403F23136707816ACF28950BF181742C98347022CD5941B7B69E21B5CFC2B4C6C5F301BD32A2E7882A1E1A9CD94743FC86AF0CD26B51B3512003CBE8628D299663DA40BAEF443677033DA8B8C21E0A0F12FB93F4D63809375FC877866394A1A5409E2F13B3E5011A2A5877732415281B7B19991E6EE0A470561B6BCB46D87B4086F18CA29C5FDCD622F4315DCFB11DB2C6CF136B7B0A870AE89669AD1011477899B8F679E5C9A8413959CA0CBFB3B54AD58C98B94760058C6F1F499435118D9143723DA05BA8F13E5CCA1813F91CE01092917BA1D798BA3481121026713BE1889B58375E5C4F9BB0BCC5FA808E2C00A36CA575C68B1D232778F71BF0927C5F2092D0629588826D02005DB9BC0DCE456E2B928EC9FB9C7A138E7B1065A2B660C287C3D062144CCA71E5C1294442073AD48AFC555767F1BEBAF550D520659496AF9237A22C27670A080F8A461778AA42C6CA9A954C28A658C73847A586FC3EF266562240ACB6978E026152B1149B8D426AEFE37BBD263A00DA05DF48375E53BACF9C4C11D4BBB055666AD008736B9C323A9974661215495E032AAEC611AF0E6A9244C2BFB6F3195D5121EDC3C0719C3FC1365C2BFC70D5C6140E6A383714A0931CCDFF946ADCF73993AA113C90AEF03374E251ACE73770A350428EC32A9DDB4AED8832526968412863966228644B9AF9842C2E967957F10D350A3499876F25D157BB2812501C8DC95365F83BC64B6340FA6CB4C2816B31824D028726DE0112AA9CCC9E0B6869099D310AA6E5B79609487E7A20A56BA75C45986F92F5A4D1672F3D99927A1193BA15BF5DF2586E823292593C49321BAC9044E4844A7A6BCB08309E2520B6ACF20E73BA5B05931E29BA43B2000A48C72A5DF05EF715CD8865CF16A835A83C271402071D1068A426839CA424CB666545664EA5E7461AF147B9D84583285EA1A05A02732031BB0BA40B14C828BB0E82807FC57882B31D9CF509BE7B712F56994721B55DA921EEE8AD45C8B4E99931C9B71B473A89A2D4821213A1ACFC453A41784D35B522E93C2D994D083674C71583782128476B04FEC71F17CCC65B9C83F52C207B08ADB10824A505B6DA8A78D4C599A5B09979D9491E1383EA155576730614FCBDEC1A8C801B94083A0FB55790B136BC5F37B752F3A6C636481DEBC5DA8892AC1B04AC7447953015E7251838ACBB6E24B508578B62D7450C46C76272806AC407112B73F7946D9654A45E943B406776E057C22E669B34A39D92F87928F8689CB8363B5B07B861BE5A750BEDB4A909605E6E26A489A5A4D9FA7BE3976479F8ABAB955200C479E75983BE821E79682FFB18553B72CF0797B2D2117ADD5AC0ABC71CF0E4CA83C26D218295AEC75872BA3A8B3CA22A2AB83404A046355FD394BF35D66DF46A6124D18B9A4606305A5968C4CCDF6B77A5EF23C5D54C68389E610B30DE122C2B2CDCEA30B3C780612FB9992721E26273A3D8A85F38CFDA38C66AE39B2F9186EF7BC1E0C98E8976A6CBC6C4875D73D7FB24C3DA70FE850E80AA818301D60C70F3038153866DCD5D179E22DB59B8991BB4 +ct = 05ED6A301313B34C67A40B05211E451869D148917D9CFEAA4144521DAFB1BC3CABE8FC527D998CDB6F1BA7A0609FA2144A3BD8DB8460612C8281586F4AEDA3F599CFFE70130A9C8BB5A91812B259167603B8282E96CA090EE6D83588980AE78ACD18324FACE44CBF68340002F1E0F6483DFCCFE092933D5A823F5ED4F06D38EE5747894CA0ED4A64438B1C6DB6DEA5D1A7DEED2A84F4622764FF3739924F3102912357F030CA7491D1A13F50B891294D3271D029E3402351D78479F253891D726B2C9AFB763E7A12BA3F150C54CEE377A91852B4C669A263D882D98896DDEDEEAEFE850159C3638408CA155BCC2D7D5579F156FCC2F7B77758AD4A5723AA45336054D810181E8BC9EAFB7ABD4349FA0F8A22B0E1418767E62EA6C84C2A7BC74E6E575DB8E6FB7EA79AB108C4985F3DC0424AF17B2BA1BA6C6AA2161D872DAA33B3C86D49CC6C0D5C8C07ED16FED4D2FD7F342B41D3F9B616766EC9CEFA0F1A2FC91CF84925243C344B02D6553B4F28D172ECA7A101B3A2EF6081A101DE8E95B1C32BC8B3327F24FF93C29DD66B9F508BA045339DE2C600469A73A65BD72CC348892AECFD3753F489566479AA7FF5390312081E24D9B64CBF8780D959DB66F9BFAA756EBD7CFAE55F991F81E586BDC74EF77A2FA3F3765905118F19443D3482EA18AC6BDA92A754CDC493E052D4482F57FB4ADDA00F9761F9DEED1B77FDE37FCBDFAD1CAE385BF05DE62880932DEAF957891FA11CD255E7C65619FD71B2641A085A5CD9FF4851FB57CCBDDCC10EDB41376032D6227ACF702B2E6265AC9AEE41A2C183EC16ABA9545E88988BB88EF7C0967E1164FA4F8B8943000CE8261420C53AF5A465F15BC6C76DFE8431439FA598D4EE11C3673EA9AB144893E4261454570702E6311392F79728C54DAB95D1329FD70D33E934FAF5FE220FCF9AACFC4D573798BB0D7DD218CEB8413629154745E6CED8A4A6EFEE1E93DCFB3F3BF3811513D5201F0B0A2C213E307767F989FBE19AAC74BAE70013B5D73905A709566356D4212B68349CFC4C7147F09CF0168AE636600BA31C87741AFE142D1CB03F56095DE4BB034991E54D863A9E56C6B9D1786D54A41C08BDBAE1596AADAD9118D3CC0B8121E25B0EB080A5E089EBCC32438A1DB1B72AD7D7B743A15118674F64992395316F426E365AE04DA9919E1A8FBD0959A2EA2A0938BFE7D2FBE844D89F36683E076F8E54E27AC5805128D0B58CDDC93793633FEDD427989AEF1463AF97643D628CC79DF9725C37F745839E85D9916D1C5337A16B47034FF2A36F3B022232BDC881577845CDC8A5621FC21AE5B5BF8EE0BB4E2ABDBBA1C348F2FD58313C9251B8E84FDEFE3915B8EA3CC13A5687AFFD790EBF25C7E761C90B1A0C7F6E9A3BBE04D6595B45D6FF3BA2D238D85ACF7206B0AE25B326E2191291510324A9FDBAED3BB5C770DB6F215DD693D4090BBF610F2208FDC7ADEC620D82F86CBB17DB7D31FB758A332D17E7FFAC763BFAC78B0F3C8A746BB60530A168FB5A06BC129F8F427BCC +ss = 0B642D9427CAAAB926DFC155993BCB41BFBFB91E6C6D1C4165D8750222CC3688 + +count = 56 +seed = 687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235 +generateEntropy = 63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +encapEntropyPreHash = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +pk = 605471FEAA9E92B94016A9A05F585F3C52A993A91A6DB73C9AE6364DD2A07B6C2AFB449122E76A3B273D424B94343B3BD7E7B1E1366204820819C8BA8970218A22262CA649D8E3223167BE77D9A466C860AD7C320B227E873A0D68FAAA441C0907805996D64F7759BDEED65CCE25B367F02094714BE404CA9FE56F6AD99E7D38B5396281314898036493002CB516878DB66AB19E09478872C0F76ABBE0F754B443B13DD5AFE610C1ADFC52FB3C82488984DBCC4D9850A0EE4BBC07D0051208C87914A3FA5159C775AD91A552C2FA2AC573787FFA68F456012AF600AF60183F97CB3E2936EF683FD8E2B5742C6DE946B96F825CD0F4807640A532561C70600D4995BF8D2CA543DB1EACD68D28B207617C23CD9A57BBF75ABCB620D941913E6506AA0123F89C261CE9C39C605646904D22586643F4AD250870AFE94DC950913602CC1CDBB77BB9B4DF518D1A18AB0C5A25948302C0535908E70F84587EFF169114161C3E646740893FAAF6B37B42168FDBC494549776D528BFA2C2BAF6A00A7498F403347A646C9A58328C59274AE8CFF8B82787A29D67336DADD3404FB5509640C29C9456FCF82D4ABBCD9899AB108A1FEF872617C5CA780970182861C046A594D62757D33247B79E12873493634C16FA70983C9B593814E69BB160120B4129370519327AC2332063992AF4370D9871E7A27D13420A6FB16ED9B579D1CA1D36A2094EAC96B537109AD83F4DF1A1D2E184C309AB65D75A3E409C57578214EA4035657757AB92AA930A76D251A1B87BC6B58F9D900E38156D73A1961C43BE2E044314C89EA9601937C0A87D9C4B14CB9E79D83E722CC40B048BEC5CCD038304AC0A65BF93B9A787105EB31B5BE8845C5C57B9A9CAF6243F54438ED84159F5B1B8B246073B1715B0F635E8078991118DFEE2CE08887F9680BD4E672D3AA78DF8954554D398D1675D785B85DD28A1675944D7597968F22855999F148CCEABFABC2358C315076C6B4333A82520A8332543AA100034BB0A6776CD959BCB263074FC28956726D0D99B9D81A7DEC14F13AC5CEB5B9EAAECB28E282BB517CAC09809073C3D085718D1DBBD75EC83707CC768BC79A3B637D0ACB34F37C9C2B4C0EEF3233CF91C0BF5A6A9279F6AD136808A9A3515B02E303F4DA26F93264C5AB9010A9C8550B9076D6471C196675EDB08223672C1A229AD31C05EBC4FAB557F46B4BB37DC2B605A87B888A1F475516DB87B92451127436EDA7922BB45B8B8462122542DE969C31622CDD62676A8FAAC5663A8BC2191711383EF4C1CD7A183BB55CC3C83B566E5514F233D79A2963710C5E5225F7B09B0B6176F451A7F77570B1C17B7BA335511BC3C3FEB884E459ADD3A594DD35662419272499B4E9258DC9ACA946CA80911999D455D06407CF9C69E814478A9F5151780BD754A440BC69925155FFF0A675E0C322C69174C27CD804279EBD3260FEB62C0E24EB63C7A042996C25BC9342C589C340E99999F9C5054FF35C760A43974096C5FD23BB9E51E2483722A132B0277BB24010297C4BA2C58BB286C49ED20B7AAE98C5D9B0601F06EE53C1808E07FDA53114EFC6D36B28B906611BE3A29E68A8DA76457BE5419D70059F7C329AAD28692D45892F335D02D36153217D5DB379B621E416A54CE8071DFDA35F639A04B14 +sk = F80C63DD6CBDA93B6CEE719FBAD6BDBE1A03F18B3379306ACE5625FB38C5EDAC9C8C94525C85961E14A76082BBD760CCF9B5AC777088B0CC80E0304FBCFC697CFB13DCF1CF777325EB473D11A43DA4575B697A860445B02CF75E8B945FF9433A337C754E19453D4BBFD2F07C76E8B7A68B92ABC870B56202F7634B9B37902D39BCA04653FAD9A0E4F0BE548ABB97C7A1FA18C34CEBBAE3987F4B3C52A5006629159AC6875276053908B389D931BC7E2871751169B6D81C8D8B5F52854A3E644C5C504675D688BA030E9E78A79E7788522516FFDA2EC9946AA9791A634B6AB6D04456003ACF348BDCD859567A74A7B73556820F8DFC12E467AE2FD11025E430114A5A60D3B42BB43845721637A69596EB953AB7B3E3B28B3BD9923DBC5189A37E9FE7BD9B763FA905314C0A35387A8E8552BF7135698E15B8D99B0777A0A5AF1B7DAFC172AA6A4D69202F10351603771876C580A7D24479DB0D804B6513A09281F291F2706AB128905663AECB0BB31A41046771449D12C335051A2EB50CA81ACE90940A8A6A355B21A9C7505491EA3B48B5323CC567EAD909FBDB380FD504C851452BD34F0F65A39AC62D922A3C50A8566EDAB03358745D701332E4011022BFD4839AE7B6745C66ACA80ABAB8213369E299253B40A7922DF02AB70F9723BACCB1AD563AD20C5EB8A01AE564BE24F40CE91A0F06EC68C0604C74250909D317F8968947A12EA297A279821F1B5377B02653D66897AA526CF51553C268481F7174BD9495DA4B0305650358A637A5FC31C99BA7BA304C6811B555E4B1C2F80EB4223C54032D16238861FB650BCBA24B127026FBA51F5985476103FE1375B94007A06BC2AB048BCB4A78E6D3C748B141BE410992733630B8C917F89960273740A595071824A9D02908D52D334373E8A575D5D52E96E5AD0CC95BF2C761AE577B9EF6BEAD33103E5033E0765D748C409F8A44227B8F55838B38695C5E132F2CB9BFDD7CB8522906E9BC03DDA468A04012277417869277E2169C63112E6A8942A1C13AEE97300FF4CAABF862058B6E7CC16F34C79BA200853701A98D630936A8A595098C8B19820AC91F47451E011069AA688BFBF5AC4EE018C53639A1B0573C8A420C4619166B011E79BD0B843D97766810A48E55D5CE389B5DE4A739F77CCC5FB70D52B3CA5D01729935BF7E4BB984576F2ACB7466C8248F975BAD539B2260568DFA34CF2974D83699761C95405943A7A88374112F8AE79B4D244BF2D683F7CC7A533229BBD8B5E822C8B3449548634FF34BCAEFF25A41AA84A1FA1F52F486F89630A7730E4F81AD23C14D6906816A849810951727042ED0782EF26C31281C0AADE6C9334A88ACB917B781C4F16327196422C24541065B5E80F4374DA0853D478625A68F728A20C1C82CA4FCC4D62744FA658059141221A917D6121187D3B621179AA8F7B7CD0904E6E0787F9A5F65EAA78011B6B63290A55542C80A4BFAD64677467DD1B12785E6BFBC31C1F3D46DB55C0A035604EF658279DB3232C675BC0BC97717CA3EB71D4F44CAAF1B07BDDC90AE982886594F98C41AE7481562CB63D0B2539EEC589146735490A4A87B6EC5CC77BFC0810627AA3452CB061A1648EC7CBB4937605471FEAA9E92B94016A9A05F585F3C52A993A91A6DB73C9AE6364DD2A07B6C2AFB449122E76A3B273D424B94343B3BD7E7B1E1366204820819C8BA8970218A22262CA649D8E3223167BE77D9A466C860AD7C320B227E873A0D68FAAA441C0907805996D64F7759BDEED65CCE25B367F02094714BE404CA9FE56F6AD99E7D38B5396281314898036493002CB516878DB66AB19E09478872C0F76ABBE0F754B443B13DD5AFE610C1ADFC52FB3C82488984DBCC4D9850A0EE4BBC07D0051208C87914A3FA5159C775AD91A552C2FA2AC573787FFA68F456012AF600AF60183F97CB3E2936EF683FD8E2B5742C6DE946B96F825CD0F4807640A532561C70600D4995BF8D2CA543DB1EACD68D28B207617C23CD9A57BBF75ABCB620D941913E6506AA0123F89C261CE9C39C605646904D22586643F4AD250870AFE94DC950913602CC1CDBB77BB9B4DF518D1A18AB0C5A25948302C0535908E70F84587EFF169114161C3E646740893FAAF6B37B42168FDBC494549776D528BFA2C2BAF6A00A7498F403347A646C9A58328C59274AE8CFF8B82787A29D67336DADD3404FB5509640C29C9456FCF82D4ABBCD9899AB108A1FEF872617C5CA780970182861C046A594D62757D33247B79E12873493634C16FA70983C9B593814E69BB160120B4129370519327AC2332063992AF4370D9871E7A27D13420A6FB16ED9B579D1CA1D36A2094EAC96B537109AD83F4DF1A1D2E184C309AB65D75A3E409C57578214EA4035657757AB92AA930A76D251A1B87BC6B58F9D900E38156D73A1961C43BE2E044314C89EA9601937C0A87D9C4B14CB9E79D83E722CC40B048BEC5CCD038304AC0A65BF93B9A787105EB31B5BE8845C5C57B9A9CAF6243F54438ED84159F5B1B8B246073B1715B0F635E8078991118DFEE2CE08887F9680BD4E672D3AA78DF8954554D398D1675D785B85DD28A1675944D7597968F22855999F148CCEABFABC2358C315076C6B4333A82520A8332543AA100034BB0A6776CD959BCB263074FC28956726D0D99B9D81A7DEC14F13AC5CEB5B9EAAECB28E282BB517CAC09809073C3D085718D1DBBD75EC83707CC768BC79A3B637D0ACB34F37C9C2B4C0EEF3233CF91C0BF5A6A9279F6AD136808A9A3515B02E303F4DA26F93264C5AB9010A9C8550B9076D6471C196675EDB08223672C1A229AD31C05EBC4FAB557F46B4BB37DC2B605A87B888A1F475516DB87B92451127436EDA7922BB45B8B8462122542DE969C31622CDD62676A8FAAC5663A8BC2191711383EF4C1CD7A183BB55CC3C83B566E5514F233D79A2963710C5E5225F7B09B0B6176F451A7F77570B1C17B7BA335511BC3C3FEB884E459ADD3A594DD35662419272499B4E9258DC9ACA946CA80911999D455D06407CF9C69E814478A9F5151780BD754A440BC69925155FFF0A675E0C322C69174C27CD804279EBD3260FEB62C0E24EB63C7A042996C25BC9342C589C340E99999F9C5054FF35C760A43974096C5FD23BB9E51E2483722A132B0277BB24010297C4BA2C58BB286C49ED20B7AAE98C5D9B0601F06EE53C1808E07FDA53114EFC6D36B28B906611BE3A29E68A8DA76457BE5419D70059F7C329AAD28692D45892F335D02D36153217D5DB379B621E416A54CE8071DFDA35F639A04B14AA73B40DEDD61E6FDAAC86971965C03AB14AE69E8130426FDF830BD57D0974CE3AFDB8A246A56EE71465591831C371F2EB87467B0559DEDD776BA063EE6D2F93 +ct = 909F5615AFD3C1E5BD517378A979CF9A4267592AE7A8A723314DCD337E5296E07C686EA98FB8FF29067C99D0C8214DF3E1A4A3CD694DD8F53F9B1ECEEFFC203A6BF9E7022ADD6374B08B0C009A0F2B57CB55221FD486E4787ECB8CDE273E980C25B831CE8504E9125B4C402F826EE5F4E2965FBA01771978EDACA1B9AE19E0E302CD019AFFA2FE3714B7C136FE5D3B6F9D7E6622493942323B33DE56202A94D4CF505DF02AF304CB7339460A2DA004D783024AEDE73BEEE0C388816B90B36449F84FB145D99FBED6D46A1B57369F2F1AF1B4887E5AD0B318B527E25F81B0A847188D0BCF722482B90B1E96B114CD0274C8D00401B0A39B29E4C6B07979199A547A27D9EC39DDC7B29FF2D7033CAF8463658113451FC604C0A01656A2968871E153D77D6A1C328EF92ABD4EEE745A3C58D518A0AF004F2C636E2F0BB636436B0517D6F8D6A4323727518B720F55D993E2C9E1653DB50A43F10C4A69FEE9B170C98DA672C1B21A9987E0A231AED4241114D605555955A4FFA66314853FE8E1E4306ADDDF09BFFF1F22EDD64448A2F59ADD8237A759C2B5112DC3AD69404C65C2CA5F97345B492F0100882C83CF33F15E6DC2459976FF8870507865F9616AF8F0AEEE21FC008C9EED3565100F7443A731A5D6392F0D5E88AFC84D6A3F3C3274187A39BEDEE638E5C56E9A1A17047303DB8920A77F17B322C9573FE0096CE446ED1457CEE4FB2BA448D9A9BD690D89C58E47816B08995A36ED6C1A965B4C78CC5D7E90D5EE1CF5FFFDD6874B6B2ABCE7EA3ADA69BEE4CCF3892E8DCC8538CAD74FCED9DC8AA13B976E891ACB8EDA3700BBA39091E4FCB25EBE17F011D392E54B98AB4743FB7DDCAF0840CA05E8691E1C6FF4F46B45663DE89F4BC9B4ABDA850563336C0B82FAD2815D879131F58C4C5850B98AB57EB36A4A3E540E80F7115186754F93719794FD73D7236059A4DBE8169C71F01DD7C4FA1E6E3B3E80E5551C29C428996169E863CA1EC09189138588FE85B759D75C6FAD53746F5B6A6CCD6C2A970D1860FCC12998A7E9CA3DE51050F3B9CEF4A303F80591683CA7FA17909099EB288BE46819EC8E93C54BAB05B67854D7A105AFA20E62DAD71C90924A7FE13C5B0FFCB47DE697B9CCF4F33ABEB151E63A02B1835AD4FB5D4D0D858CD9F0A857801A6AA316076A4ACBB4ADE6F55DEC9B9F77D1633CCB4B391A4F879336AF32C7B54D45DA9683BBD83AE8D8E1A87BAA2E98D1D5C8ACB8418A2BEF076B9C35C45B97B7E5EE24BEE56FEF50D7FE9F30449440EEA673D96F3DEF3FAD0009054C7F4B1F36FEE689BFE6907453F2D08830D7524E311ABA74DB389DF58EDFB4F3715C880779352388ED09E5378760C42105F023574CF146E6A88FD7CD42660DE906BC57DC7F49F6691378FB8575C637979D445E2E74D36961FE0BC675A84E638F8AC4CBB0B85F365B3A73EFA97A4BBBA437A6FFCFF21B50226741F19400751B5B47C1657A259B427FB44FEBE3442123FAEE30EB71EEEBDBDAA798FF7D4DF03B2E5F08B1F248 +ss = 79462708F754BF842716F900E850C228B00996B0E3801B43F6A928BFD4AA9E50 + +count = 57 +seed = 4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3 +generateEntropy = 6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +encapEntropyPreHash = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +pk = 5B668AE6721C79E07EE5D26233936D195B62B192058CFBCB0A5A73EA0154D78224EBE84B7B611CED7256D0726492A4B41D4A8D6B2CA73A3668F93A77294439B0D8CA9A725C5278C21D896CA5D706E5F03D71526CB175ADE2606E3C3A24D510B4D9816AA6846A77663A80F5AC0D364747307068DA942B15CD2E02A3EED2818F9056D697897B509BD5048B178240C841580BBB77A79423996072F39497869007B19442F401009BA1A039C18F191CCA42F9551713CD791C9FB847690CF6247BB752A17A9873E97BCC36B793B6AD827ACF418543054698D77693F9C38C84354CC81C7A3B6A43ACCCC32DA070FE29411F17A420521FC69C0D09A6425A20AFFC98681568B8CCEA88E54B8DD9F12AEF4B3C10F256EB1519671091984A1DBE972A901BB4B24246D7DB01B86665374BB6CB841B3CDB2593BA5C96E32C20936ECBC4ABFD24AF76158B36A2C752A9BBA8946B34C414EEDB355A3CCB87431221AA2E936B0BD7540E697142DA0817B1B51314FC71CF4017F50544474C572C70BD142C676B69AFBA4292F5F19E88163F2FFBA3B1685073C3BBCAC825B095B5D259228A459FA7E866E09735E4CAB8FA733D4DB6A98172846397883394059C635D23C09FBEE3CAB350B9976C6A8A900C8E1693C3704E779049CD1221CE767651BC23755A3A49C6BE0C314A8C501579F7A447070EFFE0314FA3687AB92090738434E55280A42F22A66EAB77A2932B07E6857A32E31A527A2A909865E053A32148B59CBAC224C12468E444916CA375DC204C600899F90BA7C854B3646F2AF3981797AFC4E261C7A93AABC40A93990DABC82564336D01B2447FD35E8E86A0CBF676CFE6C3D229B256E585D8373D26C3AD66161890325533818F845301D9311BC8035714A722ED9206967123E65410562A745FE28F90D50D772A9CDED6354132688DDB1AE6956EADD896CFAA71C44AA925FB3B2C6B7D5E47CBAE00A91040456F4023174C73DD8A4D50F9714AD1CFF718321677A6962587BA6CA82C341F02A7382BE9715B41994DB91E6D0B487207B9B660793E62470B806A7444B6FAAB38F48747484062FF443AE1DA9E7EF41F797398F0527406787E00E197AC3248EE4A0E5037CF6C754AB9A24D08936E9D3313B99AC18886CFA9972030F1A40E58B25939A21698C434391785A3A98F0445567A9DBC0B4284D49652BB1862BB76FCFC6ABE60831CAC9AEF6469464319411A30F7601B5358568B014E67A76EA42ACACD7C3FC2F983BCE1BC0667897B92590DC724B5284FECF7C36B3842C61C27AF1A2F2EC95899591E707272BEA384CB9C8C9409BB26D743FAF196D3B8B33119A379D5CBF6823D4176CA83BA4E2A426745F346A42861A7B5343AD3AC26EA8895F24A379C449156123ED91A4CA701BD789DA84BA0ED5C707D373634AB7A65680667191F806B6F62CACB4B40AFDD649CC9D1650C3A5E40C8346C91B27EC1B1A957C778EC9C968C670FC84645FC07881C54946B5AB0B6033F45AFCC6A61FBB99746F3991F5B827C22972939C5FF620BDC4B131EB393D108C56556719ABBB978452FF0A12A1D138C9065C304C8514658193232C832B05B0B21A10483C6FAAB378C6B1415B75B43796F314542B9D7C87C1CA5FC13A12E8459454D36096C3BA38E979A3D4C852032429BFE1E663E0C256C2E93 +sk = D809438C90AEA78B897A528534FB009D716DE8D513D32168A1537489E52255D00F49C424BF5B5DB0E15A3A9B9845ECCF287776F9700FF5BB7AB9F40FFEAB7F148A9633546846B672CDA9AB8A37C8F9711B76474E7975AB7E16675A8626F8648B605066A4FB4A5C255A0A39387B03BB7F618C9ED1B37E488D4B7175B593860F6C97D637A2D8761D3B933291B2CCFA6BACC4DCC4DDBCA804C7C55EDB9FC5ABB503036059DA4D2929447CAB1BB1CB746AB01293A2B2F2638BEB06030D476BCD2C335DD5226B7450F8B5B2B130332DC9210640C10DAA5FAAC16C1381C2A0C4AAE3174BE4FAA53CA9CBF29769084715D6F8C163A0185030B0C7C9621336A9875946FBB73BDA9774C07615711451F5594A44313878204C291AB7550AAF981409D4D7CBEE727BA689400DAB7382605F03873F38566421A354B59A3B48BC8F62A09519D932AF5800A9A0C6EFD5783BD93483A0AAAC7853C890C3BA18835D1A2E8F14BD0768CC7D0B951909825C988648F797F5711FBC654380E661BBC41CF89B088E1410F19669AEF65FD817564A4A4F40281B5E16A69BE2B503495A4B6B680A08A54FE0B80AE668041AA120C7A363E38AAF2156CEE293BFD4396DCC503646ACB74B9460142E4476807C058D72C9610E3CBB50A29ED7244419C2C258659B3A8A23E7E69A3047298378424B7A12DF3CCE34F1364732B292B105EEE6A487126815BC0013D66FB7099EFD4931E4301D570BCF2FACBA0B433B9A03147242C298052650416651DB690CE81C268381032B17C429A8E418B7E2BB63D30B570DA588CBC36DC3798C65F81EF05530B9043310E182E88BB3E58356DE408898738C9B3C457FACA42B9B81ED7C4118869D5153338EF4260006C6BE294B528C779BD6C8FFCB16E2AAB439D3032B8AC45216282346200CF1C812033A4F9667AF842481D807F92245BB322E04343971A656087CCA8CE9BD3117013AE816BA745888A4AD51A167A17482EE5B88B0BBA455A565B1D97BD3B9BEEAEAC0B4F2879A727028D4A1C61900D0770F15451A01964366D8A6AD1B5BC520392D43BCA270CCF9A72DF3D68B955C4BED0352B3F78151C4716512097BC92F2CF0A2560923D01358AB1B5F8B7BC687F5C110B04C6512372F119FB23BB852398A6F599F4D145A8AFABAF8AC8726ABAEE569C4579B494A01C67E232B93080D5DF1542DD59F21760A24747E98E26466280C04D1784D9B581B4CABCAC1C3DDE1CA8E00588E0732F76B99EC844032D99EF65C8A9EF4A661E78A47B0542B3129E850647862132C208CB9B3986EB5B510EA1854300EE966B0D3BC09922260FFC96B894A181A95A41F1BB3ACB2572475B3FE8933FE3902C965678B95512289CFBAC30A2B159B8F2B3535E40881D81C204CBA9080B9A7B23190965EB660754368955C0C7929E9447B92AC78E7867C1B4770596047FA820C03A11CAA3C2BA48120E29AD46C289920222C511C9E18343AB20067F926435C6D6B040955F9394601B805E38A751BC8A1853FC05857EAE658A8A7CAD729373E73253E7728FDCA89E347BBFC48A7BAFA48CB167111367F40C93BF71CCF208A891C383BA3B593F2663148D779ED82B23F4B6796209D51425E9168CB22224F39F0695B668AE6721C79E07EE5D26233936D195B62B192058CFBCB0A5A73EA0154D78224EBE84B7B611CED7256D0726492A4B41D4A8D6B2CA73A3668F93A77294439B0D8CA9A725C5278C21D896CA5D706E5F03D71526CB175ADE2606E3C3A24D510B4D9816AA6846A77663A80F5AC0D364747307068DA942B15CD2E02A3EED2818F9056D697897B509BD5048B178240C841580BBB77A79423996072F39497869007B19442F401009BA1A039C18F191CCA42F9551713CD791C9FB847690CF6247BB752A17A9873E97BCC36B793B6AD827ACF418543054698D77693F9C38C84354CC81C7A3B6A43ACCCC32DA070FE29411F17A420521FC69C0D09A6425A20AFFC98681568B8CCEA88E54B8DD9F12AEF4B3C10F256EB1519671091984A1DBE972A901BB4B24246D7DB01B86665374BB6CB841B3CDB2593BA5C96E32C20936ECBC4ABFD24AF76158B36A2C752A9BBA8946B34C414EEDB355A3CCB87431221AA2E936B0BD7540E697142DA0817B1B51314FC71CF4017F50544474C572C70BD142C676B69AFBA4292F5F19E88163F2FFBA3B1685073C3BBCAC825B095B5D259228A459FA7E866E09735E4CAB8FA733D4DB6A98172846397883394059C635D23C09FBEE3CAB350B9976C6A8A900C8E1693C3704E779049CD1221CE767651BC23755A3A49C6BE0C314A8C501579F7A447070EFFE0314FA3687AB92090738434E55280A42F22A66EAB77A2932B07E6857A32E31A527A2A909865E053A32148B59CBAC224C12468E444916CA375DC204C600899F90BA7C854B3646F2AF3981797AFC4E261C7A93AABC40A93990DABC82564336D01B2447FD35E8E86A0CBF676CFE6C3D229B256E585D8373D26C3AD66161890325533818F845301D9311BC8035714A722ED9206967123E65410562A745FE28F90D50D772A9CDED6354132688DDB1AE6956EADD896CFAA71C44AA925FB3B2C6B7D5E47CBAE00A91040456F4023174C73DD8A4D50F9714AD1CFF718321677A6962587BA6CA82C341F02A7382BE9715B41994DB91E6D0B487207B9B660793E62470B806A7444B6FAAB38F48747484062FF443AE1DA9E7EF41F797398F0527406787E00E197AC3248EE4A0E5037CF6C754AB9A24D08936E9D3313B99AC18886CFA9972030F1A40E58B25939A21698C434391785A3A98F0445567A9DBC0B4284D49652BB1862BB76FCFC6ABE60831CAC9AEF6469464319411A30F7601B5358568B014E67A76EA42ACACD7C3FC2F983BCE1BC0667897B92590DC724B5284FECF7C36B3842C61C27AF1A2F2EC95899591E707272BEA384CB9C8C9409BB26D743FAF196D3B8B33119A379D5CBF6823D4176CA83BA4E2A426745F346A42861A7B5343AD3AC26EA8895F24A379C449156123ED91A4CA701BD789DA84BA0ED5C707D373634AB7A65680667191F806B6F62CACB4B40AFDD649CC9D1650C3A5E40C8346C91B27EC1B1A957C778EC9C968C670FC84645FC07881C54946B5AB0B6033F45AFCC6A61FBB99746F3991F5B827C22972939C5FF620BDC4B131EB393D108C56556719ABBB978452FF0A12A1D138C9065C304C8514658193232C832B05B0B21A10483C6FAAB378C6B1415B75B43796F314542B9D7C87C1CA5FC13A12E8459454D36096C3BA38E979A3D4C852032429BFE1E663E0C256C2E93CF754F2EE43694865A09CA7BEB0DEDA9B1328FD0ABDF30CA5C338E27E8BE04B5230E05B7114FF0395CC6634DB1EAE8258072D09C09F291E92D6620B177DC50D7 +ct = 78E7B98228BFDF95F03288762317F3EB2AD2750F51D4078A9FD1F14F002AC59489B6EA1AD30D86EC7AD46296F8D0C69DB4AC9970137901A93F02377F7AF74746C5620A853BDBEB7D706C9B743A78F5AC0F80DD34EA8CC9737EC8DB9B1DA502F14BA2D578EA6836AD314DB2A07133D7C0F80E3A3BD196361CE8E8F24884DD9F602F894656FB68520BA493D064F93F48A9D4D219C8312B9476859A462CB15961F0B045CCEEB860CEF99D4496ABAB16A5FFFC21483E9FDAA826AA9B960F395E8AE4C433E69D10C2687BC17005BEFD809FFCC76070634BF58DC37CCB9806F530EF6ADA63CA422A35CA1349A74A5D0EBDE8036A0801F3F61E838242189D9CB1A8725BE3B93E07AC509CACE9A58426D9CC6D084BEEFF08D8FD3F1020ED2E0A3C0BB7E380049C76B4C8D18F8BA2309A813CF36F247006C247C6A418FE9F070703B80FBCD2AD45DDB3F9707C4F685736C680376D622F79644C2B4EAC7858B960C954C7F1772E708CEDA6812ADB59A6A9A277337C44D0A3156327FED348976D07B500EF61046D2B881B3882AB2358EF741EDD947D72A0EB26C19912DE1D2C77B6F523D277AB762585BDB095162ACA9FD027BBE2BCBB6C4C57EC0B01194363FE086048FCA61489AF4E9A06D8367B28EB465A9F8BF986C207B26BB9EDE3200D6F407DC957A0CE7866882E83CD89AF5702F38FBDC974EDAB62F24BF50C53037437260659EA579348950652F93162BF1A9BCDBB72E44D04B4B3C3975588922EAFF1569837704CC6BB60404E589BB0E1CDBB79E503D0F946186FD35B4E0A294E2CEFDE2C0DCB2B2383348F899176FA5B620B941C68805B52959D0571EC26B9DBDD75F0895561396B3ED20BAA07B7D20D0DEF905B805DBF334601BEB359B93E9D30C56D91AD58CD93193D7DB67DEDDEB02D05B64B23F765368524CDFD40F8F59DFD5CA7280A03E0DA103DB6976331514B965F1D71861A846A59CFF73865BFE35690AE34BA8978876C809BDBADE6726E4ABA2447DF9F0399A06844B1CCA43728EDD3FA348B34B7F15DE627550B1392DD3E0996EE3D8B7351D6A5601C796C4FA317641100ECC8EA2BC8827B6B88344FB5EB4AECC3F24B78FFDCD278DC5D5C7566031DA41BF4B4AF39D11F5355DF82FA68986FF0E84E931B520F600030495E6DDB4AC02F3DFEA6F182FB1332C5F6180D476501118D32A79217A9FDC3CA8DBF3B942158A0CD42C44A426A03101E444CC84DAED5CB8A17DA4E84F56F2C0B9A665E4C144994D982595A22D7E4F1F1E1937E8B0B4C70959621E0EE3F92FEA44FF164B6F7DDBA625C97152494834E604526B8CAF76F995B18F9AFB0BD263ADA10751F45DF9FF83FDF1A64ABF7874EE144E225E39EB4A22179622E7D45DF70BC61237D35BA64E11468C408BEBA085EFE12ADED232044F4BE8EBBC019512EAE687ADA59B8ED47ED82D2B593C46080A75D2B9DD5BD6A612C7C1AF0D76A231DF4D3BAD49F09EF01A38652DC84FF60F3E6F22B471113BDC51DD5C33B73CC65AC2C701F4CBDDBA9B361680FBBD0B4 +ss = BF535EEBD3721E4D832FA4C11369808A154FAED4602220B4070B78900B008358 + +count = 58 +seed = BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE +generateEntropy = 6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +encapEntropyPreHash = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +pk = 98CCA518437873F144E7E261E8465B3720582CF7706D684F84E618E8834F35857D4A8BBC303134B5E235DD1B2387A81C663876C5530293F99571B97AE5A299DF0C012E9662947089C9F81687722FBDC30CE50689690B30932A8A3CE7BCF6A353BF988DD310A2C347BFE6B30999E69C455B9F472B9BCA0216C84265E5D9486F6A7F1F3125C16467AE41B9F85180497B255ADB06A406A13A221388E14C0DE8CF73B6A952C2B2501644831C3700B7C273B7A3180A7641621F33B41C0F9255EFEC1025FC46F658C64FC89352C54C264B97E5A91C2386CD3790605127740DA2076EAB4876E128F3746843205B8328CFCDC65FEB92C2D973BBBFC68FD7A46DB51641B7830E73589F41D413FB571C37685DFF142863078ACF00043395BFAB3589B0CB435981B84E54318AB46E398389B8E146CAB2A9666330EC4C90A652A0F036951519880A45BF5D000D4E40C6B6554CD222880D0B91B67153C43909EB2C0926354D436C2318C593F9FC214B548E17245C0C9B83174A6783508B97AC6A8D8A88ECD278E2E52C3C9138B1685DABBA2BB1425075B298CB9120E790AFDCB9792C88698CC156CA5A789474992F470B1D554514823E87BCAE52CCC872C951B0C24B4A2B0460F488EE7768D56B07DC79B3B4CC321E5878AC0A5C3146AAEB6CA123206B0C7B5AA6E0BEC5D0A903AC9415DA345AF199CAB86BA99234C9526E6E8812F6DA8001F31337B8498A8374AE527B6032A0CF3142D1D34181A5AFD6AA432A588AE1F644F5A100FA593F0ED2753F441AE5677484738FF694ABCEC58781B06D0213579F827FB4F97B3FC343A445BA3035AEE989685E7B20BE6103FD39AFABC334417379BD666181925ED369680B851A54C41B6546B9C04CA69742B2A814763674ABC9CBCB03E96F9466CBEAEC698CB5C9ACF814E90887F8D15BEE556B28F50B739185EB7A5A06E896ED0048BBD905E016436477A68EBBAB1E172928AC8FA9A8B0A0D999B135A753A29A47D0136865B0F382572B0697D0FCCADC8A77C1B591BD73B639E13F9C21B6F0969B0ABA3EA807303377AFE0F49421B68D0712823FC448FA9A468FA000D5964BCF9A9E7FC92DECE03BF6732A36935B25023B47FC94C15795DD983BB4531E935A19778305D0E8A75C2CC770EB46B6D5759DF503BAC33F0669C775729C59EB94D48223D763880E8B58473683CEE48E309380F7B442E6C83F0EB9BBB0B1AE805B1498471AC1149D578B454041AAA2F5CF13390F10A72DF3385C6A8A1F990BB946F4C888E585069B5849882788A1BE27DA0725276FF9DB130519050B74CFF69A68534222499CC61F5845A8FC0AC5629E0CDA20D3EA2F0046B78A2267FA0187F15721EC53083018772097892BE85C1BE99480247E6E30AAC8FA2C593C630B981E57515E0F7414CFA8B606D931280A950E567C93B319FD23CA1B682FC0B960DD309F80455CABBBC71979C59A025008462C0681465D748FF2A6AE24E86C79922E2845568CEB5063FCB81B78295B93A80B221AE7E14A9A9BB7182C1ACF347F2FA73784835F3375A29ED05E4BD120A119CD0FDA29F76A1EB873AA88D0CB3C661FF0D5652F2B4604E2BDB1497486687F17B8CE7A096A59E0922260AE99BB7412E306CC0B25940FFDDF25214EE4DD4E1AEB851878E2493C05E2BD5A30B5B99D369454 +sk = BA45541CE7B3DE134E6B17030710BCCE09BCDBA837F23566DBF1928C99CFFCB674CAB9C41B3151FAA3078177B9126C7973E25687452DA075965BAA804276859B092D9D4095B5E3A27943776DA65262511F62A3AA875B258C7929B502AD6CBA00E3B38011C943310BB5CB24791A71BC5A2796D6197192D9594936089D88BFE976058CA16C152193838A3D7306B312F8160DF15288F9063514A403ACB76BE298F5C92D65A90A0BCB28A4F438EA447A9C881808A18A2F5C3C1B876B3AE94ED28478FDDC1E98A64FD797A0931CC4A18777E5D481D9E92C0CF2B5F5A58635B368CBC8C25DC733550774C0861795939B74E83A23757C212927805663DE14A0FA00CF10F51850DBB4CDD7CAABD5C09B2818CC0A09A58169E3827969518E8FC7BC8325B45656861A848347A358EF1155E5D43F7910A738A132C8892977075C9A19C1EB6399F2E7BF1DBAB593A907BDA509EF5B0DE35A222FC951A0829A838591A0441294C35CA0B86BE6FC02E1EA1B7D4004E5BCBCAA2A280EF37067D72790BB5D59587E050272DDF8B117286FE80C1BBF078E6D259A9B53BD6FF1B43A86B24ADB27BBFA3546C179B8F295726AB768BC7FC8DC2A62715030D93581165F1E4A03D42374A31039D55741C9C49A1C807468CC826F0380B90C9C3F319CF1F73811D674B05C147BB2613BA56365EA04872B9244B236B0D480DD0B47B7797A23286269F97450E13791B205C8AA3310B72F3423B263D93CA320AE1FF04FE6E3BB703A6C4FC17DCFB6341AEB485576B53D1CAB71D9049DCC68CF86008BDB6152994E70152F96C8AE4A0819102BA5077B26086B2DC6B04B324A31AECCB372CC18976BB9DA42C8EBA89640149ACC544511546C5DD293C3173EF28CA92B85B86188BC6FC09E2725307A2C3802C6086F922CDDC62B5989C5A6846496D2BCBF7775A4B3737EE6C6B69CC3373C96E79675CBC781146C7A78824AAE4322E1A69DBF64336EFC3348E414ECAB04010B9F7399310253679B48AF3C23961BF345B35172C1D472F9A31274C730373A29154A581631A0916A21259A46EFA387B36CC9272B5284085709E46F07BABFCC835959D841B3647F51147A013987DD9556111435124101E5D42FF0848BFE2169A49485C094226EC6994CB50BA9F6476FB2A39522A08145B987593F2FE67A2B2CCB036C4E6540145758C6745A389955CE9744CB8030BD85A838A5904198B318A4D265EEA61C70E5A34156BA00A53F05C9BE7F1AC214F6A75DC8154EECCEC7CA6218B34B8E063231C450EA3A8B48F7C97D9C58FED709C350A28A34873CE76F0FC7A4237AAEA0804E2D3874D726AEC41C3AC8E02706DA459C01736B7A5E0936B3ABCCBEBF146350EA2A246C225BA897473817F28C8D6BBB55FE98A48DE682A91770EDB1BDB190A0EFD677A7FC29FC62690668924CB5887F4078179AADE85C0DC8E3529862B2760B187B7778A56C6B026769E339ACA5F8C948801FDDC4ACC3BCC7FF548DD9FC12CD7A394C24A7CBE18D3D22AE3B48BEB295905B217AF384393705107F33B02547822B0A2CB1B57B6FC637E071C0FDBA2F87F010D0C81C42DB454F5C7BE69AC0069C33330BC40532248FD0B90A28908F7471FBCC543FA94403818698CCA518437873F144E7E261E8465B3720582CF7706D684F84E618E8834F35857D4A8BBC303134B5E235DD1B2387A81C663876C5530293F99571B97AE5A299DF0C012E9662947089C9F81687722FBDC30CE50689690B30932A8A3CE7BCF6A353BF988DD310A2C347BFE6B30999E69C455B9F472B9BCA0216C84265E5D9486F6A7F1F3125C16467AE41B9F85180497B255ADB06A406A13A221388E14C0DE8CF73B6A952C2B2501644831C3700B7C273B7A3180A7641621F33B41C0F9255EFEC1025FC46F658C64FC89352C54C264B97E5A91C2386CD3790605127740DA2076EAB4876E128F3746843205B8328CFCDC65FEB92C2D973BBBFC68FD7A46DB51641B7830E73589F41D413FB571C37685DFF142863078ACF00043395BFAB3589B0CB435981B84E54318AB46E398389B8E146CAB2A9666330EC4C90A652A0F036951519880A45BF5D000D4E40C6B6554CD222880D0B91B67153C43909EB2C0926354D436C2318C593F9FC214B548E17245C0C9B83174A6783508B97AC6A8D8A88ECD278E2E52C3C9138B1685DABBA2BB1425075B298CB9120E790AFDCB9792C88698CC156CA5A789474992F470B1D554514823E87BCAE52CCC872C951B0C24B4A2B0460F488EE7768D56B07DC79B3B4CC321E5878AC0A5C3146AAEB6CA123206B0C7B5AA6E0BEC5D0A903AC9415DA345AF199CAB86BA99234C9526E6E8812F6DA8001F31337B8498A8374AE527B6032A0CF3142D1D34181A5AFD6AA432A588AE1F644F5A100FA593F0ED2753F441AE5677484738FF694ABCEC58781B06D0213579F827FB4F97B3FC343A445BA3035AEE989685E7B20BE6103FD39AFABC334417379BD666181925ED369680B851A54C41B6546B9C04CA69742B2A814763674ABC9CBCB03E96F9466CBEAEC698CB5C9ACF814E90887F8D15BEE556B28F50B739185EB7A5A06E896ED0048BBD905E016436477A68EBBAB1E172928AC8FA9A8B0A0D999B135A753A29A47D0136865B0F382572B0697D0FCCADC8A77C1B591BD73B639E13F9C21B6F0969B0ABA3EA807303377AFE0F49421B68D0712823FC448FA9A468FA000D5964BCF9A9E7FC92DECE03BF6732A36935B25023B47FC94C15795DD983BB4531E935A19778305D0E8A75C2CC770EB46B6D5759DF503BAC33F0669C775729C59EB94D48223D763880E8B58473683CEE48E309380F7B442E6C83F0EB9BBB0B1AE805B1498471AC1149D578B454041AAA2F5CF13390F10A72DF3385C6A8A1F990BB946F4C888E585069B5849882788A1BE27DA0725276FF9DB130519050B74CFF69A68534222499CC61F5845A8FC0AC5629E0CDA20D3EA2F0046B78A2267FA0187F15721EC53083018772097892BE85C1BE99480247E6E30AAC8FA2C593C630B981E57515E0F7414CFA8B606D931280A950E567C93B319FD23CA1B682FC0B960DD309F80455CABBBC71979C59A025008462C0681465D748FF2A6AE24E86C79922E2845568CEB5063FCB81B78295B93A80B221AE7E14A9A9BB7182C1ACF347F2FA73784835F3375A29ED05E4BD120A119CD0FDA29F76A1EB873AA88D0CB3C661FF0D5652F2B4604E2BDB1497486687F17B8CE7A096A59E0922260AE99BB7412E306CC0B25940FFDDF25214EE4DD4E1AEB851878E2493C05E2BD5A30B5B99D3694543A842153DEE9E035299D7E268C9492D71188F9FB24BDC2DD20C1DDCA647A15231100CED48ADD211A5C937B8D6079D8E271AF3F949EDC61F70E60453AEF20DEA9 +ct = D793DFE0884A98CD776624207687CA1753B04CEF55D5DC4B9C5C94264ED0AA15B03251EE0FAF7C60C6221FC790F6E32C36DF947183BA0F3371CAE13EF196F36EE80ED758DF37AC6D9F45F14F351849FA5A18A4B9904B4E47B400B7BD80F7F458B92EE9A1577289A0CBABE7B8D7BDCC1D9BDB1605C96B509514DBF7FC9C84327F692526233F6723B04791CAEAF19B687052CB36CF248A254D4B1ABE5C2AA0D7EDE7174DCDDB2FDE19F5E91014967169A2DB30AA756D794012C290811361DDF4818C6BC1D74C7BB6E7830051C7B3EC51D66C3B1613C8144711CE70585F8FCA8001BCD9CA247DFE8449BFF0F7D52F384E496617449F003F145DDA4B53015AFECC31A72E3803AB561C35A72716D8CE3566A66AA0E921A1098CCF09712086C22C1CE4951791A46C78CAE8734B49C571710EE0EE2CF1138E1FAE19455C4C2B573EB8183DD9892E3D0DC150DAB5ACD32F8237B680865BDDCAAF0D5176FFB2382DCD75EDB2CC8398AE9789B7C49D44E4D4D18E705CAA7E3021229A52D45B12677D8D208EFE1DA2ED0F17C60BEF179C36A5B40B4D2B52A43CB251B65508148666111078D1D0E9ACD129526E48CC09148941E1B53E31392C6BFDB1406B7447589D2FC121E106830935B94AED6AEB66DF8FE843CCE9A0B91AC388E5C4C023E2522026CD518F48345411590AE042B607BD38E33FD15398C721DAA0A1023AEB4704B34125CCD18856EE95910B9044A83560D6EC6B2DD6BAC5BA82F47275B39996BE603485B9A8C8CFC71550F21F1F98458BB29FDB6D1700D47603F64734A910E143094DC3B0FD1B035C6CA03C57B009F4E3DAC49EFBD95D522A130CC70A98145F1B670463BD70917FA0AA10514584F180AD500FCE41902D7C5D1CA1E0BDBA213998FC5050419E2C5D1A149A9739DAD7F64B778D1CF6349939CA95BFD6797DDF9E6FDB14B770874A7F29A8C3CAEED48CD08BCD44931B194E648FEFA354CC754D2DBD1C829DC084EE2292BAEF7F221871E783E5ADC8DC8B2385D24CF98BE75C43628D990EE4B3CA96852F83A300E8FE2A84C1D894B0625036BE83CA29FE97C56DEA2E55C0261C04D5646F2E18CBE6AEEE22EAC0FC9E1A29DB9DF885A612DAB313ECBDE8CA25DA4D689B2D426B55B4FE36BF4512C730F55355CB5A7A980117FC1E63E50BE364D54C91B3001E89C36158D266F36D403CFB90F9CF73B86FB7435FEA20581ADFD570DA4C4C48FC689C1B67B4F457B7EC1C96E9C484FDDC58A27954402CF1D8E2C44BFD518F6B509B8178D4BA3C1B7BD2D1E8CF79C031AAAC3DBE6A9DBD211796A733ABAAF7F43684391368C98069CC42D069815EAC5046E13A8BD6DD39BC4ED2D3F292DA8EE67003947AB77903D72F97E9BDF0C3AF3D916534400545A3075570626F51C00F2BCB9DC611F0BFF8807BBA0A5E8D28CA8B988EAD01B7CD106D61F5D2E72FA46F8B9C80DE2D12778EF8A59444AF28F101B243660CE379C006B8AF92B26C8F1B6186390FEC31183227FC770ACA96B4583773FEE1ED5B1C96949D5DC66F2E76 +ss = 3602269C7AF9FE28EA1019208DC3AB33BA09239D435C509903CA67345717E845 + +count = 59 +seed = A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179 +generateEntropy = a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +encapEntropyPreHash = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +pk = 5E451E4C8C85A192C91DF27C17C0684BAA6375B17586F8BF1EF12B91615BD08A340C58629CD45F7A392F10A04916C249AF956B180BC418B8A95F66B2D0847E79D247B430812D682B1FB91879FAAB68F25602579BF0D895073780007B7D61940239913EB217CB16A63EA08B29656712A21A32C754953335C29E769DF17125D84C32B3250EC96067B975BF524091EE4013A8B67A19A331DAF38A396A765F7820A5E3606A734F5BA854D1E6B6E70CB9EE5B00D4D18D928921EBB8048E284A3A05A3DF9469EC53195180AC9F869A8E8866D69019E9730FD6E672DB024B6ECB4DC55729024033703B6FDB7BBEEECB2345782815843B7B7664627CAD52038F98DB605FD23D24080F809A276419C876AAC69977998B1400395829656C97BE262E053197EAD738D9BC995145CB2713B5E181223E04497C8114EC5A05384AA31CB84406F93365D7059DD88DB8F94A8F068FCD10BE96E32A0E926DCA518B3FE9286A755F29D83CF667407758141B2011FBB1764D3334F3A763A17CCE33C2816AC79EC4CC4C2D842B004C352ABA419BE87281779300708BB20143A43413A2A55C41E36444046A3C021A4D7818DD146D1DC335C66152866597AA69A44F39A2814A4830E002672731D93B7FE5F77587B782AA279CC9807D6126392F812E83662D49DB231DD3060F882D71D2A0A4C94ADB3784BA1785187423D7E8A82F379EECBA7E6F6A67B568698AC3A2C0B096B015100BF9ACFEE522A0192E49880439CC1FA9B30FB7A10544E1867B0C34DA981CE6E660CEBB8853545994454815178C60B04DCA7073531AA2A5095F7B8578CD9889F3428A7D1C72B8FB320F304FE5D23A4291666BF7AA1AFB5086532FC5AA347DC29279A4484261614F2774C81374AA453024B68D384B01565A36D98B751297477A61780E98135375AF8EF68359332826DA01BA6A73D5263ABC659454F57D83172D0E515D3754270AD84543D995C0534788A6786927B952698ABE693BFBB358E9E393151AAC991C97FEC8C55CC407BF027DF7E2A505DB531D47344552321107B651FA4E47D4B389C5825E02CA1F42839ADA4D7EEA2CCB24A74E34672BF1BC4F33C88C3603A3FA6CE87AA5CFE30125F99E81550C19B58A807BA8A586415C2924A6E467CA8BC85A5400F910457E8B9D74A11E2668C0F1A2A1D0389361D09900EC6671206139380EBF9390B2401555BA0A57FCA36D2742F569A573096A2B442C5992C3FB65271479291F097CB94589FA15BF73CB9319D93860EACF1CD1BF7D380E03587CE3FAAEB6360D79574803B5C49841B74918768EFB518CA46B26929F68639EB8FA9F73E61A8B69B004CB5D9D92CF0DAC9ABC03171444A03409714DC1514931182701C19E242AE73B465AF335C8D3588FF468346ABF76604B6EF887A7EB8E8B44005BB55AF328155AF7928C732E7805010CF0A50EC68E29ACCCEBC4A39E2ACA10084E2543746BE6C81D482F6F3C1FE0D31C6A69329D783A1BFA0B43E289A2F843C71196809CA4B82C75C59C7AA5D311350AA55E89735D9C34E6982D17C033937253D9778CA31A14A9894C5D801415056552C410484970CF2AC86B374644A37976EC4A123C0603CCC01C6C6E994514F13885BCEB2F8B0A57073E0F3130DACA54C038DC1085402160513337AF2B6DD900B04DC3BDFCC90BDB +sk = 2D80A415A1B29961459E396204E5B5E65540A2A9AE9CD52D867A9E20952FC7565B66151653448353697B09723B17E3B1EF375A3E260A5869B579883FD1EB3A06DA5C11E493F4CC9D18381856FB2C36223E7214AD78A178B2153DCDE882451776478A4E06B392CE9B9D0310A5A134B42C37312A8932151571D85CB69D9333FF8685569568A0FC4568682EC2F5506F59742601C46DB34EFB9665B5815574518FF677BE1C0991B644B5931B112220C6EEE10C37C19316156BCBF354FB661635E42F6B26B07F9552D7B1A65D51C7EB6A132034BD755674DFC14345AA72ACBB85D4724B2BA14925421E570543AE904F9BC4016BC0389FB9922CB12A393A24DF219290DC506E501003C0AE8CBBC685A25A91147265207F93F190B12BAEBE7CC7EDEC476553762EA45E48694DDD172B6787B7D9719E89D77563C9C2CCB77CAEB23D7AA9181B82B6CBA09AEF1851235C7986194C8322280B4192B94262FC79CEACE4B894C86814D4929BD773E6A73FB0C7C36C67391A314555674CF415292055BB39319DCAA7B07230204C068028B3AE7A7223DF112032D60EDD1B6B52EA1ED13B86231A1EFB2969A691CEF0D219835A44E907BB0CD2CE6DA1442AF1460F2AB882959E0862BCCFCC6E3FC2BDB5EB673B218D6E9C5DC6461D8796945B614C81A68F9CF381D256BC1E63285141814077AF5F54C2C6B487DD29CDB1D2CE08F09122D09632AB823CB00D86A57F8933743F347C203894D0043F5692A6E12283ABFA1B98B39C6D638132EA4B94644E89A0ADC35816BE01A408F752B3215029D7661B554BD39ABAA906AF32F877CD4B28BCC217825AC897D06A4C233462FBA602A81321DB93279A19BF44131B86035DB3C4CA911F1FA30146F9BE0333650C3C24A5C85BF5E252413853DEFB040F8A16F4ABB9E18CB3D496A69B356D8206C106864C7464A7A7EC5E998B3FD5B18DF1D947E171272EC5AA1137CCBE50AE73ECC106250C0392A41A73A4861ACEA19257BE33CEF406B7EAC1796F605A709A4BC06BBE40867966E830E8AAC19AF626A4642A8447276F09CFBA6486564079E1AA38D7E179D9634E3398B743A1812F02818E979B4434A4516C2C77672600D5B7D3BB6D7E3253189C3694120DBE2519C62C80558AC1D522855682962DF611FEBC9F33FA27A0787501A42802863B5CDCC6AA81B964CC2C9B8081B63750A6358DB5566A0D3229D2989E98199855A2448F54688ED2487B816F5CD651206350FBBB5CDD995A9DB37B089CAA57AB0DEDDC9392EA1C0F99031A42C350CAB7B6F54C1E4ACDD0E28D7975A188502FEF055FEB5889BF87929B6006562626335B05EDFC544F10CBD927AB3C4C9E806700349B9A0099801D5948CFF3BF0977A9691A25AC880D593A36D1E5436EAB078BD9A6BF25BC3D6B5BDFA02AAB06AB5842C440E40D430AAD9311015A8767417B233FA8CFC64914533031AB39B845A3C50CE00BA0F1A586053768EA48293044F3A831B456320600404761C7E826A0B111AE37DB49B31BB3E9389BD3E354F08879906996DF2036AC49B9C773AF5FEC5375519AE7B8C61CE475AC544D13A5B421B8A686251B6D1C64F8A353406248B0430C8A3A308B600D0C9506D6509AAC9A460935645E451E4C8C85A192C91DF27C17C0684BAA6375B17586F8BF1EF12B91615BD08A340C58629CD45F7A392F10A04916C249AF956B180BC418B8A95F66B2D0847E79D247B430812D682B1FB91879FAAB68F25602579BF0D895073780007B7D61940239913EB217CB16A63EA08B29656712A21A32C754953335C29E769DF17125D84C32B3250EC96067B975BF524091EE4013A8B67A19A331DAF38A396A765F7820A5E3606A734F5BA854D1E6B6E70CB9EE5B00D4D18D928921EBB8048E284A3A05A3DF9469EC53195180AC9F869A8E8866D69019E9730FD6E672DB024B6ECB4DC55729024033703B6FDB7BBEEECB2345782815843B7B7664627CAD52038F98DB605FD23D24080F809A276419C876AAC69977998B1400395829656C97BE262E053197EAD738D9BC995145CB2713B5E181223E04497C8114EC5A05384AA31CB84406F93365D7059DD88DB8F94A8F068FCD10BE96E32A0E926DCA518B3FE9286A755F29D83CF667407758141B2011FBB1764D3334F3A763A17CCE33C2816AC79EC4CC4C2D842B004C352ABA419BE87281779300708BB20143A43413A2A55C41E36444046A3C021A4D7818DD146D1DC335C66152866597AA69A44F39A2814A4830E002672731D93B7FE5F77587B782AA279CC9807D6126392F812E83662D49DB231DD3060F882D71D2A0A4C94ADB3784BA1785187423D7E8A82F379EECBA7E6F6A67B568698AC3A2C0B096B015100BF9ACFEE522A0192E49880439CC1FA9B30FB7A10544E1867B0C34DA981CE6E660CEBB8853545994454815178C60B04DCA7073531AA2A5095F7B8578CD9889F3428A7D1C72B8FB320F304FE5D23A4291666BF7AA1AFB5086532FC5AA347DC29279A4484261614F2774C81374AA453024B68D384B01565A36D98B751297477A61780E98135375AF8EF68359332826DA01BA6A73D5263ABC659454F57D83172D0E515D3754270AD84543D995C0534788A6786927B952698ABE693BFBB358E9E393151AAC991C97FEC8C55CC407BF027DF7E2A505DB531D47344552321107B651FA4E47D4B389C5825E02CA1F42839ADA4D7EEA2CCB24A74E34672BF1BC4F33C88C3603A3FA6CE87AA5CFE30125F99E81550C19B58A807BA8A586415C2924A6E467CA8BC85A5400F910457E8B9D74A11E2668C0F1A2A1D0389361D09900EC6671206139380EBF9390B2401555BA0A57FCA36D2742F569A573096A2B442C5992C3FB65271479291F097CB94589FA15BF73CB9319D93860EACF1CD1BF7D380E03587CE3FAAEB6360D79574803B5C49841B74918768EFB518CA46B26929F68639EB8FA9F73E61A8B69B004CB5D9D92CF0DAC9ABC03171444A03409714DC1514931182701C19E242AE73B465AF335C8D3588FF468346ABF76604B6EF887A7EB8E8B44005BB55AF328155AF7928C732E7805010CF0A50EC68E29ACCCEBC4A39E2ACA10084E2543746BE6C81D482F6F3C1FE0D31C6A69329D783A1BFA0B43E289A2F843C71196809CA4B82C75C59C7AA5D311350AA55E89735D9C34E6982D17C033937253D9778CA31A14A9894C5D801415056552C410484970CF2AC86B374644A37976EC4A123C0603CCC01C6C6E994514F13885BCEB2F8B0A57073E0F3130DACA54C038DC1085402160513337AF2B6DD900B04DC3BDFCC90BDBDA43CAE3C4DA51D69A57EB87094A03CD3A9C3E6B4ED864CC691A60F0509CC6467A3CC8AA3239D4C52CE4C95AFDEFF6EFBFACAC10D294EDC0E7CF4535059BFDBA +ct = 2EF58C14C9258E8E8D59AEC0096B1645D2FC8A2E12F8BDF9813CD87A32835FDA60F096E647CA601C29C41D3331ED6AFF01978D01A0E7D9774211BBA0CBACB6226379A79C8B6575993589B5D73205F92A21A7B30B175CD228B5A449554A99E0C6E6547BE25AC510B9D1E2EAA8E7AF3A6F6F4D43B4887BCD7C5BC9C4C8A1AF737575802AFABAD38B7CA3EDCA440EE9F62F36F5566809572D5712BB03A1936A09E55365905763A631D6FA6D3C441B8B0C90FE04D2CBE0FBEB2ABBA2288EE38AA58E22453A7109F1E0999B3E9E4EBCB39A5763BCDE0290FA7213D9B357359E06DE0F6033433E78585AFE7CAB779A088A9DECF5619BB8C35DD51AACE7A5C3567162017853595D889D57AC96FA8BEDFF46CC035B15C51A72FD865923CB60F8A4562F9C30009EEC7BAD7A9E0C4188EA89A7BA3F719CA1E5243F94A95C2E3B74336D5BE81AB156528B104007F4CBEE6F88346537865CD9CBC40980462890FB2C994119A74A3D65078E24DED0F91718800B72B66629B4E8B534566EE45227A30EC724925066766C4D450AEB655D91B5426B8F2562DB6120BD8EBDF0F96758DEC90DCA1EAEB3479242E65F097EBC602F0AE36B4DD0FF2F7FC067A33B281582E51F93A5948ADFCDBFFF34A51BF8B3826EA030056CCEF16C9288CA0073EC8C50985EECBC97FEADA2C3139F33AF954C03ECDB4A01B468EA4EAE5FF407F27B6F26C1AE5FABFCD592E31C47F8E4567E3D985FE6D93FD7B0255C8D4E00497F93AE1DBF56F55037F2F5D58012757484E9785CC7052778D3198392CB3A7A1CA0E17A9DE34206FEB0BEBC7E454C90DC6351D3C7B8CBA681B8CA70993B19D47A8D12DDBA0105BA12441592FDF4205656A36BB261A42181BE2CB3C967A54C1BD20DEAF6B4882BE7DB475DEF1EEE3F2083A72B77F1C8766DF31C578B48EA5955752E836017213818DD12B0BA8DF7767C5CC432983AB3D82199DFAB7BD98346DF7BDE7D795B96F61417B768F188D3777EE7A17E6D957BC69BA16E1F345D44E4E18E5189705DF89C4BDC10DB1A6CD1429B10596779FF942A703349FFCF6D1144F105A0BA48E04D4A26AF9C9DFFDE23B8BC66B69AF9B7771DBA70A77ECE86564E266B330937921D695145DF0402C8C81B6F2789ADBE07CFAC8ACECDB8D6F8AA0B053FEEFAA1CF4503AB6C3AE6013B93EAFB5AE3C58EA090F1F26E8A96F5BAC73E53FF9FBA367DE06F0B98CBCE936C4C5DFCF19DA140DBF528C431A99787F0698DAE81AC2DF8F5BD837CE013618CB342F8234AC64A5B40A55FD1443F477215A0E8CEFF7A4C0646B0797CE22C495EFCCBD0BF9D6F46B5E2A4065F5E7B0E6196BE5BB6872D1424A1ECED35892FDC4BA8361C21197E5DCBCBB26D34C39E156B2B60EB9105B4172DE9FB8D5950D92E25B4EAC39272D3010792A39943F00C41804D2CC3713E7E321A044F726132689853F954E727FE0B822E5BE6BB0CBD39F6642379C273C0CF30B5DBA4933EF09E9A8C069089C57C6CEE8FEEB1F51692FA5FDFFB0F6AEC6E827E0245E72777B91BCF +ss = 5E039D591CFB128E51D0804E0993084FC92B0BCA9C0F2D84E24F5FEA5EFB3B8B + +count = 60 +seed = 99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E +generateEntropy = 47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +encapEntropyPreHash = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +pk = A20C8DA5745F754B89A990746EF771CF07A6D8109998936B282757F344A1B00B851EAAC27A9A7FBF480D44262868542128461598B5597B10CD3A2A26E3F941A9A4719AB2033FA1181ED08E3247BDD396A834E43F5700522CB307FF4B150BBA9D8B6AAB47361A7947B7A04B8D923202AB1A3D6644BE06BC6C1E0735D5D92821C5B8E9B9A83C343D0C456B181B6FA566B0E83602428B6CD33405A95ABB623A73299C5B4550A7D6C31D6EF81473489BBE457E744B5D1E39AB74D8A051951ABD01A6CFF3942A102A33080327437635C1C17966834340C26654A3F38616E5EACB0E489141B14E9D1B15B7FB30927715273547999B93EA2A1CA2189F5645CC4889943F3CCD95496B71F392F78A82AA1A21D66382C37154323C0616804F50125D6B0698E5DCA3E2D5658CE153BBF57E4B1908C92587B8C863FF4872E9E1963AE6C971C6AC3932BC974B9F15E5743EC069ED203C3624A022F9A7420BA951425A432B46C5E8BB666091D6F223E357CE96C55BF067B3C3F51ABE70ABD85A73A42233800853031313AE9971D280B3AED18489E75CDC16CBB3EBC95A8C97A768AAA6C0BB0DA7943037BF2B4A523E33ABF669C262941F326B11EC6BC8EF51B0666268D6D433B5190BB6996F65925A7EB0761EAB6906178BE9A923D1C61C0B7683CEA681648C44608217D6DC86441A8F423A9D1C288B32EBCD049C15EC151E256A322EE79E2C689A23A53B8D473F4C643AEDC646401761A7B75F7BD4145E837B756003BAB223FF1A74FEACC2E449B5DD9B5777D62FF0E20E4B395821474AB428AA2EA219BFA169B95039616598DAE0B9282C69CE329B534BC7AEA58E17467B1348B1AB2A031324BF835C985371B0F53877DCA53570199B23BC4D70A9425A32B54749082E794E10012E9B458205E106DA807C03AC3202A4350050815487626BD018706C69A6AB02FCB92621114A16CACFBEA02AEC424F82FB874800C61CC23BC6618ED75674A70A6C43C4068E2A7C9723A054967E4DAB09F337695BBB01053A7C5DBC764A0856D2B75DD4A94A9898AF8B95A62B487EC7FA9F00AB75325C9AB8248F1DB65FD7661DFB0B8EECDC2A4134103380988758379D0A73B0F348B00B4B13B115E74674AAAC2BA8C2A7FF440340B622B5C0BCE05CB601259913C488FEE540D7C058A28A0C28B856EA800D26A6A26F8BCDE7D78298314CEA6056B00A845321A245949A8C7C98D9F8821F1264C658A8061A3014249B7E522D586A54AD7A12AD805544247D74058BC9AC0F603A44AC5199BFFB69C1570C4076B345064EC00C5AE0D6A2308947593A84DDB6133BA40577B7B245C20B5D04C5D08281CA0AA10DA2A358386D2A4C048C89A2402C9150A7419C0A1AA17562FE786F00486DC82A9809DAB08F7B16D9432981087B6741269424598EAA99082525D5DB0DEAF1B96F55B41EE209F57ACEB895BABC38828B712724204744834303C496B7171FC458534F46892627AE54800FE6F11D06B6AF2B6B9259144F769B1F16C0586C9CAF01F8491251907FD213AA6C0BCE5B08F060124FB99822D964C502AC49C16CE9FB17EB0C91AF559947C056AF77CA687C4F675C89BE35AAE91584CF82202734379B56784FC5CE56E3852D89B052367D9A5D375D06EC7863E051CB44929F17A4656A2CB2C58D8D457897A1AA0D +sk = CA481DB6775F3D276A56CA0E60CA79BE147E63B6898F4B814C69A06F55111C9824CBC1C109A01A7BAA259DA651A1A51D60BB358432550BC1AA1CF3656E0667D726C69A39AE564BB99162C824634B8B8A706D82175BD9657EC09A308B51A3B429822667A5135FE4350A8B3CA10E8B03B6DA0BBD616CEEC0A08476909C6182EF0314B284CC3F43C337307FACF7B617348779D7493AE0A25D415124BC5D9134182169238CEA1A46A3001A8165713A3E5C16AE03A477207B99C2CC674FCBB14CA439FCC3032E4C2F1E92841D73859C76CFBE245193816D87C12BB3F12763174997760D6887A429A37F78C32CC1AC8FACC587AA235821C254A2341B7C6BCF8B52C908836B67D39D63458AFA9530FC2748DE4A698AF346F8B5405DC7B43B05953554021AF73C585B6EF248C07ED23116BAA18C845571823D25CBAE0AF57D4F6AB2473B5919CBABDD7B4CCCC1BE89150CFC585953389172590EDD61C3885446B500495247AED57A9FB1140CEB6B29F7F9A9F524106D8CADA3432C12468F9BFB9A50B920CDE85654C25249350F6760293DDAA28C771963497C4C5230C05862A4391330F54CADC3B0C92B9798F5BDF8B21016725AC8F565466464C2033872684608111248FCCF94C61337EB6B1A9017E342C29EB2B148936119797FDB2757BEF51A9A2601A00C6F0547B1831B1CA1118CD2E1CDD601A0B491C588CB5ED88AC36AE183848B9F87264CC5B020B2E965E5B89FF74C58CD2B338177BF1350AFDA9A74516A5845381E5FE132B4089506E8CDE6346FCC760759592345927C5C6A97045B0AD3973E806778759B35988953C80B3E7574B7CAA225C744372EE3042E07CCE978A3F964395D40176AAB7905A4BBA98250F594C5A96BAC41851E09F897DF0376A89516040C1F8FCCB93D44AB474C56913826C9E2171EF67510B53EB31153FC028B3625AA7A353BBE79CC76D393E209115DD00B5D6C98F80101705544604351CDB87715618343BC3FA227C1E9FA1EA3989390B02C59EC9174E5165239427592A2D973774CA62DBD9410164BCFD95834C11621F7DA54DC55C44C594785FB0016448F2CC39A05E01D8581658A2410CAA630347C3F0F6C86F344816BD13B3A04313A730F2DE9BB50659B642353F6463D2E2A1A78B722287616CDC266B01098B3544632152DB3B23938D67C63E51949496E13182326D5B7D70B81D90CC6C5D84D4E5907833A7A76D3850AC4993A696C4B210DCF352A32B4C83DC9114305308129BB4FF73A91D733303BCA92FC0083D95D32CA54557A6FF3C42C2BAB46FF913E1D39BA3F6092E30AB47F9985C7C439448C92B245259D388E291C04DE427F378011CA983B21B2BA8BEA9D6EB36001AC4FA5061EE1670066F9252524848973782774CFA795A2285A2669515D4FDA7093BC54439753FB6B4E6B781EEFF574155B2438E074B332417D751EAB1BA1475436E8FC1B670C3928A3553D2BCFD1A59C46EA2542884F91F98A38D42ECC026EBCF91258ACC99A50AE1EDC88B90C98B74C3961B70759F39B3C20175FA80386376CDE2B66DFF213151B800921AB6932B45B720932A540C79CCA0EACA0A9D5BC841C3ACF3C08096C0446326114F05CB09745EBB986DDB76913FAA6A20C8DA5745F754B89A990746EF771CF07A6D8109998936B282757F344A1B00B851EAAC27A9A7FBF480D44262868542128461598B5597B10CD3A2A26E3F941A9A4719AB2033FA1181ED08E3247BDD396A834E43F5700522CB307FF4B150BBA9D8B6AAB47361A7947B7A04B8D923202AB1A3D6644BE06BC6C1E0735D5D92821C5B8E9B9A83C343D0C456B181B6FA566B0E83602428B6CD33405A95ABB623A73299C5B4550A7D6C31D6EF81473489BBE457E744B5D1E39AB74D8A051951ABD01A6CFF3942A102A33080327437635C1C17966834340C26654A3F38616E5EACB0E489141B14E9D1B15B7FB30927715273547999B93EA2A1CA2189F5645CC4889943F3CCD95496B71F392F78A82AA1A21D66382C37154323C0616804F50125D6B0698E5DCA3E2D5658CE153BBF57E4B1908C92587B8C863FF4872E9E1963AE6C971C6AC3932BC974B9F15E5743EC069ED203C3624A022F9A7420BA951425A432B46C5E8BB666091D6F223E357CE96C55BF067B3C3F51ABE70ABD85A73A42233800853031313AE9971D280B3AED18489E75CDC16CBB3EBC95A8C97A768AAA6C0BB0DA7943037BF2B4A523E33ABF669C262941F326B11EC6BC8EF51B0666268D6D433B5190BB6996F65925A7EB0761EAB6906178BE9A923D1C61C0B7683CEA681648C44608217D6DC86441A8F423A9D1C288B32EBCD049C15EC151E256A322EE79E2C689A23A53B8D473F4C643AEDC646401761A7B75F7BD4145E837B756003BAB223FF1A74FEACC2E449B5DD9B5777D62FF0E20E4B395821474AB428AA2EA219BFA169B95039616598DAE0B9282C69CE329B534BC7AEA58E17467B1348B1AB2A031324BF835C985371B0F53877DCA53570199B23BC4D70A9425A32B54749082E794E10012E9B458205E106DA807C03AC3202A4350050815487626BD018706C69A6AB02FCB92621114A16CACFBEA02AEC424F82FB874800C61CC23BC6618ED75674A70A6C43C4068E2A7C9723A054967E4DAB09F337695BBB01053A7C5DBC764A0856D2B75DD4A94A9898AF8B95A62B487EC7FA9F00AB75325C9AB8248F1DB65FD7661DFB0B8EECDC2A4134103380988758379D0A73B0F348B00B4B13B115E74674AAAC2BA8C2A7FF440340B622B5C0BCE05CB601259913C488FEE540D7C058A28A0C28B856EA800D26A6A26F8BCDE7D78298314CEA6056B00A845321A245949A8C7C98D9F8821F1264C658A8061A3014249B7E522D586A54AD7A12AD805544247D74058BC9AC0F603A44AC5199BFFB69C1570C4076B345064EC00C5AE0D6A2308947593A84DDB6133BA40577B7B245C20B5D04C5D08281CA0AA10DA2A358386D2A4C048C89A2402C9150A7419C0A1AA17562FE786F00486DC82A9809DAB08F7B16D9432981087B6741269424598EAA99082525D5DB0DEAF1B96F55B41EE209F57ACEB895BABC38828B712724204744834303C496B7171FC458534F46892627AE54800FE6F11D06B6AF2B6B9259144F769B1F16C0586C9CAF01F8491251907FD213AA6C0BCE5B08F060124FB99822D964C502AC49C16CE9FB17EB0C91AF559947C056AF77CA687C4F675C89BE35AAE91584CF82202734379B56784FC5CE56E3852D89B052367D9A5D375D06EC7863E051CB44929F17A4656A2CB2C58D8D457897A1AA0D6533C524A32345EEFDADC74A3C6AD7E981832797FAF1068955B79F118DFF93588F1481D7CAB000E33FA07DE8DC9627A85E76FABB4428A3376E66300CF12A0787 +ct = CC18BE84B498262137E39C8C5540DE67A3474E2F9E94953081CAED1A428F3DC8FF3CF27DFFAB8278AC4402A1FCD4C285FC13F251BFBD2E7D5F1E79030BAD0D12F4BA296F374546A5C03A8D270FFC8093E276C62E887CF91BC7B17F2C37065982DBA258B0F8ABF6FB391D5A077A0167E16D046DF535A703412D4C9AE46467AB0DE3B2AC5B80BD5E1875E727DBD633E742DEE2A2166303F7998878A0F96A364ED5B92F9BB74505D8F8694613062353EAF64C50AA7098BD142C431352BCCE1DC9D874505A60EC6318B71158ECC0A6A9C225C19C52D8DDDF1C7B3984A3D90896E89D443398BDF1FBC2569280F22353A9307288B0D99D31FBFA3E391BF4B530165870133645310D41BBB4132A51F8A9F4B62D950CDC33C4C0FC231BCF79D90DBD78D8BEB891EEDBCA40FEF6136C488D474217A77EFA163EDAFB5A23A7D424233923F1E7A4DFF5EC8AD07FFEF39E6ED8F5733A7CA4A484B926FE4268728FF7CE3323E67B3891175677DBADEED1EE2612B58791A6E93D3A9B9662015916359E775BF6357F2ED5A71DBF6783873443BAE37E4DE66B14DA166A4410B2C3D1B0CCF2C26E7A5FC9252B7D7077C32B53BF40D745DB6D32D4C9D7ACB4BD1192ACC55F3BED993871547C361C986AB1B356296E17E34F69F41EE8C60CB97999591484DEB6C6D9EC55ADCBED8D21A6BF236BBBF1981372E6CAC0F688945BCCA2EBD6F76B39C705550B38A10BA9B3F8BFA789E5A80310AF1EF038472E960BD7C2FF20B94E347DD985A702A9D63FDF2CD869BD83D132DBC29E2495B29A8DF54CF7551A68541816CBEA53F3FBB7F32FCA6F9971A7E65CD9147BB81BA13B82DCF914254D7AF5BBB3452346653020870C33AFCA72F5DEC04EAC5B834F29FFE71A9B449306F04FC847421EAB8F42AA045F70A2748D56F69A1AFA39F9B24D04D57D7FF7257262F7E4833A50E617B8AC649414A74278225DAB5AB45B1AF3B65E5C4C8BE12E7CA0F2A74F881E7ABBA0B6402A315EB4FF7CE84C6C0F60309612B53C2AD943A5FC485F8766D493363533B13FFE17B9F8C279213E8F942E35858B3D19627394E5C71B74BD84593976BCC50390557942A4DBD0C4D413AA6B5B4492B957E61EA18C61FBB2C719FB1F79890F91B65BBD173C55B29F01853BAAFC6680629682FD16CF8413488AFCB4CC3C70CAA02B02466901ED472836C4384E8B7C0019436553D4D10FBE261CE1CD1B82494F047947C14F11643EFC41699A6DB1E7803382C51BA88783CE64E3952049897E03D181B4E17AB6AFD40A96AB682A97573CCB1E1B1F09D19547BC746A12F7DEB1447CEB4CD54F6F5E2305CA3F10EC3B4EDBC2B2BA34DE88EEC1218EB1276E1C29CDBD9615C3751B278077A05FE2A35863748207D62ABC17435C2DB742BE8FDEDD9EADF5C71258C906E68EEAE12D438A10F409CD9CBDC3CFE72D116B7C3F1D288DFD9A01899B0FAD6AB18FB34687204620282844DDAD79C457BAD5E03C6D6E6AEEBC7AEBEA18B60D34C106EB66A6B07209D2FBBC99506B0475241E2E6C722D +ss = EAE95E643381DF7A1CA1954EB0D529DB88A8001B8C1ED98A4B055936BBC6C038 + +count = 61 +seed = C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993 +generateEntropy = aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +encapEntropyPreHash = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +pk = DB55C6CEC7B63C0721AAD84D2B6551FA941167C78A0C105ED9E5300A24BB2C8B2265251A38EC2B9D05A0635B2849A81A2A7C6F2660504D5602FD2763046820CA168D70B76E35B9641CE46A44F2A394F496DC32353C1A84302381E8D74CE4294A4A260A5B0704797567AE831D7C4410593CB7B9AB74D2042C84805C3AEA6EBD193A927C8189082333B3A5E96857E3970BE7DACA4C884D7BB0B3B9C250CB4135D0B8C90AE320DCB3C423E8A6DE79AD594240AE7AA036E320AD8807CCB7A1BC80C704C9532960864A9528347636B4123337DB7E2DE37823C6AE084418FDD05FF7E904211924FE5A370537762DFA012A2153AF96A46987776D245FDCB9434D66AA10524A3CA74E494C9DE919C8E23C3FF77C58CBD1CBAF5B8A69803A32E23959B2A7D9F808689906A0985AEFF5A8464A2AF64BA053A3C18D89B2CAE3814CD712484288ABF7655063C403F635D7A2AFB9D804E2E89677131BBBF7009C981548036726D25F05F004D605A24B7C2BCCC4294F065C013C8ECB242D25611B5C82BCABEB9E578758F2F3AD3F087BB6813DB1F3990C867A2E679F47F074FD012E87B3B6F51CB1707B9287D99FDBF43C8E58940109C376789E16C4A30B6BC34C870364192C555B81AF58962AE771DF477FF421A9B46C6E64BACD1A8A6D00DA4D9507212C910ED2C62D199C7E330A11982C514F27AAC092A5216B13AD54BEEBAA4049065A68D8CE9B1C969EA01599A71D633197BC33C2F6F958F72CCF14C7C09D973770F170F1F7BB9E458A00936D8677717F4A17655BC7A7EC56119779F7AA391D2356AE3A97D7CA04971CC2515154E148568C176A659A8DECBB2C5C449CCD914D3CB7431CB3A0A400A8C7B59B1CC770C5BB5B64E0932C61783C9979D6CBAC042216A0CC5800EA160C8C8556E0721D610FCE13992396C382E93BAD1514D780CEE046525C443FAE063C5882A01E5A73658A30864B1D6344A6CC46729BAB7810C46F5B480D309A263E30461769A55A2965BA6BA0B44054F211B98C6C2355150ACAB81881E5AC1E561A4BC4B39F9902D1027E56155F5D71B7CA67415185319BA769F88345611CA2C20B233DCACA9DDBA42EDB204576BD028A79BFCA57C9DBB0A54B933C970DE35032B9B51D00C9922ABB5106897CB896065FCA846AA486D9C27F5B616E99EA0ADA711729B75D86669645B9A223959B3C1C2F3AB6536D74295473C4C055AEF8C2CD2D321E9E73CBB872698B3A60667BC768014332083139D08C321157CFF1481F259ED56A7A3FF1717BB64FC951297C709A4AE3C05FE3910D6507AC947F944B970070570FDC9843A8A5BA564141F80F1654766F93048BE6297A1CB76C105A7BA3ADA06A42ED1AB3C17542201712F11824766C07BF14685AB0A9F69A15AD6574E59709D2411B37B509DE3B7FE5E8B0AC65922DF23E680C33141418F9551660467ACCC0C794A67CC530A5B130B4CF1C28747601D26983764ACBDDD30E42EB96125956A5870142574419977209A12E09AB3C5E8A22C1C5252527C90987A816B8830A757EC44B12E2E2BCBF19097D02B19AE47CC7BC99189370A1AACEF36415DED82FA7A63BE809B515F79F06612DABCA5768201C59E2C92EBA6D13B72C31648EE1D504EC3E89C8D796E77FA9A772499AEC973B63E864CE36A29DE99ECEC9695D12112C +sk = 90D7129B79C095B3063F53058A4BAA74C262A99C822894254A050409215FE67773C26C7A6DCC739D8406A6055B388204604C7B065C0CDCCC16FA880858A36D6200C6CEC473BF81B245E09C6E5A55A8D8314334C23DC14FD6A9C011A2CA93753AFA8609320B1D01FB9A2A4263DDEAB8D5A00C40346B8F84AFC7B945F521321103A5219B533F52BEE42256EDD1B9A526013A00CE07D44EBFD66C0BB67775D1ACDE4AADB7C98731931E54F5C458264894971DF5D0CCD93817BB77A2E7D29CE47ABA205C0971F34096280CC725A3C22A4EE24A9938CC2FCD9A670272A463C852EFC04388CA8CE86A8E9F63273AA208610C2274709C55922AD371C197741AF0526218E84C3BCB61355AB94D5C94DCBB4BC08986AC075E01134B4029C8C1D78F829796C1CAB0EA2075BC25B797D82A8E0385EF1094D0A2B1731624308487991A7164D8A507F2390F354B4FA3A225D5A46463145EBB57B98724F1D3CABF11AD4FDC00BFA267D8F3107CEB7DA37C060AA23E247C28AD0069D30681E37807117AB841F23548CAA02212AFBC1BC54297202FA549DEF55DDEB5BA4D10ACE2650511366EBE9C1D61FA9D5574C86C0714AA523CDF946E1FD259148A7E2AB5C21884314E3B8082BC210B5209CCB6B95EAA2EF62203A0B707BF9C5DB1A155169B07D41C0EDB9709744CAAA36622F189773AD7A59DC142317454D9C81D55D1C637876F104B6836A6842B87174290125505461EEA77D63A8DAD03C7941B69D7F66E434922E13A8182FCC35E51C9CE81978E35818504CB32E4A6DFC777227A5484409A38B2A1E2243110E84D024B1FE0E0BB36D4AAC0622152599FEFA177B294BECE391D47553983E420DE5462C72AB588B2934680A399AC40EF35A5E8819458E0A7BED1AFBB29A446ECBCD4E45A50176EE201526E314CDE085AFDA30226039CEB41A14D87256BF566DB30AC77ACB80B29B1F9D602E919707C96863304372A353771E1CE994241A12369FBF42BCB4315592724CD5085A589B1B4CA46DC49CD65A1247178151E455741C8B5D7C9CAFCB75BF27A5B4ED05B22E932B1E3BFB0C93248400E5485486E0C39FD5CCEC680C78E6137BE96823DECA37C6306D31C9142FC03EC540AC0120EBBE9BD5237583E1972D0C4676708AD35B559FB89BD872428A3E0504350451DD65F58BCB292C0BA437394DAE55E6DF13A8F41827939016A081935D1788C4807A53A011B89528FB60F386632E725B163E83E105324C3914F26F389DAC199A926A25A02624D9A530BF0AFAFA4C5FFE6A5EF9422E422019FF337D1BC2FE16A07D9A046D183137D477DDA378E17A95FC7E02ECDDC0D551724A4F36EE7648C9AA771BD15AE29B7259ABB63D0983917156EDE6557BE445735EC539B2199F9816C562842627CC83BCAA659075F5179ABDD1A7056D27F7DD96A6813A940A9321CFB1946E95C16836EF028106BC26A3EE450D8E569EEB23B70722BCBF828821648B1668E6E47869AFB16C0E4B827C4CEC3C4C9948A6C7F874968DC80160A811CD06D58A885D033210341A6F7907F53A82C98468F6BDB7CC7A60107973DB0E70F9A387673234D6665019676215EE4597C65A13A2636CEE74266F373A4E48BB1DB019BF44EBFB0A5DB55C6CEC7B63C0721AAD84D2B6551FA941167C78A0C105ED9E5300A24BB2C8B2265251A38EC2B9D05A0635B2849A81A2A7C6F2660504D5602FD2763046820CA168D70B76E35B9641CE46A44F2A394F496DC32353C1A84302381E8D74CE4294A4A260A5B0704797567AE831D7C4410593CB7B9AB74D2042C84805C3AEA6EBD193A927C8189082333B3A5E96857E3970BE7DACA4C884D7BB0B3B9C250CB4135D0B8C90AE320DCB3C423E8A6DE79AD594240AE7AA036E320AD8807CCB7A1BC80C704C9532960864A9528347636B4123337DB7E2DE37823C6AE084418FDD05FF7E904211924FE5A370537762DFA012A2153AF96A46987776D245FDCB9434D66AA10524A3CA74E494C9DE919C8E23C3FF77C58CBD1CBAF5B8A69803A32E23959B2A7D9F808689906A0985AEFF5A8464A2AF64BA053A3C18D89B2CAE3814CD712484288ABF7655063C403F635D7A2AFB9D804E2E89677131BBBF7009C981548036726D25F05F004D605A24B7C2BCCC4294F065C013C8ECB242D25611B5C82BCABEB9E578758F2F3AD3F087BB6813DB1F3990C867A2E679F47F074FD012E87B3B6F51CB1707B9287D99FDBF43C8E58940109C376789E16C4A30B6BC34C870364192C555B81AF58962AE771DF477FF421A9B46C6E64BACD1A8A6D00DA4D9507212C910ED2C62D199C7E330A11982C514F27AAC092A5216B13AD54BEEBAA4049065A68D8CE9B1C969EA01599A71D633197BC33C2F6F958F72CCF14C7C09D973770F170F1F7BB9E458A00936D8677717F4A17655BC7A7EC56119779F7AA391D2356AE3A97D7CA04971CC2515154E148568C176A659A8DECBB2C5C449CCD914D3CB7431CB3A0A400A8C7B59B1CC770C5BB5B64E0932C61783C9979D6CBAC042216A0CC5800EA160C8C8556E0721D610FCE13992396C382E93BAD1514D780CEE046525C443FAE063C5882A01E5A73658A30864B1D6344A6CC46729BAB7810C46F5B480D309A263E30461769A55A2965BA6BA0B44054F211B98C6C2355150ACAB81881E5AC1E561A4BC4B39F9902D1027E56155F5D71B7CA67415185319BA769F88345611CA2C20B233DCACA9DDBA42EDB204576BD028A79BFCA57C9DBB0A54B933C970DE35032B9B51D00C9922ABB5106897CB896065FCA846AA486D9C27F5B616E99EA0ADA711729B75D86669645B9A223959B3C1C2F3AB6536D74295473C4C055AEF8C2CD2D321E9E73CBB872698B3A60667BC768014332083139D08C321157CFF1481F259ED56A7A3FF1717BB64FC951297C709A4AE3C05FE3910D6507AC947F944B970070570FDC9843A8A5BA564141F80F1654766F93048BE6297A1CB76C105A7BA3ADA06A42ED1AB3C17542201712F11824766C07BF14685AB0A9F69A15AD6574E59709D2411B37B509DE3B7FE5E8B0AC65922DF23E680C33141418F9551660467ACCC0C794A67CC530A5B130B4CF1C28747601D26983764ACBDDD30E42EB96125956A5870142574419977209A12E09AB3C5E8A22C1C5252527C90987A816B8830A757EC44B12E2E2BCBF19097D02B19AE47CC7BC99189370A1AACEF36415DED82FA7A63BE809B515F79F06612DABCA5768201C59E2C92EBA6D13B72C31648EE1D504EC3E89C8D796E77FA9A772499AEC973B63E864CE36A29DE99ECEC9695D12112CE2F60F27DA7F318EB94A74B437F8E0BC9513E9BCC38DAD99C174C1D75E0145F1E2F8D320AC3CB0C52EFDC753282F092BC39BAF4A18783A48EA031A191865EB78 +ct = CBEEC8C5D1013221D499DF4B687FC8DD032863EEE2A09D95CCFD7CCB41BAC0B0A3122FDC92EFA08BABA7D722EA15C19BDA3F4977AA8AFEBDCDFC3F0E1F4274680048F9E060339D3245E7CD07C368B0A132C6AB6C5FBBE6FC4D87BCED0AE4504A62B3E81DB9F586D2F33C61AB9F04939946AE1C38C0D34D97DB4097E424BFF268243D2CDE37211A073BA22C10FA87BDBC19AF7A7F5F07CE8745458F9EF15134BBFC4EEBB6889D668111C83AF7ACF73E63291A25A47650D2E0471B020B06BE0C34B191550CE2D2AB8323A4F224212EC47FBEEF84B36D17E593E4DC3441196F5B091DDF778C6127A9AB08F6B84997CB057BBA3508B7C31982A0A8A017BFB99279BD375DCB94D8F3AC4C6BC61CB3E63CB1FDC5CAA637D1C9330ED8A251037075D44375450E4224176F475A48854D58652637189D2DDBBE38EF9D34F059582F8796066D8D18362A708190AD0ADC3E91F2F51421EA2172E0170600BFBF23730C6CB025ED8CA4B9AE033F6CBD6EF7F69A7DE1E6F711F42D091A79908C7493AD1B68DED11F32DAA940CD4E92BBAC9EABCE85B3FEA56828A10E01847B92C64CE819E72F62BE4AE0C0F4B6FAC1ED60FCD91C166A4E0C17C13D52075F41113D03404BC422FEDA4B37F990C039218C217B5106A095587E2812E66437D8786B8FC9F3365EEAEBFF0C2E6FF6848F0AA570033471A9834EF83FE62884C2022C8934133970DA578C441787E17423EF9CF2BC3A40B8CC481FE29B8380AF23C42E2A808DA7E5EE6D1D7C96B13031898A8AECCCE1928C49C0A81D47BEDCD8CC53ABA9E77BBC83174AF15C7DE9869DA8FD3B924850FF97558207D7134EC48B9FF33501D4021B6F89208E8421BC07F1D37519614BFD0FA4FC195D54D2F05C118681B2465ADE4375807C5314CB21AFE0936098F6ECA70294F6D1F6DD9E512E0D87CDEF023E317CA27D2F1B373BDA5D96733379CA70731D3710FDB7592DB380CC230E13ED0DC3FE8D8CFE15D730CCF7B6E7151353C21CFFC8B53B5DC2BEEB3FC3DFDD1E4F3EDAD81EB1745353B47668022AE0FBEDFC534AE4248286117550B9BDA0E5643FD95B3293DEA31D9F4F2EEE4FFD4FB3964855E9947CB520EFC349B28B42EFEF607C416BC4A339F04D6EB7E1743F631F061CF4FA5440CA2410AD3088F08190A05FAC211345EB0EAFF7DE7E2294A58B7F27C792FD39DC3B8084F390DB55548E45EFC9674249482140B33C8219C7EDEB1ECBFB17C9F4E07A99ACD348628780138ABCE0C15C96840F04EBE7176090E13D0A08990096149CE1F07C865D35E19B9E1873347D25C03ED113CDBDB3EAB39532247EF19EA00361C4388EDAFDE0B12BEE641310C8AF0C184E3C2D8D5BF7769BAF1F7F6C6B7C7CAF0C1E40E6063E6E601ECE23874E7016D2FDC98ACBBB62B1230CC7C1CEAF1699D004E63F1351501D99D6F23760003C2BCADED3A44CF7B0B572243D8E137DC4AA785ACDDDA836D986C1DCA0587827ECB85B579241C5EFA06E30AFE5CD363C2F63C0E3ACD503F8277FA867626845E6578B40E983 +ss = DFFF52CA2AFC33401B4F72F5E6AB5D9BC21C08A6843FFB2CED24775D786B5A0C + +count = 62 +seed = F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5 +generateEntropy = 6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +encapEntropyPreHash = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +pk = 7A2912329482F244226AE33507BA8FC8366736352380B346CA39A936190F09576C5188C5E82315E3532F34D41F1B50BCCC42C1138802CCD5B50A7846FFA7BCADD91FE757AB7FE30E873BA233E13B21D25461030593433F4F66482D94B916AA8D1B4B8D6786926E9364CB579F52236218F199C3925142B53500291A3164516FABB941F98F0DAAA1E2D619C9622D649A0408AC02D5CCB9B787C1F9B196DA37020E362ECDBAB03CCCB63B659C6347104074B1F8254499C8452364726B1294669A3A24AC8B487752175B30CBA68860184D5F78B845B107BEBA80F8750475D059DAD57CAF827878B926FACBC00B54388F24B7B431347E334FFA046C45E234124C958CF66023DCA620E1400CD5C08B89554A474D7D04086E5CBD0D051C03C4580D3442A575255C833026BC19DD301A70367FED300EF27779D2A49819A370519C7FC404ACB3FA441A931C67A3033799519C883BEA134242F35F92393DC134BCE15713DDB33E252B991AF10C7134A8ACD09408C8CB2ADA36BBC25224E8867A4138ED9B4DAF403A477321614B3EE5C7BC2281441936B0B05513C1525421871D007346BCF52D6E09B756B4529BB5480AA3165E617CEF41720167707F35A4415975A62114C7918AD83BBD8905A283D14D22B2400CB29FB1E102562CBEE5A9C10929229F8C60A4B153C430A361812E75B244E4C3954A945459F735D45572E83B505030C13867C720567FD681C539D7094F5558DC5A86DA79B38049B0A45A1259713AF2C1640EE0279BB7191F0C0EC59C2F91184CA70A2E8B7576CE493E32F2C549C4BAD6C925039C4C57114075281AC7631FF4D94EE0723C3400CB2D73C184489AA5B440AD470CDE548F2F70903D08B9B4CB6DB68A5D4FBB049A5A9727F50F9E6C59295C62BED7182CA96D6093578DD014F7EB0B121AC6FAF917FA9B47F6650C6C7336D8848DEDB92A0F70971E456E9AE625CFE266B1000C4EA6252DE1CE20C014BC161FEF405FF327CDDDA37BE4919C2A0C097D6995B0EB743FF66A548307CEE1080A13841ED12333E62EFF081514A5915022C550C6021A27889BB0421DF3A709AB2F9F3B0C0F6019FA8810CE3A9C37F53CD651ACB4E5BC1D8B231F373B7A4CA6723A9710681016943F29697B09F6ABFC1C60E8FC4C201A9AB05C260D2452C83B88423B904DF74F425A9B4D116DE0D059D96779D61017C2E984C2BCCD6159C82DFA5AE7BC63E59304B1105CA054A71D753E7E583742E715BFECC80E51245FF53C16854AE0AB41C581402221CC8834A5F4556A84C19F6172C7C80C759299A42C71BD67040A29185A45C14B91B56A4AF9178E0BBB0C4C197549B5C9765A8874686C63445DEA7A85D43AC4D0B979B4CA13A80BF8DB634A163FE3F4327210A7A128716B9805BC1920DD322B15C74FC722A126069ABB8C95BD090F84497D832A1AB72358D4193B6542BFD627A139374404DC1998416F46054D1B4B538E778D6D0507FBF5571BD01CE56362164793E58355366495AEC80EEA35463C4044B202451B3604D6AB96ACC3617ACC1015379564D6A5FF1A6AE4D802712A94422A99D90988206776055545172B0282B5162B479D748A2E9D22356AF11DAF2629036665EED0642044B76775CFD9417DDACFDCB371AAEF7ABB3C2CFDCA88891DBF808A90028D4F12C57E4985F7 +sk = 0246C2025246911B525E6C3421584BFDBC83D73AB936E76A26236A85215C78DB7DDD010C2E038E3DDA69B5AA2E9F4997D8589BDBF918BE1C046CD518E6958AE6925146009D185B53456B5E16D59257F20CD0F6677535510D02602D5BA5B61C440FA07FABB1B5FBB38437E90522665776892EF205A41A1A2083902648844DC9D65E633266AF871481F036A2888D3FB9901355397F37875A4494777C781EC40478D09A820204A4115701D25A74B4BD91676EA6391FA160617C80CD05B0A80E040CDF22B29978CA55282F2C40316A35433DCC8FF7CCCF4280C0B11C548B5CC08FA45BD0760CE03A02F25689D0F057FAE44CB1574C42E760CB331C2CE4BE16823DBB2870592BA844F30DC407298590A088425E023B856E106437C6074547260A856E648CBA07E51A23E70D7CC65656B4692EC24277F04905C4AEEAAACD36341C705B504CFABA73201C2745AB06B056F1768447981E0D676EC904698EDB230F369190D8C1DADAA5CA59001EE8A68C302F04298DC5700C56B2B577D89CD9A585B239089847CD3E96CA80D928867B27F3657987724FF9031649C246CBCB4673F6CB8544150C9975A13938C89A68CD0B6DE5237FC8D2B7A6BB94E0C0856F00B821636801E9AC84F35276065EE4108BC1D755C1C428566A1CA3762D050458DBC7093567A4465453AB8656272A3C03B4A3C55929271437724471D5D4926109C9792BA49D117813948106D27C33069EB3C40AA8370B79E23F35934AC28666FE72B43F722151F3C26C96CC3B6A40D9E1876E55970F252811070FEFC00D70A009E4871F136A08515AB239C33E2DE638C4260D0C89CFE30B8F8E5927F2C59FEA3947FFD0BD636B10876C3C387C00E15469B42B80BFEB8681DC7715C2B248CA6FED92A9399B72D1023F9507229593BD9BD936A0F6ABBA09BC3367782370B60D9CBD0E8B3D5744101C8CA97EAB822FA4CC399B5BE3195CB1E3C9260030AF60BBE3295C4DE898C502543589142CF48DBC7505EC9A9D93CB6DD4C9678C1CC0A082C5631A255142603DCC01FC07C27D628D89F09B473816B5D5171C18A3F9737BD6D3420D4BCCBD3A5624A2686E54062CE4696E061C83BC2586F1A618639E51E63BC6C64825EB50D4F88334B29145BACC49E28DD564B7A578217FAC230AD00A44F3ACBF8753AA572D66E1AB9198CECDF9BC722455BD267FAF98424EBA4031C3BBEC8298A9388CABC6B3BEEC7A7FBB1C814811117A9D550407C9E6099CEA65ECE641F69454B6A0CA9BF86A3DD472F7C0A7703C6A5B25464C0B091B29258DE673220857878434EA14CF50054FB2E63547E9BE15107BEB7A78CD5C00CBB1462A0347E72B51A15CCB5C333894ABA511295B37C97C7F4C2EB6D97219559B40A67310F457108015AC1B8E3AE15ACF85689C4058EC8A0BB18B75615011F2701BDE8BA70986B39D3368E1F978675A49FBE8509F1239A1C88F1DF4ADF0AC8B68A87E2A403373FB808A7B1192371C7E68B80854B0E4335739090B953A2B67999F9878A32415B78C22289EEAAEFE3298FD38ABEB6ABCF5A55BCA388004E46375A729CC45926A7C3E3BC8B4E2A2B196AABE5651B642C1CB50F666A1BB6DA4D1CCE8C6344356A68DE044214453D03B5C7A2912329482F244226AE33507BA8FC8366736352380B346CA39A936190F09576C5188C5E82315E3532F34D41F1B50BCCC42C1138802CCD5B50A7846FFA7BCADD91FE757AB7FE30E873BA233E13B21D25461030593433F4F66482D94B916AA8D1B4B8D6786926E9364CB579F52236218F199C3925142B53500291A3164516FABB941F98F0DAAA1E2D619C9622D649A0408AC02D5CCB9B787C1F9B196DA37020E362ECDBAB03CCCB63B659C6347104074B1F8254499C8452364726B1294669A3A24AC8B487752175B30CBA68860184D5F78B845B107BEBA80F8750475D059DAD57CAF827878B926FACBC00B54388F24B7B431347E334FFA046C45E234124C958CF66023DCA620E1400CD5C08B89554A474D7D04086E5CBD0D051C03C4580D3442A575255C833026BC19DD301A70367FED300EF27779D2A49819A370519C7FC404ACB3FA441A931C67A3033799519C883BEA134242F35F92393DC134BCE15713DDB33E252B991AF10C7134A8ACD09408C8CB2ADA36BBC25224E8867A4138ED9B4DAF403A477321614B3EE5C7BC2281441936B0B05513C1525421871D007346BCF52D6E09B756B4529BB5480AA3165E617CEF41720167707F35A4415975A62114C7918AD83BBD8905A283D14D22B2400CB29FB1E102562CBEE5A9C10929229F8C60A4B153C430A361812E75B244E4C3954A945459F735D45572E83B505030C13867C720567FD681C539D7094F5558DC5A86DA79B38049B0A45A1259713AF2C1640EE0279BB7191F0C0EC59C2F91184CA70A2E8B7576CE493E32F2C549C4BAD6C925039C4C57114075281AC7631FF4D94EE0723C3400CB2D73C184489AA5B440AD470CDE548F2F70903D08B9B4CB6DB68A5D4FBB049A5A9727F50F9E6C59295C62BED7182CA96D6093578DD014F7EB0B121AC6FAF917FA9B47F6650C6C7336D8848DEDB92A0F70971E456E9AE625CFE266B1000C4EA6252DE1CE20C014BC161FEF405FF327CDDDA37BE4919C2A0C097D6995B0EB743FF66A548307CEE1080A13841ED12333E62EFF081514A5915022C550C6021A27889BB0421DF3A709AB2F9F3B0C0F6019FA8810CE3A9C37F53CD651ACB4E5BC1D8B231F373B7A4CA6723A9710681016943F29697B09F6ABFC1C60E8FC4C201A9AB05C260D2452C83B88423B904DF74F425A9B4D116DE0D059D96779D61017C2E984C2BCCD6159C82DFA5AE7BC63E59304B1105CA054A71D753E7E583742E715BFECC80E51245FF53C16854AE0AB41C581402221CC8834A5F4556A84C19F6172C7C80C759299A42C71BD67040A29185A45C14B91B56A4AF9178E0BBB0C4C197549B5C9765A8874686C63445DEA7A85D43AC4D0B979B4CA13A80BF8DB634A163FE3F4327210A7A128716B9805BC1920DD322B15C74FC722A126069ABB8C95BD090F84497D832A1AB72358D4193B6542BFD627A139374404DC1998416F46054D1B4B538E778D6D0507FBF5571BD01CE56362164793E58355366495AEC80EEA35463C4044B202451B3604D6AB96ACC3617ACC1015379564D6A5FF1A6AE4D802712A94422A99D90988206776055545172B0282B5162B479D748A2E9D22356AF11DAF2629036665EED0642044B76775CFD9417DDACFDCB371AAEF7ABB3C2CFDCA88891DBF808A90028D4F12C57E4985F7D4BF608793939ECBA27DFF5889D4D921C583999A57E20A48085AC549573E6ABF393308641A9A4647F230201E1389624A296B55192A9819FCB19AB77C25F95445 +ct = 3A3E99CDFA0AFF52920DA4CA405CB98307CE61FAA8BF07561C783E8D1636003E6BA1A0E38FF422D21D7E842D98ABDD2632FE1209D662E08A8E3E1459DE3D8F206C6FB378019611CBEE5A835A23AD221F07574E9AE19DABA2AA1E619D25CB73F7AED357D2A68BEB6CA21A905DD876D55FD28B251C94121F4934E8046DC44E31821E44294AB66A42BDC3A0C87A74352872FADB4CF156977B539666718B51F3F725E0F4BE96AA399DFF16802666ED4DF9CD2D83470B90E3BD5B7CF395D029082F0923285CED2148A983AB4D11F525CD9043D261B15EE0D51287E85DB7FDB7215C3363E5E6D2DBC93A546AEE48705A40BB9C8580864AC705499639E7536DB42044D7DAFC6D3ECC7F843CC1AC3374EAD10F60A0F7D31414C3893777A43FC2D9F99BC46D175640A105A0E297EF62D8BD7507A54060ADFD1654AD8446D9B359E6C331D9112DCA7AD22A5A4319EC7FC9BC4ACA3A32CD5F4F34FCB1035521E46E52FF8538A4AD7EC024E9C49F03A6720C55514FB874553875CAFD8924DB711971CA4BCBF8F29BD7571CBF318FAA88E2BD408527A627A1268C96979505FBE85D47720C01DD721795C3A75ACC8DE5184E8EEBAB9F1FF4C4D12FFD3A7C4625C23A2893B1A4C45F4544530F3E9AC72709684B3B3DF2E47E405E84A5339073AD3BBB6C20D9E2300998BE532DB686DDFA4D8EDDED3F5EF868EC100B1D517197313165ED23EC974880D5ADA8D915549121EAF1F0851D9572844D804596573CE5C1A32D2C7BBA0E8FE1190FFE1AF0280E6D781DD31D767FD38899BF7D46BBAD2F7AC2E4CB5FD6E949E259E1EFF9C8A27D8C9C383BB02385C47635D7F631438C560AFB7E4331F1FE6786B6F07379A1CE0A68FEA618616E3F1E5D59C9928C98BA8F00EB1011641F0B2718AE378E4F9CE04C5A539AD899988070E4FFF6CAED2F74F885FF9541BB6B3B713C12FA642C86B075489D06EE26EADC5DFADB91A619E9BFD0BC00B9645605B4B10E5E4029CD30D53C98CAC5C449014E460674F41664F953F624AB6D15DB60365C4FF87AF8993371AE1ABE09428DD55A04154D5A6183D7F2FC1F02B714839A5C7A1EF97B96A3C77E5032191468C43A43107004857F360A0FABEFC62EEDFBE21FC76D148FA89E435CD0004460FA6DCA391393AC3A2E4351C6DA5D9C504E49E8A3988FCF260DCAA781B2882897C6C6913DC72B813634FB39A67C7D341CE8BD5494DD499ACC1824F7585D9A0AF542B8C8D50C6CF42BD79DE25F4575AF276544A3A55B11081CD798053B56C36BA4D0F4BC68E197A4B6BFF7F00E5A3EF02878D5333C0E35C4288A541EA49991C5652D6B751307A15CACDA2774D676EC53C0D36535ECA12BD7428660FA8A8C1C1BE54CEF68D23DA94C0BF547B3EDF5B3D4BC618A5CF67D96A9E8F71839098404573C83E3B0E6CD698B1344697BD4E348A5D56EC3D87C32A1B083C21845251DBB844B16EA2528571E42B631F5A48698658AE63ABCC46E36E721997CDB747F05492BA5701DA2848617A84087D31D040F1DD2DEA513AE87C4 +ss = C870A7BE3DC7BBF5836727E5BD82CF977B1332E7DB276473E4029ED95204ACDA + +count = 63 +seed = D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC +generateEntropy = 7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +encapEntropyPreHash = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +pk = 8E892A62437CE84445F2E82B495C9730FAB393DC6F3B36BB2A63759A79AE27B162250076A608522440AC1E04630BA766B4C256341C6AC967B36E6934DC58CDA15621827B9558076361192E89708ED88A71826A20E8EC948B9C7915566C70A7C15A72C36ECC7A3CC644EAE696022657C53500A0F13A8AE50FDFA432D8D2530999275E5B9C1D341FB34B8A5A7421B7D290CBC3218486B555C92572BAC8F1085F058A87FD48796824844553261CA11F06978A03F3A8D68657C22064AF83166280AF52270E004731D20B18982283E51CA3DB7A2679DA6FB0AABA1E75A2D283ADD699A797E1BE93502C6823007BA5B9760A338768615B671BAEDC6A6A6937B9E1C35575776A4A791FEC7751079C6683BA29EA28BAD199175B9629C44BBF219CD88A19F1089AA551946E58032A9C9DFD29BC4CA3B654F494990CC02BBB8E1280B54BA3920EF98903F171C27A5C0FB679C8E84774F22136E89915A534D973733410A96280A3207407235CA0D81A636A35B9DD628DEE9A64A12918D0DC6D4C600989168A163730FAB8C78E61A57970C16C813B791A0EE9F625C438CCD1A9429A93062C4AB38DA5890188829AD116A6F1564A43A2E4F3BBA3712207B65E701995C99B29D691C86BD9844AF2471EB5CECD934F764629DC25839C809432E395FD8582CDA980359246EEF0637B9771FA5853099007F173C8598164DA69C8E67A910A50B9940B213547815E0589326B02FF21B89BC4200219652DEA6CCD59883E29127E2ABE3787738B124D839A67E02195D64989520737E3AA99C6822F2C32249256C45455CBD931A5A1FB27CD56A21E22B51C03217AA387E151631CFA445B2B77EC90AE01828601961ADA8A8E6192104F02BA5064C4EFC27CF2DC3353FC98F34BB947B21EC5235FBA6CAFFB6BC6B1C09A783AB8EF14C4921A28A3896BAC07AE8BA98C117B3624E01ED0496A8C649A38A33FB679BB535A7D1960028CA6C8BA825178E74F0E50B5D74C2A9119B595B863D0375A3DA173C63A03D8C60A8D613CC08064588890E3894A9BF4580704038841526AB84E27CABC8FA4CAD6DBBDE9B53017F100778478B86138FBD6BE713A7E695358538BC4CB5A4FFF531BFF178BB16ACE5A295CA0340985F34267A3A931998B29A36935D3B13AF0631CD37777689CA0B43B9208AFBAB88EF886A8672B331224C66C6086B8B15A8EB86107FC0AE260BF08F970CDEC98ECE9A197751B6996258FFB6DCE05306380770DC63498E9B5D65ACAC5A179D8946B27630525B39C3755C070A120C9F468AB3AA8B1A48848081B888BAAA1156BD600733BE887ABF962C46107C432C34EDCA8E549977D9A6F7EB77EB9974BB353896E8261502820F599257CD9C2852328B0FBC5C2B98658D67E4A636575A46E074A1EFDA2CFA50A0594B0A421661D81D95A9AE0CA1C037532BA7EEAD089961C29765C443D428BF20767D1F08615E85D0C08B0FA5076E297143249283C13486F61A4D9D39780624055D6043120A510D4A686F9B490C74F2DA782AB42157A00991BE019E093A509C0C00B7C1E6AB611DFC4373C640A2F488E7632BE1289666206CBA2B096A479B2140C6AA301BC448B13B6839447C4675AA1BE46EB6ECFCB4DDF2569B2D79ABE93FCEAFF0F0FF88688C870D19759A41D3D361A0CEC73CC908F52BAD8 +sk = 34C91F6EC981B1830501D8969F8847B2C6BD5D5C43DFA044C43B551E610D5675BB7E7C9E393B411E69575301BF4EF4C7FD0B4B59E213905A254EB5540ACA856C370DD28899541B725091C23907C04390AD32A56385075F42A7545672544FE177B74C7ED99507E4D95DEF7C4A9F84C9687B9BC318A23EB452FB7635D5201165A47391D21A7CA732FE9B3455C44EE4E54FC3A6518D51402CD5A2D49429B9C8815CD4B1A22C59ED368ED6C7A9DF83B958CC83C4654C5CD040245543431C0D2C9091376611CFDC2EB9181B21C8417E3931AA2B1141C1051CB82ACA4BBBE6DABDA3356BBF4962C3F883D0578580477AC56353AC7524F3855DE2B00967B7BEE0668112D51CCBC139FA73374DF2685A3CC06838B150F92A64C17772053DE2B05CC4D51832B8A2B8428436D99E1F2484B127CE0D861DC8A11AB0B0019E0B3439733B36A7A600F4638D820BA5624B445349A86465E1B25DE787207DDA0B629CB472D415A42A8BA191B76B5829D4D987A2B0C235521C187A0BADDB603D755EB37396CDD57FF76276CCCA997B00CD481587CB8728830021DCBB8478A267B744A5BFD08B4ACB2C1E726121996E55B60D40F6975637831C392845D6823D4B9092151149992794F4AB29D4164A44239F07C365A87ED9786AF7A57AC0BC0D491018007B6BF7705A21B082D1E040A4F4C25E329EF9A8518956044E7683AF94728487A4F95305D4E15AAD45C040F1CF9C442C519B2AA47A4DFC29063243C21F8B838171701B4B73516944EFC4B61FB5BCA63C3ED12A123F55B832E6C312E8BC48F145D62953F5901F7530068F2C9C9F51CA8FCB342852936D414FDDC2C04F551C827071F99C7C24C991F9C97E10E051694C86789A9442D79092B6547D67AF70D8C8B074CDBF854718A882DAACA3B8EAAD0BB1C2D3E859D3EB03C0A23B290518EF88CE1BB02FE71399EF71B380EC1AEC4C7C6BF3830C1B15F7718D0E471D10234393D94FBD3305ABD09CDF070A0ABC09D7497D2F9B939794B923EB3F28B40904A53A05216A526132D9F3CC64606B40F26434142645D79481A8316E8CB0A9321A4C530A0AD139ED5953168A4AC864C726874E1366AB09A249F251CE5B1A7F5CA60AD66375BFDBCFA3D7AD23A13649C03327D409FDA64581CB00A696557945C58E96C1C889BE648C4885958ADEA79AB212A0BB15506BF5635E437ECEE47B60032B4273B8C96806639C87031B6E23B71996B4576626124281AE4CA0A8FC081E1C91667967B25F76C4F72624CB29BD0A865FD67A4DBF14ACC7A09871BC7ADEAAB37B298F12B60B6372B741681627E4C8346C0D34392716EC173B1B711B1C0A1D010DCA486BD5167223658A5C55BCD0739DCFE30DFCF9BD8AA45B3CA0B5A90243547767A1843E4C87922031819EF9249800C6DB8B0270F9CB8F2624ADF4199741870B0630E1BB1B325768C79984D5E33283A991BB3C98B6BB8BE0EBAAC47C4310C51EB565BABA36BE54F6A3151A104911C38EF78E61F1654EF35B2C836C2321A52FAC710D6B03811444DE5B8403569C8CE0444EF615DAD54AE5649E68AB437C00A2C9EA9B18F59346D8B2A5C6582D763730BBC7F24A7EE7C23607C0683A2826FBB4BAD4A58FF6E3BB3122BC8E892A62437CE84445F2E82B495C9730FAB393DC6F3B36BB2A63759A79AE27B162250076A608522440AC1E04630BA766B4C256341C6AC967B36E6934DC58CDA15621827B9558076361192E89708ED88A71826A20E8EC948B9C7915566C70A7C15A72C36ECC7A3CC644EAE696022657C53500A0F13A8AE50FDFA432D8D2530999275E5B9C1D341FB34B8A5A7421B7D290CBC3218486B555C92572BAC8F1085F058A87FD48796824844553261CA11F06978A03F3A8D68657C22064AF83166280AF52270E004731D20B18982283E51CA3DB7A2679DA6FB0AABA1E75A2D283ADD699A797E1BE93502C6823007BA5B9760A338768615B671BAEDC6A6A6937B9E1C35575776A4A791FEC7751079C6683BA29EA28BAD199175B9629C44BBF219CD88A19F1089AA551946E58032A9C9DFD29BC4CA3B654F494990CC02BBB8E1280B54BA3920EF98903F171C27A5C0FB679C8E84774F22136E89915A534D973733410A96280A3207407235CA0D81A636A35B9DD628DEE9A64A12918D0DC6D4C600989168A163730FAB8C78E61A57970C16C813B791A0EE9F625C438CCD1A9429A93062C4AB38DA5890188829AD116A6F1564A43A2E4F3BBA3712207B65E701995C99B29D691C86BD9844AF2471EB5CECD934F764629DC25839C809432E395FD8582CDA980359246EEF0637B9771FA5853099007F173C8598164DA69C8E67A910A50B9940B213547815E0589326B02FF21B89BC4200219652DEA6CCD59883E29127E2ABE3787738B124D839A67E02195D64989520737E3AA99C6822F2C32249256C45455CBD931A5A1FB27CD56A21E22B51C03217AA387E151631CFA445B2B77EC90AE01828601961ADA8A8E6192104F02BA5064C4EFC27CF2DC3353FC98F34BB947B21EC5235FBA6CAFFB6BC6B1C09A783AB8EF14C4921A28A3896BAC07AE8BA98C117B3624E01ED0496A8C649A38A33FB679BB535A7D1960028CA6C8BA825178E74F0E50B5D74C2A9119B595B863D0375A3DA173C63A03D8C60A8D613CC08064588890E3894A9BF4580704038841526AB84E27CABC8FA4CAD6DBBDE9B53017F100778478B86138FBD6BE713A7E695358538BC4CB5A4FFF531BFF178BB16ACE5A295CA0340985F34267A3A931998B29A36935D3B13AF0631CD37777689CA0B43B9208AFBAB88EF886A8672B331224C66C6086B8B15A8EB86107FC0AE260BF08F970CDEC98ECE9A197751B6996258FFB6DCE05306380770DC63498E9B5D65ACAC5A179D8946B27630525B39C3755C070A120C9F468AB3AA8B1A48848081B888BAAA1156BD600733BE887ABF962C46107C432C34EDCA8E549977D9A6F7EB77EB9974BB353896E8261502820F599257CD9C2852328B0FBC5C2B98658D67E4A636575A46E074A1EFDA2CFA50A0594B0A421661D81D95A9AE0CA1C037532BA7EEAD089961C29765C443D428BF20767D1F08615E85D0C08B0FA5076E297143249283C13486F61A4D9D39780624055D6043120A510D4A686F9B490C74F2DA782AB42157A00991BE019E093A509C0C00B7C1E6AB611DFC4373C640A2F488E7632BE1289666206CBA2B096A479B2140C6AA301BC448B13B6839447C4675AA1BE46EB6ECFCB4DDF2569B2D79ABE93FCEAFF0F0FF88688C870D19759A41D3D361A0CEC73CC908F52BAD865F03ADD3941D22C80D50659F501F8CCA1B448D84462CCB93D5F065889484BC0EAC9D531A532770837A854B4F5531F6E0C8D6C10183B30D3435498C2DD142951 +ct = A37E48A5F89B418765EE73D585AAADF3AB787504364574B84C2ECB3373AF7DCA5582D287A60588C9514086C3A56486D832F0BB56499F22BD19F437505760C1948B04E6DC667881565B63EEDE3D6432F073C7F9F3569CAF3E9E62A6EA7E6B2C2D290ACF3502C87C9702681FE4C6A5CCB0AC957EA2ACC8DD68E574E64508B5C3F8823E8E23ECDE3A8CDA95136D4784F2A17FF9E0E4132A48F1FABF69AD502EFC4DC4A2EB5C05F56FDA2B8243FDEF423D1DA695966F6BCE461B2468F5603B78B1BCC9E8DE0DA3D5CEBDF71A4A2DBCBD653929742EF45E550B34A4B55CF6832347BD9BC0CC56F1CC72F2D92C37689FB2CF08B37D3EC7782941DFDA884F43D58E3CF9DD73F359091DD89D2AEA83C0E5D163775841D41CB6B7E1CD1DAB4C8396F507613E2F842059F5CD8F8D5EB60DEC519AD7D3473A61A1EE79B6EE2D2011F72CE44FC72294C1A8147A6C2C6916D1A88A2BEAB3E886E0B11B815C4C9AA57A253270DD14FE11590ABCBA02E750FB3190C486FD754247FCB0219634A74ACD1F53FBD3A193E6F36049BF3C920D2F0AE28E6F3F70C414BC5EA3660E8D192C1DA4AA6834CCBF2CE4F7A943FF6B32F0246401F6EF6914F5584551290DAE6C3A97F346551A481151796A507654E99819950DA5CE8381F142B3F6AC31B0E6F8B34315FDCE5A024928EF205C2A6A989266D0A4123A5A98CDD9002C29D19D497FDC6F0C77F3B4B1BF569B89DDB22A73D0A59C518B91321277064EE8C5C9765E54C99B60BB9ED63E2D43D9EA7246CB6F8CAD230FF95B622F64748E5E2FCAD034754069997DD003A5FBA93B8D29476C91FBAB4FF0B90C180ACD747EBAB9CD7066F995FDF389874B926478E4A10EB749455DA26CF1D7E78D119E34F0AF246FD5D7DCBAD8479E85C51E59941A0B0B0DEDEED9508DF28198DDCB34624DDB45A50519809A2931594AB8292E96C54D5EB7342355083C2B6206479B50ED7FBD1C35958A94017D40E9E86A5C442E9EF5780357E47AE64631B2F803427F90BC408D3AB639C065F75183249229D8C27716E137891BFF8EE4EE1467B61708E385ED429624EBA3E53440F3248E0C32DA91DED4F934CEC4F872B78283B8E701FA635C941569E113F87A92373091A78DAC58B4AD5521C8472C9F145196D0B594C73126C226B7625D6B7FDE4BDF56E3B32E88ACB3575DCE80AAB36A1A09F9B646AA12D60637EABE185FCB81F45D54C952FD721FC74D761BBD405D50730CB81FE7A6D45B3551B8DC57A78491BC41A310F2478AFD09A539B2AC1545C4796B11DEAD5C4CF2D7342A13B7AA8CA9BBB86BBBAF965DE4D3513EE114F53FB1FDB4C52BB638B2A06C9A93FC93C50458B4D3AF86274258B43A7323281C4E7F2AFF58B43A414708DEC53F4BF23AB3EBE2BF3D51547472F4857F84A697A339AA184FF98A0E980438CEF69EE243B112D5F182F071C4F7BD78410867E3A07D274A7E4A15BD04BD6801D19A3CCA7F50EC6C03D5EA9C495737D71AD9D3A019CBC2C6FD5954680CC6D63722C4AB581BA095A39C29270DBA +ss = 3A14474E05DF3FF59C6105B1F2AF004A8B8164DD049EB6929B9C9881A873AB08 + +count = 64 +seed = 5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93 +generateEntropy = f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +encapEntropyPreHash = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +pk = 61101724795296A2499158C8E1B50E4C900D65C8AE65503932DCA40E058E8192CEC2A997CF12C8A1227567B12A1B21BB31D3198C85C4878C6EA1967668E3952D04B4123CBB9CD8C77F3A7397A9133D99654E6C56E7465D9B98BDBD624C12E36C62B60B6A32C9086A8EEB9B8919706F4573A33C393F74BB51D5609231F1707E152F23F36F6C6830EF28253C8CB81EC5C27ADB02FBDA5302212826F0B88AA4B4D72A509E29CB1BFC8177C019C60598E693BCE999AABC4621123415235208E7869F62AA7B50A51724C13DA2DB59D5BA5302C772F2C1820FB0882EF32F73321C17F40D019CAD39C3B12C57C3519CA0B38366AC4353B133C39262BE6EE47ECF660286F6CA8EB7090418ABA0D9833E22B46B761FA2872FB80972B551809C02775BE07C796636A2C619FC748B90D28E1E702FFB0653E250C8C3759178C39E42411327A81C7E7887B21915A5CC032C37A11382C4D9186221B1C66AFCAE8184559910201C8BAAACEC62BAB984E080433B9465E64A2D987028E9D9090CB2C41753742CD77F0998C672441E83D45F2D06C22899C2136362271B731F6BA3965B32E2517463E627AECA0AE5644BB8602F7FC599ABC120AA111E2E549A276A18D2A92C39502F6F9519CE76C0BCB514E8084C7122A321479338F59ECE08A0ACD30F0AD68F2091855D5980219083398A6C0A63C70D3743678A1C0202A69DC526DDB77E30B779C36AC2575704EAD94DDF1661A38B2624E733F2E2AE18467CE2C3083B75017411390314AB06ABB4D0FB58BFF99DC3949E92994703E85FB6B863AE1C29BDD6656CD75D9BA453AA115A32745F2DC1829881A9F4D5CC2CC053AB79B89D107E6054C69DC93F5AA9C8CA6CC1A7583F2E2739B102378D93990CB8280B21A5D5BA8415C48EC17288044623A9631577C16639922978258CEE0B6C51BBCFE3F70BE07CBAFB7C58111CC7F2F922AA023D5AD01D2D31A57E0469AC428B6FB88A97D957AE22BEB768C3CB7C9F02F583FA2513DB7C580D2986984314E8B346A06501D8972E31AB8EF5B983E9A15E8FFC624D0041FD523570960E09E57D616A06297BB3F9D938F5655628B06C4F6C4FA5F8136F8CC05DFAB7389237EA75AEF46117BF1B67AA978BA622491260128E743F28F95F533B708F3C59230B23FABA96FFB5C239B32B30A65B36FC5A0A76B76F04A60C9C7D5EB78EBE44B736EB56A0812F59D9B5812916246228F2523175242CD1F432F9FB054A8B52D824349DC0756091B2F7C21E2A899362157BF9F631287B90D6C80FB55B1469273F79892435D031B62982C49A1464E2274F815F56F3B6F8C949BE11388DF1151E7077F603AE592623E4259853A2B90159344B041AA29C8AFC5074BEE81959102E0C57A761F1B1AA65B1DCB66A18BBBBE12B2B2942A37D13C77C77B2BDE758EB1901F74C7D57D373A47737D6E23998E35DCEE70983359B4162C7135126E90A807604034D52ADD3530456B66F0DA64453150AFBB67D67D9B359137C2420250C279A1C537AB06952E4823F09372198C253D5B71A7E70A1C48B1DCAC3A85FEAAC35A11E670B2840A57F2A7C77B6A00CC80A282F0A1C8160080C702D619A6B6D68C757306C93A5B21BA8185B1A46C79B03C35880A7B265A3E05B2DB868482FCDBA0367177BBBCAD04F3A50ADEB85DED90BD59DAB +sk = AB4545850434076342EAE8409FE0590C34955E860267305FCA05C347BB3E53BC714E3134A6E9B338674A9AABB02F021D1A09A190757F03D573C27687F7E35F2D77294D10CDED732218395B344523F1B704B27689DCC286B5C98217F239C159AE5D655436F00517A50C6DC6B7F4F111E7F37A0F319BF6ACC7B0E3345C9367B2A2B8D9D644936220C0A817FBB38CEB3469CD55C661E1C58D06807504443448C4E53204DC59C60A5153494478EB4056C9A85967A42EBBC287AFDA51FDD6B84B285523D41D80A56F7A68A168A4527D902311B18D5E381CFDD578BB7924FE687D3AEA5607906815181171A727E4DBCE1B678762A8B03C2A2BFF1635CA85332AE90F14B880C5EC4E5389B7816AB885C44A8D83C5EF0C4C754C7B6E673D984938D3CA4EB0F5B83B90BEC27172AC85154EF27B91623841E188D76B040F958C38C8A112C05B54103E55A159DE0954F2477E798A573339508B7C2AC3872A623429777BA3179060135C083E2198D1E0AA01967C39C27372A1A36A92BAC3BB13EE3C94B1F0391E2702C50253DD497F16F39BDCB9C68CCAAB6312084884B113E70F38555422767F4E613B2E87AFFC01395FCA37DF0A1AEF74263C1001392732D9D1047CC7C6FB910AE6136C33094526876A113514F2918909532A759617DBE2C97E72176490995DC82B663655DF65324B1996A42150BE41B2A1C90F03B2A6F04174DA1B1CC7FBB024C3C972B9714300C683C28A90F48B01C28607922C3ED25601A609673481B365544B7C36A9550EF20C37005B0E395A268E90CE1A5271E1421B46303B80CBCC81E2894D7569E82C2F5D8C6996C766BC505976628CADD84A3F468C67C209117C8254BBAA1BA584DC2661728A69E959949ED6C9F1B42F01EC8E55614AEB7168CFBB5E16504EB9F585C7789C48E59C17B5975C444BD6E32A6654BCE298A605043BD367400C14B1D8E1A592A034543C04A44C85711AA66C807FB07378FB525600C19D9A4A9A8C920BA7DB0B1D912A45F2B6D518B469E9121D25CF40499196376D3D92827E1B96AE255AFF288037793C7DB07E1D15533C07162AACAE3255C0CC368E2FBA3FEF09540952910EAC0FB2F3AE376AA666FC97A3E122570CCF797C79EC575835E0BE6E808B3CB1B72D8241C3679BF15020B6A63BE65B95A2C9147EB98C6553C71C550E37603E6B73C877C94E7B603A22ECA456C1409D5AA049673D0EA17C123B1835692253FCB589186BAA498F39481C3D0640A4D34931033B30F26EBED6CA9C49BA6FB219D6DC8461937284235A6417CC9C0CA0AD385B04B01C81D5A7B97A34977250E3679AC55C3D76D83B1F7B99DBA039DC179147223B5D6C11FC9109DC062A1E4B7C88C710C449320949BB4405B28EA2C04D48C58AABB46EDAA58E442F3AB6C9810B6D702855F7CA91AF71B0E574BAC1040DBE864DDAA76827874839414CF3418D1702C6F368A10714CB25E208C8A5779F639837A07E348841A11714F41399DA175C49678307D3634D6B9921880FD43CCB8D7842E5F34CE44A4923E7CE6B671C7A989AA748604D147CE7AC25A1533E80AB321B7AACB8D523A3A6298BEB0CFDA435D77714993173D080827FB07B7855769EBA987696AFDF58231F361D61101724795296A2499158C8E1B50E4C900D65C8AE65503932DCA40E058E8192CEC2A997CF12C8A1227567B12A1B21BB31D3198C85C4878C6EA1967668E3952D04B4123CBB9CD8C77F3A7397A9133D99654E6C56E7465D9B98BDBD624C12E36C62B60B6A32C9086A8EEB9B8919706F4573A33C393F74BB51D5609231F1707E152F23F36F6C6830EF28253C8CB81EC5C27ADB02FBDA5302212826F0B88AA4B4D72A509E29CB1BFC8177C019C60598E693BCE999AABC4621123415235208E7869F62AA7B50A51724C13DA2DB59D5BA5302C772F2C1820FB0882EF32F73321C17F40D019CAD39C3B12C57C3519CA0B38366AC4353B133C39262BE6EE47ECF660286F6CA8EB7090418ABA0D9833E22B46B761FA2872FB80972B551809C02775BE07C796636A2C619FC748B90D28E1E702FFB0653E250C8C3759178C39E42411327A81C7E7887B21915A5CC032C37A11382C4D9186221B1C66AFCAE8184559910201C8BAAACEC62BAB984E080433B9465E64A2D987028E9D9090CB2C41753742CD77F0998C672441E83D45F2D06C22899C2136362271B731F6BA3965B32E2517463E627AECA0AE5644BB8602F7FC599ABC120AA111E2E549A276A18D2A92C39502F6F9519CE76C0BCB514E8084C7122A321479338F59ECE08A0ACD30F0AD68F2091855D5980219083398A6C0A63C70D3743678A1C0202A69DC526DDB77E30B779C36AC2575704EAD94DDF1661A38B2624E733F2E2AE18467CE2C3083B75017411390314AB06ABB4D0FB58BFF99DC3949E92994703E85FB6B863AE1C29BDD6656CD75D9BA453AA115A32745F2DC1829881A9F4D5CC2CC053AB79B89D107E6054C69DC93F5AA9C8CA6CC1A7583F2E2739B102378D93990CB8280B21A5D5BA8415C48EC17288044623A9631577C16639922978258CEE0B6C51BBCFE3F70BE07CBAFB7C58111CC7F2F922AA023D5AD01D2D31A57E0469AC428B6FB88A97D957AE22BEB768C3CB7C9F02F583FA2513DB7C580D2986984314E8B346A06501D8972E31AB8EF5B983E9A15E8FFC624D0041FD523570960E09E57D616A06297BB3F9D938F5655628B06C4F6C4FA5F8136F8CC05DFAB7389237EA75AEF46117BF1B67AA978BA622491260128E743F28F95F533B708F3C59230B23FABA96FFB5C239B32B30A65B36FC5A0A76B76F04A60C9C7D5EB78EBE44B736EB56A0812F59D9B5812916246228F2523175242CD1F432F9FB054A8B52D824349DC0756091B2F7C21E2A899362157BF9F631287B90D6C80FB55B1469273F79892435D031B62982C49A1464E2274F815F56F3B6F8C949BE11388DF1151E7077F603AE592623E4259853A2B90159344B041AA29C8AFC5074BEE81959102E0C57A761F1B1AA65B1DCB66A18BBBBE12B2B2942A37D13C77C77B2BDE758EB1901F74C7D57D373A47737D6E23998E35DCEE70983359B4162C7135126E90A807604034D52ADD3530456B66F0DA64453150AFBB67D67D9B359137C2420250C279A1C537AB06952E4823F09372198C253D5B71A7E70A1C48B1DCAC3A85FEAAC35A11E670B2840A57F2A7C77B6A00CC80A282F0A1C8160080C702D619A6B6D68C757306C93A5B21BA8185B1A46C79B03C35880A7B265A3E05B2DB868482FCDBA0367177BBBCAD04F3A50ADEB85DED90BD59DABB8A3B8CF4709204A2FDB19889B0022EA655DFD58FF27E17D530510E1EEF457933FC3D8392CB53F36ED647364A04E37278A0E0A45B720F4A75C580C9920EBA98D +ct = 25E080415EF5CCB5D8C322634C5DB0F0ED10C73D5A0BAD7B2C5B899D74E6EDEF6B2A8EB9DF8D415BD41DDB01F670B8939D464561ED8C37A2B2217A49D4A0C7B5BC13D4A481FC383BACFC6CB979901098929B9FF7B5ECEB2BC21BCB830B4556C36151A386E2479297066521935A10D3F16222B9246C2885FAEFC2F8597D4AF4F13EBA79C30499435D93420E9F2E46BA2D7C54244A3EB47165ECE9255511DC524D697D13EFEFA8B62B6E61461FEA69830593D894016E83264103A876920663383E13BDADCE37A85D29744751EEEAC229CF89C282A56EE0959E46106E12BD94F4ADDC061442DFF73D7DE2D6AFC2AAE8230A88E53E7E4978B6B897AA6AB040261F9A5BB22F578BC03B0E81D2CE5A05A235EEF3A6177D4064443E20D9603EFC34816E688F515E5A48AF57A98DE730B0F5747D9F3F691F6BBC5F88A7B137E9244EAFBD539F9FB4F2989AE16881DF8036B3ABAE959A2FFF2313EBB7D044EC566A8DDFEFF1114029A30E44ADA4DBFA56CC1EF04774721A507795C10DE58E35F3BB1B1DC4D62095FDE786821BB410EF6AB4972B0A681DDD1A7FE8CA50828DAA7D5D19865644528C2A5A4C475A6B9BD3897E8DCBA0499E6DD75595ABEA0A485F7E41A727353DBD7D45ECB0AA82E39FE03B177710F6180421A465C1930EC9CEF35797E708227BD67451F8810267016EB07116BE1B4327902F538C5512902E6E64364B9AB0392A43892D4396549DB5EFF4EA7DF6754E34125E303311FD6F1CAA7F90D7361F201AF5B4D2632FC7815FE27B93E5B4251A4B1FB4717726E0182EFC9E9A07568871F9552DDD1C986FFB24B88F9EA5E591B07CB8A3E207053D3547950A5DC042B44341F6D178975A9BEDC001451BF7FB6CC4BFAB92972CB5E4217E28A21B8664C6C405C642A6E6400973ECF0F3FA7430936BB58F7D62EAA15F469577CCF957459687ED56713450913641DF199A0747C840FAB4E2B5F7323AE1E736BA0DCE06105327168A457EB1CF4F4B6C5E89D95DE5D9C65A6DF684812D00A22E4890F18EDED894472EF37DC078ACB3BE6997E0E4B34A6D3475056322E3B19930CC5C3482051DD8E9EFB5FE1A288EE3D9CCD181B57D41C7C66BA732707902CE5B9806F63621FD064F387FF413031F04502B482BBFF950BBBE9E854F8E58770A55CCEE324FDBB830FDF4CB47CC579FB49CC092614CB5789239C96D281BF065326B8F58F006BBAB07602C0657A616300286D89C5FDC2CF0D2E4A43152198755AD777C23A6DD8A9A8E64832119D0818CDBFE3CBE8B7EA5E2739E54790E0685203B2CFDF8831E339968B4770EAE40CA9A0723BB1CC9BE0FC4CBCB91A29514418FC04CEE2CD852A222A131927059AB5233FA77E8520211F42BC91FFF9646EA95434A2E867F8C0D4B43FA2E7B72B6C0E2AB72CBEDA1F8538E20FCE37FE6E0B9C4E03A9091A1D7F7B081B2B220BCD0C686729E2CADF8DC00612DF4A8AEA565CAA001EAA4F4309093ECC4FB9FDA290EAFFA313C3796C72F57EABC1CD4FD58E272C9B1471A3806212385A4C4 +ss = 2D26F4DA925E01CAAEAF4A89F5CE81148A000F7A36DFEE74E059A933D973DDBB + +count = 65 +seed = 905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B +generateEntropy = b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +encapEntropyPreHash = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +pk = 657B941F466659FCC971C1174AA4459551848E7A116B751E5E4022C8F2A4B3152A1B26A3096539C9B0BD6A435EA1E33413AC4D5F401F5DE8570CC11CD4BB9FAC473328D55501702743E2C8D1B97CEDC8AD3D55B67D284158EA8BF1A4A8A17A9DE6D5669E8B9571200B05300CB30BCEC4A58B06F70830C2B32D28992B70427781854456129CBAB53A7C72FF557193D3A221D06177D002095BC04E993B8606245416C3B998B01716AF3B43A535F7A6BEA71270B34EC808CA00E9453AE660B732963BA634F14378B1691A90E3708125CDE31BAE3D10451A5643F526CB790A8D6E091A725681FB539E9B05BDA7B04C48A31B39DA6E39E6BE624663B6284DE9F958C50149CE4090E6A486B68511AE90A0F093297BF090DB3C81D34400A40CBE11D74271E23BBB7A49EA875EA7F7CC25516A899198362ACC52C8A8CA14BEE12BBCEA9A6E3509B6887A3D1D4C3B2B4314C4C44F44C96F48B29A8E7B85339037ACF131F2692B7E7A49282237C8F37267C835C24883D1A189D4DCCB7C6BB1FE622FC31301A6D3612A448084E0A210449B7E15A4FD84A9A538B2D5844DC170C911FC1282BC513E8C18C469A01A548D1CE4853128A03A8B1D369B353C3003B0A29D210AB6AF23ACD010AE3671493C774EFAD8B3746180746401D0E5862A3265E7969F247C954955B4AFC13FC420143C10263EB1C6DABBBF5A8857A7F3BEE7658C8399503C21A9A38BA554132344E214CD2036C2B30D0770CC5DD87ED9B246E7F955EA926965748CB9E58351A938F7E4AC249CA5C970CFDE48C0ADE051BA873D36A581E0FC50D9583109A79549FC5B32BA432444046AC0A66F3C64AE1498F43B1B36D8082442B5AAA7BBCFF2C4CDA8C0C4D2C62CF9135A75709CEB5B82BA4EF5716C4986A36BD7B4AD5C3A505869FD34AEC2D7CABA492F4BC30D232382B2651D5923242BB50DF87092ACE5566BC5A18FB2925CAB467B641DF7B5B91142318D120456245F2F0887FF13516D23216637393C469CE1F776CF2426C6577844CB3D4E0A92ABA85FFB59979A7C33EAF51EA2BAC9862160BF8A85553A3D4EDC05DA102106F632C91B8D1DF2A9B2734185283941EBCDFD788107B307738786D6C0A0E7D4957DFB17488C5D6CC11B83E3504EF2923034A06270563E18A18BB29F48C36A64C132AA626DCFC5A615E4416DF76746673E500186A117A27C5007A4B04867213C33739E27058ADB23C0DE35CE6158C99E59B88B147E2AC05F09F7C0A414C3240ABAF65C24CFDB6857ECA66BFC58E52472861BAB1E03CE70D2115480B443A9BF799379AF9AC978D0072F75BC7923816A189DA5974ED948B8A709A8191CC9BE60AC2A383A7E27CC62543A2A0CA9EA6897D284AE79B595D0893514F75DB35C9254B7AC47260785C1B86A98A5DD733D3DC2B947D148F698C5A117821847604151068412268169C86D50BE92D77683386025704575177AAC0B9D3D3196A610985E860E2F799F480B1331BA346DB0C379CB1833223836D88FD4E11DBF2985825C78330658B9A189233BC76B172127BC7A98E6C644D28DA7B0857F67157AE2C27659297C32A7EB653697A295097A32AC235A11887388265ECB3B46A75C865C239395300D0F8152CBCBA77B4D655C9F1EA4B448FBE32C4996FC298D26CAE25D276BCF6E66BA65E3E97791 +sk = D7E3338B3CA1D6118B7485BF85AB9E8F6C36E158B67D2C3530B0A544B8AFAA0A8604710987429D0D1B1EAABA8F06422E992C475DC4CF909061EFE673A3547575E8B00BA47D5A158C22E6B2C280B3152165A5A01A43D801E96791B6D99C92C0B0602C94C0B13F2672146A7044E4372C5FA8843FA7974692B0F292AF9FC3B5793092C705421E6AA39B7B3EEC76694F5555985A94879ABF737949BC33CFD1F8563565B2F345B6B3389FE061509BE046B3A048A73599AC20466F0707E9B46045352F94507659BA428CC6994EE3375B07D09AD3BE1872C15692C7394626CFC01BF5435D7922BF9199533A22CC4FF021A97C571DB311485B36E2A3344EB880C67819AEA18B09919FBC57CBC11CB228F8C24F38A445C512245C3A5CBC65D20269EE849BC268899981B9F334704499B60A891139D9470A1A147F38470752C4EAEC5B14D51817FCCA22E7BC1C585CD2189131960A9E9284AC7940B2949707EC7A67F22DB280775D8163394A3A9557BD48F50C26F177FFE83030A3455DE1196A763F8AF156DF73CE3BD07AC70447573A79DD04A59E8B40E39C6FEA736E14F1B1B67B5CF556C3ADB29FACFCA4E6D8B759D37737863DA2A7AC4A645A8F202AD61C17068385C21415F7E14146D896020B89CC73AAD60135D5A3B94879184E086F1066A9F56041B6029D1F538FB5B18A7A741E04E2C158B69927A1A7708BCC411988C0C315D0D1BC3A31B0CD473FCD3ABACB1BB3EB23224379B5350081EFCB8C45584D3B845E2500420453718AD83194130983A355B1388BF246B9FE7400443C52629812FC1125C3800C3F824C0FF95BC24A2E8B306D5E3278FFFC585843BBFCD06D2EC3482295717A5111AA7B6475040083106A01491CF981197EEB77D9B01C2BE476F07C59CBEB5C4D19A2000D61546A9CC149A149BA8E57CB0ECB3105D94715C7B1BA7800785EDBA95A7352583354B93CBEF98C78BFA946A7431813EC36AC45488B170859C098B7C6813CAB2FFB519814C3A9DE3C254ED7A144FB6D15B183CB48A9021972233382FC8C388511ADD6A86837801F4BEA0DF0103B3A152648BBCDA68499352691BE0C3E5218A7C22C8CE49790AF1BCD4F6717EAA18CB489B446D24F5CE239C79A6E34215E87BCB8461B5B509C895EC22F94C17C3BCC5904D968C469B200D3322B423761E3749556476D925A915971A62A5A330ACBD106AD77DA7897815CFA31CD44310D44915D762164B6170B2916B5427C694FF3340FB16B73500E92833ECC35BB25DB6E652701D85AB215B366A173604C2797C2A9C420E069E7E4B3D1120DBD1C196D105211134478D23CC4428F8F56182FF3A51C7B84F01A08BA157E86B9374FB7C2E7ECA3D4B65F4A73472E38C6F7C06883C99C4CE934F9B04436D250EF262C42D4862B90C11F4924087469210A25CF4CB29D139D85D9C904004CB246348C60736D707B2B9B111C91ACD3937D9E8934032746AA5025BCEC8BF637936448A0DD67A27DB2A74B60BBA82BCC87D73D4A9033C427A85883613EDA43829C7CA3C7A8F24364633610D8199A5EC8038D0B6686ABBD47692ADA94282C40799ED4BF8ECB65EE7C8B2047C41EB255318C139B89CE909831FE3024BAC10B4110CA34F1BD657B941F466659FCC971C1174AA4459551848E7A116B751E5E4022C8F2A4B3152A1B26A3096539C9B0BD6A435EA1E33413AC4D5F401F5DE8570CC11CD4BB9FAC473328D55501702743E2C8D1B97CEDC8AD3D55B67D284158EA8BF1A4A8A17A9DE6D5669E8B9571200B05300CB30BCEC4A58B06F70830C2B32D28992B70427781854456129CBAB53A7C72FF557193D3A221D06177D002095BC04E993B8606245416C3B998B01716AF3B43A535F7A6BEA71270B34EC808CA00E9453AE660B732963BA634F14378B1691A90E3708125CDE31BAE3D10451A5643F526CB790A8D6E091A725681FB539E9B05BDA7B04C48A31B39DA6E39E6BE624663B6284DE9F958C50149CE4090E6A486B68511AE90A0F093297BF090DB3C81D34400A40CBE11D74271E23BBB7A49EA875EA7F7CC25516A899198362ACC52C8A8CA14BEE12BBCEA9A6E3509B6887A3D1D4C3B2B4314C4C44F44C96F48B29A8E7B85339037ACF131F2692B7E7A49282237C8F37267C835C24883D1A189D4DCCB7C6BB1FE622FC31301A6D3612A448084E0A210449B7E15A4FD84A9A538B2D5844DC170C911FC1282BC513E8C18C469A01A548D1CE4853128A03A8B1D369B353C3003B0A29D210AB6AF23ACD010AE3671493C774EFAD8B3746180746401D0E5862A3265E7969F247C954955B4AFC13FC420143C10263EB1C6DABBBF5A8857A7F3BEE7658C8399503C21A9A38BA554132344E214CD2036C2B30D0770CC5DD87ED9B246E7F955EA926965748CB9E58351A938F7E4AC249CA5C970CFDE48C0ADE051BA873D36A581E0FC50D9583109A79549FC5B32BA432444046AC0A66F3C64AE1498F43B1B36D8082442B5AAA7BBCFF2C4CDA8C0C4D2C62CF9135A75709CEB5B82BA4EF5716C4986A36BD7B4AD5C3A505869FD34AEC2D7CABA492F4BC30D232382B2651D5923242BB50DF87092ACE5566BC5A18FB2925CAB467B641DF7B5B91142318D120456245F2F0887FF13516D23216637393C469CE1F776CF2426C6577844CB3D4E0A92ABA85FFB59979A7C33EAF51EA2BAC9862160BF8A85553A3D4EDC05DA102106F632C91B8D1DF2A9B2734185283941EBCDFD788107B307738786D6C0A0E7D4957DFB17488C5D6CC11B83E3504EF2923034A06270563E18A18BB29F48C36A64C132AA626DCFC5A615E4416DF76746673E500186A117A27C5007A4B04867213C33739E27058ADB23C0DE35CE6158C99E59B88B147E2AC05F09F7C0A414C3240ABAF65C24CFDB6857ECA66BFC58E52472861BAB1E03CE70D2115480B443A9BF799379AF9AC978D0072F75BC7923816A189DA5974ED948B8A709A8191CC9BE60AC2A383A7E27CC62543A2A0CA9EA6897D284AE79B595D0893514F75DB35C9254B7AC47260785C1B86A98A5DD733D3DC2B947D148F698C5A117821847604151068412268169C86D50BE92D77683386025704575177AAC0B9D3D3196A610985E860E2F799F480B1331BA346DB0C379CB1833223836D88FD4E11DBF2985825C78330658B9A189233BC76B172127BC7A98E6C644D28DA7B0857F67157AE2C27659297C32A7EB653697A295097A32AC235A11887388265ECB3B46A75C865C239395300D0F8152CBCBA77B4D655C9F1EA4B448FBE32C4996FC298D26CAE25D276BCF6E66BA65E3E9779146FE6C37136273736CCB11DF5B6D55DEBBC087DE802404B72A003C5E8C809719D7E4B5D8021C486B9C3114D7CBBEB7CD49EBA8A61BC2BCAE1F1BEF30A1DAF76D +ct = 1D597DA26AFA055E20E20CB3DCCC730B73075CC9B0C01499A4856D0218E744654023B54734E6428408884C182AD6AF6B2FD3CA2F245037F7F540706C5EF18CC520FFBD5CEA84D308A4BBD9999EFE0B95B1F599A141C383DF89D2BEB33077CABB7B10F332526B1AC199576799444B86377AED9A18D6CE0C94B157DB14DF2BBB515464A622E32661CADBC9E6ECFA9733635F3847F2363E58F7E994563375D4E4C0B3174A84AC0CD4408041C4A11563AC5195C1DA47C86D7B88E7323B5ED66D3850A04A348C46BBC627F497B49E3E1D7BD8E23162AD8C232F750D3FBF55C267DB2D9FDF0854972E8EAA6898BCB21CEDEEC79B6BCF494FAE1D6B174779C3F70C27B64E196EC8E8A7C861CF75A5C62AA8A71A7677B995F16A8727BD5E1BC0FB2638BCC864CB1AFA8F793462ED0AA445592E1142CA2FED5792CFCAB5F6FF8E7B7A335043AF926C7C0175C92899EC0E3D2B5BB945334A4379A3533FA1607F6406869191B2F4472F9742AAA9C66BF9A843AA4DDD8F32F4113412CAFFE113DD80C55ADA924D5EF5F5D8E2A7DF5C764F53062730764368589B76B5C6399A8674AF24C02337EEE30E1FB44C8C9AA85F72BF07A61246043B21032FBA0E675A1D1B0C4284228E1EA990FF7803A1992C53D0BD85FD3A4D753DC1F9E1B873D64D5898B78C7DA9F72969D48A433F5AB9766915BD24E9BA07170338EE670B77F68C204A68AF32E3B6DE3580A973872BC756B5EC976A393966AA452F5757745660A15E4E2D4D3E549E99F309E18774CD74F73D5D4572C3A0C49FAFCE2342F1BDAC88D35D22E8663E27470F5691C150344508214F0B0F9F57755AFC52F5590615C64C06D4D611F6920CE7D0F51178DBBC906D71947C1DBBE1D98A7433860D3D21C2E83C4C3EFED6A738CFB48304746E5A7CB7E32CDB8AF44AB7F09E98EBD18B8B4606EFA2C646E37C6123B4FBB37E3DB5C3AAF550A536B1B86B47AB17865E6AF273628F3881937043A56FE323B5368B021F3723ACA9A3937EBA3828ADFB9873A3F2D027C9264B56FDF4CB608F5451EBA1FB1EE4734FB5B1D4ACAAF29ADC1F376D23E45D188D4086F4DC4942531DB72E586AD70350B04036D63EAFE4234FE90DBD68D83E91CBB0F43CD87A8BD3CD5E6A6C81A0706CE2EDB2C9C00ECE4F86D9B82157B4E82BE4C6D655F2BD1376DE64410D0D77CDBE737D8DF1C3751B0B33D1503B1354E70B5A6B3BF5E21435FC575FDDC26F9B261B19DA5CD045FE041FC6C35EA7A4C1C24307D2F4DF6DD6C5D4B211F0C5A98093F7E05815496F0B3B7A80E0079F0E60C5393A6E9079145137B2E89093EA7DF4336B40DE06CFEE5FDEEF322770B114729342B1A24892B0C759147B08275FFA24B5BCF679A5B404B292C818DA88631919A403110959A560D81AAAB2BEBC33F796E2F179CA5F25D3EA7C7DE3A310ACED8DCAB766E02E22AE9130D963DBB3EED2D0316D26F25AF53FF23974CAFCD2543B97F8B13ADF08FFB687926A51403F811BF3606C1C73ECE86E0A724B9A15325278D6F2C6481EDE68FB +ss = 5012217B85A1E5DBA62A2476D7A441411D8ECDDBE2D3A291F658B7DC1D1197E9 + +count = 66 +seed = A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4 +generateEntropy = c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +encapEntropyPreHash = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +pk = EB9B77F8C16DCE72611902A8CCB81E8CD4C5A2FB1D8FC30CE226BB45779F41073FF3EC0362BA152102CF45D3A95874A551C14C8A621436E248FFBBC4CA3B4033D50EFA392DBAD9C339745803F845736C30BF309546229EF52788AB223758C03491F62913FB4CA4307DC6B4C7FD9503A701AD21671387CB2CBC728ECFF4641E312779C7034CE720554A948A021751D4628890CA7367611D4B9F269C5CCB2381F1F6A01B0634D9C5C954FBB934E4144922CCFA2035892C4CC2A8457300946ABA4FFE77868D34C7A90507BE43748A366C49D0A927E66610A08CD0152A2C1BADA92A05694B6E3D2610ACD4579D5634FD2675F2101290E2BA1855252B57A438B50FCB854EA7B6A89B109EA9857C23AA38333428B94CA5A524977D72077B56978328C18980382EBC967DD37E6136360A958D5F00C3B9996DE3B97B6468B9F98C3C50F37A9E73AC8E8364288347D9B018D437B3B065C120D26E9033078B5838DFC7CE68F244B32C5B4AC04DEF068F58FA733E99A418176575EC2BA0F78D4C402D67176DB5717023B57F8D26C636A11F49B926D20B277D2613941C3E786B1A9A3C1135993BCE22A1DE16434A5902C0F101993B65777399828BA52330A2F356203521A3C59B6007C3AA41D198A8232D27C05F8E0280C9076D54D5AEBDFBC95C7C06BCE24507892641F90D2B774A2D98764C42BCF009799432B706DA59BD84CDE4892427C0586929C99850C7D769AD9A221C85A4062A62B2A1847454554224C4CC47898574FA66D147C4AEDC59FF612F49285DB54170508C89E6787A8CE6515CEC673D4545970CA8EC486802933E319800FBE46D5CC14C8363656DAC0600D895FE383FCBC3614FE334CAC0A94C185B73DB30CB5A56A8D04CB271B13859862F164F980625D78AC35ED120605CBD69E6410EB05168819440816EEBF8CC9AD153CDA5BC2EFBB00A7563A55856711231CD12873A9A56996C174AE43B5C172A1445BB40CB3DEEF9051035B33214A61E26852EF3BCB3FB319E1B4D6BD832D6B9BB54B6021D180881D59D2458564ACBA148B0AC36CB501CC8242919064EE24343F26A87A0696000533A20943445C72B9260B4C8A46A1C921C582600D978C5370B400B2412F73541A13BA0349E66FA4025735CAB6402AAC51E08A019B48115C49C665F415244FA91C208C6B1F2BB02BC18C47A5AEE366EDBE3BAE1E41A8B405DDEAA22A2FB254A6B70DC5A16C0217E4DFB933A127039B788E6C035DF8993FF86923500BA466A81D34A0ADA271DA4262F33123A1B81A13621211845A167449D93370BD95A89725A56A8452B510A7FD2642AF41A4A7856ABD9688DD7C85433A868103679A8EB2BDFAA0CB52CC141267E91E2C1E57162C6B4897C9004A3D375C1C8BB87C5AE2CC80C2A107E0F904E5BF8065AC96C9152AEB07322FA181A83A9CBA0224C9FAA0F06CB67E2787EBA832D3F53AC60B7B014D28945361759689C3EC65F8B885EDA081443A2AFD2A735B1C57C201AA4D273B1302267E5A63ABEFBCAE8E1B2D3883439E2BE2436382EB9BD62146DE0E446B6E2BAF8300575091DB145A646C733BF352989938FDD8003218A607739C60DA6758BF448BF18A22630B08AC40635382E3BF86D16625C45E12EBEEF4308B229C948D425016D674119C0AADEFEB21338BA6CEDBF7DF723 +sk = D338B8576C1FD9168551A681F9C590095B6B8D8474F571226A4B68EE81A83738BB964356EDB663D925960388C92896029A201EC7F046CDE497E3384F613A444634AA3C41656C6031D5233720241603612BEC1032AFA7B3D41242CE374C8B118CF6219FB5E645002530781CB4660403F88287D115BAAA07CE95496A7232862282A653367FBBCA1E337155A3C8905E368C1974418E735F93B6965FEC11CE7B43D81710D727A4C4B434003B9110D013568B7BBFB341212543031C862FAC505944B86394554772047B2A864A6675ED984583269362759CBB464E7E248A48C3554B8054ED9342AEDC8E221439F812697B691BD5C89B7FB11EC716BFF96C97DD73C45B00980BC6B1F69117C2329386518058E97B26626D98196025724BAF0C5729109399E035ACE9A630CB6D7CA9CBC16AB560DA5C01E37601BC0DCA7A3AF891B80418C0056145C7AC8C176605411A39BFE843CAFB4FA61463B20A504E984308F2B82CA7081A97951D0961B2664E2D7B41DF902571D02C1FE24EC0EA998609248CF51CF2F81D96A983DBD29BB37B9A7D559C72FC0BAAE894583A842FCAC92D910C7D682DDE70A4A7B26E3259B290A182392CBE36B68D2E321708E9C00D8C06DCA5043C1A461E76438B7801E8FACA17045B272B16999471F8FB42F53A43294124C3B2B7F7A13EEE8B195A01871909A70E41A0CEDB37F3F733EE259F40C1CD12C79DAF90788D78CEAAAB9E1D20B7FF8800A17AC28953A4E90B257D099DA195B6701A695195BC730389A84A499AB784762631935A5A974398C6988A59822BC6382B9CDC6072F0A6CF65C9DFF2309D1A433AC52E6CBAB472E788F76558D57986BAC5C79B921F06E509DB18C70EE88AF044B527E221E5A5105A19610F059FBF6009B985190AC81640607CC4FB69D4892B5D9AC12BAC26765AAD5C874FE3080BEFF77961CB9E747A8E4B4ACAF3F3B81D51A4A755AE8EF2994E8A722DCB5B8014C1CCDC6A79046664C3B75C02B91E0B4C5C250B8EDA5D67E9A0984A6052053D22266B2413B98D841E8AA686F4E0AEB8D5B2ED2C8BBDDB0374D0AD8CD47A0E6945F0AC352307AC0DB224EBA29BC09397F05B1308828CD42B85C556BF0A938959FA7CDE083D3D0163C21B016133145AE0C47EF73604999E76F9AD19432F82E762BA8174F89A23D09333F7E677F33BC15BF996AE6999ADA8747BB0C454412C2B651D2A90382937427EA555B3856D0250AB1E3663B8D78F3D96CF9EB90B5A501129715DF5DB38086076C4B351305A9718903ABF12609FB1BC8A59162E2152F8E0C62241CA5DEB5260D71AE162B7EA827A342584576B00DC674A5BE149C7744D7FF43A5B04A3EBD38C110630FF656F2FF042EB603403D14F18EB17CF675C995C2790E936CF8B60E758484BC04314E50105B28346829077AAACA72ACB46D331E9127B17DCAE5E639D2B33B9F3CCA468F731BF0B332BA41D196AB77B3C436702078730369CF59144540EA08B5025A4C880C1530F40A852E35F96519C91EAA680D90D25A4256FEB1878B48E39143CE43378EB3335D3E03F2A358782E0B54AB56860148DC0FA5CFD149CF26A7260639A347AA72B977B6F38BF29E1472C26B4D7F80E4BB3192DE06EC05A6AEB9B77F8C16DCE72611902A8CCB81E8CD4C5A2FB1D8FC30CE226BB45779F41073FF3EC0362BA152102CF45D3A95874A551C14C8A621436E248FFBBC4CA3B4033D50EFA392DBAD9C339745803F845736C30BF309546229EF52788AB223758C03491F62913FB4CA4307DC6B4C7FD9503A701AD21671387CB2CBC728ECFF4641E312779C7034CE720554A948A021751D4628890CA7367611D4B9F269C5CCB2381F1F6A01B0634D9C5C954FBB934E4144922CCFA2035892C4CC2A8457300946ABA4FFE77868D34C7A90507BE43748A366C49D0A927E66610A08CD0152A2C1BADA92A05694B6E3D2610ACD4579D5634FD2675F2101290E2BA1855252B57A438B50FCB854EA7B6A89B109EA9857C23AA38333428B94CA5A524977D72077B56978328C18980382EBC967DD37E6136360A958D5F00C3B9996DE3B97B6468B9F98C3C50F37A9E73AC8E8364288347D9B018D437B3B065C120D26E9033078B5838DFC7CE68F244B32C5B4AC04DEF068F58FA733E99A418176575EC2BA0F78D4C402D67176DB5717023B57F8D26C636A11F49B926D20B277D2613941C3E786B1A9A3C1135993BCE22A1DE16434A5902C0F101993B65777399828BA52330A2F356203521A3C59B6007C3AA41D198A8232D27C05F8E0280C9076D54D5AEBDFBC95C7C06BCE24507892641F90D2B774A2D98764C42BCF009799432B706DA59BD84CDE4892427C0586929C99850C7D769AD9A221C85A4062A62B2A1847454554224C4CC47898574FA66D147C4AEDC59FF612F49285DB54170508C89E6787A8CE6515CEC673D4545970CA8EC486802933E319800FBE46D5CC14C8363656DAC0600D895FE383FCBC3614FE334CAC0A94C185B73DB30CB5A56A8D04CB271B13859862F164F980625D78AC35ED120605CBD69E6410EB05168819440816EEBF8CC9AD153CDA5BC2EFBB00A7563A55856711231CD12873A9A56996C174AE43B5C172A1445BB40CB3DEEF9051035B33214A61E26852EF3BCB3FB319E1B4D6BD832D6B9BB54B6021D180881D59D2458564ACBA148B0AC36CB501CC8242919064EE24343F26A87A0696000533A20943445C72B9260B4C8A46A1C921C582600D978C5370B400B2412F73541A13BA0349E66FA4025735CAB6402AAC51E08A019B48115C49C665F415244FA91C208C6B1F2BB02BC18C47A5AEE366EDBE3BAE1E41A8B405DDEAA22A2FB254A6B70DC5A16C0217E4DFB933A127039B788E6C035DF8993FF86923500BA466A81D34A0ADA271DA4262F33123A1B81A13621211845A167449D93370BD95A89725A56A8452B510A7FD2642AF41A4A7856ABD9688DD7C85433A868103679A8EB2BDFAA0CB52CC141267E91E2C1E57162C6B4897C9004A3D375C1C8BB87C5AE2CC80C2A107E0F904E5BF8065AC96C9152AEB07322FA181A83A9CBA0224C9FAA0F06CB67E2787EBA832D3F53AC60B7B014D28945361759689C3EC65F8B885EDA081443A2AFD2A735B1C57C201AA4D273B1302267E5A63ABEFBCAE8E1B2D3883439E2BE2436382EB9BD62146DE0E446B6E2BAF8300575091DB145A646C733BF352989938FDD8003218A607739C60DA6758BF448BF18A22630B08AC40635382E3BF86D16625C45E12EBEEF4308B229C948D425016D674119C0AADEFEB21338BA6CEDBF7DF723A074ED1F76E97D68434BA4AF2AF0E549204222679E9E643580C35AF3CDD247CEB2DCA81E3F5F748D23C9D356A2209F6B2D60247B2E45C9808DE497F64F124643 +ct = 62A20A2BA68C9FBC4E9AB487FC36DE9C902FB6E2B9D42A040328B8798E9C8115A0C4CF5F39B0238FE74442936D0891172D6B97C219B4AAA3C628AFE98C56A33070859D5BCA5AD6338CF9491FE2DBBE4F2993F773D5A19C9CC70CE7364BBCAC0CCBD1723B4234265F4C643E425411F3665B7A2047E1C8E07C28B8CBC548BC4740903DFC6A7263B6800DF39DF6519720A9D1D0F7C9B239EEC124FF99F5CAAB64715E595CA1BA9F6A81583F4825FF9E32711AD3F741108A6888905B79DD7342B903488CBCCDBAA690ABC5E49A2534C8CA791B729E116C4304E55BB636C0331BC9C1520A1667356C4698D7D5CD8DB4B8C0CCCCF770405C056FA881558A2E6E1932793252A3CB7C1AE07E7135597E0B8BB173E7544CDF583EE8B33E24756EAE89628AD34C31C5C66590FD2D037512D309A2DE438FA13098A64AA0955A4F5460A8F19E3F1DA1E8EB7BF3B56F3E685E685906818F030B7FBDAA9EAD26F2AD8EDAE76006835BE6A5F07219451ADB37D8ADB356C4B3FD07DDA85579369071FDD5214EBE2CCE89819C316B0F43071367C6EB871947DAB8A2FCD14E656DC27F7A9E8E2596E6479440348A661E31F5A1AFF7347CD890DC3B9728762375E562788BE050748E6E00343E88FA11B165FFFBAB52D2C9004F63526B818DD4128AB69797A661731AB37534E0FE4306F865A353FAFD10B18A7E9438B41D9A9105A52292AB0488F2417C2B2D9A0B74D688F2BA3AB686CF4B08DCEC84C603AD326302684E2768AAFBD1BD7D2FDA5AE14664E287A1F55734A761BC363B91E31F5D5430992F4A6A377930623329FF9169A03736DFD875623A034D7BD4178CD01DC84F6384D6D001BFD22A543E1E9DFC2AC0AAB237FCF8DC7D4D7B3DCA4C00EBB191DD5C24B64B7730F7F4865E8DBD9739C8A374FBCA4DF0A99E8BF3EB0B7ABFD123CDA4DB5994AF01F3FC416A860C3F012C2BC6038D8AC9186ACC89E61F9B820F226CC26B5EBFC6DA09FA5141A1C8B2C2BA3C9C7F8975E73E825155B70FAB089103BFE2D3DEA873FB566E7C70E78CDDA058FC8EE87A58C98986957F5B5C6D25E33C856CE0E5A79F4A9592E223998C34B8459562D0712B7762699A382B470BAA29B4A7186F89F603F3AC17DF82BC52FA30D533DB99E1884B5D58DB45F0B5BE099DF8F27B7CFF57DD5F1F38F58345B43268A24D2B97F8F05334D0DCA0FB01F6F0E271AE002657887A7BC26A140D8761765909253D625CF8D5C3B16F27A9D055E5E4A055DB9E0F5817B9F64B7122D14EB54D3B2881F70D89C07D5D3150F8273731B245A99689B2FD31D089B3D7925645732C890BCF6058EE829A7DB67C34D8B6E0CBFCEDD73FDC7B83A038B5A044C6D9FE947C2608A9200EB21438BF942E66E0E3786ADF6B624FEA3F86185D84C0BAC24FDFB8956FCE2DC60E62721F89F25385031CC0948247E5EE3E6DD849474F4128409363C99BF4035CC43976B9B0EAF70E464833E99701D6708502037E5967490CF5D94F05E62844A329A36F819EB4ED5F93769C99EA65B57CF7F542E36B +ss = 0DCECAC51C5261E34023D2E04146CCEA10A0B39AE7EDC50736127184FECFC8D8 + +count = 67 +seed = 074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0 +generateEntropy = 334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +encapEntropyPreHash = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +pk = 9BD11C902A159F41CB5395BE189B1B7E98CC23658DCCC7BF9A843A77B2A6BFA27BC941B04F391950D998C607A59B49330811200B38B243060B55E381C078100DA84975091F3A0ACB06F22AE3FB1B7D756D36F54200A367C109B13CF40F3671231D5B0CE9E5908776768767209F4726C54277D0F8B0E05BB4CD50BB5547A01051C89ABC4A352745316C8D85A3187D68382EF05DC96294446972F4C76C7B9B91A4BABE06FC634E76AE4B778F939C308F22B8C816BC3FD6B48E168F5DFBC19FD8CB7E4686BF2325CB060638C723364B27C8E3123FE26CF9862F247CC31C844AE77754206B03B497BB3283CC7E38664B23771F709E1D308CFAF5086F25ACBD04CBD9F1612ACC2712D129C9C195BC024CB057B0766AAE7B533E60F04D947947F920470BC37E5EB4AC4FA1C48066877B4456D4EA2A5EE089DE38A7FC7573FAE5480BEA823727132651A85D873378CB97D6F7BE1250A94621ABF5EABF0114952665CD2A5005AF338B36D19F6E4C8F77E2CFB6F24D3CB7A909315A026B5AAD50A9CD4BAF3308059A91323B1C226FFC76B3565CD9386592476B76057E3477C8B7CBB201CA91546A2354B59328D411A724CBD8B3689EFA335D879996FB0D1D2244EDB361BE4B2489E84086F4A995F20FFA9404082C4E66061D3EF668FC155BCE04916C92B8FA46B77A4A9FA82C8C0CA5A5A5245883D25FDED230E74B22394169464BC33FD51FB7F2AA9214B1ED546DCFD00AD554AEC80882EC170C6EC44794204170D738EF9341D6034920A7AEC3B68FAC00527B2812D88969C6207F9AA122464A4D76320EAD6271D2836E574155310A756CD4249FA7474B301CA978A0653935B7740A16C50DF1EB678C1BC3EB451CF6FA35BEB903CD89CDE0AA58A43BCE9CF591286792FB3B5E658B5A32196EA24A4252B093D2AB40884C39A4ABCBD19B108B81172E18A84A288AAC2982D113454335423148168BB6B9D97494179BBA1EC8760BE59D06251B94B4BAAF82A6481C4A8F33B0FC3164635452E6497F992308688352CBF44537C618000536F9C41A64361EE162236F9227219B8B84A3984C649EA82211207C974F6C7575027AEEF57E496A58CE2719096A58E2E31E82844F4D674A4CD9CFCADA79AFB0C63E634D2514BA4D8604CCC42B2EEB64691AAF23727C93C4ABE1423C27B3B7ABF0B649334760056E591C32FE812A753723F7C93EF5524C8E0267DB177E6E55620715688CD0AC70B2A90E133CAEC86945BC74D7EA1CB88479A37B45EAE4993BB7048E5316BF66B9715591148C9A20A35412C2404BB62C512B3800B9AE104453D95ACFFE000D3AE85B96D8092532796A03039BA2154F84AFA4A402ACB673B8799441BC505E836C3B558E1FE2057FA79153E1630D72AFD96AA4FE9C0ED4822AB33A559719B81D274EF0A2773E405761A036521278DF5AB3617CBD89D7543CFC7C6AD373B2D0B781DC78DD3B2AFA34B6565979231681FFFB8C62843DCD11686EA59406E23CDF96AED95554E47027C5B6976F5515BC40B0E3A31C556219F89B73C0871E1FF552CA04C33DAA4A363794CC7C0E05249B53D20460EAA8AD217787C8C9423A7EB71058B5A8081B82454DC91F77F8608D60CAFF30A7C42424542A1746F0F10FEB3F0FA52EAAD4F2D4C36E59CA0A5389566FAD53898992A17BBE0A0F +sk = 9BFC3A71FA83A4070DB5064ADA8410A770845E818C49B91E09A251E1925EDB226EE8AB153F94B2417560D88959113A6BBC854B0065748E6A7DB90977ADA0216F3C41CFF70E5202B306CC22FF8A138C360D75B9CB1BBA849C5BCC8C9B55E80647E513C9E3E15F66A144F013822DA24266765E3F1125F435BDA4C46EF57430EAE331E1D54C91960EEB363CA25387D0D441ABB930E4A7C329191C5FF7A87996A4B1AA74162611E67B303E284C7098A65069356B55304B11B8BBA66C5829647493C09BF62166017977A988333092EFE98D9C13A2BCE53F8EA2C81A0099B7D5C2B11704971366A5565CC14610DF796C604700680226CB165E9ACAA6AB507A923B4D472A4B6C9424E7F5A622F87F4F8A1083B4755067A93C285CC0748D241C7051971128CC5AF4DB5C1F7C144F98B6BF9703F5338628CA22DF4B84D10312EDDA9DF71442464A24491A62687928C22455DCC23ECA964E9248543520790D813924CB58A0C156AAFBCF63906EC5FA891936C7E16B5FAFD98026D64EA2012BD75B6C5F376EEB74AE9B29CFF7041C650B91A2B852C021562BA33B66EBACF787BE40810F22AA43F4174571C77710F775D1719968A5523780B613262F94BC36B611B63F460DC6E02CC588AF99F164302276B0386E697469C55928C0E62438C25AF90577DE0883CF45819262905ED30D9A1A7918B82F9B4A28CA5B8DD1D9AD4326ADC7BA69C087765CC6511668CC0BE83D510245F8834E890662E06774F389C0C623BE3212AAE5ACCEDB101C43463B68889EA9A2C21AA0ACB5329FF80A336F8914FBC602E2B9AE452647777651CCC4BEF70AC06423B66EC5982C861AD9723DFBC834CA6A6433174C1D6C1AB9569265A96AB5D48495D72122763B3A7275B297713F1A729BDC48329B64FFF9C45955C6091375D4D77FBAC540DACB140666610EC7A15FF18BC741AA69425508D5CF682BAFB6D3C9DFE02D80349597F56FBEBB7EC8031FE71B6D6C065C4E6B5E5D17ABF3B412DED81EFCC8B6B1935FB37B467A5CC61F318AED20678800726509BAA73BBA244030500050D4B23E4AD71349CB0877566AD100BA77F8B409BC8F0EF8CFBCFA3CD1BAA1935C9ABCA798FF6965EC7B53141B6709597BC4F9983766403ED80DF4095D59AB482FAB7FCA432EF5E76AFFC77F74F4CDA522A0085A4917D04167A00B09863850D6CAA0621C2D473DE0763B7D3168B6147BDB009EB260901FA82013C8C0A3F6C39DE3CC49A773D08B357EF932077B5BAB86391239B3C366C43010AD15EA2EB1E05267029E5AD8139728A907B98761B65DD6DAB895363159B48875FB6AA80882256A04460B2977280688745C5914C089B37BFC949A8F9864AFEC2E4DC13F6092070EB561D09B530EBA2CCD66B87B0986ADEA1933448066521E28AC2ED9C57EDE492799B401CDBA8377D593DAFC1A0D233004E25877242C30070779D8BC5BB488DD3988004B5A8554861B560EBAA5BFFF7C89DED193EA077F421C216996C1445B165B912901B217315636A168C0216AC026FBBD4239858837B02DAB5A39D1BE6B072468A264661C5E34F42380C66526377C990092434BCB551A744227445C5108FCFC3CB4526D0B711DBD4539CEA05A08A78FBA723F9BD11C902A159F41CB5395BE189B1B7E98CC23658DCCC7BF9A843A77B2A6BFA27BC941B04F391950D998C607A59B49330811200B38B243060B55E381C078100DA84975091F3A0ACB06F22AE3FB1B7D756D36F54200A367C109B13CF40F3671231D5B0CE9E5908776768767209F4726C54277D0F8B0E05BB4CD50BB5547A01051C89ABC4A352745316C8D85A3187D68382EF05DC96294446972F4C76C7B9B91A4BABE06FC634E76AE4B778F939C308F22B8C816BC3FD6B48E168F5DFBC19FD8CB7E4686BF2325CB060638C723364B27C8E3123FE26CF9862F247CC31C844AE77754206B03B497BB3283CC7E38664B23771F709E1D308CFAF5086F25ACBD04CBD9F1612ACC2712D129C9C195BC024CB057B0766AAE7B533E60F04D947947F920470BC37E5EB4AC4FA1C48066877B4456D4EA2A5EE089DE38A7FC7573FAE5480BEA823727132651A85D873378CB97D6F7BE1250A94621ABF5EABF0114952665CD2A5005AF338B36D19F6E4C8F77E2CFB6F24D3CB7A909315A026B5AAD50A9CD4BAF3308059A91323B1C226FFC76B3565CD9386592476B76057E3477C8B7CBB201CA91546A2354B59328D411A724CBD8B3689EFA335D879996FB0D1D2244EDB361BE4B2489E84086F4A995F20FFA9404082C4E66061D3EF668FC155BCE04916C92B8FA46B77A4A9FA82C8C0CA5A5A5245883D25FDED230E74B22394169464BC33FD51FB7F2AA9214B1ED546DCFD00AD554AEC80882EC170C6EC44794204170D738EF9341D6034920A7AEC3B68FAC00527B2812D88969C6207F9AA122464A4D76320EAD6271D2836E574155310A756CD4249FA7474B301CA978A0653935B7740A16C50DF1EB678C1BC3EB451CF6FA35BEB903CD89CDE0AA58A43BCE9CF591286792FB3B5E658B5A32196EA24A4252B093D2AB40884C39A4ABCBD19B108B81172E18A84A288AAC2982D113454335423148168BB6B9D97494179BBA1EC8760BE59D06251B94B4BAAF82A6481C4A8F33B0FC3164635452E6497F992308688352CBF44537C618000536F9C41A64361EE162236F9227219B8B84A3984C649EA82211207C974F6C7575027AEEF57E496A58CE2719096A58E2E31E82844F4D674A4CD9CFCADA79AFB0C63E634D2514BA4D8604CCC42B2EEB64691AAF23727C93C4ABE1423C27B3B7ABF0B649334760056E591C32FE812A753723F7C93EF5524C8E0267DB177E6E55620715688CD0AC70B2A90E133CAEC86945BC74D7EA1CB88479A37B45EAE4993BB7048E5316BF66B9715591148C9A20A35412C2404BB62C512B3800B9AE104453D95ACFFE000D3AE85B96D8092532796A03039BA2154F84AFA4A402ACB673B8799441BC505E836C3B558E1FE2057FA79153E1630D72AFD96AA4FE9C0ED4822AB33A559719B81D274EF0A2773E405761A036521278DF5AB3617CBD89D7543CFC7C6AD373B2D0B781DC78DD3B2AFA34B6565979231681FFFB8C62843DCD11686EA59406E23CDF96AED95554E47027C5B6976F5515BC40B0E3A31C556219F89B73C0871E1FF552CA04C33DAA4A363794CC7C0E05249B53D20460EAA8AD217787C8C9423A7EB71058B5A8081B82454DC91F77F8608D60CAFF30A7C42424542A1746F0F10FEB3F0FA52EAAD4F2D4C36E59CA0A5389566FAD53898992A17BBE0A0F26659F74FC9EC372FE18BE4ED6AA28B7CD84AD1C0F0115DAD011A11D20FDA9EDABA5068AF837BE962F439F233593D193CE5E08F7D66EFB3389885927B89D2523 +ct = 454EBF31D8AB7BE6F8615035FD4F13BD40EE3E6DFD58E307AC2496B25BBB30222661AA2F65A314902C74FD897EDF3230AE401EBC263393C017195ABCF2EE916BF5B8B0A5F5AD109A7F8C049EE62C8E907719593BD3B3D2D35B0EB548C4EEC3C8C11787591967D8EFFE9C9DDB995C98520B4A9CB0A3A3B00CB1EFDE9334671FCE0D5C3052E0FDC48DF0D844C2960419B23AC63BB013BE9761D621DC41BCDD661452EC7A2FEBEFFCCC63B203F26441A366CC8C94ECC89F85404999584FA1B27D66BAD84BD997847B04BF1A594D301ADEEF612BACD232010BB54A8F5C06601E1F95F2C976017D9DF439BBAA02DA479DA944A71FE08082186BF464F3EE043CAD702E5E1F38E76793F19D7ACF46B40EC3D1773183F083F85FB6B2D6DBFC42ED98E78720B11E8C524FEC0A6F86A2A407957FF6D5E4137D8E0D080080F0A9F23CAD84224F558DE68B5F88D05850B29914E9A25AF725C39299546181E7390BF26B1A058F65300E351277EA19AC971FDF2943B44F13D690956C4E864891E397A06BBC70282F229DA50403BC3E354D898F5A079F8CB1333B1F6B0186B83B5DCF264682FAD6281F94FE08C370B2C29BB7FB9F3BEE2BD3A0E408CD1A14A497AB300CB7B39A2C15737F29D3FD9566092FAB82A01839700373C836CA73805C072A9E940E7B7C8739957B7561E90F601B7C50D2A4387D89E1CBEDAA6605062CAD5AFCCE27339CBECBC1CC13B1D690892816B7EDEFDDB90116FC14C6BEEE6D991F72A749830E82E3159B1632921B776EB9B9EA222573BA96355E10140EF9A47695C9F551EF7E2ACB055E54E712F44852604A46057F84358F6C886F2440E55EC68C0ECDE354C99BF5A912C68EDD8F488468ECDB968BF15C9CB764E67315C1A5D585615CE989DA13C8BAA041C448182BEC6005F018437036C296475B83C887E87C5D560DE293C35C8E942BDBE271CED6DD26FBCA0CAC7D1600188F65F32A9B20BE73CED637FE59A24D43B7896A33E58A2858AABD699A4C273C6B2D3AEE18253238F7E44DFA959142ECB729F5011FB840CABC16C183487C18DF53386B81C2EE131DD8959E3894BF36D74B91EA2F117FCD3596BFDC34926D5598864F5FAF775D71B6F17B471AA5EE0FEDF7461324D125AEA4441A1433B908CA4D4693945235B9153A2F1B17B2EA2825CE21101521D52488AE9FBD69B6977A17DF0269AAD0F22F1670AD5D4B95FC4292DE7037BD4E90A2AB0C7356F39951F76A8746C6D16C94861A205DA3F09CD84ABD40C038038B77D61B90FE747E86E41F9CF1E4B745C88556D6DDF1C817D352AE7DEDD801AC158CF4D1C036E39EA1CD1E10A2E1BAB5115FBF61BD52CFB2ABD6F5E96CB7DF1442BFC32F0A3D011691FF429BFB73C5E978E7F349776886FED906480E945103F109FC7616EE73A2F8F0B027E87BF9F4C5D88D085751DC708E1B9E36A6DBBEADBF37A8D2C641AE45A4F31747EBFAD00EF64BD00BB5D1DB84E5F395A914979C62791607A9F9A9AB421A2243329B755DB72A6C26DAF6713711E4D65E287983 +ss = 0D403F00C22FAB72899D302CB536854B934446B62F9DA6D9D6CF1C0F7ABAC2E6 + +count = 68 +seed = CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA +generateEntropy = 6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +encapEntropyPreHash = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +pk = 8683354B3C3F035586B50B88C4140F346A05ADA7CE4BEAAA5F096614CC767AF89FFCCB95124B00E8379EFAF76CA381AE4886ABED9240BDA4710DAC62A71017059B07921C770DA1CA2D209338536C3A9B5238313BCE565FB861BF8AD3A78F030B3F646B34347F1D215E8EC1789D602D92A971FA3C2E892A09CFA68968F96F206A7535766ED7533497FB051C8036B0AA81C2C802FB7333CC6744EC830E4BE56EF1E4874371409486C477CC4EE90092D2919F585BA21F32BC973ACAEF42B4969746AB2618631B6536EC298B2828ABF41E24776BF288CA6A4A8094D63C7CEAC44854BA9E4837E44B3A7B269D6CCBB6D1712E9FFA937EC5194A3541E3FC9C685102F9A47FAA077FECD688D607996E5B60C1715E617994B842B46574B87086A061488BB2445B357A38934B612C16168E662112756BFD764A4FCC5F7B1634F6F28094464D600046EE03B4540C1049BB3D18F783FBA2AC5BD36ECDE662D9E08E2A89CB754B090DB7175277941E5973D010AE08A4B4C922AA99F47F657A49C3B81FCDB54C905A3010405ED544BDDA9942BC857B6D979F796C859E0627A5212543477ED791C2ADC95FDFAC9D21D19750B8B5DDB95F02D721A9304099BA6B2CD0A40C1A2F9DC1649B2318ACC93A5FBC52E3F4900BB44D20A7250142AE5F3B77C0720C77104B74C78EB821BD32E260051C499B5CCDD9D716521163557B5E4526ACAF09A2BEDA04994188A5065B4A975B215171EB288024581CFFA37D6289813773B29F1C0EF5587F9C98049F548D2A0C3A5C71C1693B5EC8C64CE0267FDF625485DCC4B5553C5736A0D0623CFE20596F984C014AAC0380BA9B58257A993B1BE3BD2CB9AC25912B36B2C085443074F093510A46CDE5441EE3CC88DC2CD636A5EF77310F91CB21ABB149DB2541407726582B54B50306CAB4B5356492C220C138C64B4AB293680E01C2AEB369BD611064FD8955B790222BD5997DD76BFBE50A2BD039C1F14F0469B623C53195A3B2FF068182D951DAB05FFCE9A6C8FAB42886987B7999043C12870965BD463980AA6B35E13B5BF9C25B64920D7788A291A98EBC30D3785783C27E53CA9AE809004F23706E3CC0B9AC0BD571084100299C932DB2933CD91566AAA367371B16069A706BE664E86107B33B1CF05360248C808EA250FCACAF9096715478463932A1C632CC9A185EEB08583A9309259C567743995AF013216B1086815B851655D0F14FCC43682720ACDFC36F35806894177EA2144F6E28837CC887E560874DDCAAF60A3580FCC7A5F1733180B1F1202A08182345370CC5C46CD28A507AD846D1D9415AF679D4B22EE560C6C1B2499D5B74AA2758DA090E62713343B3A8B14C68E415A3F196C2573C5E828A16CEA51443104F9CD899AD03C3B727774B48AE61DB98FEDA4C1E029B57F89D1735381166B70450215AF92120CA61A8A38E575ABF2CFAA54C613031A9BA60275D23178BA553A3ED7179AAC44FB3607E93C1C57C7BAD6854533844BF3D6A9B95A966F891612239CF6CC41DF1A859AFEA9C0CEC6D2679CD7C71C2CF251DC9759666C871853A1012294022FABDEB2269B430397F337B3F416E528748903CCB8B24C8FA28197244C0AC3A0345E699B247C863E9A58D8CAEE564224FAA36C70ECD281B67EB98908468420B38F3C24DA9290EA98B24 +sk = 5E484946337E3F4135D738B0862B69F7B247A5BB0812D56201300C53BB87B798B2B551CCEA75A87F002D7DE7878ED08E976A2CB62B4AA559BC36816E9690973F608B262612F89B5BC784365E33193FE9013C05818E0A7151297EA53C95089388BE203071D0335535436C799F6D3AA3260A9C8C9C9E36F79F13135C3DAB92914137C33773660AA15557C32B7A086A5A1CFD125DEA60183ECBA94DA22F0F3A18DD2131BC792C4013B7BF84A7840C976C53117653C4F947839D8CB35538BB97899418688A9E062F9FC17D77450D85261AAB01BD9EE77E917966BD26BD3D3990AABC8561CBADDC5A22F8C80D99453FA7350B2A022E4CA48DEA6C9C07309543611ABFC7CDA76AA03E51ACFDF0CC73921EF2D02F45990AEE50CA77B93F14E4BEF44576134391F7B67658E1CC7876713742267A556EA8F562BD858B24E04314B025CCB5BE0650642A23460C3C65E0D6CB68232CFF709204B7B7CAB0741807100A712686B982F632095D7730DD9385A7A26C23741474E12CD8FC259EF346B5F287EB01B046104EF8415372B47DA145AB0C5C1774626B5DEA7D72DB4C62FAB14C03CA51384420690A799194E8AA05BB914DB21956BEDC948299BAED7289C884AB9833C8669422ADF51D4E1A0466056EECA478F11AB55CE2CE34430ADDC889044A5601357EA6A5B097B54252B046FA83C0211C236953954C36840E390D2707848C0B879ABA2354EA200FCA56CBB86C0C2269A81C790B966893F782AAE9A4BD1B02FA85995A757FF2083FD26347C97711E07560AF77CB59C7CD64F7CDBC880AD26A7BD7FCB9B210710E581C49453A3200AC08554A641068E6879BA6665AE9F281FC14C8FBFCB0CAC0081C1A06DB017D80048B324248F699825A489D0726893E109127A0AE802CCA29AC56F6118D209A54CB842C9A8C539E43B9681CB868018C95D872C532A10A77BF52A796D33187FB8AA3FD780BD2C4B30FB7394DC64B0FE05B81128763A1325BD00EBA411247B1C22A1146FEBA1B255C51F74999DD29A9453151BD9869E3D548347B93C1B798FE92A053B88C80D7AFA5C561D31435D61251253B9A4C2B0F42830C81E990006DCEBDDB7002240EE8E276D4E31C2D249B84414F3997B9C4F5C0698CB2A24C48E3605F6D704E5DB734EAD12D62634DEDC68ED6A1248273BAD5ECAC0651978B098FFCC148667671D4B59EA6095B0B363C31299E5B90282F914BEBC66F6291338BB7600C8310B83963336952EC33854ED7C979B71F30188180B11BB66314C93242ECB890123C9F2AAA786ACBC7DBF560CFC1625D06C3828998ED51B79D28C583BB38719706D1D67B9BA5A556CB9EE1DC4FF2C53C33969F2F97BB93056729F65FD90AA2D7113EDF611C521761BE671FE37BAADA7A2B4A114DD458A19966A2A42914D61B47AEF5ABCCF8240C88AF752B51BCD0A3788C2AA38AAD8DC00D835476C8386DD3A8628B261F1D6B2B9F771842C97DA7BBC3D03696F60524BE6476430044F6A8AA48C22901F750DC55C1EA7813EC3518B26B3FD0657EA6FCB6BE94C026244A0401593664673FAA680F866E174143B0CC086FDACC1F7126C3E941F090332D8487D5E66061D5311C9B5C8EDC39BDFC34948400A9A3AFF3A85A8683354B3C3F035586B50B88C4140F346A05ADA7CE4BEAAA5F096614CC767AF89FFCCB95124B00E8379EFAF76CA381AE4886ABED9240BDA4710DAC62A71017059B07921C770DA1CA2D209338536C3A9B5238313BCE565FB861BF8AD3A78F030B3F646B34347F1D215E8EC1789D602D92A971FA3C2E892A09CFA68968F96F206A7535766ED7533497FB051C8036B0AA81C2C802FB7333CC6744EC830E4BE56EF1E4874371409486C477CC4EE90092D2919F585BA21F32BC973ACAEF42B4969746AB2618631B6536EC298B2828ABF41E24776BF288CA6A4A8094D63C7CEAC44854BA9E4837E44B3A7B269D6CCBB6D1712E9FFA937EC5194A3541E3FC9C685102F9A47FAA077FECD688D607996E5B60C1715E617994B842B46574B87086A061488BB2445B357A38934B612C16168E662112756BFD764A4FCC5F7B1634F6F28094464D600046EE03B4540C1049BB3D18F783FBA2AC5BD36ECDE662D9E08E2A89CB754B090DB7175277941E5973D010AE08A4B4C922AA99F47F657A49C3B81FCDB54C905A3010405ED544BDDA9942BC857B6D979F796C859E0627A5212543477ED791C2ADC95FDFAC9D21D19750B8B5DDB95F02D721A9304099BA6B2CD0A40C1A2F9DC1649B2318ACC93A5FBC52E3F4900BB44D20A7250142AE5F3B77C0720C77104B74C78EB821BD32E260051C499B5CCDD9D716521163557B5E4526ACAF09A2BEDA04994188A5065B4A975B215171EB288024581CFFA37D6289813773B29F1C0EF5587F9C98049F548D2A0C3A5C71C1693B5EC8C64CE0267FDF625485DCC4B5553C5736A0D0623CFE20596F984C014AAC0380BA9B58257A993B1BE3BD2CB9AC25912B36B2C085443074F093510A46CDE5441EE3CC88DC2CD636A5EF77310F91CB21ABB149DB2541407726582B54B50306CAB4B5356492C220C138C64B4AB293680E01C2AEB369BD611064FD8955B790222BD5997DD76BFBE50A2BD039C1F14F0469B623C53195A3B2FF068182D951DAB05FFCE9A6C8FAB42886987B7999043C12870965BD463980AA6B35E13B5BF9C25B64920D7788A291A98EBC30D3785783C27E53CA9AE809004F23706E3CC0B9AC0BD571084100299C932DB2933CD91566AAA367371B16069A706BE664E86107B33B1CF05360248C808EA250FCACAF9096715478463932A1C632CC9A185EEB08583A9309259C567743995AF013216B1086815B851655D0F14FCC43682720ACDFC36F35806894177EA2144F6E28837CC887E560874DDCAAF60A3580FCC7A5F1733180B1F1202A08182345370CC5C46CD28A507AD846D1D9415AF679D4B22EE560C6C1B2499D5B74AA2758DA090E62713343B3A8B14C68E415A3F196C2573C5E828A16CEA51443104F9CD899AD03C3B727774B48AE61DB98FEDA4C1E029B57F89D1735381166B70450215AF92120CA61A8A38E575ABF2CFAA54C613031A9BA60275D23178BA553A3ED7179AAC44FB3607E93C1C57C7BAD6854533844BF3D6A9B95A966F891612239CF6CC41DF1A859AFEA9C0CEC6D2679CD7C71C2CF251DC9759666C871853A1012294022FABDEB2269B430397F337B3F416E528748903CCB8B24C8FA28197244C0AC3A0345E699B247C863E9A58D8CAEE564224FAA36C70ECD281B67EB98908468420B38F3C24DA9290EA98B242CA3D8AD2DAB1DD8A2F4320658FE6EACABF70D907920593919119CF3745163360F4DFF8E56F68440836A072412A30D851ACE2C7C6F02D60E7A8420001A63E6C6 +ct = CC6EDBDAE7FAA07675568A32E556B25F34740418B3603A6ED17CF2943C1531B60542379810B7BDF525790222217880D92343AEDEEAE9D5F1FF7773C676B1894399F36037DDA6A1F2DF2D894FE157A64BBD04A0948DF19303CAF2A59188FB0415291246E115F0663C17DDF4259F2326C3E1C6ADA0A12E69A6DFAE45E3B6C6F8952B09D9C1721886076BDD8FF34878110ABF83EADFC84DFD1F9A426A533E1AC51D87AA50E3EF4F05DB558713D78ABCAEEFC2C98B9900D0A3BCCC818D5572E6F47F99CE87F687874CE23CB1ECFD88D3107D61C2862FC306BA30477BB7A0D121DC6E378D6C20A4F1C300FE69EBDC020F2585A539D972A3A935A2F1D49697F9696313D7AFBDEBA2E97A2107AE83E7D3CCC6ED795C77263D3B4C3632241E0F95028A2B3EB37385B847F67BC4E0F5BAF7EB89E293BBC95F77D609453023934B5C04D34C4AAF06CEBE6C122F76A3608C48FA264A59477B5F41C63936CFCC1E86CD443F9F8FDFC5741CE9CF25F4D4B7FEAF143237D6C03B684514D9C67CEE6BAEBF58A43F10383F72E9CF74B2FB8B865A450756764894640013F2C569E1DDA9DEF2DFE70A48A78510DA2EE18F17279688BFF62CB2F48F6EF0D72AFFE36CE9F656E723B692E418CF98E5A2A4D72E908F148788FD04D680497084CB01795FCAA77EEEBB0AC2C600351C84B4A3D1F6C537E9D9CCF373B2A26E7EECCA9B02183EF4AACBD24BAE4863A40B1A5F3C60F514D718B345A62C15B9F38880D00E50A01A18E7573B213A8DADFD54E2064C9A64CC6354DE8CE3E70C2F1457CC5F0F54055E5F0C05414C125CE82A398F025EBF224302429D818BA3838AE58F895C97130C1DC5CA577C05152FD543F7E6C1E292D8B7B6757023685D8F57A0F44BAEE68375F4D226973007275426EB9EC937835A2E26A1DB9F4DDD63F415E3225B6689210FB7FA323A479A59702F13C11425EE68C982F0106BBF4F6B01127F3BC7801D6B52F3B6226E73EC40659E1FD9A22B33F8614F514A20580C56859470FBA19AD5A558252F939614D1CAD9E3760EA33BEB784D311305EBB0A00CBD28C6DD9902F0C3CB5A88DBA565A4F494E1ED31C657A81685F706B1B0532E0DF6B8D9D90E3318125F1ABF6EF69E3044C04DD09599DBFCBF3E473C022F4B5A2DD2437AF91784767B2763FB99494BD13AF326B0403118DB6BA8271E34016548F56E4E5C75D2002CF237D5F5C26F5AE692444AFB5F6C51958B83B3ED983D248E0FFB8C0ABF455C34D17DF51A8F86C5B3044BE0660D7843033194A1DC4B84D475C089EC2AC1820A0B79C26B7CA3F888F24F784A54536FB852ABD51B0CEF758C855FE33FFA2155F4CB1C0F4AB9AB5B0D74B31067E2C6651460A151D16252F32CE4E037516978EECB123E23671B453B31893601D2D79F22ACE7EB3DDF6A22714C5AE97DF6BEF6EF3ACBA526AFD8920F2CABA016C10CDA20D0C39B32E78D0BFF0CC7A445753CBCAD615B55CE00851C70A92DA2421CC9105A85B6E642052F2692FB84CF642AAA44A9EB7572A6974FD3B767B4E0 +ss = 8C0346216CC65F95D2E0CAAEEC4BFFAACCC49132CBA2DEE8F2A6CE1F922E6DB4 + +count = 69 +seed = 6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA +generateEntropy = 995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +encapEntropyPreHash = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +pk = B147B4694B12C461130F3126F8F71673E4643B2147DED2A7270AB360F6303DC05B03A314BB776C488318686069C3A4C91CC62435E829A6A8621EF5CF838311A4278D7F453EA5484D32F94C2E9628F5532FF93771DAE106C8AC9CC80AD07D306B1DA78463A08226657680E5ACABA6819543CD96194AA5973D4F7B8682B13A07E7A5194C91EC95A2D671A2627710A4C78AA107B3707942D0C78F3EB2B3A58B7833FCB0FD7785E349A2F0027AFF079B62A68E3F425122F7BC0A0B4C053A6696F90A67088F139B2A39F542D6439091E4C1A0824734D8B6E5E6483F48CA738C39A5BC2016C0746CFA9C1889297F5377D614ACFF2833CED20ABED0AA6C7024221B73D53610575C6D91A262A5E834ABB63CF74207437B31B1E989ECD7416B2C4E7BF807B5F8973006877E204A42774C93A1B394E885CF727B7FD286DEF2B4C8D5684460219C31B1B225AA08AC2EE1DA3922E935E981B3B5E2C3D044A784BC965A580D3052AC48000EF6183B94B0A870E65207BA8029C0BD34A10443E5706792207FE2224DA533D307C3E3077E6E1CBAD064B0399ABC6F445B651864F18B42E1A518FEA187BDD08072E47588527C3B9A5EB244AE9E910F93C92B69FAA7250BCF38E68E9C3A2B2B733B18032F37673907097A4CD65A9B396DB4859312D59113E07B39746C52126EA697A69929B1B625B5AE1B809CE9A811D13CCA70971AE8BD6AD223206691AF6897F136CB451699E0A19739D52D60CC89DFD654A320A79B2C7CD55116843239D6847B8BDC1EFA29CDC0A979F0E3A8F225A16FCB7996FC8CA3E79FAB55B93DC2A395117426A17AF4D404151814CEC80E856B777EB35085F1AD14285078803C2D76AC1D25C3F8609AEEEC4ADBCB64136516A2077CFF4C13748C5D1FE6386782688D944E0027A2F8C9AF77B79352EA5523767CBDE4577877AF1F8017E4DB244E833E99DABD0FC70824BC3C50A38275040446A5C74406873BA0B5BFC2570A406570B424727379E5C1C39EC194A29A8AA249844BEA2A078C1C0F25A400D6BADA80731A00B87BB5A19325B4E79B78AF0BBB2C52C3DB38AE552CA972C3927291145438115A952BF2A85E78F6141E1CAE8516B056E614B7015017E71D54268AB9919B7EBA09D196768D99651D60A334FC443C8CCD9064A420263A68531F0E86CDC48776A3D44B4726916273A0D3002DE095526257BC5E6246DCC10814D1907885207A53241A184AB7E40D87148A336A33262A4BB0826B417ABCDF957F68737ADEE682194115348AC58814661765BB321254A874C4A3C6745CF984528C2B9726AC35441015233219E169D0EA761425C06513720881B330185B48BC271B275DC024419D8761EB23801EB704F6326F162656713ACC2915A1A6F877A583C8372CC391EBCF2CB22873C5BD22C58C80640CCE759B2C09B368AB4AB504C613493479B7725A18811837213F9237734577AF09C4BE0B3FE07AB78B712B0683060BE76920CC5FC56993E56C7B46A543AD675B2D13357C008911320E0D292268768B8370C66CE757AF191BB703CB5732113ACB8F02618EAC98693224ABCCEA04E7B3157C03B27A3CC4F0B880DC4877AC35077C1C2D5584B971261D2C4BB767C75907827AD7370F4074721445E155A3A1624CB4ACA373DE6947F148CA7E2B3C93605E706EDDD992 +sk = DE4627135B3976B8AC07C0059BB28D09E98E3428228C1786C2E8A1D6029D93CB9EED217D09B03E9A7561AF7441E4271C7B6C8C862C5A93E955A05A87B01A63D9E8A334B26E1FC0346051BF31D078860A9AFE939F4A90C2A395B2B6C205475164E36A0C2930CD26E26420470B0D068E36971A978B17BE984A418A3CC5C6B62AB00D6DCA5657F71E08B215EDFB88A5B6751EAA525DEA4B0BD41430388E0CFB445DA3347EAA375B86858F19C81B73A4BF88C2F807638D808F78535B9FC6C6BC0C1402E16F0B784F9A22A30E5C6C1932C2063BC558A7B2636C76D5C0CB77E6C5518B3B31D920A23B2BFFF3AB93FB03B3386F670B07655989C5185D5D393631E9ACEE701DAD333379A63EFBCC636BF2B4FA05B84A375559079C5909651E481DA96B01A771BEFC7BC407DB7D9F94B819A468D443A7AA8C9B4741266875268602336C1B1160A4CE5D41C57FB915335C87A72A7345316373D921A6D0CA09606154199C4F06C244A7C568BC5D82449149F92AD3350B51D3C474E77A3A1053160570C876132434AEDD92C8961B95588910102C62AE1A75479175CDD666AB85478EBB6133920E9154441F1383B0F147137614DADC823F1848FA478B1F301D3F745C647C216C741DFD3B3195483F24F1A5313CB458273FFEB559689004CD534EC1369B0C68A873651F7413037118C6F98C538DAB9C1EC649FF2301A03A650CC0C138E79D15F9079A639737E840A7DC720B173BB329A34CF65418495E4DF2805A491A4C96B47D452725850CA8EB3944399F9D14157FA46B76F0891525461113766DC025EE1C2E735198C3DB253A2B8A566CACB81B65A1C9473C6C6DA9743D780685CF83CEBB441CDFDC9FBA20A9CE2943759C4D08C57A0E74BB0E1888E94723169437AEC19AEC1A2A46C81AE4645DE32BB18F3527F4DCB8221A0F7BE74F3F5A8CAB0609BE216465819FB858232B008A855C9E6B54439A67AAFFD9701967BC46A274D1D6AC1D45CEE7C54CF49669E89A44FFD7B73B2A12327A85BF5938E6975B949C03EF3A1D824CCDE033CB175A3356C8A998E4C69D94630A896606FC1979DCB5C172A54EEA2E99D5AE331BC64D708FAE45C514A2544843CA59C3C122947BC3660DA7357AC0E33F55485E79EB3117D14C42EC5C56653E0DD1A4E8205FE571823098AD8D9844A25B92238063A92040C500CC0BC2B25B493E4CF69DE95C87B03B773A796D13F42014847727345888EB06D9251AEDE24D03E292CB452A3A38A0A461C8B4F9CD9F87B09BC0CA98E62E5027595C24792F818865777A346004FE3B5B587452648263AAF688154526D591ACADB74520F3627D7395EC7B71DC3C6E8414985D591A05C88B6455870C48B12C576D7B328B88795295C051CA6293B0FB4DC61AB8AD34CFB114A4C7E44AB4667D4B1948C83C28BAA424B19370AFE997D8B08E447A2EFF376024F5CA54DC8EC0972B96F057ACF5A6B0D32869FAB3E1797EE2571B1620A076082C4BA6799C27B07FB073092A7A2F7AA110635CB94900E487A6664B318F54956039C57CE509EDE489FAABAC96CB11F58C87708A8ED3408A526701BFB8507D67415FE64E7D41081AC12C21F3092AF02810C604F02C4064E348B4F98F6BE65D87650EB147B4694B12C461130F3126F8F71673E4643B2147DED2A7270AB360F6303DC05B03A314BB776C488318686069C3A4C91CC62435E829A6A8621EF5CF838311A4278D7F453EA5484D32F94C2E9628F5532FF93771DAE106C8AC9CC80AD07D306B1DA78463A08226657680E5ACABA6819543CD96194AA5973D4F7B8682B13A07E7A5194C91EC95A2D671A2627710A4C78AA107B3707942D0C78F3EB2B3A58B7833FCB0FD7785E349A2F0027AFF079B62A68E3F425122F7BC0A0B4C053A6696F90A67088F139B2A39F542D6439091E4C1A0824734D8B6E5E6483F48CA738C39A5BC2016C0746CFA9C1889297F5377D614ACFF2833CED20ABED0AA6C7024221B73D53610575C6D91A262A5E834ABB63CF74207437B31B1E989ECD7416B2C4E7BF807B5F8973006877E204A42774C93A1B394E885CF727B7FD286DEF2B4C8D5684460219C31B1B225AA08AC2EE1DA3922E935E981B3B5E2C3D044A784BC965A580D3052AC48000EF6183B94B0A870E65207BA8029C0BD34A10443E5706792207FE2224DA533D307C3E3077E6E1CBAD064B0399ABC6F445B651864F18B42E1A518FEA187BDD08072E47588527C3B9A5EB244AE9E910F93C92B69FAA7250BCF38E68E9C3A2B2B733B18032F37673907097A4CD65A9B396DB4859312D59113E07B39746C52126EA697A69929B1B625B5AE1B809CE9A811D13CCA70971AE8BD6AD223206691AF6897F136CB451699E0A19739D52D60CC89DFD654A320A79B2C7CD55116843239D6847B8BDC1EFA29CDC0A979F0E3A8F225A16FCB7996FC8CA3E79FAB55B93DC2A395117426A17AF4D404151814CEC80E856B777EB35085F1AD14285078803C2D76AC1D25C3F8609AEEEC4ADBCB64136516A2077CFF4C13748C5D1FE6386782688D944E0027A2F8C9AF77B79352EA5523767CBDE4577877AF1F8017E4DB244E833E99DABD0FC70824BC3C50A38275040446A5C74406873BA0B5BFC2570A406570B424727379E5C1C39EC194A29A8AA249844BEA2A078C1C0F25A400D6BADA80731A00B87BB5A19325B4E79B78AF0BBB2C52C3DB38AE552CA972C3927291145438115A952BF2A85E78F6141E1CAE8516B056E614B7015017E71D54268AB9919B7EBA09D196768D99651D60A334FC443C8CCD9064A420263A68531F0E86CDC48776A3D44B4726916273A0D3002DE095526257BC5E6246DCC10814D1907885207A53241A184AB7E40D87148A336A33262A4BB0826B417ABCDF957F68737ADEE682194115348AC58814661765BB321254A874C4A3C6745CF984528C2B9726AC35441015233219E169D0EA761425C06513720881B330185B48BC271B275DC024419D8761EB23801EB704F6326F162656713ACC2915A1A6F877A583C8372CC391EBCF2CB22873C5BD22C58C80640CCE759B2C09B368AB4AB504C613493479B7725A18811837213F9237734577AF09C4BE0B3FE07AB78B712B0683060BE76920CC5FC56993E56C7B46A543AD675B2D13357C008911320E0D292268768B8370C66CE757AF191BB703CB5732113ACB8F02618EAC98693224ABCCEA04E7B3157C03B27A3CC4F0B880DC4877AC35077C1C2D5584B971261D2C4BB767C75907827AD7370F4074721445E155A3A1624CB4ACA373DE6947F148CA7E2B3C93605E706EDDD992DE62EFF56F6B49A156D065D85EAF0AA21CA229A20FA4E1372A410AB1C4AB6E7EB28F7E7A15A005F92400CE33DB073D49B53871594A88FC45E0F94207B5F0F2DC +ct = C543D4032D1E98D70EE56B5B7AA1AA456F157F9405CE77EBA7F9C61C8D4634834B2A3DD128ED8022D30D6300EC237AA27B302302932082D9974B04DA94EDB0288EB04855E224669CEB3814CB91854F47FA0BFDFD376B0620DEB5A230C1705555C8D45BFD2751F57E2CF296276AE1A4078DFC4A98DDD7E5CB419B0F0AE1C3CEC1FF4FF1DE6D316CEF569D428C89B9C08EECF992B80CC2C4E5432C1DBC505E3A361F8570E71104591049F72B2C9B17869DB01F14AB30630726A7AD7B6AABE63270B81C033FFF7BDEE9E4189FB9D53BC910DFB3FB5773B8EEB63FD38B32DE2AD0EBB24FD3C7E0AF6BE8970602A270107C0B227A3D35677694CDA2128DF7EF7BA60E5F3D5255C04B817B3B01316D6B6E3D1159693FC7B27C3D5BC8ECB1C82403C7B736CC0844089DA19D5945FAAC08B074605D14B7B3A51DDC7ED207D84820465E44AFF42E9C5871E0FBD1DC147C79868D65911E5966D3480ECF644BEFE22A120C8D069E867D3132F44AE3482A1EA00A1EE14A5240C8412E0E07637BB2859A9C6A6F5B5CE2D7C810B9281A949992FF7A6CD4A7E3474625013E86F6F2713932D2C33C5D65AE15F26E7E45A5A24B9205574282900580338A26D07A2066C050FC5C44972ACD5DC2C2A0FD1D8634B34A4D839B5809D3AB4C14800722DB9F8A94D0239AF0A5C756AA815B1F733999C6F2DBF7E144BF2E2B8C6999394817A1875F4EC794680A4C509046FFC64C4D84D8606A19EA5EC8CDBEE7F5199037A8BBBF9F69BC4159A505B68BDA0E450695977A586D9917E843098E3C7F97A80DF5D092172E89364B1EDC37E8A1738E21FFF20170B157775B4F8F6B9DDD5D0202E735FCD380649C0F0EA7E7C708ACA92A3DA4AB0727907646C78203C81B9816ECFBE1D2B00C85ABFE0EE7BF92B9F9381EF3684400F5ED6625599D472D859D9A21060CCA7D37174945048EC244550EEABD26747F8D2F6C2D0293FFCD68046E5A83E651D65357CF82CF59A6183158F11C114934DC98E9E74CD9AB8CFB4C0811DE80B44ED75E37D1459B614801A548410909E2B9763AC2CDBC1B31F11C5DA7025E909C76465A1BD2E7F0813FFB2E75BFBCBC79B92F0F5220103F2AE62D957B9D69787491A556F45CCFBB7CCB005D5106817EB97ADBE2B83180D242190A54B88BA1FED0FA8B5BE2B264B1D9541A28DC321F0F3DAE9EE41723840EC7B703F41B6635AFA3E683B42364D69F5C5ADD12B20F60F5B3D1E19FFEAA3A98F4D61B3BF1F5FEB947DC586E5D13805C710EC734CD680EB89FFD9CBC1DB5AB3B2E01DB928C7AEAF6F91EC3AE0B48C3E133CE87B6561175C65F9A1417D048F8E9636F5751C62DCFD7EE7BEE93FC5CEF56E0D005AD82CBE3B93BF7E07DF37A8958FD74113F6765BA3614D89DF1A27C49998C88B65A2087118264FB5851581393100EDFF4A3FA54E807B042E62981866ECFE07D4C1E5DE3D49283E18E306074A332ED1E090DA35912DDE3C10416FF0A5E056C0F3BA4734668404E02EE2476C3400A51D7D9EECB09074F23CAC5FF87603BB4 +ss = 35151C059E5220D4ABAB9380FB0EBFA061148E6096D8F5678E4308CBA0226261 + +count = 70 +seed = F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F +generateEntropy = 3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +encapEntropyPreHash = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +pk = C0C8122855031D7BB0CA735042BB43B8EC6EE13061046ACAB9B873B13519C22678ACE2B59F92AA4E8269844B1DE5E3426D66C0451A8D78CC07E719033A536C2BF4C7397C64C6478BE5F42A06413B8B44111AD9742B8B020711446D63CDD64490C0917557B884EB429B05DBC0DF7ACEC032ADBBA55D3E104F7BF391CBA28B903A07712A8DA3A1A92F5682CD650A628573844032A307704FE77AF738696E974181A85C5CA1C14F7546F8713701115883480BE2CC686625A37B62292367B5E1546F4189592639CDA4CC20974C6A87C0377D15B8EC5C84B70233B64800B79C62E536553B43263532C6BC2B726970CC58BB20F0C0BD35B317D9B66B327BBEB5175D9611985AD799EBB19AD0587AEB856C288464D983256649827DE9AF0FC79AFA1AA5817C06D3447A25AB3EB8248167BA60A4462ED47C007107B1EECB630AC4707B837F24D26DA46BCDA77C4B6ED5B4118B79294744788B9A9C21B168565D9398B41EDB91517493F5FB48AE5CC04FB95BB13A8FCDB8615262408AE25C2985189BA8AB99643624B70557A984011474586C357F1C7551F0BB069336FE85BB903040F48C4A111113507055F2716D37EA6A6FFA48F40584914C4738397430D65756F298AAD345671077DA8A4173728364A493BDCA944B1879B114166CC3B8293937221257C2E78F8F1C7794ECCBF0368CE34921A2EBB01E32A92255A676E77C39564B575AA5D1F9C7D1388226D636F4F12C5636B2E2F712C59CA583A811BDFA56448C013CC820F21A36C3351AEC3C2C6F01243FF47BF17181ECAC752108C43A97729C6B9472270FCEF5A7C08665F7AA9FAA55B152163E8446C1BEE5082192B5ECEAB269EC13E7879DA3768BBEDC0A104C5E9496C63E9507881A4C8E758211076653F369E58B59BD7CAE5B9A64772C2A84329E43F492FECABBB56514CBE70970F361E6D3C6595065F6CC668C64BAE7D587FA8BBAD129136D5C9B6F757A51E653D2754AA0E35307845A55B80086D5A0E86302D306B9EE1550419B495D424F701A098220897FC47333D5A1E994C8584A00D79804E4989A1CF02DCF9A0AC2AC52BE1090BB149778235FF6091075A5360CE095CB705C81E3BE126984F51AA471F90FF98C21D3989FD936502A8A2B38C4A2320A618DF751C7099D1063495A6A5936C744A094CC1FF1B04BA8B56B0464E852BBE06176034CBF5239CD2C687FACC2CD37329ADBEC3A77B4842AEC40BE902E8AF72FA5805345668408CC7B6073097391921E765E4D76025FD5C78E246DA268A4DB21446F2CC3273861D2081DAACC2CC775631927B709DC1FA8993B1E92619590C08940342219682AF351495B2E0AAC74786C897FAB196ABB609E216997C2C7B283BFEFCA4B1F2B1B6E98991BB32424321AB7D61E4D13C44DC93295A75F6145BF2D4B8F1A03109BD7038EF4B16FC15F44CA6EA3411B68400EB20C46C11CBB98201D705A6CF4F4B792AAAE80D97A6AB830576AA651142793FA7DA0B8BEDD877217D54897375EC285849A79268BABACE85176842C601EF8C740A21C2C5321436A21CB968ECB5410E811912CB0962F713322021516535907914B86E9411D27CF164B580528768AD37B57300DC201557BB0A142D9416ED7AFEF52D284175DEC18F24979EF5BA8EDDF7CAA3880AEC7B42A147E75F0DD62B3D0 +sk = 84D7070EE80107976BFD1B0DB6CC33F3C98178817D8460B63DC012311638AA43B253A705BC994931BAB38A62C5D1DBA793B8437BD600A8725D36AA898E353D6B955B80F8578F855BCEE194CE2C6E4C6179ADE8176E34578FB24B6D60C395B674A7A8A4C72550F83A09D24582F94125690428A4E76972B77A53E852FF3718A440B67D6521CA699E5A8C434DC47A38032129BB76BCB4C810028938FC94F1741A1FB26EC95252E259B8F9176BBAD8763CB63DA6F295B460CDE1479BE8D6B9E3C49AB77845C21C8F3F88741759461E339F76376AB81B4F07E7BF0DB861A4AC5B24E09D4144AC900B43CEC07F1DD2CC4F7C976EB0BAA4D8637BCAA70946391109981E978CA023313B200092D26CCC823EBBAA85B8BA1680636D0BE656F01769555B058AF7825FA00D10A38B0A2B127A773CAB406C1D4310A0882889759F20B44AECF68DD24416D9491CB523A1AFB1A1ED87B28E5589F4059132603E228B185D426F49031AF8FA21B11CB0F37C4557F94B2F158340921F95091128C5616F54105D47253F150FF335081D231F5B308A526B9506B03E0B5C6A88394F0C9C6E7C2B475C7508A3A8B1E0D571D1C364784CC8A7CA7AE6C2B24366A0D2865658D42A8495B24A16C9A9D8B1EA77332A1058DC292EC02C4723FA7204E93EEFC24F10C4877425975CBB6142026A2AA649FC6C77E8C72DD3E5B0D9E9495A02C251B12B7AB51F6A9853BFD151A4873CAB4102DB62676496A8B38C8038E4C6D988880A6B2774875A5FE69693D9726AF64A51D77A03E523BAD8B2A6DBCEA137A051D19E81059D07437E38DB7891956C5B2C8ABE282B5A02A5530C56A7B4B46DAAB256588B04344365313A3AD94A2D7ACA4BA7072CB9259E2676A5C86215B24FAA159BC18BCE05451C69D2699A056ED3F6A7F2BC7676F11BB06CB72DC53D7EA6BAFEE89797B57445F3AE11262543A2882B863CDB455D5EA03EBA56946DC61D798A76BDBC4CA7F2A102C518224A2091211EC4D251CCFB08AA2598065A79B8B61A56E925031A579AC5BDEEF1A6E0B1381FE180DB008F19E775E030052A624B91D1550FE5365260150CCAAF228ACB8FE471D2C8B4B27BB57D62AE9AD9CE15A0B72ED98B8A619CFDD3A17ADA37CC455D77640EA327088E9C33D4281B65DC9A27C68D27088B1F2A5FC586BB0993753E62A67BC3886048274AC267A95B42AAAC3E60C2699321A79301ACD350B92899A2C0CCC4703B243660A39C5901E3B6BB146C588DD3431C4A5BEAD8AA29E04F8FDC0D04783751707CC25AC359952ABE7384F839B42D9C9982DC66A21C7FB5CB7316748423E25005D389BCD56FC498080F88CD75EC974CA9CE9F2BA995B50ECA85CF09612FCBDC492CCC6D0662A59F8CC0FF3355F17424ABB6C774A377B81C12B9982F60777926BA0B860123434CAE8F926E902A5E633019E3C62087A1BDDDF2186768BAF91656D903C4F1CA88163B8DCA041823BB6EE525583816CDFAFCCBCFE63DCAE0B93C46A14FB72114194CD084C208921925E7C55EC807EE6C0A8DDB71C4AB3BD5836B7FA160009DABD1E5498D005718548324B0339EC71AC4A75C81F522DFD92B64E3676B337758490E068C3CC747BC004DA30CECAB9C542FFCE826C0C8122855031D7BB0CA735042BB43B8EC6EE13061046ACAB9B873B13519C22678ACE2B59F92AA4E8269844B1DE5E3426D66C0451A8D78CC07E719033A536C2BF4C7397C64C6478BE5F42A06413B8B44111AD9742B8B020711446D63CDD64490C0917557B884EB429B05DBC0DF7ACEC032ADBBA55D3E104F7BF391CBA28B903A07712A8DA3A1A92F5682CD650A628573844032A307704FE77AF738696E974181A85C5CA1C14F7546F8713701115883480BE2CC686625A37B62292367B5E1546F4189592639CDA4CC20974C6A87C0377D15B8EC5C84B70233B64800B79C62E536553B43263532C6BC2B726970CC58BB20F0C0BD35B317D9B66B327BBEB5175D9611985AD799EBB19AD0587AEB856C288464D983256649827DE9AF0FC79AFA1AA5817C06D3447A25AB3EB8248167BA60A4462ED47C007107B1EECB630AC4707B837F24D26DA46BCDA77C4B6ED5B4118B79294744788B9A9C21B168565D9398B41EDB91517493F5FB48AE5CC04FB95BB13A8FCDB8615262408AE25C2985189BA8AB99643624B70557A984011474586C357F1C7551F0BB069336FE85BB903040F48C4A111113507055F2716D37EA6A6FFA48F40584914C4738397430D65756F298AAD345671077DA8A4173728364A493BDCA944B1879B114166CC3B8293937221257C2E78F8F1C7794ECCBF0368CE34921A2EBB01E32A92255A676E77C39564B575AA5D1F9C7D1388226D636F4F12C5636B2E2F712C59CA583A811BDFA56448C013CC820F21A36C3351AEC3C2C6F01243FF47BF17181ECAC752108C43A97729C6B9472270FCEF5A7C08665F7AA9FAA55B152163E8446C1BEE5082192B5ECEAB269EC13E7879DA3768BBEDC0A104C5E9496C63E9507881A4C8E758211076653F369E58B59BD7CAE5B9A64772C2A84329E43F492FECABBB56514CBE70970F361E6D3C6595065F6CC668C64BAE7D587FA8BBAD129136D5C9B6F757A51E653D2754AA0E35307845A55B80086D5A0E86302D306B9EE1550419B495D424F701A098220897FC47333D5A1E994C8584A00D79804E4989A1CF02DCF9A0AC2AC52BE1090BB149778235FF6091075A5360CE095CB705C81E3BE126984F51AA471F90FF98C21D3989FD936502A8A2B38C4A2320A618DF751C7099D1063495A6A5936C744A094CC1FF1B04BA8B56B0464E852BBE06176034CBF5239CD2C687FACC2CD37329ADBEC3A77B4842AEC40BE902E8AF72FA5805345668408CC7B6073097391921E765E4D76025FD5C78E246DA268A4DB21446F2CC3273861D2081DAACC2CC775631927B709DC1FA8993B1E92619590C08940342219682AF351495B2E0AAC74786C897FAB196ABB609E216997C2C7B283BFEFCA4B1F2B1B6E98991BB32424321AB7D61E4D13C44DC93295A75F6145BF2D4B8F1A03109BD7038EF4B16FC15F44CA6EA3411B68400EB20C46C11CBB98201D705A6CF4F4B792AAAE80D97A6AB830576AA651142793FA7DA0B8BEDD877217D54897375EC285849A79268BABACE85176842C601EF8C740A21C2C5321436A21CB968ECB5410E811912CB0962F713322021516535907914B86E9411D27CF164B580528768AD37B57300DC201557BB0A142D9416ED7AFEF52D284175DEC18F24979EF5BA8EDDF7CAA3880AEC7B42A147E75F0DD62B3D066F161D27DC34E1A2F4B98B14A2B221D7EAE26A593BFE432487D9994CB480656D8128601C28B1DEF8D393A0DB283229F7C7383152A814E7CEFE8EF9D9768C473 +ct = DA35DF2985BCD9A10982F3A0A88AF1EE00F083E6A7CF8C64D49E72AD03269EED600E6FEEDBB202CC5FBB12D0F35020B77FDCA235243A2252C82EA4E1D6120262A8CE8A668087D8AD506212240371E5BBE49CF86FCF157E7E284877BBA3FDDD12D2B0BD809C0C29202F07914683F5A248EB748FBFE64C8186CF4B14ACF2F5DE8755E35FA7AB5CE21221576EB118D2D2F9CF5AA0C1D5F8E6ECFBBC5B58D58B6EC340D703685933136B0544016F4974FA814B4AE34688E8FEDF457FD28DAF52784EFA7667041D272275264542B3E04279FE41B74F463E1D77918A5A4D6E1735771CBA792F7B9B014113A96E7A37D318E5A0137770A8F8535D8E54AB1E1CC4F879DC0FC5EBABE4711D940FAC307DA1D1152EADD5BB2883D47F4004EEB4AACA12991CAF663986B4D02CFF065C653B6689FB17F219808B5338319A357D4CDF9D293DC4C4391E88C481B1F7954BC875D6B0959AB89E540291968346632FF24D722A8AFE0E085ABFCD28BE0524578A97DDE657EB9B448DBA91AD1CB58F86FE7626148EAA1962061819821F95D221E7469FDDEEE982B47F3DB8E1B330F84DE756673EDCBC484C645199D92F637173E853E02A805D3E2D9E311E5ADC58E762E8F8D5B64A4CE0EBAC2BB9CC7D738C018FE43FAFDE7C8A1174C2A81C1737901DB8B1F230EECD6FC269EC01396E6893F23BCA652A1A6E3C501FCF016E4592AA5419149BEAF877B8DDBD2B5F9073D5BF532CD1C65161026E0D0CE1969B3B0F208FE23611F8052D54D35ED967E327613B6EEF23A473EFB91D9D23A0B429593F68C61DF78035642DEF971298B70820A43920FE8CF29BC3EEBFECA730DF4E9BA41BFDD3A00E494451F3F19498F3DE4398AE829E5DA0EAA288F9757E7DBA0CE162DBED3B8D7FA9D22D5912B147BD8B88613BB9ED81A9EE73B8FABF3456537F8AAD9B9565C8A638F96F05C9E83B8F147CF1FA829489352AA273172A577FE238A231EDBFFEB6953AB06D5AE7DC63F46B0340F78BF836EB2BD5DC4D72A31260188A888882AB30556EDDC2283879E6481A31EC28A8F3CA1A8DE59E1909B5A0B5A49E4F530E9A0FB285E970A8314F4EF7E8FEE8826A84B062D6DB950D3F15F6ED870678317CA86515485F5922F51B6921D5405F434AC153DBD18E153CDBCCAF0938CEBBE40ABA7795726233FF439D09B03A47F4E9EE894188E5629F8121366222836E8E382C7BABF7A7924991B7F810BA3FCBBF9B286929D67134B55BE9452F54B844BB2D7C8AA76EB76B11C7062A69FD5F2C4A477BBB1826FD5062905B4E89403DBC582125DA4149AD5891A79D6191C95AE2B3041C603F8DBD339FD855FDF7658974878F5369501C8E69C5A561CC2620140F01294E86B2CBEBB393637B8580934C0DEE84A765797BEB43C730C758F83DEA6C5F7BE36EA53C70D33FA62C808BA9A81EFE57F8EF9017FE1EB19CBFAC3556BDCD2FD77E9B39CF7B033F88F43D974923C04DCE51E215BD10667EB54CFC5ACC416EB447E3FC2A4EB309439FCDD2AB4470F660630BA09604626C0C +ss = FA4C0C7C5BBB803ACD4AE91E49CB8CC659A94490E8B786CABFD9B92E949FBB0B + +count = 71 +seed = A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D +generateEntropy = dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +encapEntropyPreHash = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +pk = 80B3B92647A1DBEC6BB883A4B2160E4DCC84C89C6ADBD955CC055933D3238E325FA826ACEF899A555873A5B9C189117844202C65E40EABA07D9FA94D421BAFE8F3A5E3346B6B93CEF8B75628E4418E2885660B1D3DF32D1BD50CC50757C5227928B32E0C567872E66BCB58128B15C8696710A7B33BFDA469128996F6979F896B93D22910383C90D0D877A56B4B7C77C53C99128719C2995497DD36877276A25FA8B74A4947E223215A314A075585DA457DAAF17C41711363950EF9013A8AD95F9E07635546485A3568AA502D608321061A6999057E705C46B6691183874FA9EA38BC392F718C99DDBBA59A1865A135207A00058A408B6C61772CE777456C92B28A51CE823F7524A26639AC64AA49D6903CC2B2B5B60B59643BC950230362CABA6ABB5BA4F6964331B1F62099CF385BE3F5B43C2B8402006BB3386F5A16354E45118F0B759C3363AB4069EC2C4C15CAC4E07A24FAB0C682548337D157E6BA213C7801DC5A0A7045A442B4939D611469746E9DA665E2E910B51C56B77A035900B25490216C0BB53E04173B3BC454A7A17D77283EE278E7D30496301480C8C1AF6B3E1DCA213B174F968C8A45A3BA2044BDDB1492BEF2AF610B4ED2481AE0823DF53282BA7750FBC7A764DB58E3789CCAEA778083C27ED101E3C75BE5486249F9818A08047F97447773C7DEC3BA7C59AECB5778A09CB7F1182B2E0A01C182A1BD13AB7D72AF97F96F564607A9A970B35A6ADFF275C35C22C2444AD6E997D821C065EA49080900E766C0079B7ACAE7BC7CB3B31301656FD39591E0BFEC2C33F05A0DD633BBA463781F1C519D902342BC12BD16C1AC8305EA9769E489073297784EE45F99B248670749C728385F601FC84C1FFB298BCC447537785226BB5DE712B7BDD04A0CE39226919105F06ECF6BCDDB0CB5EC3B5505B5A169B05480B2587CE4934D2B232A44A6683920A81A6038C59497C9B47FAA62F4F2120B15C360616E6573BCC5A23A88887B50D1A7DBAA429BB00A9F87B63829B1B641922425016C979DB571BA0F1A139267BB362C68F47689715CAD6636402049C2B5C616C321CBA6E43C1C1A48A0E141CF3A71C0099BD183A5C0E59BCA9A2FB637C1B534CB6687493EAC495ACC7C5FCC4898A52E44094FB1B7014A15C88E11A9E7244EE53C2D5B16708C233ED37859268501630A296D63C094F563F0E559C59453ABF05A93722AED5AC0C3CC6A0BE7890F8C3191677C21F70C8153CED3E2BD96A4BFDCE27F86B809D8AB04DFAA837FE030F420B845D23C78CC82A2D7C440897C91C3B726B4622445899DE72BFA263B93C3CCEAA8500B4B0C240046387B25BD98B5901AA670180A2A8B27DE424F4D804A68DCA2E044430D701B67E9B4AF33C60FC54BB3A94A8B8604FA5882A401A5647B8DFBB20878E4B4094136BD4B5BC14288463C2E87F0CDF6D9497FDB5F42F26D2F9CA2E048A757A59B440C2C5642232E714D11FBA959AB9AC52126BF689864AC98CBD1A633BAA3ECF75C09C4C6878994CDCB3E882798EA02AEAF39915DCBCEBFE2BA14E620F53B3D83AB58BBF99509033DB99B0ACBAC29FB4674C95CB94982AC398C2771A8AB6DA1CE9B0771E3D5C2E7655B4BB99EBBB57ADBC7A540F228114639B811C5C1D3B614DAF84266BC4C312FA43C4109DAFDE79000AB39 +sk = 47318B2CC6A9D8BC6EBE7C12489017C03214325B61A2A8541FB783C448C3A31C1D82BA7906B09E3512AF8D00D0706A3D391281F0315044C9C4F92B0AD72C60E18637577B942A442589CBB466AC344438750B86CC86B97D16339A9DB0365E6696B183041543B031C9220E82BFB89C21A5B0A0D301109568B1C00B2B878C9284375949C88394F141ABC188EF7607CB8151BAE654A7B7BFD785B44BBBB5C5A68CA5F96BFE5ABF179CB83A58AEE518202C9119C80081BEB38CAFF81F5EA51811F13BE9491F431B127783227BF9B691031145D6A144213FB4F1C89C38C00C81ABF075C4415586BDF28B946380C948B94D7A0C3A793100842230663F4EDA9174DC7214884E0F552A50D16DFD0A5DDFA7920B0AA50437BFC735A546F5B0F4BB22E174B061BC80E91428547576B6205490CA3934C9B15FCB69611A1639974478800B2CBA3D5243A0E2762BE2F87035295FFF40B56BE37DDC71915434C4AF6472C1E5C519506E691703C49C715B50B360A5C2FCDB79F59C7ADE27380F9905EB7AA6F5042C6A32BAE657C699EB85A53395C0303E87E89800131F96969BF45B3F574A40ED813268603A24F1C3180607814914775350B88A1FA7E1034C9CB155879668950AD5950803ABC0CC58BDFC408FC1F2BF7D3A2972AA66B58844C048150C0B8C89ACA3BD3269474875BF10A94D2B9EA3687AB9547EA59731B73A8849AC7B7C4B946D70B8B87C56B81B77024503BA87485BA3655F669770410E89FC84925B87C008C3CC13C7B9447D82FC2932A1C641230725A422B6219D9BDB5CEEF17E121132E6615075E0B26CF71E91A1593210A09507214716A3405B2503CA5F29D4479914CD10B3457AA62A6BB71BD08736E1519E69F709B8C8439B4441BBAB5D0911BC6737CA742747CA592E5ED734A8AA1B77450A9D4188E05422BD9240E285865D530E718C6F1A816153CC27414446BBA8129A1716171AA60AE086AD09951C2B9AA2744E0153CBD4EC9D1736908CD78E7CD75D0333434715C517633EE6603F7993083724A596069F3270C071B6BAB955844A081A896096F76059B9738D819CA3B6588D5F578058D28D2D0710B2BB2E307A5F9E18533713C41E172A99614A97C00AC0A83A25526C399CC9FA9B74CC4774830C8E754231B04274C90C526DEA7FE3D203688114E7A90D3AC02AE69A139649B754581BB56825A215C3BA282A26C036E5D5785C07C62956B612FC37FB73A7C6EBB506B998D54979FF29781CD09CCB64993299745B34B6D7F897C0E05E1A6966E6757DBEE29AF2EACBBB7701DBC39294DB584C7C3A7841112258951D88145CF73404A17ADB8CC4D11788225557A83B652F95053E8507093B2A8B00CE77E7BBBE83233DC18880F2274472C05E646B90952FE92440D164092A058D69C96869D8A83377A2DA92C2D668607DEC3CBEFC6242B49A9DA97C19C2067722C8D309CB898593B08B5D8138BF2FD1C59081614F764ACB392D7FEB205A85270DFC1129929CF7B53D41031C92944972B8BC9A9C494AB384996647E177A87A101C45C747660AA4A38088A5F7919CA46DAD338576463A1C1425A6C4409E2BA8217827AE83BED4E6C80AB528A6BBC1AD58C868B995D9F72C77E84173C9CA80B3B92647A1DBEC6BB883A4B2160E4DCC84C89C6ADBD955CC055933D3238E325FA826ACEF899A555873A5B9C189117844202C65E40EABA07D9FA94D421BAFE8F3A5E3346B6B93CEF8B75628E4418E2885660B1D3DF32D1BD50CC50757C5227928B32E0C567872E66BCB58128B15C8696710A7B33BFDA469128996F6979F896B93D22910383C90D0D877A56B4B7C77C53C99128719C2995497DD36877276A25FA8B74A4947E223215A314A075585DA457DAAF17C41711363950EF9013A8AD95F9E07635546485A3568AA502D608321061A6999057E705C46B6691183874FA9EA38BC392F718C99DDBBA59A1865A135207A00058A408B6C61772CE777456C92B28A51CE823F7524A26639AC64AA49D6903CC2B2B5B60B59643BC950230362CABA6ABB5BA4F6964331B1F62099CF385BE3F5B43C2B8402006BB3386F5A16354E45118F0B759C3363AB4069EC2C4C15CAC4E07A24FAB0C682548337D157E6BA213C7801DC5A0A7045A442B4939D611469746E9DA665E2E910B51C56B77A035900B25490216C0BB53E04173B3BC454A7A17D77283EE278E7D30496301480C8C1AF6B3E1DCA213B174F968C8A45A3BA2044BDDB1492BEF2AF610B4ED2481AE0823DF53282BA7750FBC7A764DB58E3789CCAEA778083C27ED101E3C75BE5486249F9818A08047F97447773C7DEC3BA7C59AECB5778A09CB7F1182B2E0A01C182A1BD13AB7D72AF97F96F564607A9A970B35A6ADFF275C35C22C2444AD6E997D821C065EA49080900E766C0079B7ACAE7BC7CB3B31301656FD39591E0BFEC2C33F05A0DD633BBA463781F1C519D902342BC12BD16C1AC8305EA9769E489073297784EE45F99B248670749C728385F601FC84C1FFB298BCC447537785226BB5DE712B7BDD04A0CE39226919105F06ECF6BCDDB0CB5EC3B5505B5A169B05480B2587CE4934D2B232A44A6683920A81A6038C59497C9B47FAA62F4F2120B15C360616E6573BCC5A23A88887B50D1A7DBAA429BB00A9F87B63829B1B641922425016C979DB571BA0F1A139267BB362C68F47689715CAD6636402049C2B5C616C321CBA6E43C1C1A48A0E141CF3A71C0099BD183A5C0E59BCA9A2FB637C1B534CB6687493EAC495ACC7C5FCC4898A52E44094FB1B7014A15C88E11A9E7244EE53C2D5B16708C233ED37859268501630A296D63C094F563F0E559C59453ABF05A93722AED5AC0C3CC6A0BE7890F8C3191677C21F70C8153CED3E2BD96A4BFDCE27F86B809D8AB04DFAA837FE030F420B845D23C78CC82A2D7C440897C91C3B726B4622445899DE72BFA263B93C3CCEAA8500B4B0C240046387B25BD98B5901AA670180A2A8B27DE424F4D804A68DCA2E044430D701B67E9B4AF33C60FC54BB3A94A8B8604FA5882A401A5647B8DFBB20878E4B4094136BD4B5BC14288463C2E87F0CDF6D9497FDB5F42F26D2F9CA2E048A757A59B440C2C5642232E714D11FBA959AB9AC52126BF689864AC98CBD1A633BAA3ECF75C09C4C6878994CDCB3E882798EA02AEAF39915DCBCEBFE2BA14E620F53B3D83AB58BBF99509033DB99B0ACBAC29FB4674C95CB94982AC398C2771A8AB6DA1CE9B0771E3D5C2E7655B4BB99EBBB57ADBC7A540F228114639B811C5C1D3B614DAF84266BC4C312FA43C4109DAFDE79000AB397537E68CCF14E8B7E57090D8F648529DC461CA3950288879E88116ACAF57B4A2B6D75EAC6C76CED1B0A025B40A55440712AD8424672E761E9BC400D63812006F +ct = 2AE65FF9BB3921463D5A4FA59032DE79451B71137E7019EBCAC2234F3478E1E4C4172B97515BEAA552B9580D76BAB278B304B83B05390BC98EC094559F3D21FAAEA79E5D0CF3F9892155BF0E4E989D3C85350C66A94DB3D006530119E4E44BE9B2312EFF20F06D762D4CE489BDDEBF30BCC765A1553AA5A3B5F620DE634F64DE66F1E56D288266195795794441353674E93C69B7D86D829695EC15353186460C20ED184D5AC56917276008772AB381EDFEBAA45A36B8294D9B84C4E5518163E98DA4B5D7461D28493039AC8F378A154152CACDD3D3AAF66EF966C0FB298978D9C293979D0582BD8271C79F5922769D8210F4C7F198B73CD0249330F5B25ED55964F2300694FD1C1D438E7BA0FA0A6AD12F66220A390ED79CE1C40A7A6F50C64435BF538A3A2A1BC859118C35477AF3AF986CCE9BE6FE75BCAA59ACF3FF7FDB1C873AFB6CC5B69621F6B49715A0F362CE441961C452CBF81C128A2B81C1A1B667017026C09DD36AF0DBB856F0D7A4B21CD44003A878243955A12E62F41737D81C16180BD83297AC9990976E506684A24E4F97737E463823B025BA95873954C153BD42DDB06209ACF5BD7E9C9CA404D57202F7236FBD5949004F73828A59FFCAD810E038C741534F044A4BD4FCC0668DF733A7609E493D753FCABC6359B959582A5DC66CDF50A8C88A97B9738F2CDAB363F01124526CA23FB047432789D6C1E430974329411F8C1C63936CDF937540F66C2CC9B76BAC4D9A44055386918370D8051CB79C8C703CD37D3B6C1D53675EA2BFC7976D40ECE547FBE3B969804341FF267CDA5F583A95D0169BB2359ABA56378F319F8587E602459AF732CB1559D684CC4F776E1766F1CEB1483A4D1983E8698B56B37940EA9A7FDA8C8CF9C9E0DC724CA1D60E0C572894D2B9835AA9E82C058FB28271A5979E397AE0C2E72629BD5A56B995F2E3D9DE0C7FCD608E4DDF8A4B0638B1810B70D2B3FDC358CCF45DA5A22C000E4BB70F4067884BFFD9E419C7825145BC80491B417A26567A6B91ED7D89E8E9E9F47B24B0FE1C3DACED4EABB3D1571DBCEFB3E3AA7AE52DCC66AD97BC87B629875165FFA709588B4725E64B07781420D6F6CFC2B485BFDB7CA3D47314452A862050555FD324C5A56BAC047F43A3073F07B05BCF14F505CE528BEF347A2CC2C846675E4EA9417B7E741B776DE1D767A4F3573E78E7D5976E73C8F7CD24AEE462294B4E652460C66E6A4A5F1591446FFEE52A0A61526D16392AA40A4111D4715709FC70AED98E128342F7DA9EA80412C749C80DB3D64C5DBBDE06244C18DE5EDE7F550A8E086F21654994628413E9EA53644B2CCCB530CD1B2288BB9E51F529271E9A9EB795FCE68A74DFDD2CBCBBF98407D68E691C11A979463322B1402629C2338CFB2B14A7BB2CF9AC8073E6E5543E3E989B60DA52F1E07859F591DB172A877483FFD523633E1B8DA9E68BA748F2FFEAD7F9D3882E9FC56D4B4329E1A22CE06E11D0F674C568A2B1218BD4A16A60AAC59DC30FD6B8B76C06A230C39393BD +ss = B7A8E7B3C6D244B6B0DCC45947DC91F795ED21A5B5AD545205CD5B210DF37325 + +count = 72 +seed = 6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A +generateEntropy = 1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +encapEntropyPreHash = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +pk = 03A20A0337040ADAB8BD449E0BEAA93B07512485BA33F291AF1A44540BD04AF4A3DD2A09F6454D7304D0944674A580551061BA5F88217AA57C10640DC1A97396F138C1A32CF40B0BD9286F88C4087F9084A9012D248C63EFEC072D77AB0E736719A23A913B7B8B62AAA5BB40BE97CBBC1C29EDB283C776AEB9B032E2C2691AEC9CE89617B84B09712B40E2B713E566C714E0BAA75957D6BA5062BA76471357252B72AC66BA97E10921CA2313A232A6BA908DEA13645B5617938381FBCD748A11F61CBCB615C458D056F0D55A449C4F544C6673322EF106010CF139D1C586AED5A5DC210FFF7A60F3138C34A4244398B692C567ADE5BEB55C1EDCFCBD93183E1ED0C2AFF5BDAB67B51E39A58BDB8388D67CC1EC0D7313B7EC8A56CF3C9B73214C4ADA14592794749B6834E9B81A2BA47DE929E9AC7856B56549F40F38F0784BA0CDFC195952D3155222BCEABA0E3C233FF7E19A65822437217A42721F9C060AC2CBB9C4E6BFA9FC3014D8ADD7B4BDF78291423511F9874A07E06A82B6369FE349E08333C7F56B7B7B808A0B4E888A95799A2DF4873944CC43EB958B1508C66E571268E79A69178793E7A4D430507E1259D01C86F999C16772CFB7B4B330114FF55A51EE5407BCE95A6D27875A91773420C24F8734B3023E9DB777819CA2163C431DE46F22F38398D46EE352B815B6B07E1A242B01A4230B59EA8C7B0C3C3DBE2B7C77B4C860660DAA04C452E391C710722C67BC0632C072FC1E5296A2E70932D4D38EFBB96BD636BB41260A7BF27CF5E71CE3708E6884CF0B8584ADC3CD3B5C5EE1003A13731704472A203C8F9B49534309BF2B60CC3E2448E02B5A46D889FFD78FBE722A709A2D5B5C8A7D805BCFF44052C553CB990AD016079BD87DB7573EB1D431D1E549EDC8AB56A0BF52999F32555E8EF2B03182BD8D812CCA638055A73B548C8B432A2A7D4A6A074AA212D50362D1382747CA8DBB95E03945D95B995D6346D7DB47B24B86E4F774F3767DB7996335B789733CB251F9B1EDD04F8F8CB7AF4C947AF224DFE0AF6A42C7B65120B9C18ABE9161D88CC5C4780FD74403CD177F7160281884A11CF686F0F523F39CB7AD39B780F13A8EE83C0D646F9D85BABEB306D53A7DF53AB00B5A1AA8C215914A48222940FEE10D1939BA5C93617690CAE113A59DE071C969436B3771FC50B2F4AA641A4C852922380A420FCDFCCB81816F4B474A2AB293A4D97B2B280CEF031148EA7E4C9C0DB7E7CD0E50B203A6B7519C3CBC8062C9B60B8B81CD956463B8180C67F34BE4868E3BA94B9F0226D9F010D9EC5EF0BB62C865C807184B96526D94170AF9474BBC100530F7C77E46B98C2AA41F92A48D8027C855C7F84684389BCC8E7C67164A204BC5C0C90828FAA439FBA235B6F20785CC8EF4C090A708BFBBE26E1933886CC96AD9B4562A119D4C66589C85BF0E55606886206734142D432C1B032E0AA93EE3731F069A8CC069A03B95A8AB873B447A04EAD3A32BE3054AF834882BCC581712BE18539B805577E50FF5D982C98C0B0DFCCC96A4C6429281068C8429997DC17A6600F0736B8453E3D77636FAA8D0CA89F9193BB34819CA1117EA368EA23198EE11345C613993EC052992954099BB9A086057DF0C5465326E1932AA50DA74AA8435D9294FD6B7C05A153F30 +sk = CD28AA8C74142A0508C2534D5ADC64284806BB2C653BB9783ADC640E9945C253AF86F57C19B42C6697AC85D1BFA46B5231559C11F5A0DA9B2BF43C40001D4E6C00B81237343E15A41DA190CF8940B641A4B42B72D9CC8BAC681369DC07D80AA62F135B0F956355A4A68E575F34393C42BCCEA68A7A63C269A5821557299FF63B9F0161368F6084132C8B56984F4D1626D7436DAE2596E1B24A86562374B066D2483A1B354FFF9766845480FF396F6AD089B724B0F15A34C2288DEB05A8418909803CBFE2F3C63C30056F358FAB798F4E385EB0E35ED0C38ADE7382787A2502D117AD0BC6CC0A4746AAAD23345F10074B21970C18EACC898472766B2313472DD3348C82F69B7D961CD35A8C61984E7CA20AE6382F04A977A72B532A1395707CBB7CD595E0DA0202498058E59F22E0C340C438851674E3AB1E0D872FDA3BAA7F87B67F449E6BB461BDF1CD771475D5B59FACC30181599DDAC8CE68DC2DE5741B21422FDD512B39D9633ADB202AF3941E323C9326297CB58086C3282F722C4D50B94B32153FF30B91F07A811A9D9E07B7667846806B6F7071AE29323156B668F831A9F79AB7949CB363DCC8D151349DB4B5EC1266E7F5AF98105C95C0A4D47648AEEB01FBE1113948B407FCBE199BC2CDBA40257745D765C6A0766012F19DF41A770E96CC95D3CBC70549F7E61914A73DC71062F2A3A377EC26DED59E0CC85B11A74F43C3237C7561CB7046C0E660B5BB0BA0634FF2B211438A9B9B906F241B04B2439F29A3CF0AD9128D683F0C2C26CA050978CC179872B1664A751458C072106FDFA07D97105188278268B0481018782F361D08555FE5799A0654398285B378F7A9F143CE20673184C75E8B662085899812912FB8A60485921B2F7B3FEAB95CB7AA327D8B9DBCF7C7256A131270B731E33F8F555CF4F8B7A1E6AABB4C83D2938B7B21BEB1C3B3CB3BC08BF52FC1F5715FA89EF8E205D85862F6A2CF420592AA24568FA0B8DCBB90D0B654C7C82C7411B6C3E219F46C352AA034C4FA0AA4FC47DAAC204B351497727B96714359A66466F6C4CC2B83BF6B87785367C7116489D6C5FEB975E41C4BBB2A3D8FDA920021C523227A438374D96032F62C41B17422584AB5880475CDDA8B7F4844E5420C25D97235B0ACF71012ADAB59298BC80052AAF1807E8015695D92184741BAD318BA9AE27C306A2E42C80512534963B70B9D0B7F5AE70326C33E7D43249E8C9CE386947C167C8F33C88947244989C45B4858203249FA5A136734153CD94F1AD467B5043F7ED77F58D34490D1B5F9E323F3E2146011921B8A9F94E419BB85AD965443E7F4A73534457BE43EE5F677A63A7738762B799600FA0B9CD328AE4CF507C1D9845EDA77C30BB7C39C618AFB402CD9B016F0092CB61E8BE13A18925CA122A142409B8DC637A364093CD76925A194AEDA21C61709255BA2DE330693B888A6C2C6F0C39FA5B4C7FCFBCC198B3253C0ABC5AB5EDFB438ED3A82B72B5F54A39D21C37879480C4A648F182A94EA566C598BA4CF697140A20FDF4CABBC540B80E8664216A6E880553899964A7B239D00C68E720706512CD2A58B9C49BC0ACB90283B506CA196F7855ED69AB21F059A11FA3FC4670D03A20A0337040ADAB8BD449E0BEAA93B07512485BA33F291AF1A44540BD04AF4A3DD2A09F6454D7304D0944674A580551061BA5F88217AA57C10640DC1A97396F138C1A32CF40B0BD9286F88C4087F9084A9012D248C63EFEC072D77AB0E736719A23A913B7B8B62AAA5BB40BE97CBBC1C29EDB283C776AEB9B032E2C2691AEC9CE89617B84B09712B40E2B713E566C714E0BAA75957D6BA5062BA76471357252B72AC66BA97E10921CA2313A232A6BA908DEA13645B5617938381FBCD748A11F61CBCB615C458D056F0D55A449C4F544C6673322EF106010CF139D1C586AED5A5DC210FFF7A60F3138C34A4244398B692C567ADE5BEB55C1EDCFCBD93183E1ED0C2AFF5BDAB67B51E39A58BDB8388D67CC1EC0D7313B7EC8A56CF3C9B73214C4ADA14592794749B6834E9B81A2BA47DE929E9AC7856B56549F40F38F0784BA0CDFC195952D3155222BCEABA0E3C233FF7E19A65822437217A42721F9C060AC2CBB9C4E6BFA9FC3014D8ADD7B4BDF78291423511F9874A07E06A82B6369FE349E08333C7F56B7B7B808A0B4E888A95799A2DF4873944CC43EB958B1508C66E571268E79A69178793E7A4D430507E1259D01C86F999C16772CFB7B4B330114FF55A51EE5407BCE95A6D27875A91773420C24F8734B3023E9DB777819CA2163C431DE46F22F38398D46EE352B815B6B07E1A242B01A4230B59EA8C7B0C3C3DBE2B7C77B4C860660DAA04C452E391C710722C67BC0632C072FC1E5296A2E70932D4D38EFBB96BD636BB41260A7BF27CF5E71CE3708E6884CF0B8584ADC3CD3B5C5EE1003A13731704472A203C8F9B49534309BF2B60CC3E2448E02B5A46D889FFD78FBE722A709A2D5B5C8A7D805BCFF44052C553CB990AD016079BD87DB7573EB1D431D1E549EDC8AB56A0BF52999F32555E8EF2B03182BD8D812CCA638055A73B548C8B432A2A7D4A6A074AA212D50362D1382747CA8DBB95E03945D95B995D6346D7DB47B24B86E4F774F3767DB7996335B789733CB251F9B1EDD04F8F8CB7AF4C947AF224DFE0AF6A42C7B65120B9C18ABE9161D88CC5C4780FD74403CD177F7160281884A11CF686F0F523F39CB7AD39B780F13A8EE83C0D646F9D85BABEB306D53A7DF53AB00B5A1AA8C215914A48222940FEE10D1939BA5C93617690CAE113A59DE071C969436B3771FC50B2F4AA641A4C852922380A420FCDFCCB81816F4B474A2AB293A4D97B2B280CEF031148EA7E4C9C0DB7E7CD0E50B203A6B7519C3CBC8062C9B60B8B81CD956463B8180C67F34BE4868E3BA94B9F0226D9F010D9EC5EF0BB62C865C807184B96526D94170AF9474BBC100530F7C77E46B98C2AA41F92A48D8027C855C7F84684389BCC8E7C67164A204BC5C0C90828FAA439FBA235B6F20785CC8EF4C090A708BFBBE26E1933886CC96AD9B4562A119D4C66589C85BF0E55606886206734142D432C1B032E0AA93EE3731F069A8CC069A03B95A8AB873B447A04EAD3A32BE3054AF834882BCC581712BE18539B805577E50FF5D982C98C0B0DFCCC96A4C6429281068C8429997DC17A6600F0736B8453E3D77636FAA8D0CA89F9193BB34819CA1117EA368EA23198EE11345C613993EC052992954099BB9A086057DF0C5465326E1932AA50DA74AA8435D9294FD6B7C05A153F3082F68B15681CCA5C2852C18D6E88BCB102A059C1D21936582ADB71790CC0A335273B38BDDC18488024EC90E62A4110129A42A16D2A93C45439888E76008604C6 +ct = E7657F1E554DDBF021C005B3B9453285A16D4D8CFBA2358A97FD2AAE89F83DBECD0447BDBE9589DED04BAADA5114F3BB1B4B775C8BA614008BA2D5929EDD4D3DAE28253164D131CDA2FCA2B1D4588E176892764848B62172F56AC74C2D9052347F857286781015FC8CC1888A3FFB77837B1C79128D15A405DCF2A68E47DC7FF1131C89E5268033C9304088E6924C59AC82B424122E5B85A55059198598E2BDB173EB0FE9E407B46228A4B16690097BC82941A66404EA7EFD014807CB4CE9D8EA9F4CD3B3A7643A5FAC11D493197DBAAA40BEA54ECB8E0FFBBD887B2501985C019D252D3D663EAC74466008FF6749AC901F3470E755269BBC1D77690F4880B0BF0FD8F0115C2B90BA408D3E1FE46A845A47DCBB404E4B12A296E304920C3828191CBD9B9C81A8BB02EEC087FC9F018EF936297D7A52339DF66396129E4A1C18820CB1BA69B26C9BF1B68C886F8ED7C4F61EBF2AF19402AE037D990C77FC2699D4D22683F4BD46A105459055C5C713E8C1DB1DDA5CE6A658184D26ECD10E5B1D523241E494396A99DD172372737129C29F8C74BC30858076FA33034C44997D084A6C5BC791C4E8C9869B1520AE29D7901B743ED50E9AD108B37132F34FD1D05FD4B5AE9634AE0B1B1C1C46FC1FA1B73A794DA19FBA6FE28A299E6EA7B738E45FD1FC0628968F32906D9486E3AAC29B488A17A7D6437A9F139DB14C0B6F387DFF426E107D2BCB3FB9EC5658B4351A20487C31AA367858355AFCF508F4B6740D912F726C45DE57359683FD9CB65F7F0BA8AB8A319830E6E586C293E953539F85A5C264C30721137128D0E0217D69CC195772FE97D536B8B47643B1A67B90E198D320652833C03F0C382A45F86522966303E3365C6F5B743C53B4F7CDB931BFC894211F71097EBEF6ACA00074DA9465528A82D24718D54473E333C9070EDAA7EB6DB2CDDC806F5AB277EA8EB3DD1C93EB6F433CFF71694EC6560D2F664EA4113CA1FEC25F37BA7083780A2D91EA6F679F3A40172154A053983099F83D48F3BF50C795A832C9F70C88407439607844BB27EBE20F602E0A88781B767D6C2002960B2BB98754A4618301D9973E3FFE8513615F8B0F13175376AE222FBFE36C8125A570719F62152C2945BA648F534B85CA8270CB7DD5B955E25961116DEAD8915466ED19AC772D256B7DE7B10A597E44FFCBB0032C85FC9E5A8F609E2C1C9BD888ABA0F0708B579729E6B7E5377641DDF0649D1B506677D316076E482A8F166CE186448E504B4B9607CF5F3AF8F7B5389049A79E15473F130904C3BD8DA512EBC26951134E767D6D5BAFEE7C6326FBD96DE4239B7229D69331E76EF0D165276E5A2D229D49E3215803E0B82A63E0B20231271DF111F1C27F9F1632E4F86E90DB18A4254521939F6CA60AF9BD7AF584B2109DB991D9E2B9223E0ADD7D5D92B597D0AE7657629B256B5ACEFA958422606C84EBA6C136925815007D126322E9854497907DDE52CB68F65AF75370CAF56467DD1D6E9DA860D26DD4F1E33006A6F41CF3423E58 +ss = 70CF00481198A97F14E0870C268CA55B6EF787D130A4C32314EB7C0A531CD188 + +count = 73 +seed = 53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864 +generateEntropy = 3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +encapEntropyPreHash = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +pk = 611BA36D3A65C0D17CB22B7F3A682B593595B1C682D521A16DD621A05A7D22C9B2D29C9BB75CC5A8567ED3A545BAD39E2C85CEC0F83F37C6AAF101BEC273BCA5D606A5E76FDC183175A233C93373E956580A522BADD22D97D71199C1A7B4149E652686EDA541E69187A2ABB68F89AE9492443547CFDE7B5D609B4835911D154C33E49248C4CBB244ACBF03E93E52E71ED87A75CBC43C3F505422C1AC31C014E82009D4B13BF2CB7DAB16896A320FE6C0476F37767CCCCD80850DC94B410B983FBBCB484DD09B44A817FD95686106C710D983CD2BBC11DC4AE59091A401A6941BC704142C792C407F7524EDE1A71A726E2F921B0626768307C31DAB514A783FEBD67B50E93479D2C7D1787142F591607B7A5626A718D502B37A6F5B8766E8175C6EF276934A12AC1107AA3362840513D3F5C02042AE681181DCAB30F6810389DB07C3FA1790345E786031E3196BCC01C22BD064B2F9C439D7B7A7B7633232AAA4D88E0288CDB791049B8A8C64883637098DEF7C88FBCB974554AF0F3C51C70A758176215871227869766452871602093D6949E1D078691537D9D7030B36926147AFF8151CFBA202C0364795122D1D748A18289CDB33982900B38EF9AAA5D10D146985C757CE5CF82AE0A2489E0C00C83550D455A03FC885DC7A5EBCD71529ECB0CA13CE1259186F9B0CEB4B90789ACA0762C8BEE063780801CE365540F440B0AA0128103AE0F5B4A5D9B98FF3AEC5793E8FD046A7E15B517C5C4164105E87C593DB19B85792B6C705E615C4D95C38BC4BAB4F30737A20241A3189EB38865C6B60F6341DFB931626E729CE39313E122687862BCED934CCF88411730FD066BE831542ABC5B15A1CB2D3F0AEACE904CB419754D9A5CFA35D72E570C8D3B0BDE5A5B18201F14CCA3E3564C16769757A2DAA89B03DD993EC8B7C9FCC63098478AF1890346A8824A4B142F88759F382292AC404F436BD21282D6A3242417B36211C84B75F388151F087186CFC01E59383E8218039DB15DA50120AA1C5489743BC42335A774F8494A4244ACB6677B22A46224DF7BDD8A9292AE58E07F3068CD975ABB51E44631172535E52C910B48748A190C50D877903A4C7B9F4B18993669D254EF566058528A157428111D43D360AB54343ADEBC2A3636720F1E0C8CCFCB0FC3B71B55353C2682946408CAD171FB711CF0B3AB561BA6722647ACEE4B8DAF0AEE2C43352609DC617549841ADAC54ADFD3319EFC715DD917AB2B887DFEB49CBB6323ACB566E43638A5C9B6F865DA4157CC3F866066A551230A335510F55733CA4F3A6329AA0830894E06A05EE578C45B3117FD07D62718A9842CED5F49710F7B15741BA5B06298C550B96BC6FDB0561926240FAF09012E2CB49C66868E27EA318AAAC50BF882C5BB8E674381A96645B7A7DFA936201933C31955E24912E436528027B39F74A909AA5EF4653CC23C5E448BE6F81088FD322FBB1779BE52AD60005C2F57241932EA3B435C47A39E6E0477B989C00BD5EA71BA671D8A37DC64D36216CCEBB14E6DC7420C362926B555598B92F6A78061423A4CC8961D57733982FB8C78573C35584185FED801EA674A7FDA06008517B42D1A45FCC50416883D0963D3B744EDB5E8548C3B3DC474F7843C49A8DBFC939C41AF7F8EC6C8354AEB0C67E05EAE0 +sk = 8DC4A33D0A013D102A7ED6A5303693669033816BCE0C8A83594695531999647A48F6708C65220BE4D9A60F013201A36EE053796356B26E3617126C3D0A354D2FBB82312A372FFA37B939A7BAC8AD0E127F18EABC771462FC57B542A73BB7067FDE6BCFFE4982E6DB3394264D34DAB222318856BA8B6919C5A0A667866C0D2166B69AE04432C044F289BFD7255542CC7946B82C2DB388C8B656F234A3B607C2F6611ACC3A5A12C8111E42138ABCA9B8DBA79921A177682C2AD1138B133636951F5AA77A52B7554943AF52F7B53D0B84ECF44FD77018F7062E564C5E58753994724242D6B3A8F8A66DF518F7E13A0A5C1C4B253DCE12AE197342F5D72C296498BC9888EC347F528958AA689C8DDB81870184C9E2254F918B7465354826870300790044165216C8BC279AE93854381C28CB438BCE444B2258AFC3A84CD4F91DE8373F877B30137C4CE4664E4D330BF763B344489604E97F4C9C24FFC226D07C5824CCABE38CAE22487EA2EA0E89920F304BB911B401F45735089512DCA2298EA1A57F643CD7524A3D6C9F055B25EAA62FBDA318A7B8C8DC9C5CEA953AD5170C0452A7BC04469987712D0522256A1EC52961561175C32ABE93DC5ED37289B9D4CBD3966911FAB85FE47B3C68692CF5A845286BAEF91493E15C6D23437BF7517EC5CF609C8628D82FF7CACB54D4A5EAD25C85F59AB51151F9350247782459B598A2089A85F2C9BF66797E863A4CA0732268A4E40C57009D0C7D1AB1FF46B78E350DBFC19FCAE823BCC040183A27182ABDE00A966A6075E68C011AA62EEF913024CCC85B460098FACC9C4C81D17C577BC009B8F9416D225D156C4E75B84691A90948D31883B1B2AB3635DC357AE867B2496983CF9595423C541E3C17947042B3D141EF825C99862302BA911C67619434B3F9CC489E8C8ABAE92AF1EC3045C895EDB41F745AA1F3D1A625E47EABB49432129A5608571431C4890C8FA5769563B8B1F9BA3C1B77B034F568038865C90304A4F79F65F74C17FAB9E6B52236CB636EF5B686271F955A9E889B7A1EA1A010828AEA1A838DE1723F0149CF172F48890161C34039E99B36185F068B5707FA476D650BF149479B8C928F93089A4B941047B5B528135685797E0B9E65F595D9016A614393CFD630C6A217D0A03091853F606B238EE13C92C2B5D9E19B2C57638CE82A3D767639E115838B8EEAA5A47B7B686EA05CC088ABD47A10AE593AE39A07F55CB4C1347ACAF7CF59422182749E6AEC39D62CCB876094BA3CC0B871C57A03A00AD67C5C1C6EF911C6DC36B13CAB713BE1A6610CAA46DB4EBB86B76572A0BD60ADF163B325C89B506C33CC343C37A2BCA7CACABD90494F044B550778677C2EBEE76E03622705556B509C204087B5C5E5936C0153857691C3149521B800B76C43195897067529A4A87D68E974ED57178B7980EEE227E4150AF1234025757EAA3B645064202D632EAEA3943B40CB10922BF569AB2C44867C411BC8240D110134D78143D3D44B450056BE166B57921FE64A44F80968A1941D91A971E10C347ABA369702B1ED542984F28B6254BF61D94B69F015B0E32B05E8897502238FD21D87978EAAD45BF5997654B40A903319CA64095C9297611BA36D3A65C0D17CB22B7F3A682B593595B1C682D521A16DD621A05A7D22C9B2D29C9BB75CC5A8567ED3A545BAD39E2C85CEC0F83F37C6AAF101BEC273BCA5D606A5E76FDC183175A233C93373E956580A522BADD22D97D71199C1A7B4149E652686EDA541E69187A2ABB68F89AE9492443547CFDE7B5D609B4835911D154C33E49248C4CBB244ACBF03E93E52E71ED87A75CBC43C3F505422C1AC31C014E82009D4B13BF2CB7DAB16896A320FE6C0476F37767CCCCD80850DC94B410B983FBBCB484DD09B44A817FD95686106C710D983CD2BBC11DC4AE59091A401A6941BC704142C792C407F7524EDE1A71A726E2F921B0626768307C31DAB514A783FEBD67B50E93479D2C7D1787142F591607B7A5626A718D502B37A6F5B8766E8175C6EF276934A12AC1107AA3362840513D3F5C02042AE681181DCAB30F6810389DB07C3FA1790345E786031E3196BCC01C22BD064B2F9C439D7B7A7B7633232AAA4D88E0288CDB791049B8A8C64883637098DEF7C88FBCB974554AF0F3C51C70A758176215871227869766452871602093D6949E1D078691537D9D7030B36926147AFF8151CFBA202C0364795122D1D748A18289CDB33982900B38EF9AAA5D10D146985C757CE5CF82AE0A2489E0C00C83550D455A03FC885DC7A5EBCD71529ECB0CA13CE1259186F9B0CEB4B90789ACA0762C8BEE063780801CE365540F440B0AA0128103AE0F5B4A5D9B98FF3AEC5793E8FD046A7E15B517C5C4164105E87C593DB19B85792B6C705E615C4D95C38BC4BAB4F30737A20241A3189EB38865C6B60F6341DFB931626E729CE39313E122687862BCED934CCF88411730FD066BE831542ABC5B15A1CB2D3F0AEACE904CB419754D9A5CFA35D72E570C8D3B0BDE5A5B18201F14CCA3E3564C16769757A2DAA89B03DD993EC8B7C9FCC63098478AF1890346A8824A4B142F88759F382292AC404F436BD21282D6A3242417B36211C84B75F388151F087186CFC01E59383E8218039DB15DA50120AA1C5489743BC42335A774F8494A4244ACB6677B22A46224DF7BDD8A9292AE58E07F3068CD975ABB51E44631172535E52C910B48748A190C50D877903A4C7B9F4B18993669D254EF566058528A157428111D43D360AB54343ADEBC2A3636720F1E0C8CCFCB0FC3B71B55353C2682946408CAD171FB711CF0B3AB561BA6722647ACEE4B8DAF0AEE2C43352609DC617549841ADAC54ADFD3319EFC715DD917AB2B887DFEB49CBB6323ACB566E43638A5C9B6F865DA4157CC3F866066A551230A335510F55733CA4F3A6329AA0830894E06A05EE578C45B3117FD07D62718A9842CED5F49710F7B15741BA5B06298C550B96BC6FDB0561926240FAF09012E2CB49C66868E27EA318AAAC50BF882C5BB8E674381A96645B7A7DFA936201933C31955E24912E436528027B39F74A909AA5EF4653CC23C5E448BE6F81088FD322FBB1779BE52AD60005C2F57241932EA3B435C47A39E6E0477B989C00BD5EA71BA671D8A37DC64D36216CCEBB14E6DC7420C362926B555598B92F6A78061423A4CC8961D57733982FB8C78573C35584185FED801EA674A7FDA06008517B42D1A45FCC50416883D0963D3B744EDB5E8548C3B3DC474F7843C49A8DBFC939C41AF7F8EC6C8354AEB0C67E05EAE0104FBF09445794C0EA0654F5CAF70EE09D51C8386D4E1F467B10633C710AC2A4A3729672816F3EBA84C9638A79676EEAC0F22C8A48E0C5D50A26FF0844C66B99 +ct = 8B40CF1A2D7E21F68E130A85C5A680C65DF56B5CC055D26AD8E6A7E6E75BF88FCC88B5212F2B78521DF1A8F3B1A1D3091CB9270D1AA7865FD1E3AA8BAF208FC1A8B80CDB1D0F229489C15FB02D60F44E09E942D9E36ACEE57013F2F40C17477DC8D2BCEB137E92C140314E8D6F38328056119C757493633D2CDECA9C0E1E727F47406BDDBB7A9B056EF6E4D149498CECC738D835D0D99A5703B0B9BFF04883FB064009F6961363323B7C47E35983F04ABFC00F74A63923DA69CFE3784F8999F6E4ACDC9B9E06E743C03B4C0CC2A404DDB7654888DAF0FDE21FFB1A96D81D95EAB5EEA064938BC105439E287EAB89AED0824DFD4CE65ED0B8A8FFB674AE38BA39A1FA3A8DCF36CBA494A5855ACE0B4F8145AB9C636F1A4D6AF147FF23F94C021E2DA8D0D05564D6C85E502E753B8EE49898B66B6F078A99675435FCAB58BA8C9979761906986DFA4BE67314A3515AA24A0C2757A95509498E08EEB103AD02BA5711E2C84F25E651A611C5C5E48DE5BA54F9C2E6D9930D7F861D14F5CFEF3D297593ABB5E77CEC126846E15238FA7984D05E86DBDB12CB1D44445F9538F89FEE20F677F05437BC27068C61D4D095CC68327ECA3764972B494FD2838400FC3A6F6C64D4B17683A7E778C3807C6F1C1C6A4D92AFD6CAD80DE8C57F06BA5919B10AABA0605F19F61ED80AA119035F37D3F6D8A01E2D72E6C53E47489B5DC876CB99FA742618C9E5016EDCF26D78174AC028C832A1C1AE30514ABF95C35A35F9387D3A30946AECDB5642C0B84150FB8F0ED1DD06F59FE575330EE2D9D5675AE705986D1308923506D47EA2B2FFA7B92FC2C7B2745A07F6D331BA484145C98EF78736A77AECD75C56D719EF112646F57F6166986FA33655D8DB7D2171704C5D69AB50A9588EFAB7ED1B834D8903F2770CFACB204A4B143262AFA85E20DA03D94C22A39A9145B9143E4952722C2CC6DA0723566BB2EB9E1F2C30814A9B80DB5192A673D3A8E8003D30C910B9D31191941E824563B41DAB9FA47C6725986D5EC406B8E43915057D1EB15F68EAE588289D5C4D5AFC0BA4FE38D765786C4F4820415678F79330138D2FEE5E060DF6FAE9B1CAC289FE2D20B298100D0FF4EE76B59EE7DBCA227F4579BC507EB05AF390A2A445BDFE1885D8659A776F3DC6BBB760F93598DBF29F80108A2F007C901F158EE5328BEA6893550FF0E2B2C51FD5FE1269177149B89CE127A7097832003DF2A420FE8D674EBB2CFAF2385C13643ACF832E2D27309A6246FDB1CEC405F1C39AA2986BE172A48F8054989DF59EADF564D99E075CF9053574FBE0B5FBDB1E4E173D4336A8ABF77A6348CCCB49B5B1DC1D75ADC8647792D3A6C4AAB50FF8C0BED7E3A094D0A6882F4547317275837DC7BF460FD37A396E6A4F3E13C404239C58C9EC850FD89C7359F9BB2751FB60A932EEEBCDFBD21C8E3527E4455352AE13D402D45CA7948E6211CE31ED48FAB0ECDAD75D0FE5CF564D521FD2EC76BF52829606EEA3170BD44545B710F2D731A18BBA457B4530EF9BAC +ss = 2E8FF9C053137CA6B6C31CE8BA7F14135A7E102C211E68EB99DE12B94273F9E2 + +count = 74 +seed = DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E +generateEntropy = ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +encapEntropyPreHash = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +pk = DB0A138C9442FD3A7580E68EEC01077D31525465BABEF901806363A2D664EF8C1908A30491E336E27B0F8690AC71C30ADB145805A15FC654AB8982565EAA96FECB93A2EC7EBB697652965FC5AB837F6B7A20E224E4361977B71C694A88E5252F608CAC97E97DD7C80A5AD10D62681B57162269F7B8D812AF039226CE2A7930E43007C0B3EC6A4CDB3897EE85796D051CB053881E1B9706A572CCC75D0EF32F92610C40DB4553824F1A352FEFD979A310124B9456A9106367EC6A50DB6FE0B057FDBB00A46028C0D6A638BB7F2139CA6DF68F014C4E1E0B79670869353912B5D67EDD4B77C70C067AA76D174CCED6C7A901C65737082276188CFFE28BCFAA2604447E68D490C0F11CD22B8C351C2D63E7A01EE460BC408E174BC4A6CB023492C6EED42F5D85244EC883B1B49B8E3584F27835F21B6B2E6060E0671F289771D124168E196EDACC1ABA26CEC9E09FE7367F46893C2EA3677CAA3005E34E722608A3B64A3B987289952DD695A82DE89B9034390355C5E33546EB833F602CB9324C095BB4CF66C05FA0AB98D69BBDCFF155C3169F3DF2A575901724B678FB080B67F32240AB8F0198CB43176F6FFC93FA602748D591F0B2ACB9AA67A8D8B15C27140C320B0EE040E737077A8C9FD6A20DCB865FF51C41808757B0CA750C502A356B1C7D821F1BF804AE2B337819C5EA89542E079045C887BA6550E4F05693F5C7012424D37A17E2294669C0538CE69A1F1C1F121784E3C3537424BBC4D73CF1A685F03A24C4BA8FD603B328D2A07FA2B714DC1EED17693727732EC7BE2B02C0614CAF3D42B222061DDCD758A0674133E6CFC5362F855B717695ACDB971AAF16320690606C1C42238856D757B5D610BD64427F04C97ABE1BC6B0185116CBBB2DCA28B5D7A9AEE205DBD37E92BB36311C8936D958AA1744CA67332A600D8C719377273C7FB0029F27C75817746E1058DD196DE71B0E4302682DA21B4EC1BECA3CBDF690509573959D816CF5FA034CE01D6A4AC477E3BFEA75732678AEA6C0A5401C623DC225C7A9A7AE6A572F738387181913CC71B9379A5A2BBDC45773C6A1167FE756E13731F47226BC678331312B99428B07B2122B2B9DC86B01C5F090FF632FA83B598863C0B42623549CA831F66BDBBBB1D4747D56A97DCEF9C81766A3D90043C1A99CE5E81105E9113043342A539DE446A7C5F9C4B46A8CADEC388FBB8BCA527D90A56C649200CB2A7F968611934014F9A7B6FAF3015BF6494EF72FBA0C7BA40C499357ACC96562C65B9CA7C53231045E35771947172118EAA02CD95F7137C93E2159D9389607C3011A76363560A97DF950B0329258B0126C7BC10E4081CE46B7C7B0AF0752B038386E9AFA2D0A7543D85AB909376B618C0A2D33875D264B76941430E81C48832F43270160176ED5938492A06CC08392237CAA8487ABD3C83019000BB6671784109C7BC4C2A0362A5B5122E620ABA511C49CA42D75091B3B1ABAAD9B8162BC27F182AE310872E789CF05F6C949598C41C3B73A1A9CC0808E68F95C8AD8392F021F77C79618685DB2FB1D04A9A8ACB8441CCC764AA3B191736F5A24AE31C23428390C1C22C6A6052664DB63B94960A433584036C05E031A07823A03CA153015FB2665C77D8FCC529F21AFDE0D4F32CBFA399F2973D812F516C86B +sk = 38BBB649E7520A59AC57783E32A5022489365713CCE30171AB46AB219B7E81369AF44BAB6F5BADCF613E963938A0829ACE625BD8594ED3C0981C5963F68874AA87685599041C4C296B4CC181E57667D499B2F961F44773CA958193E97988D816D702078C0147E41390F503921F139384D75EFC91CD08544536B4C9C09BCC2914A807E090D98B5C07C1A4A0C16FF0EAB557E5CCC1871BA1A36FF66B1ACD113FACD6BD16053F22CC85634A3D56E564E30862AA1409D48AAF92643B62009F8E206C2C8BB7F357B9432A8474349C3E1679F1D154CFD4A373665A86C481B9C3163308CF3A1A265A6313D0068BA2181AE5E5A1114995005C8FB574C4A7DA80562953348A80BC23CD90C37A2D166EE4E895F2A429AFF3C9EEEB869EC9982D367C5809396987A2EFE93DFDA2CF45E774CC3541BFE655A7280AF9B7601FA5183AB62682465FDB273AB435355B84563047BC4C6204AEC310D4B91E8B849182C16A57605A6F5690D3804D8857379E11B324977F30B461954A17CB16C4DD93761224A47F4C680373C51DE251CB69A2C737CBB1F76D7278033AE86480C7776CC7CA02393F333B6CC00C200AE58922756D3664A30D7B262302672C27A7496746F8F56797726340C734473522FA880819D76A004A480F48B74F7C6EE1998741D39FEC12759670B4E8057AEDC67950B929E200526BA5A27E0BBB67570BAE100B77D525AF70B7B6143A7419A35273C14B492E1E42C5B5918A62F3C829A50C1FD8715B030CEC454C90C72E6509AB1936AE7490C6B62A6720A840AA714F7B6B0134335C75C44A421598B790631E2CA497E256BE08910B69C01997BCD20591D1967EF5EC5C035B0C1F19A01BC0103DE6CAFDA45DB70950CF551DA2442741EB7233B36396C124C6365A83B66D9CC896FF448F54194FA05267B8154895173075039143DCC58062CBBB1946A917ABB184788052920D1428C856BAFB3461A463627EC7430671CE75BC2ADC95622EB2925A582A15E487787389BCF14DFD84801A37BC39136CC1A49CAB7CB924772606D48D3941BCCD3221EB418B12A6342AB6C357F273795339BBC720439AA9CD5A478122B8B01769EDB013686C8E872A4E2C049A755A8F954614665C61D5D9AEC7D67CDDB779512A308BA3CFFD5C4BC642C091226667C40957C17B3C92BEA102143DEC663B6155464AC7A9559C533A647C5A106C38972A26BEAB45C2F04C974C9BB860BCA64615B6F0782305C81862ABC973D280088BAC791876D3172D4E340F26452F60009A49989BEC107B680B62CDC12751F9079ED07C28143A405A600A974230B20719B0953DA3C2DA574CE2C31786C77600646E25B3C305F6507D91084A836366C273D62C526E0630F9B483CAF335D6BBB5BCF4ADEB4143443A07055349CFB690948487F7795B67DC2E45430E7A5C9564CC84CAC0AD0832480AA844417446B9B086A493B7AA163B76A50F35B7384BD054147A8621674843C3040CE06EAEC68B6CE8A2C5B42390C76350E10DDDB35C9F4C4A1CC148BA08601F92B2FB12C9088922C3463139239A62E878E4DB61A3529A8FA7905A7A1AAF90216DAB5026469B27D4122AF5561BB91D111A721A78587EEA259A4C7F6B743574398E30A119DB0A138C9442FD3A7580E68EEC01077D31525465BABEF901806363A2D664EF8C1908A30491E336E27B0F8690AC71C30ADB145805A15FC654AB8982565EAA96FECB93A2EC7EBB697652965FC5AB837F6B7A20E224E4361977B71C694A88E5252F608CAC97E97DD7C80A5AD10D62681B57162269F7B8D812AF039226CE2A7930E43007C0B3EC6A4CDB3897EE85796D051CB053881E1B9706A572CCC75D0EF32F92610C40DB4553824F1A352FEFD979A310124B9456A9106367EC6A50DB6FE0B057FDBB00A46028C0D6A638BB7F2139CA6DF68F014C4E1E0B79670869353912B5D67EDD4B77C70C067AA76D174CCED6C7A901C65737082276188CFFE28BCFAA2604447E68D490C0F11CD22B8C351C2D63E7A01EE460BC408E174BC4A6CB023492C6EED42F5D85244EC883B1B49B8E3584F27835F21B6B2E6060E0671F289771D124168E196EDACC1ABA26CEC9E09FE7367F46893C2EA3677CAA3005E34E722608A3B64A3B987289952DD695A82DE89B9034390355C5E33546EB833F602CB9324C095BB4CF66C05FA0AB98D69BBDCFF155C3169F3DF2A575901724B678FB080B67F32240AB8F0198CB43176F6FFC93FA602748D591F0B2ACB9AA67A8D8B15C27140C320B0EE040E737077A8C9FD6A20DCB865FF51C41808757B0CA750C502A356B1C7D821F1BF804AE2B337819C5EA89542E079045C887BA6550E4F05693F5C7012424D37A17E2294669C0538CE69A1F1C1F121784E3C3537424BBC4D73CF1A685F03A24C4BA8FD603B328D2A07FA2B714DC1EED17693727732EC7BE2B02C0614CAF3D42B222061DDCD758A0674133E6CFC5362F855B717695ACDB971AAF16320690606C1C42238856D757B5D610BD64427F04C97ABE1BC6B0185116CBBB2DCA28B5D7A9AEE205DBD37E92BB36311C8936D958AA1744CA67332A600D8C719377273C7FB0029F27C75817746E1058DD196DE71B0E4302682DA21B4EC1BECA3CBDF690509573959D816CF5FA034CE01D6A4AC477E3BFEA75732678AEA6C0A5401C623DC225C7A9A7AE6A572F738387181913CC71B9379A5A2BBDC45773C6A1167FE756E13731F47226BC678331312B99428B07B2122B2B9DC86B01C5F090FF632FA83B598863C0B42623549CA831F66BDBBBB1D4747D56A97DCEF9C81766A3D90043C1A99CE5E81105E9113043342A539DE446A7C5F9C4B46A8CADEC388FBB8BCA527D90A56C649200CB2A7F968611934014F9A7B6FAF3015BF6494EF72FBA0C7BA40C499357ACC96562C65B9CA7C53231045E35771947172118EAA02CD95F7137C93E2159D9389607C3011A76363560A97DF950B0329258B0126C7BC10E4081CE46B7C7B0AF0752B038386E9AFA2D0A7543D85AB909376B618C0A2D33875D264B76941430E81C48832F43270160176ED5938492A06CC08392237CAA8487ABD3C83019000BB6671784109C7BC4C2A0362A5B5122E620ABA511C49CA42D75091B3B1ABAAD9B8162BC27F182AE310872E789CF05F6C949598C41C3B73A1A9CC0808E68F95C8AD8392F021F77C79618685DB2FB1D04A9A8ACB8441CCC764AA3B191736F5A24AE31C23428390C1C22C6A6052664DB63B94960A433584036C05E031A07823A03CA153015FB2665C77D8FCC529F21AFDE0D4F32CBFA399F2973D812F516C86B0F353D6A29813D354471EB8B4C38DF93939EB3B1DB80DDD1CDD6558A9F2687A3E03FF73E02A217659F53D8C47556BF3D8C94040F630D63605E2D0F923579370C +ct = 087B75B8A26B2B4E3C850D95F4504A5CE2D9F2400F84645F51D95F572DAD4AAFD3C99F5A8ACD682F7655E23765502705A4AF1574AB38705D4EAC749C78EFE1532F45646BC3358DC2188DDB8A271E8CAA490F81078A9DC3602948F68D392A22E62D584881DEA33F273F1B400C41AD60ED97C67AF9594F44340A49FA8EC7FFE1857CA2785AF21B5346F275D5303BBA6F0D4A0D5A105428B444FDAF0990931E49228C18F90B81A9A8B1B85466986080D0F8D5ECF6256484CA2222F075A718371D15C4AE79FFC2480496C93E2D9909A61AEDC1D29F583CFEE4CEBE3EF54A0A2727E00D5D0525679AABBDD574856CADA9A7A112DF04F7395910D9BEDC5D8B3A373CBD2603012AC33D3523D55C0BB4AE0472BC04C5ED974F6954CB4A7C0D9672BAC55840DBAE2323258746DF9810F0A3CF4C4155C943EB2FED097E481199BA5BD6D853EC00336C751D5E0E853A271FF1F735E4C431B3B349A0874A49592D416554C65D18F7C489DF1F8C633DF432EDBFBE05769FB6FBD780D89451FAF60EB9230F1DE745FA3A68E200FE2DFBACC5C530E6DBACF9022872C84A84390ECA3763402518857C111151F68FA31954892C4F52CB2506B4EC11E466C43225C146530C39387D065A3481DBA695EC9F3EC7FA0859DED1AAF74961A03330F47F213F68F2053840D488B09D72466EF48E3CC7AC30415B574DA8F45C636E19AE109693579D9D66AEFC5CEFD59DC4BBD71DD16F8A2243B113D04B0366B00799A8B4167CDEB34D3CA6ADD02F91578A31B97A4ECF993A34D40E69DB8FB294DFB3EF35E3FBDA0575CED7B1DD09F3C05D645A1D67B73AD22AF881C658D5BC0FDF5E03CD57C77996F22F6E55115D962AB57068CB6A83A96ADF997742DAC616F40BBC391BCE131A18B41FA51D3373E1A70BCB8E40E333BD13BB27C8B60669C610FABF07B83E5A7B908B116233DDEAACBD9511ABF1BAB725C1C15BE87F16C7C82237D37B3916D6A91C55B668801EB4C37E5BCBCB27CD25DA2D218C6FCA8D0AE1EFDDF6C31C1EF2F1BCC6AF451122FB9BF9E7F75DBB5DA4CDB5F55DFA3E56C099C34F624C83939A38EB99D3B734E9EC0959AFA21DE5C2C4BAAC40571218F0CE0193CD912788CA2794F9F48B7C23800FD0F312795A58F723CF1B3DFA86A5D9A1EC9D036F29D6DB54C3DFFF3731E1A0827912C0580DBE616D12B2904212189ECDF5DCFE363A07DD51C0CAAD17CF60AE567C4A2663273D3A639483665AF1A0FD17AC29B9487CF883F1F6726F49918E161419399ABBA4C60FA27471C61B46392940E83B447B1D56D98A2B64B907DE903FBFB88F9EB02E89C46CA3F7B963873F607BC7FBF4B1561DB504DFCF2CD78E4C5F859F49793AAE1427CA2D2FA70FC0E7067F7E5AED5DA6372E95F54186F72971FDED9DE28F7405AC23463A4478B1CC9721EC7D2D07A302DE94AD42E990699D71C7A5290CF3B65E316E3AE2CA9CD349A0A7F7483970B0179352AB93D4A4B110279C9E5D4B0554D904FBA60A710FCCEB98423BA7FCF5F6C73165B8D29D74058FBC +ss = FFE9448FE824EC92022890969F1FA8E2FA87E5B3E95A9A155839177CD3C8E359 + +count = 75 +seed = 8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13 +generateEntropy = 6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +encapEntropyPreHash = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +pk = 35A0C8EA287462D8CF8841CDC9016796500E61E89EFF672E87C667F453C8CCD148B94C9A9A3765649CCC6E1C05E5350218D091783B6C7E4958A0807E73E9839992C8C36A87891B7CE5D7122E38B5CDD745FEB1058FC2827B882DF77CB564323746855392247B054527EE862ABC91A557C431E55B81D23B1C1A94992EF540E07338FA944D24B17ED4E693EEB8224A0C5307202457C8033AA4651B2B30F85A9BD8070D1B11675FE240A1009DACFAB21D50036426A6DC9C3DFC05CD1612BA91DA51BD5A0F7EF9B235F1B3B2641747AB8A380B42C060357BF259548CB80788CB41DA4C7D3C4B9401925588920DF255167240F6B092C1329799F0039B74CBD549B2C053A71D4641071A3A95A460B2B3A8ADA727193267DE555E6CE87986AC06E647C4B7967CDBE5083C4B99A1B44B5DF58959C48BEABA0818608FD4046EA0C09A28416C6A97A1066C0650CA619D14A056252D38539F1C2676B69CC53502487389648FE596783BAAD0D7627CC6AB2DA5B6788410B67285841A323E04D037F25E103B38B07672248186C969B04661AC6B2753C5429EEDA389599B78E84608DEA89556A9510627B29E13B1713A1442158561DB8F435BBD6234A420618985DC4F71F0A5F15762FA16084F178E0E76BFC9EC5C35FB52E52301E6809CBB287D42B7591828AFE605CFCC93C337BAB78B55237B075A8BF08C48C15087E82600655234FA99F6987DA7904EF50A1599867D56760AE1D70006925ADE67157508289F137DEF9B9714F4CB72A017EE6A6325F9418F3A0EA3A8762C55987AB406DD9A6D248A33EAF264774AAFF6F00607F37BC20041D3A170E07407792A43C5407FB3622CCB065B74BC1A54F86AF9F7246D288FEE725A6FD85E82477483F778D5388728C4565467A9BA3216D92089BC1C742A20B03BB526B73573CDC91AA8E085F1ECCD1866280E791BD1E43D4843A440E050E2967DAAE26686CC2D32F512332CAC82095AB0005133023E75C9C92B0388BC8B2822A82F93FC3520972E2E0A062A388931092BFA8758F251895C641186D1B40F6A332DF3088BB24381DA133CE40D3461A7D87A93E702472E49AD91CC013C936B02A96C4CE14C2B23AC79869C6D139C8D85B58DA27C6EB4C4250BC3DDAA56DBBBBFFAF452C09074E013A3C7599CD5B8A876076523C6B0AEFC6A503BCEE0FA76407B779DB92453F7AAA4E58401CBC6F3718A3352013E1383B4222572118878C99289B91B02D929DBA06C6DEB6F4C2B0459F86D04FC8D287B6A676B17E45997027568BF7BCCA05C3D394C1557873711174242CA50CFA30BB3D715D1400807CC5FF1049CE720BE3C360FEBCCB61DD7244F4352B655A517485AB13B413983CC089749AC7144312966B2C67AD50096BC176142858881F09E3A075F8FA6BF638A13AF572BA026A172B23317A01A999C8C1EF478422CBFA9802F98F2856BD6A11F8584C532807771C19C411A2900C5A57C9B8E44B4C07B3BE3477BAA738AB2C407653A309D7A82CFC6B86A1B59AD1251E008598E453E04E3306C1877DC703869DA25A9B91FEC80AAF4F30B4D0A83E2DAAAC73990F05A9002D6ADA0409450454291E37112A9AD97147CC89999DC89A30C809757933C5D0356F329BFA3823D34197B7D9E60E307BBABD9B3E8272A0EF1B3333269A7AF6A5BB8740BFA +sk = AF361347809757C2AE0C4A60393C90222C394CF136E95517552721FF136DCC234D64715A1AB43D15708187F89A6830791E0062CD43253EE486AC54179D320FA6A8BAC4D0C07B7158A1ECCFE52C4847403849982D73288877D04EAAD37D392AA487597F80F19AF7444E5A82CFBE51609AE515C1B320B6C75AEFC121D5E2904A0185654A418E5C7A379B41838ACE149B45C5A4040DD239ADA846102A6BBC811EBED4710B2393ECC4BB8C6254DC815D2667831F962887A74EB883A5A8642E0B427450D01321246A8797B7BE1211EAF64B0C706EEDFA17CBA2B010626112AB6B2B2B928DF38CCBD9B639B9C6AD090E92DA98B5C9914549BEB6A9B5505579A56943D210722BF590D63C1ED56534A96552005226C34CC1AC32572D2AC0823BCE348086096525188088DF229536BAC34A1C95083309A0971F31D975DE0598E4E009D24661B2A79DFAE85343B94FB1BC171493AD77D767E0814837348616205652EB4F98838CE536691DE8C3AF0A4970EB0C3600B4605841BCB0884E08BCA3198B04B2AFA6F575229C56462B9516026D32D2CE33A4B1ADD3B411371EA6516765F457613CCB50F94AB9395F6FBC94395A6C9C104CE3B79171A83A49B22ADD3A915086B804C3B42301BC1F14630EE3217F059AEF485C019A4248B4A78A516D75919EB2B15BB1E5A34CB6B470CA7A797BA1B5193CB4565497F98BFE30A7578044867897C332687D925C8BAB05D0C35693F557F541B571D6AB7E4A752B80267B0329D7558FE4BBC54C8612AA95C03F81641A129B1793160DBA78C4E0269E9361087328A73C67C0044217A25C2E05B64A1B8EBEC972606BC220B1A456D8BA86A76AC4A3C06429CFB6035EA50549DB887A5F6170EA282BCC295A2EF000F571038FA97B6BD98FE0399ECE3755D4B55E16261F7FAB678C394C83676CB9F080BCC915C8B1C67DC998D7097074249585E31C5B30BD0250ABC570531DB43F546C2E05983A7B5219127809987343CF722FC38525B2ECAAD2CA703679CBB7500420F83960D7505BB7B7B59A8B6F0C876C7A53D893A10468A516FA7A6A08C04D3259AD003DB768559E173DF06A08793B10E5A1A46145B6F0FBB230CA504424B4E9617CB3F509993567B4CB94CB2CB39811BC1EAB31B5F5691FF4108E5A6EAA9B15DC2AA45FC4AD26B9CA007A7C2A680ACEFA88F12790ABEC7E3DA1C13A355C1C669117070A7E1976F6859921E273F53632B4144B58E0A74207100D2CADE0C8A0410814D40A4234843A44978D0D4A173BE52434760423235F5D7C8E1F56C8181487BBA930CC9272ACD524EB6C9D71D753FE62B0E9BA33A478B7E82B36D9690607550ACA261085A08725281B02E531432B35398B7ED1355B8172776926BFE41880DF90AF6951A58981C708724DEBA6B6C2BB8AF1C0009C71A0B82AC0D14CB0910A8EC3988251DC9E93F17E067608115C85BB6C47D33A2A9359A35BEB47C3A04AB65537F59BC1EBACBED4B97855F753A954929B6449A4DB7D2098CDFC04008873004BC535BD5C74DD49247419601513C4E8125731307BC858845896A67D33902AFA4B58B50BE969B947851BBD791D66887CC6E92E19A2B92BA6BCC2825C4239AB2894B2467547FF3A63BEF65E35A0C8EA287462D8CF8841CDC9016796500E61E89EFF672E87C667F453C8CCD148B94C9A9A3765649CCC6E1C05E5350218D091783B6C7E4958A0807E73E9839992C8C36A87891B7CE5D7122E38B5CDD745FEB1058FC2827B882DF77CB564323746855392247B054527EE862ABC91A557C431E55B81D23B1C1A94992EF540E07338FA944D24B17ED4E693EEB8224A0C5307202457C8033AA4651B2B30F85A9BD8070D1B11675FE240A1009DACFAB21D50036426A6DC9C3DFC05CD1612BA91DA51BD5A0F7EF9B235F1B3B2641747AB8A380B42C060357BF259548CB80788CB41DA4C7D3C4B9401925588920DF255167240F6B092C1329799F0039B74CBD549B2C053A71D4641071A3A95A460B2B3A8ADA727193267DE555E6CE87986AC06E647C4B7967CDBE5083C4B99A1B44B5DF58959C48BEABA0818608FD4046EA0C09A28416C6A97A1066C0650CA619D14A056252D38539F1C2676B69CC53502487389648FE596783BAAD0D7627CC6AB2DA5B6788410B67285841A323E04D037F25E103B38B07672248186C969B04661AC6B2753C5429EEDA389599B78E84608DEA89556A9510627B29E13B1713A1442158561DB8F435BBD6234A420618985DC4F71F0A5F15762FA16084F178E0E76BFC9EC5C35FB52E52301E6809CBB287D42B7591828AFE605CFCC93C337BAB78B55237B075A8BF08C48C15087E82600655234FA99F6987DA7904EF50A1599867D56760AE1D70006925ADE67157508289F137DEF9B9714F4CB72A017EE6A6325F9418F3A0EA3A8762C55987AB406DD9A6D248A33EAF264774AAFF6F00607F37BC20041D3A170E07407792A43C5407FB3622CCB065B74BC1A54F86AF9F7246D288FEE725A6FD85E82477483F778D5388728C4565467A9BA3216D92089BC1C742A20B03BB526B73573CDC91AA8E085F1ECCD1866280E791BD1E43D4843A440E050E2967DAAE26686CC2D32F512332CAC82095AB0005133023E75C9C92B0388BC8B2822A82F93FC3520972E2E0A062A388931092BFA8758F251895C641186D1B40F6A332DF3088BB24381DA133CE40D3461A7D87A93E702472E49AD91CC013C936B02A96C4CE14C2B23AC79869C6D139C8D85B58DA27C6EB4C4250BC3DDAA56DBBBBFFAF452C09074E013A3C7599CD5B8A876076523C6B0AEFC6A503BCEE0FA76407B779DB92453F7AAA4E58401CBC6F3718A3352013E1383B4222572118878C99289B91B02D929DBA06C6DEB6F4C2B0459F86D04FC8D287B6A676B17E45997027568BF7BCCA05C3D394C1557873711174242CA50CFA30BB3D715D1400807CC5FF1049CE720BE3C360FEBCCB61DD7244F4352B655A517485AB13B413983CC089749AC7144312966B2C67AD50096BC176142858881F09E3A075F8FA6BF638A13AF572BA026A172B23317A01A999C8C1EF478422CBFA9802F98F2856BD6A11F8584C532807771C19C411A2900C5A57C9B8E44B4C07B3BE3477BAA738AB2C407653A309D7A82CFC6B86A1B59AD1251E008598E453E04E3306C1877DC703869DA25A9B91FEC80AAF4F30B4D0A83E2DAAAC73990F05A9002D6ADA0409450454291E37112A9AD97147CC89999DC89A30C809757933C5D0356F329BFA3823D34197B7D9E60E307BBABD9B3E8272A0EF1B3333269A7AF6A5BB8740BFA12E89C47142418C26396EF0174C02F69DC00022D56494D31AF935490EDEE63859F684FB055ECE19459EB464E91E126A7A6E3ED11CCEE0046DA234D964C985110 +ct = 1F2D0A172AF9DFCA569878612151E46E0784B0F2DF0F81A2DD709CB8ABF57585E9AE0E68B50D48B506C84A8710F42826A0CAA795495203ACCF99E76AC2A06B184C9C3F011367F9431A4EBFDD0F57CF8B3B5F0BE55FD0A1EC018E1A2D898D1F126980CEBCB135CBCD5A23E9468261C46592082D9712DEFA7913999386CFD2F69F7907D28BAD9E0C1DB983DBB9645BA4CFD15FBA1AEFD667CCBB497AC67B77C382DC498E5E4407B5E3805FD1680A723B6CD64FCA2A962ED8117BDAEB3ACEEFBB7B1D943B91AF4CE217842EBD7B67BE89774258C2639EF840CCFF2E1C0B0F1B03FD536366B99200B48F110E9ADB48A9AC3D77AB8BE563F5B89C50309180C4233416CA2B0606B7AEB390BE541A468B878E49C79AED0E5472539762C859E1B04CA23BE4D12ACE5C9511B9AC563272944577CDAF9495F95B55CF91BB2D4FBDCC513452C32F080B11FB49ED6866FDD443C3BA3581B9DBF550CEF4B4C18E7A8E2DB5E442DEA3C09AD5A3995E5D4691D13EC4710C1ACFC2CA3CFEABE621D54AA1E13DBF3FFFEC5189E2DFA14C382F21D17EDD9CFFDEDF5AA835301428110333A723EC6A8BCCECC0B93C62A763105F1E32F6F6F15B31DDCE5F6F95052A50CADB5143D195C47B317E7633D37BF11DDA9F0698299BCD25CF53DF532C2684EFD4B6166BF5F5EEA80CEDBA05B8703513767F158EF78D1E19DBFE7B6F38686E8538B6924A0EC78A5D9E4E2A12D4F3EA7CB55FC334486AE00F7A9289694FA7B59C64C2DFA003015C9785DEE363E7825CDD21815521E4438DF858EBA176E1849305D87E0D128CE5281EA24B6DBF821025DE118C52DDC6B60ECF5E527486FFA58DE8A1EE1C4F3314400A0C72687617A03E0FCD606D4B6A4A36B777FB333661DA0BCE06E96A497B5A2B915FCBA5FC8E652B486E5641BF62FBF01278D62C73884EC4BFF145674FB8220E69D7EC8ABDF220AA8F44C90EDE9B1EF5A026817E6BD389C365FDCE6DA3F268F3D4B1C98C9321098D76FAE308278FE8877F7E3A9EEEAEB57DB7B5D9CF671B969AB9998B048E4B37787ABBF9D6B384EE41756EFA4B2235C070A7017475BC808FEBD77A6EE3FFAD7A686BEBE6E84BB3B0C8537399EB39292FCC986D8FDDA05DC3E358E5CA02FDFEBDD84AADD7F78E77E2C8FDDC372E00AB5332683D6FD2BC00FE3758C616CA954CEEF955498699D653F3E35A22B5B8A385588EBCDA436A9DB907A5B069BD8CB0AA5852EE037C31D9C3C7A6AEB30624600D33625DE5DFC69CCB4DFAF0876F9A85536AEA7F67ADA95CE0C3426B9F3F2C51352D721B2EC3862A9B57B4CBB3495CF41883FFB772307166227759F745C9904AB2ACB946E5D38CE5346B9EC712E623F9D4F9DE43E5BA41159BA3D6C18F515CEB0775A38A2DF97A042A6673FAE30F1C957CB6B6E1A1E9C90992E03CDF0D2D79B9EF3D00639EA26BD33E8495958D8696FDFF69893B956E61024137C207FF6B46C2E00C1CE77BE0F3AF4DAA3743E420C2521640A159891CB26C539E1BBF35F6833D64E62FA1DB57904D88681F +ss = E3F110E7D74400CB476B0E34141A107D874986A3732ECC103D9BDFE76BD492F1 + +count = 76 +seed = 9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C +generateEntropy = acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +encapEntropyPreHash = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +pk = E4749BCD8577D50A102352B869402EFDE59F5FB54BBEE919E7D4A8BB8CC40FB8C7240401113152BA727CECFC8E4B817C5D537DF050902BD03DF866317006A2AEF59CAC269813A47FD337A0C5B694F4B080F100089255614634A2B0BB1ECBCC3F1D84CDFB3054FA749736E531C2E673716079CF45C89B444B7D821D892C7EC39A74D39B815C2B9981CA47F5E56840341FF9D23FC877285F9B90FC78BEA1B9C5C647AC52D066AD7B8CA2AA01E0729FA22C39D9C3C6CD833C6AAC061AAB1C1EE6819D2A245997B8580A9E1630112CC6B62C4952215A3281111675F25A10CA0C32BC68C7BC920BFBC7BCD82EDFE130B0434AFA29B2B9D90AC3F1143B5664E5E51984B52D976439794507D92CB256A1520078972B843FF3DBC6736602F68B289E0850EE845E49586C889CCDC104CBF13470F6F6C0E6766007E5C3A1348166933A45A1A62E0B749EE14A38E11A094BAE60A38C84079D81AA655782138671A0FA186A727457D351A8A45B6FE05369F7B158DE844E31117DDC47AF9FE52075C6ACD5F93A31C38EC7F608FF9096C8562E0271A35FA7265A56B24BF31C6A727376D1AB3F600573342E60884F41D355B2336E464B94554B7C108614C3394FBD561A2E74BA7045C0D74032877901E4F8A95C41CE9FC72013C51FA93B5C0B3C3B0A8C90CE0960F510A9F6A453B8B0012F7C2430350B8A4B6143AB5ADC7AAA6F3533E230C3062B7CAA33B1E9A3BFDA7BBFFEF8341AD0A33AB272BADA717A4790F4C99CF430BF114B62854810EAB7AF582A2EA327A599C490E25795CC5C42219771391B33DF4C7FC01524C4C520EB4559C2EA8C38AB5CFE27035C756248662C1E969EF478A2D2419ED9DA7125EC32B0557EDB5B77E0DAB221544E5F7A57A2941B89B803ED1C7D8DE65F64A29D8E7BC2020B723D391987F83DB0BC35E96AAE7B2772B37159A3257EAD277532119CF55959FBEC482169C5391A9409877C79255CBD1C8D2B8352CBA074BC4714DEB09F9CD81624D2782DE91EFBC30882C45631E96E35C9B53F77CC0D268722BA5EB858A1DE719A88EC240DA229CD7766B9A237641C1277C006A6672BF61AB5DAB4C223B7381FD3C16704CF7920B2F11210C969B6B46A152B72598DE4AAC1665D72A45BF51370DE61559F83081DCB6AA49339E489968C80498550AFC467C8AAF0C6C1B9085699B801C75EACC3142BE38DE6F6A64AD6708C426EACC13B09D8BEA819BDC200258D31A8D1F308D0A7470DD35161379191576A03B81D70EC58565CA7C4A6BB333338D8113D70F5BEF45B6835917E17C2945A06CBB7F2225675252F351593B06A6DB504B6E67C6E88763FB06879187C5053029724B3477281CC5C5294B36B64F12A08084EEA098489D5CAD338A0CFA61231268BB866C2C524C71BD6A467C845AC7A4EAC579049734970859A2EA753C6B93EF01532B130A103C6244A17870B75023E0014E6D8433AE5CD2B145BFE253A8BBA300B6465FCE277E2FABE36D6C8112887CB0A6DAEA4A54E258CF89071E407594DE1BF1F4AA2BEB50263DC5D5FC729B632957375B5CE6373D9B93211A66A29736A6ED616EF8538E95C45BF595B2EB743D79436D6385BAB74C80D88C1A1F4022E6C3BB3D2294C474C2C554F3BE4D7FAE86455763B97EC8FDBE9640219B35FC36033966A3525D485F1 +sk = 31CB44A14C3FF840758055BF2AFABAD14A723C048D4D20C5908BB781844D574A96A0807C59D5192548A0089396A78B953AA52677B9A111CB012954B674571C5D0C7C5E6488D498290F7665F4F32DBA7228ADE2A724413798EC32619901215663B2C26360612558070BD06261BBAB86B4F96056A498BF37B1B84238C5099EC8F1AF4251C0862B861F334EEE85AF8D364A54F6BAD0E44A23A0577933CA8482889A955086EA3A2C94B057C1C20D540CD6D2976126854AC123CD386A855CAA385927318825494861079AC84606AC0F1810EB78A8398740BE69CFA1777C61A5CC1D758AE28C072D6087C379A567648558AC8A1883734C64361DB33CDD156FD371A2ABE534B162C6E336143B944DC2309AAC106525D6586793A2B3420358185FC787C2CEE3875E3425BE5627C1D49313413EE498B17E8C295908B718B3C4A6E03024D77F1EC37EAEB7462E09C683CB9B272431EF0ABBD0422AE2569FC37902AB90BD2C236F4DA66D78301A61765A77E43ACE81102C7355749C1463B55F10E26727086D73A1800924C6B0EAB6EC905D5B01ADC538C9EEC7A25989B85F24B1F68B9A22637613E9ACF609A67CB20B38BAB1A8D81CBD22A5EA8C7587A13BF8EB8A37E5949084C26B4433741A31C502A4C412535FC6A1C5000057C65103027F78F81DDFC4A8843C59F8563BEBDA15DA543BE2146A3EB7B521700958BB2A5064923236193D981BD1E2920D00B1CFC504E32495DBB116C5BB7AA21B6CEC5C9FC0B1AB73330544E7AF5BB1CEB7C159E3509938D0332CF51ADD245606617DCEC688F117BFEDC27DC5B8B4884446861B592B720B53FB23CF08513F66C3B51833E51B9A63E297054A8C03F8BAA257C64C2C8A265A8A92052C41146BDB3A32CE0B7196AA33564806DAC33AC05A20178C2A0CB04000D484F0325C9D16956DA0AF88F68BB72B7BC6B122A486CC1EB01BD3027AA316C6D7C1AE7D8B9A747443C5D7237989A93ED939D905832E76AFAE4172D5F70589E54F7B5CBABB536E5F316B3D38911513B400AD83F7B2A3C72A6C09EA3B4F68129ED285FB99442FE61237D61756A2AD78B7790EE69748B79E42EBBBD6B9B0D803A3EB77477609AB2CEA5920128356C369878855126C22F1AB66A3A4C202892C8863B609F7926175CF1E3967EA93B7ADE7A8E6779672023DD5D81BD4D9345AF36A38DB17E96B8D85B7C0BEB586AEFC9FD9EBC585F071C1B9C34FA2283A60884A0CC5EA210887AA677D24192DB582F05117FA189C868A3CFFE8B2FB584686EB3D009733E1D86C07D6A9893C7E9410B4CA99A4A880B48053878A45340D0056031068A63113BE4B51A630016875541E099935EA92B2668AE84C5A183CBBFED619691038973CC07B72ADB803CBE26986C827AC75428CF183CD5FE7C9C719378438058F470B62FA977DD658F219983F97B517BB1AED01A478A18DBB89AC1B916419A3B25F388C276C190B866356EC84C33B29022286C08A34D26948C59341A789CFA168ADC0C7A73DB36A72EC6C2C688C06AA3EB1FBB25B7B828CC3719C7B2473719F4E2B5C4AB8A4FC172A132439E0E3AF22A1BEAE17BA4CF39A155925C62A4C9CA76436496646906630B9349A335A4852C01B018F77DA15E4749BCD8577D50A102352B869402EFDE59F5FB54BBEE919E7D4A8BB8CC40FB8C7240401113152BA727CECFC8E4B817C5D537DF050902BD03DF866317006A2AEF59CAC269813A47FD337A0C5B694F4B080F100089255614634A2B0BB1ECBCC3F1D84CDFB3054FA749736E531C2E673716079CF45C89B444B7D821D892C7EC39A74D39B815C2B9981CA47F5E56840341FF9D23FC877285F9B90FC78BEA1B9C5C647AC52D066AD7B8CA2AA01E0729FA22C39D9C3C6CD833C6AAC061AAB1C1EE6819D2A245997B8580A9E1630112CC6B62C4952215A3281111675F25A10CA0C32BC68C7BC920BFBC7BCD82EDFE130B0434AFA29B2B9D90AC3F1143B5664E5E51984B52D976439794507D92CB256A1520078972B843FF3DBC6736602F68B289E0850EE845E49586C889CCDC104CBF13470F6F6C0E6766007E5C3A1348166933A45A1A62E0B749EE14A38E11A094BAE60A38C84079D81AA655782138671A0FA186A727457D351A8A45B6FE05369F7B158DE844E31117DDC47AF9FE52075C6ACD5F93A31C38EC7F608FF9096C8562E0271A35FA7265A56B24BF31C6A727376D1AB3F600573342E60884F41D355B2336E464B94554B7C108614C3394FBD561A2E74BA7045C0D74032877901E4F8A95C41CE9FC72013C51FA93B5C0B3C3B0A8C90CE0960F510A9F6A453B8B0012F7C2430350B8A4B6143AB5ADC7AAA6F3533E230C3062B7CAA33B1E9A3BFDA7BBFFEF8341AD0A33AB272BADA717A4790F4C99CF430BF114B62854810EAB7AF582A2EA327A599C490E25795CC5C42219771391B33DF4C7FC01524C4C520EB4559C2EA8C38AB5CFE27035C756248662C1E969EF478A2D2419ED9DA7125EC32B0557EDB5B77E0DAB221544E5F7A57A2941B89B803ED1C7D8DE65F64A29D8E7BC2020B723D391987F83DB0BC35E96AAE7B2772B37159A3257EAD277532119CF55959FBEC482169C5391A9409877C79255CBD1C8D2B8352CBA074BC4714DEB09F9CD81624D2782DE91EFBC30882C45631E96E35C9B53F77CC0D268722BA5EB858A1DE719A88EC240DA229CD7766B9A237641C1277C006A6672BF61AB5DAB4C223B7381FD3C16704CF7920B2F11210C969B6B46A152B72598DE4AAC1665D72A45BF51370DE61559F83081DCB6AA49339E489968C80498550AFC467C8AAF0C6C1B9085699B801C75EACC3142BE38DE6F6A64AD6708C426EACC13B09D8BEA819BDC200258D31A8D1F308D0A7470DD35161379191576A03B81D70EC58565CA7C4A6BB333338D8113D70F5BEF45B6835917E17C2945A06CBB7F2225675252F351593B06A6DB504B6E67C6E88763FB06879187C5053029724B3477281CC5C5294B36B64F12A08084EEA098489D5CAD338A0CFA61231268BB866C2C524C71BD6A467C845AC7A4EAC579049734970859A2EA753C6B93EF01532B130A103C6244A17870B75023E0014E6D8433AE5CD2B145BFE253A8BBA300B6465FCE277E2FABE36D6C8112887CB0A6DAEA4A54E258CF89071E407594DE1BF1F4AA2BEB50263DC5D5FC729B632957375B5CE6373D9B93211A66A29736A6ED616EF8538E95C45BF595B2EB743D79436D6385BAB74C80D88C1A1F4022E6C3BB3D2294C474C2C554F3BE4D7FAE86455763B97EC8FDBE9640219B35FC36033966A3525D485F12FAC52CA60594E514333EAD02CB1BFA5CD1D9ECDA4A0B25CCDFC47AD3F632A85F03A8ABB0A5010F400AE5722A75BDF5A2F6D5B546B34D73857CB1BFC7E587AA7 +ct = 2C0B8450785EDE64FBF91E190C6B063F50B0AA80BD41C9AD969679FEFC58C69E1354C123AB70C1AF7E44AC63C8A8062E5BAD5313EA0565966301BB0556FB4B7C490463B6CD940AE2D9651A274323F799E25F1888853853C5EC2A4FD34F8AFF4159194E3FBA5FAD3C799CE439C84094C028EF6FC333FBDF19CB40BA8D1228B97CF602A0F7FDE3D15BF5382EDE4AF8A4C6BDC6732AD363735A28ADDCA063AB702F1BF656B474985D31DD68B51DD92E773D3359FF8A02BA792A06689C37EEB3815DCCA7FEB88BD5ECC79E5404ACA3621B3F81AB7BD55BBB293058F61BA5A93A7FEB9A90617EAC208DEF7C6737B353B4C3155B59726CB97A211E1DB42CF2F6805DEE40A68A966BE225A4D94542E9B972D3CF07F3D81EA54535E25AA7F56B8160ACDFA6097EE7FCC81A6F9FB05FB975BBD18315D68740FBACCCB17ACC9132B6622FF91EA8A2AB02CAE313D67A11DB654440A9B63A819A9A51AAA593FE1AA99D70A6ED17C99A25CE4A424DCA9EF9E6DF285818ECE4D4D596505FEC0DE68DB54F7EF7AEED7542908A8A47E07BC69DC4AD657C66FC97C2F3E79009C14A1E115E77D17948D9D599EB85D91F3B07EABE2BED6C549672A751FC75ED2FF131210A14C03987F09B61E24B144C4F7A64D8E0BE83642777A8CC9897379649DF060E5173F5C09BCD2C630DD7CDD51BF995A053DA7590DA319BAA2F8AA4904443AB1E9C5560F3F3624A744A20EFC8F2F7401DF81A228003CFA0F0196F6D57D0AAF7BF962994A60857EB5949BA5ECA8683324CEDAE9BDAA636B1EBE97F43C31A5AF9C51E78C6745231A3E5ED0C0B1E637FDA928F02A3C04B6BCE519EC653971F74E07544EBF78F0F71F58081EFB797F08EF9698A6665889DD1774C551B30158F4FFAF9B6C3E2E3A34213E4147A8437B118C12F5DE786D0EBCA5BB74AAAF88885EDBFCD96A3CE37864D522F7FFB5A1516E447EA2185451B408CB880721B09BC17F33A75C1B1DDD2A33D74D5F24E0F658E4DE0B049074992FF844F90B6E0D444F3612E7C53502643266FC97CD6D94899E5C131EC29F472C991BCC618C8E8786F83952FF53570D32A46FA9CE0A88CC4F4C2A84F185DE78F7CB1B428254886916000E4F030859556E2C5C172A7B73CE74999A58DB2C48CF23E55C43AF92557484DE624ACE9C4930B7A9E0BE561788D645BF8CB2EF2DA50CB04BF3889F39801686B8ED02D94B7C8A0DD936820791267AA3443AB4EB85CF794A80E96C2BBA992FCCFC655FB130569F9A2C47B54A0EA5EAA76C78A56729A516ACB6FC67067467518D79BA9CED47DF8E13113B12BBC467536994E1ECB8628D86AF891B30F4545EE20876340141B8043C0022031070691FDB2EE4F9A043F2AE05693E62434581900DE61A659769FB901460A495D90EEE56948FE26C517EAA0905CA92CBC47BF9CE4FABB881A6AF68EC1EA10AF30933BE24B791A0102F29733D9C1251B679F1CE2F08AEC8B19C75C010822A8439A704D51AEB55B63C958DB26CB0F839756FFFA5D1465E7F3F40661ED966229C193 +ss = E26737292D1A1FC6772D9C14F9D74F0F4E830C0BA04253AEEA21E69830A3A360 + +count = 77 +seed = 542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A +generateEntropy = 241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +encapEntropyPreHash = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +pk = E26411E0CB6648D36C6236468793848AA4B7F4510377E0A24BDCCB712BC98CB21CEABC08101328D3D032CFE9C82D21372924C69AB5A402E9B3D88C87E9BC5C90335E5AC231A1B87EA3C2527B82445D7C8596B10A609616E4DA431C9593B91A1AA21A2E436A359A7A5901902A6B516D562363BF95890501AF4C5946626ACE3F276AF8966709CBB9B666B9842102F3077978E4872307AC65EA11002CBE4DD0BB83677419B89C9E0C9847FA6441C86B8B601663E40357831D1B3C21B4A8985ED50E546C2917F332D4ACB59BD64D9BE88EFB981362458B8D868DA7EC516EA9C807A29C5D51385781302072C1F3295DA2559003D4265CB330F43AC5B774562C182BE83636FA034BDBC3CB25AB6C8C21C69B873329321533A788287A40C1659F457C5E6E15456DA54A7FDB18C8BA246447606F2AA340A48B4FC667D7E67EFEC47910E05C3DA4463B75359668821711530835357B6A8EC62A3E7817C508C79754063F7110362BE73416A46533341CDE577C17A75B3316AC59575EB1A1575EC0104EE77F70941E91786AD457832E1493466A3FAAA55911E9BACEF8CE49F579F1753B5138797EF827F0BB0821EA69BD9C43ABF2181D0775FB64B8694C74F0323600FD3E5F1BC5CBDACDB2329928247E4759747C02CDD924CF1C93BAE5C37BE8C3B9C7E09B4660C3B9901EE33B62350A695D799B52743D5158C015CC609E891C87F9BA02616ED2D3A1C14AABEF101B4B42AD5C47916481BEF01B11B9496819AB76A428C0F5B8A69EBB24FB5B3407E1C22E2020341575C7098E63379406C9B60B6A1733C171682B1776719DB5ACBD2AC6AC4B97AA0A3C8C168A5AB389010A01B4DD01829EE4A402E54E633A229A94CF96E01F72EC4054C13335B89BD6E91E965BC324924C028B433074C9705AC4CA2682FB1B385F058D574515319397754CAC9F68CB70022882A24242D1C3F1242CABDAA4D68A91DDC8A22C939BDF1539645A912A33C1D11A5849211D831ABC2C86834BE35BC3500CC44522BF9ACA86988AAF580BF45A5FF7F8192E110E163356B8A52486F772204BBBBC19BEFC631433F081E8556579D288B3B27C1A8209ECFBAA30A82B34EB722FE2BE60534E2F625C0AE477826A9E75B7C5AED2398525358BF0AD127C15915133A32A9ADD47A72270A98F942807FC59F2420E14365A758C534F289160A65CFB34619C7C9B2992083CC699F554BD64586DCF379605581711D607235C944820CC28416AC761498D8B54193A8CAC8B815D7B19A21B02A6D5A737C4984F3A888C0B9E3F51B95ED9430327642A082787132E94D6C26B298B77554E7F2237AC286F419266580697FC9316EC1176C4D763B194C52D79B25604974C1BC899560B72094701709797C5183391A268853B9FF3AA277C707906BE0B078FD6619050E14B48BC73F877BEE69A3EBDABBB8B2198CF51B14B2CC9ABE673CAA803B419BE1C34B6341C2E83D2013152B557A87AC4FB55C5C86CCBBA995492CF960479B044B3D6233317677C78A453D4E247ECDAB3FB200C3D2A0564C4100A995C4F70597E498CF0897B507AB35E4587E2B875030303DC2CA8CEB41AE2A9725085C12040C8D0CB20ACE46F1936725BCABD60D0B880F7AABC887090195D95FB6EC060B5257AC37481FAA2ECCAEF99C0DA37285D53BAEB0E25BDB9 +sk = DE9A3F4DC6A54E98C850E3AF0F7ABC5CB5B363BC668F2C10C6E197927C89E57088C4960C46B767E27129FE78C7CAE38717E6A2A7FC16DBC1582AC697E8915C90281A0A784C4B75345A13161BC6A586166D4385B507748D3B9516B10550F05782125C10F3761AEA2C631AFA83870C003950B891D96AE721317B192F21A50F2B2CAF49F81177790C29C02216759B005692CCAB4281927A46739FF7A9583E9A5EB9A62314E4967F5BB375FB627E5A45B918C801B4B1DAC24D55C13AA7FC5CFC104647295650B5CADCAC2C74AAAC28B82233F64C1C01AB50F16213154D0312C5ADD25AF449CFDDF494045000A01C449D1084C876163C83C13321B1F6F87757DC186D4C30CE916240E538F196936AB9BB419093FD593409F3A308827AD9002E5A621FB1387AC06B442970CDA9C720AC9049CFF1C307806E9FF9209FD0CC52B9517C685C36C45801875DBCE490163C91C707755CC8701AF04DEB9AA0CE460F24C72E5D811C4ECC297ABCC4C9BA304C75812196409C19BE10C494A8B138A6F05FB5558E7F2CBF6F1694E7D417F73781205B941EAA3ECDF91C71E998F9A8B6B72400A048A77CE4AD17EB265313303CC86150D477E42A39CB4B8C5A3723D03550F4B76D5FB7B524EC2658D374A8C955B0FB3FE878072EBC0201B2328B737F9F19BCA8411F35980890D71E7BD9707C917545AA6A659C3C70877134BBB0A1E970E7035021168C4A493CE1C9950456A76CDC05FEF147FDD625D2B4BC51B39F3B9BC73A35A06A7485306457544B88C168B22E81CBE9BB0174A2B526B6BA0641456A3CC941569124557D3BC652DC8259AC66552DB0AE06CBAEDD091C268C2C6F4BC7E948329778CF48C3B37F9A3ED714C5C8E0099036514D9A052631B256FB7E7F7C91EA0311B8DB8721D5001AE90991111C5873499BBA20A9D08A135ABEAA544706DABF7338497C578084E1BDCE9155F87417B29313DD39505CC90C45C12C324B5D5AF01EB2656D58607724725485465E33A6A64DA220421C038F0A625254AD127AC941EB23362649D2049F8AE8C057321AEEAA31E0E98FE3DA74D53938F4F900B6A33F1305A383CC12B35894AD498293957950010CF7912174373967C294BB89A90331C828048E3FA862FADC95283025E2F66DCA10104BE8B9F286C198B8C9F0F24C79A454E8DC0742283CBBA84B95B388D8F6912F4B74198AA52AB561CE59508CA6CC09251FA2780EC0DA59D8B12B17179320D23B822A3395466DAC34384A364D06882592734F72AB0D2DD7131196AFD4DA54FC5801D85928CF61BB257274C98479EE0C2F65FB985F6C669D948FAC153158530849311F0BC51AE72BB8C23AB5FED55E793A4E8489B423044A1B017273A4BE35A305E19934B99B45DD2734AD4CB4C5B368C7A32650F306B7148C199A44BCC3A297429CCA6015E906204C827CFF8C9DCD48BF1B638091F732DFDC570CE6618DFC839B4A4648A52BB8302E32098C26E9A51A6571C9C290005265B6359F07598B10C7674F5356B0365CEACBB55B1A1822811C92C44F0E4BBDA4A13364749C5384CA7670ACCE69BC48B6A0B0B2BAE8AC5CC40ACA6CE24957167CC0F24DD0CAA3A0228C13934FBBB0C205F53D713AA441F5B0FEB01FE26411E0CB6648D36C6236468793848AA4B7F4510377E0A24BDCCB712BC98CB21CEABC08101328D3D032CFE9C82D21372924C69AB5A402E9B3D88C87E9BC5C90335E5AC231A1B87EA3C2527B82445D7C8596B10A609616E4DA431C9593B91A1AA21A2E436A359A7A5901902A6B516D562363BF95890501AF4C5946626ACE3F276AF8966709CBB9B666B9842102F3077978E4872307AC65EA11002CBE4DD0BB83677419B89C9E0C9847FA6441C86B8B601663E40357831D1B3C21B4A8985ED50E546C2917F332D4ACB59BD64D9BE88EFB981362458B8D868DA7EC516EA9C807A29C5D51385781302072C1F3295DA2559003D4265CB330F43AC5B774562C182BE83636FA034BDBC3CB25AB6C8C21C69B873329321533A788287A40C1659F457C5E6E15456DA54A7FDB18C8BA246447606F2AA340A48B4FC667D7E67EFEC47910E05C3DA4463B75359668821711530835357B6A8EC62A3E7817C508C79754063F7110362BE73416A46533341CDE577C17A75B3316AC59575EB1A1575EC0104EE77F70941E91786AD457832E1493466A3FAAA55911E9BACEF8CE49F579F1753B5138797EF827F0BB0821EA69BD9C43ABF2181D0775FB64B8694C74F0323600FD3E5F1BC5CBDACDB2329928247E4759747C02CDD924CF1C93BAE5C37BE8C3B9C7E09B4660C3B9901EE33B62350A695D799B52743D5158C015CC609E891C87F9BA02616ED2D3A1C14AABEF101B4B42AD5C47916481BEF01B11B9496819AB76A428C0F5B8A69EBB24FB5B3407E1C22E2020341575C7098E63379406C9B60B6A1733C171682B1776719DB5ACBD2AC6AC4B97AA0A3C8C168A5AB389010A01B4DD01829EE4A402E54E633A229A94CF96E01F72EC4054C13335B89BD6E91E965BC324924C028B433074C9705AC4CA2682FB1B385F058D574515319397754CAC9F68CB70022882A24242D1C3F1242CABDAA4D68A91DDC8A22C939BDF1539645A912A33C1D11A5849211D831ABC2C86834BE35BC3500CC44522BF9ACA86988AAF580BF45A5FF7F8192E110E163356B8A52486F772204BBBBC19BEFC631433F081E8556579D288B3B27C1A8209ECFBAA30A82B34EB722FE2BE60534E2F625C0AE477826A9E75B7C5AED2398525358BF0AD127C15915133A32A9ADD47A72270A98F942807FC59F2420E14365A758C534F289160A65CFB34619C7C9B2992083CC699F554BD64586DCF379605581711D607235C944820CC28416AC761498D8B54193A8CAC8B815D7B19A21B02A6D5A737C4984F3A888C0B9E3F51B95ED9430327642A082787132E94D6C26B298B77554E7F2237AC286F419266580697FC9316EC1176C4D763B194C52D79B25604974C1BC899560B72094701709797C5183391A268853B9FF3AA277C707906BE0B078FD6619050E14B48BC73F877BEE69A3EBDABBB8B2198CF51B14B2CC9ABE673CAA803B419BE1C34B6341C2E83D2013152B557A87AC4FB55C5C86CCBBA995492CF960479B044B3D6233317677C78A453D4E247ECDAB3FB200C3D2A0564C4100A995C4F70597E498CF0897B507AB35E4587E2B875030303DC2CA8CEB41AE2A9725085C12040C8D0CB20ACE46F1936725BCABD60D0B880F7AABC887090195D95FB6EC060B5257AC37481FAA2ECCAEF99C0DA37285D53BAEB0E25BDB93EB856043B822DF9D60B55FCCB537AFA3CACCA9EF50433BDE1DD9831E534D192A59B3BD23B49A95BC1FAD20070FEC930B6060BD827D742B077092E422268E15D +ct = A86CEF6CBEC42D8AEA488688BCD2F5A1DCF7716149399BEB3EB373810B7976F4D76A37CFBBEE50167F2F38B3E1CB60EE8C74CB60B7FA62E412A341794891A7FF3603E926FB870B876B94AA0F52909824A8EDF9699C5F5A3D309E29097F48B5354987DEA5BEAE36BF29DF79B0733622F1C67623A006D79A9909839CD70DF5A1C0BB1B18FA1602FC2D30C965DBB7433F972E73CB3DD31C6F9BE7C5F19C0E74C8F653CDC115725C7E77099F90B2FA2914FD713775FA619AC87F129CD9BD9A35393281BFBD18C56A0164C0C470C3AB1E4B4CE754E1466EE17DABB944A5953849E2DE8A5E69C4CC1B46D6704A03BA021EF55B240210148AB0380970440CC686D8F50E26DB02EA4281AA99BE5A35618576A1CE9CA39D7E4BE2F3D7ACEBB603F602030A995AF41F3441DD939AB30C19CA6D262438424EDF43375D28642F88AB6EC7BC75247E17399942EADE8F8A9DD2E9DE6ACA95256839EC4CBB280B6F7B86ED4016B95AE567BBB8AE138DC77763ED5BD71EFD669FEF71E37BB02EDFE11B3FCA0404C46B4B300476A020ED6BA561E231E731478D47154F35D5D9EE02D52D82482C490A32CED521C81B8BFBC18AEE4375B1C8A31C58ED19F7ED744D8C7EDC471082480CBA60E0B36CAF6B7B95404F427CD47FC93D548E8B5FD014BB045288BDBC2C8AA4164554535F5A3B36F7871EE965965B741F57386D15AA545BFC0E405831166A9D8496FB49894D3F2B3E7635E6C7EA7BBE009489736D506C808DFDF20103A340AF5206B227C9D913522608BF5593C6D08F596DC0341925497765BB68D3C9C9D34B6AB026CDE93CEB535BDB577220F59B87B7272733E9106856CD2E9C6A225F94011CB54E65670855C910251649616D9782A34CD4DE063CFDE8E1C3144B910EC2F83EE3D5A1D0C7B282214F467B3534945723130CEF32B8D8F56C74FAB9DD7750B4858DE350FF1D3B2674BF78076F0282BA0CB74244A4D6887F188BB8DF9ED1663B53543E8A64CA604A4189F0FFF339B8AAD602D39C9877BD96513439C258455F9FF7BD0B05293E8637F8A56F3A96D5B47E122B1367AE7D8F8C65FA4EE444BB8ECAD8D96BA05D060BB03BAC1B63D1A257576E672D77286402B3832297949400E4E799BF2DC14DD2FE364B9EE06F528DB197A9DDD93B9DA9426F7D8DDEBB8F809C6ADF1602F4812C01B002A75728325E3A9A148E0C85CABD9415BAD35C9347E45AD4D01D5D1DA29A6A13CB0949B75BD07A942F26F2851946AE9DEFBAB4094293EB2FF4765F99068DE9328C8E0061C7A6C858EFD839D9725061E9A04DDCEFC0A2D614FAE5D0BBE0F8ADBE61B1AF37CE882ED75397FB228AE317FB91CA45C498AD05B5F9CE1E81D73E94F4ECDD0208F58A363366625E0408136637514A194F79501209C7FD5D798764AC5AD5A88FCDAA776B7D2D134A00759497B469E7B91ABEE9734961CF5A8EAFB4B8DCDE96BE81405A7C06C541FBD8881AA352FDB3B5AF4D00194274E86CA1D8E5E76A60A12E4DF51884E7F8F9EC171383177E7D7280D36623101A +ss = 1D8DB19740E2F6BA7C8C04216CF2398FE9221B2404ADDFEF8996A03EC72EAD37 + +count = 78 +seed = 6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0 +generateEntropy = b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +encapEntropyPreHash = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +pk = FB262AA9A031E49084A6127B8410A5A46CBCABE6B18F607C97D4AF6C6A598A089BB40C1998D16CD307895035B15DF2C34BFC05F634813EEC780C96B83FAB557075CDE3B64EAE6BA98B65106E729B81D11C926404E99164BAC5B546997D2A842F6AA9CE1F6BB7AB7551A06A3649E1CAF7872AC675CB8981A124CA05A318BFF9A234853821A3036A86404B0F056491A5B20AE09DEDB123DF8B4E9EB612A00207C6CCBC580373B0921FE2831F50610340865232C60660655184D8A0867A47811B88BCDC4E6DEC5874839919188F63740588BA97405BB1FF2925C1553188C0137336948F7809DBB96D2F910A9C0AA95D49267E543057976E3DC7346CDC7560E68911B8829D37BD0EB20DD5E2B0EB1538A98A76A68798B5469F9DCA82A08648A2DA13BDC1A9B52A7B6F345626BB691AECCD14EC20F1C252B4FB2595474B2DEA0EDDA47B87CB51F020072D489A2E79CFCF9A12B52BB4F626C35BA4C0888C7939F38E6126484A7932F5D6A029E1CA5CEA27D729065D7137BB518C1885A299B58E1F6446FDD8449E58A21453CDE7AB683BEC6D84876CEE590D1AD93852885DB721B85D4061DCA1327179ACDBFC329416B23234572901B3F63A2CDA36AA65B17035F449AF2B404691957C30028F053989C501D8C2CF8A8CC0C04AA59F3B19A98777F814A18A0753A7180264E59F2BE7C9F0266B8DC481CAB4833BE8B3B599818AA930571748D41657256015F68A8C887C23205A6655F30C51084925167BB75C98B8A25B7579BDF40A912365164814794BDB0B78824FE9066CC63473496AB9CEA06248D883D1846FC8084D59F05277AA3EEC0C3186D68BDCEB6C240CD0128A6BC1361467B861AB025309C82183233C37B35E8AF1B464331CBE7CC3974A48A8E015A491677567472F263E31188966EB556151819CF52772053936ABB0D0A48E99357E558301DC8157A8A7853212828269786919A8F9032E17F9B692BA8EFAEBB602E83BD4B75160541500779D1907B1159170DEA870E6F57F5229222E85B178DAB32F897BF45510EAD084887566942656357B7896570756AB1614994F982841A525C8EC63CCC8E4575DF03BE2F5CF96505ADE252FA4E80FCFF664F6FA8C337980251904A9135ABCC509DB15A49FE4C6D57B41BB6383B3483CA5F5CE11641F9EAA423C0C3254A508D4319DFE72168070CC8C771ED3E06CE74C93240947A8DAB87D889F9AD894F37243B25259153324E103B73C708371400EBF007BB5459EE084BE938A18D055AF7CC7AA98FBB88A156849765936E7273BC385A1BCA94A74368168CF26D8806C7901EEE2359C8694B5439F1E82C0A6892E4A68C4858A9A00B1496E177D1EFB57EB9C0AE382B56626595673230903CC19C79714364CC4B10891823535E21CBCD45C90D471E684AF1FE243E925C848565A1989637F7614C900AF1BEA9049B78E07F00950AC800EF72860E209C192A4AA0B901090987BF15A2DB6165516AD0238A40B0BB233A365BBF2BAB2F60EEB8A54771A8D8E5279E2740298563AA2868E2DF1BE582897C7A9A0547ACC2D8933ABA9CBD5D937073455489A30E8CC3659C03D37240BFF084D77F09DEE76B60952221ED2C1AA73B772CBCEA4D7A1FD64561E88BB90327B7C13C809696C0E4711CE152577517BE0A2FB3D597FA5804E0C106A4C10 +sk = C65B5692B9737BD5BCEF94376A685FE08CB59C2B94884B47BB6A4B292C4EF8DBCFD1D9392BA3C464442CBE0879FAC60CB733496FFA7116011CADA07377EAC759172DB45C9035532A5A48C18F3343E7FB3A0A7A1DA9C75F647648A822BB8FCC59A2E0476FE958CDF968433B46EA296056A8460EDC0B7D4430252B227CC38C8DFA639A72759DE9325D3BBBDB1A5305E546580127B11332BB666236924FF1F13105176B81A777EBC946BD4B962E8050C0F80BE026A513F7C9C74308F8336A9BC73BCABC8353AA10AFB69AA502B3B6E9A53AC67F8CD8784BE4519AB3C6E8E47212BB59EC3958BE442BF2162DDA987C602030770555C0BC62B1422367B95A91399642155CD0B17DBB848B642C765FDA2400358040D4CD154A68DB36265BB525FC90988FD0C04BF0B66CE052BB216D6183B444CC385BB8AE17388D5E8024AA41563653B5F72899CC16B37D642F6FF7385F557C941571A1C73BD9425FEF3C343ED9B88BD02A9BE5652736AE69949E43B5C9719C4B8E42C9071C10E3D454B3C90D315C93579CB106A3B16BAB7163983F5C514B818516BBA802B7FB1166679EE03C4C41EBCFFC6322DB61A7988927DD83B48C24BFE82A4FB1901F70E2C39C411FA65C43D56C02C79849E7745BEE15B70E405939B055C2A76FE1021E094B4671A290F5D708EBF0B1155B94FEE9B34CD9858D3A8DD4BC27F5FC0627F2A80D6681C11324ECB74639540B72A23083C3758CB29AD40C979B42679E1436FC56B3A7D1115137015E2A2AF9A8BEF038B6905C8847C16558BA2BC6EA92AD90B026228695D664720C15E6708B0934064760A745EA4A5587BA211312C7203005F838A2D5B7BB09B8DC7AA39D4956D494472F71A268991CA907AACF8048FC98C095798D0EA043C42C437F6762ED3678B6D701560016F405CAD66117C786B56B3A88FB5968C26869F73A2227B129553B220F67CAE75B5433B29259553AB4375A0AA6766B2AA0AD480B6969201ED21CCDA0A39F8B8F565112565065D8D26DBC1A57425A29FE0A606BA826FFE45A69493B08B11712E88A2B4B0371DB5C0EC0125E2659ED08275D18277B9C0CA51797D46CAFE91951737868483A418427733EE2637B4AA9496C30FECAB67B0B7278A76DA2DA201874711E6928B7A40E7859378C867B9BA81529656200584EA9A5881B657B68980EF8CB201338AC1B856C4EC5B0C48A80BCD6676C0CA624F05296E59155D5587C2C20BFA1BEF1005BBE9840DB205D9658935A67614595BB3FE48E52877FC5BA639D023F54D534C58CB90A0A98BD1C2E9E940FDC61193D4753D17463D7EB8C9C6575E0F6845B5C0A5BC69C5F90128D3078960671394B75C5C72EAFFC1E8EF4AFDB395FFD40A2F6BC75FB9B79E1D8756705B710B0BAC1DBB4AC312FFF30745590739C08BB25CC9EC62CAF1226176C161ECE62AEDEC392A3591EC2AC80E92571C1417BE7D82B2F9A1990D50DAB78C1DEE631304AB5AC57274846A8FDC6547B224C72E0781B233FF8A6C876ECA3A3E060A00B560F661042E85340C4A8257660C0592A429C7B81B5137D410B5492864E156DAD292DABF59035FB0E02247E6C6847CFD86B6958C74209A8F389041E5389EBF5B9B633B7FCC08CFE14BAFB262AA9A031E49084A6127B8410A5A46CBCABE6B18F607C97D4AF6C6A598A089BB40C1998D16CD307895035B15DF2C34BFC05F634813EEC780C96B83FAB557075CDE3B64EAE6BA98B65106E729B81D11C926404E99164BAC5B546997D2A842F6AA9CE1F6BB7AB7551A06A3649E1CAF7872AC675CB8981A124CA05A318BFF9A234853821A3036A86404B0F056491A5B20AE09DEDB123DF8B4E9EB612A00207C6CCBC580373B0921FE2831F50610340865232C60660655184D8A0867A47811B88BCDC4E6DEC5874839919188F63740588BA97405BB1FF2925C1553188C0137336948F7809DBB96D2F910A9C0AA95D49267E543057976E3DC7346CDC7560E68911B8829D37BD0EB20DD5E2B0EB1538A98A76A68798B5469F9DCA82A08648A2DA13BDC1A9B52A7B6F345626BB691AECCD14EC20F1C252B4FB2595474B2DEA0EDDA47B87CB51F020072D489A2E79CFCF9A12B52BB4F626C35BA4C0888C7939F38E6126484A7932F5D6A029E1CA5CEA27D729065D7137BB518C1885A299B58E1F6446FDD8449E58A21453CDE7AB683BEC6D84876CEE590D1AD93852885DB721B85D4061DCA1327179ACDBFC329416B23234572901B3F63A2CDA36AA65B17035F449AF2B404691957C30028F053989C501D8C2CF8A8CC0C04AA59F3B19A98777F814A18A0753A7180264E59F2BE7C9F0266B8DC481CAB4833BE8B3B599818AA930571748D41657256015F68A8C887C23205A6655F30C51084925167BB75C98B8A25B7579BDF40A912365164814794BDB0B78824FE9066CC63473496AB9CEA06248D883D1846FC8084D59F05277AA3EEC0C3186D68BDCEB6C240CD0128A6BC1361467B861AB025309C82183233C37B35E8AF1B464331CBE7CC3974A48A8E015A491677567472F263E31188966EB556151819CF52772053936ABB0D0A48E99357E558301DC8157A8A7853212828269786919A8F9032E17F9B692BA8EFAEBB602E83BD4B75160541500779D1907B1159170DEA870E6F57F5229222E85B178DAB32F897BF45510EAD084887566942656357B7896570756AB1614994F982841A525C8EC63CCC8E4575DF03BE2F5CF96505ADE252FA4E80FCFF664F6FA8C337980251904A9135ABCC509DB15A49FE4C6D57B41BB6383B3483CA5F5CE11641F9EAA423C0C3254A508D4319DFE72168070CC8C771ED3E06CE74C93240947A8DAB87D889F9AD894F37243B25259153324E103B73C708371400EBF007BB5459EE084BE938A18D055AF7CC7AA98FBB88A156849765936E7273BC385A1BCA94A74368168CF26D8806C7901EEE2359C8694B5439F1E82C0A6892E4A68C4858A9A00B1496E177D1EFB57EB9C0AE382B56626595673230903CC19C79714364CC4B10891823535E21CBCD45C90D471E684AF1FE243E925C848565A1989637F7614C900AF1BEA9049B78E07F00950AC800EF72860E209C192A4AA0B901090987BF15A2DB6165516AD0238A40B0BB233A365BBF2BAB2F60EEB8A54771A8D8E5279E2740298563AA2868E2DF1BE582897C7A9A0547ACC2D8933ABA9CBD5D937073455489A30E8CC3659C03D37240BFF084D77F09DEE76B60952221ED2C1AA73B772CBCEA4D7A1FD64561E88BB90327B7C13C809696C0E4711CE152577517BE0A2FB3D597FA5804E0C106A4C10306AED2A804A1C9BAD4AB9E59F6126AD7C8633CDD0C2DD9D4C6F639D312ED47BE99C0E7B82BE89BC3C1EAEE6680AA4EFD394E40C2B3F30523C8117F7C26A8969 +ct = 23664DABDDC72005181DEDD4683615FEBB4936288AA5E632624426F07B51A793B5E7A469F91895314F08278C98C5D6B8A184830209A05F7D9C38BCF5F84CD7DA273D7C64615C78FCA0FE08910A506CBF7DFB28B4F9AA5C0CD4CDA71C9CACA34BF27B15CA2E603FF4CDDB14A639277C1DCAC2242B534737922863E1551307071394ACBC98AF20BEDC07163FA84B6C63B08A1380A3D4157FD2006306C95A0D488A83D9B22C3E1B492A97F4921D5099509FEA1D08AE5EB44117B1C7E9417B9A3E6FAC0D519B56380A8B5C5207F454779FD839426E0988BA8936FF50545BCF0E9DDAA818AC0EF08BD2D5A3FAB95BD157C13EF512267278C2F94512A8D5642AC6323F668F1002230DF845D6D5CB5EB02FB4C31B8EE5A820C30A53B74A87E0AB2AF7C51E0546CF5E41CC72B634ACBC96ACE5257B1C221019B4FD70CD0D958E5200927BA66B154613191A0E139CBAE734F2F78F7878373E4C4178E2E3C3E2A7A11E06BDC24D151B475611FB1DF5F39FB5D0FAD043211E16066210EBCE0F31503BF8E62431C863ACF928DA8EEF07FFB5F60E01A6DCAE1C558BC282B3090759F7239A20EC0F5A37CB48B351432CCB3344E25EDD5965422F559C6493FB8C5DFC297DF280536C37CCB41D2625F455BEFC77B71E7D84DC06DC50D32025609D0928EC8BD6B1F78F1784A72FDDB987B5999D1F289D29740ECD423193B9651BE956750D31406FC31A8BE3465F8C06B5742F66F4609E120AF2EA64F6C99895BAB22EF2F19D9F3CB6D7BC27B5550F34F6EBB51B02AFFBE626F051FDCA7C47C57123EEB2EE8865A91AAEE9BEA87F5B5BA63B86696863A9CC67F765C4C0E8DD90D59942710288F0F8C446533EB4E74D22B5F89CF1C714C139E487FB0DDFAE6D900E3B6FB7E568AB7116BB92E04754415C74BEFF6BB6C5D814FFB7A198C5771845BE3B0E2F2D397BE8083E1CB0F87A965D78768E3EDDBE3F234124CD92EF5C55F28A76357413EB2C4E26E7FEB772770733AF930B5C7251B2F0FAA388EFB08D45900738A7D1FEDAE2217914CB18FC3B0C1AEEA2B2C93C72F1811F7BFFB281EBD38020D006E286E0132C5C4875F8657C3E5B141294A69AA98AC26748DAFC3172222314F9B5B9EF0DA13BA75B7B2D8EAF62D50D7442258F6EE56E399964514290CA006095E125AB63E178DCDDE424F03BF59EAA68393FB7D6C36E1091FFE079BFC9BE2FF099722E1BD33F9FA47DC0766C76EA6FDD660DC2D6FAA41CE8B268136C6B050D449A47FA4051817831AA555CCDBDAB8853B377CAFCCCE731849F64539BDCE72785ED15C0AC3E4ED94AE3D4630D7E6AD08AB5B48C018CBD943FC968AD687C5F4117BCE83A663D622A6FFE5A47D44A409EE9D47D32BA9EF5A6453FBCD81CD92C27F9C033E32E83E1A2E7B32F4ED094A79A387F90A6F7F45AAFBEDA7FF11B35BD732BC8F3B75CD84682929D20419BA2FD2640DB63867532639DD4D1CC1042AAAE6821011446EA8E7D2B0BED9B7AAA6C17BED3955DDC566685D7E124A9A01D460DFAEFF51A32405D74ED +ss = CB0026C186440C0744C1C1C708D8FBF2B7AA1126792A7363576BCB2E64384117 + +count = 79 +seed = 7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851 +generateEntropy = 28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +encapEntropyPreHash = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +pk = 5226AA8EDABD5A4A5A7CF6633A394B756AB38BC652EBC1BDB728C74EC316D039AC982B118F1AAEFEC04E48448D45F72B319289691A93A20283C3CB1FEC992364CA83226332107704D3390F71E1883B46BC2F31B4242744E0847E72D5645586AD0B8C0FE48AC04A003045AC2D2101B52C7C1D494673BEA69766A5ADCB38CE3A978209471B5D7095A720A4C1971D94970884F11FA90C5C8B7009E2E1769B382004C93A2D9187B23929D941468444CDDE233DB3791656C860705B714E3AAF076921458B8DDDD61E09AC461E96A1B1E9AF19AC6984129B6C8CA9D4E39D70277B5D9A6A4B605F5E0454AC05729C2691E87A8D79353289678490A822C41C52A2F56B91A35F89918AEE8935EF2BBC48485BD747CC5C59066B7577739B669AD21A5561018F021663F5CF48E08F39881D221552C846AD789810030326C8530DBB369681C69CC00C2390FA857A37AD81623EED4262DB69929353118A0886E6C1CA3D36C65898968EB7C187B7B866F18A8BB369AEC780E0033EBF1B0DF846CD60633A461C569683598C7744FBECC54282725E337CEC503D12A87F9CF5BA6587BAF31B852BD45A871ABB81E88C8B8A56D324C87A777BEAF543BA153A222418BBC57D7E1325FC2A075608988BDC44E276AF10CA2D7E52B045514080597A0FF73732789D0F955F93BA77E8034900251416B43E291984CAD36C53C947CC954A8320C11424BE43283A6DC586A9FB39B2927867B79772DC1CAA16234233ADB5AC819F1A172DA5194EDB997F924A827A85FC7C7A8281C98F7A9CEE443F68A2AEA6001DE7C7475B46B55EE8991DCCC6527B5FA1393C9107C4D35A073CE29A7EA205A9279B62F5CE21F3AAB0838B42E6679000CC4C182504A2A4E81757B7F6A183428786F09C76C69E2D7598F1E5049CB57738DAAB6972ABF6D8BFD2AC7137493BD2B8B5F997519B2026EF38623294B91999A5419356BFE03E338194E471926FE5842E79740F416ADAE2A24F441BA4A0C08ACC175F347EE3B614664496A5E51C01A55B1D2A3E8486CEC4C3BA461970868502A0F9553D776514857BB8A872C7F736CCB432B1392E99568B51B9C9A56C441AC0CCBE785693722F90D63A0F78C8EE777236EA43DE2583D0E093EC8BCAB7C8C6DDD8254258B7A5732939D953E491A6BF310449083986B2A0F236C5B9A300DB22299146B9A0943115845F3FE98045CA844BCB1132E0BC98CB54746937B1479DADAC5A4F9320DC572BA81CB250F13869D132FA259604A76A5DD56A7543B96C3096D3046389A917DCE53CBDD9AB04A65B31C6C5CFA23A2AD53FAEA3BFF3985FDFF9CA3E3965989C072F4659EE8914DDDA0ACF30A64A1A823B78561D5A9304950EA3056F50B82915C71AE0B6883EF319D061464D8050F37C24C62C7693F204DD4B4D74B66DD7526FDBD707A3490769764ADBEA61C09A2D7F464D7E932705212D6A9151B46C2ED93A7B99C1148F679D622419A4574310AC20941B3E51591CA5D53CFF51A6ED2C081EE7B4BC23C8BA8B1AA2924406618715731B1CC404929A38911020FAC6647C24306E349F1ECB4E2F530E8F200EB9C0A315606A3E130498F96AD5865EBB4CBB55265E69316A3BC96E51745B02F4A593B796B5951F48DDD5D61BCB3F79106FB3F881087B21E528BDC627A8A1FDBB3B1FF5D83954F7 +sk = 52D431D74363BA07B7EC47C2A5B98157F616B8C7B7D3E68CE3F2A31365BF4E21747203C5EDD758000A8C09D38A83457FB7B015BDB187E842B46CB9BFAB29A917435431184219339DF7CB81018A81B283814FF8B15E3A526AC35185BB45C7A865C45AB0CA1C7C5CAC9E35F753D378556A62C8AAC92F0FF59651C1ABB789970A32C69D153B14A687FC2A56B9E0C382BA4F907A0BEF79BDDFF781776ABD042044A1C84C4C80AB9CE9A76BFA6374E9CEE06081E3661A09CC3272331936CC85D6B2319CC7873227303191C36842B61013C0A41082B82034A2E1BFC8C47916859EDA53033D5427741510E842265AE36D530A19E5D7365127BCAB5B506321ABE2B69DE823B660B4699F8859DE76899098159C211CFFE51C7198CF1025BF9EE69236C913B16AAD84AA4C381A577B6C7A3403627B323F11EBC1F304747F47407DB9A8C9E4B866082597F28B6EC272AD2140A43A52188B061650BFFAE19761BA99CA724B71191B6DC5B16450CAC50B247415370D5B207701AAEC3A13CB477983F180388050175658CCB4714ACB603B6B3AEC340DC6C164FCB81331EC194C382FED024E0D962B056627A5B05A00B5511D78BADAA489F8BB3F3C5B484F9C1450708B89828EF24B815EB43A6B8B127BFA49ACACAFC46434987BCAF5F91A926140BD56504FB4525EE1921B63733DB2986DC133078CAA44518871BA12894A553BD024FB731A0AC44AB80199394A2385BC440515877CB69B73B0C847E40ADF238847608908C20BF7E1B86FA84781371D4CB52FCF2CC30306C8D98C679D4CB41EAA0EA8B395C08CAC6DF2348474A9504592ECD34A93B3262C9751E42193719B617355C59A25679D909A5E756C8DB03E3B174E1A063EDC733B9350B4F738618648BAEAEC5B76376D05329BE6E706E632BD61292755F361096CC4565573562053B4402C42C85B5299B1CCA0B9CFEC4605D63665F24561D8C1DCFA896D1C6D8918A3E6F2A8D4224FF97503D1EBCC8D5395F0A64D1454623890BB7AC6B87B29333096535118CD243C52E49CBC0945385E38781B9BCB6B220A66D96D426B9A1F4C4C4D0349CE2BC790732247EC5D98E43BCD37CD94B652BFCA7B988B063BB102EA0772DF0AAEC74C228261B4FA7A49F3B329F2C7C6D04C859C9816D5BA2AABB85E52DCAE066B9AF4D9951766041CC783DC672DDE42558F50473BB43BC1F93BC6EA7D33F46AC4999CD33698EEA603C7DA265AD713E48691C8B048B21134C9998DA19060CFB6AE31CB5A3B7387F2257FE94BB3EA4C963D01849FB021741395F1862085F031B6B05A7834551A6C8F0EF91397A29E12DB6D776B05C7F12C8B260CF128C02E48A9F403A487AC3A6C0888C5299414AAB1D7283252F62F465867A851BE9A82C9A79A25CFA727C632727C765D4C496D466942147A8A7B65AEC4BA84E4E2745671BCB207654B087A26F93AC77C82CF34A7C2F86FE8F48FF9A0B663D79BBA6B2B8908B32FC145E4F65C6A8A379A99C9E68A10C278130A1969E0CB708D0CA6FF1669D8756D1D530ADE051ABA3A07903B5D801456315057187758351588BED222785C9FE83A0FB4C59245CC2A72B309767348EEDB7C2097B457BBAC8AA96A67D785803744E149B3F131A85226AA8EDABD5A4A5A7CF6633A394B756AB38BC652EBC1BDB728C74EC316D039AC982B118F1AAEFEC04E48448D45F72B319289691A93A20283C3CB1FEC992364CA83226332107704D3390F71E1883B46BC2F31B4242744E0847E72D5645586AD0B8C0FE48AC04A003045AC2D2101B52C7C1D494673BEA69766A5ADCB38CE3A978209471B5D7095A720A4C1971D94970884F11FA90C5C8B7009E2E1769B382004C93A2D9187B23929D941468444CDDE233DB3791656C860705B714E3AAF076921458B8DDDD61E09AC461E96A1B1E9AF19AC6984129B6C8CA9D4E39D70277B5D9A6A4B605F5E0454AC05729C2691E87A8D79353289678490A822C41C52A2F56B91A35F89918AEE8935EF2BBC48485BD747CC5C59066B7577739B669AD21A5561018F021663F5CF48E08F39881D221552C846AD789810030326C8530DBB369681C69CC00C2390FA857A37AD81623EED4262DB69929353118A0886E6C1CA3D36C65898968EB7C187B7B866F18A8BB369AEC780E0033EBF1B0DF846CD60633A461C569683598C7744FBECC54282725E337CEC503D12A87F9CF5BA6587BAF31B852BD45A871ABB81E88C8B8A56D324C87A777BEAF543BA153A222418BBC57D7E1325FC2A075608988BDC44E276AF10CA2D7E52B045514080597A0FF73732789D0F955F93BA77E8034900251416B43E291984CAD36C53C947CC954A8320C11424BE43283A6DC586A9FB39B2927867B79772DC1CAA16234233ADB5AC819F1A172DA5194EDB997F924A827A85FC7C7A8281C98F7A9CEE443F68A2AEA6001DE7C7475B46B55EE8991DCCC6527B5FA1393C9107C4D35A073CE29A7EA205A9279B62F5CE21F3AAB0838B42E6679000CC4C182504A2A4E81757B7F6A183428786F09C76C69E2D7598F1E5049CB57738DAAB6972ABF6D8BFD2AC7137493BD2B8B5F997519B2026EF38623294B91999A5419356BFE03E338194E471926FE5842E79740F416ADAE2A24F441BA4A0C08ACC175F347EE3B614664496A5E51C01A55B1D2A3E8486CEC4C3BA461970868502A0F9553D776514857BB8A872C7F736CCB432B1392E99568B51B9C9A56C441AC0CCBE785693722F90D63A0F78C8EE777236EA43DE2583D0E093EC8BCAB7C8C6DDD8254258B7A5732939D953E491A6BF310449083986B2A0F236C5B9A300DB22299146B9A0943115845F3FE98045CA844BCB1132E0BC98CB54746937B1479DADAC5A4F9320DC572BA81CB250F13869D132FA259604A76A5DD56A7543B96C3096D3046389A917DCE53CBDD9AB04A65B31C6C5CFA23A2AD53FAEA3BFF3985FDFF9CA3E3965989C072F4659EE8914DDDA0ACF30A64A1A823B78561D5A9304950EA3056F50B82915C71AE0B6883EF319D061464D8050F37C24C62C7693F204DD4B4D74B66DD7526FDBD707A3490769764ADBEA61C09A2D7F464D7E932705212D6A9151B46C2ED93A7B99C1148F679D622419A4574310AC20941B3E51591CA5D53CFF51A6ED2C081EE7B4BC23C8BA8B1AA2924406618715731B1CC404929A38911020FAC6647C24306E349F1ECB4E2F530E8F200EB9C0A315606A3E130498F96AD5865EBB4CBB55265E69316A3BC96E51745B02F4A593B796B5951F48DDD5D61BCB3F79106FB3F881087B21E528BDC627A8A1FDBB3B1FF5D83954F79BB3963CC1C5CF2B2D1C6CA76226328AB765A79999CCC71FE98D5BF3B34F51B19C35D165453E5FCDC6F9DF64526D9DE698F2BD3E6BAC6C7FDD86601B9BA5F4A5 +ct = A7D918C3251367B43A2CAF232D30CC44BC8313689F61C174CD6055E0939DAFAB9EE9C4CC5C451F6836D2D9FE0B6F1B737BA4B6020737487095AECC3C972201925C7A3E4C6BADDDA7441B89B2A35F8D2E4878D316E5B92E5B6F28EAB2E2D1A98843853324D35A023741F11C426442FB3A8D50A0F9BF5209059AC1E47BBFA11724F49488111C551F11DE6BA8C28E576758F2C30B219AE6BC3C79D73E5DA64F03E0ACEF5BBAEDB7DB863B7E8255F76E5C7FF26E42DF8F82A5435F5BBF861283710FA7DE3AFAE930013F1B6B7DDAA122121C83E0DF00F231020324312B077CA26E4E9C2BD815F93824CA59FA9F4E3AAD70E4D55A853187A4E3CA642710EA0109C00750820AAAFD98BE4A25BB7E1D18164F9A4D439F3FF7169696A108F7274E2D50F269F93967DC2371BE9AAC3716DBC499C9CF6639D02EE86438E2DA002CFF11D70C5F025E4A9A446D0FA9314C1E6B445AEC37771E579182D494FB5C448354B1ABE91FEBF5512C11CA7D2DBD0DCFDC37C91F67613C64B76836A5D91F57FC3678B12707D8451277F776EFF18EF083A00FD39332DDED503819BF343A5ED505059D15BF011766BC392188E8483E64B1438A1B2C270DBB1ED0521212B0BEAA0545FA703CE2FE495113FAE988C7F23282F536EFA269B81A75921A56888BAED7F23FA82195A78225AE72534D28650394AD9681278BCEAAD1A8A1C1E6AA0D51EA85717BA3CF304C67269E0562E90E8281D5C96645B8DDA08D3508DA723554B1CFB0E0B96C3367B49AB0D74793A772E6468B79AF1EB6FF720521361A2D2D70ACEEAADBE408A0CB8349F5083E899B6FE37E381D28B5CBA394BB9B7D943DF0167E1CFA7B263E942BE68F1BE1050AC3B51D5772C5EC02E7BF5A4D585B6031EEE47C35CAFB5D74DB20D643E39F382B8E69054F397CA6FDF47384328FBDAD37BCB29AFF15F2ECA75E7F9D8E8F5C24026EF6E4695345E07AEAB117B347B322B44F150E1B66286E24A31C5714E3D4191283D0AC8D8DB9DE4454710439758381D7C1392219168B8302CECE11F26D6B04A77F8A5DA32B22909498E154486AA5B4425700E1D08EE9DDB319217F7A9E5932C5BFC021EDD7E46FCD67638248C79A6C6C130EED0E8E634F332CD5ECB25FA65CE4B6FEE1CE618CCA6DF05EB9187D0B3D0B200B454753D7B16C7606470760B9CABEB4C3F13D4CBC63A96D2B97A403CE1E85075A7BEADB8C34E94508E87736B563848C1AE9CD34DA56D06DEA69811ADDA02507FFD9C3F10F6850BBE5585A507FCF0F79BE02B677EFD4FF3E4945EC800C6AAD1ECC53B9EA6A2C35B74FF196EE7A25938E267FDB83ECD8E5691E5644905FEC3FFBE86676DC30411C12EA05BFEEE31FCD4A804EC59D73BB15C931D031E8DBD36AFE294985AB20D87E8E338733EC6A6B7B4BFA1E0AD6A9905EBC7D4B5B23CF36C5B589A04357F792BA8D3B9F3270F3EE491DC0683E16DED773A9A6595D43FCF9EFE8C0917A71637C4A03598EEAB0CBF1F0DB3E33B1DA48987C00D85B207B7E960E866469CF67A05BCA16 +ss = F855334CDE90E9E858863DBAED7BF4C45BF189861750EAA59355A3648B1CA1CB + +count = 80 +seed = 09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E +generateEntropy = c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +encapEntropyPreHash = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +pk = 724ABFCD15255F0A5EFB7783D909031ED02C52A203DE570873C7A7C556202D53A6C086899802BDC877BC6A813AB59B781BB95F4FCA9EE76028AECB9142A992DD7180BC1C15DBEBB66765C5ABBCC5EBF764D5234D89A378D5925FBAF63A00E35D568804B973450A045E55C7C5F4907FEE390FE6877963E386BC20CBE929C3D247611E346EAE401ACB972843DC204EEABB043644EEA29BA2C1A160B98F0D28CAF0677AB2ABA362B7BFADACA4E1197F54F03AC8033814A71E1CF407972B3F1D9A986637A972B46D3AC46509C053EFBCB9A475BC4055265961C79E1374C2159BD2409A84F22755A1B32E4B604783BCB2AC49A27A5B0B07AE346AC38F54A2943559F02270BBB19508E903888ACA4BAB72E332285837B9EBB466E5CBA74D5AB6BB3B2A0FA26209A97F959C905BB4B058BA8ABF30A5A6C190A018A9803AC29D84BA710B30DA9A0844CC1A1478C289C32737144812355E0D7589B9AB765CA3B23353A350876F05081F3E4B14D8F66C998B81F458A394CC68C3B7BFD37366EC93113DB928E5F9BF0E9AAAEAFC619E332A7EF3898A66020DFC64F671879691C023409B53686770F8148A2B6F7B62B6AA42981EA0CEA7753599585034B9AD99C9AC8B12872B1A47A088BD8AFCA2D42093928A4FB770198C4CC50B0214C4C94FC7B62B5E636423C6ADB553B138591F6372CA6D53343FF7C70782A2DDC4801B262F220A539181C13F3C3E8E0A0D7191A43A54AB008D326DF803FD8757F88AC9BDC8BC75CB83517AC71FF8613B3BA713377FDAD2199BFA332B8C22C136350ADB9553E3643D0C45413782F3BC9E941965DC051DF98738CF50113AB422E4A22759CA016BEA6FCBA390ED64540112842F5B1373A2847107A43403B4AA5CCAE154B9C54831E3911239B79F1FE997BAE30A542560FE6647A2E7C4916097FD484C3D040456EA2BF8B63DBCDCC8577B7AED99C05FA28D468272876B614045095E918600F7C94BB0944F62235C169B58789AE8BC3E6F677CA8D238602399E307553E235D11836BE120B3BAC41B0A668E0841AB11F49E27AABDFC27AFCAABBF542911B6A220CDD626D819C44C72556A3946DF86C43D1B8693944D399A3B5B1309B9780E34330CA387CDE8E4C9B2D0775A962F447828D6295873CC1629777FD93C062098B6149A3E7C383E2C33CC3FE7730537416FC1ADB6C09F4CAA736E4C796D2A97FA3807C9EAB72993B4B876136B856C7BC75AD054288EF491EFFA872247A99AA39A9C2B7602027D65A169317CAFCBB77C37D89ED32489E3C2557998A06689B06AB96615BB5752D439DA446354CB0640686AA794444A806C31D721B8C6B820810A5AFC00932A885107B5F968B5C8EC98207293D8851892A01DFAE4A99832326E3863BCDA75190C4A487B46E3914B702017B1B520CCC30A5C475FB2DA94EA217F76556BFEE825076533973BAD3AC7305B5C764CD040D723617090AF4A7811E9AB206C6A331A647D9385A5E7D8BAD6C89B390B617018C4A0691D262429BBA173598B37D7C245452853506437E756A399670AD8E292B0D820E3567047C82870E82236389D99D678CD9B49526AAC30D1B830B12F4E62407A59C8F88B7B5D088A2D08B9F114C3F158650F32C682EA6A76CB62D3AD7357CC617D597A3DBBDF515F6852D71220768859D599BBAA +sk = 28BA2F24DB8E2A5B21092964F1871E97E10F2727C8B27916A5068EDD27670D26B91A93332157AC686205E23616EB0271B081B51923C5996743CC114F3AD310CD6791AEB05F77960991513EC655533921A8D14CB2589399EBF18F7BA89BB7D6CD2D7336ECE1B7B63B98F26A49D356578CE7275EE67677D1482E1BB3D85B88325BAE0A00CFD1288C34078D73965442B7B140705F0FB76EE3D0921112C400C7A4D1337D6A3A8CDFF9AF05C64C079C64DD143F1FD56C28096313E82D51836A2DC1B0F37A2E00545F802B417A9406E55420B4D71FBC2210D05A771CDC164AD50932EA40A876051828236153B4E1715EDB1453045721E89A60ACD0066227704B8AB991E8A06812226BC59943C0814C847A1865C19DF4B7FA13BA3EF95543E724EF854CCB28BC1DB49B75C1ACA3649F848BC6F32C139AA79197543C628238ADB755F4DA6BD67130772B4790B28C9F1544A4E9860E875E68C1CDD9CC0CF17451434C7C53F3A9BE39849720B1B80A836BA4C531D49BAD16077E90203C9120C23239CEA972454B08A5F10812443CA75B913DF98DBE29C3312157E156311F67354D414AA041833F8454ACA5B3898B3572E819FB2C4CADA43C9C5191D6F7AED8F310CF77CCAF0C478686952E71A8A8173D0C223B04462B96C04EA7B218A13519B90CBE3BE8C32B276F90D349ACBB6362706DCD54AAD0497A058AB0138A8E57D514D5D431043184BD1A07B77C3299BA6C7205938ECA8403F31A1C605A942B73775A1AC11C40D81988E69C15079719AA769B5F618052D5290D84714CA57418366C15B74DA4E98DF96ABDD19884EC1703F7978C4DD72B48528789D7148F16C23EF8BCD1F353CC4A76E7C238AEB1035424300F529ACD46926874190556133021A6A9283DDFE02EDADB7DE23A4D141B0787539B68110B4882A51F95403865BECEA06E2D7A1C1F534FA3366BC1AB387EB867477B92F00C0D09615BFCC1138137CEDE4098AD57894FF74982D71BA2ECA6A0F502CDC9C89BC6A44BD84FD8B62BB5D84332FAA830E2A732259945028D2830A8AA866F92C24E46D164C4F4658791C11F0703D906A82546C75F81285C24597BBA4B1BE3972F069D6B383D61CC32B9B66604B7CDC4BB39058C74CE770F04F758E6124543E13D2365A915802F75E90997B10B15E650AEE33A291C87030517B6C29CF10670D2DC5C8889AAB7518B4DC86D86E25C52ACC4DB175A5957118F983C3A4443B33803A3161AB24004B7A789778C8414A8AA8C819468EBC28B68AFE5333F7E666D44B5A961533280B0021BD3B24E2AA51BA58F2F45767A5722E918B1204656A2B44CE628A3A84125F918999A6311CB3569431C7B0D6B58ADAB6A30F9473B3747E33C7A2A9BAF87B709353A77743949277147928273F112B5E618167A5715157B49CED69A2492203A08730ED07B7AA14BAD136CFA969DFA68C28AF40B9763872ED1B05D4161489BCE1F473D4CC067A86258F6B664D2436D4856166CC60467887F9B97439F607D336114E46B2A2964C228A18EB532CC4C6813DFB841E60C3BAA59978234A06FC95AAAEABEC0123230AC33BDC48A4452403842BD6158C668F28F20BB5501984C5D3992594A9238E03798D178702B86973350724ABFCD15255F0A5EFB7783D909031ED02C52A203DE570873C7A7C556202D53A6C086899802BDC877BC6A813AB59B781BB95F4FCA9EE76028AECB9142A992DD7180BC1C15DBEBB66765C5ABBCC5EBF764D5234D89A378D5925FBAF63A00E35D568804B973450A045E55C7C5F4907FEE390FE6877963E386BC20CBE929C3D247611E346EAE401ACB972843DC204EEABB043644EEA29BA2C1A160B98F0D28CAF0677AB2ABA362B7BFADACA4E1197F54F03AC8033814A71E1CF407972B3F1D9A986637A972B46D3AC46509C053EFBCB9A475BC4055265961C79E1374C2159BD2409A84F22755A1B32E4B604783BCB2AC49A27A5B0B07AE346AC38F54A2943559F02270BBB19508E903888ACA4BAB72E332285837B9EBB466E5CBA74D5AB6BB3B2A0FA26209A97F959C905BB4B058BA8ABF30A5A6C190A018A9803AC29D84BA710B30DA9A0844CC1A1478C289C32737144812355E0D7589B9AB765CA3B23353A350876F05081F3E4B14D8F66C998B81F458A394CC68C3B7BFD37366EC93113DB928E5F9BF0E9AAAEAFC619E332A7EF3898A66020DFC64F671879691C023409B53686770F8148A2B6F7B62B6AA42981EA0CEA7753599585034B9AD99C9AC8B12872B1A47A088BD8AFCA2D42093928A4FB770198C4CC50B0214C4C94FC7B62B5E636423C6ADB553B138591F6372CA6D53343FF7C70782A2DDC4801B262F220A539181C13F3C3E8E0A0D7191A43A54AB008D326DF803FD8757F88AC9BDC8BC75CB83517AC71FF8613B3BA713377FDAD2199BFA332B8C22C136350ADB9553E3643D0C45413782F3BC9E941965DC051DF98738CF50113AB422E4A22759CA016BEA6FCBA390ED64540112842F5B1373A2847107A43403B4AA5CCAE154B9C54831E3911239B79F1FE997BAE30A542560FE6647A2E7C4916097FD484C3D040456EA2BF8B63DBCDCC8577B7AED99C05FA28D468272876B614045095E918600F7C94BB0944F62235C169B58789AE8BC3E6F677CA8D238602399E307553E235D11836BE120B3BAC41B0A668E0841AB11F49E27AABDFC27AFCAABBF542911B6A220CDD626D819C44C72556A3946DF86C43D1B8693944D399A3B5B1309B9780E34330CA387CDE8E4C9B2D0775A962F447828D6295873CC1629777FD93C062098B6149A3E7C383E2C33CC3FE7730537416FC1ADB6C09F4CAA736E4C796D2A97FA3807C9EAB72993B4B876136B856C7BC75AD054288EF491EFFA872247A99AA39A9C2B7602027D65A169317CAFCBB77C37D89ED32489E3C2557998A06689B06AB96615BB5752D439DA446354CB0640686AA794444A806C31D721B8C6B820810A5AFC00932A885107B5F968B5C8EC98207293D8851892A01DFAE4A99832326E3863BCDA75190C4A487B46E3914B702017B1B520CCC30A5C475FB2DA94EA217F76556BFEE825076533973BAD3AC7305B5C764CD040D723617090AF4A7811E9AB206C6A331A647D9385A5E7D8BAD6C89B390B617018C4A0691D262429BBA173598B37D7C245452853506437E756A399670AD8E292B0D820E3567047C82870E82236389D99D678CD9B49526AAC30D1B830B12F4E62407A59C8F88B7B5D088A2D08B9F114C3F158650F32C682EA6A76CB62D3AD7357CC617D597A3DBBDF515F6852D71220768859D599BBAA6D029BB2121C788B5B6EAD7226DF664490DAE362C4BEFB615717D81C656B32735FE6141A25F7AB9F875F79E0A82D6EA5CDE5A017AB637D5FDB7C42646A1D71DF +ct = 72A78ED97EC6F0DAFF51A9BAE85D1873B68DCFAA8EB163FBA6FB07A90DFDE6AAC88F65FB4BC7E7EFE6EE951364905859A26AEA558ADDA81619A3D073190F9DF2D0B68016BFC247BD2C3A1CEEC29912EF21B27EB77C7D5FC0CD9B774B75E3E2C584D8116FD0417BFAE6D2E4DE494841E45A217C2A10ED1BD3F158589DAC32DEDE68EBFC3707C473ACA1C9D44B1EAE40339106531779EA144367C767729D4991E7FB0BF3173E3DE8937FD489D09EA263AEE0DA2561E43BE35FCCC2D58EB25DC424E528B9C5575C5E1C53D0581BCF9D5148013A8CFBB5F4C2683AC792F2BE1D4DA00B136262300D51497CA16A2E6CBCDCA91A006F3CE6231D31AD90ADFCC92CF09420A789FCCE4F6254A6BBF1385CA5985C9DC9D8CD57F98EBB445DE0BAFCDD98B8B3FEC85743D9BC78E2CA193B3774E3C5DCA74EA7A8AA51A468AB4587F6C97596F7E66121BB61EAE71A9965BCBBC415D52C826016E84B204199FF893AA7A9212785E456B86775EAE7479B9E109959E4BB26F4E1ECA3181E9FF9E26708616316D5CAFD25F6169CC291B65F555590942871F3E4B62D4A41D9D9C75E8B215006A4371D8AE773333043FA33C0F293119B94E9D0E5E43EE298B7998FD6CDD1A9752BBB3DC19933A3BB232C37D4E5BFC279FA1405B7030D3C3AC2D47C999EF5FD2948DFF6A21855398D0186175923FB9C0A5D9018C74693C6123C52268A28A5B42550B965BC9DA6B3DB2F86613DAE9565646A4CB39A3D3F47C1583CBCA427F7F0B53FC60B31D474C810FDD85C8996189BE93FA1DC6935AC3A9BA2E62CC45C32F74D7C0490EB6E1AAA4F821ACCC848003D83C3B715D43ADB0C7D1D9B7FE54BDDD6A34FDB5A99158C8EE4AB3B9D1B4D4DB6F1518477E3931A56C014E3981AE2B406FD12CB1C6F275CFA4B3AF67457BD10D70D681C00ECB97D5D99EFAC58213FE364E2CB532C198F51A8B5773297CEC7CAC4342189FBDA4C2902A8687E8DFBC0DB4984FDBB9ACC6CF1E7C93B2AD02E7D346D22F3D36187A398F2D28BEBB8AAF98347130835EC07AE255B8BC6D4E50271C6C9CFE29D099DB6C8547A6526B5AA8F30B1E655F82E85ED78DF36215E2FCC5E127BD3670ABA5A368A4D16B8020634590DD1C6FAF3AC0DCBB74B006195F24F503F3EF13B5AE09B0730F9C140AF4B3481A0F50C3C65B90CADB05DFA01EF6494D8FC06A3D2A30B15D4324118CDC330AE4581B2DFFE0D8E7570B5082A9DF811B492F4F9F5C607990056B8CC03F74203F9BCC38E5BA90734142E7DACF63D2EBB1AA4F4A4EA4E29B0849054B57D8AF63F028AC835C50735808039EB602545BC1494592F30BFFB0C1ECE40726F335FBD052FA5CB6CD3FCACBA194850A05BD81C7838624AC8350E64AC910AC805DFE584A680CF9E43D6DF0F654540913DAA58CB0D14C208117E198271DB03E978436C193688B8809DEC85E7E4BEF4F2BEB731AB4220738477764DBFA8DBEE0B1A969BCF0D0BB1468DCF14C20C25D4A02746D0932554FD8501967F2DECE5FD18925C30C0B81AB2EACE088819 +ss = 3030433313514EA95B5D6A2FDFB64D4225FC84EB70336323507AED63C5755481 + +count = 81 +seed = E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D +generateEntropy = 0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +encapEntropyPreHash = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +pk = 30E92DBF312758B73BEB83625DF3B8D5C47A7A334D4E140915CA1401D461D7052E9FF05F73A1598DC9622C324C1C8B5DE9B0386EA3CD95B86D80085588AC69AE310BE6B5B5379202F4F14878FBB5508907B99490E4191B1E13A6890A9209F0A12910A3E096747EBA94A337AF9E609DA4E8A9F8003633EC099983B8E778CA3D72BCA1C19B4FB4A0FAA4459EA06782367580B7AA49AB74B60C4CEF7AB3BB9BA081227A7E1AC2F5400F8F7395F96567403B2401A2ABB0B70E92E6CA2102C597F496CC8881D7B688861C7988363112155B5B88271072A7A7D68B76036059CA5E402532CE8763C52CA237A334832832F2A49BE3907D15852FCED4675547796D3046535390D44580C24BCC3D67A50CFA2AD8936D46121A7F60179BE7AAD0746E8A2C8CAE124D27181A374493DA6A68D47387A44460B39A45B2619F1D29B08BA4495230470B87BB926279EB760B9041632317C4D7A19E7753458DAC07EB73331D808CE318555E1A2828DA2F1D101CDC9B8363990B85064F63226C36C71061444E17A28C3B56332BAB4BEC2602F5C31394C870DD21030997564DE52602C2628C41CB7AC2388EF35371F870A21675AC522660268A1802A2E4CA4C7152A9776410910175FD08C5E0307F4C2A61C877ABBD2185CE58738FDA15335ABA2C77A804F94077A777FB49854C7A78462263E435A1D7B4A5205AB879438A91EB60397704CD937E66C7310625A6276182D86894EF9750F1817D85709BC578092D3B65F5C84514361264909DC2147AE6F3A577097E64BBB2C679C845D827B1AC393497575E385BB39563E125C3A3925A21160201897072F03F45D6BA85DB7EB1D5B8EC7111DD785EBDE07056653507E967385945389493B95C0A95827583F01DCD473FD3138887D3472E18B24C1B7E2C837668FC6917175471F3CAA1323A34432B72C7B68F658868A2AE87306109B1053ED2BCEDCB7037AB72D8C2BF48D29A0822575CC91CA1E5698286C9B19A7471A5B652F6A900659DF9183C76417F0FC89D743AA635791D588CAE6F650F3D314D65A6AE81A935F38B964F290BE7A1A75F256776F17383F9BB9F9203415622B60B2A152A7CE3420CB49C3592AB8AAEC009A237A12C2C04ABAA08A382622DC84A053C94881664A97381AB88CA41846E82C02E00C6033B4721DB29B71FD29069297A2CC387F2AA5336816C66E75B594BCD144171C3F7AC6DF8A9A10A71F35B39A3DA7D53571CB33860315288C2F7843E855D27DB6F27B38940F973B2B063EBA12B3A8B73D46C6781AC87F44C91E982CB27E534161212B367AB74A318B0F41E7A060823F17814F9A6E4F5A9093A6379FB0291D99916B15ABC596550F152BC79703F1B0393B720CB85A510D4C9557ACF3E620CF994C0BF8C06C2606041E7C3CE6044879A7612C3A2FA587B1B7676B956291A7BA5A78527A163AE08696C7C881076189BC1623C8D360C8D85C287A9C0C6965D0FA315E2037EED604084416FE31B2F01C7678311ADA765ACD7F70DE59A9A85A8249205C78CAC786AAC9A0A0A7352B18F9CF936165A9C39D99AAC7C175A5025F1C66D04354480175FC3249930E66C9D06AA50E7ADFEFAB6AA9C205C1507A8F40512A45CEBFB2B39F3330A962ED717408E0934FDE42A5E1CBF04C80F37D7DFC7EB53A785194C4A1232E61C37A5 +sk = 2F766AD78A0112B8CD4BF28DD0F589873553BF114F19C2719F61A32CBC85C71975B911237BC6AA6ACB32B613CAC9DC80C85493FAF63C3E337C274542AB4729D02ABC5DC07309032C7112540522575D663C89714AA7A456410144D7C2BC1041C03D5A56E08CC7E5663C01F52E5077288BB8CBFBA21B4A8A19C055691E05C22F94C62C3CC2B6A9C155E2A4EB2BB9D95B8C9D5A6394D05AF87B038C210D9FAA266CF07088B3CC7AB56FF3366FBD595B3C790B5497B34B94A72D8153FA13B40BE96B51315CA4D22BE3828C3556843545C47B0254266A802A44BEE6E5A19A446472322C6AAA4CF47218EE3C99247564C552C93ED589EA8BB2C637BCF7277D5B5058DD80342815B2E8864B4C330920A82EC76B4A7BB893E0D18278F47F84743223A67F2983AC8C4A1845A61259670B02D6053CA181BA4C1BCCA05B7AF2A27C59C1E4E38DA723B787AA2F36C71E3BE05039183BFFEA6AB3BC779DE2273326B327D42517B6C6ED8C7F96C6330D4C39E3D2A7B81A538693329ABBBB5947B068C3CF7B45C173C1BA9964C86ED91D0BF64E209C1910C218434311A50A2128D52754148159891E00475654AB30B9693AD507B2E19ACB7FE6B14F27C09C6B2570B861926683A285014631C2D7CB8C0C10A25D073D3C067AB819B9DC27971825AE21CC2E50D377E3396F0266A5BA598BBE9A868B0B6CAD2CA3A8CB503778967BB930D90795719B237238C1F831007C690186949C600C6F587AC0D81C8334C57FE0C59DB3E2815D63C26C620FDD75836261644D99327A334EA5A40571F0CDA39CA716D2BB894A50BC4CC84D6621B60509DAC77ECAA39B9779A3696749CE83933EB70C1E85BB2DC3421AE9A0EF40AC2D83A1FAC16C6DCCB0AA16AFF9A94BB6D125665C3001B845E7F20E7C90A3DB636950B0836BA008DA33500FE47FD4A81DF0E268C62974BAD02A6D3B2267F917E2046DF3C1883187683F030A28A129902083CE26730438B0DC0042998C9472F5A7FDBA371D74481DBCB9BC4CB281E7CC1DC4455823AE1AB8B233E83324544913DC261B6274464B656BCB645F87B0CF4512AF443959E67C47D679020C2905D45E21DA586EE8291085A8A432AC6AFAAC594081EC298DC13175779B8635FC8EAE58982258759999A57B704A5B040245D282A9B6C9CBCA838399523F26695F60389AD42F6512783AE65A0C25B7258674398839AF28866671329109A58E579C026549F0B7041DBB6623665FBC9A2EDE41C0436635325912366AB1364B5A3162C4B8C2A14480AA6BF165588B8D26EA968291CABF66A4E26722F87977DAB7807A2C65A26A9CBD339BAC0B24E6B46E0A8082BE95BB7A41B1B8B670ED3105EAF994A06A6414E9ABE2A1B608C29C94B846012A0FCBD6959ED411D8D0C70A32559C68C74D94B2A9707B9D9755E3C69AC40782E97A1F904A32DA824C7459B59B174A9FBB6B41947F47B3361D5558D831B2B444818FFA4C17F4BFCF8B9C7CE451F4CA99884C13F85C24D3CC4740D2567A54AB0583A175759FD7E197F3000A39717BFD9C768248518D50791CD84DBA795E85388DCA21507BC669FF0B906BF515F38C04DC838D0D1357377B1601887AE1B0A0C4490D38A871910C695C50008E5A5A30E92DBF312758B73BEB83625DF3B8D5C47A7A334D4E140915CA1401D461D7052E9FF05F73A1598DC9622C324C1C8B5DE9B0386EA3CD95B86D80085588AC69AE310BE6B5B5379202F4F14878FBB5508907B99490E4191B1E13A6890A9209F0A12910A3E096747EBA94A337AF9E609DA4E8A9F8003633EC099983B8E778CA3D72BCA1C19B4FB4A0FAA4459EA06782367580B7AA49AB74B60C4CEF7AB3BB9BA081227A7E1AC2F5400F8F7395F96567403B2401A2ABB0B70E92E6CA2102C597F496CC8881D7B688861C7988363112155B5B88271072A7A7D68B76036059CA5E402532CE8763C52CA237A334832832F2A49BE3907D15852FCED4675547796D3046535390D44580C24BCC3D67A50CFA2AD8936D46121A7F60179BE7AAD0746E8A2C8CAE124D27181A374493DA6A68D47387A44460B39A45B2619F1D29B08BA4495230470B87BB926279EB760B9041632317C4D7A19E7753458DAC07EB73331D808CE318555E1A2828DA2F1D101CDC9B8363990B85064F63226C36C71061444E17A28C3B56332BAB4BEC2602F5C31394C870DD21030997564DE52602C2628C41CB7AC2388EF35371F870A21675AC522660268A1802A2E4CA4C7152A9776410910175FD08C5E0307F4C2A61C877ABBD2185CE58738FDA15335ABA2C77A804F94077A777FB49854C7A78462263E435A1D7B4A5205AB879438A91EB60397704CD937E66C7310625A6276182D86894EF9750F1817D85709BC578092D3B65F5C84514361264909DC2147AE6F3A577097E64BBB2C679C845D827B1AC393497575E385BB39563E125C3A3925A21160201897072F03F45D6BA85DB7EB1D5B8EC7111DD785EBDE07056653507E967385945389493B95C0A95827583F01DCD473FD3138887D3472E18B24C1B7E2C837668FC6917175471F3CAA1323A34432B72C7B68F658868A2AE87306109B1053ED2BCEDCB7037AB72D8C2BF48D29A0822575CC91CA1E5698286C9B19A7471A5B652F6A900659DF9183C76417F0FC89D743AA635791D588CAE6F650F3D314D65A6AE81A935F38B964F290BE7A1A75F256776F17383F9BB9F9203415622B60B2A152A7CE3420CB49C3592AB8AAEC009A237A12C2C04ABAA08A382622DC84A053C94881664A97381AB88CA41846E82C02E00C6033B4721DB29B71FD29069297A2CC387F2AA5336816C66E75B594BCD144171C3F7AC6DF8A9A10A71F35B39A3DA7D53571CB33860315288C2F7843E855D27DB6F27B38940F973B2B063EBA12B3A8B73D46C6781AC87F44C91E982CB27E534161212B367AB74A318B0F41E7A060823F17814F9A6E4F5A9093A6379FB0291D99916B15ABC596550F152BC79703F1B0393B720CB85A510D4C9557ACF3E620CF994C0BF8C06C2606041E7C3CE6044879A7612C3A2FA587B1B7676B956291A7BA5A78527A163AE08696C7C881076189BC1623C8D360C8D85C287A9C0C6965D0FA315E2037EED604084416FE31B2F01C7678311ADA765ACD7F70DE59A9A85A8249205C78CAC786AAC9A0A0A7352B18F9CF936165A9C39D99AAC7C175A5025F1C66D04354480175FC3249930E66C9D06AA50E7ADFEFAB6AA9C205C1507A8F40512A45CEBFB2B39F3330A962ED717408E0934FDE42A5E1CBF04C80F37D7DFC7EB53A785194C4A1232E61C37A564C819D9BF66855F6AE70627F04DA8378547E5867E2EB9759FE0971EFD601C4A11EAFECA9E810796C34E8CFCE9D59342884456007B01DDD12EDCE6D10ED87E4C +ct = 98322D7A13921EF76042F6DF285A8BD2D0618D843820CD3FC35706C97D92720BAECED43615976F33A50EB4F4871B2CAF187088AC58BF63793322CCBE9A510CFF90786A7C3F28CEC3BA32C2D90D280A6411BEDC9046AE4A13A59FBC3FE2330C34D78C6743009EFDC3554392C4139CBB5855659A8A4C814F89BEA551FD3E8C219DACA38F46F8C6FF101E07A31F0A07B8BE8EE2656C189B30C9C6BC69DB6B6F14799A239B0D8677E2A76F31E081182BFC44371F8592B1A4A8A01DC524BEBCDD43F8E48A77550628253B5B78688E6C73CE990E967C6D67383EA3E66B9D8349FCE9EEC43DC2C2301A4AF7A9BEB52AA99DF13C8F578210647E8935871546416B46BF2ADE02A6AAE8B36DD9F0722DDBB5A06FE93E496427EDE60CCB84CD6B29539AD2D7F608D825D6B10AF253852912E2C959EBA801E3D895CEB04319D3791C31855E40D112B93B5444DA843439805F9C154BC0436859A4009354D0497334739EFF86318AD7ADCB4F64B4E67775D8294F92B8501A88FDB13462D82A568CE39FCEF1598A56E3E0188FE62AC5E456F6D87D37CE482D59509CDBE28D909D452A5D7E2A8D8CF90043E23C330026811BABBD9CACFE298C77B487A9814356133CBFBC0C1BCC9FA503012AD5536432313B3A88596D44D16E2B7339B50456EBDCA6345D95FF6E36CCA50B0036A79A86C8500B532AD3159444455DE6EBE469820EC9B9FD8C956134E99A85D4BB83B02F1AD116DE1249750391D9D9B860F9B75817BB09C688FA9BECAF9A5776A8CB6EE94A4540EC7B9B790A7E787B746BA8343CCDD9C73AC6B2F19CE9A2106EE0E2FBC2399DE6B4250B963E6BF5FCB0FB58F4F182A4375077848C09A1F358B2CCAFA3BD7784DF29B099171E74DCE17558934198C0FD3FA998245AB3BCD782B32B810953C845685408AF76D6C6CC252DF2A339247A5C97409B7E59E652C3C70B4D7B10BC4AD9D1DC5B5572ABC7DF75B0D335ED85C98AA6EC2B9A1EB49533B258BD1BB353339D3BCF303232CA1742F7B3BC69C959CF9A540BF7A5B08564D997F467EF6FBB69747B56C4BC07E7E3D6B4738AF1BACA39417DE8C34D72798336D2934162B6EBFA6BF46EBA85B1CD94BF04CC7B5E36A1EF66A9BF687477114295F8EA84C80267C64BD617722D6F7DE3601216059D7E82BDC18728C2F2CFD63EA1029CAE451B15AABF7BE2D13D7191D1EFFEBA909B05A419B820424CB464E7DDBD0D272BC464E689263FD501650B7AD691565625941DEE3D6DDF9195FEC5718DDFF43B067446A32E2B34D1482348446DCC8B92E0A8077C0DCD1E59F05C9B6A7B1FA867F878DCF731E5FA38ED9596F207DBA7BA0FCB3EBF2E1B0A8BCAFFAE5BBDCDBF62FA40F5AE8612B1E319671FBC71DA87F5297DFAE4BD161E02B7115E9C5C6F09A1C44540D5C8435C7E2CDA96B9BCF9414E8EF6F1D938ADE592AEF958996D908DF29D589857A422B620AE1710889B58CE7A59A4DC96AA46A7D194AE8E530DF9DA7BD319ABA09F94F2F02FE5C4DF2AFC59F77453742F35C08D943F59E6E3 +ss = B8B9F3AF55E8C616D07C7042CCC26BB4B83D20FD502BA5CC7B72310990EC50EC + +count = 82 +seed = 373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE +generateEntropy = 2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +encapEntropyPreHash = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +pk = BE0AAFF4D255D72C6E8424C2D5D23F0AA4C28094691AC4BF0F56A51EA4799810CFB024C151C35CC3C6CC90A41AB964370C2BC953A84A73C87A02813DE34B933F233DA28643A93388F944C033236372FA6E6ACA085B598123F27122A40074A4AF57684D46398E5D58B13A863B0B984E224A7AD52C1C4EB26909451DCF2A15DCB11AC4CA38D93CA350078138E0AE87F1390FC9045EEA420260C913C6B54DD93495F31AAC32350CD03500DA308FD8BA0777C999CB4982C91E569A1C52396EDC506AC7CC43264A05CC880191501860F1A32F7760AD3B17FF693508339FCFC05FAE095C6A96C1E6864BAF147186BC22DD882620E5A5F4516DF92B8B715394C5677D0DB913EFB25459D6C636442A8CE22899F8943957BB2B281A8ED14BB5D0CE6DE3086EA8B6165798619B2ECBFB22727CAFC6409E23088C6C940C23E86A603788C07BA89D6BADCEF07D79174ACF70C55B7B30C067BD8202A1A70998459C54384196F814515EC9C7F360061270090EF37AD32115242C2AADC0121E1A08623038B311982C669DE3DBB1C7789530191B07A947C9637BFA241ED35AA1D03C81F0D70F8B95112A3B1B08B25C34DC7E1D577FD30A808AC574DECBB51538C2A017287E62128F32AFB0F7A73EC8831E6B975007592B5C652FA636C7315BAA474F873A5DA2E82FD146268DC951689BA83E046C0F4820447C3B3E6C78CD240BC4D21E0A4660EB1C69402B617B83057874122E203BD6313D7874A987F2987599CD4D7946E50665F7D9A80651CC8DBBBC4DF605F48274FBA0640F8609B6554A7760856259C32DF00D3056AEF65436A285583CFC9D9A644F66E382D4907C6D78AA461A2B6BA8887C238F81D31E796A675EE8B7A598AFD5D79A0587965420A2E9F2782B71331737680A499AA759824D11ACF1A001F9A5865B6568ED8A1F4F4CC38F74C24E231965E9830232924526BAA377B2EE933A1FC4677EE74FD98A0881628315AA95085C7415A1A51A98406FA345A69802BA71CFC885816EA30FADEA0232B13EAFBC24B84347124BB41F8C663506665CE4C3801B09933C19675C1F9CE54C418207B69215C91B10451730DE65A4AAB6C97804AD33C50233F83599133510BB334D9C1F4B7970087700EF45500CCB31B7933FE74A346AEA4C9BD409BC5A186F00BDCA67CFA8D041DFEAA56547A71C35CEF1B664629AC9D4F431CFCCAF62A781A4BBB2ADCA7A7914627DA380873977E6E1A11FEC0938A3A886E9B328A8A539557F6C700285693266742F779BBE2E7A0603060673C7BE9591BE19A57A0CAC91CD1C61860A86356B90715886ACAC2306190CFF686883A61E56140F64BA76123C1B07614FF5C8A4B402CDBA738AB68B749C1151DA62C30DFAA3BF826D4848C4910C9EA20669735CCA4DF583E0C5412B610BCE816FD17AB9C203A7EA42081901C8CD78940F090EFB49718AC90AD6A101093580C13B5FFA0AC0D7B094D913A9DDFAB03F835F79173E966746C69A0228D06A2C363E94522EC68312CD312ECCDC688C4A88F6A5B7C3464CB7EC842FC1377359A162032C8C504105461936714F451481D8A4942D1715B6A65583999B96B0C47A914F2F721F5EC6315C91B009E714F6518BFDC75E828256F25740C91E7EFD93A5D7DB1850127DF85B8F086DFC57F1F62A86D6EE7E45AFF3F27BC1 +sk = 6C33B8AB2B4FEBAC9FF7DC3E4A689F468A4F08D5C87EF8A142B4766E24073DF336EFA5A0D6FC17B6BB2C615658EB04AA9035560FF7979E27C65A85CA6B1B9BFAAAB23D89C6A825CDF7E312F81066D516BE72680E5A665830F74E371BC411BA86F00704DCD3C40C8C1295D6B52ACA51AD41732032535AF95BEF907127EAB1EEB54899A36961793EC47B91D9725643664082C4375F4843B0031B815C8DFFCB7F25D4414191746D5AAD14093BF2C005DF655F69917BAA956721B4CB8B8B51531A4A6C0CA50F8AB21DFC7CD9F81D730157A59B971E4B4A0FBA8EF49754A7C2BE0325C8BC623FD2A94A6CC4226677260FFCB64D75167D63334E395DF5BA4505495CBC8C3A3E40AB68796D6C646775339C29683A21F921A7C6A79D39A95C876F782A27A6365908381D793B537D1A681CAB5599817E050CCCF7803BF9A90CCC4084743C96069183B08702979C9DCA2B9D9BC26E1DE849976AA1465B29EB260FFC64478C39945A9B402520172CD7861C5A0CC089A028C8200208B3E4D7B3A91CC8C209C5E1D201278B01CAB34126C701BFC2913DF501F6D73D9424CF1176B8616C04C10940EF9832957585EC350E9761505162AECB28884F659EA23125C382CF24F383F9B09FEEE8AACB981DF21A6BCEC26E2A67493B919FEA06170C18B79E5A01E6E89516707BCC7CA353727825514AA0D52504606013E53BA916BD133814C36B98FFF15F847B7383854F692450AAD28231F2BB4FD839D2B532066114DA65BE8CC5073F9992E03836CA3A623C301999A56FB00332D1BA8A26D599D0F5A97975814BE81FC9DBC536D1C165A131CA3C55D04A05D7A53FFF1299D3860CAFD8BC6E3B97E72A595D294303A12994510F74887FD1D7BB18DA70BFC5BDD58C1F6C1CB56F5994B7F2225CE0AB29E8CF3DC851F1AA5BF2BA255F7215CC71C5DA95115D6A98A2317224BC6DE1B2C79353BC5C3C046A7A0933A73419F7B117B88F3A53777143546CD29014E15E37C33770A8A9A11BC2F38777E400132A812A984908B3D2B87FC465B564045E79453C0666E3682A894C269551AFE25286FCDB681CB50B260B4327B46C2D0699BECA103965B0A218902EB4680C1B8C3ECB2011A396B0DCA97D56AAD231168FD9A7CF177B85B7729DE4A4BF035482AA7758ACA9E1F36BC9033EA34C6DFF91091E8B36FD2A2C6B1094A8338AD540C8F53CAB80D73E7DEC3977452915B616D0F0BF9E842663CC477CDB5DC94579D6222D1B647EF4D358C5435D3D0799242B66818A683E8C5651B0B26CE4909F8656FF35CD7FFA1C5988074FFA32DF093BCDA32AEE2003825593B545B44190787C4C8656D85CAC293F615811CCB35EB0413F44B1722E0A182F09481712AC68E3C9D31085EA77946A54BAA91C8AB8E814C5B94206070C0A6037BC02A292082018933A5AC32141180A6DC760C2C9ACEB3B1A1505464150A732664AA51B02A721B63759379A638BBFD07FF9A7A84E071FDA70200C61894A8891DACC375C120A35E0A4F296A02845477BC0484FB5BC539C3B8BEA3ED2511D480B1DBE76C640622B67A1A8E000B954057322CC005F88284D6290A5D720E32B5F6CB6B992BC182D66A73B5019572867640343F267133B060545D4B2BE0AAFF4D255D72C6E8424C2D5D23F0AA4C28094691AC4BF0F56A51EA4799810CFB024C151C35CC3C6CC90A41AB964370C2BC953A84A73C87A02813DE34B933F233DA28643A93388F944C033236372FA6E6ACA085B598123F27122A40074A4AF57684D46398E5D58B13A863B0B984E224A7AD52C1C4EB26909451DCF2A15DCB11AC4CA38D93CA350078138E0AE87F1390FC9045EEA420260C913C6B54DD93495F31AAC32350CD03500DA308FD8BA0777C999CB4982C91E569A1C52396EDC506AC7CC43264A05CC880191501860F1A32F7760AD3B17FF693508339FCFC05FAE095C6A96C1E6864BAF147186BC22DD882620E5A5F4516DF92B8B715394C5677D0DB913EFB25459D6C636442A8CE22899F8943957BB2B281A8ED14BB5D0CE6DE3086EA8B6165798619B2ECBFB22727CAFC6409E23088C6C940C23E86A603788C07BA89D6BADCEF07D79174ACF70C55B7B30C067BD8202A1A70998459C54384196F814515EC9C7F360061270090EF37AD32115242C2AADC0121E1A08623038B311982C669DE3DBB1C7789530191B07A947C9637BFA241ED35AA1D03C81F0D70F8B95112A3B1B08B25C34DC7E1D577FD30A808AC574DECBB51538C2A017287E62128F32AFB0F7A73EC8831E6B975007592B5C652FA636C7315BAA474F873A5DA2E82FD146268DC951689BA83E046C0F4820447C3B3E6C78CD240BC4D21E0A4660EB1C69402B617B83057874122E203BD6313D7874A987F2987599CD4D7946E50665F7D9A80651CC8DBBBC4DF605F48274FBA0640F8609B6554A7760856259C32DF00D3056AEF65436A285583CFC9D9A644F66E382D4907C6D78AA461A2B6BA8887C238F81D31E796A675EE8B7A598AFD5D79A0587965420A2E9F2782B71331737680A499AA759824D11ACF1A001F9A5865B6568ED8A1F4F4CC38F74C24E231965E9830232924526BAA377B2EE933A1FC4677EE74FD98A0881628315AA95085C7415A1A51A98406FA345A69802BA71CFC885816EA30FADEA0232B13EAFBC24B84347124BB41F8C663506665CE4C3801B09933C19675C1F9CE54C418207B69215C91B10451730DE65A4AAB6C97804AD33C50233F83599133510BB334D9C1F4B7970087700EF45500CCB31B7933FE74A346AEA4C9BD409BC5A186F00BDCA67CFA8D041DFEAA56547A71C35CEF1B664629AC9D4F431CFCCAF62A781A4BBB2ADCA7A7914627DA380873977E6E1A11FEC0938A3A886E9B328A8A539557F6C700285693266742F779BBE2E7A0603060673C7BE9591BE19A57A0CAC91CD1C61860A86356B90715886ACAC2306190CFF686883A61E56140F64BA76123C1B07614FF5C8A4B402CDBA738AB68B749C1151DA62C30DFAA3BF826D4848C4910C9EA20669735CCA4DF583E0C5412B610BCE816FD17AB9C203A7EA42081901C8CD78940F090EFB49718AC90AD6A101093580C13B5FFA0AC0D7B094D913A9DDFAB03F835F79173E966746C69A0228D06A2C363E94522EC68312CD312ECCDC688C4A88F6A5B7C3464CB7EC842FC1377359A162032C8C504105461936714F451481D8A4942D1715B6A65583999B96B0C47A914F2F721F5EC6315C91B009E714F6518BFDC75E828256F25740C91E7EFD93A5D7DB1850127DF85B8F086DFC57F1F62A86D6EE7E45AFF3F27BC1DB315CAFBAEC2F8A0142F45AFFFF65289E826C9244AB1CB03F9F65DF3E3CBCF711136E2681DF2EF881B51A092A9BADBE72C9772C169808521C47149578621E28 +ct = C324CF3A1900484410A1DE432AC56A735217564A14F75A75526E6C83672BE590AFFF601320226F0C0614068ABB30B7B0AA66D54B4FAA789F9D9E0E48DAAF7CB452F4897CBE76FAFD89BE2FE0C32F9D0D4ECD61E6AD891998D5C4B334CB9DD402C2284E0F03A85DF505C876D300DA586E398AC16331D8F8B8E84B7347EA13D50DD1A33B7116520638E8BD779793F6CBDB1ED82D8ACE7F25E50F94EFFA23DE36BEC9210B1DCEBB1319A8AF22200A33A49C09B63998A18B4D438E1E4958F5DB78CCFE9E10FF0537F35931F05E629D8BA4A5B18E9C1EF194089DA0C96105BD287EAC7ADEBF758F4355B560404351C58646BA01A955644D1FCEA3A30F7AFC01641D360E74EA49BD27C1C3943092FA740075AF38EAD19E6376E4C91F9075BE124B4A43A0DBED278B3ABE532698E57B60D1DE574F31E159D98EE07896B6E9D88A4F2594BE1F0A0C73D7466FE92F8464191B7A7E54791981EB2A8D39A0B712F5D4507F8FAEDFC7E49EC6F31ACC77466494EF73277330AC837272D68CCAE0D05D75A235E353AB29216A2E8C7ACCA8123D24441CD51CDC6DFFF3AB4FC70800A427642C1E1795D41C9BA9FC87A3035E7F1CFE390F1EFBB9B955EC6A0918BC45411E8325FE8F4D6BD928D4029949508DFD4978395B6D021C92453B8599D8705951E2FECDA5F03476ADD8B6D7FD9B1336E70A57F42017CFBB329E925180E034A438A50623589871E47EA8994C1ECE7E35EA42384B1E66DEDBB3A111513B6DD7F25D95F5FF0236B717BADC740505777B2CBBCAAB063523C6A8D1EF6A9CC9F689DC6EB2759D5916C4AF16564E6C23F38A4C27DC1219094A023EBF5B56827EA897045DC881F0A89A853645942356EFF1A1A9BEA7F2C12C68B5EBCE0706FAF9CD72E453E0188071856C7FF37B952CCBB53CAD0CBF604DF59438C4022F6F26D71E9073CC1A45AC6BD3F6A71F3EB284FDE720416CCF1ABCBA0C9239144A6AA38AE655786A2C3820407C77F8378858F0877E6CEFCD5BCD8E5FAEDDECD68C1E2FCDF9BDA5EEF60FB7E8AE441CB8054FF7C94A8697BDE5001893ABF8140424583DF49796D1FD10F4DC493BDAF3C1C3B76FC1D34346CE5A5B7755A68F8C5490CE8827CB8AB61C3339F0DECB83F09230EAA58E6154BD8E1A77291654450A4949C3DAF8B4C05B001D94F21F0698C426A93D64B2D1005D1217BE6783588EDA458545CC1D677B2770B25491224D8D194285AD612F741ADAADEC5B2882D13334B9BECEBB39F9F0D4DE237FD36D7B4E114A079BEE6D7C2AFEE75C4961F81C75887A616F1E6497A4825C939128FDCA95DF452C5F4D27B1D516B33DE9336E394906547AB7FA5ED5A45CAFCBB56E324B606DAEBF25E705590EBE36AB32F5B4A4171AB7832DBB66177E9AE6C29E5E4F503AB861488D5AD246988D4CF8A41276F1048E4D778776D34577679069E4248CC09A5EC7F533685E137AC32C984E91E8830E1934F6B2F91B33A3605C53E51A8B7264D53B69AF57507F5B5AB6D4F1B1B09AA1E50CA13CBBAE62AE464E99C40C2072 +ss = 2E4139C499A24CAA334754E10C6BBDDC7A0830499CA65E941AF8D87EE022D483 + +count = 83 +seed = 16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F +generateEntropy = 9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +encapEntropyPreHash = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +pk = 690B34B6586039100E84215EDDB39AD2D40BA9F80165623122A2C5FAF3437AB0376894CE67397D32A67C3BFB9761850C1C68AD988348725C83A378143D504400F995157903B9D04EE43404AB2CC7C35B8E0E09CCE4559945F5640450703F81C35ED332746162F7B8328F78BFC3359E7C1B4FCF06155FC745C70245FFEC09ECA957C8475C62B05BFFF288A5E5A5C78206E48C3EF373658859C3D9636786980578C07B764641D6A87222224557D10436FC72B563883ECB0934E50B6EC89429D7792EC0BFCDA416FC2AC323A58DF3FBCDB6E023140478868055251B1C09FA023E240E109869C1D2967F598A529042D9859F97CCA2E85A635418707B3AA1835B77DF93AE4DC53F228083DE6A04BDF58655C59BF57B107987B88CBC001E010B9C2458BDF138288190F955B62C7013DD5784C809A7B1A29F8C3C33F0311A555306327392DDD44EC8F72FD5893F56F58BAF207F9EE98B7E31092F761C390763A8B57409C7C5C665A913E20C9B62A5E80646364AA8E3B95030FB2FB289991B8637EA57C7B324A25E0389CE979B5E816FF841456261BF042C85DAD84F80D788076B7C69CABB8E389A72657D7D63949657B934A468516C36674194DF1AC3F595A294C28D24C26E1B1B5AF5B542E025A182868E1555442E0B0D064865ED5CC1665074E55AAAD601779E591E1ED2AB07CC551437603D24CA743218FA846822B2857F871FA26834E0422746A6C7DAD256BC0B4BFFF21BD7309482D7669F8857543A0436140EC684C959D26F2F827A84B37534B7AA3BC0A08163689F01141B511E7D11A316D2AA7D73909E889DD000C20E38667DA048278B5EE87188607B4210642F5C38866FAC1549637C600C8BE8C60C11AA394E8344B6C6536E687EF6DABAC397ABF1CA7486F6AE87D8A3DC8070B5687F7C6A73225B9233685C6B703D33677998C24E40A72894193CCA1C5ACBE4A133D85A6912587AD4AD522214974CBB1F877E16164683021EA9C335D41B000CF52A3ED45B2D95B7E2D061B5213DB4C6BC36D76DF5DB9EE6984D31BCB1F6757DE7E51871F1AE7F388C5134956D3286A49BBA39967889C9A424772BF5DAB014C94893A4C8B74AB099687919243C7633CAF297B2B73AB15DF419F6EC22D15A95553831BE379ED0489749C495E3B6B8E190049A8065DBA8933FB21BA3A751CFF289A2E2772B06A4687338CA88C0EEF1488B848AFA1041F4F9607EB18BC0650055803041B728F2F1922CD984D228096FF29E71F097921423CB82254C40A615240A2482A3F5F095F5B399A8F9ADDEB6B726F43E3AF64D09038CAFEA26686CAA2CE2194CBA660EDBB083F92DC2A51142BBC922958C86C62CE7A4B3A4C95240D72244A912C3C193485208CDDC4514495B35863CFC6CB41FA721A78080FD7BA72669AC6B29ACCD3B832D35AD70F7584E197D695B78C832000C1C337FC019F0AAC04B2149A469420C15B2DAF5281DBA5DC3618E0135C043F139CC74B14E7451FC11328F06B73F124766403541131D94506628C30B7BA68564179FAED9C9D2A20F3B61793A33A65E92B699A47FDE974EECBACE22690273A757DA903A886778002D283A819CB1EA2D34B8462DCAB57C85653E363629D9270738434AB1BB46BB71890031FFECAF8FC027D2DFA2A4AD271DD702F055836F40CA137E5D0EF9 +sk = 2220BFA6A447DB5013ED5811B45742B6E95C723A35851518E04B1B619C5607944C341A1ACA4C0EB297BFE3990D514ABA3DE30867D646CD76A1EC1176F1E84EE60704B0E04366E27ED0F321BBF42322F5289F5167435B880851B48DE717E40A1B56387D4705815701BC2B80C55F33B3C20244E0E27FFCF43C457A3674000A4404B4157CBEFA05C54F50021684059939A3AA088DBBA13BE56047DF450AFE33C8742ABB0CF48E0B1C24E8719EECE41EC4A3254836B4E45B4EEBBB43D398A813BCCC0C42CC4E437050740C892B657765B252943896325E3F4C45887452847AA315BA8C811B39254A5C3EE64F65823FCF2A92E3198D2981289E021530AA4CBD210FABF51094392E25E755D778A02CA145FFF47165711AB9397A0F9B3DEF26BD0E5143C23A815C8582976521D63BC74D8B42B95280CDC77DE3528628862F44D475F49AC204C87D2647414A4A136A094B7FB923BFD3496B187592E81B8168BDFFD9522F60BC37052FC579CB3F7A398DD677BA14A3FCA1248057A59A58531B7A1F1773735A27612520B03121390CF624D46927CEC7C7D00AB13DC2BA6445236BC68642EC9659D7BBA40AA692C40794BC4BF5F13FBB617E711A54BD825329AC6A9AF2A88A54A600C0CD6754B4A3ACCADB397CABF2AF41463C00512D6D206D011BAF6D833E4ABB8DFBF736DF8036278A8125389C3B99940881760AC150967464483242DD52358A075271FB82D949AF57F345E5DC46845A94A37893613A76B6E7B4D0DB0EDDA213302677FB73C493A349704333278B201B6BAA8315731A348DED27283DBAA05E057C26C35D68A5252F1715337A1543895DFA4C395F9909B7B1283B450B71730292C32DCFFCA05221B14849AA5F94888E2A3FD33CAB3B380F8093742247AC27012E8D7A6B8702983DFBA43601677679568A8051925133FBF6550DC318E387C3E3176EC9C3CAD6A739C6BA5B72FA587F000CA8F06EEA003CD05970652B0F3F92B8BD4AA1570B02CAB21D2BD0A9937A499943CE285B32706589C11CB662461444629F5C755B4A09805DD5659127BDCF5466270A5CB6328FDD0583E701AA98D34095506284B63A6F7B39D0B31FEDC43E20E4BCB39B99D82515E041627FC5402290BE758A062822C26B750463141D9DE8793B385F556A3A3F74BD8AB61F69304AC4082E08F2CD05E5BEADE17D2C87B9535A084A6B0547389D08F548030B1DDA0137D170039E082C5583BC83695AFF0898F7E19E54204582989556B924DF35A00C518AB95CBB466B5BA0D8AEF007A8294294870902E74152832365FDB79508B69E45484139B4342DF8C391864B80E807B9DC8DDCD4463FD1A986986B81A62D79AA9565308AC1471F09D09A23F24E4EE5522B00265770674C61348FDB3BFDD539994B20FF22B210162961B56DBA538252610FA607372DB1317497B85307B61D890A62B90E4DD37246763DC6093AF5F4CD0DC20081BA4CE2D6BBDC969580607022C590A1687004B0730AF71C60590D1A6B2A5E51C742D2CBBAA826600055F4811287A062DA1696A22808507AAC327A9194C5C6D49C823557100C158E60B845AF953539A855D217C5A77599B1783F7488AA85F222DF73B837E4B8D1006A8FD6B5B06083690B34B6586039100E84215EDDB39AD2D40BA9F80165623122A2C5FAF3437AB0376894CE67397D32A67C3BFB9761850C1C68AD988348725C83A378143D504400F995157903B9D04EE43404AB2CC7C35B8E0E09CCE4559945F5640450703F81C35ED332746162F7B8328F78BFC3359E7C1B4FCF06155FC745C70245FFEC09ECA957C8475C62B05BFFF288A5E5A5C78206E48C3EF373658859C3D9636786980578C07B764641D6A87222224557D10436FC72B563883ECB0934E50B6EC89429D7792EC0BFCDA416FC2AC323A58DF3FBCDB6E023140478868055251B1C09FA023E240E109869C1D2967F598A529042D9859F97CCA2E85A635418707B3AA1835B77DF93AE4DC53F228083DE6A04BDF58655C59BF57B107987B88CBC001E010B9C2458BDF138288190F955B62C7013DD5784C809A7B1A29F8C3C33F0311A555306327392DDD44EC8F72FD5893F56F58BAF207F9EE98B7E31092F761C390763A8B57409C7C5C665A913E20C9B62A5E80646364AA8E3B95030FB2FB289991B8637EA57C7B324A25E0389CE979B5E816FF841456261BF042C85DAD84F80D788076B7C69CABB8E389A72657D7D63949657B934A468516C36674194DF1AC3F595A294C28D24C26E1B1B5AF5B542E025A182868E1555442E0B0D064865ED5CC1665074E55AAAD601779E591E1ED2AB07CC551437603D24CA743218FA846822B2857F871FA26834E0422746A6C7DAD256BC0B4BFFF21BD7309482D7669F8857543A0436140EC684C959D26F2F827A84B37534B7AA3BC0A08163689F01141B511E7D11A316D2AA7D73909E889DD000C20E38667DA048278B5EE87188607B4210642F5C38866FAC1549637C600C8BE8C60C11AA394E8344B6C6536E687EF6DABAC397ABF1CA7486F6AE87D8A3DC8070B5687F7C6A73225B9233685C6B703D33677998C24E40A72894193CCA1C5ACBE4A133D85A6912587AD4AD522214974CBB1F877E16164683021EA9C335D41B000CF52A3ED45B2D95B7E2D061B5213DB4C6BC36D76DF5DB9EE6984D31BCB1F6757DE7E51871F1AE7F388C5134956D3286A49BBA39967889C9A424772BF5DAB014C94893A4C8B74AB099687919243C7633CAF297B2B73AB15DF419F6EC22D15A95553831BE379ED0489749C495E3B6B8E190049A8065DBA8933FB21BA3A751CFF289A2E2772B06A4687338CA88C0EEF1488B848AFA1041F4F9607EB18BC0650055803041B728F2F1922CD984D228096FF29E71F097921423CB82254C40A615240A2482A3F5F095F5B399A8F9ADDEB6B726F43E3AF64D09038CAFEA26686CAA2CE2194CBA660EDBB083F92DC2A51142BBC922958C86C62CE7A4B3A4C95240D72244A912C3C193485208CDDC4514495B35863CFC6CB41FA721A78080FD7BA72669AC6B29ACCD3B832D35AD70F7584E197D695B78C832000C1C337FC019F0AAC04B2149A469420C15B2DAF5281DBA5DC3618E0135C043F139CC74B14E7451FC11328F06B73F124766403541131D94506628C30B7BA68564179FAED9C9D2A20F3B61793A33A65E92B699A47FDE974EECBACE22690273A757DA903A886778002D283A819CB1EA2D34B8462DCAB57C85653E363629D9270738434AB1BB46BB71890031FFECAF8FC027D2DFA2A4AD271DD702F055836F40CA137E5D0EF9C8D853E65B5B118E28B7CB6F0D5D6F282E0EA20FD72F3690A6B232B20A8A55EC6CEB14F7662BE0C42779459F69A145C0E2CE9F0BD9A0CD1BF32ED5694CC9AE32 +ct = 1F5D4D55EDE2DD05BE7F87C0FADDE30550A5D90923B7BA8E773B5EA78DD3770B9CAC323D98A6E08C19BD600C830E2C2FEFFCE4DAC32376EDA9248E0CBBA9FA0EF6656DD0CA9B3797992C92869164EFE226FED579384121C0FA2B417D5A9F1EEC78ADE19AD9942730593C9AD039EA26883991A02B93F7459EF9D461D5D4894EBCB31025F095F1B6BCC6153D5A998B50BEC88D447A8FF33224D2BA9E9A58D2299EC6D3735096CA81244B315CFD39DB3B85FC718AFF5954B017724B3C6BA3F6780D87E637B0EFCA63C4523099016F78F2DF9BFAF6B0DFAC64332F1C5CFA54A646000F00196FF0686F0BE1728F6407EEAADA48F9E7A6946815527972C9B661A7CE051E76F3B6767DBB186AC7B923BC7284F2840F7B321873B2E46206489771533324248CADD5ABED7AFBCCB43FE0AF06F2C6D6F867B189522261A2A7F042679E8C9E15AFF58FF305D6FA288B1471F46AC82F664012E1C1375DA9A100AC4FCD9D093F191FDF8B12088897B2D8E9E0CC9A986A458751717FEB6438DE9186CCA6B8D361A29D2FA7742DE825ED2FDE97A021087D2DEBA129EAFAF10F370C2833C80818B26E062DD34CB9A4B23377F79C20AAC87C9F93F7B7AB25F74AC0FE18F092E1BF6E43A82ED4C456682F11DD7CF5B41E94FBBAED42A1EC9432E36514214C6600B053A0C9DA4F99587267755E95C3B45BAAB7FBC3570A2749A2533E9DCC2BFD4AC1D477D585BDDBC1F44626E40A3B2678ECA64316CB6B9FCF232BB26D988B3EEA81E9568BA4868FF8DD72D457513552F6C25C5C5C605401922DE6DC878688CC6762B3904B7AB8F06BD64F239CC5103863A7D066570235F53D4811361AC876A15770755F9834B7D49C831D97C5602BFD14B9EA2B37DFCAA87E9FF0F7EFF68933C5CC9D8E5A5DBB5ABF8B7B7239D384DD2C3A500AE16C50511F3B464F07A1DE801EC034C3533E55FC94398DEB4E9E6099EB40A75548EB34DD62201D39057D2D3AF3EE71EBF3458267672DA7650CCCEC7D34F8D53B3B63C4BEC77DF151483331A461C724320F4B8C14F0BD96E0B932A39D41DFDC8D256F213DEB9DFA7A9C2B43FC15D807B3F4062D0C1C80FA96EBC28C0F4ADA8E47750AED8089AF233686E9AA2463DAF738CF0E754ED0CE169A1C7B99396BF71C61C81C924066045481A88A2995D0578786CF787ACC37287795CE12A14C7E128556ED72EBF3C25C60F8A4909233EFAC38BA1068E81CCFD3236372565985C41909CF5E40A8962569B361A026B2A5F5AD411E6AFB36A536920C977DB512AC027E1C240A0AA0A0176FC61334C5FDD25099164227D3D4755045EA9414D3D199A16A8C4D9E6DDB25B187928E7037E6E42F895AA598A9CC3F04B1BFD9E8122D1A6F4D8076ADE9F9C33EE2B9AAFC78B685FCBEB2C0B39B84C5B12D0AC4DDD3421F8D20FE77540A78816D364658B49B7161DF6B87D3D7D7F4FC26FA13EFE503C1A50D3EF67B9E367B4EACB81082E3A29C29E708F988D888A80FEDBC9ED2B2ECD1DA8378DA262113FE18A9EF88B8636862D9A92542 +ss = E412F3AAC1C0284D999D5A7F8344B4053D10965FCBE1638F7EF666EF29C521D2 + +count = 84 +seed = D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8 +generateEntropy = 9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +encapEntropyPreHash = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +pk = 44BB530C48419ABC7578B33D6DB56C76179E9DA3808BA4C8D7C227BA5C64AFD5C87E01C1AD12A294758F45804719DC7369950E9E6398BFCB60A7819585A689462346AA5968DFA83BBB3B8A51BB59311C9D100A4A0C7586056201FFC3CBD92C3A42D6851EC064A89227B4D1551CA7AF6B5B3E892B4E44571669412E4240A08C42551DCC50086389F9E0C0290956B5AC58844A84BE308D0A5562B57B5CBC594CEAE87910A13167F27CE63B822F201AF5E9C33BCA746BA7C5E8541FFF17324228321C7A0EC976646A6B5615F80FB56351D319B31960AA8823426682A610652652994D4A78C25659B533F5B40E6236A6E704CD891502E9C2D1858CA64C94D3734AC0BBCAB2DB2F9E03450E721A38C82A4C26A487F006E1966FBF8063AB115E74F441837506559BA5B7266F62B17E4D959209B657193689A0354149880D08434FBC282713118D9DAA89C52186EA918CE2C170D8380E45A32E9F710CD6F89DAF91C9210B767D743F61655A9702051D7C8A46F17A681B136C0863CB62430D084D282099D1636C04D6B1EC212A74046D2D8108470123DD751DB685A1A1FB3A3B2C216F51302FA13AD73B919A439D424A4AD9E12994D1963B3C0E0316739CE50A1A7C23D65ACEA61423A5792321A84AD2E1B3F5B595F11637EACA77FC753260E04CEC9CCF55D70D4D567BB78749EFD005C9525F6E921F0630C25CB9A129781B9B864B7556272D5B4164E340D9464BF192979A073384F6A5E52AA0B6B74D43FAA5412C5914524974161AFCD91660705659DCA87BA482D67C8C1400B069E66A19905B331243701AC8261952C5B736B25290235669FBDCC254631294FA2E97C440D97A0211C35C2FF4B6009AA66E27CC09BC09307C7B3794A5D189892EA60B2B323E95057FF355114AB48613E2760E00BAEB82B0A763067E216AAB899E7CA06E195A5E92486CE8911BFD5C7D956318AC3B029436A9D88C56AAE2A3DC7B382F2C5E7265A037A827761447FC59A40A3C8693BC996CA786FA7AC1BBCC6AA404A1BFDB3D227C6ABE42CFC463C2F1542AE418CF4B38CC2C1595F9343D41B4A1967C7C94A7A0AE91CEC8235705805AF096CBEFD0CAD6DC0BB5130907D64E76E4BE957A117D121D66071598112EA7D02B9648CF53E57AF9E7CC3C9803AAB327D87C53E41CB9BBC42368D332E0A963C3385C18936AD7483A5F4292B625C844C2282F25AF0C86984DDC09371AB555D57DE146664FAAB59DFA514F8BB8D397A987BBC8DBE147EFC2A34DAAA712BAA1E36C9C5113A7F47BA8C4A83DB2DC79AE93688AF7C480DC8ADF0B12D7F5453E669BE2D805DD6961454BA8B40C6EFA961E53DA19EEA2243C998B504C8AB9EAA2DB11B2F9B591990040954A1567074E69154AD6E618D0830D3B554FE4C99F48B51CF6609952CC9693ACAB000C335B98126B4B45A9F317F80A6049558FE9D855A026AEFDC649D295387C530E075CCB32AAA202171C6F6907A4A2202A9C5FCF252D98328F12F927E31C596047140AF9B177E0352B120954D00529A07D6B2BCE5026A6D7CBA01231A85BA39B1692694788C9215B69FCD111FDC8934A1BA24CC7890EB479AEF01FF29161B0A7AD921BB72A8B495FFA74C62C880BF03F0BC175EB865A17ECB56E0AEA501BEF8E12D3025185BA4CF8EDD1B0F297471D58C26516 +sk = 7934A9FABC835BF9A77BB807332251DAA00876E5500D2C59F07485ED01BC934911A336ACDE5527DD166476CA1D1AA558CD88CD7BD17CE1791958E851991867C0525C9472A953C8B04A730E2E132C6C26811CB86F3234229F4CAA2AEACD2E3C840E97B8F1805B94D7317B08354BCAB64887A4E6A98FFD90A7544562CEABBCCE6489C6E8534119C9589C405D7A96DE3230094A459549B6F37078F2C01FC9080F049464B0A969EB742419147C8B39B8065A769D400A17BB25DE51A699B69D54BA460D33AC6A6965916829B7A578D0B24BFF786CEF9963BF961ADCC20F9A0CB1C159865A344A0E36879C67852DF50ACA08A46E72A4A70C027CE283DE5BCB219808F2635BD7540915C5485AB70358CB017882B12ACB4426B22B02605873F2BD0DA59A658075136CBE15418CCA0A11386AAD43A52E3C5AC97F36BC7F648808C260643C325CF456E6166EEEC74EE8476AD62C73D7D334AC279D84B66B6C8AAC217A813DBB3DC6007317A165E6A1657D0277C1E683BECCC956D973C7624E959724FF9275C1AA2BB5ACA75159721B8C6D7B299C7ACB4704C654335982E83AB3724CCAB3709D20601C2A943D5BFBB3D384A7E83A7793905301B1704CF49992077B19F0204F3394717C9AB9A173113004FD325EDB797A30155D0D2A1E4984644F245F5B495B56A98FDC487B29B4A5C6DC4E3047A8DA2C9325F1705613705628458BD525FB333087CB4B967A61A994CBEFC504D18C1B8A62898AF32BC454A57E264722897D5DC71E32C2495CA857E1A234AE61C77083BA9B780342D7CFDFF8B7EC1257B79CAD017113A3238510C5683C3A8C396986ED392B0122C16E34A7249691EA7A931C44087FA1731746C1F3855BC72414FE3484D85B5E2586B6231B4BCF27831EA7B57070A815795F43E90B2112B235F5959EA253DB76192BCB11D4E16399D40C5DC0A15D98C3B3B0289F07839F7738ABA3281D45AA0A9CA1D349A64E79246C2C7770227F1E1CC74DB8AB7EA7B0E60A9DC0E45443B30CA656CD6A8897AB105BDA51B02179936F04374554A52992710F2A70972479462A2859736C2FE4359A474939AC3531B2905F90BC38860B5615ABFB1A1327814C01048BB93C9725C7C3B0547921975766A97E29D529E4D8A090C36820DB0FEC33277CC679CD4A51F7CA05F204BFF20ACF63EC403AC7CCAB951A8EC166C545ABFCE8734833274F724E77E68137967DA75515E3C270CE79838839721BF3A14C952085071D6B3A555CE62D96E7736A583F44F726AEB921CAA340D4BB788D63645DEB2621629DFF8A2C51D23BFEE95CAA7756F1884A0CD263039C37F7415E83D4908507C1B17A7308CB329D829C86953422B8B2F1786A4B86B980751255339258572A02AB22AD845632F859EAC223E1245AC3533D359246316A3CC1AC58B4E6386592859547171CE05DD7A76BF8E93901EB7F40114175AC45E0B35109AC57BE844C52D31A7BA60A24F30EF0E45581242C02E020EC86AF106836B3DBA8071BB8E8574FDF208100982E55F4B0DCA72521440A2AEA68C57B2039D14B21A56274972ECCAC7EED41C4B26CBE2C973507F1CDF4E618077406CCD3C8C5118545178351522485730B1A1CA7971B01766B914E835244BB530C48419ABC7578B33D6DB56C76179E9DA3808BA4C8D7C227BA5C64AFD5C87E01C1AD12A294758F45804719DC7369950E9E6398BFCB60A7819585A689462346AA5968DFA83BBB3B8A51BB59311C9D100A4A0C7586056201FFC3CBD92C3A42D6851EC064A89227B4D1551CA7AF6B5B3E892B4E44571669412E4240A08C42551DCC50086389F9E0C0290956B5AC58844A84BE308D0A5562B57B5CBC594CEAE87910A13167F27CE63B822F201AF5E9C33BCA746BA7C5E8541FFF17324228321C7A0EC976646A6B5615F80FB56351D319B31960AA8823426682A610652652994D4A78C25659B533F5B40E6236A6E704CD891502E9C2D1858CA64C94D3734AC0BBCAB2DB2F9E03450E721A38C82A4C26A487F006E1966FBF8063AB115E74F441837506559BA5B7266F62B17E4D959209B657193689A0354149880D08434FBC282713118D9DAA89C52186EA918CE2C170D8380E45A32E9F710CD6F89DAF91C9210B767D743F61655A9702051D7C8A46F17A681B136C0863CB62430D084D282099D1636C04D6B1EC212A74046D2D8108470123DD751DB685A1A1FB3A3B2C216F51302FA13AD73B919A439D424A4AD9E12994D1963B3C0E0316739CE50A1A7C23D65ACEA61423A5792321A84AD2E1B3F5B595F11637EACA77FC753260E04CEC9CCF55D70D4D567BB78749EFD005C9525F6E921F0630C25CB9A129781B9B864B7556272D5B4164E340D9464BF192979A073384F6A5E52AA0B6B74D43FAA5412C5914524974161AFCD91660705659DCA87BA482D67C8C1400B069E66A19905B331243701AC8261952C5B736B25290235669FBDCC254631294FA2E97C440D97A0211C35C2FF4B6009AA66E27CC09BC09307C7B3794A5D189892EA60B2B323E95057FF355114AB48613E2760E00BAEB82B0A763067E216AAB899E7CA06E195A5E92486CE8911BFD5C7D956318AC3B029436A9D88C56AAE2A3DC7B382F2C5E7265A037A827761447FC59A40A3C8693BC996CA786FA7AC1BBCC6AA404A1BFDB3D227C6ABE42CFC463C2F1542AE418CF4B38CC2C1595F9343D41B4A1967C7C94A7A0AE91CEC8235705805AF096CBEFD0CAD6DC0BB5130907D64E76E4BE957A117D121D66071598112EA7D02B9648CF53E57AF9E7CC3C9803AAB327D87C53E41CB9BBC42368D332E0A963C3385C18936AD7483A5F4292B625C844C2282F25AF0C86984DDC09371AB555D57DE146664FAAB59DFA514F8BB8D397A987BBC8DBE147EFC2A34DAAA712BAA1E36C9C5113A7F47BA8C4A83DB2DC79AE93688AF7C480DC8ADF0B12D7F5453E669BE2D805DD6961454BA8B40C6EFA961E53DA19EEA2243C998B504C8AB9EAA2DB11B2F9B591990040954A1567074E69154AD6E618D0830D3B554FE4C99F48B51CF6609952CC9693ACAB000C335B98126B4B45A9F317F80A6049558FE9D855A026AEFDC649D295387C530E075CCB32AAA202171C6F6907A4A2202A9C5FCF252D98328F12F927E31C596047140AF9B177E0352B120954D00529A07D6B2BCE5026A6D7CBA01231A85BA39B1692694788C9215B69FCD111FDC8934A1BA24CC7890EB479AEF01FF29161B0A7AD921BB72A8B495FFA74C62C880BF03F0BC175EB865A17ECB56E0AEA501BEF8E12D3025185BA4CF8EDD1B0F297471D58C26516F69BD52CB1D071F1CC7720F949D44F66F40C917EB30F3A4B0EB519ECAD2D03DCFAEB2EF44D2F608621E831187CE79B2D2F4A20F1568BBE76B0D3D5AF36111714 +ct = 55B89334DD971C479417D6D70BAA960E1BDF4ADF3DA2D9D2AB18113F740E0558502F016B99254163B21199E2BDFFC897FB3B1022B53B9BFA61C200C0F071BB74507BD0BECB61EA9E4D9F860D376F3D9D23D3EEA50FE0BE1CE6C40B27323C17EE5E9A9DDA5BDEA6021070927A035D822B44A6D457BC9227E162CB2C27CE543BC19A9B3437613C037AE5103B5082F7BA35EDAE372FA5965D00EF8E6CAF2E856B4F0F57995512328203D9524BA18E1912EEEA55DB3E1CA0B8F0AD957E04D009E71CED4F0767BCA4CC3673C33BB0A06AD8C0536EA5B6DD0C093339A0324623F5D4C007F23F0562D505B2737F9482D41B2C293D31B2E9BC5EC86FA8A140E2D1FEAE33FA5E7636C94783F61CB0068CB7AC71DBD06FE2BB6A58010A391B1DEDBEBD34093F6F8DFB6977B1B709C895BD0F2A8D8A39AA9DC3CFC8E8D522BB9EDB8555F06CC418E68F4BFE6E449B069573AE3506D8D8E8167F0B25AFCD48F018E03762AA85B2474C6AEE304ACF649EED0E9688D6C62ABD8638590C74E0359881CD0ED9204777955B6135DE3A777074BE90669DCB9400AC25D55E022A9362224BFB9A830E237113ED56B89898957854161EF6771E58B6A1A7947A381216CE20A97451555D3D2CB902E69BC762651412EF5852C823B1A8DC477426DB5A9DBA4818B76B40E59C8267CC26CB28E2E050502D8506E9511FF57A5A732082170FB25907B272136485D4EB8F2767332E1156B4C7A54F567957CBF0530F7293F61736F44A31FA94B1B6EBF7D79E2A87493C2B5FFDF03DEADE92C1983DF596E16439B6B0DEC17CD95D600748EE2074A219E43F06FF7B93124DAEB91A2ECE0D684559D8A820B4FB35C1B647065EFC0C98EF4A38DE1927C499178F4DE44F74F1849D057FF153571D5ADE12845E0C61E35171DB6C63EBCD9C8269458A3A1C5CB26C20EFB664E79306C841DCCD240A2ECC86F69C00FAC5332CFA28D874847E1A8A3AB531324BF13377D7ACE16DF5B960B1EBEA092A40F5E1B09BA3BF56807FF9037A1BA0C903A7A1BE491D7B27A78A10FEB3A3030280766EC0A75FAE99BD4CF2CA5BE940D45064B0215628C09E4D6FFCFCF7B1B69B1C05A82838FF64C414E66FE6F2816DDCB90887EA23A9F0DE07F7509F005800E2202C63C1B241DD470B48AC484786AEA204AAB301B15F0B647A5776491A7857AF5DE8EE4D77E6B84C1697663A72F28934F5ED40EE72419E7700E18DE42C0365BA0D5F55FD644A874ED0C047D198D379AAC2D60B233A3D8F97F336A7685371DCD1849996157FD921DC42D2A63755B82F4B776912C27837E2AC17C24485E08F7BAC7FEBE512FF7A92F8ABFB262BD53F887D54E77861ECAC9E14D68E27E211EC53DFF507295A0D82B58E2E8E00CE698FB0199D5D7F9F200D876090613D6ADC34A08ED46B55303917373464E5C7DA621E73738DAA1D3CE09DA22B98B48ECF37F8A0D4A44A3E8B086B2F7FA078CC5714F3CD296508DAAEBDBFA565D3ED8010816F4DE58FB4B25DA0A25161A91A38CC42287DEBBF8C30F28B288C +ss = 4F9DE6E4CBD9948D2DE9250654D5DB97FFE24CF222F68BA51D6261F02F4DC5E7 + +count = 85 +seed = FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792 +generateEntropy = 6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +encapEntropyPreHash = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +pk = 9EB92FFF176A27197EB4AB0171211DC7FA954C652698C50105B5C2E9F7A2A887BFB40880F8624E1FC67B1B43A51139AC6025B9EEB60925D424BB82C58B4B617618C43C99B07FB14E5B86538D29700E1CCB4F53A52BDA2EF566B20D8CCE1D7616DC81398D14ABD03964940C794E6100DA994D5BC0BCF28B04A8971214E7AB9285515EF09A7B486ECAE5C84655C9EE15255B715C3B784D9C243993171C604A3E29450728396E7572228610BB9AC04B06577B3636C137A24E2139B48DB005553152C6B040CF0B2408248675EB90AFB66D6105537A316C7C989746F43C3B284342E2CDB5F2183A16CE71AB39C67797112B0B907C00F6A47F17DB08D924826D526CF88234A25676D82449F93B2859076978860E499A0DE134A936E35F06A7802456008C23970818318AA2B55A1762A9394DDA7A49EBB4B38469410F5945DBA2801AC25BA39A2DF819B0DB194B53C4247FA5065FF99F73E71D51C22F51FC262DD2809EBCC6879B0D90004DA5BA7CC9462F6C822AC8FAC8AB95B769A465CD743BA2BABB26958AB9C3494D329A0C736C28A9CF84F5C90C5A0594485A9B339212D01BF6910105D44109B09BD063B4F2F3B903C94DC650812AE5CC87527754D476FFA82F34F39B5462006029875712CFB1DA648DABACE5AA1590B5CCEA82C20E74795C71BB70826EF4D0BBA580A447693A42D8AF3256C64CE327B370CE576B6343F2BF8FECC76E1434D5E448AA8A3B326584DDC56496704BE54108F8572170C2BC39680598017641422BB81645959B8092E82A54C68AFF60B78BE78107E7BCACB241B09913461579B52AAC5C6C8627CC033BE2273580A523D4CB7979CB65D7056643856BE187DDAC112799559A87168AA96A18089A6C547E87DA949C62B8EA876AA0192AF409BFBC354F05DC08FED46904A2688FBA59FB71B83031A19BC8A6350BBA93552BE0C01B73C89964563FE588A5B76971DACBA69868B588BB2F9076532D6A8FB4316DDA4C85C2945A2A29B6EAD3900E50ABEF2B44375AC36BCB0E028A20CCE58353C827F1D53A9A0510E3827CBD1383A6D18C0D22C374E2B6061C2197A6CB094CA9DCB42F0418C24A9CB893C45423447CD5EABB0B9B410C9144013543E5C3BAD525377CE8073D4A5F4A22BB24874B7E21523CCA731265572B487E3B42AE581A617437348C290F00AD09460AA0C7B6A1A53128E4E01B3C406A296CB35CA0BD0D1917DFF42A4848AB3BC28A2A28044C719CCAAC45C513CA007653BC854DBDB79181157AA17220153CA3563B21BE77ACEAE06BCD02531FF5B7F5453DB0119364DC4E97AC7A495287815B5EB512129643AAC4F42B3AF35AFC1207DB0A3194302FEF097BAE37BF382C154E78154B3407BBD90BB2143BC285AF1EA0B1B4FBCD3EA373A077C6107AC2800C89F20544CB7A83BAF26EF19367724B1C989C39BCB4337DEABF7D531FE2B3327F4AB0F6457C5F3869590C49664923993CB2B0103B8E8A41CC5793ACD192A047972978A2EA1B9E354CB135F2AD8928574B2C14FBC1A4C02715292C9052B69AB2A8329C02938BFA0994C209F816A24EB13F4365AF2D20240EF66F9BF6B39D54AB5D350C7CB3CD6F645379815AA3028232BC89BB89BFA2C62E351A3C6401B7B384EC61A83F9056F3665E523A0C28D48E778B0314C1EC2A83EE9805D0 +sk = 46F47850E2B9AA4A6D209125BE58806002C278A6295DA7A4FFE85551529F17D83B358B243F2A622F353EB6138CC6380F8AD3340D7575E865A6CFD34BF473A3DA8B9FC961CD921452D09B3209D041D6612576C573B08422715160B891A3370268468078F5464D7E5B84B3A3793F0C7CB2A0A13DF37B9763CFBF054C768B1E65A00E8366B406251F812C5D428853D0E00F7BD58A8E348275461C1336C2AC6A39783A35D849AA9A847F37F50BE0B95F617BC7ADB28C0506C16EA3CE89AAA28A9252F0E228D0FCA732289D05D9395133A82D8CB76DB2023924273B39CB52B5A846F338B96C5B6F3ACB41C7265A0C5B13094231F05943D58875BA7C2A6889F16107D325AD1B810A0B3C9E8928169D440194BBB90F771796856F9878158A432EFF742FBFD5ACAF59521E361F448C0BEBD805A1B4435D0761D0448D83E1201A506A0B0A4980172D05E88D7D87B42054680CDA74A386027AA4C3C5193FB1A893BEC2722D55AB9B840D99CC81408153B383345192649EB99825BB4B1957326C4791A2722951C0AB67472F4841C20C23926C3C331F24C360E81977C2791FF3171C2C489B68C923B65D8EE6BD2D510E6AE97FB771BAB401BC1A42935F38A0FD43AE2F8A24D8FC3F6E15C2C6BC800B73CCD8E91C592452484B44E6B2A624881064526182950349C78C7D58180B1676B5191EB6065C50596232B9566E4B8F0635A7D71927F8EB8572E62D57996DDF66CFED2147DC3451E95C034D6B9145BC0D30C915D66B1CCE367406212F8BB40755091C9CB0306A490EF5336E21F82C1B7B6CCC8980DA28A348815112F00C57362EB163A36E016D60F020BD12B6796C9A88A8AF4E833FC4585652E76F2FF77DEED799757C7F64E07EE6E6A300DD1CBBC840AF561746D279BEAA71DEA5318AA3CB3C4C63C4A91E0FB60D6DD6ABF1FB24D1B078DE9413F1B0BFD8916577C4CC9E0B0C332625A5FB705E94BABBE0659E022234586529A194012A6E9E7650C504C380436E1DF83E5C5C9E22F79F394BC0F22A0ACF114B90829B43112FDD617089C8B9D872B70D7027D74402B65058347B56074BA33FB91998E5A559D46622F5423808C8236317767A32E4772AE66CA472EC7828D682D045835EBC5E0089B0FF955DCFB9605214A3E5087F7EE57D5369ABCFF1BE00C7BBC5B5B25A0C1D853424123C98FB330318432D324BBC7330342224BAFF909849D65E1D08A77E07D07CF16CE6F64FC71374EEFB66BF9C742E518F2E30C480F82652B81C4CE7BF42593B990980D94062F96A7178258F31E2B90E86241C04B7B44057BF4700A040B6C0B08E4E8A6BF1CB1EEF738F51CA9BEB9C19B94B1CC623704A6C2455009F48B4CDD0F4A5D7F06320457670DB92C7A4371743593600022DA4600C56296D336A52E98888818CA10282D4767010A7ABDF81BB6752048B5B163DA385D7C5CB134108ECB03398500C1612A1BD563B21A0BC7B94C9719A75BF3B3E02143BF04A7E3D9B0070C4B449CB9594A1A8BBF871E595178BBCB611B466A8677905443ABFA1601A9664C5F54F36DCC1DDF35381F586B4AA4566C02BE610186DF8493A30479F4C72AAF049A6666E806B13FD77C3B738721F81218B48984EF374BABC0156F94E9EB92FFF176A27197EB4AB0171211DC7FA954C652698C50105B5C2E9F7A2A887BFB40880F8624E1FC67B1B43A51139AC6025B9EEB60925D424BB82C58B4B617618C43C99B07FB14E5B86538D29700E1CCB4F53A52BDA2EF566B20D8CCE1D7616DC81398D14ABD03964940C794E6100DA994D5BC0BCF28B04A8971214E7AB9285515EF09A7B486ECAE5C84655C9EE15255B715C3B784D9C243993171C604A3E29450728396E7572228610BB9AC04B06577B3636C137A24E2139B48DB005553152C6B040CF0B2408248675EB90AFB66D6105537A316C7C989746F43C3B284342E2CDB5F2183A16CE71AB39C67797112B0B907C00F6A47F17DB08D924826D526CF88234A25676D82449F93B2859076978860E499A0DE134A936E35F06A7802456008C23970818318AA2B55A1762A9394DDA7A49EBB4B38469410F5945DBA2801AC25BA39A2DF819B0DB194B53C4247FA5065FF99F73E71D51C22F51FC262DD2809EBCC6879B0D90004DA5BA7CC9462F6C822AC8FAC8AB95B769A465CD743BA2BABB26958AB9C3494D329A0C736C28A9CF84F5C90C5A0594485A9B339212D01BF6910105D44109B09BD063B4F2F3B903C94DC650812AE5CC87527754D476FFA82F34F39B5462006029875712CFB1DA648DABACE5AA1590B5CCEA82C20E74795C71BB70826EF4D0BBA580A447693A42D8AF3256C64CE327B370CE576B6343F2BF8FECC76E1434D5E448AA8A3B326584DDC56496704BE54108F8572170C2BC39680598017641422BB81645959B8092E82A54C68AFF60B78BE78107E7BCACB241B09913461579B52AAC5C6C8627CC033BE2273580A523D4CB7979CB65D7056643856BE187DDAC112799559A87168AA96A18089A6C547E87DA949C62B8EA876AA0192AF409BFBC354F05DC08FED46904A2688FBA59FB71B83031A19BC8A6350BBA93552BE0C01B73C89964563FE588A5B76971DACBA69868B588BB2F9076532D6A8FB4316DDA4C85C2945A2A29B6EAD3900E50ABEF2B44375AC36BCB0E028A20CCE58353C827F1D53A9A0510E3827CBD1383A6D18C0D22C374E2B6061C2197A6CB094CA9DCB42F0418C24A9CB893C45423447CD5EABB0B9B410C9144013543E5C3BAD525377CE8073D4A5F4A22BB24874B7E21523CCA731265572B487E3B42AE581A617437348C290F00AD09460AA0C7B6A1A53128E4E01B3C406A296CB35CA0BD0D1917DFF42A4848AB3BC28A2A28044C719CCAAC45C513CA007653BC854DBDB79181157AA17220153CA3563B21BE77ACEAE06BCD02531FF5B7F5453DB0119364DC4E97AC7A495287815B5EB512129643AAC4F42B3AF35AFC1207DB0A3194302FEF097BAE37BF382C154E78154B3407BBD90BB2143BC285AF1EA0B1B4FBCD3EA373A077C6107AC2800C89F20544CB7A83BAF26EF19367724B1C989C39BCB4337DEABF7D531FE2B3327F4AB0F6457C5F3869590C49664923993CB2B0103B8E8A41CC5793ACD192A047972978A2EA1B9E354CB135F2AD8928574B2C14FBC1A4C02715292C9052B69AB2A8329C02938BFA0994C209F816A24EB13F4365AF2D20240EF66F9BF6B39D54AB5D350C7CB3CD6F645379815AA3028232BC89BB89BFA2C62E351A3C6401B7B384EC61A83F9056F3665E523A0C28D48E778B0314C1EC2A83EE9805D010E01965F9C196D2F5F90CE3CE8F552F8A0D76BA8F5345365392FEBC50560012A2985C1C4D203778597947D710DEC806E36B0CD949FE460EF141213BFC525E5B +ct = A94180C718B23E998B15D6104564B5E20E1D102DA4EFAD7A9740C473EF19F3DB7B226847DE6CB72BE56BEEE3E1BD44D0AFE0A4B55498B4475D8D936D441566CC182E0264F93A6024CF478E3658CD02DAC2C21CB6DE61F8EE7983FB6D79CEE0CC5B134E6887B4C4F79C635533A19BC8819BA2A56715825BA29836CBFC51479CB2C2EF8B0B50332DDB523008F6AD3B5EBA02C767ADAAB5D930760EB496D4C3EDD90BBB24B9CE0DC76013791565D368641F2B8F25A8660810F48E3A12F65BDAD160F3605E2D573844432509E598B3FEE53FDD4A9B83C1B187B66F5E9F2111062E74A3A7E006D638E3DD4990947E0AD370B0F29E183A7FE376C00D8A0713B02D7E1CD8132B7AFAA3FADBF7CEA991B3D9A96EF80A75010C40FA3A31153F15E23446A9491304170E2432112B84F86714A9CAC0F8B60391734EE6A94EF6DEFD30A02079DCD29D938387669A0A3893597AE4F036E1D7020F132B1AF3C8F135033D224CAA5F2791D9943C067257389DCBDFE8544981D6C1C3D5DAD7FD953372FC8910A16BCE4865DEFBDB413CEB80F13374C9D83B54B201C7F4345C97B51D22B33DBFAE34535D9F7F2AECA05D2066B2E9CA9F3C4F7D3DF5FCD1B1153B35418B7C7BC318A9E0810E2328065317F50D5239088AB28724642428CFDDD933032A72D95CAAB610AFA65C968E5381BDF0C7892D3E0696CB75BF1ABE5A14ACEE27CB73CABC5BB23A1AD12EF4D4E917EC4E13B736D1DD50C68B7AB98D8CB2E1EF75E3C1AD1DB7355B484B6AE44B5B7F963B772ABBC5B0ACF47D158853F65CEB9C8829B70481F6D531F59703F7233205806A91061E45FDF6B9EE5546CEBF701CF54BC0805FECDF48804E95956AB9041898AA623FF5C6D3D6F45EC370680F43F138FB6E36018B5D92858A29A17621D9B844F513AF8C021CAFE10687B180D7CBD9FE1B0880B6857947C55C40488F3046E76FC8A00BC4F9DA531A036AB71174AFEF52B3FB4686FA471C34DDFA2F1740A88BE223B536C4325B9CAE46E0B0479CD4CDFA0FBF05F0718052AE62486461D423E4AB819114110FC48A676BB83F3CBEEAAA474C4066CA54DE523DBABBB29DDC39BE50898077649925042F28D15C4C95BB6E745E5367242DC7650E45DD9AD2A5769930099BA2C0F20994D304EEACF8FB3C86EFBA0036D82C8E9ABB01C1F3260EF78D7AFE632261B0012EB612F8A98950018FB12AF3AA0524FAA597DB80873D2FBFED5637098CECD7B2CE5C32A51AC967F277470FEC875E7C00B895AF511D17731519439498A51940733A891E8A2DB137B06E425BB07D0D9D84A6FA70E26F09D61C8800AB74357AECA7BB223F324B9E18A2EB4C0AA1D996543AACE1882726BE7283C0220DC74EC51B6CB82755FA14AA487563053C773A6BAB1547265FDBF4DD4C5738271B410031128A23D2E25289758F4F1C0AEA20C2D30AD81DAAA919B30E268B1A44072A66B0846A436B72BB9FB2A8ED78B551257030DFE5C13B116B8EB577804CC0375872FD0622D96C6EEFB72BAF82B6429C8D7BB0D0098C6D +ss = DA6373247F33971B39D955418425EF1D1A233FAE7FB1985C0126F541AB8D58D7 + +count = 86 +seed = 1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35 +generateEntropy = 6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +encapEntropyPreHash = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +pk = 5C405485D51FB10CB0F150B9DB466C53E070F5849049D225047BC47AA15F630A6D62C5B179906EE6C067FA3384A4C22748F984EB31AB4CD69083DA31A5B45F586560371BC99113C44D05828FA7687AA649B261BEB0EB4EEBCB8548139BBD6A0A844CA1E4E59F3D7C4372EA8632B278A7E68B59032012C5518A8021BD5367557077C9C1B4A50944EA1A834BB61004B2CBA7F6401A57839A3CB85B326449A25457851B4A2BBA2E2187F040745FB608079C8B59D2B191813D51C5C3F329B1F5E40771E1B33F63CA400555CE5351CFFCA2DDD268D7855151618587C8B037E7CA290467E4A7C2C38290B84AB8DC4A839F57102DD559114092165B13B130B41BEA2F857C84AE45C1734375A3EA91021014D29AC58F12BD5A44B91CE986E094A66089479DCAC23A6275B864195DF24F2D4A97F1B26B508C3A5BB89B9F0A913867C1294C252D5022D9FC60FFEB3FF3C29B2DD1AA97F22271C5C8E749CACEA39F2C637FF4A235882747CECA1D95E093966462AD401510EC112026BF0FBC106270988B2C35CC7269DA693A7D67052F9156D30C916AD6552EACAA3AC2396BC56668686EA8A1578E46658A71B4B7365AE56A263C783973C1B63100B1AFF4C3FEB64856A781334C6E83519E541511B4D581914C697FF31239DAC56662A145316AC4D14E522480782C4EC52B1A2B8A85F657217ED11426A2A606C01C17171FD10824C07042B189225D40919AAC5CBE05B031689B1EA61041F6091D961A8910A205E62FF21909C6B4095B270D87C9727A2B611118C84AAC033EA9CAB5F40EFAD6117F2160A56505FD775D3F415AAE9271A9B2B1FD1964EDFB772A9C4875F06826A49C26E93F0B1846E006468DE71B98AC6FC0F81AB146236739C9A7B6C13952089D621936E8B265B50DD4016547A2ABD52339DAA0B459D265558A1D9B61C73E49346396B6155195C9C3A437614E68E23143F09FD28857AAEA50AA808600F5C5CA33C5963CC00C4B1C1CE2609486AC4F1B2DDB7B06ACB62398A32320F315DABCAF5D4A833E2A01A6E7C971CA15E40C459EF18DB8452AABE1584412B4C4DC52E6004CA56B5F48555041CC828A7A6DA77C435F05574E5C25EFC3C6057443EB77993C987CAC2363C3030D88E288F4D08966E624794078A39C53ECF273DF178CB022A5FB025A2687409A785CD6C019F5761B0A3087AE91844A69C2A89C1A00B1CAEC7C1F7A67425B87BE02D80B67CA6C7DC3B45BF425DFD33DC5A13E7531907ED6329593C333466D9628668B98422C985182F8C0952CBF5052225363398E516D23678B5320A9CCA38E21C6BE86822C4FCBB9094277BCE80992858C5498C6BCC57DB982C196B1A78C317975544FFDF33E57A30DD29A5CA4A22A918746FD9A84EE1008DB920432E39B6FF182C930243CF350C6F486832A807A36C8A9242A5C39140EAA7A45BACE0086A86FE36BE28ACEC756B5E9A47225638659B250C52B564751CE8C42C39BD1046D2B6CDA70B7951707B63073F0EB5EA3FC5229F816EBF4007CE97307C6607B4CA17CA30330570D4F39BF76998147060CC04B33D4B91294F85F4A717EF9C288E3741F70FA5823AB8329F56D9D0B05C996701A050A387362DB09427D5587E7751131953146EA3591818F0DDE74E33983C010419218B08822DA9C3C62EAE1F2284801B3E4 +sk = 8747252C693A0D6C06AB66071B13517E1C45ABB370D26ABA3FB31641A170B365C5F6235D1FD688D81C72716A3921420D228A7BD5A1C48FF445C47489B8116B7CA14D3EA78B20A7B5E579C5681187A2AA8FC900557501003FB9BEAD185BA9E7939F247BF1757EA66A4392095EA90239A3C67A8CA70186047D9A6B06B8887FAE01BA8E556319A003934C88DDEB05F9F3B4964A6545E8443F57383A2BCDAFD96C794B399296615BCB9C59F8703595709724B6A4BCAD06E116F4542C4322072E3C6713015B1339512419B4DAA8C87F5A8BFF481964A8AB8A101943230F9527A10A604DF6275E1EF18FE54A57D7544402134AB77802333897D4769AC23093F9B951D735B5623452C90270A0896ED3A81BF1191E451A4A67A4542556AF78F1690982360FF1BFCFF66386827DF93BCD894AC8C996BE6E0A29DE70CCD459B9DE46ACC9E8043BB82D01C40E5785845FF4B0DDB8184AFC5E52A72E899093669A9EB110A100A1159241BDD40612A9B1955B1752810764E7B68D89704A61442ADF68108AA229E406CD10B6527A39A6B46068685B5E802CC25614492DBB6E06BA2160E930733956E7B29AB9981D4B477CD4EAB880E56EB711B278F540AC204A996B32FD06B8BFCB7729660CF5125FE1626199F6285DA628FAF491DCE2CA3BF285902350D52C0649339F31EA3AB764B90701BD647194FB27383681C13470B8D5CCB61DD74C5F666FFEA7B0714C469C4803107235599C998349B5BE7AB9E9DC6F01E928593939270411EE2490F16C54BA672EE03B710978760B962319BAB3C2FC67CD9C2E9D4C153A8717826BC4C3D6C7444C051A61A06A2C87A1207A20754E9D7725B91077766871509CCC93F5A1FC1C20680263082801F6B81E8F319B92110F2DA22F0D8C251EE4531B127C44B378DA6A0D26F55DE3285190BA1357012E42521CD1855252147D1ABCB1582422F55091B5EAADE93194CFA0BE536343A282C4A948C355984CD20A7CA454BA034AC7355B02730107A71B3986FA01FAA38D17E07494FB510E5526F690BFB27294FBB963A0606E140A182A9A247029ABDFF6BD8E876EC92207312432CC2700EC4C6A4A7037C5B612EEB2099D54872A5884E28981D794C7855590F1F1464017C8724BC92E0B644DE92B5B80A573F641E4E65BD6F0396184086D6A5A50662F9CC6241FB7241D194B6D23AE6FA3C59FE60C81309FF7E39F93F72BCB0696EDC771A80CC5FFC74138AC9D01B95DEFE7258BC555E3E28CAB6A73372337EFA0B4AA0C7D13B312A7313F8B63426C6677407903822AA1ACF4ACF4A130C4C68DD4DC47DD061ED0A4969E5AB630BAA11FA0AA51133C6509C83E603425A385730AA0E07A2BAC0754358C812F483F5CA6BEF3105CCE4CC33532116C6493F19880F693581E08999BE24DB44B84970C8FA4F6784D50614CDC9E626A31966ACF81309EA6A730EB42011663CF10A90A9EC12F3FE133A7D02CFB95CECC6B52CC08571BD03E8315532B7C76C2040B60E9021A24734854B6A3D77CBFD087015410B7322AD5D9B04F651F895AB5BFC25F8CC9703BC67DC5EB5AEDE41682A17FEB1B4339335EFAA44A64E8B4EB0BBE17FB00875A06318C1E68C42E6CE0946A59C61700A72779765C405485D51FB10CB0F150B9DB466C53E070F5849049D225047BC47AA15F630A6D62C5B179906EE6C067FA3384A4C22748F984EB31AB4CD69083DA31A5B45F586560371BC99113C44D05828FA7687AA649B261BEB0EB4EEBCB8548139BBD6A0A844CA1E4E59F3D7C4372EA8632B278A7E68B59032012C5518A8021BD5367557077C9C1B4A50944EA1A834BB61004B2CBA7F6401A57839A3CB85B326449A25457851B4A2BBA2E2187F040745FB608079C8B59D2B191813D51C5C3F329B1F5E40771E1B33F63CA400555CE5351CFFCA2DDD268D7855151618587C8B037E7CA290467E4A7C2C38290B84AB8DC4A839F57102DD559114092165B13B130B41BEA2F857C84AE45C1734375A3EA91021014D29AC58F12BD5A44B91CE986E094A66089479DCAC23A6275B864195DF24F2D4A97F1B26B508C3A5BB89B9F0A913867C1294C252D5022D9FC60FFEB3FF3C29B2DD1AA97F22271C5C8E749CACEA39F2C637FF4A235882747CECA1D95E093966462AD401510EC112026BF0FBC106270988B2C35CC7269DA693A7D67052F9156D30C916AD6552EACAA3AC2396BC56668686EA8A1578E46658A71B4B7365AE56A263C783973C1B63100B1AFF4C3FEB64856A781334C6E83519E541511B4D581914C697FF31239DAC56662A145316AC4D14E522480782C4EC52B1A2B8A85F657217ED11426A2A606C01C17171FD10824C07042B189225D40919AAC5CBE05B031689B1EA61041F6091D961A8910A205E62FF21909C6B4095B270D87C9727A2B611118C84AAC033EA9CAB5F40EFAD6117F2160A56505FD775D3F415AAE9271A9B2B1FD1964EDFB772A9C4875F06826A49C26E93F0B1846E006468DE71B98AC6FC0F81AB146236739C9A7B6C13952089D621936E8B265B50DD4016547A2ABD52339DAA0B459D265558A1D9B61C73E49346396B6155195C9C3A437614E68E23143F09FD28857AAEA50AA808600F5C5CA33C5963CC00C4B1C1CE2609486AC4F1B2DDB7B06ACB62398A32320F315DABCAF5D4A833E2A01A6E7C971CA15E40C459EF18DB8452AABE1584412B4C4DC52E6004CA56B5F48555041CC828A7A6DA77C435F05574E5C25EFC3C6057443EB77993C987CAC2363C3030D88E288F4D08966E624794078A39C53ECF273DF178CB022A5FB025A2687409A785CD6C019F5761B0A3087AE91844A69C2A89C1A00B1CAEC7C1F7A67425B87BE02D80B67CA6C7DC3B45BF425DFD33DC5A13E7531907ED6329593C333466D9628668B98422C985182F8C0952CBF5052225363398E516D23678B5320A9CCA38E21C6BE86822C4FCBB9094277BCE80992858C5498C6BCC57DB982C196B1A78C317975544FFDF33E57A30DD29A5CA4A22A918746FD9A84EE1008DB920432E39B6FF182C930243CF350C6F486832A807A36C8A9242A5C39140EAA7A45BACE0086A86FE36BE28ACEC756B5E9A47225638659B250C52B564751CE8C42C39BD1046D2B6CDA70B7951707B63073F0EB5EA3FC5229F816EBF4007CE97307C6607B4CA17CA30330570D4F39BF76998147060CC04B33D4B91294F85F4A717EF9C288E3741F70FA5823AB8329F56D9D0B05C996701A050A387362DB09427D5587E7751131953146EA3591818F0DDE74E33983C010419218B08822DA9C3C62EAE1F2284801B3E47C3991FA7983D0DD6E7157CFB152538466E9D5C3998A2B8ED862162B91CA851CCE7683F8A03D3CF04E46970FF7D6A12494AE12558346DFC8FD9370BF944A0102 +ct = A4DB79E6DA55191F585544DD32928AC432171953F3A57EAF2FD786BF1641EF364CD03DCC519FE94C40AD5D3851A820B90C43EF631F15A48FEF9191281DDA67EF23C6AA3093B26C36A7B6F69A86DC1828498540AE4F6C1FB170387D62EAE9B73313D39D07E94A903BAF6DD09ED3BAF005A9E35C7C87CC6724B37BB80FA2153F150F9C811079D3D545BEF636476FDFCE30DC32561F41FDBA2EF7B4F21C58E1EBC033F5C457FDA302AE3D32FA0BCC4F3CB0897AF041C562D48AF1DA6C9EF4CCB651335A825394544BAF7D8914F0CE818E68D711CCF45B9873E108C48AD3876AE59DB02B553B6581B9A5BE72D31CA4033E4CBB767C1ED34D3356541A113D2CF60ED6BEBE3134F8C0A9BFE30C17E2F18FA8E308BBA726429282C7286D0904BF78925B09CD47973566DFCAAD7DB814A3500181EB93D438159358C075F4CDC270E14D74CBAD91A493F05AFD4C8AD851694676103FA00C156E5EE3CC4B9F3C6762E3E5D5AA4E245568BB730DE5C2E0E32EED4310D9FDFD30C68A67ACA0BB692BD5453BAF3056BB10E031CA15B342E6DA3D891FE40DC17CB6ADCF6B3B72943ADDE54D7B01A5BF3A129DE2846817D7C2D9054158D08117A69D5A7A0DB6ABA4286DA7D76E85AABEFD343BFEE54395B046AA35E3F7F5648C84B5C1B6610406FCEBBC01CE448BC8D533198BED851792582FB421C55C5FBC989983D978AA163CC88E01C12437CE22C58A6B5186DD0652417775500146236E12420DDB24054E607E11180A22687744226CEF0CC55D2CEB94E1C0675CE338F2537A3E60C126A91A81702DD3FE1FB7C2FB310571FA3DADC83DDC4B18B1AA5707E907142311FE4988196EC6B48814AD55A0EE7724BEAC278C7D68229B3F63357D81EF5FC16F2C7EE9E8A8E7FBF7FFF7B958F0592C5E1246C6AB95474DB7183FFD15CCD227DA5DD1A3DB842814AB5D4B515546BBEDACD42E4E9ABBEFA9416AD009BB072B5D691C1ADE296BE26F87FBCD82EDA2C93AE73AD7171D1EF1840F26014D8F152A720C47E24F15209E2A478DD7DB0EDDE040403A0655804720F8643B86F37776A2F7DC6B478D77A87EAC0194693787B6439F4B045732866237A8A2EBF9934070737B89DD2AF08C59BA182EB239FCDC476495AC756FAA7451C719156C1DBE099FA7BAA32C16156F4209C9F2C66544CC54DB33BBE0EDAD660CBC13E69F4D808BA98A7854CEFFBB2CD50A5B727762038A216B8B5E85DD01E138EDF154DCE1DE6E832374F0A0614390F76D1E658277FB909C1E95B4E81A9D6852DAA5368281AB21799C6898C07992BF5F7EED402522449461394C87AF555FADF1932DAB0CAB6CC80AEA73340181E91FD99EEB65A013B42F577D9436C75A7166BBF845EDE506AF88E6B1F915EF43043627CA208435E805D5588F4265346A7DAA1C9EFA72592FC999E84E49E6E0872AEBACAE9ED89BCF98CB40466AD61FEEC016E629527923430C13E8CA8C009EBA5D307D29BFAA6E1E6F56DED592573B75FEFDA3955317126A9B2869608C32701FF0F62447D1369765 +ss = 037452D74A46B60F415DAD3498ADBAC608DCABE4EDC7070A358E7325C72CE76F + +count = 87 +seed = AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C +generateEntropy = e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +encapEntropyPreHash = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +pk = 7E395F02D56D41B5C5889BB6B2F149425A2AC8AA06FF23A82841887DE199B56C91846392A026B50E87453F44588EE6AD4A443F54D25ECAE39AAF286EFB47A760DA01B6C13FA178811C47A0DFB14110FC6482543E8A3A52ABEC3A8D7176AA2868B2D46CF68538C27514222A34371C25FE832184206E5ABB699D61426027A942581D0BAB075A367793C81B7FDC11E2F6772C8040D271BE5D07D00B330A6C874B46D26F51DB8F43F22DFCD72613F8C22D15C28A2B384051142C148B07F7362EEA4771959B635A215B1351F650342D2A071ACB16DD8AB50539096F295E44173BCAC20F3CB271A8041E3008A742057EF2FB2D78F8A3A3C252F6D38D8E85BD57A75D45AB4DC21B8033992CAA623866E8989F98560DE33004D3409F233020899340B2591E1A4A0223A79E20B4B85C632CE7609C0C45A0246251468C1B6C20716315A54520C5718F4C5C7066331FC7E953ED91AA5F3B92E69617B29C256657124242AE8305780CC0CAF00C92896929A1648BE9B47F86F144A3B12D9DD51F347875E6DA935F0BD043ABBFDC7B85066A7836D442872C56FDD41D9A3A01D9AC6A12531079F74B273CA129F36A7AE463F6464436E50FA70CBC2756BD25234893B50A2898345E588B819C0955E9C50072517D58B0A3E4BFC9832B727C7F2FA924AC672D4D104A8F3AB81200A624C61EB6AA7B4553AEB2084360F1C03E443AB99ACB63AC699443A638BA9B8013C7ACA95ACEBC9ED6B12E8BE5A6CCC74EFEA7CEFC7A0F5EE18857250D08F03CD94CB4C455141D7AA2FBFCBE3EB896C2404BFA3580BC63B73265581D87618B206CAA9468C65BB1863B18F560413D1B1D392259F37C00F7D89124C56913483513006FEFF89092F218FDCBB8B118B206B64F2DE52BE0B553665C32831BB4CBA3762991716BE65E6A222B30A0A5CB246207352732BC3C8AD7A2C3243C62424AF222A922787F7FE44DF05299DA1105F9EBB0C5AA18B6C6C73F43390AF9C2454442110AAB4AA629C8F300DD38318C43A25D269885F970DDD8AC1E5918E59A3D53DC8A44873EEA97C31F34108B893B634284D69153779230C28B2A1636B6B839A4D91B7E23F0414B111F2E7C1B3ED58613120FEC37C78308587494233313950D82CE946778E044C3D245A19C29B09A80C3B55416A811AF33032A0068C7A4767F05E9AAC3E8B99B967F88D5281A38B072B8C4E194794C40BCD5366714525E846048E55C008CB48B5EA0C61655B8819B08FBB88337E20D63003F2453462598CA66181ACE033C707C1AE9760CED165596B2B163E54934540C4F7097BDF14D29EA850B95BE6FD42973436144270549A81B5F73192C2C6AC2474686A9A3EE556B6F26A9039866176026E25A60B5864E963850CDC8219D21859B5C5C3714434EA53BB16786DDE8036F317C430B3BDB025E6B62C097340F1E961B90E0C5182183DE05B293A05B58DCC251D8A2911C6E71A635F5179D06D93D33D8CB332C8B835C0E2973261BDAA43E414153118B66C641F834C949E77FCDBCB59DC27089138A2E07A5B40C7666794FD8E6B97685BC4A3C2A65912C35F50A278BBAD765C8C775BACF28181D61530E54AE7FDCAA2681A01BF51C0D7A033D6B005893B98DA86005381F1C6E600B1787BBBC13A01210C0764A4A2578D4BF90A24704178F06A4E4B110F5 +sk = A32B081D2579D7737A984126B05465963AC3D0FC3D471B94E30B242699AE3EE7A305D187D9371AF3568D7BBABDC30CA69BE166AAA07C67799DCE7345B2024EE41C5A6F35733CD12EFA19256DDB74440829C6B52AAA25B258BAC8D950CCDEA410535BB3A44A46EBC44F5772CDAD96596980C32A14916CF5C4A2FA8538491F7EEA270543ABC467344FF098EDB4762F658B6B26431B9863CFA7546C1489A25BC9061B8CA0165528241B4BC173BF17B4E7873A5081016A1C55E4BB1E7F71B849274D03E05E866656C126485979CE9660AFDF3622E3051F76D02243E660A5A78C663880A7F9765DF45410926A86ACC7962878B4037CF2960B06F072367B476EB24B8C57924A9C699815BBEB0BB10B2A88B0C63F0171C759D59CEA91C5C043A41A8155E462325893685F18C5458A0AC3E5BF2C696C8F07727C090E1D3502D075A706551C54A00A710027C52CBD83FB9DBD7567ACA2B6EB809C00838E56B209E0C5AAD2E6235E2C157D3659D906452F4A8C60B26F838A51F6789E42C00580E4595A5C0A12B796CB44240A4724C298ABFF1332BB0970A3EC475A434EC4DC2A4AA92C42E22035A4499C66827C882B542A8FB22B6B6054984FDCBD6A637583145010D89A4654BF0BC0A0C3B86788459B659A539833629C1B585A13134D766C9E8003282683AAC1486A934EDD3A7511319A7952B5EB7C5947B69AB5C904B2481A7709C95BCA352DF45E8BB87775A9CB566581C3777E7B975C629C89063C8F0E982A24D344EE8A22221A02C6538154217C453AC0ECD4BB1F820BAAB94D920765C4AC15972AA79BA974F3B5055EFA7FE5BCB454F7AE70E1C017322A20C73EBF278054060687C6301E13B52952459C56BC8D8795044302FC9123921143EC2C73278939826682126B65C7D9BAC044AE6CC7CA40F92C8FF28470E41D51895ADB53AE30216B1ABA552FCC14AB277A872029F3DC8D56794D842BA06770808F1C097787973B0A14280C5FBCC45C102C23821A07EEA6C3ABB4B52AE116F4B38E4A50CFB849177766495463197BCA3197B53AB72B172C163003C9AB89721EFF925F56B59373F5ABD1430B0731419A12BA80641628D78D712BBB74579C0A18A4CB2AA6EDD76FD7605FBF8214A00AA44E486810F3AC6E36345431C23F247F251112CB8A6C76444B1A5277B7C68AFD2C49D4A81FC5069B9A004CDF0587A4A193D243BC5F16357E1B1F280706B4C16F9D8B3B6A5815A1597C49076589D5303A5C89AD320CF6042F2F819CDFF04B850870E807B4F2B6BF99AA8F3FD16E95B3BEDF247CDBDAB048586116DB7A4530C360BB240FB2964FD41A5128CEE9FA6AD434B536345A49BC758D849260B78CD9F3B3E8461CBE906E93B209742C0ABEC1C1BBA9BAA05A8FD05637D26548F48512F5477B93D0BD54F6674158B2F6EA0488191EB023A641B175CC689A2F326214793228138D6DA03BFE4466DC962FD2A7C57102CF3F96CF3A6619D2F613CA063A35F4515C0473140B8EC3C53B1D9974021616BCA2459BC31502DAAFC861990C1B97EA1AB5AE018EAD781A67A075CC4924F9EA364BEC33ED167637F0A643C3A810914A49366AF69B3CC25938E77422832B7078C6BE562513EE3648758515E3C04F7E395F02D56D41B5C5889BB6B2F149425A2AC8AA06FF23A82841887DE199B56C91846392A026B50E87453F44588EE6AD4A443F54D25ECAE39AAF286EFB47A760DA01B6C13FA178811C47A0DFB14110FC6482543E8A3A52ABEC3A8D7176AA2868B2D46CF68538C27514222A34371C25FE832184206E5ABB699D61426027A942581D0BAB075A367793C81B7FDC11E2F6772C8040D271BE5D07D00B330A6C874B46D26F51DB8F43F22DFCD72613F8C22D15C28A2B384051142C148B07F7362EEA4771959B635A215B1351F650342D2A071ACB16DD8AB50539096F295E44173BCAC20F3CB271A8041E3008A742057EF2FB2D78F8A3A3C252F6D38D8E85BD57A75D45AB4DC21B8033992CAA623866E8989F98560DE33004D3409F233020899340B2591E1A4A0223A79E20B4B85C632CE7609C0C45A0246251468C1B6C20716315A54520C5718F4C5C7066331FC7E953ED91AA5F3B92E69617B29C256657124242AE8305780CC0CAF00C92896929A1648BE9B47F86F144A3B12D9DD51F347875E6DA935F0BD043ABBFDC7B85066A7836D442872C56FDD41D9A3A01D9AC6A12531079F74B273CA129F36A7AE463F6464436E50FA70CBC2756BD25234893B50A2898345E588B819C0955E9C50072517D58B0A3E4BFC9832B727C7F2FA924AC672D4D104A8F3AB81200A624C61EB6AA7B4553AEB2084360F1C03E443AB99ACB63AC699443A638BA9B8013C7ACA95ACEBC9ED6B12E8BE5A6CCC74EFEA7CEFC7A0F5EE18857250D08F03CD94CB4C455141D7AA2FBFCBE3EB896C2404BFA3580BC63B73265581D87618B206CAA9468C65BB1863B18F560413D1B1D392259F37C00F7D89124C56913483513006FEFF89092F218FDCBB8B118B206B64F2DE52BE0B553665C32831BB4CBA3762991716BE65E6A222B30A0A5CB246207352732BC3C8AD7A2C3243C62424AF222A922787F7FE44DF05299DA1105F9EBB0C5AA18B6C6C73F43390AF9C2454442110AAB4AA629C8F300DD38318C43A25D269885F970DDD8AC1E5918E59A3D53DC8A44873EEA97C31F34108B893B634284D69153779230C28B2A1636B6B839A4D91B7E23F0414B111F2E7C1B3ED58613120FEC37C78308587494233313950D82CE946778E044C3D245A19C29B09A80C3B55416A811AF33032A0068C7A4767F05E9AAC3E8B99B967F88D5281A38B072B8C4E194794C40BCD5366714525E846048E55C008CB48B5EA0C61655B8819B08FBB88337E20D63003F2453462598CA66181ACE033C707C1AE9760CED165596B2B163E54934540C4F7097BDF14D29EA850B95BE6FD42973436144270549A81B5F73192C2C6AC2474686A9A3EE556B6F26A9039866176026E25A60B5864E963850CDC8219D21859B5C5C3714434EA53BB16786DDE8036F317C430B3BDB025E6B62C097340F1E961B90E0C5182183DE05B293A05B58DCC251D8A2911C6E71A635F5179D06D93D33D8CB332C8B835C0E2973261BDAA43E414153118B66C641F834C949E77FCDBCB59DC27089138A2E07A5B40C7666794FD8E6B97685BC4A3C2A65912C35F50A278BBAD765C8C775BACF28181D61530E54AE7FDCAA2681A01BF51C0D7A033D6B005893B98DA86005381F1C6E600B1787BBBC13A01210C0764A4A2578D4BF90A24704178F06A4E4B110F58AACD8940FF6FC27F175342BE74D48075F8AE9320CAE20A41C879C27C1BF815D7F7054814869CF7625E45647BC1547AFF288DBB90699B2AD84893F3B755D9722 +ct = 9E0D9479CC0C6672A85DFCAF8C259CFA1CF68A93825FCAD76CBCE06FA3E40EFC821CA036B349FE50EA23E7E22E1C9CD7F8A930F2DC42F867E33884D0CCAABE685E7A7516CED70CAAE58FF50151AD1932F41AF9BDE629F2E96B3CBB7592B178699179E9CA85DF7FD2BBCA8DE9F30AFBE3F8724D77042DCFB19C31CF239BEDF529482BC947E85334ED7C541B2CCF368D2EFEAE1582A0622AA52C24905EC634D11BA0D1B20A946F2E571DB7F867E8EC9E3DEEB544C77D20CFFF9A0A44CDFDC42CD972A01AA8822E0BC728A66EBC0038A7ED1DD7BEC0E0E66CEC422385E0DFE33657EED638341F08BCD32C6BE72EAC5A378BCD02ADEA563734105C7EA803ED2D6260993182EECA13A4A3C999A209E78E4D64ED1E4D7BBBF91A72F02F760B654895C6398F3DD7D270D28133D66C13E899B8EC69A70F5983B539F975EF2294651305DCA09ED622CF151E337A7027145C9B3AF2849ADA810A96D391DC6F4FBDC1745DD30BD358EA3507A55F2E3C19A7F27D212397148C52698B59EB1477F8C6CA3FA829DF3447FFF20F6AB7F5EC445124F29C5F7B79CBAB1B1D23E8EC69EDE923AA3E734B9C999337014E813BC9E310C6850901993133F11019C95E1BD421896E3D2460E61DA9A6A64C7EBF0376395F509AFDB8460420F26ECD066F33EF121E41DFBE769BE03E25716D7F347D9E9BC0BC65A579F5508BD0562B9AAFB98A9B2E5986057632CB409FF5C10FC3D40CB5582231E5BBB4BE2871B8EAD348C1B9D9E81B876D70D03B9DDDAE0AF4DD5CC6F898817753B35EFB191004229B0754E69C9428AACA4DAAC582E1DA39B5983A5A4DE38998D26197A4171F5D6C28B90428522F50FC212A923E90D1E2005348A5E47E6E6F6D005788D2B455A3E35349AFB822AB5F4F1B9F696E0B186DD2B66A9236179763C639DF4CB6D4FF80D3B9942421D11DA771B184EDE6AC47F74A9250B7AE35B4BE975211A9E12972871F702216995DBE6E39688EAAE21EEA262AA89EAA8A8434120FA4252EAD0BA0FFC4F53EC1AB745A171A0F73A60D84B023A4C4E58F173F0C3455C1B056988897C2DA23D6CAAC0DE7A36334E5AEA093C5D6485CCF06F736CCB18DCDBE853FE6B9441545DFC3535F16D936ADC69B9D2BA08C8CC6DAD333190788EC3541E4C19B38D4319C0038F5BC41D4574141F819FF48385F45AA0DD7F6D5CD5E70E05D3A4366F9878E74BACEE5638B3AF0521A50399043C856E9F3E4ED2951BFD758662C82F8AC8325814349110D696B84ACC146AB30C00484B241FDF4BE8D179F6C8B618F8FB35340AC61FB9E221DC9226A1C59896389B3E24FD844197550016A53C5CF67D7A9F8FBA80B7E61B4E39D36CCD32C7EE8948820810811ADA941BE1EFF722EB83CC69B42C396F3AB0BAD3118C708C51B73D41C9C1DA494C0998C183AC5E592A9E0663753584C0364450847D906F5A261652BE33BC0CD359A732B9D1696E245FF04252635540996A57D8A625D37DE41A80EE1D51770777E709E673E31C83C739E2173381F4BA99D8E7FBD6D9D31 +ss = 2CFCF5FA2B4C0AAA85C6069616E19E6715FEC913592D6B8F57EBA9CB4E3B162A + +count = 88 +seed = CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3 +generateEntropy = e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +encapEntropyPreHash = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +pk = B5D6022EF207E7629736D614527619E33CB92600A1E39A20B25A5B16EB0EC1070E5D566B28449BFB38936F44721ED428CED5768EE647A771B7D76A30C7E5563B515F5AA89FFE994CFFD9277B0695049C355267B3A07C61F3C5A2C0D4AB8DF76129C19F44F762B51BC0374A43E6F6C1155901B2430B2B77AFC9BA4E14D3658607387DBC2D12B99EC0C0B0C2721AF298A6EBC92A7E6B97BC460674931E21F68377C8303B24CAE8D5AB720C79C4399414A514254603B565397857A7078B36E24A262CF9070A92C034C76614D5AB455B60B3B3388500946677195CD587942342A6FC91BEF144EA412ECE186A422B85A213C43FD0C361AA00698458F5C5370C6C553A9C238201754E2B2E2785BB03053E0B414E472087A0276BF2D805CF477378CA34D8F01C21B433F33B49A8B9BCF762451460558FB9C3CD071E654C250DF04B6541BAA278C1669BB49CA3AB4C78CC92D0137A2864BAE0C904E23AA28395EDCB435D9C1CF742562D603BC61C521145CA16F69192B137EE372F04402527BC557B754E187355A388410751267561A6B1F59E04190EBC604FF64A2B08B244B57ABE84F18938C5A9ECDC972191BBA33915C653A84B1A970AAC7343AC98BDB7BB877A3170E8B1E8693FA5089F421281B5763865C584CFDA6AAD7482D00A0520D947FDDB173947865FE178F9800570D4B2B9529A42A514A8691C8531A271C18E5F84380C20CD9A992051D29B5BE76B2235B511514904E3B284E8854556334515162DB1B09894B18A3127982269509BBC5E8758015A5B810569E544BEF9398F7D195A50A958DD78BDA187CEA0B7B2BCA04E2CD90DB634A3D52B734E224C4C60BA3C8240D7B2755AE5892A09A0E7EA1B2424402C45A0AD59563AB97ED906A1A15B8C4412219203CE6826B91DD00AD602089EBC5163B416C0D02009A7A5440350A00A7B49309CE39BA26DF79ECE038F23F4B4300C01287A51F5FC619EBA04AB1B78E6396BB23C1CB86A0F3BB11F7D31A161A480B8F33734CC63EA7219D76BAB759B1AB3405CA61B535B893B1BF2B678849751A6A4F18923EF44470E543924D0C462D8A078782B80241334F547D2AA474D95B8709747162B228993BA15A0C4FBD8BD662A1A2F01CFA859CA723A011949823FBB55947B9C27C2BAD547B0E6D29665071B30F3C8C536651E6437C0D4A314AB38A8F707928C0C2B864A3A67397A936DBFB98FAB2C0935441B83157D05072891A43573882BE97686534C8BC7015AC267B75F0A79C6991CB6C96C735A4BEA90ACC9BB6BA1B12388F0821A074018909F76944D9295B5EFF73E70AC1B0E1644E3A40685305F8A0626B2F05969FBB4CAE07C61F6213159B3471654A88AB58EC3A648F2944625820F6592C67126BC085DCE216FA708089D4947AB911AC14C00E53782A01580FD967594E0B2B2A3272D590AA70C7A3F419ACCD33C1B1294D21242C739A3E8E577316C23EBD4B4C4D0577B2BBB12CCA71841B54C0B76729320BCE26DBFE5BBC017C92491762A6C938D4BB0099AAEA190813A3A78E5685D83975050D719D6B6A80AC313D3018D25B9054B5013F832C1353401E6CBA3FE527B8D2906871B79836CB35284725E733D8FB60E6A8410E5F61428A3CF9C25FD45802D5699F33205A71D6404704483BD2C82E92BA9457926A45BFA0985 +sk = D1F46E67CC5AEA63CA9EC413938661C2F8156CC79E10A64174774545B597E91A8CADB58DEB15B27F343073B071873870BF858B5FA3AC3689698DEB68C570406972210C2B9909571A12753448E00E6A0C165A101469828E8F60A16B55478C8899D9A38C1751BF220A60A999B0D2A429B375137DB8BC9B85AD5FCC073355AE630100F8FC68EBB8534135590CE22D0A0672AB54936C8665AAF476B50293A32135283777C375767B04547501A53B72A14D3C4DE4E001D16B2B2B598A22D784A3711C39DB183AC82CF895B242954B41C713BF464464917D6B608D21B67B3519A6DF161AD237359E262B95C6BE3A8522B9248346785FD0DB03CD083A21092F4D91AF156B12F4C9C77C11CC0B68ADBDB813BEB21289743758F8136661704D0C5CA9302A064040334017D47815B7C35363F5C730298670536C69C122CC91CDFD18783EFC4C39C8C29CB1023F1488A7469F1CFC1D7EBB3D1CEAADBA3B07310000BD89C043290ABED896E655CB1F43A1C7335AEE30044D9652E6D3B8E394218F63072C7050A2984032C45735A3AAA4108AED8B9A19C13B9BAC28CCB123D9987C45B91E89B7A949B5B4AD56ABE4237F21DBBC53AB651BD4B703069F82133C54ACC1AA415DF9961A4785337535869FB758CD04B798907E36197EA428C66AA516F602404E87341E154A0E09C881725CBF00761FD9645B658D97D21F33059E4A898DEB0C826D9057AC302663897D71567117FC4416C860775B026E51A52663711868777D542F1224B277EC005F2BBCFC0C84146591CB36CABA82692B010DE229797CAC57AEB64AF446A896527BED9B3E55539C0F6A0E9ECA5953890B95B0B282C3A4C46A44A8705A54A8806CCC0D3C736A20D34AAB118813651D85F12906958933D69679D0457A4817DC83B525CCC63E94C1BCB1C869CB3A0BC46D47084481C2563754AA8F44682B870ED04996CB8886F43B91AC8767AE12856CE5B85F55C8802830BA1BABF5797D0DA723EEC24616A195AC809371D93F89B19C874C840EE9C39E7370CA561B6E91552CEA47F1D09C9CF633E7CABC9EF85F89D01A29D9CFCA8143BB05C3015B3C6035AFDC45AC7B08B5406566BF864657BB3A82322793906462C03C20969F76C2C8C8EA2622A373C3E40164A77055EBAE05787965B60A861C09658C32D4194DCCD7AB1DF87826590890B1785F0385B965B5AB3B870A0088696A783B5C7A69962B86F789BD43588705315258C117C4313198AF42E2B7FE39894A86189FFC4E8C6BAC5E7A0F03D86D18089A6999972F309A6DEBB365781F64197165D259BDA98C7A920A9E790BDDC587E7C08040D649B8B08FBBF36D1904970354410BD77B87889668566CDF4A94E1C65B04D33C269C5152B049850857308BA1310283A976A31DB34722E97C97DA85D14372E14A8A95BB45C63670BD7712686200D451CAFE599AB0D3A183D2B0DF7B8FBF0995042BA0CE682EBA8B71DC6C0744262C75B7638B51B9C4931D4F7C842328486A799D06027CD5CC75E4B1B6816C2AD66B86ED047EF978184BD344C00AA1200432C5D142246B883B5B85AD5CC8F8FA994F4A790F3B6C201353F77AA9B7E9BB195375060282B7DA42ECD36295FA55F8B5CE94B812BC421BB5D6022EF207E7629736D614527619E33CB92600A1E39A20B25A5B16EB0EC1070E5D566B28449BFB38936F44721ED428CED5768EE647A771B7D76A30C7E5563B515F5AA89FFE994CFFD9277B0695049C355267B3A07C61F3C5A2C0D4AB8DF76129C19F44F762B51BC0374A43E6F6C1155901B2430B2B77AFC9BA4E14D3658607387DBC2D12B99EC0C0B0C2721AF298A6EBC92A7E6B97BC460674931E21F68377C8303B24CAE8D5AB720C79C4399414A514254603B565397857A7078B36E24A262CF9070A92C034C76614D5AB455B60B3B3388500946677195CD587942342A6FC91BEF144EA412ECE186A422B85A213C43FD0C361AA00698458F5C5370C6C553A9C238201754E2B2E2785BB03053E0B414E472087A0276BF2D805CF477378CA34D8F01C21B433F33B49A8B9BCF762451460558FB9C3CD071E654C250DF04B6541BAA278C1669BB49CA3AB4C78CC92D0137A2864BAE0C904E23AA28395EDCB435D9C1CF742562D603BC61C521145CA16F69192B137EE372F04402527BC557B754E187355A388410751267561A6B1F59E04190EBC604FF64A2B08B244B57ABE84F18938C5A9ECDC972191BBA33915C653A84B1A970AAC7343AC98BDB7BB877A3170E8B1E8693FA5089F421281B5763865C584CFDA6AAD7482D00A0520D947FDDB173947865FE178F9800570D4B2B9529A42A514A8691C8531A271C18E5F84380C20CD9A992051D29B5BE76B2235B511514904E3B284E8854556334515162DB1B09894B18A3127982269509BBC5E8758015A5B810569E544BEF9398F7D195A50A958DD78BDA187CEA0B7B2BCA04E2CD90DB634A3D52B734E224C4C60BA3C8240D7B2755AE5892A09A0E7EA1B2424402C45A0AD59563AB97ED906A1A15B8C4412219203CE6826B91DD00AD602089EBC5163B416C0D02009A7A5440350A00A7B49309CE39BA26DF79ECE038F23F4B4300C01287A51F5FC619EBA04AB1B78E6396BB23C1CB86A0F3BB11F7D31A161A480B8F33734CC63EA7219D76BAB759B1AB3405CA61B535B893B1BF2B678849751A6A4F18923EF44470E543924D0C462D8A078782B80241334F547D2AA474D95B8709747162B228993BA15A0C4FBD8BD662A1A2F01CFA859CA723A011949823FBB55947B9C27C2BAD547B0E6D29665071B30F3C8C536651E6437C0D4A314AB38A8F707928C0C2B864A3A67397A936DBFB98FAB2C0935441B83157D05072891A43573882BE97686534C8BC7015AC267B75F0A79C6991CB6C96C735A4BEA90ACC9BB6BA1B12388F0821A074018909F76944D9295B5EFF73E70AC1B0E1644E3A40685305F8A0626B2F05969FBB4CAE07C61F6213159B3471654A88AB58EC3A648F2944625820F6592C67126BC085DCE216FA708089D4947AB911AC14C00E53782A01580FD967594E0B2B2A3272D590AA70C7A3F419ACCD33C1B1294D21242C739A3E8E577316C23EBD4B4C4D0577B2BBB12CCA71841B54C0B76729320BCE26DBFE5BBC017C92491762A6C938D4BB0099AAEA190813A3A78E5685D83975050D719D6B6A80AC313D3018D25B9054B5013F832C1353401E6CBA3FE527B8D2906871B79836CB35284725E733D8FB60E6A8410E5F61428A3CF9C25FD45802D5699F33205A71D6404704483BD2C82E92BA9457926A45BFA0985149E0B6B49FE8ADBA1217C2C57C83F2B8C5F1D92F319E502B184A65869214F75D82C2F1BF2E6AEBDE5660FA73356982E12999D8FDAFBB3CB186341D0386DEAD0 +ct = ED5E2079428744F1871BCB3803773997FD3CBCE4D574D7489A7907C84716AD220EFF0C0CAEAF0F784D0A633F8724D0D70A4E40F115C49BF1C5133A3A99A5F6027BF2BA7BDBEF436D1D8E4A9DDA831DA76E127BFEE0CE3C0483646402F789205D95D406421FEFB2C5A62D60F4C47FFC7C3AEC46BE075BF05FB6336C78B098F47BD1B368F2E5C3DA0E1732F43E67C14C556EC3F7D977B70491A35B5539B8532CA72CAE5B5B8E9936A6FB3A565B535D33EEA5C1B35A5DA0F3BC589B109CD12280DB6557377E9BDDD74B06E583DA873B78F96F323DFEF547D6EAA42D4E450E7CD213DF9B598C9D2134DF772E64CF09D7084ECB4DC6FC079E6B736C2D4B2FDA87B9ED23000E8558C90F5CB9278FFBAC209702CB4F3228944067CAE55CECCCF609F126465754D1040BFF976623811E7A9A1CDCE5D9001074DC30935A06B6543FB5B1F4943961B6330FA0138604B1102DC0F0C643E409EB350E15CCD2EC73280C73DC513E30264EC961366EF741D9CED8F116FC73728AF6CEEC1B61D934124522068D063D5E9479335336C33B7D8EA0EAA02F2E20D0BA7663D863EC198C3D4DB75F0787EE80AFE016BA37F15949C2E7B84B72DC88419DB17F2E992D0E89C451200AA97372331E3A8237BA5AE4B527E33F724F45A8507C22532F064E6843512613D762E5DE7B0FC41670089C15D2F78F8EDDD1DF63D350AC99708459DD6B667E9244D6CD1D3DA09D9B0A194E2E169D5EBFBA9DFC84E62F678A3BF6F0D7BA198B8A1DFC9023AAAA06890FCC8ADE8769C0B049C3143DEC8282287C07C9244CB5CF4592E48CEC9FB6DB7B26C394EA09405194845588F8F29D872502C81D55D11DE84C1507C29F7EAB440D3D5F9D43806E2C3006E3A716F39D9B3DEEF5FB68D3F58121DD5DDD0FB2DF785B6C6A02FF04DC67DAB0928D8CCBB8E8D60F48214F4BB1BC770E940501491AF59F951740EA8C052BFCDD5F22082C46AA94A0E0279AACE1B3A8AA11EA177F8C193E1530B65033F0DA63E1396E5F094EE8D87E87B0738804FEDBA103C38B2422C712B48E1C9515FFBBB7808516C3985250FDF5727E4B3799D242977E9DBB35EAEA63971D2807EA18290CDA801A8654D3C6035FDCE27009368846D18EB5C80615512ACE4C93448552855C4901AC2D3867FBE4A1279CB9F63BAB8348E2128D8435A09DB1ABF5112E8D72BD5D3F77A93544021EC281494267EFD97CFD2B21881DDA6C49CDDD56BBE77E80BE8143C1F38FD47DE797F45A054DDDE6B3117F5D02F78222936D7D3B10135C0942812C049BCD5B257B7F6AC111C92E43C250536B85171EF4337E1F7B55CAE372C943226FC29A06B2AF4D2B69A6A68E91881D6781806510E565CA3776204ADED42213168C22E6D33F167CA62E552F057D8F0D3E0648FE810D5514C5BF4D78410CC41333313716CCD5F0B5540E9106F7D0813ECAD7D180AF071464088F6D233B606C495D78B372C16FE8F94CD574DE08C7369195620704682D7F1465D02D04A87CCBA9BC55BFBF2E4EC387B84AA70E8ECD6EBE7870 +ss = D3551ED0FD716E4887C82A6F24C5008BA80A9B5C3FC9E50F188EB224BE8102C8 + +count = 89 +seed = 96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0 +generateEntropy = 470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +encapEntropyPreHash = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +pk = C55170FE0945513748C0ECC9098A02E9D51E44ACC267272633645AD562816D479466B54D2150AFB682B4F32265F1F4BCED21CAF7C7980105B08056CC4192BFE0DA9AA5E00864B0A34712204CF6AE82DBAD360A7C840B4804826C39A59AE029056C1B2542B6A589EB47C14A70ACD1731BB0A4D657656915B91D696B2F92AFD82245945C7B77958A5B6A3B6CBB179AB83A0F32591B757E8B68368D6A5EE63490604AAE70EA7FB4619C91A455429A6B195214BD28BC717385D3CB8235991C05088C7939BF852125DAFC3BC368479165438092B530BB2B869246988B8F85425A2A523ED108C6D2F54358580944D64D801078A4B621F58012F9D8A17A92AB8AD43821E24E2F87BFA844ABD0C6B08650AB76D5397F2CB0060B31AF689FC8612249D46374848F496B360E733FC991809DA804DCBAB14030A4BD18CFE37B41CAD91A66A263437B7DDC2484ED55ACB16AB95A1A8C9345A898E89C37248F9768524C616BABD17A8DC7924F37345DCC32DE04273C5A0AC038A133BA01CE2481FFB57BA153826A7CC4123570293C82082B6A75FA05031CC7FDBB9031E10CA94AA283AA26EB3546F894B646B9A85AFC5DF3B513DB522EFB340287C64492AAAAC5FC25547129B56B9541EB0912222C2E60A11B9304692A749BB174CB47679CC294253B0F768A7872F698C23493FD908C9FF95F9275551B947BFE84780F86C1E0BC105F6CB7C9430369B58BBB07B3B0C87D8541618C76A43D52C98A08166E052B4487177AD222E6A002F7FA3F3601CF1EF0B4C02AB550D76447EAA695561118A46301B544B493C368B5B77AB17C5AF4543FA6A8C682A46AF39CA48046B1529684A53D0E492E1B8596F55334ADE15591DBC4B411537C88A5113458F187A6D77278675B0C85BB017416B6E9543FA1B924B631AC1DDC5556127548FA8CE0C90125139BDF13428E2C7805607A44251A5F289BE4E3A2C3C95C5B5CBF7C87B4A7D87A39A44B672BBE9AF8343DCB062EA3A039E949A7F151C8900484368F1CFA385BD13CF55685BFA4B959F8634ED7C437FC9C044B401683CC7482722C98583DE24EAD414C1833858BE987672C557DB87AEFE4CE2DB8A676D14083462DB35862DC0CAE95F88EC1F59426FA2E24E9CFC54813BE07C98F78A87B9703276B455E15474D7A283D5738D4B639369077E7790DEAD3336E1467C871A571080004A91162FCC31D2912646A9406902248FBBF28DAC4343B081C327743335B9EFA4B7FD13D5177064A5B6E8065B64D8C6580B47E6472C8F5139268145BA7A23A02F59ACF680692B20EC2DCC087A99BE036BF7E9C8C0DF15F168C508AE28E33D951740A9B0F0321E35CC01328B7BA860592B566CB369B21F51B7AE583D26652DA729F07F5B8D59CAEC65AAE42C7C9CBE73C68504F26670BEDC542FBDC67A95C9F2DA1A08E559797170EE63147A4688C8E101E5AAB48A4D1862506CFCD297C7EA61A9ED4A54FD3A28380292FC1570FA2AE43920B0E940675B60534425C69F35BBA714C88B3A6C323090B4C56B7F89963059F8CCB0994373FC1344412F694175C2EABEA110E035BEE6ABF546396D79472EEDA164BF49350F54C2E75754F502DE4A42721B37974A8266C49B57C6837B38A28CA489F02FA05307D7163B35BA6A4C5024B70BA27DB0DE8D64BB8B55C83BFDD24 +sk = 09D0009AA9878C697E2EAC9CEC9675A9570660346547D7AA8D4548E3AA917E238CBBC10C389445D15714B237566CB44132D6983C9610E779570B74482D5BA2742A1BB51C68142C1680B800F1938795367B6D8A56C32A0D77922C78116643530AAC01CFB2692F4BD6BBDE615A3335B397487DB8A1175A043719EA58D0DBA627D7C8511468B34442879CC227E6B39E084DBB68BE71CB988766114A80B1979118ECA08217540F032966688C99FEABA06D0A0A1E701DEAACBCFF9C2F2948A209AC8EE505C85FE0444B5C70D067100B63CBD6D98F9AAB73CB06C97FF31D7AA0CE188707DDC5C07D495B27957B369055650ABD5D9B9F75761770920DD0B574A5841C3BBC9F6F1AB0179C118C7A83B2934E950B3DC732C84264C66FCB0DF78975FCAB5FEABA4E6AF97131696A0CDA1CC9E2C40A266FBE6667C1ABB361F063103311A792B95CC525FF872BF3F394FFB48B30B334CA02BB32A901E3478F811505DA066DE6A5CABA425DF83C27565CA48B16BB2855A797A72DFD57615D5117B24374C2D306473A349521A8107790D268AC6B5813C593CB9E8621F8C68FD2E8082C491C95C5AC74C86DD37B0A4EA0CB66AA576AF50FBDB0A31235BDC9E8107F1859ACD2674FC72C6669A3465556F90269CC30B0A8F53563378EE016A7ABCB5460D5371B01754BD7373C2314E2A42D98636112F3CBE0638E513B38D4850AFD6A1D3D485308181FEBD88B75F532E4541965E0BC592885FD1C1B3108C33F74725850617B526AD4F2C8CECC19B0A0ADE15057C90AB086C26CB014BFF92988903BAFEFA3C4C96CCBCEF178F988A40D339DB324257DE69A119125C52A4147360B1274808299446EE768680170457ACEF18814559996FA96B418275E031199E0D578E86C946381C369AB839B1A75E9D6845C98AECA24253B3B0F00EC7E92CC6F6A40A4D8B04900CA3E78CC7A5C51886E0901A908BF0A08947E3B524F1C606B055451AB6EDA2BBCF832510B3075E2CB0ECD493B71102F4EC69565F96651A3A2C3B738C2D55805798253E055DC8508B98822E6803785130D22E494B50025B0CCBC69667013C4CE4A140C2E9BA928D41D7FB5237DA8C5AC0310EF5007B2B0C6737BC17A747C5A2C1F3C1166BC2B0AD7AAAB1D870E54694C1CA293665286C4EAA35D34BD6EA7AACEA04871C257CF63641264AAA0DB4F65337274356F71D02310A57E44D23EC6B4185BC5CB45A65D3B592AF3138216332060264A6E53702D766D0F4A0F14F70B75B780688591CC414283A59AD2F84D665354D71C2AAA1C278AB6C8BA902283B286F82761906C9B2796595BF5AC01455ED2B43607207A30C949AFB1BA5C50659143C98237279003CA820B4B5963B0882A088CE09C99F4A6368971A7D6885237BCE28580E2EC483FA305FFFC0ACA173A89CC41727A55D4E29A8C410B3FE851B3D58B58C31920759ADA529DA162CCE47618B2F715F3658D71F5455365C67B04748B371A5A96B75F342CC4C031C713C04D2B6CDEC0CC92B7596BF4A2A0C91537A0C8174B3456489D2DB70D3AF2995C4830245120E9411E92ECB2293700973386983A0C6591CD5EAA34D5CC00FD672D20A604E78696D5542646C120E02C8DC5162630E71465ACCBC55170FE0945513748C0ECC9098A02E9D51E44ACC267272633645AD562816D479466B54D2150AFB682B4F32265F1F4BCED21CAF7C7980105B08056CC4192BFE0DA9AA5E00864B0A34712204CF6AE82DBAD360A7C840B4804826C39A59AE029056C1B2542B6A589EB47C14A70ACD1731BB0A4D657656915B91D696B2F92AFD82245945C7B77958A5B6A3B6CBB179AB83A0F32591B757E8B68368D6A5EE63490604AAE70EA7FB4619C91A455429A6B195214BD28BC717385D3CB8235991C05088C7939BF852125DAFC3BC368479165438092B530BB2B869246988B8F85425A2A523ED108C6D2F54358580944D64D801078A4B621F58012F9D8A17A92AB8AD43821E24E2F87BFA844ABD0C6B08650AB76D5397F2CB0060B31AF689FC8612249D46374848F496B360E733FC991809DA804DCBAB14030A4BD18CFE37B41CAD91A66A263437B7DDC2484ED55ACB16AB95A1A8C9345A898E89C37248F9768524C616BABD17A8DC7924F37345DCC32DE04273C5A0AC038A133BA01CE2481FFB57BA153826A7CC4123570293C82082B6A75FA05031CC7FDBB9031E10CA94AA283AA26EB3546F894B646B9A85AFC5DF3B513DB522EFB340287C64492AAAAC5FC25547129B56B9541EB0912222C2E60A11B9304692A749BB174CB47679CC294253B0F768A7872F698C23493FD908C9FF95F9275551B947BFE84780F86C1E0BC105F6CB7C9430369B58BBB07B3B0C87D8541618C76A43D52C98A08166E052B4487177AD222E6A002F7FA3F3601CF1EF0B4C02AB550D76447EAA695561118A46301B544B493C368B5B77AB17C5AF4543FA6A8C682A46AF39CA48046B1529684A53D0E492E1B8596F55334ADE15591DBC4B411537C88A5113458F187A6D77278675B0C85BB017416B6E9543FA1B924B631AC1DDC5556127548FA8CE0C90125139BDF13428E2C7805607A44251A5F289BE4E3A2C3C95C5B5CBF7C87B4A7D87A39A44B672BBE9AF8343DCB062EA3A039E949A7F151C8900484368F1CFA385BD13CF55685BFA4B959F8634ED7C437FC9C044B401683CC7482722C98583DE24EAD414C1833858BE987672C557DB87AEFE4CE2DB8A676D14083462DB35862DC0CAE95F88EC1F59426FA2E24E9CFC54813BE07C98F78A87B9703276B455E15474D7A283D5738D4B639369077E7790DEAD3336E1467C871A571080004A91162FCC31D2912646A9406902248FBBF28DAC4343B081C327743335B9EFA4B7FD13D5177064A5B6E8065B64D8C6580B47E6472C8F5139268145BA7A23A02F59ACF680692B20EC2DCC087A99BE036BF7E9C8C0DF15F168C508AE28E33D951740A9B0F0321E35CC01328B7BA860592B566CB369B21F51B7AE583D26652DA729F07F5B8D59CAEC65AAE42C7C9CBE73C68504F26670BEDC542FBDC67A95C9F2DA1A08E559797170EE63147A4688C8E101E5AAB48A4D1862506CFCD297C7EA61A9ED4A54FD3A28380292FC1570FA2AE43920B0E940675B60534425C69F35BBA714C88B3A6C323090B4C56B7F89963059F8CCB0994373FC1344412F694175C2EABEA110E035BEE6ABF546396D79472EEDA164BF49350F54C2E75754F502DE4A42721B37974A8266C49B57C6837B38A28CA489F02FA05307D7163B35BA6A4C5024B70BA27DB0DE8D64BB8B55C83BFDD2429B1BFF7F12EDA28DFEDFBF0AC16E27008C9FDC62C35E53B28A312BDC91C40BF8B2809FD40008BE70A6B184981101724BC3D5EC5E1956B510B82FD5AD0668A5A +ct = E9E8B57094849BF2A09A5431B0CFC2CE5A1A6C288B1E7B825A28C5991F8B6D5DEAD55E5BB9FEB5F98A8DEA6A33F9CAB55751C5C8B841B69F3769598F1A1016F0FF9CC42A9927D98607DD7FA1B25E1C2EF43909115E09B6FB434225FDB20A1E3A1DDBC4B7925B34B696A50DF2AC800D00CFF4C0C0E31510EC3D8D0B44D2D80EE5CEE9039802DF9E7367BB0E6E2E71FCD3B5F6AA97CCC6866AFA43619F5EF2726D9E33D2E6404156CADF8EFE1A356C2F2235008A43027720270C3FD0BBBC01CC07A0894247275F1E9A54CF22C819674CADED80C2979D720A6F233C6A0BAE986EF0694007816BB504806769B52177C23753E706D94BE0F5BCFB4E2607A723DA0B2018A1C1711940A353E96C3C6F34A773591ABE5F4BAEA44BC45670A6B8346B0C6EBF8CA3A5DCD33E82913440A9C28FC5A6B8E03D600D2C13A210D4F7A43D66DFA8214060F05754F7B76BE16199F19C5FD0B832F2FDA4EB447640BE835A34F5C9C73DEEE68776C7BFF2BAC601E501A1AE72535067377DFD3A0D07462C3DE3728DC5C02585F4E5CD7B1EE7A47052CCE9A90F098180BBA4EFBEDD10866BB2EF1389EFCDE7D48E9E8F3AA3B0419D23A97C4F915423A26E8181817A2F0B0B9C3AEC1DE80D355CB0313A806ABCB25139980488FFB2084E5A93162CF027D0271050D69E563A42B61107B3CB2BC17562D2ACEC2169BAA778B0BBECBA170C8C40A8E65D3CA9F8409FC14BE20D236846D50BF1019189CFD2AA44F199FDBDA6AF4AC5646B1890817F93DBEDA0FA1BF0EA1E00C1467048F36D8E996D5757A36D48C73DFBE9B9B8F42004A98600685A0500DB9BC9912AA10A7D8EDE8E8CB2CDCE5F67E5AAD00B4D0E17AD03873704DC62769CF5629BD3A3F281FDD75B6E682E1B9CEAEEEF7E3218B37AAD6D4C3F1786B7E5BFD657E3DA0D69AD6E21DB3F00480A56528DC09A72AB06C786EAF3839599F2AA4E7B34F072BF50F28E03A90819894B6F886DA655865F96AD4E6CD8EB3E440351E60CB9FE6D018B3712C32E2E904FE932B49D1590869A19315FF6352F1CC9D97E7D3DA89716F5F2931FCCBBD6ED96EDA6CB5E021A6F5048545585DB127C8CFE7C3AB905A35879CBCE540A1348ED02602A1C3AC0C9CDCF6F3366C396219938AB002736AB1DDE1165F44C90EC3D22FDCC3E86B32BE8677B914BFA24F21036B11C8EE5ACF390E10247E85B71EFC50BAA05945C09771D060F83D7FDB02688732D852507CF53BBCE32DE17703278C71C46026D72870732D822F8F8D0D216A397AB4CD5C6AEDA1FD35287AE6720CD4106D64A8141307ABF41FE68096EA51C59B2827ACF7E54C8E9A00ECCA352B276D588F4E00C54D0AED2E098E6BE9F174C3ACCAF83FC7E5D7CD6B6E6216F54BC9E777DE0A239574D85DF930B00E61C3096962298C2B5D644740FAE2A1867288A2ECD6240CF4E8D207CC2B7362FB1CC064763F0A7CB3696987C33BAC822F431F981885BF7C0377041A2C7EA34F0FB0E3F0147BD0362BC5E6D1EA51289BB1E5187DB1DE6656BDA982BA0A91458 +ss = 03139CF9F20FB6BDAA4EE906AEEE834815FA924E05ED7E7E3BFB432AAD944D6F + +count = 90 +seed = D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A +generateEntropy = 6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +encapEntropyPreHash = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +pk = D3B1CDAFCAC7F6D08082DA095A7658B3A45F7BF717D4B80A3A050A04CB23E01103FFB1731B2C35A9DC23C4341976B188F5226459A02D348BC9D2064D574040147B41612914CFC2954E4190905446E5AB8632EC96145B917DFB4A9DAC62B18CB0120679E739901D9BCA662024335A083911AA53828D6D79C948425422C32EC471C2FA843B54F6731FC401475612A135AAE4B146FA829871C0654C075DCE41190483C3EF60B7336200A4A39CFB6787AC09AC85F4CB3DBB494727A20ACC8A1CC9CC765862B0D402147A08A5E4AA6E679D482786910399BAC7A36EFA477236B1A01BAF452BADB3F184D7D6AC6EF64CDFB89D1CE66A059A4659D8137DFB3C95CBC9E8D86E064CBFDFA50C68130A8D82258407BB7B926F7A802B53209F3AB78784102E88FB91E6311D496251F7B574AEE5797E881BA1DB16AF40281586267D826C0F33A0518C26E6533E19EA0EBF29474A131D882A189AC03B835C16C34C9AE7A1C4D9F5159F85B8542284E0409DFB0876FA6488E6519867B5C53896867772210E95399A1733D2E78532B7651CA9704AC063DF086CAE4AAF65150093F27054F34E2849449C7680EF1CA1A0AC399A01A9B74484A967592CE85086230582518414C247BB7680ABFC2A04A35A20A851B73548A8E4CFC2B84CB5EC24108396C28498A6614790D56BF8D1B9F9E40BF574C497218EEBC06217C9BD361BAA5D0715E666C2D3D299346A79BE0BBE4B7CCD49F948A60438514129C126AA1F3875718922C5124728F09FE5437AE83194DDEB81F0D744FD2B9B59FC223E2792501B4932924FACC16C1E5444DBD6A823016B3AFCB46EF59CEEB49728AC541BBB6BB64B7E196C59910628C8CA22B1138D884842C387B594B544E5D99784B06ACC3B5D80BA81CD34739A20AF11F7735D645D9FF25C07F8AF9B5902524A1953CA2A58D6B796E3695A006AD6C703DD161C12C01B9BC995773C5D2CE59470C765C3F5401CC07885C77BFB3C15D7F766F0EC7CB3F601DBFC210D599093A21C87D82002212B06898A5A878D4EE913EB451DCE14A1BC424838D4797ED14D9EEA2473B304D6624F1725C820751A9D313CBDC79AC9A26548587FB41371C5F48A4DA04D37AB7189685AAA054853F0491A0388AE4B7AF4259969E29EAAA2B2EB9503518C7C53BA0E6BD20EA8355A63F1C481EB5E662A0B792014AE4C0981274D902759AF794338072A839B05D9D42C1EBB1A3DA33B54066D1A63024A3B1D1437B37A83BBE816075CF416275A6F58336905937105E63A1A017F87911CF0B41DAA41A5DAE3856A606E2A9333176628198B49D2517F54A9182E4BA877760517DC94A079538822251204B4C4A2382CC7889BF84923C09072F86BD1C5879ECC3A37678E6D031568C24012578DDE5CA01005B2DF71A4A0B0455A03AFBE7C366BF1B086973038FB5DEBD793A303B4C867B611772733F66574CB0D7C303563C389B2F1B46E98945A94B142B2B0D647521F4B58F12326FD86286A448909191BC600BC7578B0169A45C071C77F280C583788F9C2AA1200A73431AD56D23B20471BB67A627A594BA9922B1FFB75D2D030432A954C71235A9278857C3010A8A8906C070B77060FB831842140770ACB92E856C8A95E163D5181CAAD6A478AC9AE82EE27F7256F4D4CACDDD43F45CFA4DE4DD067CDCA +sk = 96D9C668915384C2847B7991E5F557949C99A3D46A2FC9AE7448A229A89EF7F405C2911777FB1E2F44721BE8CC326A80E524486A16A083527E22D51E4EF624B02625FD6A857BEA2C0590A3A4E39F0E041B7284BCC501201842345ED5CEB097A5A5F730EE53176F8ACBF9E03C6DC4A069718DD64C47E1D17323D29ACC630DB2DA9922804802CC768070245380CEC6672F6A5A9D14E4012BB13CAF8C320A320ED63B0591087A0C5A76EA29B57D5C997FDB372E9A57E3F4827A2441CC485718A421D3C45BD0426A87589362E52953822CF785802B2C6AA441ADAEF93DC6451AC68A9867C9B9703ABEDCAA540146BA6DD8ACF7DC317A82A4C1396267032FCCB53BE9306E20E4713B82842E03B7FA984E5827C441E293352B2E2A51566EACA8D9C4206000655F761729020F7FF9B230D6C4B986BC94551175A8ACC7E2A2C174C500666D3CF021A9B40F1A465447291F920865AD16240309B5C838A2DDC5BEB8AA11BF987AA9D7C082E8C55C63AB01D0664E545E505B4AAE50606136B6B01499A5BA10174852224AC6BD242D5D21758C4342F9A02A3D46A9A845112ADCCBB73488CFE3055CAC398B0245C467B94EB342E1845969D70511BC7100F886308CBF21C13840BC17626AC93DFCC4EB22BA18F62B15B521539901166598F25555C32587637A341017885AF1A6D1841AA1C747D918253E1C873C2CCF292BAD45805D8946B00DD23CBDA03878F66357D175D67A1B743C1E5428CE90661067011874B062E9AC8A0F726B55B76627C53338549C3F2605840A11D5606ACD104BFADCB51253AF718835826628235878D6160F15033844D76AE946AE6C240053C2AD6C3A3D72E721D9565A6C79B56840CC5A878C6A4033BB9C88DC43B130348082E41C269CC0D3B05FFE356B5695BB01C95F8AA9C30E50CF31F11419E13ACFFC7192B75948E06A68458DB80A8F71573B6EDC1513AA5B060CB77B12C62761BC188159A49C95180249B3E35C3100635012637CB9CF17CA9936787AAC954BCFC655AEC8B4215861A7709F2846A1C14889D0384591753E3F19CAD2236DFCB7B225ABC430A7B61E6018AB30146D60A6563B2F980ACF66186FEE70A458750CC62C433E651F447CCEF8A773BB2731A866832AE535F0D82E605371F6B35FD6FC1188A52080C609BDD8748C321CA37190321B286C849D35224BB5107D83E2827EF0C63859133852630B237247AA8C100678E43618289239EF19C99AA6B9156704643285BEC89F0B0C21F3A091E2063E5D3029F52C33AF97529E701298D3961F492E6B731D4E2064D034533F4611FEFB64F1899EF563AD71A52E20B199F0D80C557CC8CEDBA3CD1746D3A6AC2E697637F08A43D681ECE3769C8980C76A26ADCC585EB1194D28AB163ABA5563A5C7985720248662BBC21470022EF4110B33B6B8B744A80AB36D0A9B0A7988A0C98C6A597F8CDC76791C467B0CB53A020928F7A55981B520017BC06B36D10A21433797C15124E0892A81230BD6BB4774D46F73B874602588D3F8966469194041BDEE87AC54059458B19724949E7998AE8018755D491BFFDA76A70A64EFF902A4281734A7484037C739B7BF71B658B779CF6370420D2073FB820BEA1B1DF29C3B12C54ED3B1CDAFCAC7F6D08082DA095A7658B3A45F7BF717D4B80A3A050A04CB23E01103FFB1731B2C35A9DC23C4341976B188F5226459A02D348BC9D2064D574040147B41612914CFC2954E4190905446E5AB8632EC96145B917DFB4A9DAC62B18CB0120679E739901D9BCA662024335A083911AA53828D6D79C948425422C32EC471C2FA843B54F6731FC401475612A135AAE4B146FA829871C0654C075DCE41190483C3EF60B7336200A4A39CFB6787AC09AC85F4CB3DBB494727A20ACC8A1CC9CC765862B0D402147A08A5E4AA6E679D482786910399BAC7A36EFA477236B1A01BAF452BADB3F184D7D6AC6EF64CDFB89D1CE66A059A4659D8137DFB3C95CBC9E8D86E064CBFDFA50C68130A8D82258407BB7B926F7A802B53209F3AB78784102E88FB91E6311D496251F7B574AEE5797E881BA1DB16AF40281586267D826C0F33A0518C26E6533E19EA0EBF29474A131D882A189AC03B835C16C34C9AE7A1C4D9F5159F85B8542284E0409DFB0876FA6488E6519867B5C53896867772210E95399A1733D2E78532B7651CA9704AC063DF086CAE4AAF65150093F27054F34E2849449C7680EF1CA1A0AC399A01A9B74484A967592CE85086230582518414C247BB7680ABFC2A04A35A20A851B73548A8E4CFC2B84CB5EC24108396C28498A6614790D56BF8D1B9F9E40BF574C497218EEBC06217C9BD361BAA5D0715E666C2D3D299346A79BE0BBE4B7CCD49F948A60438514129C126AA1F3875718922C5124728F09FE5437AE83194DDEB81F0D744FD2B9B59FC223E2792501B4932924FACC16C1E5444DBD6A823016B3AFCB46EF59CEEB49728AC541BBB6BB64B7E196C59910628C8CA22B1138D884842C387B594B544E5D99784B06ACC3B5D80BA81CD34739A20AF11F7735D645D9FF25C07F8AF9B5902524A1953CA2A58D6B796E3695A006AD6C703DD161C12C01B9BC995773C5D2CE59470C765C3F5401CC07885C77BFB3C15D7F766F0EC7CB3F601DBFC210D599093A21C87D82002212B06898A5A878D4EE913EB451DCE14A1BC424838D4797ED14D9EEA2473B304D6624F1725C820751A9D313CBDC79AC9A26548587FB41371C5F48A4DA04D37AB7189685AAA054853F0491A0388AE4B7AF4259969E29EAAA2B2EB9503518C7C53BA0E6BD20EA8355A63F1C481EB5E662A0B792014AE4C0981274D902759AF794338072A839B05D9D42C1EBB1A3DA33B54066D1A63024A3B1D1437B37A83BBE816075CF416275A6F58336905937105E63A1A017F87911CF0B41DAA41A5DAE3856A606E2A9333176628198B49D2517F54A9182E4BA877760517DC94A079538822251204B4C4A2382CC7889BF84923C09072F86BD1C5879ECC3A37678E6D031568C24012578DDE5CA01005B2DF71A4A0B0455A03AFBE7C366BF1B086973038FB5DEBD793A303B4C867B611772733F66574CB0D7C303563C389B2F1B46E98945A94B142B2B0D647521F4B58F12326FD86286A448909191BC600BC7578B0169A45C071C77F280C583788F9C2AA1200A73431AD56D23B20471BB67A627A594BA9922B1FFB75D2D030432A954C71235A9278857C3010A8A8906C070B77060FB831842140770ACB92E856C8A95E163D5181CAAD6A478AC9AE82EE27F7256F4D4CACDDD43F45CFA4DE4DD067CDCAB990059E901097D00E0EBAF40C5D5DAB009C66798489D357E760478CE884CCE5C95FA08ED106CE84660E8A4C90BD2B22634E40769AA0090A101C5DDDAD45EDC5 +ct = 922014A568044CA7D9086946CCDA46596385465C8065A9BEF75A70EDCACD8DEC0BB08233AB0E0013CB4DC03F59052091254AA8D8895AE1E73A608ED4D913658FFACFEE15EFBDB2CA0ABC843E2FA32AC1DC6FAAF8ACF19E6D2FF14356DD4DFC6171470C9667309AB421FC8663807FF4C614126C4BBF4ADC193CB58465FEC7A70BD508D75838A349827227CAA2F1A4C02461646557A467C73715E4D8B309DE5FEDBB0D8827EA6503C814587CDCCF916BA51FF1B72A2546AC78C170FECF26B84D8D80F6F51131903C5982FCE030DB8C83A6C1D4304E72DC79D77D7E47C7131229FA8279820B627F3DABE4B64B356DCB6E982BF07B1537F656C3DD57E71434AE394FB9E30C14589378AC83D84C6800837445C4610EF536D8C8CAA31A52274434BE4CC66B6B21A6F28463796CA5CF0CDDEBF6663EF308D3066B689FE515F30D0F5B014E49E4971F7B68BECEE860EA549301753BF8FC95EC7574B51DB83389632E7F9291E20BBF20E898E52AAEBCAA3B9FC67CA7F8D63892F355D365C166961A5A3E07D7549E5910CCC06DDBED484002B7B8A0AD3F977FA92BDA8DE05D711C95486693BD79F4D43CDCA8D5FD162A400D8F33D7535774967943282C52164EF50FC337068A374B01D75757F9F36631C963E1981B83F6CFAB6FA528350AE7FBD39C795BA1967402065949296AE14BC734F12BB5559CCCE061BA8579BA3DED45E8C763EF76DFBA1099CEBC9CAD903C5703515FCF3C5867DC73C8C73E176154D41BD4A6F0C039BB56F6FD7806E0F6EFA0BD0F57BA4E64D759C51BB10523AC8673FB236D7502F68532778BCF6ABA52FF6F43A45457CDDB8975623E5A80D85D2119F1828C44D8D5D2610B5D2AFCEE960E85221531B2D0E9C67389B791820D8658D312B2F1C1BA567C297D3D9307568F84BB7CDA8962BBF35A2B41665732121C938953ED1784304B5907F3429C1038522CD7C29E19B33AE7CD8171C7EF05BBF46AA069F05495E31C2357A13D478971F4657FFE95A1F867832BA3DE2A386A46C511BED2E63541B51695B4CFF7AA0D7E453BF56F16BE0128D1D03CAA79C5260BF27C4DEC61497B47D7E7ED1A1795E5D4DE8EFD141A44DB98FD8588663526EA7382E7C36E5B6983EFDEF927BBD8B78E71B8328DA1DC87F84CADF0772E5E01E920EC0DBD625701368156D91D00D621BE1F439AC76AACF8931CC5840358C6DBABD03148CDE362D7E2DD2B98F6CB50B2BE7E8DF737F5044F96430A121F1A9B93A2E17DF7AAC2F17C2D9032F5DF61F98810167300A1075A81A74D3280C603908A236B6042B6FB9F8FAC23B7E4B967DDD3D3FBD7FA1C01A78E9AA44221E0273EBADCA5515F1F8ED6B07ABDD73E7245E865A2E735BB2D309764EB69D32BDB2DA08EA101FD86E6BA18019422F9A1771AE69DCF9525A2D4F4E7C56A80668995F3BFE8D37CB934F34722EB48C841E54277202156DAC0094901D061D9A5E7A9DB61247028728A41262946311662AD4EBB60750FCFAB13ED586E70E4BD7D45D5F3B6F6E2FE1122900948F1BFA130 +ss = F87CFFE1A96BCDED4FE027DC8006065D67D0190B87D805135BDAFCB5EDB9803C + +count = 91 +seed = C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3 +generateEntropy = dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +encapEntropyPreHash = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +pk = 112B1DD09313B9A25B7094700639775F89B8D0314EEF0186ADF7CEABAC36CC9292C270717F27CAEA51B1AFE1CFE6B6A1CB1A7DA53C6715C9C9B2694BD5A581B733AD4841B229FB7A17BC213B969935C672D0993A94EC170BDC8B7C800E66BC6514F84FBC81C7D1C9417B79A82E5B3980ACC792A19C46D13A2E75A3AF791BEB401F7555793D94C0EE1B9E98A5B6C52777E537BFB287268CA9524A4438AD87A0E85279E474C5BE7740B7867D8B04781A2436A8D343F62274E236C736DC3C59D5B326563B9C86798AB14A6C9A0E67B36DB89A82AF690DA7016418BA2D6C435E39095BB81A0E49C01A73A31EC9159844D1A3EB233D16B932919421E6A342473A71DE629477183E8F34B2B7C8ABB7A3B6E516107CB5229D780B93417F9BC94C38BCAA58F34DD88835308C742875CCCF4928122199CD932148F48A94C5C2252295890BB4645761D3C2C0F33AB3E1021AA56B573E9C6FDAC37C83F678B97148CE573A244B0487F3CF771BC7B6A13FE53A6BA58854B87A67A6A17D6A301C85F7C061071B4DDB27B3F404DC402EBACB8254A0568D48B2D299BD831188886A65AEA5CD8D987F6017A2F4392F455C2B4F9B63E6CC1A27EA38F2588B0F8086D7A5C5E4B05B76D2B8918820CB8851704CA6D730861B512FEFB0A76B61401E23B01EA710C5E3B73FA716DFA6408A635423C61372592DBF174D6D811EEF7C4D885BCA5FE669233A141E43810AD10235CB59F824728BD7ACF17765BCD354A493AA60438F07D266D728B640CB07D50275BC2605FA6C964614B2C8143B37B184F3C30668662149BC18C6038706C12F0D31B896B69A7D588D0004497E4808D8C12253987F000168EA758A5B32C195F03F23A07C5A546A6607084CF79E073BC6CC1CB372E385CA827C490A42D900035BF735C6242031B8332BC57765ECCE4792706F1CBA0C7CC390E7BD3595AB876C4E397C58FC325C9607B0EE39692C31730EB4744E967E7FF8139FD1A545622EC870516B2925628BA782CAC845B2429C3CC0EBF7747F414E8D35CD4A91C959D2276404A5DF4790F4363104E6A0D1D60A48B65BBD92B417B51A5338CEBE36C0F218BF27968C05D99947E9B44B4B5B2934C538F85CD7C8B9E3C31637E14C5C0279CDD6386E20CA89A53671FB2F04249565491AC2F900AD380D1A68B67693B185F26A232AA1B43503398002085713CA4B2F94CBCF6E837B020404B7F519A2B520F93B901943C918393F26061346A0193CE9BA8A48B5C4B01B0EFA231EBA0528C5B38CD32CD5D22586494734FA746B411759303A51A12EC58B03FC99A1EDFB1CB01375032054878A6EC9DC4425945AAE387E7FC6CD399C90049854CF51B3DB690EB78A0A2DB04D05102DACAA9834620ABA427B5733BF1D1693643C88BD265AF0280ECC66344B81129C491B3998C6C70CCF03257C2D06115B72AEC35B4C8774CC7936C578B29FB3B0A5C66709363B73F41B08DB919CBE57AD817CBB5DF62B7836AF6FF4AB8CBB07C9FCB7E3D601B2117E6A7242ABB24EA96CA867B597E9E9B45C01ABA9B54D2D323DF8B38D3D37B72C2790E1041037355F274CCEAC2714A92955B31C55D4903A85BCA55B2BC22C536AAB22557D912FE2234423E7BC0894BB5F846A2DBC4A0DBB11C51840059EC11BF6CEFA3AB473E1CB0F0BD17EE0BC3C59 +sk = B1C127D24808FB2B9922332832131C4FD67FE8A1A070AC8D17100BF9F6291EFA0BC8114D98F65C8F4ABAC3AB17B4241DECCC37688B881BCB68503B54379838BBC100B5BAB306327E7965B694644C470A5148666C7FA89872D39AFF60BC533C83F280ABFBC26F073331EF40B694AB25FEEA5B2F55196798B70681CAA21537DFB5746C66129775852E5850F57C2DB2E8A0E90530A57B387B1C429101D04096C3E0BB6E9AF19F83B1B0B74C47BAC678B0F2269798573FBCA5D8E687965B13E495827ADBA63DA8A17564A3E68037B3A4991993401C1C6B149895FFBC03760C13595035A713140EB7A42FF6ADFE6BB371C9AF5A686EF858A8FB7A63FA137492B53305685205B08D44A3AC8F8948F2B7BED9CACE27AB6265722D8F2950E0C9ADE053A4C4CA8E3F80A907A39E33DB78E6065FE9DC050A5A730595AE5EA32E38C512EDB79DCF345F1D9C238A1732C552AB8DB2CCCCD11822972896B323CC43AA03633617F82E89D63D4A1003CF9C5CE3379B1D53A63EAC57ADBC91510316ACDC30FD74A1A2E6C23584AD1CB28444F9231661079B0913E20B3278D8A2E8B18556F336CB750694066B6C82C5D267A903B624CD440D8E187D9E438D178C8394706F016B835E1522AB6904F80CC24358B7DD3BB271039ACC174164021E8A522FAC473054D5B4CB3BC64BB107C6B637CD6360E312A85A3B1E3D2B64436A87E81016ACB763A23CA9B7463023148B0C4888BFB18D9441841F723B9436B77B09C79FC714385A3AE97B5BDE0A2A0C541DCD2B668C696281389EC270BC6D088FC42506CEC85BCB4B611342AF0A61B1B9D75E0DF43BE293CEE6EB0413363716EBBC48EC6C361A48B9D871BD5742FEF2AB286094A92B508CB794F2F69A8EE15C2D748D8FCA8CD2284719815E75B3B0DF76298E48280BF530E09A34D166CD5379777D472F0994BA8E5629EA7691FB973F45869635B61B277C375606B911AA1228271C85B047942A52187BB231412B50F5BE423476720240E62B9D3CFC5B7AF5CE9FB38E03349063741ADE945E994A2D6492A92B1250880318B9B9CE845BA29BD3733228AE960663050888BB98A0FDC21D6FB34CFB5C1AF6D9B98ED6AE454C09B89B6067401FB30A17DD331A845C713715B5BD4A087BBC14CBBC9D2EA83D0F9B0D56D939D01B7D590B3082D2405A20724E2C44B5123BC1407B11DA3DE5889AC52B7B7821C4AF1303D3959EEF3888B8847F3E0695B5B844E8E3C221718A25057E707A50E0159AF4462BB1D103B9057FF7FBC1740BAE1AFA44138AA2B7E3270CF80A6AC745CF701040C97253133EA195648E929E6C6394940B6ECEB18844F1C862DA6597A46F64E0CB5D2803EABA4A08110A011A32452185A6425D9D44B43463893369514957592F519C22D2B06BDC762C519D5CB84E9A68456AC60AEAE85AC6453DE2BCC103E32DD509309FDC08E3B3698A193D83D62DF74719703BB5F8CC5DB7B88B80110D74D6949D00469B840FF7FABDD4C0CEC1A097A6117C28046B06B82C8EE8204296428AB703840ACF7F3333D742726B114D3292B3154B2C4095B6D465657EC0780C488A0C60443717109363C45777271955135E60B46104BC18BAC09A18690B37C8078A22645532112B1DD09313B9A25B7094700639775F89B8D0314EEF0186ADF7CEABAC36CC9292C270717F27CAEA51B1AFE1CFE6B6A1CB1A7DA53C6715C9C9B2694BD5A581B733AD4841B229FB7A17BC213B969935C672D0993A94EC170BDC8B7C800E66BC6514F84FBC81C7D1C9417B79A82E5B3980ACC792A19C46D13A2E75A3AF791BEB401F7555793D94C0EE1B9E98A5B6C52777E537BFB287268CA9524A4438AD87A0E85279E474C5BE7740B7867D8B04781A2436A8D343F62274E236C736DC3C59D5B326563B9C86798AB14A6C9A0E67B36DB89A82AF690DA7016418BA2D6C435E39095BB81A0E49C01A73A31EC9159844D1A3EB233D16B932919421E6A342473A71DE629477183E8F34B2B7C8ABB7A3B6E516107CB5229D780B93417F9BC94C38BCAA58F34DD88835308C742875CCCF4928122199CD932148F48A94C5C2252295890BB4645761D3C2C0F33AB3E1021AA56B573E9C6FDAC37C83F678B97148CE573A244B0487F3CF771BC7B6A13FE53A6BA58854B87A67A6A17D6A301C85F7C061071B4DDB27B3F404DC402EBACB8254A0568D48B2D299BD831188886A65AEA5CD8D987F6017A2F4392F455C2B4F9B63E6CC1A27EA38F2588B0F8086D7A5C5E4B05B76D2B8918820CB8851704CA6D730861B512FEFB0A76B61401E23B01EA710C5E3B73FA716DFA6408A635423C61372592DBF174D6D811EEF7C4D885BCA5FE669233A141E43810AD10235CB59F824728BD7ACF17765BCD354A493AA60438F07D266D728B640CB07D50275BC2605FA6C964614B2C8143B37B184F3C30668662149BC18C6038706C12F0D31B896B69A7D588D0004497E4808D8C12253987F000168EA758A5B32C195F03F23A07C5A546A6607084CF79E073BC6CC1CB372E385CA827C490A42D900035BF735C6242031B8332BC57765ECCE4792706F1CBA0C7CC390E7BD3595AB876C4E397C58FC325C9607B0EE39692C31730EB4744E967E7FF8139FD1A545622EC870516B2925628BA782CAC845B2429C3CC0EBF7747F414E8D35CD4A91C959D2276404A5DF4790F4363104E6A0D1D60A48B65BBD92B417B51A5338CEBE36C0F218BF27968C05D99947E9B44B4B5B2934C538F85CD7C8B9E3C31637E14C5C0279CDD6386E20CA89A53671FB2F04249565491AC2F900AD380D1A68B67693B185F26A232AA1B43503398002085713CA4B2F94CBCF6E837B020404B7F519A2B520F93B901943C918393F26061346A0193CE9BA8A48B5C4B01B0EFA231EBA0528C5B38CD32CD5D22586494734FA746B411759303A51A12EC58B03FC99A1EDFB1CB01375032054878A6EC9DC4425945AAE387E7FC6CD399C90049854CF51B3DB690EB78A0A2DB04D05102DACAA9834620ABA427B5733BF1D1693643C88BD265AF0280ECC66344B81129C491B3998C6C70CCF03257C2D06115B72AEC35B4C8774CC7936C578B29FB3B0A5C66709363B73F41B08DB919CBE57AD817CBB5DF62B7836AF6FF4AB8CBB07C9FCB7E3D601B2117E6A7242ABB24EA96CA867B597E9E9B45C01ABA9B54D2D323DF8B38D3D37B72C2790E1041037355F274CCEAC2714A92955B31C55D4903A85BCA55B2BC22C536AAB22557D912FE2234423E7BC0894BB5F846A2DBC4A0DBB11C51840059EC11BF6CEFA3AB473E1CB0F0BD17EE0BC3C59175EB63C3144108548720CE7EE0F43A9FF3F52A9924EFE9F2F59318BB93C86B5E15274A8E2BC08FE818B117BA28C5DFAE74D54FCDF6F20052F79BE333EDC8DDE +ct = 3E4CE5CED61DA4C323AE10DB3EB49FB68477E49A4D8A7EB19064F75CD640538F0AF831553F7690E3531E305813C18DEC92A0FB67A341F6E551DEEB0B3438A1A22391AD168A5FC16D6483D0A0F2002D5F43153674B07F6A5C5E337E3351A5DBD3C315D460541EE170E2E7CBA41942C1753A401E230D50D7B80884FD269F913EE4F326FACECCDABE1510EB55FAF17155EB4568F19F4E396213C9A7A252E1815AA0FEDF980409F218D5BA5B383BED0D331D50053DABD30C98619DA2223D746ABC4486EBBE371E33313AF8225E435CBA697EB1B3B99F7A209640C4C82A99CAA9C9642ED63878CC886CA77C45360A2234550E68EC486BD584E1BA6BF122AF1B931CA3D7C6BE30C281D6C5F6E6CEE2C9AB2CE047E56F8F80CE3EF606A0B0DCA9CA7B2B5945E065FD6E50535A3DF08C2FC90B2F02A2638BCF88679D669D7C16E32586CA509E960B73032F223A65EE1286BB54F0780194A0961684E5D4D1E09D147068742488267781305863FC1E2F4EA2CD37B1E34F4179C75F9BC433F279791A62A1D3646B57784AA401AF9AD6082A8F2850602B8EE534250C68223B77E23C7D2A7740D51948BDE1ABC0816F2EF176E9C15AC7A4F40775AC5B9641B7F08C3B084D79FE86464CB1848AF41E52DF272DAC4576319923E22D6845867422E0A07C4AAD7A60B8CF2F344CF82F492704D60C5621F798F9911B24BAE1C04BCE123E40F35A5A78DE33F89CA5BC310D4DC5FDC021159CCF412B875A985CEBAD40E723C9AB585267D1AEEE9737B0422C63F9D84660927A29C88E78660CD989BBA8C29CA60F83FEC307D4C9A676B49A4DA9DD9396E8A7A33CC72842378CEA52F9115D44E99D78B9996D2C8DC3C4198C67007E1F2972F434989B8450C8F87AA7BCD03AFA3542E937AB649FFD3E66E44BBA1747BCA1514C3B00F9B00391812D1AFE38524AFBD89D09948FD648D7945EE3DDD0BB0C67E063362B70F7C96EF09D1944CEDD28C371FD5A4F8D7BE55E47E052D72C95C362D8D1D1C83CA29F70B2422C1F909D14C4D404C39F2AA52EF69B936AE27E0F38C4B564E47399C0E58321AFB00BFAF647ACE5B18582968987A20766CADD4DD7B166DF9CD2DF9B3D339E70FE5BECFCB3A486B0A7CD616CFC8B439012C1A6E87DB9C0BE4CB9566051D5FB0712C5C80AAF79974EE299BC7526D2E351A7A8CBE2F35196C0028CB8BC451049876BAB7D2B6EA233A16BF2F052BDC82CDD43DF3D4DB55FC52DB36FA70AE7F98601BD6C89282AC94FE34854C86BAD00A597A5A684233929F1CA77F6200BE14E2D3F93D089089D800C73DBF4416DD831E175522CADA8FC004FE5AF3581F34FF2084D34ADD151AC9EC634BE82D9C2E149FA94ADF14B03827DE33B1B08C15EB890029713AEF895B413A1992078C1CD4ACADDAFB0546BFA8F940BE6393DFA51EAD36703900E35D8E8D05E02920A37F2F5C4BEC938FDB4B5AD058A9CEDA464A8D1A70AD936A5F7CC55B37E3F1651C3D8CDFDD7CFB1CB33B7E5D59F87E1102B3A534713025B6855DBDB7958708897D3 +ss = D2D4A23DEC18FD2C413D0C64D58C1D14E19D2A18AEF1CB038D14C3C2E79F6A69 + +count = 92 +seed = A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8 +generateEntropy = 690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +encapEntropyPreHash = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +pk = DBF001BFA28B07E21ADC142C75111B9785AA2109A795AB792DE4CB7B6298A504200F8850D32CC44E54182761A1C9C9BA591A9FA6873A61025515B068099BB1E63751C5B887D283077F86B733E4344D13310CE12D22322F254A0E92779A87067D19C53C70DBB927E14E1F2892B5273949428EB4C70C49DA8AA7FB87048961DB4892A6F89F18F0BB69347B9575025A964047AC7BD2C7472838383A6072F8338B23AA07D6B7B221E18D4E3C62641916106694315A2FC5BB88C6D664667680DF556C3C046398A88328421F32ECB758BC64CF246815A25922021DCB67C995FC72CC6B46BF5CA9EF3998535AC5CFAB70AA54318F9532DCD138A4C03E2FF5024C52BB486BA7665B27610B822975C412331ED6C98E66721DAA1897936371113A4F17D96EA735A5CDC019809C3907C03FA950C00EBA9DFFC69A902151A39163F2931E1C0271D491562E0A87FDF7B7846C31151017EF08727DFB68F22A8585295659EA358CC1B85C9AB4D107413225B8259804B31850EB347E1FD37F5435617A7A07B15321CC204B1A6B7C30D67E91C088A458BEF5CB704E6B662189A9C0079E224A94E21502C0F1A4DFF6028EF6645CBA38C0C86EAF673E9B2613620BC216914A9781645FC48E33CB9EA06182637439F1D1A19FA50CFD3B5E2CB8310229B74ECBAEAD4B079D535521B8587A2995FA9B8C6694BE6E432343C97C16CA23BF53883E23CC38F10C38E54F5639B9FC0943A4F41CD0ACC8DB40CB12E644CB74B9D4B858F7D6767830B92381A42368476CF2602ADB9ED08B35FF5C4D1EA93C94AA75E218779825401D859902D19822E9820D86C7E57562795B89CDA97EBA773070BBC502884A6F437D7EA7A459C0764CD943E0B6A5B61B8358530459685E2842AE9AB867FA712172207E692A7AFFA872323779087547C3D8B89F368CE078ACECD55AAFD5305371A5BEF24FB255211B2169F4543927C845A3049F7A88513A682303960C2D12BC277656F15738C4368DEB70CFF2A32A1D179F4FDCA57812CEDB21B356E0AA63270788B510E58B4BF613473FE931DC80A9CB8BAFE63AAAC3913936C8A939C413CCA10A1277409250B5DA321EE5C24AD3D093C1C7095FBA34B81380E5DA561BC039E3A8C15FF3982A7938BC16446A3AB2679A50C2E5C1D1A08127DB4CEA30340B5589B2327988C97B78F003D1315DACB301520A11F9F0B4FB33CE7C0203FF11C6A66136C0AAB83928C145F4B968783B131281F2153925DC13AD133FCC5247B595CEF0F03FF0DA0A429C0DE9A54F66C03F1A616C7210B7ED3624FDD27E99F38472867A9283C6B294B0D7014CF9EB62F0D7B051B190F093450453C056081370B45F5EBC4C03808FBB5C6D8B659BD22612C2872DE9034B11C6AA6D356B2BACCEA0F909DA0C775969C12FD5BB0C8A9BED5172A9358E01C29D308636B5D668F5B2C9DEF1380BA23B5C84259D887D3DC4882702B41D99C72C800DD5B19935D7722610741A105C1D227C38C5665CD5A6DAAA991A9868499830C1697FA430BF4F95B03004126FAC283A167281E4B847EBA8487B0032914EDB0B67B1E320C25BAB50499378115CB07A9000E0156C9C93C1D90693B9C22623A3EB15618FA1C470481C4CF292B7462410D057C2E5851E08E31FD88AF2F84B0CF79A88DE834C1F17C7A5FA17D329CAA0 +sk = EEEB8866B17CDA12A45FCC6F9D05AFD103835147647A7301EE071366398473C8103AB3B064E340F4F9866190ACEDE02473FB49635BC38DEBCFF0F34C5175AE0EC025AAF19CCCD46D658C2A6BA62B50D1452B09C21B430EE9A3CE05D36A8E1AAB2BF0185F35664B4999CC8C0DF049C01056AF6AACB025708C184534F1172B28FCC94AAC2FB7012E20443F11F43478E7B1DD8A5C7D9B5A8818C0D2259C7F710F51003777B060F8DB5FE06C3520D35E97F6B5792B0AC3304349387B637686CAC1A6E45149173041FD7C3CFFF5A398BA832DBA04DD7179D0768122A701F4E0BFA48149FF140E2978A723FB985B939458B081E1068EE5102E5F540365E6ACCBB8C28DB84125B21E8D04622412C2F075CB57019EB828616CAA245A8B099A01BD86268CF491823E440E984335AF59924FAC1D43263AF725895C717E827532D35C7DA9AC1420B46AEF13C9F33A427BB5A1BC646F7B54A21760527D303BACB2A21AA39C5577BCD5F416F126741FBA9C2CF9401EC20A14E9A7BB927CC8135BBB0C3180696093289F4B19539C58655B8698A5D1339C9490BE7C04AD3311FD422045A5027B203407CB5755462C21AC51F523389E803F30E12FA9C0AA7B4A1FDD85C66989AF558CBA916C9A037AC7DE1A3F7F1B5BD3208FB6F28661696AD0DB88D10A3B224A5BB5C99CCC96820E153E478AC579C65BEC5A3D4B85AFF1C4AF5BB222E7AAAF9E9149AFD11EA5E86990913D2B543913942D148639D9815D4A8908362A84BFB6AD20B8ACF9596DF4187009E7B773070450010744712F9E7A9B8E9624E3E2B1D6140A9E4789775ABCBD2657AA487740314EA1E446DB5C09746ACCAEE29783B23EBFB255BA5C9706F1254703C676EA09801762E9FA45D858732AE7218B37107B3708EABA05D2C035FD447CEBA46EE446AA324BC184E7B929F7513C16BFDE5C5E55C05E6B5041552C17DD223AF273CBBF65A44B4B6DABD51B341464A9993EFFD671481592C5A655D116B963975006B13503BAAE38332248F58656620098F42F97A813DFC7B4DF880E5E783AF5D833B89079474040AC05A6A7EC5E9EC1BDB282443C736514514F1CB7455958608A62503428464D89C66B209C417445416A54AA66234B1A5BF1C0C3F7064B6D0A7243E170B6ACB01C033C5B1670A3BA6801024C03B24CC1786025FBC56BF04F3B241E4BE701C9764938695BEA4316ADB6ABACFB44F2041D2C29BB867379374B211E990F194B872A7B684A212DC179A4ADD943AABB1E6BEB93F5CB100FE342D0781AA80989406571D1B79D08E31AE15B81740A22DF02270F920EBFAA3C9D74392CD64E71F363DF221134E9BE32B6B855FB76E15B5C91CC6C3F750AEED71071A0803987CA7F35882AC31413A6001A6023C0A183961722B6EBBA16F5577D95BEA2C5AB446AC8E57ACC96281A07599A8D335C2C12388BB0CB9F8633CD2251C8A7563B396072D0CF6E7B8E3AF2192E5731341214C30708E128914C124973E759D4221F1735386B874905220C41FC731A22B9C665CEF0CC5353B799399905F0ACB549F13C6FA56FAE2907D0353FF2054ACCEC40310A2C4B62AAC3F392B014BA88FC90EB868693EAC83516336BAA601F600518FC820BC8B0E76C66DBF001BFA28B07E21ADC142C75111B9785AA2109A795AB792DE4CB7B6298A504200F8850D32CC44E54182761A1C9C9BA591A9FA6873A61025515B068099BB1E63751C5B887D283077F86B733E4344D13310CE12D22322F254A0E92779A87067D19C53C70DBB927E14E1F2892B5273949428EB4C70C49DA8AA7FB87048961DB4892A6F89F18F0BB69347B9575025A964047AC7BD2C7472838383A6072F8338B23AA07D6B7B221E18D4E3C62641916106694315A2FC5BB88C6D664667680DF556C3C046398A88328421F32ECB758BC64CF246815A25922021DCB67C995FC72CC6B46BF5CA9EF3998535AC5CFAB70AA54318F9532DCD138A4C03E2FF5024C52BB486BA7665B27610B822975C412331ED6C98E66721DAA1897936371113A4F17D96EA735A5CDC019809C3907C03FA950C00EBA9DFFC69A902151A39163F2931E1C0271D491562E0A87FDF7B7846C31151017EF08727DFB68F22A8585295659EA358CC1B85C9AB4D107413225B8259804B31850EB347E1FD37F5435617A7A07B15321CC204B1A6B7C30D67E91C088A458BEF5CB704E6B662189A9C0079E224A94E21502C0F1A4DFF6028EF6645CBA38C0C86EAF673E9B2613620BC216914A9781645FC48E33CB9EA06182637439F1D1A19FA50CFD3B5E2CB8310229B74ECBAEAD4B079D535521B8587A2995FA9B8C6694BE6E432343C97C16CA23BF53883E23CC38F10C38E54F5639B9FC0943A4F41CD0ACC8DB40CB12E644CB74B9D4B858F7D6767830B92381A42368476CF2602ADB9ED08B35FF5C4D1EA93C94AA75E218779825401D859902D19822E9820D86C7E57562795B89CDA97EBA773070BBC502884A6F437D7EA7A459C0764CD943E0B6A5B61B8358530459685E2842AE9AB867FA712172207E692A7AFFA872323779087547C3D8B89F368CE078ACECD55AAFD5305371A5BEF24FB255211B2169F4543927C845A3049F7A88513A682303960C2D12BC277656F15738C4368DEB70CFF2A32A1D179F4FDCA57812CEDB21B356E0AA63270788B510E58B4BF613473FE931DC80A9CB8BAFE63AAAC3913936C8A939C413CCA10A1277409250B5DA321EE5C24AD3D093C1C7095FBA34B81380E5DA561BC039E3A8C15FF3982A7938BC16446A3AB2679A50C2E5C1D1A08127DB4CEA30340B5589B2327988C97B78F003D1315DACB301520A11F9F0B4FB33CE7C0203FF11C6A66136C0AAB83928C145F4B968783B131281F2153925DC13AD133FCC5247B595CEF0F03FF0DA0A429C0DE9A54F66C03F1A616C7210B7ED3624FDD27E99F38472867A9283C6B294B0D7014CF9EB62F0D7B051B190F093450453C056081370B45F5EBC4C03808FBB5C6D8B659BD22612C2872DE9034B11C6AA6D356B2BACCEA0F909DA0C775969C12FD5BB0C8A9BED5172A9358E01C29D308636B5D668F5B2C9DEF1380BA23B5C84259D887D3DC4882702B41D99C72C800DD5B19935D7722610741A105C1D227C38C5665CD5A6DAAA991A9868499830C1697FA430BF4F95B03004126FAC283A167281E4B847EBA8487B0032914EDB0B67B1E320C25BAB50499378115CB07A9000E0156C9C93C1D90693B9C22623A3EB15618FA1C470481C4CF292B7462410D057C2E5851E08E31FD88AF2F84B0CF79A88DE834C1F17C7A5FA17D329CAA09BC32A138A2FB5B6072464172ABE0FD97E9EABF357C3FA5391D94A415B53ABD381C38C2CB5CFAFAC81B96A810AB749B61806B6D54C9F8CF4BF1BE0192423288F +ct = 7C87310316CC1AAE495EF575650D79BC38E091B72BF809E003C71ADFF6C4729139CE41CB1F669F1E1281F223781293E3D9AC647D16EA0D08402CC265F1F4C26D08B7D4651D88F2332BDB9F9F3B417AFE26A433BCE1E8A975D86B547E77E8D4189BD9E46F6F2842166D6389A5CD399E735686BDF4779991C1242E3BFEF69552D6282C476AC51EDA2C9D7A4E3100F8BC8FCDFC449EB57DA0F392CD889BCF45C337A84E48E3B83AD72C50C9D2905A4E22E59CC73AD7FE85D6BEA30550BA2BA5929A3847A9B78D886CA1B93E0C4C14DE5056360E7DD398CC271D96A7950F4C439526EAF8505A37C0DD6AB037885E48D8B66E9C3FB3C218D74AA7F31FCE3FCB58C2FBBCA23D78F994A4465907A6328C2E35D83259CE735CDEE26D516BE175C2BBD5E24616111FC7A3D95AE11D035AF9497BA41692A12900926E8FAA3A80A5349269D2786E4A1F9F57EA473C6173C2C88D6E4FF2371EA3FE8261C21C63D7E29AC72A2995762A378A45A9C8D811F2F92229967C3A7A409452F4EB01083FADD41A0948DE85363733B7C0349DD1FD4D231ACAB563CB5A908A19B819E579AC1A599F5B8135C2794B34A3314D1B8559961FA26E9396BAC778A6697363EF60A60158736C92F7C1BA912791AB962B327E6369C6EDACF69FC9AF49379387D5E8C4CADEEE9B3D5EEDC6919BE78A199DF3341F23678C6D657B5C65279484F18E4A9789B675085EDE2D55BD10311617649DED74918A752A44FF9361D7402EAF97128BED4147EF3CA81B159B304588D22802A2E05A0B2AC5031F9162FA524D28EF0381E166BB81FE396124C4247082EA6DD755F48D8B419BD6C52CAD8CA084CED3AEEA060642FFE0FC7E6C1630D056B449FFC1DA8E693F64925FC179938CF5283F6E3584EADC904338857396FE810F4F3175868578BC21608EDD7A8109AC5A8635FF8C4C3C6DA0C3C618CB2B3448E31E8414D16EA50BAF6A4564F686D12692BFE4AEFA5A0E57B84C55589D0B4CEB2F358AC33254453E001846A2C7C299DED877A07A28D0DB5E7A5E6D41C246775F951CF114F3CE64AD839681C17E995CA123CF2A24006400B4969B99E75D066B774FE4E994828FF84F171D9C618FD2D5A01EF845379831051C84A734C40871CF53935FF8AD0954902C017E8C323DD751CCF14BC50638A31629E4FA70EA6E912B6A6422AC19442832E8A051E7019A820BC6AB81CB9715998F34014DF73DB8F62F5957D53D1FD3192D9F76CB8E2587DC9A1738207F956F6BC706C3B3B7DB0C578D220F30EF2925A7E35CE01059BE2B8AC6561EA7AC253D5F50706515947771C052B015F61FF347ECDFAA1C895AF5BC7E8DC7463A301221AF6C95EB65B8FCD77B1CB4577F5053E34766631E75A0A320EC678ECAFEF5084E514EB48AB6490658492BDA71D6ACEC26488D29DFE809F576FD7F5F38ECB4918657E4C8F25FA09932F435F211E41B207A61D60C9BECFD50FA6D498DE3F4647D6AA922D5A82B33CE96399B67FBE369DA888179F95F655122E0028512944875308EDE8CE87E67A6 +ss = 52E36F81DD9A23FB9BB2363C31B715106D38520A31A3304CF754A9432E757224 + +count = 93 +seed = 92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2 +generateEntropy = 32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +encapEntropyPreHash = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +pk = 2DF84A0272C13DA5A495942BA848AC92D302A98A3E55937B8B1B49FE588BE32A540EC90B5CEBBD90D1B80DD24D32EB85FC041A7CA307E522B8C5FA9C85BC258C8ABB9F2678D29569F313A1E660A2454730261A6766945CE42C140E5181C68461EAF12D1F185C358233B9BB4902FC5089F851BAC83CE3F07BD7B185EF08626D7029129703334084375BC5BA27BA023CA6722319A916BAAD529715661E3A413C8137CBBB206E313906DF1CA77CBA73E5499F54FC53047741AF2341D5623278F76131AB47AF10BB4DEA8F493B6C0E4829ECF4C425A46D21755E93E5A80D0A927739848695BE93444A98A45D02D1131E493DA5A0A1117B41D4AB3DB35A7A2E95C6055BA70EF159E7AA0DD5452598F91477087BEF1396ACD48E747B962205AF92EB99FAA809B4BC47EB93BFD3860102D4ADCBFC39BE80024550656C42785A6788C7A851B107823A02A3DAA4CAF25097F1F9AFB29416DBB360C4A824E3CA2A30E19F94B805DE181D0A028E685C378DCC225112899A6B79869109CA4B094909B21042C179C6CDEB22564CFB6F89135022FCA3028CAF7ABAB19A4045DD5A60721C6BB47AC53E40CD932511F2E5473D3B4CEEB44BE1A00E090A886D345B13A58620C49CA0893F23058412054AE5069C1014361CFB0379C2215F330ABC647114A3C597765FD014C64C8C1B1B45B3BD02BE9D5A55B0CACFCE297581FB48FE0256F4C0CFC84AAE1C542F36730E5F10795C72157C653210686801210418B549A7398CA8B7C70ED007CB153D2A55178AE23A5B095EE2D116B9F3A1A9F19FAEC40D75256CDF76AB8E393210D3AFAE375A7BC384799A6EFC5B76F287499C6701368B8DDC219A9F2295E6E01D22C4A50BD08179A08044B702FFD786FAA088F867B63B951A92751CB0F839CD554A83745444C3BB88D3609A9A4BC2E0BC73108A71CC7534217872539BD6E942CD36A09AA0374A3894D279A1F7C38A56E7C0298948C330B8C3A5B6AEC3BBDBB87384677ADA78017564A7FE40C2983A9ED3ACBCE5E29E3A78502952A9540A44975572A1512B1D4284D9BB528E538F43A15216F4B4F2A5208E06C43896A19C416C99C3B677564975948468792EDB6532F9B0567F407FC6D6C302766C6D1373BF78A18896188CF20CCEC39632269F6A193DE5EC5DCA85CAD6BC79023C691D5682643B6F314827E0B24539E2AA91123B3FE42308F041DFB6C876D079D60A3EF5735AB8A36ABAE34F4A12729BE4A00F753C7E4699572375E6C7B037948684206C08A27EC12B26F7349CDACC3559AC29D5CBC35C310870597E391AC4E4C02991096F37492083BC1C43304BC3D5925843622494C735942DAC8904CF195387ECCDCFCC8A999B6D1B744A542359E6B167F91022BE1660BBD218A6A6861AA17C57152552172F38B43D5281956CAA77DAF9B94CF60CBF08CD9D9B4C1EDB6C4A17BAE3B36800891910C280C3E7CBF4AA11F33A7C70E3B419C2B2B9A64709C31878F913FB934D77B4C36E329BA98B44F394631E0A289042061F527D67446D6AB55CE7B43EE1080FBAE67085A2A03B36CC9AD9B5B546156C3C5A79B092A67912A19575F6B5546397C15AE334B451C3D919422F28B70727C75FB631A2AB012BD5971B5B2B75F80E14BEC0494BAEAE3C7AE947BD69827E1FB86388052C3BF3F8B4CD25A568 +sk = B27CA8D40A1CF8AAC1A62553FF541EF56B4B4E352E38C0AE8C2CB2240C2D2525ADC52B1953A1C239E3ADD71B5F7693196875BABF8B31EDC528F3B320E6569997639F1C9B5279C38D5DDB3B691B0228AC4480D45077DB55BAC24285C5820C49BE25632C4AAAA23ED84E10A1256D9CCA9B584D423A9FD37276CBFC5953C9284A4097BF71706069AC413AB857C64EBD179EB75496170778AFD74180D877C9D69E1956450B1289948323F64227960A0B24B442E78C551C5B35E89B34B018B80BD094F7594365195F44C05BACBB2E0A976A86559BD6B23D220B5C900375C6B188FB353C3B064CED669BEE6751D5D22659EB89900A92B7BA84EAB58B7E95CB8495191CA0491EF75A3ABB9469A7939796C2F8C15CA22283235852B0A96DAEC403C5C057B5AC91D09CB16E01BB0D078170E0CE9596B913E953C5AA67BD8A2FF20C0261CA814F334244886DAA0694368293FD858E14E23D13E66AC89A58867574804786C4C48D2FC003336C002A7776217ACFE7084588455A0A85B8AA51C33E99B1CDB75541855577911DB00475DF42168E7A21EFE57402303DFE37AB5BF10200395550A1639DA2AA8E358748EC38946BBD3DFC27DEB08F4F017ABE33A2DF3B9B96CAC0E8C261E487CFFF31A1484CA5E04036797CB4FC87AE6CC72F9EC0835AE2B160B425ACFA8B75236D92870E4D43BFA7EA5C98827F95DB6DD4200068650E3D8812DE827C3F660CF8049933DAA52793AC10F57AD8F2A7445927CA6022D5A485F9424662A175B2A6349B248AAF4853BE709D42228C3CE3B13990794B9698869842B81649CBD9482C2435886441ED9A7927384371D02005A514717ABEC398BD183B321134A4DE85A1FC9B72F7268CCAFBAE289C15DCEC18BC26B81EC43C6B8A3919625165617D60C33F1E6B04CD5492414A15BBCA5CE84284557C9CB481A951FA5DF2E444E2C20969F38284E60FF15B0EE707115880BC6D3834230C7D22C7CD69229D1EEA957F58B2D47B11CA97C926070CF1C1934EF83F5A26241C7C73959C8A0501C2C1C70671987243635FEA56CE6EE292B1D6AA26C4CDDFAA1751520FC3218E7E20C13C6A1DF4835C7D6C0BA45923CEB2AB40FA7FE3732E47AB652309CDF28091D8D86308B73F90D86995220ACDD9C544C95FCD24A77E7C90F2F15E52AAB595E11B1AC0799A3CA95E0644771420AEDC777A9048FA89CE94780C8F2B903548BD46A2C22E453B68736F5CCA6C35EBB027C0C7035678F7F69A9CA02FBB4B23746759660251F6757BE3AA1767D7280AA75B60A7A0CC892F70F67CDA886CFCABB451A36023C688D7AB5E0A3B5BC88514CED3597A594D0E28C7AA25859E57BE9FB12691C047A8A7373FE1695AE742027A8F5630CB2776721815742C66A4BA0C7E7E8B8281144B80288CC7296BFC8625A2CB995B548D48294B2FBCA97D375B91203392CC27FE835F62DB97B14739F6C8B1880A53DDD388E2636F866416817A110258A098D9AF4458A64C68654E97099746B9B9E23ADAB5653970C00719B54E4A2D2092CD7BD62AD9317357E35224184A4E24B4A58014F666B33E1530365070B73AA6DA432D04F2588F34AC1CB3B3F7FB4AB200B459966FAFC689CC40ADAD0C26108859A2943E2DF84A0272C13DA5A495942BA848AC92D302A98A3E55937B8B1B49FE588BE32A540EC90B5CEBBD90D1B80DD24D32EB85FC041A7CA307E522B8C5FA9C85BC258C8ABB9F2678D29569F313A1E660A2454730261A6766945CE42C140E5181C68461EAF12D1F185C358233B9BB4902FC5089F851BAC83CE3F07BD7B185EF08626D7029129703334084375BC5BA27BA023CA6722319A916BAAD529715661E3A413C8137CBBB206E313906DF1CA77CBA73E5499F54FC53047741AF2341D5623278F76131AB47AF10BB4DEA8F493B6C0E4829ECF4C425A46D21755E93E5A80D0A927739848695BE93444A98A45D02D1131E493DA5A0A1117B41D4AB3DB35A7A2E95C6055BA70EF159E7AA0DD5452598F91477087BEF1396ACD48E747B962205AF92EB99FAA809B4BC47EB93BFD3860102D4ADCBFC39BE80024550656C42785A6788C7A851B107823A02A3DAA4CAF25097F1F9AFB29416DBB360C4A824E3CA2A30E19F94B805DE181D0A028E685C378DCC225112899A6B79869109CA4B094909B21042C179C6CDEB22564CFB6F89135022FCA3028CAF7ABAB19A4045DD5A60721C6BB47AC53E40CD932511F2E5473D3B4CEEB44BE1A00E090A886D345B13A58620C49CA0893F23058412054AE5069C1014361CFB0379C2215F330ABC647114A3C597765FD014C64C8C1B1B45B3BD02BE9D5A55B0CACFCE297581FB48FE0256F4C0CFC84AAE1C542F36730E5F10795C72157C653210686801210418B549A7398CA8B7C70ED007CB153D2A55178AE23A5B095EE2D116B9F3A1A9F19FAEC40D75256CDF76AB8E393210D3AFAE375A7BC384799A6EFC5B76F287499C6701368B8DDC219A9F2295E6E01D22C4A50BD08179A08044B702FFD786FAA088F867B63B951A92751CB0F839CD554A83745444C3BB88D3609A9A4BC2E0BC73108A71CC7534217872539BD6E942CD36A09AA0374A3894D279A1F7C38A56E7C0298948C330B8C3A5B6AEC3BBDBB87384677ADA78017564A7FE40C2983A9ED3ACBCE5E29E3A78502952A9540A44975572A1512B1D4284D9BB528E538F43A15216F4B4F2A5208E06C43896A19C416C99C3B677564975948468792EDB6532F9B0567F407FC6D6C302766C6D1373BF78A18896188CF20CCEC39632269F6A193DE5EC5DCA85CAD6BC79023C691D5682643B6F314827E0B24539E2AA91123B3FE42308F041DFB6C876D079D60A3EF5735AB8A36ABAE34F4A12729BE4A00F753C7E4699572375E6C7B037948684206C08A27EC12B26F7349CDACC3559AC29D5CBC35C310870597E391AC4E4C02991096F37492083BC1C43304BC3D5925843622494C735942DAC8904CF195387ECCDCFCC8A999B6D1B744A542359E6B167F91022BE1660BBD218A6A6861AA17C57152552172F38B43D5281956CAA77DAF9B94CF60CBF08CD9D9B4C1EDB6C4A17BAE3B36800891910C280C3E7CBF4AA11F33A7C70E3B419C2B2B9A64709C31878F913FB934D77B4C36E329BA98B44F394631E0A289042061F527D67446D6AB55CE7B43EE1080FBAE67085A2A03B36CC9AD9B5B546156C3C5A79B092A67912A19575F6B5546397C15AE334B451C3D919422F28B70727C75FB631A2AB012BD5971B5B2B75F80E14BEC0494BAEAE3C7AE947BD69827E1FB86388052C3BF3F8B4CD25A5687EF43A72EF04766F1E899D25C9A005009C788B5FAF985123CFB3FB97975DE26DC06C5BEF7B6508409DAF847A64C8D30D0974FD3BA7476DC76C46B458A036D884 +ct = 4C5CE3680E598066FFE1EE7645E55CED8C9A55B6902A491AEB9B6447F58B6184343638F13F4F79D067A0A8A4F10CA355188FDE778B848886E2F38979B5AEF4F14DD0B47E7A95AE839F6A1945D9B32D830189F3994C43DE711F71E8439BCF957B62A8F97CD869EE551D167B4C97E209B972E175947E7C5423EA86B5FF5D4004BBEA6163EE2858FDC9D8A04180D01AEE7E75B8616BD1E37EF33DB050FF02674C3D9C58AF7C1A76D79F4940E29B3DD1365C8259B2DA36E8B8A7D05887BFD3E145E8C78F01CDB63FEDF457A1AF4746828734F23B947F68D217E3FAD14D7CF15B26651915C371D3CD4C58094F15DABD0013E7878EB8ACAAB33EFDD47B2B20688A85A3F92C6A4D90F6045127A17AF0F8643B064A4A30A983F7DDDCE4D8893A3F964578D0529113D9D248E09A41792D4053B8B04942E866AD0DE54F8FE31B64024E647EAB8A10C87526899C6FCE476314ACA7B9B5E2F809721D2660DCDF9FBA5734714592BE7157ED459BFA0500B94242C48E2EFAA774E0F78B0EFEE997658CC82C2DFC8C686C3406A6D997296F2FD3281D3E44750DEBA5B22CBCF7E45BA3663F2909A643838C9E7D5FFDA9AB840C9A0AF6D6FE29BE8A7615D896D8879EC16BCB9999559A645627553BF231FAA4344F6258FC4679C790668D09AB7393CDE99170A770E3BC4491C35F22BC7234C346191E09CAC7CE819B8E43DA70880BD3563622196D860DB3FD4B1E1E814660A024EDC779BDEB38CB686318EE950AAF42AA3B0042716D5365A102C5FEA90A7C0DBE71CEF891F12CA3D20F0A35F7D59E8EC5B35972FDB474D52D780C54B5C79D1C165DB237AC235528A42B21E3D667968418019AFE9F68F44D46DC96EB87A7DA38F2B0B943C9C6C2E87C724C99C65E5CCA40D6C85E32778CE1065F65C95795E0F1ABE400A4C78F22303D8ED54F9BE517CE2EEAE1AE6DBC04E9604DE79952DC74758027C616ACB8F586EE0F7BB7274D3E1E147E27039A44E3C1E0A5A874BB0E70A60F897AAE005701DAE3A9696652869F541EE178EAB5118D3115C923321BD28F9D6358FA012633076754110877C00376C5CCD57E6917DF937AF1C6F449993088D01993E4B470E98CF8F42F7A81120D175CA4CFAF063F76950D2E75046AFE842BDC15FE4CDB69369CC112050B62369D4820C97F407D8355CEE5D8C4B682E7D184F6FA02992BAE0FBBD2ABDAABFF5BA49F4571FED93789E52ACE387AD29A7A6EB8C0FFAB868A4542A42C1B35FD3D42E426714C01F82C8B11D77D768CB5908E60934678140524922EE339D3783C912151EAB2F051C1E61EEA79148F442FB7715855A0C9D6B857412D5CC3526584131180EC763AFF11813EB16446E876F48A25B8FE13EFB071991FF1DEF484AA00A976C4CA8D65B4AF8AB6D59EEB6957932F218DACE7BA7D57D402A9EDA506220A22F03BB70CB60134BC3334B005AAA26A7EA14808F13DCB1EB11BB40DF9A8CAA714A5F0B076F1C64BEF4A0607B174406155E77E531307EB8C5FE2A53D1BE40301EC59AA2CD995FFD5E55708 +ss = D072CB81AFF4AA5712E56F0E9567DD89F2B03488735BA4751A7F0DF1C786402A + +count = 94 +seed = BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7 +generateEntropy = 6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +encapEntropyPreHash = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +pk = FED53D194419C06B92E51498AC2601869A1024EB0370CA3A420C48A765A5B99BAB88A759251CB83259A628603C54A831AC0147F3A97B8329474258B7BD6067476605A2B2B8311252FE54565C865E2DD96EA9E43B23121C27AB02C348310ACC38D9D583B0D8105DC87896C238069C689027910F9BCB5D29AEEBF57C2B9C78F76866768C0699C6BF743C0B43108C128A5277F39B32C351926369FB8754CD0197EB9AB602F391C4BA564BE2C3423005266229A10B21D31A7CC3D40C2E7192CB6628AFA692D3E75AACE66E7BB1169893C8EE45BDA5560E7F79C711D32D52C0C783EB40BF8977C3063CB114B6368A8D1486A86CB108D146A648E080751440F4D8087116701987C328D8547D0573F8C03D321AC07138A60954297CD832DFB989FD99ABA8B213E7501CB3D25B384C023F66776EFA3AD4981037A54400729634A782ADFC24404BBB4F2405A27A8500CD79E8521DAEE48848E485F53A28DE91089D849EBFB54D97D0CFB3CBA46A27438F426EEA1A0122F2180630864AE46CC5F3A828725CAE89331D540B5B3633EEBC0228000D75908F21277104D7816F56854C3289AD1A5C72C1655830089CFB9C90B1306724CB2828BE679B989A3565758B058AE983C1EA9B71F10553795537D454EED50F50A40274592AE165C846D85527E479E3FA8D8865047BF68D200287C0A5B8A6A78C4769BB3A795979B774713A522DBB723F3628F2F4126B639E3B4C5C4B076D321A208A123D82852AA0DB6FF8457E745B6B710B396C8106E635A379E22C59F17DF7B7070EAAB38D5448E4AB67E6B21078D5B9F9979C6D7365CD1423CEF6B4C2B186AC6B792EF9351B6040F423CA22E7A1455A0473273E3B53B92A132D7C44556477907FB41F981A06CAC9BEEB9655FE90C4FE93CC33337D78294F7C128FFEE82B0D4211E550342C599C9932A201F3CB8BB253A0559FD667A3D2CB46A4936F5CF9C4D0D105880A446066AE06841E12F259E4E6220D932633F77F9A6B463E180778D53C37E0BF423717F4D476ECAB6BFBDA7E461AC3CC9806FF4B38FB80C0AC9B0DCEF56E9B27881D1AA0892657B12A913A8AB84037A6C78399F53816D79C6A1FB40F1CE200334A7E74760999F8A0294C3029BB23EE0CB81700B95BA20140CC5DE537ACA62C9808240E74D508A93263EB14B7D202A31DDC2147747192BA1F38932538241AD1DB35CAA40097393038957B64E716D4CB3675AA9EA46257BF55A6D1FBC2C356B020073E16EBCBDDB3692515BE92DBA54CB62C702165C74864C3A7CE67D8AF92EB78496C4E8EB78B55DB7963B016A252A85E655C95936D6006BC07BA6250E458A387BD7BB43A3F5A16CD8733B66565377C1A74D5488C1A0DBFD7A6DFB474EAF29FA80AADC83267D0B98EB7A8AD3AEABA977A0A5E55B8937AB68E385F94DB13FBC6C26BC23B0B8BA331A578B99B493D875F206C278A3B4F63E156FD386FC13104D6DC96AE9BB3055481B846183DE71ECA09273E58C466EA225B1824246C799AB8B045FB844572882299BD6F1B2787E1094BCA102FB20E0A274257062385DAC60F37A15B0496ED23C465A3BA46BCC0BA9B5B78C93B45CAC0151687859B155AD62A8539CC6B872AEED63847CA64797460FF5F477504DF1B1894FEE3E6BBF8218590936E0102DCE8ADF459D590355576E1 +sk = 2735BC066A2488726C89432E56452ACB24A2A5407522988C0732CE072128C8D5147C42988F94A8516C77873858394A2BEF65B87741C5B9691B6DB84E3B1B2B2F851B1305832E4210E5D05710A5BB7195B8BEE0CBA9B5BA21BA57B962A280565AABE1C9015635CF1A7121A8581FA0A78AB26FC82838B6A405C6FA5D46469136CCCC34930664240915BA5C86E67ED9E73F4B123233C92D73BC05408005DCD6CFD62635C3026C990753C55CA8DD385A29B1C79FDB97C0B4CC8F26B28BA573B5194D6BCC065F5B97DF702009C43A65ECCF452447AF91200EF68F18CAC25E5C71E62A39FD7A26C6B64B47E29D1E4084801599ABA838A3808ED83454B506965507CC6D0B34BB139300D1014168A79D5707C74BBC7B980461249FC31734DC384C9DAC4EA6EB4701402084719593B62AAE53C8D55719945975CFD25BFF31C886640FEC37CAB3942676C840A453C6751CAF16A4743495BCDE6528A942A47E7C2D6499B2A872A76E928EF4B0AABBB21604F33231235A7CB47C96D9C976A2AAD533A06A24024AD0925007984D99ABA3AA8168A8AC92F662348686F756BDC1A23F8537545D13AE9F657CAA801788C9368864A05F40AF22E33E10705741F06EF577CADE6CCBF1D01065565A5B13284690BF611093E45684D6C69FC0F548AF852248DB6A6E86A2A907C95CE0053FD942A92B024DD18803474B03F73FC022912257454C008D137C5E8404379DB2719581AF17108A03F58DEA58892912C5FAB701D28CA845068761F6BAB69BBB75584F7D289DD921AB30379248C91106A784738B17CF0044418BB9CE34BCD913BB26D04CA04896109A255A39BEBA1A2B58490862409E473CA623933AC14C90F64CC74AF396C3186917061B5C8C28F3E8B694535FC2C73AF9843031C19166D2C8A3A76A2ABA45ECA36321BA367BD5B176B5C7B8D7B7192C95CF2803E2C3CA5D585C4EA63009C7B850F08759C278F1027C59499526A8B2E494203197A9304022FA0C4E47A3A6FBD8BC59A7C1312A6D19D3063E8078B1A1BFF964AF48151E4CD3CD87F49BBBE01AFA3A5BF46A7F9BC97DE729285AF35A6A9168683658EE37BA6D9499CBAA8CB44C93BEB287EF7CC7B1EB6491154C14FC2027AB49316B70B8237A546090C9687CC70CBFB82208A7F61F63AAC1A42961568407343A050B1048967C5334F3542860249FF9C2FAC8639EF8C125D0B9FD537FCA93C1006A77499658C0286267B910C10B12A6136152BCBC03E782C41B1FE94A000CD974A3A9ADE3A3B8B4BB8ED8B403683AB4EA3B84B84C4825F61F99D72EACD894337523C6B6AF765BCC99393213938D66B18B2B168D6C73C2EACC42AD22255CD3AC6D75200111C0A6076F02F906B1C96213E80310B8752B1B619E72366F9A0BA4283520333EBF8693F93A7FD6C3560058A8D16CB50B585B3D519E4263B050259A9A0A8823E3CADCD0B81C1CA53820323A9539133C68B0A6CAC1FC834B808D9375431F961FE3233C49FC9E88EA1ED0A068A271B502C0A0376A1309F86013B4947BB671C1B048C0905C8CE16D8035C7C05B9CB8755C7D7B6DB2907DACC5A91B61B666837F209075E8AC5B86444B49AC878F9B2E18D42E0F791AB7CB7C973CA8E0437F158889FED53D194419C06B92E51498AC2601869A1024EB0370CA3A420C48A765A5B99BAB88A759251CB83259A628603C54A831AC0147F3A97B8329474258B7BD6067476605A2B2B8311252FE54565C865E2DD96EA9E43B23121C27AB02C348310ACC38D9D583B0D8105DC87896C238069C689027910F9BCB5D29AEEBF57C2B9C78F76866768C0699C6BF743C0B43108C128A5277F39B32C351926369FB8754CD0197EB9AB602F391C4BA564BE2C3423005266229A10B21D31A7CC3D40C2E7192CB6628AFA692D3E75AACE66E7BB1169893C8EE45BDA5560E7F79C711D32D52C0C783EB40BF8977C3063CB114B6368A8D1486A86CB108D146A648E080751440F4D8087116701987C328D8547D0573F8C03D321AC07138A60954297CD832DFB989FD99ABA8B213E7501CB3D25B384C023F66776EFA3AD4981037A54400729634A782ADFC24404BBB4F2405A27A8500CD79E8521DAEE48848E485F53A28DE91089D849EBFB54D97D0CFB3CBA46A27438F426EEA1A0122F2180630864AE46CC5F3A828725CAE89331D540B5B3633EEBC0228000D75908F21277104D7816F56854C3289AD1A5C72C1655830089CFB9C90B1306724CB2828BE679B989A3565758B058AE983C1EA9B71F10553795537D454EED50F50A40274592AE165C846D85527E479E3FA8D8865047BF68D200287C0A5B8A6A78C4769BB3A795979B774713A522DBB723F3628F2F4126B639E3B4C5C4B076D321A208A123D82852AA0DB6FF8457E745B6B710B396C8106E635A379E22C59F17DF7B7070EAAB38D5448E4AB67E6B21078D5B9F9979C6D7365CD1423CEF6B4C2B186AC6B792EF9351B6040F423CA22E7A1455A0473273E3B53B92A132D7C44556477907FB41F981A06CAC9BEEB9655FE90C4FE93CC33337D78294F7C128FFEE82B0D4211E550342C599C9932A201F3CB8BB253A0559FD667A3D2CB46A4936F5CF9C4D0D105880A446066AE06841E12F259E4E6220D932633F77F9A6B463E180778D53C37E0BF423717F4D476ECAB6BFBDA7E461AC3CC9806FF4B38FB80C0AC9B0DCEF56E9B27881D1AA0892657B12A913A8AB84037A6C78399F53816D79C6A1FB40F1CE200334A7E74760999F8A0294C3029BB23EE0CB81700B95BA20140CC5DE537ACA62C9808240E74D508A93263EB14B7D202A31DDC2147747192BA1F38932538241AD1DB35CAA40097393038957B64E716D4CB3675AA9EA46257BF55A6D1FBC2C356B020073E16EBCBDDB3692515BE92DBA54CB62C702165C74864C3A7CE67D8AF92EB78496C4E8EB78B55DB7963B016A252A85E655C95936D6006BC07BA6250E458A387BD7BB43A3F5A16CD8733B66565377C1A74D5488C1A0DBFD7A6DFB474EAF29FA80AADC83267D0B98EB7A8AD3AEABA977A0A5E55B8937AB68E385F94DB13FBC6C26BC23B0B8BA331A578B99B493D875F206C278A3B4F63E156FD386FC13104D6DC96AE9BB3055481B846183DE71ECA09273E58C466EA225B1824246C799AB8B045FB844572882299BD6F1B2787E1094BCA102FB20E0A274257062385DAC60F37A15B0496ED23C465A3BA46BCC0BA9B5B78C93B45CAC0151687859B155AD62A8539CC6B872AEED63847CA64797460FF5F477504DF1B1894FEE3E6BBF8218590936E0102DCE8ADF459D590355576E12C0DB43F39B672B2CD912F907CF76A0F6FDA925EB2D205546431BE0B37B204114F797C007E4061F95C7D56CFC7EE5C49E849DDE3FEA8F25E7876DF2A18515C34 +ct = BAFB19B80A5CE997C3664CB158299C969C9020D74B644EA41906922A18329F70271FEA4912E7A67335279F58CB3E5E4B7BD7FE3C4A18327BE182BEF8D989E13CF8CC43955E9F6BFB3D4A2C8AD71DC01BF30C34718D01D5D4460C3F7F85E881ABC66E483F8406ABA076C08F6BA3C796945D4E286E9ED09E8B64204FED1354A33EAB64A60EEAC0296357E5AE0058FD67FDA21B0A6DB5029732F86E9C9B92F7D3B5380BC601A5FF35A037862BDE3A399D27E6119F0C43CC8CF852C522EEF46B4867753684E30B27F4D98FE039F203164855CFF6315769BE970D0AAACD411D35679B33BD68A852F836374921C99BCE48C782321E68B16DC964463732ED2BC4002757C7587CC3C780DB57BC7F1BF936A6F685E0F82DEF692568B99DDCB49A8376F2774F2E77F7DE0D188258C4E1BBD0652BE82112371D92EB01D8C38C9A84E5237AB8F6A333642B2A86C9DE4993703428104F76F8BCA911135C78101DEA18F0929F6A00B0F07854E814764F15832F18F60B6F25262BD448453E51686775A824FF5C743B811625FCDB7503E0834C79596B066B6EE2C3548CD6062AC11663E5497632280CFB8BB33B392C8747681A84831CB37799C4E42A25E16552354756CA0D41F19FCE9B3C9F8BAF18D05DAD841740B110F2C1B4E101F76158F307E9543E2015AE0924628996E652588E7EDADB51855ADB306CE70B1223EC445C425AD76D26E89514AB335CE2236E6A3AB1A7BA399B806609E5D22857F3ADF23DF5CFA3C4EDF0AC3EB60A00C27D7C02E0AA3851FB6EC063ECEF6E819AD52F92F260BAE7F83BB44BA8FAB3A608251C2B1DF90548F9DD2BEAC4FDDFB54FA10B251E42F3FC4FA9EB320BBC8AC34BBAF8DEE65BEF1C83EE499397F7930D61B4BED065D809A1F5E6E377C9563C660DD8DDEDA94058861B4875504DAC970EF8097EB7A75822D5EB139D10159D6007CCEB08A8EA28BAA27F78BF60E825353C5AF62F2DEC4AC0E7876A004DCDB4F12854EFF4013166053B9108F5439AF99FAD00C61169BACD84876956E53F1C0267B6E2985DAA07E34BF852947C247450A6AB3BC1820C52BB3AC9550BE7AADA0F8AA692806DC57A748F2C355555C5C58BFEF181E7277DA1C25CCE4B995E6B8A90833AABCCE74E7DE925A2A2C888930D052B9541908472C79E7A5B8E9E08E4CD3DCE557B35E34D94A741121AF0A7DF97131567393826F86A7BC0B785965C5BE0DA83FE4357D2A36E57EB1B1DDF651CF7EA1497563F4CFA4BA171DC8343A3FB549931479DD581FF018B5B10B9E1CB529CA248C00EC45B3F36C1DE804254F54C9B68A328319B59555FF57D832B3F9C047F2D343289582099685AAD6BF96FB956334DBFA7E86589D8D643780C431434F64411CFB85E9898288DF9207C7B38798CF8C68DF372C2A6BE4C11CA29D29CAED09345BFE47071AA801758331B37F658DB6E7EC1408A43486B772807646E5186A40E73EB875DB09DABF293AF7083878248306E2318C72B6E0843F852CEF164446A25481ECE7432B974A0C240CA35DF4AFFDC +ss = DA1085CBC7452CF2AC98CA36631C6EBCFFF02E60485F9E807CDB3DB77BC92243 + +count = 95 +seed = 121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F +generateEntropy = 527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +encapEntropyPreHash = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +pk = A0E473A9D639B1299251B46D07C79C0DF1CEB995A968B5B707B760D8BCB120F6226EF5B742F34548902A7C73338A8CBF8D6B02A83470874B1EC5845DCFD3A4067C420F8485FAE1286A23ADB7373B9217C6DC173748870BFD164A16D62A3A6608F5E2B7FE78B92364A4B821967DB45AE29AA1B11C0CD67CB4299B32D263AAD7A26EEB3A69BA56790FD806ABE3935D82487AEC3205A856B4981E7F53B8F82A30D13C1B725B1418607B6619B0E8A8870BBA6070E33545730182FB5F6F9938AB2CA68C50719FDB472A88384EF210B0C22785367DEDFC840979AB758479506064B7971426D70AF9A95E7D585DC8B67D4FFC2082BC45A4FA9B4FB9541493C3DFB88FCA757ECCB50F1A9CCED9C046F37062E3879E13958BCF063041E858810B057680276D2CA12A307F511217FD626561587617674319382A4A00CE5E3BCFC5ECB5B3816133910650A469AC663F7A4A742DDB87C4E5BE636213880C246370B1CBB8ADAAB6BB7E1185E1F95C945BB001A0210CF56F326B35051B8DBE85245F9BC6D973B39AFB3A3B961501862B4CAABD0D55693C201390F48FB7511990571985764BE7373A7FC4BBD5E82B31F52494B15B6C2C8B5B593182028BD7AC7A40FB446EA756463C396DE29D0FDBA2569B9001E169F7C824C8A42D313A15B682BD52004867837344324E2F91A06A4C9F7CA447D6291635257CB0934E015C1937F732C1BBA2C13591CCF4ADD16960B2303476000D984A8FC8036772C3B7C5721261387AE535129A7921A1711C98103161A95EBE16C0E0A28555DC3598CAC2D701A98CA249801A4BB10379A5C29A1932ACB6F6C3D040639FA98FA7297C6D453E35587488576DB9BB2F9D1C37F8260CBA3BA90E4B779867AD97DB03FF005ECFE3470D2C25D54105CA287A9E0C039C2A2B71A1CBC6260D59A268D60C05D61202EC336CB8285B41A043BF58949DF50DEF5937BEE1AF32D174E8FB463D03449BA747E92A79A1EAC8DED247AA0A50821A16AD4C9F533A0FA24684D452A71DF461AEE15CDDC2185551112682B4867C6CC27C43BF835432CCA184840B85886A5D970E9F515F7F97151410C401E9BAADF41CE2B8642313C295D28587A327C41C24DA18967A6426663642DCF389C50892D6847718365CBBBB80723C1397B90447B197842C96A141BF6CD317BF12BB64C664FD237E886A9F793313AAB15F668C91C71149C4B90B35B147F7C34B8AB6948799897855B22283050B113D64A60AAC739948844A9F99C448D21C414425D77560670C298F493D891128AB1665D8141D2B1C8E67950A68255B7F9376332B1CD7C6630AC05AE7C127FA7ACC35E640E94285E78661B15B21685A36C889A8CC890CE53C36EF23C2F17CBD8C31351BEBA827949F8707A05324ABF05AA71857BCBE690405AB0030E648FCD3BFC0F2AE2C627E04F490BC3BA237059AB93085DE218029F056B0F57ABD342170F5B16DB069073A3C16BB1C0BDA5136952919B22AC477AC2489237BB0869656614E4AC248B003799C761B2BA5F2711B24A01419C88937DC4CE745ACC16C796E0123A4228EC623A2A4E059B80B72BEB1329C9204B6555B0A62C14DF0B19B4A157BCA985090B428DBA8587B53CA2714B2EC2A04D306B3CD5D09045252960A068412F1BD67B83A217049D0685EC3D63D691559A327B2 +sk = A680635121C694AC4672C809BB3B913E8CA2F659C756DB1D7BB2369F41AB4AC9B3F5141216F3C997B00DCDE37352D46463F371FEC14B26AAB239498D44975F787504815552E727329DD78428F5568B912C76B572AD9B3D335A9F5BC0283C76AEF8D81369A0CEB4523BDC4BB0607C29D9998962F76B217774D74A3453A61FF1F40F89A51365212F39A07E913824BF36B6DBF6C8934014DD8716E998A982B124AED8B082C3A2998708BC1C4733773B73E0BE315203E8E264A032797280CA0AB023A9D81FBF0565F491837CF031E219084B640EE8710589E05E1701870BDB7BF0B0BB539A0B3AB0028447110288C1D7D83F89578413A46B0B04406657B4E7E5A6D04BBB91055BECC8AB907CA9647C4B8B144045B6CABCB974A47A35308A23E9C9281C61C556EC148C9A663AD9518CEA36AAEC71B6995110FC01CB66B75E128478280FCD31A3416A12E28C15BA617574730437DA8BDFB86B58D88C789C4F9E23ADCEE53B170C6A0B80033AD52CFE1A155EA1A568F5B2EF77AB74878E0CE42A1F7C3C845713D17105AB2C91B83836E11B9858A66997B22E8A67682588CA78E6B6D736298EE34B100BCE61E0AD921A9F020A7032351DAED655D35B3659A96B32DB9E68D882FC986DA904408A98C469A84CD29CC999B2B071F84C921C585B9B3233C5BEDF82637BB1253A4B29B36B42B54751DC629A215656AA1890C0C56E0CB62A3C02252B771D72375A60374BF8D84552080E0D456579930B3F2A2A3B7913C031112FABACAEF75BB2DA5202D7671359282CB4707B52740D9CA06AB7034B48A292404D26B6CFD08C8B0DA61550044069F4CF27488C028001F2C29292840B60B321DE5CBDEF1CA216838091C3172ED26D141C957DD93BB6A59D9E883640D87A2A85605A9730DD5333843805374B58747C7262D5A65EF442D6843DEB731C943269B4A9BF00F39B4A3847840C1BF4B9907FD7B9A66C5DA724CEC467102F080D4D0BC519D0B2504A05F7207EDCE7398D009348F64267E01B0EC207780791942565AEB061BF03719D706F87953C4757A75A126EAD15C6C9447C02938C3B75A58AB25CE65A5CAA21898FA8050319880223899F5546E0D253DF7950691B86F8E3115438C3B80CC2E7A6178A96A0F38A0CC47394BE36C9B0721580D646A89B9327210D40728F4BC4ADBD8B130EECCCF528A5A09595F32C0F64E602F6898B8A4C82D79A8ED31C4172A7812C295C93841929B782B334490EEAA38C17CB4E77664306BC7B01726EC656E24311C51B0524C72F0745665D43073604C59EC88DF6FC9EE2F2A0476079BCFB735E562F57E2B0E1987A0220C98F0B4CDEBC70F93CA709C5C2FAC7098A7B866662ACCDF09C85974D7C88CE9AFB01F48276EE320D70C7C0E15950FC0775E13173B60555A470302D0A0047260E5CF85EA2F3C326968D3C308C15EB400B13BCAAA65EBF941EF59A069BA0BD3D00841B6124574303BA8C2BC9F90F107865882C18EBA462F6B09EAEE05796E43A8647C59C64B7A8DB9C0941299280AF728B872C303755B682A3EC10C5876F040543BBA028E870C02A4312AEE9CF2BD1302DF80BD0FACBD0765A778A7FA2D3A4C9675965D6799FC7BD4E28A4E2A53948790234F62BA0E473A9D639B1299251B46D07C79C0DF1CEB995A968B5B707B760D8BCB120F6226EF5B742F34548902A7C73338A8CBF8D6B02A83470874B1EC5845DCFD3A4067C420F8485FAE1286A23ADB7373B9217C6DC173748870BFD164A16D62A3A6608F5E2B7FE78B92364A4B821967DB45AE29AA1B11C0CD67CB4299B32D263AAD7A26EEB3A69BA56790FD806ABE3935D82487AEC3205A856B4981E7F53B8F82A30D13C1B725B1418607B6619B0E8A8870BBA6070E33545730182FB5F6F9938AB2CA68C50719FDB472A88384EF210B0C22785367DEDFC840979AB758479506064B7971426D70AF9A95E7D585DC8B67D4FFC2082BC45A4FA9B4FB9541493C3DFB88FCA757ECCB50F1A9CCED9C046F37062E3879E13958BCF063041E858810B057680276D2CA12A307F511217FD626561587617674319382A4A00CE5E3BCFC5ECB5B3816133910650A469AC663F7A4A742DDB87C4E5BE636213880C246370B1CBB8ADAAB6BB7E1185E1F95C945BB001A0210CF56F326B35051B8DBE85245F9BC6D973B39AFB3A3B961501862B4CAABD0D55693C201390F48FB7511990571985764BE7373A7FC4BBD5E82B31F52494B15B6C2C8B5B593182028BD7AC7A40FB446EA756463C396DE29D0FDBA2569B9001E169F7C824C8A42D313A15B682BD52004867837344324E2F91A06A4C9F7CA447D6291635257CB0934E015C1937F732C1BBA2C13591CCF4ADD16960B2303476000D984A8FC8036772C3B7C5721261387AE535129A7921A1711C98103161A95EBE16C0E0A28555DC3598CAC2D701A98CA249801A4BB10379A5C29A1932ACB6F6C3D040639FA98FA7297C6D453E35587488576DB9BB2F9D1C37F8260CBA3BA90E4B779867AD97DB03FF005ECFE3470D2C25D54105CA287A9E0C039C2A2B71A1CBC6260D59A268D60C05D61202EC336CB8285B41A043BF58949DF50DEF5937BEE1AF32D174E8FB463D03449BA747E92A79A1EAC8DED247AA0A50821A16AD4C9F533A0FA24684D452A71DF461AEE15CDDC2185551112682B4867C6CC27C43BF835432CCA184840B85886A5D970E9F515F7F97151410C401E9BAADF41CE2B8642313C295D28587A327C41C24DA18967A6426663642DCF389C50892D6847718365CBBBB80723C1397B90447B197842C96A141BF6CD317BF12BB64C664FD237E886A9F793313AAB15F668C91C71149C4B90B35B147F7C34B8AB6948799897855B22283050B113D64A60AAC739948844A9F99C448D21C414425D77560670C298F493D891128AB1665D8141D2B1C8E67950A68255B7F9376332B1CD7C6630AC05AE7C127FA7ACC35E640E94285E78661B15B21685A36C889A8CC890CE53C36EF23C2F17CBD8C31351BEBA827949F8707A05324ABF05AA71857BCBE690405AB0030E648FCD3BFC0F2AE2C627E04F490BC3BA237059AB93085DE218029F056B0F57ABD342170F5B16DB069073A3C16BB1C0BDA5136952919B22AC477AC2489237BB0869656614E4AC248B003799C761B2BA5F2711B24A01419C88937DC4CE745ACC16C796E0123A4228EC623A2A4E059B80B72BEB1329C9204B6555B0A62C14DF0B19B4A157BCA985090B428DBA8587B53CA2714B2EC2A04D306B3CD5D09045252960A068412F1BD67B83A217049D0685EC3D63D691559A327B2AAE8E61B905723FA092FB95B839F6DE3670C39CE0498C27B87D20C24E7F64E22E32D432B4F9F751BDE0496C580A181FFED762AA35454A02D3F1F47EE0394C89C +ct = 8F9648D01A9027F4E1AB3D988F096F3470D09707E288699141A14A78A88C95E1771E6E12B02BD13C2E99207B33F9AADD87C79715928CF9FD76956FC73C2A21D24AF756AC54F75ACCF2667AB9D8458380743A1609A7DA99A5FB521D1061C263964800096B930CE7D448AD1CA9BF48524892960A762B382A1EF36B4ECE3EBD9515EC7295692546891C10C53C6829AE866943E569F539FF1101B5F0B2AC7D1C94EEBAF6378B13BBC1C8A2B144A62A10D752A1F05DBF1A9CF7F1192FB7919CE51FD6CDCBD6BA26B6B8AD7FCAAAD17F3B96DDB8CB78CD0EB4E96958AD38D2FE9BB71A87547AA7CB0ED2AD6CDE695112E6379A333D135808DE697F7FEBE9C179F627F419689B2050E5DE6C87BAE3FDEA59124D39F06F264E2723683A092FB8382186F1737048026459D6E242C0E7FD386F6AE6C8B09FB6613F26745DA21F43FF145C83DEE40C927918C26E8C855038FA8F994790C799393EB031D3DB7F499138186CFF085F3669B45351CC0579299D1E37578D753E447EC2B161DC50373065D20B44712EB059040F72F98F51858E0A250A97409374EF7BD73D58798697B0FCFA35946933856CA5A0A964B7DCA6617EA2D35D16A8B83F536972BBA727BC3C16EE363B5B63CAE7C13AB11B4287568EE64229671DC45F06FEB3DBA8ECABCFC16FBCFFCFDCB4227EF4E705992CA8978A19D1190842A4099A21CE4F96814FEB88E094A69EA7B7BF0EEE9932A1C235AC2ADE53897D3D8BE0E4F02FA7F0CDA13C4EE78127F1FA8C611F50CA159DBD048E9D888234BE8D80B49324621F7980E490A13CA0C5CB8D4CFA07528E808839FB9A21FC167BAA489F3C96AD67B89FFDB4145F3FC9A827C2DB3588B0B348FB8F5F469315B7B89F5C25EDA806D921DEF1768029F99777ED29AD1031CD40EB1C12A92A8D2A130D2D0C1560598C430CB2CFD73E19E290EA864E80384359188D67A53A15A4F31DF7502BB3123BCE2614B87C82DECFD29C0264286A9641AF0EAE2A38E6CA1F065A9E619E3CF39C1158A4BC46A40EBE72536F4607372471D5D6D6CAE5E2FF6265B7BE9DD3B466C159D54FAFEAE8E3CC62ECFA7BD2D047C0E3E93D163D93C7EAD30CD0CB41B789546CF11DFE9306CCAFECB8519C08573268FE46DB18203F6C4CA916C4E1133D5422EB966F716622DBDCD7DB21834BB10BB36631AA2C50FA46D2909F0EEF33B3C62846267A9D5E7187623337950DA98496A703A5E9F7BEC4C2E1CCA8CEA8FFDA5BABE1BE1E612DF7E9625EFFEF36733097CDE4E88ABCF2B8878D3CD9A47C6F907ECDC63E87E89C6CCC6AF8CAB530DCCAF3597E33AF7DDD3814D9FFA5E90A335E31DD2ABCAAD72807AD5C6D89F6FCB1581AEC0F0BFBE7315CDB428D905795BACE3138178A8B1460C665398FD57295014F82C8630EACBBBB4C52A1D22E58FD028B5097758AD913922F6ECCFCFABD165D9959F29C2DFC6B4A548D6E75544D70BAAD0AD24D74DBE1E51EF9C9EA4AE3345B121AC8F0D041F359BC653987C4215EE7253FD0BC21384D0BA14630F5C049A398 +ss = ACA83F1DC628FA87B20133BED4C2EEE34B98021F295AB585DFDCEFC9E3C032F5 + +count = 96 +seed = B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420 +generateEntropy = ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +encapEntropyPreHash = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +pk = 4D960C98359F5719B20DCA6D1E2916F2829E73F79B55B468170B64F2F8B0C788796801C8EC244E1973C7E033B768414C55D43079B2711BDA630E678B184A70DD161C4DABBCB91C07FB634620D1450664A444E82D22A0A4F54AC6C7C02D74120B2CE205FE49A139B9C8194341F4295EF126B37F3B22E35792A8853B60EB3F7ED01314491C4451470870A5EA5B1D23442019BC1DEF547FB8935ECBEBA0833228B8D7BF2A4ACA52436A3F993F6164666EBB3C38317BF5B48CC7182C00D58D4A095D0FD4C60E4229E77803C4F38F22464C7A4259E45AC71E8CCDE6E5738DCC798777317F9847F8357DCE21B24AE462D0465F1D58203F3B8590D88DEB9C6DF4722A1420A9EA0813EC3777A6CB11CA0271292B6C662A870C292291164004299C82442A8DD5404E74CFBCB45175237AE5649F7136CB47B9C6C053203F265BAB420EEE2C95A5960F8A87C3333785E1B89FF841A6AA5AA964F3A853E512ACABB60E29C3A4810DF33830134C0E49BC5E1BA41B07B671E1BA6BFDA82576406E6DA854920A46914C8EA986B1D6A0328D4A450FC0CE698B9D16954AAA0C52B6F2B5FF7B5347E84C3AF403E9B31EC180238CD5AF96F5C6F0D3644AB51717F7255AD6551F44378294778937CC56B610680704BFB37E3CCC07C5276777E37F36623DEC8225388C3A5A2C7026EB902C63260CE27FFE657BCE34A47DB43667B9293E04AB9677B6FDB0B0A429A4435A9F5624628A2C07BBFA8AFED562BE4233019524E67CAE6F955226437433BC59835561C462071AC38058C145787C242D4B6DC055170675190882792EA49726DC8B2CB638763784D3C23E1791C93A55383A8C4B59643626F8948D228B670312893AB3CE5B123401B1B24432545889D4D124D2B846070C1663B87A3475C01ADC4F4DF286FC91C76B018C05B5A26A696DF86C4B1FBB2ED3050CC9B54CA2786839F854B9461655972FE21C3C98007A693A4D0B8AAFA3AB73F1C411DD283CCE59528477B6E089847CE6518F29B523602F80AC573618070BCA649EFB84FC3947D43B229E05682914C153809521EC9B7978A6BD667F59B18F1D986222DC9AB345AD2C7C7CC5799C15297C22C3734DF18A218C5BACB364C9136B8E055053567A1856C21B96A1A2723913C98CC364BBD1FC4EDEF37E1853C523727A6C677CA4C82AC4D49238E1B60C1531D1DC9835C4A96124A0011C09350353AAC4568A84293E8666F6016E56C38371489EDDBB3DF3E53E6767BD01E231EB122F13F59A83A35101844AB389954E8068F6D7128C738AC1774EDC6465EAE8CCBABCBB41271467C407D36928D9E3174C99665E3A9AF0FC1B2733925B254A3ABA050EC3925DABC511427C0B2930BCA63BA7629366C1BA620CC0D7090752157B5D70C098745E37DB7316056C7BB37C024226425107DA8BA0E9C30E2606752F31A017E50A0E10C05332677EC851EAE14F594A55D07392C23A962248CCEE1221FEB2C8F801860892B33EF2247B801E5FF55BA97675A71037FD133133840050B8B7914125E9D30165847319EB1E483005CA0BB8338B75EED618C47408D0260DDFB1527640A148F29E64F65FCAFC59A8715A8126830024767009BAD41A3385C0173BE51A35F3825843B59FE06B5FC03DC21F6D925B9F6D92FFF175C9DD625BFAF502B4E2870961858852 +sk = CF8293B02A9A6F579F51066BD6E51ABD270104634CFD482823102F2B63B18A8BB4F45A5AF4D8202523CC1779B44FD283860BD004307C399CA5D8EACADE156AF824A988F5AC6BB50EAFA6177A95B9752C922BD6A7C4265A6A88B11D0403E47127B1E80787742669E763929483393CAD6EF91F18143E9D2B7CD3E028C6F56B91768113259BCAB926A082A2A6185A1BF18656448A628258E21A3C6CCA23449B4F9483AE9D01BDD4BC674E06566300AD2A215809E547E2626F8D9437BAA727F3F05C31E85E4D34643148981BB6A82C3C75099A33A0E7528D45303D98223E1A4EF6536170F53A0C61004BEB75FA34B8AED5156E4A538269775808283CB0BA5282607D50661D2A626FAC2737C98CF33050353BB83E1C1136F1C26FE48D81973EB974AB1BA4B97C95C0DEE065523430CC06620DEBBA3DB92888497658BC5C64B98BE65AB2A0738F0750022B95A66C583354A63865B5237FE7098D279C53F731F3FCAE8689754194A7B888199B89761FD09FF75677B2C500D7359905E76357163834712659F26D0D8C9B47192404975CFB89969A77615D1A3FB404BAAA54511FF1B3B08C1577EB274F5B3B0B825434E87F60D18FA73141F912701A99A7C11305000789229A144A0899685596AA646F13573EBA0B54DD3205DE2C60C3CA1614066474B89F2377994BD14EE0A77E1D4C0AF77748C1E623CB8947A98636694C4EFAF0CE2BF779C66A317989A335A0071505831471C8D845A5FA4B3E42D195074244F70578124C4C7894AB84584DAEC8C13A6598524C023CA99F4C0499A68ACA3E6827798B10EF9A4639605E2FE8656606438274AC8ED8C87AE0A16BA3B8E5857A7F25831D8B85BC7105828575320C6BABA75489455154B31E50074A313BA9AD10B747F39405544F44949DDE165070C8271F1BA80E57BB5BD1320C8A1F8FB47354079532BBA51282AE3197026E18C46AE6B2AB9940EABA9F1EE421592770C9A9604263A4917C825C084C3534381F22C057592DD97940ADB1A439D5128CF795CDD25640FA9229220A1CE4A6624CC9956105465246334C77FFCB9907159461CB1416637D8DF34AB4B401413C27B6D5A1D23331F88273222653ADF9685A614BEC9840355B1A23A0C4CE60B0B678AFFED200BCB383BEC2580C89127B2870745C15570BA1CEC89F5DCCC47BE517BB020C57959E433C11DF10810D5B37AA8AB3392B3358793246F11ECE238646724BEB859C861463C42B5030D9A1FDBA3E1D391F9CA5A99DF58A7948C66FA2B50864B73A40B52DC7CFF031B3A3B21009268CD5CB00A89B44C156333B802AD03B2F07F70F7C11057CE78705AB6EE43681AFF0874030807412A7743399CAE832F6F3B65DF56AB1B30D6967379E10B4EF53B9EFB5632A23B942F832A7FA22CDE494B0C7393D51AC807A38AF119D526A5A3B91068E107812269EC85410AA739C288C20446B68880343F2E12157094DD424A349D1523E76C0ACB9C29C22B6346386B522B0466BC8A85B97430A1DF80850510C4825EC4F2AAB987C4A07F11693E7BBB4662A4890A3C54EBC0CBBD75CA468428E38276E81C43D81A8D0E3BDBEBAC9AEB89FC9D7870BB88C5C16A137C41FEE75640774C4B536BB1D7BBCE797844D960C98359F5719B20DCA6D1E2916F2829E73F79B55B468170B64F2F8B0C788796801C8EC244E1973C7E033B768414C55D43079B2711BDA630E678B184A70DD161C4DABBCB91C07FB634620D1450664A444E82D22A0A4F54AC6C7C02D74120B2CE205FE49A139B9C8194341F4295EF126B37F3B22E35792A8853B60EB3F7ED01314491C4451470870A5EA5B1D23442019BC1DEF547FB8935ECBEBA0833228B8D7BF2A4ACA52436A3F993F6164666EBB3C38317BF5B48CC7182C00D58D4A095D0FD4C60E4229E77803C4F38F22464C7A4259E45AC71E8CCDE6E5738DCC798777317F9847F8357DCE21B24AE462D0465F1D58203F3B8590D88DEB9C6DF4722A1420A9EA0813EC3777A6CB11CA0271292B6C662A870C292291164004299C82442A8DD5404E74CFBCB45175237AE5649F7136CB47B9C6C053203F265BAB420EEE2C95A5960F8A87C3333785E1B89FF841A6AA5AA964F3A853E512ACABB60E29C3A4810DF33830134C0E49BC5E1BA41B07B671E1BA6BFDA82576406E6DA854920A46914C8EA986B1D6A0328D4A450FC0CE698B9D16954AAA0C52B6F2B5FF7B5347E84C3AF403E9B31EC180238CD5AF96F5C6F0D3644AB51717F7255AD6551F44378294778937CC56B610680704BFB37E3CCC07C5276777E37F36623DEC8225388C3A5A2C7026EB902C63260CE27FFE657BCE34A47DB43667B9293E04AB9677B6FDB0B0A429A4435A9F5624628A2C07BBFA8AFED562BE4233019524E67CAE6F955226437433BC59835561C462071AC38058C145787C242D4B6DC055170675190882792EA49726DC8B2CB638763784D3C23E1791C93A55383A8C4B59643626F8948D228B670312893AB3CE5B123401B1B24432545889D4D124D2B846070C1663B87A3475C01ADC4F4DF286FC91C76B018C05B5A26A696DF86C4B1FBB2ED3050CC9B54CA2786839F854B9461655972FE21C3C98007A693A4D0B8AAFA3AB73F1C411DD283CCE59528477B6E089847CE6518F29B523602F80AC573618070BCA649EFB84FC3947D43B229E05682914C153809521EC9B7978A6BD667F59B18F1D986222DC9AB345AD2C7C7CC5799C15297C22C3734DF18A218C5BACB364C9136B8E055053567A1856C21B96A1A2723913C98CC364BBD1FC4EDEF37E1853C523727A6C677CA4C82AC4D49238E1B60C1531D1DC9835C4A96124A0011C09350353AAC4568A84293E8666F6016E56C38371489EDDBB3DF3E53E6767BD01E231EB122F13F59A83A35101844AB389954E8068F6D7128C738AC1774EDC6465EAE8CCBABCBB41271467C407D36928D9E3174C99665E3A9AF0FC1B2733925B254A3ABA050EC3925DABC511427C0B2930BCA63BA7629366C1BA620CC0D7090752157B5D70C098745E37DB7316056C7BB37C024226425107DA8BA0E9C30E2606752F31A017E50A0E10C05332677EC851EAE14F594A55D07392C23A962248CCEE1221FEB2C8F801860892B33EF2247B801E5FF55BA97675A71037FD133133840050B8B7914125E9D30165847319EB1E483005CA0BB8338B75EED618C47408D0260DDFB1527640A148F29E64F65FCAFC59A8715A8126830024767009BAD41A3385C0173BE51A35F3825843B59FE06B5FC03DC21F6D925B9F6D92FFF175C9DD625BFAF502B4E287096185885264E085F67E48F00A7A7F82963E8C67176BFF839A54FA1008328C0612F98D83D35AEDA108EA4D6C6BC0FB958286850422BC357CA67B83C986048E0D0087FA11EC +ct = BB06BFEECC7B7777B56768C6165C5347166BA71E8DC7E9E0258FF889BC123E6B6A1461F717FFBBC9CF11662E6FFEA09EB65AA287ECB4D7206D103F931B0E3C9EA8D71BE6F87B03EDF777EC1427F839922A7C8EEDC8DB4C8FECCA7665227029D6E23F5ED9163253D64D715042A5F301B41E2C59337F282DF32195EFCA03BDB3BD1D8B65C562ABF51EE8FCB39F51CC69DEA3BE7547341608444CA2EB9A9EFF2A3805224504440CF702C95A1FABAE452BA47A25E4D6401D24C0D8FC61962D4E11842FF6C6F82084D28F921E81E818DBE81B7E6A25596ABEC6809157A90C6F8779F4810BB3890D93E6F30546D982732AF2CBAD9E054AB510B64E6377DACB97104C64D9AE8CB451700F9A7776BEC488786733BAF3FBD6153B8B80C468FEB5EE28338817233A34A35E35F97D518AA8C07C9921E3D1BB96984FE1D543630B4FF34CB6AA6C64D7E3A7EBEA73E4B1379A8C53ACE1F2F2F07DF7017262FF152686BA28D8A3A348125F33BA2E795BDA25D2869F8DECB8E02453169E6EC9AF252D673D09060AC1F8E6E203E5950B11D1EFEC554D7E405F918E3472F25AAB2FFAB059EA043038031D23AF3911743FBEDAEC446C316B2801AF1152393F55820A5A7BB6D0DDBCEDE3F9E02423D7C8FD195F0194D2C5BD5A4BA6A9A5C934C1F7CE98D7476E2CF77837AAC2B738B1D6925797CD8752103DF9DE929119340993E36993956EB1CB7B8CD3CB067FE790A36BCF52CE218E9D5C009651EE835C724ADD8872ABB9E360742609E10EE43656719F140A155644AD25825AF6DD160D0CD944E1481AAA174A265DD18DA10AC0DC9F68337C5780672A36001209D8901E28F449ADA470A7134AF449A57494684E98124AD3901D680BCF62BE505368F8277ADE5BA33C3BF448462964728CBAB403FE5B10581E2BB377E10589A06B4C1AFB54927A87A016F63CFD1EC46A8C1A1764EBE07958FA2DC54C2CB90336C4769C7D118F56848122255B995752CF2B51133A4F96753A47B9B7C14E3A2565A326237926C870C8F67FA709F50EA174C3D0D57BD660438244EBD6C68102F1990FB1F1E06F0428A5210159EEA9C1774DCC4CBAEFF4461BA6966F164121EA26F328E831EAC62702119B42C7F430487145B68AFC16E7BAECD74A7EE349997A5244B6E9D74F17F00283DDD99808103AADF2365E4EB5DB20B40C3325333DD9877E019EFC9F1B95FFE67E88976A796DD735A68405C465225E951ACD794336FF7D7C5420BAA47ADA9C9A8C5700BEE94F0C80E693939D73C5C3A0C029DB9053D8D3C2E3F6EA47378FD225E704185D29C30F0C7AFAF47B3B9DE45539B026C77F788D00AB2A2CB41B5C995C0120C1229E9C138E6480BD9AADBABAE6CFD7ABB5FA97EC99D35B76702E8D84D2DF0333E3C9F4002D0C68E98E81440CB0D551C77AB6DF66348E2D798AA8092618B958317881F01EE209CEC22CC8EF0123A0C346EE47A158518C43FE926BA6F49056EF387F023AB9C57A6C0832E53C178A761ED7C382F76A81B340D98EE6FEFE208108994BA3F31F48 +ss = 3CC0EF85A74184338A10FFBFAD5F6D04860D51E7DACF3EE73033B70969785AF8 + +count = 97 +seed = 59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4 +generateEntropy = ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +encapEntropyPreHash = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +pk = B49B9264FAAFE731C0DEE965AC981965A28FF907CEABAC477E2C9B6DC95AAEB0531CBCB65D8B3F6251BE17ECAA89A5B57C1198EA66AF1F4461B91C360E4531C4D49269896107F10ED1F1070E68CDDB2A4E06C387F3126087A71A366A250B450BE1567DC957BBD034B66AB65FD4EAB2D89B8481EC2427A4AF3C1B861C799263F492779053A0128508C86EBD6201C876BBE8AB8053B790314047A1901C9F327207B2130BE5BCE8504BB03817A380975CD81FE0C0416986A7B74A16A21146636ABE4D2B2C5C1223D39265A6845804D49E5F160ABFE3CA21A345B5D044AFA5636C37B976F2894869BF4500C62AE9941B9B3C3E6064FEC351268243FD75BF287CAE8AAA9AAEFC1CFBA1032AD2623A6239A7F834A4826F86132B59AB24EFC9C57CBA929A64BA90271B987BC08A913298911650399429E9BFC40742DF735F7CB935EDA73A41F96CAACBB34324B29E64348C6063AEB0BCEE9066028B3340AA147B09C42752CFD6D491FFA497E17AB6C0726AEFE59C2577764A1A996FD879E58C23F1C0AC9E9372B3F0BE42C829B7B09ACB722E3189A2B3E72124895CCAB565DAE583C6C76C34C2C0075568379639869325F6E92E0B91A2D4100B2F4AA6486B756CD521E1B781A964A21B8B0C72637A2E4299FE15C1AC275FB077CF42F36453E7603C91A648E09CBF128ED188639B7247584B333003A2175BC587925111654F24680C540B32643B035FF38BB4598785524504EBCB26163D513867D74744C8B562BD48989B3A328374A125CA05FA962AC08B0D22277E578206A165A9E3D31A084B4492C664448AA62986B55FE8C8420816A5A9C035644F592969FD0951B6E9AA57303D1F9927FF6B3DE99263E2E11CD8317CFC899A45706746E9850922B9A4F9CDE515623F3C48B86379C969969934CCBEC4BEA3E9796889CBCC56285E9A85F0B3471BF9692F3C72FFD945089B9A262AC1A8844C38C807F7274708AA0587F94A107089A99694FC627291C30FD6B0430ECA692DB54A96019EAF89635CF54F579A63048070B7F32DD2C32A18E2B7E8400344412E9DC5943BF3AF11B4AA6C328499DA7C220670958A22BFFC89B8F0091C8665B6605571D8A1B5C934CE4686C7C047AE416BC6E39B7CCC92CB076DE94001374217E9B8820354351CB377B4F06B7FBB69F64C7B48F781DED2CFEE998718D875EB94866E7C5135358EA4EC92849978438C77CEC1BA1803BF9933C8856657C953125EB76014BACCA8EC9BE6290936130D166B187E1463E55CAE3AD85E96E81BC574220AB0CD374AA1F657ABEA849259B4431F1A00EE59B35486BEB09302BF71B4C2E840963333B4A3BE37F8048D42A0F67C886DE9B47611555495248AD4C587577D45775F52135518793EA14582BF153C74210C36B9251609A4B28559ADE5A93203725A475971B92BEB88A69357BF83F384577CC1DFB62C70FC65401073C67A66AF878FD961BACF46C633E7CAC0E5092458CBBA0C3B69494C4C0C0DA6025CD6516C1AB89B3216BB9BA123040051563610251974A0B11BE7190504522A128CA3107938F5B18E4441B52F7944B0E54CD3946C57E7AE3475BEC06791A9F5A83EACBB12F40AC971CB475610A0E6C546998DAFE5C2ED852D7715B3DBA61B94849DEA30E28720BBCB90C7AF7FEB0AF619A0CF57D173405C82 +sk = A428A1343429CE9C3DADBB6213410E264426D1CB5C69C68E7F377BCBC454AAF867771258FAA622B6367FC5CC46E960682A3984A13230B3D7C25A69CE4AB9AF0234A109878E0CC42A9B858DC559AD3FE82C4060539C08828C51B337B7C0EA768BA646A2F04900A235A4042B88E8934D3B62821A13B67A912F162AA80953CB71C396D91B91521B6665062551E0A6CE453C233460789138CB16AC6E598F670C70D6325804CC494466710D984E3EA551F5EC60C5031E94421919F62C301181831B7FB4FC61DA443FE12784CF84B5ECF240DAECC87D711AAD10808B96233D345BA80B0469797DC03583214355E8E9A356E367A593A6898355AD129A8546A0D03B2279021889C118DB3583DA691A9AD544086540BB2178B2125F00C94AE753038486B6CDF1CF7E5A2202290B4E5AC807EB04BEA95678B52FF76C4757C68D2EB9283B8766F1A39E06C999015B1F1D5C3164338AEB432D54B338C361B9A7258981555FC2563E585A6FF60886C32343E0045746E50FE78A0A9BCBB6281ABE3474BA50E1267B3276A1327A8F128E2B5AB077618C59902C35488553F745D2A0C942B81C0AAB7AFD0C869B9B9C66C1847257CB22B018B81B25C468A9BC35A180B090F4BB90C4EC035C0078B799046833CD90F7BC2678CAB9B75B95A6B457DCA8FCB84937C01479A0B7B6DA9643DA507A2B8B1AE25373825189729BDA8B35FCEA315B3B359705CD5B486582379093E64F431309F0389FF899BEB4C3CA9689B412A210EB654F183362AB8398B1E3696DF7432BE662CBE62666471F2C056504A5C1C91017A6326ACC7306524058FD0937DDEAB972B00734F60D065A1BA8655DBA3093D161B99E698FC778B2FE782FA8EC7C62D422E17B24FD107B87A8338AE7AF6994C70D959CBFC3720B3174B9658F5D43713CD47325EB926320073F384F04E6831435524B686F2CD377C18363F8E554DBE6AF09F93C2FF2A1F4A87159472E7D7A4DB9243A1C6A636AD50735B870F1297B6D6B5303E2552A54AA5991340AA40301CA2D6BD9A765B72FBDE1C3C44A7649EA350E00CDE59628E06ACAD29888C9B73CF0AA65D44B60F086C21C6ABCBD544295317B55EA9AB1117989AB7B7304304E5612119396727943678C31CF2B1779C946B82420A557A8D6426263D33C7F71591C7857E90A7FA05158E315AE19D1046249B3011B22291CAE30501D1423674824B852C34C97258AB972AF6C5195FFA20B6CF05BA0498A529756F173349BEC8C180869293C5967454D01CB3C8EDC7A3A776DBA54C37513727A69CAACFBAAD8EC4A529A1872CA25CB4A99C38B225E379ACE27485D8B91FEF9CEB97C04322B59F533745D23720AE457FA11B3A0B831DE777D07F88ED1771FA1D89DB9ACBC7BAC471BD423ACAC482BFB29DE13881AEAAAE2F340C1E747A73B9071CC551EA59B03646B65BC2E6E04875754A77025985A026ADCD321574AB45CDA47134B560219338FC93B0A398D7F85169B4B32C2EC3A06529F8E3A57FD353327B03F87D5CB60C67074146FB460476C92619D9C23BA7A371FD9425CFC6486992959109CFA1C1A75AB9EBA4235AF63C6F8648AE7855A4EAB5C9D3923386996181980B16B02A53060E5A64A8CF3CED087BBB49B9264FAAFE731C0DEE965AC981965A28FF907CEABAC477E2C9B6DC95AAEB0531CBCB65D8B3F6251BE17ECAA89A5B57C1198EA66AF1F4461B91C360E4531C4D49269896107F10ED1F1070E68CDDB2A4E06C387F3126087A71A366A250B450BE1567DC957BBD034B66AB65FD4EAB2D89B8481EC2427A4AF3C1B861C799263F492779053A0128508C86EBD6201C876BBE8AB8053B790314047A1901C9F327207B2130BE5BCE8504BB03817A380975CD81FE0C0416986A7B74A16A21146636ABE4D2B2C5C1223D39265A6845804D49E5F160ABFE3CA21A345B5D044AFA5636C37B976F2894869BF4500C62AE9941B9B3C3E6064FEC351268243FD75BF287CAE8AAA9AAEFC1CFBA1032AD2623A6239A7F834A4826F86132B59AB24EFC9C57CBA929A64BA90271B987BC08A913298911650399429E9BFC40742DF735F7CB935EDA73A41F96CAACBB34324B29E64348C6063AEB0BCEE9066028B3340AA147B09C42752CFD6D491FFA497E17AB6C0726AEFE59C2577764A1A996FD879E58C23F1C0AC9E9372B3F0BE42C829B7B09ACB722E3189A2B3E72124895CCAB565DAE583C6C76C34C2C0075568379639869325F6E92E0B91A2D4100B2F4AA6486B756CD521E1B781A964A21B8B0C72637A2E4299FE15C1AC275FB077CF42F36453E7603C91A648E09CBF128ED188639B7247584B333003A2175BC587925111654F24680C540B32643B035FF38BB4598785524504EBCB26163D513867D74744C8B562BD48989B3A328374A125CA05FA962AC08B0D22277E578206A165A9E3D31A084B4492C664448AA62986B55FE8C8420816A5A9C035644F592969FD0951B6E9AA57303D1F9927FF6B3DE99263E2E11CD8317CFC899A45706746E9850922B9A4F9CDE515623F3C48B86379C969969934CCBEC4BEA3E9796889CBCC56285E9A85F0B3471BF9692F3C72FFD945089B9A262AC1A8844C38C807F7274708AA0587F94A107089A99694FC627291C30FD6B0430ECA692DB54A96019EAF89635CF54F579A63048070B7F32DD2C32A18E2B7E8400344412E9DC5943BF3AF11B4AA6C328499DA7C220670958A22BFFC89B8F0091C8665B6605571D8A1B5C934CE4686C7C047AE416BC6E39B7CCC92CB076DE94001374217E9B8820354351CB377B4F06B7FBB69F64C7B48F781DED2CFEE998718D875EB94866E7C5135358EA4EC92849978438C77CEC1BA1803BF9933C8856657C953125EB76014BACCA8EC9BE6290936130D166B187E1463E55CAE3AD85E96E81BC574220AB0CD374AA1F657ABEA849259B4431F1A00EE59B35486BEB09302BF71B4C2E840963333B4A3BE37F8048D42A0F67C886DE9B47611555495248AD4C587577D45775F52135518793EA14582BF153C74210C36B9251609A4B28559ADE5A93203725A475971B92BEB88A69357BF83F384577CC1DFB62C70FC65401073C67A66AF878FD961BACF46C633E7CAC0E5092458CBBA0C3B69494C4C0C0DA6025CD6516C1AB89B3216BB9BA123040051563610251974A0B11BE7190504522A128CA3107938F5B18E4441B52F7944B0E54CD3946C57E7AE3475BEC06791A9F5A83EACBB12F40AC971CB475610A0E6C546998DAFE5C2ED852D7715B3DBA61B94849DEA30E28720BBCB90C7AF7FEB0AF619A0CF57D173405C828DAB879DE09B58D0FC7ADE140393FFB5343ABBDDABDC118FAD519B14436A964CE63F8FFDA3565C2424C89B20974B748A65A5ABA75133FCB3156DFB6626A83BAB +ct = 48E85341492FA71D05723CC0673917821EF717D8C55F9BD6450037745A043EBE12E9A233C310791AD66C101D93B88861FA516333C842C610009DC7F63486830E641A34D44AB9F1E5CA2B7F8513C3C89456EBEA4859AEB7117F90ED1AAC3DCF53EAB33C5363CE46A7AE78CDD0473D4B5EF5DAC4450B95C5CF335A5A656720046E4C12A9054857946B4F356B79478E864E32848DB05A51439A8A72567CD04D82E2CC61ECFF93C154190DD3AC16910AEFF13723D93775B1626D55294BB16958BDBF6CFFDE4B1BEF349AF5E0C7A2C902066A0440E7E5408F9D840AA74C34A6A318FBD810FCAE361B3688EB8CA9EE0FB214B386FC3718EE9141EEE6156280A8236A5EE0EA14A017C08C5EB6A90DCD4771EABE95E33B3966B6C259E2C65E4C1C0D0B34CAF2DBA11FCBB30B10BF337D49416B3E20C492F6CFFB6C83DB5A5E09A8E4CFF44AF0675762E43CA34559E14C1FD7E7F9FC5CD48B02C7CB9B0B788FDCB86B17E302F0C4F9C0DF1672C59DAFC240267D59737B2E6E4DB21982C928810B58A2443AD99E64CBA79AC9FE77249622BDB56503364ABBE7B5ABCE8EDF18F1E710C4642CF794CC22DF0837EDB785D0FD3D60551C5AFC94DCD4F52F3973F4C9434060B0C2A61E046AE5600FB4C9B00271DDF543A0EBD1DE5E41B5A6C7EEB573F862820E92AE2D9D9718E21B93366F54FDC58B9E83285350AEF35191463358DB9FE8860739F6A4119A00F5351F66B06F6EF7A08DD9D387FEA300EE7059A98661D808B50E75F5415D7B82738B73E3BFB58B7905F572C7E47483781BFCE45A805E5D647F9197E5D829B0D80F5B5A617E68FB2FBEAF1A8906F6A5C72CB5D90A04F0109871FB3743D3F588056101EE96894218A2E68CCACD3FCBA9FF4791A985352CC60F7B006D95D66F4903CCBB2607C37B8DB8EB88567A4ACDD1552F8D558C1396046856AC2A828F9117113372FBDF1002A70C9EC7FCF1A8F74DE26D48E44787ECF27BA4383448AB4FA6813A9F320FB4165FBFC363488DE37D3A540D4C55610425A8DE574870CCFAACCC5414B4B9BB029D85F8408AA033EA4D7E7C3074F848A188E13FCE09840C11C3DBCECC928A2079D954BDBE08037729AA6135B68D208A9C1CA2BE8323A949CF303C8486D5258952DCD3190879E986A5EBD406B8D09CA922041643E9E647C9C4E61453C0EF9D64F14E56EFD043D257936431D287FBE3E7B0E4CF301C5A7CB0730DE2C1CB0D22CABD61C1D0006B3E3F310123FD000F41093F4A3054974BCB39E9F474055C1001D372F21A880F864147BCF855FC9351651DCCD8288C2525C7959CD9F2FC6D410278856A5B2B10AA0FB6EF76F5F44ACDF0C01380E38E4A8BBE861815DBF2FB0723E60ABA41B235EAFBAE36DE07F2D478EF39B05D20610772E5D89B7C74D4F626586B8A4BA5DE91D5380A84A8092EEAE7515EF70FD9DBBC54CF9FBC41B3876489FDD481CC2D2CDA5B4231C37CEB508EBBC9712B304EF4EA2BF1E4F75D8D789FE73CA2F7FB9F03C4B48C796980FF39DF52CEB477C1B2D6C4AD1C +ss = 1DB6E99F80628E170260354EE6F3854F905D198E9669B4FAAB478F4B39CC2F0E + +count = 98 +seed = DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12 +generateEntropy = aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +encapEntropyPreHash = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +pk = BC962535672A8D77C9EAF9726CC1A8B8D87D61B1461F33B7F7F5A003A8657297CD100324FEA561BA879FFA75287D9A838275734593ABC2B842D9353906334D3F9324C7D00EED794C78310421DB45CAB6900817348D67490BF1485E85A3DFA255694915D286AB5243B62D3A91F8493F0B19626FB89C0B9109C6E1084BD8C848C06B3472A65A2646DD89BE2D922A0D2C5E816652C826854AB36F44809EE56C9F7E26A1DC30823535997A05255756704AA1029B86601E2853C2D34A192A9B2B76B31C69C1A048A76A6A58E48BC8E512B1C767347AE28AE046076C20179D0977D2D54A3F78ADD2EC6BC06071D9447F0461846FB1A5E91A760112424082C2994A98D07AAB29E818FD15134DE437C7FBC59469CE8BA80545A4A5BF337FE142B72E602D8A1B3009CC95975759AD38274E234AEF0552B8AA65CDFCAC975495A84C124F8426A9C87D8DB03CE48B0382642CB9E31CE210B774724912B09B16D88AE007AC4542C092F9BBED9C262D823D9D5719B357821D4C245F384FC923CD334B9DFF579E324A0BCFBCBA61FB7AE9F69B3AB88693E005EE32BD1A6A3CA950A22421125391A060276B07242A795085D0098906969C421CBC469128FB5393B72590FD391DCDFA3CF87B9F7A4C6CC3A1791AE1717478A5280A3B7580BBEDF88F0DD7C1C09AA67D6B284334049398BA983BCBACB8C56237BC3EFB3FBFDCB358A006457832DF7A01EFD937E68B3299580CBE1C9F69E165D22683B3721E4189ADAAA91846B7717D41BAF8D9A1DC76C387F0B55C2552533326597466ECF06ACA624FBF73226E471D835B0EE4A24A8F1C5FBE359C61D974A4D57C2F7C49822286CA27116839B784D6782C13B606B87804BA0969C7C47C7A29CE16CECFF5514028C3D84944EC8CAB4B4ACB5B681723511087E25B8AE84F3741A2DE6CC21E7A370B35C255C34555F29645D4B420494C4D993BA3F092EE240F1D3691753420891ACFC9421C361CA2186B563ED63456096227EAA738A33AB56029976C1125DCA790114AEB83AEBCF271ED59BBC2E8377301B53D697CFABB4C6B40BAE19B6CECD421A1109F9CAC7B71C749E60A2005A30179C393D5033CB4F8795DE4C98D91538FB9A8CB1654B1E6A82918471470461F54CC71FBA50DEB3E1221C55AA616AD5262E352ADB7A89CA04557A2090FB05704B9521809B8CABFA325892AB46765CEE83850586918422212C812373A1C6217BA890B4C5310F7B0D5D8275B884AA9E4914C85023AB53BEA88AD4281A7F501A87534AC1D806B0F8691E9F1BC7171001043015B391CFAC09B5FA88F840C63194632BD5A012B34B50441BA08C879C44654F136CCCBB7114F7B4099016E0193CBBAE63522927DF4B740B3CA5B32B741EA15A47370B98926A1F90618F5235357E8087443C93444803DD22BBDD5340C876D41F3AC1DB59E9EF17DB71369A315600FC6801A54483FB015AD3766284A97CBC241AD73461F4B2A0F6645EF428805762A6E57474D29288404AD98FAB63AE95E25436626BC66EE10C01E55103597288AC521B463886F863833948455319D3455110B68BF7BC495D1A922191A1A230A5F036C3C4AC05EE2609D09891CE368C01F037D818805A566193A433E924B30F4E86DC76AE2B345932A0E7025F8CE6101884469E31AEACAF4D77E3F1201BC75 +sk = FA198BB15B4278509DC232002C75A8BBF1853C474C8248B5062821E4D77FD5880979922016D17377F76A89AB9477A1024C9780FB728F6DF3295666828143C52FE817B9688C70EBA292D2716AB4970840ABC4603F597B5FCDEB0144813602242625A067EA48B426738DAD0AB986369AA5326DD199C72212C59AB20C8F63429683721A2C682C5AA853B86542698732AB86FE39C340DB2D452286FDD599336B9923599B66C144C0C7848C20A6979133FB7B5EFA3726A4F44389CB93D6A9C1B7E300CB852698C236AC00B2855861C88BAD062A25423362C7774C1626834EE59880762508FB518F926A3F475D01AA8E5C8C4140537091D494AF66B0E9426359032A2264AF67E63541C2408B1853F87C68C28C8C13417F94D77F6AC3315F23405C233E14F7762C152609AC34842553DE175A6FE1C08B44BAA9D15CF09A6049B05B69F71DF322171701AE91D050778A6754E374878169181A2E1336677889318CB54218AC055491B918BC2553023167151C98B30E1340403E0C59B3252F4D0C85EBAC1877798C41AA43C5C7B738B7CE116428C049370BA6665BE646B3125AEB947B1F3B2EC5357C7566C13EAB148C453D6B2274A9295A06C822DF9222CB2026F19603B5602D08D46D4C71384E776AF2A441894826E4559F5975C586E47BC0236B4897622AE4396160334CC97ACA101805814AE44786D1E445147A4728275C32554B9BD148AE9605E10C5A6B556704F1C17297A32EB311F1E92EE5F160E8522E06554B93B5C796E44086E75D236CA88ECC533C3B348091891E35639BD6CBDB3A408720B6E3A328C4268454169267A5C5348703C412C58846C192E0A162014600DBB351424FA8D0599775BD2D851DB4B07438F655AAD6402628563DB3A435F75D440636CD64041DE162D178C923490839F190F106BE0020AB63E7B3EB718A4FB59E01057C416C330CC26E485A6D9C72B707DA0B297C0A25247D26D40F044844C2DB883A5BBFC2B06F1BFBCCC6D10B65C9BDBFB806D7A04CD71774DD60BC423C1DFA897A0512365CD54A90BA6AC509298BF6455363583843925281AA405C291F11695CDA995A9AC5F742351560B38F8720D66327B4DCC47626744241679247CBE42695B8D81C37C718CAD53D1B318F9F900757267C43B982F26639901028F8F636C35091F1CA90A1E329D5CB069A918F45A078F33AB4DFD248390627926AADDFF47ECEF1718B2B048304CD40E72FB0872B6207856A61BD764034E82BB426747405E1AE5B93C63CB12C7BF09E47E27117D26ACBC102B043616E60B714316DFC17306A77800EE87E03E4B74759794EE6943DC274AEC1A08197A841E68F258202B1124803064F6E3295DD51AD18949A5A383A81363BB00118A8569A38D138BF8835362C723E999402D3CF728B0E11F647CE2B9390615B9E50487E23CEE6F9CEFC4A1CE5E83D28D642E3C16934B43931158CCEF3832A457A5E833F317918858807AB084F687A394C257ABCD8435CD717D1E6B79E78A37BB71A236729839B89A9905B5D935AFDC2C1E6C71C597898C6A69765BA05E9784B7849C685AB5B6DE3358C6299D8A4B075045D6EE15B639601AA95603A67378157B54889C3021453E373208CD06C0DEB77BC962535672A8D77C9EAF9726CC1A8B8D87D61B1461F33B7F7F5A003A8657297CD100324FEA561BA879FFA75287D9A838275734593ABC2B842D9353906334D3F9324C7D00EED794C78310421DB45CAB6900817348D67490BF1485E85A3DFA255694915D286AB5243B62D3A91F8493F0B19626FB89C0B9109C6E1084BD8C848C06B3472A65A2646DD89BE2D922A0D2C5E816652C826854AB36F44809EE56C9F7E26A1DC30823535997A05255756704AA1029B86601E2853C2D34A192A9B2B76B31C69C1A048A76A6A58E48BC8E512B1C767347AE28AE046076C20179D0977D2D54A3F78ADD2EC6BC06071D9447F0461846FB1A5E91A760112424082C2994A98D07AAB29E818FD15134DE437C7FBC59469CE8BA80545A4A5BF337FE142B72E602D8A1B3009CC95975759AD38274E234AEF0552B8AA65CDFCAC975495A84C124F8426A9C87D8DB03CE48B0382642CB9E31CE210B774724912B09B16D88AE007AC4542C092F9BBED9C262D823D9D5719B357821D4C245F384FC923CD334B9DFF579E324A0BCFBCBA61FB7AE9F69B3AB88693E005EE32BD1A6A3CA950A22421125391A060276B07242A795085D0098906969C421CBC469128FB5393B72590FD391DCDFA3CF87B9F7A4C6CC3A1791AE1717478A5280A3B7580BBEDF88F0DD7C1C09AA67D6B284334049398BA983BCBACB8C56237BC3EFB3FBFDCB358A006457832DF7A01EFD937E68B3299580CBE1C9F69E165D22683B3721E4189ADAAA91846B7717D41BAF8D9A1DC76C387F0B55C2552533326597466ECF06ACA624FBF73226E471D835B0EE4A24A8F1C5FBE359C61D974A4D57C2F7C49822286CA27116839B784D6782C13B606B87804BA0969C7C47C7A29CE16CECFF5514028C3D84944EC8CAB4B4ACB5B681723511087E25B8AE84F3741A2DE6CC21E7A370B35C255C34555F29645D4B420494C4D993BA3F092EE240F1D3691753420891ACFC9421C361CA2186B563ED63456096227EAA738A33AB56029976C1125DCA790114AEB83AEBCF271ED59BBC2E8377301B53D697CFABB4C6B40BAE19B6CECD421A1109F9CAC7B71C749E60A2005A30179C393D5033CB4F8795DE4C98D91538FB9A8CB1654B1E6A82918471470461F54CC71FBA50DEB3E1221C55AA616AD5262E352ADB7A89CA04557A2090FB05704B9521809B8CABFA325892AB46765CEE83850586918422212C812373A1C6217BA890B4C5310F7B0D5D8275B884AA9E4914C85023AB53BEA88AD4281A7F501A87534AC1D806B0F8691E9F1BC7171001043015B391CFAC09B5FA88F840C63194632BD5A012B34B50441BA08C879C44654F136CCCBB7114F7B4099016E0193CBBAE63522927DF4B740B3CA5B32B741EA15A47370B98926A1F90618F5235357E8087443C93444803DD22BBDD5340C876D41F3AC1DB59E9EF17DB71369A315600FC6801A54483FB015AD3766284A97CBC241AD73461F4B2A0F6645EF428805762A6E57474D29288404AD98FAB63AE95E25436626BC66EE10C01E55103597288AC521B463886F863833948455319D3455110B68BF7BC495D1A922191A1A230A5F036C3C4AC05EE2609D09891CE368C01F037D818805A566193A433E924B30F4E86DC76AE2B345932A0E7025F8CE6101884469E31AEACAF4D77E3F1201BC75919A696301240CD6129F66BE58E19D99B0D827D9932785CD9EA3D92F7BA54463FDA268813EFAB5204EFA60F78BF81D320D01AC09AC06244F7AFBD2D80FD356D9 +ct = 11A268DB2BEE6743849F2492BEA30B6C7458C3AA74364BCEFBC00502E30BBC3D38A6B35E56F73C84774660D3DB94F1224715F9ED1DFF8B76E7D714C68D85F5681DAE7E6928102EA340FA3D892D6E0B22C7CE2D4156BF0B68A63DD0390B49856E397E063B14AC2ECD40CFDB807F794B258F2893B4626A7D1A6A2B9CD1F1D3F0D74249E6CA9ECF42E527F11E1AF6D4FA34DF25A1E236422F83965A5535533BBAB735114794A16A3378A7E64C86FD33402C4E1A5244750EBE3AE44086134B25C7317A60B1F0989D12348618C1BFA05A9E2A9B34B500637DFB96471186F63AC4CB7407F2C636440133B30B8D9957CAB6585D71EAE68CB330431AE66B334B3B90A299E890852A785FCF51B772E3C0FA0980D89B51ADE1BCA47F6F53384566F03A0F2BBEE9FE38931F593401C4A14D9070B18CA7A905C698063A3080256619819B593BFB31FB7CC643D073B166F5D41482041871ECE479918F1F1F121F55EE63A2D12A581E839436F3E4CF5C338518F84BEE8FC08BFF8B107ABEBACC3AB9FFBB0D922D9AB1C0EFAC50D5C82F458968413702719800DB5AF2AE8DA624653889B642F09ABB3EC2464ECF548FB8EA1AED42318EFC9AAE51CD7EA08883C1546AE0D87950B9BF49DAA72F3006AFFCAB882681C8F6DCE038EF3C7653C7D91E975EDB5B6283CA48A93CA55F84027CCAE22A666351633A4414DF8FDEC7004157A174A38811351BAE1339D897FDE8BED32D491B88648EB022577F16C5165D1323B7203030B649E89B07571933AF62B5F2764A05DB9842332AD171B6A7968F87AB14809D0A5C11EA8541F733677AAA809979F4F389201F27EB240F378BCFA6D5AB63AF483CCEA73ECA4ABE515810D89C8E472CB7BECD19EBFE54D70CD035FBAB8E87AF97E1396AB607B64A752C869A92214581E0EF343305E1174236D26FE10F36810872B08268C59385D7B03A5D3389F5F840E65C12C50C576D4D99072929F378EDE448A5AAF01CC582D4692C655004C561E4A653120F9A3D27789D63EF5EE62F340D2FBCB72728A64D3FC0C04F19C7675A80A1001889F7C2A8FE7761475A26018573F9B079B7C770A3B0DC8193F1C86B29483F0725D3F52A1C9D7004AF1DCE7794811F98C1BB8320FC3AF0995989F583A4F6112FC00B05D1CB4EBB1D8A40F8F99A8085B28DEB6129AA524DF1AB6613AF704CCA378525719C71680E189C19E8E49157F29E2289697DA776B4EDC11502B75FF7B62BEF945E04A195759DA9522F9CDA1A3F8DECFB227A734A7D16551E57659B7AA9F9C5D27C67F02FA1ECD003446B58FF6912B274B22ADCC05048FD7CAB9E151B933A641E2441D841352CA90C2615058AC1206101A3CE973609EBE82F3FB0443C96107E52E6346B68F248626FBFEB726CDFD3F103A1E2E9733DDDE3E2D6A5D5DC482657FA26EBC2D5723E6506F1624B745380F1A515FB6498A2AA6BB79681BAC39242C6ADAF4D02571EEAE7DF7416F833D74EBC0929D9F7B53A439C185B9C8D50E2BB9B81F3562A56B756929FA9DF3CA7906A28E8CF +ss = EF8DE288A7CE14CCD5172A4A2F91588559E3780A75B1DF329A53B1E400C4C7F5 + +count = 99 +seed = 2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B +generateEntropy = 195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +encapEntropyPreHash = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +pk = 28441CC07C18856568C4FC0EDDC04175F564BDA148788608B71756367551A5709127668EFBD60B389877001B948F2C50CE62C7ED63122DAA7C1889400A4175AB959D09AB124BEA2C9D3659B8B4861E482EDED950DBF57A47C87F79FBC143D20420F4162F711963C47DCF7B8EA7FAA329D6A70F601D3A1B15A7890804917C84477D95F916A3761E3D94A0B0D69D9B7C39692B7F4ACB9091F87583810CCF67BDF86C4BE8F08762F2C3428646A3D33DF4B67EB87A2662353A208403BF59334BD9758A9439F8D8BDD45195F2255282A73456D168A2B249E8D180D5B310BA828685B3A1DABA2FB88783BB5062C13B79C2B0C3A10085664377EADBB477329567D1158882085850B95697248C6271F44988218777D33823AD70791BD40E29825ED124B963E05D06547C740A5AB7A1488E38C464B53B6F016BA1B7648A14AAA111907846C5DF162F61CC62747386915724A3B054E868BC04C934D64B7F2FF461AAE980FA806CCA7A9C4D7255564B420887946F7A72E4D1384D8222C70330B09C08D9A70AA176529F0685D087B8F9EB464A776F93606B05D0729FD2AFA7969EEC2662EBB7C7FC821D6B5393707ACF25C0C2C81702CB195F8CF730E8A46442E91E18FC7577F4AAFD6933450491EE24763BF6786D794D889C3005A323CEF2A8863C7AE00998D2E3CCC1F5A6C8A933D5D615CE82AF312990969C6288B6893C42142AD87AB483362461B87C641F646410EF5B393283230220A34730397188920B6873F16478331CB22A5A2C73273D865985533A1F8E109DBDE719C10C8ED87A831AB65562751EBBB15D3D5B6E01F78DB26A54E47943D6B31F916A552ED01A39F96DFF820765D6AE52265010545162D509F6AC3F9B7C0FD0ECAD4008732D6A9DF9449B2017B389522F11870704127BC6D018E0A420DD441EBF636C31B3B63DA9C00DC15BE0B3188371BBC855254217B99294815D78194FDABCD1970E31E38D37B4B1CC69BF428514F50AC9BCCA9125E6473028571BE535FCA274651752DAC691FF8A28C555036378B260ACB060FABA9573B0B65CBC76B892425294D65658F4A1B3309B424C6865BF1AB307B88022087F97F6882D4360ECD91F3D2513059A784BB256E47670AFD5C1AD5C177142A2955B082FD0B546577CA5286E0F1C85AF8B0BD5650038609E8EC8344E6CCB6DF93A056644CB89294FA19266948E9A561BFA66517A900B67F6BE5EFB853C703CCB4A296A493C24607A6AC4A749361D8F738080A80CA62AAF658B6A972894E6CA402AF3C09D2A6E9C181005E0C4D193361859011173BC8B97755FD1085B52808373B29733A7D0488C5F890364ABB9716920C074645AE023679BC9C2B3AD29B9051A94A124A43688A1027C35B90F9303664AA37AA92284F97DBCC7AD0F12B5B6BA38CE0A07130110518C74EA36CA6D6A44399A3983101458F926E0BB3357BAC5A294446463814806AD1623185F295D27F2C913C9608314174B2BB8BC03A92DB6CC6F044D964A7E3E289EA8F064D9B5C0D0EB43357495D09C0FBC4069903BCDC683763BC4C6ACC2517B7C94E3E0265029BFF55773421BC6143A38F57410BFB50BF21BAFEC948548A87667D95439BB78CCA2C9DA670BEB4C816478683B5487A4CE6401EC27A1605F879E2D9C53BF27E165246401CAD7840A077934B8 +sk = 55873EC8C5BAC259501E025FAED327B9B659B0810E7D43B8BF7A25A8C1A51062CFBC9BBEAB182747196797913398DB1C1CA41C1CC3A883400A29797AB4CBB553076C204167AAD2208355279F504DD9A476985362898B4E423821CC2642C335C3C953C866451CECE03098D5A2AE366DDAE1A06E05547E1C0C0667CC98494BFA778EEBC5CBACCC3038F93B82E57F814799CB7A921FB14042AAC83A1B4897BC6A15C87FC94144828966C49B6CB8F842A3157B60D6B3271C3661529D8A93C7DAF7B4DE1396308C0CBBFC9F984617CBB5B1825C88BDBC4C74C58EF3D54D089613A6A431E3A59ACF4201FBB6828DB0061F1BC514DCBFE72023CF8102E9834D5D6BBA8A354FE04C6008B37F9B07857CDA1238F5A562F288F3217FFD1A1BF8B2A0FCF3AF0310C84BD6CD805C246C4A227C9BCF963093A9755CBA968E7C06CC4F987B516171461B69E013076CB652C2A0B10F1B0FC9D6B583A929FA3905BA4B6B41F19D862C82B5F170277530A278773FA740ECA749C00A61735AA1A27719CFB75EB0768956718239F43239E25A316339DB665EB9784AB581137D020B992782956522B824B3EA4CB540A4B12AD7C512046711B0463F779E1279BCD2B7238580C72DF6120850376DB48978DC717CD1424D0B5E7331B76D0AC0B024C6283C8418E5B1A7A297AA483E5D2A65F2181EDE32C69CC4B9A8C4C0B90BB17EC06336D2100766AED931876CE45435B5662DD8A5B9F545292C870A16925546AE0CECACFB737647504EA1A29D13E0BC2D060BF7480345051E9379CFB0F901B9A426641802E5522FF8B199439026B123CF9B5827FFA147567912C46C88CEF0B41D9526D227A72262C0E3B3157DC4898E07CAEBC8038142B5172A799B8A6DB0F7703730C98E1957FEF13D5D7B2A52945EFF5C4337B6CC5004BACBB419BA73568AA357F61C70383447C6015A5896B9C0C0A2F2C7A76D940278D736D6B685F4FB3CC392CAAC1830B439468B6BC73585B4205751E55103099986308702A477588611A990580D88657024FA6D371550141405A8240109824788675D2546AFAD54628E93281ABCCAE4EAC11D200AA5C40A9E440D9F2A40DEB31C2688A3266C9E16B60461087DA271A1973374C99693C8111F9D458F92AC3208268078B177C818038305AB421B6D8297063061BB36F1318BB2108163A723A4BFC3C2A25F958F28B2B806A15E4310B8852103843C8AC26C7773084F1F82151C52083E69772A049123027916F039FD08713B98039F3B84CC83A8F88B2C19F48A958A443339A5A2158DFD7A08D11983601A1892A8C1152C602EDB1592C3AE555B2EE54C5DC6020C0B95626FC06D85D78120AC135FD369DE6B6AA902BB015A7BC3BA13A7391960C533D2F1A6278494E78B6A3C5B91A2B1AA2A0752E5C0A30E33CC86DCBA2E3232C98B9AAF1BBDF9E825B15A6DC3A741D43A53EB10AD18E93541E224EC5A952D673984990AF0D81577D1BC83B09856794D11707FAAC63A1E49A799224B51464916BC07F0A69F06F26696F5806E92CA4ADA050CDA48A9C90635A9C68ACC753A711115C35488758A68256A32F4964C431D50C0A8C5053D1A41126A952270A309F69931C32194FD201BC3809DB548A000558528441CC07C18856568C4FC0EDDC04175F564BDA148788608B71756367551A5709127668EFBD60B389877001B948F2C50CE62C7ED63122DAA7C1889400A4175AB959D09AB124BEA2C9D3659B8B4861E482EDED950DBF57A47C87F79FBC143D20420F4162F711963C47DCF7B8EA7FAA329D6A70F601D3A1B15A7890804917C84477D95F916A3761E3D94A0B0D69D9B7C39692B7F4ACB9091F87583810CCF67BDF86C4BE8F08762F2C3428646A3D33DF4B67EB87A2662353A208403BF59334BD9758A9439F8D8BDD45195F2255282A73456D168A2B249E8D180D5B310BA828685B3A1DABA2FB88783BB5062C13B79C2B0C3A10085664377EADBB477329567D1158882085850B95697248C6271F44988218777D33823AD70791BD40E29825ED124B963E05D06547C740A5AB7A1488E38C464B53B6F016BA1B7648A14AAA111907846C5DF162F61CC62747386915724A3B054E868BC04C934D64B7F2FF461AAE980FA806CCA7A9C4D7255564B420887946F7A72E4D1384D8222C70330B09C08D9A70AA176529F0685D087B8F9EB464A776F93606B05D0729FD2AFA7969EEC2662EBB7C7FC821D6B5393707ACF25C0C2C81702CB195F8CF730E8A46442E91E18FC7577F4AAFD6933450491EE24763BF6786D794D889C3005A323CEF2A8863C7AE00998D2E3CCC1F5A6C8A933D5D615CE82AF312990969C6288B6893C42142AD87AB483362461B87C641F646410EF5B393283230220A34730397188920B6873F16478331CB22A5A2C73273D865985533A1F8E109DBDE719C10C8ED87A831AB65562751EBBB15D3D5B6E01F78DB26A54E47943D6B31F916A552ED01A39F96DFF820765D6AE52265010545162D509F6AC3F9B7C0FD0ECAD4008732D6A9DF9449B2017B389522F11870704127BC6D018E0A420DD441EBF636C31B3B63DA9C00DC15BE0B3188371BBC855254217B99294815D78194FDABCD1970E31E38D37B4B1CC69BF428514F50AC9BCCA9125E6473028571BE535FCA274651752DAC691FF8A28C555036378B260ACB060FABA9573B0B65CBC76B892425294D65658F4A1B3309B424C6865BF1AB307B88022087F97F6882D4360ECD91F3D2513059A784BB256E47670AFD5C1AD5C177142A2955B082FD0B546577CA5286E0F1C85AF8B0BD5650038609E8EC8344E6CCB6DF93A056644CB89294FA19266948E9A561BFA66517A900B67F6BE5EFB853C703CCB4A296A493C24607A6AC4A749361D8F738080A80CA62AAF658B6A972894E6CA402AF3C09D2A6E9C181005E0C4D193361859011173BC8B97755FD1085B52808373B29733A7D0488C5F890364ABB9716920C074645AE023679BC9C2B3AD29B9051A94A124A43688A1027C35B90F9303664AA37AA92284F97DBCC7AD0F12B5B6BA38CE0A07130110518C74EA36CA6D6A44399A3983101458F926E0BB3357BAC5A294446463814806AD1623185F295D27F2C913C9608314174B2BB8BC03A92DB6CC6F044D964A7E3E289EA8F064D9B5C0D0EB43357495D09C0FBC4069903BCDC683763BC4C6ACC2517B7C94E3E0265029BFF55773421BC6143A38F57410BFB50BF21BAFEC948548A87667D95439BB78CCA2C9DA670BEB4C816478683B5487A4CE6401EC27A1605F879E2D9C53BF27E165246401CAD7840A077934B8CB6D7232426BDBDFDACD373C9190722E7BF342825F7D829185DCC9120588FC76AE77E0F9F21EABD8C0C6EEA7767F4E10FDE5C2D79B8400BF96B19014B457EC21 +ct = 7F60D2E6EE01AE6FBB198364141AF9A1AC4BA1B161CBDB16B86224FA77129864F00B71AA221DD1F300BA3EAFB2694610CA8F27C24CDFCD240961C27CF42D01561CCAF742379B19085C462270636676D6DCC5786E23D3881C83CD5FFD667C017FCA1F404A15A5BD368CD95A8FBDEBCCB9771B95958BDE3F65533190C0A758586094EBB86101582DC69FCCD7C2C1900D30648F360B4C805F143C8FE201D2DE242C66378439CBD304A30C67213F364F8FCBB202FFDCC290E85E8F0F718677FF8CB81D4AB3CF0DA5640C5F61B11A240099201D0BFAABECBBBB27A4623D77860BF52DC53A3AFB65ED2FCD4E9C9B1D1A996A643140CCE0D8B801728ED51BC3A47C9003375D8B19401E1C6841379A45BD2BE02A41222C4FE63E19C978D480E2D4E353AB957A1B81B74BBC7655A3D0261C8B2B06F6642BA4A5F8DD87B98B9AE355F57F8A5F978C6372BF594DF54DD8BF7650803EE13D9094B3EE86A1C3E2C21E4FD1F143D8A95CCE869DD365C29FA004070B0BDB899138FBF1D83EB9F76CBC112016C8CE1118FBDF76C3C907D1D3CAE2BA0BA5E419814DADEF0887CDC5817CA9C7B050574CF84009A6731136B39807687D3C3D6863C5D780BD6303F10A7D311D1C2A1C87039C17C6668501D572FC9D56B249ED0E95E17851AEBB45E288A32A1206C4FA475455309CD3D759CA19C47C0128A95DBD07E67937C0324B4B53BAB7402363FB32606387E2C419C0350943C8CB4760C2AA7D2FF9B1392E528B98493A61D2DC6D85CBF9E5759106D6BD1DAD276FB3AA45AAF75EB80BDB5D83AFFD7880371562100226B4E373B421B9EB3032938205012C6C083DD9E44BDFA842E280F03373F6E7E4DB5A50B4AA0B34789AF9AD051709B1E9ABDD71AD733DCC021DFA3A63609994F0FAFC5C1D88A39D46F81FA70E6164575321C2EBBB71F32893348AF887BAD2B1720CD5A86EA3774C1EBD53B15B9F01A4B5542A5F54053107E38ACE2594170B81DCD98D1CC47FEE808BE78DEBA05491F913ADE44B8914D65865EB0EB0F7E02DCBA1DE0D4B34E70485F83F96A5E41BBC064E3458473F43A70D51593F442EE2BD5B39E2C77C53BE83B9188101E3455C513BF4B8F744286BD529DA2804F804CE48E864A15F391A6793E4609279EAD144CDA084F3087678CA971EB22ED3B4B7FB740BE0407571F58DDE930D895140AD8EA096F06A3E255CD95AD48C4A46B99FF777B16452123A28D73B4A0CC0899C0CDAA1286FBE1C5FE95FA9418B5A473CC6ADBA14AFB06F080A544E49E148E492A8CE4BA9F4B5F781436F8FE30058A46F4D49A44E1FDE1B6F07E2A247CD3973AD76D3F473CAE88A2BAB3BEB78BD1875B240B23A901A9AD3F4421E5E355EAB0D3E1E197B246EB4F0861AEFB55BFD3BB54BF2CD6FFDCDFA0B78BAA674130CA2512B7069E7C33903A0A5EEEE7AF46FAFA52DD3F2E952CF909806B9CD2AA6826E823959A4BF03847BA50A4026FA0A72B78CBF6AA7FCD4908BA3BBCBDDE68708EC0AEC44B1E35C4E9E1EB7F01AFF0D9CE48F99BA01D78CEE +ss = 4793F705AED572ACE61DB13BEDE3900F2538EADDB904988C1F015BAC605A1093 diff --git a/third_party/boringssl/kit/src/crypto/lhash/internal.h b/third_party/boringssl/kit/src/crypto/lhash/internal.h index 64dca1d3..512f06df 100644 --- a/third_party/boringssl/kit/src/crypto/lhash/internal.h +++ b/third_party/boringssl/kit/src/crypto/lhash/internal.h @@ -157,6 +157,16 @@ OPENSSL_EXPORT void OPENSSL_lh_doall_arg(_LHASH *lh, void *arg); #define DEFINE_LHASH_OF(type) \ + /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ + * to the wrong type. While the cast itself is valid, it is often a bug \ + * because calling it through the cast is UB. However, we never actually \ + * call functions as |lhash_cmp_func|. The type is just a type-erased \ + * function pointer. (C does not guarantee function pointers fit in \ + * |void*|, and GCC will warn on this.) Thus we just disable the false \ + * positive warning. */ \ + OPENSSL_MSVC_PRAGMA(warning(push)) \ + OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ + \ DECLARE_LHASH_OF(type) \ \ typedef int (*lhash_##type##_cmp_func)(const type *, const type *); \ @@ -243,7 +253,9 @@ OPENSSL_EXPORT void OPENSSL_lh_doall_arg(_LHASH *lh, LHASH_OF(type) *lh, void (*func)(type *, void *), void *arg) { \ LHASH_DOALL_##type cb = {func, arg}; \ OPENSSL_lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall_arg, &cb); \ - } + } \ + \ + OPENSSL_MSVC_PRAGMA(warning(pop)) #if defined(__cplusplus) diff --git a/third_party/boringssl/kit/src/crypto/mem.c b/third_party/boringssl/kit/src/crypto/mem.c index 43d3deb6..89832fce 100644 --- a/third_party/boringssl/kit/src/crypto/mem.c +++ b/third_party/boringssl/kit/src/crypto/mem.c @@ -57,8 +57,11 @@ #include #include +#include +#include #include #include +#include #include @@ -68,12 +71,17 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3)) OPENSSL_MSVC_PRAGMA(warning(pop)) #endif +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +#include +#include +#include +#endif + #include "internal.h" #define OPENSSL_MALLOC_PREFIX 8 -OPENSSL_STATIC_ASSERT(OPENSSL_MALLOC_PREFIX >= sizeof(size_t), - "size_t too large"); +static_assert(OPENSSL_MALLOC_PREFIX >= sizeof(size_t), "size_t too large"); #if defined(OPENSSL_ASAN) void __asan_poison_memory_region(const volatile void *addr, size_t size); @@ -121,7 +129,7 @@ WEAK_SYMBOL_FUNC(void, sdallocx, (void *ptr, size_t size, int flags)); // primitives used must tolerate every other synchronization primitive linked // into the process, including pthreads locks. Failing to meet these constraints // may result in deadlocks, crashes, or memory corruption. -WEAK_SYMBOL_FUNC(void*, OPENSSL_memory_alloc, (size_t size)); +WEAK_SYMBOL_FUNC(void *, OPENSSL_memory_alloc, (size_t size)); WEAK_SYMBOL_FUNC(void, OPENSSL_memory_free, (void *ptr)); WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr)); @@ -129,17 +137,106 @@ WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr)); // are linking in BoringSSL and, roughly, what version they are using. static const uint8_t kBoringSSLBinaryTag[18] = { // 16 bytes of magic tag. - 0x8c, 0x62, 0x20, 0x0b, 0xd2, 0xa0, 0x72, 0x58, - 0x44, 0xa8, 0x96, 0x69, 0xad, 0x55, 0x7e, 0xec, + 0x8c, + 0x62, + 0x20, + 0x0b, + 0xd2, + 0xa0, + 0x72, + 0x58, + 0x44, + 0xa8, + 0x96, + 0x69, + 0xad, + 0x55, + 0x7e, + 0xec, // Current source iteration. Incremented ~monthly. - 2, 0, + 3, + 0, }; +#if defined(BORINGSSL_MALLOC_FAILURE_TESTING) +static CRYPTO_MUTEX malloc_failure_lock = CRYPTO_MUTEX_INIT; +static uint64_t current_malloc_count = 0; +static uint64_t malloc_number_to_fail = 0; +static int malloc_failure_enabled = 0, break_on_malloc_fail = 0, + any_malloc_failed = 0; + +static void malloc_exit_handler(void) { + CRYPTO_MUTEX_lock_read(&malloc_failure_lock); + if (any_malloc_failed) { + // Signal to the test driver that some allocation failed, so it knows to + // increment the counter and continue. + _exit(88); + } + CRYPTO_MUTEX_unlock_read(&malloc_failure_lock); +} + +static void init_malloc_failure(void) { + const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); + if (env != NULL && env[0] != 0) { + char *endptr; + malloc_number_to_fail = strtoull(env, &endptr, 10); + if (*endptr == 0) { + malloc_failure_enabled = 1; + atexit(malloc_exit_handler); + } + } + break_on_malloc_fail = getenv("MALLOC_BREAK_ON_FAIL") != NULL; +} + +// should_fail_allocation returns one if the current allocation should fail and +// zero otherwise. +static int should_fail_allocation() { + static CRYPTO_once_t once = CRYPTO_ONCE_INIT; + CRYPTO_once(&once, init_malloc_failure); + if (!malloc_failure_enabled) { + return 0; + } + + // We lock just so multi-threaded tests are still correct, but we won't test + // every malloc exhaustively. + CRYPTO_MUTEX_lock_write(&malloc_failure_lock); + int should_fail = current_malloc_count == malloc_number_to_fail; + current_malloc_count++; + any_malloc_failed = any_malloc_failed || should_fail; + CRYPTO_MUTEX_unlock_write(&malloc_failure_lock); + + if (should_fail && break_on_malloc_fail) { + raise(SIGTRAP); + } + if (should_fail) { + errno = ENOMEM; + } + return should_fail; +} + +void OPENSSL_reset_malloc_counter_for_testing(void) { + CRYPTO_MUTEX_lock_write(&malloc_failure_lock); + current_malloc_count = 0; + CRYPTO_MUTEX_unlock_write(&malloc_failure_lock); +} + +#else +static int should_fail_allocation(void) { return 0; } +#endif + void *OPENSSL_malloc(size_t size) { + if (should_fail_allocation()) { + goto err; + } + if (OPENSSL_memory_alloc != NULL) { assert(OPENSSL_memory_free != NULL); assert(OPENSSL_memory_get_size != NULL); - return OPENSSL_memory_alloc(size); + void *ptr = OPENSSL_memory_alloc(size); + if (ptr == NULL && size != 0) { + goto err; + } + return ptr; } if (size + OPENSSL_MALLOC_PREFIX < size) { @@ -151,18 +248,23 @@ void *OPENSSL_malloc(size_t size) { // rare code path. uint8_t unused = *(volatile uint8_t *)kBoringSSLBinaryTag; (void) unused; - return NULL; + goto err; } void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); if (ptr == NULL) { - return NULL; + goto err; } *(size_t *)ptr = size; __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; + + err: + // This only works because ERR does not call OPENSSL_malloc. + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; } void OPENSSL_free(void *orig_ptr) { @@ -180,11 +282,18 @@ void OPENSSL_free(void *orig_ptr) { size_t size = *(size_t *)ptr; OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); + +// ASan knows to intercept malloc and free, but not sdallocx. +#if defined(OPENSSL_ASAN) + (void)sdallocx; + free(ptr); +#else if (sdallocx) { sdallocx(ptr, size + OPENSSL_MALLOC_PREFIX, 0 /* flags */); } else { free(ptr); } +#endif } void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { @@ -233,8 +342,18 @@ void OPENSSL_cleanse(void *ptr, size_t len) { #endif // !OPENSSL_NO_ASM } -void OPENSSL_clear_free(void *ptr, size_t unused) { - OPENSSL_free(ptr); +void OPENSSL_clear_free(void *ptr, size_t unused) { OPENSSL_free(ptr); } + +int CRYPTO_secure_malloc_init(size_t size, size_t min_size) { return 0; } + +int CRYPTO_secure_malloc_initialized(void) { return 0; } + +size_t CRYPTO_secure_used(void) { return 0; } + +void *OPENSSL_secure_malloc(size_t size) { return OPENSSL_malloc(size); } + +void OPENSSL_secure_clear_free(void *ptr, size_t len) { + OPENSSL_clear_free(ptr, len); } int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { @@ -290,6 +409,34 @@ char *OPENSSL_strdup(const char *s) { return ret; } +int OPENSSL_isalpha(int c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +int OPENSSL_isdigit(int c) { return c >= '0' && c <= '9'; } + +int OPENSSL_isxdigit(int c) { + return OPENSSL_isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +int OPENSSL_fromxdigit(uint8_t *out, int c) { + if (OPENSSL_isdigit(c)) { + *out = c - '0'; + return 1; + } + if ('a' <= c && c <= 'f') { + *out = c - 'a' + 10; + return 1; + } + if ('A' <= c && c <= 'F') { + *out = c - 'A' + 10; + return 1; + } + return 0; +} + +int OPENSSL_isalnum(int c) { return OPENSSL_isalpha(c) || OPENSSL_isdigit(c); } + int OPENSSL_tolower(int c) { if (c >= 'A' && c <= 'Z') { return c + ('a' - 'A'); @@ -297,6 +444,11 @@ int OPENSSL_tolower(int c) { return c; } +int OPENSSL_isspace(int c) { + return c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || + c == ' '; +} + int OPENSSL_strcasecmp(const char *a, const char *b) { for (size_t i = 0;; i++) { const int aa = OPENSSL_tolower(a[i]); @@ -341,6 +493,62 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) { return vsnprintf(buf, n, format, args); } +int OPENSSL_vasprintf_internal(char **str, const char *format, va_list args, + int system_malloc) { + void *(*allocate)(size_t) = system_malloc ? malloc : OPENSSL_malloc; + void (*deallocate)(void *) = system_malloc ? free : OPENSSL_free; + void *(*reallocate)(void *, size_t) = + system_malloc ? realloc : OPENSSL_realloc; + char *candidate = NULL; + size_t candidate_len = 64; // TODO(bbe) what's the best initial size? + + if ((candidate = allocate(candidate_len)) == NULL) { + goto err; + } + va_list args_copy; + va_copy(args_copy, args); + int ret = vsnprintf(candidate, candidate_len, format, args_copy); + va_end(args_copy); + if (ret < 0) { + goto err; + } + if ((size_t)ret >= candidate_len) { + // Too big to fit in allocation. + char *tmp; + + candidate_len = (size_t)ret + 1; + if ((tmp = reallocate(candidate, candidate_len)) == NULL) { + goto err; + } + candidate = tmp; + ret = vsnprintf(candidate, candidate_len, format, args); + } + // At this point this should not happen unless vsnprintf is insane. + if (ret < 0 || (size_t)ret >= candidate_len) { + goto err; + } + *str = candidate; + return ret; + + err: + deallocate(candidate); + *str = NULL; + errno = ENOMEM; + return -1; +} + +int OPENSSL_vasprintf(char **str, const char *format, va_list args) { + return OPENSSL_vasprintf_internal(str, format, args, /*system_malloc=*/0); +} + +int OPENSSL_asprintf(char **str, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = OPENSSL_vasprintf(str, format, args); + va_end(args); + return ret; +} + char *OPENSSL_strndup(const char *str, size_t size) { size = OPENSSL_strnlen(str, size); @@ -352,7 +560,6 @@ char *OPENSSL_strndup(const char *str, size_t size) { } char *ret = OPENSSL_malloc(alloc_size); if (ret == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } @@ -391,7 +598,6 @@ void *OPENSSL_memdup(const void *data, size_t size) { void *ret = OPENSSL_malloc(size); if (ret == NULL) { - OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/obj/obj.c b/third_party/boringssl/kit/src/crypto/obj/obj.c index 958625d0..67c73d4f 100644 --- a/third_party/boringssl/kit/src/crypto/obj/obj.c +++ b/third_party/boringssl/kit/src/crypto/obj/obj.c @@ -77,24 +77,20 @@ DEFINE_LHASH_OF(ASN1_OBJECT) -static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX global_added_lock = CRYPTO_MUTEX_INIT; // These globals are protected by |global_added_lock|. static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL; static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL; static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL; -static struct CRYPTO_STATIC_MUTEX global_next_nid_lock = - CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX global_next_nid_lock = CRYPTO_MUTEX_INIT; static unsigned global_next_nid = NUM_NID; static int obj_next_nid(void) { - int ret; - - CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock); - ret = global_next_nid++; - CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock); - + CRYPTO_MUTEX_lock_write(&global_next_nid_lock); + int ret = global_next_nid++; + CRYPTO_MUTEX_unlock_write(&global_next_nid_lock); return ret; } @@ -155,7 +151,6 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { return r; err: - OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE); OPENSSL_free(ln); OPENSSL_free(sn); OPENSSL_free(data); @@ -214,17 +209,17 @@ int OBJ_obj2nid(const ASN1_OBJECT *obj) { return obj->nid; } - CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + CRYPTO_MUTEX_lock_read(&global_added_lock); if (global_added_by_data != NULL) { ASN1_OBJECT *match; match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj); if (match != NULL) { - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); return match->nid; } } - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); const uint16_t *nid_ptr = bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), @@ -260,18 +255,18 @@ static int short_name_cmp(const void *key, const void *element) { } int OBJ_sn2nid(const char *short_name) { - CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + CRYPTO_MUTEX_lock_read(&global_added_lock); if (global_added_by_short_name != NULL) { ASN1_OBJECT *match, template; template.sn = short_name; match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template); if (match != NULL) { - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); return match->nid; } } - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); const uint16_t *nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, @@ -295,18 +290,18 @@ static int long_name_cmp(const void *key, const void *element) { } int OBJ_ln2nid(const char *long_name) { - CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + CRYPTO_MUTEX_lock_read(&global_added_lock); if (global_added_by_long_name != NULL) { ASN1_OBJECT *match, template; template.ln = long_name; match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template); if (match != NULL) { - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); return match->nid; } } - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); const uint16_t *nid_ptr = bsearch( long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), @@ -350,18 +345,18 @@ ASN1_OBJECT *OBJ_nid2obj(int nid) { return (ASN1_OBJECT *)&kObjects[nid]; } - CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + CRYPTO_MUTEX_lock_read(&global_added_lock); if (global_added_by_nid != NULL) { ASN1_OBJECT *match, template; template.nid = nid; match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template); if (match != NULL) { - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); return match; } } - CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + CRYPTO_MUTEX_unlock_read(&global_added_lock); err: OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID); @@ -506,25 +501,37 @@ static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { // obj_add_object inserts |obj| into the various global hashes for run-time // added objects. It returns one on success or zero otherwise. static int obj_add_object(ASN1_OBJECT *obj) { - int ok; - ASN1_OBJECT *old_object; - obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA); - CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock); + CRYPTO_MUTEX_lock_write(&global_added_lock); if (global_added_by_nid == NULL) { global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); + } + if (global_added_by_data == NULL) { global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); - global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + } + if (global_added_by_short_name == NULL) { + global_added_by_short_name = + lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + } + if (global_added_by_long_name == NULL) { global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); } + int ok = 0; + if (global_added_by_nid == NULL || + global_added_by_data == NULL || + global_added_by_short_name == NULL || + global_added_by_long_name == NULL) { + goto err; + } + // We don't pay attention to |old_object| (which contains any previous object // that was evicted from the hashes) because we don't have a reference count // on ASN1_OBJECT values. Also, we should never have duplicates nids and so // should always have objects in |global_added_by_nid|. - + ASN1_OBJECT *old_object; ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); if (obj->length != 0 && obj->data != NULL) { ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); @@ -535,8 +542,9 @@ static int obj_add_object(ASN1_OBJECT *obj) { if (obj->ln != NULL) { ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); } - CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); +err: + CRYPTO_MUTEX_unlock_write(&global_added_lock); return ok; } diff --git a/third_party/boringssl/kit/src/crypto/obj/obj_dat.h b/third_party/boringssl/kit/src/crypto/obj/obj_dat.h index 778d8e3c..654b3c08 100644 --- a/third_party/boringssl/kit/src/crypto/obj/obj_dat.h +++ b/third_party/boringssl/kit/src/crypto/obj/obj_dat.h @@ -57,7 +57,7 @@ /* This file is generated by crypto/obj/objects.go. */ -#define NUM_NID 963 +#define NUM_NID 965 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -8777,10 +8777,13 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { {"AuthPSK", "auth-psk", NID_auth_psk, 0, NULL, 0}, {"KxANY", "kx-any", NID_kx_any, 0, NULL, 0}, {"AuthANY", "auth-any", NID_auth_any, 0, NULL, 0}, - {"CECPQ2", "CECPQ2", NID_CECPQ2, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, {"ED448", "ED448", NID_ED448, 3, &kObjectData[6181], 0}, {"X448", "X448", NID_X448, 3, &kObjectData[6184], 0}, {"SHA512-256", "sha512-256", NID_sha512_256, 9, &kObjectData[6187], 0}, + {"HKDF", "hkdf", NID_hkdf, 0, NULL, 0}, + {"X25519Kyber768Draft00", "X25519Kyber768Draft00", + NID_X25519Kyber768Draft00, 0, NULL, 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -8842,7 +8845,6 @@ static const uint16_t kNIDsInShortNameOrder[] = { 110 /* CAST5-CFB */, 109 /* CAST5-ECB */, 111 /* CAST5-OFB */, - 959 /* CECPQ2 */, 894 /* CMAC */, 13 /* CN */, 141 /* CRLReason */, @@ -8878,6 +8880,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 949 /* ED25519 */, 960 /* ED448 */, 99 /* GN */, + 963 /* HKDF */, 855 /* HMAC */, 780 /* HMAC-MD5 */, 781 /* HMAC-SHA1 */, @@ -8979,6 +8982,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 458 /* UID */, 0 /* UNDEF */, 948 /* X25519 */, + 964 /* X25519Kyber768Draft00 */, 961 /* X448 */, 11 /* X500 */, 378 /* X500algorithms */, @@ -9750,7 +9754,6 @@ static const uint16_t kNIDsInLongNameOrder[] = { 285 /* Biometric Info */, 179 /* CA Issuers */, 785 /* CA Repository */, - 959 /* CECPQ2 */, 131 /* Code Signing */, 783 /* Diffie-Hellman based MAC */, 382 /* Directory */, @@ -9850,6 +9853,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 133 /* Time Stamping */, 375 /* Trust Root */, 948 /* X25519 */, + 964 /* X25519Kyber768Draft00 */, 961 /* X448 */, 12 /* X509 */, 402 /* X509v3 AC Targeting */, @@ -10096,6 +10100,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 601 /* generic cryptogram */, 99 /* givenName */, 814 /* gost89-cnt */, + 963 /* hkdf */, 855 /* hmac */, 780 /* hmac-md5 */, 781 /* hmac-sha1 */, diff --git a/third_party/boringssl/kit/src/crypto/obj/obj_mac.num b/third_party/boringssl/kit/src/crypto/obj/obj_mac.num index f110ee92..a0519ace 100644 --- a/third_party/boringssl/kit/src/crypto/obj/obj_mac.num +++ b/third_party/boringssl/kit/src/crypto/obj/obj_mac.num @@ -947,7 +947,8 @@ auth_ecdsa 955 auth_psk 956 kx_any 957 auth_any 958 -CECPQ2 959 ED448 960 X448 961 sha512_256 962 +hkdf 963 +X25519Kyber768Draft00 964 diff --git a/third_party/boringssl/kit/src/crypto/obj/objects.go b/third_party/boringssl/kit/src/crypto/obj/objects.go index 361cdfe2..077a6e12 100644 --- a/third_party/boringssl/kit/src/crypto/obj/objects.go +++ b/third_party/boringssl/kit/src/crypto/obj/objects.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -19,7 +21,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "os" "os/exec" "sort" @@ -518,24 +519,11 @@ extern "C" { return err } - return ioutil.WriteFile(path, []byte(formatted), 0666) + return os.WriteFile(path, []byte(formatted), 0666) } -// TODO(davidben): Replace this with sort.Slice once Go 1.8 is sufficiently -// common. -type nidSorter struct { - nids []int - objs *objects - cmp func(a, b object) bool -} - -func (a nidSorter) obj(i int) object { return a.objs.byNID[a.nids[i]] } -func (a nidSorter) Len() int { return len(a.nids) } -func (a nidSorter) Swap(i, j int) { a.nids[i], a.nids[j] = a.nids[j], a.nids[i] } -func (a nidSorter) Less(i, j int) bool { return a.cmp(a.obj(i), a.obj(j)) } - func sortNIDs(nids []int, objs *objects, cmp func(a, b object) bool) { - sort.Sort(&nidSorter{nids, objs, cmp}) + sort.Slice(nids, func(i, j int) bool { return cmp(objs.byNID[nids[i]], objs.byNID[nids[j]]) }) } func writeData(path string, objs *objects) error { @@ -710,7 +698,7 @@ func writeData(path string, objs *objects) error { return err } - return ioutil.WriteFile(path, []byte(formatted), 0666) + return os.WriteFile(path, []byte(formatted), 0666) } func main() { diff --git a/third_party/boringssl/kit/src/crypto/obj/objects.txt b/third_party/boringssl/kit/src/crypto/obj/objects.txt index 25c24305..3ad32ea3 100644 --- a/third_party/boringssl/kit/src/crypto/obj/objects.txt +++ b/third_party/boringssl/kit/src/crypto/obj/objects.txt @@ -1332,8 +1332,8 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme : dh-std-kdf : dh-cofactor-kdf -# NID for CECPQ2 (no corresponding OID). - : CECPQ2 +# NIDs for post quantum hybrid KEMs in TLS (no corresponding OIDs). + : X25519Kyber768Draft00 # See RFC 8410. 1 3 101 110 : X25519 @@ -1356,3 +1356,5 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme # TLS 1.3 cipher suites do not specify key exchange or authentication. : KxANY : kx-any : AuthANY : auth-any + + : HKDF : hkdf diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_all.c b/third_party/boringssl/kit/src/crypto/pem/pem_all.c index e419774d..cade0a25 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_all.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_all.c @@ -127,126 +127,117 @@ IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) -/* - * We treat RSA or DSA private keys as a special case. For private keys we - * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract - * the relevant private key: this means can handle "traditional" and PKCS#8 - * formats transparently. - */ -static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) -{ - RSA *rtmp; - if (!key) - return NULL; - rtmp = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - if (!rtmp) - return NULL; - if (rsa) { - RSA_free(*rsa); - *rsa = rtmp; - } - return rtmp; +// We treat RSA or DSA private keys as a special case. For private keys we +// read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract +// the relevant private key: this means can handle "traditional" and PKCS#8 +// formats transparently. +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) { + RSA *rtmp; + if (!key) { + return NULL; + } + rtmp = EVP_PKEY_get1_RSA(key); + EVP_PKEY_free(key); + if (!rtmp) { + return NULL; + } + if (rsa) { + RSA_free(*rsa); + *rsa = rtmp; + } + return rtmp; } RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); + void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); } -RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); +RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); } -IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, - RSAPrivateKey) +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) -IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, - RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, - PEM_STRING_PUBLIC, - RSA_PUBKEY) +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) +IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) #ifndef OPENSSL_NO_DSA -static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) -{ - DSA *dtmp; - if (!key) - return NULL; - dtmp = EVP_PKEY_get1_DSA(key); - EVP_PKEY_free(key); - if (!dtmp) - return NULL; - if (dsa) { - DSA_free(*dsa); - *dsa = dtmp; - } - return dtmp; +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) { + DSA *dtmp; + if (!key) { + return NULL; + } + dtmp = EVP_PKEY_get1_DSA(key); + EVP_PKEY_free(key); + if (!dtmp) { + return NULL; + } + if (dsa) { + DSA_free(*dsa); + *dsa = dtmp; + } + return dtmp; } DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ + void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); // will free pktmp } -IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, - DSAPrivateKey) +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) - IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) -DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) +DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); // will free pktmp } IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) #endif -static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) -{ - EC_KEY *dtmp; - if (!key) - return NULL; - dtmp = EVP_PKEY_get1_EC_KEY(key); - EVP_PKEY_free(key); - if (!dtmp) - return NULL; - if (eckey) { - EC_KEY_free(*eckey); - *eckey = dtmp; - } - return dtmp; +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) { + EC_KEY *dtmp; + if (!key) { + return NULL; + } + dtmp = EVP_PKEY_get1_EC_KEY(key); + EVP_PKEY_free(key); + if (!dtmp) { + return NULL; + } + if (eckey) { + EC_KEY_free(*eckey); + *eckey = dtmp; + } + return dtmp; } EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_eckey(pktmp, key); /* will free pktmp */ + void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_eckey(pktmp, key); // will free pktmp } IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) - IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) +IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ + void *u) { + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_eckey(pktmp, eckey); // will free pktmp } -IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) +IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) - IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) +IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_info.c b/third_party/boringssl/kit/src/crypto/pem/pem_info.c index 3a1d0cce..c097013d 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_info.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_info.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_info.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,288 +70,194 @@ #include STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return 0; - } - STACK_OF(X509_INFO) *ret = PEM_X509_INFO_read_bio(b, sk, cb, u); - BIO_free(b); - return ret; + pem_password_cb *cb, void *u) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + STACK_OF(X509_INFO) *ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + BIO_free(b); + return ret; } enum parse_result_t { - parse_ok, - parse_error, - parse_new_entry, + parse_ok, + parse_error, + parse_new_entry, }; static enum parse_result_t parse_x509(X509_INFO *info, const uint8_t *data, - size_t len, int key_type) -{ - if (info->x509 != NULL) { - return parse_new_entry; - } - info->x509 = d2i_X509(NULL, &data, len); - return info->x509 != NULL ? parse_ok : parse_error; + size_t len, int key_type) { + if (info->x509 != NULL) { + return parse_new_entry; + } + info->x509 = d2i_X509(NULL, &data, len); + return info->x509 != NULL ? parse_ok : parse_error; } static enum parse_result_t parse_x509_aux(X509_INFO *info, const uint8_t *data, - size_t len, int key_type) -{ - if (info->x509 != NULL) { - return parse_new_entry; - } - info->x509 = d2i_X509_AUX(NULL, &data, len); - return info->x509 != NULL ? parse_ok : parse_error; + size_t len, int key_type) { + if (info->x509 != NULL) { + return parse_new_entry; + } + info->x509 = d2i_X509_AUX(NULL, &data, len); + return info->x509 != NULL ? parse_ok : parse_error; } static enum parse_result_t parse_crl(X509_INFO *info, const uint8_t *data, - size_t len, int key_type) -{ - if (info->crl != NULL) { - return parse_new_entry; - } - info->crl = d2i_X509_CRL(NULL, &data, len); - return info->crl != NULL ? parse_ok : parse_error; + size_t len, int key_type) { + if (info->crl != NULL) { + return parse_new_entry; + } + info->crl = d2i_X509_CRL(NULL, &data, len); + return info->crl != NULL ? parse_ok : parse_error; } static enum parse_result_t parse_key(X509_INFO *info, const uint8_t *data, - size_t len, int key_type) -{ - if (info->x_pkey != NULL) { - return parse_new_entry; - } - info->x_pkey = X509_PKEY_new(); - if (info->x_pkey == NULL) { - return parse_error; - } - info->x_pkey->dec_pkey = d2i_PrivateKey(key_type, NULL, &data, len); - return info->x_pkey->dec_pkey != NULL ? parse_ok : parse_error; + size_t len, int key_type) { + if (info->x_pkey != NULL) { + return parse_new_entry; + } + info->x_pkey = X509_PKEY_new(); + if (info->x_pkey == NULL) { + return parse_error; + } + info->x_pkey->dec_pkey = d2i_PrivateKey(key_type, NULL, &data, len); + return info->x_pkey->dec_pkey != NULL ? parse_ok : parse_error; } STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) -{ - X509_INFO *info = NULL; - char *name = NULL, *header = NULL; - unsigned char *data = NULL; - long len; - int ok = 0; - STACK_OF(X509_INFO) *ret = NULL; + pem_password_cb *cb, void *u) { + X509_INFO *info = NULL; + char *name = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ok = 0; + STACK_OF(X509_INFO) *ret = NULL; - if (sk == NULL) { - ret = sk_X509_INFO_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else { - ret = sk; + if (sk == NULL) { + ret = sk_X509_INFO_new_null(); + if (ret == NULL) { + return NULL; } - size_t orig_num = sk_X509_INFO_num(ret); + } else { + ret = sk; + } + size_t orig_num = sk_X509_INFO_num(ret); - info = X509_INFO_new(); - if (info == NULL) { - goto err; + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + + for (;;) { + if (!PEM_read_bio(bp, &name, &header, &data, &len)) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + ERR_clear_error(); + break; + } + goto err; } - for (;;) { - if (!PEM_read_bio(bp, &name, &header, &data, &len)) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { - ERR_clear_error(); - break; - } - goto err; - } - - enum parse_result_t (*parse_function)(X509_INFO *, const uint8_t *, - size_t, int) = NULL; - int key_type = EVP_PKEY_NONE; - if (strcmp(name, PEM_STRING_X509) == 0 || - strcmp(name, PEM_STRING_X509_OLD) == 0) { - parse_function = parse_x509; - } else if (strcmp(name, PEM_STRING_X509_TRUSTED) == 0) { - parse_function = parse_x509_aux; - } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { - parse_function = parse_crl; - } else if (strcmp(name, PEM_STRING_RSA) == 0) { - parse_function = parse_key; - key_type = EVP_PKEY_RSA; - } else if (strcmp(name, PEM_STRING_DSA) == 0) { - parse_function = parse_key; - key_type = EVP_PKEY_DSA; - } else if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { - parse_function = parse_key; - key_type = EVP_PKEY_EC; - } - - /* If a private key has a header, assume it is encrypted. */ - if (key_type != EVP_PKEY_NONE && strlen(header) > 10) { - if (info->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, info)) { - goto err; - } - info = X509_INFO_new(); - if (info == NULL) { - goto err; - } - } - /* Historically, raw entries pushed an empty key. */ - info->x_pkey = X509_PKEY_new(); - if (info->x_pkey == NULL || - !PEM_get_EVP_CIPHER_INFO(header, &info->enc_cipher)) { - goto err; - } - info->enc_data = (char *)data; - info->enc_len = (int)len; - data = NULL; - } else if (parse_function != NULL) { - EVP_CIPHER_INFO cipher; - if (!PEM_get_EVP_CIPHER_INFO(header, &cipher) || - !PEM_do_header(&cipher, data, &len, cb, u)) { - goto err; - } - enum parse_result_t result = - parse_function(info, data, len, key_type); - if (result == parse_new_entry) { - if (!sk_X509_INFO_push(ret, info)) { - goto err; - } - info = X509_INFO_new(); - if (info == NULL) { - goto err; - } - result = parse_function(info, data, len, key_type); - } - if (result != parse_ok) { - OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); - goto err; - } - } - OPENSSL_free(name); - OPENSSL_free(header); - OPENSSL_free(data); - name = NULL; - header = NULL; - data = NULL; + enum parse_result_t (*parse_function)(X509_INFO *, const uint8_t *, size_t, + int) = NULL; + int key_type = EVP_PKEY_NONE; + if (strcmp(name, PEM_STRING_X509) == 0 || + strcmp(name, PEM_STRING_X509_OLD) == 0) { + parse_function = parse_x509; + } else if (strcmp(name, PEM_STRING_X509_TRUSTED) == 0) { + parse_function = parse_x509_aux; + } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { + parse_function = parse_crl; + } else if (strcmp(name, PEM_STRING_RSA) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_RSA; + } else if (strcmp(name, PEM_STRING_DSA) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_DSA; + } else if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { + parse_function = parse_key; + key_type = EVP_PKEY_EC; } - /* Push the last entry on the stack if not empty. */ - if (info->x509 != NULL || info->crl != NULL || - info->x_pkey != NULL || info->enc_data != NULL) { + // If a private key has a header, assume it is encrypted. + if (key_type != EVP_PKEY_NONE && strlen(header) > 10) { + if (info->x_pkey != NULL) { if (!sk_X509_INFO_push(ret, info)) { - goto err; + goto err; } - info = NULL; + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + } + // Historically, raw entries pushed an empty key. + info->x_pkey = X509_PKEY_new(); + if (info->x_pkey == NULL || + !PEM_get_EVP_CIPHER_INFO(header, &info->enc_cipher)) { + goto err; + } + info->enc_data = (char *)data; + info->enc_len = (int)len; + data = NULL; + } else if (parse_function != NULL) { + EVP_CIPHER_INFO cipher; + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher) || + !PEM_do_header(&cipher, data, &len, cb, u)) { + goto err; + } + enum parse_result_t result = parse_function(info, data, len, key_type); + if (result == parse_new_entry) { + if (!sk_X509_INFO_push(ret, info)) { + goto err; + } + info = X509_INFO_new(); + if (info == NULL) { + goto err; + } + result = parse_function(info, data, len, key_type); + } + if (result != parse_ok) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + goto err; + } } - - ok = 1; - - err: - X509_INFO_free(info); - if (!ok) { - while (sk_X509_INFO_num(ret) > orig_num) { - X509_INFO_free(sk_X509_INFO_pop(ret)); - } - if (ret != sk) { - sk_X509_INFO_free(ret); - } - ret = NULL; - } - OPENSSL_free(name); OPENSSL_free(header); OPENSSL_free(data); - return ret; -} + name = NULL; + header = NULL; + data = NULL; + } -/* A TJH addition */ -int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - int i, ret = 0; - unsigned char *data = NULL; - const char *objstr = NULL; - char buf[PEM_BUFSIZE]; - unsigned char *iv = NULL; - unsigned iv_len = 0; - - if (enc != NULL) { - iv_len = EVP_CIPHER_iv_length(enc); - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); - if (objstr == NULL) { - OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); - goto err; - } + // Push the last entry on the stack if not empty. + if (info->x509 != NULL || info->crl != NULL || info->x_pkey != NULL || + info->enc_data != NULL) { + if (!sk_X509_INFO_push(ret, info)) { + goto err; } + info = NULL; + } - /* - * now for the fun part ... if we have a private key then we have to be - * able to handle a not-yet-decrypted key being written out correctly ... - * if it is decrypted or it is non-encrypted then we use the base code - */ - if (xi->x_pkey != NULL) { - if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { - if (enc == NULL) { - OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL); - goto err; - } - - /* copy from weirdo names into more normal things */ - iv = xi->enc_cipher.iv; - data = (unsigned char *)xi->enc_data; - i = xi->enc_len; - - /* - * we take the encryption data from the internal stuff rather - * than what the user has passed us ... as we have to match - * exactly for some strange reason - */ - objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); - if (objstr == NULL) { - OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); - goto err; - } - - /* create the right magic header stuff */ - assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); - buf[0] = '\0'; - PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, iv_len, (char *)iv); - - /* use the normal code to write things out */ - i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); - if (i <= 0) - goto err; - } else { - /* Add DSA/DH */ - /* normal optionally encrypted stuff */ - if (PEM_write_bio_RSAPrivateKey(bp, - xi->x_pkey->dec_pkey->pkey.rsa, - enc, kstr, klen, cb, u) <= 0) - goto err; - } - } - - /* if we have a certificate then write it out now */ - if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) - goto err; - - /* - * we are ignoring anything else that is loaded into the X509_INFO - * structure for the moment ... as I don't need it so I'm not coding it - * here and Eric can do it when this makes it into the base library --tjh - */ - - ret = 1; + ok = 1; err: - OPENSSL_cleanse(buf, PEM_BUFSIZE); + X509_INFO_free(info); + if (!ok) { + while (sk_X509_INFO_num(ret) > orig_num) { + X509_INFO_free(sk_X509_INFO_pop(ret)); + } + if (ret != sk) { + sk_X509_INFO_free(ret); + } + ret = NULL; + } + + OPENSSL_free(name); + OPENSSL_free(header); + OPENSSL_free(data); return ret; } diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_lib.c b/third_party/boringssl/kit/src/crypto/pem/pem_lib.c index 747d694e..30ba387e 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_lib.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_lib.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_lib.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -74,696 +73,717 @@ #include "../internal.h" -#define MIN_LENGTH 4 +#define MIN_LENGTH 4 -static int load_iv(char **fromp, unsigned char *to, int num); +static int load_iv(char **fromp, unsigned char *to, size_t num); static int check_pem(const char *nm, const char *name); -void PEM_proc_type(char *buf, int type) -{ - const char *str; +// PEM_proc_type appends a Proc-Type header to |buf|, determined by |type|. +static void PEM_proc_type(char buf[PEM_BUFSIZE], int type) { + const char *str; - if (type == PEM_TYPE_ENCRYPTED) - str = "ENCRYPTED"; - else if (type == PEM_TYPE_MIC_CLEAR) - str = "MIC-CLEAR"; - else if (type == PEM_TYPE_MIC_ONLY) - str = "MIC-ONLY"; - else - str = "BAD-TYPE"; + if (type == PEM_TYPE_ENCRYPTED) { + str = "ENCRYPTED"; + } else if (type == PEM_TYPE_MIC_CLEAR) { + str = "MIC-CLEAR"; + } else if (type == PEM_TYPE_MIC_ONLY) { + str = "MIC-ONLY"; + } else { + str = "BAD-TYPE"; + } - OPENSSL_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); - OPENSSL_strlcat(buf, str, PEM_BUFSIZE); - OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE); + OPENSSL_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); + OPENSSL_strlcat(buf, str, PEM_BUFSIZE); + OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE); } -void PEM_dek_info(char *buf, const char *type, int len, char *str) -{ - static const unsigned char map[17] = "0123456789ABCDEF"; - long i; - int j; +// PEM_dek_info appends a DEK-Info header to |buf|, with an algorithm of |type| +// and a single parameter, specified by hex-encoding |len| bytes from |str|. +static void PEM_dek_info(char buf[PEM_BUFSIZE], const char *type, size_t len, + char *str) { + static const unsigned char map[17] = "0123456789ABCDEF"; - OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); - OPENSSL_strlcat(buf, type, PEM_BUFSIZE); - OPENSSL_strlcat(buf, ",", PEM_BUFSIZE); - j = strlen(buf); - if (j + (len * 2) + 1 > PEM_BUFSIZE) - return; - for (i = 0; i < len; i++) { - buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; - buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; - } - buf[j + i * 2] = '\n'; - buf[j + i * 2 + 1] = '\0'; + OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); + OPENSSL_strlcat(buf, type, PEM_BUFSIZE); + OPENSSL_strlcat(buf, ",", PEM_BUFSIZE); + size_t buf_len = strlen(buf); + // We must write an additional |2 * len + 2| bytes after |buf_len|, including + // the trailing newline and NUL. + if (len > (PEM_BUFSIZE - buf_len - 2) / 2) { + return; + } + for (size_t i = 0; i < len; i++) { + buf[buf_len + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[buf_len + i * 2 + 1] = map[(str[i]) & 0x0f]; + } + buf[buf_len + len * 2] = '\n'; + buf[buf_len + len * 2 + 1] = '\0'; } void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, - pem_password_cb *cb, void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return NULL; - } - void *ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); - BIO_free(b); - return ret; + pem_password_cb *cb, void *u) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + void *ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); + BIO_free(b); + return ret; } -static int check_pem(const char *nm, const char *name) -{ - /* Normal matching nm and name */ - if (!strcmp(nm, name)) - return 1; +static int check_pem(const char *nm, const char *name) { + // Normal matching nm and name + if (!strcmp(nm, name)) { + return 1; + } - /* Make PEM_STRING_EVP_PKEY match any private key */ + // Make PEM_STRING_EVP_PKEY match any private key - if (!strcmp(name, PEM_STRING_EVP_PKEY)) { - return !strcmp(nm, PEM_STRING_PKCS8) || - !strcmp(nm, PEM_STRING_PKCS8INF) || - !strcmp(nm, PEM_STRING_RSA) || - !strcmp(nm, PEM_STRING_EC) || - !strcmp(nm, PEM_STRING_DSA); - } + if (!strcmp(name, PEM_STRING_EVP_PKEY)) { + return !strcmp(nm, PEM_STRING_PKCS8) || !strcmp(nm, PEM_STRING_PKCS8INF) || + !strcmp(nm, PEM_STRING_RSA) || !strcmp(nm, PEM_STRING_EC) || + !strcmp(nm, PEM_STRING_DSA); + } - /* Permit older strings */ + // Permit older strings - if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) - return 1; + if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) { + return 1; + } - if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && - !strcmp(name, PEM_STRING_X509_REQ)) - return 1; + if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && + !strcmp(name, PEM_STRING_X509_REQ)) { + return 1; + } - /* Allow normal certs to be read as trusted certs */ - if (!strcmp(nm, PEM_STRING_X509) && - !strcmp(name, PEM_STRING_X509_TRUSTED)) - return 1; + // Allow normal certs to be read as trusted certs + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_X509_TRUSTED)) { + return 1; + } - if (!strcmp(nm, PEM_STRING_X509_OLD) && - !strcmp(name, PEM_STRING_X509_TRUSTED)) - return 1; + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) { + return 1; + } - /* Some CAs use PKCS#7 with CERTIFICATE headers */ - if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) - return 1; + // Some CAs use PKCS#7 with CERTIFICATE headers + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) { + return 1; + } - if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && - !strcmp(name, PEM_STRING_PKCS7)) - return 1; + if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && !strcmp(name, PEM_STRING_PKCS7)) { + return 1; + } #ifndef OPENSSL_NO_CMS - if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) - return 1; - /* Allow CMS to be read from PKCS#7 headers */ - if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) - return 1; + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) { + return 1; + } + // Allow CMS to be read from PKCS#7 headers + if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) { + return 1; + } #endif - return 0; + return 0; } -static const EVP_CIPHER *cipher_by_name(const char *name) -{ - /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. Note - * the PEM code assumes that ciphers have at least 8 bytes of IV, at most 20 - * bytes of overhead and generally behave like CBC mode. */ - if (0 == strcmp(name, SN_des_cbc)) { - return EVP_des_cbc(); - } else if (0 == strcmp(name, SN_des_ede3_cbc)) { - return EVP_des_ede3_cbc(); - } else if (0 == strcmp(name, SN_aes_128_cbc)) { - return EVP_aes_128_cbc(); - } else if (0 == strcmp(name, SN_aes_192_cbc)) { - return EVP_aes_192_cbc(); - } else if (0 == strcmp(name, SN_aes_256_cbc)) { - return EVP_aes_256_cbc(); - } else { - return NULL; - } +static const EVP_CIPHER *cipher_by_name(const char *name) { + // This is similar to the (deprecated) function |EVP_get_cipherbyname|. Note + // the PEM code assumes that ciphers have at least 8 bytes of IV, at most 20 + // bytes of overhead and generally behave like CBC mode. + if (0 == strcmp(name, SN_des_cbc)) { + return EVP_des_cbc(); + } else if (0 == strcmp(name, SN_des_ede3_cbc)) { + return EVP_des_ede3_cbc(); + } else if (0 == strcmp(name, SN_aes_128_cbc)) { + return EVP_aes_128_cbc(); + } else if (0 == strcmp(name, SN_aes_192_cbc)) { + return EVP_aes_192_cbc(); + } else if (0 == strcmp(name, SN_aes_256_cbc)) { + return EVP_aes_256_cbc(); + } else { + return NULL; + } } int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, - void *u) -{ - EVP_CIPHER_INFO cipher; - char *nm = NULL, *header = NULL; - unsigned char *data = NULL; - long len; - int ret = 0; + void *u) { + EVP_CIPHER_INFO cipher; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ret = 0; - for (;;) { - if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { - uint32_t error = ERR_peek_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { - ERR_add_error_data(2, "Expecting: ", name); - } - return 0; - } - if (check_pem(nm, name)) - break; - OPENSSL_free(nm); - OPENSSL_free(header); - OPENSSL_free(data); + for (;;) { + if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { + uint32_t error = ERR_peek_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + ERR_add_error_data(2, "Expecting: ", name); + } + return 0; } - if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) - goto err; - if (!PEM_do_header(&cipher, data, &len, cb, u)) - goto err; - - *pdata = data; - *plen = len; - - if (pnm) - *pnm = nm; - - ret = 1; - - err: - if (!ret || !pnm) - OPENSSL_free(nm); + if (check_pem(nm, name)) { + break; + } + OPENSSL_free(nm); OPENSSL_free(header); - if (!ret) - OPENSSL_free(data); - return ret; -} - -int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return 0; - } - int ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); - BIO_free(b); - return ret; -} - -int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) -{ - EVP_CIPHER_CTX ctx; - int dsize = 0, i, j, ret = 0; - unsigned char *p, *data = NULL; - const char *objstr = NULL; - char buf[PEM_BUFSIZE]; - unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char iv[EVP_MAX_IV_LENGTH]; - - if (enc != NULL) { - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); - if (objstr == NULL || - cipher_by_name(objstr) == NULL || - EVP_CIPHER_iv_length(enc) < 8) { - OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); - goto err; - } - } - - if ((dsize = i2d(x, NULL)) < 0) { - OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); - dsize = 0; - goto err; - } - /* dzise + 8 bytes are needed */ - /* actually it needs the cipher block size extra... */ - data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); - if (data == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - p = data; - i = i2d(x, &p); - - if (enc != NULL) { - const unsigned iv_len = EVP_CIPHER_iv_length(enc); - - if (kstr == NULL) { - klen = 0; - if (!callback) - callback = PEM_def_callback; - klen = (*callback) (buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); - goto err; - } - kstr = (unsigned char *)buf; - } - assert(iv_len <= (int)sizeof(iv)); - if (!RAND_bytes(iv, iv_len)) /* Generate a salt */ - goto err; - /* - * The 'iv' is used as the iv and as a salt. It is NOT taken from - * the BytesToKey function - */ - if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) - goto err; - - if (kstr == (unsigned char *)buf) - OPENSSL_cleanse(buf, PEM_BUFSIZE); - - assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); - - buf[0] = '\0'; - PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, iv_len, (char *)iv); - /* k=strlen(buf); */ - - EVP_CIPHER_CTX_init(&ctx); - ret = 1; - if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) - || !EVP_EncryptUpdate(&ctx, data, &j, data, i) - || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) - ret = 0; - else - i += j; - EVP_CIPHER_CTX_cleanup(&ctx); - if (ret == 0) - goto err; - } else { - ret = 1; - buf[0] = '\0'; - } - i = PEM_write_bio(bp, name, buf, data, i); - if (i <= 0) - ret = 0; - err: - OPENSSL_cleanse(key, sizeof(key)); - OPENSSL_cleanse(iv, sizeof(iv)); - OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); - OPENSSL_cleanse(buf, PEM_BUFSIZE); OPENSSL_free(data); - return (ret); + } + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) { + goto err; + } + if (!PEM_do_header(&cipher, data, &len, cb, u)) { + goto err; + } + + *pdata = data; + *plen = len; + + if (pnm) { + *pnm = nm; + } + + ret = 1; + +err: + if (!ret || !pnm) { + OPENSSL_free(nm); + } + OPENSSL_free(header); + if (!ret) { + OPENSSL_free(data); + } + return ret; +} + +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); + BIO_free(b); + return ret; +} + +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) { + EVP_CIPHER_CTX ctx; + int dsize = 0, i, j, ret = 0; + unsigned char *p, *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL || cipher_by_name(objstr) == NULL || + EVP_CIPHER_iv_length(enc) < 8) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + dsize = 0; + goto err; + } + // dzise + 8 bytes are needed + // actually it needs the cipher block size extra... + data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); + if (data == NULL) { + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + const unsigned iv_len = EVP_CIPHER_iv_length(enc); + + if (kstr == NULL) { + klen = 0; + if (!callback) { + callback = PEM_def_callback; + } + klen = (*callback)(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); + goto err; + } + kstr = (unsigned char *)buf; + } + assert(iv_len <= sizeof(iv)); + if (!RAND_bytes(iv, iv_len)) { // Generate a salt + goto err; + } + // The 'iv' is used as the iv and as a salt. It is NOT taken from + // the BytesToKey function + if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) { + goto err; + } + + if (kstr == (unsigned char *)buf) { + OPENSSL_cleanse(buf, PEM_BUFSIZE); + } + + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof(buf)); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, iv_len, (char *)iv); + // k=strlen(buf); + + EVP_CIPHER_CTX_init(&ctx); + ret = 1; + if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) || + !EVP_EncryptUpdate(&ctx, data, &j, data, i) || + !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) { + ret = 0; + } else { + i += j; + } + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) { + goto err; + } + } else { + ret = 1; + buf[0] = '\0'; + } + i = PEM_write_bio(bp, name, buf, data, i); + if (i <= 0) { + ret = 0; + } +err: + OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(iv, sizeof(iv)); + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + OPENSSL_free(data); + return ret; } int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, - pem_password_cb *callback, void *u) -{ - int i = 0, j, o, klen; - long len; - EVP_CIPHER_CTX ctx; - unsigned char key[EVP_MAX_KEY_LENGTH]; - char buf[PEM_BUFSIZE]; + pem_password_cb *callback, void *u) { + int i = 0, j, o, klen; + long len; + EVP_CIPHER_CTX ctx; + unsigned char key[EVP_MAX_KEY_LENGTH]; + char buf[PEM_BUFSIZE]; - len = *plen; + len = *plen; - if (cipher->cipher == NULL) - return (1); + if (cipher->cipher == NULL) { + return 1; + } - klen = 0; - if (!callback) - callback = PEM_def_callback; - klen = callback(buf, PEM_BUFSIZE, 0, u); - if (klen <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); - return (0); - } + klen = 0; + if (!callback) { + callback = PEM_def_callback; + } + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + return 0; + } - if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), - (unsigned char *)buf, klen, 1, key, NULL)) - return 0; + if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), + (unsigned char *)buf, klen, 1, key, NULL)) { + return 0; + } - j = (int)len; - EVP_CIPHER_CTX_init(&ctx); - o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); - if (o) - o = EVP_DecryptUpdate(&ctx, data, &i, data, j); - if (o) - o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_cleanse((char *)buf, sizeof(buf)); - OPENSSL_cleanse((char *)key, sizeof(key)); - if (!o) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); - return (0); - } - j += i; - *plen = j; - return (1); + j = (int)len; + EVP_CIPHER_CTX_init(&ctx); + o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); + if (o) { + o = EVP_DecryptUpdate(&ctx, data, &i, data, j); + } + if (o) { + o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); + } + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_cleanse((char *)buf, sizeof(buf)); + OPENSSL_cleanse((char *)key, sizeof(key)); + if (!o) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); + return 0; + } + j += i; + *plen = j; + return 1; } -int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) -{ - const EVP_CIPHER *enc = NULL; - char *p, c; - char **header_pp = &header; +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) { + const EVP_CIPHER *enc = NULL; + char *p, c; + char **header_pp = &header; - cipher->cipher = NULL; - OPENSSL_memset(cipher->iv, 0, sizeof(cipher->iv)); - if ((header == NULL) || (*header == '\0') || (*header == '\n')) - return (1); - if (strncmp(header, "Proc-Type: ", 11) != 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); - return (0); - } - header += 11; - if (*header != '4') - return (0); - header++; - if (*header != ',') - return (0); - header++; - if (strncmp(header, "ENCRYPTED", 9) != 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); - return (0); - } - for (; (*header != '\n') && (*header != '\0'); header++) ; - if (*header == '\0') { - OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); - return (0); + cipher->cipher = NULL; + OPENSSL_memset(cipher->iv, 0, sizeof(cipher->iv)); + if ((header == NULL) || (*header == '\0') || (*header == '\n')) { + return 1; + } + if (strncmp(header, "Proc-Type: ", 11) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); + return 0; + } + header += 11; + if (*header != '4') { + return 0; + } + header++; + if (*header != ',') { + return 0; + } + header++; + if (strncmp(header, "ENCRYPTED", 9) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); + return 0; + } + for (; (*header != '\n') && (*header != '\0'); header++) { + ; + } + if (*header == '\0') { + OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); + return 0; + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); + return 0; + } + header += 10; + + p = header; + for (;;) { + c = *header; + if (!((c >= 'A' && c <= 'Z') || c == '-' || + OPENSSL_isdigit(c))) { + break; } header++; - if (strncmp(header, "DEK-Info: ", 10) != 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); - return (0); - } - header += 10; + } + *header = '\0'; + cipher->cipher = enc = cipher_by_name(p); + *header = c; + header++; - p = header; - for (;;) { - c = *header; - if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || - ((c >= '0') && (c <= '9')))) - break; - header++; - } - *header = '\0'; - cipher->cipher = enc = cipher_by_name(p); - *header = c; - header++; + if (enc == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return 0; + } + // The IV parameter must be at least 8 bytes long to be used as the salt in + // the KDF. (This should not happen given |cipher_by_name|.) + if (EVP_CIPHER_iv_length(enc) < 8) { + assert(0); + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return 0; + } + if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) { + return 0; + } - if (enc == NULL) { - OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); - return (0); - } - // The IV parameter must be at least 8 bytes long to be used as the salt in - // the KDF. (This should not happen given |cipher_by_name|.) - if (EVP_CIPHER_iv_length(enc) < 8) { - assert(0); - OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); - return 0; - } - if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) - return (0); - - return (1); + return 1; } -static int load_iv(char **fromp, unsigned char *to, int num) -{ - int v, i; - char *from; +static int load_iv(char **fromp, unsigned char *to, size_t num) { + uint8_t v; + char *from; - from = *fromp; - for (i = 0; i < num; i++) - to[i] = 0; - num *= 2; - for (i = 0; i < num; i++) { - if ((*from >= '0') && (*from <= '9')) - v = *from - '0'; - else if ((*from >= 'A') && (*from <= 'F')) - v = *from - 'A' + 10; - else if ((*from >= 'a') && (*from <= 'f')) - v = *from - 'a' + 10; - else { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS); - return (0); - } - from++; - to[i / 2] |= v << (long)((!(i & 1)) * 4); + from = *fromp; + for (size_t i = 0; i < num; i++) { + to[i] = 0; + } + num *= 2; + for (size_t i = 0; i < num; i++) { + if (!OPENSSL_fromxdigit(&v, *from)) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS); + return 0; } + from++; + to[i / 2] |= v << (!(i & 1)) * 4; + } - *fromp = from; - return (1); + *fromp = from; + return 1; } int PEM_write(FILE *fp, const char *name, const char *header, - const unsigned char *data, long len) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return 0; - } - int ret = PEM_write_bio(b, name, header, data, len); - BIO_free(b); - return (ret); + const unsigned char *data, long len) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_write_bio(b, name, header, data, len); + BIO_free(b); + return ret; } int PEM_write_bio(BIO *bp, const char *name, const char *header, - const unsigned char *data, long len) -{ - int nlen, n, i, j, outl; - unsigned char *buf = NULL; - EVP_ENCODE_CTX ctx; - int reason = ERR_R_BUF_LIB; + const unsigned char *data, long len) { + int nlen, n, i, j, outl; + unsigned char *buf = NULL; + EVP_ENCODE_CTX ctx; + int reason = ERR_R_BUF_LIB; - EVP_EncodeInit(&ctx); - nlen = strlen(name); + EVP_EncodeInit(&ctx); + nlen = strlen(name); - if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || - (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) - goto err; + if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) { + goto err; + } - i = strlen(header); - if (i > 0) { - if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) - goto err; + i = strlen(header); + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) { + goto err; } + } - buf = OPENSSL_malloc(PEM_BUFSIZE * 8); - if (buf == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } + buf = OPENSSL_malloc(PEM_BUFSIZE * 8); + if (buf == NULL) { + goto err; + } - i = j = 0; - while (len > 0) { - n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); - EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); - if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) - goto err; - i += outl; - len -= n; - j += n; + i = j = 0; + while (len > 0) { + n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); + EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) { + goto err; } - EVP_EncodeFinal(&ctx, buf, &outl); - if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) - goto err; + i += outl; + len -= n; + j += n; + } + EVP_EncodeFinal(&ctx, buf, &outl); + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) { + goto err; + } + OPENSSL_free(buf); + buf = NULL; + if ((BIO_write(bp, "-----END ", 9) != 9) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) { + goto err; + } + return i + outl; +err: + if (buf) { OPENSSL_free(buf); - buf = NULL; - if ((BIO_write(bp, "-----END ", 9) != 9) || - (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) - goto err; - return (i + outl); - err: - if (buf) { - OPENSSL_free(buf); - } - OPENSSL_PUT_ERROR(PEM, reason); - return (0); + } + OPENSSL_PUT_ERROR(PEM, reason); + return 0; } int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, - long *len) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return 0; - } - int ret = PEM_read_bio(b, name, header, data, len); - BIO_free(b); - return (ret); + long *len) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_read_bio(b, name, header, data, len); + BIO_free(b); + return ret; } int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, - long *len) -{ - EVP_ENCODE_CTX ctx; - int end = 0, i, k, bl = 0, hl = 0, nohead = 0; - char buf[256]; - BUF_MEM *nameB; - BUF_MEM *headerB; - BUF_MEM *dataB, *tmpB; + long *len) { + EVP_ENCODE_CTX ctx; + int end = 0, i, k, bl = 0, hl = 0, nohead = 0; + char buf[256]; + BUF_MEM *nameB; + BUF_MEM *headerB; + BUF_MEM *dataB, *tmpB; - nameB = BUF_MEM_new(); - headerB = BUF_MEM_new(); - dataB = BUF_MEM_new(); - if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { - BUF_MEM_free(nameB); - BUF_MEM_free(headerB); - BUF_MEM_free(dataB); - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - return (0); - } - - buf[254] = '\0'; - for (;;) { - i = BIO_gets(bp, buf, 254); - - if (i <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE); - goto err; - } - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (strncmp(buf, "-----BEGIN ", 11) == 0) { - i = strlen(&(buf[11])); - - if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) - continue; - if (!BUF_MEM_grow(nameB, i + 9)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); - nameB->data[i - 6] = '\0'; - break; - } - } - hl = 0; - if (!BUF_MEM_grow(headerB, 256)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - headerB->data[0] = '\0'; - for (;;) { - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (buf[0] == '\n') - break; - if (!BUF_MEM_grow(headerB, hl + i + 9)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - if (strncmp(buf, "-----END ", 9) == 0) { - nohead = 1; - break; - } - OPENSSL_memcpy(&(headerB->data[hl]), buf, i); - headerB->data[hl + i] = '\0'; - hl += i; - } - - bl = 0; - if (!BUF_MEM_grow(dataB, 1024)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - dataB->data[0] = '\0'; - if (!nohead) { - for (;;) { - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (i != 65) - end = 1; - if (strncmp(buf, "-----END ", 9) == 0) - break; - if (i > 65) - break; - if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { - OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_memcpy(&(dataB->data[bl]), buf, i); - dataB->data[bl + i] = '\0'; - bl += i; - if (end) { - buf[0] = '\0'; - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - break; - } - } - } else { - tmpB = headerB; - headerB = dataB; - dataB = tmpB; - bl = hl; - } - i = strlen(nameB->data); - if ((strncmp(buf, "-----END ", 9) != 0) || - (strncmp(nameB->data, &(buf[9]), i) != 0) || - (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE); - goto err; - } - - EVP_DecodeInit(&ctx); - i = EVP_DecodeUpdate(&ctx, - (unsigned char *)dataB->data, &bl, - (unsigned char *)dataB->data, bl); - if (i < 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); - goto err; - } - i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); - if (i < 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); - goto err; - } - bl += k; - - if (bl == 0) - goto err; - *name = nameB->data; - *header = headerB->data; - *data = (unsigned char *)dataB->data; - *len = bl; - OPENSSL_free(nameB); - OPENSSL_free(headerB); - OPENSSL_free(dataB); - return (1); - err: + nameB = BUF_MEM_new(); + headerB = BUF_MEM_new(); + dataB = BUF_MEM_new(); + if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { BUF_MEM_free(nameB); BUF_MEM_free(headerB); BUF_MEM_free(dataB); - return (0); + return 0; + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE); + goto err; + } + + while ((i >= 0) && (buf[i] <= ' ')) { + i--; + } + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (strncmp(buf, "-----BEGIN ", 11) == 0) { + i = strlen(&(buf[11])); + + if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) { + continue; + } + if (!BUF_MEM_grow(nameB, i + 9)) { + goto err; + } + OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + goto err; + } + headerB->data[0] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) { + break; + } + + while ((i >= 0) && (buf[i] <= ' ')) { + i--; + } + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (buf[0] == '\n') { + break; + } + if (!BUF_MEM_grow(headerB, hl + i + 9)) { + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + OPENSSL_memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + goto err; + } + dataB->data[0] = '\0'; + if (!nohead) { + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) { + break; + } + + while ((i >= 0) && (buf[i] <= ' ')) { + i--; + } + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (i != 65) { + end = 1; + } + if (strncmp(buf, "-----END ", 9) == 0) { + break; + } + if (i > 65) { + break; + } + if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { + goto err; + } + OPENSSL_memcpy(&(dataB->data[bl]), buf, i); + dataB->data[bl + i] = '\0'; + bl += i; + if (end) { + buf[0] = '\0'; + i = BIO_gets(bp, buf, 254); + if (i <= 0) { + break; + } + + while ((i >= 0) && (buf[i] <= ' ')) { + i--; + } + buf[++i] = '\n'; + buf[++i] = '\0'; + + break; + } + } + } else { + tmpB = headerB; + headerB = dataB; + dataB = tmpB; + bl = hl; + } + i = strlen(nameB->data); + if ((strncmp(buf, "-----END ", 9) != 0) || + (strncmp(nameB->data, &(buf[9]), i) != 0) || + (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE); + goto err; + } + + EVP_DecodeInit(&ctx); + i = EVP_DecodeUpdate(&ctx, (unsigned char *)dataB->data, &bl, + (unsigned char *)dataB->data, bl); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + bl += k; + + if (bl == 0) { + goto err; + } + *name = nameB->data; + *header = headerB->data; + *data = (unsigned char *)dataB->data; + *len = bl; + OPENSSL_free(nameB); + OPENSSL_free(headerB); + OPENSSL_free(dataB); + return 1; +err: + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + return 0; } -int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) -{ - if (!buf || !userdata || size < 0) { - return 0; - } - size_t len = strlen((char *)userdata); - if (len >= (size_t)size) { - return 0; - } - OPENSSL_strlcpy(buf, userdata, (size_t)size); - return len; +int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) { + if (!buf || !userdata || size < 0) { + return 0; + } + size_t len = strlen((char *)userdata); + if (len >= (size_t)size) { + return 0; + } + OPENSSL_strlcpy(buf, userdata, (size_t)size); + return (int)len; } diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_oth.c b/third_party/boringssl/kit/src/crypto/pem/pem_oth.c index 797f8223..a94fed9b 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_oth.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_oth.c @@ -1,4 +1,3 @@ -/* crypto/pem/pem_oth.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -60,28 +59,29 @@ #include #include -#include #include +#include #include #include #include -/* Handle 'other' PEMs: not private keys */ +// Handle 'other' PEMs: not private keys void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, - pem_password_cb *cb, void *u) -{ - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - char *ret = NULL; + pem_password_cb *cb, void *u) { + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + char *ret = NULL; - if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) - return NULL; - p = data; - ret = d2i(x, &p, len); - if (ret == NULL) - OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); - OPENSSL_free(data); - return ret; + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) { + return NULL; + } + p = data; + ret = d2i(x, &p, len); + if (ret == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + } + OPENSSL_free(data); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_pk8.c b/third_party/boringssl/kit/src/crypto/pem/pem_pk8.c index 8a1f0409..610f36ca 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_pk8.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_pk8.c @@ -64,187 +64,180 @@ #include #include -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); -static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); - -/* - * These functions write a private key in PKCS#8 format: it is a "drop in" - * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' - * is NULL then it uses the unencrypted private key form. The 'nid' versions - * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. - */ - -int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); -} - -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; - char buf[PEM_BUFSIZE]; - int ret; - if (!(p8inf = EVP_PKEY2PKCS8(x))) { - OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); - return 0; - } - if (enc || (nid != -1)) { - if (!kstr) { - klen = 0; - if (!cb) - cb = PEM_def_callback; - klen = cb(buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return 0; - } + pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u); - kstr = buf; - } - p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if (kstr == buf) - OPENSSL_cleanse(buf, klen); +// These functions write a private key in PKCS#8 format: it is a "drop in" +// replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' +// is NULL then it uses the unencrypted private key form. The 'nid' versions +// uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, + char *kstr, int klen, pem_password_cb *cb, + void *u) { + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) { + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, + void *u) { + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, char *kstr, + int klen, pem_password_cb *cb, void *u) { + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) { + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + if (!(p8inf = EVP_PKEY2PKCS8(x))) { + OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + klen = 0; + if (!cb) { + cb = PEM_def_callback; + } + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); PKCS8_PRIV_KEY_INFO_free(p8inf); - if (isder) - ret = i2d_PKCS8_bio(bp, p8); - else - ret = PEM_write_bio_PKCS8(bp, p8); - X509_SIG_free(p8); - return ret; - } else { - if (isder) - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - else - ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; + return 0; + } + + kstr = buf; } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) { + OPENSSL_cleanse(buf, klen); + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (isder) { + ret = i2d_PKCS8_bio(bp, p8); + } else { + ret = PEM_write_bio_PKCS8(bp, p8); + } + X509_SIG_free(p8); + return ret; + } else { + if (isder) { + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + } else { + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } } EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - PKCS8_PRIV_KEY_INFO *p8inf = NULL; - X509_SIG *p8 = NULL; - int klen; - EVP_PKEY *ret; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_PKCS8_bio(bp, NULL); - if (!p8) - return NULL; + void *u) { + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); + if (!p8) { + return NULL; + } - klen = 0; - if (!cb) - cb = PEM_def_callback; - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - if (klen <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); - return NULL; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); + klen = 0; + if (!cb) { + cb = PEM_def_callback; + } + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (!p8inf) - return NULL; - ret = EVP_PKCS82PKEY(p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if (!ret) - return NULL; - if (x) { - if (*x) - EVP_PKEY_free(*x); - *x = ret; + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) { + return NULL; + } + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (!ret) { + return NULL; + } + if (x) { + if (*x) { + EVP_PKEY_free(*x); } - return ret; + *x = ret; + } + return ret; } -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) { + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); } -int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, char *kstr, + int klen, pem_password_cb *cb, void *u) { + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); } -int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, + char *kstr, int klen, pem_password_cb *cb, + void *u) { + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); } -int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, - void *u) -{ - return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) { + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); } -static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, +static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - BIO *bp; - int ret; - if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return (0); - } - ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); - BIO_free(bp); - return ret; + pem_password_cb *cb, void *u) { + BIO *bp; + int ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; } EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - BIO *bp; - EVP_PKEY *ret; - if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return NULL; - } - ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); - BIO_free(bp); - return ret; + void *u) { + BIO *bp; + EVP_PKEY *ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; } @@ -252,4 +245,4 @@ IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, - PKCS8_PRIV_KEY_INFO) + PKCS8_PRIV_KEY_INFO) diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_pkey.c b/third_party/boringssl/kit/src/crypto/pem/pem_pkey.c index 48d8c966..2d28d6c0 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_pkey.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_pkey.c @@ -69,146 +69,114 @@ #include EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - EVP_PKEY *ret = NULL; + void *u) { + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + EVP_PKEY *ret = NULL; - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) - return NULL; - p = data; + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) { + return NULL; + } + p = data; - if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - if (*x) - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - X509_SIG *p8; - int klen; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if (!p8) - goto p8err; - - klen = 0; - if (!cb) - cb = PEM_def_callback; - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - if (klen <= 0) { - OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); - goto err; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - if (*x) - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm, PEM_STRING_RSA) == 0) { - /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the - * standalone format. This and the cases below probably should not - * accept PKCS#8. */ - ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); - } else if (strcmp(nm, PEM_STRING_EC) == 0) { - ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); - } else if (strcmp(nm, PEM_STRING_DSA) == 0) { - ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); + if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (!p8inf) { + goto p8err; + } + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) { + EVP_PKEY_free((EVP_PKEY *)*x); + } + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if (!p8) { + goto p8err; } - p8err: - if (ret == NULL) - OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); - err: - OPENSSL_free(nm); - OPENSSL_free(data); - return (ret); + klen = 0; + if (!cb) { + cb = PEM_def_callback; + } + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) { + goto p8err; + } + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) { + EVP_PKEY_free((EVP_PKEY *)*x); + } + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_RSA) == 0) { + // TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the + // standalone format. This and the cases below probably should not + // accept PKCS#8. + ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); + } else if (strcmp(nm, PEM_STRING_EC) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); + } else if (strcmp(nm, PEM_STRING_DSA) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); + } +p8err: + if (ret == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + } + +err: + OPENSSL_free(nm); + OPENSSL_free(data); + return ret; } int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u); + unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) { + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u); } EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return NULL; - } - EVP_PKEY *ret = PEM_read_bio_PrivateKey(b, x, cb, u); - BIO_free(b); - return ret; + void *u) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return NULL; + } + EVP_PKEY *ret = PEM_read_bio_PrivateKey(b, x, cb, u); + BIO_free(b); + return ret; } int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return 0; - } - int ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); - BIO_free(b); - return ret; -} - - -/* Transparently read in PKCS#3 or X9.42 DH parameters */ - -DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - DH *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) - return NULL; - p = data; - - ret = d2i_DHparams(x, &p, len); - - if (ret == NULL) - OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); - return ret; -} - -DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); - return NULL; - } - DH *ret = PEM_read_bio_DHparams(b, x, cb, u); - BIO_free(b); - return ret; + unsigned char *kstr, int klen, pem_password_cb *cb, + void *u) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + int ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_x509.c b/third_party/boringssl/kit/src/crypto/pem/pem_x509.c index 97f814db..fbaf6ca6 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_x509.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_x509.c @@ -1,4 +1,3 @@ -/* pem_x509.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. diff --git a/third_party/boringssl/kit/src/crypto/pem/pem_xaux.c b/third_party/boringssl/kit/src/crypto/pem/pem_xaux.c index b0cceca3..5967175f 100644 --- a/third_party/boringssl/kit/src/crypto/pem/pem_xaux.c +++ b/third_party/boringssl/kit/src/crypto/pem/pem_xaux.c @@ -1,4 +1,3 @@ -/* pem_xaux.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. diff --git a/third_party/boringssl/kit/src/crypto/perlasm/arm-xlate.pl b/third_party/boringssl/kit/src/crypto/perlasm/arm-xlate.pl index c000e020..e876c8b2 100755 --- a/third_party/boringssl/kit/src/crypto/perlasm/arm-xlate.pl +++ b/third_party/boringssl/kit/src/crypto/perlasm/arm-xlate.pl @@ -151,6 +151,28 @@ sub expand_line { return $line; } +my ($arch_defines, $target_defines); +if ($flavour =~ /32/) { + $arch_defines = "defined(__ARMEL__)"; +} elsif ($flavour =~ /64/) { + $arch_defines = "defined(__AARCH64EL__)"; +} else { + die "unknown architecture: $flavour"; +} +if ($flavour =~ /linux/) { + # Although the flavour is specified as "linux", it is really used by all + # ELF platforms. + $target_defines = "defined(__ELF__)"; +} elsif ($flavour =~ /ios/) { + # Although the flavour is specified as "ios", it is really used by all Apple + # platforms. + $target_defines = "defined(__APPLE__)"; +} elsif ($flavour =~ /win/) { + $target_defines = "defined(_WIN32)"; +} else { + die "unknown target: $flavour"; +} + print <<___; // This file is generated from a similarly-named Perl script in the BoringSSL // source tree. Do not edit by hand. @@ -162,12 +184,9 @@ print <<___; #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) +#if !defined(OPENSSL_NO_ASM) && $arch_defines && $target_defines ___ -print "#if defined(__arm__)\n" if ($flavour eq "linux32"); -print "#if defined(__aarch64__)\n" if ($flavour eq "linux64" || $flavour eq "win64"); - print "#if defined(BORINGSSL_PREFIX)\n"; print "#include \n"; print "#endif\n"; @@ -239,10 +258,12 @@ while(my $line=<>) { print "\n"; } -print "#endif\n" if ($flavour eq "linux32" || $flavour eq "linux64" || $flavour eq "win64"); -print "#endif // !OPENSSL_NO_ASM\n"; - -# See https://www.airs.com/blog/archives/518. -print ".section\t.note.GNU-stack,\"\",\%progbits\n" if ($flavour =~ /linux/); +print <<___; +#endif // !OPENSSL_NO_ASM && $arch_defines && $target_defines +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",\%progbits +#endif +___ close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/perlasm/ppc-xlate.pl b/third_party/boringssl/kit/src/crypto/perlasm/ppc-xlate.pl deleted file mode 100644 index fff9c004..00000000 --- a/third_party/boringssl/kit/src/crypto/perlasm/ppc-xlate.pl +++ /dev/null @@ -1,317 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the OpenSSL license (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -my $flavour = shift; -my $output = shift; -open STDOUT,">$output" || die "can't open $output: $!"; - -my %GLOBALS; -my %TYPES; -my $dotinlocallabels=($flavour=~/linux/)?1:0; - -################################################################ -# directives which need special treatment on different platforms -################################################################ -my $type = sub { - my ($dir,$name,$type) = @_; - - $TYPES{$name} = $type; - if ($flavour =~ /linux/) { - $name =~ s|^\.||; - ".type $name,$type"; - } else { - ""; - } -}; -my $globl = sub { - my $junk = shift; - my $name = shift; - my $global = \$GLOBALS{$name}; - my $type = \$TYPES{$name}; - my $ret; - - $name =~ s|^\.||; - - SWITCH: for ($flavour) { - /aix/ && do { if (!$$type) { - $$type = "\@function"; - } - if ($$type =~ /function/) { - $name = ".$name"; - } - last; - }; - /osx/ && do { $name = "_$name"; - last; - }; - /linux.*(32|64le)/ - && do { $ret .= ".globl $name"; - if (!$$type) { - $ret .= "\n.type $name,\@function"; - $$type = "\@function"; - } - last; - }; - /linux.*64/ && do { $ret .= ".globl $name"; - if (!$$type) { - $ret .= "\n.type $name,\@function"; - $$type = "\@function"; - } - if ($$type =~ /function/) { - $ret .= "\n.section \".opd\",\"aw\""; - $ret .= "\n.align 3"; - $ret .= "\n$name:"; - $ret .= "\n.quad .$name,.TOC.\@tocbase,0"; - $ret .= "\n.previous"; - $name = ".$name"; - } - last; - }; - } - - $ret = ".globl $name" if (!$ret); - $$global = $name; - $ret; -}; -my $text = sub { - my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; - $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); - $ret; -}; -my $machine = sub { - my $junk = shift; - my $arch = shift; - if ($flavour =~ /osx/) - { $arch =~ s/\"//g; - $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any"); - } - ".machine $arch"; -}; -my $size = sub { - if ($flavour =~ /linux/) - { shift; - my $name = shift; - my $real = $GLOBALS{$name} ? \$GLOBALS{$name} : \$name; - my $ret = ".size $$real,.-$$real"; - $name =~ s|^\.||; - if ($$real ne $name) { - $ret .= "\n.size $name,.-$$real"; - } - $ret; - } - else - { ""; } -}; -my $asciz = sub { - shift; - my $line = join(",",@_); - if ($line =~ /^"(.*)"$/) - { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; } - else - { ""; } -}; -my $quad = sub { - shift; - my @ret; - my ($hi,$lo); - for (@_) { - if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io) - { $hi=$1?"0x$1":"0"; $lo="0x$2"; } - elsif (/^([0-9]+)$/o) - { $hi=$1>>32; $lo=$1&0xffffffff; } # error-prone with 32-bit perl - else - { $hi=undef; $lo=$_; } - - if (defined($hi)) - { push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo"); } - else - { push(@ret,".quad $lo"); } - } - join("\n",@ret); -}; - -################################################################ -# simplified mnemonics not handled by at least one assembler -################################################################ -my $cmplw = sub { - my $f = shift; - my $cr = 0; $cr = shift if ($#_>1); - # Some out-of-date 32-bit GNU assembler just can't handle cmplw... - ($flavour =~ /linux.*32/) ? - " .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 : - " cmplw ".join(',',$cr,@_); -}; -my $bdnz = sub { - my $f = shift; - my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint - " bc $bo,0,".shift; -} if ($flavour!~/linux/); -my $bltlr = sub { - my $f = shift; - my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint - ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints - " .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 : - " bclr $bo,0"; -}; -my $bnelr = sub { - my $f = shift; - my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint - ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints - " .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 : - " bclr $bo,2"; -}; -my $beqlr = sub { - my $f = shift; - my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint - ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints - " .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 : - " bclr $bo,2"; -}; -# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two -# arguments is 64, with "operand out of range" error. -my $extrdi = sub { - my ($f,$ra,$rs,$n,$b) = @_; - $b = ($b+$n)&63; $n = 64-$n; - " rldicl $ra,$rs,$b,$n"; -}; -my $vmr = sub { - my ($f,$vx,$vy) = @_; - " vor $vx,$vy,$vy"; -}; - -# Some ABIs specify vrsave, special-purpose register #256, as reserved -# for system use. -my $no_vrsave = ($flavour =~ /aix|linux64le/); -my $mtspr = sub { - my ($f,$idx,$ra) = @_; - if ($idx == 256 && $no_vrsave) { - " or $ra,$ra,$ra"; - } else { - " mtspr $idx,$ra"; - } -}; -my $mfspr = sub { - my ($f,$rd,$idx) = @_; - if ($idx == 256 && $no_vrsave) { - " li $rd,-1"; - } else { - " mfspr $rd,$idx"; - } -}; - -# PowerISA 2.06 stuff -sub vsxmem_op { - my ($f, $vrt, $ra, $rb, $op) = @_; - " .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1); -} -# made-up unaligned memory reference AltiVec/VMX instructions -my $lvx_u = sub { vsxmem_op(@_, 844); }; # lxvd2x -my $stvx_u = sub { vsxmem_op(@_, 972); }; # stxvd2x -my $lvdx_u = sub { vsxmem_op(@_, 588); }; # lxsdx -my $stvdx_u = sub { vsxmem_op(@_, 716); }; # stxsdx -my $lvx_4w = sub { vsxmem_op(@_, 780); }; # lxvw4x -my $stvx_4w = sub { vsxmem_op(@_, 908); }; # stxvw4x - -# PowerISA 2.07 stuff -sub vcrypto_op { - my ($f, $vrt, $vra, $vrb, $op) = @_; - " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op; -} -my $vcipher = sub { vcrypto_op(@_, 1288); }; -my $vcipherlast = sub { vcrypto_op(@_, 1289); }; -my $vncipher = sub { vcrypto_op(@_, 1352); }; -my $vncipherlast= sub { vcrypto_op(@_, 1353); }; -my $vsbox = sub { vcrypto_op(@_, 0, 1480); }; -my $vshasigmad = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); }; -my $vshasigmaw = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); }; -my $vpmsumb = sub { vcrypto_op(@_, 1032); }; -my $vpmsumd = sub { vcrypto_op(@_, 1224); }; -my $vpmsubh = sub { vcrypto_op(@_, 1096); }; -my $vpmsumw = sub { vcrypto_op(@_, 1160); }; -my $vaddudm = sub { vcrypto_op(@_, 192); }; - -my $mtsle = sub { - my ($f, $arg) = @_; - " .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2); -}; - -# PowerISA 3.0 stuff -my $maddhdu = sub { - my ($f, $rt, $ra, $rb, $rc) = @_; - " .long ".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|49; -}; -my $maddld = sub { - my ($f, $rt, $ra, $rb, $rc) = @_; - " .long ".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|51; -}; - -my $darn = sub { - my ($f, $rt, $l) = @_; - " .long ".sprintf "0x%X",(31<<26)|($rt<<21)|($l<<16)|(755<<1); -}; - -print <<___; -// This file is generated from a similarly-named Perl script in the BoringSSL -// source tree. Do not edit by hand. - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) -#define OPENSSL_NO_ASM -#endif -#endif - -#if !defined(OPENSSL_NO_ASM) && defined(__powerpc64__) -___ - -while($line=<>) { - - $line =~ s|[#!;].*$||; # get rid of asm-style comments... - $line =~ s|/\*.*\*/||; # ... and C-style comments... - $line =~ s|^\s+||; # ... and skip white spaces in beginning... - $line =~ s|\s+$||; # ... and at the end - - { - $line =~ s|\.L(\w+)|L$1|g; # common denominator for Locallabel - $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels); - } - - { - $line =~ s|(^[\.\w]+)\:\s*||; - my $label = $1; - if ($label) { - my $xlated = ($GLOBALS{$label} or $label); - print "$xlated:"; - if ($flavour =~ /linux.*64le/) { - if ($TYPES{$label} =~ /function/) { - printf "\n.localentry %s,0\n",$xlated; - } - } - } - } - - { - $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||; - my $c = $1; $c = "\t" if ($c eq ""); - my $mnemonic = $2; - my $f = $3; - my $opcode = eval("\$$mnemonic"); - $line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/); - if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } - elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } - } - - print $line if ($line); - print "\n"; -} - -print "#endif // !OPENSSL_NO_ASM && __powerpc64__\n"; - -# See https://www.airs.com/blog/archives/518. -print ".section\t.note.GNU-stack,\"\",\@progbits\n" if ($flavour =~ /linux/); - -close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/perlasm/x86_64-xlate.pl b/third_party/boringssl/kit/src/crypto/perlasm/x86_64-xlate.pl index e3745f89..16a78468 100755 --- a/third_party/boringssl/kit/src/crypto/perlasm/x86_64-xlate.pl +++ b/third_party/boringssl/kit/src/crypto/perlasm/x86_64-xlate.pl @@ -59,6 +59,10 @@ # 9. .init segment is allowed to contain calls to functions only. # a. If function accepts more than 4 arguments *and* >4th argument # is declared as non 64-bit value, do clear its upper part. +# +# TODO(https://crbug.com/boringssl/259): The dual-ABI mechanism described here +# does not quite unwind correctly on Windows. The seh_directive logic below has +# the start of a new mechanism. use strict; @@ -72,6 +76,7 @@ open STDOUT,">$output" || die "can't open $output: $!" my $gas=1; $gas=0 if ($output =~ /\.asm$/); my $elf=1; $elf=0 if (!$gas); +my $apple=0; my $win64=0; my $prefix=""; my $decor=".L"; @@ -91,7 +96,7 @@ if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1; $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`; $prefix =~ s|\R$||; # Better chomp } -elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; } +elsif ($flavour eq "macosx") { $gas=1; $elf=0; $apple=1; $prefix="_"; $decor="L\$"; } elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; } elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; } elsif (!$gas) { die "unknown flavour $flavour"; } @@ -709,15 +714,351 @@ my %globals; return ($elf ? $self->{value} : undef); } } +{ package seh_directive; + # This implements directives, like MASM's, for specifying Windows unwind + # codes. See https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170 + # for details on the Windows unwind mechanism. Unlike MASM's directives, we + # have no .seh_endprolog directive. Instead, the last prolog directive is + # implicitly the end of the prolog. + # + # TODO(https://crbug.com/boringssl/259): For now, SEH directives are ignored + # on non-Windows platforms. This means functions need to specify both CFI + # and SEH directives, often redundantly. Ideally we'd abstract between the + # two. E.g., we can synthesize CFI from SEH prologs, but SEH does not + # annotate epilogs, so we'd need to combine parts from both. Or we can + # restrict ourselves to a subset of CFI and synthesize SEH from CFI. + # + # Additionally, this only supports @abi-omnipotent functions. It is + # incompatible with the automatic calling convention conversion. The main + # complication is the current scheme modifies RDI and RSI (non-volatile on + # Windows) at the start of the function, and saves them in the parameter + # stack area. This can be expressed with .seh_savereg, but .seh_savereg is + # only usable late in the prolog. However, unwind information gives enough + # information to locate the parameter stack area at any point in the + # function, so we can defer conversion or implement other schemes. + + my $UWOP_PUSH_NONVOL = 0; + my $UWOP_ALLOC_LARGE = 1; + my $UWOP_ALLOC_SMALL = 2; + my $UWOP_SET_FPREG = 3; + my $UWOP_SAVE_NONVOL = 4; + my $UWOP_SAVE_NONVOL_FAR = 5; + my $UWOP_SAVE_XMM128 = 8; + my $UWOP_SAVE_XMM128_FAR = 9; + + my %UWOP_REG_TO_NUMBER = ("%rax" => 0, "%rcx" => 1, "%rdx" => 2, "%rbx" => 3, + "%rsp" => 4, "%rbp" => 5, "%rsi" => 6, "%rdi" => 7, + map(("%r$_" => $_), (8..15))); + my %UWOP_NUMBER_TO_REG = reverse %UWOP_REG_TO_NUMBER; + + # The contents of the pdata and xdata sections so far. + my ($xdata, $pdata) = ("", ""); + + my %info; + + my $next_label = 0; + my $current_label_func = ""; + + # _new_unwind_label allocates a new label, unique to the file. + sub _new_unwind_label { + my ($name) = (@_); + # Labels only need to be unique, but to make diffs easier to read, scope + # them all under the current function. + my $func = $current_function->{name}; + if ($func ne $current_label_func) { + $current_label_func = $func; + $next_label = 0; + } + + my $num = $next_label++; + return ".LSEH_${name}_${func}_${num}"; + } + + sub _check_in_proc { + die "Missing .seh_startproc directive" unless %info; + } + + sub _check_not_in_proc { + die "Missing .seh_endproc directive" if %info; + } + + sub _startproc { + _check_not_in_proc(); + if ($current_function->{abi} eq "svr4") { + die "SEH directives can only be used with \@abi-omnipotent"; + } + + my $info_label = _new_unwind_label("info"); + my $start_label = _new_unwind_label("begin"); + %info = ( + # info_label is the label of the function's entry in .xdata. + info_label => $info_label, + # start_label is the start of the function. + start_label => $start_label, + # endprolog is the label of the last unwind code in the function. + endprolog => $start_label, + # unwind_codes contains the textual representation of the + # unwind codes in the function so far. + unwind_codes => "", + # num_codes is the number of 16-bit words in unwind_codes. + num_codes => 0, + # frame_reg is the number of the frame register, or zero if + # there is none. + frame_reg => 0, + # frame_offset is the offset into the fixed part of the stack that + # the frame register points into. + frame_offset => 0, + # has_offset is whether directives taking an offset have + # been used. This is used to check that such directives + # come after the fixed portion of the stack frame is established. + has_offset => 0, + # has_nonpushreg is whether directives other than + # .seh_pushreg have been used. This is used to check that + # .seh_pushreg directives are first. + has_nonpushreg => 0, + ); + return $start_label; + } + + sub _add_unwind_code { + my ($op, $value, @extra) = @_; + _check_in_proc(); + if ($op != $UWOP_PUSH_NONVOL) { + $info{has_nonpushreg} = 1; + } elsif ($info{has_nonpushreg}) { + die ".seh_pushreg directives must appear first in the prolog"; + } + + my $label = _new_unwind_label("prolog"); + # Encode an UNWIND_CODE structure. See + # https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170#struct-unwind_code + my $encoded = $op | ($value << 4); + my $codes = <<____; + .byte $label-$info{start_label} + .byte $encoded +____ + # Some opcodes need additional values to encode themselves. + foreach (@extra) { + $codes .= "\t.value\t$_\n"; + } + + $info{num_codes} += 1 + scalar(@extra); + # Unwind codes are listed in reverse order. + $info{unwind_codes} = $codes . $info{unwind_codes}; + # Track the label of the last unwind code. It implicitly is the end of + # the prolog. MASM has an endprolog directive, but it seems to be + # unnecessary. + $info{endprolog} = $label; + return $label; + } + + sub _updating_fixed_allocation { + _check_in_proc(); + if ($info{frame_reg} != 0) { + # Windows documentation does not explicitly forbid .seh_allocstack + # after .seh_setframe, but it appears to have no effect. Offsets are + # still relative to the fixed allocation when the frame register was + # established. + die "fixed allocation may not be increased after .seh_setframe"; + } + if ($info{has_offset}) { + # Windows documentation does not explicitly forbid .seh_savereg + # before .seh_allocstack, but it does not work very well. Offsets + # are relative to the top of the final fixed allocation, not where + # RSP currently is. + die "directives with an offset must come after the fixed allocation is established."; + } + } + + sub _endproc { + _check_in_proc(); + if ($info{num_codes} == 0) { + # If a Windows function has no directives (i.e. it doesn't touch the + # stack), it is a leaf function and is not expected to appear in + # .pdata or .xdata. + die ".seh_endproc found with no unwind codes"; + } + + my $end_label = _new_unwind_label("end"); + # Encode a RUNTIME_FUNCTION. See + # https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170#struct-runtime_function + $pdata .= <<____; + .rva $info{start_label} + .rva $end_label + .rva $info{info_label} + +____ + + # Encode an UNWIND_INFO. See + # https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170#struct-unwind_info + my $frame_encoded = $info{frame_reg} | (($info{frame_offset} / 16) << 4); + $xdata .= <<____; +$info{info_label}: + .byte 1 # version 1, no flags + .byte $info{endprolog}-$info{start_label} + .byte $info{num_codes} + .byte $frame_encoded +$info{unwind_codes} +____ + + %info = (); + return $end_label; + } + + sub re { + my ($class, $line) = @_; + if ($$line =~ s/^\s*\.seh_(\w+)\s*//) { + my $dir = $1; + if (!$win64) { + $$line = ""; + return; + } + + my $label; + SWITCH: for ($dir) { + /^startproc$/ && do { + $label = _startproc(); + last; + }; + /^pushreg$/ && do { + $$line =~ /^(%\w+)\s*$/ or die "could not parse .seh_$dir"; + my $reg_num = $UWOP_REG_TO_NUMBER{$1} or die "unknown register $1"; + _updating_fixed_allocation(); + $label = _add_unwind_code($UWOP_PUSH_NONVOL, $reg_num); + last; + }; + /^allocstack$/ && do { + my $num = eval($$line); + if ($num <= 0 || $num % 8 != 0) { + die "invalid stack allocation: $num"; + } + _updating_fixed_allocation(); + if ($num <= 128) { + $label = _add_unwind_code($UWOP_ALLOC_SMALL, ($num - 8) / 8); + } elsif ($num < 512 * 1024) { + $label = _add_unwind_code($UWOP_ALLOC_LARGE, 0, $num / 8); + } elsif ($num < 4 * 1024 * 1024 * 1024) { + $label = _add_unwind_code($UWOP_ALLOC_LARGE, 1, $num >> 16, $num & 0xffff); + } else { + die "stack allocation too large: $num" + } + last; + }; + /^setframe$/ && do { + if ($info{frame_reg} != 0) { + die "duplicate .seh_setframe directive"; + } + if ($info{has_offset}) { + die "directives with with an offset must come after .seh_setframe."; + } + $$line =~ /(%\w+)\s*,\s*(.+)/ or die "could not parse .seh_$dir"; + my $reg_num = $UWOP_REG_TO_NUMBER{$1} or die "unknown register $1"; + my $offset = eval($2); + if ($offset < 0 || $offset % 16 != 0 || $offset > 240) { + die "invalid offset: $offset"; + } + $info{frame_reg} = $reg_num; + $info{frame_offset} = $offset; + $label = _add_unwind_code($UWOP_SET_FPREG, 0); + last; + }; + /^savereg$/ && do { + $$line =~ /(%\w+)\s*,\s*(.+)/ or die "could not parse .seh_$dir"; + my $reg_num = $UWOP_REG_TO_NUMBER{$1} or die "unknown register $1"; + my $offset = eval($2); + if ($offset < 0 || $offset % 8 != 0) { + die "invalid offset: $offset"; + } + if ($offset < 8 * 65536) { + $label = _add_unwind_code($UWOP_SAVE_NONVOL, $reg_num, $offset / 8); + } else { + $label = _add_unwind_code($UWOP_SAVE_NONVOL_FAR, $reg_num, $offset >> 16, $offset & 0xffff); + } + $info{has_offset} = 1; + last; + }; + /^savexmm128$/ && do { + $$line =~ /%xmm(\d+)\s*,\s*(.+)/ or die "could not parse .seh_$dir"; + my $reg_num = $1; + my $offset = eval($2); + if ($offset < 0 || $offset % 16 != 0) { + die "invalid offset: $offset"; + } + if ($offset < 16 * 65536) { + $label = _add_unwind_code($UWOP_SAVE_XMM128, $reg_num, $offset / 16); + } else { + $label = _add_unwind_code($UWOP_SAVE_XMM128_FAR, $reg_num, $offset >> 16, $offset & 0xffff); + } + $info{has_offset} = 1; + last; + }; + /^endproc$/ && do { + $label = _endproc(); + last; + }; + die "unknown SEH directive .seh_$dir"; + } + + # All SEH directives compile to labels inline. The other data is + # emitted later. + $$line = ""; + $label .= ":"; + return label->re(\$label); + } + } + + sub pdata_and_xdata { + return "" unless $win64; + + my $ret = ""; + if ($pdata ne "") { + $ret .= <<____; +.section .pdata +.align 4 +$pdata +____ + } + if ($xdata ne "") { + $ret .= <<____; +.section .xdata +.align 4 +$xdata +____ + } + return $ret; + } +} { package directive; # pick up directives, which start with . + my %sections; + sub nasm_section { + my ($name, $qualifiers) = @_; + my $ret = "section\t$name"; + if (exists $sections{$name}) { + # Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392701. Only + # emit section qualifiers the first time a section is referenced. + # For all subsequent references, require the qualifiers match and + # omit them. + # + # See also https://crbug.com/1422018 and b/270643835. + my $old = $sections{$name}; + die "Inconsistent qualifiers: $qualifiers vs $old" if ($qualifiers ne "" && $qualifiers ne $old); + } else { + $sections{$name} = $qualifiers; + if ($qualifiers ne "") { + $ret .= " $qualifiers"; + } + } + return $ret; + } sub re { my ($class, $line) = @_; my $self = {}; my $ret; my $dir; - # chain-call to cfi_directive + # chain-call to cfi_directive and seh_directive. $ret = cfi_directive->re($line) and return $ret; + $ret = seh_directive->re($line) and return $ret; if ($$line =~ /^\s*(\.\w+)/) { bless $self,$class; @@ -787,6 +1128,9 @@ my %globals; $self->{value} = ".p2align\t" . (log($$line)/log(2)); } elsif ($dir eq ".section") { $current_segment=$$line; + if (!$elf && $current_segment eq ".rodata") { + if ($flavour eq "macosx") { $self->{value} = ".section\t__DATA,__const"; } + } if (!$elf && $current_segment eq ".init") { if ($flavour eq "macosx") { $self->{value} = ".mod_init_func"; } elsif ($flavour eq "mingw64") { $self->{value} = ".section\t.ctors"; } @@ -814,7 +1158,7 @@ my %globals; SWITCH: for ($dir) { /\.text/ && do { my $v=undef; if ($nasm) { - $v="section .text code align=64\n"; + $v=nasm_section(".text", "code align=64")."\n"; } else { $v="$current_segment\tENDS\n" if ($current_segment); $current_segment = ".text\$"; @@ -827,7 +1171,7 @@ my %globals; }; /\.data/ && do { my $v=undef; if ($nasm) { - $v="section .data data align=8\n"; + $v=nasm_section(".data", "data align=8")."\n"; } else { $v="$current_segment\tENDS\n" if ($current_segment); $current_segment = "_DATA"; @@ -839,18 +1183,20 @@ my %globals; /\.section/ && do { my $v=undef; $$line =~ s/([^,]*).*/$1/; $$line = ".CRT\$XCU" if ($$line eq ".init"); + $$line = ".rdata" if ($$line eq ".rodata"); if ($nasm) { - $v="section $$line"; - if ($$line=~/\.([px])data/) { - $v.=" rdata align="; - $v.=$1 eq "p"? 4 : 8; + my $qualifiers = ""; + if ($$line=~/\.([prx])data/) { + $qualifiers = "rdata align="; + $qualifiers .= $1 eq "p"? 4 : 8; } elsif ($$line=~/\.CRT\$/i) { - $v.=" rdata align=8"; + $qualifiers = "rdata align=8"; } + $v = nasm_section($$line, $qualifiers); } else { $v="$current_segment\tENDS\n" if ($current_segment); $v.="$$line\tSEGMENT"; - if ($$line=~/\.([px])data/) { + if ($$line=~/\.([prx])data/) { $v.=" READONLY"; $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref); } elsif ($$line=~/\.CRT\$/i) { @@ -908,11 +1254,11 @@ my %globals; map(s/(0b[0-1]+)/oct($1)/eig,@str); map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm); while ($#str>15) { - $self->{value}.="DB\t" + $self->{value}.="\tDB\t" .join(",",@str[0..15])."\n"; foreach (0..15) { shift @str; } } - $self->{value}.="DB\t" + $self->{value}.="\tDB\t" .join(",",@str) if (@str); last; }; @@ -1146,15 +1492,17 @@ ___ } if ($nasm) { + die "unknown target" unless ($win64); print <<___; +\%ifidn __OUTPUT_FORMAT__, win64 default rel -%define XMMWORD -%define YMMWORD -%define ZMMWORD +\%define XMMWORD +\%define YMMWORD +\%define ZMMWORD -%ifdef BORINGSSL_PREFIX -%include "boringssl_prefix_symbols_nasm.inc" -%endif +\%ifdef BORINGSSL_PREFIX +\%include "boringssl_prefix_symbols_nasm.inc" +\%endif ___ } elsif ($masm) { print <<___; @@ -1163,22 +1511,32 @@ ___ } if ($gas) { - print <<___; + my $target; + if ($elf) { + # The "elf" target is really ELF with SysV ABI, but every ELF platform + # uses the SysV ABI. + $target = "defined(__ELF__)"; + } elsif ($apple) { + $target = "defined(__APPLE__)"; + } else { + die "unknown target: $flavour"; + } + print <<___; #if defined(__has_feature) #if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) #define OPENSSL_NO_ASM #endif #endif -#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) && $target #if defined(BORINGSSL_PREFIX) #include #endif ___ } -while(defined(my $line=<>)) { - +sub process_line { + my $line = shift; $line =~ s|\R$||; # Better chomp if ($nasm) { @@ -1258,11 +1616,34 @@ while(defined(my $line=<>)) { print $line,"\n"; } +while(defined(my $line=<>)) { + process_line($line); +} +foreach my $line (split(/\n/, seh_directive->pdata_and_xdata())) { + process_line($line); +} + print "\n$current_segment\tENDS\n" if ($current_segment && $masm); -print "END\n" if ($masm); -print "#endif\n" if ($gas); -# See https://www.airs.com/blog/archives/518. -print ".section\t.note.GNU-stack,\"\",\@progbits\n" if ($elf); +if ($masm) { + print "END\n"; +} elsif ($gas) { + print <<___; +#endif +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",\%progbits +#endif +___ +} elsif ($nasm) { + print <<___; +\%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +\%endif +___ +} else { + die "unknown assembler"; +} close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/perlasm/x86asm.pl b/third_party/boringssl/kit/src/crypto/perlasm/x86asm.pl index c22421f9..d66255ed 100644 --- a/third_party/boringssl/kit/src/crypto/perlasm/x86asm.pl +++ b/third_party/boringssl/kit/src/crypto/perlasm/x86asm.pl @@ -284,22 +284,49 @@ $comment source tree. Do not edit by hand. ___ if ($win32) { print <<___ unless $masm; -%ifdef BORINGSSL_PREFIX -%include "boringssl_prefix_symbols_nasm.inc" -%endif +\%ifdef BORINGSSL_PREFIX +\%include "boringssl_prefix_symbols_nasm.inc" +\%endif +\%ifidn __OUTPUT_FORMAT__, win32 +___ + print @out; + print <<___ unless $masm; +\%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +\%endif ___ } else { + my $target; + if ($elf) { + $target = "defined(__ELF__)"; + } elsif ($macosx) { + $target = "defined(__APPLE__)"; + } else { + die "unknown target"; + } + print <<___; -#if defined(__i386__) +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__i386__) && $target #if defined(BORINGSSL_PREFIX) #include #endif +___ + print @out; + print <<___; +#endif // !defined(OPENSSL_NO_ASM) && defined(__i386__) && $target +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",\%progbits +#endif ___ } - print @out; - print "#endif\n" unless ($win32); - # See https://www.airs.com/blog/archives/518. - print ".section\t.note.GNU-stack,\"\",\@progbits\n" if ($elf); } sub ::asm_init diff --git a/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_test.cc b/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_test.cc index bf853796..3c042ec5 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_test.cc +++ b/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_test.cc @@ -639,6 +639,7 @@ static void TestPEMCRLs(const char *pem) { bssl::UniquePtr bio(BIO_new_mem_buf(pem, strlen(pem))); ASSERT_TRUE(bio); bssl::UniquePtr crls(sk_X509_CRL_new_null()); + ASSERT_TRUE(crls); ASSERT_TRUE(PKCS7_get_PEM_CRLs(crls.get(), bio.get())); ASSERT_EQ(1u, sk_X509_CRL_num(crls.get())); diff --git a/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_x509.c b/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_x509.c index 773c5923..fd71bd7b 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_x509.c +++ b/third_party/boringssl/kit/src/crypto/pkcs7/pkcs7_x509.c @@ -328,7 +328,6 @@ int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) { if (*out == NULL) { *out = OPENSSL_malloc(p7->ber_len); if (*out == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return -1; } OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len); diff --git a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs12_test.cc b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs12_test.cc index e67630d6..79ebae39 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs12_test.cc +++ b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs12_test.cc @@ -34,7 +34,7 @@ std::string GetTestData(const char *path); static const char kPassword[] = "foo"; // kUnicodePassword is the password for unicode_password.p12 -static const char kUnicodePassword[] = u8"Hello, 世界"; +static const char kUnicodePassword[] = "Hello, 世界"; static bssl::Span StringToBytes(const std::string &str) { return bssl::MakeConstSpan(reinterpret_cast(str.data()), @@ -391,7 +391,7 @@ TEST(PKCS12Test, RoundTrip) { {bssl::Span(kTestCert2)}, 0, 0, 0, 0); // Test some Unicode. - TestRoundTrip(kPassword, u8"Hello, 世界!", + TestRoundTrip(kPassword, "Hello, 世界!", bssl::Span(kTestKey), bssl::Span(kTestCert), {bssl::Span(kTestCert2)}, 0, 0, 0, 0); @@ -599,3 +599,45 @@ TEST(PKCS12Test, Order) { ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(), {cert2.get(), cert3.get()})); ExpectPKCS12Parse(p12, key1.get(), nullptr, {cert2.get(), cert3.get()}); } + +TEST(PKCS12Test, CreateWithAlias) { + bssl::UniquePtr key = MakeTestKey(); + ASSERT_TRUE(key); + bssl::UniquePtr cert1 = MakeTestCert(key.get()); + ASSERT_TRUE(cert1); + bssl::UniquePtr cert2 = MakeTestCert(key.get()); + ASSERT_TRUE(cert2); + + std::string alias = "I'm an alias"; + int res = X509_alias_set1( + cert1.get(), reinterpret_cast(alias.data()), + alias.size()); + ASSERT_EQ(res, 1); + + std::vector certs = {cert1.get(), cert2.get()}; + std::vector der; + ASSERT_TRUE(PKCS12CreateVector(&der, key.get(), certs)); + + bssl::UniquePtr bio(BIO_new_mem_buf(der.data(), der.size())); + ASSERT_TRUE(bio); + bssl::UniquePtr p12(d2i_PKCS12_bio(bio.get(), nullptr)); + ASSERT_TRUE(p12); + + EVP_PKEY *parsed_key = nullptr; + X509 *parsed_cert = nullptr; + STACK_OF(X509) *ca_certs = nullptr; + ASSERT_TRUE( + PKCS12_parse(p12.get(), kPassword, &parsed_key, &parsed_cert, &ca_certs)); + + bssl::UniquePtr delete_key(parsed_key); + bssl::UniquePtr delete_cert(parsed_cert); + bssl::UniquePtr delete_ca_certs(ca_certs); + ASSERT_EQ(sk_X509_num(ca_certs), 1UL); + + int alias_len = 0; + const unsigned char *parsed_alias = + X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len); + ASSERT_TRUE(parsed_alias); + ASSERT_EQ(alias, std::string(reinterpret_cast(parsed_alias), + static_cast(alias_len))); +} diff --git a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8.c b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8.c index 84b7b127..6dd111b8 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8.c +++ b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8.c @@ -76,7 +76,6 @@ static int pkcs12_encode_password(const char *in, size_t in_len, uint8_t **out, size_t *out_len) { CBB cbb; if (!CBB_init(&cbb, in_len * 2)) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return 0; } @@ -162,7 +161,6 @@ int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, I = OPENSSL_malloc(I_len); if (I_len != 0 && I == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } @@ -390,7 +388,6 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, buf = OPENSSL_malloc(in_len); if (buf == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_test.cc b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_test.cc index beb532f4..d431d666 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_test.cc +++ b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_test.cc @@ -23,90 +23,68 @@ // kEncryptedPBES2WithDESAndSHA1 is a PKCS#8 encrypted private key using PBES2 -// with DES-EDE3-CBC and HMAC-SHA-1. It was generated with: +// with DES-EDE3-CBC and HMAC-SHA-1 and a password of "testing". It was +// generated with: // -// openssl genrsa 512 > test.key +// clang-format off +// +// openssl ecparam -genkey -name prime256v1 > test.key // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 des3 -v2prf hmacWithSHA1 -outform der -// hexdump -Cv test.key.encrypted +// xxd -i test.key.encrypted // -// The password is "testing". +// clang-format on static const uint8_t kEncryptedPBES2WithDESAndSHA1[] = { - 0x30, 0x82, 0x01, 0x9e, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, - 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, - 0x30, 0x0e, 0x04, 0x08, 0x06, 0xa5, 0x4b, 0x0c, 0x0c, 0x50, 0x8c, 0x19, 0x02, 0x02, 0x08, 0x00, - 0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x3a, 0xd0, - 0x70, 0x4b, 0x26, 0x50, 0x13, 0x7b, 0x04, 0x82, 0x01, 0x58, 0xa6, 0xee, 0x02, 0xf2, 0xf2, 0x7c, - 0x19, 0x91, 0xe3, 0xce, 0x32, 0x85, 0xc5, 0x01, 0xd9, 0xe3, 0x5e, 0x14, 0xb6, 0xb8, 0x78, 0xad, - 0xda, 0x01, 0xec, 0x9e, 0x42, 0xe8, 0xbf, 0x0b, 0x46, 0x03, 0xbc, 0x92, 0x6f, 0xe4, 0x0f, 0x0f, - 0x48, 0x30, 0x10, 0x10, 0x9b, 0xfb, 0x4b, 0xb9, 0x45, 0xf8, 0xcf, 0xab, 0xa1, 0x18, 0xdd, 0x19, - 0xa4, 0xa4, 0xe1, 0xf0, 0xa1, 0x8d, 0xc2, 0x23, 0xe7, 0x0d, 0x7a, 0x64, 0x21, 0x6b, 0xfa, 0x48, - 0xb9, 0x41, 0xc1, 0x0c, 0x4b, 0xce, 0x6f, 0x1a, 0x91, 0x9b, 0x9f, 0xdd, 0xcf, 0xa9, 0x8d, 0x33, - 0x2c, 0x45, 0x81, 0x5c, 0x5e, 0x67, 0xc6, 0x68, 0x43, 0x62, 0xff, 0x5e, 0x9b, 0x1a, 0x15, 0x3a, - 0x9d, 0x71, 0x3f, 0xbe, 0x32, 0x2f, 0xe5, 0x90, 0x65, 0x65, 0x9c, 0x22, 0xf6, 0x29, 0x2e, 0xcf, - 0x26, 0x16, 0x7b, 0x66, 0x48, 0x55, 0xad, 0x9a, 0x8d, 0x89, 0xf4, 0x48, 0x4f, 0x1f, 0x9d, 0xb8, - 0xfa, 0xe1, 0xf1, 0x3b, 0x39, 0x5c, 0x72, 0xc6, 0xb8, 0x3e, 0x98, 0xe8, 0x77, 0xe8, 0xb6, 0x71, - 0x84, 0xa8, 0x6e, 0xca, 0xaf, 0x62, 0x96, 0x49, 0x8a, 0x21, 0x6f, 0x9e, 0x78, 0x07, 0x97, 0x38, - 0x40, 0x66, 0x42, 0x5a, 0x1b, 0xe0, 0x9b, 0xe9, 0x91, 0x82, 0xe4, 0xea, 0x8f, 0x2a, 0xb2, 0x80, - 0xce, 0xe8, 0x57, 0xd3, 0xac, 0x11, 0x9d, 0xb2, 0x39, 0x0f, 0xe1, 0xce, 0x18, 0x96, 0x38, 0xa1, - 0x19, 0x80, 0x88, 0x81, 0x3d, 0xda, 0xaa, 0x8e, 0x15, 0x27, 0x19, 0x73, 0x0c, 0xf3, 0xaf, 0x45, - 0xe9, 0x1b, 0xad, 0x6c, 0x3d, 0xbf, 0x95, 0xf7, 0xa0, 0x87, 0x0e, 0xde, 0xf1, 0xd8, 0xee, 0xaa, - 0x92, 0x76, 0x8d, 0x32, 0x45, 0xa1, 0xe7, 0xf5, 0x05, 0xd6, 0x2c, 0x67, 0x63, 0x10, 0xfa, 0xde, - 0x80, 0xc7, 0x5b, 0x96, 0x0f, 0x24, 0x50, 0x78, 0x30, 0xe5, 0x89, 0xf3, 0x73, 0xfa, 0x40, 0x11, - 0xd5, 0x26, 0xb8, 0x36, 0x96, 0x98, 0xe6, 0xbd, 0x73, 0x62, 0x56, 0xb9, 0xea, 0x28, 0x16, 0x93, - 0x5b, 0x33, 0xae, 0x83, 0xf9, 0x1f, 0xee, 0xef, 0xc8, 0xbf, 0xc7, 0xb1, 0x47, 0x43, 0xa1, 0xc6, - 0x1a, 0x64, 0x47, 0x02, 0x40, 0x3e, 0xbc, 0x0f, 0x80, 0x71, 0x5c, 0x44, 0x60, 0xbc, 0x78, 0x2e, - 0xd2, 0x77, 0xf8, 0x6e, 0x12, 0x51, 0x89, 0xdb, 0x90, 0x64, 0xcd, 0x76, 0x10, 0x29, 0x73, 0xc2, - 0x2f, 0x94, 0x7b, 0x98, 0xcd, 0xbb, 0x61, 0x16, 0x1d, 0x52, 0x11, 0x73, 0x48, 0xe6, 0x39, 0xfc, - 0xd6, 0x2d, + 0x30, 0x81, 0xd5, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x0e, 0x04, 0x08, 0x65, + 0x0b, 0xb8, 0x2a, 0x45, 0x13, 0x65, 0x4c, 0x02, 0x02, 0x08, 0x00, 0x30, + 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, + 0x08, 0x16, 0x42, 0xa5, 0x98, 0xc2, 0x38, 0xdd, 0x80, 0x04, 0x81, 0x90, + 0x8a, 0xfd, 0xc1, 0xb1, 0x6c, 0x8a, 0x26, 0x80, 0xff, 0x15, 0x9a, 0x15, + 0x72, 0x04, 0x25, 0xe2, 0x2d, 0xfd, 0xfe, 0xfd, 0xbb, 0x1d, 0xcb, 0xbc, + 0x3c, 0x07, 0xf2, 0x3e, 0x97, 0xe6, 0x24, 0x2d, 0x06, 0x1f, 0xa2, 0xc8, + 0x72, 0xa0, 0x1b, 0x1f, 0xe2, 0x41, 0x1a, 0x53, 0xe5, 0xba, 0x17, 0x62, + 0x49, 0xe8, 0xae, 0x1a, 0x5a, 0xf0, 0x4c, 0x5f, 0x74, 0x05, 0x3f, 0xc3, + 0xb3, 0xa2, 0x8b, 0xb8, 0xc5, 0x17, 0x20, 0xec, 0xca, 0x3a, 0xf9, 0x00, + 0xd8, 0xb1, 0x97, 0x61, 0x98, 0x28, 0xfe, 0x79, 0x1e, 0xe0, 0x7e, 0xb4, + 0x7c, 0x40, 0x89, 0x1e, 0x56, 0xa6, 0x63, 0x4f, 0x32, 0x6e, 0x00, 0x77, + 0x7d, 0xf1, 0xb9, 0x77, 0x92, 0xbf, 0x02, 0xbb, 0x9d, 0x45, 0x15, 0xd4, + 0x4a, 0xb5, 0xe7, 0xb5, 0xb4, 0x9d, 0x06, 0x3c, 0x57, 0xf3, 0x8a, 0x9b, + 0x58, 0x85, 0xad, 0x99, 0x16, 0x2d, 0xe9, 0x14, 0xa4, 0xa8, 0xad, 0x51, + 0xce, 0x29, 0x55, 0x52, 0xb7, 0x42, 0xb3, 0x25, 0x6d, 0x2f, 0x00, 0x91, }; // kEncryptedPBES2WithAESAndSHA256 is a PKCS#8 encrypted private key using PBES2 -// with AES-128-CBC and HMAC-SHA-256. It was generated with: +// with AES-128-CBC and HMAC-SHA-256 and a password of "testing". It was generated with: // -// openssl genrsa 512 > test.key +// clang-format off +// +// openssl ecparam -genkey -name prime256v1 > test.key // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 aes-128-cbc -v2prf hmacWithSHA256 -outform der -// hexdump -Cv test.key.encrypted +// xxd -i test.key.encrypted // -// The password is "testing". +// clang-format on static const uint8_t kEncryptedPBES2WithAESAndSHA256[] = { - 0x30, 0x82, 0x01, 0xbd, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, - 0xd0, 0x39, 0xb7, 0x6d, 0xd0, 0xff, 0x85, 0xa8, 0x02, 0x02, 0x08, 0x00, - 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, - 0x05, 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x01, 0x02, 0x04, 0x10, 0x95, 0xc6, 0x49, 0xc1, 0x61, 0x70, 0x74, - 0x36, 0xfe, 0xc0, 0x98, 0x19, 0x26, 0x32, 0x9e, 0x1a, 0x04, 0x82, 0x01, - 0x60, 0x87, 0xe3, 0x4d, 0xff, 0x33, 0x2b, 0x25, 0x07, 0x5f, 0x99, 0x24, - 0x70, 0x40, 0x29, 0xb4, 0xaa, 0xce, 0xdd, 0x93, 0x60, 0x5c, 0x65, 0xec, - 0xba, 0xee, 0xf8, 0x5e, 0xc7, 0x8f, 0x3e, 0x49, 0x00, 0xdf, 0xa7, 0xb2, - 0xbb, 0xa7, 0xf7, 0x74, 0x56, 0xe0, 0xeb, 0x33, 0xe2, 0x30, 0x60, 0x3b, - 0xd3, 0x34, 0x7b, 0xb0, 0x76, 0xc0, 0xed, 0xa2, 0x7d, 0x51, 0x99, 0x4d, - 0x52, 0x1c, 0x9e, 0xd7, 0x28, 0x58, 0x32, 0xcf, 0x55, 0xf0, 0x19, 0x87, - 0x5e, 0x66, 0x69, 0x00, 0x75, 0xd7, 0x68, 0x98, 0x64, 0x6a, 0x1e, 0x8c, - 0xef, 0x7b, 0xbc, 0x9e, 0xed, 0xaf, 0x67, 0xcf, 0xc4, 0x6c, 0x40, 0x8a, - 0x23, 0x73, 0xe6, 0x79, 0x5f, 0x7a, 0x15, 0x53, 0x2c, 0x70, 0x3b, 0x69, - 0xba, 0x3d, 0xfb, 0x6e, 0xb9, 0x27, 0x78, 0x9b, 0xc3, 0x4b, 0xb8, 0xe3, - 0xe7, 0x31, 0x82, 0x43, 0xee, 0x81, 0x5b, 0x01, 0x3b, 0x7e, 0x23, 0xb1, - 0xcc, 0x20, 0xc9, 0xe0, 0xca, 0x9d, 0xaa, 0x9c, 0xe9, 0x47, 0x96, 0x0d, - 0xc4, 0x1e, 0x1b, 0x1f, 0xb1, 0xee, 0x2b, 0x99, 0xaf, 0x2a, 0xb4, 0x9f, - 0x29, 0xb5, 0x9b, 0x83, 0x5e, 0xe5, 0x7e, 0xf7, 0xf7, 0x58, 0x31, 0x54, - 0xf6, 0x29, 0x6b, 0xfc, 0x85, 0x1d, 0x8a, 0x5f, 0x22, 0x03, 0xed, 0xce, - 0x06, 0x5b, 0x93, 0x57, 0x23, 0x4e, 0x0e, 0x5b, 0xf8, 0x29, 0x29, 0x7c, - 0x2d, 0x4a, 0xc6, 0x9a, 0x97, 0x64, 0x4c, 0x15, 0x72, 0xee, 0xaa, 0xd9, - 0xed, 0xfd, 0x8f, 0xa2, 0x36, 0xf5, 0xf8, 0xe7, 0xf7, 0xfe, 0x67, 0x4b, - 0xbe, 0x85, 0xe3, 0xda, 0x3a, 0xcc, 0x5f, 0x17, 0xbe, 0xa6, 0x1a, 0x38, - 0xed, 0x85, 0x4a, 0xd6, 0x05, 0x4b, 0x5f, 0x54, 0x0e, 0xfd, 0xdc, 0x32, - 0x9a, 0x0d, 0xca, 0xec, 0x02, 0x3f, 0x78, 0x23, 0x6e, 0x6a, 0xfa, 0x2c, - 0x04, 0x86, 0xc8, 0x74, 0xa6, 0xf7, 0x2f, 0x1a, 0xf1, 0x1a, 0x51, 0x09, - 0x2b, 0x04, 0xdc, 0x53, 0xaf, 0x39, 0x85, 0x35, 0x81, 0xc3, 0x11, 0xf0, - 0x7d, 0xb7, 0xb3, 0x77, 0x0e, 0x8e, 0x22, 0xda, 0x1f, 0xb0, 0x3d, 0x59, - 0xca, 0xa9, 0x70, 0xc3, 0x33, 0x66, 0xcb, 0x81, 0xfc, 0x85, 0x2a, 0xf0, - 0xbc, 0xd0, 0x30, 0x85, 0x1b, 0xe6, 0x9b, 0x76, 0x88, 0xca, 0xf1, 0xf5, - 0xc8, 0x19, 0x8a, 0x62, 0x16, 0x7b, 0x01, 0xc1, 0x1d, 0x80, 0xc0, 0xf7, - 0xc2, 0x0b, 0xe3, 0xbf, 0x83, 0x9a, 0x3c, 0xc0, 0x0f, 0x5e, 0xea, 0xf7, - 0xb2, 0x4c, 0xcd, 0x5e, 0xf0, 0xad, 0xa5, 0x98, 0x25, 0x62, 0x69, 0xba, - 0xd7, 0xab, 0x78, 0x59, 0xd0, + 0x30, 0x81, 0xec, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0xfc, + 0x66, 0x7f, 0x51, 0xe7, 0xb8, 0x2a, 0x22, 0x02, 0x02, 0x08, 0x00, 0x30, + 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05, + 0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, + 0x01, 0x02, 0x04, 0x10, 0xde, 0x59, 0xa1, 0x6c, 0xbc, 0xca, 0xd2, 0x04, + 0x64, 0x93, 0xcb, 0xae, 0x0d, 0x57, 0xcd, 0x71, 0x04, 0x81, 0x90, 0x66, + 0x84, 0x20, 0x5b, 0x8d, 0xfc, 0xa8, 0x08, 0x2c, 0xf1, 0x05, 0xea, 0xef, + 0x74, 0x6b, 0xa7, 0xf5, 0xce, 0xf5, 0xef, 0x71, 0x55, 0xcd, 0x6c, 0x4a, + 0xdd, 0xda, 0x6b, 0xc8, 0x51, 0xf5, 0x59, 0x87, 0x18, 0x48, 0x4e, 0xac, + 0x8d, 0x3f, 0xa4, 0xd7, 0x51, 0x81, 0xf1, 0x4b, 0x18, 0x66, 0x3c, 0x4e, + 0xf3, 0x08, 0x3e, 0x76, 0xf0, 0x12, 0x30, 0x93, 0x4e, 0x49, 0x86, 0xe0, + 0xb3, 0xd1, 0x82, 0x92, 0xaa, 0x1f, 0x2b, 0x62, 0xe2, 0x6d, 0x0d, 0x0d, + 0xad, 0xb8, 0xcf, 0xe8, 0x9a, 0x4e, 0xab, 0x31, 0x21, 0x5d, 0x6e, 0xec, + 0xbc, 0xa1, 0x10, 0xef, 0x5f, 0xc5, 0xd3, 0x93, 0x57, 0x19, 0x95, 0xee, + 0x0e, 0xce, 0x6c, 0x07, 0x08, 0xf1, 0xab, 0xe6, 0x0b, 0x06, 0x3f, 0xbd, + 0x6d, 0x19, 0x48, 0x3c, 0xa0, 0xd7, 0x81, 0x5f, 0xa6, 0x06, 0x05, 0xac, + 0x47, 0xb0, 0x51, 0x5b, 0xc5, 0x8b, 0xbe, 0x46, 0x43, 0x10, 0x9a, 0xd4, + 0xc3, 0x49, 0xc2, 0x0a, 0xe7, 0xd0, 0x34, 0x8b, 0xad, 0xfb, 0x4d, }; // kNullPassword is a PKCS#8 encrypted private key using the null password. diff --git a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_x509.c b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_x509.c index e2a02e83..83d34e6a 100644 --- a/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_x509.c +++ b/third_party/boringssl/kit/src/crypto/pkcs8/pkcs8_x509.c @@ -90,62 +90,16 @@ int pkcs12_iterations_acceptable(uint64_t iterations) { return 0 < iterations && iterations <= kIterationsLimit; } -// Minor tweak to operation: zero private key data -static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) { - // Since the structure must still be valid use ASN1_OP_FREE_PRE - if (operation == ASN1_OP_FREE_PRE) { - PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; - if (key->pkey) { - OPENSSL_cleanse(key->pkey->data, key->pkey->length); - } - } - return 1; -} +ASN1_SEQUENCE(PKCS8_PRIV_KEY_INFO) = { + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0), +} ASN1_SEQUENCE_END(PKCS8_PRIV_KEY_INFO) -ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING), - ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) -} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +IMPLEMENT_ASN1_FUNCTIONS_const(PKCS8_PRIV_KEY_INFO) -IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) - -int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, - int ptype, void *pval, uint8_t *penc, int penclen) { - if (version >= 0 && - !ASN1_INTEGER_set(priv->version, version)) { - return 0; - } - - if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { - return 0; - } - - if (penc != NULL) { - ASN1_STRING_set0(priv->pkey, penc, penclen); - } - - return 1; -} - -int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const uint8_t **pk, int *ppklen, - X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) { - if (ppkalg) { - *ppkalg = p8->pkeyalg->algorithm; - } - if (pk) { - *pk = ASN1_STRING_data(p8->pkey); - *ppklen = ASN1_STRING_length(p8->pkey); - } - if (pa) { - *pa = p8->pkeyalg; - } - return 1; -} - -EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) { uint8_t *der = NULL; int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der); if (der_len < 0) { @@ -166,7 +120,7 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { return ret; } -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) { CBB cbb; uint8_t *der = NULL; size_t der_len; @@ -380,7 +334,6 @@ static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, // Convert the friendly name to UTF-8. CBB cbb; if (!CBB_init(&cbb, CBS_len(&value))) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); goto err; } while (CBS_len(&value) != 0) { @@ -393,7 +346,6 @@ static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, } } if (!CBB_finish(&cbb, out_friendly_name, out_friendly_name_len)) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); goto err; } @@ -828,7 +780,9 @@ PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { } for (;;) { - int n = BIO_read(bio, &buf->data[used], buf->length - used); + size_t max_read = buf->length - used; + int n = BIO_read(bio, &buf->data[used], + max_read > INT_MAX ? INT_MAX : (int)max_read); if (n < 0) { if (used == 0) { goto out; @@ -888,7 +842,6 @@ int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) { if (*out == NULL) { *out = OPENSSL_malloc(p12->ber_len); if (*out == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return -1; } OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); @@ -927,7 +880,6 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, if (!ca_certs) { ca_certs = sk_X509_new_null(); if (ca_certs == NULL) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); return 0; } ca_certs_alloced = 1; @@ -993,8 +945,8 @@ int PKCS12_verify_mac(const PKCS12 *p12, const char *password, // add_bag_attributes adds the bagAttributes field of a SafeBag structure, // containing the specified friendlyName and localKeyId attributes. -static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id, - size_t key_id_len) { +static int add_bag_attributes(CBB *bag, const char *name, size_t name_len, + const uint8_t *key_id, size_t key_id_len) { if (name == NULL && key_id_len == 0) { return 1; // Omit the OPTIONAL SET. } @@ -1003,7 +955,7 @@ static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id, if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) { return 0; } - if (name != NULL) { + if (name_len != 0) { // See https://tools.ietf.org/html/rfc2985, section 5.5.1. if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || @@ -1014,7 +966,7 @@ static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id, } // Convert the friendly name to a BMPString. CBS name_cbs; - CBS_init(&name_cbs, (const uint8_t *)name, strlen(name)); + CBS_init(&name_cbs, (const uint8_t *)name, name_len); while (CBS_len(&name_cbs) != 0) { uint32_t c; if (!cbs_get_utf8(&name_cbs, &c) || @@ -1059,10 +1011,24 @@ static int add_cert_bag(CBB *cbb, X509 *cert, const char *name, } uint8_t *buf; int len = i2d_X509(cert, NULL); + + int int_name_len = 0; + const char *cert_name = (const char *)X509_alias_get0(cert, &int_name_len); + size_t name_len = int_name_len; + if (name) { + if (name_len != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_AMBIGUOUS_FRIENDLY_NAME); + return 0; + } + name_len = strlen(name); + } else { + name = cert_name; + } + if (len < 0 || !CBB_add_space(&cert_value, &buf, (size_t)len) || i2d_X509(cert, &buf) < 0 || - !add_bag_attributes(&bag, name, key_id, key_id_len) || + !add_bag_attributes(&bag, name, name_len, key_id, key_id_len) || !CBB_flush(cbb)) { return 0; } @@ -1323,7 +1289,11 @@ PKCS12 *PKCS12_create(const char *password, const char *name, goto err; } } - if (!add_bag_attributes(&bag, name, key_id, key_id_len) || + size_t name_len = 0; + if (name) { + name_len = strlen(name); + } + if (!add_bag_attributes(&bag, name, name_len, key_id, key_id_len) || !CBB_flush(&content_infos)) { goto err; } diff --git a/third_party/boringssl/kit/src/crypto/poly1305/poly1305.c b/third_party/boringssl/kit/src/crypto/poly1305/poly1305.c index c07b1e9f..12f49bbd 100644 --- a/third_party/boringssl/kit/src/crypto/poly1305/poly1305.c +++ b/third_party/boringssl/kit/src/crypto/poly1305/poly1305.c @@ -18,27 +18,15 @@ #include +#include #include -#include - #include "internal.h" #include "../internal.h" #if !defined(BORINGSSL_HAS_UINT128) || !defined(OPENSSL_X86_64) -// We can assume little-endian. -static uint32_t U8TO32_LE(const uint8_t *m) { - uint32_t r; - OPENSSL_memcpy(&r, m, sizeof(r)); - return r; -} - -static void U32TO8_LE(uint8_t *m, uint32_t v) { - OPENSSL_memcpy(m, &v, sizeof(v)); -} - static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; } struct poly1305_state_st { @@ -50,7 +38,7 @@ struct poly1305_state_st { uint8_t key[16]; }; -OPENSSL_STATIC_ASSERT( +static_assert( sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state), "poly1305_state isn't large enough to hold aligned poly1305_state_st"); @@ -76,10 +64,10 @@ static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in, } poly1305_donna_16bytes: - t0 = U8TO32_LE(in); - t1 = U8TO32_LE(in + 4); - t2 = U8TO32_LE(in + 8); - t3 = U8TO32_LE(in + 12); + t0 = CRYPTO_load_u32_le(in); + t1 = CRYPTO_load_u32_le(in + 4); + t2 = CRYPTO_load_u32_le(in + 8); + t3 = CRYPTO_load_u32_le(in + 12); in += 16; len -= 16; @@ -142,10 +130,10 @@ poly1305_donna_atmost15bytes: } len = 0; - t0 = U8TO32_LE(mp + 0); - t1 = U8TO32_LE(mp + 4); - t2 = U8TO32_LE(mp + 8); - t3 = U8TO32_LE(mp + 12); + t0 = CRYPTO_load_u32_le(mp + 0); + t1 = CRYPTO_load_u32_le(mp + 4); + t2 = CRYPTO_load_u32_le(mp + 8); + t3 = CRYPTO_load_u32_le(mp + 12); state->h0 += t0 & 0x3ffffff; state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; @@ -167,10 +155,10 @@ void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { } #endif - t0 = U8TO32_LE(key + 0); - t1 = U8TO32_LE(key + 4); - t2 = U8TO32_LE(key + 8); - t3 = U8TO32_LE(key + 12); + t0 = CRYPTO_load_u32_le(key + 0); + t1 = CRYPTO_load_u32_le(key + 4); + t2 = CRYPTO_load_u32_le(key + 8); + t3 = CRYPTO_load_u32_le(key + 12); // precompute multipliers state->r0 = t0 & 0x3ffffff; @@ -206,6 +194,11 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, size_t in_len) { struct poly1305_state_st *state = poly1305_aligned_state(statep); + // Work around a C language bug. See https://crbug.com/1019588. + if (in_len == 0) { + return; + } + #if defined(OPENSSL_POLY1305_NEON) if (CRYPTO_is_NEON_capable()) { CRYPTO_poly1305_update_neon(statep, in, in_len); @@ -248,7 +241,6 @@ void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { struct poly1305_state_st *state = poly1305_aligned_state(statep); - uint64_t f0, f1, f2, f3; uint32_t g0, g1, g2, g3, g4; uint32_t b, nb; @@ -301,21 +293,22 @@ void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { state->h3 = (state->h3 & nb) | (g3 & b); state->h4 = (state->h4 & nb) | (g4 & b); - f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]); - f1 = ((state->h1 >> 6) | (state->h2 << 20)) + - (uint64_t)U8TO32_LE(&state->key[4]); - f2 = ((state->h2 >> 12) | (state->h3 << 14)) + - (uint64_t)U8TO32_LE(&state->key[8]); - f3 = ((state->h3 >> 18) | (state->h4 << 8)) + - (uint64_t)U8TO32_LE(&state->key[12]); + uint64_t f0 = ((state->h0) | (state->h1 << 26)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[0]); + uint64_t f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[4]); + uint64_t f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[8]); + uint64_t f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)CRYPTO_load_u32_le(&state->key[12]); - U32TO8_LE(&mac[0], f0); + CRYPTO_store_u32_le(&mac[0], (uint32_t)f0); f1 += (f0 >> 32); - U32TO8_LE(&mac[4], f1); + CRYPTO_store_u32_le(&mac[4], (uint32_t)f1); f2 += (f1 >> 32); - U32TO8_LE(&mac[8], f2); + CRYPTO_store_u32_le(&mac[8], (uint32_t)f2); f3 += (f2 >> 32); - U32TO8_LE(&mac[12], f3); + CRYPTO_store_u32_le(&mac[12], (uint32_t)f3); } #endif // !BORINGSSL_HAS_UINT128 || !OPENSSL_X86_64 diff --git a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm.c b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm.c index d6f034c6..d01e0b73 100644 --- a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm.c +++ b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm.c @@ -17,6 +17,7 @@ #include +#include #include #include "../internal.h" @@ -183,7 +184,7 @@ struct poly1305_state_st { uint8_t key[16]; }; -OPENSSL_STATIC_ASSERT( +static_assert( sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state), "poly1305_state isn't large enough to hold aligned poly1305_state_st."); diff --git a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm_asm.S b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm_asm.S index 80a4b31f..7895ab49 100644 --- a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm_asm.S +++ b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_arm_asm.S @@ -4,7 +4,7 @@ #endif #endif -#if defined(__arm__) && !defined(OPENSSL_NO_ASM) && !defined(__APPLE__) +#if defined(__ARMEL__) && !defined(OPENSSL_NO_ASM) && defined(__ELF__) #if defined(BORINGSSL_PREFIX) #include @@ -2022,7 +2022,7 @@ vst1.8 d4,[r0,: 64] add sp,sp,#0 bx lr -#endif /* __arm__ && !OPENSSL_NO_ASM && !__APPLE__ */ +#endif /* __ARMEL__ && !OPENSSL_NO_ASM && __ELF__ */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_vec.c b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_vec.c index 83f1efee..209b4033 100644 --- a/third_party/boringssl/kit/src/crypto/poly1305/poly1305_vec.c +++ b/third_party/boringssl/kit/src/crypto/poly1305/poly1305_vec.c @@ -20,6 +20,8 @@ #include +#include + #include "../internal.h" @@ -27,22 +29,6 @@ #include -static uint32_t load_u32_le(const uint8_t in[4]) { - uint32_t ret; - OPENSSL_memcpy(&ret, in, 4); - return ret; -} - -static uint64_t load_u64_le(const uint8_t in[8]) { - uint64_t ret; - OPENSSL_memcpy(&ret, in, 8); - return ret; -} - -static void store_u64_le(uint8_t out[8], uint64_t v) { - OPENSSL_memcpy(out, &v, 8); -} - typedef __m128i xmmi; static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = { @@ -92,9 +78,10 @@ typedef struct poly1305_state_internal_t { } poly1305_state_internal; /* 448 bytes total + 63 bytes for alignment = 511 bytes raw */ -OPENSSL_STATIC_ASSERT( - sizeof(struct poly1305_state_internal_t) + 63 <= sizeof(poly1305_state), - "poly1305_state isn't large enough to hold aligned poly1305_state_internal_t"); +static_assert(sizeof(struct poly1305_state_internal_t) + 63 <= + sizeof(poly1305_state), + "poly1305_state isn't large enough to hold aligned " + "poly1305_state_internal_t"); static inline poly1305_state_internal *poly1305_aligned_state( poly1305_state *state) { @@ -112,8 +99,8 @@ void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) { uint64_t t0, t1; // clamp key - t0 = load_u64_le(key + 0); - t1 = load_u64_le(key + 8); + t0 = CRYPTO_load_u64_le(key + 0); + t1 = CRYPTO_load_u64_le(key + 8); r0 = t0 & 0xffc0fffffff; t0 >>= 44; t0 |= t1 << 20; @@ -131,10 +118,10 @@ void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) { p->R22.d[3] = (uint32_t)(r2 >> 32); // store pad - p->R23.d[1] = load_u32_le(key + 16); - p->R23.d[3] = load_u32_le(key + 20); - p->R24.d[1] = load_u32_le(key + 24); - p->R24.d[3] = load_u32_le(key + 28); + p->R23.d[1] = CRYPTO_load_u32_le(key + 16); + p->R23.d[3] = CRYPTO_load_u32_le(key + 20); + p->R24.d[1] = CRYPTO_load_u32_le(key + 24); + p->R24.d[3] = CRYPTO_load_u32_le(key + 28); // H = 0 st->H[0] = _mm_setzero_si128(); @@ -766,8 +753,8 @@ void CRYPTO_poly1305_finish(poly1305_state *state, uint8_t mac[16]) { } poly1305_donna_atleast16bytes: - t0 = load_u64_le(m + 0); - t1 = load_u64_le(m + 8); + t0 = CRYPTO_load_u64_le(m + 0); + t1 = CRYPTO_load_u64_le(m + 8); h0 += t0 & 0xfffffffffff; t0 = shr128_pair(t1, t0, 44); h1 += t0 & 0xfffffffffff; @@ -806,8 +793,8 @@ poly1305_donna_atmost15bytes: OPENSSL_memset(m + leftover, 0, 16 - leftover); leftover = 16; - t0 = load_u64_le(m + 0); - t1 = load_u64_le(m + 8); + t0 = CRYPTO_load_u64_le(m + 0); + t1 = CRYPTO_load_u64_le(m + 8); h0 += t0 & 0xfffffffffff; t0 = shr128_pair(t1, t0, 44); h1 += t0 & 0xfffffffffff; @@ -853,8 +840,8 @@ poly1305_donna_finish: t1 = (t1 >> 24); h2 += (t1)+c; - store_u64_le(mac + 0, ((h0) | (h1 << 44))); - store_u64_le(mac + 8, ((h1 >> 20) | (h2 << 24))); + CRYPTO_store_u64_le(mac + 0, ((h0) | (h1 << 44))); + CRYPTO_store_u64_le(mac + 8, ((h1 >> 20) | (h2 << 24))); } #endif // BORINGSSL_HAS_UINT128 && OPENSSL_X86_64 diff --git a/third_party/boringssl/kit/src/crypto/pool/internal.h b/third_party/boringssl/kit/src/crypto/pool/internal.h index b39ee426..d8c560bc 100644 --- a/third_party/boringssl/kit/src/crypto/pool/internal.h +++ b/third_party/boringssl/kit/src/crypto/pool/internal.h @@ -18,6 +18,7 @@ #include #include +#include "../internal.h" #include "../lhash/internal.h" @@ -39,6 +40,7 @@ struct crypto_buffer_st { struct crypto_buffer_pool_st { LHASH_OF(CRYPTO_BUFFER) *bufs; CRYPTO_MUTEX lock; + const uint64_t hash_key[2]; }; diff --git a/third_party/boringssl/kit/src/crypto/pool/pool.c b/third_party/boringssl/kit/src/crypto/pool/pool.c index 89bf4c2a..e889f521 100644 --- a/third_party/boringssl/kit/src/crypto/pool/pool.c +++ b/third_party/boringssl/kit/src/crypto/pool/pool.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "../internal.h" @@ -26,10 +28,13 @@ static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) { - return OPENSSL_hash32(buf->data, buf->len); + return (uint32_t)SIPHASH_24(buf->pool->hash_key, buf->data, buf->len); } static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) { + // Only |CRYPTO_BUFFER|s from the same pool have compatible hashes. + assert(a->pool != NULL); + assert(a->pool == b->pool); if (a->len != b->len) { return 1; } @@ -50,6 +55,7 @@ CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) { } CRYPTO_MUTEX_init(&pool->lock); + RAND_bytes((uint8_t *)&pool->hash_key, sizeof(pool->hash_key)); return pool; } @@ -84,6 +90,7 @@ static CRYPTO_BUFFER *crypto_buffer_new(const uint8_t *data, size_t len, CRYPTO_BUFFER tmp; tmp.data = (uint8_t *) data; tmp.len = len; + tmp.pool = pool; CRYPTO_MUTEX_lock_read(&pool->lock); CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp); diff --git a/third_party/boringssl/kit/src/crypto/rand_extra/deterministic.c b/third_party/boringssl/kit/src/crypto/rand_extra/deterministic.c index 435f0633..ecdf84d6 100644 --- a/third_party/boringssl/kit/src/crypto/rand_extra/deterministic.c +++ b/third_party/boringssl/kit/src/crypto/rand_extra/deterministic.c @@ -30,16 +30,16 @@ // multi-threaded program, replace this with a thread-local. (A mutex would not // be deterministic.) static uint64_t g_num_calls = 0; -static struct CRYPTO_STATIC_MUTEX g_num_calls_lock = CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX g_num_calls_lock = CRYPTO_MUTEX_INIT; void RAND_reset_for_fuzzing(void) { g_num_calls = 0; } void CRYPTO_sysrand(uint8_t *out, size_t requested) { static const uint8_t kZeroKey[32]; - CRYPTO_STATIC_MUTEX_lock_write(&g_num_calls_lock); + CRYPTO_MUTEX_lock_write(&g_num_calls_lock); uint64_t num_calls = g_num_calls++; - CRYPTO_STATIC_MUTEX_unlock_write(&g_num_calls_lock); + CRYPTO_MUTEX_unlock_write(&g_num_calls_lock); uint8_t nonce[12]; OPENSSL_memset(nonce, 0, sizeof(nonce)); diff --git a/third_party/boringssl/kit/src/crypto/rand_extra/forkunsafe.c b/third_party/boringssl/kit/src/crypto/rand_extra/forkunsafe.c index 0f1ececc..356afddf 100644 --- a/third_party/boringssl/kit/src/crypto/rand_extra/forkunsafe.c +++ b/third_party/boringssl/kit/src/crypto/rand_extra/forkunsafe.c @@ -17,13 +17,12 @@ #include #include "../fipsmodule/rand/internal.h" +#include "../internal.h" -// g_buffering_enabled is true if fork-unsafe buffering has been enabled. -static int g_buffering_enabled = 0; - -// g_lock protects |g_buffering_enabled|. -static struct CRYPTO_STATIC_MUTEX g_lock = CRYPTO_STATIC_MUTEX_INIT; +// g_buffering_enabled is one if fork-unsafe buffering has been enabled and zero +// otherwise. +static CRYPTO_atomic_u32 g_buffering_enabled = 0; #if !defined(OPENSSL_WINDOWS) void RAND_enable_fork_unsafe_buffering(int fd) { @@ -32,15 +31,10 @@ void RAND_enable_fork_unsafe_buffering(int fd) { abort(); } - CRYPTO_STATIC_MUTEX_lock_write(&g_lock); - g_buffering_enabled = 1; - CRYPTO_STATIC_MUTEX_unlock_write(&g_lock); + CRYPTO_atomic_store_u32(&g_buffering_enabled, 1); } #endif int rand_fork_unsafe_buffering_enabled(void) { - CRYPTO_STATIC_MUTEX_lock_read(&g_lock); - const int ret = g_buffering_enabled; - CRYPTO_STATIC_MUTEX_unlock_read(&g_lock); - return ret; + return CRYPTO_atomic_load_u32(&g_buffering_enabled) != 0; } diff --git a/third_party/boringssl/kit/src/crypto/rand_extra/passive.c b/third_party/boringssl/kit/src/crypto/rand_extra/passive.c index a2b388f8..c54e2e8a 100644 --- a/third_party/boringssl/kit/src/crypto/rand_extra/passive.c +++ b/third_party/boringssl/kit/src/crypto/rand_extra/passive.c @@ -12,23 +12,147 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include + #include "../fipsmodule/rand/internal.h" +#include "../internal.h" #if defined(BORINGSSL_FIPS) +#define ENTROPY_READ_LEN \ + (/* last_block size */ 16 + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD) + +#if defined(OPENSSL_ANDROID) + +#include +#include +#include +#include +#include +#include + +// socket_history_t enumerates whether the entropy daemon should be contacted +// for a given entropy request. Values other than socket_not_yet_attempted are +// sticky so if the first attempt to read from the daemon fails it's assumed +// that the daemon is not present and no more attempts will be made. If the +// first attempt is successful then attempts will be made forever more. +enum socket_history_t { + // initial value, no connections to the entropy daemon have been made yet. + socket_not_yet_attempted = 0, + // reading from the entropy daemon was successful + socket_success, + // reading from the entropy daemon failed. + socket_failed, +}; + +static _Atomic enum socket_history_t g_socket_history = + socket_not_yet_attempted; + +// DAEMON_RESPONSE_LEN is the number of bytes that the entropy daemon replies +// with. +#define DAEMON_RESPONSE_LEN 496 + +static_assert(ENTROPY_READ_LEN == DAEMON_RESPONSE_LEN, + "entropy daemon response length mismatch"); + +static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) { + // |RAND_need_entropy| should never call this function for more than + // |DAEMON_RESPONSE_LEN| bytes. + if (out_entropy_len > DAEMON_RESPONSE_LEN) { + abort(); + } + + const enum socket_history_t socket_history = atomic_load(&g_socket_history); + if (socket_history == socket_failed) { + return 0; + } + + int ret = 0; + const int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + goto out; + } + + struct sockaddr_un sun; + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_UNIX; + static const char kSocketPath[] = "/dev/socket/prng_seeder"; + static_assert(sizeof(kSocketPath) <= UNIX_PATH_MAX, + "kSocketPath too long"); + OPENSSL_memcpy(sun.sun_path, kSocketPath, sizeof(kSocketPath)); + + if (connect(sock, (struct sockaddr *)&sun, sizeof(sun))) { + goto out; + } + + uint8_t buffer[DAEMON_RESPONSE_LEN]; + size_t done = 0; + while (done < sizeof(buffer)) { + ssize_t n; + do { + n = read(sock, buffer + done, sizeof(buffer) - done); + } while (n == -1 && errno == EINTR); + + if (n < 1) { + goto out; + } + done += n; + } + + if (done != DAEMON_RESPONSE_LEN) { + // The daemon should always write |DAEMON_RESPONSE_LEN| bytes on every + // connection. + goto out; + } + + assert(out_entropy_len <= DAEMON_RESPONSE_LEN); + OPENSSL_memcpy(out_entropy, buffer, out_entropy_len); + ret = 1; + +out: + if (socket_history == socket_not_yet_attempted) { + enum socket_history_t expected = socket_history; + // If another thread has already updated |g_socket_history| then we defer + // to their value. + atomic_compare_exchange_strong(&g_socket_history, &expected, + (ret == 0) ? socket_failed : socket_success); + } + + close(sock); + return ret; +} + +#else + +static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) { + return 0; +} + +#endif // OPENSSL_ANDROID + // RAND_need_entropy is called by the FIPS module when it has blocked because of // a lack of entropy. This signal is used as an indication to feed it more. void RAND_need_entropy(size_t bytes_needed) { - uint8_t buf[CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t buf[ENTROPY_READ_LEN]; size_t todo = sizeof(buf); if (todo > bytes_needed) { todo = bytes_needed; } - int used_cpu; - CRYPTO_get_seed_entropy(buf, todo, &used_cpu); - RAND_load_entropy(buf, todo, used_cpu); + int want_additional_input; + if (get_seed_from_daemon(buf, todo)) { + want_additional_input = 1; + } else { + CRYPTO_get_seed_entropy(buf, todo, &want_additional_input); + } + + if (boringssl_fips_break_test("CRNG")) { + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in |rand_get_seed|. + OPENSSL_memset(buf, 0, todo); + } + + RAND_load_entropy(buf, todo, want_additional_input); } #endif // FIPS diff --git a/third_party/boringssl/kit/src/crypto/rand_extra/rand_test.cc b/third_party/boringssl/kit/src/crypto/rand_extra/rand_test.cc index 7f7c19ff..1af28b04 100644 --- a/third_party/boringssl/kit/src/crypto/rand_extra/rand_test.cc +++ b/third_party/boringssl/kit/src/crypto/rand_extra/rand_test.cc @@ -18,7 +18,6 @@ #include -#include #include #include "../fipsmodule/rand/fork_detect.h" @@ -57,7 +56,7 @@ TEST(RandTest, NotObviouslyBroken) { #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_IOS) && \ !defined(OPENSSL_FUCHSIA) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) -static bool ForkAndRand(bssl::Span out) { +static bool ForkAndRand(bssl::Span out, bool fork_unsafe_buffering) { int pipefds[2]; if (pipe(pipefds) < 0) { perror("pipe"); @@ -77,6 +76,9 @@ static bool ForkAndRand(bssl::Span out) { if (child == 0) { // This is the child. Generate entropy and write it to the parent. close(pipefds[0]); + if (fork_unsafe_buffering) { + RAND_enable_fork_unsafe_buffering(-1); + } RAND_bytes(out.data(), out.size()); while (!out.empty()) { ssize_t ret = write(pipefds[1], out.data(), out.size()); @@ -137,18 +139,27 @@ TEST(RandTest, Fork) { // intentionally uses smaller buffers than the others, to minimize the chance // of sneaking by with a large enough buffer that we've since reseeded from // the OS. - uint8_t buf1[16], buf2[16], buf3[16]; - ASSERT_TRUE(ForkAndRand(buf1)); - ASSERT_TRUE(ForkAndRand(buf2)); - RAND_bytes(buf3, sizeof(buf3)); + // + // All child processes should have different PRNGs, including the ones that + // disavow fork-safety. Although they are produced by fork, they themselves do + // not fork after that call. + uint8_t bufs[5][16]; + ASSERT_TRUE(ForkAndRand(bufs[0], /*fork_unsafe_buffering=*/false)); + ASSERT_TRUE(ForkAndRand(bufs[1], /*fork_unsafe_buffering=*/false)); + ASSERT_TRUE(ForkAndRand(bufs[2], /*fork_unsafe_buffering=*/true)); + ASSERT_TRUE(ForkAndRand(bufs[3], /*fork_unsafe_buffering=*/true)); + RAND_bytes(bufs[4], sizeof(bufs[4])); - // All should be different. - EXPECT_NE(Bytes(buf1), Bytes(buf2)); - EXPECT_NE(Bytes(buf2), Bytes(buf3)); - EXPECT_NE(Bytes(buf1), Bytes(buf3)); - EXPECT_NE(Bytes(buf1), Bytes(kZeros)); - EXPECT_NE(Bytes(buf2), Bytes(kZeros)); - EXPECT_NE(Bytes(buf3), Bytes(kZeros)); + // All should be different and non-zero. + for (const auto &buf : bufs) { + EXPECT_NE(Bytes(buf), Bytes(kZeros)); + } + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(bufs); i++) { + for (size_t j = 0; j < i; j++) { + EXPECT_NE(Bytes(bufs[i]), Bytes(bufs[j])) + << "buffers " << i << " and " << j << " matched"; + } + } } #endif // !OPENSSL_WINDOWS && !OPENSSL_IOS && // !OPENSSL_FUCHSIA && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/third_party/boringssl/kit/src/crypto/refcount_c11.c b/third_party/boringssl/kit/src/crypto/refcount.c similarity index 65% rename from third_party/boringssl/kit/src/crypto/refcount_c11.c rename to third_party/boringssl/kit/src/crypto/refcount.c index 0a331a45..74ebdd7c 100644 --- a/third_party/boringssl/kit/src/crypto/refcount_c11.c +++ b/third_party/boringssl/kit/src/crypto/refcount.c @@ -14,41 +14,35 @@ #include "internal.h" - -#if defined(OPENSSL_C11_ATOMIC) - #include #include -#include #include -#include - // See comment above the typedef of CRYPTO_refcount_t about these tests. -static_assert(alignof(CRYPTO_refcount_t) == alignof(_Atomic CRYPTO_refcount_t), - "_Atomic alters the needed alignment of a reference count"); -static_assert(sizeof(CRYPTO_refcount_t) == sizeof(_Atomic CRYPTO_refcount_t), - "_Atomic alters the size of a reference count"); +static_assert(alignof(CRYPTO_refcount_t) == alignof(CRYPTO_atomic_u32), + "CRYPTO_refcount_t does not match CRYPTO_atomic_u32 alignment"); +static_assert(sizeof(CRYPTO_refcount_t) == sizeof(CRYPTO_atomic_u32), + "CRYPTO_refcount_t does not match CRYPTO_atomic_u32 size"); static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, "CRYPTO_REFCOUNT_MAX is incorrect"); void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) { - _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *) in_count; - uint32_t expected = atomic_load(count); + CRYPTO_atomic_u32 *count = (CRYPTO_atomic_u32 *)in_count; + uint32_t expected = CRYPTO_atomic_load_u32(count); while (expected != CRYPTO_REFCOUNT_MAX) { uint32_t new_value = expected + 1; - if (atomic_compare_exchange_weak(count, &expected, new_value)) { + if (CRYPTO_atomic_compare_exchange_weak_u32(count, &expected, new_value)) { break; } } } int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { - _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *)in_count; - uint32_t expected = atomic_load(count); + CRYPTO_atomic_u32 *count = (CRYPTO_atomic_u32 *)in_count; + uint32_t expected = CRYPTO_atomic_load_u32(count); for (;;) { if (expected == 0) { @@ -57,11 +51,10 @@ int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { return 0; } else { const uint32_t new_value = expected - 1; - if (atomic_compare_exchange_weak(count, &expected, new_value)) { + if (CRYPTO_atomic_compare_exchange_weak_u32(count, &expected, + new_value)) { return new_value == 0; } } } } - -#endif // OPENSSL_C11_ATOMIC diff --git a/third_party/boringssl/kit/src/crypto/refcount_lock.c b/third_party/boringssl/kit/src/crypto/refcount_lock.c deleted file mode 100644 index fb1c11f6..00000000 --- a/third_party/boringssl/kit/src/crypto/refcount_lock.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include "internal.h" - -#include - -#include - - -#if !defined(OPENSSL_C11_ATOMIC) - -OPENSSL_STATIC_ASSERT((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, - "CRYPTO_REFCOUNT_MAX is incorrect"); - -static struct CRYPTO_STATIC_MUTEX g_refcount_lock = CRYPTO_STATIC_MUTEX_INIT; - -void CRYPTO_refcount_inc(CRYPTO_refcount_t *count) { - CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); - if (*count < CRYPTO_REFCOUNT_MAX) { - (*count)++; - } - CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); -} - -int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count) { - int ret; - - CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); - if (*count == 0) { - abort(); - } - if (*count < CRYPTO_REFCOUNT_MAX) { - (*count)--; - } - ret = (*count == 0); - CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); - - return ret; -} - -#endif // OPENSSL_C11_ATOMIC diff --git a/third_party/boringssl/kit/src/crypto/asn1/a_print.c b/third_party/boringssl/kit/src/crypto/rsa_extra/internal.h similarity index 84% rename from third_party/boringssl/kit/src/crypto/asn1/a_print.c rename to third_party/boringssl/kit/src/crypto/rsa_extra/internal.h index c7efede8..6317cfc0 100644 --- a/third_party/boringssl/kit/src/crypto/asn1/a_print.c +++ b/third_party/boringssl/kit/src/crypto/rsa_extra/internal.h @@ -54,30 +54,24 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ -#include -#include +#ifndef OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H -#include "internal.h" +#if defined(__cplusplus) +extern "C" { +#endif -int ASN1_PRINTABLE_type(const unsigned char *s, int len) -{ - if (len < 0) { - len = strlen((const char *)s); - } +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); - int printable = 1; - for (int i = 0; i < len; i++) { - unsigned char c = s[i]; - if (c & 0x80) { - /* No need to continue iterating. */ - return V_ASN1_T61STRING; - } - if (!asn1_is_printable(c)) { - printable = 0; - } - } - return printable ? V_ASN1_PRINTABLESTRING : V_ASN1_IA5STRING; -} +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RSA_EXTRA_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_crypt.c b/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_crypt.c new file mode 100644 index 00000000..c9d29fc1 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_crypt.c @@ -0,0 +1,568 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" +#include "../fipsmodule/rsa/internal.h" +#include "../internal.h" +#include "internal.h" + + +static void rand_nonzero(uint8_t *out, size_t len) { + RAND_bytes(out, len); + + for (size_t i = 0; i < len; i++) { + while (out[i] == 0) { + RAND_bytes(out + i, 1); + } + } +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, + const EVP_MD *md, const EVP_MD *mgf1md) { + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + if (to_len < 2 * mdlen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + size_t emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + uint8_t *seed = to + 1; + uint8_t *db = to + mdlen + 1; + + uint8_t *dbmask = NULL; + int ret = 0; + if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { + goto out; + } + OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); + if (!RAND_bytes(seed, mdlen)) { + goto out; + } + + dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + goto out; + } + + if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < emlen - mdlen; i++) { + db[i] ^= dbmask[i]; + } + + uint8_t seedmask[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= seedmask[i]; + } + ret = 1; + +out: + OPENSSL_free(dbmask); + return ret; +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; + + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + // The encoded message is one byte smaller than the modulus to ensure that it + // doesn't end up greater than the modulus. Thus there's an extra "+1" here + // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. + if (from_len < 1 + 2 * mdlen + 1) { + // 'from_len' is the length of the modulus, i.e. does not depend on the + // particular ciphertext. + goto decoding_err; + } + + size_t dblen = from_len - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + goto err; + } + + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + + uint8_t seed[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= maskedseed[i]; + } + + if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < dblen; i++) { + db[i] ^= maskeddb[i]; + } + + uint8_t phash[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { + goto err; + } + + crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_w(from[0]); + + crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; + size_t one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + crypto_word_t equals1 = constant_time_eq_w(db[i], 1); + crypto_word_t equals0 = constant_time_eq_w(db[i], 0); + one_index = + constant_time_select_w(looking_for_one_byte & equals1, i, one_index); + looking_for_one_byte = + constant_time_select_w(equals1, 0, looking_for_one_byte); + bad |= looking_for_one_byte & ~equals0; + } + + bad |= looking_for_one_byte; + + // Whether the overall padding was valid or not in OAEP is public. + if (constant_time_declassify_w(bad)) { + goto decoding_err; + } + + // Once the padding is known to be valid, the output length is also public. + static_assert(sizeof(size_t) <= sizeof(crypto_word_t), + "size_t does not fit in crypto_word_t"); + one_index = constant_time_declassify_w(one_index); + + one_index++; + size_t mlen = dblen - one_index; + if (max_out < mlen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; + OPENSSL_free(db); + return 1; + +decoding_err: + // To avoid chosen ciphertext attacks, the error message should not reveal + // which kind of decoding error happened. + OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); +err: + OPENSSL_free(db); + return 0; +} + +static int rsa_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 7.2.1. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + to[0] = 0; + to[1] = 2; + + size_t padding_len = to_len - 3 - from_len; + rand_nonzero(to + 2, padding_len); + to[2 + padding_len] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +static int rsa_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return 0; + } + + // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography + // Standard", section 7.2.2. + if (from_len < RSA_PKCS1_PADDING_SIZE) { + // |from| is zero-padded to the size of the RSA modulus, a public value, so + // this can be rejected in non-constant time. + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); + crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); + + crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; + for (size_t i = 2; i < from_len; i++) { + crypto_word_t equals0 = constant_time_is_zero_w(from[i]); + zero_index = + constant_time_select_w(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); + } + + // The input must begin with 00 02. + crypto_word_t valid_index = first_byte_is_zero; + valid_index &= second_byte_is_two; + + // We must have found the end of PS. + valid_index &= ~looking_for_index; + + // PS must be at least 8 bytes long, and it starts two bytes into |from|. + valid_index &= constant_time_ge_w(zero_index, 2 + 8); + + // Skip the zero byte. + zero_index++; + + // NOTE: Although this logic attempts to be constant time, the API contracts + // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + // impossible to completely avoid Bleichenbacher's attack. Consumers should + // use |RSA_PADDING_NONE| and perform the padding check in constant-time + // combined with a swap to a random session key or other mitigation. + CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index)); + CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index)); + + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { + // This shouldn't happen because this function is always called with + // |max_out| as the key size and |from_len| is bounded by the key size. + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; +} + +int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + if (!rsa_check_public_key(rsa)) { + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + uint8_t *buf = NULL; + BN_CTX *ctx = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + buf = OPENSSL_malloc(rsa_size); + if (!f || !result || !buf) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = rsa_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, NULL, 0, + NULL, NULL); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (BN_bin2bn(buf, rsa_size, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // usually the padding functions would catch this + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + // put in leading 0 bytes if the number is less than the length of the + // modulus + if (!BN_bn2bin_padded(out, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + OPENSSL_free(buf); + + return ret; +} + +static int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + goto err; + } + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + goto err; + } + + if (!rsa_private_transform(rsa, buf, in, rsa_size)) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + rsa_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + *out_len = rsa_size; + ret = 1; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + CONSTTIME_DECLASSIFY(&ret, sizeof(ret)); + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + } else { + CONSTTIME_DECLASSIFY(out, *out_len); + } + +err: + if (padding != RSA_NO_PADDING) { + OPENSSL_free(buf); + } + + return ret; +} + +int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->decrypt) { + return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} + +int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return (int)out_len; +} diff --git a/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_test.cc b/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_test.cc index 883eb97f..e332cdf7 100644 --- a/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_test.cc +++ b/third_party/boringssl/kit/src/crypto/rsa_extra/rsa_test.cc @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -79,229 +80,202 @@ // kPlaintext is a sample plaintext. -static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; -static const size_t kPlaintextLen = sizeof(kPlaintext) - 1; +static const uint8_t kPlaintext[] = {0x54, 0x85, 0x9b, 0x34, + 0x2c, 0x49, 0xea, 0x2a}; -// kKey1 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey1[] = - "\x30\x82\x01\x38\x02\x01\x00\x02\x41\x00\xaa\x36\xab\xce\x88\xac\xfd\xff" - "\x55\x52\x3c\x7f\xc4\x52\x3f\x90\xef\xa0\x0d\xf3\x77\x4a\x25\x9f\x2e\x62" - "\xb4\xc5\xd9\x9c\xb5\xad\xb3\x00\xa0\x28\x5e\x53\x01\x93\x0e\x0c\x70\xfb" - "\x68\x76\x93\x9c\xe6\x16\xce\x62\x4a\x11\xe0\x08\x6d\x34\x1e\xbc\xac\xa0" - "\xa1\xf5\x02\x01\x11\x02\x40\x0a\x03\x37\x48\x62\x64\x87\x69\x5f\x5f\x30" - "\xbc\x38\xb9\x8b\x44\xc2\xcd\x2d\xff\x43\x40\x98\xcd\x20\xd8\xa1\x38\xd0" - "\x90\xbf\x64\x79\x7c\x3f\xa7\xa2\xcd\xcb\x3c\xd1\xe0\xbd\xba\x26\x54\xb4" - "\xf9\xdf\x8e\x8a\xe5\x9d\x73\x3d\x9f\x33\xb3\x01\x62\x4a\xfd\x1d\x51\x02" - "\x21\x00\xd8\x40\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf" - "\xce\x33\x52\x52\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x12\x0d\x02\x21" - "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f" - "\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x89\x02\x20\x59" - "\x0b\x95\x72\xa2\xc2\xa9\xc4\x06\x05\x9d\xc2\xab\x2f\x1d\xaf\xeb\x7e\x8b" - "\x4f\x10\xa7\x54\x9e\x8e\xed\xf5\xb4\xfc\xe0\x9e\x05\x02\x21\x00\x8e\x3c" - "\x05\x21\xfe\x15\xe0\xea\x06\xa3\x6f\xf0\xf1\x0c\x99\x52\xc3\x5b\x7a\x75" - "\x14\xfd\x32\x38\xb8\x0a\xad\x52\x98\x62\x8d\x51\x02\x20\x36\x3f\xf7\x18" - "\x9d\xa8\xe9\x0b\x1d\x34\x1f\x71\xd0\x9b\x76\xa8\xa9\x43\xe1\x1d\x10\xb2" - "\x4d\x24\x9f\x2d\xea\xfe\xf8\x0c\x18\x26"; -// kFIPSKey is a DER-encoded RSAPrivateKey that is FIPS-compliant. -static const uint8_t kFIPSKey[] = - "\x30\x82\x02\x5c\x02\x01\x00\x02\x81\x81\x00\xa1\x71\x90\x77\x86\x8a\xc7" - "\xb8\xfc\x2a\x45\x82\x6d\xee\xeb\x35\x3a\x18\x3f\xb6\xb0\x1e\xb1\xd3\x09" - "\x6b\x05\x4d\xec\x1c\x37\x6f\x09\x31\x32\xda\x21\x8a\x49\x0e\x16\x28\xed" - "\x9a\x30\xf3\x14\x53\xfd\x5b\xb0\xf6\x4a\x5d\x52\xe1\xda\xe1\x40\x6e\x65" - "\xbf\xca\x45\xd9\x62\x96\x4a\x1e\x11\xc4\x61\x83\x1f\x58\x8d\x5e\xd0\x12" - "\xaf\xa5\xec\x9b\x97\x2f\x6c\xb2\x82\x4a\x73\xd0\xd3\x9a\xc9\x69\x6b\x24" - "\x3c\x82\x6f\xee\x4d\x0c\x7e\xdf\xd7\xae\xea\x3a\xeb\x04\x27\x8d\x43\x81" - "\x59\xa7\x90\x56\xc1\x69\x42\xb3\xaf\x1c\x8d\x4e\xbf\x02\x03\x01\x00\x01" - "\x02\x81\x80\x60\x82\xcd\x44\x46\xcf\xeb\xf9\x6f\xf5\xad\x3b\xfd\x90\x18" - "\x57\xe7\x74\xdb\x91\xd0\xd3\x68\xa6\xaa\x38\xaa\x21\x1d\x06\xf9\x34\x8d" - "\xa0\x35\xb0\x24\xe0\xd0\x2f\x75\x9b\xdd\xfe\x91\x48\x9f\x5c\x5e\x57\x54" - "\x00\xc8\x0f\xe6\x1e\x52\x84\xd9\xc9\xa5\x55\xf4\x0a\xbe\x88\x46\x7a\xfb" - "\x18\x37\x8e\xe6\x6e\xa2\x5f\x80\x48\x34\x3f\x5c\xbe\x0e\x1e\xe8\x2f\x50" - "\xba\x14\x96\x3c\xea\xfb\xd2\x49\x33\xdc\x12\xb8\xa7\x8a\xb5\x27\xf9\x00" - "\x4b\xf5\xd2\x2a\xd0\x2c\x1d\x9b\xd5\x6c\x3e\x4b\xb9\x7e\x39\xf7\x3e\x39" - "\xc9\x47\x5e\xbe\x91\x02\x41\x00\xcd\x33\xcf\x37\x01\xd7\x59\xcc\xbe\xa0" - "\x1c\xb9\xf5\xe7\x44\x9f\x62\x91\xa7\xa7\x7b\x0c\x52\xcd\x7e\xe6\x31\x11" - "\x8b\xd8\x2c\x8a\x63\xe1\x07\xc9\xcb\xce\x01\x45\x63\xf5\x5d\x44\xfb\xeb" - "\x8d\x74\x16\x20\x7d\x3b\xb4\xa1\x61\xb0\xa8\x29\x51\xc9\xef\xb6\xa1\xd5" - "\x02\x41\x00\xc9\x68\xa6\xd3\x88\xd5\x49\x9d\x6b\x44\x96\xfd\xbf\x66\x27" - "\xb4\x1f\x90\x76\x86\x2f\xe2\xce\x20\x5d\xee\x9b\xeb\xc4\xb4\x62\x47\x79" - "\x99\xb1\x99\xbc\xa2\xa6\xb6\x96\x64\xd5\x77\x9b\x45\xd4\xf0\x99\xb5\x9e" - "\x61\x4d\xf5\x12\xdd\x84\x14\xaf\x1e\xdd\x83\x24\x43\x02\x40\x60\x29\x7f" - "\x59\xcf\xcb\x13\x92\x17\x63\x01\x13\x44\x61\x74\x8f\x1c\xaa\x15\x5f\x2f" - "\x12\xbf\x5a\xfd\xb4\xf2\x19\xbe\xe7\x37\x38\x43\x46\x19\x58\x3f\xe1\xf2" - "\x46\x8a\x69\x59\xa4\x12\x4a\x78\xa7\x86\x17\x03\x99\x0f\x34\xf1\x8a\xcf" - "\xc3\x4d\x48\xcc\xc5\x51\x61\x02\x41\x00\xc2\x12\xb3\x5d\xf5\xe5\xff\xcf" - "\x4e\x43\x83\x72\xf2\xf1\x4e\xa4\xc4\x1d\x81\xf7\xff\x40\x7e\xfa\xb5\x48" - "\x6c\xba\x1c\x8a\xec\x80\x8e\xed\xc8\x32\xa9\x8f\xd9\x30\xeb\x6e\x32\x3b" - "\xd4\x44\xcf\xd1\x1f\x6b\xe0\x37\x46\xd5\x35\xde\x79\x9d\x2c\xb9\x83\x1d" - "\x10\xdd\x02\x40\x0f\x14\x95\x96\xa0\xe2\x6c\xd4\x88\xa7\x0b\x82\x14\x10" - "\xad\x26\x0d\xe4\xa1\x5e\x01\x3d\x21\xd2\xfb\x0e\xf9\x58\xa5\xca\x1e\x21" - "\xb3\xf5\x9a\x6c\x3d\x5a\x72\xb1\x2d\xfe\xac\x09\x4f\xdd\xe5\x44\xd1\x4e" - "\xf8\x59\x85\x3a\x65\xe2\xcd\xbc\x27\x1d\x9b\x48\x9f\xb9"; +// kKey1 is a DER-encoded 1024-bit RSAPrivateKey with e = 65537. +static const uint8_t kKey1[] = { + 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xa1, + 0x71, 0x90, 0x77, 0x86, 0x8a, 0xc7, 0xb8, 0xfc, 0x2a, 0x45, 0x82, 0x6d, + 0xee, 0xeb, 0x35, 0x3a, 0x18, 0x3f, 0xb6, 0xb0, 0x1e, 0xb1, 0xd3, 0x09, + 0x6b, 0x05, 0x4d, 0xec, 0x1c, 0x37, 0x6f, 0x09, 0x31, 0x32, 0xda, 0x21, + 0x8a, 0x49, 0x0e, 0x16, 0x28, 0xed, 0x9a, 0x30, 0xf3, 0x14, 0x53, 0xfd, + 0x5b, 0xb0, 0xf6, 0x4a, 0x5d, 0x52, 0xe1, 0xda, 0xe1, 0x40, 0x6e, 0x65, + 0xbf, 0xca, 0x45, 0xd9, 0x62, 0x96, 0x4a, 0x1e, 0x11, 0xc4, 0x61, 0x83, + 0x1f, 0x58, 0x8d, 0x5e, 0xd0, 0x12, 0xaf, 0xa5, 0xec, 0x9b, 0x97, 0x2f, + 0x6c, 0xb2, 0x82, 0x4a, 0x73, 0xd0, 0xd3, 0x9a, 0xc9, 0x69, 0x6b, 0x24, + 0x3c, 0x82, 0x6f, 0xee, 0x4d, 0x0c, 0x7e, 0xdf, 0xd7, 0xae, 0xea, 0x3a, + 0xeb, 0x04, 0x27, 0x8d, 0x43, 0x81, 0x59, 0xa7, 0x90, 0x56, 0xc1, 0x69, + 0x42, 0xb3, 0xaf, 0x1c, 0x8d, 0x4e, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x80, 0x60, 0x82, 0xcd, 0x44, 0x46, 0xcf, 0xeb, 0xf9, 0x6f, + 0xf5, 0xad, 0x3b, 0xfd, 0x90, 0x18, 0x57, 0xe7, 0x74, 0xdb, 0x91, 0xd0, + 0xd3, 0x68, 0xa6, 0xaa, 0x38, 0xaa, 0x21, 0x1d, 0x06, 0xf9, 0x34, 0x8d, + 0xa0, 0x35, 0xb0, 0x24, 0xe0, 0xd0, 0x2f, 0x75, 0x9b, 0xdd, 0xfe, 0x91, + 0x48, 0x9f, 0x5c, 0x5e, 0x57, 0x54, 0x00, 0xc8, 0x0f, 0xe6, 0x1e, 0x52, + 0x84, 0xd9, 0xc9, 0xa5, 0x55, 0xf4, 0x0a, 0xbe, 0x88, 0x46, 0x7a, 0xfb, + 0x18, 0x37, 0x8e, 0xe6, 0x6e, 0xa2, 0x5f, 0x80, 0x48, 0x34, 0x3f, 0x5c, + 0xbe, 0x0e, 0x1e, 0xe8, 0x2f, 0x50, 0xba, 0x14, 0x96, 0x3c, 0xea, 0xfb, + 0xd2, 0x49, 0x33, 0xdc, 0x12, 0xb8, 0xa7, 0x8a, 0xb5, 0x27, 0xf9, 0x00, + 0x4b, 0xf5, 0xd2, 0x2a, 0xd0, 0x2c, 0x1d, 0x9b, 0xd5, 0x6c, 0x3e, 0x4b, + 0xb9, 0x7e, 0x39, 0xf7, 0x3e, 0x39, 0xc9, 0x47, 0x5e, 0xbe, 0x91, 0x02, + 0x41, 0x00, 0xcd, 0x33, 0xcf, 0x37, 0x01, 0xd7, 0x59, 0xcc, 0xbe, 0xa0, + 0x1c, 0xb9, 0xf5, 0xe7, 0x44, 0x9f, 0x62, 0x91, 0xa7, 0xa7, 0x7b, 0x0c, + 0x52, 0xcd, 0x7e, 0xe6, 0x31, 0x11, 0x8b, 0xd8, 0x2c, 0x8a, 0x63, 0xe1, + 0x07, 0xc9, 0xcb, 0xce, 0x01, 0x45, 0x63, 0xf5, 0x5d, 0x44, 0xfb, 0xeb, + 0x8d, 0x74, 0x16, 0x20, 0x7d, 0x3b, 0xb4, 0xa1, 0x61, 0xb0, 0xa8, 0x29, + 0x51, 0xc9, 0xef, 0xb6, 0xa1, 0xd5, 0x02, 0x41, 0x00, 0xc9, 0x68, 0xa6, + 0xd3, 0x88, 0xd5, 0x49, 0x9d, 0x6b, 0x44, 0x96, 0xfd, 0xbf, 0x66, 0x27, + 0xb4, 0x1f, 0x90, 0x76, 0x86, 0x2f, 0xe2, 0xce, 0x20, 0x5d, 0xee, 0x9b, + 0xeb, 0xc4, 0xb4, 0x62, 0x47, 0x79, 0x99, 0xb1, 0x99, 0xbc, 0xa2, 0xa6, + 0xb6, 0x96, 0x64, 0xd5, 0x77, 0x9b, 0x45, 0xd4, 0xf0, 0x99, 0xb5, 0x9e, + 0x61, 0x4d, 0xf5, 0x12, 0xdd, 0x84, 0x14, 0xaf, 0x1e, 0xdd, 0x83, 0x24, + 0x43, 0x02, 0x40, 0x60, 0x29, 0x7f, 0x59, 0xcf, 0xcb, 0x13, 0x92, 0x17, + 0x63, 0x01, 0x13, 0x44, 0x61, 0x74, 0x8f, 0x1c, 0xaa, 0x15, 0x5f, 0x2f, + 0x12, 0xbf, 0x5a, 0xfd, 0xb4, 0xf2, 0x19, 0xbe, 0xe7, 0x37, 0x38, 0x43, + 0x46, 0x19, 0x58, 0x3f, 0xe1, 0xf2, 0x46, 0x8a, 0x69, 0x59, 0xa4, 0x12, + 0x4a, 0x78, 0xa7, 0x86, 0x17, 0x03, 0x99, 0x0f, 0x34, 0xf1, 0x8a, 0xcf, + 0xc3, 0x4d, 0x48, 0xcc, 0xc5, 0x51, 0x61, 0x02, 0x41, 0x00, 0xc2, 0x12, + 0xb3, 0x5d, 0xf5, 0xe5, 0xff, 0xcf, 0x4e, 0x43, 0x83, 0x72, 0xf2, 0xf1, + 0x4e, 0xa4, 0xc4, 0x1d, 0x81, 0xf7, 0xff, 0x40, 0x7e, 0xfa, 0xb5, 0x48, + 0x6c, 0xba, 0x1c, 0x8a, 0xec, 0x80, 0x8e, 0xed, 0xc8, 0x32, 0xa9, 0x8f, + 0xd9, 0x30, 0xeb, 0x6e, 0x32, 0x3b, 0xd4, 0x44, 0xcf, 0xd1, 0x1f, 0x6b, + 0xe0, 0x37, 0x46, 0xd5, 0x35, 0xde, 0x79, 0x9d, 0x2c, 0xb9, 0x83, 0x1d, + 0x10, 0xdd, 0x02, 0x40, 0x0f, 0x14, 0x95, 0x96, 0xa0, 0xe2, 0x6c, 0xd4, + 0x88, 0xa7, 0x0b, 0x82, 0x14, 0x10, 0xad, 0x26, 0x0d, 0xe4, 0xa1, 0x5e, + 0x01, 0x3d, 0x21, 0xd2, 0xfb, 0x0e, 0xf9, 0x58, 0xa5, 0xca, 0x1e, 0x21, + 0xb3, 0xf5, 0x9a, 0x6c, 0x3d, 0x5a, 0x72, 0xb1, 0x2d, 0xfe, 0xac, 0x09, + 0x4f, 0xdd, 0xe5, 0x44, 0xd1, 0x4e, 0xf8, 0x59, 0x85, 0x3a, 0x65, 0xe2, + 0xcd, 0xbc, 0x27, 0x1d, 0x9b, 0x48, 0x9f, 0xb9}; -static const uint8_t kFIPSPublicKey[] = - "\x30\x81\x89\x02\x81\x81\x00\xa1\x71\x90\x77\x86\x8a\xc7\xb8\xfc\x2a\x45" - "\x82\x6d\xee\xeb\x35\x3a\x18\x3f\xb6\xb0\x1e\xb1\xd3\x09\x6b\x05\x4d\xec" - "\x1c\x37\x6f\x09\x31\x32\xda\x21\x8a\x49\x0e\x16\x28\xed\x9a\x30\xf3\x14" - "\x53\xfd\x5b\xb0\xf6\x4a\x5d\x52\xe1\xda\xe1\x40\x6e\x65\xbf\xca\x45\xd9" - "\x62\x96\x4a\x1e\x11\xc4\x61\x83\x1f\x58\x8d\x5e\xd0\x12\xaf\xa5\xec\x9b" - "\x97\x2f\x6c\xb2\x82\x4a\x73\xd0\xd3\x9a\xc9\x69\x6b\x24\x3c\x82\x6f\xee" - "\x4d\x0c\x7e\xdf\xd7\xae\xea\x3a\xeb\x04\x27\x8d\x43\x81\x59\xa7\x90\x56" - "\xc1\x69\x42\xb3\xaf\x1c\x8d\x4e\xbf\x02\x03\x01\x00\x01"; +static const uint8_t kKey1Public[] = { + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa1, 0x71, 0x90, 0x77, 0x86, + 0x8a, 0xc7, 0xb8, 0xfc, 0x2a, 0x45, 0x82, 0x6d, 0xee, 0xeb, 0x35, 0x3a, + 0x18, 0x3f, 0xb6, 0xb0, 0x1e, 0xb1, 0xd3, 0x09, 0x6b, 0x05, 0x4d, 0xec, + 0x1c, 0x37, 0x6f, 0x09, 0x31, 0x32, 0xda, 0x21, 0x8a, 0x49, 0x0e, 0x16, + 0x28, 0xed, 0x9a, 0x30, 0xf3, 0x14, 0x53, 0xfd, 0x5b, 0xb0, 0xf6, 0x4a, + 0x5d, 0x52, 0xe1, 0xda, 0xe1, 0x40, 0x6e, 0x65, 0xbf, 0xca, 0x45, 0xd9, + 0x62, 0x96, 0x4a, 0x1e, 0x11, 0xc4, 0x61, 0x83, 0x1f, 0x58, 0x8d, 0x5e, + 0xd0, 0x12, 0xaf, 0xa5, 0xec, 0x9b, 0x97, 0x2f, 0x6c, 0xb2, 0x82, 0x4a, + 0x73, 0xd0, 0xd3, 0x9a, 0xc9, 0x69, 0x6b, 0x24, 0x3c, 0x82, 0x6f, 0xee, + 0x4d, 0x0c, 0x7e, 0xdf, 0xd7, 0xae, 0xea, 0x3a, 0xeb, 0x04, 0x27, 0x8d, + 0x43, 0x81, 0x59, 0xa7, 0x90, 0x56, 0xc1, 0x69, 0x42, 0xb3, 0xaf, 0x1c, + 0x8d, 0x4e, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01}; // kOAEPCiphertext1 is a sample encryption of |kPlaintext| with |kKey1| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext1[] = - "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89\x2b\xfb" - "\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52\x33\x89\x5c\x74" - "\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44\xb0\x05\xc3\x9e\xd8\x27" - "\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2"; +// RSA OAEP, SHA-1, and no label. It was generated with: +// +// clang-format off +// openssl pkeyutl -encrypt -inkey key1.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -in plaintext | xxd -i +// clang-format on +static const uint8_t kOAEPCiphertext1[] = { + 0x53, 0xa3, 0x0e, 0xc7, 0x95, 0x52, 0x80, 0x6f, 0x9d, 0x4c, 0xd2, 0x87, + 0xa0, 0x5d, 0x4b, 0xee, 0x78, 0x7d, 0xaa, 0x2a, 0xf6, 0x48, 0x5e, 0x83, + 0xb4, 0xc7, 0xd5, 0x82, 0xa7, 0xe9, 0x3e, 0x4c, 0x54, 0xa0, 0x1e, 0x5f, + 0x49, 0x17, 0x26, 0x36, 0x37, 0x22, 0x09, 0xe8, 0xde, 0x8d, 0x51, 0x49, + 0x0b, 0x34, 0x27, 0x30, 0x1f, 0x12, 0xbd, 0xf4, 0x2f, 0xed, 0x9e, 0xcf, + 0x9e, 0xda, 0x41, 0x69, 0xf7, 0x86, 0x64, 0xfc, 0x7d, 0x0a, 0x4b, 0x28, + 0x28, 0x9e, 0x38, 0x97, 0xae, 0x01, 0x86, 0xbe, 0xb0, 0x92, 0xfd, 0xa0, + 0x5c, 0x75, 0xaf, 0x01, 0x88, 0xf7, 0x24, 0xa8, 0xcd, 0x44, 0x3c, 0x13, + 0x42, 0xf7, 0x03, 0x9b, 0x88, 0x1c, 0x65, 0xf4, 0x83, 0xba, 0xc8, 0x10, + 0xe2, 0x9a, 0x37, 0x79, 0x77, 0xef, 0x20, 0x3d, 0x2d, 0xa4, 0xe5, 0x3e, + 0xd4, 0x18, 0x3e, 0x12, 0xc1, 0xc3, 0x68, 0x65}; -// kKey2 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey2[] = - "\x30\x81\xfb\x02\x01\x00\x02\x33\x00\xa3\x07\x9a\x90\xdf\x0d\xfd\x72\xac" - "\x09\x0c\xcc\x2a\x78\xb8\x74\x13\x13\x3e\x40\x75\x9c\x98\xfa\xf8\x20\x4f" - "\x35\x8a\x0b\x26\x3c\x67\x70\xe7\x83\xa9\x3b\x69\x71\xb7\x37\x79\xd2\x71" - "\x7b\xe8\x34\x77\xcf\x02\x01\x03\x02\x32\x6c\xaf\xbc\x60\x94\xb3\xfe\x4c" - "\x72\xb0\xb3\x32\xc6\xfb\x25\xa2\xb7\x62\x29\x80\x4e\x68\x65\xfc\xa4\x5a" - "\x74\xdf\x0f\x8f\xb8\x41\x3b\x52\xc0\xd0\xe5\x3d\x9b\x59\x0f\xf1\x9b\xe7" - "\x9f\x49\xdd\x21\xe5\xeb\x02\x1a\x00\xcf\x20\x35\x02\x8b\x9d\x86\x98\x40" - "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x91\x02\x1a" - "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f" - "\x6c\x42\xd0\x88\x66\xb1\xd0\x5f\x02\x1a\x00\x8a\x15\x78\xac\x5d\x13\xaf" - "\x10\x2b\x22\xb9\x99\xcd\x74\x61\xf1\x5e\x6d\x22\xcc\x03\x23\xdf\xdf\x0b" - "\x02\x1a\x00\x86\x55\x21\x4a\xc5\x4d\x8d\x4e\xcd\x61\x77\xf1\xc7\x36\x90" - "\xce\x2a\x48\x2c\x8b\x05\x99\xcb\xe0\x3f\x02\x1a\x00\x83\xef\xef\xb8\xa9" - "\xa4\x0d\x1d\xb6\xed\x98\xad\x84\xed\x13\x35\xdc\xc1\x08\xf3\x22\xd0\x57" - "\xcf\x8d"; +// kKey2 is a 2048-bit RSA private key, with e = 3. +static const uint8_t kKey2[] = { + 0x30, 0x82, 0x04, 0xa1, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0x93, 0x3a, 0x4f, 0xc9, 0x6a, 0x0a, 0x6b, 0x28, 0x04, 0xfa, 0xb7, 0x05, + 0x56, 0xdf, 0xa0, 0xaa, 0x4f, 0xaa, 0xab, 0x94, 0xa0, 0xa9, 0x25, 0xef, + 0xc5, 0x96, 0xd2, 0xd4, 0x66, 0x16, 0x62, 0x2c, 0x13, 0x7b, 0x91, 0xd0, + 0x36, 0x0a, 0x10, 0x11, 0x6d, 0x7a, 0x91, 0xb6, 0xe4, 0x74, 0x57, 0xc1, + 0x3d, 0x7a, 0xbe, 0x24, 0x05, 0x3a, 0x04, 0x0b, 0x73, 0x91, 0x53, 0xb1, + 0x74, 0x10, 0xe1, 0x87, 0xdc, 0x91, 0x28, 0x9c, 0x1e, 0xe5, 0xf2, 0xb9, + 0xfc, 0xa2, 0x48, 0x34, 0xb6, 0x78, 0xed, 0x6d, 0x95, 0xfb, 0xf2, 0xc0, + 0x4e, 0x1c, 0xa4, 0x15, 0x00, 0x3c, 0x8a, 0x68, 0x2b, 0xd6, 0xce, 0xd5, + 0xb3, 0x9f, 0x66, 0x02, 0xa7, 0x0d, 0x08, 0xa3, 0x23, 0x9b, 0xe5, 0x36, + 0x96, 0x13, 0x22, 0xf9, 0x69, 0xa6, 0x87, 0x88, 0x9b, 0x85, 0x3f, 0x83, + 0x9c, 0xab, 0x1a, 0x1b, 0x6d, 0x8d, 0x16, 0xf4, 0x5e, 0xbd, 0xee, 0x4b, + 0x59, 0x56, 0xf8, 0x9d, 0x58, 0xcd, 0xd2, 0x83, 0x85, 0x59, 0x43, 0x84, + 0x63, 0x4f, 0xe6, 0x1a, 0x86, 0x66, 0x0d, 0xb5, 0xa0, 0x87, 0x89, 0xb6, + 0x13, 0x82, 0x43, 0xda, 0x34, 0x92, 0x3b, 0x68, 0xc4, 0x95, 0x71, 0x2f, + 0x15, 0xc2, 0xe0, 0x43, 0x67, 0x3c, 0x08, 0x00, 0x36, 0x10, 0xc3, 0xb4, + 0x46, 0x4c, 0x4e, 0x6e, 0xf5, 0x44, 0xa9, 0x04, 0x44, 0x9d, 0xce, 0xc7, + 0x05, 0x79, 0xee, 0x11, 0xcf, 0xaf, 0x2c, 0xd7, 0x9a, 0x32, 0xd3, 0xa5, + 0x30, 0xd4, 0x3a, 0x78, 0x43, 0x37, 0x74, 0x22, 0x90, 0x24, 0x04, 0x11, + 0xd7, 0x95, 0x08, 0x52, 0xa4, 0x71, 0x41, 0x68, 0x94, 0xb0, 0xa0, 0xc3, + 0xec, 0x4e, 0xd2, 0xc4, 0x30, 0x71, 0x98, 0x64, 0x9c, 0xe3, 0x7c, 0x76, + 0xef, 0x33, 0xa3, 0x2b, 0xb1, 0x87, 0x63, 0xd2, 0x5c, 0x09, 0xfc, 0x90, + 0x2d, 0x92, 0xf4, 0x57, 0x02, 0x01, 0x03, 0x02, 0x82, 0x01, 0x00, 0x62, + 0x26, 0xdf, 0xdb, 0x9c, 0x06, 0xf2, 0x1a, 0xad, 0xfc, 0x7a, 0x03, 0x8f, + 0x3f, 0xc0, 0x71, 0x8a, 0x71, 0xc7, 0xb8, 0x6b, 0x1b, 0x6e, 0x9f, 0xd9, + 0x0f, 0x37, 0x38, 0x44, 0x0e, 0xec, 0x1d, 0x62, 0x52, 0x61, 0x35, 0x79, + 0x5c, 0x0a, 0xb6, 0x48, 0xfc, 0x61, 0x24, 0x98, 0x4d, 0x8f, 0xd6, 0x28, + 0xfc, 0x7e, 0xc2, 0xae, 0x26, 0xad, 0x5c, 0xf7, 0xb6, 0x37, 0xcb, 0xa2, + 0xb5, 0xeb, 0xaf, 0xe8, 0x60, 0xc5, 0xbd, 0x69, 0xee, 0xa1, 0xd1, 0x53, + 0x16, 0xda, 0xcd, 0xce, 0xfb, 0x48, 0xf3, 0xb9, 0x52, 0xa1, 0xd5, 0x89, + 0x68, 0x6d, 0x63, 0x55, 0x7d, 0xb1, 0x9a, 0xc7, 0xe4, 0x89, 0xe3, 0xcd, + 0x14, 0xee, 0xac, 0x6f, 0x5e, 0x05, 0xc2, 0x17, 0xbd, 0x43, 0x79, 0xb9, + 0x62, 0x17, 0x50, 0xf1, 0x19, 0xaf, 0xb0, 0x67, 0xae, 0x2a, 0x57, 0xbd, + 0xc7, 0x66, 0xbc, 0xf3, 0xb3, 0x64, 0xa1, 0xe3, 0x16, 0x74, 0x9e, 0xea, + 0x02, 0x5c, 0xab, 0x94, 0xd8, 0x97, 0x02, 0x42, 0x0c, 0x2c, 0xba, 0x54, + 0xb9, 0xaf, 0xe0, 0x45, 0x93, 0xad, 0x7f, 0xb3, 0x10, 0x6a, 0x96, 0x50, + 0x4b, 0xaf, 0xcf, 0xc8, 0x27, 0x62, 0x2d, 0x83, 0xe9, 0x26, 0xc6, 0x94, + 0xc1, 0xef, 0x5c, 0x8e, 0x06, 0x42, 0x53, 0xe5, 0x56, 0xaf, 0xc2, 0x99, + 0x01, 0xaa, 0x9a, 0x71, 0xbc, 0xe8, 0x21, 0x33, 0x2a, 0x2d, 0xa3, 0x36, + 0xac, 0x1b, 0x86, 0x19, 0xf8, 0xcd, 0x1f, 0x80, 0xa4, 0x26, 0x98, 0xb8, + 0x9f, 0x62, 0x62, 0xd5, 0x1a, 0x7f, 0xee, 0xdb, 0xdf, 0x81, 0xd3, 0x21, + 0xdb, 0x33, 0x92, 0xee, 0xff, 0xe2, 0x2f, 0x32, 0x77, 0x73, 0x6a, 0x58, + 0xab, 0x21, 0xf3, 0xe3, 0xe1, 0xbc, 0x4f, 0x12, 0x72, 0xa6, 0xb5, 0xc2, + 0xfb, 0x27, 0x9e, 0xc8, 0xca, 0xab, 0x64, 0xa0, 0x87, 0x07, 0x9d, 0xef, + 0xca, 0x0f, 0xdb, 0x02, 0x81, 0x81, 0x00, 0xe6, 0xd3, 0x4d, 0xc0, 0xa1, + 0x91, 0x0e, 0x62, 0xfd, 0xb0, 0xdd, 0xc6, 0x30, 0xb8, 0x8c, 0xcb, 0x14, + 0xc1, 0x4b, 0x69, 0x30, 0xdd, 0xcd, 0x86, 0x67, 0xcb, 0x37, 0x14, 0xc5, + 0x03, 0xd2, 0xb4, 0x69, 0xab, 0x3d, 0xe5, 0x16, 0x81, 0x0f, 0xe5, 0x50, + 0xf4, 0x18, 0xb1, 0xec, 0xbc, 0x71, 0xe9, 0x80, 0x99, 0x06, 0xe4, 0xa3, + 0xfe, 0x44, 0x84, 0x4a, 0x2d, 0x1e, 0x07, 0x7f, 0x22, 0x70, 0x6d, 0x4f, + 0xd4, 0x93, 0x0b, 0x8b, 0x99, 0xce, 0x1e, 0xab, 0xcd, 0x4c, 0xd2, 0xd3, + 0x10, 0x47, 0x5c, 0x09, 0x9f, 0x6d, 0x82, 0xc0, 0x08, 0x75, 0xe3, 0x3d, + 0x83, 0xc2, 0x19, 0x50, 0x29, 0xec, 0x1f, 0x84, 0x29, 0xcc, 0xf1, 0x56, + 0xee, 0xbd, 0x54, 0x5d, 0xe6, 0x19, 0xdf, 0x0d, 0x1c, 0xa4, 0xbb, 0x0a, + 0xfe, 0x84, 0x44, 0x29, 0x1d, 0xf9, 0x5c, 0x80, 0x96, 0x5b, 0x24, 0xb4, + 0xf7, 0x02, 0x1b, 0x02, 0x81, 0x81, 0x00, 0xa3, 0x48, 0xf1, 0x9c, 0x58, + 0xc2, 0x5f, 0x38, 0xfb, 0xd8, 0x12, 0x39, 0xf1, 0x8e, 0x73, 0xa1, 0xcf, + 0x78, 0x12, 0xe0, 0xed, 0x2a, 0xbb, 0xef, 0xac, 0x23, 0xb2, 0xbf, 0xd6, + 0x0c, 0xe9, 0x6e, 0x1e, 0xab, 0xea, 0x3f, 0x68, 0x36, 0xa7, 0x1f, 0xe5, + 0xab, 0xe0, 0x86, 0xa5, 0x76, 0x32, 0x98, 0xdd, 0x75, 0xb5, 0x2b, 0xbc, + 0xcb, 0x8a, 0x03, 0x00, 0x7c, 0x2e, 0xca, 0xf8, 0xbc, 0x19, 0xe4, 0xe3, + 0xa3, 0x31, 0xbd, 0x1d, 0x20, 0x2b, 0x09, 0xad, 0x6f, 0x4c, 0xed, 0x48, + 0xd4, 0xdf, 0x87, 0xf9, 0xf0, 0x46, 0xb9, 0x86, 0x4c, 0x4b, 0x71, 0xe7, + 0x48, 0x78, 0xdc, 0xed, 0xc7, 0x82, 0x02, 0x44, 0xd3, 0xa6, 0xb3, 0x10, + 0x5f, 0x62, 0x81, 0xfc, 0xb8, 0xe4, 0x0e, 0xf4, 0x1a, 0xdd, 0xab, 0x3f, + 0xbc, 0x63, 0x79, 0x5b, 0x39, 0x69, 0x5e, 0xea, 0xa9, 0x15, 0xfe, 0x90, + 0xec, 0xda, 0x75, 0x02, 0x81, 0x81, 0x00, 0x99, 0xe2, 0x33, 0xd5, 0xc1, + 0x0b, 0x5e, 0xec, 0xa9, 0x20, 0x93, 0xd9, 0x75, 0xd0, 0x5d, 0xdc, 0xb8, + 0x80, 0xdc, 0xf0, 0xcb, 0x3e, 0x89, 0x04, 0x45, 0x32, 0x24, 0xb8, 0x83, + 0x57, 0xe1, 0xcd, 0x9b, 0xc7, 0x7e, 0x98, 0xb9, 0xab, 0x5f, 0xee, 0x35, + 0xf8, 0x10, 0x76, 0x9d, 0xd2, 0xf6, 0x9b, 0xab, 0x10, 0xaf, 0x43, 0x17, + 0xfe, 0xd8, 0x58, 0x31, 0x73, 0x69, 0x5a, 0x54, 0xc1, 0xa0, 0x48, 0xdf, + 0xe3, 0x0c, 0xb2, 0x5d, 0x11, 0x34, 0x14, 0x72, 0x88, 0xdd, 0xe1, 0xe2, + 0x0a, 0xda, 0x3d, 0x5b, 0xbf, 0x9e, 0x57, 0x2a, 0xb0, 0x4e, 0x97, 0x7e, + 0x57, 0xd6, 0xbb, 0x8a, 0xc6, 0x9d, 0x6a, 0x58, 0x1b, 0xdd, 0xf6, 0x39, + 0xf4, 0x7e, 0x38, 0x3e, 0x99, 0x66, 0x94, 0xb3, 0x68, 0x6d, 0xd2, 0x07, + 0x54, 0x58, 0x2d, 0x70, 0xbe, 0xa6, 0x3d, 0xab, 0x0e, 0xe7, 0x6d, 0xcd, + 0xfa, 0x01, 0x67, 0x02, 0x81, 0x80, 0x6c, 0xdb, 0x4b, 0xbd, 0x90, 0x81, + 0x94, 0xd0, 0xa7, 0xe5, 0x61, 0x7b, 0xf6, 0x5e, 0xf7, 0xc1, 0x34, 0xfa, + 0xb7, 0x40, 0x9e, 0x1c, 0x7d, 0x4a, 0x72, 0xc2, 0x77, 0x2a, 0x8e, 0xb3, + 0x46, 0x49, 0x69, 0xc7, 0xf1, 0x7f, 0x9a, 0xcf, 0x1a, 0x15, 0x43, 0xc7, + 0xeb, 0x04, 0x6e, 0x4e, 0xcc, 0x65, 0xe8, 0xf9, 0x23, 0x72, 0x7d, 0xdd, + 0x06, 0xac, 0xaa, 0xfd, 0x74, 0x87, 0x50, 0x7d, 0x66, 0x98, 0x97, 0xc2, + 0x21, 0x28, 0xbe, 0x15, 0x72, 0x06, 0x73, 0x9f, 0x88, 0x9e, 0x30, 0x8d, + 0xea, 0x5a, 0xa6, 0xa0, 0x2f, 0x26, 0x59, 0x88, 0x32, 0x4b, 0xef, 0x85, + 0xa5, 0xe8, 0x9e, 0x85, 0x01, 0x56, 0xd8, 0x8d, 0x19, 0xcc, 0xb5, 0x94, + 0xec, 0x56, 0xa8, 0x7b, 0x42, 0xb4, 0xa2, 0xbc, 0x93, 0xc7, 0x7f, 0xd2, + 0xec, 0xfb, 0x92, 0x26, 0x46, 0x3f, 0x47, 0x1b, 0x63, 0xff, 0x0b, 0x48, + 0x91, 0xa3, 0x02, 0x81, 0x80, 0x2c, 0x4a, 0xb9, 0xa4, 0x46, 0x7b, 0xff, + 0x50, 0x7e, 0xbf, 0x60, 0x47, 0x3b, 0x2b, 0x66, 0x82, 0xdc, 0x0e, 0x53, + 0x65, 0x71, 0xe9, 0xda, 0x2a, 0xb8, 0x32, 0x93, 0x42, 0xb7, 0xff, 0xea, + 0x67, 0x66, 0xf1, 0xbc, 0x87, 0x28, 0x65, 0x29, 0x79, 0xca, 0xab, 0x93, + 0x56, 0xda, 0x95, 0xc1, 0x26, 0x44, 0x3d, 0x27, 0xc1, 0x91, 0xc6, 0x9b, + 0xd9, 0xec, 0x9d, 0xb7, 0x49, 0xe7, 0x16, 0xee, 0x99, 0x87, 0x50, 0x95, + 0x81, 0xd4, 0x5c, 0x5b, 0x5a, 0x5d, 0x0a, 0x43, 0xa5, 0xa7, 0x8f, 0x5a, + 0x80, 0x49, 0xa0, 0xb7, 0x10, 0x85, 0xc7, 0xf4, 0x42, 0x34, 0x86, 0xb6, + 0x5f, 0x3f, 0x88, 0x9e, 0xc7, 0xf5, 0x59, 0x29, 0x39, 0x68, 0x48, 0xf2, + 0xd7, 0x08, 0x5b, 0x92, 0x8e, 0x6b, 0xea, 0xa5, 0x63, 0x5f, 0xc0, 0xfb, + 0xe4, 0xe1, 0xb2, 0x7d, 0xb7, 0x40, 0xe9, 0x55, 0x06, 0xbf, 0x58, 0x25, + 0x6f}; -// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext2[] = - "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a\x8b\x40" - "\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4\x17\x53\x03\x29" - "\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52\x62\x51"; - -// kKey3 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey3[] = - "\x30\x82\x02\x5b\x02\x01\x00\x02\x81\x81\x00\xbb\xf8\x2f\x09\x06\x82\xce" - "\x9c\x23\x38\xac\x2b\x9d\xa8\x71\xf7\x36\x8d\x07\xee\xd4\x10\x43\xa4\x40" - "\xd6\xb6\xf0\x74\x54\xf5\x1f\xb8\xdf\xba\xaf\x03\x5c\x02\xab\x61\xea\x48" - "\xce\xeb\x6f\xcd\x48\x76\xed\x52\x0d\x60\xe1\xec\x46\x19\x71\x9d\x8a\x5b" - "\x8b\x80\x7f\xaf\xb8\xe0\xa3\xdf\xc7\x37\x72\x3e\xe6\xb4\xb7\xd9\x3a\x25" - "\x84\xee\x6a\x64\x9d\x06\x09\x53\x74\x88\x34\xb2\x45\x45\x98\x39\x4e\xe0" - "\xaa\xb1\x2d\x7b\x61\xa5\x1f\x52\x7a\x9a\x41\xf6\xc1\x68\x7f\xe2\x53\x72" - "\x98\xca\x2a\x8f\x59\x46\xf8\xe5\xfd\x09\x1d\xbd\xcb\x02\x01\x11\x02\x81" - "\x81\x00\xa5\xda\xfc\x53\x41\xfa\xf2\x89\xc4\xb9\x88\xdb\x30\xc1\xcd\xf8" - "\x3f\x31\x25\x1e\x06\x68\xb4\x27\x84\x81\x38\x01\x57\x96\x41\xb2\x94\x10" - "\xb3\xc7\x99\x8d\x6b\xc4\x65\x74\x5e\x5c\x39\x26\x69\xd6\x87\x0d\xa2\xc0" - "\x82\xa9\x39\xe3\x7f\xdc\xb8\x2e\xc9\x3e\xda\xc9\x7f\xf3\xad\x59\x50\xac" - "\xcf\xbc\x11\x1c\x76\xf1\xa9\x52\x94\x44\xe5\x6a\xaf\x68\xc5\x6c\x09\x2c" - "\xd3\x8d\xc3\xbe\xf5\xd2\x0a\x93\x99\x26\xed\x4f\x74\xa1\x3e\xdd\xfb\xe1" - "\xa1\xce\xcc\x48\x94\xaf\x94\x28\xc2\xb7\xb8\x88\x3f\xe4\x46\x3a\x4b\xc8" - "\x5b\x1c\xb3\xc1\x02\x41\x00\xee\xcf\xae\x81\xb1\xb9\xb3\xc9\x08\x81\x0b" - "\x10\xa1\xb5\x60\x01\x99\xeb\x9f\x44\xae\xf4\xfd\xa4\x93\xb8\x1a\x9e\x3d" - "\x84\xf6\x32\x12\x4e\xf0\x23\x6e\x5d\x1e\x3b\x7e\x28\xfa\xe7\xaa\x04\x0a" - "\x2d\x5b\x25\x21\x76\x45\x9d\x1f\x39\x75\x41\xba\x2a\x58\xfb\x65\x99\x02" - "\x41\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35" - "\x3f\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x86\x98\x40" - "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x33\x52\x52" - "\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x15\x03\x02\x40\x54\x49\x4c\xa6" - "\x3e\xba\x03\x37\xe4\xe2\x40\x23\xfc\xd6\x9a\x5a\xeb\x07\xdd\xdc\x01\x83" - "\xa4\xd0\xac\x9b\x54\xb0\x51\xf2\xb1\x3e\xd9\x49\x09\x75\xea\xb7\x74\x14" - "\xff\x59\xc1\xf7\x69\x2e\x9a\x2e\x20\x2b\x38\xfc\x91\x0a\x47\x41\x74\xad" - "\xc9\x3c\x1f\x67\xc9\x81\x02\x40\x47\x1e\x02\x90\xff\x0a\xf0\x75\x03\x51" - "\xb7\xf8\x78\x86\x4c\xa9\x61\xad\xbd\x3a\x8a\x7e\x99\x1c\x5c\x05\x56\xa9" - "\x4c\x31\x46\xa7\xf9\x80\x3f\x8f\x6f\x8a\xe3\x42\xe9\x31\xfd\x8a\xe4\x7a" - "\x22\x0d\x1b\x99\xa4\x95\x84\x98\x07\xfe\x39\xf9\x24\x5a\x98\x36\xda\x3d" - "\x02\x41\x00\xb0\x6c\x4f\xda\xbb\x63\x01\x19\x8d\x26\x5b\xdb\xae\x94\x23" - "\xb3\x80\xf2\x71\xf7\x34\x53\x88\x50\x93\x07\x7f\xcd\x39\xe2\x11\x9f\xc9" - "\x86\x32\x15\x4f\x58\x83\xb1\x67\xa9\x67\xbf\x40\x2b\x4e\x9e\x2e\x0f\x96" - "\x56\xe6\x98\xea\x36\x66\xed\xfb\x25\x79\x80\x39\xf7"; - -// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext3[] = - "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7\x90\xc4" - "\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce\xf0\xc4\x36\x6f" - "\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3\xf2\xf1\x92\xdb\xea\xca" - "\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06\x69\xac\x22\xe9\xf3\xa7\x85\x2e" - "\x3c\x15\xd9\x13\xca\xb0\xb8\x86\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49" - "\x54\x61\x03\x46\xf4\xd4\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a" - "\x1f\xc4\x02\x6a\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20" - "\x2f\xb1"; - -static const uint8_t kTwoPrimeKey[] = - "\x30\x82\x04\xa1\x02\x01\x00\x02\x82\x01\x01\x00\x93\x3a\x4f\xc9\x6a\x0a" - "\x6b\x28\x04\xfa\xb7\x05\x56\xdf\xa0\xaa\x4f\xaa\xab\x94\xa0\xa9\x25\xef" - "\xc5\x96\xd2\xd4\x66\x16\x62\x2c\x13\x7b\x91\xd0\x36\x0a\x10\x11\x6d\x7a" - "\x91\xb6\xe4\x74\x57\xc1\x3d\x7a\xbe\x24\x05\x3a\x04\x0b\x73\x91\x53\xb1" - "\x74\x10\xe1\x87\xdc\x91\x28\x9c\x1e\xe5\xf2\xb9\xfc\xa2\x48\x34\xb6\x78" - "\xed\x6d\x95\xfb\xf2\xc0\x4e\x1c\xa4\x15\x00\x3c\x8a\x68\x2b\xd6\xce\xd5" - "\xb3\x9f\x66\x02\xa7\x0d\x08\xa3\x23\x9b\xe5\x36\x96\x13\x22\xf9\x69\xa6" - "\x87\x88\x9b\x85\x3f\x83\x9c\xab\x1a\x1b\x6d\x8d\x16\xf4\x5e\xbd\xee\x4b" - "\x59\x56\xf8\x9d\x58\xcd\xd2\x83\x85\x59\x43\x84\x63\x4f\xe6\x1a\x86\x66" - "\x0d\xb5\xa0\x87\x89\xb6\x13\x82\x43\xda\x34\x92\x3b\x68\xc4\x95\x71\x2f" - "\x15\xc2\xe0\x43\x67\x3c\x08\x00\x36\x10\xc3\xb4\x46\x4c\x4e\x6e\xf5\x44" - "\xa9\x04\x44\x9d\xce\xc7\x05\x79\xee\x11\xcf\xaf\x2c\xd7\x9a\x32\xd3\xa5" - "\x30\xd4\x3a\x78\x43\x37\x74\x22\x90\x24\x04\x11\xd7\x95\x08\x52\xa4\x71" - "\x41\x68\x94\xb0\xa0\xc3\xec\x4e\xd2\xc4\x30\x71\x98\x64\x9c\xe3\x7c\x76" - "\xef\x33\xa3\x2b\xb1\x87\x63\xd2\x5c\x09\xfc\x90\x2d\x92\xf4\x57\x02\x01" - "\x03\x02\x82\x01\x00\x62\x26\xdf\xdb\x9c\x06\xf2\x1a\xad\xfc\x7a\x03\x8f" - "\x3f\xc0\x71\x8a\x71\xc7\xb8\x6b\x1b\x6e\x9f\xd9\x0f\x37\x38\x44\x0e\xec" - "\x1d\x62\x52\x61\x35\x79\x5c\x0a\xb6\x48\xfc\x61\x24\x98\x4d\x8f\xd6\x28" - "\xfc\x7e\xc2\xae\x26\xad\x5c\xf7\xb6\x37\xcb\xa2\xb5\xeb\xaf\xe8\x60\xc5" - "\xbd\x69\xee\xa1\xd1\x53\x16\xda\xcd\xce\xfb\x48\xf3\xb9\x52\xa1\xd5\x89" - "\x68\x6d\x63\x55\x7d\xb1\x9a\xc7\xe4\x89\xe3\xcd\x14\xee\xac\x6f\x5e\x05" - "\xc2\x17\xbd\x43\x79\xb9\x62\x17\x50\xf1\x19\xaf\xb0\x67\xae\x2a\x57\xbd" - "\xc7\x66\xbc\xf3\xb3\x64\xa1\xe3\x16\x74\x9e\xea\x02\x5c\xab\x94\xd8\x97" - "\x02\x42\x0c\x2c\xba\x54\xb9\xaf\xe0\x45\x93\xad\x7f\xb3\x10\x6a\x96\x50" - "\x4b\xaf\xcf\xc8\x27\x62\x2d\x83\xe9\x26\xc6\x94\xc1\xef\x5c\x8e\x06\x42" - "\x53\xe5\x56\xaf\xc2\x99\x01\xaa\x9a\x71\xbc\xe8\x21\x33\x2a\x2d\xa3\x36" - "\xac\x1b\x86\x19\xf8\xcd\x1f\x80\xa4\x26\x98\xb8\x9f\x62\x62\xd5\x1a\x7f" - "\xee\xdb\xdf\x81\xd3\x21\xdb\x33\x92\xee\xff\xe2\x2f\x32\x77\x73\x6a\x58" - "\xab\x21\xf3\xe3\xe1\xbc\x4f\x12\x72\xa6\xb5\xc2\xfb\x27\x9e\xc8\xca\xab" - "\x64\xa0\x87\x07\x9d\xef\xca\x0f\xdb\x02\x81\x81\x00\xe6\xd3\x4d\xc0\xa1" - "\x91\x0e\x62\xfd\xb0\xdd\xc6\x30\xb8\x8c\xcb\x14\xc1\x4b\x69\x30\xdd\xcd" - "\x86\x67\xcb\x37\x14\xc5\x03\xd2\xb4\x69\xab\x3d\xe5\x16\x81\x0f\xe5\x50" - "\xf4\x18\xb1\xec\xbc\x71\xe9\x80\x99\x06\xe4\xa3\xfe\x44\x84\x4a\x2d\x1e" - "\x07\x7f\x22\x70\x6d\x4f\xd4\x93\x0b\x8b\x99\xce\x1e\xab\xcd\x4c\xd2\xd3" - "\x10\x47\x5c\x09\x9f\x6d\x82\xc0\x08\x75\xe3\x3d\x83\xc2\x19\x50\x29\xec" - "\x1f\x84\x29\xcc\xf1\x56\xee\xbd\x54\x5d\xe6\x19\xdf\x0d\x1c\xa4\xbb\x0a" - "\xfe\x84\x44\x29\x1d\xf9\x5c\x80\x96\x5b\x24\xb4\xf7\x02\x1b\x02\x81\x81" - "\x00\xa3\x48\xf1\x9c\x58\xc2\x5f\x38\xfb\xd8\x12\x39\xf1\x8e\x73\xa1\xcf" - "\x78\x12\xe0\xed\x2a\xbb\xef\xac\x23\xb2\xbf\xd6\x0c\xe9\x6e\x1e\xab\xea" - "\x3f\x68\x36\xa7\x1f\xe5\xab\xe0\x86\xa5\x76\x32\x98\xdd\x75\xb5\x2b\xbc" - "\xcb\x8a\x03\x00\x7c\x2e\xca\xf8\xbc\x19\xe4\xe3\xa3\x31\xbd\x1d\x20\x2b" - "\x09\xad\x6f\x4c\xed\x48\xd4\xdf\x87\xf9\xf0\x46\xb9\x86\x4c\x4b\x71\xe7" - "\x48\x78\xdc\xed\xc7\x82\x02\x44\xd3\xa6\xb3\x10\x5f\x62\x81\xfc\xb8\xe4" - "\x0e\xf4\x1a\xdd\xab\x3f\xbc\x63\x79\x5b\x39\x69\x5e\xea\xa9\x15\xfe\x90" - "\xec\xda\x75\x02\x81\x81\x00\x99\xe2\x33\xd5\xc1\x0b\x5e\xec\xa9\x20\x93" - "\xd9\x75\xd0\x5d\xdc\xb8\x80\xdc\xf0\xcb\x3e\x89\x04\x45\x32\x24\xb8\x83" - "\x57\xe1\xcd\x9b\xc7\x7e\x98\xb9\xab\x5f\xee\x35\xf8\x10\x76\x9d\xd2\xf6" - "\x9b\xab\x10\xaf\x43\x17\xfe\xd8\x58\x31\x73\x69\x5a\x54\xc1\xa0\x48\xdf" - "\xe3\x0c\xb2\x5d\x11\x34\x14\x72\x88\xdd\xe1\xe2\x0a\xda\x3d\x5b\xbf\x9e" - "\x57\x2a\xb0\x4e\x97\x7e\x57\xd6\xbb\x8a\xc6\x9d\x6a\x58\x1b\xdd\xf6\x39" - "\xf4\x7e\x38\x3e\x99\x66\x94\xb3\x68\x6d\xd2\x07\x54\x58\x2d\x70\xbe\xa6" - "\x3d\xab\x0e\xe7\x6d\xcd\xfa\x01\x67\x02\x81\x80\x6c\xdb\x4b\xbd\x90\x81" - "\x94\xd0\xa7\xe5\x61\x7b\xf6\x5e\xf7\xc1\x34\xfa\xb7\x40\x9e\x1c\x7d\x4a" - "\x72\xc2\x77\x2a\x8e\xb3\x46\x49\x69\xc7\xf1\x7f\x9a\xcf\x1a\x15\x43\xc7" - "\xeb\x04\x6e\x4e\xcc\x65\xe8\xf9\x23\x72\x7d\xdd\x06\xac\xaa\xfd\x74\x87" - "\x50\x7d\x66\x98\x97\xc2\x21\x28\xbe\x15\x72\x06\x73\x9f\x88\x9e\x30\x8d" - "\xea\x5a\xa6\xa0\x2f\x26\x59\x88\x32\x4b\xef\x85\xa5\xe8\x9e\x85\x01\x56" - "\xd8\x8d\x19\xcc\xb5\x94\xec\x56\xa8\x7b\x42\xb4\xa2\xbc\x93\xc7\x7f\xd2" - "\xec\xfb\x92\x26\x46\x3f\x47\x1b\x63\xff\x0b\x48\x91\xa3\x02\x81\x80\x2c" - "\x4a\xb9\xa4\x46\x7b\xff\x50\x7e\xbf\x60\x47\x3b\x2b\x66\x82\xdc\x0e\x53" - "\x65\x71\xe9\xda\x2a\xb8\x32\x93\x42\xb7\xff\xea\x67\x66\xf1\xbc\x87\x28" - "\x65\x29\x79\xca\xab\x93\x56\xda\x95\xc1\x26\x44\x3d\x27\xc1\x91\xc6\x9b" - "\xd9\xec\x9d\xb7\x49\xe7\x16\xee\x99\x87\x50\x95\x81\xd4\x5c\x5b\x5a\x5d" - "\x0a\x43\xa5\xa7\x8f\x5a\x80\x49\xa0\xb7\x10\x85\xc7\xf4\x42\x34\x86\xb6" - "\x5f\x3f\x88\x9e\xc7\xf5\x59\x29\x39\x68\x48\xf2\xd7\x08\x5b\x92\x8e\x6b" - "\xea\xa5\x63\x5f\xc0\xfb\xe4\xe1\xb2\x7d\xb7\x40\xe9\x55\x06\xbf\x58\x25" - "\x6f"; - -static const uint8_t kTwoPrimeEncryptedMessage[] = { +// kPKCS1Ciphertext2 is "hello world" encrypted with kKey2 and RSAES-PKCS1-v1_5. +static const uint8_t kPKCS1Ciphertext2[] = { 0x63, 0x0a, 0x30, 0x45, 0x43, 0x11, 0x45, 0xb7, 0x99, 0x67, 0x90, 0x35, 0x37, 0x27, 0xff, 0xbc, 0xe0, 0xbf, 0xa6, 0xd1, 0x47, 0x50, 0xbb, 0x6c, 0x1c, 0xaa, 0x66, 0xf2, 0xff, 0x9d, 0x9a, 0xa6, 0xb4, 0x16, 0x63, 0xb0, @@ -323,8 +297,107 @@ static const uint8_t kTwoPrimeEncryptedMessage[] = { 0xc2, 0x73, 0x51, 0xb5, 0x03, 0xfb, 0xf9, 0xf6, 0xb5, 0x8d, 0x4e, 0x6c, 0x21, 0x0e, 0xf9, 0x97, 0x26, 0x57, 0xf3, 0x52, 0x72, 0x07, 0xf8, 0xb4, 0xcd, 0xb4, 0x39, 0xcf, 0xbf, 0x78, 0xcc, 0xb6, 0x87, 0xf9, 0xb7, 0x8b, - 0x6a, 0xce, 0x9f, 0xc8, -}; + 0x6a, 0xce, 0x9f, 0xc8}; + +// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using +// RSA OAEP, SHA-1, and no label. It was generated with: +// +// clang-format off +// openssl pkeyutl -encrypt -inkey key2.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -in plaintext | xxd -i +// clang-format on +static const uint8_t kOAEPCiphertext2[] = { + 0x56, 0x10, 0x50, 0x5b, 0x9a, 0xa8, 0x2e, 0x3f, 0x24, 0x06, 0x5b, 0xd3, + 0x06, 0x03, 0xde, 0x18, 0x69, 0xb2, 0x1b, 0xec, 0x12, 0x14, 0x76, 0xb9, + 0x8c, 0x7b, 0xf8, 0x4a, 0xaf, 0x87, 0xa8, 0x83, 0x49, 0x1c, 0x5e, 0xb4, + 0xe5, 0x9f, 0xff, 0x00, 0xf2, 0xdd, 0x34, 0xf0, 0x10, 0x9f, 0xca, 0xc6, + 0x02, 0x54, 0x23, 0xb2, 0xc3, 0xdc, 0x74, 0xa8, 0x9f, 0xd2, 0xdc, 0x87, + 0x48, 0x2f, 0x02, 0x8b, 0xf1, 0x7a, 0x91, 0x8d, 0x2d, 0x77, 0x7f, 0x6f, + 0x8f, 0x19, 0xde, 0x90, 0x54, 0x0d, 0x1b, 0x7b, 0x96, 0x81, 0x84, 0xf9, + 0x03, 0x48, 0xef, 0xab, 0xe5, 0x07, 0xcd, 0x7f, 0x01, 0xeb, 0x86, 0x8d, + 0x7e, 0x7e, 0xf8, 0x2a, 0x50, 0x02, 0xcd, 0xcb, 0xa5, 0xfe, 0xc2, 0x35, + 0x1f, 0x82, 0xef, 0xb9, 0x1d, 0x98, 0xd5, 0x07, 0x94, 0x37, 0x08, 0x13, + 0x1c, 0xc8, 0x19, 0x06, 0x13, 0x2d, 0x1c, 0xb2, 0x50, 0x34, 0xad, 0x99, + 0x3c, 0xe6, 0xce, 0x4c, 0x88, 0x6d, 0x96, 0xc8, 0x85, 0xd1, 0x5e, 0xd5, + 0x77, 0x02, 0x0a, 0xa9, 0x2a, 0xf1, 0xa3, 0x4a, 0x04, 0x65, 0x87, 0x05, + 0x6b, 0x34, 0x65, 0x1c, 0xef, 0x64, 0x11, 0xee, 0x23, 0x7e, 0x36, 0x4f, + 0x4c, 0x5d, 0xb7, 0xd6, 0x79, 0x30, 0xec, 0xdf, 0xde, 0x35, 0x32, 0xd0, + 0xb0, 0x7e, 0x26, 0x1f, 0xea, 0xa2, 0x78, 0x98, 0x4b, 0x77, 0x9b, 0x03, + 0x75, 0x33, 0x08, 0x72, 0x91, 0x0b, 0x77, 0xc0, 0x6e, 0xe1, 0x0f, 0x14, + 0xf1, 0xf0, 0xb9, 0xe5, 0x5f, 0x08, 0xc2, 0x92, 0x79, 0x2e, 0x6f, 0xef, + 0x2a, 0x1b, 0x31, 0x64, 0x36, 0x67, 0xf8, 0x1d, 0xc8, 0xb7, 0xc3, 0x15, + 0x6c, 0xd8, 0x35, 0x34, 0x44, 0xb2, 0x91, 0xf2, 0x07, 0x86, 0xd6, 0xfa, + 0x42, 0x04, 0xae, 0xc5, 0x17, 0x14, 0x61, 0x6f, 0x12, 0x84, 0xb9, 0x99, + 0x47, 0xd1, 0xdc, 0x3c}; + +// kKey3 is a DER-encoded RSAPrivateKey. It is a 1024-bit RSA private key with +// exponent 17. +static const uint8_t kKey3[] = { + 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbb, + 0xf8, 0x2f, 0x09, 0x06, 0x82, 0xce, 0x9c, 0x23, 0x38, 0xac, 0x2b, 0x9d, + 0xa8, 0x71, 0xf7, 0x36, 0x8d, 0x07, 0xee, 0xd4, 0x10, 0x43, 0xa4, 0x40, + 0xd6, 0xb6, 0xf0, 0x74, 0x54, 0xf5, 0x1f, 0xb8, 0xdf, 0xba, 0xaf, 0x03, + 0x5c, 0x02, 0xab, 0x61, 0xea, 0x48, 0xce, 0xeb, 0x6f, 0xcd, 0x48, 0x76, + 0xed, 0x52, 0x0d, 0x60, 0xe1, 0xec, 0x46, 0x19, 0x71, 0x9d, 0x8a, 0x5b, + 0x8b, 0x80, 0x7f, 0xaf, 0xb8, 0xe0, 0xa3, 0xdf, 0xc7, 0x37, 0x72, 0x3e, + 0xe6, 0xb4, 0xb7, 0xd9, 0x3a, 0x25, 0x84, 0xee, 0x6a, 0x64, 0x9d, 0x06, + 0x09, 0x53, 0x74, 0x88, 0x34, 0xb2, 0x45, 0x45, 0x98, 0x39, 0x4e, 0xe0, + 0xaa, 0xb1, 0x2d, 0x7b, 0x61, 0xa5, 0x1f, 0x52, 0x7a, 0x9a, 0x41, 0xf6, + 0xc1, 0x68, 0x7f, 0xe2, 0x53, 0x72, 0x98, 0xca, 0x2a, 0x8f, 0x59, 0x46, + 0xf8, 0xe5, 0xfd, 0x09, 0x1d, 0xbd, 0xcb, 0x02, 0x01, 0x11, 0x02, 0x81, + 0x81, 0x00, 0xa5, 0xda, 0xfc, 0x53, 0x41, 0xfa, 0xf2, 0x89, 0xc4, 0xb9, + 0x88, 0xdb, 0x30, 0xc1, 0xcd, 0xf8, 0x3f, 0x31, 0x25, 0x1e, 0x06, 0x68, + 0xb4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xb2, 0x94, 0x10, + 0xb3, 0xc7, 0x99, 0x8d, 0x6b, 0xc4, 0x65, 0x74, 0x5e, 0x5c, 0x39, 0x26, + 0x69, 0xd6, 0x87, 0x0d, 0xa2, 0xc0, 0x82, 0xa9, 0x39, 0xe3, 0x7f, 0xdc, + 0xb8, 0x2e, 0xc9, 0x3e, 0xda, 0xc9, 0x7f, 0xf3, 0xad, 0x59, 0x50, 0xac, + 0xcf, 0xbc, 0x11, 0x1c, 0x76, 0xf1, 0xa9, 0x52, 0x94, 0x44, 0xe5, 0x6a, + 0xaf, 0x68, 0xc5, 0x6c, 0x09, 0x2c, 0xd3, 0x8d, 0xc3, 0xbe, 0xf5, 0xd2, + 0x0a, 0x93, 0x99, 0x26, 0xed, 0x4f, 0x74, 0xa1, 0x3e, 0xdd, 0xfb, 0xe1, + 0xa1, 0xce, 0xcc, 0x48, 0x94, 0xaf, 0x94, 0x28, 0xc2, 0xb7, 0xb8, 0x88, + 0x3f, 0xe4, 0x46, 0x3a, 0x4b, 0xc8, 0x5b, 0x1c, 0xb3, 0xc1, 0x02, 0x41, + 0x00, 0xee, 0xcf, 0xae, 0x81, 0xb1, 0xb9, 0xb3, 0xc9, 0x08, 0x81, 0x0b, + 0x10, 0xa1, 0xb5, 0x60, 0x01, 0x99, 0xeb, 0x9f, 0x44, 0xae, 0xf4, 0xfd, + 0xa4, 0x93, 0xb8, 0x1a, 0x9e, 0x3d, 0x84, 0xf6, 0x32, 0x12, 0x4e, 0xf0, + 0x23, 0x6e, 0x5d, 0x1e, 0x3b, 0x7e, 0x28, 0xfa, 0xe7, 0xaa, 0x04, 0x0a, + 0x2d, 0x5b, 0x25, 0x21, 0x76, 0x45, 0x9d, 0x1f, 0x39, 0x75, 0x41, 0xba, + 0x2a, 0x58, 0xfb, 0x65, 0x99, 0x02, 0x41, 0x00, 0xc9, 0x7f, 0xb1, 0xf0, + 0x27, 0xf4, 0x53, 0xf6, 0x34, 0x12, 0x33, 0xea, 0xaa, 0xd1, 0xd9, 0x35, + 0x3f, 0x6c, 0x42, 0xd0, 0x88, 0x66, 0xb1, 0xd0, 0x5a, 0x0f, 0x20, 0x35, + 0x02, 0x8b, 0x9d, 0x86, 0x98, 0x40, 0xb4, 0x16, 0x66, 0xb4, 0x2e, 0x92, + 0xea, 0x0d, 0xa3, 0xb4, 0x32, 0x04, 0xb5, 0xcf, 0xce, 0x33, 0x52, 0x52, + 0x4d, 0x04, 0x16, 0xa5, 0xa4, 0x41, 0xe7, 0x00, 0xaf, 0x46, 0x15, 0x03, + 0x02, 0x40, 0x54, 0x49, 0x4c, 0xa6, 0x3e, 0xba, 0x03, 0x37, 0xe4, 0xe2, + 0x40, 0x23, 0xfc, 0xd6, 0x9a, 0x5a, 0xeb, 0x07, 0xdd, 0xdc, 0x01, 0x83, + 0xa4, 0xd0, 0xac, 0x9b, 0x54, 0xb0, 0x51, 0xf2, 0xb1, 0x3e, 0xd9, 0x49, + 0x09, 0x75, 0xea, 0xb7, 0x74, 0x14, 0xff, 0x59, 0xc1, 0xf7, 0x69, 0x2e, + 0x9a, 0x2e, 0x20, 0x2b, 0x38, 0xfc, 0x91, 0x0a, 0x47, 0x41, 0x74, 0xad, + 0xc9, 0x3c, 0x1f, 0x67, 0xc9, 0x81, 0x02, 0x40, 0x47, 0x1e, 0x02, 0x90, + 0xff, 0x0a, 0xf0, 0x75, 0x03, 0x51, 0xb7, 0xf8, 0x78, 0x86, 0x4c, 0xa9, + 0x61, 0xad, 0xbd, 0x3a, 0x8a, 0x7e, 0x99, 0x1c, 0x5c, 0x05, 0x56, 0xa9, + 0x4c, 0x31, 0x46, 0xa7, 0xf9, 0x80, 0x3f, 0x8f, 0x6f, 0x8a, 0xe3, 0x42, + 0xe9, 0x31, 0xfd, 0x8a, 0xe4, 0x7a, 0x22, 0x0d, 0x1b, 0x99, 0xa4, 0x95, + 0x84, 0x98, 0x07, 0xfe, 0x39, 0xf9, 0x24, 0x5a, 0x98, 0x36, 0xda, 0x3d, + 0x02, 0x41, 0x00, 0xb0, 0x6c, 0x4f, 0xda, 0xbb, 0x63, 0x01, 0x19, 0x8d, + 0x26, 0x5b, 0xdb, 0xae, 0x94, 0x23, 0xb3, 0x80, 0xf2, 0x71, 0xf7, 0x34, + 0x53, 0x88, 0x50, 0x93, 0x07, 0x7f, 0xcd, 0x39, 0xe2, 0x11, 0x9f, 0xc9, + 0x86, 0x32, 0x15, 0x4f, 0x58, 0x83, 0xb1, 0x67, 0xa9, 0x67, 0xbf, 0x40, + 0x2b, 0x4e, 0x9e, 0x2e, 0x0f, 0x96, 0x56, 0xe6, 0x98, 0xea, 0x36, 0x66, + 0xed, 0xfb, 0x25, 0x79, 0x80, 0x39, 0xf7}; + +// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using +// RSA OAEP, SHA-1, and no label. +static const uint8_t kOAEPCiphertext3[] = { + 0xb8, 0x24, 0x6b, 0x56, 0xa6, 0xed, 0x58, 0x81, 0xae, 0xb5, 0x85, 0xd9, + 0xa2, 0x5b, 0x2a, 0xd7, 0x90, 0xc4, 0x17, 0xe0, 0x80, 0x68, 0x1b, 0xf1, + 0xac, 0x2b, 0xc3, 0xde, 0xb6, 0x9d, 0x8b, 0xce, 0xf0, 0xc4, 0x36, 0x6f, + 0xec, 0x40, 0x0a, 0xf0, 0x52, 0xa7, 0x2e, 0x9b, 0x0e, 0xff, 0xb5, 0xb3, + 0xf2, 0xf1, 0x92, 0xdb, 0xea, 0xca, 0x03, 0xc1, 0x27, 0x40, 0x05, 0x71, + 0x13, 0xbf, 0x1f, 0x06, 0x69, 0xac, 0x22, 0xe9, 0xf3, 0xa7, 0x85, 0x2e, + 0x3c, 0x15, 0xd9, 0x13, 0xca, 0xb0, 0xb8, 0x86, 0x3a, 0x95, 0xc9, 0x92, + 0x94, 0xce, 0x86, 0x74, 0x21, 0x49, 0x54, 0x61, 0x03, 0x46, 0xf4, 0xd4, + 0x74, 0xb2, 0x6f, 0x7c, 0x48, 0xb4, 0x2e, 0xe6, 0x8e, 0x1f, 0x57, 0x2a, + 0x1f, 0xc4, 0x02, 0x6a, 0xc4, 0x56, 0xb4, 0xf5, 0x9f, 0x7b, 0x62, 0x1e, + 0xa1, 0xb9, 0xd8, 0x8f, 0x64, 0x20, 0x2f, 0xb1}; // kEstonianRSAKey is an RSAPublicKey encoded with a negative modulus. See // https://crbug.com/532048. @@ -383,81 +456,118 @@ static const uint8_t kExponent1RSAKey[] = { }; struct RSAEncryptParam { - const uint8_t *der; - size_t der_len; - const uint8_t *oaep_ciphertext; - size_t oaep_ciphertext_len; + bssl::Span der; + bssl::Span oaep_ciphertext; } kRSAEncryptParams[] = { - {kKey1, sizeof(kKey1) - 1, kOAEPCiphertext1, sizeof(kOAEPCiphertext1) - 1}, - {kKey2, sizeof(kKey2) - 1, kOAEPCiphertext2, sizeof(kOAEPCiphertext2) - 1}, - {kKey3, sizeof(kKey3) - 1, kOAEPCiphertext3, sizeof(kOAEPCiphertext3) - 1}, + {kKey1, kOAEPCiphertext1}, + {kKey2, kOAEPCiphertext2}, + {kKey3, kOAEPCiphertext3}, }; class RSAEncryptTest : public testing::TestWithParam {}; TEST_P(RSAEncryptTest, TestKey) { + // Construct an RSA key in different ways. const auto ¶m = GetParam(); - bssl::UniquePtr key( - RSA_private_key_from_bytes(param.der, param.der_len)); - ASSERT_TRUE(key); + bssl::UniquePtr parsed( + RSA_private_key_from_bytes(param.der.data(), param.der.size())); + ASSERT_TRUE(parsed); + EXPECT_TRUE(RSA_get0_e(parsed.get())); + EXPECT_TRUE(RSA_get0_d(parsed.get())); - EXPECT_TRUE(RSA_check_key(key.get())); + bssl::UniquePtr constructed(RSA_new_private_key( + RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), + RSA_get0_d(parsed.get()), RSA_get0_p(parsed.get()), + RSA_get0_q(parsed.get()), RSA_get0_dmp1(parsed.get()), + RSA_get0_dmq1(parsed.get()), RSA_get0_iqmp(parsed.get()))); + ASSERT_TRUE(constructed); + EXPECT_TRUE(RSA_get0_e(constructed.get())); + EXPECT_TRUE(RSA_get0_d(constructed.get())); - uint8_t ciphertext[256]; + bssl::UniquePtr no_crt(RSA_new_private_key_no_crt( + RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()), + RSA_get0_d(parsed.get()))); + ASSERT_TRUE(no_crt); + EXPECT_TRUE(RSA_get0_e(no_crt.get())); + EXPECT_TRUE(RSA_get0_d(no_crt.get())); - // Test that PKCS#1 v1.5 encryption round-trips. - size_t ciphertext_len = 0; - ASSERT_TRUE(RSA_encrypt(key.get(), &ciphertext_len, ciphertext, - sizeof(ciphertext), kPlaintext, kPlaintextLen, - RSA_PKCS1_PADDING)); - EXPECT_EQ(RSA_size(key.get()), ciphertext_len); + bssl::UniquePtr no_e(RSA_new_private_key_no_e(RSA_get0_n(parsed.get()), + RSA_get0_d(parsed.get()))); + ASSERT_TRUE(no_e); + EXPECT_FALSE(RSA_get0_e(no_e.get())); + EXPECT_TRUE(RSA_get0_d(no_e.get())); - uint8_t plaintext[256]; - size_t plaintext_len = 0; - ASSERT_TRUE(RSA_decrypt(key.get(), &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, ciphertext_len, - RSA_PKCS1_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), Bytes(plaintext, plaintext_len)); + bssl::UniquePtr pub( + RSA_new_public_key(RSA_get0_n(parsed.get()), RSA_get0_e(parsed.get()))); + ASSERT_TRUE(pub); + EXPECT_TRUE(RSA_get0_e(pub.get())); + EXPECT_FALSE(RSA_get0_d(pub.get())); - // Test that OAEP encryption round-trips. - ciphertext_len = 0; - ASSERT_TRUE(RSA_encrypt(key.get(), &ciphertext_len, ciphertext, - sizeof(ciphertext), kPlaintext, kPlaintextLen, - RSA_PKCS1_OAEP_PADDING)); - EXPECT_EQ(RSA_size(key.get()), ciphertext_len); + for (RSA *key : + {parsed.get(), constructed.get(), no_crt.get(), no_e.get(), pub.get()}) { + EXPECT_TRUE(RSA_check_key(key)); - plaintext_len = 0; - ASSERT_TRUE(RSA_decrypt(key.get(), &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, ciphertext_len, - RSA_PKCS1_OAEP_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), Bytes(plaintext, plaintext_len)); + std::vector ciphertext(RSA_size(key)), plaintext(RSA_size(key)); + size_t ciphertext_len = 0, plaintext_len = 0; - // |oaep_ciphertext| should decrypt to |kPlaintext|. - plaintext_len = 0; - ASSERT_TRUE(RSA_decrypt(key.get(), &plaintext_len, plaintext, - sizeof(plaintext), param.oaep_ciphertext, - param.oaep_ciphertext_len, RSA_PKCS1_OAEP_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), Bytes(plaintext, plaintext_len)); + if (RSA_get0_e(key) != nullptr) { + // Test that PKCS#1 v1.5 encryption round-trips. + ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext.data(), + ciphertext.size(), kPlaintext, sizeof(kPlaintext), + RSA_PKCS1_PADDING)); + EXPECT_EQ(RSA_size(key), ciphertext_len); - // Try decrypting corrupted ciphertexts. - OPENSSL_memcpy(ciphertext, param.oaep_ciphertext, param.oaep_ciphertext_len); - for (size_t i = 0; i < param.oaep_ciphertext_len; i++) { - SCOPED_TRACE(i); - ciphertext[i] ^= 1; - EXPECT_FALSE(RSA_decrypt( - key.get(), &plaintext_len, plaintext, sizeof(plaintext), ciphertext, - param.oaep_ciphertext_len, RSA_PKCS1_OAEP_PADDING)); - ERR_clear_error(); - ciphertext[i] ^= 1; - } + ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext_len, RSA_PKCS1_PADDING)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); - // Test truncated ciphertexts. - for (size_t len = 0; len < param.oaep_ciphertext_len; len++) { - SCOPED_TRACE(len); - EXPECT_FALSE(RSA_decrypt(key.get(), &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, len, - RSA_PKCS1_OAEP_PADDING)); - ERR_clear_error(); + // Test that OAEP encryption round-trips. + ciphertext_len = 0; + ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext.data(), + ciphertext.size(), kPlaintext, sizeof(kPlaintext), + RSA_PKCS1_OAEP_PADDING)); + EXPECT_EQ(RSA_size(key), ciphertext_len); + + plaintext_len = 0; + ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext_len, RSA_PKCS1_OAEP_PADDING)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); + } + + if (RSA_get0_d(key) != nullptr) { + // |oaep_ciphertext| should decrypt to |kPlaintext|. + plaintext_len = 0; + ASSERT_TRUE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), param.oaep_ciphertext.data(), + param.oaep_ciphertext.size(), + RSA_PKCS1_OAEP_PADDING)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); + + // Try decrypting corrupted ciphertexts. + ciphertext.assign( + param.oaep_ciphertext.data(), + param.oaep_ciphertext.data() + param.oaep_ciphertext.size()); + for (size_t i = 0; i < ciphertext.size(); i++) { + SCOPED_TRACE(i); + ciphertext[i] ^= 1; + EXPECT_FALSE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); + ERR_clear_error(); + ciphertext[i] ^= 1; + } + + // Test truncated ciphertexts. + for (size_t len = 0; len < ciphertext.size(); len++) { + SCOPED_TRACE(len); + EXPECT_FALSE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), len, + RSA_PKCS1_OAEP_PADDING)); + ERR_clear_error(); + } + } } } @@ -465,29 +575,28 @@ INSTANTIATE_TEST_SUITE_P(All, RSAEncryptTest, testing::ValuesIn(kRSAEncryptParams)); TEST(RSATest, TestDecrypt) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); ASSERT_TRUE(rsa); EXPECT_TRUE(RSA_check_key(rsa.get())); - uint8_t out[256]; + std::vector out(RSA_size(rsa.get())); size_t out_len; - ASSERT_TRUE(RSA_decrypt( - rsa.get(), &out_len, out, sizeof(out), kTwoPrimeEncryptedMessage, - sizeof(kTwoPrimeEncryptedMessage), RSA_PKCS1_PADDING)); - EXPECT_EQ(Bytes("hello world"), Bytes(out, out_len)); + ASSERT_TRUE(RSA_decrypt(rsa.get(), &out_len, out.data(), out.size(), + kPKCS1Ciphertext2, sizeof(kPKCS1Ciphertext2), + RSA_PKCS1_PADDING)); + out.resize(out_len); + EXPECT_EQ(Bytes("hello world"), Bytes(out)); } TEST(RSATest, CheckFIPS) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kFIPSKey, sizeof(kFIPSKey) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); EXPECT_TRUE(RSA_check_fips(rsa.get())); // Check that RSA_check_fips works on a public key. bssl::UniquePtr pub( - RSA_public_key_from_bytes(kFIPSPublicKey, sizeof(kFIPSPublicKey) - 1)); + RSA_public_key_from_bytes(kKey1Public, sizeof(kKey1Public))); ASSERT_TRUE(pub); EXPECT_TRUE(RSA_check_fips(pub.get())); } @@ -513,6 +622,7 @@ TEST(RSATest, GenerateFIPS) { SCOPED_TRACE(bits); rsa.reset(RSA_new()); + ASSERT_TRUE(rsa); ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), bits, nullptr)); EXPECT_EQ(bits, BN_num_bits(rsa->n)); } @@ -542,55 +652,9 @@ TEST(RSATest, BadKey) { EXPECT_FALSE(key); } -TEST(RSATest, OnlyDGiven) { - static const char kN[] = - "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd09ac42b2662" - "1cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e5808c659"; - static const char kE[] = "010001"; - static const char kD[] = - "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea316eaeca21a" - "73ac365e58713195f2ae9849348525ca855386b6d028e437a9495a01"; - - bssl::UniquePtr key(RSA_new()); - ASSERT_TRUE(key); - ASSERT_TRUE(BN_hex2bn(&key->n, kN)); - ASSERT_TRUE(BN_hex2bn(&key->e, kE)); - ASSERT_TRUE(BN_hex2bn(&key->d, kD)); - - // Keys with only n, e, and d are functional. - EXPECT_TRUE(RSA_check_key(key.get())); - - const uint8_t kDummyHash[32] = {0}; - uint8_t buf[64]; - unsigned buf_len = sizeof(buf); - ASSERT_LE(RSA_size(key.get()), sizeof(buf)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - &buf_len, key.get())); - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - buf_len, key.get())); - - // Keys without the public exponent must continue to work when blinding is - // disabled to support Java's RSAPrivateKeySpec API. See - // https://bugs.chromium.org/p/boringssl/issues/detail?id=12. - bssl::UniquePtr key2(RSA_new()); - ASSERT_TRUE(key2); - ASSERT_TRUE(BN_hex2bn(&key2->n, kN)); - ASSERT_TRUE(BN_hex2bn(&key2->d, kD)); - key2->flags |= RSA_FLAG_NO_BLINDING; - - ASSERT_LE(RSA_size(key2.get()), sizeof(buf)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - &buf_len, key2.get())); - - // Verify the signature with |key|. |key2| has no public exponent. - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - buf_len, key.get())); -} - TEST(RSATest, ASN1) { // Test that private keys may be decoded. - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); // Test that the serialization round-trips. @@ -598,7 +662,7 @@ TEST(RSATest, ASN1) { size_t der_len; ASSERT_TRUE(RSA_private_key_to_bytes(&der, &der_len, rsa.get())); bssl::UniquePtr delete_der(der); - EXPECT_EQ(Bytes(kKey1, sizeof(kKey1) - 1), Bytes(der, der_len)); + EXPECT_EQ(Bytes(kKey1), Bytes(der, der_len)); // Test that serializing public keys works. ASSERT_TRUE(RSA_public_key_to_bytes(&der, &der_len, rsa.get())); @@ -682,36 +746,18 @@ TEST(RSATest, RoundKeyLengths) { TEST(RSATest, BlindingDisabled) { bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1)); + RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); ASSERT_TRUE(rsa); rsa->flags |= RSA_FLAG_NO_BLINDING; - uint8_t sig[256]; - ASSERT_GE(sizeof(sig), RSA_size(rsa.get())); - + std::vector sig(RSA_size(rsa.get())); static const uint8_t kZeros[32] = {0}; unsigned sig_len; - ASSERT_TRUE( - RSA_sign(NID_sha256, kZeros, sizeof(kZeros), sig, &sig_len, rsa.get())); - EXPECT_TRUE( - RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig, sig_len, rsa.get())); -} - -// Test that decrypting with a public key fails gracefully rather than crashing. -TEST(RSATest, DecryptPublic) { - bssl::UniquePtr pub( - RSA_public_key_from_bytes(kFIPSPublicKey, sizeof(kFIPSPublicKey) - 1)); - ASSERT_TRUE(pub); - ASSERT_EQ(1024u / 8u, RSA_size(pub.get())); - - size_t len; - uint8_t in[1024 / 8] = {0}, out[1024 / 8]; - EXPECT_FALSE(RSA_decrypt(pub.get(), &len, out, sizeof(out), in, sizeof(in), - RSA_PKCS1_PADDING)); - uint32_t err = ERR_get_error(); - EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); - EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + ASSERT_TRUE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), sig.data(), &sig_len, + rsa.get())); + EXPECT_TRUE(RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig.data(), + sig_len, rsa.get())); } TEST(RSATest, CheckKey) { @@ -937,7 +983,7 @@ TEST(RSATest, KeygenFail) { EXPECT_FALSE(rsa->d_fixed); EXPECT_FALSE(rsa->dmp1_fixed); EXPECT_FALSE(rsa->dmq1_fixed); - EXPECT_FALSE(rsa->inv_small_mod_large_mont); + EXPECT_FALSE(rsa->iqmp_mont); EXPECT_FALSE(rsa->private_key_frozen); // Failed key generations leave the previous contents alone. @@ -1021,6 +1067,357 @@ TEST(RSATest, KeygenInternalRetry) { EXPECT_TRUE(RSA_generate_key_ex(rsa.get(), 2048, e.get(), &cb)); } +// Test that, after a key has been used, it can still be modified into another +// key. +TEST(RSATest, OverwriteKey) { + // Make a key and perform public and private key operations with it, so that + // all derived values are filled in. + bssl::UniquePtr key1(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + ASSERT_TRUE(key1); + + ASSERT_TRUE(RSA_check_key(key1.get())); + size_t len; + std::vector ciphertext(RSA_size(key1.get())); + ASSERT_TRUE(RSA_encrypt(key1.get(), &len, ciphertext.data(), + ciphertext.size(), kPlaintext, sizeof(kPlaintext), + RSA_PKCS1_OAEP_PADDING)); + ciphertext.resize(len); + + std::vector plaintext(RSA_size(key1.get())); + ASSERT_TRUE(RSA_decrypt(key1.get(), &len, plaintext.data(), + plaintext.size(), ciphertext.data(), ciphertext.size(), + RSA_PKCS1_OAEP_PADDING)); + plaintext.resize(len); + EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext)); + + // Overwrite |key1| with the contents of |key2|. + bssl::UniquePtr key2(RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); + ASSERT_TRUE(key2); + + auto copy_rsa_fields = [](RSA *dst, const RSA *src) { + bssl::UniquePtr n(BN_dup(RSA_get0_n(src))); + ASSERT_TRUE(n); + bssl::UniquePtr e(BN_dup(RSA_get0_e(src))); + ASSERT_TRUE(e); + bssl::UniquePtr d(BN_dup(RSA_get0_d(src))); + ASSERT_TRUE(d); + bssl::UniquePtr p(BN_dup(RSA_get0_p(src))); + ASSERT_TRUE(p); + bssl::UniquePtr q(BN_dup(RSA_get0_q(src))); + ASSERT_TRUE(q); + bssl::UniquePtr dmp1(BN_dup(RSA_get0_dmp1(src))); + ASSERT_TRUE(dmp1); + bssl::UniquePtr dmq1(BN_dup(RSA_get0_dmq1(src))); + ASSERT_TRUE(dmq1); + bssl::UniquePtr iqmp(BN_dup(RSA_get0_iqmp(src))); + ASSERT_TRUE(iqmp); + ASSERT_TRUE(RSA_set0_key(dst, n.release(), e.release(), d.release())); + ASSERT_TRUE(RSA_set0_factors(dst, p.release(), q.release())); + ASSERT_TRUE(RSA_set0_crt_params(dst, dmp1.release(), dmq1.release(), + iqmp.release())); + }; + ASSERT_NO_FATAL_FAILURE(copy_rsa_fields(key1.get(), key2.get())); + + auto check_rsa_compatible = [&](RSA *enc, RSA *dec) { + ciphertext.resize(RSA_size(enc)); + ASSERT_TRUE(RSA_encrypt(enc, &len, ciphertext.data(), ciphertext.size(), + kPlaintext, sizeof(kPlaintext), + RSA_PKCS1_OAEP_PADDING)); + ciphertext.resize(len); + + plaintext.resize(RSA_size(dec)); + ASSERT_TRUE(RSA_decrypt(dec, &len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); + plaintext.resize(len); + EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext)); + }; + + ASSERT_NO_FATAL_FAILURE( + check_rsa_compatible(/*enc=*/key1.get(), /*dec=*/key2.get())); + ASSERT_NO_FATAL_FAILURE( + check_rsa_compatible(/*enc=*/key2.get(), /*dec=*/key1.get())); + + // If we generate a new key on top of |key1|, it should be usable and + // self-consistent. We test this by making a new key with the same parameters + // and checking they behave the same. + ASSERT_TRUE( + RSA_generate_key_ex(key1.get(), 1024, RSA_get0_e(key2.get()), nullptr)); + EXPECT_NE(0, BN_cmp(RSA_get0_n(key1.get()), RSA_get0_n(key2.get()))); + + key2.reset(RSA_new()); + ASSERT_TRUE(key2); + ASSERT_NO_FATAL_FAILURE(copy_rsa_fields(key2.get(), key1.get())); + ASSERT_NO_FATAL_FAILURE( + check_rsa_compatible(/*enc=*/key1.get(), /*dec=*/key2.get())); + ASSERT_NO_FATAL_FAILURE( + check_rsa_compatible(/*enc=*/key2.get(), /*dec=*/key1.get())); +} + +// Test that RSA keys do not support operations will cleanly fail them. +TEST(RSATest, MissingParameters) { + bssl::UniquePtr sample(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + ASSERT_TRUE(sample); + + // Make a sample signature. + const uint8_t kZeros[32] = {0}; + std::vector sig(RSA_size(sample.get())); + unsigned len_u; + ASSERT_TRUE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), sig.data(), &len_u, + sample.get())); + sig.resize(len_u); + + // A public key cannot perform private key operations. + bssl::UniquePtr rsa( + RSA_new_public_key(RSA_get0_n(sample.get()), RSA_get0_e(sample.get()))); + ASSERT_TRUE(rsa); + + std::vector out(RSA_size(sample.get())); + EXPECT_FALSE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), out.data(), &len_u, + rsa.get())); + uint32_t err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + + size_t len; + EXPECT_FALSE(RSA_decrypt(rsa.get(), &len, out.data(), out.size(), + kOAEPCiphertext1, sizeof(kOAEPCiphertext1), + RSA_PKCS1_OAEP_PADDING)); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + + // A private key without e cannot perform public key operations. + rsa.reset(RSA_new_private_key_no_e(RSA_get0_n(sample.get()), + RSA_get0_d(sample.get()))); + ASSERT_TRUE(rsa); + + EXPECT_FALSE(RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig.data(), + sig.size(), rsa.get())); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + + EXPECT_FALSE(RSA_encrypt(rsa.get(), &len, out.data(), out.size(), kPlaintext, + sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING)); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); +} + +TEST(RSATest, Negative) { + auto dup_neg = [](const BIGNUM *bn) -> bssl::UniquePtr { + bssl::UniquePtr ret(BN_dup(bn)); + if (!ret) { + return nullptr; + } + BN_set_negative(ret.get(), 1); + return ret; + }; + + bssl::UniquePtr key( + RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + ASSERT_TRUE(key); + const BIGNUM *n = RSA_get0_n(key.get()); + bssl::UniquePtr neg_n = dup_neg(n); + ASSERT_TRUE(neg_n); + const BIGNUM *e = RSA_get0_e(key.get()); + bssl::UniquePtr neg_e = dup_neg(e); + ASSERT_TRUE(neg_e); + const BIGNUM *d = RSA_get0_d(key.get()); + bssl::UniquePtr neg_d = dup_neg(d); + ASSERT_TRUE(neg_d); + const BIGNUM *p = RSA_get0_p(key.get()); + bssl::UniquePtr neg_p = dup_neg(p); + ASSERT_TRUE(neg_p); + const BIGNUM *q = RSA_get0_q(key.get()); + bssl::UniquePtr neg_q = dup_neg(q); + ASSERT_TRUE(neg_q); + const BIGNUM *dmp1 = RSA_get0_dmp1(key.get()); + bssl::UniquePtr neg_dmp1 = dup_neg(dmp1); + ASSERT_TRUE(neg_dmp1); + const BIGNUM *dmq1 = RSA_get0_dmq1(key.get()); + bssl::UniquePtr neg_dmq1 = dup_neg(dmq1); + ASSERT_TRUE(neg_dmq1); + const BIGNUM *iqmp = RSA_get0_iqmp(key.get()); + bssl::UniquePtr neg_iqmp = dup_neg(iqmp); + ASSERT_TRUE(neg_iqmp); + + EXPECT_FALSE(RSA_new_public_key(neg_n.get(), e)); + EXPECT_FALSE(RSA_new_public_key(n, neg_e.get())); + EXPECT_FALSE(RSA_new_private_key(neg_n.get(), e, d, p, q, dmp1, dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, neg_e.get(), d, p, q, dmp1, dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, neg_d.get(), p, q, dmp1, dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, d, neg_p.get(), q, dmp1, dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, d, p, neg_q.get(), dmp1, dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, d, p, q, neg_dmp1.get(), dmq1, iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, d, p, q, dmp1, neg_dmq1.get(), iqmp)); + EXPECT_FALSE(RSA_new_private_key(n, e, d, p, q, dmp1, dmq1, neg_iqmp.get())); +} + +TEST(RSATest, LargeE) { + // Test an RSA key with large e by swapping d and e in kKey1. + // Since e is small, e mod (p-1) and e mod (q-1) will simply be e. + bssl::UniquePtr key(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); + ASSERT_TRUE(key); + const BIGNUM *n = RSA_get0_n(key.get()); + const BIGNUM *e = RSA_get0_e(key.get()); + const BIGNUM *d = RSA_get0_d(key.get()); + const BIGNUM *p = RSA_get0_p(key.get()); + const BIGNUM *q = RSA_get0_q(key.get()); + const BIGNUM *iqmp = RSA_get0_iqmp(key.get()); + + // By default, the large exponent is not allowed as e. + bssl::UniquePtr pub(RSA_new_public_key(n, /*e=*/d)); + EXPECT_FALSE(pub); + bssl::UniquePtr priv(RSA_new_private_key(n, /*e=*/d, /*d=*/e, p, q, + /*dmp1=*/e, /*dmq1=*/e, iqmp)); + EXPECT_FALSE(priv); + + // Constructing such a key piecemeal also would not work. This was only + // possible with private APIs, so when |RSA| is opaque, this case will be + // impossible. + priv.reset(RSA_new()); + ASSERT_TRUE(priv); + priv->n = BN_dup(n); + ASSERT_TRUE(priv->n); + priv->e = BN_dup(d); // Swapped + ASSERT_TRUE(priv->e); + priv->d = BN_dup(e); + ASSERT_TRUE(priv->d); + + static const uint8_t kDigest[32] = {0}; + std::vector sig(RSA_size(priv.get())); + size_t len; + EXPECT_FALSE(RSA_sign_pss_mgf1(priv.get(), &len, sig.data(), sig.size(), + kDigest, sizeof(kDigest), EVP_sha256(), + EVP_sha256(), /*salt_len=*/32)); + + // But the "large e" APIs tolerate it. + pub.reset(RSA_new_public_key_large_e(n, /*e=*/d)); + ASSERT_TRUE(pub); + priv.reset(RSA_new_private_key_large_e(n, /*e=*/d, /*d=*/e, p, q, /*dmp1=*/e, + /*dmq1=*/e, iqmp)); + ASSERT_TRUE(priv); + + // Test that operations work correctly. + sig.resize(RSA_size(priv.get())); + ASSERT_TRUE(RSA_sign_pss_mgf1(priv.get(), &len, sig.data(), sig.size(), + kDigest, sizeof(kDigest), EVP_sha256(), + EVP_sha256(), /*salt_len=*/32)); + sig.resize(len); + + EXPECT_TRUE(RSA_verify_pss_mgf1(pub.get(), kDigest, sizeof(kDigest), + EVP_sha256(), EVP_sha256(), /*salt_len=*/32, + sig.data(), sig.size())); + + // e = 1 is still invalid. + EXPECT_FALSE(RSA_new_public_key_large_e(n, BN_value_one())); + + // e must still be odd. + bssl::UniquePtr bad_e(BN_dup(d)); + ASSERT_TRUE(bad_e); + ASSERT_TRUE(BN_add_word(bad_e.get(), 1)); + EXPECT_FALSE(RSA_new_public_key_large_e(n, bad_e.get())); + + // e must still be bounded by n. + bad_e.reset(BN_dup(n)); + ASSERT_TRUE(bad_e); + ASSERT_TRUE(BN_add_word(bad_e.get(), 2)); // Preserve parity. + EXPECT_FALSE(RSA_new_public_key_large_e(n, bad_e.get())); +} + +// Test minimum key limits on RSA keys. Currently, we require a minimum of +// 512-bit RSA. +// +// TODO(crbug.com/boringssl/607): Raise this limit. 512-bit RSA was factored in +// 1999. +TEST(RSATest, SmallKey) { + static const uint8_t kRSA511Private[] = { + 0x30, 0x82, 0x01, 0x39, 0x02, 0x01, 0x00, 0x02, 0x40, 0x56, 0xc1, 0x3d, + 0xb3, 0x4f, 0xe4, 0xe9, 0x2f, 0x29, 0x8a, 0xd3, 0xe2, 0xfe, 0xb3, 0x3b, + 0x88, 0x02, 0x8b, 0xdd, 0x44, 0xb5, 0x41, 0x4b, 0x43, 0x97, 0x93, 0x75, + 0x78, 0x4b, 0x10, 0x30, 0x88, 0xce, 0xd2, 0x32, 0xe3, 0x9e, 0xda, 0x68, + 0xc9, 0xc3, 0xcd, 0xa1, 0xde, 0xbc, 0x4a, 0xeb, 0x37, 0x60, 0xd2, 0x82, + 0x2f, 0x5d, 0x21, 0x3b, 0x88, 0x0e, 0x12, 0x44, 0x4d, 0x5d, 0x44, 0xc1, + 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x08, 0xe5, 0xf5, 0x30, + 0x29, 0x27, 0xaf, 0x8b, 0x38, 0xd5, 0x96, 0x7a, 0x17, 0xe9, 0xc6, 0x57, + 0x62, 0xfb, 0x79, 0x8c, 0x8c, 0x92, 0xcf, 0xe7, 0x74, 0xea, 0x99, 0x07, + 0xe7, 0x9b, 0x17, 0x7f, 0x30, 0x9f, 0x86, 0x55, 0x15, 0x8d, 0xe6, 0xa8, + 0x0d, 0x7b, 0x42, 0x41, 0x27, 0x18, 0x29, 0x55, 0xb1, 0x08, 0x07, 0x2a, + 0x4e, 0x67, 0x19, 0x9c, 0xe3, 0xe4, 0x84, 0xd6, 0x82, 0x62, 0xd4, 0x81, + 0x02, 0x21, 0x00, 0xcd, 0x5a, 0x9b, 0x23, 0x3d, 0xb5, 0x9c, 0x56, 0xbc, + 0xc5, 0x56, 0xcf, 0x77, 0x58, 0xc0, 0x62, 0x72, 0xa0, 0x85, 0x77, 0xf4, + 0xc3, 0xf8, 0x47, 0x6d, 0xc0, 0x8f, 0x18, 0x77, 0xee, 0xf1, 0xad, 0x02, + 0x20, 0x6c, 0x26, 0xaa, 0x8a, 0xaf, 0x7b, 0x9f, 0x35, 0x19, 0x08, 0xc2, + 0xa0, 0x9f, 0x4e, 0x9e, 0x62, 0x48, 0xb1, 0x7c, 0x0e, 0x68, 0x63, 0x0d, + 0x05, 0x76, 0x73, 0x0a, 0xa0, 0xb3, 0xed, 0x6d, 0xb1, 0x02, 0x21, 0x00, + 0xc2, 0x26, 0x1c, 0xb0, 0xa7, 0xe2, 0x31, 0x4a, 0x4c, 0x34, 0xe2, 0xcb, + 0x49, 0x51, 0xce, 0xaa, 0x05, 0x27, 0xc0, 0xa8, 0x55, 0xf0, 0x85, 0xa6, + 0xba, 0x9c, 0x28, 0x6e, 0x00, 0xce, 0x17, 0x0d, 0x02, 0x20, 0x65, 0x51, + 0xb0, 0x11, 0xaf, 0x26, 0xbc, 0x57, 0x4d, 0x35, 0xb4, 0xc8, 0x2f, 0x96, + 0xc2, 0xb0, 0xc6, 0xf3, 0x67, 0x8a, 0x43, 0xe7, 0x0f, 0xaa, 0xdf, 0x76, + 0x15, 0x2d, 0xca, 0x82, 0x93, 0x71, 0x02, 0x21, 0x00, 0x9e, 0x89, 0x74, + 0x15, 0x7e, 0x73, 0x43, 0xa0, 0x1e, 0xa9, 0xa5, 0x9f, 0xad, 0xf1, 0xa0, + 0xfa, 0x13, 0x86, 0x10, 0x3f, 0xb0, 0xba, 0x3f, 0x45, 0x87, 0x13, 0x02, + 0x86, 0xa4, 0xa4, 0x31, 0x92}; + static const uint8_t kRSA511Public[] = { + 0x30, 0x47, 0x02, 0x40, 0x56, 0xc1, 0x3d, 0xb3, 0x4f, 0xe4, 0xe9, + 0x2f, 0x29, 0x8a, 0xd3, 0xe2, 0xfe, 0xb3, 0x3b, 0x88, 0x02, 0x8b, + 0xdd, 0x44, 0xb5, 0x41, 0x4b, 0x43, 0x97, 0x93, 0x75, 0x78, 0x4b, + 0x10, 0x30, 0x88, 0xce, 0xd2, 0x32, 0xe3, 0x9e, 0xda, 0x68, 0xc9, + 0xc3, 0xcd, 0xa1, 0xde, 0xbc, 0x4a, 0xeb, 0x37, 0x60, 0xd2, 0x82, + 0x2f, 0x5d, 0x21, 0x3b, 0x88, 0x0e, 0x12, 0x44, 0x4d, 0x5d, 0x44, + 0xc1, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01}; + static const uint8_t kRSA512Private[] = { + 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xa5, 0x44, + 0x8f, 0x3d, 0xa2, 0x0b, 0x20, 0xc6, 0xac, 0x10, 0xc1, 0x27, 0x11, 0xf0, + 0x43, 0x5d, 0x05, 0xb7, 0x0f, 0x80, 0x3b, 0x9b, 0x85, 0xf1, 0x7a, 0x0e, + 0xbd, 0x72, 0xed, 0x8a, 0xdc, 0xa1, 0xaa, 0xd4, 0x53, 0xcb, 0x65, 0x78, + 0x4b, 0x30, 0x6b, 0x52, 0x51, 0xee, 0xcd, 0x2f, 0x90, 0x7b, 0xd1, 0x9c, + 0xe9, 0x79, 0x98, 0x58, 0xe3, 0x47, 0x35, 0xa7, 0xcd, 0x6a, 0x71, 0x38, + 0xb5, 0x0d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0x94, 0x24, + 0x82, 0xa9, 0xe2, 0xa9, 0x4a, 0xf6, 0x0b, 0xa2, 0xf1, 0x21, 0x0e, 0x89, + 0x6a, 0x38, 0xe6, 0x38, 0x93, 0xe2, 0x84, 0x8c, 0x02, 0x62, 0xd4, 0xe0, + 0x85, 0x9d, 0x91, 0xa4, 0xd9, 0xe3, 0x77, 0x6c, 0x26, 0x85, 0xf6, 0x2e, + 0x0a, 0xe4, 0x18, 0x73, 0x06, 0x9a, 0xea, 0xde, 0x78, 0x65, 0xba, 0x7a, + 0xdb, 0xc0, 0x3b, 0xf7, 0x29, 0x1e, 0x43, 0xed, 0xaf, 0xf5, 0xaf, 0xa8, + 0xdf, 0x01, 0x02, 0x21, 0x00, 0xdb, 0x93, 0x05, 0x2d, 0xf3, 0xdf, 0xe4, + 0x31, 0xef, 0x50, 0xc7, 0x54, 0x0f, 0x08, 0x5d, 0x50, 0x42, 0xfa, 0xb9, + 0x20, 0x37, 0x98, 0xd3, 0xc0, 0x64, 0x2f, 0xb6, 0xe4, 0xb2, 0xfe, 0xe5, + 0x6d, 0x02, 0x21, 0x00, 0xc0, 0xaf, 0x3a, 0x1f, 0xd9, 0xba, 0x5a, 0x6a, + 0xc2, 0x80, 0x2e, 0x7b, 0x65, 0x3d, 0x8a, 0x76, 0xae, 0x4b, 0x5a, 0xff, + 0x7a, 0x9a, 0x5e, 0xc2, 0xfa, 0x07, 0xfb, 0x2d, 0x0c, 0x16, 0x6a, 0x21, + 0x02, 0x20, 0x06, 0xf3, 0xb9, 0xb7, 0x41, 0xc0, 0x75, 0xfe, 0x2a, 0xc0, + 0x98, 0xff, 0x0d, 0x56, 0xcb, 0x75, 0x8e, 0x19, 0x58, 0x21, 0x30, 0x01, + 0x73, 0xba, 0xe4, 0xb1, 0x2a, 0x0e, 0x45, 0xa8, 0x92, 0x65, 0x02, 0x20, + 0x25, 0xcd, 0xbb, 0x3f, 0xa8, 0x7e, 0x11, 0x63, 0x44, 0xc9, 0xd5, 0x54, + 0xcc, 0x66, 0x28, 0x96, 0x64, 0x57, 0xd0, 0x80, 0xb3, 0x53, 0x3a, 0x28, + 0x52, 0xd9, 0xe2, 0x03, 0xd2, 0x8d, 0x4b, 0x41, 0x02, 0x20, 0x09, 0x30, + 0xd9, 0xfd, 0xad, 0x31, 0x1a, 0x38, 0xb7, 0x71, 0x06, 0xed, 0x49, 0xa6, + 0xe2, 0xec, 0x42, 0xc2, 0x8e, 0xe9, 0xec, 0xf7, 0x3e, 0xb7, 0x4a, 0x5e, + 0x2e, 0xa2, 0x7a, 0x8d, 0xa4, 0x95}; + static const uint8_t kRSA512Public[] = { + 0x30, 0x48, 0x02, 0x41, 0x00, 0xa5, 0x44, 0x8f, 0x3d, 0xa2, 0x0b, + 0x20, 0xc6, 0xac, 0x10, 0xc1, 0x27, 0x11, 0xf0, 0x43, 0x5d, 0x05, + 0xb7, 0x0f, 0x80, 0x3b, 0x9b, 0x85, 0xf1, 0x7a, 0x0e, 0xbd, 0x72, + 0xed, 0x8a, 0xdc, 0xa1, 0xaa, 0xd4, 0x53, 0xcb, 0x65, 0x78, 0x4b, + 0x30, 0x6b, 0x52, 0x51, 0xee, 0xcd, 0x2f, 0x90, 0x7b, 0xd1, 0x9c, + 0xe9, 0x79, 0x98, 0x58, 0xe3, 0x47, 0x35, 0xa7, 0xcd, 0x6a, 0x71, + 0x38, 0xb5, 0x0d, 0x02, 0x03, 0x01, 0x00, 0x01}; + + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(kRSA511Public, sizeof(kRSA511Public))); + EXPECT_FALSE(rsa); + rsa.reset(RSA_private_key_from_bytes(kRSA511Private, sizeof(kRSA511Private))); + EXPECT_FALSE(rsa); + + rsa.reset(RSA_public_key_from_bytes(kRSA512Public, sizeof(kRSA512Public))); + EXPECT_TRUE(rsa); + rsa.reset(RSA_private_key_from_bytes(kRSA512Private, sizeof(kRSA512Private))); + EXPECT_TRUE(rsa); +} + #if !defined(BORINGSSL_SHARED_LIBRARY) TEST(RSATest, SqrtTwo) { bssl::UniquePtr sqrt(BN_new()), pow2(BN_new()); @@ -1054,15 +1451,15 @@ TEST(RSATest, SqrtTwo) { #if defined(OPENSSL_THREADS) TEST(RSATest, Threads) { bssl::UniquePtr rsa_template( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa_template); const uint8_t kDummyHash[32] = {0}; - uint8_t sig[256]; - unsigned sig_len = sizeof(sig); - ASSERT_LE(RSA_size(rsa_template.get()), sizeof(sig)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, + std::vector sig(RSA_size(rsa_template.get())); + unsigned sig_len; + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig.data(), &sig_len, rsa_template.get())); + sig.resize(sig_len); // RSA keys may be assembled piece-meal and then used in parallel between // threads, which requires internal locking to create some derived properties. @@ -1093,17 +1490,17 @@ TEST(RSATest, Threads) { EXPECT_EQ(0, BN_cmp(d, rsa_template->d)); }; auto sign = [&] { - uint8_t sig2[256]; - unsigned sig2_len = sizeof(sig2); - ASSERT_LE(RSA_size(rsa.get()), sizeof(sig2)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig2, - &sig2_len, rsa.get())); + std::vector sig2(RSA_size(rsa.get())); + unsigned sig2_len; + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig2.data(), &sig2_len, rsa.get())); + sig2.resize(sig2_len); // RSASSA-PKCS1-v1_5 is deterministic. - EXPECT_EQ(Bytes(sig, sig_len), Bytes(sig2, sig2_len)); + EXPECT_EQ(Bytes(sig), Bytes(sig2)); }; auto verify = [&] { - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, - sig_len, rsa.get())); + EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig.data(), sig.size(), rsa.get())); }; std::vector threads; @@ -1125,11 +1522,12 @@ TEST(RSATest, Threads) { // platforms when running tests standalone via all_tests.go. // // Additionally, even when running disabled tests standalone, limit this to -// x86_64. On other platforms, this test hits resource limits or is too slow. -#if defined(OPENSSL_X86_64) +// x86_64. On other platforms, this test hits resource limits or is too slow. We +// also disable on FreeBSD. See https://crbug.com/boringssl/603. +#if defined(OPENSSL_TSAN) || \ + (defined(OPENSSL_X86_64) && !defined(OPENSSL_FREEBSD)) TEST(RSATest, DISABLED_BlindingCacheConcurrency) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); #if defined(OPENSSL_TSAN) @@ -1142,13 +1540,11 @@ TEST(RSATest, DISABLED_BlindingCacheConcurrency) { const uint8_t kDummyHash[32] = {0}; auto worker = [&] { - uint8_t sig[256]; - ASSERT_LE(RSA_size(rsa.get()), sizeof(sig)); - + std::vector sig(RSA_size(rsa.get())); for (size_t i = 0; i < kSignaturesPerThread; i++) { - unsigned sig_len = sizeof(sig); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, - &sig_len, rsa.get())); + unsigned sig_len = sig.size(); + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig.data(), &sig_len, rsa.get())); } }; @@ -1161,6 +1557,6 @@ TEST(RSATest, DISABLED_BlindingCacheConcurrency) { thread.join(); } } -#endif // X86_64 +#endif // TSAN || (X86_64 && !FREEBSD) #endif // THREADS diff --git a/third_party/boringssl/kit/src/crypto/siphash/siphash.c b/third_party/boringssl/kit/src/crypto/siphash/siphash.c index bb9a0c15..0921eac2 100644 --- a/third_party/boringssl/kit/src/crypto/siphash/siphash.c +++ b/third_party/boringssl/kit/src/crypto/siphash/siphash.c @@ -48,8 +48,7 @@ uint64_t SIPHASH_24(const uint64_t key[2], const uint8_t *input, v[3] = key[1] ^ UINT64_C(0x7465646279746573); while (input_len >= sizeof(uint64_t)) { - uint64_t m; - memcpy(&m, input, sizeof(m)); + uint64_t m = CRYPTO_load_u64_le(input); v[3] ^= m; siphash_round(v); siphash_round(v); @@ -59,18 +58,16 @@ uint64_t SIPHASH_24(const uint64_t key[2], const uint8_t *input, input_len -= sizeof(uint64_t); } - union { - uint8_t bytes[8]; - uint64_t word; - } last_block; - last_block.word = 0; - OPENSSL_memcpy(last_block.bytes, input, input_len); - last_block.bytes[7] = orig_input_len & 0xff; + uint8_t last_block[8]; + OPENSSL_memset(last_block, 0, sizeof(last_block)); + OPENSSL_memcpy(last_block, input, input_len); + last_block[7] = orig_input_len & 0xff; - v[3] ^= last_block.word; + uint64_t last_block_word = CRYPTO_load_u64_le(last_block); + v[3] ^= last_block_word; siphash_round(v); siphash_round(v); - v[0] ^= last_block.word; + v[0] ^= last_block_word; v[2] ^= 0xff; siphash_round(v); diff --git a/third_party/boringssl/kit/src/crypto/siphash/siphash_test.cc b/third_party/boringssl/kit/src/crypto/siphash/siphash_test.cc index 6d8f9e7a..6407e0da 100644 --- a/third_party/boringssl/kit/src/crypto/siphash/siphash_test.cc +++ b/third_party/boringssl/kit/src/crypto/siphash/siphash_test.cc @@ -23,14 +23,12 @@ TEST(SipHash, Basic) { // This is the example from appendix A of the SipHash paper. - union { - uint8_t bytes[16]; - uint64_t words[2]; - } key; - + uint8_t key_bytes[16]; for (unsigned i = 0; i < 16; i++) { - key.bytes[i] = i; + key_bytes[i] = i; } + uint64_t key[2]; + memcpy(key, key_bytes, sizeof(key)); uint8_t input[15]; for (unsigned i = 0; i < sizeof(input); i++) { @@ -38,7 +36,7 @@ TEST(SipHash, Basic) { } EXPECT_EQ(UINT64_C(0xa129ca6149be45e5), - SIPHASH_24(key.words, input, sizeof(input))); + SIPHASH_24(key, input, sizeof(input))); } TEST(SipHash, Vectors) { diff --git a/third_party/boringssl/kit/src/crypto/stack/stack.c b/third_party/boringssl/kit/src/crypto/stack/stack.c index 6da6e3b2..6b4f8bc7 100644 --- a/third_party/boringssl/kit/src/crypto/stack/stack.c +++ b/third_party/boringssl/kit/src/crypto/stack/stack.c @@ -57,22 +57,38 @@ #include #include +#include +#include #include #include "../internal.h" +struct stack_st { + // num contains the number of valid pointers in |data|. + size_t num; + void **data; + // sorted is non-zero if the values pointed to by |data| are in ascending + // order, based on |comp|. + int sorted; + // num_alloc contains the number of pointers allocated in the buffer pointed + // to by |data|, which may be larger than |num|. + size_t num_alloc; + // comp is an optional comparison function. + OPENSSL_sk_cmp_func comp; +}; + // kMinSize is the number of pointers that will be initially allocated in a new // stack. static const size_t kMinSize = 4; -_STACK *sk_new(stack_cmp_func comp) { - _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); +OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp) { + OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK)); if (ret == NULL) { return NULL; } - OPENSSL_memset(ret, 0, sizeof(_STACK)); + OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK)); ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize); if (ret->data == NULL) { @@ -91,16 +107,16 @@ err: return NULL; } -_STACK *sk_new_null(void) { return sk_new(NULL); } +OPENSSL_STACK *OPENSSL_sk_new_null(void) { return OPENSSL_sk_new(NULL); } -size_t sk_num(const _STACK *sk) { +size_t OPENSSL_sk_num(const OPENSSL_STACK *sk) { if (sk == NULL) { return 0; } return sk->num; } -void sk_zero(_STACK *sk) { +void OPENSSL_sk_zero(OPENSSL_STACK *sk) { if (sk == NULL || sk->num == 0) { return; } @@ -109,21 +125,21 @@ void sk_zero(_STACK *sk) { sk->sorted = 0; } -void *sk_value(const _STACK *sk, size_t i) { +void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i) { if (!sk || i >= sk->num) { return NULL; } return sk->data[i]; } -void *sk_set(_STACK *sk, size_t i, void *value) { +void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *value) { if (!sk || i >= sk->num) { return NULL; } return sk->data[i] = value; } -void sk_free(_STACK *sk) { +void OPENSSL_sk_free(OPENSSL_STACK *sk) { if (sk == NULL) { return; } @@ -131,8 +147,9 @@ void sk_free(_STACK *sk) { OPENSSL_free(sk); } -void sk_pop_free_ex(_STACK *sk, void (*call_free_func)(stack_free_func, void *), - stack_free_func free_func) { +void OPENSSL_sk_pop_free_ex(OPENSSL_STACK *sk, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { if (sk == NULL) { return; } @@ -142,25 +159,30 @@ void sk_pop_free_ex(_STACK *sk, void (*call_free_func)(stack_free_func, void *), call_free_func(free_func, sk->data[i]); } } - sk_free(sk); + OPENSSL_sk_free(sk); } -// Historically, |sk_pop_free| called the function as |stack_free_func| +// Historically, |sk_pop_free| called the function as |OPENSSL_sk_free_func| // directly. This is undefined in C. Some callers called |sk_pop_free| directly, // so we must maintain a compatibility version for now. -static void call_free_func_legacy(stack_free_func func, void *ptr) { +static void call_free_func_legacy(OPENSSL_sk_free_func func, void *ptr) { func(ptr); } -void sk_pop_free(_STACK *sk, stack_free_func free_func) { - sk_pop_free_ex(sk, call_free_func_legacy, free_func); +void sk_pop_free(OPENSSL_STACK *sk, OPENSSL_sk_free_func free_func) { + OPENSSL_sk_pop_free_ex(sk, call_free_func_legacy, free_func); } -size_t sk_insert(_STACK *sk, void *p, size_t where) { +size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, size_t where) { if (sk == NULL) { return 0; } + if (sk->num >= INT_MAX) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW); + return 0; + } + if (sk->num_alloc <= sk->num + 1) { // Attempt to double the size of the array. size_t new_alloc = sk->num_alloc << 1; @@ -201,7 +223,7 @@ size_t sk_insert(_STACK *sk, void *p, size_t where) { return sk->num; } -void *sk_delete(_STACK *sk, size_t where) { +void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where) { void *ret; if (!sk || where >= sk->num) { @@ -212,30 +234,46 @@ void *sk_delete(_STACK *sk, size_t where) { if (where != sk->num - 1) { OPENSSL_memmove(&sk->data[where], &sk->data[where + 1], - sizeof(void *) * (sk->num - where - 1)); + sizeof(void *) * (sk->num - where - 1)); } sk->num--; return ret; } -void *sk_delete_ptr(_STACK *sk, const void *p) { +void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p) { if (sk == NULL) { return NULL; } for (size_t i = 0; i < sk->num; i++) { if (sk->data[i] == p) { - return sk_delete(sk, i); + return OPENSSL_sk_delete(sk, i); } } return NULL; } -int sk_find(const _STACK *sk, size_t *out_index, const void *p, - int (*call_cmp_func)(stack_cmp_func, const void **, - const void **)) { +void OPENSSL_sk_delete_if(OPENSSL_STACK *sk, + OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data) { + if (sk == NULL) { + return; + } + + size_t new_num = 0; + for (size_t i = 0; i < sk->num; i++) { + if (!call_func(func, sk->data[i], data)) { + sk->data[new_num] = sk->data[i]; + new_num++; + } + } + sk->num = new_num; +} + +int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, const void *p, + OPENSSL_sk_call_cmp_func call_cmp_func) { if (sk == NULL) { return 0; } @@ -257,10 +295,9 @@ int sk_find(const _STACK *sk, size_t *out_index, const void *p, return 0; } - if (!sk_is_sorted(sk)) { + if (!OPENSSL_sk_is_sorted(sk)) { for (size_t i = 0; i < sk->num; i++) { - const void *elem = sk->data[i]; - if (call_cmp_func(sk->comp, &p, &elem) == 0) { + if (call_cmp_func(sk->comp, p, sk->data[i]) == 0) { if (out_index) { *out_index = i; } @@ -279,8 +316,7 @@ int sk_find(const _STACK *sk, size_t *out_index, const void *p, // Bias |mid| towards |lo|. See the |r == 0| case below. size_t mid = lo + (hi - lo - 1) / 2; assert(lo <= mid && mid < hi); - const void *elem = sk->data[mid]; - int r = call_cmp_func(sk->comp, &p, &elem); + int r = call_cmp_func(sk->comp, p, sk->data[mid]); if (r > 0) { lo = mid + 1; // |mid| is too low. } else if (r < 0) { @@ -305,38 +341,40 @@ int sk_find(const _STACK *sk, size_t *out_index, const void *p, return 0; // Not found. } -void *sk_shift(_STACK *sk) { +void *OPENSSL_sk_shift(OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } if (sk->num == 0) { return NULL; } - return sk_delete(sk, 0); + return OPENSSL_sk_delete(sk, 0); } -size_t sk_push(_STACK *sk, void *p) { return (sk_insert(sk, p, sk->num)); } +size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p) { + return OPENSSL_sk_insert(sk, p, sk->num); +} -void *sk_pop(_STACK *sk) { +void *OPENSSL_sk_pop(OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } if (sk->num == 0) { return NULL; } - return sk_delete(sk, sk->num - 1); + return OPENSSL_sk_delete(sk, sk->num - 1); } -_STACK *sk_dup(const _STACK *sk) { +OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) { if (sk == NULL) { return NULL; } - _STACK *ret = OPENSSL_malloc(sizeof(_STACK)); + OPENSSL_STACK *ret = OPENSSL_malloc(sizeof(OPENSSL_STACK)); if (ret == NULL) { return NULL; } - OPENSSL_memset(ret, 0, sizeof(_STACK)); + OPENSSL_memset(ret, 0, sizeof(OPENSSL_STACK)); ret->data = OPENSSL_malloc(sizeof(void *) * sk->num_alloc); if (ret->data == NULL) { @@ -351,41 +389,98 @@ _STACK *sk_dup(const _STACK *sk) { return ret; err: - sk_free(ret); + OPENSSL_sk_free(ret); return NULL; } -void sk_sort(_STACK *sk) { +static size_t parent_idx(size_t idx) { + assert(idx > 0); + return (idx - 1) / 2; +} + +static size_t left_idx(size_t idx) { + // The largest possible index is |PTRDIFF_MAX|, not |SIZE_MAX|. If + // |ptrdiff_t|, a signed type, is the same size as |size_t|, this cannot + // overflow. + assert(idx <= PTRDIFF_MAX); + static_assert(PTRDIFF_MAX <= (SIZE_MAX - 1) / 2, "2 * idx + 1 may oveflow"); + return 2 * idx + 1; +} + +// down_heap fixes the subtree rooted at |i|. |i|'s children must each satisfy +// the heap property. Only the first |num| elements of |sk| are considered. +static void down_heap(OPENSSL_STACK *sk, OPENSSL_sk_call_cmp_func call_cmp_func, + size_t i, size_t num) { + assert(i < num && num <= sk->num); + for (;;) { + size_t left = left_idx(i); + if (left >= num) { + break; // No left child. + } + + // Swap |i| with the largest of its children. + size_t next = i; + if (call_cmp_func(sk->comp, sk->data[next], sk->data[left]) < 0) { + next = left; + } + size_t right = left + 1; // Cannot overflow because |left < num|. + if (right < num && + call_cmp_func(sk->comp, sk->data[next], sk->data[right]) < 0) { + next = right; + } + + if (i == next) { + break; // |i| is already larger than its children. + } + + void *tmp = sk->data[i]; + sk->data[i] = sk->data[next]; + sk->data[next] = tmp; + i = next; + } +} + +void OPENSSL_sk_sort(OPENSSL_STACK *sk, + OPENSSL_sk_call_cmp_func call_cmp_func) { if (sk == NULL || sk->comp == NULL || sk->sorted) { return; } - // sk->comp is a function that takes pointers to pointers to elements, but - // qsort take a comparison function that just takes pointers to elements. - // However, since we're passing an array of pointers to qsort, we can just - // cast the comparison function and everything works. - // - // TODO(davidben): This is undefined behavior, but the call is in libc so, - // e.g., CFI does not notice. Unfortunately, |qsort| is missing a void* - // parameter in its callback and |qsort_s| / |qsort_r| are a mess of - // incompatibility. if (sk->num >= 2) { - int (*comp_func)(const void *, const void *) = - (int (*)(const void *, const void *))(sk->comp); - qsort(sk->data, sk->num, sizeof(void *), comp_func); + // |qsort| lacks a context parameter in the comparison function for us to + // pass in |call_cmp_func| and |sk->comp|. While we could cast |sk->comp| to + // the expected type, it is undefined behavior in C can trip sanitizers. + // |qsort_r| and |qsort_s| avoid this, but using them is impractical. See + // https://stackoverflow.com/a/39561369 + // + // Use our own heap sort instead. This is not performance-sensitive, so we + // optimize for simplicity and size. First, build a max-heap in place. + for (size_t i = parent_idx(sk->num - 1); i < sk->num; i--) { + down_heap(sk, call_cmp_func, i, sk->num); + } + + // Iteratively remove the maximum element to populate the result in reverse. + for (size_t i = sk->num - 1; i > 0; i--) { + void *tmp = sk->data[0]; + sk->data[0] = sk->data[i]; + sk->data[i] = tmp; + down_heap(sk, call_cmp_func, 0, i); + } } sk->sorted = 1; } -int sk_is_sorted(const _STACK *sk) { +int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk) { if (!sk) { return 1; } - return sk->sorted; + // Zero- and one-element lists are always sorted. + return sk->sorted || (sk->comp != NULL && sk->num < 2); } -stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp) { - stack_cmp_func old = sk->comp; +OPENSSL_sk_cmp_func OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_cmp_func comp) { + OPENSSL_sk_cmp_func old = sk->comp; if (sk->comp != comp) { sk->sorted = 0; @@ -395,12 +490,12 @@ stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp) { return old; } -_STACK *sk_deep_copy(const _STACK *sk, - void *(*call_copy_func)(stack_copy_func, void *), - stack_copy_func copy_func, - void (*call_free_func)(stack_free_func, void *), - stack_free_func free_func) { - _STACK *ret = sk_dup(sk); +OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, + OPENSSL_sk_call_copy_func call_copy_func, + OPENSSL_sk_copy_func copy_func, + OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func) { + OPENSSL_STACK *ret = OPENSSL_sk_dup(sk); if (ret == NULL) { return NULL; } @@ -416,7 +511,7 @@ _STACK *sk_deep_copy(const _STACK *sk, call_free_func(free_func, ret->data[j]); } } - sk_free(ret); + OPENSSL_sk_free(ret); return NULL; } } diff --git a/third_party/boringssl/kit/src/crypto/stack/stack_test.cc b/third_party/boringssl/kit/src/crypto/stack/stack_test.cc index 7be84ed0..228182b6 100644 --- a/third_party/boringssl/kit/src/crypto/stack/stack_test.cc +++ b/third_party/boringssl/kit/src/crypto/stack/stack_test.cc @@ -24,6 +24,7 @@ #include #include +#include // Define a custom stack type for testing. @@ -163,7 +164,7 @@ TEST(StackTest, Basic) { // Test both deep and shallow copies. bssl::UniquePtr copy(sk_TEST_INT_deep_copy( sk.get(), - [](TEST_INT *x) -> TEST_INT * { + [](const TEST_INT *x) -> TEST_INT * { return x == nullptr ? nullptr : TEST_INT_new(*x).release(); }, TEST_INT_free)); @@ -179,13 +180,12 @@ TEST(StackTest, Basic) { } // Deep copies may fail. This should clean up temporaries. - EXPECT_FALSE(sk_TEST_INT_deep_copy(sk.get(), - [](TEST_INT *x) -> TEST_INT * { - return x == nullptr || *x == 4 - ? nullptr - : TEST_INT_new(*x).release(); - }, - TEST_INT_free)); + EXPECT_FALSE(sk_TEST_INT_deep_copy( + sk.get(), + [](const TEST_INT *x) -> TEST_INT * { + return x == nullptr || *x == 4 ? nullptr : TEST_INT_new(*x).release(); + }, + TEST_INT_free)); // sk_TEST_INT_zero clears a stack, but does not free the elements. ShallowStack shallow2(sk_TEST_INT_dup(sk.get())); @@ -211,7 +211,7 @@ TEST(StackTest, BigStack) { static uint64_t g_compare_count = 0; -static int compare(const TEST_INT **a, const TEST_INT **b) { +static int compare(const TEST_INT *const *a, const TEST_INT *const *b) { g_compare_count++; if (**a < **b) { return -1; @@ -222,7 +222,7 @@ static int compare(const TEST_INT **a, const TEST_INT **b) { return 0; } -static int compare_reverse(const TEST_INT **a, const TEST_INT **b) { +static int compare_reverse(const TEST_INT *const *a, const TEST_INT *const *b) { return -compare(a, b); } @@ -274,7 +274,9 @@ TEST(StackTest, Sorted) { // Copies preserve comparison and sorted information. bssl::UniquePtr copy(sk_TEST_INT_deep_copy( sk.get(), - [](TEST_INT *x) -> TEST_INT * { return TEST_INT_new(*x).release(); }, + [](const TEST_INT *x) -> TEST_INT * { + return TEST_INT_new(*x).release(); + }, TEST_INT_free)); ASSERT_TRUE(copy); EXPECT_TRUE(sk_TEST_INT_is_sorted(copy.get())); @@ -290,6 +292,7 @@ TEST(StackTest, Sorted) { // Removing elements does not affect sortedness. TEST_INT_free(sk_TEST_INT_delete(sk.get(), 0)); EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); // Changing the comparison function invalidates sortedness. sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse); @@ -315,6 +318,7 @@ TEST(StackTest, Sorted) { // sk_*_find should return the first matching element in all cases. TEST(StackTest, FindFirst) { bssl::UniquePtr sk(sk_TEST_INT_new(compare)); + ASSERT_TRUE(sk); auto value = TEST_INT_new(1); ASSERT_TRUE(value); ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value))); @@ -392,3 +396,124 @@ TEST(StackTest, BinarySearch) { } } } + +TEST(StackTest, DeleteIf) { + bssl::UniquePtr sk(sk_TEST_INT_new(compare)); + ASSERT_TRUE(sk); + for (int v : {1, 9, 2, 8, 3, 7, 4, 6, 5}) { + auto obj = TEST_INT_new(v); + ASSERT_TRUE(obj); + ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(obj))); + } + + auto keep_only_multiples = [](TEST_INT *x, void *data) { + auto d = static_cast(data); + if (*x % *d == 0) { + return 0; + } + TEST_INT_free(x); + return 1; + }; + + int d = 2; + sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d); + ExpectStackEquals(sk.get(), {2, 8, 4, 6}); + + EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); + sk_TEST_INT_sort(sk.get()); + ExpectStackEquals(sk.get(), {2, 4, 6, 8}); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // Keep only multiples of four. + d = 4; + sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d); + ExpectStackEquals(sk.get(), {4, 8}); + + // Removing elements preserves the sorted bit. + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // Delete everything. + d = 16; + sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d); + ExpectStackEquals(sk.get(), {}); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); +} + +TEST(StackTest, IsSorted) { + bssl::UniquePtr sk(sk_TEST_INT_new_null()); + ASSERT_TRUE(sk); + EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); + + // Empty lists are always known to be sorted. + sk_TEST_INT_set_cmp_func(sk.get(), compare); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // As are one-element lists. + auto value = TEST_INT_new(2); + ASSERT_TRUE(value); + ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value))); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // Two-element lists require an explicit sort. + value = TEST_INT_new(1); + ASSERT_TRUE(value); + ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value))); + EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); + + // The list is now sorted. + sk_TEST_INT_sort(sk.get()); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // After changing the comparison function, it no longer is sorted. + sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse); + EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); + + sk_TEST_INT_sort(sk.get()); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // But, starting from one element, switching the comparison function preserves + // the sorted bit. + TEST_INT_free(sk_TEST_INT_pop(sk.get())); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + sk_TEST_INT_set_cmp_func(sk.get(), compare); + EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get())); + + // Without a comparison function, the list cannot be sorted. + sk_TEST_INT_set_cmp_func(sk.get(), nullptr); + EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); +} + +TEST(StackTest, Sort) { + constexpr size_t kMaxLength = 100; + constexpr int kIterations = 500; + for (size_t len = 0; len < kMaxLength; len++) { + SCOPED_TRACE(len); + for (int iter = 0; iter < kIterations; iter++) { + // Make a random input list. + std::vector vec(len); + RAND_bytes(reinterpret_cast(vec.data()), + sizeof(int) * vec.size()); + SCOPED_TRACE(testing::PrintToString(vec)); + + // Convert it to a |STACK_OF(TEST_INT)|. + bssl::UniquePtr sk(sk_TEST_INT_new(compare)); + ASSERT_TRUE(sk); + for (int v : vec) { + auto value = TEST_INT_new(v); + ASSERT_TRUE(value); + ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value))); + } + + // Sort it with our sort implementation. + sk_TEST_INT_sort(sk.get()); + std::vector result; + for (const TEST_INT *v : sk.get()) { + result.push_back(*v); + } + + // The result must match the STL's version. + std::sort(vec.begin(), vec.end()); + EXPECT_EQ(vec, result); + } + } +} diff --git a/third_party/boringssl/kit/src/crypto/test/CMakeLists.txt b/third_party/boringssl/kit/src/crypto/test/CMakeLists.txt index b968fd78..9bfa2ec5 100644 --- a/third_party/boringssl/kit/src/crypto/test/CMakeLists.txt +++ b/third_party/boringssl/kit/src/crypto/test/CMakeLists.txt @@ -5,7 +5,6 @@ add_library( abi_test.cc file_test.cc - malloc.cc test_util.cc wycheproof_util.cc ) @@ -18,14 +17,7 @@ endif() if(WIN32) target_link_libraries(test_support_lib dbghelp) endif() -add_dependencies(test_support_lib global_target) +target_link_libraries(test_support_lib boringssl_gtest crypto) -add_library( - boringssl_gtest_main - - OBJECT - - gtest_main.cc -) - -add_dependencies(boringssl_gtest_main global_target) +add_library(boringssl_gtest_main STATIC gtest_main.cc) +target_link_libraries(boringssl_gtest_main boringssl_gtest crypto test_support_lib) diff --git a/third_party/boringssl/kit/src/crypto/test/abi_test.h b/third_party/boringssl/kit/src/crypto/test/abi_test.h index ffe44792..24340c90 100644 --- a/third_party/boringssl/kit/src/crypto/test/abi_test.h +++ b/third_party/boringssl/kit/src/crypto/test/abi_test.h @@ -179,78 +179,7 @@ struct alignas(16) Reg128 { CALLER_STATE_REGISTER(uint64_t, x28) \ CALLER_STATE_REGISTER(uint64_t, x29) -#elif defined(OPENSSL_PPC64LE) - -// CRReg only compares the CR2-CR4 bits of a CR register. -struct CRReg { - uint32_t masked() const { return value & 0x00fff000; } - bool operator==(CRReg r) const { return masked() == r.masked(); } - bool operator!=(CRReg r) const { return masked() != r.masked(); } - uint32_t value; -}; - -// References: -// ELFv2: http://openpowerfoundation.org/wp-content/uploads/resources/leabi/leabi-20170510.pdf -// -// Note vector and floating-point registers on POWER have two different names. -// Originally, there were 32 floating-point registers and 32 vector registers, -// labelled f0-f31 and v0-v31 respectively. Later, VSX (Vector Scalar Extension) -// unified them into 64 registers vs0-vs63. f0-f31 map to the lower halves of -// vs0-vs31. v0-v31 map to vs32-vs63. The ABI was defined in terms of pre-VSX -// names, so we use those names here. In particular, f14-f31 are -// callee-saved, but the upper halves of vs14-vs31 are not. -#define LOOP_CALLER_STATE_REGISTERS() \ - CALLER_STATE_REGISTER(Reg128, v20) \ - CALLER_STATE_REGISTER(Reg128, v21) \ - CALLER_STATE_REGISTER(Reg128, v22) \ - CALLER_STATE_REGISTER(Reg128, v23) \ - CALLER_STATE_REGISTER(Reg128, v24) \ - CALLER_STATE_REGISTER(Reg128, v25) \ - CALLER_STATE_REGISTER(Reg128, v26) \ - CALLER_STATE_REGISTER(Reg128, v27) \ - CALLER_STATE_REGISTER(Reg128, v28) \ - CALLER_STATE_REGISTER(Reg128, v29) \ - CALLER_STATE_REGISTER(Reg128, v30) \ - CALLER_STATE_REGISTER(Reg128, v31) \ - CALLER_STATE_REGISTER(uint64_t, r14) \ - CALLER_STATE_REGISTER(uint64_t, r15) \ - CALLER_STATE_REGISTER(uint64_t, r16) \ - CALLER_STATE_REGISTER(uint64_t, r17) \ - CALLER_STATE_REGISTER(uint64_t, r18) \ - CALLER_STATE_REGISTER(uint64_t, r19) \ - CALLER_STATE_REGISTER(uint64_t, r20) \ - CALLER_STATE_REGISTER(uint64_t, r21) \ - CALLER_STATE_REGISTER(uint64_t, r22) \ - CALLER_STATE_REGISTER(uint64_t, r23) \ - CALLER_STATE_REGISTER(uint64_t, r24) \ - CALLER_STATE_REGISTER(uint64_t, r25) \ - CALLER_STATE_REGISTER(uint64_t, r26) \ - CALLER_STATE_REGISTER(uint64_t, r27) \ - CALLER_STATE_REGISTER(uint64_t, r28) \ - CALLER_STATE_REGISTER(uint64_t, r29) \ - CALLER_STATE_REGISTER(uint64_t, r30) \ - CALLER_STATE_REGISTER(uint64_t, r31) \ - CALLER_STATE_REGISTER(uint64_t, f14) \ - CALLER_STATE_REGISTER(uint64_t, f15) \ - CALLER_STATE_REGISTER(uint64_t, f16) \ - CALLER_STATE_REGISTER(uint64_t, f17) \ - CALLER_STATE_REGISTER(uint64_t, f18) \ - CALLER_STATE_REGISTER(uint64_t, f19) \ - CALLER_STATE_REGISTER(uint64_t, f20) \ - CALLER_STATE_REGISTER(uint64_t, f21) \ - CALLER_STATE_REGISTER(uint64_t, f22) \ - CALLER_STATE_REGISTER(uint64_t, f23) \ - CALLER_STATE_REGISTER(uint64_t, f24) \ - CALLER_STATE_REGISTER(uint64_t, f25) \ - CALLER_STATE_REGISTER(uint64_t, f26) \ - CALLER_STATE_REGISTER(uint64_t, f27) \ - CALLER_STATE_REGISTER(uint64_t, f28) \ - CALLER_STATE_REGISTER(uint64_t, f29) \ - CALLER_STATE_REGISTER(uint64_t, f30) \ - CALLER_STATE_REGISTER(uint64_t, f31) \ - CALLER_STATE_REGISTER(CRReg, cr) - -#endif // X86_64 || X86 || ARM || AARCH64 || PPC64LE +#endif // X86_64 || X86 || ARM || AARCH64 // Enable ABI testing if all of the following are true. // @@ -302,12 +231,6 @@ inline crypto_word_t ToWord(T t) { // on 32-bit architectures for simplicity. static_assert(sizeof(T) == 4, "parameter types must be word-sized"); return (crypto_word_t)t; -#elif defined(OPENSSL_PPC64LE) - // ELFv2, section 2.2.2.3 says the parameter save area sign- or zero-extends - // parameters passed in memory. Section 2.2.3 is unclear on how to handle - // register parameters, but section 2.2.2.3 additionally says that the memory - // copy of a parameter is identical to the register one. - return (crypto_word_t)t; #elif defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64) // AAPCS64, section 5.4.2, clauses C.7 and C.14 says any remaining bits in // aarch are unspecified. iOS64 contradicts this and says the callee extends @@ -362,9 +285,9 @@ inline crypto_word_t ToWord(T t) { template inline crypto_word_t CheckImpl(Result *out, bool unwind, R (*func)(Args...), typename DeductionGuard::Type... args) { - // We only support up to 8 arguments, so all arguments on aarch64 and ppc64le - // are passed in registers. This is simpler and avoids the iOS discrepancy - // around packing small arguments on the stack. (See the iOS64 reference.) + // We only support up to 8 arguments, so all arguments on aarch64 are passed + // in registers. This is simpler and avoids the iOS discrepancy around packing + // small arguments on the stack. (See the iOS64 reference.) static_assert(sizeof...(args) <= 8, "too many arguments for abi_test_trampoline"); @@ -380,9 +303,9 @@ inline crypto_word_t CheckImpl(Result *out, bool unwind, R (*func)(Args...), // CheckImpl implementation. It must be specialized for void returns because we // call |func| directly. template -inline typename std::enable_if::value, crypto_word_t>::type -CheckImpl(Result *out, bool /* unwind */, R (*func)(Args...), - typename DeductionGuard::Type... args) { +inline std::enable_if_t::value, crypto_word_t> CheckImpl( + Result *out, bool /* unwind */, R (*func)(Args...), + typename DeductionGuard::Type... args) { *out = Result(); return func(args...); } diff --git a/third_party/boringssl/kit/src/crypto/test/asm/trampoline-ppc.pl b/third_party/boringssl/kit/src/crypto/test/asm/trampoline-ppc.pl deleted file mode 100755 index b29c3612..00000000 --- a/third_party/boringssl/kit/src/crypto/test/asm/trampoline-ppc.pl +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env perl -# Copyright (c) 2019, Google Inc. -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# This file defines helper functions for crypto/test/abi_test.h on ppc64le. See -# that header for details on how to use this. -# -# For convenience, this file is linked into libcrypto, where consuming builds -# already support architecture-specific sources. The static linker should drop -# this code in non-test binaries. This includes a shared library build of -# libcrypto, provided --gc-sections or equivalent is used. -# -# References: -# -# ELFv2: http://openpowerfoundation.org/wp-content/uploads/resources/leabi/leabi-20170510.pdf - -use strict; - -my $flavour = shift; -my $output = shift; -if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; -my $dir = $1; -my $xlate; -( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or -die "can't locate ppc-xlate.pl"; - -open OUT, "| \"$^X\" \"$xlate\" $flavour \"$output\""; -*STDOUT = *OUT; - -unless ($flavour =~ /linux.*64le/) { - die "This file only supports the ELFv2 ABI, used by ppc64le"; -} - -my $code = ""; - -sub load_or_store_regs { - # $op is "l" or "st". - my ($op, $base_reg, $base_offset) = @_; - # Vector registers. - foreach (20..31) { - my $offset = $base_offset + ($_ - 20) * 16; - # Vector registers only support indexed register addressing. - $code .= "\tli\tr11, $offset\n"; - $code .= "\t${op}vx\tv$_, r11, $base_reg\n"; - } - # Save general registers. - foreach (14..31) { - my $offset = $base_offset + 192 + ($_ - 14) * 8; - $code .= "\t${op}d\tr$_, $offset($base_reg)\n"; - } - # Save floating point registers. - foreach (14..31) { - my $offset = $base_offset + 336 + ($_ - 14) * 8; - $code .= "\t${op}fd\tf$_, $offset($base_reg)\n"; - } -} - -sub load_regs { - my ($base_reg, $base_offset) = @_; - load_or_store_regs("l", $base_reg, $base_offset); -} - -sub store_regs { - my ($base_reg, $base_offset) = @_; - load_or_store_regs("st", $base_reg, $base_offset); -} - -my ($func, $state, $argv, $argc) = ("r3", "r4", "r5", "r6"); -$code .= <<____; -.machine "any" -.text - -# abi_test_trampoline loads callee-saved registers from |state|, calls |func| -# with |argv|, then saves the callee-saved registers into |state|. It returns -# the result of |func|. The |unwind| argument is unused. -# uint64_t abi_test_trampoline(void (*func)(...), CallerState *state, -# const uint64_t *argv, size_t argc, -# uint64_t unwind); -.globl abi_test_trampoline -.align 5 -abi_test_trampoline: - # LR is saved into the caller's stack frame. - mflr r0 - std r0, 16(r1) - - # Allocate 66*8 = 528 bytes of stack frame. From the top of the stack - # to the bottom, the stack frame is: - # - # 0(r1) - Back chain pointer - # 8(r1) - CR save area - # 16(r1) - LR save area (for |func|) - # 24(r1) - TOC pointer save area - # 32(r1) - Saved copy of |state| - # 40(r1) - Padding - # 48(r1) - Vector register save area (v20-v31, 12 registers) - # 240(r1) - General register save area (r14-r31, 18 registers) - # 384(r1) - Floating point register save area (f14-f31, 18 registers) - # - # Note the layouts of the register save areas and CallerState match. - # - # In the ELFv2 ABI, the parameter save area is optional if the function - # is non-variadic and all parameters fit in registers. We only support - # such functions, so we omit it to test that |func| does not rely on it. - stdu r1, -528(r1) - - mfcr r0 - std r0, 8(r1) # Save CR - std r2, 24(r1) # Save TOC - std $state, 32(r1) # Save |state| -____ -# Save registers to the stack. -store_regs("r1", 48); -# Load registers from the caller. -load_regs($state, 0); -$code .= <<____; - # Load CR from |state|. - ld r0, 480($state) - mtcr r0 - - # Move parameters into temporary registers so they are not clobbered. - addi r11, $argv, -8 # Adjust for ldu below - mr r12, $func - - # Load parameters into registers. - cmpdi $argc, 0 - beq .Largs_done - mtctr $argc - ldu r3, 8(r11) - bdz .Largs_done - ldu r4, 8(r11) - bdz .Largs_done - ldu r5, 8(r11) - bdz .Largs_done - ldu r6, 8(r11) - bdz .Largs_done - ldu r7, 8(r11) - bdz .Largs_done - ldu r8, 8(r11) - bdz .Largs_done - ldu r9, 8(r11) - bdz .Largs_done - ldu r10, 8(r11) - -.Largs_done: - li r2, 0 # Clear TOC to test |func|'s global entry point - mtctr r12 - bctrl - ld r2, 24(r1) # Restore TOC - - ld $state, 32(r1) # Reload |state| -____ -# Output resulting registers to the caller. -store_regs($state, 0); -# Restore registers from the stack. -load_regs("r1", 48); -$code .= <<____; - mfcr r0 - std r0, 480($state) # Output CR to caller - ld r0, 8(r1) - mtcrf 0b00111000, r0 # Restore CR2-CR4 - addi r1, r1, 528 - ld r0, 16(r1) # Restore LR - mtlr r0 - blr -.size abi_test_trampoline,.-abi_test_trampoline -____ - -# abi_test_clobber_* clobbers the corresponding register. These are used to test -# the ABI-testing framework. -foreach (0..31) { - # r1 is the stack pointer. r13 is the thread pointer. - next if ($_ == 1 || $_ == 13); - $code .= <<____; -.globl abi_test_clobber_r$_ -.align 5 -abi_test_clobber_r$_: - li r$_, 0 - blr -.size abi_test_clobber_r$_,.-abi_test_clobber_r$_ -____ -} - -foreach (0..31) { - $code .= <<____; -.globl abi_test_clobber_f$_ -.align 4 -abi_test_clobber_f$_: - li r0, 0 - # Use the red zone. - std r0, -8(r1) - lfd f$_, -8(r1) - blr -.size abi_test_clobber_f$_,.-abi_test_clobber_f$_ -____ -} - -foreach (0..31) { - $code .= <<____; -.globl abi_test_clobber_v$_ -.align 4 -abi_test_clobber_v$_: - vxor v$_, v$_, v$_ - blr -.size abi_test_clobber_v$_,.-abi_test_clobber_v$_ -____ -} - -foreach (0..7) { - # PPC orders CR fields in big-endian, so the mask is reversed from what one - # would expect. - my $mask = 1 << (7 - $_); - $code .= <<____; -.globl abi_test_clobber_cr$_ -.align 4 -abi_test_clobber_cr$_: - # Flip the bits on cr$_ rather than setting to zero. With a four-bit - # register, zeroing it will do nothing 1 in 16 times. - mfcr r0 - not r0, r0 - mtcrf $mask, r0 - blr -.size abi_test_clobber_cr$_,.-abi_test_clobber_cr$_ -____ -} - -$code .= <<____; -.globl abi_test_clobber_ctr -.align 4 -abi_test_clobber_ctr: - li r0, 0 - mtctr r0 - blr -.size abi_test_clobber_ctr,.-abi_test_clobber_ctr - -.globl abi_test_clobber_lr -.align 4 -abi_test_clobber_lr: - mflr r0 - mtctr r0 - li r0, 0 - mtlr r0 - bctr -.size abi_test_clobber_lr,.-abi_test_clobber_lr - -____ - -print $code; -close STDOUT or die "error closing STDOUT: $!"; diff --git a/third_party/boringssl/kit/src/crypto/test/asm/trampoline-x86_64.pl b/third_party/boringssl/kit/src/crypto/test/asm/trampoline-x86_64.pl index f6d83850..75c85ec4 100755 --- a/third_party/boringssl/kit/src/crypto/test/asm/trampoline-x86_64.pl +++ b/third_party/boringssl/kit/src/crypto/test/asm/trampoline-x86_64.pl @@ -139,8 +139,8 @@ my $code = <<____; .globl abi_test_trampoline .align 16 abi_test_trampoline: -.Labi_test_trampoline_seh_begin: .cfi_startproc +.seh_startproc # Stack layout: # 8 bytes - align # $caller_state_size bytes - saved caller registers @@ -178,7 +178,7 @@ my $caller_state_offset = $scratch_offset + 8; $code .= <<____; subq \$$stack_alloc_size, %rsp .cfi_adjust_cfa_offset $stack_alloc_size -.Labi_test_trampoline_seh_prolog_alloc: +.seh_allocstack $stack_alloc_size ____ $code .= <<____ if (!$win64); movq $unwind, $unwind_offset(%rsp) @@ -186,20 +186,20 @@ ____ # Store our caller's state. This is needed because we modify it ourselves, and # also to isolate the test infrastruction from the function under test failing # to save some register. -my %reg_offsets; $code .= store_caller_state($caller_state_offset, "%rsp", sub { my ($off, $reg) = @_; $reg = substr($reg, 1); - $reg_offsets{$reg} = $off; - $off -= $stack_alloc_size + 8; + # SEH records offsets relative to %rsp (when there is no frame pointer), while + # CFI records them relative to the CFA, the value of the parent's stack + # pointer just before the call. + my $cfi_off = $off - $stack_alloc_size - 8; + my $seh_dir = ".seh_savereg"; + $seh_dir = ".seh_savexmm128" if ($reg =~ /^xmm/); return <<____; -.cfi_offset $reg, $off -.Labi_test_trampoline_seh_prolog_$reg: +.cfi_offset $reg, $cfi_off +$seh_dir \%$reg, $off ____ }); -$code .= <<____; -.Labi_test_trampoline_seh_prolog_end: -____ $code .= load_caller_state(0, $state); $code .= <<____; @@ -295,7 +295,7 @@ $code .= <<____; # %rax already contains \$func's return value, unmodified. ret .cfi_endproc -.Labi_test_trampoline_seh_end: +.seh_endproc .size abi_test_trampoline,.-abi_test_trampoline ____ @@ -334,10 +334,10 @@ $code .= <<____; .align 16 abi_test_bad_unwind_wrong_register: .cfi_startproc -.Labi_test_bad_unwind_wrong_register_seh_begin: +.seh_startproc pushq %r12 -.cfi_push %r13 # This should be %r12 -.Labi_test_bad_unwind_wrong_register_seh_push_r13: +.cfi_push %r13 # This should be %r13 +.seh_pushreg %r13 # This should be %r13 # Windows evaluates epilogs directly in the unwinder, rather than using # unwind codes. Add a nop so there is one non-epilog point (immediately # before the nop) where the unwinder can observe the mistake. @@ -345,7 +345,7 @@ abi_test_bad_unwind_wrong_register: popq %r12 .cfi_pop %r12 ret -.Labi_test_bad_unwind_wrong_register_seh_end: +.seh_endproc .cfi_endproc .size abi_test_bad_unwind_wrong_register,.-abi_test_bad_unwind_wrong_register @@ -357,10 +357,10 @@ abi_test_bad_unwind_wrong_register: .align 16 abi_test_bad_unwind_temporary: .cfi_startproc -.Labi_test_bad_unwind_temporary_seh_begin: +.seh_startproc pushq %r12 .cfi_push %r12 -.Labi_test_bad_unwind_temporary_seh_push_r12: +.seh_pushreg %r12 movq %r12, %rax inc %rax @@ -374,8 +374,8 @@ abi_test_bad_unwind_temporary: popq %r12 .cfi_pop %r12 ret -.Labi_test_bad_unwind_temporary_seh_end: .cfi_endproc +.seh_endproc .size abi_test_bad_unwind_temporary,.-abi_test_bad_unwind_temporary # abi_test_get_and_clear_direction_flag clears the direction flag. If the flag @@ -412,9 +412,9 @@ if ($win64) { .globl abi_test_bad_unwind_epilog .align 16 abi_test_bad_unwind_epilog: -.Labi_test_bad_unwind_epilog_seh_begin: +.seh_startproc pushq %r12 -.Labi_test_bad_unwind_epilog_seh_push_r12: +.seh_pushreg %r12 nop @@ -422,136 +422,8 @@ abi_test_bad_unwind_epilog: popq %r12 nop ret -.Labi_test_bad_unwind_epilog_seh_end: +.seh_endproc .size abi_test_bad_unwind_epilog,.-abi_test_bad_unwind_epilog -____ - - # Add unwind metadata for SEH. - # - # TODO(davidben): This is all manual right now. Once we've added SEH tests, - # add support for emitting these in x86_64-xlate.pl, probably based on MASM - # and Yasm's unwind directives, and unify with CFI. (Sadly, NASM does not - # support these directives.) Then push that upstream to replace the - # error-prone and non-standard custom handlers. - - # See https://docs.microsoft.com/en-us/cpp/build/struct-unwind-code?view=vs-2017 - my $UWOP_PUSH_NONVOL = 0; - my $UWOP_ALLOC_LARGE = 1; - my $UWOP_ALLOC_SMALL = 2; - my $UWOP_SAVE_NONVOL = 4; - my $UWOP_SAVE_XMM128 = 8; - - my %UWOP_REG_NUMBER = (rax => 0, rcx => 1, rdx => 2, rbx => 3, rsp => 4, - rbp => 5, rsi => 6, rdi => 7, - map(("r$_" => $_), (8..15))); - - my $unwind_codes = ""; - my $num_slots = 0; - foreach my $reg (reverse @caller_state) { - $reg = substr($reg, 1); - die "unknown register $reg" unless exists($reg_offsets{$reg}); - if ($reg =~ /^r/) { - die "unknown register $reg" unless exists($UWOP_REG_NUMBER{$reg}); - my $info = $UWOP_SAVE_NONVOL | ($UWOP_REG_NUMBER{$reg} << 4); - my $value = $reg_offsets{$reg} / 8; - $unwind_codes .= <<____; - .byte .Labi_test_trampoline_seh_prolog_$reg-.Labi_test_trampoline_seh_begin - .byte $info - .value $value -____ - $num_slots += 2; - } elsif ($reg =~ /^xmm/) { - my $info = $UWOP_SAVE_XMM128 | (substr($reg, 3) << 4); - my $value = $reg_offsets{$reg} / 16; - $unwind_codes .= <<____; - .byte .Labi_test_trampoline_seh_prolog_$reg-.Labi_test_trampoline_seh_begin - .byte $info - .value $value -____ - $num_slots += 2; - } else { - die "unknown register $reg"; - } - } - - if ($stack_alloc_size <= 128) { - my $info = $UWOP_ALLOC_SMALL | ((($stack_alloc_size - 8) / 8) << 4); - $unwind_codes .= <<____; - .byte .Labi_test_trampoline_seh_prolog_alloc-.Labi_test_trampoline_seh_begin - .byte $info -____ - $num_slots++; - } else { - die "stack allocation needs three unwind slots" if ($stack_alloc_size > 512 * 1024 + 8); - my $info = $UWOP_ALLOC_LARGE; - my $value = $stack_alloc_size / 8; - $unwind_codes .= <<____; - .byte .Labi_test_trampoline_seh_prolog_alloc-.Labi_test_trampoline_seh_begin - .byte $info - .value $value -____ - $num_slots += 2; - } - - $code .= <<____; -.section .pdata -.align 4 - # https://docs.microsoft.com/en-us/cpp/build/struct-runtime-function?view=vs-2017 - .rva .Labi_test_trampoline_seh_begin - .rva .Labi_test_trampoline_seh_end - .rva .Labi_test_trampoline_seh_info - - .rva .Labi_test_bad_unwind_wrong_register_seh_begin - .rva .Labi_test_bad_unwind_wrong_register_seh_end - .rva .Labi_test_bad_unwind_wrong_register_seh_info - - .rva .Labi_test_bad_unwind_temporary_seh_begin - .rva .Labi_test_bad_unwind_temporary_seh_end - .rva .Labi_test_bad_unwind_temporary_seh_info - - .rva .Labi_test_bad_unwind_epilog_seh_begin - .rva .Labi_test_bad_unwind_epilog_seh_end - .rva .Labi_test_bad_unwind_epilog_seh_info - -.section .xdata -.align 8 -.Labi_test_trampoline_seh_info: - # https://docs.microsoft.com/en-us/cpp/build/struct-unwind-info?view=vs-2017 - .byte 1 # version 1, no flags - .byte .Labi_test_trampoline_seh_prolog_end-.Labi_test_trampoline_seh_begin - .byte $num_slots - .byte 0 # no frame register -$unwind_codes - -.align 8 -.Labi_test_bad_unwind_wrong_register_seh_info: - .byte 1 # version 1, no flags - .byte .Labi_test_bad_unwind_wrong_register_seh_push_r13-.Labi_test_bad_unwind_wrong_register_seh_begin - .byte 1 # one slot - .byte 0 # no frame register - - .byte .Labi_test_bad_unwind_wrong_register_seh_push_r13-.Labi_test_bad_unwind_wrong_register_seh_begin - .byte @{[$UWOP_PUSH_NONVOL | ($UWOP_REG_NUMBER{r13} << 4)]} - -.align 8 -.Labi_test_bad_unwind_temporary_seh_info: - .byte 1 # version 1, no flags - .byte .Labi_test_bad_unwind_temporary_seh_push_r12-.Labi_test_bad_unwind_temporary_seh_begin - .byte 1 # one slot - .byte 0 # no frame register - - .byte .Labi_test_bad_unwind_temporary_seh_push_r12-.Labi_test_bad_unwind_temporary_seh_begin - .byte @{[$UWOP_PUSH_NONVOL | ($UWOP_REG_NUMBER{r12} << 4)]} - -.align 8 -.Labi_test_bad_unwind_epilog_seh_info: - .byte 1 # version 1, no flags - .byte .Labi_test_bad_unwind_epilog_seh_push_r12-.Labi_test_bad_unwind_epilog_seh_begin - .byte 1 # one slot - .byte 0 # no frame register - - .byte .Labi_test_bad_unwind_epilog_seh_push_r12-.Labi_test_bad_unwind_epilog_seh_begin - .byte @{[$UWOP_PUSH_NONVOL | ($UWOP_REG_NUMBER{r12} << 4)]} ____ } diff --git a/third_party/boringssl/kit/src/crypto/test/file_test.cc b/third_party/boringssl/kit/src/crypto/test/file_test.cc index 47a6f4c8..d7ef9511 100644 --- a/third_party/boringssl/kit/src/crypto/test/file_test.cc +++ b/third_party/boringssl/kit/src/crypto/test/file_test.cc @@ -20,12 +20,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include "../internal.h" #include "./test_util.h" @@ -56,11 +58,11 @@ static const char *FindDelimiter(const char *str) { // leading and trailing whitespace removed. static std::string StripSpace(const char *str, size_t len) { // Remove leading space. - while (len > 0 && isspace(*str)) { + while (len > 0 && OPENSSL_isspace(*str)) { str++; len--; } - while (len > 0 && isspace(str[len - 1])) { + while (len > 0 && OPENSSL_isspace(str[len - 1])) { len--; } return std::string(str, len); @@ -377,7 +379,8 @@ class FileLineReader : public FileTest::LineReader { return FileTest::kReadError; } - if (fgets(out, len, file_) == nullptr) { + len = std::min(len, size_t{INT_MAX}); + if (fgets(out, static_cast(len), file_) == nullptr) { return feof(file_) ? FileTest::kReadEOF : FileTest::kReadError; } diff --git a/third_party/boringssl/kit/src/crypto/test/gtest_main.cc b/third_party/boringssl/kit/src/crypto/test/gtest_main.cc index a79f2638..591cef70 100644 --- a/third_party/boringssl/kit/src/crypto/test/gtest_main.cc +++ b/third_party/boringssl/kit/src/crypto/test/gtest_main.cc @@ -17,7 +17,6 @@ #include -#include #include #include "abi_test.h" diff --git a/third_party/boringssl/kit/src/crypto/test/gtest_main.h b/third_party/boringssl/kit/src/crypto/test/gtest_main.h index 20ccf214..05d468ec 100644 --- a/third_party/boringssl/kit/src/crypto/test/gtest_main.h +++ b/third_party/boringssl/kit/src/crypto/test/gtest_main.h @@ -31,13 +31,15 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) #include #endif +#include "../internal.h" + BSSL_NAMESPACE_BEGIN -class ErrorTestEventListener : public testing::EmptyTestEventListener { +class TestEventListener : public testing::EmptyTestEventListener { public: - ErrorTestEventListener() {} - ~ErrorTestEventListener() override {} + TestEventListener() {} + ~TestEventListener() override {} void OnTestEnd(const testing::TestInfo &test_info) override { if (test_info.result()->Failed()) { @@ -48,6 +50,13 @@ class ErrorTestEventListener : public testing::EmptyTestEventListener { // error queue without printing. ERR_clear_error(); } + + // Malloc failure testing is quadratic in the number of mallocs. Running + // multiple tests sequentially thus scales badly. Reset the malloc counter + // between tests. This way we will test, each test with the first allocation + // failing, then the second, and so on, until the test with the most + // allocations runs out. + OPENSSL_reset_malloc_counter_for_testing(); } }; @@ -75,8 +84,7 @@ inline void SetupGoogleTest() { signal(SIGPIPE, SIG_IGN); #endif - testing::UnitTest::GetInstance()->listeners().Append( - new ErrorTestEventListener); + testing::UnitTest::GetInstance()->listeners().Append(new TestEventListener); } BSSL_NAMESPACE_END diff --git a/third_party/boringssl/kit/src/crypto/test/malloc.cc b/third_party/boringssl/kit/src/crypto/test/malloc.cc deleted file mode 100644 index 17189398..00000000 --- a/third_party/boringssl/kit/src/crypto/test/malloc.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* Copyright (c) 2014, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include - -#if defined(__GLIBC__) && !defined(__UCLIBC__) -#define OPENSSL_GLIBC -#endif - -// This file isn't built on ARM or Aarch64 because we link statically in those -// builds and trying to override malloc in a static link doesn't work. It also -// requires glibc. It's also disabled on ASan builds as this interferes with -// ASan's malloc interceptor. -// -// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to -// coexist. -#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \ - !defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN) && \ - !defined(OPENSSL_MSAN) && !defined(OPENSSL_TSAN) - -#include -#include -#include -#include -#include -#include - -#include - - -// This file defines overrides for the standard allocation functions that allow -// a given allocation to be made to fail for testing. If the program is run -// with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will -// return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation -// will signal SIGTRAP rather than return NULL. -// -// This code is not thread safe. - -static uint64_t current_malloc_count = 0; -static uint64_t malloc_number_to_fail = 0; -static bool failure_enabled = false, break_on_fail = false, in_call = false; - -extern "C" { -// These are other names for the standard allocation functions. -extern void *__libc_malloc(size_t size); -extern void *__libc_calloc(size_t num_elems, size_t size); -extern void *__libc_realloc(void *ptr, size_t size); -} - -static void exit_handler(void) { - if (failure_enabled && current_malloc_count > malloc_number_to_fail) { - _exit(88); - } -} - -static void cpp_new_handler() { - // Return to try again. It won't fail a second time. - return; -} - -// should_fail_allocation returns true if the current allocation should fail. -static bool should_fail_allocation() { - static bool init = false; - - if (in_call) { - return false; - } - - in_call = true; - - if (!init) { - const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); - if (env != NULL && env[0] != 0) { - char *endptr; - malloc_number_to_fail = strtoull(env, &endptr, 10); - if (*endptr == 0) { - failure_enabled = true; - atexit(exit_handler); - std::set_new_handler(cpp_new_handler); - } - } - break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL")); - init = true; - } - - in_call = false; - - if (!failure_enabled) { - return false; - } - - bool should_fail = (current_malloc_count == malloc_number_to_fail); - current_malloc_count++; - - if (should_fail && break_on_fail) { - raise(SIGTRAP); - } - return should_fail; -} - -extern "C" { - -void *malloc(size_t size) { - if (should_fail_allocation()) { - errno = ENOMEM; - return NULL; - } - - return __libc_malloc(size); -} - -void *calloc(size_t num_elems, size_t size) { - if (should_fail_allocation()) { - errno = ENOMEM; - return NULL; - } - - return __libc_calloc(num_elems, size); -} - -void *realloc(void *ptr, size_t size) { - if (should_fail_allocation()) { - errno = ENOMEM; - return NULL; - } - - return __libc_realloc(ptr, size); -} - -} // extern "C" - -#endif // defined(linux) && GLIBC && !ARM && !AARCH64 && !ASAN && !TSAN diff --git a/third_party/boringssl/kit/src/crypto/test/test_util.cc b/third_party/boringssl/kit/src/crypto/test/test_util.cc index 7f954138..23e8909f 100644 --- a/third_party/boringssl/kit/src/crypto/test/test_util.cc +++ b/third_party/boringssl/kit/src/crypto/test/test_util.cc @@ -39,22 +39,6 @@ std::ostream &operator<<(std::ostream &os, const Bytes &in) { return os; } -static bool FromHexDigit(uint8_t *out, char c) { - if ('0' <= c && c <= '9') { - *out = c - '0'; - return true; - } - if ('a' <= c && c <= 'f') { - *out = c - 'a' + 10; - return true; - } - if ('A' <= c && c <= 'F') { - *out = c - 'A' + 10; - return true; - } - return false; -} - bool DecodeHex(std::vector *out, const std::string &in) { out->clear(); if (in.size() % 2 != 0) { @@ -63,8 +47,8 @@ bool DecodeHex(std::vector *out, const std::string &in) { out->reserve(in.size() / 2); for (size_t i = 0; i < in.size(); i += 2) { uint8_t hi, lo; - if (!FromHexDigit(&hi, in[i]) || - !FromHexDigit(&lo, in[i + 1])) { + if (!OPENSSL_fromxdigit(&hi, in[i]) || + !OPENSSL_fromxdigit(&lo, in[i + 1])) { return false; } out->push_back((hi << 4) | lo); diff --git a/third_party/boringssl/kit/src/crypto/test/wycheproof_util.cc b/third_party/boringssl/kit/src/crypto/test/wycheproof_util.cc index cd870ddf..9d317060 100644 --- a/third_party/boringssl/kit/src/crypto/test/wycheproof_util.cc +++ b/third_party/boringssl/kit/src/crypto/test/wycheproof_util.cc @@ -14,6 +14,7 @@ #include "./wycheproof_util.h" +#include #include #include @@ -138,7 +139,8 @@ bssl::UniquePtr GetWycheproofBIGNUM(FileTest *t, const char *key, return nullptr; } BIGNUM *bn = nullptr; - if (BN_hex2bn(&bn, value.c_str()) != static_cast(value.size())) { + if (value.size() > INT_MAX || + BN_hex2bn(&bn, value.c_str()) != static_cast(value.size())) { BN_free(bn); t->PrintLine("Could not decode value '%s'", value.c_str()); return nullptr; @@ -151,8 +153,9 @@ bssl::UniquePtr GetWycheproofBIGNUM(FileTest *t, const char *key, // https://github.com/google/wycheproof/blob/0329f5b751ef102bd6b7b7181b6e049522a887f5/java/com/google/security/wycheproof/JsonUtil.java#L62. if ('0' > value[0] || value[0] > '7') { bssl::UniquePtr tmp(BN_new()); - if (!tmp || - !BN_set_bit(tmp.get(), value.size() * 4) || + if (!tmp || // + value.size() > INT_MAX / 4 || + !BN_set_bit(tmp.get(), static_cast(value.size() * 4)) || !BN_sub(ret.get(), ret.get(), tmp.get())) { return nullptr; } diff --git a/third_party/boringssl/kit/src/crypto/thread_none.c b/third_party/boringssl/kit/src/crypto/thread_none.c index 4f07b9d9..e6f7d427 100644 --- a/third_party/boringssl/kit/src/crypto/thread_none.c +++ b/third_party/boringssl/kit/src/crypto/thread_none.c @@ -28,14 +28,6 @@ void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {} void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {} -void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {} - -void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {} - -void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {} - -void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {} - void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { if (*once) { return; diff --git a/third_party/boringssl/kit/src/crypto/thread_pthread.c b/third_party/boringssl/kit/src/crypto/thread_pthread.c index e873d049..a40fbc00 100644 --- a/third_party/boringssl/kit/src/crypto/thread_pthread.c +++ b/third_party/boringssl/kit/src/crypto/thread_pthread.c @@ -12,81 +12,49 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include "internal.h" #if defined(OPENSSL_PTHREADS) +#include #include #include #include -#include -#include - - -OPENSSL_STATIC_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t), - "CRYPTO_MUTEX is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(CRYPTO_MUTEX) >= alignof(pthread_rwlock_t), - "CRYPTO_MUTEX has insufficient alignment"); -#endif - void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { - if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) { + if (pthread_rwlock_init(lock, NULL) != 0) { abort(); } } void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { - if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) { + if (pthread_rwlock_rdlock(lock) != 0) { abort(); } } void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { - if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) { + if (pthread_rwlock_wrlock(lock) != 0) { abort(); } } void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { - if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + if (pthread_rwlock_unlock(lock) != 0) { abort(); } } void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { - if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + if (pthread_rwlock_unlock(lock) != 0) { abort(); } } void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { - pthread_rwlock_destroy((pthread_rwlock_t *) lock); -} - -void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { - if (pthread_rwlock_rdlock(&lock->lock) != 0) { - abort(); - } -} - -void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { - if (pthread_rwlock_wrlock(&lock->lock) != 0) { - abort(); - } -} - -void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { - if (pthread_rwlock_unlock(&lock->lock) != 0) { - abort(); - } -} - -void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { - if (pthread_rwlock_unlock(&lock->lock) != 0) { - abort(); - } + pthread_rwlock_destroy(lock); } void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { @@ -120,7 +88,7 @@ static void thread_local_destructor(void *arg) { } } - OPENSSL_free(pointers); + free(pointers); } static pthread_once_t g_thread_local_init_once = PTHREAD_ONCE_INIT; @@ -155,14 +123,14 @@ int CRYPTO_set_thread_local(thread_local_data_t index, void *value, void **pointers = pthread_getspecific(g_thread_local_key); if (pointers == NULL) { - pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + pointers = malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pointers == NULL) { destructor(value); return 0; } OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pthread_setspecific(g_thread_local_key, pointers) != 0) { - OPENSSL_free(pointers); + free(pointers); destructor(value); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/thread_test.cc b/third_party/boringssl/kit/src/crypto/thread_test.cc index aa17e356..161c063d 100644 --- a/third_party/boringssl/kit/src/crypto/thread_test.cc +++ b/third_party/boringssl/kit/src/crypto/thread_test.cc @@ -57,8 +57,8 @@ TEST(ThreadTest, Once) { static CRYPTO_once_t once_init_value = CRYPTO_ONCE_INIT; static CRYPTO_once_t once_bss; -static struct CRYPTO_STATIC_MUTEX mutex_init_value = CRYPTO_STATIC_MUTEX_INIT; -static struct CRYPTO_STATIC_MUTEX mutex_bss; +static CRYPTO_MUTEX mutex_init_value = CRYPTO_MUTEX_INIT; +static CRYPTO_MUTEX mutex_bss; static CRYPTO_EX_DATA_CLASS ex_data_class_value = CRYPTO_EX_DATA_CLASS_INIT; static CRYPTO_EX_DATA_CLASS ex_data_class_bss; @@ -66,8 +66,8 @@ static CRYPTO_EX_DATA_CLASS ex_data_class_bss; TEST(ThreadTest, InitZeros) { if (FIPS_mode()) { // Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT|, - // |CRYPTO_STATIC_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and - // so can be placed in the BSS section. + // |CRYPTO_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and so can + // be placed in the BSS section. EXPECT_EQ(Bytes((uint8_t *)&once_bss, sizeof(once_bss)), Bytes((uint8_t *)&once_init_value, sizeof(once_init_value))); EXPECT_EQ(Bytes((uint8_t *)&mutex_bss, sizeof(mutex_bss)), diff --git a/third_party/boringssl/kit/src/crypto/thread_win.c b/third_party/boringssl/kit/src/crypto/thread_win.c index 49ecc12a..6daa8144 100644 --- a/third_party/boringssl/kit/src/crypto/thread_win.c +++ b/third_party/boringssl/kit/src/crypto/thread_win.c @@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Ensure we can't call OPENSSL_malloc circularly. +#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC #include "internal.h" #if defined(OPENSSL_WINDOWS_THREADS) @@ -20,20 +22,10 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3)) #include OPENSSL_MSVC_PRAGMA(warning(pop)) +#include #include #include -#include -#include - - -OPENSSL_STATIC_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK), - "CRYPTO_MUTEX is too small"); -#if defined(__GNUC__) || defined(__clang__) -OPENSSL_STATIC_ASSERT(alignof(CRYPTO_MUTEX) >= alignof(SRWLOCK), - "CRYPTO_MUTEX has insufficient alignment"); -#endif - static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) { void (**init)(void) = (void (**)(void))arg; (**init)(); @@ -47,45 +39,29 @@ void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { } void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { - InitializeSRWLock((SRWLOCK *) lock); + InitializeSRWLock(lock); } void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { - AcquireSRWLockShared((SRWLOCK *) lock); + AcquireSRWLockShared(lock); } void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { - AcquireSRWLockExclusive((SRWLOCK *) lock); + AcquireSRWLockExclusive(lock); } void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { - ReleaseSRWLockShared((SRWLOCK *) lock); + ReleaseSRWLockShared(lock); } void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { - ReleaseSRWLockExclusive((SRWLOCK *) lock); + ReleaseSRWLockExclusive(lock); } void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { // SRWLOCKs require no cleanup. } -void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { - AcquireSRWLockShared(&lock->lock); -} - -void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { - AcquireSRWLockExclusive(&lock->lock); -} - -void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { - ReleaseSRWLockShared(&lock->lock); -} - -void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { - ReleaseSRWLockExclusive(&lock->lock); -} - static SRWLOCK g_destructors_lock = SRWLOCK_INIT; static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; @@ -131,7 +107,7 @@ static void NTAPI thread_local_destructor(PVOID module, DWORD reason, } } - OPENSSL_free(pointers); + free(pointers); } // Thread Termination Callbacks. @@ -236,14 +212,14 @@ int CRYPTO_set_thread_local(thread_local_data_t index, void *value, void **pointers = get_thread_locals(); if (pointers == NULL) { - pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + pointers = malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (pointers == NULL) { destructor(value); return 0; } OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); if (TlsSetValue(g_thread_local_key, pointers) == 0) { - OPENSSL_free(pointers); + free(pointers); destructor(value); return 0; } diff --git a/third_party/boringssl/kit/src/crypto/trust_token/internal.h b/third_party/boringssl/kit/src/crypto/trust_token/internal.h index 0aa19363..8fc5d6ea 100644 --- a/third_party/boringssl/kit/src/crypto/trust_token/internal.h +++ b/third_party/boringssl/kit/src/crypto/trust_token/internal.h @@ -71,6 +71,7 @@ typedef struct { // TRUST_TOKEN_PRETOKEN represents the intermediate state a client keeps during // a Trust_Token issuance operation. typedef struct pmb_pretoken_st { + uint8_t salt[TRUST_TOKEN_NONCE_SIZE]; uint8_t t[TRUST_TOKEN_NONCE_SIZE]; EC_SCALAR r; EC_AFFINE Tp; @@ -93,22 +94,29 @@ DEFINE_STACK_OF(TRUST_TOKEN_PRETOKEN) // functions for |TRUST_TOKENS_experiment_v1|'s PMBTokens construction which // uses P-384. int pmbtoken_exp1_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_exp1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len); int pmbtoken_exp1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *pmbtoken_exp1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); // pmbtoken_exp1_get_h_for_testing returns H in uncompressed coordinates. This // function is used to confirm H was computed as expected. @@ -118,27 +126,66 @@ OPENSSL_EXPORT int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]); // functions for |TRUST_TOKENS_experiment_v2|'s PMBTokens construction which // uses P-384. int pmbtoken_exp2_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len); int pmbtoken_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *pmbtoken_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); // pmbtoken_exp2_get_h_for_testing returns H in uncompressed coordinates. This // function is used to confirm H was computed as expected. OPENSSL_EXPORT int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]); +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_pst_v1|'s PMBTokens construction which uses +// P-384. +int pmbtoken_pst1_generate_key(CBB *out_private, CBB *out_public); +int pmbtoken_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len); +int pmbtoken_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int pmbtoken_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); +int pmbtoken_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +STACK_OF(TRUST_TOKEN) *pmbtoken_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); +int pmbtoken_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len); + +// pmbtoken_pst1_get_h_for_testing returns H in uncompressed coordinates. This +// function is used to confirm H was computed as expected. +OPENSSL_EXPORT int pmbtoken_pst1_get_h_for_testing(uint8_t out[97]); + // VOPRF. // @@ -153,22 +200,58 @@ OPENSSL_EXPORT int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]); // functions for |TRUST_TOKENS_experiment_v2|'s VOPRF construction which uses // P-384. int voprf_exp2_generate_key(CBB *out_private, CBB *out_public); +int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, size_t secret_len); int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len); int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); -STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count); +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, size_t num_to_issue, uint8_t private_metadata); -STACK_OF(TRUST_TOKEN) * - voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id); +STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); + +// The following functions implement the corresponding |TRUST_TOKENS_METHOD| +// functions for |TRUST_TOKENS_pst_v1|'s VOPRF construction which uses P-384. +int voprf_pst1_generate_key(CBB *out_private, CBB *out_public); +int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, size_t secret_len); +int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len); +int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len); +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len); +int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata); +OPENSSL_EXPORT int voprf_pst1_sign_with_proof_scalar_for_testing( + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, + size_t num_to_issue, uint8_t private_metadata, + const uint8_t *proof_scalar_buf, size_t proof_scalar_len); +STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); +int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); // Trust Tokens internals. @@ -179,6 +262,12 @@ struct trust_token_method_st { // zero on failure. int (*generate_key)(CBB *out_private, CBB *out_public); + // derive_key_from_secret deterministically derives a keypair based on + // |secret| and writes their serialized forms into |out_private| and + // |out_public|. It returns one on success and zero on failure. + int (*derive_key_from_secret)(CBB *out_private, CBB *out_public, + const uint8_t *secret, size_t secret_len); + // client_key_from_bytes decodes a client key from |in| and sets |key| // to the resulting key. It returns one on success and zero // on failure. @@ -191,14 +280,17 @@ struct trust_token_method_st { int (*issuer_key_from_bytes)(TRUST_TOKEN_ISSUER_KEY *key, const uint8_t *in, size_t len); - // blind generates a new issuance request for |count| tokens. On + // blind generates a new issuance request for |count| tokens. If + // |include_message| is set, then |msg| is used to derive the token nonces. On // success, it returns a newly-allocated |STACK_OF(TRUST_TOKEN_PRETOKEN)| and // writes a request to the issuer to |cbb|. On failure, it returns NULL. The - // |STACK_OF(TRUST_TOKEN_PRETOKEN)|s should be passed to |pmbtoken_unblind| when - // the server responds. + // |STACK_OF(TRUST_TOKEN_PRETOKEN)|s should be passed to |pmbtoken_unblind| + // when the server responds. // // This function implements the AT.Usr0 operation. - STACK_OF(TRUST_TOKEN_PRETOKEN) * (*blind)(CBB *cbb, size_t count); + STACK_OF(TRUST_TOKEN_PRETOKEN) *(*blind)(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, size_t msg_len); // sign parses a request for |num_requested| tokens from |cbs| and // issues |num_to_issue| tokens with |key| and a private metadata value of @@ -218,20 +310,22 @@ struct trust_token_method_st { // returns NULL. // // This function implements the AT.Usr1 operation. - STACK_OF(TRUST_TOKEN) * - (*unblind)(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id); + STACK_OF(TRUST_TOKEN) *(*unblind)( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id); - // read parses a PMBToken from |token| and verifies it using |key|. On - // success, it returns one and stores the nonce and private metadata bit in - // |out_nonce| and |*out_private_metadata|. Otherwise, it returns zero. Note - // that, unlike the output of |unblind|, |token| does not have a - // four-byte key ID prepended. + // read parses a token from |token| and verifies it using |key|. If + // |include_message| is set, then the nonce is derived from |msg| and the salt + // in the token. On success, it returns one and stores the nonce and private + // metadata bit in |out_nonce| and |*out_private_metadata|. Otherwise, it + // returns zero. Note that, unlike the output of |unblind|, |token| does not + // have a four-byte key ID prepended. int (*read)(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len); + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len); // whether the construction supports private metadata. int has_private_metadata; @@ -270,7 +364,7 @@ struct trust_token_client_st { size_t num_keys; // pretokens is the intermediate state during an active issuance. - STACK_OF(TRUST_TOKEN_PRETOKEN)* pretokens; + STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens; // srr_key is the public key used to verify the signature of the SRR. EVP_PKEY *srr_key; diff --git a/third_party/boringssl/kit/src/crypto/trust_token/pmbtoken.c b/third_party/boringssl/kit/src/crypto/trust_token/pmbtoken.c index a6549b9c..d49a2b86 100644 --- a/third_party/boringssl/kit/src/crypto/trust_token/pmbtoken.c +++ b/third_party/boringssl/kit/src/crypto/trust_token/pmbtoken.c @@ -30,19 +30,21 @@ #include "internal.h" -typedef int (*hash_t_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, +typedef int (*hash_t_func_t)(const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t t[TRUST_TOKEN_NONCE_SIZE]); -typedef int (*hash_s_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, +typedef int (*hash_s_func_t)(const EC_GROUP *group, EC_JACOBIAN *out, const EC_AFFINE *t, const uint8_t s[TRUST_TOKEN_NONCE_SIZE]); typedef int (*hash_c_func_t)(const EC_GROUP *group, EC_SCALAR *out, uint8_t *buf, size_t len); +typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len); typedef struct { const EC_GROUP *group; EC_PRECOMP g_precomp; EC_PRECOMP h_precomp; - EC_RAW_POINT h; + EC_JACOBIAN h; // hash_t implements the H_t operation in PMBTokens. It returns one on success // and zero on error. hash_t_func_t hash_t; @@ -52,6 +54,9 @@ typedef struct { // hash_c implements the H_c operation in PMBTokens. It returns one on success // and zero on error. hash_c_func_t hash_c; + // hash_to_scalar implements the HashToScalar operation for PMBTokens. It + // returns one on success and zero on error. + hash_to_scalar_func_t hash_to_scalar; int prefix_point : 1; } PMBTOKEN_METHOD; @@ -60,7 +65,9 @@ static const uint8_t kDefaultAdditionalData[32] = {0}; static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, const uint8_t *h_bytes, size_t h_len, hash_t_func_t hash_t, hash_s_func_t hash_s, - hash_c_func_t hash_c, int prefix_point) { + hash_c_func_t hash_c, + hash_to_scalar_func_t hash_to_scalar, + int prefix_point) { method->group = EC_GROUP_new_by_curve_name(curve_nid); if (method->group == NULL) { return 0; @@ -69,6 +76,7 @@ static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, method->hash_t = hash_t; method->hash_s = hash_s; method->hash_c = hash_c; + method->hash_to_scalar = hash_to_scalar; method->prefix_point = prefix_point; EC_AFFINE h; @@ -85,27 +93,37 @@ static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid, return 1; } -// generate_keypair generates a keypair for the PMBTokens construction. -// |out_x| and |out_y| are set to the secret half of the keypair, while -// |*out_pub| is set to the public half of the keypair. It returns one on -// success and zero on failure. -static int generate_keypair(const PMBTOKEN_METHOD *method, EC_SCALAR *out_x, - EC_SCALAR *out_y, EC_RAW_POINT *out_pub) { - if (!ec_random_nonzero_scalar(method->group, out_x, kDefaultAdditionalData) || - !ec_random_nonzero_scalar(method->group, out_y, kDefaultAdditionalData) || - !ec_point_mul_scalar_precomp(method->group, out_pub, &method->g_precomp, - out_x, &method->h_precomp, out_y, NULL, - NULL)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - return 0; +static int derive_scalar_from_secret(const PMBTOKEN_METHOD *method, + EC_SCALAR *out, const uint8_t *secret, + size_t secret_len, uint8_t scalar_id) { + static const uint8_t kKeygenLabel[] = "TrustTokenPMBTokenKeyGen"; + + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kKeygenLabel, sizeof(kKeygenLabel)) || + !CBB_add_u8(&cbb, scalar_id) || + !CBB_add_bytes(&cbb, secret, secret_len) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_to_scalar(method->group, out, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + goto err; } - return 1; + + ok = 1; + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; } static int point_to_cbb(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); if (len == 0) { return 0; } @@ -155,29 +173,34 @@ static int cbs_get_prefixed_point(CBS *cbs, const EC_GROUP *group, return 1; } -static int mul_public_3(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1, - const EC_RAW_POINT *p2, const EC_SCALAR *scalar2) { - EC_RAW_POINT points[3] = {*p0, *p1, *p2}; +static int mul_public_3(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1, + const EC_JACOBIAN *p2, const EC_SCALAR *scalar2) { + EC_JACOBIAN points[3] = {*p0, *p1, *p2}; EC_SCALAR scalars[3] = {*scalar0, *scalar1, *scalar2}; return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points, scalars, 3); } -static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method, - CBB *out_private, CBB *out_public) { +static int pmbtoken_compute_keys(const PMBTOKEN_METHOD *method, + CBB *out_private, CBB *out_public, + const EC_SCALAR *x0, const EC_SCALAR *y0, + const EC_SCALAR *x1, const EC_SCALAR *y1, + const EC_SCALAR *xs, const EC_SCALAR *ys) { const EC_GROUP *group = method->group; - EC_RAW_POINT pub[3]; - EC_SCALAR x0, y0, x1, y1, xs, ys; - if (!generate_keypair(method, &x0, &y0, &pub[0]) || - !generate_keypair(method, &x1, &y1, &pub[1]) || - !generate_keypair(method, &xs, &ys, &pub[2])) { + EC_JACOBIAN pub[3]; + if (!ec_point_mul_scalar_precomp(group, &pub[0], &method->g_precomp, + x0, &method->h_precomp, y0, NULL, NULL) || + !ec_point_mul_scalar_precomp(group, &pub[1], &method->g_precomp, + x1, &method->h_precomp, y1, NULL, NULL) || + !ec_point_mul_scalar_precomp(method->group, &pub[2], &method->g_precomp, + xs, &method->h_precomp, ys, NULL, NULL)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); return 0; } - const EC_SCALAR *scalars[] = {&x0, &y0, &x1, &y1, &xs, &ys}; + const EC_SCALAR *scalars[] = {x0, y0, x1, y1, xs, ys}; size_t scalar_len = BN_num_bytes(&group->order); for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { uint8_t *buf; @@ -206,6 +229,42 @@ static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method, return 1; } +static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method, + CBB *out_private, CBB *out_public) { + EC_SCALAR x0, y0, x1, y1, xs, ys; + if (!ec_random_nonzero_scalar(method->group, &x0, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, &y0, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, &x1, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, &y1, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, &xs, kDefaultAdditionalData) || + !ec_random_nonzero_scalar(method->group, &ys, kDefaultAdditionalData)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + return 0; + } + + return pmbtoken_compute_keys(method, out_private, out_public, &x0, &y0, &x1, + &y1, &xs, &ys); +} + +static int pmbtoken_derive_key_from_secret(const PMBTOKEN_METHOD *method, + CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + EC_SCALAR x0, y0, x1, y1, xs, ys; + if (!derive_scalar_from_secret(method, &x0, secret, secret_len, 0) || + !derive_scalar_from_secret(method, &y0, secret, secret_len, 1) || + !derive_scalar_from_secret(method, &x1, secret, secret_len, 2) || + !derive_scalar_from_secret(method, &y1, secret, secret_len, 3) || + !derive_scalar_from_secret(method, &xs, secret, secret_len, 4) || + !derive_scalar_from_secret(method, &ys, secret, secret_len, 5)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + return 0; + } + + return pmbtoken_compute_keys(method, out_private, out_public, &x0, &y0, &x1, + &y1, &xs, &ys); +} + static int pmbtoken_client_key_from_bytes(const PMBTOKEN_METHOD *method, TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len) { @@ -244,7 +303,7 @@ static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, } // Recompute the public key. - EC_RAW_POINT pub[3]; + EC_JACOBIAN pub[3]; EC_AFFINE pub_affine[3]; if (!ec_point_mul_scalar_precomp(group, &pub[0], &method->g_precomp, &key->x0, &method->h_precomp, &key->y0, NULL, NULL) || @@ -265,12 +324,14 @@ static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, return 1; } -static STACK_OF(TRUST_TOKEN_PRETOKEN) * - pmbtoken_blind(const PMBTOKEN_METHOD *method, CBB *cbb, size_t count) { +static STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_blind( + const PMBTOKEN_METHOD *method, CBB *cbb, size_t count, int include_message, + const uint8_t *msg, size_t msg_len) { + SHA512_CTX hash_ctx; + const EC_GROUP *group = method->group; STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = sk_TRUST_TOKEN_PRETOKEN_new_null(); if (pretokens == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -279,17 +340,24 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * TRUST_TOKEN_PRETOKEN *pretoken = OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); if (pretoken == NULL || !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_PRETOKEN_free(pretoken); goto err; } - RAND_bytes(pretoken->t, sizeof(pretoken->t)); + RAND_bytes(pretoken->salt, sizeof(pretoken->salt)); + if (include_message) { + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(pretoken->t, &hash_ctx); + } else { + OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE); + } // We sample |pretoken->r| in Montgomery form to simplify inverting. if (!ec_random_nonzero_scalar(group, &pretoken->r, kDefaultAdditionalData)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -299,7 +367,7 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r); ec_scalar_from_montgomery(group, &rinv, &rinv); - EC_RAW_POINT T, Tp; + EC_JACOBIAN T, Tp; if (!method->hash_t(group, &T, pretoken->t) || !ec_point_mul_scalar(group, &Tp, &T, &rinv) || !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) { @@ -324,7 +392,6 @@ static int scalar_to_cbb(CBB *out, const EC_GROUP *group, uint8_t *buf; size_t scalar_len = BN_num_bytes(&group->order); if (!CBB_add_space(out, &buf, scalar_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ec_scalar_to_bytes(group, buf, &scalar_len, scalar); @@ -364,7 +431,6 @@ static int hash_c_dleq(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !point_to_cbb(&cbb, method->group, K1) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -402,7 +468,6 @@ static int hash_c_dleqor(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !point_to_cbb(&cbb, method->group, K11) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -434,7 +499,6 @@ static int hash_c_batch(const PMBTOKEN_METHOD *method, EC_SCALAR *out, !CBB_add_u16(&cbb, (uint16_t)index) || !CBB_finish(&cbb, &buf, &len) || !method->hash_c(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -452,8 +516,8 @@ err: static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, const TRUST_TOKEN_ISSUER_KEY *priv, - const EC_RAW_POINT *T, const EC_RAW_POINT *S, - const EC_RAW_POINT *W, const EC_RAW_POINT *Ws, + const EC_JACOBIAN *T, const EC_JACOBIAN *S, + const EC_JACOBIAN *W, const EC_JACOBIAN *Ws, uint8_t private_metadata) { const EC_GROUP *group = method->group; @@ -473,7 +537,7 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, idx_Ko1, num_idx, }; - EC_RAW_POINT jacobians[num_idx]; + EC_JACOBIAN jacobians[num_idx]; // Setup the DLEQ proof. EC_SCALAR ks0, ks1; @@ -569,7 +633,6 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, if (!scalar_to_cbb(cbb, group, &cs) || !scalar_to_cbb(cbb, group, &us) || !scalar_to_cbb(cbb, group, &vs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -605,7 +668,6 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, !scalar_to_cbb(cbb, group, &u1) || !scalar_to_cbb(cbb, group, &v0) || !scalar_to_cbb(cbb, group, &v1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -613,11 +675,11 @@ static int dleq_generate(const PMBTOKEN_METHOD *method, CBB *cbb, } static int dleq_verify(const PMBTOKEN_METHOD *method, CBS *cbs, - const TRUST_TOKEN_CLIENT_KEY *pub, const EC_RAW_POINT *T, - const EC_RAW_POINT *S, const EC_RAW_POINT *W, - const EC_RAW_POINT *Ws) { + const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *T, + const EC_JACOBIAN *S, const EC_JACOBIAN *W, + const EC_JACOBIAN *Ws) { const EC_GROUP *group = method->group; - const EC_RAW_POINT *g = &group->generator->raw; + const EC_JACOBIAN *g = &group->generator->raw; // We verify a DLEQ proof for the validity token and a DLEQOR2 proof for the // private metadata token. To allow amortizing Jacobian-to-affine conversions, @@ -637,7 +699,7 @@ static int dleq_verify(const PMBTOKEN_METHOD *method, CBS *cbs, idx_K11, num_idx, }; - EC_RAW_POINT jacobians[num_idx]; + EC_JACOBIAN jacobians[num_idx]; // Decode the DLEQ proof. EC_SCALAR cs, us, vs; @@ -649,7 +711,7 @@ static int dleq_verify(const PMBTOKEN_METHOD *method, CBS *cbs, } // Ks = us*(G;T) + vs*(H;S) - cs*(pubs;Ws) - EC_RAW_POINT pubs; + EC_JACOBIAN pubs; ec_affine_to_jacobian(group, &pubs, &pub->pubs); EC_SCALAR minus_cs; ec_scalar_neg(group, &minus_cs, &cs); @@ -672,7 +734,7 @@ static int dleq_verify(const PMBTOKEN_METHOD *method, CBS *cbs, return 0; } - EC_RAW_POINT pub0, pub1; + EC_JACOBIAN pub0, pub1; ec_affine_to_jacobian(group, &pub0, &pub->pub0); ec_affine_to_jacobian(group, &pub1, &pub->pub1); EC_SCALAR minus_c0, minus_c1; @@ -741,17 +803,17 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, return 0; } - if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || + if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) || num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); return 0; } int ret = 0; - EC_RAW_POINT *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_JACOBIAN *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); @@ -764,13 +826,12 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, !point_to_cbb(&batch_cbb, method->group, &key->pubs) || !point_to_cbb(&batch_cbb, method->group, &key->pub0) || !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } for (size_t i = 0; i < num_to_issue; i++) { EC_AFFINE Tp_affine; - EC_RAW_POINT Tp; + EC_JACOBIAN Tp; if (!cbs_get_prefixed_point(cbs, group, &Tp_affine, method->prefix_point)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); goto err; @@ -785,7 +846,7 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, uint8_t s[TRUST_TOKEN_NONCE_SIZE]; RAND_bytes(s, TRUST_TOKEN_NONCE_SIZE); // The |jacobians| and |affines| contain Sp, Wp, and Wsp. - EC_RAW_POINT jacobians[3]; + EC_JACOBIAN jacobians[3]; EC_AFFINE affines[3]; if (!method->hash_s(group, &jacobians[0], &Tp_affine, s) || !ec_point_mul_scalar_batch(group, &jacobians[1], &Tp, &xb, @@ -805,7 +866,6 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, !point_to_cbb(&batch_cbb, group, &affines[0]) || !point_to_cbb(&batch_cbb, group, &affines[1]) || !point_to_cbb(&batch_cbb, group, &affines[2])) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } Tps[i] = Tp; @@ -827,7 +887,7 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method, } } - EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + EC_JACOBIAN Tp_batch, Sp_batch, Wp_batch, Wsp_batch; if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, /*g_scalar=*/NULL, Tps, es, num_to_issue) || @@ -874,46 +934,41 @@ err: return ret; } -static STACK_OF(TRUST_TOKEN) * - pmbtoken_unblind(const PMBTOKEN_METHOD *method, - const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id) { +static STACK_OF(TRUST_TOKEN) *pmbtoken_unblind( + const PMBTOKEN_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { const EC_GROUP *group = method->group; if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return NULL; } - int ok = 0; - STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); return NULL; } - if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || - count > ((size_t)-1) / sizeof(EC_SCALAR)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - return 0; - } - EC_RAW_POINT *Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); + EC_JACOBIAN *Tps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Sps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Wps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Wsps = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (!Tps || - !Sps || - !Wps || - !Wsps || - !es || + if (ret == NULL || + Tps == NULL || + Sps == NULL || + Wps == NULL || + Wsps == NULL || + es == NULL || !CBB_init(&batch_cbb, 0) || !point_to_cbb(&batch_cbb, method->group, &key->pubs) || !point_to_cbb(&batch_cbb, method->group, &key->pub0) || !point_to_cbb(&batch_cbb, method->group, &key->pub1)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -944,12 +999,11 @@ static STACK_OF(TRUST_TOKEN) * !point_to_cbb(&batch_cbb, group, &Sp_affine) || !point_to_cbb(&batch_cbb, group, &Wp_affine) || !point_to_cbb(&batch_cbb, group, &Wsp_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } // Unblind the token. - EC_RAW_POINT jacobians[3]; + EC_JACOBIAN jacobians[3]; EC_AFFINE affines[3]; if (!ec_point_mul_scalar(group, &jacobians[0], &Sps[i], &pretoken->r) || !ec_point_mul_scalar(group, &jacobians[1], &Wps[i], &pretoken->r) || @@ -965,7 +1019,7 @@ static STACK_OF(TRUST_TOKEN) * if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + 3 * (2 + point_len)) || !CBB_add_u32(&token_cbb, key_id) || - !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) || !cbb_add_prefixed_point(&token_cbb, group, &affines[0], method->prefix_point) || !cbb_add_prefixed_point(&token_cbb, group, &affines[1], @@ -982,7 +1036,6 @@ static STACK_OF(TRUST_TOKEN) * CBB_cleanup(&token_cbb); if (token == NULL || !sk_TRUST_TOKEN_push(ret, token)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_free(token); goto err; } @@ -997,7 +1050,7 @@ static STACK_OF(TRUST_TOKEN) * } } - EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch; + EC_JACOBIAN Tp_batch, Sp_batch, Wp_batch, Wsp_batch; if (!ec_point_mul_scalar_public_batch(group, &Tp_batch, /*g_scalar=*/NULL, Tps, es, count) || !ec_point_mul_scalar_public_batch(group, &Sp_batch, @@ -1037,12 +1090,13 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { const EC_GROUP *group = method->group; - CBS cbs; + CBS cbs, salt; CBS_init(&cbs, token, token_len); EC_AFFINE S, W, Ws; - if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) || !cbs_get_prefixed_point(&cbs, group, &S, method->prefix_point) || !cbs_get_prefixed_point(&cbs, group, &W, method->prefix_point) || !cbs_get_prefixed_point(&cbs, group, &Ws, method->prefix_point) || @@ -1051,15 +1105,25 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, return 0; } + if (include_message) { + SHA512_CTX hash_ctx; + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(out_nonce, &hash_ctx); + } else { + OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt)); + } - EC_RAW_POINT T; + EC_JACOBIAN T; if (!method->hash_t(group, &T, out_nonce)) { return 0; } // We perform three multiplications with S and T. This is enough that it is // worth using |ec_point_mul_scalar_precomp|. - EC_RAW_POINT S_jacobian; + EC_JACOBIAN S_jacobian; EC_PRECOMP S_precomp, T_precomp; ec_affine_to_jacobian(group, &S_jacobian, &S); if (!ec_init_precomp(group, &S_precomp, &S_jacobian) || @@ -1067,7 +1131,7 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, return 0; } - EC_RAW_POINT Ws_calculated; + EC_JACOBIAN Ws_calculated; // Check the validity of the token. if (!ec_point_mul_scalar_precomp(group, &Ws_calculated, &T_precomp, &key->xs, &S_precomp, &key->ys, NULL, NULL) || @@ -1076,7 +1140,7 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, return 0; } - EC_RAW_POINT W0, W1; + EC_JACOBIAN W0, W1; if (!ec_point_mul_scalar_precomp(group, &W0, &T_precomp, &key->x0, &S_precomp, &key->y0, NULL, NULL) || !ec_point_mul_scalar_precomp(group, &W1, &T_precomp, &key->x1, &S_precomp, @@ -1100,14 +1164,14 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method, // PMBTokens experiment v1. -static int pmbtoken_exp1_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, +static int pmbtoken_exp1_hash_t(const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { const uint8_t kHashTLabel[] = "PMBTokens Experiment V1 HashT"; return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); } -static int pmbtoken_exp1_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, +static int pmbtoken_exp1_hash_s(const EC_GROUP *group, EC_JACOBIAN *out, const EC_AFFINE *t, const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { const uint8_t kHashSLabel[] = "PMBTokens Experiment V1 HashS"; @@ -1121,7 +1185,6 @@ static int pmbtoken_exp1_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, !CBB_finish(&cbb, &buf, &len) || !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1140,6 +1203,13 @@ static int pmbtoken_exp1_hash_c(const EC_GROUP *group, EC_SCALAR *out, group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); } +static int pmbtoken_exp1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashLabel[] = "PMBTokens Experiment V1 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha512_draft07( + group, out, kHashLabel, sizeof(kHashLabel), buf, len); +} + static int pmbtoken_exp1_ok = 0; static PMBTOKEN_METHOD pmbtoken_exp1_method; static CRYPTO_once_t pmbtoken_exp1_method_once = CRYPTO_ONCE_INIT; @@ -1159,10 +1229,10 @@ static void pmbtoken_exp1_init_method_impl(void) { 0x87, 0xc3, 0x95, 0xd0, 0x13, 0xb7, 0x0b, 0x5c, 0xc7, }; - pmbtoken_exp1_ok = - pmbtoken_init_method(&pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH), - pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s, - pmbtoken_exp1_hash_c, 1); + pmbtoken_exp1_ok = pmbtoken_init_method( + &pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s, pmbtoken_exp1_hash_c, + pmbtoken_exp1_hash_to_scalar, 1); } static int pmbtoken_exp1_init_method(void) { @@ -1182,6 +1252,17 @@ int pmbtoken_exp1_generate_key(CBB *out_private, CBB *out_public) { return pmbtoken_generate_key(&pmbtoken_exp1_method, out_private, out_public); } +int pmbtoken_exp1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!pmbtoken_exp1_init_method()) { + return 0; + } + + return pmbtoken_derive_key_from_secret(&pmbtoken_exp1_method, out_private, + out_public, secret, secret_len); +} + int pmbtoken_exp1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len) { if (!pmbtoken_exp1_init_method()) { @@ -1198,11 +1279,15 @@ int pmbtoken_exp1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp1_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp1_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!pmbtoken_exp1_init_method()) { return NULL; } - return pmbtoken_blind(&pmbtoken_exp1_method, cbb, count); + return pmbtoken_blind(&pmbtoken_exp1_method, cbb, count, include_message, msg, + msg_len); } int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -1215,10 +1300,10 @@ int pmbtoken_exp1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, num_to_issue, private_metadata); } -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp1_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *pmbtoken_exp1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!pmbtoken_exp1_init_method()) { return NULL; } @@ -1229,12 +1314,14 @@ STACK_OF(TRUST_TOKEN) * int pmbtoken_exp1_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { if (!pmbtoken_exp1_init_method()) { return 0; } return pmbtoken_read(&pmbtoken_exp1_method, key, out_nonce, - out_private_metadata, token, token_len); + out_private_metadata, token, token_len, include_message, + msg, msg_len); } int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]) { @@ -1250,14 +1337,14 @@ int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]) { // PMBTokens experiment v2. -static int pmbtoken_exp2_hash_t(const EC_GROUP *group, EC_RAW_POINT *out, +static int pmbtoken_exp2_hash_t(const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { const uint8_t kHashTLabel[] = "PMBTokens Experiment V2 HashT"; return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); } -static int pmbtoken_exp2_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, +static int pmbtoken_exp2_hash_s(const EC_GROUP *group, EC_JACOBIAN *out, const EC_AFFINE *t, const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { const uint8_t kHashSLabel[] = "PMBTokens Experiment V2 HashS"; @@ -1271,7 +1358,6 @@ static int pmbtoken_exp2_hash_s(const EC_GROUP *group, EC_RAW_POINT *out, !CBB_finish(&cbb, &buf, &len) || !ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -1290,6 +1376,13 @@ static int pmbtoken_exp2_hash_c(const EC_GROUP *group, EC_SCALAR *out, group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); } +static int pmbtoken_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashLabel[] = "PMBTokens Experiment V2 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha512_draft07( + group, out, kHashLabel, sizeof(kHashLabel), buf, len); +} + static int pmbtoken_exp2_ok = 0; static PMBTOKEN_METHOD pmbtoken_exp2_method; static CRYPTO_once_t pmbtoken_exp2_method_once = CRYPTO_ONCE_INIT; @@ -1309,10 +1402,10 @@ static void pmbtoken_exp2_init_method_impl(void) { 0x25, 0x62, 0xbf, 0x59, 0xb2, 0xd2, 0x3d, 0x71, 0xff }; - pmbtoken_exp2_ok = - pmbtoken_init_method(&pmbtoken_exp2_method, NID_secp384r1, kH, sizeof(kH), - pmbtoken_exp2_hash_t, pmbtoken_exp2_hash_s, - pmbtoken_exp2_hash_c, 0); + pmbtoken_exp2_ok = pmbtoken_init_method( + &pmbtoken_exp2_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_exp2_hash_t, pmbtoken_exp2_hash_s, pmbtoken_exp2_hash_c, + pmbtoken_exp2_hash_to_scalar, 0); } static int pmbtoken_exp2_init_method(void) { @@ -1332,6 +1425,18 @@ int pmbtoken_exp2_generate_key(CBB *out_private, CBB *out_public) { return pmbtoken_generate_key(&pmbtoken_exp2_method, out_private, out_public); } + +int pmbtoken_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!pmbtoken_exp2_init_method()) { + return 0; + } + + return pmbtoken_derive_key_from_secret(&pmbtoken_exp2_method, out_private, + out_public, secret, secret_len); +} + int pmbtoken_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len) { if (!pmbtoken_exp2_init_method()) { @@ -1348,11 +1453,15 @@ int pmbtoken_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp2_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * pmbtoken_exp2_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!pmbtoken_exp2_init_method()) { return NULL; } - return pmbtoken_blind(&pmbtoken_exp2_method, cbb, count); + return pmbtoken_blind(&pmbtoken_exp2_method, cbb, count, include_message, msg, + msg_len); } int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -1365,10 +1474,10 @@ int pmbtoken_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, num_to_issue, private_metadata); } -STACK_OF(TRUST_TOKEN) * - pmbtoken_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *pmbtoken_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!pmbtoken_exp2_init_method()) { return NULL; } @@ -1379,12 +1488,14 @@ STACK_OF(TRUST_TOKEN) * int pmbtoken_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { if (!pmbtoken_exp2_init_method()) { return 0; } return pmbtoken_read(&pmbtoken_exp2_method, key, out_nonce, - out_private_metadata, token, token_len); + out_private_metadata, token, token_len, include_message, + msg, msg_len); } int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]) { @@ -1397,3 +1508,177 @@ int pmbtoken_exp2_get_h_for_testing(uint8_t out[97]) { ec_point_to_bytes(pmbtoken_exp2_method.group, &h, POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; } + +// PMBTokens PST v1. + +static int pmbtoken_pst1_hash_t(const EC_GROUP *group, EC_JACOBIAN *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "PMBTokens PST V1 HashT"; + return ec_hash_to_curve_p384_xmd_sha384_sswu( + group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE); +} + +static int pmbtoken_pst1_hash_s(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_AFFINE *t, + const uint8_t s[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashSLabel[] = "PMBTokens PST V1 HashS"; + int ret = 0; + CBB cbb; + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !point_to_cbb(&cbb, group, t) || + !CBB_add_bytes(&cbb, s, TRUST_TOKEN_NONCE_SIZE) || + !CBB_finish(&cbb, &buf, &len) || + !ec_hash_to_curve_p384_xmd_sha384_sswu( + group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + CBB_cleanup(&cbb); + return ret; +} + +static int pmbtoken_pst1_hash_c(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "PMBTokens PST V1 HashC"; + return ec_hash_to_scalar_p384_xmd_sha384( + group, out, kHashCLabel, sizeof(kHashCLabel), buf, len); +} + +static int pmbtoken_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashLabel[] = "PMBTokens PST V1 HashToScalar"; + return ec_hash_to_scalar_p384_xmd_sha384( + group, out, kHashLabel, sizeof(kHashLabel), buf, len); +} + +static int pmbtoken_pst1_ok = 0; +static PMBTOKEN_METHOD pmbtoken_pst1_method; +static CRYPTO_once_t pmbtoken_pst1_method_once = CRYPTO_ONCE_INIT; + +static void pmbtoken_pst1_init_method_impl(void) { + // This is the output of |ec_hash_to_scalar_p384_xmd_sha384| with DST + // "PMBTokens PST V1 HashH" and message "generator". + static const uint8_t kH[] = { + 0x04, 0x4c, 0xfa, 0xd4, 0x33, 0x6d, 0x8c, 0x4e, 0x18, 0xce, 0x1a, + 0x82, 0x7b, 0x53, 0x8c, 0xf8, 0x63, 0x18, 0xe5, 0xa3, 0x96, 0x0d, + 0x05, 0xde, 0xf4, 0x83, 0xa7, 0xd8, 0xde, 0x9c, 0x50, 0x81, 0x38, + 0xc9, 0x38, 0x25, 0xa3, 0x70, 0x97, 0xc1, 0x1c, 0x33, 0x2e, 0x83, + 0x68, 0x64, 0x9c, 0x53, 0x73, 0xc3, 0x03, 0xc1, 0xa9, 0xd8, 0x92, + 0xa2, 0x32, 0xf4, 0x22, 0x40, 0x07, 0x2d, 0x9b, 0x6f, 0xab, 0xff, + 0x2a, 0x92, 0x03, 0xb1, 0x73, 0x09, 0x1a, 0x6a, 0x4a, 0xc2, 0x4c, + 0xac, 0x13, 0x59, 0xf4, 0x28, 0x0e, 0x78, 0x69, 0xa5, 0xdf, 0x0d, + 0x74, 0xeb, 0x14, 0xca, 0x8a, 0x32, 0xbb, 0xd3, 0x91 + }; + + pmbtoken_pst1_ok = pmbtoken_init_method( + &pmbtoken_pst1_method, NID_secp384r1, kH, sizeof(kH), + pmbtoken_pst1_hash_t, pmbtoken_pst1_hash_s, pmbtoken_pst1_hash_c, + pmbtoken_pst1_hash_to_scalar, 0); +} + +static int pmbtoken_pst1_init_method(void) { + CRYPTO_once(&pmbtoken_pst1_method_once, pmbtoken_pst1_init_method_impl); + if (!pmbtoken_pst1_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int pmbtoken_pst1_generate_key(CBB *out_private, CBB *out_public) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + + return pmbtoken_generate_key(&pmbtoken_pst1_method, out_private, out_public); +} + + +int pmbtoken_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + + return pmbtoken_derive_key_from_secret(&pmbtoken_pst1_method, out_private, + out_public, secret, secret_len); +} + +int pmbtoken_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_client_key_from_bytes(&pmbtoken_pst1_method, key, in, len); +} + +int pmbtoken_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_issuer_key_from_bytes(&pmbtoken_pst1_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) *pmbtoken_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + if (!pmbtoken_pst1_init_method()) { + return NULL; + } + return pmbtoken_blind(&pmbtoken_pst1_method, cbb, count, include_message, msg, + msg_len); +} + +int pmbtoken_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_sign(&pmbtoken_pst1_method, key, cbb, cbs, num_requested, + num_to_issue, private_metadata); +} + +STACK_OF(TRUST_TOKEN) *pmbtoken_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { + if (!pmbtoken_pst1_init_method()) { + return NULL; + } + return pmbtoken_unblind(&pmbtoken_pst1_method, key, pretokens, cbs, count, + key_id); +} + +int pmbtoken_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, + const uint8_t *msg, size_t msg_len) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + return pmbtoken_read(&pmbtoken_pst1_method, key, out_nonce, + out_private_metadata, token, token_len, include_message, + msg, msg_len); +} + +int pmbtoken_pst1_get_h_for_testing(uint8_t out[97]) { + if (!pmbtoken_pst1_init_method()) { + return 0; + } + EC_AFFINE h; + return ec_jacobian_to_affine(pmbtoken_pst1_method.group, &h, + &pmbtoken_pst1_method.h) && + ec_point_to_bytes(pmbtoken_pst1_method.group, &h, + POINT_CONVERSION_UNCOMPRESSED, out, 97) == 97; +} diff --git a/third_party/boringssl/kit/src/crypto/trust_token/trust_token.c b/third_party/boringssl/kit/src/crypto/trust_token/trust_token.c index 3334fba8..93172c37 100644 --- a/third_party/boringssl/kit/src/crypto/trust_token/trust_token.c +++ b/third_party/boringssl/kit/src/crypto/trust_token/trust_token.c @@ -30,6 +30,7 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) { static const TRUST_TOKEN_METHOD kMethod = { pmbtoken_exp1_generate_key, + pmbtoken_exp1_derive_key_from_secret, pmbtoken_exp1_client_key_from_bytes, pmbtoken_exp1_issuer_key_from_bytes, pmbtoken_exp1_blind, @@ -46,6 +47,7 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) { const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) { static const TRUST_TOKEN_METHOD kMethod = { voprf_exp2_generate_key, + voprf_exp2_derive_key_from_secret, voprf_exp2_client_key_from_bytes, voprf_exp2_issuer_key_from_bytes, voprf_exp2_blind, @@ -62,6 +64,7 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void) { const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) { static const TRUST_TOKEN_METHOD kMethod = { pmbtoken_exp2_generate_key, + pmbtoken_exp2_derive_key_from_secret, pmbtoken_exp2_client_key_from_bytes, pmbtoken_exp2_issuer_key_from_bytes, pmbtoken_exp2_blind, @@ -75,6 +78,41 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void) { return &kMethod; } +const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void) { + static const TRUST_TOKEN_METHOD kMethod = { + voprf_pst1_generate_key, + voprf_pst1_derive_key_from_secret, + voprf_pst1_client_key_from_bytes, + voprf_pst1_issuer_key_from_bytes, + voprf_pst1_blind, + voprf_pst1_sign, + voprf_pst1_unblind, + voprf_pst1_read, + 0, /* has_private_metadata */ + 6, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + +const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void) { + static const TRUST_TOKEN_METHOD kMethod = { + pmbtoken_pst1_generate_key, + pmbtoken_pst1_derive_key_from_secret, + pmbtoken_pst1_client_key_from_bytes, + pmbtoken_pst1_issuer_key_from_bytes, + pmbtoken_pst1_blind, + pmbtoken_pst1_sign, + pmbtoken_pst1_unblind, + pmbtoken_pst1_read, + 1, /* has_private_metadata */ + 3, /* max_keys */ + 0, /* has_srr */ + }; + return &kMethod; +} + + void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) { OPENSSL_free(pretoken); } @@ -82,13 +120,11 @@ void TRUST_TOKEN_PRETOKEN_free(TRUST_TOKEN_PRETOKEN *pretoken) { TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) { TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN)); ret->data = OPENSSL_memdup(data, len); if (len != 0 && ret->data == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -110,34 +146,55 @@ int TRUST_TOKEN_generate_key(const TRUST_TOKEN_METHOD *method, size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id) { // Prepend the key ID in front of the PMBTokens format. - int ret = 0; CBB priv_cbb, pub_cbb; - CBB_zero(&priv_cbb); - CBB_zero(&pub_cbb); - if (!CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len) || - !CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len) || - !CBB_add_u32(&priv_cbb, id) || + CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len); + CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len); + if (!CBB_add_u32(&priv_cbb, id) || // !CBB_add_u32(&pub_cbb, id)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } if (!method->generate_key(&priv_cbb, &pub_cbb)) { - goto err; + return 0; } if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) || !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); - goto err; + return 0; } - ret = 1; + return 1; +} -err: - CBB_cleanup(&priv_cbb); - CBB_cleanup(&pub_cbb); - return ret; +int TRUST_TOKEN_derive_key_from_secret( + const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key, + size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, + size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id, + const uint8_t *secret, size_t secret_len) { + // Prepend the key ID in front of the PMBTokens format. + CBB priv_cbb, pub_cbb; + CBB_init_fixed(&priv_cbb, out_priv_key, max_priv_key_len); + CBB_init_fixed(&pub_cbb, out_pub_key, max_pub_key_len); + if (!CBB_add_u32(&priv_cbb, id) || // + !CBB_add_u32(&pub_cbb, id)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!method->derive_key_from_secret(&priv_cbb, &pub_cbb, secret, + secret_len)) { + return 0; + } + + if (!CBB_finish(&priv_cbb, NULL, out_priv_key_len) || + !CBB_finish(&pub_cbb, NULL, out_pub_key_len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); + return 0; + } + + return 1; } TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, @@ -150,7 +207,6 @@ TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(const TRUST_TOKEN_METHOD *method, TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT)); @@ -202,8 +258,9 @@ int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) { return 1; } -int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, - size_t *out_len, size_t count) { +static int trust_token_client_begin_issuance_impl( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + int include_message, const uint8_t *msg, size_t msg_len) { if (count > ctx->max_batchsize) { count = ctx->max_batchsize; } @@ -213,17 +270,16 @@ int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = NULL; if (!CBB_init(&request, 0) || !CBB_add_u16(&request, count)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } - pretokens = ctx->method->blind(&request, count); + pretokens = + ctx->method->blind(&request, count, include_message, msg, msg_len); if (pretokens == NULL) { goto err; } if (!CBB_finish(&request, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -238,6 +294,20 @@ err: return ret; } +int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, + size_t *out_len, size_t count) { + return trust_token_client_begin_issuance_impl(ctx, out, out_len, count, + /*include_message=*/0, NULL, 0); +} + +int TRUST_TOKEN_CLIENT_begin_issuance_over_message( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + const uint8_t *msg, size_t msg_len) { + return trust_token_client_begin_issuance_impl( + ctx, out, out_len, count, /*include_message=*/1, msg, msg_len); +} + + STACK_OF(TRUST_TOKEN) * TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, @@ -305,7 +375,6 @@ int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out, !CBB_add_bytes(&inner, data, data_len) || (ctx->method->has_srr && !CBB_add_u64(&request, time)) || !CBB_finish(&request, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); CBB_cleanup(&request); return 0; } @@ -321,7 +390,6 @@ int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx, CBS_init(&in, response, response_len); if (!ctx->method->has_srr) { if (!CBS_stow(&in, out_rr, out_rr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } @@ -358,7 +426,6 @@ int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx, size_t srr_len, sig_len; if (!CBS_stow(&srr, &srr_buf, &srr_len) || !CBS_stow(&sig, &sig_buf, &sig_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); OPENSSL_free(srr_buf); OPENSSL_free(sig_buf); return 0; @@ -381,7 +448,6 @@ TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(const TRUST_TOKEN_METHOD *method, TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER)); if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return NULL; } OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER)); @@ -439,7 +505,6 @@ int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx, ctx->metadata_key_len = 0; ctx->metadata_key = OPENSSL_memdup(key, len); if (ctx->metadata_key == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ctx->metadata_key_len = len; @@ -491,7 +556,6 @@ int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, if (!CBB_init(&response, 0) || !CBB_add_u16(&response, num_to_issue) || !CBB_add_u32(&response, public_metadata)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -506,7 +570,6 @@ int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, } if (!CBB_finish(&response, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -518,13 +581,11 @@ err: return ret; } - -int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, - uint32_t *out_public, uint8_t *out_private, - TRUST_TOKEN **out_token, - uint8_t **out_client_data, - size_t *out_client_data_len, - const uint8_t *request, size_t request_len) { +static int trust_token_issuer_redeem_impl( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + int include_message, const uint8_t *msg, size_t msg_len) { CBS request_cbs, token_cbs; CBS_init(&request_cbs, request, request_len); if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { @@ -546,7 +607,8 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; if (key == NULL || !ctx->method->read(&key->key, nonce, &private_metadata, - CBS_data(&token_cbs), CBS_len(&token_cbs))) { + CBS_data(&token_cbs), CBS_len(&token_cbs), + include_message, msg, msg_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); return 0; } @@ -562,13 +624,11 @@ int TRUST_TOKEN_ISSUER_redeem_raw(const TRUST_TOKEN_ISSUER *ctx, uint8_t *client_data_buf = NULL; size_t client_data_len = 0; if (!CBS_stow(&client_data, &client_data_buf, &client_data_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); if (token == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } *out_public = public_metadata; @@ -584,48 +644,26 @@ err: return 0; } -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type, - uint64_t value) { - if (value <= 23) { - return CBB_add_u8(cbb, value | major_type); - } - if (value <= 0xff) { - return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value); - } - if (value <= 0xffff) { - return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value); - } - if (value <= 0xffffffff) { - return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value); - } - if (value <= 0xffffffffffffffff) { - return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value); - } - return 0; +int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, + uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, + uint8_t **out_client_data, + size_t *out_client_data_len, + const uint8_t *request, size_t request_len) { + return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token, + out_client_data, out_client_data_len, + request, request_len, 0, NULL, 0); } -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_int(CBB *cbb, uint64_t value) { - return add_cbor_int_with_type(cbb, 0, value); -} - -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_bytes(CBB *cbb, const uint8_t *data, size_t len) { - return add_cbor_int_with_type(cbb, 0x40, len) && - CBB_add_bytes(cbb, data, len); -} - -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_text(CBB *cbb, const char *data, size_t len) { - return add_cbor_int_with_type(cbb, 0x60, len) && - CBB_add_bytes(cbb, (const uint8_t *)data, len); -} - -// https://tools.ietf.org/html/rfc7049#section-2.1 -static int add_cbor_map(CBB *cbb, uint8_t size) { - return add_cbor_int_with_type(cbb, 0xa0, size); +int TRUST_TOKEN_ISSUER_redeem_over_message( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + const uint8_t *msg, size_t msg_len) { + return trust_token_issuer_redeem_impl(ctx, out_public, out_private, out_token, + out_client_data, out_client_data_len, + request, request_len, 1, msg, msg_len); } static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len, @@ -640,212 +678,6 @@ static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len, return metadata_obfuscator[0] >> 7; } -int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, - size_t *out_len, TRUST_TOKEN **out_token, - uint8_t **out_client_data, - size_t *out_client_data_len, - uint64_t *out_redemption_time, - const uint8_t *request, size_t request_len, - uint64_t lifetime) { - CBS request_cbs, token_cbs; - CBS_init(&request_cbs, request, request_len); - if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); - return 0; - } - - uint32_t public_metadata = 0; - uint8_t private_metadata = 0; - - CBS token_copy = token_cbs; - - // Parse the token. If there is an error, treat it as an invalid token. - if (!CBS_get_u32(&token_cbs, &public_metadata)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); - return 0; - } - - const struct trust_token_issuer_key_st *key = - trust_token_issuer_get_key(ctx, public_metadata); - uint8_t nonce[TRUST_TOKEN_NONCE_SIZE]; - if (key == NULL || - !ctx->method->read(&key->key, nonce, &private_metadata, - CBS_data(&token_cbs), CBS_len(&token_cbs))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); - return 0; - } - - int ok = 0; - CBB response, srr; - uint8_t *srr_buf = NULL, *sig_buf = NULL, *client_data_buf = NULL; - size_t srr_len = 0, sig_len = 0, client_data_len = 0; - EVP_MD_CTX md_ctx; - EVP_MD_CTX_init(&md_ctx); - CBB_zero(&srr); - if (!CBB_init(&response, 0)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - CBS client_data; - uint64_t redemption_time = 0; - if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) || - (ctx->method->has_srr && !CBS_get_u64(&request_cbs, &redemption_time))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR); - goto err; - } - - const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; - uint8_t token_hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha_ctx; - SHA256_Init(&sha_ctx); - SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); - SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy)); - SHA256_Final(token_hash, &sha_ctx); - - uint8_t metadata_obfuscator = get_metadata_obfuscator( - ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash)); - - // The SRR is constructed as per the format described in - // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5 - - // The V2 protocol is intended to be used with - // |TRUST_TOKEN_ISSUER_redeem_raw|. However, we temporarily support it with - // |TRUST_TOKEN_ISSUER_redeem| to ease the transition for existing issuer - // callers. Those callers' consumers currently expect an expiry-timestamp - // field, so we fill in a placeholder value. - // - // TODO(svaldez): After the existing issues have migrated to - // |TRUST_TOKEN_ISSUER_redeem_raw| remove this logic. - uint64_t expiry_time = 0; - if (ctx->method->has_srr) { - expiry_time = redemption_time + lifetime; - } - - static const char kClientDataLabel[] = "client-data"; - static const char kExpiryTimestampLabel[] = "expiry-timestamp"; - static const char kMetadataLabel[] = "metadata"; - static const char kPrivateLabel[] = "private"; - static const char kPublicLabel[] = "public"; - static const char kTokenHashLabel[] = "token-hash"; - - // CBOR requires map keys to be sorted by length then sorted lexically. - // https://tools.ietf.org/html/rfc7049#section-3.9 - assert(strlen(kMetadataLabel) < strlen(kTokenHashLabel)); - assert(strlen(kTokenHashLabel) < strlen(kClientDataLabel)); - assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel)); - assert(strlen(kPublicLabel) < strlen(kPrivateLabel)); - - size_t map_entries = 4; - - if (!CBB_init(&srr, 0) || - !add_cbor_map(&srr, map_entries) || // SRR map - !add_cbor_text(&srr, kMetadataLabel, strlen(kMetadataLabel)) || - !add_cbor_map(&srr, 2) || // Metadata map - !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) || - !add_cbor_int(&srr, public_metadata) || - !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) || - !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) || - !add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) || - !add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) || - !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) || - !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) || - !add_cbor_text(&srr, kExpiryTimestampLabel, - strlen(kExpiryTimestampLabel)) || - !add_cbor_int(&srr, expiry_time) || - !CBB_finish(&srr, &srr_buf, &srr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestSignInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) || - !EVP_DigestSign(&md_ctx, NULL, &sig_len, srr_buf, srr_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR); - goto err; - } - - // Merge SRR and Signature into single string. - // TODO(svaldez): Expose API to construct this from the caller. - if (!ctx->method->has_srr) { - static const char kSRRHeader[] = "body=:"; - static const char kSRRSplit[] = ":, signature=:"; - static const char kSRREnd[] = ":"; - - size_t srr_b64_len, sig_b64_len; - if (!EVP_EncodedLength(&srr_b64_len, srr_len) || - !EVP_EncodedLength(&sig_b64_len, sig_len)) { - goto err; - } - - sig_buf = OPENSSL_malloc(sig_len); - uint8_t *srr_b64_buf = OPENSSL_malloc(srr_b64_len); - uint8_t *sig_b64_buf = OPENSSL_malloc(sig_b64_len); - if (!sig_buf || - !srr_b64_buf || - !sig_b64_buf || - !EVP_DigestSign(&md_ctx, sig_buf, &sig_len, srr_buf, srr_len) || - !CBB_add_bytes(&response, (const uint8_t *)kSRRHeader, - strlen(kSRRHeader)) || - !CBB_add_bytes(&response, srr_b64_buf, - EVP_EncodeBlock(srr_b64_buf, srr_buf, srr_len)) || - !CBB_add_bytes(&response, (const uint8_t *)kSRRSplit, - strlen(kSRRSplit)) || - !CBB_add_bytes(&response, sig_b64_buf, - EVP_EncodeBlock(sig_b64_buf, sig_buf, sig_len)) || - !CBB_add_bytes(&response, (const uint8_t *)kSRREnd, strlen(kSRREnd))) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - OPENSSL_free(srr_b64_buf); - OPENSSL_free(sig_b64_buf); - goto err; - } - - OPENSSL_free(srr_b64_buf); - OPENSSL_free(sig_b64_buf); - } else { - CBB child; - uint8_t *ptr; - if (!CBB_add_u16_length_prefixed(&response, &child) || - !CBB_add_bytes(&child, srr_buf, srr_len) || - !CBB_add_u16_length_prefixed(&response, &child) || - !CBB_reserve(&child, &ptr, sig_len) || - !EVP_DigestSign(&md_ctx, ptr, &sig_len, srr_buf, srr_len) || - !CBB_did_write(&child, sig_len) || - !CBB_flush(&response)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!CBS_stow(&client_data, &client_data_buf, &client_data_len) || - !CBB_finish(&response, out, out_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - - TRUST_TOKEN *token = TRUST_TOKEN_new(nonce, TRUST_TOKEN_NONCE_SIZE); - if (token == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); - goto err; - } - *out_token = token; - *out_client_data = client_data_buf; - *out_client_data_len = client_data_len; - *out_redemption_time = redemption_time; - - ok = 1; - -err: - CBB_cleanup(&response); - CBB_cleanup(&srr); - OPENSSL_free(srr_buf); - OPENSSL_free(sig_buf); - EVP_MD_CTX_cleanup(&md_ctx); - if (!ok) { - OPENSSL_free(client_data_buf); - } - return ok; -} - int TRUST_TOKEN_decode_private_metadata(const TRUST_TOKEN_METHOD *method, uint8_t *out_value, const uint8_t *key, size_t key_len, const uint8_t *nonce, diff --git a/third_party/boringssl/kit/src/crypto/trust_token/trust_token_test.cc b/third_party/boringssl/kit/src/crypto/trust_token/trust_token_test.cc index f9f183d9..df679b61 100644 --- a/third_party/boringssl/kit/src/crypto/trust_token/trust_token_test.cc +++ b/third_party/boringssl/kit/src/crypto/trust_token/trust_token_test.cc @@ -12,6 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -44,6 +45,8 @@ BSSL_NAMESPACE_BEGIN namespace { +const uint8_t kMessage[] = "MSG"; + TEST(TrustTokenTest, KeyGenExp1) { uint8_t priv_key[TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE]; uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE]; @@ -54,6 +57,73 @@ TEST(TrustTokenTest, KeyGenExp1) { TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001)); ASSERT_EQ(292u, priv_key_len); ASSERT_EQ(301u, pub_key_len); + + const uint8_t kKeygenSecret[] = "SEED"; + ASSERT_TRUE(TRUST_TOKEN_derive_key_from_secret( + TRUST_TOKEN_experiment_v1(), priv_key, &priv_key_len, + TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, &pub_key_len, + TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001, kKeygenSecret, + sizeof(kKeygenSecret) - 1)); + + const uint8_t kExpectedPriv[] = { + 0x00, 0x00, 0x00, 0x01, 0x98, 0xaa, 0x32, 0xfc, 0x5f, 0x83, 0x35, 0xea, + 0x57, 0x4f, 0x9e, 0x61, 0x48, 0x6e, 0x89, 0x9d, 0x3d, 0xaa, 0x38, 0x5d, + 0xd0, 0x06, 0x96, 0x62, 0xe8, 0x0b, 0xd6, 0x5f, 0x12, 0xa4, 0xcc, 0xa9, + 0xb5, 0x20, 0x1b, 0x13, 0x8c, 0x1c, 0xaf, 0x36, 0x1b, 0xab, 0x0c, 0xc6, + 0xac, 0x38, 0xae, 0x96, 0x3d, 0x14, 0x9d, 0xb8, 0x8d, 0xf4, 0x7f, 0xe2, + 0x7d, 0xeb, 0x17, 0xc2, 0xbc, 0x63, 0x42, 0x93, 0x94, 0xe4, 0x97, 0xbf, + 0x97, 0xea, 0x02, 0x40, 0xac, 0xb6, 0xa5, 0x03, 0x4c, 0x6b, 0x4c, 0xb8, + 0x8c, 0xf4, 0x66, 0x1b, 0x4e, 0x02, 0x45, 0xf9, 0xcd, 0xb6, 0x0f, 0x59, + 0x09, 0x21, 0x03, 0x7e, 0x92, 0x1f, 0x3f, 0x40, 0x83, 0x50, 0xe3, 0xdc, + 0x9e, 0x6f, 0x65, 0xc5, 0xbd, 0x2c, 0x7d, 0xab, 0x74, 0x49, 0xc8, 0xa2, + 0x3c, 0xab, 0xcb, 0x4d, 0x63, 0x73, 0x81, 0x2b, 0xb2, 0x1e, 0x00, 0x8f, + 0x00, 0xb8, 0xd8, 0xb4, 0x5d, 0xc4, 0x3f, 0x3d, 0xa8, 0x4f, 0x4c, 0x72, + 0x0e, 0x20, 0x17, 0x4b, 0xac, 0x14, 0x8f, 0xb2, 0xa5, 0x20, 0x41, 0x2b, + 0xf7, 0x62, 0x25, 0x6a, 0xd6, 0x41, 0x26, 0x62, 0x10, 0xc1, 0xbc, 0x42, + 0xac, 0x54, 0x1b, 0x75, 0x05, 0xd6, 0x53, 0xb1, 0x7b, 0x84, 0x6a, 0x7b, + 0x5b, 0x2a, 0x34, 0x6e, 0x43, 0x4b, 0x43, 0xcc, 0x6c, 0xdb, 0x1d, 0x02, + 0x34, 0x7f, 0xd1, 0xe8, 0xfd, 0x42, 0x2c, 0xd9, 0x14, 0xdb, 0xd6, 0xf4, + 0xad, 0xb5, 0xe4, 0xac, 0xdd, 0x7e, 0xb5, 0x4c, 0x3f, 0x59, 0x24, 0xfa, + 0x04, 0xd9, 0xb6, 0xd2, 0xb7, 0x7d, 0xf1, 0xfa, 0x13, 0xc0, 0x4d, 0xd5, + 0xca, 0x3a, 0x4e, 0xa8, 0xdd, 0xa9, 0xfc, 0xcb, 0x06, 0xb2, 0xde, 0x4b, + 0x2a, 0x86, 0xbb, 0x0d, 0x41, 0xb6, 0x3d, 0xfb, 0x49, 0xc8, 0xdf, 0x9a, + 0x48, 0xe5, 0x68, 0x8a, 0xfc, 0x86, 0x9c, 0x79, 0x5a, 0x79, 0xc1, 0x09, + 0x33, 0x53, 0xdc, 0x3d, 0xe9, 0x93, 0x7c, 0x5b, 0x72, 0xf7, 0xa0, 0x8a, + 0x1f, 0x07, 0x6c, 0x38, 0x3c, 0x99, 0x0b, 0xe4, 0x4e, 0xa4, 0xbd, 0x41, + 0x1f, 0x83, 0xa6, 0xd3 + }; + ASSERT_EQ(Bytes(kExpectedPriv, sizeof(kExpectedPriv)), + Bytes(priv_key, priv_key_len)); + + const uint8_t kExpectedPub[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x61, 0x04, 0x5e, 0x06, 0x6b, 0x7b, 0xfd, + 0x54, 0x01, 0xe0, 0xd2, 0xb5, 0x12, 0xce, 0x48, 0x16, 0x66, 0xb2, 0xdf, + 0xfd, 0xa8, 0x38, 0x7c, 0x1f, 0x45, 0x1a, 0xb8, 0x21, 0x52, 0x17, 0x25, + 0xbb, 0x0b, 0x00, 0xd4, 0xa1, 0xbc, 0x28, 0xd9, 0x08, 0x36, 0x98, 0xb2, + 0x17, 0xd3, 0xb5, 0xad, 0xb6, 0x4e, 0x03, 0x5f, 0xd3, 0x66, 0x2c, 0x58, + 0x1c, 0xcc, 0xc6, 0x23, 0xa4, 0xf9, 0xa2, 0x7e, 0xb0, 0xe4, 0xd3, 0x95, + 0x41, 0x6f, 0xba, 0x23, 0x4a, 0x82, 0x93, 0x29, 0x73, 0x75, 0x38, 0x85, + 0x64, 0x9c, 0xaa, 0x12, 0x6d, 0x7d, 0xcd, 0x52, 0x02, 0x91, 0x9f, 0xa9, + 0xee, 0x4b, 0xfd, 0x68, 0x97, 0x40, 0xdc, 0x00, 0x61, 0x04, 0x14, 0x16, + 0x39, 0xf9, 0x63, 0x66, 0x94, 0x03, 0xfa, 0x0b, 0xbf, 0xca, 0x5a, 0x39, + 0x9f, 0x27, 0x5b, 0x3f, 0x69, 0x7a, 0xc9, 0xf7, 0x25, 0x7c, 0x84, 0x9e, + 0x1d, 0x61, 0x5a, 0x24, 0x53, 0xf2, 0x4a, 0x9d, 0xe9, 0x05, 0x53, 0xfd, + 0x12, 0x01, 0x2d, 0x9a, 0x69, 0x50, 0x74, 0x82, 0xa3, 0x45, 0x73, 0xdc, + 0x34, 0x36, 0x31, 0x44, 0x07, 0x0c, 0xda, 0x13, 0xbe, 0x94, 0x37, 0x65, + 0xa0, 0xab, 0x16, 0x52, 0x90, 0xe5, 0x8a, 0x03, 0xe5, 0x98, 0x79, 0x14, + 0x79, 0xd5, 0x17, 0xee, 0xd4, 0xb8, 0xda, 0x77, 0x76, 0x03, 0x20, 0x2a, + 0x7e, 0x3b, 0x76, 0x0b, 0x23, 0xb7, 0x72, 0x77, 0xb2, 0xeb, 0x00, 0x61, + 0x04, 0x68, 0x18, 0x4d, 0x23, 0x23, 0xf4, 0x45, 0xb8, 0x81, 0x0d, 0xa4, + 0x5d, 0x0b, 0x9e, 0x08, 0xfb, 0x45, 0xfb, 0x96, 0x29, 0x43, 0x2f, 0xab, + 0x93, 0x04, 0x4c, 0x04, 0xb6, 0x5e, 0x27, 0xf5, 0x39, 0x66, 0x94, 0x15, + 0x1d, 0xb1, 0x1c, 0x7c, 0x27, 0x6f, 0xa5, 0x19, 0x0c, 0x30, 0x12, 0xcc, + 0x77, 0x7f, 0x10, 0xa9, 0x7c, 0xe4, 0x08, 0x77, 0x3c, 0xd3, 0x6f, 0xa4, + 0xf4, 0xaf, 0xf1, 0x9d, 0x14, 0x1d, 0xd0, 0x02, 0x33, 0x50, 0x55, 0x00, + 0x6a, 0x47, 0x96, 0xe1, 0x8b, 0x4e, 0x44, 0x41, 0xad, 0xb3, 0xea, 0x0d, + 0x0d, 0xd5, 0x73, 0x8e, 0x62, 0x67, 0x8a, 0xb4, 0xe7, 0x5d, 0x17, 0xa9, + 0x24}; + ASSERT_EQ(Bytes(kExpectedPub, sizeof(kExpectedPub)), + Bytes(pub_key, pub_key_len)); } TEST(TrustTokenTest, KeyGenExp2VOPRF) { @@ -66,6 +136,37 @@ TEST(TrustTokenTest, KeyGenExp2VOPRF) { TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001)); ASSERT_EQ(52u, priv_key_len); ASSERT_EQ(101u, pub_key_len); + + const uint8_t kKeygenSecret[] = "SEED"; + ASSERT_TRUE(TRUST_TOKEN_derive_key_from_secret( + TRUST_TOKEN_experiment_v2_voprf(), priv_key, &priv_key_len, + TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, &pub_key_len, + TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001, kKeygenSecret, + sizeof(kKeygenSecret) - 1)); + + const uint8_t kExpectedPriv[] = { + 0x00, 0x00, 0x00, 0x01, 0x0b, 0xe2, 0xc4, 0x73, 0x92, 0xe7, 0xf8, + 0x3e, 0xba, 0xab, 0x85, 0xa7, 0x77, 0xd7, 0x0a, 0x02, 0xc5, 0x36, + 0xfe, 0x62, 0xa3, 0xca, 0x01, 0x75, 0xc7, 0x62, 0x19, 0xc7, 0xf0, + 0x30, 0xc5, 0x14, 0x60, 0x13, 0x97, 0x4f, 0x63, 0x05, 0x37, 0x92, + 0x7b, 0x76, 0x8e, 0x9f, 0xd0, 0x1a, 0x74, 0x44 + }; + ASSERT_EQ(Bytes(kExpectedPriv, sizeof(kExpectedPriv)), + Bytes(priv_key, priv_key_len)); + + const uint8_t kExpectedPub[] = { + 0x00, 0x00, 0x00, 0x01, 0x04, 0x2c, 0x9c, 0x11, 0xc1, 0xe5, 0x52, 0x59, + 0x0b, 0x6d, 0x88, 0x8b, 0x6e, 0x28, 0xe8, 0xc5, 0xa3, 0xbe, 0x48, 0x18, + 0xf7, 0x1d, 0x31, 0xcf, 0xa2, 0x6e, 0x2a, 0xd6, 0xcb, 0x83, 0x26, 0x04, + 0xbd, 0x93, 0x67, 0xe4, 0x53, 0xf6, 0x11, 0x7d, 0x45, 0xe9, 0xfe, 0x27, + 0x33, 0x90, 0xdb, 0x1b, 0xfc, 0x9b, 0x31, 0x4d, 0x39, 0x1f, 0x1f, 0x8c, + 0x43, 0x06, 0x70, 0x2c, 0x84, 0xdc, 0x23, 0x18, 0xc7, 0x6a, 0x58, 0xcf, + 0x9e, 0xc1, 0xfa, 0xf2, 0x30, 0xdd, 0xad, 0x62, 0x24, 0xde, 0x11, 0xc1, + 0xba, 0x8d, 0xc3, 0x4f, 0xfb, 0xe5, 0xa5, 0xd4, 0x37, 0xba, 0x3b, 0x70, + 0xc0, 0xc3, 0xef, 0x20, 0x43 + }; + ASSERT_EQ(Bytes(kExpectedPub, sizeof(kExpectedPub)), + Bytes(pub_key, pub_key_len)); } TEST(TrustTokenTest, KeyGenExp2PMB) { @@ -78,6 +179,73 @@ TEST(TrustTokenTest, KeyGenExp2PMB) { TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001)); ASSERT_EQ(292u, priv_key_len); ASSERT_EQ(295u, pub_key_len); + + const uint8_t kKeygenSecret[] = "SEED"; + ASSERT_TRUE(TRUST_TOKEN_derive_key_from_secret( + TRUST_TOKEN_experiment_v2_pmb(), priv_key, &priv_key_len, + TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, &pub_key_len, + TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001, kKeygenSecret, + sizeof(kKeygenSecret) - 1)); + + const uint8_t kExpectedPriv[] = { + 0x00, 0x00, 0x00, 0x01, 0x1b, 0x74, 0xdc, 0xf0, 0xa9, 0xa7, 0x6c, 0xfb, + 0x41, 0xef, 0xfa, 0x65, 0x52, 0xc9, 0x86, 0x4e, 0xfb, 0x16, 0x9d, 0xea, + 0x62, 0x3f, 0x47, 0xab, 0x1f, 0x1b, 0x05, 0xf2, 0x4f, 0x05, 0xfe, 0x64, + 0xb7, 0xe8, 0xcd, 0x2a, 0x10, 0xfa, 0xa2, 0x48, 0x3f, 0x0e, 0x8b, 0x94, + 0x39, 0xf1, 0xe7, 0x53, 0xe9, 0x50, 0x29, 0xe2, 0xb7, 0x0e, 0xc0, 0x94, + 0xa9, 0xd3, 0xef, 0x64, 0x10, 0x1d, 0x08, 0xd0, 0x60, 0xcb, 0x6d, 0x97, + 0x68, 0xc7, 0x04, 0x92, 0x07, 0xb2, 0x22, 0x83, 0xf7, 0xd9, 0x9b, 0x2c, + 0xf2, 0x52, 0x34, 0x0c, 0x42, 0x31, 0x47, 0x41, 0x19, 0xb9, 0xee, 0xfc, + 0x46, 0xbd, 0x14, 0xce, 0x42, 0xd7, 0x43, 0xc8, 0x32, 0x3b, 0x24, 0xed, + 0xdc, 0x69, 0xa3, 0x8e, 0x29, 0x01, 0xbe, 0xae, 0x24, 0x39, 0x14, 0xa7, + 0x52, 0xe5, 0xd5, 0xff, 0x9a, 0xc4, 0x15, 0x79, 0x29, 0x4c, 0x9b, 0x4e, + 0xfc, 0x61, 0xf2, 0x12, 0x6f, 0x4f, 0xd3, 0x96, 0x28, 0xb0, 0x79, 0xf0, + 0x4e, 0x6e, 0x7d, 0x56, 0x19, 0x1b, 0xc2, 0xd7, 0xf9, 0x3a, 0x58, 0x06, + 0xe5, 0xec, 0xa4, 0x33, 0x14, 0x1c, 0x78, 0x0c, 0x83, 0x94, 0x34, 0x22, + 0x5a, 0x8e, 0x2e, 0xa1, 0x72, 0x4a, 0x03, 0x35, 0xfe, 0x46, 0x92, 0x41, + 0x6b, 0xe6, 0x4b, 0x3f, 0xf0, 0xe7, 0x0b, 0xb5, 0xf3, 0x66, 0x6c, 0xc6, + 0x14, 0xcf, 0xce, 0x32, 0x0a, 0x2c, 0x28, 0xba, 0x4e, 0xb9, 0x75, 0x4a, + 0xa9, 0x2d, 0xb0, 0x8c, 0xd0, 0x62, 0x52, 0x29, 0x1f, 0x12, 0xfd, 0xfb, + 0xd3, 0x2a, 0x36, 0x0f, 0x89, 0x32, 0x86, 0x25, 0x56, 0xb9, 0xe7, 0x3c, + 0xeb, 0xb4, 0x84, 0x41, 0x2b, 0xa8, 0xf3, 0xa5, 0x3d, 0xfe, 0x56, 0x94, + 0x5b, 0x74, 0xb3, 0x5b, 0x27, 0x3f, 0xe7, 0xcf, 0xe4, 0xf8, 0x15, 0x95, + 0x2a, 0xd2, 0x5f, 0x92, 0xb4, 0x6a, 0x89, 0xa5, 0x54, 0xbd, 0x27, 0x5e, + 0xeb, 0x43, 0x07, 0x9b, 0x2b, 0x8b, 0x22, 0x59, 0x13, 0x4b, 0x9c, 0x56, + 0xd8, 0x63, 0xd9, 0xe6, 0x85, 0x15, 0x2c, 0x82, 0x52, 0x40, 0x8f, 0xb1, + 0xe7, 0x56, 0x07, 0x98 + }; + ASSERT_EQ(Bytes(kExpectedPriv, sizeof(kExpectedPriv)), + Bytes(priv_key, priv_key_len)); + + const uint8_t kExpectedPub[] = { + 0x00, 0x00, 0x00, 0x01, 0x04, 0x48, 0xb1, 0x2d, 0xdd, 0x03, 0x32, 0xeb, + 0x93, 0x31, 0x3d, 0x59, 0x74, 0xf0, 0xcf, 0xaa, 0xa5, 0x39, 0x5f, 0x53, + 0xc4, 0x94, 0x98, 0xbe, 0x8f, 0x22, 0xd7, 0x30, 0xde, 0x1e, 0xb4, 0xf3, + 0x32, 0x23, 0x90, 0x0b, 0xa6, 0x37, 0x4a, 0x4b, 0x44, 0xb3, 0x26, 0x52, + 0x93, 0x7b, 0x4b, 0xa4, 0x79, 0xe8, 0x77, 0x6a, 0x19, 0x81, 0x2a, 0xdd, + 0x91, 0xfb, 0x90, 0x8b, 0x24, 0xb5, 0xbe, 0x20, 0x2e, 0xe8, 0xbc, 0xd3, + 0x83, 0x6c, 0xa8, 0xc5, 0xa1, 0x9a, 0x5b, 0x5e, 0x60, 0xda, 0x45, 0x2e, + 0x31, 0x7f, 0x54, 0x0e, 0x14, 0x40, 0xd2, 0x4d, 0x40, 0x2e, 0x21, 0x79, + 0xfc, 0x77, 0xdd, 0xc7, 0x2d, 0x04, 0xfe, 0xc6, 0xe3, 0xcf, 0x99, 0xef, + 0x88, 0xab, 0x76, 0x86, 0x16, 0x14, 0xed, 0x72, 0x35, 0xa7, 0x05, 0x13, + 0x9f, 0x2c, 0x53, 0xd5, 0xdf, 0x66, 0x75, 0x2e, 0x68, 0xdc, 0xd4, 0xc4, + 0x00, 0x36, 0x08, 0x6d, 0xb7, 0x15, 0xf7, 0xe5, 0x32, 0x59, 0x81, 0x16, + 0x57, 0xaa, 0x72, 0x06, 0xf0, 0xad, 0xd1, 0x85, 0xa0, 0x04, 0xd4, 0x11, + 0x95, 0x1d, 0xac, 0x0b, 0x25, 0xbe, 0x59, 0xa2, 0xb3, 0x30, 0xee, 0x97, + 0x07, 0x2a, 0x51, 0x15, 0xc1, 0x8d, 0xa8, 0xa6, 0x57, 0x9a, 0x4e, 0xbf, + 0xd7, 0x2d, 0x35, 0x07, 0x6b, 0xd6, 0xc9, 0x3c, 0xe4, 0xcf, 0x0b, 0x14, + 0x3e, 0x10, 0x51, 0x77, 0xd6, 0x84, 0x04, 0xbe, 0xd1, 0xd5, 0xa8, 0xf3, + 0x9d, 0x1d, 0x4f, 0xc1, 0xc9, 0xf1, 0x0c, 0x6d, 0xb6, 0xcb, 0xe2, 0x05, + 0x0b, 0x9c, 0x7a, 0x3a, 0x9a, 0x99, 0xe9, 0xa1, 0x93, 0xdc, 0x72, 0x2e, + 0xef, 0xf3, 0x8d, 0xb9, 0x7b, 0xb0, 0x19, 0x24, 0x95, 0x0d, 0x68, 0xa7, + 0xe0, 0xaa, 0x0b, 0xb1, 0xd1, 0xcc, 0x52, 0x14, 0xf9, 0x6c, 0x91, 0x59, + 0xe4, 0xe1, 0x9b, 0xf9, 0x12, 0x39, 0xb1, 0x79, 0xbb, 0x21, 0x92, 0x00, + 0xa4, 0x89, 0xf5, 0xbd, 0xd7, 0x89, 0x27, 0x40, 0xdc, 0xb1, 0x09, 0x38, + 0x63, 0x91, 0x8c, 0xa5, 0x27, 0x27, 0x97, 0x39, 0x35, 0xfa, 0x1a, 0x8a, + 0xa7, 0xe5, 0xc4, 0xd8, 0xbf, 0xe7, 0xbe + }; + ASSERT_EQ(Bytes(kExpectedPub, sizeof(kExpectedPub)), + Bytes(pub_key, pub_key_len)); } // Test that H in |TRUST_TOKEN_experiment_v1| was computed correctly. @@ -124,26 +292,343 @@ TEST(TrustTokenTest, HExp2) { EXPECT_EQ(Bytes(h), Bytes(expected_bytes, expected_len)); } +// Test that H in |TRUST_TOKEN_pst_v1_pmb| was computed correctly. +TEST(TrustTokenTest, HPST1) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); + ASSERT_TRUE(group); + + const uint8_t kHGen[] = "generator"; + const uint8_t kHLabel[] = "PMBTokens PST V1 HashH"; + + bssl::UniquePtr expected_h(EC_POINT_new(group)); + ASSERT_TRUE(expected_h); + ASSERT_TRUE(ec_hash_to_curve_p384_xmd_sha384_sswu( + group, &expected_h->raw, kHLabel, sizeof(kHLabel), kHGen, sizeof(kHGen))); + uint8_t expected_bytes[1 + 2 * EC_MAX_BYTES]; + size_t expected_len = + EC_POINT_point2oct(group, expected_h.get(), POINT_CONVERSION_UNCOMPRESSED, + expected_bytes, sizeof(expected_bytes), nullptr); + + uint8_t h[97]; + ASSERT_TRUE(pmbtoken_pst1_get_h_for_testing(h)); + EXPECT_EQ(Bytes(h), Bytes(expected_bytes, expected_len)); +} + +static int ec_point_uncompressed_from_compressed( + const EC_GROUP *group, uint8_t out[EC_MAX_UNCOMPRESSED], size_t *out_len, + const uint8_t *in, size_t len) { + bssl::UniquePtr point(EC_POINT_new(group)); + if (!point || + !EC_POINT_oct2point(group, point.get(), in, len, nullptr)) { + return 0; + } + + *out_len = + EC_POINT_point2oct(group, point.get(), POINT_CONVERSION_UNCOMPRESSED, out, + EC_MAX_UNCOMPRESSED, nullptr); + return 1; +} + +static bool setup_voprf_test_key(const EC_GROUP *group, + TRUST_TOKEN_ISSUER_KEY *out) { + static const uint8_t kPrivateKey[] = { + 0x05, 0x16, 0x46, 0xb9, 0xe6, 0xe7, 0xa7, 0x1a, 0xe2, 0x7c, 0x1e, 0x1d, + 0x0b, 0x87, 0xb4, 0x38, 0x1d, 0xb6, 0xd3, 0x59, 0x5e, 0xee, 0xb1, 0xad, + 0xb4, 0x15, 0x79, 0xad, 0xbf, 0x99, 0x2f, 0x42, 0x78, 0xf9, 0x01, 0x6e, + 0xaf, 0xc9, 0x44, 0xed, 0xaa, 0x2b, 0x43, 0x18, 0x35, 0x81, 0x77, 0x9d + }; + + static const uint8_t kPublicKey[] = { + 0x03, 0x1d, 0x68, 0x96, 0x86, 0xc6, 0x11, 0x99, 0x1b, 0x55, + 0xf1, 0xa1, 0xd8, 0xf4, 0x30, 0x5c, 0xcd, 0x6c, 0xb7, 0x19, + 0x44, 0x6f, 0x66, 0x0a, 0x30, 0xdb, 0x61, 0xb7, 0xaa, 0x87, + 0xb4, 0x6a, 0xcf, 0x59, 0xb7, 0xc0, 0xd4, 0xa9, 0x07, 0x7b, + 0x3d, 0xa2, 0x1c, 0x25, 0xdd, 0x48, 0x22, 0x29, 0xa0 + }; + + if (!ec_scalar_from_bytes(group, &out->xs, kPrivateKey, + sizeof(kPrivateKey))) { + return false; + } + + bssl::UniquePtr pub(EC_POINT_new(group)); + return pub && + EC_POINT_oct2point(group, pub.get(), kPublicKey, sizeof(kPublicKey), + nullptr) && + ec_jacobian_to_affine(group, &out->pubs, &pub->raw); +} + +TEST(TrustTokenTest, PSTV1VOPRFTestVector1) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); + TRUST_TOKEN_ISSUER_KEY key; + ASSERT_TRUE(setup_voprf_test_key(group, &key)); + + static const uint8_t kBlindedElement[] = { + 0x02, 0xd3, 0x38, 0xc0, 0x5c, 0xbe, 0xcb, 0x82, 0xde, 0x13, + 0xd6, 0x70, 0x0f, 0x09, 0xcb, 0x61, 0x19, 0x05, 0x43, 0xa7, + 0xb7, 0xe2, 0xc6, 0xcd, 0x4f, 0xca, 0x56, 0x88, 0x7e, 0x56, + 0x4e, 0xa8, 0x26, 0x53, 0xb2, 0x7f, 0xda, 0xd3, 0x83, 0x99, + 0x5e, 0xa6, 0xd0, 0x2c, 0xf2, 0x6d, 0x0e, 0x24, 0xd9 + }; + + static const uint8_t kEvaluatedElement[] = { + 0x02, 0xa7, 0xbb, 0xa5, 0x89, 0xb3, 0xe8, 0x67, 0x2a, 0xa1, + 0x9e, 0x8f, 0xd2, 0x58, 0xde, 0x2e, 0x6a, 0xae, 0x20, 0x10, + 0x1c, 0x8d, 0x76, 0x12, 0x46, 0xde, 0x97, 0xa6, 0xb5, 0xee, + 0x9c, 0xf1, 0x05, 0xfe, 0xbc, 0xe4, 0x32, 0x7a, 0x32, 0x62, + 0x55, 0xa3, 0xc6, 0x04, 0xf6, 0x3f, 0x60, 0x0e, 0xf6 + }; + + static const uint8_t kProof[] = { + 0xbf, 0xc6, 0xcf, 0x38, 0x59, 0x12, 0x7f, 0x5f, 0xe2, 0x55, 0x48, 0x85, + 0x98, 0x56, 0xd6, 0xb7, 0xfa, 0x1c, 0x74, 0x59, 0xf0, 0xba, 0x57, 0x12, + 0xa8, 0x06, 0xfc, 0x09, 0x1a, 0x30, 0x00, 0xc4, 0x2d, 0x8b, 0xa3, 0x4f, + 0xf4, 0x5f, 0x32, 0xa5, 0x2e, 0x40, 0x53, 0x3e, 0xfd, 0x2a, 0x03, 0xbc, + 0x87, 0xf3, 0xbf, 0x4f, 0x9f, 0x58, 0x02, 0x82, 0x97, 0xcc, 0xb9, 0xcc, + 0xb1, 0x8a, 0xe7, 0x18, 0x2b, 0xcd, 0x1e, 0xf2, 0x39, 0xdf, 0x77, 0xe3, + 0xbe, 0x65, 0xef, 0x14, 0x7f, 0x3a, 0xcf, 0x8b, 0xc9, 0xcb, 0xfc, 0x55, + 0x24, 0xb7, 0x02, 0x26, 0x34, 0x14, 0xf0, 0x43, 0xe3, 0xb7, 0xca, 0x2e + }; + + static const uint8_t kProofScalar[] = { + 0x80, 0x3d, 0x95, 0x5f, 0x0e, 0x07, 0x3a, 0x04, 0xaa, 0x5d, 0x92, 0xb3, + 0xfb, 0x73, 0x9f, 0x56, 0xf9, 0xdb, 0x00, 0x12, 0x66, 0x67, 0x7f, 0x62, + 0xc0, 0x95, 0x02, 0x1d, 0xb0, 0x18, 0xcd, 0x8c, 0xbb, 0x55, 0x94, 0x1d, + 0x40, 0x73, 0x69, 0x8c, 0xe4, 0x5c, 0x40, 0x5d, 0x13, 0x48, 0xb7, 0xb1 + }; + + uint8_t blinded_buf[EC_MAX_UNCOMPRESSED]; + size_t blinded_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, blinded_buf, &blinded_len, kBlindedElement, + sizeof(kBlindedElement))); + + CBS sign_input; + CBS_init(&sign_input, blinded_buf, blinded_len); + bssl::ScopedCBB response; + ASSERT_TRUE(CBB_init(response.get(), 0)); + ASSERT_TRUE(voprf_pst1_sign_with_proof_scalar_for_testing( + &key, response.get(), &sign_input, /*num_requested=*/1, + /*num_to_issue=*/1, + /*private_metadata=*/0, kProofScalar, sizeof(kProofScalar))); + + uint8_t evaluated_buf[EC_MAX_UNCOMPRESSED]; + size_t evaluated_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, evaluated_buf, &evaluated_len, kEvaluatedElement, + sizeof(kEvaluatedElement))); + + bssl::ScopedCBB expected_response; + ASSERT_TRUE(CBB_init(expected_response.get(), 0)); + ASSERT_TRUE( + CBB_add_bytes(expected_response.get(), evaluated_buf, evaluated_len)); + ASSERT_TRUE(CBB_add_u16(expected_response.get(), sizeof(kProof))); + ASSERT_TRUE(CBB_add_bytes(expected_response.get(), kProof, sizeof(kProof))); + ASSERT_TRUE(CBB_flush(expected_response.get())); + + ASSERT_EQ(Bytes(CBB_data(expected_response.get()), + CBB_len(expected_response.get())), + Bytes(CBB_data(response.get()), CBB_len(response.get()))); +} + +TEST(TrustTokenTest, PSTV1VOPRFTestVector2) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); + TRUST_TOKEN_ISSUER_KEY key; + ASSERT_TRUE(setup_voprf_test_key(group, &key)); + + static const uint8_t kBlindedElement[] = { + 0x02, 0xf2, 0x74, 0x69, 0xe0, 0x59, 0x88, 0x6f, 0x22, 0x1b, + 0xe5, 0xf2, 0xcc, 0xa0, 0x3d, 0x2b, 0xdc, 0x61, 0xe5, 0x52, + 0x21, 0x72, 0x1c, 0x3b, 0x3e, 0x56, 0xfc, 0x01, 0x2e, 0x36, + 0xd3, 0x1a, 0xe5, 0xf8, 0xdc, 0x05, 0x81, 0x09, 0x59, 0x15, + 0x56, 0xa6, 0xdb, 0xd3, 0xa8, 0xc6, 0x9c, 0x43, 0x3b + }; + + static const uint8_t kEvaluatedElement[] = { + 0x03, 0xf1, 0x6f, 0x90, 0x39, 0x47, 0x03, 0x54, 0x00, 0xe9, + 0x6b, 0x7f, 0x53, 0x1a, 0x38, 0xd4, 0xa0, 0x7a, 0xc8, 0x9a, + 0x80, 0xf8, 0x9d, 0x86, 0xa1, 0xbf, 0x08, 0x9c, 0x52, 0x5a, + 0x92, 0xc7, 0xf4, 0x73, 0x37, 0x29, 0xca, 0x30, 0xc5, 0x6c, + 0xe7, 0x8b, 0x1a, 0xb4, 0xf7, 0xd9, 0x2d, 0xb8, 0xb4 + }; + + static const uint8_t kProof[] = { + 0xd0, 0x05, 0xd6, 0xda, 0xaa, 0xd7, 0x57, 0x14, 0x14, 0xc1, 0xe0, + 0xc7, 0x5f, 0x7e, 0x57, 0xf2, 0x11, 0x3c, 0xa9, 0xf4, 0x60, 0x4e, + 0x84, 0xbc, 0x90, 0xf9, 0xbe, 0x52, 0xda, 0x89, 0x6f, 0xff, 0x3b, + 0xee, 0x49, 0x6d, 0xcd, 0xe2, 0xa5, 0x78, 0xae, 0x9d, 0xf3, 0x15, + 0x03, 0x25, 0x85, 0xf8, 0x01, 0xfb, 0x21, 0xc6, 0x08, 0x0a, 0xc0, + 0x56, 0x72, 0xb2, 0x91, 0xe5, 0x75, 0xa4, 0x02, 0x95, 0xb3, 0x06, + 0xd9, 0x67, 0x71, 0x7b, 0x28, 0xe0, 0x8f, 0xcc, 0x8a, 0xd1, 0xca, + 0xb4, 0x78, 0x45, 0xd1, 0x6a, 0xf7, 0x3b, 0x3e, 0x64, 0x3d, 0xdc, + 0xc1, 0x91, 0x20, 0x8e, 0x71, 0xc6, 0x46, 0x30 + }; + + static const uint8_t kProofScalar[] = { + 0x80, 0x3d, 0x95, 0x5f, 0x0e, 0x07, 0x3a, 0x04, 0xaa, 0x5d, 0x92, 0xb3, + 0xfb, 0x73, 0x9f, 0x56, 0xf9, 0xdb, 0x00, 0x12, 0x66, 0x67, 0x7f, 0x62, + 0xc0, 0x95, 0x02, 0x1d, 0xb0, 0x18, 0xcd, 0x8c, 0xbb, 0x55, 0x94, 0x1d, + 0x40, 0x73, 0x69, 0x8c, 0xe4, 0x5c, 0x40, 0x5d, 0x13, 0x48, 0xb7, 0xb1 + }; + + uint8_t blinded_buf[EC_MAX_UNCOMPRESSED]; + size_t blinded_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, blinded_buf, &blinded_len, kBlindedElement, + sizeof(kBlindedElement))); + + CBS sign_input; + CBS_init(&sign_input, blinded_buf, blinded_len); + bssl::ScopedCBB response; + ASSERT_TRUE(CBB_init(response.get(), 0)); + ASSERT_TRUE(voprf_pst1_sign_with_proof_scalar_for_testing( + &key, response.get(), &sign_input, /*num_requested=*/1, + /*num_to_issue=*/1, + /*private_metadata=*/0, kProofScalar, sizeof(kProofScalar))); + + uint8_t evaluated_buf[EC_MAX_UNCOMPRESSED]; + size_t evaluated_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, evaluated_buf, &evaluated_len, kEvaluatedElement, + sizeof(kEvaluatedElement))); + + bssl::ScopedCBB expected_response; + ASSERT_TRUE(CBB_init(expected_response.get(), 0)); + ASSERT_TRUE( + CBB_add_bytes(expected_response.get(), evaluated_buf, evaluated_len)); + ASSERT_TRUE(CBB_add_u16(expected_response.get(), sizeof(kProof))); + ASSERT_TRUE(CBB_add_bytes(expected_response.get(), kProof, sizeof(kProof))); + ASSERT_TRUE(CBB_flush(expected_response.get())); + + ASSERT_EQ(Bytes(CBB_data(expected_response.get()), + CBB_len(expected_response.get())), + Bytes(CBB_data(response.get()), CBB_len(response.get()))); +} + +TEST(TrustTokenTest, PSTV1VOPRFTestVector3) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); + TRUST_TOKEN_ISSUER_KEY key; + ASSERT_TRUE(setup_voprf_test_key(group, &key)); + + static const uint8_t kBlindedElement1[] = { + 0x02, 0xd3, 0x38, 0xc0, 0x5c, 0xbe, 0xcb, 0x82, 0xde, 0x13, + 0xd6, 0x70, 0x0f, 0x09, 0xcb, 0x61, 0x19, 0x05, 0x43, 0xa7, + 0xb7, 0xe2, 0xc6, 0xcd, 0x4f, 0xca, 0x56, 0x88, 0x7e, 0x56, + 0x4e, 0xa8, 0x26, 0x53, 0xb2, 0x7f, 0xda, 0xd3, 0x83, 0x99, + 0x5e, 0xa6, 0xd0, 0x2c, 0xf2, 0x6d, 0x0e, 0x24, 0xd9 + }; + static const uint8_t kBlindedElement2[] = { + 0x02, 0xfa, 0x02, 0x47, 0x0d, 0x7f, 0x15, 0x10, 0x18, 0xb4, + 0x1e, 0x82, 0x22, 0x3c, 0x32, 0xfa, 0xd8, 0x24, 0xde, 0x6a, + 0xd4, 0xb5, 0xce, 0x9f, 0x8e, 0x9f, 0x98, 0x08, 0x3c, 0x9a, + 0x72, 0x6d, 0xe9, 0xa1, 0xfc, 0x39, 0xd7, 0xa0, 0xcb, 0x6f, + 0x4f, 0x18, 0x8d, 0xd9, 0xce, 0xa0, 0x14, 0x74, 0xcd + }; + + static const uint8_t kEvaluatedElement1[] = { + 0x02, 0xa7, 0xbb, 0xa5, 0x89, 0xb3, 0xe8, 0x67, 0x2a, 0xa1, + 0x9e, 0x8f, 0xd2, 0x58, 0xde, 0x2e, 0x6a, 0xae, 0x20, 0x10, + 0x1c, 0x8d, 0x76, 0x12, 0x46, 0xde, 0x97, 0xa6, 0xb5, 0xee, + 0x9c, 0xf1, 0x05, 0xfe, 0xbc, 0xe4, 0x32, 0x7a, 0x32, 0x62, + 0x55, 0xa3, 0xc6, 0x04, 0xf6, 0x3f, 0x60, 0x0e, 0xf6 + }; + + static const uint8_t kEvaluatedElement2[] = { + 0x02, 0x8e, 0x9e, 0x11, 0x56, 0x25, 0xff, 0x4c, 0x2f, 0x07, + 0xbf, 0x87, 0xce, 0x3f, 0xd7, 0x3f, 0xc7, 0x79, 0x94, 0xa7, + 0xa0, 0xc1, 0xdf, 0x03, 0xd2, 0xa6, 0x30, 0xa3, 0xd8, 0x45, + 0x93, 0x0e, 0x2e, 0x63, 0xa1, 0x65, 0xb1, 0x14, 0xd9, 0x8f, + 0xe3, 0x4e, 0x61, 0xb6, 0x8d, 0x23, 0xc0, 0xb5, 0x0a + }; + + static const uint8_t kProof[] = { + 0x6d, 0x8d, 0xcb, 0xd2, 0xfc, 0x95, 0x55, 0x0a, 0x02, 0x21, 0x1f, + 0xb7, 0x8a, 0xfd, 0x01, 0x39, 0x33, 0xf3, 0x07, 0xd2, 0x1e, 0x7d, + 0x85, 0x5b, 0x0b, 0x1e, 0xd0, 0xaf, 0x78, 0x07, 0x6d, 0x81, 0x37, + 0xad, 0x8b, 0x0a, 0x1b, 0xfa, 0x05, 0x67, 0x6d, 0x32, 0x52, 0x49, + 0xc1, 0xdb, 0xb9, 0xa5, 0x2b, 0xd8, 0x1b, 0x1c, 0x2b, 0x7b, 0x0e, + 0xfc, 0x77, 0xcf, 0x7b, 0x27, 0x8e, 0x1c, 0x94, 0x7f, 0x62, 0x83, + 0xf1, 0xd4, 0xc5, 0x13, 0x05, 0x3f, 0xc0, 0xad, 0x19, 0xe0, 0x26, + 0xfb, 0x0c, 0x30, 0x65, 0x4b, 0x53, 0xd9, 0xce, 0xa4, 0xb8, 0x7b, + 0x03, 0x72, 0x71, 0xb5, 0xd2, 0xe2, 0xd0, 0xea + }; + + static const uint8_t kProofScalar[] = { + 0xa0, 0x97, 0xe7, 0x22, 0xed, 0x24, 0x27, 0xde, 0x86, 0x96, + 0x69, 0x10, 0xac, 0xba, 0x9f, 0x5c, 0x35, 0x0e, 0x80, 0x40, + 0xf8, 0x28, 0xbf, 0x6c, 0xec, 0xa2, 0x74, 0x05, 0x42, 0x0c, + 0xdf, 0x3d, 0x63, 0xcb, 0x3a, 0xef, 0x00, 0x5f, 0x40, 0xba, + 0x51, 0x94, 0x3c, 0x80, 0x26, 0x87, 0x79, 0x63 + }; + + uint8_t blinded_buf[2*EC_MAX_UNCOMPRESSED]; + size_t blinded_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, blinded_buf, &blinded_len, kBlindedElement1, + sizeof(kBlindedElement1))); + size_t offset = blinded_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, blinded_buf + offset, &blinded_len, kBlindedElement2, + sizeof(kBlindedElement2))); + + CBS sign_input; + CBS_init(&sign_input, blinded_buf, offset + blinded_len); + bssl::ScopedCBB response; + ASSERT_TRUE(CBB_init(response.get(), 0)); + ASSERT_TRUE(voprf_pst1_sign_with_proof_scalar_for_testing( + &key, response.get(), &sign_input, /*num_requested=*/2, + /*num_to_issue=*/2, + /*private_metadata=*/0, kProofScalar, sizeof(kProofScalar))); + + uint8_t evaluated_buf[2 * EC_MAX_UNCOMPRESSED]; + size_t evaluated_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, evaluated_buf, &evaluated_len, kEvaluatedElement1, + sizeof(kEvaluatedElement1))); + offset = evaluated_len; + ASSERT_TRUE(ec_point_uncompressed_from_compressed( + group, evaluated_buf + offset, &evaluated_len, kEvaluatedElement2, + sizeof(kEvaluatedElement2))); + + bssl::ScopedCBB expected_response; + ASSERT_TRUE(CBB_init(expected_response.get(), 0)); + ASSERT_TRUE(CBB_add_bytes(expected_response.get(), evaluated_buf, + offset + evaluated_len)); + ASSERT_TRUE(CBB_add_u16(expected_response.get(), sizeof(kProof))); + ASSERT_TRUE(CBB_add_bytes(expected_response.get(), kProof, sizeof(kProof))); + ASSERT_TRUE(CBB_flush(expected_response.get())); + + ASSERT_EQ(Bytes(CBB_data(expected_response.get()), + CBB_len(expected_response.get())), + Bytes(CBB_data(response.get()), CBB_len(response.get()))); +} + static std::vector AllMethods() { return { TRUST_TOKEN_experiment_v1(), TRUST_TOKEN_experiment_v2_voprf(), - TRUST_TOKEN_experiment_v2_pmb() + TRUST_TOKEN_experiment_v2_pmb(), + TRUST_TOKEN_pst_v1_voprf(), + TRUST_TOKEN_pst_v1_pmb() }; } class TrustTokenProtocolTestBase : public ::testing::Test { public: - explicit TrustTokenProtocolTestBase(const TRUST_TOKEN_METHOD *method_arg) - : method_(method_arg) {} + explicit TrustTokenProtocolTestBase(const TRUST_TOKEN_METHOD *method_arg, + bool use_msg) + : method_(method_arg), use_msg_(use_msg) {} // KeyID returns the key ID associated with key index |i|. static uint32_t KeyID(size_t i) { + assert(i <= UINT32_MAX); // Use a different value from the indices to that we do not mix them up. - return 7 + i; + return static_cast(7 + i); } - const TRUST_TOKEN_METHOD *method() { return method_; } + const TRUST_TOKEN_METHOD *method() const { return method_; } + + bool use_message() const { return use_msg_; } protected: void SetupContexts() { @@ -183,6 +668,7 @@ class TrustTokenProtocolTestBase : public ::testing::Test { } const TRUST_TOKEN_METHOD *method_; + bool use_msg_; uint16_t client_max_batchsize = 10; uint16_t issuer_max_batchsize = 10; bssl::UniquePtr client; @@ -192,13 +678,17 @@ class TrustTokenProtocolTestBase : public ::testing::Test { class TrustTokenProtocolTest : public TrustTokenProtocolTestBase, - public testing::WithParamInterface { + public testing::WithParamInterface< + std::tuple> { public: - TrustTokenProtocolTest() : TrustTokenProtocolTestBase(GetParam()) {} + TrustTokenProtocolTest() + : TrustTokenProtocolTestBase(std::get<0>(GetParam()), + std::get<1>(GetParam())) {} }; INSTANTIATE_TEST_SUITE_P(TrustTokenAllProtocolTest, TrustTokenProtocolTest, - testing::ValuesIn(AllMethods())); + testing::Combine(testing::ValuesIn(AllMethods()), + testing::Bool())); TEST_P(TrustTokenProtocolTest, InvalidToken) { ASSERT_NO_FATAL_FAILURE(SetupContexts()); @@ -208,8 +698,13 @@ TEST_P(TrustTokenProtocolTest, InvalidToken) { size_t key_index; size_t tokens_issued; - ASSERT_TRUE( - TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, &msg_len, 1)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 1, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 1)); + } bssl::UniquePtr free_issue_msg(issue_msg); ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( issuer.get(), &issue_resp, &resp_len, &tokens_issued, issue_msg, msg_len, @@ -229,13 +724,20 @@ TEST_P(TrustTokenProtocolTest, InvalidToken) { ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_redemption( client.get(), &redeem_msg, &msg_len, token, NULL, 0, 0)); bssl::UniquePtr free_redeem_msg(redeem_msg); + uint32_t public_value; + uint8_t private_value; TRUST_TOKEN *rtoken; uint8_t *client_data; size_t client_data_len; - uint64_t redemption_time; - ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem( - issuer.get(), &redeem_resp, &resp_len, &rtoken, &client_data, - &client_data_len, &redemption_time, redeem_msg, msg_len, 600)); + if (use_message()) { + ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem_over_message( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len, kMessage, sizeof(kMessage))); + } else { + ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len)); + } bssl::UniquePtr free_redeem_resp(redeem_resp); } } @@ -245,8 +747,13 @@ TEST_P(TrustTokenProtocolTest, TruncatedIssuanceRequest) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); msg_len = 10; size_t tokens_issued; @@ -262,8 +769,13 @@ TEST_P(TrustTokenProtocolTest, TruncatedIssuanceResponse) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -284,8 +796,13 @@ TEST_P(TrustTokenProtocolTest, ExtraDataIssuanceResponse) { uint8_t *request = NULL, *response = NULL; size_t request_len, response_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &request, - &request_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &request, &request_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &request, + &request_len, 10)); + } bssl::UniquePtr free_request(request); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue(issuer.get(), &response, &response_len, @@ -308,8 +825,13 @@ TEST_P(TrustTokenProtocolTest, TruncatedRedemptionRequest) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -327,78 +849,27 @@ TEST_P(TrustTokenProtocolTest, TruncatedRedemptionRequest) { const uint8_t kClientData[] = "\x70TEST CLIENT DATA"; uint64_t kRedemptionTime = (method()->has_srr ? 13374242 : 0); - uint8_t *redeem_msg = NULL, *redeem_resp = NULL; + uint8_t *redeem_msg = NULL; ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_redemption( client.get(), &redeem_msg, &msg_len, token, kClientData, sizeof(kClientData) - 1, kRedemptionTime)); bssl::UniquePtr free_redeem_msg(redeem_msg); msg_len = 10; + uint32_t public_value; + uint8_t private_value; TRUST_TOKEN *rtoken; uint8_t *client_data; size_t client_data_len; - uint64_t redemption_time; - ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem( - issuer.get(), &redeem_resp, &resp_len, &rtoken, &client_data, - &client_data_len, &redemption_time, redeem_msg, msg_len, 600)); - } -} - -TEST_P(TrustTokenProtocolTest, TruncatedRedemptionResponse) { - ASSERT_NO_FATAL_FAILURE(SetupContexts()); - - uint8_t *issue_msg = NULL, *issue_resp = NULL; - size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); - bssl::UniquePtr free_issue_msg(issue_msg); - size_t tokens_issued; - ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( - issuer.get(), &issue_resp, &resp_len, &tokens_issued, issue_msg, msg_len, - /*public_metadata=*/KeyID(0), /*private_metadata=*/0, - /*max_issuance=*/10)); - bssl::UniquePtr free_msg(issue_resp); - size_t key_index; - bssl::UniquePtr tokens( - TRUST_TOKEN_CLIENT_finish_issuance(client.get(), &key_index, issue_resp, - resp_len)); - ASSERT_TRUE(tokens); - - for (TRUST_TOKEN *token : tokens.get()) { - const uint8_t kClientData[] = "\x70TEST CLIENT DATA"; - uint64_t kRedemptionTime = 0; - - uint8_t *redeem_msg = NULL, *redeem_resp = NULL; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_redemption( - client.get(), &redeem_msg, &msg_len, token, kClientData, - sizeof(kClientData) - 1, kRedemptionTime)); - bssl::UniquePtr free_redeem_msg(redeem_msg); - TRUST_TOKEN *rtoken; - uint8_t *client_data; - size_t client_data_len; - uint64_t redemption_time; - ASSERT_TRUE(TRUST_TOKEN_ISSUER_redeem( - issuer.get(), &redeem_resp, &resp_len, &rtoken, &client_data, - &client_data_len, &redemption_time, redeem_msg, msg_len, 600)); - bssl::UniquePtr free_redeem_resp(redeem_resp); - bssl::UniquePtr free_client_data(client_data); - bssl::UniquePtr free_rtoken(rtoken); - - ASSERT_EQ(redemption_time, kRedemptionTime); - ASSERT_EQ(Bytes(kClientData, sizeof(kClientData) - 1), - Bytes(client_data, client_data_len)); - resp_len = 10; - - // If the protocol doesn't use SRRs, TRUST_TOKEN_CLIENT_finish_redemtpion - // leaves all SRR validation to the caller. - uint8_t *srr = NULL, *sig = NULL; - size_t srr_len, sig_len; - bool expect_failure = !method()->has_srr; - ASSERT_EQ(expect_failure, TRUST_TOKEN_CLIENT_finish_redemption( - client.get(), &srr, &srr_len, &sig, &sig_len, - redeem_resp, resp_len)); - bssl::UniquePtr free_srr(srr); - bssl::UniquePtr free_sig(sig); + if (use_message()) { + ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem_over_message( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len, kMessage, sizeof(kMessage))); + } else { + ASSERT_FALSE(TRUST_TOKEN_ISSUER_redeem( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len)); + } } } @@ -447,8 +918,13 @@ TEST_P(TrustTokenProtocolTest, IssuedWithBadKeyID) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -464,13 +940,14 @@ TEST_P(TrustTokenProtocolTest, IssuedWithBadKeyID) { class TrustTokenMetadataTest : public TrustTokenProtocolTestBase, public testing::WithParamInterface< - std::tuple> { + std::tuple> { public: TrustTokenMetadataTest() - : TrustTokenProtocolTestBase(std::get<0>(GetParam())) {} + : TrustTokenProtocolTestBase(std::get<0>(GetParam()), + std::get<1>(GetParam())) {} - int public_metadata() { return std::get<1>(GetParam()); } - bool private_metadata() { return std::get<2>(GetParam()); } + int public_metadata() { return std::get<2>(GetParam()); } + bool private_metadata() { return std::get<3>(GetParam()); } }; TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) { @@ -478,140 +955,13 @@ TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); - bssl::UniquePtr free_issue_msg(issue_msg); - size_t tokens_issued; - bool result = TRUST_TOKEN_ISSUER_issue( - issuer.get(), &issue_resp, &resp_len, &tokens_issued, issue_msg, msg_len, - public_metadata(), private_metadata(), /*max_issuance=*/1); - if (!method()->has_private_metadata && private_metadata()) { - ASSERT_FALSE(result); - return; + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); } - ASSERT_TRUE(result); - bssl::UniquePtr free_msg(issue_resp); - size_t key_index; - bssl::UniquePtr tokens( - TRUST_TOKEN_CLIENT_finish_issuance(client.get(), &key_index, issue_resp, - resp_len)); - ASSERT_TRUE(tokens); - - for (TRUST_TOKEN *token : tokens.get()) { - const uint8_t kClientData[] = "\x70TEST CLIENT DATA"; - uint64_t kRedemptionTime = (method()->has_srr ? 13374242 : 0); - - const uint8_t kExpectedSRRV1[] = - "\xa4\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69" - "\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6a\x74\x6f\x6b\x65\x6e" - "\x2d\x68\x61\x73\x68\x58\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x6b\x63\x6c\x69\x65\x6e\x74\x2d\x64\x61\x74\x61" - "\x70\x54\x45\x53\x54\x20\x43\x4c\x49\x45\x4e\x54\x20\x44\x41\x54\x41" - "\x70\x65\x78\x70\x69\x72\x79\x2d\x74\x69\x6d\x65\x73\x74\x61\x6d\x70" - "\x1a\x00\xcc\x15\x7a"; - - const uint8_t kExpectedSRRV2[] = - "\xa4\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69" - "\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6a\x74\x6f\x6b\x65\x6e" - "\x2d\x68\x61\x73\x68\x58\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x6b\x63\x6c\x69\x65\x6e\x74\x2d\x64\x61\x74\x61" - "\x70\x54\x45\x53\x54\x20\x43\x4c\x49\x45\x4e\x54\x20\x44\x41\x54\x41" - "\x70\x65\x78\x70\x69\x72\x79\x2d\x74\x69\x6d\x65\x73\x74\x61\x6d\x70" - "\x00"; - - const uint8_t *expected_srr = kExpectedSRRV1; - size_t expected_srr_len = sizeof(kExpectedSRRV1) - 1; - if (!method()->has_srr) { - expected_srr = kExpectedSRRV2; - expected_srr_len = sizeof(kExpectedSRRV2) - 1; - } - - uint8_t *redeem_msg = NULL, *redeem_resp = NULL; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_redemption( - client.get(), &redeem_msg, &msg_len, token, kClientData, - sizeof(kClientData) - 1, kRedemptionTime)); - bssl::UniquePtr free_redeem_msg(redeem_msg); - TRUST_TOKEN *rtoken; - uint8_t *client_data; - size_t client_data_len; - uint64_t redemption_time; - ASSERT_TRUE(TRUST_TOKEN_ISSUER_redeem( - issuer.get(), &redeem_resp, &resp_len, &rtoken, &client_data, - &client_data_len, &redemption_time, redeem_msg, msg_len, 600)); - bssl::UniquePtr free_redeem_resp(redeem_resp); - bssl::UniquePtr free_client_data(client_data); - bssl::UniquePtr free_rtoken(rtoken); - - ASSERT_EQ(redemption_time, kRedemptionTime); - ASSERT_EQ(Bytes(kClientData, sizeof(kClientData) - 1), - Bytes(client_data, client_data_len)); - - uint8_t *srr = NULL, *sig = NULL; - size_t srr_len, sig_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_finish_redemption( - client.get(), &srr, &srr_len, &sig, &sig_len, redeem_resp, resp_len)); - bssl::UniquePtr free_srr(srr); - bssl::UniquePtr free_sig(sig); - - if (!method()->has_srr) { - size_t b64_len; - ASSERT_TRUE(EVP_EncodedLength(&b64_len, expected_srr_len)); - b64_len -= 1; - const char kSRRHeader[] = "body=:"; - ASSERT_LT(sizeof(kSRRHeader) - 1 + b64_len, srr_len); - - ASSERT_EQ(Bytes(kSRRHeader, sizeof(kSRRHeader) - 1), - Bytes(srr, sizeof(kSRRHeader) - 1)); - uint8_t *decoded_srr = - (uint8_t *)OPENSSL_malloc(expected_srr_len + 2); - ASSERT_TRUE(decoded_srr); - ASSERT_LE( - int(expected_srr_len), - EVP_DecodeBlock(decoded_srr, srr + sizeof(kSRRHeader) - 1, b64_len)); - srr = decoded_srr; - srr_len = expected_srr_len; - free_srr.reset(srr); - } - - const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash"; - uint8_t token_hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha_ctx; - SHA256_Init(&sha_ctx); - SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel)); - SHA256_Update(&sha_ctx, token->data, token->len); - SHA256_Final(token_hash, &sha_ctx); - - // Check the token hash is in the SRR. - ASSERT_EQ(Bytes(token_hash), Bytes(srr + 41, sizeof(token_hash))); - - uint8_t decode_private_metadata; - ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata( - method(), &decode_private_metadata, metadata_key, - sizeof(metadata_key), token_hash, sizeof(token_hash), srr[27])); - ASSERT_EQ(srr[18], public_metadata()); - ASSERT_EQ(decode_private_metadata, private_metadata()); - - // Clear out the metadata bits. - srr[18] = 0; - srr[27] = 0; - - // Clear out the token hash. - OPENSSL_memset(srr + 41, 0, sizeof(token_hash)); - - ASSERT_EQ(Bytes(expected_srr, expected_srr_len), - Bytes(srr, srr_len)); - } -} - -TEST_P(TrustTokenMetadataTest, RawSetAndGetMetadata) { - ASSERT_NO_FATAL_FAILURE(SetupContexts()); - - uint8_t *issue_msg = NULL, *issue_resp = NULL; - size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; bool result = TRUST_TOKEN_ISSUER_issue( @@ -644,9 +994,15 @@ TEST_P(TrustTokenMetadataTest, RawSetAndGetMetadata) { TRUST_TOKEN *rtoken; uint8_t *client_data; size_t client_data_len; - ASSERT_TRUE(TRUST_TOKEN_ISSUER_redeem_raw( - issuer.get(), &public_value, &private_value, &rtoken, - &client_data, &client_data_len, redeem_msg, msg_len)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_ISSUER_redeem_over_message( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_ISSUER_redeem( + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, msg_len)); + } bssl::UniquePtr free_client_data(client_data); bssl::UniquePtr free_rtoken(rtoken); @@ -667,8 +1023,13 @@ TEST_P(TrustTokenMetadataTest, TooManyRequests) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -694,8 +1055,13 @@ TEST_P(TrustTokenMetadataTest, TruncatedProof) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -720,7 +1086,8 @@ TEST_P(TrustTokenMetadataTest, TruncatedProof) { if (method() == TRUST_TOKEN_experiment_v1()) { token_length += 4; } - if (method() == TRUST_TOKEN_experiment_v2_voprf()) { + if (method() == TRUST_TOKEN_experiment_v2_voprf() || + method() == TRUST_TOKEN_pst_v1_voprf()) { token_length = 1 + 2 * BN_num_bytes(&group->field); } for (size_t i = 0; i < count; i++) { @@ -757,8 +1124,13 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -783,7 +1155,8 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) { if (method() == TRUST_TOKEN_experiment_v1()) { token_length += 4; } - if (method() == TRUST_TOKEN_experiment_v2_voprf()) { + if (method() == TRUST_TOKEN_experiment_v2_voprf() || + method() == TRUST_TOKEN_pst_v1_voprf()) { token_length = 1 + 2 * BN_num_bytes(&group->field); } for (size_t i = 0; i < count; i++) { @@ -815,6 +1188,7 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) { INSTANTIATE_TEST_SUITE_P( TrustTokenAllMetadataTest, TrustTokenMetadataTest, testing::Combine(testing::ValuesIn(AllMethods()), + testing::Bool(), testing::Values(TrustTokenProtocolTest::KeyID(0), TrustTokenProtocolTest::KeyID(1), TrustTokenProtocolTest::KeyID(2)), @@ -823,13 +1197,14 @@ INSTANTIATE_TEST_SUITE_P( class TrustTokenBadKeyTest : public TrustTokenProtocolTestBase, public testing::WithParamInterface< - std::tuple> { + std::tuple> { public: TrustTokenBadKeyTest() - : TrustTokenProtocolTestBase(std::get<0>(GetParam())) {} + : TrustTokenProtocolTestBase(std::get<0>(GetParam()), + std::get<1>(GetParam())) {} - bool private_metadata() { return std::get<1>(GetParam()); } - int corrupted_key() { return std::get<2>(GetParam()); } + bool private_metadata() { return std::get<2>(GetParam()); } + int corrupted_key() { return std::get<3>(GetParam()); } }; TEST_P(TrustTokenBadKeyTest, BadKey) { @@ -845,8 +1220,13 @@ TEST_P(TrustTokenBadKeyTest, BadKey) { uint8_t *issue_msg = NULL, *issue_resp = NULL; size_t msg_len, resp_len; - ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, - &msg_len, 10)); + if (use_message()) { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance_over_message( + client.get(), &issue_msg, &msg_len, 10, kMessage, sizeof(kMessage))); + } else { + ASSERT_TRUE(TRUST_TOKEN_CLIENT_begin_issuance(client.get(), &issue_msg, + &msg_len, 10)); + } bssl::UniquePtr free_issue_msg(issue_msg); struct trust_token_issuer_key_st *key = &issuer->keys[0]; @@ -854,7 +1234,7 @@ TEST_P(TrustTokenBadKeyTest, BadKey) { &key->key.y1, &key->key.xs, &key->key.ys}; // Corrupt private key scalar. - scalars[corrupted_key()]->bytes[0] ^= 42; + scalars[corrupted_key()]->words[0] ^= 42; size_t tokens_issued; ASSERT_TRUE(TRUST_TOKEN_ISSUER_issue( @@ -877,6 +1257,7 @@ TEST_P(TrustTokenBadKeyTest, BadKey) { INSTANTIATE_TEST_SUITE_P(TrustTokenAllBadKeyTest, TrustTokenBadKeyTest, testing::Combine(testing::ValuesIn(AllMethods()), + testing::Bool(), testing::Bool(), testing::Values(0, 1, 2, 3, 4, 5))); diff --git a/third_party/boringssl/kit/src/crypto/trust_token/voprf.c b/third_party/boringssl/kit/src/crypto/trust_token/voprf.c index f93ee9cd..ea7c1931 100644 --- a/third_party/boringssl/kit/src/crypto/trust_token/voprf.c +++ b/third_party/boringssl/kit/src/crypto/trust_token/voprf.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "../ec_extra/internal.h" #include "../fipsmodule/ec/internal.h" @@ -28,7 +29,7 @@ #include "internal.h" -typedef int (*hash_to_group_func_t)(const EC_GROUP *group, EC_RAW_POINT *out, +typedef int (*hash_to_group_func_t)(const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t t[TRUST_TOKEN_NONCE_SIZE]); typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out, uint8_t *buf, size_t len); @@ -62,19 +63,24 @@ static int voprf_init_method(VOPRF_METHOD *method, int curve_nid, static int cbb_add_point(CBB *out, const EC_GROUP *group, const EC_AFFINE *point) { - size_t len = - ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0); - if (len == 0) { - return 0; - } - uint8_t *p; + size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED); return CBB_add_space(out, &p, len) && ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p, len) == len && CBB_flush(out); } +static int cbb_serialize_point(CBB *out, const EC_GROUP *group, + const EC_AFFINE *point) { + uint8_t *p; + size_t len = ec_point_byte_len(group, POINT_CONVERSION_COMPRESSED); + return CBB_add_u16(out, len) && CBB_add_space(out, &p, len) && + ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED, p, len) == + len && + CBB_flush(out); +} + static int cbs_get_point(CBS *cbs, const EC_GROUP *group, EC_AFFINE *out) { CBS child; size_t plen = 1 + 2 * BN_num_bytes(&group->field); @@ -91,7 +97,6 @@ static int scalar_to_cbb(CBB *out, const EC_GROUP *group, uint8_t *buf; size_t scalar_len = BN_num_bytes(&group->order); if (!CBB_add_space(out, &buf, scalar_len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } ec_scalar_to_bytes(group, buf, &scalar_len, scalar); @@ -110,20 +115,18 @@ static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) { return 1; } -static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private, - CBB *out_public) { +static int voprf_calculate_key(const VOPRF_METHOD *method, CBB *out_private, + CBB *out_public, const EC_SCALAR *priv) { const EC_GROUP *group = method->group; - EC_RAW_POINT pub; - EC_SCALAR priv; + EC_JACOBIAN pub; EC_AFFINE pub_affine; - if (!ec_random_nonzero_scalar(group, &priv, kDefaultAdditionalData) || - !ec_point_mul_scalar_base(group, &pub, &priv) || + if (!ec_point_mul_scalar_base(group, &pub, priv) || !ec_jacobian_to_affine(group, &pub_affine, &pub)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); return 0; } - if (!scalar_to_cbb(out_private, group, &priv) || + if (!scalar_to_cbb(out_private, group, priv) || !cbb_add_point(out_public, group, &pub_affine)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); return 0; @@ -132,6 +135,46 @@ static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private, return 1; } + +static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private, + CBB *out_public) { + EC_SCALAR priv; + if (!ec_random_nonzero_scalar(method->group, &priv, kDefaultAdditionalData)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + return 0; + } + return voprf_calculate_key(method, out_private, out_public, &priv); +} + +static int voprf_derive_key_from_secret(const VOPRF_METHOD *method, + CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + static const uint8_t kKeygenLabel[] = "TrustTokenVOPRFKeyGen"; + + EC_SCALAR priv; + int ok = 0; + CBB cbb; + CBB_zero(&cbb); + uint8_t *buf = NULL; + size_t len; + if (!CBB_init(&cbb, 0) || + !CBB_add_bytes(&cbb, kKeygenLabel, sizeof(kKeygenLabel)) || + !CBB_add_bytes(&cbb, secret, secret_len) || + !CBB_finish(&cbb, &buf, &len) || + !method->hash_to_scalar(method->group, &priv, buf, len)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE); + goto err; + } + + ok = voprf_calculate_key(method, out_private, out_public, &priv); + +err: + CBB_cleanup(&cbb); + OPENSSL_free(buf); + return ok; +} + static int voprf_client_key_from_bytes(const VOPRF_METHOD *method, TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len) { @@ -154,7 +197,7 @@ static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method, } // Recompute the public key. - EC_RAW_POINT pub; + EC_JACOBIAN pub; if (!ec_point_mul_scalar_base(group, &pub, &key->xs) || !ec_jacobian_to_affine(group, &key->pubs, &pub)) { return 0; @@ -163,13 +206,17 @@ static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method, return 1; } -static STACK_OF(TRUST_TOKEN_PRETOKEN) * - voprf_blind(const VOPRF_METHOD *method, CBB *cbb, size_t count) { +static STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_blind(const VOPRF_METHOD *method, + CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + SHA512_CTX hash_ctx; + const EC_GROUP *group = method->group; STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens = sk_TRUST_TOKEN_PRETOKEN_new_null(); if (pretokens == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -179,18 +226,25 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); if (pretoken == NULL || !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_PRETOKEN_free(pretoken); goto err; } - RAND_bytes(pretoken->t, sizeof(pretoken->t)); + RAND_bytes(pretoken->salt, sizeof(pretoken->salt)); + if (include_message) { + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(pretoken->t, &hash_ctx); + } else { + OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE); + } // We sample r in Montgomery form to simplify inverting. EC_SCALAR r; if (!ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -201,7 +255,7 @@ static STACK_OF(TRUST_TOKEN_PRETOKEN) * ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r); // Tp is the blinded token in the VOPRF protocol. - EC_RAW_POINT P, Tp; + EC_JACOBIAN P, Tp; if (!method->hash_to_group(group, &P, pretoken->t) || !ec_point_mul_scalar(group, &Tp, &P, &r) || !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) { @@ -240,7 +294,6 @@ static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out, !cbb_add_point(&cbb, method->group, K1) || !CBB_finish(&cbb, &buf, &len) || !method->hash_to_scalar(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -252,6 +305,30 @@ err: return ok; } +static int hash_to_scalar_challenge(const VOPRF_METHOD *method, EC_SCALAR *out, + const EC_AFFINE *Bm, const EC_AFFINE *a0, + const EC_AFFINE *a1, const EC_AFFINE *a2, + const EC_AFFINE *a3) { + static const uint8_t kChallengeLabel[] = "Challenge"; + + CBB cbb; + uint8_t transcript[5 * EC_MAX_COMPRESSED + 2 + sizeof(kChallengeLabel) - 1]; + size_t len; + if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) || + !cbb_serialize_point(&cbb, method->group, Bm) || + !cbb_serialize_point(&cbb, method->group, a0) || + !cbb_serialize_point(&cbb, method->group, a1) || + !cbb_serialize_point(&cbb, method->group, a2) || + !cbb_serialize_point(&cbb, method->group, a3) || + !CBB_add_bytes(&cbb, kChallengeLabel, sizeof(kChallengeLabel) - 1) || + !CBB_finish(&cbb, NULL, &len) || + !method->hash_to_scalar(method->group, out, transcript, len)) { + return 0; + } + + return 1; +} + static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out, const CBB *points, size_t index) { static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH"; @@ -272,7 +349,6 @@ static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out, !CBB_add_u16(&cbb, (uint16_t)index) || !CBB_finish(&cbb, &buf, &len) || !method->hash_to_scalar(method->group, out, buf, len)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -286,7 +362,7 @@ err: static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb, const TRUST_TOKEN_ISSUER_KEY *priv, - const EC_RAW_POINT *T, const EC_RAW_POINT *W) { + const EC_JACOBIAN *T, const EC_JACOBIAN *W) { const EC_GROUP *group = method->group; enum { @@ -296,7 +372,7 @@ static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb, idx_k1, num_idx, }; - EC_RAW_POINT jacobians[num_idx]; + EC_JACOBIAN jacobians[num_idx]; // Setup the DLEQ proof. EC_SCALAR r; @@ -335,25 +411,24 @@ static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb, // Store DLEQ proof in transcript. if (!scalar_to_cbb(cbb, group, &c) || !scalar_to_cbb(cbb, group, &u)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); return 0; } return 1; } -static int mul_public_2(const EC_GROUP *group, EC_RAW_POINT *out, - const EC_RAW_POINT *p0, const EC_SCALAR *scalar0, - const EC_RAW_POINT *p1, const EC_SCALAR *scalar1) { - EC_RAW_POINT points[2] = {*p0, *p1}; +static int mul_public_2(const EC_GROUP *group, EC_JACOBIAN *out, + const EC_JACOBIAN *p0, const EC_SCALAR *scalar0, + const EC_JACOBIAN *p1, const EC_SCALAR *scalar1) { + EC_JACOBIAN points[2] = {*p0, *p1}; EC_SCALAR scalars[2] = {*scalar0, *scalar1}; return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points, scalars, 2); } static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs, - const TRUST_TOKEN_CLIENT_KEY *pub, const EC_RAW_POINT *T, - const EC_RAW_POINT *W) { + const TRUST_TOKEN_CLIENT_KEY *pub, const EC_JACOBIAN *T, + const EC_JACOBIAN *W) { const EC_GROUP *group = method->group; @@ -364,7 +439,7 @@ static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs, idx_k1, num_idx, }; - EC_RAW_POINT jacobians[num_idx]; + EC_JACOBIAN jacobians[num_idx]; // Decode the DLEQ proof. EC_SCALAR c, u; @@ -375,7 +450,7 @@ static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs, } // k0;k1 = u*(G;T) - c*(pub;W) - EC_RAW_POINT pubs; + EC_JACOBIAN pubs; ec_affine_to_jacobian(group, &pubs, &pub->pubs); EC_SCALAR minus_c; ec_scalar_neg(group, &minus_c, &c); @@ -410,24 +485,24 @@ static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs, return 1; } -static int voprf_sign(const VOPRF_METHOD *method, - const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, - size_t num_requested, size_t num_to_issue) { +static int voprf_sign_tt(const VOPRF_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue) { const EC_GROUP *group = method->group; if (num_requested < num_to_issue) { OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); return 0; } - if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) || + if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) || num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); return 0; } int ret = 0; - EC_RAW_POINT *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT)); + EC_JACOBIAN *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); @@ -436,13 +511,12 @@ static int voprf_sign(const VOPRF_METHOD *method, !es || !CBB_init(&batch_cbb, 0) || !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } for (size_t i = 0; i < num_to_issue; i++) { EC_AFFINE BT_affine, Z_affine; - EC_RAW_POINT BT, Z; + EC_JACOBIAN BT, Z; if (!cbs_get_point(cbs, group, &BT_affine)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); goto err; @@ -456,7 +530,6 @@ static int voprf_sign(const VOPRF_METHOD *method, if (!cbb_add_point(&batch_cbb, group, &BT_affine) || !cbb_add_point(&batch_cbb, group, &Z_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } BTs[i] = BT; @@ -476,7 +549,7 @@ static int voprf_sign(const VOPRF_METHOD *method, } } - EC_RAW_POINT BT_batch, Z_batch; + EC_JACOBIAN BT_batch, Z_batch; if (!ec_point_mul_scalar_public_batch(group, &BT_batch, /*g_scalar=*/NULL, BTs, es, num_to_issue) || @@ -510,39 +583,35 @@ err: return ret; } -static STACK_OF(TRUST_TOKEN) * - voprf_unblind(const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, CBS *cbs, - size_t count, uint32_t key_id) { +static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt( + const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { const EC_GROUP *group = method->group; if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return NULL; } - int ok = 0; - STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); + if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); return NULL; } - if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) || - count > ((size_t)-1) / sizeof(EC_SCALAR)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); - return 0; - } - EC_RAW_POINT *BTs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); - EC_RAW_POINT *Zs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT)); + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); + EC_JACOBIAN *BTs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Zs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR)); CBB batch_cbb; CBB_zero(&batch_cbb); - if (!BTs || - !Zs || - !es || + if (ret == NULL || + BTs == NULL || + Zs == NULL || + es == NULL || !CBB_init(&batch_cbb, 0) || !cbb_add_point(&batch_cbb, method->group, &key->pubs)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } @@ -561,13 +630,12 @@ static STACK_OF(TRUST_TOKEN) * if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) || !cbb_add_point(&batch_cbb, group, &Z_affine)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); goto err; } // Unblind the token. // pretoken->r is rinv. - EC_RAW_POINT N; + EC_JACOBIAN N; EC_AFFINE N_affine; if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) || !ec_jacobian_to_affine(group, &N_affine, &N)) { @@ -580,7 +648,7 @@ static STACK_OF(TRUST_TOKEN) * size_t point_len = 1 + 2 * BN_num_bytes(&group->field); if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) || !CBB_add_u32(&token_cbb, key_id) || - !CBB_add_bytes(&token_cbb, pretoken->t, TRUST_TOKEN_NONCE_SIZE) || + !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) || !cbb_add_point(&token_cbb, group, &N_affine) || !CBB_flush(&token_cbb)) { CBB_cleanup(&token_cbb); @@ -592,7 +660,6 @@ static STACK_OF(TRUST_TOKEN) * CBB_cleanup(&token_cbb); if (token == NULL || !sk_TRUST_TOKEN_push(ret, token)) { - OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE); TRUST_TOKEN_free(token); goto err; } @@ -607,7 +674,7 @@ static STACK_OF(TRUST_TOKEN) * } } - EC_RAW_POINT BT_batch, Z_batch; + EC_JACOBIAN BT_batch, Z_batch; if (!ec_point_mul_scalar_public_batch(group, &BT_batch, /*g_scalar=*/NULL, BTs, es, count) || !ec_point_mul_scalar_public_batch(group, &Z_batch, @@ -636,28 +703,431 @@ err: return ret; } +static void sha384_update_u16(SHA512_CTX *ctx, uint16_t v) { + uint8_t buf[2] = {v >> 8, v & 0xff}; + SHA384_Update(ctx, buf, 2); +} + +static void sha384_update_point_with_length( + SHA512_CTX *ctx, const EC_GROUP *group, const EC_AFFINE *point) { + uint8_t buf[EC_MAX_COMPRESSED]; + size_t len = ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED, + buf, sizeof(buf)); + assert(len > 0); + sha384_update_u16(ctx, (uint16_t)len); + SHA384_Update(ctx, buf, len); +} + +static int compute_composite_seed(const VOPRF_METHOD *method, + uint8_t out[SHA384_DIGEST_LENGTH], + const EC_AFFINE *pub) { + const EC_GROUP *group = method->group; + static const uint8_t kSeedDST[] = "Seed-OPRFV1-\x01-P384-SHA384"; + + SHA512_CTX hash_ctx; + SHA384_Init(&hash_ctx); + sha384_update_point_with_length(&hash_ctx, group, pub); + sha384_update_u16(&hash_ctx, sizeof(kSeedDST) - 1); + SHA384_Update(&hash_ctx, kSeedDST, sizeof(kSeedDST) - 1); + SHA384_Final(out, &hash_ctx); + + return 1; +} + +static int compute_composite_element(const VOPRF_METHOD *method, + uint8_t seed[SHA384_DIGEST_LENGTH], + EC_SCALAR *di, size_t index, + const EC_AFFINE *C, const EC_AFFINE *D) { + static const uint8_t kCompositeLabel[] = "Composite"; + const EC_GROUP *group = method->group; + + if (index > UINT16_MAX) { + return 0; + } + + CBB cbb; + uint8_t transcript[2 + SHA384_DIGEST_LENGTH + 2 + 2 * EC_MAX_COMPRESSED + + sizeof(kCompositeLabel) - 1]; + size_t len; + if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) || + !CBB_add_u16(&cbb, SHA384_DIGEST_LENGTH) || + !CBB_add_bytes(&cbb, seed, SHA384_DIGEST_LENGTH) || + !CBB_add_u16(&cbb, index) || + !cbb_serialize_point(&cbb, group, C) || + !cbb_serialize_point(&cbb, group, D) || + !CBB_add_bytes(&cbb, kCompositeLabel, + sizeof(kCompositeLabel) - 1) || + !CBB_finish(&cbb, NULL, &len) || + !method->hash_to_scalar(method->group, di, transcript, len)) { + return 0; + } + + return 1; +} + +static int generate_proof(const VOPRF_METHOD *method, CBB *cbb, + const TRUST_TOKEN_ISSUER_KEY *priv, + const EC_SCALAR *r, const EC_JACOBIAN *M, + const EC_JACOBIAN *Z) { + const EC_GROUP *group = method->group; + + enum { + idx_M, + idx_Z, + idx_t2, + idx_t3, + num_idx, + }; + EC_JACOBIAN jacobians[num_idx]; + + if (!ec_point_mul_scalar_base(group, &jacobians[idx_t2], r) || + !ec_point_mul_scalar(group, &jacobians[idx_t3], M, r)) { + return 0; + } + + + EC_AFFINE affines[num_idx]; + jacobians[idx_M] = *M; + jacobians[idx_Z] = *Z; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + EC_SCALAR c; + if (!hash_to_scalar_challenge(method, &c, &priv->pubs, &affines[idx_M], + &affines[idx_Z], &affines[idx_t2], + &affines[idx_t3])) { + return 0; + } + + EC_SCALAR c_mont; + ec_scalar_to_montgomery(group, &c_mont, &c); + + // s = r - c*xs + EC_SCALAR s; + ec_scalar_mul_montgomery(group, &s, &priv->xs, &c_mont); + ec_scalar_sub(group, &s, r, &s); + + // Store DLEQ proof in transcript. + if (!scalar_to_cbb(cbb, group, &c) || + !scalar_to_cbb(cbb, group, &s)) { + return 0; + } + + return 1; +} + +static int verify_proof(const VOPRF_METHOD *method, CBS *cbs, + const TRUST_TOKEN_CLIENT_KEY *pub, + const EC_JACOBIAN *M, const EC_JACOBIAN *Z) { + const EC_GROUP *group = method->group; + + enum { + idx_M, + idx_Z, + idx_t2, + idx_t3, + num_idx, + }; + EC_JACOBIAN jacobians[num_idx]; + + EC_SCALAR c, s; + if (!scalar_from_cbs(cbs, group, &c) || + !scalar_from_cbs(cbs, group, &s)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return 0; + } + + EC_JACOBIAN pubs; + ec_affine_to_jacobian(group, &pubs, &pub->pubs); + if (!ec_point_mul_scalar_public(group, &jacobians[idx_t2], &s, &pubs, + &c) || + !mul_public_2(group, &jacobians[idx_t3], M, &s, Z, &c)) { + return 0; + } + + EC_AFFINE affines[num_idx]; + jacobians[idx_M] = *M; + jacobians[idx_Z] = *Z; + if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) { + return 0; + } + + EC_SCALAR expected_c; + if (!hash_to_scalar_challenge(method, &expected_c, &pub->pubs, + &affines[idx_M], &affines[idx_Z], + &affines[idx_t2], &affines[idx_t3])) { + return 0; + } + + // c == expected_c + if (!ec_scalar_equal_vartime(group, &c, &expected_c)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF); + return 0; + } + + return 1; +} + +static int voprf_sign_impl(const VOPRF_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, + CBS *cbs, size_t num_requested, size_t num_to_issue, + const EC_SCALAR *proof_scalar) { + const EC_GROUP *group = method->group; + if (num_requested < num_to_issue) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (num_to_issue > ((size_t)-1) / sizeof(EC_JACOBIAN) || + num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return 0; + } + + int ret = 0; + EC_JACOBIAN *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_JACOBIAN)); + EC_SCALAR *dis = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR)); + if (!BTs || !Zs || !dis) { + goto err; + } + + uint8_t seed[SHA384_DIGEST_LENGTH]; + if (!compute_composite_seed(method, seed, &key->pubs)) { + goto err; + } + + // This implements the BlindEvaluateBatch as defined in section 4 of + // draft-robert-privacypass-batched-tokens-01, based on the constructions + // in draft-irtf-cfrg-voprf-21. To optimize the computation of the proof, + // the computation of di is done during the token signing and passed into + // the proof generation. + for (size_t i = 0; i < num_to_issue; i++) { + EC_AFFINE BT_affine, Z_affine; + EC_JACOBIAN BT, Z; + if (!cbs_get_point(cbs, group, &BT_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + ec_affine_to_jacobian(group, &BT, &BT_affine); + if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) || + !ec_jacobian_to_affine(group, &Z_affine, &Z) || + !cbb_add_point(cbb, group, &Z_affine)) { + goto err; + } + BTs[i] = BT; + Zs[i] = Z; + if (!compute_composite_element(method, seed, &dis[i], i, &BT_affine, + &Z_affine)) { + goto err; + } + + if (!CBB_flush(cbb)) { + goto err; + } + } + + EC_JACOBIAN M, Z; + if (!ec_point_mul_scalar_public_batch(group, &M, + /*g_scalar=*/NULL, BTs, dis, + num_to_issue) || + !ec_point_mul_scalar(group, &Z, &M, &key->xs)) { + goto err; + } + + CBB proof; + if (!CBB_add_u16_length_prefixed(cbb, &proof) || + !generate_proof(method, &proof, key, proof_scalar, &M, &Z) || + !CBB_flush(cbb)) { + goto err; + } + + // Skip over any unused requests. + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(BTs); + OPENSSL_free(Zs); + OPENSSL_free(dis); + return ret; +} + +static int voprf_sign(const VOPRF_METHOD *method, + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue) { + EC_SCALAR proof_scalar; + if (!ec_random_nonzero_scalar(method->group, &proof_scalar, + kDefaultAdditionalData)) { + return 0; + } + + return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue, + &proof_scalar); +} + +static int voprf_sign_with_proof_scalar_for_testing( + const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, + CBS *cbs, size_t num_requested, size_t num_to_issue, + const uint8_t *proof_scalar_buf, size_t proof_scalar_len) { + EC_SCALAR proof_scalar; + if (!ec_scalar_from_bytes(method->group, &proof_scalar, proof_scalar_buf, + proof_scalar_len)) { + return 0; + } + return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue, + &proof_scalar); +} + +static STACK_OF(TRUST_TOKEN) *voprf_unblind( + const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { + const EC_GROUP *group = method->group; + if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + return NULL; + } + + if (count > ((size_t)-1) / sizeof(EC_JACOBIAN) || + count > ((size_t)-1) / sizeof(EC_SCALAR)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW); + return NULL; + } + + int ok = 0; + STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null(); + EC_JACOBIAN *BTs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_JACOBIAN *Zs = OPENSSL_malloc(count * sizeof(EC_JACOBIAN)); + EC_SCALAR *dis = OPENSSL_malloc(count * sizeof(EC_SCALAR)); + if (ret == NULL || !BTs || !Zs || !dis) { + goto err; + } + + uint8_t seed[SHA384_DIGEST_LENGTH]; + if (!compute_composite_seed(method, seed, &key->pubs)) { + goto err; + } + + for (size_t i = 0; i < count; i++) { + const TRUST_TOKEN_PRETOKEN *pretoken = + sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i); + + EC_AFFINE Z_affine; + if (!cbs_get_point(cbs, group, &Z_affine)) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); + goto err; + } + + ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp); + ec_affine_to_jacobian(group, &Zs[i], &Z_affine); + if (!compute_composite_element(method, seed, &dis[i], i, &pretoken->Tp, + &Z_affine)) { + goto err; + } + + // Unblind the token. + // pretoken->r is rinv. + EC_JACOBIAN N; + EC_AFFINE N_affine; + if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) || + !ec_jacobian_to_affine(group, &N_affine, &N)) { + goto err; + } + + // Serialize the token. Include |key_id| to avoid an extra copy in the layer + // above. + CBB token_cbb; + size_t point_len = 1 + 2 * BN_num_bytes(&group->field); + if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) || + !CBB_add_u32(&token_cbb, key_id) || + !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) || + !cbb_add_point(&token_cbb, group, &N_affine) || + !CBB_flush(&token_cbb)) { + CBB_cleanup(&token_cbb); + goto err; + } + + TRUST_TOKEN *token = + TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb)); + CBB_cleanup(&token_cbb); + if (token == NULL || + !sk_TRUST_TOKEN_push(ret, token)) { + TRUST_TOKEN_free(token); + goto err; + } + } + + EC_JACOBIAN M, Z; + if (!ec_point_mul_scalar_public_batch(group, &M, + /*g_scalar=*/NULL, BTs, dis, + count) || + !ec_point_mul_scalar_public_batch(group, &Z, + /*g_scalar=*/NULL, Zs, dis, + count)) { + goto err; + } + + CBS proof; + if (!CBS_get_u16_length_prefixed(cbs, &proof) || + !verify_proof(method, &proof, key, &M, &Z) || + CBS_len(&proof) != 0) { + goto err; + } + + ok = 1; + +err: + OPENSSL_free(BTs); + OPENSSL_free(Zs); + OPENSSL_free(dis); + if (!ok) { + sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free); + ret = NULL; + } + return ret; +} + static int voprf_read(const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], - const uint8_t *token, size_t token_len) { + const uint8_t *token, size_t token_len, + int include_message, const uint8_t *msg, size_t msg_len) { const EC_GROUP *group = method->group; - CBS cbs; + CBS cbs, salt; CBS_init(&cbs, token, token_len); EC_AFFINE Ws; - if (!CBS_copy_bytes(&cbs, out_nonce, TRUST_TOKEN_NONCE_SIZE) || + if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) || !cbs_get_point(&cbs, group, &Ws) || CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN); return 0; } + if (include_message) { + SHA512_CTX hash_ctx; + assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE); + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt)); + SHA512_Update(&hash_ctx, msg, msg_len); + SHA512_Final(out_nonce, &hash_ctx); + } else { + OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt)); + } - EC_RAW_POINT T; + + EC_JACOBIAN T; if (!method->hash_to_group(group, &T, out_nonce)) { return 0; } - EC_RAW_POINT Ws_calculated; + EC_JACOBIAN Ws_calculated; if (!ec_point_mul_scalar(group, &Ws_calculated, &T, &key->xs) || !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK); @@ -670,7 +1140,7 @@ static int voprf_read(const VOPRF_METHOD *method, // VOPRF experiment v2. -static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_RAW_POINT *out, +static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out, const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { const uint8_t kHashTLabel[] = "TrustToken VOPRF Experiment V2 HashToGroup"; return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( @@ -711,6 +1181,17 @@ int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) { return voprf_generate_key(&voprf_exp2_method, out_private, out_public); } +int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!voprf_exp2_init_method()) { + return 0; + } + + return voprf_derive_key_from_secret(&voprf_exp2_method, out_private, + out_public, secret, secret_len); +} + int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, const uint8_t *in, size_t len) { if (!voprf_exp2_init_method()) { @@ -727,11 +1208,15 @@ int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len); } -STACK_OF(TRUST_TOKEN_PRETOKEN) * voprf_exp2_blind(CBB *cbb, size_t count) { +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { if (!voprf_exp2_init_method()) { return NULL; } - return voprf_blind(&voprf_exp2_method, cbb, count); + return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg, + msg_len); } int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, @@ -740,27 +1225,156 @@ int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, if (!voprf_exp2_init_method() || private_metadata != 0) { return 0; } - return voprf_sign(&voprf_exp2_method, key, cbb, cbs, num_requested, - num_to_issue); + return voprf_sign_tt(&voprf_exp2_method, key, cbb, cbs, num_requested, + num_to_issue); } -STACK_OF(TRUST_TOKEN) * - voprf_exp2_unblind(const TRUST_TOKEN_CLIENT_KEY *key, - const STACK_OF(TRUST_TOKEN_PRETOKEN) * pretokens, - CBS *cbs, size_t count, uint32_t key_id) { +STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { if (!voprf_exp2_init_method()) { return NULL; } - return voprf_unblind(&voprf_exp2_method, key, pretokens, cbs, count, + return voprf_unblind_tt(&voprf_exp2_method, key, pretokens, cbs, count, key_id); } int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key, uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], uint8_t *out_private_metadata, const uint8_t *token, - size_t token_len) { + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len) { if (!voprf_exp2_init_method()) { return 0; } - return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len); + return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len, + include_message, msg, msg_len); +} + +// VOPRF PST v1. + +static int voprf_pst1_hash_to_group(const EC_GROUP *group, EC_JACOBIAN *out, + const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) { + const uint8_t kHashTLabel[] = "HashToGroup-OPRFV1-\x01-P384-SHA384"; + return ec_hash_to_curve_p384_xmd_sha384_sswu(group, out, kHashTLabel, + sizeof(kHashTLabel) - 1, t, + TRUST_TOKEN_NONCE_SIZE); +} + +static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + uint8_t *buf, size_t len) { + const uint8_t kHashCLabel[] = "HashToScalar-OPRFV1-\x01-P384-SHA384"; + return ec_hash_to_scalar_p384_xmd_sha384(group, out, kHashCLabel, + sizeof(kHashCLabel) - 1, buf, len); +} + +static int voprf_pst1_ok = 0; +static VOPRF_METHOD voprf_pst1_method; +static CRYPTO_once_t voprf_pst1_method_once = CRYPTO_ONCE_INIT; + +static void voprf_pst1_init_method_impl(void) { + voprf_pst1_ok = + voprf_init_method(&voprf_pst1_method, NID_secp384r1, + voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar); +} + +static int voprf_pst1_init_method(void) { + CRYPTO_once(&voprf_pst1_method_once, voprf_pst1_init_method_impl); + if (!voprf_pst1_ok) { + OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) { + if (!voprf_pst1_init_method()) { + return 0; + } + + return voprf_generate_key(&voprf_pst1_method, out_private, out_public); +} + +int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public, + const uint8_t *secret, + size_t secret_len) { + if (!voprf_pst1_init_method()) { + return 0; + } + + return voprf_derive_key_from_secret(&voprf_pst1_method, out_private, + out_public, secret, secret_len); +} + +int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len); +} + +int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key, + const uint8_t *in, size_t len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len); +} + +STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count, + int include_message, + const uint8_t *msg, + size_t msg_len) { + if (!voprf_pst1_init_method()) { + return NULL; + } + return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg, + msg_len); +} + +int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, + size_t num_requested, size_t num_to_issue, + uint8_t private_metadata) { + if (!voprf_pst1_init_method() || private_metadata != 0) { + return 0; + } + return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested, + num_to_issue); +} + + +int voprf_pst1_sign_with_proof_scalar_for_testing( + const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested, + size_t num_to_issue, uint8_t private_metadata, + const uint8_t *proof_scalar_buf, size_t proof_scalar_len) { + if (!voprf_pst1_init_method() || private_metadata != 0) { + return 0; + } + return voprf_sign_with_proof_scalar_for_testing( + &voprf_pst1_method, key, cbb, cbs, num_requested, num_to_issue, + proof_scalar_buf, proof_scalar_len); +} + +STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind( + const TRUST_TOKEN_CLIENT_KEY *key, + const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count, + uint32_t key_id) { + if (!voprf_pst1_init_method()) { + return NULL; + } + return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id); +} + +int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key, + uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE], + uint8_t *out_private_metadata, const uint8_t *token, + size_t token_len, int include_message, const uint8_t *msg, + size_t msg_len) { + if (!voprf_pst1_init_method()) { + return 0; + } + return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len, + include_message, msg, msg_len); } diff --git a/third_party/boringssl/kit/src/crypto/x509/a_digest.c b/third_party/boringssl/kit/src/crypto/x509/a_digest.c index b88d6ac7..4686993e 100644 --- a/third_party/boringssl/kit/src/crypto/x509/a_digest.c +++ b/third_party/boringssl/kit/src/crypto/x509/a_digest.c @@ -62,35 +62,33 @@ #include int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, - unsigned char *md, unsigned int *len) -{ - int i, ret; - unsigned char *str, *p; + unsigned char *md, unsigned int *len) { + int i, ret; + unsigned char *str, *p; - i = i2d(data, NULL); - if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return (0); - } - p = str; - i2d(data, &p); + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + return 0; + } + p = str; + i2d(data, &p); - ret = EVP_Digest(str, i, md, len, type, NULL); - OPENSSL_free(str); - return ret; + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; } int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, - unsigned char *md, unsigned int *len) -{ - int i, ret; - unsigned char *str = NULL; + unsigned char *md, unsigned int *len) { + int i, ret; + unsigned char *str = NULL; - i = ASN1_item_i2d(asn, &str, it); - if (!str) - return (0); + i = ASN1_item_i2d(asn, &str, it); + if (!str) { + return 0; + } - ret = EVP_Digest(str, i, md, len, type, NULL); - OPENSSL_free(str); - return ret; + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/a_sign.c b/third_party/boringssl/kit/src/crypto/x509/a_sign.c index 6c7f7136..7f80e5b0 100644 --- a/third_party/boringssl/kit/src/crypto/x509/a_sign.c +++ b/third_party/boringssl/kit/src/crypto/x509/a_sign.c @@ -62,67 +62,75 @@ #include #include +#include + #include "internal.h" -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey, const EVP_MD *type) -{ - EVP_MD_CTX ctx; - EVP_MD_CTX_init(&ctx); - if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { - EVP_MD_CTX_cleanup(&ctx); - return 0; - } - return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, + const EVP_MD *type) { + if (signature->type != V_ASN1_BIT_STRING) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { + EVP_MD_CTX_cleanup(&ctx); + return 0; + } + return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); } -int ASN1_item_sign_ctx(const ASN1_ITEM *it, - X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) -{ - EVP_PKEY *pkey; - unsigned char *buf_in = NULL, *buf_out = NULL; - size_t inl = 0, outl = 0; +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx) { + int ret = 0; + uint8_t *in = NULL, *out = NULL; + if (signature->type != V_ASN1_BIT_STRING) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + goto err; + } - pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + // Write out the requested copies of the AlgorithmIdentifier. + if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { + goto err; + } + if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { + goto err; + } - /* Write out the requested copies of the AlgorithmIdentifier. */ - if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { - goto err; - } - if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { - goto err; - } + int in_len = ASN1_item_i2d(asn, &in, it); + if (in_len < 0) { + goto err; + } - inl = ASN1_item_i2d(asn, &buf_in, it); - outl = EVP_PKEY_size(pkey); - buf_out = OPENSSL_malloc((unsigned int)outl); - if ((buf_in == NULL) || (buf_out == NULL)) { - outl = 0; - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto err; - } + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + size_t out_len = EVP_PKEY_size(pkey); + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + goto err; + } - if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { - outl = 0; - OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; - } - if (signature->data != NULL) - OPENSSL_free(signature->data); - signature->data = buf_out; - buf_out = NULL; - signature->length = outl; - /* - * In the interests of compatibility, I'll make sure that the bit string - * has a 'not-used bits' value of 0 - */ - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - err: - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(buf_in); - OPENSSL_free(buf_out); - return (outl); + out = OPENSSL_malloc(out_len); + if (out == NULL) { + goto err; + } + + if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } + + ASN1_STRING_set0(signature, out, (int)out_len); + out = NULL; + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ret = (int)out_len; + +err: + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(in); + OPENSSL_free(out); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/a_verify.c b/third_party/boringssl/kit/src/crypto/x509/a_verify.c index ec671c03..a70769fd 100644 --- a/third_party/boringssl/kit/src/crypto/x509/a_verify.c +++ b/third_party/boringssl/kit/src/crypto/x509/a_verify.c @@ -57,7 +57,6 @@ #include #include -#include #include #include @@ -72,47 +71,46 @@ int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, const ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { - if (!pkey) { - OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - return 0; + if (!pkey) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + size_t sig_len; + if (signature->type == V_ASN1_BIT_STRING) { + if (!ASN1_BIT_STRING_num_bytes(signature, &sig_len)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; } + } else { + sig_len = (size_t)ASN1_STRING_length(signature); + } - size_t sig_len; - if (signature->type == V_ASN1_BIT_STRING) { - if (!ASN1_BIT_STRING_num_bytes(signature, &sig_len)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); - return 0; - } - } else { - sig_len = (size_t)ASN1_STRING_length(signature); - } + EVP_MD_CTX ctx; + uint8_t *buf_in = NULL; + int ret = 0, inl = 0; + EVP_MD_CTX_init(&ctx); - EVP_MD_CTX ctx; - uint8_t *buf_in = NULL; - int ret = 0, inl = 0; - EVP_MD_CTX_init(&ctx); + if (!x509_digest_verify_init(&ctx, a, pkey)) { + goto err; + } - if (!x509_digest_verify_init(&ctx, a, pkey)) { - goto err; - } + inl = ASN1_item_i2d(asn, &buf_in, it); - inl = ASN1_item_i2d(asn, &buf_in, it); + if (buf_in == NULL) { + goto err; + } - if (buf_in == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto err; - } + if (!EVP_DigestVerify(&ctx, ASN1_STRING_get0_data(signature), sig_len, buf_in, + inl)) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } - if (!EVP_DigestVerify(&ctx, ASN1_STRING_get0_data(signature), sig_len, - buf_in, inl)) { - OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; - } - - ret = 1; + ret = 1; err: - OPENSSL_free(buf_in); - EVP_MD_CTX_cleanup(&ctx); - return ret; + OPENSSL_free(buf_in); + EVP_MD_CTX_cleanup(&ctx); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/algorithm.c b/third_party/boringssl/kit/src/crypto/x509/algorithm.c index 7f904803..16235eee 100644 --- a/third_party/boringssl/kit/src/crypto/x509/algorithm.c +++ b/third_party/boringssl/kit/src/crypto/x509/algorithm.c @@ -64,6 +64,15 @@ #include "internal.h" +// Restrict the digests that are allowed in X509 certificates +static int x509_digest_nid_ok(const int digest_nid) { + switch (digest_nid) { + case NID_md4: + case NID_md5: + return 0; + } + return 1; +} int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); @@ -77,7 +86,7 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { return 0; } - /* RSA-PSS has special signature algorithm logic. */ + // RSA-PSS has special signature algorithm logic. if (pad_mode == RSA_PKCS1_PSS_PADDING) { return x509_rsa_ctx_to_pss(ctx, algor); } @@ -87,23 +96,24 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); } - /* Default behavior: look up the OID for the algorithm/hash pair and encode - * that. */ + // Default behavior: look up the OID for the algorithm/hash pair and encode + // that. const EVP_MD *digest = EVP_MD_CTX_md(ctx); if (digest == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } + const int digest_nid = EVP_MD_type(digest); int sign_nid; - if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), - EVP_PKEY_id(pkey))) { + if (!x509_digest_nid_ok(digest_nid) || + !OBJ_find_sigid_by_algs(&sign_nid, digest_nid, EVP_PKEY_id(pkey))) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } - /* RSA signature algorithms include an explicit NULL parameter. Others omit - * it. */ + // RSA signature algorithms include an explicit NULL parameter. Others omit + // it. int paramtype = (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); @@ -112,7 +122,7 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey) { - /* Convert the signature OID into digest and public key OIDs. */ + // Convert the signature OID into digest and public key OIDs. int sigalg_nid = OBJ_obj2nid(sigalg->algorithm); int digest_nid, pkey_nid; if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) { @@ -120,13 +130,19 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, return 0; } - /* Check the public key OID matches the public key type. */ + // Check the public key OID matches the public key type. if (pkey_nid != EVP_PKEY_id(pkey)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); return 0; } - /* NID_undef signals that there are custom parameters to set. */ + // Check for permitted digest algorithms + if (!x509_digest_nid_ok(digest_nid)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + + // NID_undef signals that there are custom parameters to set. if (digest_nid == NID_undef) { if (sigalg_nid == NID_rsassaPss) { return x509_rsa_pss_to_ctx(ctx, sigalg, pkey); @@ -142,17 +158,17 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, return 0; } - /* The parameter should be an explicit NULL for RSA and omitted for ECDSA. For - * compatibility, we allow either for both algorithms. See b/167375496. - * - * TODO(davidben): Chromium's verifier allows both forms for RSA, but enforces - * ECDSA more strictly. Align with Chromium and add a flag for b/167375496. */ + // The parameter should be an explicit NULL for RSA and omitted for ECDSA. For + // compatibility, we allow either for both algorithms. See b/167375496. + // + // TODO(davidben): Chromium's verifier allows both forms for RSA, but enforces + // ECDSA more strictly. Align with Chromium and add a flag for b/167375496. if (sigalg->parameter != NULL && sigalg->parameter->type != V_ASN1_NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); return 0; } - /* Otherwise, initialize with the digest from the OID. */ + // Otherwise, initialize with the digest from the OID. const EVP_MD *digest = EVP_get_digestbynid(digest_nid); if (digest == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); diff --git a/third_party/boringssl/kit/src/crypto/x509/asn1_gen.c b/third_party/boringssl/kit/src/crypto/x509/asn1_gen.c index cd8185bf..321f63be 100644 --- a/third_party/boringssl/kit/src/crypto/x509/asn1_gen.c +++ b/third_party/boringssl/kit/src/crypto/x509/asn1_gen.c @@ -56,771 +56,532 @@ #include +#include +#include +#include #include #include +#include #include -#include #include #include +#include "../conf/internal.h" #include "../internal.h" #include "../x509v3/internal.h" #include "internal.h" -/* - * Although this file is in crypto/x509 for layering purposes, it emits - * errors from the ASN.1 module for OpenSSL compatibility. - */ -#define ASN1_GEN_FLAG 0x10000 -#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) -#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) -#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) -#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) -#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) -#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) -#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) -#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) +// Although this file is in crypto/x509 for layering purposes, it emits +// errors from the ASN.1 module for OpenSSL compatibility. -#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} +// ASN1_GEN_MAX_DEPTH is the maximum number of nested TLVs allowed. +#define ASN1_GEN_MAX_DEPTH 50 -#define ASN1_FLAG_EXP_MAX 20 -/* Maximum number of nested sequences */ -#define ASN1_GEN_SEQ_MAX_DEPTH 50 +// ASN1_GEN_MAX_OUTPUT is the maximum output, in bytes, allowed. This limit is +// necessary because the SEQUENCE and SET section reference mechanism allows the +// output length to grow super-linearly with the input length. +#define ASN1_GEN_MAX_OUTPUT (64 * 1024) -/* Input formats */ - -/* ASCII: default */ -#define ASN1_GEN_FORMAT_ASCII 1 -/* UTF8 */ -#define ASN1_GEN_FORMAT_UTF8 2 -/* Hex */ -#define ASN1_GEN_FORMAT_HEX 3 -/* List of bits */ +// ASN1_GEN_FORMAT_* are the values for the format modifiers. +#define ASN1_GEN_FORMAT_ASCII 1 +#define ASN1_GEN_FORMAT_UTF8 2 +#define ASN1_GEN_FORMAT_HEX 3 #define ASN1_GEN_FORMAT_BITLIST 4 -struct tag_name_st { - const char *strnam; - int len; - int tag; -}; +// generate_v3 converts |str| into an ASN.1 structure and writes the result to +// |cbb|. It returns one on success and zero on error. |depth| bounds recursion, +// and |format| specifies the current format modifier. +// +// If |tag| is non-zero, the structure is implicitly tagged with |tag|. |tag| +// must not have the constructed bit set. +static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int format, int depth); -typedef struct { - int exp_tag; - int exp_class; - int exp_constructed; - int exp_pad; - long exp_len; -} tag_exp_type; +static int bitstr_cb(const char *elem, size_t len, void *bitstr); -typedef struct { - int imp_tag; - int imp_class; - int utype; - int format; - const char *str; - tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; - int exp_count; -} tag_exp_arg; +ASN1_TYPE *ASN1_generate_v3(const char *str, const X509V3_CTX *cnf) { + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !generate_v3(&cbb, str, cnf, /*tag=*/0, ASN1_GEN_FORMAT_ASCII, + /*depth=*/0)) { + CBB_cleanup(&cbb); + return NULL; + } -static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, - int *perr); -static int bitstr_cb(const char *elem, int len, void *bitstr); -static int asn1_cb(const char *elem, int len, void *bitstr); -static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, - int exp_constructed, int exp_pad, int imp_ok); -static int parse_tagging(const char *vstart, int vlen, int *ptag, - int *pclass); -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, - int depth, int *perr); -static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); -static int asn1_str2tag(const char *tagstr, int len); + // While not strictly necessary to avoid a DoS (we rely on any super-linear + // checks being performed internally), cap the overall output to + // |ASN1_GEN_MAX_OUTPUT| so the externally-visible behavior is consistent. + if (CBB_len(&cbb) > ASN1_GEN_MAX_OUTPUT) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + CBB_cleanup(&cbb); + return NULL; + } -ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) -{ - int err = 0; - ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); - if (err) - OPENSSL_PUT_ERROR(ASN1, err); - return ret; + const uint8_t *der = CBB_data(&cbb); + ASN1_TYPE *ret = d2i_ASN1_TYPE(NULL, &der, CBB_len(&cbb)); + CBB_cleanup(&cbb); + return ret; } -static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, - int *perr) -{ - ASN1_TYPE *ret; - tag_exp_arg asn1_tags; - tag_exp_type *etmp; - - int i, len; - - unsigned char *orig_der = NULL, *new_der = NULL; - const unsigned char *cpy_start; - unsigned char *p; - const unsigned char *cp; - int cpy_len; - long hdr_len = 0; - int hdr_constructed = 0, hdr_tag, hdr_class; - int r; - - asn1_tags.imp_tag = -1; - asn1_tags.imp_class = -1; - asn1_tags.format = ASN1_GEN_FORMAT_ASCII; - asn1_tags.exp_count = 0; - if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { - *perr = ASN1_R_UNKNOWN_TAG; - return NULL; - } - - if ((asn1_tags.utype == V_ASN1_SEQUENCE) - || (asn1_tags.utype == V_ASN1_SET)) { - if (!cnf) { - *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; - return NULL; - } - if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { - *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; - return NULL; - } - ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); - } else - ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); - - if (!ret) - return NULL; - - /* If no tagging return base type */ - if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) - return ret; - - /* Generate the encoding */ - cpy_len = i2d_ASN1_TYPE(ret, &orig_der); - ASN1_TYPE_free(ret); - ret = NULL; - /* Set point to start copying for modified encoding */ - cpy_start = orig_der; - - /* Do we need IMPLICIT tagging? */ - if (asn1_tags.imp_tag != -1) { - /* If IMPLICIT we will replace the underlying tag */ - /* Skip existing tag+len */ - r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, - cpy_len); - if (r & 0x80) - goto err; - /* Update copy length */ - cpy_len -= cpy_start - orig_der; - /* - * For IMPLICIT tagging the length should match the original length - * and constructed flag should be consistent. - */ - hdr_constructed = r & V_ASN1_CONSTRUCTED; - /* - * Work out new length with IMPLICIT tag: ignore constructed because - * it will mess up if indefinite length - */ - len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); - } else - len = cpy_len; - - /* Work out length in any EXPLICIT, starting from end */ - - for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; - i < asn1_tags.exp_count; i++, etmp--) { - /* Content length: number of content octets + any padding */ - len += etmp->exp_pad; - etmp->exp_len = len; - /* Total object length: length including new header */ - len = ASN1_object_size(0, len, etmp->exp_tag); - } - - /* Allocate buffer for new encoding */ - - new_der = OPENSSL_malloc(len); - if (!new_der) - goto err; - - /* Generate tagged encoding */ - - p = new_der; - - /* Output explicit tags first */ - - for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; - i++, etmp++) { - ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, - etmp->exp_tag, etmp->exp_class); - if (etmp->exp_pad) - *p++ = 0; - } - - /* If IMPLICIT, output tag */ - - if (asn1_tags.imp_tag != -1) { - if (asn1_tags.imp_class == V_ASN1_UNIVERSAL - && (asn1_tags.imp_tag == V_ASN1_SEQUENCE - || asn1_tags.imp_tag == V_ASN1_SET)) - hdr_constructed = V_ASN1_CONSTRUCTED; - ASN1_put_object(&p, hdr_constructed, hdr_len, - asn1_tags.imp_tag, asn1_tags.imp_class); - } - - /* Copy across original encoding */ - OPENSSL_memcpy(p, cpy_start, cpy_len); - - cp = new_der; - - /* Obtain new ASN1_TYPE structure */ - ret = d2i_ASN1_TYPE(NULL, &cp, len); - - err: - if (orig_der) - OPENSSL_free(orig_der); - if (new_der) - OPENSSL_free(new_der); - - return ret; - +static int cbs_str_equal(const CBS *cbs, const char *str) { + return CBS_len(cbs) == strlen(str) && + OPENSSL_memcmp(CBS_data(cbs), str, strlen(str)) == 0; } -static int asn1_cb(const char *elem, int len, void *bitstr) -{ - tag_exp_arg *arg = bitstr; - int i; - int utype; - int vlen = 0; - const char *p, *vstart = NULL; +// parse_tag decodes a tag specifier in |cbs|. It returns the tag on success or +// zero on error. +static CBS_ASN1_TAG parse_tag(const CBS *cbs) { + CBS copy = *cbs; + uint64_t num; + if (!CBS_get_u64_decimal(©, &num) || + num > CBS_ASN1_TAG_NUMBER_MASK) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } - int tmp_tag, tmp_class; - - if (elem == NULL) - return -1; - - for (i = 0, p = elem; i < len; p++, i++) { - /* Look for the ':' in name value pairs */ - if (*p == ':') { - vstart = p + 1; - vlen = len - (vstart - elem); - len = p - elem; - break; - } - } - - utype = asn1_str2tag(elem, len); - - if (utype == -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); - ERR_add_error_data(2, "tag=", elem); - return -1; - } - - /* If this is not a modifier mark end of string and exit */ - if (!(utype & ASN1_GEN_FLAG)) { - arg->utype = utype; - arg->str = vstart; - /* If no value and not end of string, error */ - if (!vstart && elem[len]) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); - return -1; - } + CBS_ASN1_TAG tag_class = CBS_ASN1_CONTEXT_SPECIFIC; + // The tag may be suffixed by a class. + uint8_t c; + if (CBS_get_u8(©, &c)) { + switch (c) { + case 'U': + tag_class = CBS_ASN1_UNIVERSAL; + break; + case 'A': + tag_class = CBS_ASN1_APPLICATION; + break; + case 'P': + tag_class = CBS_ASN1_PRIVATE; + break; + case 'C': + tag_class = CBS_ASN1_CONTEXT_SPECIFIC; + break; + default: { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); return 0; + } } - - switch (utype) { - - case ASN1_GEN_FLAG_IMP: - /* Check for illegal multiple IMPLICIT tagging */ - if (arg->imp_tag != -1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); - return -1; - } - if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) - return -1; - break; - - case ASN1_GEN_FLAG_EXP: - - if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) - return -1; - if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) - return -1; - break; - - case ASN1_GEN_FLAG_SEQWRAP: - if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_SETWRAP: - if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_BITWRAP: - if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_OCTWRAP: - if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_FORMAT: - if (!vstart) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); - return -1; - } - if (!strncmp(vstart, "ASCII", 5)) - arg->format = ASN1_GEN_FORMAT_ASCII; - else if (!strncmp(vstart, "UTF8", 4)) - arg->format = ASN1_GEN_FORMAT_UTF8; - else if (!strncmp(vstart, "HEX", 3)) - arg->format = ASN1_GEN_FORMAT_HEX; - else if (!strncmp(vstart, "BITLIST", 7)) - arg->format = ASN1_GEN_FORMAT_BITLIST; - else { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); - return -1; - } - break; - + if (CBS_len(©) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); + return 0; } + } - return 1; + // Tag [UNIVERSAL 0] is reserved for indefinite-length end-of-contents. We + // also use zero in this file to indicator no explicit tagging. + if (tag_class == CBS_ASN1_UNIVERSAL && num == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + return tag_class | (CBS_ASN1_TAG)num; } -static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) -{ - char erch[2]; - long tag_num; - char *eptr; - if (!vstart) - return 0; - tag_num = strtoul(vstart, &eptr, 10); - /* Check we haven't gone past max length: should be impossible */ - if (eptr && *eptr && (eptr > vstart + vlen)) - return 0; - if (tag_num < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); - return 0; - } - *ptag = tag_num; - /* If we have non numeric characters, parse them */ - if (eptr) - vlen -= eptr - vstart; - else - vlen = 0; - if (vlen) { - switch (*eptr) { - - case 'U': - *pclass = V_ASN1_UNIVERSAL; - break; - - case 'A': - *pclass = V_ASN1_APPLICATION; - break; - - case 'P': - *pclass = V_ASN1_PRIVATE; - break; - - case 'C': - *pclass = V_ASN1_CONTEXT_SPECIFIC; - break; - - default: - erch[0] = *eptr; - erch[1] = 0; - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER); - ERR_add_error_data(2, "Char=", erch); - return 0; - break; - - } - } else - *pclass = V_ASN1_CONTEXT_SPECIFIC; - - return 1; - +static int generate_wrapped(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int padding, int format, + int depth) { + CBB child; + return CBB_add_asn1(cbb, &child, tag) && + (!padding || CBB_add_u8(&child, 0)) && + generate_v3(&child, str, cnf, /*tag=*/0, format, depth + 1) && + CBB_flush(cbb); } -/* Handle multiple types: SET and SEQUENCE */ +static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, + CBS_ASN1_TAG tag, int format, int depth) { + assert((tag & CBS_ASN1_CONSTRUCTED) == 0); + if (depth > ASN1_GEN_MAX_DEPTH) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; + } -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, - int depth, int *perr) -{ - ASN1_TYPE *ret = NULL; - STACK_OF(ASN1_TYPE) *sk = NULL; - STACK_OF(CONF_VALUE) *sect = NULL; - unsigned char *der = NULL; - int derlen; - size_t i; - sk = sk_ASN1_TYPE_new_null(); - if (!sk) - goto bad; - if (section) { - if (!cnf) - goto bad; - sect = X509V3_get_section(cnf, (char *)section); - if (!sect) - goto bad; - for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { - ASN1_TYPE *typ = - generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, - depth + 1, perr); - if (!typ) - goto bad; - if (!sk_ASN1_TYPE_push(sk, typ)) - goto bad; - } + // Process modifiers. This function uses a mix of NUL-terminated strings and + // |CBS|. Several functions only work with NUL-terminated strings, so we need + // to keep track of when a slice spans the whole buffer. + for (;;) { + // Skip whitespace. + while (*str != '\0' && OPENSSL_isspace((unsigned char)*str)) { + str++; } - /* - * Now we has a STACK of the components, convert to the correct form - */ - - if (utype == V_ASN1_SET) - derlen = i2d_ASN1_SET_ANY(sk, &der); - else - derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); - - if (derlen < 0) - goto bad; - - if (!(ret = ASN1_TYPE_new())) - goto bad; - - if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) - goto bad; - - ret->type = utype; - - ret->value.asn1_string->data = der; - ret->value.asn1_string->length = derlen; - - der = NULL; - - bad: - - if (der) - OPENSSL_free(der); - - if (sk) - sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); - if (sect) - X509V3_section_free(cnf, sect); - - return ret; -} - -static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, - int exp_constructed, int exp_pad, int imp_ok) -{ - tag_exp_type *exp_tmp; - /* Can only have IMPLICIT if permitted */ - if ((arg->imp_tag != -1) && !imp_ok) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); - return 0; + // Modifiers end at commas. + const char *comma = strchr(str, ','); + if (comma == NULL) { + break; } - if (arg->exp_count == ASN1_FLAG_EXP_MAX) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED); - return 0; + // Remove trailing whitespace. + CBS modifier; + CBS_init(&modifier, (const uint8_t *)str, comma - str); + for (;;) { + uint8_t v; + CBS copy = modifier; + if (!CBS_get_last_u8(©, &v) || !OPENSSL_isspace(v)) { + break; + } + modifier = copy; } - exp_tmp = &arg->exp_list[arg->exp_count++]; + // Advance the string past the modifier, but save the original value. We + // will need to rewind if this is not a recognized modifier. + const char *str_old = str; + str = comma + 1; - /* - * If IMPLICIT set tag to implicit value then reset implicit tag since it - * has been used. - */ - if (arg->imp_tag != -1) { - exp_tmp->exp_tag = arg->imp_tag; - exp_tmp->exp_class = arg->imp_class; - arg->imp_tag = -1; - arg->imp_class = -1; + // Each modifier is either NAME:VALUE or NAME. + CBS name; + int has_value = CBS_get_until_first(&modifier, &name, ':'); + if (has_value) { + CBS_skip(&modifier, 1); // Skip the colon. } else { - exp_tmp->exp_tag = exp_tag; - exp_tmp->exp_class = exp_class; - } - exp_tmp->exp_constructed = exp_constructed; - exp_tmp->exp_pad = exp_pad; - - return 1; -} - -static int asn1_str2tag(const char *tagstr, int len) -{ - unsigned int i; - static const struct tag_name_st *tntmp, tnst[] = { - ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), - ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), - ASN1_GEN_STR("NULL", V_ASN1_NULL), - ASN1_GEN_STR("INT", V_ASN1_INTEGER), - ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), - ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), - ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), - ASN1_GEN_STR("OID", V_ASN1_OBJECT), - ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), - ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), - ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), - ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), - ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), - ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), - ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), - ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), - ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), - ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), - ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), - ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), - ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), - ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), - ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), - ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), - ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), - ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), - ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), - ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), - ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), - ASN1_GEN_STR("T61", V_ASN1_T61STRING), - ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), - ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), - ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), - ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), - ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), - ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), - - /* Special cases */ - ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), - ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), - ASN1_GEN_STR("SET", V_ASN1_SET), - /* type modifiers */ - /* Explicit tag */ - ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), - ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), - /* Implicit tag */ - ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), - ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), - /* OCTET STRING wrapper */ - ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), - /* SEQUENCE wrapper */ - ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), - /* SET wrapper */ - ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), - /* BIT STRING wrapper */ - ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), - ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), - ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), - }; - - if (len == -1) - len = strlen(tagstr); - - tntmp = tnst; - for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { - if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) - return tntmp->tag; + name = modifier; + CBS_init(&modifier, NULL, 0); } - return -1; -} + if (cbs_str_equal(&name, "FORMAT") || cbs_str_equal(&name, "FORM")) { + if (cbs_str_equal(&modifier, "ASCII")) { + format = ASN1_GEN_FORMAT_ASCII; + } else if (cbs_str_equal(&modifier, "UTF8")) { + format = ASN1_GEN_FORMAT_UTF8; + } else if (cbs_str_equal(&modifier, "HEX")) { + format = ASN1_GEN_FORMAT_HEX; + } else if (cbs_str_equal(&modifier, "BITLIST")) { + format = ASN1_GEN_FORMAT_BITLIST; + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return 0; + } + } else if (cbs_str_equal(&name, "IMP") || + cbs_str_equal(&name, "IMPLICIT")) { + if (tag != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; + } + tag = parse_tag(&modifier); + if (tag == 0) { + return 0; + } + } else if (cbs_str_equal(&name, "EXP") || + cbs_str_equal(&name, "EXPLICIT")) { + // It would actually be supportable, but OpenSSL does not allow wrapping + // an explicit tag in an implicit tag. + if (tag != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); + return 0; + } + tag = parse_tag(&modifier); + return tag != 0 && + generate_wrapped(cbb, str, cnf, tag | CBS_ASN1_CONSTRUCTED, + /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "OCTWRAP")) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "BITWRAP")) { + tag = tag == 0 ? CBS_ASN1_BITSTRING : tag; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/1, format, depth); + } else if (cbs_str_equal(&name, "SEQWRAP")) { + tag = tag == 0 ? CBS_ASN1_SEQUENCE : (tag | CBS_ASN1_CONSTRUCTED); + tag |= CBS_ASN1_CONSTRUCTED; + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else if (cbs_str_equal(&name, "SETWRAP")) { + tag = tag == 0 ? CBS_ASN1_SET : (tag | CBS_ASN1_CONSTRUCTED); + return generate_wrapped(cbb, str, cnf, tag, /*padding=*/0, format, depth); + } else { + // If this was not a recognized modifier, rewind |str| to before splitting + // on the comma. The type itself consumes all remaining input. + str = str_old; + break; + } + } -static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) -{ - ASN1_TYPE *atmp = NULL; + // The final element is, like modifiers, NAME:VALUE or NAME, but VALUE spans + // the length of the string, including any commas. + const char *colon = strchr(str, ':'); + CBS name; + const char *value; + int has_value = colon != NULL; + if (has_value) { + CBS_init(&name, (const uint8_t *)str, colon - str); + value = colon + 1; + } else { + CBS_init(&name, (const uint8_t *)str, strlen(str)); + value = ""; // Most types treat missing and empty value equivalently. + } - CONF_VALUE vtmp; + static const struct { + const char *name; + CBS_ASN1_TAG type; + } kTypes[] = { + {"BOOL", CBS_ASN1_BOOLEAN}, + {"BOOLEAN", CBS_ASN1_BOOLEAN}, + {"NULL", CBS_ASN1_NULL}, + {"INT", CBS_ASN1_INTEGER}, + {"INTEGER", CBS_ASN1_INTEGER}, + {"ENUM", CBS_ASN1_ENUMERATED}, + {"ENUMERATED", CBS_ASN1_ENUMERATED}, + {"OID", CBS_ASN1_OBJECT}, + {"OBJECT", CBS_ASN1_OBJECT}, + {"UTCTIME", CBS_ASN1_UTCTIME}, + {"UTC", CBS_ASN1_UTCTIME}, + {"GENERALIZEDTIME", CBS_ASN1_GENERALIZEDTIME}, + {"GENTIME", CBS_ASN1_GENERALIZEDTIME}, + {"OCT", CBS_ASN1_OCTETSTRING}, + {"OCTETSTRING", CBS_ASN1_OCTETSTRING}, + {"BITSTR", CBS_ASN1_BITSTRING}, + {"BITSTRING", CBS_ASN1_BITSTRING}, + {"UNIVERSALSTRING", CBS_ASN1_UNIVERSALSTRING}, + {"UNIV", CBS_ASN1_UNIVERSALSTRING}, + {"IA5", CBS_ASN1_IA5STRING}, + {"IA5STRING", CBS_ASN1_IA5STRING}, + {"UTF8", CBS_ASN1_UTF8STRING}, + {"UTF8String", CBS_ASN1_UTF8STRING}, + {"BMP", CBS_ASN1_BMPSTRING}, + {"BMPSTRING", CBS_ASN1_BMPSTRING}, + {"PRINTABLESTRING", CBS_ASN1_PRINTABLESTRING}, + {"PRINTABLE", CBS_ASN1_PRINTABLESTRING}, + {"T61", CBS_ASN1_T61STRING}, + {"T61STRING", CBS_ASN1_T61STRING}, + {"TELETEXSTRING", CBS_ASN1_T61STRING}, + {"SEQUENCE", CBS_ASN1_SEQUENCE}, + {"SEQ", CBS_ASN1_SEQUENCE}, + {"SET", CBS_ASN1_SET}, + }; + CBS_ASN1_TAG type = 0; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTypes); i++) { + if (cbs_str_equal(&name, kTypes[i].name)) { + type = kTypes[i].type; + break; + } + } + if (type == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG); + return 0; + } - unsigned char *rdata; - long rdlen; + // If there is an implicit tag, use the constructed bit from the base type. + tag = tag == 0 ? type : (tag | (type & CBS_ASN1_CONSTRUCTED)); + CBB child; + if (!CBB_add_asn1(cbb, &child, tag)) { + return 0; + } - int no_unused = 1; + switch (type) { + case CBS_ASN1_NULL: + if (*value != '\0') { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); + return 0; + } + return CBB_flush(cbb); - if (!(atmp = ASN1_TYPE_new())) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return NULL; + case CBS_ASN1_BOOLEAN: { + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT); + return 0; + } + ASN1_BOOLEAN boolean; + if (!X509V3_bool_from_string(value, &boolean)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); + return 0; + } + return CBB_add_u8(&child, boolean ? 0xff : 0x00) && CBB_flush(cbb); } - if (!str) - str = ""; + case CBS_ASN1_INTEGER: + case CBS_ASN1_ENUMERATED: { + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + return 0; + } + ASN1_INTEGER *obj = s2i_ASN1_INTEGER(NULL, value); + if (obj == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); + return 0; + } + int len = i2c_ASN1_INTEGER(obj, NULL); + uint8_t *out; + int ok = len > 0 && // + CBB_add_space(&child, &out, len) && + i2c_ASN1_INTEGER(obj, &out) == len && + CBB_flush(cbb); + ASN1_INTEGER_free(obj); + return ok; + } - switch (utype) { + case CBS_ASN1_OBJECT: { + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + return 0; + } + ASN1_OBJECT *obj = OBJ_txt2obj(value, /*dont_search_names=*/0); + if (obj == NULL || obj->length == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + return 0; + } + int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb); + ASN1_OBJECT_free(obj); + return ok; + } - case V_ASN1_NULL: - if (str && *str) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); - goto bad_form; + case CBS_ASN1_UTCTIME: + case CBS_ASN1_GENERALIZEDTIME: { + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); + return 0; + } + CBS value_cbs; + CBS_init(&value_cbs, (const uint8_t*)value, strlen(value)); + int ok = type == CBS_ASN1_UTCTIME + ? CBS_parse_utc_time(&value_cbs, NULL, + /*allow_timezone_offset=*/0) + : CBS_parse_generalized_time(&value_cbs, NULL, + /*allow_timezone_offset=*/0); + if (!ok) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); + return 0; + } + return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) && + CBB_flush(cbb); + } + + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_UTF8STRING: + case CBS_ASN1_BMPSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: { + int encoding; + if (format == ASN1_GEN_FORMAT_ASCII) { + encoding = MBSTRING_ASC; + } else if (format == ASN1_GEN_FORMAT_UTF8) { + encoding = MBSTRING_UTF8; + } else { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); + return 0; + } + + // |maxsize| is measured in code points, rather than bytes, but pass it in + // as a loose cap so fuzzers can exit from excessively long inputs + // earlier. This limit is not load-bearing because |ASN1_mbstring_ncopy|'s + // output is already linear in the input. + ASN1_STRING *obj = NULL; + if (ASN1_mbstring_ncopy(&obj, (const uint8_t *)value, -1, encoding, + ASN1_tag2bit(type), /*minsize=*/0, + /*maxsize=*/ASN1_GEN_MAX_OUTPUT) <= 0) { + return 0; + } + int ok = CBB_add_bytes(&child, obj->data, obj->length) && CBB_flush(cbb); + ASN1_STRING_free(obj); + return ok; + } + + case CBS_ASN1_BITSTRING: + if (format == ASN1_GEN_FORMAT_BITLIST) { + ASN1_BIT_STRING *obj = ASN1_BIT_STRING_new(); + if (obj == NULL) { + return 0; } - break; - - case V_ASN1_BOOLEAN: - if (format != ASN1_GEN_FORMAT_ASCII) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT); - goto bad_form; + if (!CONF_parse_list(value, ',', 1, bitstr_cb, obj)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); + ASN1_BIT_STRING_free(obj); + return 0; } - vtmp.name = NULL; - vtmp.section = NULL; - vtmp.value = (char *)str; - if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); - goto bad_str; + int len = i2c_ASN1_BIT_STRING(obj, NULL); + uint8_t *out; + int ok = len > 0 && // + CBB_add_space(&child, &out, len) && + i2c_ASN1_BIT_STRING(obj, &out) == len && // + CBB_flush(cbb); + ASN1_BIT_STRING_free(obj); + return ok; + } + + // The other formats are the same as OCTET STRING, but with the leading + // zero bytes. + if (!CBB_add_u8(&child, 0)) { + return 0; + } + OPENSSL_FALLTHROUGH; + + case CBS_ASN1_OCTETSTRING: + if (format == ASN1_GEN_FORMAT_ASCII) { + return CBB_add_bytes(&child, (const uint8_t *)value, strlen(value)) && + CBB_flush(cbb); + } + if (format == ASN1_GEN_FORMAT_HEX) { + size_t len; + uint8_t *data = x509v3_hex_to_bytes(value, &len); + if (data == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX); + return 0; } - break; + int ok = CBB_add_bytes(&child, data, len) && CBB_flush(cbb); + OPENSSL_free(data); + return ok; + } - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - if (format != ASN1_GEN_FORMAT_ASCII) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); - goto bad_form; + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + return 0; + + case CBS_ASN1_SEQUENCE: + case CBS_ASN1_SET: + if (has_value) { + if (cnf == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); + return 0; } - if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); - goto bad_str; + const STACK_OF(CONF_VALUE) *section = X509V3_get_section(cnf, value); + if (section == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); + return 0; } - break; - - case V_ASN1_OBJECT: - if (format != ASN1_GEN_FORMAT_ASCII) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); - goto bad_form; + for (size_t i = 0; i < sk_CONF_VALUE_num(section); i++) { + const CONF_VALUE *conf = sk_CONF_VALUE_value(section, i); + if (!generate_v3(&child, conf->value, cnf, /*tag=*/0, + ASN1_GEN_FORMAT_ASCII, depth + 1)) { + return 0; + } + // This recursive call, by referencing |section|, is the one place + // where |generate_v3|'s output can be super-linear in the input. + // Check bounds here. + if (CBB_len(&child) > ASN1_GEN_MAX_OUTPUT) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + return 0; + } } - if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - goto bad_str; - } - break; - - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: - if (format != ASN1_GEN_FORMAT_ASCII) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); - goto bad_form; - } - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - atmp->value.asn1_string->type = utype; - if (!ASN1_TIME_check(atmp->value.asn1_string)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE); - goto bad_str; - } - - break; - - case V_ASN1_BMPSTRING: - case V_ASN1_PRINTABLESTRING: - case V_ASN1_IA5STRING: - case V_ASN1_T61STRING: - case V_ASN1_UTF8STRING: - case V_ASN1_VISIBLESTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_GENERALSTRING: - case V_ASN1_NUMERICSTRING: - - if (format == ASN1_GEN_FORMAT_ASCII) - format = MBSTRING_ASC; - else if (format == ASN1_GEN_FORMAT_UTF8) - format = MBSTRING_UTF8; - else { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); - goto bad_form; - } - - if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, - -1, format, ASN1_tag2bit(utype)) <= 0) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - - break; - - case V_ASN1_BIT_STRING: - - case V_ASN1_OCTET_STRING: - - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - goto bad_form; - } - - if (format == ASN1_GEN_FORMAT_HEX) { - - if (!(rdata = x509v3_hex_to_bytes((char *)str, &rdlen))) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX); - goto bad_str; - } - - atmp->value.asn1_string->data = rdata; - atmp->value.asn1_string->length = rdlen; - atmp->value.asn1_string->type = utype; - - } else if (format == ASN1_GEN_FORMAT_ASCII) - ASN1_STRING_set(atmp->value.asn1_string, str, -1); - else if ((format == ASN1_GEN_FORMAT_BITLIST) - && (utype == V_ASN1_BIT_STRING)) { - if (!CONF_parse_list - (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); - goto bad_str; - } - no_unused = 0; - - } else { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); - goto bad_form; - } - - if ((utype == V_ASN1_BIT_STRING) && no_unused) { - atmp->value.asn1_string->flags - &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; - } - - break; + } + if (type == CBS_ASN1_SET) { + // The SET type here is a SET OF and must be sorted. + return CBB_flush_asn1_set_of(&child) && CBB_flush(cbb); + } + return CBB_flush(cbb); default: - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE); - goto bad_str; - break; - } - - atmp->type = utype; - return atmp; - - bad_str: - ERR_add_error_data(2, "string=", str); - bad_form: - - ASN1_TYPE_free(atmp); - return NULL; - + OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR); + return 0; + } } -static int bitstr_cb(const char *elem, int len, void *bitstr) -{ - long bitnum; - char *eptr; - if (!elem) - return 0; - bitnum = strtoul(elem, &eptr, 10); - if (eptr && *eptr && (eptr != elem + len)) - return 0; - if (bitnum < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); - return 0; - } - if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { - OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; +static int bitstr_cb(const char *elem, size_t len, void *bitstr) { + CBS cbs; + CBS_init(&cbs, (const uint8_t *)elem, len); + uint64_t bitnum; + if (!CBS_get_u64_decimal(&cbs, &bitnum) || CBS_len(&cbs) != 0 || + // Cap the highest allowed bit so this mechanism cannot be used to create + // extremely large allocations with short inputs. The highest named bit in + // RFC 5280 is 8, so 256 should give comfortable margin but still only + // allow a 32-byte allocation. + // + // We do not consider this function to be safe with untrusted inputs (even + // without bugs, it is prone to string injection vulnerabilities), so DoS + // is not truly a concern, but the limit is necessary to keep fuzzing + // effective. + bitnum > 256) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, (int)bitnum, 1)) { + return 0; + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509/by_dir.c b/third_party/boringssl/kit/src/crypto/x509/by_dir.c index a630cdf0..ff9a9bdd 100644 --- a/third_party/boringssl/kit/src/crypto/x509/by_dir.c +++ b/third_party/boringssl/kit/src/crypto/x509/by_dir.c @@ -1,4 +1,3 @@ -/* crypto/x509/by_dir.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,19 +70,19 @@ #include "internal.h" typedef struct lookup_dir_hashes_st { - unsigned long hash; - int suffix; + unsigned long hash; + int suffix; } BY_DIR_HASH; typedef struct lookup_dir_entry_st { - char *dir; - int dir_type; - STACK_OF(BY_DIR_HASH) *hashes; + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; } BY_DIR_ENTRY; typedef struct lookup_dir_st { - BUF_MEM *buffer; - STACK_OF(BY_DIR_ENTRY) *dirs; + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; } BY_DIR; DEFINE_STACK_OF(BY_DIR_HASH) @@ -98,362 +97,317 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, X509_OBJECT *ret); static X509_LOOKUP_METHOD x509_dir_lookup = { "Load certs from files in a directory", - new_dir, /* new */ - free_dir, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - dir_ctrl, /* ctrl */ - get_cert_by_subject, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ + new_dir, // new + free_dir, // free + NULL, // init + NULL, // shutdown + dir_ctrl, // ctrl + get_cert_by_subject, // get_by_subject }; -X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) -{ - return (&x509_dir_lookup); -} +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) { return &x509_dir_lookup; } static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **retp) -{ - int ret = 0; - BY_DIR *ld; - char *dir = NULL; + char **retp) { + int ret = 0; + char *dir = NULL; - ld = (BY_DIR *)ctx->method_data; + BY_DIR *ld = ctx->method_data; - switch (cmd) { + switch (cmd) { case X509_L_ADD_DIR: - if (argl == X509_FILETYPE_DEFAULT) { - dir = (char *)getenv(X509_get_default_cert_dir_env()); - if (dir) - ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); - else - ret = add_cert_dir(ld, X509_get_default_cert_dir(), - X509_FILETYPE_PEM); - if (!ret) { - OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR); - } - } else - ret = add_cert_dir(ld, argp, (int)argl); - break; - } - return (ret); -} - -static int new_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) - return (0); - if ((a->buffer = BUF_MEM_new()) == NULL) { - OPENSSL_free(a); - return (0); - } - a->dirs = NULL; - lu->method_data = (char *)a; - return (1); -} - -static void by_dir_hash_free(BY_DIR_HASH *hash) -{ - OPENSSL_free(hash); -} - -static int by_dir_hash_cmp(const BY_DIR_HASH **a, const BY_DIR_HASH **b) -{ - if ((*a)->hash > (*b)->hash) - return 1; - if ((*a)->hash < (*b)->hash) - return -1; - return 0; -} - -static void by_dir_entry_free(BY_DIR_ENTRY *ent) -{ - if (ent->dir) - OPENSSL_free(ent->dir); - if (ent->hashes) - sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); - OPENSSL_free(ent); -} - -static void free_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - a = (BY_DIR *)lu->method_data; - if (a->dirs != NULL) - sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); - if (a->buffer != NULL) - BUF_MEM_free(a->buffer); - OPENSSL_free(a); -} - -static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) -{ - size_t j, len; - const char *s, *ss, *p; - - if (dir == NULL || !*dir) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY); - return 0; - } - - s = dir; - p = s; - do { - if ((*p == ':') || (*p == '\0')) { - BY_DIR_ENTRY *ent; - ss = s; - s = p + 1; - len = p - ss; - if (len == 0) - continue; - for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { - ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); - if (strlen(ent->dir) == len && - strncmp(ent->dir, ss, len) == 0) - break; - } - if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) - continue; - if (ctx->dirs == NULL) { - ctx->dirs = sk_BY_DIR_ENTRY_new_null(); - if (!ctx->dirs) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; - } - } - ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); - if (!ent) - return 0; - ent->dir_type = type; - ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); - ent->dir = OPENSSL_malloc(len + 1); - if (!ent->dir || !ent->hashes) { - by_dir_entry_free(ent); - return 0; - } - OPENSSL_strlcpy(ent->dir, ss, len + 1); - if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { - by_dir_entry_free(ent); - return 0; - } + if (argl == X509_FILETYPE_DEFAULT) { + dir = (char *)getenv(X509_get_default_cert_dir_env()); + if (dir) { + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); + } else { + ret = + add_cert_dir(ld, X509_get_default_cert_dir(), X509_FILETYPE_PEM); } - } while (*p++ != '\0'); - return 1; + if (!ret) { + OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR); + } + } else { + ret = add_cert_dir(ld, argp, (int)argl); + } + break; + } + return ret; } -/* - * g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| - * objects. - */ -static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = - CRYPTO_STATIC_MUTEX_INIT; +static int new_dir(X509_LOOKUP *lu) { + BY_DIR *a; + + if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) { + return 0; + } + if ((a->buffer = BUF_MEM_new()) == NULL) { + OPENSSL_free(a); + return 0; + } + a->dirs = NULL; + lu->method_data = a; + return 1; +} + +static void by_dir_hash_free(BY_DIR_HASH *hash) { OPENSSL_free(hash); } + +static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, + const BY_DIR_HASH *const *b) { + if ((*a)->hash > (*b)->hash) { + return 1; + } + if ((*a)->hash < (*b)->hash) { + return -1; + } + return 0; +} + +static void by_dir_entry_free(BY_DIR_ENTRY *ent) { + if (ent != NULL) { + OPENSSL_free(ent->dir); + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + OPENSSL_free(ent); + } +} + +static void free_dir(X509_LOOKUP *lu) { + BY_DIR *a = lu->method_data; + if (a != NULL) { + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + BUF_MEM_free(a->buffer); + OPENSSL_free(a); + } +} + +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) { + size_t j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = p - ss; + if (len == 0) { + continue; + } + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == len && strncmp(ent->dir, ss, len) == 0) { + break; + } + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) { + continue; + } + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { + return 0; + } + } + ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) { + return 0; + } + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = OPENSSL_malloc(len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + OPENSSL_strlcpy(ent->dir, ss, len + 1); + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +// g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| +// objects. +static CRYPTO_MUTEX g_ent_hashes_lock = CRYPTO_MUTEX_INIT; static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - BY_DIR *ctx; - union { - struct { - X509 st_x509; - X509_CINF st_x509_cinf; - } x509; - struct { - X509_CRL st_crl; - X509_CRL_INFO st_crl_info; - } crl; - } data; - int ok = 0; - size_t i; - int j, k; - unsigned long h; - unsigned long hash_array[2]; - int hash_index; - BUF_MEM *b = NULL; - X509_OBJECT stmp, *tmp; - const char *postfix = ""; + X509_OBJECT *ret) { + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + size_t i; + int j, k; + unsigned long h; + unsigned long hash_array[2]; + int hash_index; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix = ""; - if (name == NULL) - return (0); + if (name == NULL) { + return 0; + } - stmp.type = type; - if (type == X509_LU_X509) { - data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; - data.x509.st_x509_cinf.subject = name; - stmp.data.x509 = &data.x509.st_x509; - postfix = ""; - } else if (type == X509_LU_CRL) { - data.crl.st_crl.crl = &data.crl.st_crl_info; - data.crl.st_crl_info.issuer = name; - stmp.data.crl = &data.crl.st_crl; - postfix = "r"; - } else { - OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE); + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix = ""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix = "r"; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + goto finish; + } + + BY_DIR *ctx = xl->method_data; + + hash_array[0] = X509_NAME_hash(name); + hash_array[1] = X509_NAME_hash_old(name); + for (hash_index = 0; hash_index < 2; ++hash_index) { + h = hash_array[hash_index]; + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + size_t idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { goto finish; - } - - if ((b = BUF_MEM_new()) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); - goto finish; - } - - ctx = (BY_DIR *)xl->method_data; - - hash_array[0] = X509_NAME_hash(name); - hash_array[1] = X509_NAME_hash_old(name); - for (hash_index = 0; hash_index < 2; ++hash_index) { - h = hash_array[hash_index]; - for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { - BY_DIR_ENTRY *ent; - size_t idx; - BY_DIR_HASH htmp, *hent; - ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); - j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; - if (!BUF_MEM_grow(b, j)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto finish; - } - if (type == X509_LU_CRL && ent->hashes) { - htmp.hash = h; - CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock); - if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - k = hent->suffix; - } else { - hent = NULL; - k = 0; - } - CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock); - } else { - k = 0; - hent = NULL; - } - for (;;) { - char c = '/'; -#ifdef OPENSSL_SYS_VMS - c = ent->dir[strlen(ent->dir) - 1]; - if (c != ':' && c != '>' && c != ']') { - /* - * If no separator is present, we assume the directory - * specifier is a logical name, and add a colon. We - * really should use better VMS routines for merging - * things like this, but this will do for now... -- - * Richard Levitte - */ - c = ':'; - } else { - c = '\0'; - } -#endif - if (c == '\0') { - /* - * This is special. When c == '\0', no directory - * separator should be added. - */ - BIO_snprintf(b->data, b->max, - "%s%08lx.%s%d", ent->dir, h, postfix, k); - } else { - BIO_snprintf(b->data, b->max, - "%s%c%08lx.%s%d", ent->dir, c, h, - postfix, k); - } -#ifndef OPENSSL_NO_POSIX_IO -# if defined(_WIN32) && !defined(stat) -# define stat _stat -# endif - { - struct stat st; - if (stat(b->data, &st) < 0) - break; - } -#endif - /* found one. */ - if (type == X509_LU_X509) { - if ((X509_load_cert_file(xl, b->data, - ent->dir_type)) == 0) - break; - } else if (type == X509_LU_CRL) { - if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) - break; - } - /* else case will caught higher up */ - k++; - } - - /* - * we have added it to the cache so now pull it out again - */ - CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock); - tmp = NULL; - sk_X509_OBJECT_sort(xl->store_ctx->objs); - if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { - tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx); - } - CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock); - - /* - * If a CRL, update the last file suffix added for this - */ - - if (type == X509_LU_CRL) { - CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock); - /* - * Look for entry again in case another thread added an entry - * first. - */ - if (!hent) { - htmp.hash = h; - sk_BY_DIR_HASH_sort(ent->hashes); - if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - } - if (!hent) { - hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); - if (hent == NULL) { - CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); - ok = 0; - goto finish; - } - hent->hash = h; - hent->suffix = k; - if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { - CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); - OPENSSL_free(hent); - ok = 0; - goto finish; - } - sk_BY_DIR_HASH_sort(ent->hashes); - } else if (hent->suffix < k) - hent->suffix = k; - - CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); - } - - if (tmp != NULL) { - ok = 1; - ret->type = tmp->type; - OPENSSL_memcpy(&ret->data, &tmp->data, sizeof(ret->data)); - /* - * If we were going to up the reference count, we would need - * to do it on a perl 'type' basis - */ - /* - * CRYPTO_add(&tmp->data.x509->references,1, - * CRYPTO_LOCK_X509); - */ - goto finish; - } + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_MUTEX_lock_read(&g_ent_hashes_lock); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; } + CRYPTO_MUTEX_unlock_read(&g_ent_hashes_lock); + } else { + k = 0; + hent = NULL; + } + for (;;) { + BIO_snprintf(b->data, b->max, "%s/%08lx.%s%d", ent->dir, h, postfix, + k); +#ifndef OPENSSL_NO_POSIX_IO +#if defined(_WIN32) && !defined(stat) +#define stat _stat +#endif + { + struct stat st; + if (stat(b->data, &st) < 0) { + break; + } + } +#endif + // found one. + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) { + break; + } + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) { + break; + } + } + // else case will caught higher up + k++; + } + + // we have added it to the cache so now pull it out again + CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock); + tmp = NULL; + sk_X509_OBJECT_sort(xl->store_ctx->objs); + if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx); + } + CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock); + + // If a CRL, update the last file suffix added for this + + if (type == X509_LU_CRL) { + CRYPTO_MUTEX_lock_write(&g_ent_hashes_lock); + // Look for entry again in case another thread added an entry + // first. + if (!hent) { + htmp.hash = h; + sk_BY_DIR_HASH_sort(ent->hashes); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + sk_BY_DIR_HASH_sort(ent->hashes); + } else if (hent->suffix < k) { + hent->suffix = k; + } + + CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + OPENSSL_memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + + // Clear any errors that might have been raised processing empty + // or malformed files. + ERR_clear_error(); + + // If we were going to up the reference count, we would need + // to do it on a perl 'type' basis + goto finish; + } } - finish: - if (b != NULL) - BUF_MEM_free(b); - return (ok); + } +finish: + BUF_MEM_free(b); + return ok; } #endif // OPENSSL_TRUSTY diff --git a/third_party/boringssl/kit/src/crypto/x509/by_file.c b/third_party/boringssl/kit/src/crypto/x509/by_file.c index 1614c8c6..7c056f08 100644 --- a/third_party/boringssl/kit/src/crypto/x509/by_file.c +++ b/third_party/boringssl/kit/src/crypto/x509/by_file.c @@ -1,4 +1,3 @@ -/* crypto/x509/by_file.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -65,213 +64,219 @@ #ifndef OPENSSL_NO_STDIO -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret); +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); static X509_LOOKUP_METHOD x509_file_lookup = { "Load file into cache", - NULL, /* new */ - NULL, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - by_file_ctrl, /* ctrl */ - NULL, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ + NULL, // new + NULL, // free + NULL, // init + NULL, // shutdown + by_file_ctrl, // ctrl + NULL, // get_by_subject }; -X509_LOOKUP_METHOD *X509_LOOKUP_file(void) -{ - return (&x509_file_lookup); -} +X509_LOOKUP_METHOD *X509_LOOKUP_file(void) { return &x509_file_lookup; } -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, - long argl, char **ret) -{ - int ok = 0; - const char *file; +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret) { + int ok = 0; + const char *file; - switch (cmd) { + switch (cmd) { case X509_L_FILE_LOAD: - if (argl == X509_FILETYPE_DEFAULT) { - file = getenv(X509_get_default_cert_file_env()); - if (file) - ok = (X509_load_cert_crl_file(ctx, file, - X509_FILETYPE_PEM) != 0); + if (argl == X509_FILETYPE_DEFAULT) { + file = getenv(X509_get_default_cert_file_env()); + if (file) { + ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); + } - else - ok = (X509_load_cert_crl_file - (ctx, X509_get_default_cert_file(), - X509_FILETYPE_PEM) != 0); + else { + ok = (X509_load_cert_crl_file(ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + } - if (!ok) { - OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS); - } + if (!ok) { + OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) { + ok = (X509_load_cert_crl_file(ctx, argp, X509_FILETYPE_PEM) != 0); } else { - if (argl == X509_FILETYPE_PEM) - ok = (X509_load_cert_crl_file(ctx, argp, - X509_FILETYPE_PEM) != 0); - else - ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); } - break; - } - return (ok); + } + break; + } + return ok; } -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509 *x = NULL; +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) { + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; - if (file == NULL) - return (1); - in = BIO_new(BIO_s_file()); + in = BIO_new(BIO_s_file()); - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); - goto err; - } + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } - if (type == X509_FILETYPE_PEM) { - for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); - if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && - count > 0) { - ERR_clear_error(); - break; - } - OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); - goto err; - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_free(x); - x = NULL; + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + if (x == NULL) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + ERR_clear_error(); + break; } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_bio(in, NULL); - if (x == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); - goto err; - } - err: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} - -int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509_CRL *x = NULL; - - if (file == NULL) - return (1); - in = BIO_new(BIO_s_file()); - - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); - goto err; - } - - if (type == X509_FILETYPE_PEM) { - for (;;) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && - count > 0) { - ERR_clear_error(); - break; - } - OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); - goto err; - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_CRL_free(x); - x = NULL; - } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - if (x == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); - goto err; - } - err: - if (x != NULL) - X509_CRL_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} - -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - STACK_OF(X509_INFO) *inf; - X509_INFO *itmp; - BIO *in; - size_t i; - int count = 0; - if (type != X509_FILETYPE_PEM) - return X509_load_cert_file(ctx, file, type); - in = BIO_new_file(file, "r"); - if (!in) { - OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); - return 0; - } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); - BIO_free(in); - if (!inf) { OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); - return 0; + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) { + goto err; + } + count++; + X509_free(x); + x = NULL; } - for (i = 0; i < sk_X509_INFO_num(inf); i++) { - itmp = sk_X509_INFO_value(inf, i); - if (itmp->x509) { - X509_STORE_add_cert(ctx->store_ctx, itmp->x509); - count++; - } - if (itmp->crl) { - X509_STORE_add_crl(ctx->store_ctx, itmp->crl); - count++; - } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; } - sk_X509_INFO_pop_free(inf, X509_INFO_free); - return count; + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) { + goto err; + } + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); + goto err; + } + + if (ret == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATE_FOUND); + } + +err: + X509_free(x); + BIO_free(in); + return ret; } -#endif /* OPENSSL_NO_STDIO */ +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + in = BIO_new(BIO_s_file()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + if (x == NULL) { + uint32_t error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_PEM && + ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + ERR_clear_error(); + break; + } + OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) { + goto err; + } + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) { + goto err; + } + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE); + goto err; + } + + if (ret == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_FOUND); + } + +err: + X509_CRL_free(x); + BIO_free(in); + return ret; +} + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) { + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + size_t i; + int count = 0; + + if (type != X509_FILETYPE_PEM) { + return X509_load_cert_file(ctx, file, type); + } + in = BIO_new_file(file, "r"); + if (!in) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) { + goto err; + } + count++; + } + if (itmp->crl) { + if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) { + goto err; + } + count++; + } + } + + if (count == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND); + } + +err: + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + +#endif // OPENSSL_NO_STDIO diff --git a/third_party/boringssl/kit/src/crypto/x509/i2d_pr.c b/third_party/boringssl/kit/src/crypto/x509/i2d_pr.c index c3fb8a8a..e5865a42 100644 --- a/third_party/boringssl/kit/src/crypto/x509/i2d_pr.c +++ b/third_party/boringssl/kit/src/crypto/x509/i2d_pr.c @@ -1,4 +1,3 @@ -/* crypto/asn1/i2d_pr.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,28 +55,25 @@ * [including the GNU Public Licence.] */ #include +#include #include #include #include #include -#include -int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) -{ - switch (EVP_PKEY_id(a)) { +int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) { + switch (EVP_PKEY_id(a)) { case EVP_PKEY_RSA: - return i2d_RSAPrivateKey(a->pkey.rsa, pp); + return i2d_RSAPrivateKey(EVP_PKEY_get0_RSA(a), pp); case EVP_PKEY_EC: - return i2d_ECPrivateKey(a->pkey.ec, pp); + return i2d_ECPrivateKey(EVP_PKEY_get0_EC_KEY(a), pp); case EVP_PKEY_DSA: - return i2d_DSAPrivateKey(a->pkey.dsa, pp); + return i2d_DSAPrivateKey(EVP_PKEY_get0_DSA(a), pp); default: - /* - * Although this file is in crypto/x509 for layering reasons, it emits - * an error code from ASN1 for OpenSSL compatibility. - */ - OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return -1; - } + // Although this file is in crypto/x509 for layering reasons, it emits + // an error code from ASN1 for OpenSSL compatibility. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } } diff --git a/third_party/boringssl/kit/src/crypto/x509/internal.h b/third_party/boringssl/kit/src/crypto/x509/internal.h index 45920872..47b285ae 100644 --- a/third_party/boringssl/kit/src/crypto/x509/internal.h +++ b/third_party/boringssl/kit/src/crypto/x509/internal.h @@ -64,20 +64,21 @@ #include #include "../asn1/internal.h" +#include "../internal.h" #if defined(__cplusplus) extern "C" { #endif -/* Internal structures. */ +// Internal structures. typedef struct X509_val_st { ASN1_TIME *notBefore; ASN1_TIME *notAfter; } X509_VAL; -DECLARE_ASN1_FUNCTIONS(X509_VAL) +DECLARE_ASN1_FUNCTIONS_const(X509_VAL) struct X509_pubkey_st { X509_ALGOR *algor; @@ -106,13 +107,14 @@ struct x509_attributes_st { STACK_OF(ASN1_TYPE) *set; } /* X509_ATTRIBUTE */; -struct x509_cert_aux_st { +typedef struct x509_cert_aux_st { STACK_OF(ASN1_OBJECT) *trust; // trusted uses STACK_OF(ASN1_OBJECT) *reject; // rejected uses ASN1_UTF8STRING *alias; // "friendly name" ASN1_OCTET_STRING *keyid; // key id of private key - STACK_OF(X509_ALGOR) *other; // other unspecified info -} /* X509_CERT_AUX */; +} X509_CERT_AUX; + +DECLARE_ASN1_FUNCTIONS_const(X509_CERT_AUX) struct X509_extension_st { ASN1_OBJECT *object; @@ -134,6 +136,8 @@ typedef struct { ASN1_ENCODING enc; } X509_CINF; +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(X509_CINF) struct x509_st { @@ -144,20 +148,17 @@ struct x509_st { CRYPTO_EX_DATA ex_data; // These contain copies of various extension values long ex_pathlen; - long ex_pcpathlen; - unsigned long ex_flags; - unsigned long ex_kusage; - unsigned long ex_xkusage; - unsigned long ex_nscert; + uint32_t ex_flags; + uint32_t ex_kusage; + uint32_t ex_xkusage; + uint32_t ex_nscert; ASN1_OCTET_STRING *skid; AUTHORITY_KEYID *akid; - X509_POLICY_CACHE *policy_cache; STACK_OF(DIST_POINT) *crldp; STACK_OF(GENERAL_NAME) *altname; NAME_CONSTRAINTS *nc; - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + unsigned char cert_hash[SHA256_DIGEST_LENGTH]; X509_CERT_AUX *aux; - CRYPTO_BUFFER *buf; CRYPTO_MUTEX lock; } /* X509 */; @@ -170,15 +171,26 @@ typedef struct { STACK_OF(X509_ATTRIBUTE) *attributes; // [ 0 ] } X509_REQ_INFO; +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) struct X509_req_st { X509_REQ_INFO *req_info; X509_ALGOR *sig_alg; ASN1_BIT_STRING *signature; - CRYPTO_refcount_t references; } /* X509_REQ */; +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + // Set up if indirect CRL + STACK_OF(GENERAL_NAME) *issuer; + // Revocation reason + int reason; +} /* X509_REVOKED */; + typedef struct { ASN1_INTEGER *version; X509_ALGOR *sig_alg; @@ -190,6 +202,8 @@ typedef struct { ASN1_ENCODING enc; } X509_CRL_INFO; +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) struct X509_crl_st { @@ -208,15 +222,13 @@ struct X509_crl_st { // CRL and base CRL numbers for delta processing ASN1_INTEGER *crl_number; ASN1_INTEGER *base_crl_number; - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + unsigned char crl_hash[SHA256_DIGEST_LENGTH]; STACK_OF(GENERAL_NAMES) *issuers; - const X509_CRL_METHOD *meth; - void *meth_data; } /* X509_CRL */; struct X509_VERIFY_PARAM_st { char *name; - time_t check_time; // Time to use + int64_t check_time; // POSIX time to use unsigned long inh_flags; // Inheritance flags unsigned long flags; // Various verify flags int purpose; // purpose to check untrusted certificates @@ -256,12 +268,6 @@ struct x509_lookup_method_st { char **ret); int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret); - int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret); - int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type, unsigned char *bytes, - int len, X509_OBJECT *ret); - int (*get_by_alias)(X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret); } /* X509_LOOKUP_METHOD */; // This is used to hold everything. It is used for all certificate @@ -301,7 +307,7 @@ struct x509_lookup_st { int init; // have we been started int skip; // don't use us. X509_LOOKUP_METHOD *method; // the functions - char *method_data; // method data + void *method_data; // method data X509_STORE *store_ctx; // who owns us } /* X509_LOOKUP */; @@ -339,9 +345,6 @@ struct x509_store_ctx_st { int valid; // if 0, rebuild chain int last_untrusted; // index of last untrusted cert STACK_OF(X509) *chain; // chain of X509s - built up and trusted - X509_POLICY_TREE *tree; // Valid policy tree - - int explicit_policy; // Require explicit policy value // When something goes wrong, this is why int error_depth; @@ -358,47 +361,63 @@ struct x509_store_ctx_st { CRYPTO_EX_DATA ex_data; } /* X509_STORE_CTX */; -ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +ASN1_TYPE *ASN1_generate_v3(const char *str, const X509V3_CTX *cnf); + +int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); -/* RSA-PSS functions. */ +// RSA-PSS functions. -/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on - * signature algorithm parameters in |sigalg| (which must have type - * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on - * error. */ +// x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on +// signature algorithm parameters in |sigalg| (which must have type +// |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on +// error. int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); -/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for - * |ctx|, which must have been configured for an RSA-PSS signing operation. It - * returns one on success and zero on error. */ +// x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for +// |ctx|, which must have been configured for an RSA-PSS signing operation. It +// returns one on success and zero on error. int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor); -/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS - * parameters in |sigalg| to |bp|. It returns one on success and zero on - * error. */ +// x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS +// parameters in |sigalg| to |bp|. It returns one on success and zero on +// error. int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, ASN1_PCTX *pctx); -/* Signature algorithm functions. */ +// Signature algorithm functions. -/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an - * AlgorithmIdentifer and saves the result in |algor|. It returns one on - * success, or zero on error. */ +// x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an +// AlgorithmIdentifer and saves the result in |algor|. It returns one on +// success, or zero on error. int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); -/* x509_digest_verify_init sets up |ctx| for a signature verification operation - * with public key |pkey| and parameters from |algor|. The |ctx| argument must - * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or - * zero on error. */ +// x509_digest_verify_init sets up |ctx| for a signature verification operation +// with public key |pkey| and parameters from |algor|. The |ctx| argument must +// have been initialised with |EVP_MD_CTX_init|. It returns one on success, or +// zero on error. int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); +// Path-building functions. + +// X509_policy_check checks certificate policies in |certs|. |user_policies| is +// the user-initial-policy-set. If |user_policies| is NULL or empty, it is +// interpreted as anyPolicy. |flags| is a set of |X509_V_FLAG_*| values to +// apply. It returns |X509_V_OK| on success and |X509_V_ERR_*| on error. It +// additionally sets |*out_current_cert| to the certificate where the error +// occurred. If the function succeeded, or the error applies to the entire +// chain, it sets |*out_current_cert| to NULL. +int X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, + unsigned long flags, X509 **out_current_cert); + + #if defined(__cplusplus) -} /* extern C */ +} // extern C #endif -#endif /* OPENSSL_HEADER_X509_INTERNAL_H */ +#endif // OPENSSL_HEADER_X509_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/x509/name_print.c b/third_party/boringssl/kit/src/crypto/x509/name_print.c index b5523c0f..5dc34dae 100644 --- a/third_party/boringssl/kit/src/crypto/x509/name_print.c +++ b/third_party/boringssl/kit/src/crypto/x509/name_print.c @@ -56,6 +56,7 @@ #include +#include #include #include @@ -64,183 +65,163 @@ #include -static int maybe_write(BIO *out, const void *buf, int len) -{ - /* If |out| is NULL, ignore the output but report the length. */ - return out == NULL || BIO_write(out, buf, len) == len; +static int maybe_write(BIO *out, const void *buf, int len) { + // If |out| is NULL, ignore the output but report the length. + return out == NULL || BIO_write(out, buf, len) == len; } -/* do_indent prints |indent| spaces to |out|. */ -static int do_indent(BIO *out, int indent) -{ - for (int i = 0; i < indent; i++) { - if (!maybe_write(out, " ", 1)) { - return 0; - } +// do_indent prints |indent| spaces to |out|. +static int do_indent(BIO *out, int indent) { + for (int i = 0; i < indent; i++) { + if (!maybe_write(out, " ", 1)) { + return 0; } - return 1; + } + return 1; } -#define FN_WIDTH_LN 25 -#define FN_WIDTH_SN 10 +#define FN_WIDTH_LN 25 +#define FN_WIDTH_SN 10 static int do_name_ex(BIO *out, const X509_NAME *n, int indent, - unsigned long flags) -{ - int i, prev = -1, orflags, cnt; - int fn_opt, fn_nid; - ASN1_OBJECT *fn; - ASN1_STRING *val; - X509_NAME_ENTRY *ent; - char objtmp[80]; - const char *objbuf; - int outlen, len; - const char *sep_dn, *sep_mv, *sep_eq; - int sep_dn_len, sep_mv_len, sep_eq_len; - if (indent < 0) - indent = 0; - outlen = indent; - if (!do_indent(out, indent)) - return -1; - switch (flags & XN_FLAG_SEP_MASK) { + unsigned long flags) { + int prev = -1, orflags; + char objtmp[80]; + const char *objbuf; + int outlen, len; + const char *sep_dn, *sep_mv, *sep_eq; + int sep_dn_len, sep_mv_len, sep_eq_len; + if (indent < 0) { + indent = 0; + } + outlen = indent; + if (!do_indent(out, indent)) { + return -1; + } + switch (flags & XN_FLAG_SEP_MASK) { case XN_FLAG_SEP_MULTILINE: - sep_dn = "\n"; - sep_dn_len = 1; - sep_mv = " + "; - sep_mv_len = 3; - break; + sep_dn = "\n"; + sep_dn_len = 1; + sep_mv = " + "; + sep_mv_len = 3; + break; case XN_FLAG_SEP_COMMA_PLUS: - sep_dn = ","; - sep_dn_len = 1; - sep_mv = "+"; - sep_mv_len = 1; - indent = 0; - break; + sep_dn = ","; + sep_dn_len = 1; + sep_mv = "+"; + sep_mv_len = 1; + indent = 0; + break; case XN_FLAG_SEP_CPLUS_SPC: - sep_dn = ", "; - sep_dn_len = 2; - sep_mv = " + "; - sep_mv_len = 3; - indent = 0; - break; + sep_dn = ", "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; case XN_FLAG_SEP_SPLUS_SPC: - sep_dn = "; "; - sep_dn_len = 2; - sep_mv = " + "; - sep_mv_len = 3; - indent = 0; - break; + sep_dn = "; "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; default: - return -1; - } + return -1; + } - if (flags & XN_FLAG_SPC_EQ) { - sep_eq = " = "; - sep_eq_len = 3; + if (flags & XN_FLAG_SPC_EQ) { + sep_eq = " = "; + sep_eq_len = 3; + } else { + sep_eq = "="; + sep_eq_len = 1; + } + + int cnt = X509_NAME_entry_count(n); + for (int i = 0; i < cnt; i++) { + const X509_NAME_ENTRY *ent; + if (flags & XN_FLAG_DN_REV) { + ent = X509_NAME_get_entry(n, cnt - i - 1); } else { - sep_eq = "="; - sep_eq_len = 1; + ent = X509_NAME_get_entry(n, i); + } + if (prev != -1) { + if (prev == X509_NAME_ENTRY_set(ent)) { + if (!maybe_write(out, sep_mv, sep_mv_len)) { + return -1; + } + outlen += sep_mv_len; + } else { + if (!maybe_write(out, sep_dn, sep_dn_len)) { + return -1; + } + outlen += sep_dn_len; + if (!do_indent(out, indent)) { + return -1; + } + outlen += indent; + } + } + prev = X509_NAME_ENTRY_set(ent); + const ASN1_OBJECT *fn = X509_NAME_ENTRY_get_object(ent); + const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent); + assert((flags & XN_FLAG_FN_MASK) == XN_FLAG_FN_SN); + int fn_nid = OBJ_obj2nid(fn); + if (fn_nid == NID_undef) { + OBJ_obj2txt(objtmp, sizeof(objtmp), fn, 1); + objbuf = objtmp; + } else { + objbuf = OBJ_nid2sn(fn_nid); + } + int objlen = strlen(objbuf); + if (!maybe_write(out, objbuf, objlen) || + !maybe_write(out, sep_eq, sep_eq_len)) { + return -1; + } + outlen += objlen + sep_eq_len; + // If the field name is unknown then fix up the DER dump flag. We + // might want to limit this further so it will DER dump on anything + // other than a few 'standard' fields. + if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) { + orflags = ASN1_STRFLGS_DUMP_ALL; + } else { + orflags = 0; } - fn_opt = flags & XN_FLAG_FN_MASK; - - cnt = X509_NAME_entry_count(n); - for (i = 0; i < cnt; i++) { - if (flags & XN_FLAG_DN_REV) - ent = X509_NAME_get_entry(n, cnt - i - 1); - else - ent = X509_NAME_get_entry(n, i); - if (prev != -1) { - if (prev == X509_NAME_ENTRY_set(ent)) { - if (!maybe_write(out, sep_mv, sep_mv_len)) - return -1; - outlen += sep_mv_len; - } else { - if (!maybe_write(out, sep_dn, sep_dn_len)) - return -1; - outlen += sep_dn_len; - if (!do_indent(out, indent)) - return -1; - outlen += indent; - } - } - prev = X509_NAME_ENTRY_set(ent); - fn = X509_NAME_ENTRY_get_object(ent); - val = X509_NAME_ENTRY_get_data(ent); - fn_nid = OBJ_obj2nid(fn); - if (fn_opt != XN_FLAG_FN_NONE) { - int objlen, fld_len; - if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) { - OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1); - fld_len = 0; /* XXX: what should this be? */ - objbuf = objtmp; - } else { - if (fn_opt == XN_FLAG_FN_SN) { - fld_len = FN_WIDTH_SN; - objbuf = OBJ_nid2sn(fn_nid); - } else if (fn_opt == XN_FLAG_FN_LN) { - fld_len = FN_WIDTH_LN; - objbuf = OBJ_nid2ln(fn_nid); - } else { - fld_len = 0; /* XXX: what should this be? */ - objbuf = ""; - } - } - objlen = strlen(objbuf); - if (!maybe_write(out, objbuf, objlen)) - return -1; - if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { - if (!do_indent(out, fld_len - objlen)) - return -1; - outlen += fld_len - objlen; - } - if (!maybe_write(out, sep_eq, sep_eq_len)) - return -1; - outlen += objlen + sep_eq_len; - } - /* - * If the field name is unknown then fix up the DER dump flag. We - * might want to limit this further so it will DER dump on anything - * other than a few 'standard' fields. - */ - if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) - orflags = ASN1_STRFLGS_DUMP_ALL; - else - orflags = 0; - - len = ASN1_STRING_print_ex(out, val, flags | orflags); - if (len < 0) - return -1; - outlen += len; + len = ASN1_STRING_print_ex(out, val, flags | orflags); + if (len < 0) { + return -1; } - return outlen; + outlen += len; + } + return outlen; } int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, - unsigned long flags) -{ - if (flags == XN_FLAG_COMPAT) - return X509_NAME_print(out, nm, indent); - return do_name_ex(out, nm, indent, flags); + unsigned long flags) { + if (flags == XN_FLAG_COMPAT) { + return X509_NAME_print(out, nm, indent); + } + return do_name_ex(out, nm, indent, flags); } int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, - unsigned long flags) -{ - BIO *bio = NULL; - if (fp != NULL) { - /* If |fp| is NULL, this function returns the number of bytes without - * writing. */ - bio = BIO_new_fp(fp, BIO_NOCLOSE); - if (bio == NULL) { - return -1; - } + unsigned long flags) { + BIO *bio = NULL; + if (fp != NULL) { + // If |fp| is NULL, this function returns the number of bytes without + // writing. + bio = BIO_new_fp(fp, BIO_NOCLOSE); + if (bio == NULL) { + return -1; } - int ret = X509_NAME_print_ex(bio, nm, indent, flags); - BIO_free(bio); - return ret; + } + int ret = X509_NAME_print_ex(bio, nm, indent, flags); + BIO_free(bio); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/policy.c b/third_party/boringssl/kit/src/crypto/x509/policy.c new file mode 100644 index 00000000..b0c27126 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/policy.c @@ -0,0 +1,790 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "../x509v3/internal.h" +#include "internal.h" + + +// This file computes the X.509 policy tree, as described in RFC 5280, section +// 6.1. It differs in that: +// +// (1) It does not track "qualifier_set". This is not needed as it is not +// output by this implementation. +// +// (2) It builds a directed acyclic graph, rather than a tree. When a given +// policy matches multiple parents, RFC 5280 makes a separate node for +// each parent. This representation condenses them into one node with +// multiple parents. Thus we refer to this structure as a "policy graph", +// rather than a "policy tree". +// +// (3) "expected_policy_set" is not tracked explicitly and built temporarily +// as part of building the graph. +// +// (4) anyPolicy nodes are not tracked explicitly. +// +// (5) Some pruning steps are deferred to when policies are evaluated, as a +// reachability pass. + +// An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node +// from RFC 5280, section 6.1.2, step (a), but we store some fields differently. +typedef struct x509_policy_node_st { + // policy is the "valid_policy" field from RFC 5280. + ASN1_OBJECT *policy; + + // parent_policies, if non-empty, is the list of "valid_policy" values for all + // nodes which are a parent of this node. In this case, no entry in this list + // will be anyPolicy. This list is in no particular order and may contain + // duplicates if the corresponding certificate had duplicate mappings. + // + // If empty, this node has a single parent, anyPolicy. The node is then a root + // policies, and is in authorities-constrained-policy-set if it has a path to + // a leaf node. + // + // Note it is not possible for a policy to have both anyPolicy and a + // concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs if + // there was no match in step (d.1.i). We do not need to represent a parent + // list of, say, {anyPolicy, OID1, OID2}. + STACK_OF(ASN1_OBJECT) *parent_policies; + + // mapped is one if this node matches a policy mapping in the certificate and + // zero otherwise. + int mapped; + + // reachable is one if this node is reachable from some valid policy in the + // end-entity certificate. It is computed during |has_explicit_policy|. + int reachable; +} X509_POLICY_NODE; + +DEFINE_STACK_OF(X509_POLICY_NODE) + +// An X509_POLICY_LEVEL is the collection of nodes at the same depth in the +// policy graph. This structure can also be used to represent a level's +// "expected_policy_set" values. See |process_policy_mappings|. +typedef struct x509_policy_level_st { + // nodes is the list of nodes at this depth, except for the anyPolicy node, if + // any. This list is sorted by policy OID for efficient lookup. + STACK_OF(X509_POLICY_NODE) *nodes; + + // has_any_policy is one if there is an anyPolicy node at this depth, and zero + // otherwise. + int has_any_policy; +} X509_POLICY_LEVEL; + +DEFINE_STACK_OF(X509_POLICY_LEVEL) + +static int is_any_policy(const ASN1_OBJECT *obj) { + return OBJ_obj2nid(obj) == NID_any_policy; +} + +static void x509_policy_node_free(X509_POLICY_NODE *node) { + if (node != NULL) { + ASN1_OBJECT_free(node->policy); + sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free); + OPENSSL_free(node); + } +} + +static X509_POLICY_NODE *x509_policy_node_new(const ASN1_OBJECT *policy) { + assert(!is_any_policy(policy)); + X509_POLICY_NODE *node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); + if (node == NULL) { + return NULL; + } + OPENSSL_memset(node, 0, sizeof(X509_POLICY_NODE)); + node->policy = OBJ_dup(policy); + node->parent_policies = sk_ASN1_OBJECT_new_null(); + if (node->policy == NULL || node->parent_policies == NULL) { + x509_policy_node_free(node); + return NULL; + } + return node; +} + +static int x509_policy_node_cmp(const X509_POLICY_NODE *const *a, + const X509_POLICY_NODE *const *b) { + return OBJ_cmp((*a)->policy, (*b)->policy); +} + +static void x509_policy_level_free(X509_POLICY_LEVEL *level) { + if (level != NULL) { + sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free); + OPENSSL_free(level); + } +} + +static X509_POLICY_LEVEL *x509_policy_level_new(void) { + X509_POLICY_LEVEL *level = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL)); + if (level == NULL) { + return NULL; + } + OPENSSL_memset(level, 0, sizeof(X509_POLICY_LEVEL)); + level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp); + if (level->nodes == NULL) { + x509_policy_level_free(level); + return NULL; + } + return level; +} + +static int x509_policy_level_is_empty(const X509_POLICY_LEVEL *level) { + return !level->has_any_policy && sk_X509_POLICY_NODE_num(level->nodes) == 0; +} + +static void x509_policy_level_clear(X509_POLICY_LEVEL *level) { + level->has_any_policy = 0; + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + x509_policy_node_free(sk_X509_POLICY_NODE_value(level->nodes, i)); + } + sk_X509_POLICY_NODE_zero(level->nodes); +} + +// x509_policy_level_find returns the node in |level| corresponding to |policy|, +// or NULL if none exists. +static X509_POLICY_NODE *x509_policy_level_find(X509_POLICY_LEVEL *level, + const ASN1_OBJECT *policy) { + assert(sk_X509_POLICY_NODE_is_sorted(level->nodes)); + X509_POLICY_NODE node; + node.policy = (ASN1_OBJECT *)policy; + size_t idx; + if (!sk_X509_POLICY_NODE_find(level->nodes, &idx, &node)) { + return NULL; + } + return sk_X509_POLICY_NODE_value(level->nodes, idx); +} + +// x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns +// one on success and zero on error. No policy in |nodes| may already be present +// in |level|. This function modifies |nodes| to avoid making a copy, but the +// caller is still responsible for releasing |nodes| itself. +// +// This function is used to add nodes to |level| in bulk, and avoid resorting +// |level| after each addition. +static int x509_policy_level_add_nodes(X509_POLICY_LEVEL *level, + STACK_OF(X509_POLICY_NODE) *nodes) { + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i); + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { + return 0; + } + sk_X509_POLICY_NODE_set(nodes, i, NULL); + } + sk_X509_POLICY_NODE_sort(level->nodes); + +#if !defined(NDEBUG) + // There should be no duplicate nodes. + for (size_t i = 1; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + assert(OBJ_cmp(sk_X509_POLICY_NODE_value(level->nodes, i - 1)->policy, + sk_X509_POLICY_NODE_value(level->nodes, i)->policy) != 0); + } +#endif + return 1; +} + +static int policyinfo_cmp(const POLICYINFO *const *a, + const POLICYINFO *const *b) { + return OBJ_cmp((*a)->policyid, (*b)->policyid); +} + +static int delete_if_not_in_policies(X509_POLICY_NODE *node, void *data) { + const CERTIFICATEPOLICIES *policies = data; + assert(sk_POLICYINFO_is_sorted(policies)); + POLICYINFO info; + info.policyid = node->policy; + if (sk_POLICYINFO_find(policies, NULL, &info)) { + return 0; + } + x509_policy_node_free(node); + return 1; +} + +// process_certificate_policies updates |level| to incorporate |x509|'s +// certificate policies extension. This implements steps (d) and (e) of RFC +// 5280, section 6.1.3. |level| must contain the previous level's +// "expected_policy_set" information. For all but the top-most level, this is +// the output of |process_policy_mappings|. |any_policy_allowed| specifies +// whether anyPolicy is allowed or inhibited, taking into account the exception +// for self-issued certificates. +static int process_certificate_policies(const X509 *x509, + X509_POLICY_LEVEL *level, + int any_policy_allowed) { + int ret = 0; + int critical; + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + CERTIFICATEPOLICIES *policies = + X509_get_ext_d2i(x509, NID_certificate_policies, &critical, NULL); + if (policies == NULL) { + if (critical != -1) { + return 0; // Syntax error in the extension. + } + + // RFC 5280, section 6.1.3, step (e). + x509_policy_level_clear(level); + return 1; + } + + // certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4. + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (sk_POLICYINFO_num(policies) == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp); + sk_POLICYINFO_sort(policies); + int cert_has_any_policy = 0; + for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { + const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); + if (is_any_policy(policy->policyid)) { + cert_has_any_policy = 1; + } + if (i > 0 && OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid, + policy->policyid) == 0) { + // Per RFC 5280, section 4.2.1.4, |policies| may not have duplicates. + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + } + + // This does the same thing as RFC 5280, section 6.1.3, step (d), though in + // a slighty different order. |level| currently contains "expected_policy_set" + // values of the previous level. See |process_policy_mappings| for details. + const int previous_level_has_any_policy = level->has_any_policy; + + // First, we handle steps (d.1.i) and (d.2). The net effect of these two steps + // is to intersect |level| with |policies|, ignoring anyPolicy if it is + // inhibited. + if (!cert_has_any_policy || !any_policy_allowed) { + sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_not_in_policies, + policies); + level->has_any_policy = 0; + } + + // Step (d.1.ii) may attach new nodes to the previous level's anyPolicy node. + if (previous_level_has_any_policy) { + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) { + goto err; + } + for (size_t i = 0; i < sk_POLICYINFO_num(policies); i++) { + const POLICYINFO *policy = sk_POLICYINFO_value(policies, i); + // Though we've reordered the steps slightly, |policy| is in |level| if + // and only if it would have been a match in step (d.1.ii). + if (!is_any_policy(policy->policyid) && + x509_policy_level_find(level, policy->policyid) == NULL) { + X509_POLICY_NODE *node = x509_policy_node_new(policy->policyid); + if (node == NULL || // + !sk_X509_POLICY_NODE_push(new_nodes, node)) { + x509_policy_node_free(node); + goto err; + } + } + } + if (!x509_policy_level_add_nodes(level, new_nodes)) { + goto err; + } + } + + ret = 1; + +err: + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + CERTIFICATEPOLICIES_free(policies); + return ret; +} + +static int compare_issuer_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) { + return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy); +} + +static int compare_subject_policy(const POLICY_MAPPING *const *a, + const POLICY_MAPPING *const *b) { + return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); +} + +static int delete_if_mapped(X509_POLICY_NODE *node, void *data) { + const POLICY_MAPPINGS *mappings = data; + // |mappings| must have been sorted by |compare_issuer_policy|. + assert(sk_POLICY_MAPPING_is_sorted(mappings)); + POLICY_MAPPING mapping; + mapping.issuerDomainPolicy = node->policy; + if (!sk_POLICY_MAPPING_find(mappings, /*out_index=*/NULL, &mapping)) { + return 0; + } + x509_policy_node_free(node); + return 1; +} + +// process_policy_mappings processes the policy mappings extension of |cert|, +// whose corresponding graph level is |level|. |mapping_allowed| specifies +// whether policy mapping is inhibited at this point. On success, it returns an +// |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On +// error, it returns NULL. This implements steps (a) and (b) of RFC 5280, +// section 6.1.4. +// +// We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|. +// |has_any_policy| indicates whether there is an anyPolicy node with +// "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains +// P2 in its "expected_policy_set", the level will contain a node of policy P2 +// with P1 in |parent_policies|. +// +// This is equivalent to the |X509_POLICY_LEVEL| that would result if the next +// certificats contained anyPolicy. |process_certificate_policies| will filter +// this result down to compute the actual level. +static X509_POLICY_LEVEL *process_policy_mappings(const X509 *cert, + X509_POLICY_LEVEL *level, + int mapping_allowed) { + int ok = 0; + STACK_OF(X509_POLICY_NODE) *new_nodes = NULL; + X509_POLICY_LEVEL *next = NULL; + int critical; + POLICY_MAPPINGS *mappings = + X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL); + if (mappings == NULL && critical != -1) { + // Syntax error in the policy mappings extension. + goto err; + } + + if (mappings != NULL) { + // PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5. + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (sk_POLICY_MAPPING_num(mappings) == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + goto err; + } + + // RFC 5280, section 6.1.4, step (a). + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + if (is_any_policy(mapping->issuerDomainPolicy) || + is_any_policy(mapping->subjectDomainPolicy)) { + goto err; + } + } + + // Sort to group by issuerDomainPolicy. + sk_POLICY_MAPPING_set_cmp_func(mappings, compare_issuer_policy); + sk_POLICY_MAPPING_sort(mappings); + + if (mapping_allowed) { + // Mark nodes as mapped, and add any nodes to |level| which may be needed + // as part of RFC 5280, section 6.1.4, step (b.1). + new_nodes = sk_X509_POLICY_NODE_new_null(); + if (new_nodes == NULL) { + goto err; + } + const ASN1_OBJECT *last_policy = NULL; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + const POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + // There may be multiple mappings with the same |issuerDomainPolicy|. + if (last_policy != NULL && + OBJ_cmp(mapping->issuerDomainPolicy, last_policy) == 0) { + continue; + } + last_policy = mapping->issuerDomainPolicy; + + X509_POLICY_NODE *node = + x509_policy_level_find(level, mapping->issuerDomainPolicy); + if (node == NULL) { + if (!level->has_any_policy) { + continue; + } + node = x509_policy_node_new(mapping->issuerDomainPolicy); + if (node == NULL || // + !sk_X509_POLICY_NODE_push(new_nodes, node)) { + x509_policy_node_free(node); + goto err; + } + } + node->mapped = 1; + } + if (!x509_policy_level_add_nodes(level, new_nodes)) { + goto err; + } + } else { + // RFC 5280, section 6.1.4, step (b.2). If mapping is inhibited, delete + // all mapped nodes. + sk_X509_POLICY_NODE_delete_if(level->nodes, delete_if_mapped, mappings); + sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); + mappings = NULL; + } + } + + // If a node was not mapped, it retains the original "explicit_policy_set" + // value, itself. Add those to |mappings|. + if (mappings == NULL) { + mappings = sk_POLICY_MAPPING_new_null(); + if (mappings == NULL) { + goto err; + } + } + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (!node->mapped) { + POLICY_MAPPING *mapping = POLICY_MAPPING_new(); + if (mapping == NULL) { + goto err; + } + mapping->issuerDomainPolicy = OBJ_dup(node->policy); + mapping->subjectDomainPolicy = OBJ_dup(node->policy); + if (mapping->issuerDomainPolicy == NULL || + mapping->subjectDomainPolicy == NULL || + !sk_POLICY_MAPPING_push(mappings, mapping)) { + POLICY_MAPPING_free(mapping); + goto err; + } + } + } + + // Sort to group by subjectDomainPolicy. + sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy); + sk_POLICY_MAPPING_sort(mappings); + + // Convert |mappings| to our "expected_policy_set" representation. + next = x509_policy_level_new(); + if (next == NULL) { + goto err; + } + next->has_any_policy = level->has_any_policy; + + X509_POLICY_NODE *last_node = NULL; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) { + POLICY_MAPPING *mapping = sk_POLICY_MAPPING_value(mappings, i); + // Skip mappings where |issuerDomainPolicy| does not appear in the graph. + if (!level->has_any_policy && + x509_policy_level_find(level, mapping->issuerDomainPolicy) == NULL) { + continue; + } + + if (last_node == NULL || + OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) != 0) { + last_node = x509_policy_node_new(mapping->subjectDomainPolicy); + if (last_node == NULL || + !sk_X509_POLICY_NODE_push(next->nodes, last_node)) { + x509_policy_node_free(last_node); + goto err; + } + } + + if (!sk_ASN1_OBJECT_push(last_node->parent_policies, + mapping->issuerDomainPolicy)) { + goto err; + } + mapping->issuerDomainPolicy = NULL; + } + + sk_X509_POLICY_NODE_sort(next->nodes); + ok = 1; + +err: + if (!ok) { + x509_policy_level_free(next); + next = NULL; + } + + sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free); + sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free); + return next; +} + +// apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum +// of its current value and |skip_certs|. It returns one on success and zero if +// |skip_certs| is negative. +static int apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value) { + if (skip_certs == NULL) { + return 1; + } + + // TODO(https://crbug.com/boringssl/443): Move this check into the parser. + if (skip_certs->type & V_ASN1_NEG) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + return 0; + } + + // If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. + uint64_t u64; + if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value) { + *value = (size_t)u64; + } + ERR_clear_error(); + return 1; +} + +// process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and +// |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit +// anyPolicy extensions. It returns one on success and zero on error. This +// implements steps (i) and (j) of RFC 5280, section 6.1.4. +static int process_policy_constraints(const X509 *x509, size_t *explicit_policy, + size_t *policy_mapping, + size_t *inhibit_any_policy) { + int critical; + POLICY_CONSTRAINTS *constraints = + X509_get_ext_d2i(x509, NID_policy_constraints, &critical, NULL); + if (constraints == NULL && critical != -1) { + return 0; + } + if (constraints != NULL) { + if (constraints->requireExplicitPolicy == NULL && + constraints->inhibitPolicyMapping == NULL) { + // Per RFC 5280, section 4.2.1.11, at least one of the fields must be + // present. + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_POLICY_EXTENSION); + POLICY_CONSTRAINTS_free(constraints); + return 0; + } + int ok = + apply_skip_certs(constraints->requireExplicitPolicy, explicit_policy) && + apply_skip_certs(constraints->inhibitPolicyMapping, policy_mapping); + POLICY_CONSTRAINTS_free(constraints); + if (!ok) { + return 0; + } + } + + ASN1_INTEGER *inhibit_any_policy_ext = + X509_get_ext_d2i(x509, NID_inhibit_any_policy, &critical, NULL); + if (inhibit_any_policy_ext == NULL && critical != -1) { + return 0; + } + int ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy); + ASN1_INTEGER_free(inhibit_any_policy_ext); + return ok; +} + +// has_explicit_policy returns one if the set of authority-space policy OIDs +// |levels| has some non-empty intersection with |user_policies|, and zero +// otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This +// function modifies |levels| and should only be called at the end of policy +// evaluation. +static int has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels, + const STACK_OF(ASN1_OBJECT) *user_policies) { + assert(user_policies == NULL || sk_ASN1_OBJECT_is_sorted(user_policies)); + + // Step (g.i). If the policy graph is empty, the intersection is empty. + size_t num_levels = sk_X509_POLICY_LEVEL_num(levels); + X509_POLICY_LEVEL *level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1); + if (x509_policy_level_is_empty(level)) { + return 0; + } + + // If |user_policies| is empty, we interpret it as having a single anyPolicy + // value. The caller may also have supplied anyPolicy explicitly. + int user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) == 0; + for (size_t i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) { + if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) { + user_has_any_policy = 1; + break; + } + } + + // Step (g.ii). If the policy graph is not empty and the user set contains + // anyPolicy, the intersection is the entire (non-empty) graph. + if (user_has_any_policy) { + return 1; + } + + // Step (g.iii) does not delete anyPolicy nodes, so if the graph has + // anyPolicy, some explicit policy will survive. The actual intersection may + // synthesize some nodes in step (g.iii.3), but we do not return the policy + // list itself, so we skip actually computing this. + if (level->has_any_policy) { + return 1; + } + + // We defer pruning the tree, so as we look for nodes with parent anyPolicy, + // step (g.iii.1), we must limit to nodes reachable from the bottommost level. + // Start by marking each of those nodes as reachable. + for (size_t i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1; + } + + for (size_t i = num_levels - 1; i < num_levels; i--) { + level = sk_X509_POLICY_LEVEL_value(levels, i); + for (size_t j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) { + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(level->nodes, j); + if (!node->reachable) { + continue; + } + if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) { + // |node|'s parent is anyPolicy and is part of "valid_policy_node_set". + // If it exists in |user_policies|, the intersection is non-empty and we + // can return immediately. + if (sk_ASN1_OBJECT_find(user_policies, /*out_index=*/NULL, + node->policy)) { + return 1; + } + } else if (i > 0) { + // |node|'s parents are concrete policies. Mark the parents reachable, + // to be inspected by the next loop iteration. + X509_POLICY_LEVEL *prev = sk_X509_POLICY_LEVEL_value(levels, i - 1); + for (size_t k = 0; k < sk_ASN1_OBJECT_num(node->parent_policies); k++) { + X509_POLICY_NODE *parent = x509_policy_level_find( + prev, sk_ASN1_OBJECT_value(node->parent_policies, k)); + if (parent != NULL) { + parent->reachable = 1; + } + } + } + } + } + + return 0; +} + +static int asn1_object_cmp(const ASN1_OBJECT *const *a, + const ASN1_OBJECT *const *b) { + return OBJ_cmp(*a, *b); +} + +int X509_policy_check(const STACK_OF(X509) *certs, + const STACK_OF(ASN1_OBJECT) *user_policies, + unsigned long flags, X509 **out_current_cert) { + *out_current_cert = NULL; + int ret = X509_V_ERR_OUT_OF_MEM; + X509_POLICY_LEVEL *level = NULL; + STACK_OF(X509_POLICY_LEVEL) *levels = NULL; + STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL; + size_t num_certs = sk_X509_num(certs); + + // Skip policy checking if the chain is just the trust anchor. + if (num_certs <= 1) { + return X509_V_OK; + } + + // See RFC 5280, section 6.1.2, steps (d) through (f). + size_t explicit_policy = + (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1; + size_t inhibit_any_policy = + (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1; + size_t policy_mapping = + (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1; + + levels = sk_X509_POLICY_LEVEL_new_null(); + if (levels == NULL) { + goto err; + } + + for (size_t i = num_certs - 2; i < num_certs; i--) { + X509 *cert = sk_X509_value(certs, i); + if (!x509v3_cache_extensions(cert)) { + goto err; + } + const int is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0; + + if (level == NULL) { + assert(i == num_certs - 2); + level = x509_policy_level_new(); + if (level == NULL) { + goto err; + } + level->has_any_policy = 1; + } + + // RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed| is + // computed as in step (d.2). + const int any_policy_allowed = + inhibit_any_policy > 0 || (i > 0 && is_self_issued); + if (!process_certificate_policies(cert, level, any_policy_allowed)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + + // RFC 5280, section 6.1.3, step (f). + if (explicit_policy == 0 && x509_policy_level_is_empty(level)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + + // Insert into the list. + if (!sk_X509_POLICY_LEVEL_push(levels, level)) { + goto err; + } + X509_POLICY_LEVEL *current_level = level; + level = NULL; + + // If this is not the leaf certificate, we go to section 6.1.4. If it + // is the leaf certificate, we go to section 6.1.5 instead. + if (i != 0) { + // RFC 5280, section 6.1.4, steps (a) and (b). + level = process_policy_mappings(cert, current_level, policy_mapping > 0); + if (level == NULL) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + // RFC 5280, section 6.1.4, step (h-j) for non-leaves, and section 6.1.5, + // step (a-b) for leaves. In the leaf case, RFC 5280 says only to update + // |explicit_policy|, but |policy_mapping| and |inhibit_any_policy| are no + // longer read at this point, so we use the same process. + if (i == 0 || !is_self_issued) { + if (explicit_policy > 0) { + explicit_policy--; + } + if (policy_mapping > 0) { + policy_mapping--; + } + if (inhibit_any_policy > 0) { + inhibit_any_policy--; + } + } + if (!process_policy_constraints(cert, &explicit_policy, &policy_mapping, + &inhibit_any_policy)) { + ret = X509_V_ERR_INVALID_POLICY_EXTENSION; + *out_current_cert = cert; + goto err; + } + } + + // RFC 5280, section 6.1.5, step (g). We do not output the policy set, so it + // is only necessary to check if the user-constrained-policy-set is not empty. + if (explicit_policy == 0) { + // Build a sorted copy of |user_policies| for more efficient lookup. + if (user_policies != NULL) { + user_policies_sorted = sk_ASN1_OBJECT_dup(user_policies); + if (user_policies_sorted == NULL) { + goto err; + } + sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted, asn1_object_cmp); + sk_ASN1_OBJECT_sort(user_policies_sorted); + } + + if (!has_explicit_policy(levels, user_policies_sorted)) { + ret = X509_V_ERR_NO_EXPLICIT_POLICY; + goto err; + } + } + + ret = X509_V_OK; + +err: + x509_policy_level_free(level); + // |user_policies_sorted|'s contents are owned by |user_policies|, so we do + // not use |sk_ASN1_OBJECT_pop_free|. + sk_ASN1_OBJECT_free(user_policies_sorted); + sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free); + return ret; +} diff --git a/third_party/boringssl/kit/src/crypto/x509/rsa_pss.c b/third_party/boringssl/kit/src/crypto/x509/rsa_pss.c index 21a6bea9..9e69663e 100644 --- a/third_party/boringssl/kit/src/crypto/x509/rsa_pss.c +++ b/third_party/boringssl/kit/src/crypto/x509/rsa_pss.c @@ -9,7 +9,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -56,12 +56,13 @@ #include #include +#include #include #include #include -#include #include +#include #include #include "internal.h" @@ -77,19 +78,19 @@ static int rsa_pss_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, } ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { - ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), - ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), - ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), - ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3), + ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR, 0), + ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR, 1), + ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER, 2), + ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER, 3), } ASN1_SEQUENCE_END_cb(RSA_PSS_PARAMS, RSA_PSS_PARAMS) -IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) +IMPLEMENT_ASN1_FUNCTIONS_const(RSA_PSS_PARAMS) -/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ -static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { - if (alg == NULL || alg->parameter == NULL || - OBJ_obj2nid(alg->algorithm) != NID_mgf1 || +// Given an MGF1 Algorithm ID decode to an Algorithm Identifier +static X509_ALGOR *rsa_mgf1_decode(const X509_ALGOR *alg) { + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || + alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { return NULL; } @@ -99,30 +100,27 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { return d2i_X509_ALGOR(NULL, &p, plen); } -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, - X509_ALGOR **pmaskHash) { - *pmaskHash = NULL; - +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) { if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { return NULL; } const uint8_t *p = alg->parameter->value.sequence->data; int plen = alg->parameter->value.sequence->length; - RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); - if (pss == NULL) { - return NULL; - } - - *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - return pss; + return d2i_RSA_PSS_PARAMS(NULL, &p, plen); } -/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +static int is_allowed_pss_md(const EVP_MD *md) { + int md_type = EVP_MD_type(md); + return md_type == NID_sha256 || md_type == NID_sha384 || + md_type == NID_sha512; +} + +// rsa_md_to_algor sets |*palg| to an |X509_ALGOR| describing the digest |md|, +// which must be an allowed PSS digest. static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) { - if (EVP_MD_type(md) == NID_sha1) { - return 1; - } + // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. + assert(is_allowed_pss_md(md)); *palg = X509_ALGOR_new(); if (*palg == NULL) { return 0; @@ -131,16 +129,14 @@ static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) { return 1; } -/* Allocate and set MGF1 algorithm ID from EVP_MD */ +// rsa_md_to_mgf1 sets |*palg| to an |X509_ALGOR| describing MGF-1 with the +// digest |mgf1md|, which must be an allowed PSS digest. static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { + // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. + assert(is_allowed_pss_md(mgf1md)); X509_ALGOR *algtmp = NULL; ASN1_STRING *stmp = NULL; - *palg = NULL; - - if (EVP_MD_type(mgf1md) == NID_sha1) { - return 1; - } - /* need to embed algorithm ID inside another */ + // need to embed algorithm ID inside another if (!rsa_md_to_algor(&algtmp, mgf1md) || !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) { goto err; @@ -162,38 +158,35 @@ err: return 0; } -/* convert algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { - const EVP_MD *md; +static const EVP_MD *rsa_algor_to_md(const X509_ALGOR *alg) { if (!alg) { - return EVP_sha1(); - } - md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL) { + // If omitted, PSS defaults to SHA-1, which we do not allow. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + const EVP_MD *md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL || !is_allowed_pss_md(md)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; } return md; } -/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_mgf1_to_md(const X509_ALGOR *alg, - X509_ALGOR *maskHash) { - const EVP_MD *md; +static const EVP_MD *rsa_mgf1_to_md(const X509_ALGOR *alg) { if (!alg) { - return EVP_sha1(); - } - /* Check mask and lookup mask hash algorithm */ - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || - maskHash == NULL) { + // If omitted, PSS defaults to MGF-1 with SHA-1, which we do not allow. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return NULL; } - md = EVP_get_digestbyobj(maskHash->algorithm); - if (md == NULL) { + // Check mask and lookup mask hash algorithm. + X509_ALGOR *maskHash = rsa_mgf1_decode(alg); + if (maskHash == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return NULL; } - return md; + const EVP_MD *ret = rsa_algor_to_md(maskHash); + X509_ALGOR_free(maskHash); + return ret; } int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { @@ -205,18 +198,14 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return 0; } - EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + if (sigmd != mgf1md || !is_allowed_pss_md(sigmd)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; + } + int md_len = (int)EVP_MD_size(sigmd); if (saltlen == -1) { - saltlen = EVP_MD_size(sigmd); - } else if (saltlen == -2) { - // TODO(davidben): Forbid this mode. The world has largely standardized on - // salt length matching hash length. - saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; - if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { - saltlen--; - } - } else if (saltlen != (int)EVP_MD_size(sigmd)) { - // We only allow salt length matching hash length and, for now, the -2 case. + saltlen = md_len; + } else if (saltlen != md_len) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } @@ -228,12 +217,12 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { goto err; } - if (saltlen != 20) { - pss->saltLength = ASN1_INTEGER_new(); - if (!pss->saltLength || - !ASN1_INTEGER_set(pss->saltLength, saltlen)) { - goto err; - } + // The DEFAULT value is 20, but this does not match any supported digest. + assert(saltlen != 20); + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength || // + !ASN1_INTEGER_set_int64(pss->saltLength, saltlen)) { + goto err; } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || @@ -241,7 +230,7 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { goto err; } - /* Finally create string with pss parameter encoding. */ + // Finally create string with pss parameter encoding. if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { goto err; } @@ -260,35 +249,40 @@ int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); - /* Decode PSS parameters */ + // Decode PSS parameters int ret = 0; - X509_ALGOR *maskHash; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); if (pss == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); goto err; } - const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); + const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm); const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); if (mgf1md == NULL || md == NULL) { goto err; } - int saltlen = 20; - if (pss->saltLength != NULL) { - saltlen = ASN1_INTEGER_get(pss->saltLength); - - /* Could perform more salt length sanity checks but the main - * RSA routines will trap other invalid values anyway. */ - if (saltlen < 0) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } + // We require the MGF-1 and signing hashes to match. + if (mgf1md != md) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; } - /* low-level routines support only trailer field 0xbc (value 1) - * and PKCS#1 says we should reject any other value anyway. */ + // We require the salt length be the hash length. The DEFAULT value is 20, but + // this does not match any supported salt length. + uint64_t salt_len = 0; + if (pss->saltLength == NULL || + !ASN1_INTEGER_get_uint64(&salt_len, pss->saltLength) || + salt_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + assert(salt_len <= INT_MAX); + + // The trailer field must be 1 (0xbc). This value is DEFAULT, so the structure + // is required to omit it in DER. Although a syntax error, we also tolerate an + // explicitly-encoded value. See the certificates in cl/362617931. if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); goto err; @@ -297,7 +291,7 @@ int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY_CTX *pctx; if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || - !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, (int)salt_len) || !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { goto err; } @@ -306,7 +300,6 @@ int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, err: RSA_PSS_PARAMS_free(pss); - X509_ALGOR_free(maskHash); return ret; } @@ -315,8 +308,8 @@ int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); int rv = 0; - X509_ALGOR *maskHash; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + X509_ALGOR *maskHash = NULL; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); if (!pss) { if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { goto err; @@ -325,8 +318,8 @@ int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, goto err; } - if (BIO_puts(bp, "\n") <= 0 || - !BIO_indent(bp, indent, 128) || + if (BIO_puts(bp, "\n") <= 0 || // + !BIO_indent(bp, indent, 128) || // BIO_puts(bp, "Hash Algorithm: ") <= 0) { goto err; } @@ -339,31 +332,31 @@ int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, goto err; } - if (BIO_puts(bp, "\n") <= 0 || - !BIO_indent(bp, indent, 128) || + if (BIO_puts(bp, "\n") <= 0 || // + !BIO_indent(bp, indent, 128) || // BIO_puts(bp, "Mask Algorithm: ") <= 0) { goto err; } if (pss->maskGenAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || - BIO_puts(bp, " with ") <= 0) { - goto err; - } - - if (maskHash) { - if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { + maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + if (maskHash == NULL) { + if (BIO_puts(bp, "INVALID") <= 0) { + goto err; + } + } else { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || + BIO_puts(bp, " with ") <= 0 || + i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { goto err; } - } else if (BIO_puts(bp, "INVALID") <= 0) { - goto err; } } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { goto err; } BIO_puts(bp, "\n"); - if (!BIO_indent(bp, indent, 128) || + if (!BIO_indent(bp, indent, 128) || // BIO_puts(bp, "Salt Length: 0x") <= 0) { goto err; } @@ -377,7 +370,7 @@ int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, } BIO_puts(bp, "\n"); - if (!BIO_indent(bp, indent, 128) || + if (!BIO_indent(bp, indent, 128) || // BIO_puts(bp, "Trailer Field: 0x") <= 0) { goto err; } diff --git a/third_party/boringssl/kit/src/crypto/x509/t_crl.c b/third_party/boringssl/kit/src/crypto/x509/t_crl.c index d924f855..1957e317 100644 --- a/third_party/boringssl/kit/src/crypto/x509/t_crl.c +++ b/third_party/boringssl/kit/src/crypto/x509/t_crl.c @@ -54,6 +54,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#include + #include #include #include @@ -61,70 +63,83 @@ #include #include -int X509_CRL_print_fp(FILE *fp, X509_CRL *x) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); - return 0; - } - int ret = X509_CRL_print(b, x); - BIO_free(b); - return ret; +int X509_CRL_print_fp(FILE *fp, X509_CRL *x) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + int ret = X509_CRL_print(b, x); + BIO_free(b); + return ret; } -int X509_CRL_print(BIO *out, X509_CRL *x) -{ - STACK_OF(X509_REVOKED) *rev; - X509_REVOKED *r; - long l; - size_t i; - char *p; +int X509_CRL_print(BIO *out, X509_CRL *x) { + long version = X509_CRL_get_version(x); + assert(X509_CRL_VERSION_1 <= version && version <= X509_CRL_VERSION_2); + const X509_ALGOR *sig_alg; + const ASN1_BIT_STRING *signature; + X509_CRL_get0_signature(x, &signature, &sig_alg); + if (BIO_printf(out, "Certificate Revocation List (CRL):\n") <= 0 || + BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", version + 1, + (unsigned long)version) <= 0 || + // Note this and the other |X509_signature_print| call both print the + // outer signature algorithm, rather than printing the inner and outer + // ones separately. This matches OpenSSL, though it was probably a bug. + !X509_signature_print(out, sig_alg, NULL)) { + return 0; + } - BIO_printf(out, "Certificate Revocation List (CRL):\n"); - l = X509_CRL_get_version(x); - BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); - const X509_ALGOR *sig_alg; - const ASN1_BIT_STRING *signature; - X509_CRL_get0_signature(x, &signature, &sig_alg); - // Note this and the other |X509_signature_print| call print the outer - // signature algorithm twice, rather than both the inner and outer ones. - // This matches OpenSSL, though it was probably a bug. - X509_signature_print(out, sig_alg, NULL); - p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); - BIO_printf(out, "%8sIssuer: %s\n", "", p); - OPENSSL_free(p); - BIO_printf(out, "%8sLast Update: ", ""); - ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x)); - BIO_printf(out, "\n%8sNext Update: ", ""); - if (X509_CRL_get0_nextUpdate(x)) - ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x)); - else - BIO_printf(out, "NONE"); - BIO_printf(out, "\n"); + char *issuer = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); + int ok = issuer != NULL && BIO_printf(out, "%8sIssuer: %s\n", "", issuer) > 0; + OPENSSL_free(issuer); + if (!ok) { + return 0; + } - X509V3_extensions_print(out, "CRL extensions", X509_CRL_get0_extensions(x), - 0, 8); - - rev = X509_CRL_get_REVOKED(x); - - if (sk_X509_REVOKED_num(rev) > 0) - BIO_printf(out, "Revoked Certificates:\n"); - else - BIO_printf(out, "No Revoked Certificates.\n"); - - for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { - r = sk_X509_REVOKED_value(rev, i); - BIO_printf(out, " Serial Number: "); - i2a_ASN1_INTEGER(out, r->serialNumber); - BIO_printf(out, "\n Revocation Date: "); - ASN1_TIME_print(out, r->revocationDate); - BIO_printf(out, "\n"); - X509V3_extensions_print(out, "CRL entry extensions", - r->extensions, 0, 8); + if (BIO_printf(out, "%8sLast Update: ", "") <= 0 || + !ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x)) || + BIO_printf(out, "\n%8sNext Update: ", "") <= 0) { + return 0; + } + if (X509_CRL_get0_nextUpdate(x)) { + if (!ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x))) { + return 0; } - X509_signature_print(out, sig_alg, signature); + } else { + if (BIO_printf(out, "NONE") <= 0) { + return 0; + } + } - return 1; + if (BIO_printf(out, "\n") <= 0 || + !X509V3_extensions_print(out, "CRL extensions", + X509_CRL_get0_extensions(x), 0, 8)) { + return 0; + } + const STACK_OF(X509_REVOKED) *rev = X509_CRL_get_REVOKED(x); + if (sk_X509_REVOKED_num(rev) > 0) { + if (BIO_printf(out, "Revoked Certificates:\n") <= 0) { + return 0; + } + } else { + if (BIO_printf(out, "No Revoked Certificates.\n") <= 0) { + return 0; + } + } + + for (size_t i = 0; i < sk_X509_REVOKED_num(rev); i++) { + const X509_REVOKED *r = sk_X509_REVOKED_value(rev, i); + if (BIO_printf(out, " Serial Number: ") <= 0 || + i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r)) <= 0 || + BIO_printf(out, "\n Revocation Date: ") <= 0 || + !ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r)) || + BIO_printf(out, "\n") <= 0 || + !X509V3_extensions_print(out, "CRL entry extensions", + X509_REVOKED_get0_extensions(r), 0, 8)) { + } + } + + return X509_signature_print(out, sig_alg, signature); } diff --git a/third_party/boringssl/kit/src/crypto/x509/t_req.c b/third_party/boringssl/kit/src/crypto/x509/t_req.c index 82026641..e9287d5f 100644 --- a/third_party/boringssl/kit/src/crypto/x509/t_req.c +++ b/third_party/boringssl/kit/src/crypto/x509/t_req.c @@ -54,6 +54,7 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#include #include #include @@ -81,7 +82,7 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { long l; EVP_PKEY *pkey; - STACK_OF(X509_ATTRIBUTE) * sk; + STACK_OF(X509_ATTRIBUTE) *sk; char mlch = ' '; int nmindent = 0; @@ -104,7 +105,11 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_REQ_get_version(x); - if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) { + // Only zero, |X509_REQ_VERSION_1|, is valid but our parser accepts some + // invalid values for compatibility. + assert(0 <= l && l <= 2); + if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, + (unsigned long)l) <= 0) { goto err; } } @@ -184,10 +189,8 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, goto err; } - if (type == V_ASN1_PRINTABLESTRING || - type == V_ASN1_UTF8STRING || - type == V_ASN1_IA5STRING || - type == V_ASN1_T61STRING) { + if (type == V_ASN1_PRINTABLESTRING || type == V_ASN1_UTF8STRING || + type == V_ASN1_IA5STRING || type == V_ASN1_T61STRING) { if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) { goto err; } @@ -205,13 +208,12 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, if (exts) { BIO_printf(bio, "%8sRequested Extensions:\n", ""); - size_t i; - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); + for (size_t i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + const X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); if (BIO_printf(bio, "%12s", "") <= 0) { goto err; } - ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + const ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bio, obj); const int is_critical = X509_EXTENSION_get_critical(ex); if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) { diff --git a/third_party/boringssl/kit/src/crypto/x509/t_x509.c b/third_party/boringssl/kit/src/crypto/x509/t_x509.c index 7c32a879..1d71576c 100644 --- a/third_party/boringssl/kit/src/crypto/x509/t_x509.c +++ b/third_party/boringssl/kit/src/crypto/x509/t_x509.c @@ -54,6 +54,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#include + #include #include #include @@ -68,298 +70,262 @@ int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, - unsigned long cflag) -{ - BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); - if (b == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); - return 0; - } - int ret = X509_print_ex(b, x, nmflag, cflag); - BIO_free(b); - return ret; + unsigned long cflag) { + BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); + if (b == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + int ret = X509_print_ex(b, x, nmflag, cflag); + BIO_free(b); + return ret; } -int X509_print_fp(FILE *fp, X509 *x) -{ - return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +int X509_print_fp(FILE *fp, X509 *x) { + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); } -int X509_print(BIO *bp, X509 *x) -{ - return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +int X509_print(BIO *bp, X509 *x) { + return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); } int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, - unsigned long cflag) -{ - long l; - int ret = 0, i; - char *m = NULL, mlch = ' '; - int nmindent = 0; - X509_CINF *ci; - ASN1_INTEGER *bs; - EVP_PKEY *pkey = NULL; - const char *neg; + unsigned long cflag) { + char mlch = ' '; + int nmindent = 0; + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } - if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { - mlch = '\n'; - nmindent = 12; + if (nmflags == X509_FLAG_COMPAT) { + nmindent = 16; + } + + const X509_CINF *ci = x->cert_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate:\n", 13) <= 0) { + return 0; + } + if (BIO_write(bp, " Data:\n", 10) <= 0) { + return 0; + } + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + long l = X509_get_version(x); + assert(X509_VERSION_1 <= l && l <= X509_VERSION_3); + if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, + (unsigned long)l) <= 0) { + return 0; + } + } + if (!(cflag & X509_FLAG_NO_SERIAL)) { + if (BIO_write(bp, " Serial Number:", 22) <= 0) { + return 0; } - if (nmflags == X509_FLAG_COMPAT) - nmindent = 16; + const ASN1_INTEGER *serial = X509_get0_serialNumber(x); + uint64_t serial_u64; + if (ASN1_INTEGER_get_uint64(&serial_u64, serial)) { + assert(serial->type != V_ASN1_NEG_INTEGER); + if (BIO_printf(bp, " %" PRIu64 " (0x%" PRIx64 ")\n", serial_u64, + serial_u64) <= 0) { + return 0; + } + } else { + ERR_clear_error(); // Clear |ASN1_INTEGER_get_uint64|'s error. + const char *neg = + (serial->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; + if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) { + return 0; + } - ci = x->cert_info; - if (!(cflag & X509_FLAG_NO_HEADER)) { - if (BIO_write(bp, "Certificate:\n", 13) <= 0) - goto err; - if (BIO_write(bp, " Data:\n", 10) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_VERSION)) { - l = X509_get_version(x); - if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_SERIAL)) { - - if (BIO_write(bp, " Serial Number:", 22) <= 0) - goto err; - - bs = X509_get_serialNumber(x); - if (bs->length < (int)sizeof(long) - || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) { - l = ASN1_INTEGER_get(bs); - if (bs->type == V_ASN1_NEG_INTEGER) { - l = -l; - neg = "-"; - } else - neg = ""; - if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0) - goto err; - } else { - neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; - if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) - goto err; - - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02x%c", bs->data[i], - ((i + 1 == bs->length) ? '\n' : ':')) <= 0) - goto err; - } + for (int i = 0; i < serial->length; i++) { + if (BIO_printf(bp, "%02x%c", serial->data[i], + ((i + 1 == serial->length) ? '\n' : ':')) <= 0) { + return 0; } + } + } + } + if (!(cflag & X509_FLAG_NO_SIGNAME)) { + if (X509_signature_print(bp, ci->signature, NULL) <= 0) { + return 0; + } + } + + if (!(cflag & X509_FLAG_NO_ISSUER)) { + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) { + return 0; + } + if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) < + 0) { + return 0; + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + } + if (!(cflag & X509_FLAG_NO_VALIDITY)) { + if (BIO_write(bp, " Validity\n", 17) <= 0) { + return 0; + } + if (BIO_write(bp, " Not Before: ", 24) <= 0) { + return 0; + } + if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) { + return 0; + } + if (BIO_write(bp, "\n Not After : ", 25) <= 0) { + return 0; + } + if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) { + return 0; + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) { + return 0; + } + if (X509_NAME_print_ex(bp, X509_get_subject_name(x), nmindent, nmflags) < + 0) { + return 0; + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) { + return 0; + } + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) { + return 0; + } + if (BIO_puts(bp, "\n") <= 0) { + return 0; } - if (!(cflag & X509_FLAG_NO_SIGNAME)) { - if (X509_signature_print(bp, ci->signature, NULL) <= 0) - goto err; + EVP_PKEY *pkey = X509_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); } + } - if (!(cflag & X509_FLAG_NO_ISSUER)) { - if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) - goto err; - if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) - < 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; + if (!(cflag & X509_FLAG_NO_IDS)) { + if (ci->issuerUID) { + if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) { + return 0; + } + if (!X509_signature_dump(bp, ci->issuerUID, 12)) { + return 0; + } } - if (!(cflag & X509_FLAG_NO_VALIDITY)) { - if (BIO_write(bp, " Validity\n", 17) <= 0) - goto err; - if (BIO_write(bp, " Not Before: ", 24) <= 0) - goto err; - if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) - goto err; - if (BIO_write(bp, "\n Not After : ", 25) <= 0) - goto err; - if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; + if (ci->subjectUID) { + if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) { + return 0; + } + if (!X509_signature_dump(bp, ci->subjectUID, 12)) { + return 0; + } } - if (!(cflag & X509_FLAG_NO_SUBJECT)) { - if (BIO_printf(bp, " Subject:%c", mlch) <= 0) - goto err; - if (X509_NAME_print_ex - (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + X509V3_extensions_print(bp, "X509v3 extensions", ci->extensions, cflag, 8); + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) { + return 0; } - if (!(cflag & X509_FLAG_NO_PUBKEY)) { - if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) - goto err; - if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) - goto err; - if (BIO_puts(bp, "\n") <= 0) - goto err; - - pkey = X509_get_pubkey(x); - if (pkey == NULL) { - BIO_printf(bp, "%12sUnable to load Public Key\n", ""); - ERR_print_errors(bp); - } else { - EVP_PKEY_print_public(bp, pkey, 16, NULL); - EVP_PKEY_free(pkey); - } + } + if (!(cflag & X509_FLAG_NO_AUX)) { + if (!X509_CERT_AUX_print(bp, x->aux, 0)) { + return 0; } + } - if (!(cflag & X509_FLAG_NO_IDS)) { - if (ci->issuerUID) { - if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) - goto err; - if (!X509_signature_dump(bp, ci->issuerUID, 12)) - goto err; - } - if (ci->subjectUID) { - if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) - goto err; - if (!X509_signature_dump(bp, ci->subjectUID, 12)) - goto err; - } - } - - if (!(cflag & X509_FLAG_NO_EXTENSIONS)) - X509V3_extensions_print(bp, "X509v3 extensions", - ci->extensions, cflag, 8); - - if (!(cflag & X509_FLAG_NO_SIGDUMP)) { - if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_AUX)) { - if (!X509_CERT_AUX_print(bp, x->aux, 0)) - goto err; - } - ret = 1; - err: - if (m != NULL) - OPENSSL_free(m); - return (ret); -} - -int X509_ocspid_print(BIO *bp, X509 *x) -{ - unsigned char *der = NULL; - unsigned char *dertmp; - int derlen; - int i; - unsigned char SHA1md[SHA_DIGEST_LENGTH]; - - /* - * display the hash of the subject as it would appear in OCSP requests - */ - if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) - goto err; - derlen = i2d_X509_NAME(x->cert_info->subject, NULL); - if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) - goto err; - i2d_X509_NAME(x->cert_info->subject, &dertmp); - - if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) - goto err; - for (i = 0; i < SHA_DIGEST_LENGTH; i++) { - if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) - goto err; - } - OPENSSL_free(der); - der = NULL; - - /* - * display the hash of the public key as it would appear in OCSP requests - */ - if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) - goto err; - - if (!EVP_Digest(x->cert_info->key->public_key->data, - x->cert_info->key->public_key->length, - SHA1md, NULL, EVP_sha1(), NULL)) - goto err; - for (i = 0; i < SHA_DIGEST_LENGTH; i++) { - if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) - goto err; - } - BIO_printf(bp, "\n"); - - return (1); - err: - if (der != NULL) - OPENSSL_free(der); - return (0); + return 1; } int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, - const ASN1_STRING *sig) -{ - if (BIO_puts(bp, " Signature Algorithm: ") <= 0) - return 0; - if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) - return 0; + const ASN1_STRING *sig) { + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) { + return 0; + } - /* RSA-PSS signatures have parameters to print. */ - int sig_nid = OBJ_obj2nid(sigalg->algorithm); - if (sig_nid == NID_rsassaPss && - !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) { - return 0; - } + // RSA-PSS signatures have parameters to print. + int sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid == NID_rsassaPss && + !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) { + return 0; + } - if (sig) - return X509_signature_dump(bp, sig, 9); - else if (BIO_puts(bp, "\n") <= 0) - return 0; - return 1; + if (sig) { + return X509_signature_dump(bp, sig, 9); + } else if (BIO_puts(bp, "\n") <= 0) { + return 0; + } + return 1; } -int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) -{ - char *s, *c, *b; - int ret = 0, l, i; +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) { + char *s, *c, *b; + int ret = 0, i; - l = 80 - 2 - obase; - - b = X509_NAME_oneline(name, NULL, 0); - if (!b) - return 0; - if (!*b) { - OPENSSL_free(b); - return 1; - } - s = b + 1; /* skip the first slash */ - - c = s; - for (;;) { - if (((*s == '/') && - ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || - ((s[2] >= 'A') - && (s[2] <= 'Z') - && (s[3] == '=')) - ))) || (*s == '\0')) { - i = s - c; - if (BIO_write(bp, c, i) != i) - goto err; - c = s + 1; /* skip following slash */ - if (*s != '\0') { - if (BIO_write(bp, ", ", 2) != 2) - goto err; - } - l--; - } - if (*s == '\0') - break; - s++; - l--; - } - - ret = 1; - if (0) { - err: - OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); - } + b = X509_NAME_oneline(name, NULL, 0); + if (!b) { + return 0; + } + if (!*b) { OPENSSL_free(b); - return (ret); + return 1; + } + s = b + 1; // skip the first slash + + c = s; + for (;;) { + if (((*s == '/') && ((s[1] >= 'A') && (s[1] <= 'Z') && + ((s[2] == '=') || ((s[2] >= 'A') && (s[2] <= 'Z') && + (s[3] == '='))))) || + (*s == '\0')) { + i = s - c; + if (BIO_write(bp, c, i) != i) { + goto err; + } + c = s + 1; // skip following slash + if (*s != '\0') { + if (BIO_write(bp, ", ", 2) != 2) { + goto err; + } + } + } + if (*s == '\0') { + break; + } + s++; + } + + ret = 1; + if (0) { + err: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/t_x509a.c b/third_party/boringssl/kit/src/crypto/x509/t_x509a.c index 4c7b2128..956b9a03 100644 --- a/third_party/boringssl/kit/src/crypto/x509/t_x509a.c +++ b/third_party/boringssl/kit/src/crypto/x509/t_x509a.c @@ -63,54 +63,59 @@ #include "internal.h" -/* X509_CERT_AUX and string set routines */ +// X509_CERT_AUX and string set routines -int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) -{ - char oidstr[80], first; - size_t i; - int j; - if (!aux) - return 1; - if (aux->trust) { - first = 1; - BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); - for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { - if (!first) - BIO_puts(out, ", "); - else - first = 0; - OBJ_obj2txt(oidstr, sizeof oidstr, - sk_ASN1_OBJECT_value(aux->trust, i), 0); - BIO_puts(out, oidstr); - } - BIO_puts(out, "\n"); - } else - BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); - if (aux->reject) { - first = 1; - BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); - for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { - if (!first) - BIO_puts(out, ", "); - else - first = 0; - OBJ_obj2txt(oidstr, sizeof oidstr, - sk_ASN1_OBJECT_value(aux->reject, i), 0); - BIO_puts(out, oidstr); - } - BIO_puts(out, "\n"); - } else - BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); - if (aux->alias) { - BIO_printf(out, "%*sAlias: %.*s\n", indent, "", aux->alias->length, - aux->alias->data); - } - if (aux->keyid) { - BIO_printf(out, "%*sKey Id: ", indent, ""); - for (j = 0; j < aux->keyid->length; j++) - BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]); - BIO_write(out, "\n", 1); - } +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) { + char oidstr[80], first; + size_t i; + int j; + if (!aux) { return 1; + } + if (aux->trust) { + first = 1; + BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { + if (!first) { + BIO_puts(out, ", "); + } else { + first = 0; + } + OBJ_obj2txt(oidstr, sizeof oidstr, sk_ASN1_OBJECT_value(aux->trust, i), + 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); + } + if (aux->reject) { + first = 1; + BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { + if (!first) { + BIO_puts(out, ", "); + } else { + first = 0; + } + OBJ_obj2txt(oidstr, sizeof oidstr, sk_ASN1_OBJECT_value(aux->reject, i), + 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + } + if (aux->alias) { + BIO_printf(out, "%*sAlias: %.*s\n", indent, "", aux->alias->length, + aux->alias->data); + } + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (j = 0; j < aux->keyid->length; j++) { + BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]); + } + BIO_write(out, "\n", 1); + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509/test/make_basic_constraints.go b/third_party/boringssl/kit/src/crypto/x509/test/make_basic_constraints.go index 23158b59..ea502b4c 100644 --- a/third_party/boringssl/kit/src/crypto/x509/test/make_basic_constraints.go +++ b/third_party/boringssl/kit/src/crypto/x509/test/make_basic_constraints.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2020, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2020, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // make_basic_constraints.go generates self-signed certificates with the basic // constraints extension. @@ -23,8 +25,8 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" - "io/ioutil" "math/big" + "os" "time" ) @@ -75,7 +77,7 @@ func main() { } certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes}) - if err := ioutil.WriteFile(fmt.Sprintf("basic_constraints_%s.pem", cert.name), certPEM, 0666); err != nil { + if err := os.WriteFile(fmt.Sprintf("basic_constraints_%s.pem", cert.name), certPEM, 0666); err != nil { panic(err) } } diff --git a/third_party/boringssl/kit/src/crypto/x509/test/make_invalid_extensions.go b/third_party/boringssl/kit/src/crypto/x509/test/make_invalid_extensions.go index d0c2ceeb..8287bf8d 100644 --- a/third_party/boringssl/kit/src/crypto/x509/test/make_invalid_extensions.go +++ b/third_party/boringssl/kit/src/crypto/x509/test/make_invalid_extensions.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2020, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2020, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // make_invalid_extensions.go generates a number of certificate chains with // invalid extension encodings. @@ -49,9 +51,9 @@ var extensions = []extension{ var leafKey, intermediateKey, rootKey *ecdsa.PrivateKey func init() { - leafKey = ecdsaKeyFromPEMOrPanic(leafKeyPEM) - intermediateKey = ecdsaKeyFromPEMOrPanic(intermediateKeyPEM) - rootKey = ecdsaKeyFromPEMOrPanic(rootKeyPEM) + leafKey = mustParseECDSAKey(leafKeyPEM) + intermediateKey = mustParseECDSAKey(intermediateKeyPEM) + rootKey = mustParseECDSAKey(rootKeyPEM) } type templateAndKey struct { @@ -59,7 +61,7 @@ type templateAndKey struct { key *ecdsa.PrivateKey } -func generateCertificateOrPanic(path string, subject, issuer *templateAndKey) []byte { +func mustGenerateCertificate(path string, subject, issuer *templateAndKey) []byte { cert, err := x509.CreateCertificate(rand.Reader, &subject.template, &issuer.template, &subject.key.PublicKey, issuer.key) if err != nil { panic(err) @@ -135,9 +137,9 @@ func main() { } // Generate a valid certificate chain from the templates. - generateCertificateOrPanic("invalid_extension_root.pem", &root, &root) - generateCertificateOrPanic("invalid_extension_intermediate.pem", &intermediate, &root) - leafDER := generateCertificateOrPanic("invalid_extension_leaf.pem", &leaf, &intermediate) + mustGenerateCertificate("invalid_extension_root.pem", &root, &root) + mustGenerateCertificate("invalid_extension_intermediate.pem", &intermediate, &root) + leafDER := mustGenerateCertificate("invalid_extension_leaf.pem", &leaf, &intermediate) leafCert, err := x509.ParseCertificate(leafDER) if err != nil { @@ -151,15 +153,15 @@ func main() { rootInvalid := root rootInvalid.template.ExtraExtensions = invalidExtension - generateCertificateOrPanic(fmt.Sprintf("invalid_extension_root_%s.pem", ext.name), &rootInvalid, &rootInvalid) + mustGenerateCertificate(fmt.Sprintf("invalid_extension_root_%s.pem", ext.name), &rootInvalid, &rootInvalid) intermediateInvalid := intermediate intermediateInvalid.template.ExtraExtensions = invalidExtension - generateCertificateOrPanic(fmt.Sprintf("invalid_extension_intermediate_%s.pem", ext.name), &intermediateInvalid, &root) + mustGenerateCertificate(fmt.Sprintf("invalid_extension_intermediate_%s.pem", ext.name), &intermediateInvalid, &root) leafInvalid := leaf leafInvalid.template.ExtraExtensions = invalidExtension - generateCertificateOrPanic(fmt.Sprintf("invalid_extension_leaf_%s.pem", ext.name), &leafInvalid, &intermediate) + mustGenerateCertificate(fmt.Sprintf("invalid_extension_leaf_%s.pem", ext.name), &leafInvalid, &intermediate) // Additionally generate a copy of the leaf certificate with extra data in // the extension. @@ -177,7 +179,7 @@ func main() { leafTrailingData := leaf leafTrailingData.template.ExtraExtensions = trailingDataExtension - generateCertificateOrPanic(fmt.Sprintf("trailing_data_leaf_%s.pem", ext.name), &leafTrailingData, &intermediate) + mustGenerateCertificate(fmt.Sprintf("trailing_data_leaf_%s.pem", ext.name), &leafTrailingData, &intermediate) } } @@ -199,7 +201,7 @@ Hr+qcPlp5N1jM3ACXys57bPujg+hRANCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44Tq ChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolt -----END PRIVATE KEY-----` -func ecdsaKeyFromPEMOrPanic(in string) *ecdsa.PrivateKey { +func mustParseECDSAKey(in string) *ecdsa.PrivateKey { keyBlock, _ := pem.Decode([]byte(in)) if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" { panic("could not decode private key") diff --git a/third_party/boringssl/kit/src/crypto/x509/test/make_many_constraints.go b/third_party/boringssl/kit/src/crypto/x509/test/make_many_constraints.go index 578618df..24a5c407 100644 --- a/third_party/boringssl/kit/src/crypto/x509/test/make_many_constraints.go +++ b/third_party/boringssl/kit/src/crypto/x509/test/make_many_constraints.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2017, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // make_many_constraints.go generates test certificates many_constraints.pem, // many_names*.pem, and some_names*.pem for x509_test.cc @@ -107,10 +109,10 @@ func main() { NotBefore: notBefore, NotAfter: notAfter, BasicConstraintsValid: true, - IsCA: true, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - KeyUsage: x509.KeyUsageCertSign, - SignatureAlgorithm: x509.SHA256WithRSA, + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageCertSign, + SignatureAlgorithm: x509.SHA256WithRSA, } for i := 0; i < 513; i++ { caTemplate.ExcludedDNSDomains = append(caTemplate.ExcludedDNSDomains, fmt.Sprintf("x%d.test", i)) @@ -149,10 +151,10 @@ func main() { NotBefore: notBefore, NotAfter: notAfter, BasicConstraintsValid: true, - IsCA: false, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, - SignatureAlgorithm: x509.SHA256WithRSA, + IsCA: false, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + SignatureAlgorithm: x509.SHA256WithRSA, } for i := 0; i < leaf.names; i++ { leafTemplate.DNSNames = append(leafTemplate.DNSNames, fmt.Sprintf("t%d.test", i)) diff --git a/third_party/boringssl/kit/src/crypto/x509/test/make_policy_certs.go b/third_party/boringssl/kit/src/crypto/x509/test/make_policy_certs.go new file mode 100644 index 00000000..739d8ced --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/make_policy_certs.go @@ -0,0 +1,353 @@ +// Copyright (c) 2020, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore + +// make_policy_certs.go generates certificates for testing policy handling. +package main + +import ( + "crypto/ecdsa" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "encoding/pem" + "flag" + "math/big" + "os" + "time" + + "golang.org/x/crypto/cryptobyte" + cbasn1 "golang.org/x/crypto/cryptobyte/asn1" +) + +var resetFlag = flag.Bool("reset", false, "if set, regenerates certificates that already exist") + +var ( + // https://davidben.net/oid + testOID1 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 1}) + testOID2 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 2}) + testOID3 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 3}) + testOID4 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 4}) + testOID5 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 5}) + + // https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.4 + certificatePoliciesOID = asn1.ObjectIdentifier([]int{2, 5, 29, 32}) + anyPolicyOID = asn1.ObjectIdentifier([]int{2, 5, 29, 32, 0}) + + // https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.5 + policyMappingsOID = asn1.ObjectIdentifier([]int{2, 5, 29, 33}) + + // https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.11 + policyConstraintsOID = asn1.ObjectIdentifier([]int{2, 5, 29, 36}) +) + +var leafKey, intermediateKey, rootKey *ecdsa.PrivateKey + +func init() { + leafKey = mustParseECDSAKey(leafKeyPEM) + intermediateKey = mustParseECDSAKey(intermediateKeyPEM) + rootKey = mustParseECDSAKey(rootKeyPEM) +} + +type templateAndKey struct { + template x509.Certificate + key *ecdsa.PrivateKey +} + +func mustGenerateCertificate(path string, subject, issuer *templateAndKey) { + if !*resetFlag { + // Skip if the file already exists. + _, err := os.Stat(path) + if err == nil { + return + } + if !os.IsNotExist(err) { + panic(err) + } + } + cert, err := x509.CreateCertificate(rand.Reader, &subject.template, &issuer.template, &subject.key.PublicKey, issuer.key) + if err != nil { + panic(err) + } + file, err := os.Create(path) + if err != nil { + panic(err) + } + defer file.Close() + err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: cert}) + if err != nil { + panic(err) + } +} + +func main() { + flag.Parse() + + notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z") + if err != nil { + panic(err) + } + notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z") + if err != nil { + panic(err) + } + + root2 := templateAndKey{ + template: x509.Certificate{ + SerialNumber: new(big.Int).SetInt64(1), + Subject: pkix.Name{CommonName: "Policy Root 2"}, + NotBefore: notBefore, + NotAfter: notAfter, + BasicConstraintsValid: true, + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageCertSign, + SignatureAlgorithm: x509.ECDSAWithSHA256, + }, + key: rootKey, + } + root := templateAndKey{ + template: x509.Certificate{ + SerialNumber: new(big.Int).SetInt64(1), + Subject: pkix.Name{CommonName: "Policy Root"}, + NotBefore: notBefore, + NotAfter: notAfter, + BasicConstraintsValid: true, + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageCertSign, + SignatureAlgorithm: x509.ECDSAWithSHA256, + }, + key: rootKey, + } + intermediate := templateAndKey{ + template: x509.Certificate{ + SerialNumber: new(big.Int).SetInt64(2), + Subject: pkix.Name{CommonName: "Policy Intermediate"}, + NotBefore: notBefore, + NotAfter: notAfter, + BasicConstraintsValid: true, + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageCertSign, + SignatureAlgorithm: x509.ECDSAWithSHA256, + PolicyIdentifiers: []asn1.ObjectIdentifier{testOID1, testOID2}, + }, + key: intermediateKey, + } + leaf := templateAndKey{ + template: x509.Certificate{ + SerialNumber: new(big.Int).SetInt64(3), + Subject: pkix.Name{CommonName: "www.example.com"}, + NotBefore: notBefore, + NotAfter: notAfter, + BasicConstraintsValid: true, + IsCA: false, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageCertSign, + SignatureAlgorithm: x509.ECDSAWithSHA256, + DNSNames: []string{"www.example.com"}, + PolicyIdentifiers: []asn1.ObjectIdentifier{testOID1, testOID2}, + }, + key: leafKey, + } + + // Generate a valid certificate chain from the templates. + mustGenerateCertificate("policy_root.pem", &root, &root) + mustGenerateCertificate("policy_intermediate.pem", &intermediate, &root) + mustGenerateCertificate("policy_leaf.pem", &leaf, &intermediate) + + // root2 is used for tests that need a longer chain, using a Root/Root2 + // cross-sign as one of the certificates. + mustGenerateCertificate("policy_root2.pem", &root2, &root2) + + // Introduce syntax errors in the leaf and intermediate. + leafInvalid := leaf + leafInvalid.template.PolicyIdentifiers = nil + leafInvalid.template.ExtraExtensions = []pkix.Extension{{Id: certificatePoliciesOID, Value: []byte("INVALID")}} + mustGenerateCertificate("policy_leaf_invalid.pem", &leafInvalid, &root) + + intermediateInvalid := intermediate + intermediateInvalid.template.PolicyIdentifiers = nil + intermediateInvalid.template.ExtraExtensions = []pkix.Extension{{Id: certificatePoliciesOID, Value: []byte("INVALID")}} + mustGenerateCertificate("policy_intermediate_invalid.pem", &intermediateInvalid, &root) + + // Duplicates are not allowed in certificatePolicies. + leafDuplicate := leaf + leafDuplicate.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2} + mustGenerateCertificate("policy_leaf_duplicate.pem", &leafDuplicate, &root) + + intermediateDuplicate := intermediate + intermediateDuplicate.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2} + mustGenerateCertificate("policy_intermediate_duplicate.pem", &intermediateDuplicate, &root) + + // Various policy constraints with requireExplicitPolicy values. + b := cryptobyte.NewBuilder(nil) + b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) { + seq.AddASN1Int64WithTag(0, cbasn1.Tag(0).ContextSpecific()) + }) + requireExplicitPolicy0 := b.BytesOrPanic() + + b = cryptobyte.NewBuilder(nil) + b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) { + seq.AddASN1Int64WithTag(1, cbasn1.Tag(0).ContextSpecific()) + }) + requireExplicitPolicy1 := b.BytesOrPanic() + + b = cryptobyte.NewBuilder(nil) + b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) { + seq.AddASN1Int64WithTag(2, cbasn1.Tag(0).ContextSpecific()) + }) + requireExplicitPolicy2 := b.BytesOrPanic() + + // A version of the intermediate that sets requireExplicitPolicy, skipping + // zero certificates. + intermediateRequire := intermediate + intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy0}} + mustGenerateCertificate("policy_intermediate_require.pem", &intermediateRequire, &root) + + // Same as above, but there are no policies on the intermediate. + intermediateRequire.template.PolicyIdentifiers = nil + mustGenerateCertificate("policy_intermediate_require_no_policies.pem", &intermediateRequire, &root) + + // Same as above, but the policy list has duplicates. + intermediateRequire.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2} + mustGenerateCertificate("policy_intermediate_require_duplicate.pem", &intermediateRequire, &root) + + // Corresponding certificates that instead assert the anyPolicy OID. + intermediateAny := intermediate + intermediateAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID} + mustGenerateCertificate("policy_intermediate_any.pem", &intermediateAny, &root) + + // Other requireExplicitPolicy values, on the leaf and intermediate. + intermediateRequire = intermediate + intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy1}} + mustGenerateCertificate("policy_intermediate_require1.pem", &intermediateRequire, &root) + intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy2}} + mustGenerateCertificate("policy_intermediate_require2.pem", &intermediateRequire, &root) + leafRequire := leaf + leafRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy0}} + mustGenerateCertificate("policy_leaf_require.pem", &leafRequire, &intermediate) + leafRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy1}} + mustGenerateCertificate("policy_leaf_require1.pem", &leafRequire, &intermediate) + + leafAny := leaf + leafAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID} + mustGenerateCertificate("policy_leaf_any.pem", &leafAny, &intermediate) + + // An intermediate which maps OID1 to (OID2, OID3), and which asserts the + // input OIDs either all at once, or as anyPolicy. + b = cryptobyte.NewBuilder(nil) + b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) { + // Map OID3 to (OID1, OID2). + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID3) + mapping.AddASN1ObjectIdentifier(testOID1) + }) + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID3) + mapping.AddASN1ObjectIdentifier(testOID2) + }) + + // Map all pairs of OID4 and OID5 to each other. + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID4) + mapping.AddASN1ObjectIdentifier(testOID4) + }) + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID4) + mapping.AddASN1ObjectIdentifier(testOID5) + }) + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID5) + mapping.AddASN1ObjectIdentifier(testOID4) + }) + seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) { + mapping.AddASN1ObjectIdentifier(testOID5) + mapping.AddASN1ObjectIdentifier(testOID5) + }) + }) + intermediateMapped := intermediate + intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID3, testOID4, testOID5} + intermediateMapped.template.ExtraExtensions = []pkix.Extension{{Id: policyMappingsOID, Value: b.BytesOrPanic()}} + mustGenerateCertificate("policy_intermediate_mapped.pem", &intermediateMapped, &root) + + intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID} + mustGenerateCertificate("policy_intermediate_mapped_any.pem", &intermediateMapped, &root) + + intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID3} + mustGenerateCertificate("policy_intermediate_mapped_oid3.pem", &intermediateMapped, &root) + + // Leaves which assert more specific OIDs, to test intermediate_mapped. + leafSingle := leaf + leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1} + mustGenerateCertificate("policy_leaf_oid1.pem", &leafSingle, &intermediate) + leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID2} + mustGenerateCertificate("policy_leaf_oid2.pem", &leafSingle, &intermediate) + leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID3} + mustGenerateCertificate("policy_leaf_oid3.pem", &leafSingle, &intermediate) + leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID4} + mustGenerateCertificate("policy_leaf_oid4.pem", &leafSingle, &intermediate) + leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID5} + mustGenerateCertificate("policy_leaf_oid5.pem", &leafSingle, &intermediate) + + leafNone := leaf + leafNone.template.PolicyIdentifiers = nil + mustGenerateCertificate("policy_leaf_none.pem", &leafNone, &intermediate) + + // Make version of Root, signed by Root 2, with policy mapping inhibited. + // This can be combined with intermediateMapped to test the combination. + b = cryptobyte.NewBuilder(nil) + b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) { + seq.AddASN1Int64WithTag(0, cbasn1.Tag(1).ContextSpecific()) + }) + inhibitPolicyMapping0 := b.BytesOrPanic() + + inhibitMapping := root + inhibitMapping.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID} + inhibitMapping.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: inhibitPolicyMapping0}} + mustGenerateCertificate("policy_root_cross_inhibit_mapping.pem", &inhibitMapping, &root2) +} + +const leafKeyPEM = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgoPUXNXuH9mgiS/nk +024SYxryxMa3CyGJldiHymLxSquhRANCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5 +w8u3SSwm7HZREvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5X +-----END PRIVATE KEY-----` + +const intermediateKeyPEM = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgWHKCKgY058ahE3t6 +vpxVQgzlycgCVMogwjK0y3XMNfWhRANCAATiOnyojN4xS5C8gJ/PHL5cOEsMbsoE +Y6KT9xRQSh8lEL4d1Vb36kqUgkpqedEImo0Og4Owk6VWVVR/m4Lk+yUw +-----END PRIVATE KEY-----` + +const rootKeyPEM = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBwND/eHytW0I417J +Hr+qcPlp5N1jM3ACXys57bPujg+hRANCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44Tq +ChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolt +-----END PRIVATE KEY-----` + +func mustParseECDSAKey(in string) *ecdsa.PrivateKey { + keyBlock, _ := pem.Decode([]byte(in)) + if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" { + panic("could not decode private key") + } + key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes) + if err != nil { + panic(err) + } + return key.(*ecdsa.PrivateKey) +} diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate.pem new file mode 100644 index 00000000..759deb4c --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqjCCAVGgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgYUwgYIwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAoGCCqGSM49BAMCA0cAMEQCIFN2ZtknXQ9vz23qD1ecprC9iIo7 +j/SI42Ub64qZQaraAiA+CRCWJz/l+NQ1+TPWYDDWY6Wh2L9Wbddh1Nj5KJEkhQ== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_any.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_any.pem new file mode 100644 index 00000000..0931964f --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_any.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBkDCCATWgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjajBoMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZIzj0EAwIDSQAwRgIh +AJbyXshUwjsFCiqrJkg91GzJdhZZ+3WXOekCJgi8uEESAiEAhv4sEE0wRRqgHDjl +vIt26IELfFE2Z/FBF3ihGmi6NoI= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_duplicate.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_duplicate.pem new file mode 100644 index 00000000..0eafe8d8 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBvDCCAWKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZYwgZMwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgUpG6 +FUeWrC62BtTPHiSlWBdnLWUYH0llS6uYUkpJFJECIQCWfhoZYXvHdMhgBDSI/vzY +Sw4uNdcMxrC2kP6lIioUSw== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_invalid.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_invalid.pem new file mode 100644 index 00000000..11c95afc --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_invalid.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjDCCATKgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjZzBlMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjAOBgNVHSAEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgS2uK +cYlZ1bxeqgMy3X0Sfi0arAnqpePsAqAeEf+HJHQCIQDwfCnXrWyHET9lM/gJSkfN +j/JRJvJELDrAMVewCxZWKA== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped.pem new file mode 100644 index 00000000..fa45e604 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAlSgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggGHMIIBgzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wXgYDVR0gBFcwVTAPBg0qhkiG9xIEAYS3CQIBMA8GDSqG +SIb3EgQBhLcJAgIwDwYNKoZIhvcSBAGEtwkCAzAPBg0qhkiG9xIEAYS3CQIEMA8G +DSqGSIb3EgQBhLcJAgUwgcsGA1UdIQSBwzCBwDAeBg0qhkiG9xIEAYS3CQIDBg0q +hkiG9xIEAYS3CQIBMB4GDSqGSIb3EgQBhLcJAgMGDSqGSIb3EgQBhLcJAgIwHgYN +KoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBDAeBg0qhkiG9xIEAYS3CQIEBg0q +hkiG9xIEAYS3CQIFMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgQwHgYN +KoZIhvcSBAGEtwkCBQYNKoZIhvcSBAGEtwkCBTAKBggqhkjOPQQDAgNIADBFAiAe +Ah2vJMZsW/RV35mM7b7/NjsjScjPEIxfDJu49inNXQIhANmGBqyWUogh/gXyVB0/ +IfDro27pANW3R02A+zH34q5k +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_any.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_any.pem new file mode 100644 index 00000000..ae47bf45 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_any.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYjCCAgegAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggE6MIIBNjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wEQYDVR0gBAowCDAGBgRVHSAAMIHLBgNVHSEEgcMwgcAw +HgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG9xIEAYS3CQID +Bg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3EgQBhLcJAgQw +HgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG9xIEAYS3CQIF +Bg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3EgQBhLcJAgUw +CgYIKoZIzj0EAwIDSQAwRgIhAIOx3GL5xlldQGdTLIvTTAvczm8wiYHzZDAif2yj +wAjEAiEAg4K02kTYX9x7PC/u1PYdwvo+LVbnGbO6AN6U3K2d7gs= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_oid3.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_oid3.pem new file mode 100644 index 00000000..c04a38a4 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_mapped_oid3.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICajCCAhCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjggFDMIIBPzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkNL3/g7u +qGsIhGHCxes9UFqAba4wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMIHLBgNV +HSEEgcMwgcAwHgYNKoZIhvcSBAGEtwkCAwYNKoZIhvcSBAGEtwkCATAeBg0qhkiG +9xIEAYS3CQIDBg0qhkiG9xIEAYS3CQICMB4GDSqGSIb3EgQBhLcJAgQGDSqGSIb3 +EgQBhLcJAgQwHgYNKoZIhvcSBAGEtwkCBAYNKoZIhvcSBAGEtwkCBTAeBg0qhkiG +9xIEAYS3CQIFBg0qhkiG9xIEAYS3CQIEMB4GDSqGSIb3EgQBhLcJAgUGDSqGSIb3 +EgQBhLcJAgUwCgYIKoZIzj0EAwIDSAAwRQIhAK0bRaGgd5qQlX+zTw3IUynFHxfk +zRbZagnTzjYtkNNmAiBJ2kOnvRdW930eHAwZPGpc1Hn5hMSOQdUhNZ3XZDASkQ== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require.pem new file mode 100644 index 00000000..5cf5d5bf --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQAwCgYIKoZIzj0EAwIDRwAwRAIgbPUZ9ezH +SgTqom7VLPOvrQQXwy3b/ijSobs7+SOouKMCIDaqcb9143BG005etqeTvlgUyOGF +GQDWhiW8bizH+KEl +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require1.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require1.pem new file mode 100644 index 00000000..7087404b --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require1.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBujCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQEwCgYIKoZIzj0EAwIDSQAwRgIhAIAwvhHB +GQDN5YXlidd+n3OT/SqoeXfp7RiEonBnCkW4AiEA+iFc47EOBchHb+Gy0gg8F9Po +RnlpoulWDfbDwx9r4lc= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require2.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require2.pem new file mode 100644 index 00000000..350f4191 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require2.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuTCCAV+gAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgZMwgZAwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMCsGA1UdIAQkMCIwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMAwGA1UdJAQFMAOAAQIwCgYIKoZIzj0EAwIDSAAwRQIgOpliSKKA ++wy/auQnKKl+wwtn/hGw6eZXgIOtFgDmyMYCIQC84zoJL87AE64gsrdX4XSHq6lb +WhZQp9ZnDaNu88SQLQ== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_duplicate.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_duplicate.pem new file mode 100644 index 00000000..733087af --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByjCCAXCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjgaQwgaEwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJDS9/4O7qhr +CIRhwsXrPVBagG2uMDwGA1UdIAQ1MDMwDwYNKoZIhvcSBAGEtwkCATAPBg0qhkiG +9xIEAYS3CQICMA8GDSqGSIb3EgQBhLcJAgIwDAYDVR0kBAUwA4ABADAKBggqhkjO +PQQDAgNIADBFAiA2GxzMRYYo7NNq8u/ZvffXkCj/phqXQ8I64tEDd0X8pgIhAOJJ +e+dzzf4vbWfMlYkOQ4kf6ei5Zf+J2PL6VrqVrHQa +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_no_policies.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_no_policies.pem new file mode 100644 index 00000000..1e81e0c1 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_intermediate_require_no_policies.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBizCCATCgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE +AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia +jQ6Dg7CTpVZVVH+bguT7JTCjZTBjMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE +YcLF6z1QWoBtrjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDJYPgf +50fFDVho5TFeqkNVONx0ArVNgULPB27yPDHLrwIhAN+eua6oM4Q/O0jUESQ4VAKt +ts7ZCquTZbvgRgyqtjuT +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf.pem new file mode 100644 index 00000000..fb70306c --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBpzCCAU2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo34wfDAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wKwYDVR0gBCQwIjAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQB +hLcJAgIwCgYIKoZIzj0EAwIDSAAwRQIgBEOriD1N3/cqoAofxEtf73M7Wi4UfjFK +jiU9nQhwnnoCIQD1v/XDp2BkWNHxNq7TaPnil3xXTvMX97yUbkUg8IRo0w== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_any.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_any.pem new file mode 100644 index 00000000..d2c1b9e9 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_any.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjTCCATOgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2QwYjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wEQYDVR0gBAowCDAGBgRVHSAAMAoGCCqGSM49BAMCA0gAMEUCIQC4 +UwAf1R4HefSzyO8lyQ3fmMjkptVEhFBee0a7N12IvwIgJMYZgQ52VTbqXyXqraJ8 +V+y+o7eHds7NewqnyuLbc78= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_duplicate.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_duplicate.pem new file mode 100644 index 00000000..bdeb13cb --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_duplicate.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBsTCCAVigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE +AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY +vFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle +TS8wQT/cjw/wPgoeV6OBkDCBjTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5j +b20wPAYDVR0gBDUwMzAPBg0qhkiG9xIEAYS3CQIBMA8GDSqGSIb3EgQBhLcJAgIw +DwYNKoZIhvcSBAGEtwkCAjAKBggqhkjOPQQDAgNHADBEAiBjYDwsWcs35hU/wPqa +5gf0QUMvV/8z5LPX14fB2y4RGQIgMw0ekrt9K5UcgkvFupV/XXIjLRFQvc8URA3C +/+w+2/4= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_invalid.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_invalid.pem new file mode 100644 index 00000000..de7a5e9b --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_invalid.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBgjCCASigAwIBAgIBAzAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowGjEYMBYGA1UE +AxMPd3d3LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkSrY +vFVtkZJmvirfY0JDDYrZQrNJecPLt0ksJux2URL5nAQiQY1SERGnEaiNLpoc0dle +TS8wQT/cjw/wPgoeV6NhMF8wDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t +MA4GA1UdIAQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiAgfcDIeqmV+u5YtUe4 +aBnj13tZAJAQh6ttum1xZ+xHEgIhAJqvGX5c0/d1qYelBlm/jE3UuivijdEjVsLX +GVH+X1VA +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_none.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_none.pem new file mode 100644 index 00000000..13ad7cec --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_none.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBezCCASCgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1EwTzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wCgYIKoZIzj0EAwIDSQAwRgIhAIDFeeYJ8nmYo09OnJFpNS3A6fYO +ZliHkAqOsg193DTnAiEA3OSHLCczcvRjMG+qd/FI61u2sKU1hhHh7uHtD/YO/dA= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid1.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid1.pem new file mode 100644 index 00000000..94cd1a77 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlTCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIBMAoGCCqGSM49BAMC +A0cAMEQCIHh4Bo8l/HVJhLMWcYusPOE0arqoDrJ5E0M6nEi3nRhgAiAArK8bBohG +fZ3DmVMq/2BJtQZwRRj+50VKWuf9mBSflQ== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid2.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid2.pem new file mode 100644 index 00000000..10adf86c --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid2.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQICMAoGCCqGSM49BAMC +A0kAMEYCIQDvW7rdL6MSW/0BPNET4hEeECO6LWmZZHKCHIu6o33dsAIhAPwgm6lD +KV2hMOxkE6rBDQzlCr+zAkQrxSzQZqJp5p+W +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid3.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid3.pem new file mode 100644 index 00000000..e5c10315 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid3.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIDMAoGCCqGSM49BAMC +A0kAMEYCIQDBPnPpRsOH20ncg8TKUdlONfbO62WafQj9SKgyi/nGBQIhAMhT8J7f +fTEou6jlAilaIQwlAgZzVKRqgghIHezFY86T +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid4.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid4.pem new file mode 100644 index 00000000..7dd7a547 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid4.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIEMAoGCCqGSM49BAMC +A0kAMEYCIQD2gnpCTMxUalCtEV52eXzqeJgsKMYvEpJTuU/VqH5KwQIhAPEavAkt +cSJsgMgJcJnbBzAdSrbOgHXF2etDHmFbg0hz +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid5.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid5.pem new file mode 100644 index 00000000..2a9aee73 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_oid5.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo20wazAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh +bXBsZS5jb20wGgYDVR0gBBMwETAPBg0qhkiG9xIEAYS3CQIFMAoGCCqGSM49BAMC +A0kAMEYCIQDDFVjhlQ1Wu0KITcRX8kELpVDeYSKSlvEbZc3rn1QjkQIhAMPthqBi +I0acz8DPQcdFmHXV0xR2xyC1yuen0gES5WLR +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require.pem new file mode 100644 index 00000000..169b8444 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l +eGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS +BAGEtwkCAjAMBgNVHSQEBTADgAEAMAoGCCqGSM49BAMCA0kAMEYCIQDrNQPi/mdK +l7Nd/YmMXWYTHJBWWin1zA64Ohkd7z4jGgIhAJpw/umk5MxS1MwSi+YTkkcSQKpl +YROQH6+T53DauoW6 +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require1.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require1.pem new file mode 100644 index 00000000..261ef954 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_leaf_require1.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBuDCCAV2gAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg +SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa +MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR +qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo4GNMIGKMA4GA1UdDwEB/wQEAwICBDATBgNV +HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5l +eGFtcGxlLmNvbTArBgNVHSAEJDAiMA8GDSqGSIb3EgQBhLcJAgEwDwYNKoZIhvcS +BAGEtwkCAjAMBgNVHSQEBTADgAEBMAoGCCqGSM49BAMCA0kAMEYCIQCtXENGJrKv +IOeLHO/3Nu/SMRXc69Vb3q+4b/uHBFbuqwIhAK22Wfh/ZIHKu3FwbjL+sN0Z39pf +Dsak6fp1y4tqNuvK +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_root.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_root.pem new file mode 100644 index 00000000..595f8a13 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_root.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCCARqgAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg +Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowFjEUMBIGA1UE +AxMLUG9saWN5IFJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQmdqXYl1Gv +Y7y3jcTTK6MVXIQr44TqChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAP +EPSJwPndjolto1cwVTAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU0GnnoB+yeN63WMthnh6Uh1HH +dRIwCgYIKoZIzj0EAwIDSQAwRgIhAKVxVAaJnmvt+q4SqegGS23QSzKPM9Yakw9e +bOUU9+52AiEAjXPRBdd90YDey4VFu4f/78yVe0cxMK30lll7lLl7TTA= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_root2.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_root2.pem new file mode 100644 index 00000000..1350035f --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_root2.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBeDCCAR6gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg +Um9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAYMRYwFAYD +VQQDEw1Qb2xpY3kgUm9vdCAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJnal +2JdRr2O8t43E0yujFVyEK+OE6goUWCOiHlfbSAeoyLDmPkKJdW5PMf+wORRjp1Fh +VSxADxD0icD53Y6JbaNXMFUwDgYDVR0PAQH/BAQDAgIEMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNBp56Afsnjet1jLYZ4e +lIdRx3USMAoGCCqGSM49BAMCA0gAMEUCIQDm9rw9ODVtJUPBn2lWoK8s7ElbyY4/ +Gc2thHR50UUzbgIgKRenEDhKiBR6cGC77RaIiaaafW8b7HMd7obuZdDU/58= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/policy_root_cross_inhibit_mapping.pem b/third_party/boringssl/kit/src/crypto/x509/test/policy_root_cross_inhibit_mapping.pem new file mode 100644 index 00000000..9273a530 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/policy_root_cross_inhibit_mapping.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBljCCAT2gAwIBAgIBATAKBggqhkjOPQQDAjAYMRYwFAYDVQQDEw1Qb2xpY3kg +Um9vdCAyMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAWMRQwEgYD +VQQDEwtQb2xpY3kgUm9vdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCZ2pdiX +Ua9jvLeNxNMroxVchCvjhOoKFFgjoh5X20gHqMiw5j5CiXVuTzH/sDkUY6dRYVUs +QA8Q9InA+d2OiW2jeDB2MA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEF +BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTQaeegH7J43rdYy2GeHpSH +Ucd1EjARBgNVHSAECjAIMAYGBFUdIAAwDAYDVR0kBAUwA4EBADAKBggqhkjOPQQD +AgNHADBEAiBzR3JGEf9PITYuiXTx+vx9gXji5idGsVog9wRUbY98wwIgVVeYNQQb +x+RN2wYp3kmm8iswUOrqiI6J4PSzT8CYP8Q= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1.pem new file mode 100644 index 00000000..1ab90d44 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpTCCAY2gAwIBAgIBADANBgkqhkiG9w0BAQowADAUMRIwEAYDVQQDDAlCb3Jp +bmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAG +A1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +ugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkW +f6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQS +jHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy +8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50 ++UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk +7ZE1QJQQ1L4iKmPeQistuQIDAQABMA0GCSqGSIb3DQEBCjAAA4IBAQAQvYDcDDNx +QPctGNiZTH9N2I2wdVXHmsybRW7tXWVYm+yE8IzfVUUBkCL5WvbLxlujMAbQpHp8 +EnKECVsNAklHAAQ6KFDTngyDAjdyGiNKKMm37UW/I7BkdFZE+jBYKoVU5xeLSPm1 +jNKQWqjGnaZ+wV7Fl8Zy+QOr7Z35zrDNbCF/EkzoE6+i/bbqXIgu5x14rj9c4JAs +aKPpTtpDI1zt9BfGMPsBxsxeckqnG8OlNc6YI8svAK849naTAPx93jDWmDBYqfsb +MeZOo9+AfUP7pjoDZHsQCmPdmlDgAtMvi8K1oFbw4BBTu+CaCzhNS5xEbITef09i +tjiySH0Q5r01 +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_explicit.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_explicit.pem new file mode 100644 index 00000000..7847916e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_explicit.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAbmgAwIBAgIBADA5BgkqhkiG9w0BAQowLKALMAkGBSsOAwIaBQChGDAW +BgkqhkiG9w0BAQgwCQYFKw4DAhoFAKIDAgEUMBQxEjAQBgNVBAMMCUJvcmluZ1NT +TDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1OTU5WjAUMRIwEAYDVQQD +DAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6C9qE +GRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94Z +nsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgP +iEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gU +R69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq +32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVA +lBDUviIqY95CKy25AgMBAAEwOQYJKoZIhvcNAQEKMCygCzAJBgUrDgMCGgUAoRgw +FgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiAwIBFAOCAQEATo0Z3YqPt4fzBXz22vyH +7Ckr1cicKTeE3lV8LYHII4easVkueN7HrfrpTPu04kn4Y8pjprh0gRj9vcf6i6Sj +khPnfmXTTbeFxHs763BQVAOoutgteyUhBZ5UjqaXnnF7PYhyG/0ykxWryvius+dz +ujhW9T0aPo95GWITtj1NHzGmCjQYqUSrfkJynC8c/juTo3MLWrMnirDsAYizTg4W +CWBfeMKRfAH6aOybSBNZh7/KU+ZiFPKJi+NKPPaZNZa0l1JZ46LL1NWVq6bybZH8 +ncNZpooQKTfCaK221pbqxx4YIJT0NoICU8291LSNLz8/5uBkjUo744cF4tuNFZ4k +sg== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_mgf1_syntax_error.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_mgf1_syntax_error.pem new file mode 100644 index 00000000..3ba32f18 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha1_mgf1_syntax_error.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxzCCAZ6gAwIBAgIBADAeBgkqhkiG9w0BAQowEaEPMA0GCSqGSIb3DQEBCDAA +MBQxEjAQBgNVBAMMCUJvcmluZ1NTTDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkx +MjMxMjM1OTU5WjAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6C9qEGRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPh +Cm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARI +hIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyK +j32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRT +zNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEm +gyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIqY95CKy25AgMBAAEwHgYJKoZIhvcN +AQEKMBGhDzANBgkqhkiG9w0BAQgwAAOCAQEANdpvRLqZLsYfruBHXjviZaKoHeoQ +1ixqeSLzcP0KzWRT3H3tX46KuYABaMurK0yPMDfW6oLCfJa3fUFt0FYJYnf/w7mp +MsmOf+7aaY8oYqI6wRwtAB0JQcC2tKsio+UEiI6hZq2ghhGa5c+YLXhN4Dt+/cK9 +UkisKL4O61jKulfaErOsUSaYTo9/PJpPcUhE/zVtsfAGJH0ojSCrSpEYv4TNO9Qm +WOJ4hMreEOLVxw4xC65wRmOWl4JpGxle1mNzjsL4kOcDwsnepEOcpAqJronQ+HnI +1RCR04oEnOOWYAtFxuWzTds3BjszGPRSu3srGZpaI1j/kB+a3g/7hXufOA== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha224.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha224.pem new file mode 100644 index 00000000..422615d5 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha224.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCBAUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCBAUAogMCARwwFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCBAUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCBAUAogMCARwDggEB +AHttVo+XfLdlRXHc59yGAr7wQgqIbWOD6QSo4Tb4XbAh4nc9MQhccfT4YOMyHa9I +i1VyE9e2dna8gt9VfIyCeTnNS1RYbKagaUzo2dt/G0lQjfXRVkB1yobJEaAzZ8kg +cbknjlrlMEtHW+ET2vTHKvOjHjHXy3GYt8ynSldnotikqVobW5Kd/nYR7s9SR1Yz +VhweDRcWeb3IYSAx953t1voky/7pTltcyb5FfJLIPmj2AsoFSRnXrj1Sx0K+S68m +E0TdKwOTr2QN9nmHrIbCIeiAVeBlIOY6jH8TjobwFV2Y3RlqC+8S+Vgje/Hg/jrV +Q9fS9+RIVSOFZiOgW/1hjAA= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256.pem new file mode 100644 index 00000000..fc8ce18e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASADggEB +ALVhRTv78XF2RjMusWAuTknDWkju6uvtq+iTpwCWaJO2QA2L3spEiUw52PsW9gQW +AIOttLlgQFPD3dt3OL0FBK5y79Rh/h/mrOpwbVoMOHSsgikVZhbQ0D30Y8LQYMTD +cxDYgPbnI4Q1VatdcCR8aavSDfV4JGPpJPkz8QX6HaFAoCUAz5UhiiS3MT8IzucO +nNOV7AH9yfWDfvCWDGyuIYphjFZ761VjZFFIGJuXZ9uDXDDjNxlLwO7sci/pwO89 +OiRM40RxkS9vl8MjIsFSMGXOR+mf+FNtQ2vF1ZqCVxPWFuHHwmXycqrLuY3fOboF +tF5Q3O1V7sh5Bs47h29KbQU= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_explicit_trailer.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_explicit_trailer.pem new file mode 100644 index 00000000..52820b76 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_explicit_trailer.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFzCCAcagAwIBAgIBADBGBgkqhkiG9w0BAQowOaAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASCjAwIBATAUMRIwEAYD +VQQDDAlCb3JpbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1 +OVowFDESMBAGA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWs +sZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXC +zepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Ak +y+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs +2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmE +T19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABMEYGCSqGSIb3DQEBCjA5oA8w +DQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIB +IKMDAgEBA4IBAQA6p/W2ZA06aYzRXL1v/VnU11udk5+UIbGAuhSVv9a+zJ4/79UX +Xk4/otg74fq/Ayy3hPm9lcOTGbXYHSgY4eFR8J1VS/P2ZPRCyypXwLSYg+Yt5Fdc +SaA2JVF2jrgMbIAzBsyz4CCOzajcF/he8+NmH7pDZhLGv4pIWaFqAPrGntIpPwVW +Qib62z9qzeexXIm+1Jp3nh21sXLbWdBM5tt5NNqST+cgzzrRnPtwQTbdcKk9i4Jh +3/BairkWclVHxibtNPoLvhU91tJw61rES29x3vG//7WwEoT2aLCkp9/ZHrM5ukpe +RxWXU+JZXiO59WWDCdK0YAuoteozepn4Cwei +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_sha384.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_sha384.pem new file mode 100644 index 00000000..dd3b4e93 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_sha384.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCASAwFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCASADggEB +AFMuNrMzLKfCvjDw35e5aoOPsTHKmkreUl4yHjUxX3i0heSkvy3FFcXhGjOscySF +hBoAZU1DJaIHGzq2/k9Z3pk+NFhLg6tlHvLgcySHl4kR4sqTceJeOgy4RHJU04Gv +wFAfRXx8QTJr1d00EPBoSnj7afDtvcRkzDSsgQ+YiQ9zjvt+uzuhZ25CUw8KY+Xy +CZqQYE5yIMMRoKZExPcXuWTD8Ho5pVxjeLv2+nEO73NaAP0FwisCuY98ng0ffTgG +5biORaDLzoTQv0QXtHS5TRUd6ycQ7nW28M4U1ZP9s9gj1zl+emvmi1UjNs3bcRW3 +Jk0lRwKo8awDUhfWJ/YPIns= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_syntax_error.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_syntax_error.pem new file mode 100644 index 00000000..5d77bf27 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_mgf1_syntax_error.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAbSgAwIBAgIBADA0BgkqhkiG9w0BAQowJ6APMA0GCWCGSAFlAwQCAQUA +oQ8wDQYJKoZIhvcNAQEIMACiAwIBIDAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwIhgP +MDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAGA1UEAwwJQm9y +aW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAugvahBkSAUF1 +fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkWf6PeGZ7F5AX1 +PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQSjHD4D4hKtgdM +gVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy8U+YFEevb/V0 +lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50+UMgat9ocewI +2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk7ZE1QJQQ1L4i +KmPeQistuQIDAQABMDQGCSqGSIb3DQEBCjAnoA8wDQYJYIZIAWUDBAIBBQChDzAN +BgkqhkiG9w0BAQgwAKIDAgEgA4IBAQAJ0RuKq+OgFlcm2EMk+VXH8hSo87N3wcyK +9SzLwONh2uVYR3W1ig+/EwqK0M9w5UwvSVNdFa3m2qVXApprUm7eCJ2c7rWiBkQy +sVCHwWVCseItZ8ipJHHz0uC5k3EFBSVbsbRdTJ8FPbRDBXXn2iSz6OzUJVZ5PfV1 +XRC81Aoi8DbhFwNga7/mJ80Ru4UGEePT6SsyUU5sgZ0w37r+5VPQgL4oOMO2NKz+ +O060CbcDcOXrCm1x0BXIOc7gZEao5mriJTFQTq4PsuMnJ9a7aU+PYPfTxptr/VxB +yJJSi0sjTpqmWKStBjeZlEYq57nWZLmueA9xf8T1Ah6WRDRFo8m1 +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_omit_nulls.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_omit_nulls.pem new file mode 100644 index 00000000..c5b025ba --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_omit_nulls.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAb2gAwIBAgIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa +MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIDAUMRIwEAYDVQQDDAlCb3Jp +bmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowFDESMBAG +A1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +ugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBcHprZ5BkW +f6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepBrhtp5UQS +jHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aNlcMj6MYy +8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65LUduTL50 ++UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19WJH4PrFwk +7ZE1QJQQ1L4iKmPeQistuQIDAQABMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUD +BAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgA4IBAQAss/sOR0J5 +rAmctg1qnUYeUKr3RN2MTAb58ZsbE9Gvjr4lgdRo4ADIwqfKYcEe3Xms0WO8gAle +efbzrcqM1wZ6wjdcZEI9xz2L5moX0lD40Jd18OFe4wrmt7eMCaz+gTdHx+5uQy53 +4H+Vw6IUeO9m1K1wqDkwsiPWv22FqKghD07wKiNR7bkPnQDERRRN6UliCFfMEXOx +h9IbYJQUIVvBFqkI9C/lKbrmxdS7fv3wFnu61knkh7JNIXXWNdYHHRDqNDZOhakn +0wf3qY359CofKk+9kg/9cj1lP8HwgATxL69pBmSvM7O6ybDRhp4+/oySQCbcOIfs +IOo8AoyPo4u2 +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt31.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt31.pem new file mode 100644 index 00000000..964df209 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt31.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCAR8wFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCAR8DggEB +ACRCt8NtcKkDg86ub1PiWSws4b/5v9ujPbatTrocCOXnob3Z4dnHKpjeUC0et/ex +s4hlluZ9WHb+WgR5LP7I1eIE5C1RIL5aVLguSBi8/qQICNVgeMvZSgv/mDJ0eiv2 +xztcYlDwANPIh2RDpVyD6qUphvH8W6vrd6mo3aYgegigaDr/8d01MZh5s4120iWn ++8XKXNep8YqLhYemn3WeXtvK4vEEdFln6WeRRlGKevX9LqOegshs8HgKjjYRH++I +c5HtwRZFkkMnXOV0XyG5zPrsx0qDcJCGHrC20bM+ZZz60QOtb1BSMIS5KjMy5OPQ +bueM0YwX72tPKox+3lJgXAk= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt_overflow.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt_overflow.pem new file mode 100644 index 00000000..85f5f3a9 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_salt_overflow.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGzCCAcigAwIBAgIBADBIBgkqhkiG9w0BAQowO6APMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogoCCEAAAAAAAAAgMBQxEjAQ +BgNVBAMMCUJvcmluZ1NTTDAiGA8wMDAwMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1 +OTU5WjAUMRIwEAYDVQQDDAlCb3JpbmdTU0wwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6C9qEGRIBQXV8Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4 +RayxkFwemtnkGRZ/o94ZnsXkBfU/IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGi +JcLN6kGuG2nlRBKMcPgPiEq2B0yBXFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpn +UCTL5o2VwyPoxjLxT5gUR69v9XSVFj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh +4izZHrktR25MvnT5QyBq32hx7AjZ2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6C +eYRPX1Ykfg+sXCTtkTVAlBDUviIqY95CKy25AgMBAAEwSAYJKoZIhvcNAQEKMDug +DzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIK +AghAAAAAAAAAIAOCAQEAn7ufGUhwZUfP13AEXFZGo7tpWYKbiDpVnHTtj/21/SWd +TXP1LJWIJuo8pGs/ZsXI+XoXJMk01G1wVPPUny/D7T9WXLW191UFzIGO0bJZIfv2 +M9YbRkTsCiAYUuyFUlwwSLMqMXrZjRXlgulv3DjWrDHrAqfst847Ety24P1uYG7C +m4JV8Sa0SIKRntd00YYmk6oUZNgEzUps7moLsOEox3U2s6wTipl/++9H5CI5mQTS +fdGMRzEsuJRfXkgMccEfDw2wvNfmNzILGDsvxjCilkEisuMPxlRptSk5agYFujAW +D3QjJGCgGlSXhN3JuH9S2/0N5gRQpN/98beTTXpxvg== +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_unknown_mgf.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_unknown_mgf.pem new file mode 100644 index 00000000..e2966526 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_unknown_mgf.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAcSgAwIBAgIBADBEBgkqhkiG9w0BAQowN6APMA0GCWCGSAFlAwQCAQUA +oR8wHQYMKoZIhvcSBAGEtwkAMA0GCWCGSAFlAwQCAQUAogMCASAwFDESMBAGA1UE +AwwJQm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTla +MBQxEjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQ +XB6a2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3q +Qa4baeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvm +jZXDI+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNke +uS1Hbky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9f +ViR+D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBEBgkqhkiG9w0BAQowN6APMA0G +CWCGSAFlAwQCAQUAoR8wHQYMKoZIhvcSBAGEtwkAMA0GCWCGSAFlAwQCAQUAogMC +ASADggEBACdP7ToiiM+6TqeAbKRqsPuFX9Q0qJtjX8mGVyzOEy402hEhglMeL9il +FFFKCgo/wux4VIbw7BVLFDfYPcj8E7snj+J0mITIFt5oCwXG+MrJUnfklBEEyelF +kVyr1ZVIwsk/lWSaOcQocbx8/szRRhwwVTT7BySnMV4e/y7Z9beye6tl7lg4373K +E4akVubalnkoTHP5fZ6f0AfOXJEnLw2Mn0zjwrZmasMyXxLH8ApUVruPBQHY7IQB +sMAURzkRtcCyzhQniJFcu7oMmkj+v8FVG02792DOWP+Y/yC0ccmHcvDbdzJW5SDm +rBvNkmnPt6sYs7/RLRaVky7cRMAQrFs= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_wrong_trailer.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_wrong_trailer.pem new file mode 100644 index 00000000..dda85016 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha256_wrong_trailer.pem @@ -0,0 +1,22 @@ +This certificate has a trailerField of 2, but the signature was still +generated with the standard 0xbc suffix. + +-----BEGIN CERTIFICATE----- +MIIDFzCCAcagAwIBAgIBADBGBgkqhkiG9w0BAQowOaAPMA0GCWCGSAFlAwQCAQUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASCjAwIBAjAUMRIwEAYD +VQQDDAlCb3JpbmdTU0wwIhgPMDAwMDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1 +OVowFDESMBAGA1UEAwwJQm9yaW5nU1NMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWs +sZBcHprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXC +zepBrhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Ak +y+aNlcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs +2R65LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmE +T19WJH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABMEYGCSqGSIb3DQEBCjA5oA8w +DQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIB +IKMDAgECA4IBAQCVtDpbDRnbn7UQd8sPq+XSHk2nwvlhwSKZ0XZ0vwBGkNuhO/SY +BhVUez+uGxXnJE+MkVAAh3NOdEQV6apEX5tymCyB0vqwLQB86gANOt82kF/tOW4M +Sv5f6L8GJbYtpTd/cyAMEs7U/X9O5W1G9sLINWeukUYHPVKjj/tE3NfLCE8SWlw4 +SCnbuhs5WXnEgUP/9JgL8xyI6bxn9E2OUvqD+U24k0PbtAdk09697gUYUDQlmxi6 +MRoQYKTezNJt4DXRhqUlokWiF5D42MaMz5WXtLQaBfbqQB6n1Ln+hTaGwWP6xNSm +Mip0TYOwAQdcTvr8UoQUJR/90SX+S4m6cu4d +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha384.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha384.pem new file mode 100644 index 00000000..faf59b88 --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha384.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAgUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATAwFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAgUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATADggEB +AASUWBIEjb0TkXJKhj3RNRRe0D+KWFpyAn/kdBgDce/LEQVywj8IeS+s9z9TcGEK +iKr8tPIsNUM1agj3gd1zWuM5rbUABQyGzeWcfjmhmhK5mnCSOu/OD+DJjWqyHpQq +/Qf2djrpXJXKVNoSBzci4KUpFIfKMT4KjnUKY9L8lxfl9zaPeIaFeXgtyhHYnpjX +vyomoLaL3cXeeKIffgPa9s9QZGx2fKOnFmcS3eKL9pIcj4Z6K8+Nchg6Z2qYKWtM +hH1ZFlNDC3VOPgNkHoBrU6gE5fQv6lO64egL9pM0bpaOi7drhHKjkw2URi4C9KGK +P9GfRmqV9Y9UlJsLSGIghxs= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/test/pss_sha512.pem b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha512.pem new file mode 100644 index 00000000..1beb991e --- /dev/null +++ b/third_party/boringssl/kit/src/crypto/x509/test/pss_sha512.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAcGgAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUA +oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwFDESMBAGA1UEAwwJ +Qm9yaW5nU1NMMCIYDzAwMDAwMTAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMBQx +EjAQBgNVBAMMCUJvcmluZ1NTTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALoL2oQZEgFBdXwuPb29W75T63JfNJKKdYi6YrmKM+EKbcMue/hFrLGQXB6a +2eQZFn+j3hmexeQF9T8iWxh2S6rzAr1Yj+qXeDBaMf4oBEiEhBxIsaIlws3qQa4b +aeVEEoxw+A+ISrYHTIFcV/i0bcIFt5p7v7wbu686a/w0vIqPfad5amdQJMvmjZXD +I+jGMvFPmBRHr2/1dJUWPaKsJluwR514pJv74urIyEt+dFPM2/5kc2HiLNkeuS1H +bky+dPlDIGrfaHHsCNnb/GjvQ6YfvDXRrYPCxWMk0x3FMSaDK9T0zoJ5hE9fViR+ +D6xcJO2RNUCUENS+Iipj3kIrLbkCAwEAATBBBgkqhkiG9w0BAQowNKAPMA0GCWCG +SAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEB +ADwQHPC6MMvgBBfgYHRvcdQqfzPb3I9HJa+Y01BAIAeICadmyB389cjhv9X1mFi9 +xJOhsuek71D4YrOghExMbGXIAlalAq/rQHTzXV6cqiSrbUmmvsLmlilOeODIjuUC +z3Ldc5LvwU8nima46jP/ryMYaIjCpbNsH/MzAbYO/CNm8osjeJoKhGyozkj9tr2T +JaSFe5icta2WHfjfLP7wSkIf3NdfXNkBIBKMdHCuiEgeUeSColpgAFfngFKIJ3EG +EbgptjPoePJ0T6VOdwzSX+QhGLabaOiX0ptrhAwuCNHVAKuf5wCWKvl6mYgBaDfB +YFmL46BAX2ghB+WM/FSizPs= +-----END CERTIFICATE----- diff --git a/third_party/boringssl/kit/src/crypto/x509/x509.c b/third_party/boringssl/kit/src/crypto/x509/x509.c index 9049a35d..f6b8fabd 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509.c @@ -61,8 +61,8 @@ #include -/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define - * it to avoid downstream churn. */ +// |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define +// it to avoid downstream churn. OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM) int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { @@ -73,8 +73,7 @@ int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { s = sig->data; for (i = 0; i < n; i++) { if ((i % 18) == 0) { - if (BIO_write(bp, "\n", 1) <= 0 || - BIO_indent(bp, indent, indent) <= 0) { + if (BIO_write(bp, "\n", 1) <= 0 || BIO_indent(bp, indent, indent) <= 0) { return 0; } } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_att.c b/third_party/boringssl/kit/src/crypto/x509/x509_att.c index e2a5121a..062168ea 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_att.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_att.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_att.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,302 +56,169 @@ #include #include -#include #include -#include #include #include "../asn1/internal.h" #include "internal.h" -int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) -{ - return sk_X509_ATTRIBUTE_num(x); -} - -int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, - int lastpos) -{ - const ASN1_OBJECT *obj = OBJ_nid2obj(nid); - if (obj == NULL) { - return -1; - } - return X509at_get_attr_by_OBJ(x, obj, lastpos); -} - -int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - const ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_ATTRIBUTE *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_ATTRIBUTE_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_ATTRIBUTE_value(sk, lastpos); - if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); - } - return (-1); -} - -X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) -{ - if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) - return NULL; - else - return sk_X509_ATTRIBUTE_value(x, loc); -} - -X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) -{ - X509_ATTRIBUTE *ret; - - if (x == NULL || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) - return (NULL); - ret = sk_X509_ATTRIBUTE_delete(x, loc); - return (ret); -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, - X509_ATTRIBUTE *attr) -{ - X509_ATTRIBUTE *new_attr = NULL; - STACK_OF(X509_ATTRIBUTE) *sk = NULL; - - if (x == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - goto err2; - } - - if (*x == NULL) { - if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) - goto err; - } else - sk = *x; - - if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) - goto err2; - if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) - goto err; - if (*x == NULL) - *x = sk; - return (sk); - err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - err2: - if (new_attr != NULL) - X509_ATTRIBUTE_free(new_attr); - if (sk != NULL) - sk_X509_ATTRIBUTE_free(sk); - return (NULL); -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) - **x, const ASN1_OBJECT *obj, - int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) - **x, int nid, int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) - **x, const char *attrname, - int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int attrtype, const void *data, - int len) -{ - const ASN1_OBJECT *obj; + int len) { + const ASN1_OBJECT *obj; - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); - return (NULL); - } - return X509_ATTRIBUTE_create_by_OBJ(attr, obj, attrtype, data, len); + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + return X509_ATTRIBUTE_create_by_OBJ(attr, obj, attrtype, data, len); } X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj, int attrtype, const void *data, - int len) -{ - X509_ATTRIBUTE *ret; + int len) { + X509_ATTRIBUTE *ret; - if ((attr == NULL) || (*attr == NULL)) { - if ((ret = X509_ATTRIBUTE_new()) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return (NULL); - } - } else - ret = *attr; + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + return NULL; + } + } else { + ret = *attr; + } - if (!X509_ATTRIBUTE_set1_object(ret, obj)) - goto err; - if (!X509_ATTRIBUTE_set1_data(ret, attrtype, data, len)) - goto err; + if (!X509_ATTRIBUTE_set1_object(ret, obj)) { + goto err; + } + if (!X509_ATTRIBUTE_set1_data(ret, attrtype, data, len)) { + goto err; + } - if ((attr != NULL) && (*attr == NULL)) - *attr = ret; - return (ret); - err: - if ((attr == NULL) || (ret != *attr)) - X509_ATTRIBUTE_free(ret); - return (NULL); + if ((attr != NULL) && (*attr == NULL)) { + *attr = ret; + } + return ret; +err: + if ((attr == NULL) || (ret != *attr)) { + X509_ATTRIBUTE_free(ret); + } + return NULL; } X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *attrname, int type, const unsigned char *bytes, - int len) -{ - ASN1_OBJECT *obj; - X509_ATTRIBUTE *nattr; + int len) { + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; - obj = OBJ_txt2obj(attrname, 0); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", attrname); - return (NULL); - } - nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nattr; + obj = OBJ_txt2obj(attrname, 0); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", attrname); + return NULL; + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; } -int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) -{ - if ((attr == NULL) || (obj == NULL)) - return (0); - ASN1_OBJECT_free(attr->object); - attr->object = OBJ_dup(obj); - return attr->object != NULL; +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) { + if ((attr == NULL) || (obj == NULL)) { + return 0; + } + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return attr->object != NULL; } int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, - const void *data, int len) -{ - ASN1_TYPE *ttmp = NULL; - ASN1_STRING *stmp = NULL; - int atype = 0; - if (!attr) - return 0; - if (attrtype & MBSTRING_FLAG) { - stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, - OBJ_obj2nid(attr->object)); - if (!stmp) { - OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); - return 0; - } - atype = stmp->type; - } else if (len != -1) { - if (!(stmp = ASN1_STRING_type_new(attrtype))) - goto err; - if (!ASN1_STRING_set(stmp, data, len)) - goto err; - atype = attrtype; - } - /* - * This is a bit naughty because the attribute should really have at - * least one value but some types use and zero length SET and require - * this. - */ - if (attrtype == 0) { - ASN1_STRING_free(stmp); - return 1; - } - if (!(ttmp = ASN1_TYPE_new())) - goto err; - if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { - if (!ASN1_TYPE_set1(ttmp, attrtype, data)) - goto err; - } else { - ASN1_TYPE_set(ttmp, atype, stmp); - stmp = NULL; - } - if (!sk_ASN1_TYPE_push(attr->set, ttmp)) - goto err; - return 1; - err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ASN1_TYPE_free(ttmp); - ASN1_STRING_free(stmp); + const void *data, int len) { + ASN1_TYPE *ttmp = NULL; + ASN1_STRING *stmp = NULL; + int atype = 0; + if (!attr) { return 0; -} - -int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) -{ - return sk_ASN1_TYPE_num(attr->set); -} - -ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) -{ - if (attr == NULL) - return (NULL); - return (attr->object); -} - -void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, - int attrtype, void *unused) -{ - ASN1_TYPE *ttmp; - ttmp = X509_ATTRIBUTE_get0_type(attr, idx); - if (!ttmp) - return NULL; - if (attrtype != ASN1_TYPE_get(ttmp)) { - OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE); - return NULL; + } + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + return 0; } - return (void *)asn1_type_value_as_pointer(ttmp); + atype = stmp->type; + } else if (len != -1) { + if (!(stmp = ASN1_STRING_type_new(attrtype))) { + goto err; + } + if (!ASN1_STRING_set(stmp, data, len)) { + goto err; + } + atype = attrtype; + } + // This is a bit naughty because the attribute should really have at + // least one value but some types use and zero length SET and require + // this. + if (attrtype == 0) { + ASN1_STRING_free(stmp); + return 1; + } + if (!(ttmp = ASN1_TYPE_new())) { + goto err; + } + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) { + goto err; + } + } else { + ASN1_TYPE_set(ttmp, atype, stmp); + stmp = NULL; + } + if (!sk_ASN1_TYPE_push(attr->set, ttmp)) { + goto err; + } + return 1; +err: + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); + return 0; } -ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) -{ - if (attr == NULL) - return NULL; - if (idx >= X509_ATTRIBUTE_count(attr)) - return NULL; - return sk_ASN1_TYPE_value(attr->set, idx); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) { + return (int)sk_ASN1_TYPE_num(attr->set); +} + +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) { + if (attr == NULL) { + return NULL; + } + return attr->object; +} + +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int attrtype, + void *unused) { + ASN1_TYPE *ttmp; + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) { + return NULL; + } + if (attrtype != ASN1_TYPE_get(ttmp)) { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE); + return NULL; + } + return (void *)asn1_type_value_as_pointer(ttmp); +} + +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) { + if (attr == NULL) { + return NULL; + } + if (idx >= X509_ATTRIBUTE_count(attr)) { + return NULL; + } + return sk_ASN1_TYPE_value(attr->set, idx); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_cmp.c b/third_party/boringssl/kit/src/crypto/x509/x509_cmp.c index 5811f440..b696b949 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_cmp.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_cmp.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_cmp.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,391 +70,226 @@ #include "internal.h" -int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) -{ - int i; - X509_CINF *ai, *bi; - - ai = a->cert_info; - bi = b->cert_info; - i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); - if (i) - return (i); - return (X509_NAME_cmp(ai->issuer, bi->issuer)); +int X509_issuer_name_cmp(const X509 *a, const X509 *b) { + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); } -int X509_issuer_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +int X509_subject_name_cmp(const X509 *a, const X509 *b) { + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); } -int X509_subject_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) { + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); } -int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) -{ - return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { + return OPENSSL_memcmp(a->crl_hash, b->crl_hash, SHA256_DIGEST_LENGTH); } -int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) -{ - return OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, 20); +X509_NAME *X509_get_issuer_name(const X509 *a) { + return a->cert_info->issuer; } -X509_NAME *X509_get_issuer_name(const X509 *a) -{ - return (a->cert_info->issuer); +unsigned long X509_issuer_name_hash(X509 *x) { + return (X509_NAME_hash(x->cert_info->issuer)); } -unsigned long X509_issuer_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->issuer)); +unsigned long X509_issuer_name_hash_old(X509 *x) { + return (X509_NAME_hash_old(x->cert_info->issuer)); } -unsigned long X509_issuer_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->issuer)); +X509_NAME *X509_get_subject_name(const X509 *a) { + return a->cert_info->subject; } -X509_NAME *X509_get_subject_name(const X509 *a) -{ - return (a->cert_info->subject); +ASN1_INTEGER *X509_get_serialNumber(X509 *a) { + return a->cert_info->serialNumber; } -ASN1_INTEGER *X509_get_serialNumber(X509 *a) -{ - return (a->cert_info->serialNumber); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) { + return x509->cert_info->serialNumber; } -const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) -{ - return x509->cert_info->serialNumber; +unsigned long X509_subject_name_hash(X509 *x) { + return (X509_NAME_hash(x->cert_info->subject)); } -unsigned long X509_subject_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->subject)); +unsigned long X509_subject_name_hash_old(X509 *x) { + return (X509_NAME_hash_old(x->cert_info->subject)); } -unsigned long X509_subject_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->subject)); +// Compare two certificates: they must be identical for this to work. NB: +// Although "cmp" operations are generally prototyped to take "const" +// arguments (eg. for use in STACKs), the way X509 handling is - these +// operations may involve ensuring the hashes are up-to-date and ensuring +// certain cert information is cached. So this is the point where the +// "depth-first" constification tree has to halt with an evil cast. +int X509_cmp(const X509 *a, const X509 *b) { + // Fill in the |cert_hash| fields. + // + // TODO(davidben): This may fail, in which case the the hash will be all + // zeros. This produces a consistent comparison (failures are sticky), but + // not a good one. OpenSSL now returns -2, but this is not a consistent + // comparison and may cause misbehaving sorts by transitivity. For now, we + // retain the old OpenSSL behavior, which was to ignore the error. See + // https://crbug.com/boringssl/355. + x509v3_cache_extensions((X509 *)a); + x509v3_cache_extensions((X509 *)b); + + return OPENSSL_memcmp(a->cert_hash, b->cert_hash, SHA256_DIGEST_LENGTH); } -/* - * Compare two certificates: they must be identical for this to work. NB: - * Although "cmp" operations are generally prototyped to take "const" - * arguments (eg. for use in STACKs), the way X509 handling is - these - * operations may involve ensuring the hashes are up-to-date and ensuring - * certain cert information is cached. So this is the point where the - * "depth-first" constification tree has to halt with an evil cast. - */ -int X509_cmp(const X509 *a, const X509 *b) -{ - /* Fill in the |sha1_hash| fields. - * - * TODO(davidben): This may fail, in which case the the hash will be all - * zeros. This produces a consistent comparison (failures are sticky), but - * not a good one. OpenSSL now returns -2, but this is not a consistent - * comparison and may cause misbehaving sorts by transitivity. For now, we - * retain the old OpenSSL behavior, which was to ignore the error. See - * https://crbug.com/boringssl/355. */ - x509v3_cache_extensions((X509 *)a); - x509v3_cache_extensions((X509 *)b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { + int ret; - int rv = OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); - if (rv) - return rv; - /* Check for match against stored encoding too */ - if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) { - rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len); - if (rv) - return rv; - return OPENSSL_memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, - a->cert_info->enc.len); + // Ensure canonical encoding is present and up to date + + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) { + return -2; } - return rv; -} + } -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) -{ - int ret; - - /* Ensure canonical encoding is present and up to date */ - - if (!a->canon_enc || a->modified) { - ret = i2d_X509_NAME((X509_NAME *)a, NULL); - if (ret < 0) - return -2; + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) { + return -2; } + } - if (!b->canon_enc || b->modified) { - ret = i2d_X509_NAME((X509_NAME *)b, NULL); - if (ret < 0) - return -2; - } + ret = a->canon_enclen - b->canon_enclen; - ret = a->canon_enclen - b->canon_enclen; - - if (ret) - return ret; - - return OPENSSL_memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); - -} - -unsigned long X509_NAME_hash(X509_NAME *x) -{ - unsigned long ret = 0; - unsigned char md[SHA_DIGEST_LENGTH]; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), - NULL)) - return 0; - - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; - return (ret); -} - -/* - * I now DER encode the name and hash it. Since I cache the DER encoding, - * this is reasonably efficient. - */ - -unsigned long X509_NAME_hash_old(X509_NAME *x) -{ - EVP_MD_CTX md_ctx; - unsigned long ret = 0; - unsigned char md[16]; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - EVP_MD_CTX_init(&md_ctx); - /* EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); */ - if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) - && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) - && EVP_DigestFinal_ex(&md_ctx, md, NULL)) - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; - EVP_MD_CTX_cleanup(&md_ctx); - - return (ret); -} - -/* Search a stack of X509 for a match */ -X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial) -{ - size_t i; - X509_CINF cinf; - X509 x, *x509 = NULL; - - if (!sk) - return NULL; - - x.cert_info = &cinf; - cinf.serialNumber = serial; - cinf.issuer = name; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_issuer_and_serial_cmp(x509, &x) == 0) - return (x509); - } - return (NULL); -} - -X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) -{ - X509 *x509; - size_t i; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) - return (x509); - } - return (NULL); -} - -EVP_PKEY *X509_get_pubkey(X509 *x) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (NULL); - return (X509_PUBKEY_get(x->cert_info->key)); -} - -ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) -{ - if (!x) - return NULL; - return x->cert_info->key->public_key; -} - -int X509_check_private_key(X509 *x, const EVP_PKEY *k) -{ - EVP_PKEY *xk; - int ret; - - xk = X509_get_pubkey(x); - - if (xk) - ret = EVP_PKEY_cmp(xk, k); - else - ret = -2; - - switch (ret) { - case 1: - break; - case 0: - OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); - break; - case -2: - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); - } - if (xk) - EVP_PKEY_free(xk); - if (ret > 0) - return 1; - return 0; -} - -/* - * Check a suite B algorithm is permitted: pass in a public key and the NID - * of its signature (or 0 if no signature). The pflags is a pointer to a - * flags field which must contain the suite B verification flags. - */ - -static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) -{ - const EC_GROUP *grp = NULL; - int curve_nid; - if (pkey && pkey->type == EVP_PKEY_EC) - grp = EC_KEY_get0_group(pkey->pkey.ec); - if (!grp) - return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; - curve_nid = EC_GROUP_get_curve_name(grp); - /* Check curve is consistent with LOS */ - if (curve_nid == NID_secp384r1) { /* P-384 */ - /* - * Check signature algorithm is consistent with curve. - */ - if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) - return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; - if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) - return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - /* If we encounter P-384 we cannot use P-256 later */ - *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; - } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */ - if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) - return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; - if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) - return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - } else - return X509_V_ERR_SUITE_B_INVALID_CURVE; - - return X509_V_OK; -} - -int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, - unsigned long flags) -{ - int rv, sign_nid; - size_t i; - EVP_PKEY *pk = NULL; - unsigned long tflags; - if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) - return X509_V_OK; - tflags = flags; - /* If no EE certificate passed in must be first in chain */ - if (x == NULL) { - x = sk_X509_value(chain, 0); - i = 1; - } else - i = 0; - - if (X509_get_version(x) != X509_VERSION_3) { - rv = X509_V_ERR_SUITE_B_INVALID_VERSION; - /* Correct error depth */ - i = 0; - goto end; - } - - pk = X509_get_pubkey(x); - /* Check EE key only */ - rv = check_suite_b(pk, -1, &tflags); - if (rv != X509_V_OK) { - /* Correct error depth */ - i = 0; - goto end; - } - for (; i < sk_X509_num(chain); i++) { - sign_nid = X509_get_signature_nid(x); - x = sk_X509_value(chain, i); - if (X509_get_version(x) != X509_VERSION_3) { - rv = X509_V_ERR_SUITE_B_INVALID_VERSION; - goto end; - } - EVP_PKEY_free(pk); - pk = X509_get_pubkey(x); - rv = check_suite_b(pk, sign_nid, &tflags); - if (rv != X509_V_OK) - goto end; - } - - /* Final check: root CA signature */ - rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); - end: - if (pk) - EVP_PKEY_free(pk); - if (rv != X509_V_OK) { - /* Invalid signature or LOS errors are for previous cert */ - if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM - || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) - i--; - /* - * If we have LOS error and flags changed then we are signing P-384 - * with P-256. Use more meaninggul error. - */ - if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) - rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; - if (perror_depth) - *perror_depth = i; - } - return rv; -} - -int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) -{ - int sign_nid; - if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) - return X509_V_OK; - sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); - return check_suite_b(pk, sign_nid, &flags); -} - -/* - * Not strictly speaking an "up_ref" as a STACK doesn't have a reference - * count but it has the same effect by duping the STACK and upping the ref of - * each X509 structure. - */ -STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) -{ - STACK_OF(X509) *ret; - size_t i; - ret = sk_X509_dup(chain); - for (i = 0; i < sk_X509_num(ret); i++) { - X509_up_ref(sk_X509_value(ret, i)); - } + if (ret) { return ret; + } + + return OPENSSL_memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); +} + +unsigned long X509_NAME_hash(X509_NAME *x) { + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + // Make sure X509_NAME structure contains valid cached encoding + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL)) { + return 0; + } + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + return ret; +} + +// I now DER encode the name and hash it. Since I cache the DER encoding, +// this is reasonably efficient. + +unsigned long X509_NAME_hash_old(X509_NAME *x) { + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + // Make sure X509_NAME structure contains valid cached encoding + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + // EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) && + EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) && + EVP_DigestFinal_ex(&md_ctx, md, NULL)) { + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + } + EVP_MD_CTX_cleanup(&md_ctx); + + return ret; +} + +X509 *X509_find_by_issuer_and_serial(const STACK_OF(X509) *sk, X509_NAME *name, + const ASN1_INTEGER *serial) { + if (serial->type != V_ASN1_INTEGER && serial->type != V_ASN1_NEG_INTEGER) { + return NULL; + } + + for (size_t i = 0; i < sk_X509_num(sk); i++) { + X509 *x509 = sk_X509_value(sk, i); + if (ASN1_INTEGER_cmp(X509_get0_serialNumber(x509), serial) == 0 && + X509_NAME_cmp(X509_get_issuer_name(x509), name) == 0) { + return x509; + } + } + return NULL; +} + +X509 *X509_find_by_subject(const STACK_OF(X509) *sk, X509_NAME *name) { + for (size_t i = 0; i < sk_X509_num(sk); i++) { + X509 *x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) { + return x509; + } + } + return NULL; +} + +EVP_PKEY *X509_get_pubkey(X509 *x) { + if ((x == NULL) || (x->cert_info == NULL)) { + return NULL; + } + return (X509_PUBKEY_get(x->cert_info->key)); +} + +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) { + if (!x) { + return NULL; + } + return x->cert_info->key->public_key; +} + +int X509_check_private_key(X509 *x, const EVP_PKEY *k) { + EVP_PKEY *xk; + int ret; + + xk = X509_get_pubkey(x); + + if (xk) { + ret = EVP_PKEY_cmp(xk, k); + } else { + ret = -2; + } + + switch (ret) { + case 1: + break; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + } + if (xk) { + EVP_PKEY_free(xk); + } + if (ret > 0) { + return 1; + } + return 0; +} + +// Not strictly speaking an "up_ref" as a STACK doesn't have a reference +// count but it has the same effect by duping the STACK and upping the ref of +// each X509 structure. +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) { + STACK_OF(X509) *ret = sk_X509_dup(chain); + if (ret == NULL) { + return NULL; + } + for (size_t i = 0; i < sk_X509_num(ret); i++) { + X509_up_ref(sk_X509_value(ret, i)); + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_d2.c b/third_party/boringssl/kit/src/crypto/x509/x509_d2.c index 69ae54ed..748bd88a 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_d2.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_d2.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_d2.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -59,48 +58,53 @@ #include #ifndef OPENSSL_NO_STDIO -int X509_STORE_set_default_paths(X509_STORE *ctx) -{ - X509_LOOKUP *lookup; +int X509_STORE_set_default_paths(X509_STORE *ctx) { + X509_LOOKUP *lookup; - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) { + return 0; + } + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) { + return 0; + } + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - /* clear any errors */ - ERR_clear_error(); + // clear any errors + ERR_clear_error(); - return (1); + return 1; } int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *path) -{ - X509_LOOKUP *lookup; + const char *path) { + X509_LOOKUP *lookup; - if (file != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) - return (0); + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) { + return 0; } - if (path != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) - return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) { + return 0; } - if ((path == NULL) && (file == NULL)) - return (0); - return (1); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) { + return 0; + } + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) { + return 0; + } + } + if ((path == NULL) && (file == NULL)) { + return 0; + } + return 1; } #endif diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_def.c b/third_party/boringssl/kit/src/crypto/x509/x509_def.c index d2bc3e5c..1721da5d 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_def.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_def.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_def.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,7 +56,7 @@ #include -/* TODO(fork): cleanup */ +// TODO(fork): cleanup #if defined(OPENSSL_FUCHSIA) #define OPENSSLDIR "/config/ssl" @@ -65,39 +64,23 @@ #define OPENSSLDIR "/etc/ssl" #endif -#define X509_CERT_AREA OPENSSLDIR -#define X509_CERT_DIR OPENSSLDIR "/certs" -#define X509_CERT_FILE OPENSSLDIR "/cert.pem" -#define X509_PRIVATE_DIR OPENSSLDIR "/private" -#define X509_CERT_DIR_EVP "SSL_CERT_DIR" -#define X509_CERT_FILE_EVP "SSL_CERT_FILE" +#define X509_CERT_AREA OPENSSLDIR +#define X509_CERT_DIR OPENSSLDIR "/certs" +#define X509_CERT_FILE OPENSSLDIR "/cert.pem" +#define X509_PRIVATE_DIR OPENSSLDIR "/private" +#define X509_CERT_DIR_EVP "SSL_CERT_DIR" +#define X509_CERT_FILE_EVP "SSL_CERT_FILE" -const char *X509_get_default_private_dir(void) -{ - return (X509_PRIVATE_DIR); -} +const char *X509_get_default_private_dir(void) { return X509_PRIVATE_DIR; } -const char *X509_get_default_cert_area(void) -{ - return (X509_CERT_AREA); -} +const char *X509_get_default_cert_area(void) { return X509_CERT_AREA; } -const char *X509_get_default_cert_dir(void) -{ - return (X509_CERT_DIR); -} +const char *X509_get_default_cert_dir(void) { return X509_CERT_DIR; } -const char *X509_get_default_cert_file(void) -{ - return (X509_CERT_FILE); -} +const char *X509_get_default_cert_file(void) { return X509_CERT_FILE; } -const char *X509_get_default_cert_dir_env(void) -{ - return (X509_CERT_DIR_EVP); -} +const char *X509_get_default_cert_dir_env(void) { return X509_CERT_DIR_EVP; } -const char *X509_get_default_cert_file_env(void) -{ - return (X509_CERT_FILE_EVP); +const char *X509_get_default_cert_file_env(void) { + return X509_CERT_FILE_EVP; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_ext.c b/third_party/boringssl/kit/src/crypto/x509/x509_ext.c index a08e2a85..a8f561d4 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_ext.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_ext.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_ext.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -64,149 +63,120 @@ #include "internal.h" -int X509_CRL_get_ext_count(const X509_CRL *x) -{ - return (X509v3_get_ext_count(x->crl->extensions)); +int X509_CRL_get_ext_count(const X509_CRL *x) { + return (X509v3_get_ext_count(x->crl->extensions)); } -int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) { + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); } int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); + int lastpos) { + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); } -int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) { + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); } -X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) -{ - return (X509v3_get_ext(x->crl->extensions, loc)); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) { + return (X509v3_get_ext(x->crl->extensions, loc)); } -X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) -{ - return (X509v3_delete_ext(x->crl->extensions, loc)); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) { + return (X509v3_delete_ext(x->crl->extensions, loc)); } void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, int *out_critical, - int *out_idx) -{ - return X509V3_get_d2i(crl->crl->extensions, nid, out_critical, out_idx); + int *out_idx) { + return X509V3_get_d2i(crl->crl->extensions, nid, out_critical, out_idx); } int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); + unsigned long flags) { + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); } -int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +int X509_CRL_add_ext(X509_CRL *x, const X509_EXTENSION *ex, int loc) { + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); } -int X509_get_ext_count(const X509 *x) -{ - return (X509v3_get_ext_count(x->cert_info->extensions)); +int X509_get_ext_count(const X509 *x) { + return (X509v3_get_ext_count(x->cert_info->extensions)); } -int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) { + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); } -int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) { + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); } -int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical - (x->cert_info->extensions, crit, lastpos)); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) { + return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit, lastpos)); } -X509_EXTENSION *X509_get_ext(const X509 *x, int loc) -{ - return (X509v3_get_ext(x->cert_info->extensions, loc)); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc) { + return (X509v3_get_ext(x->cert_info->extensions, loc)); } -X509_EXTENSION *X509_delete_ext(X509 *x, int loc) -{ - return (X509v3_delete_ext(x->cert_info->extensions, loc)); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc) { + return (X509v3_delete_ext(x->cert_info->extensions, loc)); } -int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +int X509_add_ext(X509 *x, const X509_EXTENSION *ex, int loc) { + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); } void *X509_get_ext_d2i(const X509 *x509, int nid, int *out_critical, - int *out_idx) -{ - return X509V3_get_d2i(x509->cert_info->extensions, nid, out_critical, - out_idx); + int *out_idx) { + return X509V3_get_d2i(x509->cert_info->extensions, nid, out_critical, + out_idx); } int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, - flags); + unsigned long flags) { + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, flags); } -int X509_REVOKED_get_ext_count(const X509_REVOKED *x) -{ - return (X509v3_get_ext_count(x->extensions)); +int X509_REVOKED_get_ext_count(const X509_REVOKED *x) { + return (X509v3_get_ext_count(x->extensions)); } -int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) { + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); } int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); + int lastpos) { + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); } int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, - int lastpos) -{ - return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); + int lastpos) { + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); } -X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) -{ - return (X509v3_get_ext(x->extensions, loc)); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) { + return (X509v3_get_ext(x->extensions, loc)); } -X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) -{ - return (X509v3_delete_ext(x->extensions, loc)); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) { + return (X509v3_delete_ext(x->extensions, loc)); } -int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +int X509_REVOKED_add_ext(X509_REVOKED *x, const X509_EXTENSION *ex, int loc) { + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); } void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, int nid, - int *out_critical, int *out_idx) -{ - return X509V3_get_d2i(revoked->extensions, nid, out_critical, out_idx); + int *out_critical, int *out_idx) { + return X509V3_get_d2i(revoked->extensions, nid, out_critical, out_idx); } int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); + unsigned long flags) { + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_lu.c b/third_party/boringssl/kit/src/crypto/x509/x509_lu.c index 041a5fd5..929afffe 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_lu.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_lu.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_lu.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,765 +65,677 @@ #include "../internal.h" #include "internal.h" -X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) -{ - X509_LOOKUP *ret; +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) { + X509_LOOKUP *ret; - ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); - if (ret == NULL) - return NULL; + ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) { + return NULL; + } - ret->init = 0; - ret->skip = 0; - ret->method = method; - ret->method_data = NULL; - ret->store_ctx = NULL; - if ((method->new_item != NULL) && !method->new_item(ret)) { - OPENSSL_free(ret); - return NULL; - } - return ret; + ret->init = 0; + ret->skip = 0; + ret->method = method; + ret->method_data = NULL; + ret->store_ctx = NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) { + OPENSSL_free(ret); + return NULL; + } + return ret; } -void X509_LOOKUP_free(X509_LOOKUP *ctx) -{ - if (ctx == NULL) - return; - if ((ctx->method != NULL) && (ctx->method->free != NULL)) - (*ctx->method->free) (ctx); - OPENSSL_free(ctx); +void X509_LOOKUP_free(X509_LOOKUP *ctx) { + if (ctx == NULL) { + return; + } + if ((ctx->method != NULL) && (ctx->method->free != NULL)) { + (*ctx->method->free)(ctx); + } + OPENSSL_free(ctx); } -int X509_LOOKUP_init(X509_LOOKUP *ctx) -{ - if (ctx->method == NULL) - return 0; - if (ctx->method->init != NULL) - return ctx->method->init(ctx); - else - return 1; +int X509_LOOKUP_init(X509_LOOKUP *ctx) { + if (ctx->method == NULL) { + return 0; + } + if (ctx->method->init != NULL) { + return ctx->method->init(ctx); + } else { + return 1; + } } -int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) -{ - if (ctx->method == NULL) - return 0; - if (ctx->method->shutdown != NULL) - return ctx->method->shutdown(ctx); - else - return 1; +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) { + if (ctx->method == NULL) { + return 0; + } + if (ctx->method->shutdown != NULL) { + return ctx->method->shutdown(ctx); + } else { + return 1; + } } int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret) -{ - if (ctx->method == NULL) - return -1; - if (ctx->method->ctrl != NULL) - return ctx->method->ctrl(ctx, cmd, argc, argl, ret); - else - return 1; + char **ret) { + if (ctx->method == NULL) { + return -1; + } + if (ctx->method->ctrl != NULL) { + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + } else { + return 1; + } } int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) - return 0; - if (ctx->skip) - return 0; - return ctx->method->get_by_subject(ctx, type, name, ret) > 0; + X509_OBJECT *ret) { + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) { + return 0; + } + if (ctx->skip) { + return 0; + } + return ctx->method->get_by_subject(ctx, type, name, ret) > 0; } -int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) - return 0; - return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; -} - -int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) - return 0; - return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; -} - -int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) - return 0; - return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; -} - -static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b) -{ - int ret; - - ret = ((*a)->type - (*b)->type); - if (ret) - return ret; - switch ((*a)->type) { +static int x509_object_cmp(const X509_OBJECT *a, const X509_OBJECT *b) { + int ret = a->type - b->type; + if (ret) { + return ret; + } + switch (a->type) { case X509_LU_X509: - ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); - break; + return X509_subject_name_cmp(a->data.x509, b->data.x509); case X509_LU_CRL: - ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); - break; + return X509_CRL_cmp(a->data.crl, b->data.crl); default: - /* abort(); */ - return 0; - } - return ret; + // abort(); + return 0; + } } -X509_STORE *X509_STORE_new(void) -{ - X509_STORE *ret; +static int x509_object_cmp_sk(const X509_OBJECT *const *a, + const X509_OBJECT *const *b) { + return x509_object_cmp(*a, *b); +} - if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) - return NULL; - OPENSSL_memset(ret, 0, sizeof(*ret)); - CRYPTO_MUTEX_init(&ret->objs_lock); - ret->objs = sk_X509_OBJECT_new(x509_object_cmp); - if (ret->objs == NULL) - goto err; - ret->cache = 1; - ret->get_cert_methods = sk_X509_LOOKUP_new_null(); - if (ret->get_cert_methods == NULL) - goto err; - ret->param = X509_VERIFY_PARAM_new(); - if (ret->param == NULL) - goto err; +X509_STORE *X509_STORE_new(void) { + X509_STORE *ret; - ret->references = 1; - return ret; - err: - if (ret) { - CRYPTO_MUTEX_cleanup(&ret->objs_lock); - if (ret->param) - X509_VERIFY_PARAM_free(ret->param); - if (ret->get_cert_methods) - sk_X509_LOOKUP_free(ret->get_cert_methods); - if (ret->objs) - sk_X509_OBJECT_free(ret->objs); - OPENSSL_free(ret); - } + if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) { return NULL; -} + } + OPENSSL_memset(ret, 0, sizeof(*ret)); + CRYPTO_MUTEX_init(&ret->objs_lock); + ret->objs = sk_X509_OBJECT_new(x509_object_cmp_sk); + if (ret->objs == NULL) { + goto err; + } + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + if (ret->get_cert_methods == NULL) { + goto err; + } + ret->param = X509_VERIFY_PARAM_new(); + if (ret->param == NULL) { + goto err; + } -int X509_STORE_up_ref(X509_STORE *store) -{ - CRYPTO_refcount_inc(&store->references); - return 1; -} - -static void cleanup(X509_OBJECT *a) -{ - if (a == NULL) { - return; + ret->references = 1; + return ret; +err: + if (ret) { + CRYPTO_MUTEX_cleanup(&ret->objs_lock); + if (ret->param) { + X509_VERIFY_PARAM_free(ret->param); } - if (a->type == X509_LU_X509) { - X509_free(a->data.x509); - } else if (a->type == X509_LU_CRL) { - X509_CRL_free(a->data.crl); + if (ret->get_cert_methods) { + sk_X509_LOOKUP_free(ret->get_cert_methods); + } + if (ret->objs) { + sk_X509_OBJECT_free(ret->objs); + } + OPENSSL_free(ret); + } + return NULL; +} + +int X509_STORE_up_ref(X509_STORE *store) { + CRYPTO_refcount_inc(&store->references); + return 1; +} + +static void cleanup(X509_OBJECT *a) { + if (a == NULL) { + return; + } + if (a->type == X509_LU_X509) { + X509_free(a->data.x509); + } else if (a->type == X509_LU_CRL) { + X509_CRL_free(a->data.crl); + } else { + // abort(); + } + + OPENSSL_free(a); +} + +void X509_STORE_free(X509_STORE *vfy) { + size_t j; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { + return; + } + + CRYPTO_MUTEX_cleanup(&vfy->objs_lock); + + sk = vfy->get_cert_methods; + for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { + lu = sk_X509_LOOKUP_value(sk, j); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + if (vfy->param) { + X509_VERIFY_PARAM_free(vfy->param); + } + OPENSSL_free(vfy); +} + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) { + size_t i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk = v->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (m == lu->method) { + return lu; + } + } + // a new one + lu = X509_LOOKUP_new(m); + if (lu == NULL) { + return NULL; + } else { + lu->store_ctx = v; + if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) { + return lu; } else { - /* abort(); */ - } - - OPENSSL_free(a); -} - -void X509_STORE_free(X509_STORE *vfy) -{ - size_t j; - STACK_OF(X509_LOOKUP) *sk; - X509_LOOKUP *lu; - - if (vfy == NULL) - return; - - if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { - return; - } - - CRYPTO_MUTEX_cleanup(&vfy->objs_lock); - - sk = vfy->get_cert_methods; - for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { - lu = sk_X509_LOOKUP_value(sk, j); - X509_LOOKUP_shutdown(lu); - X509_LOOKUP_free(lu); - } - sk_X509_LOOKUP_free(sk); - sk_X509_OBJECT_pop_free(vfy->objs, cleanup); - - if (vfy->param) - X509_VERIFY_PARAM_free(vfy->param); - OPENSSL_free(vfy); -} - -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) -{ - size_t i; - STACK_OF(X509_LOOKUP) *sk; - X509_LOOKUP *lu; - - sk = v->get_cert_methods; - for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { - lu = sk_X509_LOOKUP_value(sk, i); - if (m == lu->method) { - return lu; - } - } - /* a new one */ - lu = X509_LOOKUP_new(m); - if (lu == NULL) - return NULL; - else { - lu->store_ctx = v; - if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) - return lu; - else { - X509_LOOKUP_free(lu); - return NULL; - } + X509_LOOKUP_free(lu); + return NULL; } + } } int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - X509_STORE *ctx = vs->ctx; - X509_LOOKUP *lu; - X509_OBJECT stmp, *tmp; - int i; + X509_OBJECT *ret) { + X509_STORE *ctx = vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i; - CRYPTO_MUTEX_lock_write(&ctx->objs_lock); - tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); - CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); - if (tmp == NULL || type == X509_LU_CRL) { - for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { - lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); - if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { - tmp = &stmp; - break; - } - } - if (tmp == NULL) - return 0; + if (tmp == NULL || type == X509_LU_CRL) { + for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { + tmp = &stmp; + break; + } } + if (tmp == NULL) { + return 0; + } + } - /* - * if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret); - */ + // if (ret->data.ptr != NULL) X509_OBJECT_free_contents(ret); - ret->type = tmp->type; - ret->data.ptr = tmp->data.ptr; + ret->type = tmp->type; + ret->data.ptr = tmp->data.ptr; - X509_OBJECT_up_ref_count(ret); + X509_OBJECT_up_ref_count(ret); - return 1; + return 1; } -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) -{ - X509_OBJECT *obj; - int ret = 1; +static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) { + if (x == NULL) { + return 0; + } - if (x == NULL) - return 0; - obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; - } - obj->type = X509_LU_X509; - obj->data.x509 = x; + X509_OBJECT *const obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + return 0; + } - CRYPTO_MUTEX_lock_write(&ctx->objs_lock); - - X509_OBJECT_up_ref_count(obj); - - if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); - ret = 0; - } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ret = 0; - } - - CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); - - return ret; -} - -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) -{ - X509_OBJECT *obj; - int ret = 1; - - if (x == NULL) - return 0; - obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; - } + if (is_crl) { obj->type = X509_LU_CRL; - obj->data.crl = x; + obj->data.crl = (X509_CRL *)x; + } else { + obj->type = X509_LU_X509; + obj->data.x509 = (X509 *)x; + } + X509_OBJECT_up_ref_count(obj); - CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); - X509_OBJECT_up_ref_count(obj); + int ret = 1; + int added = 0; + // Duplicates are silently ignored + if (!X509_OBJECT_retrieve_match(ctx->objs, obj)) { + ret = added = (sk_X509_OBJECT_push(ctx->objs, obj) != 0); + } - if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE); - ret = 0; - } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ret = 0; - } + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); - CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + if (!added) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + } - return ret; + return ret; } -int X509_OBJECT_up_ref_count(X509_OBJECT *a) -{ - switch (a->type) { +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) { + return x509_store_add(ctx, x, /*is_crl=*/0); +} + +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) { + return x509_store_add(ctx, x, /*is_crl=*/1); +} + +int X509_OBJECT_up_ref_count(X509_OBJECT *a) { + switch (a->type) { case X509_LU_X509: - X509_up_ref(a->data.x509); - break; + X509_up_ref(a->data.x509); + break; case X509_LU_CRL: - X509_CRL_up_ref(a->data.crl); - break; - } - return 1; + X509_CRL_up_ref(a->data.crl); + break; + } + return 1; } -void X509_OBJECT_free_contents(X509_OBJECT *a) -{ - switch (a->type) { +void X509_OBJECT_free_contents(X509_OBJECT *a) { + switch (a->type) { case X509_LU_X509: - X509_free(a->data.x509); - break; + X509_free(a->data.x509); + break; case X509_LU_CRL: - X509_CRL_free(a->data.crl); - break; - } + X509_CRL_free(a->data.crl); + break; + } } -int X509_OBJECT_get_type(const X509_OBJECT *a) -{ - return a->type; -} +int X509_OBJECT_get_type(const X509_OBJECT *a) { return a->type; } -X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) -{ - if (a == NULL || a->type != X509_LU_X509) { - return NULL; - } - return a->data.x509; +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) { + if (a == NULL || a->type != X509_LU_X509) { + return NULL; + } + return a->data.x509; } static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name, int *pnmatch) -{ - X509_OBJECT stmp; - X509 x509_s; - X509_CINF cinf_s; - X509_CRL crl_s; - X509_CRL_INFO crl_info_s; + X509_NAME *name, int *pnmatch) { + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; - stmp.type = type; - switch (type) { + stmp.type = type; + switch (type) { case X509_LU_X509: - stmp.data.x509 = &x509_s; - x509_s.cert_info = &cinf_s; - cinf_s.subject = name; - break; + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; case X509_LU_CRL: - stmp.data.crl = &crl_s; - crl_s.crl = &crl_info_s; - crl_info_s.issuer = name; - break; + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; default: - /* abort(); */ - return -1; + // abort(); + return -1; + } + + size_t idx; + sk_X509_OBJECT_sort(h); + if (!sk_X509_OBJECT_find(h, &idx, &stmp)) { + return -1; + } + + if (pnmatch != NULL) { + *pnmatch = 1; + for (size_t tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { + const X509_OBJECT *tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(tobj, &stmp)) { + break; + } + (*pnmatch)++; } + } - size_t idx; - sk_X509_OBJECT_sort(h); - if (!sk_X509_OBJECT_find(h, &idx, &stmp)) - return -1; - - if (pnmatch != NULL) { - int tidx; - const X509_OBJECT *tobj, *pstmp; - *pnmatch = 1; - pstmp = &stmp; - for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++) { - tobj = sk_X509_OBJECT_value(h, tidx); - if (x509_object_cmp(&tobj, &pstmp)) - break; - (*pnmatch)++; - } - } - - return idx; + return (int)idx; } int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) -{ - return x509_object_idx_cnt(h, type, name, NULL); + X509_NAME *name) { + return x509_object_idx_cnt(h, type, name, NULL); } -X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, - int type, X509_NAME *name) -{ - int idx; - idx = X509_OBJECT_idx_by_subject(h, type, name); - if (idx == -1) - return NULL; - return sk_X509_OBJECT_value(h, idx); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) { + int idx; + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) { + return NULL; + } + return sk_X509_OBJECT_value(h, idx); } -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) -{ - return st->objs; +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) { + return st->objs; } -STACK_OF (X509) * X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) -{ - int i, idx, cnt; - STACK_OF(X509) *sk; - X509 *x; - X509_OBJECT *obj; - sk = sk_X509_new_null(); - if (sk == NULL) - return NULL; - CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); - if (idx < 0) { - /* - * Nothing found in cache: do lookup to possibly add new objects to - * cache - */ - X509_OBJECT xobj; - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { - sk_X509_free(sk); - return NULL; - } - X509_OBJECT_free_contents(&xobj); - CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); - if (idx < 0) { - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - sk_X509_free(sk); - return NULL; - } - } - for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); - x = obj->data.x509; - if (!sk_X509_push(sk, x)) { - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - sk_X509_pop_free(sk, X509_free); - return NULL; - } - X509_up_ref(x); - } +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) { + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + sk = sk_X509_new_null(); + if (sk == NULL) { + return NULL; + } + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + // Nothing found in cache: do lookup to possibly add new objects to + // cache + X509_OBJECT xobj; CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - return sk; - -} - -STACK_OF (X509_CRL) * X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) -{ - int i, idx, cnt; - STACK_OF(X509_CRL) *sk; - X509_CRL *x; - X509_OBJECT *obj, xobj; - sk = sk_X509_CRL_new_null(); - if (sk == NULL) - return NULL; - - /* Always do lookup to possibly add new CRLs to cache. */ - if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { - sk_X509_CRL_free(sk); - return NULL; + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; } X509_OBJECT_free_contents(&xobj); CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - sk_X509_CRL_free(sk); - return NULL; + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_free(sk); + return NULL; } + } + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + if (!sk_X509_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + X509_up_ref(x); + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; +} - for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); - x = obj->data.crl; - X509_CRL_up_ref(x); - if (!sk_X509_CRL_push(sk, x)) { - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - X509_CRL_free(x); - sk_X509_CRL_pop_free(sk, X509_CRL_free); - return NULL; - } - } +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) { + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + sk = sk_X509_CRL_new_null(); + if (sk == NULL) { + return NULL; + } + + // Always do lookup to possibly add new CRLs to cache. + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - return sk; + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + X509_CRL_up_ref(x); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; } X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, - X509_OBJECT *x) -{ - size_t idx, i; - X509_OBJECT *obj; - - sk_X509_OBJECT_sort(h); - if (!sk_X509_OBJECT_find(h, &idx, x)) { - return NULL; - } - if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) - return sk_X509_OBJECT_value(h, idx); - for (i = idx; i < sk_X509_OBJECT_num(h); i++) { - obj = sk_X509_OBJECT_value(h, i); - if (x509_object_cmp - ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) - return NULL; - if (x->type == X509_LU_X509) { - if (!X509_cmp(obj->data.x509, x->data.x509)) - return obj; - } else if (x->type == X509_LU_CRL) { - if (!X509_CRL_match(obj->data.crl, x->data.crl)) - return obj; - } else - return obj; - } + X509_OBJECT *x) { + sk_X509_OBJECT_sort(h); + size_t idx; + if (!sk_X509_OBJECT_find(h, &idx, x)) { return NULL; -} - -/* - * Try to get issuer certificate from store. Due to limitations of the API - * this can only retrieve a single certificate matching a given subject name. - * However it will fill the cache with all matching certificates, so we can - * examine the cache for all matches. Return values are: 1 lookup - * successful. 0 certificate not found. -1 some other error. - */ -int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -{ - X509_NAME *xn; - X509_OBJECT obj, *pobj; - int idx, ret; - size_t i; - xn = X509_get_issuer_name(x); - if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) - return 0; - /* If certificate matches all OK */ - if (ctx->check_issued(ctx, x, obj.data.x509)) { - *issuer = obj.data.x509; - return 1; + } + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) { + return sk_X509_OBJECT_value(h, idx); + } + for (size_t i = idx; i < sk_X509_OBJECT_num(h); i++) { + X509_OBJECT *obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp(obj, x)) { + return NULL; } - X509_OBJECT_free_contents(&obj); - - /* Else find index of first cert accepted by 'check_issued' */ - ret = 0; - CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); - idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); - if (idx != -1) { /* should be true as we've had at least one - * match */ - /* Look through all matching certs for suitable issuer */ - for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { - pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); - /* See if we've run past the matches */ - if (pobj->type != X509_LU_X509) - break; - if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) - break; - if (ctx->check_issued(ctx, x, pobj->data.x509)) { - *issuer = pobj->data.x509; - X509_OBJECT_up_ref_count(pobj); - ret = 1; - break; - } - } + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) { + return obj; + } + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) { + return obj; + } + } else { + return obj; } - CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); - return ret; + } + return NULL; } -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) -{ - return X509_VERIFY_PARAM_set_flags(ctx->param, flags); -} - -int X509_STORE_set_depth(X509_STORE *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); +// Try to get issuer certificate from store. Due to limitations of the API +// this can only retrieve a single certificate matching a given subject name. +// However it will fill the cache with all matching certificates, so we can +// examine the cache for all matches. Return values are: 1 lookup +// successful. 0 certificate not found. -1 some other error. +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int idx, ret; + size_t i; + xn = X509_get_issuer_name(x); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) { + return 0; + } + // If certificate matches all OK + if (ctx->check_issued(ctx, x, obj.data.x509)) { + *issuer = obj.data.x509; return 1; + } + X509_OBJECT_free_contents(&obj); + + // Else find index of first cert accepted by 'check_issued' + ret = 0; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + if (idx != -1) { // should be true as we've had at least one + // match + // Look through all matching certs for suitable issuer + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + // See if we've run past the matches + if (pobj->type != X509_LU_X509) { + break; + } + if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) { + break; + } + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + *issuer = pobj->data.x509; + X509_OBJECT_up_ref_count(pobj); + ret = 1; + break; + } + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return ret; } -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) { + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); } -int X509_STORE_set_trust(X509_STORE *ctx, int trust) -{ - return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +int X509_STORE_set_depth(X509_STORE *ctx, int depth) { + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; } -int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) -{ - return X509_VERIFY_PARAM_set1(ctx->param, param); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) { + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); } -X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) -{ - return ctx->param; +int X509_STORE_set_trust(X509_STORE *ctx, int trust) { + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); } -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) -{ - ctx->verify = verify; +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) { + return X509_VERIFY_PARAM_set1(ctx->param, param); } -X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) -{ - return ctx->verify; +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) { return ctx->param; } + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) { + ctx->verify = verify; +} + +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) { + return ctx->verify; } void X509_STORE_set_verify_cb(X509_STORE *ctx, - X509_STORE_CTX_verify_cb verify_cb) -{ - ctx->verify_cb = verify_cb; + X509_STORE_CTX_verify_cb verify_cb) { + ctx->verify_cb = verify_cb; } -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) -{ - return ctx->verify_cb; +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) { + return ctx->verify_cb; } void X509_STORE_set_get_issuer(X509_STORE *ctx, - X509_STORE_CTX_get_issuer_fn get_issuer) -{ - ctx->get_issuer = get_issuer; + X509_STORE_CTX_get_issuer_fn get_issuer) { + ctx->get_issuer = get_issuer; } -X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) -{ - return ctx->get_issuer; +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) { + return ctx->get_issuer; } void X509_STORE_set_check_issued(X509_STORE *ctx, - X509_STORE_CTX_check_issued_fn check_issued) -{ - ctx->check_issued = check_issued; + X509_STORE_CTX_check_issued_fn check_issued) { + ctx->check_issued = check_issued; } -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) -{ - return ctx->check_issued; +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) { + return ctx->check_issued; } -void X509_STORE_set_check_revocation(X509_STORE *ctx, - X509_STORE_CTX_check_revocation_fn check_revocation) -{ - ctx->check_revocation = check_revocation; +void X509_STORE_set_check_revocation( + X509_STORE *ctx, X509_STORE_CTX_check_revocation_fn check_revocation) { + ctx->check_revocation = check_revocation; } -X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx) -{ - return ctx->check_revocation; +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation( + X509_STORE *ctx) { + return ctx->check_revocation; } void X509_STORE_set_get_crl(X509_STORE *ctx, - X509_STORE_CTX_get_crl_fn get_crl) -{ - ctx->get_crl = get_crl; + X509_STORE_CTX_get_crl_fn get_crl) { + ctx->get_crl = get_crl; } -X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx) -{ - return ctx->get_crl; +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx) { + return ctx->get_crl; } void X509_STORE_set_check_crl(X509_STORE *ctx, - X509_STORE_CTX_check_crl_fn check_crl) -{ - ctx->check_crl = check_crl; + X509_STORE_CTX_check_crl_fn check_crl) { + ctx->check_crl = check_crl; } -X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) -{ - return ctx->check_crl; +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) { + return ctx->check_crl; } void X509_STORE_set_cert_crl(X509_STORE *ctx, - X509_STORE_CTX_cert_crl_fn cert_crl) -{ - ctx->cert_crl = cert_crl; + X509_STORE_CTX_cert_crl_fn cert_crl) { + ctx->cert_crl = cert_crl; } -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) -{ - return ctx->cert_crl; +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) { + return ctx->cert_crl; } void X509_STORE_set_lookup_certs(X509_STORE *ctx, - X509_STORE_CTX_lookup_certs_fn lookup_certs) -{ - ctx->lookup_certs = lookup_certs; + X509_STORE_CTX_lookup_certs_fn lookup_certs) { + ctx->lookup_certs = lookup_certs; } -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) -{ - return ctx->lookup_certs; +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) { + return ctx->lookup_certs; } void X509_STORE_set_lookup_crls(X509_STORE *ctx, - X509_STORE_CTX_lookup_crls_fn lookup_crls) -{ - ctx->lookup_crls = lookup_crls; + X509_STORE_CTX_lookup_crls_fn lookup_crls) { + ctx->lookup_crls = lookup_crls; } -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) -{ - return ctx->lookup_crls; +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) { + return ctx->lookup_crls; } void X509_STORE_set_cleanup(X509_STORE *ctx, - X509_STORE_CTX_cleanup_fn ctx_cleanup) -{ - ctx->cleanup = ctx_cleanup; + X509_STORE_CTX_cleanup_fn ctx_cleanup) { + ctx->cleanup = ctx_cleanup; } -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) -{ - return ctx->cleanup; +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) { + return ctx->cleanup; } -X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) -{ - return ctx->ctx; -} +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) { return ctx->ctx; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_obj.c b/third_party/boringssl/kit/src/crypto/x509/x509_obj.c index df54f779..ed6dcc66 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_obj.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_obj.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_obj.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -67,133 +66,141 @@ #include "internal.h" -/* - * Limit to ensure we don't overflow: much greater than - * anything enountered in practice. - */ +// Limit to ensure we don't overflow: much greater than +// anything enountered in practice. -#define NAME_ONELINE_MAX (1024 * 1024) +#define NAME_ONELINE_MAX (1024 * 1024) -char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) -{ - X509_NAME_ENTRY *ne; - size_t i; - int n, lold, l, l1, l2, num, j, type; - const char *s; - char *p; - unsigned char *q; - BUF_MEM *b = NULL; - static const char hex[17] = "0123456789ABCDEF"; - int gs_doit[4]; - char tmp_buf[80]; +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) { + X509_NAME_ENTRY *ne; + size_t i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; - if (buf == NULL) { - if ((b = BUF_MEM_new()) == NULL) - goto err; - if (!BUF_MEM_grow(b, 200)) - goto err; - b->data[0] = '\0'; - len = 200; - } else if (len <= 0) { - return NULL; + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) { + goto err; } - if (a == NULL) { - if (b) { - buf = b->data; - OPENSSL_free(b); + if (!BUF_MEM_grow(b, 200)) { + goto err; + } + b->data[0] = '\0'; + len = 200; + } else if (len <= 0) { + return NULL; + } + if (a == NULL) { + if (b) { + buf = b->data; + OPENSSL_free(b); + } + OPENSSL_strlcpy(buf, "NO X509_NAME", len); + return buf; + } + + len--; // space for '\0' + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + if (num > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto err; + } + q = ne->value->data; + + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) { + if (q[j] != 0) { + gs_doit[j & 3] = 1; } - OPENSSL_strlcpy(buf, "NO X509_NAME", len); - return buf; + } + + if (gs_doit[0] | gs_doit[1] | gs_doit[2]) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + } else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; } - len--; /* space for '\0' */ - l = 0; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - ne = sk_X509_NAME_ENTRY_value(a->entries, i); - n = OBJ_obj2nid(ne->object); - if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { - i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); - s = tmp_buf; - } - l1 = strlen(s); + for (l2 = j = 0; j < num; j++) { + if (!gs_doit[j & 3]) { + continue; + } + l2++; + if ((q[j] < ' ') || (q[j] > '~')) { + l2 += 3; + } + } - type = ne->value->type; - num = ne->value->length; - if (num > NAME_ONELINE_MAX) { - OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); - goto end; - } - q = ne->value->data; - - if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; - for (j = 0; j < num; j++) - if (q[j] != 0) - gs_doit[j & 3] = 1; - - if (gs_doit[0] | gs_doit[1] | gs_doit[2]) - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; - else { - gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; - gs_doit[3] = 1; - } - } else - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; - - for (l2 = j = 0; j < num; j++) { - if (!gs_doit[j & 3]) - continue; - l2++; - if ((q[j] < ' ') || (q[j] > '~')) - l2 += 3; - } - - lold = l; - l += 1 + l1 + 1 + l2; - if (l > NAME_ONELINE_MAX) { - OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); - goto end; - } - if (b != NULL) { - if (!BUF_MEM_grow(b, l + 1)) - goto err; - p = &(b->data[lold]); - } else if (l > len) { - break; - } else - p = &(buf[lold]); - *(p++) = '/'; - OPENSSL_memcpy(p, s, (unsigned int)l1); - p += l1; - *(p++) = '='; - - q = ne->value->data; - - for (j = 0; j < num; j++) { - if (!gs_doit[j & 3]) - continue; - n = q[j]; - if ((n < ' ') || (n > '~')) { - *(p++) = '\\'; - *(p++) = 'x'; - *(p++) = hex[(n >> 4) & 0x0f]; - *(p++) = hex[n & 0x0f]; - } else - *(p++) = n; - } - *p = '\0'; + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto err; } if (b != NULL) { - p = b->data; - OPENSSL_free(b); - } else - p = buf; - if (i == 0) - *p = '\0'; - return (p); - err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - end: - BUF_MEM_free(b); - return (NULL); + if (!BUF_MEM_grow(b, l + 1)) { + goto err; + } + p = &(b->data[lold]); + } else if (l > len) { + break; + } else { + p = &(buf[lold]); + } + *(p++) = '/'; + OPENSSL_memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + + q = ne->value->data; + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) { + continue; + } + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else { + *(p++) = n; + } + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else { + p = buf; + } + if (i == 0) { + *p = '\0'; + } + return p; +err: + BUF_MEM_free(b); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_req.c b/third_party/boringssl/kit/src/crypto/x509/x509_req.c index 99eabfe6..385d8c0e 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_req.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_req.c @@ -1,4 +1,3 @@ -/* crypto/x509/x509_req.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -65,240 +64,224 @@ #include #include +#include "../asn1/internal.h" #include "internal.h" -X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - X509_REQ *ret; - X509_REQ_INFO *ri; - int i; - EVP_PKEY *pktmp; - - ret = X509_REQ_new(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto err; - } - - ri = ret->req_info; - - ri->version->length = 1; - ri->version->data = (unsigned char *)OPENSSL_malloc(1); - if (ri->version->data == NULL) - goto err; - ri->version->data[0] = 0; /* version == 0 */ - - if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) - goto err; - - pktmp = X509_get_pubkey(x); - if (pktmp == NULL) - goto err; - i = X509_REQ_set_pubkey(ret, pktmp); - EVP_PKEY_free(pktmp); - if (!i) - goto err; - - if (pkey != NULL) { - if (!X509_REQ_sign(ret, pkey, md)) - goto err; - } - return (ret); - err: - X509_REQ_free(ret); - return (NULL); +long X509_REQ_get_version(const X509_REQ *req) { + return ASN1_INTEGER_get(req->req_info->version); } -long X509_REQ_get_version(const X509_REQ *req) -{ - return ASN1_INTEGER_get(req->req_info->version); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) { + return req->req_info->subject; } -X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) -{ - return req->req_info->subject; +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) { + if ((req == NULL) || (req->req_info == NULL)) { + return NULL; + } + return (X509_PUBKEY_get(req->req_info->pubkey)); } -EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) -{ - if ((req == NULL) || (req->req_info == NULL)) - return (NULL); - return (X509_PUBKEY_get(req->req_info->pubkey)); -} +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) { + EVP_PKEY *xk = NULL; + int ok = 0; -int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) -{ - EVP_PKEY *xk = NULL; - int ok = 0; - - xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_cmp(xk, k)) { + xk = X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) { case 1: - ok = 1; - break; + ok = 1; + break; case 0: - OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); - break; + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; case -1: - OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); - break; + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; case -2: - if (k->type == EVP_PKEY_EC) { - OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB); - break; - } - if (k->type == EVP_PKEY_DH) { - /* No idea */ - OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY); - break; - } - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); - } + if (EVP_PKEY_id(k) == EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB); + break; + } + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + } - EVP_PKEY_free(xk); - return (ok); + EVP_PKEY_free(xk); + return ok; } -int X509_REQ_extension_nid(int req_nid) -{ - return req_nid == NID_ext_req || req_nid == NID_ms_ext_req; +int X509_REQ_extension_nid(int req_nid) { + return req_nid == NID_ext_req || req_nid == NID_ms_ext_req; } -STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) -{ - if (req == NULL || req->req_info == NULL) { - return NULL; - } +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) { + if (req == NULL || req->req_info == NULL) { + return NULL; + } - int idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1); - if (idx == -1) { - idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1); - } - if (idx == -1) { - return NULL; - } + int idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1); + if (idx == -1) { + idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1); + } + if (idx == -1) { + return NULL; + } - X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx); - ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type(attr, 0); - if (!ext || ext->type != V_ASN1_SEQUENCE) { - return NULL; - } - const unsigned char *p = ext->value.sequence->data; - return (STACK_OF(X509_EXTENSION) *) - ASN1_item_d2i(NULL, &p, ext->value.sequence->length, - ASN1_ITEM_rptr(X509_EXTENSIONS)); + X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx); + ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type(attr, 0); + if (!ext || ext->type != V_ASN1_SEQUENCE) { + return NULL; + } + const unsigned char *p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i( + NULL, &p, ext->value.sequence->length, ASN1_ITEM_rptr(X509_EXTENSIONS)); } -/* - * Add a STACK_OF extensions to a certificate request: allow alternative OIDs - * in case we want to create a non standard one. - */ +// Add a STACK_OF extensions to a certificate request: allow alternative OIDs +// in case we want to create a non standard one. int X509_REQ_add_extensions_nid(X509_REQ *req, - const STACK_OF(X509_EXTENSION) *exts, int nid) -{ - /* Generate encoding of extensions */ - unsigned char *ext = NULL; - int ext_len = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, - ASN1_ITEM_rptr(X509_EXTENSIONS)); - if (ext_len <= 0) { - return 0; - } - int ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, - ext_len); - OPENSSL_free(ext); - return ret; + const STACK_OF(X509_EXTENSION) *exts, int nid) { + // Generate encoding of extensions + unsigned char *ext = NULL; + int ext_len = + ASN1_item_i2d((ASN1_VALUE *)exts, &ext, ASN1_ITEM_rptr(X509_EXTENSIONS)); + if (ext_len <= 0) { + return 0; + } + int ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, ext_len); + OPENSSL_free(ext); + return ret; } -/* This is the normal usage: use the "official" OID */ +// This is the normal usage: use the "official" OID int X509_REQ_add_extensions(X509_REQ *req, - const STACK_OF(X509_EXTENSION) *exts) -{ - return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); + const STACK_OF(X509_EXTENSION) *exts) { + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); } -/* Request attribute functions */ - -int X509_REQ_get_attr_count(const X509_REQ *req) -{ - return X509at_get_attr_count(req->req_info->attributes); +int X509_REQ_get_attr_count(const X509_REQ *req) { + return (int)sk_X509_ATTRIBUTE_num(req->req_info->attributes); } -int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) -{ - return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -1; + } + return X509_REQ_get_attr_by_OBJ(req, obj, lastpos); } int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); + int lastpos) { + if (req->req_info->attributes == NULL) { + return -1; + } + lastpos++; + if (lastpos < 0) { + lastpos = 0; + } + int n = (int)sk_X509_ATTRIBUTE_num(req->req_info->attributes); + for (; lastpos < n; lastpos++) { + const X509_ATTRIBUTE *attr = + sk_X509_ATTRIBUTE_value(req->req_info->attributes, lastpos); + if (OBJ_cmp(attr->object, obj) == 0) { + return lastpos; + } + } + return -1; } -X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) -{ - return X509at_get_attr(req->req_info->attributes, loc); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) { + if (req->req_info->attributes == NULL || loc < 0 || + sk_X509_ATTRIBUTE_num(req->req_info->attributes) <= (size_t)loc) { + return NULL; + } + return sk_X509_ATTRIBUTE_value(req->req_info->attributes, loc); } -X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) -{ - return X509at_delete_attr(req->req_info->attributes, loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) { + if (req->req_info->attributes == NULL || loc < 0 || + sk_X509_ATTRIBUTE_num(req->req_info->attributes) <= (size_t)loc) { + return NULL; + } + return sk_X509_ATTRIBUTE_delete(req->req_info->attributes, loc); } -int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&req->req_info->attributes, attr)) - return 1; +static int X509_REQ_add0_attr(X509_REQ *req, X509_ATTRIBUTE *attr) { + if (req->req_info->attributes == NULL) { + req->req_info->attributes = sk_X509_ATTRIBUTE_new_null(); + } + if (req->req_info->attributes == NULL || + !sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) { return 0; + } + + return 1; } -int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, - const ASN1_OBJECT *obj, int attrtype, - const unsigned char *data, int len) -{ - if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, - attrtype, data, len)) - return 1; +int X509_REQ_add1_attr(X509_REQ *req, const X509_ATTRIBUTE *attr) { + X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_dup(attr); + if (new_attr == NULL || !X509_REQ_add0_attr(req, new_attr)) { + X509_ATTRIBUTE_free(new_attr); return 0; + } + + return 1; } -int X509_REQ_add1_attr_by_NID(X509_REQ *req, - int nid, int attrtype, - const unsigned char *data, int len) -{ - if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, - attrtype, data, len)) - return 1; +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, + int attrtype, const unsigned char *data, + int len) { + X509_ATTRIBUTE *attr = + X509_ATTRIBUTE_create_by_OBJ(NULL, obj, attrtype, data, len); + if (attr == NULL || !X509_REQ_add0_attr(req, attr)) { + X509_ATTRIBUTE_free(attr); return 0; + } + + return 1; } -int X509_REQ_add1_attr_by_txt(X509_REQ *req, - const char *attrname, int attrtype, - const unsigned char *data, int len) -{ - if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, - attrtype, data, len)) - return 1; +int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int attrtype, + const unsigned char *data, int len) { + X509_ATTRIBUTE *attr = + X509_ATTRIBUTE_create_by_NID(NULL, nid, attrtype, data, len); + if (attr == NULL || !X509_REQ_add0_attr(req, attr)) { + X509_ATTRIBUTE_free(attr); return 0; + } + + return 1; +} + +int X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int attrtype, + const unsigned char *data, int len) { + X509_ATTRIBUTE *attr = + X509_ATTRIBUTE_create_by_txt(NULL, attrname, attrtype, data, len); + if (attr == NULL || !X509_REQ_add0_attr(req, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + + return 1; } void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = req->signature; - if (palg != NULL) - *palg = req->sig_alg; + const X509_ALGOR **palg) { + if (psig != NULL) { + *psig = req->signature; + } + if (palg != NULL) { + *palg = req->sig_alg; + } } -int X509_REQ_get_signature_nid(const X509_REQ *req) -{ - return OBJ_obj2nid(req->sig_alg->algorithm); +int X509_REQ_get_signature_nid(const X509_REQ *req) { + return OBJ_obj2nid(req->sig_alg->algorithm); } -int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) -{ - req->req_info->enc.modified = 1; - return i2d_X509_REQ_INFO(req->req_info, pp); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) { + asn1_encoding_clear(&req->req_info->enc); + return i2d_X509_REQ_INFO(req->req_info, pp); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_set.c b/third_party/boringssl/kit/src/crypto/x509/x509_set.c index 93bb6a39..bfc3ae01 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_set.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_set.c @@ -63,178 +63,178 @@ #include "internal.h" -long X509_get_version(const X509 *x509) -{ - // The default version is v1(0). - if (x509->cert_info->version == NULL) { - return X509_VERSION_1; - } - return ASN1_INTEGER_get(x509->cert_info->version); +long X509_get_version(const X509 *x509) { + // The default version is v1(0). + if (x509->cert_info->version == NULL) { + return X509_VERSION_1; + } + return ASN1_INTEGER_get(x509->cert_info->version); } -int X509_set_version(X509 *x, long version) -{ - // TODO(davidben): Reject invalid version numbers. - if (x == NULL) - return (0); - if (version == 0) { - ASN1_INTEGER_free(x->cert_info->version); - x->cert_info->version = NULL; - return (1); - } +int X509_set_version(X509 *x, long version) { + if (x == NULL) { + return 0; + } + + if (version < X509_VERSION_1 || version > X509_VERSION_3) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; + } + + // v1(0) is default and is represented by omitting the version. + if (version == X509_VERSION_1) { + ASN1_INTEGER_free(x->cert_info->version); + x->cert_info->version = NULL; + return 1; + } + + if (x->cert_info->version == NULL) { + x->cert_info->version = ASN1_INTEGER_new(); if (x->cert_info->version == NULL) { - if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL) - return (0); + return 0; } - return (ASN1_INTEGER_set(x->cert_info->version, version)); + } + return ASN1_INTEGER_set_int64(x->cert_info->version, version); } -int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; +int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) { + if (serial->type != V_ASN1_INTEGER && serial->type != V_ASN1_NEG_INTEGER) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } - if (x == NULL) - return (0); - in = x->cert_info->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - ASN1_INTEGER_free(x->cert_info->serialNumber); - x->cert_info->serialNumber = in; - } + ASN1_INTEGER *in; + if (x == NULL) { + return 0; + } + in = x->cert_info->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; } - return (in != NULL); + } + return in != NULL; } -int X509_set_issuer_name(X509 *x, X509_NAME *name) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_NAME_set(&x->cert_info->issuer, name)); +int X509_set_issuer_name(X509 *x, X509_NAME *name) { + if ((x == NULL) || (x->cert_info == NULL)) { + return 0; + } + return (X509_NAME_set(&x->cert_info->issuer, name)); } -int X509_set_subject_name(X509 *x, X509_NAME *name) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_NAME_set(&x->cert_info->subject, name)); +int X509_set_subject_name(X509 *x, X509_NAME *name) { + if ((x == NULL) || (x->cert_info == NULL)) { + return 0; + } + return (X509_NAME_set(&x->cert_info->subject, name)); } -int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) { + ASN1_TIME *in; - if ((x == NULL) || (x->cert_info->validity == NULL)) - return (0); - in = x->cert_info->validity->notBefore; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notBefore); - x->cert_info->validity->notBefore = in; - } + if ((x == NULL) || (x->cert_info->validity == NULL)) { + return 0; + } + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; } - return (in != NULL); + } + return in != NULL; } -int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) -{ - return X509_set1_notBefore(x, tm); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) { + return X509_set1_notBefore(x, tm); } -const ASN1_TIME *X509_get0_notBefore(const X509 *x) -{ - return x->cert_info->validity->notBefore; +const ASN1_TIME *X509_get0_notBefore(const X509 *x) { + return x->cert_info->validity->notBefore; } -ASN1_TIME *X509_getm_notBefore(X509 *x) -{ - // Note this function takes a const |X509| pointer in OpenSSL. We require - // non-const as this allows mutating |x|. If it comes up for compatibility, - // we can relax this. - return x->cert_info->validity->notBefore; +ASN1_TIME *X509_getm_notBefore(X509 *x) { + // Note this function takes a const |X509| pointer in OpenSSL. We require + // non-const as this allows mutating |x|. If it comes up for compatibility, + // we can relax this. + return x->cert_info->validity->notBefore; } -ASN1_TIME *X509_get_notBefore(const X509 *x509) -{ - // In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our - // |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was - // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notBefore; +ASN1_TIME *X509_get_notBefore(const X509 *x509) { + // In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our + // |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was + // originally a macro, so it needs to capture both get0 and getm use cases. + return x509->cert_info->validity->notBefore; } -int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) { + ASN1_TIME *in; - if ((x == NULL) || (x->cert_info->validity == NULL)) - return (0); - in = x->cert_info->validity->notAfter; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notAfter); - x->cert_info->validity->notAfter = in; - } + if ((x == NULL) || (x->cert_info->validity == NULL)) { + return 0; + } + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; } - return (in != NULL); + } + return in != NULL; } -int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) -{ - return X509_set1_notAfter(x, tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) { + return X509_set1_notAfter(x, tm); } -const ASN1_TIME *X509_get0_notAfter(const X509 *x) -{ - return x->cert_info->validity->notAfter; +const ASN1_TIME *X509_get0_notAfter(const X509 *x) { + return x->cert_info->validity->notAfter; } -ASN1_TIME *X509_getm_notAfter(X509 *x) -{ - // Note this function takes a const |X509| pointer in OpenSSL. We require - // non-const as this allows mutating |x|. If it comes up for compatibility, - // we can relax this. - return x->cert_info->validity->notAfter; +ASN1_TIME *X509_getm_notAfter(X509 *x) { + // Note this function takes a const |X509| pointer in OpenSSL. We require + // non-const as this allows mutating |x|. If it comes up for compatibility, + // we can relax this. + return x->cert_info->validity->notAfter; } -ASN1_TIME *X509_get_notAfter(const X509 *x509) -{ - // In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our - // |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was - // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notAfter; +ASN1_TIME *X509_get_notAfter(const X509 *x509) { + // In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our + // |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was + // originally a macro, so it needs to capture both get0 and getm use cases. + return x509->cert_info->validity->notAfter; } void X509_get0_uids(const X509 *x509, const ASN1_BIT_STRING **out_issuer_uid, - const ASN1_BIT_STRING **out_subject_uid) -{ - if (out_issuer_uid != NULL) { - *out_issuer_uid = x509->cert_info->issuerUID; - } - if (out_subject_uid != NULL) { - *out_subject_uid = x509->cert_info->subjectUID; - } + const ASN1_BIT_STRING **out_subject_uid) { + if (out_issuer_uid != NULL) { + *out_issuer_uid = x509->cert_info->issuerUID; + } + if (out_subject_uid != NULL) { + *out_subject_uid = x509->cert_info->subjectUID; + } } -int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) { + if ((x == NULL) || (x->cert_info == NULL)) { + return 0; + } + return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); } -const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) -{ - return x->cert_info->extensions; +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) { + return x->cert_info->extensions; } -const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) -{ - return x->cert_info->signature; +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) { + return x->cert_info->signature; } -X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) -{ - return x509->cert_info->key; +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) { + return x509->cert_info->key; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_test.cc b/third_party/boringssl/kit/src/crypto/x509/x509_test.cc index 77c383a6..404ce5ba 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_test.cc +++ b/third_party/boringssl/kit/src/crypto/x509/x509_test.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,10 @@ #include "../test/test_util.h" #include "../x509v3/internal.h" +#if defined(OPENSSL_THREADS) +#include +#endif + std::string GetTestData(const char *path); @@ -184,26 +189,6 @@ DSLfRgaQwcb2gg2xpDFoG+W0vc6O651uF23WGt5JaFFJJxqjII05IexfCNhuPmp4 -----END CERTIFICATE----- )"; -// kExamplePSSCert is an example RSA-PSS self-signed certificate, signed with -// the default hash functions. -static const char kExamplePSSCert[] = R"( ------BEGIN CERTIFICATE----- -MIICYjCCAcagAwIBAgIJAI3qUyT6SIfzMBIGCSqGSIb3DQEBCjAFogMCAWowRTEL -MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy -bmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDEwMDkxOTA5NTVaFw0xNTEwMDkxOTA5 -NTVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQK -DBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0A -MIGJAoGBAPi4bIO0vNmoV8CltFl2jFQdeesiUgR+0zfrQf2D+fCmhRU0dXFahKg8 -0u9aTtPel4rd/7vPCqqGkr64UOTNb4AzMHYTj8p73OxaymPHAyXvqIqDWHYg+hZ3 -13mSYwFIGth7Z/FSVUlO1m5KXNd6NzYM3t2PROjCpywrta9kS2EHAgMBAAGjUDBO -MB0GA1UdDgQWBBTQQfuJQR6nrVrsNF1JEflVgXgfEzAfBgNVHSMEGDAWgBTQQfuJ -QR6nrVrsNF1JEflVgXgfEzAMBgNVHRMEBTADAQH/MBIGCSqGSIb3DQEBCjAFogMC -AWoDgYEASUy2RZcgNbNQZA0/7F+V1YTLEXwD16bm+iSVnzGwtexmQVEYIZG74K/w -xbdZQdTbpNJkp1QPjPfh0zsatw6dmt5QoZ8K8No0DjR9dgf+Wvv5WJvJUIQBoAVN -Z0IL+OQFz6+LcTHxD27JJCebrATXZA0wThGTQDm7crL+a+SujBY= ------END CERTIFICATE----- -)"; - // kBadPSSCertPEM is a self-signed RSA-PSS certificate with bad parameters. static const char kBadPSSCertPEM[] = R"( -----BEGIN CERTIFICATE----- @@ -1047,7 +1032,7 @@ TXHOSQQD8Dl4BK0wOet+TP6LBEjHlRFjAqK4bu9xpxV2 -----END CERTIFICATE----- )"; -// CertFromPEM parses the given, NUL-terminated pem block and returns an +// CertFromPEM parses the given, NUL-terminated PEM block and returns an // |X509*|. static bssl::UniquePtr CertFromPEM(const char *pem) { bssl::UniquePtr bio(BIO_new_mem_buf(pem, strlen(pem))); @@ -1055,7 +1040,7 @@ static bssl::UniquePtr CertFromPEM(const char *pem) { PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)); } -// CRLFromPEM parses the given, NUL-terminated pem block and returns an +// CRLFromPEM parses the given, NUL-terminated PEM block and returns an // |X509_CRL*|. static bssl::UniquePtr CRLFromPEM(const char *pem) { bssl::UniquePtr bio(BIO_new_mem_buf(pem, strlen(pem))); @@ -1063,7 +1048,15 @@ static bssl::UniquePtr CRLFromPEM(const char *pem) { PEM_read_bio_X509_CRL(bio.get(), nullptr, nullptr, nullptr)); } -// PrivateKeyFromPEM parses the given, NUL-terminated pem block and returns an +// CSRFromPEM parses the given, NUL-terminated PEM block and returns an +// |X509_REQ*|. +static bssl::UniquePtr CSRFromPEM(const char *pem) { + bssl::UniquePtr bio(BIO_new_mem_buf(pem, strlen(pem))); + return bssl::UniquePtr( + PEM_read_bio_X509_REQ(bio.get(), nullptr, nullptr, nullptr)); +} + +// PrivateKeyFromPEM parses the given, NUL-terminated PEM block and returns an // |EVP_PKEY*|. static bssl::UniquePtr PrivateKeyFromPEM(const char *pem) { bssl::UniquePtr bio( @@ -1106,14 +1099,13 @@ static bssl::UniquePtr CRLsToStack( return stack; } -static const time_t kReferenceTime = 1474934400 /* Sep 27th, 2016 */; +static const int64_t kReferenceTime = 1474934400 /* Sep 27th, 2016 */; static int Verify( X509 *leaf, const std::vector &roots, const std::vector &intermediates, const std::vector &crls, unsigned long flags = 0, - std::function configure_callback = nullptr, - int (*verify_callback)(int, X509_STORE_CTX *) = nullptr) { + std::function configure_callback = nullptr) { bssl::UniquePtr roots_stack(CertsToStack(roots)); bssl::UniquePtr intermediates_stack( CertsToStack(intermediates)); @@ -1137,11 +1129,11 @@ static int Verify( return X509_V_ERR_UNSPECIFIED; } - X509_STORE_CTX_trusted_stack(ctx.get(), roots_stack.get()); + X509_STORE_CTX_set0_trusted_stack(ctx.get(), roots_stack.get()); X509_STORE_CTX_set0_crls(ctx.get(), crls_stack.get()); X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx.get()); - X509_VERIFY_PARAM_set_time(param, kReferenceTime); + X509_VERIFY_PARAM_set_time_posix(param, kReferenceTime); if (configure_callback) { configure_callback(param); } @@ -1259,6 +1251,31 @@ TEST(X509Test, TestVerify) { } } +#if defined(OPENSSL_THREADS) +// Verifying the same |X509| objects on two threads should be safe. +TEST(X509Test, VerifyThreads) { + bssl::UniquePtr root(CertFromPEM(kRootCAPEM)); + bssl::UniquePtr intermediate(CertFromPEM(kIntermediatePEM)); + bssl::UniquePtr leaf(CertFromPEM(kLeafPEM)); + ASSERT_TRUE(root); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(leaf); + + const size_t kNumThreads = 10; + std::vector threads; + for (size_t i = 0; i < kNumThreads; i++) { + threads.emplace_back([&] { + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{})); + }); + } + for (auto &thread : threads) { + thread.join(); + } +} +#endif // OPENSSL_THREADS + static const char kHostname[] = "example.com"; static const char kWrongHostname[] = "example2.com"; static const char kEmail[] = "test@example.com"; @@ -1374,6 +1391,7 @@ TEST(X509Test, ZeroLengthsWithX509PARAM) { TEST(X509Test, ZeroLengthsWithCheckFunctions) { bssl::UniquePtr leaf(CertFromPEM(kSANTypesLeaf)); + ASSERT_TRUE(leaf); EXPECT_EQ( 1, X509_check_host(leaf.get(), kHostname, strlen(kHostname), 0, nullptr)); @@ -1462,6 +1480,23 @@ TEST(X509Test, TestCRL) { Verify(leaf.get(), {root.get()}, {root.get()}, {algorithm_mismatch_crl2.get()}, X509_V_FLAG_CRL_CHECK)); + // The CRL is valid for a month. + EXPECT_EQ(X509_V_ERR_CRL_HAS_EXPIRED, + Verify(leaf.get(), {root.get()}, {root.get()}, {basic_crl.get()}, + X509_V_FLAG_CRL_CHECK, [](X509_VERIFY_PARAM *param) { + X509_VERIFY_PARAM_set_time_posix( + param, kReferenceTime + 2 * 30 * 24 * 3600); + })); + + // X509_V_FLAG_NO_CHECK_TIME suppresses the validity check. + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {root.get()}, {basic_crl.get()}, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_NO_CHECK_TIME, + [](X509_VERIFY_PARAM *param) { + X509_VERIFY_PARAM_set_time_posix( + param, kReferenceTime + 2 * 30 * 24 * 3600); + })); + // Parsing kBadExtensionCRL should fail. EXPECT_FALSE(CRLFromPEM(kBadExtensionCRL)); } @@ -1725,13 +1760,46 @@ TEST(X509Test, PrintGeneralName) { } TEST(X509Test, TestPSS) { - bssl::UniquePtr cert(CertFromPEM(kExamplePSSCert)); - ASSERT_TRUE(cert); + static const char *kGoodCerts[] = { + "crypto/x509/test/pss_sha256.pem", + "crypto/x509/test/pss_sha384.pem", + "crypto/x509/test/pss_sha512.pem", + // We accept inputs with and without explicit NULLs. See RFC 4055, + // section 2.1. + "crypto/x509/test/pss_sha256_omit_nulls.pem", + // Although invalid, we tolerate an explicit trailerField value. See the + // certificates in cl/362617931. + "crypto/x509/test/pss_sha256_explicit_trailer.pem", + }; + for (const char *path : kGoodCerts) { + SCOPED_TRACE(path); + bssl::UniquePtr cert = CertFromPEM(GetTestData(path).c_str()); + ASSERT_TRUE(cert); + bssl::UniquePtr pkey(X509_get_pubkey(cert.get())); + ASSERT_TRUE(pkey); + EXPECT_TRUE(X509_verify(cert.get(), pkey.get())); + } - bssl::UniquePtr pkey(X509_get_pubkey(cert.get())); - ASSERT_TRUE(pkey); - - ASSERT_TRUE(X509_verify(cert.get(), pkey.get())); + static const char *kBadCerts[] = { + "crypto/x509/test/pss_sha1_explicit.pem", + "crypto/x509/test/pss_sha1_mgf1_syntax_error.pem", + "crypto/x509/test/pss_sha1.pem", + "crypto/x509/test/pss_sha224.pem", + "crypto/x509/test/pss_sha256_mgf1_sha384.pem", + "crypto/x509/test/pss_sha256_mgf1_syntax_error.pem", + "crypto/x509/test/pss_sha256_salt_overflow.pem", + "crypto/x509/test/pss_sha256_salt31.pem", + "crypto/x509/test/pss_sha256_unknown_mgf.pem", + "crypto/x509/test/pss_sha256_wrong_trailer.pem", + }; + for (const char *path : kBadCerts) { + SCOPED_TRACE(path); + bssl::UniquePtr cert = CertFromPEM(GetTestData(path).c_str()); + ASSERT_TRUE(cert); + bssl::UniquePtr pkey(X509_get_pubkey(cert.get())); + ASSERT_TRUE(pkey); + EXPECT_FALSE(X509_verify(cert.get(), pkey.get())); + } } TEST(X509Test, TestPSSBadParameters) { @@ -1804,6 +1872,30 @@ static bssl::UniquePtr ReencodeCertificate(X509 *cert) { return bssl::UniquePtr(d2i_X509(nullptr, &inp, len)); } +static bssl::UniquePtr ReencodeCRL(X509_CRL *crl) { + uint8_t *der = nullptr; + int len = i2d_X509_CRL(crl, &der); + bssl::UniquePtr free_der(der); + if (len <= 0) { + return nullptr; + } + + const uint8_t *inp = der; + return bssl::UniquePtr(d2i_X509_CRL(nullptr, &inp, len)); +} + +static bssl::UniquePtr ReencodeCSR(X509_REQ *req) { + uint8_t *der = nullptr; + int len = i2d_X509_REQ(req, &der); + bssl::UniquePtr free_der(der); + if (len <= 0) { + return nullptr; + } + + const uint8_t *inp = der; + return bssl::UniquePtr(d2i_X509_REQ(nullptr, &inp, len)); +} + static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { // Make a certificate like signed with |md_ctx|'s settings.' bssl::UniquePtr cert(CertFromPEM(kLeafPEM)); @@ -1818,7 +1910,7 @@ static bool SignatureRoundTrips(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { } // Re-encode the certificate. X509 objects contain a cached TBSCertificate - // encoding and |X509_sign_ctx| should have refreshed that cache. + // encoding and |X509_sign_ctx| should have dropped that cache. bssl::UniquePtr copy = ReencodeCertificate(cert.get()); return copy && X509_verify(copy.get(), pkey); } @@ -1832,18 +1924,10 @@ TEST(X509Test, RSASign) { EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get())); ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get())); - // Test RSA-PSS with custom parameters. - md_ctx.Reset(); - EVP_PKEY_CTX *pkey_ctx; - ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL, - pkey.get())); - ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); - ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512())); - ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get())); - // RSA-PSS with salt length matching hash length should work when passing in // -1 or the value explicitly. md_ctx.Reset(); + EVP_PKEY_CTX *pkey_ctx; ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL, pkey.get())); ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); @@ -1856,10 +1940,42 @@ TEST(X509Test, RSASign) { ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 32)); ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get())); + + // RSA-PSS with SHA-1 is not supported. + md_ctx.Reset(); + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha1(), NULL, + pkey.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1)); + bssl::UniquePtr cert = CertFromPEM(kLeafPEM); + ASSERT_TRUE(cert); + EXPECT_FALSE(X509_sign_ctx(cert.get(), md_ctx.get())); + + // RSA-PSS with mismatched hashes is not supported. + md_ctx.Reset(); + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL, + pkey.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512())); + cert = CertFromPEM(kLeafPEM); + ASSERT_TRUE(cert); + EXPECT_FALSE(X509_sign_ctx(cert.get(), md_ctx.get())); + + // RSA-PSS with the wrong salt length is not supported. + md_ctx.Reset(); + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL, + pkey.get())); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)); + ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 33)); + cert = CertFromPEM(kLeafPEM); + ASSERT_TRUE(cert); + EXPECT_FALSE(X509_sign_ctx(cert.get(), md_ctx.get())); } -// Test the APIs for manually signing a certificate. -TEST(X509Test, RSASignManual) { +// Test the APIs for signing a certificate, particularly whether they correctly +// handle the TBSCertificate cache. +TEST(X509Test, SignCertificate) { const int kSignatureNID = NID_sha384WithRSAEncryption; const EVP_MD *kSignatureHash = EVP_sha384(); @@ -1870,68 +1986,285 @@ TEST(X509Test, RSASignManual) { ASSERT_TRUE(X509_ALGOR_set0(algor.get(), OBJ_nid2obj(kSignatureNID), V_ASN1_NULL, nullptr)); - // Test certificates made both from other certificates and |X509_new|, in case - // there are bugs in filling in fields from different states. (Parsed - // certificate contain a TBSCertificate cache, and |X509_new| initializes - // fields based on complex ASN.1 template logic.) - for (bool new_cert : {true, false}) { - SCOPED_TRACE(new_cert); + // Test both signing with |X509_sign| and constructing a signature manually. + for (bool sign_manual : {true, false}) { + SCOPED_TRACE(sign_manual); - bssl::UniquePtr cert; - if (new_cert) { - cert.reset(X509_new()); - // Fill in some fields for the certificate arbitrarily. - EXPECT_TRUE(X509_set_version(cert.get(), X509_VERSION_3)); - EXPECT_TRUE(ASN1_INTEGER_set(X509_get_serialNumber(cert.get()), 1)); - EXPECT_TRUE(X509_gmtime_adj(X509_getm_notBefore(cert.get()), 0)); - EXPECT_TRUE( - X509_gmtime_adj(X509_getm_notAfter(cert.get()), 60 * 60 * 24)); - X509_NAME *subject = X509_get_subject_name(cert.get()); - X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, - reinterpret_cast("Test"), -1, - -1, 0); - EXPECT_TRUE(X509_set_issuer_name(cert.get(), subject)); - EXPECT_TRUE(X509_set_pubkey(cert.get(), pkey.get())); - } else { - // Extract fields from a parsed certificate. - cert = CertFromPEM(kLeafPEM); - ASSERT_TRUE(cert); + // Test certificates made both from other certificates and |X509_new|, in + // case there are bugs in filling in fields from different states. (Parsed + // certificates contain a TBSCertificate cache, and |X509_new| initializes + // fields based on complex ASN.1 template logic.) + for (bool new_cert : {true, false}) { + SCOPED_TRACE(new_cert); - // We should test with a different algorithm from what is already in the - // certificate. - EXPECT_NE(kSignatureNID, X509_get_signature_nid(cert.get())); + bssl::UniquePtr cert; + if (new_cert) { + cert.reset(X509_new()); + ASSERT_TRUE(cert); + // Fill in some fields for the certificate arbitrarily. + EXPECT_TRUE(X509_set_version(cert.get(), X509_VERSION_3)); + EXPECT_TRUE( + ASN1_INTEGER_set_int64(X509_get_serialNumber(cert.get()), 1)); + EXPECT_TRUE(X509_gmtime_adj(X509_getm_notBefore(cert.get()), 0)); + EXPECT_TRUE( + X509_gmtime_adj(X509_getm_notAfter(cert.get()), 60 * 60 * 24)); + X509_NAME *subject = X509_get_subject_name(cert.get()); + X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, + reinterpret_cast("Test"), + -1, -1, 0); + EXPECT_TRUE(X509_set_issuer_name(cert.get(), subject)); + EXPECT_TRUE(X509_set_pubkey(cert.get(), pkey.get())); + } else { + // Extract fields from a parsed certificate. + cert = CertFromPEM(kLeafPEM); + ASSERT_TRUE(cert); + + // We should test with a different algorithm from what is already in the + // certificate. + EXPECT_NE(kSignatureNID, X509_get_signature_nid(cert.get())); + } + + if (sign_manual) { + // Fill in the signature algorithm. + ASSERT_TRUE(X509_set1_signature_algo(cert.get(), algor.get())); + + // Extract the TBSCertificiate. + uint8_t *tbs_cert = nullptr; + int tbs_cert_len = i2d_re_X509_tbs(cert.get(), &tbs_cert); + bssl::UniquePtr free_tbs_cert(tbs_cert); + ASSERT_GT(tbs_cert_len, 0); + + // Generate a signature externally and fill it in. + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, kSignatureHash, + nullptr, pkey.get())); + size_t sig_len; + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), nullptr, &sig_len, tbs_cert, + tbs_cert_len)); + std::vector sig(sig_len); + ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, tbs_cert, + tbs_cert_len)); + sig.resize(sig_len); + ASSERT_TRUE( + X509_set1_signature_value(cert.get(), sig.data(), sig.size())); + } else { + int ret = X509_sign(cert.get(), pkey.get(), EVP_sha384()); + ASSERT_GT(ret, 0); + // |X509_sign| returns the length of the signature on success. + const ASN1_BIT_STRING *sig; + X509_get0_signature(&sig, /*out_alg=*/nullptr, cert.get()); + EXPECT_EQ(ret, ASN1_STRING_length(sig)); + } + + // Check the signature. + EXPECT_TRUE(X509_verify(cert.get(), pkey.get())); + + // Re-encode the certificate. X509 objects contain a cached TBSCertificate + // encoding and re-signing should have dropped that cache. + bssl::UniquePtr copy = ReencodeCertificate(cert.get()); + ASSERT_TRUE(copy); + EXPECT_TRUE(X509_verify(copy.get(), pkey.get())); } + } +} - // Fill in the signature algorithm. - ASSERT_TRUE(X509_set1_signature_algo(cert.get(), algor.get())); +// Test the APIs for signing a CRL, particularly whether they correctly handle +// the TBSCertList cache. +TEST(X509Test, SignCRL) { + const int kSignatureNID = NID_sha384WithRSAEncryption; + const EVP_MD *kSignatureHash = EVP_sha384(); - // Extract the TBSCertificiate. - uint8_t *tbs_cert = nullptr; - int tbs_cert_len = i2d_re_X509_tbs(cert.get(), &tbs_cert); - bssl::UniquePtr free_tbs_cert(tbs_cert); - ASSERT_GT(tbs_cert_len, 0); + bssl::UniquePtr pkey(PrivateKeyFromPEM(kRSAKey)); + ASSERT_TRUE(pkey); + bssl::UniquePtr algor(X509_ALGOR_new()); + ASSERT_TRUE(algor); + ASSERT_TRUE(X509_ALGOR_set0(algor.get(), OBJ_nid2obj(kSignatureNID), + V_ASN1_NULL, nullptr)); - // Generate a signature externally and fill it in. - bssl::ScopedEVP_MD_CTX md_ctx; - ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, kSignatureHash, - nullptr, pkey.get())); - size_t sig_len; - ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), nullptr, &sig_len, tbs_cert, - tbs_cert_len)); - std::vector sig(sig_len); - ASSERT_TRUE(EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, tbs_cert, - tbs_cert_len)); - sig.resize(sig_len); - ASSERT_TRUE(X509_set1_signature_value(cert.get(), sig.data(), sig.size())); + // Test both signing with |X509_CRL_sign| and constructing a signature + // manually. + for (bool sign_manual : {true, false}) { + SCOPED_TRACE(sign_manual); - // Check the signature. - EXPECT_TRUE(X509_verify(cert.get(), pkey.get())); + // Test CRLs made both from other CRLs and |X509_CRL_new|, in case there are + // bugs in filling in fields from different states. (Parsed CRLs contain a + // TBSCertList cache, and |X509_CRL_new| initializes fields based on complex + // ASN.1 template logic.) + for (bool new_crl : {true, false}) { + SCOPED_TRACE(new_crl); - // Re-encode the certificate. X509 objects contain a cached TBSCertificate - // encoding and |i2d_re_X509_tbs| should have refreshed that cache. - bssl::UniquePtr copy = ReencodeCertificate(cert.get()); - ASSERT_TRUE(copy); - EXPECT_TRUE(X509_verify(copy.get(), pkey.get())); + bssl::UniquePtr crl; + if (new_crl) { + crl.reset(X509_CRL_new()); + ASSERT_TRUE(crl); + // Fill in some fields for the certificate arbitrarily. + ASSERT_TRUE(X509_CRL_set_version(crl.get(), X509_CRL_VERSION_2)); + bssl::UniquePtr last_update(ASN1_TIME_new()); + ASSERT_TRUE(last_update); + ASSERT_TRUE(ASN1_TIME_set_posix(last_update.get(), kReferenceTime)); + ASSERT_TRUE(X509_CRL_set1_lastUpdate(crl.get(), last_update.get())); + bssl::UniquePtr issuer(X509_NAME_new()); + ASSERT_TRUE(issuer); + ASSERT_TRUE(X509_NAME_add_entry_by_txt( + issuer.get(), "CN", MBSTRING_ASC, + reinterpret_cast("Test"), -1, -1, 0)); + EXPECT_TRUE(X509_CRL_set_issuer_name(crl.get(), issuer.get())); + } else { + // Extract fields from a parsed CRL. + crl = CRLFromPEM(kBasicCRL); + ASSERT_TRUE(crl); + + // We should test with a different algorithm from what is already in the + // CRL. + EXPECT_NE(kSignatureNID, X509_CRL_get_signature_nid(crl.get())); + } + + if (sign_manual) { + // Fill in the signature algorithm. + ASSERT_TRUE(X509_CRL_set1_signature_algo(crl.get(), algor.get())); + + // Extract the TBSCertList. + uint8_t *tbs = nullptr; + int tbs_len = i2d_re_X509_CRL_tbs(crl.get(), &tbs); + bssl::UniquePtr free_tbs(tbs); + ASSERT_GT(tbs_len, 0); + + // Generate a signature externally and fill it in. + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, kSignatureHash, + nullptr, pkey.get())); + size_t sig_len; + ASSERT_TRUE( + EVP_DigestSign(md_ctx.get(), nullptr, &sig_len, tbs, tbs_len)); + std::vector sig(sig_len); + ASSERT_TRUE( + EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, tbs, tbs_len)); + sig.resize(sig_len); + ASSERT_TRUE( + X509_CRL_set1_signature_value(crl.get(), sig.data(), sig.size())); + } else { + ASSERT_TRUE(X509_CRL_sign(crl.get(), pkey.get(), EVP_sha384())); + } + + // Check the signature. + EXPECT_TRUE(X509_CRL_verify(crl.get(), pkey.get())); + + // Re-encode the CRL. X509_CRL objects contain a cached TBSCertList + // encoding and re-signing should have dropped that cache. + bssl::UniquePtr copy = ReencodeCRL(crl.get()); + ASSERT_TRUE(copy); + EXPECT_TRUE(X509_CRL_verify(copy.get(), pkey.get())); + } + } +} + +static const char kTestCSR[] = R"( +-----BEGIN CERTIFICATE REQUEST----- +MIICVDCCATwCAQAwDzENMAsGA1UEAwwEVGVzdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAK+UkwcNJfRhg5MzIQzxDdrqF9a76jNoK/BwCflKYFX7QEqf +rsLkI0J+m60fUD0v50LnKwbGoMFKZ1R/3cBNXLcdXb7ZP/ZJ7A7QwUrL+W9n3sov +U8/HSU3rHbg+V5L6egSZYuhDHoXKi33HDOL4DVUzMoU1ykmP4QwF1wUXHLqvqjbU +teQBoJWO53/XOGQu8bX04muCFnHZWT2Ubqol70JwPU2PqDU1EBlgUFO79NEmflev +b++H8tu42UCDUZXD9k5weftjneO4cud3IsUX6mDsyf7k1e2mxsS4TSZsJcG0iLBX +HSr1udXazQsjlAKjJkoI3cWshF6LGRWssAtbGiUCAwEAAaAAMA0GCSqGSIb3DQEB +CwUAA4IBAQAniYZL+amXu+wED+AwBZz+zPuxY16bveF27/gxcs/jq6hVpEQvMxfO +jfAGeDRtAU7DMxdJPjvWwwNe2JlTMSRoVDMYaiKqB5yxIYa2cjQvp7swSxuFJwbG +T8h7/d7yqem6NYYzgYsNOE5QJyNu/PsIEdvzrysfDAnREiT2ituOcVpiqUZq3DTj +NaTd1GNG3j4E87ZUmayUJD5nH91UNzKvJbpfo+bLyfy73x4QeU0SRitsZmbSBTAi +s9+zmCErxzMlAdJHGzxPkXmtvBnUzGRIsAD5h/DjYNUmQJkB60yplt84ZgThhx54 +rZGEJG3+X9OuhczVKGJyg+3gU7oDbecc +-----END CERTIFICATE REQUEST----- +)"; + +// Test the APIs for signing a CSR, particularly whether they correctly handle +// the CertificationRequestInfo cache. +TEST(X509Test, SignCSR) { + const int kSignatureNID = NID_sha384WithRSAEncryption; + const EVP_MD *kSignatureHash = EVP_sha384(); + + bssl::UniquePtr pkey(PrivateKeyFromPEM(kRSAKey)); + ASSERT_TRUE(pkey); + bssl::UniquePtr algor(X509_ALGOR_new()); + ASSERT_TRUE(algor); + ASSERT_TRUE(X509_ALGOR_set0(algor.get(), OBJ_nid2obj(kSignatureNID), + V_ASN1_NULL, nullptr)); + + // Test both signing with |X509_REQ_sign| and constructing a signature + // manually. + for (bool sign_manual : {true, false}) { + SCOPED_TRACE(sign_manual); + + // Test CSRs made both from other CSRs and |X509_REQ_new|, in case there are + // bugs in filling in fields from different states. (Parsed CSRs contain a + // CertificationRequestInfo cache, and |X509_REQ_new| initializes fields + // based on complex ASN.1 template logic.) + for (bool new_csr : {true, false}) { + SCOPED_TRACE(new_csr); + + bssl::UniquePtr csr; + if (new_csr) { + csr.reset(X509_REQ_new()); + ASSERT_TRUE(csr); + bssl::UniquePtr subject(X509_NAME_new()); + ASSERT_TRUE(subject); + ASSERT_TRUE(X509_NAME_add_entry_by_txt( + subject.get(), "CN", MBSTRING_ASC, + reinterpret_cast("New CSR"), -1, -1, 0)); + EXPECT_TRUE(X509_REQ_set_subject_name(csr.get(), subject.get())); + } else { + // Extract fields from a parsed CSR. + csr = CSRFromPEM(kTestCSR); + ASSERT_TRUE(csr); + } + + // Override the public key from the CSR unconditionally. Unlike + // certificates and CRLs, CSRs do not contain a signed copy of the + // signature algorithm, so we use a different field to confirm + // |i2d_re_X509_REQ_tbs| clears the cache as expected. + EXPECT_TRUE(X509_REQ_set_pubkey(csr.get(), pkey.get())); + + if (sign_manual) { + // Fill in the signature algorithm. + ASSERT_TRUE(X509_REQ_set1_signature_algo(csr.get(), algor.get())); + + // Extract the CertificationRequestInfo. + uint8_t *tbs = nullptr; + int tbs_len = i2d_re_X509_REQ_tbs(csr.get(), &tbs); + bssl::UniquePtr free_tbs(tbs); + ASSERT_GT(tbs_len, 0); + + // Generate a signature externally and fill it in. + bssl::ScopedEVP_MD_CTX md_ctx; + ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), nullptr, kSignatureHash, + nullptr, pkey.get())); + size_t sig_len; + ASSERT_TRUE( + EVP_DigestSign(md_ctx.get(), nullptr, &sig_len, tbs, tbs_len)); + std::vector sig(sig_len); + ASSERT_TRUE( + EVP_DigestSign(md_ctx.get(), sig.data(), &sig_len, tbs, tbs_len)); + sig.resize(sig_len); + ASSERT_TRUE( + X509_REQ_set1_signature_value(csr.get(), sig.data(), sig.size())); + } else { + ASSERT_TRUE(X509_REQ_sign(csr.get(), pkey.get(), EVP_sha384())); + } + + // Check the signature. + EXPECT_TRUE(X509_REQ_verify(csr.get(), pkey.get())); + + // Re-encode the CSR. X509_REQ objects contain a cached + // CertificationRequestInfo encoding and re-signing should have dropped + // that cache. + bssl::UniquePtr copy = ReencodeCSR(csr.get()); + ASSERT_TRUE(copy); + EXPECT_TRUE(X509_REQ_verify(copy.get(), pkey.get())); + + // Check the signature was over the new public key. + bssl::UniquePtr copy_pubkey(X509_REQ_get_pubkey(copy.get())); + ASSERT_TRUE(copy_pubkey); + EXPECT_EQ(1, EVP_PKEY_cmp(pkey.get(), copy_pubkey.get())); + } } } @@ -2027,7 +2360,7 @@ TEST(X509Test, TestFromBufferModified) { ASSERT_TRUE(root); bssl::UniquePtr fourty_two(ASN1_INTEGER_new()); - ASN1_INTEGER_set(fourty_two.get(), 42); + ASN1_INTEGER_set_int64(fourty_two.get(), 42); X509_set_serialNumber(root.get(), fourty_two.get()); ASSERT_EQ(static_cast(data_len), i2d_X509(root.get(), nullptr)); @@ -2053,12 +2386,25 @@ TEST(X509Test, TestFromBufferReused) { size_t data2_len; bssl::UniquePtr data2; ASSERT_TRUE(PEMToDER(&data2, &data2_len, kLeafPEM)); + EXPECT_TRUE(buffers_alias(root->cert_info->enc.enc, root->cert_info->enc.len, + CRYPTO_BUFFER_data(buf.get()), + CRYPTO_BUFFER_len(buf.get()))); - X509 *x509p = root.get(); + // Historically, this function tested the interaction betweeen + // |X509_parse_from_buffer| and object reuse. We no longer support object + // reuse, so |d2i_X509| will replace |raw| with a new object. However, we + // retain this test to verify that releasing objects from |d2i_X509| works + // correctly. + X509 *raw = root.release(); const uint8_t *inp = data2.get(); - X509 *ret = d2i_X509(&x509p, &inp, data2_len); + X509 *ret = d2i_X509(&raw, &inp, data2_len); + root.reset(raw); + ASSERT_EQ(root.get(), ret); - ASSERT_EQ(nullptr, root->buf); + ASSERT_EQ(nullptr, root->cert_info->enc.buf); + EXPECT_FALSE(buffers_alias(root->cert_info->enc.enc, root->cert_info->enc.len, + CRYPTO_BUFFER_data(buf.get()), + CRYPTO_BUFFER_len(buf.get()))); // Free |data2| and ensure that |root| took its own copy. Otherwise the // following will trigger a use-after-free. @@ -2073,7 +2419,7 @@ TEST(X509Test, TestFromBufferReused) { ASSERT_EQ(static_cast(data2_len), i2d_len); ASSERT_EQ(0, OPENSSL_memcmp(data2.get(), i2d, i2d_len)); - ASSERT_EQ(nullptr, root->buf); + ASSERT_EQ(nullptr, root->cert_info->enc.buf); } TEST(X509Test, TestFailedParseFromBuffer) { @@ -2121,10 +2467,10 @@ TEST(X509Test, TestPrintUTCTIME) { {"000000000000Z", "Bad time value"}, {"999999999999Z", "Bad time value"}, - // Missing components. Not legal RFC 5280, but permitted. - {"090303125425", "Mar 3 12:54:25 2009"}, - {"9003031254", "Mar 3 12:54:00 1990"}, - {"9003031254Z", "Mar 3 12:54:00 1990 GMT"}, + // Missing components. + {"090303125425", "Bad time value"}, + {"9003031254", "Bad time value"}, + {"9003031254Z", "Bad time value"}, // GENERALIZEDTIME confused for UTCTIME. {"20090303125425Z", "Bad time value"}, @@ -2140,7 +2486,9 @@ TEST(X509Test, TestPrintUTCTIME) { for (auto t : asn1_utctime_tests) { SCOPED_TRACE(t.val); bssl::UniquePtr tm(ASN1_UTCTIME_new()); + ASSERT_TRUE(tm); bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio); // Use this instead of ASN1_UTCTIME_set() because some callers get // type-confused and pass ASN1_GENERALIZEDTIME to ASN1_UTCTIME_print(). @@ -2198,6 +2546,7 @@ TEST(X509Test, PrettyPrintIntegers) { TEST(X509Test, X509NameSet) { bssl::UniquePtr name(X509_NAME_new()); + ASSERT_TRUE(name); EXPECT_TRUE(X509_NAME_add_entry_by_txt( name.get(), "C", MBSTRING_ASC, reinterpret_cast("US"), -1, -1, 0)); @@ -2220,6 +2569,67 @@ TEST(X509Test, X509NameSet) { EXPECT_EQ(X509_NAME_ENTRY_set(X509_NAME_get_entry(name.get(), 2)), 2); } +// Tests that |X509_NAME_hash| and |X509_NAME_hash_old|'s values never change. +// These functions figure into |X509_LOOKUP_hash_dir|'s on-disk format, so they +// must remain stable. In particular, if we ever remove name canonicalization, +// we'll need to preserve it for |X509_NAME_hash|. +TEST(X509Test, NameHash) { + struct { + std::vector name_der; + unsigned long hash; + unsigned long hash_old; + } kTests[] = { + // SEQUENCE { + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "Test Name" } + // } + // } + // } + {{0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x65}, + 0xc90fba01, + 0x8c0d4fea}, + + // This name canonicalizes to the same value, with OpenSSL's algorithm, as + // the above input, so |hash| matches. |hash_old| doesn't use + // canonicalization and does not match. + // + // SEQUENCE { + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // BMPString { + // u"\x09\n\x0b\x0c\x0d tEST\x09\n\x0b\x0c\x0d " + // u"\x09\n\x0b\x0c\x0d nAME\x09\n\x0b\x0c\x0d " + // } + // } + // } + // } + {{0x30, 0x4b, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x1e, 0x40, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, + 0x0d, 0x00, 0x20, 0x00, 0x74, 0x00, 0x45, 0x00, 0x53, 0x00, 0x54, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, + 0x20, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, + 0x00, 0x20, 0x00, 0x6e, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x45, 0x00, + 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x20}, + 0xc90fba01, + 0xbe2dd8c8}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(Bytes(t.name_der)); + const uint8_t *der = t.name_der.data(); + bssl::UniquePtr name( + d2i_X509_NAME(nullptr, &der, t.name_der.size())); + ASSERT_TRUE(name); + EXPECT_EQ(t.hash, X509_NAME_hash(name.get())); + EXPECT_EQ(t.hash_old, X509_NAME_hash_old(name.get())); + } +} + TEST(X509Test, NoBasicConstraintsCertSign) { bssl::UniquePtr root(CertFromPEM(kSANTypesRoot)); bssl::UniquePtr intermediate( @@ -2871,12 +3281,81 @@ MlJhXnXJFA== -----END CERTIFICATE----- )"; -// Test that the X.509 parser enforces versions are valid and match the fields +// kV1CRLWithExtensionsPEM is a v1 CRL with extensions. +static const char kV1CRLWithExtensionsPEM[] = R"( +-----BEGIN X509 CRL----- +MIIBpDCBjTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UECAwK +Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJQm9y +aW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoA4wDDAKBgNVHRQE +AwIBATANBgkqhkiG9w0BAQsFAAOCAQEAnrBKKgvd9x9zwK9rtUvVeFeJ7+LNZEAc ++a5oxpPNEsJx6hXoApYEbzXMxuWBQoCs5iEBycSGudct21L+MVf27M38KrWoeOkq +0a2siqViQZO2Fb/SUFR0k9zb8xl86Zf65lgPplALun0bV/HT7MJcl04Tc4osdsAR +eBs5nqTGNEd5AlC1iKHvQZkM//MD51DspKnDpsDiUVi54h9C1SpfZmX8H2Vvdiyu +0fZ/bPAM3VAGawatf/SyWfBMyKpoPXEG39oAzmjjOj8en82psn7m474IGaho/vBb +hl1ms5qQiLYPjm4YELtnXQoFyC72tBjbdFd/ZE9k4CNKDbxFUXFbkw== +-----END X509 CRL----- +)"; + +// kExplicitDefaultVersionCRLPEM is a v1 CRL with an explicitly-encoded version +// field. +static const char kExplicitDefaultVersionCRLPEM[] = R"( +-----BEGIN X509 CRL----- +MIIBlzCBgAIBADANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ +Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaMA0GCSqGSIb3 +DQEBCwUAA4IBAQCesEoqC933H3PAr2u1S9V4V4nv4s1kQBz5rmjGk80SwnHqFegC +lgRvNczG5YFCgKzmIQHJxIa51y3bUv4xV/bszfwqtah46SrRrayKpWJBk7YVv9JQ +VHST3NvzGXzpl/rmWA+mUAu6fRtX8dPswlyXThNziix2wBF4GzmepMY0R3kCULWI +oe9BmQz/8wPnUOykqcOmwOJRWLniH0LVKl9mZfwfZW92LK7R9n9s8AzdUAZrBq1/ +9LJZ8EzIqmg9cQbf2gDOaOM6Px6fzamyfubjvggZqGj+8FuGXWazmpCItg+ObhgQ +u2ddCgXILva0GNt0V39kT2TgI0oNvEVRcVuT +-----END X509 CRL----- +)"; + +// kV3CRLPEM is a v3 CRL. CRL versions only go up to v2. +static const char kV3CRLPEM[] = R"( +-----BEGIN X509 CRL----- +MIIBpzCBkAIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ +Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoA4wDDAKBgNV +HRQEAwIBATANBgkqhkiG9w0BAQsFAAOCAQEAnrBKKgvd9x9zwK9rtUvVeFeJ7+LN +ZEAc+a5oxpPNEsJx6hXoApYEbzXMxuWBQoCs5iEBycSGudct21L+MVf27M38KrWo +eOkq0a2siqViQZO2Fb/SUFR0k9zb8xl86Zf65lgPplALun0bV/HT7MJcl04Tc4os +dsAReBs5nqTGNEd5AlC1iKHvQZkM//MD51DspKnDpsDiUVi54h9C1SpfZmX8H2Vv +diyu0fZ/bPAM3VAGawatf/SyWfBMyKpoPXEG39oAzmjjOj8en82psn7m474IGaho +/vBbhl1ms5qQiLYPjm4YELtnXQoFyC72tBjbdFd/ZE9k4CNKDbxFUXFbkw== +-----END X509 CRL----- +)"; + +// kV2CSRPEM is a v2 CSR. CSR versions only go up to v1. +static const char kV2CSRPEM[] = R"( +-----BEGIN CERTIFICATE REQUEST----- +MIHJMHECAQEwDzENMAsGA1UEAwwEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABJjsayyAQod1J7UJYNT8AH4WWxLdKV0ozhrIz6hCzBAze7AqXWOSH8G+1EWC +pSfL3oMQNtBdJS0kpXXaUqEAgTSgADAKBggqhkjOPQQDAgNIADBFAiAUXVaEYATg +4Cc917T73KBImxh6xyhsA5pKuYpq1S4m9wIhAK+G93HR4ur7Ghel6+zUTvIAsj9e +rsn4lSYsqI4OI4ei +-----END CERTIFICATE REQUEST----- +)"; + +// kV3CSRPEM is a v3 CSR. CSR versions only go up to v1. +static const char kV3CSRPEM[] = R"( +-----BEGIN CERTIFICATE REQUEST----- +MIHJMHECAQIwDzENMAsGA1UEAwwEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABJjsayyAQod1J7UJYNT8AH4WWxLdKV0ozhrIz6hCzBAze7AqXWOSH8G+1EWC +pSfL3oMQNtBdJS0kpXXaUqEAgTSgADAKBggqhkjOPQQDAgNIADBFAiAUXVaEYATg +4Cc917T73KBImxh6xyhsA5pKuYpq1S4m9wIhAK+G93HR4ur7Ghel6+zUTvIAsj9e +rsn4lSYsqI4OI4ei +-----END CERTIFICATE REQUEST----- +)"; + +// Test that the library enforces versions are valid and match the fields // present. TEST(X509Test, InvalidVersion) { // kExplicitDefaultVersionPEM is invalid but, for now, we accept it. See // https://crbug.com/boringssl/364. EXPECT_TRUE(CertFromPEM(kExplicitDefaultVersionPEM)); + EXPECT_TRUE(CRLFromPEM(kExplicitDefaultVersionCRLPEM)); EXPECT_FALSE(CertFromPEM(kNegativeVersionPEM)); EXPECT_FALSE(CertFromPEM(kFutureVersionPEM)); @@ -2885,6 +3364,31 @@ TEST(X509Test, InvalidVersion) { EXPECT_FALSE(CertFromPEM(kV2WithExtensionsPEM)); EXPECT_FALSE(CertFromPEM(kV1WithIssuerUniqueIDPEM)); EXPECT_FALSE(CertFromPEM(kV1WithSubjectUniqueIDPEM)); + EXPECT_FALSE(CRLFromPEM(kV1CRLWithExtensionsPEM)); + EXPECT_FALSE(CRLFromPEM(kV3CRLPEM)); + EXPECT_FALSE(CSRFromPEM(kV2CSRPEM)); + + // kV3CSRPEM is invalid but, for now, we accept it. See + // https://github.com/certbot/certbot/pull/9334 + EXPECT_TRUE(CSRFromPEM(kV3CSRPEM)); + + bssl::UniquePtr x509(X509_new()); + ASSERT_TRUE(x509); + EXPECT_FALSE(X509_set_version(x509.get(), -1)); + EXPECT_FALSE(X509_set_version(x509.get(), X509_VERSION_3 + 1)); + EXPECT_FALSE(X509_set_version(x509.get(), 9999)); + + bssl::UniquePtr crl(X509_CRL_new()); + ASSERT_TRUE(crl); + EXPECT_FALSE(X509_CRL_set_version(crl.get(), -1)); + EXPECT_FALSE(X509_CRL_set_version(crl.get(), X509_CRL_VERSION_2 + 1)); + EXPECT_FALSE(X509_CRL_set_version(crl.get(), 9999)); + + bssl::UniquePtr req(X509_REQ_new()); + ASSERT_TRUE(req); + EXPECT_FALSE(X509_REQ_set_version(req.get(), -1)); + EXPECT_FALSE(X509_REQ_set_version(req.get(), X509_REQ_VERSION_1 + 1)); + EXPECT_FALSE(X509_REQ_set_version(req.get(), 9999)); } // Unlike upstream OpenSSL, we require a non-null store in @@ -3105,6 +3609,8 @@ TEST(X509Test, GeneralName) { {0x82, 0x01, 0x61}, // [2 PRIMITIVE] { "b" } {0x82, 0x01, 0x62}, + // [3] {} + {0xa3, 0x00}, // [4] { // SEQUENCE { // SET { @@ -3202,6 +3708,12 @@ TEST(X509Test, GeneralName) { ASSERT_TRUE(a); ASSERT_EQ(ptr, kNames[i].data() + kNames[i].size()); + uint8_t *enc = nullptr; + int enc_len = i2d_GENERAL_NAME(a.get(), &enc); + ASSERT_GE(enc_len, 0); + bssl::UniquePtr free_enc(enc); + EXPECT_EQ(Bytes(enc, enc_len), Bytes(kNames[i])); + for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(kNames); j++) { SCOPED_TRACE(Bytes(kNames[j])); @@ -3464,6 +3976,95 @@ TEST(X509Test, TrustedFirst) { })); } +// Test that notBefore and notAfter checks work correctly. +TEST(X509Test, Expiry) { + bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); + ASSERT_TRUE(key); + + // The following are measured in seconds relative to kReferenceTime. The + // validity periods are staggered so we can independently test both leaf and + // root time checks. + const int64_t kSecondsInDay = 24 * 3600; + const int64_t kRootStart = -30 * kSecondsInDay; + const int64_t kIntermediateStart = -20 * kSecondsInDay; + const int64_t kLeafStart = -10 * kSecondsInDay; + const int64_t kIntermediateEnd = 10 * kSecondsInDay; + const int64_t kLeafEnd = 20 * kSecondsInDay; + const int64_t kRootEnd = 30 * kSecondsInDay; + + bssl::UniquePtr root = + MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true); + ASSERT_TRUE(root); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(root.get()), kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kRootStart)); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(root.get()), kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kRootEnd)); + ASSERT_TRUE(X509_sign(root.get(), key.get(), EVP_sha256())); + + bssl::UniquePtr intermediate = + MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true); + ASSERT_TRUE(intermediate); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(intermediate.get()), + kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kIntermediateStart)); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(intermediate.get()), + kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kIntermediateEnd)); + ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256())); + + bssl::UniquePtr leaf = + MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(leaf); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notBefore(leaf.get()), kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kLeafStart)); + ASSERT_TRUE(ASN1_TIME_adj(X509_getm_notAfter(leaf.get()), kReferenceTime, + /*offset_day=*/0, + /*offset_sec=*/kLeafEnd)); + ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256())); + + struct VerifyAt { + int64_t time; + void operator()(X509_VERIFY_PARAM *param) const { + X509_VERIFY_PARAM_set_time_posix(param, time); + } + }; + + for (bool check_time : {true, false}) { + SCOPED_TRACE(check_time); + unsigned long flags = check_time ? 0 : X509_V_FLAG_NO_CHECK_TIME; + int not_yet_valid = check_time ? X509_V_ERR_CERT_NOT_YET_VALID : X509_V_OK; + int has_expired = check_time ? X509_V_ERR_CERT_HAS_EXPIRED : X509_V_OK; + + EXPECT_EQ(not_yet_valid, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kRootStart - 1})); + EXPECT_EQ(not_yet_valid, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kIntermediateStart - 1})); + EXPECT_EQ(not_yet_valid, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kLeafStart - 1})); + + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()}, + {}, flags, VerifyAt{kReferenceTime})); + + EXPECT_EQ(has_expired, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kRootEnd + 1})); + EXPECT_EQ(has_expired, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kIntermediateEnd + 1})); + EXPECT_EQ(has_expired, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, flags, + VerifyAt{kReferenceTime + kLeafEnd + 1})); + } +} + // kConstructedBitString is an X.509 certificate where the signature is encoded // as a BER constructed BIT STRING. Note that, while OpenSSL's parser accepts // this input, it interprets the value incorrectly. @@ -3524,6 +4125,62 @@ BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQB -----END CERTIFICATE----- )"; +// kHighTagNumber is an X.509 certificate where the outermost SEQUENCE tag uses +// high tag number form. +static const char kHighTagNumber[] = R"( +-----BEGIN CERTIFICATE----- +PxCCASAwgcagAwIBAgICBNIwCgYIKoZIzj0EAwIwDzENMAsGA1UEAxMEVGVzdDAg +Fw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UEAxMEVGVz +dDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8eDZSKTNWXa7ep +Hg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQtS89yIsGjEDAO +MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAKnSIhfmzfQpeOKFHiAq +cml3ex6oaVVGoJWCsPQoZjVAAiEAqTHS9HzZBTQ20cMPXUpf8u5AXZP7adeh4qnk +soBsxWI= +-----END CERTIFICATE----- +)"; + +// kNonMinimalLengthOuter is an X.509 certificate where the outermost SEQUENCE +// has a non-minimal length. +static const char kNonMinimalLengthOuter[] = R"( +-----BEGIN CERTIFICATE----- +MIMAASAwgcagAwIBAgICBNIwCgYIKoZIzj0EAwIwDzENMAsGA1UEAxMEVGVzdDAg +Fw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UEAxMEVGVz +dDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8eDZSKTNWXa7ep +Hg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQtS89yIsGjEDAO +MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAKnSIhfmzfQpeOKFHiAq +cml3ex6oaVVGoJWCsPQoZjVAAiEAqTHS9HzZBTQ20cMPXUpf8u5AXZP7adeh4qnk +soBsxWI= +-----END CERTIFICATE----- +)"; + +// kNonMinimalLengthSignature is an X.509 certificate where the signature has a +// non-minimal length. +static const char kNonMinimalLengthSignature[] = R"( +-----BEGIN CERTIFICATE----- +MIIBITCBxqADAgECAgIE0jAKBggqhkjOPQQDAjAPMQ0wCwYDVQQDEwRUZXN0MCAX +DTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAPMQ0wCwYDVQQDEwRUZXN0 +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6ke +DUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwaMQMA4w +DAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgOBSQAwRgIhAKnSIhfmzfQpeOKFHiAq +cml3ex6oaVVGoJWCsPQoZjVAAiEAqTHS9HzZBTQ20cMPXUpf8u5AXZP7adeh4qnk +soBsxWI= +-----END CERTIFICATE----- +)"; + +// kNonMinimalLengthSerial is an X.509 certificate where the serial number has a +// non-minimal length. +static const char kNonMinimalLengthSerial[] = R"( +-----BEGIN CERTIFICATE----- +MIIBITCBx6ADAgECAoECBNIwCgYIKoZIzj0EAwIwDzENMAsGA1UEAxMEVGVzdDAg +Fw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UEAxMEVGVz +dDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8eDZSKTNWXa7ep +Hg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQtS89yIsGjEDAO +MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAKnSIhfmzfQpeOKFHiAq +cml3ex6oaVVGoJWCsPQoZjVAAiEAqTHS9HzZBTQ20cMPXUpf8u5AXZP7adeh4qnk +soBsxWI= +-----END CERTIFICATE----- +)"; + TEST(X509Test, BER) { // Constructed strings are forbidden in DER. EXPECT_FALSE(CertFromPEM(kConstructedBitString)); @@ -3532,4 +4189,2453 @@ TEST(X509Test, BER) { EXPECT_FALSE(CertFromPEM(kIndefiniteLength)); // Padding bits in BIT STRINGs must be zero in BER. EXPECT_FALSE(CertFromPEM(kNonZeroPadding)); + // Tags must be minimal in both BER and DER, though many BER decoders + // incorrectly support non-minimal tags. + EXPECT_FALSE(CertFromPEM(kHighTagNumber)); + // Lengths must be minimal in DER. + EXPECT_FALSE(CertFromPEM(kNonMinimalLengthOuter)); + EXPECT_FALSE(CertFromPEM(kNonMinimalLengthSerial)); + // We, for now, accept a non-minimal length in the signature field. See + // b/18228011. + EXPECT_TRUE(CertFromPEM(kNonMinimalLengthSignature)); +} + +TEST(X509Test, Names) { + bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); + ASSERT_TRUE(key); + bssl::UniquePtr root = + MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true); + ASSERT_TRUE(root); + ASSERT_TRUE(X509_sign(root.get(), key.get(), EVP_sha256())); + + struct { + std::vector> cert_subject; + std::vector cert_dns_names; + std::vector cert_emails; + std::vector valid_dns_names; + std::vector invalid_dns_names; + std::vector valid_emails; + std::vector invalid_emails; + unsigned flags; + } kTests[] = { + // DNS names only match DNS names and do so case-insensitively. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{"example.com", "WWW.EXAMPLE.COM"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/ + {"example.com", "EXAMPLE.COM", "www.example.com", "WWW.EXAMPLE.COM"}, + /*invalid_dns_names=*/{"test.example.com", "example.org"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{"test@example.com", "example.com"}, + /*flags=*/0, + }, + + // DNS wildcards match exactly one component. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{"*.example.com", "*.EXAMPLE.ORG"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/ + {"www.example.com", "WWW.EXAMPLE.COM", "www.example.org", + "WWW.EXAMPLE.ORG"}, + /*invalid_dns_names=*/{"example.com", "test.www.example.com"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{"test@example.com", "www.example.com"}, + /*flags=*/0, + }, + + // DNS wildcards can be disabled. + // TODO(davidben): Can we remove this feature? Does anyone use it? + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{"example.com", "*.example.com"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{"example.com"}, + /*invalid_dns_names=*/{"www.example.com"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/X509_CHECK_FLAG_NO_WILDCARDS, + }, + + // Invalid DNS wildcards do not match. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/ + {"a.*", "**.b.example", "*c.example", "d*.example", "e*e.example", + "*", ".", "..", "*."}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/ + {"a.example", "test.b.example", "cc.example", "dd.example", + "eee.example", "f", "g."}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // IDNs match like any other DNS labels. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/ + {"xn--rger-koa.a.example", "*.xn--rger-koa.b.example", + "www.xn--rger-koa.c.example"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/ + {"xn--rger-koa.a.example", "www.xn--rger-koa.b.example", + "www.xn--rger-koa.c.example"}, + /*invalid_dns_names=*/ + {"www.xn--rger-koa.a.example", "xn--rger-koa.b.example", + "www.xn--rger-koa.d.example"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // For now, DNS names are also extracted out of the common name, but only + // there is no SAN list. + // TODO(https://crbug.com/boringssl/464): Remove this. + { + /*cert_subject=*/{{NID_commonName, "a.example"}, + {NID_commonName, "*.b.example"}}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{}, + /*valid_dns_names=*/ + {"a.example", "A.EXAMPLE", "test.b.example", "TEST.B.EXAMPLE"}, + /*invalid_dns_names=*/{}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + { + /*cert_subject=*/{{NID_commonName, "a.example"}, + {NID_commonName, "*.b.example"}}, + /*cert_dns_names=*/{"example.com"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/ + {"a.example", "A.EXAMPLE", "test.b.example", "TEST.B.EXAMPLE"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // Other subject RDNs do not provide DNS names. + { + /*cert_subject=*/{{NID_organizationName, "example.com"}}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/{"example.com"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // Input DNS names cannot have wildcards. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{"www.example.com"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/{"*.example.com"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // OpenSSL has some non-standard wildcard syntax for input DNS names. We + // do not support this. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{"www.a.example", "*.b.test"}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/ + {".www.a.example", ".www.b.test", ".a.example", ".b.test", ".example", + ".test"}, + /*valid_emails=*/{}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + + // Emails match case-sensitively before the '@' and case-insensitively + // after. They do not match DNS names. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{"test@a.example", "TEST@B.EXAMPLE"}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/{"a.example", "b.example"}, + /*valid_emails=*/ + {"test@a.example", "test@A.EXAMPLE", "TEST@b.example", + "TEST@B.EXAMPLE"}, + /*invalid_emails=*/ + {"TEST@a.example", "test@B.EXAMPLE", "another-test@a.example", + "est@a.example"}, + /*flags=*/0, + }, + + // Emails may also be found in the subject. + { + /*cert_subject=*/{{NID_pkcs9_emailAddress, "test@a.example"}, + {NID_pkcs9_emailAddress, "TEST@B.EXAMPLE"}}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/{"a.example", "b.example"}, + /*valid_emails=*/ + {"test@a.example", "test@A.EXAMPLE", "TEST@b.example", + "TEST@B.EXAMPLE"}, + /*invalid_emails=*/ + {"TEST@a.example", "test@B.EXAMPLE", "another-test@a.example", + "est@a.example"}, + /*flags=*/0, + }, + + // There are no email wildcard names. + { + /*cert_subject=*/{}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{"test@*.a.example", "@b.example", "*@c.example"}, + /*valid_dns_names=*/{}, + /*invalid_dns_names=*/{}, + /*valid_emails=*/{}, + /*invalid_emails=*/ + {"test@test.a.example", "test@b.example", "test@c.example"}, + /*flags=*/0, + }, + + // Unrelated RDNs can be skipped when looking in the subject. + { + /*cert_subject=*/{{NID_organizationName, "Acme Corporation"}, + {NID_commonName, "a.example"}, + {NID_pkcs9_emailAddress, "test@b.example"}, + {NID_countryName, "US"}}, + /*cert_dns_names=*/{}, + /*cert_emails=*/{}, + /*valid_dns_names=*/{"a.example"}, + /*invalid_dns_names=*/{}, + /*valid_emails=*/{"test@b.example"}, + /*invalid_emails=*/{}, + /*flags=*/0, + }, + }; + + size_t i = 0; + for (const auto &t : kTests) { + SCOPED_TRACE(i++); + + // Issue a test certificate. + bssl::UniquePtr cert = + MakeTestCert("Root", "Leaf", key.get(), /*is_ca=*/false); + ASSERT_TRUE(cert); + if (!t.cert_subject.empty()) { + bssl::UniquePtr subject(X509_NAME_new()); + ASSERT_TRUE(subject); + for (const auto &entry : t.cert_subject) { + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + subject.get(), entry.first, MBSTRING_ASC, + reinterpret_cast(entry.second.data()), + entry.second.size(), /*loc=*/-1, /*set=*/0)); + } + ASSERT_TRUE(X509_set_subject_name(cert.get(), subject.get())); + } + bssl::UniquePtr sans(sk_GENERAL_NAME_new_null()); + ASSERT_TRUE(sans); + for (const auto &dns : t.cert_dns_names) { + bssl::UniquePtr name(GENERAL_NAME_new()); + ASSERT_TRUE(name); + name->type = GEN_DNS; + name->d.dNSName = ASN1_IA5STRING_new(); + ASSERT_TRUE(name->d.dNSName); + ASSERT_TRUE(ASN1_STRING_set(name->d.dNSName, dns.data(), dns.size())); + ASSERT_TRUE(bssl::PushToStack(sans.get(), std::move(name))); + } + for (const auto &email : t.cert_emails) { + bssl::UniquePtr name(GENERAL_NAME_new()); + ASSERT_TRUE(name); + name->type = GEN_EMAIL; + name->d.rfc822Name = ASN1_IA5STRING_new(); + ASSERT_TRUE(name->d.rfc822Name); + ASSERT_TRUE( + ASN1_STRING_set(name->d.rfc822Name, email.data(), email.size())); + ASSERT_TRUE(bssl::PushToStack(sans.get(), std::move(name))); + } + if (sk_GENERAL_NAME_num(sans.get()) != 0) { + ASSERT_TRUE(X509_add1_ext_i2d(cert.get(), NID_subject_alt_name, + sans.get(), /*crit=*/0, /*flags=*/0)); + } + ASSERT_TRUE(X509_sign(cert.get(), key.get(), EVP_sha256())); + + for (const auto &dns : t.valid_dns_names) { + SCOPED_TRACE(dns); + EXPECT_EQ(1, X509_check_host(cert.get(), dns.data(), dns.size(), t.flags, + /*peername=*/nullptr)); + EXPECT_EQ(X509_V_OK, + Verify(cert.get(), {root.get()}, /*intermediates=*/{}, + /*crls=*/{}, /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + ASSERT_TRUE(X509_VERIFY_PARAM_set1_host( + param, dns.data(), dns.size())); + X509_VERIFY_PARAM_set_hostflags(param, t.flags); + })); + } + + for (const auto &dns : t.invalid_dns_names) { + SCOPED_TRACE(dns); + EXPECT_EQ(0, X509_check_host(cert.get(), dns.data(), dns.size(), t.flags, + /*peername=*/nullptr)); + EXPECT_EQ(X509_V_ERR_HOSTNAME_MISMATCH, + Verify(cert.get(), {root.get()}, /*intermediates=*/{}, + /*crls=*/{}, /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + ASSERT_TRUE(X509_VERIFY_PARAM_set1_host( + param, dns.data(), dns.size())); + X509_VERIFY_PARAM_set_hostflags(param, t.flags); + })); + } + + for (const auto &email : t.valid_emails) { + SCOPED_TRACE(email); + EXPECT_EQ( + 1, X509_check_email(cert.get(), email.data(), email.size(), t.flags)); + EXPECT_EQ(X509_V_OK, + Verify(cert.get(), {root.get()}, /*intermediates=*/{}, + /*crls=*/{}, /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + ASSERT_TRUE(X509_VERIFY_PARAM_set1_email( + param, email.data(), email.size())); + X509_VERIFY_PARAM_set_hostflags(param, t.flags); + })); + } + + for (const auto &email : t.invalid_emails) { + SCOPED_TRACE(email); + EXPECT_EQ( + 0, X509_check_email(cert.get(), email.data(), email.size(), t.flags)); + EXPECT_EQ(X509_V_ERR_EMAIL_MISMATCH, + Verify(cert.get(), {root.get()}, /*intermediates=*/{}, + /*crls=*/{}, /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + ASSERT_TRUE(X509_VERIFY_PARAM_set1_email( + param, email.data(), email.size())); + X509_VERIFY_PARAM_set_hostflags(param, t.flags); + })); + } + } +} + +TEST(X509Test, AddDuplicates) { + bssl::UniquePtr store(X509_STORE_new()); + bssl::UniquePtr a(CertFromPEM(kCrossSigningRootPEM)); + bssl::UniquePtr b(CertFromPEM(kRootCAPEM)); + + ASSERT_TRUE(store); + ASSERT_TRUE(a); + ASSERT_TRUE(b); + + EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); + EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); + EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); + EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); + EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); + EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); + + EXPECT_EQ(sk_X509_OBJECT_num(X509_STORE_get0_objects(store.get())), 2u); +} + +TEST(X509Test, BytesToHex) { + struct { + std::vector bytes; + const char *hex; + } kTests[] = { + {{}, ""}, + {{0x00}, "00"}, + {{0x00, 0x11, 0x22}, "00:11:22"}, + {{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + "01:23:45:67:89:AB:CD:EF"}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(Bytes(t.bytes)); + bssl::UniquePtr hex( + x509v3_bytes_to_hex(t.bytes.data(), t.bytes.size())); + ASSERT_TRUE(hex); + EXPECT_STREQ(hex.get(), t.hex); + } +} + +TEST(X509Test, NamePrint) { + // kTestName is a DER-encoded X.509 that covers many cases. + // + // SEQUENCE { + // SET { + // SEQUENCE { + // # countryName + // OBJECT_IDENTIFIER { 2.5.4.6 } + // PrintableString { "US" } + // } + // } + // # Sets may be multi-valued, with different attributes. Try to keep this + // # in DER set order, in case we ever enforce this in the parser. + // SET { + // SEQUENCE { + // # stateOrProvinceName + // OBJECT_IDENTIFIER { 2.5.4.8 } + // PrintableString { "Some State" } + // } + // SEQUENCE { + // # stateOrProvinceName + // OBJECT_IDENTIFIER { 2.5.4.8 } + // UTF8String { "Some Other State \xe2\x98\x83" } + // } + // SEQUENCE { + // # stateOrProvinceName + // OBJECT_IDENTIFIER { 2.5.4.8 } + // BMPString { u"Another State \u2603" } + // } + // SEQUENCE { + // # A custom OID + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2 } + // UniversalString { U"\u2603" } + // } + // } + // # Custom OIDs may have non-string values. + // SET { + // SEQUENCE { + // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.3 } + // SEQUENCE { INTEGER { 1 } INTEGER { 2 } } + // } + // } + // SET { + // SEQUENCE { + // # organizationName + // OBJECT_IDENTIFIER { 2.5.4.10 } + // PrintableString { "Org Name" } + // } + // } + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // # Embed common delimiter forms to test how well they get escaped. + // UTF8String { "Common + // Name/CN=A/CN=B,CN=A,CN=B+CN=A+CN=B;CN=A;CN=B\nCN=A\n" } + // } + // } + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // # Test escaping of leading and trailing spaces. + // UTF8String { " spaces " } + // } + // } + static const uint8_t kTestName[] = { + 0x30, 0x82, 0x01, 0x00, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x6d, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x14, 0x53, + 0x6f, 0x6d, 0x65, 0x20, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x20, 0xe2, 0x98, 0x83, 0x30, 0x25, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x1e, 0x1e, 0x00, 0x41, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x74, + 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, + 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x26, 0x03, 0x30, 0x14, + 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, + 0x09, 0x02, 0x1c, 0x04, 0x00, 0x00, 0x26, 0x03, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, + 0x09, 0x03, 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x4f, 0x72, 0x67, + 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x39, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x4e, + 0x61, 0x6d, 0x65, 0x2f, 0x43, 0x4e, 0x3d, 0x41, 0x2f, 0x43, 0x4e, 0x3d, + 0x42, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x42, 0x2b, + 0x43, 0x4e, 0x3d, 0x41, 0x2b, 0x43, 0x4e, 0x3d, 0x42, 0x3b, 0x43, 0x4e, + 0x3d, 0x41, 0x3b, 0x43, 0x4e, 0x3d, 0x42, 0x0a, 0x43, 0x4e, 0x3d, 0x41, + 0x0a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20}; + + const uint8_t *ptr = kTestName; + bssl::UniquePtr name( + d2i_X509_NAME(nullptr, &ptr, sizeof(kTestName))); + ASSERT_TRUE(name); + EXPECT_EQ(ptr, kTestName + sizeof(kTestName)); + + struct { + int indent; + unsigned long flags; + std::string printed; + } kTests[] = { + // RFC 2253 uses , and + separators and encodes the RDNs in reverse. + // OpenSSL's implementation additionally happens to reverse the values + // within each RDN. RFC 2253 says any order is permissible. + {/*indent=*/0, + /*flags=*/XN_FLAG_RFC2253, + "CN=\\ spaces\\ ," + "CN=Common " + "Name/CN=A/CN=B\\,CN=A\\,CN=B\\+CN=A\\+CN=B\\;CN=A\\;CN=B\\0ACN=A\\0A," + "O=Org Name," + "1.2.840.113554.4.1.72585.3=#3006020101020102," + "1.2.840.113554.4.1.72585.2=#1C0400002603+" + "ST=Another State \\E2\\98\\83+" + "ST=Some Other State \\E2\\98\\83+" + "ST=Some State," + "C=US"}, + {/*indent=*/2, + /*flags=*/XN_FLAG_RFC2253, + " " + "CN=\\ spaces\\ ," + "CN=Common " + "Name/CN=A/CN=B\\,CN=A\\,CN=B\\+CN=A\\+CN=B\\;CN=A\\;CN=B\\0ACN=A\\0A," + "O=Org Name," + "1.2.840.113554.4.1.72585.3=#3006020101020102," + "1.2.840.113554.4.1.72585.2=#1C0400002603+" + "ST=Another State \\E2\\98\\83+" + "ST=Some Other State \\E2\\98\\83+" + "ST=Some State," + "C=US"}, + // |XN_FLAG_ONELINE| is an OpenSSL-specific single-line format. It also + // omits |XN_FLAG_DUMP_UNKNOWN_FIELDS|, so unknown OIDs that use known + // string types will still be decoded. (This may drop important + // information if the unknown OID distinguishes between string types.) It + // also passes |ASN1_STRFLGS_ESC_QUOTE|. + {/*indent=*/0, + /*flags=*/XN_FLAG_ONELINE, + "C = US, " + "ST = Some State + " + "ST = Some Other State \\E2\\98\\83 + " + "ST = Another State \\E2\\98\\83 + " + "1.2.840.113554.4.1.72585.2 = \\E2\\98\\83, " + "1.2.840.113554.4.1.72585.3 = #3006020101020102, " + "O = Org Name, " + "CN = \"Common " + "Name/CN=A/CN=B,CN=A,CN=B+CN=A+CN=B;CN=A;CN=B\\0ACN=A\\0A\", " + "CN = \" spaces \""}, + // Callers can also customize the output, with both |XN_FLAG_*| and + // |ASN1_STRFLGS_*|. |XN_FLAG_SEP_SPLUS_SPC| uses semicolon separators. + {/*indent=*/0, + /*flags=*/XN_FLAG_SEP_SPLUS_SPC | ASN1_STRFLGS_RFC2253 | + ASN1_STRFLGS_ESC_QUOTE, + "C=US; " + "ST=Some State + " + "ST=Some Other State \\E2\\98\\83 + " + "ST=Another State \\E2\\98\\83 + " + "1.2.840.113554.4.1.72585.2=\\E2\\98\\83; " + "1.2.840.113554.4.1.72585.3=#3006020101020102; " + "O=Org Name; " + "CN=\"Common " + "Name/CN=A/CN=B,CN=A,CN=B+CN=A+CN=B;CN=A;CN=B\\0ACN=A\\0A\"; " + "CN=\" spaces \""}, + // Node uses these parameters. + {/*indent=*/0, + /*flags=*/ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_CTRL | + ASN1_STRFLGS_UTF8_CONVERT | XN_FLAG_SEP_MULTILINE | XN_FLAG_FN_SN, + "C=US\n" + "ST=Some State + " + "ST=Some Other State \xE2\x98\x83 + " + "ST=Another State \xE2\x98\x83 + " + "1.2.840.113554.4.1.72585.2=\xE2\x98\x83\n" + "1.2.840.113554.4.1.72585.3=0\\06\\02\\01\\01\\02\\01\\02\n" + "O=Org Name\n" + "CN=Common " + "Name/CN=A/CN=B\\,CN=A\\,CN=B\\+CN=A\\+CN=B\\;CN=A\\;CN=B\\0ACN=A\\0A\n" + "CN=\\ spaces\\ "}, + // |XN_FLAG_COMPAT| matches |X509_NAME_print|, rather than + // |X509_NAME_print_ex|. + // + // TODO(davidben): This works by post-processing the output of + // |X509_NAME_oneline|, which uses "/"" separators, and replacing with + // ", ". The escaping is ambiguous and the post-processing is buggy, so + // some of the trailing slashes are still present and some internal + // slashes are mis-converted. + {/*indent=*/0, + /*flags=*/XN_FLAG_COMPAT, + "C=US, " + "ST=Some State, " + "ST=Some Other State \\xE2\\x98\\x83, " + "ST=\\x00A\\x00n\\x00o\\x00t\\x00h\\x00e\\x00r\\x00 " + "\\x00S\\x00t\\x00a\\x00t\\x00e\\x00 &\\x03/" + "1.2.840.113554.4.1.72585.2=\\x00\\x00&\\x03/" + "1.2.840.113554.4.1.72585.3=0\\x06\\x02\\x01\\x01\\x02\\x01\\x02, " + "O=Org Name, " + "CN=Common Name, " + "CN=A, CN=B,CN=A,CN=B+CN=A+CN=B;CN=A;CN=B\\x0ACN=A\\x0A, " + "CN= spaces "}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.printed); + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio); + int len = X509_NAME_print_ex(bio.get(), name.get(), t.indent, t.flags); + ASSERT_GT(len, 0); + + const uint8_t *printed; + size_t printed_len; + ASSERT_TRUE(BIO_mem_contents(bio.get(), &printed, &printed_len)); + EXPECT_EQ(std::string(printed, printed + printed_len), t.printed); + if (t.flags != XN_FLAG_COMPAT) { + // TODO(davidben): |XN_FLAG_COMPAT| does not return the length. + EXPECT_EQ(static_cast(len), printed_len); + + // Passing a null |BIO| measures the output instead. + len = X509_NAME_print_ex(nullptr, name.get(), t.indent, t.flags); + EXPECT_GT(len, 0); + EXPECT_EQ(static_cast(len), printed_len); + } + } + + // TODO(davidben): This escapes the underlying bytes in the string, but that + // is ambiguous without capturing the type. Should this escape like + // |ASN1_STRFLGS_UTF8_CONVERT| instead? + static const char *kOnelineComponents[] = { + "/C=US", + "/ST=Some State", + "/ST=Some Other State \\xE2\\x98\\x83", + ("/ST=\\x00A\\x00n\\x00o\\x00t\\x00h\\x00e\\x00r\\x00 " + "\\x00S\\x00t\\x00a\\x00t\\x00e\\x00 &\\x03"), + "/1.2.840.113554.4.1.72585.2=\\x00\\x00&\\x03", + "/1.2.840.113554.4.1.72585.3=0\\x06\\x02\\x01\\x01\\x02\\x01\\x02", + "/O=Org Name", + "/CN=Common Name/CN=A/CN=B,CN=A,CN=B+CN=A+CN=B;CN=A;CN=B\\x0ACN=A\\x0A", + "/CN= spaces ", + }; + std::string oneline_expected; + for (const auto& component : kOnelineComponents) { + oneline_expected += component; + } + + // Given null buffer, |X509_NAME_oneline| allocates a new output. + bssl::UniquePtr oneline(X509_NAME_oneline(name.get(), nullptr, 0)); + ASSERT_TRUE(oneline); + EXPECT_EQ(oneline.get(), oneline_expected); + + // Otherwise it writes to the specified buffer. Note one extra byte is needed + // for the trailing NUL. + char buf[1024]; + ASSERT_GE(sizeof(buf), oneline_expected.size() + 2); + ASSERT_EQ(buf, + X509_NAME_oneline(name.get(), buf, oneline_expected.size() + 1)); + EXPECT_EQ(buf, oneline_expected); + + memset(buf, 'a', sizeof(buf)); + ASSERT_EQ(buf, + X509_NAME_oneline(name.get(), buf, oneline_expected.size() + 2)); + EXPECT_EQ(buf, oneline_expected); + + // If the length is too small, |X509_NAME_oneline| truncates at name + // entry boundaries. + EXPECT_EQ(nullptr, X509_NAME_oneline(name.get(), buf, 0)); + for (size_t len = 1; len < oneline_expected.size(); len++) { + SCOPED_TRACE(len); + memset(buf, 'a', sizeof(buf)); + EXPECT_EQ(buf, X509_NAME_oneline(name.get(), buf, len)); + + std::string truncated; + for (const auto& component : kOnelineComponents) { + if (truncated.size() + strlen(component) + 1 > len) { + break; + } + truncated += component; + } + EXPECT_EQ(buf, truncated); + } +} + +// kLargeSerialPEM is a certificate with a large serial number. +static const char kLargeSerialPEM[] = R"( +-----BEGIN CERTIFICATE----- +MIICZjCCAc+gAwIBAgIQASNFZ4mrze8BI0VniavN7zANBgkqhkiG9w0BAQsFADA2 +MRowGAYDVQQKExFCb3JpbmdTU0wgVEVTVElORzEYMBYGA1UEAxMPSW50ZXJtZWRp +YXRlIENBMCAXDTE1MDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAyMRowGAYD +VQQKExFCb3JpbmdTU0wgVEVTVElORzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMPRTRliCpKEnug6OzI0rJVcQep5p+aT +9sCg+pj+HVyg/DYTwqZ6qJRKhM+MbkhdJuU7FyqlsBeCeM/OjwMjcY0yEB/xJg1i +ygfuBztTLuPnHxtSuKwae5MeqSofp3j97sRMnuLcKlHxu8rXoOCAS9BO50uKnPwU +Ee1iEVqR92FPAgMBAAGjdzB1MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr +BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAZBgNVHQ4EEgQQo3mm9u6v +uaVeN4wRgDTidTAbBgNVHSMEFDASgBCMGmiotXbbXVd7H40UsgajMA0GCSqGSIb3 +DQEBCwUAA4GBAGP+n4kKGn/8uddYLWTXbUsz+KLuEXNDMyu3vRufLjTpIbP2MCNo +85fhLeC3fzKuGOk+6QGVLOBBcWDrrLqrmqnWdBMPULDo2QoF71a4GVjeJh+ax/tZ +PyeGVPUK21TE0LDIxf2a11d1CJw582MgZQIPk4tXk+AcU9EqIceKgECG +-----END CERTIFICATE----- +)"; + +TEST(X509Test, Print) { + bssl::UniquePtr cert(CertFromPEM(kLargeSerialPEM)); + ASSERT_TRUE(cert); + + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio); + EXPECT_TRUE(X509_print_ex(bio.get(), cert.get(), 0, 0)); + // Nothing should be left in the error queue. + EXPECT_EQ(0u, ERR_peek_error()); + + // This output is not guaranteed to be stable, but we assert on it to make + // sure something is printed. + const uint8_t *data; + size_t data_len; + ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &data_len)); + std::string print(reinterpret_cast(data), data_len); + EXPECT_EQ(print, R"(Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=BoringSSL TESTING, CN=Intermediate CA + Validity + Not Before: Jan 1 00:00:00 2015 GMT + Not After : Jan 1 00:00:00 2100 GMT + Subject: O=BoringSSL TESTING, CN=example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:c3:d1:4d:19:62:0a:92:84:9e:e8:3a:3b:32:34: + ac:95:5c:41:ea:79:a7:e6:93:f6:c0:a0:fa:98:fe: + 1d:5c:a0:fc:36:13:c2:a6:7a:a8:94:4a:84:cf:8c: + 6e:48:5d:26:e5:3b:17:2a:a5:b0:17:82:78:cf:ce: + 8f:03:23:71:8d:32:10:1f:f1:26:0d:62:ca:07:ee: + 07:3b:53:2e:e3:e7:1f:1b:52:b8:ac:1a:7b:93:1e: + a9:2a:1f:a7:78:fd:ee:c4:4c:9e:e2:dc:2a:51:f1: + bb:ca:d7:a0:e0:80:4b:d0:4e:e7:4b:8a:9c:fc:14: + 11:ed:62:11:5a:91:f7:61:4f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Subject Key Identifier: + A3:79:A6:F6:EE:AF:B9:A5:5E:37:8C:11:80:34:E2:75 + X509v3 Authority Key Identifier: + keyid:8C:1A:68:A8:B5:76:DB:5D:57:7B:1F:8D:14:B2:06:A3 + + Signature Algorithm: sha256WithRSAEncryption + 63:fe:9f:89:0a:1a:7f:fc:b9:d7:58:2d:64:d7:6d:4b:33:f8: + a2:ee:11:73:43:33:2b:b7:bd:1b:9f:2e:34:e9:21:b3:f6:30: + 23:68:f3:97:e1:2d:e0:b7:7f:32:ae:18:e9:3e:e9:01:95:2c: + e0:41:71:60:eb:ac:ba:ab:9a:a9:d6:74:13:0f:50:b0:e8:d9: + 0a:05:ef:56:b8:19:58:de:26:1f:9a:c7:fb:59:3f:27:86:54: + f5:0a:db:54:c4:d0:b0:c8:c5:fd:9a:d7:57:75:08:9c:39:f3: + 63:20:65:02:0f:93:8b:57:93:e0:1c:53:d1:2a:21:c7:8a:80: + 40:86 +)"); +} + +TEST(X509Test, AddExt) { + bssl::UniquePtr x509(X509_new()); + ASSERT_TRUE(x509); + + struct Extension { + int nid; + bool critical; + std::vector data; + }; + auto expect_extensions = [&](const std::vector &exts) { + ASSERT_EQ(static_cast(X509_get_ext_count(x509.get())), exts.size()); + for (size_t i = 0; i < exts.size(); i++) { + SCOPED_TRACE(i); + const X509_EXTENSION *ext = X509_get_ext(x509.get(), static_cast(i)); + EXPECT_EQ(OBJ_obj2nid(X509_EXTENSION_get_object(ext)), exts[i].nid); + EXPECT_EQ(X509_EXTENSION_get_critical(ext), exts[i].critical ? 1 : 0); + const ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(ext); + EXPECT_EQ(Bytes(ASN1_STRING_get0_data(data), ASN1_STRING_length(data)), + Bytes(exts[i].data)); + } + }; + + // Make a few sample extensions. + + // SEQUENCE {} + std::vector basic1_der = {0x30, 0x00}; + const uint8_t *inp = basic1_der.data(); + bssl::UniquePtr basic1_obj( + d2i_BASIC_CONSTRAINTS(nullptr, &inp, basic1_der.size())); + EXPECT_EQ(inp, basic1_der.data() + basic1_der.size()); + + // SEQUENCE { BOOLEAN { TRUE } } + std::vector basic2_der = {0x30, 0x03, 0x01, 0x01, 0xff}; + inp = basic2_der.data(); + bssl::UniquePtr basic2_obj( + d2i_BASIC_CONSTRAINTS(nullptr, &inp, basic2_der.size())); + EXPECT_EQ(inp, basic2_der.data() + basic2_der.size()); + + // OCTET_STRING {} + std::vector skid1_der = {0x04, 0x00}; + inp = skid1_der.data(); + bssl::UniquePtr skid1_obj( + d2i_ASN1_OCTET_STRING(nullptr, &inp, skid1_der.size())); + EXPECT_EQ(inp, skid1_der.data() + skid1_der.size()); + + // OCTET_STRING { "a" } + std::vector skid2_der = {0x04, 0x01, 0x61}; + inp = skid2_der.data(); + bssl::UniquePtr skid2_obj( + d2i_ASN1_OCTET_STRING(nullptr, &inp, skid2_der.size())); + EXPECT_EQ(inp, skid2_der.data() + skid2_der.size()); + + // Initially, the extension list is empty. + expect_extensions({}); + + // Adding extensions works with the default settings. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(), + /*crit=*/1, X509V3_ADD_DEFAULT)); + expect_extensions({{NID_basic_constraints, true, basic1_der}}); + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_subject_key_identifier, + skid1_obj.get(), + /*crit=*/0, X509V3_ADD_DEFAULT)); + expect_extensions({{NID_basic_constraints, true, basic1_der}, + {NID_subject_key_identifier, false, skid1_der}}); + + // By default, we cannot add duplicates. + EXPECT_EQ( + 0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic2_obj.get(), + /*crit=*/0, X509V3_ADD_DEFAULT)); + expect_extensions({{NID_basic_constraints, true, basic1_der}, + {NID_subject_key_identifier, false, skid1_der}}); + + // |X509V3_ADD_KEEP_EXISTING| silently keeps the existing extension if already + // present. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic2_obj.get(), + /*crit=*/0, X509V3_ADD_KEEP_EXISTING)); + expect_extensions({{NID_basic_constraints, true, basic1_der}, + {NID_subject_key_identifier, false, skid1_der}}); + + // |X509V3_ADD_REPLACE| replaces it. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic2_obj.get(), + /*crit=*/0, X509V3_ADD_REPLACE)); + expect_extensions({{NID_basic_constraints, false, basic2_der}, + {NID_subject_key_identifier, false, skid1_der}}); + + // |X509V3_ADD_REPLACE_EXISTING| also replaces matches. + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_subject_key_identifier, + skid2_obj.get(), + /*crit=*/1, X509V3_ADD_REPLACE_EXISTING)); + expect_extensions({{NID_basic_constraints, false, basic2_der}, + {NID_subject_key_identifier, true, skid2_der}}); + + // |X509V3_ADD_DELETE| ignores the value and deletes the extension. + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); + + // Not finding an extension to delete is an error. + EXPECT_EQ(0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); + + // |X509V3_ADD_REPLACE_EXISTING| fails if it cannot find a match. + EXPECT_EQ( + 0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(), + /*crit=*/1, X509V3_ADD_REPLACE_EXISTING)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); + + // |X509V3_ADD_REPLACE| adds a new extension if not preseent. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(), + /*crit=*/1, X509V3_ADD_REPLACE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}, + {NID_basic_constraints, true, basic1_der}}); + + // Delete the extension again. + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); + + // |X509V3_ADD_KEEP_EXISTING| adds a new extension if not preseent. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(), + /*crit=*/1, X509V3_ADD_KEEP_EXISTING)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}, + {NID_basic_constraints, true, basic1_der}}); + + // Delete the extension again. + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); + + // |X509V3_ADD_APPEND| adds a new extension if not present. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(), + /*crit=*/1, X509V3_ADD_APPEND)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}, + {NID_basic_constraints, true, basic1_der}}); + + // |X509V3_ADD_APPEND| keeps adding duplicates (invalid) even if present. + EXPECT_EQ( + 1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic2_obj.get(), + /*crit=*/0, X509V3_ADD_APPEND)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}, + {NID_basic_constraints, true, basic1_der}, + {NID_basic_constraints, false, basic2_der}}); + + // |X509V3_ADD_DELETE| only deletes one extension at a time. + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}, + {NID_basic_constraints, false, basic2_der}}); + EXPECT_EQ(1, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0, + X509V3_ADD_DELETE)); + expect_extensions({{NID_subject_key_identifier, true, skid2_der}}); +} + +TEST(X509Test, NameEntry) { + bssl::UniquePtr name(X509_NAME_new()); + ASSERT_TRUE(name); + + auto check_name = [&](const char *expected_rfc2253) { + // Check RDN indices are self-consistent. + int num = X509_NAME_entry_count(name.get()); + if (num > 0) { + // RDN indices must start at zero. + EXPECT_EQ(0, X509_NAME_ENTRY_set(X509_NAME_get_entry(name.get(), 0))); + } + for (int i = 1; i < num; i++) { + int prev = X509_NAME_ENTRY_set(X509_NAME_get_entry(name.get(), i - 1)); + int current = X509_NAME_ENTRY_set(X509_NAME_get_entry(name.get(), i)); + // RDN indices must increase consecutively. + EXPECT_TRUE(prev == current || prev + 1 == current) + << "Entry " << i << " has RDN index " << current + << " which is inconsistent with previous index " << prev; + } + + // Check the name based on the RFC 2253 serialization. Note the RFC 2253 + // serialization is in reverse. + bssl::UniquePtr bio(BIO_new(BIO_s_mem())); + ASSERT_TRUE(bio); + EXPECT_GE(X509_NAME_print_ex(bio.get(), name.get(), 0, XN_FLAG_RFC2253), 0); + const uint8_t *data; + size_t len; + ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &len)); + EXPECT_EQ(expected_rfc2253, std::string(data, data + len)); + }; + + check_name(""); + + // |loc| = -1, |set| = 0 appends as new RDNs. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_organizationName, MBSTRING_UTF8, + reinterpret_cast("Org"), /*len=*/-1, /*loc=*/-1, + /*set=*/0)); + check_name("O=Org"); + + // |loc| = -1, |set| = 0 appends as new RDNs. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_commonName, MBSTRING_UTF8, + reinterpret_cast("Name"), /*len=*/-1, /*loc=*/-1, + /*set=*/0)); + check_name("CN=Name,O=Org"); + + // Inserting in the middle of the set, but with |set| = 0 inserts a new RDN + // and fixes the "set" values as needed. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_organizationalUnitName, MBSTRING_UTF8, + reinterpret_cast("Unit"), /*len=*/-1, /*loc=*/1, + /*set=*/0)); + check_name("CN=Name,OU=Unit,O=Org"); + + // |set = -1| adds to the previous entry's RDN. (Although putting O and OU at + // the same level makes little sense, the test is written this way to check + // the function isn't using attribute types to order things.) + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_organizationName, MBSTRING_UTF8, + reinterpret_cast("Org2"), /*len=*/-1, /*loc=*/2, + /*set=*/-1)); + check_name("CN=Name,O=Org2+OU=Unit,O=Org"); + + // |set| = 1 adds to the next entry's RDN. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_commonName, MBSTRING_UTF8, + reinterpret_cast("Name2"), /*len=*/-1, /*loc=*/2, + /*set=*/-1)); + check_name("CN=Name,O=Org2+CN=Name2+OU=Unit,O=Org"); + + // If there is no previous RDN, |set| = -1 makes a new RDN. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_countryName, MBSTRING_UTF8, + reinterpret_cast("US"), /*len=*/-1, /*loc=*/0, + /*set=*/-1)); + check_name("CN=Name,O=Org2+CN=Name2+OU=Unit,O=Org,C=US"); + + // Likewise if there is no next RDN. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_commonName, MBSTRING_UTF8, + reinterpret_cast("Name3"), /*len=*/-1, /*loc=*/-1, + /*set=*/1)); + check_name("CN=Name3,CN=Name,O=Org2+CN=Name2+OU=Unit,O=Org,C=US"); + + // If |set| = 0 and we insert in the middle of an existing RDN, it adds an + // RDN boundary after the entry but not before. This is a quirk of how the + // function is implemented and hopefully not something any caller depends on. + ASSERT_TRUE(X509_NAME_add_entry_by_NID( + name.get(), NID_commonName, MBSTRING_UTF8, + reinterpret_cast("Name4"), /*len=*/-1, /*loc=*/3, + /*set=*/0)); + check_name("CN=Name3,CN=Name,O=Org2+CN=Name2,CN=Name4+OU=Unit,O=Org,C=US"); + + // Entries may be deleted. + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 7)); + check_name("CN=Name,O=Org2+CN=Name2,CN=Name4+OU=Unit,O=Org,C=US"); + + // When deleting the only attribute in an RDN, index invariants should still + // hold. + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 0)); + check_name("CN=Name,O=Org2+CN=Name2,CN=Name4+OU=Unit,O=Org"); + + // Index invariants also hold when deleting attributes from non-singular RDNs. + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 1)); + check_name("CN=Name,O=Org2+CN=Name2,CN=Name4,O=Org"); + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 1)); + check_name("CN=Name,O=Org2+CN=Name2,O=Org"); + + // Same as above, but delete the second attribute first. + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 2)); + check_name("CN=Name,CN=Name2,O=Org"); + X509_NAME_ENTRY_free(X509_NAME_delete_entry(name.get(), 1)); + check_name("CN=Name,O=Org"); +} + +// Tests that non-integer types are rejected when passed as an argument to +// X509_set_serialNumber(). +TEST(X509Test, SetSerialNumberChecksASN1StringType) { + bssl::UniquePtr root = CertFromPEM(kRootCAPEM); + ASSERT_TRUE(root); + + // Passing an IA5String to X509_set_serialNumber() should fail. + bssl::UniquePtr str(ASN1_IA5STRING_new()); + ASSERT_TRUE(str); + EXPECT_FALSE(X509_set_serialNumber(root.get(), str.get())); + + // Passing a negative serial number is allowed. While invalid, we do accept + // them and some callers rely in this for tests. + bssl::UniquePtr serial(ASN1_INTEGER_new()); + ASSERT_TRUE(serial); + ASSERT_TRUE(ASN1_INTEGER_set_int64(serial.get(), -1)); + ASSERT_TRUE(X509_set_serialNumber(root.get(), serial.get())); + int64_t val; + ASSERT_TRUE(ASN1_INTEGER_get_int64(&val, X509_get0_serialNumber(root.get()))); + EXPECT_EQ(-1, val); +} + +TEST(X509Test, Policy) { + bssl::UniquePtr oid1( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.1", /*dont_search_names=*/1)); + ASSERT_TRUE(oid1); + bssl::UniquePtr oid2( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.2", /*dont_search_names=*/1)); + ASSERT_TRUE(oid2); + bssl::UniquePtr oid3( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.3", /*dont_search_names=*/1)); + ASSERT_TRUE(oid3); + bssl::UniquePtr oid4( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.4", /*dont_search_names=*/1)); + ASSERT_TRUE(oid4); + bssl::UniquePtr oid5( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.5", /*dont_search_names=*/1)); + ASSERT_TRUE(oid5); + + bssl::UniquePtr root( + CertFromPEM(GetTestData("crypto/x509/test/policy_root.pem").c_str())); + ASSERT_TRUE(root); + bssl::UniquePtr root_cross_inhibit_mapping(CertFromPEM( + GetTestData("crypto/x509/test/policy_root_cross_inhibit_mapping.pem") + .c_str())); + ASSERT_TRUE(root_cross_inhibit_mapping); + bssl::UniquePtr root2( + CertFromPEM(GetTestData("crypto/x509/test/policy_root2.pem").c_str())); + ASSERT_TRUE(root2); + bssl::UniquePtr intermediate(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate.pem").c_str())); + ASSERT_TRUE(intermediate); + bssl::UniquePtr intermediate_any(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_any.pem").c_str())); + ASSERT_TRUE(intermediate_any); + bssl::UniquePtr intermediate_duplicate(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_duplicate.pem") + .c_str())); + ASSERT_TRUE(intermediate_duplicate); + bssl::UniquePtr intermediate_invalid(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_invalid.pem").c_str())); + ASSERT_TRUE(intermediate_invalid); + bssl::UniquePtr intermediate_mapped(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_mapped.pem") + .c_str())); + ASSERT_TRUE(intermediate_mapped); + bssl::UniquePtr intermediate_mapped_any(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_mapped_any.pem") + .c_str())); + ASSERT_TRUE(intermediate_mapped_any); + bssl::UniquePtr intermediate_mapped_oid3(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_mapped_oid3.pem") + .c_str())); + ASSERT_TRUE(intermediate_mapped_oid3); + bssl::UniquePtr intermediate_require(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_require.pem").c_str())); + ASSERT_TRUE(intermediate_require); + bssl::UniquePtr intermediate_require1(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_require1.pem") + .c_str())); + ASSERT_TRUE(intermediate_require1); + bssl::UniquePtr intermediate_require2(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_require2.pem") + .c_str())); + ASSERT_TRUE(intermediate_require2); + bssl::UniquePtr intermediate_require_duplicate(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate_require_duplicate.pem") + .c_str())); + ASSERT_TRUE(intermediate_require_duplicate); + bssl::UniquePtr intermediate_require_no_policies(CertFromPEM( + GetTestData( + "crypto/x509/test/policy_intermediate_require_no_policies.pem") + .c_str())); + ASSERT_TRUE(intermediate_require_no_policies); + bssl::UniquePtr leaf( + CertFromPEM(GetTestData("crypto/x509/test/policy_leaf.pem").c_str())); + ASSERT_TRUE(leaf); + bssl::UniquePtr leaf_any( + CertFromPEM(GetTestData("crypto/x509/test/policy_leaf_any.pem").c_str())); + ASSERT_TRUE(leaf_any); + bssl::UniquePtr leaf_duplicate(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_duplicate.pem").c_str())); + ASSERT_TRUE(leaf_duplicate); + bssl::UniquePtr leaf_invalid(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_invalid.pem").c_str())); + ASSERT_TRUE(leaf_invalid); + bssl::UniquePtr leaf_none(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_none.pem").c_str())); + ASSERT_TRUE(leaf_none); + bssl::UniquePtr leaf_oid1(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_oid1.pem").c_str())); + ASSERT_TRUE(leaf_oid1); + bssl::UniquePtr leaf_oid2(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_oid2.pem").c_str())); + ASSERT_TRUE(leaf_oid2); + bssl::UniquePtr leaf_oid3(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_oid3.pem").c_str())); + ASSERT_TRUE(leaf_oid3); + bssl::UniquePtr leaf_oid4(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_oid4.pem").c_str())); + ASSERT_TRUE(leaf_oid4); + bssl::UniquePtr leaf_oid5(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_oid5.pem").c_str())); + ASSERT_TRUE(leaf_oid5); + bssl::UniquePtr leaf_require(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_require.pem").c_str())); + ASSERT_TRUE(leaf_require); + bssl::UniquePtr leaf_require1(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_require1.pem").c_str())); + ASSERT_TRUE(leaf_require1); + + auto set_policies = [](X509_VERIFY_PARAM *param, + std::vector oids) { + for (const ASN1_OBJECT *oid : oids) { + bssl::UniquePtr copy(OBJ_dup(oid)); + ASSERT_TRUE(copy); + ASSERT_TRUE(X509_VERIFY_PARAM_add0_policy(param, copy.get())); + copy.release(); // |X509_VERIFY_PARAM_add0_policy| takes ownership on + // success. + } + }; + + // The chain is good for |oid1| and |oid2|, but not |oid3|. + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY)); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid2.get()}); + })); + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get(), oid2.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get(), oid3.get()}); + })); + + // The policy extension cannot be parsed. + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf.get(), {root.get()}, {intermediate_invalid.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{})); + + // There is a duplicate policy in the policy extension. + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf.get(), {root.get()}, {intermediate_duplicate.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + // The policy extension in the leaf cannot be parsed. + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf_duplicate.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + // Without |X509_V_FLAG_EXPLICIT_POLICY|, the policy tree is built and + // intersected with user-specified policies, but it is not required to result + // in any valid policies. + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // However, a CA with policy constraints can require an explicit policy. + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, + {intermediate_require.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf.get(), {root.get()}, {intermediate_require.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // requireExplicitPolicy applies even if the application does not configure a + // user-initial-policy-set. If the validation results in no policies, the + // chain is invalid. + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_none.get(), {root.get()}, {intermediate_require.get()}, + /*crls=*/{})); + + // A leaf can also set requireExplicitPolicy. + EXPECT_EQ(X509_V_OK, + Verify(leaf_require.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, /*flags=*/0)); + EXPECT_EQ(X509_V_OK, Verify(leaf_require.get(), {root.get()}, + {intermediate.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_require.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // requireExplicitPolicy is a count of certificates to skip. If the value is + // not zero by the end of the chain, it doesn't count. + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf.get(), {root.get()}, {intermediate_require1.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate_require2.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf_require1.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // If multiple certificates specify the constraint, the more constrained value + // wins. + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_require1.get(), {root.get()}, {intermediate_require1.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_require.get(), {root.get()}, {intermediate_require2.get()}, + /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // An intermediate that requires an explicit policy, but then specifies no + // policies should fail verification as a result. + EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf.get(), {root.get()}, + {intermediate_require_no_policies.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + // A constrained intermediate's policy extension has a duplicate policy, which + // is invalid. Historically this, and the above case, leaked memory. + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf.get(), {root.get()}, + {intermediate_require_duplicate.get()}, /*crls=*/{}, + /*flags=*/0, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + // The leaf asserts anyPolicy, but the intermediate does not. The resulting + // valid policies are the intersection. + EXPECT_EQ( + X509_V_OK, + Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // The intermediate asserts anyPolicy, but the leaf does not. The resulting + // valid policies are the intersection. + EXPECT_EQ( + X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // Both assert anyPolicy. All policies are valid. + EXPECT_EQ(X509_V_OK, + Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + EXPECT_EQ(X509_V_OK, + Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // With just a trust anchor, policy checking silently succeeds. + EXPECT_EQ(X509_V_OK, Verify(root.get(), {root.get()}, {}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + for (bool use_any : {false, true}) { + SCOPED_TRACE(use_any); + X509 *cert = + use_any ? intermediate_mapped_any.get() : intermediate_mapped.get(); + // OID3 is mapped to {OID1, OID2}, which means OID1 and OID2 (or both) are + // acceptable for OID3. + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ(X509_V_OK, Verify(leaf_oid1.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ(X509_V_OK, Verify(leaf_oid2.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // If the intermediate's policies were anyPolicy, OID3 at the leaf, despite + // being mapped, is still acceptable as OID3 at the root. Despite the OID3 + // having expected_policy_set = {OID1, OID2}, it can match the anyPolicy + // node instead. + // + // If the intermediate's policies listed OIDs explicitly, OID3 at the leaf + // is not acceptable as OID3 at the root. OID3 has expected_polciy_set = + // {OID1, OID2} and no other node allows OID3. + EXPECT_EQ(use_any ? X509_V_OK : X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_oid3.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + + // If the intermediate's policies were anyPolicy, OID1 at the leaf is no + // longer acceptable as OID1 at the root because policies only match + // anyPolicy when they match no other policy. + // + // If the intermediate's policies listed OIDs explicitly, OID1 at the leaf + // is acceptable as OID1 at the root because it will match both OID1 and + // OID3 (mapped) policies. + EXPECT_EQ(use_any ? X509_V_ERR_NO_EXPLICIT_POLICY : X509_V_OK, + Verify(leaf_oid1.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + + // All pairs of OID4 and OID5 are mapped together, so either can stand for + // the other. + EXPECT_EQ(X509_V_OK, Verify(leaf_oid4.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid4.get()}); + })); + EXPECT_EQ(X509_V_OK, Verify(leaf_oid4.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid5.get()}); + })); + EXPECT_EQ(X509_V_OK, Verify(leaf_oid5.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid4.get()}); + })); + EXPECT_EQ(X509_V_OK, Verify(leaf_oid5.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid5.get()}); + })); + + EXPECT_EQ(X509_V_OK, Verify(leaf_oid4.get(), {root.get()}, {cert}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid4.get(), oid5.get()}); + })); + } + + // Although |intermediate_mapped_oid3| contains many mappings, it only accepts + // OID3. Nodes should not be created for the other mappings. + EXPECT_EQ(X509_V_OK, Verify(leaf_oid1.get(), {root.get()}, + {intermediate_mapped_oid3.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_oid4.get(), {root.get()}, {intermediate_mapped_oid3.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid4.get()}); + })); + + // Policy mapping can be inhibited, either by the caller or a certificate in + // the chain, in which case mapped policies are unassertable (apart from some + // anyPolicy edge cases). + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_oid1.get(), {root.get()}, {intermediate_mapped_oid3.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY | X509_V_FLAG_INHIBIT_MAP, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); + EXPECT_EQ( + X509_V_ERR_NO_EXPLICIT_POLICY, + Verify(leaf_oid1.get(), {root2.get()}, + {intermediate_mapped_oid3.get(), root_cross_inhibit_mapping.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid3.get()}); + })); +} + +#if defined(OPENSSL_THREADS) +// A similar test to the above, but ensures the various bits of intermediate +// state are computed safely. +TEST(X509Test, PolicyThreads) { + const size_t kNumThreads = 10; + + bssl::UniquePtr oid1( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.1", /*dont_search_names=*/1)); + ASSERT_TRUE(oid1); + bssl::UniquePtr oid2( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.2", /*dont_search_names=*/1)); + ASSERT_TRUE(oid2); + bssl::UniquePtr oid3( + OBJ_txt2obj("1.2.840.113554.4.1.72585.2.3", /*dont_search_names=*/1)); + ASSERT_TRUE(oid3); + + auto set_policies = [](X509_VERIFY_PARAM *param, + std::vector oids) { + for (const ASN1_OBJECT *oid : oids) { + bssl::UniquePtr copy(OBJ_dup(oid)); + ASSERT_TRUE(copy); + ASSERT_TRUE(X509_VERIFY_PARAM_add0_policy(param, copy.get())); + copy.release(); // |X509_VERIFY_PARAM_add0_policy| takes ownership on + // success. + } + }; + + { + bssl::UniquePtr root( + CertFromPEM(GetTestData("crypto/x509/test/policy_root.pem").c_str())); + ASSERT_TRUE(root); + bssl::UniquePtr intermediate(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate.pem").c_str())); + ASSERT_TRUE(intermediate); + bssl::UniquePtr leaf( + CertFromPEM(GetTestData("crypto/x509/test/policy_leaf.pem").c_str())); + ASSERT_TRUE(leaf); + + std::vector threads; + for (size_t i = 0; i < kNumThreads; i++) { + threads.emplace_back([&] { + EXPECT_EQ( + X509_V_OK, + Verify(leaf.get(), {root.get()}, {intermediate.get()}, /*crls=*/{}, + X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + }); + } + for (auto &thread : threads) { + thread.join(); + } + } + + { + bssl::UniquePtr root( + CertFromPEM(GetTestData("crypto/x509/test/policy_root.pem").c_str())); + ASSERT_TRUE(root); + bssl::UniquePtr intermediate(CertFromPEM( + GetTestData("crypto/x509/test/policy_intermediate.pem").c_str())); + ASSERT_TRUE(intermediate); + bssl::UniquePtr leaf_invalid(CertFromPEM( + GetTestData("crypto/x509/test/policy_leaf_invalid.pem").c_str())); + ASSERT_TRUE(leaf_invalid); + + + std::vector threads; + for (size_t i = 0; i < kNumThreads; i++) { + threads.emplace_back([&] { + EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION, + Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()}, + /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY, + [&](X509_VERIFY_PARAM *param) { + set_policies(param, {oid1.get()}); + })); + }); + } + for (auto &thread : threads) { + thread.join(); + } + } +} +#endif // OPENSSL_THREADS + +TEST(X509Test, ExtensionFromConf) { + static const char kTestOID[] = "1.2.840.113554.4.1.72585.2"; + const struct { + const char *name; + std::string value; + // conf is the serialized confdb, or nullptr if none is to be provided. + const char *conf; + // expected is the resulting extension, encoded in DER, or the empty string + // if an error is expected. + std::vector expected; + } kTests[] = { + // Many extensions have built-in syntax. + {"basicConstraints", + "critical,CA:true", + nullptr, + {0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff}}, + + {"basicConstraints", + "critical,CA:true,pathlen:1", + nullptr, + {0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01}}, + + // key:value tuples can be repeated and just override the previous value. + {"basicConstraints", + "critical,CA:true,pathlen:100,pathlen:1", + nullptr, + {0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01}}, + + // Extension contents may be referenced from a config section. + {"basicConstraints", + "critical,@section", + "[section]\nCA = true\n", + {0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff}}, + + // If no config is provided, this should fail. + {"basicConstraints", "critical,@section", nullptr, {}}, + + // issuingDistributionPoint takes a list of name:value pairs. Omitting the + // value is not allowed. + {"issuingDistributionPoint", "fullname", nullptr, {}}, + + {"issuingDistributionPoint", + "relativename:name", + "[name]\nCN=Hello\n", + {0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x1c, 0x04, 0x14, 0x30, + 0x12, 0xa0, 0x10, 0xa1, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f}}, + + // relativename referencing a section which doesn't exist. + {"issuingDistributionPoint", + "relativename:wrong_section_name", + "[name]\nCN=Hello\n", + {}}, + + // relativename must be a single RDN. By default, the section-based name + // syntax puts each attribute into its own RDN. + {"issuingDistributionPoint", + "relativename:name", + "[name]\nCN=Hello\nC=US\n", + {}}, + + // A single RDN with multiple attributes is allowed. + {"issuingDistributionPoint", + "relativename:name", + "[name]\nCN=Hello\n+C=US\n", + {0x30, 0x26, 0x06, 0x03, 0x55, 0x1d, 0x1c, 0x04, 0x1f, 0x30, + 0x1d, 0xa0, 0x1b, 0xa1, 0x19, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x0c, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f}}, + + // Duplicate reason keys are an error. Reaching this case is interesting. + // The value can a string like "key:value,key:value", or it can be + // "@section" and reference a config section. If using a string, duplicate + // keys are possible, but then it is impossible to put commas in the + // value, as onlysomereasons expects. If using a section reference, it is + // impossible to have a duplicate key because the config file parser + // overrides the old value. + {"issuingDistributionPoint", + "onlysomereasons:keyCompromise", + nullptr, + {0x30, 0x0d, 0x06, 0x03, 0x55, 0x1d, 0x1c, 0x04, 0x06, 0x30, 0x04, 0x83, + 0x02, 0x06, 0x40}}, + {"issuingDistributionPoint", + "onlysomereasons:keyCompromise,onlysomereasons:CACompromise\n", + nullptr, + {}}, + + // subjectAltName has a series of string-based inputs for each name type. + {"subjectAltName", + "email:foo@example.com, URI:https://example.com, DNS:example.com, " + "RID:1.2.3.4, IP:127.0.0.1, IP:::1, dirName:section, " + "otherName:1.2.3.4;BOOLEAN:TRUE", + "[section]\nCN=Test\n", + {0x30, 0x78, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x71, 0x30, 0x6f, 0x81, + 0x0f, 0x66, 0x6f, 0x6f, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x82, 0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x88, 0x03, 0x2a, 0x03, 0x04, 0x87, 0x04, 0x7f, 0x00, 0x00, + 0x01, 0x87, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa4, 0x11, 0x30, 0x0f, 0x31, + 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x04, 0x54, 0x65, + 0x73, 0x74, 0xa0, 0x0a, 0x06, 0x03, 0x2a, 0x03, 0x04, 0xa0, 0x03, 0x01, + 0x01, 0xff}}, + + // Syntax errors in each case, where they exist. (The string types just + // copy the string in as-is.) + {"subjectAltName", "RID:not_an_oid", nullptr, {}}, + {"subjectAltName", "IP:not_an_ip", nullptr, {}}, + {"subjectAltName", "dirName:no_conf_db", nullptr, {}}, + {"subjectAltName", "dirName:missing_section", "[section]\nCN=Test\n", {}}, + {"subjectAltName", "otherName:missing_semicolon", nullptr, {}}, + {"subjectAltName", "otherName:1.2.3.4", nullptr, {}}, + {"subjectAltName", "otherName:invalid_oid;BOOLEAN:TRUE", nullptr, {}}, + {"subjectAltName", "otherName:1.2.3.4;invalid_value", nullptr, {}}, + + {"policyMappings", + "1.1.1.1:2.2.2.2", + nullptr, + {0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x21, 0x04, 0x0e, 0x30, 0x0c, 0x30, + 0x0a, 0x06, 0x03, 0x29, 0x01, 0x01, 0x06, 0x03, 0x52, 0x02, 0x02}}, + {"policyMappings", "invalid_oid:2.2.2.2", nullptr, {}}, + {"policyMappings", "1.1.1.1:invalid_oid", nullptr, {}}, + + // The "DER:" prefix just specifies an arbitrary byte string. Colons + // separators are ignored. + {kTestOID, "DER:0001020304", nullptr, {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, + 0x00, 0x01, 0x02, 0x03, 0x04}}, + {kTestOID, + "DER:00:01:02:03:04", + nullptr, + {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04}}, + {kTestOID, "DER:invalid hex", nullptr, {}}, + + // The "ASN1:" prefix implements a complex language for describing ASN.1 + // structures. See + // https://www.openssl.org/docs/man1.1.1/man3/ASN1_generate_nconf.html + {kTestOID, "ASN1:invalid", nullptr, {}}, + {kTestOID, + "ASN1:BOOLEAN:TRUE", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x01, 0x01, 0xff}}, + {kTestOID, "ASN1:BOOL:yes", nullptr, {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, + 0x01, 0x01, 0xff}}, + {kTestOID, + "ASN1:BOOLEAN:NO", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x01, 0x01, 0x00}}, + {kTestOID, + "ASN1:BOOLEAN", // Missing value + nullptr, + {}}, + {kTestOID, "ASN1:BOOLEAN:invalid", nullptr, {}}, + {kTestOID, "ASN1:BOOLEAN:TRUE,invalid", nullptr, {}}, + + {kTestOID, "ASN1:NULL", nullptr, {0x30, 0x12, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x02, 0x05, 0x00}}, + {kTestOID, "ASN1:NULL,invalid", nullptr, {}}, + {kTestOID, "ASN1:NULL:invalid", nullptr, {}}, + + // Missing value. + {kTestOID, "ASN1:INTEGER", nullptr, {}}, + {kTestOID, "ASN1:INTEGER:", nullptr, {}}, + {kTestOID, "ASN1:INTEGER,invalid", nullptr, {}}, + + // INTEGER may be decimal or hexadecimal. + {kTestOID, "ASN1:INT:-0x10", nullptr, {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, + 0x02, 0x01, 0xf0}}, + {kTestOID, "ASN1:INT:-10", nullptr, {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, + 0x02, 0x01, 0xf6}}, + {kTestOID, "ASN1:INT:0", nullptr, {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, + 0x02, 0x01, 0x00}}, + {kTestOID, + "ASN1:INTEGER:10", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x02, 0x01, 0x0a}}, + {kTestOID, + "ASN1:INTEGER:0x10", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x02, 0x01, 0x10}}, + + {kTestOID, "ASN1:ENUM:0", nullptr, {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, + 0x0a, 0x01, 0x00}}, + {kTestOID, + "ASN1:ENUMERATED:0", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x0a, 0x01, 0x00}}, + + // OIDs may be spelled out or specified by name. + {kTestOID, "ASN1:OBJECT:invalid", nullptr, {}}, + {kTestOID, + "ASN1:OBJECT:basicConstraints", + nullptr, + {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, 0x06, 0x03, 0x55, 0x1d, 0x13}}, + {kTestOID, + "ASN1:OBJECT:2.5.29.19", + nullptr, + {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, 0x06, 0x03, 0x55, 0x1d, 0x13}}, + {kTestOID, + "ASN1:OID:2.5.29.19", + nullptr, + {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, 0x06, 0x03, 0x55, 0x1d, 0x13}}, + + {kTestOID, "ASN1:UTC:invalid", nullptr, {}}, + {kTestOID, "ASN1:UTC:20001231235959Z", nullptr, {}}, + {kTestOID, "ASN1:UTCTIME:invalid", nullptr, {}}, + {kTestOID, + "ASN1:UTC:001231235959Z", + nullptr, + {0x30, 0x1f, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x0f, 0x17, 0x0d, 0x30, 0x30, + 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a}}, + {kTestOID, + "ASN1:UTCTIME:001231235959Z", + nullptr, + {0x30, 0x1f, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x0f, 0x17, 0x0d, 0x30, 0x30, + 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a}}, + + {kTestOID, "ASN1:GENTIME:invalid", nullptr, {}}, + {kTestOID, "ASN1:GENTIME:001231235959Z", nullptr, {}}, + {kTestOID, "ASN1:GENERALIZEDTIME:invalid", nullptr, {}}, + {kTestOID, + "ASN1:GENTIME:20001231235959Z", + nullptr, + {0x30, 0x21, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x11, 0x18, 0x0f, 0x32, 0x30, 0x30, 0x30, + 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a}}, + {kTestOID, + "ASN1:GENERALIZEDTIME:20001231235959Z", + nullptr, + {0x30, 0x21, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x11, 0x18, 0x0f, 0x32, 0x30, 0x30, 0x30, + 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a}}, + + // The default input format for string types is ASCII, which is then + // converted into the target string type. + {kTestOID, "ASN1:UTF8:hello", nullptr, {0x30, 0x17, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x07, 0x0c, 0x05, + 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:UTF8String:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x0c, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:UNIV:hello", + nullptr, + {0x30, 0x26, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x16, 0x1c, 0x14, + 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6f}}, + {kTestOID, + "ASN1:UNIVERSALSTRING:hello", + nullptr, + {0x30, 0x26, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x16, 0x1c, 0x14, + 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6f}}, + {kTestOID, + "ASN1:BMP:hello", + nullptr, + {0x30, 0x1c, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x0c, 0x1e, 0x0a, + 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f}}, + {kTestOID, + "ASN1:BMPSTRING:hello", + nullptr, + {0x30, 0x1c, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x0c, 0x1e, 0x0a, + 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f}}, + {kTestOID, "ASN1:IA5:hello", nullptr, {0x30, 0x17, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x07, 0x16, 0x05, + 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:IA5STRING:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x16, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:PRINTABLE:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x13, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:PRINTABLESTRING:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x13, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, "ASN1:T61:hello", nullptr, {0x30, 0x17, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x07, 0x14, 0x05, + 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:T61STRING:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x14, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:TELETEXSTRING:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x14, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + + // FORMAT:UTF8 switches the input format to UTF-8. This should be + // converted to the destination string, or rejected if invalid. + {kTestOID, + "ASN1:FORMAT:UTF8,UTF8:\xe2\x98\x83", + nullptr, + {0x30, 0x15, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x05, 0x0c, 0x03, 0xe2, 0x98, 0x83}}, + {kTestOID, + "ASN1:FORMAT:UTF8,UNIV:\xe2\x98\x83", + nullptr, + {0x30, 0x16, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, + 0x04, 0x06, 0x1c, 0x04, 0x00, 0x00, 0x26, 0x03}}, + {kTestOID, + "ASN1:FORMAT:UTF8,BMP:\xe2\x98\x83", + nullptr, + {0x30, 0x14, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x04, 0x1e, 0x02, 0x26, 0x03}}, + {kTestOID, "ASN1:FORMAT:UTF8,IA5:\xe2\x98\x83", nullptr, {}}, + {kTestOID, + "ASN1:FORMAT:UTF8,IA5:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x16, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, "ASN1:FORMAT:UTF8,PRINTABLE:\xe2\x98\x83", nullptr, {}}, + {kTestOID, + "ASN1:FORMAT:UTF8,PRINTABLE:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x13, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, "ASN1:FORMAT:UTF8,T61:\xe2\x98\x83", nullptr, {}}, + {kTestOID, + "ASN1:FORMAT:UTF8,T61:\xc3\xb7", + nullptr, + {0x30, 0x13, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x03, 0x14, 0x01, 0xf7}}, + + // Invalid UTF-8. + {kTestOID, "ASN1:FORMAT:UTF8,UTF8:\xff", nullptr, {}}, + + // We don't support these string types. + {kTestOID, "ASN1:NUMERIC:0", nullptr, {}}, + {kTestOID, "ASN1:NUMERICSTRING:0", nullptr, {}}, + {kTestOID, "ASN1:VISIBLE:hello", nullptr, {}}, + {kTestOID, "ASN1:VISIBLESTRING:hello", nullptr, {}}, + {kTestOID, "ASN1:GeneralString:hello", nullptr, {}}, + + // OCTET STRING and BIT STRING also default to ASCII, but also accept HEX. + // BIT STRING interprets OCTET STRING formats by having zero unused bits. + {kTestOID, "ASN1:OCT:hello", nullptr, {0x30, 0x17, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x07, 0x04, 0x05, + 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:OCTETSTRING:hello", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x04, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:FORMAT:HEX,OCT:0123abcd", + nullptr, + {0x30, 0x16, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, + 0x04, 0x06, 0x04, 0x04, 0x01, 0x23, 0xab, 0xcd}}, + {kTestOID, + "ASN1:BITSTR:hello", + nullptr, + {0x30, 0x18, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x08, + 0x03, 0x06, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:BITSTRING:hello", + nullptr, + {0x30, 0x18, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x08, + 0x03, 0x06, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f}}, + {kTestOID, + "ASN1:FORMAT:HEX,BITSTR:0123abcd", + nullptr, + {0x30, 0x17, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x07, + 0x03, 0x05, 0x00, 0x01, 0x23, 0xab, 0xcd}}, + + {kTestOID, "ASN1:FORMAT:HEX,OCT:invalid hex", nullptr, {}}, + + // BIT STRING additionally supports a BITLIST type, which specifies a + // list of bits to set. + {kTestOID, + "ASN1:FORMAT:BITLIST,BITSTR:1,5", + nullptr, + {0x30, 0x14, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x04, 0x03, 0x02, 0x02, 0x44}}, + + {kTestOID, "ASN1:FORMAT:BITLIST,BITSTR:1,invalid,5", nullptr, {}}, + // Negative bit inidices are not allowed. + {kTestOID, "ASN1:FORMAT:BITLIST,BITSTR:-1", nullptr, {}}, + // We cap bit indices at 256. + {kTestOID, "ASN1:FORMAT:BITLIST,BITSTR:257", nullptr, {}}, + {kTestOID, + "ASN1:FORMAT:BITLIST,BITSTR:256", + nullptr, + {0x30, 0x34, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x24, 0x03, 0x22, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}}, + + // Unsupported formats for string types. + {kTestOID, "ASN1:FORMAT:BITLIST,IA5:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:BITLIST,UTF8:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:BITLIST,OCT:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:BITLIST,UTC:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:HEX,IA5:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:HEX,UTF8:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:HEX,UTC:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:UTF8,OCT:abcd", nullptr, {}}, + {kTestOID, "ASN1:FORMAT:UTF8,UTC:abcd", nullptr, {}}, + + // Invalid format type. + {kTestOID, "ASN1:FORMAT:invalid,IA5:abcd", nullptr, {}}, + + // SEQUENCE and SET encode empty values when there is no value. + {kTestOID, "ASN1:SEQ", nullptr, {0x30, 0x12, 0x06, 0x0c, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, + 0x09, 0x02, 0x04, 0x02, 0x30, 0x00}}, + {kTestOID, "ASN1:SET", nullptr, {0x30, 0x12, 0x06, 0x0c, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, + 0x09, 0x02, 0x04, 0x02, 0x31, 0x00}}, + {kTestOID, "ASN1:SEQUENCE", nullptr, {0x30, 0x12, 0x06, 0x0c, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, + 0x02, 0x04, 0x02, 0x30, 0x00}}, + + // Otherwise, they require a corresponding section in the config database + // to encode values. This can be nested recursively. + {kTestOID, "ASN1:SEQ:missing_confdb", nullptr, {}}, + {kTestOID, "ASN1:SET:missing_confdb", nullptr, {}}, + {kTestOID, + "ASN1:SEQ:seq", + R"( +[seq] +val1 = NULL +val2 = IA5:a +val3 = SET:set +[set] +# Config names do not matter, only the order. +val4 = INT:1 +val3 = INT:2 +val2 = SEQ:empty +val1 = INT:3 +[empty] +)", + {0x30, 0x24, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x14, 0x30, 0x12, + 0x05, 0x00, 0x16, 0x01, 0x61, 0x31, 0x0b, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0x30, 0x00}}, + + // There is a recursion limit to stop infinite recursion. + {kTestOID, + "ASN1:SEQ:seq1", + R"( +[seq1] +val = SEQ:seq2 +[seq2] +val = SEQ:seq1 +)", + {}}, + + // Various modifiers wrap with explicit tagging or universal types. + {kTestOID, + "ASN1:EXP:0,EXP:16U,EXP:100A,EXP:1000C,OCTWRAP,SEQWRAP,SETWRAP,BITWRAP," + "NULL", + nullptr, + {0x30, 0x26, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x16, 0xa0, 0x14, + 0x30, 0x12, 0x7f, 0x64, 0x0f, 0xbf, 0x87, 0x68, 0x0b, 0x04, + 0x09, 0x30, 0x07, 0x31, 0x05, 0x03, 0x03, 0x00, 0x05, 0x00}}, + + // Invalid tag numbers. + {kTestOID, "ASN1:EXP:-1,NULL", nullptr, {}}, + {kTestOID, "ASN1:EXP:1?,NULL", nullptr, {}}, + // Fits in |uint32_t| but exceeds |CBS_ASN1_TAG_NUMBER_MASK|, the largest + // tag number we support. + {kTestOID, "ASN1:EXP:536870912,NULL", nullptr, {}}, + + // Implicit tagging may also be applied to the underlying type, or the + // wrapping modifiers. + {kTestOID, + "ASN1:IMP:1A,OCTWRAP,IMP:10,SEQWRAP,IMP:100,SETWRAP,IMP:1000,BITWRAP," + "IMP:10000,NULL", + nullptr, + {0x30, 0x20, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, + 0x84, 0xb7, 0x09, 0x02, 0x04, 0x10, 0x41, 0x0e, 0xaa, 0x0c, 0xbf, 0x64, + 0x09, 0x9f, 0x87, 0x68, 0x05, 0x00, 0x9f, 0xce, 0x10, 0x00}}, + + // Implicit tagging may not be applied to explicit tagging or itself. + // There's no rule against this in ASN.1, but OpenSSL does not allow it + // here. + {kTestOID, "ASN1:IMP:1,EXP:1,NULL", nullptr, {}}, + {kTestOID, "ASN1:IMP:1,IMP:1,NULL", nullptr, {}}, + + // [UNIVERSAL 0] is reserved. + {kTestOID, "ASN1:0U,NULL", nullptr, {}}, + + // Leading and trailing spaces on name:value pairs are removed. However, + // while these pairs are delimited by commas, a type will consumes + // everything after it, including commas, and spaces. So this is the + // string " a, b ". + {kTestOID, + "ASN1: EXP:0 , IA5: a, b ", + nullptr, + {0x30, 0x1a, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x0a, 0xa0, 0x08, + 0x16, 0x06, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x20}}, + + // Modifiers without a final type. + {kTestOID, "ASN1:EXP:1", nullptr, {}}, + + // Put it all together to describe a test Ed25519 key (wrapped inside an + // X.509 extension). + {kTestOID, + "ASN1:SEQUENCE:pkcs8", + R"( +[pkcs8] +vers = INT:0 +alg = SEQWRAP,OID:1.3.101.112 +key = FORMAT:HEX,OCTWRAP,OCT:9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 +)", + {0x30, 0x40, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, + 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x30, 0x30, 0x2e, 0x02, 0x01, + 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, + 0x20, 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, + 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, + 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60}}, + + // Sections can be referenced multiple times. + {kTestOID, + "ASN1:SEQUENCE:seq1", + R"( +[seq1] +val1 = SEQUENCE:seq2 +val2 = SEQUENCE:seq2 +[seq2] +val1 = INT:1 +val2 = INT:2 +)", + {0x30, 0x22, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 0x04, 0x12, + 0x30, 0x10, 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x02, 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}}, + + // But we cap this before it blows up exponentially. + {kTestOID, + "ASN1:SEQ:seq1", + R"( +[seq1] +val1 = SEQ:seq2 +val2 = SEQ:seq2 +[seq2] +val1 = SEQ:seq3 +val2 = SEQ:seq3 +[seq3] +val1 = SEQ:seq4 +val2 = SEQ:seq4 +[seq4] +val1 = SEQ:seq5 +val2 = SEQ:seq5 +[seq5] +val1 = SEQ:seq6 +val2 = SEQ:seq6 +[seq6] +val1 = SEQ:seq7 +val2 = SEQ:seq7 +[seq7] +val1 = SEQ:seq8 +val2 = SEQ:seq8 +[seq8] +val1 = SEQ:seq9 +val2 = SEQ:seq9 +[seq9] +val1 = SEQ:seq10 +val2 = SEQ:seq10 +[seq10] +val1 = SEQ:seq11 +val2 = SEQ:seq11 +[seq11] +val1 = SEQ:seq12 +val2 = SEQ:seq12 +[seq12] +val1 = IA5:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +val2 = IA5:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +)", + {}}, + + // Integer sizes are capped to mitigate quadratic behavior. + {kTestOID, "ASN1:INT:" + std::string(16384, '9'), nullptr, {}}, + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.name); + SCOPED_TRACE(t.value); + SCOPED_TRACE(t.conf); + + bssl::UniquePtr conf; + if (t.conf != nullptr) { + conf.reset(NCONF_new(nullptr)); + ASSERT_TRUE(conf); + bssl::UniquePtr bio(BIO_new_mem_buf(t.conf, strlen(t.conf))); + ASSERT_TRUE(bio); + long error_line; + ASSERT_TRUE(NCONF_load_bio(conf.get(), bio.get(), &error_line)) + << "Failed to load config at line " << error_line; + } + + bssl::UniquePtr ext( + X509V3_EXT_nconf(conf.get(), nullptr, t.name, t.value.c_str())); + if (t.expected.empty()) { + EXPECT_FALSE(ext); + } else { + ASSERT_TRUE(ext); + uint8_t *der = nullptr; + int len = i2d_X509_EXTENSION(ext.get(), &der); + ASSERT_GE(len, 0); + bssl::UniquePtr free_der(der); + EXPECT_EQ(Bytes(t.expected), Bytes(der, len)); + } + + // Repeat the test with an explicit |X509V3_CTX|. + X509V3_CTX ctx; + X509V3_set_ctx(&ctx, nullptr, nullptr, nullptr, nullptr, 0); + X509V3_set_nconf(&ctx, conf.get()); + ext.reset(X509V3_EXT_nconf(conf.get(), &ctx, t.name, t.value.c_str())); + if (t.expected.empty()) { + EXPECT_FALSE(ext); + } else { + ASSERT_TRUE(ext); + uint8_t *der = nullptr; + int len = i2d_X509_EXTENSION(ext.get(), &der); + ASSERT_GE(len, 0); + bssl::UniquePtr free_der(der); + EXPECT_EQ(Bytes(t.expected), Bytes(der, len)); + } + } +} + +TEST(X509Test, AddUnserializableExtension) { + bssl::UniquePtr key = PrivateKeyFromPEM(kP256Key); + ASSERT_TRUE(key); + bssl::UniquePtr x509 = + MakeTestCert("Issuer", "Subject", key.get(), /*is_ca=*/true); + ASSERT_TRUE(x509); + bssl::UniquePtr ext(X509_EXTENSION_new()); + ASSERT_TRUE(X509_EXTENSION_set_object(ext.get(), OBJ_nid2obj(NID_undef))); + EXPECT_FALSE(X509_add_ext(x509.get(), ext.get(), /*loc=*/-1)); +} + +// Test that, when constructing an |X509_NAME|, names are sorted by DER order. +TEST(X509Test, SortRDN) { + bssl::UniquePtr name(X509_NAME_new()); + ASSERT_TRUE(name); + + auto append_entry_new_rdn = [&](const char *str) { + return X509_NAME_add_entry_by_NID(name.get(), NID_commonName, MBSTRING_ASC, + reinterpret_cast(str), + strlen(str), /*loc=*/-1, /*set=*/0); + }; + auto append_entry_prev_rdn = [&](const char *str) { + return X509_NAME_add_entry_by_NID(name.get(), NID_commonName, MBSTRING_ASC, + reinterpret_cast(str), + strlen(str), /*loc=*/-1, /*set=*/-1); + }; + + // This is the sort order to expect. + ASSERT_TRUE(append_entry_new_rdn("A")); + ASSERT_TRUE(append_entry_prev_rdn("B")); + ASSERT_TRUE(append_entry_prev_rdn("AA")); + ASSERT_TRUE(append_entry_prev_rdn("AB")); + + // The same RDN, with entries added in a different order. + ASSERT_TRUE(append_entry_new_rdn("AB")); + ASSERT_TRUE(append_entry_prev_rdn("AA")); + ASSERT_TRUE(append_entry_prev_rdn("B")); + ASSERT_TRUE(append_entry_prev_rdn("A")); + + // The same RDN, with entries added in a different order. + ASSERT_TRUE(append_entry_new_rdn("A")); + ASSERT_TRUE(append_entry_prev_rdn("AA")); + ASSERT_TRUE(append_entry_prev_rdn("B")); + ASSERT_TRUE(append_entry_prev_rdn("AB")); + + uint8_t *der = nullptr; + int der_len = i2d_X509_NAME(name.get(), &der); + ASSERT_GT(der_len, 0); + bssl::UniquePtr free_der(der); + + // SEQUENCE { + // SET { + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "A" } + // } + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "B" } + // } + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "AA" } + // } + // SEQUENCE { + // # commonName + // OBJECT_IDENTIFIER { 2.5.4.3 } + // UTF8String { "AB" } + // } + // } + // ...two more copies of the above SET... + // } + static uint8_t kExpected[] = { + 0x30, 0x81, 0x84, 0x31, 0x2a, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x01, 0x41, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x01, + 0x42, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x41, 0x41, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x41, 0x42, 0x31, + 0x2a, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x01, 0x41, 0x30, + 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x01, 0x42, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x41, 0x41, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x02, 0x41, 0x42, 0x31, 0x2a, 0x30, 0x08, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x01, 0x41, 0x30, 0x08, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x01, 0x42, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x02, 0x41, 0x41, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x02, 0x41, 0x42}; + EXPECT_EQ(Bytes(kExpected), Bytes(der, der_len)); +} + +TEST(X509Test, NameAttributeValues) { + // 1.2.840.113554.4.1.72585.0. We use an unrecognized OID because using an + // arbitrary ASN.1 type as the value for commonName is invalid. Our parser + // does not check this, but best to avoid unrelated errors in tests, in case + // we decide to later. + static const uint8_t kOID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, + 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00}; + + const struct { + CBS_ASN1_TAG der_tag; + std::string der_contents; + int str_type; + std::string str_contents; + } kTests[] = { + // String types are parsed as string types. + {CBS_ASN1_BITSTRING, std::string("\0", 1), V_ASN1_BIT_STRING, ""}, + {CBS_ASN1_UTF8STRING, "abc", V_ASN1_UTF8STRING, "abc"}, + {CBS_ASN1_NUMERICSTRING, "123", V_ASN1_NUMERICSTRING, "123"}, + {CBS_ASN1_PRINTABLESTRING, "abc", V_ASN1_PRINTABLESTRING, "abc"}, + {CBS_ASN1_T61STRING, "abc", V_ASN1_T61STRING, "abc"}, + {CBS_ASN1_IA5STRING, "abc", V_ASN1_IA5STRING, "abc"}, + {CBS_ASN1_UNIVERSALSTRING, std::string("\0\0\0a", 4), + V_ASN1_UNIVERSALSTRING, std::string("\0\0\0a", 4)}, + {CBS_ASN1_BMPSTRING, std::string("\0a", 2), V_ASN1_BMPSTRING, + std::string("\0a", 2)}, + + // ENUMERATED is supported but, currently, INTEGER is not. + {CBS_ASN1_ENUMERATED, "\x01", V_ASN1_ENUMERATED, "\x01"}, + + // SEQUENCE is supported but, currently, SET is not. Note the + // |ASN1_STRING| representation will include the tag and length. + {CBS_ASN1_SEQUENCE, "", V_ASN1_SEQUENCE, std::string("\x30\x00", 2)}, + + // These types are not actually supported by the library but, + // historically, we would parse them, and not other unsupported types, due + // to quirks of |ASN1_tag2bit|. + {7, "", V_ASN1_OBJECT_DESCRIPTOR, ""}, + {8, "", V_ASN1_EXTERNAL, ""}, + {9, "", V_ASN1_REAL, ""}, + {11, "", 11 /* EMBEDDED PDV */, ""}, + {13, "", 13 /* RELATIVE-OID */, ""}, + {14, "", 14 /* TIME */, ""}, + {15, "", 15 /* not a type; reserved value */, ""}, + {29, "", 29 /* CHARACTER STRING */, ""}, + + // TODO(crbug.com/boringssl/412): Attribute values are an ANY DEFINED BY + // type, so we actually shoudl be accepting all ASN.1 types. We currently + // do not and only accept the above types. Extend this test when we fix + // this. + }; + for (const auto &t : kTests) { + SCOPED_TRACE(t.der_tag); + SCOPED_TRACE(Bytes(t.der_contents)); + + // Construct an X.509 name containing a single RDN with a single attribute: + // kOID with the specified value. + bssl::ScopedCBB cbb; + ASSERT_TRUE(CBB_init(cbb.get(), 128)); + CBB seq, rdn, attr, attr_type, attr_value; + ASSERT_TRUE(CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE)); + ASSERT_TRUE(CBB_add_asn1(&seq, &rdn, CBS_ASN1_SET)); + ASSERT_TRUE(CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE)); + ASSERT_TRUE(CBB_add_asn1(&attr, &attr_type, CBS_ASN1_OBJECT)); + ASSERT_TRUE(CBB_add_bytes(&attr_type, kOID, sizeof(kOID))); + ASSERT_TRUE(CBB_add_asn1(&attr, &attr_value, t.der_tag)); + ASSERT_TRUE(CBB_add_bytes( + &attr_value, reinterpret_cast(t.der_contents.data()), + t.der_contents.size())); + ASSERT_TRUE(CBB_flush(cbb.get())); + SCOPED_TRACE(Bytes(CBB_data(cbb.get()), CBB_len(cbb.get()))); + + // The input should parse. + const uint8_t *inp = CBB_data(cbb.get()); + bssl::UniquePtr name( + d2i_X509_NAME(nullptr, &inp, CBB_len(cbb.get()))); + ASSERT_TRUE(name); + EXPECT_EQ(inp, CBB_data(cbb.get()) + CBB_len(cbb.get())) + << "input was not fully consumed"; + + // Check there is a single attribute with the expected in-memory + // representation. + ASSERT_EQ(1, X509_NAME_entry_count(name.get())); + const X509_NAME_ENTRY *entry = X509_NAME_get_entry(name.get(), 0); + const ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(entry); + EXPECT_EQ(Bytes(OBJ_get0_data(obj), OBJ_length(obj)), Bytes(kOID)); + const ASN1_STRING *value = X509_NAME_ENTRY_get_data(entry); + EXPECT_EQ(ASN1_STRING_type(value), t.str_type); + EXPECT_EQ(Bytes(ASN1_STRING_get0_data(value), ASN1_STRING_length(value)), + Bytes(t.str_contents)); + + // The name should re-encode with the same input. + uint8_t *der = nullptr; + int der_len = i2d_X509_NAME(name.get(), &der); + ASSERT_GE(der_len, 0); + bssl::UniquePtr free_der(der); + EXPECT_EQ(Bytes(der, der_len), + (Bytes(CBB_data(cbb.get()), CBB_len(cbb.get())))); + } } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_time_test.cc b/third_party/boringssl/kit/src/crypto/x509/x509_time_test.cc index fcd51c89..7abb10d1 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_time_test.cc +++ b/third_party/boringssl/kit/src/crypto/x509/x509_time_test.cc @@ -20,7 +20,7 @@ struct TestData { const char *data; int type; - time_t cmp_time; + int64_t cmp_time; // -1 if asn1_time <= cmp_time, 1 if asn1_time > cmp_time, 0 if error. int expected; }; @@ -211,21 +211,96 @@ static TestData kX509CmpTests[] = { 0, 0, }, + // Test limits and unusual cases. + { + "99991231235959Z", V_ASN1_GENERALIZEDTIME, + // Test a very large positive time with the largest representable time + 253402300799, + -1, // TODO(bbe): This is *technically* wrong by rfc5280. + }, + { + "99991231235959Z", V_ASN1_GENERALIZEDTIME, + // one second after the largest possible time should still compare + // correctly + 253402300800, + -1, // TODO(bbe): This is *technically* wrong by rfc5280. + }, + { + "99991231235959Z", + V_ASN1_GENERALIZEDTIME, + // Test one second before the largest time + 253402300798, + 1, + }, + { + "700101000000Z", + V_ASN1_UTCTIME, + // The epoch, which should not fail. a time of 0 must be valid. + 0, + -1, + }, + { + "700101000000Z", + V_ASN1_UTCTIME, + // One second before the epoch should compare correctly. + -1, + 1, + }, + { + "700101000000Z", + V_ASN1_UTCTIME, + // One second after the epoch should compare correctly. + 1, + -1, + }, + { + "690621025615Z", + V_ASN1_UTCTIME, + // Test a negative time, we use a time from NASA, close to but not quite + // at the epoch. + -16751025, + -1, + }, + { + "690621025615Z", + V_ASN1_UTCTIME, + // Test one small second before our negative time. + -16751026, + 1, + }, + { + "690621025615Z", + V_ASN1_UTCTIME, + // Test one giant second after our negative time. + -16751024, + -1, + }, + { + "00000101000000Z", + V_ASN1_GENERALIZEDTIME, + // Test a very large negative time with the earliest representable time + -62167219200, + -1, + }, + { + "00000101000000Z", + V_ASN1_GENERALIZEDTIME, + // Test one second after the earliest time. + -62167219199, + -1, + }, + }; TEST(X509TimeTest, TestCmpTime) { for (auto &test : kX509CmpTests) { SCOPED_TRACE(test.data); - ASN1_TIME t; + bssl::UniquePtr t(ASN1_STRING_type_new(test.type)); + ASSERT_TRUE(t); + ASSERT_TRUE(ASN1_STRING_set(t.get(), test.data, strlen(test.data))); - memset(&t, 0, sizeof(t)); - t.type = test.type; - t.data = (unsigned char*) test.data; - t.length = strlen(test.data); - - EXPECT_EQ(test.expected, - X509_cmp_time(&t, &test.cmp_time)); + EXPECT_EQ(test.expected, X509_cmp_time_posix(t.get(), test.cmp_time)); } } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_trs.c b/third_party/boringssl/kit/src/crypto/x509/x509_trs.c index c95d6fca..71cf71dc 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_trs.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_trs.c @@ -63,7 +63,7 @@ #include "internal.h" -static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b); +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); static void trtable_free(X509_TRUST *p); static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); @@ -71,13 +71,10 @@ static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); static int trust_compat(X509_TRUST *trust, X509 *x, int flags); static int obj_trust(int id, X509 *x, int flags); -static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; -/* - * WARNING: the following table should be kept in order of trust and without - * any gaps so we can just subtract the minimum trust value to get an index - * into the table - */ +// WARNING: the following table should be kept in order of trust and without +// any gaps so we can just subtract the minimum trust value to get an index +// into the table static X509_TRUST trstandard[] = { {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL}, @@ -94,238 +91,224 @@ static X509_TRUST trstandard[] = { {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request", NID_ad_OCSP, NULL}, {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp, - NULL} -}; + NULL}}; -#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) +#define X509_TRUST_COUNT (sizeof(trstandard) / sizeof(X509_TRUST)) static STACK_OF(X509_TRUST) *trtable = NULL; -static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b) -{ - return (*a)->trust - (*b)->trust; +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) { + return (*a)->trust - (*b)->trust; } -int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, - int) { - int (*oldtrust) (int, X509 *, int); - oldtrust = default_trust; - default_trust = trust; - return oldtrust; -} - -int X509_check_trust(X509 *x, int id, int flags) -{ - X509_TRUST *pt; - int idx; - if (id == -1) - return 1; - /* We get this as a default value */ - if (id == 0) { - int rv; - rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); - if (rv != X509_TRUST_UNTRUSTED) - return rv; - return trust_compat(NULL, x, 0); +int X509_check_trust(X509 *x, int id, int flags) { + X509_TRUST *pt; + int idx; + if (id == -1) { + return 1; + } + // We get this as a default value + if (id == 0) { + int rv; + rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); + if (rv != X509_TRUST_UNTRUSTED) { + return rv; } - idx = X509_TRUST_get_by_id(id); - if (idx == -1) - return default_trust(id, x, flags); - pt = X509_TRUST_get0(idx); - return pt->check_trust(pt, x, flags); + return trust_compat(NULL, x, 0); + } + idx = X509_TRUST_get_by_id(id); + if (idx == -1) { + return obj_trust(id, x, flags); + } + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); } -int X509_TRUST_get_count(void) -{ - if (!trtable) - return X509_TRUST_COUNT; - return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +int X509_TRUST_get_count(void) { + if (!trtable) { + return X509_TRUST_COUNT; + } + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; } -X509_TRUST *X509_TRUST_get0(int idx) -{ - if (idx < 0) - return NULL; - if (idx < (int)X509_TRUST_COUNT) - return trstandard + idx; - return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +X509_TRUST *X509_TRUST_get0(int idx) { + if (idx < 0) { + return NULL; + } + if (idx < (int)X509_TRUST_COUNT) { + return trstandard + idx; + } + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); } -int X509_TRUST_get_by_id(int id) -{ - X509_TRUST tmp; - size_t idx; +int X509_TRUST_get_by_id(int id) { + X509_TRUST tmp; + size_t idx; - if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) - return id - X509_TRUST_MIN; - tmp.trust = id; - if (!trtable) - return -1; + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) { + return id - X509_TRUST_MIN; + } + tmp.trust = id; + if (!trtable) { + return -1; + } + if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { + return -1; + } + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) { + if (X509_TRUST_get_by_id(trust) == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2) { + int idx; + X509_TRUST *trtmp; + char *name_dup; + + // This is set according to what we change: application can't set it + flags &= ~X509_TRUST_DYNAMIC; + // This will always be set for application modified trust entries + flags |= X509_TRUST_DYNAMIC_NAME; + // Get existing entry if any + idx = X509_TRUST_get_by_id(id); + // Need a new entry + if (idx == -1) { + if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else { + trtmp = X509_TRUST_get0(idx); + } + + // Duplicate the supplied name. + name_dup = OPENSSL_strdup(name); + if (name_dup == NULL) { + if (idx == -1) { + OPENSSL_free(trtmp); + } + return 0; + } + + // OPENSSL_free existing name if dynamic + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) { + OPENSSL_free(trtmp->name); + } + trtmp->name = name_dup; + // Keep the dynamic flag of existing entry + trtmp->flags &= X509_TRUST_DYNAMIC; + // Set all other flags + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + // If its a new entry manage the dynamic table + if (idx == -1) { + // TODO(davidben): This should be locked. Alternatively, remove the dynamic + // registration mechanism entirely. The trouble is there no way to pass in + // the various parameters into an |X509_VERIFY_PARAM| directly. You can only + // register it in the global table and get an ID. + if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { + trtable_free(trtmp); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + trtable_free(trtmp); + return 0; + } sk_X509_TRUST_sort(trtable); - if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { - return -1; + } + return 1; +} + +static void trtable_free(X509_TRUST *p) { + if (!p) { + return; + } + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) { + OPENSSL_free(p->name); } - return idx + X509_TRUST_COUNT; + OPENSSL_free(p); + } } -int X509_TRUST_set(int *t, int trust) -{ - if (X509_TRUST_get_by_id(trust) == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST); - return 0; - } - *t = trust; - return 1; +void X509_TRUST_cleanup(void) { + unsigned int i; + for (i = 0; i < X509_TRUST_COUNT; i++) { + trtable_free(trstandard + i); + } + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; } -int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), - char *name, int arg1, void *arg2) -{ - int idx; - X509_TRUST *trtmp; - char *name_dup; +int X509_TRUST_get_flags(const X509_TRUST *xp) { return xp->flags; } - /* - * This is set according to what we change: application can't set it - */ - flags &= ~X509_TRUST_DYNAMIC; - /* This will always be set for application modified trust entries */ - flags |= X509_TRUST_DYNAMIC_NAME; - /* Get existing entry if any */ - idx = X509_TRUST_get_by_id(id); - /* Need a new entry */ - if (idx == -1) { - if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; - } - trtmp->flags = X509_TRUST_DYNAMIC; - } else - trtmp = X509_TRUST_get0(idx); +char *X509_TRUST_get0_name(const X509_TRUST *xp) { return xp->name; } - /* Duplicate the supplied name. */ - name_dup = OPENSSL_strdup(name); - if (name_dup == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - if (idx == -1) - OPENSSL_free(trtmp); - return 0; - } +int X509_TRUST_get_trust(const X509_TRUST *xp) { return xp->trust; } - /* OPENSSL_free existing name if dynamic */ - if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) - OPENSSL_free(trtmp->name); - trtmp->name = name_dup; - /* Keep the dynamic flag of existing entry */ - trtmp->flags &= X509_TRUST_DYNAMIC; - /* Set all other flags */ - trtmp->flags |= flags; - - trtmp->trust = id; - trtmp->check_trust = ck; - trtmp->arg1 = arg1; - trtmp->arg2 = arg2; - - /* If its a new entry manage the dynamic table */ - if (idx == -1) { - if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - trtable_free(trtmp); - return 0; - } - if (!sk_X509_TRUST_push(trtable, trtmp)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - trtable_free(trtmp); - return 0; - } - } - return 1; +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) { + if (x->aux && (x->aux->trust || x->aux->reject)) { + return obj_trust(trust->arg1, x, flags); + } + // we don't have any trust settings: for compatibility we return trusted + // if it is self signed + return trust_compat(trust, x, flags); } -static void trtable_free(X509_TRUST *p) -{ - if (!p) - return; - if (p->flags & X509_TRUST_DYNAMIC) { - if (p->flags & X509_TRUST_DYNAMIC_NAME) - OPENSSL_free(p->name); - OPENSSL_free(p); - } +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) { + if (x->aux) { + return obj_trust(trust->arg1, x, flags); + } + return X509_TRUST_UNTRUSTED; } -void X509_TRUST_cleanup(void) -{ - unsigned int i; - for (i = 0; i < X509_TRUST_COUNT; i++) - trtable_free(trstandard + i); - sk_X509_TRUST_pop_free(trtable, trtable_free); - trtable = NULL; -} - -int X509_TRUST_get_flags(const X509_TRUST *xp) -{ - return xp->flags; -} - -char *X509_TRUST_get0_name(const X509_TRUST *xp) -{ - return xp->name; -} - -int X509_TRUST_get_trust(const X509_TRUST *xp) -{ - return xp->trust; -} - -static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux && (x->aux->trust || x->aux->reject)) - return obj_trust(trust->arg1, x, flags); - /* - * we don't have any trust settings: for compatibility we return trusted - * if it is self signed - */ - return trust_compat(trust, x, flags); -} - -static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux) - return obj_trust(trust->arg1, x, flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) { + if (!x509v3_cache_extensions(x)) { return X509_TRUST_UNTRUSTED; + } + if (x->ex_flags & EXFLAG_SS) { + return X509_TRUST_TRUSTED; + } else { + return X509_TRUST_UNTRUSTED; + } } -static int trust_compat(X509_TRUST *trust, X509 *x, int flags) -{ - if (!x509v3_cache_extensions(x)) - return X509_TRUST_UNTRUSTED; - if (x->ex_flags & EXFLAG_SS) +static int obj_trust(int id, X509 *x, int flags) { + ASN1_OBJECT *obj; + size_t i; + X509_CERT_AUX *ax; + ax = x->aux; + if (!ax) { + return X509_TRUST_UNTRUSTED; + } + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if (OBJ_obj2nid(obj) == id) { + return X509_TRUST_REJECTED; + } + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if (OBJ_obj2nid(obj) == id) { return X509_TRUST_TRUSTED; - else - return X509_TRUST_UNTRUSTED; -} - -static int obj_trust(int id, X509 *x, int flags) -{ - ASN1_OBJECT *obj; - size_t i; - X509_CERT_AUX *ax; - ax = x->aux; - if (!ax) - return X509_TRUST_UNTRUSTED; - if (ax->reject) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { - obj = sk_ASN1_OBJECT_value(ax->reject, i); - if (OBJ_obj2nid(obj) == id) - return X509_TRUST_REJECTED; - } + } } - if (ax->trust) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { - obj = sk_ASN1_OBJECT_value(ax->trust, i); - if (OBJ_obj2nid(obj) == id) - return X509_TRUST_TRUSTED; - } - } - return X509_TRUST_UNTRUSTED; + } + return X509_TRUST_UNTRUSTED; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_txt.c b/third_party/boringssl/kit/src/crypto/x509/x509_txt.c index 17e14a62..45e8322b 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_txt.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_txt.c @@ -56,149 +56,134 @@ #include -const char *X509_verify_cert_error_string(long err) -{ - switch (err) { +const char *X509_verify_cert_error_string(long err) { + switch (err) { case X509_V_OK: - return "ok"; + return "ok"; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - return "unable to get issuer certificate"; + return "unable to get issuer certificate"; case X509_V_ERR_UNABLE_TO_GET_CRL: - return "unable to get certificate CRL"; + return "unable to get certificate CRL"; case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - return "unable to decrypt certificate's signature"; + return "unable to decrypt certificate's signature"; case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - return "unable to decrypt CRL's signature"; + return "unable to decrypt CRL's signature"; case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - return "unable to decode issuer public key"; + return "unable to decode issuer public key"; case X509_V_ERR_CERT_SIGNATURE_FAILURE: - return "certificate signature failure"; + return "certificate signature failure"; case X509_V_ERR_CRL_SIGNATURE_FAILURE: - return "CRL signature failure"; + return "CRL signature failure"; case X509_V_ERR_CERT_NOT_YET_VALID: - return "certificate is not yet valid"; + return "certificate is not yet valid"; case X509_V_ERR_CRL_NOT_YET_VALID: - return "CRL is not yet valid"; + return "CRL is not yet valid"; case X509_V_ERR_CERT_HAS_EXPIRED: - return "certificate has expired"; + return "certificate has expired"; case X509_V_ERR_CRL_HAS_EXPIRED: - return "CRL has expired"; + return "CRL has expired"; case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - return "format error in certificate's notBefore field"; + return "format error in certificate's notBefore field"; case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - return "format error in certificate's notAfter field"; + return "format error in certificate's notAfter field"; case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - return "format error in CRL's lastUpdate field"; + return "format error in CRL's lastUpdate field"; case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - return "format error in CRL's nextUpdate field"; + return "format error in CRL's nextUpdate field"; case X509_V_ERR_OUT_OF_MEM: - return "out of memory"; + return "out of memory"; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - return "self signed certificate"; + return "self signed certificate"; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - return "self signed certificate in certificate chain"; + return "self signed certificate in certificate chain"; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - return "unable to get local issuer certificate"; + return "unable to get local issuer certificate"; case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - return "unable to verify the first certificate"; + return "unable to verify the first certificate"; case X509_V_ERR_CERT_CHAIN_TOO_LONG: - return "certificate chain too long"; + return "certificate chain too long"; case X509_V_ERR_CERT_REVOKED: - return "certificate revoked"; + return "certificate revoked"; case X509_V_ERR_INVALID_CA: - return "invalid CA certificate"; + return "invalid CA certificate"; case X509_V_ERR_INVALID_NON_CA: - return "invalid non-CA certificate (has CA markings)"; + return "invalid non-CA certificate (has CA markings)"; case X509_V_ERR_PATH_LENGTH_EXCEEDED: - return "path length constraint exceeded"; + return "path length constraint exceeded"; case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: - return "proxy path length constraint exceeded"; + return "proxy path length constraint exceeded"; case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - return - "proxy certificates not allowed, please set the appropriate flag"; + return "proxy certificates not allowed, please set the appropriate flag"; case X509_V_ERR_INVALID_PURPOSE: - return "unsupported certificate purpose"; + return "unsupported certificate purpose"; case X509_V_ERR_CERT_UNTRUSTED: - return "certificate not trusted"; + return "certificate not trusted"; case X509_V_ERR_CERT_REJECTED: - return "certificate rejected"; + return "certificate rejected"; case X509_V_ERR_APPLICATION_VERIFICATION: - return "application verification failure"; + return "application verification failure"; case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: - return "subject issuer mismatch"; + return "subject issuer mismatch"; case X509_V_ERR_AKID_SKID_MISMATCH: - return "authority and subject key identifier mismatch"; + return "authority and subject key identifier mismatch"; case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: - return "authority and issuer serial number mismatch"; + return "authority and issuer serial number mismatch"; case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - return "key usage does not include certificate signing"; + return "key usage does not include certificate signing"; case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - return "unable to get CRL issuer certificate"; + return "unable to get CRL issuer certificate"; case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: - return "unhandled critical extension"; + return "unhandled critical extension"; case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: - return "key usage does not include CRL signing"; + return "key usage does not include CRL signing"; case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: - return "key usage does not include digital signature"; + return "key usage does not include digital signature"; case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: - return "unhandled critical CRL extension"; + return "unhandled critical CRL extension"; case X509_V_ERR_INVALID_EXTENSION: - return "invalid or inconsistent certificate extension"; + return "invalid or inconsistent certificate extension"; case X509_V_ERR_INVALID_POLICY_EXTENSION: - return "invalid or inconsistent certificate policy extension"; + return "invalid or inconsistent certificate policy extension"; case X509_V_ERR_NO_EXPLICIT_POLICY: - return "no explicit policy"; + return "no explicit policy"; case X509_V_ERR_DIFFERENT_CRL_SCOPE: - return "Different CRL scope"; + return "Different CRL scope"; case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: - return "Unsupported extension feature"; + return "Unsupported extension feature"; case X509_V_ERR_UNNESTED_RESOURCE: - return "RFC 3779 resource not subset of parent's resources"; + return "RFC 3779 resource not subset of parent's resources"; case X509_V_ERR_PERMITTED_VIOLATION: - return "permitted subtree violation"; + return "permitted subtree violation"; case X509_V_ERR_EXCLUDED_VIOLATION: - return "excluded subtree violation"; + return "excluded subtree violation"; case X509_V_ERR_SUBTREE_MINMAX: - return "name constraints minimum and maximum not supported"; + return "name constraints minimum and maximum not supported"; case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: - return "unsupported name constraint type"; + return "unsupported name constraint type"; case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: - return "unsupported or invalid name constraint syntax"; + return "unsupported or invalid name constraint syntax"; case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: - return "unsupported or invalid name syntax"; + return "unsupported or invalid name syntax"; case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: - return "CRL path validation error"; - - case X509_V_ERR_SUITE_B_INVALID_VERSION: - return "Suite B: certificate version invalid"; - case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: - return "Suite B: invalid public key algorithm"; - case X509_V_ERR_SUITE_B_INVALID_CURVE: - return "Suite B: invalid ECC curve"; - case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: - return "Suite B: invalid signature algorithm"; - case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: - return "Suite B: curve not allowed for this LOS"; - case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: - return "Suite B: cannot sign P-384 with P-256"; + return "CRL path validation error"; case X509_V_ERR_HOSTNAME_MISMATCH: - return "Hostname mismatch"; + return "Hostname mismatch"; case X509_V_ERR_EMAIL_MISMATCH: - return "Email address mismatch"; + return "Email address mismatch"; case X509_V_ERR_IP_ADDRESS_MISMATCH: - return "IP address mismatch"; + return "IP address mismatch"; case X509_V_ERR_INVALID_CALL: - return "Invalid certificate verification context"; + return "Invalid certificate verification context"; case X509_V_ERR_STORE_LOOKUP: - return "Issuer certificate lookup error"; + return "Issuer certificate lookup error"; case X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS: - return "Issuer has name constraints but leaf has no SANs"; + return "Issuer has name constraints but leaf has no SANs"; default: - return "unknown certificate verification error"; - } + return "unknown certificate verification error"; + } } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_v3.c b/third_party/boringssl/kit/src/crypto/x509/x509_v3.c index 985161d5..0f506c9d 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_v3.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_v3.c @@ -65,217 +65,228 @@ #include "internal.h" -int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) -{ - if (x == NULL) - return (0); - return (sk_X509_EXTENSION_num(x)); +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) { + if (x == NULL) { + return 0; + } + return (int)sk_X509_EXTENSION_num(x); } int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, - int lastpos) -{ - const ASN1_OBJECT *obj = OBJ_nid2obj(nid); - if (obj == NULL) { - return -1; - } - return X509v3_get_ext_by_OBJ(x, obj, lastpos); + int lastpos) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -1; + } + return X509v3_get_ext_by_OBJ(x, obj, lastpos); } int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, - const ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_EXTENSION *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_EXTENSION_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_EXTENSION_value(sk, lastpos); - if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); + const ASN1_OBJECT *obj, int lastpos) { + if (sk == NULL) { + return -1; + } + lastpos++; + if (lastpos < 0) { + lastpos = 0; + } + int n = (int)sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) { + return lastpos; } - return (-1); + } + return -1; } int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, - int lastpos) -{ - if (sk == NULL) { - return -1; - } - - lastpos++; - if (lastpos < 0) { - lastpos = 0; - } - - crit = !!crit; - int n = sk_X509_EXTENSION_num(sk); - for (; lastpos < n; lastpos++) { - const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos); - if (X509_EXTENSION_get_critical(ex) == crit) { - return lastpos; - } - } + int lastpos) { + if (sk == NULL) { return -1; + } + + lastpos++; + if (lastpos < 0) { + lastpos = 0; + } + + crit = !!crit; + int n = (int)sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + const X509_EXTENSION *ex = sk_X509_EXTENSION_value(sk, lastpos); + if (X509_EXTENSION_get_critical(ex) == crit) { + return lastpos; + } + } + return -1; } -X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) -{ - if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) - return NULL; - else - return sk_X509_EXTENSION_value(x, loc); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) { + if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) { + return NULL; + } else { + return sk_X509_EXTENSION_value(x, loc); + } } -X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) -{ - X509_EXTENSION *ret; +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) { + X509_EXTENSION *ret; - if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) - return (NULL); - ret = sk_X509_EXTENSION_delete(x, loc); - return (ret); + if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) { + return NULL; + } + ret = sk_X509_EXTENSION_delete(x, loc); + return ret; } STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, - X509_EXTENSION *ex, int loc) -{ - X509_EXTENSION *new_ex = NULL; - int n; - STACK_OF(X509_EXTENSION) *sk = NULL; + const X509_EXTENSION *ex, int loc) { + X509_EXTENSION *new_ex = NULL; + STACK_OF(X509_EXTENSION) *sk = NULL; + int free_sk = 0; - if (x == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - goto err2; + if (x == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) { + goto err; } + free_sk = 1; + } else { + sk = *x; + } - if (*x == NULL) { - if ((sk = sk_X509_EXTENSION_new_null()) == NULL) - goto err; - } else - sk = *x; + int n = (int)sk_X509_EXTENSION_num(sk); + if (loc > n) { + loc = n; + } else if (loc < 0) { + loc = n; + } - n = sk_X509_EXTENSION_num(sk); - if (loc > n) - loc = n; - else if (loc < 0) - loc = n; + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) { + goto err; + } + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) { + goto err; + } + if (*x == NULL) { + *x = sk; + } + return sk; - if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) - goto err2; - if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) - goto err; - if (*x == NULL) - *x = sk; - return (sk); - err: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - err2: - X509_EXTENSION_free(new_ex); +err: + X509_EXTENSION_free(new_ex); + if (free_sk) { sk_X509_EXTENSION_free(sk); - return NULL; + } + return NULL; } X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, - const ASN1_OCTET_STRING *data) -{ - const ASN1_OBJECT *obj; - X509_EXTENSION *ret; + const ASN1_OCTET_STRING *data) { + const ASN1_OBJECT *obj; + X509_EXTENSION *ret; - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); - return (NULL); - } - ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); - return (ret); + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + return ret; } X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, const ASN1_OBJECT *obj, int crit, - const ASN1_OCTET_STRING *data) -{ - X509_EXTENSION *ret; + const ASN1_OCTET_STRING *data) { + X509_EXTENSION *ret; - if ((ex == NULL) || (*ex == NULL)) { - if ((ret = X509_EXTENSION_new()) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return (NULL); - } - } else - ret = *ex; + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + return NULL; + } + } else { + ret = *ex; + } - if (!X509_EXTENSION_set_object(ret, obj)) - goto err; - if (!X509_EXTENSION_set_critical(ret, crit)) - goto err; - if (!X509_EXTENSION_set_data(ret, data)) - goto err; + if (!X509_EXTENSION_set_object(ret, obj)) { + goto err; + } + if (!X509_EXTENSION_set_critical(ret, crit)) { + goto err; + } + if (!X509_EXTENSION_set_data(ret, data)) { + goto err; + } - if ((ex != NULL) && (*ex == NULL)) - *ex = ret; - return (ret); - err: - if ((ex == NULL) || (ret != *ex)) - X509_EXTENSION_free(ret); - return (NULL); + if ((ex != NULL) && (*ex == NULL)) { + *ex = ret; + } + return ret; +err: + if ((ex == NULL) || (ret != *ex)) { + X509_EXTENSION_free(ret); + } + return NULL; } -int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) -{ - if ((ex == NULL) || (obj == NULL)) - return (0); - ASN1_OBJECT_free(ex->object); - ex->object = OBJ_dup(obj); - return ex->object != NULL; -} - -int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) -{ - if (ex == NULL) - return (0); - ex->critical = (crit) ? 0xFF : -1; - return (1); -} - -int X509_EXTENSION_set_data(X509_EXTENSION *ex, const ASN1_OCTET_STRING *data) -{ - int i; - - if (ex == NULL) - return (0); - i = ASN1_OCTET_STRING_set(ex->value, data->data, data->length); - if (!i) - return (0); - return (1); -} - -ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) -{ - if (ex == NULL) - return (NULL); - return (ex->object); -} - -ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) -{ - if (ex == NULL) - return (NULL); - return (ex->value); -} - -int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) -{ - if (ex == NULL) - return (0); - if (ex->critical > 0) - return 1; +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) { + if ((ex == NULL) || (obj == NULL)) { return 0; + } + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} + +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) { + if (ex == NULL) { + return 0; + } + // The critical field is DEFAULT FALSE, so non-critical extensions should omit + // the value. + ex->critical = crit ? ASN1_BOOLEAN_TRUE : ASN1_BOOLEAN_NONE; + return 1; +} + +int X509_EXTENSION_set_data(X509_EXTENSION *ex, const ASN1_OCTET_STRING *data) { + int i; + + if (ex == NULL) { + return 0; + } + i = ASN1_OCTET_STRING_set(ex->value, data->data, data->length); + if (!i) { + return 0; + } + return 1; +} + +ASN1_OBJECT *X509_EXTENSION_get_object(const X509_EXTENSION *ex) { + if (ex == NULL) { + return NULL; + } + return ex->object; +} + +ASN1_OCTET_STRING *X509_EXTENSION_get_data(const X509_EXTENSION *ex) { + if (ex == NULL) { + return NULL; + } + return ex->value; +} + +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) { + if (ex == NULL) { + return 0; + } + if (ex->critical > 0) { + return 1; + } + return 0; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_vfy.c b/third_party/boringssl/kit/src/crypto/x509/x509_vfy.c index 2dfdce20..a725d00d 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_vfy.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_vfy.c @@ -67,50 +67,51 @@ #include #include -#include "internal.h" #include "../internal.h" #include "../x509v3/internal.h" +#include "internal.h" static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; -/* CRL score values */ +// CRL score values -/* No unhandled critical extensions */ +// No unhandled critical extensions -#define CRL_SCORE_NOCRITICAL 0x100 +#define CRL_SCORE_NOCRITICAL 0x100 -/* certificate is within CRL scope */ +// certificate is within CRL scope -#define CRL_SCORE_SCOPE 0x080 +#define CRL_SCORE_SCOPE 0x080 -/* CRL times valid */ +// CRL times valid -#define CRL_SCORE_TIME 0x040 +#define CRL_SCORE_TIME 0x040 -/* Issuer name matches certificate */ +// Issuer name matches certificate -#define CRL_SCORE_ISSUER_NAME 0x020 +#define CRL_SCORE_ISSUER_NAME 0x020 -/* If this score or above CRL is probably valid */ +// If this score or above CRL is probably valid -#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) +#define CRL_SCORE_VALID \ + (CRL_SCORE_NOCRITICAL | CRL_SCORE_TIME | CRL_SCORE_SCOPE) -/* CRL issuer is certificate issuer */ +// CRL issuer is certificate issuer -#define CRL_SCORE_ISSUER_CERT 0x018 +#define CRL_SCORE_ISSUER_CERT 0x018 -/* CRL issuer is on certificate path */ +// CRL issuer is on certificate path -#define CRL_SCORE_SAME_PATH 0x008 +#define CRL_SCORE_SAME_PATH 0x008 -/* CRL issuer matches CRL AKID */ +// CRL issuer matches CRL AKID -#define CRL_SCORE_AKID 0x004 +#define CRL_SCORE_AKID 0x004 -/* Have a delta CRL with valid times */ +// Have a delta CRL with valid times -#define CRL_SCORE_TIME_DELTA 0x002 +#define CRL_SCORE_TIME_DELTA 0x002 static int null_callback(int ok, X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); @@ -125,2332 +126,2144 @@ static int check_policy(X509_STORE_CTX *ctx); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, X509_CRL *crl, X509 *x); -static int get_crl_delta(X509_STORE_CTX *ctx, - X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); -static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, - int *pcrl_score, X509_CRL *base, - STACK_OF(X509_CRL) *crls); +static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, + X509_CRL *base, STACK_OF(X509_CRL) *crls); static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score); static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons); static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); -static int check_crl_chain(X509_STORE_CTX *ctx, - STACK_OF(X509) *cert_path, +static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, STACK_OF(X509) *crl_path); static int internal_verify(X509_STORE_CTX *ctx); -static int null_callback(int ok, X509_STORE_CTX *e) -{ - return ok; +static int null_callback(int ok, X509_STORE_CTX *e) { return ok; } + +// cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns +// one and sets |*out_is_self_signed| to the result. If |x| is invalid, it +// returns zero. +static int cert_self_signed(X509 *x, int *out_is_self_signed) { + if (!x509v3_cache_extensions(x)) { + return 0; + } + *out_is_self_signed = (x->ex_flags & EXFLAG_SS) != 0; + return 1; } -/* cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns - * one and sets |*out_is_self_signed| to the result. If |x| is invalid, it - * returns zero. */ -static int cert_self_signed(X509 *x, int *out_is_self_signed) -{ - if (!x509v3_cache_extensions(x)) { - return 0; +// Given a certificate try and find an exact match in the store + +static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) { + STACK_OF(X509) *certs; + X509 *xtmp = NULL; + size_t i; + // Lookup all certs with matching subject name + certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + if (certs == NULL) { + return NULL; + } + // Look for exact match + for (i = 0; i < sk_X509_num(certs); i++) { + xtmp = sk_X509_value(certs, i); + if (!X509_cmp(xtmp, x)) { + break; } - *out_is_self_signed = (x->ex_flags & EXFLAG_SS) != 0; - return 1; + } + if (i < sk_X509_num(certs)) { + X509_up_ref(xtmp); + } else { + xtmp = NULL; + } + sk_X509_pop_free(certs, X509_free); + return xtmp; } -/* Given a certificate try and find an exact match in the store */ +int X509_verify_cert(X509_STORE_CTX *ctx) { + X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth, i, ok = 0; + int num, j, retry, trust; + STACK_OF(X509) *sktmp = NULL; -static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -{ - STACK_OF(X509) *certs; - X509 *xtmp = NULL; - size_t i; - /* Lookup all certs with matching subject name */ - certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); - if (certs == NULL) - return NULL; - /* Look for exact match */ - for (i = 0; i < sk_X509_num(certs); i++) { - xtmp = sk_X509_value(certs, i); - if (!X509_cmp(xtmp, x)) - break; + if (ctx->cert == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->chain != NULL) { + // This X509_STORE_CTX has already been used to verify a cert. We + // cannot do another one. + OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + + // first we make sure the chain we are going to build is present and that + // the first entry is in place + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + X509_up_ref(ctx->cert); + ctx->last_untrusted = 1; + + // We use a temporary STACK so we can chop and hack at it. + if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + + num = (int)sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + // If we have enough, we break + if (depth < num) { + break; // FIXME: If this happens, we should take + // note of it and, if appropriate, use the + // X509_V_ERR_CERT_CHAIN_TOO_LONG error code + // later. } - if (i < sk_X509_num(certs)) + + int is_self_signed; + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + + // If we are self signed, we break + if (is_self_signed) { + break; + } + // If asked see if we can find issuer in trusted store first + if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + // If successful for now free up cert so it will be picked up + // again later. + if (ok > 0) { + X509_free(xtmp); + break; + } + } + + // If we were passed a cert chain, use it first + if (sktmp != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } X509_up_ref(xtmp); - else - xtmp = NULL; - sk_X509_pop_free(certs, X509_free); - return xtmp; + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->last_untrusted++; + x = xtmp; + num++; + // reparse the full chain for the next one + continue; + } + } + break; + } + + // Remember how many untrusted certs we have + j = num; + // at this point, chain should contain a list of untrusted certificates. + // We now need to add at least one trusted one, if possible, otherwise we + // complain. + + do { + // Examine last certificate in chain and see if it is self signed. + i = (int)sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + + int is_self_signed; + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + + if (is_self_signed) { + // we have a self signed certificate + if (sk_X509_num(ctx->chain) == 1) { + // We have a single self signed certificate: see if we can + // find it in the store. We must have an exact match to avoid + // possible impersonation. + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) { + X509_free(xtmp); + } + bad_chain = 1; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto end; + } + } else { + // We have a match: replace certificate with store + // version so we get any trust settings. + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted = 0; + } + } else { + // extract and save self signed certificate for later use + chain_ss = sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + j--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + // We now lookup certs from the certificate store + for (;;) { + // If we have enough, we break + if (depth < num) { + break; + } + if (!cert_self_signed(x, &is_self_signed)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + goto end; + } + // If we are self signed, we break + if (is_self_signed) { + break; + } + ok = ctx->get_issuer(&xtmp, ctx, x); + + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto end; + } + if (ok == 0) { + break; + } + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + } + + // we now have our chain, lets check it... + trust = check_trust(ctx); + + // If explicitly rejected error + if (trust == X509_TRUST_REJECTED) { + ok = 0; + goto end; + } + // If it's not explicitly trusted then check if there is an alternative + // chain that could be used. We only do this if we haven't already + // checked via TRUSTED_FIRST and the user hasn't switched off alternate + // chain checking + retry = 0; + if (trust != X509_TRUST_TRUSTED && + !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && + !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { + while (j-- > 1) { + xtmp2 = sk_X509_value(ctx->chain, j - 1); + ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + if (ok < 0) { + goto end; + } + // Check if we found an alternate chain + if (ok > 0) { + // Free up the found cert we'll add it again later + X509_free(xtmp); + + // Dump all the certs above this point - we've found an + // alternate chain + while (num > j) { + xtmp = sk_X509_pop(ctx->chain); + X509_free(xtmp); + num--; + } + ctx->last_untrusted = (int)sk_X509_num(ctx->chain); + retry = 1; + break; + } + } + } + } while (retry); + + // If not explicitly trusted then indicate error unless it's a single + // self signed certificate in which case we've indicated an error already + // and set bad_chain == 1 + if (trust != X509_TRUST_TRUSTED && !bad_chain) { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->last_untrusted >= num) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + } else { + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + } + ctx->current_cert = x; + } else { + sk_X509_push(ctx->chain, chain_ss); + num++; + ctx->last_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto end; + } + } + + // We have the chain complete: now we need to check its purpose + ok = check_chain_extensions(ctx); + + if (!ok) { + goto end; + } + + ok = check_id(ctx); + + if (!ok) { + goto end; + } + + // Check revocation status: we do this after copying parameters because + // they may be needed for CRL signature verification. + ok = ctx->check_revocation(ctx); + if (!ok) { + goto end; + } + + // At this point, we have a chain and need to verify it + if (ctx->verify != NULL) { + ok = ctx->verify(ctx); + } else { + ok = internal_verify(ctx); + } + if (!ok) { + goto end; + } + + // Check name constraints + ok = check_name_constraints(ctx); + if (!ok) { + goto end; + } + + // If we get this far, evaluate policies. + if (!bad_chain) { + ok = ctx->check_policy(ctx); + } + +end: + if (sktmp != NULL) { + sk_X509_free(sktmp); + } + if (chain_ss != NULL) { + X509_free(chain_ss); + } + + // Safety net, error returns must set ctx->error + if (ok <= 0 && ctx->error == X509_V_OK) { + ctx->error = X509_V_ERR_UNSPECIFIED; + } + return ok; } -int X509_verify_cert(X509_STORE_CTX *ctx) -{ - X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; - int bad_chain = 0; - X509_VERIFY_PARAM *param = ctx->param; - int depth, i, ok = 0; - int num, j, retry, trust; - int (*cb) (int xok, X509_STORE_CTX *xctx); - STACK_OF(X509) *sktmp = NULL; - if (ctx->cert == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - if (ctx->chain != NULL) { - /* - * This X509_STORE_CTX has already been used to verify a cert. We - * cannot do another one. - */ - OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } +// Given a STACK_OF(X509) find the issuer of cert (if any) - cb = ctx->verify_cb; +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { + size_t i; + X509 *issuer; + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) { + return issuer; + } + } + return NULL; +} - /* - * first we make sure the chain we are going to build is present and that - * the first entry is in place - */ - ctx->chain = sk_X509_new_null(); - if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; +// Given a possible certificate and issuer check them + +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) { + int ret; + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) { + return 1; + } + // If we haven't asked for issuer errors don't set ctx + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) { + return 0; + } + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); +} + +// Alternative lookup method: look from a STACK stored in other_ctx + +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) { + X509_up_ref(*issuer); + return 1; + } else { + return 0; + } +} + +// Check a certificate chains extensions for consistency with the supplied +// purpose + +static int check_chain_extensions(X509_STORE_CTX *ctx) { + int ok = 0, plen = 0; + + // If |ctx->parent| is set, this is CRL path validation. + int purpose = + ctx->parent == NULL ? ctx->param->purpose : X509_PURPOSE_CRL_SIGN; + + // Check all untrusted certificates + for (int i = 0; i < ctx->last_untrusted; i++) { + X509 *x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) { goto end; + } } - X509_up_ref(ctx->cert); - ctx->last_untrusted = 1; - /* We use a temporary STACK so we can chop and hack at it. */ - if (ctx->untrusted != NULL - && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; + int must_be_ca = i > 0; + if (must_be_ca && !X509_check_ca(x)) { + ctx->error = X509_V_ERR_INVALID_CA; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) { goto end; + } + } + if (ctx->param->purpose > 0 && + X509_check_purpose(x, purpose, must_be_ca) != 1) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto end; + } + } + // Check pathlen if not self issued + if (i > 1 && !(x->ex_flags & EXFLAG_SI) && x->ex_pathlen != -1 && + plen > x->ex_pathlen + 1) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto end; + } + } + // Increment path length if not self issued + if (!(x->ex_flags & EXFLAG_SI)) { + plen++; + } + } + ok = 1; +end: + return ok; +} + +static int reject_dns_name_in_common_name(X509 *x509) { + const X509_NAME *name = X509_get_subject_name(x509); + int i = -1; + for (;;) { + i = X509_NAME_get_index_by_NID(name, NID_commonName, i); + if (i == -1) { + return X509_V_OK; } - num = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, num - 1); - depth = param->depth; + const X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); + const ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(entry); + unsigned char *idval; + int idlen = ASN1_STRING_to_UTF8(&idval, common_name); + if (idlen < 0) { + return X509_V_ERR_OUT_OF_MEM; + } + // Only process attributes that look like host names. Note it is + // important that this check be mirrored in |X509_check_host|. + int looks_like_dns = x509v3_looks_like_dns_name(idval, (size_t)idlen); + OPENSSL_free(idval); + if (looks_like_dns) { + return X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS; + } + } +} - for (;;) { - /* If we have enough, we break */ - if (depth < num) - break; /* FIXME: If this happens, we should take - * note of it and, if appropriate, use the - * X509_V_ERR_CERT_CHAIN_TOO_LONG error code - * later. */ - - int is_self_signed; - if (!cert_self_signed(x, &is_self_signed)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - goto end; - } - - /* If we are self signed, we break */ - if (is_self_signed) +static int check_name_constraints(X509_STORE_CTX *ctx) { + int i, j, rv; + int has_name_constraints = 0; + // Check name constraints for all certificates + for (i = (int)sk_X509_num(ctx->chain) - 1; i >= 0; i--) { + X509 *x = sk_X509_value(ctx->chain, i); + // Ignore self issued certs unless last in chain + if (i && (x->ex_flags & EXFLAG_SI)) { + continue; + } + // Check against constraints for all certificates higher in chain + // including trust anchor. Trust anchor not strictly speaking needed + // but if it includes constraints it is to be assumed it expects them + // to be obeyed. + for (j = (int)sk_X509_num(ctx->chain) - 1; j > i; j--) { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) { + has_name_constraints = 1; + rv = NAME_CONSTRAINTS_check(x, nc); + switch (rv) { + case X509_V_OK: + continue; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } break; - /* - * If asked see if we can find issuer in trusted store first - */ - if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { - ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto end; - } - /* - * If successful for now free up cert so it will be picked up - * again later. - */ - if (ok > 0) { - X509_free(xtmp); - break; - } } + } + } + } - /* If we were passed a cert chain, use it first */ - if (sktmp != NULL) { - xtmp = find_issuer(ctx, sktmp, x); - if (xtmp != NULL) { - if (!sk_X509_push(ctx->chain, xtmp)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = 0; - goto end; - } - X509_up_ref(xtmp); - (void)sk_X509_delete_ptr(sktmp, xtmp); - ctx->last_untrusted++; - x = xtmp; - num++; - /* - * reparse the full chain for the next one - */ - continue; - } + // Name constraints do not match against the common name, but + // |X509_check_host| still implements the legacy behavior where, on + // certificates lacking a SAN list, DNS-like names in the common name are + // checked instead. + // + // While we could apply the name constraints to the common name, name + // constraints are rare enough that can hold such certificates to a higher + // standard. Note this does not make "DNS-like" heuristic failures any + // worse. A decorative common-name misidentified as a DNS name would fail + // the name constraint anyway. + X509 *leaf = sk_X509_value(ctx->chain, 0); + if (has_name_constraints && leaf->altname == NULL) { + rv = reject_dns_name_in_common_name(leaf); + switch (rv) { + case X509_V_OK: + break; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = leaf; + if (!ctx->verify_cb(0, ctx)) { + return 0; } break; } + } - /* Remember how many untrusted certs we have */ - j = num; - /* - * at this point, chain should contain a list of untrusted certificates. - * We now need to add at least one trusted one, if possible, otherwise we - * complain. - */ + return 1; +} - do { - /* - * Examine last certificate in chain and see if it is self signed. - */ - i = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, i - 1); +static int check_id_error(X509_STORE_CTX *ctx, int errcode) { + ctx->error = errcode; + ctx->current_cert = ctx->cert; + ctx->error_depth = 0; + return ctx->verify_cb(0, ctx); +} - int is_self_signed; - if (!cert_self_signed(x, &is_self_signed)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - goto end; - } +static int check_hosts(X509 *x, X509_VERIFY_PARAM *param) { + size_t i; + size_t n = sk_OPENSSL_STRING_num(param->hosts); + char *name; - if (is_self_signed) { - /* we have a self signed certificate */ - if (sk_X509_num(ctx->chain) == 1) { - /* - * We have a single self signed certificate: see if we can - * find it in the store. We must have an exact match to avoid - * possible impersonation. - */ - ok = ctx->get_issuer(&xtmp, ctx, x); - if ((ok <= 0) || X509_cmp(x, xtmp)) { - ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; - ctx->current_cert = x; - ctx->error_depth = i - 1; - if (ok == 1) - X509_free(xtmp); - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto end; - } else { - /* - * We have a match: replace certificate with store - * version so we get any trust settings. - */ - X509_free(x); - x = xtmp; - (void)sk_X509_set(ctx->chain, i - 1, x); - ctx->last_untrusted = 0; - } - } else { - /* - * extract and save self signed certificate for later use - */ - chain_ss = sk_X509_pop(ctx->chain); - ctx->last_untrusted--; - num--; - j--; - x = sk_X509_value(ctx->chain, num - 1); - } - } - /* We now lookup certs from the certificate store */ - for (;;) { - /* If we have enough, we break */ - if (depth < num) - break; - if (!cert_self_signed(x, &is_self_signed)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - goto end; - } - /* If we are self signed, we break */ - if (is_self_signed) - break; - ok = ctx->get_issuer(&xtmp, ctx, x); - - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto end; - } - if (ok == 0) - break; - x = xtmp; - if (!sk_X509_push(ctx->chain, x)) { - X509_free(xtmp); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = 0; - goto end; - } - num++; - } - - /* we now have our chain, lets check it... */ - trust = check_trust(ctx); - - /* If explicitly rejected error */ - if (trust == X509_TRUST_REJECTED) { - ok = 0; - goto end; - } - /* - * If it's not explicitly trusted then check if there is an alternative - * chain that could be used. We only do this if we haven't already - * checked via TRUSTED_FIRST and the user hasn't switched off alternate - * chain checking - */ - retry = 0; - if (trust != X509_TRUST_TRUSTED - && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) - && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { - while (j-- > 1) { - xtmp2 = sk_X509_value(ctx->chain, j - 1); - ok = ctx->get_issuer(&xtmp, ctx, xtmp2); - if (ok < 0) - goto end; - /* Check if we found an alternate chain */ - if (ok > 0) { - /* - * Free up the found cert we'll add it again later - */ - X509_free(xtmp); - - /* - * Dump all the certs above this point - we've found an - * alternate chain - */ - while (num > j) { - xtmp = sk_X509_pop(ctx->chain); - X509_free(xtmp); - num--; - } - ctx->last_untrusted = sk_X509_num(ctx->chain); - retry = 1; - break; - } - } - } - } while (retry); - - /* - * If not explicitly trusted then indicate error unless it's a single - * self signed certificate in which case we've indicated an error already - * and set bad_chain == 1 - */ - if (trust != X509_TRUST_TRUSTED && !bad_chain) { - if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { - if (ctx->last_untrusted >= num) - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; - else - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; - ctx->current_cert = x; - } else { - - sk_X509_push(ctx->chain, chain_ss); - num++; - ctx->last_untrusted = num; - ctx->current_cert = chain_ss; - ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; - chain_ss = NULL; - } - - ctx->error_depth = num - 1; - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto end; + if (param->peername != NULL) { + OPENSSL_free(param->peername); + param->peername = NULL; + } + for (i = 0; i < n; ++i) { + name = sk_OPENSSL_STRING_value(param->hosts, i); + if (X509_check_host(x, name, strlen(name), param->hostflags, + ¶m->peername) > 0) { + return 1; } + } + return n == 0; +} - /* We have the chain complete: now we need to check its purpose */ - ok = check_chain_extensions(ctx); - - if (!ok) - goto end; - - ok = check_id(ctx); - - if (!ok) - goto end; - - /* - * Check revocation status: we do this after copying parameters because - * they may be needed for CRL signature verification. - */ - - ok = ctx->check_revocation(ctx); - if (!ok) - goto end; - - int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, - ctx->param->flags); - if (err != X509_V_OK) { - ctx->error = err; - ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); - ok = cb(0, ctx); - if (!ok) - goto end; +static int check_id(X509_STORE_CTX *ctx) { + X509_VERIFY_PARAM *vpm = ctx->param; + X509 *x = ctx->cert; + if (vpm->poison) { + if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) { + return 0; } - - /* At this point, we have a chain and need to verify it */ - if (ctx->verify != NULL) - ok = ctx->verify(ctx); - else - ok = internal_verify(ctx); - if (!ok) - goto end; - - /* Check name constraints */ - - ok = check_name_constraints(ctx); - if (!ok) - goto end; - - /* If we get this far evaluate policies */ - if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) - ok = ctx->check_policy(ctx); - - end: - if (sktmp != NULL) - sk_X509_free(sktmp); - if (chain_ss != NULL) - X509_free(chain_ss); - - /* Safety net, error returns must set ctx->error */ - if (ok <= 0 && ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - return ok; -} - -/* - * Given a STACK_OF(X509) find the issuer of cert (if any) - */ - -static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) -{ - size_t i; - X509 *issuer; - for (i = 0; i < sk_X509_num(sk); i++) { - issuer = sk_X509_value(sk, i); - if (ctx->check_issued(ctx, x, issuer)) - return issuer; + } + if (vpm->hosts && check_hosts(x, vpm) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) { + return 0; } - return NULL; + } + if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) { + return 0; + } + } + if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) { + return 0; + } + } + return 1; } -/* Given a possible certificate and issuer check them */ +static int check_trust(X509_STORE_CTX *ctx) { + int ok; + X509 *x = NULL; + // Check all trusted certificates in chain + for (size_t i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + // If explicitly trusted return trusted + if (ok == X509_TRUST_TRUSTED) { + return X509_TRUST_TRUSTED; + } + // If explicitly rejected notify callback and reject if not + // overridden. + if (ok == X509_TRUST_REJECTED) { + ctx->error_depth = (int)i; + ctx->current_cert = x; + ctx->error = X509_V_ERR_CERT_REJECTED; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + return X509_TRUST_REJECTED; + } + } + } + // If we accept partial chains and have at least one trusted certificate + // return success. + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + X509 *mx; + if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain)) { + return X509_TRUST_TRUSTED; + } + x = sk_X509_value(ctx->chain, 0); + mx = lookup_cert_match(ctx, x); + if (mx) { + (void)sk_X509_set(ctx->chain, 0, mx); + X509_free(x); + ctx->last_untrusted = 0; + return X509_TRUST_TRUSTED; + } + } -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) -{ - int ret; - ret = X509_check_issued(issuer, x); - if (ret == X509_V_OK) - return 1; - /* If we haven't asked for issuer errors don't set ctx */ - if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) - return 0; - - ctx->error = ret; - ctx->current_cert = x; - ctx->current_issuer = issuer; - return ctx->verify_cb(0, ctx); + // If no trusted certs in chain at all return untrusted and allow + // standard (no issuer cert) etc errors to be indicated. + return X509_TRUST_UNTRUSTED; } -/* Alternative lookup method: look from a STACK stored in other_ctx */ - -static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -{ - *issuer = find_issuer(ctx, ctx->other_ctx, x); - if (*issuer) { - X509_up_ref(*issuer); - return 1; - } else - return 0; -} - -/* - * Check a certificate chains extensions for consistency with the supplied - * purpose - */ - -static int check_chain_extensions(X509_STORE_CTX *ctx) -{ - int i, ok = 0, plen = 0; - X509 *x; - int (*cb) (int xok, X509_STORE_CTX *xctx); - int proxy_path_length = 0; - int purpose; - int allow_proxy_certs; - cb = ctx->verify_cb; - - enum { - // ca_or_leaf allows either type of certificate so that direct use of - // self-signed certificates works. - ca_or_leaf, - must_be_ca, - must_not_be_ca, - } ca_requirement; - - /* CRL path validation */ +static int check_revocation(X509_STORE_CTX *ctx) { + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) { + return 1; + } + int last; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) { + last = (int)sk_X509_num(ctx->chain) - 1; + } else { + // If checking CRL paths this isn't the EE certificate if (ctx->parent) { - allow_proxy_certs = 0; - purpose = X509_PURPOSE_CRL_SIGN; + return 1; + } + last = 0; + } + for (int i = 0; i <= last; i++) { + ctx->error_depth = i; + int ok = check_cert(ctx); + if (!ok) { + return ok; + } + } + return 1; +} + +static int check_cert(X509_STORE_CTX *ctx) { + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok = 0, cnum; + unsigned int last_reasons; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + // Try to retrieve relevant CRL + if (ctx->get_crl) { + ok = ctx->get_crl(ctx, &crl, x); } else { - allow_proxy_certs = - ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); - purpose = ctx->param->purpose; + ok = get_crl_delta(ctx, &crl, &dcrl, x); + } + // If error looking up CRL, nothing we can do except notify callback + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) { + goto err; } - ca_requirement = ca_or_leaf; - - /* Check all untrusted certificates */ - for (i = 0; i < ctx->last_untrusted; i++) { - int ret; - x = sk_X509_value(ctx->chain, i); - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (x->ex_flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { - ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - - switch (ca_requirement) { - case ca_or_leaf: - ret = 1; - break; - case must_not_be_ca: - if (X509_check_ca(x)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_NON_CA; - } else - ret = 1; - break; - case must_be_ca: - if (!X509_check_ca(x)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; - break; - default: - // impossible. - ret = 0; - } - - if (ret == 0) { - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - if (ctx->param->purpose > 0) { - ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca); - if (ret != 1) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_PURPOSE; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - } - /* Check pathlen if not self issued */ - if ((i > 1) && !(x->ex_flags & EXFLAG_SI) - && (x->ex_pathlen != -1) - && (plen > (x->ex_pathlen + proxy_path_length + 1))) { - ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - /* Increment path length if not self issued */ - if (!(x->ex_flags & EXFLAG_SI)) - plen++; - /* - * If this certificate is a proxy certificate, the next certificate - * must be another proxy certificate or a EE certificate. If not, - * the next certificate must be a CA certificate. - */ - if (x->ex_flags & EXFLAG_PROXY) { - if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) { - ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - proxy_path_length++; - ca_requirement = must_not_be_ca; - } else { - ca_requirement = must_be_ca; - } - } - ok = 1; - end: - return ok; -} - -static int reject_dns_name_in_common_name(X509 *x509) -{ - X509_NAME *name = X509_get_subject_name(x509); - int i = -1; - for (;;) { - i = X509_NAME_get_index_by_NID(name, NID_commonName, i); - if (i == -1) { - return X509_V_OK; - } - - X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); - ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(entry); - unsigned char *idval; - int idlen = ASN1_STRING_to_UTF8(&idval, common_name); - if (idlen < 0) { - return X509_V_ERR_OUT_OF_MEM; - } - /* Only process attributes that look like host names. Note it is - * important that this check be mirrored in |X509_check_host|. */ - int looks_like_dns = x509v3_looks_like_dns_name(idval, (size_t)idlen); - OPENSSL_free(idval); - if (looks_like_dns) { - return X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS; - } - } -} - -static int check_name_constraints(X509_STORE_CTX *ctx) -{ - int i, j, rv; - int has_name_constraints = 0; - /* Check name constraints for all certificates */ - for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { - X509 *x = sk_X509_value(ctx->chain, i); - /* Ignore self issued certs unless last in chain */ - if (i && (x->ex_flags & EXFLAG_SI)) - continue; - /* - * Check against constraints for all certificates higher in chain - * including trust anchor. Trust anchor not strictly speaking needed - * but if it includes constraints it is to be assumed it expects them - * to be obeyed. - */ - for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { - NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; - if (nc) { - has_name_constraints = 1; - rv = NAME_CONSTRAINTS_check(x, nc); - switch (rv) { - case X509_V_OK: - continue; - case X509_V_ERR_OUT_OF_MEM: - ctx->error = rv; - return 0; - default: - ctx->error = rv; - ctx->error_depth = i; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - break; - } - } - } + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) { + goto err; + } + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) { + goto err; + } + } else { + ok = 1; } - /* Name constraints do not match against the common name, but - * |X509_check_host| still implements the legacy behavior where, on - * certificates lacking a SAN list, DNS-like names in the common name are - * checked instead. - * - * While we could apply the name constraints to the common name, name - * constraints are rare enough that can hold such certificates to a higher - * standard. Note this does not make "DNS-like" heuristic failures any - * worse. A decorative common-name misidentified as a DNS name would fail - * the name constraint anyway. */ - X509 *leaf = sk_X509_value(ctx->chain, 0); - if (has_name_constraints && leaf->altname == NULL) { - rv = reject_dns_name_in_common_name(leaf); - switch (rv) { - case X509_V_OK: - break; - case X509_V_ERR_OUT_OF_MEM: - ctx->error = rv; - return 0; - default: - ctx->error = rv; - ctx->error_depth = i; - ctx->current_cert = leaf; - if (!ctx->verify_cb(0, ctx)) - return 0; - break; - } + // Don't look in full CRL if delta reason is removefromCRL + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) { + goto err; + } } - return 1; -} - -static int check_id_error(X509_STORE_CTX *ctx, int errcode) -{ - ctx->error = errcode; - ctx->current_cert = ctx->cert; - ctx->error_depth = 0; - return ctx->verify_cb(0, ctx); -} - -static int check_hosts(X509 *x, X509_VERIFY_PARAM *param) -{ - size_t i; - size_t n = sk_OPENSSL_STRING_num(param->hosts); - char *name; - - if (param->peername != NULL) { - OPENSSL_free(param->peername); - param->peername = NULL; - } - for (i = 0; i < n; ++i) { - name = sk_OPENSSL_STRING_value(param->hosts, i); - if (X509_check_host(x, name, strlen(name), param->hostflags, - ¶m->peername) > 0) - return 1; - } - return n == 0; -} - -static int check_id(X509_STORE_CTX *ctx) -{ - X509_VERIFY_PARAM *vpm = ctx->param; - X509 *x = ctx->cert; - if (vpm->poison) { - if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) - return 0; - } - if (vpm->hosts && check_hosts(x, vpm) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) - return 0; - } - if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) - return 0; - } - if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) - return 0; - } - return 1; -} - -static int check_trust(X509_STORE_CTX *ctx) -{ - size_t i; - int ok; - X509 *x = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - cb = ctx->verify_cb; - /* Check all trusted certificates in chain */ - for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { - x = sk_X509_value(ctx->chain, i); - ok = X509_check_trust(x, ctx->param->trust, 0); - /* If explicitly trusted return trusted */ - if (ok == X509_TRUST_TRUSTED) - return X509_TRUST_TRUSTED; - /* - * If explicitly rejected notify callback and reject if not - * overridden. - */ - if (ok == X509_TRUST_REJECTED) { - ctx->error_depth = i; - ctx->current_cert = x; - ctx->error = X509_V_ERR_CERT_REJECTED; - ok = cb(0, ctx); - if (!ok) - return X509_TRUST_REJECTED; - } - } - /* - * If we accept partial chains and have at least one trusted certificate - * return success. - */ - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - X509 *mx; - if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain)) - return X509_TRUST_TRUSTED; - x = sk_X509_value(ctx->chain, 0); - mx = lookup_cert_match(ctx, x); - if (mx) { - (void)sk_X509_set(ctx->chain, 0, mx); - X509_free(x); - ctx->last_untrusted = 0; - return X509_TRUST_TRUSTED; - } - } - - /* - * If no trusted certs in chain at all return untrusted and allow - * standard (no issuer cert) etc errors to be indicated. - */ - return X509_TRUST_UNTRUSTED; -} - -static int check_revocation(X509_STORE_CTX *ctx) -{ - int i, last, ok; - if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) - return 1; - if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) - last = sk_X509_num(ctx->chain) - 1; - else { - /* If checking CRL paths this isn't the EE certificate */ - if (ctx->parent) - return 1; - last = 0; - } - for (i = 0; i <= last; i++) { - ctx->error_depth = i; - ok = check_cert(ctx); - if (!ok) - return ok; - } - return 1; -} - -static int check_cert(X509_STORE_CTX *ctx) -{ - X509_CRL *crl = NULL, *dcrl = NULL; - X509 *x; - int ok = 0, cnum; - unsigned int last_reasons; - cnum = ctx->error_depth; - x = sk_X509_value(ctx->chain, cnum); - ctx->current_cert = x; - ctx->current_issuer = NULL; - ctx->current_crl_score = 0; - ctx->current_reasons = 0; - while (ctx->current_reasons != CRLDP_ALL_REASONS) { - last_reasons = ctx->current_reasons; - /* Try to retrieve relevant CRL */ - if (ctx->get_crl) - ok = ctx->get_crl(ctx, &crl, x); - else - ok = get_crl_delta(ctx, &crl, &dcrl, x); - /* - * If error looking up CRL, nothing we can do except notify callback - */ - if (!ok) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - ctx->current_crl = crl; - ok = ctx->check_crl(ctx, crl); - if (!ok) - goto err; - - if (dcrl) { - ok = ctx->check_crl(ctx, dcrl); - if (!ok) - goto err; - ok = ctx->cert_crl(ctx, dcrl, x); - if (!ok) - goto err; - } else - ok = 1; - - /* Don't look in full CRL if delta reason is removefromCRL */ - if (ok != 2) { - ok = ctx->cert_crl(ctx, crl, x); - if (!ok) - goto err; - } - - X509_CRL_free(crl); - X509_CRL_free(dcrl); - crl = NULL; - dcrl = NULL; - /* - * If reasons not updated we wont get anywhere by another iteration, - * so exit loop. - */ - if (last_reasons == ctx->current_reasons) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - } - err: X509_CRL_free(crl); X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + // If reasons not updated we wont get anywhere by another iteration, + // so exit loop. + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } +err: + X509_CRL_free(crl); + X509_CRL_free(dcrl); - ctx->current_crl = NULL; - return ok; - + ctx->current_crl = NULL; + return ok; } -/* Check CRL times against values in X509_STORE_CTX */ - -static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) -{ - time_t *ptime; - int i; - if (notify) - ctx->current_crl = crl; - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; - else - ptime = NULL; - - i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime); - if (i == 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i > 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (X509_CRL_get0_nextUpdate(crl)) { - i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime); - - if (i == 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - /* Ignore expiry of base CRL is delta is valid */ - if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - } - - if (notify) - ctx->current_crl = NULL; +// Check CRL times against values in X509_STORE_CTX +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) { + if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) { return 1; + } + + if (notify) { + ctx->current_crl = crl; + } + int64_t ptime; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) { + ptime = ctx->param->check_time; + } else { + ptime = time(NULL); + } + + int i = X509_cmp_time_posix(X509_CRL_get0_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) { + return 0; + } + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + if (i > 0) { + if (!notify) { + return 0; + } + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + if (X509_CRL_get0_nextUpdate(crl)) { + i = X509_cmp_time_posix(X509_CRL_get0_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) { + return 0; + } + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + // Ignore expiry of base CRL is delta is valid + if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) { + return 0; + } + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + } + + if (notify) { + ctx->current_crl = NULL; + } + + return 1; } static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 **pissuer, int *pscore, unsigned int *preasons, - STACK_OF(X509_CRL) *crls) -{ - int crl_score, best_score = *pscore; - size_t i; - unsigned int reasons, best_reasons = 0; - X509 *x = ctx->current_cert; - X509_CRL *crl, *best_crl = NULL; - X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + STACK_OF(X509_CRL) *crls) { + int crl_score, best_score = *pscore; + size_t i; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - crl = sk_X509_CRL_value(crls, i); - reasons = *preasons; - crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); - if (crl_score < best_score || crl_score == 0) - continue; - /* If current CRL is equivalent use it if it is newer */ - if (crl_score == best_score && best_crl != NULL) { - int day, sec; - if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl), - X509_CRL_get0_lastUpdate(crl)) == 0) - continue; - /* - * ASN1_TIME_diff never returns inconsistent signs for |day| - * and |sec|. - */ - if (day <= 0 && sec <= 0) - continue; - } - best_crl = crl; - best_crl_issuer = crl_issuer; - best_score = crl_score; - best_reasons = reasons; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + if (crl_score < best_score || crl_score == 0) { + continue; } - - if (best_crl) { - if (*pcrl) - X509_CRL_free(*pcrl); - *pcrl = best_crl; - *pissuer = best_crl_issuer; - *pscore = best_score; - *preasons = best_reasons; - X509_CRL_up_ref(best_crl); - if (*pdcrl) { - X509_CRL_free(*pdcrl); - *pdcrl = NULL; - } - get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + // If current CRL is equivalent use it if it is newer + if (crl_score == best_score && best_crl != NULL) { + int day, sec; + if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl), + X509_CRL_get0_lastUpdate(crl)) == 0) { + continue; + } + // ASN1_TIME_diff never returns inconsistent signs for |day| + // and |sec|. + if (day <= 0 && sec <= 0) { + continue; + } } + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } - if (best_score >= CRL_SCORE_VALID) - return 1; - - return 0; -} - -/* - * Compare two CRL extensions for delta checking purposes. They should be - * both present or both absent. If both present all fields must be identical. - */ - -static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) -{ - ASN1_OCTET_STRING *exta, *extb; - int i; - i = X509_CRL_get_ext_by_NID(a, nid, -1); - if (i >= 0) { - /* Can't have multiple occurrences */ - if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) - return 0; - exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); - } else - exta = NULL; - - i = X509_CRL_get_ext_by_NID(b, nid, -1); - - if (i >= 0) { - - if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) - return 0; - extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); - } else - extb = NULL; - - if (!exta && !extb) - return 1; - - if (!exta || !extb) - return 0; - - if (ASN1_OCTET_STRING_cmp(exta, extb)) - return 0; + if (best_crl) { + if (*pcrl) { + X509_CRL_free(*pcrl); + } + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + X509_CRL_up_ref(best_crl); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + if (best_score >= CRL_SCORE_VALID) { return 1; + } + + return 0; } -/* See if a base and delta are compatible */ +// Compare two CRL extensions for delta checking purposes. They should be +// both present or both absent. If both present all fields must be identical. -static int check_delta_base(X509_CRL *delta, X509_CRL *base) -{ - /* Delta CRL must be a delta */ - if (!delta->base_crl_number) - return 0; - /* Base must have a CRL number */ - if (!base->crl_number) - return 0; - /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) - return 0; - /* AKID and IDP must match */ - if (!crl_extension_match(delta, base, NID_authority_key_identifier)) - return 0; - if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) - return 0; - /* Delta CRL base number must not exceed Full CRL number. */ - if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) - return 0; - /* Delta CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) - return 1; +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) { + const ASN1_OCTET_STRING *exta, *extb; + int i; + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + // Can't have multiple occurrences + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) { + return 0; + } + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else { + exta = NULL; + } + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) { + return 0; + } + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else { + extb = NULL; + } + + if (!exta && !extb) { + return 1; + } + + if (!exta || !extb) { return 0; + } + + if (ASN1_OCTET_STRING_cmp(exta, extb)) { + return 0; + } + + return 1; } -/* - * For a given base CRL find a delta... maybe extend to delta scoring or - * retrieve a chain of deltas... - */ +// See if a base and delta are compatible + +static int check_delta_base(X509_CRL *delta, X509_CRL *base) { + // Delta CRL must be a delta + if (!delta->base_crl_number) { + return 0; + } + // Base must have a CRL number + if (!base->crl_number) { + return 0; + } + // Issuer names must match + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) { + return 0; + } + // AKID and IDP must match + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) { + return 0; + } + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) { + return 0; + } + // Delta CRL base number must not exceed Full CRL number. + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) { + return 0; + } + // Delta CRL number must exceed full CRL number + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) { + return 1; + } + return 0; +} + +// For a given base CRL find a delta... maybe extend to delta scoring or +// retrieve a chain of deltas... static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, - X509_CRL *base, STACK_OF(X509_CRL) *crls) -{ - X509_CRL *delta; - size_t i; - if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) - return; - if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) - return; - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - delta = sk_X509_CRL_value(crls, i); - if (check_delta_base(delta, base)) { - if (check_crl_time(ctx, delta, 0)) - *pscore |= CRL_SCORE_TIME_DELTA; - X509_CRL_up_ref(delta); - *dcrl = delta; - return; - } + X509_CRL *base, STACK_OF(X509_CRL) *crls) { + X509_CRL *delta; + size_t i; + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) { + return; + } + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) { + return; + } + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) { + *pscore |= CRL_SCORE_TIME_DELTA; + } + X509_CRL_up_ref(delta); + *dcrl = delta; + return; } - *dcrl = NULL; + } + *dcrl = NULL; } -/* - * For a given CRL return how suitable it is for the supplied certificate - * 'x'. The return value is a mask of several criteria. If the issuer is not - * the certificate issuer this is returned in *pissuer. The reasons mask is - * also used to determine if the CRL is suitable: if no new reasons the CRL - * is rejected, otherwise reasons is updated. - */ +// For a given CRL return how suitable it is for the supplied certificate +// 'x'. The return value is a mask of several criteria. If the issuer is not +// the certificate issuer this is returned in *pissuer. The reasons mask is +// also used to determine if the CRL is suitable: if no new reasons the CRL +// is rejected, otherwise reasons is updated. static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, - unsigned int *preasons, X509_CRL *crl, X509 *x) -{ + unsigned int *preasons, X509_CRL *crl, X509 *x) { + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; - int crl_score = 0; - unsigned int tmp_reasons = *preasons, crl_reasons; + // First see if we can reject CRL straight away - /* First see if we can reject CRL straight away */ - - /* Invalid IDP cannot be processed */ - if (crl->idp_flags & IDP_INVALID) - return 0; - /* Reason codes or indirect CRLs need extended CRL support */ - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { - if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) - return 0; - } else if (crl->idp_flags & IDP_REASONS) { - /* If no new reasons reject */ - if (!(crl->idp_reasons & ~tmp_reasons)) - return 0; + // Invalid IDP cannot be processed + if (crl->idp_flags & IDP_INVALID) { + return 0; + } + // Reason codes or indirect CRLs need extended CRL support + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) { + return 0; } - /* Don't process deltas at this stage */ - else if (crl->base_crl_number) - return 0; - /* If issuer name doesn't match certificate need indirect CRL */ - if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { - if (!(crl->idp_flags & IDP_INDIRECT)) - return 0; - } else - crl_score |= CRL_SCORE_ISSUER_NAME; - - if (!(crl->flags & EXFLAG_CRITICAL)) - crl_score |= CRL_SCORE_NOCRITICAL; - - /* Check expiry */ - if (check_crl_time(ctx, crl, 0)) - crl_score |= CRL_SCORE_TIME; - - /* Check authority key ID and locate certificate issuer */ - crl_akid_check(ctx, crl, pissuer, &crl_score); - - /* If we can't locate certificate issuer at this point forget it */ - - if (!(crl_score & CRL_SCORE_AKID)) - return 0; - - /* Check cert for matching CRL distribution points */ - - if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { - /* If no new reasons reject */ - if (!(crl_reasons & ~tmp_reasons)) - return 0; - tmp_reasons |= crl_reasons; - crl_score |= CRL_SCORE_SCOPE; + } else if (crl->idp_flags & IDP_REASONS) { + // If no new reasons reject + if (!(crl->idp_reasons & ~tmp_reasons)) { + return 0; } + } + // Don't process deltas at this stage + else if (crl->base_crl_number) { + return 0; + } + // If issuer name doesn't match certificate need indirect CRL + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) { + return 0; + } + } else { + crl_score |= CRL_SCORE_ISSUER_NAME; + } - *preasons = tmp_reasons; + if (!(crl->flags & EXFLAG_CRITICAL)) { + crl_score |= CRL_SCORE_NOCRITICAL; + } - return crl_score; + // Check expiry + if (check_crl_time(ctx, crl, 0)) { + crl_score |= CRL_SCORE_TIME; + } + // Check authority key ID and locate certificate issuer + crl_akid_check(ctx, crl, pissuer, &crl_score); + + // If we can't locate certificate issuer at this point forget it + + if (!(crl_score & CRL_SCORE_AKID)) { + return 0; + } + + // Check cert for matching CRL distribution points + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + // If no new reasons reject + if (!(crl_reasons & ~tmp_reasons)) { + return 0; + } + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; } -static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, - X509 **pissuer, int *pcrl_score) -{ - X509 *crl_issuer = NULL; - X509_NAME *cnm = X509_CRL_get_issuer(crl); - int cidx = ctx->error_depth; - size_t i; +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score) { + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + size_t i; - if ((size_t)cidx != sk_X509_num(ctx->chain) - 1) - cidx++; + if ((size_t)cidx != sk_X509_num(ctx->chain) - 1) { + cidx++; + } + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) { crl_issuer = sk_X509_value(ctx->chain, cidx); - + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) { + continue; + } if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { - *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; - *pissuer = crl_issuer; - return; - } + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; } + } - for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) { - crl_issuer = sk_X509_value(ctx->chain, cidx); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; - *pissuer = crl_issuer; - return; - } + // Anything else needs extended CRL support + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + return; + } + + // Otherwise the CRL issuer is not on the path. Look for it in the set of + // untrusted certificates. + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) { + continue; } - - /* Anything else needs extended CRL support */ - - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) - return; - - /* - * Otherwise the CRL issuer is not on the path. Look for it in the set of - * untrusted certificates. - */ - for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { - crl_issuer = sk_X509_value(ctx->untrusted, i); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pissuer = crl_issuer; - *pcrl_score |= CRL_SCORE_AKID; - return; - } + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; } + } } -/* - * Check the path of a CRL issuer certificate. This creates a new - * X509_STORE_CTX and populates it with most of the parameters from the - * parent. This could be optimised somewhat since a lot of path checking will - * be duplicated by the parent, but this will rarely be used in practice. - */ +// Check the path of a CRL issuer certificate. This creates a new +// X509_STORE_CTX and populates it with most of the parameters from the +// parent. This could be optimised somewhat since a lot of path checking will +// be duplicated by the parent, but this will rarely be used in practice. -static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) -{ - X509_STORE_CTX crl_ctx; - int ret; - /* Don't allow recursive CRL path validation */ - if (ctx->parent) +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) { + X509_STORE_CTX crl_ctx; + int ret; + // Don't allow recursive CRL path validation + if (ctx->parent) { + return 0; + } + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) { + return -1; + } + + crl_ctx.crls = ctx->crls; + // Copy verify params across + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + // Verify CRL issuer + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) { + goto err; + } + + // Check chain is acceptable + + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); +err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +// RFC 3280 says nothing about the relationship between CRL path and +// certificate path, which could lead to situations where a certificate could +// be revoked or validated by a CA not authorised to do so. RFC 5280 is more +// strict and states that the two paths must end in the same trust anchor, +// though some discussions remain... until this is resolved we use the +// RFC 5280 version + +static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) { + X509 *cert_ta, *crl_ta; + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) { + return 1; + } + return 0; +} + +// Check for match between two dist point names: three separate cases. 1. +// Both are relative names and compare X509_NAME types. 2. One full, one +// relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and +// compare two GENERAL_NAMES. 4. One is NULL: automatic match. + +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) { + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + size_t i, j; + if (!a || !b) { + return 1; + } + if (a->type == 1) { + if (!a->dpname) { + return 0; + } + // Case 1: two X509_NAME + if (b->type == 1) { + if (!b->dpname) { return 0; - if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) - return -1; - - crl_ctx.crls = ctx->crls; - /* Copy verify params across */ - X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); - - crl_ctx.parent = ctx; - crl_ctx.verify_cb = ctx->verify_cb; - - /* Verify CRL issuer */ - ret = X509_verify_cert(&crl_ctx); - - if (ret <= 0) - goto err; - - /* Check chain is acceptable */ - - ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); - err: - X509_STORE_CTX_cleanup(&crl_ctx); - return ret; -} - -/* - * RFC 3280 says nothing about the relationship between CRL path and - * certificate path, which could lead to situations where a certificate could - * be revoked or validated by a CA not authorised to do so. RFC 5280 is more - * strict and states that the two paths must end in the same trust anchor, - * though some discussions remain... until this is resolved we use the - * RFC 5280 version - */ - -static int check_crl_chain(X509_STORE_CTX *ctx, - STACK_OF(X509) *cert_path, - STACK_OF(X509) *crl_path) -{ - X509 *cert_ta, *crl_ta; - cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); - crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); - if (!X509_cmp(cert_ta, crl_ta)) + } + if (!X509_NAME_cmp(a->dpname, b->dpname)) { return 1; - return 0; -} - -/* - * Check for match between two dist point names: three separate cases. 1. - * Both are relative names and compare X509_NAME types. 2. One full, one - * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and - * compare two GENERAL_NAMES. 4. One is NULL: automatic match. - */ - -static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) -{ - X509_NAME *nm = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gena, *genb; - size_t i, j; - if (!a || !b) - return 1; - if (a->type == 1) { - if (!a->dpname) - return 0; - /* Case 1: two X509_NAME */ - if (b->type == 1) { - if (!b->dpname) - return 0; - if (!X509_NAME_cmp(a->dpname, b->dpname)) - return 1; - else - return 0; - } - /* Case 2: set name and GENERAL_NAMES appropriately */ - nm = a->dpname; - gens = b->name.fullname; - } else if (b->type == 1) { - if (!b->dpname) - return 0; - /* Case 2: set name and GENERAL_NAMES appropriately */ - gens = a->name.fullname; - nm = b->dpname; - } - - /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ - if (nm) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gena = sk_GENERAL_NAME_value(gens, i); - if (gena->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(nm, gena->d.directoryName)) - return 1; - } + } else { return 0; + } } - - /* Else case 3: two GENERAL_NAMES */ - - for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { - gena = sk_GENERAL_NAME_value(a->name.fullname, i); - for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { - genb = sk_GENERAL_NAME_value(b->name.fullname, j); - if (!GENERAL_NAME_cmp(gena, genb)) - return 1; - } + // Case 2: set name and GENERAL_NAMES appropriately + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) { + return 0; } + // Case 2: set name and GENERAL_NAMES appropriately + gens = a->name.fullname; + nm = b->dpname; + } - return 0; - -} - -static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) -{ - size_t i; - X509_NAME *nm = X509_CRL_get_issuer(crl); - /* If no CRLissuer return is successful iff don't need a match */ - if (!dp->CRLissuer) - return ! !(crl_score & CRL_SCORE_ISSUER_NAME); - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(gen->d.directoryName, nm)) - return 1; + // Handle case 2 with one GENERAL_NAMES and one X509_NAME + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) { + continue; + } + if (!X509_NAME_cmp(nm, gena->d.directoryName)) { + return 1; + } } return 0; + } + + // Else case 3: two GENERAL_NAMES + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) { + return 1; + } + } + } + + return 0; } -/* Check CRLDP and IDP */ +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) { + size_t i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + // If no CRLissuer return is successful iff don't need a match + if (!dp->CRLissuer) { + return !!(crl_score & CRL_SCORE_ISSUER_NAME); + } + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) { + continue; + } + if (!X509_NAME_cmp(gen->d.directoryName, nm)) { + return 1; + } + } + return 0; +} + +// Check CRLDP and IDP static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, - unsigned int *preasons) -{ - size_t i; - if (crl->idp_flags & IDP_ONLYATTR) - return 0; - if (x->ex_flags & EXFLAG_CA) { - if (crl->idp_flags & IDP_ONLYUSER) - return 0; + unsigned int *preasons) { + size_t i; + if (crl->idp_flags & IDP_ONLYATTR) { + return 0; + } + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) { + return 0; + } + } else { + if (crl->idp_flags & IDP_ONLYCA) { + return 0; + } + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) && + (crl_score & CRL_SCORE_ISSUER_NAME)) { + return 1; + } + return 0; +} + +// Retrieve CRL corresponding to current certificate. If deltas enabled try +// to find a delta CRL too + +static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 *x) { + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, ctx->crls); + + if (ok) { + goto done; + } + + // Lookup CRLs from store + + skcrl = ctx->lookup_crls(ctx, nm); + + // If no CRLs found and a near match from get_crl_sk use that + if (!skcrl && crl) { + goto done; + } + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + +done: + + // If we got any kind of CRL use it and return success + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +// Check CRL validity +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) { + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0; + int cnum = ctx->error_depth; + int chnum = (int)sk_X509_num(ctx->chain) - 1; + // if we have an alternative CRL issuer cert use that + if (ctx->current_issuer) { + issuer = ctx->current_issuer; + } + + // Else find CRL issuer: if not last certificate then issuer is next + // certificate in chain. + else if (cnum < chnum) { + issuer = sk_X509_value(ctx->chain, cnum + 1); + } else { + issuer = sk_X509_value(ctx->chain, chnum); + // If not self signed, can't check signature + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } + } + } + + if (issuer) { + // Skip most tests for deltas because they have already been done + if (!crl->base_crl_number) { + // Check for cRLSign bit if keyUsage present + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } + } + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) { + goto err; + } + } + + // Attempt to get issuer certificate public key + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + goto err; + } } else { - if (crl->idp_flags & IDP_ONLYCA) - return 0; - } - *preasons = crl->idp_reasons; - for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); - if (crldp_check_crlissuer(dp, crl, crl_score)) { - if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { - *preasons &= dp->dp_reasons; - return 1; - } - } - } - if ((!crl->idp || !crl->idp->distpoint) - && (crl_score & CRL_SCORE_ISSUER_NAME)) - return 1; - return 0; -} - -/* - * Retrieve CRL corresponding to current certificate. If deltas enabled try - * to find a delta CRL too - */ - -static int get_crl_delta(X509_STORE_CTX *ctx, - X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) -{ - int ok; - X509 *issuer = NULL; - int crl_score = 0; - unsigned int reasons; - X509_CRL *crl = NULL, *dcrl = NULL; - STACK_OF(X509_CRL) *skcrl; - X509_NAME *nm = X509_get_issuer_name(x); - reasons = ctx->current_reasons; - ok = get_crl_sk(ctx, &crl, &dcrl, - &issuer, &crl_score, &reasons, ctx->crls); - - if (ok) - goto done; - - /* Lookup CRLs from store */ - - skcrl = ctx->lookup_crls(ctx, nm); - - /* If no CRLs found and a near match from get_crl_sk use that */ - if (!skcrl && crl) - goto done; - - get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); - - sk_X509_CRL_pop_free(skcrl, X509_CRL_free); - - done: - - /* If we got any kind of CRL use it and return success */ - if (crl) { - ctx->current_issuer = issuer; - ctx->current_crl_score = crl_score; - ctx->current_reasons = reasons; - *pcrl = crl; - *pdcrl = dcrl; - return 1; - } - - return 0; -} - -/* Check CRL validity */ -static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) -{ - X509 *issuer = NULL; - EVP_PKEY *ikey = NULL; - int ok = 0, chnum, cnum; - cnum = ctx->error_depth; - chnum = sk_X509_num(ctx->chain) - 1; - /* if we have an alternative CRL issuer cert use that */ - if (ctx->current_issuer) - issuer = ctx->current_issuer; - - /* - * Else find CRL issuer: if not last certificate then issuer is next - * certificate in chain. - */ - else if (cnum < chnum) - issuer = sk_X509_value(ctx->chain, cnum + 1); - else { - issuer = sk_X509_value(ctx->chain, chnum); - /* If not self signed, can't check signature */ - if (!ctx->check_issued(ctx, issuer, issuer)) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (issuer) { - /* - * Skip most tests for deltas because they have already been done - */ - if (!crl->base_crl_number) { - /* Check for cRLSign bit if keyUsage present */ - if ((issuer->ex_flags & EXFLAG_KUSAGE) && - !(issuer->ex_kusage & KU_CRL_SIGN)) { - ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { - ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { - if (check_crl_path(ctx, ctx->current_issuer) <= 0) { - ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (crl->idp_flags & IDP_INVALID) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - } - - if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { - ok = check_crl_time(ctx, crl, 1); - if (!ok) - goto err; - } - - /* Attempt to get issuer certificate public key */ - ikey = X509_get_pubkey(issuer); - - if (!ikey) { - ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } else { - int rv; - rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); - if (rv != X509_V_OK) { - ctx->error = rv; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - /* Verify CRL signature */ - if (X509_CRL_verify(crl, ikey) <= 0) { - ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - } - - ok = 1; - - err: - EVP_PKEY_free(ikey); - return ok; -} - -/* Check certificate against CRL */ -static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) -{ - int ok; - X509_REVOKED *rev; - /* - * The rules changed for this... previously if a CRL contained unhandled - * critical extensions it could still be used to indicate a certificate - * was revoked. This has since been changed since critical extension can - * change the meaning of CRL entries. - */ - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (crl->flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + // Verify CRL signature + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; + if (!ok) { + goto err; + } + } } - /* - * Look for serial number of certificate in CRL If found make sure reason - * is not removeFromCRL. - */ - if (X509_CRL_get0_by_cert(crl, &rev, x)) { - if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) - return 2; - ctx->error = X509_V_ERR_CERT_REVOKED; + } + + ok = 1; + +err: + EVP_PKEY_free(ikey); + return ok; +} + +// Check certificate against CRL +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { + int ok; + X509_REVOKED *rev; + // The rules changed for this... previously if a CRL contained unhandled + // critical extensions it could still be used to indicate a certificate + // was revoked. This has since been changed since critical extension can + // change the meaning of CRL entries. + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + return 0; + } + } + // Look for serial number of certificate in CRL If found make sure reason + // is not removeFromCRL. + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) { + return 2; + } + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) { + return 0; + } + } + + return 1; +} + +static int check_policy(X509_STORE_CTX *ctx) { + // TODO(davidben): Why do we disable policy validation for CRL paths? + if (ctx->parent) { + return 1; + } + + X509 *current_cert = NULL; + int ret = X509_policy_check(ctx->chain, ctx->param->policies, + ctx->param->flags, ¤t_cert); + if (ret != X509_V_OK) { + ctx->current_cert = current_cert; + ctx->error = ret; + if (ret == X509_V_ERR_OUT_OF_MEM) { + return 0; + } + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + // Verification errors need to be "sticky", a callback may have allowed + // an SSL handshake to continue despite an error, and we must then + // remain in an error state. Therefore, we MUST NOT clear earlier + // verification errors by setting the error to X509_V_OK. + if (!ctx->verify_cb(2, ctx)) { + return 0; + } + } + + return 1; +} + +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) { + if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) { + return 1; + } + + int64_t ptime; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) { + ptime = ctx->param->check_time; + } else { + ptime = time(NULL); + } + + int i = X509_cmp_time_posix(X509_get_notBefore(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + if (i > 0) { + ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + i = X509_cmp_time_posix(X509_get_notAfter(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + if (i < 0) { + ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) { + return 0; + } + } + + return 1; +} + +static int internal_verify(X509_STORE_CTX *ctx) { + int ok = 0; + X509 *xs, *xi; + EVP_PKEY *pkey = NULL; + + int n = (int)sk_X509_num(ctx->chain); + ctx->error_depth = n - 1; + n--; + xi = sk_X509_value(ctx->chain, n); + + if (ctx->check_issued(ctx, xi, xi)) { + xs = xi; + } else { + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + xs = xi; + goto check_cert; + } + if (n <= 0) { + ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert = xi; + ok = ctx->verify_cb(0, ctx); + goto end; + } else { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + } + + // ctx->error=0; not needed + while (n >= 0) { + ctx->error_depth = n; + + // Skip signature check for self signed certificates unless + // explicitly asked for. It doesn't add any security and just wastes + // time. + if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) { + if ((pkey = X509_get_pubkey(xi)) == NULL) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert = xi; ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; - } - - return 1; -} - -static int check_policy(X509_STORE_CTX *ctx) -{ - int ret; - if (ctx->parent) - return 1; - ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, - ctx->param->policies, ctx->param->flags); - if (ret == 0) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } - /* Invalid or inconsistent extensions */ - if (ret == -1) { - /* - * Locate certificates with bad extensions and notify callback. - */ - X509 *x; - size_t i; - for (i = 1; i < sk_X509_num(ctx->chain); i++) { - x = sk_X509_value(ctx->chain, i); - if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) - continue; - ctx->current_cert = x; - ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; - if (!ctx->verify_cb(0, ctx)) - return 0; + if (!ok) { + goto end; } - return 1; - } - if (ret == -2) { - ctx->current_cert = NULL; - ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; - return ctx->verify_cb(0, ctx); - } - - if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { - ctx->current_cert = NULL; - /* - * Verification errors need to be "sticky", a callback may have allowed - * an SSL handshake to continue despite an error, and we must then - * remain in an error state. Therefore, we MUST NOT clear earlier - * verification errors by setting the error to X509_V_OK. - */ - if (!ctx->verify_cb(2, ctx)) - return 0; - } - - return 1; -} - -static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) -{ - time_t *ptime; - int i; - - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; - else - ptime = NULL; - - i = X509_cmp_time(X509_get_notBefore(x), ptime); - if (i == 0) { - ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i > 0) { - ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - i = X509_cmp_time(X509_get_notAfter(x), ptime); - if (i == 0) { - ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i < 0) { - ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - return 1; -} - -static int internal_verify(X509_STORE_CTX *ctx) -{ - int ok = 0, n; - X509 *xs, *xi; - EVP_PKEY *pkey = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - - cb = ctx->verify_cb; - - n = sk_X509_num(ctx->chain); - ctx->error_depth = n - 1; - n--; - xi = sk_X509_value(ctx->chain, n); - - if (ctx->check_issued(ctx, xi, xi)) - xs = xi; - else { - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - xs = xi; - goto check_cert; - } - if (n <= 0) { - ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - ctx->current_cert = xi; - ok = cb(0, ctx); - goto end; - } else { - n--; - ctx->error_depth = n; - xs = sk_X509_value(ctx->chain, n); - } - } - -/* ctx->error=0; not needed */ - while (n >= 0) { - ctx->error_depth = n; - - /* - * Skip signature check for self signed certificates unless - * explicitly asked for. It doesn't add any security and just wastes - * time. - */ - if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) { - if ((pkey = X509_get_pubkey(xi)) == NULL) { - ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - ctx->current_cert = xi; - ok = (*cb) (0, ctx); - if (!ok) - goto end; - } else if (X509_verify(xs, pkey) <= 0) { - ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - ctx->current_cert = xs; - ok = (*cb) (0, ctx); - if (!ok) { - EVP_PKEY_free(pkey); - goto end; - } - } - EVP_PKEY_free(pkey); - pkey = NULL; - } - - check_cert: - ok = check_cert_time(ctx, xs); - if (!ok) - goto end; - - /* The last error (if any) is still in the error value */ - ctx->current_issuer = xi; + } else if (X509_verify(xs, pkey) <= 0) { + ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; ctx->current_cert = xs; - ok = (*cb) (1, ctx); - if (!ok) - goto end; - - n--; - if (n >= 0) { - xi = xs; - xs = sk_X509_value(ctx->chain, n); + ok = ctx->verify_cb(0, ctx); + if (!ok) { + EVP_PKEY_free(pkey); + goto end; } + } + EVP_PKEY_free(pkey); + pkey = NULL; } - ok = 1; - end: - return ok; + + check_cert: + ok = check_cert_time(ctx, xs); + if (!ok) { + goto end; + } + + // The last error (if any) is still in the error value + ctx->current_issuer = xi; + ctx->current_cert = xs; + ok = ctx->verify_cb(1, ctx); + if (!ok) { + goto end; + } + + n--; + if (n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + ok = 1; +end: + return ok; } -int X509_cmp_current_time(const ASN1_TIME *ctm) -{ - return X509_cmp_time(ctm, NULL); +int X509_cmp_current_time(const ASN1_TIME *ctm) { + return X509_cmp_time_posix(ctm, time(NULL)); } -int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) -{ - static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1; - static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; - ASN1_TIME *asn1_cmp_time = NULL; - int i, day, sec, ret = 0; - - /* - * Note that ASN.1 allows much more slack in the time format than RFC 5280. - * In RFC 5280, the representation is fixed: - * UTCTime: YYMMDDHHMMSSZ - * GeneralizedTime: YYYYMMDDHHMMSSZ - * - * We do NOT currently enforce the following RFC 5280 requirement: - * "CAs conforming to this profile MUST always encode certificate - * validity dates through the year 2049 as UTCTime; certificate validity - * dates in 2050 or later MUST be encoded as GeneralizedTime." - */ - switch (ctm->type) { - case V_ASN1_UTCTIME: - if (ctm->length != (int)(utctime_length)) - return 0; - break; - case V_ASN1_GENERALIZEDTIME: - if (ctm->length != (int)(generalizedtime_length)) - return 0; - break; - default: - return 0; - } - - /** - * Verify the format: the ASN.1 functions we use below allow a more - * flexible format than what's mandated by RFC 5280. - * Digit and date ranges will be verified in the conversion methods. - */ - for (i = 0; i < ctm->length - 1; i++) { - if (!isdigit(ctm->data[i])) - return 0; - } - if (ctm->data[ctm->length - 1] != 'Z') - return 0; - - /* - * There is ASN1_UTCTIME_cmp_time_t but no - * ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t, - * so we go through ASN.1 - */ - asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time); - if (asn1_cmp_time == NULL) - goto err; - if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) - goto err; - - /* - * X509_cmp_time comparison is <=. - * The return value 0 is reserved for errors. - */ - ret = (day >= 0 && sec >= 0) ? -1 : 1; - - err: - ASN1_TIME_free(asn1_cmp_time); - return ret; +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) { + int64_t compare_time = (cmp_time == NULL) ? time(NULL) : *cmp_time; + return X509_cmp_time_posix(ctm, compare_time); } -ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec) -{ - return X509_time_adj(s, offset_sec, NULL); +int X509_cmp_time_posix(const ASN1_TIME *ctm, int64_t cmp_time) { + int64_t ctm_time; + if (!ASN1_TIME_to_posix(ctm, &ctm_time)) { + return 0; + } + // The return value 0 is reserved for errors. + return (ctm_time - cmp_time <= 0) ? -1 : 1; } -ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) -{ - return X509_time_adj_ex(s, 0, offset_sec, in_tm); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec) { + return X509_time_adj(s, offset_sec, NULL); } -ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, - int offset_day, long offset_sec, time_t *in_tm) -{ - time_t t = 0; - - if (in_tm) { - t = *in_tm; - } else { - time(&t); - } - - return ASN1_TIME_adj(s, t, offset_day, offset_sec); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) { + return X509_time_adj_ex(s, 0, offset_sec, in_tm); } -/* Make a delta CRL as the diff between two full CRLs */ +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, + time_t *in_tm) { + int64_t t = 0; -X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, - EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) -{ - X509_CRL *crl = NULL; - int i; - size_t j; - STACK_OF(X509_REVOKED) *revs = NULL; - /* CRLs can't be delta already */ - if (base->base_crl_number || newer->base_crl_number) { - OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA); - return NULL; - } - /* Base and new CRL must have a CRL number */ - if (!base->crl_number || !newer->crl_number) { - OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER); - return NULL; - } - /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { - OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH); - return NULL; - } - /* AKID and IDP must match */ - if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { - OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH); - return NULL; - } - if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { - OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH); - return NULL; - } - /* Newer CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { - OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER); - return NULL; - } - /* CRLs must verify */ - if (skey && (X509_CRL_verify(base, skey) <= 0 || - X509_CRL_verify(newer, skey) <= 0)) { - OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE); - return NULL; - } - /* Create new CRL */ - crl = X509_CRL_new(); - if (!crl || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) - goto memerr; - /* Set issuer name */ - if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) - goto memerr; + if (in_tm) { + t = *in_tm; + } else { + t = time(NULL); + } - if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) - goto memerr; - if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) - goto memerr; + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} - /* Set base CRL number: must be critical */ +// Make a delta CRL as the diff between two full CRLs - if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) - goto memerr; - - /* - * Copy extensions across from newest CRL to delta: this will set CRL - * number to correct value too. - */ - - for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { - X509_EXTENSION *ext; - ext = X509_CRL_get_ext(newer, i); - if (!X509_CRL_add_ext(crl, ext, -1)) - goto memerr; - } - - /* Go through revoked entries, copying as needed */ - - revs = X509_CRL_get_REVOKED(newer); - - for (j = 0; j < sk_X509_REVOKED_num(revs); j++) { - X509_REVOKED *rvn, *rvtmp; - rvn = sk_X509_REVOKED_value(revs, j); - /* - * Add only if not also in base. TODO: need something cleverer here - * for some more complex CRLs covering multiple CAs. - */ - if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) { - rvtmp = X509_REVOKED_dup(rvn); - if (!rvtmp) - goto memerr; - if (!X509_CRL_add0_revoked(crl, rvtmp)) { - X509_REVOKED_free(rvtmp); - goto memerr; - } - } - } - /* TODO: optionally prune deleted entries */ - - if (skey && md && !X509_CRL_sign(crl, skey, md)) - goto memerr; - - return crl; - - memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - if (crl) - X509_CRL_free(crl); +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey, + const EVP_MD *md, unsigned int flags) { + X509_CRL *crl = NULL; + int i; + size_t j; + STACK_OF(X509_REVOKED) *revs = NULL; + // CRLs can't be delta already + if (base->base_crl_number || newer->base_crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA); return NULL; + } + // Base and new CRL must have a CRL number + if (!base->crl_number || !newer->crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER); + return NULL; + } + // Issuer names must match + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { + OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH); + return NULL; + } + // AKID and IDP must match + if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { + OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH); + return NULL; + } + if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { + OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH); + return NULL; + } + // Newer CRL number must exceed full CRL number + if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { + OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER); + return NULL; + } + // CRLs must verify + if (skey && + (X509_CRL_verify(base, skey) <= 0 || X509_CRL_verify(newer, skey) <= 0)) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE); + return NULL; + } + // Create new CRL + crl = X509_CRL_new(); + if (!crl || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) { + goto memerr; + } + // Set issuer name + if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) { + goto memerr; + } + + if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) { + goto memerr; + } + if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) { + goto memerr; + } + + // Set base CRL number: must be critical + + if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) { + goto memerr; + } + + // Copy extensions across from newest CRL to delta: this will set CRL + // number to correct value too. + + for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { + const X509_EXTENSION *ext = X509_CRL_get_ext(newer, i); + if (!X509_CRL_add_ext(crl, ext, -1)) { + goto memerr; + } + } + + // Go through revoked entries, copying as needed + + revs = X509_CRL_get_REVOKED(newer); + + for (j = 0; j < sk_X509_REVOKED_num(revs); j++) { + X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, j); + // Add only if not also in base. TODO: need something cleverer here + // for some more complex CRLs covering multiple CAs. + if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) { + rvtmp = X509_REVOKED_dup(rvn); + if (!rvtmp) { + goto memerr; + } + if (!X509_CRL_add0_revoked(crl, rvtmp)) { + X509_REVOKED_free(rvtmp); + goto memerr; + } + } + } + // TODO: optionally prune deleted entries + + if (skey && md && !X509_CRL_sign(crl, skey, md)) { + goto memerr; + } + + return crl; + +memerr: + if (crl) { + X509_CRL_free(crl); + } + return NULL; } int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_unused * unused, + CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_unused, - CRYPTO_EX_free *free_func) -{ - /* - * This function is (usually) called only once, by - * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). - */ - int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, - free_func)) { - return -1; - } - return index; + CRYPTO_EX_free *free_func) { + // This function is (usually) called only once, by + // SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; } -int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) -{ - return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) { + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); } -void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) -{ - return CRYPTO_get_ex_data(&ctx->ex_data, idx); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) { + return CRYPTO_get_ex_data(&ctx->ex_data, idx); } -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) -{ - return ctx->error; +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) { return ctx->error; } + +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) { + ctx->error = err; } -void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) -{ - ctx->error = err; +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) { + return ctx->error_depth; } -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) -{ - return ctx->error_depth; +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) { + return ctx->current_cert; } -X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) -{ - return ctx->current_cert; +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) { + return ctx->chain; } -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) -{ - return ctx->chain; +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) { + return ctx->chain; } -STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) -{ - return ctx->chain; +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) { + if (!ctx->chain) { + return NULL; + } + return X509_chain_up_ref(ctx->chain); } -STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) -{ - if (!ctx->chain) - return NULL; - return X509_chain_up_ref(ctx->chain); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) { + return ctx->current_issuer; } -X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) -{ - return ctx->current_issuer; +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) { + return ctx->current_crl; } -X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) -{ - return ctx->current_crl; +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) { + return ctx->parent; } -X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) -{ - return ctx->parent; +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) { ctx->cert = x; } + +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { + ctx->untrusted = sk; } -void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) -{ - ctx->cert = x; +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) { + return ctx->untrusted; } -void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->untrusted = sk; +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) { + ctx->crls = sk; } -STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) -{ - return ctx->untrusted; +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) { + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); } -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) -{ - ctx->crls = sk; +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) { + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); } -int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) -{ - return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); -} - -int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) -{ - return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); -} - -/* - * This function is used to set the X509_STORE_CTX purpose and trust values. - * This is intended to be used when another structure has its own trust and - * purpose values which (if set) will be inherited by the ctx. If they aren't - * set then we will usually have a default purpose in mind which should then - * be used to set the trust value. An example of this is SSL use: an SSL - * structure will have its own purpose and trust settings which the - * application can set: if they aren't set then we use the default of SSL - * client/server. - */ +// This function is used to set the X509_STORE_CTX purpose and trust values. +// This is intended to be used when another structure has its own trust and +// purpose values which (if set) will be inherited by the ctx. If they aren't +// set then we will usually have a default purpose in mind which should then +// be used to set the trust value. An example of this is SSL use: an SSL +// structure will have its own purpose and trust settings which the +// application can set: if they aren't set then we use the default of SSL +// client/server. int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, - int purpose, int trust) -{ - int idx; - /* If purpose not set use default */ - if (!purpose) - purpose = def_purpose; - /* If we have a purpose then check it is valid */ - if (purpose) { - X509_PURPOSE *ptmp; - idx = X509_PURPOSE_get_by_id(purpose); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - ptmp = X509_PURPOSE_get0(idx); - if (ptmp->trust == X509_TRUST_DEFAULT) { - idx = X509_PURPOSE_get_by_id(def_purpose); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - ptmp = X509_PURPOSE_get0(idx); - } - /* If trust not set then get from purpose default */ - if (!trust) - trust = ptmp->trust; + int purpose, int trust) { + int idx; + // If purpose not set use default + if (!purpose) { + purpose = def_purpose; + } + // If we have a purpose then check it is valid + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); + return 0; } - if (trust) { - idx = X509_TRUST_get_by_id(trust); - if (idx == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); - return 0; - } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); } + // If trust not set then get from purpose default + if (!trust) { + trust = ptmp->trust; + } + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } - if (purpose && !ctx->param->purpose) - ctx->param->purpose = purpose; - if (trust && !ctx->param->trust) - ctx->param->trust = trust; - return 1; + if (purpose && !ctx->param->purpose) { + ctx->param->purpose = purpose; + } + if (trust && !ctx->param->trust) { + ctx->param->trust = trust; + } + return 1; } -X509_STORE_CTX *X509_STORE_CTX_new(void) -{ - X509_STORE_CTX *ctx; - ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); - if (!ctx) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return NULL; - } - X509_STORE_CTX_zero(ctx); - return ctx; +X509_STORE_CTX *X509_STORE_CTX_new(void) { + X509_STORE_CTX *ctx; + ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); + if (!ctx) { + return NULL; + } + X509_STORE_CTX_zero(ctx); + return ctx; } -void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) -{ - OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); +void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); } -void X509_STORE_CTX_free(X509_STORE_CTX *ctx) -{ - if (ctx == NULL) { - return; - } - X509_STORE_CTX_cleanup(ctx); - OPENSSL_free(ctx); +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) { + if (ctx == NULL) { + return; + } + X509_STORE_CTX_cleanup(ctx); + OPENSSL_free(ctx); } int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, - STACK_OF(X509) *chain) -{ - X509_STORE_CTX_zero(ctx); - ctx->ctx = store; - ctx->cert = x509; - ctx->untrusted = chain; + STACK_OF(X509) *chain) { + X509_STORE_CTX_zero(ctx); + ctx->ctx = store; + ctx->cert = x509; + ctx->untrusted = chain; - CRYPTO_new_ex_data(&ctx->ex_data); + CRYPTO_new_ex_data(&ctx->ex_data); - if (store == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - goto err; - } + if (store == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } - ctx->param = X509_VERIFY_PARAM_new(); - if (!ctx->param) - goto err; + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) { + goto err; + } - /* - * Inherit callbacks and flags from X509_STORE. - */ + // Inherit callbacks and flags from X509_STORE. + ctx->verify_cb = store->verify_cb; + ctx->cleanup = store->cleanup; + + if (!X509_VERIFY_PARAM_inherit(ctx->param, store->param) || + !X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default"))) { + goto err; + } + + if (store->check_issued) { + ctx->check_issued = store->check_issued; + } else { + ctx->check_issued = check_issued; + } + + if (store->get_issuer) { + ctx->get_issuer = store->get_issuer; + } else { + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + } + + if (store->verify_cb) { ctx->verify_cb = store->verify_cb; - ctx->cleanup = store->cleanup; + } else { + ctx->verify_cb = null_callback; + } - if (!X509_VERIFY_PARAM_inherit(ctx->param, store->param) || - !X509_VERIFY_PARAM_inherit(ctx->param, - X509_VERIFY_PARAM_lookup("default"))) { - goto err; - } + if (store->verify) { + ctx->verify = store->verify; + } else { + ctx->verify = internal_verify; + } - if (store->check_issued) - ctx->check_issued = store->check_issued; - else - ctx->check_issued = check_issued; + if (store->check_revocation) { + ctx->check_revocation = store->check_revocation; + } else { + ctx->check_revocation = check_revocation; + } - if (store->get_issuer) - ctx->get_issuer = store->get_issuer; - else - ctx->get_issuer = X509_STORE_CTX_get1_issuer; + if (store->get_crl) { + ctx->get_crl = store->get_crl; + } else { + ctx->get_crl = NULL; + } - if (store->verify_cb) - ctx->verify_cb = store->verify_cb; - else - ctx->verify_cb = null_callback; + if (store->check_crl) { + ctx->check_crl = store->check_crl; + } else { + ctx->check_crl = check_crl; + } - if (store->verify) - ctx->verify = store->verify; - else - ctx->verify = internal_verify; + if (store->cert_crl) { + ctx->cert_crl = store->cert_crl; + } else { + ctx->cert_crl = cert_crl; + } - if (store->check_revocation) - ctx->check_revocation = store->check_revocation; - else - ctx->check_revocation = check_revocation; + if (store->lookup_certs) { + ctx->lookup_certs = store->lookup_certs; + } else { + ctx->lookup_certs = X509_STORE_get1_certs; + } - if (store->get_crl) - ctx->get_crl = store->get_crl; - else - ctx->get_crl = NULL; + if (store->lookup_crls) { + ctx->lookup_crls = store->lookup_crls; + } else { + ctx->lookup_crls = X509_STORE_get1_crls; + } - if (store->check_crl) - ctx->check_crl = store->check_crl; - else - ctx->check_crl = check_crl; + ctx->check_policy = check_policy; - if (store->cert_crl) - ctx->cert_crl = store->cert_crl; - else - ctx->cert_crl = cert_crl; + return 1; - if (store->lookup_certs) - ctx->lookup_certs = store->lookup_certs; - else - ctx->lookup_certs = X509_STORE_get1_certs; +err: + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); + if (ctx->param != NULL) { + X509_VERIFY_PARAM_free(ctx->param); + } - if (store->lookup_crls) - ctx->lookup_crls = store->lookup_crls; - else - ctx->lookup_crls = X509_STORE_get1_crls; - - ctx->check_policy = check_policy; - - return 1; - - err: - CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); - if (ctx->param != NULL) { - X509_VERIFY_PARAM_free(ctx->param); - } - - OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + return 0; } -/* - * Set alternative lookup method: just a STACK of trusted certificates. This - * avoids X509_STORE nastiness where it isn't needed. - */ +// Set alternative lookup method: just a STACK of trusted certificates. This +// avoids X509_STORE nastiness where it isn't needed. -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->other_ctx = sk; - ctx->get_issuer = get_issuer_sk; +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, + STACK_OF(X509) *sk) { + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; } -void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) -{ - /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free| - * also calls this function. */ - if (ctx->cleanup != NULL) { - ctx->cleanup(ctx); - ctx->cleanup = NULL; - } - if (ctx->param != NULL) { - if (ctx->parent == NULL) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = NULL; - } - if (ctx->tree != NULL) { - X509_policy_tree_free(ctx->tree); - ctx->tree = NULL; - } - if (ctx->chain != NULL) { - sk_X509_pop_free(ctx->chain, X509_free); - ctx->chain = NULL; - } - CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data)); - OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { + X509_STORE_CTX_set0_trusted_stack(ctx, sk); } -void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { + // We need to be idempotent because, unfortunately, |X509_STORE_CTX_free| + // also calls this function. + if (ctx->cleanup != NULL) { + ctx->cleanup(ctx); + ctx->cleanup = NULL; + } + if (ctx->param != NULL) { + if (ctx->parent == NULL) { + X509_VERIFY_PARAM_free(ctx->param); + } + ctx->param = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data)); + OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); } -void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) -{ - X509_VERIFY_PARAM_set_flags(ctx->param, flags); +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) { + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) { + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, unsigned long flags, + int64_t t) { + X509_VERIFY_PARAM_set_time_posix(ctx->param, t); } void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, - time_t t) -{ - X509_VERIFY_PARAM_set_time(ctx->param, t); + time_t t) { + X509_STORE_CTX_set_time_posix(ctx, flags, t); } -X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) -{ - return ctx->cert; +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) { + return ctx->cert; } void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)) -{ - ctx->verify_cb = verify_cb; + int (*verify_cb)(int, X509_STORE_CTX *)) { + ctx->verify_cb = verify_cb; } -X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) -{ - return ctx->tree; +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) { + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) { + return 0; + } + return X509_VERIFY_PARAM_inherit(ctx->param, param); } -int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) -{ - return ctx->explicit_policy; +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) { + return ctx->param; } -int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) -{ - const X509_VERIFY_PARAM *param; - param = X509_VERIFY_PARAM_lookup(name); - if (!param) - return 0; - return X509_VERIFY_PARAM_inherit(ctx->param, param); -} - -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) -{ - return ctx->param; -} - -void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) -{ - if (ctx->param) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = param; +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) { + if (ctx->param) { + X509_VERIFY_PARAM_free(ctx->param); + } + ctx->param = param; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509_vpm.c b/third_party/boringssl/kit/src/crypto/x509/x509_vpm.c index 29d5341e..583b4a05 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509_vpm.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509_vpm.c @@ -62,590 +62,490 @@ #include #include -#include "internal.h" #include "../internal.h" #include "../x509v3/internal.h" +#include "internal.h" -/* X509_VERIFY_PARAM functions */ +// X509_VERIFY_PARAM functions #define SET_HOST 0 #define ADD_HOST 1 -static char *str_copy(char *s) -{ - return OPENSSL_strdup(s); -} - -static void str_free(char *s) -{ - OPENSSL_free(s); -} +static void str_free(char *s) { OPENSSL_free(s); } #define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode, - const char *name, size_t namelen) -{ - char *copy; + const char *name, size_t namelen) { + char *copy; - if (name == NULL || namelen == 0) { - // Unlike OpenSSL, we reject trying to set or add an empty name. - return 0; + if (name == NULL || namelen == 0) { + // Unlike OpenSSL, we reject trying to set or add an empty name. + return 0; + } + + // Refuse names with embedded NUL bytes. + // XXX: Do we need to push an error onto the error stack? + if (name && OPENSSL_memchr(name, '\0', namelen)) { + return 0; + } + + if (mode == SET_HOST && param->hosts) { + string_stack_free(param->hosts); + param->hosts = NULL; + } + + copy = OPENSSL_strndup(name, namelen); + if (copy == NULL) { + return 0; + } + + if (param->hosts == NULL && + (param->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { + OPENSSL_free(copy); + return 0; + } + + if (!sk_OPENSSL_STRING_push(param->hosts, copy)) { + OPENSSL_free(copy); + if (sk_OPENSSL_STRING_num(param->hosts) == 0) { + sk_OPENSSL_STRING_free(param->hosts); + param->hosts = NULL; } + return 0; + } - /* - * Refuse names with embedded NUL bytes. - * XXX: Do we need to push an error onto the error stack? - */ - if (name && OPENSSL_memchr(name, '\0', namelen)) - return 0; - - if (mode == SET_HOST && param->hosts) { - string_stack_free(param->hosts); - param->hosts = NULL; - } - - copy = OPENSSL_strndup(name, namelen); - if (copy == NULL) - return 0; - - if (param->hosts == NULL && - (param->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { - OPENSSL_free(copy); - return 0; - } - - if (!sk_OPENSSL_STRING_push(param->hosts, copy)) { - OPENSSL_free(copy); - if (sk_OPENSSL_STRING_num(param->hosts) == 0) { - sk_OPENSSL_STRING_free(param->hosts); - param->hosts = NULL; - } - return 0; - } - - return 1; + return 1; } -static void x509_verify_param_zero(X509_VERIFY_PARAM *param) -{ - if (!param) - return; - param->name = NULL; - param->purpose = 0; - param->trust = 0; - /* - * param->inh_flags = X509_VP_FLAG_DEFAULT; - */ - param->inh_flags = 0; - param->flags = 0; - param->depth = -1; - if (param->policies) { - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - param->policies = NULL; - } - if (param->hosts) { - string_stack_free(param->hosts); - param->hosts = NULL; - } - if (param->peername) { - OPENSSL_free(param->peername); - param->peername = NULL; - } - if (param->email) { - OPENSSL_free(param->email); - param->email = NULL; - param->emaillen = 0; - } - if (param->ip) { - OPENSSL_free(param->ip); - param->ip = NULL; - param->iplen = 0; - } - param->poison = 0; +static void x509_verify_param_zero(X509_VERIFY_PARAM *param) { + if (!param) { + return; + } + param->name = NULL; + param->purpose = 0; + param->trust = 0; + // param->inh_flags = X509_VP_FLAG_DEFAULT; + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } + if (param->hosts) { + string_stack_free(param->hosts); + param->hosts = NULL; + } + if (param->peername) { + OPENSSL_free(param->peername); + param->peername = NULL; + } + if (param->email) { + OPENSSL_free(param->email); + param->email = NULL; + param->emaillen = 0; + } + if (param->ip) { + OPENSSL_free(param->ip); + param->ip = NULL; + param->iplen = 0; + } + param->poison = 0; } -X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) -{ - X509_VERIFY_PARAM *param; - param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); - if (!param) - return NULL; - OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM)); - x509_verify_param_zero(param); - return param; +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) { + X509_VERIFY_PARAM *param; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + if (!param) { + return NULL; + } + OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM)); + x509_verify_param_zero(param); + return param; } -void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) -{ - if (param == NULL) - return; - x509_verify_param_zero(param); - OPENSSL_free(param); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) { + if (param == NULL) { + return; + } + x509_verify_param_zero(param); + OPENSSL_free(param); } -/*- - * This function determines how parameters are "inherited" from one structure - * to another. There are several different ways this can happen. - * - * 1. If a child structure needs to have its values initialized from a parent - * they are simply copied across. For example SSL_CTX copied to SSL. - * 2. If the structure should take on values only if they are currently unset. - * For example the values in an SSL structure will take appropriate value - * for SSL servers or clients but only if the application has not set new - * ones. - * - * The "inh_flags" field determines how this function behaves. - * - * Normally any values which are set in the default are not copied from the - * destination and verify flags are ORed together. - * - * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied - * to the destination. Effectively the values in "to" become default values - * which will be used only if nothing new is set in "from". - * - * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether - * they are set or not. Flags is still Ored though. - * - * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead - * of ORed. - * - * If X509_VP_FLAG_LOCKED is set then no values are copied. - * - * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed - * after the next call. - */ +//- +// This function determines how parameters are "inherited" from one structure +// to another. There are several different ways this can happen. +// +// 1. If a child structure needs to have its values initialized from a parent +// they are simply copied across. For example SSL_CTX copied to SSL. +// 2. If the structure should take on values only if they are currently unset. +// For example the values in an SSL structure will take appropriate value +// for SSL servers or clients but only if the application has not set new +// ones. +// +// The "inh_flags" field determines how this function behaves. +// +// Normally any values which are set in the default are not copied from the +// destination and verify flags are ORed together. +// +// If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied +// to the destination. Effectively the values in "to" become default values +// which will be used only if nothing new is set in "from". +// +// If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether +// they are set or not. Flags is still Ored though. +// +// If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead +// of ORed. +// +// If X509_VP_FLAG_LOCKED is set then no values are copied. +// +// If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed +// after the next call. -/* Macro to test if a field should be copied from src to dest */ +// Macro to test if a field should be copied from src to dest #define test_x509_verify_param_copy(field, def) \ (to_overwrite || \ ((src->field != (def)) && (to_default || (dest->field == (def))))) -/* Macro to test and copy a field if necessary */ +// Macro to test and copy a field if necessary -#define x509_verify_param_copy(field, def) \ - if (test_x509_verify_param_copy(field, def)) \ - dest->field = src->field +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, - const X509_VERIFY_PARAM *src) -{ - unsigned long inh_flags; - int to_default, to_overwrite; - if (!src) - return 1; - inh_flags = dest->inh_flags | src->inh_flags; - - if (inh_flags & X509_VP_FLAG_ONCE) - dest->inh_flags = 0; - - if (inh_flags & X509_VP_FLAG_LOCKED) - return 1; - - if (inh_flags & X509_VP_FLAG_DEFAULT) - to_default = 1; - else - to_default = 0; - - if (inh_flags & X509_VP_FLAG_OVERWRITE) - to_overwrite = 1; - else - to_overwrite = 0; - - x509_verify_param_copy(purpose, 0); - x509_verify_param_copy(trust, 0); - x509_verify_param_copy(depth, -1); - - /* If overwrite or check time not set, copy across */ - - if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { - dest->check_time = src->check_time; - dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; - /* Don't need to copy flag: that is done below */ - } - - if (inh_flags & X509_VP_FLAG_RESET_FLAGS) - dest->flags = 0; - - dest->flags |= src->flags; - - if (test_x509_verify_param_copy(policies, NULL)) { - if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) - return 0; - } - - /* Copy the host flags if and only if we're copying the host list */ - if (test_x509_verify_param_copy(hosts, NULL)) { - if (dest->hosts) { - string_stack_free(dest->hosts); - dest->hosts = NULL; - } - if (src->hosts) { - dest->hosts = - sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); - if (dest->hosts == NULL) - return 0; - dest->hostflags = src->hostflags; - } - } - - if (test_x509_verify_param_copy(email, NULL)) { - if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) - return 0; - } - - if (test_x509_verify_param_copy(ip, NULL)) { - if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) - return 0; - } - - dest->poison = src->poison; - + const X509_VERIFY_PARAM *src) { + unsigned long inh_flags; + int to_default, to_overwrite; + if (!src) { return 1; + } + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) { + dest->inh_flags = 0; + } + + if (inh_flags & X509_VP_FLAG_LOCKED) { + return 1; + } + + if (inh_flags & X509_VP_FLAG_DEFAULT) { + to_default = 1; + } else { + to_default = 0; + } + + if (inh_flags & X509_VP_FLAG_OVERWRITE) { + to_overwrite = 1; + } else { + to_overwrite = 0; + } + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + // If overwrite or check time not set, copy across + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + // Don't need to copy flag: that is done below + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) { + dest->flags = 0; + } + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) { + return 0; + } + } + + // Copy the host flags if and only if we're copying the host list + if (test_x509_verify_param_copy(hosts, NULL)) { + if (dest->hosts) { + string_stack_free(dest->hosts); + dest->hosts = NULL; + } + if (src->hosts) { + dest->hosts = + sk_OPENSSL_STRING_deep_copy(src->hosts, OPENSSL_strdup, str_free); + if (dest->hosts == NULL) { + return 0; + } + dest->hostflags = src->hostflags; + } + } + + if (test_x509_verify_param_copy(email, NULL)) { + if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) { + return 0; + } + } + + if (test_x509_verify_param_copy(ip, NULL)) { + if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) { + return 0; + } + } + + dest->poison = src->poison; + + return 1; } int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from) -{ - unsigned long save_flags = to->inh_flags; - int ret; - to->inh_flags |= X509_VP_FLAG_DEFAULT; - ret = X509_VERIFY_PARAM_inherit(to, from); - to->inh_flags = save_flags; - return ret; + const X509_VERIFY_PARAM *from) { + unsigned long save_flags = to->inh_flags; + int ret; + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; } -static int int_x509_param_set1(char **pdest, size_t *pdestlen, - const char *src, size_t srclen) -{ - void *tmp; - if (src == NULL || srclen == 0) { - // Unlike OpenSSL, we do not allow an empty string to disable previously - // configured checks. - return 0; - } - - tmp = OPENSSL_memdup(src, srclen); - if (!tmp) { - return 0; - } - - if (*pdest) - OPENSSL_free(*pdest); - *pdest = tmp; - if (pdestlen) - *pdestlen = srclen; - return 1; -} - -int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) -{ - if (param->name) - OPENSSL_free(param->name); - param->name = OPENSSL_strdup(name); - if (param->name) - return 1; +static int int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src, + size_t srclen) { + void *tmp; + if (src == NULL || srclen == 0) { + // Unlike OpenSSL, we do not allow an empty string to disable previously + // configured checks. return 0; + } + + tmp = OPENSSL_memdup(src, srclen); + if (!tmp) { + return 0; + } + + if (*pdest) { + OPENSSL_free(*pdest); + } + *pdest = tmp; + if (pdestlen) { + *pdestlen = srclen; + } + return 1; } -int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) -{ - param->flags |= flags; - if (flags & X509_V_FLAG_POLICY_MASK) - param->flags |= X509_V_FLAG_POLICY_CHECK; +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) { + if (param->name) { + OPENSSL_free(param->name); + } + param->name = OPENSSL_strdup(name); + if (param->name) { return 1; + } + return 0; +} + +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) { + param->flags |= flags; + return 1; } int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, - unsigned long flags) -{ - param->flags &= ~flags; - return 1; + unsigned long flags) { + param->flags &= ~flags; + return 1; } -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) -{ - return param->flags; +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) { + return param->flags; } -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) -{ - return X509_PURPOSE_set(¶m->purpose, purpose); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) { + return X509_PURPOSE_set(¶m->purpose, purpose); } -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) -{ - return X509_TRUST_set(¶m->trust, trust); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) { + return X509_TRUST_set(¶m->trust, trust); } -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) -{ - param->depth = depth; +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) { + param->depth = depth; } -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) -{ - param->check_time = t; - param->flags |= X509_V_FLAG_USE_CHECK_TIME; +void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, int64_t t) { + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} + +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) { + X509_VERIFY_PARAM_set_time_posix(param, t); } int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, - ASN1_OBJECT *policy) -{ + ASN1_OBJECT *policy) { + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); if (!param->policies) { - param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) - return 0; + return 0; } - if (!sk_ASN1_OBJECT_push(param->policies, policy)) - return 0; - return 1; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) { + return 0; + } + return 1; } int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies) -{ - size_t i; - ASN1_OBJECT *oid, *doid; - if (!param) - return 0; - if (param->policies) - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + const STACK_OF(ASN1_OBJECT) *policies) { + if (!param) { + return 0; + } - if (!policies) { - param->policies = NULL; - return 1; - } - - param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) - return 0; - - for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { - oid = sk_ASN1_OBJECT_value(policies, i); - doid = OBJ_dup(oid); - if (!doid) - return 0; - if (!sk_ASN1_OBJECT_push(param->policies, doid)) { - ASN1_OBJECT_free(doid); - return 0; - } - } - param->flags |= X509_V_FLAG_POLICY_CHECK; + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + if (!policies) { + param->policies = NULL; return 1; + } + + param->policies = + sk_ASN1_OBJECT_deep_copy(policies, OBJ_dup, ASN1_OBJECT_free); + if (!param->policies) { + return 0; + } + + return 1; } -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - if (!int_x509_param_set_hosts(param, SET_HOST, name, namelen)) { - param->poison = 1; - return 0; - } - return 1; +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, + size_t namelen) { + if (!int_x509_param_set_hosts(param, SET_HOST, name, namelen)) { + param->poison = 1; + return 0; + } + return 1; } -int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - if (!int_x509_param_set_hosts(param, ADD_HOST, name, namelen)) { - param->poison = 1; - return 0; - } - return 1; +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, const char *name, + size_t namelen) { + if (!int_x509_param_set_hosts(param, ADD_HOST, name, namelen)) { + param->poison = 1; + return 0; + } + return 1; } void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags) -{ - param->hostflags = flags; + unsigned int flags) { + param->hostflags = flags; } -char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) -{ - return param->peername; +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) { + return param->peername; } -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen) -{ - if (OPENSSL_memchr(email, '\0', emaillen) != NULL || - !int_x509_param_set1(¶m->email, ¶m->emaillen, - email, emaillen)) { - param->poison = 1; - return 0; - } +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, + size_t emaillen) { + if (OPENSSL_memchr(email, '\0', emaillen) != NULL || + !int_x509_param_set1(¶m->email, ¶m->emaillen, email, emaillen)) { + param->poison = 1; + return 0; + } - return 1; + return 1; } -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, size_t iplen) -{ - if ((iplen != 4 && iplen != 16) || - !int_x509_param_set1((char **)¶m->ip, ¶m->iplen, - (char *)ip, iplen)) { - param->poison = 1; - return 0; - } +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, + size_t iplen) { + if ((iplen != 4 && iplen != 16) || + !int_x509_param_set1((char **)¶m->ip, ¶m->iplen, (char *)ip, + iplen)) { + param->poison = 1; + return 0; + } - return 1; + return 1; } -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) -{ - unsigned char ipout[16]; - size_t iplen; +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) { + unsigned char ipout[16]; + size_t iplen; - iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); - if (iplen == 0) - return 0; - return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); + iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); + if (iplen == 0) { + return 0; + } + return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); } -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) -{ - return param->depth; +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) { + return param->depth; } -const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) -{ - return param->name; +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) { + return param->name; } #define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0, 0 -/* - * Default verify parameters: these are used for various applications and can - * be overridden by the user specified table. NB: the 'name' field *must* be - * in alphabetical order because it will be searched using OBJ_search. - */ +// Default verify parameters: these are used for various applications and can +// be overridden by the user specified table. NB: the 'name' field *must* be +// in alphabetical order because it will be searched using OBJ_search. static const X509_VERIFY_PARAM default_table[] = { - { - (char *)"default", /* X509 default parameters */ - 0, /* Check time */ - 0, /* internal flags */ - X509_V_FLAG_TRUSTED_FIRST, /* flags */ - 0, /* purpose */ - 0, /* trust */ - 100, /* depth */ - NULL, /* policies */ + {(char *)"default", // X509 default parameters + 0, // Check time + 0, // internal flags + X509_V_FLAG_TRUSTED_FIRST, // flags + 0, // purpose + 0, // trust + 100, // depth + NULL, // policies vpm_empty_id}, - { - (char *)"pkcs7", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SMIME_SIGN, /* purpose */ - X509_TRUST_EMAIL, /* trust */ - -1, /* depth */ - NULL, /* policies */ + {(char *)"pkcs7", // S/MIME sign parameters + 0, // Check time + 0, // internal flags + 0, // flags + X509_PURPOSE_SMIME_SIGN, // purpose + X509_TRUST_EMAIL, // trust + -1, // depth + NULL, // policies vpm_empty_id}, - { - (char *)"smime_sign", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SMIME_SIGN, /* purpose */ - X509_TRUST_EMAIL, /* trust */ - -1, /* depth */ - NULL, /* policies */ + {(char *)"smime_sign", // S/MIME sign parameters + 0, // Check time + 0, // internal flags + 0, // flags + X509_PURPOSE_SMIME_SIGN, // purpose + X509_TRUST_EMAIL, // trust + -1, // depth + NULL, // policies vpm_empty_id}, - { - (char *)"ssl_client", /* SSL/TLS client parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SSL_CLIENT, /* purpose */ - X509_TRUST_SSL_CLIENT, /* trust */ - -1, /* depth */ - NULL, /* policies */ + {(char *)"ssl_client", // SSL/TLS client parameters + 0, // Check time + 0, // internal flags + 0, // flags + X509_PURPOSE_SSL_CLIENT, // purpose + X509_TRUST_SSL_CLIENT, // trust + -1, // depth + NULL, // policies vpm_empty_id}, - { - (char *)"ssl_server", /* SSL/TLS server parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SSL_SERVER, /* purpose */ - X509_TRUST_SSL_SERVER, /* trust */ - -1, /* depth */ - NULL, /* policies */ - vpm_empty_id} -}; + {(char *)"ssl_server", // SSL/TLS server parameters + 0, // Check time + 0, // internal flags + 0, // flags + X509_PURPOSE_SSL_SERVER, // purpose + X509_TRUST_SSL_SERVER, // trust + -1, // depth + NULL, // policies + vpm_empty_id}}; -static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; - -static int param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b) -{ - return strcmp((*a)->name, (*b)->name); -} - -int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) -{ - X509_VERIFY_PARAM *ptmp; - if (!param_table) { - param_table = sk_X509_VERIFY_PARAM_new(param_cmp); - if (!param_table) - return 0; - } else { - size_t idx; - - sk_X509_VERIFY_PARAM_sort(param_table); - if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) { - ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); - X509_VERIFY_PARAM_free(ptmp); - (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); - } +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(default_table); i++) { + if (strcmp(default_table[i].name, name) == 0) { + return &default_table[i]; } - if (!sk_X509_VERIFY_PARAM_push(param_table, param)) - return 0; - return 1; -} - -int X509_VERIFY_PARAM_get_count(void) -{ - int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); - if (param_table) - num += sk_X509_VERIFY_PARAM_num(param_table); - return num; -} - -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) -{ - int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); - if (id < num) - return default_table + id; - return sk_X509_VERIFY_PARAM_value(param_table, id - num); -} - -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) -{ - X509_VERIFY_PARAM pm; - unsigned i, limit; - - pm.name = (char *)name; - if (param_table) { - size_t idx; - sk_X509_VERIFY_PARAM_sort(param_table); - if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm)) - return sk_X509_VERIFY_PARAM_value(param_table, idx); - } - - limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); - for (i = 0; i < limit; i++) { - if (strcmp(default_table[i].name, name) == 0) { - return &default_table[i]; - } - } - return NULL; -} - -void X509_VERIFY_PARAM_table_cleanup(void) -{ - if (param_table) - sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); - param_table = NULL; + } + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509cset.c b/third_party/boringssl/kit/src/crypto/x509/x509cset.c index 316f0847..6dd1fc08 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509cset.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509cset.c @@ -59,218 +59,219 @@ #include #include +#include "../asn1/internal.h" #include "../internal.h" #include "internal.h" -int X509_CRL_set_version(X509_CRL *x, long version) -{ - if (x == NULL) - return (0); +int X509_CRL_set_version(X509_CRL *x, long version) { + if (x == NULL) { + return 0; + } + + if (version < X509_CRL_VERSION_1 || version > X509_CRL_VERSION_2) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; + } + + // v1(0) is default and is represented by omitting the version. + if (version == X509_CRL_VERSION_1) { + ASN1_INTEGER_free(x->crl->version); + x->crl->version = NULL; + return 1; + } + + if (x->crl->version == NULL) { + x->crl->version = ASN1_INTEGER_new(); if (x->crl->version == NULL) { - if ((x->crl->version = ASN1_INTEGER_new()) == NULL) - return (0); + return 0; } - return (ASN1_INTEGER_set(x->crl->version, version)); + } + return ASN1_INTEGER_set_int64(x->crl->version, version); } -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) -{ - if ((x == NULL) || (x->crl == NULL)) - return (0); - return (X509_NAME_set(&x->crl->issuer, name)); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) { + if ((x == NULL) || (x->crl == NULL)) { + return 0; + } + return (X509_NAME_set(&x->crl->issuer, name)); } -int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) { + ASN1_TIME *in; - if (x == NULL) - return (0); - in = x->crl->lastUpdate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->crl->lastUpdate); - x->crl->lastUpdate = in; - } + if (x == NULL) { + return 0; + } + in = x->crl->lastUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; } - return (in != NULL); + } + return in != NULL; } -int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { + ASN1_TIME *in; - if (x == NULL) - return (0); - in = x->crl->nextUpdate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->crl->nextUpdate); - x->crl->nextUpdate = in; - } + if (x == NULL) { + return 0; + } + in = x->crl->nextUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; } - return (in != NULL); + } + return in != NULL; } -int X509_CRL_sort(X509_CRL *c) -{ - /* Sort the data so it will be written in serial number order. */ - sk_X509_REVOKED_sort(c->crl->revoked); - c->crl->enc.modified = 1; - return 1; +int X509_CRL_sort(X509_CRL *c) { + // Sort the data so it will be written in serial number order. + sk_X509_REVOKED_sort(c->crl->revoked); + asn1_encoding_clear(&c->crl->enc); + return 1; } -int X509_CRL_up_ref(X509_CRL *crl) -{ - CRYPTO_refcount_inc(&crl->references); - return 1; +int X509_CRL_up_ref(X509_CRL *crl) { + CRYPTO_refcount_inc(&crl->references); + return 1; } -long X509_CRL_get_version(const X509_CRL *crl) -{ - return ASN1_INTEGER_get(crl->crl->version); +long X509_CRL_get_version(const X509_CRL *crl) { + return ASN1_INTEGER_get(crl->crl->version); } -const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl) -{ - return crl->crl->lastUpdate; +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl) { + return crl->crl->lastUpdate; } -const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) -{ - return crl->crl->nextUpdate; +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) { + return crl->crl->nextUpdate; } -ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) -{ - return crl->crl->lastUpdate; +ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) { + return crl->crl->lastUpdate; } -ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl) -{ - return crl->crl->nextUpdate; +ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl) { + return crl->crl->nextUpdate; } -X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl) -{ - return crl->crl->issuer; +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl) { return crl->crl->issuer; } + +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl) { + return crl->crl->revoked; } -STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl) -{ - return crl->crl->revoked; -} - -const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl) -{ - return crl->crl->extensions; +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl) { + return crl->crl->extensions; } void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = crl->signature; - if (palg != NULL) - *palg = crl->sig_alg; + const X509_ALGOR **palg) { + if (psig != NULL) { + *psig = crl->signature; + } + if (palg != NULL) { + *palg = crl->sig_alg; + } } -int X509_CRL_get_signature_nid(const X509_CRL *crl) -{ - return OBJ_obj2nid(crl->sig_alg->algorithm); +int X509_CRL_get_signature_nid(const X509_CRL *crl) { + return OBJ_obj2nid(crl->sig_alg->algorithm); } -const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *revoked) -{ - return revoked->revocationDate; +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *revoked) { + return revoked->revocationDate; } -int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, const ASN1_TIME *tm) -{ - ASN1_TIME *in; +int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, + const ASN1_TIME *tm) { + ASN1_TIME *in; - if (revoked == NULL) - return (0); - in = revoked->revocationDate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(revoked->revocationDate); - revoked->revocationDate = in; - } + if (revoked == NULL) { + return 0; + } + in = revoked->revocationDate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(revoked->revocationDate); + revoked->revocationDate = in; } - return (in != NULL); + } + return in != NULL; } -const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *revoked) -{ - return revoked->serialNumber; +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber( + const X509_REVOKED *revoked) { + return revoked->serialNumber; } int X509_REVOKED_set_serialNumber(X509_REVOKED *revoked, - const ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; + const ASN1_INTEGER *serial) { + ASN1_INTEGER *in; - if (revoked == NULL) - return (0); - in = revoked->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - ASN1_INTEGER_free(revoked->serialNumber); - revoked->serialNumber = in; - } + if (serial->type != V_ASN1_INTEGER && serial->type != V_ASN1_NEG_INTEGER) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } + + if (revoked == NULL) { + return 0; + } + in = revoked->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(revoked->serialNumber); + revoked->serialNumber = in; } - return (in != NULL); + } + return in != NULL; } -const STACK_OF(X509_EXTENSION) * - X509_REVOKED_get0_extensions(const X509_REVOKED *r) -{ - return r->extensions; +const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions( + const X509_REVOKED *r) { + return r->extensions; } -int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) -{ - crl->crl->enc.modified = 1; - return i2d_X509_CRL_INFO(crl->crl, outp); +int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) { + asn1_encoding_clear(&crl->crl->enc); + return i2d_X509_CRL_INFO(crl->crl, outp); } -int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) -{ - return i2d_X509_CRL_INFO(crl->crl, outp); +int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) { + return i2d_X509_CRL_INFO(crl->crl, outp); } -int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo) -{ - /* TODO(davidben): Const-correct generated ASN.1 dup functions. - * Alternatively, when the types are hidden and we can embed required fields - * directly in structs, import |X509_ALGOR_copy| from upstream. */ - X509_ALGOR *copy1 = X509_ALGOR_dup((X509_ALGOR *)algo); - X509_ALGOR *copy2 = X509_ALGOR_dup((X509_ALGOR *)algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } +int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo) { + X509_ALGOR *copy1 = X509_ALGOR_dup(algo); + X509_ALGOR *copy2 = X509_ALGOR_dup(algo); + if (copy1 == NULL || copy2 == NULL) { + X509_ALGOR_free(copy1); + X509_ALGOR_free(copy2); + return 0; + } - X509_ALGOR_free(crl->sig_alg); - crl->sig_alg = copy1; - X509_ALGOR_free(crl->crl->sig_alg); - crl->crl->sig_alg = copy2; - return 1; + X509_ALGOR_free(crl->sig_alg); + crl->sig_alg = copy1; + X509_ALGOR_free(crl->crl->sig_alg); + crl->crl->sig_alg = copy2; + return 1; } int X509_CRL_set1_signature_value(X509_CRL *crl, const uint8_t *sig, - size_t sig_len) -{ - if (!ASN1_STRING_set(crl->signature, sig, sig_len)) { - return 0; - } - crl->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - crl->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - return 1; + size_t sig_len) { + if (!ASN1_STRING_set(crl->signature, sig, sig_len)) { + return 0; + } + crl->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + crl->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509name.c b/third_party/boringssl/kit/src/crypto/x509/x509name.c index 6bc09521..eec2c8e0 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509name.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509name.c @@ -68,321 +68,318 @@ int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, char *buf, - int len) -{ - const ASN1_OBJECT *obj; + int len) { + const ASN1_OBJECT *obj; - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-1); - return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -1; + } + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); } int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, - char *buf, int len) -{ - int i; - ASN1_STRING *data; - - i = X509_NAME_get_index_by_OBJ(name, obj, -1); - if (i < 0) - return (-1); - data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); - i = (data->length > (len - 1)) ? (len - 1) : data->length; - if (buf == NULL) - return (data->length); - OPENSSL_memcpy(buf, data->data, i); - buf[i] = '\0'; - return (i); + char *buf, int len) { + int i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) { + return -1; + } + const ASN1_STRING *data = + X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + i = (data->length > (len - 1)) ? (len - 1) : data->length; + if (buf == NULL) { + return data->length; + } + OPENSSL_memcpy(buf, data->data, i); + buf[i] = '\0'; + return i; } -int X509_NAME_entry_count(const X509_NAME *name) -{ - if (name == NULL) - return (0); - return (sk_X509_NAME_ENTRY_num(name->entries)); +int X509_NAME_entry_count(const X509_NAME *name) { + if (name == NULL) { + return 0; + } + return (int)sk_X509_NAME_ENTRY_num(name->entries); } -int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) -{ - const ASN1_OBJECT *obj; +int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) { + const ASN1_OBJECT *obj; - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return -2; + } + return X509_NAME_get_index_by_OBJ(name, obj, lastpos); } -/* NOTE: you should be passsing -1, not 0 as lastpos */ +// NOTE: you should be passsing -1, not 0 as lastpos int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, - int lastpos) -{ - int n; - X509_NAME_ENTRY *ne; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL) - return (-1); - if (lastpos < 0) - lastpos = -1; - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - for (lastpos++; lastpos < n; lastpos++) { - ne = sk_X509_NAME_ENTRY_value(sk, lastpos); - if (OBJ_cmp(ne->object, obj) == 0) - return (lastpos); + int lastpos) { + if (name == NULL) { + return -1; + } + if (lastpos < 0) { + lastpos = -1; + } + const STACK_OF(X509_NAME_ENTRY) *sk = name->entries; + int n = (int)sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + const X509_NAME_ENTRY *ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) { + return lastpos; } - return (-1); + } + return -1; } -X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) -{ - if (name == NULL || loc < 0 - || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) - return (NULL); - else - return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) { + if (name == NULL || loc < 0 || + sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) { + return NULL; + } else { + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); + } } -X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) -{ - X509_NAME_ENTRY *ret; - int i, n, set_prev, set_next; - STACK_OF(X509_NAME_ENTRY) *sk; +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) { + if (name == NULL || loc < 0 || + sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) { + return NULL; + } - if (name == NULL || loc < 0 - || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) - return (NULL); - sk = name->entries; - ret = sk_X509_NAME_ENTRY_delete(sk, loc); - n = sk_X509_NAME_ENTRY_num(sk); - name->modified = 1; - if (loc == n) - return (ret); - - /* else we need to fixup the set field */ - if (loc != 0) - set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; - else - set_prev = ret->set - 1; - set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; - - /* - * set_prev is the previous set set is the current set set_next is the - * following prev 1 1 1 1 1 1 1 1 set 1 1 2 2 next 1 1 2 2 2 2 3 2 so - * basically only if prev and next differ by 2, then re-number down by 1 - */ - if (set_prev + 1 < set_next) - for (i = loc; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i)->set--; - return (ret); -} - -int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); + STACK_OF(X509_NAME_ENTRY) *sk = name->entries; + X509_NAME_ENTRY *ret = sk_X509_NAME_ENTRY_delete(sk, loc); + size_t n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if ((size_t)loc == n) { return ret; + } + + int set_prev; + if (loc != 0) { + set_prev = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + } else { + set_prev = ret->set - 1; + } + int set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + // If we removed a singleton RDN, update the RDN indices so they are + // consecutive again. + if (set_prev + 1 < set_next) { + for (size_t i = loc; i < n; i++) { + sk_X509_NAME_ENTRY_value(sk, i)->set--; + } + } + return ret; +} + +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, + ossl_ssize_t len, int loc, int set) { + X509_NAME_ENTRY *ne = + X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) { + return 0; + } + int ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; } int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, - const unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; + const unsigned char *bytes, ossl_ssize_t len, + int loc, int set) { + X509_NAME_ENTRY *ne = + X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) { + return 0; + } + int ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; } int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, - const unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; + const unsigned char *bytes, ossl_ssize_t len, + int loc, int set) { + X509_NAME_ENTRY *ne = + X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) { + return 0; + } + int ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; } -/* - * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the - * guy we are about to stomp on. - */ -int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, - int set) -{ - X509_NAME_ENTRY *new_name = NULL; - int n, i, inc; - STACK_OF(X509_NAME_ENTRY) *sk; +// if set is -1, append to previous set, 0 'a new one', and 1, prepend to the +// guy we are about to stomp on. +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *entry, int loc, + int set) { + X509_NAME_ENTRY *new_name = NULL; + int i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; - if (name == NULL) - return (0); - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - if (loc > n) - loc = n; - else if (loc < 0) - loc = n; + if (name == NULL) { + return 0; + } + sk = name->entries; + int n = (int)sk_X509_NAME_ENTRY_num(sk); + if (loc > n) { + loc = n; + } else if (loc < 0) { + loc = n; + } - inc = (set == 0); - name->modified = 1; + inc = (set == 0); + name->modified = 1; - if (set == -1) { - if (loc == 0) { - set = 0; - inc = 1; - } else { - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; - } - } else { /* if (set >= 0) */ - - if (loc >= n) { - if (loc != 0) - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; - else - set = 0; - } else - set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; } + } else { // if (set >= 0) - if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) - goto err; - new_name->set = set; - if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto err; + if (loc >= n) { + if (loc != 0) { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + } else { + set = 0; + } + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; } - if (inc) { - n = sk_X509_NAME_ENTRY_num(sk); - for (i = loc + 1; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i)->set += 1; + } + + if ((new_name = X509_NAME_ENTRY_dup(entry)) == NULL) { + goto err; + } + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + goto err; + } + if (inc) { + n = (int)sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) { + sk_X509_NAME_ENTRY_value(sk, i)->set += 1; } - return (1); - err: - if (new_name != NULL) - X509_NAME_ENTRY_free(new_name); - return (0); + } + return 1; +err: + if (new_name != NULL) { + X509_NAME_ENTRY_free(new_name); + } + return 0; } X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, - int len) -{ - ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; + ossl_ssize_t len) { + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; - obj = OBJ_txt2obj(field, 0); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", field); - return (NULL); - } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nentry; + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", field); + return NULL; + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; } X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, const unsigned char *bytes, - int len) -{ - const ASN1_OBJECT *obj = OBJ_nid2obj(nid); - if (obj == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); - return NULL; - } - return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ossl_ssize_t len) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); } X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, - const ASN1_OBJECT *obj, - int type, + const ASN1_OBJECT *obj, int type, const unsigned char *bytes, - int len) -{ - X509_NAME_ENTRY *ret; + ossl_ssize_t len) { + X509_NAME_ENTRY *ret; - if ((ne == NULL) || (*ne == NULL)) { - if ((ret = X509_NAME_ENTRY_new()) == NULL) - return (NULL); - } else - ret = *ne; + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) { + return NULL; + } + } else { + ret = *ne; + } - if (!X509_NAME_ENTRY_set_object(ret, obj)) - goto err; - if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) - goto err; + if (!X509_NAME_ENTRY_set_object(ret, obj)) { + goto err; + } + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) { + goto err; + } - if ((ne != NULL) && (*ne == NULL)) - *ne = ret; - return (ret); - err: - if ((ne == NULL) || (ret != *ne)) - X509_NAME_ENTRY_free(ret); - return (NULL); + if ((ne != NULL) && (*ne == NULL)) { + *ne = ret; + } + return ret; +err: + if ((ne == NULL) || (ret != *ne)) { + X509_NAME_ENTRY_free(ret); + } + return NULL; } -int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) -{ - if ((ne == NULL) || (obj == NULL)) { - OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - ASN1_OBJECT_free(ne->object); - ne->object = OBJ_dup(obj); - return ((ne->object == NULL) ? 0 : 1); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) { + if ((ne == NULL) || (obj == NULL)) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); } int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, int len) -{ - int i; - - if ((ne == NULL) || ((bytes == NULL) && (len != 0))) - return (0); - if ((type > 0) && (type & MBSTRING_FLAG)) - return ASN1_STRING_set_by_NID(&ne->value, bytes, - len, type, - OBJ_obj2nid(ne->object)) ? 1 : 0; - if (len < 0) - len = strlen((const char *)bytes); - i = ASN1_STRING_set(ne->value, bytes, len); - if (!i) - return (0); - if (type != V_ASN1_UNDEF) { - ne->value->type = type; - } - return (1); + const unsigned char *bytes, ossl_ssize_t len) { + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) { + return 0; + } + if ((type > 0) && (type & MBSTRING_FLAG)) { + return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type, + OBJ_obj2nid(ne->object)) + ? 1 + : 0; + } + if (len < 0) { + len = strlen((const char *)bytes); + } + if (!ASN1_STRING_set(ne->value, bytes, len)) { + return 0; + } + if (type != V_ASN1_UNDEF) { + ne->value->type = type; + } + return 1; } -ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->object); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) { + if (ne == NULL) { + return NULL; + } + return ne->object; } -ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->value); +ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) { + if (ne == NULL) { + return NULL; + } + return ne->value; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509rset.c b/third_party/boringssl/kit/src/crypto/x509/x509rset.c index 72b41489..8b8beffd 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509rset.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509rset.c @@ -62,23 +62,48 @@ #include "internal.h" -int X509_REQ_set_version(X509_REQ *x, long version) -{ - if (x == NULL) - return (0); - return (ASN1_INTEGER_set(x->req_info->version, version)); +int X509_REQ_set_version(X509_REQ *x, long version) { + if (x == NULL) { + return 0; + } + if (version != X509_REQ_VERSION_1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; + } + return ASN1_INTEGER_set_int64(x->req_info->version, version); } -int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) -{ - if ((x == NULL) || (x->req_info == NULL)) - return (0); - return (X509_NAME_set(&x->req_info->subject, name)); +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) { + if ((x == NULL) || (x->req_info == NULL)) { + return 0; + } + return (X509_NAME_set(&x->req_info->subject, name)); } -int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->req_info == NULL)) - return (0); - return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) { + if ((x == NULL) || (x->req_info == NULL)) { + return 0; + } + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} + +int X509_REQ_set1_signature_algo(X509_REQ *req, const X509_ALGOR *algo) { + X509_ALGOR *copy = X509_ALGOR_dup(algo); + if (copy == NULL) { + return 0; + } + + X509_ALGOR_free(req->sig_alg); + req->sig_alg = copy; + return 1; +} + +int X509_REQ_set1_signature_value(X509_REQ *req, const uint8_t *sig, + size_t sig_len) { + if (!ASN1_STRING_set(req->signature, sig, sig_len)) { + return 0; + } + req->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + req->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x509spki.c b/third_party/boringssl/kit/src/crypto/x509/x509spki.c index 4a9b95e7..2b9b904e 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x509spki.c +++ b/third_party/boringssl/kit/src/crypto/x509/x509spki.c @@ -61,77 +61,73 @@ #include #include -int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (0); - return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) { + if ((x == NULL) || (x->spkac == NULL)) { + return 0; + } + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); } -EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (NULL); - return (X509_PUBKEY_get(x->spkac->pubkey)); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) { + if ((x == NULL) || (x->spkac == NULL)) { + return NULL; + } + return (X509_PUBKEY_get(x->spkac->pubkey)); } -/* Load a Netscape SPKI from a base64 encoded string */ +// Load a Netscape SPKI from a base64 encoded string -NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) -{ - unsigned char *spki_der; - const unsigned char *p; - size_t spki_len; - NETSCAPE_SPKI *spki; - if (len <= 0) - len = strlen(str); - if (!EVP_DecodedLength(&spki_len, len)) { - OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); - return NULL; - } - if (!(spki_der = OPENSSL_malloc(spki_len))) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (!EVP_DecodeBase64 - (spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) { - OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); - OPENSSL_free(spki_der); - return NULL; - } - p = spki_der; - spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, ossl_ssize_t len) { + unsigned char *spki_der; + const unsigned char *p; + size_t spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) { + len = strlen(str); + } + if (!EVP_DecodedLength(&spki_len, len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); + return NULL; + } + if (!(spki_der = OPENSSL_malloc(spki_len))) { + return NULL; + } + if (!EVP_DecodeBase64(spki_der, &spki_len, spki_len, (const uint8_t *)str, + len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); OPENSSL_free(spki_der); - return spki; + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + OPENSSL_free(spki_der); + return spki; } -/* Generate a base64 encoded string from an SPKI */ +// Generate a base64 encoded string from an SPKI -char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) -{ - unsigned char *der_spki, *p; - char *b64_str; - size_t b64_len; - int der_len; - der_len = i2d_NETSCAPE_SPKI(spki, NULL); - if (!EVP_EncodedLength(&b64_len, der_len)) { - OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); - return NULL; - } - der_spki = OPENSSL_malloc(der_len); - if (der_spki == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return NULL; - } - b64_str = OPENSSL_malloc(b64_len); - if (b64_str == NULL) { - OPENSSL_free(der_spki); - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return NULL; - } - p = der_spki; - i2d_NETSCAPE_SPKI(spki, &p); - EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) { + unsigned char *der_spki, *p; + char *b64_str; + size_t b64_len; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + if (!EVP_EncodedLength(&b64_len, der_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return NULL; + } + der_spki = OPENSSL_malloc(der_len); + if (der_spki == NULL) { + return NULL; + } + b64_str = OPENSSL_malloc(b64_len); + if (b64_str == NULL) { OPENSSL_free(der_spki); - return b64_str; + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + OPENSSL_free(der_spki); + return b64_str; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_algor.c b/third_party/boringssl/kit/src/crypto/x509/x_algor.c index a454c0cc..819aee5f 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_algor.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_algor.c @@ -65,89 +65,85 @@ ASN1_SEQUENCE(X509_ALGOR) = { - ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), - ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) + ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), + ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY), } ASN1_SEQUENCE_END(X509_ALGOR) -ASN1_ITEM_TEMPLATE(X509_ALGORS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) -ASN1_ITEM_TEMPLATE_END(X509_ALGORS) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_ALGOR) +IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_ALGOR) -IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) - -int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) -{ - if (!alg) - return 0; - if (ptype != V_ASN1_UNDEF) { - if (alg->parameter == NULL) - alg->parameter = ASN1_TYPE_new(); - if (alg->parameter == NULL) - return 0; +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) { + if (!alg) { + return 0; + } + if (ptype != V_ASN1_UNDEF) { + if (alg->parameter == NULL) { + alg->parameter = ASN1_TYPE_new(); } - if (alg) { - ASN1_OBJECT_free(alg->algorithm); - alg->algorithm = aobj; + if (alg->parameter == NULL) { + return 0; } - if (ptype == 0) - return 1; - if (ptype == V_ASN1_UNDEF) { - if (alg->parameter) { - ASN1_TYPE_free(alg->parameter); - alg->parameter = NULL; - } - } else - ASN1_TYPE_set(alg->parameter, ptype, pval); + } + if (alg) { + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = aobj; + } + if (ptype == 0) { return 1; + } + if (ptype == V_ASN1_UNDEF) { + if (alg->parameter) { + ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + } + } else { + ASN1_TYPE_set(alg->parameter, ptype, pval); + } + return 1; } void X509_ALGOR_get0(const ASN1_OBJECT **out_obj, int *out_param_type, - const void **out_param_value, const X509_ALGOR *alg) -{ - if (out_obj != NULL) { - *out_obj = alg->algorithm; + const void **out_param_value, const X509_ALGOR *alg) { + if (out_obj != NULL) { + *out_obj = alg->algorithm; + } + if (out_param_type != NULL) { + int type = V_ASN1_UNDEF; + const void *value = NULL; + if (alg->parameter != NULL) { + type = alg->parameter->type; + value = asn1_type_value_as_pointer(alg->parameter); } - if (out_param_type != NULL) { - int type = V_ASN1_UNDEF; - const void *value = NULL; - if (alg->parameter != NULL) { - type = alg->parameter->type; - value = asn1_type_value_as_pointer(alg->parameter); - } - *out_param_type = type; - if (out_param_value != NULL) { - *out_param_value = value; - } + *out_param_type = type; + if (out_param_value != NULL) { + *out_param_value = value; } + } } -/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ +// Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD -void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) -{ - int param_type; +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) { + int param_type; - if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) - param_type = V_ASN1_UNDEF; - else - param_type = V_ASN1_NULL; - - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) { + param_type = V_ASN1_UNDEF; + } else { + param_type = V_ASN1_NULL; + } + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); } -/* - * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. - */ -int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) -{ - int rv; - rv = OBJ_cmp(a->algorithm, b->algorithm); - if (rv) - return rv; - if (!a->parameter && !b->parameter) - return 0; - return ASN1_TYPE_cmp(a->parameter, b->parameter); +// X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) { + int rv; + rv = OBJ_cmp(a->algorithm, b->algorithm); + if (rv) { + return rv; + } + if (!a->parameter && !b->parameter) { + return 0; + } + return ASN1_TYPE_cmp(a->parameter, b->parameter); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_all.c b/third_party/boringssl/kit/src/crypto/x509/x_all.c index 7ceff504..6808ab78 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_all.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_all.c @@ -66,138 +66,100 @@ #include #include +#include "../asn1/internal.h" #include "internal.h" -int X509_verify(X509 *x509, EVP_PKEY *pkey) -{ - if (X509_ALGOR_cmp(x509->sig_alg, x509->cert_info->signature)) { - OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); - return 0; - } - return ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), x509->sig_alg, - x509->signature, x509->cert_info, pkey); +int X509_verify(X509 *x509, EVP_PKEY *pkey) { + if (X509_ALGOR_cmp(x509->sig_alg, x509->cert_info->signature)) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); + return 0; + } + return ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), x509->sig_alg, + x509->signature, x509->cert_info, pkey); } -int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) -{ - return ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), - req->sig_alg, req->signature, req->req_info, pkey); +int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { + return ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), req->sig_alg, + req->signature, req->req_info, pkey); } -int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->cert_info->enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, pkey, md)); +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) { + asn1_encoding_clear(&x->cert_info->enc); + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, pkey, md)); } -int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) -{ - x->cert_info->enc.modified = 1; - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), - x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, ctx); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) { + asn1_encoding_clear(&x->cert_info->enc); + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, ctx); } -int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, - x->signature, x->req_info, pkey, md)); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { + asn1_encoding_clear(&x->req_info->enc); + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, pkey, md)); } -int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) -{ - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), - x->sig_alg, NULL, x->signature, x->req_info, - ctx); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { + asn1_encoding_clear(&x->req_info->enc); + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, ctx); } -int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->crl->enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, - x->sig_alg, x->signature, x->crl, pkey, md)); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) { + asn1_encoding_clear(&x->crl->enc); + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); } -int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) -{ - x->crl->enc.modified = 1; - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), - x->crl->sig_alg, x->sig_alg, x->signature, - x->crl, ctx); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { + asn1_encoding_clear(&x->crl->enc); + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, ctx); } -int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, - x->signature, x->spkac, pkey, md)); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { + return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md)); } -int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) -{ - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, - spki->signature, spki->spkac, pkey)); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) { + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, + spki->signature, spki->spkac, pkey)); } -X509 *d2i_X509_fp(FILE *fp, X509 **x509) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); } -int i2d_X509_fp(FILE *fp, X509 *x509) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); } -X509 *d2i_X509_bio(BIO *bp, X509 **x509) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } -int i2d_X509_bio(BIO *bp, X509 *x509) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); } -X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); } -int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); } -X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); } -int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); -} - -X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -} - -int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -} - -X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); -} - -int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); } @@ -223,6 +185,9 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) return ret; \ } +IMPLEMENT_D2I_FP(X509, d2i_X509_fp, d2i_X509_bio); +IMPLEMENT_I2D_FP(X509, i2d_X509_fp, i2d_X509_bio); + IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio) IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio) @@ -257,6 +222,9 @@ IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio) return ret; \ } +IMPLEMENT_D2I_BIO(X509, d2i_X509_bio, d2i_X509) +IMPLEMENT_I2D_BIO(X509, i2d_X509_bio, i2d_X509) + IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey) IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey) @@ -266,7 +234,6 @@ IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey) IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY) IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY) -#ifndef OPENSSL_NO_DSA IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio) IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio) @@ -278,7 +245,6 @@ IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey) IMPLEMENT_D2I_BIO(DSA, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY) IMPLEMENT_I2D_BIO(DSA, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY) -#endif IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio) IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio) @@ -292,42 +258,46 @@ IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey) IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY) IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY) -int X509_pubkey_digest(const X509 *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - ASN1_BIT_STRING *key; - key = X509_get0_pubkey_bitstr(data); - if (!key) - return 0; - return EVP_Digest(key->data, key->length, md, len, type, NULL); +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) { + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) { + return 0; + } + return EVP_Digest(key->data, key->length, md, len, type, NULL); } -int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); +int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out, + unsigned *out_len) { + uint8_t *der = NULL; + // TODO(https://crbug.com/boringssl/407): This function is not const-correct. + int der_len = i2d_X509((X509 *)x509, &der); + if (der_len < 0) { + return 0; + } + + int ret = EVP_Digest(der, der_len, out, out_len, md, NULL); + OPENSSL_free(der); + return ret; } -int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) { + return ( + ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); } -int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) { + return ( + ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); } int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); + unsigned char *md, unsigned int *len) { + return ( + ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); } IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio) @@ -341,16 +311,16 @@ IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp, IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp, i2d_PKCS8_PRIV_KEY_INFO_bio) -int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) { + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) { + return 0; + } + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; } IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio) @@ -364,16 +334,16 @@ IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio, IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio, i2d_PKCS8_PRIV_KEY_INFO) -int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) { + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) { + return 0; + } + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; } IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey) diff --git a/third_party/boringssl/kit/src/crypto/x509/x_attrib.c b/third_party/boringssl/kit/src/crypto/x509/x_attrib.c index 91b3ee8f..14428b38 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_attrib.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_attrib.c @@ -56,43 +56,42 @@ #include #include -#include #include +#include #include "internal.h" ASN1_SEQUENCE(X509_ATTRIBUTE) = { - ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), - ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY), + ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), + ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY), } ASN1_SEQUENCE_END(X509_ATTRIBUTE) -IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_ATTRIBUTE) +IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_ATTRIBUTE) -X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int attrtype, void *value) -{ - ASN1_OBJECT *obj = OBJ_nid2obj(nid); - if (obj == NULL) { - return NULL; - } - - X509_ATTRIBUTE *ret = X509_ATTRIBUTE_new(); - ASN1_TYPE *val = ASN1_TYPE_new(); - if (ret == NULL || val == NULL) { - goto err; - } - - ret->object = obj; - if (!sk_ASN1_TYPE_push(ret->set, val)) { - goto err; - } - - ASN1_TYPE_set(val, attrtype, value); - return ret; - - err: - X509_ATTRIBUTE_free(ret); - ASN1_TYPE_free(val); +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int attrtype, void *value) { + ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { return NULL; + } + + X509_ATTRIBUTE *ret = X509_ATTRIBUTE_new(); + ASN1_TYPE *val = ASN1_TYPE_new(); + if (ret == NULL || val == NULL) { + goto err; + } + + ret->object = obj; + if (!sk_ASN1_TYPE_push(ret->set, val)) { + goto err; + } + + ASN1_TYPE_set(val, attrtype, value); + return ret; + +err: + X509_ATTRIBUTE_free(ret); + ASN1_TYPE_free(val); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_crl.c b/third_party/boringssl/kit/src/crypto/x509/x_crl.c index 0d419ac1..e140748c 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_crl.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_crl.c @@ -65,501 +65,414 @@ #include #include +#include + +#include "../asn1/internal.h" #include "../internal.h" #include "internal.h" -/* - * Method to handle CRL access. In general a CRL could be very large (several - * Mb) and can consume large amounts of resources if stored in memory by - * multiple processes. This method allows general CRL operations to be - * redirected to more efficient callbacks: for example a CRL entry database. - */ - -#define X509_CRL_METHOD_DYNAMIC 1 - -struct x509_crl_method_st { - int flags; - int (*crl_init) (X509_CRL *crl); - int (*crl_free) (X509_CRL *crl); - int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, - ASN1_INTEGER *ser, X509_NAME *issuer); - int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); -}; - -static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b); +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b); static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); ASN1_SEQUENCE(X509_REVOKED) = { - ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), - ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) + ASN1_SIMPLE(X509_REVOKED, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_REVOKED, revocationDate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_REVOKED, extensions, X509_EXTENSION), } ASN1_SEQUENCE_END(X509_REVOKED) -static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); -static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer); +static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer); -static const X509_CRL_METHOD int_crl_meth = { - 0, - 0, 0, - def_crl_lookup, - def_crl_verify -}; - -static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; - -/* - * The X509_CRL_INFO structure needs a bit of customisation. Since we cache - * the original encoding the signature wont be affected by reordering of the - * revoked field. - */ +// The X509_CRL_INFO structure needs a bit of customisation. Since we cache +// the original encoding the signature wont be affected by reordering of the +// revoked field. static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; + void *exarg) { + X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; - if (!a || !a->revoked) - return 1; - switch (operation) { - /* - * Just set cmp function here. We don't sort because that would - * affect the output of X509_CRL_print(). - */ - case ASN1_OP_D2I_POST: - /* TODO(davidben): Check that default |versions| are never encoded and - * that |extensions| is only present in v2. */ - - (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); - break; - } + if (!a || !a->revoked) { return 1; + } + switch (operation) { + // Just set cmp function here. We don't sort because that would + // affect the output of X509_CRL_print(). + case ASN1_OP_D2I_POST: + (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); + break; + } + return 1; } ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { - ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), - ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), - ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), - ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) + ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), + ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), + ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0), } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) -/* - * Set CRL entry issuer according to CRL certificate issuer extension. Check - * for unhandled critical CRL entry extensions. - */ +// Set CRL entry issuer according to CRL certificate issuer extension. Check +// for unhandled critical CRL entry extensions. -static int crl_set_issuers(X509_CRL *crl) -{ +static int crl_set_issuers(X509_CRL *crl) { + size_t i, k; + int j; + GENERAL_NAMES *gens, *gtmp; + STACK_OF(X509_REVOKED) *revoked; - size_t i, k; - int j; - GENERAL_NAMES *gens, *gtmp; - STACK_OF(X509_REVOKED) *revoked; - - revoked = X509_CRL_get_REVOKED(crl); - - gens = NULL; - for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { - X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); - STACK_OF(X509_EXTENSION) *exts; - ASN1_ENUMERATED *reason; - X509_EXTENSION *ext; - gtmp = X509_REVOKED_get_ext_d2i(rev, - NID_certificate_issuer, &j, NULL); - if (!gtmp && (j != -1)) { - crl->flags |= EXFLAG_INVALID; - return 1; - } - - if (gtmp) { - gens = gtmp; - if (!crl->issuers) { - crl->issuers = sk_GENERAL_NAMES_new_null(); - if (!crl->issuers) - return 0; - } - if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) - return 0; - } - rev->issuer = gens; - - reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); - if (!reason && (j != -1)) { - crl->flags |= EXFLAG_INVALID; - return 1; - } - - if (reason) { - rev->reason = ASN1_ENUMERATED_get(reason); - ASN1_ENUMERATED_free(reason); - } else - rev->reason = CRL_REASON_NONE; - - /* Check for critical CRL entry extensions */ - - exts = rev->extensions; - - for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { - ext = sk_X509_EXTENSION_value(exts, k); - if (X509_EXTENSION_get_critical(ext)) { - if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == - NID_certificate_issuer) - continue; - crl->flags |= EXFLAG_CRITICAL; - break; - } - } + revoked = X509_CRL_get_REVOKED(crl); + gens = NULL; + for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { + X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); + STACK_OF(X509_EXTENSION) *exts; + ASN1_ENUMERATED *reason; + X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL); + if (!gtmp && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; } - return 1; + if (gtmp) { + gens = gtmp; + if (!crl->issuers) { + crl->issuers = sk_GENERAL_NAMES_new_null(); + if (!crl->issuers) { + return 0; + } + } + if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) { + return 0; + } + } + rev->issuer = gens; + reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); + if (!reason && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (reason) { + rev->reason = ASN1_ENUMERATED_get(reason); + ASN1_ENUMERATED_free(reason); + } else { + rev->reason = CRL_REASON_NONE; + } + + // Check for critical CRL entry extensions + + exts = rev->extensions; + + for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { + ext = sk_X509_EXTENSION_value(exts, k); + if (X509_EXTENSION_get_critical(ext)) { + if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == + NID_certificate_issuer) { + continue; + } + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + } + + return 1; } -/* - * The X509_CRL structure needs a bit of customisation. Cache some extensions - * and hash of the whole CRL. - */ +// The X509_CRL structure needs a bit of customisation. Cache some extensions +// and hash of the whole CRL. static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_CRL *crl = (X509_CRL *)*pval; - STACK_OF(X509_EXTENSION) *exts; - X509_EXTENSION *ext; - size_t idx; - int i; + void *exarg) { + X509_CRL *crl = (X509_CRL *)*pval; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + size_t idx; + int i; - switch (operation) { + switch (operation) { case ASN1_OP_NEW_POST: - crl->idp = NULL; - crl->akid = NULL; - crl->flags = 0; - crl->idp_flags = 0; - crl->idp_reasons = CRLDP_ALL_REASONS; - crl->meth = default_crl_method; - crl->meth_data = NULL; - crl->issuers = NULL; - crl->crl_number = NULL; - crl->base_crl_number = NULL; - break; + crl->idp = NULL; + crl->akid = NULL; + crl->flags = 0; + crl->idp_flags = 0; + crl->idp_reasons = CRLDP_ALL_REASONS; + crl->issuers = NULL; + crl->crl_number = NULL; + crl->base_crl_number = NULL; + break; - case ASN1_OP_D2I_POST: - if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL)) { - return 0; + case ASN1_OP_D2I_POST: { + // The version must be one of v1(0) or v2(1). + long version = X509_CRL_VERSION_1; + if (crl->crl->version != NULL) { + version = ASN1_INTEGER_get(crl->crl->version); + // TODO(https://crbug.com/boringssl/364): |X509_CRL_VERSION_1| + // should also be rejected. This means an explicitly-encoded X.509v1 + // version. v1 is DEFAULT, so DER requires it be omitted. + if (version < X509_CRL_VERSION_1 || version > X509_CRL_VERSION_2) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; } + } - crl->idp = X509_CRL_get_ext_d2i(crl, - NID_issuing_distribution_point, &i, - NULL); - if (crl->idp != NULL) { - if (!setup_idp(crl, crl->idp)) { - return 0; - } - } else if (i != -1) { - return 0; + // Per RFC 5280, section 5.1.2.1, extensions require v2. + if (version != X509_CRL_VERSION_2 && crl->crl->extensions != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + return 0; + } + + if (!X509_CRL_digest(crl, EVP_sha256(), crl->crl_hash, NULL)) { + return 0; + } + + crl->idp = + X509_CRL_get_ext_d2i(crl, NID_issuing_distribution_point, &i, NULL); + if (crl->idp != NULL) { + if (!setup_idp(crl, crl->idp)) { + return 0; } + } else if (i != -1) { + return 0; + } - crl->akid = X509_CRL_get_ext_d2i(crl, - NID_authority_key_identifier, &i, - NULL); - if (crl->akid == NULL && i != -1) { - return 0; + crl->akid = + X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, &i, NULL); + if (crl->akid == NULL && i != -1) { + return 0; + } + + crl->crl_number = X509_CRL_get_ext_d2i(crl, NID_crl_number, &i, NULL); + if (crl->crl_number == NULL && i != -1) { + return 0; + } + + crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, &i, NULL); + if (crl->base_crl_number == NULL && i != -1) { + return 0; + } + // Delta CRLs must have CRL number + if (crl->base_crl_number && !crl->crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER); + return 0; + } + + // See if we have any unhandled critical CRL extensions and indicate + // this in a flag. We only currently handle IDP so anything else + // critical sets the flag. This code accesses the X509_CRL structure + // directly: applications shouldn't do this. + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { + int nid; + ext = sk_X509_EXTENSION_value(exts, idx); + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + if (nid == NID_freshest_crl) { + crl->flags |= EXFLAG_FRESHEST; } - - crl->crl_number = X509_CRL_get_ext_d2i(crl, - NID_crl_number, &i, NULL); - if (crl->crl_number == NULL && i != -1) { - return 0; + if (X509_EXTENSION_get_critical(ext)) { + // We handle IDP and deltas + if ((nid == NID_issuing_distribution_point) || + (nid == NID_authority_key_identifier) || (nid == NID_delta_crl)) { + continue; + } + crl->flags |= EXFLAG_CRITICAL; + break; } + } - crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, &i, - NULL); - if (crl->base_crl_number == NULL && i != -1) { - return 0; - } - /* Delta CRLs must have CRL number */ - if (crl->base_crl_number && !crl->crl_number) { - OPENSSL_PUT_ERROR(X509, X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER); - return 0; - } + if (!crl_set_issuers(crl)) { + return 0; + } - /* - * See if we have any unhandled critical CRL extensions and indicate - * this in a flag. We only currently handle IDP so anything else - * critical sets the flag. This code accesses the X509_CRL structure - * directly: applications shouldn't do this. - */ - - exts = crl->crl->extensions; - - for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { - int nid; - ext = sk_X509_EXTENSION_value(exts, idx); - nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); - if (nid == NID_freshest_crl) - crl->flags |= EXFLAG_FRESHEST; - if (X509_EXTENSION_get_critical(ext)) { - /* We handle IDP and deltas */ - if ((nid == NID_issuing_distribution_point) - || (nid == NID_authority_key_identifier) - || (nid == NID_delta_crl)) - continue; - crl->flags |= EXFLAG_CRITICAL; - break; - } - } - - if (!crl_set_issuers(crl)) - return 0; - - if (crl->meth->crl_init) { - if (crl->meth->crl_init(crl) == 0) - return 0; - } - break; + break; + } case ASN1_OP_FREE_POST: - /* |crl->meth| may be NULL if constructing the object failed before - * |ASN1_OP_NEW_POST| was run. */ - if (crl->meth && crl->meth->crl_free) { - if (!crl->meth->crl_free(crl)) - return 0; - } - if (crl->akid) - AUTHORITY_KEYID_free(crl->akid); - if (crl->idp) - ISSUING_DIST_POINT_free(crl->idp); - ASN1_INTEGER_free(crl->crl_number); - ASN1_INTEGER_free(crl->base_crl_number); - sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); - break; - } - return 1; + AUTHORITY_KEYID_free(crl->akid); + ISSUING_DIST_POINT_free(crl->idp); + ASN1_INTEGER_free(crl->crl_number); + ASN1_INTEGER_free(crl->base_crl_number); + sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + break; + } + return 1; } -/* Convert IDP into a more convenient form */ +// Convert IDP into a more convenient form -static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) -{ - int idp_only = 0; - /* Set various flags according to IDP */ - crl->idp_flags |= IDP_PRESENT; - if (idp->onlyuser > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYUSER; +static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) { + int idp_only = 0; + // Set various flags according to IDP + crl->idp_flags |= IDP_PRESENT; + if (idp->onlyuser > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYUSER; + } + if (idp->onlyCA > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYCA; + } + if (idp->onlyattr > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYATTR; + } + + if (idp_only > 1) { + crl->idp_flags |= IDP_INVALID; + } + + if (idp->indirectCRL > 0) { + crl->idp_flags |= IDP_INDIRECT; + } + + if (idp->onlysomereasons) { + crl->idp_flags |= IDP_REASONS; + if (idp->onlysomereasons->length > 0) { + crl->idp_reasons = idp->onlysomereasons->data[0]; } - if (idp->onlyCA > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYCA; - } - if (idp->onlyattr > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYATTR; + if (idp->onlysomereasons->length > 1) { + crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); } + crl->idp_reasons &= CRLDP_ALL_REASONS; + } - if (idp_only > 1) - crl->idp_flags |= IDP_INVALID; - - if (idp->indirectCRL > 0) - crl->idp_flags |= IDP_INDIRECT; - - if (idp->onlysomereasons) { - crl->idp_flags |= IDP_REASONS; - if (idp->onlysomereasons->length > 0) - crl->idp_reasons = idp->onlysomereasons->data[0]; - if (idp->onlysomereasons->length > 1) - crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); - crl->idp_reasons &= CRLDP_ALL_REASONS; - } - - return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); + return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); } ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = { - ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), - ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) + ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), + ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING), } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) -IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) +// Although |X509_REVOKED| contains an |X509_NAME|, it can be const. It is not +// affected by https://crbug.com/boringssl/407 because the |X509_NAME| does +// not participate in serialization. +IMPLEMENT_ASN1_FUNCTIONS_const(X509_REVOKED) +IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_REVOKED) IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) -static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b) -{ - return ASN1_STRING_cmp((*a)->serialNumber, (*b)->serialNumber); +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b) { + return ASN1_STRING_cmp((*a)->serialNumber, (*b)->serialNumber); } -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) -{ - X509_CRL_INFO *inf; - inf = crl->crl; - if (!inf->revoked) - inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); - if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return 0; - } - inf->enc.modified = 1; - return 1; -} - -int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey) -{ - if (crl->meth->crl_verify) - return crl->meth->crl_verify(crl, pkey); +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) { + X509_CRL_INFO *inf; + inf = crl->crl; + if (!inf->revoked) { + inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); + } + if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { return 0; + } + asn1_encoding_clear(&inf->enc); + return 1; } -int X509_CRL_get0_by_serial(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial) -{ - if (crl->meth->crl_lookup) - return crl->meth->crl_lookup(crl, ret, serial, NULL); +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey) { + if (X509_ALGOR_cmp(crl->sig_alg, crl->crl->sig_alg) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); return 0; + } + + return ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), crl->sig_alg, + crl->signature, crl->crl, pkey); } -int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) -{ - if (crl->meth->crl_lookup) - return crl->meth->crl_lookup(crl, ret, - X509_get_serialNumber(x), - X509_get_issuer_name(x)); - return 0; +int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *serial) { + return crl_lookup(crl, ret, serial, NULL); } -static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) -{ - if (X509_ALGOR_cmp(crl->sig_alg, crl->crl->sig_alg) != 0) { - OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); - return 0; - } - - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), - crl->sig_alg, crl->signature, crl->crl, r)); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) { + return crl_lookup(crl, ret, X509_get_serialNumber(x), + X509_get_issuer_name(x)); } static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, - X509_REVOKED *rev) -{ - size_t i; + X509_REVOKED *rev) { + size_t i; - if (!rev->issuer) { - if (!nm) - return 1; - if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) - return 1; - return 0; + if (!rev->issuer) { + if (!nm) { + return 1; } - - if (!nm) - nm = X509_CRL_get_issuer(crl); - - for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); - if (gen->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(nm, gen->d.directoryName)) - return 1; + if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) { + return 1; } return 0; + } + if (!nm) { + nm = X509_CRL_get_issuer(crl); + } + + for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); + if (gen->type != GEN_DIRNAME) { + continue; + } + if (!X509_NAME_cmp(nm, gen->d.directoryName)) { + return 1; + } + } + return 0; } -static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT; +static CRYPTO_MUTEX g_crl_sort_lock = CRYPTO_MUTEX_INIT; -static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer) -{ - X509_REVOKED rtmp, *rev; - size_t idx; - rtmp.serialNumber = serial; - /* - * Sort revoked into serial number order if not already sorted. Do this - * under a lock to avoid race condition. - */ +static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) { + // Use an assert, rather than a runtime error, because returning nothing for a + // CRL is arguably failing open, rather than closed. + assert(serial->type == V_ASN1_INTEGER || serial->type == V_ASN1_NEG_INTEGER); + X509_REVOKED rtmp, *rev; + size_t idx; + rtmp.serialNumber = serial; + // Sort revoked into serial number order if not already sorted. Do this + // under a lock to avoid race condition. - CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock); - const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); - CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock); + CRYPTO_MUTEX_lock_read(&g_crl_sort_lock); + const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); + CRYPTO_MUTEX_unlock_read(&g_crl_sort_lock); - if (!is_sorted) { - CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock); - if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { - sk_X509_REVOKED_sort(crl->crl->revoked); - } - CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock); + if (!is_sorted) { + CRYPTO_MUTEX_lock_write(&g_crl_sort_lock); + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + sk_X509_REVOKED_sort(crl->crl->revoked); } + CRYPTO_MUTEX_unlock_write(&g_crl_sort_lock); + } - if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) - return 0; - /* Need to look for matching name */ - for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { - rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); - if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) - return 0; - if (crl_revoked_issuer_match(crl, issuer, rev)) { - if (ret) - *ret = rev; - if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) - return 2; - return 1; - } - } + if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) { return 0; -} - -void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) -{ - if (meth == NULL) - default_crl_method = &int_crl_meth; - else - default_crl_method = meth; -} - -X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), - int (*crl_free) (X509_CRL *crl), - int (*crl_lookup) (X509_CRL *crl, - X509_REVOKED **ret, - ASN1_INTEGER *ser, - X509_NAME *issuer), - int (*crl_verify) (X509_CRL *crl, - EVP_PKEY *pk)) -{ - X509_CRL_METHOD *m; - m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); - if (!m) - return NULL; - m->crl_init = crl_init; - m->crl_free = crl_free; - m->crl_lookup = crl_lookup; - m->crl_verify = crl_verify; - m->flags = X509_CRL_METHOD_DYNAMIC; - return m; -} - -void X509_CRL_METHOD_free(X509_CRL_METHOD *m) -{ - if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) - return; - OPENSSL_free(m); -} - -void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) -{ - crl->meth_data = dat; -} - -void *X509_CRL_get_meth_data(X509_CRL *crl) -{ - return crl->meth_data; + } + // Need to look for matching name + for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { + rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); + if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) { + return 0; + } + if (crl_revoked_issuer_match(crl, issuer, rev)) { + if (ret) { + *ret = rev; + } + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) { + return 2; + } + return 1; + } + } + return 0; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_exten.c b/third_party/boringssl/kit/src/crypto/x509/x_exten.c index 89998ca1..e181d982 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_exten.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_exten.c @@ -63,15 +63,16 @@ ASN1_SEQUENCE(X509_EXTENSION) = { - ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), - ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), - ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) + ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), + ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), + ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING), } ASN1_SEQUENCE_END(X509_EXTENSION) ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) -IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_EXTENSION) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(X509_EXTENSIONS, X509_EXTENSIONS, + X509_EXTENSIONS) +IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_EXTENSION) diff --git a/third_party/boringssl/kit/src/crypto/x509/x_info.c b/third_party/boringssl/kit/src/crypto/x509/x_info.c index 177cd0eb..0f074f61 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_info.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_info.c @@ -61,38 +61,40 @@ #include #include -X509_INFO *X509_INFO_new(void) -{ - X509_INFO *ret = NULL; +X509_INFO *X509_INFO_new(void) { + X509_INFO *ret = NULL; - ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); - if (ret == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - return (NULL); - } + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + return NULL; + } - ret->enc_cipher.cipher = NULL; - ret->enc_len = 0; - ret->enc_data = NULL; + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; - ret->x509 = NULL; - ret->crl = NULL; - ret->x_pkey = NULL; - return (ret); + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return ret; } -void X509_INFO_free(X509_INFO *x) -{ - if (x == NULL) - return; +void X509_INFO_free(X509_INFO *x) { + if (x == NULL) { + return; + } - if (x->x509 != NULL) - X509_free(x->x509); - if (x->crl != NULL) - X509_CRL_free(x->crl); - if (x->x_pkey != NULL) - X509_PKEY_free(x->x_pkey); - if (x->enc_data != NULL) - OPENSSL_free(x->enc_data); - OPENSSL_free(x); + if (x->x509 != NULL) { + X509_free(x->x509); + } + if (x->crl != NULL) { + X509_CRL_free(x->crl); + } + if (x->x_pkey != NULL) { + X509_PKEY_free(x->x_pkey); + } + if (x->enc_data != NULL) { + OPENSSL_free(x->enc_data); + } + OPENSSL_free(x); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_name.c b/third_party/boringssl/kit/src/crypto/x509/x_name.c index 4fea082c..3063ce7b 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_name.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_name.c @@ -74,65 +74,57 @@ typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) -/* - * Maximum length of X509_NAME: much larger than anything we should - * ever see in practice. - */ +// Maximum length of X509_NAME: much larger than anything we should +// ever see in practice. #define X509_NAME_MAX (1024 * 1024) -static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); +static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it, int opt, + ASN1_TLC *ctx); static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); + const ASN1_ITEM *it); static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); static int x509_name_encode(X509_NAME *a); static int x509_name_canon(X509_NAME *a); static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, unsigned char **in); ASN1_SEQUENCE(X509_NAME_ENTRY) = { - ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), - ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) + ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), + ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE), } ASN1_SEQUENCE_END(X509_NAME_ENTRY) -IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_NAME_ENTRY) +IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_NAME_ENTRY) -/* - * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so - * declare two template wrappers for this - */ +// For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so +// declare two template wrappers for this -ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) +ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, + 0, RDNS, + X509_NAME_ENTRY) ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) -/* - * Normally that's where it would end: we'd have two nested STACK structures - * representing the ASN1. Unfortunately X509_NAME uses a completely different - * form and caches encodings so we have to process the internal form and - * convert to the external form. - */ +// Normally that's where it would end: we'd have two nested STACK structures +// representing the ASN1. Unfortunately X509_NAME uses a completely different +// form and caches encodings so we have to process the internal form and +// convert to the external form. static const ASN1_EXTERN_FUNCS x509_name_ff = { - NULL, x509_name_ex_new, x509_name_ex_free, - 0, /* Default clear behaviour is OK */ + 0, // Default clear behaviour is OK x509_name_ex_d2i, x509_name_ex_i2d, - NULL, }; IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) @@ -141,404 +133,396 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) -static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) -{ - X509_NAME *ret = NULL; - ret = OPENSSL_malloc(sizeof(X509_NAME)); - if (!ret) - goto memerr; - if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) - goto memerr; - if ((ret->bytes = BUF_MEM_new()) == NULL) - goto memerr; - ret->canon_enc = NULL; - ret->canon_enclen = 0; - ret->modified = 1; - *val = (ASN1_VALUE *)ret; - return 1; +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { + X509_NAME *ret = NULL; + ret = OPENSSL_malloc(sizeof(X509_NAME)); + if (!ret) { + goto memerr; + } + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) { + goto memerr; + } + if ((ret->bytes = BUF_MEM_new()) == NULL) { + goto memerr; + } + ret->canon_enc = NULL; + ret->canon_enclen = 0; + ret->modified = 1; + *val = (ASN1_VALUE *)ret; + return 1; - memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - if (ret) { - if (ret->entries) - sk_X509_NAME_ENTRY_free(ret->entries); - OPENSSL_free(ret); +memerr: + if (ret) { + if (ret->entries) { + sk_X509_NAME_ENTRY_free(ret->entries); } - return 0; + OPENSSL_free(ret); + } + return 0; } -static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - X509_NAME *a; - if (!pval || !*pval) - return; - a = (X509_NAME *)*pval; +static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { + X509_NAME *a; + if (!pval || !*pval) { + return; + } + a = (X509_NAME *)*pval; - BUF_MEM_free(a->bytes); - sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); - if (a->canon_enc) - OPENSSL_free(a->canon_enc); - OPENSSL_free(a); - *pval = NULL; + BUF_MEM_free(a->bytes); + sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + } + OPENSSL_free(a); + *pval = NULL; } -static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_free(ne); +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) { + sk_X509_NAME_ENTRY_free(ne); } -static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) { + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); } -static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, - char opt, ASN1_TLC *ctx) -{ - const unsigned char *p = *in, *q; - STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; - X509_NAME *nm = NULL; - size_t i, j; - int ret; - STACK_OF(X509_NAME_ENTRY) *entries; - X509_NAME_ENTRY *entry; - /* Bound the size of an X509_NAME we are willing to parse. */ - if (len > X509_NAME_MAX) { - len = X509_NAME_MAX; - } - q = p; +static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it, int opt, + ASN1_TLC *ctx) { + const unsigned char *p = *in, *q; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + X509_NAME *nm = NULL; + size_t i, j; + int ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + // Bound the size of an X509_NAME we are willing to parse. + if (len > X509_NAME_MAX) { + len = X509_NAME_MAX; + } + q = p; - /* Get internal representation of Name */ - ASN1_VALUE *intname_val = NULL; - ret = ASN1_item_ex_d2i(&intname_val, - &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), - tag, aclass, opt, ctx); - if (ret <= 0) - return ret; - intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val; - - if (*val) - x509_name_ex_free(val, NULL); - ASN1_VALUE *nm_val = NULL; - if (!x509_name_ex_new(&nm_val, NULL)) - goto err; - nm = (X509_NAME *)nm_val; - /* We've decoded it: now cache encoding */ - if (!BUF_MEM_grow(nm->bytes, p - q)) - goto err; - OPENSSL_memcpy(nm->bytes->data, q, p - q); - - /* Convert internal representation to X509_NAME structure */ - for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname); i++) { - entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname, i); - for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { - entry = sk_X509_NAME_ENTRY_value(entries, j); - entry->set = i; - if (!sk_X509_NAME_ENTRY_push(nm->entries, entry)) - goto err; - (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); - } - } - ret = x509_name_canon(nm); - if (!ret) - goto err; - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_free); - nm->modified = 0; - *val = (ASN1_VALUE *)nm; - *in = p; + // Get internal representation of Name + ASN1_VALUE *intname_val = NULL; + ret = ASN1_item_ex_d2i(&intname_val, &p, len, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, + /*aclass=*/0, opt, /*buf=*/NULL); + if (ret <= 0) { return ret; - err: - X509_NAME_free(nm); - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_pop_free); - OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); - return 0; + } + intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val; + + if (*val) { + x509_name_ex_free(val, NULL); + } + ASN1_VALUE *nm_val = NULL; + if (!x509_name_ex_new(&nm_val, NULL)) { + goto err; + } + nm = (X509_NAME *)nm_val; + // We've decoded it: now cache encoding + if (!BUF_MEM_grow(nm->bytes, p - q)) { + goto err; + } + OPENSSL_memcpy(nm->bytes->data, q, p - q); + + // Convert internal representation to X509_NAME structure + for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname, i); + for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { + entry = sk_X509_NAME_ENTRY_value(entries, j); + entry->set = (int)i; + if (!sk_X509_NAME_ENTRY_push(nm->entries, entry)) { + goto err; + } + (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); + } + } + ret = x509_name_canon(nm); + if (!ret) { + goto err; + } + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); + nm->modified = 0; + *val = (ASN1_VALUE *)nm; + *in = p; + return ret; +err: + X509_NAME_free(nm); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + return 0; } static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) -{ - X509_NAME *a = (X509_NAME *)*val; - if (a->modified && - (!x509_name_encode(a) || - !x509_name_canon(a))) { - return -1; - } - int ret = a->bytes->length; - if (out != NULL) { - OPENSSL_memcpy(*out, a->bytes->data, ret); - *out += ret; - } - return ret; + const ASN1_ITEM *it) { + X509_NAME *a = (X509_NAME *)*val; + if (a->modified && (!x509_name_encode(a) || !x509_name_canon(a))) { + return -1; + } + int ret = a->bytes->length; + if (out != NULL) { + OPENSSL_memcpy(*out, a->bytes->data, ret); + *out += ret; + } + return ret; } -static int x509_name_encode(X509_NAME *a) -{ - int len; - unsigned char *p; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry; - int set = -1; - size_t i; - STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = - sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if (!intname) - goto memerr; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if (entry->set != set) { - entries = sk_X509_NAME_ENTRY_new_null(); - if (!entries) - goto memerr; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { - sk_X509_NAME_ENTRY_free(entries); - goto memerr; - } - set = entry->set; - } - if (!sk_X509_NAME_ENTRY_push(entries, entry)) - goto memerr; +static int x509_name_encode(X509_NAME *a) { + int len; + unsigned char *p; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry; + int set = -1; + size_t i; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = + sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) { + goto err; + } + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) { + goto err; + } + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto err; + } + set = entry->set; } - ASN1_VALUE *intname_val = (ASN1_VALUE *)intname; - len = - ASN1_item_ex_i2d(&intname_val, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), - /*tag=*/-1, /*aclass=*/0); - if (len <= 0) { + if (!sk_X509_NAME_ENTRY_push(entries, entry)) { goto err; } - if (!BUF_MEM_grow(a->bytes, len)) - goto memerr; - p = (unsigned char *)a->bytes->data; - if (ASN1_item_ex_i2d(&intname_val, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), - /*tag=*/-1, /*aclass=*/0) <= 0) { - goto err; - } - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_free); - a->modified = 0; - return 1; - memerr: - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + } + ASN1_VALUE *intname_val = (ASN1_VALUE *)intname; + len = ASN1_item_ex_i2d(&intname_val, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + /*tag=*/-1, /*aclass=*/0); + if (len <= 0) { + goto err; + } + if (!BUF_MEM_grow(a->bytes, len)) { + goto err; + } + p = (unsigned char *)a->bytes->data; + if (ASN1_item_ex_i2d(&intname_val, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + /*tag=*/-1, /*aclass=*/0) <= 0) { + goto err; + } + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); + a->modified = 0; + return 1; err: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); + return 0; +} + +// This function generates the canonical encoding of the Name structure. In +// it all strings are converted to UTF8, leading, trailing and multiple +// spaces collapsed, converted to lower case and the leading SEQUENCE header +// removed. In future we could also normalize the UTF8 too. By doing this +// comparison of Name structures can be rapidly perfomed by just using +// OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE +// name constraints of type dirName can also be checked with a simple +// OPENSSL_memcmp(). + +static int x509_name_canon(X509_NAME *a) { + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int set = -1, ret = 0, len; + size_t i; + + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + // Special case: empty X509_NAME => null encoding + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) { + goto err; + } + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) { + goto err; + } + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto err; + } + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + if (tmpentry == NULL) { + goto err; + } + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) { + goto err; + } + if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) { + goto err; + } + tmpentry = NULL; + } + + // Finally generate encoding + + len = i2d_name_canon(intname, NULL); + if (len < 0) { + goto err; + } + a->canon_enclen = len; + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) { + goto err; + } + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + +err: + + if (tmpentry) { + X509_NAME_ENTRY_free(tmpentry); + } + if (intname) { sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_free); + local_sk_X509_NAME_ENTRY_pop_free); + } + return ret; +} + +// Bitmap of all the types of string that will be canonicalized. + +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING | \ + B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING | \ + B_ASN1_VISIBLESTRING) + +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) { + unsigned char *to, *from; + int len, i; + + // If type not in bitmask just copy string across + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { + if (!ASN1_STRING_copy(out, in)) { + return 0; + } + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) { return 0; -} + } -/* - * This function generates the canonical encoding of the Name structure. In - * it all strings are converted to UTF8, leading, trailing and multiple - * spaces collapsed, converted to lower case and the leading SEQUENCE header - * removed. In future we could also normalize the UTF8 too. By doing this - * comparison of Name structures can be rapidly perfomed by just using - * OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE name - * constraints of type dirName can also be checked with a simple OPENSSL_memcmp(). - */ + to = out->data; + from = to; -static int x509_name_canon(X509_NAME *a) -{ - unsigned char *p; - STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry, *tmpentry = NULL; - int set = -1, ret = 0, len; - size_t i; + len = out->length; - if (a->canon_enc) { - OPENSSL_free(a->canon_enc); - a->canon_enc = NULL; - } - /* Special case: empty X509_NAME => null encoding */ - if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { - a->canon_enclen = 0; - return 1; - } - intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if (!intname) - goto err; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if (entry->set != set) { - entries = sk_X509_NAME_ENTRY_new_null(); - if (!entries) - goto err; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { - sk_X509_NAME_ENTRY_free(entries); - goto err; - } - set = entry->set; - } - tmpentry = X509_NAME_ENTRY_new(); - if (tmpentry == NULL) - goto err; - tmpentry->object = OBJ_dup(entry->object); - if (!asn1_string_canon(tmpentry->value, entry->value)) - goto err; - if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) - goto err; - tmpentry = NULL; - } + // Convert string in place to canonical form. - /* Finally generate encoding */ + // Ignore leading spaces + while ((len > 0) && OPENSSL_isspace(*from)) { + from++; + len--; + } - len = i2d_name_canon(intname, NULL); - if (len < 0) { - goto err; - } - a->canon_enclen = len; + to = from + len; - p = OPENSSL_malloc(a->canon_enclen); + // Ignore trailing spaces + while ((len > 0) && OPENSSL_isspace(to[-1])) { + to--; + len--; + } - if (!p) - goto err; + to = out->data; - a->canon_enc = p; - - i2d_name_canon(intname, &p); - - ret = 1; - - err: - - if (tmpentry) - X509_NAME_ENTRY_free(tmpentry); - if (intname) - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_pop_free); - return ret; -} - -/* Bitmap of all the types of string that will be canonicalized. */ - -#define ASN1_MASK_CANON \ - (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ - | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ - | B_ASN1_VISIBLESTRING) - -static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) -{ - unsigned char *to, *from; - int len, i; - - /* If type not in bitmask just copy string across */ - if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { - if (!ASN1_STRING_copy(out, in)) - return 0; - return 1; - } - - out->type = V_ASN1_UTF8STRING; - out->length = ASN1_STRING_to_UTF8(&out->data, in); - if (out->length == -1) - return 0; - - to = out->data; - from = to; - - len = out->length; - - /* - * Convert string in place to canonical form. Ultimately we may need to - * handle a wider range of characters but for now ignore anything with - * MSB set and rely on the isspace() and tolower() functions. - */ - - /* Ignore leading spaces */ - while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + i = 0; + while (i < len) { + // Collapse multiple spaces + if (OPENSSL_isspace(*from)) { + // Copy one space across + *to++ = ' '; + // Ignore subsequent spaces. Note: don't need to check len here + // because we know the last character is a non-space so we can't + // overflow. + do { from++; - len--; + i++; + } while (OPENSSL_isspace(*from)); + } else { + *to++ = OPENSSL_tolower(*from); + from++; + i++; } + } - to = from + len; - - /* Ignore trailing spaces */ - while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { - to--; - len--; - } - - to = out->data; - - i = 0; - while (i < len) { - /* If MSB set just copy across */ - if (*from & 0x80) { - *to++ = *from++; - i++; - } - /* Collapse multiple spaces */ - else if (isspace(*from)) { - /* Copy one space across */ - *to++ = ' '; - /* - * Ignore subsequent spaces. Note: don't need to check len here - * because we know the last character is a non-space so we can't - * overflow. - */ - do { - from++; - i++; - } - while (!(*from & 0x80) && isspace(*from)); - } else { - *to++ = OPENSSL_tolower(*from); - from++; - i++; - } - } - - out->length = to - out->data; - - return 1; + out->length = to - out->data; + return 1; } -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, - unsigned char **in) -{ - int len, ltmp; - size_t i; - ASN1_VALUE *v; - STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, + unsigned char **in) { + int len, ltmp; + size_t i; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; - len = 0; - for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { - v = sk_ASN1_VALUE_value(intname, i); - ltmp = ASN1_item_ex_i2d(&v, in, ASN1_ITEM_rptr(X509_NAME_ENTRIES), - /*tag=*/-1, /*aclass=*/0); - if (ltmp < 0) - return ltmp; - len += ltmp; + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, ASN1_ITEM_rptr(X509_NAME_ENTRIES), + /*tag=*/-1, /*aclass=*/0); + if (ltmp < 0) { + return ltmp; } - return len; + len += ltmp; + } + return len; } -int X509_NAME_set(X509_NAME **xn, X509_NAME *name) -{ - if ((name = X509_NAME_dup(name)) == NULL) - return 0; - X509_NAME_free(*xn); - *xn = name; - return 1; +int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { + if ((name = X509_NAME_dup(name)) == NULL) { + return 0; + } + X509_NAME_free(*xn); + *xn = name; + return 1; } -int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) -{ - return ne->set; -} +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) { return ne->set; } int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, - size_t *pderlen) -{ - /* Make sure encoding is valid */ - if (i2d_X509_NAME(nm, NULL) <= 0) - return 0; - if (pder != NULL) - *pder = (unsigned char *)nm->bytes->data; - if (pderlen != NULL) - *pderlen = nm->bytes->length; - return 1; + size_t *pderlen) { + // Make sure encoding is valid + if (i2d_X509_NAME(nm, NULL) <= 0) { + return 0; + } + if (pder != NULL) { + *pder = (unsigned char *)nm->bytes->data; + } + if (pderlen != NULL) { + *pderlen = nm->bytes->length; + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_pkey.c b/third_party/boringssl/kit/src/crypto/x509/x_pkey.c index e562d730..d48ecd11 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_pkey.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_pkey.c @@ -66,41 +66,46 @@ #include "../internal.h" -X509_PKEY *X509_PKEY_new(void) -{ - X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY)); - if (ret == NULL) { - OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); +X509_PKEY *X509_PKEY_new(void) { + X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + goto err; + } + OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); - ret->enc_algor = X509_ALGOR_new(); - if (ret->enc_algor == NULL) - goto err; - ret->enc_pkey = ASN1_OCTET_STRING_new(); - if (ret->enc_pkey == NULL) - goto err; - return ret; + ret->enc_algor = X509_ALGOR_new(); + if (ret->enc_algor == NULL) { + goto err; + } + ret->enc_pkey = ASN1_OCTET_STRING_new(); + if (ret->enc_pkey == NULL) { + goto err; + } + return ret; - err: - if (ret != NULL) - X509_PKEY_free(ret); - return NULL; +err: + if (ret != NULL) { + X509_PKEY_free(ret); + } + return NULL; } -void X509_PKEY_free(X509_PKEY *x) -{ - if (x == NULL) - return; +void X509_PKEY_free(X509_PKEY *x) { + if (x == NULL) { + return; + } - if (x->enc_algor != NULL) - X509_ALGOR_free(x->enc_algor); - if (x->enc_pkey != NULL) - ASN1_OCTET_STRING_free(x->enc_pkey); - if (x->dec_pkey != NULL) - EVP_PKEY_free(x->dec_pkey); - if ((x->key_data != NULL) && (x->key_free)) - OPENSSL_free(x->key_data); - OPENSSL_free(x); + if (x->enc_algor != NULL) { + X509_ALGOR_free(x->enc_algor); + } + if (x->enc_pkey != NULL) { + ASN1_OCTET_STRING_free(x->enc_pkey); + } + if (x->dec_pkey != NULL) { + EVP_PKEY_free(x->dec_pkey); + } + if ((x->key_data != NULL) && (x->key_free)) { + OPENSSL_free(x->key_data); + } + OPENSSL_free(x); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_pubkey.c b/third_party/boringssl/kit/src/crypto/x509/x_pubkey.c index c283e0db..cd0cfefa 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_pubkey.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_pubkey.c @@ -70,148 +70,145 @@ #include "../internal.h" #include "internal.h" -/* Minor tweak to operation: free up EVP_PKEY */ +// Minor tweak to operation: free up EVP_PKEY static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_POST) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - EVP_PKEY_free(pubkey->pkey); - } - return 1; + void *exarg) { + if (operation == ASN1_OP_FREE_POST) { + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + } + return 1; } ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { - ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), - ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) + ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), + ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING), } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) -IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_PUBKEY) -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) -{ - X509_PUBKEY *pk = NULL; - uint8_t *spki = NULL; - size_t spki_len; +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { + X509_PUBKEY *pk = NULL; + uint8_t *spki = NULL; + size_t spki_len; - if (x == NULL) - return (0); - - CBB cbb; - if (!CBB_init(&cbb, 0) || - !EVP_marshal_public_key(&cbb, pkey) || - !CBB_finish(&cbb, &spki, &spki_len) || - spki_len > LONG_MAX) { - CBB_cleanup(&cbb); - OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); - goto error; - } - - const uint8_t *p = spki; - pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); - if (pk == NULL || p != spki + spki_len) { - OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); - goto error; - } - - OPENSSL_free(spki); - X509_PUBKEY_free(*x); - *x = pk; - - return 1; - error: - X509_PUBKEY_free(pk); - OPENSSL_free(spki); + if (x == NULL) { return 0; + } + + CBB cbb; + if (!CBB_init(&cbb, 0) || // + !EVP_marshal_public_key(&cbb, pkey) || + !CBB_finish(&cbb, &spki, &spki_len) || // + spki_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + + const uint8_t *p = spki; + pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); + if (pk == NULL || p != spki + spki_len) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + OPENSSL_free(spki); + X509_PUBKEY_free(*x); + *x = pk; + + return 1; +error: + X509_PUBKEY_free(pk); + OPENSSL_free(spki); + return 0; } -/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of - * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| - * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is - * not. */ -static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; +// g_pubkey_lock is used to protect the initialisation of the |pkey| member of +// |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| +// inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is +// not. +static CRYPTO_MUTEX g_pubkey_lock = CRYPTO_MUTEX_INIT; -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) -{ - EVP_PKEY *ret = NULL; - uint8_t *spki = NULL; +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) { + EVP_PKEY *ret = NULL; + uint8_t *spki = NULL; - if (key == NULL) - goto error; + if (key == NULL) { + goto error; + } - CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); - if (key->pkey != NULL) { - CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); - EVP_PKEY_up_ref(key->pkey); - return key->pkey; - } - CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + CRYPTO_MUTEX_lock_read(&g_pubkey_lock); + if (key->pkey != NULL) { + CRYPTO_MUTEX_unlock_read(&g_pubkey_lock); + EVP_PKEY_up_ref(key->pkey); + return key->pkey; + } + CRYPTO_MUTEX_unlock_read(&g_pubkey_lock); - /* Re-encode the |X509_PUBKEY| to DER and parse it. */ - int spki_len = i2d_X509_PUBKEY(key, &spki); - if (spki_len < 0) { - goto error; - } - CBS cbs; - CBS_init(&cbs, spki, (size_t)spki_len); - ret = EVP_parse_public_key(&cbs); - if (ret == NULL || CBS_len(&cbs) != 0) { - OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); - goto error; - } + // Re-encode the |X509_PUBKEY| to DER and parse it. + int spki_len = i2d_X509_PUBKEY(key, &spki); + if (spki_len < 0) { + goto error; + } + CBS cbs; + CBS_init(&cbs, spki, (size_t)spki_len); + ret = EVP_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } - /* Check to see if another thread set key->pkey first */ - CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); - if (key->pkey) { - CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); - EVP_PKEY_free(ret); - ret = key->pkey; - } else { - key->pkey = ret; - CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); - } - - OPENSSL_free(spki); - EVP_PKEY_up_ref(ret); - return ret; - - error: - OPENSSL_free(spki); + // Check to see if another thread set key->pkey first + CRYPTO_MUTEX_lock_write(&g_pubkey_lock); + if (key->pkey) { + CRYPTO_MUTEX_unlock_write(&g_pubkey_lock); EVP_PKEY_free(ret); - return NULL; + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_MUTEX_unlock_write(&g_pubkey_lock); + } + + OPENSSL_free(spki); + EVP_PKEY_up_ref(ret); + return ret; + +error: + OPENSSL_free(spki); + EVP_PKEY_free(ret); + return NULL; } int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, int param_type, - void *param_value, uint8_t *key, int key_len) -{ - if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) { - return 0; - } + void *param_value, uint8_t *key, int key_len) { + if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) { + return 0; + } - ASN1_STRING_set0(pub->public_key, key, key_len); - /* Set the number of unused bits to zero. */ - pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; - return 1; + ASN1_STRING_set0(pub->public_key, key, key_len); + // Set the number of unused bits to zero. + pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; } int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key, int *out_key_len, X509_ALGOR **out_alg, - X509_PUBKEY *pub) -{ - if (out_obj != NULL) { - *out_obj = pub->algor->algorithm; - } - if (out_key != NULL) { - *out_key = pub->public_key->data; - *out_key_len = pub->public_key->length; - } - if (out_alg != NULL) { - *out_alg = pub->algor; - } - return 1; + X509_PUBKEY *pub) { + if (out_obj != NULL) { + *out_obj = pub->algor->algorithm; + } + if (out_key != NULL) { + *out_key = pub->public_key->data; + *out_key_len = pub->public_key->length; + } + if (out_alg != NULL) { + *out_alg = pub->algor; + } + return 1; } const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key(const X509_PUBKEY *pub) { - return pub->public_key; + return pub->public_key; } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_req.c b/third_party/boringssl/kit/src/crypto/x509/x_req.c index 0e9dce11..59cfbab7 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_req.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_req.c @@ -63,43 +63,53 @@ #include "internal.h" -/* - * X509_REQ_INFO is handled in an unusual way to get round invalid encodings. - * Some broken certificate requests don't encode the attributes field if it - * is empty. This is in violation of PKCS#10 but we need to tolerate it. We - * do this by making the attributes field OPTIONAL then using the callback to - * initialise it to an empty STACK. This means that the field will be - * correctly encoded unless we NULL out the field. - */ +// X509_REQ_INFO is handled in an unusual way to get round invalid encodings. +// Some broken certificate requests don't encode the attributes field if it +// is empty. This is in violation of PKCS#10 but we need to tolerate it. We +// do this by making the attributes field OPTIONAL then using the callback to +// initialise it to an empty STACK. This means that the field will be +// correctly encoded unless we NULL out the field. static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; + void *exarg) { + X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; - if (operation == ASN1_OP_NEW_POST) { - rinf->attributes = sk_X509_ATTRIBUTE_new_null(); - if (!rinf->attributes) - return 0; + if (operation == ASN1_OP_NEW_POST) { + rinf->attributes = sk_X509_ATTRIBUTE_new_null(); + if (!rinf->attributes) { + return 0; } - return 1; + } + + if (operation == ASN1_OP_D2I_POST) { + // The only defined CSR version is v1(0). For compatibility, we also accept + // a hypothetical v3(2). Although not defined, older versions of certbot + // use it. See https://github.com/certbot/certbot/pull/9334. + long version = ASN1_INTEGER_get(rinf->version); + if (version != X509_REQ_VERSION_1 && version != 2) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return 0; + } + } + + return 1; } ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { - ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), - ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), - /* This isn't really OPTIONAL but it gets around invalid encodings. */ - ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) + ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), + ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), + // This isn't really OPTIONAL but it gets around invalid encodings. + ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0), } ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) -ASN1_SEQUENCE_ref(X509_REQ, 0) = { - ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), - ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) +ASN1_SEQUENCE(X509_REQ) = { + ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), + ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(X509_REQ) IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) diff --git a/third_party/boringssl/kit/src/crypto/x509/x_sig.c b/third_party/boringssl/kit/src/crypto/x509/x_sig.c index 8f9a5b74..adf224df 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_sig.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_sig.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_sig.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -67,11 +66,11 @@ struct X509_sig_st { } /* X509_SIG */; ASN1_SEQUENCE(X509_SIG) = { - ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), - ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING) + ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), + ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING), } ASN1_SEQUENCE_END(X509_SIG) -IMPLEMENT_ASN1_FUNCTIONS(X509_SIG) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_SIG) void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **out_alg, const ASN1_OCTET_STRING **out_digest) { diff --git a/third_party/boringssl/kit/src/crypto/x509/x_spki.c b/third_party/boringssl/kit/src/crypto/x509/x_spki.c index 86da6ddf..905a87be 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_spki.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_spki.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_spki.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,26 +54,24 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ - /* - * This module was send to me my Pat Richards who wrote it. - * It is under my Copyright with his permission. - */ +// This module was send to me my Pat Richards who wrote it. +// It is under my Copyright with his permission. -#include #include +#include ASN1_SEQUENCE(NETSCAPE_SPKAC) = { - ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), - ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING) + ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), + ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING), } ASN1_SEQUENCE_END(NETSCAPE_SPKAC) -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_SPKAC) ASN1_SEQUENCE(NETSCAPE_SPKI) = { - ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), - ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), - ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING) + ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), + ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING), } ASN1_SEQUENCE_END(NETSCAPE_SPKI) -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_SPKI) diff --git a/third_party/boringssl/kit/src/crypto/x509/x_val.c b/third_party/boringssl/kit/src/crypto/x509/x_val.c index 006c53b1..cc02e92f 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_val.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_val.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_val.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -64,8 +63,8 @@ ASN1_SEQUENCE(X509_VAL) = { - ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), - ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME) + ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), + ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME), } ASN1_SEQUENCE_END(X509_VAL) -IMPLEMENT_ASN1_FUNCTIONS(X509_VAL) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_VAL) diff --git a/third_party/boringssl/kit/src/crypto/x509/x_x509.c b/third_party/boringssl/kit/src/crypto/x509/x_x509.c index 9d350bdb..31dbebe1 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_x509.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_x509.c @@ -1,4 +1,3 @@ -/* crypto/asn1/x_x509.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -68,327 +67,486 @@ #include #include +#include "../asn1/internal.h" +#include "../bytestring/internal.h" #include "../internal.h" #include "internal.h" static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { - ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), - ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), - ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), - ASN1_SIMPLE(X509_CINF, validity, X509_VAL), - ASN1_SIMPLE(X509_CINF, subject, X509_NAME), - ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), - ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), - ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) + ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), + ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), + ASN1_SIMPLE(X509_CINF, validity, X509_VAL), + ASN1_SIMPLE(X509_CINF, subject, X509_NAME), + ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), + ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3), } ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) -/* X509 top level structure needs a bit of customisation */ -extern void policy_cache_free(X509_POLICY_CACHE *cache); - -static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509 *ret = (X509 *)*pval; - - switch (operation) { - - case ASN1_OP_NEW_POST: - ret->ex_flags = 0; - ret->ex_pathlen = -1; - ret->skid = NULL; - ret->akid = NULL; - ret->aux = NULL; - ret->crldp = NULL; - ret->buf = NULL; - CRYPTO_new_ex_data(&ret->ex_data); - CRYPTO_MUTEX_init(&ret->lock); - break; - - case ASN1_OP_D2I_PRE: - CRYPTO_BUFFER_free(ret->buf); - ret->buf = NULL; - break; - - case ASN1_OP_D2I_POST: { - /* The version must be one of v1(0), v2(1), or v3(2). */ - long version = 0; - if (ret->cert_info->version != NULL) { - version = ASN1_INTEGER_get(ret->cert_info->version); - /* TODO(https://crbug.com/boringssl/364): |version| = 0 should also - * be rejected. This means an explicitly-encoded X.509v1 version. - * v1 is DEFAULT, so DER requires it be omitted. */ - if (version < 0 || version > 2) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); - return 0; - } - } - - /* Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. */ - if (version == 0 && (ret->cert_info->issuerUID != NULL || - ret->cert_info->subjectUID != NULL)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return 0; - } - - /* Per RFC 5280, section 4.1.2.9, extensions require v3. */ - if (version != 2 && ret->cert_info->extensions != NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return 0; - } - - break; - } - - case ASN1_OP_FREE_POST: - CRYPTO_MUTEX_cleanup(&ret->lock); - CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data); - X509_CERT_AUX_free(ret->aux); - ASN1_OCTET_STRING_free(ret->skid); - AUTHORITY_KEYID_free(ret->akid); - CRL_DIST_POINTS_free(ret->crldp); - policy_cache_free(ret->policy_cache); - GENERAL_NAMES_free(ret->altname); - NAME_CONSTRAINTS_free(ret->nc); - CRYPTO_BUFFER_free(ret->buf); - break; - - } - - return 1; +// x509_new_null returns a new |X509| object where the |cert_info|, |sig_alg|, +// and |signature| fields are not yet filled in. +static X509 *x509_new_null(void) { + X509 *ret = OPENSSL_malloc(sizeof(X509)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(X509)); + ret->references = 1; + ret->ex_pathlen = -1; + CRYPTO_new_ex_data(&ret->ex_data); + CRYPTO_MUTEX_init(&ret->lock); + return ret; } -ASN1_SEQUENCE_ref(X509, x509_cb) = { - ASN1_SIMPLE(X509, cert_info, X509_CINF), - ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_ref(X509, X509) - -IMPLEMENT_ASN1_FUNCTIONS(X509) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509) - -X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { - if (CRYPTO_BUFFER_len(buf) > LONG_MAX) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); - return 0; - } - - X509 *x509 = X509_new(); - if (x509 == NULL) { +X509 *X509_new(void) { + X509 *ret = x509_new_null(); + if (ret == NULL) { return NULL; } - x509->cert_info->enc.alias_only_on_next_parse = 1; - - const uint8_t *inp = CRYPTO_BUFFER_data(buf); - X509 *x509p = x509; - X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf)); - if (ret == NULL || - inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) { - X509_free(x509p); + ret->cert_info = X509_CINF_new(); + ret->sig_alg = X509_ALGOR_new(); + ret->signature = ASN1_BIT_STRING_new(); + if (ret->cert_info == NULL || ret->sig_alg == NULL || + ret->signature == NULL) { + X509_free(ret); return NULL; } - assert(x509p == x509); - assert(ret == x509); - - CRYPTO_BUFFER_up_ref(buf); - ret->buf = buf; return ret; } -int X509_up_ref(X509 *x) -{ - CRYPTO_refcount_inc(&x->references); - return 1; +void X509_free(X509 *x509) { + if (x509 == NULL || !CRYPTO_refcount_dec_and_test_zero(&x509->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, x509, &x509->ex_data); + + X509_CINF_free(x509->cert_info); + X509_ALGOR_free(x509->sig_alg); + ASN1_BIT_STRING_free(x509->signature); + ASN1_OCTET_STRING_free(x509->skid); + AUTHORITY_KEYID_free(x509->akid); + CRL_DIST_POINTS_free(x509->crldp); + GENERAL_NAMES_free(x509->altname); + NAME_CONSTRAINTS_free(x509->nc); + X509_CERT_AUX_free(x509->aux); + CRYPTO_MUTEX_cleanup(&x509->lock); + + OPENSSL_free(x509); } -int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused, - CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) -{ - int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, - free_func)) { - return -1; - } - return index; -} - -int X509_set_ex_data(X509 *r, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); -} - -void *X509_get_ex_data(X509 *r, int idx) -{ - return (CRYPTO_get_ex_data(&r->ex_data, idx)); -} - -/* - * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with - * extra info tagged on the end. Since these functions set how a certificate - * is trusted they should only be used when the certificate comes from a - * reliable source such as local storage. - */ - -X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) -{ - const unsigned char *q = *pp; - X509 *ret; - int freeret = 0; - - if (!a || *a == NULL) - freeret = 1; - ret = d2i_X509(a, &q, length); - /* If certificate unreadable then forget it */ - if (!ret) - return NULL; - /* update length */ - length -= q - *pp; - /* Parse auxiliary information if there is any. */ - if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) - goto err; - *pp = q; - return ret; - err: - if (freeret) { - X509_free(ret); - if (a) - *a = NULL; - } +static X509 *x509_parse(CBS *cbs, CRYPTO_BUFFER *buf) { + CBS cert, tbs, sigalg, sig; + if (!CBS_get_asn1(cbs, &cert, CBS_ASN1_SEQUENCE) || + // Bound the length to comfortably fit in an int. Lengths in this + // module often omit overflow checks. + CBS_len(&cert) > INT_MAX / 2 || + !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_element(&cert, &sigalg, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return NULL; + } + + // For just the signature field, we accept non-minimal BER lengths, though not + // indefinite-length encoding. See b/18228011. + // + // TODO(crbug.com/boringssl/354): Switch the affected callers to convert the + // certificate before parsing and then remove this workaround. + CBS_ASN1_TAG tag; + size_t header_len; + int indefinite; + if (!CBS_get_any_ber_asn1_element(&cert, &sig, &tag, &header_len, + /*out_ber_found=*/NULL, + &indefinite) || + tag != CBS_ASN1_BITSTRING || indefinite || // + !CBS_skip(&sig, header_len) || // + CBS_len(&cert) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return NULL; + } + + X509 *ret = x509_new_null(); + if (ret == NULL) { + return NULL; + } + + // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled + // from the tasn_*.c implementation, replace this with |CBS|-based functions. + const uint8_t *inp = CBS_data(&tbs); + if (ASN1_item_ex_d2i((ASN1_VALUE **)&ret->cert_info, &inp, CBS_len(&tbs), + ASN1_ITEM_rptr(X509_CINF), /*tag=*/-1, + /*aclass=*/0, /*opt=*/0, buf) <= 0 || + inp != CBS_data(&tbs) + CBS_len(&tbs)) { + goto err; + } + + inp = CBS_data(&sigalg); + ret->sig_alg = d2i_X509_ALGOR(NULL, &inp, CBS_len(&sigalg)); + if (ret->sig_alg == NULL || inp != CBS_data(&sigalg) + CBS_len(&sigalg)) { + goto err; + } + + inp = CBS_data(&sig); + ret->signature = c2i_ASN1_BIT_STRING(NULL, &inp, CBS_len(&sig)); + if (ret->signature == NULL || inp != CBS_data(&sig) + CBS_len(&sig)) { + goto err; + } + + // The version must be one of v1(0), v2(1), or v3(2). + long version = X509_VERSION_1; + if (ret->cert_info->version != NULL) { + version = ASN1_INTEGER_get(ret->cert_info->version); + // TODO(https://crbug.com/boringssl/364): |X509_VERSION_1| should + // also be rejected here. This means an explicitly-encoded X.509v1 + // version. v1 is DEFAULT, so DER requires it be omitted. + if (version < X509_VERSION_1 || version > X509_VERSION_3) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + goto err; + } + } + + // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. + if (version == X509_VERSION_1 && (ret->cert_info->issuerUID != NULL || + ret->cert_info->subjectUID != NULL)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + goto err; + } + + // Per RFC 5280, section 4.1.2.9, extensions require v3. + if (version != X509_VERSION_3 && ret->cert_info->extensions != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + goto err; + } + + return ret; + +err: + X509_free(ret); + return NULL; } -/* - * Serialize trusted certificate to *pp or just return the required buffer - * length if pp == NULL. We ultimately want to avoid modifying *pp in the - * error path, but that depends on similar hygiene in lower-level functions. - * Here we avoid compounding the problem. - */ -static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) -{ - int length, tmplen; - unsigned char *start = pp != NULL ? *pp : NULL; +X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { + X509 *ret = NULL; + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + goto err; + } - assert(pp == NULL || *pp != NULL); + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + ret = x509_parse(&cbs, NULL); + if (ret == NULL) { + goto err; + } - /* - * This might perturb *pp on error, but fixing that belongs in i2d_X509() - * not here. It should be that if a == NULL length is zero, but we check - * both just in case. - */ - length = i2d_X509(a, pp); - if (length <= 0 || a == NULL) { - return length; + *inp = CBS_data(&cbs); + +err: + if (out != NULL) { + X509_free(*out); + *out = ret; + } + return ret; +} + +int i2d_X509(X509 *x509, uint8_t **outp) { + if (x509 == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE); + return -1; + } + + CBB cbb, cert; + if (!CBB_init(&cbb, 64) || // + !CBB_add_asn1(&cbb, &cert, CBS_ASN1_SEQUENCE)) { + goto err; + } + + // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled + // from the tasn_*.c implementation, replace this with |CBS|-based functions. + uint8_t *out; + int len = i2d_X509_CINF(x509->cert_info, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_X509_CINF(x509->cert_info, &out) != len) { + goto err; + } + + len = i2d_X509_ALGOR(x509->sig_alg, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_X509_ALGOR(x509->sig_alg, &out) != len) { + goto err; + } + + len = i2d_ASN1_BIT_STRING(x509->signature, NULL); + if (len < 0 || // + !CBB_add_space(&cert, &out, (size_t)len) || + i2d_ASN1_BIT_STRING(x509->signature, &out) != len) { + goto err; + } + + return CBB_finish_i2d(&cbb, outp); + +err: + CBB_cleanup(&cbb); + return -1; +} + +static int x509_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { + *pval = (ASN1_VALUE *)X509_new(); + return *pval != NULL; +} + +static void x509_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { + X509_free((X509 *)*pval); + *pval = NULL; +} + +static int x509_d2i_cb(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int opt, ASN1_TLC *ctx) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + return 0; + } + + CBS cbs; + CBS_init(&cbs, *in, len); + if (opt && !CBS_peek_asn1_tag(&cbs, CBS_ASN1_SEQUENCE)) { + return -1; + } + + X509 *ret = x509_parse(&cbs, NULL); + if (ret == NULL) { + return 0; + } + + *in = CBS_data(&cbs); + X509_free((X509 *)*pval); + *pval = (ASN1_VALUE *)ret; + return 1; +} + +static int x509_i2d_cb(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it) { + return i2d_X509((X509 *)*pval, out); +} + +static const ASN1_EXTERN_FUNCS x509_extern_funcs = { + x509_new_cb, + x509_free_cb, + /*asn1_ex_clear=*/NULL, + x509_d2i_cb, + x509_i2d_cb, +}; + +IMPLEMENT_EXTERN_ASN1(X509, V_ASN1_SEQUENCE, x509_extern_funcs) + +X509 *X509_dup(X509 *x509) { + uint8_t *der = NULL; + int len = i2d_X509(x509, &der); + if (len < 0) { + return NULL; + } + + const uint8_t *inp = der; + X509 *ret = d2i_X509(NULL, &inp, len); + OPENSSL_free(der); + return ret; +} + +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + CBS cbs; + CBS_init(&cbs, CRYPTO_BUFFER_data(buf), CRYPTO_BUFFER_len(buf)); + X509 *ret = x509_parse(&cbs, buf); + if (ret == NULL || CBS_len(&cbs) != 0) { + X509_free(ret); + return NULL; + } + + return ret; +} + +int X509_up_ref(X509 *x) { + CRYPTO_refcount_inc(&x->references); + return 1; +} + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int X509_set_ex_data(X509 *r, int idx, void *arg) { + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *X509_get_ex_data(X509 *r, int idx) { + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +// X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with +// extra info tagged on the end. Since these functions set how a certificate +// is trusted they should only be used when the certificate comes from a +// reliable source such as local storage. + +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) { + const unsigned char *q = *pp; + X509 *ret; + int freeret = 0; + + if (!a || *a == NULL) { + freeret = 1; + } + ret = d2i_X509(a, &q, length); + // If certificate unreadable then forget it + if (!ret) { + return NULL; + } + // update length + length -= q - *pp; + // Parse auxiliary information if there is any. + if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) { + goto err; + } + *pp = q; + return ret; +err: + if (freeret) { + X509_free(ret); + if (a) { + *a = NULL; } + } + return NULL; +} - if (a->aux != NULL) { - tmplen = i2d_X509_CERT_AUX(a->aux, pp); - if (tmplen < 0) { - if (start != NULL) - *pp = start; - return tmplen; - } - length += tmplen; - } +// Serialize trusted certificate to *pp or just return the required buffer +// length if pp == NULL. We ultimately want to avoid modifying *pp in the +// error path, but that depends on similar hygiene in lower-level functions. +// Here we avoid compounding the problem. +static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) { + int length, tmplen; + unsigned char *start = pp != NULL ? *pp : NULL; + assert(pp == NULL || *pp != NULL); + + // This might perturb *pp on error, but fixing that belongs in i2d_X509() + // not here. It should be that if a == NULL length is zero, but we check + // both just in case. + length = i2d_X509(a, pp); + if (length <= 0 || a == NULL) { return length; + } + + if (a->aux != NULL) { + tmplen = i2d_X509_CERT_AUX(a->aux, pp); + if (tmplen < 0) { + if (start != NULL) { + *pp = start; + } + return tmplen; + } + length += tmplen; + } + + return length; } -/* - * Serialize trusted certificate to *pp, or just return the required buffer - * length if pp == NULL. - * - * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since - * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do - * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the - * allocated buffer. - */ -int i2d_X509_AUX(X509 *a, unsigned char **pp) -{ - int length; - unsigned char *tmp; +// Serialize trusted certificate to *pp, or just return the required buffer +// length if pp == NULL. +// +// When pp is not NULL, but *pp == NULL, we allocate the buffer, but since +// we're writing two ASN.1 objects back to back, we can't have i2d_X509() do +// the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the +// allocated buffer. +int i2d_X509_AUX(X509 *a, unsigned char **pp) { + int length; + unsigned char *tmp; - /* Buffer provided by caller */ - if (pp == NULL || *pp != NULL) - return i2d_x509_aux_internal(a, pp); + // Buffer provided by caller + if (pp == NULL || *pp != NULL) { + return i2d_x509_aux_internal(a, pp); + } - /* Obtain the combined length */ - if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) - return length; - - /* Allocate requisite combined storage */ - *pp = tmp = OPENSSL_malloc(length); - if (tmp == NULL) - return -1; /* Push error onto error stack? */ - - /* Encode, but keep *pp at the originally malloced pointer */ - length = i2d_x509_aux_internal(a, &tmp); - if (length <= 0) { - OPENSSL_free(*pp); - *pp = NULL; - } + // Obtain the combined length + if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) { return length; + } + + // Allocate requisite combined storage + *pp = tmp = OPENSSL_malloc(length); + if (tmp == NULL) { + return -1; // Push error onto error stack? + } + + // Encode, but keep *pp at the originally malloced pointer + length = i2d_x509_aux_internal(a, &tmp); + if (length <= 0) { + OPENSSL_free(*pp); + *pp = NULL; + } + return length; } -int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) -{ - x509->cert_info->enc.modified = 1; - return i2d_X509_CINF(x509->cert_info, outp); +int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) { + asn1_encoding_clear(&x509->cert_info->enc); + return i2d_X509_CINF(x509->cert_info, outp); } -int i2d_X509_tbs(X509 *x509, unsigned char **outp) -{ - return i2d_X509_CINF(x509->cert_info, outp); +int i2d_X509_tbs(X509 *x509, unsigned char **outp) { + return i2d_X509_CINF(x509->cert_info, outp); } -int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo) -{ - /* TODO(davidben): Const-correct generated ASN.1 dup functions. - * Alternatively, when the types are hidden and we can embed required fields - * directly in structs, import |X509_ALGOR_copy| from upstream. */ - X509_ALGOR *copy1 = X509_ALGOR_dup((X509_ALGOR *)algo); - X509_ALGOR *copy2 = X509_ALGOR_dup((X509_ALGOR *)algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } +int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo) { + X509_ALGOR *copy1 = X509_ALGOR_dup(algo); + X509_ALGOR *copy2 = X509_ALGOR_dup(algo); + if (copy1 == NULL || copy2 == NULL) { + X509_ALGOR_free(copy1); + X509_ALGOR_free(copy2); + return 0; + } - X509_ALGOR_free(x509->sig_alg); - x509->sig_alg = copy1; - X509_ALGOR_free(x509->cert_info->signature); - x509->cert_info->signature = copy2; - return 1; + X509_ALGOR_free(x509->sig_alg); + x509->sig_alg = copy1; + X509_ALGOR_free(x509->cert_info->signature); + x509->cert_info->signature = copy2; + return 1; } -int X509_set1_signature_value(X509 *x509, const uint8_t *sig, size_t sig_len) -{ - if (!ASN1_STRING_set(x509->signature, sig, sig_len)) { - return 0; - } - x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - return 1; +int X509_set1_signature_value(X509 *x509, const uint8_t *sig, size_t sig_len) { + if (!ASN1_STRING_set(x509->signature, sig, sig_len)) { + return 0; + } + x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return 1; } void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, - const X509 *x) -{ - if (psig) - *psig = x->signature; - if (palg) - *palg = x->sig_alg; + const X509 *x) { + if (psig) { + *psig = x->signature; + } + if (palg) { + *palg = x->sig_alg; + } } -int X509_get_signature_nid(const X509 *x) -{ - return OBJ_obj2nid(x->sig_alg->algorithm); +int X509_get_signature_nid(const X509 *x) { + return OBJ_obj2nid(x->sig_alg->algorithm); } diff --git a/third_party/boringssl/kit/src/crypto/x509/x_x509a.c b/third_party/boringssl/kit/src/crypto/x509/x_x509a.c index fca02a63..4b34caaa 100644 --- a/third_party/boringssl/kit/src/crypto/x509/x_x509a.c +++ b/third_party/boringssl/kit/src/crypto/x509/x_x509a.c @@ -64,138 +64,146 @@ #include "internal.h" -/* - * X509_CERT_AUX routines. These are used to encode additional user - * modifiable data about a certificate. This data is appended to the X509 - * encoding when the *_X509_AUX routines are used. This means that the - * "traditional" X509 routines will simply ignore the extra data. - */ +// X509_CERT_AUX routines. These are used to encode additional user +// modifiable data about a certificate. This data is appended to the X509 +// encoding when the *_X509_AUX routines are used. This means that the +// "traditional" X509 routines will simply ignore the extra data. static X509_CERT_AUX *aux_get(X509 *x); ASN1_SEQUENCE(X509_CERT_AUX) = { - ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), - ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), - ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), - ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), - ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1) + ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), + ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), + ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), } ASN1_SEQUENCE_END(X509_CERT_AUX) -IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) +IMPLEMENT_ASN1_FUNCTIONS_const(X509_CERT_AUX) -static X509_CERT_AUX *aux_get(X509 *x) -{ - if (!x) - return NULL; - if (!x->aux && !(x->aux = X509_CERT_AUX_new())) - return NULL; - return x->aux; +static X509_CERT_AUX *aux_get(X509 *x) { + if (!x) { + return NULL; + } + if (!x->aux && !(x->aux = X509_CERT_AUX_new())) { + return NULL; + } + return x->aux; } -int X509_alias_set1(X509 *x, const unsigned char *name, int len) -{ - X509_CERT_AUX *aux; - if (!name) { - if (!x || !x->aux || !x->aux->alias) - return 1; - ASN1_UTF8STRING_free(x->aux->alias); - x->aux->alias = NULL; - return 1; +int X509_alias_set1(X509 *x, const unsigned char *name, ossl_ssize_t len) { + X509_CERT_AUX *aux; + // TODO(davidben): Empty aliases are not meaningful in PKCS#12, and the + // getters cannot quite represent them. Also erase the object if |len| is + // zero. + if (!name) { + if (!x || !x->aux || !x->aux->alias) { + return 1; } - if (!(aux = aux_get(x))) - return 0; - if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) - return 0; - return ASN1_STRING_set(aux->alias, name, len); + ASN1_UTF8STRING_free(x->aux->alias); + x->aux->alias = NULL; + return 1; + } + if (!(aux = aux_get(x))) { + return 0; + } + if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) { + return 0; + } + return ASN1_STRING_set(aux->alias, name, len); } -int X509_keyid_set1(X509 *x, const unsigned char *id, int len) -{ - X509_CERT_AUX *aux; - if (!id) { - if (!x || !x->aux || !x->aux->keyid) - return 1; - ASN1_OCTET_STRING_free(x->aux->keyid); - x->aux->keyid = NULL; - return 1; +int X509_keyid_set1(X509 *x, const unsigned char *id, ossl_ssize_t len) { + X509_CERT_AUX *aux; + // TODO(davidben): Empty key IDs are not meaningful in PKCS#12, and the + // getters cannot quite represent them. Also erase the object if |len| is + // zero. + if (!id) { + if (!x || !x->aux || !x->aux->keyid) { + return 1; } - if (!(aux = aux_get(x))) - return 0; - if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) - return 0; - return ASN1_STRING_set(aux->keyid, id, len); + ASN1_OCTET_STRING_free(x->aux->keyid); + x->aux->keyid = NULL; + return 1; + } + if (!(aux = aux_get(x))) { + return 0; + } + if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) { + return 0; + } + return ASN1_STRING_set(aux->keyid, id, len); } -unsigned char *X509_alias_get0(X509 *x, int *len) -{ - if (!x->aux || !x->aux->alias) - return NULL; - if (len) - *len = x->aux->alias->length; - return x->aux->alias->data; +unsigned char *X509_alias_get0(X509 *x, int *out_len) { + const ASN1_UTF8STRING *alias = x->aux != NULL ? x->aux->alias : NULL; + if (out_len != NULL) { + *out_len = alias != NULL ? alias->length : 0; + } + return alias != NULL ? alias->data : NULL; } -unsigned char *X509_keyid_get0(X509 *x, int *len) -{ - if (!x->aux || !x->aux->keyid) - return NULL; - if (len) - *len = x->aux->keyid->length; - return x->aux->keyid->data; +unsigned char *X509_keyid_get0(X509 *x, int *out_len) { + const ASN1_OCTET_STRING *keyid = x->aux != NULL ? x->aux->keyid : NULL; + if (out_len != NULL) { + *out_len = keyid != NULL ? keyid->length : 0; + } + return keyid != NULL ? keyid->data : NULL; } -int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) -{ - ASN1_OBJECT *objtmp = OBJ_dup(obj); - if (objtmp == NULL) - goto err; - X509_CERT_AUX *aux = aux_get(x); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) { + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) { + goto err; + } + X509_CERT_AUX *aux = aux_get(x); + if (aux->trust == NULL) { + aux->trust = sk_ASN1_OBJECT_new_null(); if (aux->trust == NULL) { - aux->trust = sk_ASN1_OBJECT_new_null(); - if (aux->trust == NULL) - goto err; + goto err; } - if (!sk_ASN1_OBJECT_push(aux->trust, objtmp)) - goto err; - return 1; + } + if (!sk_ASN1_OBJECT_push(aux->trust, objtmp)) { + goto err; + } + return 1; - err: - ASN1_OBJECT_free(objtmp); - return 0; +err: + ASN1_OBJECT_free(objtmp); + return 0; } -int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) -{ - ASN1_OBJECT *objtmp = OBJ_dup(obj); - if (objtmp == NULL) - goto err; - X509_CERT_AUX *aux = aux_get(x); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) { + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) { + goto err; + } + X509_CERT_AUX *aux = aux_get(x); + if (aux->reject == NULL) { + aux->reject = sk_ASN1_OBJECT_new_null(); if (aux->reject == NULL) { - aux->reject = sk_ASN1_OBJECT_new_null(); - if (aux->reject == NULL) - goto err; + goto err; } - if (!sk_ASN1_OBJECT_push(aux->reject, objtmp)) - goto err; - return 1; + } + if (!sk_ASN1_OBJECT_push(aux->reject, objtmp)) { + goto err; + } + return 1; - err: - ASN1_OBJECT_free(objtmp); - return 0; +err: + ASN1_OBJECT_free(objtmp); + return 0; } -void X509_trust_clear(X509 *x) -{ - if (x->aux && x->aux->trust) { - sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); - x->aux->trust = NULL; - } +void X509_trust_clear(X509 *x) { + if (x->aux && x->aux->trust) { + sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); + x->aux->trust = NULL; + } } -void X509_reject_clear(X509 *x) -{ - if (x->aux && x->aux->reject) { - sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); - x->aux->reject = NULL; - } +void X509_reject_clear(X509 *x) { + if (x->aux && x->aux->reject) { + sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); + x->aux->reject = NULL; + } } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/ext_dat.h b/third_party/boringssl/kit/src/crypto/x509v3/ext_dat.h index 79301263..0d327699 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/ext_dat.h +++ b/third_party/boringssl/kit/src/crypto/x509v3/ext_dat.h @@ -54,7 +54,7 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -/* This file contains a table of "standard" extensions */ +// This file contains a table of "standard" extensions #if defined(__cplusplus) extern "C" { @@ -65,23 +65,19 @@ extern const X509V3_EXT_METHOD v3_info, v3_sinfo; extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, - v3_freshest_crl; -extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, - v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern const X509V3_EXT_METHOD v3_crl_hold; extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; extern const X509V3_EXT_METHOD v3_addr, v3_asid; -/* - * This table will be searched using OBJ_bsearch so it *must* kept in order - * of the ext_nid values. - */ +// This table will be searched using OBJ_bsearch so it *must* kept in order +// of the ext_nid values. -/* TODO(fork): OCSP support */ +// TODO(fork): OCSP support #define OPENSSL_NO_OCSP static const X509V3_EXT_METHOD *const standard_exts[] = { @@ -120,7 +116,6 @@ static const X509V3_EXT_METHOD *const standard_exts[] = { #ifndef OPENSSL_NO_OCSP &v3_crl_hold, #endif - &v3_pci, &v3_name_constraints, &v3_policy_mappings, &v3_inhibit_anyp, @@ -129,10 +124,11 @@ static const X509V3_EXT_METHOD *const standard_exts[] = { &v3_freshest_crl, }; -/* Number of standard extensions */ +// Number of standard extensions -#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) +#define STANDARD_EXTENSION_COUNT \ + (sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *)) #if defined(__cplusplus) -} /* extern C */ +} // extern C #endif diff --git a/third_party/boringssl/kit/src/crypto/x509v3/internal.h b/third_party/boringssl/kit/src/crypto/x509v3/internal.h index 3e6081b4..315d9343 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/internal.h +++ b/third_party/boringssl/kit/src/crypto/x509v3/internal.h @@ -65,31 +65,36 @@ #include #include +// TODO(davidben): Merge x509 and x509v3. This include is needed because some +// internal typedefs are shared between the two, but the two modules depend on +// each other circularly. +#include "../x509/internal.h" + #if defined(__cplusplus) extern "C" { #endif -// x509v3_bytes_to_hex encodes |len| bytes from |buffer| to hex and returns a +// x509v3_bytes_to_hex encodes |len| bytes from |in| to hex and returns a // newly-allocated NUL-terminated string containing the result, or NULL on // allocation error. // -// Note this function was historically named |hex_to_string| in OpenSSL, not -// |string_to_hex|. -char *x509v3_bytes_to_hex(const unsigned char *buffer, long len); +// This function was historically named |hex_to_string| in OpenSSL. Despite the +// name, |hex_to_string| converted to hex. +OPENSSL_EXPORT char *x509v3_bytes_to_hex(const uint8_t *in, size_t len); // x509v3_hex_string_to_bytes decodes |str| in hex and returns a newly-allocated // array containing the result, or NULL on error. On success, it sets |*len| to // the length of the result. Colon separators between bytes in the input are // allowed and ignored. // -// Note this function was historically named |string_to_hex| in OpenSSL, not -// |hex_to_string|. -unsigned char *x509v3_hex_to_bytes(const char *str, long *len); +// This function was historically named |string_to_hex| in OpenSSL. Despite the +// name, |string_to_hex| converted from hex. +unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len); -// x509v3_name_cmp returns zero if |name| is equal to |cmp| or begins with |cmp| -// followed by '.'. Otherwise, it returns a non-zero number. -int x509v3_name_cmp(const char *name, const char *cmp); +// x509v3_conf_name_matches returns one if |name| is equal to |cmp| or begins +// with |cmp| followed by '.', and zero otherwise. +int x509v3_conf_name_matches(const char *name, const char *cmp); // x509v3_looks_like_dns_name returns one if |in| looks like a DNS name and zero // otherwise. @@ -99,7 +104,7 @@ OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in, // x509v3_cache_extensions fills in a number of fields relating to X.509 // extensions in |x|. It returns one on success and zero if some extensions were // invalid. -int x509v3_cache_extensions(X509 *x); +OPENSSL_EXPORT int x509v3_cache_extensions(X509 *x); // x509v3_a2i_ipadd decodes |ipasc| as an IPv4 or IPv6 address. IPv6 addresses // use colon-separated syntax while IPv4 addresses use dotted decimal syntax. If @@ -122,168 +127,71 @@ typedef struct { int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, STACK_OF(CONF_VALUE) **extlist); -typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; +// X509V3_NAME_from_section adds attributes to |nm| by interpreting the +// key/value pairs in |dn_sk|. It returns one on success and zero on error. +// |chtype|, which should be one of |MBSTRING_*| constants, determines the +// character encoding used to interpret values. +int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, + int chtype); -DEFINE_STACK_OF(X509_POLICY_DATA) +// X509V3_bool_from_string decodes |str| as a boolean. On success, it returns +// one and sets |*out_bool| to resulting value. Otherwise, it returns zero. +int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool); -/* Internal structures */ +// X509V3_get_value_bool decodes |value| as a boolean. On success, it returns +// one and sets |*out_bool| to the resulting value. Otherwise, it returns zero. +int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool); -/* - * This structure and the field names correspond to the Policy 'node' of - * RFC 3280. NB this structure contains no pointers to parent or child data: - * X509_POLICY_NODE contains that. This means that the main policy data can - * be kept static and cached with the certificate. - */ +// X509V3_get_value_int decodes |value| as an integer. On success, it returns +// one and sets |*aint| to the resulting value. Otherwise, it returns zero. If +// |*aint| was non-NULL at the start of the function, it frees the previous +// value before writing a new one. +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); -struct X509_POLICY_DATA_st { - unsigned int flags; - /* Policy OID and qualifiers for this data */ - ASN1_OBJECT *valid_policy; - STACK_OF(POLICYQUALINFO) *qualifier_set; - STACK_OF(ASN1_OBJECT) *expected_policy_set; -}; +// X509V3_get_section behaves like |NCONF_get_section| but queries |ctx|'s +// config database. +const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, + const char *section); -/* X509_POLICY_DATA flags values */ +// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to +// |*extlist|. It returns one on success and zero on error. If |*extlist| is +// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the result. Either |name| or |value| may be NULL to omit the +// field. +// +// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the +// function returns. +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); -/* - * This flag indicates the structure has been mapped using a policy mapping - * extension. If policy mapping is not active its references get deleted. - */ +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value +// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); -#define POLICY_DATA_FLAG_MAPPED 0x1 +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string +// representation of |aint|. Note this string representation may be decimal or +// hexadecimal, depending on the size of |aint|. +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); -/* - * This flag indicates the data doesn't correspond to a policy in Certificate - * Policies: it has been mapped to any policy. - */ +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); -#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 +#define X509V3_conf_err(val) \ + ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ + ",value:", (val)->value); -/* AND with flags to see if any mapping has occurred */ - -#define POLICY_DATA_FLAG_MAP_MASK 0x3 - -/* qualifiers are shared and shouldn't be freed */ - -#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 - -/* Parent node is an extra node and should be freed */ - -#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 - -/* Corresponding CertificatePolicies is critical */ - -#define POLICY_DATA_FLAG_CRITICAL 0x10 - -/* This structure is cached with a certificate */ - -struct X509_POLICY_CACHE_st { - /* anyPolicy data or NULL if no anyPolicy */ - X509_POLICY_DATA *anyPolicy; - /* other policy data */ - STACK_OF(X509_POLICY_DATA) *data; - /* If InhibitAnyPolicy present this is its value or -1 if absent. */ - long any_skip; - /* - * If policyConstraints and requireExplicitPolicy present this is its - * value or -1 if absent. - */ - long explicit_skip; - /* - * If policyConstraints and policyMapping present this is its value or -1 - * if absent. - */ - long map_skip; -}; - -/* - * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL - */ - -/* This structure represents the relationship between nodes */ - -struct X509_POLICY_NODE_st { - /* node data this refers to */ - const X509_POLICY_DATA *data; - /* Parent node */ - X509_POLICY_NODE *parent; - /* Number of child nodes */ - int nchild; -}; - -struct X509_POLICY_LEVEL_st { - /* Cert for this level */ - X509 *cert; - /* nodes at this level */ - STACK_OF(X509_POLICY_NODE) *nodes; - /* anyPolicy node */ - X509_POLICY_NODE *anyPolicy; - /* Extra data */ - /* - * STACK_OF(X509_POLICY_DATA) *extra_data; - */ - unsigned int flags; -}; - -struct X509_POLICY_TREE_st { - /* This is the tree 'level' data */ - X509_POLICY_LEVEL *levels; - int nlevel; - /* - * Extra policy data when additional nodes (not from the certificate) are - * required. - */ - STACK_OF(X509_POLICY_DATA) *extra_data; - /* This is the authority constained policy set */ - STACK_OF(X509_POLICY_NODE) *auth_policies; - STACK_OF(X509_POLICY_NODE) *user_policies; - unsigned int flags; -}; - -/* Set if anyPolicy present in user policies */ -#define POLICY_FLAG_ANY_POLICY 0x2 - -/* Useful macros */ - -#define node_data_critical(data) ((data)->flags & POLICY_DATA_FLAG_CRITICAL) -#define node_critical(node) node_data_critical((node)->data) - -/* Internal functions */ - -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, - int crit); -void policy_data_free(X509_POLICY_DATA *data); - -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id); -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); - -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); - -void policy_cache_init(void); - -void policy_cache_free(X509_POLICY_CACHE *cache); - -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id); - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, - const ASN1_OBJECT *id); - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree); -void policy_node_free(X509_POLICY_NODE *node); -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); - -const X509_POLICY_CACHE *policy_cache_set(X509 *x); +// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero +// value otherwise. Note this function does not provide a comparison suitable +// for sorting. +// +// This function is exported for testing. +OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, + const GENERAL_NAME *b); #if defined(__cplusplus) -} /* extern C */ +} // extern C #endif -#endif /* OPENSSL_HEADER_X509V3_INTERNAL_H */ +#endif // OPENSSL_HEADER_X509V3_INTERNAL_H diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_cache.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_cache.c deleted file mode 100644 index 8303664a..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_cache.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include -#include -#include -#include - -#include "../internal.h" -#include "../x509/internal.h" -#include "internal.h" - -static int policy_data_cmp(const X509_POLICY_DATA **a, - const X509_POLICY_DATA **b); -static int policy_cache_set_int(long *out, ASN1_INTEGER *value); - -/* - * Set cache entry according to CertificatePolicies extension. Note: this - * destroys the passed CERTIFICATEPOLICIES structure. - */ - -static int policy_cache_create(X509 *x, - CERTIFICATEPOLICIES *policies, int crit) -{ - size_t i; - int ret = 0; - X509_POLICY_CACHE *cache = x->policy_cache; - X509_POLICY_DATA *data = NULL; - POLICYINFO *policy; - if (sk_POLICYINFO_num(policies) == 0) - goto bad_policy; - cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); - if (!cache->data) - goto bad_policy; - for (i = 0; i < sk_POLICYINFO_num(policies); i++) { - policy = sk_POLICYINFO_value(policies, i); - data = policy_data_new(policy, NULL, crit); - if (!data) - goto bad_policy; - /* - * Duplicate policy OIDs are illegal: reject if matches found. - */ - sk_X509_POLICY_DATA_sort(cache->data); - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { - if (cache->anyPolicy) { - ret = -1; - goto bad_policy; - } - cache->anyPolicy = data; - } else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data)) { - ret = -1; - goto bad_policy; - } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) - goto bad_policy; - data = NULL; - } - ret = 1; - bad_policy: - if (ret == -1) - x->ex_flags |= EXFLAG_INVALID_POLICY; - if (data) - policy_data_free(data); - sk_POLICYINFO_pop_free(policies, POLICYINFO_free); - if (ret <= 0) { - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); - cache->data = NULL; - } - return ret; -} - -static int policy_cache_new(X509 *x) -{ - X509_POLICY_CACHE *cache; - ASN1_INTEGER *ext_any = NULL; - POLICY_CONSTRAINTS *ext_pcons = NULL; - CERTIFICATEPOLICIES *ext_cpols = NULL; - POLICY_MAPPINGS *ext_pmaps = NULL; - int i; - cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); - if (!cache) - return 0; - cache->anyPolicy = NULL; - cache->data = NULL; - cache->any_skip = -1; - cache->explicit_skip = -1; - cache->map_skip = -1; - - x->policy_cache = cache; - - /* - * Handle requireExplicitPolicy *first*. Need to process this even if we - * don't have any policies. - */ - ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); - - if (!ext_pcons) { - if (i != -1) - goto bad_cache; - } else { - if (!ext_pcons->requireExplicitPolicy - && !ext_pcons->inhibitPolicyMapping) - goto bad_cache; - if (!policy_cache_set_int(&cache->explicit_skip, - ext_pcons->requireExplicitPolicy)) - goto bad_cache; - if (!policy_cache_set_int(&cache->map_skip, - ext_pcons->inhibitPolicyMapping)) - goto bad_cache; - } - - /* Process CertificatePolicies */ - - ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); - /* - * If no CertificatePolicies extension or problem decoding then there is - * no point continuing because the valid policies will be NULL. - */ - if (!ext_cpols) { - /* If not absent some problem with extension */ - if (i != -1) - goto bad_cache; - return 1; - } - - i = policy_cache_create(x, ext_cpols, i); - - /* NB: ext_cpols freed by policy_cache_set_policies */ - - if (i <= 0) - return i; - - ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); - - if (!ext_pmaps) { - /* If not absent some problem with extension */ - if (i != -1) - goto bad_cache; - } else { - i = policy_cache_set_mapping(x, ext_pmaps); - if (i <= 0) - goto bad_cache; - } - - ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); - - if (!ext_any) { - if (i != -1) - goto bad_cache; - } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) - goto bad_cache; - - if (0) { - bad_cache: - x->ex_flags |= EXFLAG_INVALID_POLICY; - } - - if (ext_pcons) - POLICY_CONSTRAINTS_free(ext_pcons); - - if (ext_any) - ASN1_INTEGER_free(ext_any); - - return 1; - -} - -void policy_cache_free(X509_POLICY_CACHE *cache) -{ - if (!cache) - return; - if (cache->anyPolicy) - policy_data_free(cache->anyPolicy); - if (cache->data) - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); - OPENSSL_free(cache); -} - -/* - * g_x509_policy_cache_lock is used to protect against concurrent calls to - * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in - * the |X509| structure, but |CRYPTO_once_t| isn't public. - */ -static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock = - CRYPTO_STATIC_MUTEX_INIT; - -const X509_POLICY_CACHE *policy_cache_set(X509 *x) -{ - X509_POLICY_CACHE *cache; - - CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock); - cache = x->policy_cache; - CRYPTO_STATIC_MUTEX_unlock_read(&g_x509_policy_cache_lock); - - if (cache != NULL) - return cache; - - CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock); - if (x->policy_cache == NULL) - policy_cache_new(x); - cache = x->policy_cache; - CRYPTO_STATIC_MUTEX_unlock_write(&g_x509_policy_cache_lock); - - return cache; -} - -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id) -{ - size_t idx; - X509_POLICY_DATA tmp; - - tmp.valid_policy = (ASN1_OBJECT *)id; - sk_X509_POLICY_DATA_sort(cache->data); - if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp)) - return NULL; - return sk_X509_POLICY_DATA_value(cache->data, idx); -} - -static int policy_data_cmp(const X509_POLICY_DATA **a, - const X509_POLICY_DATA **b) -{ - return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); -} - -static int policy_cache_set_int(long *out, ASN1_INTEGER *value) -{ - if (value == NULL) - return 1; - if (value->type == V_ASN1_NEG_INTEGER) - return 0; - *out = ASN1_INTEGER_get(value); - return 1; -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_data.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_data.c deleted file mode 100644 index f83795d7..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_data.c +++ /dev/null @@ -1,132 +0,0 @@ -/* pcy_data.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include - -#include "internal.h" - -/* Policy Node routines */ - -void policy_data_free(X509_POLICY_DATA *data) -{ - ASN1_OBJECT_free(data->valid_policy); - /* Don't free qualifiers if shared */ - if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) - sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); - sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); - OPENSSL_free(data); -} - -/* - * Create a data based on an existing policy. If 'id' is NULL use the oid in - * the policy, otherwise use 'id'. This behaviour covers the two types of - * data in RFC 3280: data with from a CertificatePolcies extension and - * additional data with just the qualifiers of anyPolicy and ID from another - * source. - */ - -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, - const ASN1_OBJECT *cid, int crit) -{ - X509_POLICY_DATA *ret; - ASN1_OBJECT *id; - if (!policy && !cid) - return NULL; - if (cid) { - id = OBJ_dup(cid); - if (!id) - return NULL; - } else - id = NULL; - ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); - if (!ret) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ASN1_OBJECT_free(id); - return NULL; - } - ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); - if (!ret->expected_policy_set) { - OPENSSL_free(ret); - ASN1_OBJECT_free(id); - return NULL; - } - - if (crit) - ret->flags = POLICY_DATA_FLAG_CRITICAL; - else - ret->flags = 0; - - if (id) - ret->valid_policy = id; - else { - ret->valid_policy = policy->policyid; - policy->policyid = NULL; - } - - if (policy) { - ret->qualifier_set = policy->qualifiers; - policy->qualifiers = NULL; - } else - ret->qualifier_set = NULL; - - return ret; -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_lib.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_lib.c deleted file mode 100644 index 3b752dd2..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_lib.c +++ /dev/null @@ -1,155 +0,0 @@ -/* pcy_lib.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include - -#include "internal.h" - -/* accessor functions */ - -/* X509_POLICY_TREE stuff */ - -int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) -{ - if (!tree) - return 0; - return tree->nlevel; -} - -X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, - int i) -{ - if (!tree || (i < 0) || (i >= tree->nlevel)) - return NULL; - return tree->levels + i; -} - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const - X509_POLICY_TREE - *tree) -{ - if (!tree) - return NULL; - return tree->auth_policies; -} - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const - X509_POLICY_TREE - *tree) -{ - if (!tree) - return NULL; - if (tree->flags & POLICY_FLAG_ANY_POLICY) - return tree->auth_policies; - else - return tree->user_policies; -} - -/* X509_POLICY_LEVEL stuff */ - -int X509_policy_level_node_count(X509_POLICY_LEVEL *level) -{ - int n; - if (!level) - return 0; - if (level->anyPolicy) - n = 1; - else - n = 0; - if (level->nodes) - n += sk_X509_POLICY_NODE_num(level->nodes); - return n; -} - -X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) -{ - if (!level) - return NULL; - if (level->anyPolicy) { - if (i == 0) - return level->anyPolicy; - i--; - } - return sk_X509_POLICY_NODE_value(level->nodes, i); -} - -/* X509_POLICY_NODE stuff */ - -const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) -{ - if (!node) - return NULL; - return node->data->valid_policy; -} - -STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const - X509_POLICY_NODE - *node) -{ - if (!node) - return NULL; - return node->data->qualifier_set; -} - -const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE - *node) -{ - if (!node) - return NULL; - return node->parent; -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_map.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_map.c deleted file mode 100644 index c96777f4..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_map.c +++ /dev/null @@ -1,131 +0,0 @@ -/* pcy_map.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include - -#include "../x509/internal.h" -#include "internal.h" - -/* - * Set policy mapping entries in cache. Note: this modifies the passed - * POLICY_MAPPINGS structure - */ - -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) -{ - POLICY_MAPPING *map; - X509_POLICY_DATA *data; - X509_POLICY_CACHE *cache = x->policy_cache; - size_t i; - int ret = 0; - if (sk_POLICY_MAPPING_num(maps) == 0) { - ret = -1; - goto bad_mapping; - } - for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { - map = sk_POLICY_MAPPING_value(maps, i); - /* Reject if map to or from anyPolicy */ - if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) - || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { - ret = -1; - goto bad_mapping; - } - - /* Attempt to find matching policy data */ - data = policy_cache_find_data(cache, map->issuerDomainPolicy); - /* If we don't have anyPolicy can't map */ - if (!data && !cache->anyPolicy) - continue; - - /* Create a NODE from anyPolicy */ - if (!data) { - data = policy_data_new(NULL, map->issuerDomainPolicy, - cache->anyPolicy->flags - & POLICY_DATA_FLAG_CRITICAL); - if (!data) - goto bad_mapping; - data->qualifier_set = cache->anyPolicy->qualifier_set; - /* - * map->issuerDomainPolicy = NULL; - */ - data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!sk_X509_POLICY_DATA_push(cache->data, data)) { - policy_data_free(data); - goto bad_mapping; - } - } else - data->flags |= POLICY_DATA_FLAG_MAPPED; - if (!sk_ASN1_OBJECT_push(data->expected_policy_set, - map->subjectDomainPolicy)) - goto bad_mapping; - map->subjectDomainPolicy = NULL; - - } - - ret = 1; - bad_mapping: - if (ret == -1) - x->ex_flags |= EXFLAG_INVALID_POLICY; - sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); - return ret; - -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_node.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_node.c deleted file mode 100644 index aa28056b..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_node.c +++ /dev/null @@ -1,189 +0,0 @@ -/* pcy_node.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include -#include -#include -#include - -#include "internal.h" - -static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **b) -{ - return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); -} - -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) -{ - return sk_X509_POLICY_NODE_new(node_cmp); -} - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, - const ASN1_OBJECT *id) -{ - X509_POLICY_DATA n; - X509_POLICY_NODE l; - size_t idx; - - n.valid_policy = (ASN1_OBJECT *)id; - l.data = &n; - - sk_X509_POLICY_NODE_sort(nodes); - if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l)) - return NULL; - - return sk_X509_POLICY_NODE_value(nodes, idx); - -} - -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id) -{ - X509_POLICY_NODE *node; - size_t i; - for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { - node = sk_X509_POLICY_NODE_value(level->nodes, i); - if (node->parent == parent) { - if (!OBJ_cmp(node->data->valid_policy, id)) - return node; - } - } - return NULL; -} - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree) -{ - X509_POLICY_NODE *node; - node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); - if (!node) - return NULL; - node->data = data; - node->parent = parent; - node->nchild = 0; - if (level) { - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { - if (level->anyPolicy) - goto node_error; - level->anyPolicy = node; - } else { - - if (!level->nodes) - level->nodes = policy_node_cmp_new(); - if (!level->nodes) - goto node_error; - if (!sk_X509_POLICY_NODE_push(level->nodes, node)) - goto node_error; - } - } - - if (tree) { - if (!tree->extra_data) - tree->extra_data = sk_X509_POLICY_DATA_new_null(); - if (!tree->extra_data) - goto node_error; - if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) - goto node_error; - } - - if (parent) - parent->nchild++; - - return node; - - node_error: - policy_node_free(node); - return 0; - -} - -void policy_node_free(X509_POLICY_NODE *node) -{ - OPENSSL_free(node); -} - -/* - * See if a policy node matches a policy OID. If mapping enabled look through - * expected policy set otherwise just valid policy. - */ - -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) -{ - size_t i; - ASN1_OBJECT *policy_oid; - const X509_POLICY_DATA *x = node->data; - - if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) - || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { - if (!OBJ_cmp(x->valid_policy, oid)) - return 1; - return 0; - } - - for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { - policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); - if (!OBJ_cmp(policy_oid, oid)) - return 1; - } - return 0; - -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/pcy_tree.c b/third_party/boringssl/kit/src/crypto/x509v3/pcy_tree.c deleted file mode 100644 index 9e655286..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/pcy_tree.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "../internal.h" -#include "../x509/internal.h" -#include "internal.h" - -/* - * Enable this to print out the complete policy tree at various point during - * evaluation. - */ - -/* - * #define OPENSSL_POLICY_DEBUG - */ - -#ifdef OPENSSL_POLICY_DEBUG - -static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, - X509_POLICY_NODE *node, int indent) -{ - if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) - || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) - BIO_puts(err, " Not Mapped\n"); - else { - int i; - STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; - ASN1_OBJECT *oid; - BIO_puts(err, " Expected: "); - for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { - oid = sk_ASN1_OBJECT_value(pset, i); - if (i) - BIO_puts(err, ", "); - i2a_ASN1_OBJECT(err, oid); - } - BIO_puts(err, "\n"); - } -} - -static void tree_print(char *str, X509_POLICY_TREE *tree, - X509_POLICY_LEVEL *curr) -{ - X509_POLICY_LEVEL *plev; - X509_POLICY_NODE *node; - int i; - BIO *err; - err = BIO_new_fp(stderr, BIO_NOCLOSE); - if (!curr) - curr = tree->levels + tree->nlevel; - else - curr++; - BIO_printf(err, "Level print after %s\n", str); - BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); - for (plev = tree->levels; plev != curr; plev++) { - BIO_printf(err, "Level %ld, flags = %x\n", - plev - tree->levels, plev->flags); - for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { - node = sk_X509_POLICY_NODE_value(plev->nodes, i); - X509_POLICY_NODE_print(err, node, 2); - expected_print(err, plev, node, 2); - BIO_printf(err, " Flags: %x\n", node->data->flags); - } - if (plev->anyPolicy) - X509_POLICY_NODE_print(err, plev->anyPolicy, 2); - } - - BIO_free(err); - -} -#else - -# define tree_print(a,b,c) /* */ - -#endif - -/*- - * Initialize policy tree. Return values: - * 0 Some internal error occurred. - * -1 Inconsistent or invalid extensions in certificates. - * 1 Tree initialized OK. - * 2 Policy tree is empty. - * 5 Tree OK and requireExplicitPolicy true. - * 6 Tree empty and requireExplicitPolicy true. - */ - -static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, - unsigned int flags) -{ - X509_POLICY_TREE *tree; - X509_POLICY_LEVEL *level; - const X509_POLICY_CACHE *cache; - X509_POLICY_DATA *data = NULL; - X509 *x; - int ret = 1; - int i, n; - int explicit_policy; - int any_skip; - int map_skip; - *ptree = NULL; - n = sk_X509_num(certs); - -#if 0 - /* Disable policy mapping for now... */ - flags |= X509_V_FLAG_INHIBIT_MAP; -#endif - - if (flags & X509_V_FLAG_EXPLICIT_POLICY) - explicit_policy = 0; - else - explicit_policy = n + 1; - - if (flags & X509_V_FLAG_INHIBIT_ANY) - any_skip = 0; - else - any_skip = n + 1; - - if (flags & X509_V_FLAG_INHIBIT_MAP) - map_skip = 0; - else - map_skip = n + 1; - - /* Can't do anything with just a trust anchor */ - if (n == 1) - return 1; - /* - * First setup policy cache in all certificates apart from the trust - * anchor. Note any bad cache results on the way. Also can calculate - * explicit_policy value at this point. - */ - for (i = n - 2; i >= 0; i--) { - x = sk_X509_value(certs, i); - X509_check_purpose(x, -1, -1); - cache = policy_cache_set(x); - /* If cache NULL something bad happened: return immediately */ - if (cache == NULL) - return 0; - /* - * If inconsistent extensions keep a note of it but continue - */ - if (x->ex_flags & EXFLAG_INVALID_POLICY) - ret = -1; - /* - * Otherwise if we have no data (hence no CertificatePolicies) and - * haven't already set an inconsistent code note it. - */ - else if ((ret == 1) && !cache->data) - ret = 2; - if (explicit_policy > 0) { - if (!(x->ex_flags & EXFLAG_SI)) - explicit_policy--; - if ((cache->explicit_skip != -1) - && (cache->explicit_skip < explicit_policy)) - explicit_policy = cache->explicit_skip; - } - } - - if (ret != 1) { - if (ret == 2 && !explicit_policy) - return 6; - return ret; - } - - /* If we get this far initialize the tree */ - - tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); - - if (!tree) - return 0; - - tree->flags = 0; - tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); - tree->nlevel = 0; - tree->extra_data = NULL; - tree->auth_policies = NULL; - tree->user_policies = NULL; - - if (!tree->levels) { - OPENSSL_free(tree); - return 0; - } - - OPENSSL_memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); - - tree->nlevel = n; - - level = tree->levels; - - /* Root data: initialize to anyPolicy */ - - data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); - - if (!data || !level_add_node(level, data, NULL, tree)) - goto bad_tree; - - for (i = n - 2; i >= 0; i--) { - level++; - x = sk_X509_value(certs, i); - cache = policy_cache_set(x); - X509_up_ref(x); - level->cert = x; - - if (!cache->anyPolicy) - level->flags |= X509_V_FLAG_INHIBIT_ANY; - - /* Determine inhibit any and inhibit map flags */ - if (any_skip == 0) { - /* - * Any matching allowed if certificate is self issued and not the - * last in the chain. - */ - if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) - level->flags |= X509_V_FLAG_INHIBIT_ANY; - } else { - if (!(x->ex_flags & EXFLAG_SI)) - any_skip--; - if ((cache->any_skip >= 0) - && (cache->any_skip < any_skip)) - any_skip = cache->any_skip; - } - - if (map_skip == 0) - level->flags |= X509_V_FLAG_INHIBIT_MAP; - else { - if (!(x->ex_flags & EXFLAG_SI)) - map_skip--; - if ((cache->map_skip >= 0) - && (cache->map_skip < map_skip)) - map_skip = cache->map_skip; - } - - } - - *ptree = tree; - - if (explicit_policy) - return 1; - else - return 5; - - bad_tree: - - X509_policy_tree_free(tree); - - return 0; - -} - -static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, - X509_POLICY_DATA *data) -{ - X509_POLICY_LEVEL *last = curr - 1; - X509_POLICY_NODE *node; - int matched = 0; - size_t i; - /* Iterate through all in nodes linking matches */ - for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { - node = sk_X509_POLICY_NODE_value(last->nodes, i); - if (policy_node_match(last, node, data->valid_policy)) { - if (!level_add_node(curr, data, node, NULL)) - return 0; - matched = 1; - } - } - if (!matched && last->anyPolicy) { - if (!level_add_node(curr, data, last->anyPolicy, NULL)) - return 0; - } - return 1; -} - -/* - * This corresponds to RFC 3280 6.1.3(d)(1): link any data from - * CertificatePolicies onto matching parent or anyPolicy if no match. - */ - -static int tree_link_nodes(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache) -{ - size_t i; - X509_POLICY_DATA *data; - - for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { - data = sk_X509_POLICY_DATA_value(cache->data, i); - /* - * If a node is mapped any it doesn't have a corresponding - * CertificatePolicies entry. However such an identical node would - * be created if anyPolicy matching is enabled because there would be - * no match with the parent valid_policy_set. So we create link - * because then it will have the mapping flags right and we can prune - * it later. - */ -#if 0 - if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) - && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) - continue; -#endif - /* Look for matching nodes in previous level */ - if (!tree_link_matching_nodes(curr, data)) - return 0; - } - return 1; -} - -/* - * This corresponds to RFC 3280 6.1.3(d)(2): Create new data for any unmatched - * policies in the parent and link to anyPolicy. - */ - -static int tree_add_unmatched(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id, - X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -{ - X509_POLICY_DATA *data; - if (id == NULL) - id = node->data->valid_policy; - /* - * Create a new node with qualifiers from anyPolicy and id from unmatched - * node. - */ - data = policy_data_new(NULL, id, node_critical(node)); - - if (data == NULL) - return 0; - /* Curr may not have anyPolicy */ - data->qualifier_set = cache->anyPolicy->qualifier_set; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!level_add_node(curr, data, node, tree)) { - policy_data_free(data); - return 0; - } - - return 1; -} - -static int tree_link_unmatched(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -{ - const X509_POLICY_LEVEL *last = curr - 1; - size_t i; - - if ((last->flags & X509_V_FLAG_INHIBIT_MAP) - || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { - /* If no policy mapping: matched if one child present */ - if (node->nchild) - return 1; - if (!tree_add_unmatched(curr, cache, NULL, node, tree)) - return 0; - /* Add it */ - } else { - /* If mapping: matched if one child per expected policy set */ - STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; - if ((size_t)node->nchild == sk_ASN1_OBJECT_num(expset)) - return 1; - /* Locate unmatched nodes */ - for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { - ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); - if (level_find_node(curr, node, oid)) - continue; - if (!tree_add_unmatched(curr, cache, oid, node, tree)) - return 0; - } - - } - - return 1; - -} - -static int tree_link_any(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - X509_POLICY_TREE *tree) -{ - size_t i; - /* - * X509_POLICY_DATA *data; - */ - X509_POLICY_NODE *node; - X509_POLICY_LEVEL *last = curr - 1; - - for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { - node = sk_X509_POLICY_NODE_value(last->nodes, i); - - if (!tree_link_unmatched(curr, cache, node, tree)) - return 0; - -#if 0 - - /* - * Skip any node with any children: we only want unmathced nodes. - * Note: need something better for policy mapping because each node - * may have multiple children - */ - if (node->nchild) - continue; - - /* - * Create a new node with qualifiers from anyPolicy and id from - * unmatched node. - */ - data = policy_data_new(NULL, node->data->valid_policy, - node_critical(node)); - - if (data == NULL) - return 0; - /* Curr may not have anyPolicy */ - data->qualifier_set = cache->anyPolicy->qualifier_set; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!level_add_node(curr, data, node, tree)) { - policy_data_free(data); - return 0; - } -#endif - - } - /* Finally add link to anyPolicy */ - if (last->anyPolicy) { - if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL)) - return 0; - } - return 1; -} - -/* - * Prune the tree: delete any child mapped child data on the current level - * then proceed up the tree deleting any data with no children. If we ever - * have no data on a level we can halt because the tree will be empty. - */ - -static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) -{ - STACK_OF(X509_POLICY_NODE) *nodes; - X509_POLICY_NODE *node; - int i; - nodes = curr->nodes; - if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { - for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node = sk_X509_POLICY_NODE_value(nodes, i); - /* Delete any mapped data: see RFC 3280 XXXX */ - if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { - node->parent->nchild--; - OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(nodes, i); - } - } - } - - for (;;) { - --curr; - nodes = curr->nodes; - for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node = sk_X509_POLICY_NODE_value(nodes, i); - if (node->nchild == 0) { - node->parent->nchild--; - OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(nodes, i); - } - } - if (curr->anyPolicy && !curr->anyPolicy->nchild) { - if (curr->anyPolicy->parent) - curr->anyPolicy->parent->nchild--; - OPENSSL_free(curr->anyPolicy); - curr->anyPolicy = NULL; - } - if (curr == tree->levels) { - /* If we zapped anyPolicy at top then tree is empty */ - if (!curr->anyPolicy) - return 2; - return 1; - } - } - -} - -static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, - X509_POLICY_NODE *pcy) -{ - if (!*pnodes) { - *pnodes = policy_node_cmp_new(); - if (!*pnodes) - return 0; - } else { - sk_X509_POLICY_NODE_sort(*pnodes); - if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy)) - return 1; - } - if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) - return 0; - - return 1; - -} - -/* - * Calculate the authority set based on policy tree. The 'pnodes' parameter - * is used as a store for the set of policy nodes used to calculate the user - * set. If the authority set is not anyPolicy then pnodes will just point to - * the authority set. If however the authority set is anyPolicy then the set - * of valid policies (other than anyPolicy) is store in pnodes. The return - * value of '2' is used in this case to indicate that pnodes should be freed. - */ - -static int tree_calculate_authority_set(X509_POLICY_TREE *tree, - STACK_OF(X509_POLICY_NODE) **pnodes) -{ - X509_POLICY_LEVEL *curr; - X509_POLICY_NODE *node, *anyptr; - STACK_OF(X509_POLICY_NODE) **addnodes; - int i; - size_t j; - curr = tree->levels + tree->nlevel - 1; - - /* If last level contains anyPolicy set is anyPolicy */ - if (curr->anyPolicy) { - if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) - return 0; - addnodes = pnodes; - } else - /* Add policies to authority set */ - addnodes = &tree->auth_policies; - - curr = tree->levels; - for (i = 1; i < tree->nlevel; i++) { - /* - * If no anyPolicy node on this this level it can't appear on lower - * levels so end search. - */ - if (!(anyptr = curr->anyPolicy)) - break; - curr++; - for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { - node = sk_X509_POLICY_NODE_value(curr->nodes, j); - if ((node->parent == anyptr) - && !tree_add_auth_node(addnodes, node)) - return 0; - } - } - - if (addnodes == pnodes) - return 2; - - *pnodes = tree->auth_policies; - - return 1; -} - -static int tree_calculate_user_set(X509_POLICY_TREE *tree, - STACK_OF(ASN1_OBJECT) *policy_oids, - STACK_OF(X509_POLICY_NODE) *auth_nodes) -{ - size_t i; - X509_POLICY_NODE *node; - ASN1_OBJECT *oid; - - X509_POLICY_NODE *anyPolicy; - X509_POLICY_DATA *extra; - - /* - * Check if anyPolicy present in authority constrained policy set: this - * will happen if it is a leaf node. - */ - - if (sk_ASN1_OBJECT_num(policy_oids) <= 0) - return 1; - - anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; - - for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { - oid = sk_ASN1_OBJECT_value(policy_oids, i); - if (OBJ_obj2nid(oid) == NID_any_policy) { - tree->flags |= POLICY_FLAG_ANY_POLICY; - return 1; - } - } - - for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { - oid = sk_ASN1_OBJECT_value(policy_oids, i); - node = tree_find_sk(auth_nodes, oid); - if (!node) { - if (!anyPolicy) - continue; - /* - * Create a new node with policy ID from user set and qualifiers - * from anyPolicy. - */ - extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); - if (!extra) - return 0; - extra->qualifier_set = anyPolicy->data->qualifier_set; - extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS - | POLICY_DATA_FLAG_EXTRA_NODE; - node = level_add_node(NULL, extra, anyPolicy->parent, tree); - } - if (!tree->user_policies) { - tree->user_policies = sk_X509_POLICY_NODE_new_null(); - if (!tree->user_policies) - return 1; - } - if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) - return 0; - } - return 1; - -} - -static int tree_evaluate(X509_POLICY_TREE *tree) -{ - int ret, i; - X509_POLICY_LEVEL *curr = tree->levels + 1; - const X509_POLICY_CACHE *cache; - - for (i = 1; i < tree->nlevel; i++, curr++) { - cache = policy_cache_set(curr->cert); - if (!tree_link_nodes(curr, cache)) - return 0; - - if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) - && !tree_link_any(curr, cache, tree)) - return 0; - tree_print("before tree_prune()", tree, curr); - ret = tree_prune(tree, curr); - if (ret != 1) - return ret; - } - - return 1; - -} - -static void exnode_free(X509_POLICY_NODE *node) -{ - if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) - OPENSSL_free(node); -} - -void X509_policy_tree_free(X509_POLICY_TREE *tree) -{ - X509_POLICY_LEVEL *curr; - int i; - - if (!tree) - return; - - sk_X509_POLICY_NODE_free(tree->auth_policies); - sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); - - for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { - if (curr->cert) - X509_free(curr->cert); - if (curr->nodes) - sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); - if (curr->anyPolicy) - policy_node_free(curr->anyPolicy); - } - - if (tree->extra_data) - sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); - - OPENSSL_free(tree->levels); - OPENSSL_free(tree); - -} - -/*- - * Application policy checking function. - * Return codes: - * 0 Internal Error. - * 1 Successful. - * -1 One or more certificates contain invalid or inconsistent extensions - * -2 User constrained policy set empty and requireExplicit true. - */ - -int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, - STACK_OF(X509) *certs, - STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) -{ - int ret; - int calc_ret; - X509_POLICY_TREE *tree = NULL; - STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; - *ptree = NULL; - - *pexplicit_policy = 0; - ret = tree_init(&tree, certs, flags); - - switch (ret) { - - /* Tree empty requireExplicit False: OK */ - case 2: - return 1; - - /* Some internal error */ - case -1: - return -1; - - /* Some internal error */ - case 0: - return 0; - - /* Tree empty requireExplicit True: Error */ - - case 6: - *pexplicit_policy = 1; - return -2; - - /* Tree OK requireExplicit True: OK and continue */ - case 5: - *pexplicit_policy = 1; - break; - - /* Tree OK: continue */ - - case 1: - if (!tree) - /* - * tree_init() returns success and a null tree - * if it's just looking at a trust anchor. - * I'm not sure that returning success here is - * correct, but I'm sure that reporting this - * as an internal error which our caller - * interprets as a malloc failure is wrong. - */ - return 1; - break; - } - - if (!tree) - goto error; - ret = tree_evaluate(tree); - - tree_print("tree_evaluate()", tree, NULL); - - if (ret <= 0) - goto error; - - /* Return value 2 means tree empty */ - if (ret == 2) { - X509_policy_tree_free(tree); - if (*pexplicit_policy) - return -2; - else - return 1; - } - - /* Tree is not empty: continue */ - - calc_ret = tree_calculate_authority_set(tree, &auth_nodes); - - if (!calc_ret) - goto error; - - ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); - - if (calc_ret == 2) - sk_X509_POLICY_NODE_free(auth_nodes); - - if (!ret) - goto error; - - - if (tree) - *ptree = tree; - - if (*pexplicit_policy) { - nodes = X509_policy_tree_get0_user_policies(tree); - if (sk_X509_POLICY_NODE_num(nodes) <= 0) - return -2; - } - - return 1; - - error: - - X509_policy_tree_free(tree); - - return 0; - -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/tab_test.cc b/third_party/boringssl/kit/src/crypto/x509v3/tab_test.cc index bf91a265..b5b662fd 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/tab_test.cc +++ b/third_party/boringssl/kit/src/crypto/x509v3/tab_test.cc @@ -1,4 +1,3 @@ -/* tabtest.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_akey.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_akey.c index 0aba20ed..2af596af 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_akey.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_akey.c @@ -1,4 +1,3 @@ -/* v3_akey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -69,158 +68,154 @@ #include "internal.h" -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, - STACK_OF(CONF_VALUE) - *extlist); -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist); +static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_akey_id = { NID_authority_key_identifier, - X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, - (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, - 0, 0, - NULL + X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_KEYID), + 0, + 0, + 0, + 0, + 0, + 0, + i2v_AUTHORITY_KEYID, + v2i_AUTHORITY_KEYID, + 0, + 0, + NULL, }; -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, - STACK_OF(CONF_VALUE) - *extlist) -{ - char *tmp = NULL; - int extlist_was_null = extlist == NULL; - if (akeyid->keyid) { - tmp = x509v3_bytes_to_hex(akeyid->keyid->data, akeyid->keyid->length); - int ok = tmp != NULL && X509V3_add_value("keyid", tmp, &extlist); - OPENSSL_free(tmp); - if (!ok) { - goto err; - } +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist) { + const AUTHORITY_KEYID *akeyid = ext; + int extlist_was_null = extlist == NULL; + if (akeyid->keyid) { + char *tmp = x509v3_bytes_to_hex(akeyid->keyid->data, akeyid->keyid->length); + int ok = tmp != NULL && X509V3_add_value("keyid", tmp, &extlist); + OPENSSL_free(tmp); + if (!ok) { + goto err; } - if (akeyid->issuer) { - STACK_OF(CONF_VALUE) *tmpextlist = - i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); - if (tmpextlist == NULL) { - goto err; - } - extlist = tmpextlist; + } + if (akeyid->issuer) { + STACK_OF(CONF_VALUE) *tmpextlist = + i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); + if (tmpextlist == NULL) { + goto err; } - if (akeyid->serial) { - tmp = x509v3_bytes_to_hex(akeyid->serial->data, akeyid->serial->length); - int ok = tmp != NULL && X509V3_add_value("serial", tmp, &extlist); - OPENSSL_free(tmp); - if (!ok) { - goto err; - } + extlist = tmpextlist; + } + if (akeyid->serial) { + if (!X509V3_add_value_int("serial", akeyid->serial, &extlist)) { + goto err; } - return extlist; + } + return extlist; err: - if (extlist_was_null) { - sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free); - } - return NULL; + if (extlist_was_null) { + sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free); + } + return NULL; } -/* - * Currently two options: keyid: use the issuers subject keyid, the value - * 'always' means its is an error if the issuer certificate doesn't have a - * key id. issuer: use the issuers cert issuer and serial number. The default - * is to only use this if keyid is not present. With the option 'always' this - * is always included. - */ +// Currently two options: keyid: use the issuers subject keyid, the value +// 'always' means its is an error if the issuer certificate doesn't have a +// key id. issuer: use the issuers cert issuer and serial number. The default +// is to only use this if keyid is not present. With the option 'always' this +// is always included. -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - char keyid = 0, issuer = 0; - size_t i; - int j; - CONF_VALUE *cnf; - ASN1_OCTET_STRING *ikeyid = NULL; - X509_NAME *isname = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - ASN1_INTEGER *serial = NULL; - X509_EXTENSION *ext; - X509 *cert; - AUTHORITY_KEYID *akeyid; +static void *v2i_AUTHORITY_KEYID(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values) { + char keyid = 0, issuer = 0; + int j; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + const X509 *cert; + AUTHORITY_KEYID *akeyid; - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - cnf = sk_CONF_VALUE_value(values, i); - if (!strcmp(cnf->name, "keyid")) { - keyid = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - keyid = 2; - } else if (!strcmp(cnf->name, "issuer")) { - issuer = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - issuer = 2; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION); - ERR_add_error_data(2, "name=", cnf->name); - return NULL; - } + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) { + keyid = 2; + } + } else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) { + issuer = 2; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION); + ERR_add_error_data(2, "name=", cnf->name); + return NULL; } + } - if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) - return AUTHORITY_KEYID_new(); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); - return NULL; + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { + return AUTHORITY_KEYID_new(); } - - cert = ctx->issuer_cert; - - if (keyid) { - j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if ((j >= 0) && (ext = X509_get_ext(cert, j))) - ikeyid = X509V3_EXT_d2i(ext); - if (keyid == 2 && !ikeyid) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); - return NULL; - } - } - - if ((issuer && !ikeyid) || (issuer == 2)) { - isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if (!isname || !serial) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); - goto err; - } - } - - if (!(akeyid = AUTHORITY_KEYID_new())) - goto err; - - if (isname) { - if (!(gens = sk_GENERAL_NAME_new_null()) - || !(gen = GENERAL_NAME_new()) - || !sk_GENERAL_NAME_push(gens, gen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - gen->type = GEN_DIRNAME; - gen->d.dirn = isname; - } - - akeyid->issuer = gens; - akeyid->serial = serial; - akeyid->keyid = ikeyid; - - return akeyid; - - err: - X509_NAME_free(isname); - ASN1_INTEGER_free(serial); - ASN1_OCTET_STRING_free(ikeyid); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + const X509_EXTENSION *ext; + if ((j >= 0) && (ext = X509_get_ext(cert, j))) { + ikeyid = X509V3_EXT_d2i(ext); + } + if (keyid == 2 && !ikeyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); + if (!isname || !serial) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) { + goto err; + } + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) || !(gen = GENERAL_NAME_new()) || + !sk_GENERAL_NAME_push(gens, gen)) { + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + +err: + X509_NAME_free(isname); + ASN1_INTEGER_free(serial); + ASN1_OCTET_STRING_free(ikeyid); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_akeya.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_akeya.c index 844dee52..f18f4e33 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_akeya.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_akeya.c @@ -1,4 +1,3 @@ -/* v3_akey_asn1.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -64,9 +63,9 @@ ASN1_SEQUENCE(AUTHORITY_KEYID) = { - ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), - ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), - ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) + ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), + ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2), } ASN1_SEQUENCE_END(AUTHORITY_KEYID) IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_alt.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_alt.c index ce1c6e58..ddd112a2 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_alt.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_alt.c @@ -1,4 +1,3 @@ -/* v3_alt.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -68,573 +67,570 @@ #include "internal.h" -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); -static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); +static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx); + +static STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES_cb( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) { + return i2v_GENERAL_NAMES(method, ext, ret); +} const X509V3_EXT_METHOD v3_alt[] = { - {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - (X509V3_EXT_V2I)v2i_subject_alt, - NULL, NULL, NULL}, + {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0, + i2v_GENERAL_NAMES_cb, v2i_subject_alt, NULL, NULL, NULL}, - {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - (X509V3_EXT_V2I)v2i_issuer_alt, - NULL, NULL, NULL}, + {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0, + i2v_GENERAL_NAMES_cb, v2i_issuer_alt, NULL, NULL, NULL}, - {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - NULL, NULL, NULL, NULL}, + {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0, + i2v_GENERAL_NAMES_cb, NULL, NULL, NULL, NULL}, }; -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, - GENERAL_NAMES *gens, - STACK_OF(CONF_VALUE) *ret) -{ - int ret_was_null = ret == NULL; - for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); - STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret); - if (tmp == NULL) { - if (ret_was_null) { - sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); - } - return NULL; - } - ret = tmp; +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + const GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) { + int ret_was_null = ret == NULL; + for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); + STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret); + if (tmp == NULL) { + if (ret_was_null) { + sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); + } + return NULL; } - if (!ret) - return sk_CONF_VALUE_new_null(); - return ret; + ret = tmp; + } + if (!ret) { + return sk_CONF_VALUE_new_null(); + } + return ret; } -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, - GENERAL_NAME *gen, - STACK_OF(CONF_VALUE) *ret) -{ - /* Note the error-handling for this function relies on there being at most - * one |X509V3_add_value| call. If there were two and the second failed, we - * would need to sometimes free the first call's result. */ - unsigned char *p; - char oline[256], htmp[5]; - int i; - switch (gen->type) { +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(const X509V3_EXT_METHOD *method, + const GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) { + // Note the error-handling for this function relies on there being at most + // one |X509V3_add_value| call. If there were two and the second failed, we + // would need to sometimes free the first call's result. + unsigned char *p; + char oline[256], htmp[5]; + int i; + switch (gen->type) { case GEN_OTHERNAME: - if (!X509V3_add_value("othername", "", &ret)) - return NULL; - break; - - case GEN_X400: - if (!X509V3_add_value("X400Name", "", &ret)) - return NULL; - break; - - case GEN_EDIPARTY: - if (!X509V3_add_value("EdiPartyName", "", &ret)) - return NULL; - break; - - case GEN_EMAIL: - if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret)) - return NULL; - break; - - case GEN_DNS: - if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret)) - return NULL; - break; - - case GEN_URI: - if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret)) - return NULL; - break; - - case GEN_DIRNAME: - if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL - || !X509V3_add_value("DirName", oline, &ret)) - return NULL; - break; - - case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_snprintf(oline, sizeof oline, - "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - oline[0] = 0; - for (i = 0; i < 8; i++) { - BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); - p += 2; - OPENSSL_strlcat(oline, htmp, sizeof(oline)); - if (i != 7) - OPENSSL_strlcat(oline, ":", sizeof(oline)); - } - } else { - if (!X509V3_add_value("IP Address", "", &ret)) - return NULL; - break; - } - if (!X509V3_add_value("IP Address", oline, &ret)) - return NULL; - break; - - case GEN_RID: - i2t_ASN1_OBJECT(oline, 256, gen->d.rid); - if (!X509V3_add_value("Registered ID", oline, &ret)) - return NULL; - break; - } - return ret; -} - -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) -{ - unsigned char *p; - int i; - switch (gen->type) { - case GEN_OTHERNAME: - BIO_printf(out, "othername:"); - break; - - case GEN_X400: - BIO_printf(out, "X400Name:"); - break; - - case GEN_EDIPARTY: - /* Maybe fix this: it is supported now */ - BIO_printf(out, "EdiPartyName:"); - break; - - case GEN_EMAIL: - BIO_printf(out, "email:"); - ASN1_STRING_print(out, gen->d.ia5); - break; - - case GEN_DNS: - BIO_printf(out, "DNS:"); - ASN1_STRING_print(out, gen->d.ia5); - break; - - case GEN_URI: - BIO_printf(out, "URI:"); - ASN1_STRING_print(out, gen->d.ia5); - break; - - case GEN_DIRNAME: - BIO_printf(out, "DirName: "); - X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); - break; - - case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) { - BIO_printf(out, ":%X", p[0] << 8 | p[1]); - p += 2; - } - BIO_puts(out, "\n"); - } else { - BIO_printf(out, "IP Address:"); - break; - } - break; - - case GEN_RID: - BIO_printf(out, "Registered ID"); - i2a_ASN1_OBJECT(out, gen->d.rid); - break; - } - return 1; -} - -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - size_t i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (!X509V3_add_value("othername", "", &ret)) { return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!x509v3_name_cmp(cnf->name, "issuer") && cnf->value && - !strcmp(cnf->value, "copy")) { - if (!copy_issuer(ctx, gens)) - goto err; - } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); + } + break; + + case GEN_X400: + if (!X509V3_add_value("X400Name", "", &ret)) { + return NULL; + } + break; + + case GEN_EDIPARTY: + if (!X509V3_add_value("EdiPartyName", "", &ret)) { + return NULL; + } + break; + + case GEN_EMAIL: + if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret)) { + return NULL; + } + break; + + case GEN_DNS: + if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret)) { + return NULL; + } + break; + + case GEN_URI: + if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret)) { + return NULL; + } + break; + + case GEN_DIRNAME: + if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL || + !X509V3_add_value("DirName", oline, &ret)) { + return NULL; + } + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) { + BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d", p[0], p[1], p[2], + p[3]); + } else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_snprintf(htmp, sizeof(htmp), "%X", v); + p += 2; + OPENSSL_strlcat(oline, htmp, sizeof(oline)); + if (i != 7) { + OPENSSL_strlcat(oline, ":", sizeof(oline)); + } } - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; + } else { + if (!X509V3_add_value("IP Address", "", &ret)) { + return NULL; + } + break; + } + if (!X509V3_add_value("IP Address", oline, &ret)) { + return NULL; + } + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + if (!X509V3_add_value("Registered ID", oline, &ret)) { + return NULL; + } + break; + } + return ret; } -/* Append subject altname of issuer to issuer alt name of subject */ +int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen) { + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) -{ - if (ctx && (ctx->flags == CTX_TEST)) - return 1; - if (!ctx || !ctx->issuer_cert) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS); - return 0; - } - int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); - if (i < 0) - return 1; + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; - int ret = 0; - GENERAL_NAMES *ialt = NULL; - X509_EXTENSION *ext; - if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR); - goto err; - } + case GEN_EDIPARTY: + // Maybe fix this: it is supported now + BIO_printf(out, "EdiPartyName:"); + break; - for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j); - if (!sk_GENERAL_NAME_push(gens, gen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; + case GEN_EMAIL: + BIO_printf(out, "email:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_URI: + BIO_printf(out, "URI:"); + ASN1_STRING_print(out, gen->d.ia5); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: { + const unsigned char *p = gen->d.ip->data; + if (gen->d.ip->length == 4) { + BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + } else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (int i = 0; i < 8; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_printf(out, ":%X", v); + p += 2; } - /* Ownership of |gen| has moved from |ialt| to |gens|. */ - sk_GENERAL_NAME_set(ialt, j, NULL); + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; } - ret = 1; + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} + +static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { + return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (x509v3_conf_name_matches(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_issuer(ctx, gens)) { + goto err; + } + } else { + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +// Append subject altname of issuer to issuer alt name of subject + +static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens) { + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { + return 1; + } + if (!ctx || !ctx->issuer_cert) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS); + return 0; + } + int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) { + return 1; + } + + int ret = 0; + GENERAL_NAMES *ialt = NULL; + X509_EXTENSION *ext; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j); + if (!sk_GENERAL_NAME_push(gens, gen)) { + goto err; + } + // Ownership of |gen| has moved from |ialt| to |gens|. + sk_GENERAL_NAME_set(ialt, j, NULL); + } + + ret = 1; err: - GENERAL_NAMES_free(ialt); - return ret; + GENERAL_NAMES_free(ialt); + return ret; } -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - size_t i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "copy")) { - if (!copy_email(ctx, gens, 0)) - goto err; - } else if (!x509v3_name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "move")) { - if (!copy_email(ctx, gens, 1)) - goto err; - } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); - } - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); +static void *v2i_subject_alt(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) { + goto err; + } + } else if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) { + goto err; + } + } else { + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; } -/* - * Copy any email addresses in a certificate or request to GENERAL_NAMES - */ - -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) -{ - X509_NAME *nm; - ASN1_IA5STRING *email = NULL; - X509_NAME_ENTRY *ne; - GENERAL_NAME *gen = NULL; - int i; - if (ctx != NULL && ctx->flags == CTX_TEST) - return 1; - if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS); - goto err; - } - /* Find the subject name */ - if (ctx->subject_cert) - nm = X509_get_subject_name(ctx->subject_cert); - else - nm = X509_REQ_get_subject_name(ctx->subject_req); - - /* Now add any email address(es) to STACK */ - i = -1; - while ((i = X509_NAME_get_index_by_NID(nm, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(nm, i); - email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); - if (move_p) { - X509_NAME_delete_entry(nm, i); - X509_NAME_ENTRY_free(ne); - i--; - } - if (!email || !(gen = GENERAL_NAME_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - gen->d.ia5 = email; - email = NULL; - gen->type = GEN_EMAIL; - if (!sk_GENERAL_NAME_push(gens, gen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - gen = NULL; - } +// Copy any email addresses in a certificate or request to GENERAL_NAMES +static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) { + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + if (ctx != NULL && ctx->flags == X509V3_CTX_TEST) { return 1; + } + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + // Find the subject name + if (ctx->subject_cert) { + nm = X509_get_subject_name(ctx->subject_cert); + } else { + nm = X509_REQ_get_subject_name(ctx->subject_req); + } - err: - GENERAL_NAME_free(gen); - ASN1_IA5STRING_free(email); - return 0; + // Now add any email address(es) to STACK + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + goto err; + } + gen = NULL; + } + return 1; + +err: + GENERAL_NAME_free(gen); + ASN1_IA5STRING_free(email); + return 0; } GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAME *gen; - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - size_t i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null(); + if (gens == NULL) { return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) { + GENERAL_NAME_free(gen); + goto err; + } + } + return gens; +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; } GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf) -{ - return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); + const X509V3_CTX *ctx, const CONF_VALUE *cnf) { + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); } GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, - const char *value, int is_nc) -{ - char is_string = 0; - GENERAL_NAME *gen = NULL; + const X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc) { + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } - if (!value) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); - return NULL; + GENERAL_NAME *gen = NULL; + if (out) { + gen = out; + } else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + return NULL; } + } - if (out) - gen = out; - else { - gen = GENERAL_NAME_new(); - if (gen == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - } - - switch (gen_type) { + switch (gen_type) { case GEN_URI: case GEN_EMAIL: - case GEN_DNS: - is_string = 1; - break; + case GEN_DNS: { + ASN1_IA5STRING *str = ASN1_IA5STRING_new(); + if (str == NULL || !ASN1_STRING_set(str, value, strlen(value))) { + ASN1_STRING_free(str); + goto err; + } + gen->type = gen_type; + gen->d.ia5 = str; + break; + } - case GEN_RID: - { - ASN1_OBJECT *obj; - if (!(obj = OBJ_txt2obj(value, 0))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", value); - goto err; - } - gen->d.rid = obj; - } - break; + case GEN_RID: { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; + } + gen->type = GEN_RID; + gen->d.rid = obj; + break; + } case GEN_IPADD: - if (is_nc) - gen->d.ip = a2i_IPADDRESS_NC(value); - else - gen->d.ip = a2i_IPADDRESS(value); - if (gen->d.ip == NULL) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS); - ERR_add_error_data(2, "value=", value); - goto err; - } - break; + gen->type = GEN_IPADD; + if (is_nc) { + gen->d.ip = a2i_IPADDRESS_NC(value); + } else { + gen->d.ip = a2i_IPADDRESS(value); + } + if (gen->d.ip == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; case GEN_DIRNAME: - if (!do_dirname(gen, value, ctx)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR); - goto err; - } - break; + if (!do_dirname(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; case GEN_OTHERNAME: - if (!do_othername(gen, value, ctx)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR); - goto err; - } - break; - default: - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE); + if (!do_othername(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR); goto err; - } + } + break; + default: + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE); + goto err; + } - if (is_string) { - if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || - !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, - strlen(value))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - } + return gen; - gen->type = gen_type; - - return gen; - - err: - if (!out) - GENERAL_NAME_free(gen); - return NULL; +err: + if (!out) { + GENERAL_NAME_free(gen); + } + return NULL; } GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) -{ - int type; + const X509V3_CTX *ctx, const CONF_VALUE *cnf, + int is_nc) { + const char *name = cnf->name; + const char *value = cnf->value; + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } - char *name, *value; - - name = cnf->name; - value = cnf->value; - - if (!value) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); - return NULL; - } - - if (!x509v3_name_cmp(name, "email")) - type = GEN_EMAIL; - else if (!x509v3_name_cmp(name, "URI")) - type = GEN_URI; - else if (!x509v3_name_cmp(name, "DNS")) - type = GEN_DNS; - else if (!x509v3_name_cmp(name, "RID")) - type = GEN_RID; - else if (!x509v3_name_cmp(name, "IP")) - type = GEN_IPADD; - else if (!x509v3_name_cmp(name, "dirName")) - type = GEN_DIRNAME; - else if (!x509v3_name_cmp(name, "otherName")) - type = GEN_OTHERNAME; - else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION); - ERR_add_error_data(2, "name=", name); - return NULL; - } - - return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + int type; + if (x509v3_conf_name_matches(name, "email")) { + type = GEN_EMAIL; + } else if (x509v3_conf_name_matches(name, "URI")) { + type = GEN_URI; + } else if (x509v3_conf_name_matches(name, "DNS")) { + type = GEN_DNS; + } else if (x509v3_conf_name_matches(name, "RID")) { + type = GEN_RID; + } else if (x509v3_conf_name_matches(name, "IP")) { + type = GEN_IPADD; + } else if (x509v3_conf_name_matches(name, "dirName")) { + type = GEN_DIRNAME; + } else if (x509v3_conf_name_matches(name, "otherName")) { + type = GEN_OTHERNAME; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + return NULL; + } + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); } -static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -{ - char *objtmp = NULL; - const char *p; - int objlen; - if (!(p = strchr(value, ';'))) - return 0; - if (!(gen->d.otherName = OTHERNAME_new())) - return 0; - /* - * Free this up because we will overwrite it. no need to free type_id - * because it is static - */ - ASN1_TYPE_free(gen->d.otherName->value); - if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) - return 0; - objlen = p - value; - objtmp = OPENSSL_malloc(objlen + 1); - if (objtmp == NULL) - return 0; - OPENSSL_strlcpy(objtmp, value, objlen + 1); - gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); - OPENSSL_free(objtmp); - if (!gen->d.otherName->type_id) - return 0; - return 1; +static int do_othername(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx) { + const char *semicolon = strchr(value, ';'); + if (semicolon == NULL) { + return 0; + } + + OTHERNAME *name = OTHERNAME_new(); + if (name == NULL) { + return 0; + } + + char *objtmp = OPENSSL_strndup(value, semicolon - value); + if (objtmp == NULL) { + goto err; + } + ASN1_OBJECT_free(name->type_id); + name->type_id = OBJ_txt2obj(objtmp, /*dont_search_names=*/0); + OPENSSL_free(objtmp); + if (name->type_id == NULL) { + goto err; + } + + ASN1_TYPE_free(name->value); + name->value = ASN1_generate_v3(semicolon + 1, ctx); + if (name->value == NULL) { + goto err; + } + + gen->type = GEN_OTHERNAME; + gen->d.otherName = name; + return 1; + +err: + OTHERNAME_free(name); + return 0; } -static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -{ - int ret = 0; - STACK_OF(CONF_VALUE) *sk = NULL; - X509_NAME *nm = X509_NAME_new(); - if (nm == NULL) - goto err; - sk = X509V3_get_section(ctx, value); - if (sk == NULL) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); - ERR_add_error_data(2, "section=", value); - goto err; - } - /* FIXME: should allow other character types... */ - if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) - goto err; - gen->d.dirn = nm; - ret = 1; +static int do_dirname(GENERAL_NAME *gen, const char *value, + const X509V3_CTX *ctx) { + int ret = 0; + X509_NAME *nm = X509_NAME_new(); + if (nm == NULL) { + goto err; + } + const STACK_OF(CONF_VALUE) *sk = X509V3_get_section(ctx, value); + if (sk == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + // FIXME: should allow other character types... + if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) { + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = nm; + ret = 1; - err: - if (!ret) - X509_NAME_free(nm); - X509V3_section_free(ctx, sk); - return ret; +err: + if (!ret) { + X509_NAME_free(nm); + } + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_bcons.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_bcons.c index aefefdff..e614b8ec 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_bcons.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_bcons.c @@ -1,4 +1,3 @@ -/* v3_bcons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -65,69 +64,72 @@ #include #include -static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - BASIC_CONSTRAINTS *bcons, - STACK_OF(CONF_VALUE) - *extlist); -static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); +#include "internal.h" + + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist); +static void *v2i_BASIC_CONSTRAINTS(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_bcons = { - NID_basic_constraints, 0, + NID_basic_constraints, + 0, ASN1_ITEM_ref(BASIC_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, - (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, - NULL, NULL, - NULL + 0, + 0, + 0, + 0, + 0, + 0, + i2v_BASIC_CONSTRAINTS, + v2i_BASIC_CONSTRAINTS, + NULL, + NULL, + NULL, }; ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { - ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), - ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) + ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), + ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER), } ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) -IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) +IMPLEMENT_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) -static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - BASIC_CONSTRAINTS *bcons, - STACK_OF(CONF_VALUE) - *extlist) -{ - X509V3_add_value_bool("CA", bcons->ca, &extlist); - X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); - return extlist; +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *extlist) { + const BASIC_CONSTRAINTS *bcons = ext; + X509V3_add_value_bool("CA", bcons->ca, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; } -static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - BASIC_CONSTRAINTS *bcons = NULL; - CONF_VALUE *val; - size_t i; - if (!(bcons = BASIC_CONSTRAINTS_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "CA")) { - if (!X509V3_get_value_bool(val, &bcons->ca)) - goto err; - } else if (!strcmp(val->name, "pathlen")) { - if (!X509V3_get_value_int(val, &bcons->pathlen)) - goto err; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - return bcons; - err: - BASIC_CONSTRAINTS_free(bcons); +static void *v2i_BASIC_CONSTRAINTS(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values) { + BASIC_CONSTRAINTS *bcons = NULL; + if (!(bcons = BASIC_CONSTRAINTS_new())) { return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) { + goto err; + } + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) { + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; +err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_bitst.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_bitst.c index 871b7761..1201738b 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_bitst.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_bitst.c @@ -1,4 +1,3 @@ -/* v3_bitst.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -75,8 +74,7 @@ static const BIT_STRING_BITNAME ns_cert_type_table[] = { {5, "SSL CA", "sslCA"}, {6, "S/MIME CA", "emailCA"}, {7, "Object Signing CA", "objCA"}, - {-1, NULL, NULL} -}; + {-1, NULL, NULL}}; static const BIT_STRING_BITNAME key_usage_type_table[] = { {0, "Digital Signature", "digitalSignature"}, @@ -88,57 +86,56 @@ static const BIT_STRING_BITNAME key_usage_type_table[] = { {6, "CRL Sign", "cRLSign"}, {7, "Encipher Only", "encipherOnly"}, {8, "Decipher Only", "decipherOnly"}, - {-1, NULL, NULL} -}; + {-1, NULL, NULL}}; -const X509V3_EXT_METHOD v3_nscert = -EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); -const X509V3_EXT_METHOD v3_key_usage = -EXT_BITSTRING(NID_key_usage, key_usage_type_table); +static STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) { + const ASN1_BIT_STRING *bits = ext; + const BIT_STRING_BITNAME *bnam; + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) { + X509V3_add_value(bnam->lname, NULL, &ret); + } + } + return ret; +} -STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *ret) -{ +static void *v2i_ASN1_BIT_STRING(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + ASN1_BIT_STRING *bs; + if (!(bs = ASN1_BIT_STRING_new())) { + return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); const BIT_STRING_BITNAME *bnam; for (bnam = method->usr_data; bnam->lname; bnam++) { - if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) - X509V3_add_value(bnam->lname, NULL, &ret); + if (!strcmp(bnam->sname, val->name) || !strcmp(bnam->lname, val->name)) { + if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { + ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } } - return ret; + if (!bnam->lname) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; } -ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - CONF_VALUE *val; - ASN1_BIT_STRING *bs; - size_t i; - const BIT_STRING_BITNAME *bnam; - if (!(bs = ASN1_BIT_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - for (bnam = method->usr_data; bnam->lname; bnam++) { - if (!strcmp(bnam->sname, val->name) || - !strcmp(bnam->lname, val->name)) { - if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ASN1_BIT_STRING_free(bs); - return NULL; - } - break; - } - } - if (!bnam->lname) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); - X509V3_conf_err(val); - ASN1_BIT_STRING_free(bs); - return NULL; - } - } - return bs; -} +#define EXT_BITSTRING(nid, table) \ + { \ + nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), 0, 0, 0, 0, 0, 0, \ + i2v_ASN1_BIT_STRING, v2i_ASN1_BIT_STRING, NULL, NULL, (void *)(table) \ + } + +const X509V3_EXT_METHOD v3_nscert = + EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); +const X509V3_EXT_METHOD v3_key_usage = + EXT_BITSTRING(NID_key_usage, key_usage_type_table); diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_conf.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_conf.c index 31927523..7904c7f7 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_conf.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_conf.c @@ -1,4 +1,3 @@ -/* v3_conf.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -55,9 +54,10 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -/* extension creation utilities */ +// extension creation utilities #include +#include #include #include @@ -74,395 +74,345 @@ static int v3_check_critical(const char **value); static int v3_check_generic(const char **value); -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, const char *value); +static X509_EXTENSION *do_ext_nconf(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, int crit, const char *value); static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, int crit, int type, - X509V3_CTX *ctx); -static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, - int ext_nid, int crit, void *ext_struc); -static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, - long *ext_len); -/* CONF *conf: Config file */ -/* char *name: Name */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, - const char *value) -{ - int crit; - int ext_type; - X509_EXTENSION *ret; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(name, value, crit, ext_type, ctx); - ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); - if (!ret) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION); - ERR_add_error_data(4, "name=", name, ", value=", value); - } - return ret; + const X509V3_CTX *ctx); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc); +static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx, + size_t *ext_len); + +X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *name, const char *value) { + // If omitted, fill in an empty |X509V3_CTX|. + X509V3_CTX ctx_tmp; + if (ctx == NULL) { + X509V3_set_ctx(&ctx_tmp, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx_tmp, conf); + ctx = &ctx_tmp; + } + + int crit = v3_check_critical(&value); + int ext_type = v3_check_generic(&value); + if (ext_type != 0) { + return v3_generic_extension(name, value, crit, ext_type, ctx); + } + X509_EXTENSION *ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION); + ERR_add_error_data(4, "name=", name, ", value=", value); + } + return ret; } -/* CONF *conf: Config file */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - const char *value) -{ - int crit; - int ext_type; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(OBJ_nid2sn(ext_nid), - value, crit, ext_type, ctx); - return do_ext_nconf(conf, ctx, ext_nid, crit, value); +X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, const char *value) { + // If omitted, fill in an empty |X509V3_CTX|. + X509V3_CTX ctx_tmp; + if (ctx == NULL) { + X509V3_set_ctx(&ctx_tmp, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx_tmp, conf); + ctx = &ctx_tmp; + } + + int crit = v3_check_critical(&value); + int ext_type = v3_check_generic(&value); + if (ext_type != 0) { + return v3_generic_extension(OBJ_nid2sn(ext_nid), value, crit, ext_type, + ctx); + } + return do_ext_nconf(conf, ctx, ext_nid, crit, value); } -/* CONF *conf: Config file */ -/* char *value: Value */ -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, const char *value) -{ - const X509V3_EXT_METHOD *method; - X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; - void *ext_struc; - if (ext_nid == NID_undef) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); - return NULL; - } - if (!(method = X509V3_EXT_get_nid(ext_nid))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); - return NULL; - } - /* Now get internal extension representation based on type */ - if (method->v2i) { - if (*value == '@') - nval = NCONF_get_section(conf, value + 1); - else - nval = X509V3_parse_list(value); - if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING); - ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", - value); - if (*value != '@') - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - return NULL; - } - ext_struc = method->v2i(method, ctx, nval); - if (*value != '@') - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - if (!ext_struc) - return NULL; - } else if (method->s2i) { - if (!(ext_struc = method->s2i(method, ctx, value))) - return NULL; - } else if (method->r2i) { - if (!ctx->db || !ctx->db_meth) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); - return NULL; - } - if (!(ext_struc = method->r2i(method, ctx, value))) - return NULL; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); - ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); - return NULL; - } - - ext = do_ext_i2d(method, ext_nid, crit, ext_struc); - if (method->it) - ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); - else - method->ext_free(ext_struc); - return ext; - -} - -static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, - int ext_nid, int crit, void *ext_struc) -{ - unsigned char *ext_der; - int ext_len; - ASN1_OCTET_STRING *ext_oct; - X509_EXTENSION *ext; - /* Convert internal representation to DER */ - if (method->it) { - ext_der = NULL; - ext_len = - ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); - if (ext_len < 0) - goto merr; - } else { - unsigned char *p; - ext_len = method->i2d(ext_struc, NULL); - if (!(ext_der = OPENSSL_malloc(ext_len))) - goto merr; - p = ext_der; - method->i2d(ext_struc, &p); - } - if (!(ext_oct = ASN1_OCTET_STRING_new())) - goto merr; - ext_oct->data = ext_der; - ext_oct->length = ext_len; - - ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); - if (!ext) - goto merr; - ASN1_OCTET_STRING_free(ext_oct); - - return ext; - - merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); +// CONF *conf: Config file +// char *value: Value +static X509_EXTENSION *do_ext_nconf(const CONF *conf, const X509V3_CTX *ctx, + int ext_nid, int crit, const char *value) { + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + const STACK_OF(CONF_VALUE) *nval; + STACK_OF(CONF_VALUE) *nval_owned = NULL; + void *ext_struc; + if (ext_nid == NID_undef) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); return NULL; - -} - -/* Given an internal structure, nid and critical flag create an extension */ - -X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) -{ - const X509V3_EXT_METHOD *method; - if (!(method = X509V3_EXT_get_nid(ext_nid))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + // Now get internal extension representation based on type + if (method->v2i) { + if (*value == '@') { + // TODO(davidben): This is the only place where |X509V3_EXT_nconf|'s + // |conf| parameter is used. All other codepaths use the copy inside + // |ctx|. Should this be switched and then the parameter ignored? + if (conf == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); return NULL; + } + nval = NCONF_get_section(conf, value + 1); + } else { + nval_owned = X509V3_parse_list(value); + nval = nval_owned; } - return do_ext_i2d(method, ext_nid, crit, ext_struc); + if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value); + sk_CONF_VALUE_pop_free(nval_owned, X509V3_conf_free); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + sk_CONF_VALUE_pop_free(nval_owned, X509V3_conf_free); + if (!ext_struc) { + return NULL; + } + } else if (method->s2i) { + if (!(ext_struc = method->s2i(method, ctx, value))) { + return NULL; + } + } else if (method->r2i) { + // TODO(davidben): Should this check be removed? This matches OpenSSL, but + // r2i-based extensions do not necessarily require a config database. The + // two built-in extensions only use it some of the time, and already handle + // |X509V3_get_section| returning NULL. + if (!ctx->db) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) { + return NULL; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); + return NULL; + } + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); + return ext; } -/* Check the extension string for critical flag */ -static int v3_check_critical(const char **value) -{ - const char *p = *value; - if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) - return 0; - p += 9; - while (isspace((unsigned char)*p)) - p++; - *value = p; - return 1; +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc) { + // Convert the extension's internal representation to DER. + unsigned char *ext_der = NULL; + int ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); + if (ext_len < 0) { + return NULL; + } + + ASN1_OCTET_STRING *ext_oct = ASN1_OCTET_STRING_new(); + if (ext_oct == NULL) { + OPENSSL_free(ext_der); + return NULL; + } + ASN1_STRING_set0(ext_oct, ext_der, ext_len); + + X509_EXTENSION *ext = + X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + ASN1_OCTET_STRING_free(ext_oct); + return ext; } -/* Check extension string for generic extension and return the type */ -static int v3_check_generic(const char **value) -{ - int gen_type = 0; - const char *p = *value; - if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { - p += 4; - gen_type = 1; - } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { - p += 5; - gen_type = 2; - } else - return 0; +// Given an internal structure, nid and critical flag create an extension - while (isspace((unsigned char)*p)) - p++; - *value = p; - return gen_type; +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) { + const X509V3_EXT_METHOD *method; + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); } -/* Create a generic extension: for now just handle DER type */ +// Check the extension string for critical flag +static int v3_check_critical(const char **value) { + const char *p = *value; + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) { + return 0; + } + p += 9; + while (OPENSSL_isspace((unsigned char)*p)) { + p++; + } + *value = p; + return 1; +} + +// Check extension string for generic extension and return the type +static int v3_check_generic(const char **value) { + int gen_type = 0; + const char *p = *value; + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else { + return 0; + } + + while (OPENSSL_isspace((unsigned char)*p)) { + p++; + } + *value = p; + return gen_type; +} + +// Create a generic extension: for now just handle DER type static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, int crit, int gen_type, - X509V3_CTX *ctx) -{ - unsigned char *ext_der = NULL; - long ext_len = 0; - ASN1_OBJECT *obj = NULL; - ASN1_OCTET_STRING *oct = NULL; - X509_EXTENSION *extension = NULL; - if (!(obj = OBJ_txt2obj(ext, 0))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR); - ERR_add_error_data(2, "name=", ext); - goto err; + const X509V3_CTX *ctx) { + unsigned char *ext_der = NULL; + size_t ext_len = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR); + ERR_add_error_data(2, "name=", ext); + goto err; + } + + if (gen_type == 1) { + ext_der = x509v3_hex_to_bytes(value, &ext_len); + } else if (gen_type == 2) { + ext_der = generic_asn1(value, ctx, &ext_len); + } + + if (ext_der == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (ext_len > INT_MAX) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_OVERFLOW); + goto err; + } + + oct = ASN1_OCTET_STRING_new(); + if (oct == NULL) { + goto err; + } + + ASN1_STRING_set0(oct, ext_der, (int)ext_len); + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + +err: + ASN1_OBJECT_free(obj); + ASN1_OCTET_STRING_free(oct); + OPENSSL_free(ext_der); + return extension; +} + +static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx, + size_t *ext_len) { + ASN1_TYPE *typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) { + return NULL; + } + unsigned char *ext_der = NULL; + int len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + if (len < 0) { + return NULL; + } + *ext_len = len; + return ext_der; +} + +// This is the main function: add a bunch of extensions based on a config +// file section to an extension STACK. + +int X509V3_EXT_add_nconf_sk(const CONF *conf, const X509V3_CTX *ctx, + const char *section, + STACK_OF(X509_EXTENSION) **sk) { + const STACK_OF(CONF_VALUE) *nval = NCONF_get_section(conf, section); + if (nval == NULL) { + return 0; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + X509_EXTENSION *ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value); + int ok = ext != NULL && // + (sk == NULL || X509v3_add_ext(sk, ext, -1) != NULL); + X509_EXTENSION_free(ext); + if (!ok) { + return 0; } - - if (gen_type == 1) - ext_der = x509v3_hex_to_bytes(value, &ext_len); - else if (gen_type == 2) - ext_der = generic_asn1(value, ctx, &ext_len); - - if (ext_der == NULL) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR); - ERR_add_error_data(2, "value=", value); - goto err; - } - - if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - - oct->data = ext_der; - oct->length = ext_len; - ext_der = NULL; - - extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); - - err: - ASN1_OBJECT_free(obj); - ASN1_OCTET_STRING_free(oct); - if (ext_der) - OPENSSL_free(ext_der); - return extension; - + } + return 1; } -static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, - long *ext_len) -{ - ASN1_TYPE *typ; - unsigned char *ext_der = NULL; - typ = ASN1_generate_v3(value, ctx); - if (typ == NULL) - return NULL; - *ext_len = i2d_ASN1_TYPE(typ, &ext_der); - ASN1_TYPE_free(typ); - return ext_der; +// Convenience functions to add extensions to a certificate, CRL and request + +int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509 *cert) { + STACK_OF(X509_EXTENSION) **sk = NULL; + if (cert) { + sk = &cert->cert_info->extensions; + } + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } -/* - * This is the main function: add a bunch of extensions based on a config - * file section to an extension STACK. - */ +// Same as above but for a CRL -int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, - STACK_OF(X509_EXTENSION) **sk) -{ - X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; - CONF_VALUE *val; - size_t i; - if (!(nval = NCONF_get_section(conf, section))) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) - return 0; - if (sk) - X509v3_add_ext(sk, ext, -1); - X509_EXTENSION_free(ext); - } - return 1; +int X509V3_EXT_CRL_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509_CRL *crl) { + STACK_OF(X509_EXTENSION) **sk = NULL; + if (crl) { + sk = &crl->crl->extensions; + } + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } -/* - * Convenience functions to add extensions to a certificate, CRL and request - */ +// Add extensions to certificate request -int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509 *cert) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - if (cert) - sk = &cert->cert_info->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} - -/* Same as above but for a CRL */ - -int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_CRL *crl) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - if (crl) - sk = &crl->crl->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} - -/* Add extensions to certificate request */ - -int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, - X509_REQ *req) -{ - STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; - int i; - if (req) - sk = &extlist; - i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); - if (!i || !sk) - return i; - i = X509_REQ_add_extensions(req, extlist); - sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); +int X509V3_EXT_REQ_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509_REQ *req) { + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + if (req) { + sk = &extlist; + } + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) { return i; + } + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; } -/* Config database functions */ +// Config database functions -char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) -{ - if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); - return NULL; - } - if (ctx->db_meth->get_string) - return ctx->db_meth->get_string(ctx->db, name, section); +const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, + const char *section) { + if (ctx->db == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); return NULL; + } + return NCONF_get_section(ctx->db, section); } -STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) -{ - if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); - return NULL; - } - if (ctx->db_meth->get_section) - return ctx->db_meth->get_section(ctx->db, section); - return NULL; +void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf) { + ctx->db = conf; } -void X509V3_string_free(X509V3_CTX *ctx, char *str) -{ - if (!str) - return; - if (ctx->db_meth->free_string) - ctx->db_meth->free_string(ctx->db, str); -} - -void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) -{ - if (!section) - return; - if (ctx->db_meth->free_section) - ctx->db_meth->free_section(ctx->db, section); -} - -static char *nconf_get_string(void *db, const char *section, const char *value) -{ - /* TODO(fork): This returns a non-const pointer because |X509V3_CONF_METHOD| - * allows |get_string| to return caller-owned pointers, provided they're - * freed by |free_string|. |nconf_method| leaves |free_string| NULL, and - * there are no other implementations of |X509V3_CONF_METHOD|, so this can - * be simplified if we make it private. */ - return (char *)NCONF_get_string(db, section, value); -} - -static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) -{ - return NCONF_get_section(db, section); -} - -static const X509V3_CONF_METHOD nconf_method = { - nconf_get_string, - nconf_get_section, - NULL, - NULL -}; - -void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) -{ - ctx->db_meth = &nconf_method; - ctx->db = conf; -} - -void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, - X509_CRL *crl, int flags) -{ - ctx->issuer_cert = issuer; - ctx->subject_cert = subj; - ctx->crl = crl; - ctx->subject_req = req; - ctx->flags = flags; +void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, const X509 *subj, + const X509_REQ *req, const X509_CRL *crl, int flags) { + OPENSSL_memset(ctx, 0, sizeof(*ctx)); + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_cpols.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_cpols.c index 6e3eb141..7464a426 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_cpols.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_cpols.c @@ -1,4 +1,3 @@ -/* v3_cpols.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -71,430 +70,408 @@ #include "internal.h" -/* Certificate policies extension support: this one is a bit complex... */ +// Certificate policies extension support: this one is a bit complex... -static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, - BIO *out, int indent); -static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value); -static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, +static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out, + int indent); +static void *r2i_certpol(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const char *value); +static void print_qualifiers(BIO *out, const STACK_OF(POLICYQUALINFO) *quals, int indent); -static void print_notice(BIO *out, USERNOTICE *notice, int indent); -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org); -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org); -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); +static void print_notice(BIO *out, const USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *polstrs, + int ia5org); +static POLICYQUALINFO *notice_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *unot, + int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, + const STACK_OF(CONF_VALUE) *nos); const X509V3_EXT_METHOD v3_cpols = { - NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), - 0, 0, 0, 0, - 0, 0, - 0, 0, - (X509V3_EXT_I2R)i2r_certpol, - (X509V3_EXT_R2I)r2i_certpol, - NULL + NID_certificate_policies, + 0, + ASN1_ITEM_ref(CERTIFICATEPOLICIES), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + i2r_certpol, + r2i_certpol, + NULL, }; -ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) +ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) -IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +IMPLEMENT_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES) ASN1_SEQUENCE(POLICYINFO) = { - ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), - ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) + ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), + ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO), } ASN1_SEQUENCE_END(POLICYINFO) -IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) +IMPLEMENT_ASN1_FUNCTIONS_const(POLICYINFO) -ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); +ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, + ASN1_ANY); ASN1_ADB(POLICYQUALINFO) = { - ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), - ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) + ADB_ENTRY(NID_id_qt_cps, + ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), + ADB_ENTRY(NID_id_qt_unotice, + ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)), } ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); ASN1_SEQUENCE(POLICYQUALINFO) = { - ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), - ASN1_ADB_OBJECT(POLICYQUALINFO) + ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), + ASN1_ADB_OBJECT(POLICYQUALINFO), } ASN1_SEQUENCE_END(POLICYQUALINFO) -IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) +IMPLEMENT_ASN1_FUNCTIONS_const(POLICYQUALINFO) ASN1_SEQUENCE(USERNOTICE) = { - ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), - ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) + ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), + ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT), } ASN1_SEQUENCE_END(USERNOTICE) -IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) +IMPLEMENT_ASN1_FUNCTIONS_const(USERNOTICE) ASN1_SEQUENCE(NOTICEREF) = { - ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), - ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) + ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), + ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER), } ASN1_SEQUENCE_END(NOTICEREF) -IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) +IMPLEMENT_ASN1_FUNCTIONS_const(NOTICEREF) -static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value) -{ - STACK_OF(POLICYINFO) *pols = NULL; - char *pstr; - POLICYINFO *pol; - ASN1_OBJECT *pobj; - STACK_OF(CONF_VALUE) *vals; - CONF_VALUE *cnf; - size_t i; - int ia5org; - pols = sk_POLICYINFO_new_null(); - if (pols == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - vals = X509V3_parse_list(value); - if (vals == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB); - goto err; - } - ia5org = 0; - for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { - cnf = sk_CONF_VALUE_value(vals, i); - if (cnf->value || !cnf->name) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pstr = cnf->name; - if (!strcmp(pstr, "ia5org")) { - ia5org = 1; - continue; - } else if (*pstr == '@') { - STACK_OF(CONF_VALUE) *polsect; - polsect = X509V3_get_section(ctx, pstr + 1); - if (!polsect) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); - - X509V3_conf_err(cnf); - goto err; - } - pol = policy_section(ctx, polsect, ia5org); - X509V3_section_free(ctx, polsect); - if (!pol) - goto err; - } else { - if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol = POLICYINFO_new(); - if (pol == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ASN1_OBJECT_free(pobj); - goto err; - } - pol->policyid = pobj; - } - if (!sk_POLICYINFO_push(pols, pol)) { - POLICYINFO_free(pol); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - return pols; - err: - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - sk_POLICYINFO_pop_free(pols, POLICYINFO_free); +static void *r2i_certpol(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const char *value) { + STACK_OF(POLICYINFO) *pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { return NULL; + } + STACK_OF(CONF_VALUE) *vals = X509V3_parse_list(value); + if (vals == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB); + goto err; + } + int ia5org = 0; + for (size_t i = 0; i < sk_CONF_VALUE_num(vals); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + POLICYINFO *pol; + const char *pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + const STACK_OF(CONF_VALUE) *polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + if (!pol) { + goto err; + } + } else { + ASN1_OBJECT *pobj = OBJ_txt2obj(cnf->name, 0); + if (pobj == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + ASN1_OBJECT_free(pobj); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; +err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; } -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org) -{ - size_t i; - CONF_VALUE *cnf; - POLICYINFO *pol; - POLICYQUALINFO *qual; - if (!(pol = POLICYINFO_new())) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { - cnf = sk_CONF_VALUE_value(polstrs, i); - if (!strcmp(cnf->name, "policyIdentifier")) { - ASN1_OBJECT *pobj; - if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol->policyid = pobj; - - } else if (!x509v3_name_cmp(cnf->name, "CPS")) { - if (!pol->qualifiers) - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (!(qual = POLICYQUALINFO_new())) - goto merr; - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; - qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); - if (qual->pqualid == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); - goto err; - } - qual->d.cpsuri = ASN1_IA5STRING_new(); - if (qual->d.cpsuri == NULL) { - goto err; - } - if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!x509v3_name_cmp(cnf->name, "userNotice")) { - STACK_OF(CONF_VALUE) *unot; - if (*cnf->value != '@') { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); - X509V3_conf_err(cnf); - goto err; - } - unot = X509V3_get_section(ctx, cnf->value + 1); - if (!unot) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); - - X509V3_conf_err(cnf); - goto err; - } - qual = notice_section(ctx, unot, ia5org); - X509V3_section_free(ctx, unot); - if (!qual) - goto err; - if (!pol->qualifiers) - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); - - X509V3_conf_err(cnf); - goto err; - } - } - if (!pol->policyid) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER); +static POLICYINFO *policy_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *polstrs, + int ia5org) { + POLICYINFO *pol; + POLICYQUALINFO *qual; + if (!(pol = POLICYINFO_new())) { + goto err; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(polstrs, i); + if (!strcmp(cnf->name, "policyIdentifier")) { + ASN1_OBJECT *pobj; + if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); goto err; - } + } + pol->policyid = pobj; - return pol; - - merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - - err: - POLICYINFO_free(pol); - return NULL; - -} - -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org) -{ - size_t i; - int ret; - CONF_VALUE *cnf; - USERNOTICE *not; - POLICYQUALINFO *qual; - if (!(qual = POLICYQUALINFO_new())) - goto merr; - qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); - if (qual->pqualid == NULL) { + } else if (x509v3_conf_name_matches(cnf->name, "CPS")) { + if (!pol->qualifiers) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + } + if (!(qual = POLICYQUALINFO_new())) { + goto err; + } + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { + goto err; + } + qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); + if (qual->pqualid == NULL) { OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); goto err; - } - if (!(not = USERNOTICE_new())) - goto merr; - qual->d.usernotice = not; - for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { - cnf = sk_CONF_VALUE_value(unot, i); - if (!strcmp(cnf->name, "explicitText")) { - not->exptext = ASN1_VISIBLESTRING_new(); - if (not->exptext == NULL) - goto merr; - if (!ASN1_STRING_set(not->exptext, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "organization")) { - NOTICEREF *nref; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - if (ia5org) - nref->organization->type = V_ASN1_IA5STRING; - else - nref->organization->type = V_ASN1_VISIBLESTRING; - if (!ASN1_STRING_set(nref->organization, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "noticeNumbers")) { - NOTICEREF *nref; - STACK_OF(CONF_VALUE) *nos; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - nos = X509V3_parse_list(cnf->value); - if (!nos || !sk_CONF_VALUE_num(nos)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS); - X509V3_conf_err(cnf); - goto err; - } - ret = nref_nos(nref->noticenos, nos); - sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); - if (!ret) - goto err; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); - X509V3_conf_err(cnf); - goto err; - } - } - - if (not->noticeref && - (!not->noticeref->noticenos || !not->noticeref->organization)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + } + qual->d.cpsuri = ASN1_IA5STRING_new(); + if (qual->d.cpsuri == NULL) { goto err; + } + if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, strlen(cnf->value))) { + goto err; + } + } else if (x509v3_conf_name_matches(cnf->name, "userNotice")) { + if (*cnf->value != '@') { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + const STACK_OF(CONF_VALUE) *unot = + X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + if (!qual) { + goto err; + } + if (!pol->qualifiers) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + } + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; } + } + if (!pol->policyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } - return qual; + return pol; - merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - - err: - POLICYQUALINFO_free(qual); - return NULL; +err: + POLICYINFO_free(pol); + return NULL; } -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) -{ - CONF_VALUE *cnf; - ASN1_INTEGER *aint; - - size_t i; - - for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { - cnf = sk_CONF_VALUE_value(nos, i); - if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); - goto err; +static POLICYQUALINFO *notice_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *unot, + int ia5org) { + USERNOTICE *notice; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) { + goto err; + } + qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(notice = USERNOTICE_new())) { + goto err; + } + qual->d.usernotice = notice; + for (size_t i = 0; i < sk_CONF_VALUE_num(unot); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + notice->exptext = ASN1_VISIBLESTRING_new(); + if (notice->exptext == NULL) { + goto err; + } + if (!ASN1_STRING_set(notice->exptext, cnf->value, strlen(cnf->value))) { + goto err; + } + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!notice->noticeref) { + if (!(nref = NOTICEREF_new())) { + goto err; } - if (!sk_ASN1_INTEGER_push(nnums, aint)) - goto merr; - } - return 1; - - merr: - ASN1_INTEGER_free(aint); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - - err: - return 0; -} - -static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, - BIO *out, int indent) -{ - size_t i; - POLICYINFO *pinfo; - /* First print out the policy OIDs */ - for (i = 0; i < sk_POLICYINFO_num(pol); i++) { - pinfo = sk_POLICYINFO_value(pol, i); - BIO_printf(out, "%*sPolicy: ", indent, ""); - i2a_ASN1_OBJECT(out, pinfo->policyid); - BIO_puts(out, "\n"); - if (pinfo->qualifiers) - print_qualifiers(out, pinfo->qualifiers, indent + 2); - } - return 1; -} - -static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, - int indent) -{ - POLICYQUALINFO *qualinfo; - size_t i; - for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { - qualinfo = sk_POLICYQUALINFO_value(quals, i); - switch (OBJ_obj2nid(qualinfo->pqualid)) { - case NID_id_qt_cps: - BIO_printf(out, "%*sCPS: %.*s\n", indent, "", - qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data); - break; - - case NID_id_qt_unotice: - BIO_printf(out, "%*sUser Notice:\n", indent, ""); - print_notice(out, qualinfo->d.usernotice, indent + 2); - break; - - default: - BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); - - i2a_ASN1_OBJECT(out, qualinfo->pqualid); - BIO_puts(out, "\n"); - break; + notice->noticeref = nref; + } else { + nref = notice->noticeref; + } + if (ia5org) { + nref->organization->type = V_ASN1_IA5STRING; + } else { + nref->organization->type = V_ASN1_VISIBLESTRING; + } + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) { + goto err; + } + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!notice->noticeref) { + if (!(nref = NOTICEREF_new())) { + goto err; } + notice->noticeref = nref; + } else { + nref = notice->noticeref; + } + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + goto err; + } + int ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) { + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; } + } + + if (notice->noticeref && + (!notice->noticeref->noticenos || !notice->noticeref->organization)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + +err: + POLICYQUALINFO_free(qual); + return NULL; } -static void print_notice(BIO *out, USERNOTICE *notice, int indent) -{ - size_t i; - if (notice->noticeref) { - NOTICEREF *ref; - ref = notice->noticeref; - BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", - ref->organization->length, ref->organization->data); - BIO_printf(out, "%*sNumber%s: ", indent, "", - sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); - for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { - ASN1_INTEGER *num; - char *tmp; - num = sk_ASN1_INTEGER_value(ref->noticenos, i); - if (i) - BIO_puts(out, ", "); - if (num == NULL) - BIO_puts(out, "(null)"); - else { - tmp = i2s_ASN1_INTEGER(NULL, num); - if (tmp == NULL) - return; - BIO_puts(out, tmp); - OPENSSL_free(tmp); - } - } - BIO_puts(out, "\n"); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, + const STACK_OF(CONF_VALUE) *nos) { + for (size_t i = 0; i < sk_CONF_VALUE_num(nos); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nos, i); + ASN1_INTEGER *aint = s2i_ASN1_INTEGER(NULL, cnf->name); + if (aint == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + return 0; } - if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", - notice->exptext->length, notice->exptext->data); + if (!sk_ASN1_INTEGER_push(nnums, aint)) { + ASN1_INTEGER_free(aint); + return 0; + } + } + return 1; } -void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) -{ - const X509_POLICY_DATA *dat = node->data; - +static int i2r_certpol(const X509V3_EXT_METHOD *method, void *ext, BIO *out, + int indent) { + const STACK_OF(POLICYINFO) *pol = ext; + // First print out the policy OIDs + for (size_t i = 0; i < sk_POLICYINFO_num(pol); i++) { + const POLICYINFO *pinfo = sk_POLICYINFO_value(pol, i); BIO_printf(out, "%*sPolicy: ", indent, ""); - - i2a_ASN1_OBJECT(out, dat->valid_policy); + i2a_ASN1_OBJECT(out, pinfo->policyid); BIO_puts(out, "\n"); - BIO_printf(out, "%*s%s\n", indent + 2, "", - node_data_critical(dat) ? "Critical" : "Non Critical"); - if (dat->qualifier_set) - print_qualifiers(out, dat->qualifier_set, indent + 2); - else - BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); + if (pinfo->qualifiers) { + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + } + return 1; +} + +static void print_qualifiers(BIO *out, const STACK_OF(POLICYQUALINFO) *quals, + int indent) { + for (size_t i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + const POLICYQUALINFO *qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %.*s\n", indent, "", + qualinfo->d.cpsuri->length, qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void print_notice(BIO *out, const USERNOTICE *notice, int indent) { + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", + ref->organization->length, ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (size_t i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) { + BIO_puts(out, ", "); + } + if (num == NULL) { + BIO_puts(out, "(null)"); + } else { + tmp = i2s_ASN1_INTEGER(NULL, num); + if (tmp == NULL) { + return; + } + BIO_puts(out, tmp); + OPENSSL_free(tmp); + } + } + BIO_puts(out, "\n"); + } + if (notice->exptext) { + BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "", + notice->exptext->length, notice->exptext->data); + } } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_crld.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_crld.c index 93e5b6dc..4162c353 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_crld.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_crld.c @@ -1,4 +1,3 @@ -/* v3_crld.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -66,119 +65,142 @@ #include #include -#include "internal.h" #include "../x509/internal.h" +#include "internal.h" -static void *v2i_crld(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent); const X509V3_EXT_METHOD v3_crld = { - NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), - 0, 0, 0, 0, - 0, 0, + NID_crl_distribution_points, + 0, + ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, + 0, + 0, + 0, + 0, + 0, 0, v2i_crld, - i2r_crldp, 0, - NULL + i2r_crldp, + 0, + NULL, }; const X509V3_EXT_METHOD v3_freshest_crl = { - NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), - 0, 0, 0, 0, - 0, 0, + NID_freshest_crl, + 0, + ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, + 0, + 0, + 0, + 0, + 0, 0, v2i_crld, - i2r_crldp, 0, - NULL + i2r_crldp, + 0, + NULL, }; -static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, - char *sect) -{ - STACK_OF(CONF_VALUE) *gnsect; - STACK_OF(GENERAL_NAME) *gens; - if (*sect == '@') - gnsect = X509V3_get_section(ctx, sect + 1); - else - gnsect = X509V3_parse_list(sect); - if (!gnsect) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); - return NULL; - } - gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); - if (*sect == '@') - X509V3_section_free(ctx, gnsect); - else - sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); - return gens; +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(const X509V3_CTX *ctx, + char *sect) { + const STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(CONF_VALUE) *gnsect_owned = NULL; + if (*sect == '@') { + gnsect = X509V3_get_section(ctx, sect + 1); + } else { + gnsect_owned = X509V3_parse_list(sect); + gnsect = gnsect_owned; + } + if (!gnsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + STACK_OF(GENERAL_NAME) *gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + sk_CONF_VALUE_pop_free(gnsect_owned, X509V3_conf_free); + return gens; } -static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, - CONF_VALUE *cnf) -{ - STACK_OF(GENERAL_NAME) *fnm = NULL; - STACK_OF(X509_NAME_ENTRY) *rnm = NULL; - if (!strncmp(cnf->name, "fullname", 9)) { - fnm = gnames_from_sectname(ctx, cnf->value); - if (!fnm) - goto err; - } else if (!strcmp(cnf->name, "relativename")) { - int ret; - STACK_OF(CONF_VALUE) *dnsect; - X509_NAME *nm; - nm = X509_NAME_new(); - if (!nm) - return -1; - dnsect = X509V3_get_section(ctx, cnf->value); - if (!dnsect) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); - return -1; - } - ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); - X509V3_section_free(ctx, dnsect); - rnm = nm->entries; - nm->entries = NULL; - X509_NAME_free(nm); - if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) - goto err; - /* - * Since its a name fragment can't have more than one RDNSequence - */ - if (sk_X509_NAME_ENTRY_value(rnm, - sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); - goto err; - } - } else - return 0; - - if (*pdp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET); - goto err; +// set_dist_point_name decodes a DistributionPointName from |cnf| and writes the +// result in |*pdp|. It returns 1 on success, -1 on error, and 0 if |cnf| used +// an unrecognized input type. The zero return can be used by callers to support +// additional syntax. +static int set_dist_point_name(DIST_POINT_NAME **pdp, const X509V3_CTX *ctx, + const CONF_VALUE *cnf) { + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + if (!strncmp(cnf->name, "fullname", 9)) { + // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i + // function, |cnf->value| may be NULL. + if (cnf->value == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return -1; } - - *pdp = DIST_POINT_NAME_new(); - if (!*pdp) - goto err; - if (fnm) { - (*pdp)->type = 0; - (*pdp)->name.fullname = fnm; - } else { - (*pdp)->type = 1; - (*pdp)->name.relativename = rnm; + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) { + goto err; } + } else if (!strcmp(cnf->name, "relativename")) { + // If |cnf| comes from |X509V3_parse_list|, which is possible for a v2i + // function, |cnf->value| may be NULL. + if (cnf->value == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return -1; + } + const STACK_OF(CONF_VALUE) *dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + return -1; + } + X509_NAME *nm = X509_NAME_new(); + if (!nm) { + return -1; + } + int ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) { + goto err; + } + // There can only be one RDN in nameRelativeToCRLIssuer. + if (sk_X509_NAME_ENTRY_value(rnm, sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else { + return 0; + } - return 1; + if (*pdp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } - err: - if (fnm) - sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); - if (rnm) - sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); - return -1; + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) { + goto err; + } + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + +err: + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; } static const BIT_STRING_BITNAME reason_flags[] = { @@ -191,373 +213,387 @@ static const BIT_STRING_BITNAME reason_flags[] = { {6, "Certificate Hold", "certificateHold"}, {7, "Privilege Withdrawn", "privilegeWithdrawn"}, {8, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; + {-1, NULL, NULL}}; -static int set_reasons(ASN1_BIT_STRING **preas, char *value) -{ - STACK_OF(CONF_VALUE) *rsk = NULL; - const BIT_STRING_BITNAME *pbn; - const char *bnam; - size_t i; - int ret = 0; - rsk = X509V3_parse_list(value); - if (!rsk) - return 0; - if (*preas) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { - bnam = sk_CONF_VALUE_value(rsk, i)->name; - if (!*preas) { - *preas = ASN1_BIT_STRING_new(); - if (!*preas) - goto err; - } - for (pbn = reason_flags; pbn->lname; pbn++) { - if (!strcmp(pbn->sname, bnam)) { - if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) - goto err; - break; - } - } - if (!pbn->lname) - goto err; - } - ret = 1; - - err: - sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); - return ret; -} - -static int print_reasons(BIO *out, const char *rname, - ASN1_BIT_STRING *rflags, int indent) -{ - int first = 1; - const BIT_STRING_BITNAME *pbn; - BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); - for (pbn = reason_flags; pbn->lname; pbn++) { - if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { - if (first) - first = 0; - else - BIO_puts(out, ", "); - BIO_puts(out, pbn->lname); - } - } - if (first) - BIO_puts(out, "\n"); - else - BIO_puts(out, "\n"); - return 1; -} - -static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - size_t i; - CONF_VALUE *cnf; - DIST_POINT *point = NULL; - point = DIST_POINT_new(); - if (!point) +static int set_reasons(ASN1_BIT_STRING **preas, const char *value) { + if (*preas) { + // Duplicate "reasons" or "onlysomereasons" key. + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); + return 0; + } + int ret = 0; + STACK_OF(CONF_VALUE) *rsk = X509V3_parse_list(value); + if (!rsk) { + return 0; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + const char *bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) { goto err; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - int ret; - cnf = sk_CONF_VALUE_value(nval, i); - ret = set_dist_point_name(&point->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(cnf->name, "reasons")) { - if (!set_reasons(&point->reasons, cnf->value)) - goto err; - } else if (!strcmp(cnf->name, "CRLissuer")) { - point->CRLissuer = gnames_from_sectname(ctx, cnf->value); - if (!point->CRLissuer) - goto err; - } + } } + const BIT_STRING_BITNAME *pbn; + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) { + goto err; + } + break; + } + } + if (!pbn->lname) { + goto err; + } + } + ret = 1; - return point; - - err: - if (point) - DIST_POINT_free(point); - return NULL; +err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; } -static void *v2i_crld(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - STACK_OF(DIST_POINT) *crld = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - CONF_VALUE *cnf; - size_t i; - if (!(crld = sk_DIST_POINT_new_null())) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - DIST_POINT *point; - cnf = sk_CONF_VALUE_value(nval, i); - if (!cnf->value) { - STACK_OF(CONF_VALUE) *dpsect; - dpsect = X509V3_get_section(ctx, cnf->name); - if (!dpsect) - goto err; - point = crldp_from_section(ctx, dpsect); - X509V3_section_free(ctx, dpsect); - if (!point) - goto err; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - } else { - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - if (!(gens = GENERAL_NAMES_new())) - goto merr; - if (!sk_GENERAL_NAME_push(gens, gen)) - goto merr; - gen = NULL; - if (!(point = DIST_POINT_new())) - goto merr; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - if (!(point->distpoint = DIST_POINT_NAME_new())) - goto merr; - point->distpoint->name.fullname = gens; - point->distpoint->type = 0; - gens = NULL; - } +static int print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, + int indent) { + int first = 1; + const BIT_STRING_BITNAME *pbn; + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) { + first = 0; + } else { + BIO_puts(out, ", "); + } + BIO_puts(out, pbn->lname); } - return crld; + } + if (first) { + BIO_puts(out, "\n"); + } else { + BIO_puts(out, "\n"); + } + return 1; +} - merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - err: - GENERAL_NAME_free(gen); - GENERAL_NAMES_free(gens); - sk_DIST_POINT_pop_free(crld, DIST_POINT_free); - return NULL; +static DIST_POINT *crldp_from_section(const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + DIST_POINT *point = NULL; + point = DIST_POINT_new(); + if (!point) { + goto err; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + int ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) { + continue; + } + if (ret < 0) { + goto err; + } + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) { + goto err; + } + } else if (!strcmp(cnf->name, "CRLissuer")) { + GENERAL_NAMES_free(point->CRLissuer); + point->CRLissuer = gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) { + goto err; + } + } + } + + return point; + +err: + DIST_POINT_free(point); + return NULL; +} + +static void *v2i_crld(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + if (!(crld = sk_DIST_POINT_new_null())) { + goto err; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + const STACK_OF(CONF_VALUE) *dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) { + goto err; + } + point = crldp_from_section(ctx, dpsect); + if (!point) { + goto err; + } + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto err; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) { + goto err; + } + if (!(gens = GENERAL_NAMES_new())) { + goto err; + } + if (!sk_GENERAL_NAME_push(gens, gen)) { + goto err; + } + gen = NULL; + if (!(point = DIST_POINT_new())) { + goto err; + } + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto err; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) { + goto err; + } + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + +err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; } static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + void *exarg) { + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; - switch (operation) { + switch (operation) { case ASN1_OP_NEW_POST: - dpn->dpname = NULL; - break; + dpn->dpname = NULL; + break; case ASN1_OP_FREE_POST: - if (dpn->dpname) - X509_NAME_free(dpn->dpname); - break; - } - return 1; + X509_NAME_free(dpn->dpname); + break; + } + return 1; } ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { - ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), - ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) + ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), + ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1), } ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) - IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) ASN1_SEQUENCE(DIST_POINT) = { - ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), - ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), - ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) + ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2), } ASN1_SEQUENCE_END(DIST_POINT) IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) -ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) +ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) ASN1_SEQUENCE(ISSUING_DIST_POINT) = { - ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), - ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) + ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), + ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5), } ASN1_SEQUENCE_END(ISSUING_DIST_POINT) IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent); -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); +static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); const X509V3_EXT_METHOD v3_idp = { - NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + NID_issuing_distribution_point, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(ISSUING_DIST_POINT), - 0, 0, 0, 0, - 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, v2i_idp, - i2r_idp, 0, - NULL + i2r_idp, + 0, + NULL, }; -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - ISSUING_DIST_POINT *idp = NULL; - CONF_VALUE *cnf; - char *name, *val; - size_t i; - int ret; - idp = ISSUING_DIST_POINT_new(); - if (!idp) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - name = cnf->name; - val = cnf->value; - ret = set_dist_point_name(&idp->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(name, "onlyuser")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) - goto err; - } else if (!strcmp(name, "onlyCA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) - goto err; - } else if (!strcmp(name, "onlyAA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) - goto err; - } else if (!strcmp(name, "indirectCRL")) { - if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) - goto err; - } else if (!strcmp(name, "onlysomereasons")) { - if (!set_reasons(&idp->onlysomereasons, val)) - goto err; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); - X509V3_conf_err(cnf); - goto err; - } +static void *v2i_idp(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + ISSUING_DIST_POINT *idp = ISSUING_DIST_POINT_new(); + if (!idp) { + goto err; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + const char *name = cnf->name; + const char *val = cnf->value; + int ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) { + continue; } - return idp; - - merr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - err: - ISSUING_DIST_POINT_free(idp); - return NULL; -} - -static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) -{ - size_t i; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - BIO_printf(out, "%*s", indent + 2, ""); - GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); - BIO_puts(out, "\n"); + if (ret < 0) { + goto err; } - return 1; -} - -static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) -{ - if (dpn->type == 0) { - BIO_printf(out, "%*sFull Name:\n", indent, ""); - print_gens(out, dpn->name.fullname, indent); + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) { + goto err; + } + } else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) { + goto err; + } + } else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) { + goto err; + } + } else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) { + goto err; + } + } else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) { + goto err; + } } else { - X509_NAME ntmp; - ntmp.entries = dpn->name.relativename; - BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); - X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); - BIO_puts(out, "\n"); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; } - return 1; + } + return idp; + +err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) { + size_t i; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) { + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; } static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, - int indent) -{ - ISSUING_DIST_POINT *idp = pidp; - if (idp->distpoint) - print_distpoint(out, idp->distpoint, indent); - if (idp->onlyuser > 0) - BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); - if (idp->onlyCA > 0) - BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); - if (idp->indirectCRL > 0) - BIO_printf(out, "%*sIndirect CRL\n", indent, ""); - if (idp->onlysomereasons) - print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); - if (idp->onlyattr > 0) - BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); - if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) - && (idp->indirectCRL <= 0) && !idp->onlysomereasons - && (idp->onlyattr <= 0)) - BIO_printf(out, "%*s\n", indent, ""); + int indent) { + ISSUING_DIST_POINT *idp = pidp; + if (idp->distpoint) { + print_distpoint(out, idp->distpoint, indent); + } + if (idp->onlyuser > 0) { + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + } + if (idp->onlyCA > 0) { + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + } + if (idp->indirectCRL > 0) { + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + } + if (idp->onlysomereasons) { + print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); + } + if (idp->onlyattr > 0) { + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + } + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) && + (idp->indirectCRL <= 0) && !idp->onlysomereasons && + (idp->onlyattr <= 0)) { + BIO_printf(out, "%*s\n", indent, ""); + } - return 1; + return 1; } static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, - int indent) -{ - STACK_OF(DIST_POINT) *crld = pcrldp; - DIST_POINT *point; - size_t i; - for (i = 0; i < sk_DIST_POINT_num(crld); i++) { - BIO_puts(out, "\n"); - point = sk_DIST_POINT_value(crld, i); - if (point->distpoint) - print_distpoint(out, point->distpoint, indent); - if (point->reasons) - print_reasons(out, "Reasons", point->reasons, indent); - if (point->CRLissuer) { - BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); - print_gens(out, point->CRLissuer, indent); - } + int indent) { + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + size_t i; + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) { + print_distpoint(out, point->distpoint, indent); } - return 1; + if (point->reasons) { + print_reasons(out, "Reasons", point->reasons, indent); + } + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; } -int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) -{ - size_t i; - STACK_OF(X509_NAME_ENTRY) *frag; - X509_NAME_ENTRY *ne; - if (!dpn || (dpn->type != 1)) - return 1; - frag = dpn->name.relativename; - dpn->dpname = X509_NAME_dup(iname); - if (!dpn->dpname) - return 0; - for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { - ne = sk_X509_NAME_ENTRY_value(frag, i); - if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - } - /* generate cached encoding of name */ - if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) { + size_t i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + if (!dpn || (dpn->type != 1)) { return 1; + } + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) { + return 0; + } + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + // generate cached encoding of name + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_enum.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_enum.c index 9b222bbd..3143a98d 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_enum.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_enum.c @@ -1,4 +1,3 @@ -/* v3_enum.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -57,8 +56,8 @@ #include -#include #include +#include #include #include "internal.h" @@ -73,34 +72,40 @@ static const ENUMERATED_NAMES crl_reasons[] = { {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"}, {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, - {CRL_REASON_CESSATION_OF_OPERATION, - "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", + "cessationOfOperation"}, {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"}, {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; + {-1, NULL, NULL}}; + +static char *i2s_ASN1_ENUMERATED_TABLE(const X509V3_EXT_METHOD *method, + void *ext) { + const ASN1_ENUMERATED *e = ext; + long strval = ASN1_ENUMERATED_get(e); + for (const ENUMERATED_NAMES *enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) { + return OPENSSL_strdup(enam->lname); + } + } + return i2s_ASN1_ENUMERATED(method, e); +} const X509V3_EXT_METHOD v3_crl_reason = { - NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + NID_crl_reason, 0, - 0, 0, 0, 0, - (void *)crl_reasons + ASN1_ITEM_ref(ASN1_ENUMERATED), + 0, + 0, + 0, + 0, + i2s_ASN1_ENUMERATED_TABLE, + 0, + 0, + 0, + 0, + 0, + (void *)crl_reasons, }; - -char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, - const ASN1_ENUMERATED *e) -{ - const ENUMERATED_NAMES *enam; - long strval; - strval = ASN1_ENUMERATED_get(e); - for (enam = method->usr_data; enam->lname; enam++) { - if (strval == enam->bitnum) - return OPENSSL_strdup(enam->lname); - } - return i2s_ASN1_ENUMERATED(method, e); -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_extku.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_extku.c index 952e032c..d678ac78 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_extku.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_extku.c @@ -1,4 +1,3 @@ -/* v3_extku.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -63,86 +62,93 @@ #include #include +#include "internal.h" + + static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD - *method, void *eku, STACK_OF(CONF_VALUE) - *extlist); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( + const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); const X509V3_EXT_METHOD v3_ext_ku = { - NID_ext_key_usage, 0, + NID_ext_key_usage, + 0, ASN1_ITEM_ref(EXTENDED_KEY_USAGE), - 0, 0, 0, 0, - 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, i2v_EXTENDED_KEY_USAGE, v2i_EXTENDED_KEY_USAGE, - 0, 0, - NULL + 0, + 0, + NULL, }; -/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +// NB OCSP acceptable responses also is a SEQUENCE OF OBJECT const X509V3_EXT_METHOD v3_ocsp_accresp = { - NID_id_pkix_OCSP_acceptableResponses, 0, + NID_id_pkix_OCSP_acceptableResponses, + 0, ASN1_ITEM_ref(EXTENDED_KEY_USAGE), - 0, 0, 0, 0, - 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, i2v_EXTENDED_KEY_USAGE, v2i_EXTENDED_KEY_USAGE, - 0, 0, - NULL + 0, + 0, + NULL, }; -ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) +ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) -IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +IMPLEMENT_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *ext_list) -{ - EXTENDED_KEY_USAGE *eku = a; - size_t i; - ASN1_OBJECT *obj; +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( + const X509V3_EXT_METHOD *method, void *a, STACK_OF(CONF_VALUE) *ext_list) { + const EXTENDED_KEY_USAGE *eku = a; + for (size_t i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + const ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(eku, i); char obj_tmp[80]; - for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { - obj = sk_ASN1_OBJECT_value(eku, i); - i2t_ASN1_OBJECT(obj_tmp, 80, obj); - X509V3_add_value(NULL, obj_tmp, &ext_list); - } - return ext_list; + i2t_ASN1_OBJECT(obj_tmp, 80, obj); + X509V3_add_value(NULL, obj_tmp, &ext_list); + } + return ext_list; } static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - EXTENDED_KEY_USAGE *extku; - char *extval; - ASN1_OBJECT *objtmp; - CONF_VALUE *val; - size_t i; + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + EXTENDED_KEY_USAGE *extku = sk_ASN1_OBJECT_new_null(); + if (extku == NULL) { + return NULL; + } - if (!(extku = sk_ASN1_OBJECT_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + const char *extval; + if (val->value) { + extval = val->value; + } else { + extval = val->name; } + ASN1_OBJECT *obj = OBJ_txt2obj(extval, 0); + if (obj == NULL || !sk_ASN1_OBJECT_push(extku, obj)) { + ASN1_OBJECT_free(obj); + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (val->value) - extval = val->value; - else - extval = val->name; - if (!(objtmp = OBJ_txt2obj(extval, 0))) { - sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - sk_ASN1_OBJECT_push(extku, objtmp); - } - return extku; + return extku; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_genn.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_genn.c index ae79374a..609c5dae 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_genn.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_genn.c @@ -1,4 +1,3 @@ -/* v3_genn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -62,205 +61,210 @@ #include #include +#include "internal.h" + ASN1_SEQUENCE(OTHERNAME) = { - ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), - /* Maybe have a true ANY DEFINED BY later */ - ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) + ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), + // Maybe have a true ANY DEFINED BY later + ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0), } ASN1_SEQUENCE_END(OTHERNAME) -IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) +IMPLEMENT_ASN1_FUNCTIONS_const(OTHERNAME) ASN1_SEQUENCE(EDIPARTYNAME) = { - /* DirectoryString is a CHOICE type, so use explicit tagging. */ - ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), - ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) + // DirectoryString is a CHOICE type, so use explicit tagging. + ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), + ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1), } ASN1_SEQUENCE_END(EDIPARTYNAME) -IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) +IMPLEMENT_ASN1_FUNCTIONS_const(EDIPARTYNAME) ASN1_CHOICE(GENERAL_NAME) = { - ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), - ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), - ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), - /* Don't decode this */ - ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), - /* X509_NAME is a CHOICE type so use EXPLICIT */ - ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), - ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), - ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), - ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), - ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) + ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), + ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), + ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), + // Don't decode this + ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), + // X509_NAME is a CHOICE type so use EXPLICIT + ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), + ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), + ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, + GEN_URI), + ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), + ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID), } ASN1_CHOICE_END(GENERAL_NAME) IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) -ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) +ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, + 0, GeneralNames, + GENERAL_NAME) ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME) -static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) -{ - /* nameAssigner is optional and may be NULL. */ - if (a->nameAssigner == NULL) { - if (b->nameAssigner != NULL) { - return -1; - } - } else { - if (b->nameAssigner == NULL || - ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner) != 0) { - return -1; - } +static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) { + // nameAssigner is optional and may be NULL. + if (a->nameAssigner == NULL) { + if (b->nameAssigner != NULL) { + return -1; } + } else { + if (b->nameAssigner == NULL || + ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner) != 0) { + return -1; + } + } - /* partyName may not be NULL. */ - return ASN1_STRING_cmp(a->partyName, b->partyName); + // partyName may not be NULL. + return ASN1_STRING_cmp(a->partyName, b->partyName); } -/* Returns 0 if they are equal, != 0 otherwise. */ -int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) -{ - if (!a || !b || a->type != b->type) - return -1; - - switch (a->type) { - case GEN_X400: - return ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); - - case GEN_EDIPARTY: - return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); - - case GEN_OTHERNAME: - return OTHERNAME_cmp(a->d.otherName, b->d.otherName); - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - return ASN1_STRING_cmp(a->d.ia5, b->d.ia5); - - case GEN_DIRNAME: - return X509_NAME_cmp(a->d.dirn, b->d.dirn); - - case GEN_IPADD: - return ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); - - case GEN_RID: - return OBJ_cmp(a->d.rid, b->d.rid); - } +// Returns 0 if they are equal, != 0 otherwise. +static int othername_cmp(const OTHERNAME *a, const OTHERNAME *b) { + int result = -1; + if (!a || !b) { return -1; -} - -/* Returns 0 if they are equal, != 0 otherwise. */ -int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) -{ - int result = -1; - - if (!a || !b) - return -1; - /* Check their type first. */ - if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) - return result; - /* Check the value. */ - result = ASN1_TYPE_cmp(a->value, b->value); + } + // Check their type first. + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) { return result; + } + // Check the value. + result = ASN1_TYPE_cmp(a->value, b->value); + return result; } -void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) -{ - switch (type) { +// Returns 0 if they are equal, != 0 otherwise. +int GENERAL_NAME_cmp(const GENERAL_NAME *a, const GENERAL_NAME *b) { + if (!a || !b || a->type != b->type) { + return -1; + } + + switch (a->type) { case GEN_X400: - a->d.x400Address = value; - break; + return ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); case GEN_EDIPARTY: - a->d.ediPartyName = value; - break; + return edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); case GEN_OTHERNAME: - a->d.otherName = value; - break; + return othername_cmp(a->d.otherName, b->d.otherName); case GEN_EMAIL: case GEN_DNS: case GEN_URI: - a->d.ia5 = value; - break; + return ASN1_STRING_cmp(a->d.ia5, b->d.ia5); case GEN_DIRNAME: - a->d.dirn = value; - break; + return X509_NAME_cmp(a->d.dirn, b->d.dirn); case GEN_IPADD: - a->d.ip = value; - break; + return ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); case GEN_RID: - a->d.rid = value; - break; - } - a->type = type; + return OBJ_cmp(a->d.rid, b->d.rid); + } + + return -1; } -void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) -{ - if (ptype) - *ptype = a->type; - switch (a->type) { +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) { + switch (type) { case GEN_X400: - return a->d.x400Address; + a->d.x400Address = value; + break; case GEN_EDIPARTY: - return a->d.ediPartyName; + a->d.ediPartyName = value; + break; case GEN_OTHERNAME: - return a->d.otherName; + a->d.otherName = value; + break; case GEN_EMAIL: case GEN_DNS: case GEN_URI: - return a->d.ia5; + a->d.ia5 = value; + break; case GEN_DIRNAME: - return a->d.dirn; + a->d.dirn = value; + break; case GEN_IPADD: - return a->d.ip; + a->d.ip = value; + break; case GEN_RID: - return a->d.rid; + a->d.rid = value; + break; + } + a->type = type; +} + +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) { + if (ptype) { + *ptype = a->type; + } + switch (a->type) { + case GEN_X400: + return a->d.x400Address; + + case GEN_EDIPARTY: + return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; default: - return NULL; - } + return NULL; + } } -int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, ASN1_TYPE *value) -{ - OTHERNAME *oth; - oth = OTHERNAME_new(); - if (!oth) - return 0; - ASN1_TYPE_free(oth->value); - oth->type_id = oid; - oth->value = value; - GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); - return 1; +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, + ASN1_TYPE *value) { + OTHERNAME *oth; + oth = OTHERNAME_new(); + if (!oth) { + return 0; + } + ASN1_TYPE_free(oth->value); + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; } -int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, - ASN1_OBJECT **poid, ASN1_TYPE **pvalue) -{ - if (gen->type != GEN_OTHERNAME) - return 0; - if (poid) - *poid = gen->d.otherName->type_id; - if (pvalue) - *pvalue = gen->d.otherName->value; - return 1; +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **poid, + ASN1_TYPE **pvalue) { + if (gen->type != GEN_OTHERNAME) { + return 0; + } + if (poid) { + *poid = gen->d.otherName->type_id; + } + if (pvalue) { + *pvalue = gen->d.otherName->value; + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_ia5.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_ia5.c index 700200c5..e0f9e6bf 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_ia5.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_ia5.c @@ -1,4 +1,3 @@ -/* v3_ia5.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -70,10 +69,48 @@ #include "../internal.h" -static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - ASN1_IA5STRING *ia5); -static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); +static char *i2s_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, void *ext) { + const ASN1_IA5STRING *ia5 = ext; + char *tmp; + if (!ia5 || !ia5->length) { + return NULL; + } + if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { + return NULL; + } + OPENSSL_memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static void *s2i_ASN1_IA5STRING(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str) { + ASN1_IA5STRING *ia5; + if (!str) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = ASN1_IA5STRING_new())) { + goto err; + } + if (!ASN1_STRING_set(ia5, str, strlen(str))) { + ASN1_IA5STRING_free(ia5); + goto err; + } + return ia5; +err: + return NULL; +} + +#define EXT_IA5STRING(nid) \ + { \ + nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), 0, 0, 0, 0, i2s_ASN1_IA5STRING, \ + s2i_ASN1_IA5STRING, 0, 0, 0, 0, NULL \ + } + +#define EXT_END \ + { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + const X509V3_EXT_METHOD v3_ns_ia5_list[] = { EXT_IA5STRING(NID_netscape_base_url), EXT_IA5STRING(NID_netscape_revocation_url), @@ -82,40 +119,4 @@ const X509V3_EXT_METHOD v3_ns_ia5_list[] = { EXT_IA5STRING(NID_netscape_ca_policy_url), EXT_IA5STRING(NID_netscape_ssl_server_name), EXT_IA5STRING(NID_netscape_comment), - EXT_END -}; - -static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - ASN1_IA5STRING *ia5) -{ - char *tmp; - if (!ia5 || !ia5->length) - return NULL; - if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - OPENSSL_memcpy(tmp, ia5->data, ia5->length); - tmp[ia5->length] = 0; - return tmp; -} - -static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) -{ - ASN1_IA5STRING *ia5; - if (!str) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if (!(ia5 = ASN1_IA5STRING_new())) - goto err; - if (!ASN1_STRING_set(ia5, str, strlen(str))) { - ASN1_IA5STRING_free(ia5); - goto err; - } - return ia5; - err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; -} + EXT_END}; diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_info.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_info.c index 3615c71d..5e14b765 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_info.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_info.c @@ -1,4 +1,3 @@ -/* v3_info.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -68,151 +67,147 @@ #include #include -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, AUTHORITY_INFO_ACCESS - *ainfo, STACK_OF(CONF_VALUE) - *ret); -static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) - *nval); +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret); +static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); -const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, +const X509V3_EXT_METHOD v3_info = { + NID_info_access, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, - (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - 0, 0, - NULL + 0, + 0, + 0, + 0, + 0, + 0, + i2v_AUTHORITY_INFO_ACCESS, + v2i_AUTHORITY_INFO_ACCESS, + 0, + 0, + NULL, }; -const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, +const X509V3_EXT_METHOD v3_sinfo = { + NID_sinfo_access, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, - (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - 0, 0, - NULL + 0, + 0, + 0, + 0, + 0, + 0, + i2v_AUTHORITY_INFO_ACCESS, + v2i_AUTHORITY_INFO_ACCESS, + 0, + 0, + NULL, }; ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { - ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), - ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) + ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), + ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME), } ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) -ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) +ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( - X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, - STACK_OF(CONF_VALUE) *ret) -{ - ACCESS_DESCRIPTION *desc; - size_t i; - int nlen; - char objtmp[80], *ntmp; - CONF_VALUE *vtmp; - STACK_OF(CONF_VALUE) *tret = ret; + const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) { + const AUTHORITY_INFO_ACCESS *ainfo = ext; + ACCESS_DESCRIPTION *desc; + int nlen; + char objtmp[80], *ntmp; + CONF_VALUE *vtmp; + STACK_OF(CONF_VALUE) *tret = ret; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { - STACK_OF(CONF_VALUE) *tmp; - - desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); - tmp = i2v_GENERAL_NAME(method, desc->location, tret); - if (tmp == NULL) - goto err; - tret = tmp; - vtmp = sk_CONF_VALUE_value(tret, i); - i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); - nlen = strlen(objtmp) + strlen(vtmp->name) + 5; - ntmp = OPENSSL_malloc(nlen); - if (ntmp == NULL) - goto err; - OPENSSL_strlcpy(ntmp, objtmp, nlen); - OPENSSL_strlcat(ntmp, " - ", nlen); - OPENSSL_strlcat(ntmp, vtmp->name, nlen); - OPENSSL_free(vtmp->name); - vtmp->name = ntmp; + for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + STACK_OF(CONF_VALUE) *tmp; + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); + tmp = i2v_GENERAL_NAME(method, desc->location, tret); + if (tmp == NULL) { + goto err; } - if (ret == NULL && tret == NULL) - return sk_CONF_VALUE_new_null(); + tret = tmp; + vtmp = sk_CONF_VALUE_value(tret, i); + i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); + nlen = strlen(objtmp) + strlen(vtmp->name) + 5; + ntmp = OPENSSL_malloc(nlen); + if (ntmp == NULL) { + goto err; + } + OPENSSL_strlcpy(ntmp, objtmp, nlen); + OPENSSL_strlcat(ntmp, " - ", nlen); + OPENSSL_strlcat(ntmp, vtmp->name, nlen); + OPENSSL_free(vtmp->name); + vtmp->name = ntmp; + } + if (ret == NULL && tret == NULL) { + return sk_CONF_VALUE_new_null(); + } - return tret; - err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - if (ret == NULL && tret != NULL) - sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); + return tret; +err: + if (ret == NULL && tret != NULL) { + sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); + } + return NULL; +} + +static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + AUTHORITY_INFO_ACCESS *ainfo = NULL; + ACCESS_DESCRIPTION *acc; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { return NULL; -} - -static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) - *nval) -{ - AUTHORITY_INFO_ACCESS *ainfo = NULL; - CONF_VALUE *cnf, ctmp; - ACCESS_DESCRIPTION *acc; - size_t i; - int objlen; - char *objtmp, *ptmp; - if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (!(acc = ACCESS_DESCRIPTION_new()) || + !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { + goto err; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!(acc = ACCESS_DESCRIPTION_new()) - || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - ptmp = strchr(cnf->name, ';'); - if (!ptmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); - goto err; - } - objlen = ptmp - cnf->name; - ctmp.name = ptmp + 1; - ctmp.value = cnf->value; - if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) - goto err; - if (!(objtmp = OPENSSL_malloc(objlen + 1))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_strlcpy(objtmp, cnf->name, objlen + 1); - acc->method = OBJ_txt2obj(objtmp, 0); - if (!acc->method) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", objtmp); - OPENSSL_free(objtmp); - goto err; - } - OPENSSL_free(objtmp); - + char *ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; } - return ainfo; - err: - sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); - return NULL; + CONF_VALUE ctmp; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) { + goto err; + } + char *objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name); + if (objtmp == NULL) { + goto err; + } + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", objtmp); + OPENSSL_free(objtmp); + goto err; + } + OPENSSL_free(objtmp); + } + return ainfo; +err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; } -int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a) -{ - i2a_ASN1_OBJECT(bp, a->method); -#ifdef UNDEF - i2a_GENERAL_NAME(bp, a->location); -#endif - return 2; +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a) { + i2a_ASN1_OBJECT(bp, a->method); + return 2; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_int.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_int.c index 7bde446c..0ca2b5ec 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_int.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_int.c @@ -1,4 +1,3 @@ -/* v3_int.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -60,32 +59,63 @@ #include #include + +static char *i2s_ASN1_INTEGER_cb(const X509V3_EXT_METHOD *method, void *ext) { + return i2s_ASN1_INTEGER(method, ext); +} + +static void *s2i_asn1_int(const X509V3_EXT_METHOD *meth, const X509V3_CTX *ctx, + const char *value) { + return s2i_ASN1_INTEGER(meth, value); +} + const X509V3_EXT_METHOD v3_crl_num = { - NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + NID_crl_number, 0, - 0, 0, 0, 0, NULL + ASN1_ITEM_ref(ASN1_INTEGER), + 0, + 0, + 0, + 0, + i2s_ASN1_INTEGER_cb, + 0, + 0, + 0, + 0, + 0, + NULL, }; const X509V3_EXT_METHOD v3_delta_crl = { - NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + NID_delta_crl, 0, - 0, 0, 0, 0, NULL + ASN1_ITEM_ref(ASN1_INTEGER), + 0, + 0, + 0, + 0, + i2s_ASN1_INTEGER_cb, + 0, + 0, + 0, + 0, + 0, + NULL, }; -static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, - char *value) -{ - return s2i_ASN1_INTEGER(meth, value); -} - const X509V3_EXT_METHOD v3_inhibit_anyp = { - NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - (X509V3_EXT_S2I)s2i_asn1_int, - 0, 0, 0, 0, NULL + NID_inhibit_any_policy, + 0, + ASN1_ITEM_ref(ASN1_INTEGER), + 0, + 0, + 0, + 0, + i2s_ASN1_INTEGER_cb, + s2i_asn1_int, + 0, + 0, + 0, + 0, + NULL, }; diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_lib.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_lib.c index 1b57f672..d25b8397 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_lib.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_lib.c @@ -1,4 +1,3 @@ -/* v3_lib.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -58,6 +57,7 @@ */ /* X509 v3 extension utilities */ +#include #include #include @@ -71,309 +71,271 @@ #include "ext_dat.h" static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; -static void ext_list_free(X509V3_EXT_METHOD *ext); - -static int ext_stack_cmp(const X509V3_EXT_METHOD **a, - const X509V3_EXT_METHOD **b) -{ - return ((*a)->ext_nid - (*b)->ext_nid); +static int ext_stack_cmp(const X509V3_EXT_METHOD *const *a, + const X509V3_EXT_METHOD *const *b) { + return ((*a)->ext_nid - (*b)->ext_nid); } -int X509V3_EXT_add(X509V3_EXT_METHOD *ext) -{ - if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ext_list_free(ext); - return 0; - } - if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - ext_list_free(ext); - return 0; - } - return 1; +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) { + // We only support |ASN1_ITEM|-based extensions. + assert(ext->it != NULL); + + // TODO(davidben): This should be locked. Also check for duplicates. + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) { + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + return 0; + } + sk_X509V3_EXT_METHOD_sort(ext_list); + return 1; } -static int ext_cmp(const void *void_a, const void *void_b) -{ - const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a; - const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b; - return ext_stack_cmp(a, b); +static int ext_cmp(const void *void_a, const void *void_b) { + const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a; + const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b; + return ext_stack_cmp(a, b); } -const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) -{ - X509V3_EXT_METHOD tmp; - const X509V3_EXT_METHOD *t = &tmp, *const *ret; - size_t idx; +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) { + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const * ret; + size_t idx; - if (nid < 0) - return NULL; - tmp.ext_nid = nid; - ret = - bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, + if (nid < 0) { + return NULL; + } + tmp.ext_nid = nid; + ret = bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, sizeof(X509V3_EXT_METHOD *), ext_cmp); - if (ret) - return *ret; - if (!ext_list) - return NULL; + if (ret) { + return *ret; + } + if (!ext_list) { + return NULL; + } - sk_X509V3_EXT_METHOD_sort(ext_list); - if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) - return NULL; - return sk_X509V3_EXT_METHOD_value(ext_list, idx); + if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) { + return NULL; + } + return sk_X509V3_EXT_METHOD_value(ext_list, idx); } -const X509V3_EXT_METHOD *X509V3_EXT_get(const X509_EXTENSION *ext) -{ - int nid; - if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) - return NULL; - return X509V3_EXT_get_nid(nid); +const X509V3_EXT_METHOD *X509V3_EXT_get(const X509_EXTENSION *ext) { + int nid; + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) { + return NULL; + } + return X509V3_EXT_get_nid(nid); } -int X509V3_EXT_free(int nid, void *ext_data) -{ - const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid); - if (ext_method == NULL) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION); - return 0; - } +int X509V3_EXT_free(int nid, void *ext_data) { + const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid); + if (ext_method == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION); + return 0; + } - if (ext_method->it != NULL) - ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it)); - else if (ext_method->ext_free != NULL) - ext_method->ext_free(ext_data); - else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION); - return 0; - } - - return 1; + ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it)); + return 1; } -int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) -{ - for (; extlist->ext_nid != -1; extlist++) - if (!X509V3_EXT_add(extlist)) - return 0; - return 1; +int X509V3_EXT_add_alias(int nid_to, int nid_from) { +OPENSSL_BEGIN_ALLOW_DEPRECATED + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (!(tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + if (!X509V3_EXT_add(tmpext)) { + OPENSSL_free(tmpext); + return 0; + } + return 1; +OPENSSL_END_ALLOW_DEPRECATED } -int X509V3_EXT_add_alias(int nid_to, int nid_from) -{ - const X509V3_EXT_METHOD *ext; - X509V3_EXT_METHOD *tmpext; +// Legacy function: we don't need to add standard extensions any more because +// they are now kept in ext_dat.h. - if (!(ext = X509V3_EXT_get_nid(nid_from))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND); - return 0; - } - if (! - (tmpext = - (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return 0; - } - *tmpext = *ext; - tmpext->ext_nid = nid_to; - tmpext->ext_flags |= X509V3_EXT_DYNAMIC; - return X509V3_EXT_add(tmpext); -} +int X509V3_add_standard_extensions(void) { return 1; } -void X509V3_EXT_cleanup(void) -{ - sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); - ext_list = NULL; -} +// Return an extension internal structure -static void ext_list_free(X509V3_EXT_METHOD *ext) -{ - if (ext->ext_flags & X509V3_EXT_DYNAMIC) - OPENSSL_free(ext); -} +void *X509V3_EXT_d2i(const X509_EXTENSION *ext) { + const X509V3_EXT_METHOD *method; + const unsigned char *p; -/* - * Legacy function: we don't need to add standard extensions any more because - * they are now kept in ext_dat.h. - */ - -int X509V3_add_standard_extensions(void) -{ - return 1; -} - -/* Return an extension internal structure */ - -void *X509V3_EXT_d2i(const X509_EXTENSION *ext) -{ - const X509V3_EXT_METHOD *method; - const unsigned char *p; - - if (!(method = X509V3_EXT_get(ext))) - return NULL; - p = ext->value->data; - void *ret; - if (method->it) { - ret = ASN1_item_d2i(NULL, &p, ext->value->length, - ASN1_ITEM_ptr(method->it)); - } else { - ret = method->d2i(NULL, &p, ext->value->length); - } - if (ret == NULL) { - return NULL; - } - /* Check for trailing data. */ - if (p != ext->value->data + ext->value->length) { - if (method->it) { - ASN1_item_free(ret, ASN1_ITEM_ptr(method->it)); - } else { - method->ext_free(ret); - } - OPENSSL_PUT_ERROR(X509V3, X509V3_R_TRAILING_DATA_IN_EXTENSION); - return NULL; - } - return ret; + if (!(method = X509V3_EXT_get(ext))) { + return NULL; + } + p = ext->value->data; + void *ret = + ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it)); + if (ret == NULL) { + return NULL; + } + // Check for trailing data. + if (p != ext->value->data + ext->value->length) { + ASN1_item_free(ret, ASN1_ITEM_ptr(method->it)); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_TRAILING_DATA_IN_EXTENSION); + return NULL; + } + return ret; } void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *extensions, int nid, - int *out_critical, int *out_idx) -{ - int lastpos; - size_t i; - X509_EXTENSION *ex, *found_ex = NULL; - if (!extensions) { - if (out_idx) - *out_idx = -1; - if (out_critical) - *out_critical = -1; - return NULL; + int *out_critical, int *out_idx) { + int lastpos; + X509_EXTENSION *ex, *found_ex = NULL; + if (!extensions) { + if (out_idx) { + *out_idx = -1; } - if (out_idx) - lastpos = *out_idx + 1; - else - lastpos = 0; - if (lastpos < 0) - lastpos = 0; - for (i = lastpos; i < sk_X509_EXTENSION_num(extensions); i++) { - ex = sk_X509_EXTENSION_value(extensions, i); - if (OBJ_obj2nid(ex->object) == nid) { - if (out_idx) { - /* TODO(https://crbug.com/boringssl/379): Consistently reject - * duplicate extensions. */ - *out_idx = i; - found_ex = ex; - break; - } else if (found_ex) { - /* Found more than one */ - if (out_critical) - *out_critical = -2; - return NULL; - } - found_ex = ex; - } + if (out_critical) { + *out_critical = -1; } - if (found_ex) { - /* Found it */ - if (out_critical) - *out_critical = X509_EXTENSION_get_critical(found_ex); - return X509V3_EXT_d2i(found_ex); - } - - /* Extension not found */ - if (out_idx) - *out_idx = -1; - if (out_critical) - *out_critical = -1; return NULL; + } + if (out_idx) { + lastpos = *out_idx + 1; + } else { + lastpos = 0; + } + if (lastpos < 0) { + lastpos = 0; + } + for (size_t i = lastpos; i < sk_X509_EXTENSION_num(extensions); i++) { + ex = sk_X509_EXTENSION_value(extensions, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (out_idx) { + // TODO(https://crbug.com/boringssl/379): Consistently reject + // duplicate extensions. + *out_idx = (int)i; + found_ex = ex; + break; + } else if (found_ex) { + // Found more than one + if (out_critical) { + *out_critical = -2; + } + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + // Found it + if (out_critical) { + *out_critical = X509_EXTENSION_get_critical(found_ex); + } + return X509V3_EXT_d2i(found_ex); + } + + // Extension not found + if (out_idx) { + *out_idx = -1; + } + if (out_critical) { + *out_critical = -1; + } + return NULL; } -/* - * This function is a general extension append, replace and delete utility. - * The precise operation is governed by the 'flags' value. The 'crit' and - * 'value' arguments (if relevant) are the extensions internal structure. - */ +// This function is a general extension append, replace and delete utility. +// The precise operation is governed by the 'flags' value. The 'crit' and +// 'value' arguments (if relevant) are the extensions internal structure. int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, - int crit, unsigned long flags) -{ - int errcode, extidx = -1; - X509_EXTENSION *ext = NULL, *extmp; - STACK_OF(X509_EXTENSION) *ret = NULL; - unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + int crit, unsigned long flags) { + int errcode, extidx = -1; + X509_EXTENSION *ext = NULL, *extmp; + STACK_OF(X509_EXTENSION) *ret = NULL; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; - /* - * If appending we don't care if it exists, otherwise look for existing - * extension. - */ - if (ext_op != X509V3_ADD_APPEND) - extidx = X509v3_get_ext_by_NID(*x, nid, -1); + // If appending we don't care if it exists, otherwise look for existing + // extension. + if (ext_op != X509V3_ADD_APPEND) { + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + } - /* See if extension exists */ - if (extidx >= 0) { - /* If keep existing, nothing to do */ - if (ext_op == X509V3_ADD_KEEP_EXISTING) - return 1; - /* If default then its an error */ - if (ext_op == X509V3_ADD_DEFAULT) { - errcode = X509V3_R_EXTENSION_EXISTS; - goto err; - } - /* If delete, just delete it */ - if (ext_op == X509V3_ADD_DELETE) { - if (!sk_X509_EXTENSION_delete(*x, extidx)) - return -1; - return 1; - } - } else { - /* - * If replace existing or delete, error since extension must exist - */ - if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || - (ext_op == X509V3_ADD_DELETE)) { - errcode = X509V3_R_EXTENSION_NOT_FOUND; - goto err; - } + // See if extension exists + if (extidx >= 0) { + // If keep existing, nothing to do + if (ext_op == X509V3_ADD_KEEP_EXISTING) { + return 1; } - - /* - * If we get this far then we have to create an extension: could have - * some flags for alternative encoding schemes... - */ - - ext = X509V3_EXT_i2d(nid, crit, value); - - if (!ext) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION); - return 0; + // If default then its an error + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; } - - /* If extension exists replace it.. */ - if (extidx >= 0) { - extmp = sk_X509_EXTENSION_value(*x, extidx); - X509_EXTENSION_free(extmp); - if (!sk_X509_EXTENSION_set(*x, extidx, ext)) - return -1; - return 1; + // If delete, just delete it + if (ext_op == X509V3_ADD_DELETE) { + X509_EXTENSION *prev_ext = sk_X509_EXTENSION_delete(*x, extidx); + if (prev_ext == NULL) { + return -1; + } + X509_EXTENSION_free(prev_ext); + return 1; } + } else { + // If replace existing or delete, error since extension must exist + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } - if ((ret = *x) == NULL - && (ret = sk_X509_EXTENSION_new_null()) == NULL) - goto m_fail; - if (!sk_X509_EXTENSION_push(ret, ext)) - goto m_fail; + // If we get this far then we have to create an extension: could have + // some flags for alternative encoding schemes... - *x = ret; - return 1; + ext = X509V3_EXT_i2d(nid, crit, value); - m_fail: - if (ret != *x) - sk_X509_EXTENSION_free(ret); - X509_EXTENSION_free(ext); - return -1; - - err: - if (!(flags & X509V3_ADD_SILENT)) - OPENSSL_PUT_ERROR(X509V3, errcode); + if (!ext) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION); return 0; + } + + // If extension exists replace it.. + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) { + return -1; + } + return 1; + } + + if ((ret = *x) == NULL && (ret = sk_X509_EXTENSION_new_null()) == NULL) { + goto m_fail; + } + if (!sk_X509_EXTENSION_push(ret, ext)) { + goto m_fail; + } + + *x = ret; + return 1; + +m_fail: + if (ret != *x) { + sk_X509_EXTENSION_free(ret); + } + X509_EXTENSION_free(ext); + return -1; + +err: + if (!(flags & X509V3_ADD_SILENT)) { + OPENSSL_PUT_ERROR(X509V3, errcode); + } + return 0; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_ncons.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_ncons.c index 739a59ec..ac9559f5 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_ncons.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_ncons.c @@ -1,4 +1,3 @@ -/* v3_ncons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -70,43 +69,50 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind); static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, const char *name); -static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); +static int print_nc_ipadd(BIO *bp, const ASN1_OCTET_STRING *ip); static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); static int nc_dn(X509_NAME *sub, X509_NAME *nm); -static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); -static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); -static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); +static int nc_dns(const ASN1_IA5STRING *sub, const ASN1_IA5STRING *dns); +static int nc_email(const ASN1_IA5STRING *sub, const ASN1_IA5STRING *eml); +static int nc_uri(const ASN1_IA5STRING *uri, const ASN1_IA5STRING *base); const X509V3_EXT_METHOD v3_name_constraints = { - NID_name_constraints, 0, + NID_name_constraints, + 0, ASN1_ITEM_ref(NAME_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, - 0, v2i_NAME_CONSTRAINTS, - i2r_NAME_CONSTRAINTS, 0, - NULL + 0, + 0, + 0, + 0, + 0, + 0, + 0, + v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, + 0, + NULL, }; ASN1_SEQUENCE(GENERAL_SUBTREE) = { - ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), - ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), - ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) + ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), + ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), + ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1), } ASN1_SEQUENCE_END(GENERAL_SUBTREE) ASN1_SEQUENCE(NAME_CONSTRAINTS) = { - ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, - GENERAL_SUBTREE, 0), - ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, - GENERAL_SUBTREE, 1), + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, + GENERAL_SUBTREE, 0), + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, + GENERAL_SUBTREE, 1), } ASN1_SEQUENCE_END(NAME_CONSTRAINTS) @@ -114,445 +120,436 @@ IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - size_t i; - CONF_VALUE tval, *val; - STACK_OF(GENERAL_SUBTREE) **ptree = NULL; - NAME_CONSTRAINTS *ncons = NULL; - GENERAL_SUBTREE *sub = NULL; - ncons = NAME_CONSTRAINTS_new(); - if (!ncons) - goto memerr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!strncmp(val->name, "permitted", 9) && val->name[9]) { - ptree = &ncons->permittedSubtrees; - tval.name = val->name + 10; - } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { - ptree = &ncons->excludedSubtrees; - tval.name = val->name + 9; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); - goto err; - } - tval.value = val->value; - sub = GENERAL_SUBTREE_new(); - if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) - goto err; - if (!*ptree) - *ptree = sk_GENERAL_SUBTREE_new_null(); - if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) - goto memerr; - sub = NULL; + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) { + goto err; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + CONF_VALUE tval; + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) { + goto err; + } + if (!*ptree) { + *ptree = sk_GENERAL_SUBTREE_new_null(); + } + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) { + goto err; + } + sub = NULL; + } - return ncons; + return ncons; - memerr: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - err: - if (ncons) - NAME_CONSTRAINTS_free(ncons); - if (sub) - GENERAL_SUBTREE_free(sub); - - return NULL; +err: + NAME_CONSTRAINTS_free(ncons); + GENERAL_SUBTREE_free(sub); + return NULL; } static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, - BIO *bp, int ind) -{ - NAME_CONSTRAINTS *ncons = a; - do_i2r_name_constraints(method, ncons->permittedSubtrees, - bp, ind, "Permitted"); - do_i2r_name_constraints(method, ncons->excludedSubtrees, - bp, ind, "Excluded"); - return 1; + BIO *bp, int ind) { + NAME_CONSTRAINTS *ncons = a; + do_i2r_name_constraints(method, ncons->permittedSubtrees, bp, ind, + "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, bp, ind, "Excluded"); + return 1; } static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, - BIO *bp, int ind, const char *name) -{ - GENERAL_SUBTREE *tree; - size_t i; - if (sk_GENERAL_SUBTREE_num(trees) > 0) - BIO_printf(bp, "%*s%s:\n", ind, "", name); - for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { - tree = sk_GENERAL_SUBTREE_value(trees, i); - BIO_printf(bp, "%*s", ind + 2, ""); - if (tree->base->type == GEN_IPADD) - print_nc_ipadd(bp, tree->base->d.ip); - else - GENERAL_NAME_print(bp, tree->base); - BIO_puts(bp, "\n"); + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, + int ind, const char *name) { + GENERAL_SUBTREE *tree; + size_t i; + if (sk_GENERAL_SUBTREE_num(trees) > 0) { + BIO_printf(bp, "%*s%s:\n", ind, "", name); + } + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) { + print_nc_ipadd(bp, tree->base->d.ip); + } else { + GENERAL_NAME_print(bp, tree->base); } - return 1; + BIO_puts(bp, "\n"); + } + return 1; } -static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) -{ - int i, len; - unsigned char *p; - p = ip->data; - len = ip->length; - BIO_puts(bp, "IP:"); - if (len == 8) { - BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - } else if (len == 32) { - for (i = 0; i < 16; i++) { - BIO_printf(bp, "%X", p[0] << 8 | p[1]); - p += 2; - if (i == 7) - BIO_puts(bp, "/"); - else if (i != 15) - BIO_puts(bp, ":"); - } - } else - BIO_printf(bp, "IP Address:"); - return 1; +static int print_nc_ipadd(BIO *bp, const ASN1_OCTET_STRING *ip) { + int i, len; + unsigned char *p; + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", p[0], p[1], p[2], p[3], p[4], + p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + uint16_t v = ((uint16_t)p[0] << 8) | p[1]; + BIO_printf(bp, "%X", v); + p += 2; + if (i == 7) { + BIO_puts(bp, "/"); + } else if (i != 15) { + BIO_puts(bp, ":"); + } + } + } else { + BIO_printf(bp, "IP Address:"); + } + return 1; } -/*- - * Check a certificate conforms to a specified set of constraints. - * Return values: - * X509_V_OK: All constraints obeyed. - * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. - * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. - * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. - * X509_V_ERR_UNSPECIFIED: Unspecified error. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: Bad or unsupported constraint - * syntax. - * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: Bad or unsupported syntax of name. - */ +//- +// Check a certificate conforms to a specified set of constraints. +// Return values: +// X509_V_OK: All constraints obeyed. +// X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. +// X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. +// X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. +// X509_V_ERR_UNSPECIFIED: Unspecified error. +// X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. +// X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: Bad or unsupported constraint +// syntax. +// X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: Bad or unsupported syntax of name. -int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) -{ - int r, i; - size_t j; - X509_NAME *nm; +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) { + int r, i; + size_t j; + X509_NAME *nm; - nm = X509_get_subject_name(x); + nm = X509_get_subject_name(x); - /* Guard against certificates with an excessive number of names or - * constraints causing a computationally expensive name constraints - * check. */ - size_t name_count = - X509_NAME_entry_count(nm) + sk_GENERAL_NAME_num(x->altname); - size_t constraint_count = sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) + - sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); - size_t check_count = constraint_count * name_count; - if (name_count < (size_t)X509_NAME_entry_count(nm) || - constraint_count < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) || - (constraint_count && check_count / constraint_count != name_count) || - check_count > 1 << 20) { - return X509_V_ERR_UNSPECIFIED; + // Guard against certificates with an excessive number of names or + // constraints causing a computationally expensive name constraints + // check. + size_t name_count = + X509_NAME_entry_count(nm) + sk_GENERAL_NAME_num(x->altname); + size_t constraint_count = sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) + + sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); + size_t check_count = constraint_count * name_count; + if (name_count < (size_t)X509_NAME_entry_count(nm) || + constraint_count < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) || + (constraint_count && check_count / constraint_count != name_count) || + check_count > 1 << 20) { + return X509_V_ERR_UNSPECIFIED; + } + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) { + return r; } - if (X509_NAME_entry_count(nm) > 0) { - GENERAL_NAME gntmp; - gntmp.type = GEN_DIRNAME; - gntmp.d.directoryName = nm; + gntmp.type = GEN_EMAIL; - r = nc_match(&gntmp, nc); + // Process any email address attributes in subject name - if (r != X509_V_OK) - return r; + for (i = -1;;) { + i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); + if (i == -1) { + break; + } + const X509_NAME_ENTRY *ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } - gntmp.type = GEN_EMAIL; - - /* Process any email address attributes in subject name */ - - for (i = -1;;) { - X509_NAME_ENTRY *ne; - i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); - if (i == -1) - break; - ne = X509_NAME_get_entry(nm, i); - gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); - if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - - r = nc_match(&gntmp, nc); - - if (r != X509_V_OK) - return r; - } + r = nc_match(&gntmp, nc); + if (r != X509_V_OK) { + return r; + } } + } - for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); - r = nc_match(gen, nc); - if (r != X509_V_OK) - return r; + for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); + r = nc_match(gen, nc); + if (r != X509_V_OK) { + return r; } + } - return X509_V_OK; - + return X509_V_OK; } -static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) -{ - GENERAL_SUBTREE *sub; - int r, match = 0; - size_t i; +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) { + GENERAL_SUBTREE *sub; + int r, match = 0; + size_t i; - /* - * Permitted subtrees: if any subtrees exist of matching the type at - * least one subtree must match. - */ + // Permitted subtrees: if any subtrees exist of matching the type at + // least one subtree must match. - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - /* If we already have a match don't bother trying any more */ - if (match == 2) - continue; - if (match == 0) - match = 1; - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - match = 2; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) { + continue; + } + if (sub->minimum || sub->maximum) { + return X509_V_ERR_SUBTREE_MINMAX; + } + // If we already have a match don't bother trying any more + if (match == 2) { + continue; + } + if (match == 0) { + match = 1; + } + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) { + match = 2; + } else if (r != X509_V_ERR_PERMITTED_VIOLATION) { + return r; + } + } + + if (match == 1) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + + // Excluded subtrees: must not match any of these + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) { + continue; + } + if (sub->minimum || sub->maximum) { + return X509_V_ERR_SUBTREE_MINMAX; } - if (match == 1) - return X509_V_ERR_PERMITTED_VIOLATION; - - /* Excluded subtrees: must not match any of these */ - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - return X509_V_ERR_EXCLUDED_VIOLATION; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; - + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) { + return X509_V_ERR_EXCLUDED_VIOLATION; + } else if (r != X509_V_ERR_PERMITTED_VIOLATION) { + return r; } + } - return X509_V_OK; - + return X509_V_OK; } -static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) -{ - switch (base->type) { +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) { + switch (base->type) { case GEN_DIRNAME: - return nc_dn(gen->d.directoryName, base->d.directoryName); + return nc_dn(gen->d.directoryName, base->d.directoryName); case GEN_DNS: - return nc_dns(gen->d.dNSName, base->d.dNSName); + return nc_dns(gen->d.dNSName, base->d.dNSName); case GEN_EMAIL: - return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); case GEN_URI: - return nc_uri(gen->d.uniformResourceIdentifier, - base->d.uniformResourceIdentifier); + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); default: - return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; - } - + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } } -/* - * directoryName name constraint matching. The canonical encoding of - * X509_NAME makes this comparison easy. It is matched if the subtree is a - * subset of the name. - */ +// directoryName name constraint matching. The canonical encoding of +// X509_NAME makes this comparison easy. It is matched if the subtree is a +// subset of the name. -static int nc_dn(X509_NAME *nm, X509_NAME *base) -{ - /* Ensure canonical encodings are up to date. */ - if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->modified && i2d_X509_NAME(base, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->canon_enclen > nm->canon_enclen) - return X509_V_ERR_PERMITTED_VIOLATION; - if (OPENSSL_memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) - return X509_V_ERR_PERMITTED_VIOLATION; +static int nc_dn(X509_NAME *nm, X509_NAME *base) { + // Ensure canonical encodings are up to date. + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) { + return X509_V_ERR_OUT_OF_MEM; + } + if (base->modified && i2d_X509_NAME(base, NULL) < 0) { + return X509_V_ERR_OUT_OF_MEM; + } + if (base->canon_enclen > nm->canon_enclen) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + if (OPENSSL_memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + return X509_V_OK; +} + +static int starts_with(const CBS *cbs, uint8_t c) { + return CBS_len(cbs) > 0 && CBS_data(cbs)[0] == c; +} + +static int equal_case(const CBS *a, const CBS *b) { + if (CBS_len(a) != CBS_len(b)) { + return 0; + } + // Note we cannot use |OPENSSL_strncasecmp| because that would stop + // iterating at NUL. + const uint8_t *a_data = CBS_data(a), *b_data = CBS_data(b); + for (size_t i = 0; i < CBS_len(a); i++) { + if (OPENSSL_tolower(a_data[i]) != OPENSSL_tolower(b_data[i])) { + return 0; + } + } + return 1; +} + +static int has_suffix_case(const CBS *a, const CBS *b) { + if (CBS_len(a) < CBS_len(b)) { + return 0; + } + CBS copy = *a; + CBS_skip(©, CBS_len(a) - CBS_len(b)); + return equal_case(©, b); +} + +static int nc_dns(const ASN1_IA5STRING *dns, const ASN1_IA5STRING *base) { + CBS dns_cbs, base_cbs; + CBS_init(&dns_cbs, dns->data, dns->length); + CBS_init(&base_cbs, base->data, base->length); + + // Empty matches everything + if (CBS_len(&base_cbs) == 0) { return X509_V_OK; + } + + // If |base_cbs| begins with a '.', do a simple suffix comparison. This is + // not part of RFC5280, but is part of OpenSSL's original behavior. + if (starts_with(&base_cbs, '.')) { + if (has_suffix_case(&dns_cbs, &base_cbs)) { + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + // Otherwise can add zero or more components on the left so compare RHS + // and if dns is longer and expect '.' as preceding character. + if (CBS_len(&dns_cbs) > CBS_len(&base_cbs)) { + uint8_t dot; + if (!CBS_skip(&dns_cbs, CBS_len(&dns_cbs) - CBS_len(&base_cbs) - 1) || + !CBS_get_u8(&dns_cbs, &dot) || dot != '.') { + return X509_V_ERR_PERMITTED_VIOLATION; + } + } + + if (!equal_case(&dns_cbs, &base_cbs)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + + return X509_V_OK; } -static int starts_with(const CBS *cbs, uint8_t c) -{ - return CBS_len(cbs) > 0 && CBS_data(cbs)[0] == c; -} +static int nc_email(const ASN1_IA5STRING *eml, const ASN1_IA5STRING *base) { + CBS eml_cbs, base_cbs; + CBS_init(&eml_cbs, eml->data, eml->length); + CBS_init(&base_cbs, base->data, base->length); -static int equal_case(const CBS *a, const CBS *b) -{ - if (CBS_len(a) != CBS_len(b)) { - return 0; + // TODO(davidben): In OpenSSL 1.1.1, this switched from the first '@' to the + // last one. Match them here, or perhaps do an actual parse. Looks like + // multiple '@'s may be allowed in quoted strings. + CBS eml_local, base_local; + if (!CBS_get_until_first(&eml_cbs, &eml_local, '@')) { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + int base_has_at = CBS_get_until_first(&base_cbs, &base_local, '@'); + + // Special case: initial '.' is RHS match + if (!base_has_at && starts_with(&base_cbs, '.')) { + if (has_suffix_case(&eml_cbs, &base_cbs)) { + return X509_V_OK; } - /* Note we cannot use |OPENSSL_strncasecmp| because that would stop - * iterating at NUL. */ - const uint8_t *a_data = CBS_data(a), *b_data = CBS_data(b); - for (size_t i = 0; i < CBS_len(a); i++) { - if (OPENSSL_tolower(a_data[i]) != OPENSSL_tolower(b_data[i])) { - return 0; - } - } - return 1; -} + return X509_V_ERR_PERMITTED_VIOLATION; + } -static int has_suffix_case(const CBS *a, const CBS *b) -{ - if (CBS_len(a) < CBS_len(b)) { - return 0; - } - CBS copy = *a; - CBS_skip(©, CBS_len(a) - CBS_len(b)); - return equal_case(©, b); -} - -static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) -{ - CBS dns_cbs, base_cbs; - CBS_init(&dns_cbs, dns->data, dns->length); - CBS_init(&base_cbs, base->data, base->length); - - /* Empty matches everything */ - if (CBS_len(&base_cbs) == 0) { - return X509_V_OK; - } - - /* If |base_cbs| begins with a '.', do a simple suffix comparison. This is - * not part of RFC5280, but is part of OpenSSL's original behavior. */ - if (starts_with(&base_cbs, '.')) { - if (has_suffix_case(&dns_cbs, &base_cbs)) { - return X509_V_OK; - } + // If we have anything before '@' match local part + if (base_has_at) { + // TODO(davidben): This interprets a constraint of "@example.com" as + // "example.com", which is not part of RFC5280. + if (CBS_len(&base_local) > 0) { + // Case sensitive match of local part + if (!CBS_mem_equal(&base_local, CBS_data(&eml_local), + CBS_len(&eml_local))) { return X509_V_ERR_PERMITTED_VIOLATION; + } } + // Position base after '@' + assert(starts_with(&base_cbs, '@')); + CBS_skip(&base_cbs, 1); + } - /* - * Otherwise can add zero or more components on the left so compare RHS - * and if dns is longer and expect '.' as preceding character. - */ - if (CBS_len(&dns_cbs) > CBS_len(&base_cbs)) { - uint8_t dot; - if (!CBS_skip(&dns_cbs, CBS_len(&dns_cbs) - CBS_len(&base_cbs) - 1) || - !CBS_get_u8(&dns_cbs, &dot) || - dot != '.') { - return X509_V_ERR_PERMITTED_VIOLATION; - } - } - - if (!equal_case(&dns_cbs, &base_cbs)) { - return X509_V_ERR_PERMITTED_VIOLATION; - } - - return X509_V_OK; + // Just have hostname left to match: case insensitive + assert(starts_with(&eml_cbs, '@')); + CBS_skip(&eml_cbs, 1); + if (!equal_case(&base_cbs, &eml_cbs)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + return X509_V_OK; } -static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) -{ - CBS eml_cbs, base_cbs; - CBS_init(&eml_cbs, eml->data, eml->length); - CBS_init(&base_cbs, base->data, base->length); +static int nc_uri(const ASN1_IA5STRING *uri, const ASN1_IA5STRING *base) { + CBS uri_cbs, base_cbs; + CBS_init(&uri_cbs, uri->data, uri->length); + CBS_init(&base_cbs, base->data, base->length); - /* TODO(davidben): In OpenSSL 1.1.1, this switched from the first '@' to the - * last one. Match them here, or perhaps do an actual parse. Looks like - * multiple '@'s may be allowed in quoted strings. */ - CBS eml_local, base_local; - if (!CBS_get_until_first(&eml_cbs, &eml_local, '@')) { - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + // Check for foo:// and skip past it + CBS scheme; + uint8_t byte; + if (!CBS_get_until_first(&uri_cbs, &scheme, ':') || + !CBS_skip(&uri_cbs, 1) || // Skip the colon + !CBS_get_u8(&uri_cbs, &byte) || byte != '/' || + !CBS_get_u8(&uri_cbs, &byte) || byte != '/') { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + + // Look for a port indicator as end of hostname first. Otherwise look for + // trailing slash, or the end of the string. + // TODO(davidben): This is not a correct URI parser and mishandles IPv6 + // literals. + CBS host; + if (!CBS_get_until_first(&uri_cbs, &host, ':') && + !CBS_get_until_first(&uri_cbs, &host, '/')) { + host = uri_cbs; + } + + if (CBS_len(&host) == 0) { + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + } + + // Special case: initial '.' is RHS match + if (starts_with(&base_cbs, '.')) { + if (has_suffix_case(&host, &base_cbs)) { + return X509_V_OK; } - int base_has_at = CBS_get_until_first(&base_cbs, &base_local, '@'); + return X509_V_ERR_PERMITTED_VIOLATION; + } - /* Special case: inital '.' is RHS match */ - if (!base_has_at && starts_with(&base_cbs, '.')) { - if (has_suffix_case(&eml_cbs, &base_cbs)) { - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - /* If we have anything before '@' match local part */ - if (base_has_at) { - /* TODO(davidben): This interprets a constraint of "@example.com" as - * "example.com", which is not part of RFC5280. */ - if (CBS_len(&base_local) > 0) { - /* Case sensitive match of local part */ - if (!CBS_mem_equal(&base_local, CBS_data(&eml_local), - CBS_len(&eml_local))) { - return X509_V_ERR_PERMITTED_VIOLATION; - } - } - /* Position base after '@' */ - assert(starts_with(&base_cbs, '@')); - CBS_skip(&base_cbs, 1); - } - - /* Just have hostname left to match: case insensitive */ - assert(starts_with(&eml_cbs, '@')); - CBS_skip(&eml_cbs, 1); - if (!equal_case(&base_cbs, &eml_cbs)) { - return X509_V_ERR_PERMITTED_VIOLATION; - } - - return X509_V_OK; -} - -static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) -{ - CBS uri_cbs, base_cbs; - CBS_init(&uri_cbs, uri->data, uri->length); - CBS_init(&base_cbs, base->data, base->length); - - /* Check for foo:// and skip past it */ - CBS scheme; - uint8_t byte; - if (!CBS_get_until_first(&uri_cbs, &scheme, ':') || - !CBS_skip(&uri_cbs, 1) || // Skip the colon - !CBS_get_u8(&uri_cbs, &byte) || byte != '/' || - !CBS_get_u8(&uri_cbs, &byte) || byte != '/') { - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - } - - /* Look for a port indicator as end of hostname first. Otherwise look for - * trailing slash, or the end of the string. - * TODO(davidben): This is not a correct URI parser and mishandles IPv6 - * literals. */ - CBS host; - if (!CBS_get_until_first(&uri_cbs, &host, ':') && - !CBS_get_until_first(&uri_cbs, &host, '/')) { - host = uri_cbs; - } - - if (CBS_len(&host) == 0) { - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - } - - /* Special case: inital '.' is RHS match */ - if (starts_with(&base_cbs, '.')) { - if (has_suffix_case(&host, &base_cbs)) { - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - if (!equal_case(&base_cbs, &host)) { - return X509_V_ERR_PERMITTED_VIOLATION; - } - - return X509_V_OK; + if (!equal_case(&base_cbs, &host)) { + return X509_V_ERR_PERMITTED_VIOLATION; + } + return X509_V_OK; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_ocsp.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_ocsp.c index c63646a2..f0ed0b82 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_ocsp.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_ocsp.c @@ -13,56 +13,69 @@ #include #include -/* - * OCSP extensions and a couple of CRL entry extensions - */ +// OCSP extensions and a couple of CRL entry extensions static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); -static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, - void *nocheck, BIO *out, int indent); +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, + BIO *out, int indent); static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str); + const X509V3_CTX *ctx, const char *str); const X509V3_EXT_METHOD v3_crl_invdate = { - NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_ocsp_acutoff, 0, - NULL + NID_invalidity_date, + 0, + ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + i2r_ocsp_acutoff, + 0, + NULL, }; const X509V3_EXT_METHOD v3_ocsp_nocheck = { - NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), - 0, 0, 0, 0, - 0, s2i_ocsp_nocheck, - 0, 0, - i2r_ocsp_nocheck, 0, - NULL + NID_id_pkix_OCSP_noCheck, + 0, + ASN1_ITEM_ref(ASN1_NULL), + 0, + 0, + 0, + 0, + 0, + s2i_ocsp_nocheck, + 0, + 0, + i2r_ocsp_nocheck, + 0, + NULL, }; static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, - BIO *bp, int ind) -{ - if (BIO_printf(bp, "%*s", ind, "") <= 0) - return 0; - if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) - return 0; - return 1; + BIO *bp, int ind) { + if (BIO_printf(bp, "%*s", ind, "") <= 0) { + return 0; + } + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) { + return 0; + } + return 1; } -/* Nocheck is just a single NULL. Don't print anything and always set it */ +// Nocheck is just a single NULL. Don't print anything and always set it static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, - BIO *out, int indent) -{ - return 1; + BIO *out, int indent) { + return 1; } static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str) -{ - return ASN1_NULL_new(); + const X509V3_CTX *ctx, const char *str) { + return ASN1_NULL_new(); } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_pci.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_pci.c deleted file mode 100644 index 57b64ef7..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_pci.c +++ /dev/null @@ -1,289 +0,0 @@ -/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ -/* - * Contributed to the OpenSSL Project 2004 by Richard Levitte - * (richard@levitte.org) - */ -/* Copyright (c) 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "../internal.h" -#include "internal.h" - - -static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, - BIO *out, int indent); -static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); - -const X509V3_EXT_METHOD v3_pci = - { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), - 0, 0, 0, 0, - 0, 0, - NULL, NULL, - (X509V3_EXT_I2R)i2r_pci, - (X509V3_EXT_R2I)r2i_pci, - NULL, -}; - -static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, - BIO *out, int indent) -{ - BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); - if (pci->pcPathLengthConstraint) - i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); - else - BIO_printf(out, "infinite"); - BIO_puts(out, "\n"); - BIO_printf(out, "%*sPolicy Language: ", indent, ""); - i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); - BIO_puts(out, "\n"); - if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) - BIO_printf(out, "%*sPolicy Text: %.*s\n", indent, "", - pci->proxyPolicy->policy->length, - pci->proxyPolicy->policy->data); - return 1; -} - -static int process_pci_value(CONF_VALUE *val, - ASN1_OBJECT **language, ASN1_INTEGER **pathlen, - ASN1_OCTET_STRING **policy) -{ - int free_policy = 0; - - if (strcmp(val->name, "language") == 0) { - if (*language) { - OPENSSL_PUT_ERROR(X509V3, - X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); - X509V3_conf_err(val); - return 0; - } - if (!(*language = OBJ_txt2obj(val->value, 0))) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return 0; - } - } else if (strcmp(val->name, "pathlen") == 0) { - if (*pathlen) { - OPENSSL_PUT_ERROR(X509V3, - X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); - X509V3_conf_err(val); - return 0; - } - if (!X509V3_get_value_int(val, pathlen)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH); - X509V3_conf_err(val); - return 0; - } - } else if (strcmp(val->name, "policy") == 0) { - unsigned char *tmp_data = NULL; - long val_len; - if (!*policy) { - *policy = ASN1_OCTET_STRING_new(); - if (!*policy) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - return 0; - } - free_policy = 1; - } - if (strncmp(val->value, "hex:", 4) == 0) { - unsigned char *tmp_data2 = - x509v3_hex_to_bytes(val->value + 4, &val_len); - - if (!tmp_data2) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT); - X509V3_conf_err(val); - goto err; - } - - tmp_data = OPENSSL_realloc((*policy)->data, - (*policy)->length + val_len + 1); - if (tmp_data) { - (*policy)->data = tmp_data; - OPENSSL_memcpy(&(*policy)->data[(*policy)->length], - tmp_data2, val_len); - (*policy)->length += val_len; - (*policy)->data[(*policy)->length] = '\0'; - } else { - OPENSSL_free(tmp_data2); - /* - * realloc failure implies the original data space is b0rked - * too! - */ - (*policy)->data = NULL; - (*policy)->length = 0; - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - OPENSSL_free(tmp_data2); - } else if (strncmp(val->value, "text:", 5) == 0) { - val_len = strlen(val->value + 5); - tmp_data = OPENSSL_realloc((*policy)->data, - (*policy)->length + val_len + 1); - if (tmp_data) { - (*policy)->data = tmp_data; - OPENSSL_memcpy(&(*policy)->data[(*policy)->length], - val->value + 5, val_len); - (*policy)->length += val_len; - (*policy)->data[(*policy)->length] = '\0'; - } else { - /* - * realloc failure implies the original data space is b0rked - * too! - */ - (*policy)->data = NULL; - (*policy)->length = 0; - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); - X509V3_conf_err(val); - goto err; - } - if (!tmp_data) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - } - return 1; - err: - if (free_policy) { - ASN1_OCTET_STRING_free(*policy); - *policy = NULL; - } - return 0; -} - -static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value) -{ - PROXY_CERT_INFO_EXTENSION *pci = NULL; - STACK_OF(CONF_VALUE) *vals; - ASN1_OBJECT *language = NULL; - ASN1_INTEGER *pathlen = NULL; - ASN1_OCTET_STRING *policy = NULL; - size_t i, j; - int nid; - - vals = X509V3_parse_list(value); - for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { - CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); - if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING); - X509V3_conf_err(cnf); - goto err; - } - if (*cnf->name == '@') { - STACK_OF(CONF_VALUE) *sect; - int success_p = 1; - - sect = X509V3_get_section(ctx, cnf->name + 1); - if (!sect) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION); - X509V3_conf_err(cnf); - goto err; - } - for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { - success_p = - process_pci_value(sk_CONF_VALUE_value(sect, j), - &language, &pathlen, &policy); - } - X509V3_section_free(ctx, sect); - if (!success_p) - goto err; - } else { - if (!process_pci_value(cnf, &language, &pathlen, &policy)) { - X509V3_conf_err(cnf); - goto err; - } - } - } - - /* Language is mandatory */ - if (!language) { - OPENSSL_PUT_ERROR(X509V3, - X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); - goto err; - } - nid = OBJ_obj2nid(language); - if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) { - OPENSSL_PUT_ERROR(X509V3, - X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); - goto err; - } - - pci = PROXY_CERT_INFO_EXTENSION_new(); - if (!pci) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - - pci->proxyPolicy->policyLanguage = language; - language = NULL; - pci->proxyPolicy->policy = policy; - policy = NULL; - pci->pcPathLengthConstraint = pathlen; - pathlen = NULL; - goto end; - err: - if (language) { - ASN1_OBJECT_free(language); - language = NULL; - } - if (pathlen) { - ASN1_INTEGER_free(pathlen); - pathlen = NULL; - } - if (policy) { - ASN1_OCTET_STRING_free(policy); - policy = NULL; - } - if (pci) { - PROXY_CERT_INFO_EXTENSION_free(pci); - pci = NULL; - } - end: - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - return pci; -} diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_pcia.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_pcia.c deleted file mode 100644 index 3f285f30..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_pcia.c +++ /dev/null @@ -1,57 +0,0 @@ -/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ -/* - * Contributed to the OpenSSL Project 2004 by Richard Levitte - * (richard@levitte.org) - */ -/* Copyright (c) 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - - -ASN1_SEQUENCE(PROXY_POLICY) = - { - ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), - ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(PROXY_POLICY) - -IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) - -ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = - { - ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), - ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) -} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) - -IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_pcons.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_pcons.c index 1a463143..7b70a4e4 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_pcons.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_pcons.c @@ -1,4 +1,3 @@ -/* v3_pcons.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -65,75 +64,79 @@ #include #include -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD - *method, void *bcons, STACK_OF(CONF_VALUE) - *extlist); +#include "internal.h" + + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS( + const X509V3_EXT_METHOD *method, void *bcons, + STACK_OF(CONF_VALUE) *extlist); static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); const X509V3_EXT_METHOD v3_policy_constraints = { - NID_policy_constraints, 0, + NID_policy_constraints, + 0, ASN1_ITEM_ref(POLICY_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, i2v_POLICY_CONSTRAINTS, v2i_POLICY_CONSTRAINTS, - NULL, NULL, - NULL -}; + NULL, + NULL, + NULL}; ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { - ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), - ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) + ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER, 0), + ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER, 1), } ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *extlist) -{ - POLICY_CONSTRAINTS *pcons = a; - X509V3_add_value_int("Require Explicit Policy", - pcons->requireExplicitPolicy, &extlist); - X509V3_add_value_int("Inhibit Policy Mapping", - pcons->inhibitPolicyMapping, &extlist); - return extlist; +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS( + const X509V3_EXT_METHOD *method, void *a, STACK_OF(CONF_VALUE) *extlist) { + const POLICY_CONSTRAINTS *pcons = a; + X509V3_add_value_int("Require Explicit Policy", pcons->requireExplicitPolicy, + &extlist); + X509V3_add_value_int("Inhibit Policy Mapping", pcons->inhibitPolicyMapping, + &extlist); + return extlist; } static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - POLICY_CONSTRAINTS *pcons = NULL; - CONF_VALUE *val; - size_t i; - if (!(pcons = POLICY_CONSTRAINTS_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "requireExplicitPolicy")) { - if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) - goto err; - } else if (!strcmp(val->name, "inhibitPolicyMapping")) { - if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) - goto err; - } else { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); - goto err; - } - - return pcons; - err: - POLICY_CONSTRAINTS_free(pcons); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values) { + POLICY_CONSTRAINTS *pcons = NULL; + if (!(pcons = POLICY_CONSTRAINTS_new())) { return NULL; + } + for (size_t i = 0; i < sk_CONF_VALUE_num(values); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) { + goto err; + } + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) { + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; +err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_pmaps.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_pmaps.c index caacdb27..cd8efd6d 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_pmaps.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_pmaps.c @@ -1,4 +1,3 @@ -/* v3_pmaps.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -63,92 +62,89 @@ #include #include +#include "internal.h" + + static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD - *method, void *pmps, STACK_OF(CONF_VALUE) - *extlist); + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( + const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist); const X509V3_EXT_METHOD v3_policy_mappings = { - NID_policy_mappings, 0, + NID_policy_mappings, + 0, ASN1_ITEM_ref(POLICY_MAPPINGS), - 0, 0, 0, 0, - 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, i2v_POLICY_MAPPINGS, v2i_POLICY_MAPPINGS, - 0, 0, - NULL + 0, + 0, + NULL, }; ASN1_SEQUENCE(POLICY_MAPPING) = { - ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), - ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) + ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), + ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT), } ASN1_SEQUENCE_END(POLICY_MAPPING) -ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, - POLICY_MAPPING) +ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, POLICY_MAPPING) ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *ext_list) -{ - POLICY_MAPPINGS *pmaps = a; - POLICY_MAPPING *pmap; - size_t i; - char obj_tmp1[80]; - char obj_tmp2[80]; - for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { - pmap = sk_POLICY_MAPPING_value(pmaps, i); - i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); - i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); - X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); - } - return ext_list; +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( + const X509V3_EXT_METHOD *method, void *a, STACK_OF(CONF_VALUE) *ext_list) { + const POLICY_MAPPINGS *pmaps = a; + for (size_t i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + const POLICY_MAPPING *pmap = sk_POLICY_MAPPING_value(pmaps, i); + char obj_tmp1[80], obj_tmp2[80]; + i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); + i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); + X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); + } + return ext_list; } static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - POLICY_MAPPINGS *pmaps; - POLICY_MAPPING *pmap; - ASN1_OBJECT *obj1, *obj2; - CONF_VALUE *val; - size_t i; + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval) { + POLICY_MAPPINGS *pmaps = sk_POLICY_MAPPING_new_null(); + if (pmaps == NULL) { + return NULL; + } - if (!(pmaps = sk_POLICY_MAPPING_new_null())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; + for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { + const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + goto err; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!val->value || !val->name) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - obj1 = OBJ_txt2obj(val->name, 0); - obj2 = OBJ_txt2obj(val->value, 0); - if (!obj1 || !obj2) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - pmap = POLICY_MAPPING_new(); - if (!pmap) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - pmap->issuerDomainPolicy = obj1; - pmap->subjectDomainPolicy = obj2; - sk_POLICY_MAPPING_push(pmaps, pmap); + POLICY_MAPPING *pmap = POLICY_MAPPING_new(); + if (pmap == NULL || !sk_POLICY_MAPPING_push(pmaps, pmap)) { + POLICY_MAPPING_free(pmap); + goto err; } - return pmaps; + + pmap->issuerDomainPolicy = OBJ_txt2obj(val->name, 0); + pmap->subjectDomainPolicy = OBJ_txt2obj(val->value, 0); + if (!pmap->issuerDomainPolicy || !pmap->subjectDomainPolicy) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + goto err; + } + } + return pmaps; + +err: + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + return NULL; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_prn.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_prn.c index ee4c4824..f6260e24 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_prn.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_prn.c @@ -1,4 +1,3 @@ -/* v3_prn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -55,7 +54,7 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -/* X509 v3 extension utilities */ +// X509 v3 extension utilities #include @@ -64,167 +63,163 @@ #include #include -/* Extension printing routines */ +// Extension printing routines -static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, +static int unknown_ext_print(BIO *out, const X509_EXTENSION *ext, unsigned long flag, int indent, int supported); -/* Print out a name+value stack */ +// Print out a name+value stack -void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, - int ml) -{ - size_t i; - CONF_VALUE *nval; - if (!val) - return; - if (!ml || !sk_CONF_VALUE_num(val)) { - BIO_printf(out, "%*s", indent, ""); - if (!sk_CONF_VALUE_num(val)) - BIO_puts(out, "\n"); +void X509V3_EXT_val_prn(BIO *out, const STACK_OF(CONF_VALUE) *val, int indent, + int ml) { + if (!val) { + return; + } + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) { + BIO_puts(out, "\n"); } - for (i = 0; i < sk_CONF_VALUE_num(val); i++) { - if (ml) - BIO_printf(out, "%*s", indent, ""); - else if (i > 0) - BIO_printf(out, ", "); - nval = sk_CONF_VALUE_value(val, i); - if (!nval->name) - BIO_puts(out, nval->value); - else if (!nval->value) - BIO_puts(out, nval->name); - else - BIO_printf(out, "%s:%s", nval->name, nval->value); - if (ml) - BIO_puts(out, "\n"); + } + for (size_t i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) { + BIO_printf(out, "%*s", indent, ""); + } else if (i > 0) { + BIO_printf(out, ", "); } + const CONF_VALUE *nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) { + BIO_puts(out, nval->value); + } else if (!nval->value) { + BIO_puts(out, nval->name); + } else { + BIO_printf(out, "%s:%s", nval->name, nval->value); + } + if (ml) { + BIO_puts(out, "\n"); + } + } } -/* Main routine: print out a general extension */ +// Main routine: print out a general extension -int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent) -{ - void *ext_str = NULL; - char *value = NULL; - const X509V3_EXT_METHOD *method; - STACK_OF(CONF_VALUE) *nval = NULL; - int ok = 1; - - if (!(method = X509V3_EXT_get(ext))) - return unknown_ext_print(out, ext, flag, indent, 0); - const ASN1_STRING *ext_data = X509_EXTENSION_get_data(ext); - const unsigned char *p = ASN1_STRING_get0_data(ext_data); - if (method->it) { - ext_str = ASN1_item_d2i(NULL, &p, ASN1_STRING_length(ext_data), +int X509V3_EXT_print(BIO *out, const X509_EXTENSION *ext, unsigned long flag, + int indent) { + const X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); + if (method == NULL) { + return unknown_ext_print(out, ext, flag, indent, 0); + } + const ASN1_STRING *ext_data = X509_EXTENSION_get_data(ext); + const unsigned char *p = ASN1_STRING_get0_data(ext_data); + void *ext_str = ASN1_item_d2i(NULL, &p, ASN1_STRING_length(ext_data), ASN1_ITEM_ptr(method->it)); - } else { - ext_str = method->d2i(NULL, &p, ASN1_STRING_length(ext_data)); + if (!ext_str) { + return unknown_ext_print(out, ext, flag, indent, 1); + } + + char *value = NULL; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 0; + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + goto err; } + BIO_printf(out, "%*s%s", indent, "", value); + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) { + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED); + goto err; + } - if (!ext_str) - return unknown_ext_print(out, ext, flag, indent, 1); + ok = 1; - if (method->i2s) { - if (!(value = method->i2s(method, ext_str))) { - ok = 0; - goto err; - } - BIO_printf(out, "%*s%s", indent, "", value); - } else if (method->i2v) { - if (!(nval = method->i2v(method, ext_str, NULL))) { - ok = 0; - goto err; - } - X509V3_EXT_val_prn(out, nval, indent, - method->ext_flags & X509V3_EXT_MULTILINE); - } else if (method->i2r) { - if (!method->i2r(method, ext_str, out, indent)) - ok = 0; - } else - ok = 0; - - err: - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - if (value) - OPENSSL_free(value); - if (method->it) - ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); - else - method->ext_free(ext_str); - return ok; +err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + OPENSSL_free(value); + ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); + return ok; } int X509V3_extensions_print(BIO *bp, const char *title, const STACK_OF(X509_EXTENSION) *exts, - unsigned long flag, int indent) -{ - size_t i; - int j; + unsigned long flag, int indent) { + size_t i; + int j; - if (sk_X509_EXTENSION_num(exts) <= 0) - return 1; - - if (title) { - BIO_printf(bp, "%*s%s:\n", indent, "", title); - indent += 4; - } - - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ex; - ex = sk_X509_EXTENSION_value(exts, i); - if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) - return 0; - obj = X509_EXTENSION_get_object(ex); - i2a_ASN1_OBJECT(bp, obj); - j = X509_EXTENSION_get_critical(ex); - if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) - return 0; - if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { - BIO_printf(bp, "%*s", indent + 4, ""); - ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); - } - if (BIO_write(bp, "\n", 1) <= 0) - return 0; - } + if (sk_X509_EXTENSION_num(exts) <= 0) { return 1; + } + + if (title) { + BIO_printf(bp, "%*s%s:\n", indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + const X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) { + return 0; + } + const ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) { + return 0; + } + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); + } + if (BIO_write(bp, "\n", 1) <= 0) { + return 0; + } + } + return 1; } -static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, - unsigned long flag, int indent, int supported) -{ - switch (flag & X509V3_EXT_UNKNOWN_MASK) { - +static int unknown_ext_print(BIO *out, const X509_EXTENSION *ext, + unsigned long flag, int indent, int supported) { + switch (flag & X509V3_EXT_UNKNOWN_MASK) { case X509V3_EXT_DEFAULT: - return 0; + return 0; case X509V3_EXT_ERROR_UNKNOWN: - if (supported) - BIO_printf(out, "%*s", indent, ""); - else - BIO_printf(out, "%*s", indent, ""); - return 1; + if (supported) { + BIO_printf(out, "%*s", indent, ""); + } else { + BIO_printf(out, "%*s", indent, ""); + } + return 1; case X509V3_EXT_PARSE_UNKNOWN: case X509V3_EXT_DUMP_UNKNOWN: { - const ASN1_STRING *data = X509_EXTENSION_get_data(ext); - return BIO_hexdump(out, ASN1_STRING_get0_data(data), - ASN1_STRING_length(data), indent); + const ASN1_STRING *data = X509_EXTENSION_get_data(ext); + return BIO_hexdump(out, ASN1_STRING_get0_data(data), + ASN1_STRING_length(data), indent); } default: - return 1; - } + return 1; + } } -int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) -{ - BIO *bio_tmp; - int ret; - if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) - return 0; - ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); - BIO_free(bio_tmp); - return ret; +int X509V3_EXT_print_fp(FILE *fp, const X509_EXTENSION *ext, int flag, + int indent) { + BIO *bio_tmp; + int ret; + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + return 0; + } + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_purp.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_purp.c index 133839ad..1f5a88cd 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_purp.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_purp.c @@ -1,4 +1,3 @@ -/* v3_purp.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2001. @@ -59,8 +58,8 @@ #include -#include #include +#include #include #include #include @@ -70,13 +69,13 @@ #include "../x509/internal.h" #include "internal.h" -#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define V1_ROOT (EXFLAG_V1 | EXFLAG_SS) #define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) #define xku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) #define ns_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); @@ -96,16 +95,14 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); -static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b); +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); static void xptable_free(X509_PURPOSE *p); static X509_PURPOSE xstandard[] = { {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, - check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient", - NULL}, + check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient", NULL}, {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, - check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", - NULL}, + check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", NULL}, {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, (char *)"Netscape SSL server", (char *)"nssslserver", NULL}, @@ -125,805 +122,767 @@ static X509_PURPOSE xstandard[] = { (char *)"timestampsign", NULL}, }; -#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) +#define X509_PURPOSE_COUNT (sizeof(xstandard) / sizeof(X509_PURPOSE)) static STACK_OF(X509_PURPOSE) *xptable = NULL; -static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b) -{ - return (*a)->purpose - (*b)->purpose; +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) { + return (*a)->purpose - (*b)->purpose; } -/* - * As much as I'd like to make X509_check_purpose use a "const" X509* I - * really can't because it does recalculate hashes and do other non-const - * things. - */ -int X509_check_purpose(X509 *x, int id, int ca) -{ - int idx; - const X509_PURPOSE *pt; - if (!x509v3_cache_extensions(x)) { - return -1; - } - - if (id == -1) - return 1; - idx = X509_PURPOSE_get_by_id(id); - if (idx == -1) - return -1; - pt = X509_PURPOSE_get0(idx); - return pt->check_purpose(pt, x, ca); -} - -int X509_PURPOSE_set(int *p, int purpose) -{ - if (X509_PURPOSE_get_by_id(purpose) == -1) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE); - return 0; - } - *p = purpose; - return 1; -} - -int X509_PURPOSE_get_count(void) -{ - if (!xptable) - return X509_PURPOSE_COUNT; - return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; -} - -X509_PURPOSE *X509_PURPOSE_get0(int idx) -{ - if (idx < 0) - return NULL; - if (idx < (int)X509_PURPOSE_COUNT) - return xstandard + idx; - return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); -} - -int X509_PURPOSE_get_by_sname(char *sname) -{ - int i; - X509_PURPOSE *xptmp; - for (i = 0; i < X509_PURPOSE_get_count(); i++) { - xptmp = X509_PURPOSE_get0(i); - if (!strcmp(xptmp->sname, sname)) - return i; - } +// As much as I'd like to make X509_check_purpose use a "const" X509* I +// really can't because it does recalculate hashes and do other non-const +// things. +int X509_check_purpose(X509 *x, int id, int ca) { + int idx; + const X509_PURPOSE *pt; + if (!x509v3_cache_extensions(x)) { return -1; + } + + if (id == -1) { + return 1; + } + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) { + return -1; + } + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); } -int X509_PURPOSE_get_by_id(int purpose) -{ - X509_PURPOSE tmp; - size_t idx; +int X509_PURPOSE_set(int *p, int purpose) { + if (X509_PURPOSE_get_by_id(purpose) == -1) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} - if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) - return purpose - X509_PURPOSE_MIN; - tmp.purpose = purpose; - if (!xptable) - return -1; +int X509_PURPOSE_get_count(void) { + if (!xptable) { + return X509_PURPOSE_COUNT; + } + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} - sk_X509_PURPOSE_sort(xptable); - if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) - return -1; - return idx + X509_PURPOSE_COUNT; +X509_PURPOSE *X509_PURPOSE_get0(int idx) { + if (idx < 0) { + return NULL; + } + if (idx < (int)X509_PURPOSE_COUNT) { + return xstandard + idx; + } + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} + +int X509_PURPOSE_get_by_sname(const char *sname) { + X509_PURPOSE *xptmp; + for (int i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) { + return i; + } + } + return -1; +} + +int X509_PURPOSE_get_by_id(int purpose) { + X509_PURPOSE tmp; + size_t idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) { + return purpose - X509_PURPOSE_MIN; + } + tmp.purpose = purpose; + if (!xptable) { + return -1; + } + + if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) { + return -1; + } + return idx + X509_PURPOSE_COUNT; } int X509_PURPOSE_add(int id, int trust, int flags, - int (*ck) (const X509_PURPOSE *, const X509 *, int), - char *name, char *sname, void *arg) -{ - int idx; - X509_PURPOSE *ptmp; - char *name_dup, *sname_dup; + int (*ck)(const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg) { + X509_PURPOSE *ptmp; + char *name_dup, *sname_dup; - /* - * This is set according to what we change: application can't set it - */ - flags &= ~X509_PURPOSE_DYNAMIC; - /* This will always be set for application modified trust entries */ - flags |= X509_PURPOSE_DYNAMIC_NAME; - /* Get existing entry if any */ - idx = X509_PURPOSE_get_by_id(id); - /* Need a new entry */ + // This is set according to what we change: application can't set it + flags &= ~X509_PURPOSE_DYNAMIC; + // This will always be set for application modified trust entries + flags |= X509_PURPOSE_DYNAMIC_NAME; + // Get existing entry if any + int idx = X509_PURPOSE_get_by_id(id); + // Need a new entry + if (idx == -1) { + if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else { + ptmp = X509_PURPOSE_get0(idx); + } + + // Duplicate the supplied names. + name_dup = OPENSSL_strdup(name); + sname_dup = OPENSSL_strdup(sname); + if (name_dup == NULL || sname_dup == NULL) { + if (name_dup != NULL) { + OPENSSL_free(name_dup); + } + if (sname_dup != NULL) { + OPENSSL_free(sname_dup); + } if (idx == -1) { - if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return 0; - } - ptmp->flags = X509_PURPOSE_DYNAMIC; - } else - ptmp = X509_PURPOSE_get0(idx); - - /* Duplicate the supplied names. */ - name_dup = OPENSSL_strdup(name); - sname_dup = OPENSSL_strdup(sname); - if (name_dup == NULL || sname_dup == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - if (name_dup != NULL) - OPENSSL_free(name_dup); - if (sname_dup != NULL) - OPENSSL_free(sname_dup); - if (idx == -1) - OPENSSL_free(ptmp); - return 0; + OPENSSL_free(ptmp); } - - /* OPENSSL_free existing name if dynamic */ - if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { - OPENSSL_free(ptmp->name); - OPENSSL_free(ptmp->sname); - } - /* dup supplied name */ - ptmp->name = name_dup; - ptmp->sname = sname_dup; - /* Keep the dynamic flag of existing entry */ - ptmp->flags &= X509_PURPOSE_DYNAMIC; - /* Set all other flags */ - ptmp->flags |= flags; - - ptmp->purpose = id; - ptmp->trust = trust; - ptmp->check_purpose = ck; - ptmp->usr_data = arg; - - /* If its a new entry manage the dynamic table */ - if (idx == -1) { - if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - xptable_free(ptmp); - return 0; - } - if (!sk_X509_PURPOSE_push(xptable, ptmp)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - xptable_free(ptmp); - return 0; - } - } - return 1; -} - -static void xptable_free(X509_PURPOSE *p) -{ - if (!p) - return; - if (p->flags & X509_PURPOSE_DYNAMIC) { - if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { - OPENSSL_free(p->name); - OPENSSL_free(p->sname); - } - OPENSSL_free(p); - } -} - -void X509_PURPOSE_cleanup(void) -{ - unsigned int i; - sk_X509_PURPOSE_pop_free(xptable, xptable_free); - for (i = 0; i < X509_PURPOSE_COUNT; i++) - xptable_free(xstandard + i); - xptable = NULL; -} - -int X509_PURPOSE_get_id(const X509_PURPOSE *xp) -{ - return xp->purpose; -} - -char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp) -{ - return xp->name; -} - -char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) -{ - return xp->sname; -} - -int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) -{ - return xp->trust; -} - -static int nid_cmp(const void *void_a, const void *void_b) -{ - const int *a = void_a, *b = void_b; - - return *a - *b; -} - -int X509_supported_extension(X509_EXTENSION *ex) -{ - /* - * This table is a list of the NIDs of supported extensions: that is - * those which are used by the verify process. If an extension is - * critical and doesn't appear in this list then the verify process will - * normally reject the certificate. The list must be kept in numerical - * order because it will be searched using bsearch. - */ - - static const int supported_nids[] = { - NID_netscape_cert_type, /* 71 */ - NID_key_usage, /* 83 */ - NID_subject_alt_name, /* 85 */ - NID_basic_constraints, /* 87 */ - NID_certificate_policies, /* 89 */ - NID_ext_key_usage, /* 126 */ - NID_policy_constraints, /* 401 */ - NID_proxyCertInfo, /* 663 */ - NID_name_constraints, /* 666 */ - NID_policy_mappings, /* 747 */ - NID_inhibit_any_policy /* 748 */ - }; - - int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); - - if (ex_nid == NID_undef) - return 0; - - if (bsearch - (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int), - sizeof(int), nid_cmp) != NULL) - return 1; return 0; + } + + // OPENSSL_free existing name if dynamic + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(ptmp->name); + OPENSSL_free(ptmp->sname); + } + // dup supplied name + ptmp->name = name_dup; + ptmp->sname = sname_dup; + // Keep the dynamic flag of existing entry + ptmp->flags &= X509_PURPOSE_DYNAMIC; + // Set all other flags + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + // If its a new entry manage the dynamic table + if (idx == -1) { + // TODO(davidben): This should be locked. Alternatively, remove the dynamic + // registration mechanism entirely. The trouble is there no way to pass in + // the various parameters into an |X509_VERIFY_PARAM| directly. You can only + // register it in the global table and get an ID. + if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { + xptable_free(ptmp); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + xptable_free(ptmp); + return 0; + } + sk_X509_PURPOSE_sort(xptable); + } + return 1; } -static int setup_dp(X509 *x, DIST_POINT *dp) -{ - X509_NAME *iname = NULL; - size_t i; - if (dp->reasons) { - if (dp->reasons->length > 0) - dp->dp_reasons = dp->reasons->data[0]; - if (dp->reasons->length > 1) - dp->dp_reasons |= (dp->reasons->data[1] << 8); - dp->dp_reasons &= CRLDP_ALL_REASONS; - } else - dp->dp_reasons = CRLDP_ALL_REASONS; - if (!dp->distpoint || (dp->distpoint->type != 1)) - return 1; - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type == GEN_DIRNAME) { - iname = gen->d.directoryName; - break; - } +static void xptable_free(X509_PURPOSE *p) { + if (!p) { + return; + } + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(p->name); + OPENSSL_free(p->sname); } - if (!iname) - iname = X509_get_issuer_name(x); - - return DIST_POINT_set_dpname(dp->distpoint, iname); + OPENSSL_free(p); + } } -static int setup_crldp(X509 *x) -{ - int j; - x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &j, NULL); - if (x->crldp == NULL && j != -1) { - return 0; - } - for (size_t i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) { - return 0; - } - } +void X509_PURPOSE_cleanup(void) { + unsigned int i; + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + for (i = 0; i < X509_PURPOSE_COUNT; i++) { + xptable_free(xstandard + i); + } + xptable = NULL; +} + +int X509_PURPOSE_get_id(const X509_PURPOSE *xp) { return xp->purpose; } + +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp) { return xp->name; } + +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) { return xp->sname; } + +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) { return xp->trust; } + +static int nid_cmp(const void *void_a, const void *void_b) { + const int *a = void_a, *b = void_b; + + return *a - *b; +} + +int X509_supported_extension(const X509_EXTENSION *ex) { + // This table is a list of the NIDs of supported extensions: that is + // those which are used by the verify process. If an extension is + // critical and doesn't appear in this list then the verify process will + // normally reject the certificate. The list must be kept in numerical + // order because it will be searched using bsearch. + + static const int supported_nids[] = { + NID_netscape_cert_type, // 71 + NID_key_usage, // 83 + NID_subject_alt_name, // 85 + NID_basic_constraints, // 87 + NID_certificate_policies, // 89 + NID_ext_key_usage, // 126 + NID_policy_constraints, // 401 + NID_name_constraints, // 666 + NID_policy_mappings, // 747 + NID_inhibit_any_policy // 748 + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) { + return 0; + } + + if (bsearch(&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int), + sizeof(int), nid_cmp) != NULL) { return 1; + } + return 0; } -int x509v3_cache_extensions(X509 *x) -{ - BASIC_CONSTRAINTS *bs; - PROXY_CERT_INFO_EXTENSION *pci; - ASN1_BIT_STRING *usage; - ASN1_BIT_STRING *ns; - EXTENDED_KEY_USAGE *extusage; - X509_EXTENSION *ex; - size_t i; - int j; - - CRYPTO_MUTEX_lock_read(&x->lock); - const int is_set = x->ex_flags & EXFLAG_SET; - CRYPTO_MUTEX_unlock_read(&x->lock); - - if (is_set) { - return (x->ex_flags & EXFLAG_INVALID) == 0; +static int setup_dp(X509 *x, DIST_POINT *dp) { + X509_NAME *iname = NULL; + size_t i; + if (dp->reasons) { + if (dp->reasons->length > 0) { + dp->dp_reasons = dp->reasons->data[0]; } - - CRYPTO_MUTEX_lock_write(&x->lock); - if (x->ex_flags & EXFLAG_SET) { - CRYPTO_MUTEX_unlock_write(&x->lock); - return (x->ex_flags & EXFLAG_INVALID) == 0; + if (dp->reasons->length > 1) { + dp->dp_reasons |= (dp->reasons->data[1] << 8); } - - if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL)) - x->ex_flags |= EXFLAG_INVALID; - /* V1 should mean no extensions ... */ - if (X509_get_version(x) == X509_VERSION_1) - x->ex_flags |= EXFLAG_V1; - /* Handle basic constraints */ - if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &j, NULL))) { - if (bs->ca) - x->ex_flags |= EXFLAG_CA; - if (bs->pathlen) { - if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) - || !bs->ca) { - x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; - } else { - /* TODO(davidben): |ASN1_INTEGER_get| returns -1 on overflow, - * which currently acts as if the constraint isn't present. This - * works (an overflowing path length constraint may as well be - * infinity), but Chromium's verifier simply treats values above - * 255 as an error. */ - x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); - } - } else - x->ex_pathlen = -1; - BASIC_CONSTRAINTS_free(bs); - x->ex_flags |= EXFLAG_BCONS; - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else { + dp->dp_reasons = CRLDP_ALL_REASONS; + } + if (!dp->distpoint || (dp->distpoint->type != 1)) { + return 1; + } + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; } - /* Handle proxy certificates */ - if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &j, NULL))) { - if (x->ex_flags & EXFLAG_CA - || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 - || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { - x->ex_flags |= EXFLAG_INVALID; - } - if (pci->pcPathLengthConstraint) { - x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); - } else - x->ex_pcpathlen = -1; - PROXY_CERT_INFO_EXTENSION_free(pci); - x->ex_flags |= EXFLAG_PROXY; - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - /* Handle key usage */ - if ((usage = X509_get_ext_d2i(x, NID_key_usage, &j, NULL))) { - if (usage->length > 0) { - x->ex_kusage = usage->data[0]; - if (usage->length > 1) - x->ex_kusage |= usage->data[1] << 8; - } else - x->ex_kusage = 0; - x->ex_flags |= EXFLAG_KUSAGE; - ASN1_BIT_STRING_free(usage); - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - x->ex_xkusage = 0; - if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &j, NULL))) { - x->ex_flags |= EXFLAG_XKUSAGE; - for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { - switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { - case NID_server_auth: - x->ex_xkusage |= XKU_SSL_SERVER; - break; + } + if (!iname) { + iname = X509_get_issuer_name(x); + } - case NID_client_auth: - x->ex_xkusage |= XKU_SSL_CLIENT; - break; + return DIST_POINT_set_dpname(dp->distpoint, iname); +} - case NID_email_protect: - x->ex_xkusage |= XKU_SMIME; - break; - - case NID_code_sign: - x->ex_xkusage |= XKU_CODE_SIGN; - break; - - case NID_ms_sgc: - case NID_ns_sgc: - x->ex_xkusage |= XKU_SGC; - break; - - case NID_OCSP_sign: - x->ex_xkusage |= XKU_OCSP_SIGN; - break; - - case NID_time_stamp: - x->ex_xkusage |= XKU_TIMESTAMP; - break; - - case NID_dvcs: - x->ex_xkusage |= XKU_DVCS; - break; - - case NID_anyExtendedKeyUsage: - x->ex_xkusage |= XKU_ANYEKU; - break; - } - } - sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; +static int setup_crldp(X509 *x) { + int j; + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &j, NULL); + if (x->crldp == NULL && j != -1) { + return 0; + } + for (size_t i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) { + return 0; } + } + return 1; +} - if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &j, NULL))) { - if (ns->length > 0) - x->ex_nscert = ns->data[0]; - else - x->ex_nscert = 0; - x->ex_flags |= EXFLAG_NSCERT; - ASN1_BIT_STRING_free(ns); - } else if (j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &j, NULL); - if (x->skid == NULL && j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &j, NULL); - if (x->akid == NULL && j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - /* Does subject name match issuer ? */ - if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { - x->ex_flags |= EXFLAG_SI; - /* If SKID matches AKID also indicate self signed */ - if (X509_check_akid(x, x->akid) == X509_V_OK && - !ku_reject(x, KU_KEY_CERT_SIGN)) - x->ex_flags |= EXFLAG_SS; - } - x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &j, NULL); - if (x->altname == NULL && j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL); - if (x->nc == NULL && j != -1) { - x->ex_flags |= EXFLAG_INVALID; - } - if (!setup_crldp(x)) { - x->ex_flags |= EXFLAG_INVALID; - } +int x509v3_cache_extensions(X509 *x) { + BASIC_CONSTRAINTS *bs; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + size_t i; + int j; - for (j = 0; j < X509_get_ext_count(x); j++) { - ex = X509_get_ext(x, j); - if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) - == NID_freshest_crl) - x->ex_flags |= EXFLAG_FRESHEST; - if (!X509_EXTENSION_get_critical(ex)) - continue; - if (!X509_supported_extension(ex)) { - x->ex_flags |= EXFLAG_CRITICAL; - break; - } - } - x->ex_flags |= EXFLAG_SET; + CRYPTO_MUTEX_lock_read(&x->lock); + const int is_set = x->ex_flags & EXFLAG_SET; + CRYPTO_MUTEX_unlock_read(&x->lock); + if (is_set) { + return (x->ex_flags & EXFLAG_INVALID) == 0; + } + + CRYPTO_MUTEX_lock_write(&x->lock); + if (x->ex_flags & EXFLAG_SET) { CRYPTO_MUTEX_unlock_write(&x->lock); return (x->ex_flags & EXFLAG_INVALID) == 0; + } + + if (!X509_digest(x, EVP_sha256(), x->cert_hash, NULL)) { + x->ex_flags |= EXFLAG_INVALID; + } + // V1 should mean no extensions ... + if (X509_get_version(x) == X509_VERSION_1) { + x->ex_flags |= EXFLAG_V1; + } + // Handle basic constraints + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &j, NULL))) { + if (bs->ca) { + x->ex_flags |= EXFLAG_CA; + } + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else { + // TODO(davidben): |ASN1_INTEGER_get| returns -1 on overflow, + // which currently acts as if the constraint isn't present. This + // works (an overflowing path length constraint may as well be + // infinity), but Chromium's verifier simply treats values above + // 255 as an error. + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } + } else { + x->ex_pathlen = -1; + } + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + // Handle key usage + if ((usage = X509_get_ext_d2i(x, NID_key_usage, &j, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) { + x->ex_kusage |= usage->data[1] << 8; + } + } else { + x->ex_kusage = 0; + } + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &j, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + + case NID_anyExtendedKeyUsage: + x->ex_xkusage |= XKU_ANYEKU; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &j, NULL))) { + if (ns->length > 0) { + x->ex_nscert = ns->data[0]; + } else { + x->ex_nscert = 0; + } + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } else if (j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &j, NULL); + if (x->skid == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &j, NULL); + if (x->akid == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + // Does subject name match issuer ? + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { + x->ex_flags |= EXFLAG_SI; + // If SKID matches AKID also indicate self signed + if (X509_check_akid(x, x->akid) == X509_V_OK && + !ku_reject(x, KU_KEY_CERT_SIGN)) { + x->ex_flags |= EXFLAG_SS; + } + } + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &j, NULL); + if (x->altname == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL); + if (x->nc == NULL && j != -1) { + x->ex_flags |= EXFLAG_INVALID; + } + if (!setup_crldp(x)) { + x->ex_flags |= EXFLAG_INVALID; + } + + for (j = 0; j < X509_get_ext_count(x); j++) { + const X509_EXTENSION *ex = X509_get_ext(x, j); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_freshest_crl) { + x->ex_flags |= EXFLAG_FRESHEST; + } + if (!X509_EXTENSION_get_critical(ex)) { + continue; + } + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + x->ex_flags |= EXFLAG_SET; + + CRYPTO_MUTEX_unlock_write(&x->lock); + return (x->ex_flags & EXFLAG_INVALID) == 0; } -/* check_ca returns one if |x| should be considered a CA certificate and zero - * otherwise. */ -static int check_ca(const X509 *x) -{ - /* keyUsage if present should allow cert signing */ - if (ku_reject(x, KU_KEY_CERT_SIGN)) - return 0; - /* Version 1 certificates are considered CAs and don't have extensions. */ - if ((x->ex_flags & V1_ROOT) == V1_ROOT) { - return 1; - } - /* Otherwise, it's only a CA if basicConstraints says so. */ - return ((x->ex_flags & EXFLAG_BCONS) && - (x->ex_flags & EXFLAG_CA)); +// check_ca returns one if |x| should be considered a CA certificate and zero +// otherwise. +static int check_ca(const X509 *x) { + // keyUsage if present should allow cert signing + if (ku_reject(x, KU_KEY_CERT_SIGN)) { + return 0; + } + // Version 1 certificates are considered CAs and don't have extensions. + if ((x->ex_flags & V1_ROOT) == V1_ROOT) { + return 1; + } + // Otherwise, it's only a CA if basicConstraints says so. + return ((x->ex_flags & EXFLAG_BCONS) && (x->ex_flags & EXFLAG_CA)); } -int X509_check_ca(X509 *x) -{ - if (!x509v3_cache_extensions(x)) { - return 0; - } - return check_ca(x); +int X509_check_ca(X509 *x) { + if (!x509v3_cache_extensions(x)) { + return 0; + } + return check_ca(x); } static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (xku_reject(x, XKU_SSL_CLIENT)) - return 0; - if (ca) - return check_ca(x); - /* We need to do digital signatures or key agreement */ - if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) - return 0; - /* nsCertType if present should allow SSL client use */ - if (ns_reject(x, NS_SSL_CLIENT)) - return 0; - return 1; + int ca) { + if (xku_reject(x, XKU_SSL_CLIENT)) { + return 0; + } + if (ca) { + return check_ca(x); + } + // We need to do digital signatures or key agreement + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) { + return 0; + } + // nsCertType if present should allow SSL client use + if (ns_reject(x, NS_SSL_CLIENT)) { + return 0; + } + return 1; } -/* - * Key usage needed for TLS/SSL server: digital signature, encipherment or - * key agreement. The ssl code can check this more thoroughly for individual - * key types. - */ -#define KU_TLS \ - (KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT) +// Key usage needed for TLS/SSL server: digital signature, encipherment or +// key agreement. The ssl code can check this more thoroughly for individual +// key types. +#define KU_TLS (KU_DIGITAL_SIGNATURE | KU_KEY_ENCIPHERMENT | KU_KEY_AGREEMENT) static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (xku_reject(x, XKU_SSL_SERVER)) - return 0; - if (ca) - return check_ca(x); + int ca) { + if (xku_reject(x, XKU_SSL_SERVER)) { + return 0; + } + if (ca) { + return check_ca(x); + } - if (ns_reject(x, NS_SSL_SERVER)) - return 0; - if (ku_reject(x, KU_TLS)) - return 0; - - return 1; + if (ns_reject(x, NS_SSL_SERVER)) { + return 0; + } + if (ku_reject(x, KU_TLS)) { + return 0; + } + return 1; } static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = check_purpose_ssl_server(xp, x, ca); - if (!ret || ca) - return ret; - /* We need to encipher or Netscape complains */ - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; + int ca) { + int ret; + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) { return ret; + } + // We need to encipher or Netscape complains + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) { + return 0; + } + return ret; } -/* purpose_smime returns one if |x| is a valid S/MIME leaf (|ca| is zero) or CA - * (|ca| is one) certificate, and zero otherwise. */ -static int purpose_smime(const X509 *x, int ca) -{ - if (xku_reject(x, XKU_SMIME)) - return 0; - if (ca) { - /* check nsCertType if present */ - if ((x->ex_flags & EXFLAG_NSCERT) && - (x->ex_nscert & NS_SMIME_CA) == 0) { - return 0; - } +// purpose_smime returns one if |x| is a valid S/MIME leaf (|ca| is zero) or CA +// (|ca| is one) certificate, and zero otherwise. +static int purpose_smime(const X509 *x, int ca) { + if (xku_reject(x, XKU_SMIME)) { + return 0; + } + if (ca) { + // check nsCertType if present + if ((x->ex_flags & EXFLAG_NSCERT) && (x->ex_nscert & NS_SMIME_CA) == 0) { + return 0; + } - return check_ca(x); - } - if (x->ex_flags & EXFLAG_NSCERT) { - return (x->ex_nscert & NS_SMIME) == NS_SMIME; - } - return 1; + return check_ca(x); + } + if (x->ex_flags & EXFLAG_NSCERT) { + return (x->ex_nscert & NS_SMIME) == NS_SMIME; + } + return 1; } static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) - return 0; + int ca) { + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) { return ret; + } + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) { + return 0; + } + return ret; } static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; + int ca) { + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) { return ret; + } + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) { + return 0; + } + return ret; } static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (ca) { - return check_ca(x); - } - if (ku_reject(x, KU_CRL_SIGN)) - return 0; - return 1; + int ca) { + if (ca) { + return check_ca(x); + } + if (ku_reject(x, KU_CRL_SIGN)) { + return 0; + } + return 1; } -/* - * OCSP helper: this is *not* a full OCSP check. It just checks that each CA - * is valid. Additional checks must be made on the chain. - */ +// OCSP helper: this is *not* a full OCSP check. It just checks that each CA +// is valid. Additional checks must be made on the chain. -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - if (ca) - return check_ca(x); - /* leaf certificate is checked in OCSP_verify() */ - return 1; +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) { + if (ca) { + return check_ca(x); + } + // leaf certificate is checked in OCSP_verify() + return 1; } static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int i_ext; + int ca) { + int i_ext; - /* If ca is true we must return if this is a valid CA certificate. */ - if (ca) - return check_ca(x); + // If ca is true we must return if this is a valid CA certificate. + if (ca) { + return check_ca(x); + } - /* - * Check the optional key usage field: - * if Key Usage is present, it must be one of digitalSignature - * and/or nonRepudiation (other values are not consistent and shall - * be rejected). - */ - if ((x->ex_flags & EXFLAG_KUSAGE) - && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || - !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) - return 0; + // Check the optional key usage field: + // if Key Usage is present, it must be one of digitalSignature + // and/or nonRepudiation (other values are not consistent and shall + // be rejected). + if ((x->ex_flags & EXFLAG_KUSAGE) && + ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) { + return 0; + } - /* Only time stamp key usage is permitted and it's required. */ - if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) - return 0; + // Only time stamp key usage is permitted and it's required. + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) { + return 0; + } - /* Extended Key Usage MUST be critical */ - i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); - if (i_ext >= 0) { - X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); - if (!X509_EXTENSION_get_critical(ext)) - return 0; + // Extended Key Usage MUST be critical + i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + const X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) { + return 0; } + } - return 1; + return 1; } -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - return 1; +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) { return 1; } + +// Various checks to see if one certificate issued the second. This can be +// used to prune a set of possible issuer certificates which have been looked +// up using some simple method such as by subject name. These are: 1. Check +// issuer_name(subject) == subject_name(issuer) 2. If akid(subject) exists +// check it matches issuer 3. If key_usage(issuer) exists check it supports +// certificate signing returns 0 for OK, positive for reason for mismatch, +// reasons match codes for X509_verify_cert() + +int X509_check_issued(X509 *issuer, X509 *subject) { + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) { + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + } + if (!x509v3_cache_extensions(issuer) || !x509v3_cache_extensions(subject)) { + return X509_V_ERR_UNSPECIFIED; + } + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) { + return ret; + } + } + + if (ku_reject(issuer, KU_KEY_CERT_SIGN)) { + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + } + return X509_V_OK; } -/* - * Various checks to see if one certificate issued the second. This can be - * used to prune a set of possible issuer certificates which have been looked - * up using some simple method such as by subject name. These are: 1. Check - * issuer_name(subject) == subject_name(issuer) 2. If akid(subject) exists - * check it matches issuer 3. If key_usage(issuer) exists check it supports - * certificate signing returns 0 for OK, positive for reason for mismatch, - * reasons match codes for X509_verify_cert() - */ - -int X509_check_issued(X509 *issuer, X509 *subject) -{ - if (X509_NAME_cmp(X509_get_subject_name(issuer), - X509_get_issuer_name(subject))) - return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; - if (!x509v3_cache_extensions(issuer) || - !x509v3_cache_extensions(subject)) { - return X509_V_ERR_UNSPECIFIED; - } - - if (subject->akid) { - int ret = X509_check_akid(issuer, subject->akid); - if (ret != X509_V_OK) - return ret; - } - - if (subject->ex_flags & EXFLAG_PROXY) { - if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) - return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; - } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) - return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) { + if (!akid) { return X509_V_OK; -} + } -int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) -{ - - if (!akid) - return X509_V_OK; - - /* Check key ids (if present) */ - if (akid->keyid && issuer->skid && - ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) - return X509_V_ERR_AKID_SKID_MISMATCH; - /* Check serial number */ - if (akid->serial && - ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - /* Check issuer name */ - if (akid->issuer) { - /* - * Ugh, for some peculiar reason AKID includes SEQUENCE OF - * GeneralName. So look for a DirName. There may be more than one but - * we only take any notice of the first. - */ - GENERAL_NAMES *gens; - GENERAL_NAME *gen; - X509_NAME *nm = NULL; - size_t i; - gens = akid->issuer; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type == GEN_DIRNAME) { - nm = gen->d.dirn; - break; - } - } - if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + // Check key ids (if present) + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) { + return X509_V_ERR_AKID_SKID_MISMATCH; + } + // Check serial number + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) { + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + // Check issuer name + if (akid->issuer) { + // Ugh, for some peculiar reason AKID includes SEQUENCE OF + // GeneralName. So look for a DirName. There may be more than one but + // we only take any notice of the first. + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + size_t i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } } - return X509_V_OK; -} - -uint32_t X509_get_extension_flags(X509 *x) -{ - /* Ignore the return value. On failure, |x->ex_flags| will include - * |EXFLAG_INVALID|. */ - x509v3_cache_extensions(x); - return x->ex_flags; -} - -uint32_t X509_get_key_usage(X509 *x) -{ - if (!x509v3_cache_extensions(x)) { - return 0; + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) { + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; } - if (x->ex_flags & EXFLAG_KUSAGE) - return x->ex_kusage; - return UINT32_MAX; + } + return X509_V_OK; } -uint32_t X509_get_extended_key_usage(X509 *x) -{ - if (!x509v3_cache_extensions(x)) { - return 0; - } - if (x->ex_flags & EXFLAG_XKUSAGE) - return x->ex_xkusage; - return UINT32_MAX; +uint32_t X509_get_extension_flags(X509 *x) { + // Ignore the return value. On failure, |x->ex_flags| will include + // |EXFLAG_INVALID|. + x509v3_cache_extensions(x); + return x->ex_flags; } -const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509) -{ - if (!x509v3_cache_extensions(x509)) { - return NULL; - } - return x509->skid; +uint32_t X509_get_key_usage(X509 *x) { + if (!x509v3_cache_extensions(x)) { + return 0; + } + if (x->ex_flags & EXFLAG_KUSAGE) { + return x->ex_kusage; + } + return UINT32_MAX; } -const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509) -{ - if (!x509v3_cache_extensions(x509)) { - return NULL; - } - return x509->akid != NULL ? x509->akid->keyid : NULL; +uint32_t X509_get_extended_key_usage(X509 *x) { + if (!x509v3_cache_extensions(x)) { + return 0; + } + if (x->ex_flags & EXFLAG_XKUSAGE) { + return x->ex_xkusage; + } + return UINT32_MAX; } -const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509) -{ - if (!x509v3_cache_extensions(x509)) { - return NULL; - } - return x509->akid != NULL ? x509->akid->issuer : NULL; +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509) { + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->skid; } -const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509) -{ - if (!x509v3_cache_extensions(x509)) { - return NULL; - } - return x509->akid != NULL ? x509->akid->serial : NULL; +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509) { + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->keyid : NULL; } -long X509_get_pathlen(X509 *x509) -{ - if (!x509v3_cache_extensions(x509) || - (x509->ex_flags & EXFLAG_BCONS) == 0) { - return -1; - } - return x509->ex_pathlen; +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509) { + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->issuer : NULL; +} + +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509) { + if (!x509v3_cache_extensions(x509)) { + return NULL; + } + return x509->akid != NULL ? x509->akid->serial : NULL; +} + +long X509_get_pathlen(X509 *x509) { + if (!x509v3_cache_extensions(x509) || (x509->ex_flags & EXFLAG_BCONS) == 0) { + return -1; + } + return x509->ex_pathlen; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_skey.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_skey.c index 1cae7e18..caa7fe50 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_skey.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_skey.c @@ -1,4 +1,3 @@ -/* v3_skey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -55,102 +54,118 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#include #include #include #include #include #include +#include #include #include "../x509/internal.h" #include "internal.h" -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); -const X509V3_EXT_METHOD v3_skey_id = { - NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, - (X509V3_EXT_S2I)s2i_skey_id, - 0, 0, 0, 0, - NULL -}; - -char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct) -{ - return x509v3_bytes_to_hex(oct->data, oct->length); +char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *oct) { + return x509v3_bytes_to_hex(oct->data, oct->length); } -ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str) -{ - ASN1_OCTET_STRING *oct; - long length; - - if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!(oct->data = x509v3_hex_to_bytes(str, &length))) { - ASN1_OCTET_STRING_free(oct); - return NULL; - } - - oct->length = length; - - return oct; - -} - -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) -{ - ASN1_OCTET_STRING *oct; - ASN1_BIT_STRING *pk; - unsigned char pkey_dig[EVP_MAX_MD_SIZE]; - unsigned int diglen; - - if (strcmp(str, "hash")) - return s2i_ASN1_OCTET_STRING(method, ctx, str); - - if (!(oct = ASN1_OCTET_STRING_new())) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (ctx && (ctx->flags == CTX_TEST)) - return oct; - - if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (ctx->subject_req) - pk = ctx->subject_req->req_info->pubkey->public_key; - else - pk = ctx->subject_cert->cert_info->key->public_key; - - if (!pk) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (!EVP_Digest - (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) - goto err; - - if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - - return oct; - - err: - ASN1_OCTET_STRING_free(oct); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const char *str) { + size_t len; + uint8_t *data = x509v3_hex_to_bytes(str, &len); + if (data == NULL) { return NULL; + } + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_OVERFLOW); + goto err; + } + + ASN1_OCTET_STRING *oct = ASN1_OCTET_STRING_new(); + if (oct == NULL) { + goto err; + } + ASN1_STRING_set0(oct, data, (int)len); + return oct; + +err: + OPENSSL_free(data); + return NULL; } + +static char *i2s_ASN1_OCTET_STRING_cb(const X509V3_EXT_METHOD *method, + void *ext) { + return i2s_ASN1_OCTET_STRING(method, ext); +} + +static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const char *str) { + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) { + return s2i_ASN1_OCTET_STRING(method, ctx, str); + } + + if (!(oct = ASN1_OCTET_STRING_new())) { + return NULL; + } + + if (ctx && (ctx->flags == X509V3_CTX_TEST)) { + return oct; + } + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) { + pk = ctx->subject_req->req_info->pubkey->public_key; + } else { + pk = ctx->subject_cert->cert_info->key->public_key; + } + + if (!pk) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) { + goto err; + } + + if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { + goto err; + } + + return oct; + +err: + ASN1_OCTET_STRING_free(oct); + return NULL; +} + +const X509V3_EXT_METHOD v3_skey_id = { + NID_subject_key_identifier, + 0, + ASN1_ITEM_ref(ASN1_OCTET_STRING), + 0, + 0, + 0, + 0, + i2s_ASN1_OCTET_STRING_cb, + s2i_skey_id, + 0, + 0, + 0, + 0, + NULL, +}; diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3_utl.c b/third_party/boringssl/kit/src/crypto/x509v3/v3_utl.c index 5d91aede..bbc82e28 100644 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3_utl.c +++ b/third_party/boringssl/kit/src/crypto/x509v3/v3_utl.c @@ -1,4 +1,3 @@ -/* v3_utl.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -63,6 +62,7 @@ #include #include +#include #include #include #include @@ -75,1363 +75,1281 @@ static char *strip_spaces(char *name); -static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b); -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, - GENERAL_NAMES *gens); +static int sk_strcmp(const char *const *a, const char *const *b); +static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, + const GENERAL_NAMES *gens); static void str_free(OPENSSL_STRING str); -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, + const ASN1_IA5STRING *email); static int ipv4_from_asc(unsigned char v4[4], const char *in); static int ipv6_from_asc(unsigned char v6[16], const char *in); -static int ipv6_cb(const char *elem, int len, void *usr); -static int ipv6_hex(unsigned char *out, const char *in, int inlen); +static int ipv6_cb(const char *elem, size_t len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, size_t inlen); -/* Add a CONF_VALUE name value pair to stack */ +// Add a CONF_VALUE name value pair to stack static int x509V3_add_len_value(const char *name, const char *value, size_t value_len, int omit_value, - STACK_OF(CONF_VALUE) **extlist) -{ - CONF_VALUE *vtmp = NULL; - char *tname = NULL, *tvalue = NULL; - int extlist_was_null = *extlist == NULL; - if (name && !(tname = OPENSSL_strdup(name))) - goto malloc_err; - if (!omit_value) { - /* |CONF_VALUE| cannot represent strings with NULs. */ - if (OPENSSL_memchr(value, 0, value_len)) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); - goto err; - } - tvalue = OPENSSL_strndup(value, value_len); - if (tvalue == NULL) { - goto malloc_err; - } + STACK_OF(CONF_VALUE) **extlist) { + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + int extlist_was_null = *extlist == NULL; + if (name && !(tname = OPENSSL_strdup(name))) { + goto err; + } + if (!omit_value) { + // |CONF_VALUE| cannot represent strings with NULs. + if (OPENSSL_memchr(value, 0, value_len)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_VALUE); + goto err; } - if (!(vtmp = CONF_VALUE_new())) - goto malloc_err; - if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) - goto malloc_err; - vtmp->section = NULL; - vtmp->name = tname; - vtmp->value = tvalue; - if (!sk_CONF_VALUE_push(*extlist, vtmp)) - goto malloc_err; - return 1; - malloc_err: - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - err: - if (extlist_was_null) { - sk_CONF_VALUE_free(*extlist); - *extlist = NULL; + tvalue = OPENSSL_strndup(value, value_len); + if (tvalue == NULL) { + goto err; } - OPENSSL_free(vtmp); - OPENSSL_free(tname); - OPENSSL_free(tvalue); - return 0; + } + if (!(vtmp = CONF_VALUE_new())) { + goto err; + } + if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) { + goto err; + } + vtmp->section = NULL; + vtmp->name = tname; + vtmp->value = tvalue; + if (!sk_CONF_VALUE_push(*extlist, vtmp)) { + goto err; + } + return 1; +err: + if (extlist_was_null) { + sk_CONF_VALUE_free(*extlist); + *extlist = NULL; + } + OPENSSL_free(vtmp); + OPENSSL_free(tname); + OPENSSL_free(tvalue); + return 0; } int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist) -{ - return x509V3_add_len_value(name, value, value != NULL ? strlen(value) : 0, - /*omit_value=*/value == NULL, extlist); -} - -int X509V3_add_value_uchar(const char *name, const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist) -{ - return X509V3_add_value(name, (const char *)value, extlist); + STACK_OF(CONF_VALUE) **extlist) { + return x509V3_add_len_value(name, value, value != NULL ? strlen(value) : 0, + /*omit_value=*/value == NULL, extlist); } int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, - STACK_OF(CONF_VALUE) **extlist) -{ - return x509V3_add_len_value(name, (const char *)value->data, value->length, - /*omit_value=*/0, extlist); + STACK_OF(CONF_VALUE) **extlist) { + return x509V3_add_len_value(name, (const char *)value->data, value->length, + /*omit_value=*/0, extlist); } -/* Free function for STACK_OF(CONF_VALUE) */ +// Free function for STACK_OF(CONF_VALUE) -void X509V3_conf_free(CONF_VALUE *conf) -{ - if (!conf) - return; - if (conf->name) - OPENSSL_free(conf->name); - if (conf->value) - OPENSSL_free(conf->value); - if (conf->section) - OPENSSL_free(conf->section); - OPENSSL_free(conf); +void X509V3_conf_free(CONF_VALUE *conf) { + if (!conf) { + return; + } + OPENSSL_free(conf->name); + OPENSSL_free(conf->value); + OPENSSL_free(conf->section); + OPENSSL_free(conf); } int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) -{ - if (asn1_bool) - return X509V3_add_value(name, "TRUE", extlist); - return X509V3_add_value(name, "FALSE", extlist); + STACK_OF(CONF_VALUE) **extlist) { + if (asn1_bool) { + return X509V3_add_value(name, "TRUE", extlist); + } + return X509V3_add_value(name, "FALSE", extlist); } -int X509V3_add_value_bool_nf(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) -{ - if (asn1_bool) - return X509V3_add_value(name, "TRUE", extlist); - return 1; -} +static char *bignum_to_string(const BIGNUM *bn) { + char *tmp, *ret; + size_t len; -static char *bignum_to_string(const BIGNUM *bn) -{ - char *tmp, *ret; - size_t len; + // Display large numbers in hex and small numbers in decimal. Converting to + // decimal takes quadratic time and is no more useful than hex for large + // numbers. + if (BN_num_bits(bn) < 32) { + return BN_bn2dec(bn); + } - /* - * Display large numbers in hex and small numbers in decimal. Converting to - * decimal takes quadratic time and is no more useful than hex for large - * numbers. - */ - if (BN_num_bits(bn) < 32) { - return BN_bn2dec(bn); - } + tmp = BN_bn2hex(bn); + if (tmp == NULL) { + return NULL; + } - tmp = BN_bn2hex(bn); - if (tmp == NULL) { - return NULL; - } - - len = strlen(tmp) + 3; - ret = OPENSSL_malloc(len); - if (ret == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - OPENSSL_free(tmp); - return NULL; - } - - /* Prepend "0x", but place it after the "-" if negative. */ - if (tmp[0] == '-') { - OPENSSL_strlcpy(ret, "-0x", len); - OPENSSL_strlcat(ret, tmp + 1, len); - } else { - OPENSSL_strlcpy(ret, "0x", len); - OPENSSL_strlcat(ret, tmp, len); - } + len = strlen(tmp) + 3; + ret = OPENSSL_malloc(len); + if (ret == NULL) { OPENSSL_free(tmp); - return ret; + return NULL; + } + + // Prepend "0x", but place it after the "-" if negative. + if (tmp[0] == '-') { + OPENSSL_strlcpy(ret, "-0x", len); + OPENSSL_strlcat(ret, tmp + 1, len); + } else { + OPENSSL_strlcpy(ret, "0x", len); + OPENSSL_strlcat(ret, tmp, len); + } + OPENSSL_free(tmp); + return ret; } -char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) -{ - BIGNUM *bntmp = NULL; - char *strtmp = NULL; - if (!a) - return NULL; - if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || - !(strtmp = bignum_to_string(bntmp))) - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; +char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *method, + const ASN1_ENUMERATED *a) { + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) { + return NULL; + } + if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || + !(strtmp = bignum_to_string(bntmp))) { + } + BN_free(bntmp); + return strtmp; } -char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) -{ - BIGNUM *bntmp = NULL; - char *strtmp = NULL; - if (!a) - return NULL; - if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || - !(strtmp = bignum_to_string(bntmp))) - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; +char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) { + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) { + return NULL; + } + if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || + !(strtmp = bignum_to_string(bntmp))) { + } + BN_free(bntmp); + return strtmp; } -ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) -{ - BIGNUM *bn = NULL; - ASN1_INTEGER *aint; - int isneg, ishex; - int ret; - if (!value) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); - return 0; +ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *method, + const char *value) { + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg, ishex; + int ret; + if (!value) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + return 0; + } + bn = BN_new(); + if (value[0] == '-') { + value++; + isneg = 1; + } else { + isneg = 0; + } + + if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { + value += 2; + ishex = 1; + } else { + ishex = 0; + } + + if (ishex) { + ret = BN_hex2bn(&bn, value); + } else { + // Decoding from decimal scales quadratically in the input length. Bound the + // largest decimal input we accept in the config parser. 8,192 decimal + // digits allows values up to 27,213 bits. Ths exceeds the largest RSA, DSA, + // or DH modulus we support, and those are not usefully represented in + // decimal. + if (strlen(value) > 8192) { + BN_free(bn); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + return 0; } - bn = BN_new(); - if (value[0] == '-') { - value++; - isneg = 1; - } else - isneg = 0; + ret = BN_dec2bn(&bn, value); + } - if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { - value += 2; - ishex = 1; - } else - ishex = 0; - - if (ishex) - ret = BN_hex2bn(&bn, value); - else - ret = BN_dec2bn(&bn, value); - - if (!ret || value[ret]) { - BN_free(bn); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR); - return 0; - } - - if (isneg && BN_is_zero(bn)) - isneg = 0; - - aint = BN_to_ASN1_INTEGER(bn, NULL); + if (!ret || value[ret]) { BN_free(bn); - if (!aint) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR); - return 0; - } - if (isneg) - aint->type |= V_ASN1_NEG; - return aint; + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR); + return 0; + } + + if (isneg && BN_is_zero(bn)) { + isneg = 0; + } + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return 0; + } + if (isneg) { + aint->type |= V_ASN1_NEG; + } + return aint; } int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist) -{ - char *strtmp; - int ret; - if (!aint) - return 1; - if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) - return 0; - ret = X509V3_add_value(name, strtmp, extlist); - OPENSSL_free(strtmp); - return ret; + STACK_OF(CONF_VALUE) **extlist) { + char *strtmp; + int ret; + if (!aint) { + return 1; + } + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) { + return 0; + } + ret = X509V3_add_value(name, strtmp, extlist); + OPENSSL_free(strtmp); + return ret; } -int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) -{ - char *btmp; - if (!(btmp = value->value)) - goto err; - if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") - || !strcmp(btmp, "Y") || !strcmp(btmp, "y") - || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { - *asn1_bool = 0xff; - return 1; - } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") - || !strcmp(btmp, "N") || !strcmp(btmp, "n") - || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { - *asn1_bool = 0; - return 1; - } - err: +int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool) { + if (!strcmp(str, "TRUE") || !strcmp(str, "true") || !strcmp(str, "Y") || + !strcmp(str, "y") || !strcmp(str, "YES") || !strcmp(str, "yes")) { + *out_bool = ASN1_BOOLEAN_TRUE; + return 1; + } + if (!strcmp(str, "FALSE") || !strcmp(str, "false") || !strcmp(str, "N") || + !strcmp(str, "n") || !strcmp(str, "NO") || !strcmp(str, "no")) { + *out_bool = ASN1_BOOLEAN_FALSE; + return 1; + } + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + return 0; +} + +int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool) { + const char *btmp = value->value; + if (btmp == NULL) { OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING); + goto err; + } + if (!X509V3_bool_from_string(btmp, out_bool)) { + goto err; + } + return 1; + +err: + X509V3_conf_err(value); + return 0; +} + +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) { + ASN1_INTEGER *itmp; + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { X509V3_conf_err(value); return 0; + } + ASN1_INTEGER_free(*aint); + *aint = itmp; + return 1; } -int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) -{ - ASN1_INTEGER *itmp; - if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { - X509V3_conf_err(value); - return 0; - } - *aint = itmp; - return 1; -} +#define HDR_NAME 1 +#define HDR_VALUE 2 -#define HDR_NAME 1 -#define HDR_VALUE 2 +// #define DEBUG -/* - * #define DEBUG - */ - -STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) -{ - char *p, *q, c; - char *ntmp, *vtmp; - STACK_OF(CONF_VALUE) *values = NULL; - char *linebuf; - int state; - /* We are going to modify the line so copy it first */ - linebuf = OPENSSL_strdup(line); - if (linebuf == NULL) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - goto err; - } - state = HDR_NAME; - ntmp = NULL; - /* Go through all characters */ - for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); - p++) { - - switch (state) { - case HDR_NAME: - if (c == ':') { - state = HDR_VALUE; - *p = 0; - ntmp = strip_spaces(q); - if (!ntmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); - goto err; - } - q = p + 1; - } else if (c == ',') { - *p = 0; - ntmp = strip_spaces(q); - q = p + 1; +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) { + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + // We are going to modify the line so copy it first + linebuf = OPENSSL_strdup(line); + if (linebuf == NULL) { + goto err; + } + state = HDR_NAME; + ntmp = NULL; + // Go through all characters + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); p++) { + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; #if 0 printf("%s\n", ntmp); #endif - if (!ntmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); - goto err; - } - X509V3_add_value(ntmp, NULL, &values); - } - break; + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; - case HDR_VALUE: - if (c == ',') { - state = HDR_NAME; - *p = 0; - vtmp = strip_spaces(q); + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); #if 0 printf("%s\n", ntmp); #endif - if (!vtmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); - goto err; - } - X509V3_add_value(ntmp, vtmp, &values); - ntmp = NULL; - q = p + 1; - } - + if (!vtmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; } } + } - if (state == HDR_VALUE) { - vtmp = strip_spaces(q); + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); #if 0 printf("%s=%s\n", ntmp, vtmp); #endif - if (!vtmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); - goto err; - } - X509V3_add_value(ntmp, vtmp, &values); - } else { - ntmp = strip_spaces(q); + if (!vtmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); #if 0 printf("%s\n", ntmp); #endif - if (!ntmp) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); - goto err; - } - X509V3_add_value(ntmp, NULL, &values); + if (!ntmp) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME); + goto err; } - OPENSSL_free(linebuf); - return values; - - err: - OPENSSL_free(linebuf); - sk_CONF_VALUE_pop_free(values, X509V3_conf_free); - return NULL; - -} - -/* Delete leading and trailing spaces from a string */ -static char *strip_spaces(char *name) -{ - char *p, *q; - /* Skip over leading spaces */ - p = name; - while (*p && isspace((unsigned char)*p)) - p++; - if (!*p) - return NULL; - q = p + strlen(p) - 1; - while ((q != p) && isspace((unsigned char)*q)) - q--; - if (p != q) - q[1] = 0; - if (!*p) - return NULL; - return p; -} - -/* hex string utilities */ - -/* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) - */ - -char *x509v3_bytes_to_hex(const unsigned char *buffer, long len) -{ - char *tmp, *q; - const unsigned char *p; - int i; - static const char hexdig[] = "0123456789ABCDEF"; - if (!buffer || !len) - return NULL; - if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - } - q = tmp; - for (i = 0, p = buffer; i < len; i++, p++) { - *q++ = hexdig[(*p >> 4) & 0xf]; - *q++ = hexdig[*p & 0xf]; - *q++ = ':'; - } - q[-1] = 0; - - return tmp; -} - -unsigned char *x509v3_hex_to_bytes(const char *str, long *len) -{ - unsigned char *hexbuf, *q; - unsigned char ch, cl, *p; - if (!str) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) - goto err; - for (p = (unsigned char *)str, q = hexbuf; *p;) { - ch = *p++; - if (ch == ':') - continue; - cl = *p++; - if (!cl) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS); - OPENSSL_free(hexbuf); - return NULL; - } - - if ((ch >= '0') && (ch <= '9')) - ch -= '0'; - else if ((ch >= 'a') && (ch <= 'f')) - ch -= 'a' - 10; - else if ((ch >= 'A') && (ch <= 'F')) - ch -= 'A' - 10; - else - goto badhex; - - if ((cl >= '0') && (cl <= '9')) - cl -= '0'; - else if ((cl >= 'a') && (cl <= 'f')) - cl -= 'a' - 10; - else if ((cl >= 'A') && (cl <= 'F')) - cl -= 'A' - 10; - else - goto badhex; - - *q++ = (ch << 4) | cl; - } - - if (len) - *len = q - hexbuf; - - return hexbuf; - - err: - if (hexbuf) - OPENSSL_free(hexbuf); - OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); - return NULL; - - badhex: - OPENSSL_free(hexbuf); - OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT); - return NULL; - -} - -int x509v3_name_cmp(const char *name, const char *cmp) -{ - int len, ret; - char c; - len = strlen(cmp); - if ((ret = strncmp(name, cmp, len))) - return ret; - c = name[len]; - if (!c || (c == '.')) - return 0; - return 1; -} - -static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b) -{ - return strcmp(*a, *b); -} - -STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) -{ - GENERAL_NAMES *gens; - STACK_OF(OPENSSL_STRING) *ret; - - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return ret; -} - -STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) -{ - AUTHORITY_INFO_ACCESS *info; - STACK_OF(OPENSSL_STRING) *ret = NULL; - size_t i; - - info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); - if (!info) - return NULL; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { - ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); - if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { - if (ad->location->type == GEN_URI) { - if (!append_ia5 - (&ret, ad->location->d.uniformResourceIdentifier)) - break; - } - } - } - AUTHORITY_INFO_ACCESS_free(info); - return ret; -} - -STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) -{ - GENERAL_NAMES *gens; - STACK_OF(X509_EXTENSION) *exts; - STACK_OF(OPENSSL_STRING) *ret; - - exts = X509_REQ_get_extensions(x); - gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_REQ_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - return ret; -} - -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, - GENERAL_NAMES *gens) -{ - STACK_OF(OPENSSL_STRING) *ret = NULL; - X509_NAME_ENTRY *ne; - ASN1_IA5STRING *email; - GENERAL_NAME *gen; - int i; - size_t j; - /* Now add any email address(es) to STACK */ - i = -1; - /* First supplied X509_NAME */ - while ((i = X509_NAME_get_index_by_NID(name, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(name, i); - email = X509_NAME_ENTRY_get_data(ne); - if (!append_ia5(&ret, email)) - return NULL; - } - for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { - gen = sk_GENERAL_NAME_value(gens, j); - if (gen->type != GEN_EMAIL) - continue; - if (!append_ia5(&ret, gen->d.ia5)) - return NULL; - } - return ret; -} - -static void str_free(OPENSSL_STRING str) -{ - OPENSSL_free(str); -} - -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) -{ - /* First some sanity checks */ - if (email->type != V_ASN1_IA5STRING) - return 1; - if (email->data == NULL || email->length == 0) - return 1; - /* |OPENSSL_STRING| cannot represent strings with embedded NULs. Do not - * report them as outputs. */ - if (OPENSSL_memchr(email->data, 0, email->length) != NULL) - return 1; - - char *emtmp = NULL; - if (!*sk) - *sk = sk_OPENSSL_STRING_new(sk_strcmp); - if (!*sk) - goto err; - - emtmp = OPENSSL_strndup((char *)email->data, email->length); - if (emtmp == NULL) { - goto err; - } - - /* Don't add duplicates */ - sk_OPENSSL_STRING_sort(*sk); - if (sk_OPENSSL_STRING_find(*sk, NULL, emtmp)) { - OPENSSL_free(emtmp); - return 1; - } - if (!sk_OPENSSL_STRING_push(*sk, emtmp)) { - goto err; - } - return 1; + X509V3_add_value(ntmp, NULL, &values); + } + OPENSSL_free(linebuf); + return values; err: - /* TODO(davidben): Fix the error-handling in this file. It currently relies - * on |append_ia5| leaving |*sk| at NULL on error. */ - OPENSSL_free(emtmp); - X509_email_free(*sk); - *sk = NULL; + OPENSSL_free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; +} + +// Delete leading and trailing spaces from a string +static char *strip_spaces(char *name) { + char *p, *q; + // Skip over leading spaces + p = name; + while (*p && OPENSSL_isspace((unsigned char)*p)) { + p++; + } + if (!*p) { + return NULL; + } + q = p + strlen(p) - 1; + while ((q != p) && OPENSSL_isspace((unsigned char)*q)) { + q--; + } + if (p != q) { + q[1] = 0; + } + if (!*p) { + return NULL; + } + return p; +} + +// hex string utilities + +char *x509v3_bytes_to_hex(const uint8_t *in, size_t len) { + CBB cbb; + if (!CBB_init(&cbb, len * 3 + 1)) { + goto err; + } + for (size_t i = 0; i < len; i++) { + static const char hex[] = "0123456789ABCDEF"; + if ((i > 0 && !CBB_add_u8(&cbb, ':')) || + !CBB_add_u8(&cbb, hex[in[i] >> 4]) || + !CBB_add_u8(&cbb, hex[in[i] & 0xf])) { + goto err; + } + } + uint8_t *ret; + size_t unused_len; + if (!CBB_add_u8(&cbb, 0) || !CBB_finish(&cbb, &ret, &unused_len)) { + goto err; + } + + return (char *)ret; + +err: + CBB_cleanup(&cbb); + return NULL; +} + +unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len) { + unsigned char *hexbuf, *q; + unsigned char ch, cl, *p; + uint8_t high, low; + if (!str) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) { + goto err; + } + for (p = (unsigned char *)str, q = hexbuf; *p;) { + ch = *p++; + if (ch == ':') { + continue; + } + cl = *p++; + if (!cl) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + if (!OPENSSL_fromxdigit(&high, ch)) { + goto badhex; + } + if (!OPENSSL_fromxdigit(&low, cl)) { + goto badhex; + } + *q++ = (high << 4) | low; + } + + if (len) { + *len = q - hexbuf; + } + + return hexbuf; + +err: + OPENSSL_free(hexbuf); + return NULL; + +badhex: + OPENSSL_free(hexbuf); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT); + return NULL; +} + +int x509v3_conf_name_matches(const char *name, const char *cmp) { + // |name| must begin with |cmp|. + size_t len = strlen(cmp); + if (strncmp(name, cmp, len) != 0) { return 0; + } + // |name| must either be equal to |cmp| or begin with |cmp|, followed by '.'. + return name[len] == '\0' || name[len] == '.'; } -void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) -{ - sk_OPENSSL_STRING_pop_free(sk, str_free); +static int sk_strcmp(const char *const *a, const char *const *b) { + return strcmp(*a, *b); } -typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags); +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) { + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; -/* Skip pattern prefix to match "wildcard" subject */ -static void skip_prefix(const unsigned char **p, size_t *plen, + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) { + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + size_t i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) { + return NULL; + } + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier)) { + break; + } + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) { + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} + +static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, + const GENERAL_NAMES *gens) { + STACK_OF(OPENSSL_STRING) *ret = NULL; + // Now add any email address(es) to STACK + int i = -1; + // First supplied X509_NAME + while ((i = X509_NAME_get_index_by_NID(name, NID_pkcs9_emailAddress, i)) >= + 0) { + const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i); + const ASN1_IA5STRING *email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) { + return NULL; + } + } + for (size_t j = 0; j < sk_GENERAL_NAME_num(gens); j++) { + const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, j); + if (gen->type != GEN_EMAIL) { + continue; + } + if (!append_ia5(&ret, gen->d.ia5)) { + return NULL; + } + } + return ret; +} + +static void str_free(OPENSSL_STRING str) { OPENSSL_free(str); } + +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, + const ASN1_IA5STRING *email) { + // First some sanity checks + if (email->type != V_ASN1_IA5STRING) { + return 1; + } + if (email->data == NULL || email->length == 0) { + return 1; + } + // |OPENSSL_STRING| cannot represent strings with embedded NULs. Do not + // report them as outputs. + if (OPENSSL_memchr(email->data, 0, email->length) != NULL) { + return 1; + } + + char *emtmp = NULL; + if (!*sk) { + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + } + if (!*sk) { + goto err; + } + + emtmp = OPENSSL_strndup((char *)email->data, email->length); + if (emtmp == NULL) { + goto err; + } + + // Don't add duplicates + sk_OPENSSL_STRING_sort(*sk); + if (sk_OPENSSL_STRING_find(*sk, NULL, emtmp)) { + OPENSSL_free(emtmp); + return 1; + } + if (!sk_OPENSSL_STRING_push(*sk, emtmp)) { + goto err; + } + return 1; + +err: + // TODO(davidben): Fix the error-handling in this file. It currently relies + // on |append_ia5| leaving |*sk| at NULL on error. + OPENSSL_free(emtmp); + X509_email_free(*sk); + *sk = NULL; + return 0; +} + +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) { + sk_OPENSSL_STRING_pop_free(sk, str_free); +} + +typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *pattern = *p; - size_t pattern_len = *plen; + unsigned int flags); - /* - * If subject starts with a leading '.' followed by more octets, and - * pattern is longer, compare just an equal-length suffix with the - * full subject (starting at the '.'), provided the prefix contains - * no NULs. - */ - if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) - return; - - while (pattern_len > subject_len && *pattern) { - if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && - *pattern == '.') - break; - ++pattern; - --pattern_len; - } - - /* Skip if entire prefix acceptable */ - if (pattern_len == subject_len) { - *p = pattern; - *plen = pattern_len; - } -} - -/* Compare while ASCII ignoring case. */ +// Compare while ASCII ignoring case. static int equal_nocase(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - while (pattern_len) { - unsigned char l = *pattern; - unsigned char r = *subject; - /* The pattern must not contain NUL characters. */ - if (l == 0) - return 0; - if (l != r) { - if ('A' <= l && l <= 'Z') - l = (l - 'A') + 'a'; - if ('A' <= r && r <= 'Z') - r = (r - 'A') + 'a'; - if (l != r) - return 0; - } - ++pattern; - ++subject; - --pattern_len; + unsigned int flags) { + if (pattern_len != subject_len) { + return 0; + } + while (pattern_len) { + unsigned char l = *pattern; + unsigned char r = *subject; + // The pattern must not contain NUL characters. + if (l == 0) { + return 0; } - return 1; + if (l != r) { + if (OPENSSL_tolower(l) != OPENSSL_tolower(r)) { + return 0; + } + } + ++pattern; + ++subject; + --pattern_len; + } + return 1; } -/* Compare using OPENSSL_memcmp. */ +// Compare using OPENSSL_memcmp. static int equal_case(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - return !OPENSSL_memcmp(pattern, subject, pattern_len); + unsigned int flags) { + if (pattern_len != subject_len) { + return 0; + } + return !OPENSSL_memcmp(pattern, subject, pattern_len); } -/* - * RFC 5280, section 7.5, requires that only the domain is compared in a - * case-insensitive manner. - */ +// RFC 5280, section 7.5, requires that only the domain is compared in a +// case-insensitive manner. static int equal_email(const unsigned char *a, size_t a_len, const unsigned char *b, size_t b_len, - unsigned int unused_flags) -{ - size_t i = a_len; - if (a_len != b_len) + unsigned int unused_flags) { + size_t i = a_len; + if (a_len != b_len) { + return 0; + } + // We search backwards for the '@' character, so that we do not have to + // deal with quoted local-parts. The domain part is compared in a + // case-insensitive manner. + while (i > 0) { + --i; + if (a[i] == '@' || b[i] == '@') { + if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) { return 0; - /* - * We search backwards for the '@' character, so that we do not have to - * deal with quoted local-parts. The domain part is compared in a - * case-insensitive manner. - */ - while (i > 0) { - --i; - if (a[i] == '@' || b[i] == '@') { - if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) - return 0; - break; - } + } + break; } - if (i == 0) - i = a_len; - return equal_case(a, i, b, i, 0); + } + if (i == 0) { + i = a_len; + } + return equal_case(a, i, b, i, 0); } -/* - * Compare the prefix and suffix with the subject, and check that the - * characters in-between are valid. - */ +// Compare the prefix and suffix with the subject, and check that the +// characters in-between are valid. static int wildcard_match(const unsigned char *prefix, size_t prefix_len, const unsigned char *suffix, size_t suffix_len, const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *wildcard_start; - const unsigned char *wildcard_end; - const unsigned char *p; - int allow_multi = 0; - int allow_idna = 0; + unsigned int flags) { + const unsigned char *wildcard_start; + const unsigned char *wildcard_end; + const unsigned char *p; + int allow_idna = 0; - if (subject_len < prefix_len + suffix_len) - return 0; - if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) - return 0; - wildcard_start = subject + prefix_len; - wildcard_end = subject + (subject_len - suffix_len); - if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) - return 0; - /* - * If the wildcard makes up the entire first label, it must match at - * least one character. - */ - if (prefix_len == 0 && *suffix == '.') { - if (wildcard_start == wildcard_end) - return 0; - allow_idna = 1; - if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) - allow_multi = 1; + if (subject_len < prefix_len + suffix_len) { + return 0; + } + if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) { + return 0; + } + wildcard_start = subject + prefix_len; + wildcard_end = subject + (subject_len - suffix_len); + if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) { + return 0; + } + // If the wildcard makes up the entire first label, it must match at + // least one character. + if (prefix_len == 0 && *suffix == '.') { + if (wildcard_start == wildcard_end) { + return 0; } - /* IDNA labels cannot match partial wildcards */ - if (!allow_idna && - subject_len >= 4 - && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0) - return 0; - /* The wildcard may match a literal '*' */ - if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') - return 1; - /* - * Check that the part matched by the wildcard contains only - * permitted characters and only matches a single label unless - * allow_multi is set. - */ - for (p = wildcard_start; p != wildcard_end; ++p) - if (!(('0' <= *p && *p <= '9') || - ('A' <= *p && *p <= 'Z') || - ('a' <= *p && *p <= 'z') || - *p == '-' || (allow_multi && *p == '.'))) - return 0; + allow_idna = 1; + } + // IDNA labels cannot match partial wildcards + if (!allow_idna && subject_len >= 4 && + OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0) { + return 0; + } + // The wildcard may match a literal '*' + if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') { return 1; + } + // Check that the part matched by the wildcard contains only + // permitted characters and only matches a single label. + for (p = wildcard_start; p != wildcard_end; ++p) { + if (!OPENSSL_isalnum(*p) && *p != '-') { + return 0; + } + } + return 1; } -#define LABEL_START (1 << 0) -#define LABEL_END (1 << 1) -#define LABEL_HYPHEN (1 << 2) -#define LABEL_IDNA (1 << 3) +#define LABEL_START (1 << 0) +#define LABEL_END (1 << 1) +#define LABEL_HYPHEN (1 << 2) +#define LABEL_IDNA (1 << 3) static const unsigned char *valid_star(const unsigned char *p, size_t len, - unsigned int flags) -{ - const unsigned char *star = 0; - size_t i; - int state = LABEL_START; - int dots = 0; - for (i = 0; i < len; ++i) { - /* - * Locate first and only legal wildcard, either at the start - * or end of a non-IDNA first and not final label. - */ - if (p[i] == '*') { - int atstart = (state & LABEL_START); - int atend = (i == len - 1 || p[i + 1] == '.'); - /* - * At most one wildcard per pattern. - * No wildcards in IDNA labels. - * No wildcards after the first label. - */ - if (star != NULL || (state & LABEL_IDNA) != 0 || dots) - return NULL; - /* Only full-label '*.example.com' wildcards? */ - if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) - && (!atstart || !atend)) - return NULL; - /* No 'foo*bar' wildcards */ - if (!atstart && !atend) - return NULL; - star = &p[i]; - state &= ~LABEL_START; - } else if (('a' <= p[i] && p[i] <= 'z') - || ('A' <= p[i] && p[i] <= 'Z') - || ('0' <= p[i] && p[i] <= '9')) { - if ((state & LABEL_START) != 0 - && len - i >= 4 - && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) - state |= LABEL_IDNA; - state &= ~(LABEL_HYPHEN | LABEL_START); - } else if (p[i] == '.') { - if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) - return NULL; - state = LABEL_START; - ++dots; - } else if (p[i] == '-') { - /* no domain/subdomain starts with '-' */ - if ((state & LABEL_START) != 0) - return NULL; - state |= LABEL_HYPHEN; - } else - return NULL; - } - - /* - * The final label must not end in a hyphen or ".", and - * there must be at least two dots after the star. - */ - if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) + unsigned int flags) { + const unsigned char *star = 0; + size_t i; + int state = LABEL_START; + int dots = 0; + for (i = 0; i < len; ++i) { + // Locate first and only legal wildcard, either at the start + // or end of a non-IDNA first and not final label. + if (p[i] == '*') { + int atstart = (state & LABEL_START); + int atend = (i == len - 1 || p[i + 1] == '.'); + // At most one wildcard per pattern. + // No wildcards in IDNA labels. + // No wildcards after the first label. + if (star != NULL || (state & LABEL_IDNA) != 0 || dots) { return NULL; - return star; + } + // Only full-label '*.example.com' wildcards. + if (!atstart || !atend) { + return NULL; + } + star = &p[i]; + state &= ~LABEL_START; + } else if (OPENSSL_isalnum(p[i])) { + if ((state & LABEL_START) != 0 && len - i >= 4 && + OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) { + state |= LABEL_IDNA; + } + state &= ~(LABEL_HYPHEN | LABEL_START); + } else if (p[i] == '.') { + if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) { + return NULL; + } + state = LABEL_START; + ++dots; + } else if (p[i] == '-') { + // no domain/subdomain starts with '-' + if ((state & LABEL_START) != 0) { + return NULL; + } + state |= LABEL_HYPHEN; + } else { + return NULL; + } + } + + // The final label must not end in a hyphen or ".", and + // there must be at least two dots after the star. + if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) { + return NULL; + } + return star; } -/* Compare using wildcards. */ +// Compare using wildcards. static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *star = NULL; + unsigned int flags) { + const unsigned char *star = NULL; - /* - * Subject names starting with '.' can only match a wildcard pattern - * via a subject sub-domain pattern suffix match. - */ - if (!(subject_len > 1 && subject[0] == '.')) - star = valid_star(pattern, pattern_len, flags); - if (star == NULL) - return equal_nocase(pattern, pattern_len, - subject, subject_len, flags); - return wildcard_match(pattern, star - pattern, - star + 1, (pattern + pattern_len) - star - 1, - subject, subject_len, flags); + // Subject names starting with '.' can only match a wildcard pattern + // via a subject sub-domain pattern suffix match. + if (!(subject_len > 1 && subject[0] == '.')) { + star = valid_star(pattern, pattern_len, flags); + } + if (star == NULL) { + return equal_nocase(pattern, pattern_len, subject, subject_len, flags); + } + return wildcard_match(pattern, star - pattern, star + 1, + (pattern + pattern_len) - star - 1, subject, + subject_len, flags); } int x509v3_looks_like_dns_name(const unsigned char *in, size_t len) { - /* This function is used as a heuristic for whether a common name is a - * hostname to be matched, or merely a decorative name to describe the - * subject. This heuristic must be applied to both name constraints and the - * common name fallback, so it must be loose enough to accept hostname - * common names, and tight enough to reject decorative common names. */ + // This function is used as a heuristic for whether a common name is a + // hostname to be matched, or merely a decorative name to describe the + // subject. This heuristic must be applied to both name constraints and the + // common name fallback, so it must be loose enough to accept hostname + // common names, and tight enough to reject decorative common names. - if (len > 0 && in[len - 1] == '.') { - len--; + if (len > 0 && in[len - 1] == '.') { + len--; + } + + // Wildcards are allowed in front. + if (len >= 2 && in[0] == '*' && in[1] == '.') { + in += 2; + len -= 2; + } + + if (len == 0) { + return 0; + } + + size_t label_start = 0; + for (size_t i = 0; i < len; i++) { + unsigned char c = in[i]; + if (OPENSSL_isalnum(c) || (c == '-' && i > label_start) || + // These are not valid characters in hostnames, but commonly found + // in deployments outside the Web PKI. + c == '_' || c == ':') { + continue; } - /* Wildcards are allowed in front. */ - if (len >= 2 && in[0] == '*' && in[1] == '.') { - in += 2; - len -= 2; + // Labels must not be empty. + if (c == '.' && i > label_start && i < len - 1) { + label_start = i + 1; + continue; } - if (len == 0) { - return 0; - } + return 0; + } - size_t label_start = 0; - for (size_t i = 0; i < len; i++) { - unsigned char c = in[i]; - if ((c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'Z') || - (c == '-' && i > label_start) || - /* These are not valid characters in hostnames, but commonly found - * in deployments outside the Web PKI. */ - c == '_' || - c == ':') { - continue; - } - - /* Labels must not be empty. */ - if (c == '.' && i > label_start && i < len - 1) { - label_start = i + 1; - continue; - } - - return 0; - } - - return 1; + return 1; } -/* - * Compare an ASN1_STRING to a supplied string. If they match return 1. If - * cmp_type > 0 only compare if string matches the type, otherwise convert it - * to UTF8. - */ +// Compare an ASN1_STRING to a supplied string. If they match return 1. If +// cmp_type > 0 only compare if string matches the type, otherwise convert it +// to UTF8. -static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, +static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal, unsigned int flags, int check_type, const char *b, - size_t blen, char **peername) -{ - int rv = 0; + size_t blen, char **peername) { + int rv = 0; - if (!a->data || !a->length) - return 0; - if (cmp_type > 0) { - if (cmp_type != a->type) - return 0; - if (cmp_type == V_ASN1_IA5STRING) - rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); - else if (a->length == (int)blen && !OPENSSL_memcmp(a->data, b, blen)) - rv = 1; - if (rv > 0 && peername) - *peername = OPENSSL_strndup((char *)a->data, a->length); - } else { - int astrlen; - unsigned char *astr; - astrlen = ASN1_STRING_to_UTF8(&astr, a); - if (astrlen < 0) - return -1; - /* - * We check the common name against DNS name constraints if it passes - * |x509v3_looks_like_dns_name|. Thus we must not consider common names - * for DNS fallbacks if they fail this check. - */ - if (check_type == GEN_DNS && - !x509v3_looks_like_dns_name(astr, astrlen)) { - rv = 0; - } else { - rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); - } - if (rv > 0 && peername) - *peername = OPENSSL_strndup((char *)astr, astrlen); - OPENSSL_free(astr); + if (!a->data || !a->length) { + return 0; + } + if (cmp_type > 0) { + if (cmp_type != a->type) { + return 0; } - return rv; + if (cmp_type == V_ASN1_IA5STRING) { + rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); + } else if (a->length == (int)blen && !OPENSSL_memcmp(a->data, b, blen)) { + rv = 1; + } + if (rv > 0 && peername) { + *peername = OPENSSL_strndup((char *)a->data, a->length); + } + } else { + int astrlen; + unsigned char *astr; + astrlen = ASN1_STRING_to_UTF8(&astr, a); + if (astrlen < 0) { + return -1; + } + // We check the common name against DNS name constraints if it passes + // |x509v3_looks_like_dns_name|. Thus we must not consider common names + // for DNS fallbacks if they fail this check. + if (check_type == GEN_DNS && !x509v3_looks_like_dns_name(astr, astrlen)) { + rv = 0; + } else { + rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); + } + if (rv > 0 && peername) { + *peername = OPENSSL_strndup((char *)astr, astrlen); + } + OPENSSL_free(astr); + } + return rv; } static int do_x509_check(X509 *x, const char *chk, size_t chklen, - unsigned int flags, int check_type, char **peername) -{ - GENERAL_NAMES *gens = NULL; - X509_NAME *name = NULL; - size_t i; - int j; - int cnid = NID_undef; - int alt_type; - int rv = 0; - equal_fn equal; - - /* See below, this flag is internal-only */ - flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; - if (check_type == GEN_EMAIL) { - cnid = NID_pkcs9_emailAddress; - alt_type = V_ASN1_IA5STRING; - equal = equal_email; - } else if (check_type == GEN_DNS) { - cnid = NID_commonName; - /* Implicit client-side DNS sub-domain pattern */ - if (chklen > 1 && chk[0] == '.') - flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; - alt_type = V_ASN1_IA5STRING; - if (flags & X509_CHECK_FLAG_NO_WILDCARDS) - equal = equal_nocase; - else - equal = equal_wildcard; + unsigned int flags, int check_type, char **peername) { + int cnid = NID_undef; + int alt_type; + int rv = 0; + equal_fn equal; + if (check_type == GEN_EMAIL) { + cnid = NID_pkcs9_emailAddress; + alt_type = V_ASN1_IA5STRING; + equal = equal_email; + } else if (check_type == GEN_DNS) { + cnid = NID_commonName; + alt_type = V_ASN1_IA5STRING; + if (flags & X509_CHECK_FLAG_NO_WILDCARDS) { + equal = equal_nocase; } else { - alt_type = V_ASN1_OCTET_STRING; - equal = equal_case; + equal = equal_wildcard; } + } else { + alt_type = V_ASN1_OCTET_STRING; + equal = equal_case; + } - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - if (gens) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - GENERAL_NAME *gen; - ASN1_STRING *cstr; - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != check_type) - continue; - if (check_type == GEN_EMAIL) - cstr = gen->d.rfc822Name; - else if (check_type == GEN_DNS) - cstr = gen->d.dNSName; - else - cstr = gen->d.iPAddress; - /* Positive on success, negative on error! */ - if ((rv = do_check_string(cstr, alt_type, equal, flags, check_type, - chk, chklen, peername)) != 0) - break; - } - GENERAL_NAMES_free(gens); - return rv; + GENERAL_NAMES *gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens) { + for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != check_type) { + continue; + } + const ASN1_STRING *cstr; + if (check_type == GEN_EMAIL) { + cstr = gen->d.rfc822Name; + } else if (check_type == GEN_DNS) { + cstr = gen->d.dNSName; + } else { + cstr = gen->d.iPAddress; + } + // Positive on success, negative on error! + if ((rv = do_check_string(cstr, alt_type, equal, flags, check_type, chk, + chklen, peername)) != 0) { + break; + } } + GENERAL_NAMES_free(gens); + return rv; + } - /* We're done if CN-ID is not pertinent */ - if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) - return 0; - - j = -1; - name = X509_get_subject_name(x); - while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { - X509_NAME_ENTRY *ne; - ASN1_STRING *str; - ne = X509_NAME_get_entry(name, j); - str = X509_NAME_ENTRY_get_data(ne); - /* Positive on success, negative on error! */ - if ((rv = do_check_string(str, -1, equal, flags, check_type, - chk, chklen, peername)) != 0) - return rv; - } + // We're done if CN-ID is not pertinent + if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) { return 0; + } + + int j = -1; + const X509_NAME *name = X509_get_subject_name(x); + while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { + const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, j); + const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne); + // Positive on success, negative on error! + if ((rv = do_check_string(str, -1, equal, flags, check_type, chk, chklen, + peername)) != 0) { + return rv; + } + } + return 0; } -int X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername) -{ - if (chk == NULL) - return -2; - if (OPENSSL_memchr(chk, '\0', chklen)) - return -2; - return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); +int X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, + char **peername) { + if (chk == NULL) { + return -2; + } + if (OPENSSL_memchr(chk, '\0', chklen)) { + return -2; + } + return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); } int X509_check_email(X509 *x, const char *chk, size_t chklen, - unsigned int flags) -{ - if (chk == NULL) - return -2; - if (OPENSSL_memchr(chk, '\0', chklen)) - return -2; - return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); + unsigned int flags) { + if (chk == NULL) { + return -2; + } + if (OPENSSL_memchr(chk, '\0', chklen)) { + return -2; + } + return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); } int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags) -{ - if (chk == NULL) - return -2; - return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); + unsigned int flags) { + if (chk == NULL) { + return -2; + } + return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); } -int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) -{ - unsigned char ipout[16]; - size_t iplen; +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) { + unsigned char ipout[16]; + size_t iplen; - if (ipasc == NULL) - return -2; - iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); - if (iplen == 0) - return -2; - return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); + if (ipasc == NULL) { + return -2; + } + iplen = (size_t)x509v3_a2i_ipadd(ipout, ipasc); + if (iplen == 0) { + return -2; + } + return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); } -/* - * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible - * with RFC 3280. - */ +// Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible +// with RFC 3280. -ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) -{ - unsigned char ipout[16]; - ASN1_OCTET_STRING *ret; - int iplen; +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) { + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; - iplen = x509v3_a2i_ipadd(ipout, ipasc); - if (!iplen) - return NULL; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - return NULL; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { - ASN1_OCTET_STRING_free(ret); - return NULL; - } - return ret; -} - -ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) -{ - ASN1_OCTET_STRING *ret = NULL; - unsigned char ipout[32]; - char *iptmp = NULL, *p; - int iplen1, iplen2; - p = strchr(ipasc, '/'); - if (!p) - return NULL; - iptmp = OPENSSL_strdup(ipasc); - if (!iptmp) - return NULL; - p = iptmp + (p - ipasc); - *p++ = 0; - - iplen1 = x509v3_a2i_ipadd(ipout, iptmp); - - if (!iplen1) - goto err; - - iplen2 = x509v3_a2i_ipadd(ipout + iplen1, p); - - OPENSSL_free(iptmp); - iptmp = NULL; - - if (!iplen2 || (iplen1 != iplen2)) - goto err; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - goto err; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) - goto err; - - return ret; - - err: - if (iptmp) - OPENSSL_free(iptmp); - if (ret) - ASN1_OCTET_STRING_free(ret); + iplen = x509v3_a2i_ipadd(ipout, ipasc); + if (!iplen) { return NULL; + } + + ret = ASN1_OCTET_STRING_new(); + if (!ret) { + return NULL; + } + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; } -int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc) -{ - /* If string contains a ':' assume IPv6 */ +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) { + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + p = strchr(ipasc, '/'); + if (!p) { + return NULL; + } + iptmp = OPENSSL_strdup(ipasc); + if (!iptmp) { + return NULL; + } + p = iptmp + (p - ipasc); + *p++ = 0; - if (strchr(ipasc, ':')) { - if (!ipv6_from_asc(ipout, ipasc)) - return 0; - return 16; - } else { - if (!ipv4_from_asc(ipout, ipasc)) - return 0; - return 4; + iplen1 = x509v3_a2i_ipadd(ipout, iptmp); + + if (!iplen1) { + goto err; + } + + iplen2 = x509v3_a2i_ipadd(ipout + iplen1, p); + + OPENSSL_free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) { + goto err; + } + + ret = ASN1_OCTET_STRING_new(); + if (!ret) { + goto err; + } + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) { + goto err; + } + + return ret; + +err: + if (iptmp) { + OPENSSL_free(iptmp); + } + if (ret) { + ASN1_OCTET_STRING_free(ret); + } + return NULL; +} + +int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc) { + // If string contains a ':' assume IPv6 + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) { + return 0; } + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) { + return 0; + } + return 4; + } } -static int ipv4_from_asc(unsigned char v4[4], const char *in) -{ - int a0, a1, a2, a3; - if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) - return 0; - if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) - || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) - return 0; - v4[0] = a0; - v4[1] = a1; - v4[2] = a2; - v4[3] = a3; - return 1; +static int ipv4_from_asc(unsigned char v4[4], const char *in) { + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) { + return 0; + } + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) || (a2 < 0) || + (a2 > 255) || (a3 < 0) || (a3 > 255)) { + return 0; + } + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; } typedef struct { - /* Temporary store for IPV6 output */ - unsigned char tmp[16]; - /* Total number of bytes in tmp */ - int total; - /* The position of a zero (corresponding to '::') */ - int zero_pos; - /* Number of zeroes */ - int zero_cnt; + // Temporary store for IPV6 output + unsigned char tmp[16]; + // Total number of bytes in tmp + int total; + // The position of a zero (corresponding to '::') + int zero_pos; + // Number of zeroes + int zero_cnt; } IPV6_STAT; -static int ipv6_from_asc(unsigned char v6[16], const char *in) -{ - IPV6_STAT v6stat; - v6stat.total = 0; - v6stat.zero_pos = -1; - v6stat.zero_cnt = 0; - /* - * Treat the IPv6 representation as a list of values separated by ':'. - * The presence of a '::' will parse as one, two or three zero length - * elements. - */ - if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) +static int ipv6_from_asc(unsigned char v6[16], const char *in) { + IPV6_STAT v6stat; + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + // Treat the IPv6 representation as a list of values separated by ':'. + // The presence of a '::' will parse as one, two or three zero length + // elements. + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) { + return 0; + } + + if (v6stat.zero_pos == -1) { + // If no '::' must have exactly 16 bytes + if (v6stat.total != 16) { + return 0; + } + } else { + // If '::' must have less than 16 bytes + if (v6stat.total >= 16) { + return 0; + } + if (v6stat.zero_cnt > 3) { + // More than three zeroes is an error + return 0; + } else if (v6stat.zero_cnt == 3) { + // Can only have three zeroes if nothing else present + if (v6stat.total > 0) { return 0; - - /* Now for some sanity checks */ - - if (v6stat.zero_pos == -1) { - /* If no '::' must have exactly 16 bytes */ - if (v6stat.total != 16) - return 0; + } + } else if (v6stat.zero_cnt == 2) { + // Can only have two zeroes if at start or end + if (v6stat.zero_pos != 0 && v6stat.zero_pos != v6stat.total) { + return 0; + } } else { - /* If '::' must have less than 16 bytes */ - if (v6stat.total == 16) - return 0; - /* More than three zeroes is an error */ - if (v6stat.zero_cnt > 3) - return 0; - /* Can only have three zeroes if nothing else present */ - else if (v6stat.zero_cnt == 3) { - if (v6stat.total > 0) - return 0; - } - /* Can only have two zeroes if at start or end */ - else if (v6stat.zero_cnt == 2) { - if ((v6stat.zero_pos != 0) - && (v6stat.zero_pos != v6stat.total)) - return 0; - } else - /* Can only have one zero if *not* start or end */ - { - if ((v6stat.zero_pos == 0) - || (v6stat.zero_pos == v6stat.total)) - return 0; - } + // Can only have one zero if *not* start or end + if (v6stat.zero_pos == 0 || v6stat.zero_pos == v6stat.total) { + return 0; + } } + } - /* Format result */ + // Format the result. + if (v6stat.zero_pos >= 0) { + // Copy initial part + OPENSSL_memcpy(v6, v6stat.tmp, v6stat.zero_pos); + // Zero middle + OPENSSL_memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + // Copy final part + if (v6stat.total != v6stat.zero_pos) { + OPENSSL_memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } + } else { + OPENSSL_memcpy(v6, v6stat.tmp, 16); + } - if (v6stat.zero_pos >= 0) { - /* Copy initial part */ - OPENSSL_memcpy(v6, v6stat.tmp, v6stat.zero_pos); - /* Zero middle */ - OPENSSL_memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); - /* Copy final part */ - if (v6stat.total != v6stat.zero_pos) - OPENSSL_memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, - v6stat.tmp + v6stat.zero_pos, - v6stat.total - v6stat.zero_pos); - } else - OPENSSL_memcpy(v6, v6stat.tmp, 16); - - return 1; + return 1; } -static int ipv6_cb(const char *elem, int len, void *usr) -{ - IPV6_STAT *s = usr; - /* Error if 16 bytes written */ - if (s->total == 16) +static int ipv6_cb(const char *elem, size_t len, void *usr) { + IPV6_STAT *s = usr; + // Error if 16 bytes written + if (s->total == 16) { + return 0; + } + if (len == 0) { + // Zero length element, corresponds to '::' + if (s->zero_pos == -1) { + s->zero_pos = s->total; + } else if (s->zero_pos != s->total) { + // If we've already got a :: its an error + return 0; + } + if (s->zero_cnt >= 3) { + // More than three zeros is an error. + return 0; + } + s->zero_cnt++; + } else { + // If more than 4 characters could be final a.b.c.d form + if (len > 4) { + // Need at least 4 bytes left + if (s->total > 12) { return 0; - if (len == 0) { - /* Zero length element, corresponds to '::' */ - if (s->zero_pos == -1) - s->zero_pos = s->total; - /* If we've already got a :: its an error */ - else if (s->zero_pos != s->total) - return 0; - s->zero_cnt++; + } + // Must be end of string + if (elem[len]) { + return 0; + } + if (!ipv4_from_asc(s->tmp + s->total, elem)) { + return 0; + } + s->total += 4; } else { - /* If more than 4 characters could be final a.b.c.d form */ - if (len > 4) { - /* Need at least 4 bytes left */ - if (s->total > 12) - return 0; - /* Must be end of string */ - if (elem[len]) - return 0; - if (!ipv4_from_asc(s->tmp + s->total, elem)) - return 0; - s->total += 4; - } else { - if (!ipv6_hex(s->tmp + s->total, elem, len)) - return 0; - s->total += 2; - } - } - return 1; -} - -/* - * Convert a string of up to 4 hex digits into the corresponding IPv6 form. - */ - -static int ipv6_hex(unsigned char *out, const char *in, int inlen) -{ - unsigned char c; - unsigned int num = 0; - if (inlen > 4) + if (!ipv6_hex(s->tmp + s->total, elem, len)) { return 0; - while (inlen--) { - c = *in++; - num <<= 4; - if ((c >= '0') && (c <= '9')) - num |= c - '0'; - else if ((c >= 'A') && (c <= 'F')) - num |= c - 'A' + 10; - else if ((c >= 'a') && (c <= 'f')) - num |= c - 'a' + 10; - else - return 0; + } + s->total += 2; } - out[0] = num >> 8; - out[1] = num & 0xff; - return 1; + } + return 1; } -int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF (CONF_VALUE) * dn_sk, - unsigned long chtype) -{ - CONF_VALUE *v; +// Convert a string of up to 4 hex digits into the corresponding IPv6 form. + +static int ipv6_hex(unsigned char *out, const char *in, size_t inlen) { + if (inlen > 4) { + return 0; + } + uint16_t num = 0; + while (inlen--) { + uint8_t val; + if (!OPENSSL_fromxdigit(&val, *in++)) { + return 0; + } + num = (num << 4) | val; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, + int chtype) { + if (!nm) { + return 0; + } + + for (size_t i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + const CONF_VALUE *v = sk_CONF_VALUE_value(dn_sk, i); + const char *type = v->name; + // Skip past any leading X. X: X, etc to allow for multiple instances + for (const char *p = type; *p; p++) { + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) { + type = p; + } + break; + } + } int mval; - size_t i; - char *p, *type; - if (!nm) - return 0; - - for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { - v = sk_CONF_VALUE_value(dn_sk, i); - type = v->name; - /* - * Skip past any leading X. X: X, etc to allow for multiple instances - */ - for (p = type; *p; p++) - if ((*p == ':') || (*p == ',') || (*p == '.')) { - p++; - if (*p) - type = p; - break; - } - if (*type == '+') { - mval = -1; - type++; - } else - mval = 0; - if (!X509_NAME_add_entry_by_txt(nm, type, chtype, - (unsigned char *)v->value, -1, -1, - mval)) - return 0; - + if (*type == '+') { + mval = -1; + type++; + } else { + mval = 0; } - return 1; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, (unsigned char *)v->value, + -1, -1, mval)) { + return 0; + } + } + return 1; } diff --git a/third_party/boringssl/kit/src/crypto/x509v3/v3name_test.cc b/third_party/boringssl/kit/src/crypto/x509v3/v3name_test.cc deleted file mode 100644 index a501115c..00000000 --- a/third_party/boringssl/kit/src/crypto/x509v3/v3name_test.cc +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#include -#include - -#include - -#include -#include -#include -#include - -#include "../internal.h" -#include "internal.h" - - -static const char *const names[] = { - "a", "b", ".", "*", "@", - ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..", - "-example.com", "example-.com", - "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com", - "*@example.com", "test@*.example.com", "example.com", "www.example.com", - "test.www.example.com", "*.example.com", "*.www.example.com", - "test.*.example.com", "www.*.com", - ".www.example.com", "*www.example.com", - "example.net", "xn--rger-koa.example.com", - "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com", - "*.good--example.com", "www.good--example.com", - "*.xn--bar.com", "xn--foo.xn--bar.com", - "a.example.com", "b.example.com", - "postmaster@example.com", "Postmaster@example.com", - "postmaster@EXAMPLE.COM", - NULL -}; - -static const char *const exceptions[] = { - "set CN: host: [*.example.com] matches [a.example.com]", - "set CN: host: [*.example.com] matches [b.example.com]", - "set CN: host: [*.example.com] matches [www.example.com]", - "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]", - "set CN: host: [*.www.example.com] matches [test.www.example.com]", - "set CN: host: [*.www.example.com] matches [.www.example.com]", - "set CN: host: [*www.example.com] matches [www.example.com]", - "set CN: host: [test.www.example.com] matches [.www.example.com]", - "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]", - "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]", - "set CN: host: [*.good--example.com] matches [www.good--example.com]", - "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]", - "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]", - "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]", - "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]", - "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]", - "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]", - "set dnsName: host: [*.example.com] matches [www.example.com]", - "set dnsName: host: [*.example.com] matches [a.example.com]", - "set dnsName: host: [*.example.com] matches [b.example.com]", - "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]", - "set dnsName: host: [*.www.example.com] matches [test.www.example.com]", - "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]", - "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]", - "set dnsName: host: [*.www.example.com] matches [.www.example.com]", - "set dnsName: host: [*www.example.com] matches [www.example.com]", - "set dnsName: host: [test.www.example.com] matches [.www.example.com]", - "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]", - "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]", - "set dnsName: host: [*.good--example.com] matches [www.good--example.com]", - "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]", - "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]", - "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]", - "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]", - NULL -}; - -static int is_exception(const char *msg) -{ - const char *const *p; - for (p = exceptions; *p; ++p) - if (strcmp(msg, *p) == 0) - return 1; - return 0; -} - -static int set_cn(X509 *crt, ...) -{ - int ret = 0; - X509_NAME *n = NULL; - va_list ap; - va_start(ap, crt); - n = X509_NAME_new(); - if (n == NULL) - goto out; - while (1) { - int nid; - const char *name; - nid = va_arg(ap, int); - if (nid == 0) - break; - name = va_arg(ap, const char *); - if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, - (unsigned char *)name, -1, -1, 1)) - goto out; - } - if (!X509_set_subject_name(crt, n)) - goto out; - ret = 1; - out: - X509_NAME_free(n); - va_end(ap); - return ret; -} - -/* - * int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); X509_EXTENSION - * *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, - * ASN1_OCTET_STRING *data); int X509_add_ext(X509 *x, X509_EXTENSION *ex, - * int loc); - */ - -static int set_altname(X509 *crt, ...) -{ - int ret = 0; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - ASN1_IA5STRING *ia5 = NULL; - va_list ap; - va_start(ap, crt); - gens = sk_GENERAL_NAME_new_null(); - if (gens == NULL) - goto out; - while (1) { - int type; - const char *name; - type = va_arg(ap, int); - if (type == 0) - break; - name = va_arg(ap, const char *); - - gen = GENERAL_NAME_new(); - if (gen == NULL) - goto out; - ia5 = ASN1_IA5STRING_new(); - if (ia5 == NULL) - goto out; - if (!ASN1_STRING_set(ia5, name, -1)) - goto out; - switch (type) { - case GEN_EMAIL: - case GEN_DNS: - GENERAL_NAME_set0_value(gen, type, ia5); - ia5 = NULL; - break; - default: - abort(); - } - sk_GENERAL_NAME_push(gens, gen); - gen = NULL; - } - if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0)) - goto out; - ret = 1; - out: - ASN1_IA5STRING_free(ia5); - GENERAL_NAME_free(gen); - GENERAL_NAMES_free(gens); - va_end(ap); - return ret; -} - -static int set_cn1(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, name, 0); -} - -static int set_cn_and_email(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, name, - NID_pkcs9_emailAddress, "dummy@example.com", 0); -} - -static int set_cn2(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, "dummy value", - NID_commonName, name, 0); -} - -static int set_cn3(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, name, - NID_commonName, "dummy value", 0); -} - -static int set_email1(X509 *crt, const char *name) -{ - return set_cn(crt, NID_pkcs9_emailAddress, name, 0); -} - -static int set_email2(X509 *crt, const char *name) -{ - return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com", - NID_pkcs9_emailAddress, name, 0); -} - -static int set_email3(X509 *crt, const char *name) -{ - return set_cn(crt, NID_pkcs9_emailAddress, name, - NID_pkcs9_emailAddress, "dummy@example.com", 0); -} - -static int set_email_and_cn(X509 *crt, const char *name) -{ - return set_cn(crt, NID_pkcs9_emailAddress, name, - NID_commonName, "www.example.org", 0); -} - -static int set_altname_dns(X509 *crt, const char *name) -{ - return set_altname(crt, GEN_DNS, name, 0); -} - -static int set_altname_email(X509 *crt, const char *name) -{ - return set_altname(crt, GEN_EMAIL, name, 0); -} - -struct set_name_fn { - int (*fn) (X509 *, const char *); - const char *name; - int host; - int email; -}; - -static const struct set_name_fn name_fns[] = { - {set_cn1, "set CN", 1, 0}, - {set_cn2, "set CN", 1, 0}, - {set_cn3, "set CN", 1, 0}, - {set_cn_and_email, "set CN", 1, 0}, - {set_email1, "set emailAddress", 0, 1}, - {set_email2, "set emailAddress", 0, 1}, - {set_email3, "set emailAddress", 0, 1}, - {set_email_and_cn, "set emailAddress", 0, 1}, - {set_altname_dns, "set dnsName", 1, 0}, - {set_altname_email, "set rfc822Name", 0, 1}, - {NULL, NULL, 0, 0}, -}; - -static X509 *make_cert(void) -{ - X509 *ret = NULL; - X509 *crt = NULL; - X509_NAME *issuer = NULL; - crt = X509_new(); - if (crt == NULL) - goto out; - if (!X509_set_version(crt, X509_VERSION_3)) - goto out; - ret = crt; - crt = NULL; - out: - X509_NAME_free(issuer); - return ret; -} - -static int errors; - -static void check_message(const struct set_name_fn *fn, const char *op, - const char *nameincert, int match, const char *name) -{ - char msg[1024]; - if (match < 0) - return; - BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]", - fn->name, op, nameincert, - match ? "matches" : "does not match", name); - if (is_exception(msg)) - return; - puts(msg); - ++errors; -} - -static void run_cert(X509 *crt, const char *nameincert, - const struct set_name_fn *fn) -{ - const char *const *pname = names; - while (*pname) { - int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0; - size_t namelen = strlen(*pname); - char *name = (char *)malloc(namelen); - int match, ret; - OPENSSL_memcpy(name, *pname, namelen); - - ret = X509_check_host(crt, name, namelen, 0, NULL); - match = -1; - if (ret < 0) { - fprintf(stderr, "internal error in X509_check_host\n"); - ++errors; - } else if (fn->host) { - if (ret == 1 && !samename) - match = 1; - if (ret == 0 && samename) - match = 0; - } else if (ret == 1) - match = 1; - check_message(fn, "host", nameincert, match, *pname); - - ret = X509_check_host(crt, name, namelen, - X509_CHECK_FLAG_NO_WILDCARDS, NULL); - match = -1; - if (ret < 0) { - fprintf(stderr, "internal error in X509_check_host\n"); - ++errors; - } else if (fn->host) { - if (ret == 1 && !samename) - match = 1; - if (ret == 0 && samename) - match = 0; - } else if (ret == 1) - match = 1; - check_message(fn, "host-no-wildcards", nameincert, match, *pname); - - ret = X509_check_email(crt, name, namelen, 0); - match = -1; - if (fn->email) { - if (ret && !samename) - match = 1; - if (!ret && samename && strchr(nameincert, '@') != NULL) - match = 0; - } else if (ret) - match = 1; - check_message(fn, "email", nameincert, match, *pname); - ++pname; - free(name); - } -} - -// TODO(davidben): Convert this test to GTest more thoroughly. -TEST(X509V3Test, NameTest) { - const struct set_name_fn *pfn = name_fns; - while (pfn->name) { - const char *const *pname = names; - while (*pname) { - // The common name fallback requires the name look sufficiently - // DNS-like. - if (strcmp(pfn->name, "set CN") == 0 && - !x509v3_looks_like_dns_name( - reinterpret_cast(*pname), - strlen(*pname))) { - ++pname; - continue; - } - bssl::UniquePtr crt(make_cert()); - ASSERT_TRUE(crt); - ASSERT_TRUE(pfn->fn(crt.get(), *pname)); - run_cert(crt.get(), *pname, pfn); - ++pname; - } - ++pfn; - } - EXPECT_EQ(0, errors); -} diff --git a/third_party/boringssl/kit/src/decrepit/CMakeLists.txt b/third_party/boringssl/kit/src/decrepit/CMakeLists.txt index 16985da1..927882e9 100644 --- a/third_party/boringssl/kit/src/decrepit/CMakeLists.txt +++ b/third_party/boringssl/kit/src/decrepit/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(../include) - add_library( decrepit @@ -21,9 +19,6 @@ add_library( x509/x509_decrepit.c xts/xts.c ) - -add_dependencies(decrepit global_target) - target_link_libraries(decrepit crypto ssl) add_executable( @@ -35,15 +30,7 @@ add_executable( evp/evp_test.cc ripemd/ripemd_test.cc xts/xts_test.cc - - $ ) - -add_dependencies(decrepit_test global_target) - -target_link_libraries(decrepit_test test_support_lib boringssl_gtest decrepit - crypto) -if(WIN32) - target_link_libraries(decrepit_test ws2_32) -endif() +target_link_libraries(decrepit_test test_support_lib boringssl_gtest_main + decrepit crypto) add_dependencies(all_tests decrepit_test) diff --git a/third_party/boringssl/kit/src/decrepit/blowfish/blowfish.c b/third_party/boringssl/kit/src/decrepit/blowfish/blowfish.c index aa872bc6..7c209da5 100644 --- a/third_party/boringssl/kit/src/decrepit/blowfish/blowfish.c +++ b/third_party/boringssl/kit/src/decrepit/blowfish/blowfish.c @@ -61,6 +61,7 @@ #include #include +#include "../../crypto/fipsmodule/cipher/internal.h" #include "../../crypto/internal.h" #include "../macros.h" diff --git a/third_party/boringssl/kit/src/decrepit/cast/cast.c b/third_party/boringssl/kit/src/decrepit/cast/cast.c index dffee5c1..314e3da2 100644 --- a/third_party/boringssl/kit/src/decrepit/cast/cast.c +++ b/third_party/boringssl/kit/src/decrepit/cast/cast.c @@ -64,6 +64,7 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3)) OPENSSL_MSVC_PRAGMA(warning(pop)) #endif +#include "../../crypto/fipsmodule/cipher/internal.h" #include "../../crypto/internal.h" #include "internal.h" #include "../macros.h" diff --git a/third_party/boringssl/kit/src/decrepit/cfb/cfb.c b/third_party/boringssl/kit/src/decrepit/cfb/cfb.c index fa1cfd4f..c15292cf 100644 --- a/third_party/boringssl/kit/src/decrepit/cfb/cfb.c +++ b/third_party/boringssl/kit/src/decrepit/cfb/cfb.c @@ -10,7 +10,7 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include @@ -19,6 +19,7 @@ #include #include +#include "../../crypto/fipsmodule/cipher/internal.h" #include "../../crypto/internal.h" typedef struct { diff --git a/third_party/boringssl/kit/src/decrepit/cfb/cfb_test.cc b/third_party/boringssl/kit/src/decrepit/cfb/cfb_test.cc index 2510a88a..da9681ec 100644 --- a/third_party/boringssl/kit/src/decrepit/cfb/cfb_test.cc +++ b/third_party/boringssl/kit/src/decrepit/cfb/cfb_test.cc @@ -10,7 +10,7 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include diff --git a/third_party/boringssl/kit/src/decrepit/des/cfb64ede.c b/third_party/boringssl/kit/src/decrepit/des/cfb64ede.c index 6c399230..820c52e9 100644 --- a/third_party/boringssl/kit/src/decrepit/des/cfb64ede.c +++ b/third_party/boringssl/kit/src/decrepit/des/cfb64ede.c @@ -58,7 +58,7 @@ #include -#include "../../crypto/fipsmodule/des/internal.h" +#include "../../crypto/des/internal.h" #include "../../crypto/internal.h" diff --git a/third_party/boringssl/kit/src/decrepit/macros.h b/third_party/boringssl/kit/src/decrepit/macros.h index 7888f0d1..4e4ea939 100644 --- a/third_party/boringssl/kit/src/decrepit/macros.h +++ b/third_party/boringssl/kit/src/decrepit/macros.h @@ -61,35 +61,35 @@ // NOTE - c is not incremented as per n2l -#define n2ln(c, l1, l2, n) \ - { \ - c += n; \ - l1 = l2 = 0; \ - switch (n) { \ - case 8: \ - l2 = ((unsigned long)(*(--(c)))); \ - OPENSSL_FALLTHROUGH; \ - case 7: \ - l2 |= ((unsigned long)(*(--(c)))) << 8; \ - OPENSSL_FALLTHROUGH; \ - case 6: \ - l2 |= ((unsigned long)(*(--(c)))) << 16; \ - OPENSSL_FALLTHROUGH; \ - case 5: \ - l2 |= ((unsigned long)(*(--(c)))) << 24; \ - OPENSSL_FALLTHROUGH; \ - case 4: \ - l1 = ((unsigned long)(*(--(c)))); \ - OPENSSL_FALLTHROUGH; \ - case 3: \ - l1 |= ((unsigned long)(*(--(c)))) << 8; \ - OPENSSL_FALLTHROUGH; \ - case 2: \ - l1 |= ((unsigned long)(*(--(c)))) << 16; \ - OPENSSL_FALLTHROUGH; \ - case 1: \ - l1 |= ((unsigned long)(*(--(c)))) << 24; \ - } \ +#define n2ln(c, l1, l2, n) \ + { \ + c += n; \ + l1 = l2 = 0; \ + switch (n) { \ + case 8: \ + l2 = ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + l2 |= ((uint32_t)(*(--(c)))) << 8; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + l2 |= ((uint32_t)(*(--(c)))) << 16; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + l2 |= ((uint32_t)(*(--(c)))) << 24; \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + l1 = ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + l1 |= ((uint32_t)(*(--(c)))) << 8; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + l1 |= ((uint32_t)(*(--(c)))) << 16; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + l1 |= ((uint32_t)(*(--(c)))) << 24; \ + } \ } // NOTE - c is not incremented as per l2n @@ -99,25 +99,25 @@ switch (n) { \ case 8: \ *(--(c)) = (unsigned char)(((l2)) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 7: \ *(--(c)) = (unsigned char)(((l2) >> 8) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 6: \ *(--(c)) = (unsigned char)(((l2) >> 16) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 5: \ *(--(c)) = (unsigned char)(((l2) >> 24) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 4: \ *(--(c)) = (unsigned char)(((l1)) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 3: \ *(--(c)) = (unsigned char)(((l1) >> 8) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 2: \ *(--(c)) = (unsigned char)(((l1) >> 16) & 0xff); \ - OPENSSL_FALLTHROUGH; \ + OPENSSL_FALLTHROUGH; \ case 1: \ *(--(c)) = (unsigned char)(((l1) >> 24) & 0xff); \ } \ @@ -129,11 +129,9 @@ *((c)++) = (unsigned char)(((l) >> 8L) & 0xff), \ *((c)++) = (unsigned char)(((l)) & 0xff)) -#define n2l(c, l) \ - (l = ((unsigned long)(*((c)++))) << 24L, \ - l |= ((unsigned long)(*((c)++))) << 16L, \ - l |= ((unsigned long)(*((c)++))) << 8L, \ - l |= ((unsigned long)(*((c)++)))) +#define n2l(c, l) \ + (l = ((uint32_t)(*((c)++))) << 24L, l |= ((uint32_t)(*((c)++))) << 16L, \ + l |= ((uint32_t)(*((c)++))) << 8L, l |= ((uint32_t)(*((c)++)))) #endif // OPENSSL_HEADER_DECREPIT_MACROS_H diff --git a/third_party/boringssl/kit/src/decrepit/ripemd/ripemd_test.cc b/third_party/boringssl/kit/src/decrepit/ripemd/ripemd_test.cc index 0700baee..6338fec7 100644 --- a/third_party/boringssl/kit/src/decrepit/ripemd/ripemd_test.cc +++ b/third_party/boringssl/kit/src/decrepit/ripemd/ripemd_test.cc @@ -57,17 +57,13 @@ static const RIPEMDTestCase kRIPEMDTestCases[] = { // TODO(davidben): Convert this file to GTest properly. TEST(RIPEMDTest, RunTest) { - unsigned test_num = 0; - int ok = 1; - for (const auto &test : kRIPEMDTestCases) { - test_num++; - + SCOPED_TRACE(test.input); const size_t input_len = strlen(test.input); for (size_t stride = 0; stride <= input_len; stride++) { + SCOPED_TRACE(stride); uint8_t digest[RIPEMD160_DIGEST_LENGTH]; - if (stride == 0) { RIPEMD160(reinterpret_cast(test.input), input_len, digest); @@ -89,12 +85,7 @@ TEST(RIPEMDTest, RunTest) { RIPEMD160_Final(digest, &ctx); } - if (OPENSSL_memcmp(digest, test.expected, sizeof(digest)) != 0) { - fprintf(stderr, "#%u: bad result with stride %u: ", test_num, - static_cast(stride)); - hexdump(stderr, "", digest, sizeof(digest)); - ok = 0; - } + EXPECT_EQ(Bytes(digest), Bytes(test.expected)); } } @@ -107,12 +98,6 @@ TEST(RIPEMDTest, RunTest) { static const uint8_t kMillionADigest[RIPEMD160_DIGEST_LENGTH] = { 0x52, 0x78, 0x32, 0x43, 0xc1, 0x69, 0x7b, 0xdb, 0xe1, 0x6d, 0x37, 0xf9, 0x7f, 0x68, 0xf0, 0x83, 0x25, 0xdc, 0x15, 0x28}; - - if (OPENSSL_memcmp(digest, kMillionADigest, sizeof(digest)) != 0) { - fprintf(stderr, u8"Digest incorrect for “million a's” test: "); - hexdump(stderr, "", digest, sizeof(digest)); - ok = 0; - } - - EXPECT_EQ(1, ok); + EXPECT_EQ(Bytes(digest), Bytes(kMillionADigest)) + << "Digest incorrect for \"million a's\" test"; } diff --git a/third_party/boringssl/kit/src/decrepit/rsa/rsa_decrepit.c b/third_party/boringssl/kit/src/decrepit/rsa/rsa_decrepit.c index 54be9b27..2c06fe34 100644 --- a/third_party/boringssl/kit/src/decrepit/rsa/rsa_decrepit.c +++ b/third_party/boringssl/kit/src/decrepit/rsa/rsa_decrepit.c @@ -61,7 +61,7 @@ #include -RSA *RSA_generate_key(int bits, unsigned long e_value, void *callback, +RSA *RSA_generate_key(int bits, uint64_t e_value, void *callback, void *cb_arg) { assert(callback == NULL); assert(cb_arg == NULL); @@ -71,7 +71,7 @@ RSA *RSA_generate_key(int bits, unsigned long e_value, void *callback, if (rsa == NULL || e == NULL || - !BN_set_word(e, e_value) || + !BN_set_u64(e, e_value) || !RSA_generate_key_ex(rsa, bits, e, NULL)) { goto err; } diff --git a/third_party/boringssl/kit/src/decrepit/x509/x509_decrepit.c b/third_party/boringssl/kit/src/decrepit/x509/x509_decrepit.c index 3abab06a..5af499ed 100644 --- a/third_party/boringssl/kit/src/decrepit/x509/x509_decrepit.c +++ b/third_party/boringssl/kit/src/decrepit/x509/x509_decrepit.c @@ -19,8 +19,9 @@ #include -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - int ext_nid, const char *value) { +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + const X509V3_CTX *ctx, int ext_nid, + const char *value) { assert(conf == NULL); return X509V3_EXT_nconf_nid(NULL, ctx, ext_nid, value); } diff --git a/third_party/boringssl/kit/src/decrepit/xts/xts.c b/third_party/boringssl/kit/src/decrepit/xts/xts.c index a433c3be..8a66f0f2 100644 --- a/third_party/boringssl/kit/src/decrepit/xts/xts.c +++ b/third_party/boringssl/kit/src/decrepit/xts/xts.c @@ -53,7 +53,8 @@ #include #include -#include "../crypto/fipsmodule/modes/internal.h" +#include "../../crypto/fipsmodule/cipher/internal.h" +#include "../../crypto/fipsmodule/modes/internal.h" typedef struct xts128_context { diff --git a/third_party/boringssl/kit/src/decrepit/xts/xts_test.cc b/third_party/boringssl/kit/src/decrepit/xts/xts_test.cc index 22e80fac..346ca556 100644 --- a/third_party/boringssl/kit/src/decrepit/xts/xts_test.cc +++ b/third_party/boringssl/kit/src/decrepit/xts/xts_test.cc @@ -10,7 +10,7 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include diff --git a/third_party/boringssl/kit/src/go.mod b/third_party/boringssl/kit/src/go.mod index 25a9d663..23038f02 100644 --- a/third_party/boringssl/kit/src/go.mod +++ b/third_party/boringssl/kit/src/go.mod @@ -1,8 +1,13 @@ module boringssl.googlesource.com/boringssl -go 1.13 +go 1.19 require ( - golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - golang.org/x/net v0.0.0-20210614182718-04defd469f4e + golang.org/x/crypto v0.6.0 + golang.org/x/net v0.7.0 +) + +require ( + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect ) diff --git a/third_party/boringssl/kit/src/go.sum b/third_party/boringssl/kit/src/go.sum index 87e3c894..a97a9607 100644 --- a/third_party/boringssl/kit/src/go.sum +++ b/third_party/boringssl/kit/src/go.sum @@ -1,13 +1,8 @@ -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/third_party/boringssl/kit/src/include/openssl/aead.h b/third_party/boringssl/kit/src/include/openssl/aead.h index 38eb0761..376bff17 100644 --- a/third_party/boringssl/kit/src/include/openssl/aead.h +++ b/third_party/boringssl/kit/src/include/openssl/aead.h @@ -138,12 +138,10 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void); // authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void); -// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See -// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See RFC 8452. OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void); -// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See -// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See RFC 8452. OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void); // EVP_aead_aes_128_gcm_randnonce is AES-128 in Galois Counter Mode with @@ -180,6 +178,10 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void); // v1.0. OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void); +// EVP_aead_aes_128_ccm_matter is AES-128-CCM with M=16 and L=2 (16-byte tags +// and 13-byte nonces), as used in the Matter specification. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_matter(void); + // EVP_has_aes_hardware returns one if we enable hardware support for fast and // constant-time AES-GCM. OPENSSL_EXPORT int EVP_has_aes_hardware(void); @@ -208,19 +210,19 @@ OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); // AEAD operations. union evp_aead_ctx_st_state { - uint8_t opaque[580]; + uint8_t opaque[564]; uint64_t alignment; }; -// An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key -// and message-independent IV. -typedef struct evp_aead_ctx_st { +// An evp_aead_ctx_st (typedefed as |EVP_AEAD_CTX| in base.h) represents an AEAD +// algorithm configured with a specific key and message-independent IV. +struct evp_aead_ctx_st { const EVP_AEAD *aead; union evp_aead_ctx_st_state state; // tag_len may contain the actual length of the authentication tag if it is // known at initialization time. uint8_t tag_len; -} EVP_AEAD_CTX; +}; // EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by // any AEAD defined in this header. @@ -398,14 +400,14 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx); OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void); OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void); + OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void); OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void); OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void); OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void); -OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void); - // EVP_aead_aes_128_gcm_tls12 is AES-128 in Galois Counter Mode using the TLS // 1.2 nonce construction. OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls12(void); diff --git a/third_party/boringssl/kit/src/include/openssl/arm_arch.h b/third_party/boringssl/kit/src/include/openssl/arm_arch.h index 81dc7965..7215f62e 100644 --- a/third_party/boringssl/kit/src/include/openssl/arm_arch.h +++ b/third_party/boringssl/kit/src/include/openssl/arm_arch.h @@ -53,54 +53,12 @@ #ifndef OPENSSL_HEADER_ARM_ARCH_H #define OPENSSL_HEADER_ARM_ARCH_H -#if !defined(__ARM_ARCH__) -# if defined(__CC_ARM) -# define __ARM_ARCH__ __TARGET_ARCH_ARM -# if defined(__BIG_ENDIAN) -# define __ARMEB__ -# else -# define __ARMEL__ -# endif -# elif defined(__GNUC__) -# if defined(__aarch64__) -# define __ARM_ARCH__ 8 -# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define __ARMEB__ -# else -# define __ARMEL__ -# endif - // Why doesn't gcc define __ARM_ARCH__? Instead it defines - // bunch of below macros. See all_architectires[] table in - // gcc/config/arm/arm.c. On a side note it defines - // __ARMEL__/__ARMEB__ for little-/big-endian. -# elif defined(__ARM_ARCH) -# define __ARM_ARCH__ __ARM_ARCH -# elif defined(__ARM_ARCH_8A__) -# define __ARM_ARCH__ 8 -# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ - defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \ - defined(__ARM_ARCH_7EM__) -# define __ARM_ARCH__ 7 -# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \ - defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \ - defined(__ARM_ARCH_6T2__) -# define __ARM_ARCH__ 6 -# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ - defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \ - defined(__ARM_ARCH_5TEJ__) -# define __ARM_ARCH__ 5 -# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) -# define __ARM_ARCH__ 4 -# else -# error "unsupported ARM architecture" -# endif -# endif -#endif +// arm_arch.h contains symbols used by ARM assembly, and the C code that calls +// it. It is included as a public header to simplify the build, but is not +// intended for external use. -// Even when building for 32-bit ARM, support for aarch64 crypto instructions -// will be included. -#define __ARM_MAX_ARCH__ 8 +#if defined(__ARMEL__) || defined(_M_ARM) || defined(__AARCH64EL__) || \ + defined(_M_ARM64) // ARMV7_NEON is true when a NEON unit is present in the current CPU. #define ARMV7_NEON (1 << 0) @@ -117,8 +75,28 @@ // ARMV8_PMULL indicates support for carryless multiplication. #define ARMV8_PMULL (1 << 5) +// ARMV8_SHA512 indicates support for hardware SHA-512 instructions. +#define ARMV8_SHA512 (1 << 6) + #if defined(__ASSEMBLER__) +// We require the ARM assembler provide |__ARM_ARCH| from Arm C Language +// Extensions (ACLE). This is supported in GCC 4.8+ and Clang 3.2+. MSVC does +// not implement ACLE, but we require Clang's assembler on Windows. +#if !defined(__ARM_ARCH) +#error "ARM assembler must define __ARM_ARCH" +#endif + +// __ARM_ARCH__ is used by OpenSSL assembly to determine the minimum target ARM +// version. +// +// TODO(davidben): Switch the assembly to use |__ARM_ARCH| directly. +#define __ARM_ARCH__ __ARM_ARCH + +// Even when building for 32-bit ARM, support for aarch64 crypto instructions +// will be included. +#define __ARM_MAX_ARCH__ 8 + // Support macros for // - Armv8.3-A Pointer Authentication and // - Armv8.5-A Branch Target Identification @@ -235,6 +213,8 @@ .popsection; #endif -#endif /* defined __ASSEMBLER__ */ +#endif // __ASSEMBLER__ + +#endif // __ARMEL__ || _M_ARM || __AARCH64EL__ || _M_ARM64 #endif // OPENSSL_HEADER_ARM_ARCH_H diff --git a/third_party/boringssl/kit/src/include/openssl/asn1.h b/third_party/boringssl/kit/src/include/openssl/asn1.h index d8a371c3..c9f265a2 100644 --- a/third_party/boringssl/kit/src/include/openssl/asn1.h +++ b/third_party/boringssl/kit/src/include/openssl/asn1.h @@ -55,8 +55,8 @@ * [including the GNU Public Licence.] */ -#ifndef HEADER_ASN1_H -#define HEADER_ASN1_H +#ifndef OPENSSL_HEADER_ASN1_H +#define OPENSSL_HEADER_ASN1_H #include @@ -213,38 +213,10 @@ OPENSSL_EXPORT const char *ASN1_tag2str(int tag); // // Note: If |out| and |*out| are both non-NULL, the object at |*out| is not // updated in-place. Instead, it is freed, and the pointer is updated to the -// new object. This differs from OpenSSL, which behaves more like -// |d2i_SAMPLE_with_reuse|. Callers are recommended to set |out| to NULL and -// instead use the return value. +// new object. This differs from OpenSSL. Callers are recommended to set |out| +// to NULL and instead use the return value. SAMPLE *d2i_SAMPLE(SAMPLE **out, const uint8_t **inp, long len); -// d2i_SAMPLE_with_reuse parses a structure from up to |len| bytes at |*inp|. On -// success, it advances |*inp| by the number of bytes read and returns a -// non-NULL pointer to an object containing the parsed structure. The object is -// determined from |out| as follows: -// -// If |out| is NULL, the function places the result in a newly-allocated -// |SAMPLE| object and returns it. This mode is recommended. -// -// If |out| is non-NULL, but |*out| is NULL, the function also places the result -// in a newly-allocated |SAMPLE| object. It sets |*out| to this object and also -// returns it. -// -// If |out| and |*out| are both non-NULL, the function updates the object at -// |*out| in-place with the result and returns |*out|. -// -// If any of the above fail, the function returns NULL. -// -// This function does not reject trailing data in the input. This allows the -// caller to parse a sequence of concatenated structures. Callers parsing only -// one structure should check for trailing data by comparing the updated |*inp| -// with the end of the input. -// -// WARNING: Callers should not rely on the in-place update mode. It often -// produces the wrong result or breaks the type's internal invariants. Future -// revisions of BoringSSL may standardize on the |d2i_SAMPLE| behavior. -SAMPLE *d2i_SAMPLE_with_reuse(SAMPLE **out, const uint8_t **inp, long len); - // i2d_SAMPLE marshals |in|. On error, it returns a negative value. On success, // it returns the length of the result and outputs it via |outp| as follows: // @@ -348,8 +320,8 @@ OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); // ASN1_item_d2i parses the ASN.1 type |it| from up to |len| bytes at |*inp|. -// It behaves like |d2i_SAMPLE_with_reuse|, except that |out| and the return -// value are cast to |ASN1_VALUE| pointers. +// It behaves like |d2i_SAMPLE|, except that |out| and the return value are cast +// to |ASN1_VALUE| pointers. // // TODO(https://crbug.com/boringssl/444): C strict aliasing forbids type-punning // |T*| and |ASN1_VALUE*| the way this function signature does. When that bug is @@ -447,10 +419,22 @@ OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, // integer type. FALSE is zero, TRUE is 0xff, and an omitted OPTIONAL BOOLEAN is // -1. +// ASN1_BOOLEAN_FALSE is FALSE as an |ASN1_BOOLEAN|. +#define ASN1_BOOLEAN_FALSE 0 + +// ASN1_BOOLEAN_TRUE is TRUE as an |ASN1_BOOLEAN|. Some code incorrectly uses +// 1, so prefer |b != ASN1_BOOLEAN_FALSE| over |b == ASN1_BOOLEAN_TRUE|. +#define ASN1_BOOLEAN_TRUE 0xff + +// ASN1_BOOLEAN_NONE, in contexts where the |ASN1_BOOLEAN| represents an +// OPTIONAL BOOLEAN, is an omitted value. Using this value in other contexts is +// undefined and may be misinterpreted as TRUE. +#define ASN1_BOOLEAN_NONE (-1) + // d2i_ASN1_BOOLEAN parses a DER-encoded ASN.1 BOOLEAN from up to |len| bytes at // |*inp|. On success, it advances |*inp| by the number of bytes read and // returns the result. If |out| is non-NULL, it additionally writes the result -// to |*out|. On error, it returns -1. +// to |*out|. On error, it returns |ASN1_BOOLEAN_NONE|. // // This function does not reject trailing data in the input. This allows the // caller to parse a sequence of concatenated structures. Callers parsing only @@ -459,9 +443,6 @@ OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, // // WARNING: This function's is slightly different from other |d2i_*| functions // because |ASN1_BOOLEAN| is not a pointer type. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. OPENSSL_EXPORT ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, long len); @@ -472,7 +453,8 @@ OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp); // The following |ASN1_ITEM|s have ASN.1 type BOOLEAN and C type |ASN1_BOOLEAN|. // |ASN1_TBOOLEAN| and |ASN1_FBOOLEAN| must be marked OPTIONAL. When omitted, -// they are parsed as TRUE and FALSE, respectively, rather than -1. +// they are parsed as TRUE and FALSE, respectively, rather than +// |ASN1_BOOLEAN_NONE|. DECLARE_ASN1_ITEM(ASN1_BOOLEAN) DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) @@ -485,31 +467,39 @@ DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) // |ASN1_STRING|, to represent most values. // An asn1_string_st (aka |ASN1_STRING|) represents a value of a string-like -// ASN.1 type. It contains a type field, and a byte string data field with a +// ASN.1 type. It contains a |type| field, and a byte string |data| field with a // type-specific representation. // -// When representing a string value, the type field is one of -// |V_ASN1_OCTET_STRING|, |V_ASN1_UTF8STRING|, |V_ASN1_NUMERICSTRING|, -// |V_ASN1_PRINTABLESTRING|, |V_ASN1_T61STRING|, |V_ASN1_VIDEOTEXSTRING|, -// |V_ASN1_IA5STRING|, |V_ASN1_GRAPHICSTRING|, |V_ASN1_ISO64STRING|, -// |V_ASN1_VISIBLESTRING|, |V_ASN1_GENERALSTRING|, |V_ASN1_UNIVERSALSTRING|, or -// |V_ASN1_BMPSTRING|. The data contains the byte representation of of the +// If |type| is one of |V_ASN1_OCTET_STRING|, |V_ASN1_UTF8STRING|, +// |V_ASN1_NUMERICSTRING|, |V_ASN1_PRINTABLESTRING|, |V_ASN1_T61STRING|, +// |V_ASN1_VIDEOTEXSTRING|, |V_ASN1_IA5STRING|, |V_ASN1_GRAPHICSTRING|, +// |V_ASN1_ISO64STRING|, |V_ASN1_VISIBLESTRING|, |V_ASN1_GENERALSTRING|, +// |V_ASN1_UNIVERSALSTRING|, or |V_ASN1_BMPSTRING|, the object represents an +// ASN.1 string type. The data contains the byte representation of the // string. // -// When representing a BIT STRING value, the type field is |V_ASN1_BIT_STRING|. -// See bit string documentation below for how the data and flags are used. +// If |type| is |V_ASN1_BIT_STRING|, the object represents a BIT STRING value. +// See bit string documentation below for the data and flags. // -// When representing an INTEGER or ENUMERATED value, the type field is one of -// |V_ASN1_INTEGER|, |V_ASN1_NEG_INTEGER|, |V_ASN1_ENUMERATED|, or -// |V_ASN1_NEG_ENUMERATED|. See integer documentation below for details. +// If |type| is one of |V_ASN1_INTEGER|, |V_ASN1_NEG_INTEGER|, +// |V_ASN1_ENUMERATED|, or |V_ASN1_NEG_ENUMERATED|, the object represents an +// INTEGER or ENUMERATED value. See integer documentation below for details. // -// When representing a GeneralizedTime or UTCTime value, the type field is -// |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, respectively. The data contains -// the DER encoding of the value. For example, the UNIX epoch would be +// If |type| is |V_ASN1_GENERALIZEDTIME| or |V_ASN1_UTCTIME|, the object +// represents a GeneralizedTime or UTCTime value, respectively. The data +// contains the DER encoding of the value. For example, the UNIX epoch would be // "19700101000000Z" for a GeneralizedTime and "700101000000Z" for a UTCTime. // -// |ASN1_STRING|, when stored in an |ASN1_TYPE|, may also represent an element -// with tag not directly supported by this library. See |ASN1_TYPE| for details. +// If |type| is |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or |V_ASN1_OTHER|, the object +// represents a SEQUENCE, SET, or arbitrary ASN.1 value, respectively. Unlike +// the above cases, the data contains the DER encoding of the entire structure, +// including the header. If the value is explicitly or implicitly tagged, this +// too will be reflected in the data field. As this case handles unknown types, +// the contents are not checked when parsing or serializing. +// +// Other values of |type| do not represent a valid ASN.1 value, though +// default-constructed objects may set |type| to -1. Such objects cannot be +// serialized. // // |ASN1_STRING| additionally has the following typedefs: |ASN1_BIT_STRING|, // |ASN1_BMPSTRING|, |ASN1_ENUMERATED|, |ASN1_GENERALIZEDTIME|, @@ -526,15 +516,14 @@ DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) // |ASN1_STRING_length|. // // If a function returns an |ASN1_STRING| where the typedef or ASN.1 structure -// implies constraints on the type field, callers may assume that the type field -// is correct. However, if a function takes an |ASN1_STRING| as input, callers -// must ensure the type field matches. These invariants are not captured by the -// C type system and may not be checked at runtime. For example, callers may -// assume the output of |X509_get0_serialNumber| has type |V_ASN1_INTEGER| or -// |V_ASN1_NEG_INTEGER|. Callers must not pass a string of type -// |V_ASN1_OCTET_STRING| to |X509_set_serialNumber|. Doing so may break -// invariants on the |X509| object and break the |X509_get0_serialNumber| -// invariant. +// implies constraints on |type|, callers may assume that |type| is correct. +// However, if a function takes an |ASN1_STRING| as input, callers must ensure +// |type| matches. These invariants are not captured by the C type system and +// may not be checked at runtime. For example, callers may assume the output of +// |X509_get0_serialNumber| has type |V_ASN1_INTEGER| or |V_ASN1_NEG_INTEGER|. +// Callers must not pass a string of type |V_ASN1_OCTET_STRING| to +// |X509_set_serialNumber|. Doing so may break invariants on the |X509| object +// and break the |X509_get0_serialNumber| invariant. // // TODO(https://crbug.com/boringssl/445): This is very unfriendly. Getting the // type field wrong should not cause memory errors, but it may do strange @@ -605,8 +594,11 @@ OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *str); OPENSSL_EXPORT int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); // ASN1_STRING_set sets the contents of |str| to a copy of |len| bytes from -// |data|. It returns one on success and zero on error. -OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +// |data|. It returns one on success and zero on error. If |data| is NULL, it +// updates the length and allocates the buffer as needed, but does not +// initialize the contents. +OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, + ossl_ssize_t len); // ASN1_STRING_set0 sets the contents of |str| to |len| bytes from |data|. It // takes ownership of |data|, which must have been allocated with @@ -638,10 +630,7 @@ OPENSSL_EXPORT void ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *str); // The following functions parse up to |len| bytes from |*inp| as a // DER-encoded ASN.1 value of the corresponding type, as described in -// |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_BMPSTRING *d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **out, const uint8_t **inp, long len); @@ -751,15 +740,17 @@ OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, // the result. If |out| is NULL, it returns the selected output type without // constructing an |ASN1_STRING|. On error, this function returns -1. OPENSSL_EXPORT int ASN1_mbstring_copy(ASN1_STRING **out, const uint8_t *in, - int len, int inform, unsigned long mask); + ossl_ssize_t len, int inform, + unsigned long mask); // ASN1_mbstring_ncopy behaves like |ASN1_mbstring_copy| but returns an error if // the input is less than |minsize| or greater than |maxsize| codepoints long. A // |maxsize| value of zero is ignored. Note the sizes are measured in // codepoints, not output bytes. OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const uint8_t *in, - int len, int inform, unsigned long mask, - long minsize, long maxsize); + ossl_ssize_t len, int inform, + unsigned long mask, ossl_ssize_t minsize, + ossl_ssize_t maxsize); // ASN1_STRING_set_by_NID behaves like |ASN1_mbstring_ncopy|, but determines // |mask|, |minsize|, and |maxsize| based on |nid|. When |nid| is a recognized @@ -785,7 +776,7 @@ OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const uint8_t *in, // to call |ASN1_mbstring_ncopy| directly instead. OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, - int len, int inform, + ossl_ssize_t len, int inform, int nid); // STABLE_NO_MASK causes |ASN1_STRING_TABLE_add| to allow types other than @@ -830,7 +821,7 @@ OPENSSL_EXPORT ASN1_STRING *DIRECTORYSTRING_new(void); OPENSSL_EXPORT void DIRECTORYSTRING_free(ASN1_STRING *str); // d2i_DIRECTORYSTRING parses up to |len| bytes from |*inp| as a DER-encoded -// X.509 DirectoryString (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// X.509 DirectoryString (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -863,7 +854,7 @@ OPENSSL_EXPORT ASN1_STRING *DISPLAYTEXT_new(void); OPENSSL_EXPORT void DISPLAYTEXT_free(ASN1_STRING *str); // d2i_DISPLAYTEXT parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// DisplayText (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// DisplayText (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -924,10 +915,7 @@ OPENSSL_EXPORT ASN1_BIT_STRING *ASN1_BIT_STRING_new(void); OPENSSL_EXPORT void ASN1_BIT_STRING_free(ASN1_BIT_STRING *str); // d2i_ASN1_BIT_STRING parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 BIT STRING, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 BIT STRING, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, const uint8_t **inp, long len); @@ -939,11 +927,7 @@ OPENSSL_EXPORT int i2d_ASN1_BIT_STRING(const ASN1_BIT_STRING *in, // c2i_ASN1_BIT_STRING decodes |len| bytes from |*inp| as the contents of a // DER-encoded BIT STRING, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out, const uint8_t **inp, long len); @@ -983,7 +967,8 @@ OPENSSL_EXPORT int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, // TODO(davidben): Maybe it should? Wrapping a byte string in a bit string is a // common use case. OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *str, - const unsigned char *d, int length); + const unsigned char *d, + ossl_ssize_t length); // ASN1_BIT_STRING_set_bit sets bit |n| of |str| to one if |value| is non-zero // and zero if |value| is zero, resizing |str| as needed. It then truncates @@ -1014,6 +999,12 @@ OPENSSL_EXPORT int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *str, // |V_ASN1_INTEGER| or |V_ASN1_ENUMERATED|, while negative values have a type of // |V_ASN1_NEG_INTEGER| or |V_ASN1_NEG_ENUMERATED|. Note this differs from DER's // two's complement representation. +// +// The data in the |ASN1_STRING| may not have leading zeros. Note this means +// zero is represented as the empty string. Parsing functions will never return +// invalid representations. If an invalid input is constructed, the marshaling +// functions will skip leading zeros, however other functions, such as +// |ASN1_INTEGER_cmp| or |ASN1_INTEGER_get|, may not return the correct result. DEFINE_STACK_OF(ASN1_INTEGER) @@ -1028,10 +1019,7 @@ OPENSSL_EXPORT void ASN1_INTEGER_free(ASN1_INTEGER *str); OPENSSL_EXPORT ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); // d2i_ASN1_INTEGER parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 INTEGER, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 INTEGER, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **out, const uint8_t **inp, long len); @@ -1041,11 +1029,7 @@ OPENSSL_EXPORT int i2d_ASN1_INTEGER(const ASN1_INTEGER *in, uint8_t **outp); // c2i_ASN1_INTEGER decodes |len| bytes from |*inp| as the contents of a // DER-encoded INTEGER, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// some invalid inputs, but this will be removed in the future. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **in, const uint8_t **outp, long len); @@ -1068,17 +1052,24 @@ OPENSSL_EXPORT int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, uint8_t **outp); // |ASN1_INTEGER*|. DECLARE_ASN1_ITEM(ASN1_INTEGER) -// ASN1_INTEGER_set sets |a| to an INTEGER with value |v|. It returns one on -// success and zero on error. -OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); - // ASN1_INTEGER_set_uint64 sets |a| to an INTEGER with value |v|. It returns one // on success and zero on error. OPENSSL_EXPORT int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v); -// ASN1_INTEGER_get returns the value of |a| as a |long|, or -1 if |a| is out of -// range or the wrong type. -OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); +// ASN1_INTEGER_set_int64 sets |a| to an INTEGER with value |v|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int ASN1_INTEGER_set_int64(ASN1_INTEGER *out, int64_t v); + +// ASN1_INTEGER_get_uint64 converts |a| to a |uint64_t|. On success, it returns +// one and sets |*out| to the result. If |a| did not fit or has the wrong type, +// it returns zero. +OPENSSL_EXPORT int ASN1_INTEGER_get_uint64(uint64_t *out, + const ASN1_INTEGER *a); + +// ASN1_INTEGER_get_int64 converts |a| to a |int64_t|. On success, it returns +// one and sets |*out| to the result. If |a| did not fit or has the wrong type, +// it returns zero. +OPENSSL_EXPORT int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a); // BN_to_ASN1_INTEGER sets |ai| to an INTEGER with value |bn| and returns |ai| // on success or NULL or error. If |ai| is NULL, it returns a newly-allocated @@ -1106,10 +1097,7 @@ OPENSSL_EXPORT ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); OPENSSL_EXPORT void ASN1_ENUMERATED_free(ASN1_ENUMERATED *str); // d2i_ASN1_ENUMERATED parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 ENUMERATED, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// ASN.1 ENUMERATED, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **out, const uint8_t **inp, long len); @@ -1123,18 +1111,30 @@ OPENSSL_EXPORT int i2d_ASN1_ENUMERATED(const ASN1_ENUMERATED *in, // |ASN1_ENUMERATED*|. DECLARE_ASN1_ITEM(ASN1_ENUMERATED) -// ASN1_ENUMERATED_set sets |a| to an ENUMERATED with value |v|. It returns one -// on success and zero on error. -OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +// ASN1_ENUMERATED_set_uint64 sets |a| to an ENUMERATED with value |v|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v); -// ASN1_ENUMERATED_get returns the value of |a| as a |long|, or -1 if |a| is out -// of range or the wrong type. -OPENSSL_EXPORT long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +// ASN1_ENUMERATED_set_int64 sets |a| to an ENUMERATED with value |v|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *out, int64_t v); + +// ASN1_ENUMERATED_get_uint64 converts |a| to a |uint64_t|. On success, it +// returns one and sets |*out| to the result. If |a| did not fit or has the +// wrong type, it returns zero. +OPENSSL_EXPORT int ASN1_ENUMERATED_get_uint64(uint64_t *out, + const ASN1_ENUMERATED *a); + +// ASN1_ENUMERATED_get_int64 converts |a| to a |int64_t|. On success, it +// returns one and sets |*out| to the result. If |a| did not fit or has the +// wrong type, it returns zero. +OPENSSL_EXPORT int ASN1_ENUMERATED_get_int64(int64_t *out, + const ASN1_ENUMERATED *a); // BN_to_ASN1_ENUMERATED sets |ai| to an ENUMERATED with value |bn| and returns // |ai| on success or NULL or error. If |ai| is NULL, it returns a -// newly-allocated |ASN1_INTEGER| on success instead, which the caller must -// release with |ASN1_INTEGER_free|. +// newly-allocated |ASN1_ENUMERATED| on success instead, which the caller must +// release with |ASN1_ENUMERATED_free|. OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); @@ -1172,7 +1172,7 @@ OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_new(void); OPENSSL_EXPORT void ASN1_UTCTIME_free(ASN1_UTCTIME *str); // d2i_ASN1_UTCTIME parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 UTCTime, as described in |d2i_SAMPLE_with_reuse|. +// ASN.1 UTCTime, as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1190,20 +1190,23 @@ DECLARE_ASN1_ITEM(ASN1_UTCTIME) // ASN1_UTCTIME_check returns one if |a| is a valid UTCTime and zero otherwise. OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); -// ASN1_UTCTIME_set represents |t| as a UTCTime and writes the result to |s|. It -// returns |s| on success and NULL on error. If |s| is NULL, it returns a -// newly-allocated |ASN1_UTCTIME| instead. +// ASN1_UTCTIME_set represents |posix_time| as a UTCTime and writes the result +// to |s|. It returns |s| on success and NULL on error. If |s| is NULL, it +// returns a newly-allocated |ASN1_UTCTIME| instead. // // Note this function may fail if the time is out of range for UTCTime. -OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, + int64_t posix_time); -// ASN1_UTCTIME_adj adds |offset_day| days and |offset_sec| seconds to |t| and -// writes the result to |s| as a UTCTime. It returns |s| on success and NULL on -// error. If |s| is NULL, it returns a newly-allocated |ASN1_UTCTIME| instead. +// ASN1_UTCTIME_adj adds |offset_day| days and |offset_sec| seconds to +// |posix_time| and writes the result to |s| as a UTCTime. It returns |s| on +// success and NULL on error. If |s| is NULL, it returns a newly-allocated +// |ASN1_UTCTIME| instead. // // Note this function may fail if the time overflows or is out of range for // UTCTime. -OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, + int64_t posix_time, int offset_day, long offset_sec); // ASN1_UTCTIME_set_string sets |s| to a UTCTime whose contents are a copy of @@ -1226,10 +1229,7 @@ OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_new(void); OPENSSL_EXPORT void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *str); // d2i_ASN1_GENERALIZEDTIME parses up to |len| bytes from |*inp| as a -// DER-encoded ASN.1 GeneralizedTime, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// DER-encoded ASN.1 GeneralizedTime, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME( ASN1_GENERALIZEDTIME **out, const uint8_t **inp, long len); @@ -1246,23 +1246,24 @@ DECLARE_ASN1_ITEM(ASN1_GENERALIZEDTIME) // zero otherwise. OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); -// ASN1_GENERALIZEDTIME_set represents |t| as a GeneralizedTime and writes the -// result to |s|. It returns |s| on success and NULL on error. If |s| is NULL, -// it returns a newly-allocated |ASN1_GENERALIZEDTIME| instead. +// ASN1_GENERALIZEDTIME_set represents |posix_time| as a GeneralizedTime and +// writes the result to |s|. It returns |s| on success and NULL on error. If |s| +// is NULL, it returns a newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time is out of range for GeneralizedTime. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set( - ASN1_GENERALIZEDTIME *s, time_t t); + ASN1_GENERALIZEDTIME *s, int64_t posix_time); // ASN1_GENERALIZEDTIME_adj adds |offset_day| days and |offset_sec| seconds to -// |t| and writes the result to |s| as a GeneralizedTime. It returns |s| on -// success and NULL on error. If |s| is NULL, it returns a newly-allocated -// |ASN1_GENERALIZEDTIME| instead. +// |posix_time| and writes the result to |s| as a GeneralizedTime. It returns +// |s| on success and NULL on error. If |s| is NULL, it returns a +// newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time overflows or is out of range for // GeneralizedTime. OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj( - ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); + ASN1_GENERALIZEDTIME *s, int64_t posix_time, int offset_day, + long offset_sec); // ASN1_GENERALIZEDTIME_set_string sets |s| to a GeneralizedTime whose contents // are a copy of |str|. It returns one on success and zero on error or if |str| @@ -1284,7 +1285,7 @@ OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_new(void); OPENSSL_EXPORT void ASN1_TIME_free(ASN1_TIME *str); // d2i_ASN1_TIME parses up to |len| bytes from |*inp| as a DER-encoded X.509 -// Time (RFC 5280), as described in |d2i_SAMPLE_with_reuse|. +// Time (RFC 5280), as described in |d2i_SAMPLE|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1312,24 +1313,29 @@ DECLARE_ASN1_ITEM(ASN1_TIME) OPENSSL_EXPORT int ASN1_TIME_diff(int *out_days, int *out_seconds, const ASN1_TIME *from, const ASN1_TIME *to); -// ASN1_TIME_set represents |t| as a GeneralizedTime or UTCTime and writes -// the result to |s|. As in RFC 5280, section 4.1.2.5, it uses UTCTime when the -// time fits and GeneralizedTime otherwise. It returns |s| on success and NULL -// on error. If |s| is NULL, it returns a newly-allocated |ASN1_TIME| instead. -// -// Note this function may fail if the time is out of range for GeneralizedTime. -OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); - -// ASN1_TIME_adj adds |offset_day| days and |offset_sec| seconds to -// |t| and writes the result to |s|. As in RFC 5280, section 4.1.2.5, it uses +// ASN1_TIME_set_posix represents |posix_time| as a GeneralizedTime or UTCTime +// and writes the result to |s|. As in RFC 5280, section 4.1.2.5, it uses // UTCTime when the time fits and GeneralizedTime otherwise. It returns |s| on // success and NULL on error. If |s| is NULL, it returns a newly-allocated -// |ASN1_GENERALIZEDTIME| instead. +// |ASN1_TIME| instead. +// +// Note this function may fail if the time is out of range for GeneralizedTime. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set_posix(ASN1_TIME *s, int64_t posix_time); + +// ASN1_TIME_set is exactly the same as |ASN1_TIME_set_posix| but with a +// time_t as input for compatibility. +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t time); + +// ASN1_TIME_adj adds |offset_day| days and |offset_sec| seconds to +// |posix_time| and writes the result to |s|. As in RFC 5280, section 4.1.2.5, +// it uses UTCTime when the time fits and GeneralizedTime otherwise. It returns +// |s| on success and NULL on error. If |s| is NULL, it returns a +// newly-allocated |ASN1_GENERALIZEDTIME| instead. // // Note this function may fail if the time overflows or is out of range for // GeneralizedTime. -OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, - long offset_sec); +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, + int offset_day, long offset_sec); // ASN1_TIME_check returns one if |t| is a valid UTCTime or GeneralizedTime, and // zero otherwise. |t|'s type determines which check is performed. This @@ -1349,6 +1355,20 @@ OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime( // GeneralizedTime. If |str| is neither, it returns zero. OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); +// ASN1_TIME_set_string_X509 behaves like |ASN1_TIME_set_string| except it +// additionally converts GeneralizedTime to UTCTime if it is in the range where +// UTCTime is used. See RFC 5280, section 4.1.2.5. +OPENSSL_EXPORT int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str); + +// ASN1_TIME_to_time_t converts |t| to a time_t value in |out|. On +// success, one is returned. On failure zero is returned. This function +// will fail if the time can not be represented in a time_t. +OPENSSL_EXPORT int ASN1_TIME_to_time_t(const ASN1_TIME *t, time_t *out); + +// ASN1_TIME_to_posix converts |t| to a POSIX time value in |out|. On +// success, one is returned. On failure zero is returned. +OPENSSL_EXPORT int ASN1_TIME_to_posix(const ASN1_TIME *t, int64_t *out); + // TODO(davidben): Expand and document function prototypes generated in macros. @@ -1368,9 +1388,6 @@ OPENSSL_EXPORT void ASN1_NULL_free(ASN1_NULL *null); // d2i_ASN1_NULL parses a DER-encoded ASN.1 NULL value from up to |len| bytes // at |*inp|, as described in |d2i_SAMPLE|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. OPENSSL_EXPORT ASN1_NULL *d2i_ASN1_NULL(ASN1_NULL **out, const uint8_t **inp, long len); @@ -1405,7 +1422,7 @@ DEFINE_STACK_OF(ASN1_OBJECT) // TODO(davidben): Should we just ignore all those parameters? NIDs and names // are only relevant for |ASN1_OBJECT|s in the obj.h table. OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, const uint8_t *data, - int len, const char *sn, + size_t len, const char *sn, const char *ln); // ASN1_OBJECT_free releases memory associated with |a|. If |a| is a static @@ -1413,21 +1430,17 @@ OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, const uint8_t *data, OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a); // d2i_ASN1_OBJECT parses a DER-encoded ASN.1 OBJECT IDENTIFIER from up to |len| -// bytes at |*inp|, as described in |d2i_SAMPLE_with_reuse|. -// -// TODO(https://crbug.com/boringssl/354): This function currently also accepts -// BER, but this will be removed in the future. +// bytes at |*inp|, as described in |d2i_SAMPLE|. OPENSSL_EXPORT ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const uint8_t **inp, long len); // i2d_ASN1_OBJECT marshals |in| as a DER-encoded ASN.1 OBJECT IDENTIFIER, as // described in |i2d_SAMPLE|. -OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, uint8_t **outp); +OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, uint8_t **outp); // c2i_ASN1_OBJECT decodes |len| bytes from |*inp| as the contents of a // DER-encoded OBJECT IDENTIFIER, excluding the tag and length. It behaves like -// |d2i_SAMPLE_with_reuse| except, on success, it always consumes all |len| -// bytes. +// |d2i_SAMPLE| except, on success, it always consumes all |len| bytes. OPENSSL_EXPORT ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const uint8_t **inp, long len); @@ -1469,15 +1482,14 @@ DECLARE_ASN1_ITEM(ASN1_OBJECT) // |ASN1_BOOLEAN|. // // If |type| is |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or |V_ASN1_OTHER|, the tag is -// SEQUENCE, SET, or some non-universal tag, respectively. |value| is an -// |ASN1_STRING| containing the entire element, including the tag and length. -// The |ASN1_STRING|'s |type| field matches the containing |ASN1_TYPE|'s |type|. +// SEQUENCE, SET, or some arbitrary tag, respectively. |value| uses the +// corresponding |ASN1_STRING| representation. Although any type may be +// represented in |V_ASN1_OTHER|, the parser will always return the more +// specific encoding when available. // -// Other positive values of |type|, up to |V_ASN1_MAX_UNIVERSAL|, correspond to -// universal primitive tags not directly supported by this library. |value| is -// an |ASN1_STRING| containing the body of the element, excluding the tag -// and length. The |ASN1_STRING|'s |type| field matches the containing -// |ASN1_TYPE|'s |type|. +// Other values of |type| do not represent a valid ASN.1 value, though +// default-constructed objects may set |type| to -1. Such objects cannot be +// serialized. struct asn1_type_st { int type; union { @@ -1517,10 +1529,10 @@ OPENSSL_EXPORT ASN1_TYPE *ASN1_TYPE_new(void); OPENSSL_EXPORT void ASN1_TYPE_free(ASN1_TYPE *a); // d2i_ASN1_TYPE parses up to |len| bytes from |*inp| as an ASN.1 value of any -// type, as described in |d2i_SAMPLE_with_reuse|. Note this function only -// validates primitive, universal types supported by this library. Values of -// type |V_ASN1_SEQUENCE|, |V_ASN1_SET|, |V_ASN1_OTHER|, or an unsupported -// primitive type must be validated by the caller when interpreting. +// type, as described in |d2i_SAMPLE|. Note this function only validates +// primitive, universal types supported by this library. Values of type +// |V_ASN1_SEQUENCE|, |V_ASN1_SET|, |V_ASN1_OTHER|, or an unsupported primitive +// type must be validated by the caller when interpreting. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1564,9 +1576,9 @@ OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; // d2i_ASN1_SEQUENCE_ANY parses up to |len| bytes from |*inp| as a DER-encoded -// ASN.1 SEQUENCE OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The -// resulting |ASN1_SEQUENCE_ANY| owns its contents and thus must be released -// with |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. +// ASN.1 SEQUENCE OF ANY structure, as described in |d2i_SAMPLE|. The resulting +// |ASN1_SEQUENCE_ANY| owns its contents and thus must be released with +// |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. // // TODO(https://crbug.com/boringssl/354): This function currently also accepts // BER, but this will be removed in the future. @@ -1580,7 +1592,7 @@ OPENSSL_EXPORT int i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *in, uint8_t **outp); // d2i_ASN1_SET_ANY parses up to |len| bytes from |*inp| as a DER-encoded ASN.1 -// SET OF ANY structure, as described in |d2i_SAMPLE_with_reuse|. The resulting +// SET OF ANY structure, as described in |d2i_SAMPLE|. The resulting // |ASN1_SEQUENCE_ANY| owns its contents and thus must be released with // |sk_ASN1_TYPE_pop_free| and |ASN1_TYPE_free|, not |sk_ASN1_TYPE_free|. // @@ -1620,6 +1632,8 @@ OPENSSL_EXPORT int ASN1_TIME_print(BIO *out, const ASN1_TIME *a); // replaced with '.'. OPENSSL_EXPORT int ASN1_STRING_print(BIO *out, const ASN1_STRING *str); +// The following flags must not collide with |XN_FLAG_*|. + // ASN1_STRFLGS_ESC_2253 causes characters to be escaped as in RFC 2253, section // 2.4. #define ASN1_STRFLGS_ESC_2253 1 @@ -1727,13 +1741,11 @@ OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf, int buf_len, // |*out_length|, |*out_tag|, and |*out_class| to the element's length, tag // number, and tag class, respectively, // -// Unlike OpenSSL, this function does not support indefinite-length elements. +// Unlike OpenSSL, this function only supports DER. Indefinite and non-minimal +// lengths are rejected. // // This function is difficult to use correctly. Use |CBS_get_asn1| and related // functions from bytestring.h. -// -// TODO(https://crbug.com/boringssl/354): Remove support for non-minimal -// lengths. OPENSSL_EXPORT int ASN1_get_object(const unsigned char **inp, long *out_length, int *out_tag, int *out_class, long max_len); @@ -1809,15 +1821,6 @@ OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); // Deprecated functions. -// ASN1_PRINTABLE_type interprets |len| bytes from |s| as a Latin-1 string. It -// returns the first of |V_ASN1_PRINTABLESTRING|, |V_ASN1_IA5STRING|, or -// |V_ASN1_T61STRING| that can represent every character. If |len| is negative, -// |strlen(s)| is used instead. -// -// TODO(davidben): Remove this once all copies of Conscrypt have been updated -// past https://github.com/google/conscrypt/pull/1032. -OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int len); - // ASN1_STRING_set_default_mask does nothing. OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); @@ -1899,7 +1902,7 @@ OPENSSL_EXPORT void ASN1_PRINTABLE_free(ASN1_STRING *str); // d2i_ASN1_PRINTABLE parses up to |len| bytes from |*inp| as a DER-encoded // CHOICE of an ad-hoc subset of string-like types, as described in -// |d2i_SAMPLE_with_reuse|. +// |d2i_SAMPLE|. // // Do not use this. Despite, the name it has no connection to PrintableString or // printable characters. See https://crbug.com/boringssl/412. @@ -1922,6 +1925,32 @@ OPENSSL_EXPORT int i2d_ASN1_PRINTABLE(const ASN1_STRING *in, uint8_t **outp); // printable characters. See https://crbug.com/boringssl/412. DECLARE_ASN1_ITEM(ASN1_PRINTABLE) +// ASN1_INTEGER_set sets |a| to an INTEGER with value |v|. It returns one on +// success and zero on error. +// +// Use |ASN1_INTEGER_set_uint64| and |ASN1_INTEGER_set_int64| instead. +OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); + +// ASN1_ENUMERATED_set sets |a| to an ENUMERATED with value |v|. It returns one +// on success and zero on error. +// +// Use |ASN1_ENUMERATED_set_uint64| and |ASN1_ENUMERATED_set_int64| instead. +OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); + +// ASN1_INTEGER_get returns the value of |a| as a |long|, or -1 if |a| is out of +// range or the wrong type. +// +// WARNING: This function's return value cannot distinguish errors from -1. +// Use |ASN1_INTEGER_get_uint64| and |ASN1_INTEGER_get_int64| instead. +OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); + +// ASN1_ENUMERATED_get returns the value of |a| as a |long|, or -1 if |a| is out +// of range or the wrong type. +// +// WARNING: This function's return value cannot distinguish errors from -1. +// Use |ASN1_ENUMERATED_get_uint64| and |ASN1_ENUMERATED_get_int64| instead. +OPENSSL_EXPORT long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); + #if defined(__cplusplus) } // extern C @@ -2035,5 +2064,7 @@ BSSL_NAMESPACE_END #define ASN1_R_NESTED_TOO_DEEP 192 #define ASN1_R_BAD_TEMPLATE 193 #define ASN1_R_INVALID_BIT_STRING_PADDING 194 +#define ASN1_R_WRONG_INTEGER_TYPE 195 +#define ASN1_R_INVALID_INTEGER 196 -#endif +#endif // OPENSSL_HEADER_ASN1_H diff --git a/third_party/boringssl/kit/src/include/openssl/asn1t.h b/third_party/boringssl/kit/src/include/openssl/asn1t.h index dccbd1ac..7547b60a 100644 --- a/third_party/boringssl/kit/src/include/openssl/asn1t.h +++ b/third_party/boringssl/kit/src/include/openssl/asn1t.h @@ -54,13 +54,13 @@ * Hudson (tjh@cryptsoft.com). * */ -#ifndef HEADER_ASN1T_H -#define HEADER_ASN1T_H +#ifndef OPENSSL_HEADER_ASN1T_H +#define OPENSSL_HEADER_ASN1T_H #include #include -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif @@ -244,11 +244,6 @@ typedef struct ASN1_TLC_st ASN1_TLC; (flags), (tag), offsetof(stname, field),\ #field, ASN1_ITEM_ref(type) } -/* used when the structure is combined with the parent */ - -#define ASN1_EX_COMBINE(flags, tag, type) { \ - (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } - /* implicit and explicit helper macros */ #define ASN1_IMP_EX(stname, field, type, tag, ex) \ @@ -260,7 +255,6 @@ typedef struct ASN1_TLC_st ASN1_TLC; /* Any defined by macros: the field used is in the table itself */ #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } -#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } /* Plain simple type */ #define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) @@ -349,8 +343,8 @@ typedef struct ASN1_TLC_st ASN1_TLC; */ struct ASN1_TEMPLATE_st { -unsigned long flags; /* Various flags */ -long tag; /* tag, not used if no tagging */ +uint32_t flags; /* Various flags */ +int tag; /* tag, not used if no tagging */ unsigned long offset; /* Offset of this field in structure */ const char *field_name; /* Field name */ ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ @@ -367,7 +361,7 @@ typedef struct ASN1_ADB_st ASN1_ADB; typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL; struct ASN1_ADB_st { - unsigned long flags; /* Various flags */ + uint32_t flags; /* Various flags */ unsigned long offset; /* Offset of selector field */ ASN1_MUST_BE_NULL *unused; const ASN1_ADB_TABLE *tbl; /* Table of possible types */ @@ -377,7 +371,7 @@ struct ASN1_ADB_st { }; struct ASN1_ADB_TABLE_st { - long value; /* NID for an object or value for an int */ + int value; /* NID for an object */ const ASN1_TEMPLATE tt; /* item for this value */ }; @@ -442,23 +436,11 @@ struct ASN1_ADB_TABLE_st { #define ASN1_TFLG_ADB_OID (0x1<<8) -#define ASN1_TFLG_ADB_INT (0x1<<9) - -/* This flag means a parent structure is passed - * instead of the field: this is useful is a - * SEQUENCE is being combined with a CHOICE for - * example. Since this means the structure and - * item name will differ we need to use the - * ASN1_CHOICE_END_name() macro for example. - */ - -#define ASN1_TFLG_COMBINE (0x1<<10) - /* This is the actual ASN1 item itself */ struct ASN1_ITEM_st { char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ -long utype; /* underlying type */ +int utype; /* underlying type */ const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ long tcount; /* Number of templates if SEQUENCE or CHOICE */ const void *funcs; /* functions that handle this type */ @@ -512,48 +494,8 @@ const char *sname; /* Structure name */ #define ASN1_ITYPE_MSTRING 0x5 -/* Cache for ASN1 tag and length, so we - * don't keep re-reading it for things - * like CHOICE - */ - -struct ASN1_TLC_st{ - char valid; /* Values below are valid */ - int ret; /* return value */ - long plen; /* length */ - int ptag; /* class value */ - int pclass; /* class value */ - int hdrlen; /* header length */ -}; - -/* Typedefs for ASN1 function pointers */ - -typedef ASN1_VALUE * ASN1_new_func(void); -typedef void ASN1_free_func(ASN1_VALUE *a); -typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); -typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); - -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); - -typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); -typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); -typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); - -typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, - int indent, const char *fname, - const ASN1_PCTX *pctx); - -typedef struct ASN1_EXTERN_FUNCS_st { - void *app_data; - ASN1_ex_new_func *asn1_ex_new; - ASN1_ex_free_func *asn1_ex_free; - ASN1_ex_free_func *asn1_ex_clear; - ASN1_ex_d2i *asn1_ex_d2i; - ASN1_ex_i2d *asn1_ex_i2d; - /* asn1_ex_print is unused. */ - ASN1_ex_print_func *asn1_ex_print; -} ASN1_EXTERN_FUNCS; +/* Deprecated tag and length cache */ +struct ASN1_TLC_st; /* This is the ASN1_AUX structure: it handles various * miscellaneous requirements. For example the use of @@ -577,7 +519,7 @@ typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, typedef struct ASN1_AUX_st { void *app_data; - int flags; + uint32_t flags; int ref_offset; /* Offset of reference value */ ASN1_aux_cb *asn1_cb; int enc_offset; /* Offset of ASN1_ENCODING structure */ @@ -691,13 +633,17 @@ typedef struct ASN1_AUX_st { int i2d_##fname(const stname *a, unsigned char **out) \ { \ return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ - } + } -#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ - stname * stname##_dup(stname *x) \ - { \ - return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ - } +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname *stname##_dup(stname *x) { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +#define IMPLEMENT_ASN1_DUP_FUNCTION_const(stname) \ + stname *stname##_dup(const stname *x) { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), (void *)x); \ + } #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) @@ -712,7 +658,9 @@ DECLARE_ASN1_ITEM(ASN1_SEQUENCE) DEFINE_STACK_OF(ASN1_VALUE) -#ifdef __cplusplus -} -#endif + +#if defined(__cplusplus) +} // extern "C" #endif + +#endif // OPENSSL_HEADER_ASN1T_H diff --git a/third_party/boringssl/kit/src/include/openssl/base.h b/third_party/boringssl/kit/src/include/openssl/base.h index 983eadc5..2249aea6 100644 --- a/third_party/boringssl/kit/src/include/openssl/base.h +++ b/third_party/boringssl/kit/src/include/openssl/base.h @@ -96,9 +96,6 @@ extern "C" { #elif defined(__ARMEL__) || defined(_M_ARM) #define OPENSSL_32_BIT #define OPENSSL_ARM -#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN) -#define OPENSSL_64_BIT -#define OPENSSL_PPC64LE #elif defined(__MIPSEL__) && !defined(__LP64__) #define OPENSSL_32_BIT #define OPENSSL_MIPS @@ -107,6 +104,7 @@ extern "C" { #define OPENSSL_MIPS64 #elif defined(__riscv) && __SIZEOF_POINTER__ == 8 #define OPENSSL_64_BIT +#define OPENSSL_RISCV64 #elif defined(__riscv) && __SIZEOF_POINTER__ == 4 #define OPENSSL_32_BIT #elif defined(__pnacl__) @@ -166,6 +164,10 @@ extern "C" { #define OPENSSL_FREEBSD #endif +#if defined(__OpenBSD__) +#define OPENSSL_OPENBSD +#endif + // BoringSSL requires platform's locking APIs to make internal global state // thread-safe, including the PRNG. On some single-threaded embedded platforms, // locking APIs may not exist, so this dependency may be disabled with the @@ -195,7 +197,7 @@ extern "C" { // A consumer may use this symbol in the preprocessor to temporarily build // against multiple revisions of BoringSSL at the same time. It is not // recommended to do so for longer than is necessary. -#define BORINGSSL_API_VERSION 16 +#define BORINGSSL_API_VERSION 23 #if defined(BORINGSSL_SHARED_LIBRARY) @@ -223,6 +225,33 @@ extern "C" { #endif // defined(BORINGSSL_SHARED_LIBRARY) +#if defined(_MSC_VER) + +// OPENSSL_DEPRECATED is used to mark a function as deprecated. Use +// of any functions so marked in caller code will produce a warning. +// OPENSSL_BEGIN_ALLOW_DEPRECATED and OPENSSL_END_ALLOW_DEPRECATED +// can be used to suppress the warning in regions of caller code. +#define OPENSSL_DEPRECATED __declspec(deprecated) +#define OPENSSL_BEGIN_ALLOW_DEPRECATED \ + __pragma(warning(push)) __pragma(warning(disable : 4996)) +#define OPENSSL_END_ALLOW_DEPRECATED __pragma(warning(pop)) + +#elif defined(__GNUC__) || defined(__clang__) + +#define OPENSSL_DEPRECATED __attribute__((__deprecated__)) +#define OPENSSL_BEGIN_ALLOW_DEPRECATED \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#define OPENSSL_END_ALLOW_DEPRECATED _Pragma("GCC diagnostic pop") + +#else + +#define OPENSSL_DEPRECATED +#define OPENSSL_BEGIN_ALLOW_DEPRECATED +#define OPENSSL_END_ALLOW_DEPRECATED + +#endif + #if defined(__GNUC__) || defined(__clang__) // MinGW has two different printf implementations. Ensure the format macro @@ -325,6 +354,19 @@ enum ssl_verify_result_t BORINGSSL_ENUM_INT; #define BORINGSSL_ENUM_INT #endif +// ossl_ssize_t is a signed type which is large enough to fit the size of any +// valid memory allocation. We prefer using |size_t|, but sometimes we need a +// signed type for OpenSSL API compatibility. This type can be used in such +// cases to avoid overflow. +// +// Not all |size_t| values fit in |ossl_ssize_t|, but all |size_t| values that +// are sizes of or indices into C objects, can be converted without overflow. +typedef ptrdiff_t ossl_ssize_t; + +// CBS_ASN1_TAG is the type used by |CBS| and |CBB| for ASN.1 tags. See that +// header for details. This type is defined in base.h as a forward declaration. +typedef uint32_t CBS_ASN1_TAG; + // CRYPTO_THREADID is a dummy value. typedef int CRYPTO_THREADID; @@ -362,10 +404,6 @@ typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; typedef struct Netscape_spkac_st NETSCAPE_SPKAC; typedef struct Netscape_spki_st NETSCAPE_SPKI; typedef struct RIPEMD160state_st RIPEMD160_CTX; -typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; -typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; -typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; -typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; typedef struct X509_algor_st X509_ALGOR; typedef struct X509_crl_st X509_CRL; @@ -391,6 +429,7 @@ typedef struct conf_st CONF; typedef struct conf_value_st CONF_VALUE; typedef struct crypto_buffer_pool_st CRYPTO_BUFFER_POOL; typedef struct crypto_buffer_st CRYPTO_BUFFER; +typedef struct ctr_drbg_state_st CTR_DRBG_STATE; typedef struct dh_st DH; typedef struct dsa_st DSA; typedef struct ec_group_st EC_GROUP; @@ -402,6 +441,7 @@ typedef struct engine_st ENGINE; typedef struct env_md_ctx_st EVP_MD_CTX; typedef struct env_md_st EVP_MD; typedef struct evp_aead_st EVP_AEAD; +typedef struct evp_aead_ctx_st EVP_AEAD_CTX; typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; typedef struct evp_cipher_st EVP_CIPHER; typedef struct evp_encode_ctx_st EVP_ENCODE_CTX; @@ -410,9 +450,7 @@ typedef struct evp_hpke_ctx_st EVP_HPKE_CTX; typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; typedef struct evp_hpke_kem_st EVP_HPKE_KEM; typedef struct evp_hpke_key_st EVP_HPKE_KEY; -typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; -typedef struct evp_pkey_method_st EVP_PKEY_METHOD; typedef struct evp_pkey_st EVP_PKEY; typedef struct hmac_ctx_st HMAC_CTX; typedef struct md4_state_st MD4_CTX; @@ -448,8 +486,6 @@ typedef struct trust_token_issuer_st TRUST_TOKEN_ISSUER; typedef struct trust_token_method_st TRUST_TOKEN_METHOD; typedef struct v3_ext_ctx X509V3_CTX; typedef struct x509_attributes_st X509_ATTRIBUTE; -typedef struct x509_cert_aux_st X509_CERT_AUX; -typedef struct x509_crl_method_st X509_CRL_METHOD; typedef struct x509_lookup_st X509_LOOKUP; typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; typedef struct x509_object_st X509_OBJECT; @@ -519,8 +555,8 @@ namespace internal { template struct DeleterImpl {}; -template struct Deleter { + template void operator()(T *ptr) { // Rather than specialize Deleter for each type, we specialize // DeleterImpl. This allows bssl::UniquePtr to be used while only @@ -604,7 +640,7 @@ class StackAllocatedMovable { // bssl::UniquePtr rsa(RSA_new()); // bssl::UniquePtr bio(BIO_new(BIO_s_mem())); template -using UniquePtr = std::unique_ptr>; +using UniquePtr = std::unique_ptr; #define BORINGSSL_MAKE_UP_REF(type, up_ref_func) \ inline UniquePtr UpRef(type *v) { \ diff --git a/third_party/boringssl/kit/src/include/openssl/bio.h b/third_party/boringssl/kit/src/include/openssl/bio.h index 18bc893f..707a4b15 100644 --- a/third_party/boringssl/kit/src/include/openssl/bio.h +++ b/third_party/boringssl/kit/src/include/openssl/bio.h @@ -107,14 +107,14 @@ OPENSSL_EXPORT int BIO_up_ref(BIO *bio); // bytes read, zero on EOF, or a negative number on error. OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); -// BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|. -// It returns the number of bytes read or a negative number on error. The -// phrase "reads a line" is in quotes in the previous sentence because the -// exact operation depends on the BIO's method. For example, a digest BIO will -// return the digest in response to a |BIO_gets| call. +// BIO_gets reads a line from |bio| and writes at most |size| bytes into |buf|. +// It returns the number of bytes read or a negative number on error. This +// function's output always includes a trailing NUL byte, so it will read at +// most |size - 1| bytes. // -// TODO(fork): audit the set of BIOs that we end up needing. If all actually -// return a line for this call, remove the warning above. +// If the function read a complete line, the output will include the newline +// character, '\n'. If no newline was found before |size - 1| bytes or EOF, it +// outputs the bytes which were available. OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); // BIO_write writes |len| bytes from |data| to |bio|. It returns the number of @@ -328,7 +328,7 @@ OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); // BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented -// by |indent| spaces. +// by |indent| spaces. It returns one on success and zero otherwise. OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent); @@ -383,7 +383,7 @@ OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void); // // If |len| is negative, then |buf| is treated as a NUL-terminated string, but // don't depend on this in new code. -OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len); +OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, ossl_ssize_t len); // BIO_mem_contents sets |*out_contents| to point to the current contents of // |bio| and |*out_len| to contain the length of that data. It returns one on @@ -508,6 +508,25 @@ OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename); // |FILE| will be closed when |bio| is freed. OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename); +// BIO_tell returns the file offset of |bio|, or a negative number on error or +// if |bio| does not support the operation. +// +// TODO(https://crbug.com/boringssl/465): On platforms where |long| is 32-bit, +// this function cannot report 64-bit offsets. +OPENSSL_EXPORT long BIO_tell(BIO *bio); + +// BIO_seek sets the file offset of |bio| to |offset|. It returns a non-negative +// number on success and a negative number on error. If |bio| is a file +// descriptor |BIO|, it returns the resulting file offset on success. If |bio| +// is a file |BIO|, it returns zero on success. +// +// WARNING: This function's return value conventions differs from most functions +// in this library. +// +// TODO(https://crbug.com/boringssl/465): On platforms where |long| is 32-bit, +// this function cannot handle 64-bit offsets. +OPENSSL_EXPORT long BIO_seek(BIO *bio, long offset); + // Socket BIOs. // @@ -854,7 +873,6 @@ struct bio_st { #define BIO_C_GET_FILE_PTR 107 #define BIO_C_SET_FILENAME 108 #define BIO_C_SET_SSL 109 -#define BIO_C_GET_SSL 110 #define BIO_C_SET_MD 111 #define BIO_C_GET_MD 112 #define BIO_C_GET_CIPHER_STATUS 113 @@ -868,9 +886,6 @@ struct bio_st { #define BIO_C_GET_PROXY_PARAM 121 #define BIO_C_SET_BUFF_READ_DATA 122 // data to read first #define BIO_C_GET_ACCEPT 124 -#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 -#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 -#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 #define BIO_C_FILE_SEEK 128 #define BIO_C_GET_CIPHER_CTX 129 #define BIO_C_SET_BUF_MEM_EOF_RETURN 130 // return end of input value diff --git a/third_party/boringssl/kit/src/include/openssl/blake2.h b/third_party/boringssl/kit/src/include/openssl/blake2.h index 9ec1e6c6..03e3a465 100644 --- a/third_party/boringssl/kit/src/include/openssl/blake2.h +++ b/third_party/boringssl/kit/src/include/openssl/blake2.h @@ -28,10 +28,7 @@ extern "C" { struct blake2b_state_st { uint64_t h[8]; uint64_t t_low, t_high; - union { - uint8_t bytes[BLAKE2B_CBLOCK]; - uint64_t words[16]; - } block; + uint8_t block[BLAKE2B_CBLOCK]; size_t block_used; }; diff --git a/third_party/boringssl/kit/src/include/openssl/bn.h b/third_party/boringssl/kit/src/include/openssl/bn.h index 2b4d0639..0361645a 100644 --- a/third_party/boringssl/kit/src/include/openssl/bn.h +++ b/third_party/boringssl/kit/src/include/openssl/bn.h @@ -136,7 +136,16 @@ extern "C" { // BN provides support for working with arbitrary sized integers. For example, // although the largest integer supported by the compiler might be 64 bits, BN -// will allow you to work with numbers until you run out of memory. +// will allow you to work with much larger numbers. +// +// This library is developed for use inside BoringSSL, and uses implementation +// strategies that may not be ideal for other applications. Non-cryptographic +// uses should use a more general-purpose integer library, especially if +// performance-sensitive. +// +// Many functions in BN scale quadratically or higher in the bit length of their +// input. Callers at this layer are assumed to have capped input sizes within +// their performance tolerances. // BN_ULONG is the native word size when working with big integers. @@ -148,17 +157,15 @@ extern "C" { // Projects which use |BN_*_FMT*| with outdated C headers may need to define it // externally. #if defined(OPENSSL_64_BIT) -#define BN_ULONG uint64_t +typedef uint64_t BN_ULONG; #define BN_BITS2 64 #define BN_DEC_FMT1 "%" PRIu64 -#define BN_DEC_FMT2 "%019" PRIu64 #define BN_HEX_FMT1 "%" PRIx64 #define BN_HEX_FMT2 "%016" PRIx64 #elif defined(OPENSSL_32_BIT) -#define BN_ULONG uint32_t +typedef uint32_t BN_ULONG; #define BN_BITS2 32 #define BN_DEC_FMT1 "%" PRIu32 -#define BN_DEC_FMT2 "%09" PRIu32 #define BN_HEX_FMT1 "%" PRIx32 #define BN_HEX_FMT2 "%08" PRIx32 #else @@ -205,6 +212,10 @@ OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn); // BN_num_bytes returns the minimum number of bytes needed to represent the // absolute value of |bn|. +// +// While |size_t| is the preferred type for byte counts, callers can assume that +// |BIGNUM|s are bounded such that this value, and its corresponding bit count, +// will always fit in |int|. OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn); // BN_zero sets |bn| to zero. @@ -280,6 +291,10 @@ OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in); // BN_bn2dec returns an allocated string that contains a NUL-terminated, // decimal representation of |bn|. If |bn| is negative, the first char in the // resulting string will be '-'. Returns NULL on allocation failure. +// +// Converting an arbitrarily large integer to decimal is quadratic in the bit +// length of |a|. This function assumes the caller has capped the input within +// performance tolerances. OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); // BN_dec2bn parses the leading decimal number from |in|, which may be @@ -288,6 +303,10 @@ OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); // decimal number and stores it in |*outp|. If |*outp| is NULL then it // allocates a new BIGNUM and updates |*outp|. It returns the number of bytes // of |in| processed or zero on error. +// +// Converting an arbitrarily large integer to decimal is quadratic in the bit +// length of |a|. This function assumes the caller has capped the input within +// performance tolerances. OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in); // BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in| @@ -584,9 +603,14 @@ OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); // BN_mod_sqrt returns a newly-allocated |BIGNUM|, r, such that -// r^2 == a (mod p). |p| must be a prime. It returns NULL on error or if |a| is -// not a square mod |p|. In the latter case, it will add |BN_R_NOT_A_SQUARE| to -// the error queue. +// r^2 == a (mod p). It returns NULL on error or if |a| is not a square mod |p|. +// In the latter case, it will add |BN_R_NOT_A_SQUARE| to the error queue. +// If |a| is a square and |p| > 2, there are two possible square roots. This +// function may return either and may even select one non-deterministically. +// +// This function only works if |p| is a prime. If |p| is composite, it may fail +// or return an arbitrary value. Callers should not pass attacker-controlled +// values of |p|. OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); @@ -676,6 +700,9 @@ OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback, // the callback, or 1 if |callback| is NULL. OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n); +// BN_GENCB_get_arg returns |callback->arg|. +OPENSSL_EXPORT void *BN_GENCB_get_arg(const BN_GENCB *callback); + // BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe // is non-zero then the prime will be such that (ret-1)/2 is also a prime. // (This is needed for Diffie-Hellman groups to ensure that the only subgroups @@ -805,8 +832,9 @@ OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, // Note this function may incorrectly report |a| has no inverse if the random // blinding value has no inverse. It should only be used when |n| has few // non-invertible elements, such as an RSA modulus. -int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, - const BN_MONT_CTX *mont, BN_CTX *ctx); +OPENSSL_EXPORT int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, + const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); // BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be // non-negative and must be less than |n|. |n| must be odd. This function @@ -844,15 +872,6 @@ OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont); OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from); -// BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If -// so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It -// then stores it as |*pmont|. It returns one on success and zero on error. Note -// this function assumes |mod| is public. -// -// If |*pmont| is already non-NULL then it does nothing and returns one. -int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, - const BIGNUM *mod, BN_CTX *bn_ctx); - // BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. |a| is // assumed to be in the range [0, n), where |n| is the Montgomery modulus. It // returns one on success or zero on error. @@ -959,6 +978,9 @@ OPENSSL_EXPORT int BN_bn2binpad(const BIGNUM *in, uint8_t *out, int len); // conservative.) #define BN_prime_checks BN_prime_checks_for_validation +// BN_secure_new calls |BN_new|. +OPENSSL_EXPORT BIGNUM *BN_secure_new(void); + // Private functions diff --git a/third_party/boringssl/kit/src/include/openssl/bytestring.h b/third_party/boringssl/kit/src/include/openssl/bytestring.h index 5ef37420..33e13ef8 100644 --- a/third_party/boringssl/kit/src/include/openssl/bytestring.h +++ b/third_party/boringssl/kit/src/include/openssl/bytestring.h @@ -18,6 +18,7 @@ #include #include +#include #if defined(__cplusplus) extern "C" { @@ -159,6 +160,13 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); // one. Otherwise, it returns zero and leaves |cbs| unmodified. OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); +// CBS_get_u64_decimal reads a decimal integer from |cbs| and writes it to +// |*out|. It stops reading at the end of the string, or the first non-digit +// character. It returns one on success and zero on error. This function behaves +// analogously to |strtoul| except it does not accept empty inputs, leading +// zeros, or negative values. +OPENSSL_EXPORT int CBS_get_u64_decimal(CBS *cbs, uint64_t *out); + // Parsing ASN.1 // @@ -168,8 +176,8 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); // SEQUENCE, branching on CHOICEs or OPTIONAL fields, checking for trailing // data, and handling explict vs. implicit tagging. // -// Tags are represented as |unsigned| values in memory. The upper few bits store -// the class and constructed bit, and the remaining bits store the tag +// Tags are represented as |CBS_ASN1_TAG| values in memory. The upper few bits +// store the class and constructed bit, and the remaining bits store the tag // number. Note this differs from the DER serialization, to support tag numbers // beyond 31. Consumers must use the constants defined below to decompose or // assemble tags. @@ -230,44 +238,52 @@ OPENSSL_EXPORT int CBS_get_until_first(CBS *cbs, CBS *out, uint8_t c); // including tag and length bytes) and advances |cbs| over it. The ASN.1 // element must match |tag_value|. It returns one on success and zero // on error. -OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); +OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, CBS_ASN1_TAG tag_value); // CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the // ASN.1 header bytes too. -OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); +OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, + CBS_ASN1_TAG tag_value); // CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one // if the next ASN.1 element on |cbs| would have tag |tag_value|. If // |cbs| is empty or the tag does not match, it returns zero. Note: if // it returns one, CBS_get_asn1 may still fail if the rest of the // element is malformed. -OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); +OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, CBS_ASN1_TAG tag_value); // CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs| // (not including tag and length bytes), sets |*out_tag| to the tag number, and // advances |*cbs|. It returns one on success and zero on error. Either of |out| // and |out_tag| may be NULL to ignore the value. -OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag); +OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, + CBS_ASN1_TAG *out_tag); // CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from // |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to // the tag number and |*out_header_len| to the length of the ASN.1 header. Each // of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value. OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, - unsigned *out_tag, + CBS_ASN1_TAG *out_tag, size_t *out_header_len); // CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but // also allows indefinite-length elements to be returned and does not enforce -// that lengths are minimal. For indefinite-lengths, |*out_header_len| and +// that lengths are minimal. It sets |*out_indefinite| to one if the length was +// indefinite and zero otherwise. If indefinite, |*out_header_len| and // |CBS_len(out)| will be equal as only the header is returned (although this is -// also true for empty elements so the length must be checked too). If +// also true for empty elements so |*out_indefinite| should be checked). If // |out_ber_found| is not NULL then it is set to one if any case of invalid DER // but valid BER is found, and to zero otherwise. +// +// This function will not successfully parse an end-of-contents (EOC) as an +// element. Callers parsing indefinite-length encoding must check for EOC +// separately. OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, - unsigned *out_tag, + CBS_ASN1_TAG *out_tag, size_t *out_header_len, - int *out_ber_found); + int *out_ber_found, + int *out_indefinite); // CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| // and sets |*out| to its value. It returns one on success and zero on error, @@ -290,7 +306,7 @@ OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out); // one, otherwise zero. It returns one on success, whether or not the element // was present, and zero on decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, - unsigned tag); + CBS_ASN1_TAG tag); // CBS_get_optional_asn1_octet_string gets an optional // explicitly-tagged OCTET STRING from |cbs|. If present, it sets @@ -300,7 +316,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, // present, and zero on decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, - unsigned tag); + CBS_ASN1_TAG tag); // CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged // INTEGER from |cbs|. If present, it sets |*out| to the @@ -308,7 +324,7 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, // on success, whether or not the element was present, and zero on // decode failure. OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, - unsigned tag, + CBS_ASN1_TAG tag, uint64_t default_value); // CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from @@ -316,7 +332,8 @@ OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, // boolean. Otherwise, it sets |*out| to |default_value|. It returns one on // success, whether or not the element was present, and zero on decode // failure. -OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, +OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, + CBS_ASN1_TAG tag, int default_value); // CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING @@ -339,14 +356,42 @@ OPENSSL_EXPORT int CBS_is_valid_asn1_integer(const CBS *cbs, // ASN.1 INTEGER body and zero otherwise. OPENSSL_EXPORT int CBS_is_unsigned_asn1_integer(const CBS *cbs); +// CBS_is_valid_asn1_oid returns one if |cbs| is a valid DER-encoded ASN.1 +// OBJECT IDENTIFIER contents (not including the element framing) and zero +// otherwise. This function tolerates arbitrarily large OID components. +OPENSSL_EXPORT int CBS_is_valid_asn1_oid(const CBS *cbs); + // CBS_asn1_oid_to_text interprets |cbs| as DER-encoded ASN.1 OBJECT IDENTIFIER // contents (not including the element framing) and returns the ASCII // representation (e.g., "1.2.840.113554.4.1.72585") in a newly-allocated // string, or NULL on failure. The caller must release the result with // |OPENSSL_free|. +// +// This function may fail if |cbs| is an invalid OBJECT IDENTIFIER, or if any +// OID components are too large. OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); +// CBS_parse_generalized_time returns one if |cbs| is a valid DER-encoded, ASN.1 +// GeneralizedTime body within the limitations imposed by RFC 5280, or zero +// otherwise. If |allow_timezone_offset| is non-zero, four-digit timezone +// offsets, which would not be allowed by DER, are permitted. On success, if +// |out_tm| is non-NULL, |*out_tm| will be zeroed, and then set to the +// corresponding time in UTC. This function does not compute |out_tm->tm_wday| +// or |out_tm->tm_yday|. +OPENSSL_EXPORT int CBS_parse_generalized_time(const CBS *cbs, struct tm *out_tm, + int allow_timezone_offset); + +// CBS_parse_utc_time returns one if |cbs| is a valid DER-encoded, ASN.1 +// UTCTime body within the limitations imposed by RFC 5280, or zero otherwise. +// If |allow_timezone_offset| is non-zero, four-digit timezone offsets, which +// would not be allowed by DER, are permitted. On success, if |out_tm| is +// non-NULL, |*out_tm| will be zeroed, and then set to the corresponding time +// in UTC. This function does not compute |out_tm->tm_wday| or +// |out_tm->tm_yday|. +OPENSSL_EXPORT int CBS_parse_utc_time(const CBS *cbs, struct tm *out_tm, + int allow_timezone_offset); + // CRYPTO ByteBuilder. // // |CBB| objects allow one to build length-prefixed serialisations. A |CBB| @@ -364,28 +409,40 @@ OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); struct cbb_buffer_st { uint8_t *buf; - size_t len; // The number of valid bytes. - size_t cap; // The size of buf. - char can_resize; /* One iff |buf| is owned by this object. If not then |buf| - cannot be resized. */ - char error; /* One iff there was an error writing to this CBB. All future - operations will fail. */ + // len is the number of valid bytes in |buf|. + size_t len; + // cap is the size of |buf|. + size_t cap; + // can_resize is one iff |buf| is owned by this object. If not then |buf| + // cannot be resized. + unsigned can_resize : 1; + // error is one if there was an error writing to this CBB. All future + // operations will fail. + unsigned error : 1; }; -struct cbb_st { +struct cbb_child_st { + // base is a pointer to the buffer this |CBB| writes to. struct cbb_buffer_st *base; - // child points to a child CBB if a length-prefix is pending. - CBB *child; // offset is the number of bytes from the start of |base->buf| to this |CBB|'s // pending length prefix. size_t offset; // pending_len_len contains the number of bytes in this |CBB|'s pending // length-prefix, or zero if no length-prefix is pending. uint8_t pending_len_len; - char pending_is_asn1; - // is_child is true iff this is a child |CBB| (as opposed to a top-level - // |CBB|). Top-level objects are valid arguments for |CBB_finish|. + unsigned pending_is_asn1 : 1; +}; + +struct cbb_st { + // child points to a child CBB if a length-prefix is pending. + CBB *child; + // is_child is one if this is a child |CBB| and zero if it is a top-level + // |CBB|. This determines which arm of the union is valid. char is_child; + union { + struct cbb_buffer_st base; + struct cbb_child_st child; + } u; }; // CBB_zero sets an uninitialised |cbb| to the zero state. It must be @@ -401,7 +458,8 @@ OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity); // CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since // |buf| cannot grow, trying to write more than |len| bytes will cause CBB -// functions to fail. It returns one on success or zero on error. +// functions to fail. This function is infallible and always returns one. It is +// safe, but not necessary, to call |CBB_cleanup| on |cbb|. OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); // CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects @@ -462,7 +520,7 @@ OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); // CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an // ASN.1 object can be written. The |tag| argument will be used as the tag for // the object. It returns one on success or zero on error. -OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag); +OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, CBS_ASN1_TAG tag); // CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on // success and zero otherwise. @@ -530,11 +588,23 @@ OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); // error. OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); +// CBB_add_asn1_uint64_with_tag behaves like |CBB_add_asn1_uint64| but uses +// |tag| as the tag instead of INTEGER. This is useful if the INTEGER type uses +// implicit tagging. +OPENSSL_EXPORT int CBB_add_asn1_uint64_with_tag(CBB *cbb, uint64_t value, + CBS_ASN1_TAG tag); + // CBB_add_asn1_int64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| // and writes |value| in its contents. It returns one on success and zero on // error. OPENSSL_EXPORT int CBB_add_asn1_int64(CBB *cbb, int64_t value); +// CBB_add_asn1_int64_with_tag behaves like |CBB_add_asn1_int64| but uses |tag| +// as the tag instead of INTEGER. This is useful if the INTEGER type uses +// implicit tagging. +OPENSSL_EXPORT int CBB_add_asn1_int64_with_tag(CBB *cbb, int64_t value, + CBS_ASN1_TAG tag); + // CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the // given contents. It returns one on success and zero on error. OPENSSL_EXPORT int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, diff --git a/third_party/boringssl/kit/src/include/openssl/chacha.h b/third_party/boringssl/kit/src/include/openssl/chacha.h index cfbaa756..2868c290 100644 --- a/third_party/boringssl/kit/src/include/openssl/chacha.h +++ b/third_party/boringssl/kit/src/include/openssl/chacha.h @@ -29,6 +29,12 @@ extern "C" { // CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and // nonce and writes the result to |out|. If |in| and |out| alias, they must be // equal. The initial block counter is specified by |counter|. +// +// This function implements a 32-bit block counter as in RFC 8439. On overflow, +// the counter wraps. Reusing a key, nonce, and block counter combination is not +// secure, so wrapping is usually a bug in the caller. While it is possible to +// wrap without reuse with a large initial block counter, this is not +// recommended and may not be portable to other ChaCha20 implementations. OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter); diff --git a/third_party/boringssl/kit/src/include/openssl/cipher.h b/third_party/boringssl/kit/src/include/openssl/cipher.h index 2458847e..310d7c23 100644 --- a/third_party/boringssl/kit/src/include/openssl/cipher.h +++ b/third_party/boringssl/kit/src/include/openssl/cipher.h @@ -174,6 +174,11 @@ OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, // of output bytes may be up to |in_len| plus the block length minus one and // |out| must have sufficient space. The number of bytes actually output is // written to |*out_len|. It returns one on success and zero otherwise. +// +// If |ctx| is an AEAD cipher, e.g. |EVP_aes_128_gcm|, and |out| is NULL, this +// function instead adds |in_len| bytes from |in| to the AAD and sets |*out_len| +// to |in_len|. The AAD must be fully specified in this way before this function +// is used to encrypt plaintext. OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len); @@ -191,6 +196,11 @@ OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, // output bytes may be up to |in_len| plus the block length minus one and |out| // must have sufficient space. The number of bytes actually output is written // to |*out_len|. It returns one on success and zero otherwise. +// +// If |ctx| is an AEAD cipher, e.g. |EVP_aes_128_gcm|, and |out| is NULL, this +// function instead adds |in_len| bytes from |in| to the AAD and sets |*out_len| +// to |in_len|. The AAD must be fully specified in this way before this function +// is used to decrypt ciphertext. OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len); @@ -204,24 +214,6 @@ OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len); -// EVP_Cipher performs a one-shot encryption/decryption operation. No partial -// blocks are maintained between calls. However, any internal cipher state is -// still updated. For CBC-mode ciphers, the IV is updated to the final -// ciphertext block. For stream ciphers, the stream is advanced past the bytes -// used. It returns one on success and zero otherwise, unless |EVP_CIPHER_flags| -// has |EVP_CIPH_FLAG_CUSTOM_CIPHER| set. Then it returns the number of bytes -// written or -1 on error. -// -// WARNING: this differs from the usual return value convention when using -// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. -// -// TODO(davidben): The normal ciphers currently never fail, even if, e.g., -// |in_len| is not a multiple of the block size for CBC-mode decryption. The -// input just gets rounded up while the output gets truncated. This should -// either be officially documented or fail. -OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, - const uint8_t *in, size_t in_len); - // EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate| // depending on how |ctx| has been setup. OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, @@ -349,6 +341,12 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, #define EVP_CIPH_GCM_MODE 0x6 #define EVP_CIPH_XTS_MODE 0x7 +// The following values are never returned from |EVP_CIPHER_mode| and are +// included only to make it easier to compile code with BoringSSL. +#define EVP_CIPH_CCM_MODE 0x8 +#define EVP_CIPH_OCB_MODE 0x9 +#define EVP_CIPH_WRAP_MODE 0xa + // Cipher flags (for |EVP_CIPHER_flags|). @@ -420,6 +418,30 @@ OPENSSL_EXPORT int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, OPENSSL_EXPORT int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len); +// EVP_Cipher historically exposed an internal implementation detail of |ctx| +// and should not be used. Use |EVP_CipherUpdate| and |EVP_CipherFinal_ex| +// instead. +// +// If |ctx|'s cipher does not have the |EVP_CIPH_FLAG_CUSTOM_CIPHER| flag, it +// encrypts or decrypts |in_len| bytes from |in| and writes the resulting +// |in_len| bytes to |out|. It returns one on success and zero on error. +// |in_len| must be a multiple of the cipher's block size, or the behavior is +// undefined. +// +// TODO(davidben): Rather than being undefined (it'll often round the length up +// and likely read past the buffer), just fail the operation. +// +// If |ctx|'s cipher has the |EVP_CIPH_FLAG_CUSTOM_CIPHER| flag, it runs in one +// of two modes: If |in| is non-NULL, it behaves like |EVP_CipherUpdate|. If +// |in| is NULL, it behaves like |EVP_CipherFinal_ex|. In both cases, it returns +// |*out_len| on success and -1 on error. +// +// WARNING: The two possible calling conventions of this function signal errors +// incompatibly. In the first, zero indicates an error. In the second, zero +// indicates success with zero bytes of output. +OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len); + // EVP_add_cipher_alias does nothing and returns one. OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); @@ -433,6 +455,12 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name); // These AEADs are deprecated AES-GCM implementations that set // |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and // |EVP_aead_aes_256_gcm| instead. +// +// WARNING: Although these APIs allow streaming an individual AES-GCM operation, +// this is not secure. Until calling |EVP_DecryptFinal_ex|, the tag has not yet +// been checked and output released by |EVP_DecryptUpdate| is unauthenticated +// and easily manipulated by attackers. Callers must buffer the output and may +// not act on it until the entire operation is complete. OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void); OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void); @@ -484,9 +512,6 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_cast5_cbc(void); // The following flags do nothing and are included only to make it easier to // compile code with BoringSSL. -#define EVP_CIPH_CCM_MODE (-1) -#define EVP_CIPH_OCB_MODE (-2) -#define EVP_CIPH_WRAP_MODE (-3) #define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 // EVP_CIPHER_CTX_set_flags does nothing. @@ -575,6 +600,9 @@ struct evp_cipher_ctx_st { int final_used; uint8_t final[EVP_MAX_BLOCK_LENGTH]; // possible final block + + // Has this structure been rendered unusable by a failure. + int poisoned; } /* EVP_CIPHER_CTX */; typedef struct evp_cipher_info_st { @@ -582,45 +610,6 @@ typedef struct evp_cipher_info_st { unsigned char iv[EVP_MAX_IV_LENGTH]; } EVP_CIPHER_INFO; -struct evp_cipher_st { - // type contains a NID identifing the cipher. (e.g. NID_aes_128_gcm.) - int nid; - - // block_size contains the block size, in bytes, of the cipher, or 1 for a - // stream cipher. - unsigned block_size; - - // key_len contains the key size, in bytes, for the cipher. If the cipher - // takes a variable key size then this contains the default size. - unsigned key_len; - - // iv_len contains the IV size, in bytes, or zero if inapplicable. - unsigned iv_len; - - // ctx_size contains the size, in bytes, of the per-key context for this - // cipher. - unsigned ctx_size; - - // flags contains the OR of a number of flags. See |EVP_CIPH_*|. - uint32_t flags; - - // app_data is a pointer to opaque, user data. - void *app_data; - - int (*init)(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, - int enc); - - int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, - size_t inl); - - // cleanup, if non-NULL, releases memory associated with the context. It is - // called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been - // called at this point. - void (*cleanup)(EVP_CIPHER_CTX *); - - int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); -}; - #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/conf.h b/third_party/boringssl/kit/src/include/openssl/conf.h index 6890c7d2..c9027c1d 100644 --- a/third_party/boringssl/kit/src/include/openssl/conf.h +++ b/third_party/boringssl/kit/src/include/openssl/conf.h @@ -77,7 +77,10 @@ extern "C" { // [section_name] // key2=value2 // -// Config files are represented by a |CONF|. +// Config files are represented by a |CONF|. Use of this module is strongly +// discouraged. It is a remnant of the OpenSSL command-line tool. Parsing an +// untrusted input as a config file risks string injection and denial of service +// vulnerabilities. struct conf_value_st { char *section; @@ -110,8 +113,8 @@ OPENSSL_EXPORT int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line); // NCONF_get_section returns a stack of values for a given section in |conf|. // If |section| is NULL, the default section is returned. It returns NULL on // error. -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, - const char *section); +OPENSSL_EXPORT const STACK_OF(CONF_VALUE) *NCONF_get_section( + const CONF *conf, const char *section); // NCONF_get_string returns the value of the key |name|, in section |section|. // The |section| argument may be NULL to indicate the default section. It @@ -121,19 +124,6 @@ OPENSSL_EXPORT const char *NCONF_get_string(const CONF *conf, const char *name); -// Utility functions - -// CONF_parse_list takes a list separated by 'sep' and calls |list_cb| giving -// the start and length of each member, optionally stripping leading and -// trailing whitespace. This can be used to parse comma separated lists for -// example. If |list_cb| returns <= 0, then the iteration is halted and that -// value is returned immediately. Otherwise it returns one. Note that |list_cb| -// may be called on an empty member. -int CONF_parse_list(const char *list, char sep, int remove_whitespace, - int (*list_cb)(const char *elem, int len, void *usr), - void *arg); - - // Deprecated functions // These defines do nothing but are provided to make old code easier to @@ -179,5 +169,6 @@ BSSL_NAMESPACE_END #define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 104 #define CONF_R_VARIABLE_HAS_NO_VALUE 105 #define CONF_R_VARIABLE_EXPANSION_TOO_LONG 106 +#define CONF_R_VARIABLE_EXPANSION_NOT_SUPPORTED 107 #endif // OPENSSL_HEADER_THREAD_H diff --git a/third_party/boringssl/kit/src/include/openssl/cpu.h b/third_party/boringssl/kit/src/include/openssl/cpu.h index 91cf95e1..d865020c 100644 --- a/third_party/boringssl/kit/src/include/openssl/cpu.h +++ b/third_party/boringssl/kit/src/include/openssl/cpu.h @@ -1,202 +1,18 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. +/* Copyright (c) 2014, Google Inc. * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef OPENSSL_HEADER_CPU_H -#define OPENSSL_HEADER_CPU_H +// This header is provided for compatibility with older revisions of BoringSSL. +// TODO(davidben): Remove this header. -#include - -#if defined(__cplusplus) -extern "C" { -#endif - - -// Runtime CPU feature support - - -#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) -// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or -// x86-64 system. -// -// Index 0: -// EDX for CPUID where EAX = 1 -// Bit 20 is always zero -// Bit 28 is adjusted to reflect whether the data cache is shared between -// multiple logical cores -// Bit 30 is used to indicate an Intel CPU -// Index 1: -// ECX for CPUID where EAX = 1 -// Bit 11 is used to indicate AMD XOP support, not SDBG -// Index 2: -// EBX for CPUID where EAX = 7 -// Index 3: -// ECX for CPUID where EAX = 7 -// -// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM -// bits in XCR0, so it is not necessary to check those. -extern uint32_t OPENSSL_ia32cap_P[4]; - -#if defined(BORINGSSL_FIPS) && !defined(BORINGSSL_SHARED_LIBRARY) -const uint32_t *OPENSSL_ia32cap_get(void); -#else -OPENSSL_INLINE const uint32_t *OPENSSL_ia32cap_get(void) { - return OPENSSL_ia32cap_P; -} -#endif - -#endif - -#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) - -#if defined(OPENSSL_APPLE) -// iOS builds use the static ARM configuration. -#define OPENSSL_STATIC_ARMCAP -#endif - -#if !defined(OPENSSL_STATIC_ARMCAP) -// CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON -// unit. Note that |OPENSSL_armcap_P| also exists and contains the same -// information in a form that's easier for assembly to use. -OPENSSL_EXPORT int CRYPTO_is_NEON_capable_at_runtime(void); - -// CRYPTO_is_ARMv8_AES_capable_at_runtime returns true if the current CPU -// supports the ARMv8 AES instruction. -int CRYPTO_is_ARMv8_AES_capable_at_runtime(void); - -// CRYPTO_is_ARMv8_PMULL_capable_at_runtime returns true if the current CPU -// supports the ARMv8 PMULL instruction. -int CRYPTO_is_ARMv8_PMULL_capable_at_runtime(void); - -#if defined(OPENSSL_ARM) -// CRYPTO_has_broken_NEON returns one if the current CPU is known to have a -// broken NEON unit. See https://crbug.com/341598. -OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); - -// CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 -// workaround was needed. See https://crbug.com/boringssl/46. -OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); -#endif -#endif // !OPENSSL_STATIC_ARMCAP - -// CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If -// this is known statically, it is a constant inline function. -OPENSSL_INLINE int CRYPTO_is_NEON_capable(void) { -#if defined(__ARM_NEON__) || defined(__ARM_NEON) || \ - defined(OPENSSL_STATIC_ARMCAP_NEON) - return 1; -#elif defined(OPENSSL_STATIC_ARMCAP) - return 0; -#else - return CRYPTO_is_NEON_capable_at_runtime(); -#endif -} - -OPENSSL_INLINE int CRYPTO_is_ARMv8_AES_capable(void) { -#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) - return 1; -#elif defined(OPENSSL_STATIC_ARMCAP) - return 0; -#else - return CRYPTO_is_ARMv8_AES_capable_at_runtime(); -#endif -} - -OPENSSL_INLINE int CRYPTO_is_ARMv8_PMULL_capable(void) { -#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) - return 1; -#elif defined(OPENSSL_STATIC_ARMCAP) - return 0; -#else - return CRYPTO_is_ARMv8_PMULL_capable_at_runtime(); -#endif -} - -#endif // OPENSSL_ARM || OPENSSL_AARCH64 - -#if defined(OPENSSL_PPC64LE) - -// CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports -// the Vector.AES category of instructions. -int CRYPTO_is_PPC64LE_vcrypto_capable(void); - -extern unsigned long OPENSSL_ppc64le_hwcap2; - -#endif // OPENSSL_PPC64LE - -#if defined(BORINGSSL_DISPATCH_TEST) -// Runtime CPU dispatch testing support - -// BORINGSSL_function_hit is an array of flags. The following functions will -// set these flags if BORINGSSL_DISPATCH_TEST is defined. -// 0: aes_hw_ctr32_encrypt_blocks -// 1: aes_hw_encrypt -// 2: aesni_gcm_encrypt -// 3: aes_hw_set_encrypt_key -// 4: vpaes_encrypt -// 5: vpaes_set_encrypt_key -extern uint8_t BORINGSSL_function_hit[7]; -#endif // BORINGSSL_DISPATCH_TEST - - -#if defined(__cplusplus) -} // extern C -#endif - -#endif // OPENSSL_HEADER_CPU_H +#include "crypto.h" diff --git a/third_party/boringssl/kit/src/include/openssl/crypto.h b/third_party/boringssl/kit/src/include/openssl/crypto.h index 93b1a9bb..171ac43f 100644 --- a/third_party/boringssl/kit/src/include/openssl/crypto.h +++ b/third_party/boringssl/kit/src/include/openssl/crypto.h @@ -59,6 +59,12 @@ OPENSSL_EXPORT int CRYPTO_has_asm(void); // success and zero on error. OPENSSL_EXPORT int BORINGSSL_self_test(void); +// BORINGSSL_integrity_test triggers the module's integrity test where the code +// and data of the module is matched against a hash injected at build time. It +// returns one on success or zero if there's a mismatch. This function only +// exists if the module was built in FIPS mode without ASAN. +OPENSSL_EXPORT int BORINGSSL_integrity_test(void); + // CRYPTO_pre_sandbox_init initializes the crypto library, pre-acquiring some // unusual resources to aid running in sandboxed environments. It is safe to // call this function multiple times and concurrently from multiple threads. @@ -67,6 +73,13 @@ OPENSSL_EXPORT int BORINGSSL_self_test(void); // SANDBOXING.md in the source tree. OPENSSL_EXPORT void CRYPTO_pre_sandbox_init(void); +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 +// workaround was needed. See https://crbug.com/boringssl/46. +OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); +#endif // OPENSSL_ARM && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP + // FIPS monitoring @@ -161,6 +174,27 @@ OPENSSL_EXPORT void OPENSSL_cleanup(void); // |BORINGSSL_FIPS| and zero otherwise. OPENSSL_EXPORT int FIPS_mode_set(int on); +// FIPS_module_name returns the name of the FIPS module. +OPENSSL_EXPORT const char *FIPS_module_name(void); + +// FIPS_version returns the version of the FIPS module, or zero if the build +// isn't exactly at a verified version. The version, expressed in base 10, will +// be a date in the form yyyymmddXX where XX is often "00", but can be +// incremented if multiple versions are defined on a single day. +// +// (This format exceeds a |uint32_t| in the year 4294.) +OPENSSL_EXPORT uint32_t FIPS_version(void); + +// FIPS_query_algorithm_status returns one if |algorithm| is FIPS validated in +// the current BoringSSL and zero otherwise. +OPENSSL_EXPORT int FIPS_query_algorithm_status(const char *algorithm); + +#if defined(OPENSSL_ARM) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) +// CRYPTO_has_broken_NEON returns zero. +OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); +#endif + #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/ctrdrbg.h b/third_party/boringssl/kit/src/include/openssl/ctrdrbg.h new file mode 100644 index 00000000..5440fb4d --- /dev/null +++ b/third_party/boringssl/kit/src/include/openssl/ctrdrbg.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CTRDRBG_H +#define OPENSSL_HEADER_CTRDRBG_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// FIPS pseudo-random number generator. + + +// CTR-DRBG state objects. +// +// CTR_DRBG_STATE contains the state of a FIPS AES-CTR-based pseudo-random +// number generator. If BoringSSL was built in FIPS mode then this is a FIPS +// Approved algorithm. + +// CTR_DRBG_ENTROPY_LEN is the number of bytes of input entropy. See SP +// 800-90Ar1, table 3. +#define CTR_DRBG_ENTROPY_LEN 48 + +// CTR_DRBG_MAX_GENERATE_LENGTH is the maximum number of bytes that can be +// generated in a single call to |CTR_DRBG_generate|. +#define CTR_DRBG_MAX_GENERATE_LENGTH 65536 + +// CTR_DRBG_new returns an initialized |CTR_DRBG_STATE|, or NULL if either +// allocation failed or if |personalization_len| is invalid. +OPENSSL_EXPORT CTR_DRBG_STATE *CTR_DRBG_new( + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, + size_t personalization_len); + +// CTR_DRBG_free frees |state| if non-NULL, or else does nothing. +OPENSSL_EXPORT void CTR_DRBG_free(CTR_DRBG_STATE* state); + +// CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy +// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// additional data. It returns one on success or zero on error. +OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional +// data (if any) and then writes |out_len| random bytes to |out|, where +// |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, + size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_clear zeroises the state of |drbg|. +OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { +BSSL_NAMESPACE_BEGIN +BORINGSSL_MAKE_DELETER(CTR_DRBG_STATE, CTR_DRBG_free) +BSSL_NAMESPACE_END +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_CTRDRBG_H diff --git a/third_party/boringssl/kit/src/include/openssl/dh.h b/third_party/boringssl/kit/src/include/openssl/dh.h index 21c96232..660627db 100644 --- a/third_party/boringssl/kit/src/include/openssl/dh.h +++ b/third_party/boringssl/kit/src/include/openssl/dh.h @@ -89,6 +89,9 @@ OPENSSL_EXPORT int DH_up_ref(DH *dh); // Properties. +// DH_bits returns the size of |dh|'s group modulus, in bits. +OPENSSL_EXPORT unsigned DH_bits(const DH *dh); + // DH_get0_pub_key returns |dh|'s public key. OPENSSL_EXPORT const BIGNUM *DH_get0_pub_key(const DH *dh); @@ -134,15 +137,40 @@ OPENSSL_EXPORT int DH_set_length(DH *dh, unsigned priv_length); // Standard parameters. +// DH_get_rfc7919_2048 returns the group `ffdhe2048` from +// https://tools.ietf.org/html/rfc7919#appendix-A.1. It returns NULL if out +// of memory. +OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void); + // BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated // and returned. It returns NULL on allocation failure. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); -// DH_get_rfc7919_2048 returns the group `ffdhe2048` from -// https://tools.ietf.org/html/rfc7919#appendix-A.1. It returns NULL if out -// of memory. -OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void); +// BN_get_rfc3526_prime_2048 sets |*ret| to the 2048-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret); + +// BN_get_rfc3526_prime_3072 sets |*ret| to the 3072-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret); + +// BN_get_rfc3526_prime_4096 sets |*ret| to the 4096-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret); + +// BN_get_rfc3526_prime_6144 sets |*ret| to the 6144-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret); + +// BN_get_rfc3526_prime_8192 sets |*ret| to the 8192-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret); // Parameter generation. @@ -216,7 +244,6 @@ OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); #define DH_CHECK_NOT_SUITABLE_GENERATOR 0x08 #define DH_CHECK_Q_NOT_PRIME 0x10 #define DH_CHECK_INVALID_Q_VALUE 0x20 -#define DH_CHECK_INVALID_J_VALUE 0x40 // These are compatibility defines. #define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR @@ -302,31 +329,6 @@ OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, DH *dh); -struct dh_st { - BIGNUM *p; - BIGNUM *g; - BIGNUM *pub_key; // g^x mod p - BIGNUM *priv_key; // x - - // priv_length contains the length, in bits, of the private value. If zero, - // the private value will be the same length as |p|. - unsigned priv_length; - - CRYPTO_MUTEX method_mont_p_lock; - BN_MONT_CTX *method_mont_p; - - // Place holders if we want to do X9.42 DH - BIGNUM *q; - BIGNUM *j; - unsigned char *seed; - int seedlen; - BIGNUM *counter; - - int flags; - CRYPTO_refcount_t references; -}; - - #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/digest.h b/third_party/boringssl/kit/src/include/openssl/digest.h index fa761689..6e889993 100644 --- a/third_party/boringssl/kit/src/include/openssl/digest.h +++ b/third_party/boringssl/kit/src/include/openssl/digest.h @@ -117,6 +117,13 @@ OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_new(void); // freshly initialised state. It does not free |ctx| itself. It returns one. OPENSSL_EXPORT int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +// EVP_MD_CTX_cleanse zeros the digest state in |ctx| and then performs the +// actions of |EVP_MD_CTX_cleanup|. Note that some |EVP_MD_CTX| objects contain +// more than just a digest (e.g. those resulting from |EVP_DigestSignInit|) but +// this function does not zero out more than just the digest state even in that +// case. +OPENSSL_EXPORT void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx); + // EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. OPENSSL_EXPORT void EVP_MD_CTX_free(EVP_MD_CTX *ctx); diff --git a/third_party/boringssl/kit/src/include/openssl/dsa.h b/third_party/boringssl/kit/src/include/openssl/dsa.h index e6ddce67..4075001a 100644 --- a/third_party/boringssl/kit/src/include/openssl/dsa.h +++ b/third_party/boringssl/kit/src/include/openssl/dsa.h @@ -62,9 +62,7 @@ #include -#include #include -#include #if defined(__cplusplus) extern "C" { @@ -94,6 +92,9 @@ OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); // Properties. +// DSA_bits returns the size of |dsa|'s group modulus, in bits. +OPENSSL_EXPORT unsigned DSA_bits(const DSA *dsa); + // DSA_get0_pub_key returns |dsa|'s public key. OPENSSL_EXPORT const BIGNUM *DSA_get0_pub_key(const DSA *dsa); @@ -395,25 +396,6 @@ OPENSSL_EXPORT DSA *DSA_generate_parameters(int bits, unsigned char *seed, void *cb_arg); -struct dsa_st { - long version; - BIGNUM *p; - BIGNUM *q; // == 20 - BIGNUM *g; - - BIGNUM *pub_key; // y public key - BIGNUM *priv_key; // x private key - - int flags; - // Normally used to cache montgomery values - CRYPTO_MUTEX method_mont_lock; - BN_MONT_CTX *method_mont_p; - BN_MONT_CTX *method_mont_q; - CRYPTO_refcount_t references; - CRYPTO_EX_DATA ex_data; -}; - - #if defined(__cplusplus) } // extern C @@ -439,5 +421,6 @@ BSSL_NAMESPACE_END #define DSA_R_DECODE_ERROR 105 #define DSA_R_ENCODE_ERROR 106 #define DSA_R_INVALID_PARAMETERS 107 +#define DSA_R_TOO_MANY_ITERATIONS 108 #endif // OPENSSL_HEADER_DSA_H diff --git a/third_party/boringssl/kit/src/include/openssl/ec.h b/third_party/boringssl/kit/src/include/openssl/ec.h index cc8138de..dd5259bb 100644 --- a/third_party/boringssl/kit/src/include/openssl/ec.h +++ b/third_party/boringssl/kit/src/include/openssl/ec.h @@ -253,13 +253,23 @@ OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx); // EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| -// into, at most, |len| bytes at |buf|. It returns the number of bytes written -// or zero on error if |buf| is non-NULL, else the number of bytes needed. The -// |ctx| argument may be used if not NULL. +// into, at most, |max_out| bytes at |buf|. It returns the number of bytes +// written or zero on error if |buf| is non-NULL, else the number of bytes +// needed. The |ctx| argument may be used if not NULL. OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, - uint8_t *buf, size_t len, BN_CTX *ctx); + uint8_t *buf, size_t max_out, + BN_CTX *ctx); + +// EC_POINT_point2buf serialises |point| into the X9.62 form given by |form| to +// a newly-allocated buffer and sets |*out_buf| to point to it. It returns the +// length of the result on success or zero on error. The caller must release +// |*out_buf| with |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_POINT_point2buf(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t **out_buf, BN_CTX *ctx); // EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the // serialised point to |cbb|. It returns one on success and zero on error. @@ -309,6 +319,31 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, BN_CTX *ctx); +// Hash-to-curve. +// +// The following functions implement primitives from +// draft-irtf-cfrg-hash-to-curve-16. The |dst| parameter in each function is the +// domain separation tag and must be unique for each protocol and between the +// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec +// for additional guidance on this parameter. + +// EC_hash_to_curve_p256_xmd_sha256_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P256_XMD:SHA-256_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_hash_to_curve_p256_xmd_sha256_sswu( + const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + +// EC_hash_to_curve_p384_xmd_sha384_sswu hashes |msg| to a point on |group| and +// writes the result to |out|, implementing the P384_XMD:SHA-384_SSWU_RO_ suite +// from draft-irtf-cfrg-hash-to-curve-16. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_hash_to_curve_p384_xmd_sha384_sswu( + const EC_GROUP *group, EC_POINT *out, const uint8_t *dst, size_t dst_len, + const uint8_t *msg, size_t msg_len); + + // Deprecated functions. // EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based @@ -323,7 +358,15 @@ OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, // |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always // return |NID_undef|. // -// Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| instead. +// This function is provided for compatibility with some legacy applications +// only. Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| +// instead. This ensures the result meets preconditions necessary for +// elliptic curve algorithms to function correctly and securely. +// +// Given invalid parameters, this function may fail or it may return an +// |EC_GROUP| which breaks these preconditions. Subsequent operations may then +// return arbitrary, incorrect values. Callers should not pass +// attacker-controlled values to this function. OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); diff --git a/third_party/boringssl/kit/src/include/openssl/ec_key.h b/third_party/boringssl/kit/src/include/openssl/ec_key.h index 3a408566..00986cf4 100644 --- a/third_party/boringssl/kit/src/include/openssl/ec_key.h +++ b/third_party/boringssl/kit/src/include/openssl/ec_key.h @@ -167,8 +167,9 @@ OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key, // about the problem can be found on the error stack. OPENSSL_EXPORT int EC_KEY_check_key(const EC_KEY *key); -// EC_KEY_check_fips performs a signing pairwise consistency test (FIPS 140-2 -// 4.9.2). It returns one if it passes and zero otherwise. +// EC_KEY_check_fips performs both a signing pairwise consistency test +// (FIPS 140-2 4.9.2) and the consistency test from SP 800-56Ar3 section +// 5.6.2.1.4. It returns one if it passes and zero otherwise. OPENSSL_EXPORT int EC_KEY_check_fips(const EC_KEY *key); // EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to @@ -178,12 +179,38 @@ OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x, const BIGNUM *y); -// EC_KEY_key2buf encodes the public key in |key| to an allocated octet string -// and sets |*out_buf| to point to it. It returns the length of the encoded -// octet string or zero if an error occurred. +// EC_KEY_oct2key decodes |len| bytes from |in| as an EC public key in X9.62 +// form. |key| must already have a group configured. On success, it sets the +// public key in |key| to the result and returns one. Otherwise, it returns +// zero. +OPENSSL_EXPORT int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, + BN_CTX *ctx); + +// EC_KEY_key2buf behaves like |EC_POINT_point2buf|, except it encodes the +// public key in |key|. OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, - unsigned char **out_buf, BN_CTX *ctx); + uint8_t **out_buf, BN_CTX *ctx); + +// EC_KEY_oct2priv decodes a big-endian, zero-padded integer from |len| bytes +// from |in| and sets |key|'s private key to the result. It returns one on +// success and zero on error. The input must be padded to the size of |key|'s +// group order. +OPENSSL_EXPORT int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len); + +// EC_KEY_priv2oct serializes |key|'s private key as a big-endian integer, +// zero-padded to the size of |key|'s group order and writes the result to at +// most |max_out| bytes of |out|. It returns the number of bytes written on +// success and zero on error. If |out| is NULL, it returns the number of bytes +// needed without writing anything. +OPENSSL_EXPORT size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, + size_t max_out); + +// EC_KEY_priv2buf behaves like |EC_KEY_priv2oct| but sets |*out_buf| to a +// newly-allocated buffer containing the result. It returns the size of the +// result on success and zero on error. The caller must release |*out_buf| with +// |OPENSSL_free| when done. +OPENSSL_EXPORT size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf); // Key generation. @@ -194,7 +221,9 @@ OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key); // EC_KEY_generate_key_fips behaves like |EC_KEY_generate_key| but performs -// additional checks for FIPS compliance. +// additional checks for FIPS compliance. This function is applicable when +// generating keys for either signing/verification or key agreement because +// both types of consistency check (PCT) are performed. OPENSSL_EXPORT int EC_KEY_generate_key_fips(EC_KEY *key); // EC_KEY_derive_from_secret deterministically derives a private key for |group| @@ -332,7 +361,7 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, long len); // i2o_ECPublicKey marshals an EC point from |key|, as described in -// |i2d_SAMPLE|. +// |i2d_SAMPLE|, except it returns zero on error instead of a negative value. // // Use |EC_POINT_point2cbb| instead. OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); diff --git a/third_party/boringssl/kit/src/include/openssl/ecdsa.h b/third_party/boringssl/kit/src/include/openssl/ecdsa.h index bc0dba56..56be1547 100644 --- a/third_party/boringssl/kit/src/include/openssl/ecdsa.h +++ b/third_party/boringssl/kit/src/include/openssl/ecdsa.h @@ -232,5 +232,6 @@ BSSL_NAMESPACE_END #define ECDSA_R_NOT_IMPLEMENTED 103 #define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 #define ECDSA_R_ENCODE_ERROR 105 +#define ECDSA_R_TOO_MANY_ITERATIONS 106 #endif // OPENSSL_HEADER_ECDSA_H diff --git a/third_party/boringssl/kit/src/include/openssl/err.h b/third_party/boringssl/kit/src/include/openssl/err.h index 28ba2507..0ec71b17 100644 --- a/third_party/boringssl/kit/src/include/openssl/err.h +++ b/third_party/boringssl/kit/src/include/openssl/err.h @@ -163,12 +163,16 @@ OPENSSL_EXPORT void ERR_free_strings(void); // ERR_GET_LIB returns the library code for the error. This is one of // the |ERR_LIB_*| values. -#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff)) +OPENSSL_INLINE int ERR_GET_LIB(uint32_t packed_error) { + return (int)((packed_error >> 24) & 0xff); +} // ERR_GET_REASON returns the reason code for the error. This is one of // library-specific |LIB_R_*| values where |LIB| is the library (see // |ERR_GET_LIB|). Note that reason codes are specific to the library. -#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff)) +OPENSSL_INLINE int ERR_GET_REASON(uint32_t packed_error) { + return (int)(packed_error & 0xfff); +} // ERR_get_error gets the packed error code for the least recent error and // removes that error from the queue. If there are no errors in the queue then @@ -184,8 +188,12 @@ OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line); #define ERR_FLAG_STRING 1 // ERR_FLAG_MALLOCED is passed into |ERR_set_error_data| to indicate that |data| -// was allocated with |OPENSSL_malloc|. It is never returned from -// |ERR_get_error_line_data|. +// was allocated with |OPENSSL_malloc|. +// +// It is, separately, returned in |*flags| from |ERR_get_error_line_data| to +// indicate that |*data| has a non-static lifetime, but this lifetime is still +// managed by the library. The caller must not call |OPENSSL_free| or |free| on +// |data|. #define ERR_FLAG_MALLOCED 2 // ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the @@ -411,7 +419,10 @@ OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf); #define ERR_ERROR_STRING_BUF_LEN 120 // ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code. -#define ERR_GET_FUNC(packed_error) 0 +OPENSSL_INLINE int ERR_GET_FUNC(uint32_t packed_error) { + (void)packed_error; + return 0; +} // ERR_TXT_* are provided for compatibility with code that assumes that it's // using OpenSSL. diff --git a/third_party/boringssl/kit/src/include/openssl/evp.h b/third_party/boringssl/kit/src/include/openssl/evp.h index e195907a..1cdaca27 100644 --- a/third_party/boringssl/kit/src/include/openssl/evp.h +++ b/third_party/boringssl/kit/src/include/openssl/evp.h @@ -178,11 +178,7 @@ OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey); #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey #define EVP_PKEY_ED25519 NID_ED25519 #define EVP_PKEY_X25519 NID_X25519 - -// EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of -// the given type. It returns one if successful or zero if the |type| argument -// is not one of the |EVP_PKEY_*| values or if |key| is NULL. -OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +#define EVP_PKEY_HKDF NID_hkdf // EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if // successful or zero if the |type| argument is not one of the |EVP_PKEY_*| @@ -238,9 +234,9 @@ OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); // Raw keys // // Some keys types support a "raw" serialization. Currently the only supported -// raw format is Ed25519, where the public key and private key formats are those -// specified in RFC 8032. Note the RFC 8032 private key format is the 32-byte -// prefix of |ED25519_sign|'s 64-byte private key. +// raw formats are X25519 and Ed25519, where the formats are those specified in +// RFC 7748 and RFC 8032, respectively. Note the RFC 8032 private key format is +// the 32-byte prefix of |ED25519_sign|'s 64-byte private key. // EVP_PKEY_new_raw_private_key returns a newly allocated |EVP_PKEY| wrapping a // private key of the specified type. It returns one on success and zero on @@ -665,11 +661,11 @@ OPENSSL_EXPORT int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); // success and zero on error. OPENSSL_EXPORT int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); -// EVP_PKEY_derive derives a shared key between the two keys configured in -// |ctx|. If |key| is non-NULL then, on entry, |out_key_len| must contain the -// amount of space at |key|. If sufficient then the shared key will be written -// to |key| and |*out_key_len| will be set to the length. If |key| is NULL then -// |out_key_len| will be set to the maximum length. +// EVP_PKEY_derive derives a shared key from |ctx|. If |key| is non-NULL then, +// on entry, |out_key_len| must contain the amount of space at |key|. If +// sufficient then the shared key will be written to |key| and |*out_key_len| +// will be set to the length. If |key| is NULL then |out_key_len| will be set to +// the maximum length. // // WARNING: Setting |out| to NULL only gives the maximum size of the key. The // actual key may be smaller. @@ -935,7 +931,10 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, // EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by // |in|. It returns one on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point and |pkey| must already +// have an EC group configured. If it is an X25519 key, it is the 32-byte X25519 +// public key representation. This function is not supported for other key types +// and will fail. OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, size_t len); @@ -945,7 +944,10 @@ OPENSSL_EXPORT int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, // |OPENSSL_free| to release this buffer. The function returns the length of the // buffer on success and zero on error. // -// This function only works on X25519 keys. +// If |pkey| is an EC key, the format is an X9.62 point with uncompressed +// coordinates. If it is an X25519 key, it is the 32-byte X25519 public key +// representation. This function is not supported for other key types and will +// fail. OPENSSL_EXPORT size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr); @@ -1017,6 +1019,23 @@ OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp); OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len); +// EVP_PKEY_CTX_set_dsa_paramgen_bits returns zero. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, + int nbits); + +// EVP_PKEY_CTX_set_dsa_paramgen_q_bits returns zero. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, + int qbits); + +// EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of +// the given type. If successful, it returns one. If the |type| argument +// is not one of |EVP_PKEY_RSA|, |EVP_PKEY_DSA|, or |EVP_PKEY_EC| values or if +// |key| is NULL, it returns zero. This function may not be used with other +// |EVP_PKEY_*| types. +// +// Use the |EVP_PKEY_assign_*| functions instead. +OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); + // Preprocessor compatibility section (hidden). // @@ -1041,29 +1060,6 @@ OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, ERR_put_error(ERR_LIB_EVP, 0, reason, __FILE__, __LINE__) -// Private structures. - -struct evp_pkey_st { - CRYPTO_refcount_t references; - - // type contains one of the EVP_PKEY_* values or NID_undef and determines - // which element (if any) of the |pkey| union is valid. - int type; - - union { - void *ptr; - RSA *rsa; - DSA *dsa; - DH *dh; - EC_KEY *ec; - } pkey; - - // ameth contains a pointer to a method table that contains many ASN.1 - // methods for the key type. - const EVP_PKEY_ASN1_METHOD *ameth; -} /* EVP_PKEY */; - - #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/ex_data.h b/third_party/boringssl/kit/src/include/openssl/ex_data.h index 102f8a8f..8f2f98b0 100644 --- a/third_party/boringssl/kit/src/include/openssl/ex_data.h +++ b/third_party/boringssl/kit/src/include/openssl/ex_data.h @@ -145,7 +145,7 @@ OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_free *free_func); // TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument -// should have been returned from a previous call to |TYPE_get_ex_new_index|. +// must have been returned from a previous call to |TYPE_get_ex_new_index|. OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg); // TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such diff --git a/third_party/boringssl/kit/src/include/openssl/hmac.h b/third_party/boringssl/kit/src/include/openssl/hmac.h index b5d1e420..7a4737f2 100644 --- a/third_party/boringssl/kit/src/include/openssl/hmac.h +++ b/third_party/boringssl/kit/src/include/openssl/hmac.h @@ -98,6 +98,10 @@ OPENSSL_EXPORT HMAC_CTX *HMAC_CTX_new(void); // HMAC_CTX_cleanup frees data owned by |ctx|. It does not free |ctx| itself. OPENSSL_EXPORT void HMAC_CTX_cleanup(HMAC_CTX *ctx); +// HMAC_CTX_cleanse zeros the digest state from |ctx| and then performs the +// actions of |HMAC_CTX_cleanup|. +OPENSSL_EXPORT void HMAC_CTX_cleanse(HMAC_CTX *ctx); + // HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. OPENSSL_EXPORT void HMAC_CTX_free(HMAC_CTX *ctx); @@ -133,6 +137,9 @@ OPENSSL_EXPORT int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, // |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. OPENSSL_EXPORT size_t HMAC_size(const HMAC_CTX *ctx); +// HMAC_CTX_get_md returns |ctx|'s hash function. +OPENSSL_EXPORT const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); + // HMAC_CTX_copy_ex sets |dest| equal to |src|. On entry, |dest| must have been // initialised by calling |HMAC_CTX_init|. It returns one on success and zero // on error. diff --git a/third_party/boringssl/kit/src/include/openssl/hpke.h b/third_party/boringssl/kit/src/include/openssl/hpke.h index 56251b7b..eaf5947f 100644 --- a/third_party/boringssl/kit/src/include/openssl/hpke.h +++ b/third_party/boringssl/kit/src/include/openssl/hpke.h @@ -30,7 +30,7 @@ extern "C" { // Hybrid Public Key Encryption (HPKE) enables a sender to encrypt messages to a // receiver with a public key. // -// See https://tools.ietf.org/html/draft-irtf-cfrg-hpke-12. +// See RFC 9180. // Parameters. @@ -51,6 +51,30 @@ OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void); // will be one of the |EVP_HPKE_KEM_*| constants. OPENSSL_EXPORT uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem); +// EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of an encoded public key +// for all KEMs currently supported by this library. +#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 32 + +// EVP_HPKE_KEM_public_key_len returns the length of a public key for |kem|. +// This value will be at most |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH|. +OPENSSL_EXPORT size_t EVP_HPKE_KEM_public_key_len(const EVP_HPKE_KEM *kem); + +// EVP_HPKE_MAX_PRIVATE_KEY_LENGTH is the maximum length of an encoded private +// key for all KEMs currently supported by this library. +#define EVP_HPKE_MAX_PRIVATE_KEY_LENGTH 32 + +// EVP_HPKE_KEM_private_key_len returns the length of a private key for |kem|. +// This value will be at most |EVP_HPKE_MAX_PRIVATE_KEY_LENGTH|. +OPENSSL_EXPORT size_t EVP_HPKE_KEM_private_key_len(const EVP_HPKE_KEM *kem); + +// EVP_HPKE_MAX_ENC_LENGTH is the maximum length of "enc", the encapsulated +// shared secret, for all KEMs currently supported by this library. +#define EVP_HPKE_MAX_ENC_LENGTH 32 + +// EVP_HPKE_KEM_enc_len returns the length of the "enc", the encapsulated shared +// secret, for |kem|. This value will be at most |EVP_HPKE_MAX_ENC_LENGTH|. +OPENSSL_EXPORT size_t EVP_HPKE_KEM_enc_len(const EVP_HPKE_KEM *kem); + // The following constants are KDF identifiers. #define EVP_HPKE_HKDF_SHA256 0x0001 @@ -60,6 +84,11 @@ OPENSSL_EXPORT const EVP_HPKE_KDF *EVP_hpke_hkdf_sha256(void); // EVP_HPKE_KDF_id returns the HPKE KDF identifier for |kdf|. OPENSSL_EXPORT uint16_t EVP_HPKE_KDF_id(const EVP_HPKE_KDF *kdf); +// EVP_HPKE_KDF_hkdf_md returns the HKDF hash function corresponding to |kdf|, +// or NULL if |kdf| is not an HKDF-based KDF. All currently supported KDFs are +// HKDF-based. +OPENSSL_EXPORT const EVP_MD *EVP_HPKE_KDF_hkdf_md(const EVP_HPKE_KDF *kdf); + // The following constants are AEAD identifiers. #define EVP_HPKE_AES_128_GCM 0x0001 #define EVP_HPKE_AES_256_GCM 0x0002 @@ -127,28 +156,22 @@ OPENSSL_EXPORT int EVP_HPKE_KEY_generate(EVP_HPKE_KEY *key, // EVP_HPKE_KEY_kem returns the HPKE KEM used by |key|. OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_HPKE_KEY_kem(const EVP_HPKE_KEY *key); -// EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of a public key for all -// KEMs supported by this library. -#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 32 - // EVP_HPKE_KEY_public_key writes |key|'s public key to |out| and sets // |*out_len| to the number of bytes written. On success, it returns one and // writes at most |max_out| bytes. If |max_out| is too small, it returns zero. // Setting |max_out| to |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH| will ensure the public -// key fits. +// key fits. An exact size can also be determined by +// |EVP_HPKE_KEM_public_key_len|. OPENSSL_EXPORT int EVP_HPKE_KEY_public_key(const EVP_HPKE_KEY *key, uint8_t *out, size_t *out_len, size_t max_out); -// EVP_HPKE_MAX_PRIVATE_KEY_LENGTH is the maximum length of a private key for -// all KEMs supported by this library. -#define EVP_HPKE_MAX_PRIVATE_KEY_LENGTH 32 - // EVP_HPKE_KEY_private_key writes |key|'s private key to |out| and sets // |*out_len| to the number of bytes written. On success, it returns one and // writes at most |max_out| bytes. If |max_out| is too small, it returns zero. // Setting |max_out| to |EVP_HPKE_MAX_PRIVATE_KEY_LENGTH| will ensure the -// private key fits. +// private key fits. An exact size can also be determined by +// |EVP_HPKE_KEM_private_key_len|. OPENSSL_EXPORT int EVP_HPKE_KEY_private_key(const EVP_HPKE_KEY *key, uint8_t *out, size_t *out_len, size_t max_out); @@ -182,16 +205,13 @@ OPENSSL_EXPORT EVP_HPKE_CTX *EVP_HPKE_CTX_new(void); // created with |EVP_HPKE_CTX_new|. OPENSSL_EXPORT void EVP_HPKE_CTX_free(EVP_HPKE_CTX *ctx); -// EVP_HPKE_MAX_ENC_LENGTH is the maximum length of "enc", the encapsulated -// shared secret, for all supported KEMs in this library. -#define EVP_HPKE_MAX_ENC_LENGTH 32 - // EVP_HPKE_CTX_setup_sender implements the SetupBaseS HPKE operation. It // encapsulates a shared secret for |peer_public_key| and sets up |ctx| as a // sender context. It writes the encapsulated shared secret to |out_enc| and // sets |*out_enc_len| to the number of bytes written. It writes at most // |max_enc| bytes and fails if the buffer is too small. Setting |max_enc| to at -// least |EVP_HPKE_MAX_ENC_LENGTH| will ensure the buffer is large enough. +// least |EVP_HPKE_MAX_ENC_LENGTH| will ensure the buffer is large enough. An +// exact size may also be determined by |EVP_PKEY_KEM_enc_len|. // // This function returns one on success and zero on error. Note that // |peer_public_key| may be invalid, in which case this function will return an @@ -229,6 +249,34 @@ OPENSSL_EXPORT int EVP_HPKE_CTX_setup_recipient( const EVP_HPKE_AEAD *aead, const uint8_t *enc, size_t enc_len, const uint8_t *info, size_t info_len); +// EVP_HPKE_CTX_setup_auth_sender implements the SetupAuthS HPKE operation. It +// behaves like |EVP_HPKE_CTX_setup_sender| but authenticates the resulting +// context with |key|. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_auth_sender( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len); + +// EVP_HPKE_CTX_setup_auth_sender_with_seed_for_testing behaves like +// |EVP_HPKE_CTX_setup_auth_sender|, but takes a seed to behave +// deterministically. The seed's format depends on |kem|. For X25519, it is the +// sender's ephemeral private key. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_auth_sender_with_seed_for_testing( + EVP_HPKE_CTX *ctx, uint8_t *out_enc, size_t *out_enc_len, size_t max_enc, + const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, const EVP_HPKE_AEAD *aead, + const uint8_t *peer_public_key, size_t peer_public_key_len, + const uint8_t *info, size_t info_len, const uint8_t *seed, size_t seed_len); + +// EVP_HPKE_CTX_setup_auth_recipient implements the SetupAuthR HPKE operation. +// It behaves like |EVP_HPKE_CTX_setup_recipient| but checks the resulting +// context was authenticated with |peer_public_key|. +OPENSSL_EXPORT int EVP_HPKE_CTX_setup_auth_recipient( + EVP_HPKE_CTX *ctx, const EVP_HPKE_KEY *key, const EVP_HPKE_KDF *kdf, + const EVP_HPKE_AEAD *aead, const uint8_t *enc, size_t enc_len, + const uint8_t *info, size_t info_len, const uint8_t *peer_public_key, + size_t peer_public_key_len); + // Using an HPKE context. // @@ -292,6 +340,10 @@ OPENSSL_EXPORT int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *ctx, uint8_t *out, // up as a sender. OPENSSL_EXPORT size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *ctx); +// EVP_HPKE_CTX_kem returns |ctx|'s configured KEM, or NULL if the context has +// not been set up. +OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_HPKE_CTX_kem(const EVP_HPKE_CTX *ctx); + // EVP_HPKE_CTX_aead returns |ctx|'s configured AEAD, or NULL if the context has // not been set up. OPENSSL_EXPORT const EVP_HPKE_AEAD *EVP_HPKE_CTX_aead(const EVP_HPKE_CTX *ctx); @@ -307,6 +359,7 @@ OPENSSL_EXPORT const EVP_HPKE_KDF *EVP_HPKE_CTX_kdf(const EVP_HPKE_CTX *ctx); // but accessing or modifying their fields is forbidden. struct evp_hpke_ctx_st { + const EVP_HPKE_KEM *kem; const EVP_HPKE_AEAD *aead; const EVP_HPKE_KDF *kdf; EVP_AEAD_CTX aead_ctx; diff --git a/third_party/boringssl/kit/src/include/openssl/kdf.h b/third_party/boringssl/kit/src/include/openssl/kdf.h new file mode 100644 index 00000000..7adad381 --- /dev/null +++ b/third_party/boringssl/kit/src/include/openssl/kdf.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_KDF_H +#define OPENSSL_HEADER_KDF_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// KDF support for EVP. + + +// HKDF-specific functions. +// +// The following functions are provided for OpenSSL compatibility. Prefer the +// HKDF functions in . In each, |ctx| must be created with +// |EVP_PKEY_CTX_new_id| with |EVP_PKEY_HKDF| and then initialized with +// |EVP_PKEY_derive_init|. + +// EVP_PKEY_HKDEF_MODE_* define "modes" for use with |EVP_PKEY_CTX_hkdf_mode|. +// The mispelling of "HKDF" as "HKDEF" is intentional for OpenSSL compatibility. +#define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +#define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +#define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +// EVP_PKEY_CTX_hkdf_mode configures which HKDF operation to run. It returns one +// on success and zero on error. |mode| must be one of |EVP_PKEY_HKDEF_MODE_*|. +// By default, the mode is |EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND|. +// +// If |mode| is |EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND| or +// |EVP_PKEY_HKDEF_MODE_EXPAND_ONLY|, the output is variable-length. +// |EVP_PKEY_derive| uses the size of the output buffer as the output length for +// HKDF-Expand. +// +// WARNING: Although this API calls it a "mode", HKDF-Extract and HKDF-Expand +// are distinct operations with distinct inputs and distinct kinds of keys. +// Callers should not pass input secrets for one operation into the other. +OPENSSL_EXPORT int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); + +// EVP_PKEY_CTX_set_hkdf_md sets |md| as the digest to use with HKDF. It returns +// one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_set1_hkdf_key configures HKDF to use |key_len| bytes from |key| +// as the "key", described below. It returns one on success and zero on error. +// +// Which input is the key depends on the "mode" (see |EVP_PKEY_CTX_hkdf_mode|). +// If |EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND| or +// |EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY|, this function specifies the input keying +// material (IKM) for HKDF-Extract. If |EVP_PKEY_HKDEF_MODE_EXPAND_ONLY|, it +// instead specifies the pseudorandom key (PRK) for HKDF-Expand. +OPENSSL_EXPORT int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const uint8_t *key, + size_t key_len); + +// EVP_PKEY_CTX_set1_hkdf_salt configures HKDF to use |salt_len| bytes from +// |salt| as the salt parameter to HKDF-Extract. It returns one on success and +// zero on error. If performing HKDF-Expand only, this parameter is ignored. +OPENSSL_EXPORT int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const uint8_t *salt, + size_t salt_len); + +// EVP_PKEY_CTX_add1_hkdf_info appends |info_len| bytes from |info| to the info +// parameter used with HKDF-Expand. It returns one on success and zero on error. +// If performing HKDF-Extract only, this parameter is ignored. +OPENSSL_EXPORT int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const uint8_t *info, + size_t info_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_KDF_H diff --git a/third_party/boringssl/kit/src/include/openssl/kyber.h b/third_party/boringssl/kit/src/include/openssl/kyber.h new file mode 100644 index 00000000..cafae9d1 --- /dev/null +++ b/third_party/boringssl/kit/src/include/openssl/kyber.h @@ -0,0 +1,128 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_KYBER_H +#define OPENSSL_HEADER_KYBER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Kyber768. + + +// KYBER_public_key contains a Kyber768 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_public_key { + union { + uint8_t bytes[512 * (3 + 9) + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_private_key contains a Kyber768 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_private_key { + union { + uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public +// key. +#define KYBER_PUBLIC_KEY_BYTES 1184 + +// KYBER_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key| and sets |out_private_key| to +// the private key. +OPENSSL_EXPORT void KYBER_generate_key( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key); + +// KYBER_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. (This is faster than parsing the output of +// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key +// that was just generated.) +OPENSSL_EXPORT void KYBER_public_from_private( + struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key); + +// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. +#define KYBER_CIPHERTEXT_BYTES 1088 + +// KYBER_encap encrypts a random secret key of length |out_shared_secret_len| to +// |public_key|, writes the ciphertext to |ciphertext|, and writes the random +// key to |out_shared_secret|. The party calling |KYBER_decap| must already know +// the correct value of |out_shared_secret_len|. +OPENSSL_EXPORT void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t *out_shared_secret, + size_t out_shared_secret_len, + const struct KYBER_public_key *public_key); + +// KYBER_decap decrypts a key of length |out_shared_secret_len| from +// |ciphertext| using |private_key| and writes it to |out_shared_secret|. If +// |ciphertext| is invalid, |out_shared_secret| is filled with a key that +// will always be the same for the same |ciphertext| and |private_key|, but +// which appears to be random unless one has access to |private_key|. These +// alternatives occur in constant time. Any subsequent symmetric encryption +// using |out_shared_secret| must use an authenticated encryption scheme in +// order to discover the decapsulation failure. +OPENSSL_EXPORT void KYBER_decap( + uint8_t *out_shared_secret, size_t out_shared_secret_len, + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key); + + +// Serialisation of keys. + +// KYBER_marshal_public_key serializes |public_key| to |out| in the standard +// format for Kyber public keys. It returns one on success or zero on allocation +// error. +OPENSSL_EXPORT int KYBER_marshal_public_key( + CBB *out, const struct KYBER_public_key *public_key); + +// KYBER_parse_public_key parses a public key, in the format generated by +// |KYBER_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_public_key( + struct KYBER_public_key *out_public_key, CBS *in); + +// KYBER_marshal_private_key serializes |private_key| to |out| in the standard +// format for Kyber private keys. It returns one on success or zero on +// allocation error. +OPENSSL_EXPORT int KYBER_marshal_private_key( + CBB *out, const struct KYBER_private_key *private_key); + +// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by +// |KYBER_marshal_private_key|. +#define KYBER_PRIVATE_KEY_BYTES 2400 + +// KYBER_parse_private_key parses a private key, in the format generated by +// |KYBER_marshal_private_key|, from |in| and writes the result to +// |out_private_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_private_key( + struct KYBER_private_key *out_private_key, CBS *in); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_KYBER_H diff --git a/third_party/boringssl/kit/src/include/openssl/mem.h b/third_party/boringssl/kit/src/include/openssl/mem.h index 476299ae..8da1dd67 100644 --- a/third_party/boringssl/kit/src/include/openssl/mem.h +++ b/third_party/boringssl/kit/src/include/openssl/mem.h @@ -75,17 +75,26 @@ extern "C" { // unless stated otherwise. -// OPENSSL_malloc acts like a regular |malloc|. +#ifndef _BORINGSSL_PROHIBIT_OPENSSL_MALLOC +// OPENSSL_malloc is similar to a regular |malloc|, but allocates additional +// private data. The resulting pointer must be freed with |OPENSSL_free|. In +// the case of a malloc failure, prior to returning NULL |OPENSSL_malloc| will +// push |ERR_R_MALLOC_FAILURE| onto the openssl error stack. OPENSSL_EXPORT void *OPENSSL_malloc(size_t size); +#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the -// memory allocated at |ptr| and frees it. +// memory allocated at |ptr| and frees it along with the private data. +// It must only be used on on |ptr| values obtained from |OPENSSL_malloc| OPENSSL_EXPORT void OPENSSL_free(void *ptr); +#ifndef _BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that // contains the contents of |ptr|. Unlike |realloc|, a new buffer is always -// allocated and the data at |ptr| is always wiped and freed. +// allocated and the data at |ptr| is always wiped and freed. Memory is +// allocated with |OPENSSL_malloc| and must be freed with |OPENSSL_free|. OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size); +#endif // !_BORINGSSL_PROHIBIT_OPENSSL_MALLOC // OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to // |memset_s| from C11. @@ -110,13 +119,42 @@ OPENSSL_EXPORT char *OPENSSL_strdup(const char *s); // OPENSSL_strnlen has the same behaviour as strnlen(3). OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len); -// OPENSSL_tolower is a locale-independent version of tolower(3). +// OPENSSL_isalpha is a locale-independent, ASCII-only version of isalpha(3), It +// only recognizes 'a' through 'z' and 'A' through 'Z' as alphabetic. +OPENSSL_EXPORT int OPENSSL_isalpha(int c); + +// OPENSSL_isdigit is a locale-independent, ASCII-only version of isdigit(3), It +// only recognizes '0' through '9' as digits. +OPENSSL_EXPORT int OPENSSL_isdigit(int c); + +// OPENSSL_isxdigit is a locale-independent, ASCII-only version of isxdigit(3), +// It only recognizes '0' through '9', 'a' through 'f', and 'A through 'F' as +// digits. +OPENSSL_EXPORT int OPENSSL_isxdigit(int c); + +// OPENSSL_fromxdigit returns one if |c| is a hexadecimal digit as recognized +// by OPENSSL_isxdigit, and sets |out| to the corresponding value. Otherwise +// zero is returned. +OPENSSL_EXPORT int OPENSSL_fromxdigit(uint8_t *out, int c); + +// OPENSSL_isalnum is a locale-independent, ASCII-only version of isalnum(3), It +// only recognizes what |OPENSSL_isalpha| and |OPENSSL_isdigit| recognize. +OPENSSL_EXPORT int OPENSSL_isalnum(int c); + +// OPENSSL_tolower is a locale-independent, ASCII-only version of tolower(3). It +// only lowercases ASCII values. Other values are returned as-is. OPENSSL_EXPORT int OPENSSL_tolower(int c); -// OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). +// OPENSSL_isspace is a locale-independent, ASCII-only version of isspace(3). It +// only recognizes '\t', '\n', '\v', '\f', '\r', and ' '. +OPENSSL_EXPORT int OPENSSL_isspace(int c); + +// OPENSSL_strcasecmp is a locale-independent, ASCII-only version of +// strcasecmp(3). OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b); -// OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). +// OPENSSL_strncasecmp is a locale-independent, ASCII-only version of +// strncasecmp(3). OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n); // DECIMAL_SIZE returns an upper bound for the length of the decimal @@ -131,12 +169,25 @@ OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...) OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) OPENSSL_PRINTF_FORMAT_FUNC(3, 0); +// OPENSSL_vasprintf has the same behavior as vasprintf(3), except that +// memory allocated in a returned string must be freed with |OPENSSL_free|. +OPENSSL_EXPORT int OPENSSL_vasprintf(char **str, const char *format, + va_list args) + OPENSSL_PRINTF_FORMAT_FUNC(2, 0); + +// OPENSSL_asprintf has the same behavior as asprintf(3), except that +// memory allocated in a returned string must be freed with |OPENSSL_free|. +OPENSSL_EXPORT int OPENSSL_asprintf(char **str, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(2, 3); + // OPENSSL_strndup returns an allocated, duplicate of |str|, which is, at most, -// |size| bytes. The result is always NUL terminated. +// |size| bytes. The result is always NUL terminated. The memory allocated +// must be freed with |OPENSSL_free|. OPENSSL_EXPORT char *OPENSSL_strndup(const char *str, size_t size); // OPENSSL_memdup returns an allocated, duplicate of |size| bytes from |data| or -// NULL on allocation failure. +// NULL on allocation failure. The memory allocated must be freed with +// |OPENSSL_free|. OPENSSL_EXPORT void *OPENSSL_memdup(const void *data, size_t size); // OPENSSL_strlcpy acts like strlcpy(3). @@ -164,6 +215,21 @@ OPENSSL_EXPORT void CRYPTO_free(void *ptr, const char *file, int line); // allocations on free, but we define |OPENSSL_clear_free| for compatibility. OPENSSL_EXPORT void OPENSSL_clear_free(void *ptr, size_t len); +// CRYPTO_secure_malloc_init returns zero. +OPENSSL_EXPORT int CRYPTO_secure_malloc_init(size_t size, size_t min_size); + +// CRYPTO_secure_malloc_initialized returns zero. +OPENSSL_EXPORT int CRYPTO_secure_malloc_initialized(void); + +// CRYPTO_secure_used returns zero. +OPENSSL_EXPORT size_t CRYPTO_secure_used(void); + +// OPENSSL_secure_malloc calls |OPENSSL_malloc|. +OPENSSL_EXPORT void *OPENSSL_secure_malloc(size_t size); + +// OPENSSL_secure_clear_free calls |OPENSSL_clear_free|. +OPENSSL_EXPORT void OPENSSL_secure_clear_free(void *ptr, size_t len); + #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/nid.h b/third_party/boringssl/kit/src/include/openssl/nid.h index bf7f3da5..4dd8841b 100644 --- a/third_party/boringssl/kit/src/include/openssl/nid.h +++ b/third_party/boringssl/kit/src/include/openssl/nid.h @@ -4235,9 +4235,6 @@ extern "C" { #define LN_auth_any "auth-any" #define NID_auth_any 958 -#define SN_CECPQ2 "CECPQ2" -#define NID_CECPQ2 959 - #define SN_ED448 "ED448" #define NID_ED448 960 #define OBJ_ED448 1L, 3L, 101L, 113L @@ -4251,6 +4248,13 @@ extern "C" { #define NID_sha512_256 962 #define OBJ_sha512_256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 6L +#define SN_hkdf "HKDF" +#define LN_hkdf "hkdf" +#define NID_hkdf 963 + +#define SN_X25519Kyber768Draft00 "X25519Kyber768Draft00" +#define NID_X25519Kyber768Draft00 964 + #if defined(__cplusplus) } /* extern C */ diff --git a/third_party/boringssl/kit/src/include/openssl/obj.h b/third_party/boringssl/kit/src/include/openssl/obj.h index ad7271ec..3fb8bdeb 100644 --- a/third_party/boringssl/kit/src/include/openssl/obj.h +++ b/third_party/boringssl/kit/src/include/openssl/obj.h @@ -183,8 +183,15 @@ OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, // Adding objects at runtime. -// OBJ_create adds a known object and returns the nid of the new object, or +// OBJ_create adds a known object and returns the NID of the new object, or // NID_undef on error. +// +// WARNING: This function modifies global state. The table cannot contain +// duplicate OIDs, short names, or long names. If two callers in the same +// address space add conflicting values, only one registration will take effect. +// Avoid this function if possible. Instead, callers can process OIDs unknown to +// BoringSSL by acting on the byte representation directly. See |OBJ_get0_data| +// and |OBJ_length|. OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name, const char *long_name); diff --git a/third_party/boringssl/kit/src/include/openssl/opensslconf.h b/third_party/boringssl/kit/src/include/openssl/opensslconf.h index 3f1faf32..51657030 100644 --- a/third_party/boringssl/kit/src/include/openssl/opensslconf.h +++ b/third_party/boringssl/kit/src/include/openssl/opensslconf.h @@ -59,6 +59,7 @@ #define OPENSSL_NO_SM3 #define OPENSSL_NO_SM4 #define OPENSSL_NO_SRP +#define OPENSSL_NO_SSL_TRACE #define OPENSSL_NO_SSL2 #define OPENSSL_NO_SSL3 #define OPENSSL_NO_SSL3_METHOD diff --git a/third_party/boringssl/kit/src/include/openssl/pem.h b/third_party/boringssl/kit/src/include/openssl/pem.h index a94f2766..21885ba3 100644 --- a/third_party/boringssl/kit/src/include/openssl/pem.h +++ b/third_party/boringssl/kit/src/include/openssl/pem.h @@ -349,10 +349,6 @@ OPENSSL_EXPORT int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, - EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *cd, - void *u); OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len); @@ -376,9 +372,6 @@ OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, // password. OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, void *userdata); -OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); -OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, - char *str); DECLARE_PEM_rw(X509, X509) @@ -421,40 +414,40 @@ DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) DECLARE_PEM_rw(PUBKEY, EVP_PKEY) -OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, const EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, + int nid, char *kstr, int klen, pem_password_cb *cb, void *u); OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); -OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cd, void *u); diff --git a/third_party/boringssl/kit/src/include/openssl/pkcs8.h b/third_party/boringssl/kit/src/include/openssl/pkcs8.h index 968640b7..8774681e 100644 --- a/third_party/boringssl/kit/src/include/openssl/pkcs8.h +++ b/third_party/boringssl/kit/src/include/openssl/pkcs8.h @@ -122,6 +122,8 @@ OPENSSL_EXPORT EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, // and decrypts it using |password|, sets |*out_key| to the included private // key and appends the included certificates to |out_certs|. It returns one on // success and zero on error. The caller takes ownership of the outputs. +// Any friendlyName attributes (RFC 2985) in the PKCS#12 structure will be +// returned on the |X509| objects as aliases. See also |X509_alias_get0|. OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, CBS *in, const char *password); @@ -219,6 +221,11 @@ OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password, // implemented for compatibility with external packages. Note the output still // requires a password for the MAC. Unencrypted keys in PKCS#12 are also not // widely supported and may not open in other implementations. +// +// If |cert| or |chain| have associated aliases (see |X509_alias_set1|), they +// will be included in the output as friendlyName attributes (RFC 2985). It is +// an error to specify both an alias on |cert| and a non-NULL |name| +// parameter. OPENSSL_EXPORT PKCS12 *PKCS12_create(const char *password, const char *name, const EVP_PKEY *pkey, X509 *cert, const STACK_OF(X509) *chain, int key_nid, @@ -278,5 +285,6 @@ BSSL_NAMESPACE_END #define PKCS8_R_UNSUPPORTED_PRF 130 #define PKCS8_R_INVALID_CHARACTERS 131 #define PKCS8_R_UNSUPPORTED_OPTIONS 132 +#define PKCS8_R_AMBIGUOUS_FRIENDLY_NAME 133 #endif // OPENSSL_HEADER_PKCS8_H diff --git a/third_party/boringssl/kit/src/include/openssl/rand.h b/third_party/boringssl/kit/src/include/openssl/rand.h index bd41f9e3..586274d1 100644 --- a/third_party/boringssl/kit/src/include/openssl/rand.h +++ b/third_party/boringssl/kit/src/include/openssl/rand.h @@ -25,9 +25,20 @@ extern "C" { // Random number generation. -// RAND_bytes writes |len| bytes of random data to |buf| and returns one. +// RAND_bytes writes |len| bytes of random data to |buf| and returns one. In the +// event that sufficient random data can not be obtained, |abort| is called. OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len); +// RAND_get_system_entropy_for_custom_prng writes |len| bytes of random data +// from a system entropy source to |buf|. The maximum length of entropy which +// may be requested is 256 bytes. If more than 256 bytes of data is requested, +// or if sufficient random data can not be obtained, |abort| is called. +// |RAND_bytes| should normally be used instead of this function. This function +// should only be used for seed values or where |malloc| should not be called +// from BoringSSL. This function is not FIPS compliant. +OPENSSL_EXPORT void RAND_get_system_entropy_for_custom_prng(uint8_t *buf, + size_t len); + // RAND_cleanup frees any resources used by the RNG. This is not safe if other // threads might still be calling |RAND_bytes|. OPENSSL_EXPORT void RAND_cleanup(void); diff --git a/third_party/boringssl/kit/src/include/openssl/rsa.h b/third_party/boringssl/kit/src/include/openssl/rsa.h index 57a2cb2c..fd183f79 100644 --- a/third_party/boringssl/kit/src/include/openssl/rsa.h +++ b/third_party/boringssl/kit/src/include/openssl/rsa.h @@ -79,7 +79,22 @@ extern "C" { // documented, functions which take a |const| pointer are non-mutating and // functions which take a non-|const| pointer are mutating. -// RSA_new returns a new, empty |RSA| object or NULL on error. +// RSA_new_public_key returns a new |RSA| object containing a public key with +// the specified parameters, or NULL on error or invalid input. +OPENSSL_EXPORT RSA *RSA_new_public_key(const BIGNUM *n, const BIGNUM *e); + +// RSA_new_private_key returns a new |RSA| object containing a private key with +// the specified parameters, or NULL on error or invalid input. All parameters +// are mandatory and may not be NULL. +// +// This function creates standard RSA private keys with CRT parameters. +OPENSSL_EXPORT RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, + const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp); + +// RSA_new returns a new, empty |RSA| object or NULL on error. Prefer using +// |RSA_new_public_key| or |RSA_new_private_key| to import an RSA key. OPENSSL_EXPORT RSA *RSA_new(void); // RSA_new_method acts the same as |RSA_new| but takes an explicit |ENGINE|. @@ -148,6 +163,20 @@ OPENSSL_EXPORT void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, const BIGNUM **out_dmq1, const BIGNUM **out_iqmp); + +// Setting individual properties. +// +// These functions allow setting individual properties of an |RSA| object. This +// is typically used with |RSA_new| to construct an RSA key field by field. +// Prefer instead to use |RSA_new_public_key| and |RSA_new_private_key|. These +// functions defer some initialization to the first use of an |RSA| object. This +// means invalid inputs may be caught late. +// +// TODO(crbug.com/boringssl/316): This deferred initialization also causes +// performance problems in multi-threaded applications. The preferred APIs +// currently have the same issues, but they will initialize eagerly in the +// future. + // RSA_set0_key sets |rsa|'s modulus, public exponent, and private exponent to // |n|, |e|, and |d| respectively, if non-NULL. On success, it takes ownership // of each argument and returns one. Otherwise, it returns zero. @@ -298,8 +327,8 @@ OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, // |hash_nid|. Passing unhashed inputs will not result in a secure signature // scheme. OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, - unsigned digest_len, uint8_t *out, - unsigned *out_len, RSA *rsa); + size_t digest_len, uint8_t *out, unsigned *out_len, + RSA *rsa); // RSA_sign_pss_mgf1 signs |digest_len| bytes from |digest| with the public key // from |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It @@ -570,6 +599,48 @@ OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, const RSA *rsa); +// Obscure RSA variants. +// +// These functions allow creating RSA keys with obscure combinations of +// parameters. + +// RSA_new_private_key_no_crt behaves like |RSA_new_private_key| but constructs +// an RSA key without CRT coefficients. +// +// Keys created by this function will be less performant and cannot be +// serialized. +OPENSSL_EXPORT RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e, + const BIGNUM *d); + +// RSA_new_private_key_no_e behaves like |RSA_new_private_key| but constructs an +// RSA key without CRT parameters or public exponent. +// +// Keys created by this function will be less performant, cannot be serialized, +// and lack hardening measures that protect against side channels and fault +// attacks. +OPENSSL_EXPORT RSA *RSA_new_private_key_no_e(const BIGNUM *n, const BIGNUM *d); + +// RSA_new_public_key_large_e behaves like |RSA_new_public_key| but allows any +// |e| up to |n|. +// +// BoringSSL typically bounds public exponents as a denial-of-service +// mitigation. Keys created by this function may perform worse than those +// created by |RSA_new_public_key|. +OPENSSL_EXPORT RSA *RSA_new_public_key_large_e(const BIGNUM *n, + const BIGNUM *e); + +// RSA_new_private_key_large_e behaves like |RSA_new_private_key| but allows any +// |e| up to |n|. +// +// BoringSSL typically bounds public exponents as a denial-of-service +// mitigation. Keys created by this function may perform worse than those +// created by |RSA_new_private_key|. +OPENSSL_EXPORT RSA *RSA_new_private_key_large_e( + const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, + const BIGNUM *iqmp); + + // ex_data functions. // // See |ex_data.h| for details. @@ -600,6 +671,17 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx); // RSA_FLAG_EXT_PKEY is deprecated and ignored. #define RSA_FLAG_EXT_PKEY 0x20 +// RSA_FLAG_NO_PUBLIC_EXPONENT indicates that private keys without a public +// exponent are allowed. This is an internal constant. Use +// |RSA_new_private_key_no_e| to construct such keys. +#define RSA_FLAG_NO_PUBLIC_EXPONENT 0x40 + +// RSA_FLAG_LARGE_PUBLIC_EXPONENT indicates that keys with a large public +// exponent are allowed. This is an internal constant. Use +// |RSA_new_public_key_large_e| and |RSA_new_private_key_large_e| to construct +// such keys. +#define RSA_FLAG_LARGE_PUBLIC_EXPONENT 0x80 + // RSA public exponent values. @@ -625,7 +707,7 @@ OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); // should use instead. It returns NULL on error, or a newly-allocated |RSA| on // success. This function is provided for compatibility only. The |callback| // and |cb_arg| parameters must be NULL. -OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback, +OPENSSL_EXPORT RSA *RSA_generate_key(int bits, uint64_t e, void *callback, void *cb_arg); // d2i_RSAPublicKey parses a DER-encoded RSAPublicKey structure (RFC 8017) from @@ -688,6 +770,14 @@ OPENSSL_EXPORT int RSA_print(BIO *bio, const RSA *rsa, int indent); // the id-RSASSA-PSS key encoding. OPENSSL_EXPORT const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa); +// RSA_new_method_no_e returns a newly-allocated |RSA| object backed by +// |engine|, with a public modulus of |n| and no known public exponent. +// +// Do not use this function. It exists only to support Conscrypt, whose use +// should be replaced with a more sound mechanism. See +// https://crbug.com/boringssl/602. +OPENSSL_EXPORT RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n); + struct rsa_meth_st { struct openssl_method_common_st common; @@ -728,67 +818,6 @@ struct rsa_meth_st { }; -// Private functions. - -typedef struct bn_blinding_st BN_BLINDING; - -struct rsa_st { - RSA_METHOD *meth; - - // Access to the following fields was historically allowed, but - // deprecated. Use |RSA_get0_*| and |RSA_set0_*| instead. Access to all other - // fields is forbidden and will cause threading errors. - BIGNUM *n; - BIGNUM *e; - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *dmp1; - BIGNUM *dmq1; - BIGNUM *iqmp; - - // be careful using this if the RSA structure is shared - CRYPTO_EX_DATA ex_data; - CRYPTO_refcount_t references; - int flags; - - CRYPTO_MUTEX lock; - - // Used to cache montgomery values. The creation of these values is protected - // by |lock|. - BN_MONT_CTX *mont_n; - BN_MONT_CTX *mont_p; - BN_MONT_CTX *mont_q; - - // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, - // but with the correct widths to prevent side channels. These must use - // separate copies due to threading concerns caused by OpenSSL's API - // mistakes. See https://github.com/openssl/openssl/issues/5158 and - // the |freeze_private_key| implementation. - BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; - - // inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|, - // if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using - // |mont_q|. - BIGNUM *inv_small_mod_large_mont; - - // num_blindings contains the size of the |blindings| and |blindings_inuse| - // arrays. This member and the |blindings_inuse| array are protected by - // |lock|. - unsigned num_blindings; - // blindings is an array of BN_BLINDING structures that can be reserved by a - // thread by locking |lock| and changing the corresponding element in - // |blindings_inuse| from 0 to 1. - BN_BLINDING **blindings; - unsigned char *blindings_inuse; - uint64_t blinding_fork_generation; - - // private_key_frozen is one if the key has been used for a private key - // operation and may no longer be mutated. - unsigned private_key_frozen:1; -}; - - #if defined(__cplusplus) } // extern C diff --git a/third_party/boringssl/kit/src/include/openssl/service_indicator.h b/third_party/boringssl/kit/src/include/openssl/service_indicator.h new file mode 100644 index 00000000..33b38b23 --- /dev/null +++ b/third_party/boringssl/kit/src/include/openssl/service_indicator.h @@ -0,0 +1,96 @@ +/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SERVICE_INDICATOR_H +#define OPENSSL_HEADER_SERVICE_INDICATOR_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// FIPS_service_indicator_before_call and |FIPS_service_indicator_after_call| +// both currently return the same local thread counter which is slowly +// incremented whenever approved services are called. The +// |CALL_SERVICE_AND_CHECK_APPROVED| macro is strongly recommended over calling +// these functions directly. +// +// |FIPS_service_indicator_before_call| is intended to be called immediately +// before an approved service, while |FIPS_service_indicator_after_call| should +// be called immediately after. If the values returned from these two functions +// are not equal, this means that the service called inbetween is deemed to be +// approved. If the values are still the same, this means the counter has not +// been incremented, and the service called is not approved for FIPS. +// +// In non-FIPS builds, |FIPS_service_indicator_before_call| always returns zero +// and |FIPS_service_indicator_after_call| always returns one. Thus calls always +// appear to be approved. This is intended to simplify testing. +OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(void); +OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void); + +#if defined(__cplusplus) +} + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +// CALL_SERVICE_AND_CHECK_APPROVED runs |func| and sets |approved| to one of the +// |FIPSStatus*| values, above, depending on whether |func| invoked an +// approved service. The result of |func| becomes the result of this macro. +#define CALL_SERVICE_AND_CHECK_APPROVED(approved, func) \ + [&] { \ + bssl::FIPSIndicatorHelper fips_indicator_helper(&approved); \ + return func; \ + }() + +namespace bssl { + +enum class FIPSStatus { + NOT_APPROVED = 0, + APPROVED = 1, +}; + +// FIPSIndicatorHelper records whether the service indicator counter advanced +// during its lifetime. +class FIPSIndicatorHelper { + public: + FIPSIndicatorHelper(FIPSStatus *result) + : result_(result), before_(FIPS_service_indicator_before_call()) { + *result_ = FIPSStatus::NOT_APPROVED; + } + + ~FIPSIndicatorHelper() { + uint64_t after = FIPS_service_indicator_after_call(); + if (after != before_) { + *result_ = FIPSStatus::APPROVED; + } + } + + FIPSIndicatorHelper(const FIPSIndicatorHelper&) = delete; + FIPSIndicatorHelper &operator=(const FIPSIndicatorHelper &) = delete; + + private: + FIPSStatus *const result_; + const uint64_t before_; +}; + +} // namespace bssl +} // extern "C++" + +#endif // !BORINGSSL_NO_CXX +#endif // __cplusplus + +#endif // OPENSSL_HEADER_SERVICE_INDICATOR_H diff --git a/third_party/boringssl/kit/src/include/openssl/span.h b/third_party/boringssl/kit/src/include/openssl/span.h index 79f1d416..34b39c00 100644 --- a/third_party/boringssl/kit/src/include/openssl/span.h +++ b/third_party/boringssl/kit/src/include/openssl/span.h @@ -96,6 +96,15 @@ class Span : private internal::SpanBase { private: static const size_t npos = static_cast(-1); + // Heuristically test whether C is a container type that can be converted into + // a Span by checking for data() and size() member functions. + // + // TODO(davidben): Require C++17 support for std::is_convertible_v, etc. + template + using EnableIfContainer = std::enable_if_t< + std::is_convertible().data()), T *>::value && + std::is_integral().size())>::value>; + public: constexpr Span() : Span(nullptr, 0) {} constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {} @@ -103,29 +112,12 @@ class Span : private internal::SpanBase { template constexpr Span(T (&array)[N]) : Span(array, N) {} - template < - typename C, - // TODO(davidben): Switch everything to std::enable_if_t when we remove - // support for MSVC 2015. Although we could write our own enable_if_t and - // MSVC 2015 has std::enable_if_t anyway, MSVC 2015's SFINAE - // implementation is problematic and does not work below unless we write - // the ::type at use. - // - // TODO(davidben): Move this and the identical copy below into an - // EnableIfContainer alias when we drop MSVC 2015 support. MSVC 2015's - // SFINAE support cannot handle type aliases. - typename = typename std::enable_if< - std::is_convertible().data()), T *>::value && - std::is_integral().size())>::value>::type, - typename = typename std::enable_if::value, C>::type> + template , + typename = std::enable_if_t::value, C>> Span(const C &container) : data_(container.data()), size_(container.size()) {} - template < - typename C, - typename = typename std::enable_if< - std::is_convertible().data()), T *>::value && - std::is_integral().size())>::value>::type, - typename = typename std::enable_if::value, C>::type> + template , + typename = std::enable_if_t::value, C>> explicit Span(C &container) : data_(container.data()), size_(container.size()) {} @@ -213,6 +205,11 @@ auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) { return MakeConstSpan(c.data(), c.size()); } +template +Span MakeConstSpan(T (&array)[size]) { + return array; +} + BSSL_NAMESPACE_END } // extern C++ diff --git a/third_party/boringssl/kit/src/include/openssl/ssl.h b/third_party/boringssl/kit/src/include/openssl/ssl.h index ca7ae142..f8f696b8 100644 --- a/third_party/boringssl/kit/src/include/openssl/ssl.h +++ b/third_party/boringssl/kit/src/include/openssl/ssl.h @@ -157,11 +157,6 @@ #include #endif -// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has -// been out for a year or so (assuming that they fix it in that release.) See -// https://boringssl-review.googlesource.com/c/boringssl/+/21664. -#include - // Forward-declare struct timeval. On Windows, it is defined in winsock2.h and // Windows headers define too many macros to be included in public headers. // However, only a forward declaration is needed. @@ -1086,6 +1081,21 @@ OPENSSL_EXPORT int SSL_set_ocsp_response(SSL *ssl, OPENSSL_EXPORT const char *SSL_get_signature_algorithm_name(uint16_t sigalg, int include_curve); +// SSL_get_all_signature_algorithm_names outputs a list of possible strings +// |SSL_get_signature_algorithm_name| may return in this version of BoringSSL. +// It writes at most |max_out| entries to |out| and returns the total number it +// would have written, if |max_out| had been large enough. |max_out| may be +// initially set to zero to size the output. +// +// This function is only intended to help initialize tables in callers that want +// possible strings pre-declared. This list would not be suitable to set a list +// of supported features. It is in no particular order, and may contain +// placeholder, experimental, or deprecated values that do not apply to every +// caller. Future versions of BoringSSL may also return strings not in this +// list, so this does not apply if, say, sending strings across services. +OPENSSL_EXPORT size_t SSL_get_all_signature_algorithm_names(const char **out, + size_t max_out); + // SSL_get_signature_algorithm_key_type returns the key type associated with // |sigalg| as an |EVP_PKEY_*| constant or |EVP_PKEY_NONE| if unknown. OPENSSL_EXPORT int SSL_get_signature_algorithm_key_type(uint16_t sigalg); @@ -1365,10 +1375,15 @@ OPENSSL_EXPORT int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher); // function returns |NID_auth_any|. OPENSSL_EXPORT int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher); -// SSL_CIPHER_get_prf_nid retuns the NID for |cipher|'s PRF hash. If |cipher| is -// a pre-TLS-1.2 cipher, it returns |NID_md5_sha1| but note these ciphers use +// SSL_CIPHER_get_handshake_digest returns |cipher|'s PRF hash. If |cipher| +// is a pre-TLS-1.2 cipher, it returns |EVP_md5_sha1| but note these ciphers use // SHA-256 in TLS 1.2. Other return values may be treated uniformly in all // applicable versions. +OPENSSL_EXPORT const EVP_MD *SSL_CIPHER_get_handshake_digest( + const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_prf_nid behaves like |SSL_CIPHER_get_handshake_digest| but +// returns the NID constant. Use |SSL_CIPHER_get_handshake_digest| instead. OPENSSL_EXPORT int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher); // SSL_CIPHER_get_min_version returns the minimum protocol version required @@ -1399,6 +1414,37 @@ OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher); OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits); +// SSL_get_all_cipher_names outputs a list of possible strings +// |SSL_CIPHER_get_name| may return in this version of BoringSSL. It writes at +// most |max_out| entries to |out| and returns the total number it would have +// written, if |max_out| had been large enough. |max_out| may be initially set +// to zero to size the output. +// +// This function is only intended to help initialize tables in callers that want +// possible strings pre-declared. This list would not be suitable to set a list +// of supported features. It is in no particular order, and may contain +// placeholder, experimental, or deprecated values that do not apply to every +// caller. Future versions of BoringSSL may also return strings not in this +// list, so this does not apply if, say, sending strings across services. +OPENSSL_EXPORT size_t SSL_get_all_cipher_names(const char **out, + size_t max_out); + + +// SSL_get_all_standard_cipher_names outputs a list of possible strings +// |SSL_CIPHER_standard_name| may return in this version of BoringSSL. It writes +// at most |max_out| entries to |out| and returns the total number it would have +// written, if |max_out| had been large enough. |max_out| may be initially set +// to zero to size the output. +// +// This function is only intended to help initialize tables in callers that want +// possible strings pre-declared. This list would not be suitable to set a list +// of supported features. It is in no particular order, and may contain +// placeholder, experimental, or deprecated values that do not apply to every +// caller. Future versions of BoringSSL may also return strings not in this +// list, so this does not apply if, say, sending strings across services. +OPENSSL_EXPORT size_t SSL_get_all_standard_cipher_names(const char **out, + size_t max_out); + // Cipher suite configuration. // @@ -1435,7 +1481,8 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, // // Available cipher rules are: // -// |ALL| matches all ciphers. +// |ALL| matches all ciphers, except for deprecated ciphers which must be +// named explicitly. // // |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE, // ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is @@ -1454,9 +1501,6 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, // // |SHA1|, and its alias |SHA|, match legacy cipher suites using HMAC-SHA1. // -// Although implemented, authentication-only ciphers match no rules and must be -// explicitly selected by name. -// // Deprecated cipher rules: // // |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, @@ -1495,8 +1539,7 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, // // TLS 1.3 ciphers do not participate in this mechanism and instead have a // built-in preference order. Functions to set cipher lists do not affect TLS -// 1.3, and functions to query the cipher list do not include TLS 1.3 -// ciphers. +// 1.3, and functions to query the cipher list do not include TLS 1.3 ciphers. // SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is // substituted when a cipher string starts with 'DEFAULT'. @@ -2281,65 +2324,111 @@ OPENSSL_EXPORT void SSL_CTX_set_ticket_aead_method( OPENSSL_EXPORT SSL_SESSION *SSL_process_tls13_new_session_ticket( SSL *ssl, const uint8_t *buf, size_t buf_len); - -// Elliptic curve Diffie-Hellman. +// SSL_CTX_set_num_tickets configures |ctx| to send |num_tickets| immediately +// after a successful TLS 1.3 handshake as a server. It returns one. Large +// values of |num_tickets| will be capped within the library. // -// Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an -// elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves -// are supported. ECDHE is always enabled, but the curve preferences may be -// configured with these functions. +// By default, BoringSSL sends two tickets. +OPENSSL_EXPORT int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); + +// SSL_CTX_get_num_tickets returns the number of tickets |ctx| will send +// immediately after a successful TLS 1.3 handshake as a server. +OPENSSL_EXPORT size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); + + +// Diffie-Hellman groups and ephemeral key exchanges. // -// Note that TLS 1.3 renames these from curves to groups. For consistency, we -// currently use the TLS 1.2 name in the API. - -// SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each -// element of |curves| should be a curve nid. It returns one on success and -// zero on failure. +// Most TLS handshakes (ECDHE cipher suites in TLS 1.2, and all supported TLS +// 1.3 modes) incorporate an ephemeral key exchange, most commonly using +// Elliptic Curve Diffie-Hellman (ECDH), as described in RFC 8422. The key +// exchange algorithm is negotiated separately from the cipher suite, using +// NamedGroup values, which define Diffie-Hellman groups. // -// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| -// values defined below. -OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, - size_t curves_len); - -// SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each -// element of |curves| should be a curve nid. It returns one on success and -// zero on failure. +// Historically, these values were known as "curves", in reference to ECDH, and +// some APIs refer to the original name. RFC 7919 renamed them to "groups" in +// reference to Diffie-Hellman in general. These values are also used to select +// experimental post-quantum KEMs. Though not Diffie-Hellman groups, KEMs can +// fill a similar role in TLS, so they use the same codepoints. // -// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| -// values defined below. -OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, - size_t curves_len); +// In TLS 1.2, the ECDH values also negotiate elliptic curves used in ECDSA. In +// TLS 1.3 and later, ECDSA curves are part of the signature algorithm. See +// |SSL_SIGN_*|. -// SSL_CTX_set1_curves_list sets the preferred curves for |ctx| to be the -// colon-separated list |curves|. Each element of |curves| should be a curve -// name (e.g. P-256, X25519, ...). It returns one on success and zero on -// failure. -OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); +// SSL_GROUP_* define TLS group IDs. +#define SSL_GROUP_SECP224R1 21 +#define SSL_GROUP_SECP256R1 23 +#define SSL_GROUP_SECP384R1 24 +#define SSL_GROUP_SECP521R1 25 +#define SSL_GROUP_X25519 29 +#define SSL_GROUP_X25519_KYBER768_DRAFT00 0x6399 -// SSL_set1_curves_list sets the preferred curves for |ssl| to be the -// colon-separated list |curves|. Each element of |curves| should be a curve -// name (e.g. P-256, X25519, ...). It returns one on success and zero on -// failure. -OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); +// SSL_CTX_set1_group_ids sets the preferred groups for |ctx| to |group_ids|. +// Each element of |group_ids| should be one of the |SSL_GROUP_*| constants. It +// returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set1_group_ids(SSL_CTX *ctx, + const uint16_t *group_ids, + size_t num_group_ids); -// SSL_CURVE_* define TLS curve IDs. -#define SSL_CURVE_SECP224R1 21 -#define SSL_CURVE_SECP256R1 23 -#define SSL_CURVE_SECP384R1 24 -#define SSL_CURVE_SECP521R1 25 -#define SSL_CURVE_X25519 29 -#define SSL_CURVE_CECPQ2 16696 +// SSL_set1_group_ids sets the preferred groups for |ssl| to |group_ids|. Each +// element of |group_ids| should be one of the |SSL_GROUP_*| constants. It +// returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set1_group_ids(SSL *ssl, const uint16_t *group_ids, + size_t num_group_ids); -// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently -// completed handshake or 0 if not applicable. +// SSL_get_group_id returns the ID of the group used by |ssl|'s most recently +// completed handshake, or 0 if not applicable. +OPENSSL_EXPORT uint16_t SSL_get_group_id(const SSL *ssl); + +// SSL_get_group_name returns a human-readable name for the group specified by +// the given TLS group ID, or NULL if the group is unknown. +OPENSSL_EXPORT const char *SSL_get_group_name(uint16_t group_id); + +// SSL_get_all_group_names outputs a list of possible strings +// |SSL_get_group_name| may return in this version of BoringSSL. It writes at +// most |max_out| entries to |out| and returns the total number it would have +// written, if |max_out| had been large enough. |max_out| may be initially set +// to zero to size the output. // -// TODO(davidben): This API currently does not work correctly if there is a -// renegotiation in progress. Fix this. -OPENSSL_EXPORT uint16_t SSL_get_curve_id(const SSL *ssl); +// This function is only intended to help initialize tables in callers that want +// possible strings pre-declared. This list would not be suitable to set a list +// of supported features. It is in no particular order, and may contain +// placeholder, experimental, or deprecated values that do not apply to every +// caller. Future versions of BoringSSL may also return strings not in this +// list, so this does not apply if, say, sending strings across services. +OPENSSL_EXPORT size_t SSL_get_all_group_names(const char **out, size_t max_out); -// SSL_get_curve_name returns a human-readable name for the curve specified by -// the given TLS curve id, or NULL if the curve is unknown. -OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); +// The following APIs also configure Diffie-Hellman groups, but use |NID_*| +// constants instead of |SSL_GROUP_*| constants. These are provided for OpenSSL +// compatibility. Where NIDs are unstable constants specific to OpenSSL and +// BoringSSL, group IDs are defined by the TLS protocol. Prefer the group ID +// representation if storing persistently, or exporting to another process or +// library. + +// SSL_CTX_set1_groups sets the preferred groups for |ctx| to be |groups|. Each +// element of |groups| should be a |NID_*| constant from nid.h. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, + size_t num_groups); + +// SSL_set1_groups sets the preferred groups for |ssl| to be |groups|. Each +// element of |groups| should be a |NID_*| constant from nid.h. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_set1_groups(SSL *ssl, const int *groups, + size_t num_groups); + +// SSL_CTX_set1_groups_list decodes |groups| as a colon-separated list of group +// names (e.g. "X25519" or "P-256") and sets |ctx|'s preferred groups to the +// result. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups); + +// SSL_set1_groups_list decodes |groups| as a colon-separated list of group +// names (e.g. "X25519" or "P-256") and sets |ssl|'s preferred groups to the +// result. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set1_groups_list(SSL *ssl, const char *groups); + +// SSL_get_negotiated_group returns the NID of the group used by |ssl|'s most +// recently completed handshake, or |NID_undef| if not applicable. +OPENSSL_EXPORT int SSL_get_negotiated_group(const SSL *ssl); // Certificate verification. @@ -2389,21 +2478,51 @@ OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); // SSL_CTX_set_verify configures certificate verification behavior. |mode| is // one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is -// used to customize certificate verification. See the behavior of -// |X509_STORE_CTX_set_verify_cb|. +// used to customize certificate verification, but is deprecated. See +// |X509_STORE_CTX_set_verify_cb| for details. // // The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with // |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +// +// WARNING: |callback| should be NULL. This callback does not replace the +// default certificate verification process and is, instead, called multiple +// times in the course of that process. It is very difficult to implement this +// callback safely, without inadvertently relying on implementation details or +// making incorrect assumptions about when the callback is called. +// +// Instead, use |SSL_CTX_set_custom_verify| or +// |SSL_CTX_set_cert_verify_callback| to customize certificate verification. +// Those callbacks can inspect the peer-sent chain, call |X509_verify_cert| and +// inspect the result, or perform other operations more straightforwardly. +// +// TODO(crbug.com/boringssl/426): We cite |X509_STORE_CTX_set_verify_cb| but +// haven't documented it yet. Later that will have a more detailed warning about +// why one should not use this callback. OPENSSL_EXPORT void SSL_CTX_set_verify( SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); // SSL_set_verify configures certificate verification behavior. |mode| is one of // the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to -// customize certificate verification. See the behavior of +// customize certificate verification, but is deprecated. See the behavior of // |X509_STORE_CTX_set_verify_cb|. // // The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with // |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +// +// WARNING: |callback| should be NULL. This callback does not replace the +// default certificate verification process and is, instead, called multiple +// times in the course of that process. It is very difficult to implement this +// callback safely, without inadvertently relying on implementation details or +// making incorrect assumptions about when the callback is called. +// +// Instead, use |SSL_set_custom_verify| or |SSL_CTX_set_cert_verify_callback| to +// customize certificate verification. Those callbacks can inspect the peer-sent +// chain, call |X509_verify_cert| and inspect the result, or perform other +// operations more straightforwardly. +// +// TODO(crbug.com/boringssl/426): We cite |X509_STORE_CTX_set_verify_cb| but +// haven't documented it yet. Later that will have a more detailed warning about +// why one should not use this callback. OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); @@ -2459,6 +2578,15 @@ OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))( int ok, X509_STORE_CTX *store_ctx); +// SSL_set1_host sets a DNS name that will be required to be present in the +// verified leaf certificate. It returns one on success and zero on error. +// +// Note: unless _some_ name checking is performed, certificate validation is +// ineffective. Simply checking that a host has some certificate from a CA is +// rarely meaningful—you have to check that the CA believed that the host was +// who you expect to be talking to. +OPENSSL_EXPORT int SSL_set1_host(SSL *ssl, const char *hostname); + // SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain // accepted in verification. This number does not include the leaf, so a depth // of 1 allows the leaf and one CA certificate. @@ -2632,6 +2760,11 @@ OPENSSL_EXPORT int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, size_t num_prefs); +// SSL_set_hostflags calls |X509_VERIFY_PARAM_set_hostflags| on the +// |X509_VERIFY_PARAM| associated with this |SSL*|. The |flags| argument +// should be one of the |X509_CHECK_*| constants. +OPENSSL_EXPORT void SSL_set_hostflags(SSL *ssl, unsigned flags); + // Client certificate CA list. // @@ -2697,7 +2830,7 @@ OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); // SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from // it. It returns a newly-allocated stack of the certificate subjects or NULL -// on error. +// on error. Duplicates in |file| are ignored. OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); // SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on @@ -2710,6 +2843,11 @@ OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, const char *file); +// SSL_add_bio_cert_subjects_to_stack behaves like +// |SSL_add_file_cert_subjects_to_stack| but reads from |bio|. +OPENSSL_EXPORT int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + BIO *bio); + // Server name indication. // @@ -2788,7 +2926,7 @@ OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); // WARNING: this function is dangerous because it breaks the usual return value // convention. OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, - unsigned protos_len); + size_t protos_len); // SSL_set_alpn_protos sets the client ALPN protocol list on |ssl| to |protos|. // |protos| must be in wire-format (i.e. a series of non-empty, 8-bit @@ -2799,7 +2937,7 @@ OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, // WARNING: this function is dangerous because it breaks the usual return value // convention. OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, - unsigned protos_len); + size_t protos_len); // SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called // during ClientHello processing in order to select an ALPN protocol from the @@ -3887,13 +4025,14 @@ OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, const uint8_t **out_write_iv, size_t *out_iv_len); -// SSL_get_key_block_len returns the length of |ssl|'s key block. It is an error -// to call this function during a handshake. +// SSL_get_key_block_len returns the length of |ssl|'s key block, for TLS 1.2 +// and below. It is an error to call this function during a handshake, or if +// |ssl| negotiated TLS 1.3. OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl); // SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s -// current connection state. It is an error to call this function during a -// handshake. +// current connection state, for TLS 1.2 and below. It is an error to call this +// function during a handshake, or if |ssl| negotiated TLS 1.3. OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len); @@ -3947,8 +4086,9 @@ OPENSSL_EXPORT int SSL_CTX_set_record_protocol_version(SSL_CTX *ctx, // those cases, BoringSSL will not predict a signature as there is no benefit. // Callers must allow for handshakes to complete without a predicted signature. // -// For now, only TLS 1.3 is hinted. TLS 1.2 will work, but the hints will be -// empty. +// Handshake hints are supported for TLS 1.3 and partially supported for +// TLS 1.2. TLS 1.2 resumption handshakes are not yet fully hinted. They will +// still work, but may not be as efficient. // SSL_serialize_capabilities writes an opaque byte string to |out| describing // some of |ssl|'s capabilities. It returns one on success and zero on error. @@ -4025,10 +4165,16 @@ OPENSSL_EXPORT int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, // |len| bytes from |buf| contain the handshake message, one-byte // ChangeCipherSpec body, and two-byte alert, respectively. // +// In connections that enable ECH, |cb| is additionally called with +// |content_type| = |SSL3_RT_CLIENT_HELLO_INNER| for each ClientHelloInner that +// is encrypted or decrypted. The |len| bytes from |buf| contain the +// ClientHelloInner, including the reconstructed outer extensions and handshake +// header. +// // For a V2ClientHello, |version| is |SSL2_VERSION|, |content_type| is zero, and // the |len| bytes from |buf| contain the V2ClientHello structure. OPENSSL_EXPORT void SSL_CTX_set_msg_callback( - SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, + SSL_CTX *ctx, void (*cb)(int is_write, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); // SSL_CTX_set_msg_callback_arg sets the |arg| parameter of the message @@ -4098,6 +4244,13 @@ enum ssl_renegotiate_mode_t BORINGSSL_ENUM_INT { // renegotiation attempts by a server. If |ssl| is a server, peer-initiated // renegotiations are *always* rejected and this function does nothing. // +// WARNING: Renegotiation is error-prone, complicates TLS's security properties, +// and increases its attack surface. When enabled, many common assumptions about +// BoringSSL's behavior no longer hold, and the calling application must handle +// more cases. Renegotiation is also incompatible with many application +// protocols, e.g. section 9.2.1 of RFC 7540. Many functions behave in ambiguous +// or undefined ways during a renegotiation. +// // The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set // at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to // allow one renegotiation, |ssl_renegotiate_freely| to allow all @@ -4119,6 +4272,20 @@ enum ssl_renegotiate_mode_t BORINGSSL_ENUM_INT { // e.g., ALPN must enable renegotiation before the handshake and conditionally // disable it afterwards. // +// When enabled, renegotiation can cause properties of |ssl|, such as the cipher +// suite, to change during the lifetime of the connection. More over, during a +// renegotiation, not all properties of the new handshake are available or fully +// established. In BoringSSL, most functions, such as |SSL_get_current_cipher|, +// report information from the most recently completed handshake, not the +// pending one. However, renegotiation may rerun handshake callbacks, such as +// |SSL_CTX_set_cert_cb|. Such callbacks must ensure they are acting on the +// desired versions of each property. +// +// BoringSSL does not reverify peer certificates on renegotiation and instead +// requires they match between handshakes, so certificate verification callbacks +// (see |SSL_CTX_set_custom_verify|) may assume |ssl| is in the initial +// handshake and use |SSL_get0_peer_certificates|, etc. +// // There is no support in BoringSSL for initiating renegotiations as a client // or server. OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl, @@ -4254,12 +4421,24 @@ OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( // respected on clients. OPENSSL_EXPORT void SSL_CTX_set_reverify_on_resume(SSL_CTX *ctx, int enabled); -// SSL_set_enforce_rsa_key_usage configures whether the keyUsage extension of -// RSA leaf certificates will be checked for consistency with the TLS -// usage. This parameter may be set late; it will not be read until after the +// SSL_set_enforce_rsa_key_usage configures whether, when |ssl| is a client +// negotiating TLS 1.2 or below, the keyUsage extension of RSA leaf server +// certificates will be checked for consistency with the TLS usage. In all other +// cases, this check is always enabled. +// +// This parameter may be set late; it will not be read until after the // certificate verification callback. OPENSSL_EXPORT void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled); +// SSL_was_key_usage_invalid returns one if |ssl|'s handshake succeeded despite +// using TLS parameters which were incompatible with the leaf certificate's +// keyUsage extension. Otherwise, it returns zero. +// +// If |SSL_set_enforce_rsa_key_usage| is enabled or not applicable, this +// function will always return zero because key usages will be consistently +// checked. +OPENSSL_EXPORT int SSL_was_key_usage_invalid(const SSL *ssl); + // SSL_ST_* are possible values for |SSL_state|, the bitmasks that make them up, // and some historical values for compatibility. Only |SSL_ST_INIT| and // |SSL_ST_OK| are ever returned. @@ -4446,13 +4625,6 @@ OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, // SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); -// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the -// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is -// responsible for calling |OPENSSL_free| on the result. -// -// Use |SSL_CIPHER_standard_name| instead. -OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); - typedef void COMP_METHOD; typedef struct ssl_comp_st SSL_COMP; @@ -4791,6 +4963,21 @@ OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl); // For example, "TLSv1.2" or "DTLSv1". OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl); +// SSL_get_all_version_names outputs a list of possible strings +// |SSL_get_version| may return in this version of BoringSSL. It writes at most +// |max_out| entries to |out| and returns the total number it would have +// written, if |max_out| had been large enough. |max_out| may be initially set +// to zero to size the output. +// +// This function is only intended to help initialize tables in callers that want +// possible strings pre-declared. This list would not be suitable to set a list +// of supported features. It is in no particular order, and may contain +// placeholder, experimental, or deprecated values that do not apply to every +// caller. Future versions of BoringSSL may also return strings not in this +// list, so this does not apply if, say, sending strings across services. +OPENSSL_EXPORT size_t SSL_get_all_version_names(const char **out, + size_t max_out); + // SSL_get_cipher_list returns the name of the |n|th cipher in the output of // |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| instead. OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n); @@ -4915,12 +5102,12 @@ OPENSSL_EXPORT int SSL_state(const SSL *ssl); // Use |SSL_CTX_set_quiet_shutdown| instead. OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); -// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list -// containing |ec_key|'s curve. +// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_groups| with a one-element list +// containing |ec_key|'s curve. The remainder of |ec_key| is ignored. OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); -// SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing -// |ec_key|'s curve. +// SSL_set_tmp_ecdh calls |SSL_set1_groups| with a one-element list containing +// |ec_key|'s curve. The remainder of |ec_key| is ignored. OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); // SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls @@ -5069,12 +5256,89 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg); SSL_R_TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE #define SSL_R_TLSV1_CERTIFICATE_REQUIRED SSL_R_TLSV1_ALERT_CERTIFICATE_REQUIRED -// SSL_CIPHER_get_value calls |SSL_CIPHER_get_protocol_id|. +// The following symbols are compatibility aliases for equivalent functions that +// use the newer "group" terminology. New code should use the new functions for +// consistency, but we do not plan to remove these aliases. +#define SSL_CTX_set1_curves SSL_CTX_set1_groups +#define SSL_set1_curves SSL_set1_groups +#define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +#define SSL_set1_curves_list SSL_set1_groups_list +#define SSL_get_curve_id SSL_get_group_id +#define SSL_get_curve_name SSL_get_group_name +#define SSL_get_all_curve_names SSL_get_all_group_names +#define SSL_CURVE_SECP224R1 SSL_GROUP_SECP224R1 +#define SSL_CURVE_SECP256R1 SSL_GROUP_SECP256R1 +#define SSL_CURVE_SECP384R1 SSL_GROUP_SECP384R1 +#define SSL_CURVE_SECP521R1 SSL_GROUP_SECP521R1 +#define SSL_CURVE_X25519 SSL_GROUP_X25519 +#define SSL_CURVE_X25519_KYBER768_DRAFT00 SSL_GROUP_X25519_KYBER768_DRAFT00 + +// TLSEXT_nid_unknown is a constant used in OpenSSL for +// |SSL_get_negotiated_group| to return an unrecognized group. BoringSSL never +// returns this value, but we define this constant for compatibility. +#define TLSEXT_nid_unknown 0x1000000 + + +// Compliance policy configurations // -// TODO(davidben): |SSL_CIPHER_get_value| was our name for this function, but -// upstream added it as |SSL_CIPHER_get_protocol_id|. Switch callers to the new -// name and remove this one. -OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); +// A TLS connection has a large number of different parameters. Some are well +// known, like cipher suites, but many are obscure and configuration functions +// for them may not exist. These policy controls allow broad configuration +// goals to be specified so that they can flow down to all the different +// parameters of a TLS connection. + +enum ssl_compliance_policy_t BORINGSSL_ENUM_INT { + // ssl_compliance_policy_none does nothing. However, since setting this + // doesn't undo other policies it's an error to try and set it. + ssl_compliance_policy_none, + + // ssl_policy_fips_202205 configures a TLS connection to use: + // * TLS 1.2 or 1.3 + // * For TLS 1.2, only ECDHE_[RSA|ECDSA]_WITH_AES_*_GCM_SHA*. + // * For TLS 1.3, only AES-GCM + // * P-256 or P-384 for key agreement. + // * For server signatures, only PKCS#1/PSS with SHA256/384/512, or ECDSA + // with P-256 or P-384. + // + // Note: this policy can be configured even if BoringSSL has not been built in + // FIPS mode. Call |FIPS_mode| to check that. + // + // Note: this setting aids with compliance with NIST requirements but does not + // guarantee it. Careful reading of SP 800-52r2 is recommended. + ssl_compliance_policy_fips_202205, + + // ssl_compliance_policy_wpa3_192_202304 configures a TLS connection to use: + // * TLS 1.2 or 1.3. + // * For TLS 1.2, only TLS_ECDHE_[ECDSA|RSA]_WITH_AES_256_GCM_SHA384. + // * For TLS 1.3, only AES-256-GCM. + // * P-384 for key agreement. + // * For handshake signatures, only ECDSA with P-384 and SHA-384, or RSA + // with SHA-384 or SHA-512. + // + // No limitations on the certificate chain nor leaf public key are imposed, + // other than by the supported signature algorithms. But WPA3's "192-bit" + // mode requires at least P-384 or 3072-bit along the chain. The caller must + // enforce this themselves on the verified chain using functions such as + // `X509_STORE_CTX_get0_chain`. + // + // Note that this setting is less secure than the default. The + // implementation risks of using a more obscure primitive like P-384 + // dominate other considerations. + ssl_compliance_policy_wpa3_192_202304, +}; + +// SSL_CTX_set_compliance_policy configures various aspects of |ctx| based on +// the given policy requirements. Subsequently calling other functions that +// configure |ctx| may override |policy|, or may not. This should be the final +// configuration function called in order to have defined behaviour. It's a +// fatal error if |policy| is |ssl_compliance_policy_none|. +OPENSSL_EXPORT int SSL_CTX_set_compliance_policy( + SSL_CTX *ctx, enum ssl_compliance_policy_t policy); + +// SSL_set_compliance_policy acts the same as |SSL_CTX_set_compliance_policy|, +// but only configures a single |SSL*|. +OPENSSL_EXPORT int SSL_set_compliance_policy( + SSL *ssl, enum ssl_compliance_policy_t policy); // Nodejs compatibility section (hidden). @@ -5114,6 +5378,7 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); #define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist #define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_GET_NEGOTIATED_GROUP doesnt_exist #define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist #define SSL_CTRL_GET_READ_AHEAD doesnt_exist #define SSL_CTRL_GET_RI_SUPPORT doesnt_exist @@ -5129,6 +5394,8 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); #define SSL_CTRL_SESS_NUMBER doesnt_exist #define SSL_CTRL_SET_CURVES doesnt_exist #define SSL_CTRL_SET_CURVES_LIST doesnt_exist +#define SSL_CTRL_SET_GROUPS doesnt_exist +#define SSL_CTRL_SET_GROUPS_LIST doesnt_exist #define SSL_CTRL_SET_ECDH_AUTO doesnt_exist #define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist #define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist @@ -5177,7 +5444,7 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); #define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size #define SSL_CTX_set0_chain SSL_CTX_set0_chain #define SSL_CTX_set1_chain SSL_CTX_set1_chain -#define SSL_CTX_set1_curves SSL_CTX_set1_curves +#define SSL_CTX_set1_groups SSL_CTX_set1_groups #define SSL_CTX_set_max_cert_list SSL_CTX_set_max_cert_list #define SSL_CTX_set_max_send_fragment SSL_CTX_set_max_send_fragment #define SSL_CTX_set_mode SSL_CTX_set_mode @@ -5202,6 +5469,7 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); #define SSL_get0_chain_certs SSL_get0_chain_certs #define SSL_get_max_cert_list SSL_get_max_cert_list #define SSL_get_mode SSL_get_mode +#define SSL_get_negotiated_group SSL_get_negotiated_group #define SSL_get_options SSL_get_options #define SSL_get_secure_renegotiation_support \ SSL_get_secure_renegotiation_support @@ -5210,7 +5478,7 @@ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher); #define SSL_session_reused SSL_session_reused #define SSL_set0_chain SSL_set0_chain #define SSL_set1_chain SSL_set1_chain -#define SSL_set1_curves SSL_set1_curves +#define SSL_set1_groups SSL_set1_groups #define SSL_set_max_cert_list SSL_set_max_cert_list #define SSL_set_max_send_fragment SSL_set_max_send_fragment #define SSL_set_mode SSL_set_mode @@ -5243,62 +5511,6 @@ BORINGSSL_MAKE_UP_REF(SSL_ECH_KEYS, SSL_ECH_KEYS_up_ref) BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) BORINGSSL_MAKE_UP_REF(SSL_SESSION, SSL_SESSION_up_ref) -enum class OpenRecordResult { - kOK, - kDiscard, - kIncompleteRecord, - kAlertCloseNotify, - kError, -}; - -// *** EXPERIMENTAL -- DO NOT USE *** -// -// OpenRecord decrypts the first complete SSL record from |in| in-place, sets -// |out| to the decrypted application data, and |out_record_len| to the length -// of the encrypted record. Returns: -// - kOK if an application-data record was successfully decrypted and verified. -// - kDiscard if a record was sucessfully processed, but should be discarded. -// - kIncompleteRecord if |in| did not contain a complete record. -// - kAlertCloseNotify if a record was successfully processed but is a -// close_notify alert. -// - kError if an error occurred or the record is invalid. |*out_alert| will be -// set to an alert to emit, or zero if no alert should be emitted. -OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span *out, - size_t *out_record_len, - uint8_t *out_alert, - Span in); - -OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len); - -// SealRecordSuffixLen returns the length of the suffix written by |SealRecord|. -// -// |plaintext_len| must be equal to the size of the plaintext passed to -// |SealRecord|. -// -// |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned -// suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. -OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len); - -// *** EXPERIMENTAL -- DO NOT USE *** -// -// SealRecord encrypts the cleartext of |in| and scatters the resulting TLS -// application data record between |out_prefix|, |out|, and |out_suffix|. It -// returns true on success or false if an error occurred. -// -// The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of -// |out| must equal the length of |in|, which must not exceed -// |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal -// |SealRecordSuffixLen|. -// -// If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting. -// |SealRecordPrefixLen| accounts for the required overhead if that is the case. -// -// |out| may equal |in| to encrypt in-place but may not otherwise alias. -// |out_prefix| and |out_suffix| may not alias anything. -OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span out_prefix, - Span out, Span out_suffix, - Span in); - // *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** // @@ -5356,6 +5568,18 @@ OPENSSL_EXPORT bool SSL_get_traffic_secrets( const SSL *ssl, Span *out_read_traffic_secret, Span *out_write_traffic_secret); +// SSL_CTX_set_aes_hw_override_for_testing sets |override_value| to +// override checking for aes hardware support for testing. If |override_value| +// is set to true, the library will behave as if aes hardware support is +// present. If it is set to false, the library will behave as if aes hardware +// support is not present. +OPENSSL_EXPORT void SSL_CTX_set_aes_hw_override_for_testing( + SSL_CTX *ctx, bool override_value); + +// SSL_set_aes_hw_override_for_testing acts the same as +// |SSL_CTX_set_aes_override_for_testing| but only configures a single |SSL*|. +OPENSSL_EXPORT void SSL_set_aes_hw_override_for_testing(SSL *ssl, + bool override_value); BSSL_NAMESPACE_END @@ -5584,7 +5808,7 @@ BSSL_NAMESPACE_END #define SSL_R_INVALID_ECH_PUBLIC_NAME 317 #define SSL_R_INVALID_ECH_CONFIG_LIST 318 #define SSL_R_ECH_REJECTED 319 -#define SSL_R_OUTER_EXTENSION_NOT_FOUND 320 +#define SSL_R_INVALID_OUTER_EXTENSION 320 #define SSL_R_INCONSISTENT_ECH_NEGOTIATION 321 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 diff --git a/third_party/boringssl/kit/src/include/openssl/ssl3.h b/third_party/boringssl/kit/src/include/openssl/ssl3.h index e3910f00..221adf08 100644 --- a/third_party/boringssl/kit/src/include/openssl/ssl3.h +++ b/third_party/boringssl/kit/src/include/openssl/ssl3.h @@ -1,4 +1,3 @@ -/* ssl/ssl3.h */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -118,7 +117,6 @@ #define OPENSSL_HEADER_SSL3_H #include -#include #ifdef __cplusplus extern "C" { @@ -251,10 +249,6 @@ extern "C" { #define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ (EVP_AEAD_MAX_OVERHEAD + EVP_AEAD_MAX_NONCE_LENGTH) -OPENSSL_STATIC_ASSERT(SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= - SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD, - "max overheads are inconsistent"); - // SSL3_RT_MAX_COMPRESSED_LENGTH is an alias for // |SSL3_RT_MAX_PLAIN_LENGTH|. Compression is gone, so don't include the // compression overhead. @@ -275,6 +269,7 @@ OPENSSL_STATIC_ASSERT(SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= // Pseudo content type for SSL/TLS header info #define SSL3_RT_HEADER 0x100 +#define SSL3_RT_CLIENT_HELLO_INNER 0x101 #define SSL3_AL_WARNING 1 #define SSL3_AL_FATAL 2 diff --git a/third_party/boringssl/kit/src/include/openssl/stack.h b/third_party/boringssl/kit/src/include/openssl/stack.h index 04e942cb..7d5d4d7e 100644 --- a/third_party/boringssl/kit/src/include/openssl/stack.h +++ b/third_party/boringssl/kit/src/include/openssl/stack.h @@ -59,8 +59,6 @@ #include -#include - #if defined(__cplusplus) extern "C" { #endif @@ -69,185 +67,301 @@ extern "C" { // A stack, in OpenSSL, is an array of pointers. They are the most commonly // used collection object. // -// This file defines macros for type safe use of the stack functions. A stack -// of a specific type of object has type |STACK_OF(type)|. This can be defined -// (once) with |DEFINE_STACK_OF(type)| and declared where needed with -// |DECLARE_STACK_OF(type)|. For example: +// This file defines macros for type-safe use of the stack functions. A stack +// type is named like |STACK_OF(FOO)| and is accessed with functions named +// like |sk_FOO_*|. Note the stack will typically contain /pointers/ to |FOO|. // -// typedef struct foo_st { -// int bar; -// } FOO; -// -// DEFINE_STACK_OF(FOO) -// -// Although note that the stack will contain /pointers/ to |FOO|. -// -// A macro will be defined for each of the sk_* functions below. For -// STACK_OF(FOO), the macros would be sk_FOO_new, sk_FOO_pop etc. +// The |DECLARE_STACK_OF| macro makes |STACK_OF(FOO)| available, and +// |DEFINE_STACK_OF| makes the corresponding functions available. -// stack_free_func is a function that frees an element in a stack. Note its -// actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be -// passed a type-specific wrapper to call it correctly. -typedef void (*stack_free_func)(void *ptr); - -// stack_copy_func is a function that copies an element in a stack. Note its -// actual type is T *(*)(T *) for some T. Low-level |sk_*| functions will be -// passed a type-specific wrapper to call it correctly. -typedef void *(*stack_copy_func)(void *ptr); - -// stack_cmp_func is a comparison function that returns a value < 0, 0 or > 0 -// if |*a| is less than, equal to or greater than |*b|, respectively. Note the -// extra indirection - the function is given a pointer to a pointer to the -// element. This differs from the usual qsort/bsearch comparison function. -// -// Note its actual type is int (*)(const T **, const T **). Low-level |sk_*| -// functions will be passed a type-specific wrapper to call it correctly. -typedef int (*stack_cmp_func)(const void **a, const void **b); - -// stack_st contains an array of pointers. It is not designed to be used -// directly, rather the wrapper macros should be used. -typedef struct stack_st { - // num contains the number of valid pointers in |data|. - size_t num; - void **data; - // sorted is non-zero if the values pointed to by |data| are in ascending - // order, based on |comp|. - int sorted; - // num_alloc contains the number of pointers allocated in the buffer pointed - // to by |data|, which may be larger than |num|. - size_t num_alloc; - // comp is an optional comparison function. - stack_cmp_func comp; -} _STACK; - +// Defining stacks. +// STACK_OF expands to the stack type for |type|. #define STACK_OF(type) struct stack_st_##type +// DECLARE_STACK_OF declares the |STACK_OF(type)| type. It does not make the +// corresponding |sk_type_*| functions available. This macro should be used in +// files which only need the type. #define DECLARE_STACK_OF(type) STACK_OF(type); -// These are the raw stack functions, you shouldn't be using them. Rather you -// should be using the type stack macros implemented above. +// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements +// are |type| *. This macro makes the |sk_name_*| functions available. +// +// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. +#define DEFINE_NAMED_STACK_OF(name, type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(name, type, false) -// sk_new creates a new, empty stack with the given comparison function, which -// may be zero. It returns the new stack or NULL on allocation failure. -OPENSSL_EXPORT _STACK *sk_new(stack_cmp_func comp); +// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are +// |type| *. This macro makes the |sk_type_*| functions available. +// +// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. +#define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type) -// sk_new_null creates a new, empty stack. It returns the new stack or NULL on -// allocation failure. -OPENSSL_EXPORT _STACK *sk_new_null(void); +// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are const |type| *. This macro makes the |sk_type_*| functions available. +// +// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. +#define DEFINE_CONST_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) -// sk_num returns the number of elements in |s|. -OPENSSL_EXPORT size_t sk_num(const _STACK *sk); -// sk_zero resets |sk| to the empty state but does nothing to free the +// Using stacks. +// +// After the |DEFINE_STACK_OF| macro is used, the following functions are +// available. + +#if 0 // Sample + +// sk_SAMPLE_free_func is a callback to free an element in a stack. +typedef void (*sk_SAMPLE_free_func)(SAMPLE *); + +// sk_SAMPLE_copy_func is a callback to copy an element in a stack. It should +// return the copy or NULL on error. +typedef SAMPLE *(*sk_SAMPLE_copy_func)(const SAMPLE *); + +// sk_SAMPLE_cmp_func is a callback to compare |*a| to |*b|. It should return a +// value < 0, 0, or > 0 if |*a| is less than, equal to, or greater than |*b|, +// respectively. Note the extra indirection - the function is given a pointer +// to a pointer to the element. This is the |qsort|/|bsearch| comparison +// function applied to an array of |SAMPLE*|. +typedef int (*sk_SAMPLE_cmp_func)(const SAMPLE *const *a, + const SAMPLE *const *b); + +// sk_SAMPLE_new creates a new, empty stack with the given comparison function, +// which may be NULL. It returns the new stack or NULL on allocation failure. +STACK_OF(SAMPLE) *sk_SAMPLE_new(sk_SAMPLE_cmp_func comp); + +// sk_SAMPLE_new_null creates a new, empty stack. It returns the new stack or +// NULL on allocation failure. +STACK_OF(SAMPLE) *sk_SAMPLE_new_null(void); + +// sk_SAMPLE_num returns the number of elements in |sk|. It is safe to cast this +// value to |int|. |sk| is guaranteed to have at most |INT_MAX| elements. +size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); + +// sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the // individual elements themselves. -OPENSSL_EXPORT void sk_zero(_STACK *sk); +void sk_SAMPLE_zero(STACK_OF(SAMPLE) *sk); -// sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of +// sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of // range. -OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i); +SAMPLE *sk_SAMPLE_value(const STACK_OF(SAMPLE) *sk, size_t i); -// sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out -// of range, it returns NULL. -OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p); +// sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| +// is out of range, it returns NULL. +SAMPLE *sk_SAMPLE_set(STACK_OF(SAMPLE) *sk, size_t i, SAMPLE *p); -// sk_free frees the given stack and array of pointers, but does nothing to -// free the individual elements. Also see |sk_pop_free_ex|. -OPENSSL_EXPORT void sk_free(_STACK *sk); +// sk_SAMPLE_free frees |sk|, but does nothing to free the individual elements. +// Use |sk_SAMPLE_pop_free| to also free the elements. +void sk_SAMPLE_free(STACK_OF(SAMPLE) *sk); -// sk_pop_free_ex calls |free_func| on each element in the stack and then frees -// the stack itself. Note this corresponds to |sk_FOO_pop_free|. It is named -// |sk_pop_free_ex| as a workaround for existing code calling an older version -// of |sk_pop_free|. -OPENSSL_EXPORT void sk_pop_free_ex(_STACK *sk, - void (*call_free_func)(stack_free_func, - void *), - stack_free_func free_func); +// sk_SAMPLE_pop_free calls |free_func| on each element in |sk| and then +// frees the stack itself. +void sk_SAMPLE_pop_free(STACK_OF(SAMPLE) *sk, sk_SAMPLE_free_func free_func); -// sk_insert inserts |p| into the stack at index |where|, moving existing +// sk_SAMPLE_insert inserts |p| into the stack at index |where|, moving existing // elements if needed. It returns the length of the new stack, or zero on // error. -OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); +size_t sk_SAMPLE_insert(STACK_OF(SAMPLE) *sk, SAMPLE *p, size_t where); -// sk_delete removes the pointer at index |where|, moving other elements down -// if needed. It returns the removed pointer, or NULL if |where| is out of +// sk_SAMPLE_delete removes the pointer at index |where|, moving other elements +// down if needed. It returns the removed pointer, or NULL if |where| is out of // range. -OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); +SAMPLE *sk_SAMPLE_delete(STACK_OF(SAMPLE) *sk, size_t where); -// sk_delete_ptr removes, at most, one instance of |p| from the stack based on +// sk_SAMPLE_delete_ptr removes, at most, one instance of |p| from |sk| based on // pointer equality. If an instance of |p| is found then |p| is returned, // otherwise it returns NULL. -OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, const void *p); +SAMPLE *sk_SAMPLE_delete_ptr(STACK_OF(SAMPLE) *sk, const SAMPLE *p); -// sk_find returns the first value in the stack equal to |p|. If a comparison -// function has been set on the stack, equality is defined by it, otherwise -// pointer equality is used. If the stack is sorted, then a binary search is -// used, otherwise a linear search is performed. If a matching element is found, -// its index is written to -// |*out_index| (if |out_index| is not NULL) and one is returned. Otherwise zero -// is returned. +// sk_SAMPLE_delete_if_func is the callback function for |sk_SAMPLE_delete_if|. +// It should return one to remove |p| and zero to keep it. +typedef int (*sk_SAMPLE_delete_if_func)(SAMPLE *p, void *data); + +// sk_SAMPLE_delete_if calls |func| with each element of |sk| and removes the +// entries where |func| returned one. This function does not free or return +// removed pointers so, if |sk| owns its contents, |func| should release the +// pointers prior to returning one. +void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, + void *data); + +// sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison +// function determines equality, or pointer equality if |sk| has no comparison +// function. +// +// If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary +// search. Otherwise it performs a linear search. If it finds a matching +// element, it writes the index to |*out_index| (if |out_index| is not NULL) and +// returns one. Otherwise, it returns zero. // // Note this differs from OpenSSL. The type signature is slightly different, and -// OpenSSL's sk_find will implicitly sort |sk| if it has a comparison function +// OpenSSL's version will implicitly sort |sk| if it has a comparison function // defined. -OPENSSL_EXPORT int sk_find(const _STACK *sk, size_t *out_index, const void *p, - int (*call_cmp_func)(stack_cmp_func, const void **, - const void **)); +int sk_SAMPLE_find(const STACK_OF(SAMPLE) *sk, size_t *out_index, + const SAMPLE *p); -// sk_shift removes and returns the first element in the stack, or returns NULL -// if the stack is empty. -OPENSSL_EXPORT void *sk_shift(_STACK *sk); +// sk_SAMPLE_shift removes and returns the first element in |sk|, or NULL if +// |sk| is empty. +SAMPLE *sk_SAMPLE_shift(STACK_OF(SAMPLE) *sk); -// sk_push appends |p| to the stack and returns the length of the new stack, or -// 0 on allocation failure. -OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p); +// sk_SAMPLE_push appends |p| to |sk| and returns the length of the new stack, +// or 0 on allocation failure. +size_t sk_SAMPLE_push(STACK_OF(SAMPLE) *sk, SAMPLE *p); -// sk_pop returns and removes the last element on the stack, or NULL if the -// stack is empty. -OPENSSL_EXPORT void *sk_pop(_STACK *sk); +// sk_SAMPLE_pop removes and returns the last element of |sk|, or NULL if |sk| +// is empty. +SAMPLE *sk_SAMPLE_pop(STACK_OF(SAMPLE) *sk); -// sk_dup performs a shallow copy of a stack and returns the new stack, or NULL -// on error. -OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk); +// sk_SAMPLE_dup performs a shallow copy of a stack and returns the new stack, +// or NULL on error. Use |sk_SAMPLE_deep_copy| to also copy the elements. +STACK_OF(SAMPLE) *sk_SAMPLE_dup(const STACK_OF(SAMPLE) *sk); -// sk_sort sorts the elements of |sk| into ascending order based on the -// comparison function. The stack maintains a |sorted| flag and sorting an +// sk_SAMPLE_sort sorts the elements of |sk| into ascending order based on the +// comparison function. The stack maintains a "sorted" flag and sorting an // already sorted stack is a no-op. -OPENSSL_EXPORT void sk_sort(_STACK *sk); +void sk_SAMPLE_sort(STACK_OF(SAMPLE) *sk); -// sk_is_sorted returns one if |sk| is known to be sorted and zero +// sk_SAMPLE_is_sorted returns one if |sk| is known to be sorted and zero // otherwise. -OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk); +int sk_SAMPLE_is_sorted(const STACK_OF(SAMPLE) *sk); -// sk_set_cmp_func sets the comparison function to be used by |sk| and returns -// the previous one. -OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp); +// sk_SAMPLE_set_cmp_func sets the comparison function to be used by |sk| and +// returns the previous one. +sk_SAMPLE_cmp_func sk_SAMPLE_set_cmp_func(STACK_OF(SAMPLE) *sk, + sk_SAMPLE_cmp_func comp); -// sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in -// |sk| by using |copy_func|. If an error occurs, |free_func| is used to free -// any copies already made and NULL is returned. -OPENSSL_EXPORT _STACK *sk_deep_copy( - const _STACK *sk, void *(*call_copy_func)(stack_copy_func, void *), - stack_copy_func copy_func, void (*call_free_func)(stack_free_func, void *), - stack_free_func free_func); +// sk_SAMPLE_deep_copy performs a copy of |sk| and of each of the non-NULL +// elements in |sk| by using |copy_func|. If an error occurs, it calls +// |free_func| to free any copies already made and returns NULL. +STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, + sk_SAMPLE_copy_func copy_func, + sk_SAMPLE_free_func free_func); + +#endif // Sample -// Deprecated functions. +// Private functions. +// +// The |sk_*| functions generated above are implemented internally using the +// type-erased functions below. Callers should use the typed wrappers instead. +// When using the type-erased functions, callers are responsible for ensuring +// the underlying types are correct. Casting pointers to the wrong types will +// result in memory errors. + +// OPENSSL_sk_free_func is a function that frees an element in a stack. Note its +// actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be +// passed a type-specific wrapper to call it correctly. +typedef void (*OPENSSL_sk_free_func)(void *ptr); + +// OPENSSL_sk_copy_func is a function that copies an element in a stack. Note +// its actual type is T *(*)(const T *) for some T. Low-level |sk_*| functions +// will be passed a type-specific wrapper to call it correctly. +typedef void *(*OPENSSL_sk_copy_func)(const void *ptr); + +// OPENSSL_sk_cmp_func is a comparison function that returns a value < 0, 0 or > +// 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note +// the extra indirection - the function is given a pointer to a pointer to the +// element. This differs from the usual qsort/bsearch comparison function. +// +// Note its actual type is |int (*)(const T *const *a, const T *const *b)|. +// Low-level |sk_*| functions will be passed a type-specific wrapper to call it +// correctly. +typedef int (*OPENSSL_sk_cmp_func)(const void *const *a, const void *const *b); + +// OPENSSL_sk_delete_if_func is the generic version of +// |sk_SAMPLE_delete_if_func|. +typedef int (*OPENSSL_sk_delete_if_func)(void *obj, void *data); + +// The following function types call the above type-erased signatures with the +// true types. +typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *); +typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *); +typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *, + const void *); +typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, + void *); + +// An OPENSSL_STACK contains an array of pointers. It is not designed to be used +// directly, rather the wrapper macros should be used. +typedef struct stack_st OPENSSL_STACK; + +// The following are raw stack functions. They implement the corresponding typed +// |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be +// using them. Rather, callers should use the typed functions. +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_EXPORT size_t OPENSSL_sk_num(const OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_zero(OPENSSL_STACK *sk); +OPENSSL_EXPORT void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i); +OPENSSL_EXPORT void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *p); +OPENSSL_EXPORT void OPENSSL_sk_free(OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex( + OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func); +OPENSSL_EXPORT size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, + size_t where); +OPENSSL_EXPORT void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where); +OPENSSL_EXPORT void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p); +OPENSSL_EXPORT void OPENSSL_sk_delete_if( + OPENSSL_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, + OPENSSL_sk_delete_if_func func, void *data); +OPENSSL_EXPORT int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, + const void *p, + OPENSSL_sk_call_cmp_func call_cmp_func); +OPENSSL_EXPORT void *OPENSSL_sk_shift(OPENSSL_STACK *sk); +OPENSSL_EXPORT size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p); +OPENSSL_EXPORT void *OPENSSL_sk_pop(OPENSSL_STACK *sk); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk); +OPENSSL_EXPORT void OPENSSL_sk_sort(OPENSSL_STACK *sk, + OPENSSL_sk_call_cmp_func call_cmp_func); +OPENSSL_EXPORT int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk); +OPENSSL_EXPORT OPENSSL_sk_cmp_func +OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_cmp_func comp); +OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_deep_copy( + const OPENSSL_STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, + OPENSSL_sk_copy_func copy_func, OPENSSL_sk_call_free_func call_free_func, + OPENSSL_sk_free_func free_func); + + +// Deprecated private functions (hidden). +// +// TODO(crbug.com/boringssl/499): Migrate callers to the typed wrappers, or at +// least the new names and remove the old ones. + +typedef OPENSSL_STACK _STACK; + +OPENSSL_INLINE OPENSSL_STACK *sk_new_null(void) { + return OPENSSL_sk_new_null(); +} + +OPENSSL_INLINE size_t sk_num(const OPENSSL_STACK *sk) { + return OPENSSL_sk_num(sk); +} + +OPENSSL_INLINE void *sk_value(const OPENSSL_STACK *sk, size_t i) { + return OPENSSL_sk_value(sk, i); +} + +OPENSSL_INLINE void sk_free(OPENSSL_STACK *sk) { OPENSSL_sk_free(sk); } + +OPENSSL_INLINE size_t sk_push(OPENSSL_STACK *sk, void *p) { + return OPENSSL_sk_push(sk, p); +} + +OPENSSL_INLINE void *sk_pop(OPENSSL_STACK *sk) { return OPENSSL_sk_pop(sk); } // sk_pop_free behaves like |sk_pop_free_ex| but performs an invalid function // pointer cast. It exists because some existing callers called |sk_pop_free| // directly. // // TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. -OPENSSL_EXPORT void sk_pop_free(_STACK *sk, stack_free_func free_func); +OPENSSL_EXPORT void sk_pop_free(OPENSSL_STACK *sk, + OPENSSL_sk_free_func free_func); -// Defining stack types. -// -// This set of macros is used to emit the typed functions that act on a -// |STACK_OF(T)|. - #if !defined(BORINGSSL_NO_CXX) extern "C++" { BSSL_NAMESPACE_BEGIN @@ -277,155 +391,159 @@ BSSL_NAMESPACE_END #endif #define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ + /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ + * to the wrong type. While the cast itself is valid, it is often a bug \ + * because calling it through the cast is UB. However, we never actually \ + * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ + * function pointer. (C does not guarantee function pointers fit in \ + * |void*|, and GCC will warn on this.) Thus we just disable the false \ + * positive warning. */ \ + OPENSSL_MSVC_PRAGMA(warning(push)) \ + OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ + \ DECLARE_STACK_OF(name) \ \ - typedef void (*stack_##name##_free_func)(ptrtype); \ - typedef ptrtype (*stack_##name##_copy_func)(ptrtype); \ - typedef int (*stack_##name##_cmp_func)(constptrtype *a, constptrtype *b); \ + typedef void (*sk_##name##_free_func)(ptrtype); \ + typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ + typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ + constptrtype const *); \ + typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ \ - OPENSSL_INLINE void sk_##name##_call_free_func(stack_free_func free_func, \ - void *ptr) { \ - ((stack_##name##_free_func)free_func)((ptrtype)ptr); \ + OPENSSL_INLINE void sk_##name##_call_free_func( \ + OPENSSL_sk_free_func free_func, void *ptr) { \ + ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ } \ \ - OPENSSL_INLINE void *sk_##name##_call_copy_func(stack_copy_func copy_func, \ - void *ptr) { \ - return (void *)((stack_##name##_copy_func)copy_func)((ptrtype)ptr); \ + OPENSSL_INLINE void *sk_##name##_call_copy_func( \ + OPENSSL_sk_copy_func copy_func, const void *ptr) { \ + return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ } \ \ - OPENSSL_INLINE int sk_##name##_call_cmp_func( \ - stack_cmp_func cmp_func, const void **a, const void **b) { \ - constptrtype a_ptr = (constptrtype)*a; \ - constptrtype b_ptr = (constptrtype)*b; \ - return ((stack_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ + OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ + const void *a, const void *b) { \ + constptrtype a_ptr = (constptrtype)a; \ + constptrtype b_ptr = (constptrtype)b; \ + /* |cmp_func| expects an extra layer of pointers to match qsort. */ \ + return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ } \ \ - OPENSSL_INLINE STACK_OF(name) * \ - sk_##name##_new(stack_##name##_cmp_func comp) { \ - return (STACK_OF(name) *)sk_new((stack_cmp_func)comp); \ + OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ + OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ + return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ + } \ + \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ } \ \ OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ - return (STACK_OF(name) *)sk_new_null(); \ + return (STACK_OF(name) *)OPENSSL_sk_new_null(); \ } \ \ OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ - return sk_num((const _STACK *)sk); \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ } \ \ OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ - sk_zero((_STACK *)sk); \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ size_t i) { \ - return (ptrtype)sk_value((const _STACK *)sk, i); \ + return (ptrtype)OPENSSL_sk_value((const OPENSSL_STACK *)sk, i); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ ptrtype p) { \ - return (ptrtype)sk_set((_STACK *)sk, i, (void *)p); \ + return (ptrtype)OPENSSL_sk_set((OPENSSL_STACK *)sk, i, (void *)p); \ } \ \ - OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) * sk) { \ - sk_free((_STACK *)sk); \ + OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ } \ \ - OPENSSL_INLINE void sk_##name##_pop_free( \ - STACK_OF(name) * sk, stack_##name##_free_func free_func) { \ - sk_pop_free_ex((_STACK *)sk, sk_##name##_call_free_func, \ - (stack_free_func)free_func); \ + OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ + sk_##name##_free_func free_func) { \ + OPENSSL_sk_pop_free_ex((OPENSSL_STACK *)sk, sk_##name##_call_free_func, \ + (OPENSSL_sk_free_func)free_func); \ } \ \ OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ size_t where) { \ - return sk_insert((_STACK *)sk, (void *)p, where); \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)p, where); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ size_t where) { \ - return (ptrtype)sk_delete((_STACK *)sk, where); \ + return (ptrtype)OPENSSL_sk_delete((OPENSSL_STACK *)sk, where); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ constptrtype p) { \ - return (ptrtype)sk_delete_ptr((_STACK *)sk, (const void *)p); \ + return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)p); \ + } \ + \ + OPENSSL_INLINE void sk_##name##_delete_if( \ + STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ + OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ + (OPENSSL_sk_delete_if_func)func, data); \ } \ \ OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ - size_t * out_index, constptrtype p) { \ - return sk_find((const _STACK *)sk, out_index, (const void *)p, \ - sk_##name##_call_cmp_func); \ + size_t *out_index, constptrtype p) { \ + return OPENSSL_sk_find((const OPENSSL_STACK *)sk, out_index, \ + (const void *)p, sk_##name##_call_cmp_func); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ - return (ptrtype)sk_shift((_STACK *)sk); \ + return (ptrtype)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ } \ \ OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ - return sk_push((_STACK *)sk, (void *)p); \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)p); \ } \ \ OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ - return (ptrtype)sk_pop((_STACK *)sk); \ + return (ptrtype)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ } \ \ - OPENSSL_INLINE STACK_OF(name) * sk_##name##_dup(const STACK_OF(name) *sk) { \ - return (STACK_OF(name) *)sk_dup((const _STACK *)sk); \ + OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ + return (STACK_OF(name) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ } \ \ OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ - sk_sort((_STACK *)sk); \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk, sk_##name##_call_cmp_func); \ } \ \ OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ - return sk_is_sorted((const _STACK *)sk); \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ } \ \ - OPENSSL_INLINE stack_##name##_cmp_func sk_##name##_set_cmp_func( \ - STACK_OF(name) *sk, stack_##name##_cmp_func comp) { \ - return (stack_##name##_cmp_func)sk_set_cmp_func((_STACK *)sk, \ - (stack_cmp_func)comp); \ + OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ + STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ + return (sk_##name##_cmp_func)OPENSSL_sk_set_cmp_func( \ + (OPENSSL_STACK *)sk, (OPENSSL_sk_cmp_func)comp); \ } \ \ - OPENSSL_INLINE STACK_OF(name) * \ - sk_##name##_deep_copy(const STACK_OF(name) *sk, \ - ptrtype(*copy_func)(ptrtype), \ - void (*free_func)(ptrtype)) { \ - return (STACK_OF(name) *)sk_deep_copy( \ - (const _STACK *)sk, sk_##name##_call_copy_func, \ - (stack_copy_func)copy_func, sk_##name##_call_free_func, \ - (stack_free_func)free_func); \ - } + OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ + const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ + sk_##name##_free_func free_func) { \ + return (STACK_OF(name) *)OPENSSL_sk_deep_copy( \ + (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ + (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ + (OPENSSL_sk_free_func)free_func); \ + } \ + \ + OPENSSL_MSVC_PRAGMA(warning(pop)) -// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements -// are |type| *. -#define DEFINE_NAMED_STACK_OF(name, type) \ - BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \ - BORINGSSL_DEFINE_STACK_TRAITS(name, type, false) - -// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are -// |type| *. -#define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type) - -// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements -// are const |type| *. -#define DEFINE_CONST_STACK_OF(type) \ - BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ - BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) - -// DEFINE_SPECIAL_STACK_OF defines |STACK_OF(type)| to be a stack whose elements -// are |type|, where |type| must be a typedef for a pointer. -#define DEFINE_SPECIAL_STACK_OF(type) \ - OPENSSL_STATIC_ASSERT(sizeof(type) == sizeof(void *), \ - #type " is not a pointer"); \ - BORINGSSL_DEFINE_STACK_OF_IMPL(type, type, const type) +// Built-in stacks. typedef char *OPENSSL_STRING; DEFINE_STACK_OF(void) -DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING) +DEFINE_NAMED_STACK_OF(OPENSSL_STRING, char) #if defined(__cplusplus) @@ -443,25 +561,26 @@ namespace internal { // Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. template -struct DeleterImpl< - Stack, typename std::enable_if::kIsConst>::type> { - static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); } +struct DeleterImpl::kIsConst>> { + static void Free(Stack *sk) { + OPENSSL_sk_free(reinterpret_cast(sk)); + } }; // Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the // corresponding type's deleter. template -struct DeleterImpl< - Stack, typename std::enable_if::kIsConst>::type> { +struct DeleterImpl::kIsConst>> { static void Free(Stack *sk) { // sk_FOO_pop_free is defined by macros and bound by name, so we cannot // access it from C++ here. using Type = typename StackTraits::Type; - sk_pop_free_ex(reinterpret_cast<_STACK *>(sk), - [](stack_free_func /* unused */, void *ptr) { - DeleterImpl::Free(reinterpret_cast(ptr)); - }, - nullptr); + OPENSSL_sk_pop_free_ex( + reinterpret_cast(sk), + [](OPENSSL_sk_free_func /* unused */, void *ptr) { + DeleterImpl::Free(reinterpret_cast(ptr)); + }, + nullptr); } }; @@ -482,7 +601,7 @@ class StackIteratorImpl { Type *operator*() const { return reinterpret_cast( - sk_value(reinterpret_cast(sk_), idx_)); + OPENSSL_sk_value(reinterpret_cast(sk_), idx_)); } StackIteratorImpl &operator++(/* prefix */) { @@ -502,22 +621,21 @@ class StackIteratorImpl { }; template -using StackIterator = typename std::enable_if::kIsStack, - StackIteratorImpl>::type; +using StackIterator = + std::enable_if_t::kIsStack, StackIteratorImpl>; } // namespace internal // PushToStack pushes |elem| to |sk|. It returns true on success and false on // allocation failure. template -inline - typename std::enable_if::kIsConst, bool>::type - PushToStack(Stack *sk, - UniquePtr::Type> elem) { - if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) { +inline std::enable_if_t::kIsConst, bool> +PushToStack(Stack *sk, + UniquePtr::Type> elem) { + if (!OPENSSL_sk_push(reinterpret_cast(sk), elem.get())) { return false; } - // sk_push takes ownership on success. + // OPENSSL_sk_push takes ownership on success. elem.release(); return true; } @@ -533,7 +651,7 @@ inline bssl::internal::StackIterator begin(const Stack *sk) { template inline bssl::internal::StackIterator end(const Stack *sk) { return bssl::internal::StackIterator( - sk, sk_num(reinterpret_cast(sk))); + sk, OPENSSL_sk_num(reinterpret_cast(sk))); } } // extern C++ diff --git a/third_party/boringssl/kit/src/include/openssl/thread.h b/third_party/boringssl/kit/src/include/openssl/thread.h index 91706fec..366ad618 100644 --- a/third_party/boringssl/kit/src/include/openssl/thread.h +++ b/third_party/boringssl/kit/src/include/openssl/thread.h @@ -66,38 +66,13 @@ extern "C" { #endif -#if !defined(OPENSSL_THREADS) -typedef struct crypto_mutex_st { - char padding; // Empty structs have different sizes in C and C++. -} CRYPTO_MUTEX; -#elif defined(OPENSSL_WINDOWS) -// CRYPTO_MUTEX can appear in public header files so we really don't want to -// pull in windows.h. It's statically asserted that this structure is large -// enough to contain a Windows SRWLOCK by thread_win.c. -typedef union crypto_mutex_st { - void *handle; -} CRYPTO_MUTEX; -#elif defined(__MACH__) && defined(__APPLE__) -typedef pthread_rwlock_t CRYPTO_MUTEX; -#else -// It is reasonable to include pthread.h on non-Windows systems, however the -// |pthread_rwlock_t| that we need is hidden under feature flags, and we can't -// ensure that we'll be able to get it. It's statically asserted that this -// structure is large enough to contain a |pthread_rwlock_t| by -// thread_pthread.c. -typedef union crypto_mutex_st { - double alignment; - uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8]; -} CRYPTO_MUTEX; -#endif - // CRYPTO_refcount_t is the type of a reference count. // // Since some platforms use C11 atomics to access this, it should have the // _Atomic qualifier. However, this header is included by C++ programs as well // as C code that might not set -std=c11. So, in practice, it's not possible to // do that. Instead we statically assert that the size and native alignment of -// a plain uint32_t and an _Atomic uint32_t are equal in refcount_c11.c. +// a plain uint32_t and an _Atomic uint32_t are equal in refcount.c. typedef uint32_t CRYPTO_refcount_t; diff --git a/third_party/boringssl/kit/src/include/openssl/time.h b/third_party/boringssl/kit/src/include/openssl/time.h new file mode 100644 index 00000000..723ce10a --- /dev/null +++ b/third_party/boringssl/kit/src/include/openssl/time.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_TIME_H +#define OPENSSL_HEADER_TIME_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// OPENSSL_posix_to_tm converts a int64_t POSIX time value in |time|, which must +// be in the range of year 0000 to 9999, to a broken out time value in |tm|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm); + +// OPENSSL_tm_to_posix converts a time value between the years 0 and 9999 in +// |tm| to a POSIX time value in |out|. One is returned on success, zero is +// returned on failure. It is a failure if |tm| contains out of range values. +OPENSSL_EXPORT int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_TIME_H diff --git a/third_party/boringssl/kit/src/include/openssl/tls1.h b/third_party/boringssl/kit/src/include/openssl/tls1.h index a3136c0d..772fb87a 100644 --- a/third_party/boringssl/kit/src/include/openssl/tls1.h +++ b/third_party/boringssl/kit/src/include/openssl/tls1.h @@ -408,6 +408,8 @@ extern "C" { #define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 #define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0x0300C027 + #define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 #define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 #define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 @@ -452,9 +454,15 @@ extern "C" { #define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC // TLS 1.3 ciphersuites from RFC 8446. -#define TLS1_CK_AES_128_GCM_SHA256 0x03001301 -#define TLS1_CK_AES_256_GCM_SHA384 0x03001302 -#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303 +#define TLS1_3_CK_AES_128_GCM_SHA256 0x03001301 +#define TLS1_3_CK_AES_256_GCM_SHA384 0x03001302 +#define TLS1_3_CK_CHACHA20_POLY1305_SHA256 0x03001303 + +// The following constants are legacy aliases of |TLS1_3_CK_*|. +// TODO(davidben): Migrate callers to the new name and remove these. +#define TLS1_CK_AES_128_GCM_SHA256 TLS1_3_CK_AES_128_GCM_SHA256 +#define TLS1_CK_AES_256_GCM_SHA384 TLS1_3_CK_AES_256_GCM_SHA384 +#define TLS1_CK_CHACHA20_POLY1305_SHA256 TLS1_3_CK_CHACHA20_POLY1305_SHA256 // XXX // Inconsistency alert: @@ -512,6 +520,8 @@ extern "C" { #define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" #define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA256 "ECDHE-RSA-AES128-SHA256" + #define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" #define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" #define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" @@ -624,10 +634,15 @@ extern "C" { "ECDHE-PSK-CHACHA20-POLY1305" // TLS 1.3 ciphersuites from RFC 8446. -#define TLS1_TXT_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" -#define TLS1_TXT_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" -#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +#define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +#define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +#define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +// The following constants are legacy aliases of |TLS1_3_CK_*|. +// TODO(bbe): Migrate callers to the new name and remove these. +#define TLS1_TXT_AES_128_GCM_SHA256 TLS1_3_RFC_AES_128_GCM_SHA256 +#define TLS1_TXT_AES_256_GCM_SHA384 TLS1_3_RFC_AES_256_GCM_SHA384 +#define TLS1_TXT_CHACHA20_POLY1305_SHA256 TLS1_3_RFC_CHACHA20_POLY1305_SHA256 #define TLS_CT_RSA_SIGN 1 #define TLS_CT_DSS_SIGN 2 diff --git a/third_party/boringssl/kit/src/include/openssl/trust_token.h b/third_party/boringssl/kit/src/include/openssl/trust_token.h index d9247f79..b6aa6b34 100644 --- a/third_party/boringssl/kit/src/include/openssl/trust_token.h +++ b/third_party/boringssl/kit/src/include/openssl/trust_token.h @@ -48,6 +48,14 @@ OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_voprf(void); // PMBTokens and P-384 with up to 3 keys, without RR verification. OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v2_pmb(void); +// TRUST_TOKEN_pst_v1_voprf is an experimental Trust Tokens protocol +// using VOPRFs and P-384 with up to 6 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_voprf(void); + +// TRUST_TOKEN_pst_v1_pmb is an experimental Trust Tokens protocol using +// PMBTokens and P-384 with up to 3 keys, without RR verification. +OPENSSL_EXPORT const TRUST_TOKEN_METHOD *TRUST_TOKEN_pst_v1_pmb(void); + // trust_token_st represents a single-use token for the Trust Token protocol. // For the client, this is the token and its corresponding signature. For the // issuer, this is the token itself. @@ -78,15 +86,30 @@ OPENSSL_EXPORT void TRUST_TOKEN_free(TRUST_TOKEN *token); // to ensure success, these should be at least // |TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE| and |TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE|. // -// WARNING: This API is unstable and the serializations of these keys are -// subject to change. Keys generated with this function may not be persisted. -// // This function returns one on success or zero on error. OPENSSL_EXPORT int TRUST_TOKEN_generate_key( const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key, size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id); +// TRUST_TOKEN_derive_key_from_secret deterministically derives a new Trust +// Token keypair labeled with |id| from an input |secret| and serializes the +// private and public keys, writing the private key to |out_priv_key| and +// setting |*out_priv_key_len| to the number of bytes written, and writing the +// public key to |out_pub_key| and setting |*out_pub_key_len| to the number of +// bytes written. +// +// At most |max_priv_key_len| and |max_pub_key_len| bytes are written. In order +// to ensure success, these should be at least +// |TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE| and |TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE|. +// +// This function returns one on success or zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_derive_key_from_secret( + const TRUST_TOKEN_METHOD *method, uint8_t *out_priv_key, + size_t *out_priv_key_len, size_t max_priv_key_len, uint8_t *out_pub_key, + size_t *out_pub_key_len, size_t max_pub_key_len, uint32_t id, + const uint8_t *secret, size_t secret_len); + // Trust Token client implementation. // @@ -128,6 +151,15 @@ OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, size_t *out_len, size_t count); +// TRUST_TOKEN_CLIENT_begin_issuance_over_message produces a request for a trust +// token derived from |msg| and serializes the request into a newly-allocated +// buffer, setting |*out| to that buffer and |*out_len| to its length. The +// caller takes ownership of the buffer and must call |OPENSSL_free| when done. +// It returns one on success and zero on error. +OPENSSL_EXPORT int TRUST_TOKEN_CLIENT_begin_issuance_over_message( + TRUST_TOKEN_CLIENT *ctx, uint8_t **out, size_t *out_len, size_t count, + const uint8_t *msg, size_t msg_len); + // TRUST_TOKEN_CLIENT_finish_issuance consumes |response| from the issuer and // extracts the tokens, returning a list of tokens and the index of the key used // to sign the tokens in |*out_key_index|. The caller can use this to determine @@ -224,28 +256,6 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_issue( uint32_t public_metadata, uint8_t private_metadata, size_t max_issuance); // TRUST_TOKEN_ISSUER_redeem ingests a |request| for token redemption and -// verifies the token. If the token is valid, a RR is produced with a lifetime -// of |lifetime| (in seconds), signing over the requested data from the request -// and the value of the token, storing the result into a newly-allocated buffer -// and setting |*out| to that buffer and |*out_len| to its length. The extracted -// |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in -// |*out_token|. The extracted client data is stored into a newly-allocated -// buffer and stored in |*out_client_data|. In TrustTokenV1, the extracted -// redemption time is stored in |*out_redemption_time|. The caller takes -// ownership of each output buffer and must call |OPENSSL_free| when done. It -// returns one on success or zero on error. -// -// The caller must keep track of all values of |*out_token| seen globally before -// returning the SRR to the client. If the value has been reused, the caller -// must discard the SRR and report an error to the caller. Returning an SRR with -// replayed values allows an attacker to double-spend tokens. -OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( - const TRUST_TOKEN_ISSUER *ctx, uint8_t **out, size_t *out_len, - TRUST_TOKEN **out_token, uint8_t **out_client_data, - size_t *out_client_data_len, uint64_t *out_redemption_time, - const uint8_t *request, size_t request_len, uint64_t lifetime); - -// TRUST_TOKEN_ISSUER_redeem_raw ingests a |request| for token redemption and // verifies the token. The public metadata is stored in |*out_public|. The // private metadata (if any) is stored in |*out_private|. The extracted // |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in @@ -258,11 +268,35 @@ OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( // returning a response to the client. If the value has been reused, the caller // must report an error to the client. Returning a response with replayed values // allows an attacker to double-spend tokens. -OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_raw( +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem( const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, TRUST_TOKEN **out_token, uint8_t **out_client_data, size_t *out_client_data_len, const uint8_t *request, size_t request_len); +// TRUST_TOKEN_ISSUER_redeem_raw is a legacy alias for +// |TRUST_TOKEN_ISSUER_redeem|. +#define TRUST_TOKEN_ISSUER_redeem_raw TRUST_TOKEN_ISSUER_redeem + +// TRUST_TOKEN_ISSUER_redeem_over_message ingests a |request| for token +// redemption and a message and verifies the token and that it is derived from +// the provided |msg|. The public metadata is stored in +// |*out_public|. The private metadata (if any) is stored in |*out_private|. The +// extracted |TRUST_TOKEN| is stored into a newly-allocated buffer and stored in +// |*out_token|. The extracted client data is stored into a newly-allocated +// buffer and stored in |*out_client_data|. The caller takes ownership of each +// output buffer and must call |OPENSSL_free| when done. It returns one on +// success or zero on error. +// +// The caller must keep track of all values of |*out_token| seen globally before +// returning a response to the client. If the value has been reused, the caller +// must report an error to the client. Returning a response with replayed values +// allows an attacker to double-spend tokens. +OPENSSL_EXPORT int TRUST_TOKEN_ISSUER_redeem_over_message( + const TRUST_TOKEN_ISSUER *ctx, uint32_t *out_public, uint8_t *out_private, + TRUST_TOKEN **out_token, uint8_t **out_client_data, + size_t *out_client_data_len, const uint8_t *request, size_t request_len, + const uint8_t *msg, size_t msg_len); + // TRUST_TOKEN_decode_private_metadata decodes |encrypted_bit| using the // private metadata key specified by a |key| buffer of length |key_len| and the // nonce by a |nonce| buffer of length |nonce_len|. The nonce in diff --git a/third_party/boringssl/kit/src/include/openssl/type_check.h b/third_party/boringssl/kit/src/include/openssl/type_check.h index c267938c..6460ab14 100644 --- a/third_party/boringssl/kit/src/include/openssl/type_check.h +++ b/third_party/boringssl/kit/src/include/openssl/type_check.h @@ -64,17 +64,6 @@ extern "C" { #endif -#if defined(__cplusplus) || (defined(_MSC_VER) && !defined(__clang__)) -// In C++ and non-clang MSVC, |static_assert| is a keyword. -#define OPENSSL_STATIC_ASSERT(cond, msg) static_assert(cond, msg) -#else -// C11 defines the |_Static_assert| keyword and the |static_assert| macro in -// assert.h. While the former is available at all versions in Clang and GCC, the -// later depends on libc and, in glibc, depends on being built in C11 mode. We -// do not require this, for now, so use |_Static_assert| directly. -#define OPENSSL_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) -#endif - // CHECKED_CAST casts |p| from type |from| to type |to|. // // TODO(davidben): Although this macro is not public API and is unused in diff --git a/third_party/boringssl/kit/src/include/openssl/x509.h b/third_party/boringssl/kit/src/include/openssl/x509.h index 0964780b..c41b3a5c 100644 --- a/third_party/boringssl/kit/src/include/openssl/x509.h +++ b/third_party/boringssl/kit/src/include/openssl/x509.h @@ -60,8 +60,8 @@ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ -#ifndef HEADER_X509_H -#define HEADER_X509_H +#ifndef OPENSSL_HEADER_X509_H +#define OPENSSL_HEADER_X509_H #include #include @@ -90,230 +90,78 @@ extern "C" { // Legacy X.509 library. // // This header is part of OpenSSL's X.509 implementation. It is retained for -// compatibility but otherwise underdocumented and not actively maintained. In -// the future, a replacement library will be available. Meanwhile, minimize +// compatibility but should not be used by new code. The functions are difficult +// to use correctly, and have buggy or non-standard behaviors. They are thus +// particularly prone to behavior changes and API removals, as BoringSSL +// iterates on these issues. +// +// In the future, a replacement library will be available. Meanwhile, minimize // dependencies on this header where possible. +// +// TODO(https://crbug.com/boringssl/426): Documentation for this library is +// still in progress. Some functions have not yet been documented, and some +// functions have not yet been grouped into sections. -#define X509_FILETYPE_PEM 1 -#define X509_FILETYPE_ASN1 2 -#define X509_FILETYPE_DEFAULT 3 - -#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 -#define X509v3_KU_NON_REPUDIATION 0x0040 -#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 -#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 -#define X509v3_KU_KEY_AGREEMENT 0x0008 -#define X509v3_KU_KEY_CERT_SIGN 0x0004 -#define X509v3_KU_CRL_SIGN 0x0002 -#define X509v3_KU_ENCIPHER_ONLY 0x0001 -#define X509v3_KU_DECIPHER_ONLY 0x8000 -#define X509v3_KU_UNDEF 0xffff - -struct X509_algor_st { - ASN1_OBJECT *algorithm; - ASN1_TYPE *parameter; -} /* X509_ALGOR */; - -DECLARE_ASN1_FUNCTIONS(X509_ALGOR) - -DEFINE_STACK_OF(X509_ALGOR) - -typedef STACK_OF(X509_ALGOR) X509_ALGORS; - -DEFINE_STACK_OF(X509_NAME_ENTRY) - -DEFINE_STACK_OF(X509_NAME) - -typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; - -DEFINE_STACK_OF(X509_EXTENSION) - -DEFINE_STACK_OF(X509_ATTRIBUTE) - -// This stuff is certificate "auxiliary info" -// it contains details which are useful in certificate -// stores and databases. When used this is tagged onto -// the end of the certificate itself - -DECLARE_STACK_OF(DIST_POINT) -DECLARE_STACK_OF(GENERAL_NAME) +// Certificates. +// +// An |X509| object represents an X.509 certificate, defined in RFC 5280. +// +// Although an |X509| is a mutable object, mutating an |X509| can give incorrect +// results. Callers typically obtain |X509|s by parsing some input with +// |d2i_X509|, etc. Such objects carry information such as the serialized +// TBSCertificate and decoded extensions, which will become inconsistent when +// mutated. +// +// Instead, mutation functions should only be used when issuing new +// certificates, as described in a later section. DEFINE_STACK_OF(X509) -// This is used for a table of trust checking functions +// X509 is an |ASN1_ITEM| whose ASN.1 type is X.509 Certificate (RFC 5280) and C +// type is |X509*|. +DECLARE_ASN1_ITEM(X509) -struct x509_trust_st { - int trust; - int flags; - int (*check_trust)(struct x509_trust_st *, X509 *, int); - char *name; - int arg1; - void *arg2; -} /* X509_TRUST */; +// X509_up_ref adds one to the reference count of |x509| and returns one. +OPENSSL_EXPORT int X509_up_ref(X509 *x509); -DEFINE_STACK_OF(X509_TRUST) +// X509_chain_up_ref returns a newly-allocated |STACK_OF(X509)| containing a +// shallow copy of |chain|, or NULL on error. That is, the return value has the +// same contents as |chain|, and each |X509|'s reference count is incremented by +// one. +OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); -// standard trust ids +// X509_dup returns a newly-allocated copy of |x509|, or NULL on error. This +// function works by serializing the structure, so auxiliary properties (see +// |i2d_X509_AUX|) are not preserved. Additionally, if |x509| is incomplete, +// this function may fail. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |crl| was +// mutated. +OPENSSL_EXPORT X509 *X509_dup(X509 *x509); -#define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings +// X509_free decrements |x509|'s reference count and, if zero, releases memory +// associated with |x509|. +OPENSSL_EXPORT void X509_free(X509 *x509); -#define X509_TRUST_COMPAT 1 -#define X509_TRUST_SSL_CLIENT 2 -#define X509_TRUST_SSL_SERVER 3 -#define X509_TRUST_EMAIL 4 -#define X509_TRUST_OBJECT_SIGN 5 -#define X509_TRUST_OCSP_SIGN 6 -#define X509_TRUST_OCSP_REQUEST 7 -#define X509_TRUST_TSA 8 +// d2i_X509 parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// Certificate (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509 *d2i_X509(X509 **out, const uint8_t **inp, long len); -// Keep these up to date! -#define X509_TRUST_MIN 1 -#define X509_TRUST_MAX 8 +// X509_parse_from_buffer parses an X.509 structure from |buf| and returns a +// fresh X509 or NULL on error. There must not be any trailing data in |buf|. +// The returned structure (if any) holds a reference to |buf| rather than +// copying parts of it as a normal |d2i_X509| call would do. +OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); - -// trust_flags values -#define X509_TRUST_DYNAMIC 1 -#define X509_TRUST_DYNAMIC_NAME 2 - -// check_trust return codes - -#define X509_TRUST_TRUSTED 1 -#define X509_TRUST_REJECTED 2 -#define X509_TRUST_UNTRUSTED 3 - -// Flags for X509_print_ex() - -#define X509_FLAG_COMPAT 0 -#define X509_FLAG_NO_HEADER 1L -#define X509_FLAG_NO_VERSION (1L << 1) -#define X509_FLAG_NO_SERIAL (1L << 2) -#define X509_FLAG_NO_SIGNAME (1L << 3) -#define X509_FLAG_NO_ISSUER (1L << 4) -#define X509_FLAG_NO_VALIDITY (1L << 5) -#define X509_FLAG_NO_SUBJECT (1L << 6) -#define X509_FLAG_NO_PUBKEY (1L << 7) -#define X509_FLAG_NO_EXTENSIONS (1L << 8) -#define X509_FLAG_NO_SIGDUMP (1L << 9) -#define X509_FLAG_NO_AUX (1L << 10) -#define X509_FLAG_NO_ATTRIBUTES (1L << 11) -#define X509_FLAG_NO_IDS (1L << 12) - -// Flags specific to X509_NAME_print_ex() - -// The field separator information - -#define XN_FLAG_SEP_MASK (0xf << 16) - -#define XN_FLAG_COMPAT 0 // Traditional SSLeay: use old X509_NAME_print -#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) // RFC 2253 ,+ -#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) // ,+ spaced: more readable -#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) // ;+ spaced -#define XN_FLAG_SEP_MULTILINE (4 << 16) // One line per field - -#define XN_FLAG_DN_REV (1 << 20) // Reverse DN order - -// How the field name is shown - -#define XN_FLAG_FN_MASK (0x3 << 21) - -#define XN_FLAG_FN_SN 0 // Object short name -#define XN_FLAG_FN_LN (1 << 21) // Object long name -#define XN_FLAG_FN_OID (2 << 21) // Always use OIDs -#define XN_FLAG_FN_NONE (3 << 21) // No field names - -#define XN_FLAG_SPC_EQ (1 << 23) // Put spaces round '=' - -// This determines if we dump fields we don't recognise: -// RFC 2253 requires this. - -#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) - -#define XN_FLAG_FN_ALIGN (1 << 25) // Align field names to 20 characters - -// Complete set of RFC 2253 flags - -#define XN_FLAG_RFC2253 \ - (ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | \ - XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS) - -// readable oneline form - -#define XN_FLAG_ONELINE \ - (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | \ - XN_FLAG_SPC_EQ | XN_FLAG_FN_SN) - -// readable multiline form - -#define XN_FLAG_MULTILINE \ - (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | \ - XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN) - -struct x509_revoked_st { - ASN1_INTEGER *serialNumber; - ASN1_TIME *revocationDate; - STACK_OF(X509_EXTENSION) /* optional */ *extensions; - // Set up if indirect CRL - STACK_OF(GENERAL_NAME) *issuer; - // Revocation reason - int reason; -}; - -DEFINE_STACK_OF(X509_REVOKED) - -DECLARE_STACK_OF(GENERAL_NAMES) - -DEFINE_STACK_OF(X509_CRL) - -struct private_key_st { - int version; - // The PKCS#8 data types - X509_ALGOR *enc_algor; - ASN1_OCTET_STRING *enc_pkey; // encrypted pub key - - // When decrypted, the following will not be NULL - EVP_PKEY *dec_pkey; - - // used to encrypt and decrypt - int key_length; - char *key_data; - int key_free; // true if we should auto free key_data - - // expanded version of 'enc_algor' - EVP_CIPHER_INFO cipher; -} /* X509_PKEY */; - -struct X509_info_st { - X509 *x509; - X509_CRL *crl; - X509_PKEY *x_pkey; - - EVP_CIPHER_INFO enc_cipher; - int enc_len; - char *enc_data; - -} /* X509_INFO */; - -DEFINE_STACK_OF(X509_INFO) - -// The next 2 structures and their 8 routines were sent to me by -// Pat Richard and are used to manipulate -// Netscapes spki structures - useful if you are writing a CA web page -struct Netscape_spkac_st { - X509_PUBKEY *pubkey; - ASN1_IA5STRING *challenge; // challenge sent in atlas >= PR2 -} /* NETSCAPE_SPKAC */; - -struct Netscape_spki_st { - NETSCAPE_SPKAC *spkac; // signed public key and challenge - X509_ALGOR *sig_algor; - ASN1_BIT_STRING *signature; -} /* NETSCAPE_SPKI */; - -// TODO(davidben): Document remaining functions, reorganize them, and define -// supported patterns for using |X509| objects in general. In particular, when -// it is safe to call mutating functions is a little tricky due to various -// internal caches. +// i2d_X509 marshals |x509| as a DER-encoded X.509 Certificate (RFC 5280), as +// described in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |x509| was +// mutated. +OPENSSL_EXPORT int i2d_X509(X509 *x509, uint8_t **outp); // X509_VERSION_* are X.509 version numbers. Note the numerical values of all // defined X.509 versions are one less than the named version. @@ -321,33 +169,143 @@ struct Netscape_spki_st { #define X509_VERSION_2 1 #define X509_VERSION_3 2 -// X509_get_version returns the numerical value of |x509|'s version. Callers may -// compare the result to the |X509_VERSION_*| constants. Unknown versions are -// rejected by the parser, but a manually-created |X509| object may encode -// invalid versions. In that case, the function will return the invalid version, -// or -1 on overflow. +// X509_get_version returns the numerical value of |x509|'s version, which will +// be one of the |X509_VERSION_*| constants. OPENSSL_EXPORT long X509_get_version(const X509 *x509); +// X509_get0_serialNumber returns |x509|'s serial number. +OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509); + +// X509_get0_notBefore returns |x509|'s notBefore time. +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notBefore(const X509 *x509); + +// X509_get0_notAfter returns |x509|'s notAfter time. +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notAfter(const X509 *x509); + +// X509_get_issuer_name returns |x509|'s issuer. +OPENSSL_EXPORT X509_NAME *X509_get_issuer_name(const X509 *x509); + +// X509_get_subject_name returns |x509|'s subject. +OPENSSL_EXPORT X509_NAME *X509_get_subject_name(const X509 *x509); + +// X509_get_X509_PUBKEY returns the public key of |x509|. Note this function is +// not const-correct for legacy reasons. Callers should not modify the returned +// object. +OPENSSL_EXPORT X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509); + +// X509_get_pubkey returns |x509|'s public key as an |EVP_PKEY|, or NULL if the +// public key was unsupported or could not be decoded. This function returns a +// reference to the |EVP_PKEY|. The caller must release the result with +// |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *X509_get_pubkey(X509 *x509); + +// X509_get0_pubkey_bitstr returns the BIT STRING portion of |x509|'s public +// key. Note this does not contain the AlgorithmIdentifier portion. +// +// WARNING: This function returns a non-const pointer for OpenSSL compatibility, +// but the caller must not modify the resulting object. Doing so will break +// internal invariants in |x509|. +OPENSSL_EXPORT ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x509); + +// X509_get0_uids sets |*out_issuer_uid| to a non-owning pointer to the +// issuerUID field of |x509|, or NULL if |x509| has no issuerUID. It similarly +// outputs |x509|'s subjectUID field to |*out_subject_uid|. +// +// Callers may pass NULL to either |out_issuer_uid| or |out_subject_uid| to +// ignore the corresponding field. +OPENSSL_EXPORT void X509_get0_uids(const X509 *x509, + const ASN1_BIT_STRING **out_issuer_uid, + const ASN1_BIT_STRING **out_subject_uid); + +// X509_get0_extensions returns |x509|'s extension list, or NULL if |x509| omits +// it. +OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_get0_extensions( + const X509 *x509); + +// X509_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_count(const X509 *x); + +// X509_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); + +// X509_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, + int lastpos); + +// X509_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but +// searches for extensions in |x|. +OPENSSL_EXPORT int X509_get_ext_by_critical(const X509 *x, int crit, + int lastpos); + +// X509_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| is +// out of bounds. This function returns a non-const pointer for OpenSSL +// compatibility, but callers should not mutate the result. +OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(const X509 *x, int loc); + +// X509_get0_tbs_sigalg returns the signature algorithm in |x509|'s +// TBSCertificate. For the outer signature algorithm, see |X509_get0_signature|. +// +// Certificates with mismatched signature algorithms will successfully parse, +// but they will be rejected when verifying. +OPENSSL_EXPORT const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x509); + +// X509_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |x509|, respectively. Either output pointer may be +// NULL to ignore the value. +// +// This function outputs the outer signature algorithm. For the one in the +// TBSCertificate, see |X509_get0_tbs_sigalg|. Certificates with mismatched +// signature algorithms will successfully parse, but they will be rejected when +// verifying. +OPENSSL_EXPORT void X509_get0_signature(const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg, + const X509 *x509); + +// X509_get_signature_nid returns the NID corresponding to |x509|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x509); + +// i2d_X509_tbs serializes the TBSCertificate portion of |x509|, as described in +// |i2d_SAMPLE|. +// +// This function preserves the original encoding of the TBSCertificate and may +// not reflect modifications made to |x509|. It may be used to manually verify +// the signature of an existing certificate. To generate certificates, use +// |i2d_re_X509_tbs| instead. +OPENSSL_EXPORT int i2d_X509_tbs(X509 *x509, unsigned char **outp); + +// X509_verify checks that |x509| has a valid signature by |pkey|. It returns +// one if the signature is valid and zero otherwise. Note this function only +// checks the signature itself and does not perform a full certificate +// validation. +OPENSSL_EXPORT int X509_verify(X509 *x509, EVP_PKEY *pkey); + + +// Issuing certificates. +// +// An |X509| object may also represent an incomplete certificate. Callers may +// construct empty |X509| objects, fill in fields individually, and finally sign +// the result. The following functions may be used for this purpose. + +// X509_new returns a newly-allocated, empty |X509| object, or NULL on error. +// This produces an incomplete certificate which may be filled in to issue a new +// certificate. +OPENSSL_EXPORT X509 *X509_new(void); + // X509_set_version sets |x509|'s version to |version|, which should be one of // the |X509V_VERSION_*| constants. It returns one on success and zero on error. // // If unsure, use |X509_VERSION_3|. OPENSSL_EXPORT int X509_set_version(X509 *x509, long version); -// X509_get0_serialNumber returns |x509|'s serial number. -OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509); - // X509_set_serialNumber sets |x509|'s serial number to |serial|. It returns one // on success and zero on error. OPENSSL_EXPORT int X509_set_serialNumber(X509 *x509, const ASN1_INTEGER *serial); -// X509_get0_notBefore returns |x509|'s notBefore time. -OPENSSL_EXPORT const ASN1_TIME *X509_get0_notBefore(const X509 *x509); - -// X509_get0_notAfter returns |x509|'s notAfter time. -OPENSSL_EXPORT const ASN1_TIME *X509_get0_notAfter(const X509 *x509); - // X509_set1_notBefore sets |x509|'s notBefore time to |tm|. It returns one on // success and zero on error. OPENSSL_EXPORT int X509_set1_notBefore(X509 *x509, const ASN1_TIME *tm); @@ -362,106 +320,204 @@ OPENSSL_EXPORT ASN1_TIME *X509_getm_notBefore(X509 *x509); // X509_getm_notAfter returns a mutable pointer to |x509|'s notAfter time. OPENSSL_EXPORT ASN1_TIME *X509_getm_notAfter(X509 *x); -// X509_get_notBefore returns |x509|'s notBefore time. Note this function is not -// const-correct for legacy reasons. Use |X509_get0_notBefore| or -// |X509_getm_notBefore| instead. -OPENSSL_EXPORT ASN1_TIME *X509_get_notBefore(const X509 *x509); +// X509_set_issuer_name sets |x509|'s issuer to a copy of |name|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_set_issuer_name(X509 *x509, X509_NAME *name); -// X509_get_notAfter returns |x509|'s notAfter time. Note this function is not -// const-correct for legacy reasons. Use |X509_get0_notAfter| or -// |X509_getm_notAfter| instead. -OPENSSL_EXPORT ASN1_TIME *X509_get_notAfter(const X509 *x509); +// X509_set_subject_name sets |x509|'s subject to a copy of |name|. It returns +// one on success and zero on error. +OPENSSL_EXPORT int X509_set_subject_name(X509 *x509, X509_NAME *name); -// X509_set_notBefore calls |X509_set1_notBefore|. Use |X509_set1_notBefore| -// instead. -OPENSSL_EXPORT int X509_set_notBefore(X509 *x509, const ASN1_TIME *tm); +// X509_set_pubkey sets |x509|'s public key to |pkey|. It returns one on success +// and zero on error. This function does not take ownership of |pkey| and +// internally copies and updates reference counts as needed. +OPENSSL_EXPORT int X509_set_pubkey(X509 *x509, EVP_PKEY *pkey); -// X509_set_notAfter calls |X509_set1_notAfter|. Use |X509_set1_notAfter| -// instead. -OPENSSL_EXPORT int X509_set_notAfter(X509 *x509, const ASN1_TIME *tm); +// X509_delete_ext removes the extension in |x| at index |loc| and returns the +// removed extension, or NULL if |loc| was out of bounds. If non-NULL, the +// caller must release the result with |X509_EXTENSION_free|. +OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc); -// X509_get0_uids sets |*out_issuer_uid| to a non-owning pointer to the -// issuerUID field of |x509|, or NULL if |x509| has no issuerUID. It similarly -// outputs |x509|'s subjectUID field to |*out_subject_uid|. +// X509_add_ext adds a copy of |ex| to |x|. It returns one on success and zero +// on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. // -// Callers may pass NULL to either |out_issuer_uid| or |out_subject_uid| to -// ignore the corresponding field. -OPENSSL_EXPORT void X509_get0_uids(const X509 *x509, - const ASN1_BIT_STRING **out_issuer_uid, - const ASN1_BIT_STRING **out_subject_uid); +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_add_ext(X509 *x, const X509_EXTENSION *ex, int loc); -// X509_extract_key is a legacy alias to |X509_get_pubkey|. Use -// |X509_get_pubkey| instead. -#define X509_extract_key(x) X509_get_pubkey(x) +// X509_sign signs |x509| with |pkey| and replaces the signature algorithm and +// signature fields. It returns the length of the signature on success and zero +// on error. This function uses digest algorithm |md|, or |pkey|'s default if +// NULL. Other signing parameters use |pkey|'s defaults. To customize them, use +// |X509_sign_ctx|. +OPENSSL_EXPORT int X509_sign(X509 *x509, EVP_PKEY *pkey, const EVP_MD *md); -// X509_get_pathlen returns path length constraint from the basic constraints -// extension in |x509|. (See RFC 5280, section 4.2.1.9.) It returns -1 if the -// constraint is not present, or if some extension in |x509| was invalid. +// X509_sign_ctx signs |x509| with |ctx| and replaces the signature algorithm +// and signature fields. It returns the length of the signature on success and +// zero on error. The signature algorithm and parameters come from |ctx|, which +// must have been initialized with |EVP_DigestSignInit|. The caller should +// configure the corresponding |EVP_PKEY_CTX| before calling this function. +OPENSSL_EXPORT int X509_sign_ctx(X509 *x509, EVP_MD_CTX *ctx); + +// i2d_re_X509_tbs serializes the TBSCertificate portion of |x509|, as described +// in |i2d_SAMPLE|. // -// Note that decoding an |X509| object will not check for invalid extensions. To -// detect the error case, call |X509_get_extensions_flags| and check the -// |EXFLAG_INVALID| bit. -OPENSSL_EXPORT long X509_get_pathlen(X509 *x509); +// This function re-encodes the TBSCertificate and may not reflect |x509|'s +// original encoding. It may be used to manually generate a signature for a new +// certificate. To verify certificates, use |i2d_X509_tbs| instead. +OPENSSL_EXPORT int i2d_re_X509_tbs(X509 *x509, unsigned char **outp); -// X509_REQ_VERSION_1 is the version constant for |X509_REQ| objects. Note no -// other versions are defined. -#define X509_REQ_VERSION_1 0 +// X509_set1_signature_algo sets |x509|'s signature algorithm to |algo| and +// returns one on success or zero on error. It updates both the signature field +// of the TBSCertificate structure, and the signatureAlgorithm field of the +// Certificate. +OPENSSL_EXPORT int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo); -// X509_REQ_get_version returns the numerical value of |req|'s version. This -// will be |X509_REQ_VERSION_1| for valid certificate requests. If |req| is -// invalid, it may return another value, or -1 on overflow. +// X509_set1_signature_value sets |x509|'s signature to a copy of the |sig_len| +// bytes pointed by |sig|. It returns one on success and zero on error. // -// TODO(davidben): Enforce the version number in the parser. -OPENSSL_EXPORT long X509_REQ_get_version(const X509_REQ *req); +// Due to a specification error, X.509 certificates store signatures in ASN.1 +// BIT STRINGs, but signature algorithms return byte strings rather than bit +// strings. This function creates a BIT STRING containing a whole number of +// bytes, with the bit order matching the DER encoding. This matches the +// encoding used by all X.509 signature algorithms. +OPENSSL_EXPORT int X509_set1_signature_value(X509 *x509, const uint8_t *sig, + size_t sig_len); -// X509_REQ_get_subject_name returns |req|'s subject name. Note this function is -// not const-correct for legacy reasons. -OPENSSL_EXPORT X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); -// X509_REQ_extract_key is a legacy alias for |X509_REQ_get_pubkey|. -#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +// Auxiliary certificate properties. +// +// |X509| objects optionally maintain auxiliary properties. These are not part +// of the certificates themselves, and thus are not covered by signatures or +// preserved by the standard serialization. They are used as inputs or outputs +// to other functions in this library. -// X509_name_cmp is a legacy alias for |X509_NAME_cmp|. -#define X509_name_cmp(a, b) X509_NAME_cmp((a), (b)) +// i2d_X509_AUX marshals |x509| as a DER-encoded X.509 Certificate (RFC 5280), +// followed optionally by a separate, OpenSSL-specific structure with auxiliary +// properties. It behaves as described in |i2d_SAMPLE|. +// +// Unlike similarly-named functions, this function does not output a single +// ASN.1 element. Directly embedding the output in a larger ASN.1 structure will +// not behave correctly. +OPENSSL_EXPORT int i2d_X509_AUX(X509 *x509, unsigned char **outp); + +// d2i_X509_AUX parses up to |length| bytes from |*inp| as a DER-encoded X.509 +// Certificate (RFC 5280), followed optionally by a separate, OpenSSL-specific +// structure with auxiliary properties. It behaves as described in |d2i_SAMPLE|. +// +// Some auxiliary properties affect trust decisions, so this function should not +// be used with untrusted input. +// +// Unlike similarly-named functions, this function does not parse a single +// ASN.1 element. Trying to parse data directly embedded in a larger ASN.1 +// structure will not behave correctly. +OPENSSL_EXPORT X509 *d2i_X509_AUX(X509 **x509, const unsigned char **inp, + long length); + +// X509_alias_set1 sets |x509|'s alias to |len| bytes from |name|. If |name| is +// NULL, the alias is cleared instead. Aliases are not part of the certificate +// itself and will not be serialized by |i2d_X509|. +OPENSSL_EXPORT int X509_alias_set1(X509 *x509, const unsigned char *name, + ossl_ssize_t len); + +// X509_keyid_set1 sets |x509|'s key ID to |len| bytes from |id|. If |id| is +// NULL, the key ID is cleared instead. Key IDs are not part of the certificate +// itself and will not be serialized by |i2d_X509|. +OPENSSL_EXPORT int X509_keyid_set1(X509 *x509, const unsigned char *id, + ossl_ssize_t len); + +// X509_alias_get0 looks up |x509|'s alias. If found, it sets |*out_len| to the +// alias's length and returns a pointer to a buffer containing the contents. If +// not found, it outputs the empty string by returning NULL and setting +// |*out_len| to zero. +// +// If |x509| was parsed from a PKCS#12 structure (see +// |PKCS12_get_key_and_certs|), the alias will reflect the friendlyName +// attribute (RFC 2985). +// +// WARNING: In OpenSSL, this function did not set |*out_len| when the alias was +// missing. Callers that target both OpenSSL and BoringSSL should set the value +// to zero before calling this function. +OPENSSL_EXPORT unsigned char *X509_alias_get0(X509 *x509, int *out_len); + +// X509_keyid_get0 looks up |x509|'s key ID. If found, it sets |*out_len| to the +// key ID's length and returns a pointer to a buffer containing the contents. If +// not found, it outputs the empty string by returning NULL and setting +// |*out_len| to zero. +// +// WARNING: In OpenSSL, this function did not set |*out_len| when the alias was +// missing. Callers that target both OpenSSL and BoringSSL should set the value +// to zero before calling this function. +OPENSSL_EXPORT unsigned char *X509_keyid_get0(X509 *x509, int *out_len); + + +// Certificate revocation lists. +// +// An |X509_CRL| object represents an X.509 certificate revocation list (CRL), +// defined in RFC 5280. A CRL is a signed list of certificates which are no +// longer considered valid. +// +// Although an |X509_CRL| is a mutable object, mutating an |X509_CRL| can give +// incorrect results. Callers typically obtain |X509_CRL|s by parsing some input +// with |d2i_X509_CRL|, etc. Such objects carry information such as the +// serialized TBSCertList and decoded extensions, which will become inconsistent +// when mutated. +// +// Instead, mutation functions should only be used when issuing new CRLs, as +// described in a later section. + +DEFINE_STACK_OF(X509_CRL) + +// X509_CRL is an |ASN1_ITEM| whose ASN.1 type is X.509 CertificateList (RFC +// 5280) and C type is |X509_CRL*|. +DECLARE_ASN1_ITEM(X509_CRL) + +// X509_CRL_up_ref adds one to the reference count of |crl| and returns one. +OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); + +// X509_CRL_dup returns a newly-allocated copy of |crl|, or NULL on error. This +// function works by serializing the structure, so if |crl| is incomplete, it +// may fail. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |crl| was +// mutated. +OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); + +// X509_CRL_free decrements |crl|'s reference count and, if zero, releases +// memory associated with |crl|. +OPENSSL_EXPORT void X509_CRL_free(X509_CRL *crl); + +// d2i_X509_CRL parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// CertificateList (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL(X509_CRL **out, const uint8_t **inp, + long len); + +// i2d_X509_CRL marshals |crl| as a X.509 CertificateList (RFC 5280), as +// described in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |crl| was +// mutated. +OPENSSL_EXPORT int i2d_X509_CRL(X509_CRL *crl, uint8_t **outp); #define X509_CRL_VERSION_1 0 #define X509_CRL_VERSION_2 1 -// X509_CRL_get_version returns the numerical value of |crl|'s version. Callers -// may compare the result to |X509_CRL_VERSION_*| constants. If |crl| is -// invalid, it may return another value, or -1 on overflow. -// -// TODO(davidben): Enforce the version number in the parser. +// X509_CRL_get_version returns the numerical value of |crl|'s version, which +// will be one of the |X509_CRL_VERSION_*| constants. OPENSSL_EXPORT long X509_CRL_get_version(const X509_CRL *crl); -// X509_CRL_get0_lastUpdate returns |crl|'s lastUpdate time. +// X509_CRL_get0_lastUpdate returns |crl|'s thisUpdate time. The OpenSSL API +// refers to this field as lastUpdate. OPENSSL_EXPORT const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); // X509_CRL_get0_nextUpdate returns |crl|'s nextUpdate time, or NULL if |crl| // has none. OPENSSL_EXPORT const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); -// X509_CRL_set1_lastUpdate sets |crl|'s lastUpdate time to |tm|. It returns one -// on success and zero on error. -OPENSSL_EXPORT int X509_CRL_set1_lastUpdate(X509_CRL *crl, const ASN1_TIME *tm); - -// X509_CRL_set1_nextUpdate sets |crl|'s nextUpdate time to |tm|. It returns one -// on success and zero on error. -OPENSSL_EXPORT int X509_CRL_set1_nextUpdate(X509_CRL *crl, const ASN1_TIME *tm); - -// The following symbols are deprecated aliases to |X509_CRL_set1_*|. -#define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate -#define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate - -// X509_CRL_get_lastUpdate returns a mutable pointer to |crl|'s lastUpdate time. -// Use |X509_CRL_get0_lastUpdate| or |X509_CRL_set1_lastUpdate| instead. -OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl); - -// X509_CRL_get_nextUpdate returns a mutable pointer to |crl|'s nextUpdate time, -// or NULL if |crl| has none. Use |X509_CRL_get0_nextUpdate| or -// |X509_CRL_set1_nextUpdate| instead. -OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl); - // X509_CRL_get_issuer returns |crl|'s issuer name. Note this function is not // const-correct for legacy reasons. OPENSSL_EXPORT X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); @@ -479,264 +535,819 @@ OPENSSL_EXPORT STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions( const X509_CRL *crl); -// X509_SIG_get0 sets |*out_alg| and |*out_digest| to non-owning pointers to -// |sig|'s algorithm and digest fields, respectively. Either |out_alg| and -// |out_digest| may be NULL to skip those fields. -OPENSSL_EXPORT void X509_SIG_get0(const X509_SIG *sig, - const X509_ALGOR **out_alg, - const ASN1_OCTET_STRING **out_digest); +// X509_CRL_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_count(const X509_CRL *x); -// X509_SIG_getm behaves like |X509_SIG_get0| but returns mutable pointers. -OPENSSL_EXPORT void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, - ASN1_OCTET_STRING **out_digest); +// X509_CRL_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, + int lastpos); -OPENSSL_EXPORT void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); -OPENSSL_EXPORT X509_CRL_METHOD *X509_CRL_METHOD_new( - int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), - int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, - X509_NAME *issuer), - int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); -OPENSSL_EXPORT void X509_CRL_METHOD_free(X509_CRL_METHOD *m); +// X509_CRL_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for +// extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, + const ASN1_OBJECT *obj, int lastpos); -OPENSSL_EXPORT void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); -OPENSSL_EXPORT void *X509_CRL_get_meth_data(X509_CRL *crl); +// X509_CRL_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but +// searches for extensions in |x|. +OPENSSL_EXPORT int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, + int lastpos); -// X509_get_X509_PUBKEY returns the public key of |x509|. Note this function is -// not const-correct for legacy reasons. Callers should not modify the returned -// object. -OPENSSL_EXPORT X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509); +// X509_CRL_get_ext returns the extension in |x| at index |loc|, or NULL if +// |loc| is out of bounds. This function returns a non-const pointer for OpenSSL +// compatibility, but callers should not mutate the result. +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); -// X509_verify_cert_error_string returns |err| as a human-readable string, where -// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns -// a default description. -OPENSSL_EXPORT const char *X509_verify_cert_error_string(long err); +// X509_CRL_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |crl|, respectively. Either output pointer may be NULL +// to ignore the value. +// +// This function outputs the outer signature algorithm, not the one in the +// TBSCertList. CRLs with mismatched signature algorithms will successfully +// parse, but they will be rejected when verifying. +OPENSSL_EXPORT void X509_CRL_get0_signature(const X509_CRL *crl, + const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg); -// X509_verify checks that |x509| has a valid signature by |pkey|. It returns -// one if the signature is valid and zero otherwise. Note this function only -// checks the signature itself and does not perform a full certificate -// validation. -OPENSSL_EXPORT int X509_verify(X509 *x509, EVP_PKEY *pkey); +// X509_CRL_get_signature_nid returns the NID corresponding to |crl|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_CRL_get_signature_nid(const X509_CRL *crl); -// X509_REQ_verify checks that |req| has a valid signature by |pkey|. It returns -// one if the signature is valid and zero otherwise. -OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey); +// i2d_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described in +// |i2d_SAMPLE|. +// +// This function preserves the original encoding of the TBSCertList and may not +// reflect modifications made to |crl|. It may be used to manually verify the +// signature of an existing CRL. To generate CRLs, use |i2d_re_X509_CRL_tbs| +// instead. +OPENSSL_EXPORT int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); // X509_CRL_verify checks that |crl| has a valid signature by |pkey|. It returns // one if the signature is valid and zero otherwise. OPENSSL_EXPORT int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey); -// NETSCAPE_SPKI_verify checks that |spki| has a valid signature by |pkey|. It -// returns one if the signature is valid and zero otherwise. -OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey); -// NETSCAPE_SPKI_b64_decode decodes |len| bytes from |str| as a base64-encoded -// Netscape signed public key and challenge (SPKAC) structure. It returns a -// newly-allocated |NETSCAPE_SPKI| structure with the result, or NULL on error. -// If |len| is 0 or negative, the length is calculated with |strlen| and |str| -// must be a NUL-terminated C string. -OPENSSL_EXPORT NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, - int len); +// Issuing certificate revocation lists. +// +// An |X509_CRL| object may also represent an incomplete CRL. Callers may +// construct empty |X509_CRL| objects, fill in fields individually, and finally +// sign the result. The following functions may be used for this purpose. -// NETSCAPE_SPKI_b64_encode encodes |spki| as a base64-encoded Netscape signed -// public key and challenge (SPKAC) structure. It returns a newly-allocated -// NUL-terminated C string with the result, or NULL on error. The caller must -// release the memory with |OPENSSL_free| when done. -OPENSSL_EXPORT char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki); +// X509_CRL_new returns a newly-allocated, empty |X509_CRL| object, or NULL on +// error. This object may be filled in and then signed to construct a CRL. +OPENSSL_EXPORT X509_CRL *X509_CRL_new(void); -// NETSCAPE_SPKI_get_pubkey decodes and returns the public key in |spki| as an -// |EVP_PKEY|, or NULL on error. The caller takes ownership of the resulting -// pointer and must call |EVP_PKEY_free| when done. -OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *spki); +// X509_CRL_set_version sets |crl|'s version to |version|, which should be one +// of the |X509_CRL_VERSION_*| constants. It returns one on success and zero on +// error. +// +// If unsure, use |X509_CRL_VERSION_2|. Note that, unlike certificates, CRL +// versions are only defined up to v2. Callers should not use |X509_VERSION_3|. +OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *crl, long version); -// NETSCAPE_SPKI_set_pubkey sets |spki|'s public key to |pkey|. It returns one -// on success or zero on error. This function does not take ownership of |pkey|, -// so the caller may continue to manage its lifetime independently of |spki|. -OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *spki, - EVP_PKEY *pkey); +// X509_CRL_set_issuer_name sets |crl|'s issuer to a copy of |name|. It returns +// one on success and zero on error. +OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *crl, X509_NAME *name); -// X509_signature_dump writes a human-readable representation of |sig| to |bio|, -// indented with |indent| spaces. It returns one on success and zero on error. -OPENSSL_EXPORT int X509_signature_dump(BIO *bio, const ASN1_STRING *sig, - int indent); +// X509_CRL_set1_lastUpdate sets |crl|'s thisUpdate time to |tm|. It returns one +// on success and zero on error. The OpenSSL API refers to this field as +// lastUpdate. +OPENSSL_EXPORT int X509_CRL_set1_lastUpdate(X509_CRL *crl, const ASN1_TIME *tm); -// X509_signature_print writes a human-readable representation of |alg| and -// |sig| to |bio|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509_signature_print(BIO *bio, const X509_ALGOR *alg, - const ASN1_STRING *sig); +// X509_CRL_set1_nextUpdate sets |crl|'s nextUpdate time to |tm|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_CRL_set1_nextUpdate(X509_CRL *crl, const ASN1_TIME *tm); -// X509_sign signs |x509| with |pkey| and replaces the signature algorithm and -// signature fields. It returns one on success and zero on error. This function -// uses digest algorithm |md|, or |pkey|'s default if NULL. Other signing -// parameters use |pkey|'s defaults. To customize them, use |X509_sign_ctx|. -OPENSSL_EXPORT int X509_sign(X509 *x509, EVP_PKEY *pkey, const EVP_MD *md); +// X509_CRL_delete_ext removes the extension in |x| at index |loc| and returns +// the removed extension, or NULL if |loc| was out of bounds. If non-NULL, the +// caller must release the result with |X509_EXTENSION_free|. +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); -// X509_sign_ctx signs |x509| with |ctx| and replaces the signature algorithm -// and signature fields. It returns one on success and zero on error. The -// signature algorithm and parameters come from |ctx|, which must have been -// initialized with |EVP_DigestSignInit|. The caller should configure the -// corresponding |EVP_PKEY_CTX| before calling this function. -OPENSSL_EXPORT int X509_sign_ctx(X509 *x509, EVP_MD_CTX *ctx); - -// X509_REQ_sign signs |req| with |pkey| and replaces the signature algorithm -// and signature fields. It returns one on success and zero on error. This -// function uses digest algorithm |md|, or |pkey|'s default if NULL. Other -// signing parameters use |pkey|'s defaults. To customize them, use -// |X509_REQ_sign_ctx|. -OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *req, EVP_PKEY *pkey, - const EVP_MD *md); - -// X509_REQ_sign_ctx signs |req| with |ctx| and replaces the signature algorithm -// and signature fields. It returns one on success and zero on error. The -// signature algorithm and parameters come from |ctx|, which must have been -// initialized with |EVP_DigestSignInit|. The caller should configure the -// corresponding |EVP_PKEY_CTX| before calling this function. -OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *req, EVP_MD_CTX *ctx); +// X509_CRL_add_ext adds a copy of |ex| to |x|. It returns one on success and +// zero on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_CRL_add_ext(X509_CRL *x, const X509_EXTENSION *ex, + int loc); // X509_CRL_sign signs |crl| with |pkey| and replaces the signature algorithm -// and signature fields. It returns one on success and zero on error. This -// function uses digest algorithm |md|, or |pkey|'s default if NULL. Other -// signing parameters use |pkey|'s defaults. To customize them, use -// |X509_CRL_sign_ctx|. +// and signature fields. It returns the length of the signature on success and +// zero on error. This function uses digest algorithm |md|, or |pkey|'s default +// if NULL. Other signing parameters use |pkey|'s defaults. To customize them, +// use |X509_CRL_sign_ctx|. OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *crl, EVP_PKEY *pkey, const EVP_MD *md); // X509_CRL_sign_ctx signs |crl| with |ctx| and replaces the signature algorithm -// and signature fields. It returns one on success and zero on error. The -// signature algorithm and parameters come from |ctx|, which must have been -// initialized with |EVP_DigestSignInit|. The caller should configure the -// corresponding |EVP_PKEY_CTX| before calling this function. +// and signature fields. It returns the length of the signature on success and +// zero on error. The signature algorithm and parameters come from |ctx|, which +// must have been initialized with |EVP_DigestSignInit|. The caller should +// configure the corresponding |EVP_PKEY_CTX| before calling this function. OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *crl, EVP_MD_CTX *ctx); -// NETSCAPE_SPKI_sign signs |spki| with |pkey| and replaces the signature -// algorithm and signature fields. It returns one on success and zero on error. -// This function uses digest algorithm |md|, or |pkey|'s default if NULL. Other -// signing parameters use |pkey|'s defaults. -OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *spki, EVP_PKEY *pkey, - const EVP_MD *md); +// i2d_re_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described +// in |i2d_SAMPLE|. +// +// This function re-encodes the TBSCertList and may not reflect |crl|'s original +// encoding. It may be used to manually generate a signature for a new CRL. To +// verify CRLs, use |i2d_X509_CRL_tbs| instead. +OPENSSL_EXPORT int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); -// X509_pubkey_digest hashes the DER encoding of |x509|'s subjectPublicKeyInfo -// field with |md| and writes the result to |out|. |EVP_MD_CTX_size| bytes are -// written, which is at most |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, -// |*out_len| is set to the number of bytes written. This function returns one -// on success and zero on error. -OPENSSL_EXPORT int X509_pubkey_digest(const X509 *x509, const EVP_MD *md, - uint8_t *out, unsigned *out_len); +// X509_CRL_set1_signature_algo sets |crl|'s signature algorithm to |algo| and +// returns one on success or zero on error. It updates both the signature field +// of the TBSCertList structure, and the signatureAlgorithm field of the CRL. +OPENSSL_EXPORT int X509_CRL_set1_signature_algo(X509_CRL *crl, + const X509_ALGOR *algo); -// X509_digest hashes |x509|'s DER encoding with |md| and writes the result to -// |out|. |EVP_MD_CTX_size| bytes are written, which is at most -// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number -// of bytes written. This function returns one on success and zero on error. -// Note this digest covers the entire certificate, not just the signed portion. -OPENSSL_EXPORT int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out, - unsigned *out_len); +// X509_CRL_set1_signature_value sets |crl|'s signature to a copy of the +// |sig_len| bytes pointed by |sig|. It returns one on success and zero on +// error. +// +// Due to a specification error, X.509 CRLs store signatures in ASN.1 BIT +// STRINGs, but signature algorithms return byte strings rather than bit +// strings. This function creates a BIT STRING containing a whole number of +// bytes, with the bit order matching the DER encoding. This matches the +// encoding used by all X.509 signature algorithms. +OPENSSL_EXPORT int X509_CRL_set1_signature_value(X509_CRL *crl, + const uint8_t *sig, + size_t sig_len); -// X509_CRL_digest hashes |crl|'s DER encoding with |md| and writes the result -// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most -// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number -// of bytes written. This function returns one on success and zero on error. -// Note this digest covers the entire CRL, not just the signed portion. -OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *crl, const EVP_MD *md, - uint8_t *out, unsigned *out_len); -// X509_REQ_digest hashes |req|'s DER encoding with |md| and writes the result -// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most -// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number -// of bytes written. This function returns one on success and zero on error. -// Note this digest covers the entire certificate request, not just the signed -// portion. -OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *req, const EVP_MD *md, - uint8_t *out, unsigned *out_len); +// Certificate requests. +// +// An |X509_REQ| represents a PKCS #10 certificate request (RFC 2986). These are +// also referred to as certificate signing requests or CSRs. CSRs are a common +// format used to request a certificate from a CA. +// +// Although an |X509_REQ| is a mutable object, mutating an |X509_REQ| can give +// incorrect results. Callers typically obtain |X509_REQ|s by parsing some input +// with |d2i_X509_REQ|, etc. Such objects carry information such as the +// serialized CertificationRequestInfo, which will become inconsistent when +// mutated. +// +// Instead, mutation functions should only be used when issuing new CRLs, as +// described in a later section. -// X509_NAME_digest hashes |name|'s DER encoding with |md| and writes the result -// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most -// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number -// of bytes written. This function returns one on success and zero on error. -OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *name, const EVP_MD *md, - uint8_t *out, unsigned *out_len); +// X509_REQ is an |ASN1_ITEM| whose ASN.1 type is CertificateRequest (RFC 2986) +// and C type is |X509_REQ*|. +DECLARE_ASN1_ITEM(X509_REQ) -// X509_parse_from_buffer parses an X.509 structure from |buf| and returns a -// fresh X509 or NULL on error. There must not be any trailing data in |buf|. -// The returned structure (if any) holds a reference to |buf| rather than -// copying parts of it as a normal |d2i_X509| call would do. -OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); - -OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509); -OPENSSL_EXPORT int i2d_X509_fp(FILE *fp, X509 *x509); -OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); -OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); -OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); -OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); -OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); -OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); -OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); -#ifndef OPENSSL_NO_DSA -OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); -OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); -OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); -OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); -#endif -OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); -OPENSSL_EXPORT int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); -OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); -OPENSSL_EXPORT int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); -OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); -OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); -OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp( - FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf); -OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, - PKCS8_PRIV_KEY_INFO *p8inf); -OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); -OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); -OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); -OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); -OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); - -OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp, X509 **x509); -OPENSSL_EXPORT int i2d_X509_bio(BIO *bp, X509 *x509); -OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); -OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); -OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); -OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); -OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); -OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); -OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); -OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); -#ifndef OPENSSL_NO_DSA -OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); -OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); -OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); -OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); -#endif -OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); -OPENSSL_EXPORT int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); -OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); -OPENSSL_EXPORT int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); -OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); -OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); -OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio( - BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf); -OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, - PKCS8_PRIV_KEY_INFO *p8inf); -OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); -OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); -OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); -OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); -OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); -OPENSSL_EXPORT DH *d2i_DHparams_bio(BIO *bp, DH **dh); -OPENSSL_EXPORT int i2d_DHparams_bio(BIO *bp, const DH *dh); - -OPENSSL_EXPORT X509 *X509_dup(X509 *x509); -OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); -OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); -OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); -OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +// X509_REQ_dup returns a newly-allocated copy of |req|, or NULL on error. This +// function works by serializing the structure, so if |req| is incomplete, it +// may fail. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |req| was +// mutated. OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); -OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); + +// X509_REQ_free releases memory associated with |req|. +OPENSSL_EXPORT void X509_REQ_free(X509_REQ *req); + +// d2i_X509_REQ parses up to |len| bytes from |*inp| as a DER-encoded +// CertificateRequest (RFC 2986), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ(X509_REQ **out, const uint8_t **inp, + long len); + +// i2d_X509_REQ marshals |req| as a CertificateRequest (RFC 2986), as described +// in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |req| was +// mutated. +OPENSSL_EXPORT int i2d_X509_REQ(X509_REQ *req, uint8_t **outp); + +// X509_REQ_VERSION_1 is the version constant for |X509_REQ| objects. No other +// versions are defined. +#define X509_REQ_VERSION_1 0 + +// X509_REQ_get_version returns the numerical value of |req|'s version. This +// will always be |X509_REQ_VERSION_1| for valid CSRs. For compatibility, +// |d2i_X509_REQ| also accepts some invalid version numbers, in which case this +// function may return other values. +OPENSSL_EXPORT long X509_REQ_get_version(const X509_REQ *req); + +// X509_REQ_get_subject_name returns |req|'s subject name. Note this function is +// not const-correct for legacy reasons. +OPENSSL_EXPORT X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); + +// X509_REQ_get_pubkey returns |req|'s public key as an |EVP_PKEY|, or NULL if +// the public key was unsupported or could not be decoded. This function returns +// a reference to the |EVP_PKEY|. The caller must release the result with +// |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); + +// X509_REQ_get_attr_count returns the number of attributes in |req|. +OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); + +// X509_REQ_get_attr returns the attribute at index |loc| in |req|, or NULL if +// out of bounds. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); + +// X509_REQ_get_attr_by_NID returns the index of the attribute in |req| of type +// |nid|, or a negative number if not found. If found, callers can use +// |X509_REQ_get_attr| to look up the attribute by index. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching attributes by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); + +// X509_REQ_get_attr_by_OBJ behaves like |X509_REQ_get_attr_by_NID| but looks +// for attributes of type |obj|. +OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, + const ASN1_OBJECT *obj, + int lastpos); + +// X509_REQ_extension_nid returns one if |nid| is a supported CSR attribute type +// for carrying extensions and zero otherwise. The supported types are +// |NID_ext_req| (pkcs-9-at-extensionRequest from RFC 2985) and |NID_ms_ext_req| +// (a Microsoft szOID_CERT_EXTENSIONS variant). +OPENSSL_EXPORT int X509_REQ_extension_nid(int nid); + +// X509_REQ_get_extensions decodes the list of requested extensions in |req| and +// returns a newly-allocated |STACK_OF(X509_EXTENSION)| containing the result. +// It returns NULL on error, or if |req| did not request extensions. +// +// CSRs do not store extensions directly. Instead there are attribute types +// which are defined to hold extensions. See |X509_REQ_extension_nid|. This +// function supports both pkcs-9-at-extensionRequest from RFC 2985 and the +// Microsoft szOID_CERT_EXTENSIONS variant. If both are present, +// pkcs-9-at-extensionRequest is preferred. +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); + +// X509_REQ_get0_signature sets |*out_sig| and |*out_alg| to the signature and +// signature algorithm of |req|, respectively. Either output pointer may be NULL +// to ignore the value. +OPENSSL_EXPORT void X509_REQ_get0_signature(const X509_REQ *req, + const ASN1_BIT_STRING **out_sig, + const X509_ALGOR **out_alg); + +// X509_REQ_get_signature_nid returns the NID corresponding to |req|'s signature +// algorithm, or |NID_undef| if the signature algorithm does not correspond to +// a known NID. +OPENSSL_EXPORT int X509_REQ_get_signature_nid(const X509_REQ *req); + +// X509_REQ_verify checks that |req| has a valid signature by |pkey|. It returns +// one if the signature is valid and zero otherwise. +OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey); + + +// Issuing certificate requests. +// +// An |X509_REQ| object may also represent an incomplete CSR. Callers may +// construct empty |X509_REQ| objects, fill in fields individually, and finally +// sign the result. The following functions may be used for this purpose. + +// X509_REQ_new returns a newly-allocated, empty |X509_REQ| object, or NULL on +// error. This object may be filled in and then signed to construct a CSR. +OPENSSL_EXPORT X509_REQ *X509_REQ_new(void); + +// X509_REQ_set_version sets |req|'s version to |version|, which should be +// |X509_REQ_VERSION_1|. It returns one on success and zero on error. +// +// The only defined CSR version is |X509_REQ_VERSION_1|, so there is no need to +// call this function. +OPENSSL_EXPORT int X509_REQ_set_version(X509_REQ *req, long version); + +// X509_REQ_set_subject_name sets |req|'s subject to a copy of |name|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); + +// X509_REQ_set_pubkey sets |req|'s public key to |pkey|. It returns one on +// success and zero on error. This function does not take ownership of |pkey| +// and internally copies and updates reference counts as needed. +OPENSSL_EXPORT int X509_REQ_set_pubkey(X509_REQ *req, EVP_PKEY *pkey); + +// X509_REQ_delete_attr removes the attribute at index |loc| in |req|. It +// returns the removed attribute to the caller, or NULL if |loc| was out of +// bounds. If non-NULL, the caller must release the result with +// |X509_ATTRIBUTE_free| when done. It is also safe, but not necessary, to call +// |X509_ATTRIBUTE_free| if the result is NULL. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); + +// X509_REQ_add1_attr appends a copy of |attr| to |req|'s list of attributes. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, + const X509_ATTRIBUTE *attr); + +// X509_REQ_add1_attr_by_OBJ appends a new attribute to |req| with type |obj|. +// It returns one on success and zero on error. The value is determined by +// |X509_ATTRIBUTE_set1_data|. +// +// WARNING: The interpretation of |attrtype|, |data|, and |len| is complex and +// error-prone. See |X509_ATTRIBUTE_set1_data| for details. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, + int attrtype, + const unsigned char *data, + int len); + +// X509_REQ_add1_attr_by_NID behaves like |X509_REQ_add1_attr_by_OBJ| except the +// attribute type is determined by |nid|. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, + int attrtype, + const unsigned char *data, + int len); + +// X509_REQ_add1_attr_by_txt behaves like |X509_REQ_add1_attr_by_OBJ| except the +// attribute type is determined by calling |OBJ_txt2obj| with |attrname|. +OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int attrtype, + const unsigned char *data, + int len); + +// X509_REQ_add_extensions_nid adds an attribute to |req| of type |nid|, to +// request the certificate extensions in |exts|. It returns one on success and +// zero on error. |nid| should be |NID_ext_req| or |NID_ms_ext_req|. +OPENSSL_EXPORT int X509_REQ_add_extensions_nid( + X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts, int nid); + +// X509_REQ_add_extensions behaves like |X509_REQ_add_extensions_nid|, using the +// standard |NID_ext_req| for the attribute type. +OPENSSL_EXPORT int X509_REQ_add_extensions( + X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts); + +// X509_REQ_sign signs |req| with |pkey| and replaces the signature algorithm +// and signature fields. It returns the length of the signature on success and +// zero on error. This function uses digest algorithm |md|, or |pkey|'s default +// if NULL. Other signing parameters use |pkey|'s defaults. To customize them, +// use |X509_REQ_sign_ctx|. +OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *req, EVP_PKEY *pkey, + const EVP_MD *md); + +// X509_REQ_sign_ctx signs |req| with |ctx| and replaces the signature algorithm +// and signature fields. It returns the length of the signature on success and +// zero on error. The signature algorithm and parameters come from |ctx|, which +// must have been initialized with |EVP_DigestSignInit|. The caller should +// configure the corresponding |EVP_PKEY_CTX| before calling this function. +OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *req, EVP_MD_CTX *ctx); + +// i2d_re_X509_REQ_tbs serializes the CertificationRequestInfo (see RFC 2986) +// portion of |req|, as described in |i2d_SAMPLE|. +// +// This function re-encodes the CertificationRequestInfo and may not reflect +// |req|'s original encoding. It may be used to manually generate a signature +// for a new certificate request. +OPENSSL_EXPORT int i2d_re_X509_REQ_tbs(X509_REQ *req, uint8_t **outp); + +// X509_REQ_set1_signature_algo sets |req|'s signature algorithm to |algo| and +// returns one on success or zero on error. +OPENSSL_EXPORT int X509_REQ_set1_signature_algo(X509_REQ *req, + const X509_ALGOR *algo); + +// X509_REQ_set1_signature_value sets |req|'s signature to a copy of the +// |sig_len| bytes pointed by |sig|. It returns one on success and zero on +// error. +// +// Due to a specification error, PKCS#10 certificate requests store signatures +// in ASN.1 BIT STRINGs, but signature algorithms return byte strings rather +// than bit strings. This function creates a BIT STRING containing a whole +// number of bytes, with the bit order matching the DER encoding. This matches +// the encoding used by all X.509 signature algorithms. +OPENSSL_EXPORT int X509_REQ_set1_signature_value(X509_REQ *req, + const uint8_t *sig, + size_t sig_len); + + +// Names. +// +// An |X509_NAME| represents an X.509 Name structure (RFC 5280). X.509 names are +// a complex, hierarchical structure over a collection of attributes. Each name +// is sequence of relative distinguished names (RDNs), decreasing in +// specificity. For example, the first RDN may specify the country, while the +// next RDN may specify a locality. Each RDN is, itself, a set of attributes. +// Having more than one attribute in an RDN is uncommon, but possible. Within an +// RDN, attributes have the same level in specificity. Attribute types are +// OBJECT IDENTIFIERs. This determines the ASN.1 type of the value, which is +// commonly a string but may be other types. +// +// The |X509_NAME| representation flattens this two-level structure into a +// single list of attributes. Each attribute is stored in an |X509_NAME_ENTRY|, +// with also maintains the index of the RDN it is part of, accessible via +// |X509_NAME_ENTRY_set|. This can be used to recover the two-level structure. +// +// X.509 names are largely vestigial. Historically, DNS names were parsed out of +// the subject's common name attribute, but this is deprecated and has since +// moved to the subject alternative name extension. In modern usage, X.509 names +// are primarily opaque identifiers to link a certificate with its issuer. + +DEFINE_STACK_OF(X509_NAME_ENTRY) +DEFINE_STACK_OF(X509_NAME) + +// X509_NAME is an |ASN1_ITEM| whose ASN.1 type is X.509 Name (RFC 5280) and C +// type is |X509_NAME*|. +DECLARE_ASN1_ITEM(X509_NAME) + +// X509_NAME_new returns a new, empty |X509_NAME_new|, or NULL on +// error. +OPENSSL_EXPORT X509_NAME *X509_NAME_new(void); + +// X509_NAME_free releases memory associated with |name|. +OPENSSL_EXPORT void X509_NAME_free(X509_NAME *name); + +// d2i_X509_NAME parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// Name (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_NAME *d2i_X509_NAME(X509_NAME **out, const uint8_t **inp, + long len); + +// i2d_X509_NAME marshals |in| as a DER-encoded X.509 Name (RFC 5280), as +// described in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |in| was +// mutated. +OPENSSL_EXPORT int i2d_X509_NAME(X509_NAME *in, uint8_t **outp); + +// X509_NAME_dup returns a newly-allocated copy of |name|, or NULL on error. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |name| was +// mutated. +OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *name); + +// X509_NAME_get0_der sets |*out_der| and |*out_der_len| +// +// Avoid this function and prefer |i2d_X509_NAME|. It is one of the reasons +// these functions are not consistently thread-safe or const-correct. Depending +// on the resolution of https://crbug.com/boringssl/407, this function may be +// removed or cause poor performance. +OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *name, const uint8_t **out_der, + size_t *out_der_len); + +// X509_NAME_set makes a copy of |name|. On success, it frees |*xn|, sets |*xn| +// to the copy, and returns one. Otherwise, it returns zero. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |name| was +// mutated. +OPENSSL_EXPORT int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +// X509_NAME_entry_count returns the number of entries in |name|. +OPENSSL_EXPORT int X509_NAME_entry_count(const X509_NAME *name); + +// X509_NAME_get_index_by_NID returns the zero-based index of the first +// attribute in |name| with type |nid|, or -1 if there is none. |nid| should be +// one of the |NID_*| constants. If |lastpos| is non-negative, it begins +// searching at |lastpos+1|. To search all attributes, pass in -1, not zero. +// +// Indices from this function refer to |X509_NAME|'s flattened representation. +OPENSSL_EXPORT int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, + int lastpos); + +// X509_NAME_get_index_by_OBJ behaves like |X509_NAME_get_index_by_NID| but +// looks for attributes with type |obj|. +OPENSSL_EXPORT int X509_NAME_get_index_by_OBJ(const X509_NAME *name, + const ASN1_OBJECT *obj, + int lastpos); + +// X509_NAME_get_entry returns the attribute in |name| at index |loc|, or NULL +// if |loc| is out of range. |loc| is interpreted using |X509_NAME|'s flattened +// representation. This function returns a non-const pointer for OpenSSL +// compatibility, but callers should not mutate the result. Doing so will break +// internal invariants in the library. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, + int loc); + +// X509_NAME_delete_entry removes and returns the attribute in |name| at index +// |loc|, or NULL if |loc| is out of range. |loc| is interpreted using +// |X509_NAME|'s flattened representation. If the attribute is found, the caller +// is responsible for releasing the result with |X509_NAME_ENTRY_free|. +// +// This function will internally update RDN indices (see |X509_NAME_ENTRY_set|) +// so they continue to be consecutive. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, + int loc); + +// X509_NAME_add_entry adds a copy of |entry| to |name| and returns one on +// success or zero on error. If |loc| is -1, the entry is appended to |name|. +// Otherwise, it is inserted at index |loc|. If |set| is -1, the entry is added +// to the previous entry's RDN. If it is 0, the entry becomes a singleton RDN. +// If 1, it is added to next entry's RDN. +// +// This function will internally update RDN indices (see |X509_NAME_ENTRY_set|) +// so they continue to be consecutive. +OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name, + const X509_NAME_ENTRY *entry, int loc, + int set); + +// X509_NAME_add_entry_by_OBJ adds a new entry to |name| and returns one on +// success or zero on error. The entry's attribute type is |obj|. The entry's +// attribute value is determined by |type|, |bytes|, and |len|, as in +// |X509_NAME_ENTRY_set_data|. The entry's position is determined by |loc| and +// |set| as in |X509_NAME_add_entry|. +OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, + const ASN1_OBJECT *obj, int type, + const uint8_t *bytes, + ossl_ssize_t len, int loc, + int set); + +// X509_NAME_add_entry_by_NID behaves like |X509_NAME_add_entry_by_OBJ| but sets +// the entry's attribute type to |nid|, which should be one of the |NID_*| +// constants. +OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, + int type, const uint8_t *bytes, + ossl_ssize_t len, int loc, + int set); + +// X509_NAME_add_entry_by_txt behaves like |X509_NAME_add_entry_by_OBJ| but sets +// the entry's attribute type to |field|, which is passed to |OBJ_txt2obj|. +OPENSSL_EXPORT int X509_NAME_add_entry_by_txt(X509_NAME *name, + const char *field, int type, + const uint8_t *bytes, + ossl_ssize_t len, int loc, + int set); + +// X509_NAME_ENTRY is an |ASN1_ITEM| whose ASN.1 type is AttributeTypeAndValue +// (RFC 5280) and C type is |X509_NAME_ENTRY*|. +DECLARE_ASN1_ITEM(X509_NAME_ENTRY) + +// X509_NAME_ENTRY_new returns a new, empty |X509_NAME_ENTRY_new|, or NULL on +// error. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_new(void); + +// X509_NAME_ENTRY_free releases memory associated with |entry|. +OPENSSL_EXPORT void X509_NAME_ENTRY_free(X509_NAME_ENTRY *entry); + +// d2i_X509_NAME_ENTRY parses up to |len| bytes from |*inp| as a DER-encoded +// AttributeTypeAndValue (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **out, + const uint8_t **inp, + long len); + +// i2d_X509_NAME_ENTRY marshals |in| as a DER-encoded AttributeTypeAndValue (RFC +// 5280), as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_NAME_ENTRY(const X509_NAME_ENTRY *in, + uint8_t **outp); + +// X509_NAME_ENTRY_dup returns a newly-allocated copy of |entry|, or NULL on +// error. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup( + const X509_NAME_ENTRY *entry); + +// X509_NAME_ENTRY_get_object returns |entry|'s attribute type. This function +// returns a non-const pointer for OpenSSL compatibility, but callers should not +// mutate the result. Doing so will break internal invariants in the library. +OPENSSL_EXPORT ASN1_OBJECT *X509_NAME_ENTRY_get_object( + const X509_NAME_ENTRY *entry); + +// X509_NAME_ENTRY_set_object sets |entry|'s attribute type to |obj|. It returns +// one on success and zero on error. +OPENSSL_EXPORT int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *entry, + const ASN1_OBJECT *obj); + +// X509_NAME_ENTRY_get_data returns |entry|'s attribute value, represented as an +// |ASN1_STRING|. This value may have any ASN.1 type, so callers must check the +// type before interpreting the contents. This function returns a non-const +// pointer for OpenSSL compatibility, but callers should not mutate the result. +// Doing so will break internal invariants in the library. +// +// TODO(https://crbug.com/boringssl/412): Although the spec says any ASN.1 type +// is allowed, we currently only allow an ad-hoc set of types. Additionally, it +// is unclear if some types can even be represented by this function. +OPENSSL_EXPORT ASN1_STRING *X509_NAME_ENTRY_get_data( + const X509_NAME_ENTRY *entry); + +// X509_NAME_ENTRY_set_data sets |entry|'s value to |len| bytes from |bytes|. It +// returns one on success and zero on error. If |len| is -1, |bytes| must be a +// NUL-terminated C string and the length is determined by |strlen|. |bytes| is +// converted to an ASN.1 type as follows: +// +// If |type| is a |MBSTRING_*| constant, the value is an ASN.1 string. The +// string is determined by decoding |bytes| in the encoding specified by |type|, +// and then re-encoding it in a form appropriate for |entry|'s attribute type. +// See |ASN1_STRING_set_by_NID| for details. +// +// Otherwise, the value is an |ASN1_STRING| with type |type| and value |bytes|. +// See |ASN1_STRING| for how to format ASN.1 types as an |ASN1_STRING|. If +// |type| is |V_ASN1_UNDEF| the previous |ASN1_STRING| type is reused. +OPENSSL_EXPORT int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *entry, int type, + const uint8_t *bytes, + ossl_ssize_t len); + +// X509_NAME_ENTRY_set returns the zero-based index of the RDN which contains +// |entry|. Consecutive entries with the same index are part of the same RDN. +OPENSSL_EXPORT int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *entry); + +// X509_NAME_ENTRY_create_by_OBJ creates a new |X509_NAME_ENTRY| with attribute +// type |obj|. The attribute value is determined from |type|, |bytes|, and |len| +// as in |X509_NAME_ENTRY_set_data|. It returns the |X509_NAME_ENTRY| on success +// and NULL on error. +// +// If |out| is non-NULL and |*out| is NULL, it additionally sets |*out| to the +// result on success. If both |out| and |*out| are non-NULL, it updates the +// object at |*out| instead of allocating a new one. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ( + X509_NAME_ENTRY **out, const ASN1_OBJECT *obj, int type, + const uint8_t *bytes, ossl_ssize_t len); + +// X509_NAME_ENTRY_create_by_NID behaves like |X509_NAME_ENTRY_create_by_OBJ| +// except the attribute type is |nid|, which should be one of the |NID_*| +// constants. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID( + X509_NAME_ENTRY **out, int nid, int type, const uint8_t *bytes, + ossl_ssize_t len); + +// X509_NAME_ENTRY_create_by_txt behaves like |X509_NAME_ENTRY_create_by_OBJ| +// except the attribute type is |field|, which is passed to |OBJ_txt2obj|. +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt( + X509_NAME_ENTRY **out, const char *field, int type, const uint8_t *bytes, + ossl_ssize_t len); + + +// Extensions. +// +// X.509 certificates and CRLs may contain a list of extensions (RFC 5280). +// Extensions have a type, specified by an object identifier (|ASN1_OBJECT|) and +// a byte string value, which should a DER-encoded structure whose type is +// determined by the extension type. This library represents extensions with the +// |X509_EXTENSION| type. + +// X509_EXTENSION is an |ASN1_ITEM| whose ASN.1 type is X.509 Extension (RFC +// 5280) and C type is |X509_EXTENSION*|. +DECLARE_ASN1_ITEM(X509_EXTENSION) + +// X509_EXTENSION_new returns a newly-allocated, empty |X509_EXTENSION| object +// or NULL on error. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_new(void); + +// X509_EXTENSION_free releases memory associated with |ex|. +OPENSSL_EXPORT void X509_EXTENSION_free(X509_EXTENSION *ex); + +// d2i_X509_EXTENSION parses up to |len| bytes from |*inp| as a DER-encoded +// X.509 Extension (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **out, + const uint8_t **inp, + long len); + +// i2d_X509_EXTENSION marshals |ex| as a DER-encoded X.509 Extension (RFC +// 5280), as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_EXTENSION(const X509_EXTENSION *ex, uint8_t **outp); + +// X509_EXTENSION_dup returns a newly-allocated copy of |ex|, or NULL on error. +// This function works by serializing the structure, so if |ex| is incomplete, +// it may fail. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(const X509_EXTENSION *ex); + +// X509_EXTENSION_create_by_NID creates a new |X509_EXTENSION| with type |nid|, +// value |data|, and critical bit |crit|. It returns an |X509_EXTENSION| on +// success, and NULL on error. |nid| should be a |NID_*| constant. +// +// If |ex| and |*ex| are both non-NULL, |*ex| is used to hold the result, +// otherwise a new object is allocated. If |ex| is non-NULL and |*ex| is NULL, +// the function sets |*ex| to point to the newly allocated result, in addition +// to returning the result. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID( + X509_EXTENSION **ex, int nid, int crit, const ASN1_OCTET_STRING *data); + +// X509_EXTENSION_create_by_OBJ behaves like |X509_EXTENSION_create_by_NID|, but +// the extension type is determined by an |ASN1_OBJECT|. +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ( + X509_EXTENSION **ex, const ASN1_OBJECT *obj, int crit, + const ASN1_OCTET_STRING *data); + +// X509_EXTENSION_get_object returns |ex|'s extension type. This function +// returns a non-const pointer for OpenSSL compatibility, but callers should not +// mutate the result. +OPENSSL_EXPORT ASN1_OBJECT *X509_EXTENSION_get_object(const X509_EXTENSION *ex); + +// X509_EXTENSION_get_data returns |ne|'s extension value. This function returns +// a non-const pointer for OpenSSL compatibility, but callers should not mutate +// the result. +OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data( + const X509_EXTENSION *ne); + +// X509_EXTENSION_get_critical returns one if |ex| is critical and zero +// otherwise. +OPENSSL_EXPORT int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +// X509_EXTENSION_set_object sets |ex|'s extension type to |obj|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_EXTENSION_set_object(X509_EXTENSION *ex, + const ASN1_OBJECT *obj); + +// X509_EXTENSION_set_critical sets |ex| to critical if |crit| is non-zero and +// to non-critical if |crit| is zero. +OPENSSL_EXPORT int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); + +// X509_EXTENSION_set_data set's |ex|'s extension value to a copy of |data|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_EXTENSION_set_data(X509_EXTENSION *ex, + const ASN1_OCTET_STRING *data); + + +// Extension lists. +// +// The following functions manipulate lists of extensions. Most of them have +// corresponding functions on the containing |X509|, |X509_CRL|, or +// |X509_REVOKED|. + +DEFINE_STACK_OF(X509_EXTENSION) +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +// X509_EXTENSIONS is an |ASN1_ITEM| whose ASN.1 type is SEQUENCE of Extension +// (RFC 5280) and C type is |STACK_OF(X509_EXTENSION)*|. +DECLARE_ASN1_ITEM(X509_EXTENSIONS) + +// d2i_X509_EXTENSIONS parses up to |len| bytes from |*inp| as a DER-encoded +// SEQUENCE OF Extension (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_EXTENSIONS *d2i_X509_EXTENSIONS(X509_EXTENSIONS **out, + const uint8_t **inp, + long len); + +// i2d_X509_EXTENSIONS marshals |alg| as a DER-encoded SEQUENCE OF Extension +// (RFC 5280), as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_EXTENSIONS(const X509_EXTENSIONS *alg, + uint8_t **outp); + +// X509v3_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); + +// X509v3_get_ext_by_NID returns the index of the first extension in |x| with +// type |nid|, or a negative number if not found. If found, callers can use +// |X509v3_get_ext| to look up the extension by index. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching extensions by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); + +// X509v3_get_ext_by_OBJ behaves like |X509v3_get_ext_by_NID| but looks for +// extensions matching |obj|. +OPENSSL_EXPORT int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); + +// X509v3_get_ext_by_critical returns the index of the first extension in |x| +// whose critical bit matches |crit|, or a negative number if no such extension +// was found. +// +// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers +// can thus loop over all matching extensions by first passing -1 and then +// passing the previously-returned value until no match is returned. +OPENSSL_EXPORT int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); + +// X509v3_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| +// is out of bounds. This function returns a non-const pointer for OpenSSL +// compatibility, but callers should not mutate the result. +OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, + int loc); + +// X509v3_delete_ext removes the extension in |x| at index |loc| and returns the +// removed extension, or NULL if |loc| was out of bounds. If an extension was +// returned, the caller must release it with |X509_EXTENSION_free|. +OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, + int loc); + +// X509v3_add_ext adds a copy of |ex| to the extension list in |*x|. If |*x| is +// NULL, it allocates a new |STACK_OF(X509_EXTENSION)| to hold the copy and sets +// |*x| to the new list. It returns |*x| on success and NULL on error. The +// caller retains ownership of |ex| and can release it independently of |*x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext( + STACK_OF(X509_EXTENSION) **x, const X509_EXTENSION *ex, int loc); + + +// Algorithm identifiers. +// +// An |X509_ALGOR| represents an AlgorithmIdentifier structure, used in X.509 +// to represent signature algorithms and public key algorithms. + +DEFINE_STACK_OF(X509_ALGOR) + +// X509_ALGOR is an |ASN1_ITEM| whose ASN.1 type is AlgorithmIdentifier and C +// type is |X509_ALGOR*|. +DECLARE_ASN1_ITEM(X509_ALGOR) + +// X509_ALGOR_new returns a newly-allocated, empty |X509_ALGOR| object, or NULL +// on error. +OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_new(void); + +// X509_ALGOR_dup returns a newly-allocated copy of |alg|, or NULL on error. +// This function works by serializing the structure, so if |alg| is incomplete, +// it may fail. +OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg); + +// X509_ALGOR_free releases memory associated with |alg|. +OPENSSL_EXPORT void X509_ALGOR_free(X509_ALGOR *alg); + +// d2i_X509_ALGOR parses up to |len| bytes from |*inp| as a DER-encoded +// AlgorithmIdentifier, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **out, const uint8_t **inp, + long len); + +// i2d_X509_ALGOR marshals |alg| as a DER-encoded AlgorithmIdentifier, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_ALGOR(const X509_ALGOR *alg, uint8_t **outp); // X509_ALGOR_set0 sets |alg| to an AlgorithmIdentifier with algorithm |obj| and // parameter determined by |param_type| and |param_value|. It returns one on @@ -787,67 +1398,42 @@ OPENSSL_EXPORT void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); // ordering. OPENSSL_EXPORT int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); -OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *xn); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); -OPENSSL_EXPORT int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); -OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, - size_t *pderlen); - -// X509_cmp_time compares |s| against |*t|. On success, it returns a negative -// number if |s| <= |*t| and a positive number if |s| > |*t|. On error, it -// returns zero. If |t| is NULL, it uses the current time instead of |*t|. +// Attributes. // -// WARNING: Unlike most comparison functions, this function returns zero on -// error, not equality. -OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); +// Unlike certificates and CRLs, CSRs use a separate Attribute structure (RFC +// 2985, RFC 2986) for extensibility. This is represented by the library as +// |X509_ATTRIBUTE|. -// X509_cmp_current_time behaves like |X509_cmp_time| but compares |s| against -// the current time. -OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); +DEFINE_STACK_OF(X509_ATTRIBUTE) -// X509_time_adj calls |X509_time_adj_ex| with |offset_day| equal to zero. -OPENSSL_EXPORT ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, - time_t *t); +// X509_ATTRIBUTE is an |ASN1_ITEM| whose ASN.1 type is Attribute (RFC 2986) and +// C type is |X509_ATTRIBUTE*|. +DECLARE_ASN1_ITEM(X509_ATTRIBUTE) -// X509_time_adj_ex behaves like |ASN1_TIME_adj|, but adds an offset to |*t|. If -// |t| is NULL, it uses the current time instead of |*t|. -OPENSSL_EXPORT ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, - long offset_sec, time_t *t); +// X509_ATTRIBUTE_new returns a newly-allocated, empty |X509_ATTRIBUTE| object, +// or NULL on error. |X509_ATTRIBUTE_set1_*| may be used to finish initializing +// it. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_new(void); -// X509_gmtime_adj behaves like |X509_time_adj_ex| but adds |offset_sec| to the -// current time. -OPENSSL_EXPORT ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec); +// X509_ATTRIBUTE_dup returns a newly-allocated copy of |attr|, or NULL on +// error. This function works by serializing the structure, so if |attr| is +// incomplete, it may fail. +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(const X509_ATTRIBUTE *attr); -OPENSSL_EXPORT const char *X509_get_default_cert_area(void); -OPENSSL_EXPORT const char *X509_get_default_cert_dir(void); -OPENSSL_EXPORT const char *X509_get_default_cert_file(void); -OPENSSL_EXPORT const char *X509_get_default_cert_dir_env(void); -OPENSSL_EXPORT const char *X509_get_default_cert_file_env(void); -OPENSSL_EXPORT const char *X509_get_default_private_dir(void); +// X509_ATTRIBUTE_free releases memory associated with |attr|. +OPENSSL_EXPORT void X509_ATTRIBUTE_free(X509_ATTRIBUTE *attr); -OPENSSL_EXPORT X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, - const EVP_MD *md); +// d2i_X509_ATTRIBUTE parses up to |len| bytes from |*inp| as a DER-encoded +// Attribute (RFC 2986), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_ATTRIBUTE *d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **out, + const uint8_t **inp, + long len); -DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) - -DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) - -// X509_PUBKEY_set serializes |pkey| into a newly-allocated |X509_PUBKEY| -// structure. On success, it frees |*x|, sets |*x| to the new object, and -// returns one. Otherwise, it returns zero. -OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); - -// X509_PUBKEY_get decodes the public key in |key| and returns an |EVP_PKEY| on -// success, or NULL on error. The caller must release the result with -// |EVP_PKEY_free| when done. The |EVP_PKEY| is cached in |key|, so callers must -// not mutate the result. -OPENSSL_EXPORT EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); - -DECLARE_ASN1_FUNCTIONS(X509_SIG) -DECLARE_ASN1_FUNCTIONS(X509_REQ) - -DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +// i2d_X509_ATTRIBUTE marshals |alg| as a DER-encoded Attribute (RFC 2986), as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_ATTRIBUTE(const X509_ATTRIBUTE *alg, + uint8_t **outp); // X509_ATTRIBUTE_create returns a newly-allocated |X509_ATTRIBUTE|, or NULL on // error. The attribute has type |nid| and contains a single value determined by @@ -856,832 +1442,6 @@ DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int attrtype, void *value); -DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) -DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) - -DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) - -DECLARE_ASN1_FUNCTIONS(X509_NAME) - -// X509_NAME_set makes a copy of |name|. On success, it frees |*xn|, sets |*xn| -// to the copy, and returns one. Otherwise, it returns zero. -OPENSSL_EXPORT int X509_NAME_set(X509_NAME **xn, X509_NAME *name); - -DECLARE_ASN1_FUNCTIONS(X509) -DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) - -// X509_up_ref adds one to the reference count of |x509| and returns one. -OPENSSL_EXPORT int X509_up_ref(X509 *x509); - -OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_unused *unused, - CRYPTO_EX_dup *dup_unused, - CRYPTO_EX_free *free_func); -OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); -OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); -OPENSSL_EXPORT int i2d_X509_AUX(X509 *a, unsigned char **pp); -OPENSSL_EXPORT X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, - long length); - -// i2d_re_X509_tbs serializes the TBSCertificate portion of |x509|, as described -// in |i2d_SAMPLE|. -// -// This function re-encodes the TBSCertificate and may not reflect |x509|'s -// original encoding. It may be used to manually generate a signature for a new -// certificate. To verify certificates, use |i2d_X509_tbs| instead. -OPENSSL_EXPORT int i2d_re_X509_tbs(X509 *x509, unsigned char **outp); - -// i2d_X509_tbs serializes the TBSCertificate portion of |x509|, as described in -// |i2d_SAMPLE|. -// -// This function preserves the original encoding of the TBSCertificate and may -// not reflect modifications made to |x509|. It may be used to manually verify -// the signature of an existing certificate. To generate certificates, use -// |i2d_re_X509_tbs| instead. -OPENSSL_EXPORT int i2d_X509_tbs(X509 *x509, unsigned char **outp); - -// X509_set1_signature_algo sets |x509|'s signature algorithm to |algo| and -// returns one on success or zero on error. It updates both the signature field -// of the TBSCertificate structure, and the signatureAlgorithm field of the -// Certificate. -OPENSSL_EXPORT int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo); - -// X509_set1_signature_value sets |x509|'s signature to a copy of the |sig_len| -// bytes pointed by |sig|. It returns one on success and zero on error. -// -// Due to a specification error, X.509 certificates store signatures in ASN.1 -// BIT STRINGs, but signature algorithms return byte strings rather than bit -// strings. This function creates a BIT STRING containing a whole number of -// bytes, with the bit order matching the DER encoding. This matches the -// encoding used by all X.509 signature algorithms. -OPENSSL_EXPORT int X509_set1_signature_value(X509 *x509, const uint8_t *sig, - size_t sig_len); - -// X509_get0_signature sets |*out_sig| and |*out_alg| to the signature and -// signature algorithm of |x509|, respectively. Either output pointer may be -// NULL to ignore the value. -// -// This function outputs the outer signature algorithm. For the one in the -// TBSCertificate, see |X509_get0_tbs_sigalg|. Certificates with mismatched -// signature algorithms will successfully parse, but they will be rejected when -// verifying. -OPENSSL_EXPORT void X509_get0_signature(const ASN1_BIT_STRING **out_sig, - const X509_ALGOR **out_alg, - const X509 *x509); - -// X509_get_signature_nid returns the NID corresponding to |x509|'s signature -// algorithm, or |NID_undef| if the signature algorithm does not correspond to -// a known NID. -OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x509); - -OPENSSL_EXPORT int X509_alias_set1(X509 *x, const unsigned char *name, int len); -OPENSSL_EXPORT int X509_keyid_set1(X509 *x, const unsigned char *id, int len); -OPENSSL_EXPORT unsigned char *X509_alias_get0(X509 *x, int *len); -OPENSSL_EXPORT unsigned char *X509_keyid_get0(X509 *x, int *len); -OPENSSL_EXPORT int (*X509_TRUST_set_default(int (*trust)(int, X509 *, - int)))(int, X509 *, - int); -OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); -OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); -OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); -OPENSSL_EXPORT void X509_trust_clear(X509 *x); -OPENSSL_EXPORT void X509_reject_clear(X509 *x); - -DECLARE_ASN1_FUNCTIONS(X509_REVOKED) -DECLARE_ASN1_FUNCTIONS(X509_CRL) - -OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); -OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, - ASN1_INTEGER *serial); -OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, - X509 *x); - -OPENSSL_EXPORT X509_PKEY *X509_PKEY_new(void); -OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); - -DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) -DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) - -OPENSSL_EXPORT X509_INFO *X509_INFO_new(void); -OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); -OPENSSL_EXPORT char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); - -OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, - unsigned char *md, unsigned int *len); - -OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, - void *data, unsigned char *md, - unsigned int *len); - -OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, - const X509_ALGOR *algor1, - const ASN1_BIT_STRING *signature, - void *data, EVP_PKEY *pkey); - -OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *data, - EVP_PKEY *pkey, const EVP_MD *type); -OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, - EVP_MD_CTX *ctx); - -// X509_get_serialNumber returns a mutable pointer to |x509|'s serial number. -// Prefer |X509_get0_serialNumber|. -OPENSSL_EXPORT ASN1_INTEGER *X509_get_serialNumber(X509 *x509); - -// X509_set_issuer_name sets |x509|'s issuer to a copy of |name|. It returns one -// on success and zero on error. -OPENSSL_EXPORT int X509_set_issuer_name(X509 *x509, X509_NAME *name); - -// X509_get_issuer_name returns |x509|'s issuer. -OPENSSL_EXPORT X509_NAME *X509_get_issuer_name(const X509 *x509); - -// X509_set_subject_name sets |x509|'s subject to a copy of |name|. It returns -// one on success and zero on error. -OPENSSL_EXPORT int X509_set_subject_name(X509 *x509, X509_NAME *name); - -// X509_get_issuer_name returns |x509|'s subject. -OPENSSL_EXPORT X509_NAME *X509_get_subject_name(const X509 *x509); - -// X509_set_pubkey sets |x509|'s public key to |pkey|. It returns one on success -// and zero on error. This function does not take ownership of |pkey| and -// internally copies and updates reference counts as needed. -OPENSSL_EXPORT int X509_set_pubkey(X509 *x509, EVP_PKEY *pkey); - -// X509_get_pubkey returns |x509|'s public key as an |EVP_PKEY|, or NULL if the -// public key was unsupported or could not be decoded. This function returns a -// reference to the |EVP_PKEY|. The caller must release the result with -// |EVP_PKEY_free| when done. -OPENSSL_EXPORT EVP_PKEY *X509_get_pubkey(X509 *x509); - -// X509_get0_pubkey_bitstr returns the BIT STRING portion of |x509|'s public -// key. Note this does not contain the AlgorithmIdentifier portion. -// -// WARNING: This function returns a non-const pointer for OpenSSL compatibility, -// but the caller must not modify the resulting object. Doing so will break -// internal invariants in |x509|. -OPENSSL_EXPORT ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x509); - -// X509_get0_extensions returns |x509|'s extension list, or NULL if |x509| omits -// it. -OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_get0_extensions( - const X509 *x509); - -// X509_get0_tbs_sigalg returns the signature algorithm in |x509|'s -// TBSCertificate. For the outer signature algorithm, see |X509_get0_signature|. -// -// Certificates with mismatched signature algorithms will successfully parse, -// but they will be rejected when verifying. -OPENSSL_EXPORT const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x509); - -// X509_REQ_set_version sets |req|'s version to |version|, which should be -// |X509_REQ_VERSION_1|. It returns one on success and zero on error. -// -// Note no versions other than |X509_REQ_VERSION_1| are defined for CSRs. -OPENSSL_EXPORT int X509_REQ_set_version(X509_REQ *req, long version); - -// X509_REQ_set_subject_name sets |req|'s subject to a copy of |name|. It -// returns one on success and zero on error. -OPENSSL_EXPORT int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); - -// X509_REQ_get0_signature sets |*out_sig| and |*out_alg| to the signature and -// signature algorithm of |req|, respectively. Either output pointer may be NULL -// to ignore the value. -OPENSSL_EXPORT void X509_REQ_get0_signature(const X509_REQ *req, - const ASN1_BIT_STRING **out_sig, - const X509_ALGOR **out_alg); - -// X509_REQ_get_signature_nid returns the NID corresponding to |req|'s signature -// algorithm, or |NID_undef| if the signature algorithm does not correspond to -// a known NID. -OPENSSL_EXPORT int X509_REQ_get_signature_nid(const X509_REQ *req); - -// i2d_re_X509_REQ_tbs serializes the CertificationRequestInfo (see RFC 2986) -// portion of |req|, as described in |i2d_SAMPLE|. -// -// This function re-encodes the CertificationRequestInfo and may not reflect -// |req|'s original encoding. It may be used to manually generate a signature -// for a new certificate request. -OPENSSL_EXPORT int i2d_re_X509_REQ_tbs(X509_REQ *req, uint8_t **outp); - -// X509_REQ_set_pubkey sets |req|'s public key to |pkey|. It returns one on -// success and zero on error. This function does not take ownership of |pkey| -// and internally copies and updates reference counts as needed. -OPENSSL_EXPORT int X509_REQ_set_pubkey(X509_REQ *req, EVP_PKEY *pkey); - -// X509_REQ_get_pubkey returns |req|'s public key as an |EVP_PKEY|, or NULL if -// the public key was unsupported or could not be decoded. This function returns -// a reference to the |EVP_PKEY|. The caller must release the result with -// |EVP_PKEY_free| when done. -OPENSSL_EXPORT EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); - -// X509_REQ_extension_nid returns one if |nid| is a supported CSR attribute type -// for carrying extensions and zero otherwise. The supported types are -// |NID_ext_req| (pkcs-9-at-extensionRequest from RFC 2985) and |NID_ms_ext_req| -// (a Microsoft szOID_CERT_EXTENSIONS variant). -OPENSSL_EXPORT int X509_REQ_extension_nid(int nid); - -// X509_REQ_get_extensions decodes the list of requested extensions in |req| and -// returns a newly-allocated |STACK_OF(X509_EXTENSION)| containing the result. -// It returns NULL on error, or if |req| did not request extensions. -// -// This function supports both pkcs-9-at-extensionRequest from RFC 2985 and the -// Microsoft szOID_CERT_EXTENSIONS variant. -OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); - -// X509_REQ_add_extensions_nid adds an attribute to |req| of type |nid|, to -// request the certificate extensions in |exts|. It returns one on success and -// zero on error. |nid| should be |NID_ext_req| or |NID_ms_ext_req|. -OPENSSL_EXPORT int X509_REQ_add_extensions_nid( - X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts, int nid); - -// X509_REQ_add_extensions behaves like |X509_REQ_add_extensions_nid|, using the -// standard |NID_ext_req| for the attribute type. -OPENSSL_EXPORT int X509_REQ_add_extensions( - X509_REQ *req, const STACK_OF(X509_EXTENSION) *exts); - -// X509_REQ_get_attr_count returns the number of attributes in |req|. -OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); - -// X509_REQ_get_attr_by_NID returns the index of the attribute in |req| of type -// |nid|, or a negative number if not found. If found, callers can use -// |X509_REQ_get_attr| to look up the attribute by index. -// -// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers -// can thus loop over all matching attributes by first passing -1 and then -// passing the previously-returned value until no match is returned. -OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, - int lastpos); - -// X509_REQ_get_attr_by_OBJ behaves like |X509_REQ_get_attr_by_NID| but looks -// for attributes of type |obj|. -OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, - const ASN1_OBJECT *obj, - int lastpos); - -// X509_REQ_get_attr returns the attribute at index |loc| in |req|, or NULL if -// out of bounds. -OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); - -// X509_REQ_delete_attr removes the attribute at index |loc| in |req|. It -// returns the removed attribute to the caller, or NULL if |loc| was out of -// bounds. If non-NULL, the caller must release the result with -// |X509_ATTRIBUTE_free| when done. It is also safe, but not necessary, to call -// |X509_ATTRIBUTE_free| if the result is NULL. -OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); - -// X509_REQ_add1_attr appends a copy of |attr| to |req|'s list of attributes. It -// returns one on success and zero on error. -// -// TODO(https://crbug.com/boringssl/407): |attr| should be const. -OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); - -// X509_REQ_add1_attr_by_OBJ appends a new attribute to |req| with type |obj|. -// It returns one on success and zero on error. The value is determined by -// |X509_ATTRIBUTE_set1_data|. -// -// WARNING: The interpretation of |attrtype|, |data|, and |len| is complex and -// error-prone. See |X509_ATTRIBUTE_set1_data| for details. -OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, - const ASN1_OBJECT *obj, - int attrtype, - const unsigned char *data, - int len); - -// X509_REQ_add1_attr_by_NID behaves like |X509_REQ_add1_attr_by_OBJ| except the -// attribute type is determined by |nid|. -OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, - int attrtype, - const unsigned char *data, - int len); - -// X509_REQ_add1_attr_by_txt behaves like |X509_REQ_add1_attr_by_OBJ| except the -// attribute type is determined by calling |OBJ_txt2obj| with |attrname|. -OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req, - const char *attrname, int attrtype, - const unsigned char *data, - int len); - -// X509_CRL_set_version sets |crl|'s version to |version|, which should be one -// of the |X509_CRL_VERSION_*| constants. It returns one on success and zero on -// error. -// -// If unsure, use |X509_CRL_VERSION_2|. Note that, unlike certificates, CRL -// versions are only defined up to v2. Callers should not use |X509_VERSION_3|. -OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *crl, long version); - -// X509_CRL_set_issuer_name sets |crl|'s issuer to a copy of |name|. It returns -// one on success and zero on error. -OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *crl, X509_NAME *name); - -OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl); - -// X509_CRL_up_ref adds one to the reference count of |crl| and returns one. -OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); - -// X509_CRL_get0_signature sets |*out_sig| and |*out_alg| to the signature and -// signature algorithm of |crl|, respectively. Either output pointer may be NULL -// to ignore the value. -// -// This function outputs the outer signature algorithm, not the one in the -// TBSCertList. CRLs with mismatched signature algorithms will successfully -// parse, but they will be rejected when verifying. -OPENSSL_EXPORT void X509_CRL_get0_signature(const X509_CRL *crl, - const ASN1_BIT_STRING **out_sig, - const X509_ALGOR **out_alg); - -// X509_CRL_get_signature_nid returns the NID corresponding to |crl|'s signature -// algorithm, or |NID_undef| if the signature algorithm does not correspond to -// a known NID. -OPENSSL_EXPORT int X509_CRL_get_signature_nid(const X509_CRL *crl); - -// i2d_re_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described -// in |i2d_SAMPLE|. -// -// This function re-encodes the TBSCertList and may not reflect |crl|'s original -// encoding. It may be used to manually generate a signature for a new CRL. To -// verify CRLs, use |i2d_X509_CRL_tbs| instead. -OPENSSL_EXPORT int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); - -// i2d_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described in -// |i2d_SAMPLE|. -// -// This function preserves the original encoding of the TBSCertList and may not -// reflect modifications made to |crl|. It may be used to manually verify the -// signature of an existing CRL. To generate CRLs, use |i2d_re_X509_CRL_tbs| -// instead. -OPENSSL_EXPORT int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp); - -// X509_CRL_set1_signature_algo sets |crl|'s signature algorithm to |algo| and -// returns one on success or zero on error. It updates both the signature field -// of the TBSCertList structure, and the signatureAlgorithm field of the CRL. -OPENSSL_EXPORT int X509_CRL_set1_signature_algo(X509_CRL *crl, - const X509_ALGOR *algo); - -// X509_CRL_set1_signature_value sets |crl|'s signature to a copy of the -// |sig_len| bytes pointed by |sig|. It returns one on success and zero on -// error. -// -// Due to a specification error, X.509 CRLs store signatures in ASN.1 BIT -// STRINGs, but signature algorithms return byte strings rather than bit -// strings. This function creates a BIT STRING containing a whole number of -// bytes, with the bit order matching the DER encoding. This matches the -// encoding used by all X.509 signature algorithms. -OPENSSL_EXPORT int X509_CRL_set1_signature_value(X509_CRL *crl, - const uint8_t *sig, - size_t sig_len); - -// X509_REVOKED_get0_serialNumber returns the serial number of the certificate -// revoked by |revoked|. -OPENSSL_EXPORT const ASN1_INTEGER *X509_REVOKED_get0_serialNumber( - const X509_REVOKED *revoked); - -// X509_REVOKED_set_serialNumber sets |revoked|'s serial number to |serial|. It -// returns one on success or zero on error. -OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *revoked, - const ASN1_INTEGER *serial); - -// X509_REVOKED_get0_revocationDate returns the revocation time of the -// certificate revoked by |revoked|. -OPENSSL_EXPORT const ASN1_TIME *X509_REVOKED_get0_revocationDate( - const X509_REVOKED *revoked); - -// X509_REVOKED_set_revocationDate sets |revoked|'s revocation time to |tm|. It -// returns one on success or zero on error. -OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, - const ASN1_TIME *tm); - -// X509_REVOKED_get0_extensions returns |r|'s extensions list, or NULL if |r| -// omits it. -OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions( - const X509_REVOKED *r); - -OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, - EVP_PKEY *skey, const EVP_MD *md, - unsigned int flags); - -OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); - -OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); -OPENSSL_EXPORT int X509_chain_check_suiteb(int *perror_depth, X509 *x, - STACK_OF(X509) *chain, - unsigned long flags); -OPENSSL_EXPORT int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, - unsigned long flags); - -// X509_chain_up_ref returns a newly-allocated |STACK_OF(X509)| containing a -// shallow copy of |chain|, or NULL on error. That is, the return value has the -// same contents as |chain|, and each |X509|'s reference count is incremented by -// one. -OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); - -OPENSSL_EXPORT int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); - -OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); -OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); - -OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); -OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); - -OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); -OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); - -OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); -OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); -OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); -OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); - -OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); -OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); -OPENSSL_EXPORT int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, - unsigned long cflag); -OPENSSL_EXPORT int X509_print_fp(FILE *bp, X509 *x); -OPENSSL_EXPORT int X509_CRL_print_fp(FILE *bp, X509_CRL *x); -OPENSSL_EXPORT int X509_REQ_print_fp(FILE *bp, X509_REQ *req); -OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, - int indent, unsigned long flags); - -OPENSSL_EXPORT int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); -OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, - unsigned long flags); -OPENSSL_EXPORT int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, - unsigned long cflag); -OPENSSL_EXPORT int X509_print(BIO *bp, X509 *x); -OPENSSL_EXPORT int X509_ocspid_print(BIO *bp, X509 *x); -OPENSSL_EXPORT int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); -OPENSSL_EXPORT int X509_CRL_print(BIO *bp, X509_CRL *x); -OPENSSL_EXPORT int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, - unsigned long cflag); -OPENSSL_EXPORT int X509_REQ_print(BIO *bp, X509_REQ *req); - -OPENSSL_EXPORT int X509_NAME_entry_count(const X509_NAME *name); -OPENSSL_EXPORT int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, - char *buf, int len); -OPENSSL_EXPORT int X509_NAME_get_text_by_OBJ(const X509_NAME *name, - const ASN1_OBJECT *obj, char *buf, - int len); - -// NOTE: you should be passsing -1, not 0 as lastpos. The functions that use -// lastpos, search after that position on. -OPENSSL_EXPORT int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, - int lastpos); -OPENSSL_EXPORT int X509_NAME_get_index_by_OBJ(const X509_NAME *name, - const ASN1_OBJECT *obj, - int lastpos); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, - int loc); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, - int loc); -OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, - int loc, int set); -OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, - int type, - const unsigned char *bytes, - int len, int loc, int set); -OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, - int type, - const unsigned char *bytes, - int len, int loc, int set); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt( - X509_NAME_ENTRY **ne, const char *field, int type, - const unsigned char *bytes, int len); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID( - X509_NAME_ENTRY **ne, int nid, int type, const unsigned char *bytes, - int len); -OPENSSL_EXPORT int X509_NAME_add_entry_by_txt(X509_NAME *name, - const char *field, int type, - const unsigned char *bytes, - int len, int loc, int set); -OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ( - X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); -OPENSSL_EXPORT int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, - const ASN1_OBJECT *obj); -OPENSSL_EXPORT int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, - int len); -OPENSSL_EXPORT ASN1_OBJECT *X509_NAME_ENTRY_get_object( - const X509_NAME_ENTRY *ne); -OPENSSL_EXPORT ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); - -// X509v3_get_ext_count returns the number of extensions in |x|. -OPENSSL_EXPORT int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); - -// X509v3_get_ext_by_NID returns the index of the first extension in |x| with -// type |nid|, or a negative number if not found. If found, callers can use -// |X509v3_get_ext| to look up the extension by index. -// -// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers -// can thus loop over all matching extensions by first passing -1 and then -// passing the previously-returned value until no match is returned. -OPENSSL_EXPORT int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, - int nid, int lastpos); - -// X509v3_get_ext_by_OBJ behaves like |X509v3_get_ext_by_NID| but looks for -// extensions matching |obj|. -OPENSSL_EXPORT int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, - const ASN1_OBJECT *obj, int lastpos); - -// X509v3_get_ext_by_critical returns the index of the first extension in |x| -// whose critical bit matches |crit|, or a negative number if no such extension -// was found. -// -// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers -// can thus loop over all matching extensions by first passing -1 and then -// passing the previously-returned value until no match is returned. -OPENSSL_EXPORT int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, - int crit, int lastpos); - -// X509v3_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| -// is out of bounds. -OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, - int loc); - -// X509v3_delete_ext removes the extension in |x| at index |loc| and returns the -// removed extension, or NULL if |loc| was out of bounds. If an extension was -// returned, the caller must release it with |X509_EXTENSION_free|. -OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, - int loc); - -// X509v3_add_ext adds a copy of |ex| to the extension list in |*x|. If |*x| is -// NULL, it allocates a new |STACK_OF(X509_EXTENSION)| to hold the copy and sets -// |*x| to the new list. It returns |*x| on success and NULL on error. The -// caller retains ownership of |ex| and can release it independently of |*x|. -// -// The new extension is inserted at index |loc|, shifting extensions to the -// right. If |loc| is -1 or out of bounds, the new extension is appended to the -// list. -OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext( - STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc); - -// X509_get_ext_count returns the number of extensions in |x|. -OPENSSL_EXPORT int X509_get_ext_count(const X509 *x); - -// X509_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for -// extensions in |x|. -OPENSSL_EXPORT int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); - -// X509_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for -// extensions in |x|. -OPENSSL_EXPORT int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, - int lastpos); - -// X509_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but -// searches for extensions in |x|. -OPENSSL_EXPORT int X509_get_ext_by_critical(const X509 *x, int crit, - int lastpos); - -// X509_get_ext returns the extension in |x| at index |loc|, or NULL if |loc| is -// out of bounds. -OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(const X509 *x, int loc); - -// X509_delete_ext removes the extension in |x| at index |loc| and returns the -// removed extension, or NULL if |loc| was out of bounds. If non-NULL, the -// caller must release the result with |X509_EXTENSION_free|. It is also safe, -// but not necessary, to call |X509_EXTENSION_free| if the result is NULL. -OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc); - -// X509_add_ext adds a copy of |ex| to |x|. It returns one on success and zero -// on failure. The caller retains ownership of |ex| and can release it -// independently of |x|. -// -// The new extension is inserted at index |loc|, shifting extensions to the -// right. If |loc| is -1 or out of bounds, the new extension is appended to the -// list. -OPENSSL_EXPORT int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); - -// X509_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the extension in -// |x509|'s extension list. -// -// WARNING: This function is difficult to use correctly. See the documentation -// for |X509V3_get_d2i| for details. -OPENSSL_EXPORT void *X509_get_ext_d2i(const X509 *x509, int nid, - int *out_critical, int *out_idx); - -// X509_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension to -// |x|'s extension list. -// -// WARNING: This function may return zero or -1 on error. The caller must also -// ensure |value|'s type matches |nid|. See the documentation for -// |X509V3_add1_i2d| for details. -OPENSSL_EXPORT int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, - unsigned long flags); - -// X509_CRL_get_ext_count returns the number of extensions in |x|. -OPENSSL_EXPORT int X509_CRL_get_ext_count(const X509_CRL *x); - -// X509_CRL_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches for -// extensions in |x|. -OPENSSL_EXPORT int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, - int lastpos); - -// X509_CRL_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches for -// extensions in |x|. -OPENSSL_EXPORT int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, - const ASN1_OBJECT *obj, int lastpos); - -// X509_CRL_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| but -// searches for extensions in |x|. -OPENSSL_EXPORT int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, - int lastpos); - -// X509_CRL_get_ext returns the extension in |x| at index |loc|, or NULL if -// |loc| is out of bounds. -OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); - -// X509_CRL_delete_ext removes the extension in |x| at index |loc| and returns -// the removed extension, or NULL if |loc| was out of bounds. If non-NULL, the -// caller must release the result with |X509_EXTENSION_free|. It is also safe, -// but not necessary, to call |X509_EXTENSION_free| if the result is NULL. -OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); - -// X509_CRL_add_ext adds a copy of |ex| to |x|. It returns one on success and -// zero on failure. The caller retains ownership of |ex| and can release it -// independently of |x|. -// -// The new extension is inserted at index |loc|, shifting extensions to the -// right. If |loc| is -1 or out of bounds, the new extension is appended to the -// list. -OPENSSL_EXPORT int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); - -// X509_CRL_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the -// extension in |crl|'s extension list. -// -// WARNING: This function is difficult to use correctly. See the documentation -// for |X509V3_get_d2i| for details. -OPENSSL_EXPORT void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, - int *out_critical, int *out_idx); - -// X509_CRL_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension -// to |x|'s extension list. -// -// WARNING: This function may return zero or -1 on error. The caller must also -// ensure |value|'s type matches |nid|. See the documentation for -// |X509V3_add1_i2d| for details. -OPENSSL_EXPORT int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, - int crit, unsigned long flags); - -// X509_REVOKED_get_ext_count returns the number of extensions in |x|. -OPENSSL_EXPORT int X509_REVOKED_get_ext_count(const X509_REVOKED *x); - -// X509_REVOKED_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches -// for extensions in |x|. -OPENSSL_EXPORT int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, - int lastpos); - -// X509_REVOKED_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches -// for extensions in |x|. -OPENSSL_EXPORT int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, - const ASN1_OBJECT *obj, - int lastpos); - -// X509_REVOKED_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| -// but searches for extensions in |x|. -OPENSSL_EXPORT int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, - int crit, int lastpos); - -// X509_REVOKED_get_ext returns the extension in |x| at index |loc|, or NULL if -// |loc| is out of bounds. -OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, - int loc); - -// X509_REVOKED_delete_ext removes the extension in |x| at index |loc| and -// returns the removed extension, or NULL if |loc| was out of bounds. If -// non-NULL, the caller must release the result with |X509_EXTENSION_free|. It -// is also safe, but not necessary, to call |X509_EXTENSION_free| if the result -// is NULL. -OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, - int loc); - -// X509_REVOKED_add_ext adds a copy of |ex| to |x|. It returns one on success -// and zero on failure. The caller retains ownership of |ex| and can release it -// independently of |x|. -// -// The new extension is inserted at index |loc|, shifting extensions to the -// right. If |loc| is -1 or out of bounds, the new extension is appended to the -// list. -OPENSSL_EXPORT int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, - int loc); - -// X509_REVOKED_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the -// extension in |revoked|'s extension list. -// -// WARNING: This function is difficult to use correctly. See the documentation -// for |X509V3_get_d2i| for details. -OPENSSL_EXPORT void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, - int nid, int *out_critical, - int *out_idx); - -// X509_REVOKED_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the -// extension to |x|'s extension list. -// -// WARNING: This function may return zero or -1 on error. The caller must also -// ensure |value|'s type matches |nid|. See the documentation for -// |X509V3_add1_i2d| for details. -OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, - void *value, int crit, - unsigned long flags); - -// X509_EXTENSION_create_by_NID creates a new |X509_EXTENSION| with type |nid|, -// value |data|, and critical bit |crit|. It returns the newly-allocated -// |X509_EXTENSION| on success, and false on error. |nid| should be a |NID_*| -// constant. -// -// If |ex| and |*ex| are both non-NULL, it modifies and returns |*ex| instead of -// creating a new object. If |ex| is non-NULL, but |*ex| is NULL, it sets |*ex| -// to the new |X509_EXTENSION|, in addition to returning the result. -OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID( - X509_EXTENSION **ex, int nid, int crit, const ASN1_OCTET_STRING *data); - -// X509_EXTENSION_create_by_OBJ behaves like |X509_EXTENSION_create_by_NID|, but -// the extension type is determined by an |ASN1_OBJECT|. -OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ( - X509_EXTENSION **ex, const ASN1_OBJECT *obj, int crit, - const ASN1_OCTET_STRING *data); - -// X509_EXTENSION_set_object sets |ex|'s extension type to |obj|. It returns one -// on success and zero on error. -OPENSSL_EXPORT int X509_EXTENSION_set_object(X509_EXTENSION *ex, - const ASN1_OBJECT *obj); - -// X509_EXTENSION_set_critical sets |ex| to critical if |crit| is non-zero and -// to non-critical if |crit| is zero. -OPENSSL_EXPORT int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); - -// X509_EXTENSION_set_data set's |ex|'s extension value to a copy of |data|. It -// returns one on success and zero on error. -OPENSSL_EXPORT int X509_EXTENSION_set_data(X509_EXTENSION *ex, - const ASN1_OCTET_STRING *data); - -// X509_EXTENSION_get_object returns |ex|'s extension type. -OPENSSL_EXPORT ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); - -// X509_EXTENSION_get_data returns |ne|'s extension value. -OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); - -// X509_EXTENSION_get_critical returns one if |ex| is critical and zero -// otherwise. -OPENSSL_EXPORT int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); - -// X509at_get_attr_count returns the number of attributes in |x|. -OPENSSL_EXPORT int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); - -// X509at_get_attr_by_NID returns the index of the attribute in |x| of type -// |nid|, or a negative number if not found. If found, callers can use -// |X509at_get_attr| to look up the attribute by index. -// -// If |lastpos| is non-negative, it begins searching at |lastpos| + 1. Callers -// can thus loop over all matching attributes by first passing -1 and then -// passing the previously-returned value until no match is returned. -OPENSSL_EXPORT int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, - int nid, int lastpos); - -// X509at_get_attr_by_OBJ behaves like |X509at_get_attr_by_NID| but looks for -// attributes of type |obj|. -OPENSSL_EXPORT int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - const ASN1_OBJECT *obj, int lastpos); - -// X509at_get_attr returns the attribute at index |loc| in |x|, or NULL if -// out of bounds. -OPENSSL_EXPORT X509_ATTRIBUTE *X509at_get_attr( - const STACK_OF(X509_ATTRIBUTE) *x, int loc); - -// X509at_delete_attr removes the attribute at index |loc| in |x|. It returns -// the removed attribute to the caller, or NULL if |loc| was out of bounds. If -// non-NULL, the caller must release the result with |X509_ATTRIBUTE_free| when -// done. It is also safe, but not necessary, to call |X509_ATTRIBUTE_free| if -// the result is NULL. -OPENSSL_EXPORT X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, - int loc); - -// X509at_add1_attr appends a copy of |attr| to the attribute list in |*x|. If -// |*x| is NULL, it allocates a new |STACK_OF(X509_ATTRIBUTE)| to hold the copy -// and sets |*x| to the new list. It returns |*x| on success and NULL on error. -// The caller retains ownership of |attr| and can release it independently of -// |*x|. -OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr( - STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr); - -// X509at_add1_attr_by_OBJ behaves like |X509at_add1_attr|, but adds an -// attribute created by |X509_ATTRIBUTE_create_by_OBJ|. -OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ( - STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); - -// X509at_add1_attr_by_NID behaves like |X509at_add1_attr|, but adds an -// attribute created by |X509_ATTRIBUTE_create_by_NID|. -OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID( - STACK_OF(X509_ATTRIBUTE) **x, int nid, int type, const unsigned char *bytes, - int len); - -// X509at_add1_attr_by_txt behaves like |X509at_add1_attr|, but adds an -// attribute created by |X509_ATTRIBUTE_create_by_txt|. -OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt( - STACK_OF(X509_ATTRIBUTE) **x, const char *attrname, int type, - const unsigned char *bytes, int len); - // X509_ATTRIBUTE_create_by_NID returns a newly-allocated |X509_ATTRIBUTE| of // type |nid|, or NULL on error. The value is determined as in // |X509_ATTRIBUTE_set1_data|. @@ -1726,8 +1486,6 @@ OPENSSL_EXPORT int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, // |attr|'s type. If |len| is -1, |strlen(data)| is used instead. See // |ASN1_STRING_set_by_NID| for details. // -// TODO(davidben): Document |ASN1_STRING_set_by_NID| so the reference is useful. -// // Otherwise, if |len| is not -1, the value is an ASN.1 string. |attrtype| is an // |ASN1_STRING| type value and the |len| bytes from |data| are copied as the // type-specific representation of |ASN1_STRING|. See |ASN1_STRING| for details. @@ -1774,27 +1532,965 @@ OPENSSL_EXPORT ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); -OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); -// lookup a cert from a X509 STACK -OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, +// SignedPublicKeyAndChallenge structures. +// +// The SignedPublicKeyAndChallenge (SPKAC) is a legacy structure to request +// certificates, primarily in the legacy HTML tag. An SPKAC structure +// is represented by a |NETSCAPE_SPKI| structure. +// +// The structure is described in +// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen + +// A Netscape_spki_st, or |NETSCAPE_SPKI|, represents a +// SignedPublicKeyAndChallenge structure. Although this structure contains a +// |spkac| field of type |NETSCAPE_SPKAC|, these are misnamed. The SPKAC is the +// entire structure, not the signed portion. +struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} /* NETSCAPE_SPKI */; + +// NETSCAPE_SPKI is an |ASN1_ITEM| whose ASN.1 type is +// SignedPublicKeyAndChallenge and C type is |NETSCAPE_SPKI*|. +DECLARE_ASN1_ITEM(NETSCAPE_SPKI) + +// NETSCAPE_SPKI_new returns a newly-allocated, empty |NETSCAPE_SPKI| object, or +// NULL on error. +OPENSSL_EXPORT NETSCAPE_SPKI *NETSCAPE_SPKI_new(void); + +// NETSCAPE_SPKI_free releases memory associated with |spki|. +OPENSSL_EXPORT void NETSCAPE_SPKI_free(NETSCAPE_SPKI *spki); + +// d2i_NETSCAPE_SPKI parses up to |len| bytes from |*inp| as a DER-encoded +// SignedPublicKeyAndChallenge structure, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT NETSCAPE_SPKI *d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **out, + const uint8_t **inp, long len); + +// i2d_NETSCAPE_SPKI marshals |spki| as a DER-encoded +// SignedPublicKeyAndChallenge structure, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_NETSCAPE_SPKI(const NETSCAPE_SPKI *spki, uint8_t **outp); + +// NETSCAPE_SPKI_verify checks that |spki| has a valid signature by |pkey|. It +// returns one if the signature is valid and zero otherwise. +OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey); + +// NETSCAPE_SPKI_b64_decode decodes |len| bytes from |str| as a base64-encoded +// SignedPublicKeyAndChallenge structure. It returns a newly-allocated +// |NETSCAPE_SPKI| structure with the result, or NULL on error. If |len| is 0 or +// negative, the length is calculated with |strlen| and |str| must be a +// NUL-terminated C string. +OPENSSL_EXPORT NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, + ossl_ssize_t len); + +// NETSCAPE_SPKI_b64_encode encodes |spki| as a base64-encoded +// SignedPublicKeyAndChallenge structure. It returns a newly-allocated +// NUL-terminated C string with the result, or NULL on error. The caller must +// release the memory with |OPENSSL_free| when done. +OPENSSL_EXPORT char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki); + +// NETSCAPE_SPKI_get_pubkey decodes and returns the public key in |spki| as an +// |EVP_PKEY|, or NULL on error. The caller takes ownership of the resulting +// pointer and must call |EVP_PKEY_free| when done. +OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *spki); + +// NETSCAPE_SPKI_set_pubkey sets |spki|'s public key to |pkey|. It returns one +// on success or zero on error. This function does not take ownership of |pkey|, +// so the caller may continue to manage its lifetime independently of |spki|. +OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *spki, + EVP_PKEY *pkey); + +// NETSCAPE_SPKI_sign signs |spki| with |pkey| and replaces the signature +// algorithm and signature fields. It returns the length of the signature on +// success and zero on error. This function uses digest algorithm |md|, or +// |pkey|'s default if NULL. Other signing parameters use |pkey|'s defaults. +OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *spki, EVP_PKEY *pkey, + const EVP_MD *md); + +// A Netscape_spkac_st, or |NETSCAPE_SPKAC|, represents a PublicKeyAndChallenge +// structure. This type is misnamed. The full SPKAC includes the signature, +// which is represented with the |NETSCAPE_SPKI| type. +struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; +} /* NETSCAPE_SPKAC */; + +// NETSCAPE_SPKAC is an |ASN1_ITEM| whose ASN.1 type is PublicKeyAndChallenge +// and C type is |NETSCAPE_SPKAC*|. +DECLARE_ASN1_ITEM(NETSCAPE_SPKAC) + +// NETSCAPE_SPKAC_new returns a newly-allocated, empty |NETSCAPE_SPKAC| object, +// or NULL on error. +OPENSSL_EXPORT NETSCAPE_SPKAC *NETSCAPE_SPKAC_new(void); + +// NETSCAPE_SPKAC_free releases memory associated with |spkac|. +OPENSSL_EXPORT void NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *spkac); + +// d2i_NETSCAPE_SPKAC parses up to |len| bytes from |*inp| as a DER-encoded +// PublicKeyAndChallenge structure, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **out, + const uint8_t **inp, + long len); + +// i2d_NETSCAPE_SPKAC marshals |spkac| as a DER-encoded PublicKeyAndChallenge +// structure, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_NETSCAPE_SPKAC(const NETSCAPE_SPKAC *spkac, + uint8_t **outp); + + +// Printing functions. +// +// The following functions output human-readable representations of +// X.509-related structures. They should only be used for debugging or logging +// and not parsed programmatically. In many cases, the outputs are ambiguous, so +// attempting to parse them can lead to string injection vulnerabilities. + +// The following flags control |X509_print_ex| and |X509_REQ_print_ex|. + +// X509_FLAG_COMPAT disables all flags. It additionally causes names to be +// printed with a 16-byte indent. +#define X509_FLAG_COMPAT 0 + +// X509_FLAG_NO_HEADER skips a header identifying the type of object printed. +#define X509_FLAG_NO_HEADER 1L + +// X509_FLAG_NO_VERSION skips printing the X.509 version number. +#define X509_FLAG_NO_VERSION (1L << 1) + +// X509_FLAG_NO_SERIAL skips printing the serial number. It is ignored in +// |X509_REQ_print_fp|. +#define X509_FLAG_NO_SERIAL (1L << 2) + +// X509_FLAG_NO_SIGNAME skips printing the signature algorithm in the +// TBSCertificate. It is ignored in |X509_REQ_print_fp|. +#define X509_FLAG_NO_SIGNAME (1L << 3) + +// X509_FLAG_NO_ISSUER skips printing the issuer. +#define X509_FLAG_NO_ISSUER (1L << 4) + +// X509_FLAG_NO_VALIDITY skips printing the notBefore and notAfter times. It is +// ignored in |X509_REQ_print_fp|. +#define X509_FLAG_NO_VALIDITY (1L << 5) + +// X509_FLAG_NO_SUBJECT skips printing the subject. +#define X509_FLAG_NO_SUBJECT (1L << 6) + +// X509_FLAG_NO_PUBKEY skips printing the public key. +#define X509_FLAG_NO_PUBKEY (1L << 7) + +// X509_FLAG_NO_EXTENSIONS skips printing the extension list. It is ignored in +// |X509_REQ_print_fp|. CSRs instead have attributes, which is controlled by +// |X509_FLAG_NO_ATTRIBUTES|. +#define X509_FLAG_NO_EXTENSIONS (1L << 8) + +// X509_FLAG_NO_SIGDUMP skips printing the signature and outer signature +// algorithm. +#define X509_FLAG_NO_SIGDUMP (1L << 9) + +// X509_FLAG_NO_AUX skips printing auxiliary properties. (See |d2i_X509_AUX| and +// related functions.) +#define X509_FLAG_NO_AUX (1L << 10) + +// X509_FLAG_NO_ATTRIBUTES skips printing CSR attributes. It does nothing for +// certificates and CRLs. +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +// X509_FLAG_NO_IDS skips printing the issuerUniqueID and subjectUniqueID in a +// certificate. It is ignored in |X509_REQ_print_fp|. +#define X509_FLAG_NO_IDS (1L << 12) + +// X509_print_ex writes a human-readable representation of |x| to |bp|. It +// returns one on success and zero on error. |nmflags| is the flags parameter +// for |X509_NAME_print_ex| when printing the subject and issuer. |cflag| should +// be some combination of the |X509_FLAG_*| constants. +OPENSSL_EXPORT int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); + +// X509_print_ex_fp behaves like |X509_print_ex| but writes to |fp|. +OPENSSL_EXPORT int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, + unsigned long cflag); + +// X509_print calls |X509_print_ex| with |XN_FLAG_COMPAT| and |X509_FLAG_COMPAT| +// flags. +OPENSSL_EXPORT int X509_print(BIO *bp, X509 *x); + +// X509_print_fp behaves like |X509_print| but writes to |fp|. +OPENSSL_EXPORT int X509_print_fp(FILE *fp, X509 *x); + +// X509_CRL_print writes a human-readable representation of |x| to |bp|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_CRL_print(BIO *bp, X509_CRL *x); + +// X509_CRL_print_fp behaves like |X509_CRL_print| but writes to |fp|. +OPENSSL_EXPORT int X509_CRL_print_fp(FILE *fp, X509_CRL *x); + +// X509_REQ_print_ex writes a human-readable representation of |x| to |bp|. It +// returns one on success and zero on error. |nmflags| is the flags parameter +// for |X509_NAME_print_ex|, when printing the subject. |cflag| should be some +// combination of the |X509_FLAG_*| constants. +OPENSSL_EXPORT int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); + +// X509_REQ_print calls |X509_REQ_print_ex| with |XN_FLAG_COMPAT| and +// |X509_FLAG_COMPAT| flags. +OPENSSL_EXPORT int X509_REQ_print(BIO *bp, X509_REQ *req); + +// X509_REQ_print_fp behaves like |X509_REQ_print| but writes to |fp|. +OPENSSL_EXPORT int X509_REQ_print_fp(FILE *fp, X509_REQ *req); + +// The following flags are control |X509_NAME_print_ex|. They must not collide +// with |ASN1_STRFLGS_*|. +// +// TODO(davidben): This is far, far too many options and most of them are +// useless. Trim this down. + +// XN_FLAG_COMPAT prints with |X509_NAME_print|'s format and return value +// convention. +#define XN_FLAG_COMPAT 0 + +// XN_FLAG_SEP_MASK determines the separators to use between attributes. +#define XN_FLAG_SEP_MASK (0xf << 16) + +// XN_FLAG_SEP_COMMA_PLUS separates RDNs with "," and attributes within an RDN +// with "+", as in RFC 2253. +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) + +// XN_FLAG_SEP_CPLUS_SPC behaves like |XN_FLAG_SEP_COMMA_PLUS| but adds spaces +// between the separators. +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) + +// XN_FLAG_SEP_SPLUS_SPC separates RDNs with "; " and attributes within an RDN +// with " + ". +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) + +// XN_FLAG_SEP_MULTILINE prints each attribute on one line. +#define XN_FLAG_SEP_MULTILINE (4 << 16) + +// XN_FLAG_DN_REV prints RDNs in reverse, from least significant to most +// significant, as RFC 2253. +#define XN_FLAG_DN_REV (1 << 20) + +// XN_FLAG_FN_MASK determines how attribute types are displayed. +#define XN_FLAG_FN_MASK (0x3 << 21) + +// XN_FLAG_FN_SN uses the attribute type's short name, when available. +#define XN_FLAG_FN_SN 0 + +// XN_FLAG_SPC_EQ wraps the "=" operator with spaces when printing attributes. +#define XN_FLAG_SPC_EQ (1 << 23) + +// XN_FLAG_DUMP_UNKNOWN_FIELDS causes unknown attribute types to be printed in +// hex, as in RFC 2253. +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +// XN_FLAG_RFC2253 prints like RFC 2253. +#define XN_FLAG_RFC2253 \ + (ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS) + +// XN_FLAG_ONELINE prints a one-line representation of the name. +#define XN_FLAG_ONELINE \ + (ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | XN_FLAG_FN_SN) + +// X509_NAME_print_ex writes a human-readable representation of |nm| to |out|. +// Each line of output is indented by |indent| spaces. It returns the number of +// bytes written on success, and -1 on error. If |out| is NULL, it returns the +// number of bytes it would have written but does not write anything. |flags| +// should be some combination of |XN_FLAG_*| and |ASN1_STRFLGS_*| values and +// determines the output. If unsure, use |XN_FLAG_RFC2253|. +// +// If |flags| is |XN_FLAG_COMPAT|, or zero, this function calls +// |X509_NAME_print| instead. In that case, it returns one on success, rather +// than the output length. +OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); + +// X509_NAME_print prints a human-readable representation of |name| to |bp|. It +// returns one on success and zero on error. |obase| is ignored. +// +// This function outputs a legacy format that does not correctly handle string +// encodings and other cases. Prefer |X509_NAME_print_ex| if printing a name for +// debugging purposes. +OPENSSL_EXPORT int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); + +// X509_NAME_oneline writes a human-readable representation to |name| to a +// buffer as a NUL-terminated C string. +// +// If |buf| is NULL, returns a newly-allocated buffer containing the result on +// success, or NULL on error. The buffer must be released with |OPENSSL_free| +// when done. +// +// If |buf| is non-NULL, at most |size| bytes of output are written to |buf| +// instead. |size| includes the trailing NUL. The function then returns |buf| on +// success or NULL on error. If the output does not fit in |size| bytes, the +// output is silently truncated at an attribute boundary. +// +// This function outputs a legacy format that does not correctly handle string +// encodings and other cases. Prefer |X509_NAME_print_ex| if printing a name for +// debugging purposes. +OPENSSL_EXPORT char *X509_NAME_oneline(const X509_NAME *name, char *buf, int size); + +// X509_NAME_print_ex_fp behaves like |X509_NAME_print_ex| but writes to |fp|. +OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, + int indent, unsigned long flags); + +// X509_signature_dump writes a human-readable representation of |sig| to |bio|, +// indented with |indent| spaces. It returns one on success and zero on error. +OPENSSL_EXPORT int X509_signature_dump(BIO *bio, const ASN1_STRING *sig, + int indent); + +// X509_signature_print writes a human-readable representation of |alg| and +// |sig| to |bio|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509_signature_print(BIO *bio, const X509_ALGOR *alg, + const ASN1_STRING *sig); + + +// Convenience functions. + +// X509_pubkey_digest hashes the contents of the BIT STRING in |x509|'s +// subjectPublicKeyInfo field with |md| and writes the result to |out|. +// |EVP_MD_CTX_size| bytes are written, which is at most |EVP_MAX_MD_SIZE|. If +// |out_len| is not NULL, |*out_len| is set to the number of bytes written. This +// function returns one on success and zero on error. +// +// This hash omits the BIT STRING tag, length, and number of unused bits. It +// also omits the AlgorithmIdentifier which describes the key type. It +// corresponds to the OCSP KeyHash definition and is not suitable for other +// purposes. +OPENSSL_EXPORT int X509_pubkey_digest(const X509 *x509, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_digest hashes |x509|'s DER encoding with |md| and writes the result to +// |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire certificate, not just the signed portion. +OPENSSL_EXPORT int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out, + unsigned *out_len); + +// X509_CRL_digest hashes |crl|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire CRL, not just the signed portion. +OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *crl, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_REQ_digest hashes |req|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +// Note this digest covers the entire certificate request, not just the signed +// portion. +OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *req, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// X509_NAME_digest hashes |name|'s DER encoding with |md| and writes the result +// to |out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_len| is not NULL, |*out_len| is set to the number +// of bytes written. This function returns one on success and zero on error. +OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *name, const EVP_MD *md, + uint8_t *out, unsigned *out_len); + +// The following functions behave like the corresponding unsuffixed |d2i_*| +// functions, but read the result from |bp| instead. Callers using these +// functions with memory |BIO|s to parse structures already in memory should use +// |d2i_*| instead. +OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp, X509 **x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio( + BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +OPENSSL_EXPORT DH *d2i_DHparams_bio(BIO *bp, DH **dh); + +// d2i_PrivateKey_bio behaves like |d2i_AutoPrivateKey|, but reads from |bp| +// instead. +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); + +// The following functions behave like the corresponding unsuffixed |i2d_*| +// functions, but write the result to |bp|. They return one on success and zero +// on error. Callers using them with memory |BIO|s to encode structures to +// memory should use |i2d_*| directly instead. +OPENSSL_EXPORT int i2d_X509_bio(BIO *bp, X509 *x509); +OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +OPENSSL_EXPORT int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT int i2d_DHparams_bio(BIO *bp, const DH *dh); + +// i2d_PKCS8PrivateKeyInfo_bio encodes |key| as a PKCS#8 PrivateKeyInfo +// structure (see |EVP_marshal_private_key|) and writes the result to |bp|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); + +// The following functions behave like the corresponding |d2i_*_bio| functions, +// but read from |fp| instead. +OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp( + FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); + +// The following functions behave like the corresponding |i2d_*_bio| functions, +// but write to |fp| instead. +OPENSSL_EXPORT int i2d_X509_fp(FILE *fp, X509 *x509); +OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +OPENSSL_EXPORT int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); + +// X509_find_by_issuer_and_serial returns the first |X509| in |sk| whose issuer +// and serial are |name| and |serial|, respectively. If no match is found, it +// returns NULL. +OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(const STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial); -OPENSSL_EXPORT X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + const ASN1_INTEGER *serial); + +// X509_find_by_subject returns the first |X509| in |sk| whose subject is +// |name|. If no match is found, it returns NULL. +OPENSSL_EXPORT X509 *X509_find_by_subject(const STACK_OF(X509) *sk, + X509_NAME *name); + +// X509_cmp_time compares |s| against |*t|. On success, it returns a negative +// number if |s| <= |*t| and a positive number if |s| > |*t|. On error, it +// returns zero. If |t| is NULL, it uses the current time instead of |*t|. +// +// WARNING: Unlike most comparison functions, this function returns zero on +// error, not equality. +OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); + +// X509_cmp_time_posix compares |s| against |t|. On success, it returns a +// negative number if |s| <= |t| and a positive number if |s| > |t|. On error, +// it returns zero. +// +// WARNING: Unlike most comparison functions, this function returns zero on +// error, not equality. +OPENSSL_EXPORT int X509_cmp_time_posix(const ASN1_TIME *s, int64_t t); + +// X509_cmp_current_time behaves like |X509_cmp_time| but compares |s| against +// the current time. +OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); + +// X509_time_adj calls |X509_time_adj_ex| with |offset_day| equal to zero. +OPENSSL_EXPORT ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, + time_t *t); + +// X509_time_adj_ex behaves like |ASN1_TIME_adj|, but adds an offset to |*t|. If +// |t| is NULL, it uses the current time instead of |*t|. +OPENSSL_EXPORT ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, + long offset_sec, time_t *t); + +// X509_gmtime_adj behaves like |X509_time_adj_ex| but adds |offset_sec| to the +// current time. +OPENSSL_EXPORT ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); +OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); + +OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, + void *data); +OPENSSL_EXPORT void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); + + +// Deprecated functions. + +// X509_get_notBefore returns |x509|'s notBefore time. Note this function is not +// const-correct for legacy reasons. Use |X509_get0_notBefore| or +// |X509_getm_notBefore| instead. +OPENSSL_EXPORT ASN1_TIME *X509_get_notBefore(const X509 *x509); + +// X509_get_notAfter returns |x509|'s notAfter time. Note this function is not +// const-correct for legacy reasons. Use |X509_get0_notAfter| or +// |X509_getm_notAfter| instead. +OPENSSL_EXPORT ASN1_TIME *X509_get_notAfter(const X509 *x509); + +// X509_set_notBefore calls |X509_set1_notBefore|. Use |X509_set1_notBefore| +// instead. +OPENSSL_EXPORT int X509_set_notBefore(X509 *x509, const ASN1_TIME *tm); + +// X509_set_notAfter calls |X509_set1_notAfter|. Use |X509_set1_notAfter| +// instead. +OPENSSL_EXPORT int X509_set_notAfter(X509 *x509, const ASN1_TIME *tm); + +// X509_CRL_get_lastUpdate returns a mutable pointer to |crl|'s thisUpdate time. +// The OpenSSL API refers to this field as lastUpdate. +// +// Use |X509_CRL_get0_lastUpdate| or |X509_CRL_set1_lastUpdate| instead. +OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl); + +// X509_CRL_get_nextUpdate returns a mutable pointer to |crl|'s nextUpdate time, +// or NULL if |crl| has none. Use |X509_CRL_get0_nextUpdate| or +// |X509_CRL_set1_nextUpdate| instead. +OPENSSL_EXPORT ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl); + +// X509_extract_key is a legacy alias to |X509_get_pubkey|. Use +// |X509_get_pubkey| instead. +#define X509_extract_key(x) X509_get_pubkey(x) + +// X509_REQ_extract_key is a legacy alias for |X509_REQ_get_pubkey|. +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) + +// X509_name_cmp is a legacy alias for |X509_NAME_cmp|. +#define X509_name_cmp(a, b) X509_NAME_cmp((a), (b)) + +// The following symbols are deprecated aliases to |X509_CRL_set1_*|. +#define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +#define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate + +// X509_get_serialNumber returns a mutable pointer to |x509|'s serial number. +// Prefer |X509_get0_serialNumber|. +OPENSSL_EXPORT ASN1_INTEGER *X509_get_serialNumber(X509 *x509); + +// X509_NAME_get_text_by_OBJ finds the first attribute with type |obj| in +// |name|. If found, it ignores the value's ASN.1 type, writes the raw +// |ASN1_STRING| representation to |buf|, followed by a NUL byte, and +// returns the number of bytes in output, excluding the NUL byte. +// +// This function writes at most |len| bytes, including the NUL byte. If |len| is +// not large enough, it silently truncates the output to fit. If |buf| is NULL, +// it instead writes enough and returns the number of bytes in the output, +// excluding the NUL byte. +// +// WARNING: Do not use this function. It does not return enough information for +// the caller to correctly interpret its output. The attribute value may be of +// any type, including one of several ASN.1 string encodings, but this function +// only outputs the raw |ASN1_STRING| representation. See +// https://crbug.com/boringssl/436. +OPENSSL_EXPORT int X509_NAME_get_text_by_OBJ(const X509_NAME *name, + const ASN1_OBJECT *obj, char *buf, + int len); + +// X509_NAME_get_text_by_NID behaves like |X509_NAME_get_text_by_OBJ| except it +// finds an attribute of type |nid|, which should be one of the |NID_*| +// constants. +OPENSSL_EXPORT int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, + char *buf, int len); + + +// Private structures. + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */; + + +// Functions below this point have not yet been organized into sections. + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +// This stuff is certificate "auxiliary info" +// it contains details which are useful in certificate +// stores and databases. When used this is tagged onto +// the end of the certificate itself + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_STACK_OF(GENERAL_NAME) + +// This is used for a table of trust checking functions + +struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} /* X509_TRUST */; + +DEFINE_STACK_OF(X509_TRUST) + +// standard trust ids + +#define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 + +// Keep these up to date! +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 8 + + +// trust_flags values +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +// check_trust return codes + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +DEFINE_STACK_OF(X509_REVOKED) + +DECLARE_STACK_OF(GENERAL_NAMES) + +struct private_key_st { + int version; + // The PKCS#8 data types + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; // encrypted pub key + + // When decrypted, the following will not be NULL + EVP_PKEY *dec_pkey; + + // used to encrypt and decrypt + int key_length; + char *key_data; + int key_free; // true if we should auto free key_data + + // expanded version of 'enc_algor' + EVP_CIPHER_INFO cipher; +} /* X509_PKEY */; + +struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + +} /* X509_INFO */; + +DEFINE_STACK_OF(X509_INFO) + +// X509_get_pathlen returns path length constraint from the basic constraints +// extension in |x509|. (See RFC 5280, section 4.2.1.9.) It returns -1 if the +// constraint is not present, or if some extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT long X509_get_pathlen(X509 *x509); + +// X509_SIG_get0 sets |*out_alg| and |*out_digest| to non-owning pointers to +// |sig|'s algorithm and digest fields, respectively. Either |out_alg| and +// |out_digest| may be NULL to skip those fields. +OPENSSL_EXPORT void X509_SIG_get0(const X509_SIG *sig, + const X509_ALGOR **out_alg, + const ASN1_OCTET_STRING **out_digest); + +// X509_SIG_getm behaves like |X509_SIG_get0| but returns mutable pointers. +OPENSSL_EXPORT void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, + ASN1_OCTET_STRING **out_digest); + +// X509_verify_cert_error_string returns |err| as a human-readable string, where +// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns +// a default description. +OPENSSL_EXPORT const char *X509_verify_cert_error_string(long err); + +// X509_REVOKED_dup returns a newly-allocated copy of |rev|, or NULL on error. +// This function works by serializing the structure, so if |rev| is incomplete, +// it may fail. +OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(const X509_REVOKED *rev); + +OPENSSL_EXPORT const char *X509_get_default_cert_area(void); +OPENSSL_EXPORT const char *X509_get_default_cert_dir(void); +OPENSSL_EXPORT const char *X509_get_default_cert_file(void); +OPENSSL_EXPORT const char *X509_get_default_cert_dir_env(void); +OPENSSL_EXPORT const char *X509_get_default_cert_file_env(void); +OPENSSL_EXPORT const char *X509_get_default_private_dir(void); + +DECLARE_ASN1_FUNCTIONS_const(X509_PUBKEY) + +// X509_PUBKEY_set serializes |pkey| into a newly-allocated |X509_PUBKEY| +// structure. On success, it frees |*x|, sets |*x| to the new object, and +// returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); + +// X509_PUBKEY_get decodes the public key in |key| and returns an |EVP_PKEY| on +// success, or NULL on error. The caller must release the result with +// |EVP_PKEY_free| when done. The |EVP_PKEY| is cached in |key|, so callers must +// not mutate the result. +OPENSSL_EXPORT EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); + +DECLARE_ASN1_FUNCTIONS_const(X509_SIG) + +OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT void X509_trust_clear(X509 *x); +OPENSSL_EXPORT void X509_reject_clear(X509 *x); + + +OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); + +DECLARE_ASN1_FUNCTIONS_const(X509_REVOKED) + +OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, + X509 *x); + +OPENSSL_EXPORT X509_PKEY *X509_PKEY_new(void); +OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); + +OPENSSL_EXPORT X509_INFO *X509_INFO_new(void); +OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); + +OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, + void *data, unsigned char *md, + unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, + const X509_ALGOR *algor1, + const ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey); + +OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, + EVP_MD_CTX *ctx); + +OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl); + +// X509_REVOKED_get0_serialNumber returns the serial number of the certificate +// revoked by |revoked|. +OPENSSL_EXPORT const ASN1_INTEGER *X509_REVOKED_get0_serialNumber( + const X509_REVOKED *revoked); + +// X509_REVOKED_set_serialNumber sets |revoked|'s serial number to |serial|. It +// returns one on success or zero on error. +OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *revoked, + const ASN1_INTEGER *serial); + +// X509_REVOKED_get0_revocationDate returns the revocation time of the +// certificate revoked by |revoked|. +OPENSSL_EXPORT const ASN1_TIME *X509_REVOKED_get0_revocationDate( + const X509_REVOKED *revoked); + +// X509_REVOKED_set_revocationDate sets |revoked|'s revocation time to |tm|. It +// returns one on success or zero on error. +OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *revoked, + const ASN1_TIME *tm); + +// X509_REVOKED_get0_extensions returns |r|'s extensions list, or NULL if |r| +// omits it. +OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions( + const X509_REVOKED *r); + +OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, + unsigned int flags); + +OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); + +OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); + +OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); + +OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); +OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); + +OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); +OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); + +OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); + +// X509_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the extension in +// |x509|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_get_ext_d2i(const X509 *x509, int nid, + int *out_critical, int *out_idx); + +// X509_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension to +// |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +// X509_CRL_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the +// extension in |crl|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, + int *out_critical, int *out_idx); + +// X509_CRL_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the extension +// to |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, + int crit, unsigned long flags); + +// X509_REVOKED_get_ext_count returns the number of extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_count(const X509_REVOKED *x); + +// X509_REVOKED_get_ext_by_NID behaves like |X509v3_get_ext_by_NID| but searches +// for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, + int lastpos); + +// X509_REVOKED_get_ext_by_OBJ behaves like |X509v3_get_ext_by_OBJ| but searches +// for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, + const ASN1_OBJECT *obj, + int lastpos); + +// X509_REVOKED_get_ext_by_critical behaves like |X509v3_get_ext_by_critical| +// but searches for extensions in |x|. +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, + int crit, int lastpos); + +// X509_REVOKED_get_ext returns the extension in |x| at index |loc|, or NULL if +// |loc| is out of bounds. This function returns a non-const pointer for OpenSSL +// compatibility, but callers should not mutate the result. +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, + int loc); + +// X509_REVOKED_delete_ext removes the extension in |x| at index |loc| and +// returns the removed extension, or NULL if |loc| was out of bounds. If +// non-NULL, the caller must release the result with |X509_EXTENSION_free|. +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, + int loc); + +// X509_REVOKED_add_ext adds a copy of |ex| to |x|. It returns one on success +// and zero on failure. The caller retains ownership of |ex| and can release it +// independently of |x|. +// +// The new extension is inserted at index |loc|, shifting extensions to the +// right. If |loc| is -1 or out of bounds, the new extension is appended to the +// list. +OPENSSL_EXPORT int X509_REVOKED_add_ext(X509_REVOKED *x, + const X509_EXTENSION *ex, int loc); + +// X509_REVOKED_get_ext_d2i behaves like |X509V3_get_d2i| but looks for the +// extension in |revoked|'s extension list. +// +// WARNING: This function is difficult to use correctly. See the documentation +// for |X509V3_get_d2i| for details. +OPENSSL_EXPORT void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, + int nid, int *out_critical, + int *out_idx); + +// X509_REVOKED_add1_ext_i2d behaves like |X509V3_add1_i2d| but adds the +// extension to |x|'s extension list. +// +// WARNING: This function may return zero or -1 on error. The caller must also +// ensure |value|'s type matches |nid|. See the documentation for +// |X509V3_add1_i2d| for details. +OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, + void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); // PKCS#8 utilities -DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) +DECLARE_ASN1_FUNCTIONS_const(PKCS8_PRIV_KEY_INFO) -OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); -OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +// EVP_PKCS82PKEY returns |p8| as a newly-allocated |EVP_PKEY|, or NULL if the +// key was unsupported or could not be decoded. If non-NULL, the caller must +// release the result with |EVP_PKEY_free| when done. +// +// Use |EVP_parse_private_key| instead. +OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); -OPENSSL_EXPORT int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, - int version, int ptype, void *pval, - unsigned char *penc, int penclen); -OPENSSL_EXPORT int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, - const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); +// EVP_PKEY2PKCS8 encodes |pkey| as a PKCS#8 PrivateKeyInfo (RFC 5208), +// represented as a newly-allocated |PKCS8_PRIV_KEY_INFO|, or NULL on error. The +// caller must release the result with |PKCS8_PRIV_KEY_INFO_free| when done. +// +// Use |EVP_marshal_private_key| instead. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); // X509_PUBKEY_set0_param sets |pub| to a key with AlgorithmIdentifier // determined by |obj|, |param_type|, and |param_value|, and an encoded @@ -1833,7 +2529,7 @@ OPENSSL_EXPORT X509_TRUST *X509_TRUST_get0(int idx); OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); OPENSSL_EXPORT int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), - char *name, int arg1, void *arg2); + const char *name, int arg1, void *arg2); OPENSSL_EXPORT void X509_TRUST_cleanup(void); OPENSSL_EXPORT int X509_TRUST_get_flags(const X509_TRUST *xp); OPENSSL_EXPORT char *X509_TRUST_get0_name(const X509_TRUST *xp); @@ -1851,7 +2547,7 @@ struct rsa_pss_params_st { X509_ALGOR *maskHash; } /* RSA_PSS_PARAMS */; -DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) +DECLARE_ASN1_FUNCTIONS_const(RSA_PSS_PARAMS) /* SSL_CTX -> X509_STORE @@ -1976,14 +2672,6 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 #define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 -// Suite B mode algorithm violation -#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 -#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 -#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 -#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 -#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 -#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 - // Host, email and IP check errors #define X509_V_ERR_HOSTNAME_MISMATCH 62 #define X509_V_ERR_EMAIL_MISMATCH 63 @@ -2010,9 +2698,9 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_FLAG_IGNORE_CRITICAL 0x10 // Does nothing as its functionality has been enabled by default. #define X509_V_FLAG_X509_STRICT 0x00 -// Enable proxy certificate validation +// This flag does nothing as proxy certificate support has been removed. #define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 -// Enable policy checking +// Does nothing as its functionality has been enabled by default. #define X509_V_FLAG_POLICY_CHECK 0x80 // Policy variable require-explicit-policy #define X509_V_FLAG_EXPLICIT_POLICY 0x100 @@ -2030,12 +2718,6 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 // Use trusted store first #define X509_V_FLAG_TRUSTED_FIRST 0x8000 -// Suite B 128 bit only mode: not normally used -#define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 -// Suite B 192 bit only mode -#define X509_V_FLAG_SUITEB_192_LOS 0x20000 -// Suite B 128 bit mode allowing 192 bit algorithms -#define X509_V_FLAG_SUITEB_128_LOS 0x30000 // Allow partial chains if at least one certificate is in trusted store #define X509_V_FLAG_PARTIAL_CHAIN 0x80000 @@ -2045,17 +2727,16 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); // will force the behaviour to match that of previous versions. #define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +// X509_V_FLAG_NO_CHECK_TIME disables all time checks in certificate +// verification. +#define X509_V_FLAG_NO_CHECK_TIME 0x200000 + #define X509_VP_FLAG_DEFAULT 0x1 #define X509_VP_FLAG_OVERWRITE 0x2 #define X509_VP_FLAG_RESET_FLAGS 0x4 #define X509_VP_FLAG_LOCKED 0x8 #define X509_VP_FLAG_ONCE 0x10 -// Internal use: mask of policy related options -#define X509_V_FLAG_POLICY_MASK \ - (X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY | \ - X509_V_FLAG_INHIBIT_ANY | X509_V_FLAG_INHIBIT_MAP) - OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject( @@ -2089,6 +2770,11 @@ OPENSSL_EXPORT void X509_STORE_set_verify(X509_STORE *ctx, OPENSSL_EXPORT void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, X509_STORE_CTX_verify_fn verify); OPENSSL_EXPORT X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); + +// X509_STORE_set_verify_cb acts like |X509_STORE_CTX_set_verify_cb| but sets +// the verify callback for any |X509_STORE_CTX| created from this |X509_STORE| +// +// Do not use this funciton. see |X509_STORE_CTX_set_verify_cb|. OPENSSL_EXPORT void X509_STORE_set_verify_cb( X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb); #define X509_STORE_set_verify_cb_func(ctx, func) \ @@ -2143,8 +2829,21 @@ OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx); OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain); + +// X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates +// in |sk|. |sk| must remain valid for the duration of |ctx|. +// +// WARNING: This function differs from most |set0| functions in that it does not +// take ownership of its input. The caller is required to ensure the lifetimes +// are consistent. +OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, + STACK_OF(X509) *sk); + +// X509_STORE_CTX_trusted_stack is a deprecated alias for +// |X509_STORE_CTX_set0_trusted_stack|. OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); + OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); @@ -2179,15 +2878,6 @@ OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx); OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret); -OPENSSL_EXPORT int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, - X509_NAME *name, - ASN1_INTEGER *serial, - X509_OBJECT *ret); -OPENSSL_EXPORT int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret); -OPENSSL_EXPORT int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, - int len, X509_OBJECT *ret); OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); #ifndef OPENSSL_NO_STDIO @@ -2195,14 +2885,6 @@ OPENSSL_EXPORT int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *dir); OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); #endif - -OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_unused *unused, - CRYPTO_EX_dup *dup_unused, - CRYPTO_EX_free *free_func); -OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, - void *data); -OPENSSL_EXPORT void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); @@ -2230,12 +2912,30 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t); -OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( - X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)); +OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, + unsigned long flags, + int64_t t); -OPENSSL_EXPORT X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree( - X509_STORE_CTX *ctx); -OPENSSL_EXPORT int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); +// X509_STORE_CTX_set_verify_cb configures a callback function for |ctx| that is +// called multiple times during |X509_verify_cert|. The callback returns zero to +// fail verification and non-zero to proceed. Typically, it will return |ok|, +// which preserves the default behavior. Returning one when |ok| is zero will +// proceed past some error. The callback may inspect |ctx| and the error queue +// to attempt to determine the current stage of certificate verification, but +// this is often unreliable. +// +// WARNING: Do not use this function. It is extremely fragile and unpredictable. +// This callback exposes implementation details of certificate verification, +// which change as the library evolves. Attempting to use it for security checks +// can introduce vulnerabilities if making incorrect assumptions about when the +// callback is called. Additionally, overriding |ok| may leave |ctx| in an +// inconsistent state and break invariants. +// +// Instead, customize certificate verification by configuring options on the +// |X509_STORE_CTX| before verification, or applying additional checks after +// |X509_verify_cert| completes successfully. +OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( + X509_STORE_CTX *ctx, int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( X509_STORE_CTX *ctx); @@ -2268,10 +2968,12 @@ OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, + int64_t t); OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( - X509_VERIFY_PARAM *param, STACK_OF(ASN1_OBJECT) *policies); + X509_VERIFY_PARAM *param, const STACK_OF(ASN1_OBJECT) *policies); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, @@ -2295,43 +2997,8 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name( const X509_VERIFY_PARAM *param); -OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); -OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void); -OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup( const char *name); -OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void); - -OPENSSL_EXPORT int X509_policy_check(X509_POLICY_TREE **ptree, - int *pexplicit_policy, - STACK_OF(X509) *certs, - STACK_OF(ASN1_OBJECT) *policy_oids, - unsigned int flags); - -OPENSSL_EXPORT void X509_policy_tree_free(X509_POLICY_TREE *tree); - -OPENSSL_EXPORT int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); -OPENSSL_EXPORT X509_POLICY_LEVEL *X509_policy_tree_get0_level( - const X509_POLICY_TREE *tree, int i); - -OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies( - const X509_POLICY_TREE *tree); - -OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies( - const X509_POLICY_TREE *tree); - -OPENSSL_EXPORT int X509_policy_level_node_count(X509_POLICY_LEVEL *level); - -OPENSSL_EXPORT X509_POLICY_NODE *X509_policy_level_get0_node( - X509_POLICY_LEVEL *level, int i); - -OPENSSL_EXPORT const ASN1_OBJECT *X509_policy_node_get0_policy( - const X509_POLICY_NODE *node); - -OPENSSL_EXPORT STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers( - const X509_POLICY_NODE *node); -OPENSSL_EXPORT const X509_POLICY_NODE *X509_policy_node_get0_parent( - const X509_POLICY_NODE *node); #if defined(__cplusplus) @@ -2351,14 +3018,12 @@ BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free) BORINGSSL_MAKE_DELETER(X509_ATTRIBUTE, X509_ATTRIBUTE_free) BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) BORINGSSL_MAKE_UP_REF(X509_CRL, X509_CRL_up_ref) -BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free) BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free) -BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free) BORINGSSL_MAKE_DELETER(X509_PUBKEY, X509_PUBKEY_free) BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free) BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free) @@ -2414,5 +3079,9 @@ BSSL_NAMESPACE_END #define X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER 138 #define X509_R_INVALID_FIELD_FOR_VERSION 139 #define X509_R_INVALID_VERSION 140 +#define X509_R_NO_CERTIFICATE_FOUND 141 +#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 142 +#define X509_R_NO_CRL_FOUND 143 +#define X509_R_INVALID_POLICY_EXTENSION 144 -#endif +#endif // OPENSSL_HEADER_X509_H diff --git a/third_party/boringssl/kit/src/include/openssl/x509v3.h b/third_party/boringssl/kit/src/include/openssl/x509v3.h index acff637f..2a2e02c2 100644 --- a/third_party/boringssl/kit/src/include/openssl/x509v3.h +++ b/third_party/boringssl/kit/src/include/openssl/x509v3.h @@ -52,8 +52,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -#ifndef HEADER_X509V3_H -#define HEADER_X509V3_H +#ifndef OPENSSL_HEADER_X509V3_H +#define OPENSSL_HEADER_X509V3_H #include #include @@ -79,32 +79,38 @@ struct v3_ext_ctx; // Useful typedefs +typedef struct v3_ext_method X509V3_EXT_METHOD; + typedef void *(*X509V3_EXT_NEW)(void); typedef void (*X509V3_EXT_FREE)(void *); typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); -typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)( - const struct v3_ext_method *method, void *ext, - STACK_OF(CONF_VALUE) *extlist); -typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values); -typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); -typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); -typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, +typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)(const X509V3_EXT_METHOD *method, + void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const X509V3_EXT_METHOD *method, void *ext); +typedef void *(*X509V3_EXT_S2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const X509V3_EXT_METHOD *method, void *ext, BIO *out, int indent); -typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); +typedef void *(*X509V3_EXT_R2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str); // V3 extension structure struct v3_ext_method { int ext_nid; int ext_flags; - // If this is set the following four fields are ignored + + // it determines how values of this extension are allocated, released, parsed, + // and marshalled. This must be non-NULL. ASN1_ITEM_EXP *it; - // Old style ASN1 calls + + // The following functions are ignored in favor of |it|. They are retained in + // the struct only for source compatibility with existing struct definitions. X509V3_EXT_NEW ext_new; X509V3_EXT_FREE ext_free; X509V3_EXT_D2I d2i; @@ -125,32 +131,9 @@ struct v3_ext_method { void *usr_data; // Any extension specific data }; -typedef struct X509V3_CONF_METHOD_st { - char *(*get_string)(void *db, const char *section, const char *value); - STACK_OF(CONF_VALUE) *(*get_section)(void *db, const char *section); - void (*free_string)(void *db, char *string); - void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); -} X509V3_CONF_METHOD; - -// Context specific info -struct v3_ext_ctx { -#define CTX_TEST 0x1 - int flags; - X509 *issuer_cert; - X509 *subject_cert; - X509_REQ *subject_req; - X509_CRL *crl; - const X509V3_CONF_METHOD *db_meth; - void *db; - // Maybe more here -}; - -typedef struct v3_ext_method X509V3_EXT_METHOD; - DEFINE_STACK_OF(X509V3_EXT_METHOD) // ext_flags values -#define X509V3_EXT_DYNAMIC 0x1 #define X509V3_EXT_CTX_DEP 0x2 #define X509V3_EXT_MULTILINE 0x4 @@ -187,7 +170,7 @@ typedef struct GENERAL_NAME_st { OTHERNAME *otherName; // otherName ASN1_IA5STRING *rfc822Name; ASN1_IA5STRING *dNSName; - ASN1_TYPE *x400Address; + ASN1_STRING *x400Address; X509_NAME *directoryName; EDIPARTYNAME *ediPartyName; ASN1_IA5STRING *uniformResourceIdentifier; @@ -199,7 +182,6 @@ typedef struct GENERAL_NAME_st { X509_NAME *dirn; // dirn ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier ASN1_OBJECT *rid; // registeredID - ASN1_TYPE *other; // x400Address } d; } GENERAL_NAME; @@ -318,20 +300,6 @@ typedef struct POLICY_CONSTRAINTS_st { ASN1_INTEGER *inhibitPolicyMapping; } POLICY_CONSTRAINTS; -// Proxy certificate structures, see RFC 3820 -typedef struct PROXY_POLICY_st { - ASN1_OBJECT *policyLanguage; - ASN1_OCTET_STRING *policy; -} PROXY_POLICY; - -typedef struct PROXY_CERT_INFO_EXTENSION_st { - ASN1_INTEGER *pcPathLengthConstraint; - PROXY_POLICY *proxyPolicy; -} PROXY_CERT_INFO_EXTENSION; - -DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) -DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) - struct ISSUING_DIST_POINT_st { DIST_POINT_NAME *distpoint; int onlyuser; @@ -357,30 +325,6 @@ struct ISSUING_DIST_POINT_st { // onlysomereasons present #define IDP_REASONS 0x40 -#define X509V3_conf_err(val) \ - ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ - ",value:", (val)->value); - -#define X509V3_set_ctx_test(ctx) \ - X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) -#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; - -#define EXT_BITSTRING(nid, table) \ - { \ - nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), 0, 0, 0, 0, 0, 0, \ - (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ - (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, NULL, NULL, (void *)(table) \ - } - -#define EXT_IA5STRING(nid) \ - { \ - nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), 0, 0, 0, 0, \ - (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ - (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, 0, 0, 0, 0, NULL \ - } - -#define EXT_END \ - { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // X509_PURPOSE stuff @@ -397,9 +341,7 @@ struct ISSUING_DIST_POINT_st { #define EXFLAG_INVALID 0x80 #define EXFLAG_SET 0x100 #define EXFLAG_CRITICAL 0x200 -#define EXFLAG_PROXY 0x400 -#define EXFLAG_INVALID_POLICY 0x800 #define EXFLAG_FRESHEST 0x1000 // Self signed #define EXFLAG_SS 0x2000 @@ -461,28 +403,17 @@ typedef struct x509_purpose_st { DEFINE_STACK_OF(X509_PURPOSE) -DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) +DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); -// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero -// value otherwise. Note this function does not provide a comparison suitable -// for sorting. -OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, - const GENERAL_NAME *b); - - - -OPENSSL_EXPORT ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING( - X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *extlist); - // i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it // appends the value to |ret| and returns |ret| on success or NULL on error. If // it returns NULL, the caller is still responsible for freeing |ret|. If |ret| @@ -493,9 +424,18 @@ OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING( // human-readable print functions. If extracting a SAN list from a certificate, // look at |gen| directly. OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME( - X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); -OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +// GENERAL_NAME_print prints a human-readable representation of |gen| to |out|. +// It returns one on success and zero on error. +// +// TODO(davidben): Actually, it just returns one and doesn't check for I/O or +// allocation errors. But it should return zero on error. +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen); + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) // i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is @@ -508,15 +448,14 @@ DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) // human-readable print functions. If extracting a SAN list from a certificate, // look at |gen| directly. OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES( - X509V3_EXT_METHOD *method, GENERAL_NAMES *gen, + const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); -OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); +OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES( + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); -DECLARE_ASN1_FUNCTIONS(OTHERNAME) -DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) -OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +DECLARE_ASN1_FUNCTIONS_const(OTHERNAME) +DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME) OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); @@ -527,23 +466,35 @@ OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **poid, ASN1_TYPE **pvalue); -OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - const ASN1_OCTET_STRING *ia5); -OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( - X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str); +// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a +// newly-allocated, NUL-terminated string, or NULL on error. |method| is +// ignored. The caller must release the result with |OPENSSL_free| when done. +OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *oct); -DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); -DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) -DECLARE_ASN1_FUNCTIONS(POLICYINFO) -DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) -DECLARE_ASN1_FUNCTIONS(USERNOTICE) -DECLARE_ASN1_FUNCTIONS(NOTICEREF) +DECLARE_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS_const(POLICYINFO) +DECLARE_ASN1_FUNCTIONS_const(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS_const(USERNOTICE) +DECLARE_ASN1_FUNCTIONS_const(NOTICEREF) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(DIST_POINT) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, @@ -551,7 +502,11 @@ OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) DECLARE_ASN1_ITEM(POLICY_MAPPING) @@ -569,104 +524,186 @@ DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, + const X509V3_CTX *ctx, int gen_type, const char *value, int is_nc); OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf); + const X509V3_CTX *ctx, + const CONF_VALUE *cnf); OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex( - GENERAL_NAME *out, const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf, int is_nc); + GENERAL_NAME *out, const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const CONF_VALUE *cnf, int is_nc); OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); -// X509V3_EXT_conf_nid contains the only exposed instance of an LHASH in our -// public headers. The |conf| pointer must be NULL but cryptography.io wraps -// this function so we cannot, yet, replace the type with a dummy struct. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, - X509V3_CTX *ctx, int ext_nid, - const char *value); -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, - int ext_nid, - const char *value); -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, +// Deprecated config-based extension creation. +// +// The following functions allow specifying X.509 extensions using OpenSSL's +// config file syntax, from the OpenSSL command-line tool. They are retained, +// for now, for compatibility with legacy software but may be removed in the +// future. Construct the extensions using the typed C APIs instead. +// +// Callers should especially avoid these functions if passing in non-constant +// values. They use ad-hoc, string-based formats which are prone to injection +// vulnerabilities. For a CA, this means using them risks misissuance. +// +// These functions are not safe to use with untrusted inputs. The string formats +// may implicitly reference context information and, in OpenSSL (though not +// BoringSSL), one even allows reading arbitrary files. Many formats can also +// produce far larger outputs than their inputs, so untrusted inputs may lead to +// denial-of-service attacks. Finally, the parsers see much less testing and +// review than most of the library and may have bugs including memory leaks or +// crashes. + +// v3_ext_ctx, aka |X509V3_CTX|, contains additional context information for +// constructing extensions. Some string formats reference additional values in +// these objects. It must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test| before use. +struct v3_ext_ctx { + int flags; + const X509 *issuer_cert; + const X509 *subject_cert; + const X509_REQ *subject_req; + const X509_CRL *crl; + const CONF *db; +}; + +#define X509V3_CTX_TEST 0x1 + +// X509V3_set_ctx initializes |ctx| with the specified objects. Some string +// formats will reference fields in these objects. Each object may be NULL to +// omit it, in which case those formats cannot be used. |flags| should be zero, +// unless called via |X509V3_set_ctx_test|. +// +// |issuer|, |subject|, |req|, and |crl|, if non-NULL, must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, + const X509 *subject, const X509_REQ *req, + const X509_CRL *crl, int flags); + +// X509V3_set_ctx_test calls |X509V3_set_ctx| without any reference objects and +// mocks out some features that use them. The resulting extensions may be +// incomplete and should be discarded. This can be used to partially validate +// syntax. +// +// TODO(davidben): Can we remove this? +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, X509V3_CTX_TEST) + +// X509V3_set_nconf sets |ctx| to use |conf| as the config database. |ctx| must +// have previously been initialized by |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. Some string formats will reference sections in |conf|. +// |conf| may be NULL, in which case these formats cannot be used. If non-NULL, +// |conf| must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf); + +// X509V3_set_ctx_nodb calls |X509V3_set_nconf| with no config database. +#define X509V3_set_ctx_nodb(ctx) X509V3_set_nconf(ctx, NULL) + +// X509V3_EXT_nconf constructs an extension of type specified by |name|, and +// value specified by |value|. It returns a newly-allocated |X509_EXTENSION| +// object on success, or NULL on error. |conf| and |ctx| specify additional +// information referenced by some formats. Either |conf| or |ctx| may be NULL, +// in which case features which use it will be disabled. +// +// If non-NULL, |ctx| must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. +// +// Both |conf| and |ctx| provide a |CONF| object. When |ctx| is non-NULL, most +// features use the |ctx| copy, configured with |X509V3_set_ctx|, but some use +// |conf|. Callers should ensure the two match to avoid surprisingly behavior. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *name, const char *value); -OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_nconf_nid behaves like |X509V3_EXT_nconf|, except the extension +// type is specified as a NID. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_conf_nid calls |X509V3_EXT_nconf_nid|. |conf| must be NULL. +// +// TODO(davidben): This is the only exposed instance of an LHASH in our public +// headers. cryptography.io wraps this function so we cannot, yet, replace the +// type with a dummy struct. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_add_nconf_sk looks up the section named |section| in |conf|. For +// each |CONF_VALUE| in the section, it constructs an extension as in +// |X509V3_EXT_nconf|, taking |name| and |value| from the |CONF_VALUE|. Each new +// extension is appended to |*sk|. If |*sk| is non-NULL, and at least one +// extension is added, it sets |*sk| to a newly-allocated +// |STACK_OF(X509_EXTENSION)|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(const CONF *conf, + const X509V3_CTX *ctx, const char *section, STACK_OF(X509_EXTENSION) **sk); -OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_add_nconf adds extensions to |cert| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, const char *section, X509 *cert); -OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_REQ_add_nconf adds extensions to |req| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *section, X509_REQ *req); -OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, + +// X509V3_EXT_CRL_add_nconf adds extensions to |crl| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, const char *section, X509_CRL *crl); -OPENSSL_EXPORT int X509V3_add_value_bool_nf(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); -OPENSSL_EXPORT int X509V3_get_value_bool(const CONF_VALUE *value, - int *asn1_bool); -OPENSSL_EXPORT int X509V3_get_value_int(const CONF_VALUE *value, - ASN1_INTEGER **aint); -OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); -OPENSSL_EXPORT char *X509V3_get_string(X509V3_CTX *ctx, const char *name, - const char *section); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, - const char *section); -OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str); -OPENSSL_EXPORT void X509V3_section_free(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *section); -OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, - X509_REQ *req, X509_CRL *crl, int flags); - -// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to -// |*extlist|. It returns one on success and zero on error. If |*extlist| is -// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| -// containing the result. Either |name| or |value| may be NULL to omit the -// field. -// -// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the -// function returns. -OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_uchar behaves like |X509V3_add_value| but takes an -// |unsigned char| pointer. -OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, - const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value -// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. -OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string -// representation of |aint|. Note this string representation may be decimal or -// hexadecimal, depending on the size of |aint|. -OPENSSL_EXPORT int X509V3_add_value_int(const char *name, - const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist); - -OPENSSL_EXPORT char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, +OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); -OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, +OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, const char *value); -OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, +OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); -OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, - const ASN1_ENUMERATED *aint); -OPENSSL_EXPORT int X509V3_EXT_add(X509V3_EXT_METHOD *ext); -OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); -OPENSSL_EXPORT int X509V3_EXT_add_alias(int nid_to, int nid_from); -OPENSSL_EXPORT void X509V3_EXT_cleanup(void); + +// X509V3_EXT_add registers |ext| as a custom extension for the extension type +// |ext->ext_nid|. |ext| must be valid for the remainder of the address space's +// lifetime. It returns one on success and zero on error. +// +// WARNING: This function modifies global state. If other code in the same +// address space also registers an extension with type |ext->ext_nid|, the two +// registrations will conflict. Which registration takes effect is undefined. If +// the two registrations use incompatible in-memory representations, code +// expecting the other registration will then cast a type to the wrong type, +// resulting in a potentially exploitable memory error. This conflict can also +// occur if BoringSSL later adds support for |ext->ext_nid|, with a different +// in-memory representation than the one expected by |ext|. +// +// This function, additionally, is not thread-safe and cannot be called +// concurrently with any other BoringSSL function. +// +// As a result, it is impossible to safely use this function. Registering a +// custom extension has no impact on certificate verification so, instead, +// callers should simply handle the custom extension with the byte-based +// |X509_EXTENSION| APIs directly. Registering |ext| with the library has little +// practical value. +OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add(X509V3_EXT_METHOD *ext); + +// X509V3_EXT_add_alias registers a custom extension with NID |nid_to|. The +// corresponding ASN.1 type is copied from |nid_from|. It returns one on success +// and zero on error. +// +// WARNING: Do not use this function. See |X509V3_EXT_add|. +OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add_alias(int nid_to, + int nid_from); OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get( const X509_EXTENSION *ext); OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); OPENSSL_EXPORT int X509V3_add_standard_extensions(void); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); // X509V3_EXT_d2i decodes |ext| and returns a pointer to a newly-allocated // structure, with type dependent on the type of the extension. It returns NULL @@ -797,12 +834,13 @@ OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, // hexdump. #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) -OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, +OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, + const STACK_OF(CONF_VALUE) *val, int indent, int ml); -OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, +OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, const X509_EXTENSION *ext, unsigned long flag, int indent); -OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, - int indent); +OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, const X509_EXTENSION *ext, + int flag, int indent); // X509V3_extensions_print prints |title|, followed by a human-readable // representation of |exts| to |out|. It returns one on success and zero on @@ -815,7 +853,7 @@ OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, OPENSSL_EXPORT int X509_check_ca(X509 *x); OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); -OPENSSL_EXPORT int X509_supported_extension(X509_EXTENSION *ex); +OPENSSL_EXPORT int X509_supported_extension(const X509_EXTENSION *ex); OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); @@ -868,12 +906,13 @@ OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509); OPENSSL_EXPORT int X509_PURPOSE_get_count(void); OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx); -OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(char *sname); +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname); OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, int (*ck)(const X509_PURPOSE *, const X509 *, int), - char *name, char *sname, void *arg); + const char *name, const char *sname, + void *arg); OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); @@ -890,19 +929,16 @@ OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 // Disable wildcard matching for dnsName fields and common name. #define X509_CHECK_FLAG_NO_WILDCARDS 0x2 -// Wildcards must not match a partial label. -#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 -// Allow (non-partial) wildcards to match multiple labels. -#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 -// Constraint verifier subdomain patterns to match a single labels. -#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +// X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS does nothing, but is necessary in +// OpenSSL to enable standard wildcard matching. In BoringSSL, this behavior is +// always enabled. +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 +// Deprecated: this flag does nothing +#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0 +// Deprecated: this flag does nothing +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0 // Skip the subject common name fallback if subjectAltNames is missing. #define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 -// -// Match reference identifiers starting with "." to any sub-domain. -// This is a non-public flag, turned on implicitly when the subject -// reference identity is a DNS name. -#define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername); @@ -915,13 +951,6 @@ OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); -OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, - STACK_OF(CONF_VALUE) *dn_sk, - unsigned long chtype); - -OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, - int indent); -DEFINE_STACK_OF(X509_POLICY_NODE) // BEGIN ERROR CODES // The following lines are auto generated by the script mkerr.pl. Any changes @@ -1018,4 +1047,4 @@ BSSL_NAMESPACE_END #define X509V3_R_INVALID_VALUE 163 #define X509V3_R_TRAILING_DATA_IN_EXTENSION 164 -#endif +#endif // OPENSSL_HEADER_X509V3_H diff --git a/third_party/boringssl/kit/src/rust/CMakeLists.txt b/third_party/boringssl/kit/src/rust/CMakeLists.txt new file mode 100644 index 00000000..fcdf3db1 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(bssl-sys) \ No newline at end of file diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/Cargo.toml b/third_party/boringssl/kit/src/rust/bssl-crypto/Cargo.toml new file mode 100644 index 00000000..c60e9ca2 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "bssl-crypto" +version = "0.1.0" +edition = "2021" +publish = false +license = "MIT" + +[dependencies] +bssl-sys = {path = "../bssl-sys"} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/README.md b/third_party/boringssl/kit/src/rust/bssl-crypto/README.md new file mode 100644 index 00000000..bc7371a2 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/README.md @@ -0,0 +1,11 @@ +bssl-crypto +============ + +Rust bindings to BoringSSL which wrap bssl-sys. Before using this crate, first [set up `bssl-sys`](../bssl-sys/README.md). + +Then to run all tests: +``` +cd rust/bssl-crypto && cargo clippy && cargo deny check && cargo test +``` + +Unlike BoringSSL itself, this crate does not attempt to handle allocation failures. If an allocation fails, functions in this crate will panic. diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/deny.toml b/third_party/boringssl/kit/src/rust/bssl-crypto/deny.toml new file mode 100644 index 00000000..cb3f3451 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/deny.toml @@ -0,0 +1,215 @@ +# This template contains all of the possible sections and their default values + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #{ triple = "x86_64-unknown-linux-musl" }, + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory database is cloned/fetched into +db-path = "~/.cargo/advisory-db" +# The url(s) of the advisory databases to use +db-urls = ["https://github.com/rustsec/advisory-db"] +# The lint level for security vulnerabilities +vulnerability = "deny" +# The lint level for unmaintained crates +unmaintained = "warn" +# The lint level for crates that have been yanked from their source registry +yanked = "warn" +# The lint level for crates with security notices. Note that as of +# 2019-12-17 there are no security notice advisories in +# https://github.com/rustsec/advisory-db +notice = "warn" +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", +] +# Threshold for security vulnerabilities, any vulnerability with a CVSS score +# lower than the range specified will be ignored. Note that ignored advisories +# will still output a note when they are encountered. +# * None - CVSS Score 0.0 +# * Low - CVSS Score 0.1 - 3.9 +# * Medium - CVSS Score 4.0 - 6.9 +# * High - CVSS Score 7.0 - 8.9 +# * Critical - CVSS Score 9.0 - 10.0 +#severity-threshold = + +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# The lint level for crates which do not have a detectable license +unlicensed = "deny" +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +allow = [ + "MIT", +] +# List of explicitly disallowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +deny = [ + #"Nokia", +] +# Lint level for licenses considered copyleft +copyleft = "deny" +# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses +# * both - The license will be approved if it is both OSI-approved *AND* FSF +# * either - The license will be approved if it is either OSI-approved *OR* FSF +# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF +# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved +# * neither - This predicate is ignored and the default lint level is used +allow-osi-fsf-free = "neither" +# Lint level used when no other predicates are matched +# 1. License isn't in the allow or deny lists +# 2. License isn't copyleft +# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" +default = "deny" +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.8 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +#[[licenses.clarify]] +# The name of the crate the clarification applies to +#name = "ring" +# The optional version constraint for the crate +#version = "*" +# The SPDX expression for the license requirements of the crate +#expression = "MIT AND ISC AND OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +#license-files = [ + # Each entry is a crate relative path, and the (opaque) hash of its contents + #{ path = "LICENSE", hash = 0xbd0eed23 } +#] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "deny" +# Lint level for when a crate version requirement is `*` +wildcards = "allow" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "all" +# List of crates that are allowed. Use with care! +# This is meant to control any external dependencies. This is effectively +# a minimalist binding library and we try to have none, so you are strongly +# encouraged not to add dependencies here. +allow = [ + # bssl-crypto should be allowed, version appropriately. + { name = "bssl-crypto", version = "=0.1.0" }, + # bssl-sys should be allowed, version appropriately. + { name = "bssl-sys", version = "=0.1.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, + # + # Wrapper crates can optionally be specified to allow the crate when it + # is a direct dependency of the otherwise banned crate + #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, +] +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "warn" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "warn" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] + +[sources.allow-org] +# 1 or more github.com organizations to allow git sources for +#github = [""] +# 1 or more gitlab.com organizations to allow git sources for +#gitlab = [""] +# 1 or more bitbucket.org organizations to allow git sources for +#bitbucket = [""] diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/aes.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/aes.rs new file mode 100644 index 00000000..e5a16078 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/aes.rs @@ -0,0 +1,224 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/// Block size in bytes for AES. +pub const BLOCK_SIZE: usize = bssl_sys::AES_BLOCK_SIZE as usize; + +/// A single AES block. +pub type AesBlock = [u8; BLOCK_SIZE]; + +/// AES implementation used for encrypting/decrypting a single `AesBlock` at a time. +pub struct Aes; + +impl Aes { + /// Encrypts `block` in place. + pub fn encrypt(key: &AesEncryptKey, block: &mut AesBlock) { + let input = *block; + // Safety: + // - AesBlock is always a valid size and key is guaranteed to already be initialized. + unsafe { bssl_sys::AES_encrypt(input.as_ptr(), block.as_mut_ptr(), &key.0) } + } + + /// Decrypts `block` in place. + pub fn decrypt(key: &AesDecryptKey, block: &mut AesBlock) { + let input = *block; + // Safety: + // - AesBlock is always a valid size and key is guaranteed to already be initialized. + unsafe { bssl_sys::AES_decrypt(input.as_ptr(), block.as_mut_ptr(), &key.0) } + } +} + +/// An initialized key which can be used for encrypting. +pub struct AesEncryptKey(bssl_sys::AES_KEY); + +impl AesEncryptKey { + /// Initializes an encryption key from an appropriately sized array of bytes for AES-128 operations. + pub fn new_aes_128(key: [u8; 16]) -> AesEncryptKey { + new_encrypt_key(key) + } + + /// Initializes an encryption key from an appropriately sized array of bytes for AES-256 operations. + pub fn new_aes_256(key: [u8; 32]) -> AesEncryptKey { + new_encrypt_key(key) + } +} + +/// An initialized key which can be used for decrypting +pub struct AesDecryptKey(bssl_sys::AES_KEY); + +impl AesDecryptKey { + /// Initializes a decryption key from an appropriately sized array of bytes for AES-128 operations. + pub fn new_aes_128(key: [u8; 16]) -> AesDecryptKey { + new_decrypt_key(key) + } + + /// Initializes a decryption key from an appropriately sized array of bytes for AES-256 operations. + pub fn new_aes_256(key: [u8; 32]) -> AesDecryptKey { + new_decrypt_key(key) + } +} + +/// Private generically implemented function for creating a new `AesEncryptKey` from an array of bytes. +/// This should only be publicly exposed by wrapper types with the correct key lengths +fn new_encrypt_key(key: [u8; N]) -> AesEncryptKey { + let mut enc_key_uninit = core::mem::MaybeUninit::uninit(); + + // Safety: + // - key is guaranteed to point to bits/8 bytes determined by the len() * 8 used below. + // - bits is always a valid AES key size, as defined by the new_aes_* fns defined on the public + // key structs. + let result = unsafe { + bssl_sys::AES_set_encrypt_key( + key.as_ptr(), + key.len() as core::ffi::c_uint * 8, + enc_key_uninit.as_mut_ptr(), + ) + }; + assert_eq!(result, 0, "Error occurred in bssl_sys::AES_set_encrypt_key"); + + // Safety: + // - since we have checked above that initialization succeeded, this will never be UB + let enc_key = unsafe { enc_key_uninit.assume_init() }; + + AesEncryptKey(enc_key) +} + +/// Private generically implemented function for creating a new `AesDecryptKey` from an array of bytes. +/// This should only be publicly exposed by wrapper types with the correct key lengths. +fn new_decrypt_key(key: [u8; N]) -> AesDecryptKey { + let mut dec_key_uninit = core::mem::MaybeUninit::uninit(); + + // Safety: + // - key is guaranteed to point to bits/8 bytes determined by the len() * 8 used below. + // - bits is always a valid AES key size, as defined by the new_aes_* fns defined on the public + // key structs. + let result = unsafe { + bssl_sys::AES_set_decrypt_key( + key.as_ptr(), + key.len() as core::ffi::c_uint * 8, + dec_key_uninit.as_mut_ptr(), + ) + }; + assert_eq!(result, 0, "Error occurred in bssl_sys::AES_set_decrypt_key"); + + // Safety: + // - Since we have checked above that initialization succeeded, this will never be UB. + let dec_key = unsafe { dec_key_uninit.assume_init() }; + + AesDecryptKey(dec_key) +} + +#[cfg(test)] +mod tests { + use crate::aes::{Aes, AesDecryptKey, AesEncryptKey}; + use crate::test_helpers::decode_hex; + + // test data from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.1 + #[test] + fn aes_128_test_encrypt() { + let key = AesEncryptKey::new_aes_128(decode_hex("2b7e151628aed2a6abf7158809cf4f3c")); + let mut block = [0_u8; 16]; + + block.copy_from_slice(&decode_hex::<16>("6bc1bee22e409f96e93d7e117393172a")); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("3ad77bb40d7a3660a89ecaf32466ef97"), block); + + block.copy_from_slice(&decode_hex::<16>("ae2d8a571e03ac9c9eb76fac45af8e51")); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("f5d3d58503b9699de785895a96fdbaaf"), block); + + block.copy_from_slice(&decode_hex::<16>("30c81c46a35ce411e5fbc1191a0a52ef")); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("43b1cd7f598ece23881b00e3ed030688"), block); + + block.copy_from_slice(&decode_hex::<16>("f69f2445df4f9b17ad2b417be66c3710")); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("7b0c785e27e8ad3f8223207104725dd4"), block); + } + + // test data from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.2 + #[test] + fn aes_128_test_decrypt() { + let key = AesDecryptKey::new_aes_128(decode_hex("2b7e151628aed2a6abf7158809cf4f3c")); + let mut block = [0_u8; 16]; + + block.copy_from_slice(&decode_hex::<16>("3ad77bb40d7a3660a89ecaf32466ef97")); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex::<16>("6bc1bee22e409f96e93d7e117393172a"), block); + + block.copy_from_slice(&decode_hex::<16>("f5d3d58503b9699de785895a96fdbaaf")); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"), block); + + block.copy_from_slice(&decode_hex::<16>("43b1cd7f598ece23881b00e3ed030688")); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex::<16>("30c81c46a35ce411e5fbc1191a0a52ef"), block); + + block.copy_from_slice(&decode_hex::<16>("7b0c785e27e8ad3f8223207104725dd4").as_slice()); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex::<16>("f69f2445df4f9b17ad2b417be66c3710"), block); + } + + // test data from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.5 + #[test] + pub fn aes_256_test_encrypt() { + let key = AesEncryptKey::new_aes_256(decode_hex( + "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + )); + let mut block: [u8; 16]; + + block = decode_hex("6bc1bee22e409f96e93d7e117393172a"); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("f3eed1bdb5d2a03c064b5a7e3db181f8"), block); + + block = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51"); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("591ccb10d410ed26dc5ba74a31362870"), block); + + block = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef"); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("b6ed21b99ca6f4f9f153e7b1beafed1d"), block); + + block = decode_hex("f69f2445df4f9b17ad2b417be66c3710"); + Aes::encrypt(&key, &mut block); + assert_eq!(decode_hex("23304b7a39f9f3ff067d8d8f9e24ecc7"), block); + } + + // test data from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.6 + #[test] + fn aes_256_test_decrypt() { + let key = AesDecryptKey::new_aes_256(decode_hex( + "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + )); + + let mut block: [u8; 16]; + + block = decode_hex("f3eed1bdb5d2a03c064b5a7e3db181f8"); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex("6bc1bee22e409f96e93d7e117393172a"), block); + + block = decode_hex("591ccb10d410ed26dc5ba74a31362870"); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51"), block); + + block = decode_hex("b6ed21b99ca6f4f9f153e7b1beafed1d"); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex("30c81c46a35ce411e5fbc1191a0a52ef"), block); + + block = decode_hex("23304b7a39f9f3ff067d8d8f9e24ecc7"); + Aes::decrypt(&key, &mut block); + assert_eq!(decode_hex("f69f2445df4f9b17ad2b417be66c3710"), block); + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/digest.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/digest.rs new file mode 100644 index 00000000..35b65345 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/digest.rs @@ -0,0 +1,218 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +use core::marker::PhantomData; + +use crate::ForeignTypeRef; + +/// The SHA-256 digest algorithm. +#[derive(Clone)] +pub struct Sha256 {} + +/// The SHA-512 digest algorithm. +#[derive(Clone)] +pub struct Sha512 {} + +/// A reference to an [`Md`], which abstracts the details of a specific hash function allowing code +/// to deal with the concept of a "hash function" without needing to know exactly which hash function +/// it is. +#[non_exhaustive] +pub struct MdRef; + +unsafe impl ForeignTypeRef for MdRef { + type CType = bssl_sys::EVP_MD; +} + +/// Used internally to get a BoringSSL internal MD +pub trait Md { + /// The output size of the hash operation. + const OUTPUT_SIZE: usize; + + /// Gets a reference to a message digest algorithm to be used by the HKDF implementation. + fn get_md() -> &'static MdRef; +} + +impl Md for Sha256 { + const OUTPUT_SIZE: usize = bssl_sys::SHA256_DIGEST_LENGTH as usize; + + fn get_md() -> &'static MdRef { + // Safety: + // - this always returns a valid pointer to an EVP_MD + unsafe { MdRef::from_ptr(bssl_sys::EVP_sha256() as *mut _) } + } +} + +impl Sha256 { + /// Creates a new [Digest] to compute a SHA-256 hash. + pub fn new_digest() -> Digest { + // Note: This cannot be in the trait because using associated constants exprs there + // requires nightly. + Digest::::new() + } +} + +impl Md for Sha512 { + const OUTPUT_SIZE: usize = bssl_sys::SHA512_DIGEST_LENGTH as usize; + + fn get_md() -> &'static MdRef { + // Safety: + // - this always returns a valid pointer to an EVP_MD + unsafe { MdRef::from_ptr(bssl_sys::EVP_sha512() as *mut _) } + } +} + +impl Sha512 { + /// Create a new [Digest] to compute a SHA-512 hash. + pub fn new_digest() -> Digest { + // Note: This cannot be in the trait because using associated constants exprs there + // requires nightly. + Digest::::new() + } +} + +/// A pending digest operation. +pub struct Digest(bssl_sys::EVP_MD_CTX, PhantomData); + +impl Digest { + + /// Creates a new Digest from the given `Md` type parameter. + /// + /// Panics: + /// - If `Md::OUTPUT_SIZE` is not the same as `OUTPUT_SIZE`. + fn new() -> Self { + // Note: runtime assertion needed here since using {M::OUTPUT_SIZE} in return type requires + // unstable Rust feature. + assert_eq!(M::OUTPUT_SIZE, OUTPUT_SIZE); + let mut md_ctx_uninit = core::mem::MaybeUninit::::uninit(); + // Safety: + // - `EVP_DigestInit` initializes `md_ctx_uninit` + // - `MdRef` ensures the validity of `md.as_ptr` + let result = + unsafe { bssl_sys::EVP_DigestInit(md_ctx_uninit.as_mut_ptr(), M::get_md().as_ptr()) }; + assert_eq!(result, 1, "bssl_sys::EVP_DigestInit failed"); + // Safety: + // - md_ctx_uninit initialized with EVP_DigestInit, and the function returned 1 (success) + let md_ctx = unsafe { md_ctx_uninit.assume_init() }; + Self(md_ctx, PhantomData) + } + + /// Hashes the provided input into the current digest operation. + pub fn update(&mut self, data: &[u8]) { + // Safety: + // - `data` is a slice from safe Rust. + let result = unsafe { + bssl_sys::EVP_DigestUpdate(&mut self.0, data.as_ptr() as *const _, data.len()) + }; + assert_eq!(result, 1, "bssl_sys::EVP_DigestUpdate failed"); + } + + /// Computes the final digest value, consuming the object. + #[allow(clippy::expect_used)] + pub fn finalize(mut self) -> [u8; OUTPUT_SIZE] { + let mut digest_uninit = + core::mem::MaybeUninit::<[u8; bssl_sys::EVP_MAX_MD_SIZE as usize]>::uninit(); + let mut len_uninit = core::mem::MaybeUninit::::uninit(); + // Safety: + // - `digest_uninit` is allocated to `EVP_MAX_MD_SIZE` bytes long, as required by + // EVP_DigestFinal_ex + // - `self.0` is owned by `self`, and is going to be cleaned up on drop. + let result = unsafe { + bssl_sys::EVP_DigestFinal_ex( + &mut self.0, + digest_uninit.as_mut_ptr() as *mut _, + len_uninit.as_mut_ptr(), + ) + }; + assert_eq!(result, 1, "bssl_sys::EVP_DigestFinal_ex failed"); + // Safety: + // - `len_uninit` is initialized by `EVP_DigestFinal_ex`, and we checked the result above + let len = unsafe { len_uninit.assume_init() }; + assert_eq!( + OUTPUT_SIZE, len as usize, + "bssl_sys::EVP_DigestFinal_ex failed" + ); + // Safety: Result of DigestFinal_ex was checked above + let digest = unsafe { digest_uninit.assume_init() }; + digest + .get(..OUTPUT_SIZE) + .and_then(|digest| digest.try_into().ok()) + .expect("The length of `digest` was checked above") + } +} + +impl Drop for Digest { + fn drop(&mut self) { + // Safety: `self.0` is owned by `self`, and is invalidated after `drop`. + unsafe { + bssl_sys::EVP_MD_CTX_cleanup(&mut self.0); + } + } +} + +#[cfg(test)] +mod test { + use crate::test_helpers::decode_hex; + + use super::*; + + #[test] + fn test_sha256_c_type() { + unsafe { + assert_eq!( + MdRef::from_ptr(bssl_sys::EVP_sha256() as *mut _).as_ptr(), + bssl_sys::EVP_sha256() as *mut _ + ) + } + } + + #[test] + fn test_sha512_c_type() { + unsafe { + assert_eq!( + MdRef::from_ptr(bssl_sys::EVP_sha512() as *mut _).as_ptr(), + bssl_sys::EVP_sha512() as *mut _ + ) + } + } + + #[test] + fn test_digest_sha256() { + let mut digest = Sha256::new_digest(); + let msg: [u8; 4] = decode_hex("74ba2521"); + digest.update(&msg); + let expected_digest: [u8; 32] = + decode_hex("b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e"); + assert_eq!(expected_digest, digest.finalize()); + } + + #[test] + fn test_digest_sha512() { + let mut digest = Sha512::new_digest(); + let msg: [u8; 4] = decode_hex("23be86d5"); + digest.update(&msg); + let expected_digest: [u8; 64] = decode_hex(concat!( + "76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2", + "ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb" + )); + assert_eq!(expected_digest, digest.finalize()); + } + + #[test] + #[should_panic] + fn test_digest_wrong_size() { + // This should not happen since we don't externally expose Digest::new + Digest::::new(); + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/ed25519.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/ed25519.rs new file mode 100644 index 00000000..df365079 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/ed25519.rs @@ -0,0 +1,219 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +use crate::CSlice; + +/// The length in bytes of an Ed25519 public key. +pub const PUBLIC_KEY_LENGTH: usize = bssl_sys::ED25519_PUBLIC_KEY_LEN as usize; + +/// The length in bytes of an Ed25519 seed which is the 32-byte private key representation defined +/// in RFC 8032. +pub const SEED_LENGTH: usize = + (bssl_sys::ED25519_PRIVATE_KEY_LEN - bssl_sys::ED25519_PUBLIC_KEY_LEN) as usize; + +/// The length in bytes of an Ed25519 signature. +pub const SIGNATURE_LENGTH: usize = bssl_sys::ED25519_SIGNATURE_LEN as usize; + +// The length in bytes of an Ed25519 keypair. In BoringSSL, the private key is suffixed with the +// public key, so the keypair length is the same as the private key length. +const KEYPAIR_LENGTH: usize = bssl_sys::ED25519_PRIVATE_KEY_LEN as usize; + +/// An Ed25519 private key. +pub struct PrivateKey([u8; KEYPAIR_LENGTH]); + +/// An Ed25519 signature created by signing a message with a private key. +pub struct Signature([u8; SIGNATURE_LENGTH]); + +/// An Ed25519 public key used to verify a signature + message. +pub struct PublicKey([u8; PUBLIC_KEY_LENGTH]); + +/// Error returned if the verification on the signature + message fails. +#[derive(Debug)] +pub struct SignatureError; + +impl PrivateKey { + /// Generates a new Ed25519 keypair. + pub fn generate() -> Self { + let mut public_key = [0u8; PUBLIC_KEY_LENGTH]; + let mut private_key = [0u8; KEYPAIR_LENGTH]; + + // Safety: + // - Public key and private key are the correct length. + unsafe { bssl_sys::ED25519_keypair(public_key.as_mut_ptr(), private_key.as_mut_ptr()) } + + PrivateKey(private_key) + } + + /// Converts the key-pair to an array of bytes consisting of the bytes of the private key + /// followed by the bytes of the public key. + pub fn to_seed(&self) -> [u8; SEED_LENGTH] { + // This code will never panic because a length 32 slice will always fit into a + // size 32 byte array. The private key is the first 32 bytes of the keypair. + #[allow(clippy::expect_used)] + self.0[..SEED_LENGTH].try_into().expect( + "A slice of length SEED_LENGTH will always fit into an array of length SEED_LENGTH", + ) + } + + /// Builds this key-pair from `seed`, which is the 32-byte private key representation defined + /// in RFC 8032. + pub fn new_from_seed(seed: &[u8; SEED_LENGTH]) -> Self { + let mut public_key = [0u8; PUBLIC_KEY_LENGTH]; + let mut private_key = [0u8; KEYPAIR_LENGTH]; + + // Safety: + // - Public key, private key, and seed are the correct lengths. + unsafe { + bssl_sys::ED25519_keypair_from_seed( + public_key.as_mut_ptr(), + private_key.as_mut_ptr(), + seed.as_ptr(), + ) + } + PrivateKey(private_key) + } + + /// Signs the given message and returns a digital signature. + pub fn sign(&self, msg: &[u8]) -> Signature { + let mut sig_bytes = [0u8; SIGNATURE_LENGTH]; + + // Safety: + // - On allocation failure we panic. + // - Signature and private keys are always the correct length. + let result = unsafe { + bssl_sys::ED25519_sign( + sig_bytes.as_mut_ptr(), + msg.as_ptr(), + msg.len(), + self.0.as_ptr(), + ) + }; + assert_eq!(result, 1, "allocation failure in bssl_sys::ED25519_sign"); + + Signature(sig_bytes) + } + + /// Returns the PublicKey of the KeyPair. + pub fn public(&self) -> PublicKey { + let keypair_bytes = self.0; + + // This code will never panic because a length 32 slice will always fit into a + // size 32 byte array. The public key is the last 32 bytes of the keypair. + #[allow(clippy::expect_used)] + PublicKey( + keypair_bytes[PUBLIC_KEY_LENGTH..] + .try_into() + .expect("The slice is always the correct size for a public key"), + ) + } +} + +impl PublicKey { + /// Builds the public key from an array of bytes. + pub fn from_bytes(bytes: [u8; PUBLIC_KEY_LENGTH]) -> Self { + PublicKey(bytes) + } + + /// Returns the bytes of the public key. + pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] { + self.0 + } + + /// Succeeds if the signature is a valid signature created by this keypair, otherwise returns an Error. + pub fn verify(&self, message: &[u8], signature: Signature) -> Result<(), SignatureError> { + let message_cslice = CSlice::from(message); + let ret = unsafe { + bssl_sys::ED25519_verify( + message_cslice.as_ptr(), + message_cslice.len(), + signature.0.as_ptr(), + self.0.as_ptr(), + ) + }; + if ret == 1 { + Ok(()) + } else { + Err(SignatureError) + } + } +} + +impl Signature { + /// Creates a signature from a byte array. + pub fn from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Self { + Self(bytes) + } + + /// Returns the bytes of the signature. + pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] { + self.0 + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::test_helpers; + + #[test] + fn ed25519_kp_gen_roundtrip() { + let private_key = PrivateKey::generate(); + assert_ne!([0u8; 64], private_key.0); + let seed = private_key.to_seed(); + let new_private_key = PrivateKey::new_from_seed(&seed); + assert_eq!(private_key.0, new_private_key.0); + } + + #[test] + fn ed25519_empty_msg() { + // Test Case 1 from RFC test vectors: https://www.rfc-editor.org/rfc/rfc8032#section-7.1 + let pk = test_helpers::decode_hex( + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + ); + let sk = test_helpers::decode_hex( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + ); + let msg = [0u8; 0]; + let sig_expected = test_helpers::decode_hex("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + let kp = PrivateKey::new_from_seed(&sk); + let sig = kp.sign(&msg); + assert_eq!(sig_expected, sig.0); + + let pub_key = PublicKey::from_bytes(pk); + assert_eq!(pub_key.to_bytes(), kp.public().to_bytes()); + assert!(pub_key.verify(&msg, sig).is_ok()); + } + + #[test] + fn ed25519_sign_and_verify() { + // Test Case 15 from RFC test vectors: https://www.rfc-editor.org/rfc/rfc8032#section-7.1 + let pk = test_helpers::decode_hex( + "cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291", + ); + let sk = test_helpers::decode_hex( + "9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738", + ); + let msg: [u8; 14] = test_helpers::decode_hex("55c7fa434f5ed8cdec2b7aeac173"); + let sig_expected = test_helpers::decode_hex("6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06"); + let kp = PrivateKey::new_from_seed(&sk); + + let sig = kp.sign(&msg); + assert_eq!(sig_expected, sig.0); + + let pub_key = PublicKey::from_bytes(pk); + assert_eq!(pub_key.to_bytes(), kp.public().to_bytes()); + assert!(pub_key.verify(&msg, sig).is_ok()); + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/hkdf.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/hkdf.rs new file mode 100644 index 00000000..d3144951 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/hkdf.rs @@ -0,0 +1,288 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +use crate::digest::Md; +use crate::digest::{Sha256, Sha512}; +use crate::{CSlice, CSliceMut, ForeignTypeRef}; +use core::marker::PhantomData; + +/// Implementation of HKDF-SHA-256 +pub type HkdfSha256 = Hkdf; + +/// Implementation of HKDF-SHA-512 +pub type HkdfSha512 = Hkdf; + +/// Error type returned from the HKDF-Expand operations when the output key material has +/// an invalid length +#[derive(Debug)] +pub struct InvalidLength; + +/// Implementation of HKDF operations which are generic over a provided hashing functions. Type +/// aliases are provided above for convenience of commonly used hashes +pub struct Hkdf { + salt: Option>, + ikm: Vec, + _marker: PhantomData, +} + +impl Hkdf { + /// The max length of the output key material used for expanding + pub const MAX_OUTPUT_LENGTH: usize = M::OUTPUT_SIZE * 255; + + /// Creates a new instance of HKDF from a salt and key material + pub fn new(salt: Option<&[u8]>, ikm: &[u8]) -> Self { + Self { + salt: salt.map(Vec::from), + ikm: Vec::from(ikm), + _marker: PhantomData::default(), + } + } + + /// Computes HKDF-Expand operation from RFC 5869. The info argument for the expand is set to + /// the concatenation of all the elements of info_components. Returns InvalidLength if the + /// output is too large. + pub fn expand_multi_info( + &self, + info_components: &[&[u8]], + okm: &mut [u8], + ) -> Result<(), InvalidLength> { + self.expand(&info_components.concat(), okm) + } + + /// Computes HKDF-Expand operation from RFC 5869. Returns InvalidLength if the output is too large. + pub fn expand(&self, info: &[u8], okm: &mut [u8]) -> Result<(), InvalidLength> { + // extract the salt bytes from the option, or empty slice if option is None + let salt = self.salt.as_deref().unwrap_or_default(); + + //validate the output size + (okm.len() <= Self::MAX_OUTPUT_LENGTH && !okm.is_empty()) + .then(|| { + let mut okm_cslice = CSliceMut::from(okm); + + // Safety: + // - We validate the output length above, so invalid length errors will never be hit + // which leaves allocation failures as the only possible error case, in which case + // we panic immediately + let result = unsafe { + bssl_sys::HKDF( + okm_cslice.as_mut_ptr(), + okm_cslice.len(), + M::get_md().as_ptr(), + CSlice::from(self.ikm.as_slice()).as_ptr(), + self.ikm.as_slice().len(), + CSlice::from(salt).as_ptr(), + salt.len(), + CSlice::from(info).as_ptr(), + info.len(), + ) + }; + assert!(result > 0, "Allocation failure in bssl_sys::HKDF"); + }) + .ok_or(InvalidLength) + } +} + +#[cfg(test)] +mod tests { + use crate::hkdf::{HkdfSha256, HkdfSha512}; + use crate::test_helpers::{decode_hex, decode_hex_into_vec}; + use core::iter; + + struct Test { + ikm: Vec, + salt: Vec, + info: Vec, + okm: Vec, + } + + #[test] + fn hkdf_sha_256_test() { + let ikm = decode_hex_into_vec("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); + let salt = decode_hex_into_vec("000102030405060708090a0b0c"); + let info = decode_hex_into_vec("f0f1f2f3f4f5f6f7f8f9"); + + let hk = HkdfSha256::new(Some(salt.as_slice()), ikm.as_slice()); + let mut okm = [0u8; 42]; + hk.expand(&info, &mut okm) + .expect("42 is a valid length for Sha256 to output"); + + let expected = decode_hex( + "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865", + ); + assert_eq!(okm, expected); + } + + #[test] + fn hkdf_sha512_test() { + let ikm = decode_hex_into_vec("5d3db20e8238a90b62a600fa57fdb318"); + let salt = decode_hex_into_vec("1d6f3b38a1e607b5e6bcd4af1800a9d3"); + let info = decode_hex_into_vec("2bc5f39032b6fc87da69ba8711ce735b169646fd"); + + let hk = HkdfSha512::new(Some(salt.as_slice()), ikm.as_slice()); + let mut okm = [0u8; 42]; + hk.expand(&info, &mut okm).expect("Should succeed"); + + let expected = decode_hex( + "8c3cf7122dcb5eb7efaf02718f1faf70bca20dcb75070e9d0871a413a6c05fc195a75aa9ffc349d70aae", + ); + assert_eq!(okm, expected); + } + + // Test Vectors from https://tools.ietf.org/html/rfc5869. + #[test] + fn test_rfc5869_sha256() { + let tests = [ + Test { + // Test Case 1 + ikm: decode_hex_into_vec("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + salt: decode_hex_into_vec("000102030405060708090a0b0c"), + info: decode_hex_into_vec("f0f1f2f3f4f5f6f7f8f9"), + okm: decode_hex_into_vec("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") + }, + Test { + // Test Case 2 + ikm: decode_hex_into_vec( + "000102030405060708090a0b0c0d0e0f\ + 101112131415161718191a1b1c1d1e1f\ + 202122232425262728292a2b2c2d2e2f\ + 303132333435363738393a3b3c3d3e3f\ + 404142434445464748494a4b4c4d4e4f", + ), + salt: decode_hex_into_vec( + "606162636465666768696a6b6c6d6e6f\ + 707172737475767778797a7b7c7d7e7f\ + 808182838485868788898a8b8c8d8e8f\ + 909192939495969798999a9b9c9d9e9f\ + a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + ), + info: decode_hex_into_vec( + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf\ + c0c1c2c3c4c5c6c7c8c9cacbcccdcecf\ + d0d1d2d3d4d5d6d7d8d9dadbdcdddedf\ + e0e1e2e3e4e5e6e7e8e9eaebecedeeef\ + f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + ), + okm: decode_hex_into_vec( + "b11e398dc80327a1c8e7f78c596a4934\ + 4f012eda2d4efad8a050cc4c19afa97c\ + 59045a99cac7827271cb41c65e590e09\ + da3275600c2f09b8367793a9aca3db71\ + cc30c58179ec3e87c14c01d5c1f3434f\ + 1d87", + ) + }, + Test { + // Test Case 3 + ikm: decode_hex_into_vec("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + salt: Vec::new(), + info: Vec::new(), + okm: decode_hex_into_vec( + "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8"), + }, + ]; + for Test { + ikm, + salt, + info, + okm, + } in tests.iter() + { + let salt = if salt.is_empty() { + None + } else { + Some(salt.as_slice()) + }; + let hkdf = HkdfSha256::new(salt, ikm.as_slice()); + let mut okm2 = vec![0u8; okm.len()]; + assert!(hkdf.expand(info.as_slice(), &mut okm2).is_ok()); + assert_eq!(okm2.as_slice(), okm.as_slice()); + } + } + + #[test] + fn test_lengths() { + let hkdf = HkdfSha256::new(None, &[]); + let mut longest = vec![0u8; HkdfSha256::MAX_OUTPUT_LENGTH]; + assert!(hkdf.expand(&[], &mut longest).is_ok()); + // start at 1 since 0 is an invalid length + let lengths = 1..HkdfSha256::MAX_OUTPUT_LENGTH + 1; + + for length in lengths { + let mut okm = vec![0u8; length]; + + assert!(hkdf.expand(&[], &mut okm).is_ok()); + assert_eq!(okm.len(), length); + assert_eq!(okm[..], longest[..length]); + } + } + + #[test] + fn test_max_length() { + let hkdf = HkdfSha256::new(Some(&[]), &[]); + let mut okm = vec![0u8; HkdfSha256::MAX_OUTPUT_LENGTH]; + assert!(hkdf.expand(&[], &mut okm).is_ok()); + } + + #[test] + fn test_max_length_exceeded() { + let hkdf = HkdfSha256::new(Some(&[]), &[]); + let mut okm = vec![0u8; HkdfSha256::MAX_OUTPUT_LENGTH + 1]; + assert!(hkdf.expand(&[], &mut okm).is_err()); + } + + #[test] + fn test_unsupported_length() { + let hkdf = HkdfSha256::new(Some(&[]), &[]); + let mut okm = vec![0u8; 90000]; + assert!(hkdf.expand(&[], &mut okm).is_err()); + } + + #[test] + fn test_expand_multi_info() { + let info_components = &[ + &b"09090909090909090909090909090909090909090909"[..], + &b"8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a"[..], + &b"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0"[..], + &b"4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4"[..], + &b"1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d"[..], + ]; + + let hkdf = HkdfSha256::new(None, b"some ikm here"); + + // Compute HKDF-Expand on the concatenation of all the info components + let mut oneshot_res = [0u8; 16]; + hkdf.expand(&info_components.concat(), &mut oneshot_res) + .unwrap(); + + // Now iteratively join the components of info_components until it's all 1 component. The value + // of HKDF-Expand should be the same throughout + let mut num_concatted = 0; + let mut info_head = Vec::new(); + + while num_concatted < info_components.len() { + info_head.extend(info_components[num_concatted]); + + // Build the new input to be the info head followed by the remaining components + let input: Vec<&[u8]> = iter::once(info_head.as_slice()) + .chain(info_components.iter().cloned().skip(num_concatted + 1)) + .collect(); + + // Compute and compare to the one-shot answer + let mut multipart_res = [0u8; 16]; + hkdf.expand_multi_info(&input, &mut multipart_res).unwrap(); + assert_eq!(multipart_res, oneshot_res); + num_concatted += 1; + } + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/hmac.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/hmac.rs new file mode 100644 index 00000000..167e92e5 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/hmac.rs @@ -0,0 +1,447 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +use crate::{ + digest::{Md, Sha256, Sha512}, + CSlice, ForeignTypeRef as _, +}; +use core::{ + ffi::{c_uint, c_void}, + marker::PhantomData, + ptr, +}; + +/// Computes the HMAC-SHA256 of `data` as a one-shot operation. +/// +/// Calculates the HMAC of data, using the given `key` and returns the result. +/// It returns the computed HMAC. +pub fn hmac_sha256(key: &[u8], data: &[u8]) -> [u8; 32] { + hmac::<32, Sha256>(key, data) +} + +/// Computes the HMAC-SHA512 of `data` as a one-shot operation. +/// +/// Calculates the HMAC of data, using the given `key` and returns the result. +/// It returns the computed HMAC. +pub fn hmac_sha512(key: &[u8], data: &[u8]) -> [u8; 64] { + hmac::<64, Sha512>(key, data) +} + +/// An HMAC-SHA256 operation in progress. +pub struct HmacSha256(Hmac<32, Sha256>); + +impl HmacSha256 { + /// Creates a new HMAC operation from a fixed-length key. + pub fn new(key: [u8; 32]) -> Self { + Self(Hmac::new(key)) + } + + /// Creates a new HMAC operation from a variable-length key. + pub fn new_from_slice(key: &[u8]) -> Self { + Self(Hmac::new_from_slice(key)) + } + + /// Hashes the provided input into the HMAC operation. + pub fn update(&mut self, data: &[u8]) { + self.0.update(data) + } + + /// Computes the final HMAC value, consuming the object. + pub fn finalize(self) -> [u8; 32] { + self.0.finalize() + } + + /// Checks that the provided tag value matches the computed HMAC value. + pub fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { + self.0.verify_slice(tag) + } + + /// Checks that the provided tag value matches the computed HMAC value. + pub fn verify(self, tag: [u8; 32]) -> Result<(), MacError> { + self.0.verify(tag) + } + + /// Checks that the provided tag value matches the computed HMAC, truncated to the input tag's + /// length. + /// + /// Truncating an HMAC reduces the security of the construction. Callers must ensure `tag`'s + /// length matches the desired HMAC length and security level. + pub fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { + self.0.verify_truncated_left(tag) + } + + /// Resets the object to its initial state. The key is retained, but input is discarded. + pub fn reset(&mut self) { + // TODO(davidben): This method is a little odd. The main use case I can imagine is + // computing multiple HMACs with the same key, while reusing the input-independent key + // setup. However, finalize consumes the object, so you cannot actually reuse the + // context afterwards. Moreover, even if you could, that mutates the context, so a + // better pattern would be to copy the initial context, or to have an HmacKey type + // that one could create contexts out of. + self.0.reset() + } +} + +/// An HMAC-SHA512 operation in progress. +pub struct HmacSha512(Hmac<64, Sha512>); + +impl HmacSha512 { + /// Creates a new HMAC operation from a fixed-size key. + pub fn new(key: [u8; 64]) -> Self { + Self(Hmac::new(key)) + } + + /// Creates a new HMAC operation from a variable-length key. + pub fn new_from_slice(key: &[u8]) -> Self { + Self(Hmac::new_from_slice(key)) + } + + /// Hashes the provided input into the HMAC operation. + pub fn update(&mut self, data: &[u8]) { + self.0.update(data) + } + + /// Computes the final HMAC value, consuming the object. + pub fn finalize(self) -> [u8; 64] { + self.0.finalize() + } + + /// Checks that the provided tag value matches the computed HMAC value. + pub fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { + self.0.verify_slice(tag) + } + + /// Checks that the provided tag value matches the computed HMAC value. + pub fn verify(self, tag: [u8; 64]) -> Result<(), MacError> { + self.0.verify(tag) + } + + /// Checks that the provided tag value matches the computed HMAC, truncated to the input tag's + /// length. + /// + /// Truncating an HMAC reduces the security of the construction. Callers must ensure `tag`'s + /// length matches the desired HMAC length and security level. + pub fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { + self.0.verify_truncated_left(tag) + } + + /// Resets the object to its initial state. The key is retained, but input is discarded. + pub fn reset(&mut self) { + // TODO(davidben): This method is a little odd. The main use case I can imagine is + // computing multiple HMACs with the same key, while reusing the input-independent key + // setup. However, finalize consumes the object, so you cannot actually reuse the + // context afterwards. Moreover, even if you could, that mutates the context, so a + // better pattern would be to copy the initial context, or to have an HmacKey type + // that one could create contexts out of. + self.0.reset() + } +} + +/// Error type for when the output of the hmac operation is not equal to the expected value. +#[derive(Debug)] +pub struct MacError; + +/// Private generically implemented function for computing hmac as a oneshot operation. +/// This should only be exposed publicly by types with the correct output size `N` which corresponds +/// to the output size of the provided generic hash function. Ideally `N` would just come from `M`, +/// but this is not possible until the Rust language can support the `min_const_generics` feature. +/// Until then we will have to pass both separately: https://github.com/rust-lang/rust/issues/60551 +#[inline] +fn hmac(key: &[u8], data: &[u8]) -> [u8; N] { + let mut out = [0_u8; N]; + let mut size: c_uint = 0; + + // Safety: + // - buf always contains N bytes of space + // - If NULL is returned on error we panic immediately + let result = unsafe { + bssl_sys::HMAC( + M::get_md().as_ptr(), + CSlice::from(key).as_ptr(), + key.len(), + CSlice::from(data).as_ptr(), + data.len(), + out.as_mut_ptr(), + &mut size as *mut c_uint, + ) + }; + assert!(!result.is_null(), "Result of bssl_sys::HMAC was null"); + + out +} + +/// Private generically implemented hmac instance given a generic hash function and a length `N`, +/// where `N` is the output size of the hash function. This should only be exposed publicly by +/// wrapper types with the correct output size `N` which corresponds to the output size of the +/// provided generic hash function. Ideally `N` would just come from `M`, but this is not possible +/// until the Rust language can support the `min_const_generics` feature. Until then we will have to +/// pass both separately: https://github.com/rust-lang/rust/issues/60551 +struct Hmac { + ctx: *mut bssl_sys::HMAC_CTX, + _marker: PhantomData, +} + +impl Hmac { + /// Creates a new HMAC operation from a fixed-length key. + fn new(key: [u8; N]) -> Self { + Self::new_from_slice(&key) + } + + /// Creates a new HMAC operation from a variable-length key. + fn new_from_slice(key: &[u8]) -> Self { + // Safety: + // - HMAC_CTX_new panics if allocation fails + let ctx = unsafe { bssl_sys::HMAC_CTX_new() }; + assert!( + !ctx.is_null(), + "result of bssl_sys::HMAC_CTX_new() was null" + ); + + // Safety: + // - HMAC_Init_ex must be called with a context previously created with HMAC_CTX_new, + // which is the line above. + // - HMAC_Init_ex may return an error if key is null but the md is different from + // before. This is avoided here since key is guaranteed to be non-null. + // - HMAC_Init_ex returns 0 on allocation failure in which case we panic + let result = unsafe { + bssl_sys::HMAC_Init_ex( + ctx, + CSlice::from(key).as_ptr() as *const c_void, + key.len(), + M::get_md().as_ptr(), + ptr::null_mut(), + ) + }; + assert!(result > 0, "Allocation failure in bssl_sys::HMAC_Init_ex"); + + Self { + ctx, + _marker: Default::default(), + } + } + + /// Hashes the provided input into the HMAC operation. + fn update(&mut self, data: &[u8]) { + let result = unsafe { + // Safety: HMAC_Update will always return 1, in case it doesnt we panic + bssl_sys::HMAC_Update(self.ctx, data.as_ptr(), data.len()) + }; + assert_eq!(result, 1, "failure in bssl_sys::HMAC_Update"); + } + + /// Computes the final HMAC value, consuming the object. + fn finalize(self) -> [u8; N] { + let mut buf = [0_u8; N]; + let mut size: c_uint = 0; + // Safety: + // - hmac has a fixed size output of N which will never exceed the length of an N + // length array + // - on allocation failure we panic + let result = + unsafe { bssl_sys::HMAC_Final(self.ctx, buf.as_mut_ptr(), &mut size as *mut c_uint) }; + assert!(result > 0, "Allocation failure in bssl_sys::HMAC_Final"); + buf + } + + /// Checks that the provided tag value matches the computed HMAC value. + fn verify(self, tag: [u8; N]) -> Result<(), MacError> { + self.verify_slice(&tag) + } + + /// Checks that the provided tag value matches the computed HMAC value. + /// + /// Returns `Error` if `tag` is not valid or not equal in length + /// to MAC's output. + fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { + tag.len().eq(&N).then_some(()).ok_or(MacError)?; + self.verify_truncated_left(tag) + } + + /// Checks that the provided tag value matches the computed HMAC, truncated to the input tag's + /// length. + /// + /// Returns `Error` if `tag` is not valid or empty. + /// + /// Truncating an HMAC reduces the security of the construction. Callers must ensure `tag`'s + /// length matches the desired HMAC length and security level. + fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { + let len = tag.len(); + if len == 0 || len > N { + return Err(MacError); + } + + let result = &self.finalize()[..len]; + + // Safety: + // - if a != b is undefined, it simply returns a non-zero result + unsafe { + bssl_sys::CRYPTO_memcmp( + CSlice::from(result).as_ptr() as *const c_void, + CSlice::from(tag).as_ptr() as *const c_void, + result.len(), + ) + } + .eq(&0) + .then_some(()) + .ok_or(MacError) + } + + /// Resets the hmac instance to its original state + fn reset(&mut self) { + // Passing a null ptr for the key will re-use the existing key + // Safety: + // - HMAC_Init_ex must be called with a context previously created with HMAC_CTX_new, + // which will always be the case if it is coming from self + // - HMAC_Init_ex may return an error if key is null but the md is different from + // before. The MD is guaranteed to be the same because it comes from the same generic param + // - HMAC_Init_ex returns 0 on allocation failure in which case we panic + let result = unsafe { + bssl_sys::HMAC_Init_ex( + self.ctx, + ptr::null_mut(), + 0, + M::get_md().as_ptr(), + ptr::null_mut(), + ) + }; + assert!(result > 0, "Allocation failure in bssl_sys::HMAC_Init_ex"); + } +} + +impl Drop for Hmac { + fn drop(&mut self) { + unsafe { bssl_sys::HMAC_CTX_free(self.ctx) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn hmac_sha256_test() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + + let key: [u8; 20] = [0x0b; 20]; + let data = b"Hi There"; + + let mut hmac = HmacSha256::new_from_slice(&key); + hmac.update(data); + let hmac_result: [u8; 32] = hmac.finalize(); + + assert_eq!(&hmac_result, &expected_hmac); + } + + #[test] + fn hmac_sha256_reset_test() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + + let key: [u8; 20] = [0x0b; 20]; + let data = b"Hi There"; + let incorrect_data = b"This data does not match the expected mac"; + + let mut hmac = HmacSha256::new_from_slice(&key); + hmac.update(incorrect_data); + hmac.reset(); + + // hmac should be back to original state, so now when we update with the correct data it + // should work + hmac.update(data); + let hmac_result: [u8; 32] = hmac.finalize(); + assert_eq!(&hmac_result, &expected_hmac); + } + + #[test] + fn hmac_sha256_fixed_size_key_test() { + let expected_hmac = [ + 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6, 0x99, 0x3, 0xa0, 0xf1, 0xcf, 0x2b, + 0xbd, 0xc5, 0xba, 0xa, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c, 0x7a, 0x3b, 0x16, 0x96, + 0xa0, 0xb6, 0x8c, 0xf7, + ]; + + let key: [u8; 32] = [0x0b; 32]; + let data = b"Hi There"; + + let mut hmac = HmacSha256::new(key); + hmac.update(data); + let hmac_result: [u8; 32] = hmac.finalize(); + assert_eq!(&hmac_result, &expected_hmac); + } + + #[test] + fn hmac_sha256_update_test() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + let key: [u8; 20] = [0x0b; 20]; + let data = b"Hi There"; + let mut hmac: HmacSha256 = HmacSha256::new_from_slice(&key); + hmac.update(data); + let result = hmac.finalize(); + assert_eq!(&result, &expected_hmac); + assert_eq!(result.len(), 32); + } + + #[test] + fn hmac_sha256_test_big_buffer() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + let key: [u8; 20] = [0x0b; 20]; + let data = b"Hi There"; + let hmac_result = hmac_sha256(&key, data); + assert_eq!(&hmac_result, &expected_hmac); + } + + #[test] + fn hmac_sha256_update_chunks_test() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + let key: [u8; 20] = [0x0b; 20]; + let mut hmac = HmacSha256::new_from_slice(&key); + hmac.update(b"Hi"); + hmac.update(b" There"); + let result = hmac.finalize(); + assert_eq!(&result, &expected_hmac); + } + + #[test] + fn hmac_sha256_verify_test() { + let expected_hmac = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, + 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, + 0x2e, 0x32, 0xcf, 0xf7, + ]; + let key: [u8; 20] = [0x0b; 20]; + let data = b"Hi There"; + let mut hmac: HmacSha256 = HmacSha256::new_from_slice(&key); + hmac.update(data); + assert!(hmac.verify(expected_hmac).is_ok()) + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/lib.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/lib.rs new file mode 100644 index 00000000..f4d1291c --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/lib.rs @@ -0,0 +1,140 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#![deny( + missing_docs, + unsafe_op_in_unsafe_fn, + clippy::indexing_slicing, + clippy::unwrap_used, + clippy::panic, + clippy::expect_used +)] + +//! Rust BoringSSL bindings + +extern crate core; + +/// AES block operations. +pub mod aes; + +/// Hash functions. +pub mod digest; + +/// Ed25519, a signature scheme. +pub mod ed25519; + +/// HKDF, a hash-based key derivation function. +pub mod hkdf; + +/// HMAC, a hash-based message authentication code. +pub mod hmac; + +/// Random number generation. +pub mod rand; + +/// BoringSSL implemented memory-manipulation operations. +pub mod mem; + +#[cfg(test)] +mod test_helpers; + +/// This is a helper struct which provides functions for passing slices over FFI. +struct CSlice<'a>(&'a [u8]); + +impl<'a> From<&'a [u8]> for CSlice<'a> { + fn from(value: &'a [u8]) -> Self { + Self(value) + } +} + +impl CSlice<'_> { + /// Returns a raw pointer to the value, which is safe to pass over FFI. + pub fn as_ptr(&self) -> *const T { + if self.0.is_empty() { + std::ptr::null() + } else { + self.0.as_ptr() as *const T + } + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +/// This is a helper struct which provides functions for passing mutable slices over FFI. +struct CSliceMut<'a>(&'a mut [u8]); + +impl CSliceMut<'_> { + /// Returns a raw pointer to the value, which is safe to pass over FFI. + pub fn as_mut_ptr(&mut self) -> *mut T { + if self.0.is_empty() { + std::ptr::null_mut() + } else { + self.0.as_mut_ptr() as *mut T + } + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +impl<'a> From<&'a mut [u8]> for CSliceMut<'a> { + fn from(value: &'a mut [u8]) -> Self { + Self(value) + } +} + +/// A helper trait implemented by types which reference borrowed foreign types. +/// +/// # Safety +/// +/// Implementations of `ForeignTypeRef` must guarantee the following: +/// +/// - `Self::from_ptr(x).as_ptr() == x` +/// - `Self::from_mut_ptr(x).as_ptr() == x` +unsafe trait ForeignTypeRef: Sized { + /// The raw C type. + type CType; + + /// Constructs a shared instance of this type from its raw type. + /// + /// # Safety + /// + /// `ptr` must be a valid, immutable, instance of the type for the `'a` lifetime. + #[inline] + unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self { + debug_assert!(!ptr.is_null()); + unsafe { &*(ptr as *mut _) } + } + + /// Constructs a mutable reference of this type from its raw type. + /// + /// # Safety + /// + /// `ptr` must be a valid, unique, instance of the type for the `'a` lifetime. + #[inline] + unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self { + debug_assert!(!ptr.is_null()); + unsafe { &mut *(ptr as *mut _) } + } + + /// Returns a raw pointer to the wrapped value. + #[inline] + fn as_ptr(&self) -> *mut Self::CType { + self as *const _ as *mut _ + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/mem.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/mem.rs new file mode 100644 index 00000000..a9031c4e --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/mem.rs @@ -0,0 +1,62 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/// Returns true iff `a` and `b` contain the same bytes. It takes an amount of time dependent on the +/// lengths, but independent of the contents of the slices `a` and `b`. The return type is a `bool`, +/// since unlike `memcmp` in C this function cannot be used to put elements into a defined order. +pub fn crypto_memcmp(a: &[u8], b: &[u8]) -> bool { + if a.len() != b.len() { + return false; + } + if a.is_empty() && b.is_empty() { + // Avoid FFI issues with empty slices that may potentially cause UB + return true; + } + // Safety: + // - The lengths of a and b are checked above. + let result = + unsafe { bssl_sys::CRYPTO_memcmp(a.as_ptr() as *const _, b.as_ptr() as *const _, a.len()) }; + result == 0 +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_different_length() { + assert!(!crypto_memcmp(&[0, 1, 2], &[0])) + } + + #[test] + fn test_same_length_different_content() { + assert!(!crypto_memcmp(&[0, 1, 2], &[1, 2, 3])) + } + + #[test] + fn test_same_content() { + assert!(crypto_memcmp(&[0, 1, 2], &[0, 1, 2])) + } + + #[test] + fn test_empty_slices() { + assert!(crypto_memcmp(&[], &[])) + } + + #[test] + fn test_empty_slices_different() { + assert!(!crypto_memcmp(&[], &[0, 1, 2])) + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/rand.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/rand.rs new file mode 100644 index 00000000..9fdbe0a7 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/rand.rs @@ -0,0 +1,41 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +use crate::CSliceMut; + +/// Fills buf with random bytes. In the event that sufficient random data can not be obtained, +/// BoringSSL will abort, so the assert will never be hit. +pub fn rand_bytes(buf: &mut [u8]) { + let mut ffi_buf = CSliceMut::from(buf); + let result = unsafe { bssl_sys::RAND_bytes(ffi_buf.as_mut_ptr(), ffi_buf.len()) }; + assert_eq!(result, 1, "BoringSSL RAND_bytes API failed unexpectedly"); +} + +#[cfg(test)] +mod tests { + use super::rand_bytes; + + #[test] + fn test_rand_bytes() { + let mut buf = [0; 32]; + rand_bytes(&mut buf); + } + + #[test] + fn test_rand_bytes_empty() { + let mut buf = []; + rand_bytes(&mut buf); + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-crypto/src/test_helpers.rs b/third_party/boringssl/kit/src/rust/bssl-crypto/src/test_helpers.rs new file mode 100644 index 00000000..ea2d9dbc --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-crypto/src/test_helpers.rs @@ -0,0 +1,31 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +pub(crate) fn decode_hex(s: &str) -> [u8; N] { + (0..s.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("Invalid hex string")) + .collect::>() + .as_slice() + .try_into() + .unwrap() +} + +pub(crate) fn decode_hex_into_vec(s: &str) -> Vec { + (0..s.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("Invalid hex string")) + .collect::>() +} diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/CMakeLists.txt b/third_party/boringssl/kit/src/rust/bssl-sys/CMakeLists.txt new file mode 100644 index 00000000..d17a8f10 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/CMakeLists.txt @@ -0,0 +1,49 @@ +# Additional interop for things like macros and inlined functions. +add_library(rust_wrapper STATIC rust_wrapper.c) +target_link_libraries(rust_wrapper crypto) + +# Generate architecture-specific wrappers. bindgen must be called from +# ${CMAKE_BINARY_DIR}, with the output path as a relative path. bindgen writes +# the depfile using the same syntax as the command-line argument, and ninja +# requires a path relative to the top-level build directory. +set(wrapper wrapper_${RUST_BINDINGS}.rs) +binary_dir_relative_path(${wrapper} wrapper_relative) +binary_dir_relative_path(${wrapper}.d depfile_relative) + +add_custom_command( + OUTPUT ${wrapper} + COMMAND ${BINDGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.h + -o ${wrapper_relative} + --depfile=${depfile_relative} + --no-derive-default + --enable-function-attribute-detection + --use-core + --default-macro-constant-type=signed + --rustified-enum=point_conversion_form_t + # These regexes need to accept both / and \ to handle Windows file + # path differences, due a bindgen issue. See + # https://crbug.com/boringssl/595. Ideally, we would write [/\\], but + # there are many layers of escaping here. First, CMake interprets + # backslashes. Then CMake generates a Ninja or Make file. That, in + # turn, uses the shell on POSIX, and does something else on Windows. + # + # It is unlikely that every layer here has sufficiently well-defined + # escaping and correctly handled the next layer's escaping. On top of + # that, we'd likely need to detect Windows vs POSIX hosts and change + # the input. Instead, just use [[:punct:]] which is more permissive + # than necessary, but we only need to exclude unwanted libc headers. + # + # If bindgen ever supports some file-based config (see + # https://github.com/rust-lang/rust-bindgen/issues/2508), we can + # switch to that. + --allowlist-file=".*[[:punct:]]include[[:punct:]]openssl[[:punct:]].*\\.h" + --allowlist-file=".*[[:punct:]]rust_wrapper\\.h" + -- # these are LLVM arg passthroughs + -I${PROJECT_SOURCE_DIR}/include + # https://doc.rust-lang.org/nightly/rustc/platform-support.html + --target=${RUST_BINDINGS} + DEPENDS wrapper.h + DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${wrapper}.d + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_custom_target(bssl_sys ALL DEPENDS ${wrapper}) diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/Cargo.toml b/third_party/boringssl/kit/src/rust/bssl-sys/Cargo.toml new file mode 100644 index 00000000..634ed3cf --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "bssl-sys" +version = "0.1.0" +authors = ["Benjamin Brittain "] +edition = "2018" +publish = false +license = "MIT" diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/README.md b/third_party/boringssl/kit/src/rust/bssl-sys/README.md new file mode 100644 index 00000000..e2efd6c4 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/README.md @@ -0,0 +1,12 @@ +bssl-sys +============ + +A low-level binding crate for Rust that moves in lockstop with BoringSSL. BoringSSL explicitly does not have a stable ABI, `bssl-sys` is the solution for preventing subtle-memory corruption bugs due to version skew. + +### How it works +`bssl-sys` uses `bindgen` as part of the cmake build process to generate Rust compatibility shims for the targeted platform. It is important to generate it for the correct platform because `bindgen` uses LLVM information for alignment which varies depending on architecture. + +### To Use +Build `boringssl` with `-DRUST_BINDINGS=` and ensure that you have `bindgen` installed. The `rust-triple` option should match the [Rust target triple](https://doc.rust-lang.org/nightly/rustc/platform-support.html) when building `bssl-sys`. + +From there, the `bssl-sys` crate can be built. By default, it looks for `bindgen` output and BoringSSL static libraries in the `build` directory. This can be reconfigured with `BORINGSSL_BUILD_DIR` environment variable. Note the environment variable is evaluated relative to `rust/bssl-sys/src`, so using an absolute path may be more convenient. diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/build.rs b/third_party/boringssl/kit/src/rust/bssl-sys/build.rs new file mode 100644 index 00000000..2d7461ab --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/build.rs @@ -0,0 +1,57 @@ +/* Copyright (c) 2021, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +use std::env; +use std::path::Path; +use std::path::PathBuf; + +fn get_bssl_build_dir() -> PathBuf { + println!("cargo:rerun-if-env-changed=BORINGSSL_BUILD_DIR"); + if let Some(build_dir) = env::var_os("BORINGSSL_BUILD_DIR") { + return PathBuf::from(build_dir); + } + + let crate_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); + return Path::new(&crate_dir).join("../../build"); +} + +fn main() { + let bssl_build_dir = get_bssl_build_dir(); + let bssl_sys_build_dir = bssl_build_dir.join("rust/bssl-sys"); + let target = env::var("TARGET").unwrap(); + + // Find the bindgen generated target platform bindings file and set BINDGEN_RS_FILE + let bindgen_file = bssl_sys_build_dir.join(format!("wrapper_{}.rs", target)); + println!("cargo:rustc-env=BINDGEN_RS_FILE={}", bindgen_file.display()); + + // Statically link libraries. + println!( + "cargo:rustc-link-search=native={}", + bssl_build_dir.join("crypto").display() + ); + println!("cargo:rustc-link-lib=static=crypto"); + + println!( + "cargo:rustc-link-search=native={}", + bssl_build_dir.join("ssl").display() + ); + println!("cargo:rustc-link-lib=static=ssl"); + + println!( + "cargo:rustc-link-search=native={}", + bssl_sys_build_dir.display() + ); + println!("cargo:rustc-link-lib=static=rust_wrapper"); +} diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.c b/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.c new file mode 100644 index 00000000..d5419a9a --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.c @@ -0,0 +1,28 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "rust_wrapper.h" + + +int ERR_GET_LIB_RUST(uint32_t packed_error) { + return ERR_GET_LIB(packed_error); +} + +int ERR_GET_REASON_RUST(uint32_t packed_error) { + return ERR_GET_REASON(packed_error); +} + +int ERR_GET_FUNC_RUST(uint32_t packed_error) { + return ERR_GET_FUNC(packed_error); +} diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.h b/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.h new file mode 100644 index 00000000..632622a9 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/rust_wrapper.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2022, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_RUST_WRAPPER_H +#define OPENSSL_HEADER_RUST_WRAPPER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The following functions are wrappers over inline functions and macros in +// BoringSSL, which bindgen cannot currently correctly bind. These wrappers +// ensure changes to the functions remain in lockstep with the Rust versions. +int ERR_GET_LIB_RUST(uint32_t packed_error); +int ERR_GET_REASON_RUST(uint32_t packed_error); +int ERR_GET_FUNC_RUST(uint32_t packed_error); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RUST_WRAPPER_H diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/src/lib.rs b/third_party/boringssl/kit/src/rust/bssl-sys/src/lib.rs new file mode 100644 index 00000000..51ba2cf3 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/src/lib.rs @@ -0,0 +1,24 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +// Set in build.rs +include!(env!("BINDGEN_RS_FILE")); + +pub fn ERR_GET_LIB(packed_error: u32) -> i32 { + unsafe { ERR_GET_LIB_RUST(packed_error) } +} + +pub fn ERR_GET_REASON(packed_error: u32) -> i32 { + unsafe { ERR_GET_REASON_RUST(packed_error) } +} + +pub fn ERR_GET_FUNC(packed_error: u32) -> i32 { + unsafe { ERR_GET_FUNC_RUST(packed_error) } +} + +pub fn init() { + unsafe { + CRYPTO_library_init(); + } +} diff --git a/third_party/boringssl/kit/src/rust/bssl-sys/wrapper.h b/third_party/boringssl/kit/src/rust/bssl-sys/wrapper.h new file mode 100644 index 00000000..bd740495 --- /dev/null +++ b/third_party/boringssl/kit/src/rust/bssl-sys/wrapper.h @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rust_wrapper.h" diff --git a/third_party/boringssl/kit/src/sources.cmake b/third_party/boringssl/kit/src/sources.cmake index 3d3465f1..5c7e881b 100644 --- a/third_party/boringssl/kit/src/sources.cmake +++ b/third_party/boringssl/kit/src/sources.cmake @@ -11,6 +11,7 @@ set( crypto/cipher_extra/test/aes_128_cbc_sha1_tls_tests.txt crypto/cipher_extra/test/aes_128_ccm_bluetooth_tests.txt crypto/cipher_extra/test/aes_128_ccm_bluetooth_8_tests.txt + crypto/cipher_extra/test/aes_128_ccm_matter_tests.txt crypto/cipher_extra/test/aes_128_ctr_hmac_sha256.txt crypto/cipher_extra/test/aes_128_gcm_randnonce_tests.txt crypto/cipher_extra/test/aes_128_gcm_siv_tests.txt @@ -38,24 +39,35 @@ set( crypto/cipher_extra/test/nist_cavp/tdes_cbc.txt crypto/cipher_extra/test/nist_cavp/tdes_ecb.txt crypto/curve25519/ed25519_tests.txt - crypto/cmac/cavp_3des_cmac_tests.txt - crypto/cmac/cavp_aes128_cmac_tests.txt - crypto/cmac/cavp_aes192_cmac_tests.txt - crypto/cmac/cavp_aes256_cmac_tests.txt crypto/ecdh_extra/ecdh_tests.txt crypto/evp/evp_tests.txt crypto/evp/scrypt_tests.txt crypto/fipsmodule/aes/aes_tests.txt - crypto/fipsmodule/bn/bn_tests.txt - crypto/fipsmodule/bn/miller_rabin_tests.txt + crypto/fipsmodule/bn/test/exp_tests.txt + crypto/fipsmodule/bn/test/gcd_tests.txt + crypto/fipsmodule/bn/test/miller_rabin_tests.txt + crypto/fipsmodule/bn/test/mod_exp_tests.txt + crypto/fipsmodule/bn/test/mod_inv_tests.txt + crypto/fipsmodule/bn/test/mod_mul_tests.txt + crypto/fipsmodule/bn/test/mod_sqrt_tests.txt + crypto/fipsmodule/bn/test/product_tests.txt + crypto/fipsmodule/bn/test/quotient_tests.txt + crypto/fipsmodule/bn/test/shift_tests.txt + crypto/fipsmodule/bn/test/sum_tests.txt + crypto/fipsmodule/cmac/cavp_3des_cmac_tests.txt + crypto/fipsmodule/cmac/cavp_aes128_cmac_tests.txt + crypto/fipsmodule/cmac/cavp_aes192_cmac_tests.txt + crypto/fipsmodule/cmac/cavp_aes256_cmac_tests.txt crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt - crypto/fipsmodule/ec/p256-x86_64_tests.txt + crypto/fipsmodule/ec/p256-nistz_tests.txt crypto/fipsmodule/ecdsa/ecdsa_sign_tests.txt crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt crypto/fipsmodule/modes/gcm_tests.txt crypto/fipsmodule/rand/ctrdrbg_vectors.txt crypto/hmac_extra/hmac_tests.txt crypto/hpke/hpke_test_vectors.txt + crypto/kyber/keccak_tests.txt + crypto/kyber/kyber_tests.txt crypto/pkcs8/test/empty_password.p12 crypto/pkcs8/test/no_encryption.p12 crypto/pkcs8/test/nss.p12 @@ -101,6 +113,48 @@ set( crypto/x509/test/many_names1.pem crypto/x509/test/many_names2.pem crypto/x509/test/many_names3.pem + crypto/x509/test/policy_intermediate_any.pem + crypto/x509/test/policy_intermediate_duplicate.pem + crypto/x509/test/policy_intermediate_invalid.pem + crypto/x509/test/policy_intermediate_mapped_any.pem + crypto/x509/test/policy_intermediate_mapped_oid3.pem + crypto/x509/test/policy_intermediate_mapped.pem + crypto/x509/test/policy_intermediate_require_duplicate.pem + crypto/x509/test/policy_intermediate_require_no_policies.pem + crypto/x509/test/policy_intermediate_require.pem + crypto/x509/test/policy_intermediate_require1.pem + crypto/x509/test/policy_intermediate_require2.pem + crypto/x509/test/policy_intermediate.pem + crypto/x509/test/policy_leaf_any.pem + crypto/x509/test/policy_leaf_duplicate.pem + crypto/x509/test/policy_leaf_invalid.pem + crypto/x509/test/policy_leaf_none.pem + crypto/x509/test/policy_leaf_oid1.pem + crypto/x509/test/policy_leaf_oid2.pem + crypto/x509/test/policy_leaf_oid3.pem + crypto/x509/test/policy_leaf_oid4.pem + crypto/x509/test/policy_leaf_oid5.pem + crypto/x509/test/policy_leaf_require.pem + crypto/x509/test/policy_leaf_require1.pem + crypto/x509/test/policy_leaf.pem + crypto/x509/test/policy_root_cross_inhibit_mapping.pem + crypto/x509/test/policy_root.pem + crypto/x509/test/policy_root2.pem + crypto/x509/test/pss_sha1_explicit.pem + crypto/x509/test/pss_sha1_mgf1_syntax_error.pem + crypto/x509/test/pss_sha1.pem + crypto/x509/test/pss_sha224.pem + crypto/x509/test/pss_sha256_explicit_trailer.pem + crypto/x509/test/pss_sha256_mgf1_sha384.pem + crypto/x509/test/pss_sha256_mgf1_syntax_error.pem + crypto/x509/test/pss_sha256_omit_nulls.pem + crypto/x509/test/pss_sha256_salt_overflow.pem + crypto/x509/test/pss_sha256_salt31.pem + crypto/x509/test/pss_sha256_unknown_mgf.pem + crypto/x509/test/pss_sha256_wrong_trailer.pem + crypto/x509/test/pss_sha256.pem + crypto/x509/test/pss_sha384.pem + crypto/x509/test/pss_sha512.pem crypto/x509/test/some_names1.pem crypto/x509/test/some_names2.pem crypto/x509/test/some_names3.pem diff --git a/third_party/boringssl/kit/src/ssl/CMakeLists.txt b/third_party/boringssl/kit/src/ssl/CMakeLists.txt index 4f4abf8a..d8d997e3 100644 --- a/third_party/boringssl/kit/src/ssl/CMakeLists.txt +++ b/third_party/boringssl/kit/src/ssl/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(../include) - add_library( ssl @@ -41,9 +39,11 @@ add_library( tls13_enc.cc tls13_server.cc ) - -add_dependencies(ssl global_target) - +# Although libssl also provides headers that require an include directory, the +# flag is already specified by libcrypto, so we omit target_include_directories +# here. +install_if_enabled(TARGETS ssl EXPORT OpenSSLTargets ${INSTALL_DESTINATION_DEFAULT}) +set_property(TARGET ssl PROPERTY EXPORT_NAME SSL) target_link_libraries(ssl crypto) add_executable( @@ -52,14 +52,6 @@ add_executable( span_test.cc ssl_test.cc ssl_c_test.c - - $ ) - -add_dependencies(ssl_test global_target) - -target_link_libraries(ssl_test test_support_lib boringssl_gtest ssl crypto) -if(WIN32) - target_link_libraries(ssl_test ws2_32) -endif() +target_link_libraries(ssl_test test_support_lib boringssl_gtest_main ssl crypto) add_dependencies(all_tests ssl_test) diff --git a/third_party/boringssl/kit/src/ssl/bio_ssl.cc b/third_party/boringssl/kit/src/ssl/bio_ssl.cc index a2498893..fe834507 100644 --- a/third_party/boringssl/kit/src/ssl/bio_ssl.cc +++ b/third_party/boringssl/kit/src/ssl/bio_ssl.cc @@ -109,7 +109,7 @@ static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { // |bio->next_bio| with |ssl|'s rbio here, and on |BIO_CTRL_PUSH|. We call // into the corresponding |BIO| directly. (We can implement the upstream // behavior if it ends up necessary.) - bio->shutdown = num; + bio->shutdown = static_cast(num); bio->ptr = ptr; bio->init = 1; return 1; @@ -118,7 +118,7 @@ static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { return bio->shutdown; case BIO_CTRL_SET_CLOSE: - bio->shutdown = num; + bio->shutdown = static_cast(num); return 1; case BIO_CTRL_WPENDING: diff --git a/third_party/boringssl/kit/src/ssl/d1_both.cc b/third_party/boringssl/kit/src/ssl/d1_both.cc index f8c04b74..55c92fad 100644 --- a/third_party/boringssl/kit/src/ssl/d1_both.cc +++ b/third_party/boringssl/kit/src/ssl/d1_both.cc @@ -163,7 +163,6 @@ static UniquePtr dtls1_hm_fragment_new( frag->data = (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len); if (frag->data == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -174,7 +173,6 @@ static UniquePtr dtls1_hm_fragment_new( !CBB_add_u24(cbb.get(), 0 /* frag_off */) || !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || !CBB_finish(cbb.get(), NULL, NULL)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -188,7 +186,6 @@ static UniquePtr dtls1_hm_fragment_new( size_t bitmask_len = (msg_hdr->msg_len + 7) / 8; frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len); if (frag->reassembly == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } OPENSSL_memset(frag->reassembly, 0, bitmask_len); @@ -487,10 +484,7 @@ ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, // Sending handshake messages. -void DTLS_OUTGOING_MESSAGE::Clear() { - OPENSSL_free(data); - data = nullptr; -} +void DTLS_OUTGOING_MESSAGE::Clear() { data.Reset(); } void dtls_clear_outgoing_messages(SSL *ssl) { for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) { @@ -578,9 +572,7 @@ static bool add_outgoing(SSL *ssl, bool is_ccs, Array data) { DTLS_OUTGOING_MESSAGE *msg = &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len]; - size_t len; - data.Release(&msg->data, &len); - msg->len = len; + msg->data = std::move(data); msg->epoch = ssl->d1->w_epoch; msg->is_ccs = is_ccs; @@ -665,7 +657,7 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, // DTLS messages are serialized as a single fragment in |msg|. CBS cbs, body; struct hm_header_st hdr; - CBS_init(&cbs, msg->data, msg->len); + CBS_init(&cbs, msg->data.data(), msg->data.size()); if (!dtls1_parse_fragment(&cbs, &hdr, &body) || hdr.frag_off != 0 || hdr.frag_len != CBS_len(&body) || @@ -687,6 +679,7 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, // Assemble a fragment, to be sealed in-place. ScopedCBB cbb; + CBB child; uint8_t *frag = out + prefix; size_t max_frag = max_out - prefix, frag_len; if (!CBB_init_fixed(cbb.get(), frag, max_frag) || @@ -694,8 +687,8 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, !CBB_add_u24(cbb.get(), hdr.msg_len) || !CBB_add_u16(cbb.get(), hdr.seq) || !CBB_add_u24(cbb.get(), ssl->d1->outgoing_offset) || - !CBB_add_u24(cbb.get(), todo) || - !CBB_add_bytes(cbb.get(), CBS_data(&body), todo) || + !CBB_add_u24_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, CBS_data(&body), todo) || !CBB_finish(cbb.get(), NULL, &frag_len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return seal_error; diff --git a/third_party/boringssl/kit/src/ssl/d1_pkt.cc b/third_party/boringssl/kit/src/ssl/d1_pkt.cc index b9b0ef93..b8661562 100644 --- a/third_party/boringssl/kit/src/ssl/d1_pkt.cc +++ b/third_party/boringssl/kit/src/ssl/d1_pkt.cc @@ -186,8 +186,8 @@ ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, return ssl_open_record_success; } -int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, - int len) { +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, + size_t *out_bytes_written, Span in) { assert(!SSL_in_init(ssl)); *out_needs_handshake = false; @@ -196,47 +196,46 @@ int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, return -1; } - if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + // DTLS does not split the input across records. + if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH) { OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); return -1; } - if (len < 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); - return -1; + if (in.empty()) { + *out_bytes_written = 0; + return 1; } - if (len == 0) { - return 0; - } - - int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, (size_t)len, + int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, dtls1_use_current_epoch); if (ret <= 0) { return ret; } - return len; + *out_bytes_written = in.size(); + return 1; } -int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, +int dtls1_write_record(SSL *ssl, int type, Span in, enum dtls1_use_epoch_t use_epoch) { SSLBuffer *buf = &ssl->s3->write_buffer; - assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + assert(in.size() <= SSL3_RT_MAX_PLAIN_LENGTH); // There should never be a pending write buffer in DTLS. One can't write half // a datagram, so the write buffer is always dropped in // |ssl_write_buffer_flush|. assert(buf->empty()); - if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } size_t ciphertext_len; if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl), - len + SSL_max_seal_overhead(ssl)) || + in.size() + SSL_max_seal_overhead(ssl)) || !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, - buf->remaining().size(), type, in, len, use_epoch)) { + buf->remaining().size(), type, in.data(), in.size(), + use_epoch)) { buf->Clear(); return -1; } @@ -250,7 +249,7 @@ int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, } int dtls1_dispatch_alert(SSL *ssl) { - int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2, + int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, ssl->s3->send_alert, dtls1_use_current_epoch); if (ret <= 0) { return ret; diff --git a/third_party/boringssl/kit/src/ssl/dtls_method.cc b/third_party/boringssl/kit/src/ssl/dtls_method.cc index d179baef..677418b8 100644 --- a/third_party/boringssl/kit/src/ssl/dtls_method.cc +++ b/third_party/boringssl/kit/src/ssl/dtls_method.cc @@ -90,11 +90,11 @@ static bool dtls1_set_read_state(SSL *ssl, ssl_encryption_level_t level, ssl->d1->r_epoch++; OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap)); - OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + ssl->s3->read_sequence = 0; ssl->s3->aead_read_ctx = std::move(aead_ctx); ssl->s3->read_level = level; - ssl->d1->has_change_cipher_spec = 0; + ssl->d1->has_change_cipher_spec = false; return true; } @@ -103,9 +103,8 @@ static bool dtls1_set_write_state(SSL *ssl, ssl_encryption_level_t level, Span secret_for_quic) { assert(secret_for_quic.empty()); // QUIC does not use DTLS. ssl->d1->w_epoch++; - OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence, - sizeof(ssl->s3->write_sequence)); - OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + ssl->d1->last_write_sequence = ssl->s3->write_sequence; + ssl->s3->write_sequence = 0; ssl->d1->last_aead_write_ctx = std::move(ssl->s3->aead_write_ctx); ssl->s3->aead_write_ctx = std::move(aead_ctx); diff --git a/third_party/boringssl/kit/src/ssl/dtls_record.cc b/third_party/boringssl/kit/src/ssl/dtls_record.cc index 992fb526..eb3df696 100644 --- a/third_party/boringssl/kit/src/ssl/dtls_record.cc +++ b/third_party/boringssl/kit/src/ssl/dtls_record.cc @@ -123,52 +123,37 @@ BSSL_NAMESPACE_BEGIN -// to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as -// a |uint64_t|. -static uint64_t to_u64_be(const uint8_t in[8]) { - uint64_t ret = 0; - unsigned i; - for (i = 0; i < 8; i++) { - ret <<= 8; - ret |= in[i]; - } - return ret; -} - // dtls1_bitmap_should_discard returns one if |seq_num| has been seen in // |bitmap| or is stale. Otherwise it returns zero. static bool dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, - const uint8_t seq_num[8]) { + uint64_t seq_num) { const unsigned kWindowSize = sizeof(bitmap->map) * 8; - uint64_t seq_num_u = to_u64_be(seq_num); - if (seq_num_u > bitmap->max_seq_num) { + if (seq_num > bitmap->max_seq_num) { return false; } - uint64_t idx = bitmap->max_seq_num - seq_num_u; + uint64_t idx = bitmap->max_seq_num - seq_num; return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx)); } // dtls1_bitmap_record updates |bitmap| to record receipt of sequence number // |seq_num|. It slides the window forward if needed. It is an error to call // this function on a stale sequence number. -static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, - const uint8_t seq_num[8]) { +static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, uint64_t seq_num) { const unsigned kWindowSize = sizeof(bitmap->map) * 8; - uint64_t seq_num_u = to_u64_be(seq_num); // Shift the window if necessary. - if (seq_num_u > bitmap->max_seq_num) { - uint64_t shift = seq_num_u - bitmap->max_seq_num; + if (seq_num > bitmap->max_seq_num) { + uint64_t shift = seq_num - bitmap->max_seq_num; if (shift >= kWindowSize) { bitmap->map = 0; } else { bitmap->map <<= shift; } - bitmap->max_seq_num = seq_num_u; + bitmap->max_seq_num = seq_num; } - uint64_t idx = bitmap->max_seq_num - seq_num_u; + uint64_t idx = bitmap->max_seq_num - seq_num; if (idx < kWindowSize) { bitmap->map |= ((uint64_t)1) << idx; } @@ -192,11 +177,11 @@ enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, // Decode the record. uint8_t type; uint16_t version; - uint8_t sequence[8]; + uint8_t sequence_bytes[8]; CBS body; if (!CBS_get_u8(&cbs, &type) || !CBS_get_u16(&cbs, &version) || - !CBS_copy_bytes(&cbs, sequence, 8) || + !CBS_copy_bytes(&cbs, sequence_bytes, sizeof(sequence_bytes)) || !CBS_get_u16_length_prefixed(&cbs, &body) || CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { // The record header was incomplete or malformed. Drop the entire packet. @@ -222,7 +207,8 @@ enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, Span header = in.subspan(0, DTLS1_RT_HEADER_LENGTH); ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header); - uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1]; + uint64_t sequence = CRYPTO_load_u64_be(sequence_bytes); + uint16_t epoch = static_cast(sequence >> 48); if (epoch != ssl->d1->r_epoch || dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) { // Drop this record. It's from the wrong epoch or is a replay. Note that if @@ -304,12 +290,12 @@ bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, // Determine the parameters for the current epoch. uint16_t epoch = ssl->d1->w_epoch; SSLAEADContext *aead = ssl->s3->aead_write_ctx.get(); - uint8_t *seq = ssl->s3->write_sequence; + uint64_t *seq = &ssl->s3->write_sequence; if (use_epoch == dtls1_use_previous_epoch) { assert(ssl->d1->w_epoch >= 1); epoch = ssl->d1->w_epoch - 1; aead = ssl->d1->last_aead_write_ctx.get(); - seq = ssl->d1->last_write_sequence; + seq = &ssl->d1->last_write_sequence; } if (max_out < DTLS1_RT_HEADER_LENGTH) { @@ -323,9 +309,15 @@ bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, out[1] = record_version >> 8; out[2] = record_version & 0xff; - out[3] = epoch >> 8; - out[4] = epoch & 0xff; - OPENSSL_memcpy(&out[5], &seq[2], 6); + // Ensure the sequence number update does not overflow. + const uint64_t kMaxSequenceNumber = (uint64_t{1} << 48) - 1; + if (*seq + 1 > kMaxSequenceNumber) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + + uint64_t seq_with_epoch = (uint64_t{epoch} << 48) | *seq; + CRYPTO_store_u64_be(&out[3], seq_with_epoch); size_t ciphertext_len; if (!aead->CiphertextLen(&ciphertext_len, in_len, 0)) { @@ -339,12 +331,12 @@ bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, size_t len_copy; if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &len_copy, max_out - DTLS1_RT_HEADER_LENGTH, type, record_version, - &out[3] /* seq */, header, in, in_len) || - !ssl_record_sequence_update(&seq[2], 6)) { + seq_with_epoch, header, in, in_len)) { return false; } assert(ciphertext_len == len_copy); + (*seq)++; *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len; ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header); return true; diff --git a/third_party/boringssl/kit/src/ssl/encrypted_client_hello.cc b/third_party/boringssl/kit/src/ssl/encrypted_client_hello.cc index 64fee3d0..a5492e9a 100644 --- a/third_party/boringssl/kit/src/ssl/encrypted_client_hello.cc +++ b/third_party/boringssl/kit/src/ssl/encrypted_client_hello.cc @@ -203,6 +203,12 @@ bool ssl_decode_client_hello_inner( OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return false; } + // The ECH extension itself is not in the AAD and may not be referenced. + if (want == TLSEXT_TYPE_encrypted_client_hello) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION); + return false; + } // Seek to |want| in |outer_extensions|. |ext_list| is required to match // ClientHelloOuter in order. uint16_t found; @@ -210,7 +216,7 @@ bool ssl_decode_client_hello_inner( do { if (CBS_len(&outer_extensions) == 0) { *out_alert = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, SSL_R_OUTER_EXTENSION_NOT_FOUND); + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION); return false; } if (!CBS_get_u16(&outer_extensions, &found) || @@ -252,8 +258,8 @@ bool ssl_decode_client_hello_inner( return true; } -bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array *out, - bool *out_is_decrypt_error, +bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert, + bool *out_is_decrypt_error, Array *out, const SSL_CLIENT_HELLO *client_hello_outer, Span payload) { *out_is_decrypt_error = false; @@ -264,6 +270,7 @@ bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array *out, Array aad; if (!aad.CopyFrom(MakeConstSpan(client_hello_outer->client_hello, client_hello_outer->client_hello_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; return false; } @@ -278,35 +285,47 @@ bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array *out, payload.data() - client_hello_outer->client_hello, payload.size()); OPENSSL_memset(payload_aad.data(), 0, payload_aad.size()); + // Decrypt the EncodedClientHelloInner. + Array encoded; #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) // In fuzzer mode, disable encryption to improve coverage. We reserve a short // input to signal decryption failure, so the fuzzer can explore fallback to // ClientHelloOuter. const uint8_t kBadPayload[] = {0xff}; if (payload == kBadPayload) { + *out_alert = SSL_AD_DECRYPT_ERROR; *out_is_decrypt_error = true; OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); return false; } - if (!out->CopyFrom(payload)) { + if (!encoded.CopyFrom(payload)) { + *out_alert = SSL_AD_INTERNAL_ERROR; return false; } #else - // Attempt to decrypt into |out|. - if (!out->Init(payload.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + if (!encoded.Init(payload.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; return false; } size_t len; - if (!EVP_HPKE_CTX_open(hpke_ctx, out->data(), &len, out->size(), - payload.data(), payload.size(), aad.data(), - aad.size())) { + if (!EVP_HPKE_CTX_open(hs->ech_hpke_ctx.get(), encoded.data(), &len, + encoded.size(), payload.data(), payload.size(), + aad.data(), aad.size())) { + *out_alert = SSL_AD_DECRYPT_ERROR; *out_is_decrypt_error = true; OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); return false; } - out->Shrink(len); + encoded.Shrink(len); #endif + + if (!ssl_decode_client_hello_inner(hs->ssl, out_alert, out, encoded, + client_hello_outer)) { + return false; + } + + ssl_do_msg_callback(hs->ssl, /*is_write=*/0, SSL3_RT_CLIENT_HELLO_INNER, + *out); return true; } @@ -315,8 +334,7 @@ static bool is_hex_component(Span in) { return false; } for (uint8_t b : in.subspan(2)) { - if (!('0' <= b && b <= '9') && !('a' <= b && b <= 'f') && - !('A' <= b && b <= 'F')) { + if (!OPENSSL_isxdigit(b)) { return false; } } @@ -368,8 +386,7 @@ bool ssl_is_valid_ech_public_name(Span public_name) { return false; } for (uint8_t c : component) { - if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && - !('0' <= c && c <= '9') && c != '-') { + if (!OPENSSL_isalnum(c) && c != '-') { return false; } } @@ -554,7 +571,6 @@ bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, sizeof(kInfoLabel) /* includes trailing NUL */) || !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(), ech_config_.raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -585,8 +601,8 @@ bool ssl_is_valid_ech_config_list(Span ech_config_list) { static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf, const EVP_HPKE_AEAD **out_aead, - Span cipher_suites) { - const bool has_aes_hardware = EVP_has_aes_hardware(); + Span cipher_suites, + const bool has_aes_hardware) { const EVP_HPKE_AEAD *aead = nullptr; CBS cbs = cipher_suites; while (CBS_len(&cbs) != 0) { @@ -644,14 +660,16 @@ bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span out_enc, const EVP_HPKE_AEAD *aead; if (supported && // ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 && - select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites)) { + select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites, + hs->ssl->config->aes_hw_override + ? hs->ssl->config->aes_hw_override_value + : EVP_has_aes_hardware())) { ScopedCBB info; static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) || !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) || !CBB_add_bytes(info.get(), ech_config.raw.data(), ech_config.raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -699,9 +717,11 @@ static bool setup_ech_grease(SSL_HANDSHAKE *hs) { } const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256; - const EVP_HPKE_AEAD *aead = EVP_has_aes_hardware() - ? EVP_hpke_aes_128_gcm() - : EVP_hpke_chacha20_poly1305(); + const bool has_aes_hw = hs->ssl->config->aes_hw_override + ? hs->ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + const EVP_HPKE_AEAD *aead = + has_aes_hw ? EVP_hpke_aes_128_gcm() : EVP_hpke_chacha20_poly1305(); static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed), "hs->grease_seed is too small"); uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id]; @@ -789,6 +809,8 @@ bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span enc) { binder_len); } + ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_CLIENT_HELLO_INNER, + hello_inner); if (!hs->inner_transcript.Update(hello_inner)) { return false; } @@ -1017,7 +1039,6 @@ int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config, return 0; } if (!configs->configs.Push(std::move(parsed_config))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -1040,14 +1061,12 @@ int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out, CBB child; if (!CBB_init(cbb.get(), 128) || !CBB_add_u16_length_prefixed(cbb.get(), &child)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } for (const auto &config : keys->configs) { if (config->is_retry_config() && !CBB_add_bytes(&child, config->ech_config().raw.data(), config->ech_config().raw.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } diff --git a/third_party/boringssl/kit/src/ssl/extensions.cc b/third_party/boringssl/kit/src/ssl/extensions.cc index 3baef6d8..c5b1ed14 100644 --- a/third_party/boringssl/kit/src/ssl/extensions.cc +++ b/third_party/boringssl/kit/src/ssl/extensions.cc @@ -205,7 +205,12 @@ static bool tls1_check_duplicate_extensions(const CBS *cbs) { } static bool is_post_quantum_group(uint16_t id) { - return id == SSL_CURVE_CECPQ2; + switch (id) { + case SSL_GROUP_X25519_KYBER768_DRAFT00: + return true; + default: + return false; + } } bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, @@ -240,8 +245,7 @@ bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, // Skip past DTLS cookie if (SSL_is_dtls(out->ssl)) { CBS cookie; - if (!CBS_get_u8_length_prefixed(cbs, &cookie) || - CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) { + if (!CBS_get_u8_length_prefixed(cbs, &cookie)) { return false; } } @@ -303,9 +307,9 @@ bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, } static const uint16_t kDefaultGroups[] = { - SSL_CURVE_X25519, - SSL_CURVE_SECP256R1, - SSL_CURVE_SECP384R1, + SSL_GROUP_X25519, + SSL_GROUP_SECP256R1, + SSL_GROUP_SECP384R1, }; Span tls1_get_grouplist(const SSL_HANDSHAKE *hs) { @@ -341,8 +345,8 @@ bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { for (uint16_t pref_group : pref) { for (uint16_t supp_group : supp) { if (pref_group == supp_group && - // CECPQ2(b) doesn't fit in the u8-length-prefixed ECPoint field in - // TLS 1.2 and below. + // Post-quantum key agreements don't fit in the u8-length-prefixed + // ECPoint field in TLS 1.2 and below. (ssl_protocol_version(ssl) >= TLS1_3_VERSION || !is_post_quantum_group(pref_group))) { *out_group_id = pref_group; @@ -354,61 +358,10 @@ bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { return false; } -bool tls1_set_curves(Array *out_group_ids, Span curves) { - Array group_ids; - if (!group_ids.Init(curves.size())) { - return false; - } - - for (size_t i = 0; i < curves.size(); i++) { - if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) { - return false; - } - } - - *out_group_ids = std::move(group_ids); - return true; -} - -bool tls1_set_curves_list(Array *out_group_ids, const char *curves) { - // Count the number of curves in the list. - size_t count = 0; - const char *ptr = curves, *col; - do { - col = strchr(ptr, ':'); - count++; - if (col) { - ptr = col + 1; - } - } while (col); - - Array group_ids; - if (!group_ids.Init(count)) { - return false; - } - - size_t i = 0; - ptr = curves; - do { - col = strchr(ptr, ':'); - if (!ssl_name_to_group_id(&group_ids[i++], ptr, - col ? (size_t)(col - ptr) : strlen(ptr))) { - return false; - } - if (col) { - ptr = col + 1; - } - } while (col); - - assert(i == count); - *out_group_ids = std::move(group_ids); - return true; -} - bool tls1_check_group_id(const SSL_HANDSHAKE *hs, uint16_t group_id) { if (is_post_quantum_group(group_id) && ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) { - // CECPQ2(b) requires TLS 1.3. + // Post-quantum "groups" require TLS 1.3. return false; } @@ -1249,10 +1202,12 @@ static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, } } + // |orig_len| fits in |unsigned| because TLS extensions use 16-bit lengths. uint8_t *selected; uint8_t selected_len; if (ssl->ctx->next_proto_select_cb( - ssl, &selected, &selected_len, orig_contents, orig_len, + ssl, &selected, &selected_len, orig_contents, + static_cast(orig_len), ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK || !ssl->s3->next_proto_negotiated.CopyFrom( MakeConstSpan(selected, selected_len))) { @@ -1565,11 +1520,14 @@ bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, return false; } + // |protocol_name_list| fits in |unsigned| because TLS extensions use 16-bit + // lengths. const uint8_t *selected; uint8_t selected_len; int ret = ssl->ctx->alpn_select_cb( ssl, &selected, &selected_len, CBS_data(&protocol_name_list), - CBS_len(&protocol_name_list), ssl->ctx->alpn_select_cb_arg); + static_cast(CBS_len(&protocol_name_list)), + ssl->ctx->alpn_select_cb_arg); // ALPN is required when QUIC is used. if (ssl->quic_method && (ret == SSL_TLSEXT_ERR_NOACK || ret == SSL_TLSEXT_ERR_ALERT_WARNING)) { @@ -2296,11 +2254,13 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { group_id = groups[0]; - if (is_post_quantum_group(group_id) && groups.size() >= 2) { - // CECPQ2(b) is not sent as the only initial key share. We'll include the - // 2nd preference group too to avoid round-trips. - second_group_id = groups[1]; - assert(second_group_id != group_id); + // We'll try to include one post-quantum and one classical initial key + // share. + for (size_t i = 1; i < groups.size() && second_group_id == 0; i++) { + if (is_post_quantum_group(group_id) != is_post_quantum_group(groups[i])) { + second_group_id = groups[i]; + assert(second_group_id != group_id); + } } } @@ -2309,7 +2269,7 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { if (!hs->key_shares[0] || // !CBB_add_u16(cbb.get(), group_id) || !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || - !hs->key_shares[0]->Offer(&key_exchange)) { + !hs->key_shares[0]->Generate(&key_exchange)) { return false; } @@ -2318,7 +2278,7 @@ bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) { if (!hs->key_shares[1] || // !CBB_add_u16(cbb.get(), second_group_id) || !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) || - !hs->key_shares[1]->Offer(&key_exchange)) { + !hs->key_shares[1]->Generate(&key_exchange)) { return false; } } @@ -2350,10 +2310,10 @@ static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out, bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, Array *out_secret, uint8_t *out_alert, CBS *contents) { - CBS peer_key; + CBS ciphertext; uint16_t group_id; if (!CBS_get_u16(contents, &group_id) || - !CBS_get_u16_length_prefixed(contents, &peer_key) || + !CBS_get_u16_length_prefixed(contents, &ciphertext) || CBS_len(contents) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); *out_alert = SSL_AD_DECODE_ERROR; @@ -2370,7 +2330,7 @@ bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, key_share = hs->key_shares[1].get(); } - if (!key_share->Finish(out_secret, out_alert, peer_key)) { + if (!key_share->Decap(out_secret, out_alert, ciphertext)) { *out_alert = SSL_AD_INTERNAL_ERROR; return false; } @@ -2435,13 +2395,13 @@ bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, } bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { - CBB kse_bytes, public_key; + CBB entry, ciphertext; if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || - !CBB_add_u16_length_prefixed(out, &kse_bytes) || - !CBB_add_u16(&kse_bytes, hs->new_session->group_id) || - !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || - !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(), - hs->ecdh_public_key.size()) || + !CBB_add_u16_length_prefixed(out, &entry) || + !CBB_add_u16(&entry, hs->new_session->group_id) || + !CBB_add_u16_length_prefixed(&entry, &ciphertext) || + !CBB_add_bytes(&ciphertext, hs->key_share_ciphertext.data(), + hs->key_share_ciphertext.size()) || !CBB_flush(out)) { return false; } @@ -2581,7 +2541,7 @@ static bool parse_u16_array(const CBS *cbs, Array *out) { assert(CBS_len(©) == 0); *out = std::move(ret); - return 1; + return true; } static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs, @@ -3931,7 +3891,6 @@ static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method( Span ticket) { Array plaintext; if (!plaintext.Init(ticket.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_ticket_aead_error; } @@ -3976,6 +3935,16 @@ enum ssl_ticket_aead_result_t ssl_process_ticket( : ssl_ticket_aead_error; } else if (is_psk && hints && !hs->hints_requested && hints->ignore_psk) { result = ssl_ticket_aead_ignore_ticket; + } else if (!is_psk && hints && !hs->hints_requested && + !hints->decrypted_ticket.empty()) { + if (plaintext.CopyFrom(hints->decrypted_ticket)) { + result = ssl_ticket_aead_success; + *out_renew_ticket = hints->renew_ticket; + } else { + result = ssl_ticket_aead_error; + } + } else if (!is_psk && hints && !hs->hints_requested && hints->ignore_ticket) { + result = ssl_ticket_aead_ignore_ticket; } else if (ssl->session_ctx->ticket_aead_method != NULL) { result = ssl_decrypt_ticket_with_method(hs, &plaintext, out_renew_ticket, ticket); @@ -3994,12 +3963,24 @@ enum ssl_ticket_aead_result_t ssl_process_ticket( } } - if (is_psk && hints && hs->hints_requested) { + if (hints && hs->hints_requested) { if (result == ssl_ticket_aead_ignore_ticket) { - hints->ignore_psk = true; - } else if (result == ssl_ticket_aead_success && - !hints->decrypted_psk.CopyFrom(plaintext)) { - return ssl_ticket_aead_error; + if (is_psk) { + hints->ignore_psk = true; + } else { + hints->ignore_ticket = true; + } + } else if (result == ssl_ticket_aead_success) { + if (is_psk) { + if (!hints->decrypted_psk.CopyFrom(plaintext)) { + return ssl_ticket_aead_error; + } + } else { + if (!hints->decrypted_ticket.CopyFrom(plaintext)) { + return ssl_ticket_aead_error; + } + hints->renew_ticket = *out_renew_ticket; + } } } @@ -4076,10 +4057,7 @@ bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) { Span peer_sigalgs = tls1_get_peer_verify_algorithms(hs); for (uint16_t sigalg : sigalgs) { - // SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be - // negotiated. - if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || - !ssl_private_key_supports_signature_algorithm(hs, sigalg)) { + if (!ssl_private_key_supports_signature_algorithm(hs, sigalg)) { continue; } diff --git a/third_party/boringssl/kit/src/ssl/handoff.cc b/third_party/boringssl/kit/src/ssl/handoff.cc index 883f832b..a4563c7e 100644 --- a/third_party/boringssl/kit/src/ssl/handoff.cc +++ b/third_party/boringssl/kit/src/ssl/handoff.cc @@ -17,6 +17,7 @@ #include #include +#include "../crypto/internal.h" #include "internal.h" @@ -25,7 +26,7 @@ BSSL_NAMESPACE_BEGIN constexpr int kHandoffVersion = 0; constexpr int kHandbackVersion = 0; -static const unsigned kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const CBS_ASN1_TAG kHandoffTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0; // early_data_t represents the state of early data in a more compact way than // the 3 bits used by the implementation. @@ -51,12 +52,12 @@ static bool serialize_features(CBB *out) { return false; } } - CBB curves; - if (!CBB_add_asn1(out, &curves, CBS_ASN1_OCTETSTRING)) { + CBB groups; + if (!CBB_add_asn1(out, &groups, CBS_ASN1_OCTETSTRING)) { return false; } for (const NamedGroup& g : NamedGroups()) { - if (!CBB_add_u16(&curves, g.group_id)) { + if (!CBB_add_u16(&groups, g.group_id)) { return false; } } @@ -123,6 +124,9 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { return false; } bssl::UniquePtr supported(sk_SSL_CIPHER_new_null()); + if (!supported) { + return false; + } while (CBS_len(&ciphers)) { uint16_t id; if (!CBS_get_u16(&ciphers, &id)) { @@ -140,6 +144,9 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() : ssl->ctx->cipher_list->ciphers.get(); bssl::UniquePtr unsupported(sk_SSL_CIPHER_new_null()); + if (!unsupported) { + return false; + } for (const SSL_CIPHER *configured_cipher : configured) { if (sk_SSL_CIPHER_find(supported.get(), nullptr, configured_cipher)) { continue; @@ -150,7 +157,8 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { } if (sk_SSL_CIPHER_num(unsupported.get()) && !ssl->config->cipher_list) { ssl->config->cipher_list = bssl::MakeUnique(); - if (!ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) { + if (!ssl->config->cipher_list || + !ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) { return false; } } @@ -161,46 +169,46 @@ static bool apply_remote_features(SSL *ssl, CBS *in) { return false; } - CBS curves; - if (!CBS_get_asn1(in, &curves, CBS_ASN1_OCTETSTRING)) { + CBS groups; + if (!CBS_get_asn1(in, &groups, CBS_ASN1_OCTETSTRING)) { return false; } - Array supported_curves; - if (!supported_curves.Init(CBS_len(&curves) / 2)) { + Array supported_groups; + if (!supported_groups.Init(CBS_len(&groups) / 2)) { return false; } size_t idx = 0; - while (CBS_len(&curves)) { - uint16_t curve; - if (!CBS_get_u16(&curves, &curve)) { + while (CBS_len(&groups)) { + uint16_t group; + if (!CBS_get_u16(&groups, &group)) { return false; } - supported_curves[idx++] = curve; + supported_groups[idx++] = group; } - Span configured_curves = + Span configured_groups = tls1_get_grouplist(ssl->s3->hs.get()); - Array new_configured_curves; - if (!new_configured_curves.Init(configured_curves.size())) { + Array new_configured_groups; + if (!new_configured_groups.Init(configured_groups.size())) { return false; } idx = 0; - for (uint16_t configured_curve : configured_curves) { + for (uint16_t configured_group : configured_groups) { bool ok = false; - for (uint16_t supported_curve : supported_curves) { - if (supported_curve == configured_curve) { + for (uint16_t supported_group : supported_groups) { + if (supported_group == configured_group) { ok = true; break; } } if (ok) { - new_configured_curves[idx++] = configured_curve; + new_configured_groups[idx++] = configured_group; } } if (idx == 0) { return false; } - new_configured_curves.Shrink(idx); - ssl->config->supported_group_list = std::move(new_configured_curves); + new_configured_groups.Shrink(idx); + ssl->config->supported_group_list = std::move(new_configured_groups); CBS alps; CBS_init(&alps, nullptr, 0); @@ -338,14 +346,16 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) { } else { session = s3->session_reused ? ssl->session.get() : hs->new_session.get(); } + uint8_t read_sequence[8], write_sequence[8]; + CRYPTO_store_u64_be(read_sequence, s3->read_sequence); + CRYPTO_store_u64_be(write_sequence, s3->write_sequence); static const uint8_t kUnusedChannelID[64] = {0}; if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&seq, kHandbackVersion) || !CBB_add_asn1_uint64(&seq, type) || - !CBB_add_asn1_octet_string(&seq, s3->read_sequence, - sizeof(s3->read_sequence)) || - !CBB_add_asn1_octet_string(&seq, s3->write_sequence, - sizeof(s3->write_sequence)) || + !CBB_add_asn1_octet_string(&seq, read_sequence, sizeof(read_sequence)) || + !CBB_add_asn1_octet_string(&seq, write_sequence, + sizeof(write_sequence)) || !CBB_add_asn1_octet_string(&seq, s3->server_random, sizeof(s3->server_random)) || !CBB_add_asn1_octet_string(&seq, s3->client_random, @@ -366,7 +376,7 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) { sizeof(kUnusedChannelID)) || // These two fields were historically |token_binding_negotiated| and // |negotiated_token_binding_param|. - !CBB_add_asn1_bool(&seq, 0) || + !CBB_add_asn1_bool(&seq, 0) || // !CBB_add_asn1_uint64(&seq, 0) || !CBB_add_asn1_bool(&seq, s3->hs->next_proto_neg_seen) || !CBB_add_asn1_bool(&seq, s3->hs->cert_request) || @@ -377,9 +387,14 @@ bool SSL_serialize_handback(const SSL *ssl, CBB *out) { !CBB_add_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) { return false; } - if (type == handback_after_ecdhe && - !s3->hs->key_shares[0]->Serialize(&key_share)) { - return false; + if (type == handback_after_ecdhe) { + CBB private_key; + if (!CBB_add_asn1_uint64(&key_share, s3->hs->key_shares[0]->GroupID()) || + !CBB_add_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING) || + !s3->hs->key_shares[0]->SerializePrivateKey(&private_key) || + !CBB_flush(&key_share)) { + return false; + } } if (type == handback_tls13) { early_data_t early_data; @@ -485,6 +500,9 @@ bool SSL_apply_handback(SSL *ssl, Span handback) { } s3->hs = ssl_handshake_new(ssl); + if (!s3->hs) { + return false; + } SSL_HANDSHAKE *const hs = s3->hs.get(); if (!session_reused || type == handback_tls13) { hs->new_session = @@ -694,14 +712,26 @@ bool SSL_apply_handback(SSL *ssl, Span handback) { } break; } - if (!CopyExact({s3->read_sequence, sizeof(s3->read_sequence)}, &read_seq) || - !CopyExact({s3->write_sequence, sizeof(s3->write_sequence)}, - &write_seq)) { + uint8_t read_sequence[8], write_sequence[8]; + if (!CopyExact(read_sequence, &read_seq) || + !CopyExact(write_sequence, &write_seq)) { return false; } - if (type == handback_after_ecdhe && - (hs->key_shares[0] = SSLKeyShare::Create(&key_share)) == nullptr) { - return false; + s3->read_sequence = CRYPTO_load_u64_be(read_sequence); + s3->write_sequence = CRYPTO_load_u64_be(write_sequence); + if (type == handback_after_ecdhe) { + uint64_t group_id; + CBS private_key; + if (!CBS_get_asn1_uint64(&key_share, &group_id) || // + group_id > 0xffff || + !CBS_get_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING)) { + return false; + } + hs->key_shares[0] = SSLKeyShare::Create(group_id); + if (!hs->key_shares[0] || + !hs->key_shares[0]->DeserializePrivateKey(&private_key)) { + return false; + } } return true; // Trailing data allowed for extensibility. } @@ -769,21 +799,32 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, // implicit tagging to make it a little more compact. // // HandshakeHints ::= SEQUENCE { -// serverRandom [0] IMPLICIT OCTET STRING OPTIONAL, +// serverRandomTLS13 [0] IMPLICIT OCTET STRING OPTIONAL, // keyShareHint [1] IMPLICIT KeyShareHint OPTIONAL, // signatureHint [2] IMPLICIT SignatureHint OPTIONAL, // -- At most one of decryptedPSKHint or ignorePSKHint may be present. It // -- corresponds to the first entry in pre_shared_keys. TLS 1.2 session -// -- tickets will use a separate hint, to ensure the caller does not mix -// -- them up. +// -- tickets use a separate hint, to ensure the caller does not apply the +// -- hint to the wrong field. // decryptedPSKHint [3] IMPLICIT OCTET STRING OPTIONAL, // ignorePSKHint [4] IMPLICIT NULL OPTIONAL, // compressCertificateHint [5] IMPLICIT CompressCertificateHint OPTIONAL, +// -- TLS 1.2 and 1.3 use different server random hints because one contains +// -- a timestamp while the other doesn't. If the hint was generated +// -- assuming TLS 1.3 but we actually negotiate TLS 1.2, mixing the two +// -- will break this. +// serverRandomTLS12 [6] IMPLICIT OCTET STRING OPTIONAL, +// ecdheHint [7] IMPLICIT ECDHEHint OPTIONAL +// -- At most one of decryptedTicketHint or ignoreTicketHint may be present. +// -- renewTicketHint requires decryptedTicketHint. +// decryptedTicketHint [8] IMPLICIT OCTET STRING OPTIONAL, +// renewTicketHint [9] IMPLICIT NULL OPTIONAL, +// ignoreTicketHint [10] IMPLICIT NULL OPTIONAL, // } // // KeyShareHint ::= SEQUENCE { // groupId INTEGER, -// publicKey OCTET STRING, +// ciphertext OCTET STRING, // secret OCTET STRING, // } // @@ -799,16 +840,30 @@ int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello, // input OCTET STRING, // compressed OCTET STRING, // } +// +// ECDHEHint ::= SEQUENCE { +// groupId INTEGER, +// publicKey OCTET STRING, +// privateKey OCTET STRING, +// } // HandshakeHints tags. -static const unsigned kServerRandomTag = CBS_ASN1_CONTEXT_SPECIFIC | 0; -static const unsigned kKeyShareHintTag = +static const CBS_ASN1_TAG kServerRandomTLS13Tag = + CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const CBS_ASN1_TAG kKeyShareHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -static const unsigned kSignatureHintTag = +static const CBS_ASN1_TAG kSignatureHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; -static const unsigned kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3; -static const unsigned kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4; -static const unsigned kCompressCertificateTag = CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const CBS_ASN1_TAG kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const CBS_ASN1_TAG kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const CBS_ASN1_TAG kCompressCertificateTag = + CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const CBS_ASN1_TAG kServerRandomTLS12Tag = + CBS_ASN1_CONTEXT_SPECIFIC | 6; +static const CBS_ASN1_TAG kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7; +static const CBS_ASN1_TAG kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8; +static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9; +static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10; int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { const SSL_HANDSHAKE *hs = ssl->s3->hs.get(); @@ -823,20 +878,20 @@ int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { return 0; } - if (!hints->server_random.empty()) { - if (!CBB_add_asn1(&seq, &child, kServerRandomTag) || - !CBB_add_bytes(&child, hints->server_random.data(), - hints->server_random.size())) { + if (!hints->server_random_tls13.empty()) { + if (!CBB_add_asn1(&seq, &child, kServerRandomTLS13Tag) || + !CBB_add_bytes(&child, hints->server_random_tls13.data(), + hints->server_random_tls13.size())) { return 0; } } - if (hints->key_share_group_id != 0 && !hints->key_share_public_key.empty() && + if (hints->key_share_group_id != 0 && !hints->key_share_ciphertext.empty() && !hints->key_share_secret.empty()) { if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) || !CBB_add_asn1_uint64(&child, hints->key_share_group_id) || - !CBB_add_asn1_octet_string(&child, hints->key_share_public_key.data(), - hints->key_share_public_key.size()) || + !CBB_add_asn1_octet_string(&child, hints->key_share_ciphertext.data(), + hints->key_share_ciphertext.size()) || !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(), hints->key_share_secret.size())) { return 0; @@ -884,9 +939,60 @@ int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) { } } + if (!hints->server_random_tls12.empty()) { + if (!CBB_add_asn1(&seq, &child, kServerRandomTLS12Tag) || + !CBB_add_bytes(&child, hints->server_random_tls12.data(), + hints->server_random_tls12.size())) { + return 0; + } + } + + if (hints->ecdhe_group_id != 0 && !hints->ecdhe_public_key.empty() && + !hints->ecdhe_private_key.empty()) { + if (!CBB_add_asn1(&seq, &child, kECDHEHintTag) || + !CBB_add_asn1_uint64(&child, hints->ecdhe_group_id) || + !CBB_add_asn1_octet_string(&child, hints->ecdhe_public_key.data(), + hints->ecdhe_public_key.size()) || + !CBB_add_asn1_octet_string(&child, hints->ecdhe_private_key.data(), + hints->ecdhe_private_key.size())) { + return 0; + } + } + + + if (!hints->decrypted_ticket.empty()) { + if (!CBB_add_asn1(&seq, &child, kDecryptedTicketTag) || + !CBB_add_bytes(&child, hints->decrypted_ticket.data(), + hints->decrypted_ticket.size())) { + return 0; + } + } + + if (hints->renew_ticket && // + !CBB_add_asn1(&seq, &child, kRenewTicketTag)) { + return 0; + } + + if (hints->ignore_ticket && // + !CBB_add_asn1(&seq, &child, kIgnoreTicketTag)) { + return 0; + } + return CBB_flush(out); } +static bool get_optional_implicit_null(CBS *cbs, bool *out_present, + CBS_ASN1_TAG tag) { + CBS value; + int present; + if (!CBS_get_optional_asn1(cbs, &value, &present, tag) || + (present && CBS_len(&value) != 0)) { + return false; + } + *out_present = present; + return true; +} + int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { if (SSL_is_dtls(ssl)) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -898,38 +1004,47 @@ int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { return 0; } - CBS cbs, seq, server_random, key_share, signature_hint, ticket, ignore_psk, - cert_compression; - int has_server_random, has_key_share, has_signature_hint, has_ticket, - has_ignore_psk, has_cert_compression; + CBS cbs, seq, server_random_tls13, key_share, signature_hint, psk, + cert_compression, server_random_tls12, ecdhe, ticket; + int has_server_random_tls13, has_key_share, has_signature_hint, has_psk, + has_cert_compression, has_server_random_tls12, has_ecdhe, has_ticket; CBS_init(&cbs, hints, hints_len); if (!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) || - !CBS_get_optional_asn1(&seq, &server_random, &has_server_random, - kServerRandomTag) || + !CBS_get_optional_asn1(&seq, &server_random_tls13, + &has_server_random_tls13, kServerRandomTLS13Tag) || !CBS_get_optional_asn1(&seq, &key_share, &has_key_share, kKeyShareHintTag) || !CBS_get_optional_asn1(&seq, &signature_hint, &has_signature_hint, kSignatureHintTag) || - !CBS_get_optional_asn1(&seq, &ticket, &has_ticket, kDecryptedPSKTag) || - !CBS_get_optional_asn1(&seq, &ignore_psk, &has_ignore_psk, - kIgnorePSKTag) || + !CBS_get_optional_asn1(&seq, &psk, &has_psk, kDecryptedPSKTag) || + !get_optional_implicit_null(&seq, &hints_obj->ignore_psk, + kIgnorePSKTag) || !CBS_get_optional_asn1(&seq, &cert_compression, &has_cert_compression, - kCompressCertificateTag)) { + kCompressCertificateTag) || + !CBS_get_optional_asn1(&seq, &server_random_tls12, + &has_server_random_tls12, kServerRandomTLS12Tag) || + !CBS_get_optional_asn1(&seq, &ecdhe, &has_ecdhe, kECDHEHintTag) || + !CBS_get_optional_asn1(&seq, &ticket, &has_ticket, kDecryptedTicketTag) || + !get_optional_implicit_null(&seq, &hints_obj->renew_ticket, + kRenewTicketTag) || + !get_optional_implicit_null(&seq, &hints_obj->ignore_ticket, + kIgnoreTicketTag)) { OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); return 0; } - if (has_server_random && !hints_obj->server_random.CopyFrom(server_random)) { + if (has_server_random_tls13 && + !hints_obj->server_random_tls13.CopyFrom(server_random_tls13)) { return 0; } if (has_key_share) { uint64_t group_id; - CBS public_key, secret; + CBS ciphertext, secret; if (!CBS_get_asn1_uint64(&key_share, &group_id) || // group_id == 0 || group_id > 0xffff || - !CBS_get_asn1(&key_share, &public_key, CBS_ASN1_OCTETSTRING) || - !hints_obj->key_share_public_key.CopyFrom(public_key) || + !CBS_get_asn1(&key_share, &ciphertext, CBS_ASN1_OCTETSTRING) || + !hints_obj->key_share_ciphertext.CopyFrom(ciphertext) || !CBS_get_asn1(&key_share, &secret, CBS_ASN1_OCTETSTRING) || !hints_obj->key_share_secret.CopyFrom(secret)) { OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); @@ -955,15 +1070,12 @@ int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { hints_obj->signature_algorithm = static_cast(sig_alg); } - if (has_ticket && !hints_obj->decrypted_psk.CopyFrom(ticket)) { + if (has_psk && !hints_obj->decrypted_psk.CopyFrom(psk)) { return 0; } - - if (has_ignore_psk) { - if (CBS_len(&ignore_psk) != 0) { - return 0; - } - hints_obj->ignore_psk = true; + if (has_psk && hints_obj->ignore_psk) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; } if (has_cert_compression) { @@ -981,6 +1093,38 @@ int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) { hints_obj->cert_compression_alg_id = static_cast(alg); } + if (has_server_random_tls12 && + !hints_obj->server_random_tls12.CopyFrom(server_random_tls12)) { + return 0; + } + + if (has_ecdhe) { + uint64_t group_id; + CBS public_key, private_key; + if (!CBS_get_asn1_uint64(&ecdhe, &group_id) || // + group_id == 0 || group_id > 0xffff || + !CBS_get_asn1(&ecdhe, &public_key, CBS_ASN1_OCTETSTRING) || + !hints_obj->ecdhe_public_key.CopyFrom(public_key) || + !CBS_get_asn1(&ecdhe, &private_key, CBS_ASN1_OCTETSTRING) || + !hints_obj->ecdhe_private_key.CopyFrom(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + hints_obj->ecdhe_group_id = static_cast(group_id); + } + + if (has_ticket && !hints_obj->decrypted_ticket.CopyFrom(ticket)) { + return 0; + } + if (has_ticket && hints_obj->ignore_ticket) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + if (!has_ticket && hints_obj->renew_ticket) { + OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS); + return 0; + } + ssl->s3->hs->hints = std::move(hints_obj); return 1; } diff --git a/third_party/boringssl/kit/src/ssl/handshake.cc b/third_party/boringssl/kit/src/ssl/handshake.cc index fc85e21d..8d5a2387 100644 --- a/third_party/boringssl/kit/src/ssl/handshake.cc +++ b/third_party/boringssl/kit/src/ssl/handshake.cc @@ -528,20 +528,20 @@ bool ssl_send_finished(SSL_HANDSHAKE *hs) { size_t finished_len; if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session, ssl->server)) { - return 0; + return false; } // Log the master secret, if logging is enabled. if (!ssl_log_secret(ssl, "CLIENT_RANDOM", MakeConstSpan(session->secret, session->secret_length))) { - return 0; + return false; } // Copy the Finished so we can use it for renegotiation checks. if (finished_len > sizeof(ssl->s3->previous_client_finished) || finished_len > sizeof(ssl->s3->previous_server_finished)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; + return false; } if (ssl->server) { @@ -558,10 +558,10 @@ bool ssl_send_finished(SSL_HANDSHAKE *hs) { !CBB_add_bytes(&body, finished, finished_len) || !ssl_add_message_cbb(ssl, cbb.get())) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; + return false; } - return 1; + return true; } bool ssl_output_cert_chain(SSL_HANDSHAKE *hs) { diff --git a/third_party/boringssl/kit/src/ssl/handshake_client.cc b/third_party/boringssl/kit/src/ssl/handshake_client.cc index 17b41e0c..971ebd0b 100644 --- a/third_party/boringssl/kit/src/ssl/handshake_client.cc +++ b/third_party/boringssl/kit/src/ssl/handshake_client.cc @@ -215,6 +215,14 @@ static void ssl_get_client_disabled(const SSL_HANDSHAKE *hs, } } +static bool ssl_add_tls13_cipher(CBB *cbb, uint16_t cipher_id, + ssl_compliance_policy_t policy) { + if (ssl_tls13_cipher_meets_policy(cipher_id, policy)) { + return CBB_add_u16(cbb, cipher_id); + } + return true; +} + static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, ssl_client_hello_type_t type) { const SSL *const ssl = hs->ssl; @@ -235,16 +243,22 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, // Add TLS 1.3 ciphers. Order ChaCha20-Poly1305 relative to AES-GCM based on // hardware support. if (hs->max_version >= TLS1_3_VERSION) { - if (!EVP_has_aes_hardware() && - !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { - return false; - } - if (!CBB_add_u16(&child, TLS1_CK_AES_128_GCM_SHA256 & 0xffff) || - !CBB_add_u16(&child, TLS1_CK_AES_256_GCM_SHA384 & 0xffff)) { - return false; - } - if (EVP_has_aes_hardware() && - !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + + if ((!has_aes_hw && // + !ssl_add_tls13_cipher(&child, + TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff, + ssl->config->tls13_cipher_policy)) || + !ssl_add_tls13_cipher(&child, TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff, + ssl->config->tls13_cipher_policy) || + !ssl_add_tls13_cipher(&child, TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff, + ssl->config->tls13_cipher_policy) || + (has_aes_hw && // + !ssl_add_tls13_cipher(&child, + TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff, + ssl->config->tls13_cipher_policy))) { return false; } } @@ -307,7 +321,8 @@ bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, if (SSL_is_dtls(ssl)) { if (!CBB_add_u8_length_prefixed(cbb, &child) || - !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { + !CBB_add_bytes(&child, hs->dtls_cookie.data(), + hs->dtls_cookie.size())) { return false; } } @@ -331,7 +346,7 @@ bool ssl_add_client_hello(SSL_HANDSHAKE *hs) { Array msg; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) || !ssl_write_client_hello_without_extensions(hs, &body, type, - /*empty_session_id*/ false) || + /*empty_session_id=*/false) || !ssl_add_clienthello_tlsext(hs, &body, /*out_encoded=*/nullptr, &needs_psk_binder, type, CBB_len(&body)) || !ssl->method->finish_message(ssl, cbb.get(), &msg)) { @@ -620,15 +635,16 @@ static enum ssl_hs_wait_t do_read_hello_verify_request(SSL_HANDSHAKE *hs) { uint16_t server_version; if (!CBS_get_u16(&hello_verify_request, &server_version) || !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || - CBS_len(&cookie) > sizeof(ssl->d1->cookie) || CBS_len(&hello_verify_request) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } - OPENSSL_memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); - ssl->d1->cookie_len = CBS_len(&cookie); + if (!hs->dtls_cookie.CopyFrom(cookie)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } ssl->method->next_message(ssl); @@ -825,11 +841,18 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } - // Note: session_id could be empty. - hs->new_session->session_id_length = CBS_len(&server_hello.session_id); + + // Save the session ID from the server. This may be empty if the session + // isn't resumable, or if we'll receive a session ticket later. + assert(CBS_len(&server_hello.session_id) <= SSL3_SESSION_ID_SIZE); + static_assert(SSL3_SESSION_ID_SIZE <= UINT8_MAX, + "max session ID is too large"); + hs->new_session->session_id_length = + static_cast(CBS_len(&server_hello.session_id)); OPENSSL_memcpy(hs->new_session->session_id, CBS_data(&server_hello.session_id), CBS_len(&server_hello.session_id)); + hs->new_session->cipher = hs->new_cipher; } @@ -1090,7 +1113,6 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { char *raw = nullptr; if (CBS_len(&psk_identity_hint) != 0 && !CBS_strdup(&psk_identity_hint, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } @@ -1110,7 +1132,6 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } - hs->new_session->group_id = group_id; // Ensure the group is consistent with preferences. if (!tls1_check_group_id(hs, group_id)) { @@ -1119,10 +1140,9 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - // Initialize ECDH and save the peer public key for later. - hs->key_shares[0] = SSLKeyShare::Create(group_id); - if (!hs->key_shares[0] || - !hs->peer_key.CopyFrom(point)) { + // Save the group and peer public key for later. + hs->new_session->group_id = group_id; + if (!hs->peer_key.CopyFrom(point)) { return ssl_hs_error; } } else if (!(alg_k & SSL_kPSK)) { @@ -1382,11 +1402,13 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { ssl_key_usage_t intended_use = (alg_k & SSL_kRSA) ? key_usage_encipherment : key_usage_digital_signature; - if (hs->config->enforce_rsa_key_usage || - EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) { - if (!ssl_cert_check_key_usage(&leaf_cbs, intended_use)) { + if (!ssl_cert_check_key_usage(&leaf_cbs, intended_use)) { + if (hs->config->enforce_rsa_key_usage || + EVP_PKEY_id(hs->peer_pubkey.get()) != EVP_PKEY_RSA) { return ssl_hs_error; } + ERR_clear_error(); + ssl->s3->was_key_usage_invalid = true; } } @@ -1413,7 +1435,6 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { hs->new_session->psk_identity.reset(OPENSSL_strdup(identity)); if (hs->new_session->psk_identity == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } @@ -1457,15 +1478,16 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } } else if (alg_k & SSL_kECDHE) { - // Generate a keypair and serialize the public half. CBB child; if (!CBB_add_u8_length_prefixed(&body, &child)) { return ssl_hs_error; } - // Compute the premaster. + // Generate a premaster secret and encapsulate it. + bssl::UniquePtr kem = + SSLKeyShare::Create(hs->new_session->group_id); uint8_t alert = SSL_AD_DECODE_ERROR; - if (!hs->key_shares[0]->Accept(&child, &pms, &alert, hs->peer_key)) { + if (!kem || !kem->Encap(&child, &pms, &alert, hs->peer_key)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } @@ -1473,9 +1495,7 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - // The key exchange state may now be discarded. - hs->key_shares[0].reset(); - hs->key_shares[1].reset(); + // The peer key can now be discarded. hs->peer_key.Reset(); } else if (alg_k & SSL_kPSK) { // For plain PSK, other_secret is a block of 0s with the same length as @@ -1501,7 +1521,6 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || !CBBFinishArray(pms_cbb.get(), &pms)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } } diff --git a/third_party/boringssl/kit/src/ssl/handshake_server.cc b/third_party/boringssl/kit/src/ssl/handshake_server.cc index fdf95113..cffa52d8 100644 --- a/third_party/boringssl/kit/src/ssl/handshake_server.cc +++ b/third_party/boringssl/kit/src/ssl/handshake_server.cc @@ -272,7 +272,6 @@ static UniquePtr ssl_parse_client_cipher_list( UniquePtr sk(sk_SSL_CIPHER_new_null()); if (!sk) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -286,7 +285,6 @@ static UniquePtr ssl_parse_client_cipher_list( const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite); if (c != NULL && !sk_SSL_CIPHER_push(sk.get(), c)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -411,14 +409,14 @@ static bool is_probably_jdk11_with_tls13(const SSL_CLIENT_HELLO *client_hello) { // JDK 11 does not support ChaCha20-Poly1305. This is unusual: many modern // clients implement ChaCha20-Poly1305. if (ssl_client_cipher_list_contains_cipher( - client_hello, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + client_hello, TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { return false; } // JDK 11 always sends extensions in a particular order. constexpr uint16_t kMaxFragmentLength = 0x0001; constexpr uint16_t kStatusRequestV2 = 0x0011; - static CONSTEXPR_ARRAY struct { + static constexpr struct { uint16_t id; bool required; } kJavaExtensions[] = { @@ -485,7 +483,7 @@ static bool is_probably_jdk11_with_tls13(const SSL_CLIENT_HELLO *client_hello) { while (CBS_len(&supported_groups) > 0) { uint16_t group; if (!CBS_get_u16(&supported_groups, &group) || - group == SSL_CURVE_X25519) { + group == SSL_GROUP_X25519) { return false; } } @@ -554,29 +552,22 @@ static bool decrypt_ech(SSL_HANDSHAKE *hs, uint8_t *out_alert, ERR_clear_error(); continue; } - Array encoded_client_hello_inner; bool is_decrypt_error; - if (!ssl_client_hello_decrypt(hs->ech_hpke_ctx.get(), - &encoded_client_hello_inner, - &is_decrypt_error, client_hello, payload)) { + if (!ssl_client_hello_decrypt(hs, out_alert, &is_decrypt_error, + &hs->ech_client_hello_buf, client_hello, + payload)) { if (is_decrypt_error) { // Ignore the error and try another ECHConfig. ERR_clear_error(); + // The |out_alert| calling convention currently relies on a default of + // |SSL_AD_DECODE_ERROR|. https://crbug.com/boringssl/373 tracks + // switching to sum types, which avoids this. + *out_alert = SSL_AD_DECODE_ERROR; continue; } OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); return false; } - - // Recover the ClientHelloInner from the EncodedClientHelloInner. - bssl::Array client_hello_inner; - if (!ssl_decode_client_hello_inner(ssl, out_alert, &client_hello_inner, - encoded_client_hello_inner, - client_hello)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - return false; - } - hs->ech_client_hello_buf = std::move(client_hello_inner); hs->ech_config_id = config_id; ssl->s3->ech_status = ssl_ech_accepted; return true; @@ -808,12 +799,6 @@ static enum ssl_hs_wait_t do_select_certificate(SSL_HANDSHAKE *hs) { // or below. assert(ssl->s3->ech_status != ssl_ech_accepted); - // TODO(davidben): Also compute hints for TLS 1.2. When doing so, update the - // check in bssl_shim.cc to test this. - if (hs->hints_requested) { - return ssl_hs_hints_ready; - } - ssl->s3->early_data_reason = ssl_early_data_protocol_version; SSLMessage msg_unused; @@ -995,14 +980,23 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { hs->channel_id_negotiated = false; } - struct OPENSSL_timeval now; - ssl_get_current_time(ssl, &now); - ssl->s3->server_random[0] = now.tv_sec >> 24; - ssl->s3->server_random[1] = now.tv_sec >> 16; - ssl->s3->server_random[2] = now.tv_sec >> 8; - ssl->s3->server_random[3] = now.tv_sec; - if (!RAND_bytes(ssl->s3->server_random + 4, SSL3_RANDOM_SIZE - 4)) { - return ssl_hs_error; + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + if (hints && !hs->hints_requested && + hints->server_random_tls12.size() == SSL3_RANDOM_SIZE) { + OPENSSL_memcpy(ssl->s3->server_random, hints->server_random_tls12.data(), + SSL3_RANDOM_SIZE); + } else { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + CRYPTO_store_u32_be(ssl->s3->server_random, + static_cast(now.tv_sec)); + if (!RAND_bytes(ssl->s3->server_random + 4, SSL3_RANDOM_SIZE - 4)) { + return ssl_hs_error; + } + if (hints && hs->hints_requested && + !hints->server_random_tls12.CopyFrom(ssl->s3->server_random)) { + return ssl_hs_error; + } } // Implement the TLS 1.3 anti-downgrade feature. @@ -1047,7 +1041,11 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - if (ssl->session != NULL) { + if (ssl->session != nullptr) { + // No additional hints to generate in resumption. + if (hs->hints_requested) { + return ssl_hs_hints_ready; + } hs->state = state12_send_server_finished; } else { hs->state = state12_send_server_certificate; @@ -1120,18 +1118,51 @@ static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); return ssl_hs_error; - } + } hs->new_session->group_id = group_id; - // Set up ECDH, generate a key, and emit the public half. hs->key_shares[0] = SSLKeyShare::Create(group_id); if (!hs->key_shares[0] || !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) || !CBB_add_u16(cbb.get(), group_id) || - !CBB_add_u8_length_prefixed(cbb.get(), &child) || - !hs->key_shares[0]->Offer(&child)) { + !CBB_add_u8_length_prefixed(cbb.get(), &child)) { return ssl_hs_error; } + + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + bool hint_ok = false; + if (hints && !hs->hints_requested && + hints->ecdhe_group_id == group_id && + !hints->ecdhe_public_key.empty() && + !hints->ecdhe_private_key.empty()) { + CBS cbs = MakeConstSpan(hints->ecdhe_private_key); + hint_ok = hs->key_shares[0]->DeserializePrivateKey(&cbs); + } + if (hint_ok) { + // Reuse the ECDH key from handshake hints. + if (!CBB_add_bytes(&child, hints->ecdhe_public_key.data(), + hints->ecdhe_public_key.size())) { + return ssl_hs_error; + } + } else { + // Generate a key, and emit the public half. + if (!hs->key_shares[0]->Generate(&child)) { + return ssl_hs_error; + } + // If generating hints, save the ECDHE key. + if (hints && hs->hints_requested) { + bssl::ScopedCBB private_key_cbb; + if (!hints->ecdhe_public_key.CopyFrom( + MakeConstSpan(CBB_data(&child), CBB_len(&child))) || + !CBB_init(private_key_cbb.get(), 32) || + !hs->key_shares[0]->SerializePrivateKey(private_key_cbb.get()) || + !CBBFinishArray(private_key_cbb.get(), + &hints->ecdhe_private_key)) { + return ssl_hs_error; + } + hints->ecdhe_group_id = group_id; + } + } } else { assert(alg_k & SSL_kPSK); } @@ -1221,6 +1252,9 @@ static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) { static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; + if (hs->hints_requested) { + return ssl_hs_hints_ready; + } ScopedCBB cbb; CBB body; @@ -1311,7 +1345,7 @@ static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { hs->new_session->verify_result = X509_V_OK; } else if (hs->config->retain_only_sha256_of_client_certs) { // The hash will have been filled in. - hs->new_session->peer_sha256_valid = 1; + hs->new_session->peer_sha256_valid = true; } ssl->method->next_message(ssl); @@ -1371,7 +1405,6 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { } char *raw = nullptr; if (!CBS_strdup(&psk_identity, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } @@ -1457,17 +1490,17 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { } } else if (alg_k & SSL_kECDHE) { // Parse the ClientKeyExchange. - CBS peer_key; - if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) || + CBS ciphertext; + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ciphertext) || CBS_len(&client_key_exchange) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } - // Compute the premaster. + // Decapsulate the premaster secret. uint8_t alert = SSL_AD_DECODE_ERROR; - if (!hs->key_shares[0]->Finish(&premaster_secret, &alert, peer_key)) { + if (!hs->key_shares[0]->Decap(&premaster_secret, &alert, ciphertext)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } @@ -1524,7 +1557,6 @@ static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || !CBBFinishArray(new_premaster.get(), &premaster_secret)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } } diff --git a/third_party/boringssl/kit/src/ssl/internal.h b/third_party/boringssl/kit/src/ssl/internal.h index 5196f17c..fa35073f 100644 --- a/third_party/boringssl/kit/src/ssl/internal.h +++ b/third_party/boringssl/kit/src/ssl/internal.h @@ -195,7 +195,6 @@ template T *New(Args &&... args) { void *t = OPENSSL_malloc(sizeof(T)); if (t == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } return new (t) T(std::forward(args)...); @@ -216,7 +215,7 @@ void Delete(T *t) { // may be C structs which require a |BORINGSSL_MAKE_DELETER| registration. namespace internal { template -struct DeleterImpl::type> { +struct DeleterImpl> { static void Free(T *t) { Delete(t); } }; } // namespace internal @@ -245,14 +244,6 @@ UniquePtr MakeUnique(Args &&... args) { { abort(); } #endif -// CONSTEXPR_ARRAY works around a VS 2015 bug where ranged for loops don't work -// on constexpr arrays. -#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1910 -#define CONSTEXPR_ARRAY const -#else -#define CONSTEXPR_ARRAY constexpr -#endif - // Array is an owning array of elements of |T|. template class Array { @@ -323,7 +314,6 @@ class Array { } data_ = reinterpret_cast(OPENSSL_malloc(new_size * sizeof(T))); if (data_ == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } size_ = new_size; @@ -461,6 +451,27 @@ class GrowableArray { // CBBFinishArray behaves like |CBB_finish| but stores the result in an Array. OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array *out); +// GetAllNames helps to implement |*_get_all_*_names| style functions. It +// writes at most |max_out| string pointers to |out| and returns the number that +// it would have liked to have written. The strings written consist of +// |fixed_names_len| strings from |fixed_names| followed by |objects_len| +// strings taken by projecting |objects| through |name|. +template +inline size_t GetAllNames(const char **out, size_t max_out, + Span fixed_names, Name(T::*name), + Span objects) { + auto span = bssl::MakeSpan(out, max_out); + for (size_t i = 0; !span.empty() && i < fixed_names.size(); i++) { + span[0] = fixed_names[i]; + span = span.subspan(1); + } + span = span.subspan(0, objects.size()); + for (size_t i = 0; i < span.size(); i++) { + span[i] = objects[i].*name; + } + return fixed_names.size() + objects.size(); +} + // Protocol versions. // @@ -557,15 +568,15 @@ BSSL_NAMESPACE_BEGIN #define SSL_AES256 0x00000004u #define SSL_AES128GCM 0x00000008u #define SSL_AES256GCM 0x00000010u -#define SSL_eNULL 0x00000020u -#define SSL_CHACHA20POLY1305 0x00000040u +#define SSL_CHACHA20POLY1305 0x00000020u #define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM) // Bits for |algorithm_mac| (symmetric authentication). #define SSL_SHA1 0x00000001u +#define SSL_SHA256 0x00000002u // SSL_AEAD is set for all AEADs. -#define SSL_AEAD 0x00000002u +#define SSL_AEAD 0x00000004u // Bits for |algorithm_prf| (handshake digest). #define SSL_HANDSHAKE_MAC_DEFAULT 0x1 @@ -643,9 +654,11 @@ const EVP_MD *ssl_get_handshake_digest(uint16_t version, // newly-allocated |SSLCipherPreferenceList| containing the result. It returns // true on success and false on failure. If |strict| is true, nonsense will be // rejected. If false, nonsense will be silently ignored. An empty result is -// considered an error regardless of |strict|. +// considered an error regardless of |strict|. |has_aes_hw| indicates if the +// list should be ordered based on having support for AES in hardware or not. bool ssl_create_cipher_list(UniquePtr *out_cipher_list, - const char *rule_str, bool strict); + const bool has_aes_hw, const char *rule_str, + bool strict); // ssl_cipher_auth_mask_for_key returns the mask of cipher |algorithm_auth| // values suitable for use with |key| in TLS 1.2 and below. @@ -668,10 +681,21 @@ bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher); size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher); // ssl_choose_tls13_cipher returns an |SSL_CIPHER| corresponding with the best -// available from |cipher_suites| compatible with |version| and |group_id|. It -// returns NULL if there isn't a compatible cipher. -const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, - uint16_t group_id); +// available from |cipher_suites| compatible with |version|, |group_id|, and +// |policy|. It returns NULL if there isn't a compatible cipher. |has_aes_hw| +// indicates if the choice should be made as if support for AES in hardware +// is available. +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw, + uint16_t version, uint16_t group_id, + enum ssl_compliance_policy_t policy); + +// ssl_tls13_cipher_meets_policy returns true if |cipher_id| is acceptable given +// |policy|. +bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id, + enum ssl_compliance_policy_t policy); + +// ssl_cipher_is_deprecated returns true if |cipher| is deprecated. +OPENSSL_EXPORT bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher); // Transcript layer. @@ -832,15 +856,14 @@ class SSLAEADContext { // to the plaintext in |in| and returns true. Otherwise, it returns // false. The output will always be |ExplicitNonceLen| bytes ahead of |in|. bool Open(Span *out, uint8_t type, uint16_t record_version, - const uint8_t seqnum[8], Span header, - Span in); + uint64_t seqnum, Span header, Span in); // Seal encrypts and authenticates |in_len| bytes from |in| and writes the // result to |out|. It returns true on success and false on error. // // If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|. bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, - uint16_t record_version, const uint8_t seqnum[8], + uint16_t record_version, uint64_t seqnum, Span header, const uint8_t *in, size_t in_len); // SealScatter encrypts and authenticates |in_len| bytes from |in| and splits @@ -859,10 +882,9 @@ class SSLAEADContext { // If |in| and |out| alias then |out| must be == |in|. Other arguments may not // alias anything. bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix, - uint8_t type, uint16_t record_version, - const uint8_t seqnum[8], Span header, - const uint8_t *in, size_t in_len, const uint8_t *extra_in, - size_t extra_in_len); + uint8_t type, uint16_t record_version, uint64_t seqnum, + Span header, const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len); bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const; @@ -871,8 +893,7 @@ class SSLAEADContext { // necessary. Span GetAdditionalData(uint8_t storage[13], uint8_t type, uint16_t record_version, - const uint8_t seqnum[8], - size_t plaintext_len, + uint64_t seqnum, size_t plaintext_len, Span header); const SSL_CIPHER *cipher_; @@ -919,10 +940,6 @@ struct DTLS1_BITMAP { // Record layer. -// ssl_record_sequence_update increments the sequence number in |seq|. It -// returns true on success and false on wraparound. -bool ssl_record_sequence_update(uint8_t *seq, size_t seq_len); - // ssl_record_prefix_len returns the length of the prefix before the ciphertext // of a record for |ssl|. // @@ -1063,7 +1080,15 @@ bool ssl_public_key_verify(SSL *ssl, Span signature, // Key shares. -// SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. +// SSLKeyShare abstracts over KEM-like constructions, for use with TLS 1.2 ECDHE +// cipher suites and the TLS 1.3 key_share extension. +// +// TODO(davidben): This class is named SSLKeyShare after the TLS 1.3 key_share +// extension, but it really implements a KEM abstraction. Additionally, we use +// the same type for Encap, which is a one-off, stateless operation, as Generate +// and Decap. Slightly tidier would be for Generate to return a new SSLKEMKey +// (or we introduce EVP_KEM and EVP_KEM_KEY), with a Decap method, and for Encap +// to be static function. class SSLKeyShare { public: virtual ~SSLKeyShare() {} @@ -1074,40 +1099,29 @@ class SSLKeyShare { // nullptr on error. static UniquePtr Create(uint16_t group_id); - // Create deserializes an SSLKeyShare instance previously serialized by - // |Serialize|. - static UniquePtr Create(CBS *in); - - // Serializes writes the group ID and private key, in a format that can be - // read by |Create|. - bool Serialize(CBB *out); - // GroupID returns the group ID. virtual uint16_t GroupID() const PURE_VIRTUAL; - // Offer generates a keypair and writes the public value to - // |out_public_key|. It returns true on success and false on error. - virtual bool Offer(CBB *out_public_key) PURE_VIRTUAL; + // Generate generates a keypair and writes the public key to |out_public_key|. + // It returns true on success and false on error. + virtual bool Generate(CBB *out_public_key) PURE_VIRTUAL; - // Accept performs a key exchange against the |peer_key| generated by |Offer|. - // On success, it returns true, writes the public value to |out_public_key|, - // and sets |*out_secret| to the shared secret. On failure, it returns false - // and sets |*out_alert| to an alert to send to the peer. - // - // The default implementation calls |Offer| and then |Finish|, assuming a key - // exchange protocol where the peers are symmetric. - virtual bool Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key); + // Encap generates an ephemeral, symmetric secret and encapsulates it with + // |peer_key|. On success, it returns true, writes the encapsulated secret to + // |out_ciphertext|, and sets |*out_secret| to the shared secret. On failure, + // it returns false and sets |*out_alert| to an alert to send to the peer. + virtual bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, + Span peer_key) PURE_VIRTUAL; - // Finish performs a key exchange against the |peer_key| generated by - // |Accept|. On success, it returns true and sets |*out_secret| to the shared - // secret. On failure, it returns false and sets |*out_alert| to an alert to - // send to the peer. - virtual bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) PURE_VIRTUAL; + // Decap decapsulates the symmetric secret in |ciphertext|. On success, it + // returns true and sets |*out_secret| to the shared secret. On failure, it + // returns false and sets |*out_alert| to an alert to send to the peer. + virtual bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) PURE_VIRTUAL; // SerializePrivateKey writes the private key to |out|, returning true if - // successful and false otherwise. It should be called after |Offer|. + // successful and false otherwise. It should be called after |Generate|. virtual bool SerializePrivateKey(CBB *out) { return false; } // DeserializePrivateKey initializes the state of the key exchange from |in|, @@ -1118,7 +1132,7 @@ class SSLKeyShare { struct NamedGroup { int nid; uint16_t group_id; - const char name[8], alias[11]; + const char name[32], alias[32]; }; // NamedGroups returns all supported groups. @@ -1134,6 +1148,10 @@ bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid); // true. Otherwise, it returns false. bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len); +// ssl_group_id_to_nid returns the NID corresponding to |group_id| or +// |NID_undef| if unknown. +int ssl_group_id_to_nid(uint16_t group_id); + // Handshake messages. @@ -1184,12 +1202,10 @@ struct DTLS_OUTGOING_MESSAGE { DTLS_OUTGOING_MESSAGE() {} DTLS_OUTGOING_MESSAGE(const DTLS_OUTGOING_MESSAGE &) = delete; DTLS_OUTGOING_MESSAGE &operator=(const DTLS_OUTGOING_MESSAGE &) = delete; - ~DTLS_OUTGOING_MESSAGE() { Clear(); } void Clear(); - uint8_t *data = nullptr; - uint32_t len = 0; + Array data; uint16_t epoch = 0; bool is_ccs = false; }; @@ -1325,7 +1341,8 @@ enum ssl_key_usage_t { // ssl_cert_check_key_usage parses the DER-encoded, X.509 certificate in |in| // and returns true if doesn't specify a key usage or, if it does, if it // includes |bit|. Otherwise it pushes to the error queue and returns false. -bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit); +OPENSSL_EXPORT bool ssl_cert_check_key_usage(const CBS *in, + enum ssl_key_usage_t bit); // ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509 // certificate in |in|. It returns an allocated |EVP_PKEY| or else returns @@ -1498,17 +1515,19 @@ enum ssl_client_hello_type_t { // ClientHelloOuter |client_hello_outer|. If successful, it writes the recovered // ClientHelloInner to |out_client_hello_inner|. It returns true on success and // false on failure. +// +// This function is exported for fuzzing. OPENSSL_EXPORT bool ssl_decode_client_hello_inner( SSL *ssl, uint8_t *out_alert, Array *out_client_hello_inner, Span encoded_client_hello_inner, const SSL_CLIENT_HELLO *client_hello_outer); -// ssl_client_hello_decrypt attempts to decrypt the |payload| and writes the -// result to |*out|. |payload| must point into |client_hello_outer|. It returns -// true on success and false on error. On error, it sets |*out_is_decrypt_error| -// to whether the failure was due to a bad ciphertext. -bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array *out, - bool *out_is_decrypt_error, +// ssl_client_hello_decrypt attempts to decrypt and decode the |payload|. It +// writes the result to |*out|. |payload| must point into |client_hello_outer|. +// It returns true on success and false on error. On error, it sets +// |*out_is_decrypt_error| to whether the failure was due to a bad ciphertext. +bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert, + bool *out_is_decrypt_error, Array *out, const SSL_CLIENT_HELLO *client_hello_outer, Span payload); @@ -1698,10 +1717,11 @@ enum handback_t { struct SSL_HANDSHAKE_HINTS { static constexpr bool kAllowUniquePtr = true; - Array server_random; + Array server_random_tls12; + Array server_random_tls13; uint16_t key_share_group_id = 0; - Array key_share_public_key; + Array key_share_ciphertext; Array key_share_secret; uint16_t signature_algorithm = 0; @@ -1715,6 +1735,14 @@ struct SSL_HANDSHAKE_HINTS { uint16_t cert_compression_alg_id = 0; Array cert_compression_input; Array cert_compression_output; + + uint16_t ecdhe_group_id = 0; + Array ecdhe_public_key; + Array ecdhe_private_key; + + Array decrypted_ticket; + bool renew_ticket = false; + bool ignore_ticket = false; }; struct SSL_HANDSHAKE { @@ -1829,9 +1857,15 @@ struct SSL_HANDSHAKE { // ClientHelloInner. uint8_t inner_client_random[SSL3_RANDOM_SIZE] = {0}; - // cookie is the value of the cookie received from the server, if any. + // cookie is the value of the cookie in HelloRetryRequest, or empty if none + // was received. Array cookie; + // dtls_cookie is the value of the cookie in DTLS HelloVerifyRequest. If + // empty, either none was received or HelloVerifyRequest contained an empty + // cookie. + Array dtls_cookie; + // ech_client_outer contains the outer ECH extension to send in the // ClientHello, excluding the header and type byte. Array ech_client_outer; @@ -1847,9 +1881,9 @@ struct SSL_HANDSHAKE { // key_share_bytes is the key_share extension that the client should send. Array key_share_bytes; - // ecdh_public_key, for servers, is the key share to be sent to the client in - // TLS 1.3. - Array ecdh_public_key; + // key_share_ciphertext, for servers, is encapsulated shared secret to be sent + // to the client in the TLS 1.3 key_share extension. + Array key_share_ciphertext; // peer_sigalgs are the signature algorithms that the peer supports. These are // taken from the contents of the signature algorithms extension for a server @@ -2062,6 +2096,11 @@ struct SSL_HANDSHAKE { uint8_t grease_seed[ssl_grease_last_index + 1] = {0}; }; +// kMaxTickets is the maximum number of tickets to send immediately after the +// handshake. We use a one-byte ticket nonce, and there is no point in sending +// so many tickets. +constexpr size_t kMaxTickets = 16; + UniquePtr ssl_handshake_new(SSL *ssl); // ssl_check_message_type checks if |msg| has type |type|. If so it returns @@ -2447,8 +2486,13 @@ struct SSL_PROTOCOL_METHOD { ssl_open_record_t (*open_app_data)(SSL *ssl, Span *out, size_t *out_consumed, uint8_t *out_alert, Span in); - int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, - int len); + // write_app_data encrypts and writes |in| as application data. On success, it + // returns one and sets |*out_bytes_written| to the number of bytes of |in| + // written. Otherwise, it returns <= 0 and sets |*out_needs_handshake| to + // whether the operation failed because the caller needs to drive the + // handshake. + int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, + size_t *out_bytes_written, Span in); int (*dispatch_alert)(SSL *ssl); // init_message begins a new handshake message of type |type|. |cbb| is the // root CBB to be passed into |finish_message|. |*body| is set to a child CBB @@ -2622,8 +2666,8 @@ struct SSL3_STATE { SSL3_STATE(); ~SSL3_STATE(); - uint8_t read_sequence[8] = {0}; - uint8_t write_sequence[8] = {0}; + uint64_t read_sequence = 0; + uint64_t write_sequence = 0; uint8_t server_random[SSL3_RANDOM_SIZE] = {0}; uint8_t client_random[SSL3_RANDOM_SIZE] = {0}; @@ -2637,12 +2681,23 @@ struct SSL3_STATE { // |read_buffer|. Span pending_app_data; - // partial write - check the numbers match - unsigned int wnum = 0; // number of bytes sent so far - int wpend_tot = 0; // number bytes written - int wpend_type = 0; - int wpend_ret = 0; // number of bytes submitted - const uint8_t *wpend_buf = nullptr; + // unreported_bytes_written is the number of bytes successfully written to the + // transport, but not yet reported to the caller. The next |SSL_write| will + // skip this many bytes from the input. This is used if + // |SSL_MODE_ENABLE_PARTIAL_WRITE| is disabled, in which case |SSL_write| only + // reports bytes written when the full caller input is written. + size_t unreported_bytes_written = 0; + + // pending_write, if |has_pending_write| is true, is the caller-supplied data + // corresponding to the current pending write. This is used to check the + // caller retried with a compatible buffer. + Span pending_write; + + // pending_write_type, if |has_pending_write| is true, is the record type + // for the current pending write. + // + // TODO(davidben): Remove this when alerts are moved out of this write path. + uint8_t pending_write_type = 0; // read_shutdown is the shutdown state for the read half of the connection. enum ssl_shutdown_t read_shutdown = ssl_shutdown_none; @@ -2722,9 +2777,6 @@ struct SSL3_STATE { // outstanding. bool key_update_pending : 1; - // wpend_pending is true if we have a pending write outstanding. - bool wpend_pending : 1; - // early_data_accepted is true if early data was accepted by the server. bool early_data_accepted : 1; @@ -2739,6 +2791,11 @@ struct SSL3_STATE { // HelloRetryRequest message. bool used_hello_retry_request : 1; + // was_key_usage_invalid is whether the handshake succeeded despite using a + // TLS mode which was incompatible with the leaf certificate's keyUsage + // extension. + bool was_key_usage_invalid : 1; + // hs_buf is the buffer of handshake data to process. UniquePtr hs_buf; @@ -2828,8 +2885,6 @@ struct SSL3_STATE { }; // lengths of messages -#define DTLS1_COOKIE_LENGTH 256 - #define DTLS1_RT_HEADER_LENGTH 13 #define DTLS1_HM_HEADER_LENGTH 12 @@ -2895,9 +2950,6 @@ struct DTLS1_STATE { // peer sent the final flight. bool flight_has_reply : 1; - uint8_t cookie[DTLS1_COOKIE_LENGTH] = {0}; - size_t cookie_len = 0; - // The current data and handshake epoch. This is initially undefined, and // starts at zero once the initial handshake is completed. uint16_t r_epoch = 0; @@ -2910,7 +2962,7 @@ struct DTLS1_STATE { uint16_t handshake_read_seq = 0; // save last sequence number for retransmissions - uint8_t last_write_sequence[8] = {0}; + uint64_t last_write_sequence = 0; UniquePtr last_aead_write_ctx; // incoming_messages is a ring buffer of incoming handshake messages that have @@ -3040,6 +3092,10 @@ struct SSL_CONFIG { // structure for the client to use when negotiating ECH. Array client_ech_config_list; + // tls13_cipher_policy limits the set of ciphers that can be selected when + // negotiating a TLS 1.3 connection. + enum ssl_compliance_policy_t tls13_cipher_policy = ssl_compliance_policy_none; + // verify_mode is a bitmask of |SSL_VERIFY_*| values. uint8_t verify_mode = SSL_VERIFY_NONE; @@ -3088,6 +3144,15 @@ struct SSL_CONFIG { // permute_extensions is whether to permute extensions when sending messages. bool permute_extensions : 1; + + // aes_hw_override if set indicates we should override checking for aes + // hardware support, and use the value in aes_hw_override_value instead. + bool aes_hw_override : 1; + + // aes_hw_override_value is used for testing to indicate the support or lack + // of support for AES hw. The value is only considered if |aes_hw_override| is + // true. + bool aes_hw_override_value : 1; }; // From RFC 8446, used in determining PSK modes. @@ -3109,8 +3174,9 @@ bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, const EVP_PKEY *privkey); bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey); bool ssl_get_new_session(SSL_HANDSHAKE *hs); -int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session); -int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); +bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, + const SSL_SESSION *session); +bool ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); // ssl_session_new returns a newly-allocated blank |SSL_SESSION| or nullptr on // error. @@ -3126,23 +3192,22 @@ OPENSSL_EXPORT UniquePtr SSL_SESSION_parse( CBS *cbs, const SSL_X509_METHOD *x509_method, CRYPTO_BUFFER_POOL *pool); // ssl_session_serialize writes |in| to |cbb| as if it were serialising a -// session for Session-ID resumption. It returns one on success and zero on +// session for Session-ID resumption. It returns true on success and false on // error. -OPENSSL_EXPORT int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); +OPENSSL_EXPORT bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); -// ssl_session_is_context_valid returns one if |session|'s session ID context -// matches the one set on |hs| and zero otherwise. -int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session); +// ssl_session_is_context_valid returns whether |session|'s session ID context +// matches the one set on |hs|. +bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); -// ssl_session_is_time_valid returns one if |session| is still valid and zero if -// it has expired. -int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); +// ssl_session_is_time_valid returns true if |session| is still valid and false +// if it has expired. +bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); -// ssl_session_is_resumable returns one if |session| is resumable for |hs| and -// zero otherwise. -int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session); +// ssl_session_is_resumable returns whether |session| is resumable for |hs|. +bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); // ssl_session_protocol_version returns the protocol version associated with // |session|. Note that despite the name, this is not the same as @@ -3205,8 +3270,8 @@ ssl_open_record_t tls_open_app_data(SSL *ssl, Span *out, ssl_open_record_t tls_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, uint8_t *out_alert, Span in); -int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, - int len); +int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, + size_t *out_bytes_written, Span in); bool tls_new(SSL *ssl); void tls_free(SSL *ssl); @@ -3239,11 +3304,11 @@ ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, Span in); int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, - const uint8_t *buf, int len); + size_t *out_bytes_written, Span in); // dtls1_write_record sends a record. It returns one on success and <= 0 on // error. -int dtls1_write_record(SSL *ssl, int type, const uint8_t *buf, size_t len, +int dtls1_write_record(SSL *ssl, int type, Span in, enum dtls1_use_epoch_t use_epoch); int dtls1_retransmit_outgoing_messages(SSL *ssl); @@ -3292,17 +3357,6 @@ bool tls1_check_group_id(const SSL_HANDSHAKE *ssl, uint16_t group_id); // found, it returns false. bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id); -// tls1_set_curves converts the array of NIDs in |curves| into a newly allocated -// array of TLS group IDs. On success, the function returns true and writes the -// array to |*out_group_ids|. Otherwise, it returns false. -bool tls1_set_curves(Array *out_group_ids, Span curves); - -// tls1_set_curves_list converts the string of curves pointed to by |curves| -// into a newly allocated array of TLS group IDs. On success, the function -// returns true and writes the array to |*out_group_ids|. Otherwise, it returns -// false. -bool tls1_set_curves_list(Array *out_group_ids, const char *curves); - // ssl_add_clienthello_tlsext writes ClientHello extensions to |out| for |type|. // It returns true on success and false on failure. The |header_len| argument is // the length of the ClientHello written so far and is used to compute the @@ -3422,6 +3476,11 @@ struct ssl_ctx_st { // and is further constrainted by |SSL_OP_NO_*|. uint16_t conf_min_version = 0; + // num_tickets is the number of tickets to send immediately after the TLS 1.3 + // handshake. TLS 1.3 recommends single-use tickets so, by default, issue two + /// in case the client makes several connections before getting a renewal. + uint8_t num_tickets = 2; + // quic_method is the method table corresponding to the QUIC hooks. const SSL_QUIC_METHOD *quic_method = nullptr; @@ -3511,7 +3570,7 @@ struct ssl_ctx_st { bssl::UniquePtr cert; // callback that allows applications to peek at protocol messages - void (*msg_callback)(int write_p, int version, int content_type, + void (*msg_callback)(int is_write, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) = nullptr; void *msg_callback_arg = nullptr; @@ -3643,6 +3702,10 @@ struct ssl_ctx_st { int (*legacy_ocsp_callback)(SSL *ssl, void *arg) = nullptr; void *legacy_ocsp_callback_arg = nullptr; + // tls13_cipher_policy limits the set of ciphers that can be selected when + // negotiating a TLS 1.3 connection. + enum ssl_compliance_policy_t tls13_cipher_policy = ssl_compliance_policy_none; + // verify_sigalgs, if not empty, is the set of signature algorithms // accepted from the peer in decreasing order of preference. bssl::Array verify_sigalgs; @@ -3690,6 +3753,15 @@ struct ssl_ctx_st { // If enable_early_data is true, early data can be sent and accepted. bool enable_early_data : 1; + // aes_hw_override if set indicates we should override checking for AES + // hardware support, and use the value in aes_hw_override_value instead. + bool aes_hw_override : 1; + + // aes_hw_override_value is used for testing to indicate the support or lack + // of support for AES hardware. The value is only considered if + // |aes_hw_override| is true. + bool aes_hw_override_value : 1; + private: ~ssl_ctx_st(); friend OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *); @@ -3806,11 +3878,11 @@ struct ssl_session_st { // session. In TLS 1.3 and up, it is the resumption PSK for sessions handed to // the caller, but it stores the resumption secret when stored on |SSL| // objects. - int secret_length = 0; + uint8_t secret_length = 0; uint8_t secret[SSL_MAX_MASTER_KEY_LENGTH] = {0}; // session_id - valid? - unsigned session_id_length = 0; + uint8_t session_id_length = 0; uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; // this is used to determine whether the session is being reused in // the appropriate context. It is up to the application to set this, diff --git a/third_party/boringssl/kit/src/ssl/s3_both.cc b/third_party/boringssl/kit/src/ssl/s3_both.cc index cddeb3fe..6d33c6d7 100644 --- a/third_party/boringssl/kit/src/ssl/s3_both.cc +++ b/third_party/boringssl/kit/src/ssl/s3_both.cc @@ -439,7 +439,6 @@ static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, // No session id. !CBB_add_u8(&hello_body, 0) || !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_open_record_error; } @@ -664,41 +663,72 @@ void tls_next_message(SSL *ssl) { // the client. class CipherScorer { public: - CipherScorer(uint16_t group_id) - : aes_is_fine_(EVP_has_aes_hardware()), - security_128_is_fine_(group_id != SSL_CURVE_CECPQ2) {} + CipherScorer(bool has_aes_hw) : aes_is_fine_(has_aes_hw) {} - typedef std::tuple Score; + typedef std::tuple Score; // MinScore returns a |Score| that will compare less than the score of all // cipher suites. Score MinScore() const { - return Score(false, false, false); + return Score(false, false); } Score Evaluate(const SSL_CIPHER *a) const { return Score( // Something is always preferable to nothing. true, - // Either 128-bit is fine, or 256-bit is preferred. - security_128_is_fine_ || a->algorithm_enc != SSL_AES128GCM, // Either AES is fine, or else ChaCha20 is preferred. aes_is_fine_ || a->algorithm_enc == SSL_CHACHA20POLY1305); } private: const bool aes_is_fine_; - const bool security_128_is_fine_; }; -const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, - uint16_t group_id) { +bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id, + enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_none: + return true; + + case ssl_compliance_policy_fips_202205: + switch (cipher_id) { + case TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff: + case TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff: + return true; + case TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff: + return false; + default: + assert(false); + return false; + } + + case ssl_compliance_policy_wpa3_192_202304: + switch (cipher_id) { + case TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff: + return true; + case TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff: + case TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff: + return false; + default: + assert(false); + return false; + } + } + + assert(false); + return false; +} + +const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw, + uint16_t version, uint16_t group_id, + enum ssl_compliance_policy_t policy) { if (CBS_len(&cipher_suites) % 2 != 0) { return nullptr; } const SSL_CIPHER *best = nullptr; - CipherScorer scorer(group_id); + CipherScorer scorer(has_aes_hw); CipherScorer::Score best_score = scorer.MinScore(); while (CBS_len(&cipher_suites) > 0) { @@ -715,6 +745,11 @@ const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, uint16_t version, continue; } + if (!ssl_tls13_cipher_meets_policy(SSL_CIPHER_get_protocol_id(candidate), + policy)) { + continue; + } + const CipherScorer::Score candidate_score = scorer.Evaluate(candidate); // |candidate_score| must be larger to displace the current choice. That way // the client's order controls between ciphers with an equal score. diff --git a/third_party/boringssl/kit/src/ssl/s3_lib.cc b/third_party/boringssl/kit/src/ssl/s3_lib.cc index fa73d34a..8e8a034e 100644 --- a/third_party/boringssl/kit/src/ssl/s3_lib.cc +++ b/third_party/boringssl/kit/src/ssl/s3_lib.cc @@ -175,11 +175,11 @@ SSL3_STATE::SSL3_STATE() send_connection_binding(false), channel_id_valid(false), key_update_pending(false), - wpend_pending(false), early_data_accepted(false), alert_dispatch(false), renegotiate_pending(false), - used_hello_retry_request(false) {} + used_hello_retry_request(false), + was_key_usage_invalid(false) {} SSL3_STATE::~SSL3_STATE() {} diff --git a/third_party/boringssl/kit/src/ssl/s3_pkt.cc b/third_party/boringssl/kit/src/ssl/s3_pkt.cc index 450f7dc0..bc0d13dd 100644 --- a/third_party/boringssl/kit/src/ssl/s3_pkt.cc +++ b/third_party/boringssl/kit/src/ssl/s3_pkt.cc @@ -126,10 +126,11 @@ BSSL_NAMESPACE_BEGIN -static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len); +static int do_tls_write(SSL *ssl, size_t *out_bytes_written, uint8_t type, + Span in); -int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, - int len) { +int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, + size_t *out_bytes_written, Span in) { assert(ssl_can_write(ssl)); assert(!ssl->s3->aead_write_ctx->is_null_cipher()); @@ -140,33 +141,28 @@ int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, return -1; } - // TODO(davidben): Switch this logic to |size_t| and |bssl::Span|. - assert(ssl->s3->wnum <= INT_MAX); - unsigned tot = ssl->s3->wnum; - ssl->s3->wnum = 0; - - // Ensure that if we end up with a smaller value of data to write out than - // the the original len from a write which didn't complete for non-blocking - // I/O and also somehow ended up avoiding the check for this in - // tls_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be possible to - // end up with (len-tot) as a large number that will then promptly send - // beyond the end of the users buffer ... so we trap and report the error in - // a way the user will notice. - if (len < 0 || (size_t)len < tot) { + size_t total_bytes_written = ssl->s3->unreported_bytes_written; + if (in.size() < total_bytes_written) { + // This can happen if the caller disables |SSL_MODE_ENABLE_PARTIAL_WRITE|, + // asks us to write some input of length N, we successfully encrypt M bytes + // and write it, but fail to write the rest. We will report + // |SSL_ERROR_WANT_WRITE|. If the caller then retries with fewer than M + // bytes, we cannot satisfy that request. The caller is required to always + // retry with at least as many bytes as the previous attempt. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); return -1; } - const int is_early_data_write = - !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; + in = in.subspan(total_bytes_written); - unsigned n = len - tot; + const bool is_early_data_write = + !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; for (;;) { size_t max_send_fragment = ssl->max_send_fragment; if (is_early_data_write) { SSL_HANDSHAKE *hs = ssl->s3->hs.get(); if (hs->early_data_written >= hs->early_session->ticket_max_early_data) { - ssl->s3->wnum = tot; + ssl->s3->unreported_bytes_written = total_bytes_written; hs->can_early_write = false; *out_needs_handshake = true; return -1; @@ -176,53 +172,63 @@ int tls_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, hs->early_data_written}); } - const size_t nw = std::min(max_send_fragment, size_t{n}); - int ret = do_tls_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw); + const size_t to_write = std::min(max_send_fragment, in.size()); + size_t bytes_written; + int ret = do_tls_write(ssl, &bytes_written, SSL3_RT_APPLICATION_DATA, + in.subspan(0, to_write)); if (ret <= 0) { - ssl->s3->wnum = tot; + ssl->s3->unreported_bytes_written = total_bytes_written; return ret; } + // Note |bytes_written| may be less than |to_write| if there was a pending + // record from a smaller write attempt. + assert(bytes_written <= to_write); + total_bytes_written += bytes_written; + in = in.subspan(bytes_written); if (is_early_data_write) { - ssl->s3->hs->early_data_written += ret; + ssl->s3->hs->early_data_written += bytes_written; } - if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { - return tot + ret; + if (in.empty() || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + ssl->s3->unreported_bytes_written = 0; + *out_bytes_written = total_bytes_written; + return 1; } - - n -= ret; - tot += ret; } } -static int tls_write_pending(SSL *ssl, int type, const uint8_t *in, - unsigned int len) { - if (ssl->s3->wpend_tot > (int)len || - (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && - ssl->s3->wpend_buf != in) || - ssl->s3->wpend_type != type) { +// do_tls_write writes an SSL record of the given type. On success, it sets +// |*out_bytes_written| to number of bytes successfully written and returns one. +// On error, it returns a value <= 0 from the underlying |BIO|. +static int do_tls_write(SSL *ssl, size_t *out_bytes_written, uint8_t type, + Span in) { + // If there is a pending write, the retry must be consistent. + if (!ssl->s3->pending_write.empty() && + (ssl->s3->pending_write.size() > in.size() || + (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && + ssl->s3->pending_write.data() != in.data()) || + ssl->s3->pending_write_type != type)) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); return -1; } + // Flush any unwritten data to the transport. There may be data to flush even + // if |wpend_tot| is zero. int ret = ssl_write_buffer_flush(ssl); if (ret <= 0) { return ret; } - ssl->s3->wpend_pending = false; - return ssl->s3->wpend_ret; -} -// do_tls_write writes an SSL record of the given type. -static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { - // If there is still data from the previous record, flush it. - if (ssl->s3->wpend_pending) { - return tls_write_pending(ssl, type, in, len); + // If there is a pending write, we just completed it. Report it to the caller. + if (!ssl->s3->pending_write.empty()) { + *out_bytes_written = ssl->s3->pending_write.size(); + ssl->s3->pending_write = {}; + return 1; } SSLBuffer *buf = &ssl->s3->write_buffer; - if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { + if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } @@ -231,16 +237,22 @@ static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { return -1; } - size_t flight_len = 0; + // We may have unflushed handshake data that must be written before |in|. This + // may be a KeyUpdate acknowledgment, 0-RTT key change messages, or a + // NewSessionTicket. + Span pending_flight; if (ssl->s3->pending_flight != nullptr) { - flight_len = - ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset; + pending_flight = MakeConstSpan( + reinterpret_cast(ssl->s3->pending_flight->data), + ssl->s3->pending_flight->length); + pending_flight = pending_flight.subspan(ssl->s3->pending_flight_offset); } - size_t max_out = flight_len; - if (len > 0) { - const size_t max_ciphertext_len = len + SSL_max_seal_overhead(ssl); - if (max_ciphertext_len < len || max_out + max_ciphertext_len < max_out) { + size_t max_out = pending_flight.size(); + if (!in.empty()) { + const size_t max_ciphertext_len = in.size() + SSL_max_seal_overhead(ssl); + if (max_ciphertext_len < in.size() || + max_out + max_ciphertext_len < max_out) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return -1; } @@ -248,31 +260,29 @@ static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { } if (max_out == 0) { - return 0; + // Nothing to write. + *out_bytes_written = 0; + return 1; } - if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) { + if (!buf->EnsureCap(pending_flight.size() + ssl_seal_align_prefix_len(ssl), + max_out)) { return -1; } - // Add any unflushed handshake data as a prefix. This may be a KeyUpdate - // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear - // when data is added to |write_buffer| or it will be written in the wrong - // order. - if (ssl->s3->pending_flight != nullptr) { - OPENSSL_memcpy( - buf->remaining().data(), - ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, - flight_len); + // Copy |pending_flight| to the output. + if (!pending_flight.empty()) { + OPENSSL_memcpy(buf->remaining().data(), pending_flight.data(), + pending_flight.size()); ssl->s3->pending_flight.reset(); ssl->s3->pending_flight_offset = 0; - buf->DidWrite(flight_len); + buf->DidWrite(pending_flight.size()); } - if (len > 0) { + if (!in.empty()) { size_t ciphertext_len; if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, - buf->remaining().size(), type, in, len)) { + buf->remaining().size(), type, in.data(), in.size())) { return -1; } buf->DidWrite(ciphertext_len); @@ -282,16 +292,19 @@ static int do_tls_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { // acknowledgments. ssl->s3->key_update_pending = false; - // Memorize arguments so that tls_write_pending can detect bad write retries - // later. - ssl->s3->wpend_tot = len; - ssl->s3->wpend_buf = in; - ssl->s3->wpend_type = type; - ssl->s3->wpend_ret = len; - ssl->s3->wpend_pending = true; + // Flush the write buffer. + ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + // Track the unfinished write. + if (!in.empty()) { + ssl->s3->pending_write = in; + ssl->s3->pending_write_type = type; + } + return ret; + } - // We now just need to write the buffer. - return tls_write_pending(ssl, type, in, len); + *out_bytes_written = in.size(); + return 1; } ssl_open_record_t tls_open_app_data(SSL *ssl, Span *out, @@ -429,10 +442,13 @@ int tls_dispatch_alert(SSL *ssl) { return 0; } } else { - int ret = do_tls_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); + size_t bytes_written; + int ret = + do_tls_write(ssl, &bytes_written, SSL3_RT_ALERT, ssl->s3->send_alert); if (ret <= 0) { return ret; } + assert(bytes_written == 2); } ssl->s3->alert_dispatch = false; diff --git a/third_party/boringssl/kit/src/ssl/ssl_aead_ctx.cc b/third_party/boringssl/kit/src/ssl/ssl_aead_ctx.cc index 0bad2661..25569221 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_aead_ctx.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_aead_ctx.cc @@ -91,7 +91,6 @@ UniquePtr SSLAEADContext::Create( UniquePtr aead_ctx = MakeUnique(version, is_dtls, cipher); if (!aead_ctx) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -220,13 +219,13 @@ size_t SSLAEADContext::MaxOverhead() const { } Span SSLAEADContext::GetAdditionalData( - uint8_t storage[13], uint8_t type, uint16_t record_version, - const uint8_t seqnum[8], size_t plaintext_len, Span header) { + uint8_t storage[13], uint8_t type, uint16_t record_version, uint64_t seqnum, + size_t plaintext_len, Span header) { if (ad_is_header_) { return header; } - OPENSSL_memcpy(storage, seqnum, 8); + CRYPTO_store_u64_be(storage, seqnum); size_t len = 8; storage[len++] = type; storage[len++] = static_cast((record_version >> 8)); @@ -239,7 +238,7 @@ Span SSLAEADContext::GetAdditionalData( } bool SSLAEADContext::Open(Span *out, uint8_t type, - uint16_t record_version, const uint8_t seqnum[8], + uint16_t record_version, uint64_t seqnum, Span header, Span in) { if (is_null_cipher() || FUZZER_MODE) { // Handle the initial NULL cipher. @@ -288,7 +287,7 @@ bool SSLAEADContext::Open(Span *out, uint8_t type, in = in.subspan(variable_nonce_len_); } else { assert(variable_nonce_len_ == 8); - OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + CRYPTO_store_u64_be(nonce + nonce_len, seqnum); } nonce_len += variable_nonce_len_; @@ -313,8 +312,7 @@ bool SSLAEADContext::Open(Span *out, uint8_t type, bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix, uint8_t type, - uint16_t record_version, - const uint8_t seqnum[8], + uint16_t record_version, uint64_t seqnum, Span header, const uint8_t *in, size_t in_len, const uint8_t *extra_in, size_t extra_in_len) { @@ -365,7 +363,7 @@ bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, // When sending we use the sequence number as the variable part of the // nonce. assert(variable_nonce_len_ == 8); - OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + CRYPTO_store_u64_be(nonce + nonce_len, seqnum); } nonce_len += variable_nonce_len_; @@ -398,7 +396,7 @@ bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len, uint8_t type, uint16_t record_version, - const uint8_t seqnum[8], Span header, + uint64_t seqnum, Span header, const uint8_t *in, size_t in_len) { const size_t prefix_len = ExplicitNonceLen(); size_t suffix_len; diff --git a/third_party/boringssl/kit/src/ssl/ssl_asn1.cc b/third_party/boringssl/kit/src/ssl/ssl_asn1.cc index 27bc3103..3311246c 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_asn1.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_asn1.cc @@ -150,57 +150,57 @@ BSSL_NAMESPACE_BEGIN static const unsigned kVersion = 1; -static const unsigned kTimeTag = +static const CBS_ASN1_TAG kTimeTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -static const unsigned kTimeoutTag = +static const CBS_ASN1_TAG kTimeoutTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; -static const unsigned kPeerTag = +static const CBS_ASN1_TAG kPeerTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; -static const unsigned kSessionIDContextTag = +static const CBS_ASN1_TAG kSessionIDContextTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4; -static const unsigned kVerifyResultTag = +static const CBS_ASN1_TAG kVerifyResultTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5; -static const unsigned kHostNameTag = +static const CBS_ASN1_TAG kHostNameTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6; -static const unsigned kPSKIdentityTag = +static const CBS_ASN1_TAG kPSKIdentityTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8; -static const unsigned kTicketLifetimeHintTag = +static const CBS_ASN1_TAG kTicketLifetimeHintTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9; -static const unsigned kTicketTag = +static const CBS_ASN1_TAG kTicketTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10; -static const unsigned kPeerSHA256Tag = +static const CBS_ASN1_TAG kPeerSHA256Tag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13; -static const unsigned kOriginalHandshakeHashTag = +static const CBS_ASN1_TAG kOriginalHandshakeHashTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14; -static const unsigned kSignedCertTimestampListTag = +static const CBS_ASN1_TAG kSignedCertTimestampListTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15; -static const unsigned kOCSPResponseTag = +static const CBS_ASN1_TAG kOCSPResponseTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16; -static const unsigned kExtendedMasterSecretTag = +static const CBS_ASN1_TAG kExtendedMasterSecretTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17; -static const unsigned kGroupIDTag = +static const CBS_ASN1_TAG kGroupIDTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18; -static const unsigned kCertChainTag = +static const CBS_ASN1_TAG kCertChainTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19; -static const unsigned kTicketAgeAddTag = +static const CBS_ASN1_TAG kTicketAgeAddTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; -static const unsigned kIsServerTag = +static const CBS_ASN1_TAG kIsServerTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; -static const unsigned kPeerSignatureAlgorithmTag = +static const CBS_ASN1_TAG kPeerSignatureAlgorithmTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23; -static const unsigned kTicketMaxEarlyDataTag = +static const CBS_ASN1_TAG kTicketMaxEarlyDataTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24; -static const unsigned kAuthTimeoutTag = +static const CBS_ASN1_TAG kAuthTimeoutTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25; -static const unsigned kEarlyALPNTag = +static const CBS_ASN1_TAG kEarlyALPNTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; -static const unsigned kIsQuicTag = +static const CBS_ASN1_TAG kIsQuicTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27; -static const unsigned kQuicEarlyDataContextTag = +static const CBS_ASN1_TAG kQuicEarlyDataContextTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28; -static const unsigned kLocalALPSTag = +static const CBS_ASN1_TAG kLocalALPSTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 29; -static const unsigned kPeerALPSTag = +static const CBS_ASN1_TAG kPeerALPSTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 30; static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, @@ -223,7 +223,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_uint64(&child, in->time) || !CBB_add_asn1(&session, &child, kTimeoutTag) || !CBB_add_asn1_uint64(&child, in->timeout)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -234,7 +233,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kPeerTag) || !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -243,14 +241,12 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, // historically always encoded the sid_ctx. if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || !CBB_add_asn1_octet_string(&child, in->sid_ctx, in->sid_ctx_length)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->verify_result != X509_V_OK) { if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || !CBB_add_asn1_uint64(&child, in->verify_result)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -260,7 +256,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->psk_identity.get(), strlen(in->psk_identity.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -268,7 +263,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->ticket_lifetime_hint > 0) { if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || !CBB_add_asn1_uint64(&child, in->ticket_lifetime_hint)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -277,7 +271,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kTicketTag) || !CBB_add_asn1_octet_string(&child, in->ticket.data(), in->ticket.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -286,7 +279,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || !CBB_add_asn1_octet_string(&child, in->peer_sha256, sizeof(in->peer_sha256))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -295,7 +287,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || !CBB_add_asn1_octet_string(&child, in->original_handshake_hash, in->original_handshake_hash_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -305,7 +296,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string( &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list.get()), CRYPTO_BUFFER_len(in->signed_cert_timestamp_list.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -315,7 +305,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1_octet_string( &child, CRYPTO_BUFFER_data(in->ocsp_response.get()), CRYPTO_BUFFER_len(in->ocsp_response.get()))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -323,7 +312,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->extended_master_secret) { if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || !CBB_add_asn1_bool(&child, true)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -331,7 +319,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->group_id > 0 && (!CBB_add_asn1(&session, &child, kGroupIDTag) || !CBB_add_asn1_uint64(&child, in->group_id))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -341,14 +328,12 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !in->peer_sha256_valid && sk_CRYPTO_BUFFER_num(in->certs.get()) >= 2) { if (!CBB_add_asn1(&session, &child, kCertChainTag)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs.get()); i++) { const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), i); if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -358,7 +343,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_u32(&child2, in->ticket_age_add)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -366,7 +350,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!in->is_server) { if (!CBB_add_asn1(&session, &child, kIsServerTag) || !CBB_add_asn1_bool(&child, false)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -374,21 +357,18 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->peer_signature_algorithm != 0 && (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->ticket_max_early_data != 0 && (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (in->timeout != in->auth_timeout && (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || !CBB_add_asn1_uint64(&child, in->auth_timeout))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -396,7 +376,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || !CBB_add_asn1_octet_string(&child, in->early_alpn.data(), in->early_alpn.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -404,7 +383,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (in->is_quic) { if (!CBB_add_asn1(&session, &child, kIsQuicTag) || !CBB_add_asn1_bool(&child, true)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -413,7 +391,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, if (!CBB_add_asn1(&session, &child, kQuicEarlyDataContextTag) || !CBB_add_asn1_octet_string(&child, in->quic_early_data_context.data(), in->quic_early_data_context.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -426,7 +403,6 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, !CBB_add_asn1(&session, &child, kPeerALPSTag) || !CBB_add_asn1_octet_string(&child, in->peer_application_settings.data(), in->peer_application_settings.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } } @@ -438,7 +414,8 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, // tagged with |tag| from |cbs| and saves it in |*out|. If the element was not // found, it sets |*out| to NULL. It returns one on success, whether or not the // element was found, and zero on decode error. -static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag) { +static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, + CBS_ASN1_TAG tag) { CBS value; int present; if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) { @@ -452,7 +429,6 @@ static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag } char *raw = nullptr; if (!CBS_strdup(&value, &raw)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } out->reset(raw); @@ -466,7 +442,7 @@ static int SSL_SESSION_parse_string(CBS *cbs, UniquePtr *out, unsigned tag // tagged with |tag| from |cbs| and stows it in |*out|. It returns one on // success, whether or not the element was found, and zero on decode error. static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array *out, - unsigned tag) { + CBS_ASN1_TAG tag) { CBS value; if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) { OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); @@ -477,7 +453,7 @@ static bool SSL_SESSION_parse_octet_string(CBS *cbs, Array *out, static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, UniquePtr *out, - unsigned tag, + CBS_ASN1_TAG tag, CRYPTO_BUFFER_POOL *pool) { if (!CBS_peek_asn1_tag(cbs, tag)) { return 1; @@ -492,7 +468,6 @@ static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, } out->reset(CRYPTO_BUFFER_new_from_CBS(&value, pool)); if (*out == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -500,8 +475,10 @@ static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, // SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING // explicitly tagged with |tag| of size at most |max_out|. -static int SSL_SESSION_parse_bounded_octet_string( - CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) { +static int SSL_SESSION_parse_bounded_octet_string(CBS *cbs, uint8_t *out, + uint8_t *out_len, + uint8_t max_out, + CBS_ASN1_TAG tag) { CBS value; if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) || CBS_len(&value) > max_out) { @@ -509,11 +486,11 @@ static int SSL_SESSION_parse_bounded_octet_string( return 0; } OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value)); - *out_len = (uint8_t)CBS_len(&value); + *out_len = static_cast(CBS_len(&value)); return 1; } -static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, +static int SSL_SESSION_parse_long(CBS *cbs, long *out, CBS_ASN1_TAG tag, long default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -526,7 +503,7 @@ static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, return 1; } -static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, +static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, CBS_ASN1_TAG tag, uint32_t default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -539,7 +516,7 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, return 1; } -static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag, +static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, CBS_ASN1_TAG tag, uint16_t default_value) { uint64_t value; if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, @@ -601,9 +578,13 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, return nullptr; } OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id)); - ret->session_id_length = CBS_len(&session_id); + static_assert(SSL3_MAX_SSL_SESSION_ID_LENGTH <= UINT8_MAX, + "max session ID is too large"); + ret->session_id_length = static_cast(CBS_len(&session_id)); OPENSSL_memcpy(ret->secret, CBS_data(&secret), CBS_len(&secret)); - ret->secret_length = CBS_len(&secret); + static_assert(SSL_MAX_MASTER_KEY_LENGTH <= UINT8_MAX, + "max secret is too large"); + ret->secret_length = static_cast(CBS_len(&secret)); CBS child; uint64_t timeout; @@ -662,9 +643,9 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, } OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256), sizeof(ret->peer_sha256)); - ret->peer_sha256_valid = 1; + ret->peer_sha256_valid = true; } else { - ret->peer_sha256_valid = 0; + ret->peer_sha256_valid = false; } if (!SSL_SESSION_parse_bounded_octet_string( @@ -709,7 +690,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, if (has_peer || has_cert_chain) { ret->certs.reset(sk_CRYPTO_BUFFER_new_null()); if (ret->certs == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -717,7 +697,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool)); if (!buffer || !PushToStack(ret->certs.get(), std::move(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -733,7 +712,6 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&cert, pool)); if (buffer == nullptr || !PushToStack(ret->certs.get(), std::move(buffer))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } @@ -808,7 +786,7 @@ UniquePtr SSL_SESSION_parse(CBS *cbs, return ret; } -int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { +bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { return SSL_SESSION_to_bytes_full(in, cbb, 0); } diff --git a/third_party/boringssl/kit/src/ssl/ssl_buffer.cc b/third_party/boringssl/kit/src/ssl/ssl_buffer.cc index d73055fb..2ca14efa 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_buffer.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_buffer.cc @@ -232,6 +232,7 @@ int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, return 1; case ssl_open_record_close_notify: + ssl->s3->rwstate = SSL_ERROR_ZERO_RETURN; return 0; case ssl_open_record_error: diff --git a/third_party/boringssl/kit/src/ssl/ssl_cert.cc b/third_party/boringssl/kit/src/ssl/ssl_cert.cc index 68e010ad..aa46a8bb 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_cert.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_cert.cc @@ -142,9 +142,9 @@ CERT::~CERT() { x509_method->cert_free(this); } -static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) { - CRYPTO_BUFFER_up_ref(buffer); - return buffer; +static CRYPTO_BUFFER *buffer_up_ref(const CRYPTO_BUFFER *buffer) { + CRYPTO_BUFFER_up_ref(const_cast(buffer)); + return const_cast(buffer); } UniquePtr ssl_cert_dup(CERT *cert) { @@ -237,14 +237,14 @@ static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey( return leaf_cert_and_privkey_error; } - if (!ssl_is_key_type_supported(pubkey->type)) { + if (!ssl_is_key_type_supported(EVP_PKEY_id(pubkey.get()))) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return leaf_cert_and_privkey_error; } // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA // certificates, so sanity-check the key usage extension. - if (pubkey->type == EVP_PKEY_EC && + if (EVP_PKEY_id(pubkey.get()) == EVP_PKEY_EC && !ssl_cert_check_key_usage(&cert_cbs, key_usage_digital_signature)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return leaf_cert_and_privkey_error; @@ -365,7 +365,6 @@ bool ssl_parse_cert_chain(uint8_t *out_alert, UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); if (!chain) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -397,7 +396,6 @@ bool ssl_parse_cert_chain(uint8_t *out_alert, if (!buf || !PushToStack(chain.get(), std::move(buf))) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -623,7 +621,6 @@ UniquePtr ssl_parse_client_CA_list(SSL *ssl, UniquePtr ret(sk_CRYPTO_BUFFER_new_null()); if (!ret) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } @@ -647,7 +644,6 @@ UniquePtr ssl_parse_client_CA_list(SSL *ssl, if (!buffer || !PushToStack(ret.get(), std::move(buffer))) { *out_alert = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return nullptr; } } diff --git a/third_party/boringssl/kit/src/ssl/ssl_cipher.cc b/third_party/boringssl/kit/src/ssl/ssl_cipher.cc index 60b3e2c7..6f209898 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_cipher.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_cipher.cc @@ -157,17 +157,6 @@ BSSL_NAMESPACE_BEGIN static constexpr SSL_CIPHER kCiphers[] = { // The RSA ciphers - // Cipher 02 - { - SSL3_TXT_RSA_NULL_SHA, - "TLS_RSA_WITH_NULL_SHA", - SSL3_CK_RSA_NULL_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_SHA1, - SSL_HANDSHAKE_MAC_DEFAULT, - }, // Cipher 0A { @@ -264,9 +253,9 @@ static constexpr SSL_CIPHER kCiphers[] = { // Cipher 1301 { - TLS1_TXT_AES_128_GCM_SHA256, + TLS1_3_RFC_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", - TLS1_CK_AES_128_GCM_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, SSL_kGENERIC, SSL_aGENERIC, SSL_AES128GCM, @@ -276,9 +265,9 @@ static constexpr SSL_CIPHER kCiphers[] = { // Cipher 1302 { - TLS1_TXT_AES_256_GCM_SHA384, + TLS1_3_RFC_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", - TLS1_CK_AES_256_GCM_SHA384, + TLS1_3_CK_AES_256_GCM_SHA384, SSL_kGENERIC, SSL_aGENERIC, SSL_AES256GCM, @@ -288,9 +277,9 @@ static constexpr SSL_CIPHER kCiphers[] = { // Cipher 1303 { - TLS1_TXT_CHACHA20_POLY1305_SHA256, + TLS1_3_RFC_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", - TLS1_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, SSL_kGENERIC, SSL_aGENERIC, SSL_CHACHA20POLY1305, @@ -346,6 +335,18 @@ static constexpr SSL_CIPHER kCiphers[] = { SSL_HANDSHAKE_MAC_DEFAULT, }, + // Cipher C027 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + // GCM based TLS v1.2 ciphersuites from RFC 5289 // Cipher C02B @@ -466,6 +467,16 @@ Span AllCiphers() { return MakeConstSpan(kCiphers, OPENSSL_ARRAY_SIZE(kCiphers)); } +static constexpr size_t NumTLS13Ciphers() { + size_t num = 0; + for (const auto &cipher : kCiphers) { + if (cipher.algorithm_mkey == SSL_kGENERIC) { + num++; + } + } + return num; +} + #define CIPHER_ADD 1 #define CIPHER_KILL 2 #define CIPHER_DEL 3 @@ -481,24 +492,26 @@ typedef struct cipher_order_st { typedef struct cipher_alias_st { // name is the name of the cipher alias. - const char *name; + const char *name = nullptr; // The following fields are bitmasks for the corresponding fields on // |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the // bit corresponding to the cipher's value is set to 1. If any bitmask is // all zeroes, the alias matches nothing. Use |~0u| for the default value. - uint32_t algorithm_mkey; - uint32_t algorithm_auth; - uint32_t algorithm_enc; - uint32_t algorithm_mac; + uint32_t algorithm_mkey = ~0u; + uint32_t algorithm_auth = ~0u; + uint32_t algorithm_enc = ~0u; + uint32_t algorithm_mac = ~0u; // min_version, if non-zero, matches all ciphers which were added in that // particular protocol version. - uint16_t min_version; + uint16_t min_version = 0; + + // include_deprecated, if true, means this alias includes deprecated ciphers. + bool include_deprecated = false; } CIPHER_ALIAS; static const CIPHER_ALIAS kCipherAliases[] = { - // "ALL" doesn't include eNULL. It must be explicitly enabled. {"ALL", ~0u, ~0u, ~0u, ~0u, 0}, // The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. @@ -527,12 +540,16 @@ static const CIPHER_ALIAS kCipherAliases[] = { {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0}, // symmetric encryption aliases - {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0}, - {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0}, - {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0}, + {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0, /*include_deprecated=*/true}, + {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0, + /*include_deprecated=*/false}, + {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0, + /*include_deprecated=*/false}, {"AES", ~0u, ~0u, SSL_AES, ~0u, 0}, - {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0}, - {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0}, + {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0, + /*include_deprecated=*/false}, + {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, + /*include_deprecated=*/false}, // MAC aliases {"SHA1", ~0u, ~0u, ~0u, SSL_SHA1, 0}, @@ -599,9 +616,7 @@ bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, *out_fixed_iv_len = EVP_AEAD_nonce_length(*out_aead); } } else if (cipher->algorithm_mac == SSL_SHA1) { - if (cipher->algorithm_enc == SSL_eNULL) { - *out_aead = EVP_aead_null_sha1_tls(); - } else if (cipher->algorithm_enc == SSL_3DES) { + if (cipher->algorithm_enc == SSL_3DES) { if (version == TLS1_VERSION) { *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(); *out_fixed_iv_len = 8; @@ -627,6 +642,14 @@ bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, } *out_mac_secret_len = SHA_DIGEST_LENGTH; + } else if (cipher->algorithm_mac == SSL_SHA256) { + if (cipher->algorithm_enc == SSL_AES128) { + *out_aead = EVP_aead_aes_128_cbc_sha256_tls(); + } else { + return false; + } + + *out_mac_secret_len = SHA256_DIGEST_LENGTH; } else { return false; } @@ -703,54 +726,6 @@ static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, *head = curr; } -static bool ssl_cipher_collect_ciphers(Array *out_co_list, - CIPHER_ORDER **out_head, - CIPHER_ORDER **out_tail) { - Array co_list; - if (!co_list.Init(OPENSSL_ARRAY_SIZE(kCiphers))) { - return false; - } - - size_t co_list_num = 0; - for (const SSL_CIPHER &cipher : kCiphers) { - // TLS 1.3 ciphers do not participate in this mechanism. - if (cipher.algorithm_mkey != SSL_kGENERIC) { - co_list[co_list_num].cipher = &cipher; - co_list[co_list_num].next = NULL; - co_list[co_list_num].prev = NULL; - co_list[co_list_num].active = false; - co_list[co_list_num].in_group = false; - co_list_num++; - } - } - - // Prepare linked list from list entries. - if (co_list_num > 0) { - co_list[0].prev = NULL; - - if (co_list_num > 1) { - co_list[0].next = &co_list[1]; - - for (size_t i = 1; i < co_list_num - 1; i++) { - co_list[i].prev = &co_list[i - 1]; - co_list[i].next = &co_list[i + 1]; - } - - co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; - } - - co_list[co_list_num - 1].next = NULL; - - *out_head = &co_list[0]; - *out_tail = &co_list[co_list_num - 1]; - } else { - *out_head = nullptr; - *out_tail = nullptr; - } - *out_co_list = std::move(co_list); - return true; -} - SSLCipherPreferenceList::~SSLCipherPreferenceList() { OPENSSL_free(in_group_flags); } @@ -797,6 +772,11 @@ void SSLCipherPreferenceList::Remove(const SSL_CIPHER *cipher) { sk_SSL_CIPHER_delete(ciphers.get(), index); } +bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher) { + return cipher->id == TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 || + cipher->algorithm_enc == SSL_3DES; +} + // ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its // parameters in the linked list from |*head_p| to |*tail_p|. It writes the new // head and tail of the list to |*head_p| and |*tail_p|, respectively. @@ -804,19 +784,19 @@ void SSLCipherPreferenceList::Remove(const SSL_CIPHER *cipher) { // - If |cipher_id| is non-zero, only that cipher is selected. // - Otherwise, if |strength_bits| is non-negative, it selects ciphers // of that strength. -// - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and -// |min_version|. -static void ssl_cipher_apply_rule( - uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, - uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule, - int strength_bits, bool in_group, CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) { +// - Otherwise, |alias| must be non-null. It selects ciphers that matches +// |*alias|. +static void ssl_cipher_apply_rule(uint32_t cipher_id, const CIPHER_ALIAS *alias, + int rule, int strength_bits, bool in_group, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { CIPHER_ORDER *head, *tail, *curr, *next, *last; const SSL_CIPHER *cp; bool reverse = false; - if (cipher_id == 0 && strength_bits == -1 && min_version == 0 && - (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) { + if (cipher_id == 0 && strength_bits == -1 && alias->min_version == 0 && + (alias->algorithm_mkey == 0 || alias->algorithm_auth == 0 || + alias->algorithm_enc == 0 || alias->algorithm_mac == 0)) { // The rule matches nothing, so bail early. return; } @@ -862,13 +842,13 @@ static void ssl_cipher_apply_rule( continue; } } else { - if (!(alg_mkey & cp->algorithm_mkey) || - !(alg_auth & cp->algorithm_auth) || - !(alg_enc & cp->algorithm_enc) || - !(alg_mac & cp->algorithm_mac) || - (min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version) || - // The NULL cipher must be selected explicitly. - cp->algorithm_enc == SSL_eNULL) { + if (!(alias->algorithm_mkey & cp->algorithm_mkey) || + !(alias->algorithm_auth & cp->algorithm_auth) || + !(alias->algorithm_enc & cp->algorithm_enc) || + !(alias->algorithm_mac & cp->algorithm_mac) || + (alias->min_version != 0 && + SSL_CIPHER_get_min_version(cp) != alias->min_version) || + (!alias->include_deprecated && ssl_cipher_is_deprecated(cp))) { continue; } } @@ -960,8 +940,8 @@ static bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p, // Go through the list of used strength_bits values in descending order. for (int i = max_strength_bits; i >= 0; i--) { if (number_uses[i] > 0) { - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p, - tail_p); + ssl_cipher_apply_rule(/*cipher_id=*/0, /*alias=*/nullptr, CIPHER_ORD, i, + false, head_p, tail_p); } } @@ -971,13 +951,9 @@ static bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p, static bool ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p, bool strict) { - uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; - uint16_t min_version; const char *l, *buf; - int rule; - bool multi, skip_rule, in_group = false, has_group = false; + bool in_group = false, has_group = false; size_t j, buf_len; - uint32_t cipher_id; char ch; l = rule_str; @@ -988,6 +964,7 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, break; // done } + int rule; if (in_group) { if (ch == ']') { if (*tail_p) { @@ -1002,8 +979,7 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, rule = CIPHER_ADD; l++; continue; - } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && - !(ch >= '0' && ch <= '9')) { + } else if (!OPENSSL_isalnum(ch)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); return false; } else { @@ -1043,21 +1019,19 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, continue; } - multi = false; - cipher_id = 0; - alg_mkey = ~0u; - alg_auth = ~0u; - alg_enc = ~0u; - alg_mac = ~0u; - min_version = 0; - skip_rule = false; + bool multi = false; + uint32_t cipher_id = 0; + CIPHER_ALIAS alias; + bool skip_rule = false; + + // When adding, exclude deprecated ciphers by default. + alias.include_deprecated = rule != CIPHER_ADD; for (;;) { ch = *l; buf = l; buf_len = 0; - while ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '.' || ch == '_') { + while (OPENSSL_isalnum(ch) || ch == '-' || ch == '.' || ch == '_') { ch = *(++l); buf_len++; } @@ -1089,16 +1063,24 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, // If not an exact cipher, look for a matching cipher alias. for (j = 0; j < kCipherAliasesLen; j++) { if (rule_equals(kCipherAliases[j].name, buf, buf_len)) { - alg_mkey &= kCipherAliases[j].algorithm_mkey; - alg_auth &= kCipherAliases[j].algorithm_auth; - alg_enc &= kCipherAliases[j].algorithm_enc; - alg_mac &= kCipherAliases[j].algorithm_mac; + alias.algorithm_mkey &= kCipherAliases[j].algorithm_mkey; + alias.algorithm_auth &= kCipherAliases[j].algorithm_auth; + alias.algorithm_enc &= kCipherAliases[j].algorithm_enc; + alias.algorithm_mac &= kCipherAliases[j].algorithm_mac; - if (min_version != 0 && - min_version != kCipherAliases[j].min_version) { + // When specifying a combination of aliases, if any aliases + // enables deprecated ciphers, deprecated ciphers are included. This + // is slightly different from the bitmasks in that adding aliases + // can increase the set of matched ciphers. This is so that an alias + // like "RSA" will only specifiy AES-based RSA ciphers, but + // "RSA+3DES" will still specify 3DES. + alias.include_deprecated |= kCipherAliases[j].include_deprecated; + + if (alias.min_version != 0 && + alias.min_version != kCipherAliases[j].min_version) { skip_rule = true; } else { - min_version = kCipherAliases[j].min_version; + alias.min_version = kCipherAliases[j].min_version; } break; } @@ -1136,8 +1118,8 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, l++; } } else if (!skip_rule) { - ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, - min_version, rule, -1, in_group, head_p, tail_p); + ssl_cipher_apply_rule(cipher_id, &alias, rule, -1, in_group, head_p, + tail_p); } } @@ -1150,73 +1132,87 @@ static bool ssl_cipher_process_rulestr(const char *rule_str, } bool ssl_create_cipher_list(UniquePtr *out_cipher_list, - const char *rule_str, bool strict) { + const bool has_aes_hw, const char *rule_str, + bool strict) { // Return with error if nothing to do. if (rule_str == NULL || out_cipher_list == NULL) { return false; } - // Now we have to collect the available ciphers from the compiled in ciphers. - // We cannot get more than the number compiled in, so it is used for - // allocation. - Array co_list; - CIPHER_ORDER *head = nullptr, *tail = nullptr; - if (!ssl_cipher_collect_ciphers(&co_list, &head, &tail)) { - return false; + // We prefer ECDHE ciphers over non-PFS ciphers. Then we prefer AEAD over + // non-AEAD. The constants are masked by 0xffff to remove the vestigial 0x03 + // byte from SSL 2.0. + static const uint16_t kAESCiphers[] = { + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 & 0xffff, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 & 0xffff, + }; + static const uint16_t kChaChaCiphers[] = { + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 & 0xffff, + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 & 0xffff, + }; + static const uint16_t kLegacyCiphers[] = { + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA & 0xffff, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff, + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 & 0xffff, + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 & 0xffff, + TLS1_CK_RSA_WITH_AES_128_SHA & 0xffff, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA & 0xffff, + TLS1_CK_RSA_WITH_AES_256_SHA & 0xffff, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA & 0xffff, + SSL3_CK_RSA_DES_192_CBC3_SHA & 0xffff, + }; + + // Set up a linked list of ciphers. + CIPHER_ORDER co_list[OPENSSL_ARRAY_SIZE(kAESCiphers) + + OPENSSL_ARRAY_SIZE(kChaChaCiphers) + + OPENSSL_ARRAY_SIZE(kLegacyCiphers)]; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(co_list); i++) { + co_list[i].next = + i + 1 < OPENSSL_ARRAY_SIZE(co_list) ? &co_list[i + 1] : nullptr; + co_list[i].prev = i == 0 ? nullptr : &co_list[i - 1]; + co_list[i].active = false; + co_list[i].in_group = false; } + CIPHER_ORDER *head = &co_list[0]; + CIPHER_ORDER *tail = &co_list[OPENSSL_ARRAY_SIZE(co_list) - 1]; - // Now arrange all ciphers by preference: - // TODO(davidben): Compute this order once and copy it. - - // Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other - // key exchange mechanisms - ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1, - false, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, - &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, - &tail); - - // Order the bulk ciphers. First the preferred AEAD ciphers. We prefer - // CHACHA20 unless there is hardware support for fast and constant-time - // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the - // old one. - if (EVP_has_aes_hardware()) { - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, - false, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, - false, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, - -1, false, &head, &tail); - } else { - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, - -1, false, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, - false, &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, - false, &head, &tail); + // Order AES ciphers vs ChaCha ciphers based on whether we have AES hardware. + // + // TODO(crbug.com/boringssl/29): We should also set up equipreference groups + // as a server. + size_t num = 0; + if (has_aes_hw) { + for (uint16_t id : kAESCiphers) { + co_list[num++].cipher = SSL_get_cipher_by_value(id); + assert(co_list[num - 1].cipher != nullptr); + } } - - // Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC, - // 3DES_EDE_CBC_SHA. - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false, - &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false, - &head, &tail); - ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false, - &head, &tail); - - // Temporarily enable everything else for sorting - ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head, - &tail); - - // Move ciphers without forward secrecy to the end. - ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD, - -1, false, &head, &tail); - - // Now disable everything (maintaining the ordering!) - ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, - &tail); + for (uint16_t id : kChaChaCiphers) { + co_list[num++].cipher = SSL_get_cipher_by_value(id); + assert(co_list[num - 1].cipher != nullptr); + } + if (!has_aes_hw) { + for (uint16_t id : kAESCiphers) { + co_list[num++].cipher = SSL_get_cipher_by_value(id); + assert(co_list[num - 1].cipher != nullptr); + } + } + for (uint16_t id : kLegacyCiphers) { + co_list[num++].cipher = SSL_get_cipher_by_value(id); + assert(co_list[num - 1].cipher != nullptr); + } + assert(num == OPENSSL_ARRAY_SIZE(co_list)); + static_assert(OPENSSL_ARRAY_SIZE(co_list) + NumTLS13Ciphers() == + OPENSSL_ARRAY_SIZE(kCiphers), + "Not all ciphers are included in the cipher order"); // If the rule_string begins with DEFAULT, apply the default rule before // using the (possibly available) additional rules. @@ -1327,34 +1323,33 @@ BSSL_NAMESPACE_END using namespace bssl; -static constexpr int ssl_cipher_id_cmp_inner(const SSL_CIPHER *a, - const SSL_CIPHER *b) { - // C++11's constexpr functions must have a body consisting of just a - // return-statement. - return (a->id > b->id) ? 1 : ((a->id < b->id) ? -1 : 0); +static constexpr int ssl_cipher_id_cmp(const SSL_CIPHER *a, + const SSL_CIPHER *b) { + if (a->id > b->id) { + return 1; + } + if (a->id < b->id) { + return -1; + } + return 0; } -static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) { - return ssl_cipher_id_cmp_inner(reinterpret_cast(in_a), - reinterpret_cast(in_b)); +static int ssl_cipher_id_cmp_void(const void *in_a, const void *in_b) { + return ssl_cipher_id_cmp(reinterpret_cast(in_a), + reinterpret_cast(in_b)); } -template -static constexpr size_t countof(T const (&)[N]) { - return N; +template +static constexpr bool ssl_ciphers_sorted(const SSL_CIPHER (&ciphers)[N]) { + for (size_t i = 1; i < N; i++) { + if (ssl_cipher_id_cmp(&ciphers[i - 1], &ciphers[i]) >= 0) { + return false; + } + } + return true; } -template -static constexpr int check_order(const T (&arr)[I], size_t N) { - // C++11's constexpr functions must have a body consisting of just a - // return-statement. - return N > 1 ? ((ssl_cipher_id_cmp_inner(&arr[N - 2], &arr[N - 1]) < 0) - ? check_order(arr, N - 1) - : 0) - : 1; -} - -static_assert(check_order(kCiphers, countof(kCiphers)) == 1, +static_assert(ssl_ciphers_sorted(kCiphers), "Ciphers are not sorted, bsearch won't work"); const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { @@ -1363,7 +1358,7 @@ const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { c.id = 0x03000000L | value; return reinterpret_cast(bsearch( &c, kCiphers, OPENSSL_ARRAY_SIZE(kCiphers), sizeof(SSL_CIPHER), - ssl_cipher_id_cmp)); + ssl_cipher_id_cmp_void)); } uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } @@ -1375,18 +1370,12 @@ uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *cipher) { return static_cast(cipher->id); } -uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher) { - return SSL_CIPHER_get_protocol_id(cipher); -} - int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher) { return (cipher->algorithm_mac & SSL_AEAD) != 0; } int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher) { switch (cipher->algorithm_enc) { - case SSL_eNULL: - return NID_undef; case SSL_3DES: return NID_des_ede3_cbc; case SSL_AES128: @@ -1410,6 +1399,8 @@ int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher) { return NID_undef; case SSL_SHA1: return NID_sha1; + case SSL_SHA256: + return NID_sha256; } assert(0); return NID_undef; @@ -1445,22 +1436,29 @@ int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher) { return NID_undef; } -int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { +const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *cipher) { switch (cipher->algorithm_prf) { case SSL_HANDSHAKE_MAC_DEFAULT: - return NID_md5_sha1; + return EVP_md5_sha1(); case SSL_HANDSHAKE_MAC_SHA256: - return NID_sha256; + return EVP_sha256(); case SSL_HANDSHAKE_MAC_SHA384: - return NID_sha384; + return EVP_sha384(); } assert(0); - return NID_undef; + return NULL; +} + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { + const EVP_MD *md = SSL_CIPHER_get_handshake_digest(cipher); + if (md == NULL) { + return NID_undef; + } + return EVP_MD_nid(md); } int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) { - return (cipher->algorithm_enc & SSL_eNULL) == 0 && - cipher->algorithm_mac != SSL_AEAD; + return cipher->algorithm_mac != SSL_AEAD; } uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { @@ -1485,13 +1483,15 @@ uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) { return TLS1_2_VERSION; } +static const char* kUnknownCipher = "(NONE)"; + // return the actual cipher being used const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) { if (cipher != NULL) { return cipher->name; } - return "(NONE)"; + return kUnknownCipher; } const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher) { @@ -1534,14 +1534,6 @@ const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) { } } -char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) { - if (cipher == NULL) { - return NULL; - } - - return OPENSSL_strdup(SSL_CIPHER_standard_name(cipher)); -} - int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { if (cipher == NULL) { return 0; @@ -1567,11 +1559,6 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { strength_bits = 112; break; - case SSL_eNULL: - alg_bits = 0; - strength_bits = 0; - break; - default: assert(0); alg_bits = 0; @@ -1662,10 +1649,6 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, enc = "ChaCha20-Poly1305"; break; - case SSL_eNULL: - enc="None"; - break; - default: enc = "unknown"; break; @@ -1676,6 +1659,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, mac = "SHA1"; break; + case SSL_SHA256: + mac = "SHA256"; + break; + case SSL_AEAD: mac = "AEAD"; break; @@ -1715,3 +1702,13 @@ const char *SSL_COMP_get0_name(const SSL_COMP *comp) { return comp->name; } int SSL_COMP_get_id(const SSL_COMP *comp) { return comp->id; } void SSL_COMP_free_compression_methods(void) {} + +size_t SSL_get_all_cipher_names(const char **out, size_t max_out) { + return GetAllNames(out, max_out, MakeConstSpan(&kUnknownCipher, 1), + &SSL_CIPHER::name, MakeConstSpan(kCiphers)); +} + +size_t SSL_get_all_standard_cipher_names(const char **out, size_t max_out) { + return GetAllNames(out, max_out, Span(), + &SSL_CIPHER::standard_name, MakeConstSpan(kCiphers)); +} diff --git a/third_party/boringssl/kit/src/ssl/ssl_file.cc b/third_party/boringssl/kit/src/ssl/ssl_file.cc index ca4b0be2..9e06ec89 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_file.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_file.cc @@ -124,129 +124,106 @@ #include "internal.h" -static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { +static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) { return X509_NAME_cmp(*a, *b); } -// TODO(davidben): Is there any reason this doesn't call -// |SSL_add_file_cert_subjects_to_stack|? -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - STACK_OF(X509_NAME) *ret = NULL, *sk; - - sk = sk_X509_NAME_new(xname_cmp); - in = BIO_new(BIO_s_file()); - - if (sk == NULL || in == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; +static int add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio, + bool allow_empty) { + // This function historically sorted |out| after every addition and skipped + // duplicates. This implementation preserves that behavior, but only sorts at + // the end, to avoid a quadratic running time. Existing duplicates in |out| + // are preserved, but do not introduce new duplicates. + bssl::UniquePtr to_append(sk_X509_NAME_new(xname_cmp)); + if (to_append == nullptr) { + return 0; } - if (!BIO_read_filename(in, file)) { - goto err; - } + // Temporarily switch the comparison function for |out|. + struct RestoreCmpFunc { + ~RestoreCmpFunc() { sk_X509_NAME_set_cmp_func(stack, old_cmp); } + STACK_OF(X509_NAME) *stack; + int (*old_cmp)(const X509_NAME *const *, const X509_NAME *const *); + }; + RestoreCmpFunc restore = {out, sk_X509_NAME_set_cmp_func(out, xname_cmp)}; + sk_X509_NAME_sort(out); + bool first = true; for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + bssl::UniquePtr x509( + PEM_read_bio_X509(bio, nullptr, nullptr, nullptr)); + if (x509 == nullptr) { + if (first && !allow_empty) { + return 0; + } + // TODO(davidben): This ignores PEM syntax errors. It should only succeed + // on |PEM_R_NO_START_LINE|. + ERR_clear_error(); break; } - if (ret == NULL) { - ret = sk_X509_NAME_new_null(); - if (ret == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - } - xn = X509_get_subject_name(x); - if (xn == NULL) { - goto err; - } + first = false; - // Check for duplicates. - sk_X509_NAME_sort(sk); - if (sk_X509_NAME_find(sk, NULL, xn)) { + X509_NAME *subject = X509_get_subject_name(x509.get()); + // Skip if already present in |out|. Duplicates in |to_append| will be + // handled separately. + if (sk_X509_NAME_find(out, /*out_index=*/NULL, subject)) { continue; } - xn = X509_NAME_dup(xn); - if (xn == NULL || - !sk_X509_NAME_push(sk /* non-owning */, xn) || - !sk_X509_NAME_push(ret /* owning */, xn)) { - X509_NAME_free(xn); - goto err; + bssl::UniquePtr copy(X509_NAME_dup(subject)); + if (copy == nullptr || + !bssl::PushToStack(to_append.get(), std::move(copy))) { + return 0; } } - if (0) { - err: - sk_X509_NAME_pop_free(ret, X509_NAME_free); - ret = NULL; + // Append |to_append| to |stack|, skipping any duplicates. + sk_X509_NAME_sort(to_append.get()); + size_t num = sk_X509_NAME_num(to_append.get()); + for (size_t i = 0; i < num; i++) { + bssl::UniquePtr name(sk_X509_NAME_value(to_append.get(), i)); + sk_X509_NAME_set(to_append.get(), i, nullptr); + if (i + 1 < num && + X509_NAME_cmp(name.get(), sk_X509_NAME_value(to_append.get(), i + 1)) == + 0) { + continue; + } + if (!bssl::PushToStack(out, std::move(name))) { + return 0; + } } - sk_X509_NAME_free(sk); - BIO_free(in); - X509_free(x); - if (ret != NULL) { - ERR_clear_error(); - } - return ret; + // Sort |out| one last time, to preserve the historical behavior of + // maintaining the sorted list. + sk_X509_NAME_sort(out); + return 1; } -int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { + bssl::UniquePtr in(BIO_new_file(file, "r")); + if (in == nullptr) { + return nullptr; + } + bssl::UniquePtr ret(sk_X509_NAME_new_null()); + if (ret == nullptr || // + !add_bio_cert_subjects_to_stack(ret.get(), in.get(), + /*allow_empty=*/false)) { + return nullptr; + } + return ret.release(); +} + +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, const char *file) { - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - int ret = 0; - int (*oldcmp)(const X509_NAME **a, const X509_NAME **b); - - oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); - in = BIO_new(BIO_s_file()); - - if (in == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; + bssl::UniquePtr in(BIO_new_file(file, "r")); + if (in == nullptr) { + return 0; } + return SSL_add_bio_cert_subjects_to_stack(out, in.get()); +} - if (!BIO_read_filename(in, file)) { - goto err; - } - - for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { - break; - } - xn = X509_get_subject_name(x); - if (xn == NULL) { - goto err; - } - - // Check for duplicates. - sk_X509_NAME_sort(stack); - if (sk_X509_NAME_find(stack, NULL, xn)) { - continue; - } - - xn = X509_NAME_dup(xn); - if (xn == NULL || - !sk_X509_NAME_push(stack, xn)) { - X509_NAME_free(xn); - goto err; - } - } - - ERR_clear_error(); - ret = 1; - -err: - BIO_free(in); - X509_free(x); - - (void) sk_X509_NAME_set_cmp_func(stack, oldcmp); - - return ret; +int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio) { + return add_bio_cert_subjects_to_stack(out, bio, /*allow_empty=*/true); } int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { diff --git a/third_party/boringssl/kit/src/ssl/ssl_key_share.cc b/third_party/boringssl/kit/src/ssl/ssl_key_share.cc index c847a0a0..d932ef38 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_key_share.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_key_share.cc @@ -24,10 +24,12 @@ #include #include #include +#include #include #include #include #include +#include #include "internal.h" #include "../crypto/internal.h" @@ -38,85 +40,76 @@ namespace { class ECKeyShare : public SSLKeyShare { public: - ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {} + ECKeyShare(int nid, uint16_t group_id) + : group_(EC_GROUP_new_by_curve_name(nid)), group_id_(group_id) {} uint16_t GroupID() const override { return group_id_; } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { assert(!private_key_); - // Set up a shared |BN_CTX| for all operations. - UniquePtr bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return false; - } - BN_CTXScope scope(bn_ctx.get()); - // Generate a private key. - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); private_key_.reset(BN_new()); - if (!group || !private_key_ || + if (!group_ || !private_key_ || !BN_rand_range_ex(private_key_.get(), 1, - EC_GROUP_get0_order(group.get()))) { + EC_GROUP_get0_order(group_))) { return false; } // Compute the corresponding public key and serialize it. - UniquePtr public_key(EC_POINT_new(group.get())); + UniquePtr public_key(EC_POINT_new(group_)); if (!public_key || - !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL, - NULL, bn_ctx.get()) || - !EC_POINT_point2cbb(out, group.get(), public_key.get(), - POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) { + !EC_POINT_mul(group_, public_key.get(), private_key_.get(), + nullptr, nullptr, /*ctx=*/nullptr) || + !EC_POINT_point2cbb(out, group_, public_key.get(), + POINT_CONVERSION_UNCOMPRESSED, /*ctx=*/nullptr)) { return false; } return true; } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + // ECDH may be fit into a KEM-like abstraction by using a second keypair's + // public key as the ciphertext. + *out_alert = SSL_AD_INTERNAL_ERROR; + return Generate(out_ciphertext) && Decap(out_secret, out_alert, peer_key); + } + + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { + assert(group_); assert(private_key_); *out_alert = SSL_AD_INTERNAL_ERROR; - // Set up a shared |BN_CTX| for all operations. - UniquePtr bn_ctx(BN_CTX_new()); - if (!bn_ctx) { - return false; - } - BN_CTXScope scope(bn_ctx.get()); - - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); - if (!group) { - return false; - } - - UniquePtr peer_point(EC_POINT_new(group.get())); - UniquePtr result(EC_POINT_new(group.get())); - BIGNUM *x = BN_CTX_get(bn_ctx.get()); + UniquePtr peer_point(EC_POINT_new(group_)); + UniquePtr result(EC_POINT_new(group_)); + UniquePtr x(BN_new()); if (!peer_point || !result || !x) { return false; } - if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED || - !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(), - peer_key.size(), bn_ctx.get())) { + if (ciphertext.empty() || ciphertext[0] != POINT_CONVERSION_UNCOMPRESSED || + !EC_POINT_oct2point(group_, peer_point.get(), ciphertext.data(), + ciphertext.size(), /*ctx=*/nullptr)) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); *out_alert = SSL_AD_DECODE_ERROR; return false; } // Compute the x-coordinate of |peer_key| * |private_key_|. - if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(), - private_key_.get(), bn_ctx.get()) || - !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL, - bn_ctx.get())) { + if (!EC_POINT_mul(group_, result.get(), NULL, peer_point.get(), + private_key_.get(), /*ctx=*/nullptr) || + !EC_POINT_get_affine_coordinates_GFp(group_, result.get(), x.get(), + NULL, + /*ctx=*/nullptr)) { return false; } // Encode the x-coordinate left-padded with zeros. Array secret; - if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) || - !BN_bn2bin_padded(secret.data(), secret.size(), x)) { + if (!secret.Init((EC_GROUP_get_degree(group_) + 7) / 8) || + !BN_bn2bin_padded(secret.data(), secret.size(), x.get())) { return false; } @@ -125,10 +118,10 @@ class ECKeyShare : public SSLKeyShare { } bool SerializePrivateKey(CBB *out) override { + assert(group_); assert(private_key_); - UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); // Padding is added to avoid leaking the length. - size_t len = BN_num_bytes(EC_GROUP_get0_order(group.get())); + size_t len = BN_num_bytes(EC_GROUP_get0_order(group_)); return BN_bn2cbb_padded(out, len, private_key_.get()); } @@ -140,7 +133,7 @@ class ECKeyShare : public SSLKeyShare { private: UniquePtr private_key_; - int nid_; + const EC_GROUP *const group_ = nullptr; uint16_t group_id_; }; @@ -148,26 +141,33 @@ class X25519KeyShare : public SSLKeyShare { public: X25519KeyShare() {} - uint16_t GroupID() const override { return SSL_CURVE_X25519; } + uint16_t GroupID() const override { return SSL_GROUP_X25519; } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { uint8_t public_key[32]; X25519_keypair(public_key, private_key_); return !!CBB_add_bytes(out, public_key, sizeof(public_key)); } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { + // X25519 may be fit into a KEM-like abstraction by using a second keypair's + // public key as the ciphertext. + *out_alert = SSL_AD_INTERNAL_ERROR; + return Generate(out_ciphertext) && Decap(out_secret, out_alert, peer_key); + } + + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { *out_alert = SSL_AD_INTERNAL_ERROR; Array secret; if (!secret.Init(32)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } - if (peer_key.size() != 32 || - !X25519(secret.data(), private_key_, peer_key.data())) { + if (ciphertext.size() != 32 || // + !X25519(secret.data(), private_key_, ciphertext.data())) { *out_alert = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); return false; @@ -193,65 +193,63 @@ class X25519KeyShare : public SSLKeyShare { uint8_t private_key_[32]; }; -class CECPQ2KeyShare : public SSLKeyShare { +class X25519Kyber768KeyShare : public SSLKeyShare { public: - CECPQ2KeyShare() {} + X25519Kyber768KeyShare() {} - uint16_t GroupID() const override { return SSL_CURVE_CECPQ2; } + uint16_t GroupID() const override { + return SSL_GROUP_X25519_KYBER768_DRAFT00; + } - bool Offer(CBB *out) override { + bool Generate(CBB *out) override { uint8_t x25519_public_key[32]; X25519_keypair(x25519_public_key, x25519_private_key_); - uint8_t hrss_entropy[HRSS_GENERATE_KEY_BYTES]; - HRSS_public_key hrss_public_key; - RAND_bytes(hrss_entropy, sizeof(hrss_entropy)); - if (!HRSS_generate_key(&hrss_public_key, &hrss_private_key_, - hrss_entropy)) { - return false; - } - - uint8_t hrss_public_key_bytes[HRSS_PUBLIC_KEY_BYTES]; - HRSS_marshal_public_key(hrss_public_key_bytes, &hrss_public_key); + uint8_t kyber_public_key[KYBER_PUBLIC_KEY_BYTES]; + KYBER_generate_key(kyber_public_key, &kyber_private_key_); if (!CBB_add_bytes(out, x25519_public_key, sizeof(x25519_public_key)) || - !CBB_add_bytes(out, hrss_public_key_bytes, - sizeof(hrss_public_key_bytes))) { + !CBB_add_bytes(out, kyber_public_key, sizeof(kyber_public_key))) { return false; } return true; } - bool Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key) override { + bool Encap(CBB *out_ciphertext, Array *out_secret, + uint8_t *out_alert, Span peer_key) override { Array secret; - if (!secret.Init(32 + HRSS_KEY_BYTES)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + if (!secret.Init(32 + 32)) { return false; } uint8_t x25519_public_key[32]; X25519_keypair(x25519_public_key, x25519_private_key_); - - HRSS_public_key peer_public_key; - if (peer_key.size() != 32 + HRSS_PUBLIC_KEY_BYTES || - !HRSS_parse_public_key(&peer_public_key, peer_key.data() + 32) || - !X25519(secret.data(), x25519_private_key_, peer_key.data())) { + KYBER_public_key peer_kyber_pub; + CBS peer_key_cbs; + CBS peer_x25519_cbs; + CBS peer_kyber_cbs; + CBS_init(&peer_key_cbs, peer_key.data(), peer_key.size()); + if (!CBS_get_bytes(&peer_key_cbs, &peer_x25519_cbs, 32) || + !CBS_get_bytes(&peer_key_cbs, &peer_kyber_cbs, + KYBER_PUBLIC_KEY_BYTES) || + CBS_len(&peer_key_cbs) != 0 || + !X25519(secret.data(), x25519_private_key_, + CBS_data(&peer_x25519_cbs)) || + !KYBER_parse_public_key(&peer_kyber_pub, &peer_kyber_cbs)) { *out_alert = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); return false; } - uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; - uint8_t entropy[HRSS_ENCAP_BYTES]; - RAND_bytes(entropy, sizeof(entropy)); + uint8_t kyber_ciphertext[KYBER_CIPHERTEXT_BYTES]; + KYBER_encap(kyber_ciphertext, secret.data() + 32, secret.size() - 32, + &peer_kyber_pub); - if (!HRSS_encap(ciphertext, secret.data() + 32, &peer_public_key, - entropy) || - !CBB_add_bytes(out_public_key, x25519_public_key, + if (!CBB_add_bytes(out_ciphertext, x25519_public_key, sizeof(x25519_public_key)) || - !CBB_add_bytes(out_public_key, ciphertext, sizeof(ciphertext))) { + !CBB_add_bytes(out_ciphertext, kyber_ciphertext, + sizeof(kyber_ciphertext))) { return false; } @@ -259,44 +257,41 @@ class CECPQ2KeyShare : public SSLKeyShare { return true; } - bool Finish(Array *out_secret, uint8_t *out_alert, - Span peer_key) override { + bool Decap(Array *out_secret, uint8_t *out_alert, + Span ciphertext) override { *out_alert = SSL_AD_INTERNAL_ERROR; Array secret; - if (!secret.Init(32 + HRSS_KEY_BYTES)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + if (!secret.Init(32 + 32)) { return false; } - if (peer_key.size() != 32 + HRSS_CIPHERTEXT_BYTES || - !X25519(secret.data(), x25519_private_key_, peer_key.data())) { + if (ciphertext.size() != 32 + KYBER_CIPHERTEXT_BYTES || + !X25519(secret.data(), x25519_private_key_, ciphertext.data())) { *out_alert = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); return false; } - if (!HRSS_decap(secret.data() + 32, &hrss_private_key_, - peer_key.data() + 32, peer_key.size() - 32)) { - return false; - } - + KYBER_decap(secret.data() + 32, secret.size() - 32, ciphertext.data() + 32, + &kyber_private_key_); *out_secret = std::move(secret); return true; } private: uint8_t x25519_private_key_[32]; - HRSS_private_key hrss_private_key_; + KYBER_private_key kyber_private_key_; }; -CONSTEXPR_ARRAY NamedGroup kNamedGroups[] = { - {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"}, - {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"}, - {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1"}, - {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"}, - {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"}, - {NID_CECPQ2, SSL_CURVE_CECPQ2, "CECPQ2", "CECPQ2"}, +constexpr NamedGroup kNamedGroups[] = { + {NID_secp224r1, SSL_GROUP_SECP224R1, "P-224", "secp224r1"}, + {NID_X9_62_prime256v1, SSL_GROUP_SECP256R1, "P-256", "prime256v1"}, + {NID_secp384r1, SSL_GROUP_SECP384R1, "P-384", "secp384r1"}, + {NID_secp521r1, SSL_GROUP_SECP521R1, "P-521", "secp521r1"}, + {NID_X25519, SSL_GROUP_X25519, "X25519", "x25519"}, + {NID_X25519Kyber768Draft00, SSL_GROUP_X25519_KYBER768_DRAFT00, + "X25519Kyber768Draft00", ""}, }; } // namespace @@ -307,59 +302,23 @@ Span NamedGroups() { UniquePtr SSLKeyShare::Create(uint16_t group_id) { switch (group_id) { - case SSL_CURVE_SECP224R1: - return UniquePtr( - New(NID_secp224r1, SSL_CURVE_SECP224R1)); - case SSL_CURVE_SECP256R1: - return UniquePtr( - New(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1)); - case SSL_CURVE_SECP384R1: - return UniquePtr( - New(NID_secp384r1, SSL_CURVE_SECP384R1)); - case SSL_CURVE_SECP521R1: - return UniquePtr( - New(NID_secp521r1, SSL_CURVE_SECP521R1)); - case SSL_CURVE_X25519: - return UniquePtr(New()); - case SSL_CURVE_CECPQ2: - return UniquePtr(New()); + case SSL_GROUP_SECP224R1: + return MakeUnique(NID_secp224r1, SSL_GROUP_SECP224R1); + case SSL_GROUP_SECP256R1: + return MakeUnique(NID_X9_62_prime256v1, SSL_GROUP_SECP256R1); + case SSL_GROUP_SECP384R1: + return MakeUnique(NID_secp384r1, SSL_GROUP_SECP384R1); + case SSL_GROUP_SECP521R1: + return MakeUnique(NID_secp521r1, SSL_GROUP_SECP521R1); + case SSL_GROUP_X25519: + return MakeUnique(); + case SSL_GROUP_X25519_KYBER768_DRAFT00: + return MakeUnique(); default: return nullptr; } } -UniquePtr SSLKeyShare::Create(CBS *in) { - uint64_t group; - CBS private_key; - if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff || - !CBS_get_asn1(in, &private_key, CBS_ASN1_OCTETSTRING)) { - return nullptr; - } - UniquePtr key_share = Create(static_cast(group)); - if (!key_share || !key_share->DeserializePrivateKey(&private_key)) { - return nullptr; - } - return key_share; -} - -bool SSLKeyShare::Serialize(CBB *out) { - CBB private_key; - if (!CBB_add_asn1_uint64(out, GroupID()) || - !CBB_add_asn1(out, &private_key, CBS_ASN1_OCTETSTRING) || - !SerializePrivateKey(&private_key) || // - !CBB_flush(out)) { - return false; - } - return true; -} - -bool SSLKeyShare::Accept(CBB *out_public_key, Array *out_secret, - uint8_t *out_alert, Span peer_key) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return Offer(out_public_key) && - Finish(out_secret, out_alert, peer_key); -} - bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { for (const auto &group : kNamedGroups) { if (group.nid == nid) { @@ -377,7 +336,7 @@ bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) *out_group_id = group.group_id; return true; } - if (len == strlen(group.alias) && + if (strlen(group.alias) > 0 && len == strlen(group.alias) && !strncmp(group.alias, name, len)) { *out_group_id = group.group_id; return true; @@ -386,11 +345,20 @@ bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) return false; } +int ssl_group_id_to_nid(uint16_t group_id) { + for (const auto &group : kNamedGroups) { + if (group.group_id == group_id) { + return group.nid; + } + } + return NID_undef; +} + BSSL_NAMESPACE_END using namespace bssl; -const char* SSL_get_curve_name(uint16_t group_id) { +const char* SSL_get_group_name(uint16_t group_id) { for (const auto &group : kNamedGroups) { if (group.group_id == group_id) { return group.name; @@ -398,3 +366,8 @@ const char* SSL_get_curve_name(uint16_t group_id) { } return nullptr; } + +size_t SSL_get_all_group_names(const char **out, size_t max_out) { + return GetAllNames(out, max_out, Span(), &NamedGroup::name, + MakeConstSpan(kNamedGroups)); +} diff --git a/third_party/boringssl/kit/src/ssl/ssl_lib.cc b/third_party/boringssl/kit/src/ssl/ssl_lib.cc index e2e24363..d7b5be3d 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_lib.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_lib.cc @@ -140,7 +140,10 @@ #include +#include + #include +#include #include #include @@ -164,6 +167,10 @@ BSSL_NAMESPACE_BEGIN +static_assert(SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD, + "max overheads are inconsistent"); + // |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it // to avoid downstream churn. OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) @@ -477,6 +484,17 @@ bool SSL_get_traffic_secrets(const SSL *ssl, return true; } +void SSL_CTX_set_aes_hw_override_for_testing(SSL_CTX *ctx, + bool override_value) { + ctx->aes_hw_override = true; + ctx->aes_hw_override_value = override_value; +} + +void SSL_set_aes_hw_override_for_testing(SSL *ssl, bool override_value) { + ssl->config->aes_hw_override = true; + ssl->config->aes_hw_override_value = override_value; +} + BSSL_NAMESPACE_END using namespace bssl; @@ -517,7 +535,9 @@ ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method) allow_unknown_alpn_protos(false), false_start_allowed_without_alpn(false), handoff(false), - enable_early_data(false) { + enable_early_data(false), + aes_hw_override(false), + aes_hw_override_value(false) { CRYPTO_MUTEX_init(&lock); CRYPTO_new_ex_data(&ex_data); } @@ -637,6 +657,9 @@ SSL *SSL_new(SSL_CTX *ctx) { ssl->config->retain_only_sha256_of_client_certs = ctx->retain_only_sha256_of_client_certs; ssl->config->permute_extensions = ctx->permute_extensions; + ssl->config->aes_hw_override = ctx->aes_hw_override; + ssl->config->aes_hw_override_value = ctx->aes_hw_override_value; + ssl->config->tls13_cipher_policy = ctx->tls13_cipher_policy; if (!ssl->config->supported_group_list.CopyFrom(ctx->supported_group_list) || !ssl->config->alpn_client_proto_list.CopyFrom( @@ -678,7 +701,7 @@ SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg) signed_cert_timestamps_enabled(false), ocsp_stapling_enabled(false), channel_id_enabled(false), - enforce_rsa_key_usage(false), + enforce_rsa_key_usage(true), retain_only_sha256_of_client_certs(false), handoff(false), shed_handshake_config(false), @@ -1053,6 +1076,7 @@ int SSL_write(SSL *ssl, const void *buf, int num) { } int ret = 0; + size_t bytes_written = 0; bool needs_handshake = false; do { // If necessary, complete the handshake implicitly. @@ -1067,10 +1091,16 @@ int SSL_write(SSL *ssl, const void *buf, int num) { } } - ret = ssl->method->write_app_data(ssl, &needs_handshake, - (const uint8_t *)buf, num); + if (num < 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + ret = ssl->method->write_app_data( + ssl, &needs_handshake, &bytes_written, + MakeConstSpan(static_cast(buf), + static_cast(num))); } while (needs_handshake); - return ret; + return ret <= 0 ? ret : static_cast(bytes_written); } int SSL_key_update(SSL *ssl, int request_type) { @@ -1234,7 +1264,7 @@ void SSL_reset_early_data_reject(SSL *ssl) { // Discard any unfinished writes from the perspective of |SSL_write|'s // retry. The handshake will transparently flush out the pending record // (discarded by the server) to keep the framing correct. - ssl->s3->wpend_pending = false; + ssl->s3->pending_write = {}; } enum ssl_early_data_reason_t SSL_get_early_data_reason(const SSL *ssl) { @@ -1303,7 +1333,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) { } if (ret_code == 0) { - if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + if (ssl->s3->rwstate == SSL_ERROR_ZERO_RETURN) { return SSL_ERROR_ZERO_RETURN; } // An EOF was observed which violates the protocol, and the underlying @@ -1909,33 +1939,112 @@ int SSL_CTX_set_tlsext_ticket_key_cb( return 1; } -int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) { - return tls1_set_curves(&ctx->supported_group_list, - MakeConstSpan(curves, curves_len)); +static bool check_group_ids(Span group_ids) { + for (uint16_t group_id : group_ids) { + if (ssl_group_id_to_nid(group_id) == NID_undef) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + return false; + } + } + return true; } -int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) { +int SSL_CTX_set1_group_ids(SSL_CTX *ctx, const uint16_t *group_ids, + size_t num_group_ids) { + auto span = MakeConstSpan(group_ids, num_group_ids); + return check_group_ids(span) && ctx->supported_group_list.CopyFrom(span); +} + +int SSL_set1_group_ids(SSL *ssl, const uint16_t *group_ids, + size_t num_group_ids) { if (!ssl->config) { return 0; } - return tls1_set_curves(&ssl->config->supported_group_list, - MakeConstSpan(curves, curves_len)); + auto span = MakeConstSpan(group_ids, num_group_ids); + return check_group_ids(span) && + ssl->config->supported_group_list.CopyFrom(span); } -int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) { - return tls1_set_curves_list(&ctx->supported_group_list, curves); +static bool ssl_nids_to_group_ids(Array *out_group_ids, + Span nids) { + Array group_ids; + if (!group_ids.Init(nids.size())) { + return false; + } + + for (size_t i = 0; i < nids.size(); i++) { + if (!ssl_nid_to_group_id(&group_ids[i], nids[i])) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + return false; + } + } + + *out_group_ids = std::move(group_ids); + return true; } -int SSL_set1_curves_list(SSL *ssl, const char *curves) { +int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t num_groups) { + return ssl_nids_to_group_ids(&ctx->supported_group_list, + MakeConstSpan(groups, num_groups)); +} + +int SSL_set1_groups(SSL *ssl, const int *groups, size_t num_groups) { if (!ssl->config) { return 0; } - return tls1_set_curves_list(&ssl->config->supported_group_list, curves); + return ssl_nids_to_group_ids(&ssl->config->supported_group_list, + MakeConstSpan(groups, num_groups)); } -uint16_t SSL_get_curve_id(const SSL *ssl) { - // TODO(davidben): This checks the wrong session if there is a renegotiation - // in progress. +static bool ssl_str_to_group_ids(Array *out_group_ids, + const char *str) { + // Count the number of groups in the list. + size_t count = 0; + const char *ptr = str, *col; + do { + col = strchr(ptr, ':'); + count++; + if (col) { + ptr = col + 1; + } + } while (col); + + Array group_ids; + if (!group_ids.Init(count)) { + return false; + } + + size_t i = 0; + ptr = str; + do { + col = strchr(ptr, ':'); + if (!ssl_name_to_group_id(&group_ids[i++], ptr, + col ? (size_t)(col - ptr) : strlen(ptr))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + return false; + } + if (col) { + ptr = col + 1; + } + } while (col); + + assert(i == count); + *out_group_ids = std::move(group_ids); + return true; +} + +int SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups) { + return ssl_str_to_group_ids(&ctx->supported_group_list, groups); +} + +int SSL_set1_groups_list(SSL *ssl, const char *groups) { + if (!ssl->config) { + return 0; + } + return ssl_str_to_group_ids(&ssl->config->supported_group_list, groups); +} + +uint16_t SSL_get_group_id(const SSL *ssl) { SSL_SESSION *session = SSL_get_session(ssl); if (session == NULL) { return 0; @@ -1944,6 +2053,14 @@ uint16_t SSL_get_curve_id(const SSL *ssl) { return session->group_id; } +int SSL_get_negotiated_group(const SSL *ssl) { + uint16_t group_id = SSL_get_group_id(ssl); + if (group_id == 0) { + return NID_undef; + } + return ssl_group_id_to_nid(group_id); +} + int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) { return 1; } @@ -1995,18 +2112,27 @@ const char *SSL_get_cipher_list(const SSL *ssl, int n) { } int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { - return ssl_create_cipher_list(&ctx->cipher_list, str, false /* not strict */); + const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + false /* not strict */); } int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { - return ssl_create_cipher_list(&ctx->cipher_list, str, true /* strict */); + const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + true /* strict */); } int SSL_set_cipher_list(SSL *ssl, const char *str) { if (!ssl->config) { return 0; } - return ssl_create_cipher_list(&ssl->config->cipher_list, str, + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, false /* not strict */); } @@ -2014,7 +2140,10 @@ int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { if (!ssl->config) { return 0; } - return ssl_create_cipher_list(&ssl->config->cipher_list, str, + const bool has_aes_hw = ssl->config->aes_hw_override + ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(); + return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, true /* strict */); } @@ -2117,7 +2246,6 @@ int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { } ssl->hostname.reset(OPENSSL_strdup(name)); if (ssl->hostname == nullptr) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -2169,8 +2297,10 @@ found: void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + // NPN protocols have one-byte lengths, so they must fit in |unsigned|. + assert(ssl->s3->next_proto_negotiated.size() <= UINT_MAX); *out_data = ssl->s3->next_proto_negotiated.data(); - *out_len = ssl->s3->next_proto_negotiated.size(); + *out_len = static_cast(ssl->s3->next_proto_negotiated.size()); } void SSL_CTX_set_next_protos_advertised_cb( @@ -2190,7 +2320,7 @@ void SSL_CTX_set_next_proto_select_cb( } int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, - unsigned protos_len) { + size_t protos_len) { // Note this function's return value is backwards. auto span = MakeConstSpan(protos, protos_len); if (!span.empty() && !ssl_is_valid_alpn_list(span)) { @@ -2200,7 +2330,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, return ctx->alpn_client_proto_list.CopyFrom(span) ? 0 : 1; } -int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) { +int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, size_t protos_len) { // Note this function's return value is backwards. if (!ssl->config) { return 1; @@ -2224,13 +2354,16 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, unsigned *out_len) { + Span protocol; if (SSL_in_early_data(ssl) && !ssl->server) { - *out_data = ssl->s3->hs->early_session->early_alpn.data(); - *out_len = ssl->s3->hs->early_session->early_alpn.size(); + protocol = ssl->s3->hs->early_session->early_alpn; } else { - *out_data = ssl->s3->alpn_selected.data(); - *out_len = ssl->s3->alpn_selected.size(); + protocol = ssl->s3->alpn_selected; } + // ALPN protocols have one-byte lengths, so they must fit in |unsigned|. + assert(protocol.size() < UINT_MAX); + *out_data = protocol.data(); + *out_len = static_cast(protocol.size()); } void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { @@ -2562,7 +2695,13 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) { return CRYPTO_get_ex_data(&ctx->ex_data, idx); } -int SSL_want(const SSL *ssl) { return ssl->s3->rwstate; } +int SSL_want(const SSL *ssl) { + // Historically, OpenSSL did not track |SSL_ERROR_ZERO_RETURN| as an |rwstate| + // value. We do, but map it back to |SSL_ERROR_NONE| to preserve the original + // behavior. + return ssl->s3->rwstate == SSL_ERROR_ZERO_RETURN ? SSL_ERROR_NONE + : ssl->s3->rwstate; +} void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, @@ -2765,6 +2904,10 @@ void SSL_set_enforce_rsa_key_usage(SSL *ssl, int enabled) { ssl->config->enforce_rsa_key_usage = !!enabled; } +int SSL_was_key_usage_invalid(const SSL *ssl) { + return ssl->s3->was_key_usage_invalid; +} + void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { ssl->renegotiate_mode = mode; @@ -2786,35 +2929,25 @@ int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, return 1; } -static uint64_t be_to_u64(const uint8_t in[8]) { - return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) | - (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) | - (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) | - (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]); -} - uint64_t SSL_get_read_sequence(const SSL *ssl) { - // TODO(davidben): Internally represent sequence numbers as uint64_t. if (SSL_is_dtls(ssl)) { // max_seq_num already includes the epoch. assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48)); return ssl->d1->bitmap.max_seq_num; } - return be_to_u64(ssl->s3->read_sequence); + return ssl->s3->read_sequence; } uint64_t SSL_get_write_sequence(const SSL *ssl) { - uint64_t ret = be_to_u64(ssl->s3->write_sequence); + uint64_t ret = ssl->s3->write_sequence; if (SSL_is_dtls(ssl)) { assert((ret >> 48) == 0); - ret |= ((uint64_t)ssl->d1->w_epoch) << 48; + ret |= uint64_t{ssl->d1->w_epoch} << 48; } return ret; } uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { - // TODO(davidben): This checks the wrong session if there is a renegotiation - // in progress. SSL_SESSION *session = SSL_get_session(ssl); if (session == NULL) { return 0; @@ -2980,7 +3113,7 @@ int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { return 0; } int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return SSL_CTX_set1_curves(ctx, &nid, 1); + return SSL_CTX_set1_groups(ctx, &nid, 1); } int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { @@ -2989,7 +3122,7 @@ int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { return 0; } int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return SSL_set1_curves(ssl, &nid, 1); + return SSL_set1_groups(ssl, &nid, 1); } void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, @@ -3025,6 +3158,15 @@ SSL_SESSION *SSL_process_tls13_new_session_ticket(SSL *ssl, const uint8_t *buf, return session.release(); } +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) { + num_tickets = std::min(num_tickets, kMaxTickets); + static_assert(kMaxTickets <= 0xff, "Too many tickets."); + ctx->num_tickets = static_cast(num_tickets); + return 1; +} + +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx) { return ctx->num_tickets; } + int SSL_set_tlsext_status_type(SSL *ssl, int type) { if (!ssl->config) { return 0; @@ -3070,3 +3212,143 @@ int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) { ctx->legacy_ocsp_callback_arg = arg; return 1; } + +namespace fips202205 { + +// (References are to SP 800-52r2): + +// Section 3.4.2.2 +// "at least one of the NIST-approved curves, P-256 (secp256r1) and P384 +// (secp384r1), shall be supported as described in RFC 8422." +// +// Section 3.3.1 +// "The server shall be configured to only use cipher suites that are +// composed entirely of NIST approved algorithms" +static const uint16_t kGroups[] = {SSL_GROUP_SECP256R1, SSL_GROUP_SECP384R1}; + +static const uint16_t kSigAlgs[] = { + SSL_SIGN_RSA_PKCS1_SHA256, + SSL_SIGN_RSA_PKCS1_SHA384, + SSL_SIGN_RSA_PKCS1_SHA512, + // Table 4.1: + // "The curve should be P-256 or P-384" + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA256, + SSL_SIGN_RSA_PSS_RSAE_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA512, +}; + +static const char kTLS12Ciphers[] = + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:" + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + +static int Configure(SSL_CTX *ctx) { + ctx->tls13_cipher_policy = ssl_compliance_policy_fips_202205; + + return + // Section 3.1: + // "Servers that support government-only applications shall be + // configured to use TLS 1.2 and should be configured to use TLS 1.3 + // as well. These servers should not be configured to use TLS 1.1 and + // shall not use TLS 1.0, SSL 3.0, or SSL 2.0. + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION) && + SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) && + // Sections 3.3.1.1.1 and 3.3.1.1.2 are ambiguous about whether + // HMAC-SHA-1 cipher suites are permitted with TLS 1.2. However, later the + // Encrypt-then-MAC extension is required for all CBC cipher suites and so + // it's easier to drop them. + SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && + SSL_CTX_set1_group_ids(ctx, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && + SSL_CTX_set_signing_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +static int Configure(SSL *ssl) { + ssl->config->tls13_cipher_policy = ssl_compliance_policy_fips_202205; + + // See |Configure(SSL_CTX)|, above, for reasoning. + return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && + SSL_set_max_proto_version(ssl, TLS1_3_VERSION) && + SSL_set_strict_cipher_list(ssl, kTLS12Ciphers) && + SSL_set1_group_ids(ssl, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && + SSL_set_signing_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_set_verify_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +} // namespace fips202205 + +namespace wpa202304 { + +// See WPA version 3.1, section 3.5. + +static const uint16_t kGroups[] = {SSL_GROUP_SECP384R1}; + +static const uint16_t kSigAlgs[] = { + SSL_SIGN_RSA_PKCS1_SHA384, // + SSL_SIGN_RSA_PKCS1_SHA512, // + SSL_SIGN_ECDSA_SECP384R1_SHA384, // + SSL_SIGN_RSA_PSS_RSAE_SHA384, // + SSL_SIGN_RSA_PSS_RSAE_SHA512, // +}; + +static const char kTLS12Ciphers[] = + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:" + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + +static int Configure(SSL_CTX *ctx) { + ctx->tls13_cipher_policy = ssl_compliance_policy_wpa3_192_202304; + + return SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION) && + SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) && + SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && + SSL_CTX_set1_group_ids(ctx, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && + SSL_CTX_set_signing_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +static int Configure(SSL *ssl) { + ssl->config->tls13_cipher_policy = ssl_compliance_policy_wpa3_192_202304; + + return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && + SSL_set_max_proto_version(ssl, TLS1_3_VERSION) && + SSL_set_strict_cipher_list(ssl, kTLS12Ciphers) && + SSL_set1_group_ids(ssl, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && + SSL_set_signing_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_set_verify_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +} // namespace wpa202304 + +int SSL_CTX_set_compliance_policy(SSL_CTX *ctx, + enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_fips_202205: + return fips202205::Configure(ctx); + case ssl_compliance_policy_wpa3_192_202304: + return wpa202304::Configure(ctx); + default: + return 0; + } +} + +int SSL_set_compliance_policy(SSL *ssl, enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_fips_202205: + return fips202205::Configure(ssl); + case ssl_compliance_policy_wpa3_192_202304: + return wpa202304::Configure(ssl); + default: + return 0; + } +} diff --git a/third_party/boringssl/kit/src/ssl/ssl_privkey.cc b/third_party/boringssl/kit/src/ssl/ssl_privkey.cc index 8462ebf0..57116cd6 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_privkey.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_privkey.cc @@ -64,6 +64,7 @@ #include #include #include +#include #include "internal.h" #include "../crypto/internal.h" @@ -77,7 +78,7 @@ bool ssl_is_key_type_supported(int key_type) { } static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) { - if (!ssl_is_key_type_supported(pkey->type)) { + if (!ssl_is_key_type_supported(EVP_PKEY_id(pkey))) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return false; } @@ -151,6 +152,20 @@ static bool pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey, return false; } + if (ssl_protocol_version(ssl) < TLS1_2_VERSION) { + // TLS 1.0 and 1.1 do not negotiate algorithms and always sign one of two + // hardcoded algorithms. + return sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || + sigalg == SSL_SIGN_ECDSA_SHA1; + } + + // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| is not a real SignatureScheme for TLS 1.2 and + // higher. It is an internal value we use to represent TLS 1.0/1.1's MD5/SHA1 + // concatenation. + if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + return false; + } + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { // RSA keys may only be used with RSA-PSS. if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) { @@ -201,6 +216,31 @@ enum ssl_private_key_result_t ssl_private_key_sign( SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, uint16_t sigalg, Span in) { SSL *const ssl = hs->ssl; + SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); + Array spki; + if (hints) { + ScopedCBB spki_cbb; + if (!CBB_init(spki_cbb.get(), 64) || + !EVP_marshal_public_key(spki_cbb.get(), hs->local_pubkey.get()) || + !CBBFinishArray(spki_cbb.get(), &spki)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + } + + // Replay the signature from handshake hints if available. + if (hints && !hs->hints_requested && // + sigalg == hints->signature_algorithm && // + in == hints->signature_input && + MakeConstSpan(spki) == hints->signature_spki && + !hints->signature.empty() && // + hints->signature.size() <= max_out) { + // Signature algorithm and input both match. Reuse the signature from hints. + *out_len = hints->signature.size(); + OPENSSL_memcpy(out, hints->signature.data(), hints->signature.size()); + return ssl_private_key_success; + } + const SSL_PRIVATE_KEY_METHOD *key_method = hs->config->cert->key_method; EVP_PKEY *privatekey = hs->config->cert->privatekey.get(); assert(!hs->can_release_private_key); @@ -214,21 +254,33 @@ enum ssl_private_key_result_t ssl_private_key_sign( if (hs->pending_private_key_op) { ret = key_method->complete(ssl, out, out_len, max_out); } else { - ret = key_method->sign(ssl, out, out_len, max_out, - sigalg, in.data(), in.size()); + ret = key_method->sign(ssl, out, out_len, max_out, sigalg, in.data(), + in.size()); } if (ret == ssl_private_key_failure) { OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); } hs->pending_private_key_op = ret == ssl_private_key_retry; - return ret; + if (ret != ssl_private_key_success) { + return ret; + } + } else { + *out_len = max_out; + ScopedEVP_MD_CTX ctx; + if (!setup_ctx(ssl, ctx.get(), privatekey, sigalg, false /* sign */) || + !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { + return ssl_private_key_failure; + } } - *out_len = max_out; - ScopedEVP_MD_CTX ctx; - if (!setup_ctx(ssl, ctx.get(), privatekey, sigalg, false /* sign */) || - !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { - return ssl_private_key_failure; + // Save the hint if applicable. + if (hints && hs->hints_requested) { + hints->signature_algorithm = sigalg; + hints->signature_spki = std::move(spki); + if (!hints->signature_input.CopyFrom(in) || + !hints->signature.CopyFrom(MakeConstSpan(out, *out_len))) { + return ssl_private_key_failure; + } } return ssl_private_key_success; } @@ -433,12 +485,14 @@ void SSL_CTX_set_private_key_method(SSL_CTX *ctx, static constexpr size_t kMaxSignatureAlgorithmNameLen = 23; -// This was "constexpr" rather than "const", but that triggered a bug in MSVC -// where it didn't pad the strings to the correct length. -static const struct { +struct SignatureAlgorithmName { uint16_t signature_algorithm; const char name[kMaxSignatureAlgorithmNameLen]; -} kSignatureAlgorithmNames[] = { +}; + +// This was "constexpr" rather than "const", but that triggered a bug in MSVC +// where it didn't pad the strings to the correct length. +static const SignatureAlgorithmName kSignatureAlgorithmNames[] = { {SSL_SIGN_RSA_PKCS1_MD5_SHA1, "rsa_pkcs1_md5_sha1"}, {SSL_SIGN_RSA_PKCS1_SHA1, "rsa_pkcs1_sha1"}, {SSL_SIGN_RSA_PKCS1_SHA256, "rsa_pkcs1_sha256"}, @@ -464,6 +518,8 @@ const char *SSL_get_signature_algorithm_name(uint16_t sigalg, return "ecdsa_sha384"; case SSL_SIGN_ECDSA_SECP521R1_SHA512: return "ecdsa_sha512"; + // If adding more here, also update + // |SSL_get_all_signature_algorithm_names|. } } @@ -476,6 +532,14 @@ const char *SSL_get_signature_algorithm_name(uint16_t sigalg, return NULL; } +size_t SSL_get_all_signature_algorithm_names(const char **out, size_t max_out) { + const char *kPredefinedNames[] = {"ecdsa_sha256", "ecdsa_sha384", + "ecdsa_sha512"}; + return GetAllNames(out, max_out, MakeConstSpan(kPredefinedNames), + &SignatureAlgorithmName::name, + MakeConstSpan(kSignatureAlgorithmNames)); +} + int SSL_get_signature_algorithm_key_type(uint16_t sigalg) { const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE; @@ -494,9 +558,83 @@ int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { return alg != nullptr && alg->is_rsa_pss; } +static int compare_uint16_t(const void *p1, const void *p2) { + uint16_t u1 = *((const uint16_t *)p1); + uint16_t u2 = *((const uint16_t *)p2); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +static bool sigalgs_unique(Span in_sigalgs) { + if (in_sigalgs.size() < 2) { + return true; + } + + Array sigalgs; + if (!sigalgs.CopyFrom(in_sigalgs)) { + return false; + } + + qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t); + + for (size_t i = 1; i < sigalgs.size(); i++) { + if (sigalgs[i - 1] == sigalgs[i]) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM); + return false; + } + } + + return true; +} + +static bool set_sigalg_prefs(Array *out, Span prefs) { + if (!sigalgs_unique(prefs)) { + return false; + } + + // Check for invalid algorithms, and filter out |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. + Array filtered; + if (!filtered.Init(prefs.size())) { + return false; + } + size_t added = 0; + for (uint16_t pref : prefs) { + if (pref == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + // Though not intended to be used with this API, we treat + // |SSL_SIGN_RSA_PKCS1_MD5_SHA1| as a real signature algorithm in + // |SSL_PRIVATE_KEY_METHOD|. Not accepting it here makes for a confusing + // abstraction. + continue; + } + if (get_signature_algorithm(pref) == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + return false; + } + filtered[added] = pref; + added++; + } + filtered.Shrink(added); + + // This can happen if |prefs| contained only |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. + // Leaving it empty would revert to the default, so treat this as an error + // condition. + if (!prefs.empty() && filtered.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + return false; + } + + *out = std::move(filtered); + return true; +} + int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, size_t num_prefs) { - return ctx->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ctx->cert->sigalgs, MakeConstSpan(prefs, num_prefs)); } int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, @@ -504,7 +642,8 @@ int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, if (!ssl->config) { return 0; } - return ssl->config->cert->sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ssl->config->cert->sigalgs, + MakeConstSpan(prefs, num_prefs)); } static constexpr struct { @@ -560,50 +699,16 @@ static bool parse_sigalg_pairs(Array *out, const int *values, return true; } -static int compare_uint16_t(const void *p1, const void *p2) { - uint16_t u1 = *((const uint16_t *)p1); - uint16_t u2 = *((const uint16_t *)p2); - if (u1 < u2) { - return -1; - } else if (u1 > u2) { - return 1; - } else { - return 0; - } -} - -static bool sigalgs_unique(Span in_sigalgs) { - if (in_sigalgs.size() < 2) { - return true; - } - - Array sigalgs; - if (!sigalgs.CopyFrom(in_sigalgs)) { - return false; - } - - qsort(sigalgs.data(), sigalgs.size(), sizeof(uint16_t), compare_uint16_t); - - for (size_t i = 1; i < sigalgs.size(); i++) { - if (sigalgs[i - 1] == sigalgs[i]) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_SIGNATURE_ALGORITHM); - return false; - } - } - - return true; -} - int SSL_CTX_set1_sigalgs(SSL_CTX *ctx, const int *values, size_t num_values) { Array sigalgs; - if (!parse_sigalg_pairs(&sigalgs, values, num_values) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalg_pairs(&sigalgs, values, num_values)) { return 0; } if (!SSL_CTX_set_signing_algorithm_prefs(ctx, sigalgs.data(), sigalgs.size()) || - !ctx->verify_sigalgs.CopyFrom(sigalgs)) { + !SSL_CTX_set_verify_algorithm_prefs(ctx, sigalgs.data(), + sigalgs.size())) { return 0; } @@ -617,13 +722,12 @@ int SSL_set1_sigalgs(SSL *ssl, const int *values, size_t num_values) { } Array sigalgs; - if (!parse_sigalg_pairs(&sigalgs, values, num_values) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalg_pairs(&sigalgs, values, num_values)) { return 0; } if (!SSL_set_signing_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size()) || - !ssl->config->verify_sigalgs.CopyFrom(sigalgs)) { + !SSL_set_verify_algorithm_prefs(ssl, sigalgs.data(), sigalgs.size())) { return 0; } @@ -663,7 +767,7 @@ static bool parse_sigalgs_list(Array *out, const char *str) { // Note that the loop runs to len+1, i.e. it'll process the terminating NUL. for (size_t offset = 0; offset < len+1; offset++) { - const char c = str[offset]; + const unsigned char c = str[offset]; switch (c) { case '+': @@ -768,8 +872,7 @@ static bool parse_sigalgs_list(Array *out, const char *str) { return false; } - if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || c == '-' || c == '_') { + if (OPENSSL_isalnum(c) || c == '-' || c == '_') { buf[buf_used++] = c; } else { OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); @@ -786,8 +889,7 @@ static bool parse_sigalgs_list(Array *out, const char *str) { int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str) { Array sigalgs; - if (!parse_sigalgs_list(&sigalgs, str) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalgs_list(&sigalgs, str)) { return 0; } @@ -808,8 +910,7 @@ int SSL_set1_sigalgs_list(SSL *ssl, const char *str) { } Array sigalgs; - if (!parse_sigalgs_list(&sigalgs, str) || - !sigalgs_unique(sigalgs)) { + if (!parse_sigalgs_list(&sigalgs, str)) { return 0; } @@ -823,7 +924,8 @@ int SSL_set1_sigalgs_list(SSL *ssl, const char *str) { int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, size_t num_prefs) { - return ctx->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ctx->verify_sigalgs, + MakeConstSpan(prefs, num_prefs)); } int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, @@ -833,5 +935,6 @@ int SSL_set_verify_algorithm_prefs(SSL *ssl, const uint16_t *prefs, return 0; } - return ssl->config->verify_sigalgs.CopyFrom(MakeConstSpan(prefs, num_prefs)); + return set_sigalg_prefs(&ssl->config->verify_sigalgs, + MakeConstSpan(prefs, num_prefs)); } diff --git a/third_party/boringssl/kit/src/ssl/ssl_session.cc b/third_party/boringssl/kit/src/ssl/ssl_session.cc index 76e6dc44..979ac597 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_session.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_session.cc @@ -214,9 +214,9 @@ UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { } } if (session->certs != nullptr) { - auto buf_up_ref = [](CRYPTO_BUFFER *buf) { - CRYPTO_BUFFER_up_ref(buf); - return buf; + auto buf_up_ref = [](const CRYPTO_BUFFER *buf) { + CRYPTO_BUFFER_up_ref(const_cast(buf)); + return const_cast(buf); }; new_session->certs.reset(sk_CRYPTO_BUFFER_deep_copy( session->certs.get(), buf_up_ref, CRYPTO_BUFFER_free)); @@ -400,7 +400,7 @@ bool ssl_get_new_session(SSL_HANDSHAKE *hs) { return true; } -int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { +bool ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { OPENSSL_timeval now; ssl_ctx_get_current_time(ctx, &now); { @@ -412,7 +412,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { ctx->ticket_key_current->next_rotation_tv_sec > now.tv_sec) && (!ctx->ticket_key_prev || ctx->ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) { - return 1; + return true; } } @@ -423,7 +423,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { // The current key has not been initialized or it is expired. auto new_key = bssl::MakeUnique(); if (!new_key) { - return 0; + return false; } RAND_bytes(new_key->name, 16); RAND_bytes(new_key->hmac_key, 16); @@ -447,7 +447,7 @@ int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { ctx->ticket_key_prev.reset(); } - return 1; + return true; } static int ssl_encrypt_ticket_with_cipher_ctx(SSL_HANDSHAKE *hs, CBB *out, @@ -560,30 +560,28 @@ static int ssl_encrypt_ticket_with_method(SSL_HANDSHAKE *hs, CBB *out, return 1; } -int ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, +bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out, const SSL_SESSION *session) { // Serialize the SSL_SESSION to be encoded into the ticket. - uint8_t *session_buf = NULL; + uint8_t *session_buf = nullptr; size_t session_len; if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) { - return -1; + return false; } + bssl::UniquePtr free_session_buf(session_buf); - int ret = 0; if (hs->ssl->session_ctx->ticket_aead_method) { - ret = ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len); + return ssl_encrypt_ticket_with_method(hs, out, session_buf, session_len); } else { - ret = ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf, session_len); + return ssl_encrypt_ticket_with_cipher_ctx(hs, out, session_buf, + session_len); } - - OPENSSL_free(session_buf); - return ret; } -int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session) { +bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { if (session == NULL) { - return 0; + return false; } return session->sid_ctx_length == hs->config->cert->sid_ctx_length && @@ -591,9 +589,9 @@ int ssl_session_is_context_valid(const SSL_HANDSHAKE *hs, hs->config->cert->sid_ctx_length) == 0; } -int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { +bool ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { if (session == NULL) { - return 0; + return false; } struct OPENSSL_timeval now; @@ -601,14 +599,14 @@ int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { // Reject tickets from the future to avoid underflow. if (now.tv_sec < session->time) { - return 0; + return false; } return session->timeout > now.tv_sec - session->time; } -int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, - const SSL_SESSION *session) { +bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { const SSL *const ssl = hs->ssl; return ssl_session_is_context_valid(hs, session) && // The session must have been created by the same type of end point as @@ -1169,20 +1167,31 @@ SSL_SESSION *SSL_magic_pending_session_ptr(void) { } SSL_SESSION *SSL_get_session(const SSL *ssl) { - // Once the handshake completes we return the established session. Otherwise - // we return the intermediate session, either |session| (for resumption) or - // |new_session| if doing a full handshake. - if (!SSL_in_init(ssl)) { + // Once the initially handshake completes, we return the most recently + // established session. In particular, if there is a pending renegotiation, we + // do not return information about it until it completes. + // + // Code in the handshake must either use |hs->new_session| (if updating a + // partial session) or |ssl_handshake_session| (if trying to query properties + // consistently across TLS 1.2 resumption and other handshakes). + if (ssl->s3->established_session != nullptr) { return ssl->s3->established_session.get(); } + + // Otherwise, we must be in the initial handshake. SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + assert(hs != nullptr); + assert(!ssl->s3->initial_handshake_complete); + + // Return the 0-RTT session, if in the 0-RTT state. While the handshake has + // not actually completed, the public accessors all report properties as if + // it has. if (hs->early_session) { return hs->early_session.get(); } - if (hs->new_session) { - return hs->new_session.get(); - } - return ssl->session.get(); + + // Otherwise, return the partial session. + return (SSL_SESSION *)ssl_handshake_session(hs); } SSL_SESSION *SSL_get1_session(SSL *ssl) { diff --git a/third_party/boringssl/kit/src/ssl/ssl_test.cc b/third_party/boringssl/kit/src/ssl/ssl_test.cc index 4169671d..b791fc30 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_test.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_test.cc @@ -12,6 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include #include "internal.h" #include "../crypto/internal.h" @@ -351,6 +353,81 @@ static const CipherTest kCipherTests[] = { // …but not in strict mode. true, }, + // 3DES ciphers are disabled by default. + { + "RSA", + { + {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0}, + {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0}, + {TLS1_CK_RSA_WITH_AES_128_SHA, 0}, + {TLS1_CK_RSA_WITH_AES_256_SHA, 0}, + }, + false, + }, + // But 3DES ciphers may be specified by name. + { + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + { + {SSL3_CK_RSA_DES_192_CBC3_SHA, 0}, + }, + false, + }, + { + "DES-CBC3-SHA", + { + {SSL3_CK_RSA_DES_192_CBC3_SHA, 0}, + }, + false, + }, + // Or by a selector that specifically includes deprecated ciphers. + { + "3DES", + { + {SSL3_CK_RSA_DES_192_CBC3_SHA, 0}, + }, + false, + }, + // Such selectors may be combined with other selectors that would otherwise + // not allow deprecated ciphers. + { + "RSA+3DES", + { + {SSL3_CK_RSA_DES_192_CBC3_SHA, 0}, + }, + false, + }, + // The cipher must still match all combined selectors, however. "ECDHE+3DES" + // matches nothing because we do not implement + // TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA. (The test includes + // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 so the final list is not empty.) + { + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:ECDHE+3DES", + { + {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0}, + }, + false, + }, + // Although alises like "RSA" do not match 3DES when adding ciphers, they do + // match it when removing ciphers. + { + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:RSA:RSA+3DES:!RSA", + { + {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0}, + }, + false, + }, + // 3DES still participates in strength sorting. + { + "RSA:3DES:@STRENGTH", + { + {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0}, + {TLS1_CK_RSA_WITH_AES_256_SHA, 0}, + {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0}, + {TLS1_CK_RSA_WITH_AES_128_SHA, 0}, + {SSL3_CK_RSA_DES_192_CBC3_SHA, 0}, + }, + false, + }, }; static const char *kBadRules[] = { @@ -369,7 +446,7 @@ static const char *kBadRules[] = { "COMPLEMENTOFDEFAULT", // Invalid command. "?BAR", - // Special operators are not allowed if groups are used. + // Special operators are not allowed if equi-preference groups are used. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO", "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO", "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO", @@ -380,7 +457,7 @@ static const char *kBadRules[] = { "[AES128-SHA | AES128-SHA256]", }; -static const char *kMustNotIncludeNull[] = { +static const char *kMustNotIncludeDeprecated[] = { "ALL", "DEFAULT", "HIGH", @@ -393,32 +470,37 @@ static const char *kMustNotIncludeNull[] = { "TLSv1.2", }; +static const char* kShouldIncludeCBCSHA256[] = { + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", +}; + static const CurveTest kCurveTests[] = { { "P-256", - { SSL_CURVE_SECP256R1 }, + { SSL_GROUP_SECP256R1 }, }, { - "P-256:CECPQ2", - { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 }, + "P-256:X25519Kyber768Draft00", + { SSL_GROUP_SECP256R1, SSL_GROUP_X25519_KYBER768_DRAFT00 }, }, { "P-256:P-384:P-521:X25519", { - SSL_CURVE_SECP256R1, - SSL_CURVE_SECP384R1, - SSL_CURVE_SECP521R1, - SSL_CURVE_X25519, + SSL_GROUP_SECP256R1, + SSL_GROUP_SECP384R1, + SSL_GROUP_SECP521R1, + SSL_GROUP_X25519, }, }, { "prime256v1:secp384r1:secp521r1:x25519", { - SSL_CURVE_SECP256R1, - SSL_CURVE_SECP384R1, - SSL_CURVE_SECP521R1, - SSL_CURVE_X25519, + SSL_GROUP_SECP256R1, + SSL_GROUP_SECP384R1, + SSL_GROUP_SECP521R1, + SSL_GROUP_X25519, }, }, }; @@ -576,7 +658,7 @@ TEST(SSLTest, CipherRules) { ERR_clear_error(); } - for (const char *rule : kMustNotIncludeNull) { + for (const char *rule : kMustNotIncludeDeprecated) { SCOPED_TRACE(rule); bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); @@ -584,6 +666,25 @@ TEST(SSLTest, CipherRules) { ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule)); for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) { EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher)); + EXPECT_FALSE(ssl_cipher_is_deprecated(cipher)); + } + } + + { + for (const char *rule : kShouldIncludeCBCSHA256) { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule)); + + bool found = false; + for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) { + if ((TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff) == + SSL_CIPHER_get_protocol_id(cipher)) { + found = true; + break; + } + } + EXPECT_TRUE(found); } } } @@ -594,7 +695,7 @@ TEST(SSLTest, CurveRules) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); - ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule)); + ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), t.rule)); ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size()); for (size_t i = 0; i < t.expected.size(); i++) { EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]); @@ -606,7 +707,7 @@ TEST(SSLTest, CurveRules) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); - EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule)); + EXPECT_FALSE(SSL_CTX_set1_groups_list(ctx.get(), rule)); ERR_clear_error(); } } @@ -1001,7 +1102,7 @@ TEST(SSLTest, CipherProperties) { NID_sha256, }, { - TLS1_CK_AES_256_GCM_SHA384, + TLS1_3_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", NID_aes_256_gcm, NID_undef, @@ -1010,7 +1111,7 @@ TEST(SSLTest, CipherProperties) { NID_sha384, }, { - TLS1_CK_AES_128_GCM_SHA256, + TLS1_3_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", NID_aes_128_gcm, NID_undef, @@ -1019,7 +1120,7 @@ TEST(SSLTest, CipherProperties) { NID_sha256, }, { - TLS1_CK_CHACHA20_POLY1305_SHA256, + TLS1_3_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", NID_chacha20_poly1305, NID_undef, @@ -1036,14 +1137,11 @@ TEST(SSLTest, CipherProperties) { ASSERT_TRUE(cipher); EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher)); - bssl::UniquePtr rfc_name(SSL_CIPHER_get_rfc_name(cipher)); - ASSERT_TRUE(rfc_name); - EXPECT_STREQ(t.standard_name, rfc_name.get()); - EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher)); EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher)); EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher)); EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher)); + EXPECT_EQ(t.prf_nid, EVP_MD_nid(SSL_CIPHER_get_handshake_digest(cipher))); EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher)); } } @@ -1099,6 +1197,12 @@ static bool GetClientHello(SSL *ssl, std::vector *out) { if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) { return false; } + + // We did not get far enough to write a ClientHello. + if (client_hello_len == 0) { + return false; + } + *out = std::vector(client_hello, client_hello + client_hello_len); return true; } @@ -1498,6 +1602,8 @@ static bool CreateClientAndServer(bssl::UniquePtr *out_client, struct ClientConfig { SSL_SESSION *session = nullptr; std::string servername; + std::string verify_hostname; + unsigned hostflags = 0; bool early_data = false; }; @@ -1520,6 +1626,12 @@ static bool ConnectClientAndServer(bssl::UniquePtr *out_client, !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) { return false; } + if (!config.verify_hostname.empty()) { + if (!SSL_set1_host(client.get(), config.verify_hostname.c_str())) { + return false; + } + SSL_set_hostflags(client.get(), config.hostflags); + } SSL_set_shed_handshake_config(client.get(), shed_handshake_config); SSL_set_shed_handshake_config(server.get(), shed_handshake_config); @@ -1965,6 +2077,7 @@ TEST(SSLTest, UnsupportedECHConfig) { TEST(SSLTest, ECHClientRandomsMatch) { bssl::UniquePtr server_ctx = CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(server_ctx); bssl::UniquePtr keys = MakeTestECHKeys(); ASSERT_TRUE(keys); ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get())); @@ -2258,6 +2371,8 @@ XRqE7XFhHL+7TNC2a9OOAjQsEF137YPWo+rhgko= ASSERT_TRUE(X509_STORE_add_cert(store.get(), root.get())); SSL_CTX_set_cert_store(client_ctx.get(), store.release()); SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER, nullptr); + X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()), + X509_V_FLAG_NO_CHECK_TIME); static const char kSecretName[] = "secret.example"; ASSERT_TRUE(X509_VERIFY_PARAM_set1_host(SSL_CTX_get0_param(client_ctx.get()), kSecretName, strlen(kSecretName))); @@ -2331,6 +2446,7 @@ TEST(SSLTest, ECHThreads) { bssl::UniquePtr server_ctx = CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(server_ctx); ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get())); bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); @@ -2358,6 +2474,81 @@ TEST(SSLTest, ECHThreads) { } #endif // OPENSSL_THREADS +TEST(SSLTest, TLS13ExporterAvailability) { + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + // Configure only TLS 1.3. + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(), + server_ctx.get())); + + std::vector buffer(32); + const char *label = "EXPORTER-test-label"; + + // The exporters are not available before the handshake starts. + EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + + // Send the client's first flight of handshake messages. + int client_ret = SSL_do_handshake(client.get()); + EXPECT_EQ(SSL_get_error(client.get(), client_ret), SSL_ERROR_WANT_READ); + + // The handshake isn't far enough for the exporters to work. + EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + + // Send all the server's handshake messages. + int server_ret = SSL_do_handshake(server.get()); + EXPECT_EQ(SSL_get_error(server.get(), server_ret), SSL_ERROR_WANT_READ); + + // At this point in the handshake, the server should have the exporter key + // derived since it's sent its Finished message. The client hasn't yet + // processed the server's handshake messages, so the exporter shouldn't be + // available to the client. + EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + + // Finish the handshake on the client. + EXPECT_EQ(SSL_do_handshake(client.get()), 1); + + // The exporter should be available on both endpoints. + EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + + // Finish the handshake on the server. + EXPECT_EQ(SSL_do_handshake(server.get()), 1); + + // The exporter should still be available on both endpoints. + EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); + EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(), + buffer.size(), label, strlen(label), + nullptr, 0, 0)); +} + static void AppendSession(SSL_SESSION *session, void *arg) { std::vector *out = reinterpret_cast*>(arg); @@ -3077,39 +3268,39 @@ TEST(SSLTest, ClientHello) { uint16_t max_version; std::vector expected; } kTests[] = { - {TLS1_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, - 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, - 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, - {TLS1_1_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, - 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, - 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, - {TLS1_2_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9, - 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, - 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, - 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, - 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, - 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, - 0x01, 0x02, 0x01}}, - // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our - // implementation has settled enough that it won't change. + {TLS1_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, + 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, + {TLS1_1_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, + 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, + {TLS1_2_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x7c, 0x03, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xcc, 0xa9, + 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, + 0x00, 0x35, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, + 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, + 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, + 0x01}}, + // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our + // implementation has settled enough that it won't change. }; for (const auto &t : kTests) { @@ -3163,7 +3354,7 @@ static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx, bssl::UniquePtr client, server; ClientConfig config; config.session = session; - EXPECT_TRUE( + ASSERT_TRUE( ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config)); EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get())); @@ -3341,8 +3532,10 @@ static bool GetServerTicketTime(long *out, const SSL_SESSION *session) { const uint8_t *iv = ticket + 16; bssl::ScopedEVP_CIPHER_CTX ctx; int len1, len2; - if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) || - !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) || + if (len > INT_MAX || + !EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) || + !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, + static_cast(len)) || !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) { return false; } @@ -3368,7 +3561,7 @@ TEST_P(SSLVersionTest, SessionTimeout) { for (bool server_test : {false, true}) { SCOPED_TRACE(server_test); - ResetContexts(); + ASSERT_NO_FATAL_FAILURE(ResetContexts()); SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH); SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH); @@ -3895,18 +4088,18 @@ TEST_P(SSLVersionTest, AutoChain) { {cert_.get(), cert_.get()})); } -static bool ExpectBadWriteRetry() { +static bool ExpectSingleError(int lib, int reason) { + const char *expected = ERR_reason_error_string(ERR_PACK(lib, reason)); int err = ERR_get_error(); - if (ERR_GET_LIB(err) != ERR_LIB_SSL || - ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) { + if (ERR_GET_LIB(err) != lib || ERR_GET_REASON(err) != reason) { char buf[ERR_ERROR_STRING_BUF_LEN]; ERR_error_string_n(err, buf, sizeof(buf)); - fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf); + fprintf(stderr, "Wanted %s, got: %s.\n", expected, buf); return false; } if (ERR_peek_error() != 0) { - fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n"); + fprintf(stderr, "Unexpected error following %s.\n", expected); return false; } @@ -3922,8 +4115,6 @@ TEST_P(SSLVersionTest, SSLWriteRetry) { SCOPED_TRACE(enable_partial_write); // Connect a client and server. - ASSERT_TRUE(UseCertAndKey(client_ctx_.get())); - ASSERT_TRUE(Connect()); if (enable_partial_write) { @@ -3942,9 +4133,7 @@ TEST_P(SSLVersionTest, SSLWriteRetry) { ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE); break; } - ASSERT_EQ(ret, 5); - count++; } @@ -3957,14 +4146,14 @@ TEST_P(SSLVersionTest, SSLWriteRetry) { ASSERT_EQ(SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen - 1)), SSL_ERROR_SSL); - ASSERT_TRUE(ExpectBadWriteRetry()); + ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY)); // Retrying with a different buffer pointer is not legal. char data2[] = "hello"; ASSERT_EQ(SSL_get_error(client_.get(), SSL_write(client_.get(), data2, kChunkLen)), SSL_ERROR_SSL); - ASSERT_TRUE(ExpectBadWriteRetry()); + ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY)); // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move. SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); @@ -3976,7 +4165,7 @@ TEST_P(SSLVersionTest, SSLWriteRetry) { ASSERT_EQ(SSL_get_error(client_.get(), SSL_write(client_.get(), data2, kChunkLen - 1)), SSL_ERROR_SSL); - ASSERT_TRUE(ExpectBadWriteRetry()); + ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY)); // Retrying with a larger buffer is legal. ASSERT_EQ(SSL_get_error(client_.get(), @@ -3994,27 +4183,101 @@ TEST_P(SSLVersionTest, SSLWriteRetry) { // pending record, skip over that many bytes of input (on assumption they // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE // is set, this will complete in two steps. - char data3[] = "_____!"; + char data_longer[] = "_____!!!!!"; if (enable_partial_write) { - ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen); - ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1); + ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen), + kChunkLen); + ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen), + kChunkLen); } else { - ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1); + ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen), + 2 * kChunkLen); } // Check the last write was correct. The data will be spread over two // records, so SSL_read returns twice. ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); - ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1); - ASSERT_EQ(buf[0], '!'); + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0); + + // Fill the transport buffer again. This time only leave room for one + // record. + count = 0; + for (;;) { + int ret = SSL_write(client_.get(), data, kChunkLen); + if (ret <= 0) { + ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE); + break; + } + ASSERT_EQ(ret, 5); + count++; + } + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); + count--; + + // Retry the last write, with a longer input. The first half is the most + // recently failed write, from filling the buffer. |SSL_write| should write + // that to the transport, and then attempt to write the second half. + int ret = SSL_write(client_.get(), data_longer, 2 * kChunkLen); + if (enable_partial_write) { + // If partial writes are allowed, the write will succeed partially. + ASSERT_EQ(ret, kChunkLen); + + // Check the first half and make room for another record. + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); + count--; + + // Finish writing the input. + ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen), + kChunkLen); + } else { + // Otherwise, although the first half made it to the transport, the second + // half is blocked. + ASSERT_EQ(ret, -1); + ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_WRITE); + + // Check the first half and make room for another record. + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); + count--; + + // Retrying with fewer bytes than previously attempted is an error. If the + // input length is less than the number of bytes successfully written, the + // check happens at a different point, with a different error. + // + // TODO(davidben): Should these cases use the same error? + ASSERT_EQ( + SSL_get_error(client_.get(), + SSL_write(client_.get(), data_longer, kChunkLen - 1)), + SSL_ERROR_SSL); + ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_LENGTH)); + + // Complete the write with the correct retry. + ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen), + 2 * kChunkLen); + } + + // Drain the input and ensure everything was written correctly. + for (unsigned i = 0; i < count; i++) { + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); + } + + // The final write is spread over two records. + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0); + ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen); + ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0); } } TEST_P(SSLVersionTest, RecordCallback) { for (bool test_server : {true, false}) { SCOPED_TRACE(test_server); - ResetContexts(); + ASSERT_NO_FATAL_FAILURE(ResetContexts()); bool read_seen = false; bool write_seen = false; @@ -4579,6 +4842,7 @@ static void ConnectClientAndServerWithTicketMethod( state->retry_count = retry_count; state->failure_mode = failure_mode; + ASSERT_GE(ssl_test_ticket_aead_get_ex_index(), 0); ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(), state)); @@ -4632,9 +4896,9 @@ TEST_P(TicketAEADMethodTest, Resume) { SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod); bssl::UniquePtr client, server; - ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(), - server_ctx.get(), retry_count, - failure_mode, nullptr); + ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod( + &client, &server, client_ctx.get(), server_ctx.get(), retry_count, + failure_mode, nullptr)); switch (failure_mode) { case ssl_test_ticket_aead_ok: case ssl_test_ticket_aead_open_hard_fail: @@ -4650,9 +4914,9 @@ TEST_P(TicketAEADMethodTest, Resume) { ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get())); bssl::UniquePtr session = std::move(g_last_session); - ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(), - server_ctx.get(), retry_count, - failure_mode, session.get()); + ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod( + &client, &server, client_ctx.get(), server_ctx.get(), retry_count, + failure_mode, session.get())); switch (failure_mode) { case ssl_test_ticket_aead_ok: ASSERT_TRUE(client); @@ -4685,7 +4949,7 @@ std::string TicketAEADMethodParamToString( } } char retry_count[256]; - snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param)); + snprintf(retry_count, sizeof(retry_count), "%u", std::get<1>(params.param)); ret += "_"; ret += retry_count; ret += "Retries_"; @@ -4759,157 +5023,6 @@ TEST(SSLTest, SelectNextProto) { EXPECT_EQ(Bytes("x"), Bytes(result, result_len)); } -TEST(SSLTest, SealRecord) { - bssl::UniquePtr client_ctx(SSL_CTX_new(TLSv1_2_method())), - server_ctx(CreateContextWithTestCertificate(TLSv1_2_method())); - ASSERT_TRUE(client_ctx); - ASSERT_TRUE(server_ctx); - - bssl::UniquePtr client, server; - ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), - server_ctx.get())); - - const std::vector record = {1, 2, 3, 4, 5}; - std::vector prefix( - bssl::SealRecordPrefixLen(client.get(), record.size())), - body(record.size()), - suffix(bssl::SealRecordSuffixLen(client.get(), record.size())); - ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix), - bssl::MakeSpan(body), bssl::MakeSpan(suffix), - record)); - - std::vector sealed; - sealed.insert(sealed.end(), prefix.begin(), prefix.end()); - sealed.insert(sealed.end(), body.begin(), body.end()); - sealed.insert(sealed.end(), suffix.begin(), suffix.end()); - std::vector sealed_copy = sealed; - - bssl::Span plaintext; - size_t record_len; - uint8_t alert = 255; - EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert, - bssl::MakeSpan(sealed)), - bssl::OpenRecordResult::kOK); - EXPECT_EQ(record_len, sealed.size()); - EXPECT_EQ(plaintext, record); - EXPECT_EQ(255, alert); -} - -TEST(SSLTest, SealRecordInPlace) { - bssl::UniquePtr client_ctx(SSL_CTX_new(TLSv1_2_method())), - server_ctx(CreateContextWithTestCertificate(TLSv1_2_method())); - ASSERT_TRUE(client_ctx); - ASSERT_TRUE(server_ctx); - - bssl::UniquePtr client, server; - ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), - server_ctx.get())); - - const std::vector plaintext = {1, 2, 3, 4, 5}; - std::vector record = plaintext; - std::vector prefix( - bssl::SealRecordPrefixLen(client.get(), record.size())), - suffix(bssl::SealRecordSuffixLen(client.get(), record.size())); - ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix), - bssl::MakeSpan(record), bssl::MakeSpan(suffix), - record)); - record.insert(record.begin(), prefix.begin(), prefix.end()); - record.insert(record.end(), suffix.begin(), suffix.end()); - - bssl::Span result; - size_t record_len; - uint8_t alert; - EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert, - bssl::MakeSpan(record)), - bssl::OpenRecordResult::kOK); - EXPECT_EQ(record_len, record.size()); - EXPECT_EQ(plaintext, result); -} - -TEST(SSLTest, SealRecordTrailingData) { - bssl::UniquePtr client_ctx(SSL_CTX_new(TLSv1_2_method())), - server_ctx(CreateContextWithTestCertificate(TLSv1_2_method())); - ASSERT_TRUE(client_ctx); - ASSERT_TRUE(server_ctx); - - bssl::UniquePtr client, server; - ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), - server_ctx.get())); - - const std::vector plaintext = {1, 2, 3, 4, 5}; - std::vector record = plaintext; - std::vector prefix( - bssl::SealRecordPrefixLen(client.get(), record.size())), - suffix(bssl::SealRecordSuffixLen(client.get(), record.size())); - ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix), - bssl::MakeSpan(record), bssl::MakeSpan(suffix), - record)); - record.insert(record.begin(), prefix.begin(), prefix.end()); - record.insert(record.end(), suffix.begin(), suffix.end()); - record.insert(record.end(), {5, 4, 3, 2, 1}); - - bssl::Span result; - size_t record_len; - uint8_t alert; - EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert, - bssl::MakeSpan(record)), - bssl::OpenRecordResult::kOK); - EXPECT_EQ(record_len, record.size() - 5); - EXPECT_EQ(plaintext, result); -} - -TEST(SSLTest, SealRecordInvalidSpanSize) { - bssl::UniquePtr client_ctx(SSL_CTX_new(TLSv1_2_method())), - server_ctx(CreateContextWithTestCertificate(TLSv1_2_method())); - ASSERT_TRUE(client_ctx); - ASSERT_TRUE(server_ctx); - - bssl::UniquePtr client, server; - ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), - server_ctx.get())); - - std::vector record = {1, 2, 3, 4, 5}; - std::vector prefix( - bssl::SealRecordPrefixLen(client.get(), record.size())), - body(record.size()), - suffix(bssl::SealRecordSuffixLen(client.get(), record.size())); - - auto expect_err = []() { - int err = ERR_get_error(); - EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL); - EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL); - ERR_clear_error(); - }; - EXPECT_FALSE(bssl::SealRecord( - client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1), - bssl::MakeSpan(record), bssl::MakeSpan(suffix), record)); - expect_err(); - EXPECT_FALSE(bssl::SealRecord( - client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1), - bssl::MakeSpan(record), bssl::MakeSpan(suffix), record)); - expect_err(); - - EXPECT_FALSE( - bssl::SealRecord(client.get(), bssl::MakeSpan(prefix), - bssl::MakeSpan(record.data(), record.size() - 1), - bssl::MakeSpan(suffix), record)); - expect_err(); - EXPECT_FALSE( - bssl::SealRecord(client.get(), bssl::MakeSpan(prefix), - bssl::MakeSpan(record.data(), record.size() + 1), - bssl::MakeSpan(suffix), record)); - expect_err(); - - EXPECT_FALSE(bssl::SealRecord( - client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record), - bssl::MakeSpan(suffix.data(), suffix.size() - 1), record)); - expect_err(); - EXPECT_FALSE(bssl::SealRecord( - client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record), - bssl::MakeSpan(suffix.data(), suffix.size() + 1), record)); - expect_err(); -} - // The client should gracefully handle no suitable ciphers being enabled. TEST(SSLTest, NoCiphersAvailable) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); @@ -5137,7 +5250,7 @@ TEST(SSLTest, Handoff) { SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT); SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession); - SSL_CTX_set_handoff_mode(server_ctx.get(), 1); + SSL_CTX_set_handoff_mode(server_ctx.get(), true); uint8_t keys[48]; SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys)); SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys)); @@ -5185,6 +5298,7 @@ TEST(SSLTest, Handoff) { ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff)); bssl::UniquePtr handshaker(SSL_new(handshaker_ctx.get())); + ASSERT_TRUE(handshaker); // Note split handshakes determines 0-RTT support, for both the current // handshake and newly-issued tickets, entirely by |handshaker|. There is // no need to call |SSL_set_early_data_enabled| on |server|. @@ -5210,6 +5324,7 @@ TEST(SSLTest, Handoff) { ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback)); bssl::UniquePtr server2(SSL_new(server_ctx.get())); + ASSERT_TRUE(server2); ASSERT_TRUE(SSL_apply_handback(server2.get(), handback)); MoveBIOs(server2.get(), handshaker.get()); @@ -5242,7 +5357,7 @@ TEST(SSLTest, HandoffDeclined) { ASSERT_TRUE(client_ctx); ASSERT_TRUE(server_ctx); - SSL_CTX_set_handoff_mode(server_ctx.get(), 1); + SSL_CTX_set_handoff_mode(server_ctx.get(), true); ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION)); bssl::UniquePtr client, server; @@ -5337,6 +5452,7 @@ TEST(SSLTest, SigAlgs) { }; UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); unsigned n = 1; for (const auto &test : kTests) { @@ -5392,6 +5508,7 @@ TEST(SSLTest, SigAlgsList) { }; UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); unsigned n = 1; for (const auto &test : kTests) { @@ -5417,11 +5534,13 @@ TEST(SSLTest, SigAlgsList) { TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) { bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(server_ctx); bssl::UniquePtr server(SSL_new(server_ctx.get())); + ASSERT_TRUE(server); // handoff is a handoff message that has been artificially modified to pretend - // that only cipher 0x0A is supported. When it is applied to |server|, all - // ciphers but that one should be removed. + // that only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) is supported. When + // it is applied to |server|, all ciphers but that one should be removed. // // To make a new one of these, try sticking this in the |Handoff| test above: // @@ -5442,12 +5561,12 @@ TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) { 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, - 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00, - 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, + 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0xc0, + 0x2f, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1d, }; - EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get()))); + EXPECT_LT(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get()))); ASSERT_TRUE( SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)})); EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get()))); @@ -5455,11 +5574,13 @@ TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) { TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) { bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(server_ctx); bssl::UniquePtr server(SSL_new(server_ctx.get())); + ASSERT_TRUE(server); // handoff is a handoff message that has been artificially modified to pretend - // that only one curve is supported. When it is applied to |server|, all - // curves but that one should be removed. + // that only one ECDH group is supported. When it is applied to |server|, all + // groups but that one should be removed. // // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of // these. @@ -5495,10 +5616,12 @@ TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) { // flush them. bssl::UniquePtr server_ctx( CreateContextWithTestCertificate(TLS_method())); + ASSERT_TRUE(server_ctx); EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)); EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION)); bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(client_ctx); EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION)); @@ -5579,7 +5702,7 @@ TEST_P(SSLVersionTest, SessionCacheThreads) { ClientConfig config; config.session = session; UniquePtr client, server; - EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), server_ctx_.get(), config)); }; @@ -5672,7 +5795,7 @@ TEST_P(SSLVersionTest, SessionCacheThreads) { TEST_P(SSLVersionTest, SessionTicketThreads) { for (bool renew_ticket : {false, true}) { SCOPED_TRACE(renew_ticket); - ResetContexts(); + ASSERT_NO_FATAL_FAILURE(ResetContexts()); SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH); SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH); if (renew_ticket) { @@ -5691,7 +5814,7 @@ TEST_P(SSLVersionTest, SessionTicketThreads) { ClientConfig config; config.session = session; UniquePtr client, server; - EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), server_ctx_.get(), config)); }; @@ -5728,6 +5851,8 @@ TEST(SSLTest, GetCertificateThreads) { X509 *cert2 = SSL_CTX_get0_certificate(ctx.get()); thread.join(); + ASSERT_TRUE(cert2); + ASSERT_TRUE(cert2_thread); EXPECT_EQ(cert2, cert2_thread); EXPECT_EQ(0, X509_cmp(cert.get(), cert2)); } @@ -5778,7 +5903,7 @@ TEST_P(SSLVersionTest, SessionPropertiesThreads) { bssl::UniquePtr peer(SSL_get_peer_certificate(ssl)); EXPECT_TRUE(peer); EXPECT_TRUE(SSL_get_current_cipher(ssl)); - EXPECT_TRUE(SSL_get_curve_id(ssl)); + EXPECT_TRUE(SSL_get_group_id(ssl)); }; std::vector threads; @@ -5790,6 +5915,81 @@ TEST_P(SSLVersionTest, SessionPropertiesThreads) { thread.join(); } } + +static void SetValueOnFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int index, long argl, void *argp) { + if (ptr != nullptr) { + *static_cast(ptr) = argl; + } +} + +// Test that one thread can register ex_data while another thread is destroying +// an object that uses it. +TEST(SSLTest, ExDataThreads) { + static bool already_run = false; + if (already_run) { + GTEST_SKIP() << "This test consumes process-global resources and can only " + "be run once in a process. It is not compatible with " + "--gtest_repeat."; + } + already_run = true; + + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + + // Register an initial index, so the threads can exercise having any ex_data. + int first_index = + SSL_get_ex_new_index(-1, nullptr, nullptr, nullptr, SetValueOnFree); + ASSERT_GE(first_index, 0); + + // Callers may register indices concurrently with using other indices. This + // may happen if one part of an application is initializing while another part + // is already running. + static constexpr int kNumIndices = 3; + static constexpr int kNumSSLs = 10; + int index[kNumIndices]; + long values[kNumSSLs]; + std::fill(std::begin(values), std::end(values), -2); + std::vector threads; + for (size_t i = 0; i < kNumIndices; i++) { + threads.emplace_back([&, i] { + index[i] = SSL_get_ex_new_index(static_cast(i), nullptr, nullptr, + nullptr, SetValueOnFree); + ASSERT_GE(index[i], 0); + }); + } + for (size_t i = 0; i < kNumSSLs; i++) { + threads.emplace_back([&, i] { + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); + ASSERT_TRUE(SSL_set_ex_data(ssl.get(), first_index, &values[i])); + }); + } + for (auto &thread : threads) { + thread.join(); + } + + // Each of the SSL threads should have set their flag via ex_data. + for (size_t i = 0; i < kNumSSLs; i++) { + EXPECT_EQ(values[i], -1); + } + + // Each of the newly-registered indices should be distinct and work correctly. + static_assert(kNumIndices <= kNumSSLs, "values buffer too small"); + std::fill(std::begin(values), std::end(values), -2); + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); + for (size_t i = 0; i < kNumIndices; i++) { + for (size_t j = 0; j < i; j++) { + EXPECT_NE(index[i], index[j]); + } + ASSERT_TRUE(SSL_set_ex_data(ssl.get(), index[i], &values[i])); + } + ssl = nullptr; + for (size_t i = 0; i < kNumIndices; i++) { + EXPECT_EQ(values[i], static_cast(i)); + } +} #endif // OPENSSL_THREADS constexpr size_t kNumQUICLevels = 4; @@ -6100,8 +6300,10 @@ class QUICMethodTest : public testing::Test { SSL_set_accept_state(server_.get()); transport_.reset(new MockQUICTransportPair); - ex_data_.Set(client_.get(), transport_->client()); - ex_data_.Set(server_.get(), transport_->server()); + if (!ex_data_.Set(client_.get(), transport_->client()) || + !ex_data_.Set(server_.get(), transport_->server())) { + return false; + } if (allow_out_of_order_writes_) { transport_->client()->AllowOutOfOrderWrites(); transport_->server()->AllowOutOfOrderWrites(); @@ -6311,13 +6513,13 @@ TEST_F(QUICMethodTest, HelloRetryRequest) { ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method)); ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method)); - // BoringSSL predicts the most preferred curve, so using different preferences - // will trigger HelloRetryRequest. + // BoringSSL predicts the most preferred ECDH group, so using different + // preferences will trigger HelloRetryRequest. static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1}; - ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs, + ASSERT_TRUE(SSL_CTX_set1_groups(client_ctx_.get(), kClientPrefs, OPENSSL_ARRAY_SIZE(kClientPrefs))); static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519}; - ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs, + ASSERT_TRUE(SSL_CTX_set1_groups(server_ctx_.get(), kServerPrefs, OPENSSL_ARRAY_SIZE(kServerPrefs))); ASSERT_TRUE(CreateClientAndServer()); @@ -6489,7 +6691,7 @@ TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) { // The server will consume the ClientHello, but it will not accept 0-RTT. ASSERT_TRUE(ProvideHandshakeData(server_.get())); ASSERT_EQ(SSL_do_handshake(server_.get()), -1); - EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1)); + ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1)); EXPECT_FALSE(SSL_in_early_data(server_.get())); EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data)); @@ -6557,7 +6759,7 @@ TEST_F(QUICMethodTest, ZeroRTTReject) { // Configure the server to prefer P-256, which will reject 0-RTT via // HelloRetryRequest. int p256 = NID_X9_62_prime256v1; - ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1)); + ASSERT_TRUE(SSL_set1_groups(server_.get(), &p256, 1)); } else { // Disable 0-RTT on the server, so it will reject it. SSL_set_early_data_enabled(server_.get(), 0); @@ -6574,7 +6776,7 @@ TEST_F(QUICMethodTest, ZeroRTTReject) { // The server will consume the ClientHello, but it will not accept 0-RTT. ASSERT_TRUE(ProvideHandshakeData(server_.get())); ASSERT_EQ(SSL_do_handshake(server_.get()), -1); - EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1)); + ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1)); EXPECT_FALSE(SSL_in_early_data(server_.get())); EXPECT_FALSE( transport_->server()->HasReadSecret(ssl_encryption_early_data)); @@ -6742,8 +6944,8 @@ TEST_F(QUICMethodTest, Buffered) { ASSERT_TRUE(CreateClientAndServer()); BufferedFlight client_flight, server_flight; - buffered_flights.Set(client_.get(), &client_flight); - buffered_flights.Set(server_.get(), &server_flight); + ASSERT_TRUE(buffered_flights.Set(client_.get(), &client_flight)); + ASSERT_TRUE(buffered_flights.Set(server_.get(), &server_flight)); ASSERT_TRUE(CompleteHandshakesForQUIC()); @@ -6964,10 +7166,10 @@ TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) { EXPECT_FALSE(g_last_session); ASSERT_TRUE(ProvideHandshakeData(client_.get())); EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1); - EXPECT_TRUE(g_last_session); + ASSERT_TRUE(g_last_session); // Pretend that g_last_session came from a TLS-over-TCP connection. - g_last_session.get()->is_quic = false; + g_last_session->is_quic = false; // Create a second connection and verify that resumption does not occur with // a session from a non-QUIC connection. This tests that the client does not @@ -7005,7 +7207,7 @@ TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) { EXPECT_FALSE(g_last_session); ASSERT_TRUE(ProvideHandshakeData(client_.get())); EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1); - EXPECT_TRUE(g_last_session); + ASSERT_TRUE(g_last_session); // Attempt a resumption with g_last_session using TLS_method. bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); @@ -7022,7 +7224,7 @@ TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) { // The TLS-over-TCP client will refuse to resume with a quic session, so // mark is_quic = false to bypass the client check to test the server check. - g_last_session.get()->is_quic = false; + g_last_session->is_quic = false; SSL_set_session(client.get(), g_last_session.get()); BIO *bio1, *bio2; @@ -7381,7 +7583,7 @@ TEST_P(SSLVersionTest, TicketSessionIDsMatch) { bssl::UniquePtr client, server; ClientConfig config; config.session = session.get(); - EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(), server_ctx_.get(), config)); EXPECT_TRUE(SSL_session_reused(client.get())); EXPECT_TRUE(SSL_session_reused(server.get())); @@ -7389,33 +7591,11 @@ TEST_P(SSLVersionTest, TicketSessionIDsMatch) { EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get()))); } -TEST(SSLTest, WriteWhileExplicitRenegotiate) { - bssl::UniquePtr ctx(CreateContextWithTestCertificate(TLS_method())); - ASSERT_TRUE(ctx); - - ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION)); - ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION)); - ASSERT_TRUE(SSL_CTX_set_strict_cipher_list( - ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")); - - bssl::UniquePtr client, server; - ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get())); - SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit); - ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); - - static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'}; - - // Write "hello" until the buffer is full, so |client| has a pending write. - size_t num_writes = 0; - for (;;) { - int ret = SSL_write(client.get(), kInput, sizeof(kInput)); - if (ret != int(sizeof(kInput))) { - ASSERT_EQ(-1, ret); - ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret)); - break; - } - num_writes++; - } +static void WriteHelloRequest(SSL *server) { + // This function assumes TLS 1.2 with ChaCha20-Poly1305. + ASSERT_EQ(SSL_version(server), TLS1_2_VERSION); + ASSERT_EQ(SSL_CIPHER_get_cipher_nid(SSL_get_current_cipher(server)), + NID_chacha20_poly1305); // Encrypt a HelloRequest. uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0}; @@ -7432,16 +7612,15 @@ TEST(SSLTest, WriteWhileExplicitRenegotiate) { // Extract key material from |server|. static const size_t kKeyLen = 32; static const size_t kNonceLen = 12; - ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get())); + ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server)); uint8_t key_block[2u * (kKeyLen + kNonceLen)]; - ASSERT_TRUE( - SSL_generate_key_block(server.get(), key_block, sizeof(key_block))); + ASSERT_TRUE(SSL_generate_key_block(server, key_block, sizeof(key_block))); Span key = MakeSpan(key_block + kKeyLen, kKeyLen); Span nonce = MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen); uint8_t ad[13]; - uint64_t seq = SSL_get_write_sequence(server.get()); + uint64_t seq = SSL_get_write_sequence(server); for (size_t i = 0; i < 8; i++) { // The nonce is XORed with the sequence number. nonce[11 - i] ^= uint8_t(seq); @@ -7474,7 +7653,38 @@ TEST(SSLTest, WriteWhileExplicitRenegotiate) { #endif // BORINGSSL_UNSAFE_FUZZER_MODE ASSERT_EQ(int(sizeof(record)), - BIO_write(SSL_get_wbio(server.get()), record, sizeof(record))); + BIO_write(SSL_get_wbio(server), record, sizeof(record))); +} + +TEST(SSLTest, WriteWhileExplicitRenegotiate) { + bssl::UniquePtr ctx(CreateContextWithTestCertificate(TLS_method())); + ASSERT_TRUE(ctx); + + ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_strict_cipher_list( + ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get())); + SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit); + ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); + + static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'}; + + // Write "hello" until the buffer is full, so |client| has a pending write. + size_t num_writes = 0; + for (;;) { + int ret = SSL_write(client.get(), kInput, sizeof(kInput)); + if (ret != int(sizeof(kInput))) { + ASSERT_EQ(-1, ret); + ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret)); + break; + } + num_writes++; + } + + ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get())); // |SSL_read| should pick up the HelloRequest. uint8_t byte; @@ -7516,6 +7726,58 @@ TEST(SSLTest, WriteWhileExplicitRenegotiate) { EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err)); } +TEST(SSLTest, ConnectionPropertiesDuringRenegotiate) { + // Configure known connection properties, so we can check against them. + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + bssl::UniquePtr cert = GetTestCertificate(); + ASSERT_TRUE(cert); + bssl::UniquePtr key = GetTestKey(); + ASSERT_TRUE(key); + ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get())); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_strict_cipher_list( + ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")); + ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), "X25519")); + ASSERT_TRUE(SSL_CTX_set1_sigalgs_list(ctx.get(), "rsa_pkcs1_sha256")); + + // Connect a client and server that accept renegotiation. + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get())); + SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely); + ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); + + auto check_properties = [&] { + EXPECT_EQ(SSL_version(client.get()), TLS1_2_VERSION); + const SSL_CIPHER *cipher = SSL_get_current_cipher(client.get()); + ASSERT_TRUE(cipher); + EXPECT_EQ(SSL_CIPHER_get_id(cipher), + uint32_t{TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}); + EXPECT_EQ(SSL_get_group_id(client.get()), SSL_GROUP_X25519); + EXPECT_EQ(SSL_get_negotiated_group(client.get()), NID_X25519); + EXPECT_EQ(SSL_get_peer_signature_algorithm(client.get()), + SSL_SIGN_RSA_PKCS1_SHA256); + bssl::UniquePtr peer(SSL_get_peer_certificate(client.get())); + ASSERT_TRUE(peer); + EXPECT_EQ(X509_cmp(cert.get(), peer.get()), 0); + }; + check_properties(); + + // The server sends a HelloRequest. + ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get())); + + // Reading from the client will consume the HelloRequest, start a + // renegotiation, and then block on a ServerHello from the server. + uint8_t byte; + ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1)); + ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1)); + + // Connection properties should continue to report values from the original + // handshake. + check_properties(); +} TEST(SSLTest, CopyWithoutEarlyData) { bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); @@ -7668,8 +7930,8 @@ TEST(SSLTest, BIO) { // |BIO_should_write|. int ret; for (int i = 0; i < 1024; i++) { - std::vector buffer(1024); - ret = BIO_write(client_bio.get(), buffer.data(), buffer.size()); + const uint8_t kZeros[1024] = {0}; + ret = BIO_write(client_bio.get(), kZeros, sizeof(kZeros)); if (ret <= 0) { break; } @@ -7706,7 +7968,7 @@ TEST(SSLTest, ALPNConfig) { auto check_alpn_proto = [&](Span expected) { observed_alpn.clear(); bssl::UniquePtr client, server; - EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get())); + ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get())); EXPECT_EQ(Bytes(expected), Bytes(observed_alpn)); }; @@ -8002,5 +8264,520 @@ TEST(SSLTest, PermuteExtensions) { } } +TEST(SSLTest, HostMatching) { + static const char kCertPEM[] = R"( +-----BEGIN CERTIFICATE----- +MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw +DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2 +MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD +VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO +Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW +ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3 +Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP +YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD +AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu +5DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY= +-----END CERTIFICATE----- +)"; + bssl::UniquePtr cert(CertFromPEM(kCertPEM)); + ASSERT_TRUE(cert); + static const char kCertNoSANsPEM[] = R"( +-----BEGIN CERTIFICATE----- +MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw +EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy +MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV +MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE +u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw +L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG +CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG +SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW +pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4= +-----END CERTIFICATE----- +)"; + bssl::UniquePtr cert_no_sans(CertFromPEM(kCertNoSANsPEM)); + ASSERT_TRUE(cert_no_sans); + + static const char kKeyPEM[] = R"( +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ +MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+ +RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm +-----END PRIVATE KEY----- +)"; + bssl::UniquePtr key(KeyFromPEM(kKeyPEM)); + ASSERT_TRUE(key); + + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()), + cert.get())); + ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()), + cert_no_sans.get())); + SSL_CTX_set_verify(client_ctx.get(), + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()), + X509_V_FLAG_NO_CHECK_TIME); + + struct TestCase { + X509 *cert; + std::string hostname; + unsigned flags; + bool should_match; + }; + std::vector kTests = { + // These two names are present as SANs in the certificate. + {cert.get(), "example1.com", 0, true}, + {cert.get(), "example2.com", 0, true}, + // This is the CN of the certificate, but that shouldn't matter if a SAN + // extension is present. + {cert.get(), "example3.com", 0, false}, + // If the SAN is not present, we, for now, look for DNS names in the CN. + {cert_no_sans.get(), "example3.com", 0, true}, + // ... but this can be turned off. + {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, + false}, + // a*.example4.com is a SAN, but is invalid. + {cert.get(), "abc.example4.com", 0, false}, + // *.example5.com is a SAN in the certificate, which is a normal and valid + // wildcard. + {cert.get(), "abc.example5.com", 0, true}, + // This name is not present. + {cert.get(), "notexample1.com", 0, false}, + // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a + // hostname that happens to be its textual representation. + {cert.get(), "1.2.3.4", 0, false}, + }; + + for (const TestCase &test : kTests) { + SCOPED_TRACE(test.hostname); + + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(server_ctx); + ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert)); + ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())); + + ClientConfig config; + bssl::UniquePtr client, server; + config.verify_hostname = test.hostname; + config.hostflags = test.flags; + EXPECT_EQ(test.should_match, + ConnectClientAndServer(&client, &server, client_ctx.get(), + server_ctx.get(), config)); + } +} + +TEST(SSLTest, NumTickets) { + bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(server_ctx); + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(client_ctx); + bssl::UniquePtr cert = GetTestCertificate(); + ASSERT_TRUE(cert); + bssl::UniquePtr key = GetTestKey(); + ASSERT_TRUE(key); + ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get())); + ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())); + SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH); + + SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH); + static size_t ticket_count; + SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int { + ticket_count++; + return 0; + }); + + auto count_tickets = [&]() -> size_t { + ticket_count = 0; + bssl::UniquePtr client, server; + if (!ConnectClientAndServer(&client, &server, client_ctx.get(), + server_ctx.get()) || + !FlushNewSessionTickets(client.get(), server.get())) { + ADD_FAILURE() << "Could not run handshake"; + return 0; + } + return ticket_count; + }; + + // By default, we should send two tickets. + EXPECT_EQ(count_tickets(), 2u); + + for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) { + SCOPED_TRACE(num_tickets); + ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets)); + EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), num_tickets); + EXPECT_EQ(count_tickets(), num_tickets); + } + + // Configuring too many tickets causes us to stop at some point. + ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000)); + EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), 16u); + EXPECT_EQ(count_tickets(), 16u); +} + +TEST(SSLTest, CertSubjectsToStack) { + const std::string kCert1 = R"( +-----BEGIN CERTIFICATE----- +MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC +QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ +BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l +dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni +v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa +HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw +HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ +BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E +BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ= +-----END CERTIFICATE----- +)"; + const std::vector kName1 = { + 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, + 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64}; + const std::string kCert2 = R"( +-----BEGIN CERTIFICATE----- +MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE +ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg +Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y +aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c +oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j +5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh +TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG +CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0 +4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB +gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y +rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU +xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg== +-----END CERTIFICATE----- +)"; + const std::vector kName2 = { + 0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c, + 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}; + + const struct { + std::vector> existing; + std::string pem; + std::vector> expected; + } kTests[] = { + // Do nothing. + {{}, "", {}}, + // Append to an empty list, skipping duplicates. + {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}}, + // One of the names was already present. + {{kName1}, kCert1 + kCert2, {kName1, kName2}}, + // Both names were already present. + {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}}, + // Preserve existing duplicates. + {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}}, + }; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) { + SCOPED_TRACE(i); + const auto &t = kTests[i]; + + bssl::UniquePtr stack(sk_X509_NAME_new_null()); + ASSERT_TRUE(stack); + for (const auto& name : t.existing) { + const uint8_t *inp = name.data(); + bssl::UniquePtr name_obj( + d2i_X509_NAME(nullptr, &inp, name.size())); + ASSERT_TRUE(name_obj); + EXPECT_EQ(inp, name.data() + name.size()); + ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj))); + } + + bssl::UniquePtr bio(BIO_new_mem_buf(t.pem.data(), t.pem.size())); + ASSERT_TRUE(bio); + ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get())); + + // The function should have left |stack|'s comparison function alone. + EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr)); + + std::vector> expected = t.expected, result; + for (X509_NAME *name : stack.get()) { + uint8_t *der = nullptr; + int der_len = i2d_X509_NAME(name, &der); + ASSERT_GE(der_len, 0); + result.push_back(std::vector(der, der + der_len)); + OPENSSL_free(der); + } + + // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a + // well-defined order. + std::sort(expected.begin(), expected.end()); + std::sort(result.begin(), result.end()); + EXPECT_EQ(result, expected); + } +} + +#if defined(OPENSSL_LINUX) || defined(OPENSSL_APPLE) +TEST(SSLTest, EmptyClientCAList) { + // Use /dev/null on POSIX systems as an empty file. + bssl::UniquePtr names( + SSL_load_client_CA_file("/dev/null")); + EXPECT_FALSE(names); +} +#endif // OPENSSL_LINUX || OPENSSL_APPLE + +TEST(SSLTest, EmptyWriteBlockedOnHandshakeData) { + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + // Configure only TLS 1.3. This test requires post-handshake NewSessionTicket. + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + + // Connect a client and server with tiny buffer between the two. + bssl::UniquePtr client(SSL_new(client_ctx.get())), + server(SSL_new(server_ctx.get())); + ASSERT_TRUE(client); + ASSERT_TRUE(server); + SSL_set_connect_state(client.get()); + SSL_set_accept_state(server.get()); + BIO *bio1, *bio2; + ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1)); + SSL_set_bio(client.get(), bio1, bio1); + SSL_set_bio(server.get(), bio2, bio2); + ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); + + // We defer NewSessionTicket to the first write, so the server has a pending + // NewSessionTicket. See https://boringssl-review.googlesource.com/34948. This + // means an empty write will flush the ticket. However, the transport only + // allows one byte through, so this will fail with |SSL_ERROR_WANT_WRITE|. + int ret = SSL_write(server.get(), nullptr, 0); + ASSERT_EQ(ret, -1); + ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE); + + // Attempting to write non-zero data should not trip |SSL_R_BAD_WRITE_RETRY|. + const uint8_t kData[] = {'h', 'e', 'l', 'l', 'o'}; + ret = SSL_write(server.get(), kData, sizeof(kData)); + ASSERT_EQ(ret, -1); + ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE); + + // Byte by byte, the data should eventually get through. + uint8_t buf[sizeof(kData)]; + for (;;) { + ret = SSL_read(client.get(), buf, sizeof(buf)); + ASSERT_EQ(ret, -1); + ASSERT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ); + + ret = SSL_write(server.get(), kData, sizeof(kData)); + if (ret > 0) { + ASSERT_EQ(ret, 5); + break; + } + ASSERT_EQ(ret, -1); + ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE); + } + + ret = SSL_read(client.get(), buf, sizeof(buf)); + ASSERT_EQ(ret, static_cast(sizeof(kData))); + ASSERT_EQ(Bytes(buf, ret), Bytes(kData)); +} + +// Test that |SSL_ERROR_SYSCALL| continues to work after a close_notify. +TEST(SSLTest, ErrorSyscallAfterCloseNotify) { + // Make a custom |BIO| where writes fail, but without pushing to the error + // queue. + bssl::UniquePtr method(BIO_meth_new(0, nullptr)); + ASSERT_TRUE(method); + BIO_meth_set_create(method.get(), [](BIO *b) -> int { + BIO_set_init(b, 1); + return 1; + }); + static bool write_failed = false; + BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int { + // Fail the operation and don't add to the error queue. + write_failed = true; + return -1; + }); + bssl::UniquePtr wbio_silent_error(BIO_new(method.get())); + ASSERT_TRUE(wbio_silent_error); + + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + bssl::UniquePtr client, server; + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), + server_ctx.get())); + + // Replace the write |BIO| with |wbio_silent_error|. + SSL_set0_wbio(client.get(), wbio_silent_error.release()); + + // Writes should fail. There is nothing in the error queue, so + // |SSL_ERROR_SYSCALL| indicates the caller needs to check out-of-band. + const uint8_t data[1] = {0}; + int ret = SSL_write(client.get(), data, sizeof(data)); + EXPECT_EQ(ret, -1); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL); + EXPECT_TRUE(write_failed); + write_failed = false; + + // Send a close_notify from the server. It should return 0 because + // close_notify was sent, but not received. Confusingly, this is a success + // output for |SSL_shutdown|'s API. + EXPECT_EQ(SSL_shutdown(server.get()), 0); + + // Read the close_notify on the client. + uint8_t buf[1]; + ret = SSL_read(client.get(), buf, sizeof(buf)); + EXPECT_EQ(ret, 0); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN); + + // Further calls to |SSL_read| continue to report |SSL_ERROR_ZERO_RETURN|. + ret = SSL_read(client.get(), buf, sizeof(buf)); + EXPECT_EQ(ret, 0); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN); + + // Although the client has seen close_notify, it should continue to report + // |SSL_ERROR_SYSCALL| when its writes fail. + ret = SSL_write(client.get(), data, sizeof(data)); + EXPECT_EQ(ret, -1); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL); + EXPECT_TRUE(write_failed); + write_failed = false; + + // Cause |BIO_write| to fail with a return value of zero instead. + // |SSL_get_error| should not misinterpret this as a close_notify. + // + // This is not actually a correct implementation of |BIO_write|, but the rest + // of the code treats zero from |BIO_write| as an error, so ensure it does so + // correctly. Fixing https://crbug.com/boringssl/503 will make this case moot. + BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int { + write_failed = true; + return 0; + }); + ret = SSL_write(client.get(), data, sizeof(data)); + EXPECT_EQ(ret, 0); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL); + EXPECT_TRUE(write_failed); + write_failed = false; +} + +// Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving +// a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|. +TEST(SSLTest, QuietShutdown) { + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + SSL_CTX_set_quiet_shutdown(server_ctx.get(), 1); + bssl::UniquePtr client, server; + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), + server_ctx.get())); + + // Quiet shutdown is enabled, so |SSL_shutdown| on the server should + // immediately return that bidirectional shutdown "completed". + EXPECT_EQ(SSL_shutdown(server.get()), 1); + + // Shut down writes so the client gets an EOF. + EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(server.get()))); + + // Confirm no close notify was actually sent. Client reads should report a + // transport EOF, not a close_notify. (Both have zero return, but + // |SSL_get_error| is different.) + char buf[1]; + int ret = SSL_read(client.get(), buf, sizeof(buf)); + EXPECT_EQ(ret, 0); + EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL); + + // The server believes bidirectional shutdown completed, so reads should + // replay the (simulated) close_notify. + ret = SSL_read(server.get(), buf, sizeof(buf)); + EXPECT_EQ(ret, 0); + EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_ZERO_RETURN); +} + +TEST(SSLTest, InvalidSignatureAlgorithm) { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + + static const uint16_t kInvalidPrefs[] = {1234}; + EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs( + ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs))); + EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs( + ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs))); + + static const uint16_t kDuplicatePrefs[] = {SSL_SIGN_RSA_PKCS1_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256}; + EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs( + ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs))); + EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs( + ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs))); +} + +TEST(SSLTest, InvalidGroups) { + bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); + ASSERT_TRUE(ctx); + + static const uint16_t kInvalidIDs[] = {1234}; + EXPECT_FALSE(SSL_CTX_set1_group_ids( + ctx.get(), kInvalidIDs, OPENSSL_ARRAY_SIZE(kInvalidIDs))); + + // This is a valid NID, but it is not a valid group. + static const int kInvalidNIDs[] = {NID_rsaEncryption}; + EXPECT_FALSE(SSL_CTX_set1_groups( + ctx.get(), kInvalidNIDs, OPENSSL_ARRAY_SIZE(kInvalidNIDs))); +} + +TEST(SSLTest, NameLists) { + struct { + size_t (*func)(const char **, size_t); + std::vector expected; + } kTests[] = { + {SSL_get_all_version_names, {"TLSv1.3", "DTLSv1.2", "unknown"}}, + {SSL_get_all_standard_cipher_names, + {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256"}}, + {SSL_get_all_cipher_names, + {"ECDHE-ECDSA-AES128-GCM-SHA256", "TLS_AES_128_GCM_SHA256", "(NONE)"}}, + {SSL_get_all_group_names, {"P-256", "X25519"}}, + {SSL_get_all_signature_algorithm_names, + {"rsa_pkcs1_sha256", "ecdsa_secp256r1_sha256", "ecdsa_sha256"}}, + }; + for (const auto &t : kTests) { + size_t num = t.func(nullptr, 0); + EXPECT_GT(num, 0u); + + std::vector list(num); + EXPECT_EQ(num, t.func(list.data(), list.size())); + + // Check the expected values are in the list. + for (const auto &s : t.expected) { + EXPECT_NE(list.end(), std::find(list.begin(), list.end(), s)) + << "Could not find " << s; + } + + // Passing in a larger buffer should leave excess space alone. + std::vector list2(num + 1, "placeholder"); + EXPECT_EQ(num, t.func(list2.data(), list2.size())); + for (size_t i = 0; i < num; i++) { + EXPECT_STREQ(list[i], list2[i]); + } + EXPECT_STREQ(list2.back(), "placeholder"); + + // Passing in a shorter buffer should truncate the list. + for (size_t l = 0; l < num; l++) { + SCOPED_TRACE(l); + list2.resize(l); + EXPECT_EQ(num, t.func(list2.data(), list2.size())); + for (size_t i = 0; i < l; i++) { + EXPECT_STREQ(list[i], list2[i]); + } + } + } +} + } // namespace BSSL_NAMESPACE_END diff --git a/third_party/boringssl/kit/src/ssl/ssl_versions.cc b/third_party/boringssl/kit/src/ssl/ssl_versions.cc index 964f7c93..db298fb5 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_versions.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_versions.cc @@ -16,8 +16,11 @@ #include +#include + #include #include +#include #include "internal.h" #include "../crypto/internal.h" @@ -82,29 +85,29 @@ bool ssl_method_supports_version(const SSL_PROTOCOL_METHOD *method, // The following functions map between API versions and wire versions. The // public API works on wire versions. +static const char* kUnknownVersion = "unknown"; + +struct VersionInfo { + uint16_t version; + const char *name; +}; + +static const VersionInfo kVersionNames[] = { + {TLS1_3_VERSION, "TLSv1.3"}, + {TLS1_2_VERSION, "TLSv1.2"}, + {TLS1_1_VERSION, "TLSv1.1"}, + {TLS1_VERSION, "TLSv1"}, + {DTLS1_VERSION, "DTLSv1"}, + {DTLS1_2_VERSION, "DTLSv1.2"}, +}; + static const char *ssl_version_to_string(uint16_t version) { - switch (version) { - case TLS1_3_VERSION: - return "TLSv1.3"; - - case TLS1_2_VERSION: - return "TLSv1.2"; - - case TLS1_1_VERSION: - return "TLSv1.1"; - - case TLS1_VERSION: - return "TLSv1"; - - case DTLS1_VERSION: - return "DTLSv1"; - - case DTLS1_2_VERSION: - return "DTLSv1.2"; - - default: - return "unknown"; + for (const auto &v : kVersionNames) { + if (v.version == version) { + return v.name; + } } + return kUnknownVersion; } static uint16_t wire_version_to_api(uint16_t version) { @@ -383,6 +386,11 @@ const char *SSL_get_version(const SSL *ssl) { return ssl_version_to_string(ssl_version(ssl)); } +size_t SSL_get_all_version_names(const char **out, size_t max_out) { + return GetAllNames(out, max_out, MakeConstSpan(&kUnknownVersion, 1), + &VersionInfo::name, MakeConstSpan(kVersionNames)); +} + const char *SSL_SESSION_get_version(const SSL_SESSION *session) { return ssl_version_to_string(session->ssl_version); } diff --git a/third_party/boringssl/kit/src/ssl/ssl_x509.cc b/third_party/boringssl/kit/src/ssl/ssl_x509.cc index 26eb90a9..e4b3775b 100644 --- a/third_party/boringssl/kit/src/ssl/ssl_x509.cc +++ b/third_party/boringssl/kit/src/ssl/ssl_x509.cc @@ -284,7 +284,6 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) { chain.reset(sk_X509_new_null()); if (!chain) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } if (sess->is_server) { @@ -292,7 +291,6 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { // |SSL_get_peer_cert_chain|. chain_without_leaf.reset(sk_X509_new_null()); if (!chain_without_leaf) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -309,11 +307,9 @@ static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { leaf = UpRef(x509); } else if (chain_without_leaf && !PushToStack(chain_without_leaf.get(), UpRef(x509))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } if (!PushToStack(chain.get(), std::move(x509))) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -1041,7 +1037,11 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) { } STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) { - return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free); + // TODO(https://crbug.com/boringssl/407): |X509_NAME_dup| should be const. + auto name_dup = [](const X509_NAME *name) { + return X509_NAME_dup(const_cast(name)); + }; + return sk_X509_NAME_deep_copy(list, name_dup, X509_NAME_free); } static void set_client_CA_list(UniquePtr *ca_list, @@ -1100,7 +1100,6 @@ static STACK_OF(X509_NAME) * UniquePtr new_cache(sk_X509_NAME_new_null()); if (!new_cache) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return NULL; } @@ -1304,6 +1303,23 @@ int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) { return set_cert_store(&ssl->config->cert->verify_store, store, 1); } +int SSL_set1_host(SSL *ssl, const char *hostname) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return 0; + } + return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname, + strlen(hostname)); +} + +void SSL_set_hostflags(SSL *ssl, unsigned flags) { + check_ssl_x509_method(ssl); + if (!ssl->config) { + return; + } + X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags); +} + int SSL_alert_from_verify_result(long result) { switch (result) { case X509_V_ERR_CERT_CHAIN_TOO_LONG: diff --git a/third_party/boringssl/kit/src/ssl/t1_enc.cc b/third_party/boringssl/kit/src/ssl/t1_enc.cc index c8db457f..a985d38b 100644 --- a/third_party/boringssl/kit/src/ssl/t1_enc.cc +++ b/third_party/boringssl/kit/src/ssl/t1_enc.cc @@ -302,7 +302,7 @@ using namespace bssl; size_t SSL_get_key_block_len(const SSL *ssl) { // See |SSL_generate_key_block|. - if (SSL_in_init(ssl)) { + if (SSL_in_init(ssl) || ssl_protocol_version(ssl) > TLS1_2_VERSION) { return 0; } @@ -321,7 +321,7 @@ int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { // there are points where read and write states are from different epochs. // During a handshake, before ChangeCipherSpec, the encryption states may not // match |ssl->s3->client_random| and |ssl->s3->server_random|. - if (SSL_in_init(ssl)) { + if (SSL_in_init(ssl) || ssl_protocol_version(ssl) > TLS1_2_VERSION) { OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -333,16 +333,12 @@ int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len, int use_context) { - // Exporters may be used in False Start and server 0-RTT, where the handshake - // has progressed enough. Otherwise, they may not be used during a handshake. - if (SSL_in_init(ssl) && - !SSL_in_false_start(ssl) && - !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) { - OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); - return 0; - } - - if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // In TLS 1.3, the exporter may be used whenever the secret has been derived. + if (ssl->s3->have_version && ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (ssl->s3->exporter_secret_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } if (!use_context) { context = nullptr; context_len = 0; @@ -353,6 +349,13 @@ int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); } + // Exporters may be used in False Start, where the handshake has progressed + // enough. Otherwise, they may not be used during a handshake. + if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + size_t seed_len = 2 * SSL3_RANDOM_SIZE; if (use_context) { if (context_len >= 1u << 16) { @@ -363,7 +366,6 @@ int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, } Array seed; if (!seed.Init(seed_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/third_party/boringssl/kit/src/ssl/test/CMakeLists.txt b/third_party/boringssl/kit/src/ssl/test/CMakeLists.txt index bb9bd815..110c6833 100644 --- a/third_party/boringssl/kit/src/ssl/test/CMakeLists.txt +++ b/third_party/boringssl/kit/src/ssl/test/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(../../include) - add_executable( bssl_shim @@ -12,12 +10,9 @@ add_executable( test_config.cc test_state.cc ) +target_link_libraries(bssl_shim ssl crypto) -add_dependencies(bssl_shim global_target) - -target_link_libraries(bssl_shim test_support_lib ssl crypto) - -if(UNIX AND NOT APPLE AND NOT ANDROID) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_executable( handshaker @@ -30,10 +25,7 @@ if(UNIX AND NOT APPLE AND NOT ANDROID) test_config.cc test_state.cc ) - - add_dependencies(handshaker global_target) - - target_link_libraries(handshaker test_support_lib ssl crypto) + target_link_libraries(handshaker ssl crypto) else() # Declare a dummy target for run_tests to depend on. add_custom_target(handshaker) diff --git a/third_party/boringssl/kit/src/ssl/test/async_bio.cc b/third_party/boringssl/kit/src/ssl/test/async_bio.cc index fd351760..9eae290f 100644 --- a/third_party/boringssl/kit/src/ssl/test/async_bio.cc +++ b/third_party/boringssl/kit/src/ssl/test/async_bio.cc @@ -59,8 +59,8 @@ static int AsyncWrite(BIO *bio, const char *in, int inl) { return -1; } - if (!a->datagram && (size_t)inl > a->write_quota) { - inl = a->write_quota; + if (!a->datagram && static_cast(inl) > a->write_quota) { + inl = static_cast(a->write_quota); } int ret = BIO_write(bio->next_bio, in, inl); if (ret <= 0) { @@ -85,8 +85,8 @@ static int AsyncRead(BIO *bio, char *out, int outl) { return -1; } - if (!a->datagram && (size_t)outl > a->read_quota) { - outl = a->read_quota; + if (!a->datagram && static_cast(outl) > a->read_quota) { + outl = static_cast(a->read_quota); } int ret = BIO_read(bio->next_bio, out, outl); if (ret <= 0) { @@ -102,7 +102,7 @@ static long AsyncCtrl(BIO *bio, int cmd, long num, void *ptr) { return 0; } BIO_clear_retry_flags(bio); - int ret = BIO_ctrl(bio->next_bio, cmd, num, ptr); + long ret = BIO_ctrl(bio->next_bio, cmd, num, ptr); BIO_copy_next_retry(bio); return ret; } diff --git a/third_party/boringssl/kit/src/ssl/test/bssl_shim.cc b/third_party/boringssl/kit/src/ssl/test/bssl_shim.cc index f4e7fffd..e2f79d30 100644 --- a/third_party/boringssl/kit/src/ssl/test/bssl_shim.cc +++ b/third_party/boringssl/kit/src/ssl/test/bssl_shim.cc @@ -278,6 +278,20 @@ static uint16_t GetProtocolVersion(const SSL *ssl) { return 0x0201 + ~version; } +static bool CheckListContains(const char *type, + size_t (*list_func)(const char **, size_t), + const char *str) { + std::vector list(list_func(nullptr, 0)); + list_func(list.data(), list.size()); + for (const char *expected : list) { + if (strcmp(expected, str) == 0) { + return true; + } + } + fprintf(stderr, "Unexpected %s: %s\n", type, str); + return false; +} + // CheckAuthProperties checks, after the initial handshake is completed or // after a renegotiation, that authentication-related properties match |config|. static bool CheckAuthProperties(SSL *ssl, bool is_resume, @@ -407,9 +421,9 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, } if (config->expect_version != 0 && - SSL_version(ssl) != config->expect_version) { + SSL_version(ssl) != int{config->expect_version}) { fprintf(stderr, "want version %04x, got %04x\n", config->expect_version, - SSL_version(ssl)); + static_cast(SSL_version(ssl))); return false; } @@ -575,34 +589,32 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, if (config->expect_curve_id != 0) { uint16_t curve_id = SSL_get_curve_id(ssl); - if (static_cast(config->expect_curve_id) != curve_id) { + if (config->expect_curve_id != curve_id) { fprintf(stderr, "curve_id was %04x, wanted %04x\n", curve_id, - static_cast(config->expect_curve_id)); + config->expect_curve_id); return false; } } uint16_t cipher_id = SSL_CIPHER_get_protocol_id(SSL_get_current_cipher(ssl)); - if (config->expect_cipher_aes != 0 && - EVP_has_aes_hardware() && - static_cast(config->expect_cipher_aes) != cipher_id) { + if (config->expect_cipher_aes != 0 && EVP_has_aes_hardware() && + config->expect_cipher_aes != cipher_id) { fprintf(stderr, "Cipher ID was %04x, wanted %04x (has AES hardware)\n", - cipher_id, static_cast(config->expect_cipher_aes)); + cipher_id, config->expect_cipher_aes); return false; } - if (config->expect_cipher_no_aes != 0 && - !EVP_has_aes_hardware() && - static_cast(config->expect_cipher_no_aes) != cipher_id) { + if (config->expect_cipher_no_aes != 0 && !EVP_has_aes_hardware() && + config->expect_cipher_no_aes != cipher_id) { fprintf(stderr, "Cipher ID was %04x, wanted %04x (no AES hardware)\n", - cipher_id, static_cast(config->expect_cipher_no_aes)); + cipher_id, config->expect_cipher_no_aes); return false; } if (config->expect_cipher != 0 && - static_cast(config->expect_cipher) != cipher_id) { + config->expect_cipher != cipher_id) { fprintf(stderr, "Cipher ID was %04x, wanted %04x\n", cipher_id, - static_cast(config->expect_cipher)); + config->expect_cipher); return false; } @@ -666,14 +678,50 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, return false; } + if (config->expect_key_usage_invalid != !!SSL_was_key_usage_invalid(ssl)) { + fprintf(stderr, "X.509 key usage was %svalid, but wanted opposite.\n", + SSL_was_key_usage_invalid(ssl) ? "in" : ""); + return false; + } + + // Check all the selected parameters are covered by the string APIs. + if (!CheckListContains("version", SSL_get_all_version_names, + SSL_get_version(ssl)) || + !CheckListContains( + "cipher", SSL_get_all_standard_cipher_names, + SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl))) || + !CheckListContains("OpenSSL cipher name", SSL_get_all_cipher_names, + SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))) || + (SSL_get_group_id(ssl) != 0 && + !CheckListContains("group", SSL_get_all_group_names, + SSL_get_group_name(SSL_get_group_id(ssl)))) || + (SSL_get_peer_signature_algorithm(ssl) != 0 && + !CheckListContains( + "sigalg", SSL_get_all_signature_algorithm_names, + SSL_get_signature_algorithm_name( + SSL_get_peer_signature_algorithm(ssl), /*include_curve=*/0))) || + (SSL_get_peer_signature_algorithm(ssl) != 0 && + !CheckListContains( + "sigalg with curve", SSL_get_all_signature_algorithm_names, + SSL_get_signature_algorithm_name( + SSL_get_peer_signature_algorithm(ssl), /*include_curve=*/1)))) { + return false; + } + // Test that handshake hints correctly skipped the expected operations. - // - // TODO(davidben): Add support for TLS 1.2 hints and remove the version check. - // Also add a check for the session cache lookup. - if (config->handshake_hints && !config->allow_hint_mismatch && - SSL_version(ssl) == TLS1_3_VERSION) { + if (config->handshake_hints && !config->allow_hint_mismatch) { const TestState *state = GetTestState(ssl); - if (!SSL_used_hello_retry_request(ssl) && state->used_private_key) { + // If the private key operation is performed in the first roundtrip, a hint + // match should have skipped it. This is ECDHE-based cipher suites in TLS + // 1.2 and non-HRR handshakes in TLS 1.3. + bool private_key_allowed; + if (SSL_version(ssl) == TLS1_3_VERSION) { + private_key_allowed = SSL_used_hello_retry_request(ssl); + } else { + private_key_allowed = + SSL_CIPHER_get_kx_nid(SSL_get_current_cipher(ssl)) == NID_kx_rsa; + } + if (!private_key_allowed && state->used_private_key) { fprintf( stderr, "Performed private key operation, but hint should have skipped it\n"); @@ -685,6 +733,9 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume, "Performed ticket decryption, but hint should have skipped it\n"); return false; } + + // TODO(davidben): Decide what we want to do with TLS 1.2 stateful + // resumption. } return true; } diff --git a/third_party/boringssl/kit/src/ssl/test/fuzzer.h b/third_party/boringssl/kit/src/ssl/test/fuzzer.h index 00b5e844..e6d2d021 100644 --- a/third_party/boringssl/kit/src/ssl/test/fuzzer.h +++ b/third_party/boringssl/kit/src/ssl/test/fuzzer.h @@ -414,14 +414,15 @@ class TLSFuzzer { SSL_CTX_enable_ocsp_stapling(ctx_.get()); // Enable versions and ciphers that are off by default. - if (!SSL_CTX_set_strict_cipher_list(ctx_.get(), "ALL:NULL-SHA")) { + if (!SSL_CTX_set_strict_cipher_list(ctx_.get(), "ALL:3DES")) { return false; } - static const int kCurves[] = {NID_CECPQ2, NID_X25519, NID_X9_62_prime256v1, - NID_secp384r1, NID_secp521r1}; - if (!SSL_CTX_set1_curves(ctx_.get(), kCurves, - OPENSSL_ARRAY_SIZE(kCurves))) { + static const uint16_t kGroups[] = { + SSL_GROUP_X25519_KYBER768_DRAFT00, SSL_GROUP_X25519, + SSL_GROUP_SECP256R1, SSL_GROUP_SECP384R1, SSL_GROUP_SECP521R1}; + if (!SSL_CTX_set1_group_ids(ctx_.get(), kGroups, + OPENSSL_ARRAY_SIZE(kGroups))) { return false; } diff --git a/third_party/boringssl/kit/src/ssl/test/handshake_util.cc b/third_party/boringssl/kit/src/ssl/test/handshake_util.cc index b9998317..6516547f 100644 --- a/third_party/boringssl/kit/src/ssl/test/handshake_util.cc +++ b/third_party/boringssl/kit/src/ssl/test/handshake_util.cc @@ -255,7 +255,7 @@ static bool Proxy(BIO *socket, bool async, int control, int rfd, int wfd) { return false; } if (bytes_written != bytes_read) { - fprintf(stderr, "short write (%zu of %d bytes)\n", bytes_written, + fprintf(stderr, "short write (%zd of %d bytes)\n", bytes_written, bytes_read); return false; } diff --git a/third_party/boringssl/kit/src/ssl/test/handshaker.cc b/third_party/boringssl/kit/src/ssl/test/handshaker.cc index ac890633..72aaaa80 100644 --- a/third_party/boringssl/kit/src/ssl/test/handshaker.cc +++ b/third_party/boringssl/kit/src/ssl/test/handshaker.cc @@ -61,6 +61,8 @@ bool Handshaker(const TestConfig *config, int rfd, int wfd, UniquePtr ssl = config->NewSSL(ctx.get(), /*session=*/nullptr, /*test_state=*/nullptr); if (!ssl) { + fprintf(stderr, "Error creating SSL object in handshaker.\n"); + ERR_print_errors_fp(stderr); return false; } @@ -155,6 +157,8 @@ bool GenerateHandshakeHint(const TestConfig *config, config->NewSSL(ctx.get(), /*session=*/nullptr, std::unique_ptr(new TestState)); if (!ssl) { + fprintf(stderr, "Error creating SSL object in handshaker.\n"); + ERR_print_errors_fp(stderr); return false; } diff --git a/third_party/boringssl/kit/src/ssl/test/mock_quic_transport.cc b/third_party/boringssl/kit/src/ssl/test/mock_quic_transport.cc index 310b779a..b1c42f68 100644 --- a/third_party/boringssl/kit/src/ssl/test/mock_quic_transport.cc +++ b/third_party/boringssl/kit/src/ssl/test/mock_quic_transport.cc @@ -16,8 +16,9 @@ #include +#include +#include #include -#include MockQuicTransport::MockQuicTransport(bssl::UniquePtr bio, SSL *ssl) : bio_(std::move(bio)), @@ -51,11 +52,8 @@ bool ReadAll(BIO *bio, bssl::Span out) { size_t len = out.size(); uint8_t *buf = out.data(); while (len > 0) { - int chunk_len = std::numeric_limits::max(); - if (len <= static_cast(std::numeric_limits::max())) { - chunk_len = len; - } - int ret = BIO_read(bio, buf, chunk_len); + size_t chunk_len = std::min(len, size_t{INT_MAX}); + int ret = BIO_read(bio, buf, static_cast(chunk_len)); if (ret <= 0) { return false; } diff --git a/third_party/boringssl/kit/src/ssl/test/packeted_bio.cc b/third_party/boringssl/kit/src/ssl/test/packeted_bio.cc index 835dbfb1..35dd8a8f 100644 --- a/third_party/boringssl/kit/src/ssl/test/packeted_bio.cc +++ b/third_party/boringssl/kit/src/ssl/test/packeted_bio.cc @@ -195,7 +195,7 @@ static long PacketedCtrl(BIO *bio, int cmd, long num, void *ptr) { } BIO_clear_retry_flags(bio); - int ret = BIO_ctrl(bio->next_bio, cmd, num, ptr); + long ret = BIO_ctrl(bio->next_bio, cmd, num, ptr); BIO_copy_next_retry(bio); return ret; } diff --git a/third_party/boringssl/kit/src/ssl/test/runner/cipher_suites.go b/third_party/boringssl/kit/src/ssl/test/runner/cipher_suites.go index 5db57498..f7dcb9bf 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/cipher_suites.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/cipher_suites.go @@ -84,7 +84,7 @@ type cipherSuite struct { ka func(version uint16) keyAgreement // flags is a bitmask of the suite* values, above. flags int - cipher func(key, iv []byte, isRead bool) interface{} + cipher func(key, iv []byte, isRead bool) any mac func(version uint16, macKey []byte) macFunction aead func(version uint16, key, fixedNonce []byte) *tlsAead } @@ -127,11 +127,6 @@ var cipherSuites = []*cipherSuite{ {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, {TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil}, {TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_NULL_SHA, 0, 20, noIV, rsaKA, 0, cipherNull, macSHA1, nil}, -} - -func noIV(vers uint16) int { - return 0 } func ivLenChaCha20Poly1305(vers uint16) int { @@ -155,11 +150,11 @@ func ivLen3DES(vers uint16) int { type nullCipher struct{} -func cipherNull(key, iv []byte, isRead bool) interface{} { +func cipherNull(key, iv []byte, isRead bool) any { return nullCipher{} } -func cipher3DES(key, iv []byte, isRead bool) interface{} { +func cipher3DES(key, iv []byte, isRead bool) any { block, _ := des.NewTripleDESCipher(key) if isRead { return cipher.NewCBCDecrypter(block, iv) @@ -167,7 +162,7 @@ func cipher3DES(key, iv []byte, isRead bool) interface{} { return cipher.NewCBCEncrypter(block, iv) } -func cipherAES(key, iv []byte, isRead bool) interface{} { +func cipherAES(key, iv []byte, isRead bool) any { block, _ := aes.NewCipher(key) if isRead { return cipher.NewCBCDecrypter(block, iv) @@ -364,7 +359,6 @@ func cipherSuiteFromID(id uint16) *cipherSuite { // A list of the possible cipher suite ids. Taken from // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml const ( - TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 diff --git a/third_party/boringssl/kit/src/ssl/test/runner/common.go b/third_party/boringssl/kit/src/ssl/test/runner/common.go index bf6a3d17..d0279c6f 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/common.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/common.go @@ -148,12 +148,12 @@ var tls13HelloRetryRequest = []uint8{ type CurveID uint16 const ( - CurveP224 CurveID = 21 - CurveP256 CurveID = 23 - CurveP384 CurveID = 24 - CurveP521 CurveID = 25 - CurveX25519 CurveID = 29 - CurveCECPQ2 CurveID = 16696 + CurveP224 CurveID = 21 + CurveP256 CurveID = 23 + CurveP384 CurveID = 24 + CurveP521 CurveID = 25 + CurveX25519 CurveID = 29 + CurveX25519Kyber768 CurveID = 0x6399 ) // TLS Elliptic Curve Point Formats @@ -211,15 +211,24 @@ const ( // EdDSA algorithms signatureEd25519 signatureAlgorithm = 0x0807 signatureEd448 signatureAlgorithm = 0x0808 + + // signatureRSAPKCS1WithMD5AndSHA1 is the internal value BoringSSL uses to + // represent the TLS 1.0/1.1 RSA MD5/SHA1 concatenation. We define the + // constant here to test that this doesn't leak into the protocol. + signatureRSAPKCS1WithMD5AndSHA1 signatureAlgorithm = 0xff01 ) // supportedSignatureAlgorithms contains the default supported signature // algorithms. var supportedSignatureAlgorithms = []signatureAlgorithm{ signatureRSAPSSWithSHA256, + signatureRSAPSSWithSHA384, signatureRSAPKCS1WithSHA256, signatureECDSAWithP256AndSHA256, + signatureECDSAWithP384AndSHA384, signatureRSAPKCS1WithSHA1, + signatureRSAPKCS1WithSHA256, + signatureRSAPKCS1WithSHA384, signatureECDSAWithSHA1, signatureEd25519, } @@ -639,6 +648,14 @@ type ProtocolBugs struct { // HelloVerifyRequest message. SkipHelloVerifyRequest bool + // HelloVerifyRequestCookieLength, if non-zero, is the length of the cookie + // to request in HelloVerifyRequest. + HelloVerifyRequestCookieLength int + + // EmptyHelloVerifyRequestCookie, if true, causes a DTLS server to request + // an empty cookie in HelloVerifyRequest. + EmptyHelloVerifyRequestCookie bool + // SkipCertificateStatus, if true, causes the server to skip the // CertificateStatus message. This is legal because CertificateStatus is // optional, even with a status_request in ServerHello. @@ -1784,10 +1801,15 @@ type ProtocolBugs struct { // reject CertificateRequest with the CertificateAuthorities extension. ExpectNoCertificateAuthoritiesExtension bool - // UseLegacySigningAlgorithm, if non-zero, is the signature algorithm + // SigningAlgorithmForLegacyVersions, if non-zero, is the signature algorithm // to use when signing in TLS 1.1 and earlier where algorithms are not // negotiated. - UseLegacySigningAlgorithm signatureAlgorithm + SigningAlgorithmForLegacyVersions signatureAlgorithm + + // AlwaysSignAsLegacyVersion, if true, causes all TLS versions to sign as if + // they were TLS 1.1 and earlier. This can be paired with + // SendSignatureAlgorithm to send a given signature algorithm enum. + AlwaysSignAsLegacyVersion bool // RejectUnsolicitedKeyUpdate, if true, causes all unsolicited // KeyUpdates from the peer to be rejected. @@ -1872,9 +1894,9 @@ type ProtocolBugs struct { // hello retry. FailIfHelloRetryRequested bool - // FailedIfCECPQ2Offered will cause a server to reject a ClientHello if CECPQ2 + // FailedIfKyberOffered will cause a server to reject a ClientHello if Kyber // is supported. - FailIfCECPQ2Offered bool + FailIfKyberOffered bool // ExpectKeyShares, if not nil, lists (in order) the curves that a ClientHello // should have key shares for. @@ -1978,7 +2000,7 @@ func (c *Config) maxVersion(isDTLS bool) uint16 { return ret } -var defaultCurvePreferences = []CurveID{CurveCECPQ2, CurveX25519, CurveP256, CurveP384, CurveP521} +var defaultCurvePreferences = []CurveID{CurveX25519Kyber768, CurveX25519, CurveP256, CurveP384, CurveP521} func (c *Config) curvePreferences() []CurveID { if c == nil || len(c.CurvePreferences) == 0 { @@ -2169,11 +2191,11 @@ type lruSessionCache struct { type lruSessionCacheEntry struct { sessionKey string - state interface{} + state any } // Put adds the provided (sessionKey, cs) pair to the cache. -func (c *lruSessionCache) Put(sessionKey string, cs interface{}) { +func (c *lruSessionCache) Put(sessionKey string, cs any) { c.Lock() defer c.Unlock() @@ -2201,7 +2223,7 @@ func (c *lruSessionCache) Put(sessionKey string, cs interface{}) { // Get returns the value associated with a given key. It returns (nil, // false) if no value is found. -func (c *lruSessionCache) Get(sessionKey string) (interface{}, bool) { +func (c *lruSessionCache) Get(sessionKey string) (any, bool) { c.Lock() defer c.Unlock() @@ -2315,7 +2337,7 @@ func initDefaultCipherSuites() { } } -func unexpectedMessageError(wanted, got interface{}) error { +func unexpectedMessageError(wanted, got any) error { return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) } diff --git a/third_party/boringssl/kit/src/ssl/test/runner/conn.go b/third_party/boringssl/kit/src/ssl/test/runner/conn.go index ad77b665..2e9114db 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/conn.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/conn.go @@ -174,13 +174,13 @@ type halfConn struct { version uint16 // protocol version wireVersion uint16 // wire version isDTLS bool - cipher interface{} // cipher algorithm + cipher any // cipher algorithm mac macFunction seq [8]byte // 64-bit sequence number outSeq [8]byte // Mapped sequence number bfree *block // list of free blocks - nextCipher interface{} // next encryption state + nextCipher any // next encryption state nextMac macFunction // next MAC algorithm nextSeq [6]byte // next epoch's starting sequence number in DTLS @@ -207,7 +207,7 @@ func (hc *halfConn) error() error { // prepareCipherSpec sets the encryption and MAC states // that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) { +func (hc *halfConn) prepareCipherSpec(version uint16, cipher any, mac macFunction) { hc.wireVersion = version protocolVersion, ok := wireToVersion(version, hc.isDTLS) if !ok { @@ -1336,7 +1336,7 @@ func (c *Conn) doReadHandshake() ([]byte, error) { // readHandshake reads the next handshake message from // the record layer. // c.in.Mutex < L; c.out.Mutex < L. -func (c *Conn) readHandshake() (interface{}, error) { +func (c *Conn) readHandshake() (any, error) { data, err := c.doReadHandshake() if err != nil { return nil, err diff --git a/third_party/boringssl/kit/src/ssl/test/runner/handshake_client.go b/third_party/boringssl/kit/src/ssl/test/runner/handshake_client.go index 5d04994a..a51ed558 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/handshake_client.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/handshake_client.go @@ -33,7 +33,7 @@ type clientHandshakeState struct { echHPKEContext *hpke.Context suite *cipherSuite finishedHash finishedHash - keyShares map[CurveID]ecdhCurve + keyShares map[CurveID]kemImplementation masterSecret []byte session *ClientSessionState finishedBytes []byte @@ -98,7 +98,7 @@ func (c *Conn) clientHandshake() error { hs := &clientHandshakeState{ c: c, - keyShares: make(map[CurveID]ecdhCurve), + keyShares: make(map[CurveID]kemImplementation), } // Pick a session to resume. @@ -643,11 +643,11 @@ func (hs *clientHandshakeState) createClientHello(innerHello *clientHelloMsg, ec if !curvesToSend[curveID] { continue } - curve, ok := curveForCurveID(curveID, c.config) + kem, ok := kemForCurveID(curveID, c.config) if !ok { continue } - publicKey, err := curve.offer(c.config.rand()) + publicKey, err := kem.generate(c.config.rand()) if err != nil { return nil, err } @@ -663,7 +663,7 @@ func (hs *clientHandshakeState) createClientHello(innerHello *clientHelloMsg, ec group: curveID, keyExchange: publicKey, }) - hs.keyShares[curveID] = curve + hs.keyShares[curveID] = kem if c.config.Bugs.DuplicateKeyShares { hello.keyShares = append(hello.keyShares, hello.keyShares[len(hello.keyShares)-1]) @@ -925,7 +925,7 @@ func (hs *clientHandshakeState) encryptClientHello(hello, innerHello *clientHell return nil } -func (hs *clientHandshakeState) checkECHConfirmation(msg interface{}, hello *clientHelloMsg, finishedHash *finishedHash) bool { +func (hs *clientHandshakeState) checkECHConfirmation(msg any, hello *clientHelloMsg, finishedHash *finishedHash) bool { var offset int var raw, label []byte if hrr, ok := msg.(*helloRetryRequestMsg); ok { @@ -950,7 +950,7 @@ func (hs *clientHandshakeState) checkECHConfirmation(msg interface{}, hello *cli return bytes.Equal(confirmation, raw[offset:offset+echAcceptConfirmationLength]) } -func (hs *clientHandshakeState) doTLS13Handshake(msg interface{}) error { +func (hs *clientHandshakeState) doTLS13Handshake(msg any) error { c := hs.c // The first message may be a ServerHello or HelloRetryRequest. @@ -1122,7 +1122,7 @@ func (hs *clientHandshakeState) doTLS13Handshake(msg interface{}) error { // Resolve ECDHE and compute the handshake secret. ecdheSecret := zeroSecret if !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare { - curve, ok := hs.keyShares[hs.serverHello.keyShare.group] + kem, ok := hs.keyShares[hs.serverHello.keyShare.group] if !ok { c.sendAlert(alertHandshakeFailure) return errors.New("tls: server selected an unsupported group") @@ -1130,7 +1130,7 @@ func (hs *clientHandshakeState) doTLS13Handshake(msg interface{}) error { c.curveID = hs.serverHello.keyShare.group var err error - ecdheSecret, err = curve.finish(hs.serverHello.keyShare.keyExchange) + ecdheSecret, err = kem.decap(hs.serverHello.keyShare.keyExchange) if err != nil { return err } @@ -1529,15 +1529,15 @@ func (hs *clientHandshakeState) applyHelloRetryRequest(helloRetryRequest *helloR c.sendAlert(alertHandshakeFailure) return errors.New("tls: received invalid HelloRetryRequest") } - curve, ok := curveForCurveID(group, c.config) + kem, ok := kemForCurveID(group, c.config) if !ok { return errors.New("tls: Unable to get curve requested in HelloRetryRequest") } - publicKey, err := curve.offer(c.config.rand()) + publicKey, err := kem.generate(c.config.rand()) if err != nil { return err } - hs.keyShares[group] = curve + hs.keyShares[group] = kem hello.keyShares = []keyShareEntry{{ group: group, keyExchange: publicKey, @@ -1897,7 +1897,7 @@ func (hs *clientHandshakeState) establishKeys() error { clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen(c.vers)) - var clientCipher, serverCipher interface{} + var clientCipher, serverCipher any var clientHash, serverHash macFunction if hs.suite.cipher != nil { clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) diff --git a/third_party/boringssl/kit/src/ssl/test/runner/handshake_messages.go b/third_party/boringssl/kit/src/ssl/test/runner/handshake_messages.go index f2ef2fc8..b253b0c8 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/handshake_messages.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/handshake_messages.go @@ -841,6 +841,12 @@ func parseSignatureAlgorithms(reader *byteReader, out *[]signatureAlgorithm, all if !sigAlgs.readU16(&v) { return false } + if signatureAlgorithm(v) == signatureRSAPKCS1WithMD5AndSHA1 { + // signatureRSAPKCS1WithMD5AndSHA1 is an internal value BoringSSL + // uses to represent the TLS 1.0 MD5/SHA-1 concatenation. It should + // never appear on the wire. + return false + } *out = append(*out, signatureAlgorithm(v)) } return true @@ -872,11 +878,8 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { len(m.sessionID) > 32 { return false } - if m.isDTLS { - if !reader.readU8LengthPrefixedBytes(&m.cookie) || - len(m.cookie) > 32 { - return false - } + if m.isDTLS && !reader.readU8LengthPrefixedBytes(&m.cookie) { + return false } var cipherSuites byteReader if !reader.readU16LengthPrefixed(&cipherSuites) || diff --git a/third_party/boringssl/kit/src/ssl/test/runner/handshake_server.go b/third_party/boringssl/kit/src/ssl/test/runner/handshake_server.go index 4f411844..4130d9bc 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/handshake_server.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/handshake_server.go @@ -235,9 +235,16 @@ func (hs *serverHandshakeState) readClientHello() error { if c.isDTLS && !config.Bugs.SkipHelloVerifyRequest { // Per RFC 6347, the version field in HelloVerifyRequest SHOULD // be always DTLS 1.0 + cookieLen := c.config.Bugs.HelloVerifyRequestCookieLength + if cookieLen == 0 { + cookieLen = 32 + } + if c.config.Bugs.EmptyHelloVerifyRequestCookie { + cookieLen = 0 + } helloVerifyRequest := &helloVerifyRequestMsg{ vers: VersionDTLS10, - cookie: make([]byte, 32), + cookie: make([]byte, cookieLen), } if _, err := io.ReadFull(c.config.rand(), helloVerifyRequest.cookie); err != nil { c.sendAlert(alertInternalError) @@ -273,10 +280,10 @@ func (hs *serverHandshakeState) readClientHello() error { } } - if config.Bugs.FailIfCECPQ2Offered { + if config.Bugs.FailIfKyberOffered { for _, offeredCurve := range hs.clientHello.supportedCurves { if isPqGroup(offeredCurve) { - return errors.New("tls: CECPQ2 was offered") + return errors.New("tls: X25519Kyber768 was offered") } } } @@ -950,7 +957,7 @@ ResendHelloRetryRequest: // Once a curve has been selected and a key share identified, // the server needs to generate a public value and send it in // the ServerHello. - curve, ok := curveForCurveID(selectedCurve, config) + kem, ok := kemForCurveID(selectedCurve, config) if !ok { panic("tls: server failed to look up curve ID") } @@ -960,9 +967,9 @@ ResendHelloRetryRequest: if config.Bugs.SkipHelloRetryRequest { // If skipping HelloRetryRequest, use a random key to // avoid crashing. - curve2, _ := curveForCurveID(selectedCurve, config) + kem2, _ := kemForCurveID(selectedCurve, config) var err error - peerKey, err = curve2.offer(config.rand()) + peerKey, err = kem2.generate(config.rand()) if err != nil { return err } @@ -970,7 +977,7 @@ ResendHelloRetryRequest: peerKey = selectedKeyShare.keyExchange } - publicKey, ecdheSecret, err := curve.accept(config.rand(), peerKey) + ciphertext, ecdheSecret, err := kem.encap(config.rand(), peerKey) if err != nil { c.sendAlert(alertHandshakeFailure) return err @@ -984,19 +991,19 @@ ResendHelloRetryRequest: curveID = config.Bugs.SendCurve } if c.config.Bugs.InvalidECDHPoint { - publicKey[0] ^= 0xff + ciphertext[0] ^= 0xff } hs.hello.keyShare = keyShareEntry{ group: curveID, - keyExchange: publicKey, + keyExchange: ciphertext, } if config.Bugs.EncryptedExtensionsWithKeyShare { encryptedExtensions.extensions.hasKeyShare = true encryptedExtensions.extensions.keyShare = keyShareEntry{ group: curveID, - keyExchange: publicKey, + keyExchange: ciphertext, } } } else { @@ -1460,7 +1467,7 @@ func (hs *serverHandshakeState) processClientHello() (isResume bool, err error) Curves: for _, curve := range hs.clientHello.supportedCurves { if isPqGroup(curve) && c.vers < VersionTLS13 { - // CECPQ2 is TLS 1.3-only. + // Post-quantum is TLS 1.3 only. continue } @@ -2069,7 +2076,7 @@ func (hs *serverHandshakeState) establishKeys() error { clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen(c.vers)) - var clientCipher, serverCipher interface{} + var clientCipher, serverCipher any var clientHash, serverHash macFunction if hs.suite.aead == nil { diff --git a/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke.go b/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke.go index e6fc7be2..b65dcf33 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke.go @@ -14,7 +14,7 @@ // Package hpke implements Hybrid Public Key Encryption (HPKE). // -// See https://tools.ietf.org/html/draft-irtf-cfrg-hpke-12. +// See RFC 9180. package hpke import ( diff --git a/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke_test.go b/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke_test.go index eec16e9d..35503beb 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke_test.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/hpke/hpke_test.go @@ -23,7 +23,7 @@ import ( "errors" "flag" "fmt" - "io/ioutil" + "os" "path/filepath" "testing" ) @@ -98,7 +98,7 @@ type ExportTestVector struct { // TestVectors checks all relevant test vectors in test-vectors.json. func TestVectors(t *testing.T) { - jsonStr, err := ioutil.ReadFile(filepath.Join(*testDataDir, "test-vectors.json")) + jsonStr, err := os.ReadFile(filepath.Join(*testDataDir, "test-vectors.json")) if err != nil { t.Errorf("error reading test vectors: %s", err) return diff --git a/third_party/boringssl/kit/src/ssl/test/runner/hrss/hrss.go b/third_party/boringssl/kit/src/ssl/test/runner/hrss/hrss.go deleted file mode 100644 index 9f4fdd77..00000000 --- a/third_party/boringssl/kit/src/ssl/test/runner/hrss/hrss.go +++ /dev/null @@ -1,1212 +0,0 @@ -package hrss - -import ( - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "encoding/binary" - "io" - "math/bits" -) - -const ( - PublicKeySize = modQBytes - CiphertextSize = modQBytes -) - -const ( - N = 701 - Q = 8192 - mod3Bytes = 140 - modQBytes = 1138 -) - -const ( - bitsPerWord = bits.UintSize - wordsPerPoly = (N + bitsPerWord - 1) / bitsPerWord - fullWordsPerPoly = N / bitsPerWord - bitsInLastWord = N % bitsPerWord -) - -// poly3 represents a degree-N polynomial over GF(3). Each coefficient is -// bitsliced across the |s| and |a| arrays, like this: -// -// s | a | value -// ----------------- -// 0 | 0 | 0 -// 0 | 1 | 1 -// 1 | 0 | 2 (aka -1) -// 1 | 1 | -// -// ('s' is for sign, and 'a' is just a letter.) -// -// Once bitsliced as such, the following circuits can be used to implement -// addition and multiplication mod 3: -// -// (s3, a3) = (s1, a1) × (s2, a2) -// s3 = (s2 ∧ a1) ⊕ (s1 ∧ a2) -// a3 = (s1 ∧ s2) ⊕ (a1 ∧ a2) -// -// (s3, a3) = (s1, a1) + (s2, a2) -// t1 = ~(s1 ∨ a1) -// t2 = ~(s2 ∨ a2) -// s3 = (a1 ∧ a2) ⊕ (t1 ∧ s2) ⊕ (t2 ∧ s1) -// a3 = (s1 ∧ s2) ⊕ (t1 ∧ a2) ⊕ (t2 ∧ a1) -// -// Negating a value just involves swapping s and a. -type poly3 struct { - s [wordsPerPoly]uint - a [wordsPerPoly]uint -} - -func (p *poly3) trim() { - p.s[wordsPerPoly-1] &= (1 << bitsInLastWord) - 1 - p.a[wordsPerPoly-1] &= (1 << bitsInLastWord) - 1 -} - -func (p *poly3) zero() { - for i := range p.a { - p.s[i] = 0 - p.a[i] = 0 - } -} - -func (p *poly3) fromDiscrete(in *poly) { - var shift uint - s := p.s[:] - a := p.a[:] - s[0] = 0 - a[0] = 0 - - for _, v := range in { - s[0] >>= 1 - s[0] |= uint((v>>1)&1) << (bitsPerWord - 1) - a[0] >>= 1 - a[0] |= uint(v&1) << (bitsPerWord - 1) - shift++ - if shift == bitsPerWord { - s = s[1:] - a = a[1:] - s[0] = 0 - a[0] = 0 - shift = 0 - } - } - - a[0] >>= bitsPerWord - shift - s[0] >>= bitsPerWord - shift -} - -func (p *poly3) fromModQ(in *poly) int { - var shift uint - s := p.s[:] - a := p.a[:] - s[0] = 0 - a[0] = 0 - ok := 1 - - for _, v := range in { - vMod3, vOk := modQToMod3(v) - ok &= vOk - - s[0] >>= 1 - s[0] |= uint((vMod3>>1)&1) << (bitsPerWord - 1) - a[0] >>= 1 - a[0] |= uint(vMod3&1) << (bitsPerWord - 1) - shift++ - if shift == bitsPerWord { - s = s[1:] - a = a[1:] - s[0] = 0 - a[0] = 0 - shift = 0 - } - } - - a[0] >>= bitsPerWord - shift - s[0] >>= bitsPerWord - shift - - return ok -} - -func (p *poly3) fromDiscreteMod3(in *poly) { - var shift uint - s := p.s[:] - a := p.a[:] - s[0] = 0 - a[0] = 0 - - for _, v := range in { - // This duplicates the 13th bit upwards to the top of the - // uint16, essentially treating it as a sign bit and converting - // into a signed int16. The signed value is reduced mod 3, - // yeilding {-2, -1, 0, 1, 2}. - v = uint16((int16(v<<3)>>3)%3) & 7 - - // We want to map v thus: - // {-2, -1, 0, 1, 2} -> {1, 2, 0, 1, 2}. We take the bottom - // three bits and then the constants below, when shifted by - // those three bits, perform the required mapping. - s[0] >>= 1 - s[0] |= (0xbc >> v) << (bitsPerWord - 1) - a[0] >>= 1 - a[0] |= (0x7a >> v) << (bitsPerWord - 1) - shift++ - if shift == bitsPerWord { - s = s[1:] - a = a[1:] - s[0] = 0 - a[0] = 0 - shift = 0 - } - } - - a[0] >>= bitsPerWord - shift - s[0] >>= bitsPerWord - shift -} - -func (p *poly3) marshal(out []byte) { - s := p.s[:] - a := p.a[:] - sw := s[0] - aw := a[0] - var shift int - - for i := 0; i < 700; i += 5 { - acc, scale := 0, 1 - for j := 0; j < 5; j++ { - v := int(aw&1) | int(sw&1)<<1 - acc += scale * v - scale *= 3 - - shift++ - if shift == bitsPerWord { - s = s[1:] - a = a[1:] - sw = s[0] - aw = a[0] - shift = 0 - } else { - sw >>= 1 - aw >>= 1 - } - } - - out[0] = byte(acc) - out = out[1:] - } -} - -func (p *poly) fromMod2(in *poly2) { - var shift uint - words := in[:] - word := words[0] - - for i := range p { - p[i] = uint16(word & 1) - word >>= 1 - shift++ - if shift == bitsPerWord { - words = words[1:] - word = words[0] - shift = 0 - } - } -} - -func (p *poly) fromMod3(in *poly3) { - var shift uint - s := in.s[:] - a := in.a[:] - sw := s[0] - aw := a[0] - - for i := range p { - p[i] = uint16(aw&1 | (sw&1)<<1) - aw >>= 1 - sw >>= 1 - shift++ - if shift == bitsPerWord { - a = a[1:] - s = s[1:] - aw = a[0] - sw = s[0] - shift = 0 - } - } -} - -func (p *poly) fromMod3ToModQ(in *poly3) { - var shift uint - s := in.s[:] - a := in.a[:] - sw := s[0] - aw := a[0] - - for i := range p { - p[i] = mod3ToModQ(uint16(aw&1 | (sw&1)<<1)) - aw >>= 1 - sw >>= 1 - shift++ - if shift == bitsPerWord { - a = a[1:] - s = s[1:] - aw = a[0] - sw = s[0] - shift = 0 - } - } -} - -func lsbToAll(v uint) uint { - return uint(int(v<<(bitsPerWord-1)) >> (bitsPerWord - 1)) -} - -func (p *poly3) mulConst(ms, ma uint) { - ms = lsbToAll(ms) - ma = lsbToAll(ma) - - for i := range p.a { - p.s[i], p.a[i] = (ma&p.s[i])^(ms&p.a[i]), (ma&p.a[i])^(ms&p.s[i]) - } -} - -func cmovWords(out, in *[wordsPerPoly]uint, mov uint) { - for i := range out { - out[i] = (out[i] & ^mov) | (in[i] & mov) - } -} - -func rotWords(out, in *[wordsPerPoly]uint, bits uint) { - start := bits / bitsPerWord - n := (N - bits) / bitsPerWord - - for i := uint(0); i < n; i++ { - out[i] = in[start+i] - } - - carry := in[wordsPerPoly-1] - - for i := uint(0); i < start; i++ { - out[n+i] = carry | in[i]<> (bitsPerWord - bitsInLastWord) - } - - out[wordsPerPoly-1] = carry -} - -// rotBits right-rotates the bits in |in|. bits must be a non-zero power of two -// and less than bitsPerWord. -func rotBits(out, in *[wordsPerPoly]uint, bits uint) { - if (bits == 0 || (bits & (bits - 1)) != 0 || bits > bitsPerWord/2 || bitsInLastWord < bitsPerWord/2) { - panic("internal error"); - } - - carry := in[wordsPerPoly-1] << (bitsPerWord - bits) - - for i := wordsPerPoly - 2; i >= 0; i-- { - out[i] = carry | in[i]>>bits - carry = in[i] << (bitsPerWord - bits) - } - - out[wordsPerPoly-1] = carry>>(bitsPerWord-bitsInLastWord) | in[wordsPerPoly-1]>>bits -} - -func (p *poly3) rotWords(bits uint, in *poly3) { - rotWords(&p.s, &in.s, bits) - rotWords(&p.a, &in.a, bits) -} - -func (p *poly3) rotBits(bits uint, in *poly3) { - rotBits(&p.s, &in.s, bits) - rotBits(&p.a, &in.a, bits) -} - -func (p *poly3) cmov(in *poly3, mov uint) { - cmovWords(&p.s, &in.s, mov) - cmovWords(&p.a, &in.a, mov) -} - -func (p *poly3) rot(bits uint) { - if bits > N { - panic("invalid") - } - var shifted poly3 - - shift := uint(9) - for ; (1 << shift) >= bitsPerWord; shift-- { - shifted.rotWords(1<>shift)) - } - for ; shift < 9; shift-- { - shifted.rotBits(1<>shift)) - } -} - -func (p *poly3) fmadd(ms, ma uint, in *poly3) { - ms = lsbToAll(ms) - ma = lsbToAll(ma) - - for i := range p.a { - products := (ma & in.s[i]) ^ (ms & in.a[i]) - producta := (ma & in.a[i]) ^ (ms & in.s[i]) - - ns1Ana1 := ^p.s[i] & ^p.a[i] - ns2Ana2 := ^products & ^producta - - p.s[i], p.a[i] = (p.a[i]&producta)^(ns1Ana1&products)^(p.s[i]&ns2Ana2), (p.s[i]&products)^(ns1Ana1&producta)^(p.a[i]&ns2Ana2) - } -} - -func (p *poly3) modPhiN() { - factora := uint(int(p.s[wordsPerPoly-1]<<(bitsPerWord-bitsInLastWord)) >> (bitsPerWord - 1)) - factors := uint(int(p.a[wordsPerPoly-1]<<(bitsPerWord-bitsInLastWord)) >> (bitsPerWord - 1)) - ns2Ana2 := ^factors & ^factora - - for i := range p.s { - ns1Ana1 := ^p.s[i] & ^p.a[i] - p.s[i], p.a[i] = (p.a[i]&factora)^(ns1Ana1&factors)^(p.s[i]&ns2Ana2), (p.s[i]&factors)^(ns1Ana1&factora)^(p.a[i]&ns2Ana2) - } -} - -func (p *poly3) cswap(other *poly3, swap uint) { - for i := range p.s { - sums := swap & (p.s[i] ^ other.s[i]) - p.s[i] ^= sums - other.s[i] ^= sums - - suma := swap & (p.a[i] ^ other.a[i]) - p.a[i] ^= suma - other.a[i] ^= suma - } -} - -func (p *poly3) mulx() { - carrys := (p.s[wordsPerPoly-1] >> (bitsInLastWord - 1)) & 1 - carrya := (p.a[wordsPerPoly-1] >> (bitsInLastWord - 1)) & 1 - - for i := range p.s { - outCarrys := p.s[i] >> (bitsPerWord - 1) - outCarrya := p.a[i] >> (bitsPerWord - 1) - p.s[i] <<= 1 - p.a[i] <<= 1 - p.s[i] |= carrys - p.a[i] |= carrya - carrys = outCarrys - carrya = outCarrya - } -} - -func (p *poly3) divx() { - var carrys, carrya uint - - for i := len(p.s) - 1; i >= 0; i-- { - outCarrys := p.s[i] & 1 - outCarrya := p.a[i] & 1 - p.s[i] >>= 1 - p.a[i] >>= 1 - p.s[i] |= carrys << (bitsPerWord - 1) - p.a[i] |= carrya << (bitsPerWord - 1) - carrys = outCarrys - carrya = outCarrya - } -} - -type poly2 [wordsPerPoly]uint - -func (p *poly2) fromDiscrete(in *poly) { - var shift uint - words := p[:] - words[0] = 0 - - for _, v := range in { - words[0] >>= 1 - words[0] |= uint(v&1) << (bitsPerWord - 1) - shift++ - if shift == bitsPerWord { - words = words[1:] - words[0] = 0 - shift = 0 - } - } - - words[0] >>= bitsPerWord - shift -} - -func (p *poly2) setPhiN() { - for i := range p { - p[i] = ^uint(0) - } - p[wordsPerPoly-1] &= (1 << bitsInLastWord) - 1 -} - -func (p *poly2) cswap(other *poly2, swap uint) { - for i := range p { - sum := swap & (p[i] ^ other[i]) - p[i] ^= sum - other[i] ^= sum - } -} - -func (p *poly2) fmadd(m uint, in *poly2) { - m = ^(m - 1) - - for i := range p { - p[i] ^= in[i] & m - } -} - -func (p *poly2) lshift1() { - var carry uint - for i := range p { - nextCarry := p[i] >> (bitsPerWord - 1) - p[i] <<= 1 - p[i] |= carry - carry = nextCarry - } -} - -func (p *poly2) rshift1() { - var carry uint - for i := len(p) - 1; i >= 0; i-- { - nextCarry := p[i] & 1 - p[i] >>= 1 - p[i] |= carry << (bitsPerWord - 1) - carry = nextCarry - } -} - -func (p *poly2) rot(bits uint) { - if bits > N { - panic("invalid") - } - var shifted [wordsPerPoly]uint - out := (*[wordsPerPoly]uint)(p) - - shift := uint(9) - for ; (1 << shift) >= bitsPerWord; shift-- { - rotWords(&shifted, out, 1<>shift)) - } - for ; shift < 9; shift-- { - rotBits(&shifted, out, 1<>shift)) - } -} - -type poly [N]uint16 - -func (in *poly) marshal(out []byte) { - p := in[:] - - for len(p) >= 8 { - out[0] = byte(p[0]) - out[1] = byte(p[0]>>8) | byte((p[1]&0x07)<<5) - out[2] = byte(p[1] >> 3) - out[3] = byte(p[1]>>11) | byte((p[2]&0x3f)<<2) - out[4] = byte(p[2]>>6) | byte((p[3]&0x01)<<7) - out[5] = byte(p[3] >> 1) - out[6] = byte(p[3]>>9) | byte((p[4]&0x0f)<<4) - out[7] = byte(p[4] >> 4) - out[8] = byte(p[4]>>12) | byte((p[5]&0x7f)<<1) - out[9] = byte(p[5]>>7) | byte((p[6]&0x03)<<6) - out[10] = byte(p[6] >> 2) - out[11] = byte(p[6]>>10) | byte((p[7]&0x1f)<<3) - out[12] = byte(p[7] >> 5) - - p = p[8:] - out = out[13:] - } - - // There are four remaining values. - out[0] = byte(p[0]) - out[1] = byte(p[0]>>8) | byte((p[1]&0x07)<<5) - out[2] = byte(p[1] >> 3) - out[3] = byte(p[1]>>11) | byte((p[2]&0x3f)<<2) - out[4] = byte(p[2]>>6) | byte((p[3]&0x01)<<7) - out[5] = byte(p[3] >> 1) - out[6] = byte(p[3] >> 9) -} - -func (out *poly) unmarshal(in []byte) bool { - p := out[:] - for i := 0; i < 87; i++ { - p[0] = uint16(in[0]) | uint16(in[1]&0x1f)<<8 - p[1] = uint16(in[1]>>5) | uint16(in[2])<<3 | uint16(in[3]&3)<<11 - p[2] = uint16(in[3]>>2) | uint16(in[4]&0x7f)<<6 - p[3] = uint16(in[4]>>7) | uint16(in[5])<<1 | uint16(in[6]&0xf)<<9 - p[4] = uint16(in[6]>>4) | uint16(in[7])<<4 | uint16(in[8]&1)<<12 - p[5] = uint16(in[8]>>1) | uint16(in[9]&0x3f)<<7 - p[6] = uint16(in[9]>>6) | uint16(in[10])<<2 | uint16(in[11]&7)<<10 - p[7] = uint16(in[11]>>3) | uint16(in[12])<<5 - - p = p[8:] - in = in[13:] - } - - // There are four coefficients left over - p[0] = uint16(in[0]) | uint16(in[1]&0x1f)<<8 - p[1] = uint16(in[1]>>5) | uint16(in[2])<<3 | uint16(in[3]&3)<<11 - p[2] = uint16(in[3]>>2) | uint16(in[4]&0x7f)<<6 - p[3] = uint16(in[4]>>7) | uint16(in[5])<<1 | uint16(in[6]&0xf)<<9 - - if in[6]&0xf0 != 0 { - return false - } - - out[N-1] = 0 - var top int - for _, v := range out { - top += int(v) - } - - out[N-1] = uint16(-top) % Q - return true -} - -func (in *poly) marshalS3(out []byte) { - p := in[:] - for len(p) >= 5 { - out[0] = byte(p[0] + p[1]*3 + p[2]*9 + p[3]*27 + p[4]*81) - out = out[1:] - p = p[5:] - } -} - -func (out *poly) unmarshalS3(in []byte) bool { - p := out[:] - for i := 0; i < 140; i++ { - c := in[0] - if c >= 243 { - return false - } - p[0] = uint16(c % 3) - p[1] = uint16((c / 3) % 3) - p[2] = uint16((c / 9) % 3) - p[3] = uint16((c / 27) % 3) - p[4] = uint16((c / 81) % 3) - - p = p[5:] - in = in[1:] - } - - out[N-1] = 0 - return true -} - -func (p *poly) modPhiN() { - for i := range p { - p[i] = (p[i] + Q - p[N-1]) % Q - } -} - -func (out *poly) shortSample(in []byte) { - // b a result - // 00 00 00 - // 00 01 01 - // 00 10 10 - // 00 11 11 - // 01 00 10 - // 01 01 00 - // 01 10 01 - // 01 11 11 - // 10 00 01 - // 10 01 10 - // 10 10 00 - // 10 11 11 - // 11 00 11 - // 11 01 11 - // 11 10 11 - // 11 11 11 - - // 1111 1111 1100 1001 1101 0010 1110 0100 - // f f c 9 d 2 e 4 - const lookup = uint32(0xffc9d2e4) - - p := out[:] - for i := 0; i < 87; i++ { - v := binary.LittleEndian.Uint32(in) - v2 := (v & 0x55555555) + ((v >> 1) & 0x55555555) - for j := 0; j < 8; j++ { - p[j] = uint16(lookup >> ((v2 & 15) << 1) & 3) - v2 >>= 4 - } - p = p[8:] - in = in[4:] - } - - // There are four values remaining. - v := binary.LittleEndian.Uint32(in) - v2 := (v & 0x55555555) + ((v >> 1) & 0x55555555) - for j := 0; j < 4; j++ { - p[j] = uint16(lookup >> ((v2 & 15) << 1) & 3) - v2 >>= 4 - } - - out[N-1] = 0 -} - -func (out *poly) shortSamplePlus(in []byte) { - out.shortSample(in) - - var sum uint16 - for i := 0; i < N-1; i++ { - sum += mod3ResultToModQ(out[i] * out[i+1]) - } - - scale := 1 + (1 & (sum >> 12)) - for i := 0; i < len(out); i += 2 { - out[i] = (out[i] * scale) % 3 - } -} - -func mul(out, scratch, a, b []uint16) { - const schoolbookLimit = 32 - if len(a) < schoolbookLimit { - for i := 0; i < len(a)*2; i++ { - out[i] = 0 - } - for i := range a { - for j := range b { - out[i+j] += a[i] * b[j] - } - } - return - } - - lowLen := len(a) / 2 - highLen := len(a) - lowLen - aLow, aHigh := a[:lowLen], a[lowLen:] - bLow, bHigh := b[:lowLen], b[lowLen:] - - for i := 0; i < lowLen; i++ { - out[i] = aHigh[i] + aLow[i] - } - if highLen != lowLen { - out[lowLen] = aHigh[lowLen] - } - - for i := 0; i < lowLen; i++ { - out[highLen+i] = bHigh[i] + bLow[i] - } - if highLen != lowLen { - out[highLen+lowLen] = bHigh[lowLen] - } - - mul(scratch, scratch[2*highLen:], out[:highLen], out[highLen:highLen*2]) - mul(out[lowLen*2:], scratch[2*highLen:], aHigh, bHigh) - mul(out, scratch[2*highLen:], aLow, bLow) - - for i := 0; i < lowLen*2; i++ { - scratch[i] -= out[i] + out[lowLen*2+i] - } - if lowLen != highLen { - scratch[lowLen*2] -= out[lowLen*4] - } - - for i := 0; i < 2*highLen; i++ { - out[lowLen+i] += scratch[i] - } -} - -func (out *poly) mul(a, b *poly) { - var prod, scratch [2 * N]uint16 - mul(prod[:], scratch[:], a[:], b[:]) - for i := range out { - out[i] = (prod[i] + prod[i+N]) % Q - } -} - -func (p3 *poly3) mulMod3(x, y *poly3) { - // (𝑥^n - 1) is a multiple of Φ(N) so we can work mod (𝑥^n - 1) here and - // (reduce mod Φ(N) afterwards. - x3 := *x - y3 := *y - s := x3.s[:] - a := x3.a[:] - sw := s[0] - aw := a[0] - p3.zero() - var shift uint - for i := 0; i < N; i++ { - p3.fmadd(sw, aw, &y3) - sw >>= 1 - aw >>= 1 - shift++ - if shift == bitsPerWord { - s = s[1:] - a = a[1:] - sw = s[0] - aw = a[0] - shift = 0 - } - y3.mulx() - } - p3.modPhiN() -} - -// mod3ToModQ maps {0, 1, 2, 3} to {0, 1, Q-1, 0xffff} -// The case of n == 3 should never happen but is included so that modQToMod3 -// can easily catch invalid inputs. -func mod3ToModQ(n uint16) uint16 { - return uint16(uint64(0xffff1fff00010000) >> (16 * n)) -} - -// modQToMod3 maps {0, 1, Q-1} to {(0, 0), (0, 1), (1, 0)} and also returns an int -// which is one if the input is in range and zero otherwise. -func modQToMod3(n uint16) (uint16, int) { - result := (n&3 - (n>>1)&1) - return result, subtle.ConstantTimeEq(int32(mod3ToModQ(result)), int32(n)) -} - -// mod3ResultToModQ maps {0, 1, 2, 4} to {0, 1, Q-1, 1} -func mod3ResultToModQ(n uint16) uint16 { - return ((((uint16(0x13) >> n) & 1) - 1) & 0x1fff) | ((uint16(0x12) >> n) & 1) - //shift := (uint(0x324) >> (2 * n)) & 3 - //return uint16(uint64(0x00011fff00010000) >> (16 * shift)) -} - -// mulXMinus1 sets out to a×(𝑥 - 1) mod (𝑥^n - 1) -func (out *poly) mulXMinus1() { - // Multiplying by (𝑥 - 1) means negating each coefficient and adding in - // the value of the previous one. - origOut700 := out[700] - - for i := N - 1; i > 0; i-- { - out[i] = (Q - out[i] + out[i-1]) % Q - } - out[0] = (Q - out[0] + origOut700) % Q -} - -func (out *poly) lift(a *poly) { - // We wish to calculate a/(𝑥-1) mod Φ(N) over GF(3), where Φ(N) is the - // Nth cyclotomic polynomial, i.e. 1 + 𝑥 + … + 𝑥^700 (since N is prime). - - // 1/(𝑥-1) has a fairly basic structure that we can exploit to speed this up: - // - // R. = PolynomialRing(GF(3)…) - // inv = R.cyclotomic_polynomial(1).inverse_mod(R.cyclotomic_polynomial(n)) - // list(inv)[:15] - // [1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2] - // - // This three-element pattern of coefficients repeats for the whole - // polynomial. - // - // Next define the overbar operator such that z̅ = z[0] + - // reverse(z[1:]). (Index zero of a polynomial here is the coefficient - // of the constant term. So index one is the coefficient of 𝑥 and so - // on.) - // - // A less odd way to define this is to see that z̅ negates the indexes, - // so z̅[0] = z[-0], z̅[1] = z[-1] and so on. - // - // The use of z̅ is that, when working mod (𝑥^701 - 1), vz[0] = , vz[1] = , …. (Where is the inner product: the sum - // of the point-wise products.) Although we calculated the inverse mod - // Φ(N), we can work mod (𝑥^N - 1) and reduce mod Φ(N) at the end. - // (That's because (𝑥^N - 1) is a multiple of Φ(N).) - // - // When working mod (𝑥^N - 1), multiplication by 𝑥 is a right-rotation - // of the list of coefficients. - // - // Thus we can consider what the pattern of z̅, 𝑥z̅, 𝑥^2z̅, … looks like: - // - // def reverse(xs): - // suffix = list(xs[1:]) - // suffix.reverse() - // return [xs[0]] + suffix - // - // def rotate(xs): - // return [xs[-1]] + xs[:-1] - // - // zoverbar = reverse(list(inv) + [0]) - // xzoverbar = rotate(reverse(list(inv) + [0])) - // x2zoverbar = rotate(rotate(reverse(list(inv) + [0]))) - // - // zoverbar[:15] - // [1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1] - // xzoverbar[:15] - // [0, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0] - // x2zoverbar[:15] - // [2, 0, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2] - // - // (For a formula for z̅, see lemma two of appendix B.) - // - // After the first three elements have been taken care of, all then have - // a repeating three-element cycle. The next value (𝑥^3z̅) involves - // three rotations of the first pattern, thus the three-element cycle - // lines up. However, the discontinuity in the first three elements - // obviously moves to a different position. Consider the difference - // between 𝑥^3z̅ and z̅: - // - // [x-y for (x,y) in zip(zoverbar, x3zoverbar)][:15] - // [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - // - // This pattern of differences is the same for all elements, although it - // obviously moves right with the rotations. - // - // From this, we reach algorithm eight of appendix B. - - // Handle the first three elements of the inner products. - out[0] = a[0] + a[2] - out[1] = a[1] - out[2] = 2*a[0] + a[2] - - // Use the repeating pattern to complete the first three inner products. - for i := 3; i < 699; i += 3 { - out[0] += 2*a[i] + a[i+2] - out[1] += a[i] + 2*a[i+1] - out[2] += a[i+1] + 2*a[i+2] - } - - // Handle the fact that the three-element pattern doesn't fill the - // polynomial exactly (since 701 isn't a multiple of three). - out[2] += a[700] - out[0] += 2 * a[699] - out[1] += a[699] + 2*a[700] - - out[0] = out[0] % 3 - out[1] = out[1] % 3 - out[2] = out[2] % 3 - - // Calculate the remaining inner products by taking advantage of the - // fact that the pattern repeats every three cycles and the pattern of - // differences is moves with the rotation. - for i := 3; i < N; i++ { - // Add twice something is the same as subtracting when working - // mod 3. Doing it this way avoids underflow. Underflow is bad - // because "% 3" doesn't work correctly for negative numbers - // here since underflow will wrap to 2^16-1 and 2^16 isn't a - // multiple of three. - out[i] = (out[i-3] + 2*(a[i-2]+a[i-1]+a[i])) % 3 - } - - // Reduce mod Φ(N) by subtracting a multiple of out[700] from every - // element and convert to mod Q. (See above about adding twice as - // subtraction.) - v := out[700] * 2 - for i := range out { - out[i] = mod3ToModQ((out[i] + v) % 3) - } - - out.mulXMinus1() -} - -func (a *poly) cswap(b *poly, swap uint16) { - for i := range a { - sum := swap & (a[i] ^ b[i]) - a[i] ^= sum - b[i] ^= sum - } -} - -func lt(a, b uint) uint { - if a < b { - return ^uint(0) - } - return 0 -} - -func bsMul(s1, a1, s2, a2 uint) (s3, a3 uint) { - s3 = (a1 & s2) ^ (s1 & a2) - a3 = (a1 & a2) ^ (s1 & s2) - return -} - -func (out *poly3) invertMod3(in *poly3) { - // This algorithm follows algorithm 10 in the paper. (Although note that - // the paper appears to have a bug: k should start at zero, not one.) - // The best explanation for why it works is in the "Why it works" - // section of - // https://assets.onboardsecurity.com/static/downloads/NTRU/resources/NTRUTech014.pdf. - var k uint - degF, degG := uint(N-1), uint(N-1) - - var b, c, g poly3 - f := *in - - for i := range g.a { - g.a[i] = ^uint(0) - } - - b.a[0] = 1 - - var f0s, f0a uint - stillGoing := ^uint(0) - for i := 0; i < 2*(N-1)-1; i++ { - ss, sa := bsMul(f.s[0], f.a[0], g.s[0], g.a[0]) - ss, sa = sa&stillGoing&1, ss&stillGoing&1 - shouldSwap := ^uint(int((ss|sa)-1)>>(bitsPerWord-1)) & lt(degF, degG) - f.cswap(&g, shouldSwap) - b.cswap(&c, shouldSwap) - degF, degG = (degG&shouldSwap)|(degF & ^shouldSwap), (degF&shouldSwap)|(degG&^shouldSwap) - f.fmadd(ss, sa, &g) - b.fmadd(ss, sa, &c) - - f.divx() - f.s[wordsPerPoly-1] &= ((1 << bitsInLastWord) - 1) >> 1 - f.a[wordsPerPoly-1] &= ((1 << bitsInLastWord) - 1) >> 1 - c.mulx() - c.s[0] &= ^uint(1) - c.a[0] &= ^uint(1) - - degF-- - k += 1 & stillGoing - f0s = (stillGoing & f.s[0]) | (^stillGoing & f0s) - f0a = (stillGoing & f.a[0]) | (^stillGoing & f0a) - stillGoing = ^uint(int(degF-1) >> (bitsPerWord - 1)) - } - - k -= N & lt(N, k) - *out = b - out.rot(k) - out.mulConst(f0s, f0a) - out.modPhiN() -} - -func (out *poly) invertMod2(a *poly) { - // This algorithm follows mix of algorithm 10 in the paper and the first - // page of the PDF linked below. (Although note that the paper appears - // to have a bug: k should start at zero, not one.) The best explanation - // for why it works is in the "Why it works" section of - // https://assets.onboardsecurity.com/static/downloads/NTRU/resources/NTRUTech014.pdf. - var k uint - degF, degG := uint(N-1), uint(N-1) - - var f poly2 - f.fromDiscrete(a) - var b, c, g poly2 - g.setPhiN() - b[0] = 1 - - stillGoing := ^uint(0) - for i := 0; i < 2*(N-1)-1; i++ { - s := uint(f[0]&1) & stillGoing - shouldSwap := ^(s - 1) & lt(degF, degG) - f.cswap(&g, shouldSwap) - b.cswap(&c, shouldSwap) - degF, degG = (degG&shouldSwap)|(degF & ^shouldSwap), (degF&shouldSwap)|(degG&^shouldSwap) - f.fmadd(s, &g) - b.fmadd(s, &c) - - f.rshift1() - c.lshift1() - - degF-- - k += 1 & stillGoing - stillGoing = ^uint(int(degF-1) >> (bitsPerWord - 1)) - } - - k -= N & lt(N, k) - b.rot(k) - out.fromMod2(&b) -} - -func (out *poly) invert(origA *poly) { - // Inversion mod Q, which is done based on the result of inverting mod - // 2. See the NTRU paper, page three. - var a, tmp, tmp2, b poly - b.invertMod2(origA) - - // Negate a. - for i := range a { - a[i] = Q - origA[i] - } - - // We are working mod Q=2**13 and we need to iterate ceil(log_2(13)) - // times, which is four. - for i := 0; i < 4; i++ { - tmp.mul(&a, &b) - tmp[0] += 2 - tmp2.mul(&b, &tmp) - b = tmp2 - } - - *out = b -} - -type PublicKey struct { - h poly -} - -func ParsePublicKey(in []byte) (*PublicKey, bool) { - ret := new(PublicKey) - if !ret.h.unmarshal(in) { - return nil, false - } - return ret, true -} - -func (pub *PublicKey) Marshal() []byte { - ret := make([]byte, modQBytes) - pub.h.marshal(ret) - return ret -} - -func (pub *PublicKey) Encap(rand io.Reader) (ciphertext []byte, sharedKey []byte) { - var randBytes [352 + 352]byte - if _, err := io.ReadFull(rand, randBytes[:]); err != nil { - panic("rand failed") - } - - var m, r poly - m.shortSample(randBytes[:352]) - r.shortSample(randBytes[352:]) - - var mBytes, rBytes [mod3Bytes]byte - m.marshalS3(mBytes[:]) - r.marshalS3(rBytes[:]) - - ciphertext = pub.owf(&m, &r) - - h := sha256.New() - h.Write([]byte("shared key\x00")) - h.Write(mBytes[:]) - h.Write(rBytes[:]) - h.Write(ciphertext) - sharedKey = h.Sum(nil) - - return ciphertext, sharedKey -} - -func (pub *PublicKey) owf(m, r *poly) []byte { - for i := range r { - r[i] = mod3ToModQ(r[i]) - } - - var mq poly - mq.lift(m) - - var e poly - e.mul(r, &pub.h) - for i := range e { - e[i] = (e[i] + mq[i]) % Q - } - - ret := make([]byte, modQBytes) - e.marshal(ret[:]) - return ret -} - -type PrivateKey struct { - PublicKey - f, fp poly3 - hInv poly - hmacKey [32]byte -} - -func (priv *PrivateKey) Marshal() []byte { - var ret [2*mod3Bytes + modQBytes]byte - priv.f.marshal(ret[:]) - priv.fp.marshal(ret[mod3Bytes:]) - priv.h.marshal(ret[2*mod3Bytes:]) - return ret[:] -} - -func (priv *PrivateKey) Decap(ciphertext []byte) (sharedKey []byte, ok bool) { - if len(ciphertext) != modQBytes { - return nil, false - } - - var e poly - if !e.unmarshal(ciphertext) { - return nil, false - } - - var f poly - f.fromMod3ToModQ(&priv.f) - - var v1, m poly - v1.mul(&e, &f) - - var v13 poly3 - v13.fromDiscreteMod3(&v1) - // Note: v13 is not reduced mod phi(n). - - var m3 poly3 - m3.mulMod3(&v13, &priv.fp) - m3.modPhiN() - m.fromMod3(&m3) - - var mLift, delta poly - mLift.lift(&m) - for i := range delta { - delta[i] = (e[i] - mLift[i] + Q) % Q - } - delta.mul(&delta, &priv.hInv) - delta.modPhiN() - - var r poly3 - allOk := r.fromModQ(&delta) - - var mBytes, rBytes [mod3Bytes]byte - m.marshalS3(mBytes[:]) - r.marshal(rBytes[:]) - - var rPoly poly - rPoly.fromMod3(&r) - expectedCiphertext := priv.PublicKey.owf(&m, &rPoly) - - allOk &= subtle.ConstantTimeCompare(ciphertext, expectedCiphertext) - - hmacHash := hmac.New(sha256.New, priv.hmacKey[:]) - hmacHash.Write(ciphertext) - hmacDigest := hmacHash.Sum(nil) - - h := sha256.New() - h.Write([]byte("shared key\x00")) - h.Write(mBytes[:]) - h.Write(rBytes[:]) - h.Write(ciphertext) - sharedKey = h.Sum(nil) - - mask := uint8(allOk - 1) - for i := range sharedKey { - sharedKey[i] = (sharedKey[i] & ^mask) | (hmacDigest[i] & mask) - } - - return sharedKey, true -} - -func GenerateKey(rand io.Reader) PrivateKey { - var randBytes [352 + 352]byte - if _, err := io.ReadFull(rand, randBytes[:]); err != nil { - panic("rand failed") - } - - var f poly - f.shortSamplePlus(randBytes[:352]) - var priv PrivateKey - priv.f.fromDiscrete(&f) - priv.fp.invertMod3(&priv.f) - - var g poly - g.shortSamplePlus(randBytes[352:]) - - var pgPhi1 poly - for i := range g { - pgPhi1[i] = mod3ToModQ(g[i]) - } - for i := range pgPhi1 { - pgPhi1[i] = (pgPhi1[i] * 3) % Q - } - pgPhi1.mulXMinus1() - - var fModQ poly - fModQ.fromMod3ToModQ(&priv.f) - - var pfgPhi1 poly - pfgPhi1.mul(&fModQ, &pgPhi1) - - var i poly - i.invert(&pfgPhi1) - - priv.h.mul(&i, &pgPhi1) - priv.h.mul(&priv.h, &pgPhi1) - - priv.hInv.mul(&i, &fModQ) - priv.hInv.mul(&priv.hInv, &fModQ) - - return priv -} diff --git a/third_party/boringssl/kit/src/ssl/test/runner/key_agreement.go b/third_party/boringssl/kit/src/ssl/test/runner/key_agreement.go index bfd35f69..95ef5317 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/key_agreement.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/key_agreement.go @@ -17,7 +17,7 @@ import ( "io" "math/big" - "boringssl.googlesource.com/boringssl/ssl/test/runner/hrss" + "boringssl.googlesource.com/boringssl/ssl/test/runner/kyber" "golang.org/x/crypto/curve25519" ) @@ -231,28 +231,29 @@ func (ka *rsaKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm { return 0 } -// A ecdhCurve is an instance of ECDH-style key agreement for TLS. -type ecdhCurve interface { - // offer generates a keypair using rand. It returns the encoded |publicKey|. - offer(rand io.Reader) (publicKey []byte, err error) +// A kemImplementation is an instance of KEM-style construction for TLS. +type kemImplementation interface { + // generate generates a keypair using rand. It returns the encoded public key. + generate(rand io.Reader) (publicKey []byte, err error) - // accept responds to the |peerKey| generated by |offer| with the acceptor's - // |publicKey|, and returns agreed-upon |preMasterSecret| to the acceptor. - accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) + // encap generates a symmetric, shared secret, encapsulates it with |peerKey|. + // It returns the encapsulated shared secret and the secret itself. + encap(rand io.Reader, peerKey []byte) (ciphertext []byte, secret []byte, err error) - // finish returns the computed |preMasterSecret|, given the |peerKey| - // generated by |accept|. - finish(peerKey []byte) (preMasterSecret []byte, err error) + // decap decapsulates |ciphertext| and returns the resulting shared secret. + decap(ciphertext []byte) (secret []byte, err error) } -// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve. -type ellipticECDHCurve struct { +// ecdhKEM implements kemImplementation with an elliptic.Curve. +// +// TODO(davidben): Move this to Go's crypto/ecdh. +type ecdhKEM struct { curve elliptic.Curve privateKey []byte sendCompressed bool } -func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) { +func (e *ecdhKEM) generate(rand io.Reader) (publicKey []byte, err error) { var x, y *big.Int e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand) if err != nil { @@ -269,38 +270,37 @@ func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) return ret, nil } -func (e *ellipticECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) { - publicKey, err = e.offer(rand) +func (e *ecdhKEM) encap(rand io.Reader, peerKey []byte) (ciphertext []byte, secret []byte, err error) { + ciphertext, err = e.generate(rand) if err != nil { return nil, nil, err } - preMasterSecret, err = e.finish(peerKey) + secret, err = e.decap(peerKey) if err != nil { return nil, nil, err } return } -func (e *ellipticECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) { - x, y := elliptic.Unmarshal(e.curve, peerKey) +func (e *ecdhKEM) decap(ciphertext []byte) (secret []byte, err error) { + x, y := elliptic.Unmarshal(e.curve, ciphertext) if x == nil { return nil, errors.New("tls: invalid peer key") } x, _ = e.curve.ScalarMult(x, y, e.privateKey) - preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3) + secret = make([]byte, (e.curve.Params().BitSize+7)>>3) xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - return preMasterSecret, nil + copy(secret[len(secret)-len(xBytes):], xBytes) + return secret, nil } -// x25519ECDHCurve implements ecdhCurve with X25519. -type x25519ECDHCurve struct { +// x25519KEM implements kemImplementation with X25519. +type x25519KEM struct { privateKey [32]byte setHighBit bool } -func (e *x25519ECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) { +func (e *x25519KEM) generate(rand io.Reader) (publicKey []byte, err error) { _, err = io.ReadFull(rand, e.privateKey[:]) if err != nil { return @@ -313,25 +313,24 @@ func (e *x25519ECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) { return out[:], nil } -func (e *x25519ECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) { - publicKey, err = e.offer(rand) +func (e *x25519KEM) encap(rand io.Reader, peerKey []byte) (ciphertext []byte, secret []byte, err error) { + ciphertext, err = e.generate(rand) if err != nil { return nil, nil, err } - preMasterSecret, err = e.finish(peerKey) + secret, err = e.decap(peerKey) if err != nil { return nil, nil, err } return } -func (e *x25519ECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) { - if len(peerKey) != 32 { +func (e *x25519KEM) decap(ciphertext []byte) (secret []byte, err error) { + if len(ciphertext) != 32 { return nil, errors.New("tls: invalid peer key") } - var out, peerKeyCopy [32]byte - copy(peerKeyCopy[:], peerKey) - curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy) + var out [32]byte + curve25519.ScalarMult(&out, &e.privateKey, (*[32]byte)(ciphertext)) // Per RFC 7748, reject the all-zero value in constant time. var zeros [32]byte @@ -342,32 +341,35 @@ func (e *x25519ECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err er return out[:], nil } -// cecpq2Curve implements CECPQ2, which is HRSS+SXY combined with X25519. -type cecpq2Curve struct { +// kyberKEM implements Kyber combined with X25519. +type kyberKEM struct { x25519PrivateKey [32]byte - hrssPrivateKey hrss.PrivateKey + kyberPrivateKey *kyber.PrivateKey } -func (e *cecpq2Curve) offer(rand io.Reader) (publicKey []byte, err error) { +func (e *kyberKEM) generate(rand io.Reader) (publicKey []byte, err error) { if _, err := io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil { return nil, err } - var x25519Public [32]byte curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey) - e.hrssPrivateKey = hrss.GenerateKey(rand) - hrssPublic := e.hrssPrivateKey.PublicKey.Marshal() + var kyberEntropy [64]byte + if _, err := io.ReadFull(rand, kyberEntropy[:]); err != nil { + return nil, err + } + var kyberPublic *[kyber.PublicKeySize]byte + e.kyberPrivateKey, kyberPublic = kyber.NewPrivateKey(&kyberEntropy) var ret []byte ret = append(ret, x25519Public[:]...) - ret = append(ret, hrssPublic...) + ret = append(ret, kyberPublic[:]...) return ret, nil } -func (e *cecpq2Curve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) { - if len(peerKey) != 32+hrss.PublicKeySize { - return nil, nil, errors.New("tls: bad length CECPQ2 offer") +func (e *kyberKEM) encap(rand io.Reader, peerKey []byte) (ciphertext []byte, secret []byte, err error) { + if len(peerKey) != 32+kyber.PublicKeySize { + return nil, nil, errors.New("tls: bad length Kyber offer") } if _, err := io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil { @@ -385,28 +387,32 @@ func (e *cecpq2Curve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, return nil, nil, errors.New("tls: X25519 value with wrong order") } - hrssPublicKey, ok := hrss.ParsePublicKey(peerKey[32:]) + kyberPublicKey, ok := kyber.UnmarshalPublicKey((*[kyber.PublicKeySize]byte)(peerKey[32:])) if !ok { - return nil, nil, errors.New("tls: bad CECPQ2 offer") + return nil, nil, errors.New("tls: bad Kyber offer") } - hrssCiphertext, hrssShared := hrssPublicKey.Encap(rand) + var kyberShared, kyberEntropy [32]byte + if _, err := io.ReadFull(rand, kyberEntropy[:]); err != nil { + return nil, nil, err + } + kyberCiphertext := kyberPublicKey.Encap(kyberShared[:], &kyberEntropy) - publicKey = append(publicKey, x25519Public[:]...) - publicKey = append(publicKey, hrssCiphertext...) - preMasterSecret = append(preMasterSecret, x25519Shared[:]...) - preMasterSecret = append(preMasterSecret, hrssShared...) + ciphertext = append(ciphertext, x25519Public[:]...) + ciphertext = append(ciphertext, kyberCiphertext[:]...) + secret = append(secret, x25519Shared[:]...) + secret = append(secret, kyberShared[:]...) - return publicKey, preMasterSecret, nil + return ciphertext, secret, nil } -func (e *cecpq2Curve) finish(peerKey []byte) (preMasterSecret []byte, err error) { - if len(peerKey) != 32+hrss.CiphertextSize { - return nil, errors.New("tls: bad length CECPQ2 reply") +func (e *kyberKEM) decap(ciphertext []byte) (secret []byte, err error) { + if len(ciphertext) != 32+kyber.CiphertextSize { + return nil, errors.New("tls: bad length Kyber reply") } var x25519Shared, x25519PeerKey [32]byte - copy(x25519PeerKey[:], peerKey) + copy(x25519PeerKey[:], ciphertext) curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey) // Per RFC 7748, reject the all-zero value in constant time. @@ -415,31 +421,29 @@ func (e *cecpq2Curve) finish(peerKey []byte) (preMasterSecret []byte, err error) return nil, errors.New("tls: X25519 value with wrong order") } - hrssShared, ok := e.hrssPrivateKey.Decap(peerKey[32:]) - if !ok { - return nil, errors.New("tls: invalid HRSS ciphertext") - } + var kyberShared [32]byte + e.kyberPrivateKey.Decap(kyberShared[:], (*[kyber.CiphertextSize]byte)(ciphertext[32:])) - preMasterSecret = append(preMasterSecret, x25519Shared[:]...) - preMasterSecret = append(preMasterSecret, hrssShared...) + secret = append(secret, x25519Shared[:]...) + secret = append(secret, kyberShared[:]...) - return preMasterSecret, nil + return secret, nil } -func curveForCurveID(id CurveID, config *Config) (ecdhCurve, bool) { +func kemForCurveID(id CurveID, config *Config) (kemImplementation, bool) { switch id { case CurveP224: - return &ellipticECDHCurve{curve: elliptic.P224(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true + return &ecdhKEM{curve: elliptic.P224(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true case CurveP256: - return &ellipticECDHCurve{curve: elliptic.P256(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true + return &ecdhKEM{curve: elliptic.P256(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true case CurveP384: - return &ellipticECDHCurve{curve: elliptic.P384(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true + return &ecdhKEM{curve: elliptic.P384(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true case CurveP521: - return &ellipticECDHCurve{curve: elliptic.P521(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true + return &ecdhKEM{curve: elliptic.P521(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true case CurveX25519: - return &x25519ECDHCurve{setHighBit: config.Bugs.SetX25519HighBit}, true - case CurveCECPQ2: - return &cecpq2Curve{}, true + return &x25519KEM{setHighBit: config.Bugs.SetX25519HighBit}, true + case CurveX25519Kyber768: + return &kyberKEM{}, true default: return nil, false } @@ -576,7 +580,7 @@ func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clie // either be ECDSA or RSA. type ecdheKeyAgreement struct { auth keyAgreementAuthentication - curve ecdhCurve + kem kemImplementation curveID CurveID peerKey []byte } @@ -588,7 +592,7 @@ func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Cer NextCandidate: for _, candidate := range preferredCurves { if isPqGroup(candidate) && version < VersionTLS13 { - // CECPQ2 is TLS 1.3-only. + // Post-quantum "groups" require TLS 1.3. continue } @@ -605,12 +609,12 @@ NextCandidate: } var ok bool - if ka.curve, ok = curveForCurveID(curveid, config); !ok { + if ka.kem, ok = kemForCurveID(curveid, config); !ok { return nil, errors.New("tls: preferredCurves includes unsupported curve") } ka.curveID = curveid - publicKey, err := ka.curve.offer(config.rand()) + publicKey, err := ka.kem.generate(config.rand()) if err != nil { return nil, err } @@ -636,7 +640,7 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { return nil, errClientKeyExchange } - return ka.curve.finish(ckx.ciphertext[1:]) + return ka.kem.decap(ckx.ciphertext[1:]) } func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, skx *serverKeyExchangeMsg) error { @@ -646,11 +650,11 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell if skx.key[0] != 3 { // named curve return errors.New("tls: server selected unsupported curve") } - curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) - ka.curveID = curveid + curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) + ka.curveID = curveID var ok bool - if ka.curve, ok = curveForCurveID(curveid, config); !ok { + if ka.kem, ok = kemForCurveID(curveID, config); !ok { return errors.New("tls: server selected unsupported curve") } @@ -668,24 +672,24 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell } func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - if ka.curve == nil { + if ka.kem == nil { return nil, nil, errors.New("missing ServerKeyExchange message") } - publicKey, preMasterSecret, err := ka.curve.accept(config.rand(), ka.peerKey) + ciphertext, secret, err := ka.kem.encap(config.rand(), ka.peerKey) if err != nil { return nil, nil, err } ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, 1+len(publicKey)) - ckx.ciphertext[0] = byte(len(publicKey)) - copy(ckx.ciphertext[1:], publicKey) + ckx.ciphertext = make([]byte, 1+len(ciphertext)) + ckx.ciphertext[0] = byte(len(ciphertext)) + copy(ckx.ciphertext[1:], ciphertext) if config.Bugs.InvalidECDHPoint { ckx.ciphertext[1] ^= 0xff } - return preMasterSecret, ckx, nil + return secret, ckx, nil } func (ka *ecdheKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm { diff --git a/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber.go b/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber.go new file mode 100644 index 00000000..dd113f0b --- /dev/null +++ b/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber.go @@ -0,0 +1,625 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +package kyber + +// This code is ported from kyber.c. + +import ( + "crypto/subtle" + "golang.org/x/crypto/sha3" + "io" +) + +const( + CiphertextSize = 1088 + PublicKeySize = 1184 + PrivateKeySize = 2400 +) + +const ( + degree = 256 + rank = 3 + prime = 3329 + log2Prime = 12 + halfPrime = (prime - 1) / 2 + du = 10 + dv = 4 + inverseDegree = 3303 + encodedVectorSize = log2Prime * degree / 8 * rank + compressedVectorSize = du * rank * degree / 8 + barrettMultiplier = 5039 + barrettShift = 24 +) + +func reduceOnce(x uint16) uint16 { + if x >= 2*prime { + panic("reduce_once: value out of range") + } + subtracted := x - prime + mask := 0 - (subtracted >> 15) + return (mask & x) | (^mask & subtracted) +} + +func reduce(x uint32) uint16 { + if x >= prime+2*prime*prime { + panic("reduce: value out of range") + } + product := uint64(x) * barrettMultiplier + quotient := uint32(product >> barrettShift) + remainder := uint32(x) - quotient*prime + return reduceOnce(uint16(remainder)) +} + +// lt returns 0xff..f if a < b and 0 otherwise +func lt(a, b uint32) uint32 { + return uint32(0 - int32(a^((a^b)|((a-b)^a)))>>31) +} + +// Compresses (lossily) an input |x| mod 3329 into |bits| many bits by grouping +// numbers close to each other together. The formula used is +// round(2^|bits|/prime*x) mod 2^|bits|. +// Uses Barrett reduction to achieve constant time. Since we need both the +// remainder (for rounding) and the quotient (as the result), we cannot use +// |reduce| here, but need to do the Barrett reduction directly. +func compress(x uint16, bits int) uint16 { + product := uint32(x) << bits + quotient := uint32((uint64(product) * barrettMultiplier) >> barrettShift) + remainder := product - quotient*prime + + // Adjust the quotient to round correctly: + // 0 <= remainder <= halfPrime round to 0 + // halfPrime < remainder <= prime + halfPrime round to 1 + // prime + halfPrime < remainder < 2 * prime round to 2 + quotient += 1 & lt(halfPrime, remainder) + quotient += 1 & lt(prime+halfPrime, remainder) + return uint16(quotient) & ((1 << bits) - 1) +} + +func decompress(x uint16, bits int) uint16 { + product := uint32(x) * prime + power := uint32(1) << bits + // This is |product| % power, since |power| is a power of 2. + remainder := product & (power - 1) + // This is |product| / power, since |power| is a power of 2. + lower := product >> bits + // The rounding logic works since the first half of numbers mod |power| have a + // 0 as first bit, and the second half has a 1 as first bit, since |power| is + // a power of 2. As a 12 bit number, |remainder| is always positive, so we + // will shift in 0s for a right shift. + return uint16(lower + (remainder >> (bits - 1))) +} + +type scalar [degree]uint16 + +func (s *scalar) zero() { + for i := range s { + s[i] = 0 + } +} + +// This bit of Python will be referenced in some of the following comments: +// +// p = 3329 +// +// def bitreverse(i): +// ret = 0 +// for n in range(7): +// bit = i & 1 +// ret <<= 1 +// ret |= bit +// i >>= 1 +// return ret + +// kNTTRoots = [pow(17, bitreverse(i), p) for i in range(128)] +var nttRoots = [128]uint16{ + 1, 1729, 2580, 3289, 2642, 630, 1897, 848, 1062, 1919, 193, 797, + 2786, 3260, 569, 1746, 296, 2447, 1339, 1476, 3046, 56, 2240, 1333, + 1426, 2094, 535, 2882, 2393, 2879, 1974, 821, 289, 331, 3253, 1756, + 1197, 2304, 2277, 2055, 650, 1977, 2513, 632, 2865, 33, 1320, 1915, + 2319, 1435, 807, 452, 1438, 2868, 1534, 2402, 2647, 2617, 1481, 648, + 2474, 3110, 1227, 910, 17, 2761, 583, 2649, 1637, 723, 2288, 1100, + 1409, 2662, 3281, 233, 756, 2156, 3015, 3050, 1703, 1651, 2789, 1789, + 1847, 952, 1461, 2687, 939, 2308, 2437, 2388, 733, 2337, 268, 641, + 1584, 2298, 2037, 3220, 375, 2549, 2090, 1645, 1063, 319, 2773, 757, + 2099, 561, 2466, 2594, 2804, 1092, 403, 1026, 1143, 2150, 2775, 886, + 1722, 1212, 1874, 1029, 2110, 2935, 885, 2154, +} + +func (s *scalar) ntt() { + offset := degree + for step := 1; step < degree/2; step <<= 1 { + offset >>= 1 + k := 0 + for i := 0; i < step; i++ { + stepRoot := uint32(nttRoots[i+step]) + for j := k; j < k+offset; j++ { + odd := reduce(stepRoot * uint32(s[j+offset])) + even := s[j] + s[j] = reduceOnce(odd + even) + s[j+offset] = reduceOnce(even - odd + prime) + } + k += 2 * offset + } + } +} + +// kInverseNTTRoots = [pow(17, -bitreverse(i), p) for i in range(128)] +var inverseNTTRoots = [128]uint16{ + 1, 1600, 40, 749, 2481, 1432, 2699, 687, 1583, 2760, 69, 543, + 2532, 3136, 1410, 2267, 2508, 1355, 450, 936, 447, 2794, 1235, 1903, + 1996, 1089, 3273, 283, 1853, 1990, 882, 3033, 2419, 2102, 219, 855, + 2681, 1848, 712, 682, 927, 1795, 461, 1891, 2877, 2522, 1894, 1010, + 1414, 2009, 3296, 464, 2697, 816, 1352, 2679, 1274, 1052, 1025, 2132, + 1573, 76, 2998, 3040, 1175, 2444, 394, 1219, 2300, 1455, 2117, 1607, + 2443, 554, 1179, 2186, 2303, 2926, 2237, 525, 735, 863, 2768, 1230, + 2572, 556, 3010, 2266, 1684, 1239, 780, 2954, 109, 1292, 1031, 1745, + 2688, 3061, 992, 2596, 941, 892, 1021, 2390, 642, 1868, 2377, 1482, + 1540, 540, 1678, 1626, 279, 314, 1173, 2573, 3096, 48, 667, 1920, + 2229, 1041, 2606, 1692, 680, 2746, 568, 3312, +} + +func (s *scalar) inverseNTT() { + step := degree / 2 + for offset := 2; offset < degree; offset <<= 1 { + step >>= 1 + k := 0 + for i := 0; i < step; i++ { + stepRoot := uint32(inverseNTTRoots[i+step]) + for j := k; j < k+offset; j++ { + odd := s[j+offset] + even := s[j] + s[j] = reduceOnce(odd + even) + s[j+offset] = reduce(stepRoot * uint32(even-odd+prime)) + } + k += 2 * offset + } + } + for i := range s { + s[i] = reduce(uint32(s[i]) * inverseDegree) + } +} + +func (s *scalar) add(b *scalar) { + for i := range s { + s[i] = reduceOnce(s[i] + b[i]) + } +} + +func (s *scalar) sub(b *scalar) { + for i := range s { + s[i] = reduceOnce(s[i] - b[i] + prime) + } +} + +// kModRoots = [pow(17, 2*bitreverse(i) + 1, p) for i in range(128)] +var modRoots = [128]uint16{ + 17, 3312, 2761, 568, 583, 2746, 2649, 680, 1637, 1692, 723, 2606, + 2288, 1041, 1100, 2229, 1409, 1920, 2662, 667, 3281, 48, 233, 3096, + 756, 2573, 2156, 1173, 3015, 314, 3050, 279, 1703, 1626, 1651, 1678, + 2789, 540, 1789, 1540, 1847, 1482, 952, 2377, 1461, 1868, 2687, 642, + 939, 2390, 2308, 1021, 2437, 892, 2388, 941, 733, 2596, 2337, 992, + 268, 3061, 641, 2688, 1584, 1745, 2298, 1031, 2037, 1292, 3220, 109, + 375, 2954, 2549, 780, 2090, 1239, 1645, 1684, 1063, 2266, 319, 3010, + 2773, 556, 757, 2572, 2099, 1230, 561, 2768, 2466, 863, 2594, 735, + 2804, 525, 1092, 2237, 403, 2926, 1026, 2303, 1143, 2186, 2150, 1179, + 2775, 554, 886, 2443, 1722, 1607, 1212, 2117, 1874, 1455, 1029, 2300, + 2110, 1219, 2935, 394, 885, 2444, 2154, 1175, +} + +func (s *scalar) mult(a, b *scalar) { + for i := 0; i < degree/2; i++ { + realReal := uint32(a[2*i]) * uint32(b[2*i]) + imgImg := uint32(a[2*i+1]) * uint32(b[2*i+1]) + realImg := uint32(a[2*i]) * uint32(b[2*i+1]) + imgReal := uint32(a[2*i+1]) * uint32(b[2*i]) + s[2*i] = reduce(realReal + uint32(reduce(imgImg))*uint32(modRoots[i])) + s[2*i+1] = reduce(imgReal + realImg) + } +} + +func (s *scalar) innerProduct(left, right *vector) { + s.zero() + var product scalar + for i := range left { + product.mult(&left[i], &right[i]) + s.add(&product) + } +} + +func (s *scalar) fromKeccakVartime(keccak io.Reader) { + var buf [3]byte + for i := 0; i < len(s); { + keccak.Read(buf[:]) + d1 := uint16(buf[0]) + 256*uint16(buf[1]%16) + d2 := uint16(buf[1])/16 + 16*uint16(buf[2]) + if d1 < prime { + s[i] = d1 + i++ + } + if d2 < prime && i < len(s) { + s[i] = d2 + i++ + } + } +} + +func (s *scalar) centeredBinomialEta2(input *[33]byte) { + var entropy [128]byte + sha3.ShakeSum256(entropy[:], input[:]) + + for i := 0; i < len(s); i += 2 { + b := uint16(entropy[i/2]) + + value := uint16(prime) + value += (b & 1) + ((b >> 1) & 1) + value -= ((b >> 2) & 1) + ((b >> 3) & 1) + s[i] = reduceOnce(value) + + b >>= 4 + value = prime + value += (b & 1) + ((b >> 1) & 1) + value -= ((b >> 2) & 1) + ((b >> 3) & 1) + s[i+1] = reduceOnce(value) + } +} + +var masks = [8]uint16{0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff} + +func (s *scalar) encode(out []byte, bits int) []byte { + var outByte byte + outByteBits := 0 + + for i := range s { + element := s[i] + elementBitsDone := 0 + + for elementBitsDone < bits { + chunkBits := bits - elementBitsDone + outBitsRemaining := 8 - outByteBits + if chunkBits >= outBitsRemaining { + chunkBits = outBitsRemaining + outByte |= byte(element&masks[chunkBits-1]) << outByteBits + out[0] = outByte + out = out[1:] + outByteBits = 0 + outByte = 0 + } else { + outByte |= byte(element&masks[chunkBits-1]) << outByteBits + outByteBits += chunkBits + } + + elementBitsDone += chunkBits + element >>= chunkBits + } + } + + if outByteBits > 0 { + out[0] = outByte + out = out[1:] + } + + return out +} + +func (s *scalar) decode(in []byte, bits int) ([]byte, bool) { + var inByte byte + inByteBitsLeft := 0 + + for i := range s { + var element uint16 + elementBitsDone := 0 + + for elementBitsDone < bits { + if inByteBitsLeft == 0 { + inByte = in[0] + in = in[1:] + inByteBitsLeft = 8 + } + + chunkBits := bits - elementBitsDone + if chunkBits > inByteBitsLeft { + chunkBits = inByteBitsLeft + } + + element |= (uint16(inByte) & masks[chunkBits-1]) << elementBitsDone + inByteBitsLeft -= chunkBits + inByte >>= chunkBits + + elementBitsDone += chunkBits + } + + if element >= prime { + return nil, false + } + s[i] = element + } + + return in, true +} + +func (s *scalar) compress(bits int) { + for i := range s { + s[i] = compress(s[i], bits) + } +} + +func (s *scalar) decompress(bits int) { + for i := range s { + s[i] = decompress(s[i], bits) + } +} + +type vector [rank]scalar + +func (v *vector) zero() { + for i := range v { + v[i].zero() + } +} + +func (v *vector) ntt() { + for i := range v { + v[i].ntt() + } +} + +func (v *vector) inverseNTT() { + for i := range v { + v[i].inverseNTT() + } +} + +func (v *vector) add(b *vector) { + for i := range v { + v[i].add(&b[i]) + } +} + +func (out *vector) mult(m *matrix, v *vector) { + out.zero() + var product scalar + for i := 0; i < rank; i++ { + for j := 0; j < rank; j++ { + product.mult(&m[i][j], &v[j]) + out[i].add(&product) + } + } +} + +func (out *vector) multTranspose(m *matrix, v *vector) { + out.zero() + var product scalar + for i := 0; i < rank; i++ { + for j := 0; j < rank; j++ { + product.mult(&m[j][i], &v[j]) + out[i].add(&product) + } + } +} + +func (v *vector) generateSecretEta2(counter *byte, seed *[32]byte) { + var input [33]byte + copy(input[:], seed[:]) + for i := range v { + input[32] = *counter + *counter++ + v[i].centeredBinomialEta2(&input) + } +} + +func (v *vector) encode(out []byte, bits int) []byte { + for i := range v { + out = v[i].encode(out, bits) + } + return out +} + +func (v *vector) decode(out []byte, bits int) ([]byte, bool) { + var ok bool + for i := range v { + out, ok = v[i].decode(out, bits) + if !ok { + return nil, false + } + } + + return out, true +} + +func (v *vector) compress(bits int) { + for i := range v { + v[i].compress(bits) + } +} + +func (v *vector) decompress(bits int) { + for i := range v { + v[i].decompress(bits) + } +} + +type matrix [rank][rank]scalar + +func (m *matrix) expand(rho *[32]byte) { + shake := sha3.NewShake128() + + var input [34]byte + copy(input[:], rho[:]) + + for i := 0; i < rank; i++ { + for j := 0; j < rank; j++ { + input[32] = byte(i) + input[33] = byte(j) + + shake.Reset() + shake.Write(input[:]) + m[i][j].fromKeccakVartime(shake) + } + } +} + +type PublicKey struct { + t vector + rho [32]byte + publicKeyHash [32]byte + m matrix +} + +func UnmarshalPublicKey(data *[PublicKeySize]byte) (*PublicKey, bool) { + var ret PublicKey + ret.publicKeyHash = sha3.Sum256(data[:]) + in, ok := ret.t.decode(data[:], log2Prime) + if !ok { + return nil, false + } + copy(ret.rho[:], in) + ret.m.expand(&ret.rho) + return &ret, true +} + +func (pub *PublicKey) Marshal() *[PublicKeySize]byte { + var ret [PublicKeySize]byte + out := pub.t.encode(ret[:], log2Prime) + copy(out, pub.rho[:]) + return &ret +} + +func (pub *PublicKey) encryptCPA(message, entropy *[32]byte) *[CiphertextSize]byte { + var counter uint8 + var secret, error vector + secret.generateSecretEta2(&counter, entropy) + error.generateSecretEta2(&counter, entropy) + secret.ntt() + + var input [33]byte + copy(input[:], entropy[:]) + input[32] = counter + var scalarError scalar + scalarError.centeredBinomialEta2(&input) + + var u vector + u.mult(&pub.m, &secret) + u.inverseNTT() + u.add(&error) + + var v scalar + v.innerProduct(&pub.t, &secret) + v.inverseNTT() + v.add(&scalarError) + + out := make([]byte, CiphertextSize) + var expandedMessage scalar + expandedMessage.decode(message[:], 1) + expandedMessage.decompress(1) + v.add(&expandedMessage) + u.compress(du) + it := u.encode(out, du) + v.compress(dv) + v.encode(it, dv) + return (*[CiphertextSize]byte)(out) +} + +func (pub *PublicKey) Encap(outSharedSecret []byte, entropy *[32]byte) *[CiphertextSize]byte { + var input [64]byte + copy(input[:], entropy[:]) + copy(input[32:], pub.publicKeyHash[:]) + prekeyAndRandomness := sha3.Sum512(input[:]) + ciphertext := pub.encryptCPA(entropy, (*[32]byte)(prekeyAndRandomness[32:])) + ciphertextHash := sha3.Sum256(ciphertext[:]) + copy(prekeyAndRandomness[32:], ciphertextHash[:]) + sha3.ShakeSum256(outSharedSecret, prekeyAndRandomness[:]) + return ciphertext +} + +type PrivateKey struct { + PublicKey + s vector + foFailureSecret [32]byte +} + +func NewPrivateKey(entropy *[64]byte) (*PrivateKey, *[PublicKeySize]byte) { + hashed := sha3.Sum512(entropy[:32]) + rho := (*[32]byte)(hashed[:32]) + sigma := (*[32]byte)(hashed[32:]) + ret := new(PrivateKey) + copy(ret.foFailureSecret[:], entropy[32:]) + copy(ret.rho[:], rho[:]) + ret.m.expand(rho) + counter := uint8(0) + ret.s.generateSecretEta2(&counter, sigma) + ret.s.ntt() + var error vector + error.generateSecretEta2(&counter, sigma) + error.ntt() + ret.t.multTranspose(&ret.m, &ret.s) + ret.t.add(&error) + + marshalledPublicKey := ret.PublicKey.Marshal() + ret.publicKeyHash = sha3.Sum256(marshalledPublicKey[:]) + + return ret, marshalledPublicKey +} + +func (priv *PrivateKey) decryptCPA(ciphertext *[CiphertextSize]byte) [32]byte { + var u vector + u.decode(ciphertext[:], du) + u.decompress(du) + u.ntt() + + var v scalar + v.decode(ciphertext[compressedVectorSize:], dv) + v.decompress(dv) + + var mask scalar + mask.innerProduct(&priv.s, &u) + mask.inverseNTT() + v.sub(&mask) + v.compress(1) + var out [32]byte + v.encode(out[:], 1) + return out +} + +func (priv *PrivateKey) Decap(outSharedSecret []byte, ciphertext *[CiphertextSize]byte) { + decrypted := priv.decryptCPA(ciphertext) + h := sha3.New512() + h.Write(decrypted[:]) + h.Write(priv.publicKeyHash[:]) + prekeyAndRandomness := h.Sum(nil) + expectedCiphertext := priv.encryptCPA(&decrypted, (*[32]byte)(prekeyAndRandomness[32:])) + equal := subtle.ConstantTimeCompare(ciphertext[:], expectedCiphertext[:]) + var secret [32]byte + for i := range secret { + secret[i] = byte(subtle.ConstantTimeSelect(equal, int(prekeyAndRandomness[i]), int(priv.foFailureSecret[i]))) + } + ciphertextHash := sha3.Sum256(ciphertext[:]) + + shake := sha3.NewShake256() + shake.Write(secret[:]) + shake.Write(ciphertextHash[:]) + shake.Read(outSharedSecret) +} + +func (priv *PrivateKey) Marshal() *[PrivateKeySize]byte { + var ret [PrivateKeySize]byte + out := priv.s.encode(ret[:], log2Prime) + publicKey := priv.PublicKey.Marshal() + n := copy(out, publicKey[:]) + out = out[n:] + n = copy(out, priv.publicKeyHash[:]) + out = out[n:] + copy(out, priv.foFailureSecret[:]) + return &ret +} diff --git a/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber_test.go b/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber_test.go new file mode 100644 index 00000000..6ff33e9b --- /dev/null +++ b/third_party/boringssl/kit/src/ssl/test/runner/kyber/kyber_test.go @@ -0,0 +1,128 @@ +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +package kyber + +import ( + "bufio" + "bytes" + "encoding/hex" + "golang.org/x/crypto/sha3" + "os" + "strings" + "testing" +) + +func TestVectors(t *testing.T) { + in, err := os.Open("../../../../crypto/kyber/kyber_tests.txt") + if err != nil { + t.Error(err) + return + } + defer in.Close() + + scanner := bufio.NewScanner(in) + var priv *PrivateKey + var encodedPublicKey *[PublicKeySize]byte + var ciphertext *[CiphertextSize]byte + sharedSecret := make([]byte, 32) + + lineNo := 0 + for scanner.Scan() { + lineNo++ + line := scanner.Text() + + parts := strings.Split(line, "=") + if len(parts) != 2 || strings.HasPrefix(line, "count ") { + continue + } + key := strings.TrimSpace(parts[0]) + value, err := hex.DecodeString(strings.TrimSpace(parts[1])) + if err != nil { + t.Errorf("bad hex value on line %d: %q", lineNo, parts[1]) + return + } + + switch key { + case "generateEntropy": + priv, encodedPublicKey = NewPrivateKey((*[64]byte)(value)) + case "encapEntropyPreHash": + hashedEntropy := sha3.Sum256(value) + ciphertext = priv.Encap(sharedSecret, &hashedEntropy) + decapSharedSecret := make([]byte, len(sharedSecret)) + priv.Decap(decapSharedSecret, ciphertext) + if !bytes.Equal(sharedSecret, decapSharedSecret) { + t.Errorf("instance on line %d did not round trip", lineNo) + return + } + case "pk": + if !bytes.Equal(encodedPublicKey[:], value) { + t.Errorf("bad 'pk' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, encodedPublicKey) + return + } + case "sk": + encodedPrivateKey := priv.Marshal() + if !bytes.Equal(encodedPrivateKey[:], value) { + t.Errorf("bad 'sk' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, encodedPrivateKey) + return + } + case "ct": + if !bytes.Equal(ciphertext[:], value) { + t.Errorf("bad 'ct' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, ciphertext[:]) + return + } + case "ss": + if !bytes.Equal(sharedSecret[:], value) { + t.Errorf("bad 'ss' value on line %d:\nwant: %x\ncalc: %x", lineNo, value, sharedSecret[:]) + return + } + } + } +} + +func TestIteration(t *testing.T) { + h := sha3.NewShake256() + + for i := 0; i < 4096; i++ { + var generateEntropy [64]byte + h.Read(generateEntropy[:]) + var encapEntropy [32]byte + h.Read(encapEntropy[:]) + + priv, encodedPublicKey := NewPrivateKey(&generateEntropy) + h.Reset() + h.Write(encodedPublicKey[:]) + encodedPrivateKey := priv.Marshal() + h.Write(encodedPrivateKey[:]) + + var sharedSecret [32]byte + ciphertext := priv.Encap(sharedSecret[:], &encapEntropy) + h.Write(ciphertext[:]) + h.Write(sharedSecret[:]) + + var decapSharedSecret [32]byte + priv.Decap(decapSharedSecret[:], ciphertext) + if !bytes.Equal(decapSharedSecret[:], sharedSecret[:]) { + t.Errorf("Decap failed on iteration %d", i) + return + } + } + + var result [16]byte + h.Read(result[:]) + const expected = "18c6cd04eaebb33b20bb1e8e2762d30d" + if hex.EncodeToString(result[:]) != expected { + t.Errorf("iteration test produced %x, but should be %v", result, expected) + } +} diff --git a/third_party/boringssl/kit/src/ssl/test/runner/mock_quic_transport.go b/third_party/boringssl/kit/src/ssl/test/runner/mock_quic_transport.go index 709f7d12..29392744 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/mock_quic_transport.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/mock_quic_transport.go @@ -54,16 +54,16 @@ func (e encryptionLevel) String() string { // Messages from TLS that are sent over a mockQUICTransport are a series of // records in the following format: // -// enum { -// initial(0), early_data(1), handshake(2), application(3), (255) -// } EncryptionLevel; +// enum { +// initial(0), early_data(1), handshake(2), application(3), (255) +// } EncryptionLevel; // -// struct { -// ContentType record_type; -// EncryptionLevel level; -// CipherSuite cipher_suite; -// opaque encrypted_record<0..2^32-1>; -// } MockQUICRecord; +// struct { +// ContentType record_type; +// EncryptionLevel level; +// CipherSuite cipher_suite; +// opaque encrypted_record<0..2^32-1>; +// } MockQUICRecord; // // The "encrypted" record is the concatenation of the encryption key and // plaintext. It and the cipher suite exist only to check both sides agree on diff --git a/third_party/boringssl/kit/src/ssl/test/runner/prf.go b/third_party/boringssl/kit/src/ssl/test/runner/prf.go index 5731be03..fc67d750 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/prf.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/prf.go @@ -451,7 +451,7 @@ var ( // deriveTrafficAEAD derives traffic keys and constructs an AEAD given a traffic // secret. -func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) interface{} { +func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) any { key := hkdfExpandLabel(suite.hash(), secret, keyTLS13, nil, suite.keyLen) iv := hkdfExpandLabel(suite.hash(), secret, ivTLS13, nil, suite.ivLen(version)) diff --git a/third_party/boringssl/kit/src/ssl/test/runner/runner.go b/third_party/boringssl/kit/src/ssl/test/runner/runner.go index cfff7147..da0795bb 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/runner.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/runner.go @@ -32,7 +32,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "math/big" "net" "os" @@ -66,6 +65,7 @@ var ( allowHintMismatch = flag.String("allow-hint-mismatch", "", "Semicolon-separated patterns of tests where hints may mismatch") numWorkersFlag = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.") shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.") + shimExtraFlags = flag.String("shim-extra-flags", "", "Semicolon-separated extra flags to pass to the shim binary on each invocation.") handshakerPath = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.") resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.") fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") @@ -234,7 +234,7 @@ func initCertificates() { *testCerts[i].cert = cert } - channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) + channelIDPEMBlock, err := os.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) if err != nil { panic(err) } @@ -294,7 +294,7 @@ type delegatedCredentialConfig struct { func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte, err error) { pemPath := path.Join(*resourceDir, filename) - pemBytes, err := ioutil.ReadFile(pemPath) + pemBytes, err := os.ReadFile(pemPath) if err != nil { return nil, nil, err } @@ -712,7 +712,7 @@ func appendTranscript(path string, data []byte) error { return nil } - settings, err := ioutil.ReadFile(path) + settings, err := os.ReadFile(path) if err != nil { if !os.IsNotExist(err) { return err @@ -723,7 +723,7 @@ func appendTranscript(path string, data []byte) error { } settings = append(settings, data...) - return ioutil.WriteFile(path, settings, 0644) + return os.WriteFile(path, settings, 0644) } // A timeoutConn implements an idle timeout on each Read and Write operation. @@ -822,7 +822,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, tr bb := newByteBuilder() bb.addU24LengthPrefixed().addBytes(encodedInner) bb.addBytes(outer) - return ioutil.WriteFile(filepath.Join(dir, name), bb.finish(), 0644) + return os.WriteFile(filepath.Join(dir, name), bb.finish(), 0644) } } @@ -1091,7 +1091,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, tr return fmt.Errorf("messageLen < 0 not supported for DTLS tests") } // Read until EOF. - _, err := io.Copy(ioutil.Discard, tlsConn) + _, err := io.Copy(io.Discard, tlsConn) return err } if messageLen == 0 { @@ -1434,6 +1434,9 @@ func runTest(statusChan chan statusMsg, test *testCase, shimPath string, mallocN }() var flags []string + if len(*shimExtraFlags) > 0 { + flags = strings.Split(*shimExtraFlags, ";") + } if test.testType == serverTest { flags = append(flags, "-server") @@ -1840,6 +1843,7 @@ var testCipherSuites = []testCipherSuite{ {"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, {"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, {"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, + {"ECDHE_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, {"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, {"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, {"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, @@ -1851,7 +1855,6 @@ var testCipherSuites = []testCipherSuite{ {"CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256}, {"AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256}, {"AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384}, - {"RSA_WITH_NULL_SHA", TLS_RSA_WITH_NULL_SHA}, } func hasComponent(suiteName, component string) bool { @@ -1879,7 +1882,12 @@ func bigFromHex(hex string) *big.Int { func convertToSplitHandshakeTests(tests []testCase) (splitHandshakeTests []testCase, err error) { var stdout bytes.Buffer - shim := exec.Command(*shimPath, "-is-handshaker-supported") + var flags []string + if len(*shimExtraFlags) > 0 { + flags = strings.Split(*shimExtraFlags, ";") + } + flags = append(flags, "-is-handshaker-supported") + shim := exec.Command(*shimPath, flags...) shim.Stdout = &stdout if err := shim.Run(); err != nil { return nil, err @@ -3191,7 +3199,7 @@ read alert 1 0 // elliptic curves, so no extensions are // involved. MaxVersion: VersionTLS12, - CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ SendV2ClientHello: true, }, @@ -3213,7 +3221,7 @@ read alert 1 0 // elliptic curves, so no extensions are // involved. MaxVersion: VersionTLS12, - CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ SendV2ClientHello: true, }, @@ -3546,6 +3554,31 @@ read alert 1 0 }, flags: []string{"-async"}, }, + { + // DTLS 1.2 allows up to a 255-byte HelloVerifyRequest cookie, which + // is the largest encodable value. + protocol: dtls, + name: "DTLS-HelloVerifyRequest-255", + config: Config{ + MaxVersion: VersionTLS12, + Bugs: ProtocolBugs{ + HelloVerifyRequestCookieLength: 255, + }, + }, + }, + { + // DTLS 1.2 allows up to a 0-byte HelloVerifyRequest cookie, which + // was probably a mistake in the spec but test that it works + // nonetheless. + protocol: dtls, + name: "DTLS-HelloVerifyRequest-0", + config: Config{ + MaxVersion: VersionTLS12, + Bugs: ProtocolBugs{ + EmptyHelloVerifyRequestCookie: true, + }, + }, + }, } testCases = append(testCases, basicTests...) @@ -3649,9 +3682,10 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto "-psk", psk, "-psk-identity", pskIdentity) } - if hasComponent(suite.name, "NULL") { - // NULL ciphers must be explicitly enabled. - flags = append(flags, "-cipher", "DEFAULT:NULL-SHA") + + if hasComponent(suite.name, "3DES") { + // BoringSSL disables 3DES ciphers by default. + flags = append(flags, "-cipher", "3DES") } var shouldFail bool @@ -4201,6 +4235,8 @@ func addCBCSplittingTests() { "-async", "-write-different-record-sizes", "-cbc-record-splitting", + // BoringSSL disables 3DES by default. + "-cipher", "ALL:3DES", }, }) testCases = append(testCases, testCase{ @@ -4219,6 +4255,8 @@ func addCBCSplittingTests() { "-write-different-record-sizes", "-cbc-record-splitting", "-partial-write", + // BoringSSL disables 3DES by default. + "-cipher", "ALL:3DES", }, }) } @@ -5742,7 +5780,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { // elliptic curves, so no extensions are // involved. MaxVersion: VersionTLS12, - CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ SendV2ClientHello: true, V2ClientHelloChallengeLength: challengeLength, @@ -9292,7 +9330,7 @@ func addRenegotiationTests() { renegotiate: 1, config: Config{ MaxVersion: VersionTLS12, - CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, }, renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, flags: []string{ @@ -9307,7 +9345,7 @@ func addRenegotiationTests() { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, - renegotiateCiphers: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + renegotiateCiphers: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, flags: []string{ "-renegotiate-freely", "-expect-total-renegotiations", "1", @@ -9696,26 +9734,29 @@ var testSignatureAlgorithms = []struct { name string id signatureAlgorithm cert testCert + // If non-zero, the curve that must be supported in TLS 1.2 for cert to be + // accepted. + curve CurveID }{ - {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA}, - {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA}, - {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA}, - {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA}, - {"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256}, + {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA, 0}, + {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA, 0}, + {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA, 0}, + {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA, 0}, + {"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256, CurveP256}, // The “P256” in the following line is not a mistake. In TLS 1.2 the // hash function doesn't have to match the curve and so the same // signature algorithm works with P-224. - {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224}, - {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256}, - {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384}, - {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521}, - {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA}, - {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA}, - {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA}, - {"Ed25519", signatureEd25519, testCertEd25519}, + {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224, CurveP224}, + {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256, CurveP256}, + {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384, CurveP384}, + {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521, CurveP521}, + {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA, 0}, + {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA, 0}, + {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA, 0}, + {"Ed25519", signatureEd25519, testCertEd25519, 0}, // Tests for key types prior to TLS 1.2. - {"RSA", 0, testCertRSA}, - {"ECDSA", 0, testCertECDSAP256}, + {"RSA", 0, testCertRSA, 0}, + {"ECDSA", 0, testCertECDSAP256, CurveP256}, } const fakeSigAlg1 signatureAlgorithm = 0x2a01 @@ -9767,6 +9808,14 @@ func addSignatureAlgorithmTests() { rejectByDefault = true } + var curveFlags []string + if alg.curve != 0 && ver.version <= VersionTLS12 { + // In TLS 1.2, the ECDH curve list also constrains ECDSA keys. Ensure the + // corresponding curve is enabled on the shim. Also include X25519 to + // ensure the shim and runner have something in common for ECDH. + curveFlags = flagInts("-curves", []int{int(CurveX25519), int(alg.curve)}) + } + var signError, signLocalError, verifyError, verifyLocalError, defaultError, defaultLocalError string if shouldFail { signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:" @@ -9805,7 +9854,7 @@ func addSignatureAlgorithmTests() { "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), }, - flagInts("-curves", shimConfig.AllCurves)..., + curveFlags..., ), shouldFail: shouldFail, expectedError: signError, @@ -9828,14 +9877,16 @@ func addSignatureAlgorithmTests() { []string{ "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), - "-signing-prefs", strconv.Itoa(int(alg.id)), }, - flagInts("-curves", shimConfig.AllCurves)..., + curveFlags..., ), expectations: connectionExpectations{ peerSignatureAlgorithm: alg.id, }, } + if alg.id != 0 { + negotiateTest.flags = append(negotiateTest.flags, "-signing-prefs", strconv.Itoa(int(alg.id))) + } if testType == serverTest { // TLS 1.2 servers only sign on some cipher suites. @@ -9868,14 +9919,7 @@ func addSignatureAlgorithmTests() { IgnorePeerSignatureAlgorithmPreferences: shouldFail, }, }, - flags: append( - []string{ - "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)), - // The algorithm may be disabled by default, so explicitly enable it. - "-verify-prefs", strconv.Itoa(int(alg.id)), - }, - flagInts("-curves", shimConfig.AllCurves)..., - ), + flags: curveFlags, // Resume the session to assert the peer signature // algorithm is reported on both handshakes. resumeSession: !shouldFail, @@ -9883,6 +9927,11 @@ func addSignatureAlgorithmTests() { expectedError: verifyError, expectedLocalError: verifyLocalError, } + if alg.id != 0 { + verifyTest.flags = append(verifyTest.flags, "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))) + // The algorithm may be disabled by default, so explicitly enable it. + verifyTest.flags = append(verifyTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) + } // Test whether the shim expects the algorithm enabled by default. defaultTest := testCase{ @@ -9903,7 +9952,7 @@ func addSignatureAlgorithmTests() { }, flags: append( []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, - flagInts("-curves", shimConfig.AllCurves)..., + curveFlags..., ), // Resume the session to assert the peer signature // algorithm is reported on both handshakes. @@ -9927,14 +9976,14 @@ func addSignatureAlgorithmTests() { InvalidSignature: true, }, }, - flags: append( - // The algorithm may be disabled by default, so explicitly enable it. - []string{"-verify-prefs", strconv.Itoa(int(alg.id))}, - flagInts("-curves", shimConfig.AllCurves)..., - ), + flags: curveFlags, shouldFail: true, expectedError: ":BAD_SIGNATURE:", } + if alg.id != 0 { + // The algorithm may be disabled by default, so explicitly enable it. + invalidTest.flags = append(invalidTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) + } if testType == serverTest { // TLS 1.2 servers only verify when they request client certificates. @@ -10453,10 +10502,8 @@ func addSignatureAlgorithmTests() { flags: []string{ "-cert-file", path.Join(*resourceDir, rsaCertificateFile), "-key-file", path.Join(*resourceDir, rsaKeyFile), - "-signing-prefs", strconv.Itoa(int(fakeSigAlg1)), "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), - "-signing-prefs", strconv.Itoa(int(fakeSigAlg2)), }, expectations: connectionExpectations{ peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, @@ -10592,7 +10639,7 @@ func addSignatureAlgorithmTests() { Certificates: []Certificate{ed25519Certificate}, Bugs: ProtocolBugs{ // Sign with Ed25519 even though it is TLS 1.1. - UseLegacySigningAlgorithm: signatureEd25519, + SigningAlgorithmForLegacyVersions: signatureEd25519, }, }, flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, @@ -10620,7 +10667,7 @@ func addSignatureAlgorithmTests() { Certificates: []Certificate{ed25519Certificate}, Bugs: ProtocolBugs{ // Sign with Ed25519 even though it is TLS 1.1. - UseLegacySigningAlgorithm: signatureEd25519, + SigningAlgorithmForLegacyVersions: signatureEd25519, }, }, flags: []string{ @@ -10740,6 +10787,69 @@ func addSignatureAlgorithmTests() { "-verify-prefs", strconv.Itoa(int(signatureEd25519)), }, }) + + for _, testType := range []testType{clientTest, serverTest} { + for _, ver := range tlsVersions { + if ver.version < VersionTLS12 { + continue + } + + prefix := "Client-" + ver.name + "-" + if testType == serverTest { + prefix = "Server-" + ver.name + "-" + } + + // Test that the shim will not sign MD5/SHA1 with RSA at TLS 1.2, + // even if specified in signing preferences. + testCases = append(testCases, testCase{ + testType: testType, + name: prefix + "NoSign-RSA_PKCS1_MD5_SHA1", + config: Config{ + MaxVersion: ver.version, + CipherSuites: signingCiphers, + ClientAuth: RequireAnyClientCert, + VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), + // Include a valid algorithm as well, to avoid an empty list + // if filtered out. + "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), + }, + shouldFail: true, + expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", + }) + + // Test that the shim will not accept MD5/SHA1 with RSA at TLS 1.2, + // even if specified in verify preferences. + testCases = append(testCases, testCase{ + testType: testType, + name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", + config: Config{ + MaxVersion: ver.version, + Certificates: []Certificate{rsaCertificate}, + Bugs: ProtocolBugs{ + IgnorePeerSignatureAlgorithmPreferences: true, + AlwaysSignAsLegacyVersion: true, + SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, + }, + }, + flags: []string{ + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), + // Include a valid algorithm as well, to avoid an empty list + // if filtered out. + "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), + "-require-any-client-certificate", + }, + shouldFail: true, + expectedError: ":WRONG_SIGNATURE_TYPE:", + }) + } + } } // timeouts is the retransmit schedule for BoringSSL. It doubles and @@ -11252,7 +11362,7 @@ func addRSAClientKeyExchangeTests() { // version are different, to detect if the // server uses the wrong one. MaxVersion: VersionTLS11, - CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ BadRSAClientKeyExchange: bad, }, @@ -11286,13 +11396,13 @@ var testCurves = []struct { {"P-384", CurveP384}, {"P-521", CurveP521}, {"X25519", CurveX25519}, - {"CECPQ2", CurveCECPQ2}, + {"Kyber", CurveX25519Kyber768}, } const bogusCurve = 0x1234 func isPqGroup(r CurveID) bool { - return r == CurveCECPQ2 + return r == CurveX25519Kyber768 } func addCurveTests() { @@ -11756,105 +11866,125 @@ func addCurveTests() { }, }) - // CECPQ2 should not be offered by a TLS < 1.3 client. + // Kyber should not be offered by a TLS < 1.3 client. testCases = append(testCases, testCase{ - name: "CECPQ2NotInTLS12", + name: "KyberNotInTLS12", config: Config{ Bugs: ProtocolBugs{ - FailIfCECPQ2Offered: true, + FailIfKyberOffered: true, }, }, flags: []string{ "-max-version", strconv.Itoa(VersionTLS12), - "-curves", strconv.Itoa(int(CurveCECPQ2)), + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), "-curves", strconv.Itoa(int(CurveX25519)), }, }) - // CECPQ2 should not crash a TLS < 1.3 client if the server mistakenly + // Kyber should not crash a TLS < 1.3 client if the server mistakenly // selects it. testCases = append(testCases, testCase{ - name: "CECPQ2NotAcceptedByTLS12Client", + name: "KyberNotAcceptedByTLS12Client", config: Config{ Bugs: ProtocolBugs{ - SendCurve: CurveCECPQ2, + SendCurve: CurveX25519Kyber768, }, }, flags: []string{ "-max-version", strconv.Itoa(VersionTLS12), - "-curves", strconv.Itoa(int(CurveCECPQ2)), + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), "-curves", strconv.Itoa(int(CurveX25519)), }, shouldFail: true, expectedError: ":WRONG_CURVE:", }) - // CECPQ2 should not be offered by default as a client. + // Kyber should not be offered by default as a client. testCases = append(testCases, testCase{ - name: "CECPQ2NotEnabledByDefaultInClients", + name: "KyberNotEnabledByDefaultInClients", config: Config{ MinVersion: VersionTLS13, Bugs: ProtocolBugs{ - FailIfCECPQ2Offered: true, + FailIfKyberOffered: true, }, }, }) - // If CECPQ2 is offered, both X25519 and CECPQ2 should have a key-share. + // If Kyber is offered, both X25519 and Kyber should have a key-share. testCases = append(testCases, testCase{ - name: "NotJustCECPQ2KeyShare", + name: "NotJustKyberKeyShare", config: Config{ MinVersion: VersionTLS13, Bugs: ProtocolBugs{ - ExpectedKeyShares: []CurveID{CurveCECPQ2, CurveX25519}, + ExpectedKeyShares: []CurveID{CurveX25519Kyber768, CurveX25519}, }, }, flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), "-curves", strconv.Itoa(int(CurveX25519)), - "-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)), + // Cannot expect Kyber until we have a Go implementation of it. + // "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), }, }) - // ... but only if CECPQ2 is listed first. + // ... and the other way around testCases = append(testCases, testCase{ - name: "CECPQ2KeyShareNotIncludedSecond", + name: "KyberKeyShareIncludedSecond", config: Config{ MinVersion: VersionTLS13, Bugs: ProtocolBugs{ - ExpectedKeyShares: []CurveID{CurveX25519}, + ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, }, }, flags: []string{ "-curves", strconv.Itoa(int(CurveX25519)), - "-curves", strconv.Itoa(int(CurveCECPQ2)), + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), "-expect-curve-id", strconv.Itoa(int(CurveX25519)), }, }) - // If CECPQ2 is the only configured curve, the key share is sent. + // ... and even if there's another curve in the middle because it's the + // first classical and first post-quantum "curves" that get key shares + // included. testCases = append(testCases, testCase{ - name: "JustConfiguringCECPQ2Works", + name: "KyberKeyShareIncludedThird", config: Config{ MinVersion: VersionTLS13, Bugs: ProtocolBugs{ - ExpectedKeyShares: []CurveID{CurveCECPQ2}, + ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, }, }, flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), - "-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)), + "-curves", strconv.Itoa(int(CurveX25519)), + "-curves", strconv.Itoa(int(CurveP256)), + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), + "-expect-curve-id", strconv.Itoa(int(CurveX25519)), }, }) - // As a server, CECPQ2 is not yet supported by default. + // If Kyber is the only configured curve, the key share is sent. + testCases = append(testCases, testCase{ + name: "JustConfiguringKyberWorks", + config: Config{ + MinVersion: VersionTLS13, + Bugs: ProtocolBugs{ + ExpectedKeyShares: []CurveID{CurveX25519Kyber768}, + }, + }, + flags: []string{ + "-curves", strconv.Itoa(int(CurveX25519Kyber768)), + "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), + }, + }) + + // As a server, Kyber is not yet supported by default. testCases = append(testCases, testCase{ testType: serverTest, - name: "CECPQ2NotEnabledByDefaultForAServer", + name: "KyberNotEnabledByDefaultForAServer", config: Config{ MinVersion: VersionTLS13, - CurvePreferences: []CurveID{CurveCECPQ2, CurveX25519}, - DefaultCurves: []CurveID{CurveCECPQ2}, + CurvePreferences: []CurveID{CurveX25519Kyber768, CurveX25519}, + DefaultCurves: []CurveID{CurveX25519Kyber768}, }, flags: []string{ "-server-preference", @@ -15082,95 +15212,6 @@ func addTLS13CipherPreferenceTests() { "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), }, }) - - // CECPQ2 prefers 256-bit ciphers but will use AES-128 if there's nothing else. - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TLS13-CipherPreference-CECPQ2-AES128Only", - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - }, - }, - flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), - }, - }) - - // When a 256-bit cipher is offered, even if not in first place, it should be - // picked. - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TLS13-CipherPreference-CECPQ2-AES256Preferred", - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - }, - }, - flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), - }, - expectations: connectionExpectations{ - cipher: TLS_AES_256_GCM_SHA384, - }, - }) - // ... but when CECPQ2 isn't being used, the client's preference controls. - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TLS13-CipherPreference-CECPQ2-AES128PreferredOtherwise", - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - }, - }, - flags: []string{ - "-curves", strconv.Itoa(int(CurveX25519)), - }, - expectations: connectionExpectations{ - cipher: TLS_AES_128_GCM_SHA256, - }, - }) - - // Test that CECPQ2 continues to honor AES vs ChaCha20 logic. - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TLS13-CipherPreference-CECPQ2-AES128-ChaCha20-AES256", - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_CHACHA20_POLY1305_SHA256, - TLS_AES_256_GCM_SHA384, - }, - }, - flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), - "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), - "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), - }, - }) - testCases = append(testCases, testCase{ - testType: serverTest, - name: "TLS13-CipherPreference-CECPQ2-AES128-AES256-ChaCha20", - config: Config{ - MaxVersion: VersionTLS13, - CipherSuites: []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - TLS_CHACHA20_POLY1305_SHA256, - }, - }, - flags: []string{ - "-curves", strconv.Itoa(int(CurveCECPQ2)), - "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), - "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), - }, - }) } func addPeekTests() { @@ -15588,9 +15629,6 @@ func addRSAKeyUsageTests() { }, shouldFail: true, expectedError: ":KEY_USAGE_BIT_INCORRECT:", - flags: []string{ - "-enforce-rsa-key-usage", - }, }) testCases = append(testCases, testCase{ @@ -15602,9 +15640,6 @@ func addRSAKeyUsageTests() { Certificates: []Certificate{dsCert}, CipherSuites: dsSuites, }, - flags: []string{ - "-enforce-rsa-key-usage", - }, }) // TLS 1.3 removes the encipherment suites. @@ -15618,9 +15653,6 @@ func addRSAKeyUsageTests() { Certificates: []Certificate{encCert}, CipherSuites: encSuites, }, - flags: []string{ - "-enforce-rsa-key-usage", - }, }) testCases = append(testCases, testCase{ @@ -15634,46 +15666,46 @@ func addRSAKeyUsageTests() { }, shouldFail: true, expectedError: ":KEY_USAGE_BIT_INCORRECT:", - flags: []string{ - "-enforce-rsa-key-usage", - }, }) // In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag. testCases = append(testCases, testCase{ testType: clientTest, - name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced" + ver.name, + name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced-" + ver.name, config: Config{ MinVersion: ver.version, MaxVersion: ver.version, Certificates: []Certificate{dsCert}, CipherSuites: encSuites, }, + flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, }) testCases = append(testCases, testCase{ testType: clientTest, - name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced" + ver.name, + name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced-" + ver.name, config: Config{ MinVersion: ver.version, MaxVersion: ver.version, Certificates: []Certificate{encCert}, CipherSuites: dsSuites, }, + flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, }) } if ver.version >= VersionTLS13 { - // In 1.3 and above, we enforce keyUsage even without the flag. + // In 1.3 and above, we enforce keyUsage even when disabled. testCases = append(testCases, testCase{ testType: clientTest, - name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Enforced" + ver.name, + name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-AlwaysEnforced-" + ver.name, config: Config{ MinVersion: ver.version, MaxVersion: ver.version, Certificates: []Certificate{encCert}, CipherSuites: dsSuites, }, + flags: []string{"-ignore-rsa-key-usage"}, shouldFail: true, expectedError: ":KEY_USAGE_BIT_INCORRECT:", }) @@ -16364,7 +16396,7 @@ func addJDK11WorkaroundTests() { func addDelegatedCredentialTests() { certPath := path.Join(*resourceDir, rsaCertificateFile) - pemBytes, err := ioutil.ReadFile(certPath) + pemBytes, err := os.ReadFile(certPath) if err != nil { panic(err) } @@ -16776,9 +16808,7 @@ func addEncryptedClientHelloTests() { }, shouldFail: true, expectedLocalError: "remote error: illegal parameter", - // The decoding algorithm relies on the ordering requirement, so - // the wrong order appears as a missing extension. - expectedError: ":OUTER_EXTENSION_NOT_FOUND:", + expectedError: ":INVALID_OUTER_EXTENSION:", }) // Test that the server rejects duplicated values in ech_outer_extensions. @@ -16812,9 +16842,7 @@ func addEncryptedClientHelloTests() { }, shouldFail: true, expectedLocalError: "remote error: illegal parameter", - // The decoding algorithm relies on the ordering requirement, so - // duplicates appear as missing extensions. - expectedError: ":OUTER_EXTENSION_NOT_FOUND:", + expectedError: ":INVALID_OUTER_EXTENSION:", }) // Test that the server rejects references to missing extensions in @@ -16843,7 +16871,7 @@ func addEncryptedClientHelloTests() { }, shouldFail: true, expectedLocalError: "remote error: illegal parameter", - expectedError: ":DECODE_ERROR:", + expectedError: ":INVALID_OUTER_EXTENSION:", }) // Test that the server rejects a references to the ECH extension in @@ -16871,7 +16899,46 @@ func addEncryptedClientHelloTests() { }, shouldFail: true, expectedLocalError: "remote error: illegal parameter", - expectedError: ":DECODE_ERROR:", + expectedError: ":INVALID_OUTER_EXTENSION:", + }) + + // Test the message callback is correctly reported with ECH. + clientAndServerHello := "read hs 1\nread clienthelloinner\nwrite hs 2\n" + expectMsgCallback := clientAndServerHello + "write ccs\n" + if hrr { + expectMsgCallback += clientAndServerHello + } + // EncryptedExtensions onwards. + expectMsgCallback += `write hs 8 +write hs 11 +write hs 15 +write hs 20 +read hs 20 +write hs 4 +write hs 4 +` + testCases = append(testCases, testCase{ + testType: serverTest, + protocol: protocol, + name: prefix + "ECH-Server-MessageCallback" + suffix, + config: Config{ + ServerName: "secret.example", + ClientECHConfig: echConfig.ECHConfig, + DefaultCurves: defaultCurves, + Bugs: ProtocolBugs{ + NoCloseNotify: true, // Align QUIC and TCP traces. + }, + }, + flags: []string{ + "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), + "-ech-server-key", base64FlagValue(echConfig.Key), + "-ech-is-retry-config", "1", + "-expect-ech-accept", + "-expect-msg-callback", expectMsgCallback, + }, + expectations: connectionExpectations{ + echAccepted: true, + }, }) } @@ -18622,6 +18689,60 @@ func addEncryptedClientHelloTests() { shouldFail: true, expectedError: ":INCONSISTENT_ECH_NEGOTIATION:", }) + + // Test the message callback is correctly reported, with and without + // HelloRetryRequest. + clientAndServerHello := "write clienthelloinner\nwrite hs 1\nread hs 2\n" + // EncryptedExtensions onwards. + finishHandshake := `read hs 8 +read hs 11 +read hs 15 +read hs 20 +write hs 20 +read hs 4 +read hs 4 +` + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: prefix + "ECH-Client-MessageCallback", + config: Config{ + MinVersion: VersionTLS13, + MaxVersion: VersionTLS13, + ServerECHConfigs: []ServerECHConfig{echConfig}, + Bugs: ProtocolBugs{ + NoCloseNotify: true, // Align QUIC and TCP traces. + }, + }, + flags: []string{ + "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), + "-expect-ech-accept", + "-expect-msg-callback", clientAndServerHello + "write ccs\n" + finishHandshake, + }, + expectations: connectionExpectations{echAccepted: true}, + }) + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: prefix + "ECH-Client-MessageCallback-HelloRetryRequest", + config: Config{ + MinVersion: VersionTLS13, + MaxVersion: VersionTLS13, + CurvePreferences: []CurveID{CurveP384}, + ServerECHConfigs: []ServerECHConfig{echConfig}, + Bugs: ProtocolBugs{ + ExpectMissingKeyShare: true, // Check we triggered HRR. + NoCloseNotify: true, // Align QUIC and TCP traces. + }, + }, + flags: []string{ + "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), + "-expect-ech-accept", + "-expect-hrr", // Check we triggered HRR. + "-expect-msg-callback", clientAndServerHello + "write ccs\n" + clientAndServerHello + finishHandshake, + }, + expectations: connectionExpectations{echAccepted: true}, + }) } } @@ -18681,6 +18802,27 @@ func addHintMismatchTests() { curveID: CurveX25519, }, }) + if protocol != quic { + testCases = append(testCases, testCase{ + name: protocol.String() + "-HintMismatch-ECDHE-Group", + testType: serverTest, + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + DefaultCurves: []CurveID{CurveX25519, CurveP256}, + }, + flags: []string{ + "-allow-hint-mismatch", + "-on-shim-curves", strconv.Itoa(int(CurveX25519)), + "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), + }, + expectations: connectionExpectations{ + curveID: CurveX25519, + }, + }) + } // If the handshaker does HelloRetryRequest, it will omit most hints. // The shim should still work. @@ -18729,7 +18871,7 @@ func addHintMismatchTests() { // The shim and handshaker may have different signature algorithm // preferences. testCases = append(testCases, testCase{ - name: protocol.String() + "-HintMismatch-SignatureAlgorithm", + name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS13", testType: serverTest, protocol: protocol, skipSplitHandshake: true, @@ -18752,12 +18894,38 @@ func addHintMismatchTests() { peerSignatureAlgorithm: signatureRSAPSSWithSHA256, }, }) + if protocol != quic { + testCases = append(testCases, testCase{ + name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS12", + testType: serverTest, + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + VerifySignatureAlgorithms: []signatureAlgorithm{ + signatureRSAPSSWithSHA256, + signatureRSAPSSWithSHA384, + }, + }, + flags: []string{ + "-allow-hint-mismatch", + "-cert-file", path.Join(*resourceDir, rsaCertificateFile), + "-key-file", path.Join(*resourceDir, rsaKeyFile), + "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), + "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), + }, + expectations: connectionExpectations{ + peerSignatureAlgorithm: signatureRSAPSSWithSHA256, + }, + }) + } // The shim and handshaker may disagree on whether resumption is allowed. // We run the first connection with tickets enabled, so the client is // issued a ticket, then disable tickets on the second connection. testCases = append(testCases, testCase{ - name: protocol.String() + "-HintMismatch-NoTickets1", + name: protocol.String() + "-HintMismatch-NoTickets1-TLS13", testType: serverTest, protocol: protocol, skipSplitHandshake: true, @@ -18773,7 +18941,7 @@ func addHintMismatchTests() { expectResumeRejected: true, }) testCases = append(testCases, testCase{ - name: protocol.String() + "-HintMismatch-NoTickets2", + name: protocol.String() + "-HintMismatch-NoTickets2-TLS13", testType: serverTest, protocol: protocol, skipSplitHandshake: true, @@ -18787,6 +18955,39 @@ func addHintMismatchTests() { }, resumeSession: true, }) + if protocol != quic { + testCases = append(testCases, testCase{ + name: protocol.String() + "-HintMismatch-NoTickets1-TLS12", + testType: serverTest, + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + }, + flags: []string{ + "-on-resume-allow-hint-mismatch", + "-on-shim-on-resume-no-ticket", + }, + resumeSession: true, + expectResumeRejected: true, + }) + testCases = append(testCases, testCase{ + name: protocol.String() + "-HintMismatch-NoTickets2-TLS12", + testType: serverTest, + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + }, + flags: []string{ + "-on-resume-allow-hint-mismatch", + "-on-handshaker-on-resume-no-ticket", + }, + resumeSession: true, + }) + } // The shim and handshaker may disagree on whether to request a client // certificate. @@ -18940,6 +19141,296 @@ func addHintMismatchTests() { ocspResponse: testOCSPResponse, }, }) + + // The shim and handshaker may disagree on cipher suite, to the point + // that one selects RSA key exchange (no applicable hint) and the other + // selects ECDHE_RSA (hints are useful). + if protocol != quic { + testCases = append(testCases, testCase{ + testType: serverTest, + name: protocol.String() + "-HintMismatch-CipherMismatch1", + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + }, + flags: []string{ + "-allow-hint-mismatch", + "-on-shim-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "-on-handshaker-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", + }, + expectations: connectionExpectations{ + cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: protocol.String() + "-HintMismatch-CipherMismatch2", + protocol: protocol, + skipSplitHandshake: true, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS12, + }, + flags: []string{ + // There is no need to pass -allow-hint-mismatch. The + // handshaker will unnecessarily generate a signature hints. + // This is not reported as a mismatch because hints would + // not have helped the shim anyway. + "-on-shim-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", + "-on-handshaker-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + }, + expectations: connectionExpectations{ + cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, + }, + }) + } + } +} + +func addCompliancePolicyTests() { + for _, protocol := range []protocol{tls, quic} { + for _, suite := range testCipherSuites { + var isFIPSCipherSuite bool + switch suite.id { + case TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + isFIPSCipherSuite = true + } + + var isWPACipherSuite bool + switch suite.id { + case TLS_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + isWPACipherSuite = true + } + + var certFile string + var keyFile string + var certs []Certificate + if hasComponent(suite.name, "ECDSA") { + certFile = ecdsaP384CertificateFile + keyFile = ecdsaP384KeyFile + certs = []Certificate{ecdsaP384Certificate} + } else { + certFile = rsaCertificateFile + keyFile = rsaKeyFile + certs = []Certificate{rsaCertificate} + } + + maxVersion := uint16(VersionTLS13) + if !isTLS13Suite(suite.name) { + if protocol == quic { + continue + } + maxVersion = VersionTLS12 + } + + policies := []struct { + flag string + cipherSuiteOk bool + }{ + {"-fips-202205", isFIPSCipherSuite}, + {"-wpa-202304", isWPACipherSuite}, + } + + for _, policy := range policies { + testCases = append(testCases, testCase{ + testType: serverTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + suite.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: maxVersion, + CipherSuites: []uint16{suite.id}, + }, + certFile: certFile, + keyFile: keyFile, + flags: []string{ + policy.flag, + }, + shouldFail: !policy.cipherSuiteOk, + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + suite.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: maxVersion, + CipherSuites: []uint16{suite.id}, + Certificates: certs, + }, + flags: []string{ + policy.flag, + }, + shouldFail: !policy.cipherSuiteOk, + }) + } + } + + // Check that a TLS 1.3 client won't accept ChaCha20 even if the server + // picks it without it being in the client's cipher list. + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: "Compliance-fips202205-" + protocol.String() + "-Client-ReallyWontAcceptChaCha", + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: maxVersion, + Bugs: ProtocolBugs{ + SendCipherSuite: TLS_CHACHA20_POLY1305_SHA256, + }, + }, + flags: []string{ + "-fips-202205", + }, + shouldFail: true, + expectedError: ":WRONG_CIPHER_RETURNED:", + }) + + for _, curve := range testCurves { + var isFIPSCurve bool + switch curve.id { + case CurveP256, CurveP384: + isFIPSCurve = true + } + + var isWPACurve bool + switch curve.id { + case CurveP384: + isWPACurve = true + } + + policies := []struct { + flag string + curveOk bool + }{ + {"-fips-202205", isFIPSCurve}, + {"-wpa-202304", isWPACurve}, + } + + for _, policy := range policies { + testCases = append(testCases, testCase{ + testType: serverTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + curve.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS13, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{ + policy.flag, + }, + shouldFail: !policy.curveOk, + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + curve.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: VersionTLS13, + CurvePreferences: []CurveID{curve.id}, + }, + flags: []string{ + policy.flag, + }, + shouldFail: !policy.curveOk, + }) + } + } + + for _, sigalg := range testSignatureAlgorithms { + var isFIPSSigAlg bool + switch sigalg.id { + case signatureRSAPKCS1WithSHA256, + signatureRSAPKCS1WithSHA384, + signatureRSAPKCS1WithSHA512, + signatureECDSAWithP256AndSHA256, + signatureECDSAWithP384AndSHA384, + signatureRSAPSSWithSHA256, + signatureRSAPSSWithSHA384, + signatureRSAPSSWithSHA512: + isFIPSSigAlg = true + } + + var isWPASigAlg bool + switch sigalg.id { + case signatureRSAPKCS1WithSHA384, + signatureRSAPKCS1WithSHA512, + signatureECDSAWithP384AndSHA384, + signatureRSAPSSWithSHA384, + signatureRSAPSSWithSHA512: + isWPASigAlg = true + } + + if sigalg.cert == testCertECDSAP224 { + // This can work in TLS 1.2, but not with TLS 1.3. + // For consistency it's not permitted in FIPS mode. + isFIPSSigAlg = false + } + + maxVersion := uint16(VersionTLS13) + if hasComponent(sigalg.name, "PKCS1") { + if protocol == quic { + continue + } + maxVersion = VersionTLS12 + } + + policies := []struct { + flag string + sigAlgOk bool + }{ + {"-fips-202205", isFIPSSigAlg}, + {"-wpa-202304", isWPASigAlg}, + } + + for _, policy := range policies { + testCases = append(testCases, testCase{ + testType: serverTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + sigalg.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: maxVersion, + VerifySignatureAlgorithms: []signatureAlgorithm{sigalg.id}, + }, + flags: []string{ + policy.flag, + "-cert-file", path.Join(*resourceDir, getShimCertificate(sigalg.cert)), + "-key-file", path.Join(*resourceDir, getShimKey(sigalg.cert)), + }, + shouldFail: !policy.sigAlgOk, + }) + + testCases = append(testCases, testCase{ + testType: clientTest, + protocol: protocol, + name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + sigalg.name, + config: Config{ + MinVersion: VersionTLS12, + MaxVersion: maxVersion, + SignSignatureAlgorithms: []signatureAlgorithm{sigalg.id}, + Certificates: []Certificate{getRunnerCertificate(sigalg.cert)}, + }, + flags: []string{ + policy.flag, + }, + shouldFail: !policy.sigAlgOk, + }) + } + } } } @@ -19123,7 +19614,7 @@ func main() { initCertificates() if len(*shimConfigFile) != 0 { - encoded, err := ioutil.ReadFile(*shimConfigFile) + encoded, err := os.ReadFile(*shimConfigFile) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err) os.Exit(1) @@ -19185,6 +19676,7 @@ func main() { addDelegatedCredentialTests() addEncryptedClientHelloTests() addHintMismatchTests() + addCompliancePolicyTests() toAppend, err := convertToSplitHandshakeTests(testCases) if err != nil { @@ -19220,8 +19712,22 @@ func main() { noneOfPattern = strings.Split(*skipTest, ";") } + shardIndex, shardTotal, err := getSharding() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if shardTotal > 0 { + fmt.Printf("This is shard %d of 0..%d (inclusive)\n", shardIndex, shardTotal-1) + } + var foundTest bool for i := range testCases { + if shardTotal > 0 && i%shardTotal != shardIndex { + continue + } + matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name) if err != nil { fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err) @@ -19259,7 +19765,7 @@ func main() { } } - if !foundTest { + if !foundTest && shardTotal == 0 { fmt.Fprintf(os.Stderr, "No tests run\n") os.Exit(1) } diff --git a/third_party/boringssl/kit/src/ssl/test/runner/sharding.go b/third_party/boringssl/kit/src/ssl/test/runner/sharding.go new file mode 100644 index 00000000..b10973a8 --- /dev/null +++ b/third_party/boringssl/kit/src/ssl/test/runner/sharding.go @@ -0,0 +1,76 @@ +// Copyright (c) 2022, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +package runner + +import ( + "fmt" + "os" + "strconv" +) + +const ( + shardStatusFileEnv = "TEST_SHARD_STATUS_FILE" + shardTotalEnv = "TEST_TOTAL_SHARDS" + shardIndexEnv = "TEST_SHARD_INDEX" + shardPrefix = "RUNNER_" +) + +func init() { + // When run under `go test`, init() functions may be run twice if the + // test binary ends up forking and execing itself. Therefore we move + // the environment variables to names that don't interfere with Go's + // own support for sharding. If we recorded and erased them, then they + // wouldn't exist the second time the binary runs. + for _, key := range []string{shardStatusFileEnv, shardTotalEnv, shardIndexEnv} { + value := os.Getenv(key) + if len(value) > 0 { + os.Setenv(shardPrefix+key, value) + os.Setenv(key, "") + } + } +} + +// getSharding returns the shard index and count, or zeros if sharding is not +// enabled. +func getSharding() (index, total int, err error) { + statusFile := os.Getenv(shardPrefix + shardStatusFileEnv) + totalNumStr := os.Getenv(shardPrefix + shardTotalEnv) + indexStr := os.Getenv(shardPrefix + shardIndexEnv) + if len(totalNumStr) == 0 || len(indexStr) == 0 { + return 0, 0, nil + } + + totalNum, err := strconv.Atoi(totalNumStr) + if err != nil { + return 0, 0, fmt.Errorf("$%s is %q, but expected a number\n", shardTotalEnv, totalNumStr) + } + + index, err = strconv.Atoi(indexStr) + if err != nil { + return 0, 0, fmt.Errorf("$%s is %q, but expected a number\n", shardIndexEnv, indexStr) + } + + if index < 0 || index >= totalNum { + return 0, 0, fmt.Errorf("shard index/total of %d/%d is invalid\n", index, totalNum) + } + + if len(statusFile) > 0 { + if err := os.WriteFile(statusFile, nil, 0664); err != nil { + return 0, 0, err + } + } + + return index, totalNum, nil +} diff --git a/third_party/boringssl/kit/src/ssl/test/runner/sign.go b/third_party/boringssl/kit/src/ssl/test/runner/sign.go index d57cd607..70541a1e 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/sign.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/sign.go @@ -272,10 +272,10 @@ func (e *ed25519Signer) verifyMessage(key crypto.PublicKey, msg, sig []byte) err return nil } -func getSigner(version uint16, key interface{}, config *Config, sigAlg signatureAlgorithm, isVerify bool) (signer, error) { +func getSigner(version uint16, key any, config *Config, sigAlg signatureAlgorithm, isVerify bool) (signer, error) { // TLS 1.1 and below use legacy signature algorithms. - if version < VersionTLS12 { - if config.Bugs.UseLegacySigningAlgorithm == 0 || isVerify { + if version < VersionTLS12 || (!isVerify && config.Bugs.AlwaysSignAsLegacyVersion) { + if config.Bugs.SigningAlgorithmForLegacyVersions == 0 || isVerify { switch key.(type) { case *rsa.PrivateKey, *rsa.PublicKey: return &rsaPKCS1Signer{crypto.MD5SHA1}, nil @@ -287,7 +287,7 @@ func getSigner(version uint16, key interface{}, config *Config, sigAlg signature } // Fall through, forcing a particular algorithm. - sigAlg = config.Bugs.UseLegacySigningAlgorithm + sigAlg = config.Bugs.SigningAlgorithmForLegacyVersions } switch sigAlg { diff --git a/third_party/boringssl/kit/src/ssl/test/runner/tls.go b/third_party/boringssl/kit/src/ssl/test/runner/tls.go index af3fa3af..6e57d181 100644 --- a/third_party/boringssl/kit/src/ssl/test/runner/tls.go +++ b/third_party/boringssl/kit/src/ssl/test/runner/tls.go @@ -14,8 +14,8 @@ import ( "crypto/x509" "encoding/pem" "errors" - "io/ioutil" "net" + "os" "strings" "time" ) @@ -174,11 +174,11 @@ func Dial(network, addr string, config *Config) (*Conn, error) { // LoadX509KeyPair reads and parses a public/private key pair from a pair of // files. The files must contain PEM encoded data. func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { - certPEMBlock, err := ioutil.ReadFile(certFile) + certPEMBlock, err := os.ReadFile(certFile) if err != nil { return } - keyPEMBlock, err := ioutil.ReadFile(keyFile) + keyPEMBlock, err := os.ReadFile(keyFile) if err != nil { return } diff --git a/third_party/boringssl/kit/src/ssl/test/test_config.cc b/third_party/boringssl/kit/src/ssl/test/test_config.cc index 7d1cefa1..485a560b 100644 --- a/third_party/boringssl/kit/src/ssl/test/test_config.cc +++ b/third_party/boringssl/kit/src/ssl/test/test_config.cc @@ -15,15 +15,24 @@ #include "test_config.h" #include +#include +#include +#include #include #include #include +#include +#include +#include #include +#include #include +#include #include #include +#include #include #include "../../crypto/internal.h" @@ -34,235 +43,88 @@ namespace { -template struct Flag { - const char *flag; - T TestConfig::*member; + const char *name; + bool has_param; + // If |has_param| is false, |param| will be nullptr. + std::function set_param; }; -// FindField looks for the flag in |flags| that matches |flag|. If one is found, -// it returns a pointer to the corresponding field in |config|. Otherwise, it -// returns NULL. -template -T *FindField(TestConfig *config, const Flag (&flags)[N], const char *flag) { - for (size_t i = 0; i < N; i++) { - if (strcmp(flag, flags[i].flag) == 0) { - return &(config->*(flags[i].member)); - } - } - return NULL; +Flag BoolFlag(const char *name, bool TestConfig::*field) { + return Flag{name, false, [=](TestConfig *config, const char *) -> bool { + config->*field = true; + return true; + }}; } -const Flag kBoolFlags[] = { - {"-server", &TestConfig::is_server}, - {"-dtls", &TestConfig::is_dtls}, - {"-quic", &TestConfig::is_quic}, - {"-fallback-scsv", &TestConfig::fallback_scsv}, - {"-enable-ech-grease", &TestConfig::enable_ech_grease}, - {"-expect-ech-accept", &TestConfig::expect_ech_accept}, - {"-expect-no-ech-name-override", &TestConfig::expect_no_ech_name_override}, - {"-expect-no-ech-retry-configs", &TestConfig::expect_no_ech_retry_configs}, - {"-require-any-client-certificate", - &TestConfig::require_any_client_certificate}, - {"-false-start", &TestConfig::false_start}, - {"-async", &TestConfig::async}, - {"-write-different-record-sizes", - &TestConfig::write_different_record_sizes}, - {"-cbc-record-splitting", &TestConfig::cbc_record_splitting}, - {"-partial-write", &TestConfig::partial_write}, - {"-no-tls13", &TestConfig::no_tls13}, - {"-no-tls12", &TestConfig::no_tls12}, - {"-no-tls11", &TestConfig::no_tls11}, - {"-no-tls1", &TestConfig::no_tls1}, - {"-no-ticket", &TestConfig::no_ticket}, - {"-enable-channel-id", &TestConfig::enable_channel_id}, - {"-shim-writes-first", &TestConfig::shim_writes_first}, - {"-expect-session-miss", &TestConfig::expect_session_miss}, - {"-decline-alpn", &TestConfig::decline_alpn}, - {"-reject-alpn", &TestConfig::reject_alpn}, - {"-select-empty-alpn", &TestConfig::select_empty_alpn}, - {"-defer-alps", &TestConfig::defer_alps}, - {"-expect-extended-master-secret", - &TestConfig::expect_extended_master_secret}, - {"-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling}, - {"-enable-signed-cert-timestamps", - &TestConfig::enable_signed_cert_timestamps}, - {"-implicit-handshake", &TestConfig::implicit_handshake}, - {"-use-early-callback", &TestConfig::use_early_callback}, - {"-fail-early-callback", &TestConfig::fail_early_callback}, - {"-install-ddos-callback", &TestConfig::install_ddos_callback}, - {"-fail-ddos-callback", &TestConfig::fail_ddos_callback}, - {"-fail-cert-callback", &TestConfig::fail_cert_callback}, - {"-handshake-never-done", &TestConfig::handshake_never_done}, - {"-use-export-context", &TestConfig::use_export_context}, - {"-tls-unique", &TestConfig::tls_unique}, - {"-expect-ticket-renewal", &TestConfig::expect_ticket_renewal}, - {"-expect-no-session", &TestConfig::expect_no_session}, - {"-expect-ticket-supports-early-data", - &TestConfig::expect_ticket_supports_early_data}, - {"-use-ticket-callback", &TestConfig::use_ticket_callback}, - {"-renew-ticket", &TestConfig::renew_ticket}, - {"-enable-early-data", &TestConfig::enable_early_data}, - {"-check-close-notify", &TestConfig::check_close_notify}, - {"-shim-shuts-down", &TestConfig::shim_shuts_down}, - {"-verify-fail", &TestConfig::verify_fail}, - {"-verify-peer", &TestConfig::verify_peer}, - {"-verify-peer-if-no-obc", &TestConfig::verify_peer_if_no_obc}, - {"-expect-verify-result", &TestConfig::expect_verify_result}, - {"-renegotiate-once", &TestConfig::renegotiate_once}, - {"-renegotiate-freely", &TestConfig::renegotiate_freely}, - {"-renegotiate-ignore", &TestConfig::renegotiate_ignore}, - {"-renegotiate-explicit", &TestConfig::renegotiate_explicit}, - {"-forbid-renegotiation-after-handshake", - &TestConfig::forbid_renegotiation_after_handshake}, - {"-use-old-client-cert-callback", - &TestConfig::use_old_client_cert_callback}, - {"-send-alert", &TestConfig::send_alert}, - {"-peek-then-read", &TestConfig::peek_then_read}, - {"-enable-grease", &TestConfig::enable_grease}, - {"-permute-extensions", &TestConfig::permute_extensions}, - {"-use-exporter-between-reads", &TestConfig::use_exporter_between_reads}, - {"-retain-only-sha256-client-cert", - &TestConfig::retain_only_sha256_client_cert}, - {"-expect-sha256-client-cert", &TestConfig::expect_sha256_client_cert}, - {"-read-with-unfinished-write", &TestConfig::read_with_unfinished_write}, - {"-expect-secure-renegotiation", &TestConfig::expect_secure_renegotiation}, - {"-expect-no-secure-renegotiation", - &TestConfig::expect_no_secure_renegotiation}, - {"-expect-session-id", &TestConfig::expect_session_id}, - {"-expect-no-session-id", &TestConfig::expect_no_session_id}, - {"-expect-accept-early-data", &TestConfig::expect_accept_early_data}, - {"-expect-reject-early-data", &TestConfig::expect_reject_early_data}, - {"-expect-no-offer-early-data", &TestConfig::expect_no_offer_early_data}, - {"-no-op-extra-handshake", &TestConfig::no_op_extra_handshake}, - {"-handshake-twice", &TestConfig::handshake_twice}, - {"-allow-unknown-alpn-protos", &TestConfig::allow_unknown_alpn_protos}, - {"-use-custom-verify-callback", &TestConfig::use_custom_verify_callback}, - {"-allow-false-start-without-alpn", - &TestConfig::allow_false_start_without_alpn}, - {"-handoff", &TestConfig::handoff}, - {"-handshake-hints", &TestConfig::handshake_hints}, - {"-allow-hint-mismatch", &TestConfig::allow_hint_mismatch}, - {"-use-ocsp-callback", &TestConfig::use_ocsp_callback}, - {"-set-ocsp-in-callback", &TestConfig::set_ocsp_in_callback}, - {"-decline-ocsp-callback", &TestConfig::decline_ocsp_callback}, - {"-fail-ocsp-callback", &TestConfig::fail_ocsp_callback}, - {"-install-cert-compression-algs", - &TestConfig::install_cert_compression_algs}, - {"-is-handshaker-supported", &TestConfig::is_handshaker_supported}, - {"-handshaker-resume", &TestConfig::handshaker_resume}, - {"-reverify-on-resume", &TestConfig::reverify_on_resume}, - {"-enforce-rsa-key-usage", &TestConfig::enforce_rsa_key_usage}, - {"-jdk11-workaround", &TestConfig::jdk11_workaround}, - {"-server-preference", &TestConfig::server_preference}, - {"-export-traffic-secrets", &TestConfig::export_traffic_secrets}, - {"-key-update", &TestConfig::key_update}, - {"-expect-delegated-credential-used", - &TestConfig::expect_delegated_credential_used}, - {"-expect-hrr", &TestConfig::expect_hrr}, - {"-expect-no-hrr", &TestConfig::expect_no_hrr}, - {"-wait-for-debugger", &TestConfig::wait_for_debugger}, -}; +template +bool StringToInt(T *out, const char *str) { + static_assert(std::is_integral::value, "not an integral type"); + static_assert(sizeof(T) <= sizeof(long long), "type too large for long long"); -const Flag kStringFlags[] = { - {"-write-settings", &TestConfig::write_settings}, - {"-key-file", &TestConfig::key_file}, - {"-cert-file", &TestConfig::cert_file}, - {"-expect-server-name", &TestConfig::expect_server_name}, - {"-expect-ech-name-override", &TestConfig::expect_ech_name_override}, - {"-advertise-npn", &TestConfig::advertise_npn}, - {"-expect-next-proto", &TestConfig::expect_next_proto}, - {"-select-next-proto", &TestConfig::select_next_proto}, - {"-send-channel-id", &TestConfig::send_channel_id}, - {"-host-name", &TestConfig::host_name}, - {"-advertise-alpn", &TestConfig::advertise_alpn}, - {"-expect-alpn", &TestConfig::expect_alpn}, - {"-expect-late-alpn", &TestConfig::expect_late_alpn}, - {"-expect-advertised-alpn", &TestConfig::expect_advertised_alpn}, - {"-select-alpn", &TestConfig::select_alpn}, - {"-psk", &TestConfig::psk}, - {"-psk-identity", &TestConfig::psk_identity}, - {"-srtp-profiles", &TestConfig::srtp_profiles}, - {"-cipher", &TestConfig::cipher}, - {"-export-label", &TestConfig::export_label}, - {"-export-context", &TestConfig::export_context}, - {"-expect-peer-cert-file", &TestConfig::expect_peer_cert_file}, - {"-use-client-ca-list", &TestConfig::use_client_ca_list}, - {"-expect-client-ca-list", &TestConfig::expect_client_ca_list}, - {"-expect-msg-callback", &TestConfig::expect_msg_callback}, - {"-handshaker-path", &TestConfig::handshaker_path}, - {"-delegated-credential", &TestConfig::delegated_credential}, - {"-expect-early-data-reason", &TestConfig::expect_early_data_reason}, - {"-quic-early-data-context", &TestConfig::quic_early_data_context}, -}; + // |strtoull| allows leading '-' with wraparound. Additionally, both + // functions accept empty strings and leading whitespace. + if (!OPENSSL_isdigit(static_cast(*str)) && + (!std::is_signed::value || *str != '-')) { + return false; + } + + errno = 0; + char *end; + if (std::is_signed::value) { + long long value = strtoll(str, &end, 10); + if (value < std::numeric_limits::min() || + value > std::numeric_limits::max()) { + return false; + } + *out = static_cast(value); + } else { + unsigned long long value = strtoull(str, &end, 10); + if (value > std::numeric_limits::max()) { + return false; + } + *out = static_cast(value); + } + + // Check for overflow and that the whole input was consumed. + return errno != ERANGE && *end == '\0'; +} + +template +Flag IntFlag(const char *name, T TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + return StringToInt(&(config->*field), param); + }}; +} + +template +Flag IntVectorFlag(const char *name, std::vector TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + T value; + if (!StringToInt(&value, param)) { + return false; + } + (config->*field).push_back(value); + return true; + }}; +} + +Flag StringFlag(const char *name, std::string TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + config->*field = param; + return true; + }}; +} // TODO(davidben): When we can depend on C++17 or Abseil, switch this to // std::optional or absl::optional. -const Flag> kOptionalStringFlags[] = { - {"-expect-peer-application-settings", - &TestConfig::expect_peer_application_settings}, -}; - -const Flag kBase64Flags[] = { - {"-expect-ech-retry-configs", &TestConfig::expect_ech_retry_configs}, - {"-ech-config-list", &TestConfig::ech_config_list}, - {"-expect-certificate-types", &TestConfig::expect_certificate_types}, - {"-expect-channel-id", &TestConfig::expect_channel_id}, - {"-expect-ocsp-response", &TestConfig::expect_ocsp_response}, - {"-expect-signed-cert-timestamps", - &TestConfig::expect_signed_cert_timestamps}, - {"-ocsp-response", &TestConfig::ocsp_response}, - {"-signed-cert-timestamps", &TestConfig::signed_cert_timestamps}, - {"-ticket-key", &TestConfig::ticket_key}, - {"-quic-transport-params", &TestConfig::quic_transport_params}, - {"-expect-quic-transport-params", - &TestConfig::expect_quic_transport_params}, -}; - -const Flag kIntFlags[] = { - {"-port", &TestConfig::port}, - {"-resume-count", &TestConfig::resume_count}, - {"-min-version", &TestConfig::min_version}, - {"-max-version", &TestConfig::max_version}, - {"-expect-version", &TestConfig::expect_version}, - {"-mtu", &TestConfig::mtu}, - {"-export-keying-material", &TestConfig::export_keying_material}, - {"-expect-total-renegotiations", &TestConfig::expect_total_renegotiations}, - {"-expect-peer-signature-algorithm", - &TestConfig::expect_peer_signature_algorithm}, - {"-expect-curve-id", &TestConfig::expect_curve_id}, - {"-initial-timeout-duration-ms", &TestConfig::initial_timeout_duration_ms}, - {"-max-cert-list", &TestConfig::max_cert_list}, - {"-expect-cipher-aes", &TestConfig::expect_cipher_aes}, - {"-expect-cipher-no-aes", &TestConfig::expect_cipher_no_aes}, - {"-expect-cipher", &TestConfig::expect_cipher}, - {"-resumption-delay", &TestConfig::resumption_delay}, - {"-max-send-fragment", &TestConfig::max_send_fragment}, - {"-read-size", &TestConfig::read_size}, - {"-expect-ticket-age-skew", &TestConfig::expect_ticket_age_skew}, - {"-quic-use-legacy-codepoint", &TestConfig::quic_use_legacy_codepoint}, - {"-install-one-cert-compression-alg", - &TestConfig::install_one_cert_compression_alg}, - {"-early-write-after-message", &TestConfig::early_write_after_message}, -}; - -const Flag> kIntVectorFlags[] = { - {"-signing-prefs", &TestConfig::signing_prefs}, - {"-verify-prefs", &TestConfig::verify_prefs}, - {"-expect-peer-verify-pref", &TestConfig::expect_peer_verify_prefs}, - {"-curves", &TestConfig::curves}, - {"-ech-is-retry-config", &TestConfig::ech_is_retry_config}, -}; - -const Flag> kBase64VectorFlags[] = { - {"-ech-server-config", &TestConfig::ech_server_configs}, - {"-ech-server-key", &TestConfig::ech_server_keys}, -}; - -const Flag>> - kStringPairVectorFlags[] = { - {"-application-settings", &TestConfig::application_settings}, -}; +Flag OptionalStringFlag(const char *name, + std::unique_ptr TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + (config->*field).reset(new std::string(param)); + return true; + }}; +} bool DecodeBase64(std::string *out, const std::string &in) { size_t len; @@ -281,134 +143,271 @@ bool DecodeBase64(std::string *out, const std::string &in) { return true; } -bool ParseFlag(const char *flag, int argc, char **argv, int *i, - bool skip, TestConfig *out_config) { - bool *bool_field = FindField(out_config, kBoolFlags, flag); - if (bool_field != NULL) { - if (!skip) { - *bool_field = true; - } - return true; +Flag Base64Flag(const char *name, std::string TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + return DecodeBase64(&(config->*field), param); + }}; +} + +Flag Base64VectorFlag(const char *name, + std::vector TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + std::string value; + if (!DecodeBase64(&value, param)) { + return false; + } + (config->*field).push_back(std::move(value)); + return true; + }}; +} + +Flag StringPairVectorFlag( + const char *name, + std::vector> TestConfig::*field) { + return Flag{name, true, [=](TestConfig *config, const char *param) -> bool { + const char *comma = strchr(param, ','); + if (!comma) { + return false; + } + (config->*field) + .push_back(std::make_pair(std::string(param, comma - param), + std::string(comma + 1))); + return true; + }}; +} + +std::vector SortedFlags() { + std::vector flags = { + IntFlag("-port", &TestConfig::port), + BoolFlag("-server", &TestConfig::is_server), + BoolFlag("-dtls", &TestConfig::is_dtls), + BoolFlag("-quic", &TestConfig::is_quic), + IntFlag("-resume-count", &TestConfig::resume_count), + StringFlag("-write-settings", &TestConfig::write_settings), + BoolFlag("-fallback-scsv", &TestConfig::fallback_scsv), + IntVectorFlag("-signing-prefs", &TestConfig::signing_prefs), + IntVectorFlag("-verify-prefs", &TestConfig::verify_prefs), + IntVectorFlag("-expect-peer-verify-pref", + &TestConfig::expect_peer_verify_prefs), + IntVectorFlag("-curves", &TestConfig::curves), + StringFlag("-key-file", &TestConfig::key_file), + StringFlag("-cert-file", &TestConfig::cert_file), + StringFlag("-expect-server-name", &TestConfig::expect_server_name), + BoolFlag("-enable-ech-grease", &TestConfig::enable_ech_grease), + Base64VectorFlag("-ech-server-config", &TestConfig::ech_server_configs), + Base64VectorFlag("-ech-server-key", &TestConfig::ech_server_keys), + IntVectorFlag("-ech-is-retry-config", &TestConfig::ech_is_retry_config), + BoolFlag("-expect-ech-accept", &TestConfig::expect_ech_accept), + StringFlag("-expect-ech-name-override", + &TestConfig::expect_ech_name_override), + BoolFlag("-expect-no-ech-name-override", + &TestConfig::expect_no_ech_name_override), + Base64Flag("-expect-ech-retry-configs", + &TestConfig::expect_ech_retry_configs), + BoolFlag("-expect-no-ech-retry-configs", + &TestConfig::expect_no_ech_retry_configs), + Base64Flag("-ech-config-list", &TestConfig::ech_config_list), + Base64Flag("-expect-certificate-types", + &TestConfig::expect_certificate_types), + BoolFlag("-require-any-client-certificate", + &TestConfig::require_any_client_certificate), + StringFlag("-advertise-npn", &TestConfig::advertise_npn), + StringFlag("-expect-next-proto", &TestConfig::expect_next_proto), + BoolFlag("-false-start", &TestConfig::false_start), + StringFlag("-select-next-proto", &TestConfig::select_next_proto), + BoolFlag("-async", &TestConfig::async), + BoolFlag("-write-different-record-sizes", + &TestConfig::write_different_record_sizes), + BoolFlag("-cbc-record-splitting", &TestConfig::cbc_record_splitting), + BoolFlag("-partial-write", &TestConfig::partial_write), + BoolFlag("-no-tls13", &TestConfig::no_tls13), + BoolFlag("-no-tls12", &TestConfig::no_tls12), + BoolFlag("-no-tls11", &TestConfig::no_tls11), + BoolFlag("-no-tls1", &TestConfig::no_tls1), + BoolFlag("-no-ticket", &TestConfig::no_ticket), + Base64Flag("-expect-channel-id", &TestConfig::expect_channel_id), + BoolFlag("-enable-channel-id", &TestConfig::enable_channel_id), + StringFlag("-send-channel-id", &TestConfig::send_channel_id), + BoolFlag("-shim-writes-first", &TestConfig::shim_writes_first), + StringFlag("-host-name", &TestConfig::host_name), + StringFlag("-advertise-alpn", &TestConfig::advertise_alpn), + StringFlag("-expect-alpn", &TestConfig::expect_alpn), + StringFlag("-expect-late-alpn", &TestConfig::expect_late_alpn), + StringFlag("-expect-advertised-alpn", + &TestConfig::expect_advertised_alpn), + StringFlag("-select-alpn", &TestConfig::select_alpn), + BoolFlag("-decline-alpn", &TestConfig::decline_alpn), + BoolFlag("-reject-alpn", &TestConfig::reject_alpn), + BoolFlag("-select-empty-alpn", &TestConfig::select_empty_alpn), + BoolFlag("-defer-alps", &TestConfig::defer_alps), + StringPairVectorFlag("-application-settings", + &TestConfig::application_settings), + OptionalStringFlag("-expect-peer-application-settings", + &TestConfig::expect_peer_application_settings), + Base64Flag("-quic-transport-params", &TestConfig::quic_transport_params), + Base64Flag("-expect-quic-transport-params", + &TestConfig::expect_quic_transport_params), + IntFlag("-quic-use-legacy-codepoint", + &TestConfig::quic_use_legacy_codepoint), + BoolFlag("-expect-session-miss", &TestConfig::expect_session_miss), + BoolFlag("-expect-extended-master-secret", + &TestConfig::expect_extended_master_secret), + StringFlag("-psk", &TestConfig::psk), + StringFlag("-psk-identity", &TestConfig::psk_identity), + StringFlag("-srtp-profiles", &TestConfig::srtp_profiles), + BoolFlag("-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling), + BoolFlag("-enable-signed-cert-timestamps", + &TestConfig::enable_signed_cert_timestamps), + Base64Flag("-expect-signed-cert-timestamps", + &TestConfig::expect_signed_cert_timestamps), + IntFlag("-min-version", &TestConfig::min_version), + IntFlag("-max-version", &TestConfig::max_version), + IntFlag("-expect-version", &TestConfig::expect_version), + IntFlag("-mtu", &TestConfig::mtu), + BoolFlag("-implicit-handshake", &TestConfig::implicit_handshake), + BoolFlag("-use-early-callback", &TestConfig::use_early_callback), + BoolFlag("-fail-early-callback", &TestConfig::fail_early_callback), + BoolFlag("-install-ddos-callback", &TestConfig::install_ddos_callback), + BoolFlag("-fail-ddos-callback", &TestConfig::fail_ddos_callback), + BoolFlag("-fail-cert-callback", &TestConfig::fail_cert_callback), + StringFlag("-cipher", &TestConfig::cipher), + BoolFlag("-handshake-never-done", &TestConfig::handshake_never_done), + IntFlag("-export-keying-material", &TestConfig::export_keying_material), + StringFlag("-export-label", &TestConfig::export_label), + StringFlag("-export-context", &TestConfig::export_context), + BoolFlag("-use-export-context", &TestConfig::use_export_context), + BoolFlag("-tls-unique", &TestConfig::tls_unique), + BoolFlag("-expect-ticket-renewal", &TestConfig::expect_ticket_renewal), + BoolFlag("-expect-no-session", &TestConfig::expect_no_session), + BoolFlag("-expect-ticket-supports-early-data", + &TestConfig::expect_ticket_supports_early_data), + BoolFlag("-expect-accept-early-data", + &TestConfig::expect_accept_early_data), + BoolFlag("-expect-reject-early-data", + &TestConfig::expect_reject_early_data), + BoolFlag("-expect-no-offer-early-data", + &TestConfig::expect_no_offer_early_data), + BoolFlag("-use-ticket-callback", &TestConfig::use_ticket_callback), + BoolFlag("-renew-ticket", &TestConfig::renew_ticket), + BoolFlag("-enable-early-data", &TestConfig::enable_early_data), + Base64Flag("-ocsp-response", &TestConfig::ocsp_response), + Base64Flag("-expect-ocsp-response", &TestConfig::expect_ocsp_response), + BoolFlag("-check-close-notify", &TestConfig::check_close_notify), + BoolFlag("-shim-shuts-down", &TestConfig::shim_shuts_down), + BoolFlag("-verify-fail", &TestConfig::verify_fail), + BoolFlag("-verify-peer", &TestConfig::verify_peer), + BoolFlag("-verify-peer-if-no-obc", &TestConfig::verify_peer_if_no_obc), + BoolFlag("-expect-verify-result", &TestConfig::expect_verify_result), + Base64Flag("-signed-cert-timestamps", + &TestConfig::signed_cert_timestamps), + IntFlag("-expect-total-renegotiations", + &TestConfig::expect_total_renegotiations), + BoolFlag("-renegotiate-once", &TestConfig::renegotiate_once), + BoolFlag("-renegotiate-freely", &TestConfig::renegotiate_freely), + BoolFlag("-renegotiate-ignore", &TestConfig::renegotiate_ignore), + BoolFlag("-renegotiate-explicit", &TestConfig::renegotiate_explicit), + BoolFlag("-forbid-renegotiation-after-handshake", + &TestConfig::forbid_renegotiation_after_handshake), + IntFlag("-expect-peer-signature-algorithm", + &TestConfig::expect_peer_signature_algorithm), + IntFlag("-expect-curve-id", &TestConfig::expect_curve_id), + BoolFlag("-use-old-client-cert-callback", + &TestConfig::use_old_client_cert_callback), + IntFlag("-initial-timeout-duration-ms", + &TestConfig::initial_timeout_duration_ms), + StringFlag("-use-client-ca-list", &TestConfig::use_client_ca_list), + StringFlag("-expect-client-ca-list", &TestConfig::expect_client_ca_list), + BoolFlag("-send-alert", &TestConfig::send_alert), + BoolFlag("-peek-then-read", &TestConfig::peek_then_read), + BoolFlag("-enable-grease", &TestConfig::enable_grease), + BoolFlag("-permute-extensions", &TestConfig::permute_extensions), + IntFlag("-max-cert-list", &TestConfig::max_cert_list), + Base64Flag("-ticket-key", &TestConfig::ticket_key), + BoolFlag("-use-exporter-between-reads", + &TestConfig::use_exporter_between_reads), + IntFlag("-expect-cipher-aes", &TestConfig::expect_cipher_aes), + IntFlag("-expect-cipher-no-aes", &TestConfig::expect_cipher_no_aes), + IntFlag("-expect-cipher", &TestConfig::expect_cipher), + StringFlag("-expect-peer-cert-file", &TestConfig::expect_peer_cert_file), + IntFlag("-resumption-delay", &TestConfig::resumption_delay), + BoolFlag("-retain-only-sha256-client-cert", + &TestConfig::retain_only_sha256_client_cert), + BoolFlag("-expect-sha256-client-cert", + &TestConfig::expect_sha256_client_cert), + BoolFlag("-read-with-unfinished-write", + &TestConfig::read_with_unfinished_write), + BoolFlag("-expect-secure-renegotiation", + &TestConfig::expect_secure_renegotiation), + BoolFlag("-expect-no-secure-renegotiation", + &TestConfig::expect_no_secure_renegotiation), + IntFlag("-max-send-fragment", &TestConfig::max_send_fragment), + IntFlag("-read-size", &TestConfig::read_size), + BoolFlag("-expect-session-id", &TestConfig::expect_session_id), + BoolFlag("-expect-no-session-id", &TestConfig::expect_no_session_id), + IntFlag("-expect-ticket-age-skew", &TestConfig::expect_ticket_age_skew), + BoolFlag("-no-op-extra-handshake", &TestConfig::no_op_extra_handshake), + BoolFlag("-handshake-twice", &TestConfig::handshake_twice), + BoolFlag("-allow-unknown-alpn-protos", + &TestConfig::allow_unknown_alpn_protos), + BoolFlag("-use-custom-verify-callback", + &TestConfig::use_custom_verify_callback), + StringFlag("-expect-msg-callback", &TestConfig::expect_msg_callback), + BoolFlag("-allow-false-start-without-alpn", + &TestConfig::allow_false_start_without_alpn), + BoolFlag("-handoff", &TestConfig::handoff), + BoolFlag("-handshake-hints", &TestConfig::handshake_hints), + BoolFlag("-allow-hint-mismatch", &TestConfig::allow_hint_mismatch), + BoolFlag("-use-ocsp-callback", &TestConfig::use_ocsp_callback), + BoolFlag("-set-ocsp-in-callback", &TestConfig::set_ocsp_in_callback), + BoolFlag("-decline-ocsp-callback", &TestConfig::decline_ocsp_callback), + BoolFlag("-fail-ocsp-callback", &TestConfig::fail_ocsp_callback), + BoolFlag("-install-cert-compression-algs", + &TestConfig::install_cert_compression_algs), + IntFlag("-install-one-cert-compression-alg", + &TestConfig::install_one_cert_compression_alg), + BoolFlag("-reverify-on-resume", &TestConfig::reverify_on_resume), + BoolFlag("-ignore-rsa-key-usage", &TestConfig::ignore_rsa_key_usage), + BoolFlag("-expect-key-usage-invalid", + &TestConfig::expect_key_usage_invalid), + BoolFlag("-is-handshaker-supported", + &TestConfig::is_handshaker_supported), + BoolFlag("-handshaker-resume", &TestConfig::handshaker_resume), + StringFlag("-handshaker-path", &TestConfig::handshaker_path), + BoolFlag("-jdk11-workaround", &TestConfig::jdk11_workaround), + BoolFlag("-server-preference", &TestConfig::server_preference), + BoolFlag("-export-traffic-secrets", &TestConfig::export_traffic_secrets), + BoolFlag("-key-update", &TestConfig::key_update), + BoolFlag("-expect-delegated-credential-used", + &TestConfig::expect_delegated_credential_used), + StringFlag("-delegated-credential", &TestConfig::delegated_credential), + StringFlag("-expect-early-data-reason", + &TestConfig::expect_early_data_reason), + BoolFlag("-expect-hrr", &TestConfig::expect_hrr), + BoolFlag("-expect-no-hrr", &TestConfig::expect_no_hrr), + BoolFlag("-wait-for-debugger", &TestConfig::wait_for_debugger), + StringFlag("-quic-early-data-context", + &TestConfig::quic_early_data_context), + IntFlag("-early-write-after-message", + &TestConfig::early_write_after_message), + BoolFlag("-fips-202205", &TestConfig::fips_202205), + BoolFlag("-wpa-202304", &TestConfig::wpa_202304), + }; + std::sort(flags.begin(), flags.end(), [](const Flag &a, const Flag &b) { + return strcmp(a.name, b.name) < 0; + }); + return flags; +} + +const Flag *FindFlag(const char *name) { + static const std::vector kSortedFlags = SortedFlags(); + auto iter = std::lower_bound(kSortedFlags.begin(), kSortedFlags.end(), name, + [](const Flag &flag, const char *key) { + return strcmp(flag.name, key) < 0; + }); + if (iter == kSortedFlags.end() || strcmp(iter->name, name) != 0) { + return nullptr; } - - std::string *string_field = FindField(out_config, kStringFlags, flag); - if (string_field != NULL) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - if (!skip) { - string_field->assign(argv[*i]); - } - return true; - } - - std::unique_ptr *optional_string_field = - FindField(out_config, kOptionalStringFlags, flag); - if (optional_string_field != NULL) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - if (!skip) { - optional_string_field->reset(new std::string(argv[*i])); - } - return true; - } - - std::string *base64_field = FindField(out_config, kBase64Flags, flag); - if (base64_field != NULL) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - std::string value; - if (!DecodeBase64(&value, argv[*i])) { - return false; - } - if (!skip) { - *base64_field = std::move(value); - } - return true; - } - - int *int_field = FindField(out_config, kIntFlags, flag); - if (int_field) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - if (!skip) { - *int_field = atoi(argv[*i]); - } - return true; - } - - std::vector *int_vector_field = - FindField(out_config, kIntVectorFlags, flag); - if (int_vector_field) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - - // Each instance of the flag adds to the list. - if (!skip) { - int_vector_field->push_back(atoi(argv[*i])); - } - return true; - } - - std::vector *base64_vector_field = - FindField(out_config, kBase64VectorFlags, flag); - if (base64_vector_field) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - std::string value; - if (!DecodeBase64(&value, argv[*i])) { - return false; - } - // Each instance of the flag adds to the list. - if (!skip) { - base64_vector_field->push_back(std::move(value)); - } - return true; - } - - std::vector> *string_pair_vector_field = - FindField(out_config, kStringPairVectorFlags, flag); - if (string_pair_vector_field) { - *i = *i + 1; - if (*i >= argc) { - fprintf(stderr, "Missing parameter.\n"); - return false; - } - const char *comma = strchr(argv[*i], ','); - if (!comma) { - fprintf( - stderr, - "Parameter should be a comma-separated triple composed of two base64 " - "strings followed by \"true\" or \"false\".\n"); - return false; - } - // Each instance of the flag adds to the list. - if (!skip) { - string_pair_vector_field->push_back(std::make_pair( - std::string(argv[*i], comma - argv[*i]), std::string(comma + 1))); - } - return true; - } - - fprintf(stderr, "Unknown argument: %s.\n", flag); - return false; + return &*iter; } // RemovePrefix checks if |*str| begins with |prefix| + "-". If so, it advances @@ -433,15 +432,15 @@ bool ParseConfig(int argc, char **argv, bool is_shim, out_initial->argv = out_resume->argv = out_retry->argv = argv; for (int i = 0; i < argc; i++) { bool skip = false; - const char *flag = argv[i]; + const char *name = argv[i]; // -on-shim and -on-handshaker prefixes enable flags only on the shim or // handshaker. - if (RemovePrefix(&flag, "-on-shim")) { + if (RemovePrefix(&name, "-on-shim")) { if (!is_shim) { skip = true; } - } else if (RemovePrefix(&flag, "-on-handshaker")) { + } else if (RemovePrefix(&name, "-on-handshaker")) { if (is_shim) { skip = true; } @@ -449,26 +448,45 @@ bool ParseConfig(int argc, char **argv, bool is_shim, // The following prefixes allow different configurations for each of the // initial, resumption, and 0-RTT retry handshakes. - if (RemovePrefix(&flag, "-on-initial")) { - if (!ParseFlag(flag, argc, argv, &i, skip, out_initial)) { + TestConfig *out = nullptr; + if (RemovePrefix(&name, "-on-initial")) { + out = out_initial; + } else if (RemovePrefix(&name, "-on-resume")) { + out = out_resume; + } else if (RemovePrefix(&name, "-on-retry")) { + out = out_retry; + } + + const Flag *flag = FindFlag(name); + if (flag == nullptr) { + fprintf(stderr, "Unrecognized flag: %s\n", name); + return false; + } + + const char *param = nullptr; + if (flag->has_param) { + if (i >= argc) { + fprintf(stderr, "Missing parameter for %s\n", name); return false; } - } else if (RemovePrefix(&flag, "-on-resume")) { - if (!ParseFlag(flag, argc, argv, &i, skip, out_resume)) { - return false; - } - } else if (RemovePrefix(&flag, "-on-retry")) { - if (!ParseFlag(flag, argc, argv, &i, skip, out_retry)) { - return false; - } - } else { - // Unprefixed flags apply to all three. - int i_init = i; - int i_resume = i; - if (!ParseFlag(flag, argc, argv, &i_init, skip, out_initial) || - !ParseFlag(flag, argc, argv, &i_resume, skip, out_resume) || - !ParseFlag(flag, argc, argv, &i, skip, out_retry)) { - return false; + i++; + param = argv[i]; + } + + if (!skip) { + if (out != nullptr) { + if (!flag->set_param(out, param)) { + fprintf(stderr, "Invalid parameter for %s: %s\n", name, param); + return false; + } + } else { + // Unprefixed flags apply to all three. + if (!flag->set_param(out_initial, param) || + !flag->set_param(out_resume, param) || + !flag->set_param(out_retry, param)) { + fprintf(stderr, "Invalid parameter for %s: %s\n", name, param); + return false; + } } } } @@ -480,25 +498,26 @@ static CRYPTO_once_t once = CRYPTO_ONCE_INIT; static int g_config_index = 0; static CRYPTO_BUFFER_POOL *g_pool = nullptr; -static void init_once() { - g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); - if (g_config_index < 0) { - abort(); - } - g_pool = CRYPTO_BUFFER_POOL_new(); - if (!g_pool) { - abort(); - } +static bool InitGlobals() { + CRYPTO_once(&once, [] { + g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); + g_pool = CRYPTO_BUFFER_POOL_new(); + }); + return g_config_index >= 0 && g_pool != nullptr; } bool SetTestConfig(SSL *ssl, const TestConfig *config) { - CRYPTO_once(&once, init_once); + if (!InitGlobals()) { + return false; + } return SSL_set_ex_data(ssl, g_config_index, (void *)config) == 1; } const TestConfig *GetTestConfig(const SSL *ssl) { - CRYPTO_once(&once, init_once); - return (const TestConfig *)SSL_get_ex_data(ssl, g_config_index); + if (!InitGlobals()) { + return nullptr; + } + return static_cast(SSL_get_ex_data(ssl, g_config_index)); } static int LegacyOCSPCallback(SSL *ssl, void *arg) { @@ -555,8 +574,13 @@ static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out, return SSL_TLSEXT_ERR_NOACK; } - *out = (const uint8_t *)config->advertise_npn.data(); - *out_len = config->advertise_npn.size(); + if (config->advertise_npn.size() > UINT_MAX) { + fprintf(stderr, "NPN value too large.\n"); + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + + *out = reinterpret_cast(config->advertise_npn.data()); + *out_len = static_cast(config->advertise_npn.size()); return SSL_TLSEXT_ERR_OK; } @@ -570,8 +594,9 @@ static void MessageCallback(int is_write, int version, int content_type, } if (content_type == SSL3_RT_HEADER) { - if (len != - (config->is_dtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH)) { + size_t header_len = + config->is_dtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH; + if (len != header_len) { fprintf(stderr, "Incorrect length for record header: %zu.\n", len); state->msg_callback_ok = false; } @@ -582,13 +607,15 @@ static void MessageCallback(int is_write, int version, int content_type, switch (content_type) { case 0: if (version != SSL2_VERSION) { - fprintf(stderr, "Incorrect version for V2ClientHello: %x.\n", version); + fprintf(stderr, "Incorrect version for V2ClientHello: %x.\n", + static_cast(version)); state->msg_callback_ok = false; return; } state->msg_callback_text += "v2clienthello\n"; return; + case SSL3_RT_CLIENT_HELLO_INNER: case SSL3_RT_HANDSHAKE: { CBS cbs; CBS_init(&cbs, buf_u8, len); @@ -606,10 +633,19 @@ static void MessageCallback(int is_write, int version, int content_type, return; } char text[16]; - snprintf(text, sizeof(text), "hs %d\n", type); - state->msg_callback_text += text; - if (!is_write) { - state->last_message_received = type; + if (content_type == SSL3_RT_CLIENT_HELLO_INNER) { + if (type != SSL3_MT_CLIENT_HELLO) { + fprintf(stderr, "Invalid header for ClientHelloInner.\n"); + state->msg_callback_ok = false; + return; + } + state->msg_callback_text += "clienthelloinner\n"; + } else { + snprintf(text, sizeof(text), "hs %d\n", type); + state->msg_callback_text += text; + if (!is_write) { + state->last_message_received = type; + } } return; } @@ -873,9 +909,8 @@ static bool GetCertificate(SSL *ssl, bssl::UniquePtr *out_x509, const TestConfig *config = GetTestConfig(ssl); if (!config->signing_prefs.empty()) { - std::vector u16s(config->signing_prefs.begin(), - config->signing_prefs.end()); - if (!SSL_set_signing_algorithm_prefs(ssl, u16s.data(), u16s.size())) { + if (!SSL_set_signing_algorithm_prefs(ssl, config->signing_prefs.data(), + config->signing_prefs.size())) { return false; } } @@ -898,22 +933,6 @@ static bool GetCertificate(SSL *ssl, bssl::UniquePtr *out_x509, return true; } -static bool FromHexDigit(uint8_t *out, char c) { - if ('0' <= c && c <= '9') { - *out = c - '0'; - return true; - } - if ('a' <= c && c <= 'f') { - *out = c - 'a' + 10; - return true; - } - if ('A' <= c && c <= 'F') { - *out = c - 'A' + 10; - return true; - } - return false; -} - static bool HexDecode(std::string *out, const std::string &in) { if ((in.size() & 1) != 0) { return false; @@ -922,7 +941,8 @@ static bool HexDecode(std::string *out, const std::string &in) { std::unique_ptr buf(new uint8_t[in.size() / 2]); for (size_t i = 0; i < in.size() / 2; i++) { uint8_t high, low; - if (!FromHexDigit(&high, in[i * 2]) || !FromHexDigit(&low, in[i * 2 + 1])) { + if (!OPENSSL_fromxdigit(&high, in[i * 2]) || + !OPENSSL_fromxdigit(&low, in[i * 2 + 1])) { return false; } buf[i] = (high << 4) | low; @@ -1006,8 +1026,7 @@ static bool CheckPeerVerifyPrefs(SSL *ssl) { return false; } for (size_t i = 0; i < num_peer_sigalgs; i++) { - if (static_cast(peer_sigalgs[i]) != - config->expect_peer_verify_prefs[i]) { + if (peer_sigalgs[i] != config->expect_peer_verify_prefs[i]) { fprintf(stderr, "peer verify preference %zu mismatch (got %04x, wanted %04x\n", i, peer_sigalgs[i], config->expect_peer_verify_prefs[i]); @@ -1047,17 +1066,16 @@ static bool CheckCertificateRequest(SSL *ssl) { const size_t num_received = sk_X509_NAME_num(received); if (num_received != num_expected) { - fprintf(stderr, "expected %u names in CertificateRequest but got %u.\n", - static_cast(num_expected), - static_cast(num_received)); + fprintf(stderr, "expected %zu names in CertificateRequest but got %zu.\n", + num_expected, num_received); return false; } for (size_t i = 0; i < num_received; i++) { if (X509_NAME_cmp(sk_X509_NAME_value(received, i), sk_X509_NAME_value(expected.get(), i)) != 0) { - fprintf(stderr, "names in CertificateRequest differ at index #%d.\n", - static_cast(i)); + fprintf(stderr, "names in CertificateRequest differ at index #%zu.\n", + i); return false; } } @@ -1361,16 +1379,19 @@ static bool MaybeInstallCertCompressionAlg( } bssl::UniquePtr TestConfig::SetupCtx(SSL_CTX *old_ctx) const { + if (!InitGlobals()) { + return nullptr; + } + bssl::UniquePtr ssl_ctx( SSL_CTX_new(is_dtls ? DTLS_method() : TLS_method())); if (!ssl_ctx) { return nullptr; } - CRYPTO_once(&once, init_once); SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool); - std::string cipher_list = "ALL"; + std::string cipher_list = "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; if (!cipher.empty()) { cipher_list = cipher; SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE); @@ -1464,9 +1485,8 @@ bssl::UniquePtr TestConfig::SetupCtx(SSL_CTX *old_ctx) const { } if (!verify_prefs.empty()) { - std::vector u16s(verify_prefs.begin(), verify_prefs.end()); - if (!SSL_CTX_set_verify_algorithm_prefs(ssl_ctx.get(), u16s.data(), - u16s.size())) { + if (!SSL_CTX_set_verify_algorithm_prefs(ssl_ctx.get(), verify_prefs.data(), + verify_prefs.size())) { return nullptr; } } @@ -1598,7 +1618,7 @@ static unsigned PskClientCallback(SSL *ssl, const char *hint, OPENSSL_strlcpy(out_identity, config->psk_identity.c_str(), max_identity_len); OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size()); - return config->psk.size(); + return static_cast(config->psk.size()); } static unsigned PskServerCallback(SSL *ssl, const char *identity, @@ -1616,7 +1636,7 @@ static unsigned PskServerCallback(SSL *ssl, const char *identity, } OPENSSL_memcpy(out_psk, config->psk.data(), config->psk.size()); - return config->psk.size(); + return static_cast(config->psk.size()); } static ssl_verify_result_t CustomVerifyCallback(SSL *ssl, uint8_t *out_alert) { @@ -1722,8 +1742,8 @@ bssl::UniquePtr TestConfig::NewSSL( if (reverify_on_resume) { SSL_CTX_set_reverify_on_resume(ssl_ctx, 1); } - if (enforce_rsa_key_usage) { - SSL_set_enforce_rsa_key_usage(ssl.get(), 1); + if (ignore_rsa_key_usage) { + SSL_set_enforce_rsa_key_usage(ssl.get(), 0); } if (no_tls13) { SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_3); @@ -1746,6 +1766,20 @@ bssl::UniquePtr TestConfig::NewSSL( if (enable_ech_grease) { SSL_set_enable_ech_grease(ssl.get(), 1); } + if (static_cast(fips_202205) + static_cast(wpa_202304) > 1) { + fprintf(stderr, "Multiple policy options given\n"); + return nullptr; + } + if (fips_202205 && !SSL_set_compliance_policy( + ssl.get(), ssl_compliance_policy_fips_202205)) { + fprintf(stderr, "SSL_set_compliance_policy failed\n"); + return nullptr; + } + if (wpa_202304 && !SSL_set_compliance_policy( + ssl.get(), ssl_compliance_policy_wpa3_192_202304)) { + fprintf(stderr, "SSL_set_compliance_policy failed\n"); + return nullptr; + } if (!ech_config_list.empty() && !SSL_set1_ech_config_list( ssl.get(), reinterpret_cast(ech_config_list.data()), @@ -1830,11 +1864,11 @@ bssl::UniquePtr TestConfig::NewSSL( SSL_enable_signed_cert_timestamps(ssl.get()); } if (min_version != 0 && - !SSL_set_min_proto_version(ssl.get(), (uint16_t)min_version)) { + !SSL_set_min_proto_version(ssl.get(), min_version)) { return nullptr; } if (max_version != 0 && - !SSL_set_max_proto_version(ssl.get(), (uint16_t)max_version)) { + !SSL_set_max_proto_version(ssl.get(), max_version)) { return nullptr; } if (mtu != 0) { @@ -1861,38 +1895,9 @@ bssl::UniquePtr TestConfig::NewSSL( if (!check_close_notify) { SSL_set_quiet_shutdown(ssl.get(), 1); } - if (!curves.empty()) { - std::vector nids; - for (auto curve : curves) { - switch (curve) { - case SSL_CURVE_SECP224R1: - nids.push_back(NID_secp224r1); - break; - - case SSL_CURVE_SECP256R1: - nids.push_back(NID_X9_62_prime256v1); - break; - - case SSL_CURVE_SECP384R1: - nids.push_back(NID_secp384r1); - break; - - case SSL_CURVE_SECP521R1: - nids.push_back(NID_secp521r1); - break; - - case SSL_CURVE_X25519: - nids.push_back(NID_X25519); - break; - - case SSL_CURVE_CECPQ2: - nids.push_back(NID_CECPQ2); - break; - } - if (!SSL_set1_curves(ssl.get(), &nids[0], nids.size())) { - return nullptr; - } - } + if (!curves.empty() && + !SSL_set1_group_ids(ssl.get(), curves.data(), curves.size())) { + return nullptr; } if (initial_timeout_duration_ms > 0) { DTLSv1_set_initial_timeout_duration(ssl.get(), initial_timeout_duration_ms); diff --git a/third_party/boringssl/kit/src/ssl/test/test_config.h b/third_party/boringssl/kit/src/ssl/test/test_config.h index c9f2a254..e5c60579 100644 --- a/third_party/boringssl/kit/src/ssl/test/test_config.h +++ b/third_party/boringssl/kit/src/ssl/test/test_config.h @@ -32,10 +32,10 @@ struct TestConfig { int resume_count = 0; std::string write_settings; bool fallback_scsv = false; - std::vector signing_prefs; - std::vector verify_prefs; - std::vector expect_peer_verify_prefs; - std::vector curves; + std::vector signing_prefs; + std::vector verify_prefs; + std::vector expect_peer_verify_prefs; + std::vector curves; std::string key_file; std::string cert_file; std::string expect_server_name; @@ -93,9 +93,9 @@ struct TestConfig { std::string expect_ocsp_response; bool enable_signed_cert_timestamps = false; std::string expect_signed_cert_timestamps; - int min_version = 0; - int max_version = 0; - int expect_version = 0; + uint16_t min_version = 0; + uint16_t max_version = 0; + uint16_t expect_version = 0; int mtu = 0; bool implicit_handshake = false; bool use_early_callback = false; @@ -119,10 +119,6 @@ struct TestConfig { bool use_ticket_callback = false; bool renew_ticket = false; bool enable_early_data = false; - bool enable_client_custom_extension = false; - bool enable_server_custom_extension = false; - bool custom_extension_skip = false; - bool custom_extension_fail_add = false; std::string ocsp_response; bool check_close_notify = false; bool shim_shuts_down = false; @@ -137,8 +133,8 @@ struct TestConfig { bool renegotiate_ignore = false; bool renegotiate_explicit = false; bool forbid_renegotiation_after_handshake = false; - int expect_peer_signature_algorithm = 0; - int expect_curve_id = 0; + uint16_t expect_peer_signature_algorithm = 0; + uint16_t expect_curve_id = 0; bool use_old_client_cert_callback = false; int initial_timeout_duration_ms = 0; std::string use_client_ca_list; @@ -150,9 +146,9 @@ struct TestConfig { int max_cert_list = 0; std::string ticket_key; bool use_exporter_between_reads = false; - int expect_cipher_aes = 0; - int expect_cipher_no_aes = 0; - int expect_cipher = 0; + uint16_t expect_cipher_aes = 0; + uint16_t expect_cipher_no_aes = 0; + uint16_t expect_cipher = 0; std::string expect_peer_cert_file; int resumption_delay = 0; bool retain_only_sha256_client_cert = false; @@ -181,7 +177,8 @@ struct TestConfig { bool install_cert_compression_algs = false; int install_one_cert_compression_alg = 0; bool reverify_on_resume = false; - bool enforce_rsa_key_usage = false; + bool ignore_rsa_key_usage = false; + bool expect_key_usage_invalid = false; bool is_handshaker_supported = false; bool handshaker_resume = false; std::string handshaker_path; @@ -197,6 +194,8 @@ struct TestConfig { bool wait_for_debugger = false; std::string quic_early_data_context; int early_write_after_message = 0; + bool fips_202205 = false; + bool wpa_202304 = false; int argc; char **argv; diff --git a/third_party/boringssl/kit/src/ssl/test/test_state.cc b/third_party/boringssl/kit/src/ssl/test/test_state.cc index 86deb555..7c22a620 100644 --- a/third_party/boringssl/kit/src/ssl/test/test_state.cc +++ b/third_party/boringssl/kit/src/ssl/test/test_state.cc @@ -32,25 +32,26 @@ static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, delete ((TestState *)ptr); } -static void init_once() { - g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree); - if (g_state_index < 0) { - abort(); - } +static bool InitGlobals() { + CRYPTO_once(&g_once, [] { + g_state_index = + SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, TestStateExFree); + }); + return g_state_index >= 0; } struct timeval *GetClock() { - CRYPTO_once(&g_once, init_once); return &g_clock; } void AdvanceClock(unsigned seconds) { - CRYPTO_once(&g_once, init_once); g_clock.tv_sec += seconds; } bool SetTestState(SSL *ssl, std::unique_ptr state) { - CRYPTO_once(&g_once, init_once); + if (!InitGlobals()) { + return false; + } // |SSL_set_ex_data| takes ownership of |state| only on success. if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) { state.release(); @@ -60,8 +61,10 @@ bool SetTestState(SSL *ssl, std::unique_ptr state) { } TestState *GetTestState(const SSL *ssl) { - CRYPTO_once(&g_once, init_once); - return (TestState *)SSL_get_ex_data(ssl, g_state_index); + if (!InitGlobals()) { + return nullptr; + } + return static_cast(SSL_get_ex_data(ssl, g_state_index)); } static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) { diff --git a/third_party/boringssl/kit/src/ssl/tls13_both.cc b/third_party/boringssl/kit/src/ssl/tls13_both.cc index 226c67b8..5ab5a1c9 100644 --- a/third_party/boringssl/kit/src/ssl/tls13_both.cc +++ b/third_party/boringssl/kit/src/ssl/tls13_both.cc @@ -58,13 +58,11 @@ bool tls13_get_cert_verify_signature_input( enum ssl_cert_verify_context_t cert_verify_context) { ScopedCBB cbb; if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(cbb.get(), 0x20)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } } @@ -80,7 +78,6 @@ bool tls13_get_cert_verify_signature_input( static const char kContext[] = "TLS 1.3, Channel ID"; context = kContext; } else { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -88,7 +85,6 @@ bool tls13_get_cert_verify_signature_input( if (!CBB_add_bytes(cbb.get(), reinterpret_cast(context.data()), context.size())) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -97,7 +93,6 @@ bool tls13_get_cert_verify_signature_input( if (!hs->transcript.GetHash(context_hash, &context_hash_len) || !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || !CBBFinishArray(cbb.get(), out)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -186,7 +181,6 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, UniquePtr certs(sk_CRYPTO_BUFFER_new_null()); if (!certs) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -230,7 +224,6 @@ bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, if (!buf || !PushToStack(certs.get(), std::move(buf))) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return false; } @@ -475,7 +468,7 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) { CRYPTO_BUFFER_len(raw)) || !CBB_flush(&extensions)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; + return false; } ssl->s3->delegated_credential_used = true; } @@ -520,7 +513,8 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) { if (!ssl->method->init_message(ssl, cbb.get(), body, SSL3_MT_COMPRESSED_CERTIFICATE) || !CBB_add_u16(body, hs->cert_compression_alg_id) || - !CBB_add_u24(body, msg.size()) || + msg.size() > (1u << 24) - 1 || // + !CBB_add_u24(body, static_cast(msg.size())) || !CBB_add_u24_length_prefixed(body, &compressed)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return false; @@ -576,7 +570,6 @@ enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) { return ssl_private_key_failure; } - // Sign the digest. CBB child; const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); uint8_t *sig; @@ -595,40 +588,10 @@ enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) { return ssl_private_key_failure; } - SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); - Array spki; - if (hints) { - ScopedCBB spki_cbb; - if (!CBB_init(spki_cbb.get(), 64) || - !EVP_marshal_public_key(spki_cbb.get(), hs->local_pubkey.get()) || - !CBBFinishArray(spki_cbb.get(), &spki)) { - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return ssl_private_key_failure; - } - } - - if (hints && !hs->hints_requested && - signature_algorithm == hints->signature_algorithm && - MakeConstSpan(msg) == hints->signature_input && - MakeConstSpan(spki) == hints->signature_spki && - !hints->signature.empty() && hints->signature.size() <= max_sig_len) { - // Signature algorithm and input both match. Reuse the signature from hints. - sig_len = hints->signature.size(); - OPENSSL_memcpy(sig, hints->signature.data(), sig_len); - } else { - enum ssl_private_key_result_t sign_result = ssl_private_key_sign( - hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); - if (sign_result != ssl_private_key_success) { - return sign_result; - } - if (hints && hs->hints_requested) { - hints->signature_algorithm = signature_algorithm; - hints->signature_input = std::move(msg); - hints->signature_spki = std::move(spki); - if (!hints->signature.CopyFrom(MakeSpan(sig, sig_len))) { - return ssl_private_key_failure; - } - } + enum ssl_private_key_result_t sign_result = ssl_private_key_sign( + hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); + if (sign_result != ssl_private_key_success) { + return sign_result; } if (!CBB_did_write(&child, sig_len) || diff --git a/third_party/boringssl/kit/src/ssl/tls13_client.cc b/third_party/boringssl/kit/src/ssl/tls13_client.cc index af2120c3..7f84241b 100644 --- a/third_party/boringssl/kit/src/ssl/tls13_client.cc +++ b/third_party/boringssl/kit/src/ssl/tls13_client.cc @@ -192,11 +192,14 @@ static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { } // The cipher suite must be one we offered. We currently offer all supported - // TLS 1.3 ciphers, so check the version. + // TLS 1.3 ciphers unless policy controls limited it. So we check the version + // and that it's ok per policy. const SSL_CIPHER *cipher = SSL_get_cipher_by_value(server_hello.cipher_suite); if (cipher == nullptr || SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || - SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) || + !ssl_tls13_cipher_meets_policy(SSL_CIPHER_get_protocol_id(cipher), + ssl->config->tls13_cipher_policy)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return ssl_hs_error; @@ -372,7 +375,7 @@ static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { } // Check the cipher suite, in case this is after HelloRetryRequest. - if (SSL_CIPHER_get_value(hs->new_cipher) != server_hello.cipher_suite) { + if (SSL_CIPHER_get_protocol_id(hs->new_cipher) != server_hello.cipher_suite) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return ssl_hs_error; @@ -667,7 +670,6 @@ static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { } else { hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); if (!hs->ca_names) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } diff --git a/third_party/boringssl/kit/src/ssl/tls13_enc.cc b/third_party/boringssl/kit/src/ssl/tls13_enc.cc index c7b75a6d..3de10f48 100644 --- a/third_party/boringssl/kit/src/ssl/tls13_enc.cc +++ b/third_party/boringssl/kit/src/ssl/tls13_enc.cc @@ -27,6 +27,7 @@ #include #include +#include "../crypto/fipsmodule/tls/internal.h" #include "../crypto/internal.h" #include "internal.h" @@ -95,27 +96,10 @@ static bool hkdf_expand_label(Span out, const EVP_MD *digest, Span secret, Span label, Span hash) { - Span protocol_label = label_to_span("tls13 "); - ScopedCBB cbb; - CBB child; - Array hkdf_label; - if (!CBB_init(cbb.get(), 2 + 1 + protocol_label.size() + label.size() + 1 + - hash.size()) || - !CBB_add_u16(cbb.get(), out.size()) || - !CBB_add_u8_length_prefixed(cbb.get(), &child) || - !CBB_add_bytes(&child, - reinterpret_cast(protocol_label.data()), - protocol_label.size()) || - !CBB_add_bytes(&child, reinterpret_cast(label.data()), - label.size()) || - !CBB_add_u8_length_prefixed(cbb.get(), &child) || - !CBB_add_bytes(&child, hash.data(), hash.size()) || - !CBBFinishArray(cbb.get(), &hkdf_label)) { - return false; - } - - return HKDF_expand(out.data(), out.size(), digest, secret.data(), - secret.size(), hkdf_label.data(), hkdf_label.size()); + return CRYPTO_tls13_hkdf_expand_label( + out.data(), out.size(), digest, secret.data(), secret.size(), + reinterpret_cast(label.data()), label.size(), + hash.data(), hash.size()) == 1; } static const char kTLS13LabelDerived[] = "derived"; @@ -364,9 +348,9 @@ bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, !tls13_verify_data(out, out_len, hs->transcript.Digest(), hs->ssl->version, traffic_secret, MakeConstSpan(context_hash, context_hash_len))) { - return 0; + return false; } - return 1; + return true; } static const char kTLS13LabelResumptionPSK[] = "resumption"; diff --git a/third_party/boringssl/kit/src/ssl/tls13_server.cc b/third_party/boringssl/kit/src/ssl/tls13_server.cc index 2f000e55..9d26f4e0 100644 --- a/third_party/boringssl/kit/src/ssl/tls13_server.cc +++ b/third_party/boringssl/kit/src/ssl/tls13_server.cc @@ -66,25 +66,25 @@ static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs, SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); if (hints && !hs->hints_requested && hints->key_share_group_id == group_id && !hints->key_share_secret.empty()) { - // Copy DH secret from hints. - if (!hs->ecdh_public_key.CopyFrom(hints->key_share_public_key) || + // Copy the key_share secret from hints. + if (!hs->key_share_ciphertext.CopyFrom(hints->key_share_ciphertext) || !secret.CopyFrom(hints->key_share_secret)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return false; } } else { - ScopedCBB public_key; + ScopedCBB ciphertext; UniquePtr key_share = SSLKeyShare::Create(group_id); if (!key_share || // - !CBB_init(public_key.get(), 32) || - !key_share->Accept(public_key.get(), &secret, &alert, peer_key) || - !CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) { + !CBB_init(ciphertext.get(), 32) || + !key_share->Encap(ciphertext.get(), &secret, &alert, peer_key) || + !CBBFinishArray(ciphertext.get(), &hs->key_share_ciphertext)) { ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return false; } if (hints && hs->hints_requested) { hints->key_share_group_id = group_id; - if (!hints->key_share_public_key.CopyFrom(hs->ecdh_public_key) || + if (!hints->key_share_ciphertext.CopyFrom(hs->key_share_ciphertext) || !hints->key_share_secret.CopyFrom(secret)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return false; @@ -116,7 +116,11 @@ static const SSL_CIPHER *choose_tls13_cipher( const uint16_t version = ssl_protocol_version(ssl); - return ssl_choose_tls13_cipher(cipher_suites, version, group_id); + return ssl_choose_tls13_cipher( + cipher_suites, + ssl->config->aes_hw_override ? ssl->config->aes_hw_override_value + : EVP_has_aes_hardware(), + version, group_id, ssl->config->tls13_cipher_policy); } static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) { @@ -131,15 +135,12 @@ static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) { return true; } - // TLS 1.3 recommends single-use tickets, so issue multiple tickets in case - // the client makes several connections before getting a renewal. - static const int kNumTickets = 2; - // Rebase the session timestamp so that it is measured from ticket // issuance. ssl_session_rebase_time(ssl, hs->new_session.get()); - for (int i = 0; i < kNumTickets; i++) { + assert(ssl->session_ctx->num_tickets <= kMaxTickets); + for (size_t i = 0; i < ssl->session_ctx->num_tickets; i++) { UniquePtr session( SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH)); if (!session) { @@ -160,7 +161,8 @@ static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) { ssl->quic_method != nullptr ? 0xffffffff : kMaxEarlyDataAccepted; } - static_assert(kNumTickets < 256, "Too many tickets"); + static_assert(kMaxTickets < 256, "Too many tickets"); + assert(i < 256); uint8_t nonce[] = {static_cast(i)}; ScopedCBB cbb; @@ -658,28 +660,16 @@ static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) { } // Decrypt the payload with the HPKE context from the first ClientHello. - Array encoded_client_hello_inner; + uint8_t alert = SSL_AD_DECODE_ERROR; bool unused; - if (!ssl_client_hello_decrypt(hs->ech_hpke_ctx.get(), - &encoded_client_hello_inner, &unused, - &client_hello, payload)) { + if (!ssl_client_hello_decrypt(hs, &alert, &unused, + &hs->ech_client_hello_buf, &client_hello, + payload)) { // Decryption failure is fatal in the second ClientHello. OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); - ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); - return ssl_hs_error; - } - - // Recover the ClientHelloInner from the EncodedClientHelloInner. - uint8_t alert = SSL_AD_DECODE_ERROR; - bssl::Array client_hello_inner; - if (!ssl_decode_client_hello_inner(ssl, &alert, &client_hello_inner, - encoded_client_hello_inner, - &client_hello)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } - hs->ech_client_hello_buf = std::move(client_hello_inner); // Reparse |client_hello| from the buffer owned by |hs|. if (!hs->GetClientHello(&msg, &client_hello)) { @@ -751,12 +741,13 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { SSL_HANDSHAKE_HINTS *const hints = hs->hints.get(); if (hints && !hs->hints_requested && - hints->server_random.size() == random.size()) { - OPENSSL_memcpy(random.data(), hints->server_random.data(), random.size()); + hints->server_random_tls13.size() == random.size()) { + OPENSSL_memcpy(random.data(), hints->server_random_tls13.data(), + random.size()); } else { RAND_bytes(random.data(), random.size()); if (hints && hs->hints_requested && - !hints->server_random.CopyFrom(random)) { + !hints->server_random_tls13.CopyFrom(random)) { return ssl_hs_error; } } @@ -802,7 +793,7 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { return ssl_hs_error; } - hs->ecdh_public_key.Reset(); // No longer needed. + hs->key_share_ciphertext.Reset(); // No longer needed. if (!ssl->s3->used_hello_retry_request && !ssl->method->add_change_cipher_spec(ssl)) { return ssl_hs_error; diff --git a/third_party/boringssl/kit/src/ssl/tls_method.cc b/third_party/boringssl/kit/src/ssl/tls_method.cc index 326cbe75..5fcf684d 100644 --- a/third_party/boringssl/kit/src/ssl/tls_method.cc +++ b/third_party/boringssl/kit/src/ssl/tls_method.cc @@ -108,7 +108,7 @@ static bool tls_set_read_state(SSL *ssl, ssl_encryption_level_t level, } } - OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + ssl->s3->read_sequence = 0; ssl->s3->aead_read_ctx = std::move(aead_ctx); ssl->s3->read_level = level; return true; @@ -137,7 +137,7 @@ static bool tls_set_write_state(SSL *ssl, ssl_encryption_level_t level, } } - OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + ssl->s3->write_sequence = 0; ssl->s3->aead_write_ctx = std::move(aead_ctx); ssl->s3->write_level = level; return true; diff --git a/third_party/boringssl/kit/src/ssl/tls_record.cc b/third_party/boringssl/kit/src/ssl/tls_record.cc index acff1ad9..395b9a48 100644 --- a/third_party/boringssl/kit/src/ssl/tls_record.cc +++ b/third_party/boringssl/kit/src/ssl/tls_record.cc @@ -151,17 +151,6 @@ static bool ssl_needs_record_splitting(const SSL *ssl) { #endif } -bool ssl_record_sequence_update(uint8_t *seq, size_t seq_len) { - for (size_t i = seq_len - 1; i < seq_len; i--) { - ++seq[i]; - if (seq[i] != 0) { - return true; - } - } - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); - return false; -} - size_t ssl_record_prefix_len(const SSL *ssl) { size_t header_len; if (SSL_is_dtls(ssl)) { @@ -286,6 +275,13 @@ ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, return skip_early_data(ssl, out_alert, *out_consumed); } + // Ensure the sequence number update does not overflow. + if (ssl->s3->read_sequence + 1 == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + // Decrypt the body in-place. if (!ssl->s3->aead_read_ctx->Open( out, type, version, ssl->s3->read_sequence, header, @@ -301,11 +297,7 @@ ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, } ssl->s3->skip_early_data = false; - - if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return ssl_open_record_error; - } + ssl->s3->read_sequence++; // TLS 1.3 hides the record type inside the encrypted data. bool has_padding = @@ -411,13 +403,19 @@ static bool do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, out_prefix[4] = ciphertext_len & 0xff; Span header = MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH); - if (!aead->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, - out_prefix[0], record_version, ssl->s3->write_sequence, - header, in, in_len, extra_in, extra_in_len) || - !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) { + // Ensure the sequence number update does not overflow. + if (ssl->s3->write_sequence + 1 == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return false; } + if (!aead->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, + out_prefix[0], record_version, ssl->s3->write_sequence, + header, in, in_len, extra_in, extra_in_len)) { + return false; + } + + ssl->s3->write_sequence++; ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header); return true; } @@ -602,86 +600,6 @@ enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, return ssl_open_record_error; } -OpenRecordResult OpenRecord(SSL *ssl, Span *out, - size_t *out_record_len, uint8_t *out_alert, - const Span in) { - // This API is a work in progress and currently only works for TLS 1.2 servers - // and below. - if (SSL_in_init(ssl) || - SSL_is_dtls(ssl) || - ssl_protocol_version(ssl) > TLS1_2_VERSION) { - assert(false); - *out_alert = SSL_AD_INTERNAL_ERROR; - return OpenRecordResult::kError; - } - - Span plaintext; - uint8_t type = 0; - const ssl_open_record_t result = tls_open_record( - ssl, &type, &plaintext, out_record_len, out_alert, in); - - switch (result) { - case ssl_open_record_success: - if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) { - *out_alert = SSL_AD_UNEXPECTED_MESSAGE; - return OpenRecordResult::kError; - } - *out = plaintext; - return OpenRecordResult::kOK; - case ssl_open_record_discard: - return OpenRecordResult::kDiscard; - case ssl_open_record_partial: - return OpenRecordResult::kIncompleteRecord; - case ssl_open_record_close_notify: - return OpenRecordResult::kAlertCloseNotify; - case ssl_open_record_error: - return OpenRecordResult::kError; - } - assert(false); - return OpenRecordResult::kError; -} - -size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) { - return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len); -} - -size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) { - assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH); - size_t suffix_len; - if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA, - plaintext_len)) { - assert(false); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; - } - assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD); - return suffix_len; -} - -bool SealRecord(SSL *ssl, const Span out_prefix, - const Span out, Span out_suffix, - const Span in) { - // This API is a work in progress and currently only works for TLS 1.2 servers - // and below. - if (SSL_in_init(ssl) || - SSL_is_dtls(ssl) || - ssl_protocol_version(ssl) > TLS1_2_VERSION) { - assert(false); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return false; - } - - if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) || - out.size() != in.size() || - out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) { - OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); - return false; - } - return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(), - out_suffix.data(), SSL3_RT_APPLICATION_DATA, - in.data(), in.size()); -} - BSSL_NAMESPACE_END using namespace bssl; diff --git a/third_party/boringssl/kit/src/third_party/fiat/LICENSE b/third_party/boringssl/kit/src/third_party/fiat/LICENSE index bd46c613..70cae037 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/LICENSE +++ b/third_party/boringssl/kit/src/third_party/fiat/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2016 the fiat-crypto authors (see +Copyright (c) 2015-2020 the fiat-crypto authors (see https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS). Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/third_party/boringssl/kit/src/third_party/fiat/METADATA b/third_party/boringssl/kit/src/third_party/fiat/METADATA index e527c140..339fe5f8 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/METADATA +++ b/third_party/boringssl/kit/src/third_party/fiat/METADATA @@ -6,8 +6,8 @@ third_party { type: GIT value: "https://github.com/mit-plv/fiat-crypto" } - version: "0884b6d374a9d937c44bf024fe3a647ffae2c540" - last_upgrade_date { year: 2020 month: 4 day: 16 } + version: "6ccc6638716d4632304baf1adbb5c47c3a12ea6f" + last_upgrade_date { year: 2022 month: 3 day: 22 } - local_modifications: "Files renamed to .h for BoringSSL integration. Select functions patched with value barriers." + local_modifications: "Files renamed to .h for BoringSSL integration. LICENSE file is LICENSE-MIT from upstream." } diff --git a/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_mul.S b/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_mul.S new file mode 100644 index 00000000..28b17456 --- /dev/null +++ b/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_mul.S @@ -0,0 +1,175 @@ +#if !defined(OPENSSL_NO_ASM) && defined(__x86_64__) && \ + (defined(__APPLE__) || defined(__ELF__)) + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +.intel_syntax noprefix +.text +#if defined(__APPLE__) +.private_extern _fiat_curve25519_adx_mul +.global _fiat_curve25519_adx_mul +_fiat_curve25519_adx_mul: +#else +.type fiat_curve25519_adx_mul, @function +.hidden fiat_curve25519_adx_mul +.global fiat_curve25519_adx_mul +fiat_curve25519_adx_mul: +#endif + +.cfi_startproc +mov [rsp - 0x08], rbp +.cfi_offset rbp, -8-0x08 +mov rbp, rsp + +mov rax, rdx +mov rdx, [ rsi + 0x18 ] +mulx r11, r10, [ rax + 0x8 ] +mov rdx, [ rax + 0x0 ] +mov [ rsp - 0x58 ], r15 +.cfi_offset r15, -8-0x58 +mulx r8, rcx, [ rsi + 0x18 ] +mov rdx, [ rsi + 0x8 ] +mov [ rsp - 0x80 ], rbx +.cfi_offset rbx, -8-0x80 +mulx rbx, r9, [ rax + 0x18 ] +mov rdx, [ rsi + 0x8 ] +mov [ rsp - 0x70 ], r12 +.cfi_offset r12, -8-0x70 +mulx r15, r12, [ rax + 0x8 ] +mov rdx, [ rsi + 0x0 ] +mov [ rsp - 0x68 ], r13 +.cfi_offset r13, -8-0x68 +mov [ rsp - 0x60 ], r14 +.cfi_offset r14, -8-0x60 +mulx r14, r13, [ rax + 0x0 ] +mov rdx, [ rax + 0x10 ] +mov [ rsp - 0x18 ], r15 +mov [ rsp - 0x50 ], rdi +mulx rdi, r15, [ rsi + 0x0 ] +mov rdx, [ rax + 0x18 ] +mov [ rsp - 0x48 ], r13 +mov [ rsp - 0x40 ], r9 +mulx r9, r13, [ rsi + 0x0 ] +test al, al +adox rcx, rdi +mov rdx, [ rsi + 0x10 ] +mov [ rsp - 0x38 ], r13 +mulx r13, rdi, [ rax + 0x8 ] +adox r10, r9 +mov rdx, 0x0 +adox rbx, rdx +adcx rdi, rcx +adcx r8, r10 +mov r9, rdx +adcx r9, rbx +mov rdx, [ rsi + 0x10 ] +mulx r10, rcx, [ rax + 0x0 ] +mov rdx, [ rsi + 0x0 ] +mov [ rsp - 0x30 ], r15 +mulx r15, rbx, [ rax + 0x8 ] +mov rdx, -0x2 +inc rdx +adox rcx, r15 +setc r15b +clc +adcx rcx, r12 +adox r10, rdi +mov rdx, [ rax + 0x10 ] +mov [ rsp - 0x78 ], rcx +mulx rcx, rdi, [ rsi + 0x10 ] +adox rdi, r8 +mov rdx, [ rax + 0x18 ] +mov [ rsp - 0x28 ], rcx +mulx rcx, r8, [ rsi + 0x10 ] +mov rdx, [ rax + 0x10 ] +mov [ rsp - 0x20 ], r8 +mulx r12, r8, [ rsi + 0x18 ] +adox r8, r9 +mov rdx, [ rsi + 0x8 ] +mov [ rsp - 0x10 ], r12 +mulx r12, r9, [ rax + 0x10 ] +movzx rdx, r15b +lea rdx, [ rdx + rcx ] +adcx r9, r10 +adcx r13, rdi +mov r15, 0x0 +mov r10, r15 +adox r10, rdx +mov rdx, [ rax + 0x18 ] +mulx rcx, rdi, [ rsi + 0x18 ] +adox rcx, r15 +adcx r11, r8 +mov rdx, r15 +adcx rdx, r10 +adcx rcx, r15 +mov r8, rdx +mov rdx, [ rax + 0x0 ] +mulx r15, r10, [ rsi + 0x8 ] +test al, al +adox r10, r14 +adcx rbx, r10 +adox r15, [ rsp - 0x78 ] +adcx r15, [ rsp - 0x30 ] +adox r9, [ rsp - 0x18 ] +adcx r9, [ rsp - 0x38 ] +adox r13, [ rsp - 0x40 ] +adcx r12, r13 +adox r11, [ rsp - 0x20 ] +adcx r11, [ rsp - 0x28 ] +mov rdx, 0x26 +mulx rsi, r14, r12 +adox rdi, r8 +adcx rdi, [ rsp - 0x10 ] +mulx r10, r8, r11 +mov r13, 0x0 +adox rcx, r13 +adcx rcx, r13 +mulx r11, r12, rdi +xor rdi, rdi +adox r8, rbx +adox r12, r15 +mulx rbx, r13, rcx +adcx r14, [ rsp - 0x48 ] +adox r13, r9 +adox rbx, rdi +adcx rsi, r8 +adcx r10, r12 +adcx r11, r13 +adc rbx, 0x0 +mulx r9, r15, rbx +xor r9, r9 +adox r15, r14 +mov rdi, r9 +adox rdi, rsi +mov rcx, r9 +adox rcx, r10 +mov r8, [ rsp - 0x50 ] +mov [ r8 + 0x8 ], rdi +mov r12, r9 +adox r12, r11 +mov r14, r9 +cmovo r14, rdx +mov [ r8 + 0x18 ], r12 +adcx r15, r14 +mov [ r8 + 0x0 ], r15 +mov [ r8 + 0x10 ], rcx +mov rbx, [ rsp - 0x80 ] +mov r12, [ rsp - 0x70 ] +mov r13, [ rsp - 0x68 ] +mov r14, [ rsp - 0x60 ] +mov r15, [ rsp - 0x58 ] + +mov rbp, [rsp - 0x08] +ret +.cfi_endproc +#if defined(__ELF__) +.size fiat_curve25519_adx_mul, .-fiat_curve25519_adx_mul +#endif + +#endif + +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_square.S b/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_square.S new file mode 100644 index 00000000..88818217 --- /dev/null +++ b/third_party/boringssl/kit/src/third_party/fiat/asm/fiat_curve25519_adx_square.S @@ -0,0 +1,143 @@ +#if !defined(OPENSSL_NO_ASM) && defined(__x86_64__) && \ + (defined(__APPLE__) || defined(__ELF__)) + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +.intel_syntax noprefix +.text +#if defined(__APPLE__) +.private_extern _fiat_curve25519_adx_square +.global _fiat_curve25519_adx_square +_fiat_curve25519_adx_square: +#else +.type fiat_curve25519_adx_square, @function +.hidden fiat_curve25519_adx_square +.global fiat_curve25519_adx_square +fiat_curve25519_adx_square: +#endif + +.cfi_startproc +mov [rsp - 0x08], rbp +.cfi_offset rbp, -8-0x08 +mov rbp, rsp + +mov rdx, [ rsi + 0x0 ] +mulx r10, rax, [ rsi + 0x8 ] +mov rdx, [ rsi + 0x0 ] +mulx rcx, r11, [ rsi + 0x10 ] +xor rdx, rdx +adox r11, r10 +mov rdx, [ rsi + 0x0 ] +mulx r9, r8, [ rsi + 0x18 ] +mov rdx, [ rsi + 0x8 ] +mov [ rsp - 0x80 ], rbx +.cfi_offset rbx, -8-0x80 +mulx rbx, r10, [ rsi + 0x18 ] +adox r8, rcx +mov [rsp - 0x48 ], rdi +adox r10, r9 +adcx rax, rax +mov rdx, [ rsi + 0x10 ] +mulx r9, rcx, [ rsi + 0x18 ] +adox rcx, rbx +mov rdx, [ rsi + 0x10 ] +mulx rdi, rbx, [ rsi + 0x8 ] +mov rdx, 0x0 +adox r9, rdx +mov [ rsp - 0x70 ], r12 +.cfi_offset r12, -8-0x70 +mov r12, -0x3 +inc r12 +adox rbx, r8 +adox rdi, r10 +adcx r11, r11 +mov r8, rdx +adox r8, rcx +mov r10, rdx +adox r10, r9 +adcx rbx, rbx +mov rdx, [ rsi + 0x0 ] +mulx r9, rcx, rdx +mov rdx, [ rsi + 0x8 ] +mov [ rsp - 0x68 ], r13 +.cfi_offset r13, -8-0x68 +mov [ rsp - 0x60 ], r14 +.cfi_offset r14, -8-0x60 +mulx r14, r13, rdx +seto dl +inc r12 +adox r9, rax +adox r13, r11 +adox r14, rbx +adcx rdi, rdi +mov al, dl +mov rdx, [ rsi + 0x10 ] +mulx rbx, r11, rdx +adox r11, rdi +adcx r8, r8 +adox rbx, r8 +adcx r10, r10 +movzx rdx, al +mov rdi, 0x0 +adcx rdx, rdi +movzx r8, al +lea r8, [ r8 + rdx ] +mov rdx, [ rsi + 0x18 ] +mulx rdi, rax, rdx +adox rax, r10 +mov rdx, 0x26 +mov [ rsp - 0x58 ], r15 +.cfi_offset r15, -8-0x58 +mulx r15, r10, r11 +clc +adcx r10, rcx +mulx r11, rcx, rbx +adox r8, rdi +mulx rdi, rbx, r8 +inc r12 +adox rcx, r9 +mulx r8, r9, rax +adcx r15, rcx +adox r9, r13 +adcx r11, r9 +adox rbx, r14 +adox rdi, r12 +adcx r8, rbx +adc rdi, 0x0 +mulx r14, r13, rdi +test al, al +mov rdi, [ rsp - 0x48 ] +adox r13, r10 +mov r14, r12 +adox r14, r15 +mov [ rdi + 0x8 ], r14 +mov rax, r12 +adox rax, r11 +mov r10, r12 +adox r10, r8 +mov [ rdi + 0x10 ], rax +mov rcx, r12 +cmovo rcx, rdx +adcx r13, rcx +mov [ rdi + 0x0 ], r13 +mov [ rdi + 0x18 ], r10 +mov rbx, [ rsp - 0x80 ] +mov r12, [ rsp - 0x70 ] +mov r13, [ rsp - 0x68 ] +mov r14, [ rsp - 0x60 ] +mov r15, [ rsp - 0x58 ] + +mov rbp, [rsp - 0x08] +ret +.cfi_endproc +#if defined(__ELF__) +.size fiat_curve25519_adx_square, .-fiat_curve25519_adx_square +#endif + +#endif + +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/src/third_party/fiat/curve25519_32.h b/third_party/boringssl/kit/src/third_party/fiat/curve25519_32.h index 7b78d00d..cb83c606 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/curve25519_32.h +++ b/third_party/boringssl/kit/src/third_party/fiat/curve25519_32.h @@ -1,24 +1,51 @@ -/* Autogenerated: src/ExtractionOCaml/unsaturated_solinas --static 25519 10 '2^255 - 19' 32 carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes carry_scmul121666 */ +/* Autogenerated: 'src/ExtractionOCaml/unsaturated_solinas' --inline --static --use-value-barrier 25519 32 '(auto)' '2^255 - 19' carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes relax carry_scmul121666 */ /* curve description: 25519 */ -/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, carry_scmul121666 */ -/* n = 10 (from "10") */ -/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ /* machine_wordsize = 32 (from "32") */ - +/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, relax, carry_scmul121666 */ +/* n = 10 (from "(auto)") */ +/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ +/* tight_bounds_multiplier = 1 (from "") */ +/* */ /* Computed values: */ -/* carry_chain = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1] */ +/* carry_chain = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1] */ +/* eval z = z[0] + (z[1] << 26) + (z[2] << 51) + (z[3] << 77) + (z[4] << 102) + (z[5] << 128) + (z[6] << 153) + (z[7] << 179) + (z[8] << 204) + (z[9] << 230) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* balance = [0x7ffffda, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe, 0x7fffffe, 0x3fffffe] */ #include typedef unsigned char fiat_25519_uint1; typedef signed char fiat_25519_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_25519_FIAT_INLINE __inline__ +#else +# define FIAT_25519_FIAT_INLINE +#endif + +/* The type fiat_25519_loose_field_element is a field element with loose bounds. */ +/* Bounds: [[0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000], [0x0 ~> 0xc000000], [0x0 ~> 0x6000000]] */ +typedef uint32_t fiat_25519_loose_field_element[10]; + +/* The type fiat_25519_tight_field_element is a field element with tight bounds. */ +/* Bounds: [[0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000], [0x0 ~> 0x4000000], [0x0 ~> 0x2000000]] */ +typedef uint32_t fiat_25519_tight_field_element[10]; #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif +#if !defined(FIAT_25519_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint32_t fiat_25519_value_barrier_u32(uint32_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_25519_value_barrier_u32(x) (x) +#endif + /* * The function fiat_25519_addcarryx_u26 is an addition with carry. + * * Postconditions: * out1 = (arg1 + arg2 + arg3) mod 2^26 * out2 = ⌊(arg1 + arg2 + arg3) / 2^26⌋ @@ -31,16 +58,20 @@ typedef signed char fiat_25519_int1; * out1: [0x0 ~> 0x3ffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_addcarryx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { - uint32_t x1 = ((arg1 + arg2) + arg3); - uint32_t x2 = (x1 & UINT32_C(0x3ffffff)); - fiat_25519_uint1 x3 = (fiat_25519_uint1)(x1 >> 26); +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint32_t x1; + uint32_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT32_C(0x3ffffff)); + x3 = (fiat_25519_uint1)(x1 >> 26); *out1 = x2; *out2 = x3; } /* * The function fiat_25519_subborrowx_u26 is a subtraction with borrow. + * * Postconditions: * out1 = (-arg1 + arg2 + -arg3) mod 2^26 * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^26⌋ @@ -53,16 +84,20 @@ static void fiat_25519_addcarryx_u26(uint32_t* out1, fiat_25519_uint1* out2, fia * out1: [0x0 ~> 0x3ffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_subborrowx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { - int32_t x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 26); - uint32_t x3 = (x1 & UINT32_C(0x3ffffff)); +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int32_t x1; + fiat_25519_int1 x2; + uint32_t x3; + x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 26); + x3 = (x1 & UINT32_C(0x3ffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); } /* * The function fiat_25519_addcarryx_u25 is an addition with carry. + * * Postconditions: * out1 = (arg1 + arg2 + arg3) mod 2^25 * out2 = ⌊(arg1 + arg2 + arg3) / 2^25⌋ @@ -75,16 +110,20 @@ static void fiat_25519_subborrowx_u26(uint32_t* out1, fiat_25519_uint1* out2, fi * out1: [0x0 ~> 0x1ffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_addcarryx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { - uint32_t x1 = ((arg1 + arg2) + arg3); - uint32_t x2 = (x1 & UINT32_C(0x1ffffff)); - fiat_25519_uint1 x3 = (fiat_25519_uint1)(x1 >> 25); +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint32_t x1; + uint32_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT32_C(0x1ffffff)); + x3 = (fiat_25519_uint1)(x1 >> 25); *out1 = x2; *out2 = x3; } /* * The function fiat_25519_subborrowx_u25 is a subtraction with borrow. + * * Postconditions: * out1 = (-arg1 + arg2 + -arg3) mod 2^25 * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^25⌋ @@ -97,16 +136,20 @@ static void fiat_25519_addcarryx_u25(uint32_t* out1, fiat_25519_uint1* out2, fia * out1: [0x0 ~> 0x1ffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_subborrowx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { - int32_t x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 25); - uint32_t x3 = (x1 & UINT32_C(0x1ffffff)); +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int32_t x1; + fiat_25519_int1 x2; + uint32_t x3; + x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 25); + x3 = (x1 & UINT32_C(0x1ffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); } /* * The function fiat_25519_cmovznz_u32 is a single-word conditional move. + * * Postconditions: * out1 = (if arg1 = 0 then arg2 else arg3) * @@ -117,178 +160,318 @@ static void fiat_25519_subborrowx_u25(uint32_t* out1, fiat_25519_uint1* out2, fi * Output Bounds: * out1: [0x0 ~> 0xffffffff] */ -static void fiat_25519_cmovznz_u32(uint32_t* out1, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { - fiat_25519_uint1 x1 = (!(!arg1)); - uint32_t x2 = ((fiat_25519_int1)(0x0 - x1) & UINT32_C(0xffffffff)); - // Note this line has been patched from the synthesized code to add value - // barriers. - // - // Clang recognizes this pattern as a select. While it usually transforms it - // to a cmov, it sometimes further transforms it into a branch, which we do - // not want. - uint32_t x3 = ((value_barrier_u32(x2) & arg3) | (value_barrier_u32(~x2) & arg2)); +static FIAT_25519_FIAT_INLINE void fiat_25519_cmovznz_u32(uint32_t* out1, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { + fiat_25519_uint1 x1; + uint32_t x2; + uint32_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_25519_int1)(0x0 - x1) & UINT32_C(0xffffffff)); + x3 = ((fiat_25519_value_barrier_u32(x2) & arg3) | (fiat_25519_value_barrier_u32((~x2)) & arg2)); *out1 = x3; } /* * The function fiat_25519_carry_mul multiplies two field elements and reduces the result. + * * Postconditions: * eval out1 mod m = (eval arg1 * eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] - * arg2: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] - * Output Bounds: - * out1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] */ -static void fiat_25519_carry_mul(uint32_t out1[10], const uint32_t arg1[10], const uint32_t arg2[10]) { - uint64_t x1 = ((uint64_t)(arg1[9]) * ((arg2[9]) * UINT8_C(0x26))); - uint64_t x2 = ((uint64_t)(arg1[9]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x3 = ((uint64_t)(arg1[9]) * ((arg2[7]) * UINT8_C(0x26))); - uint64_t x4 = ((uint64_t)(arg1[9]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x5 = ((uint64_t)(arg1[9]) * ((arg2[5]) * UINT8_C(0x26))); - uint64_t x6 = ((uint64_t)(arg1[9]) * ((arg2[4]) * UINT8_C(0x13))); - uint64_t x7 = ((uint64_t)(arg1[9]) * ((arg2[3]) * UINT8_C(0x26))); - uint64_t x8 = ((uint64_t)(arg1[9]) * ((arg2[2]) * UINT8_C(0x13))); - uint64_t x9 = ((uint64_t)(arg1[9]) * ((arg2[1]) * UINT8_C(0x26))); - uint64_t x10 = ((uint64_t)(arg1[8]) * ((arg2[9]) * UINT8_C(0x13))); - uint64_t x11 = ((uint64_t)(arg1[8]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x12 = ((uint64_t)(arg1[8]) * ((arg2[7]) * UINT8_C(0x13))); - uint64_t x13 = ((uint64_t)(arg1[8]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x14 = ((uint64_t)(arg1[8]) * ((arg2[5]) * UINT8_C(0x13))); - uint64_t x15 = ((uint64_t)(arg1[8]) * ((arg2[4]) * UINT8_C(0x13))); - uint64_t x16 = ((uint64_t)(arg1[8]) * ((arg2[3]) * UINT8_C(0x13))); - uint64_t x17 = ((uint64_t)(arg1[8]) * ((arg2[2]) * UINT8_C(0x13))); - uint64_t x18 = ((uint64_t)(arg1[7]) * ((arg2[9]) * UINT8_C(0x26))); - uint64_t x19 = ((uint64_t)(arg1[7]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x20 = ((uint64_t)(arg1[7]) * ((arg2[7]) * UINT8_C(0x26))); - uint64_t x21 = ((uint64_t)(arg1[7]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x22 = ((uint64_t)(arg1[7]) * ((arg2[5]) * UINT8_C(0x26))); - uint64_t x23 = ((uint64_t)(arg1[7]) * ((arg2[4]) * UINT8_C(0x13))); - uint64_t x24 = ((uint64_t)(arg1[7]) * ((arg2[3]) * UINT8_C(0x26))); - uint64_t x25 = ((uint64_t)(arg1[6]) * ((arg2[9]) * UINT8_C(0x13))); - uint64_t x26 = ((uint64_t)(arg1[6]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x27 = ((uint64_t)(arg1[6]) * ((arg2[7]) * UINT8_C(0x13))); - uint64_t x28 = ((uint64_t)(arg1[6]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x29 = ((uint64_t)(arg1[6]) * ((arg2[5]) * UINT8_C(0x13))); - uint64_t x30 = ((uint64_t)(arg1[6]) * ((arg2[4]) * UINT8_C(0x13))); - uint64_t x31 = ((uint64_t)(arg1[5]) * ((arg2[9]) * UINT8_C(0x26))); - uint64_t x32 = ((uint64_t)(arg1[5]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x33 = ((uint64_t)(arg1[5]) * ((arg2[7]) * UINT8_C(0x26))); - uint64_t x34 = ((uint64_t)(arg1[5]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x35 = ((uint64_t)(arg1[5]) * ((arg2[5]) * UINT8_C(0x26))); - uint64_t x36 = ((uint64_t)(arg1[4]) * ((arg2[9]) * UINT8_C(0x13))); - uint64_t x37 = ((uint64_t)(arg1[4]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x38 = ((uint64_t)(arg1[4]) * ((arg2[7]) * UINT8_C(0x13))); - uint64_t x39 = ((uint64_t)(arg1[4]) * ((arg2[6]) * UINT8_C(0x13))); - uint64_t x40 = ((uint64_t)(arg1[3]) * ((arg2[9]) * UINT8_C(0x26))); - uint64_t x41 = ((uint64_t)(arg1[3]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x42 = ((uint64_t)(arg1[3]) * ((arg2[7]) * UINT8_C(0x26))); - uint64_t x43 = ((uint64_t)(arg1[2]) * ((arg2[9]) * UINT8_C(0x13))); - uint64_t x44 = ((uint64_t)(arg1[2]) * ((arg2[8]) * UINT8_C(0x13))); - uint64_t x45 = ((uint64_t)(arg1[1]) * ((arg2[9]) * UINT8_C(0x26))); - uint64_t x46 = ((uint64_t)(arg1[9]) * (arg2[0])); - uint64_t x47 = ((uint64_t)(arg1[8]) * (arg2[1])); - uint64_t x48 = ((uint64_t)(arg1[8]) * (arg2[0])); - uint64_t x49 = ((uint64_t)(arg1[7]) * (arg2[2])); - uint64_t x50 = ((uint64_t)(arg1[7]) * ((arg2[1]) * 0x2)); - uint64_t x51 = ((uint64_t)(arg1[7]) * (arg2[0])); - uint64_t x52 = ((uint64_t)(arg1[6]) * (arg2[3])); - uint64_t x53 = ((uint64_t)(arg1[6]) * (arg2[2])); - uint64_t x54 = ((uint64_t)(arg1[6]) * (arg2[1])); - uint64_t x55 = ((uint64_t)(arg1[6]) * (arg2[0])); - uint64_t x56 = ((uint64_t)(arg1[5]) * (arg2[4])); - uint64_t x57 = ((uint64_t)(arg1[5]) * ((arg2[3]) * 0x2)); - uint64_t x58 = ((uint64_t)(arg1[5]) * (arg2[2])); - uint64_t x59 = ((uint64_t)(arg1[5]) * ((arg2[1]) * 0x2)); - uint64_t x60 = ((uint64_t)(arg1[5]) * (arg2[0])); - uint64_t x61 = ((uint64_t)(arg1[4]) * (arg2[5])); - uint64_t x62 = ((uint64_t)(arg1[4]) * (arg2[4])); - uint64_t x63 = ((uint64_t)(arg1[4]) * (arg2[3])); - uint64_t x64 = ((uint64_t)(arg1[4]) * (arg2[2])); - uint64_t x65 = ((uint64_t)(arg1[4]) * (arg2[1])); - uint64_t x66 = ((uint64_t)(arg1[4]) * (arg2[0])); - uint64_t x67 = ((uint64_t)(arg1[3]) * (arg2[6])); - uint64_t x68 = ((uint64_t)(arg1[3]) * ((arg2[5]) * 0x2)); - uint64_t x69 = ((uint64_t)(arg1[3]) * (arg2[4])); - uint64_t x70 = ((uint64_t)(arg1[3]) * ((arg2[3]) * 0x2)); - uint64_t x71 = ((uint64_t)(arg1[3]) * (arg2[2])); - uint64_t x72 = ((uint64_t)(arg1[3]) * ((arg2[1]) * 0x2)); - uint64_t x73 = ((uint64_t)(arg1[3]) * (arg2[0])); - uint64_t x74 = ((uint64_t)(arg1[2]) * (arg2[7])); - uint64_t x75 = ((uint64_t)(arg1[2]) * (arg2[6])); - uint64_t x76 = ((uint64_t)(arg1[2]) * (arg2[5])); - uint64_t x77 = ((uint64_t)(arg1[2]) * (arg2[4])); - uint64_t x78 = ((uint64_t)(arg1[2]) * (arg2[3])); - uint64_t x79 = ((uint64_t)(arg1[2]) * (arg2[2])); - uint64_t x80 = ((uint64_t)(arg1[2]) * (arg2[1])); - uint64_t x81 = ((uint64_t)(arg1[2]) * (arg2[0])); - uint64_t x82 = ((uint64_t)(arg1[1]) * (arg2[8])); - uint64_t x83 = ((uint64_t)(arg1[1]) * ((arg2[7]) * 0x2)); - uint64_t x84 = ((uint64_t)(arg1[1]) * (arg2[6])); - uint64_t x85 = ((uint64_t)(arg1[1]) * ((arg2[5]) * 0x2)); - uint64_t x86 = ((uint64_t)(arg1[1]) * (arg2[4])); - uint64_t x87 = ((uint64_t)(arg1[1]) * ((arg2[3]) * 0x2)); - uint64_t x88 = ((uint64_t)(arg1[1]) * (arg2[2])); - uint64_t x89 = ((uint64_t)(arg1[1]) * ((arg2[1]) * 0x2)); - uint64_t x90 = ((uint64_t)(arg1[1]) * (arg2[0])); - uint64_t x91 = ((uint64_t)(arg1[0]) * (arg2[9])); - uint64_t x92 = ((uint64_t)(arg1[0]) * (arg2[8])); - uint64_t x93 = ((uint64_t)(arg1[0]) * (arg2[7])); - uint64_t x94 = ((uint64_t)(arg1[0]) * (arg2[6])); - uint64_t x95 = ((uint64_t)(arg1[0]) * (arg2[5])); - uint64_t x96 = ((uint64_t)(arg1[0]) * (arg2[4])); - uint64_t x97 = ((uint64_t)(arg1[0]) * (arg2[3])); - uint64_t x98 = ((uint64_t)(arg1[0]) * (arg2[2])); - uint64_t x99 = ((uint64_t)(arg1[0]) * (arg2[1])); - uint64_t x100 = ((uint64_t)(arg1[0]) * (arg2[0])); - uint64_t x101 = (x100 + (x45 + (x44 + (x42 + (x39 + (x35 + (x30 + (x24 + (x17 + x9))))))))); - uint64_t x102 = (x101 >> 26); - uint32_t x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); - uint64_t x104 = (x91 + (x82 + (x74 + (x67 + (x61 + (x56 + (x52 + (x49 + (x47 + x46))))))))); - uint64_t x105 = (x92 + (x83 + (x75 + (x68 + (x62 + (x57 + (x53 + (x50 + (x48 + x1))))))))); - uint64_t x106 = (x93 + (x84 + (x76 + (x69 + (x63 + (x58 + (x54 + (x51 + (x10 + x2))))))))); - uint64_t x107 = (x94 + (x85 + (x77 + (x70 + (x64 + (x59 + (x55 + (x18 + (x11 + x3))))))))); - uint64_t x108 = (x95 + (x86 + (x78 + (x71 + (x65 + (x60 + (x25 + (x19 + (x12 + x4))))))))); - uint64_t x109 = (x96 + (x87 + (x79 + (x72 + (x66 + (x31 + (x26 + (x20 + (x13 + x5))))))))); - uint64_t x110 = (x97 + (x88 + (x80 + (x73 + (x36 + (x32 + (x27 + (x21 + (x14 + x6))))))))); - uint64_t x111 = (x98 + (x89 + (x81 + (x40 + (x37 + (x33 + (x28 + (x22 + (x15 + x7))))))))); - uint64_t x112 = (x99 + (x90 + (x43 + (x41 + (x38 + (x34 + (x29 + (x23 + (x16 + x8))))))))); - uint64_t x113 = (x102 + x112); - uint64_t x114 = (x113 >> 25); - uint32_t x115 = (uint32_t)(x113 & UINT32_C(0x1ffffff)); - uint64_t x116 = (x114 + x111); - uint64_t x117 = (x116 >> 26); - uint32_t x118 = (uint32_t)(x116 & UINT32_C(0x3ffffff)); - uint64_t x119 = (x117 + x110); - uint64_t x120 = (x119 >> 25); - uint32_t x121 = (uint32_t)(x119 & UINT32_C(0x1ffffff)); - uint64_t x122 = (x120 + x109); - uint64_t x123 = (x122 >> 26); - uint32_t x124 = (uint32_t)(x122 & UINT32_C(0x3ffffff)); - uint64_t x125 = (x123 + x108); - uint64_t x126 = (x125 >> 25); - uint32_t x127 = (uint32_t)(x125 & UINT32_C(0x1ffffff)); - uint64_t x128 = (x126 + x107); - uint64_t x129 = (x128 >> 26); - uint32_t x130 = (uint32_t)(x128 & UINT32_C(0x3ffffff)); - uint64_t x131 = (x129 + x106); - uint64_t x132 = (x131 >> 25); - uint32_t x133 = (uint32_t)(x131 & UINT32_C(0x1ffffff)); - uint64_t x134 = (x132 + x105); - uint64_t x135 = (x134 >> 26); - uint32_t x136 = (uint32_t)(x134 & UINT32_C(0x3ffffff)); - uint64_t x137 = (x135 + x104); - uint64_t x138 = (x137 >> 25); - uint32_t x139 = (uint32_t)(x137 & UINT32_C(0x1ffffff)); - uint64_t x140 = (x138 * UINT8_C(0x13)); - uint64_t x141 = (x103 + x140); - uint32_t x142 = (uint32_t)(x141 >> 26); - uint32_t x143 = (uint32_t)(x141 & UINT32_C(0x3ffffff)); - uint32_t x144 = (x142 + x115); - fiat_25519_uint1 x145 = (fiat_25519_uint1)(x144 >> 25); - uint32_t x146 = (x144 & UINT32_C(0x1ffffff)); - uint32_t x147 = (x145 + x118); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_mul(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1, const fiat_25519_loose_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + uint64_t x74; + uint64_t x75; + uint64_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + uint64_t x93; + uint64_t x94; + uint64_t x95; + uint64_t x96; + uint64_t x97; + uint64_t x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint32_t x103; + uint64_t x104; + uint64_t x105; + uint64_t x106; + uint64_t x107; + uint64_t x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint32_t x115; + uint64_t x116; + uint64_t x117; + uint32_t x118; + uint64_t x119; + uint64_t x120; + uint32_t x121; + uint64_t x122; + uint64_t x123; + uint32_t x124; + uint64_t x125; + uint64_t x126; + uint32_t x127; + uint64_t x128; + uint64_t x129; + uint32_t x130; + uint64_t x131; + uint64_t x132; + uint32_t x133; + uint64_t x134; + uint64_t x135; + uint32_t x136; + uint64_t x137; + uint64_t x138; + uint32_t x139; + uint64_t x140; + uint64_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + fiat_25519_uint1 x145; + uint32_t x146; + uint32_t x147; + x1 = ((uint64_t)(arg1[9]) * ((arg2[9]) * UINT8_C(0x26))); + x2 = ((uint64_t)(arg1[9]) * ((arg2[8]) * UINT8_C(0x13))); + x3 = ((uint64_t)(arg1[9]) * ((arg2[7]) * UINT8_C(0x26))); + x4 = ((uint64_t)(arg1[9]) * ((arg2[6]) * UINT8_C(0x13))); + x5 = ((uint64_t)(arg1[9]) * ((arg2[5]) * UINT8_C(0x26))); + x6 = ((uint64_t)(arg1[9]) * ((arg2[4]) * UINT8_C(0x13))); + x7 = ((uint64_t)(arg1[9]) * ((arg2[3]) * UINT8_C(0x26))); + x8 = ((uint64_t)(arg1[9]) * ((arg2[2]) * UINT8_C(0x13))); + x9 = ((uint64_t)(arg1[9]) * ((arg2[1]) * UINT8_C(0x26))); + x10 = ((uint64_t)(arg1[8]) * ((arg2[9]) * UINT8_C(0x13))); + x11 = ((uint64_t)(arg1[8]) * ((arg2[8]) * UINT8_C(0x13))); + x12 = ((uint64_t)(arg1[8]) * ((arg2[7]) * UINT8_C(0x13))); + x13 = ((uint64_t)(arg1[8]) * ((arg2[6]) * UINT8_C(0x13))); + x14 = ((uint64_t)(arg1[8]) * ((arg2[5]) * UINT8_C(0x13))); + x15 = ((uint64_t)(arg1[8]) * ((arg2[4]) * UINT8_C(0x13))); + x16 = ((uint64_t)(arg1[8]) * ((arg2[3]) * UINT8_C(0x13))); + x17 = ((uint64_t)(arg1[8]) * ((arg2[2]) * UINT8_C(0x13))); + x18 = ((uint64_t)(arg1[7]) * ((arg2[9]) * UINT8_C(0x26))); + x19 = ((uint64_t)(arg1[7]) * ((arg2[8]) * UINT8_C(0x13))); + x20 = ((uint64_t)(arg1[7]) * ((arg2[7]) * UINT8_C(0x26))); + x21 = ((uint64_t)(arg1[7]) * ((arg2[6]) * UINT8_C(0x13))); + x22 = ((uint64_t)(arg1[7]) * ((arg2[5]) * UINT8_C(0x26))); + x23 = ((uint64_t)(arg1[7]) * ((arg2[4]) * UINT8_C(0x13))); + x24 = ((uint64_t)(arg1[7]) * ((arg2[3]) * UINT8_C(0x26))); + x25 = ((uint64_t)(arg1[6]) * ((arg2[9]) * UINT8_C(0x13))); + x26 = ((uint64_t)(arg1[6]) * ((arg2[8]) * UINT8_C(0x13))); + x27 = ((uint64_t)(arg1[6]) * ((arg2[7]) * UINT8_C(0x13))); + x28 = ((uint64_t)(arg1[6]) * ((arg2[6]) * UINT8_C(0x13))); + x29 = ((uint64_t)(arg1[6]) * ((arg2[5]) * UINT8_C(0x13))); + x30 = ((uint64_t)(arg1[6]) * ((arg2[4]) * UINT8_C(0x13))); + x31 = ((uint64_t)(arg1[5]) * ((arg2[9]) * UINT8_C(0x26))); + x32 = ((uint64_t)(arg1[5]) * ((arg2[8]) * UINT8_C(0x13))); + x33 = ((uint64_t)(arg1[5]) * ((arg2[7]) * UINT8_C(0x26))); + x34 = ((uint64_t)(arg1[5]) * ((arg2[6]) * UINT8_C(0x13))); + x35 = ((uint64_t)(arg1[5]) * ((arg2[5]) * UINT8_C(0x26))); + x36 = ((uint64_t)(arg1[4]) * ((arg2[9]) * UINT8_C(0x13))); + x37 = ((uint64_t)(arg1[4]) * ((arg2[8]) * UINT8_C(0x13))); + x38 = ((uint64_t)(arg1[4]) * ((arg2[7]) * UINT8_C(0x13))); + x39 = ((uint64_t)(arg1[4]) * ((arg2[6]) * UINT8_C(0x13))); + x40 = ((uint64_t)(arg1[3]) * ((arg2[9]) * UINT8_C(0x26))); + x41 = ((uint64_t)(arg1[3]) * ((arg2[8]) * UINT8_C(0x13))); + x42 = ((uint64_t)(arg1[3]) * ((arg2[7]) * UINT8_C(0x26))); + x43 = ((uint64_t)(arg1[2]) * ((arg2[9]) * UINT8_C(0x13))); + x44 = ((uint64_t)(arg1[2]) * ((arg2[8]) * UINT8_C(0x13))); + x45 = ((uint64_t)(arg1[1]) * ((arg2[9]) * UINT8_C(0x26))); + x46 = ((uint64_t)(arg1[9]) * (arg2[0])); + x47 = ((uint64_t)(arg1[8]) * (arg2[1])); + x48 = ((uint64_t)(arg1[8]) * (arg2[0])); + x49 = ((uint64_t)(arg1[7]) * (arg2[2])); + x50 = ((uint64_t)(arg1[7]) * ((arg2[1]) * 0x2)); + x51 = ((uint64_t)(arg1[7]) * (arg2[0])); + x52 = ((uint64_t)(arg1[6]) * (arg2[3])); + x53 = ((uint64_t)(arg1[6]) * (arg2[2])); + x54 = ((uint64_t)(arg1[6]) * (arg2[1])); + x55 = ((uint64_t)(arg1[6]) * (arg2[0])); + x56 = ((uint64_t)(arg1[5]) * (arg2[4])); + x57 = ((uint64_t)(arg1[5]) * ((arg2[3]) * 0x2)); + x58 = ((uint64_t)(arg1[5]) * (arg2[2])); + x59 = ((uint64_t)(arg1[5]) * ((arg2[1]) * 0x2)); + x60 = ((uint64_t)(arg1[5]) * (arg2[0])); + x61 = ((uint64_t)(arg1[4]) * (arg2[5])); + x62 = ((uint64_t)(arg1[4]) * (arg2[4])); + x63 = ((uint64_t)(arg1[4]) * (arg2[3])); + x64 = ((uint64_t)(arg1[4]) * (arg2[2])); + x65 = ((uint64_t)(arg1[4]) * (arg2[1])); + x66 = ((uint64_t)(arg1[4]) * (arg2[0])); + x67 = ((uint64_t)(arg1[3]) * (arg2[6])); + x68 = ((uint64_t)(arg1[3]) * ((arg2[5]) * 0x2)); + x69 = ((uint64_t)(arg1[3]) * (arg2[4])); + x70 = ((uint64_t)(arg1[3]) * ((arg2[3]) * 0x2)); + x71 = ((uint64_t)(arg1[3]) * (arg2[2])); + x72 = ((uint64_t)(arg1[3]) * ((arg2[1]) * 0x2)); + x73 = ((uint64_t)(arg1[3]) * (arg2[0])); + x74 = ((uint64_t)(arg1[2]) * (arg2[7])); + x75 = ((uint64_t)(arg1[2]) * (arg2[6])); + x76 = ((uint64_t)(arg1[2]) * (arg2[5])); + x77 = ((uint64_t)(arg1[2]) * (arg2[4])); + x78 = ((uint64_t)(arg1[2]) * (arg2[3])); + x79 = ((uint64_t)(arg1[2]) * (arg2[2])); + x80 = ((uint64_t)(arg1[2]) * (arg2[1])); + x81 = ((uint64_t)(arg1[2]) * (arg2[0])); + x82 = ((uint64_t)(arg1[1]) * (arg2[8])); + x83 = ((uint64_t)(arg1[1]) * ((arg2[7]) * 0x2)); + x84 = ((uint64_t)(arg1[1]) * (arg2[6])); + x85 = ((uint64_t)(arg1[1]) * ((arg2[5]) * 0x2)); + x86 = ((uint64_t)(arg1[1]) * (arg2[4])); + x87 = ((uint64_t)(arg1[1]) * ((arg2[3]) * 0x2)); + x88 = ((uint64_t)(arg1[1]) * (arg2[2])); + x89 = ((uint64_t)(arg1[1]) * ((arg2[1]) * 0x2)); + x90 = ((uint64_t)(arg1[1]) * (arg2[0])); + x91 = ((uint64_t)(arg1[0]) * (arg2[9])); + x92 = ((uint64_t)(arg1[0]) * (arg2[8])); + x93 = ((uint64_t)(arg1[0]) * (arg2[7])); + x94 = ((uint64_t)(arg1[0]) * (arg2[6])); + x95 = ((uint64_t)(arg1[0]) * (arg2[5])); + x96 = ((uint64_t)(arg1[0]) * (arg2[4])); + x97 = ((uint64_t)(arg1[0]) * (arg2[3])); + x98 = ((uint64_t)(arg1[0]) * (arg2[2])); + x99 = ((uint64_t)(arg1[0]) * (arg2[1])); + x100 = ((uint64_t)(arg1[0]) * (arg2[0])); + x101 = (x100 + (x45 + (x44 + (x42 + (x39 + (x35 + (x30 + (x24 + (x17 + x9))))))))); + x102 = (x101 >> 26); + x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); + x104 = (x91 + (x82 + (x74 + (x67 + (x61 + (x56 + (x52 + (x49 + (x47 + x46))))))))); + x105 = (x92 + (x83 + (x75 + (x68 + (x62 + (x57 + (x53 + (x50 + (x48 + x1))))))))); + x106 = (x93 + (x84 + (x76 + (x69 + (x63 + (x58 + (x54 + (x51 + (x10 + x2))))))))); + x107 = (x94 + (x85 + (x77 + (x70 + (x64 + (x59 + (x55 + (x18 + (x11 + x3))))))))); + x108 = (x95 + (x86 + (x78 + (x71 + (x65 + (x60 + (x25 + (x19 + (x12 + x4))))))))); + x109 = (x96 + (x87 + (x79 + (x72 + (x66 + (x31 + (x26 + (x20 + (x13 + x5))))))))); + x110 = (x97 + (x88 + (x80 + (x73 + (x36 + (x32 + (x27 + (x21 + (x14 + x6))))))))); + x111 = (x98 + (x89 + (x81 + (x40 + (x37 + (x33 + (x28 + (x22 + (x15 + x7))))))))); + x112 = (x99 + (x90 + (x43 + (x41 + (x38 + (x34 + (x29 + (x23 + (x16 + x8))))))))); + x113 = (x102 + x112); + x114 = (x113 >> 25); + x115 = (uint32_t)(x113 & UINT32_C(0x1ffffff)); + x116 = (x114 + x111); + x117 = (x116 >> 26); + x118 = (uint32_t)(x116 & UINT32_C(0x3ffffff)); + x119 = (x117 + x110); + x120 = (x119 >> 25); + x121 = (uint32_t)(x119 & UINT32_C(0x1ffffff)); + x122 = (x120 + x109); + x123 = (x122 >> 26); + x124 = (uint32_t)(x122 & UINT32_C(0x3ffffff)); + x125 = (x123 + x108); + x126 = (x125 >> 25); + x127 = (uint32_t)(x125 & UINT32_C(0x1ffffff)); + x128 = (x126 + x107); + x129 = (x128 >> 26); + x130 = (uint32_t)(x128 & UINT32_C(0x3ffffff)); + x131 = (x129 + x106); + x132 = (x131 >> 25); + x133 = (uint32_t)(x131 & UINT32_C(0x1ffffff)); + x134 = (x132 + x105); + x135 = (x134 >> 26); + x136 = (uint32_t)(x134 & UINT32_C(0x3ffffff)); + x137 = (x135 + x104); + x138 = (x137 >> 25); + x139 = (uint32_t)(x137 & UINT32_C(0x1ffffff)); + x140 = (x138 * UINT8_C(0x13)); + x141 = (x103 + x140); + x142 = (uint32_t)(x141 >> 26); + x143 = (uint32_t)(x141 & UINT32_C(0x3ffffff)); + x144 = (x142 + x115); + x145 = (fiat_25519_uint1)(x144 >> 25); + x146 = (x144 & UINT32_C(0x1ffffff)); + x147 = (x145 + x118); out1[0] = x143; out1[1] = x146; out1[2] = x147; @@ -303,135 +486,252 @@ static void fiat_25519_carry_mul(uint32_t out1[10], const uint32_t arg1[10], con /* * The function fiat_25519_carry_square squares a field element and reduces the result. + * * Postconditions: * eval out1 mod m = (eval arg1 * eval arg1) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] - * Output Bounds: - * out1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] */ -static void fiat_25519_carry_square(uint32_t out1[10], const uint32_t arg1[10]) { - uint32_t x1 = ((arg1[9]) * UINT8_C(0x13)); - uint32_t x2 = (x1 * 0x2); - uint32_t x3 = ((arg1[9]) * 0x2); - uint32_t x4 = ((arg1[8]) * UINT8_C(0x13)); - uint64_t x5 = ((uint64_t)x4 * 0x2); - uint32_t x6 = ((arg1[8]) * 0x2); - uint32_t x7 = ((arg1[7]) * UINT8_C(0x13)); - uint32_t x8 = (x7 * 0x2); - uint32_t x9 = ((arg1[7]) * 0x2); - uint32_t x10 = ((arg1[6]) * UINT8_C(0x13)); - uint64_t x11 = ((uint64_t)x10 * 0x2); - uint32_t x12 = ((arg1[6]) * 0x2); - uint32_t x13 = ((arg1[5]) * UINT8_C(0x13)); - uint32_t x14 = ((arg1[5]) * 0x2); - uint32_t x15 = ((arg1[4]) * 0x2); - uint32_t x16 = ((arg1[3]) * 0x2); - uint32_t x17 = ((arg1[2]) * 0x2); - uint32_t x18 = ((arg1[1]) * 0x2); - uint64_t x19 = ((uint64_t)(arg1[9]) * (x1 * 0x2)); - uint64_t x20 = ((uint64_t)(arg1[8]) * x2); - uint64_t x21 = ((uint64_t)(arg1[8]) * x4); - uint64_t x22 = ((arg1[7]) * ((uint64_t)x2 * 0x2)); - uint64_t x23 = ((arg1[7]) * x5); - uint64_t x24 = ((uint64_t)(arg1[7]) * (x7 * 0x2)); - uint64_t x25 = ((uint64_t)(arg1[6]) * x2); - uint64_t x26 = ((arg1[6]) * x5); - uint64_t x27 = ((uint64_t)(arg1[6]) * x8); - uint64_t x28 = ((uint64_t)(arg1[6]) * x10); - uint64_t x29 = ((arg1[5]) * ((uint64_t)x2 * 0x2)); - uint64_t x30 = ((arg1[5]) * x5); - uint64_t x31 = ((arg1[5]) * ((uint64_t)x8 * 0x2)); - uint64_t x32 = ((arg1[5]) * x11); - uint64_t x33 = ((uint64_t)(arg1[5]) * (x13 * 0x2)); - uint64_t x34 = ((uint64_t)(arg1[4]) * x2); - uint64_t x35 = ((arg1[4]) * x5); - uint64_t x36 = ((uint64_t)(arg1[4]) * x8); - uint64_t x37 = ((arg1[4]) * x11); - uint64_t x38 = ((uint64_t)(arg1[4]) * x14); - uint64_t x39 = ((uint64_t)(arg1[4]) * (arg1[4])); - uint64_t x40 = ((arg1[3]) * ((uint64_t)x2 * 0x2)); - uint64_t x41 = ((arg1[3]) * x5); - uint64_t x42 = ((arg1[3]) * ((uint64_t)x8 * 0x2)); - uint64_t x43 = ((uint64_t)(arg1[3]) * x12); - uint64_t x44 = ((uint64_t)(arg1[3]) * (x14 * 0x2)); - uint64_t x45 = ((uint64_t)(arg1[3]) * x15); - uint64_t x46 = ((uint64_t)(arg1[3]) * ((arg1[3]) * 0x2)); - uint64_t x47 = ((uint64_t)(arg1[2]) * x2); - uint64_t x48 = ((arg1[2]) * x5); - uint64_t x49 = ((uint64_t)(arg1[2]) * x9); - uint64_t x50 = ((uint64_t)(arg1[2]) * x12); - uint64_t x51 = ((uint64_t)(arg1[2]) * x14); - uint64_t x52 = ((uint64_t)(arg1[2]) * x15); - uint64_t x53 = ((uint64_t)(arg1[2]) * x16); - uint64_t x54 = ((uint64_t)(arg1[2]) * (arg1[2])); - uint64_t x55 = ((arg1[1]) * ((uint64_t)x2 * 0x2)); - uint64_t x56 = ((uint64_t)(arg1[1]) * x6); - uint64_t x57 = ((uint64_t)(arg1[1]) * (x9 * 0x2)); - uint64_t x58 = ((uint64_t)(arg1[1]) * x12); - uint64_t x59 = ((uint64_t)(arg1[1]) * (x14 * 0x2)); - uint64_t x60 = ((uint64_t)(arg1[1]) * x15); - uint64_t x61 = ((uint64_t)(arg1[1]) * (x16 * 0x2)); - uint64_t x62 = ((uint64_t)(arg1[1]) * x17); - uint64_t x63 = ((uint64_t)(arg1[1]) * ((arg1[1]) * 0x2)); - uint64_t x64 = ((uint64_t)(arg1[0]) * x3); - uint64_t x65 = ((uint64_t)(arg1[0]) * x6); - uint64_t x66 = ((uint64_t)(arg1[0]) * x9); - uint64_t x67 = ((uint64_t)(arg1[0]) * x12); - uint64_t x68 = ((uint64_t)(arg1[0]) * x14); - uint64_t x69 = ((uint64_t)(arg1[0]) * x15); - uint64_t x70 = ((uint64_t)(arg1[0]) * x16); - uint64_t x71 = ((uint64_t)(arg1[0]) * x17); - uint64_t x72 = ((uint64_t)(arg1[0]) * x18); - uint64_t x73 = ((uint64_t)(arg1[0]) * (arg1[0])); - uint64_t x74 = (x73 + (x55 + (x48 + (x42 + (x37 + x33))))); - uint64_t x75 = (x74 >> 26); - uint32_t x76 = (uint32_t)(x74 & UINT32_C(0x3ffffff)); - uint64_t x77 = (x64 + (x56 + (x49 + (x43 + x38)))); - uint64_t x78 = (x65 + (x57 + (x50 + (x44 + (x39 + x19))))); - uint64_t x79 = (x66 + (x58 + (x51 + (x45 + x20)))); - uint64_t x80 = (x67 + (x59 + (x52 + (x46 + (x22 + x21))))); - uint64_t x81 = (x68 + (x60 + (x53 + (x25 + x23)))); - uint64_t x82 = (x69 + (x61 + (x54 + (x29 + (x26 + x24))))); - uint64_t x83 = (x70 + (x62 + (x34 + (x30 + x27)))); - uint64_t x84 = (x71 + (x63 + (x40 + (x35 + (x31 + x28))))); - uint64_t x85 = (x72 + (x47 + (x41 + (x36 + x32)))); - uint64_t x86 = (x75 + x85); - uint64_t x87 = (x86 >> 25); - uint32_t x88 = (uint32_t)(x86 & UINT32_C(0x1ffffff)); - uint64_t x89 = (x87 + x84); - uint64_t x90 = (x89 >> 26); - uint32_t x91 = (uint32_t)(x89 & UINT32_C(0x3ffffff)); - uint64_t x92 = (x90 + x83); - uint64_t x93 = (x92 >> 25); - uint32_t x94 = (uint32_t)(x92 & UINT32_C(0x1ffffff)); - uint64_t x95 = (x93 + x82); - uint64_t x96 = (x95 >> 26); - uint32_t x97 = (uint32_t)(x95 & UINT32_C(0x3ffffff)); - uint64_t x98 = (x96 + x81); - uint64_t x99 = (x98 >> 25); - uint32_t x100 = (uint32_t)(x98 & UINT32_C(0x1ffffff)); - uint64_t x101 = (x99 + x80); - uint64_t x102 = (x101 >> 26); - uint32_t x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); - uint64_t x104 = (x102 + x79); - uint64_t x105 = (x104 >> 25); - uint32_t x106 = (uint32_t)(x104 & UINT32_C(0x1ffffff)); - uint64_t x107 = (x105 + x78); - uint64_t x108 = (x107 >> 26); - uint32_t x109 = (uint32_t)(x107 & UINT32_C(0x3ffffff)); - uint64_t x110 = (x108 + x77); - uint64_t x111 = (x110 >> 25); - uint32_t x112 = (uint32_t)(x110 & UINT32_C(0x1ffffff)); - uint64_t x113 = (x111 * UINT8_C(0x13)); - uint64_t x114 = (x76 + x113); - uint32_t x115 = (uint32_t)(x114 >> 26); - uint32_t x116 = (uint32_t)(x114 & UINT32_C(0x3ffffff)); - uint32_t x117 = (x115 + x88); - fiat_25519_uint1 x118 = (fiat_25519_uint1)(x117 >> 25); - uint32_t x119 = (x117 & UINT32_C(0x1ffffff)); - uint32_t x120 = (x118 + x91); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_square(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint64_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint64_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + uint64_t x74; + uint64_t x75; + uint32_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint32_t x88; + uint64_t x89; + uint64_t x90; + uint32_t x91; + uint64_t x92; + uint64_t x93; + uint32_t x94; + uint64_t x95; + uint64_t x96; + uint32_t x97; + uint64_t x98; + uint64_t x99; + uint32_t x100; + uint64_t x101; + uint64_t x102; + uint32_t x103; + uint64_t x104; + uint64_t x105; + uint32_t x106; + uint64_t x107; + uint64_t x108; + uint32_t x109; + uint64_t x110; + uint64_t x111; + uint32_t x112; + uint64_t x113; + uint64_t x114; + uint32_t x115; + uint32_t x116; + uint32_t x117; + fiat_25519_uint1 x118; + uint32_t x119; + uint32_t x120; + x1 = ((arg1[9]) * UINT8_C(0x13)); + x2 = (x1 * 0x2); + x3 = ((arg1[9]) * 0x2); + x4 = ((arg1[8]) * UINT8_C(0x13)); + x5 = ((uint64_t)x4 * 0x2); + x6 = ((arg1[8]) * 0x2); + x7 = ((arg1[7]) * UINT8_C(0x13)); + x8 = (x7 * 0x2); + x9 = ((arg1[7]) * 0x2); + x10 = ((arg1[6]) * UINT8_C(0x13)); + x11 = ((uint64_t)x10 * 0x2); + x12 = ((arg1[6]) * 0x2); + x13 = ((arg1[5]) * UINT8_C(0x13)); + x14 = ((arg1[5]) * 0x2); + x15 = ((arg1[4]) * 0x2); + x16 = ((arg1[3]) * 0x2); + x17 = ((arg1[2]) * 0x2); + x18 = ((arg1[1]) * 0x2); + x19 = ((uint64_t)(arg1[9]) * (x1 * 0x2)); + x20 = ((uint64_t)(arg1[8]) * x2); + x21 = ((uint64_t)(arg1[8]) * x4); + x22 = ((arg1[7]) * ((uint64_t)x2 * 0x2)); + x23 = ((arg1[7]) * x5); + x24 = ((uint64_t)(arg1[7]) * (x7 * 0x2)); + x25 = ((uint64_t)(arg1[6]) * x2); + x26 = ((arg1[6]) * x5); + x27 = ((uint64_t)(arg1[6]) * x8); + x28 = ((uint64_t)(arg1[6]) * x10); + x29 = ((arg1[5]) * ((uint64_t)x2 * 0x2)); + x30 = ((arg1[5]) * x5); + x31 = ((arg1[5]) * ((uint64_t)x8 * 0x2)); + x32 = ((arg1[5]) * x11); + x33 = ((uint64_t)(arg1[5]) * (x13 * 0x2)); + x34 = ((uint64_t)(arg1[4]) * x2); + x35 = ((arg1[4]) * x5); + x36 = ((uint64_t)(arg1[4]) * x8); + x37 = ((arg1[4]) * x11); + x38 = ((uint64_t)(arg1[4]) * x14); + x39 = ((uint64_t)(arg1[4]) * (arg1[4])); + x40 = ((arg1[3]) * ((uint64_t)x2 * 0x2)); + x41 = ((arg1[3]) * x5); + x42 = ((arg1[3]) * ((uint64_t)x8 * 0x2)); + x43 = ((uint64_t)(arg1[3]) * x12); + x44 = ((uint64_t)(arg1[3]) * (x14 * 0x2)); + x45 = ((uint64_t)(arg1[3]) * x15); + x46 = ((uint64_t)(arg1[3]) * ((arg1[3]) * 0x2)); + x47 = ((uint64_t)(arg1[2]) * x2); + x48 = ((arg1[2]) * x5); + x49 = ((uint64_t)(arg1[2]) * x9); + x50 = ((uint64_t)(arg1[2]) * x12); + x51 = ((uint64_t)(arg1[2]) * x14); + x52 = ((uint64_t)(arg1[2]) * x15); + x53 = ((uint64_t)(arg1[2]) * x16); + x54 = ((uint64_t)(arg1[2]) * (arg1[2])); + x55 = ((arg1[1]) * ((uint64_t)x2 * 0x2)); + x56 = ((uint64_t)(arg1[1]) * x6); + x57 = ((uint64_t)(arg1[1]) * (x9 * 0x2)); + x58 = ((uint64_t)(arg1[1]) * x12); + x59 = ((uint64_t)(arg1[1]) * (x14 * 0x2)); + x60 = ((uint64_t)(arg1[1]) * x15); + x61 = ((uint64_t)(arg1[1]) * (x16 * 0x2)); + x62 = ((uint64_t)(arg1[1]) * x17); + x63 = ((uint64_t)(arg1[1]) * ((arg1[1]) * 0x2)); + x64 = ((uint64_t)(arg1[0]) * x3); + x65 = ((uint64_t)(arg1[0]) * x6); + x66 = ((uint64_t)(arg1[0]) * x9); + x67 = ((uint64_t)(arg1[0]) * x12); + x68 = ((uint64_t)(arg1[0]) * x14); + x69 = ((uint64_t)(arg1[0]) * x15); + x70 = ((uint64_t)(arg1[0]) * x16); + x71 = ((uint64_t)(arg1[0]) * x17); + x72 = ((uint64_t)(arg1[0]) * x18); + x73 = ((uint64_t)(arg1[0]) * (arg1[0])); + x74 = (x73 + (x55 + (x48 + (x42 + (x37 + x33))))); + x75 = (x74 >> 26); + x76 = (uint32_t)(x74 & UINT32_C(0x3ffffff)); + x77 = (x64 + (x56 + (x49 + (x43 + x38)))); + x78 = (x65 + (x57 + (x50 + (x44 + (x39 + x19))))); + x79 = (x66 + (x58 + (x51 + (x45 + x20)))); + x80 = (x67 + (x59 + (x52 + (x46 + (x22 + x21))))); + x81 = (x68 + (x60 + (x53 + (x25 + x23)))); + x82 = (x69 + (x61 + (x54 + (x29 + (x26 + x24))))); + x83 = (x70 + (x62 + (x34 + (x30 + x27)))); + x84 = (x71 + (x63 + (x40 + (x35 + (x31 + x28))))); + x85 = (x72 + (x47 + (x41 + (x36 + x32)))); + x86 = (x75 + x85); + x87 = (x86 >> 25); + x88 = (uint32_t)(x86 & UINT32_C(0x1ffffff)); + x89 = (x87 + x84); + x90 = (x89 >> 26); + x91 = (uint32_t)(x89 & UINT32_C(0x3ffffff)); + x92 = (x90 + x83); + x93 = (x92 >> 25); + x94 = (uint32_t)(x92 & UINT32_C(0x1ffffff)); + x95 = (x93 + x82); + x96 = (x95 >> 26); + x97 = (uint32_t)(x95 & UINT32_C(0x3ffffff)); + x98 = (x96 + x81); + x99 = (x98 >> 25); + x100 = (uint32_t)(x98 & UINT32_C(0x1ffffff)); + x101 = (x99 + x80); + x102 = (x101 >> 26); + x103 = (uint32_t)(x101 & UINT32_C(0x3ffffff)); + x104 = (x102 + x79); + x105 = (x104 >> 25); + x106 = (uint32_t)(x104 & UINT32_C(0x1ffffff)); + x107 = (x105 + x78); + x108 = (x107 >> 26); + x109 = (uint32_t)(x107 & UINT32_C(0x3ffffff)); + x110 = (x108 + x77); + x111 = (x110 >> 25); + x112 = (uint32_t)(x110 & UINT32_C(0x1ffffff)); + x113 = (x111 * UINT8_C(0x13)); + x114 = (x76 + x113); + x115 = (uint32_t)(x114 >> 26); + x116 = (uint32_t)(x114 & UINT32_C(0x3ffffff)); + x117 = (x115 + x88); + x118 = (fiat_25519_uint1)(x117 >> 25); + x119 = (x117 & UINT32_C(0x1ffffff)); + x120 = (x118 + x91); out1[0] = x116; out1[1] = x119; out1[2] = x120; @@ -446,37 +746,56 @@ static void fiat_25519_carry_square(uint32_t out1[10], const uint32_t arg1[10]) /* * The function fiat_25519_carry reduces a field element. + * * Postconditions: * eval out1 mod m = eval arg1 mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] - * Output Bounds: - * out1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] */ -static void fiat_25519_carry(uint32_t out1[10], const uint32_t arg1[10]) { - uint32_t x1 = (arg1[0]); - uint32_t x2 = ((x1 >> 26) + (arg1[1])); - uint32_t x3 = ((x2 >> 25) + (arg1[2])); - uint32_t x4 = ((x3 >> 26) + (arg1[3])); - uint32_t x5 = ((x4 >> 25) + (arg1[4])); - uint32_t x6 = ((x5 >> 26) + (arg1[5])); - uint32_t x7 = ((x6 >> 25) + (arg1[6])); - uint32_t x8 = ((x7 >> 26) + (arg1[7])); - uint32_t x9 = ((x8 >> 25) + (arg1[8])); - uint32_t x10 = ((x9 >> 26) + (arg1[9])); - uint32_t x11 = ((x1 & UINT32_C(0x3ffffff)) + ((x10 >> 25) * UINT8_C(0x13))); - uint32_t x12 = ((fiat_25519_uint1)(x11 >> 26) + (x2 & UINT32_C(0x1ffffff))); - uint32_t x13 = (x11 & UINT32_C(0x3ffffff)); - uint32_t x14 = (x12 & UINT32_C(0x1ffffff)); - uint32_t x15 = ((fiat_25519_uint1)(x12 >> 25) + (x3 & UINT32_C(0x3ffffff))); - uint32_t x16 = (x4 & UINT32_C(0x1ffffff)); - uint32_t x17 = (x5 & UINT32_C(0x3ffffff)); - uint32_t x18 = (x6 & UINT32_C(0x1ffffff)); - uint32_t x19 = (x7 & UINT32_C(0x3ffffff)); - uint32_t x20 = (x8 & UINT32_C(0x1ffffff)); - uint32_t x21 = (x9 & UINT32_C(0x3ffffff)); - uint32_t x22 = (x10 & UINT32_C(0x1ffffff)); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + x1 = (arg1[0]); + x2 = ((x1 >> 26) + (arg1[1])); + x3 = ((x2 >> 25) + (arg1[2])); + x4 = ((x3 >> 26) + (arg1[3])); + x5 = ((x4 >> 25) + (arg1[4])); + x6 = ((x5 >> 26) + (arg1[5])); + x7 = ((x6 >> 25) + (arg1[6])); + x8 = ((x7 >> 26) + (arg1[7])); + x9 = ((x8 >> 25) + (arg1[8])); + x10 = ((x9 >> 26) + (arg1[9])); + x11 = ((x1 & UINT32_C(0x3ffffff)) + ((x10 >> 25) * UINT8_C(0x13))); + x12 = ((fiat_25519_uint1)(x11 >> 26) + (x2 & UINT32_C(0x1ffffff))); + x13 = (x11 & UINT32_C(0x3ffffff)); + x14 = (x12 & UINT32_C(0x1ffffff)); + x15 = ((fiat_25519_uint1)(x12 >> 25) + (x3 & UINT32_C(0x3ffffff))); + x16 = (x4 & UINT32_C(0x1ffffff)); + x17 = (x5 & UINT32_C(0x3ffffff)); + x18 = (x6 & UINT32_C(0x1ffffff)); + x19 = (x7 & UINT32_C(0x3ffffff)); + x20 = (x8 & UINT32_C(0x1ffffff)); + x21 = (x9 & UINT32_C(0x3ffffff)); + x22 = (x10 & UINT32_C(0x1ffffff)); out1[0] = x13; out1[1] = x14; out1[2] = x15; @@ -491,26 +810,32 @@ static void fiat_25519_carry(uint32_t out1[10], const uint32_t arg1[10]) { /* * The function fiat_25519_add adds two field elements. + * * Postconditions: * eval out1 mod m = (eval arg1 + eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] - * arg2: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] - * Output Bounds: - * out1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] */ -static void fiat_25519_add(uint32_t out1[10], const uint32_t arg1[10], const uint32_t arg2[10]) { - uint32_t x1 = ((arg1[0]) + (arg2[0])); - uint32_t x2 = ((arg1[1]) + (arg2[1])); - uint32_t x3 = ((arg1[2]) + (arg2[2])); - uint32_t x4 = ((arg1[3]) + (arg2[3])); - uint32_t x5 = ((arg1[4]) + (arg2[4])); - uint32_t x6 = ((arg1[5]) + (arg2[5])); - uint32_t x7 = ((arg1[6]) + (arg2[6])); - uint32_t x8 = ((arg1[7]) + (arg2[7])); - uint32_t x9 = ((arg1[8]) + (arg2[8])); - uint32_t x10 = ((arg1[9]) + (arg2[9])); +static FIAT_25519_FIAT_INLINE void fiat_25519_add(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = ((arg1[0]) + (arg2[0])); + x2 = ((arg1[1]) + (arg2[1])); + x3 = ((arg1[2]) + (arg2[2])); + x4 = ((arg1[3]) + (arg2[3])); + x5 = ((arg1[4]) + (arg2[4])); + x6 = ((arg1[5]) + (arg2[5])); + x7 = ((arg1[6]) + (arg2[6])); + x8 = ((arg1[7]) + (arg2[7])); + x9 = ((arg1[8]) + (arg2[8])); + x10 = ((arg1[9]) + (arg2[9])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -525,26 +850,32 @@ static void fiat_25519_add(uint32_t out1[10], const uint32_t arg1[10], const uin /* * The function fiat_25519_sub subtracts two field elements. + * * Postconditions: * eval out1 mod m = (eval arg1 - eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] - * arg2: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] - * Output Bounds: - * out1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] */ -static void fiat_25519_sub(uint32_t out1[10], const uint32_t arg1[10], const uint32_t arg2[10]) { - uint32_t x1 = ((UINT32_C(0x7ffffda) + (arg1[0])) - (arg2[0])); - uint32_t x2 = ((UINT32_C(0x3fffffe) + (arg1[1])) - (arg2[1])); - uint32_t x3 = ((UINT32_C(0x7fffffe) + (arg1[2])) - (arg2[2])); - uint32_t x4 = ((UINT32_C(0x3fffffe) + (arg1[3])) - (arg2[3])); - uint32_t x5 = ((UINT32_C(0x7fffffe) + (arg1[4])) - (arg2[4])); - uint32_t x6 = ((UINT32_C(0x3fffffe) + (arg1[5])) - (arg2[5])); - uint32_t x7 = ((UINT32_C(0x7fffffe) + (arg1[6])) - (arg2[6])); - uint32_t x8 = ((UINT32_C(0x3fffffe) + (arg1[7])) - (arg2[7])); - uint32_t x9 = ((UINT32_C(0x7fffffe) + (arg1[8])) - (arg2[8])); - uint32_t x10 = ((UINT32_C(0x3fffffe) + (arg1[9])) - (arg2[9])); +static FIAT_25519_FIAT_INLINE void fiat_25519_sub(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = ((UINT32_C(0x7ffffda) + (arg1[0])) - (arg2[0])); + x2 = ((UINT32_C(0x3fffffe) + (arg1[1])) - (arg2[1])); + x3 = ((UINT32_C(0x7fffffe) + (arg1[2])) - (arg2[2])); + x4 = ((UINT32_C(0x3fffffe) + (arg1[3])) - (arg2[3])); + x5 = ((UINT32_C(0x7fffffe) + (arg1[4])) - (arg2[4])); + x6 = ((UINT32_C(0x3fffffe) + (arg1[5])) - (arg2[5])); + x7 = ((UINT32_C(0x7fffffe) + (arg1[6])) - (arg2[6])); + x8 = ((UINT32_C(0x3fffffe) + (arg1[7])) - (arg2[7])); + x9 = ((UINT32_C(0x7fffffe) + (arg1[8])) - (arg2[8])); + x10 = ((UINT32_C(0x3fffffe) + (arg1[9])) - (arg2[9])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -559,25 +890,32 @@ static void fiat_25519_sub(uint32_t out1[10], const uint32_t arg1[10], const uin /* * The function fiat_25519_opp negates a field element. + * * Postconditions: * eval out1 mod m = -eval arg1 mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] - * Output Bounds: - * out1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] */ -static void fiat_25519_opp(uint32_t out1[10], const uint32_t arg1[10]) { - uint32_t x1 = (UINT32_C(0x7ffffda) - (arg1[0])); - uint32_t x2 = (UINT32_C(0x3fffffe) - (arg1[1])); - uint32_t x3 = (UINT32_C(0x7fffffe) - (arg1[2])); - uint32_t x4 = (UINT32_C(0x3fffffe) - (arg1[3])); - uint32_t x5 = (UINT32_C(0x7fffffe) - (arg1[4])); - uint32_t x6 = (UINT32_C(0x3fffffe) - (arg1[5])); - uint32_t x7 = (UINT32_C(0x7fffffe) - (arg1[6])); - uint32_t x8 = (UINT32_C(0x3fffffe) - (arg1[7])); - uint32_t x9 = (UINT32_C(0x7fffffe) - (arg1[8])); - uint32_t x10 = (UINT32_C(0x3fffffe) - (arg1[9])); +static FIAT_25519_FIAT_INLINE void fiat_25519_opp(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = (UINT32_C(0x7ffffda) - (arg1[0])); + x2 = (UINT32_C(0x3fffffe) - (arg1[1])); + x3 = (UINT32_C(0x7fffffe) - (arg1[2])); + x4 = (UINT32_C(0x3fffffe) - (arg1[3])); + x5 = (UINT32_C(0x7fffffe) - (arg1[4])); + x6 = (UINT32_C(0x3fffffe) - (arg1[5])); + x7 = (UINT32_C(0x7fffffe) - (arg1[6])); + x8 = (UINT32_C(0x3fffffe) - (arg1[7])); + x9 = (UINT32_C(0x7fffffe) - (arg1[8])); + x10 = (UINT32_C(0x3fffffe) - (arg1[9])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -592,6 +930,7 @@ static void fiat_25519_opp(uint32_t out1[10], const uint32_t arg1[10]) { /* * The function fiat_25519_selectznz is a multi-limb conditional select. + * * Postconditions: * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) * @@ -602,26 +941,26 @@ static void fiat_25519_opp(uint32_t out1[10], const uint32_t arg1[10]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_25519_selectznz(uint32_t out1[10], fiat_25519_uint1 arg1, const uint32_t arg2[10], const uint32_t arg3[10]) { +static FIAT_25519_FIAT_INLINE void fiat_25519_selectznz(uint32_t out1[10], fiat_25519_uint1 arg1, const uint32_t arg2[10], const uint32_t arg3[10]) { uint32_t x1; - fiat_25519_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); uint32_t x2; - fiat_25519_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); uint32_t x3; - fiat_25519_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); uint32_t x4; - fiat_25519_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); uint32_t x5; - fiat_25519_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); uint32_t x6; - fiat_25519_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); uint32_t x7; - fiat_25519_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); uint32_t x8; - fiat_25519_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); uint32_t x9; - fiat_25519_cmovznz_u32(&x9, arg1, (arg2[8]), (arg3[8])); uint32_t x10; + fiat_25519_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_25519_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_25519_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_25519_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_25519_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); + fiat_25519_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); + fiat_25519_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); + fiat_25519_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); + fiat_25519_cmovznz_u32(&x9, arg1, (arg2[8]), (arg3[8])); fiat_25519_cmovznz_u32(&x10, arg1, (arg2[9]), (arg3[9])); out1[0] = x1; out1[1] = x2; @@ -637,336 +976,582 @@ static void fiat_25519_selectznz(uint32_t out1[10], fiat_25519_uint1 arg1, const /* * The function fiat_25519_to_bytes serializes a field element to bytes in little-endian order. + * * Postconditions: * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] * - * Input Bounds: - * arg1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] * Output Bounds: * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] */ -static void fiat_25519_to_bytes(uint8_t out1[32], const uint32_t arg1[10]) { +static FIAT_25519_FIAT_INLINE void fiat_25519_to_bytes(uint8_t out1[32], const fiat_25519_tight_field_element arg1) { uint32_t x1; fiat_25519_uint1 x2; - fiat_25519_subborrowx_u26(&x1, &x2, 0x0, (arg1[0]), UINT32_C(0x3ffffed)); uint32_t x3; fiat_25519_uint1 x4; - fiat_25519_subborrowx_u25(&x3, &x4, x2, (arg1[1]), UINT32_C(0x1ffffff)); uint32_t x5; fiat_25519_uint1 x6; - fiat_25519_subborrowx_u26(&x5, &x6, x4, (arg1[2]), UINT32_C(0x3ffffff)); uint32_t x7; fiat_25519_uint1 x8; - fiat_25519_subborrowx_u25(&x7, &x8, x6, (arg1[3]), UINT32_C(0x1ffffff)); uint32_t x9; fiat_25519_uint1 x10; - fiat_25519_subborrowx_u26(&x9, &x10, x8, (arg1[4]), UINT32_C(0x3ffffff)); uint32_t x11; fiat_25519_uint1 x12; - fiat_25519_subborrowx_u25(&x11, &x12, x10, (arg1[5]), UINT32_C(0x1ffffff)); uint32_t x13; fiat_25519_uint1 x14; - fiat_25519_subborrowx_u26(&x13, &x14, x12, (arg1[6]), UINT32_C(0x3ffffff)); uint32_t x15; fiat_25519_uint1 x16; - fiat_25519_subborrowx_u25(&x15, &x16, x14, (arg1[7]), UINT32_C(0x1ffffff)); uint32_t x17; fiat_25519_uint1 x18; - fiat_25519_subborrowx_u26(&x17, &x18, x16, (arg1[8]), UINT32_C(0x3ffffff)); uint32_t x19; fiat_25519_uint1 x20; - fiat_25519_subborrowx_u25(&x19, &x20, x18, (arg1[9]), UINT32_C(0x1ffffff)); uint32_t x21; - fiat_25519_cmovznz_u32(&x21, x20, 0x0, UINT32_C(0xffffffff)); uint32_t x22; fiat_25519_uint1 x23; - fiat_25519_addcarryx_u26(&x22, &x23, 0x0, x1, (x21 & UINT32_C(0x3ffffed))); uint32_t x24; fiat_25519_uint1 x25; - fiat_25519_addcarryx_u25(&x24, &x25, x23, x3, (x21 & UINT32_C(0x1ffffff))); uint32_t x26; fiat_25519_uint1 x27; - fiat_25519_addcarryx_u26(&x26, &x27, x25, x5, (x21 & UINT32_C(0x3ffffff))); uint32_t x28; fiat_25519_uint1 x29; - fiat_25519_addcarryx_u25(&x28, &x29, x27, x7, (x21 & UINT32_C(0x1ffffff))); uint32_t x30; fiat_25519_uint1 x31; - fiat_25519_addcarryx_u26(&x30, &x31, x29, x9, (x21 & UINT32_C(0x3ffffff))); uint32_t x32; fiat_25519_uint1 x33; - fiat_25519_addcarryx_u25(&x32, &x33, x31, x11, (x21 & UINT32_C(0x1ffffff))); uint32_t x34; fiat_25519_uint1 x35; - fiat_25519_addcarryx_u26(&x34, &x35, x33, x13, (x21 & UINT32_C(0x3ffffff))); uint32_t x36; fiat_25519_uint1 x37; - fiat_25519_addcarryx_u25(&x36, &x37, x35, x15, (x21 & UINT32_C(0x1ffffff))); uint32_t x38; fiat_25519_uint1 x39; - fiat_25519_addcarryx_u26(&x38, &x39, x37, x17, (x21 & UINT32_C(0x3ffffff))); uint32_t x40; fiat_25519_uint1 x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint8_t x50; + uint32_t x51; + uint8_t x52; + uint32_t x53; + uint8_t x54; + uint8_t x55; + uint32_t x56; + uint8_t x57; + uint32_t x58; + uint8_t x59; + uint32_t x60; + uint8_t x61; + uint8_t x62; + uint32_t x63; + uint8_t x64; + uint32_t x65; + uint8_t x66; + uint32_t x67; + uint8_t x68; + uint8_t x69; + uint32_t x70; + uint8_t x71; + uint32_t x72; + uint8_t x73; + uint32_t x74; + uint8_t x75; + uint8_t x76; + uint32_t x77; + uint8_t x78; + uint32_t x79; + uint8_t x80; + uint32_t x81; + uint8_t x82; + uint8_t x83; + uint8_t x84; + uint32_t x85; + uint8_t x86; + uint32_t x87; + uint8_t x88; + fiat_25519_uint1 x89; + uint32_t x90; + uint8_t x91; + uint32_t x92; + uint8_t x93; + uint32_t x94; + uint8_t x95; + uint8_t x96; + uint32_t x97; + uint8_t x98; + uint32_t x99; + uint8_t x100; + uint32_t x101; + uint8_t x102; + uint8_t x103; + uint32_t x104; + uint8_t x105; + uint32_t x106; + uint8_t x107; + uint32_t x108; + uint8_t x109; + uint8_t x110; + uint32_t x111; + uint8_t x112; + uint32_t x113; + uint8_t x114; + uint32_t x115; + uint8_t x116; + uint8_t x117; + fiat_25519_subborrowx_u26(&x1, &x2, 0x0, (arg1[0]), UINT32_C(0x3ffffed)); + fiat_25519_subborrowx_u25(&x3, &x4, x2, (arg1[1]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x5, &x6, x4, (arg1[2]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x7, &x8, x6, (arg1[3]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x9, &x10, x8, (arg1[4]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x11, &x12, x10, (arg1[5]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x13, &x14, x12, (arg1[6]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x15, &x16, x14, (arg1[7]), UINT32_C(0x1ffffff)); + fiat_25519_subborrowx_u26(&x17, &x18, x16, (arg1[8]), UINT32_C(0x3ffffff)); + fiat_25519_subborrowx_u25(&x19, &x20, x18, (arg1[9]), UINT32_C(0x1ffffff)); + fiat_25519_cmovznz_u32(&x21, x20, 0x0, UINT32_C(0xffffffff)); + fiat_25519_addcarryx_u26(&x22, &x23, 0x0, x1, (x21 & UINT32_C(0x3ffffed))); + fiat_25519_addcarryx_u25(&x24, &x25, x23, x3, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x26, &x27, x25, x5, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x28, &x29, x27, x7, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x30, &x31, x29, x9, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x32, &x33, x31, x11, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x34, &x35, x33, x13, (x21 & UINT32_C(0x3ffffff))); + fiat_25519_addcarryx_u25(&x36, &x37, x35, x15, (x21 & UINT32_C(0x1ffffff))); + fiat_25519_addcarryx_u26(&x38, &x39, x37, x17, (x21 & UINT32_C(0x3ffffff))); fiat_25519_addcarryx_u25(&x40, &x41, x39, x19, (x21 & UINT32_C(0x1ffffff))); - uint32_t x42 = (x40 << 6); - uint32_t x43 = (x38 << 4); - uint32_t x44 = (x36 << 3); - uint32_t x45 = (x34 * (uint32_t)0x2); - uint32_t x46 = (x30 << 6); - uint32_t x47 = (x28 << 5); - uint32_t x48 = (x26 << 3); - uint32_t x49 = (x24 << 2); - uint32_t x50 = (x22 >> 8); - uint8_t x51 = (uint8_t)(x22 & UINT8_C(0xff)); - uint32_t x52 = (x50 >> 8); - uint8_t x53 = (uint8_t)(x50 & UINT8_C(0xff)); - uint8_t x54 = (uint8_t)(x52 >> 8); - uint8_t x55 = (uint8_t)(x52 & UINT8_C(0xff)); - uint32_t x56 = (x54 + x49); - uint32_t x57 = (x56 >> 8); - uint8_t x58 = (uint8_t)(x56 & UINT8_C(0xff)); - uint32_t x59 = (x57 >> 8); - uint8_t x60 = (uint8_t)(x57 & UINT8_C(0xff)); - uint8_t x61 = (uint8_t)(x59 >> 8); - uint8_t x62 = (uint8_t)(x59 & UINT8_C(0xff)); - uint32_t x63 = (x61 + x48); - uint32_t x64 = (x63 >> 8); - uint8_t x65 = (uint8_t)(x63 & UINT8_C(0xff)); - uint32_t x66 = (x64 >> 8); - uint8_t x67 = (uint8_t)(x64 & UINT8_C(0xff)); - uint8_t x68 = (uint8_t)(x66 >> 8); - uint8_t x69 = (uint8_t)(x66 & UINT8_C(0xff)); - uint32_t x70 = (x68 + x47); - uint32_t x71 = (x70 >> 8); - uint8_t x72 = (uint8_t)(x70 & UINT8_C(0xff)); - uint32_t x73 = (x71 >> 8); - uint8_t x74 = (uint8_t)(x71 & UINT8_C(0xff)); - uint8_t x75 = (uint8_t)(x73 >> 8); - uint8_t x76 = (uint8_t)(x73 & UINT8_C(0xff)); - uint32_t x77 = (x75 + x46); - uint32_t x78 = (x77 >> 8); - uint8_t x79 = (uint8_t)(x77 & UINT8_C(0xff)); - uint32_t x80 = (x78 >> 8); - uint8_t x81 = (uint8_t)(x78 & UINT8_C(0xff)); - uint8_t x82 = (uint8_t)(x80 >> 8); - uint8_t x83 = (uint8_t)(x80 & UINT8_C(0xff)); - uint8_t x84 = (uint8_t)(x82 & UINT8_C(0xff)); - uint32_t x85 = (x32 >> 8); - uint8_t x86 = (uint8_t)(x32 & UINT8_C(0xff)); - uint32_t x87 = (x85 >> 8); - uint8_t x88 = (uint8_t)(x85 & UINT8_C(0xff)); - fiat_25519_uint1 x89 = (fiat_25519_uint1)(x87 >> 8); - uint8_t x90 = (uint8_t)(x87 & UINT8_C(0xff)); - uint32_t x91 = (x89 + x45); - uint32_t x92 = (x91 >> 8); - uint8_t x93 = (uint8_t)(x91 & UINT8_C(0xff)); - uint32_t x94 = (x92 >> 8); - uint8_t x95 = (uint8_t)(x92 & UINT8_C(0xff)); - uint8_t x96 = (uint8_t)(x94 >> 8); - uint8_t x97 = (uint8_t)(x94 & UINT8_C(0xff)); - uint32_t x98 = (x96 + x44); - uint32_t x99 = (x98 >> 8); - uint8_t x100 = (uint8_t)(x98 & UINT8_C(0xff)); - uint32_t x101 = (x99 >> 8); - uint8_t x102 = (uint8_t)(x99 & UINT8_C(0xff)); - uint8_t x103 = (uint8_t)(x101 >> 8); - uint8_t x104 = (uint8_t)(x101 & UINT8_C(0xff)); - uint32_t x105 = (x103 + x43); - uint32_t x106 = (x105 >> 8); - uint8_t x107 = (uint8_t)(x105 & UINT8_C(0xff)); - uint32_t x108 = (x106 >> 8); - uint8_t x109 = (uint8_t)(x106 & UINT8_C(0xff)); - uint8_t x110 = (uint8_t)(x108 >> 8); - uint8_t x111 = (uint8_t)(x108 & UINT8_C(0xff)); - uint32_t x112 = (x110 + x42); - uint32_t x113 = (x112 >> 8); - uint8_t x114 = (uint8_t)(x112 & UINT8_C(0xff)); - uint32_t x115 = (x113 >> 8); - uint8_t x116 = (uint8_t)(x113 & UINT8_C(0xff)); - uint8_t x117 = (uint8_t)(x115 >> 8); - uint8_t x118 = (uint8_t)(x115 & UINT8_C(0xff)); - out1[0] = x51; - out1[1] = x53; - out1[2] = x55; - out1[3] = x58; - out1[4] = x60; - out1[5] = x62; - out1[6] = x65; - out1[7] = x67; - out1[8] = x69; - out1[9] = x72; - out1[10] = x74; - out1[11] = x76; - out1[12] = x79; - out1[13] = x81; - out1[14] = x83; - out1[15] = x84; - out1[16] = x86; - out1[17] = x88; - out1[18] = x90; - out1[19] = x93; - out1[20] = x95; - out1[21] = x97; - out1[22] = x100; - out1[23] = x102; - out1[24] = x104; - out1[25] = x107; - out1[26] = x109; - out1[27] = x111; - out1[28] = x114; - out1[29] = x116; - out1[30] = x118; + x42 = (x40 << 6); + x43 = (x38 << 4); + x44 = (x36 << 3); + x45 = (x34 * (uint32_t)0x2); + x46 = (x30 << 6); + x47 = (x28 << 5); + x48 = (x26 << 3); + x49 = (x24 << 2); + x50 = (uint8_t)(x22 & UINT8_C(0xff)); + x51 = (x22 >> 8); + x52 = (uint8_t)(x51 & UINT8_C(0xff)); + x53 = (x51 >> 8); + x54 = (uint8_t)(x53 & UINT8_C(0xff)); + x55 = (uint8_t)(x53 >> 8); + x56 = (x49 + (uint32_t)x55); + x57 = (uint8_t)(x56 & UINT8_C(0xff)); + x58 = (x56 >> 8); + x59 = (uint8_t)(x58 & UINT8_C(0xff)); + x60 = (x58 >> 8); + x61 = (uint8_t)(x60 & UINT8_C(0xff)); + x62 = (uint8_t)(x60 >> 8); + x63 = (x48 + (uint32_t)x62); + x64 = (uint8_t)(x63 & UINT8_C(0xff)); + x65 = (x63 >> 8); + x66 = (uint8_t)(x65 & UINT8_C(0xff)); + x67 = (x65 >> 8); + x68 = (uint8_t)(x67 & UINT8_C(0xff)); + x69 = (uint8_t)(x67 >> 8); + x70 = (x47 + (uint32_t)x69); + x71 = (uint8_t)(x70 & UINT8_C(0xff)); + x72 = (x70 >> 8); + x73 = (uint8_t)(x72 & UINT8_C(0xff)); + x74 = (x72 >> 8); + x75 = (uint8_t)(x74 & UINT8_C(0xff)); + x76 = (uint8_t)(x74 >> 8); + x77 = (x46 + (uint32_t)x76); + x78 = (uint8_t)(x77 & UINT8_C(0xff)); + x79 = (x77 >> 8); + x80 = (uint8_t)(x79 & UINT8_C(0xff)); + x81 = (x79 >> 8); + x82 = (uint8_t)(x81 & UINT8_C(0xff)); + x83 = (uint8_t)(x81 >> 8); + x84 = (uint8_t)(x32 & UINT8_C(0xff)); + x85 = (x32 >> 8); + x86 = (uint8_t)(x85 & UINT8_C(0xff)); + x87 = (x85 >> 8); + x88 = (uint8_t)(x87 & UINT8_C(0xff)); + x89 = (fiat_25519_uint1)(x87 >> 8); + x90 = (x45 + (uint32_t)x89); + x91 = (uint8_t)(x90 & UINT8_C(0xff)); + x92 = (x90 >> 8); + x93 = (uint8_t)(x92 & UINT8_C(0xff)); + x94 = (x92 >> 8); + x95 = (uint8_t)(x94 & UINT8_C(0xff)); + x96 = (uint8_t)(x94 >> 8); + x97 = (x44 + (uint32_t)x96); + x98 = (uint8_t)(x97 & UINT8_C(0xff)); + x99 = (x97 >> 8); + x100 = (uint8_t)(x99 & UINT8_C(0xff)); + x101 = (x99 >> 8); + x102 = (uint8_t)(x101 & UINT8_C(0xff)); + x103 = (uint8_t)(x101 >> 8); + x104 = (x43 + (uint32_t)x103); + x105 = (uint8_t)(x104 & UINT8_C(0xff)); + x106 = (x104 >> 8); + x107 = (uint8_t)(x106 & UINT8_C(0xff)); + x108 = (x106 >> 8); + x109 = (uint8_t)(x108 & UINT8_C(0xff)); + x110 = (uint8_t)(x108 >> 8); + x111 = (x42 + (uint32_t)x110); + x112 = (uint8_t)(x111 & UINT8_C(0xff)); + x113 = (x111 >> 8); + x114 = (uint8_t)(x113 & UINT8_C(0xff)); + x115 = (x113 >> 8); + x116 = (uint8_t)(x115 & UINT8_C(0xff)); + x117 = (uint8_t)(x115 >> 8); + out1[0] = x50; + out1[1] = x52; + out1[2] = x54; + out1[3] = x57; + out1[4] = x59; + out1[5] = x61; + out1[6] = x64; + out1[7] = x66; + out1[8] = x68; + out1[9] = x71; + out1[10] = x73; + out1[11] = x75; + out1[12] = x78; + out1[13] = x80; + out1[14] = x82; + out1[15] = x83; + out1[16] = x84; + out1[17] = x86; + out1[18] = x88; + out1[19] = x91; + out1[20] = x93; + out1[21] = x95; + out1[22] = x98; + out1[23] = x100; + out1[24] = x102; + out1[25] = x105; + out1[26] = x107; + out1[27] = x109; + out1[28] = x112; + out1[29] = x114; + out1[30] = x116; out1[31] = x117; } /* * The function fiat_25519_from_bytes deserializes a field element from bytes in little-endian order. + * * Postconditions: * eval out1 mod m = bytes_eval arg1 mod m * * Input Bounds: * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] - * Output Bounds: - * out1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] */ -static void fiat_25519_from_bytes(uint32_t out1[10], const uint8_t arg1[32]) { - uint32_t x1 = ((uint32_t)(arg1[31]) << 18); - uint32_t x2 = ((uint32_t)(arg1[30]) << 10); - uint32_t x3 = ((uint32_t)(arg1[29]) << 2); - uint32_t x4 = ((uint32_t)(arg1[28]) << 20); - uint32_t x5 = ((uint32_t)(arg1[27]) << 12); - uint32_t x6 = ((uint32_t)(arg1[26]) << 4); - uint32_t x7 = ((uint32_t)(arg1[25]) << 21); - uint32_t x8 = ((uint32_t)(arg1[24]) << 13); - uint32_t x9 = ((uint32_t)(arg1[23]) << 5); - uint32_t x10 = ((uint32_t)(arg1[22]) << 23); - uint32_t x11 = ((uint32_t)(arg1[21]) << 15); - uint32_t x12 = ((uint32_t)(arg1[20]) << 7); - uint32_t x13 = ((uint32_t)(arg1[19]) << 24); - uint32_t x14 = ((uint32_t)(arg1[18]) << 16); - uint32_t x15 = ((uint32_t)(arg1[17]) << 8); - uint8_t x16 = (arg1[16]); - uint32_t x17 = ((uint32_t)(arg1[15]) << 18); - uint32_t x18 = ((uint32_t)(arg1[14]) << 10); - uint32_t x19 = ((uint32_t)(arg1[13]) << 2); - uint32_t x20 = ((uint32_t)(arg1[12]) << 19); - uint32_t x21 = ((uint32_t)(arg1[11]) << 11); - uint32_t x22 = ((uint32_t)(arg1[10]) << 3); - uint32_t x23 = ((uint32_t)(arg1[9]) << 21); - uint32_t x24 = ((uint32_t)(arg1[8]) << 13); - uint32_t x25 = ((uint32_t)(arg1[7]) << 5); - uint32_t x26 = ((uint32_t)(arg1[6]) << 22); - uint32_t x27 = ((uint32_t)(arg1[5]) << 14); - uint32_t x28 = ((uint32_t)(arg1[4]) << 6); - uint32_t x29 = ((uint32_t)(arg1[3]) << 24); - uint32_t x30 = ((uint32_t)(arg1[2]) << 16); - uint32_t x31 = ((uint32_t)(arg1[1]) << 8); - uint8_t x32 = (arg1[0]); - uint32_t x33 = (x32 + (x31 + (x30 + x29))); - uint8_t x34 = (uint8_t)(x33 >> 26); - uint32_t x35 = (x33 & UINT32_C(0x3ffffff)); - uint32_t x36 = (x3 + (x2 + x1)); - uint32_t x37 = (x6 + (x5 + x4)); - uint32_t x38 = (x9 + (x8 + x7)); - uint32_t x39 = (x12 + (x11 + x10)); - uint32_t x40 = (x16 + (x15 + (x14 + x13))); - uint32_t x41 = (x19 + (x18 + x17)); - uint32_t x42 = (x22 + (x21 + x20)); - uint32_t x43 = (x25 + (x24 + x23)); - uint32_t x44 = (x28 + (x27 + x26)); - uint32_t x45 = (x34 + x44); - uint8_t x46 = (uint8_t)(x45 >> 25); - uint32_t x47 = (x45 & UINT32_C(0x1ffffff)); - uint32_t x48 = (x46 + x43); - uint8_t x49 = (uint8_t)(x48 >> 26); - uint32_t x50 = (x48 & UINT32_C(0x3ffffff)); - uint32_t x51 = (x49 + x42); - uint8_t x52 = (uint8_t)(x51 >> 25); - uint32_t x53 = (x51 & UINT32_C(0x1ffffff)); - uint32_t x54 = (x52 + x41); - uint32_t x55 = (x54 & UINT32_C(0x3ffffff)); - uint8_t x56 = (uint8_t)(x40 >> 25); - uint32_t x57 = (x40 & UINT32_C(0x1ffffff)); - uint32_t x58 = (x56 + x39); - uint8_t x59 = (uint8_t)(x58 >> 26); - uint32_t x60 = (x58 & UINT32_C(0x3ffffff)); - uint32_t x61 = (x59 + x38); - uint8_t x62 = (uint8_t)(x61 >> 25); - uint32_t x63 = (x61 & UINT32_C(0x1ffffff)); - uint32_t x64 = (x62 + x37); - uint8_t x65 = (uint8_t)(x64 >> 26); - uint32_t x66 = (x64 & UINT32_C(0x3ffffff)); - uint32_t x67 = (x65 + x36); - out1[0] = x35; - out1[1] = x47; - out1[2] = x50; - out1[3] = x53; +static FIAT_25519_FIAT_INLINE void fiat_25519_from_bytes(fiat_25519_tight_field_element out1, const uint8_t arg1[32]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint8_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint32_t x24; + uint32_t x25; + uint32_t x26; + uint32_t x27; + uint32_t x28; + uint32_t x29; + uint32_t x30; + uint32_t x31; + uint8_t x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint8_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint8_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint8_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + uint8_t x52; + uint32_t x53; + uint32_t x54; + uint32_t x55; + uint32_t x56; + uint32_t x57; + uint32_t x58; + uint32_t x59; + uint8_t x60; + uint32_t x61; + uint32_t x62; + uint32_t x63; + uint32_t x64; + uint8_t x65; + uint32_t x66; + uint32_t x67; + uint32_t x68; + uint32_t x69; + uint8_t x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint8_t x75; + uint32_t x76; + uint32_t x77; + uint32_t x78; + x1 = ((uint32_t)(arg1[31]) << 18); + x2 = ((uint32_t)(arg1[30]) << 10); + x3 = ((uint32_t)(arg1[29]) << 2); + x4 = ((uint32_t)(arg1[28]) << 20); + x5 = ((uint32_t)(arg1[27]) << 12); + x6 = ((uint32_t)(arg1[26]) << 4); + x7 = ((uint32_t)(arg1[25]) << 21); + x8 = ((uint32_t)(arg1[24]) << 13); + x9 = ((uint32_t)(arg1[23]) << 5); + x10 = ((uint32_t)(arg1[22]) << 23); + x11 = ((uint32_t)(arg1[21]) << 15); + x12 = ((uint32_t)(arg1[20]) << 7); + x13 = ((uint32_t)(arg1[19]) << 24); + x14 = ((uint32_t)(arg1[18]) << 16); + x15 = ((uint32_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint32_t)(arg1[15]) << 18); + x18 = ((uint32_t)(arg1[14]) << 10); + x19 = ((uint32_t)(arg1[13]) << 2); + x20 = ((uint32_t)(arg1[12]) << 19); + x21 = ((uint32_t)(arg1[11]) << 11); + x22 = ((uint32_t)(arg1[10]) << 3); + x23 = ((uint32_t)(arg1[9]) << 21); + x24 = ((uint32_t)(arg1[8]) << 13); + x25 = ((uint32_t)(arg1[7]) << 5); + x26 = ((uint32_t)(arg1[6]) << 22); + x27 = ((uint32_t)(arg1[5]) << 14); + x28 = ((uint32_t)(arg1[4]) << 6); + x29 = ((uint32_t)(arg1[3]) << 24); + x30 = ((uint32_t)(arg1[2]) << 16); + x31 = ((uint32_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint32_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x35 & UINT32_C(0x3ffffff)); + x37 = (uint8_t)(x35 >> 26); + x38 = (x28 + (uint32_t)x37); + x39 = (x27 + x38); + x40 = (x26 + x39); + x41 = (x40 & UINT32_C(0x1ffffff)); + x42 = (uint8_t)(x40 >> 25); + x43 = (x25 + (uint32_t)x42); + x44 = (x24 + x43); + x45 = (x23 + x44); + x46 = (x45 & UINT32_C(0x3ffffff)); + x47 = (uint8_t)(x45 >> 26); + x48 = (x22 + (uint32_t)x47); + x49 = (x21 + x48); + x50 = (x20 + x49); + x51 = (x50 & UINT32_C(0x1ffffff)); + x52 = (uint8_t)(x50 >> 25); + x53 = (x19 + (uint32_t)x52); + x54 = (x18 + x53); + x55 = (x17 + x54); + x56 = (x15 + (uint32_t)x16); + x57 = (x14 + x56); + x58 = (x13 + x57); + x59 = (x58 & UINT32_C(0x1ffffff)); + x60 = (uint8_t)(x58 >> 25); + x61 = (x12 + (uint32_t)x60); + x62 = (x11 + x61); + x63 = (x10 + x62); + x64 = (x63 & UINT32_C(0x3ffffff)); + x65 = (uint8_t)(x63 >> 26); + x66 = (x9 + (uint32_t)x65); + x67 = (x8 + x66); + x68 = (x7 + x67); + x69 = (x68 & UINT32_C(0x1ffffff)); + x70 = (uint8_t)(x68 >> 25); + x71 = (x6 + (uint32_t)x70); + x72 = (x5 + x71); + x73 = (x4 + x72); + x74 = (x73 & UINT32_C(0x3ffffff)); + x75 = (uint8_t)(x73 >> 26); + x76 = (x3 + (uint32_t)x75); + x77 = (x2 + x76); + x78 = (x1 + x77); + out1[0] = x36; + out1[1] = x41; + out1[2] = x46; + out1[3] = x51; out1[4] = x55; - out1[5] = x57; - out1[6] = x60; - out1[7] = x63; - out1[8] = x66; - out1[9] = x67; + out1[5] = x59; + out1[6] = x64; + out1[7] = x69; + out1[8] = x74; + out1[9] = x78; +} + +/* + * The function fiat_25519_relax is the identity function converting from tight field elements to loose field elements. + * + * Postconditions: + * out1 = arg1 + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_relax(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + x1 = (arg1[0]); + x2 = (arg1[1]); + x3 = (arg1[2]); + x4 = (arg1[3]); + x5 = (arg1[4]); + x6 = (arg1[5]); + x7 = (arg1[6]); + x8 = (arg1[7]); + x9 = (arg1[8]); + x10 = (arg1[9]); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; + out1[8] = x9; + out1[9] = x10; } /* * The function fiat_25519_carry_scmul_121666 multiplies a field element by 121666 and reduces the result. + * * Postconditions: * eval out1 mod m = (121666 * eval arg1) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999], [0x0 ~> 0xd333332], [0x0 ~> 0x6999999]] - * Output Bounds: - * out1: [[0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333], [0x0 ~> 0x4666666], [0x0 ~> 0x2333333]] */ -static void fiat_25519_carry_scmul_121666(uint32_t out1[10], const uint32_t arg1[10]) { - uint64_t x1 = ((uint64_t)UINT32_C(0x1db42) * (arg1[9])); - uint64_t x2 = ((uint64_t)UINT32_C(0x1db42) * (arg1[8])); - uint64_t x3 = ((uint64_t)UINT32_C(0x1db42) * (arg1[7])); - uint64_t x4 = ((uint64_t)UINT32_C(0x1db42) * (arg1[6])); - uint64_t x5 = ((uint64_t)UINT32_C(0x1db42) * (arg1[5])); - uint64_t x6 = ((uint64_t)UINT32_C(0x1db42) * (arg1[4])); - uint64_t x7 = ((uint64_t)UINT32_C(0x1db42) * (arg1[3])); - uint64_t x8 = ((uint64_t)UINT32_C(0x1db42) * (arg1[2])); - uint64_t x9 = ((uint64_t)UINT32_C(0x1db42) * (arg1[1])); - uint64_t x10 = ((uint64_t)UINT32_C(0x1db42) * (arg1[0])); - uint32_t x11 = (uint32_t)(x10 >> 26); - uint32_t x12 = (uint32_t)(x10 & UINT32_C(0x3ffffff)); - uint64_t x13 = (x11 + x9); - uint32_t x14 = (uint32_t)(x13 >> 25); - uint32_t x15 = (uint32_t)(x13 & UINT32_C(0x1ffffff)); - uint64_t x16 = (x14 + x8); - uint32_t x17 = (uint32_t)(x16 >> 26); - uint32_t x18 = (uint32_t)(x16 & UINT32_C(0x3ffffff)); - uint64_t x19 = (x17 + x7); - uint32_t x20 = (uint32_t)(x19 >> 25); - uint32_t x21 = (uint32_t)(x19 & UINT32_C(0x1ffffff)); - uint64_t x22 = (x20 + x6); - uint32_t x23 = (uint32_t)(x22 >> 26); - uint32_t x24 = (uint32_t)(x22 & UINT32_C(0x3ffffff)); - uint64_t x25 = (x23 + x5); - uint32_t x26 = (uint32_t)(x25 >> 25); - uint32_t x27 = (uint32_t)(x25 & UINT32_C(0x1ffffff)); - uint64_t x28 = (x26 + x4); - uint32_t x29 = (uint32_t)(x28 >> 26); - uint32_t x30 = (uint32_t)(x28 & UINT32_C(0x3ffffff)); - uint64_t x31 = (x29 + x3); - uint32_t x32 = (uint32_t)(x31 >> 25); - uint32_t x33 = (uint32_t)(x31 & UINT32_C(0x1ffffff)); - uint64_t x34 = (x32 + x2); - uint32_t x35 = (uint32_t)(x34 >> 26); - uint32_t x36 = (uint32_t)(x34 & UINT32_C(0x3ffffff)); - uint64_t x37 = (x35 + x1); - uint32_t x38 = (uint32_t)(x37 >> 25); - uint32_t x39 = (uint32_t)(x37 & UINT32_C(0x1ffffff)); - uint32_t x40 = (x38 * UINT8_C(0x13)); - uint32_t x41 = (x12 + x40); - fiat_25519_uint1 x42 = (fiat_25519_uint1)(x41 >> 26); - uint32_t x43 = (x41 & UINT32_C(0x3ffffff)); - uint32_t x44 = (x42 + x15); - fiat_25519_uint1 x45 = (fiat_25519_uint1)(x44 >> 25); - uint32_t x46 = (x44 & UINT32_C(0x1ffffff)); - uint32_t x47 = (x45 + x18); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_scmul_121666(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint32_t x11; + uint32_t x12; + uint64_t x13; + uint32_t x14; + uint32_t x15; + uint64_t x16; + uint32_t x17; + uint32_t x18; + uint64_t x19; + uint32_t x20; + uint32_t x21; + uint64_t x22; + uint32_t x23; + uint32_t x24; + uint64_t x25; + uint32_t x26; + uint32_t x27; + uint64_t x28; + uint32_t x29; + uint32_t x30; + uint64_t x31; + uint32_t x32; + uint32_t x33; + uint64_t x34; + uint32_t x35; + uint32_t x36; + uint64_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + fiat_25519_uint1 x42; + uint32_t x43; + uint32_t x44; + fiat_25519_uint1 x45; + uint32_t x46; + uint32_t x47; + x1 = ((uint64_t)UINT32_C(0x1db42) * (arg1[9])); + x2 = ((uint64_t)UINT32_C(0x1db42) * (arg1[8])); + x3 = ((uint64_t)UINT32_C(0x1db42) * (arg1[7])); + x4 = ((uint64_t)UINT32_C(0x1db42) * (arg1[6])); + x5 = ((uint64_t)UINT32_C(0x1db42) * (arg1[5])); + x6 = ((uint64_t)UINT32_C(0x1db42) * (arg1[4])); + x7 = ((uint64_t)UINT32_C(0x1db42) * (arg1[3])); + x8 = ((uint64_t)UINT32_C(0x1db42) * (arg1[2])); + x9 = ((uint64_t)UINT32_C(0x1db42) * (arg1[1])); + x10 = ((uint64_t)UINT32_C(0x1db42) * (arg1[0])); + x11 = (uint32_t)(x10 >> 26); + x12 = (uint32_t)(x10 & UINT32_C(0x3ffffff)); + x13 = (x11 + x9); + x14 = (uint32_t)(x13 >> 25); + x15 = (uint32_t)(x13 & UINT32_C(0x1ffffff)); + x16 = (x14 + x8); + x17 = (uint32_t)(x16 >> 26); + x18 = (uint32_t)(x16 & UINT32_C(0x3ffffff)); + x19 = (x17 + x7); + x20 = (uint32_t)(x19 >> 25); + x21 = (uint32_t)(x19 & UINT32_C(0x1ffffff)); + x22 = (x20 + x6); + x23 = (uint32_t)(x22 >> 26); + x24 = (uint32_t)(x22 & UINT32_C(0x3ffffff)); + x25 = (x23 + x5); + x26 = (uint32_t)(x25 >> 25); + x27 = (uint32_t)(x25 & UINT32_C(0x1ffffff)); + x28 = (x26 + x4); + x29 = (uint32_t)(x28 >> 26); + x30 = (uint32_t)(x28 & UINT32_C(0x3ffffff)); + x31 = (x29 + x3); + x32 = (uint32_t)(x31 >> 25); + x33 = (uint32_t)(x31 & UINT32_C(0x1ffffff)); + x34 = (x32 + x2); + x35 = (uint32_t)(x34 >> 26); + x36 = (uint32_t)(x34 & UINT32_C(0x3ffffff)); + x37 = (x35 + x1); + x38 = (uint32_t)(x37 >> 25); + x39 = (uint32_t)(x37 & UINT32_C(0x1ffffff)); + x40 = (x38 * UINT8_C(0x13)); + x41 = (x12 + x40); + x42 = (fiat_25519_uint1)(x41 >> 26); + x43 = (x41 & UINT32_C(0x3ffffff)); + x44 = (x42 + x15); + x45 = (fiat_25519_uint1)(x44 >> 25); + x46 = (x44 & UINT32_C(0x1ffffff)); + x47 = (x45 + x18); out1[0] = x43; out1[1] = x46; out1[2] = x47; @@ -978,4 +1563,3 @@ static void fiat_25519_carry_scmul_121666(uint32_t out1[10], const uint32_t arg1 out1[8] = x36; out1[9] = x39; } - diff --git a/third_party/boringssl/kit/src/third_party/fiat/curve25519_64.h b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64.h index 02679bbb..faed049d 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/curve25519_64.h +++ b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64.h @@ -1,26 +1,56 @@ -/* Autogenerated: src/ExtractionOCaml/unsaturated_solinas --static 25519 5 '2^255 - 19' 64 carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes carry_scmul121666 */ +/* Autogenerated: 'src/ExtractionOCaml/unsaturated_solinas' --inline --static --use-value-barrier 25519 64 '(auto)' '2^255 - 19' carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes relax carry_scmul121666 */ /* curve description: 25519 */ -/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, carry_scmul121666 */ -/* n = 5 (from "5") */ -/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ /* machine_wordsize = 64 (from "64") */ - +/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, relax, carry_scmul121666 */ +/* n = 5 (from "(auto)") */ +/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ +/* tight_bounds_multiplier = 1 (from "") */ +/* */ /* Computed values: */ -/* carry_chain = [0, 1, 2, 3, 4, 0, 1] */ +/* carry_chain = [0, 1, 2, 3, 4, 0, 1] */ +/* eval z = z[0] + (z[1] << 51) + (z[2] << 102) + (z[3] << 153) + (z[4] << 204) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* balance = [0xfffffffffffda, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe] */ #include typedef unsigned char fiat_25519_uint1; typedef signed char fiat_25519_int1; -typedef signed __int128 fiat_25519_int128; -typedef unsigned __int128 fiat_25519_uint128; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_25519_FIAT_EXTENSION __extension__ +# define FIAT_25519_FIAT_INLINE __inline__ +#else +# define FIAT_25519_FIAT_EXTENSION +# define FIAT_25519_FIAT_INLINE +#endif + +FIAT_25519_FIAT_EXTENSION typedef signed __int128 fiat_25519_int128; +FIAT_25519_FIAT_EXTENSION typedef unsigned __int128 fiat_25519_uint128; + +/* The type fiat_25519_loose_field_element is a field element with loose bounds. */ +/* Bounds: [[0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000]] */ +typedef uint64_t fiat_25519_loose_field_element[5]; + +/* The type fiat_25519_tight_field_element is a field element with tight bounds. */ +/* Bounds: [[0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000]] */ +typedef uint64_t fiat_25519_tight_field_element[5]; #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif +#if !defined(FIAT_25519_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint64_t fiat_25519_value_barrier_u64(uint64_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_25519_value_barrier_u64(x) (x) +#endif + /* * The function fiat_25519_addcarryx_u51 is an addition with carry. + * * Postconditions: * out1 = (arg1 + arg2 + arg3) mod 2^51 * out2 = ⌊(arg1 + arg2 + arg3) / 2^51⌋ @@ -33,16 +63,20 @@ typedef unsigned __int128 fiat_25519_uint128; * out1: [0x0 ~> 0x7ffffffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { - uint64_t x1 = ((arg1 + arg2) + arg3); - uint64_t x2 = (x1 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint1 x3 = (fiat_25519_uint1)(x1 >> 51); +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + uint64_t x1; + uint64_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT64_C(0x7ffffffffffff)); + x3 = (fiat_25519_uint1)(x1 >> 51); *out1 = x2; *out2 = x3; } /* * The function fiat_25519_subborrowx_u51 is a subtraction with borrow. + * * Postconditions: * out1 = (-arg1 + arg2 + -arg3) mod 2^51 * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^51⌋ @@ -55,16 +89,20 @@ static void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fia * out1: [0x0 ~> 0x7ffffffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { - int64_t x1 = ((int64_t)(arg2 - (int64_t)arg1) - (int64_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 51); - uint64_t x3 = (x1 & UINT64_C(0x7ffffffffffff)); +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + int64_t x1; + fiat_25519_int1 x2; + uint64_t x3; + x1 = ((int64_t)(arg2 - (int64_t)arg1) - (int64_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 51); + x3 = (x1 & UINT64_C(0x7ffffffffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); } /* * The function fiat_25519_cmovznz_u64 is a single-word conditional move. + * * Postconditions: * out1 = (if arg1 = 0 then arg2 else arg3) * @@ -75,83 +113,128 @@ static void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fi * Output Bounds: * out1: [0x0 ~> 0xffffffffffffffff] */ -static void fiat_25519_cmovznz_u64(uint64_t* out1, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { - fiat_25519_uint1 x1 = (!(!arg1)); - uint64_t x2 = ((fiat_25519_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); - // Note this line has been patched from the synthesized code to add value - // barriers. - // - // Clang recognizes this pattern as a select. While it usually transforms it - // to a cmov, it sometimes further transforms it into a branch, which we do - // not want. - uint64_t x3 = ((value_barrier_u64(x2) & arg3) | (value_barrier_u64(~x2) & arg2)); +static FIAT_25519_FIAT_INLINE void fiat_25519_cmovznz_u64(uint64_t* out1, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_25519_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_25519_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_25519_value_barrier_u64(x2) & arg3) | (fiat_25519_value_barrier_u64((~x2)) & arg2)); *out1 = x3; } /* * The function fiat_25519_carry_mul multiplies two field elements and reduces the result. + * * Postconditions: * eval out1 mod m = (eval arg1 * eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] - * arg2: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] - * Output Bounds: - * out1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] */ -static void fiat_25519_carry_mul(uint64_t out1[5], const uint64_t arg1[5], const uint64_t arg2[5]) { - fiat_25519_uint128 x1 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[4]) * UINT8_C(0x13))); - fiat_25519_uint128 x2 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[3]) * UINT8_C(0x13))); - fiat_25519_uint128 x3 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[2]) * UINT8_C(0x13))); - fiat_25519_uint128 x4 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[1]) * UINT8_C(0x13))); - fiat_25519_uint128 x5 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[4]) * UINT8_C(0x13))); - fiat_25519_uint128 x6 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[3]) * UINT8_C(0x13))); - fiat_25519_uint128 x7 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[2]) * UINT8_C(0x13))); - fiat_25519_uint128 x8 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[4]) * UINT8_C(0x13))); - fiat_25519_uint128 x9 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[3]) * UINT8_C(0x13))); - fiat_25519_uint128 x10 = ((fiat_25519_uint128)(arg1[1]) * ((arg2[4]) * UINT8_C(0x13))); - fiat_25519_uint128 x11 = ((fiat_25519_uint128)(arg1[4]) * (arg2[0])); - fiat_25519_uint128 x12 = ((fiat_25519_uint128)(arg1[3]) * (arg2[1])); - fiat_25519_uint128 x13 = ((fiat_25519_uint128)(arg1[3]) * (arg2[0])); - fiat_25519_uint128 x14 = ((fiat_25519_uint128)(arg1[2]) * (arg2[2])); - fiat_25519_uint128 x15 = ((fiat_25519_uint128)(arg1[2]) * (arg2[1])); - fiat_25519_uint128 x16 = ((fiat_25519_uint128)(arg1[2]) * (arg2[0])); - fiat_25519_uint128 x17 = ((fiat_25519_uint128)(arg1[1]) * (arg2[3])); - fiat_25519_uint128 x18 = ((fiat_25519_uint128)(arg1[1]) * (arg2[2])); - fiat_25519_uint128 x19 = ((fiat_25519_uint128)(arg1[1]) * (arg2[1])); - fiat_25519_uint128 x20 = ((fiat_25519_uint128)(arg1[1]) * (arg2[0])); - fiat_25519_uint128 x21 = ((fiat_25519_uint128)(arg1[0]) * (arg2[4])); - fiat_25519_uint128 x22 = ((fiat_25519_uint128)(arg1[0]) * (arg2[3])); - fiat_25519_uint128 x23 = ((fiat_25519_uint128)(arg1[0]) * (arg2[2])); - fiat_25519_uint128 x24 = ((fiat_25519_uint128)(arg1[0]) * (arg2[1])); - fiat_25519_uint128 x25 = ((fiat_25519_uint128)(arg1[0]) * (arg2[0])); - fiat_25519_uint128 x26 = (x25 + (x10 + (x9 + (x7 + x4)))); - uint64_t x27 = (uint64_t)(x26 >> 51); - uint64_t x28 = (uint64_t)(x26 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x29 = (x21 + (x17 + (x14 + (x12 + x11)))); - fiat_25519_uint128 x30 = (x22 + (x18 + (x15 + (x13 + x1)))); - fiat_25519_uint128 x31 = (x23 + (x19 + (x16 + (x5 + x2)))); - fiat_25519_uint128 x32 = (x24 + (x20 + (x8 + (x6 + x3)))); - fiat_25519_uint128 x33 = (x27 + x32); - uint64_t x34 = (uint64_t)(x33 >> 51); - uint64_t x35 = (uint64_t)(x33 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x36 = (x34 + x31); - uint64_t x37 = (uint64_t)(x36 >> 51); - uint64_t x38 = (uint64_t)(x36 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x39 = (x37 + x30); - uint64_t x40 = (uint64_t)(x39 >> 51); - uint64_t x41 = (uint64_t)(x39 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x42 = (x40 + x29); - uint64_t x43 = (uint64_t)(x42 >> 51); - uint64_t x44 = (uint64_t)(x42 & UINT64_C(0x7ffffffffffff)); - uint64_t x45 = (x43 * UINT8_C(0x13)); - uint64_t x46 = (x28 + x45); - uint64_t x47 = (x46 >> 51); - uint64_t x48 = (x46 & UINT64_C(0x7ffffffffffff)); - uint64_t x49 = (x47 + x35); - fiat_25519_uint1 x50 = (fiat_25519_uint1)(x49 >> 51); - uint64_t x51 = (x49 & UINT64_C(0x7ffffffffffff)); - uint64_t x52 = (x50 + x38); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_mul(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1, const fiat_25519_loose_field_element arg2) { + fiat_25519_uint128 x1; + fiat_25519_uint128 x2; + fiat_25519_uint128 x3; + fiat_25519_uint128 x4; + fiat_25519_uint128 x5; + fiat_25519_uint128 x6; + fiat_25519_uint128 x7; + fiat_25519_uint128 x8; + fiat_25519_uint128 x9; + fiat_25519_uint128 x10; + fiat_25519_uint128 x11; + fiat_25519_uint128 x12; + fiat_25519_uint128 x13; + fiat_25519_uint128 x14; + fiat_25519_uint128 x15; + fiat_25519_uint128 x16; + fiat_25519_uint128 x17; + fiat_25519_uint128 x18; + fiat_25519_uint128 x19; + fiat_25519_uint128 x20; + fiat_25519_uint128 x21; + fiat_25519_uint128 x22; + fiat_25519_uint128 x23; + fiat_25519_uint128 x24; + fiat_25519_uint128 x25; + fiat_25519_uint128 x26; + uint64_t x27; + uint64_t x28; + fiat_25519_uint128 x29; + fiat_25519_uint128 x30; + fiat_25519_uint128 x31; + fiat_25519_uint128 x32; + fiat_25519_uint128 x33; + uint64_t x34; + uint64_t x35; + fiat_25519_uint128 x36; + uint64_t x37; + uint64_t x38; + fiat_25519_uint128 x39; + uint64_t x40; + uint64_t x41; + fiat_25519_uint128 x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + fiat_25519_uint1 x50; + uint64_t x51; + uint64_t x52; + x1 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[4]) * UINT8_C(0x13))); + x2 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[3]) * UINT8_C(0x13))); + x3 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[2]) * UINT8_C(0x13))); + x4 = ((fiat_25519_uint128)(arg1[4]) * ((arg2[1]) * UINT8_C(0x13))); + x5 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[4]) * UINT8_C(0x13))); + x6 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[3]) * UINT8_C(0x13))); + x7 = ((fiat_25519_uint128)(arg1[3]) * ((arg2[2]) * UINT8_C(0x13))); + x8 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[4]) * UINT8_C(0x13))); + x9 = ((fiat_25519_uint128)(arg1[2]) * ((arg2[3]) * UINT8_C(0x13))); + x10 = ((fiat_25519_uint128)(arg1[1]) * ((arg2[4]) * UINT8_C(0x13))); + x11 = ((fiat_25519_uint128)(arg1[4]) * (arg2[0])); + x12 = ((fiat_25519_uint128)(arg1[3]) * (arg2[1])); + x13 = ((fiat_25519_uint128)(arg1[3]) * (arg2[0])); + x14 = ((fiat_25519_uint128)(arg1[2]) * (arg2[2])); + x15 = ((fiat_25519_uint128)(arg1[2]) * (arg2[1])); + x16 = ((fiat_25519_uint128)(arg1[2]) * (arg2[0])); + x17 = ((fiat_25519_uint128)(arg1[1]) * (arg2[3])); + x18 = ((fiat_25519_uint128)(arg1[1]) * (arg2[2])); + x19 = ((fiat_25519_uint128)(arg1[1]) * (arg2[1])); + x20 = ((fiat_25519_uint128)(arg1[1]) * (arg2[0])); + x21 = ((fiat_25519_uint128)(arg1[0]) * (arg2[4])); + x22 = ((fiat_25519_uint128)(arg1[0]) * (arg2[3])); + x23 = ((fiat_25519_uint128)(arg1[0]) * (arg2[2])); + x24 = ((fiat_25519_uint128)(arg1[0]) * (arg2[1])); + x25 = ((fiat_25519_uint128)(arg1[0]) * (arg2[0])); + x26 = (x25 + (x10 + (x9 + (x7 + x4)))); + x27 = (uint64_t)(x26 >> 51); + x28 = (uint64_t)(x26 & UINT64_C(0x7ffffffffffff)); + x29 = (x21 + (x17 + (x14 + (x12 + x11)))); + x30 = (x22 + (x18 + (x15 + (x13 + x1)))); + x31 = (x23 + (x19 + (x16 + (x5 + x2)))); + x32 = (x24 + (x20 + (x8 + (x6 + x3)))); + x33 = (x27 + x32); + x34 = (uint64_t)(x33 >> 51); + x35 = (uint64_t)(x33 & UINT64_C(0x7ffffffffffff)); + x36 = (x34 + x31); + x37 = (uint64_t)(x36 >> 51); + x38 = (uint64_t)(x36 & UINT64_C(0x7ffffffffffff)); + x39 = (x37 + x30); + x40 = (uint64_t)(x39 >> 51); + x41 = (uint64_t)(x39 & UINT64_C(0x7ffffffffffff)); + x42 = (x40 + x29); + x43 = (uint64_t)(x42 >> 51); + x44 = (uint64_t)(x42 & UINT64_C(0x7ffffffffffff)); + x45 = (x43 * UINT8_C(0x13)); + x46 = (x28 + x45); + x47 = (x46 >> 51); + x48 = (x46 & UINT64_C(0x7ffffffffffff)); + x49 = (x47 + x35); + x50 = (fiat_25519_uint1)(x49 >> 51); + x51 = (x49 & UINT64_C(0x7ffffffffffff)); + x52 = (x50 + x38); out1[0] = x48; out1[1] = x51; out1[2] = x52; @@ -161,65 +244,112 @@ static void fiat_25519_carry_mul(uint64_t out1[5], const uint64_t arg1[5], const /* * The function fiat_25519_carry_square squares a field element and reduces the result. + * * Postconditions: * eval out1 mod m = (eval arg1 * eval arg1) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] - * Output Bounds: - * out1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] */ -static void fiat_25519_carry_square(uint64_t out1[5], const uint64_t arg1[5]) { - uint64_t x1 = ((arg1[4]) * UINT8_C(0x13)); - uint64_t x2 = (x1 * 0x2); - uint64_t x3 = ((arg1[4]) * 0x2); - uint64_t x4 = ((arg1[3]) * UINT8_C(0x13)); - uint64_t x5 = (x4 * 0x2); - uint64_t x6 = ((arg1[3]) * 0x2); - uint64_t x7 = ((arg1[2]) * 0x2); - uint64_t x8 = ((arg1[1]) * 0x2); - fiat_25519_uint128 x9 = ((fiat_25519_uint128)(arg1[4]) * x1); - fiat_25519_uint128 x10 = ((fiat_25519_uint128)(arg1[3]) * x2); - fiat_25519_uint128 x11 = ((fiat_25519_uint128)(arg1[3]) * x4); - fiat_25519_uint128 x12 = ((fiat_25519_uint128)(arg1[2]) * x2); - fiat_25519_uint128 x13 = ((fiat_25519_uint128)(arg1[2]) * x5); - fiat_25519_uint128 x14 = ((fiat_25519_uint128)(arg1[2]) * (arg1[2])); - fiat_25519_uint128 x15 = ((fiat_25519_uint128)(arg1[1]) * x2); - fiat_25519_uint128 x16 = ((fiat_25519_uint128)(arg1[1]) * x6); - fiat_25519_uint128 x17 = ((fiat_25519_uint128)(arg1[1]) * x7); - fiat_25519_uint128 x18 = ((fiat_25519_uint128)(arg1[1]) * (arg1[1])); - fiat_25519_uint128 x19 = ((fiat_25519_uint128)(arg1[0]) * x3); - fiat_25519_uint128 x20 = ((fiat_25519_uint128)(arg1[0]) * x6); - fiat_25519_uint128 x21 = ((fiat_25519_uint128)(arg1[0]) * x7); - fiat_25519_uint128 x22 = ((fiat_25519_uint128)(arg1[0]) * x8); - fiat_25519_uint128 x23 = ((fiat_25519_uint128)(arg1[0]) * (arg1[0])); - fiat_25519_uint128 x24 = (x23 + (x15 + x13)); - uint64_t x25 = (uint64_t)(x24 >> 51); - uint64_t x26 = (uint64_t)(x24 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x27 = (x19 + (x16 + x14)); - fiat_25519_uint128 x28 = (x20 + (x17 + x9)); - fiat_25519_uint128 x29 = (x21 + (x18 + x10)); - fiat_25519_uint128 x30 = (x22 + (x12 + x11)); - fiat_25519_uint128 x31 = (x25 + x30); - uint64_t x32 = (uint64_t)(x31 >> 51); - uint64_t x33 = (uint64_t)(x31 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x34 = (x32 + x29); - uint64_t x35 = (uint64_t)(x34 >> 51); - uint64_t x36 = (uint64_t)(x34 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x37 = (x35 + x28); - uint64_t x38 = (uint64_t)(x37 >> 51); - uint64_t x39 = (uint64_t)(x37 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x40 = (x38 + x27); - uint64_t x41 = (uint64_t)(x40 >> 51); - uint64_t x42 = (uint64_t)(x40 & UINT64_C(0x7ffffffffffff)); - uint64_t x43 = (x41 * UINT8_C(0x13)); - uint64_t x44 = (x26 + x43); - uint64_t x45 = (x44 >> 51); - uint64_t x46 = (x44 & UINT64_C(0x7ffffffffffff)); - uint64_t x47 = (x45 + x33); - fiat_25519_uint1 x48 = (fiat_25519_uint1)(x47 >> 51); - uint64_t x49 = (x47 & UINT64_C(0x7ffffffffffff)); - uint64_t x50 = (x48 + x36); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_square(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + fiat_25519_uint128 x9; + fiat_25519_uint128 x10; + fiat_25519_uint128 x11; + fiat_25519_uint128 x12; + fiat_25519_uint128 x13; + fiat_25519_uint128 x14; + fiat_25519_uint128 x15; + fiat_25519_uint128 x16; + fiat_25519_uint128 x17; + fiat_25519_uint128 x18; + fiat_25519_uint128 x19; + fiat_25519_uint128 x20; + fiat_25519_uint128 x21; + fiat_25519_uint128 x22; + fiat_25519_uint128 x23; + fiat_25519_uint128 x24; + uint64_t x25; + uint64_t x26; + fiat_25519_uint128 x27; + fiat_25519_uint128 x28; + fiat_25519_uint128 x29; + fiat_25519_uint128 x30; + fiat_25519_uint128 x31; + uint64_t x32; + uint64_t x33; + fiat_25519_uint128 x34; + uint64_t x35; + uint64_t x36; + fiat_25519_uint128 x37; + uint64_t x38; + uint64_t x39; + fiat_25519_uint128 x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_25519_uint1 x48; + uint64_t x49; + uint64_t x50; + x1 = ((arg1[4]) * UINT8_C(0x13)); + x2 = (x1 * 0x2); + x3 = ((arg1[4]) * 0x2); + x4 = ((arg1[3]) * UINT8_C(0x13)); + x5 = (x4 * 0x2); + x6 = ((arg1[3]) * 0x2); + x7 = ((arg1[2]) * 0x2); + x8 = ((arg1[1]) * 0x2); + x9 = ((fiat_25519_uint128)(arg1[4]) * x1); + x10 = ((fiat_25519_uint128)(arg1[3]) * x2); + x11 = ((fiat_25519_uint128)(arg1[3]) * x4); + x12 = ((fiat_25519_uint128)(arg1[2]) * x2); + x13 = ((fiat_25519_uint128)(arg1[2]) * x5); + x14 = ((fiat_25519_uint128)(arg1[2]) * (arg1[2])); + x15 = ((fiat_25519_uint128)(arg1[1]) * x2); + x16 = ((fiat_25519_uint128)(arg1[1]) * x6); + x17 = ((fiat_25519_uint128)(arg1[1]) * x7); + x18 = ((fiat_25519_uint128)(arg1[1]) * (arg1[1])); + x19 = ((fiat_25519_uint128)(arg1[0]) * x3); + x20 = ((fiat_25519_uint128)(arg1[0]) * x6); + x21 = ((fiat_25519_uint128)(arg1[0]) * x7); + x22 = ((fiat_25519_uint128)(arg1[0]) * x8); + x23 = ((fiat_25519_uint128)(arg1[0]) * (arg1[0])); + x24 = (x23 + (x15 + x13)); + x25 = (uint64_t)(x24 >> 51); + x26 = (uint64_t)(x24 & UINT64_C(0x7ffffffffffff)); + x27 = (x19 + (x16 + x14)); + x28 = (x20 + (x17 + x9)); + x29 = (x21 + (x18 + x10)); + x30 = (x22 + (x12 + x11)); + x31 = (x25 + x30); + x32 = (uint64_t)(x31 >> 51); + x33 = (uint64_t)(x31 & UINT64_C(0x7ffffffffffff)); + x34 = (x32 + x29); + x35 = (uint64_t)(x34 >> 51); + x36 = (uint64_t)(x34 & UINT64_C(0x7ffffffffffff)); + x37 = (x35 + x28); + x38 = (uint64_t)(x37 >> 51); + x39 = (uint64_t)(x37 & UINT64_C(0x7ffffffffffff)); + x40 = (x38 + x27); + x41 = (uint64_t)(x40 >> 51); + x42 = (uint64_t)(x40 & UINT64_C(0x7ffffffffffff)); + x43 = (x41 * UINT8_C(0x13)); + x44 = (x26 + x43); + x45 = (x44 >> 51); + x46 = (x44 & UINT64_C(0x7ffffffffffff)); + x47 = (x45 + x33); + x48 = (fiat_25519_uint1)(x47 >> 51); + x49 = (x47 & UINT64_C(0x7ffffffffffff)); + x50 = (x48 + x36); out1[0] = x46; out1[1] = x49; out1[2] = x50; @@ -229,27 +359,36 @@ static void fiat_25519_carry_square(uint64_t out1[5], const uint64_t arg1[5]) { /* * The function fiat_25519_carry reduces a field element. + * * Postconditions: * eval out1 mod m = eval arg1 mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] - * Output Bounds: - * out1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] */ -static void fiat_25519_carry(uint64_t out1[5], const uint64_t arg1[5]) { - uint64_t x1 = (arg1[0]); - uint64_t x2 = ((x1 >> 51) + (arg1[1])); - uint64_t x3 = ((x2 >> 51) + (arg1[2])); - uint64_t x4 = ((x3 >> 51) + (arg1[3])); - uint64_t x5 = ((x4 >> 51) + (arg1[4])); - uint64_t x6 = ((x1 & UINT64_C(0x7ffffffffffff)) + ((x5 >> 51) * UINT8_C(0x13))); - uint64_t x7 = ((fiat_25519_uint1)(x6 >> 51) + (x2 & UINT64_C(0x7ffffffffffff))); - uint64_t x8 = (x6 & UINT64_C(0x7ffffffffffff)); - uint64_t x9 = (x7 & UINT64_C(0x7ffffffffffff)); - uint64_t x10 = ((fiat_25519_uint1)(x7 >> 51) + (x3 & UINT64_C(0x7ffffffffffff))); - uint64_t x11 = (x4 & UINT64_C(0x7ffffffffffff)); - uint64_t x12 = (x5 & UINT64_C(0x7ffffffffffff)); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + x1 = (arg1[0]); + x2 = ((x1 >> 51) + (arg1[1])); + x3 = ((x2 >> 51) + (arg1[2])); + x4 = ((x3 >> 51) + (arg1[3])); + x5 = ((x4 >> 51) + (arg1[4])); + x6 = ((x1 & UINT64_C(0x7ffffffffffff)) + ((x5 >> 51) * UINT8_C(0x13))); + x7 = ((fiat_25519_uint1)(x6 >> 51) + (x2 & UINT64_C(0x7ffffffffffff))); + x8 = (x6 & UINT64_C(0x7ffffffffffff)); + x9 = (x7 & UINT64_C(0x7ffffffffffff)); + x10 = ((fiat_25519_uint1)(x7 >> 51) + (x3 & UINT64_C(0x7ffffffffffff))); + x11 = (x4 & UINT64_C(0x7ffffffffffff)); + x12 = (x5 & UINT64_C(0x7ffffffffffff)); out1[0] = x8; out1[1] = x9; out1[2] = x10; @@ -259,21 +398,22 @@ static void fiat_25519_carry(uint64_t out1[5], const uint64_t arg1[5]) { /* * The function fiat_25519_add adds two field elements. + * * Postconditions: * eval out1 mod m = (eval arg1 + eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] - * arg2: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] - * Output Bounds: - * out1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] */ -static void fiat_25519_add(uint64_t out1[5], const uint64_t arg1[5], const uint64_t arg2[5]) { - uint64_t x1 = ((arg1[0]) + (arg2[0])); - uint64_t x2 = ((arg1[1]) + (arg2[1])); - uint64_t x3 = ((arg1[2]) + (arg2[2])); - uint64_t x4 = ((arg1[3]) + (arg2[3])); - uint64_t x5 = ((arg1[4]) + (arg2[4])); +static FIAT_25519_FIAT_INLINE void fiat_25519_add(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((arg1[0]) + (arg2[0])); + x2 = ((arg1[1]) + (arg2[1])); + x3 = ((arg1[2]) + (arg2[2])); + x4 = ((arg1[3]) + (arg2[3])); + x5 = ((arg1[4]) + (arg2[4])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -283,21 +423,22 @@ static void fiat_25519_add(uint64_t out1[5], const uint64_t arg1[5], const uint6 /* * The function fiat_25519_sub subtracts two field elements. + * * Postconditions: * eval out1 mod m = (eval arg1 - eval arg2) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] - * arg2: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] - * Output Bounds: - * out1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] */ -static void fiat_25519_sub(uint64_t out1[5], const uint64_t arg1[5], const uint64_t arg2[5]) { - uint64_t x1 = ((UINT64_C(0xfffffffffffda) + (arg1[0])) - (arg2[0])); - uint64_t x2 = ((UINT64_C(0xffffffffffffe) + (arg1[1])) - (arg2[1])); - uint64_t x3 = ((UINT64_C(0xffffffffffffe) + (arg1[2])) - (arg2[2])); - uint64_t x4 = ((UINT64_C(0xffffffffffffe) + (arg1[3])) - (arg2[3])); - uint64_t x5 = ((UINT64_C(0xffffffffffffe) + (arg1[4])) - (arg2[4])); +static FIAT_25519_FIAT_INLINE void fiat_25519_sub(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((UINT64_C(0xfffffffffffda) + (arg1[0])) - (arg2[0])); + x2 = ((UINT64_C(0xffffffffffffe) + (arg1[1])) - (arg2[1])); + x3 = ((UINT64_C(0xffffffffffffe) + (arg1[2])) - (arg2[2])); + x4 = ((UINT64_C(0xffffffffffffe) + (arg1[3])) - (arg2[3])); + x5 = ((UINT64_C(0xffffffffffffe) + (arg1[4])) - (arg2[4])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -307,20 +448,22 @@ static void fiat_25519_sub(uint64_t out1[5], const uint64_t arg1[5], const uint6 /* * The function fiat_25519_opp negates a field element. + * * Postconditions: * eval out1 mod m = -eval arg1 mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] - * Output Bounds: - * out1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] */ -static void fiat_25519_opp(uint64_t out1[5], const uint64_t arg1[5]) { - uint64_t x1 = (UINT64_C(0xfffffffffffda) - (arg1[0])); - uint64_t x2 = (UINT64_C(0xffffffffffffe) - (arg1[1])); - uint64_t x3 = (UINT64_C(0xffffffffffffe) - (arg1[2])); - uint64_t x4 = (UINT64_C(0xffffffffffffe) - (arg1[3])); - uint64_t x5 = (UINT64_C(0xffffffffffffe) - (arg1[4])); +static FIAT_25519_FIAT_INLINE void fiat_25519_opp(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (UINT64_C(0xfffffffffffda) - (arg1[0])); + x2 = (UINT64_C(0xffffffffffffe) - (arg1[1])); + x3 = (UINT64_C(0xffffffffffffe) - (arg1[2])); + x4 = (UINT64_C(0xffffffffffffe) - (arg1[3])); + x5 = (UINT64_C(0xffffffffffffe) - (arg1[4])); out1[0] = x1; out1[1] = x2; out1[2] = x3; @@ -330,6 +473,7 @@ static void fiat_25519_opp(uint64_t out1[5], const uint64_t arg1[5]) { /* * The function fiat_25519_selectznz is a multi-limb conditional select. + * * Postconditions: * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) * @@ -340,16 +484,16 @@ static void fiat_25519_opp(uint64_t out1[5], const uint64_t arg1[5]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_25519_selectznz(uint64_t out1[5], fiat_25519_uint1 arg1, const uint64_t arg2[5], const uint64_t arg3[5]) { +static FIAT_25519_FIAT_INLINE void fiat_25519_selectznz(uint64_t out1[5], fiat_25519_uint1 arg1, const uint64_t arg2[5], const uint64_t arg3[5]) { uint64_t x1; - fiat_25519_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); uint64_t x2; - fiat_25519_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); uint64_t x3; - fiat_25519_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); uint64_t x4; - fiat_25519_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); uint64_t x5; + fiat_25519_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_25519_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_25519_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_25519_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); fiat_25519_cmovznz_u64(&x5, arg1, (arg2[4]), (arg3[4])); out1[0] = x1; out1[1] = x2; @@ -360,260 +504,469 @@ static void fiat_25519_selectznz(uint64_t out1[5], fiat_25519_uint1 arg1, const /* * The function fiat_25519_to_bytes serializes a field element to bytes in little-endian order. + * * Postconditions: * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] * - * Input Bounds: - * arg1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] * Output Bounds: * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] */ -static void fiat_25519_to_bytes(uint8_t out1[32], const uint64_t arg1[5]) { +static FIAT_25519_FIAT_INLINE void fiat_25519_to_bytes(uint8_t out1[32], const fiat_25519_tight_field_element arg1) { uint64_t x1; fiat_25519_uint1 x2; - fiat_25519_subborrowx_u51(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0x7ffffffffffed)); uint64_t x3; fiat_25519_uint1 x4; - fiat_25519_subborrowx_u51(&x3, &x4, x2, (arg1[1]), UINT64_C(0x7ffffffffffff)); uint64_t x5; fiat_25519_uint1 x6; - fiat_25519_subborrowx_u51(&x5, &x6, x4, (arg1[2]), UINT64_C(0x7ffffffffffff)); uint64_t x7; fiat_25519_uint1 x8; - fiat_25519_subborrowx_u51(&x7, &x8, x6, (arg1[3]), UINT64_C(0x7ffffffffffff)); uint64_t x9; fiat_25519_uint1 x10; - fiat_25519_subborrowx_u51(&x9, &x10, x8, (arg1[4]), UINT64_C(0x7ffffffffffff)); uint64_t x11; - fiat_25519_cmovznz_u64(&x11, x10, 0x0, UINT64_C(0xffffffffffffffff)); uint64_t x12; fiat_25519_uint1 x13; - fiat_25519_addcarryx_u51(&x12, &x13, 0x0, x1, (x11 & UINT64_C(0x7ffffffffffed))); uint64_t x14; fiat_25519_uint1 x15; - fiat_25519_addcarryx_u51(&x14, &x15, x13, x3, (x11 & UINT64_C(0x7ffffffffffff))); uint64_t x16; fiat_25519_uint1 x17; - fiat_25519_addcarryx_u51(&x16, &x17, x15, x5, (x11 & UINT64_C(0x7ffffffffffff))); uint64_t x18; fiat_25519_uint1 x19; - fiat_25519_addcarryx_u51(&x18, &x19, x17, x7, (x11 & UINT64_C(0x7ffffffffffff))); uint64_t x20; fiat_25519_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint8_t x26; + uint64_t x27; + uint8_t x28; + uint64_t x29; + uint8_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint8_t x34; + uint64_t x35; + uint8_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint64_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint8_t x50; + uint64_t x51; + uint8_t x52; + uint64_t x53; + uint8_t x54; + uint64_t x55; + uint8_t x56; + uint64_t x57; + uint8_t x58; + uint64_t x59; + uint8_t x60; + uint64_t x61; + uint8_t x62; + uint64_t x63; + uint8_t x64; + fiat_25519_uint1 x65; + uint64_t x66; + uint8_t x67; + uint64_t x68; + uint8_t x69; + uint64_t x70; + uint8_t x71; + uint64_t x72; + uint8_t x73; + uint64_t x74; + uint8_t x75; + uint64_t x76; + uint8_t x77; + uint8_t x78; + uint64_t x79; + uint8_t x80; + uint64_t x81; + uint8_t x82; + uint64_t x83; + uint8_t x84; + uint64_t x85; + uint8_t x86; + uint64_t x87; + uint8_t x88; + uint64_t x89; + uint8_t x90; + uint8_t x91; + fiat_25519_subborrowx_u51(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0x7ffffffffffed)); + fiat_25519_subborrowx_u51(&x3, &x4, x2, (arg1[1]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x5, &x6, x4, (arg1[2]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x7, &x8, x6, (arg1[3]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x9, &x10, x8, (arg1[4]), UINT64_C(0x7ffffffffffff)); + fiat_25519_cmovznz_u64(&x11, x10, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_25519_addcarryx_u51(&x12, &x13, 0x0, x1, (x11 & UINT64_C(0x7ffffffffffed))); + fiat_25519_addcarryx_u51(&x14, &x15, x13, x3, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x16, &x17, x15, x5, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x18, &x19, x17, x7, (x11 & UINT64_C(0x7ffffffffffff))); fiat_25519_addcarryx_u51(&x20, &x21, x19, x9, (x11 & UINT64_C(0x7ffffffffffff))); - uint64_t x22 = (x20 << 4); - uint64_t x23 = (x18 * (uint64_t)0x2); - uint64_t x24 = (x16 << 6); - uint64_t x25 = (x14 << 3); - uint64_t x26 = (x12 >> 8); - uint8_t x27 = (uint8_t)(x12 & UINT8_C(0xff)); - uint64_t x28 = (x26 >> 8); - uint8_t x29 = (uint8_t)(x26 & UINT8_C(0xff)); - uint64_t x30 = (x28 >> 8); - uint8_t x31 = (uint8_t)(x28 & UINT8_C(0xff)); - uint64_t x32 = (x30 >> 8); - uint8_t x33 = (uint8_t)(x30 & UINT8_C(0xff)); - uint64_t x34 = (x32 >> 8); - uint8_t x35 = (uint8_t)(x32 & UINT8_C(0xff)); - uint8_t x36 = (uint8_t)(x34 >> 8); - uint8_t x37 = (uint8_t)(x34 & UINT8_C(0xff)); - uint64_t x38 = (x36 + x25); - uint64_t x39 = (x38 >> 8); - uint8_t x40 = (uint8_t)(x38 & UINT8_C(0xff)); - uint64_t x41 = (x39 >> 8); - uint8_t x42 = (uint8_t)(x39 & UINT8_C(0xff)); - uint64_t x43 = (x41 >> 8); - uint8_t x44 = (uint8_t)(x41 & UINT8_C(0xff)); - uint64_t x45 = (x43 >> 8); - uint8_t x46 = (uint8_t)(x43 & UINT8_C(0xff)); - uint64_t x47 = (x45 >> 8); - uint8_t x48 = (uint8_t)(x45 & UINT8_C(0xff)); - uint8_t x49 = (uint8_t)(x47 >> 8); - uint8_t x50 = (uint8_t)(x47 & UINT8_C(0xff)); - uint64_t x51 = (x49 + x24); - uint64_t x52 = (x51 >> 8); - uint8_t x53 = (uint8_t)(x51 & UINT8_C(0xff)); - uint64_t x54 = (x52 >> 8); - uint8_t x55 = (uint8_t)(x52 & UINT8_C(0xff)); - uint64_t x56 = (x54 >> 8); - uint8_t x57 = (uint8_t)(x54 & UINT8_C(0xff)); - uint64_t x58 = (x56 >> 8); - uint8_t x59 = (uint8_t)(x56 & UINT8_C(0xff)); - uint64_t x60 = (x58 >> 8); - uint8_t x61 = (uint8_t)(x58 & UINT8_C(0xff)); - uint64_t x62 = (x60 >> 8); - uint8_t x63 = (uint8_t)(x60 & UINT8_C(0xff)); - fiat_25519_uint1 x64 = (fiat_25519_uint1)(x62 >> 8); - uint8_t x65 = (uint8_t)(x62 & UINT8_C(0xff)); - uint64_t x66 = (x64 + x23); - uint64_t x67 = (x66 >> 8); - uint8_t x68 = (uint8_t)(x66 & UINT8_C(0xff)); - uint64_t x69 = (x67 >> 8); - uint8_t x70 = (uint8_t)(x67 & UINT8_C(0xff)); - uint64_t x71 = (x69 >> 8); - uint8_t x72 = (uint8_t)(x69 & UINT8_C(0xff)); - uint64_t x73 = (x71 >> 8); - uint8_t x74 = (uint8_t)(x71 & UINT8_C(0xff)); - uint64_t x75 = (x73 >> 8); - uint8_t x76 = (uint8_t)(x73 & UINT8_C(0xff)); - uint8_t x77 = (uint8_t)(x75 >> 8); - uint8_t x78 = (uint8_t)(x75 & UINT8_C(0xff)); - uint64_t x79 = (x77 + x22); - uint64_t x80 = (x79 >> 8); - uint8_t x81 = (uint8_t)(x79 & UINT8_C(0xff)); - uint64_t x82 = (x80 >> 8); - uint8_t x83 = (uint8_t)(x80 & UINT8_C(0xff)); - uint64_t x84 = (x82 >> 8); - uint8_t x85 = (uint8_t)(x82 & UINT8_C(0xff)); - uint64_t x86 = (x84 >> 8); - uint8_t x87 = (uint8_t)(x84 & UINT8_C(0xff)); - uint64_t x88 = (x86 >> 8); - uint8_t x89 = (uint8_t)(x86 & UINT8_C(0xff)); - uint8_t x90 = (uint8_t)(x88 >> 8); - uint8_t x91 = (uint8_t)(x88 & UINT8_C(0xff)); - out1[0] = x27; - out1[1] = x29; - out1[2] = x31; - out1[3] = x33; - out1[4] = x35; - out1[5] = x37; - out1[6] = x40; - out1[7] = x42; - out1[8] = x44; - out1[9] = x46; - out1[10] = x48; - out1[11] = x50; - out1[12] = x53; - out1[13] = x55; - out1[14] = x57; - out1[15] = x59; - out1[16] = x61; - out1[17] = x63; - out1[18] = x65; - out1[19] = x68; - out1[20] = x70; - out1[21] = x72; - out1[22] = x74; - out1[23] = x76; - out1[24] = x78; - out1[25] = x81; - out1[26] = x83; - out1[27] = x85; - out1[28] = x87; - out1[29] = x89; - out1[30] = x91; - out1[31] = x90; + x22 = (x20 << 4); + x23 = (x18 * (uint64_t)0x2); + x24 = (x16 << 6); + x25 = (x14 << 3); + x26 = (uint8_t)(x12 & UINT8_C(0xff)); + x27 = (x12 >> 8); + x28 = (uint8_t)(x27 & UINT8_C(0xff)); + x29 = (x27 >> 8); + x30 = (uint8_t)(x29 & UINT8_C(0xff)); + x31 = (x29 >> 8); + x32 = (uint8_t)(x31 & UINT8_C(0xff)); + x33 = (x31 >> 8); + x34 = (uint8_t)(x33 & UINT8_C(0xff)); + x35 = (x33 >> 8); + x36 = (uint8_t)(x35 & UINT8_C(0xff)); + x37 = (uint8_t)(x35 >> 8); + x38 = (x25 + (uint64_t)x37); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (x44 >> 8); + x47 = (uint8_t)(x46 & UINT8_C(0xff)); + x48 = (x46 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (uint8_t)(x48 >> 8); + x51 = (x24 + (uint64_t)x50); + x52 = (uint8_t)(x51 & UINT8_C(0xff)); + x53 = (x51 >> 8); + x54 = (uint8_t)(x53 & UINT8_C(0xff)); + x55 = (x53 >> 8); + x56 = (uint8_t)(x55 & UINT8_C(0xff)); + x57 = (x55 >> 8); + x58 = (uint8_t)(x57 & UINT8_C(0xff)); + x59 = (x57 >> 8); + x60 = (uint8_t)(x59 & UINT8_C(0xff)); + x61 = (x59 >> 8); + x62 = (uint8_t)(x61 & UINT8_C(0xff)); + x63 = (x61 >> 8); + x64 = (uint8_t)(x63 & UINT8_C(0xff)); + x65 = (fiat_25519_uint1)(x63 >> 8); + x66 = (x23 + (uint64_t)x65); + x67 = (uint8_t)(x66 & UINT8_C(0xff)); + x68 = (x66 >> 8); + x69 = (uint8_t)(x68 & UINT8_C(0xff)); + x70 = (x68 >> 8); + x71 = (uint8_t)(x70 & UINT8_C(0xff)); + x72 = (x70 >> 8); + x73 = (uint8_t)(x72 & UINT8_C(0xff)); + x74 = (x72 >> 8); + x75 = (uint8_t)(x74 & UINT8_C(0xff)); + x76 = (x74 >> 8); + x77 = (uint8_t)(x76 & UINT8_C(0xff)); + x78 = (uint8_t)(x76 >> 8); + x79 = (x22 + (uint64_t)x78); + x80 = (uint8_t)(x79 & UINT8_C(0xff)); + x81 = (x79 >> 8); + x82 = (uint8_t)(x81 & UINT8_C(0xff)); + x83 = (x81 >> 8); + x84 = (uint8_t)(x83 & UINT8_C(0xff)); + x85 = (x83 >> 8); + x86 = (uint8_t)(x85 & UINT8_C(0xff)); + x87 = (x85 >> 8); + x88 = (uint8_t)(x87 & UINT8_C(0xff)); + x89 = (x87 >> 8); + x90 = (uint8_t)(x89 & UINT8_C(0xff)); + x91 = (uint8_t)(x89 >> 8); + out1[0] = x26; + out1[1] = x28; + out1[2] = x30; + out1[3] = x32; + out1[4] = x34; + out1[5] = x36; + out1[6] = x39; + out1[7] = x41; + out1[8] = x43; + out1[9] = x45; + out1[10] = x47; + out1[11] = x49; + out1[12] = x52; + out1[13] = x54; + out1[14] = x56; + out1[15] = x58; + out1[16] = x60; + out1[17] = x62; + out1[18] = x64; + out1[19] = x67; + out1[20] = x69; + out1[21] = x71; + out1[22] = x73; + out1[23] = x75; + out1[24] = x77; + out1[25] = x80; + out1[26] = x82; + out1[27] = x84; + out1[28] = x86; + out1[29] = x88; + out1[30] = x90; + out1[31] = x91; } /* * The function fiat_25519_from_bytes deserializes a field element from bytes in little-endian order. + * * Postconditions: * eval out1 mod m = bytes_eval arg1 mod m * * Input Bounds: * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] - * Output Bounds: - * out1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] */ -static void fiat_25519_from_bytes(uint64_t out1[5], const uint8_t arg1[32]) { - uint64_t x1 = ((uint64_t)(arg1[31]) << 44); - uint64_t x2 = ((uint64_t)(arg1[30]) << 36); - uint64_t x3 = ((uint64_t)(arg1[29]) << 28); - uint64_t x4 = ((uint64_t)(arg1[28]) << 20); - uint64_t x5 = ((uint64_t)(arg1[27]) << 12); - uint64_t x6 = ((uint64_t)(arg1[26]) << 4); - uint64_t x7 = ((uint64_t)(arg1[25]) << 47); - uint64_t x8 = ((uint64_t)(arg1[24]) << 39); - uint64_t x9 = ((uint64_t)(arg1[23]) << 31); - uint64_t x10 = ((uint64_t)(arg1[22]) << 23); - uint64_t x11 = ((uint64_t)(arg1[21]) << 15); - uint64_t x12 = ((uint64_t)(arg1[20]) << 7); - uint64_t x13 = ((uint64_t)(arg1[19]) << 50); - uint64_t x14 = ((uint64_t)(arg1[18]) << 42); - uint64_t x15 = ((uint64_t)(arg1[17]) << 34); - uint64_t x16 = ((uint64_t)(arg1[16]) << 26); - uint64_t x17 = ((uint64_t)(arg1[15]) << 18); - uint64_t x18 = ((uint64_t)(arg1[14]) << 10); - uint64_t x19 = ((uint64_t)(arg1[13]) << 2); - uint64_t x20 = ((uint64_t)(arg1[12]) << 45); - uint64_t x21 = ((uint64_t)(arg1[11]) << 37); - uint64_t x22 = ((uint64_t)(arg1[10]) << 29); - uint64_t x23 = ((uint64_t)(arg1[9]) << 21); - uint64_t x24 = ((uint64_t)(arg1[8]) << 13); - uint64_t x25 = ((uint64_t)(arg1[7]) << 5); - uint64_t x26 = ((uint64_t)(arg1[6]) << 48); - uint64_t x27 = ((uint64_t)(arg1[5]) << 40); - uint64_t x28 = ((uint64_t)(arg1[4]) << 32); - uint64_t x29 = ((uint64_t)(arg1[3]) << 24); - uint64_t x30 = ((uint64_t)(arg1[2]) << 16); - uint64_t x31 = ((uint64_t)(arg1[1]) << 8); - uint8_t x32 = (arg1[0]); - uint64_t x33 = (x32 + (x31 + (x30 + (x29 + (x28 + (x27 + x26)))))); - uint8_t x34 = (uint8_t)(x33 >> 51); - uint64_t x35 = (x33 & UINT64_C(0x7ffffffffffff)); - uint64_t x36 = (x6 + (x5 + (x4 + (x3 + (x2 + x1))))); - uint64_t x37 = (x12 + (x11 + (x10 + (x9 + (x8 + x7))))); - uint64_t x38 = (x19 + (x18 + (x17 + (x16 + (x15 + (x14 + x13)))))); - uint64_t x39 = (x25 + (x24 + (x23 + (x22 + (x21 + x20))))); - uint64_t x40 = (x34 + x39); - uint8_t x41 = (uint8_t)(x40 >> 51); - uint64_t x42 = (x40 & UINT64_C(0x7ffffffffffff)); - uint64_t x43 = (x41 + x38); - uint8_t x44 = (uint8_t)(x43 >> 51); - uint64_t x45 = (x43 & UINT64_C(0x7ffffffffffff)); - uint64_t x46 = (x44 + x37); - uint8_t x47 = (uint8_t)(x46 >> 51); - uint64_t x48 = (x46 & UINT64_C(0x7ffffffffffff)); - uint64_t x49 = (x47 + x36); - out1[0] = x35; - out1[1] = x42; - out1[2] = x45; - out1[3] = x48; - out1[4] = x49; +static FIAT_25519_FIAT_INLINE void fiat_25519_from_bytes(fiat_25519_tight_field_element out1, const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint8_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint8_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint8_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + x1 = ((uint64_t)(arg1[31]) << 44); + x2 = ((uint64_t)(arg1[30]) << 36); + x3 = ((uint64_t)(arg1[29]) << 28); + x4 = ((uint64_t)(arg1[28]) << 20); + x5 = ((uint64_t)(arg1[27]) << 12); + x6 = ((uint64_t)(arg1[26]) << 4); + x7 = ((uint64_t)(arg1[25]) << 47); + x8 = ((uint64_t)(arg1[24]) << 39); + x9 = ((uint64_t)(arg1[23]) << 31); + x10 = ((uint64_t)(arg1[22]) << 23); + x11 = ((uint64_t)(arg1[21]) << 15); + x12 = ((uint64_t)(arg1[20]) << 7); + x13 = ((uint64_t)(arg1[19]) << 50); + x14 = ((uint64_t)(arg1[18]) << 42); + x15 = ((uint64_t)(arg1[17]) << 34); + x16 = ((uint64_t)(arg1[16]) << 26); + x17 = ((uint64_t)(arg1[15]) << 18); + x18 = ((uint64_t)(arg1[14]) << 10); + x19 = ((uint64_t)(arg1[13]) << 2); + x20 = ((uint64_t)(arg1[12]) << 45); + x21 = ((uint64_t)(arg1[11]) << 37); + x22 = ((uint64_t)(arg1[10]) << 29); + x23 = ((uint64_t)(arg1[9]) << 21); + x24 = ((uint64_t)(arg1[8]) << 13); + x25 = ((uint64_t)(arg1[7]) << 5); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x38 & UINT64_C(0x7ffffffffffff)); + x40 = (uint8_t)(x38 >> 51); + x41 = (x25 + (uint64_t)x40); + x42 = (x24 + x41); + x43 = (x23 + x42); + x44 = (x22 + x43); + x45 = (x21 + x44); + x46 = (x20 + x45); + x47 = (x46 & UINT64_C(0x7ffffffffffff)); + x48 = (uint8_t)(x46 >> 51); + x49 = (x19 + (uint64_t)x48); + x50 = (x18 + x49); + x51 = (x17 + x50); + x52 = (x16 + x51); + x53 = (x15 + x52); + x54 = (x14 + x53); + x55 = (x13 + x54); + x56 = (x55 & UINT64_C(0x7ffffffffffff)); + x57 = (uint8_t)(x55 >> 51); + x58 = (x12 + (uint64_t)x57); + x59 = (x11 + x58); + x60 = (x10 + x59); + x61 = (x9 + x60); + x62 = (x8 + x61); + x63 = (x7 + x62); + x64 = (x63 & UINT64_C(0x7ffffffffffff)); + x65 = (uint8_t)(x63 >> 51); + x66 = (x6 + (uint64_t)x65); + x67 = (x5 + x66); + x68 = (x4 + x67); + x69 = (x3 + x68); + x70 = (x2 + x69); + x71 = (x1 + x70); + out1[0] = x39; + out1[1] = x47; + out1[2] = x56; + out1[3] = x64; + out1[4] = x71; +} + +/* + * The function fiat_25519_relax is the identity function converting from tight field elements to loose field elements. + * + * Postconditions: + * out1 = arg1 + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_relax(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (arg1[0]); + x2 = (arg1[1]); + x3 = (arg1[2]); + x4 = (arg1[3]); + x5 = (arg1[4]); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; } /* * The function fiat_25519_carry_scmul_121666 multiplies a field element by 121666 and reduces the result. + * * Postconditions: * eval out1 mod m = (121666 * eval arg1) mod m * - * Input Bounds: - * arg1: [[0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664], [0x0 ~> 0x1a666666666664]] - * Output Bounds: - * out1: [[0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc], [0x0 ~> 0x8cccccccccccc]] */ -static void fiat_25519_carry_scmul_121666(uint64_t out1[5], const uint64_t arg1[5]) { - fiat_25519_uint128 x1 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[4])); - fiat_25519_uint128 x2 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[3])); - fiat_25519_uint128 x3 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[2])); - fiat_25519_uint128 x4 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[1])); - fiat_25519_uint128 x5 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[0])); - uint64_t x6 = (uint64_t)(x5 >> 51); - uint64_t x7 = (uint64_t)(x5 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x8 = (x6 + x4); - uint64_t x9 = (uint64_t)(x8 >> 51); - uint64_t x10 = (uint64_t)(x8 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x11 = (x9 + x3); - uint64_t x12 = (uint64_t)(x11 >> 51); - uint64_t x13 = (uint64_t)(x11 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x14 = (x12 + x2); - uint64_t x15 = (uint64_t)(x14 >> 51); - uint64_t x16 = (uint64_t)(x14 & UINT64_C(0x7ffffffffffff)); - fiat_25519_uint128 x17 = (x15 + x1); - uint64_t x18 = (uint64_t)(x17 >> 51); - uint64_t x19 = (uint64_t)(x17 & UINT64_C(0x7ffffffffffff)); - uint64_t x20 = (x18 * UINT8_C(0x13)); - uint64_t x21 = (x7 + x20); - fiat_25519_uint1 x22 = (fiat_25519_uint1)(x21 >> 51); - uint64_t x23 = (x21 & UINT64_C(0x7ffffffffffff)); - uint64_t x24 = (x22 + x10); - fiat_25519_uint1 x25 = (fiat_25519_uint1)(x24 >> 51); - uint64_t x26 = (x24 & UINT64_C(0x7ffffffffffff)); - uint64_t x27 = (x25 + x13); +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_scmul_121666(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + fiat_25519_uint128 x1; + fiat_25519_uint128 x2; + fiat_25519_uint128 x3; + fiat_25519_uint128 x4; + fiat_25519_uint128 x5; + uint64_t x6; + uint64_t x7; + fiat_25519_uint128 x8; + uint64_t x9; + uint64_t x10; + fiat_25519_uint128 x11; + uint64_t x12; + uint64_t x13; + fiat_25519_uint128 x14; + uint64_t x15; + uint64_t x16; + fiat_25519_uint128 x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + fiat_25519_uint1 x22; + uint64_t x23; + uint64_t x24; + fiat_25519_uint1 x25; + uint64_t x26; + uint64_t x27; + x1 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[4])); + x2 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[3])); + x3 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[2])); + x4 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[1])); + x5 = ((fiat_25519_uint128)UINT32_C(0x1db42) * (arg1[0])); + x6 = (uint64_t)(x5 >> 51); + x7 = (uint64_t)(x5 & UINT64_C(0x7ffffffffffff)); + x8 = (x6 + x4); + x9 = (uint64_t)(x8 >> 51); + x10 = (uint64_t)(x8 & UINT64_C(0x7ffffffffffff)); + x11 = (x9 + x3); + x12 = (uint64_t)(x11 >> 51); + x13 = (uint64_t)(x11 & UINT64_C(0x7ffffffffffff)); + x14 = (x12 + x2); + x15 = (uint64_t)(x14 >> 51); + x16 = (uint64_t)(x14 & UINT64_C(0x7ffffffffffff)); + x17 = (x15 + x1); + x18 = (uint64_t)(x17 >> 51); + x19 = (uint64_t)(x17 & UINT64_C(0x7ffffffffffff)); + x20 = (x18 * UINT8_C(0x13)); + x21 = (x7 + x20); + x22 = (fiat_25519_uint1)(x21 >> 51); + x23 = (x21 & UINT64_C(0x7ffffffffffff)); + x24 = (x22 + x10); + x25 = (fiat_25519_uint1)(x24 >> 51); + x26 = (x24 & UINT64_C(0x7ffffffffffff)); + x27 = (x25 + x13); out1[0] = x23; out1[1] = x26; out1[2] = x27; out1[3] = x16; out1[4] = x19; } - diff --git a/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_adx.h b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_adx.h new file mode 100644 index 00000000..f50f5b83 --- /dev/null +++ b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_adx.h @@ -0,0 +1,691 @@ +#include +#include +#include +#include + +typedef uint64_t fe4[4]; +typedef uint8_t fiat_uint1; +typedef int8_t fiat_int1; + +static __inline__ uint64_t fiat_value_barrier_u64(uint64_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} + +__attribute__((target("adx,bmi2"))) +static inline void fe4_mul(fe4 out, const fe4 x, const fe4 y) { fiat_curve25519_adx_mul(out, x, y); } + +__attribute__((target("adx,bmi2"))) +static inline void fe4_sq(fe4 out, const fe4 x) { fiat_curve25519_adx_square(out, x); } + +/* + * The function fiat_mulx_u64 is a multiplication, returning the full double-width result. + * + * Postconditions: + * out1 = (arg1 * arg2) mod 2^64 + * out2 = ⌊arg1 * arg2 / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0xffffffffffffffff] + */ +__attribute__((target("adx,bmi2"))) +static inline void fiat_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { +// NOTE: edited after generation +#if defined(_M_X64) + unsigned long long t; + *out1 = _umul128(arg1, arg2, &t); + *out2 = t; +#elif defined(_M_ARM64) + *out1 = arg1 * arg2; + *out2 = __umulh(arg1, arg2); +#else + unsigned __int128 t = (unsigned __int128)arg1 * arg2; + *out1 = t; + *out2 = (t >> 64); +#endif +} + +/* + * The function fiat_addcarryx_u64 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^64 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +__attribute__((target("adx,bmi2"))) +static inline void fiat_addcarryx_u64(uint64_t* out1, fiat_uint1* out2, fiat_uint1 arg1, uint64_t arg2, uint64_t arg3) { +// NOTE: edited after generation +#if defined(__has_builtin) +# if __has_builtin(__builtin_ia32_addcarryx_u64) +# define addcarry64 __builtin_ia32_addcarryx_u64 +# endif +#endif +#if defined(addcarry64) + long long unsigned int t; + *out2 = addcarry64(arg1, arg2, arg3, &t); + *out1 = t; +#elif defined(_M_X64) + long long unsigned int t; + *out2 = _addcarry_u64(arg1, arg2, arg3, out1); + *out1 = t; +#else + arg2 += arg1; + arg1 = arg2 < arg1; + uint64_t ret = arg2 + arg3; + arg1 += ret < arg2; + *out1 = ret; + *out2 = arg1; +#endif +#undef addcarry64 +} + +/* + * The function fiat_subborrowx_u64 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^64 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +__attribute__((target("adx,bmi2"))) +static inline void fiat_subborrowx_u64(uint64_t* out1, fiat_uint1* out2, fiat_uint1 arg1, uint64_t arg2, uint64_t arg3) { +#if defined(__has_builtin) +# if __has_builtin(__builtin_ia32_subborrow_u64) +# define subborrow64 __builtin_ia32_subborrow_u64 +# endif +#endif +#if defined(subborrow64) + long long unsigned int t; + *out2 = subborrow64(arg1, arg2, arg3, &t); + *out1 = t; +#elif defined(_M_X64) + long long unsigned int t; + *out2 = _subborrow_u64(arg1, arg2, arg3, &t); // NOTE: edited after generation + *out1 = t; +#else + *out1 = arg2 - arg3 - arg1; + *out2 = (arg2 < arg3) | ((arg2 == arg3) & arg1); +#endif +#undef subborrow64 +} + +/* + * The function fiat_cmovznz_u64 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +__attribute__((target("adx,bmi2"))) +static inline void fiat_cmovznz_u64(uint64_t* out1, fiat_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_value_barrier_u64(x2) & arg3) | (fiat_value_barrier_u64((~x2)) & arg2)); + *out1 = x3; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +__attribute__((target("adx,bmi2"))) +static void fe4_add(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { + uint64_t x1; + fiat_uint1 x2; + uint64_t x3; + fiat_uint1 x4; + uint64_t x5; + fiat_uint1 x6; + uint64_t x7; + fiat_uint1 x8; + uint64_t x9; + uint64_t x10; + fiat_uint1 x11; + uint64_t x12; + fiat_uint1 x13; + uint64_t x14; + fiat_uint1 x15; + uint64_t x16; + fiat_uint1 x17; + uint64_t x18; + uint64_t x19; + fiat_uint1 x20; + fiat_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_cmovznz_u64(&x9, x8, 0x0, UINT8_C(0x26)); // NOTE: clang 14 for Zen 2 uses sbb, and + fiat_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_addcarryx_u64(&x12, &x13, x11, x3, 0x0); + fiat_addcarryx_u64(&x14, &x15, x13, x5, 0x0); + fiat_addcarryx_u64(&x16, &x17, x15, x7, 0x0); + fiat_cmovznz_u64(&x18, x17, 0x0, UINT8_C(0x26)); // NOTE: clang 14 for Zen 2 uses sbb, and + fiat_addcarryx_u64(&x19, &x20, 0x0, x10, x18); + out1[0] = x19; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +__attribute__((target("adx,bmi2"))) +static void fe4_sub(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { + uint64_t x1; + uint64_t x2; + fiat_uint1 x3; + uint64_t x4; + uint64_t x5; + fiat_uint1 x6; + uint64_t x7; + uint64_t x8; + fiat_uint1 x9; + uint64_t x10; + uint64_t x11; + fiat_uint1 x12; + uint64_t x13; + uint64_t x14; + fiat_uint1 x15; + uint64_t x16; + fiat_uint1 x17; + uint64_t x18; + fiat_uint1 x19; + uint64_t x20; + fiat_uint1 x21; + uint64_t x22; + uint64_t x23; + fiat_uint1 x24; + x1 = (arg2[0]); + fiat_subborrowx_u64(&x2, &x3, 0x0, (arg1[0]), x1); + x4 = (arg2[1]); + fiat_subborrowx_u64(&x5, &x6, x3, (arg1[1]), x4); + x7 = (arg2[2]); + fiat_subborrowx_u64(&x8, &x9, x6, (arg1[2]), x7); + x10 = (arg2[3]); + fiat_subborrowx_u64(&x11, &x12, x9, (arg1[3]), x10); + fiat_cmovznz_u64(&x13, x12, 0x0, UINT8_C(0x26)); // NOTE: clang 14 for Zen 2 uses sbb, and + fiat_subborrowx_u64(&x14, &x15, 0x0, x2, x13); + fiat_subborrowx_u64(&x16, &x17, x15, x5, 0x0); + fiat_subborrowx_u64(&x18, &x19, x17, x8, 0x0); + fiat_subborrowx_u64(&x20, &x21, x19, x11, 0x0); + fiat_cmovznz_u64(&x22, x21, 0x0, UINT8_C(0x26)); // NOTE: clang 14 for Zen 2 uses sbb, and + fiat_subborrowx_u64(&x23, &x24, 0x0, x14, x22); + out1[0] = x23; + out1[1] = x16; + out1[2] = x18; + out1[3] = x20; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [0x0 ~> 0x3ffffffffffffff] // NOTE: this is not any uint64! + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +__attribute__((target("adx,bmi2"))) +static void fe4_scmul(uint64_t out1[4], const uint64_t arg1[4], uint64_t arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + fiat_uint1 x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + fiat_uint1 x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_uint1 x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + fiat_uint1 x18; + uint64_t x19; + fiat_uint1 x20; + uint64_t x21; + fiat_uint1 x22; + uint64_t x23; + fiat_uint1 x24; + uint64_t x25; + uint64_t x26; + fiat_uint1 x27; + fiat_mulx_u64(&x1, &x2, (arg1[0]), arg2); + fiat_mulx_u64(&x3, &x4, (arg1[1]), arg2); + fiat_addcarryx_u64(&x5, &x6, 0x0, x2, x3); + fiat_mulx_u64(&x7, &x8, (arg1[2]), arg2); + fiat_addcarryx_u64(&x9, &x10, x6, x4, x7); + fiat_mulx_u64(&x11, &x12, (arg1[3]), arg2); + fiat_addcarryx_u64(&x13, &x14, x10, x8, x11); + fiat_mulx_u64(&x15, &x16, (x12 + (uint64_t)x14), UINT8_C(0x26)); + fiat_addcarryx_u64(&x17, &x18, 0x0, x1, x15); + fiat_addcarryx_u64(&x19, &x20, x18, x5, 0x0); + fiat_addcarryx_u64(&x21, &x22, x20, x9, 0x0); + fiat_addcarryx_u64(&x23, &x24, x22, x13, 0x0); + fiat_cmovznz_u64(&x25, x24, 0x0, UINT8_C(0x26)); // NOTE: clang 14 for Zen 2 uses sbb, and + fiat_addcarryx_u64(&x26, &x27, 0x0, x17, x25); + out1[0] = x26; + out1[1] = x19; + out1[2] = x21; + out1[3] = x23; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +__attribute__((target("adx,bmi2"))) +static void fe4_canon(uint64_t out1[4], const uint64_t arg1[4]) { + uint64_t x1; + fiat_uint1 x2; + uint64_t x3; + fiat_uint1 x4; + uint64_t x5; + fiat_uint1 x6; + uint64_t x7; + fiat_uint1 x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_uint1 x14; + uint64_t x15; + fiat_uint1 x16; + uint64_t x17; + fiat_uint1 x18; + uint64_t x19; + fiat_uint1 x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + fiat_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0xffffffffffffffed)); + fiat_subborrowx_u64(&x3, &x4, x2, (arg1[1]), UINT64_C(0xffffffffffffffff)); + fiat_subborrowx_u64(&x5, &x6, x4, (arg1[2]), UINT64_C(0xffffffffffffffff)); + fiat_subborrowx_u64(&x7, &x8, x6, (arg1[3]), UINT64_C(0x7fffffffffffffff)); + fiat_cmovznz_u64(&x9, x8, x1, (arg1[0])); + fiat_cmovznz_u64(&x10, x8, x3, (arg1[1])); + fiat_cmovznz_u64(&x11, x8, x5, (arg1[2])); + fiat_cmovznz_u64(&x12, x8, x7, (arg1[3])); + fiat_subborrowx_u64(&x13, &x14, 0x0, x9, UINT64_C(0xffffffffffffffed)); + fiat_subborrowx_u64(&x15, &x16, x14, x10, UINT64_C(0xffffffffffffffff)); + fiat_subborrowx_u64(&x17, &x18, x16, x11, UINT64_C(0xffffffffffffffff)); + fiat_subborrowx_u64(&x19, &x20, x18, x12, UINT64_C(0x7fffffffffffffff)); + fiat_cmovznz_u64(&x21, x20, x13, x9); + fiat_cmovznz_u64(&x22, x20, x15, x10); + fiat_cmovznz_u64(&x23, x20, x17, x11); + fiat_cmovznz_u64(&x24, x20, x19, x12); + out1[0] = x21; + out1[1] = x22; + out1[2] = x23; + out1[3] = x24; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +__attribute__((target("adx,bmi2"))) +static void fe4_cswap(uint64_t out1[4], uint64_t out2[4], fiat_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + // NOTE: clang 14 for Zen 2 uses YMM registers + fiat_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_cmovznz_u64(&x5, arg1, (arg3[0]), (arg2[0])); + fiat_cmovznz_u64(&x6, arg1, (arg3[1]), (arg2[1])); + fiat_cmovznz_u64(&x7, arg1, (arg3[2]), (arg2[2])); + fiat_cmovznz_u64(&x8, arg1, (arg3[3]), (arg2[3])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out2[0] = x5; + out2[1] = x6; + out2[2] = x7; + out2[3] = x8; +} + +// The following functions are adaped from crypto/curve25519/curve25519.c +// It would be desirable to share the code, but with the current field +// implementations both 4-limb and 5-limb versions of the curve-level code need +// to be included in builds targetting an unknown variant of x86_64. + +__attribute__((target("adx,bmi2"))) +static void fe4_invert(fe4 out, const fe4 z) { + fe4 t0; + fe4 t1; + fe4 t2; + fe4 t3; + int i; + + fe4_sq(t0, z); + fe4_sq(t1, t0); + for (i = 1; i < 2; ++i) { + fe4_sq(t1, t1); + } + fe4_mul(t1, z, t1); + fe4_mul(t0, t0, t1); + fe4_sq(t2, t0); + fe4_mul(t1, t1, t2); + fe4_sq(t2, t1); + for (i = 1; i < 5; ++i) { + fe4_sq(t2, t2); + } + fe4_mul(t1, t2, t1); + fe4_sq(t2, t1); + for (i = 1; i < 10; ++i) { + fe4_sq(t2, t2); + } + fe4_mul(t2, t2, t1); + fe4_sq(t3, t2); + for (i = 1; i < 20; ++i) { + fe4_sq(t3, t3); + } + fe4_mul(t2, t3, t2); + fe4_sq(t2, t2); + for (i = 1; i < 10; ++i) { + fe4_sq(t2, t2); + } + fe4_mul(t1, t2, t1); + fe4_sq(t2, t1); + for (i = 1; i < 50; ++i) { + fe4_sq(t2, t2); + } + fe4_mul(t2, t2, t1); + fe4_sq(t3, t2); + for (i = 1; i < 100; ++i) { + fe4_sq(t3, t3); + } + fe4_mul(t2, t3, t2); + fe4_sq(t2, t2); + for (i = 1; i < 50; ++i) { + fe4_sq(t2, t2); + } + fe4_mul(t1, t2, t1); + fe4_sq(t1, t1); + for (i = 1; i < 5; ++i) { + fe4_sq(t1, t1); + } + fe4_mul(out, t1, t0); +} + +__attribute__((target("adx,bmi2"))) +void x25519_scalar_mult_adx(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { + uint8_t e[32]; + memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + // The following implementation was transcribed to Coq and proven to + // correspond to unary scalar multiplication in affine coordinates given that + // x1 != 0 is the x coordinate of some point on the curve. It was also checked + // in Coq that doing a ladderstep with x1 = x3 = 0 gives z2' = z3' = 0, and z2 + // = z3 = 0 gives z2' = z3' = 0. The statement was quantified over the + // underlying field, so it applies to Curve25519 itself and the quadratic + // twist of Curve25519. It was not proven in Coq that prime-field arithmetic + // correctly simulates extension-field arithmetic on prime-field values. + // The decoding of the byte array representation of e was not considered. + // Specification of Montgomery curves in affine coordinates: + // + // Proof that these form a group that is isomorphic to a Weierstrass curve: + // + // Coq transcription and correctness proof of the loop (where scalarbits=255): + // + // + // preconditions: 0 <= e < 2^255 (not necessarily e < order), fe_invert(0) = 0 + fe4 x1, x2 = {1}, z2 = {0}, x3, z3 = {1}, tmp0, tmp1; + OPENSSL_memcpy(x1, point, sizeof(fe4)); + x1[3] &= (uint64_t)(-1)>>1; + OPENSSL_memcpy(x3, x1, sizeof(fe4)); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + // loop invariant as of right before the test, for the case where x1 != 0: + // pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 is nonzero + // let r := e >> (pos+1) in the following equalities of projective points: + // to_xz (r*P) === if swap then (x3, z3) else (x2, z2) + // to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3) + // x1 is the nonzero x coordinate of the nonzero point (r*P-(r+1)*P) + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe4_cswap(x2, x3, swap, x2, x3); + fe4_cswap(z2, z3, swap, z2, z3); + swap = b; + // Coq transcription of ladderstep formula (called from transcribed loop): + // + // + // x1 != 0 + // x1 = 0 + fe4_sub(tmp0, x3, z3); + fe4_sub(tmp1, x2, z2); + fe4_add(x2, x2, z2); + fe4_add(z2, x3, z3); + fe4_mul(z3, tmp0, x2); + fe4_mul(z2, z2, tmp1); + fe4_sq(tmp0, tmp1); + fe4_sq(tmp1, x2); + fe4_add(x3, z3, z2); + fe4_sub(z2, z3, z2); + fe4_mul(x2, tmp1, tmp0); + fe4_sub(tmp1, tmp1, tmp0); + fe4_sq(z2, z2); + fe4_scmul(z3, tmp1, 121666); + fe4_sq(x3, x3); + fe4_add(tmp0, tmp0, z3); + fe4_mul(z3, x1, z2); + fe4_mul(z2, tmp1, tmp0); + } + // here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) else (x2, z2) + fe4_cswap(x2, x3, swap, x2, x3); + fe4_cswap(z2, z3, swap, z2, z3); + + fe4_invert(z2, z2); + fe4_mul(x2, x2, z2); + fe4_canon(x2, x2); + OPENSSL_memcpy(out, x2, sizeof(fe4)); +} + +typedef struct { + fe4 X; + fe4 Y; + fe4 Z; + fe4 T; +} ge_p3_4; + +typedef struct { + fe4 yplusx; + fe4 yminusx; + fe4 xy2d; +} ge_precomp_4; + +__attribute__((target("adx,bmi2"))) +static void inline_x25519_ge_dbl_4(ge_p3_4 *r, const ge_p3_4 *p, bool skip_t) { + // Transcribed from a Coq function proven against affine coordinates. + // https://github.com/mit-plv/fiat-crypto/blob/9943ba9e7d8f3e1c0054b2c94a5edca46ea73ef8/src/Curves/Edwards/XYZT/Basic.v#L136-L165 + fe4 trX, trZ, trT, t0, cX, cY, cZ, cT; + fe4_sq(trX, p->X); + fe4_sq(trZ, p->Y); + fe4_sq(trT, p->Z); + fe4_add(trT, trT, trT); + fe4_add(cY, p->X, p->Y); + fe4_sq(t0, cY); + fe4_add(cY, trZ, trX); + fe4_sub(cZ, trZ, trX); + fe4_sub(cX, t0, cY); + fe4_sub(cT, trT, cZ); + fe4_mul(r->X, cX, cT); + fe4_mul(r->Y, cY, cZ); + fe4_mul(r->Z, cZ, cT); + if (!skip_t) { + fe4_mul(r->T, cX, cY); + } +} + +__attribute__((target("adx,bmi2"))) +__attribute__((always_inline)) // 4% speedup with clang14 and zen2 +static inline void +ge_p3_add_p3_precomp_4(ge_p3_4 *r, const ge_p3_4 *p, const ge_precomp_4 *q) { + fe4 A, B, C, YplusX, YminusX, D, X3, Y3, Z3, T3; + // Transcribed from a Coq function proven against affine coordinates. + // https://github.com/mit-plv/fiat-crypto/blob/a36568d1d73aff5d7accc79fd28be672882f9c17/src/Curves/Edwards/XYZT/Precomputed.v#L38-L56 + fe4_add(YplusX, p->Y, p->X); + fe4_sub(YminusX, p->Y, p->X); + fe4_mul(A, YplusX, q->yplusx); + fe4_mul(B, YminusX, q->yminusx); + fe4_mul(C, q->xy2d, p->T); + fe4_add(D, p->Z, p->Z); + fe4_sub(X3, A, B); + fe4_add(Y3, A, B); + fe4_add(Z3, D, C); + fe4_sub(T3, D, C); + fe4_mul(r->X, X3, T3); + fe4_mul(r->Y, Y3, Z3); + fe4_mul(r->Z, Z3, T3); + fe4_mul(r->T, X3, Y3); +} + +__attribute__((always_inline)) // 25% speedup with clang14 and zen2 +static inline void table_select_4(ge_precomp_4 *t, const int pos, + const signed char b) { + uint8_t bnegative = constant_time_msb_w(b); + uint8_t babs = b - ((bnegative & b) << 1); + + uint8_t t_bytes[3][32] = { + {constant_time_is_zero_w(b) & 1}, {constant_time_is_zero_w(b) & 1}, {0}}; +#if defined(__clang__) + __asm__("" : "+m" (t_bytes) : /*no inputs*/); +#endif + static_assert(sizeof(t_bytes) == sizeof(k25519Precomp[pos][0]), ""); + for (int i = 0; i < 8; i++) { + constant_time_conditional_memxor(t_bytes, k25519Precomp[pos][i], + sizeof(t_bytes), + constant_time_eq_w(babs, 1 + i)); + } + + static_assert(sizeof(t_bytes) == sizeof(ge_precomp_4), ""); + + // fe4 uses saturated 64-bit limbs, so converting from bytes is just a copy. + OPENSSL_memcpy(t, t_bytes, sizeof(ge_precomp_4)); + + fe4 xy2d_neg = {0}; + fe4_sub(xy2d_neg, xy2d_neg, t->xy2d); + constant_time_conditional_memcpy(t->yplusx, t_bytes[1], sizeof(fe4), + bnegative); + constant_time_conditional_memcpy(t->yminusx, t_bytes[0], sizeof(fe4), + bnegative); + constant_time_conditional_memcpy(t->xy2d, xy2d_neg, sizeof(fe4), bnegative); +} + +// h = a * B +// where a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +__attribute__((target("adx,bmi2"))) +void x25519_ge_scalarmult_base_adx(uint8_t h[4][32], const uint8_t a[32]) { + signed char e[64]; + signed char carry; + + for (unsigned i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + // each e[i] is between 0 and 15 + // e[63] is between 0 and 7 + + carry = 0; + for (unsigned i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + // each e[i] is between -8 and 8 + + ge_p3_4 r = {{0}, {1}, {1}, {0}}; + for (unsigned i = 1; i < 64; i += 2) { + ge_precomp_4 t; + table_select_4(&t, i / 2, e[i]); + ge_p3_add_p3_precomp_4(&r, &r, &t); + } + + inline_x25519_ge_dbl_4(&r, &r, /*skip_t=*/true); + inline_x25519_ge_dbl_4(&r, &r, /*skip_t=*/true); + inline_x25519_ge_dbl_4(&r, &r, /*skip_t=*/true); + inline_x25519_ge_dbl_4(&r, &r, /*skip_t=*/false); + + for (unsigned i = 0; i < 64; i += 2) { + ge_precomp_4 t; + table_select_4(&t, i / 2, e[i]); + ge_p3_add_p3_precomp_4(&r, &r, &t); + } + + // fe4 uses saturated 64-bit limbs, so converting to bytes is just a copy. + // Satisfy stated precondition of fiat_25519_from_bytes; tests pass either way + fe4_canon(r.X, r.X); + fe4_canon(r.Y, r.Y); + fe4_canon(r.Z, r.Z); + fe4_canon(r.T, r.T); + static_assert(sizeof(ge_p3_4) == sizeof(uint8_t[4][32]), ""); + OPENSSL_memcpy(h, &r, sizeof(ge_p3_4)); +} diff --git a/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_msvc.h b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_msvc.h new file mode 100644 index 00000000..d20ec853 --- /dev/null +++ b/third_party/boringssl/kit/src/third_party/fiat/curve25519_64_msvc.h @@ -0,0 +1,1281 @@ +/* Autogenerated: 'src/ExtractionOCaml/unsaturated_solinas' --inline --static --use-value-barrier --no-wide-int 25519 64 '(auto)' '2^255 - 19' carry_mul carry_square carry add sub opp selectznz to_bytes from_bytes relax carry_scmul121666 */ +/* curve description: 25519 */ +/* machine_wordsize = 64 (from "64") */ +/* requested operations: carry_mul, carry_square, carry, add, sub, opp, selectznz, to_bytes, from_bytes, relax, carry_scmul121666 */ +/* n = 5 (from "(auto)") */ +/* s-c = 2^255 - [(1, 19)] (from "2^255 - 19") */ +/* tight_bounds_multiplier = 1 (from "") */ +/* */ +/* Computed values: */ +/* carry_chain = [0, 1, 2, 3, 4, 0, 1] */ +/* eval z = z[0] + (z[1] << 51) + (z[2] << 102) + (z[3] << 153) + (z[4] << 204) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* balance = [0xfffffffffffda, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe, 0xffffffffffffe] */ + +#include +#include +#if defined(_M_X64) +#include +#endif + +typedef unsigned char fiat_25519_uint1; +typedef signed char fiat_25519_int1; + +#define FIAT_25519_FIAT_INLINE inline + +/* The type fiat_25519_loose_field_element is a field element with loose bounds. */ +/* Bounds: [[0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000], [0x0 ~> 0x18000000000000]] */ +typedef uint64_t fiat_25519_loose_field_element[5]; + +/* The type fiat_25519_tight_field_element is a field element with tight bounds. */ +/* Bounds: [[0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000], [0x0 ~> 0x8000000000000]] */ +typedef uint64_t fiat_25519_tight_field_element[5]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#define fiat_25519_value_barrier_u64(x) (x) + +/* + * The function fiat_25519_addcarryx_u64 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^64 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u64(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { +// NOTE: edited after generation +#if defined(_M_X64) + *out2 = _addcarry_u64(arg1, arg2, arg3, out1); +#else + arg2 += arg1; + arg1 = arg2 < arg1; + arg3 += arg2; + arg1 += arg3 < arg2; + *out1 = arg3; + *out2 = arg1; +#endif +} + +/* + * The function fiat_25519_subborrowx_u64 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^64 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u64(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { +#if defined(_M_X64) + *out2 = _subborrow_u64(arg1, arg2, arg3, out1); // NOTE: edited after generation +#else + *out1 = arg2 - arg3 - arg1; + *out2 = (arg2 < arg3) | ((arg2 == arg3) & arg1); +#endif +} + +/* + * The function fiat_25519_addcarryx_u51 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^51 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^51⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x7ffffffffffff] + * arg3: [0x0 ~> 0x7ffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0x7ffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + uint64_t x1; + uint64_t x2; + fiat_25519_uint1 x3; + x1 = ((arg1 + arg2) + arg3); + x2 = (x1 & UINT64_C(0x7ffffffffffff)); + x3 = (fiat_25519_uint1)(x1 >> 51); + *out1 = x2; + *out2 = x3; +} + +/* + * The function fiat_25519_subborrowx_u51 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^51 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^51⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0x7ffffffffffff] + * arg3: [0x0 ~> 0x7ffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0x7ffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + int64_t x1; + fiat_25519_int1 x2; + uint64_t x3; + x1 = ((int64_t)(arg2 - (int64_t)arg1) - (int64_t)arg3); + x2 = (fiat_25519_int1)(x1 >> 51); + x3 = (x1 & UINT64_C(0x7ffffffffffff)); + *out1 = x3; + *out2 = (fiat_25519_uint1)(0x0 - x2); +} + +/* + * The function fiat_25519_mulx_u64 is a multiplication, returning the full double-width result. + * + * Postconditions: + * out1 = (arg1 * arg2) mod 2^64 + * out2 = ⌊arg1 * arg2 / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { +// NOTE: edited after generation +#if defined(_M_X64) + *out1 = _umul128(arg1, arg2, out2); +#elif defined(_M_ARM64) + *out1 = arg1 * arg2; + *out2 = __umulh(arg1, arg2); +#else +#error "This file is intended for MSVC on X64 or ARM64" +#endif +} + +/* + * The function fiat_25519_cmovznz_u64 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_cmovznz_u64(uint64_t* out1, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_25519_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_25519_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_25519_value_barrier_u64(x2) & arg3) | (fiat_25519_value_barrier_u64((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_25519_carry_mul multiplies two field elements and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_mul(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1, const fiat_25519_loose_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + fiat_25519_uint1 x52; + uint64_t x53; + fiat_25519_uint1 x54; + uint64_t x55; + fiat_25519_uint1 x56; + uint64_t x57; + fiat_25519_uint1 x58; + uint64_t x59; + fiat_25519_uint1 x60; + uint64_t x61; + fiat_25519_uint1 x62; + uint64_t x63; + fiat_25519_uint1 x64; + uint64_t x65; + fiat_25519_uint1 x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + fiat_25519_uint1 x70; + uint64_t x71; + fiat_25519_uint1 x72; + uint64_t x73; + fiat_25519_uint1 x74; + uint64_t x75; + fiat_25519_uint1 x76; + uint64_t x77; + fiat_25519_uint1 x78; + uint64_t x79; + fiat_25519_uint1 x80; + uint64_t x81; + fiat_25519_uint1 x82; + uint64_t x83; + fiat_25519_uint1 x84; + uint64_t x85; + fiat_25519_uint1 x86; + uint64_t x87; + fiat_25519_uint1 x88; + uint64_t x89; + fiat_25519_uint1 x90; + uint64_t x91; + fiat_25519_uint1 x92; + uint64_t x93; + fiat_25519_uint1 x94; + uint64_t x95; + fiat_25519_uint1 x96; + uint64_t x97; + fiat_25519_uint1 x98; + uint64_t x99; + fiat_25519_uint1 x100; + uint64_t x101; + fiat_25519_uint1 x102; + uint64_t x103; + fiat_25519_uint1 x104; + uint64_t x105; + fiat_25519_uint1 x106; + uint64_t x107; + fiat_25519_uint1 x108; + uint64_t x109; + fiat_25519_uint1 x110; + uint64_t x111; + fiat_25519_uint1 x112; + uint64_t x113; + fiat_25519_uint1 x114; + uint64_t x115; + fiat_25519_uint1 x116; + uint64_t x117; + fiat_25519_uint1 x118; + uint64_t x119; + fiat_25519_uint1 x120; + uint64_t x121; + fiat_25519_uint1 x122; + uint64_t x123; + fiat_25519_uint1 x124; + uint64_t x125; + fiat_25519_uint1 x126; + uint64_t x127; + fiat_25519_uint1 x128; + uint64_t x129; + fiat_25519_uint1 x130; + uint64_t x131; + fiat_25519_uint1 x132; + uint64_t x133; + fiat_25519_uint1 x134; + uint64_t x135; + uint64_t x136; + uint64_t x137; + uint64_t x138; + fiat_25519_uint1 x139; + uint64_t x140; + uint64_t x141; + uint64_t x142; + uint64_t x143; + fiat_25519_uint1 x144; + uint64_t x145; + uint64_t x146; + uint64_t x147; + uint64_t x148; + fiat_25519_uint1 x149; + uint64_t x150; + uint64_t x151; + uint64_t x152; + uint64_t x153; + uint64_t x154; + uint64_t x155; + uint64_t x156; + uint64_t x157; + fiat_25519_uint1 x158; + uint64_t x159; + uint64_t x160; + fiat_25519_mulx_u64(&x1, &x2, (arg1[4]), ((arg2[4]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x3, &x4, (arg1[4]), ((arg2[3]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x5, &x6, (arg1[4]), ((arg2[2]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x7, &x8, (arg1[4]), ((arg2[1]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x9, &x10, (arg1[3]), ((arg2[4]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x11, &x12, (arg1[3]), ((arg2[3]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x13, &x14, (arg1[3]), ((arg2[2]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x15, &x16, (arg1[2]), ((arg2[4]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x17, &x18, (arg1[2]), ((arg2[3]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x19, &x20, (arg1[1]), ((arg2[4]) * UINT8_C(0x13))); + fiat_25519_mulx_u64(&x21, &x22, (arg1[4]), (arg2[0])); + fiat_25519_mulx_u64(&x23, &x24, (arg1[3]), (arg2[1])); + fiat_25519_mulx_u64(&x25, &x26, (arg1[3]), (arg2[0])); + fiat_25519_mulx_u64(&x27, &x28, (arg1[2]), (arg2[2])); + fiat_25519_mulx_u64(&x29, &x30, (arg1[2]), (arg2[1])); + fiat_25519_mulx_u64(&x31, &x32, (arg1[2]), (arg2[0])); + fiat_25519_mulx_u64(&x33, &x34, (arg1[1]), (arg2[3])); + fiat_25519_mulx_u64(&x35, &x36, (arg1[1]), (arg2[2])); + fiat_25519_mulx_u64(&x37, &x38, (arg1[1]), (arg2[1])); + fiat_25519_mulx_u64(&x39, &x40, (arg1[1]), (arg2[0])); + fiat_25519_mulx_u64(&x41, &x42, (arg1[0]), (arg2[4])); + fiat_25519_mulx_u64(&x43, &x44, (arg1[0]), (arg2[3])); + fiat_25519_mulx_u64(&x45, &x46, (arg1[0]), (arg2[2])); + fiat_25519_mulx_u64(&x47, &x48, (arg1[0]), (arg2[1])); + fiat_25519_mulx_u64(&x49, &x50, (arg1[0]), (arg2[0])); + fiat_25519_addcarryx_u64(&x51, &x52, 0x0, x13, x7); + fiat_25519_addcarryx_u64(&x53, &x54, x52, x14, x8); + fiat_25519_addcarryx_u64(&x55, &x56, 0x0, x17, x51); + fiat_25519_addcarryx_u64(&x57, &x58, x56, x18, x53); + fiat_25519_addcarryx_u64(&x59, &x60, 0x0, x19, x55); + fiat_25519_addcarryx_u64(&x61, &x62, x60, x20, x57); + fiat_25519_addcarryx_u64(&x63, &x64, 0x0, x49, x59); + fiat_25519_addcarryx_u64(&x65, &x66, x64, x50, x61); + x67 = ((x63 >> 51) | ((x65 << 13) & UINT64_C(0xffffffffffffffff))); + x68 = (x63 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x69, &x70, 0x0, x23, x21); + fiat_25519_addcarryx_u64(&x71, &x72, x70, x24, x22); + fiat_25519_addcarryx_u64(&x73, &x74, 0x0, x27, x69); + fiat_25519_addcarryx_u64(&x75, &x76, x74, x28, x71); + fiat_25519_addcarryx_u64(&x77, &x78, 0x0, x33, x73); + fiat_25519_addcarryx_u64(&x79, &x80, x78, x34, x75); + fiat_25519_addcarryx_u64(&x81, &x82, 0x0, x41, x77); + fiat_25519_addcarryx_u64(&x83, &x84, x82, x42, x79); + fiat_25519_addcarryx_u64(&x85, &x86, 0x0, x25, x1); + fiat_25519_addcarryx_u64(&x87, &x88, x86, x26, x2); + fiat_25519_addcarryx_u64(&x89, &x90, 0x0, x29, x85); + fiat_25519_addcarryx_u64(&x91, &x92, x90, x30, x87); + fiat_25519_addcarryx_u64(&x93, &x94, 0x0, x35, x89); + fiat_25519_addcarryx_u64(&x95, &x96, x94, x36, x91); + fiat_25519_addcarryx_u64(&x97, &x98, 0x0, x43, x93); + fiat_25519_addcarryx_u64(&x99, &x100, x98, x44, x95); + fiat_25519_addcarryx_u64(&x101, &x102, 0x0, x9, x3); + fiat_25519_addcarryx_u64(&x103, &x104, x102, x10, x4); + fiat_25519_addcarryx_u64(&x105, &x106, 0x0, x31, x101); + fiat_25519_addcarryx_u64(&x107, &x108, x106, x32, x103); + fiat_25519_addcarryx_u64(&x109, &x110, 0x0, x37, x105); + fiat_25519_addcarryx_u64(&x111, &x112, x110, x38, x107); + fiat_25519_addcarryx_u64(&x113, &x114, 0x0, x45, x109); + fiat_25519_addcarryx_u64(&x115, &x116, x114, x46, x111); + fiat_25519_addcarryx_u64(&x117, &x118, 0x0, x11, x5); + fiat_25519_addcarryx_u64(&x119, &x120, x118, x12, x6); + fiat_25519_addcarryx_u64(&x121, &x122, 0x0, x15, x117); + fiat_25519_addcarryx_u64(&x123, &x124, x122, x16, x119); + fiat_25519_addcarryx_u64(&x125, &x126, 0x0, x39, x121); + fiat_25519_addcarryx_u64(&x127, &x128, x126, x40, x123); + fiat_25519_addcarryx_u64(&x129, &x130, 0x0, x47, x125); + fiat_25519_addcarryx_u64(&x131, &x132, x130, x48, x127); + fiat_25519_addcarryx_u64(&x133, &x134, 0x0, x67, x129); + x135 = (x134 + x131); + x136 = ((x133 >> 51) | ((x135 << 13) & UINT64_C(0xffffffffffffffff))); + x137 = (x133 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x138, &x139, 0x0, x136, x113); + x140 = (x139 + x115); + x141 = ((x138 >> 51) | ((x140 << 13) & UINT64_C(0xffffffffffffffff))); + x142 = (x138 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x143, &x144, 0x0, x141, x97); + x145 = (x144 + x99); + x146 = ((x143 >> 51) | ((x145 << 13) & UINT64_C(0xffffffffffffffff))); + x147 = (x143 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x148, &x149, 0x0, x146, x81); + x150 = (x149 + x83); + x151 = ((x148 >> 51) | ((x150 << 13) & UINT64_C(0xffffffffffffffff))); + x152 = (x148 & UINT64_C(0x7ffffffffffff)); + x153 = (x151 * UINT8_C(0x13)); + x154 = (x68 + x153); + x155 = (x154 >> 51); + x156 = (x154 & UINT64_C(0x7ffffffffffff)); + x157 = (x155 + x137); + x158 = (fiat_25519_uint1)(x157 >> 51); + x159 = (x157 & UINT64_C(0x7ffffffffffff)); + x160 = (x158 + x142); + out1[0] = x156; + out1[1] = x159; + out1[2] = x160; + out1[3] = x147; + out1[4] = x152; +} + +/* + * The function fiat_25519_carry_square squares a field element and reduces the result. + * + * Postconditions: + * eval out1 mod m = (eval arg1 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_square(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + fiat_25519_uint1 x40; + uint64_t x41; + fiat_25519_uint1 x42; + uint64_t x43; + fiat_25519_uint1 x44; + uint64_t x45; + fiat_25519_uint1 x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + fiat_25519_uint1 x50; + uint64_t x51; + fiat_25519_uint1 x52; + uint64_t x53; + fiat_25519_uint1 x54; + uint64_t x55; + fiat_25519_uint1 x56; + uint64_t x57; + fiat_25519_uint1 x58; + uint64_t x59; + fiat_25519_uint1 x60; + uint64_t x61; + fiat_25519_uint1 x62; + uint64_t x63; + fiat_25519_uint1 x64; + uint64_t x65; + fiat_25519_uint1 x66; + uint64_t x67; + fiat_25519_uint1 x68; + uint64_t x69; + fiat_25519_uint1 x70; + uint64_t x71; + fiat_25519_uint1 x72; + uint64_t x73; + fiat_25519_uint1 x74; + uint64_t x75; + fiat_25519_uint1 x76; + uint64_t x77; + fiat_25519_uint1 x78; + uint64_t x79; + fiat_25519_uint1 x80; + uint64_t x81; + fiat_25519_uint1 x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + fiat_25519_uint1 x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + fiat_25519_uint1 x92; + uint64_t x93; + uint64_t x94; + uint64_t x95; + uint64_t x96; + fiat_25519_uint1 x97; + uint64_t x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint64_t x103; + uint64_t x104; + uint64_t x105; + fiat_25519_uint1 x106; + uint64_t x107; + uint64_t x108; + x1 = ((arg1[4]) * UINT8_C(0x13)); + x2 = (x1 * 0x2); + x3 = ((arg1[4]) * 0x2); + x4 = ((arg1[3]) * UINT8_C(0x13)); + x5 = (x4 * 0x2); + x6 = ((arg1[3]) * 0x2); + x7 = ((arg1[2]) * 0x2); + x8 = ((arg1[1]) * 0x2); + fiat_25519_mulx_u64(&x9, &x10, (arg1[4]), x1); + fiat_25519_mulx_u64(&x11, &x12, (arg1[3]), x2); + fiat_25519_mulx_u64(&x13, &x14, (arg1[3]), x4); + fiat_25519_mulx_u64(&x15, &x16, (arg1[2]), x2); + fiat_25519_mulx_u64(&x17, &x18, (arg1[2]), x5); + fiat_25519_mulx_u64(&x19, &x20, (arg1[2]), (arg1[2])); + fiat_25519_mulx_u64(&x21, &x22, (arg1[1]), x2); + fiat_25519_mulx_u64(&x23, &x24, (arg1[1]), x6); + fiat_25519_mulx_u64(&x25, &x26, (arg1[1]), x7); + fiat_25519_mulx_u64(&x27, &x28, (arg1[1]), (arg1[1])); + fiat_25519_mulx_u64(&x29, &x30, (arg1[0]), x3); + fiat_25519_mulx_u64(&x31, &x32, (arg1[0]), x6); + fiat_25519_mulx_u64(&x33, &x34, (arg1[0]), x7); + fiat_25519_mulx_u64(&x35, &x36, (arg1[0]), x8); + fiat_25519_mulx_u64(&x37, &x38, (arg1[0]), (arg1[0])); + fiat_25519_addcarryx_u64(&x39, &x40, 0x0, x21, x17); + fiat_25519_addcarryx_u64(&x41, &x42, x40, x22, x18); + fiat_25519_addcarryx_u64(&x43, &x44, 0x0, x37, x39); + fiat_25519_addcarryx_u64(&x45, &x46, x44, x38, x41); + x47 = ((x43 >> 51) | ((x45 << 13) & UINT64_C(0xffffffffffffffff))); + x48 = (x43 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x49, &x50, 0x0, x23, x19); + fiat_25519_addcarryx_u64(&x51, &x52, x50, x24, x20); + fiat_25519_addcarryx_u64(&x53, &x54, 0x0, x29, x49); + fiat_25519_addcarryx_u64(&x55, &x56, x54, x30, x51); + fiat_25519_addcarryx_u64(&x57, &x58, 0x0, x25, x9); + fiat_25519_addcarryx_u64(&x59, &x60, x58, x26, x10); + fiat_25519_addcarryx_u64(&x61, &x62, 0x0, x31, x57); + fiat_25519_addcarryx_u64(&x63, &x64, x62, x32, x59); + fiat_25519_addcarryx_u64(&x65, &x66, 0x0, x27, x11); + fiat_25519_addcarryx_u64(&x67, &x68, x66, x28, x12); + fiat_25519_addcarryx_u64(&x69, &x70, 0x0, x33, x65); + fiat_25519_addcarryx_u64(&x71, &x72, x70, x34, x67); + fiat_25519_addcarryx_u64(&x73, &x74, 0x0, x15, x13); + fiat_25519_addcarryx_u64(&x75, &x76, x74, x16, x14); + fiat_25519_addcarryx_u64(&x77, &x78, 0x0, x35, x73); + fiat_25519_addcarryx_u64(&x79, &x80, x78, x36, x75); + fiat_25519_addcarryx_u64(&x81, &x82, 0x0, x47, x77); + x83 = (x82 + x79); + x84 = ((x81 >> 51) | ((x83 << 13) & UINT64_C(0xffffffffffffffff))); + x85 = (x81 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x86, &x87, 0x0, x84, x69); + x88 = (x87 + x71); + x89 = ((x86 >> 51) | ((x88 << 13) & UINT64_C(0xffffffffffffffff))); + x90 = (x86 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x91, &x92, 0x0, x89, x61); + x93 = (x92 + x63); + x94 = ((x91 >> 51) | ((x93 << 13) & UINT64_C(0xffffffffffffffff))); + x95 = (x91 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x96, &x97, 0x0, x94, x53); + x98 = (x97 + x55); + x99 = ((x96 >> 51) | ((x98 << 13) & UINT64_C(0xffffffffffffffff))); + x100 = (x96 & UINT64_C(0x7ffffffffffff)); + x101 = (x99 * UINT8_C(0x13)); + x102 = (x48 + x101); + x103 = (x102 >> 51); + x104 = (x102 & UINT64_C(0x7ffffffffffff)); + x105 = (x103 + x85); + x106 = (fiat_25519_uint1)(x105 >> 51); + x107 = (x105 & UINT64_C(0x7ffffffffffff)); + x108 = (x106 + x90); + out1[0] = x104; + out1[1] = x107; + out1[2] = x108; + out1[3] = x95; + out1[4] = x100; +} + +/* + * The function fiat_25519_carry reduces a field element. + * + * Postconditions: + * eval out1 mod m = eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + x1 = (arg1[0]); + x2 = ((x1 >> 51) + (arg1[1])); + x3 = ((x2 >> 51) + (arg1[2])); + x4 = ((x3 >> 51) + (arg1[3])); + x5 = ((x4 >> 51) + (arg1[4])); + x6 = ((x1 & UINT64_C(0x7ffffffffffff)) + ((x5 >> 51) * UINT8_C(0x13))); + x7 = ((fiat_25519_uint1)(x6 >> 51) + (x2 & UINT64_C(0x7ffffffffffff))); + x8 = (x6 & UINT64_C(0x7ffffffffffff)); + x9 = (x7 & UINT64_C(0x7ffffffffffff)); + x10 = ((fiat_25519_uint1)(x7 >> 51) + (x3 & UINT64_C(0x7ffffffffffff))); + x11 = (x4 & UINT64_C(0x7ffffffffffff)); + x12 = (x5 & UINT64_C(0x7ffffffffffff)); + out1[0] = x8; + out1[1] = x9; + out1[2] = x10; + out1[3] = x11; + out1[4] = x12; +} + +/* + * The function fiat_25519_add adds two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 + eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_add(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((arg1[0]) + (arg2[0])); + x2 = ((arg1[1]) + (arg2[1])); + x3 = ((arg1[2]) + (arg2[2])); + x4 = ((arg1[3]) + (arg2[3])); + x5 = ((arg1[4]) + (arg2[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_sub subtracts two field elements. + * + * Postconditions: + * eval out1 mod m = (eval arg1 - eval arg2) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_sub(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1, const fiat_25519_tight_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = ((UINT64_C(0xfffffffffffda) + (arg1[0])) - (arg2[0])); + x2 = ((UINT64_C(0xffffffffffffe) + (arg1[1])) - (arg2[1])); + x3 = ((UINT64_C(0xffffffffffffe) + (arg1[2])) - (arg2[2])); + x4 = ((UINT64_C(0xffffffffffffe) + (arg1[3])) - (arg2[3])); + x5 = ((UINT64_C(0xffffffffffffe) + (arg1[4])) - (arg2[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_opp negates a field element. + * + * Postconditions: + * eval out1 mod m = -eval arg1 mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_opp(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (UINT64_C(0xfffffffffffda) - (arg1[0])); + x2 = (UINT64_C(0xffffffffffffe) - (arg1[1])); + x3 = (UINT64_C(0xffffffffffffe) - (arg1[2])); + x4 = (UINT64_C(0xffffffffffffe) - (arg1[3])); + x5 = (UINT64_C(0xffffffffffffe) - (arg1[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_selectznz is a multi-limb conditional select. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_selectznz(uint64_t out1[5], fiat_25519_uint1 arg1, const uint64_t arg2[5], const uint64_t arg3[5]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + fiat_25519_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_25519_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_25519_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_25519_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_25519_cmovznz_u64(&x5, arg1, (arg2[4]), (arg3[4])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_to_bytes serializes a field element to bytes in little-endian order. + * + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_to_bytes(uint8_t out1[32], const fiat_25519_tight_field_element arg1) { + uint64_t x1; + fiat_25519_uint1 x2; + uint64_t x3; + fiat_25519_uint1 x4; + uint64_t x5; + fiat_25519_uint1 x6; + uint64_t x7; + fiat_25519_uint1 x8; + uint64_t x9; + fiat_25519_uint1 x10; + uint64_t x11; + uint64_t x12; + fiat_25519_uint1 x13; + uint64_t x14; + fiat_25519_uint1 x15; + uint64_t x16; + fiat_25519_uint1 x17; + uint64_t x18; + fiat_25519_uint1 x19; + uint64_t x20; + fiat_25519_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint8_t x26; + uint64_t x27; + uint8_t x28; + uint64_t x29; + uint8_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint8_t x34; + uint64_t x35; + uint8_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint64_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint8_t x50; + uint64_t x51; + uint8_t x52; + uint64_t x53; + uint8_t x54; + uint64_t x55; + uint8_t x56; + uint64_t x57; + uint8_t x58; + uint64_t x59; + uint8_t x60; + uint64_t x61; + uint8_t x62; + uint64_t x63; + uint8_t x64; + fiat_25519_uint1 x65; + uint64_t x66; + uint8_t x67; + uint64_t x68; + uint8_t x69; + uint64_t x70; + uint8_t x71; + uint64_t x72; + uint8_t x73; + uint64_t x74; + uint8_t x75; + uint64_t x76; + uint8_t x77; + uint8_t x78; + uint64_t x79; + uint8_t x80; + uint64_t x81; + uint8_t x82; + uint64_t x83; + uint8_t x84; + uint64_t x85; + uint8_t x86; + uint64_t x87; + uint8_t x88; + uint64_t x89; + uint8_t x90; + uint8_t x91; + fiat_25519_subborrowx_u51(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0x7ffffffffffed)); + fiat_25519_subborrowx_u51(&x3, &x4, x2, (arg1[1]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x5, &x6, x4, (arg1[2]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x7, &x8, x6, (arg1[3]), UINT64_C(0x7ffffffffffff)); + fiat_25519_subborrowx_u51(&x9, &x10, x8, (arg1[4]), UINT64_C(0x7ffffffffffff)); + fiat_25519_cmovznz_u64(&x11, x10, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_25519_addcarryx_u51(&x12, &x13, 0x0, x1, (x11 & UINT64_C(0x7ffffffffffed))); + fiat_25519_addcarryx_u51(&x14, &x15, x13, x3, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x16, &x17, x15, x5, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x18, &x19, x17, x7, (x11 & UINT64_C(0x7ffffffffffff))); + fiat_25519_addcarryx_u51(&x20, &x21, x19, x9, (x11 & UINT64_C(0x7ffffffffffff))); + x22 = (x20 << 4); + x23 = (x18 * (uint64_t)0x2); + x24 = (x16 << 6); + x25 = (x14 << 3); + x26 = (uint8_t)(x12 & UINT8_C(0xff)); + x27 = (x12 >> 8); + x28 = (uint8_t)(x27 & UINT8_C(0xff)); + x29 = (x27 >> 8); + x30 = (uint8_t)(x29 & UINT8_C(0xff)); + x31 = (x29 >> 8); + x32 = (uint8_t)(x31 & UINT8_C(0xff)); + x33 = (x31 >> 8); + x34 = (uint8_t)(x33 & UINT8_C(0xff)); + x35 = (x33 >> 8); + x36 = (uint8_t)(x35 & UINT8_C(0xff)); + x37 = (uint8_t)(x35 >> 8); + x38 = (x25 + (uint64_t)x37); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (x44 >> 8); + x47 = (uint8_t)(x46 & UINT8_C(0xff)); + x48 = (x46 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (uint8_t)(x48 >> 8); + x51 = (x24 + (uint64_t)x50); + x52 = (uint8_t)(x51 & UINT8_C(0xff)); + x53 = (x51 >> 8); + x54 = (uint8_t)(x53 & UINT8_C(0xff)); + x55 = (x53 >> 8); + x56 = (uint8_t)(x55 & UINT8_C(0xff)); + x57 = (x55 >> 8); + x58 = (uint8_t)(x57 & UINT8_C(0xff)); + x59 = (x57 >> 8); + x60 = (uint8_t)(x59 & UINT8_C(0xff)); + x61 = (x59 >> 8); + x62 = (uint8_t)(x61 & UINT8_C(0xff)); + x63 = (x61 >> 8); + x64 = (uint8_t)(x63 & UINT8_C(0xff)); + x65 = (fiat_25519_uint1)(x63 >> 8); + x66 = (x23 + (uint64_t)x65); + x67 = (uint8_t)(x66 & UINT8_C(0xff)); + x68 = (x66 >> 8); + x69 = (uint8_t)(x68 & UINT8_C(0xff)); + x70 = (x68 >> 8); + x71 = (uint8_t)(x70 & UINT8_C(0xff)); + x72 = (x70 >> 8); + x73 = (uint8_t)(x72 & UINT8_C(0xff)); + x74 = (x72 >> 8); + x75 = (uint8_t)(x74 & UINT8_C(0xff)); + x76 = (x74 >> 8); + x77 = (uint8_t)(x76 & UINT8_C(0xff)); + x78 = (uint8_t)(x76 >> 8); + x79 = (x22 + (uint64_t)x78); + x80 = (uint8_t)(x79 & UINT8_C(0xff)); + x81 = (x79 >> 8); + x82 = (uint8_t)(x81 & UINT8_C(0xff)); + x83 = (x81 >> 8); + x84 = (uint8_t)(x83 & UINT8_C(0xff)); + x85 = (x83 >> 8); + x86 = (uint8_t)(x85 & UINT8_C(0xff)); + x87 = (x85 >> 8); + x88 = (uint8_t)(x87 & UINT8_C(0xff)); + x89 = (x87 >> 8); + x90 = (uint8_t)(x89 & UINT8_C(0xff)); + x91 = (uint8_t)(x89 >> 8); + out1[0] = x26; + out1[1] = x28; + out1[2] = x30; + out1[3] = x32; + out1[4] = x34; + out1[5] = x36; + out1[6] = x39; + out1[7] = x41; + out1[8] = x43; + out1[9] = x45; + out1[10] = x47; + out1[11] = x49; + out1[12] = x52; + out1[13] = x54; + out1[14] = x56; + out1[15] = x58; + out1[16] = x60; + out1[17] = x62; + out1[18] = x64; + out1[19] = x67; + out1[20] = x69; + out1[21] = x71; + out1[22] = x73; + out1[23] = x75; + out1[24] = x77; + out1[25] = x80; + out1[26] = x82; + out1[27] = x84; + out1[28] = x86; + out1[29] = x88; + out1[30] = x90; + out1[31] = x91; +} + +/* + * The function fiat_25519_from_bytes deserializes a field element from bytes in little-endian order. + * + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x7f]] + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_from_bytes(fiat_25519_tight_field_element out1, const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint8_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint8_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint8_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + uint64_t x71; + x1 = ((uint64_t)(arg1[31]) << 44); + x2 = ((uint64_t)(arg1[30]) << 36); + x3 = ((uint64_t)(arg1[29]) << 28); + x4 = ((uint64_t)(arg1[28]) << 20); + x5 = ((uint64_t)(arg1[27]) << 12); + x6 = ((uint64_t)(arg1[26]) << 4); + x7 = ((uint64_t)(arg1[25]) << 47); + x8 = ((uint64_t)(arg1[24]) << 39); + x9 = ((uint64_t)(arg1[23]) << 31); + x10 = ((uint64_t)(arg1[22]) << 23); + x11 = ((uint64_t)(arg1[21]) << 15); + x12 = ((uint64_t)(arg1[20]) << 7); + x13 = ((uint64_t)(arg1[19]) << 50); + x14 = ((uint64_t)(arg1[18]) << 42); + x15 = ((uint64_t)(arg1[17]) << 34); + x16 = ((uint64_t)(arg1[16]) << 26); + x17 = ((uint64_t)(arg1[15]) << 18); + x18 = ((uint64_t)(arg1[14]) << 10); + x19 = ((uint64_t)(arg1[13]) << 2); + x20 = ((uint64_t)(arg1[12]) << 45); + x21 = ((uint64_t)(arg1[11]) << 37); + x22 = ((uint64_t)(arg1[10]) << 29); + x23 = ((uint64_t)(arg1[9]) << 21); + x24 = ((uint64_t)(arg1[8]) << 13); + x25 = ((uint64_t)(arg1[7]) << 5); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x38 & UINT64_C(0x7ffffffffffff)); + x40 = (uint8_t)(x38 >> 51); + x41 = (x25 + (uint64_t)x40); + x42 = (x24 + x41); + x43 = (x23 + x42); + x44 = (x22 + x43); + x45 = (x21 + x44); + x46 = (x20 + x45); + x47 = (x46 & UINT64_C(0x7ffffffffffff)); + x48 = (uint8_t)(x46 >> 51); + x49 = (x19 + (uint64_t)x48); + x50 = (x18 + x49); + x51 = (x17 + x50); + x52 = (x16 + x51); + x53 = (x15 + x52); + x54 = (x14 + x53); + x55 = (x13 + x54); + x56 = (x55 & UINT64_C(0x7ffffffffffff)); + x57 = (uint8_t)(x55 >> 51); + x58 = (x12 + (uint64_t)x57); + x59 = (x11 + x58); + x60 = (x10 + x59); + x61 = (x9 + x60); + x62 = (x8 + x61); + x63 = (x7 + x62); + x64 = (x63 & UINT64_C(0x7ffffffffffff)); + x65 = (uint8_t)(x63 >> 51); + x66 = (x6 + (uint64_t)x65); + x67 = (x5 + x66); + x68 = (x4 + x67); + x69 = (x3 + x68); + x70 = (x2 + x69); + x71 = (x1 + x70); + out1[0] = x39; + out1[1] = x47; + out1[2] = x56; + out1[3] = x64; + out1[4] = x71; +} + +/* + * The function fiat_25519_relax is the identity function converting from tight field elements to loose field elements. + * + * Postconditions: + * out1 = arg1 + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_relax(fiat_25519_loose_field_element out1, const fiat_25519_tight_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + x1 = (arg1[0]); + x2 = (arg1[1]); + x3 = (arg1[2]); + x4 = (arg1[3]); + x5 = (arg1[4]); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; +} + +/* + * The function fiat_25519_carry_scmul_121666 multiplies a field element by 121666 and reduces the result. + * + * Postconditions: + * eval out1 mod m = (121666 * eval arg1) mod m + * + */ +static FIAT_25519_FIAT_INLINE void fiat_25519_carry_scmul_121666(fiat_25519_tight_field_element out1, const fiat_25519_loose_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_25519_uint1 x14; + uint64_t x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + fiat_25519_uint1 x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + fiat_25519_uint1 x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + fiat_25519_uint1 x29; + uint64_t x30; + uint64_t x31; + uint64_t x32; + uint64_t x33; + uint64_t x34; + fiat_25519_uint1 x35; + uint64_t x36; + uint64_t x37; + fiat_25519_uint1 x38; + uint64_t x39; + uint64_t x40; + fiat_25519_mulx_u64(&x1, &x2, UINT32_C(0x1db42), (arg1[4])); + fiat_25519_mulx_u64(&x3, &x4, UINT32_C(0x1db42), (arg1[3])); + fiat_25519_mulx_u64(&x5, &x6, UINT32_C(0x1db42), (arg1[2])); + fiat_25519_mulx_u64(&x7, &x8, UINT32_C(0x1db42), (arg1[1])); + fiat_25519_mulx_u64(&x9, &x10, UINT32_C(0x1db42), (arg1[0])); + x11 = ((x9 >> 51) | ((x10 << 13) & UINT64_C(0xffffffffffffffff))); + x12 = (x9 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x13, &x14, 0x0, x11, x7); + x15 = (x14 + x8); + x16 = ((x13 >> 51) | ((x15 << 13) & UINT64_C(0xffffffffffffffff))); + x17 = (x13 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x18, &x19, 0x0, x16, x5); + x20 = (x19 + x6); + x21 = ((x18 >> 51) | ((x20 << 13) & UINT64_C(0xffffffffffffffff))); + x22 = (x18 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x23, &x24, 0x0, x21, x3); + x25 = (x24 + x4); + x26 = ((x23 >> 51) | ((x25 << 13) & UINT64_C(0xffffffffffffffff))); + x27 = (x23 & UINT64_C(0x7ffffffffffff)); + fiat_25519_addcarryx_u64(&x28, &x29, 0x0, x26, x1); + x30 = (x29 + x2); + x31 = ((x28 >> 51) | ((x30 << 13) & UINT64_C(0xffffffffffffffff))); + x32 = (x28 & UINT64_C(0x7ffffffffffff)); + x33 = (x31 * UINT8_C(0x13)); + x34 = (x12 + x33); + x35 = (fiat_25519_uint1)(x34 >> 51); + x36 = (x34 & UINT64_C(0x7ffffffffffff)); + x37 = (x35 + x17); + x38 = (fiat_25519_uint1)(x37 >> 51); + x39 = (x37 & UINT64_C(0x7ffffffffffff)); + x40 = (x38 + x22); + out1[0] = x36; + out1[1] = x39; + out1[2] = x40; + out1[3] = x27; + out1[4] = x32; +} diff --git a/third_party/boringssl/kit/src/third_party/fiat/p256_32.h b/third_party/boringssl/kit/src/third_party/fiat/p256_32.h index 504da42d..3812d8ce 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/p256_32.h +++ b/third_party/boringssl/kit/src/third_party/fiat/p256_32.h @@ -1,8 +1,8 @@ -/* Autogenerated: src/ExtractionOCaml/word_by_word_montgomery --static p256 '2^256 - 2^224 + 2^192 + 2^96 - 1' 32 mul square add sub opp from_montgomery nonzero selectznz to_bytes from_bytes */ +/* Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --inline --static --use-value-barrier p256 32 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp */ /* curve description: p256 */ -/* requested operations: mul, square, add, sub, opp, from_montgomery, nonzero, selectznz, to_bytes, from_bytes */ -/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ /* machine_wordsize = 32 (from "32") */ +/* requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp */ +/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ /* */ /* NOTE: In addition to the bounds specified above each function, all */ /* functions synthesized for this Montgomery arithmetic require the */ @@ -10,18 +10,47 @@ /* require the input to be in the unique saturated representation. */ /* All functions also ensure that these two properties are true of */ /* return values. */ +/* */ +/* Computed values: */ +/* eval z = z[0] + (z[1] << 32) + (z[2] << 64) + (z[3] << 96) + (z[4] << 128) + (z[5] << 160) + (z[6] << 192) + (z[7] << 224) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* twos_complement_eval z = let x1 := z[0] + (z[1] << 32) + (z[2] << 64) + (z[3] << 96) + (z[4] << 128) + (z[5] << 160) + (z[6] << 192) + (z[7] << 224) in */ +/* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ #include typedef unsigned char fiat_p256_uint1; typedef signed char fiat_p256_int1; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_P256_FIAT_INLINE __inline__ +#else +# define FIAT_P256_FIAT_INLINE +#endif + +/* The type fiat_p256_montgomery_domain_field_element is a field element in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ +typedef uint32_t fiat_p256_montgomery_domain_field_element[8]; + +/* The type fiat_p256_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ +typedef uint32_t fiat_p256_non_montgomery_domain_field_element[8]; #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif +#if !defined(FIAT_P256_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint32_t fiat_p256_value_barrier_u32(uint32_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_p256_value_barrier_u32(x) (x) +#endif + /* * The function fiat_p256_addcarryx_u32 is an addition with carry. + * * Postconditions: * out1 = (arg1 + arg2 + arg3) mod 2^32 * out2 = ⌊(arg1 + arg2 + arg3) / 2^32⌋ @@ -34,16 +63,20 @@ typedef signed char fiat_p256_int1; * out1: [0x0 ~> 0xffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_p256_addcarryx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { - uint64_t x1 = ((arg1 + (uint64_t)arg2) + arg3); - uint32_t x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); - fiat_p256_uint1 x3 = (fiat_p256_uint1)(x1 >> 32); +static FIAT_P256_FIAT_INLINE void fiat_p256_addcarryx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint64_t x1; + uint32_t x2; + fiat_p256_uint1 x3; + x1 = ((arg1 + (uint64_t)arg2) + arg3); + x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + x3 = (fiat_p256_uint1)(x1 >> 32); *out1 = x2; *out2 = x3; } /* * The function fiat_p256_subborrowx_u32 is a subtraction with borrow. + * * Postconditions: * out1 = (-arg1 + arg2 + -arg3) mod 2^32 * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^32⌋ @@ -56,16 +89,20 @@ static void fiat_p256_addcarryx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_ * out1: [0x0 ~> 0xffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_p256_subborrowx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { - int64_t x1 = ((arg2 - (int64_t)arg1) - arg3); - fiat_p256_int1 x2 = (fiat_p256_int1)(x1 >> 32); - uint32_t x3 = (uint32_t)(x1 & UINT32_C(0xffffffff)); +static FIAT_P256_FIAT_INLINE void fiat_p256_subborrowx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int64_t x1; + fiat_p256_int1 x2; + uint32_t x3; + x1 = ((arg2 - (int64_t)arg1) - arg3); + x2 = (fiat_p256_int1)(x1 >> 32); + x3 = (uint32_t)(x1 & UINT32_C(0xffffffff)); *out1 = x3; *out2 = (fiat_p256_uint1)(0x0 - x2); } /* * The function fiat_p256_mulx_u32 is a multiplication, returning the full double-width result. + * * Postconditions: * out1 = (arg1 * arg2) mod 2^32 * out2 = ⌊arg1 * arg2 / 2^32⌋ @@ -77,16 +114,20 @@ static void fiat_p256_subborrowx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat * out1: [0x0 ~> 0xffffffff] * out2: [0x0 ~> 0xffffffff] */ -static void fiat_p256_mulx_u32(uint32_t* out1, uint32_t* out2, uint32_t arg1, uint32_t arg2) { - uint64_t x1 = ((uint64_t)arg1 * arg2); - uint32_t x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); - uint32_t x3 = (uint32_t)(x1 >> 32); +static FIAT_P256_FIAT_INLINE void fiat_p256_mulx_u32(uint32_t* out1, uint32_t* out2, uint32_t arg1, uint32_t arg2) { + uint64_t x1; + uint32_t x2; + uint32_t x3; + x1 = ((uint64_t)arg1 * arg2); + x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + x3 = (uint32_t)(x1 >> 32); *out1 = x2; *out2 = x3; } /* * The function fiat_p256_cmovznz_u32 is a single-word conditional move. + * * Postconditions: * out1 = (if arg1 = 0 then arg2 else arg3) * @@ -97,21 +138,19 @@ static void fiat_p256_mulx_u32(uint32_t* out1, uint32_t* out2, uint32_t arg1, ui * Output Bounds: * out1: [0x0 ~> 0xffffffff] */ -static void fiat_p256_cmovznz_u32(uint32_t* out1, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { - fiat_p256_uint1 x1 = (!(!arg1)); - uint32_t x2 = ((fiat_p256_int1)(0x0 - x1) & UINT32_C(0xffffffff)); - // Note this line has been patched from the synthesized code to add value - // barriers. - // - // Clang recognizes this pattern as a select. While it usually transforms it - // to a cmov, it sometimes further transforms it into a branch, which we do - // not want. - uint32_t x3 = ((value_barrier_u32(x2) & arg3) | (value_barrier_u32(~x2) & arg2)); +static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u32(uint32_t* out1, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + fiat_p256_uint1 x1; + uint32_t x2; + uint32_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_p256_int1)(0x0 - x1) & UINT32_C(0xffffffff)); + x3 = ((fiat_p256_value_barrier_u32(x2) & arg3) | (fiat_p256_value_barrier_u32((~x2)) & arg2)); *out1 = x3; } /* * The function fiat_p256_mul multiplies two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -119,995 +158,1021 @@ static void fiat_p256_cmovznz_u32(uint32_t* out1, fiat_p256_uint1 arg1, uint32_t * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_mul(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { - uint32_t x1 = (arg1[1]); - uint32_t x2 = (arg1[2]); - uint32_t x3 = (arg1[3]); - uint32_t x4 = (arg1[4]); - uint32_t x5 = (arg1[5]); - uint32_t x6 = (arg1[6]); - uint32_t x7 = (arg1[7]); - uint32_t x8 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; uint32_t x9; uint32_t x10; - fiat_p256_mulx_u32(&x9, &x10, x8, (arg2[7])); uint32_t x11; uint32_t x12; - fiat_p256_mulx_u32(&x11, &x12, x8, (arg2[6])); uint32_t x13; uint32_t x14; - fiat_p256_mulx_u32(&x13, &x14, x8, (arg2[5])); uint32_t x15; uint32_t x16; - fiat_p256_mulx_u32(&x15, &x16, x8, (arg2[4])); uint32_t x17; uint32_t x18; - fiat_p256_mulx_u32(&x17, &x18, x8, (arg2[3])); uint32_t x19; uint32_t x20; - fiat_p256_mulx_u32(&x19, &x20, x8, (arg2[2])); uint32_t x21; uint32_t x22; - fiat_p256_mulx_u32(&x21, &x22, x8, (arg2[1])); uint32_t x23; uint32_t x24; - fiat_p256_mulx_u32(&x23, &x24, x8, (arg2[0])); uint32_t x25; fiat_p256_uint1 x26; - fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); uint32_t x27; fiat_p256_uint1 x28; - fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); uint32_t x29; fiat_p256_uint1 x30; - fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); uint32_t x31; fiat_p256_uint1 x32; - fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); uint32_t x33; fiat_p256_uint1 x34; - fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); uint32_t x35; fiat_p256_uint1 x36; - fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); uint32_t x37; fiat_p256_uint1 x38; - fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); - uint32_t x39 = (x38 + x10); + uint32_t x39; uint32_t x40; uint32_t x41; - fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); uint32_t x42; uint32_t x43; - fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); uint32_t x44; uint32_t x45; - fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); uint32_t x46; uint32_t x47; - fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); uint32_t x48; fiat_p256_uint1 x49; - fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); uint32_t x50; fiat_p256_uint1 x51; - fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); - uint32_t x52 = (x51 + x43); + uint32_t x52; uint32_t x53; fiat_p256_uint1 x54; - fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); uint32_t x55; fiat_p256_uint1 x56; - fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); uint32_t x57; fiat_p256_uint1 x58; - fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); uint32_t x59; fiat_p256_uint1 x60; - fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); uint32_t x61; fiat_p256_uint1 x62; - fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); uint32_t x63; fiat_p256_uint1 x64; - fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); uint32_t x65; fiat_p256_uint1 x66; - fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); uint32_t x67; fiat_p256_uint1 x68; - fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); uint32_t x69; fiat_p256_uint1 x70; - fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); uint32_t x71; uint32_t x72; - fiat_p256_mulx_u32(&x71, &x72, x1, (arg2[7])); uint32_t x73; uint32_t x74; - fiat_p256_mulx_u32(&x73, &x74, x1, (arg2[6])); uint32_t x75; uint32_t x76; - fiat_p256_mulx_u32(&x75, &x76, x1, (arg2[5])); uint32_t x77; uint32_t x78; - fiat_p256_mulx_u32(&x77, &x78, x1, (arg2[4])); uint32_t x79; uint32_t x80; - fiat_p256_mulx_u32(&x79, &x80, x1, (arg2[3])); uint32_t x81; uint32_t x82; - fiat_p256_mulx_u32(&x81, &x82, x1, (arg2[2])); uint32_t x83; uint32_t x84; - fiat_p256_mulx_u32(&x83, &x84, x1, (arg2[1])); uint32_t x85; uint32_t x86; - fiat_p256_mulx_u32(&x85, &x86, x1, (arg2[0])); uint32_t x87; fiat_p256_uint1 x88; - fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); uint32_t x89; fiat_p256_uint1 x90; - fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); uint32_t x91; fiat_p256_uint1 x92; - fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); uint32_t x93; fiat_p256_uint1 x94; - fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); uint32_t x95; fiat_p256_uint1 x96; - fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); uint32_t x97; fiat_p256_uint1 x98; - fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); uint32_t x99; fiat_p256_uint1 x100; - fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); - uint32_t x101 = (x100 + x72); + uint32_t x101; uint32_t x102; fiat_p256_uint1 x103; - fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); uint32_t x104; fiat_p256_uint1 x105; - fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); uint32_t x106; fiat_p256_uint1 x107; - fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); uint32_t x108; fiat_p256_uint1 x109; - fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); uint32_t x110; fiat_p256_uint1 x111; - fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); uint32_t x112; fiat_p256_uint1 x113; - fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); uint32_t x114; fiat_p256_uint1 x115; - fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); uint32_t x116; fiat_p256_uint1 x117; - fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); uint32_t x118; fiat_p256_uint1 x119; - fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); uint32_t x120; uint32_t x121; - fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); uint32_t x122; uint32_t x123; - fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); uint32_t x124; uint32_t x125; - fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); uint32_t x126; uint32_t x127; - fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); uint32_t x128; fiat_p256_uint1 x129; - fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); uint32_t x130; fiat_p256_uint1 x131; - fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); - uint32_t x132 = (x131 + x123); + uint32_t x132; uint32_t x133; fiat_p256_uint1 x134; - fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); uint32_t x135; fiat_p256_uint1 x136; - fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); uint32_t x137; fiat_p256_uint1 x138; - fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); uint32_t x139; fiat_p256_uint1 x140; - fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); uint32_t x141; fiat_p256_uint1 x142; - fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); uint32_t x143; fiat_p256_uint1 x144; - fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); uint32_t x145; fiat_p256_uint1 x146; - fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); uint32_t x147; fiat_p256_uint1 x148; - fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); uint32_t x149; fiat_p256_uint1 x150; - fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); - uint32_t x151 = ((uint32_t)x150 + x119); + uint32_t x151; uint32_t x152; uint32_t x153; - fiat_p256_mulx_u32(&x152, &x153, x2, (arg2[7])); uint32_t x154; uint32_t x155; - fiat_p256_mulx_u32(&x154, &x155, x2, (arg2[6])); uint32_t x156; uint32_t x157; - fiat_p256_mulx_u32(&x156, &x157, x2, (arg2[5])); uint32_t x158; uint32_t x159; - fiat_p256_mulx_u32(&x158, &x159, x2, (arg2[4])); uint32_t x160; uint32_t x161; - fiat_p256_mulx_u32(&x160, &x161, x2, (arg2[3])); uint32_t x162; uint32_t x163; - fiat_p256_mulx_u32(&x162, &x163, x2, (arg2[2])); uint32_t x164; uint32_t x165; - fiat_p256_mulx_u32(&x164, &x165, x2, (arg2[1])); uint32_t x166; uint32_t x167; - fiat_p256_mulx_u32(&x166, &x167, x2, (arg2[0])); uint32_t x168; fiat_p256_uint1 x169; - fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); uint32_t x170; fiat_p256_uint1 x171; - fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); uint32_t x172; fiat_p256_uint1 x173; - fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); uint32_t x174; fiat_p256_uint1 x175; - fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); uint32_t x176; fiat_p256_uint1 x177; - fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); uint32_t x178; fiat_p256_uint1 x179; - fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); uint32_t x180; fiat_p256_uint1 x181; - fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); - uint32_t x182 = (x181 + x153); + uint32_t x182; uint32_t x183; fiat_p256_uint1 x184; - fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); uint32_t x185; fiat_p256_uint1 x186; - fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); uint32_t x187; fiat_p256_uint1 x188; - fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); uint32_t x189; fiat_p256_uint1 x190; - fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); uint32_t x191; fiat_p256_uint1 x192; - fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); uint32_t x193; fiat_p256_uint1 x194; - fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); uint32_t x195; fiat_p256_uint1 x196; - fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); uint32_t x197; fiat_p256_uint1 x198; - fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); uint32_t x199; fiat_p256_uint1 x200; - fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); uint32_t x201; uint32_t x202; - fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); uint32_t x203; uint32_t x204; - fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); uint32_t x205; uint32_t x206; - fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); uint32_t x207; uint32_t x208; - fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); uint32_t x209; fiat_p256_uint1 x210; - fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); uint32_t x211; fiat_p256_uint1 x212; - fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); - uint32_t x213 = (x212 + x204); + uint32_t x213; uint32_t x214; fiat_p256_uint1 x215; - fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); uint32_t x216; fiat_p256_uint1 x217; - fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); uint32_t x218; fiat_p256_uint1 x219; - fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); uint32_t x220; fiat_p256_uint1 x221; - fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); uint32_t x222; fiat_p256_uint1 x223; - fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); uint32_t x224; fiat_p256_uint1 x225; - fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); uint32_t x226; fiat_p256_uint1 x227; - fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); uint32_t x228; fiat_p256_uint1 x229; - fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); uint32_t x230; fiat_p256_uint1 x231; - fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); - uint32_t x232 = ((uint32_t)x231 + x200); + uint32_t x232; uint32_t x233; uint32_t x234; - fiat_p256_mulx_u32(&x233, &x234, x3, (arg2[7])); uint32_t x235; uint32_t x236; - fiat_p256_mulx_u32(&x235, &x236, x3, (arg2[6])); uint32_t x237; uint32_t x238; - fiat_p256_mulx_u32(&x237, &x238, x3, (arg2[5])); uint32_t x239; uint32_t x240; - fiat_p256_mulx_u32(&x239, &x240, x3, (arg2[4])); uint32_t x241; uint32_t x242; - fiat_p256_mulx_u32(&x241, &x242, x3, (arg2[3])); uint32_t x243; uint32_t x244; - fiat_p256_mulx_u32(&x243, &x244, x3, (arg2[2])); uint32_t x245; uint32_t x246; - fiat_p256_mulx_u32(&x245, &x246, x3, (arg2[1])); uint32_t x247; uint32_t x248; - fiat_p256_mulx_u32(&x247, &x248, x3, (arg2[0])); uint32_t x249; fiat_p256_uint1 x250; - fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); uint32_t x251; fiat_p256_uint1 x252; - fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); uint32_t x253; fiat_p256_uint1 x254; - fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); uint32_t x255; fiat_p256_uint1 x256; - fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); uint32_t x257; fiat_p256_uint1 x258; - fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); uint32_t x259; fiat_p256_uint1 x260; - fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); uint32_t x261; fiat_p256_uint1 x262; - fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); - uint32_t x263 = (x262 + x234); + uint32_t x263; uint32_t x264; fiat_p256_uint1 x265; - fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); uint32_t x266; fiat_p256_uint1 x267; - fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); uint32_t x268; fiat_p256_uint1 x269; - fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); uint32_t x270; fiat_p256_uint1 x271; - fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); uint32_t x272; fiat_p256_uint1 x273; - fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); uint32_t x274; fiat_p256_uint1 x275; - fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); uint32_t x276; fiat_p256_uint1 x277; - fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); uint32_t x278; fiat_p256_uint1 x279; - fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); uint32_t x280; fiat_p256_uint1 x281; - fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); uint32_t x282; uint32_t x283; - fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); uint32_t x284; uint32_t x285; - fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); uint32_t x286; uint32_t x287; - fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); uint32_t x288; uint32_t x289; - fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); uint32_t x290; fiat_p256_uint1 x291; - fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); uint32_t x292; fiat_p256_uint1 x293; - fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); - uint32_t x294 = (x293 + x285); + uint32_t x294; uint32_t x295; fiat_p256_uint1 x296; - fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); uint32_t x297; fiat_p256_uint1 x298; - fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); uint32_t x299; fiat_p256_uint1 x300; - fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); uint32_t x301; fiat_p256_uint1 x302; - fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); uint32_t x303; fiat_p256_uint1 x304; - fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); uint32_t x305; fiat_p256_uint1 x306; - fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); uint32_t x307; fiat_p256_uint1 x308; - fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); uint32_t x309; fiat_p256_uint1 x310; - fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); uint32_t x311; fiat_p256_uint1 x312; - fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); - uint32_t x313 = ((uint32_t)x312 + x281); + uint32_t x313; uint32_t x314; uint32_t x315; - fiat_p256_mulx_u32(&x314, &x315, x4, (arg2[7])); uint32_t x316; uint32_t x317; - fiat_p256_mulx_u32(&x316, &x317, x4, (arg2[6])); uint32_t x318; uint32_t x319; - fiat_p256_mulx_u32(&x318, &x319, x4, (arg2[5])); uint32_t x320; uint32_t x321; - fiat_p256_mulx_u32(&x320, &x321, x4, (arg2[4])); uint32_t x322; uint32_t x323; - fiat_p256_mulx_u32(&x322, &x323, x4, (arg2[3])); uint32_t x324; uint32_t x325; - fiat_p256_mulx_u32(&x324, &x325, x4, (arg2[2])); uint32_t x326; uint32_t x327; - fiat_p256_mulx_u32(&x326, &x327, x4, (arg2[1])); uint32_t x328; uint32_t x329; - fiat_p256_mulx_u32(&x328, &x329, x4, (arg2[0])); uint32_t x330; fiat_p256_uint1 x331; - fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); uint32_t x332; fiat_p256_uint1 x333; - fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); uint32_t x334; fiat_p256_uint1 x335; - fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); uint32_t x336; fiat_p256_uint1 x337; - fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); uint32_t x338; fiat_p256_uint1 x339; - fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); uint32_t x340; fiat_p256_uint1 x341; - fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); uint32_t x342; fiat_p256_uint1 x343; - fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); - uint32_t x344 = (x343 + x315); + uint32_t x344; uint32_t x345; fiat_p256_uint1 x346; - fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); uint32_t x347; fiat_p256_uint1 x348; - fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); uint32_t x349; fiat_p256_uint1 x350; - fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); uint32_t x351; fiat_p256_uint1 x352; - fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); uint32_t x353; fiat_p256_uint1 x354; - fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); uint32_t x355; fiat_p256_uint1 x356; - fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); uint32_t x357; fiat_p256_uint1 x358; - fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); uint32_t x359; fiat_p256_uint1 x360; - fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); uint32_t x361; fiat_p256_uint1 x362; - fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); uint32_t x363; uint32_t x364; - fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); uint32_t x365; uint32_t x366; - fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); uint32_t x367; uint32_t x368; - fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); uint32_t x369; uint32_t x370; - fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); uint32_t x371; fiat_p256_uint1 x372; - fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); uint32_t x373; fiat_p256_uint1 x374; - fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); - uint32_t x375 = (x374 + x366); + uint32_t x375; uint32_t x376; fiat_p256_uint1 x377; - fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); uint32_t x378; fiat_p256_uint1 x379; - fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); uint32_t x380; fiat_p256_uint1 x381; - fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); uint32_t x382; fiat_p256_uint1 x383; - fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); uint32_t x384; fiat_p256_uint1 x385; - fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); uint32_t x386; fiat_p256_uint1 x387; - fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); uint32_t x388; fiat_p256_uint1 x389; - fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); uint32_t x390; fiat_p256_uint1 x391; - fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); uint32_t x392; fiat_p256_uint1 x393; - fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); - uint32_t x394 = ((uint32_t)x393 + x362); + uint32_t x394; uint32_t x395; uint32_t x396; - fiat_p256_mulx_u32(&x395, &x396, x5, (arg2[7])); uint32_t x397; uint32_t x398; - fiat_p256_mulx_u32(&x397, &x398, x5, (arg2[6])); uint32_t x399; uint32_t x400; - fiat_p256_mulx_u32(&x399, &x400, x5, (arg2[5])); uint32_t x401; uint32_t x402; - fiat_p256_mulx_u32(&x401, &x402, x5, (arg2[4])); uint32_t x403; uint32_t x404; - fiat_p256_mulx_u32(&x403, &x404, x5, (arg2[3])); uint32_t x405; uint32_t x406; - fiat_p256_mulx_u32(&x405, &x406, x5, (arg2[2])); uint32_t x407; uint32_t x408; - fiat_p256_mulx_u32(&x407, &x408, x5, (arg2[1])); uint32_t x409; uint32_t x410; - fiat_p256_mulx_u32(&x409, &x410, x5, (arg2[0])); uint32_t x411; fiat_p256_uint1 x412; - fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); uint32_t x413; fiat_p256_uint1 x414; - fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); uint32_t x415; fiat_p256_uint1 x416; - fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); uint32_t x417; fiat_p256_uint1 x418; - fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); uint32_t x419; fiat_p256_uint1 x420; - fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); uint32_t x421; fiat_p256_uint1 x422; - fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); uint32_t x423; fiat_p256_uint1 x424; - fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); - uint32_t x425 = (x424 + x396); + uint32_t x425; uint32_t x426; fiat_p256_uint1 x427; - fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); uint32_t x428; fiat_p256_uint1 x429; - fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); uint32_t x430; fiat_p256_uint1 x431; - fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); uint32_t x432; fiat_p256_uint1 x433; - fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); uint32_t x434; fiat_p256_uint1 x435; - fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); uint32_t x436; fiat_p256_uint1 x437; - fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); uint32_t x438; fiat_p256_uint1 x439; - fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); uint32_t x440; fiat_p256_uint1 x441; - fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); uint32_t x442; fiat_p256_uint1 x443; - fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); uint32_t x444; uint32_t x445; - fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); uint32_t x446; uint32_t x447; - fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); uint32_t x448; uint32_t x449; - fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); uint32_t x450; uint32_t x451; - fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); uint32_t x452; fiat_p256_uint1 x453; - fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); uint32_t x454; fiat_p256_uint1 x455; - fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); - uint32_t x456 = (x455 + x447); + uint32_t x456; uint32_t x457; fiat_p256_uint1 x458; - fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); uint32_t x459; fiat_p256_uint1 x460; - fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); uint32_t x461; fiat_p256_uint1 x462; - fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); uint32_t x463; fiat_p256_uint1 x464; - fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); uint32_t x465; fiat_p256_uint1 x466; - fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); uint32_t x467; fiat_p256_uint1 x468; - fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); uint32_t x469; fiat_p256_uint1 x470; - fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); uint32_t x471; fiat_p256_uint1 x472; - fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); uint32_t x473; fiat_p256_uint1 x474; - fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); - uint32_t x475 = ((uint32_t)x474 + x443); + uint32_t x475; uint32_t x476; uint32_t x477; - fiat_p256_mulx_u32(&x476, &x477, x6, (arg2[7])); uint32_t x478; uint32_t x479; - fiat_p256_mulx_u32(&x478, &x479, x6, (arg2[6])); uint32_t x480; uint32_t x481; - fiat_p256_mulx_u32(&x480, &x481, x6, (arg2[5])); uint32_t x482; uint32_t x483; - fiat_p256_mulx_u32(&x482, &x483, x6, (arg2[4])); uint32_t x484; uint32_t x485; - fiat_p256_mulx_u32(&x484, &x485, x6, (arg2[3])); uint32_t x486; uint32_t x487; - fiat_p256_mulx_u32(&x486, &x487, x6, (arg2[2])); uint32_t x488; uint32_t x489; - fiat_p256_mulx_u32(&x488, &x489, x6, (arg2[1])); uint32_t x490; uint32_t x491; - fiat_p256_mulx_u32(&x490, &x491, x6, (arg2[0])); uint32_t x492; fiat_p256_uint1 x493; - fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); uint32_t x494; fiat_p256_uint1 x495; - fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); uint32_t x496; fiat_p256_uint1 x497; - fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); uint32_t x498; fiat_p256_uint1 x499; - fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); uint32_t x500; fiat_p256_uint1 x501; - fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); uint32_t x502; fiat_p256_uint1 x503; - fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); uint32_t x504; fiat_p256_uint1 x505; - fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); - uint32_t x506 = (x505 + x477); + uint32_t x506; uint32_t x507; fiat_p256_uint1 x508; - fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); uint32_t x509; fiat_p256_uint1 x510; - fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); uint32_t x511; fiat_p256_uint1 x512; - fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); uint32_t x513; fiat_p256_uint1 x514; - fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); uint32_t x515; fiat_p256_uint1 x516; - fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); uint32_t x517; fiat_p256_uint1 x518; - fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); uint32_t x519; fiat_p256_uint1 x520; - fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); uint32_t x521; fiat_p256_uint1 x522; - fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); uint32_t x523; fiat_p256_uint1 x524; - fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); uint32_t x525; uint32_t x526; - fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); uint32_t x527; uint32_t x528; - fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); uint32_t x529; uint32_t x530; - fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); uint32_t x531; uint32_t x532; - fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); uint32_t x533; fiat_p256_uint1 x534; - fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); uint32_t x535; fiat_p256_uint1 x536; - fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); - uint32_t x537 = (x536 + x528); + uint32_t x537; uint32_t x538; fiat_p256_uint1 x539; - fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); uint32_t x540; fiat_p256_uint1 x541; - fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); uint32_t x542; fiat_p256_uint1 x543; - fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); uint32_t x544; fiat_p256_uint1 x545; - fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); uint32_t x546; fiat_p256_uint1 x547; - fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); uint32_t x548; fiat_p256_uint1 x549; - fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); uint32_t x550; fiat_p256_uint1 x551; - fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); uint32_t x552; fiat_p256_uint1 x553; - fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); uint32_t x554; fiat_p256_uint1 x555; - fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); - uint32_t x556 = ((uint32_t)x555 + x524); + uint32_t x556; uint32_t x557; uint32_t x558; - fiat_p256_mulx_u32(&x557, &x558, x7, (arg2[7])); uint32_t x559; uint32_t x560; - fiat_p256_mulx_u32(&x559, &x560, x7, (arg2[6])); uint32_t x561; uint32_t x562; - fiat_p256_mulx_u32(&x561, &x562, x7, (arg2[5])); uint32_t x563; uint32_t x564; - fiat_p256_mulx_u32(&x563, &x564, x7, (arg2[4])); uint32_t x565; uint32_t x566; - fiat_p256_mulx_u32(&x565, &x566, x7, (arg2[3])); uint32_t x567; uint32_t x568; - fiat_p256_mulx_u32(&x567, &x568, x7, (arg2[2])); uint32_t x569; uint32_t x570; - fiat_p256_mulx_u32(&x569, &x570, x7, (arg2[1])); uint32_t x571; uint32_t x572; - fiat_p256_mulx_u32(&x571, &x572, x7, (arg2[0])); uint32_t x573; fiat_p256_uint1 x574; - fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); uint32_t x575; fiat_p256_uint1 x576; - fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); uint32_t x577; fiat_p256_uint1 x578; - fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); uint32_t x579; fiat_p256_uint1 x580; - fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); uint32_t x581; fiat_p256_uint1 x582; - fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); uint32_t x583; fiat_p256_uint1 x584; - fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); uint32_t x585; fiat_p256_uint1 x586; - fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); - uint32_t x587 = (x586 + x558); + uint32_t x587; uint32_t x588; fiat_p256_uint1 x589; - fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); uint32_t x590; fiat_p256_uint1 x591; - fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); uint32_t x592; fiat_p256_uint1 x593; - fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); uint32_t x594; fiat_p256_uint1 x595; - fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); uint32_t x596; fiat_p256_uint1 x597; - fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); uint32_t x598; fiat_p256_uint1 x599; - fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); uint32_t x600; fiat_p256_uint1 x601; - fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); uint32_t x602; fiat_p256_uint1 x603; - fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); uint32_t x604; fiat_p256_uint1 x605; - fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); uint32_t x606; uint32_t x607; - fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); uint32_t x608; uint32_t x609; - fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); uint32_t x610; uint32_t x611; - fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); uint32_t x612; uint32_t x613; - fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); uint32_t x614; fiat_p256_uint1 x615; - fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); uint32_t x616; fiat_p256_uint1 x617; - fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); - uint32_t x618 = (x617 + x609); + uint32_t x618; uint32_t x619; fiat_p256_uint1 x620; - fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); uint32_t x621; fiat_p256_uint1 x622; - fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); uint32_t x623; fiat_p256_uint1 x624; - fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); uint32_t x625; fiat_p256_uint1 x626; - fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); uint32_t x627; fiat_p256_uint1 x628; - fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); uint32_t x629; fiat_p256_uint1 x630; - fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); uint32_t x631; fiat_p256_uint1 x632; - fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); uint32_t x633; fiat_p256_uint1 x634; - fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); uint32_t x635; fiat_p256_uint1 x636; - fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); - uint32_t x637 = ((uint32_t)x636 + x605); + uint32_t x637; uint32_t x638; fiat_p256_uint1 x639; - fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); uint32_t x640; fiat_p256_uint1 x641; - fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); uint32_t x642; fiat_p256_uint1 x643; - fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); uint32_t x644; fiat_p256_uint1 x645; - fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); uint32_t x646; fiat_p256_uint1 x647; - fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); uint32_t x648; fiat_p256_uint1 x649; - fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); uint32_t x650; fiat_p256_uint1 x651; - fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); uint32_t x652; fiat_p256_uint1 x653; - fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); uint32_t x654; fiat_p256_uint1 x655; - fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); uint32_t x656; - fiat_p256_cmovznz_u32(&x656, x655, x638, x621); uint32_t x657; - fiat_p256_cmovznz_u32(&x657, x655, x640, x623); uint32_t x658; - fiat_p256_cmovznz_u32(&x658, x655, x642, x625); uint32_t x659; - fiat_p256_cmovznz_u32(&x659, x655, x644, x627); uint32_t x660; - fiat_p256_cmovznz_u32(&x660, x655, x646, x629); uint32_t x661; - fiat_p256_cmovznz_u32(&x661, x655, x648, x631); uint32_t x662; - fiat_p256_cmovznz_u32(&x662, x655, x650, x633); uint32_t x663; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, (arg2[7])); + fiat_p256_mulx_u32(&x11, &x12, x8, (arg2[6])); + fiat_p256_mulx_u32(&x13, &x14, x8, (arg2[5])); + fiat_p256_mulx_u32(&x15, &x16, x8, (arg2[4])); + fiat_p256_mulx_u32(&x17, &x18, x8, (arg2[3])); + fiat_p256_mulx_u32(&x19, &x20, x8, (arg2[2])); + fiat_p256_mulx_u32(&x21, &x22, x8, (arg2[1])); + fiat_p256_mulx_u32(&x23, &x24, x8, (arg2[0])); + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); + fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); + fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); + fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); + x39 = (x38 + x10); + fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); + x52 = (x51 + x43); + fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); + fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); + fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); + fiat_p256_mulx_u32(&x71, &x72, x1, (arg2[7])); + fiat_p256_mulx_u32(&x73, &x74, x1, (arg2[6])); + fiat_p256_mulx_u32(&x75, &x76, x1, (arg2[5])); + fiat_p256_mulx_u32(&x77, &x78, x1, (arg2[4])); + fiat_p256_mulx_u32(&x79, &x80, x1, (arg2[3])); + fiat_p256_mulx_u32(&x81, &x82, x1, (arg2[2])); + fiat_p256_mulx_u32(&x83, &x84, x1, (arg2[1])); + fiat_p256_mulx_u32(&x85, &x86, x1, (arg2[0])); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); + x101 = (x100 + x72); + fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); + fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); + fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); + fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); + fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); + fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); + x132 = (x131 + x123); + fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); + fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); + fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); + fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); + fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); + fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); + fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); + fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); + x151 = ((uint32_t)x150 + x119); + fiat_p256_mulx_u32(&x152, &x153, x2, (arg2[7])); + fiat_p256_mulx_u32(&x154, &x155, x2, (arg2[6])); + fiat_p256_mulx_u32(&x156, &x157, x2, (arg2[5])); + fiat_p256_mulx_u32(&x158, &x159, x2, (arg2[4])); + fiat_p256_mulx_u32(&x160, &x161, x2, (arg2[3])); + fiat_p256_mulx_u32(&x162, &x163, x2, (arg2[2])); + fiat_p256_mulx_u32(&x164, &x165, x2, (arg2[1])); + fiat_p256_mulx_u32(&x166, &x167, x2, (arg2[0])); + fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); + x182 = (x181 + x153); + fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); + fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); + fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); + fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); + x213 = (x212 + x204); + fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); + fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); + fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); + x232 = ((uint32_t)x231 + x200); + fiat_p256_mulx_u32(&x233, &x234, x3, (arg2[7])); + fiat_p256_mulx_u32(&x235, &x236, x3, (arg2[6])); + fiat_p256_mulx_u32(&x237, &x238, x3, (arg2[5])); + fiat_p256_mulx_u32(&x239, &x240, x3, (arg2[4])); + fiat_p256_mulx_u32(&x241, &x242, x3, (arg2[3])); + fiat_p256_mulx_u32(&x243, &x244, x3, (arg2[2])); + fiat_p256_mulx_u32(&x245, &x246, x3, (arg2[1])); + fiat_p256_mulx_u32(&x247, &x248, x3, (arg2[0])); + fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); + fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); + fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); + x263 = (x262 + x234); + fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); + fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); + fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); + fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); + fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); + x294 = (x293 + x285); + fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); + fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); + x313 = ((uint32_t)x312 + x281); + fiat_p256_mulx_u32(&x314, &x315, x4, (arg2[7])); + fiat_p256_mulx_u32(&x316, &x317, x4, (arg2[6])); + fiat_p256_mulx_u32(&x318, &x319, x4, (arg2[5])); + fiat_p256_mulx_u32(&x320, &x321, x4, (arg2[4])); + fiat_p256_mulx_u32(&x322, &x323, x4, (arg2[3])); + fiat_p256_mulx_u32(&x324, &x325, x4, (arg2[2])); + fiat_p256_mulx_u32(&x326, &x327, x4, (arg2[1])); + fiat_p256_mulx_u32(&x328, &x329, x4, (arg2[0])); + fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); + fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); + fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); + fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); + fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); + fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); + fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); + x344 = (x343 + x315); + fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); + fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); + fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); + fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); + fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); + fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); + fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); + fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); + x375 = (x374 + x366); + fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); + fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); + fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); + fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); + fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); + fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); + fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); + fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); + fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); + x394 = ((uint32_t)x393 + x362); + fiat_p256_mulx_u32(&x395, &x396, x5, (arg2[7])); + fiat_p256_mulx_u32(&x397, &x398, x5, (arg2[6])); + fiat_p256_mulx_u32(&x399, &x400, x5, (arg2[5])); + fiat_p256_mulx_u32(&x401, &x402, x5, (arg2[4])); + fiat_p256_mulx_u32(&x403, &x404, x5, (arg2[3])); + fiat_p256_mulx_u32(&x405, &x406, x5, (arg2[2])); + fiat_p256_mulx_u32(&x407, &x408, x5, (arg2[1])); + fiat_p256_mulx_u32(&x409, &x410, x5, (arg2[0])); + fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); + fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); + fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); + fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); + fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); + fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); + fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); + x425 = (x424 + x396); + fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); + fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); + fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); + fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); + fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); + fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); + fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); + fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); + fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); + fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); + fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); + x456 = (x455 + x447); + fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); + fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); + fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); + fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); + x475 = ((uint32_t)x474 + x443); + fiat_p256_mulx_u32(&x476, &x477, x6, (arg2[7])); + fiat_p256_mulx_u32(&x478, &x479, x6, (arg2[6])); + fiat_p256_mulx_u32(&x480, &x481, x6, (arg2[5])); + fiat_p256_mulx_u32(&x482, &x483, x6, (arg2[4])); + fiat_p256_mulx_u32(&x484, &x485, x6, (arg2[3])); + fiat_p256_mulx_u32(&x486, &x487, x6, (arg2[2])); + fiat_p256_mulx_u32(&x488, &x489, x6, (arg2[1])); + fiat_p256_mulx_u32(&x490, &x491, x6, (arg2[0])); + fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); + fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); + fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); + fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); + fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); + fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); + fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); + x506 = (x505 + x477); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); + fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); + fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); + x537 = (x536 + x528); + fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); + fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); + fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); + fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); + fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); + fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); + fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); + fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); + fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); + x556 = ((uint32_t)x555 + x524); + fiat_p256_mulx_u32(&x557, &x558, x7, (arg2[7])); + fiat_p256_mulx_u32(&x559, &x560, x7, (arg2[6])); + fiat_p256_mulx_u32(&x561, &x562, x7, (arg2[5])); + fiat_p256_mulx_u32(&x563, &x564, x7, (arg2[4])); + fiat_p256_mulx_u32(&x565, &x566, x7, (arg2[3])); + fiat_p256_mulx_u32(&x567, &x568, x7, (arg2[2])); + fiat_p256_mulx_u32(&x569, &x570, x7, (arg2[1])); + fiat_p256_mulx_u32(&x571, &x572, x7, (arg2[0])); + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); + fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); + fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); + fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); + fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); + fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); + fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); + x587 = (x586 + x558); + fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); + fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); + fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); + fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); + fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); + fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); + fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); + fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); + fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); + fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); + fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); + x618 = (x617 + x609); + fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); + fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); + fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); + fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); + fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); + fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); + fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); + fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); + fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); + x637 = ((uint32_t)x636 + x605); + fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); + fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); + fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); + fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); + fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); + fiat_p256_cmovznz_u32(&x656, x655, x638, x621); + fiat_p256_cmovznz_u32(&x657, x655, x640, x623); + fiat_p256_cmovznz_u32(&x658, x655, x642, x625); + fiat_p256_cmovznz_u32(&x659, x655, x644, x627); + fiat_p256_cmovznz_u32(&x660, x655, x646, x629); + fiat_p256_cmovznz_u32(&x661, x655, x648, x631); + fiat_p256_cmovznz_u32(&x662, x655, x650, x633); fiat_p256_cmovznz_u32(&x663, x655, x652, x635); out1[0] = x656; out1[1] = x657; @@ -1121,1000 +1186,1028 @@ static void fiat_p256_mul(uint32_t out1[8], const uint32_t arg1[8], const uint32 /* * The function fiat_p256_square squares a field element in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_square(uint32_t out1[8], const uint32_t arg1[8]) { - uint32_t x1 = (arg1[1]); - uint32_t x2 = (arg1[2]); - uint32_t x3 = (arg1[3]); - uint32_t x4 = (arg1[4]); - uint32_t x5 = (arg1[5]); - uint32_t x6 = (arg1[6]); - uint32_t x7 = (arg1[7]); - uint32_t x8 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; uint32_t x9; uint32_t x10; - fiat_p256_mulx_u32(&x9, &x10, x8, (arg1[7])); uint32_t x11; uint32_t x12; - fiat_p256_mulx_u32(&x11, &x12, x8, (arg1[6])); uint32_t x13; uint32_t x14; - fiat_p256_mulx_u32(&x13, &x14, x8, (arg1[5])); uint32_t x15; uint32_t x16; - fiat_p256_mulx_u32(&x15, &x16, x8, (arg1[4])); uint32_t x17; uint32_t x18; - fiat_p256_mulx_u32(&x17, &x18, x8, (arg1[3])); uint32_t x19; uint32_t x20; - fiat_p256_mulx_u32(&x19, &x20, x8, (arg1[2])); uint32_t x21; uint32_t x22; - fiat_p256_mulx_u32(&x21, &x22, x8, (arg1[1])); uint32_t x23; uint32_t x24; - fiat_p256_mulx_u32(&x23, &x24, x8, (arg1[0])); uint32_t x25; fiat_p256_uint1 x26; - fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); uint32_t x27; fiat_p256_uint1 x28; - fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); uint32_t x29; fiat_p256_uint1 x30; - fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); uint32_t x31; fiat_p256_uint1 x32; - fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); uint32_t x33; fiat_p256_uint1 x34; - fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); uint32_t x35; fiat_p256_uint1 x36; - fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); uint32_t x37; fiat_p256_uint1 x38; - fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); - uint32_t x39 = (x38 + x10); + uint32_t x39; uint32_t x40; uint32_t x41; - fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); uint32_t x42; uint32_t x43; - fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); uint32_t x44; uint32_t x45; - fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); uint32_t x46; uint32_t x47; - fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); uint32_t x48; fiat_p256_uint1 x49; - fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); uint32_t x50; fiat_p256_uint1 x51; - fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); - uint32_t x52 = (x51 + x43); + uint32_t x52; uint32_t x53; fiat_p256_uint1 x54; - fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); uint32_t x55; fiat_p256_uint1 x56; - fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); uint32_t x57; fiat_p256_uint1 x58; - fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); uint32_t x59; fiat_p256_uint1 x60; - fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); uint32_t x61; fiat_p256_uint1 x62; - fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); uint32_t x63; fiat_p256_uint1 x64; - fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); uint32_t x65; fiat_p256_uint1 x66; - fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); uint32_t x67; fiat_p256_uint1 x68; - fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); uint32_t x69; fiat_p256_uint1 x70; - fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); uint32_t x71; uint32_t x72; - fiat_p256_mulx_u32(&x71, &x72, x1, (arg1[7])); uint32_t x73; uint32_t x74; - fiat_p256_mulx_u32(&x73, &x74, x1, (arg1[6])); uint32_t x75; uint32_t x76; - fiat_p256_mulx_u32(&x75, &x76, x1, (arg1[5])); uint32_t x77; uint32_t x78; - fiat_p256_mulx_u32(&x77, &x78, x1, (arg1[4])); uint32_t x79; uint32_t x80; - fiat_p256_mulx_u32(&x79, &x80, x1, (arg1[3])); uint32_t x81; uint32_t x82; - fiat_p256_mulx_u32(&x81, &x82, x1, (arg1[2])); uint32_t x83; uint32_t x84; - fiat_p256_mulx_u32(&x83, &x84, x1, (arg1[1])); uint32_t x85; uint32_t x86; - fiat_p256_mulx_u32(&x85, &x86, x1, (arg1[0])); uint32_t x87; fiat_p256_uint1 x88; - fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); uint32_t x89; fiat_p256_uint1 x90; - fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); uint32_t x91; fiat_p256_uint1 x92; - fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); uint32_t x93; fiat_p256_uint1 x94; - fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); uint32_t x95; fiat_p256_uint1 x96; - fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); uint32_t x97; fiat_p256_uint1 x98; - fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); uint32_t x99; fiat_p256_uint1 x100; - fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); - uint32_t x101 = (x100 + x72); + uint32_t x101; uint32_t x102; fiat_p256_uint1 x103; - fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); uint32_t x104; fiat_p256_uint1 x105; - fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); uint32_t x106; fiat_p256_uint1 x107; - fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); uint32_t x108; fiat_p256_uint1 x109; - fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); uint32_t x110; fiat_p256_uint1 x111; - fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); uint32_t x112; fiat_p256_uint1 x113; - fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); uint32_t x114; fiat_p256_uint1 x115; - fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); uint32_t x116; fiat_p256_uint1 x117; - fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); uint32_t x118; fiat_p256_uint1 x119; - fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); uint32_t x120; uint32_t x121; - fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); uint32_t x122; uint32_t x123; - fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); uint32_t x124; uint32_t x125; - fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); uint32_t x126; uint32_t x127; - fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); uint32_t x128; fiat_p256_uint1 x129; - fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); uint32_t x130; fiat_p256_uint1 x131; - fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); - uint32_t x132 = (x131 + x123); + uint32_t x132; uint32_t x133; fiat_p256_uint1 x134; - fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); uint32_t x135; fiat_p256_uint1 x136; - fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); uint32_t x137; fiat_p256_uint1 x138; - fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); uint32_t x139; fiat_p256_uint1 x140; - fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); uint32_t x141; fiat_p256_uint1 x142; - fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); uint32_t x143; fiat_p256_uint1 x144; - fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); uint32_t x145; fiat_p256_uint1 x146; - fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); uint32_t x147; fiat_p256_uint1 x148; - fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); uint32_t x149; fiat_p256_uint1 x150; - fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); - uint32_t x151 = ((uint32_t)x150 + x119); + uint32_t x151; uint32_t x152; uint32_t x153; - fiat_p256_mulx_u32(&x152, &x153, x2, (arg1[7])); uint32_t x154; uint32_t x155; - fiat_p256_mulx_u32(&x154, &x155, x2, (arg1[6])); uint32_t x156; uint32_t x157; - fiat_p256_mulx_u32(&x156, &x157, x2, (arg1[5])); uint32_t x158; uint32_t x159; - fiat_p256_mulx_u32(&x158, &x159, x2, (arg1[4])); uint32_t x160; uint32_t x161; - fiat_p256_mulx_u32(&x160, &x161, x2, (arg1[3])); uint32_t x162; uint32_t x163; - fiat_p256_mulx_u32(&x162, &x163, x2, (arg1[2])); uint32_t x164; uint32_t x165; - fiat_p256_mulx_u32(&x164, &x165, x2, (arg1[1])); uint32_t x166; uint32_t x167; - fiat_p256_mulx_u32(&x166, &x167, x2, (arg1[0])); uint32_t x168; fiat_p256_uint1 x169; - fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); uint32_t x170; fiat_p256_uint1 x171; - fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); uint32_t x172; fiat_p256_uint1 x173; - fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); uint32_t x174; fiat_p256_uint1 x175; - fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); uint32_t x176; fiat_p256_uint1 x177; - fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); uint32_t x178; fiat_p256_uint1 x179; - fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); uint32_t x180; fiat_p256_uint1 x181; - fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); - uint32_t x182 = (x181 + x153); + uint32_t x182; uint32_t x183; fiat_p256_uint1 x184; - fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); uint32_t x185; fiat_p256_uint1 x186; - fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); uint32_t x187; fiat_p256_uint1 x188; - fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); uint32_t x189; fiat_p256_uint1 x190; - fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); uint32_t x191; fiat_p256_uint1 x192; - fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); uint32_t x193; fiat_p256_uint1 x194; - fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); uint32_t x195; fiat_p256_uint1 x196; - fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); uint32_t x197; fiat_p256_uint1 x198; - fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); uint32_t x199; fiat_p256_uint1 x200; - fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); uint32_t x201; uint32_t x202; - fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); uint32_t x203; uint32_t x204; - fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); uint32_t x205; uint32_t x206; - fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); uint32_t x207; uint32_t x208; - fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); uint32_t x209; fiat_p256_uint1 x210; - fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); uint32_t x211; fiat_p256_uint1 x212; - fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); - uint32_t x213 = (x212 + x204); + uint32_t x213; uint32_t x214; fiat_p256_uint1 x215; - fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); uint32_t x216; fiat_p256_uint1 x217; - fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); uint32_t x218; fiat_p256_uint1 x219; - fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); uint32_t x220; fiat_p256_uint1 x221; - fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); uint32_t x222; fiat_p256_uint1 x223; - fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); uint32_t x224; fiat_p256_uint1 x225; - fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); uint32_t x226; fiat_p256_uint1 x227; - fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); uint32_t x228; fiat_p256_uint1 x229; - fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); uint32_t x230; fiat_p256_uint1 x231; - fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); - uint32_t x232 = ((uint32_t)x231 + x200); + uint32_t x232; uint32_t x233; uint32_t x234; - fiat_p256_mulx_u32(&x233, &x234, x3, (arg1[7])); uint32_t x235; uint32_t x236; - fiat_p256_mulx_u32(&x235, &x236, x3, (arg1[6])); uint32_t x237; uint32_t x238; - fiat_p256_mulx_u32(&x237, &x238, x3, (arg1[5])); uint32_t x239; uint32_t x240; - fiat_p256_mulx_u32(&x239, &x240, x3, (arg1[4])); uint32_t x241; uint32_t x242; - fiat_p256_mulx_u32(&x241, &x242, x3, (arg1[3])); uint32_t x243; uint32_t x244; - fiat_p256_mulx_u32(&x243, &x244, x3, (arg1[2])); uint32_t x245; uint32_t x246; - fiat_p256_mulx_u32(&x245, &x246, x3, (arg1[1])); uint32_t x247; uint32_t x248; - fiat_p256_mulx_u32(&x247, &x248, x3, (arg1[0])); uint32_t x249; fiat_p256_uint1 x250; - fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); uint32_t x251; fiat_p256_uint1 x252; - fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); uint32_t x253; fiat_p256_uint1 x254; - fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); uint32_t x255; fiat_p256_uint1 x256; - fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); uint32_t x257; fiat_p256_uint1 x258; - fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); uint32_t x259; fiat_p256_uint1 x260; - fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); uint32_t x261; fiat_p256_uint1 x262; - fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); - uint32_t x263 = (x262 + x234); + uint32_t x263; uint32_t x264; fiat_p256_uint1 x265; - fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); uint32_t x266; fiat_p256_uint1 x267; - fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); uint32_t x268; fiat_p256_uint1 x269; - fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); uint32_t x270; fiat_p256_uint1 x271; - fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); uint32_t x272; fiat_p256_uint1 x273; - fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); uint32_t x274; fiat_p256_uint1 x275; - fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); uint32_t x276; fiat_p256_uint1 x277; - fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); uint32_t x278; fiat_p256_uint1 x279; - fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); uint32_t x280; fiat_p256_uint1 x281; - fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); uint32_t x282; uint32_t x283; - fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); uint32_t x284; uint32_t x285; - fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); uint32_t x286; uint32_t x287; - fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); uint32_t x288; uint32_t x289; - fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); uint32_t x290; fiat_p256_uint1 x291; - fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); uint32_t x292; fiat_p256_uint1 x293; - fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); - uint32_t x294 = (x293 + x285); + uint32_t x294; uint32_t x295; fiat_p256_uint1 x296; - fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); uint32_t x297; fiat_p256_uint1 x298; - fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); uint32_t x299; fiat_p256_uint1 x300; - fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); uint32_t x301; fiat_p256_uint1 x302; - fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); uint32_t x303; fiat_p256_uint1 x304; - fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); uint32_t x305; fiat_p256_uint1 x306; - fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); uint32_t x307; fiat_p256_uint1 x308; - fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); uint32_t x309; fiat_p256_uint1 x310; - fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); uint32_t x311; fiat_p256_uint1 x312; - fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); - uint32_t x313 = ((uint32_t)x312 + x281); + uint32_t x313; uint32_t x314; uint32_t x315; - fiat_p256_mulx_u32(&x314, &x315, x4, (arg1[7])); uint32_t x316; uint32_t x317; - fiat_p256_mulx_u32(&x316, &x317, x4, (arg1[6])); uint32_t x318; uint32_t x319; - fiat_p256_mulx_u32(&x318, &x319, x4, (arg1[5])); uint32_t x320; uint32_t x321; - fiat_p256_mulx_u32(&x320, &x321, x4, (arg1[4])); uint32_t x322; uint32_t x323; - fiat_p256_mulx_u32(&x322, &x323, x4, (arg1[3])); uint32_t x324; uint32_t x325; - fiat_p256_mulx_u32(&x324, &x325, x4, (arg1[2])); uint32_t x326; uint32_t x327; - fiat_p256_mulx_u32(&x326, &x327, x4, (arg1[1])); uint32_t x328; uint32_t x329; - fiat_p256_mulx_u32(&x328, &x329, x4, (arg1[0])); uint32_t x330; fiat_p256_uint1 x331; - fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); uint32_t x332; fiat_p256_uint1 x333; - fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); uint32_t x334; fiat_p256_uint1 x335; - fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); uint32_t x336; fiat_p256_uint1 x337; - fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); uint32_t x338; fiat_p256_uint1 x339; - fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); uint32_t x340; fiat_p256_uint1 x341; - fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); uint32_t x342; fiat_p256_uint1 x343; - fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); - uint32_t x344 = (x343 + x315); + uint32_t x344; uint32_t x345; fiat_p256_uint1 x346; - fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); uint32_t x347; fiat_p256_uint1 x348; - fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); uint32_t x349; fiat_p256_uint1 x350; - fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); uint32_t x351; fiat_p256_uint1 x352; - fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); uint32_t x353; fiat_p256_uint1 x354; - fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); uint32_t x355; fiat_p256_uint1 x356; - fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); uint32_t x357; fiat_p256_uint1 x358; - fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); uint32_t x359; fiat_p256_uint1 x360; - fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); uint32_t x361; fiat_p256_uint1 x362; - fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); uint32_t x363; uint32_t x364; - fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); uint32_t x365; uint32_t x366; - fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); uint32_t x367; uint32_t x368; - fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); uint32_t x369; uint32_t x370; - fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); uint32_t x371; fiat_p256_uint1 x372; - fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); uint32_t x373; fiat_p256_uint1 x374; - fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); - uint32_t x375 = (x374 + x366); + uint32_t x375; uint32_t x376; fiat_p256_uint1 x377; - fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); uint32_t x378; fiat_p256_uint1 x379; - fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); uint32_t x380; fiat_p256_uint1 x381; - fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); uint32_t x382; fiat_p256_uint1 x383; - fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); uint32_t x384; fiat_p256_uint1 x385; - fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); uint32_t x386; fiat_p256_uint1 x387; - fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); uint32_t x388; fiat_p256_uint1 x389; - fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); uint32_t x390; fiat_p256_uint1 x391; - fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); uint32_t x392; fiat_p256_uint1 x393; - fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); - uint32_t x394 = ((uint32_t)x393 + x362); + uint32_t x394; uint32_t x395; uint32_t x396; - fiat_p256_mulx_u32(&x395, &x396, x5, (arg1[7])); uint32_t x397; uint32_t x398; - fiat_p256_mulx_u32(&x397, &x398, x5, (arg1[6])); uint32_t x399; uint32_t x400; - fiat_p256_mulx_u32(&x399, &x400, x5, (arg1[5])); uint32_t x401; uint32_t x402; - fiat_p256_mulx_u32(&x401, &x402, x5, (arg1[4])); uint32_t x403; uint32_t x404; - fiat_p256_mulx_u32(&x403, &x404, x5, (arg1[3])); uint32_t x405; uint32_t x406; - fiat_p256_mulx_u32(&x405, &x406, x5, (arg1[2])); uint32_t x407; uint32_t x408; - fiat_p256_mulx_u32(&x407, &x408, x5, (arg1[1])); uint32_t x409; uint32_t x410; - fiat_p256_mulx_u32(&x409, &x410, x5, (arg1[0])); uint32_t x411; fiat_p256_uint1 x412; - fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); uint32_t x413; fiat_p256_uint1 x414; - fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); uint32_t x415; fiat_p256_uint1 x416; - fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); uint32_t x417; fiat_p256_uint1 x418; - fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); uint32_t x419; fiat_p256_uint1 x420; - fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); uint32_t x421; fiat_p256_uint1 x422; - fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); uint32_t x423; fiat_p256_uint1 x424; - fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); - uint32_t x425 = (x424 + x396); + uint32_t x425; uint32_t x426; fiat_p256_uint1 x427; - fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); uint32_t x428; fiat_p256_uint1 x429; - fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); uint32_t x430; fiat_p256_uint1 x431; - fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); uint32_t x432; fiat_p256_uint1 x433; - fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); uint32_t x434; fiat_p256_uint1 x435; - fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); uint32_t x436; fiat_p256_uint1 x437; - fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); uint32_t x438; fiat_p256_uint1 x439; - fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); uint32_t x440; fiat_p256_uint1 x441; - fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); uint32_t x442; fiat_p256_uint1 x443; - fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); uint32_t x444; uint32_t x445; - fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); uint32_t x446; uint32_t x447; - fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); uint32_t x448; uint32_t x449; - fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); uint32_t x450; uint32_t x451; - fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); uint32_t x452; fiat_p256_uint1 x453; - fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); uint32_t x454; fiat_p256_uint1 x455; - fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); - uint32_t x456 = (x455 + x447); + uint32_t x456; uint32_t x457; fiat_p256_uint1 x458; - fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); uint32_t x459; fiat_p256_uint1 x460; - fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); uint32_t x461; fiat_p256_uint1 x462; - fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); uint32_t x463; fiat_p256_uint1 x464; - fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); uint32_t x465; fiat_p256_uint1 x466; - fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); uint32_t x467; fiat_p256_uint1 x468; - fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); uint32_t x469; fiat_p256_uint1 x470; - fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); uint32_t x471; fiat_p256_uint1 x472; - fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); uint32_t x473; fiat_p256_uint1 x474; - fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); - uint32_t x475 = ((uint32_t)x474 + x443); + uint32_t x475; uint32_t x476; uint32_t x477; - fiat_p256_mulx_u32(&x476, &x477, x6, (arg1[7])); uint32_t x478; uint32_t x479; - fiat_p256_mulx_u32(&x478, &x479, x6, (arg1[6])); uint32_t x480; uint32_t x481; - fiat_p256_mulx_u32(&x480, &x481, x6, (arg1[5])); uint32_t x482; uint32_t x483; - fiat_p256_mulx_u32(&x482, &x483, x6, (arg1[4])); uint32_t x484; uint32_t x485; - fiat_p256_mulx_u32(&x484, &x485, x6, (arg1[3])); uint32_t x486; uint32_t x487; - fiat_p256_mulx_u32(&x486, &x487, x6, (arg1[2])); uint32_t x488; uint32_t x489; - fiat_p256_mulx_u32(&x488, &x489, x6, (arg1[1])); uint32_t x490; uint32_t x491; - fiat_p256_mulx_u32(&x490, &x491, x6, (arg1[0])); uint32_t x492; fiat_p256_uint1 x493; - fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); uint32_t x494; fiat_p256_uint1 x495; - fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); uint32_t x496; fiat_p256_uint1 x497; - fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); uint32_t x498; fiat_p256_uint1 x499; - fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); uint32_t x500; fiat_p256_uint1 x501; - fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); uint32_t x502; fiat_p256_uint1 x503; - fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); uint32_t x504; fiat_p256_uint1 x505; - fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); - uint32_t x506 = (x505 + x477); + uint32_t x506; uint32_t x507; fiat_p256_uint1 x508; - fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); uint32_t x509; fiat_p256_uint1 x510; - fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); uint32_t x511; fiat_p256_uint1 x512; - fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); uint32_t x513; fiat_p256_uint1 x514; - fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); uint32_t x515; fiat_p256_uint1 x516; - fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); uint32_t x517; fiat_p256_uint1 x518; - fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); uint32_t x519; fiat_p256_uint1 x520; - fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); uint32_t x521; fiat_p256_uint1 x522; - fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); uint32_t x523; fiat_p256_uint1 x524; - fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); uint32_t x525; uint32_t x526; - fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); uint32_t x527; uint32_t x528; - fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); uint32_t x529; uint32_t x530; - fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); uint32_t x531; uint32_t x532; - fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); uint32_t x533; fiat_p256_uint1 x534; - fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); uint32_t x535; fiat_p256_uint1 x536; - fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); - uint32_t x537 = (x536 + x528); + uint32_t x537; uint32_t x538; fiat_p256_uint1 x539; - fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); uint32_t x540; fiat_p256_uint1 x541; - fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); uint32_t x542; fiat_p256_uint1 x543; - fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); uint32_t x544; fiat_p256_uint1 x545; - fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); uint32_t x546; fiat_p256_uint1 x547; - fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); uint32_t x548; fiat_p256_uint1 x549; - fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); uint32_t x550; fiat_p256_uint1 x551; - fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); uint32_t x552; fiat_p256_uint1 x553; - fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); uint32_t x554; fiat_p256_uint1 x555; - fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); - uint32_t x556 = ((uint32_t)x555 + x524); + uint32_t x556; uint32_t x557; uint32_t x558; - fiat_p256_mulx_u32(&x557, &x558, x7, (arg1[7])); uint32_t x559; uint32_t x560; - fiat_p256_mulx_u32(&x559, &x560, x7, (arg1[6])); uint32_t x561; uint32_t x562; - fiat_p256_mulx_u32(&x561, &x562, x7, (arg1[5])); uint32_t x563; uint32_t x564; - fiat_p256_mulx_u32(&x563, &x564, x7, (arg1[4])); uint32_t x565; uint32_t x566; - fiat_p256_mulx_u32(&x565, &x566, x7, (arg1[3])); uint32_t x567; uint32_t x568; - fiat_p256_mulx_u32(&x567, &x568, x7, (arg1[2])); uint32_t x569; uint32_t x570; - fiat_p256_mulx_u32(&x569, &x570, x7, (arg1[1])); uint32_t x571; uint32_t x572; - fiat_p256_mulx_u32(&x571, &x572, x7, (arg1[0])); uint32_t x573; fiat_p256_uint1 x574; - fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); uint32_t x575; fiat_p256_uint1 x576; - fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); uint32_t x577; fiat_p256_uint1 x578; - fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); uint32_t x579; fiat_p256_uint1 x580; - fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); uint32_t x581; fiat_p256_uint1 x582; - fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); uint32_t x583; fiat_p256_uint1 x584; - fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); uint32_t x585; fiat_p256_uint1 x586; - fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); - uint32_t x587 = (x586 + x558); + uint32_t x587; uint32_t x588; fiat_p256_uint1 x589; - fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); uint32_t x590; fiat_p256_uint1 x591; - fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); uint32_t x592; fiat_p256_uint1 x593; - fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); uint32_t x594; fiat_p256_uint1 x595; - fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); uint32_t x596; fiat_p256_uint1 x597; - fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); uint32_t x598; fiat_p256_uint1 x599; - fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); uint32_t x600; fiat_p256_uint1 x601; - fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); uint32_t x602; fiat_p256_uint1 x603; - fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); uint32_t x604; fiat_p256_uint1 x605; - fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); uint32_t x606; uint32_t x607; - fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); uint32_t x608; uint32_t x609; - fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); uint32_t x610; uint32_t x611; - fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); uint32_t x612; uint32_t x613; - fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); uint32_t x614; fiat_p256_uint1 x615; - fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); uint32_t x616; fiat_p256_uint1 x617; - fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); - uint32_t x618 = (x617 + x609); + uint32_t x618; uint32_t x619; fiat_p256_uint1 x620; - fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); uint32_t x621; fiat_p256_uint1 x622; - fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); uint32_t x623; fiat_p256_uint1 x624; - fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); uint32_t x625; fiat_p256_uint1 x626; - fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); uint32_t x627; fiat_p256_uint1 x628; - fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); uint32_t x629; fiat_p256_uint1 x630; - fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); uint32_t x631; fiat_p256_uint1 x632; - fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); uint32_t x633; fiat_p256_uint1 x634; - fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); uint32_t x635; fiat_p256_uint1 x636; - fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); - uint32_t x637 = ((uint32_t)x636 + x605); + uint32_t x637; uint32_t x638; fiat_p256_uint1 x639; - fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); uint32_t x640; fiat_p256_uint1 x641; - fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); uint32_t x642; fiat_p256_uint1 x643; - fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); uint32_t x644; fiat_p256_uint1 x645; - fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); uint32_t x646; fiat_p256_uint1 x647; - fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); uint32_t x648; fiat_p256_uint1 x649; - fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); uint32_t x650; fiat_p256_uint1 x651; - fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); uint32_t x652; fiat_p256_uint1 x653; - fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); uint32_t x654; fiat_p256_uint1 x655; - fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); uint32_t x656; - fiat_p256_cmovznz_u32(&x656, x655, x638, x621); uint32_t x657; - fiat_p256_cmovznz_u32(&x657, x655, x640, x623); uint32_t x658; - fiat_p256_cmovznz_u32(&x658, x655, x642, x625); uint32_t x659; - fiat_p256_cmovznz_u32(&x659, x655, x644, x627); uint32_t x660; - fiat_p256_cmovznz_u32(&x660, x655, x646, x629); uint32_t x661; - fiat_p256_cmovznz_u32(&x661, x655, x648, x631); uint32_t x662; - fiat_p256_cmovznz_u32(&x662, x655, x650, x633); uint32_t x663; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, (arg1[7])); + fiat_p256_mulx_u32(&x11, &x12, x8, (arg1[6])); + fiat_p256_mulx_u32(&x13, &x14, x8, (arg1[5])); + fiat_p256_mulx_u32(&x15, &x16, x8, (arg1[4])); + fiat_p256_mulx_u32(&x17, &x18, x8, (arg1[3])); + fiat_p256_mulx_u32(&x19, &x20, x8, (arg1[2])); + fiat_p256_mulx_u32(&x21, &x22, x8, (arg1[1])); + fiat_p256_mulx_u32(&x23, &x24, x8, (arg1[0])); + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x22, x19); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x20, x17); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x18, x15); + fiat_p256_addcarryx_u32(&x33, &x34, x32, x16, x13); + fiat_p256_addcarryx_u32(&x35, &x36, x34, x14, x11); + fiat_p256_addcarryx_u32(&x37, &x38, x36, x12, x9); + x39 = (x38 + x10); + fiat_p256_mulx_u32(&x40, &x41, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x42, &x43, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x44, &x45, x23, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x46, &x47, x23, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x47, x44); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x45, x42); + x52 = (x51 + x43); + fiat_p256_addcarryx_u32(&x53, &x54, 0x0, x23, x46); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x25, x48); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x27, x50); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x29, x52); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x31, 0x0); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x33, 0x0); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x35, x23); + fiat_p256_addcarryx_u32(&x67, &x68, x66, x37, x40); + fiat_p256_addcarryx_u32(&x69, &x70, x68, x39, x41); + fiat_p256_mulx_u32(&x71, &x72, x1, (arg1[7])); + fiat_p256_mulx_u32(&x73, &x74, x1, (arg1[6])); + fiat_p256_mulx_u32(&x75, &x76, x1, (arg1[5])); + fiat_p256_mulx_u32(&x77, &x78, x1, (arg1[4])); + fiat_p256_mulx_u32(&x79, &x80, x1, (arg1[3])); + fiat_p256_mulx_u32(&x81, &x82, x1, (arg1[2])); + fiat_p256_mulx_u32(&x83, &x84, x1, (arg1[1])); + fiat_p256_mulx_u32(&x85, &x86, x1, (arg1[0])); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x86, x83); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x84, x81); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x82, x79); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x80, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x78, x75); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x76, x73); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x74, x71); + x101 = (x100 + x72); + fiat_p256_addcarryx_u32(&x102, &x103, 0x0, x55, x85); + fiat_p256_addcarryx_u32(&x104, &x105, x103, x57, x87); + fiat_p256_addcarryx_u32(&x106, &x107, x105, x59, x89); + fiat_p256_addcarryx_u32(&x108, &x109, x107, x61, x91); + fiat_p256_addcarryx_u32(&x110, &x111, x109, x63, x93); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x65, x95); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x67, x97); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x69, x99); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x70, x101); + fiat_p256_mulx_u32(&x120, &x121, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x122, &x123, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x124, &x125, x102, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x126, &x127, x102, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x128, &x129, 0x0, x127, x124); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x125, x122); + x132 = (x131 + x123); + fiat_p256_addcarryx_u32(&x133, &x134, 0x0, x102, x126); + fiat_p256_addcarryx_u32(&x135, &x136, x134, x104, x128); + fiat_p256_addcarryx_u32(&x137, &x138, x136, x106, x130); + fiat_p256_addcarryx_u32(&x139, &x140, x138, x108, x132); + fiat_p256_addcarryx_u32(&x141, &x142, x140, x110, 0x0); + fiat_p256_addcarryx_u32(&x143, &x144, x142, x112, 0x0); + fiat_p256_addcarryx_u32(&x145, &x146, x144, x114, x102); + fiat_p256_addcarryx_u32(&x147, &x148, x146, x116, x120); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x118, x121); + x151 = ((uint32_t)x150 + x119); + fiat_p256_mulx_u32(&x152, &x153, x2, (arg1[7])); + fiat_p256_mulx_u32(&x154, &x155, x2, (arg1[6])); + fiat_p256_mulx_u32(&x156, &x157, x2, (arg1[5])); + fiat_p256_mulx_u32(&x158, &x159, x2, (arg1[4])); + fiat_p256_mulx_u32(&x160, &x161, x2, (arg1[3])); + fiat_p256_mulx_u32(&x162, &x163, x2, (arg1[2])); + fiat_p256_mulx_u32(&x164, &x165, x2, (arg1[1])); + fiat_p256_mulx_u32(&x166, &x167, x2, (arg1[0])); + fiat_p256_addcarryx_u32(&x168, &x169, 0x0, x167, x164); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x165, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x163, x160); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x161, x158); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x159, x156); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x157, x154); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x155, x152); + x182 = (x181 + x153); + fiat_p256_addcarryx_u32(&x183, &x184, 0x0, x135, x166); + fiat_p256_addcarryx_u32(&x185, &x186, x184, x137, x168); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x139, x170); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x141, x172); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x143, x174); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x145, x176); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x147, x178); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x149, x180); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x151, x182); + fiat_p256_mulx_u32(&x201, &x202, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x203, &x204, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x205, &x206, x183, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x207, &x208, x183, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x209, &x210, 0x0, x208, x205); + fiat_p256_addcarryx_u32(&x211, &x212, x210, x206, x203); + x213 = (x212 + x204); + fiat_p256_addcarryx_u32(&x214, &x215, 0x0, x183, x207); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x185, x209); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x187, x211); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x189, x213); + fiat_p256_addcarryx_u32(&x222, &x223, x221, x191, 0x0); + fiat_p256_addcarryx_u32(&x224, &x225, x223, x193, 0x0); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x195, x183); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x197, x201); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x199, x202); + x232 = ((uint32_t)x231 + x200); + fiat_p256_mulx_u32(&x233, &x234, x3, (arg1[7])); + fiat_p256_mulx_u32(&x235, &x236, x3, (arg1[6])); + fiat_p256_mulx_u32(&x237, &x238, x3, (arg1[5])); + fiat_p256_mulx_u32(&x239, &x240, x3, (arg1[4])); + fiat_p256_mulx_u32(&x241, &x242, x3, (arg1[3])); + fiat_p256_mulx_u32(&x243, &x244, x3, (arg1[2])); + fiat_p256_mulx_u32(&x245, &x246, x3, (arg1[1])); + fiat_p256_mulx_u32(&x247, &x248, x3, (arg1[0])); + fiat_p256_addcarryx_u32(&x249, &x250, 0x0, x248, x245); + fiat_p256_addcarryx_u32(&x251, &x252, x250, x246, x243); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x244, x241); + fiat_p256_addcarryx_u32(&x255, &x256, x254, x242, x239); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x240, x237); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x238, x235); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x236, x233); + x263 = (x262 + x234); + fiat_p256_addcarryx_u32(&x264, &x265, 0x0, x216, x247); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x218, x249); + fiat_p256_addcarryx_u32(&x268, &x269, x267, x220, x251); + fiat_p256_addcarryx_u32(&x270, &x271, x269, x222, x253); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x224, x255); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x226, x257); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x228, x259); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x230, x261); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x232, x263); + fiat_p256_mulx_u32(&x282, &x283, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x284, &x285, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x286, &x287, x264, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x264, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x290, &x291, 0x0, x289, x286); + fiat_p256_addcarryx_u32(&x292, &x293, x291, x287, x284); + x294 = (x293 + x285); + fiat_p256_addcarryx_u32(&x295, &x296, 0x0, x264, x288); + fiat_p256_addcarryx_u32(&x297, &x298, x296, x266, x290); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x268, x292); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x270, x294); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x272, 0x0); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x274, 0x0); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x276, x264); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x278, x282); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x280, x283); + x313 = ((uint32_t)x312 + x281); + fiat_p256_mulx_u32(&x314, &x315, x4, (arg1[7])); + fiat_p256_mulx_u32(&x316, &x317, x4, (arg1[6])); + fiat_p256_mulx_u32(&x318, &x319, x4, (arg1[5])); + fiat_p256_mulx_u32(&x320, &x321, x4, (arg1[4])); + fiat_p256_mulx_u32(&x322, &x323, x4, (arg1[3])); + fiat_p256_mulx_u32(&x324, &x325, x4, (arg1[2])); + fiat_p256_mulx_u32(&x326, &x327, x4, (arg1[1])); + fiat_p256_mulx_u32(&x328, &x329, x4, (arg1[0])); + fiat_p256_addcarryx_u32(&x330, &x331, 0x0, x329, x326); + fiat_p256_addcarryx_u32(&x332, &x333, x331, x327, x324); + fiat_p256_addcarryx_u32(&x334, &x335, x333, x325, x322); + fiat_p256_addcarryx_u32(&x336, &x337, x335, x323, x320); + fiat_p256_addcarryx_u32(&x338, &x339, x337, x321, x318); + fiat_p256_addcarryx_u32(&x340, &x341, x339, x319, x316); + fiat_p256_addcarryx_u32(&x342, &x343, x341, x317, x314); + x344 = (x343 + x315); + fiat_p256_addcarryx_u32(&x345, &x346, 0x0, x297, x328); + fiat_p256_addcarryx_u32(&x347, &x348, x346, x299, x330); + fiat_p256_addcarryx_u32(&x349, &x350, x348, x301, x332); + fiat_p256_addcarryx_u32(&x351, &x352, x350, x303, x334); + fiat_p256_addcarryx_u32(&x353, &x354, x352, x305, x336); + fiat_p256_addcarryx_u32(&x355, &x356, x354, x307, x338); + fiat_p256_addcarryx_u32(&x357, &x358, x356, x309, x340); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x311, x342); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x313, x344); + fiat_p256_mulx_u32(&x363, &x364, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x365, &x366, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x367, &x368, x345, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x369, &x370, x345, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x371, &x372, 0x0, x370, x367); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x368, x365); + x375 = (x374 + x366); + fiat_p256_addcarryx_u32(&x376, &x377, 0x0, x345, x369); + fiat_p256_addcarryx_u32(&x378, &x379, x377, x347, x371); + fiat_p256_addcarryx_u32(&x380, &x381, x379, x349, x373); + fiat_p256_addcarryx_u32(&x382, &x383, x381, x351, x375); + fiat_p256_addcarryx_u32(&x384, &x385, x383, x353, 0x0); + fiat_p256_addcarryx_u32(&x386, &x387, x385, x355, 0x0); + fiat_p256_addcarryx_u32(&x388, &x389, x387, x357, x345); + fiat_p256_addcarryx_u32(&x390, &x391, x389, x359, x363); + fiat_p256_addcarryx_u32(&x392, &x393, x391, x361, x364); + x394 = ((uint32_t)x393 + x362); + fiat_p256_mulx_u32(&x395, &x396, x5, (arg1[7])); + fiat_p256_mulx_u32(&x397, &x398, x5, (arg1[6])); + fiat_p256_mulx_u32(&x399, &x400, x5, (arg1[5])); + fiat_p256_mulx_u32(&x401, &x402, x5, (arg1[4])); + fiat_p256_mulx_u32(&x403, &x404, x5, (arg1[3])); + fiat_p256_mulx_u32(&x405, &x406, x5, (arg1[2])); + fiat_p256_mulx_u32(&x407, &x408, x5, (arg1[1])); + fiat_p256_mulx_u32(&x409, &x410, x5, (arg1[0])); + fiat_p256_addcarryx_u32(&x411, &x412, 0x0, x410, x407); + fiat_p256_addcarryx_u32(&x413, &x414, x412, x408, x405); + fiat_p256_addcarryx_u32(&x415, &x416, x414, x406, x403); + fiat_p256_addcarryx_u32(&x417, &x418, x416, x404, x401); + fiat_p256_addcarryx_u32(&x419, &x420, x418, x402, x399); + fiat_p256_addcarryx_u32(&x421, &x422, x420, x400, x397); + fiat_p256_addcarryx_u32(&x423, &x424, x422, x398, x395); + x425 = (x424 + x396); + fiat_p256_addcarryx_u32(&x426, &x427, 0x0, x378, x409); + fiat_p256_addcarryx_u32(&x428, &x429, x427, x380, x411); + fiat_p256_addcarryx_u32(&x430, &x431, x429, x382, x413); + fiat_p256_addcarryx_u32(&x432, &x433, x431, x384, x415); + fiat_p256_addcarryx_u32(&x434, &x435, x433, x386, x417); + fiat_p256_addcarryx_u32(&x436, &x437, x435, x388, x419); + fiat_p256_addcarryx_u32(&x438, &x439, x437, x390, x421); + fiat_p256_addcarryx_u32(&x440, &x441, x439, x392, x423); + fiat_p256_addcarryx_u32(&x442, &x443, x441, x394, x425); + fiat_p256_mulx_u32(&x444, &x445, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x446, &x447, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x448, &x449, x426, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x450, &x451, x426, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x452, &x453, 0x0, x451, x448); + fiat_p256_addcarryx_u32(&x454, &x455, x453, x449, x446); + x456 = (x455 + x447); + fiat_p256_addcarryx_u32(&x457, &x458, 0x0, x426, x450); + fiat_p256_addcarryx_u32(&x459, &x460, x458, x428, x452); + fiat_p256_addcarryx_u32(&x461, &x462, x460, x430, x454); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x432, x456); + fiat_p256_addcarryx_u32(&x465, &x466, x464, x434, 0x0); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x436, 0x0); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x438, x426); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x440, x444); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x442, x445); + x475 = ((uint32_t)x474 + x443); + fiat_p256_mulx_u32(&x476, &x477, x6, (arg1[7])); + fiat_p256_mulx_u32(&x478, &x479, x6, (arg1[6])); + fiat_p256_mulx_u32(&x480, &x481, x6, (arg1[5])); + fiat_p256_mulx_u32(&x482, &x483, x6, (arg1[4])); + fiat_p256_mulx_u32(&x484, &x485, x6, (arg1[3])); + fiat_p256_mulx_u32(&x486, &x487, x6, (arg1[2])); + fiat_p256_mulx_u32(&x488, &x489, x6, (arg1[1])); + fiat_p256_mulx_u32(&x490, &x491, x6, (arg1[0])); + fiat_p256_addcarryx_u32(&x492, &x493, 0x0, x491, x488); + fiat_p256_addcarryx_u32(&x494, &x495, x493, x489, x486); + fiat_p256_addcarryx_u32(&x496, &x497, x495, x487, x484); + fiat_p256_addcarryx_u32(&x498, &x499, x497, x485, x482); + fiat_p256_addcarryx_u32(&x500, &x501, x499, x483, x480); + fiat_p256_addcarryx_u32(&x502, &x503, x501, x481, x478); + fiat_p256_addcarryx_u32(&x504, &x505, x503, x479, x476); + x506 = (x505 + x477); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x459, x490); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x461, x492); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x463, x494); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x465, x496); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x467, x498); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x469, x500); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x471, x502); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x473, x504); + fiat_p256_addcarryx_u32(&x523, &x524, x522, x475, x506); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x531, &x532, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x533, &x534, 0x0, x532, x529); + fiat_p256_addcarryx_u32(&x535, &x536, x534, x530, x527); + x537 = (x536 + x528); + fiat_p256_addcarryx_u32(&x538, &x539, 0x0, x507, x531); + fiat_p256_addcarryx_u32(&x540, &x541, x539, x509, x533); + fiat_p256_addcarryx_u32(&x542, &x543, x541, x511, x535); + fiat_p256_addcarryx_u32(&x544, &x545, x543, x513, x537); + fiat_p256_addcarryx_u32(&x546, &x547, x545, x515, 0x0); + fiat_p256_addcarryx_u32(&x548, &x549, x547, x517, 0x0); + fiat_p256_addcarryx_u32(&x550, &x551, x549, x519, x507); + fiat_p256_addcarryx_u32(&x552, &x553, x551, x521, x525); + fiat_p256_addcarryx_u32(&x554, &x555, x553, x523, x526); + x556 = ((uint32_t)x555 + x524); + fiat_p256_mulx_u32(&x557, &x558, x7, (arg1[7])); + fiat_p256_mulx_u32(&x559, &x560, x7, (arg1[6])); + fiat_p256_mulx_u32(&x561, &x562, x7, (arg1[5])); + fiat_p256_mulx_u32(&x563, &x564, x7, (arg1[4])); + fiat_p256_mulx_u32(&x565, &x566, x7, (arg1[3])); + fiat_p256_mulx_u32(&x567, &x568, x7, (arg1[2])); + fiat_p256_mulx_u32(&x569, &x570, x7, (arg1[1])); + fiat_p256_mulx_u32(&x571, &x572, x7, (arg1[0])); + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x572, x569); + fiat_p256_addcarryx_u32(&x575, &x576, x574, x570, x567); + fiat_p256_addcarryx_u32(&x577, &x578, x576, x568, x565); + fiat_p256_addcarryx_u32(&x579, &x580, x578, x566, x563); + fiat_p256_addcarryx_u32(&x581, &x582, x580, x564, x561); + fiat_p256_addcarryx_u32(&x583, &x584, x582, x562, x559); + fiat_p256_addcarryx_u32(&x585, &x586, x584, x560, x557); + x587 = (x586 + x558); + fiat_p256_addcarryx_u32(&x588, &x589, 0x0, x540, x571); + fiat_p256_addcarryx_u32(&x590, &x591, x589, x542, x573); + fiat_p256_addcarryx_u32(&x592, &x593, x591, x544, x575); + fiat_p256_addcarryx_u32(&x594, &x595, x593, x546, x577); + fiat_p256_addcarryx_u32(&x596, &x597, x595, x548, x579); + fiat_p256_addcarryx_u32(&x598, &x599, x597, x550, x581); + fiat_p256_addcarryx_u32(&x600, &x601, x599, x552, x583); + fiat_p256_addcarryx_u32(&x602, &x603, x601, x554, x585); + fiat_p256_addcarryx_u32(&x604, &x605, x603, x556, x587); + fiat_p256_mulx_u32(&x606, &x607, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x608, &x609, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x610, &x611, x588, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x612, &x613, x588, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x614, &x615, 0x0, x613, x610); + fiat_p256_addcarryx_u32(&x616, &x617, x615, x611, x608); + x618 = (x617 + x609); + fiat_p256_addcarryx_u32(&x619, &x620, 0x0, x588, x612); + fiat_p256_addcarryx_u32(&x621, &x622, x620, x590, x614); + fiat_p256_addcarryx_u32(&x623, &x624, x622, x592, x616); + fiat_p256_addcarryx_u32(&x625, &x626, x624, x594, x618); + fiat_p256_addcarryx_u32(&x627, &x628, x626, x596, 0x0); + fiat_p256_addcarryx_u32(&x629, &x630, x628, x598, 0x0); + fiat_p256_addcarryx_u32(&x631, &x632, x630, x600, x588); + fiat_p256_addcarryx_u32(&x633, &x634, x632, x602, x606); + fiat_p256_addcarryx_u32(&x635, &x636, x634, x604, x607); + x637 = ((uint32_t)x636 + x605); + fiat_p256_subborrowx_u32(&x638, &x639, 0x0, x621, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x640, &x641, x639, x623, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x642, &x643, x641, x625, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x644, &x645, x643, x627, 0x0); + fiat_p256_subborrowx_u32(&x646, &x647, x645, x629, 0x0); + fiat_p256_subborrowx_u32(&x648, &x649, x647, x631, 0x0); + fiat_p256_subborrowx_u32(&x650, &x651, x649, x633, 0x1); + fiat_p256_subborrowx_u32(&x652, &x653, x651, x635, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x654, &x655, x653, x637, 0x0); + fiat_p256_cmovznz_u32(&x656, x655, x638, x621); + fiat_p256_cmovznz_u32(&x657, x655, x640, x623); + fiat_p256_cmovznz_u32(&x658, x655, x642, x625); + fiat_p256_cmovznz_u32(&x659, x655, x644, x627); + fiat_p256_cmovznz_u32(&x660, x655, x646, x629); + fiat_p256_cmovznz_u32(&x661, x655, x648, x631); + fiat_p256_cmovznz_u32(&x662, x655, x650, x633); fiat_p256_cmovznz_u32(&x663, x655, x652, x635); out1[0] = x656; out1[1] = x657; @@ -2128,6 +2221,7 @@ static void fiat_p256_square(uint32_t out1[8], const uint32_t arg1[8]) { /* * The function fiat_p256_add adds two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -2135,79 +2229,74 @@ static void fiat_p256_square(uint32_t out1[8], const uint32_t arg1[8]) { * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_add(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { uint32_t x1; fiat_p256_uint1 x2; - fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); uint32_t x3; fiat_p256_uint1 x4; - fiat_p256_addcarryx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); uint32_t x5; fiat_p256_uint1 x6; - fiat_p256_addcarryx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); uint32_t x7; fiat_p256_uint1 x8; - fiat_p256_addcarryx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); uint32_t x9; fiat_p256_uint1 x10; - fiat_p256_addcarryx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); uint32_t x11; fiat_p256_uint1 x12; - fiat_p256_addcarryx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); uint32_t x13; fiat_p256_uint1 x14; - fiat_p256_addcarryx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); uint32_t x15; fiat_p256_uint1 x16; - fiat_p256_addcarryx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); uint32_t x17; fiat_p256_uint1 x18; - fiat_p256_subborrowx_u32(&x17, &x18, 0x0, x1, UINT32_C(0xffffffff)); uint32_t x19; fiat_p256_uint1 x20; - fiat_p256_subborrowx_u32(&x19, &x20, x18, x3, UINT32_C(0xffffffff)); uint32_t x21; fiat_p256_uint1 x22; - fiat_p256_subborrowx_u32(&x21, &x22, x20, x5, UINT32_C(0xffffffff)); uint32_t x23; fiat_p256_uint1 x24; - fiat_p256_subborrowx_u32(&x23, &x24, x22, x7, 0x0); uint32_t x25; fiat_p256_uint1 x26; - fiat_p256_subborrowx_u32(&x25, &x26, x24, x9, 0x0); uint32_t x27; fiat_p256_uint1 x28; - fiat_p256_subborrowx_u32(&x27, &x28, x26, x11, 0x0); uint32_t x29; fiat_p256_uint1 x30; - fiat_p256_subborrowx_u32(&x29, &x30, x28, x13, 0x1); uint32_t x31; fiat_p256_uint1 x32; - fiat_p256_subborrowx_u32(&x31, &x32, x30, x15, UINT32_C(0xffffffff)); uint32_t x33; fiat_p256_uint1 x34; - fiat_p256_subborrowx_u32(&x33, &x34, x32, x16, 0x0); uint32_t x35; - fiat_p256_cmovznz_u32(&x35, x34, x17, x1); uint32_t x36; - fiat_p256_cmovznz_u32(&x36, x34, x19, x3); uint32_t x37; - fiat_p256_cmovznz_u32(&x37, x34, x21, x5); uint32_t x38; - fiat_p256_cmovznz_u32(&x38, x34, x23, x7); uint32_t x39; - fiat_p256_cmovznz_u32(&x39, x34, x25, x9); uint32_t x40; - fiat_p256_cmovznz_u32(&x40, x34, x27, x11); uint32_t x41; - fiat_p256_cmovznz_u32(&x41, x34, x29, x13); uint32_t x42; + fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_addcarryx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_addcarryx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_addcarryx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_addcarryx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); + fiat_p256_addcarryx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); + fiat_p256_addcarryx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); + fiat_p256_addcarryx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); + fiat_p256_subborrowx_u32(&x17, &x18, 0x0, x1, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x19, &x20, x18, x3, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x21, &x22, x20, x5, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x23, &x24, x22, x7, 0x0); + fiat_p256_subborrowx_u32(&x25, &x26, x24, x9, 0x0); + fiat_p256_subborrowx_u32(&x27, &x28, x26, x11, 0x0); + fiat_p256_subborrowx_u32(&x29, &x30, x28, x13, 0x1); + fiat_p256_subborrowx_u32(&x31, &x32, x30, x15, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x33, &x34, x32, x16, 0x0); + fiat_p256_cmovznz_u32(&x35, x34, x17, x1); + fiat_p256_cmovznz_u32(&x36, x34, x19, x3); + fiat_p256_cmovznz_u32(&x37, x34, x21, x5); + fiat_p256_cmovznz_u32(&x38, x34, x23, x7); + fiat_p256_cmovznz_u32(&x39, x34, x25, x9); + fiat_p256_cmovznz_u32(&x40, x34, x27, x11); + fiat_p256_cmovznz_u32(&x41, x34, x29, x13); fiat_p256_cmovznz_u32(&x42, x34, x31, x15); out1[0] = x35; out1[1] = x36; @@ -2221,6 +2310,7 @@ static void fiat_p256_add(uint32_t out1[8], const uint32_t arg1[8], const uint32 /* * The function fiat_p256_sub subtracts two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -2228,63 +2318,58 @@ static void fiat_p256_add(uint32_t out1[8], const uint32_t arg1[8], const uint32 * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_sub(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { uint32_t x1; fiat_p256_uint1 x2; - fiat_p256_subborrowx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); uint32_t x3; fiat_p256_uint1 x4; - fiat_p256_subborrowx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); uint32_t x5; fiat_p256_uint1 x6; - fiat_p256_subborrowx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); uint32_t x7; fiat_p256_uint1 x8; - fiat_p256_subborrowx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); uint32_t x9; fiat_p256_uint1 x10; - fiat_p256_subborrowx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); uint32_t x11; fiat_p256_uint1 x12; - fiat_p256_subborrowx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); uint32_t x13; fiat_p256_uint1 x14; - fiat_p256_subborrowx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); uint32_t x15; fiat_p256_uint1 x16; - fiat_p256_subborrowx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); uint32_t x17; - fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); uint32_t x18; fiat_p256_uint1 x19; - fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, (x17 & UINT32_C(0xffffffff))); uint32_t x20; fiat_p256_uint1 x21; - fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, (x17 & UINT32_C(0xffffffff))); uint32_t x22; fiat_p256_uint1 x23; - fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, (x17 & UINT32_C(0xffffffff))); uint32_t x24; fiat_p256_uint1 x25; - fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); uint32_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); uint32_t x28; fiat_p256_uint1 x29; - fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); uint32_t x30; fiat_p256_uint1 x31; - fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); uint32_t x32; fiat_p256_uint1 x33; - fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, (x17 & UINT32_C(0xffffffff))); + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_subborrowx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_subborrowx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_subborrowx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_subborrowx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); + fiat_p256_subborrowx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); + fiat_p256_subborrowx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); + fiat_p256_subborrowx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, x17); + fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, x17); + fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, x17); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); + fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); + fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); + fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, x17); out1[0] = x18; out1[1] = x20; out1[2] = x22; @@ -2297,68 +2382,65 @@ static void fiat_p256_sub(uint32_t out1[8], const uint32_t arg1[8], const uint32 /* * The function fiat_p256_opp negates a field element in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_opp(uint32_t out1[8], const uint32_t arg1[8]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_opp(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { uint32_t x1; fiat_p256_uint1 x2; - fiat_p256_subborrowx_u32(&x1, &x2, 0x0, 0x0, (arg1[0])); uint32_t x3; fiat_p256_uint1 x4; - fiat_p256_subborrowx_u32(&x3, &x4, x2, 0x0, (arg1[1])); uint32_t x5; fiat_p256_uint1 x6; - fiat_p256_subborrowx_u32(&x5, &x6, x4, 0x0, (arg1[2])); uint32_t x7; fiat_p256_uint1 x8; - fiat_p256_subborrowx_u32(&x7, &x8, x6, 0x0, (arg1[3])); uint32_t x9; fiat_p256_uint1 x10; - fiat_p256_subborrowx_u32(&x9, &x10, x8, 0x0, (arg1[4])); uint32_t x11; fiat_p256_uint1 x12; - fiat_p256_subborrowx_u32(&x11, &x12, x10, 0x0, (arg1[5])); uint32_t x13; fiat_p256_uint1 x14; - fiat_p256_subborrowx_u32(&x13, &x14, x12, 0x0, (arg1[6])); uint32_t x15; fiat_p256_uint1 x16; - fiat_p256_subborrowx_u32(&x15, &x16, x14, 0x0, (arg1[7])); uint32_t x17; - fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); uint32_t x18; fiat_p256_uint1 x19; - fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, (x17 & UINT32_C(0xffffffff))); uint32_t x20; fiat_p256_uint1 x21; - fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, (x17 & UINT32_C(0xffffffff))); uint32_t x22; fiat_p256_uint1 x23; - fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, (x17 & UINT32_C(0xffffffff))); uint32_t x24; fiat_p256_uint1 x25; - fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); uint32_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); uint32_t x28; fiat_p256_uint1 x29; - fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); uint32_t x30; fiat_p256_uint1 x31; - fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); uint32_t x32; fiat_p256_uint1 x33; - fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, (x17 & UINT32_C(0xffffffff))); + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, 0x0, (arg1[0])); + fiat_p256_subborrowx_u32(&x3, &x4, x2, 0x0, (arg1[1])); + fiat_p256_subborrowx_u32(&x5, &x6, x4, 0x0, (arg1[2])); + fiat_p256_subborrowx_u32(&x7, &x8, x6, 0x0, (arg1[3])); + fiat_p256_subborrowx_u32(&x9, &x10, x8, 0x0, (arg1[4])); + fiat_p256_subborrowx_u32(&x11, &x12, x10, 0x0, (arg1[5])); + fiat_p256_subborrowx_u32(&x13, &x14, x12, 0x0, (arg1[6])); + fiat_p256_subborrowx_u32(&x15, &x16, x14, 0x0, (arg1[7])); + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, x1, x17); + fiat_p256_addcarryx_u32(&x20, &x21, x19, x3, x17); + fiat_p256_addcarryx_u32(&x22, &x23, x21, x5, x17); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x7, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x9, 0x0); + fiat_p256_addcarryx_u32(&x28, &x29, x27, x11, 0x0); + fiat_p256_addcarryx_u32(&x30, &x31, x29, x13, (fiat_p256_uint1)(x17 & 0x1)); + fiat_p256_addcarryx_u32(&x32, &x33, x31, x15, x17); out1[0] = x18; out1[1] = x20; out1[2] = x22; @@ -2371,532 +2453,530 @@ static void fiat_p256_opp(uint32_t out1[8], const uint32_t arg1[8]) { /* * The function fiat_p256_from_montgomery translates a field element out of the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval out1 mod m = (eval arg1 * ((2^32)⁻¹ mod m)^8) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_from_montgomery(uint32_t out1[8], const uint32_t arg1[8]) { - uint32_t x1 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_from_montgomery(fiat_p256_non_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint32_t x1; uint32_t x2; uint32_t x3; - fiat_p256_mulx_u32(&x2, &x3, x1, UINT32_C(0xffffffff)); uint32_t x4; uint32_t x5; - fiat_p256_mulx_u32(&x4, &x5, x1, UINT32_C(0xffffffff)); uint32_t x6; uint32_t x7; - fiat_p256_mulx_u32(&x6, &x7, x1, UINT32_C(0xffffffff)); uint32_t x8; uint32_t x9; - fiat_p256_mulx_u32(&x8, &x9, x1, UINT32_C(0xffffffff)); uint32_t x10; fiat_p256_uint1 x11; - fiat_p256_addcarryx_u32(&x10, &x11, 0x0, x9, x6); uint32_t x12; fiat_p256_uint1 x13; - fiat_p256_addcarryx_u32(&x12, &x13, x11, x7, x4); uint32_t x14; fiat_p256_uint1 x15; - fiat_p256_addcarryx_u32(&x14, &x15, 0x0, x1, x8); uint32_t x16; fiat_p256_uint1 x17; - fiat_p256_addcarryx_u32(&x16, &x17, x15, 0x0, x10); uint32_t x18; fiat_p256_uint1 x19; - fiat_p256_addcarryx_u32(&x18, &x19, x17, 0x0, x12); uint32_t x20; fiat_p256_uint1 x21; - fiat_p256_addcarryx_u32(&x20, &x21, x19, 0x0, (x13 + x5)); uint32_t x22; fiat_p256_uint1 x23; - fiat_p256_addcarryx_u32(&x22, &x23, 0x0, x16, (arg1[1])); uint32_t x24; fiat_p256_uint1 x25; - fiat_p256_addcarryx_u32(&x24, &x25, x23, x18, 0x0); uint32_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u32(&x26, &x27, x25, x20, 0x0); uint32_t x28; uint32_t x29; - fiat_p256_mulx_u32(&x28, &x29, x22, UINT32_C(0xffffffff)); uint32_t x30; uint32_t x31; - fiat_p256_mulx_u32(&x30, &x31, x22, UINT32_C(0xffffffff)); uint32_t x32; uint32_t x33; - fiat_p256_mulx_u32(&x32, &x33, x22, UINT32_C(0xffffffff)); uint32_t x34; uint32_t x35; - fiat_p256_mulx_u32(&x34, &x35, x22, UINT32_C(0xffffffff)); uint32_t x36; fiat_p256_uint1 x37; - fiat_p256_addcarryx_u32(&x36, &x37, 0x0, x35, x32); uint32_t x38; fiat_p256_uint1 x39; - fiat_p256_addcarryx_u32(&x38, &x39, x37, x33, x30); uint32_t x40; fiat_p256_uint1 x41; - fiat_p256_addcarryx_u32(&x40, &x41, 0x0, x22, x34); uint32_t x42; fiat_p256_uint1 x43; - fiat_p256_addcarryx_u32(&x42, &x43, x41, x24, x36); uint32_t x44; fiat_p256_uint1 x45; - fiat_p256_addcarryx_u32(&x44, &x45, x43, x26, x38); uint32_t x46; fiat_p256_uint1 x47; - fiat_p256_addcarryx_u32(&x46, &x47, x45, ((uint32_t)x27 + x21), (x39 + x31)); uint32_t x48; fiat_p256_uint1 x49; - fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x2, x22); uint32_t x50; fiat_p256_uint1 x51; - fiat_p256_addcarryx_u32(&x50, &x51, x49, x3, x28); uint32_t x52; fiat_p256_uint1 x53; - fiat_p256_addcarryx_u32(&x52, &x53, 0x0, x42, (arg1[2])); uint32_t x54; fiat_p256_uint1 x55; - fiat_p256_addcarryx_u32(&x54, &x55, x53, x44, 0x0); uint32_t x56; fiat_p256_uint1 x57; - fiat_p256_addcarryx_u32(&x56, &x57, x55, x46, 0x0); uint32_t x58; uint32_t x59; - fiat_p256_mulx_u32(&x58, &x59, x52, UINT32_C(0xffffffff)); uint32_t x60; uint32_t x61; - fiat_p256_mulx_u32(&x60, &x61, x52, UINT32_C(0xffffffff)); uint32_t x62; uint32_t x63; - fiat_p256_mulx_u32(&x62, &x63, x52, UINT32_C(0xffffffff)); uint32_t x64; uint32_t x65; - fiat_p256_mulx_u32(&x64, &x65, x52, UINT32_C(0xffffffff)); uint32_t x66; fiat_p256_uint1 x67; - fiat_p256_addcarryx_u32(&x66, &x67, 0x0, x65, x62); uint32_t x68; fiat_p256_uint1 x69; - fiat_p256_addcarryx_u32(&x68, &x69, x67, x63, x60); uint32_t x70; fiat_p256_uint1 x71; - fiat_p256_addcarryx_u32(&x70, &x71, 0x0, x52, x64); uint32_t x72; fiat_p256_uint1 x73; - fiat_p256_addcarryx_u32(&x72, &x73, x71, x54, x66); uint32_t x74; fiat_p256_uint1 x75; - fiat_p256_addcarryx_u32(&x74, &x75, x73, x56, x68); uint32_t x76; fiat_p256_uint1 x77; - fiat_p256_addcarryx_u32(&x76, &x77, x75, ((uint32_t)x57 + x47), (x69 + x61)); uint32_t x78; fiat_p256_uint1 x79; - fiat_p256_addcarryx_u32(&x78, &x79, x77, x1, 0x0); uint32_t x80; fiat_p256_uint1 x81; - fiat_p256_addcarryx_u32(&x80, &x81, x79, x48, 0x0); uint32_t x82; fiat_p256_uint1 x83; - fiat_p256_addcarryx_u32(&x82, &x83, x81, x50, x52); uint32_t x84; fiat_p256_uint1 x85; - fiat_p256_addcarryx_u32(&x84, &x85, x83, (x51 + x29), x58); uint32_t x86; fiat_p256_uint1 x87; - fiat_p256_addcarryx_u32(&x86, &x87, 0x0, x72, (arg1[3])); uint32_t x88; fiat_p256_uint1 x89; - fiat_p256_addcarryx_u32(&x88, &x89, x87, x74, 0x0); uint32_t x90; fiat_p256_uint1 x91; - fiat_p256_addcarryx_u32(&x90, &x91, x89, x76, 0x0); uint32_t x92; fiat_p256_uint1 x93; - fiat_p256_addcarryx_u32(&x92, &x93, x91, x78, 0x0); uint32_t x94; fiat_p256_uint1 x95; - fiat_p256_addcarryx_u32(&x94, &x95, x93, x80, 0x0); uint32_t x96; fiat_p256_uint1 x97; - fiat_p256_addcarryx_u32(&x96, &x97, x95, x82, 0x0); uint32_t x98; fiat_p256_uint1 x99; - fiat_p256_addcarryx_u32(&x98, &x99, x97, x84, 0x0); uint32_t x100; fiat_p256_uint1 x101; - fiat_p256_addcarryx_u32(&x100, &x101, x99, (x85 + x59), 0x0); uint32_t x102; uint32_t x103; - fiat_p256_mulx_u32(&x102, &x103, x86, UINT32_C(0xffffffff)); uint32_t x104; uint32_t x105; - fiat_p256_mulx_u32(&x104, &x105, x86, UINT32_C(0xffffffff)); uint32_t x106; uint32_t x107; - fiat_p256_mulx_u32(&x106, &x107, x86, UINT32_C(0xffffffff)); uint32_t x108; uint32_t x109; - fiat_p256_mulx_u32(&x108, &x109, x86, UINT32_C(0xffffffff)); uint32_t x110; fiat_p256_uint1 x111; - fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x109, x106); uint32_t x112; fiat_p256_uint1 x113; - fiat_p256_addcarryx_u32(&x112, &x113, x111, x107, x104); uint32_t x114; fiat_p256_uint1 x115; - fiat_p256_addcarryx_u32(&x114, &x115, 0x0, x86, x108); uint32_t x116; fiat_p256_uint1 x117; - fiat_p256_addcarryx_u32(&x116, &x117, x115, x88, x110); uint32_t x118; fiat_p256_uint1 x119; - fiat_p256_addcarryx_u32(&x118, &x119, x117, x90, x112); uint32_t x120; fiat_p256_uint1 x121; - fiat_p256_addcarryx_u32(&x120, &x121, x119, x92, (x113 + x105)); uint32_t x122; fiat_p256_uint1 x123; - fiat_p256_addcarryx_u32(&x122, &x123, x121, x94, 0x0); uint32_t x124; fiat_p256_uint1 x125; - fiat_p256_addcarryx_u32(&x124, &x125, x123, x96, 0x0); uint32_t x126; fiat_p256_uint1 x127; - fiat_p256_addcarryx_u32(&x126, &x127, x125, x98, x86); uint32_t x128; fiat_p256_uint1 x129; - fiat_p256_addcarryx_u32(&x128, &x129, x127, x100, x102); uint32_t x130; fiat_p256_uint1 x131; - fiat_p256_addcarryx_u32(&x130, &x131, x129, x101, x103); uint32_t x132; fiat_p256_uint1 x133; - fiat_p256_addcarryx_u32(&x132, &x133, 0x0, x116, (arg1[4])); uint32_t x134; fiat_p256_uint1 x135; - fiat_p256_addcarryx_u32(&x134, &x135, x133, x118, 0x0); uint32_t x136; fiat_p256_uint1 x137; - fiat_p256_addcarryx_u32(&x136, &x137, x135, x120, 0x0); uint32_t x138; fiat_p256_uint1 x139; - fiat_p256_addcarryx_u32(&x138, &x139, x137, x122, 0x0); uint32_t x140; fiat_p256_uint1 x141; - fiat_p256_addcarryx_u32(&x140, &x141, x139, x124, 0x0); uint32_t x142; fiat_p256_uint1 x143; - fiat_p256_addcarryx_u32(&x142, &x143, x141, x126, 0x0); uint32_t x144; fiat_p256_uint1 x145; - fiat_p256_addcarryx_u32(&x144, &x145, x143, x128, 0x0); uint32_t x146; fiat_p256_uint1 x147; - fiat_p256_addcarryx_u32(&x146, &x147, x145, x130, 0x0); uint32_t x148; uint32_t x149; - fiat_p256_mulx_u32(&x148, &x149, x132, UINT32_C(0xffffffff)); uint32_t x150; uint32_t x151; - fiat_p256_mulx_u32(&x150, &x151, x132, UINT32_C(0xffffffff)); uint32_t x152; uint32_t x153; - fiat_p256_mulx_u32(&x152, &x153, x132, UINT32_C(0xffffffff)); uint32_t x154; uint32_t x155; - fiat_p256_mulx_u32(&x154, &x155, x132, UINT32_C(0xffffffff)); uint32_t x156; fiat_p256_uint1 x157; - fiat_p256_addcarryx_u32(&x156, &x157, 0x0, x155, x152); uint32_t x158; fiat_p256_uint1 x159; - fiat_p256_addcarryx_u32(&x158, &x159, x157, x153, x150); uint32_t x160; fiat_p256_uint1 x161; - fiat_p256_addcarryx_u32(&x160, &x161, 0x0, x132, x154); uint32_t x162; fiat_p256_uint1 x163; - fiat_p256_addcarryx_u32(&x162, &x163, x161, x134, x156); uint32_t x164; fiat_p256_uint1 x165; - fiat_p256_addcarryx_u32(&x164, &x165, x163, x136, x158); uint32_t x166; fiat_p256_uint1 x167; - fiat_p256_addcarryx_u32(&x166, &x167, x165, x138, (x159 + x151)); uint32_t x168; fiat_p256_uint1 x169; - fiat_p256_addcarryx_u32(&x168, &x169, x167, x140, 0x0); uint32_t x170; fiat_p256_uint1 x171; - fiat_p256_addcarryx_u32(&x170, &x171, x169, x142, 0x0); uint32_t x172; fiat_p256_uint1 x173; - fiat_p256_addcarryx_u32(&x172, &x173, x171, x144, x132); uint32_t x174; fiat_p256_uint1 x175; - fiat_p256_addcarryx_u32(&x174, &x175, x173, x146, x148); uint32_t x176; fiat_p256_uint1 x177; - fiat_p256_addcarryx_u32(&x176, &x177, x175, ((uint32_t)x147 + x131), x149); uint32_t x178; fiat_p256_uint1 x179; - fiat_p256_addcarryx_u32(&x178, &x179, 0x0, x162, (arg1[5])); uint32_t x180; fiat_p256_uint1 x181; - fiat_p256_addcarryx_u32(&x180, &x181, x179, x164, 0x0); uint32_t x182; fiat_p256_uint1 x183; - fiat_p256_addcarryx_u32(&x182, &x183, x181, x166, 0x0); uint32_t x184; fiat_p256_uint1 x185; - fiat_p256_addcarryx_u32(&x184, &x185, x183, x168, 0x0); uint32_t x186; fiat_p256_uint1 x187; - fiat_p256_addcarryx_u32(&x186, &x187, x185, x170, 0x0); uint32_t x188; fiat_p256_uint1 x189; - fiat_p256_addcarryx_u32(&x188, &x189, x187, x172, 0x0); uint32_t x190; fiat_p256_uint1 x191; - fiat_p256_addcarryx_u32(&x190, &x191, x189, x174, 0x0); uint32_t x192; fiat_p256_uint1 x193; - fiat_p256_addcarryx_u32(&x192, &x193, x191, x176, 0x0); uint32_t x194; uint32_t x195; - fiat_p256_mulx_u32(&x194, &x195, x178, UINT32_C(0xffffffff)); uint32_t x196; uint32_t x197; - fiat_p256_mulx_u32(&x196, &x197, x178, UINT32_C(0xffffffff)); uint32_t x198; uint32_t x199; - fiat_p256_mulx_u32(&x198, &x199, x178, UINT32_C(0xffffffff)); uint32_t x200; uint32_t x201; - fiat_p256_mulx_u32(&x200, &x201, x178, UINT32_C(0xffffffff)); uint32_t x202; fiat_p256_uint1 x203; - fiat_p256_addcarryx_u32(&x202, &x203, 0x0, x201, x198); uint32_t x204; fiat_p256_uint1 x205; - fiat_p256_addcarryx_u32(&x204, &x205, x203, x199, x196); uint32_t x206; fiat_p256_uint1 x207; - fiat_p256_addcarryx_u32(&x206, &x207, 0x0, x178, x200); uint32_t x208; fiat_p256_uint1 x209; - fiat_p256_addcarryx_u32(&x208, &x209, x207, x180, x202); uint32_t x210; fiat_p256_uint1 x211; - fiat_p256_addcarryx_u32(&x210, &x211, x209, x182, x204); uint32_t x212; fiat_p256_uint1 x213; - fiat_p256_addcarryx_u32(&x212, &x213, x211, x184, (x205 + x197)); uint32_t x214; fiat_p256_uint1 x215; - fiat_p256_addcarryx_u32(&x214, &x215, x213, x186, 0x0); uint32_t x216; fiat_p256_uint1 x217; - fiat_p256_addcarryx_u32(&x216, &x217, x215, x188, 0x0); uint32_t x218; fiat_p256_uint1 x219; - fiat_p256_addcarryx_u32(&x218, &x219, x217, x190, x178); uint32_t x220; fiat_p256_uint1 x221; - fiat_p256_addcarryx_u32(&x220, &x221, x219, x192, x194); uint32_t x222; fiat_p256_uint1 x223; - fiat_p256_addcarryx_u32(&x222, &x223, x221, ((uint32_t)x193 + x177), x195); uint32_t x224; fiat_p256_uint1 x225; - fiat_p256_addcarryx_u32(&x224, &x225, 0x0, x208, (arg1[6])); uint32_t x226; fiat_p256_uint1 x227; - fiat_p256_addcarryx_u32(&x226, &x227, x225, x210, 0x0); uint32_t x228; fiat_p256_uint1 x229; - fiat_p256_addcarryx_u32(&x228, &x229, x227, x212, 0x0); uint32_t x230; fiat_p256_uint1 x231; - fiat_p256_addcarryx_u32(&x230, &x231, x229, x214, 0x0); uint32_t x232; fiat_p256_uint1 x233; - fiat_p256_addcarryx_u32(&x232, &x233, x231, x216, 0x0); uint32_t x234; fiat_p256_uint1 x235; - fiat_p256_addcarryx_u32(&x234, &x235, x233, x218, 0x0); uint32_t x236; fiat_p256_uint1 x237; - fiat_p256_addcarryx_u32(&x236, &x237, x235, x220, 0x0); uint32_t x238; fiat_p256_uint1 x239; - fiat_p256_addcarryx_u32(&x238, &x239, x237, x222, 0x0); uint32_t x240; uint32_t x241; - fiat_p256_mulx_u32(&x240, &x241, x224, UINT32_C(0xffffffff)); uint32_t x242; uint32_t x243; - fiat_p256_mulx_u32(&x242, &x243, x224, UINT32_C(0xffffffff)); uint32_t x244; uint32_t x245; - fiat_p256_mulx_u32(&x244, &x245, x224, UINT32_C(0xffffffff)); uint32_t x246; uint32_t x247; - fiat_p256_mulx_u32(&x246, &x247, x224, UINT32_C(0xffffffff)); uint32_t x248; fiat_p256_uint1 x249; - fiat_p256_addcarryx_u32(&x248, &x249, 0x0, x247, x244); uint32_t x250; fiat_p256_uint1 x251; - fiat_p256_addcarryx_u32(&x250, &x251, x249, x245, x242); uint32_t x252; fiat_p256_uint1 x253; - fiat_p256_addcarryx_u32(&x252, &x253, 0x0, x224, x246); uint32_t x254; fiat_p256_uint1 x255; - fiat_p256_addcarryx_u32(&x254, &x255, x253, x226, x248); uint32_t x256; fiat_p256_uint1 x257; - fiat_p256_addcarryx_u32(&x256, &x257, x255, x228, x250); uint32_t x258; fiat_p256_uint1 x259; - fiat_p256_addcarryx_u32(&x258, &x259, x257, x230, (x251 + x243)); uint32_t x260; fiat_p256_uint1 x261; - fiat_p256_addcarryx_u32(&x260, &x261, x259, x232, 0x0); uint32_t x262; fiat_p256_uint1 x263; - fiat_p256_addcarryx_u32(&x262, &x263, x261, x234, 0x0); uint32_t x264; fiat_p256_uint1 x265; - fiat_p256_addcarryx_u32(&x264, &x265, x263, x236, x224); uint32_t x266; fiat_p256_uint1 x267; - fiat_p256_addcarryx_u32(&x266, &x267, x265, x238, x240); uint32_t x268; fiat_p256_uint1 x269; - fiat_p256_addcarryx_u32(&x268, &x269, x267, ((uint32_t)x239 + x223), x241); uint32_t x270; fiat_p256_uint1 x271; - fiat_p256_addcarryx_u32(&x270, &x271, 0x0, x254, (arg1[7])); uint32_t x272; fiat_p256_uint1 x273; - fiat_p256_addcarryx_u32(&x272, &x273, x271, x256, 0x0); uint32_t x274; fiat_p256_uint1 x275; - fiat_p256_addcarryx_u32(&x274, &x275, x273, x258, 0x0); uint32_t x276; fiat_p256_uint1 x277; - fiat_p256_addcarryx_u32(&x276, &x277, x275, x260, 0x0); uint32_t x278; fiat_p256_uint1 x279; - fiat_p256_addcarryx_u32(&x278, &x279, x277, x262, 0x0); uint32_t x280; fiat_p256_uint1 x281; - fiat_p256_addcarryx_u32(&x280, &x281, x279, x264, 0x0); uint32_t x282; fiat_p256_uint1 x283; - fiat_p256_addcarryx_u32(&x282, &x283, x281, x266, 0x0); uint32_t x284; fiat_p256_uint1 x285; - fiat_p256_addcarryx_u32(&x284, &x285, x283, x268, 0x0); uint32_t x286; uint32_t x287; - fiat_p256_mulx_u32(&x286, &x287, x270, UINT32_C(0xffffffff)); uint32_t x288; uint32_t x289; - fiat_p256_mulx_u32(&x288, &x289, x270, UINT32_C(0xffffffff)); uint32_t x290; uint32_t x291; - fiat_p256_mulx_u32(&x290, &x291, x270, UINT32_C(0xffffffff)); uint32_t x292; uint32_t x293; - fiat_p256_mulx_u32(&x292, &x293, x270, UINT32_C(0xffffffff)); uint32_t x294; fiat_p256_uint1 x295; - fiat_p256_addcarryx_u32(&x294, &x295, 0x0, x293, x290); uint32_t x296; fiat_p256_uint1 x297; - fiat_p256_addcarryx_u32(&x296, &x297, x295, x291, x288); uint32_t x298; fiat_p256_uint1 x299; - fiat_p256_addcarryx_u32(&x298, &x299, 0x0, x270, x292); uint32_t x300; fiat_p256_uint1 x301; - fiat_p256_addcarryx_u32(&x300, &x301, x299, x272, x294); uint32_t x302; fiat_p256_uint1 x303; - fiat_p256_addcarryx_u32(&x302, &x303, x301, x274, x296); uint32_t x304; fiat_p256_uint1 x305; - fiat_p256_addcarryx_u32(&x304, &x305, x303, x276, (x297 + x289)); uint32_t x306; fiat_p256_uint1 x307; - fiat_p256_addcarryx_u32(&x306, &x307, x305, x278, 0x0); uint32_t x308; fiat_p256_uint1 x309; - fiat_p256_addcarryx_u32(&x308, &x309, x307, x280, 0x0); uint32_t x310; fiat_p256_uint1 x311; - fiat_p256_addcarryx_u32(&x310, &x311, x309, x282, x270); uint32_t x312; fiat_p256_uint1 x313; - fiat_p256_addcarryx_u32(&x312, &x313, x311, x284, x286); uint32_t x314; fiat_p256_uint1 x315; - fiat_p256_addcarryx_u32(&x314, &x315, x313, ((uint32_t)x285 + x269), x287); uint32_t x316; fiat_p256_uint1 x317; - fiat_p256_subborrowx_u32(&x316, &x317, 0x0, x300, UINT32_C(0xffffffff)); uint32_t x318; fiat_p256_uint1 x319; - fiat_p256_subborrowx_u32(&x318, &x319, x317, x302, UINT32_C(0xffffffff)); uint32_t x320; fiat_p256_uint1 x321; - fiat_p256_subborrowx_u32(&x320, &x321, x319, x304, UINT32_C(0xffffffff)); uint32_t x322; fiat_p256_uint1 x323; - fiat_p256_subborrowx_u32(&x322, &x323, x321, x306, 0x0); uint32_t x324; fiat_p256_uint1 x325; - fiat_p256_subborrowx_u32(&x324, &x325, x323, x308, 0x0); uint32_t x326; fiat_p256_uint1 x327; - fiat_p256_subborrowx_u32(&x326, &x327, x325, x310, 0x0); uint32_t x328; fiat_p256_uint1 x329; - fiat_p256_subborrowx_u32(&x328, &x329, x327, x312, 0x1); uint32_t x330; fiat_p256_uint1 x331; - fiat_p256_subborrowx_u32(&x330, &x331, x329, x314, UINT32_C(0xffffffff)); uint32_t x332; fiat_p256_uint1 x333; - fiat_p256_subborrowx_u32(&x332, &x333, x331, x315, 0x0); uint32_t x334; - fiat_p256_cmovznz_u32(&x334, x333, x316, x300); uint32_t x335; - fiat_p256_cmovznz_u32(&x335, x333, x318, x302); uint32_t x336; - fiat_p256_cmovznz_u32(&x336, x333, x320, x304); uint32_t x337; - fiat_p256_cmovznz_u32(&x337, x333, x322, x306); uint32_t x338; - fiat_p256_cmovznz_u32(&x338, x333, x324, x308); uint32_t x339; - fiat_p256_cmovznz_u32(&x339, x333, x326, x310); uint32_t x340; - fiat_p256_cmovznz_u32(&x340, x333, x328, x312); uint32_t x341; + x1 = (arg1[0]); + fiat_p256_mulx_u32(&x2, &x3, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x4, &x5, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x6, &x7, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x8, &x9, x1, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x10, &x11, 0x0, x9, x6); + fiat_p256_addcarryx_u32(&x12, &x13, x11, x7, x4); + fiat_p256_addcarryx_u32(&x14, &x15, 0x0, x1, x8); + fiat_p256_addcarryx_u32(&x16, &x17, x15, 0x0, x10); + fiat_p256_addcarryx_u32(&x18, &x19, x17, 0x0, x12); + fiat_p256_addcarryx_u32(&x20, &x21, x19, 0x0, (x13 + x5)); + fiat_p256_addcarryx_u32(&x22, &x23, 0x0, x16, (arg1[1])); + fiat_p256_addcarryx_u32(&x24, &x25, x23, x18, 0x0); + fiat_p256_addcarryx_u32(&x26, &x27, x25, x20, 0x0); + fiat_p256_mulx_u32(&x28, &x29, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x30, &x31, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x32, &x33, x22, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x34, &x35, x22, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x36, &x37, 0x0, x35, x32); + fiat_p256_addcarryx_u32(&x38, &x39, x37, x33, x30); + fiat_p256_addcarryx_u32(&x40, &x41, 0x0, x22, x34); + fiat_p256_addcarryx_u32(&x42, &x43, x41, x24, x36); + fiat_p256_addcarryx_u32(&x44, &x45, x43, x26, x38); + fiat_p256_addcarryx_u32(&x46, &x47, x45, ((uint32_t)x27 + x21), (x39 + x31)); + fiat_p256_addcarryx_u32(&x48, &x49, 0x0, x2, x22); + fiat_p256_addcarryx_u32(&x50, &x51, x49, x3, x28); + fiat_p256_addcarryx_u32(&x52, &x53, 0x0, x42, (arg1[2])); + fiat_p256_addcarryx_u32(&x54, &x55, x53, x44, 0x0); + fiat_p256_addcarryx_u32(&x56, &x57, x55, x46, 0x0); + fiat_p256_mulx_u32(&x58, &x59, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x60, &x61, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x62, &x63, x52, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x64, &x65, x52, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x66, &x67, 0x0, x65, x62); + fiat_p256_addcarryx_u32(&x68, &x69, x67, x63, x60); + fiat_p256_addcarryx_u32(&x70, &x71, 0x0, x52, x64); + fiat_p256_addcarryx_u32(&x72, &x73, x71, x54, x66); + fiat_p256_addcarryx_u32(&x74, &x75, x73, x56, x68); + fiat_p256_addcarryx_u32(&x76, &x77, x75, ((uint32_t)x57 + x47), (x69 + x61)); + fiat_p256_addcarryx_u32(&x78, &x79, x77, x1, 0x0); + fiat_p256_addcarryx_u32(&x80, &x81, x79, x48, 0x0); + fiat_p256_addcarryx_u32(&x82, &x83, x81, x50, x52); + fiat_p256_addcarryx_u32(&x84, &x85, x83, (x51 + x29), x58); + fiat_p256_addcarryx_u32(&x86, &x87, 0x0, x72, (arg1[3])); + fiat_p256_addcarryx_u32(&x88, &x89, x87, x74, 0x0); + fiat_p256_addcarryx_u32(&x90, &x91, x89, x76, 0x0); + fiat_p256_addcarryx_u32(&x92, &x93, x91, x78, 0x0); + fiat_p256_addcarryx_u32(&x94, &x95, x93, x80, 0x0); + fiat_p256_addcarryx_u32(&x96, &x97, x95, x82, 0x0); + fiat_p256_addcarryx_u32(&x98, &x99, x97, x84, 0x0); + fiat_p256_addcarryx_u32(&x100, &x101, x99, (x85 + x59), 0x0); + fiat_p256_mulx_u32(&x102, &x103, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x104, &x105, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x106, &x107, x86, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x108, &x109, x86, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x109, x106); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x107, x104); + fiat_p256_addcarryx_u32(&x114, &x115, 0x0, x86, x108); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x88, x110); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x90, x112); + fiat_p256_addcarryx_u32(&x120, &x121, x119, x92, (x113 + x105)); + fiat_p256_addcarryx_u32(&x122, &x123, x121, x94, 0x0); + fiat_p256_addcarryx_u32(&x124, &x125, x123, x96, 0x0); + fiat_p256_addcarryx_u32(&x126, &x127, x125, x98, x86); + fiat_p256_addcarryx_u32(&x128, &x129, x127, x100, x102); + fiat_p256_addcarryx_u32(&x130, &x131, x129, x101, x103); + fiat_p256_addcarryx_u32(&x132, &x133, 0x0, x116, (arg1[4])); + fiat_p256_addcarryx_u32(&x134, &x135, x133, x118, 0x0); + fiat_p256_addcarryx_u32(&x136, &x137, x135, x120, 0x0); + fiat_p256_addcarryx_u32(&x138, &x139, x137, x122, 0x0); + fiat_p256_addcarryx_u32(&x140, &x141, x139, x124, 0x0); + fiat_p256_addcarryx_u32(&x142, &x143, x141, x126, 0x0); + fiat_p256_addcarryx_u32(&x144, &x145, x143, x128, 0x0); + fiat_p256_addcarryx_u32(&x146, &x147, x145, x130, 0x0); + fiat_p256_mulx_u32(&x148, &x149, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x150, &x151, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x152, &x153, x132, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x154, &x155, x132, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x156, &x157, 0x0, x155, x152); + fiat_p256_addcarryx_u32(&x158, &x159, x157, x153, x150); + fiat_p256_addcarryx_u32(&x160, &x161, 0x0, x132, x154); + fiat_p256_addcarryx_u32(&x162, &x163, x161, x134, x156); + fiat_p256_addcarryx_u32(&x164, &x165, x163, x136, x158); + fiat_p256_addcarryx_u32(&x166, &x167, x165, x138, (x159 + x151)); + fiat_p256_addcarryx_u32(&x168, &x169, x167, x140, 0x0); + fiat_p256_addcarryx_u32(&x170, &x171, x169, x142, 0x0); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x144, x132); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x146, x148); + fiat_p256_addcarryx_u32(&x176, &x177, x175, ((uint32_t)x147 + x131), x149); + fiat_p256_addcarryx_u32(&x178, &x179, 0x0, x162, (arg1[5])); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x164, 0x0); + fiat_p256_addcarryx_u32(&x182, &x183, x181, x166, 0x0); + fiat_p256_addcarryx_u32(&x184, &x185, x183, x168, 0x0); + fiat_p256_addcarryx_u32(&x186, &x187, x185, x170, 0x0); + fiat_p256_addcarryx_u32(&x188, &x189, x187, x172, 0x0); + fiat_p256_addcarryx_u32(&x190, &x191, x189, x174, 0x0); + fiat_p256_addcarryx_u32(&x192, &x193, x191, x176, 0x0); + fiat_p256_mulx_u32(&x194, &x195, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x196, &x197, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x198, &x199, x178, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x200, &x201, x178, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x202, &x203, 0x0, x201, x198); + fiat_p256_addcarryx_u32(&x204, &x205, x203, x199, x196); + fiat_p256_addcarryx_u32(&x206, &x207, 0x0, x178, x200); + fiat_p256_addcarryx_u32(&x208, &x209, x207, x180, x202); + fiat_p256_addcarryx_u32(&x210, &x211, x209, x182, x204); + fiat_p256_addcarryx_u32(&x212, &x213, x211, x184, (x205 + x197)); + fiat_p256_addcarryx_u32(&x214, &x215, x213, x186, 0x0); + fiat_p256_addcarryx_u32(&x216, &x217, x215, x188, 0x0); + fiat_p256_addcarryx_u32(&x218, &x219, x217, x190, x178); + fiat_p256_addcarryx_u32(&x220, &x221, x219, x192, x194); + fiat_p256_addcarryx_u32(&x222, &x223, x221, ((uint32_t)x193 + x177), x195); + fiat_p256_addcarryx_u32(&x224, &x225, 0x0, x208, (arg1[6])); + fiat_p256_addcarryx_u32(&x226, &x227, x225, x210, 0x0); + fiat_p256_addcarryx_u32(&x228, &x229, x227, x212, 0x0); + fiat_p256_addcarryx_u32(&x230, &x231, x229, x214, 0x0); + fiat_p256_addcarryx_u32(&x232, &x233, x231, x216, 0x0); + fiat_p256_addcarryx_u32(&x234, &x235, x233, x218, 0x0); + fiat_p256_addcarryx_u32(&x236, &x237, x235, x220, 0x0); + fiat_p256_addcarryx_u32(&x238, &x239, x237, x222, 0x0); + fiat_p256_mulx_u32(&x240, &x241, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x242, &x243, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x244, &x245, x224, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x246, &x247, x224, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x248, &x249, 0x0, x247, x244); + fiat_p256_addcarryx_u32(&x250, &x251, x249, x245, x242); + fiat_p256_addcarryx_u32(&x252, &x253, 0x0, x224, x246); + fiat_p256_addcarryx_u32(&x254, &x255, x253, x226, x248); + fiat_p256_addcarryx_u32(&x256, &x257, x255, x228, x250); + fiat_p256_addcarryx_u32(&x258, &x259, x257, x230, (x251 + x243)); + fiat_p256_addcarryx_u32(&x260, &x261, x259, x232, 0x0); + fiat_p256_addcarryx_u32(&x262, &x263, x261, x234, 0x0); + fiat_p256_addcarryx_u32(&x264, &x265, x263, x236, x224); + fiat_p256_addcarryx_u32(&x266, &x267, x265, x238, x240); + fiat_p256_addcarryx_u32(&x268, &x269, x267, ((uint32_t)x239 + x223), x241); + fiat_p256_addcarryx_u32(&x270, &x271, 0x0, x254, (arg1[7])); + fiat_p256_addcarryx_u32(&x272, &x273, x271, x256, 0x0); + fiat_p256_addcarryx_u32(&x274, &x275, x273, x258, 0x0); + fiat_p256_addcarryx_u32(&x276, &x277, x275, x260, 0x0); + fiat_p256_addcarryx_u32(&x278, &x279, x277, x262, 0x0); + fiat_p256_addcarryx_u32(&x280, &x281, x279, x264, 0x0); + fiat_p256_addcarryx_u32(&x282, &x283, x281, x266, 0x0); + fiat_p256_addcarryx_u32(&x284, &x285, x283, x268, 0x0); + fiat_p256_mulx_u32(&x286, &x287, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x288, &x289, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x290, &x291, x270, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x292, &x293, x270, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x294, &x295, 0x0, x293, x290); + fiat_p256_addcarryx_u32(&x296, &x297, x295, x291, x288); + fiat_p256_addcarryx_u32(&x298, &x299, 0x0, x270, x292); + fiat_p256_addcarryx_u32(&x300, &x301, x299, x272, x294); + fiat_p256_addcarryx_u32(&x302, &x303, x301, x274, x296); + fiat_p256_addcarryx_u32(&x304, &x305, x303, x276, (x297 + x289)); + fiat_p256_addcarryx_u32(&x306, &x307, x305, x278, 0x0); + fiat_p256_addcarryx_u32(&x308, &x309, x307, x280, 0x0); + fiat_p256_addcarryx_u32(&x310, &x311, x309, x282, x270); + fiat_p256_addcarryx_u32(&x312, &x313, x311, x284, x286); + fiat_p256_addcarryx_u32(&x314, &x315, x313, ((uint32_t)x285 + x269), x287); + fiat_p256_subborrowx_u32(&x316, &x317, 0x0, x300, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x318, &x319, x317, x302, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x320, &x321, x319, x304, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x322, &x323, x321, x306, 0x0); + fiat_p256_subborrowx_u32(&x324, &x325, x323, x308, 0x0); + fiat_p256_subborrowx_u32(&x326, &x327, x325, x310, 0x0); + fiat_p256_subborrowx_u32(&x328, &x329, x327, x312, 0x1); + fiat_p256_subborrowx_u32(&x330, &x331, x329, x314, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x332, &x333, x331, x315, 0x0); + fiat_p256_cmovznz_u32(&x334, x333, x316, x300); + fiat_p256_cmovznz_u32(&x335, x333, x318, x302); + fiat_p256_cmovznz_u32(&x336, x333, x320, x304); + fiat_p256_cmovznz_u32(&x337, x333, x322, x306); + fiat_p256_cmovznz_u32(&x338, x333, x324, x308); + fiat_p256_cmovznz_u32(&x339, x333, x326, x310); + fiat_p256_cmovznz_u32(&x340, x333, x328, x312); fiat_p256_cmovznz_u32(&x341, x333, x330, x314); out1[0] = x334; out1[1] = x335; @@ -2908,8 +2988,905 @@ static void fiat_p256_from_montgomery(uint32_t out1[8], const uint32_t arg1[8]) out1[7] = x341; } +/* + * The function fiat_p256_to_montgomery translates a field element into the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = eval arg1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_montgomery(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_non_montgomery_domain_field_element arg1) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint32_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + fiat_p256_uint1 x24; + uint32_t x25; + fiat_p256_uint1 x26; + uint32_t x27; + fiat_p256_uint1 x28; + uint32_t x29; + fiat_p256_uint1 x30; + uint32_t x31; + fiat_p256_uint1 x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + fiat_p256_uint1 x42; + uint32_t x43; + fiat_p256_uint1 x44; + uint32_t x45; + fiat_p256_uint1 x46; + uint32_t x47; + fiat_p256_uint1 x48; + uint32_t x49; + fiat_p256_uint1 x50; + uint32_t x51; + fiat_p256_uint1 x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + uint32_t x64; + uint32_t x65; + uint32_t x66; + uint32_t x67; + uint32_t x68; + uint32_t x69; + uint32_t x70; + uint32_t x71; + uint32_t x72; + uint32_t x73; + uint32_t x74; + uint32_t x75; + uint32_t x76; + uint32_t x77; + fiat_p256_uint1 x78; + uint32_t x79; + fiat_p256_uint1 x80; + uint32_t x81; + fiat_p256_uint1 x82; + uint32_t x83; + fiat_p256_uint1 x84; + uint32_t x85; + fiat_p256_uint1 x86; + uint32_t x87; + fiat_p256_uint1 x88; + uint32_t x89; + fiat_p256_uint1 x90; + uint32_t x91; + fiat_p256_uint1 x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + fiat_p256_uint1 x102; + uint32_t x103; + uint32_t x104; + uint32_t x105; + uint32_t x106; + uint32_t x107; + uint32_t x108; + uint32_t x109; + uint32_t x110; + uint32_t x111; + fiat_p256_uint1 x112; + uint32_t x113; + fiat_p256_uint1 x114; + uint32_t x115; + fiat_p256_uint1 x116; + uint32_t x117; + fiat_p256_uint1 x118; + uint32_t x119; + fiat_p256_uint1 x120; + uint32_t x121; + fiat_p256_uint1 x122; + uint32_t x123; + fiat_p256_uint1 x124; + uint32_t x125; + fiat_p256_uint1 x126; + uint32_t x127; + fiat_p256_uint1 x128; + uint32_t x129; + fiat_p256_uint1 x130; + uint32_t x131; + fiat_p256_uint1 x132; + uint32_t x133; + uint32_t x134; + uint32_t x135; + uint32_t x136; + uint32_t x137; + uint32_t x138; + uint32_t x139; + uint32_t x140; + uint32_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + uint32_t x145; + uint32_t x146; + uint32_t x147; + fiat_p256_uint1 x148; + uint32_t x149; + fiat_p256_uint1 x150; + uint32_t x151; + fiat_p256_uint1 x152; + uint32_t x153; + fiat_p256_uint1 x154; + uint32_t x155; + fiat_p256_uint1 x156; + uint32_t x157; + fiat_p256_uint1 x158; + uint32_t x159; + fiat_p256_uint1 x160; + uint32_t x161; + fiat_p256_uint1 x162; + uint32_t x163; + fiat_p256_uint1 x164; + uint32_t x165; + fiat_p256_uint1 x166; + uint32_t x167; + fiat_p256_uint1 x168; + uint32_t x169; + fiat_p256_uint1 x170; + uint32_t x171; + fiat_p256_uint1 x172; + uint32_t x173; + uint32_t x174; + uint32_t x175; + uint32_t x176; + uint32_t x177; + uint32_t x178; + uint32_t x179; + uint32_t x180; + uint32_t x181; + fiat_p256_uint1 x182; + uint32_t x183; + fiat_p256_uint1 x184; + uint32_t x185; + fiat_p256_uint1 x186; + uint32_t x187; + fiat_p256_uint1 x188; + uint32_t x189; + fiat_p256_uint1 x190; + uint32_t x191; + fiat_p256_uint1 x192; + uint32_t x193; + fiat_p256_uint1 x194; + uint32_t x195; + fiat_p256_uint1 x196; + uint32_t x197; + fiat_p256_uint1 x198; + uint32_t x199; + fiat_p256_uint1 x200; + uint32_t x201; + fiat_p256_uint1 x202; + uint32_t x203; + uint32_t x204; + uint32_t x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + uint32_t x210; + uint32_t x211; + uint32_t x212; + uint32_t x213; + uint32_t x214; + uint32_t x215; + uint32_t x216; + uint32_t x217; + fiat_p256_uint1 x218; + uint32_t x219; + fiat_p256_uint1 x220; + uint32_t x221; + fiat_p256_uint1 x222; + uint32_t x223; + fiat_p256_uint1 x224; + uint32_t x225; + fiat_p256_uint1 x226; + uint32_t x227; + fiat_p256_uint1 x228; + uint32_t x229; + fiat_p256_uint1 x230; + uint32_t x231; + fiat_p256_uint1 x232; + uint32_t x233; + fiat_p256_uint1 x234; + uint32_t x235; + fiat_p256_uint1 x236; + uint32_t x237; + fiat_p256_uint1 x238; + uint32_t x239; + fiat_p256_uint1 x240; + uint32_t x241; + fiat_p256_uint1 x242; + uint32_t x243; + uint32_t x244; + uint32_t x245; + uint32_t x246; + uint32_t x247; + uint32_t x248; + uint32_t x249; + uint32_t x250; + uint32_t x251; + fiat_p256_uint1 x252; + uint32_t x253; + fiat_p256_uint1 x254; + uint32_t x255; + fiat_p256_uint1 x256; + uint32_t x257; + fiat_p256_uint1 x258; + uint32_t x259; + fiat_p256_uint1 x260; + uint32_t x261; + fiat_p256_uint1 x262; + uint32_t x263; + fiat_p256_uint1 x264; + uint32_t x265; + fiat_p256_uint1 x266; + uint32_t x267; + fiat_p256_uint1 x268; + uint32_t x269; + fiat_p256_uint1 x270; + uint32_t x271; + fiat_p256_uint1 x272; + uint32_t x273; + uint32_t x274; + uint32_t x275; + uint32_t x276; + uint32_t x277; + uint32_t x278; + uint32_t x279; + uint32_t x280; + uint32_t x281; + uint32_t x282; + uint32_t x283; + uint32_t x284; + uint32_t x285; + uint32_t x286; + uint32_t x287; + fiat_p256_uint1 x288; + uint32_t x289; + fiat_p256_uint1 x290; + uint32_t x291; + fiat_p256_uint1 x292; + uint32_t x293; + fiat_p256_uint1 x294; + uint32_t x295; + fiat_p256_uint1 x296; + uint32_t x297; + fiat_p256_uint1 x298; + uint32_t x299; + fiat_p256_uint1 x300; + uint32_t x301; + fiat_p256_uint1 x302; + uint32_t x303; + fiat_p256_uint1 x304; + uint32_t x305; + fiat_p256_uint1 x306; + uint32_t x307; + fiat_p256_uint1 x308; + uint32_t x309; + fiat_p256_uint1 x310; + uint32_t x311; + fiat_p256_uint1 x312; + uint32_t x313; + uint32_t x314; + uint32_t x315; + uint32_t x316; + uint32_t x317; + uint32_t x318; + uint32_t x319; + uint32_t x320; + uint32_t x321; + fiat_p256_uint1 x322; + uint32_t x323; + fiat_p256_uint1 x324; + uint32_t x325; + fiat_p256_uint1 x326; + uint32_t x327; + fiat_p256_uint1 x328; + uint32_t x329; + fiat_p256_uint1 x330; + uint32_t x331; + fiat_p256_uint1 x332; + uint32_t x333; + fiat_p256_uint1 x334; + uint32_t x335; + fiat_p256_uint1 x336; + uint32_t x337; + fiat_p256_uint1 x338; + uint32_t x339; + fiat_p256_uint1 x340; + uint32_t x341; + fiat_p256_uint1 x342; + uint32_t x343; + uint32_t x344; + uint32_t x345; + uint32_t x346; + uint32_t x347; + uint32_t x348; + uint32_t x349; + uint32_t x350; + uint32_t x351; + uint32_t x352; + uint32_t x353; + uint32_t x354; + uint32_t x355; + uint32_t x356; + uint32_t x357; + fiat_p256_uint1 x358; + uint32_t x359; + fiat_p256_uint1 x360; + uint32_t x361; + fiat_p256_uint1 x362; + uint32_t x363; + fiat_p256_uint1 x364; + uint32_t x365; + fiat_p256_uint1 x366; + uint32_t x367; + fiat_p256_uint1 x368; + uint32_t x369; + fiat_p256_uint1 x370; + uint32_t x371; + fiat_p256_uint1 x372; + uint32_t x373; + fiat_p256_uint1 x374; + uint32_t x375; + fiat_p256_uint1 x376; + uint32_t x377; + fiat_p256_uint1 x378; + uint32_t x379; + fiat_p256_uint1 x380; + uint32_t x381; + fiat_p256_uint1 x382; + uint32_t x383; + uint32_t x384; + uint32_t x385; + uint32_t x386; + uint32_t x387; + uint32_t x388; + uint32_t x389; + uint32_t x390; + uint32_t x391; + fiat_p256_uint1 x392; + uint32_t x393; + fiat_p256_uint1 x394; + uint32_t x395; + fiat_p256_uint1 x396; + uint32_t x397; + fiat_p256_uint1 x398; + uint32_t x399; + fiat_p256_uint1 x400; + uint32_t x401; + fiat_p256_uint1 x402; + uint32_t x403; + fiat_p256_uint1 x404; + uint32_t x405; + fiat_p256_uint1 x406; + uint32_t x407; + fiat_p256_uint1 x408; + uint32_t x409; + fiat_p256_uint1 x410; + uint32_t x411; + fiat_p256_uint1 x412; + uint32_t x413; + uint32_t x414; + uint32_t x415; + uint32_t x416; + uint32_t x417; + uint32_t x418; + uint32_t x419; + uint32_t x420; + uint32_t x421; + uint32_t x422; + uint32_t x423; + uint32_t x424; + uint32_t x425; + uint32_t x426; + uint32_t x427; + fiat_p256_uint1 x428; + uint32_t x429; + fiat_p256_uint1 x430; + uint32_t x431; + fiat_p256_uint1 x432; + uint32_t x433; + fiat_p256_uint1 x434; + uint32_t x435; + fiat_p256_uint1 x436; + uint32_t x437; + fiat_p256_uint1 x438; + uint32_t x439; + fiat_p256_uint1 x440; + uint32_t x441; + fiat_p256_uint1 x442; + uint32_t x443; + fiat_p256_uint1 x444; + uint32_t x445; + fiat_p256_uint1 x446; + uint32_t x447; + fiat_p256_uint1 x448; + uint32_t x449; + fiat_p256_uint1 x450; + uint32_t x451; + fiat_p256_uint1 x452; + uint32_t x453; + uint32_t x454; + uint32_t x455; + uint32_t x456; + uint32_t x457; + uint32_t x458; + uint32_t x459; + uint32_t x460; + uint32_t x461; + fiat_p256_uint1 x462; + uint32_t x463; + fiat_p256_uint1 x464; + uint32_t x465; + fiat_p256_uint1 x466; + uint32_t x467; + fiat_p256_uint1 x468; + uint32_t x469; + fiat_p256_uint1 x470; + uint32_t x471; + fiat_p256_uint1 x472; + uint32_t x473; + fiat_p256_uint1 x474; + uint32_t x475; + fiat_p256_uint1 x476; + uint32_t x477; + fiat_p256_uint1 x478; + uint32_t x479; + fiat_p256_uint1 x480; + uint32_t x481; + fiat_p256_uint1 x482; + uint32_t x483; + uint32_t x484; + uint32_t x485; + uint32_t x486; + uint32_t x487; + uint32_t x488; + uint32_t x489; + uint32_t x490; + uint32_t x491; + uint32_t x492; + uint32_t x493; + uint32_t x494; + uint32_t x495; + uint32_t x496; + uint32_t x497; + fiat_p256_uint1 x498; + uint32_t x499; + fiat_p256_uint1 x500; + uint32_t x501; + fiat_p256_uint1 x502; + uint32_t x503; + fiat_p256_uint1 x504; + uint32_t x505; + fiat_p256_uint1 x506; + uint32_t x507; + fiat_p256_uint1 x508; + uint32_t x509; + fiat_p256_uint1 x510; + uint32_t x511; + fiat_p256_uint1 x512; + uint32_t x513; + fiat_p256_uint1 x514; + uint32_t x515; + fiat_p256_uint1 x516; + uint32_t x517; + fiat_p256_uint1 x518; + uint32_t x519; + fiat_p256_uint1 x520; + uint32_t x521; + fiat_p256_uint1 x522; + uint32_t x523; + uint32_t x524; + uint32_t x525; + uint32_t x526; + uint32_t x527; + uint32_t x528; + uint32_t x529; + uint32_t x530; + uint32_t x531; + fiat_p256_uint1 x532; + uint32_t x533; + fiat_p256_uint1 x534; + uint32_t x535; + fiat_p256_uint1 x536; + uint32_t x537; + fiat_p256_uint1 x538; + uint32_t x539; + fiat_p256_uint1 x540; + uint32_t x541; + fiat_p256_uint1 x542; + uint32_t x543; + fiat_p256_uint1 x544; + uint32_t x545; + fiat_p256_uint1 x546; + uint32_t x547; + fiat_p256_uint1 x548; + uint32_t x549; + fiat_p256_uint1 x550; + uint32_t x551; + fiat_p256_uint1 x552; + uint32_t x553; + fiat_p256_uint1 x554; + uint32_t x555; + fiat_p256_uint1 x556; + uint32_t x557; + fiat_p256_uint1 x558; + uint32_t x559; + fiat_p256_uint1 x560; + uint32_t x561; + fiat_p256_uint1 x562; + uint32_t x563; + fiat_p256_uint1 x564; + uint32_t x565; + fiat_p256_uint1 x566; + uint32_t x567; + fiat_p256_uint1 x568; + uint32_t x569; + fiat_p256_uint1 x570; + uint32_t x571; + uint32_t x572; + uint32_t x573; + uint32_t x574; + uint32_t x575; + uint32_t x576; + uint32_t x577; + uint32_t x578; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[4]); + x5 = (arg1[5]); + x6 = (arg1[6]); + x7 = (arg1[7]); + x8 = (arg1[0]); + fiat_p256_mulx_u32(&x9, &x10, x8, 0x4); + fiat_p256_mulx_u32(&x11, &x12, x8, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x13, &x14, x8, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x15, &x16, x8, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x17, &x18, x8, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x19, &x20, x8, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x21, &x22, x8, 0x3); + fiat_p256_addcarryx_u32(&x23, &x24, 0x0, x20, x17); + fiat_p256_addcarryx_u32(&x25, &x26, x24, x18, x15); + fiat_p256_addcarryx_u32(&x27, &x28, x26, x16, x13); + fiat_p256_addcarryx_u32(&x29, &x30, x28, x14, x11); + fiat_p256_addcarryx_u32(&x31, &x32, x30, x12, x9); + fiat_p256_mulx_u32(&x33, &x34, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x35, &x36, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x37, &x38, x21, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x39, &x40, x21, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x41, &x42, 0x0, x40, x37); + fiat_p256_addcarryx_u32(&x43, &x44, x42, x38, x35); + fiat_p256_addcarryx_u32(&x45, &x46, 0x0, x21, x39); + fiat_p256_addcarryx_u32(&x47, &x48, x46, x22, x41); + fiat_p256_addcarryx_u32(&x49, &x50, x48, x19, x43); + fiat_p256_addcarryx_u32(&x51, &x52, x50, x23, (x44 + x36)); + fiat_p256_addcarryx_u32(&x53, &x54, x52, x25, 0x0); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x27, 0x0); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x29, x21); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x31, x33); + fiat_p256_addcarryx_u32(&x61, &x62, x60, (x32 + x10), x34); + fiat_p256_mulx_u32(&x63, &x64, x1, 0x4); + fiat_p256_mulx_u32(&x65, &x66, x1, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x67, &x68, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x69, &x70, x1, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x71, &x72, x1, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x73, &x74, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x75, &x76, x1, 0x3); + fiat_p256_addcarryx_u32(&x77, &x78, 0x0, x74, x71); + fiat_p256_addcarryx_u32(&x79, &x80, x78, x72, x69); + fiat_p256_addcarryx_u32(&x81, &x82, x80, x70, x67); + fiat_p256_addcarryx_u32(&x83, &x84, x82, x68, x65); + fiat_p256_addcarryx_u32(&x85, &x86, x84, x66, x63); + fiat_p256_addcarryx_u32(&x87, &x88, 0x0, x47, x75); + fiat_p256_addcarryx_u32(&x89, &x90, x88, x49, x76); + fiat_p256_addcarryx_u32(&x91, &x92, x90, x51, x73); + fiat_p256_addcarryx_u32(&x93, &x94, x92, x53, x77); + fiat_p256_addcarryx_u32(&x95, &x96, x94, x55, x79); + fiat_p256_addcarryx_u32(&x97, &x98, x96, x57, x81); + fiat_p256_addcarryx_u32(&x99, &x100, x98, x59, x83); + fiat_p256_addcarryx_u32(&x101, &x102, x100, x61, x85); + fiat_p256_mulx_u32(&x103, &x104, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x105, &x106, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x107, &x108, x87, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x109, &x110, x87, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x111, &x112, 0x0, x110, x107); + fiat_p256_addcarryx_u32(&x113, &x114, x112, x108, x105); + fiat_p256_addcarryx_u32(&x115, &x116, 0x0, x87, x109); + fiat_p256_addcarryx_u32(&x117, &x118, x116, x89, x111); + fiat_p256_addcarryx_u32(&x119, &x120, x118, x91, x113); + fiat_p256_addcarryx_u32(&x121, &x122, x120, x93, (x114 + x106)); + fiat_p256_addcarryx_u32(&x123, &x124, x122, x95, 0x0); + fiat_p256_addcarryx_u32(&x125, &x126, x124, x97, 0x0); + fiat_p256_addcarryx_u32(&x127, &x128, x126, x99, x87); + fiat_p256_addcarryx_u32(&x129, &x130, x128, x101, x103); + fiat_p256_addcarryx_u32(&x131, &x132, x130, (((uint32_t)x102 + x62) + (x86 + x64)), x104); + fiat_p256_mulx_u32(&x133, &x134, x2, 0x4); + fiat_p256_mulx_u32(&x135, &x136, x2, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x137, &x138, x2, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x139, &x140, x2, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x141, &x142, x2, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x143, &x144, x2, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x145, &x146, x2, 0x3); + fiat_p256_addcarryx_u32(&x147, &x148, 0x0, x144, x141); + fiat_p256_addcarryx_u32(&x149, &x150, x148, x142, x139); + fiat_p256_addcarryx_u32(&x151, &x152, x150, x140, x137); + fiat_p256_addcarryx_u32(&x153, &x154, x152, x138, x135); + fiat_p256_addcarryx_u32(&x155, &x156, x154, x136, x133); + fiat_p256_addcarryx_u32(&x157, &x158, 0x0, x117, x145); + fiat_p256_addcarryx_u32(&x159, &x160, x158, x119, x146); + fiat_p256_addcarryx_u32(&x161, &x162, x160, x121, x143); + fiat_p256_addcarryx_u32(&x163, &x164, x162, x123, x147); + fiat_p256_addcarryx_u32(&x165, &x166, x164, x125, x149); + fiat_p256_addcarryx_u32(&x167, &x168, x166, x127, x151); + fiat_p256_addcarryx_u32(&x169, &x170, x168, x129, x153); + fiat_p256_addcarryx_u32(&x171, &x172, x170, x131, x155); + fiat_p256_mulx_u32(&x173, &x174, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x175, &x176, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x177, &x178, x157, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x179, &x180, x157, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x181, &x182, 0x0, x180, x177); + fiat_p256_addcarryx_u32(&x183, &x184, x182, x178, x175); + fiat_p256_addcarryx_u32(&x185, &x186, 0x0, x157, x179); + fiat_p256_addcarryx_u32(&x187, &x188, x186, x159, x181); + fiat_p256_addcarryx_u32(&x189, &x190, x188, x161, x183); + fiat_p256_addcarryx_u32(&x191, &x192, x190, x163, (x184 + x176)); + fiat_p256_addcarryx_u32(&x193, &x194, x192, x165, 0x0); + fiat_p256_addcarryx_u32(&x195, &x196, x194, x167, 0x0); + fiat_p256_addcarryx_u32(&x197, &x198, x196, x169, x157); + fiat_p256_addcarryx_u32(&x199, &x200, x198, x171, x173); + fiat_p256_addcarryx_u32(&x201, &x202, x200, (((uint32_t)x172 + x132) + (x156 + x134)), x174); + fiat_p256_mulx_u32(&x203, &x204, x3, 0x4); + fiat_p256_mulx_u32(&x205, &x206, x3, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x207, &x208, x3, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x209, &x210, x3, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x211, &x212, x3, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x213, &x214, x3, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x215, &x216, x3, 0x3); + fiat_p256_addcarryx_u32(&x217, &x218, 0x0, x214, x211); + fiat_p256_addcarryx_u32(&x219, &x220, x218, x212, x209); + fiat_p256_addcarryx_u32(&x221, &x222, x220, x210, x207); + fiat_p256_addcarryx_u32(&x223, &x224, x222, x208, x205); + fiat_p256_addcarryx_u32(&x225, &x226, x224, x206, x203); + fiat_p256_addcarryx_u32(&x227, &x228, 0x0, x187, x215); + fiat_p256_addcarryx_u32(&x229, &x230, x228, x189, x216); + fiat_p256_addcarryx_u32(&x231, &x232, x230, x191, x213); + fiat_p256_addcarryx_u32(&x233, &x234, x232, x193, x217); + fiat_p256_addcarryx_u32(&x235, &x236, x234, x195, x219); + fiat_p256_addcarryx_u32(&x237, &x238, x236, x197, x221); + fiat_p256_addcarryx_u32(&x239, &x240, x238, x199, x223); + fiat_p256_addcarryx_u32(&x241, &x242, x240, x201, x225); + fiat_p256_mulx_u32(&x243, &x244, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x245, &x246, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x247, &x248, x227, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x249, &x250, x227, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x251, &x252, 0x0, x250, x247); + fiat_p256_addcarryx_u32(&x253, &x254, x252, x248, x245); + fiat_p256_addcarryx_u32(&x255, &x256, 0x0, x227, x249); + fiat_p256_addcarryx_u32(&x257, &x258, x256, x229, x251); + fiat_p256_addcarryx_u32(&x259, &x260, x258, x231, x253); + fiat_p256_addcarryx_u32(&x261, &x262, x260, x233, (x254 + x246)); + fiat_p256_addcarryx_u32(&x263, &x264, x262, x235, 0x0); + fiat_p256_addcarryx_u32(&x265, &x266, x264, x237, 0x0); + fiat_p256_addcarryx_u32(&x267, &x268, x266, x239, x227); + fiat_p256_addcarryx_u32(&x269, &x270, x268, x241, x243); + fiat_p256_addcarryx_u32(&x271, &x272, x270, (((uint32_t)x242 + x202) + (x226 + x204)), x244); + fiat_p256_mulx_u32(&x273, &x274, x4, 0x4); + fiat_p256_mulx_u32(&x275, &x276, x4, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x277, &x278, x4, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x279, &x280, x4, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x281, &x282, x4, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x283, &x284, x4, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x285, &x286, x4, 0x3); + fiat_p256_addcarryx_u32(&x287, &x288, 0x0, x284, x281); + fiat_p256_addcarryx_u32(&x289, &x290, x288, x282, x279); + fiat_p256_addcarryx_u32(&x291, &x292, x290, x280, x277); + fiat_p256_addcarryx_u32(&x293, &x294, x292, x278, x275); + fiat_p256_addcarryx_u32(&x295, &x296, x294, x276, x273); + fiat_p256_addcarryx_u32(&x297, &x298, 0x0, x257, x285); + fiat_p256_addcarryx_u32(&x299, &x300, x298, x259, x286); + fiat_p256_addcarryx_u32(&x301, &x302, x300, x261, x283); + fiat_p256_addcarryx_u32(&x303, &x304, x302, x263, x287); + fiat_p256_addcarryx_u32(&x305, &x306, x304, x265, x289); + fiat_p256_addcarryx_u32(&x307, &x308, x306, x267, x291); + fiat_p256_addcarryx_u32(&x309, &x310, x308, x269, x293); + fiat_p256_addcarryx_u32(&x311, &x312, x310, x271, x295); + fiat_p256_mulx_u32(&x313, &x314, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x315, &x316, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x317, &x318, x297, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x319, &x320, x297, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x321, &x322, 0x0, x320, x317); + fiat_p256_addcarryx_u32(&x323, &x324, x322, x318, x315); + fiat_p256_addcarryx_u32(&x325, &x326, 0x0, x297, x319); + fiat_p256_addcarryx_u32(&x327, &x328, x326, x299, x321); + fiat_p256_addcarryx_u32(&x329, &x330, x328, x301, x323); + fiat_p256_addcarryx_u32(&x331, &x332, x330, x303, (x324 + x316)); + fiat_p256_addcarryx_u32(&x333, &x334, x332, x305, 0x0); + fiat_p256_addcarryx_u32(&x335, &x336, x334, x307, 0x0); + fiat_p256_addcarryx_u32(&x337, &x338, x336, x309, x297); + fiat_p256_addcarryx_u32(&x339, &x340, x338, x311, x313); + fiat_p256_addcarryx_u32(&x341, &x342, x340, (((uint32_t)x312 + x272) + (x296 + x274)), x314); + fiat_p256_mulx_u32(&x343, &x344, x5, 0x4); + fiat_p256_mulx_u32(&x345, &x346, x5, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x347, &x348, x5, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x349, &x350, x5, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x351, &x352, x5, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x353, &x354, x5, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x355, &x356, x5, 0x3); + fiat_p256_addcarryx_u32(&x357, &x358, 0x0, x354, x351); + fiat_p256_addcarryx_u32(&x359, &x360, x358, x352, x349); + fiat_p256_addcarryx_u32(&x361, &x362, x360, x350, x347); + fiat_p256_addcarryx_u32(&x363, &x364, x362, x348, x345); + fiat_p256_addcarryx_u32(&x365, &x366, x364, x346, x343); + fiat_p256_addcarryx_u32(&x367, &x368, 0x0, x327, x355); + fiat_p256_addcarryx_u32(&x369, &x370, x368, x329, x356); + fiat_p256_addcarryx_u32(&x371, &x372, x370, x331, x353); + fiat_p256_addcarryx_u32(&x373, &x374, x372, x333, x357); + fiat_p256_addcarryx_u32(&x375, &x376, x374, x335, x359); + fiat_p256_addcarryx_u32(&x377, &x378, x376, x337, x361); + fiat_p256_addcarryx_u32(&x379, &x380, x378, x339, x363); + fiat_p256_addcarryx_u32(&x381, &x382, x380, x341, x365); + fiat_p256_mulx_u32(&x383, &x384, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x385, &x386, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x387, &x388, x367, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x389, &x390, x367, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x391, &x392, 0x0, x390, x387); + fiat_p256_addcarryx_u32(&x393, &x394, x392, x388, x385); + fiat_p256_addcarryx_u32(&x395, &x396, 0x0, x367, x389); + fiat_p256_addcarryx_u32(&x397, &x398, x396, x369, x391); + fiat_p256_addcarryx_u32(&x399, &x400, x398, x371, x393); + fiat_p256_addcarryx_u32(&x401, &x402, x400, x373, (x394 + x386)); + fiat_p256_addcarryx_u32(&x403, &x404, x402, x375, 0x0); + fiat_p256_addcarryx_u32(&x405, &x406, x404, x377, 0x0); + fiat_p256_addcarryx_u32(&x407, &x408, x406, x379, x367); + fiat_p256_addcarryx_u32(&x409, &x410, x408, x381, x383); + fiat_p256_addcarryx_u32(&x411, &x412, x410, (((uint32_t)x382 + x342) + (x366 + x344)), x384); + fiat_p256_mulx_u32(&x413, &x414, x6, 0x4); + fiat_p256_mulx_u32(&x415, &x416, x6, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x417, &x418, x6, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x419, &x420, x6, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x421, &x422, x6, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x423, &x424, x6, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x425, &x426, x6, 0x3); + fiat_p256_addcarryx_u32(&x427, &x428, 0x0, x424, x421); + fiat_p256_addcarryx_u32(&x429, &x430, x428, x422, x419); + fiat_p256_addcarryx_u32(&x431, &x432, x430, x420, x417); + fiat_p256_addcarryx_u32(&x433, &x434, x432, x418, x415); + fiat_p256_addcarryx_u32(&x435, &x436, x434, x416, x413); + fiat_p256_addcarryx_u32(&x437, &x438, 0x0, x397, x425); + fiat_p256_addcarryx_u32(&x439, &x440, x438, x399, x426); + fiat_p256_addcarryx_u32(&x441, &x442, x440, x401, x423); + fiat_p256_addcarryx_u32(&x443, &x444, x442, x403, x427); + fiat_p256_addcarryx_u32(&x445, &x446, x444, x405, x429); + fiat_p256_addcarryx_u32(&x447, &x448, x446, x407, x431); + fiat_p256_addcarryx_u32(&x449, &x450, x448, x409, x433); + fiat_p256_addcarryx_u32(&x451, &x452, x450, x411, x435); + fiat_p256_mulx_u32(&x453, &x454, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x455, &x456, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x457, &x458, x437, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x459, &x460, x437, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x461, &x462, 0x0, x460, x457); + fiat_p256_addcarryx_u32(&x463, &x464, x462, x458, x455); + fiat_p256_addcarryx_u32(&x465, &x466, 0x0, x437, x459); + fiat_p256_addcarryx_u32(&x467, &x468, x466, x439, x461); + fiat_p256_addcarryx_u32(&x469, &x470, x468, x441, x463); + fiat_p256_addcarryx_u32(&x471, &x472, x470, x443, (x464 + x456)); + fiat_p256_addcarryx_u32(&x473, &x474, x472, x445, 0x0); + fiat_p256_addcarryx_u32(&x475, &x476, x474, x447, 0x0); + fiat_p256_addcarryx_u32(&x477, &x478, x476, x449, x437); + fiat_p256_addcarryx_u32(&x479, &x480, x478, x451, x453); + fiat_p256_addcarryx_u32(&x481, &x482, x480, (((uint32_t)x452 + x412) + (x436 + x414)), x454); + fiat_p256_mulx_u32(&x483, &x484, x7, 0x4); + fiat_p256_mulx_u32(&x485, &x486, x7, UINT32_C(0xfffffffd)); + fiat_p256_mulx_u32(&x487, &x488, x7, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x489, &x490, x7, UINT32_C(0xfffffffe)); + fiat_p256_mulx_u32(&x491, &x492, x7, UINT32_C(0xfffffffb)); + fiat_p256_mulx_u32(&x493, &x494, x7, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x495, &x496, x7, 0x3); + fiat_p256_addcarryx_u32(&x497, &x498, 0x0, x494, x491); + fiat_p256_addcarryx_u32(&x499, &x500, x498, x492, x489); + fiat_p256_addcarryx_u32(&x501, &x502, x500, x490, x487); + fiat_p256_addcarryx_u32(&x503, &x504, x502, x488, x485); + fiat_p256_addcarryx_u32(&x505, &x506, x504, x486, x483); + fiat_p256_addcarryx_u32(&x507, &x508, 0x0, x467, x495); + fiat_p256_addcarryx_u32(&x509, &x510, x508, x469, x496); + fiat_p256_addcarryx_u32(&x511, &x512, x510, x471, x493); + fiat_p256_addcarryx_u32(&x513, &x514, x512, x473, x497); + fiat_p256_addcarryx_u32(&x515, &x516, x514, x475, x499); + fiat_p256_addcarryx_u32(&x517, &x518, x516, x477, x501); + fiat_p256_addcarryx_u32(&x519, &x520, x518, x479, x503); + fiat_p256_addcarryx_u32(&x521, &x522, x520, x481, x505); + fiat_p256_mulx_u32(&x523, &x524, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x525, &x526, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x527, &x528, x507, UINT32_C(0xffffffff)); + fiat_p256_mulx_u32(&x529, &x530, x507, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x531, &x532, 0x0, x530, x527); + fiat_p256_addcarryx_u32(&x533, &x534, x532, x528, x525); + fiat_p256_addcarryx_u32(&x535, &x536, 0x0, x507, x529); + fiat_p256_addcarryx_u32(&x537, &x538, x536, x509, x531); + fiat_p256_addcarryx_u32(&x539, &x540, x538, x511, x533); + fiat_p256_addcarryx_u32(&x541, &x542, x540, x513, (x534 + x526)); + fiat_p256_addcarryx_u32(&x543, &x544, x542, x515, 0x0); + fiat_p256_addcarryx_u32(&x545, &x546, x544, x517, 0x0); + fiat_p256_addcarryx_u32(&x547, &x548, x546, x519, x507); + fiat_p256_addcarryx_u32(&x549, &x550, x548, x521, x523); + fiat_p256_addcarryx_u32(&x551, &x552, x550, (((uint32_t)x522 + x482) + (x506 + x484)), x524); + fiat_p256_subborrowx_u32(&x553, &x554, 0x0, x537, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x555, &x556, x554, x539, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x557, &x558, x556, x541, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x559, &x560, x558, x543, 0x0); + fiat_p256_subborrowx_u32(&x561, &x562, x560, x545, 0x0); + fiat_p256_subborrowx_u32(&x563, &x564, x562, x547, 0x0); + fiat_p256_subborrowx_u32(&x565, &x566, x564, x549, 0x1); + fiat_p256_subborrowx_u32(&x567, &x568, x566, x551, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x569, &x570, x568, x552, 0x0); + fiat_p256_cmovznz_u32(&x571, x570, x553, x537); + fiat_p256_cmovznz_u32(&x572, x570, x555, x539); + fiat_p256_cmovznz_u32(&x573, x570, x557, x541); + fiat_p256_cmovznz_u32(&x574, x570, x559, x543); + fiat_p256_cmovznz_u32(&x575, x570, x561, x545); + fiat_p256_cmovznz_u32(&x576, x570, x563, x547); + fiat_p256_cmovznz_u32(&x577, x570, x565, x549); + fiat_p256_cmovznz_u32(&x578, x570, x567, x551); + out1[0] = x571; + out1[1] = x572; + out1[2] = x573; + out1[3] = x574; + out1[4] = x575; + out1[5] = x576; + out1[6] = x577; + out1[7] = x578; +} + /* * The function fiat_p256_nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: @@ -2920,13 +3897,15 @@ static void fiat_p256_from_montgomery(uint32_t out1[8], const uint32_t arg1[8]) * Output Bounds: * out1: [0x0 ~> 0xffffffff] */ -static void fiat_p256_nonzero(uint32_t* out1, const uint32_t arg1[8]) { - uint32_t x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | ((arg1[5]) | ((arg1[6]) | ((arg1[7]) | (uint32_t)0x0)))))))); +static FIAT_P256_FIAT_INLINE void fiat_p256_nonzero(uint32_t* out1, const uint32_t arg1[8]) { + uint32_t x1; + x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | ((arg1[5]) | ((arg1[6]) | (arg1[7])))))))); *out1 = x1; } /* * The function fiat_p256_selectznz is a multi-limb conditional select. + * * Postconditions: * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) * @@ -2937,22 +3916,22 @@ static void fiat_p256_nonzero(uint32_t* out1, const uint32_t arg1[8]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const uint32_t arg2[8], const uint32_t arg3[8]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const uint32_t arg2[8], const uint32_t arg3[8]) { uint32_t x1; - fiat_p256_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); uint32_t x2; - fiat_p256_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); uint32_t x3; - fiat_p256_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); uint32_t x4; - fiat_p256_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); uint32_t x5; - fiat_p256_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); uint32_t x6; - fiat_p256_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); uint32_t x7; - fiat_p256_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); uint32_t x8; + fiat_p256_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); + fiat_p256_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); + fiat_p256_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); fiat_p256_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); out1[0] = x1; out1[1] = x2; @@ -2965,7 +3944,8 @@ static void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const ui } /* - * The function fiat_p256_to_bytes serializes a field element in the Montgomery domain to bytes in little-endian order. + * The function fiat_p256_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: @@ -2976,106 +3956,156 @@ static void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const ui * Output Bounds: * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] */ -static void fiat_p256_to_bytes(uint8_t out1[32], const uint32_t arg1[8]) { - uint32_t x1 = (arg1[7]); - uint32_t x2 = (arg1[6]); - uint32_t x3 = (arg1[5]); - uint32_t x4 = (arg1[4]); - uint32_t x5 = (arg1[3]); - uint32_t x6 = (arg1[2]); - uint32_t x7 = (arg1[1]); - uint32_t x8 = (arg1[0]); - uint32_t x9 = (x8 >> 8); - uint8_t x10 = (uint8_t)(x8 & UINT8_C(0xff)); - uint32_t x11 = (x9 >> 8); - uint8_t x12 = (uint8_t)(x9 & UINT8_C(0xff)); - uint8_t x13 = (uint8_t)(x11 >> 8); - uint8_t x14 = (uint8_t)(x11 & UINT8_C(0xff)); - uint8_t x15 = (uint8_t)(x13 & UINT8_C(0xff)); - uint32_t x16 = (x7 >> 8); - uint8_t x17 = (uint8_t)(x7 & UINT8_C(0xff)); - uint32_t x18 = (x16 >> 8); - uint8_t x19 = (uint8_t)(x16 & UINT8_C(0xff)); - uint8_t x20 = (uint8_t)(x18 >> 8); - uint8_t x21 = (uint8_t)(x18 & UINT8_C(0xff)); - uint8_t x22 = (uint8_t)(x20 & UINT8_C(0xff)); - uint32_t x23 = (x6 >> 8); - uint8_t x24 = (uint8_t)(x6 & UINT8_C(0xff)); - uint32_t x25 = (x23 >> 8); - uint8_t x26 = (uint8_t)(x23 & UINT8_C(0xff)); - uint8_t x27 = (uint8_t)(x25 >> 8); - uint8_t x28 = (uint8_t)(x25 & UINT8_C(0xff)); - uint8_t x29 = (uint8_t)(x27 & UINT8_C(0xff)); - uint32_t x30 = (x5 >> 8); - uint8_t x31 = (uint8_t)(x5 & UINT8_C(0xff)); - uint32_t x32 = (x30 >> 8); - uint8_t x33 = (uint8_t)(x30 & UINT8_C(0xff)); - uint8_t x34 = (uint8_t)(x32 >> 8); - uint8_t x35 = (uint8_t)(x32 & UINT8_C(0xff)); - uint8_t x36 = (uint8_t)(x34 & UINT8_C(0xff)); - uint32_t x37 = (x4 >> 8); - uint8_t x38 = (uint8_t)(x4 & UINT8_C(0xff)); - uint32_t x39 = (x37 >> 8); - uint8_t x40 = (uint8_t)(x37 & UINT8_C(0xff)); - uint8_t x41 = (uint8_t)(x39 >> 8); - uint8_t x42 = (uint8_t)(x39 & UINT8_C(0xff)); - uint8_t x43 = (uint8_t)(x41 & UINT8_C(0xff)); - uint32_t x44 = (x3 >> 8); - uint8_t x45 = (uint8_t)(x3 & UINT8_C(0xff)); - uint32_t x46 = (x44 >> 8); - uint8_t x47 = (uint8_t)(x44 & UINT8_C(0xff)); - uint8_t x48 = (uint8_t)(x46 >> 8); - uint8_t x49 = (uint8_t)(x46 & UINT8_C(0xff)); - uint8_t x50 = (uint8_t)(x48 & UINT8_C(0xff)); - uint32_t x51 = (x2 >> 8); - uint8_t x52 = (uint8_t)(x2 & UINT8_C(0xff)); - uint32_t x53 = (x51 >> 8); - uint8_t x54 = (uint8_t)(x51 & UINT8_C(0xff)); - uint8_t x55 = (uint8_t)(x53 >> 8); - uint8_t x56 = (uint8_t)(x53 & UINT8_C(0xff)); - uint8_t x57 = (uint8_t)(x55 & UINT8_C(0xff)); - uint32_t x58 = (x1 >> 8); - uint8_t x59 = (uint8_t)(x1 & UINT8_C(0xff)); - uint32_t x60 = (x58 >> 8); - uint8_t x61 = (uint8_t)(x58 & UINT8_C(0xff)); - uint8_t x62 = (uint8_t)(x60 >> 8); - uint8_t x63 = (uint8_t)(x60 & UINT8_C(0xff)); - out1[0] = x10; - out1[1] = x12; - out1[2] = x14; - out1[3] = x15; - out1[4] = x17; - out1[5] = x19; - out1[6] = x21; - out1[7] = x22; - out1[8] = x24; - out1[9] = x26; - out1[10] = x28; - out1[11] = x29; - out1[12] = x31; - out1[13] = x33; - out1[14] = x35; - out1[15] = x36; - out1[16] = x38; - out1[17] = x40; - out1[18] = x42; - out1[19] = x43; - out1[20] = x45; - out1[21] = x47; - out1[22] = x49; - out1[23] = x50; - out1[24] = x52; - out1[25] = x54; - out1[26] = x56; - out1[27] = x57; - out1[28] = x59; - out1[29] = x61; - out1[30] = x63; - out1[31] = x62; +static FIAT_P256_FIAT_INLINE void fiat_p256_to_bytes(uint8_t out1[32], const uint32_t arg1[8]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint32_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint8_t x9; + uint32_t x10; + uint8_t x11; + uint32_t x12; + uint8_t x13; + uint8_t x14; + uint8_t x15; + uint32_t x16; + uint8_t x17; + uint32_t x18; + uint8_t x19; + uint8_t x20; + uint8_t x21; + uint32_t x22; + uint8_t x23; + uint32_t x24; + uint8_t x25; + uint8_t x26; + uint8_t x27; + uint32_t x28; + uint8_t x29; + uint32_t x30; + uint8_t x31; + uint8_t x32; + uint8_t x33; + uint32_t x34; + uint8_t x35; + uint32_t x36; + uint8_t x37; + uint8_t x38; + uint8_t x39; + uint32_t x40; + uint8_t x41; + uint32_t x42; + uint8_t x43; + uint8_t x44; + uint8_t x45; + uint32_t x46; + uint8_t x47; + uint32_t x48; + uint8_t x49; + uint8_t x50; + uint8_t x51; + uint32_t x52; + uint8_t x53; + uint32_t x54; + uint8_t x55; + uint8_t x56; + x1 = (arg1[7]); + x2 = (arg1[6]); + x3 = (arg1[5]); + x4 = (arg1[4]); + x5 = (arg1[3]); + x6 = (arg1[2]); + x7 = (arg1[1]); + x8 = (arg1[0]); + x9 = (uint8_t)(x8 & UINT8_C(0xff)); + x10 = (x8 >> 8); + x11 = (uint8_t)(x10 & UINT8_C(0xff)); + x12 = (x10 >> 8); + x13 = (uint8_t)(x12 & UINT8_C(0xff)); + x14 = (uint8_t)(x12 >> 8); + x15 = (uint8_t)(x7 & UINT8_C(0xff)); + x16 = (x7 >> 8); + x17 = (uint8_t)(x16 & UINT8_C(0xff)); + x18 = (x16 >> 8); + x19 = (uint8_t)(x18 & UINT8_C(0xff)); + x20 = (uint8_t)(x18 >> 8); + x21 = (uint8_t)(x6 & UINT8_C(0xff)); + x22 = (x6 >> 8); + x23 = (uint8_t)(x22 & UINT8_C(0xff)); + x24 = (x22 >> 8); + x25 = (uint8_t)(x24 & UINT8_C(0xff)); + x26 = (uint8_t)(x24 >> 8); + x27 = (uint8_t)(x5 & UINT8_C(0xff)); + x28 = (x5 >> 8); + x29 = (uint8_t)(x28 & UINT8_C(0xff)); + x30 = (x28 >> 8); + x31 = (uint8_t)(x30 & UINT8_C(0xff)); + x32 = (uint8_t)(x30 >> 8); + x33 = (uint8_t)(x4 & UINT8_C(0xff)); + x34 = (x4 >> 8); + x35 = (uint8_t)(x34 & UINT8_C(0xff)); + x36 = (x34 >> 8); + x37 = (uint8_t)(x36 & UINT8_C(0xff)); + x38 = (uint8_t)(x36 >> 8); + x39 = (uint8_t)(x3 & UINT8_C(0xff)); + x40 = (x3 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (uint8_t)(x42 >> 8); + x45 = (uint8_t)(x2 & UINT8_C(0xff)); + x46 = (x2 >> 8); + x47 = (uint8_t)(x46 & UINT8_C(0xff)); + x48 = (x46 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (uint8_t)(x48 >> 8); + x51 = (uint8_t)(x1 & UINT8_C(0xff)); + x52 = (x1 >> 8); + x53 = (uint8_t)(x52 & UINT8_C(0xff)); + x54 = (x52 >> 8); + x55 = (uint8_t)(x54 & UINT8_C(0xff)); + x56 = (uint8_t)(x54 >> 8); + out1[0] = x9; + out1[1] = x11; + out1[2] = x13; + out1[3] = x14; + out1[4] = x15; + out1[5] = x17; + out1[6] = x19; + out1[7] = x20; + out1[8] = x21; + out1[9] = x23; + out1[10] = x25; + out1[11] = x26; + out1[12] = x27; + out1[13] = x29; + out1[14] = x31; + out1[15] = x32; + out1[16] = x33; + out1[17] = x35; + out1[18] = x37; + out1[19] = x38; + out1[20] = x39; + out1[21] = x41; + out1[22] = x43; + out1[23] = x44; + out1[24] = x45; + out1[25] = x47; + out1[26] = x49; + out1[27] = x50; + out1[28] = x51; + out1[29] = x53; + out1[30] = x55; + out1[31] = x56; } /* - * The function fiat_p256_from_bytes deserializes a field element in the Montgomery domain from bytes in little-endian order. + * The function fiat_p256_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. + * * Preconditions: * 0 ≤ bytes_eval arg1 < m * Postconditions: @@ -3087,61 +4117,644 @@ static void fiat_p256_to_bytes(uint8_t out1[32], const uint32_t arg1[8]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] */ -static void fiat_p256_from_bytes(uint32_t out1[8], const uint8_t arg1[32]) { - uint32_t x1 = ((uint32_t)(arg1[31]) << 24); - uint32_t x2 = ((uint32_t)(arg1[30]) << 16); - uint32_t x3 = ((uint32_t)(arg1[29]) << 8); - uint8_t x4 = (arg1[28]); - uint32_t x5 = ((uint32_t)(arg1[27]) << 24); - uint32_t x6 = ((uint32_t)(arg1[26]) << 16); - uint32_t x7 = ((uint32_t)(arg1[25]) << 8); - uint8_t x8 = (arg1[24]); - uint32_t x9 = ((uint32_t)(arg1[23]) << 24); - uint32_t x10 = ((uint32_t)(arg1[22]) << 16); - uint32_t x11 = ((uint32_t)(arg1[21]) << 8); - uint8_t x12 = (arg1[20]); - uint32_t x13 = ((uint32_t)(arg1[19]) << 24); - uint32_t x14 = ((uint32_t)(arg1[18]) << 16); - uint32_t x15 = ((uint32_t)(arg1[17]) << 8); - uint8_t x16 = (arg1[16]); - uint32_t x17 = ((uint32_t)(arg1[15]) << 24); - uint32_t x18 = ((uint32_t)(arg1[14]) << 16); - uint32_t x19 = ((uint32_t)(arg1[13]) << 8); - uint8_t x20 = (arg1[12]); - uint32_t x21 = ((uint32_t)(arg1[11]) << 24); - uint32_t x22 = ((uint32_t)(arg1[10]) << 16); - uint32_t x23 = ((uint32_t)(arg1[9]) << 8); - uint8_t x24 = (arg1[8]); - uint32_t x25 = ((uint32_t)(arg1[7]) << 24); - uint32_t x26 = ((uint32_t)(arg1[6]) << 16); - uint32_t x27 = ((uint32_t)(arg1[5]) << 8); - uint8_t x28 = (arg1[4]); - uint32_t x29 = ((uint32_t)(arg1[3]) << 24); - uint32_t x30 = ((uint32_t)(arg1[2]) << 16); - uint32_t x31 = ((uint32_t)(arg1[1]) << 8); - uint8_t x32 = (arg1[0]); - uint32_t x33 = (x32 + (x31 + (x30 + x29))); - uint32_t x34 = (x33 & UINT32_C(0xffffffff)); - uint32_t x35 = (x4 + (x3 + (x2 + x1))); - uint32_t x36 = (x8 + (x7 + (x6 + x5))); - uint32_t x37 = (x12 + (x11 + (x10 + x9))); - uint32_t x38 = (x16 + (x15 + (x14 + x13))); - uint32_t x39 = (x20 + (x19 + (x18 + x17))); - uint32_t x40 = (x24 + (x23 + (x22 + x21))); - uint32_t x41 = (x28 + (x27 + (x26 + x25))); - uint32_t x42 = (x41 & UINT32_C(0xffffffff)); - uint32_t x43 = (x40 & UINT32_C(0xffffffff)); - uint32_t x44 = (x39 & UINT32_C(0xffffffff)); - uint32_t x45 = (x38 & UINT32_C(0xffffffff)); - uint32_t x46 = (x37 & UINT32_C(0xffffffff)); - uint32_t x47 = (x36 & UINT32_C(0xffffffff)); - out1[0] = x34; - out1[1] = x42; - out1[2] = x43; +static FIAT_P256_FIAT_INLINE void fiat_p256_from_bytes(uint32_t out1[8], const uint8_t arg1[32]) { + uint32_t x1; + uint32_t x2; + uint32_t x3; + uint8_t x4; + uint32_t x5; + uint32_t x6; + uint32_t x7; + uint8_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint8_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint8_t x16; + uint32_t x17; + uint32_t x18; + uint32_t x19; + uint8_t x20; + uint32_t x21; + uint32_t x22; + uint32_t x23; + uint8_t x24; + uint32_t x25; + uint32_t x26; + uint32_t x27; + uint8_t x28; + uint32_t x29; + uint32_t x30; + uint32_t x31; + uint8_t x32; + uint32_t x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + uint32_t x52; + uint32_t x53; + uint32_t x54; + uint32_t x55; + uint32_t x56; + x1 = ((uint32_t)(arg1[31]) << 24); + x2 = ((uint32_t)(arg1[30]) << 16); + x3 = ((uint32_t)(arg1[29]) << 8); + x4 = (arg1[28]); + x5 = ((uint32_t)(arg1[27]) << 24); + x6 = ((uint32_t)(arg1[26]) << 16); + x7 = ((uint32_t)(arg1[25]) << 8); + x8 = (arg1[24]); + x9 = ((uint32_t)(arg1[23]) << 24); + x10 = ((uint32_t)(arg1[22]) << 16); + x11 = ((uint32_t)(arg1[21]) << 8); + x12 = (arg1[20]); + x13 = ((uint32_t)(arg1[19]) << 24); + x14 = ((uint32_t)(arg1[18]) << 16); + x15 = ((uint32_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint32_t)(arg1[15]) << 24); + x18 = ((uint32_t)(arg1[14]) << 16); + x19 = ((uint32_t)(arg1[13]) << 8); + x20 = (arg1[12]); + x21 = ((uint32_t)(arg1[11]) << 24); + x22 = ((uint32_t)(arg1[10]) << 16); + x23 = ((uint32_t)(arg1[9]) << 8); + x24 = (arg1[8]); + x25 = ((uint32_t)(arg1[7]) << 24); + x26 = ((uint32_t)(arg1[6]) << 16); + x27 = ((uint32_t)(arg1[5]) << 8); + x28 = (arg1[4]); + x29 = ((uint32_t)(arg1[3]) << 24); + x30 = ((uint32_t)(arg1[2]) << 16); + x31 = ((uint32_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint32_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x27 + (uint32_t)x28); + x37 = (x26 + x36); + x38 = (x25 + x37); + x39 = (x23 + (uint32_t)x24); + x40 = (x22 + x39); + x41 = (x21 + x40); + x42 = (x19 + (uint32_t)x20); + x43 = (x18 + x42); + x44 = (x17 + x43); + x45 = (x15 + (uint32_t)x16); + x46 = (x14 + x45); + x47 = (x13 + x46); + x48 = (x11 + (uint32_t)x12); + x49 = (x10 + x48); + x50 = (x9 + x49); + x51 = (x7 + (uint32_t)x8); + x52 = (x6 + x51); + x53 = (x5 + x52); + x54 = (x3 + (uint32_t)x4); + x55 = (x2 + x54); + x56 = (x1 + x55); + out1[0] = x35; + out1[1] = x38; + out1[2] = x41; out1[3] = x44; - out1[4] = x45; - out1[5] = x46; - out1[6] = x47; - out1[7] = x35; + out1[4] = x47; + out1[5] = x50; + out1[6] = x53; + out1[7] = x56; } +/* + * The function fiat_p256_set_one returns the field element one in the Montgomery domain. + * + * Postconditions: + * eval (from_montgomery out1) mod m = 1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_set_one(fiat_p256_montgomery_domain_field_element out1) { + out1[0] = 0x1; + out1[1] = 0x0; + out1[2] = 0x0; + out1[3] = UINT32_C(0xffffffff); + out1[4] = UINT32_C(0xffffffff); + out1[5] = UINT32_C(0xffffffff); + out1[6] = UINT32_C(0xfffffffe); + out1[7] = 0x0; +} + +/* + * The function fiat_p256_msat returns the saturated representation of the prime modulus. + * + * Postconditions: + * twos_complement_eval out1 = m + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_msat(uint32_t out1[9]) { + out1[0] = UINT32_C(0xffffffff); + out1[1] = UINT32_C(0xffffffff); + out1[2] = UINT32_C(0xffffffff); + out1[3] = 0x0; + out1[4] = 0x0; + out1[5] = 0x0; + out1[6] = 0x1; + out1[7] = UINT32_C(0xffffffff); + out1[8] = 0x0; +} + +/* + * The function fiat_p256_divstep computes a divstep. + * + * Preconditions: + * 0 ≤ eval arg4 < m + * 0 ≤ eval arg5 < m + * Postconditions: + * out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) + * twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) + * twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) + * eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) + * eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) + * 0 ≤ eval out5 < m + * 0 ≤ eval out5 < m + * 0 ≤ eval out2 < m + * 0 ≤ eval out3 < m + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffff] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg4: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg5: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out4: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * out5: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep(uint32_t* out1, uint32_t out2[9], uint32_t out3[9], uint32_t out4[8], uint32_t out5[8], uint32_t arg1, const uint32_t arg2[9], const uint32_t arg3[9], const uint32_t arg4[8], const uint32_t arg5[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_uint1 x3; + uint32_t x4; + fiat_p256_uint1 x5; + uint32_t x6; + uint32_t x7; + uint32_t x8; + uint32_t x9; + uint32_t x10; + uint32_t x11; + uint32_t x12; + uint32_t x13; + uint32_t x14; + uint32_t x15; + uint32_t x16; + fiat_p256_uint1 x17; + uint32_t x18; + fiat_p256_uint1 x19; + uint32_t x20; + fiat_p256_uint1 x21; + uint32_t x22; + fiat_p256_uint1 x23; + uint32_t x24; + fiat_p256_uint1 x25; + uint32_t x26; + fiat_p256_uint1 x27; + uint32_t x28; + fiat_p256_uint1 x29; + uint32_t x30; + fiat_p256_uint1 x31; + uint32_t x32; + fiat_p256_uint1 x33; + uint32_t x34; + uint32_t x35; + uint32_t x36; + uint32_t x37; + uint32_t x38; + uint32_t x39; + uint32_t x40; + uint32_t x41; + uint32_t x42; + uint32_t x43; + uint32_t x44; + uint32_t x45; + uint32_t x46; + uint32_t x47; + uint32_t x48; + uint32_t x49; + uint32_t x50; + uint32_t x51; + fiat_p256_uint1 x52; + uint32_t x53; + fiat_p256_uint1 x54; + uint32_t x55; + fiat_p256_uint1 x56; + uint32_t x57; + fiat_p256_uint1 x58; + uint32_t x59; + fiat_p256_uint1 x60; + uint32_t x61; + fiat_p256_uint1 x62; + uint32_t x63; + fiat_p256_uint1 x64; + uint32_t x65; + fiat_p256_uint1 x66; + uint32_t x67; + fiat_p256_uint1 x68; + uint32_t x69; + fiat_p256_uint1 x70; + uint32_t x71; + fiat_p256_uint1 x72; + uint32_t x73; + fiat_p256_uint1 x74; + uint32_t x75; + fiat_p256_uint1 x76; + uint32_t x77; + fiat_p256_uint1 x78; + uint32_t x79; + fiat_p256_uint1 x80; + uint32_t x81; + fiat_p256_uint1 x82; + uint32_t x83; + fiat_p256_uint1 x84; + uint32_t x85; + uint32_t x86; + uint32_t x87; + uint32_t x88; + uint32_t x89; + uint32_t x90; + uint32_t x91; + uint32_t x92; + uint32_t x93; + fiat_p256_uint1 x94; + uint32_t x95; + fiat_p256_uint1 x96; + uint32_t x97; + fiat_p256_uint1 x98; + uint32_t x99; + fiat_p256_uint1 x100; + uint32_t x101; + fiat_p256_uint1 x102; + uint32_t x103; + fiat_p256_uint1 x104; + uint32_t x105; + fiat_p256_uint1 x106; + uint32_t x107; + fiat_p256_uint1 x108; + uint32_t x109; + uint32_t x110; + fiat_p256_uint1 x111; + uint32_t x112; + fiat_p256_uint1 x113; + uint32_t x114; + fiat_p256_uint1 x115; + uint32_t x116; + fiat_p256_uint1 x117; + uint32_t x118; + fiat_p256_uint1 x119; + uint32_t x120; + fiat_p256_uint1 x121; + uint32_t x122; + fiat_p256_uint1 x123; + uint32_t x124; + fiat_p256_uint1 x125; + uint32_t x126; + uint32_t x127; + uint32_t x128; + uint32_t x129; + uint32_t x130; + uint32_t x131; + uint32_t x132; + uint32_t x133; + fiat_p256_uint1 x134; + uint32_t x135; + uint32_t x136; + uint32_t x137; + uint32_t x138; + uint32_t x139; + uint32_t x140; + uint32_t x141; + uint32_t x142; + uint32_t x143; + uint32_t x144; + fiat_p256_uint1 x145; + uint32_t x146; + fiat_p256_uint1 x147; + uint32_t x148; + fiat_p256_uint1 x149; + uint32_t x150; + fiat_p256_uint1 x151; + uint32_t x152; + fiat_p256_uint1 x153; + uint32_t x154; + fiat_p256_uint1 x155; + uint32_t x156; + fiat_p256_uint1 x157; + uint32_t x158; + fiat_p256_uint1 x159; + uint32_t x160; + fiat_p256_uint1 x161; + uint32_t x162; + uint32_t x163; + uint32_t x164; + uint32_t x165; + uint32_t x166; + uint32_t x167; + uint32_t x168; + uint32_t x169; + uint32_t x170; + fiat_p256_uint1 x171; + uint32_t x172; + fiat_p256_uint1 x173; + uint32_t x174; + fiat_p256_uint1 x175; + uint32_t x176; + fiat_p256_uint1 x177; + uint32_t x178; + fiat_p256_uint1 x179; + uint32_t x180; + fiat_p256_uint1 x181; + uint32_t x182; + fiat_p256_uint1 x183; + uint32_t x184; + fiat_p256_uint1 x185; + uint32_t x186; + fiat_p256_uint1 x187; + uint32_t x188; + fiat_p256_uint1 x189; + uint32_t x190; + fiat_p256_uint1 x191; + uint32_t x192; + fiat_p256_uint1 x193; + uint32_t x194; + fiat_p256_uint1 x195; + uint32_t x196; + fiat_p256_uint1 x197; + uint32_t x198; + fiat_p256_uint1 x199; + uint32_t x200; + fiat_p256_uint1 x201; + uint32_t x202; + fiat_p256_uint1 x203; + uint32_t x204; + fiat_p256_uint1 x205; + uint32_t x206; + uint32_t x207; + uint32_t x208; + uint32_t x209; + uint32_t x210; + uint32_t x211; + uint32_t x212; + uint32_t x213; + uint32_t x214; + uint32_t x215; + uint32_t x216; + uint32_t x217; + uint32_t x218; + uint32_t x219; + uint32_t x220; + uint32_t x221; + uint32_t x222; + uint32_t x223; + uint32_t x224; + uint32_t x225; + uint32_t x226; + uint32_t x227; + uint32_t x228; + uint32_t x229; + uint32_t x230; + fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (~arg1), 0x1); + x3 = (fiat_p256_uint1)((fiat_p256_uint1)(x1 >> 31) & (fiat_p256_uint1)((arg3[0]) & 0x1)); + fiat_p256_addcarryx_u32(&x4, &x5, 0x0, (~arg1), 0x1); + fiat_p256_cmovznz_u32(&x6, x3, arg1, x4); + fiat_p256_cmovznz_u32(&x7, x3, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u32(&x8, x3, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u32(&x9, x3, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u32(&x10, x3, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u32(&x11, x3, (arg2[4]), (arg3[4])); + fiat_p256_cmovznz_u32(&x12, x3, (arg2[5]), (arg3[5])); + fiat_p256_cmovznz_u32(&x13, x3, (arg2[6]), (arg3[6])); + fiat_p256_cmovznz_u32(&x14, x3, (arg2[7]), (arg3[7])); + fiat_p256_cmovznz_u32(&x15, x3, (arg2[8]), (arg3[8])); + fiat_p256_addcarryx_u32(&x16, &x17, 0x0, 0x1, (~(arg2[0]))); + fiat_p256_addcarryx_u32(&x18, &x19, x17, 0x0, (~(arg2[1]))); + fiat_p256_addcarryx_u32(&x20, &x21, x19, 0x0, (~(arg2[2]))); + fiat_p256_addcarryx_u32(&x22, &x23, x21, 0x0, (~(arg2[3]))); + fiat_p256_addcarryx_u32(&x24, &x25, x23, 0x0, (~(arg2[4]))); + fiat_p256_addcarryx_u32(&x26, &x27, x25, 0x0, (~(arg2[5]))); + fiat_p256_addcarryx_u32(&x28, &x29, x27, 0x0, (~(arg2[6]))); + fiat_p256_addcarryx_u32(&x30, &x31, x29, 0x0, (~(arg2[7]))); + fiat_p256_addcarryx_u32(&x32, &x33, x31, 0x0, (~(arg2[8]))); + fiat_p256_cmovznz_u32(&x34, x3, (arg3[0]), x16); + fiat_p256_cmovznz_u32(&x35, x3, (arg3[1]), x18); + fiat_p256_cmovznz_u32(&x36, x3, (arg3[2]), x20); + fiat_p256_cmovznz_u32(&x37, x3, (arg3[3]), x22); + fiat_p256_cmovznz_u32(&x38, x3, (arg3[4]), x24); + fiat_p256_cmovznz_u32(&x39, x3, (arg3[5]), x26); + fiat_p256_cmovznz_u32(&x40, x3, (arg3[6]), x28); + fiat_p256_cmovznz_u32(&x41, x3, (arg3[7]), x30); + fiat_p256_cmovznz_u32(&x42, x3, (arg3[8]), x32); + fiat_p256_cmovznz_u32(&x43, x3, (arg4[0]), (arg5[0])); + fiat_p256_cmovznz_u32(&x44, x3, (arg4[1]), (arg5[1])); + fiat_p256_cmovznz_u32(&x45, x3, (arg4[2]), (arg5[2])); + fiat_p256_cmovznz_u32(&x46, x3, (arg4[3]), (arg5[3])); + fiat_p256_cmovznz_u32(&x47, x3, (arg4[4]), (arg5[4])); + fiat_p256_cmovznz_u32(&x48, x3, (arg4[5]), (arg5[5])); + fiat_p256_cmovznz_u32(&x49, x3, (arg4[6]), (arg5[6])); + fiat_p256_cmovznz_u32(&x50, x3, (arg4[7]), (arg5[7])); + fiat_p256_addcarryx_u32(&x51, &x52, 0x0, x43, x43); + fiat_p256_addcarryx_u32(&x53, &x54, x52, x44, x44); + fiat_p256_addcarryx_u32(&x55, &x56, x54, x45, x45); + fiat_p256_addcarryx_u32(&x57, &x58, x56, x46, x46); + fiat_p256_addcarryx_u32(&x59, &x60, x58, x47, x47); + fiat_p256_addcarryx_u32(&x61, &x62, x60, x48, x48); + fiat_p256_addcarryx_u32(&x63, &x64, x62, x49, x49); + fiat_p256_addcarryx_u32(&x65, &x66, x64, x50, x50); + fiat_p256_subborrowx_u32(&x67, &x68, 0x0, x51, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x69, &x70, x68, x53, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x71, &x72, x70, x55, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x73, &x74, x72, x57, 0x0); + fiat_p256_subborrowx_u32(&x75, &x76, x74, x59, 0x0); + fiat_p256_subborrowx_u32(&x77, &x78, x76, x61, 0x0); + fiat_p256_subborrowx_u32(&x79, &x80, x78, x63, 0x1); + fiat_p256_subborrowx_u32(&x81, &x82, x80, x65, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x83, &x84, x82, x66, 0x0); + x85 = (arg4[7]); + x86 = (arg4[6]); + x87 = (arg4[5]); + x88 = (arg4[4]); + x89 = (arg4[3]); + x90 = (arg4[2]); + x91 = (arg4[1]); + x92 = (arg4[0]); + fiat_p256_subborrowx_u32(&x93, &x94, 0x0, 0x0, x92); + fiat_p256_subborrowx_u32(&x95, &x96, x94, 0x0, x91); + fiat_p256_subborrowx_u32(&x97, &x98, x96, 0x0, x90); + fiat_p256_subborrowx_u32(&x99, &x100, x98, 0x0, x89); + fiat_p256_subborrowx_u32(&x101, &x102, x100, 0x0, x88); + fiat_p256_subborrowx_u32(&x103, &x104, x102, 0x0, x87); + fiat_p256_subborrowx_u32(&x105, &x106, x104, 0x0, x86); + fiat_p256_subborrowx_u32(&x107, &x108, x106, 0x0, x85); + fiat_p256_cmovznz_u32(&x109, x108, 0x0, UINT32_C(0xffffffff)); + fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x93, x109); + fiat_p256_addcarryx_u32(&x112, &x113, x111, x95, x109); + fiat_p256_addcarryx_u32(&x114, &x115, x113, x97, x109); + fiat_p256_addcarryx_u32(&x116, &x117, x115, x99, 0x0); + fiat_p256_addcarryx_u32(&x118, &x119, x117, x101, 0x0); + fiat_p256_addcarryx_u32(&x120, &x121, x119, x103, 0x0); + fiat_p256_addcarryx_u32(&x122, &x123, x121, x105, (fiat_p256_uint1)(x109 & 0x1)); + fiat_p256_addcarryx_u32(&x124, &x125, x123, x107, x109); + fiat_p256_cmovznz_u32(&x126, x3, (arg5[0]), x110); + fiat_p256_cmovznz_u32(&x127, x3, (arg5[1]), x112); + fiat_p256_cmovznz_u32(&x128, x3, (arg5[2]), x114); + fiat_p256_cmovznz_u32(&x129, x3, (arg5[3]), x116); + fiat_p256_cmovznz_u32(&x130, x3, (arg5[4]), x118); + fiat_p256_cmovznz_u32(&x131, x3, (arg5[5]), x120); + fiat_p256_cmovznz_u32(&x132, x3, (arg5[6]), x122); + fiat_p256_cmovznz_u32(&x133, x3, (arg5[7]), x124); + x134 = (fiat_p256_uint1)(x34 & 0x1); + fiat_p256_cmovznz_u32(&x135, x134, 0x0, x7); + fiat_p256_cmovznz_u32(&x136, x134, 0x0, x8); + fiat_p256_cmovznz_u32(&x137, x134, 0x0, x9); + fiat_p256_cmovznz_u32(&x138, x134, 0x0, x10); + fiat_p256_cmovznz_u32(&x139, x134, 0x0, x11); + fiat_p256_cmovznz_u32(&x140, x134, 0x0, x12); + fiat_p256_cmovznz_u32(&x141, x134, 0x0, x13); + fiat_p256_cmovznz_u32(&x142, x134, 0x0, x14); + fiat_p256_cmovznz_u32(&x143, x134, 0x0, x15); + fiat_p256_addcarryx_u32(&x144, &x145, 0x0, x34, x135); + fiat_p256_addcarryx_u32(&x146, &x147, x145, x35, x136); + fiat_p256_addcarryx_u32(&x148, &x149, x147, x36, x137); + fiat_p256_addcarryx_u32(&x150, &x151, x149, x37, x138); + fiat_p256_addcarryx_u32(&x152, &x153, x151, x38, x139); + fiat_p256_addcarryx_u32(&x154, &x155, x153, x39, x140); + fiat_p256_addcarryx_u32(&x156, &x157, x155, x40, x141); + fiat_p256_addcarryx_u32(&x158, &x159, x157, x41, x142); + fiat_p256_addcarryx_u32(&x160, &x161, x159, x42, x143); + fiat_p256_cmovznz_u32(&x162, x134, 0x0, x43); + fiat_p256_cmovznz_u32(&x163, x134, 0x0, x44); + fiat_p256_cmovznz_u32(&x164, x134, 0x0, x45); + fiat_p256_cmovznz_u32(&x165, x134, 0x0, x46); + fiat_p256_cmovznz_u32(&x166, x134, 0x0, x47); + fiat_p256_cmovznz_u32(&x167, x134, 0x0, x48); + fiat_p256_cmovznz_u32(&x168, x134, 0x0, x49); + fiat_p256_cmovznz_u32(&x169, x134, 0x0, x50); + fiat_p256_addcarryx_u32(&x170, &x171, 0x0, x126, x162); + fiat_p256_addcarryx_u32(&x172, &x173, x171, x127, x163); + fiat_p256_addcarryx_u32(&x174, &x175, x173, x128, x164); + fiat_p256_addcarryx_u32(&x176, &x177, x175, x129, x165); + fiat_p256_addcarryx_u32(&x178, &x179, x177, x130, x166); + fiat_p256_addcarryx_u32(&x180, &x181, x179, x131, x167); + fiat_p256_addcarryx_u32(&x182, &x183, x181, x132, x168); + fiat_p256_addcarryx_u32(&x184, &x185, x183, x133, x169); + fiat_p256_subborrowx_u32(&x186, &x187, 0x0, x170, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x188, &x189, x187, x172, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x190, &x191, x189, x174, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x192, &x193, x191, x176, 0x0); + fiat_p256_subborrowx_u32(&x194, &x195, x193, x178, 0x0); + fiat_p256_subborrowx_u32(&x196, &x197, x195, x180, 0x0); + fiat_p256_subborrowx_u32(&x198, &x199, x197, x182, 0x1); + fiat_p256_subborrowx_u32(&x200, &x201, x199, x184, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u32(&x202, &x203, x201, x185, 0x0); + fiat_p256_addcarryx_u32(&x204, &x205, 0x0, x6, 0x1); + x206 = ((x144 >> 1) | ((x146 << 31) & UINT32_C(0xffffffff))); + x207 = ((x146 >> 1) | ((x148 << 31) & UINT32_C(0xffffffff))); + x208 = ((x148 >> 1) | ((x150 << 31) & UINT32_C(0xffffffff))); + x209 = ((x150 >> 1) | ((x152 << 31) & UINT32_C(0xffffffff))); + x210 = ((x152 >> 1) | ((x154 << 31) & UINT32_C(0xffffffff))); + x211 = ((x154 >> 1) | ((x156 << 31) & UINT32_C(0xffffffff))); + x212 = ((x156 >> 1) | ((x158 << 31) & UINT32_C(0xffffffff))); + x213 = ((x158 >> 1) | ((x160 << 31) & UINT32_C(0xffffffff))); + x214 = ((x160 & UINT32_C(0x80000000)) | (x160 >> 1)); + fiat_p256_cmovznz_u32(&x215, x84, x67, x51); + fiat_p256_cmovznz_u32(&x216, x84, x69, x53); + fiat_p256_cmovznz_u32(&x217, x84, x71, x55); + fiat_p256_cmovznz_u32(&x218, x84, x73, x57); + fiat_p256_cmovznz_u32(&x219, x84, x75, x59); + fiat_p256_cmovznz_u32(&x220, x84, x77, x61); + fiat_p256_cmovznz_u32(&x221, x84, x79, x63); + fiat_p256_cmovznz_u32(&x222, x84, x81, x65); + fiat_p256_cmovznz_u32(&x223, x203, x186, x170); + fiat_p256_cmovznz_u32(&x224, x203, x188, x172); + fiat_p256_cmovznz_u32(&x225, x203, x190, x174); + fiat_p256_cmovznz_u32(&x226, x203, x192, x176); + fiat_p256_cmovznz_u32(&x227, x203, x194, x178); + fiat_p256_cmovznz_u32(&x228, x203, x196, x180); + fiat_p256_cmovznz_u32(&x229, x203, x198, x182); + fiat_p256_cmovznz_u32(&x230, x203, x200, x184); + *out1 = x204; + out2[0] = x7; + out2[1] = x8; + out2[2] = x9; + out2[3] = x10; + out2[4] = x11; + out2[5] = x12; + out2[6] = x13; + out2[7] = x14; + out2[8] = x15; + out3[0] = x206; + out3[1] = x207; + out3[2] = x208; + out3[3] = x209; + out3[4] = x210; + out3[5] = x211; + out3[6] = x212; + out3[7] = x213; + out3[8] = x214; + out4[0] = x215; + out4[1] = x216; + out4[2] = x217; + out4[3] = x218; + out4[4] = x219; + out4[5] = x220; + out4[6] = x221; + out4[7] = x222; + out5[0] = x223; + out5[1] = x224; + out5[2] = x225; + out5[3] = x226; + out5[4] = x227; + out5[5] = x228; + out5[6] = x229; + out5[7] = x230; +} + +/* + * The function fiat_p256_divstep_precomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). + * + * Postconditions: + * eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep_precomp(uint32_t out1[8]) { + out1[0] = UINT32_C(0xb8000000); + out1[1] = UINT32_C(0x67ffffff); + out1[2] = UINT32_C(0x38000000); + out1[3] = UINT32_C(0xc0000000); + out1[4] = UINT32_C(0x7fffffff); + out1[5] = UINT32_C(0xd8000000); + out1[6] = UINT32_C(0xffffffff); + out1[7] = UINT32_C(0x2fffffff); +} diff --git a/third_party/boringssl/kit/src/third_party/fiat/p256_64.h b/third_party/boringssl/kit/src/third_party/fiat/p256_64.h index 773266a0..c7726384 100644 --- a/third_party/boringssl/kit/src/third_party/fiat/p256_64.h +++ b/third_party/boringssl/kit/src/third_party/fiat/p256_64.h @@ -1,8 +1,8 @@ -/* Autogenerated: src/ExtractionOCaml/word_by_word_montgomery --static p256 '2^256 - 2^224 + 2^192 + 2^96 - 1' 64 mul square add sub opp from_montgomery nonzero selectznz to_bytes from_bytes */ +/* Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --inline --static --use-value-barrier p256 64 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp */ /* curve description: p256 */ -/* requested operations: mul, square, add, sub, opp, from_montgomery, nonzero, selectznz, to_bytes, from_bytes */ -/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ /* machine_wordsize = 64 (from "64") */ +/* requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp */ +/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ /* */ /* NOTE: In addition to the bounds specified above each function, all */ /* functions synthesized for this Montgomery arithmetic require the */ @@ -10,20 +10,52 @@ /* require the input to be in the unique saturated representation. */ /* All functions also ensure that these two properties are true of */ /* return values. */ +/* */ +/* Computed values: */ +/* eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in */ +/* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ #include typedef unsigned char fiat_p256_uint1; typedef signed char fiat_p256_int1; -typedef signed __int128 fiat_p256_int128; -typedef unsigned __int128 fiat_p256_uint128; +#if defined(__GNUC__) || defined(__clang__) +# define FIAT_P256_FIAT_EXTENSION __extension__ +# define FIAT_P256_FIAT_INLINE __inline__ +#else +# define FIAT_P256_FIAT_EXTENSION +# define FIAT_P256_FIAT_INLINE +#endif + +FIAT_P256_FIAT_EXTENSION typedef signed __int128 fiat_p256_int128; +FIAT_P256_FIAT_EXTENSION typedef unsigned __int128 fiat_p256_uint128; + +/* The type fiat_p256_montgomery_domain_field_element is a field element in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_montgomery_domain_field_element[4]; + +/* The type fiat_p256_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_non_montgomery_domain_field_element[4]; #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif +#if !defined(FIAT_P256_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) +static __inline__ uint64_t fiat_p256_value_barrier_u64(uint64_t a) { + __asm__("" : "+r"(a) : /* no inputs */); + return a; +} +#else +# define fiat_p256_value_barrier_u64(x) (x) +#endif + /* * The function fiat_p256_addcarryx_u64 is an addition with carry. + * * Postconditions: * out1 = (arg1 + arg2 + arg3) mod 2^64 * out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋ @@ -36,16 +68,20 @@ typedef unsigned __int128 fiat_p256_uint128; * out1: [0x0 ~> 0xffffffffffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { - fiat_p256_uint128 x1 = ((arg1 + (fiat_p256_uint128)arg2) + arg3); - uint64_t x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); - fiat_p256_uint1 x3 = (fiat_p256_uint1)(x1 >> 64); +static FIAT_P256_FIAT_INLINE void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint128 x1; + uint64_t x2; + fiat_p256_uint1 x3; + x1 = ((arg1 + (fiat_p256_uint128)arg2) + arg3); + x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + x3 = (fiat_p256_uint1)(x1 >> 64); *out1 = x2; *out2 = x3; } /* * The function fiat_p256_subborrowx_u64 is a subtraction with borrow. + * * Postconditions: * out1 = (-arg1 + arg2 + -arg3) mod 2^64 * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋ @@ -58,16 +94,20 @@ static void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_ * out1: [0x0 ~> 0xffffffffffffffff] * out2: [0x0 ~> 0x1] */ -static void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { - fiat_p256_int128 x1 = ((arg2 - (fiat_p256_int128)arg1) - arg3); - fiat_p256_int1 x2 = (fiat_p256_int1)(x1 >> 64); - uint64_t x3 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); +static FIAT_P256_FIAT_INLINE void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_int128 x1; + fiat_p256_int1 x2; + uint64_t x3; + x1 = ((arg2 - (fiat_p256_int128)arg1) - arg3); + x2 = (fiat_p256_int1)(x1 >> 64); + x3 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); *out1 = x3; *out2 = (fiat_p256_uint1)(0x0 - x2); } /* * The function fiat_p256_mulx_u64 is a multiplication, returning the full double-width result. + * * Postconditions: * out1 = (arg1 * arg2) mod 2^64 * out2 = ⌊arg1 * arg2 / 2^64⌋ @@ -79,16 +119,20 @@ static void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat * out1: [0x0 ~> 0xffffffffffffffff] * out2: [0x0 ~> 0xffffffffffffffff] */ -static void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { - fiat_p256_uint128 x1 = ((fiat_p256_uint128)arg1 * arg2); - uint64_t x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); - uint64_t x3 = (uint64_t)(x1 >> 64); +static FIAT_P256_FIAT_INLINE void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { + fiat_p256_uint128 x1; + uint64_t x2; + uint64_t x3; + x1 = ((fiat_p256_uint128)arg1 * arg2); + x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + x3 = (uint64_t)(x1 >> 64); *out1 = x2; *out2 = x3; } /* * The function fiat_p256_cmovznz_u64 is a single-word conditional move. + * * Postconditions: * out1 = (if arg1 = 0 then arg2 else arg3) * @@ -99,21 +143,19 @@ static void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, ui * Output Bounds: * out1: [0x0 ~> 0xffffffffffffffff] */ -static void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { - fiat_p256_uint1 x1 = (!(!arg1)); - uint64_t x2 = ((fiat_p256_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); - // Note this line has been patched from the synthesized code to add value - // barriers. - // - // Clang recognizes this pattern as a select. While it usually transforms it - // to a cmov, it sometimes further transforms it into a branch, which we do - // not want. - uint64_t x3 = ((value_barrier_u64(x2) & arg3) | (value_barrier_u64(~x2) & arg2)); +static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_p256_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_p256_value_barrier_u64(x2) & arg3) | (fiat_p256_value_barrier_u64((~x2)) & arg2)); *out1 = x3; } /* * The function fiat_p256_mul multiplies two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -121,287 +163,297 @@ static void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_mul(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { - uint64_t x1 = (arg1[1]); - uint64_t x2 = (arg1[2]); - uint64_t x3 = (arg1[3]); - uint64_t x4 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; uint64_t x5; uint64_t x6; - fiat_p256_mulx_u64(&x5, &x6, x4, (arg2[3])); uint64_t x7; uint64_t x8; - fiat_p256_mulx_u64(&x7, &x8, x4, (arg2[2])); uint64_t x9; uint64_t x10; - fiat_p256_mulx_u64(&x9, &x10, x4, (arg2[1])); uint64_t x11; uint64_t x12; - fiat_p256_mulx_u64(&x11, &x12, x4, (arg2[0])); uint64_t x13; fiat_p256_uint1 x14; - fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); uint64_t x15; fiat_p256_uint1 x16; - fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); uint64_t x17; fiat_p256_uint1 x18; - fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); - uint64_t x19 = (x18 + x6); + uint64_t x19; uint64_t x20; uint64_t x21; - fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); uint64_t x22; uint64_t x23; - fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); uint64_t x24; uint64_t x25; - fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); uint64_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); - uint64_t x28 = (x27 + x23); + uint64_t x28; uint64_t x29; fiat_p256_uint1 x30; - fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); uint64_t x31; fiat_p256_uint1 x32; - fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); uint64_t x33; fiat_p256_uint1 x34; - fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); uint64_t x35; fiat_p256_uint1 x36; - fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); uint64_t x37; fiat_p256_uint1 x38; - fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); uint64_t x39; uint64_t x40; - fiat_p256_mulx_u64(&x39, &x40, x1, (arg2[3])); uint64_t x41; uint64_t x42; - fiat_p256_mulx_u64(&x41, &x42, x1, (arg2[2])); uint64_t x43; uint64_t x44; - fiat_p256_mulx_u64(&x43, &x44, x1, (arg2[1])); uint64_t x45; uint64_t x46; - fiat_p256_mulx_u64(&x45, &x46, x1, (arg2[0])); uint64_t x47; fiat_p256_uint1 x48; - fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); uint64_t x49; fiat_p256_uint1 x50; - fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); uint64_t x51; fiat_p256_uint1 x52; - fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); - uint64_t x53 = (x52 + x40); + uint64_t x53; uint64_t x54; fiat_p256_uint1 x55; - fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); uint64_t x56; fiat_p256_uint1 x57; - fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); uint64_t x58; fiat_p256_uint1 x59; - fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); uint64_t x60; fiat_p256_uint1 x61; - fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); uint64_t x62; fiat_p256_uint1 x63; - fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); uint64_t x64; uint64_t x65; - fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); uint64_t x66; uint64_t x67; - fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); uint64_t x68; uint64_t x69; - fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); uint64_t x70; fiat_p256_uint1 x71; - fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); - uint64_t x72 = (x71 + x67); + uint64_t x72; uint64_t x73; fiat_p256_uint1 x74; - fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); uint64_t x75; fiat_p256_uint1 x76; - fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); uint64_t x77; fiat_p256_uint1 x78; - fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); uint64_t x79; fiat_p256_uint1 x80; - fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); uint64_t x81; fiat_p256_uint1 x82; - fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); - uint64_t x83 = ((uint64_t)x82 + x63); + uint64_t x83; uint64_t x84; uint64_t x85; - fiat_p256_mulx_u64(&x84, &x85, x2, (arg2[3])); uint64_t x86; uint64_t x87; - fiat_p256_mulx_u64(&x86, &x87, x2, (arg2[2])); uint64_t x88; uint64_t x89; - fiat_p256_mulx_u64(&x88, &x89, x2, (arg2[1])); uint64_t x90; uint64_t x91; - fiat_p256_mulx_u64(&x90, &x91, x2, (arg2[0])); uint64_t x92; fiat_p256_uint1 x93; - fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); uint64_t x94; fiat_p256_uint1 x95; - fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); uint64_t x96; fiat_p256_uint1 x97; - fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); - uint64_t x98 = (x97 + x85); + uint64_t x98; uint64_t x99; fiat_p256_uint1 x100; - fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); uint64_t x101; fiat_p256_uint1 x102; - fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); uint64_t x103; fiat_p256_uint1 x104; - fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); uint64_t x105; fiat_p256_uint1 x106; - fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); uint64_t x107; fiat_p256_uint1 x108; - fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); uint64_t x109; uint64_t x110; - fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); uint64_t x111; uint64_t x112; - fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); uint64_t x113; uint64_t x114; - fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); uint64_t x115; fiat_p256_uint1 x116; - fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); - uint64_t x117 = (x116 + x112); + uint64_t x117; uint64_t x118; fiat_p256_uint1 x119; - fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); uint64_t x120; fiat_p256_uint1 x121; - fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); uint64_t x122; fiat_p256_uint1 x123; - fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); uint64_t x124; fiat_p256_uint1 x125; - fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); uint64_t x126; fiat_p256_uint1 x127; - fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); - uint64_t x128 = ((uint64_t)x127 + x108); + uint64_t x128; uint64_t x129; uint64_t x130; - fiat_p256_mulx_u64(&x129, &x130, x3, (arg2[3])); uint64_t x131; uint64_t x132; - fiat_p256_mulx_u64(&x131, &x132, x3, (arg2[2])); uint64_t x133; uint64_t x134; - fiat_p256_mulx_u64(&x133, &x134, x3, (arg2[1])); uint64_t x135; uint64_t x136; - fiat_p256_mulx_u64(&x135, &x136, x3, (arg2[0])); uint64_t x137; fiat_p256_uint1 x138; - fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); uint64_t x139; fiat_p256_uint1 x140; - fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); uint64_t x141; fiat_p256_uint1 x142; - fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); - uint64_t x143 = (x142 + x130); + uint64_t x143; uint64_t x144; fiat_p256_uint1 x145; - fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); uint64_t x146; fiat_p256_uint1 x147; - fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); uint64_t x148; fiat_p256_uint1 x149; - fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); uint64_t x150; fiat_p256_uint1 x151; - fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); uint64_t x152; fiat_p256_uint1 x153; - fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); uint64_t x154; uint64_t x155; - fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); uint64_t x156; uint64_t x157; - fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); uint64_t x158; uint64_t x159; - fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); uint64_t x160; fiat_p256_uint1 x161; - fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); - uint64_t x162 = (x161 + x157); + uint64_t x162; uint64_t x163; fiat_p256_uint1 x164; - fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); uint64_t x165; fiat_p256_uint1 x166; - fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); uint64_t x167; fiat_p256_uint1 x168; - fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); uint64_t x169; fiat_p256_uint1 x170; - fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); uint64_t x171; fiat_p256_uint1 x172; - fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); - uint64_t x173 = ((uint64_t)x172 + x153); + uint64_t x173; uint64_t x174; fiat_p256_uint1 x175; - fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); uint64_t x176; fiat_p256_uint1 x177; - fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); uint64_t x178; fiat_p256_uint1 x179; - fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); uint64_t x180; fiat_p256_uint1 x181; - fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); uint64_t x182; fiat_p256_uint1 x183; - fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); uint64_t x184; - fiat_p256_cmovznz_u64(&x184, x183, x174, x165); uint64_t x185; - fiat_p256_cmovznz_u64(&x185, x183, x176, x167); uint64_t x186; - fiat_p256_cmovznz_u64(&x186, x183, x178, x169); uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg2[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg2[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg2[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg2[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg2[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg2[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg2[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg2[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg2[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg2[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg2[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg2[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg2[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg2[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg2[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg2[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); fiat_p256_cmovznz_u64(&x187, x183, x180, x171); out1[0] = x184; out1[1] = x185; @@ -411,292 +463,304 @@ static void fiat_p256_mul(uint64_t out1[4], const uint64_t arg1[4], const uint64 /* * The function fiat_p256_square squares a field element in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_square(uint64_t out1[4], const uint64_t arg1[4]) { - uint64_t x1 = (arg1[1]); - uint64_t x2 = (arg1[2]); - uint64_t x3 = (arg1[3]); - uint64_t x4 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; uint64_t x5; uint64_t x6; - fiat_p256_mulx_u64(&x5, &x6, x4, (arg1[3])); uint64_t x7; uint64_t x8; - fiat_p256_mulx_u64(&x7, &x8, x4, (arg1[2])); uint64_t x9; uint64_t x10; - fiat_p256_mulx_u64(&x9, &x10, x4, (arg1[1])); uint64_t x11; uint64_t x12; - fiat_p256_mulx_u64(&x11, &x12, x4, (arg1[0])); uint64_t x13; fiat_p256_uint1 x14; - fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); uint64_t x15; fiat_p256_uint1 x16; - fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); uint64_t x17; fiat_p256_uint1 x18; - fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); - uint64_t x19 = (x18 + x6); + uint64_t x19; uint64_t x20; uint64_t x21; - fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); uint64_t x22; uint64_t x23; - fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); uint64_t x24; uint64_t x25; - fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); uint64_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); - uint64_t x28 = (x27 + x23); + uint64_t x28; uint64_t x29; fiat_p256_uint1 x30; - fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); uint64_t x31; fiat_p256_uint1 x32; - fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); uint64_t x33; fiat_p256_uint1 x34; - fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); uint64_t x35; fiat_p256_uint1 x36; - fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); uint64_t x37; fiat_p256_uint1 x38; - fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); uint64_t x39; uint64_t x40; - fiat_p256_mulx_u64(&x39, &x40, x1, (arg1[3])); uint64_t x41; uint64_t x42; - fiat_p256_mulx_u64(&x41, &x42, x1, (arg1[2])); uint64_t x43; uint64_t x44; - fiat_p256_mulx_u64(&x43, &x44, x1, (arg1[1])); uint64_t x45; uint64_t x46; - fiat_p256_mulx_u64(&x45, &x46, x1, (arg1[0])); uint64_t x47; fiat_p256_uint1 x48; - fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); uint64_t x49; fiat_p256_uint1 x50; - fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); uint64_t x51; fiat_p256_uint1 x52; - fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); - uint64_t x53 = (x52 + x40); + uint64_t x53; uint64_t x54; fiat_p256_uint1 x55; - fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); uint64_t x56; fiat_p256_uint1 x57; - fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); uint64_t x58; fiat_p256_uint1 x59; - fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); uint64_t x60; fiat_p256_uint1 x61; - fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); uint64_t x62; fiat_p256_uint1 x63; - fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); uint64_t x64; uint64_t x65; - fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); uint64_t x66; uint64_t x67; - fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); uint64_t x68; uint64_t x69; - fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); uint64_t x70; fiat_p256_uint1 x71; - fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); - uint64_t x72 = (x71 + x67); + uint64_t x72; uint64_t x73; fiat_p256_uint1 x74; - fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); uint64_t x75; fiat_p256_uint1 x76; - fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); uint64_t x77; fiat_p256_uint1 x78; - fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); uint64_t x79; fiat_p256_uint1 x80; - fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); uint64_t x81; fiat_p256_uint1 x82; - fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); - uint64_t x83 = ((uint64_t)x82 + x63); + uint64_t x83; uint64_t x84; uint64_t x85; - fiat_p256_mulx_u64(&x84, &x85, x2, (arg1[3])); uint64_t x86; uint64_t x87; - fiat_p256_mulx_u64(&x86, &x87, x2, (arg1[2])); uint64_t x88; uint64_t x89; - fiat_p256_mulx_u64(&x88, &x89, x2, (arg1[1])); uint64_t x90; uint64_t x91; - fiat_p256_mulx_u64(&x90, &x91, x2, (arg1[0])); uint64_t x92; fiat_p256_uint1 x93; - fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); uint64_t x94; fiat_p256_uint1 x95; - fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); uint64_t x96; fiat_p256_uint1 x97; - fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); - uint64_t x98 = (x97 + x85); + uint64_t x98; uint64_t x99; fiat_p256_uint1 x100; - fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); uint64_t x101; fiat_p256_uint1 x102; - fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); uint64_t x103; fiat_p256_uint1 x104; - fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); uint64_t x105; fiat_p256_uint1 x106; - fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); uint64_t x107; fiat_p256_uint1 x108; - fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); uint64_t x109; uint64_t x110; - fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); uint64_t x111; uint64_t x112; - fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); uint64_t x113; uint64_t x114; - fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); uint64_t x115; fiat_p256_uint1 x116; - fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); - uint64_t x117 = (x116 + x112); + uint64_t x117; uint64_t x118; fiat_p256_uint1 x119; - fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); uint64_t x120; fiat_p256_uint1 x121; - fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); uint64_t x122; fiat_p256_uint1 x123; - fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); uint64_t x124; fiat_p256_uint1 x125; - fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); uint64_t x126; fiat_p256_uint1 x127; - fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); - uint64_t x128 = ((uint64_t)x127 + x108); + uint64_t x128; uint64_t x129; uint64_t x130; - fiat_p256_mulx_u64(&x129, &x130, x3, (arg1[3])); uint64_t x131; uint64_t x132; - fiat_p256_mulx_u64(&x131, &x132, x3, (arg1[2])); uint64_t x133; uint64_t x134; - fiat_p256_mulx_u64(&x133, &x134, x3, (arg1[1])); uint64_t x135; uint64_t x136; - fiat_p256_mulx_u64(&x135, &x136, x3, (arg1[0])); uint64_t x137; fiat_p256_uint1 x138; - fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); uint64_t x139; fiat_p256_uint1 x140; - fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); uint64_t x141; fiat_p256_uint1 x142; - fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); - uint64_t x143 = (x142 + x130); + uint64_t x143; uint64_t x144; fiat_p256_uint1 x145; - fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); uint64_t x146; fiat_p256_uint1 x147; - fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); uint64_t x148; fiat_p256_uint1 x149; - fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); uint64_t x150; fiat_p256_uint1 x151; - fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); uint64_t x152; fiat_p256_uint1 x153; - fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); uint64_t x154; uint64_t x155; - fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); uint64_t x156; uint64_t x157; - fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); uint64_t x158; uint64_t x159; - fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); uint64_t x160; fiat_p256_uint1 x161; - fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); - uint64_t x162 = (x161 + x157); + uint64_t x162; uint64_t x163; fiat_p256_uint1 x164; - fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); uint64_t x165; fiat_p256_uint1 x166; - fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); uint64_t x167; fiat_p256_uint1 x168; - fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); uint64_t x169; fiat_p256_uint1 x170; - fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); uint64_t x171; fiat_p256_uint1 x172; - fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); - uint64_t x173 = ((uint64_t)x172 + x153); + uint64_t x173; uint64_t x174; fiat_p256_uint1 x175; - fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); uint64_t x176; fiat_p256_uint1 x177; - fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); uint64_t x178; fiat_p256_uint1 x179; - fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); uint64_t x180; fiat_p256_uint1 x181; - fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); uint64_t x182; fiat_p256_uint1 x183; - fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); uint64_t x184; - fiat_p256_cmovznz_u64(&x184, x183, x174, x165); uint64_t x185; - fiat_p256_cmovznz_u64(&x185, x183, x176, x167); uint64_t x186; - fiat_p256_cmovznz_u64(&x186, x183, x178, x169); uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg1[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg1[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg1[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg1[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg1[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg1[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg1[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg1[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg1[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg1[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg1[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg1[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg1[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg1[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg1[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg1[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); fiat_p256_cmovznz_u64(&x187, x183, x180, x171); out1[0] = x184; out1[1] = x185; @@ -706,6 +770,7 @@ static void fiat_p256_square(uint64_t out1[4], const uint64_t arg1[4]) { /* * The function fiat_p256_add adds two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -713,47 +778,42 @@ static void fiat_p256_square(uint64_t out1[4], const uint64_t arg1[4]) { * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_add(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { uint64_t x1; fiat_p256_uint1 x2; - fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); uint64_t x3; fiat_p256_uint1 x4; - fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); uint64_t x5; fiat_p256_uint1 x6; - fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); uint64_t x7; fiat_p256_uint1 x8; - fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); uint64_t x9; fiat_p256_uint1 x10; - fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); uint64_t x11; fiat_p256_uint1 x12; - fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); uint64_t x13; fiat_p256_uint1 x14; - fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); uint64_t x15; fiat_p256_uint1 x16; - fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); uint64_t x17; fiat_p256_uint1 x18; - fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); uint64_t x19; - fiat_p256_cmovznz_u64(&x19, x18, x9, x1); uint64_t x20; - fiat_p256_cmovznz_u64(&x20, x18, x11, x3); uint64_t x21; - fiat_p256_cmovznz_u64(&x21, x18, x13, x5); uint64_t x22; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); + fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); + fiat_p256_cmovznz_u64(&x19, x18, x9, x1); + fiat_p256_cmovznz_u64(&x20, x18, x11, x3); + fiat_p256_cmovznz_u64(&x21, x18, x13, x5); fiat_p256_cmovznz_u64(&x22, x18, x15, x7); out1[0] = x19; out1[1] = x20; @@ -763,6 +823,7 @@ static void fiat_p256_add(uint64_t out1[4], const uint64_t arg1[4], const uint64 /* * The function fiat_p256_sub subtracts two field elements in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * 0 ≤ eval arg2 < m @@ -770,38 +831,33 @@ static void fiat_p256_add(uint64_t out1[4], const uint64_t arg1[4], const uint64 * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_sub(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { uint64_t x1; fiat_p256_uint1 x2; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); uint64_t x3; fiat_p256_uint1 x4; - fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); uint64_t x5; fiat_p256_uint1 x6; - fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); uint64_t x7; fiat_p256_uint1 x8; - fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); uint64_t x9; - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); uint64_t x10; fiat_p256_uint1 x11; - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, (x9 & UINT64_C(0xffffffffffffffff))); uint64_t x12; fiat_p256_uint1 x13; - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); uint64_t x14; fiat_p256_uint1 x15; - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); uint64_t x16; fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); out1[0] = x10; out1[1] = x12; @@ -811,43 +867,40 @@ static void fiat_p256_sub(uint64_t out1[4], const uint64_t arg1[4], const uint64 /* * The function fiat_p256_opp negates a field element in the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_opp(uint64_t out1[4], const uint64_t arg1[4]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_opp(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { uint64_t x1; fiat_p256_uint1 x2; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, 0x0, (arg1[0])); uint64_t x3; fiat_p256_uint1 x4; - fiat_p256_subborrowx_u64(&x3, &x4, x2, 0x0, (arg1[1])); uint64_t x5; fiat_p256_uint1 x6; - fiat_p256_subborrowx_u64(&x5, &x6, x4, 0x0, (arg1[2])); uint64_t x7; fiat_p256_uint1 x8; - fiat_p256_subborrowx_u64(&x7, &x8, x6, 0x0, (arg1[3])); uint64_t x9; - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); uint64_t x10; fiat_p256_uint1 x11; - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, (x9 & UINT64_C(0xffffffffffffffff))); uint64_t x12; fiat_p256_uint1 x13; - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); uint64_t x14; fiat_p256_uint1 x15; - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); uint64_t x16; fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, 0x0, (arg1[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, 0x0, (arg1[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, 0x0, (arg1[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, 0x0, (arg1[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); out1[0] = x10; out1[1] = x12; @@ -857,153 +910,152 @@ static void fiat_p256_opp(uint64_t out1[4], const uint64_t arg1[4]) { /* * The function fiat_p256_from_montgomery translates a field element out of the Montgomery domain. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: * eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m * 0 ≤ eval out1 < m * - * Input Bounds: - * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] - * Output Bounds: - * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_from_montgomery(uint64_t out1[4], const uint64_t arg1[4]) { - uint64_t x1 = (arg1[0]); +static FIAT_P256_FIAT_INLINE void fiat_p256_from_montgomery(fiat_p256_non_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; uint64_t x2; uint64_t x3; - fiat_p256_mulx_u64(&x2, &x3, x1, UINT64_C(0xffffffff00000001)); uint64_t x4; uint64_t x5; - fiat_p256_mulx_u64(&x4, &x5, x1, UINT32_C(0xffffffff)); uint64_t x6; uint64_t x7; - fiat_p256_mulx_u64(&x6, &x7, x1, UINT64_C(0xffffffffffffffff)); uint64_t x8; fiat_p256_uint1 x9; - fiat_p256_addcarryx_u64(&x8, &x9, 0x0, x7, x4); uint64_t x10; fiat_p256_uint1 x11; - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x6); uint64_t x12; fiat_p256_uint1 x13; - fiat_p256_addcarryx_u64(&x12, &x13, x11, 0x0, x8); uint64_t x14; fiat_p256_uint1 x15; - fiat_p256_addcarryx_u64(&x14, &x15, 0x0, x12, (arg1[1])); uint64_t x16; uint64_t x17; - fiat_p256_mulx_u64(&x16, &x17, x14, UINT64_C(0xffffffff00000001)); uint64_t x18; uint64_t x19; - fiat_p256_mulx_u64(&x18, &x19, x14, UINT32_C(0xffffffff)); uint64_t x20; uint64_t x21; - fiat_p256_mulx_u64(&x20, &x21, x14, UINT64_C(0xffffffffffffffff)); uint64_t x22; fiat_p256_uint1 x23; - fiat_p256_addcarryx_u64(&x22, &x23, 0x0, x21, x18); uint64_t x24; fiat_p256_uint1 x25; - fiat_p256_addcarryx_u64(&x24, &x25, 0x0, x14, x20); uint64_t x26; fiat_p256_uint1 x27; - fiat_p256_addcarryx_u64(&x26, &x27, x25, (x15 + (x13 + (x9 + x5))), x22); uint64_t x28; fiat_p256_uint1 x29; - fiat_p256_addcarryx_u64(&x28, &x29, x27, x2, (x23 + x19)); uint64_t x30; fiat_p256_uint1 x31; - fiat_p256_addcarryx_u64(&x30, &x31, x29, x3, x16); uint64_t x32; fiat_p256_uint1 x33; - fiat_p256_addcarryx_u64(&x32, &x33, 0x0, x26, (arg1[2])); uint64_t x34; fiat_p256_uint1 x35; - fiat_p256_addcarryx_u64(&x34, &x35, x33, x28, 0x0); uint64_t x36; fiat_p256_uint1 x37; - fiat_p256_addcarryx_u64(&x36, &x37, x35, x30, 0x0); uint64_t x38; uint64_t x39; - fiat_p256_mulx_u64(&x38, &x39, x32, UINT64_C(0xffffffff00000001)); uint64_t x40; uint64_t x41; - fiat_p256_mulx_u64(&x40, &x41, x32, UINT32_C(0xffffffff)); uint64_t x42; uint64_t x43; - fiat_p256_mulx_u64(&x42, &x43, x32, UINT64_C(0xffffffffffffffff)); uint64_t x44; fiat_p256_uint1 x45; - fiat_p256_addcarryx_u64(&x44, &x45, 0x0, x43, x40); uint64_t x46; fiat_p256_uint1 x47; - fiat_p256_addcarryx_u64(&x46, &x47, 0x0, x32, x42); uint64_t x48; fiat_p256_uint1 x49; - fiat_p256_addcarryx_u64(&x48, &x49, x47, x34, x44); uint64_t x50; fiat_p256_uint1 x51; - fiat_p256_addcarryx_u64(&x50, &x51, x49, x36, (x45 + x41)); uint64_t x52; fiat_p256_uint1 x53; - fiat_p256_addcarryx_u64(&x52, &x53, x51, (x37 + (x31 + x17)), x38); uint64_t x54; fiat_p256_uint1 x55; - fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x48, (arg1[3])); uint64_t x56; fiat_p256_uint1 x57; - fiat_p256_addcarryx_u64(&x56, &x57, x55, x50, 0x0); uint64_t x58; fiat_p256_uint1 x59; - fiat_p256_addcarryx_u64(&x58, &x59, x57, x52, 0x0); uint64_t x60; uint64_t x61; - fiat_p256_mulx_u64(&x60, &x61, x54, UINT64_C(0xffffffff00000001)); uint64_t x62; uint64_t x63; - fiat_p256_mulx_u64(&x62, &x63, x54, UINT32_C(0xffffffff)); uint64_t x64; uint64_t x65; - fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffffffffffff)); uint64_t x66; fiat_p256_uint1 x67; - fiat_p256_addcarryx_u64(&x66, &x67, 0x0, x65, x62); uint64_t x68; fiat_p256_uint1 x69; - fiat_p256_addcarryx_u64(&x68, &x69, 0x0, x54, x64); uint64_t x70; fiat_p256_uint1 x71; - fiat_p256_addcarryx_u64(&x70, &x71, x69, x56, x66); uint64_t x72; fiat_p256_uint1 x73; - fiat_p256_addcarryx_u64(&x72, &x73, x71, x58, (x67 + x63)); uint64_t x74; fiat_p256_uint1 x75; - fiat_p256_addcarryx_u64(&x74, &x75, x73, (x59 + (x53 + x39)), x60); - uint64_t x76 = (x75 + x61); + uint64_t x76; uint64_t x77; fiat_p256_uint1 x78; - fiat_p256_subborrowx_u64(&x77, &x78, 0x0, x70, UINT64_C(0xffffffffffffffff)); uint64_t x79; fiat_p256_uint1 x80; - fiat_p256_subborrowx_u64(&x79, &x80, x78, x72, UINT32_C(0xffffffff)); uint64_t x81; fiat_p256_uint1 x82; - fiat_p256_subborrowx_u64(&x81, &x82, x80, x74, 0x0); uint64_t x83; fiat_p256_uint1 x84; - fiat_p256_subborrowx_u64(&x83, &x84, x82, x76, UINT64_C(0xffffffff00000001)); uint64_t x85; fiat_p256_uint1 x86; - fiat_p256_subborrowx_u64(&x85, &x86, x84, 0x0, 0x0); uint64_t x87; - fiat_p256_cmovznz_u64(&x87, x86, x77, x70); uint64_t x88; - fiat_p256_cmovznz_u64(&x88, x86, x79, x72); uint64_t x89; - fiat_p256_cmovznz_u64(&x89, x86, x81, x74); uint64_t x90; + x1 = (arg1[0]); + fiat_p256_mulx_u64(&x2, &x3, x1, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x4, &x5, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x6, &x7, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x8, &x9, 0x0, x7, x4); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x6); + fiat_p256_addcarryx_u64(&x12, &x13, x11, 0x0, x8); + fiat_p256_addcarryx_u64(&x14, &x15, 0x0, x12, (arg1[1])); + fiat_p256_mulx_u64(&x16, &x17, x14, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x18, &x19, x14, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x20, &x21, x14, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x22, &x23, 0x0, x21, x18); + fiat_p256_addcarryx_u64(&x24, &x25, 0x0, x14, x20); + fiat_p256_addcarryx_u64(&x26, &x27, x25, (x15 + (x13 + (x9 + x5))), x22); + fiat_p256_addcarryx_u64(&x28, &x29, x27, x2, (x23 + x19)); + fiat_p256_addcarryx_u64(&x30, &x31, x29, x3, x16); + fiat_p256_addcarryx_u64(&x32, &x33, 0x0, x26, (arg1[2])); + fiat_p256_addcarryx_u64(&x34, &x35, x33, x28, 0x0); + fiat_p256_addcarryx_u64(&x36, &x37, x35, x30, 0x0); + fiat_p256_mulx_u64(&x38, &x39, x32, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x40, &x41, x32, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x42, &x43, x32, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x44, &x45, 0x0, x43, x40); + fiat_p256_addcarryx_u64(&x46, &x47, 0x0, x32, x42); + fiat_p256_addcarryx_u64(&x48, &x49, x47, x34, x44); + fiat_p256_addcarryx_u64(&x50, &x51, x49, x36, (x45 + x41)); + fiat_p256_addcarryx_u64(&x52, &x53, x51, (x37 + (x31 + x17)), x38); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x48, (arg1[3])); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x50, 0x0); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x52, 0x0); + fiat_p256_mulx_u64(&x60, &x61, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x62, &x63, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x66, &x67, 0x0, x65, x62); + fiat_p256_addcarryx_u64(&x68, &x69, 0x0, x54, x64); + fiat_p256_addcarryx_u64(&x70, &x71, x69, x56, x66); + fiat_p256_addcarryx_u64(&x72, &x73, x71, x58, (x67 + x63)); + fiat_p256_addcarryx_u64(&x74, &x75, x73, (x59 + (x53 + x39)), x60); + x76 = (x75 + x61); + fiat_p256_subborrowx_u64(&x77, &x78, 0x0, x70, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x79, &x80, x78, x72, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x81, &x82, x80, x74, 0x0); + fiat_p256_subborrowx_u64(&x83, &x84, x82, x76, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x85, &x86, x84, 0x0, 0x0); + fiat_p256_cmovznz_u64(&x87, x86, x77, x70); + fiat_p256_cmovznz_u64(&x88, x86, x79, x72); + fiat_p256_cmovznz_u64(&x89, x86, x81, x74); fiat_p256_cmovznz_u64(&x90, x86, x83, x76); out1[0] = x87; out1[1] = x88; @@ -1011,8 +1063,285 @@ static void fiat_p256_from_montgomery(uint64_t out1[4], const uint64_t arg1[4]) out1[3] = x90; } +/* + * The function fiat_p256_to_montgomery translates a field element into the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = eval arg1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_montgomery(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_non_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + fiat_p256_uint1 x26; + uint64_t x27; + fiat_p256_uint1 x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + fiat_p256_uint1 x66; + uint64_t x67; + fiat_p256_uint1 x68; + uint64_t x69; + fiat_p256_uint1 x70; + uint64_t x71; + fiat_p256_uint1 x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + fiat_p256_uint1 x86; + uint64_t x87; + fiat_p256_uint1 x88; + uint64_t x89; + fiat_p256_uint1 x90; + uint64_t x91; + fiat_p256_uint1 x92; + uint64_t x93; + fiat_p256_uint1 x94; + uint64_t x95; + fiat_p256_uint1 x96; + uint64_t x97; + fiat_p256_uint1 x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint64_t x103; + uint64_t x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + fiat_p256_uint1 x110; + uint64_t x111; + fiat_p256_uint1 x112; + uint64_t x113; + fiat_p256_uint1 x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + fiat_p256_uint1 x126; + uint64_t x127; + fiat_p256_uint1 x128; + uint64_t x129; + fiat_p256_uint1 x130; + uint64_t x131; + fiat_p256_uint1 x132; + uint64_t x133; + fiat_p256_uint1 x134; + uint64_t x135; + fiat_p256_uint1 x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + uint64_t x140; + uint64_t x141; + uint64_t x142; + uint64_t x143; + uint64_t x144; + uint64_t x145; + fiat_p256_uint1 x146; + uint64_t x147; + fiat_p256_uint1 x148; + uint64_t x149; + fiat_p256_uint1 x150; + uint64_t x151; + fiat_p256_uint1 x152; + uint64_t x153; + fiat_p256_uint1 x154; + uint64_t x155; + fiat_p256_uint1 x156; + uint64_t x157; + fiat_p256_uint1 x158; + uint64_t x159; + fiat_p256_uint1 x160; + uint64_t x161; + fiat_p256_uint1 x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + uint64_t x168; + uint64_t x169; + uint64_t x170; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x7, &x8, x4, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x9, &x10, x4, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x11, &x12, x4, 0x3); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + fiat_p256_mulx_u64(&x19, &x20, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x21, &x22, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x23, &x24, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u64(&x27, &x28, 0x0, x11, x23); + fiat_p256_addcarryx_u64(&x29, &x30, x28, x13, x25); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x15, (x26 + x22)); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x17, x19); + fiat_p256_addcarryx_u64(&x35, &x36, x34, (x18 + x6), x20); + fiat_p256_mulx_u64(&x37, &x38, x1, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x39, &x40, x1, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x41, &x42, x1, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x43, &x44, x1, 0x3); + fiat_p256_addcarryx_u64(&x45, &x46, 0x0, x44, x41); + fiat_p256_addcarryx_u64(&x47, &x48, x46, x42, x39); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x40, x37); + fiat_p256_addcarryx_u64(&x51, &x52, 0x0, x29, x43); + fiat_p256_addcarryx_u64(&x53, &x54, x52, x31, x45); + fiat_p256_addcarryx_u64(&x55, &x56, x54, x33, x47); + fiat_p256_addcarryx_u64(&x57, &x58, x56, x35, x49); + fiat_p256_mulx_u64(&x59, &x60, x51, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x61, &x62, x51, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x63, &x64, x51, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x65, &x66, 0x0, x64, x61); + fiat_p256_addcarryx_u64(&x67, &x68, 0x0, x51, x63); + fiat_p256_addcarryx_u64(&x69, &x70, x68, x53, x65); + fiat_p256_addcarryx_u64(&x71, &x72, x70, x55, (x66 + x62)); + fiat_p256_addcarryx_u64(&x73, &x74, x72, x57, x59); + fiat_p256_addcarryx_u64(&x75, &x76, x74, (((uint64_t)x58 + x36) + (x50 + x38)), x60); + fiat_p256_mulx_u64(&x77, &x78, x2, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x79, &x80, x2, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x81, &x82, x2, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x83, &x84, x2, 0x3); + fiat_p256_addcarryx_u64(&x85, &x86, 0x0, x84, x81); + fiat_p256_addcarryx_u64(&x87, &x88, x86, x82, x79); + fiat_p256_addcarryx_u64(&x89, &x90, x88, x80, x77); + fiat_p256_addcarryx_u64(&x91, &x92, 0x0, x69, x83); + fiat_p256_addcarryx_u64(&x93, &x94, x92, x71, x85); + fiat_p256_addcarryx_u64(&x95, &x96, x94, x73, x87); + fiat_p256_addcarryx_u64(&x97, &x98, x96, x75, x89); + fiat_p256_mulx_u64(&x99, &x100, x91, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x101, &x102, x91, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x103, &x104, x91, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x105, &x106, 0x0, x104, x101); + fiat_p256_addcarryx_u64(&x107, &x108, 0x0, x91, x103); + fiat_p256_addcarryx_u64(&x109, &x110, x108, x93, x105); + fiat_p256_addcarryx_u64(&x111, &x112, x110, x95, (x106 + x102)); + fiat_p256_addcarryx_u64(&x113, &x114, x112, x97, x99); + fiat_p256_addcarryx_u64(&x115, &x116, x114, (((uint64_t)x98 + x76) + (x90 + x78)), x100); + fiat_p256_mulx_u64(&x117, &x118, x3, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x119, &x120, x3, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x121, &x122, x3, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x123, &x124, x3, 0x3); + fiat_p256_addcarryx_u64(&x125, &x126, 0x0, x124, x121); + fiat_p256_addcarryx_u64(&x127, &x128, x126, x122, x119); + fiat_p256_addcarryx_u64(&x129, &x130, x128, x120, x117); + fiat_p256_addcarryx_u64(&x131, &x132, 0x0, x109, x123); + fiat_p256_addcarryx_u64(&x133, &x134, x132, x111, x125); + fiat_p256_addcarryx_u64(&x135, &x136, x134, x113, x127); + fiat_p256_addcarryx_u64(&x137, &x138, x136, x115, x129); + fiat_p256_mulx_u64(&x139, &x140, x131, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x141, &x142, x131, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x143, &x144, x131, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x145, &x146, 0x0, x144, x141); + fiat_p256_addcarryx_u64(&x147, &x148, 0x0, x131, x143); + fiat_p256_addcarryx_u64(&x149, &x150, x148, x133, x145); + fiat_p256_addcarryx_u64(&x151, &x152, x150, x135, (x146 + x142)); + fiat_p256_addcarryx_u64(&x153, &x154, x152, x137, x139); + fiat_p256_addcarryx_u64(&x155, &x156, x154, (((uint64_t)x138 + x116) + (x130 + x118)), x140); + fiat_p256_subborrowx_u64(&x157, &x158, 0x0, x149, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x159, &x160, x158, x151, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x161, &x162, x160, x153, 0x0); + fiat_p256_subborrowx_u64(&x163, &x164, x162, x155, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x165, &x166, x164, x156, 0x0); + fiat_p256_cmovznz_u64(&x167, x166, x157, x149); + fiat_p256_cmovznz_u64(&x168, x166, x159, x151); + fiat_p256_cmovznz_u64(&x169, x166, x161, x153); + fiat_p256_cmovznz_u64(&x170, x166, x163, x155); + out1[0] = x167; + out1[1] = x168; + out1[2] = x169; + out1[3] = x170; +} + /* * The function fiat_p256_nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: @@ -1023,13 +1352,15 @@ static void fiat_p256_from_montgomery(uint64_t out1[4], const uint64_t arg1[4]) * Output Bounds: * out1: [0x0 ~> 0xffffffffffffffff] */ -static void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { - uint64_t x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | (uint64_t)0x0)))); +static FIAT_P256_FIAT_INLINE void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { + uint64_t x1; + x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); *out1 = x1; } /* * The function fiat_p256_selectznz is a multi-limb conditional select. + * * Postconditions: * eval out1 = (if arg1 = 0 then eval arg2 else eval arg3) * @@ -1040,14 +1371,14 @@ static void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { +static FIAT_P256_FIAT_INLINE void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { uint64_t x1; - fiat_p256_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); uint64_t x2; - fiat_p256_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); uint64_t x3; - fiat_p256_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); uint64_t x4; + fiat_p256_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); fiat_p256_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); out1[0] = x1; out1[1] = x2; @@ -1056,7 +1387,8 @@ static void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const ui } /* - * The function fiat_p256_to_bytes serializes a field element in the Montgomery domain to bytes in little-endian order. + * The function fiat_p256_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. + * * Preconditions: * 0 ≤ eval arg1 < m * Postconditions: @@ -1067,106 +1399,164 @@ static void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const ui * Output Bounds: * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] */ -static void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { - uint64_t x1 = (arg1[3]); - uint64_t x2 = (arg1[2]); - uint64_t x3 = (arg1[1]); - uint64_t x4 = (arg1[0]); - uint64_t x5 = (x4 >> 8); - uint8_t x6 = (uint8_t)(x4 & UINT8_C(0xff)); - uint64_t x7 = (x5 >> 8); - uint8_t x8 = (uint8_t)(x5 & UINT8_C(0xff)); - uint64_t x9 = (x7 >> 8); - uint8_t x10 = (uint8_t)(x7 & UINT8_C(0xff)); - uint64_t x11 = (x9 >> 8); - uint8_t x12 = (uint8_t)(x9 & UINT8_C(0xff)); - uint64_t x13 = (x11 >> 8); - uint8_t x14 = (uint8_t)(x11 & UINT8_C(0xff)); - uint64_t x15 = (x13 >> 8); - uint8_t x16 = (uint8_t)(x13 & UINT8_C(0xff)); - uint8_t x17 = (uint8_t)(x15 >> 8); - uint8_t x18 = (uint8_t)(x15 & UINT8_C(0xff)); - uint8_t x19 = (uint8_t)(x17 & UINT8_C(0xff)); - uint64_t x20 = (x3 >> 8); - uint8_t x21 = (uint8_t)(x3 & UINT8_C(0xff)); - uint64_t x22 = (x20 >> 8); - uint8_t x23 = (uint8_t)(x20 & UINT8_C(0xff)); - uint64_t x24 = (x22 >> 8); - uint8_t x25 = (uint8_t)(x22 & UINT8_C(0xff)); - uint64_t x26 = (x24 >> 8); - uint8_t x27 = (uint8_t)(x24 & UINT8_C(0xff)); - uint64_t x28 = (x26 >> 8); - uint8_t x29 = (uint8_t)(x26 & UINT8_C(0xff)); - uint64_t x30 = (x28 >> 8); - uint8_t x31 = (uint8_t)(x28 & UINT8_C(0xff)); - uint8_t x32 = (uint8_t)(x30 >> 8); - uint8_t x33 = (uint8_t)(x30 & UINT8_C(0xff)); - uint8_t x34 = (uint8_t)(x32 & UINT8_C(0xff)); - uint64_t x35 = (x2 >> 8); - uint8_t x36 = (uint8_t)(x2 & UINT8_C(0xff)); - uint64_t x37 = (x35 >> 8); - uint8_t x38 = (uint8_t)(x35 & UINT8_C(0xff)); - uint64_t x39 = (x37 >> 8); - uint8_t x40 = (uint8_t)(x37 & UINT8_C(0xff)); - uint64_t x41 = (x39 >> 8); - uint8_t x42 = (uint8_t)(x39 & UINT8_C(0xff)); - uint64_t x43 = (x41 >> 8); - uint8_t x44 = (uint8_t)(x41 & UINT8_C(0xff)); - uint64_t x45 = (x43 >> 8); - uint8_t x46 = (uint8_t)(x43 & UINT8_C(0xff)); - uint8_t x47 = (uint8_t)(x45 >> 8); - uint8_t x48 = (uint8_t)(x45 & UINT8_C(0xff)); - uint8_t x49 = (uint8_t)(x47 & UINT8_C(0xff)); - uint64_t x50 = (x1 >> 8); - uint8_t x51 = (uint8_t)(x1 & UINT8_C(0xff)); - uint64_t x52 = (x50 >> 8); - uint8_t x53 = (uint8_t)(x50 & UINT8_C(0xff)); - uint64_t x54 = (x52 >> 8); - uint8_t x55 = (uint8_t)(x52 & UINT8_C(0xff)); - uint64_t x56 = (x54 >> 8); - uint8_t x57 = (uint8_t)(x54 & UINT8_C(0xff)); - uint64_t x58 = (x56 >> 8); - uint8_t x59 = (uint8_t)(x56 & UINT8_C(0xff)); - uint64_t x60 = (x58 >> 8); - uint8_t x61 = (uint8_t)(x58 & UINT8_C(0xff)); - uint8_t x62 = (uint8_t)(x60 >> 8); - uint8_t x63 = (uint8_t)(x60 & UINT8_C(0xff)); - out1[0] = x6; - out1[1] = x8; - out1[2] = x10; - out1[3] = x12; - out1[4] = x14; - out1[5] = x16; - out1[6] = x18; - out1[7] = x19; - out1[8] = x21; - out1[9] = x23; - out1[10] = x25; - out1[11] = x27; - out1[12] = x29; - out1[13] = x31; - out1[14] = x33; - out1[15] = x34; - out1[16] = x36; - out1[17] = x38; - out1[18] = x40; - out1[19] = x42; - out1[20] = x44; - out1[21] = x46; - out1[22] = x48; - out1[23] = x49; - out1[24] = x51; - out1[25] = x53; - out1[26] = x55; - out1[27] = x57; - out1[28] = x59; - out1[29] = x61; - out1[30] = x63; - out1[31] = x62; +static FIAT_P256_FIAT_INLINE void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint8_t x5; + uint64_t x6; + uint8_t x7; + uint64_t x8; + uint8_t x9; + uint64_t x10; + uint8_t x11; + uint64_t x12; + uint8_t x13; + uint64_t x14; + uint8_t x15; + uint64_t x16; + uint8_t x17; + uint8_t x18; + uint8_t x19; + uint64_t x20; + uint8_t x21; + uint64_t x22; + uint8_t x23; + uint64_t x24; + uint8_t x25; + uint64_t x26; + uint8_t x27; + uint64_t x28; + uint8_t x29; + uint64_t x30; + uint8_t x31; + uint8_t x32; + uint8_t x33; + uint64_t x34; + uint8_t x35; + uint64_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint8_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint64_t x50; + uint8_t x51; + uint64_t x52; + uint8_t x53; + uint64_t x54; + uint8_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint8_t x59; + uint8_t x60; + x1 = (arg1[3]); + x2 = (arg1[2]); + x3 = (arg1[1]); + x4 = (arg1[0]); + x5 = (uint8_t)(x4 & UINT8_C(0xff)); + x6 = (x4 >> 8); + x7 = (uint8_t)(x6 & UINT8_C(0xff)); + x8 = (x6 >> 8); + x9 = (uint8_t)(x8 & UINT8_C(0xff)); + x10 = (x8 >> 8); + x11 = (uint8_t)(x10 & UINT8_C(0xff)); + x12 = (x10 >> 8); + x13 = (uint8_t)(x12 & UINT8_C(0xff)); + x14 = (x12 >> 8); + x15 = (uint8_t)(x14 & UINT8_C(0xff)); + x16 = (x14 >> 8); + x17 = (uint8_t)(x16 & UINT8_C(0xff)); + x18 = (uint8_t)(x16 >> 8); + x19 = (uint8_t)(x3 & UINT8_C(0xff)); + x20 = (x3 >> 8); + x21 = (uint8_t)(x20 & UINT8_C(0xff)); + x22 = (x20 >> 8); + x23 = (uint8_t)(x22 & UINT8_C(0xff)); + x24 = (x22 >> 8); + x25 = (uint8_t)(x24 & UINT8_C(0xff)); + x26 = (x24 >> 8); + x27 = (uint8_t)(x26 & UINT8_C(0xff)); + x28 = (x26 >> 8); + x29 = (uint8_t)(x28 & UINT8_C(0xff)); + x30 = (x28 >> 8); + x31 = (uint8_t)(x30 & UINT8_C(0xff)); + x32 = (uint8_t)(x30 >> 8); + x33 = (uint8_t)(x2 & UINT8_C(0xff)); + x34 = (x2 >> 8); + x35 = (uint8_t)(x34 & UINT8_C(0xff)); + x36 = (x34 >> 8); + x37 = (uint8_t)(x36 & UINT8_C(0xff)); + x38 = (x36 >> 8); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (uint8_t)(x44 >> 8); + x47 = (uint8_t)(x1 & UINT8_C(0xff)); + x48 = (x1 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (x48 >> 8); + x51 = (uint8_t)(x50 & UINT8_C(0xff)); + x52 = (x50 >> 8); + x53 = (uint8_t)(x52 & UINT8_C(0xff)); + x54 = (x52 >> 8); + x55 = (uint8_t)(x54 & UINT8_C(0xff)); + x56 = (x54 >> 8); + x57 = (uint8_t)(x56 & UINT8_C(0xff)); + x58 = (x56 >> 8); + x59 = (uint8_t)(x58 & UINT8_C(0xff)); + x60 = (uint8_t)(x58 >> 8); + out1[0] = x5; + out1[1] = x7; + out1[2] = x9; + out1[3] = x11; + out1[4] = x13; + out1[5] = x15; + out1[6] = x17; + out1[7] = x18; + out1[8] = x19; + out1[9] = x21; + out1[10] = x23; + out1[11] = x25; + out1[12] = x27; + out1[13] = x29; + out1[14] = x31; + out1[15] = x32; + out1[16] = x33; + out1[17] = x35; + out1[18] = x37; + out1[19] = x39; + out1[20] = x41; + out1[21] = x43; + out1[22] = x45; + out1[23] = x46; + out1[24] = x47; + out1[25] = x49; + out1[26] = x51; + out1[27] = x53; + out1[28] = x55; + out1[29] = x57; + out1[30] = x59; + out1[31] = x60; } /* - * The function fiat_p256_from_bytes deserializes a field element in the Montgomery domain from bytes in little-endian order. + * The function fiat_p256_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. + * * Preconditions: * 0 ≤ bytes_eval arg1 < m * Postconditions: @@ -1178,49 +1568,444 @@ static void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { * Output Bounds: * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ -static void fiat_p256_from_bytes(uint64_t out1[4], const uint8_t arg1[32]) { - uint64_t x1 = ((uint64_t)(arg1[31]) << 56); - uint64_t x2 = ((uint64_t)(arg1[30]) << 48); - uint64_t x3 = ((uint64_t)(arg1[29]) << 40); - uint64_t x4 = ((uint64_t)(arg1[28]) << 32); - uint64_t x5 = ((uint64_t)(arg1[27]) << 24); - uint64_t x6 = ((uint64_t)(arg1[26]) << 16); - uint64_t x7 = ((uint64_t)(arg1[25]) << 8); - uint8_t x8 = (arg1[24]); - uint64_t x9 = ((uint64_t)(arg1[23]) << 56); - uint64_t x10 = ((uint64_t)(arg1[22]) << 48); - uint64_t x11 = ((uint64_t)(arg1[21]) << 40); - uint64_t x12 = ((uint64_t)(arg1[20]) << 32); - uint64_t x13 = ((uint64_t)(arg1[19]) << 24); - uint64_t x14 = ((uint64_t)(arg1[18]) << 16); - uint64_t x15 = ((uint64_t)(arg1[17]) << 8); - uint8_t x16 = (arg1[16]); - uint64_t x17 = ((uint64_t)(arg1[15]) << 56); - uint64_t x18 = ((uint64_t)(arg1[14]) << 48); - uint64_t x19 = ((uint64_t)(arg1[13]) << 40); - uint64_t x20 = ((uint64_t)(arg1[12]) << 32); - uint64_t x21 = ((uint64_t)(arg1[11]) << 24); - uint64_t x22 = ((uint64_t)(arg1[10]) << 16); - uint64_t x23 = ((uint64_t)(arg1[9]) << 8); - uint8_t x24 = (arg1[8]); - uint64_t x25 = ((uint64_t)(arg1[7]) << 56); - uint64_t x26 = ((uint64_t)(arg1[6]) << 48); - uint64_t x27 = ((uint64_t)(arg1[5]) << 40); - uint64_t x28 = ((uint64_t)(arg1[4]) << 32); - uint64_t x29 = ((uint64_t)(arg1[3]) << 24); - uint64_t x30 = ((uint64_t)(arg1[2]) << 16); - uint64_t x31 = ((uint64_t)(arg1[1]) << 8); - uint8_t x32 = (arg1[0]); - uint64_t x33 = (x32 + (x31 + (x30 + (x29 + (x28 + (x27 + (x26 + x25))))))); - uint64_t x34 = (x33 & UINT64_C(0xffffffffffffffff)); - uint64_t x35 = (x8 + (x7 + (x6 + (x5 + (x4 + (x3 + (x2 + x1))))))); - uint64_t x36 = (x16 + (x15 + (x14 + (x13 + (x12 + (x11 + (x10 + x9))))))); - uint64_t x37 = (x24 + (x23 + (x22 + (x21 + (x20 + (x19 + (x18 + x17))))))); - uint64_t x38 = (x37 & UINT64_C(0xffffffffffffffff)); - uint64_t x39 = (x36 & UINT64_C(0xffffffffffffffff)); - out1[0] = x34; - out1[1] = x38; - out1[2] = x39; - out1[3] = x35; +static FIAT_P256_FIAT_INLINE void fiat_p256_from_bytes(uint64_t out1[4], const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint8_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint8_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint8_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + x1 = ((uint64_t)(arg1[31]) << 56); + x2 = ((uint64_t)(arg1[30]) << 48); + x3 = ((uint64_t)(arg1[29]) << 40); + x4 = ((uint64_t)(arg1[28]) << 32); + x5 = ((uint64_t)(arg1[27]) << 24); + x6 = ((uint64_t)(arg1[26]) << 16); + x7 = ((uint64_t)(arg1[25]) << 8); + x8 = (arg1[24]); + x9 = ((uint64_t)(arg1[23]) << 56); + x10 = ((uint64_t)(arg1[22]) << 48); + x11 = ((uint64_t)(arg1[21]) << 40); + x12 = ((uint64_t)(arg1[20]) << 32); + x13 = ((uint64_t)(arg1[19]) << 24); + x14 = ((uint64_t)(arg1[18]) << 16); + x15 = ((uint64_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint64_t)(arg1[15]) << 56); + x18 = ((uint64_t)(arg1[14]) << 48); + x19 = ((uint64_t)(arg1[13]) << 40); + x20 = ((uint64_t)(arg1[12]) << 32); + x21 = ((uint64_t)(arg1[11]) << 24); + x22 = ((uint64_t)(arg1[10]) << 16); + x23 = ((uint64_t)(arg1[9]) << 8); + x24 = (arg1[8]); + x25 = ((uint64_t)(arg1[7]) << 56); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x25 + x38); + x40 = (x23 + (uint64_t)x24); + x41 = (x22 + x40); + x42 = (x21 + x41); + x43 = (x20 + x42); + x44 = (x19 + x43); + x45 = (x18 + x44); + x46 = (x17 + x45); + x47 = (x15 + (uint64_t)x16); + x48 = (x14 + x47); + x49 = (x13 + x48); + x50 = (x12 + x49); + x51 = (x11 + x50); + x52 = (x10 + x51); + x53 = (x9 + x52); + x54 = (x7 + (uint64_t)x8); + x55 = (x6 + x54); + x56 = (x5 + x55); + x57 = (x4 + x56); + x58 = (x3 + x57); + x59 = (x2 + x58); + x60 = (x1 + x59); + out1[0] = x39; + out1[1] = x46; + out1[2] = x53; + out1[3] = x60; } +/* + * The function fiat_p256_set_one returns the field element one in the Montgomery domain. + * + * Postconditions: + * eval (from_montgomery out1) mod m = 1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_set_one(fiat_p256_montgomery_domain_field_element out1) { + out1[0] = 0x1; + out1[1] = UINT64_C(0xffffffff00000000); + out1[2] = UINT64_C(0xffffffffffffffff); + out1[3] = UINT32_C(0xfffffffe); +} + +/* + * The function fiat_p256_msat returns the saturated representation of the prime modulus. + * + * Postconditions: + * twos_complement_eval out1 = m + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_msat(uint64_t out1[5]) { + out1[0] = UINT64_C(0xffffffffffffffff); + out1[1] = UINT32_C(0xffffffff); + out1[2] = 0x0; + out1[3] = UINT64_C(0xffffffff00000001); + out1[4] = 0x0; +} + +/* + * The function fiat_p256_divstep computes a divstep. + * + * Preconditions: + * 0 ≤ eval arg4 < m + * 0 ≤ eval arg5 < m + * Postconditions: + * out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) + * twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) + * twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) + * eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) + * eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) + * 0 ≤ eval out5 < m + * 0 ≤ eval out5 < m + * 0 ≤ eval out2 < m + * 0 ≤ eval out3 < m + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep(uint64_t* out1, uint64_t out2[5], uint64_t out3[5], uint64_t out4[4], uint64_t out5[4], uint64_t arg1, const uint64_t arg2[5], const uint64_t arg3[5], const uint64_t arg4[4], const uint64_t arg5[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_uint1 x3; + uint64_t x4; + fiat_p256_uint1 x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + uint64_t x18; + fiat_p256_uint1 x19; + uint64_t x20; + fiat_p256_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + fiat_p256_uint1 x40; + uint64_t x41; + fiat_p256_uint1 x42; + uint64_t x43; + fiat_p256_uint1 x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + fiat_p256_uint1 x60; + uint64_t x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + fiat_p256_uint1 x65; + uint64_t x66; + fiat_p256_uint1 x67; + uint64_t x68; + fiat_p256_uint1 x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + uint64_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + fiat_p256_uint1 x81; + uint64_t x82; + fiat_p256_uint1 x83; + uint64_t x84; + fiat_p256_uint1 x85; + uint64_t x86; + fiat_p256_uint1 x87; + uint64_t x88; + fiat_p256_uint1 x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + uint64_t x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + fiat_p256_uint1 x99; + uint64_t x100; + fiat_p256_uint1 x101; + uint64_t x102; + fiat_p256_uint1 x103; + uint64_t x104; + fiat_p256_uint1 x105; + uint64_t x106; + fiat_p256_uint1 x107; + uint64_t x108; + fiat_p256_uint1 x109; + uint64_t x110; + fiat_p256_uint1 x111; + uint64_t x112; + fiat_p256_uint1 x113; + uint64_t x114; + uint64_t x115; + uint64_t x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + uint64_t x126; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (~arg1), 0x1); + x3 = (fiat_p256_uint1)((fiat_p256_uint1)(x1 >> 63) & (fiat_p256_uint1)((arg3[0]) & 0x1)); + fiat_p256_addcarryx_u64(&x4, &x5, 0x0, (~arg1), 0x1); + fiat_p256_cmovznz_u64(&x6, x3, arg1, x4); + fiat_p256_cmovznz_u64(&x7, x3, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x8, x3, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x9, x3, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u64(&x10, x3, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u64(&x11, x3, (arg2[4]), (arg3[4])); + fiat_p256_addcarryx_u64(&x12, &x13, 0x0, 0x1, (~(arg2[0]))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, (~(arg2[1]))); + fiat_p256_addcarryx_u64(&x16, &x17, x15, 0x0, (~(arg2[2]))); + fiat_p256_addcarryx_u64(&x18, &x19, x17, 0x0, (~(arg2[3]))); + fiat_p256_addcarryx_u64(&x20, &x21, x19, 0x0, (~(arg2[4]))); + fiat_p256_cmovznz_u64(&x22, x3, (arg3[0]), x12); + fiat_p256_cmovznz_u64(&x23, x3, (arg3[1]), x14); + fiat_p256_cmovznz_u64(&x24, x3, (arg3[2]), x16); + fiat_p256_cmovznz_u64(&x25, x3, (arg3[3]), x18); + fiat_p256_cmovznz_u64(&x26, x3, (arg3[4]), x20); + fiat_p256_cmovznz_u64(&x27, x3, (arg4[0]), (arg5[0])); + fiat_p256_cmovznz_u64(&x28, x3, (arg4[1]), (arg5[1])); + fiat_p256_cmovznz_u64(&x29, x3, (arg4[2]), (arg5[2])); + fiat_p256_cmovznz_u64(&x30, x3, (arg4[3]), (arg5[3])); + fiat_p256_addcarryx_u64(&x31, &x32, 0x0, x27, x27); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x28, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x29, x29); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x30, x30); + fiat_p256_subborrowx_u64(&x39, &x40, 0x0, x31, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x41, &x42, x40, x33, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x43, &x44, x42, x35, 0x0); + fiat_p256_subborrowx_u64(&x45, &x46, x44, x37, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x47, &x48, x46, x38, 0x0); + x49 = (arg4[3]); + x50 = (arg4[2]); + x51 = (arg4[1]); + x52 = (arg4[0]); + fiat_p256_subborrowx_u64(&x53, &x54, 0x0, 0x0, x52); + fiat_p256_subborrowx_u64(&x55, &x56, x54, 0x0, x51); + fiat_p256_subborrowx_u64(&x57, &x58, x56, 0x0, x50); + fiat_p256_subborrowx_u64(&x59, &x60, x58, 0x0, x49); + fiat_p256_cmovznz_u64(&x61, x60, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x62, &x63, 0x0, x53, x61); + fiat_p256_addcarryx_u64(&x64, &x65, x63, x55, (x61 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x66, &x67, x65, x57, 0x0); + fiat_p256_addcarryx_u64(&x68, &x69, x67, x59, (x61 & UINT64_C(0xffffffff00000001))); + fiat_p256_cmovznz_u64(&x70, x3, (arg5[0]), x62); + fiat_p256_cmovznz_u64(&x71, x3, (arg5[1]), x64); + fiat_p256_cmovznz_u64(&x72, x3, (arg5[2]), x66); + fiat_p256_cmovznz_u64(&x73, x3, (arg5[3]), x68); + x74 = (fiat_p256_uint1)(x22 & 0x1); + fiat_p256_cmovznz_u64(&x75, x74, 0x0, x7); + fiat_p256_cmovznz_u64(&x76, x74, 0x0, x8); + fiat_p256_cmovznz_u64(&x77, x74, 0x0, x9); + fiat_p256_cmovznz_u64(&x78, x74, 0x0, x10); + fiat_p256_cmovznz_u64(&x79, x74, 0x0, x11); + fiat_p256_addcarryx_u64(&x80, &x81, 0x0, x22, x75); + fiat_p256_addcarryx_u64(&x82, &x83, x81, x23, x76); + fiat_p256_addcarryx_u64(&x84, &x85, x83, x24, x77); + fiat_p256_addcarryx_u64(&x86, &x87, x85, x25, x78); + fiat_p256_addcarryx_u64(&x88, &x89, x87, x26, x79); + fiat_p256_cmovznz_u64(&x90, x74, 0x0, x27); + fiat_p256_cmovznz_u64(&x91, x74, 0x0, x28); + fiat_p256_cmovznz_u64(&x92, x74, 0x0, x29); + fiat_p256_cmovznz_u64(&x93, x74, 0x0, x30); + fiat_p256_addcarryx_u64(&x94, &x95, 0x0, x70, x90); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x71, x91); + fiat_p256_addcarryx_u64(&x98, &x99, x97, x72, x92); + fiat_p256_addcarryx_u64(&x100, &x101, x99, x73, x93); + fiat_p256_subborrowx_u64(&x102, &x103, 0x0, x94, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x104, &x105, x103, x96, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x106, &x107, x105, x98, 0x0); + fiat_p256_subborrowx_u64(&x108, &x109, x107, x100, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x110, &x111, x109, x101, 0x0); + fiat_p256_addcarryx_u64(&x112, &x113, 0x0, x6, 0x1); + x114 = ((x80 >> 1) | ((x82 << 63) & UINT64_C(0xffffffffffffffff))); + x115 = ((x82 >> 1) | ((x84 << 63) & UINT64_C(0xffffffffffffffff))); + x116 = ((x84 >> 1) | ((x86 << 63) & UINT64_C(0xffffffffffffffff))); + x117 = ((x86 >> 1) | ((x88 << 63) & UINT64_C(0xffffffffffffffff))); + x118 = ((x88 & UINT64_C(0x8000000000000000)) | (x88 >> 1)); + fiat_p256_cmovznz_u64(&x119, x48, x39, x31); + fiat_p256_cmovznz_u64(&x120, x48, x41, x33); + fiat_p256_cmovznz_u64(&x121, x48, x43, x35); + fiat_p256_cmovznz_u64(&x122, x48, x45, x37); + fiat_p256_cmovznz_u64(&x123, x111, x102, x94); + fiat_p256_cmovznz_u64(&x124, x111, x104, x96); + fiat_p256_cmovznz_u64(&x125, x111, x106, x98); + fiat_p256_cmovznz_u64(&x126, x111, x108, x100); + *out1 = x112; + out2[0] = x7; + out2[1] = x8; + out2[2] = x9; + out2[3] = x10; + out2[4] = x11; + out3[0] = x114; + out3[1] = x115; + out3[2] = x116; + out3[3] = x117; + out3[4] = x118; + out4[0] = x119; + out4[1] = x120; + out4[2] = x121; + out4[3] = x122; + out5[0] = x123; + out5[1] = x124; + out5[2] = x125; + out5[3] = x126; +} + +/* + * The function fiat_p256_divstep_precomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). + * + * Postconditions: + * eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep_precomp(uint64_t out1[4]) { + out1[0] = UINT64_C(0x67ffffffb8000000); + out1[1] = UINT64_C(0xc000000038000000); + out1[2] = UINT64_C(0xd80000007fffffff); + out1[3] = UINT64_C(0x2fffffffffffffff); +} diff --git a/third_party/boringssl/kit/src/third_party/fiat/p256_64_msvc.h b/third_party/boringssl/kit/src/third_party/fiat/p256_64_msvc.h new file mode 100644 index 00000000..8b65a373 --- /dev/null +++ b/third_party/boringssl/kit/src/third_party/fiat/p256_64_msvc.h @@ -0,0 +1,2002 @@ +/* Autogenerated: 'src/ExtractionOCaml/word_by_word_montgomery' --inline --static --use-value-barrier --no-wide-int p256 64 '2^256 - 2^224 + 2^192 + 2^96 - 1' mul square add sub opp from_montgomery to_montgomery nonzero selectznz to_bytes from_bytes one msat divstep divstep_precomp */ +/* curve description: p256 */ +/* machine_wordsize = 64 (from "64") */ +/* requested operations: mul, square, add, sub, opp, from_montgomery, to_montgomery, nonzero, selectznz, to_bytes, from_bytes, one, msat, divstep, divstep_precomp */ +/* m = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (from "2^256 - 2^224 + 2^192 + 2^96 - 1") */ +/* */ +/* NOTE: In addition to the bounds specified above each function, all */ +/* functions synthesized for this Montgomery arithmetic require the */ +/* input to be strictly less than the prime modulus (m), and also */ +/* require the input to be in the unique saturated representation. */ +/* All functions also ensure that these two properties are true of */ +/* return values. */ +/* */ +/* Computed values: */ +/* eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) */ +/* bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) */ +/* twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in */ +/* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ + +#include +#include +#if defined(_M_X64) +#include +#endif + +typedef unsigned char fiat_p256_uint1; +typedef signed char fiat_p256_int1; + +#define FIAT_P256_FIAT_INLINE inline + +/* The type fiat_p256_montgomery_domain_field_element is a field element in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_montgomery_domain_field_element[4]; + +/* The type fiat_p256_non_montgomery_domain_field_element is a field element NOT in the Montgomery domain. */ +/* Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] */ +typedef uint64_t fiat_p256_non_montgomery_domain_field_element[4]; + +#if (-1 & 3) != 3 +#error "This code only works on a two's complement system" +#endif + +#define fiat_p256_value_barrier_u64(x) (x) + + +/* + * The function fiat_p256_addcarryx_u64 is an addition with carry. + * + * Postconditions: + * out1 = (arg1 + arg2 + arg3) mod 2^64 + * out2 = ⌊(arg1 + arg2 + arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { +#if defined(_M_X64) + *out2 = _addcarry_u64(arg1, arg2, arg3, out1); +#else + arg2 += arg1; + arg1 = arg2 < arg1; + arg3 += arg2; + arg1 += arg3 < arg2; + *out1 = arg3; + *out2 = arg1; +#endif +} + +/* + * The function fiat_p256_subborrowx_u64 is a subtraction with borrow. + * + * Postconditions: + * out1 = (-arg1 + arg2 + -arg3) mod 2^64 + * out2 = -⌊(-arg1 + arg2 + -arg3) / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { +#if defined(_M_X64) + *out2 = _subborrow_u64(arg1, arg2, arg3, out1); // NOTE: edited after generation +#else + *out1 = arg2 - arg3 - arg1; + *out2 = (arg2 < arg3) | ((arg2 == arg3) & arg1); +#endif +} + +/* + * The function fiat_p256_mulx_u64 is a multiplication, returning the full double-width result. + * + * Postconditions: + * out1 = (arg1 * arg2) mod 2^64 + * out2 = ⌊arg1 * arg2 / 2^64⌋ + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { +// NOTE: edited after generation +#if defined(_M_X64) + *out1 = _umul128(arg1, arg2, out2); +#elif defined(_M_ARM64) + *out1 = arg1 * arg2; + *out2 = __umulh(arg1, arg2); +#else +#error "This file is intended for MSVC on X64 or ARM64" +#endif +} + +/* + * The function fiat_p256_cmovznz_u64 is a single-word conditional move. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint1 x1; + uint64_t x2; + uint64_t x3; + x1 = (!(!arg1)); + x2 = ((fiat_p256_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + x3 = ((fiat_p256_value_barrier_u64(x2) & arg3) | (fiat_p256_value_barrier_u64((~x2)) & arg2)); + *out1 = x3; +} + +/* + * The function fiat_p256_mul multiplies two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + fiat_p256_uint1 x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + fiat_p256_uint1 x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + uint64_t x99; + fiat_p256_uint1 x100; + uint64_t x101; + fiat_p256_uint1 x102; + uint64_t x103; + fiat_p256_uint1 x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + fiat_p256_uint1 x119; + uint64_t x120; + fiat_p256_uint1 x121; + uint64_t x122; + fiat_p256_uint1 x123; + uint64_t x124; + fiat_p256_uint1 x125; + uint64_t x126; + fiat_p256_uint1 x127; + uint64_t x128; + uint64_t x129; + uint64_t x130; + uint64_t x131; + uint64_t x132; + uint64_t x133; + uint64_t x134; + uint64_t x135; + uint64_t x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + fiat_p256_uint1 x140; + uint64_t x141; + fiat_p256_uint1 x142; + uint64_t x143; + uint64_t x144; + fiat_p256_uint1 x145; + uint64_t x146; + fiat_p256_uint1 x147; + uint64_t x148; + fiat_p256_uint1 x149; + uint64_t x150; + fiat_p256_uint1 x151; + uint64_t x152; + fiat_p256_uint1 x153; + uint64_t x154; + uint64_t x155; + uint64_t x156; + uint64_t x157; + uint64_t x158; + uint64_t x159; + uint64_t x160; + fiat_p256_uint1 x161; + uint64_t x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + fiat_p256_uint1 x168; + uint64_t x169; + fiat_p256_uint1 x170; + uint64_t x171; + fiat_p256_uint1 x172; + uint64_t x173; + uint64_t x174; + fiat_p256_uint1 x175; + uint64_t x176; + fiat_p256_uint1 x177; + uint64_t x178; + fiat_p256_uint1 x179; + uint64_t x180; + fiat_p256_uint1 x181; + uint64_t x182; + fiat_p256_uint1 x183; + uint64_t x184; + uint64_t x185; + uint64_t x186; + uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg2[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg2[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg2[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg2[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg2[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg2[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg2[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg2[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg2[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg2[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg2[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg2[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg2[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg2[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg2[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg2[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); + fiat_p256_cmovznz_u64(&x187, x183, x180, x171); + out1[0] = x184; + out1[1] = x185; + out1[2] = x186; + out1[3] = x187; +} + +/* + * The function fiat_p256_square squares a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + fiat_p256_uint1 x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + uint64_t x67; + uint64_t x68; + uint64_t x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + uint64_t x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + fiat_p256_uint1 x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + uint64_t x99; + fiat_p256_uint1 x100; + uint64_t x101; + fiat_p256_uint1 x102; + uint64_t x103; + fiat_p256_uint1 x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + uint64_t x110; + uint64_t x111; + uint64_t x112; + uint64_t x113; + uint64_t x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + fiat_p256_uint1 x119; + uint64_t x120; + fiat_p256_uint1 x121; + uint64_t x122; + fiat_p256_uint1 x123; + uint64_t x124; + fiat_p256_uint1 x125; + uint64_t x126; + fiat_p256_uint1 x127; + uint64_t x128; + uint64_t x129; + uint64_t x130; + uint64_t x131; + uint64_t x132; + uint64_t x133; + uint64_t x134; + uint64_t x135; + uint64_t x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + fiat_p256_uint1 x140; + uint64_t x141; + fiat_p256_uint1 x142; + uint64_t x143; + uint64_t x144; + fiat_p256_uint1 x145; + uint64_t x146; + fiat_p256_uint1 x147; + uint64_t x148; + fiat_p256_uint1 x149; + uint64_t x150; + fiat_p256_uint1 x151; + uint64_t x152; + fiat_p256_uint1 x153; + uint64_t x154; + uint64_t x155; + uint64_t x156; + uint64_t x157; + uint64_t x158; + uint64_t x159; + uint64_t x160; + fiat_p256_uint1 x161; + uint64_t x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + fiat_p256_uint1 x168; + uint64_t x169; + fiat_p256_uint1 x170; + uint64_t x171; + fiat_p256_uint1 x172; + uint64_t x173; + uint64_t x174; + fiat_p256_uint1 x175; + uint64_t x176; + fiat_p256_uint1 x177; + uint64_t x178; + fiat_p256_uint1 x179; + uint64_t x180; + fiat_p256_uint1 x181; + uint64_t x182; + fiat_p256_uint1 x183; + uint64_t x184; + uint64_t x185; + uint64_t x186; + uint64_t x187; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, (arg1[3])); + fiat_p256_mulx_u64(&x7, &x8, x4, (arg1[2])); + fiat_p256_mulx_u64(&x9, &x10, x4, (arg1[1])); + fiat_p256_mulx_u64(&x11, &x12, x4, (arg1[0])); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + x19 = (x18 + x6); + fiat_p256_mulx_u64(&x20, &x21, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x22, &x23, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x24, &x25, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, x25, x22); + x28 = (x27 + x23); + fiat_p256_addcarryx_u64(&x29, &x30, 0x0, x11, x24); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x13, x26); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x15, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x17, x20); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x19, x21); + fiat_p256_mulx_u64(&x39, &x40, x1, (arg1[3])); + fiat_p256_mulx_u64(&x41, &x42, x1, (arg1[2])); + fiat_p256_mulx_u64(&x43, &x44, x1, (arg1[1])); + fiat_p256_mulx_u64(&x45, &x46, x1, (arg1[0])); + fiat_p256_addcarryx_u64(&x47, &x48, 0x0, x46, x43); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x44, x41); + fiat_p256_addcarryx_u64(&x51, &x52, x50, x42, x39); + x53 = (x52 + x40); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x31, x45); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x33, x47); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x35, x49); + fiat_p256_addcarryx_u64(&x60, &x61, x59, x37, x51); + fiat_p256_addcarryx_u64(&x62, &x63, x61, x38, x53); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x66, &x67, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x68, &x69, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x70, &x71, 0x0, x69, x66); + x72 = (x71 + x67); + fiat_p256_addcarryx_u64(&x73, &x74, 0x0, x54, x68); + fiat_p256_addcarryx_u64(&x75, &x76, x74, x56, x70); + fiat_p256_addcarryx_u64(&x77, &x78, x76, x58, x72); + fiat_p256_addcarryx_u64(&x79, &x80, x78, x60, x64); + fiat_p256_addcarryx_u64(&x81, &x82, x80, x62, x65); + x83 = ((uint64_t)x82 + x63); + fiat_p256_mulx_u64(&x84, &x85, x2, (arg1[3])); + fiat_p256_mulx_u64(&x86, &x87, x2, (arg1[2])); + fiat_p256_mulx_u64(&x88, &x89, x2, (arg1[1])); + fiat_p256_mulx_u64(&x90, &x91, x2, (arg1[0])); + fiat_p256_addcarryx_u64(&x92, &x93, 0x0, x91, x88); + fiat_p256_addcarryx_u64(&x94, &x95, x93, x89, x86); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x87, x84); + x98 = (x97 + x85); + fiat_p256_addcarryx_u64(&x99, &x100, 0x0, x75, x90); + fiat_p256_addcarryx_u64(&x101, &x102, x100, x77, x92); + fiat_p256_addcarryx_u64(&x103, &x104, x102, x79, x94); + fiat_p256_addcarryx_u64(&x105, &x106, x104, x81, x96); + fiat_p256_addcarryx_u64(&x107, &x108, x106, x83, x98); + fiat_p256_mulx_u64(&x109, &x110, x99, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x111, &x112, x99, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x113, &x114, x99, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x114, x111); + x117 = (x116 + x112); + fiat_p256_addcarryx_u64(&x118, &x119, 0x0, x99, x113); + fiat_p256_addcarryx_u64(&x120, &x121, x119, x101, x115); + fiat_p256_addcarryx_u64(&x122, &x123, x121, x103, x117); + fiat_p256_addcarryx_u64(&x124, &x125, x123, x105, x109); + fiat_p256_addcarryx_u64(&x126, &x127, x125, x107, x110); + x128 = ((uint64_t)x127 + x108); + fiat_p256_mulx_u64(&x129, &x130, x3, (arg1[3])); + fiat_p256_mulx_u64(&x131, &x132, x3, (arg1[2])); + fiat_p256_mulx_u64(&x133, &x134, x3, (arg1[1])); + fiat_p256_mulx_u64(&x135, &x136, x3, (arg1[0])); + fiat_p256_addcarryx_u64(&x137, &x138, 0x0, x136, x133); + fiat_p256_addcarryx_u64(&x139, &x140, x138, x134, x131); + fiat_p256_addcarryx_u64(&x141, &x142, x140, x132, x129); + x143 = (x142 + x130); + fiat_p256_addcarryx_u64(&x144, &x145, 0x0, x120, x135); + fiat_p256_addcarryx_u64(&x146, &x147, x145, x122, x137); + fiat_p256_addcarryx_u64(&x148, &x149, x147, x124, x139); + fiat_p256_addcarryx_u64(&x150, &x151, x149, x126, x141); + fiat_p256_addcarryx_u64(&x152, &x153, x151, x128, x143); + fiat_p256_mulx_u64(&x154, &x155, x144, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x156, &x157, x144, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x158, &x159, x144, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x160, &x161, 0x0, x159, x156); + x162 = (x161 + x157); + fiat_p256_addcarryx_u64(&x163, &x164, 0x0, x144, x158); + fiat_p256_addcarryx_u64(&x165, &x166, x164, x146, x160); + fiat_p256_addcarryx_u64(&x167, &x168, x166, x148, x162); + fiat_p256_addcarryx_u64(&x169, &x170, x168, x150, x154); + fiat_p256_addcarryx_u64(&x171, &x172, x170, x152, x155); + x173 = ((uint64_t)x172 + x153); + fiat_p256_subborrowx_u64(&x174, &x175, 0x0, x165, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x176, &x177, x175, x167, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x178, &x179, x177, x169, 0x0); + fiat_p256_subborrowx_u64(&x180, &x181, x179, x171, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x182, &x183, x181, x173, 0x0); + fiat_p256_cmovznz_u64(&x184, x183, x174, x165); + fiat_p256_cmovznz_u64(&x185, x183, x176, x167); + fiat_p256_cmovznz_u64(&x186, x183, x178, x169); + fiat_p256_cmovznz_u64(&x187, x183, x180, x171); + out1[0] = x184; + out1[1] = x185; + out1[2] = x186; + out1[3] = x187; +} + +/* + * The function fiat_p256_add adds two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + fiat_p256_uint1 x10; + uint64_t x11; + fiat_p256_uint1 x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); + fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); + fiat_p256_cmovznz_u64(&x19, x18, x9, x1); + fiat_p256_cmovznz_u64(&x20, x18, x11, x3); + fiat_p256_cmovznz_u64(&x21, x18, x13, x5); + fiat_p256_cmovznz_u64(&x22, x18, x15, x7); + out1[0] = x19; + out1[1] = x20; + out1[2] = x21; + out1[3] = x22; +} + +/* + * The function fiat_p256_sub subtracts two field elements in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * 0 ≤ eval arg2 < m + * Postconditions: + * eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); + fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * The function fiat_p256_opp negates a field element in the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_opp(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + fiat_p256_uint1 x2; + uint64_t x3; + fiat_p256_uint1 x4; + uint64_t x5; + fiat_p256_uint1 x6; + uint64_t x7; + fiat_p256_uint1 x8; + uint64_t x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, 0x0, (arg1[0])); + fiat_p256_subborrowx_u64(&x3, &x4, x2, 0x0, (arg1[1])); + fiat_p256_subborrowx_u64(&x5, &x6, x4, 0x0, (arg1[2])); + fiat_p256_subborrowx_u64(&x7, &x8, x6, 0x0, (arg1[3])); + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); + fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); + fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * The function fiat_p256_from_montgomery translates a field element out of the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_montgomery(fiat_p256_non_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + fiat_p256_uint1 x9; + uint64_t x10; + fiat_p256_uint1 x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + fiat_p256_uint1 x23; + uint64_t x24; + fiat_p256_uint1 x25; + uint64_t x26; + fiat_p256_uint1 x27; + uint64_t x28; + fiat_p256_uint1 x29; + uint64_t x30; + fiat_p256_uint1 x31; + uint64_t x32; + fiat_p256_uint1 x33; + uint64_t x34; + fiat_p256_uint1 x35; + uint64_t x36; + fiat_p256_uint1 x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + fiat_p256_uint1 x45; + uint64_t x46; + fiat_p256_uint1 x47; + uint64_t x48; + fiat_p256_uint1 x49; + uint64_t x50; + fiat_p256_uint1 x51; + uint64_t x52; + fiat_p256_uint1 x53; + uint64_t x54; + fiat_p256_uint1 x55; + uint64_t x56; + fiat_p256_uint1 x57; + uint64_t x58; + fiat_p256_uint1 x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + uint64_t x66; + fiat_p256_uint1 x67; + uint64_t x68; + fiat_p256_uint1 x69; + uint64_t x70; + fiat_p256_uint1 x71; + uint64_t x72; + fiat_p256_uint1 x73; + uint64_t x74; + fiat_p256_uint1 x75; + uint64_t x76; + uint64_t x77; + fiat_p256_uint1 x78; + uint64_t x79; + fiat_p256_uint1 x80; + uint64_t x81; + fiat_p256_uint1 x82; + uint64_t x83; + fiat_p256_uint1 x84; + uint64_t x85; + fiat_p256_uint1 x86; + uint64_t x87; + uint64_t x88; + uint64_t x89; + uint64_t x90; + x1 = (arg1[0]); + fiat_p256_mulx_u64(&x2, &x3, x1, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x4, &x5, x1, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x6, &x7, x1, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x8, &x9, 0x0, x7, x4); + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x6); + fiat_p256_addcarryx_u64(&x12, &x13, x11, 0x0, x8); + fiat_p256_addcarryx_u64(&x14, &x15, 0x0, x12, (arg1[1])); + fiat_p256_mulx_u64(&x16, &x17, x14, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x18, &x19, x14, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x20, &x21, x14, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x22, &x23, 0x0, x21, x18); + fiat_p256_addcarryx_u64(&x24, &x25, 0x0, x14, x20); + fiat_p256_addcarryx_u64(&x26, &x27, x25, (x15 + (x13 + (x9 + x5))), x22); + fiat_p256_addcarryx_u64(&x28, &x29, x27, x2, (x23 + x19)); + fiat_p256_addcarryx_u64(&x30, &x31, x29, x3, x16); + fiat_p256_addcarryx_u64(&x32, &x33, 0x0, x26, (arg1[2])); + fiat_p256_addcarryx_u64(&x34, &x35, x33, x28, 0x0); + fiat_p256_addcarryx_u64(&x36, &x37, x35, x30, 0x0); + fiat_p256_mulx_u64(&x38, &x39, x32, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x40, &x41, x32, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x42, &x43, x32, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x44, &x45, 0x0, x43, x40); + fiat_p256_addcarryx_u64(&x46, &x47, 0x0, x32, x42); + fiat_p256_addcarryx_u64(&x48, &x49, x47, x34, x44); + fiat_p256_addcarryx_u64(&x50, &x51, x49, x36, (x45 + x41)); + fiat_p256_addcarryx_u64(&x52, &x53, x51, (x37 + (x31 + x17)), x38); + fiat_p256_addcarryx_u64(&x54, &x55, 0x0, x48, (arg1[3])); + fiat_p256_addcarryx_u64(&x56, &x57, x55, x50, 0x0); + fiat_p256_addcarryx_u64(&x58, &x59, x57, x52, 0x0); + fiat_p256_mulx_u64(&x60, &x61, x54, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x62, &x63, x54, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x64, &x65, x54, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x66, &x67, 0x0, x65, x62); + fiat_p256_addcarryx_u64(&x68, &x69, 0x0, x54, x64); + fiat_p256_addcarryx_u64(&x70, &x71, x69, x56, x66); + fiat_p256_addcarryx_u64(&x72, &x73, x71, x58, (x67 + x63)); + fiat_p256_addcarryx_u64(&x74, &x75, x73, (x59 + (x53 + x39)), x60); + x76 = (x75 + x61); + fiat_p256_subborrowx_u64(&x77, &x78, 0x0, x70, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x79, &x80, x78, x72, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x81, &x82, x80, x74, 0x0); + fiat_p256_subborrowx_u64(&x83, &x84, x82, x76, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x85, &x86, x84, 0x0, 0x0); + fiat_p256_cmovznz_u64(&x87, x86, x77, x70); + fiat_p256_cmovznz_u64(&x88, x86, x79, x72); + fiat_p256_cmovznz_u64(&x89, x86, x81, x74); + fiat_p256_cmovznz_u64(&x90, x86, x83, x76); + out1[0] = x87; + out1[1] = x88; + out1[2] = x89; + out1[3] = x90; +} + +/* + * The function fiat_p256_to_montgomery translates a field element into the Montgomery domain. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * eval (from_montgomery out1) mod m = eval arg1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_montgomery(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_non_montgomery_domain_field_element arg1) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + fiat_p256_uint1 x14; + uint64_t x15; + fiat_p256_uint1 x16; + uint64_t x17; + fiat_p256_uint1 x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + fiat_p256_uint1 x26; + uint64_t x27; + fiat_p256_uint1 x28; + uint64_t x29; + fiat_p256_uint1 x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + fiat_p256_uint1 x50; + uint64_t x51; + fiat_p256_uint1 x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + uint64_t x60; + uint64_t x61; + uint64_t x62; + uint64_t x63; + uint64_t x64; + uint64_t x65; + fiat_p256_uint1 x66; + uint64_t x67; + fiat_p256_uint1 x68; + uint64_t x69; + fiat_p256_uint1 x70; + uint64_t x71; + fiat_p256_uint1 x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + fiat_p256_uint1 x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + uint64_t x81; + uint64_t x82; + uint64_t x83; + uint64_t x84; + uint64_t x85; + fiat_p256_uint1 x86; + uint64_t x87; + fiat_p256_uint1 x88; + uint64_t x89; + fiat_p256_uint1 x90; + uint64_t x91; + fiat_p256_uint1 x92; + uint64_t x93; + fiat_p256_uint1 x94; + uint64_t x95; + fiat_p256_uint1 x96; + uint64_t x97; + fiat_p256_uint1 x98; + uint64_t x99; + uint64_t x100; + uint64_t x101; + uint64_t x102; + uint64_t x103; + uint64_t x104; + uint64_t x105; + fiat_p256_uint1 x106; + uint64_t x107; + fiat_p256_uint1 x108; + uint64_t x109; + fiat_p256_uint1 x110; + uint64_t x111; + fiat_p256_uint1 x112; + uint64_t x113; + fiat_p256_uint1 x114; + uint64_t x115; + fiat_p256_uint1 x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + fiat_p256_uint1 x126; + uint64_t x127; + fiat_p256_uint1 x128; + uint64_t x129; + fiat_p256_uint1 x130; + uint64_t x131; + fiat_p256_uint1 x132; + uint64_t x133; + fiat_p256_uint1 x134; + uint64_t x135; + fiat_p256_uint1 x136; + uint64_t x137; + fiat_p256_uint1 x138; + uint64_t x139; + uint64_t x140; + uint64_t x141; + uint64_t x142; + uint64_t x143; + uint64_t x144; + uint64_t x145; + fiat_p256_uint1 x146; + uint64_t x147; + fiat_p256_uint1 x148; + uint64_t x149; + fiat_p256_uint1 x150; + uint64_t x151; + fiat_p256_uint1 x152; + uint64_t x153; + fiat_p256_uint1 x154; + uint64_t x155; + fiat_p256_uint1 x156; + uint64_t x157; + fiat_p256_uint1 x158; + uint64_t x159; + fiat_p256_uint1 x160; + uint64_t x161; + fiat_p256_uint1 x162; + uint64_t x163; + fiat_p256_uint1 x164; + uint64_t x165; + fiat_p256_uint1 x166; + uint64_t x167; + uint64_t x168; + uint64_t x169; + uint64_t x170; + x1 = (arg1[1]); + x2 = (arg1[2]); + x3 = (arg1[3]); + x4 = (arg1[0]); + fiat_p256_mulx_u64(&x5, &x6, x4, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x7, &x8, x4, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x9, &x10, x4, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x11, &x12, x4, 0x3); + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x12, x9); + fiat_p256_addcarryx_u64(&x15, &x16, x14, x10, x7); + fiat_p256_addcarryx_u64(&x17, &x18, x16, x8, x5); + fiat_p256_mulx_u64(&x19, &x20, x11, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x21, &x22, x11, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x23, &x24, x11, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x25, &x26, 0x0, x24, x21); + fiat_p256_addcarryx_u64(&x27, &x28, 0x0, x11, x23); + fiat_p256_addcarryx_u64(&x29, &x30, x28, x13, x25); + fiat_p256_addcarryx_u64(&x31, &x32, x30, x15, (x26 + x22)); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x17, x19); + fiat_p256_addcarryx_u64(&x35, &x36, x34, (x18 + x6), x20); + fiat_p256_mulx_u64(&x37, &x38, x1, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x39, &x40, x1, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x41, &x42, x1, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x43, &x44, x1, 0x3); + fiat_p256_addcarryx_u64(&x45, &x46, 0x0, x44, x41); + fiat_p256_addcarryx_u64(&x47, &x48, x46, x42, x39); + fiat_p256_addcarryx_u64(&x49, &x50, x48, x40, x37); + fiat_p256_addcarryx_u64(&x51, &x52, 0x0, x29, x43); + fiat_p256_addcarryx_u64(&x53, &x54, x52, x31, x45); + fiat_p256_addcarryx_u64(&x55, &x56, x54, x33, x47); + fiat_p256_addcarryx_u64(&x57, &x58, x56, x35, x49); + fiat_p256_mulx_u64(&x59, &x60, x51, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x61, &x62, x51, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x63, &x64, x51, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x65, &x66, 0x0, x64, x61); + fiat_p256_addcarryx_u64(&x67, &x68, 0x0, x51, x63); + fiat_p256_addcarryx_u64(&x69, &x70, x68, x53, x65); + fiat_p256_addcarryx_u64(&x71, &x72, x70, x55, (x66 + x62)); + fiat_p256_addcarryx_u64(&x73, &x74, x72, x57, x59); + fiat_p256_addcarryx_u64(&x75, &x76, x74, (((uint64_t)x58 + x36) + (x50 + x38)), x60); + fiat_p256_mulx_u64(&x77, &x78, x2, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x79, &x80, x2, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x81, &x82, x2, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x83, &x84, x2, 0x3); + fiat_p256_addcarryx_u64(&x85, &x86, 0x0, x84, x81); + fiat_p256_addcarryx_u64(&x87, &x88, x86, x82, x79); + fiat_p256_addcarryx_u64(&x89, &x90, x88, x80, x77); + fiat_p256_addcarryx_u64(&x91, &x92, 0x0, x69, x83); + fiat_p256_addcarryx_u64(&x93, &x94, x92, x71, x85); + fiat_p256_addcarryx_u64(&x95, &x96, x94, x73, x87); + fiat_p256_addcarryx_u64(&x97, &x98, x96, x75, x89); + fiat_p256_mulx_u64(&x99, &x100, x91, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x101, &x102, x91, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x103, &x104, x91, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x105, &x106, 0x0, x104, x101); + fiat_p256_addcarryx_u64(&x107, &x108, 0x0, x91, x103); + fiat_p256_addcarryx_u64(&x109, &x110, x108, x93, x105); + fiat_p256_addcarryx_u64(&x111, &x112, x110, x95, (x106 + x102)); + fiat_p256_addcarryx_u64(&x113, &x114, x112, x97, x99); + fiat_p256_addcarryx_u64(&x115, &x116, x114, (((uint64_t)x98 + x76) + (x90 + x78)), x100); + fiat_p256_mulx_u64(&x117, &x118, x3, UINT64_C(0x4fffffffd)); + fiat_p256_mulx_u64(&x119, &x120, x3, UINT64_C(0xfffffffffffffffe)); + fiat_p256_mulx_u64(&x121, &x122, x3, UINT64_C(0xfffffffbffffffff)); + fiat_p256_mulx_u64(&x123, &x124, x3, 0x3); + fiat_p256_addcarryx_u64(&x125, &x126, 0x0, x124, x121); + fiat_p256_addcarryx_u64(&x127, &x128, x126, x122, x119); + fiat_p256_addcarryx_u64(&x129, &x130, x128, x120, x117); + fiat_p256_addcarryx_u64(&x131, &x132, 0x0, x109, x123); + fiat_p256_addcarryx_u64(&x133, &x134, x132, x111, x125); + fiat_p256_addcarryx_u64(&x135, &x136, x134, x113, x127); + fiat_p256_addcarryx_u64(&x137, &x138, x136, x115, x129); + fiat_p256_mulx_u64(&x139, &x140, x131, UINT64_C(0xffffffff00000001)); + fiat_p256_mulx_u64(&x141, &x142, x131, UINT32_C(0xffffffff)); + fiat_p256_mulx_u64(&x143, &x144, x131, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x145, &x146, 0x0, x144, x141); + fiat_p256_addcarryx_u64(&x147, &x148, 0x0, x131, x143); + fiat_p256_addcarryx_u64(&x149, &x150, x148, x133, x145); + fiat_p256_addcarryx_u64(&x151, &x152, x150, x135, (x146 + x142)); + fiat_p256_addcarryx_u64(&x153, &x154, x152, x137, x139); + fiat_p256_addcarryx_u64(&x155, &x156, x154, (((uint64_t)x138 + x116) + (x130 + x118)), x140); + fiat_p256_subborrowx_u64(&x157, &x158, 0x0, x149, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x159, &x160, x158, x151, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x161, &x162, x160, x153, 0x0); + fiat_p256_subborrowx_u64(&x163, &x164, x162, x155, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x165, &x166, x164, x156, 0x0); + fiat_p256_cmovznz_u64(&x167, x166, x157, x149); + fiat_p256_cmovznz_u64(&x168, x166, x159, x151); + fiat_p256_cmovznz_u64(&x169, x166, x161, x153); + fiat_p256_cmovznz_u64(&x170, x166, x163, x155); + out1[0] = x167; + out1[1] = x168; + out1[2] = x169; + out1[3] = x170; +} + +/* + * The function fiat_p256_nonzero outputs a single non-zero word if the input is non-zero and zero otherwise. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { + uint64_t x1; + x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | (arg1[3])))); + *out1 = x1; +} + +/* + * The function fiat_p256_selectznz is a multi-limb conditional select. + * + * Postconditions: + * out1 = (if arg1 = 0 then arg2 else arg3) + * + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + fiat_p256_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; +} + +/* + * The function fiat_p256_to_bytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. + * + * Preconditions: + * 0 ≤ eval arg1 < m + * Postconditions: + * out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] + * + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint8_t x5; + uint64_t x6; + uint8_t x7; + uint64_t x8; + uint8_t x9; + uint64_t x10; + uint8_t x11; + uint64_t x12; + uint8_t x13; + uint64_t x14; + uint8_t x15; + uint64_t x16; + uint8_t x17; + uint8_t x18; + uint8_t x19; + uint64_t x20; + uint8_t x21; + uint64_t x22; + uint8_t x23; + uint64_t x24; + uint8_t x25; + uint64_t x26; + uint8_t x27; + uint64_t x28; + uint8_t x29; + uint64_t x30; + uint8_t x31; + uint8_t x32; + uint8_t x33; + uint64_t x34; + uint8_t x35; + uint64_t x36; + uint8_t x37; + uint64_t x38; + uint8_t x39; + uint64_t x40; + uint8_t x41; + uint64_t x42; + uint8_t x43; + uint64_t x44; + uint8_t x45; + uint8_t x46; + uint8_t x47; + uint64_t x48; + uint8_t x49; + uint64_t x50; + uint8_t x51; + uint64_t x52; + uint8_t x53; + uint64_t x54; + uint8_t x55; + uint64_t x56; + uint8_t x57; + uint64_t x58; + uint8_t x59; + uint8_t x60; + x1 = (arg1[3]); + x2 = (arg1[2]); + x3 = (arg1[1]); + x4 = (arg1[0]); + x5 = (uint8_t)(x4 & UINT8_C(0xff)); + x6 = (x4 >> 8); + x7 = (uint8_t)(x6 & UINT8_C(0xff)); + x8 = (x6 >> 8); + x9 = (uint8_t)(x8 & UINT8_C(0xff)); + x10 = (x8 >> 8); + x11 = (uint8_t)(x10 & UINT8_C(0xff)); + x12 = (x10 >> 8); + x13 = (uint8_t)(x12 & UINT8_C(0xff)); + x14 = (x12 >> 8); + x15 = (uint8_t)(x14 & UINT8_C(0xff)); + x16 = (x14 >> 8); + x17 = (uint8_t)(x16 & UINT8_C(0xff)); + x18 = (uint8_t)(x16 >> 8); + x19 = (uint8_t)(x3 & UINT8_C(0xff)); + x20 = (x3 >> 8); + x21 = (uint8_t)(x20 & UINT8_C(0xff)); + x22 = (x20 >> 8); + x23 = (uint8_t)(x22 & UINT8_C(0xff)); + x24 = (x22 >> 8); + x25 = (uint8_t)(x24 & UINT8_C(0xff)); + x26 = (x24 >> 8); + x27 = (uint8_t)(x26 & UINT8_C(0xff)); + x28 = (x26 >> 8); + x29 = (uint8_t)(x28 & UINT8_C(0xff)); + x30 = (x28 >> 8); + x31 = (uint8_t)(x30 & UINT8_C(0xff)); + x32 = (uint8_t)(x30 >> 8); + x33 = (uint8_t)(x2 & UINT8_C(0xff)); + x34 = (x2 >> 8); + x35 = (uint8_t)(x34 & UINT8_C(0xff)); + x36 = (x34 >> 8); + x37 = (uint8_t)(x36 & UINT8_C(0xff)); + x38 = (x36 >> 8); + x39 = (uint8_t)(x38 & UINT8_C(0xff)); + x40 = (x38 >> 8); + x41 = (uint8_t)(x40 & UINT8_C(0xff)); + x42 = (x40 >> 8); + x43 = (uint8_t)(x42 & UINT8_C(0xff)); + x44 = (x42 >> 8); + x45 = (uint8_t)(x44 & UINT8_C(0xff)); + x46 = (uint8_t)(x44 >> 8); + x47 = (uint8_t)(x1 & UINT8_C(0xff)); + x48 = (x1 >> 8); + x49 = (uint8_t)(x48 & UINT8_C(0xff)); + x50 = (x48 >> 8); + x51 = (uint8_t)(x50 & UINT8_C(0xff)); + x52 = (x50 >> 8); + x53 = (uint8_t)(x52 & UINT8_C(0xff)); + x54 = (x52 >> 8); + x55 = (uint8_t)(x54 & UINT8_C(0xff)); + x56 = (x54 >> 8); + x57 = (uint8_t)(x56 & UINT8_C(0xff)); + x58 = (x56 >> 8); + x59 = (uint8_t)(x58 & UINT8_C(0xff)); + x60 = (uint8_t)(x58 >> 8); + out1[0] = x5; + out1[1] = x7; + out1[2] = x9; + out1[3] = x11; + out1[4] = x13; + out1[5] = x15; + out1[6] = x17; + out1[7] = x18; + out1[8] = x19; + out1[9] = x21; + out1[10] = x23; + out1[11] = x25; + out1[12] = x27; + out1[13] = x29; + out1[14] = x31; + out1[15] = x32; + out1[16] = x33; + out1[17] = x35; + out1[18] = x37; + out1[19] = x39; + out1[20] = x41; + out1[21] = x43; + out1[22] = x45; + out1[23] = x46; + out1[24] = x47; + out1[25] = x49; + out1[26] = x51; + out1[27] = x53; + out1[28] = x55; + out1[29] = x57; + out1[30] = x59; + out1[31] = x60; +} + +/* + * The function fiat_p256_from_bytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. + * + * Preconditions: + * 0 ≤ bytes_eval arg1 < m + * Postconditions: + * eval out1 mod m = bytes_eval arg1 mod m + * 0 ≤ eval out1 < m + * + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_from_bytes(uint64_t out1[4], const uint8_t arg1[32]) { + uint64_t x1; + uint64_t x2; + uint64_t x3; + uint64_t x4; + uint64_t x5; + uint64_t x6; + uint64_t x7; + uint8_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + uint64_t x13; + uint64_t x14; + uint64_t x15; + uint8_t x16; + uint64_t x17; + uint64_t x18; + uint64_t x19; + uint64_t x20; + uint64_t x21; + uint64_t x22; + uint64_t x23; + uint8_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + uint8_t x32; + uint64_t x33; + uint64_t x34; + uint64_t x35; + uint64_t x36; + uint64_t x37; + uint64_t x38; + uint64_t x39; + uint64_t x40; + uint64_t x41; + uint64_t x42; + uint64_t x43; + uint64_t x44; + uint64_t x45; + uint64_t x46; + uint64_t x47; + uint64_t x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + uint64_t x54; + uint64_t x55; + uint64_t x56; + uint64_t x57; + uint64_t x58; + uint64_t x59; + uint64_t x60; + x1 = ((uint64_t)(arg1[31]) << 56); + x2 = ((uint64_t)(arg1[30]) << 48); + x3 = ((uint64_t)(arg1[29]) << 40); + x4 = ((uint64_t)(arg1[28]) << 32); + x5 = ((uint64_t)(arg1[27]) << 24); + x6 = ((uint64_t)(arg1[26]) << 16); + x7 = ((uint64_t)(arg1[25]) << 8); + x8 = (arg1[24]); + x9 = ((uint64_t)(arg1[23]) << 56); + x10 = ((uint64_t)(arg1[22]) << 48); + x11 = ((uint64_t)(arg1[21]) << 40); + x12 = ((uint64_t)(arg1[20]) << 32); + x13 = ((uint64_t)(arg1[19]) << 24); + x14 = ((uint64_t)(arg1[18]) << 16); + x15 = ((uint64_t)(arg1[17]) << 8); + x16 = (arg1[16]); + x17 = ((uint64_t)(arg1[15]) << 56); + x18 = ((uint64_t)(arg1[14]) << 48); + x19 = ((uint64_t)(arg1[13]) << 40); + x20 = ((uint64_t)(arg1[12]) << 32); + x21 = ((uint64_t)(arg1[11]) << 24); + x22 = ((uint64_t)(arg1[10]) << 16); + x23 = ((uint64_t)(arg1[9]) << 8); + x24 = (arg1[8]); + x25 = ((uint64_t)(arg1[7]) << 56); + x26 = ((uint64_t)(arg1[6]) << 48); + x27 = ((uint64_t)(arg1[5]) << 40); + x28 = ((uint64_t)(arg1[4]) << 32); + x29 = ((uint64_t)(arg1[3]) << 24); + x30 = ((uint64_t)(arg1[2]) << 16); + x31 = ((uint64_t)(arg1[1]) << 8); + x32 = (arg1[0]); + x33 = (x31 + (uint64_t)x32); + x34 = (x30 + x33); + x35 = (x29 + x34); + x36 = (x28 + x35); + x37 = (x27 + x36); + x38 = (x26 + x37); + x39 = (x25 + x38); + x40 = (x23 + (uint64_t)x24); + x41 = (x22 + x40); + x42 = (x21 + x41); + x43 = (x20 + x42); + x44 = (x19 + x43); + x45 = (x18 + x44); + x46 = (x17 + x45); + x47 = (x15 + (uint64_t)x16); + x48 = (x14 + x47); + x49 = (x13 + x48); + x50 = (x12 + x49); + x51 = (x11 + x50); + x52 = (x10 + x51); + x53 = (x9 + x52); + x54 = (x7 + (uint64_t)x8); + x55 = (x6 + x54); + x56 = (x5 + x55); + x57 = (x4 + x56); + x58 = (x3 + x57); + x59 = (x2 + x58); + x60 = (x1 + x59); + out1[0] = x39; + out1[1] = x46; + out1[2] = x53; + out1[3] = x60; +} + +/* + * The function fiat_p256_set_one returns the field element one in the Montgomery domain. + * + * Postconditions: + * eval (from_montgomery out1) mod m = 1 mod m + * 0 ≤ eval out1 < m + * + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_set_one(fiat_p256_montgomery_domain_field_element out1) { + out1[0] = 0x1; + out1[1] = UINT64_C(0xffffffff00000000); + out1[2] = UINT64_C(0xffffffffffffffff); + out1[3] = UINT32_C(0xfffffffe); +} + +/* + * The function fiat_p256_msat returns the saturated representation of the prime modulus. + * + * Postconditions: + * twos_complement_eval out1 = m + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_msat(uint64_t out1[5]) { + out1[0] = UINT64_C(0xffffffffffffffff); + out1[1] = UINT32_C(0xffffffff); + out1[2] = 0x0; + out1[3] = UINT64_C(0xffffffff00000001); + out1[4] = 0x0; +} + +/* + * The function fiat_p256_divstep computes a divstep. + * + * Preconditions: + * 0 ≤ eval arg4 < m + * 0 ≤ eval arg5 < m + * Postconditions: + * out1 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then 1 - arg1 else 1 + arg1) + * twos_complement_eval out2 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then twos_complement_eval arg3 else twos_complement_eval arg2) + * twos_complement_eval out3 = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then ⌊(twos_complement_eval arg3 - twos_complement_eval arg2) / 2⌋ else ⌊(twos_complement_eval arg3 + (twos_complement_eval arg3 mod 2) * twos_complement_eval arg2) / 2⌋) + * eval (from_montgomery out4) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (2 * eval (from_montgomery arg5)) mod m else (2 * eval (from_montgomery arg4)) mod m) + * eval (from_montgomery out5) mod m = (if 0 < arg1 ∧ (twos_complement_eval arg3) is odd then (eval (from_montgomery arg4) - eval (from_montgomery arg4)) mod m else (eval (from_montgomery arg5) + (twos_complement_eval arg3 mod 2) * eval (from_montgomery arg4)) mod m) + * 0 ≤ eval out5 < m + * 0 ≤ eval out5 < m + * 0 ≤ eval out2 < m + * 0 ≤ eval out3 < m + * + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out4: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * out5: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep(uint64_t* out1, uint64_t out2[5], uint64_t out3[5], uint64_t out4[4], uint64_t out5[4], uint64_t arg1, const uint64_t arg2[5], const uint64_t arg3[5], const uint64_t arg4[4], const uint64_t arg5[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_uint1 x3; + uint64_t x4; + fiat_p256_uint1 x5; + uint64_t x6; + uint64_t x7; + uint64_t x8; + uint64_t x9; + uint64_t x10; + uint64_t x11; + uint64_t x12; + fiat_p256_uint1 x13; + uint64_t x14; + fiat_p256_uint1 x15; + uint64_t x16; + fiat_p256_uint1 x17; + uint64_t x18; + fiat_p256_uint1 x19; + uint64_t x20; + fiat_p256_uint1 x21; + uint64_t x22; + uint64_t x23; + uint64_t x24; + uint64_t x25; + uint64_t x26; + uint64_t x27; + uint64_t x28; + uint64_t x29; + uint64_t x30; + uint64_t x31; + fiat_p256_uint1 x32; + uint64_t x33; + fiat_p256_uint1 x34; + uint64_t x35; + fiat_p256_uint1 x36; + uint64_t x37; + fiat_p256_uint1 x38; + uint64_t x39; + fiat_p256_uint1 x40; + uint64_t x41; + fiat_p256_uint1 x42; + uint64_t x43; + fiat_p256_uint1 x44; + uint64_t x45; + fiat_p256_uint1 x46; + uint64_t x47; + fiat_p256_uint1 x48; + uint64_t x49; + uint64_t x50; + uint64_t x51; + uint64_t x52; + uint64_t x53; + fiat_p256_uint1 x54; + uint64_t x55; + fiat_p256_uint1 x56; + uint64_t x57; + fiat_p256_uint1 x58; + uint64_t x59; + fiat_p256_uint1 x60; + uint64_t x61; + uint64_t x62; + fiat_p256_uint1 x63; + uint64_t x64; + fiat_p256_uint1 x65; + uint64_t x66; + fiat_p256_uint1 x67; + uint64_t x68; + fiat_p256_uint1 x69; + uint64_t x70; + uint64_t x71; + uint64_t x72; + uint64_t x73; + fiat_p256_uint1 x74; + uint64_t x75; + uint64_t x76; + uint64_t x77; + uint64_t x78; + uint64_t x79; + uint64_t x80; + fiat_p256_uint1 x81; + uint64_t x82; + fiat_p256_uint1 x83; + uint64_t x84; + fiat_p256_uint1 x85; + uint64_t x86; + fiat_p256_uint1 x87; + uint64_t x88; + fiat_p256_uint1 x89; + uint64_t x90; + uint64_t x91; + uint64_t x92; + uint64_t x93; + uint64_t x94; + fiat_p256_uint1 x95; + uint64_t x96; + fiat_p256_uint1 x97; + uint64_t x98; + fiat_p256_uint1 x99; + uint64_t x100; + fiat_p256_uint1 x101; + uint64_t x102; + fiat_p256_uint1 x103; + uint64_t x104; + fiat_p256_uint1 x105; + uint64_t x106; + fiat_p256_uint1 x107; + uint64_t x108; + fiat_p256_uint1 x109; + uint64_t x110; + fiat_p256_uint1 x111; + uint64_t x112; + fiat_p256_uint1 x113; + uint64_t x114; + uint64_t x115; + uint64_t x116; + uint64_t x117; + uint64_t x118; + uint64_t x119; + uint64_t x120; + uint64_t x121; + uint64_t x122; + uint64_t x123; + uint64_t x124; + uint64_t x125; + uint64_t x126; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (~arg1), 0x1); + x3 = (fiat_p256_uint1)((fiat_p256_uint1)(x1 >> 63) & (fiat_p256_uint1)((arg3[0]) & 0x1)); + fiat_p256_addcarryx_u64(&x4, &x5, 0x0, (~arg1), 0x1); + fiat_p256_cmovznz_u64(&x6, x3, arg1, x4); + fiat_p256_cmovznz_u64(&x7, x3, (arg2[0]), (arg3[0])); + fiat_p256_cmovznz_u64(&x8, x3, (arg2[1]), (arg3[1])); + fiat_p256_cmovznz_u64(&x9, x3, (arg2[2]), (arg3[2])); + fiat_p256_cmovznz_u64(&x10, x3, (arg2[3]), (arg3[3])); + fiat_p256_cmovznz_u64(&x11, x3, (arg2[4]), (arg3[4])); + fiat_p256_addcarryx_u64(&x12, &x13, 0x0, 0x1, (~(arg2[0]))); + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, (~(arg2[1]))); + fiat_p256_addcarryx_u64(&x16, &x17, x15, 0x0, (~(arg2[2]))); + fiat_p256_addcarryx_u64(&x18, &x19, x17, 0x0, (~(arg2[3]))); + fiat_p256_addcarryx_u64(&x20, &x21, x19, 0x0, (~(arg2[4]))); + fiat_p256_cmovznz_u64(&x22, x3, (arg3[0]), x12); + fiat_p256_cmovznz_u64(&x23, x3, (arg3[1]), x14); + fiat_p256_cmovznz_u64(&x24, x3, (arg3[2]), x16); + fiat_p256_cmovznz_u64(&x25, x3, (arg3[3]), x18); + fiat_p256_cmovznz_u64(&x26, x3, (arg3[4]), x20); + fiat_p256_cmovznz_u64(&x27, x3, (arg4[0]), (arg5[0])); + fiat_p256_cmovznz_u64(&x28, x3, (arg4[1]), (arg5[1])); + fiat_p256_cmovznz_u64(&x29, x3, (arg4[2]), (arg5[2])); + fiat_p256_cmovznz_u64(&x30, x3, (arg4[3]), (arg5[3])); + fiat_p256_addcarryx_u64(&x31, &x32, 0x0, x27, x27); + fiat_p256_addcarryx_u64(&x33, &x34, x32, x28, x28); + fiat_p256_addcarryx_u64(&x35, &x36, x34, x29, x29); + fiat_p256_addcarryx_u64(&x37, &x38, x36, x30, x30); + fiat_p256_subborrowx_u64(&x39, &x40, 0x0, x31, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x41, &x42, x40, x33, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x43, &x44, x42, x35, 0x0); + fiat_p256_subborrowx_u64(&x45, &x46, x44, x37, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x47, &x48, x46, x38, 0x0); + x49 = (arg4[3]); + x50 = (arg4[2]); + x51 = (arg4[1]); + x52 = (arg4[0]); + fiat_p256_subborrowx_u64(&x53, &x54, 0x0, 0x0, x52); + fiat_p256_subborrowx_u64(&x55, &x56, x54, 0x0, x51); + fiat_p256_subborrowx_u64(&x57, &x58, x56, 0x0, x50); + fiat_p256_subborrowx_u64(&x59, &x60, x58, 0x0, x49); + fiat_p256_cmovznz_u64(&x61, x60, 0x0, UINT64_C(0xffffffffffffffff)); + fiat_p256_addcarryx_u64(&x62, &x63, 0x0, x53, x61); + fiat_p256_addcarryx_u64(&x64, &x65, x63, x55, (x61 & UINT32_C(0xffffffff))); + fiat_p256_addcarryx_u64(&x66, &x67, x65, x57, 0x0); + fiat_p256_addcarryx_u64(&x68, &x69, x67, x59, (x61 & UINT64_C(0xffffffff00000001))); + fiat_p256_cmovznz_u64(&x70, x3, (arg5[0]), x62); + fiat_p256_cmovznz_u64(&x71, x3, (arg5[1]), x64); + fiat_p256_cmovznz_u64(&x72, x3, (arg5[2]), x66); + fiat_p256_cmovznz_u64(&x73, x3, (arg5[3]), x68); + x74 = (fiat_p256_uint1)(x22 & 0x1); + fiat_p256_cmovznz_u64(&x75, x74, 0x0, x7); + fiat_p256_cmovznz_u64(&x76, x74, 0x0, x8); + fiat_p256_cmovznz_u64(&x77, x74, 0x0, x9); + fiat_p256_cmovznz_u64(&x78, x74, 0x0, x10); + fiat_p256_cmovznz_u64(&x79, x74, 0x0, x11); + fiat_p256_addcarryx_u64(&x80, &x81, 0x0, x22, x75); + fiat_p256_addcarryx_u64(&x82, &x83, x81, x23, x76); + fiat_p256_addcarryx_u64(&x84, &x85, x83, x24, x77); + fiat_p256_addcarryx_u64(&x86, &x87, x85, x25, x78); + fiat_p256_addcarryx_u64(&x88, &x89, x87, x26, x79); + fiat_p256_cmovznz_u64(&x90, x74, 0x0, x27); + fiat_p256_cmovznz_u64(&x91, x74, 0x0, x28); + fiat_p256_cmovznz_u64(&x92, x74, 0x0, x29); + fiat_p256_cmovznz_u64(&x93, x74, 0x0, x30); + fiat_p256_addcarryx_u64(&x94, &x95, 0x0, x70, x90); + fiat_p256_addcarryx_u64(&x96, &x97, x95, x71, x91); + fiat_p256_addcarryx_u64(&x98, &x99, x97, x72, x92); + fiat_p256_addcarryx_u64(&x100, &x101, x99, x73, x93); + fiat_p256_subborrowx_u64(&x102, &x103, 0x0, x94, UINT64_C(0xffffffffffffffff)); + fiat_p256_subborrowx_u64(&x104, &x105, x103, x96, UINT32_C(0xffffffff)); + fiat_p256_subborrowx_u64(&x106, &x107, x105, x98, 0x0); + fiat_p256_subborrowx_u64(&x108, &x109, x107, x100, UINT64_C(0xffffffff00000001)); + fiat_p256_subborrowx_u64(&x110, &x111, x109, x101, 0x0); + fiat_p256_addcarryx_u64(&x112, &x113, 0x0, x6, 0x1); + x114 = ((x80 >> 1) | ((x82 << 63) & UINT64_C(0xffffffffffffffff))); + x115 = ((x82 >> 1) | ((x84 << 63) & UINT64_C(0xffffffffffffffff))); + x116 = ((x84 >> 1) | ((x86 << 63) & UINT64_C(0xffffffffffffffff))); + x117 = ((x86 >> 1) | ((x88 << 63) & UINT64_C(0xffffffffffffffff))); + x118 = ((x88 & UINT64_C(0x8000000000000000)) | (x88 >> 1)); + fiat_p256_cmovznz_u64(&x119, x48, x39, x31); + fiat_p256_cmovznz_u64(&x120, x48, x41, x33); + fiat_p256_cmovznz_u64(&x121, x48, x43, x35); + fiat_p256_cmovznz_u64(&x122, x48, x45, x37); + fiat_p256_cmovznz_u64(&x123, x111, x102, x94); + fiat_p256_cmovznz_u64(&x124, x111, x104, x96); + fiat_p256_cmovznz_u64(&x125, x111, x106, x98); + fiat_p256_cmovznz_u64(&x126, x111, x108, x100); + *out1 = x112; + out2[0] = x7; + out2[1] = x8; + out2[2] = x9; + out2[3] = x10; + out2[4] = x11; + out3[0] = x114; + out3[1] = x115; + out3[2] = x116; + out3[3] = x117; + out3[4] = x118; + out4[0] = x119; + out4[1] = x120; + out4[2] = x121; + out4[3] = x122; + out5[0] = x123; + out5[1] = x124; + out5[2] = x125; + out5[3] = x126; +} + +/* + * The function fiat_p256_divstep_precomp returns the precomputed value for Bernstein-Yang-inversion (in montgomery form). + * + * Postconditions: + * eval (from_montgomery out1) = ⌊(m - 1) / 2⌋^(if ⌊log2 m⌋ + 1 < 46 then ⌊(49 * (⌊log2 m⌋ + 1) + 80) / 17⌋ else ⌊(49 * (⌊log2 m⌋ + 1) + 57) / 17⌋) + * 0 ≤ eval out1 < m + * + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static FIAT_P256_FIAT_INLINE void fiat_p256_divstep_precomp(uint64_t out1[4]) { + out1[0] = UINT64_C(0x67ffffffb8000000); + out1[1] = UINT64_C(0xc000000038000000); + out1[2] = UINT64_C(0xd80000007fffffff); + out1[3] = UINT64_C(0x2fffffffffffffff); +} diff --git a/third_party/boringssl/kit/src/tool/CMakeLists.txt b/third_party/boringssl/kit/src/tool/CMakeLists.txt index a591b7de..50471088 100644 --- a/third_party/boringssl/kit/src/tool/CMakeLists.txt +++ b/third_party/boringssl/kit/src/tool/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(../include) - add_executable( bssl @@ -21,20 +19,5 @@ add_executable( tool.cc transport_common.cc ) - -add_dependencies(bssl global_target) - -if(WIN32) - target_link_libraries(bssl ws2_32) -endif() - -if(APPLE OR WIN32 OR ANDROID) - target_link_libraries(bssl ssl crypto) -else() - find_library(FOUND_LIBRT rt) - if(FOUND_LIBRT) - target_link_libraries(bssl ssl crypto -lrt) - else() - target_link_libraries(bssl ssl crypto) - endif() -endif() +install_if_enabled(TARGETS bssl DESTINATION ${INSTALL_DESTINATION_DEFAULT}) +target_link_libraries(bssl ssl crypto) diff --git a/third_party/boringssl/kit/src/tool/digest.cc b/third_party/boringssl/kit/src/tool/digest.cc index 3c8fd5a6..d810928f 100644 --- a/third_party/boringssl/kit/src/tool/digest.cc +++ b/third_party/boringssl/kit/src/tool/digest.cc @@ -226,7 +226,6 @@ static bool Check(const CheckModeArguments &args, const EVP_MD *md, unsigned bad_lines = 0; unsigned parsed_lines = 0; unsigned error_lines = 0; - unsigned bad_hash_lines = 0; unsigned line_no = 0; bool ok = true; bool draining_overlong_line = false; @@ -297,7 +296,6 @@ static bool Check(const CheckModeArguments &args, const EVP_MD *md, } if (calculated_hex_digest != std::string(line, hex_size)) { - bad_hash_lines++; if (!args.status) { printf("%s: FAILED\n", target_filename.c_str()); } diff --git a/third_party/boringssl/kit/src/tool/server.cc b/third_party/boringssl/kit/src/tool/server.cc index 18b692d3..ebecee03 100644 --- a/third_party/boringssl/kit/src/tool/server.cc +++ b/third_party/boringssl/kit/src/tool/server.cc @@ -132,21 +132,37 @@ static bssl::UniquePtr MakeKeyPairForSelfSignedCert() { static bssl::UniquePtr MakeSelfSignedCert(EVP_PKEY *evp_pkey, const int valid_days) { + uint64_t serial; bssl::UniquePtr x509(X509_new()); - uint32_t serial; - RAND_bytes(reinterpret_cast(&serial), sizeof(serial)); - ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), serial >> 1); - X509_gmtime_adj(X509_get_notBefore(x509.get()), 0); - X509_gmtime_adj(X509_get_notAfter(x509.get()), 60 * 60 * 24 * valid_days); + if (!x509 || // + !X509_set_version(x509.get(), X509_VERSION_3) || + !RAND_bytes(reinterpret_cast(&serial), sizeof(serial)) || + !ASN1_INTEGER_set_uint64(X509_get_serialNumber(x509.get()), serial) || + !X509_gmtime_adj(X509_get_notBefore(x509.get()), 0) || + !X509_gmtime_adj(X509_get_notAfter(x509.get()), + 60 * 60 * 24 * valid_days)) { + return nullptr; + } - X509_NAME* subject = X509_get_subject_name(x509.get()); - X509_NAME_add_entry_by_txt(subject, "C", MBSTRING_ASC, - reinterpret_cast("US"), -1, -1, - 0); - X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC, - reinterpret_cast("BoringSSL"), -1, - -1, 0); - X509_set_issuer_name(x509.get(), subject); + X509_NAME *subject = X509_get_subject_name(x509.get()); + if (!X509_NAME_add_entry_by_txt(subject, "C", MBSTRING_ASC, + reinterpret_cast("US"), -1, + -1, 0) || + !X509_NAME_add_entry_by_txt( + subject, "O", MBSTRING_ASC, + reinterpret_cast("BoringSSL"), -1, -1, 0) || + !X509_set_issuer_name(x509.get(), subject)) { + return nullptr; + } + + // macOS requires an explicit EKU extension. + bssl::UniquePtr ekus(sk_ASN1_OBJECT_new_null()); + if (!ekus || + !sk_ASN1_OBJECT_push(ekus.get(), OBJ_nid2obj(NID_server_auth)) || + !X509_add1_ext_i2d(x509.get(), NID_ext_key_usage, ekus.get(), /*crit=*/1, + /*flags=*/0)) { + return nullptr; + } if (!X509_set_pubkey(x509.get(), evp_pkey)) { fprintf(stderr, "Failed to set public key.\n"); diff --git a/third_party/boringssl/kit/src/tool/speed.cc b/third_party/boringssl/kit/src/tool/speed.cc index b91a4ceb..8b4b13c6 100644 --- a/third_party/boringssl/kit/src/tool/speed.cc +++ b/third_party/boringssl/kit/src/tool/speed.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -28,19 +29,22 @@ #include #include #include -#include +#include #include +#include #include -#include #include -#include #include +#include +#include #include #include +#include #include #include #include #include +#include #include #if defined(OPENSSL_WINDOWS) @@ -53,6 +57,12 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) #include #endif +#if defined(OPENSSL_THREADS) +#include +#include +#include +#endif + #include "../crypto/ec_extra/internal.h" #include "../crypto/fipsmodule/ec/internal.h" #include "../crypto/internal.h" @@ -65,17 +75,18 @@ static bool g_print_json = false; // TimeResults represents the results of benchmarking a function. struct TimeResults { // num_calls is the number of function calls done in the time period. - unsigned num_calls; + uint64_t num_calls; // us is the number of microseconds that elapsed in the time period. - unsigned us; + uint64_t us; void Print(const std::string &description) const { if (g_print_json) { PrintJSON(description); } else { - printf("Did %u %s operations in %uus (%.1f ops/sec)\n", num_calls, - description.c_str(), us, - (static_cast(num_calls) / us) * 1000000); + printf( + "Did %" PRIu64 " %s operations in %" PRIu64 "us (%.1f ops/sec)\n", + num_calls, description.c_str(), us, + (static_cast(num_calls) / static_cast(us)) * 1000000); } } @@ -84,10 +95,13 @@ struct TimeResults { if (g_print_json) { PrintJSON(description, bytes_per_call); } else { - printf("Did %u %s operations in %uus (%.1f ops/sec): %.1f MB/s\n", - num_calls, description.c_str(), us, - (static_cast(num_calls) / us) * 1000000, - static_cast(bytes_per_call * num_calls) / us); + printf( + "Did %" PRIu64 " %s operations in %" PRIu64 + "us (%.1f ops/sec): %.1f MB/s\n", + num_calls, description.c_str(), us, + (static_cast(num_calls) / static_cast(us)) * 1000000, + static_cast(bytes_per_call * num_calls) / + static_cast(us)); } } @@ -98,7 +112,8 @@ struct TimeResults { puts(","); } - printf("{\"description\": \"%s\", \"numCalls\": %u, \"microseconds\": %u", + printf("{\"description\": \"%s\", \"numCalls\": %" PRIu64 + ", \"microseconds\": %" PRIu64, description.c_str(), num_calls, us); if (bytes_per_call > 0) { @@ -145,33 +160,37 @@ static uint64_t time_now() { static uint64_t g_timeout_seconds = 1; static std::vector g_chunk_lengths = {16, 256, 1350, 8192, 16384}; -static bool TimeFunction(TimeResults *results, std::function func) { +// IterationsBetweenTimeChecks returns the number of iterations of |func| to run +// in between checking the time, or zero on error. +static uint32_t IterationsBetweenTimeChecks(std::function func) { + uint64_t start = time_now(); + if (!func()) { + return 0; + } + uint64_t delta = time_now() - start; + if (delta == 0) { + return 250; + } + + // Aim for about 100ms between time checks. + uint32_t ret = static_cast(100000) / static_cast(delta); + if (ret > 1000) { + ret = 1000; + } else if (ret < 1) { + ret = 1; + } + return ret; +} + +static bool TimeFunctionImpl(TimeResults *results, std::function func, + uint32_t iterations_between_time_checks) { // total_us is the total amount of time that we'll aim to measure a function // for. const uint64_t total_us = g_timeout_seconds * 1000000; - uint64_t start = time_now(), now, delta; - unsigned done = 0, iterations_between_time_checks; - - if (!func()) { - return false; - } - now = time_now(); - delta = now - start; - if (delta == 0) { - iterations_between_time_checks = 250; - } else { - // Aim for about 100ms between time checks. - iterations_between_time_checks = - static_cast(100000) / static_cast(delta); - if (iterations_between_time_checks > 1000) { - iterations_between_time_checks = 1000; - } else if (iterations_between_time_checks < 1) { - iterations_between_time_checks = 1; - } - } - + uint64_t start = time_now(), now; + uint64_t done = 0; for (;;) { - for (unsigned i = 0; i < iterations_between_time_checks; i++) { + for (uint32_t i = 0; i < iterations_between_time_checks; i++) { if (!func()) { return false; } @@ -189,6 +208,93 @@ static bool TimeFunction(TimeResults *results, std::function func) { return true; } +static bool TimeFunction(TimeResults *results, std::function func) { + uint32_t iterations_between_time_checks = IterationsBetweenTimeChecks(func); + if (iterations_between_time_checks == 0) { + return false; + } + + return TimeFunctionImpl(results, std::move(func), + iterations_between_time_checks); +} + +#if defined(OPENSSL_THREADS) +// g_threads is the number of threads to run in parallel benchmarks. +static int g_threads = 1; + +// Latch behaves like C++20 std::latch. +class Latch { + public: + explicit Latch(int expected) : expected_(expected) {} + Latch(const Latch &) = delete; + Latch &operator=(const Latch &) = delete; + + void ArriveAndWait() { + std::unique_lock lock(lock_); + expected_--; + if (expected_ > 0) { + cond_.wait(lock, [&] { return expected_ == 0; }); + } else { + cond_.notify_all(); + } + } + + private: + int expected_; + std::mutex lock_; + std::condition_variable cond_; +}; + +static bool TimeFunctionParallel(TimeResults *results, + std::function func) { + if (g_threads <= 1) { + return TimeFunction(results, std::move(func)); + } + + uint32_t iterations_between_time_checks = IterationsBetweenTimeChecks(func); + if (iterations_between_time_checks == 0) { + return false; + } + + struct ThreadResult { + TimeResults time_result; + bool ok = false; + }; + std::vector thread_results(g_threads); + Latch latch(g_threads); + std::vector threads; + for (int i = 0; i < g_threads; i++) { + threads.emplace_back([&, i] { + // Wait for all the threads to be ready before running the benchmark. + latch.ArriveAndWait(); + thread_results[i].ok = TimeFunctionImpl( + &thread_results[i].time_result, func, iterations_between_time_checks); + }); + } + + for (auto &thread : threads) { + thread.join(); + } + + results->num_calls = 0; + results->us = 0; + for (const auto& pair : thread_results) { + if (!pair.ok) { + return false; + } + results->num_calls += pair.time_result.num_calls; + results->us += pair.time_result.us; + } + return true; +} + +#else +static bool TimeFunctionParallel(TimeResults *results, + std::function func) { + return TimeFunction(results, std::move(func)); +} +#endif + static bool SpeedRSA(const std::string &selected) { if (!selected.empty() && selected.find("RSA") == std::string::npos) { return true; @@ -203,7 +309,7 @@ static bool SpeedRSA(const std::string &selected) { {"RSA 4096", kDERRSAPrivate4096, kDERRSAPrivate4096Len}, }; - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kRSAKeys); i++) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kRSAKeys); i++) { const std::string name = kRSAKeys[i].name; bssl::UniquePtr key( @@ -214,18 +320,21 @@ static bool SpeedRSA(const std::string &selected) { return false; } - std::unique_ptr sig(new uint8_t[RSA_size(key.get())]); + static constexpr size_t kMaxSignature = 512; + if (RSA_size(key.get()) > kMaxSignature) { + abort(); + } const uint8_t fake_sha256_hash[32] = {0}; - unsigned sig_len; TimeResults results; - if (!TimeFunction(&results, - [&key, &sig, &fake_sha256_hash, &sig_len]() -> bool { - // Usually during RSA signing we're using a long-lived |RSA| that has - // already had all of its |BN_MONT_CTX|s constructed, so it makes - // sense to use |key| directly here. - return RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash), - sig.get(), &sig_len, key.get()); + if (!TimeFunctionParallel(&results, [&key, &fake_sha256_hash]() -> bool { + // Usually during RSA signing we're using a long-lived |RSA| that + // has already had all of its |BN_MONT_CTX|s constructed, so it + // makes sense to use |key| directly here. + uint8_t out[kMaxSignature]; + unsigned out_len; + return RSA_sign(NID_sha256, fake_sha256_hash, + sizeof(fake_sha256_hash), out, &out_len, key.get()); })) { fprintf(stderr, "RSA_sign failed.\n"); ERR_print_errors_fp(stderr); @@ -233,46 +342,47 @@ static bool SpeedRSA(const std::string &selected) { } results.Print(name + " signing"); - if (!TimeFunction(&results, - [&key, &fake_sha256_hash, &sig, sig_len]() -> bool { - return RSA_verify( - NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash), - sig.get(), sig_len, key.get()); - })) { + uint8_t sig[kMaxSignature]; + unsigned sig_len; + if (!RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash), sig, + &sig_len, key.get())) { + return false; + } + if (!TimeFunctionParallel( + &results, [&key, &fake_sha256_hash, &sig, sig_len]() -> bool { + return RSA_verify(NID_sha256, fake_sha256_hash, + sizeof(fake_sha256_hash), sig, sig_len, + key.get()); + })) { fprintf(stderr, "RSA_verify failed.\n"); ERR_print_errors_fp(stderr); return false; } results.Print(name + " verify (same key)"); - if (!TimeFunction(&results, - [&key, &fake_sha256_hash, &sig, sig_len]() -> bool { - // Usually during RSA verification we have to parse an RSA key from a - // certificate or similar, in which case we'd need to construct a new - // RSA key, with a new |BN_MONT_CTX| for the public modulus. If we - // were to use |key| directly instead, then these costs wouldn't be - // accounted for. - bssl::UniquePtr verify_key(RSA_new()); - if (!verify_key) { - return false; - } - verify_key->n = BN_dup(key->n); - verify_key->e = BN_dup(key->e); - if (!verify_key->n || - !verify_key->e) { - return false; - } - return RSA_verify(NID_sha256, fake_sha256_hash, - sizeof(fake_sha256_hash), sig.get(), sig_len, - verify_key.get()); - })) { + if (!TimeFunctionParallel( + &results, [&key, &fake_sha256_hash, &sig, sig_len]() -> bool { + // Usually during RSA verification we have to parse an RSA key + // from a certificate or similar, in which case we'd need to + // construct a new RSA key, with a new |BN_MONT_CTX| for the + // public modulus. If we were to use |key| directly instead, then + // these costs wouldn't be accounted for. + bssl::UniquePtr verify_key(RSA_new_public_key( + RSA_get0_n(key.get()), RSA_get0_e(key.get()))); + if (!verify_key) { + return false; + } + return RSA_verify(NID_sha256, fake_sha256_hash, + sizeof(fake_sha256_hash), sig, sig_len, + verify_key.get()); + })) { fprintf(stderr, "RSA_verify failed.\n"); ERR_print_errors_fp(stderr); return false; } results.Print(name + " verify (fresh key)"); - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { return bssl::UniquePtr(RSA_private_key_from_bytes( kRSAKeys[i].key, kRSAKeys[i].key_len)) != nullptr; })) { @@ -300,9 +410,9 @@ static bool SpeedRSAKeyGen(const std::string &selected) { const std::vector kSizes = {2048, 3072, 4096}; for (int size : kSizes) { const uint64_t start = time_now(); - unsigned num_calls = 0; - unsigned us; - std::vector durations; + uint64_t num_calls = 0; + uint64_t us; + std::vector durations; for (;;) { bssl::UniquePtr rsa(RSA_new()); @@ -335,18 +445,13 @@ static bool SpeedRSAKeyGen(const std::string &selected) { // Distribution information is useful, but doesn't fit into the standard // format used by |g_print_json|. if (!g_print_json) { - // |min| and |max| must be stored in temporary variables to avoid an MSVC - // bug on x86. There, size_t is a typedef for unsigned, but MSVC's printf - // warning tries to retain the distinction and suggest %zu for size_t - // instead of %u. It gets confused if std::vector and - // std::vector are both instantiated. Being typedefs, the two - // instantiations are identical, which somehow breaks the size_t vs - // unsigned metadata. - unsigned min = durations[0]; - unsigned median = n & 1 ? durations[n / 2] + uint64_t min = durations[0]; + uint64_t median = n & 1 ? durations[n / 2] : (durations[n / 2 - 1] + durations[n / 2]) / 2; - unsigned max = durations[n - 1]; - printf(" min: %uus, median: %uus, max: %uus\n", min, median, max); + uint64_t max = durations[n - 1]; + printf(" min: %" PRIu64 "us, median: %" PRIu64 "us, max: %" PRIu64 + "us\n", + min, median, max); } } @@ -409,6 +514,8 @@ static bool SpeedAEADChunk(const EVP_AEAD *aead, std::string name, return false; } + // TODO(davidben): In most cases, this can be |TimeFunctionParallel|, but a + // few stateful AEADs must be run serially. TimeResults results; if (direction == evp_aead_seal) { if (!TimeFunction(&results, @@ -499,7 +606,7 @@ static bool SpeedAESBlock(const std::string &name, unsigned bits, { TimeResults results; - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { AES_KEY key; return AES_set_encrypt_key(kZero, bits, &key) == 0; })) { @@ -516,7 +623,7 @@ static bool SpeedAESBlock(const std::string &name, unsigned bits, } uint8_t block[16] = {0}; TimeResults results; - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { AES_encrypt(block, block, &key); return true; })) { @@ -528,7 +635,7 @@ static bool SpeedAESBlock(const std::string &name, unsigned bits, { TimeResults results; - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { AES_KEY key; return AES_set_decrypt_key(kZero, bits, &key) == 0; })) { @@ -545,7 +652,7 @@ static bool SpeedAESBlock(const std::string &name, unsigned bits, } uint8_t block[16] = {0}; TimeResults results; - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { AES_decrypt(block, block, &key); return true; })) { @@ -560,21 +667,21 @@ static bool SpeedAESBlock(const std::string &name, unsigned bits, static bool SpeedHashChunk(const EVP_MD *md, std::string name, size_t chunk_len) { - bssl::ScopedEVP_MD_CTX ctx; - uint8_t scratch[16384]; + uint8_t input[16384] = {0}; - if (chunk_len > sizeof(scratch)) { + if (chunk_len > sizeof(input)) { return false; } name += ChunkLenSuffix(chunk_len); TimeResults results; - if (!TimeFunction(&results, [&ctx, md, chunk_len, &scratch]() -> bool { + if (!TimeFunctionParallel(&results, [md, chunk_len, &input]() -> bool { uint8_t digest[EVP_MAX_MD_SIZE]; unsigned int md_len; + bssl::ScopedEVP_MD_CTX ctx; return EVP_DigestInit_ex(ctx.get(), md, NULL /* ENGINE */) && - EVP_DigestUpdate(ctx.get(), scratch, chunk_len) && + EVP_DigestUpdate(ctx.get(), input, chunk_len) && EVP_DigestFinal_ex(ctx.get(), digest, &md_len); })) { fprintf(stderr, "EVP_DigestInit_ex failed.\n"); @@ -602,15 +709,15 @@ static bool SpeedHash(const EVP_MD *md, const std::string &name, } static bool SpeedRandomChunk(std::string name, size_t chunk_len) { - uint8_t scratch[16384]; - - if (chunk_len > sizeof(scratch)) { + static constexpr size_t kMaxChunk = 16384; + if (chunk_len > kMaxChunk) { return false; } name += ChunkLenSuffix(chunk_len); TimeResults results; - if (!TimeFunction(&results, [chunk_len, &scratch]() -> bool { + if (!TimeFunctionParallel(&results, [chunk_len]() -> bool { + uint8_t scratch[kMaxChunk]; RAND_bytes(scratch, chunk_len); return true; })) { @@ -662,29 +769,29 @@ static bool SpeedECDHCurve(const std::string &name, int nid, } TimeResults results; - if (!TimeFunction(&results, [nid, peer_value_len, &peer_value]() -> bool { - bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); - if (!key || - !EC_KEY_generate_key(key.get())) { - return false; - } - const EC_GROUP *const group = EC_KEY_get0_group(key.get()); - bssl::UniquePtr point(EC_POINT_new(group)); - bssl::UniquePtr peer_point(EC_POINT_new(group)); - bssl::UniquePtr ctx(BN_CTX_new()); - bssl::UniquePtr x(BN_new()); - if (!point || !peer_point || !ctx || !x || - !EC_POINT_oct2point(group, peer_point.get(), peer_value.get(), - peer_value_len, ctx.get()) || - !EC_POINT_mul(group, point.get(), nullptr, peer_point.get(), - EC_KEY_get0_private_key(key.get()), ctx.get()) || - !EC_POINT_get_affine_coordinates_GFp(group, point.get(), x.get(), - nullptr, ctx.get())) { - return false; - } + if (!TimeFunctionParallel( + &results, [nid, peer_value_len, &peer_value]() -> bool { + bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); + if (!key || !EC_KEY_generate_key(key.get())) { + return false; + } + const EC_GROUP *const group = EC_KEY_get0_group(key.get()); + bssl::UniquePtr point(EC_POINT_new(group)); + bssl::UniquePtr peer_point(EC_POINT_new(group)); + bssl::UniquePtr ctx(BN_CTX_new()); + bssl::UniquePtr x(BN_new()); + if (!point || !peer_point || !ctx || !x || + !EC_POINT_oct2point(group, peer_point.get(), peer_value.get(), + peer_value_len, ctx.get()) || + !EC_POINT_mul(group, point.get(), nullptr, peer_point.get(), + EC_KEY_get0_private_key(key.get()), ctx.get()) || + !EC_POINT_get_affine_coordinates_GFp( + group, point.get(), x.get(), nullptr, ctx.get())) { + return false; + } - return true; - })) { + return true; + })) { return false; } @@ -704,17 +811,18 @@ static bool SpeedECDSACurve(const std::string &name, int nid, return false; } - uint8_t signature[256]; - if (ECDSA_size(key.get()) > sizeof(signature)) { - return false; + static constexpr size_t kMaxSignature = 256; + if (ECDSA_size(key.get()) > kMaxSignature) { + abort(); } uint8_t digest[20]; OPENSSL_memset(digest, 42, sizeof(digest)); - unsigned sig_len; TimeResults results; - if (!TimeFunction(&results, [&key, &signature, &digest, &sig_len]() -> bool { - return ECDSA_sign(0, digest, sizeof(digest), signature, &sig_len, + if (!TimeFunctionParallel(&results, [&key, &digest]() -> bool { + uint8_t out[kMaxSignature]; + unsigned out_len; + return ECDSA_sign(0, digest, sizeof(digest), out, &out_len, key.get()) == 1; })) { return false; @@ -722,10 +830,17 @@ static bool SpeedECDSACurve(const std::string &name, int nid, results.Print(name + " signing"); - if (!TimeFunction(&results, [&key, &signature, &digest, sig_len]() -> bool { - return ECDSA_verify(0, digest, sizeof(digest), signature, sig_len, - key.get()) == 1; - })) { + uint8_t signature[kMaxSignature]; + unsigned sig_len; + if (!ECDSA_sign(0, digest, sizeof(digest), signature, &sig_len, key.get())) { + return false; + } + + if (!TimeFunctionParallel( + &results, [&key, &signature, &digest, sig_len]() -> bool { + return ECDSA_verify(0, digest, sizeof(digest), signature, sig_len, + key.get()) == 1; + })) { return false; } @@ -754,10 +869,8 @@ static bool Speed25519(const std::string &selected) { } TimeResults results; - - uint8_t public_key[32], private_key[64]; - - if (!TimeFunction(&results, [&public_key, &private_key]() -> bool { + if (!TimeFunctionParallel(&results, []() -> bool { + uint8_t public_key[32], private_key[64]; ED25519_keypair(public_key, private_key); return true; })) { @@ -766,19 +879,25 @@ static bool Speed25519(const std::string &selected) { results.Print("Ed25519 key generation"); + uint8_t public_key[32], private_key[64]; + ED25519_keypair(public_key, private_key); static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5}; - uint8_t signature[64]; - if (!TimeFunction(&results, [&private_key, &signature]() -> bool { - return ED25519_sign(signature, kMessage, sizeof(kMessage), - private_key) == 1; + if (!TimeFunctionParallel(&results, [&private_key]() -> bool { + uint8_t out[64]; + return ED25519_sign(out, kMessage, sizeof(kMessage), private_key) == 1; })) { return false; } results.Print("Ed25519 signing"); - if (!TimeFunction(&results, [&public_key, &signature]() -> bool { + uint8_t signature[64]; + if (!ED25519_sign(signature, kMessage, sizeof(kMessage), private_key)) { + return false; + } + + if (!TimeFunctionParallel(&results, [&public_key, &signature]() -> bool { return ED25519_verify(kMessage, sizeof(kMessage), signature, public_key) == 1; })) { @@ -788,7 +907,7 @@ static bool Speed25519(const std::string &selected) { results.Print("Ed25519 verify"); - if (!TimeFunction(&results, []() -> bool { + if (!TimeFunctionParallel(&results, []() -> bool { uint8_t out[32], in[32]; OPENSSL_memset(in, 0, sizeof(in)); X25519_public_from_private(out, in); @@ -800,7 +919,7 @@ static bool Speed25519(const std::string &selected) { results.Print("Curve25519 base-point multiplication"); - if (!TimeFunction(&results, []() -> bool { + if (!TimeFunctionParallel(&results, []() -> bool { uint8_t out[32], in1[32], in2[32]; OPENSSL_memset(in1, 0, sizeof(in1)); OPENSSL_memset(in2, 0, sizeof(in2)); @@ -840,10 +959,10 @@ static bool SpeedSPAKE2(const std::string &selected) { return false; } - if (!TimeFunction(&results, [&alice_msg, alice_msg_len]() -> bool { - bssl::UniquePtr bob(SPAKE2_CTX_new(spake2_role_bob, - kBobName, sizeof(kBobName), kAliceName, - sizeof(kAliceName))); + if (!TimeFunctionParallel(&results, [&alice_msg, alice_msg_len]() -> bool { + bssl::UniquePtr bob( + SPAKE2_CTX_new(spake2_role_bob, kBobName, sizeof(kBobName), + kAliceName, sizeof(kAliceName))); uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE], bob_key[64]; size_t bob_msg_len, bob_key_len; if (!SPAKE2_generate_msg(bob.get(), bob_msg, &bob_msg_len, @@ -874,7 +993,7 @@ static bool SpeedScrypt(const std::string &selected) { static const char kPassword[] = "password"; static const uint8_t kSalt[] = "NaCl"; - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { uint8_t out[64]; return !!EVP_PBE_scrypt(kPassword, sizeof(kPassword) - 1, kSalt, sizeof(kSalt) - 1, 1024, 8, 16, 0 /* max_mem */, @@ -885,7 +1004,7 @@ static bool SpeedScrypt(const std::string &selected) { } results.Print("scrypt (N = 1024, r = 8, p = 16)"); - if (!TimeFunction(&results, [&]() -> bool { + if (!TimeFunctionParallel(&results, [&]() -> bool { uint8_t out[64]; return !!EVP_PBE_scrypt(kPassword, sizeof(kPassword) - 1, kSalt, sizeof(kSalt) - 1, 16384, 8, 1, 0 /* max_mem */, @@ -906,7 +1025,7 @@ static bool SpeedHRSS(const std::string &selected) { TimeResults results; - if (!TimeFunction(&results, []() -> bool { + if (!TimeFunctionParallel(&results, []() -> bool { struct HRSS_public_key pub; struct HRSS_private_key priv; uint8_t entropy[HRSS_GENERATE_KEY_BYTES]; @@ -927,22 +1046,29 @@ static bool SpeedHRSS(const std::string &selected) { return false; } - uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; - if (!TimeFunction(&results, [&pub, &ciphertext]() -> bool { + if (!TimeFunctionParallel(&results, [&pub]() -> bool { uint8_t entropy[HRSS_ENCAP_BYTES]; uint8_t shared_key[HRSS_KEY_BYTES]; + uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; RAND_bytes(entropy, sizeof(entropy)); return HRSS_encap(ciphertext, shared_key, &pub, entropy); })) { fprintf(stderr, "Failed to time HRSS_encap.\n"); return false; } - results.Print("HRSS encap"); - if (!TimeFunction(&results, [&priv, &ciphertext]() -> bool { - uint8_t shared_key[HRSS_KEY_BYTES]; - return HRSS_decap(shared_key, &priv, ciphertext, sizeof(ciphertext)); + uint8_t entropy[HRSS_ENCAP_BYTES]; + uint8_t shared_key[HRSS_KEY_BYTES]; + uint8_t ciphertext[HRSS_CIPHERTEXT_BYTES]; + RAND_bytes(entropy, sizeof(entropy)); + if (!HRSS_encap(ciphertext, shared_key, &pub, entropy)) { + return false; + } + + if (!TimeFunctionParallel(&results, [&priv, &ciphertext]() -> bool { + uint8_t shared_key2[HRSS_KEY_BYTES]; + return HRSS_decap(shared_key2, &priv, ciphertext, sizeof(ciphertext)); })) { fprintf(stderr, "Failed to time HRSS_encap.\n"); return false; @@ -953,6 +1079,55 @@ static bool SpeedHRSS(const std::string &selected) { return true; } +static bool SpeedKyber(const std::string &selected) { + if (!selected.empty() && selected != "Kyber") { + return true; + } + + TimeResults results; + + uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES]; + // This ciphertext is nonsense, but Kyber decap is constant-time so, for the + // purposes of timing, it's fine. + memset(ciphertext, 42, sizeof(ciphertext)); + if (!TimeFunctionParallel(&results, [&]() -> bool { + KYBER_private_key priv; + uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES]; + KYBER_generate_key(encoded_public_key, &priv); + uint8_t shared_secret[32]; + KYBER_decap(shared_secret, sizeof(shared_secret), ciphertext, &priv); + return true; + })) { + fprintf(stderr, "Failed to time KYBER_generate_key + KYBER_decap.\n"); + return false; + } + + results.Print("Kyber generate + decap"); + + KYBER_private_key priv; + uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES]; + KYBER_generate_key(encoded_public_key, &priv); + KYBER_public_key pub; + if (!TimeFunctionParallel(&results, [&]() -> bool { + CBS encoded_public_key_cbs; + CBS_init(&encoded_public_key_cbs, encoded_public_key, + sizeof(encoded_public_key)); + if (!KYBER_parse_public_key(&pub, &encoded_public_key_cbs)) { + return false; + } + uint8_t shared_secret[32]; + KYBER_encap(ciphertext, shared_secret, sizeof(shared_secret), &pub); + return true; + })) { + fprintf(stderr, "Failed to time KYBER_encap.\n"); + return false; + } + + results.Print("Kyber parse + encap"); + + return true; +} + static bool SpeedHashToCurve(const std::string &selected) { if (!selected.empty() && selected.find("hashtocurve") == std::string::npos) { return true; @@ -965,24 +1140,38 @@ static bool SpeedHashToCurve(const std::string &selected) { TimeResults results; { - EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1); - if (group == NULL) { + const EC_GROUP *p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (p256 == NULL) { return false; } - if (!TimeFunction(&results, [&]() -> bool { - EC_RAW_POINT out; - return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07( - group, &out, kLabel, sizeof(kLabel), input, sizeof(input)); + if (!TimeFunctionParallel(&results, [&]() -> bool { + EC_JACOBIAN out; + return ec_hash_to_curve_p256_xmd_sha256_sswu( + p256, &out, kLabel, sizeof(kLabel), input, sizeof(input)); })) { fprintf(stderr, "hash-to-curve failed.\n"); return false; } - results.Print("hash-to-curve P384_XMD:SHA-512_SSWU_RO_"); + results.Print("hash-to-curve P256_XMD:SHA-256_SSWU_RO_"); - if (!TimeFunction(&results, [&]() -> bool { + const EC_GROUP *p384 = EC_GROUP_new_by_curve_name(NID_secp384r1); + if (p384 == NULL) { + return false; + } + if (!TimeFunctionParallel(&results, [&]() -> bool { + EC_JACOBIAN out; + return ec_hash_to_curve_p384_xmd_sha384_sswu( + p384, &out, kLabel, sizeof(kLabel), input, sizeof(input)); + })) { + fprintf(stderr, "hash-to-curve failed.\n"); + return false; + } + results.Print("hash-to-curve P384_XMD:SHA-384_SSWU_RO_"); + + if (!TimeFunctionParallel(&results, [&]() -> bool { EC_SCALAR out; return ec_hash_to_scalar_p384_xmd_sha512_draft07( - group, &out, kLabel, sizeof(kLabel), input, sizeof(input)); + p384, &out, kLabel, sizeof(kLabel), input, sizeof(input)); })) { fprintf(stderr, "hash-to-scalar failed.\n"); return false; @@ -1020,11 +1209,11 @@ static bool SpeedBase64(const std::string &selected) { "HWy+iMf6/7p/Ak/SIicM4XSwmlQ8pPxAZPr+E2LoVd9pMpWUwpW2UbtO5wsGTrY5" "sO45tFNN/y+jtUheB1C2ijObG/tXELaiyCdM+S/waeuv0MXtI4xnn1A="; - std::vector out(strlen(kInput)); - size_t len; TimeResults results; - if (!TimeFunction(&results, [&]() -> bool { - return EVP_DecodeBase64(out.data(), &len, out.size(), + if (!TimeFunctionParallel(&results, [&]() -> bool { + uint8_t out[sizeof(kInput)]; + size_t len; + return EVP_DecodeBase64(out, &len, sizeof(out), reinterpret_cast(kInput), strlen(kInput)); })) { @@ -1035,14 +1224,33 @@ static bool SpeedBase64(const std::string &selected) { return true; } -static TRUST_TOKEN_PRETOKEN *trust_token_pretoken_dup( - TRUST_TOKEN_PRETOKEN *in) { - TRUST_TOKEN_PRETOKEN *out = - (TRUST_TOKEN_PRETOKEN *)OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN)); - if (out) { - OPENSSL_memcpy(out, in, sizeof(TRUST_TOKEN_PRETOKEN)); +static bool SpeedSipHash(const std::string &selected) { + if (!selected.empty() && selected.find("siphash") == std::string::npos) { + return true; } - return out; + + uint64_t key[2] = {0}; + for (size_t len : g_chunk_lengths) { + std::vector input(len); + TimeResults results; + if (!TimeFunctionParallel(&results, [&]() -> bool { + SIPHASH_24(key, input.data(), input.size()); + return true; + })) { + fprintf(stderr, "SIPHASH_24 failed.\n"); + ERR_print_errors_fp(stderr); + return false; + } + results.PrintWithBytes("SipHash-2-4" + ChunkLenSuffix(len), len); + } + + return true; +} + +static TRUST_TOKEN_PRETOKEN *trust_token_pretoken_dup( + const TRUST_TOKEN_PRETOKEN *in) { + return static_cast( + OPENSSL_memdup(in, sizeof(TRUST_TOKEN_PRETOKEN))); } static bool SpeedTrustToken(std::string name, const TRUST_TOKEN_METHOD *method, @@ -1217,17 +1425,14 @@ static bool SpeedTrustToken(std::string name, const TRUST_TOKEN_METHOD *method, bssl::UniquePtr free_redeem_msg(redeem_msg); if (!TimeFunction(&results, [&]() -> bool { - uint8_t *redeem_resp = NULL; - size_t redeem_resp_len; - TRUST_TOKEN *rtoken = NULL; + uint32_t public_value; + uint8_t private_value; + TRUST_TOKEN *rtoken; uint8_t *client_data = NULL; size_t client_data_len; - uint64_t redemption_time; int ok = TRUST_TOKEN_ISSUER_redeem( - issuer.get(), &redeem_resp, &redeem_resp_len, &rtoken, &client_data, - &client_data_len, &redemption_time, redeem_msg, redeem_msg_len, - /*lifetime=*/600); - OPENSSL_free(redeem_resp); + issuer.get(), &public_value, &private_value, &rtoken, &client_data, + &client_data_len, redeem_msg, redeem_msg_len); OPENSSL_free(client_data); TRUST_TOKEN_free(rtoken); return ok; @@ -1237,38 +1442,20 @@ static bool SpeedTrustToken(std::string name, const TRUST_TOKEN_METHOD *method, } results.Print(name + " redeem"); - uint8_t *redeem_resp = NULL; - size_t redeem_resp_len; - TRUST_TOKEN *rtoken = NULL; + uint32_t public_value; + uint8_t private_value; + TRUST_TOKEN *rtoken; uint8_t *client_data = NULL; size_t client_data_len; - uint64_t redemption_time; - if (!TRUST_TOKEN_ISSUER_redeem(issuer.get(), &redeem_resp, &redeem_resp_len, + if (!TRUST_TOKEN_ISSUER_redeem(issuer.get(), &public_value, &private_value, &rtoken, &client_data, &client_data_len, - &redemption_time, redeem_msg, redeem_msg_len, - /*lifetime=*/600)) { + redeem_msg, redeem_msg_len)) { fprintf(stderr, "TRUST_TOKEN_ISSUER_redeem failed.\n"); return false; } - bssl::UniquePtr free_redeem_resp(redeem_resp); bssl::UniquePtr free_client_data(client_data); bssl::UniquePtr free_rtoken(rtoken); - if (!TimeFunction(&results, [&]() -> bool { - uint8_t *srr = NULL, *sig = NULL; - size_t srr_len, sig_len; - int ok = TRUST_TOKEN_CLIENT_finish_redemption( - client.get(), &srr, &srr_len, &sig, &sig_len, redeem_resp, - redeem_resp_len); - OPENSSL_free(srr); - OPENSSL_free(sig); - return ok; - })) { - fprintf(stderr, "TRUST_TOKEN_CLIENT_finish_redemption failed.\n"); - return false; - } - results.Print(name + " finish_redemption"); - return true; } @@ -1317,6 +1504,13 @@ static const struct argument kArguments[] = { "there is no information about the bytes per call for an operation, " "the JSON field for bytesPerCall will be omitted.", }, +#if defined(OPENSSL_THREADS) + { + "-threads", + kOptionalArgument, + "The number of threads to benchmark in parallel (default is 1)", + }, +#endif { "", kOptionalArgument, @@ -1344,6 +1538,12 @@ bool Speed(const std::vector &args) { g_timeout_seconds = atoi(args_map["-timeout"].c_str()); } +#if defined(OPENSSL_THREADS) + if (args_map.count("-threads") != 0) { + g_threads = atoi(args_map["-threads"].c_str()); + } +#endif + if (args_map.count("-chunks") != 0) { g_chunk_lengths.clear(); const char *start = args_map["-chunks"].data(); @@ -1421,6 +1621,7 @@ bool Speed(const std::vector &args) { !SpeedScrypt(selected) || !SpeedRSAKeyGen(selected) || !SpeedHRSS(selected) || + !SpeedKyber(selected) || !SpeedHashToCurve(selected) || !SpeedTrustToken("TrustToken-Exp1-Batch1", TRUST_TOKEN_experiment_v1(), 1, selected) || @@ -1434,7 +1635,8 @@ bool Speed(const std::vector &args) { TRUST_TOKEN_experiment_v2_pmb(), 1, selected) || !SpeedTrustToken("TrustToken-Exp2PMB-Batch10", TRUST_TOKEN_experiment_v2_pmb(), 10, selected) || - !SpeedBase64(selected)) { + !SpeedBase64(selected) || + !SpeedSipHash(selected)) { return false; } #if defined(BORINGSSL_FIPS) diff --git a/third_party/boringssl/kit/src/tool/transport_common.cc b/third_party/boringssl/kit/src/tool/transport_common.cc index cba3c7b9..15358de5 100644 --- a/third_party/boringssl/kit/src/tool/transport_common.cc +++ b/third_party/boringssl/kit/src/tool/transport_common.cc @@ -288,9 +288,9 @@ void PrintConnectionInfo(BIO *bio, const SSL *ssl) { BIO_printf(bio, " Resumed session: %s\n", SSL_session_reused(ssl) ? "yes" : "no"); BIO_printf(bio, " Cipher: %s\n", SSL_CIPHER_standard_name(cipher)); - uint16_t curve = SSL_get_curve_id(ssl); - if (curve != 0) { - BIO_printf(bio, " ECDHE curve: %s\n", SSL_get_curve_name(curve)); + uint16_t group = SSL_get_group_id(ssl); + if (group != 0) { + BIO_printf(bio, " ECDHE group: %s\n", SSL_get_group_name(group)); } uint16_t sigalg = SSL_get_peer_signature_algorithm(ssl); if (sigalg != 0) { @@ -306,13 +306,13 @@ void PrintConnectionInfo(BIO *bio, const SSL *ssl) { const uint8_t *next_proto; unsigned next_proto_len; SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len); - BIO_printf(bio, " Next protocol negotiated: %.*s\n", next_proto_len, - next_proto); + BIO_printf(bio, " Next protocol negotiated: %.*s\n", + static_cast(next_proto_len), next_proto); const uint8_t *alpn; unsigned alpn_len; SSL_get0_alpn_selected(ssl, &alpn, &alpn_len); - BIO_printf(bio, " ALPN protocol: %.*s\n", alpn_len, alpn); + BIO_printf(bio, " ALPN protocol: %.*s\n", static_cast(alpn_len), alpn); const char *host_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); if (host_name != nullptr && SSL_is_server(ssl)) { @@ -843,7 +843,7 @@ class SocketLineReader { } if (i == 0) { - *out_code = code; + *out_code = static_cast(code); } else if (code != *out_code) { fprintf(stderr, "Reply code varied within a single reply: was %u, now %u\n", diff --git a/third_party/boringssl/kit/src/util/BUILD.toplevel b/third_party/boringssl/kit/src/util/BUILD.toplevel index 65e0cdc2..20678644 100644 --- a/third_party/boringssl/kit/src/util/BUILD.toplevel +++ b/third_party/boringssl/kit/src/util/BUILD.toplevel @@ -18,10 +18,7 @@ load( "crypto_headers", "crypto_internal_headers", "crypto_sources", - "crypto_sources_linux_aarch64", - "crypto_sources_linux_ppc64le", - "crypto_sources_linux_x86_64", - "crypto_sources_mac_x86_64", + "crypto_sources_asm", "fips_fragments", "ssl_headers", "ssl_internal_headers", @@ -34,64 +31,51 @@ licenses(["notice"]) exports_files(["LICENSE"]) -config_setting( - name = "linux_aarch64", - values = {"cpu": "aarch64"}, -) +# By default, the C files will expect assembly files, if any, to be linked in +# with the build. This default can be flipped with -DOPENSSL_NO_ASM. If building +# in a configuration where we have no assembly optimizations, -DOPENSSL_NO_ASM +# has no effect, and either value is fine. +# +# Like C files, assembly files are wrapped in #ifdef (or NASM equivalent), so it +# is safe to include a file for the wrong platform in the build. It will just +# output an empty object file. However, we need some platform selectors to +# distinguish between gas or NASM syntax. +# +# For all non-Windows platforms, we use gas assembly syntax and can assume any +# GCC-compatible toolchain includes a gas-compatible assembler. +# +# For Windows, we use NASM on x86 and x86_64 and gas, specifically +# clang-assembler, on aarch64. We have not yet added NASM support to this build, +# and would need to detect MSVC vs clang-cl for aarch64 so, for now, we just +# disable assembly on Windows across the board. +# +# These two selects for asm_sources and asm_copts must be kept in sync. If we +# specify assembly, we don't want OPENSSL_NO_ASM. If we don't specify assembly, +# we want OPENSSL_NO_ASM, in case the C files expect them in some format (e.g. +# NASM) this build file doesn't yet support. +# +# TODO(https://crbug.com/boringssl/531): Enable assembly for Windows. +asm_sources = select({ + "@platforms//os:windows": [], + "//conditions:default": crypto_sources_asm, +}) +asm_copts = select({ + "@platforms//os:windows": ["-DOPENSSL_NO_ASM"], + "//conditions:default": [], +}) -config_setting( - name = "linux_x86_64", - values = {"cpu": "k8"}, -) - -config_setting( - name = "linux_ppc64le", - values = {"cpu": "ppc"}, -) - -config_setting( - name = "mac_x86_64", - values = {"cpu": "darwin"}, -) - -config_setting( - name = "windows_x86_64", - values = {"cpu": "x64_windows"}, -) - -config_setting( - name = "android_legacy", - values = {"crosstool_top": "//external:android/crosstool"}, -) - -config_setting( - name = "android_stlport", - values = {"crosstool_top": "@androidndk//:toolchain-stlport"}, -) - -config_setting( - name = "android_libcpp", - values = {"crosstool_top": "@androidndk//:toolchain-libcpp"}, -) - -config_setting( - name = "android_gnu_libstdcpp", - values = {"crosstool_top": "@androidndk//:toolchain-gnu-libstdcpp"}, -) - -config_setting( - name = "android_default", - values = {"crosstool_top": "@androidndk//:default_crosstool"}, -) - -posix_copts = [ +# Configure C, C++, and common flags for GCC-compatible toolchains. +# +# TODO(davidben): Can we remove some of these? In Bazel, are warnings the +# toolchain or project's responsibility? -Wa,--noexecstack should be unnecessary +# now, though https://crbug.com/boringssl/292 tracks testing this in CI. +# -fno-common did not become default until +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85678. +gcc_copts = [ # Assembler option --noexecstack adds .note.GNU-stack to each object to # ensure that binaries can be built with non-executable stack. "-Wa,--noexecstack", - # This is needed on Linux systems (at least) to get rwlock in pthread. - "-D_XOPEN_SOURCE=700", - # This list of warnings should match those in the top-level CMakeLists.txt. "-Wall", "-Werror", @@ -101,80 +85,60 @@ posix_copts = [ "-Wwrite-strings", "-Wshadow", "-fno-common", - - # Modern build environments should be able to set this to use atomic - # operations for reference counting rather than locks. However, it's - # known not to work on some Android builds. - # "-DOPENSSL_C11_ATOMIC", ] - -boringssl_copts = select({ - ":linux_aarch64": posix_copts, - ":linux_ppc64le": posix_copts, - ":linux_x86_64": posix_copts, - ":mac_x86_64": posix_copts, - ":windows_x86_64": [ - "-DWIN32_LEAN_AND_MEAN", - "-DOPENSSL_NO_ASM", - ], - "//conditions:default": ["-DOPENSSL_NO_ASM"], -}) - -crypto_sources_asm = select({ - ":linux_aarch64": crypto_sources_linux_aarch64, - ":linux_ppc64le": crypto_sources_linux_ppc64le, - ":linux_x86_64": crypto_sources_linux_x86_64, - ":mac_x86_64": crypto_sources_mac_x86_64, - "//conditions:default": [], -}) - -# For C targets only (not C++), compile with C11 support. -posix_copts_c11 = [ +gcc_copts_c11 = [ "-std=c11", "-Wmissing-prototypes", "-Wold-style-definition", "-Wstrict-prototypes", ] - -boringssl_copts_c11 = boringssl_copts + select({ - ":linux_aarch64": posix_copts_c11, - ":linux_ppc64le": posix_copts_c11, - ":linux_x86_64": posix_copts_c11, - ":mac_x86_64": posix_copts_c11, - "//conditions:default": [], -}) - -# For C++ targets only (not C), compile with C++11 support. -posix_copts_cxx = [ - "-std=c++11", +gcc_copts_cxx = [ + "-std=c++14", "-Wmissing-declarations", ] -boringssl_copts_cxx = boringssl_copts + select({ - ":linux_aarch64": posix_copts_cxx, - ":linux_ppc64le": posix_copts_cxx, - ":linux_x86_64": posix_copts_cxx, - ":mac_x86_64": posix_copts_cxx, +boringssl_copts = [ + "-DBORINGSSL_IMPLEMENTATION", +] + select({ + # We assume that non-Windows builds use a GCC-compatible toolchain and that + # Windows builds do not. + # + # TODO(davidben): Should these be querying something in @bazel_tools? + # Unfortunately, @bazel_tools is undocumented. See + # https://github.com/bazelbuild/bazel/issues/14914 + "@platforms//os:windows": [], + "//conditions:default": gcc_copts, +}) + select({ + # This is needed on glibc systems to get rwlock in pthreads, but it should + # not be set on Apple platforms or FreeBSD, where it instead disables APIs + # we use. + # See compat(5), sys/cdefs.h, and https://crbug.com/boringssl/471 + "@platforms//os:linux": ["-D_XOPEN_SOURCE=700"], + # Without WIN32_LEAN_AND_MEAN, pulls in wincrypt.h, which + # conflicts with our . + "@platforms//os:windows": ["-DWIN32_LEAN_AND_MEAN"], "//conditions:default": [], +}) + asm_copts + +boringssl_copts_c11 = boringssl_copts + select({ + "@platforms//os:windows": [], + "//conditions:default": gcc_copts_c11, +}) + +boringssl_copts_cxx = boringssl_copts + select({ + "@platforms//os:windows": [], + "//conditions:default": gcc_copts_cxx, }) cc_library( name = "crypto", - srcs = crypto_sources + crypto_internal_headers + crypto_sources_asm, + srcs = crypto_sources + crypto_internal_headers + asm_sources, hdrs = crypto_headers + fips_fragments, copts = boringssl_copts_c11, includes = ["src/include"], linkopts = select({ - # Android supports pthreads, but does not provide a libpthread - # to link against. - ":android_legacy": [], - ":android_stlport": [], - ":android_libcpp": [], - ":android_gnu_libstdcpp": [], - ":android_default": [], - ":mac_x86_64": [], - ":windows_x86_64": ["-defaultlib:advapi32.lib"], - "//conditions:default": ["-lpthread"], + "@platforms//os:windows": ["-defaultlib:advapi32.lib"], + "//conditions:default": ["-pthread"], }), visibility = ["//visibility:public"], ) diff --git a/third_party/boringssl/kit/src/util/WORKSPACE.toplevel b/third_party/boringssl/kit/src/util/WORKSPACE.toplevel new file mode 100644 index 00000000..58f81bba --- /dev/null +++ b/third_party/boringssl/kit/src/util/WORKSPACE.toplevel @@ -0,0 +1 @@ +workspace(name = "boringssl") diff --git a/third_party/boringssl/kit/src/util/all_tests.go b/third_party/boringssl/kit/src/util/all_tests.go index 884da26b..c0dceba5 100644 --- a/third_party/boringssl/kit/src/util/all_tests.go +++ b/third_party/boringssl/kit/src/util/all_tests.go @@ -1,26 +1,26 @@ -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2015, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main import ( - "bufio" "bytes" "errors" "flag" "fmt" - "math/rand" "os" "os/exec" "path" @@ -175,11 +175,17 @@ func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) { } else { cmd = exec.Command(prog, args...) } - if test.Env != nil { + if test.Env != nil || test.numShards != 0 { cmd.Env = make([]string, len(os.Environ())) copy(cmd.Env, os.Environ()) + } + if test.Env != nil { cmd.Env = append(cmd.Env, test.Env...) } + if test.numShards != 0 { + cmd.Env = append(cmd.Env, fmt.Sprintf("GTEST_SHARD_INDEX=%d", test.shard)) + cmd.Env = append(cmd.Env, fmt.Sprintf("GTEST_TOTAL_SHARDS=%d", test.numShards)) + } var outBuf bytes.Buffer cmd.Stdout = &outBuf cmd.Stderr = &outBuf @@ -265,7 +271,7 @@ func worker(tests <-chan test, results chan<- result, done *sync.WaitGroup) { } func (t test) shortName() string { - return t.Cmd[0] + t.shardMsg() + t.cpuMsg() + t.envMsg() + return strings.Join(t.Cmd, " ") + t.shardMsg() + t.cpuMsg() + t.envMsg() } func SpaceIf(returnSpace bool) string { @@ -276,7 +282,7 @@ func SpaceIf(returnSpace bool) string { } func (t test) longName() string { - return strings.Join(t.Env, " ") + SpaceIf(len(t.Env) != 0) + strings.Join(t.Cmd, " ") + t.cpuMsg() + return strings.Join(t.Env, " ") + SpaceIf(len(t.Env) != 0) + strings.Join(t.Cmd, " ") + t.shardMsg() + t.cpuMsg() } func (t test) shardMsg() string { @@ -313,70 +319,11 @@ func (t test) getGTestShards() ([]test, error) { return []test{t}, nil } - prog := path.Join(*buildDir, t.Cmd[0]) - cmd := exec.Command(prog, "--gtest_list_tests") - var stdout bytes.Buffer - cmd.Stdout = &stdout - if err := cmd.Start(); err != nil { - return nil, err - } - if err := cmd.Wait(); err != nil { - return nil, err - } - - var group string - var tests []string - scanner := bufio.NewScanner(&stdout) - for scanner.Scan() { - line := scanner.Text() - - // Remove the parameter comment and trailing space. - if idx := strings.Index(line, "#"); idx >= 0 { - line = line[:idx] - } - line = strings.TrimSpace(line) - if len(line) == 0 { - continue - } - - if line[len(line)-1] == '.' { - group = line - continue - } - - if len(group) == 0 { - return nil, fmt.Errorf("found test case %q without group", line) - } - tests = append(tests, group+line) - } - - const testsPerShard = 20 - if len(tests) <= testsPerShard { - return []test{t}, nil - } - - // Slow tests which process large test vector files tend to be grouped - // together, so shuffle the order. - shuffled := make([]string, len(tests)) - perm := rand.Perm(len(tests)) - for i, j := range perm { - shuffled[i] = tests[j] - } - - var shards []test - for i := 0; i < len(shuffled); i += testsPerShard { - n := len(shuffled) - i - if n > testsPerShard { - n = testsPerShard - } - shard := t - shard.Cmd = []string{shard.Cmd[0], "--gtest_filter=" + strings.Join(shuffled[i:i+n], ":")} - shard.shard = len(shards) - shards = append(shards, shard) - } - + shards := make([]test, *numWorkers) for i := range shards { - shards[i].numShards = len(shards) + shards[i] = t + shards[i].shard = i + shards[i].numShards = *numWorkers } return shards, nil @@ -477,14 +424,14 @@ func main() { if len(skipped) > 0 { fmt.Printf("\n%d of %d tests were skipped:\n", len(skipped), len(testCases)) for _, test := range skipped { - fmt.Printf("\t%s%s\n", strings.Join(test.Cmd, " "), test.cpuMsg()) + fmt.Printf("\t%s\n", test.shortName()) } } if len(failed) > 0 { fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(testCases)) for _, test := range failed { - fmt.Printf("\t%s%s\n", strings.Join(test.Cmd, " "), test.cpuMsg()) + fmt.Printf("\t%s\n", test.shortName()) } os.Exit(1) } diff --git a/third_party/boringssl/kit/src/util/ar/ar.go b/third_party/boringssl/kit/src/util/ar/ar.go index 756caf53..fdc2dd2b 100644 --- a/third_party/boringssl/kit/src/util/ar/ar.go +++ b/third_party/boringssl/kit/src/util/ar/ar.go @@ -10,7 +10,7 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // ar.go contains functions for parsing .a archive files. diff --git a/third_party/boringssl/kit/src/util/ar/ar_test.go b/third_party/boringssl/kit/src/util/ar/ar_test.go index ef37d795..31baaf16 100644 --- a/third_party/boringssl/kit/src/util/ar/ar_test.go +++ b/third_party/boringssl/kit/src/util/ar/ar_test.go @@ -10,14 +10,13 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package ar import ( "bytes" "flag" - "io/ioutil" "os" "path/filepath" "testing" @@ -52,7 +51,7 @@ var arTests = []arTest{ "linux", "libsample.a", map[string]string{ - "foo.c.o": "foo.c.o", + "foo.c.o": "foo.c.o", "bar.cc.o": "bar.cc.o", }, false, @@ -61,7 +60,7 @@ var arTests = []arTest{ "mac", "libsample.a", map[string]string{ - "foo.c.o": "foo.c.o", + "foo.c.o": "foo.c.o", "bar.cc.o": "bar.cc.o", }, true, @@ -70,7 +69,7 @@ var arTests = []arTest{ "windows", "sample.lib", map[string]string{ - "CMakeFiles\\sample.dir\\foo.c.obj": "foo.c.obj", + "CMakeFiles\\sample.dir\\foo.c.obj": "foo.c.obj", "CMakeFiles\\sample.dir\\bar.cc.obj": "bar.cc.obj", }, false, @@ -92,7 +91,7 @@ func TestAR(t *testing.T) { } for file, contentsPath := range test.out { - expected, err := ioutil.ReadFile(test.Path(contentsPath)) + expected, err := os.ReadFile(test.Path(contentsPath)) if err != nil { t.Fatalf("error reading %s: %s", contentsPath, err) } diff --git a/third_party/boringssl/kit/src/util/bot/DEPS b/third_party/boringssl/kit/src/util/bot/DEPS index ee6f9205..8f5a412d 100644 --- a/third_party/boringssl/kit/src/util/bot/DEPS +++ b/third_party/boringssl/kit/src/util/bot/DEPS @@ -19,23 +19,26 @@ vars = { 'checkout_sde': False, 'checkout_nasm': False, 'checkout_libcxx': False, - 'vs_version': '2015', + 'vs_version': '2019', # Run the following command to see the latest builds in CIPD: # cipd describe PACKAGE_NAME -version latest # infra/3pp/tools/cmake/linux-amd64 - 'cmake_version': 'version:2@3.21.3', + 'cmake_version': 'version:2@3.26.4.chromium.7', # infra/3pp/tools/go/linux-amd64 - 'go_version': 'version:2@1.17.2', + 'go_version': 'version:2@1.20.5', + # infra/3pp/tools/perl/windows-amd64 + 'perl_version': 'version:2@5.32.1.1', # Update the following from - # https://chromium.googlesource.com/chromium/src/+/master/DEPS - 'android_sdk_platform-tools_version': 'g7n_-r6yJd_SGRklujGB1wEt8iyr77FZTUJVS9w6O34C', - 'android_ndk_revision': '401019bf85744311b26c88ced255cd53401af8b7', + # https://chromium.googlesource.com/chromium/src/+/main/DEPS + 'android_sdk_platform-tools_version': 'RSI3iwryh7URLGRgJHsCvUxj092woTPnKt4pwFcJ6L8C', + 'android_ndk_revision': '310956bd122ec2b96049f8d7398de6b717f3452e', 'libfuzzer_revision': 'debe7d2d1982e540fbd6bd78604bf001753f9e74', - 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', - 'libcxxabi_revision': '9b8228b4a9be26e0881f36089d9a8d62df851acc', + 'libcxx_revision': 'f8279b01085b800724f5c5629dc365b9f040dc53', + 'libcxxabi_revision': '899caea3814eeb45c689fc206052968943fd5cb8', + 'ninja_version': 'version:2@1.11.1.chromium.6', } deps = { @@ -53,21 +56,11 @@ deps = { 'dep_type': 'cipd', }, - 'boringssl/util/bot/cmake-linux64': { + 'boringssl/util/bot/cmake': { 'packages': [{ - 'package': 'infra/3pp/tools/cmake/linux-amd64', + 'package': 'infra/3pp/tools/cmake/${{platform}}', 'version': Var('cmake_version'), }], - 'condition': 'host_os == "linux"', - 'dep_type': 'cipd', - }, - - 'boringssl/util/bot/cmake-mac': { - 'packages': [{ - 'package': 'infra/3pp/tools/cmake/mac-amd64', - 'version': Var('cmake_version'), - }], - 'condition': 'host_os == "mac"', 'dep_type': 'cipd', }, @@ -79,6 +72,15 @@ deps = { 'dep_type': 'cipd', }, + 'boringssl/util/bot/perl-win32': { + 'packages': [{ + 'package': 'infra/3pp/tools/perl/${{platform}}', + 'version': Var('perl_version'), + }], + 'condition': 'host_os == "win"', + 'dep_type': 'cipd', + }, + 'boringssl/util/bot/libFuzzer': { 'url': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' +'@' + Var('libfuzzer_revision'), 'condition': 'checkout_fuzzer', @@ -92,6 +94,14 @@ deps = { 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + Var('libcxxabi_revision'), 'condition': 'checkout_libcxx', }, + + 'boringssl/util/bot/ninja': { + 'packages': [{ + 'package': 'infra/3pp/tools/ninja/${{platform}}', + 'version': Var('ninja_version'), + }], + 'dep_type': 'cipd', + } } recursedeps = [ @@ -100,52 +110,6 @@ recursedeps = [ ] hooks = [ - # TODO(https://crbug.com/1180257): Use CIPD for CMake on Windows. - { - 'name': 'cmake_win32', - 'pattern': '.', - 'condition': 'host_os == "win"', - 'action': [ 'download_from_google_storage', - '--no_resume', - '--platform=win32', - '--no_auth', - '--bucket', 'chromium-tools', - '-s', 'boringssl/util/bot/cmake-win32.zip.sha1', - ], - }, - { - 'name': 'cmake_win32_extract', - 'pattern': '.', - 'condition': 'host_os == "win"', - 'action': [ 'python3', - 'boringssl/util/bot/extract.py', - 'boringssl/util/bot/cmake-win32.zip', - 'boringssl/util/bot/cmake-win32/', - ], - }, - { - 'name': 'perl_win32', - 'pattern': '.', - 'condition': 'host_os == "win"', - 'action': [ 'download_from_google_storage', - '--no_resume', - '--platform=win32', - '--no_auth', - '--bucket', 'chromium-tools', - '-s', 'boringssl/util/bot/perl-win32.zip.sha1', - ], - }, - { - 'name': 'perl_win32_extract', - 'pattern': '.', - 'condition': 'host_os == "win"', - 'action': [ 'python3', - 'boringssl/util/bot/extract.py', - '--no-prefix', - 'boringssl/util/bot/perl-win32.zip', - 'boringssl/util/bot/perl-win32/', - ], - }, { 'name': 'nasm_win32', 'pattern': '.', @@ -183,7 +147,7 @@ hooks = [ 'action': [ 'download_from_google_storage', '--no_resume', '--bucket', 'chrome-boringssl-sde', - '-s', 'boringssl/util/bot/sde-linux64.tar.bz2.sha1' + '-s', 'boringssl/util/bot/sde-linux64.tar.xz.sha1' ], }, { @@ -192,7 +156,7 @@ hooks = [ 'condition': 'checkout_sde and host_os == "linux"', 'action': [ 'python3', 'boringssl/util/bot/extract.py', - 'boringssl/util/bot/sde-linux64.tar.bz2', + 'boringssl/util/bot/sde-linux64.tar.xz', 'boringssl/util/bot/sde-linux64/', ], }, @@ -203,7 +167,7 @@ hooks = [ 'action': [ 'download_from_google_storage', '--no_resume', '--bucket', 'chrome-boringssl-sde', - '-s', 'boringssl/util/bot/sde-win32.tar.bz2.sha1' + '-s', 'boringssl/util/bot/sde-win32.tar.xz.sha1' ], }, { @@ -212,7 +176,7 @@ hooks = [ 'condition': 'checkout_sde and host_os == "win"', 'action': [ 'python3', 'boringssl/util/bot/extract.py', - 'boringssl/util/bot/sde-win32.tar.bz2', + 'boringssl/util/bot/sde-win32.tar.xz', 'boringssl/util/bot/sde-win32/', ], }, diff --git a/third_party/boringssl/kit/src/util/bot/UPDATING b/third_party/boringssl/kit/src/util/bot/UPDATING index 2e6b9144..bbe27c75 100644 --- a/third_party/boringssl/kit/src/util/bot/UPDATING +++ b/third_party/boringssl/kit/src/util/bot/UPDATING @@ -12,10 +12,10 @@ DEPS: Update the variables as described in the comments. update_clang.py: Set CLANG_REVISION and CLANG_SUB_REVISION to the values used in Chromium, found at - https://chromium.googlesource.com/chromium/src/+/master/tools/clang/scripts/update.py + https://chromium.googlesource.com/chromium/src/+/main/tools/clang/scripts/update.py vs_toolchain.py: Update _GetDesiredVsToolchainHashes from Chromium, found at - https://chromium.googlesource.com/chromium/src/+/master/build/vs_toolchain.py + https://chromium.googlesource.com/chromium/src/+/main/build/vs_toolchain.py This may require taking other updates to that file. (Don't remove MSVC versions if BoringSSL still needs to support them.) @@ -24,35 +24,20 @@ update, place the updated files in their intended location and run: upload_to_google_storage.py -b chromium-tools FILE -cmake-win32.zip: Update to the latest prebuilt release of CMake, found at - https://cmake.org/download/. Use the file labeled "Windows win64-x64 - ZIP". The download will be named cmake-VERSION-win64-x64.zip. - - The current revision is cmake-3.19.5-win64-x64.zip - nasm-win32.exe: Update to the appropriate release of NASM, found at https://www.nasm.us/. Use the same version as Chromium, found at - https://chromium.googlesource.com/chromium/src/+/master/third_party/nasm/README.chromium + https://chromium.googlesource.com/chromium/deps/nasm/+/refs/heads/main/README.chromium Extract nasm.exe from the download named nasm-VERSION-win64.zip. The current revision is nasm-2.13.03-win64.zip. - TODO(davidben): The Chromium link currently does not work. It will get - filled in in the future. See https://crbug.com/766721. - -perl-win32.zip: Update to the latest 64-bit prebuilt "Portable" edition of - Strawberry Perl, found at http://strawberryperl.com/releases.html. The - download will be named strawberry-perl-VERSION-64bit-portable.zip. - - The current revision is strawberry-perl-5.26.2.1-64bit-portable.zip. - -Finally, update sde-linux64.tar.bz2 and sde-win32.tar.bz2 by downloading the +Finally, update sde-linux64.tar.xz and sde-win32.tar.xz by downloading the latet release from Intel at https://software.intel.com/en-us/articles/intel-software-development-emulator, but upload it with the following command. (Note the bucket is different.) - upload_to_google_storage.py -b chrome-boringssl-sde sde-linux64.tar.bz2 sde-win32.tar.bz2 + upload_to_google_storage.py -b chrome-boringssl-sde sde-linux64.tar.xz sde-win32.tar.xz -The current revision is sde-external-8.50.0-2020-03-26-*.tar.bz2. +The current revision is sde-external-9.14.0-2022-10-25-*.tar.xz. When adding new files, remember to update .gitignore. diff --git a/third_party/boringssl/kit/src/util/bot/cmake-win32.zip.sha1 b/third_party/boringssl/kit/src/util/bot/cmake-win32.zip.sha1 deleted file mode 100644 index d641c172..00000000 --- a/third_party/boringssl/kit/src/util/bot/cmake-win32.zip.sha1 +++ /dev/null @@ -1 +0,0 @@ -b106d66bcdc8a71ea2cdf5446091327bfdb1bcd7 \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/extract.py b/third_party/boringssl/kit/src/util/bot/extract.py index 9b1b88a2..4ef5f651 100644 --- a/third_party/boringssl/kit/src/util/bot/extract.py +++ b/third_party/boringssl/kit/src/util/bot/extract.py @@ -118,6 +118,8 @@ def main(args): entries = IterateTar(archive, 'gz') elif archive.endswith('.tar.bz2'): entries = IterateTar(archive, 'bz2') + elif archive.endswith('.tar.xz'): + entries = IterateTar(archive, 'xz') else: raise ValueError(archive) diff --git a/third_party/boringssl/kit/src/util/bot/perl-win32.zip.sha1 b/third_party/boringssl/kit/src/util/bot/perl-win32.zip.sha1 deleted file mode 100644 index ac0c3f00..00000000 --- a/third_party/boringssl/kit/src/util/bot/perl-win32.zip.sha1 +++ /dev/null @@ -1 +0,0 @@ -10a112b4d5f4efbbba4e45ccbe1fa50943e106c6 \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.bz2.sha1 b/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.bz2.sha1 deleted file mode 100644 index c450f63d..00000000 --- a/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.bz2.sha1 +++ /dev/null @@ -1 +0,0 @@ -baacb5a29755e299d3384c41c6dd55f65235ef1f \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.xz.sha1 b/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.xz.sha1 new file mode 100644 index 00000000..96d3a0df --- /dev/null +++ b/third_party/boringssl/kit/src/util/bot/sde-linux64.tar.xz.sha1 @@ -0,0 +1 @@ +78e7af6ae04e807282d45828ca3c7d12f4eb1d91 \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/sde-win32.tar.bz2.sha1 b/third_party/boringssl/kit/src/util/bot/sde-win32.tar.bz2.sha1 deleted file mode 100644 index b9607470..00000000 --- a/third_party/boringssl/kit/src/util/bot/sde-win32.tar.bz2.sha1 +++ /dev/null @@ -1 +0,0 @@ -cc2d77ff4a221165a8bb13f43ccfbff6550b90c8 \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/sde-win32.tar.xz.sha1 b/third_party/boringssl/kit/src/util/bot/sde-win32.tar.xz.sha1 new file mode 100644 index 00000000..18553e83 --- /dev/null +++ b/third_party/boringssl/kit/src/util/bot/sde-win32.tar.xz.sha1 @@ -0,0 +1 @@ +8d3b079358b548a930046fabb6124c943e1d48fb \ No newline at end of file diff --git a/third_party/boringssl/kit/src/util/bot/update_clang.py b/third_party/boringssl/kit/src/util/bot/update_clang.py index 6d9f68bc..d0b188ad 100644 --- a/third_party/boringssl/kit/src/util/bot/update_clang.py +++ b/third_party/boringssl/kit/src/util/bot/update_clang.py @@ -9,6 +9,7 @@ from __future__ import division from __future__ import print_function import os +import platform import shutil import subprocess import stat @@ -28,8 +29,8 @@ except ImportError: # CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang # to use. These should be synced with tools/clang/scripts/update.py in # Chromium. -CLANG_REVISION = 'llvmorg-14-init-6722-g0fbd3aad' -CLANG_SUB_REVISION = 2 +CLANG_REVISION = 'llvmorg-17-init-12166-g7586aeab' +CLANG_SUB_REVISION = 3 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) @@ -94,7 +95,7 @@ def DownloadAndUnpack(url, output_dir): DownloadUrl(url, f) f.seek(0) EnsureDirExists(output_dir) - tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir) + tarfile.open(mode='r:*', fileobj=f).extractall(path=output_dir) def ReadStampFile(path=STAMP_FILE): @@ -133,11 +134,16 @@ def CopyFile(src, dst): def UpdateClang(): - cds_file = "clang-%s.tgz" % PACKAGE_VERSION + cds_file = "clang-%s.tar.xz" % PACKAGE_VERSION if sys.platform == 'win32' or sys.platform == 'cygwin': cds_full_url = CDS_URL + '/Win/' + cds_file elif sys.platform.startswith('linux'): cds_full_url = CDS_URL + '/Linux_x64/' + cds_file + elif sys.platform == 'darwin': + if platform.machine() == 'arm64': + cds_full_url = CDS_URL + '/Mac_arm64/' + cds_file + else: + cds_full_url = CDS_URL + '/Mac/' + cds_file else: return 0 diff --git a/third_party/boringssl/kit/src/util/bot/vs_toolchain.py b/third_party/boringssl/kit/src/util/bot/vs_toolchain.py index 051d78b1..9e19e22b 100644 --- a/third_party/boringssl/kit/src/util/bot/vs_toolchain.py +++ b/third_party/boringssl/kit/src/util/bot/vs_toolchain.py @@ -62,14 +62,18 @@ def FindDepotTools(): def _GetDesiredVsToolchainHashes(version): """Load a list of SHA1s corresponding to the toolchains that we want installed to build with.""" - if version == '2015': - # Update 3 final with 10.0.15063.468 SDK and no vctip.exe. - return ['f53e4598951162bad6330f7a167486c7ae5db1e5'] if version == '2017': # VS 2017 Update 9 (15.9.12) with 10.0.18362 SDK, 10.0.17763 version of # Debuggers, and 10.0.17134 version of d3dcompiler_47.dll, with ARM64 # libraries. return ['418b3076791776573a815eb298c8aa590307af63'] + if version == '2019': + # VS 2019 16.61 with 10.0.20348.0 SDK, 10.0.22621.755 version of Debuggers, + # with ARM64 libraries and UWP support. + return ['0b5ee4d2b1'] + if version == '2022': + # VS 2022 17.4 with 10.0.22621.0 SDK with ARM64 libraries and UWP support. + return ['27370823e7'] raise Exception('Unsupported VS version %s' % version) diff --git a/third_party/boringssl/kit/src/util/check_filenames.go b/third_party/boringssl/kit/src/util/check_filenames.go index 886c3f60..384c19f5 100644 --- a/third_party/boringssl/kit/src/util/check_filenames.go +++ b/third_party/boringssl/kit/src/util/check_filenames.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // check_filenames.go checks that filenames are unique. Some of our consumers do // not support multiple files with the same name in the same build target, even // if they are in different directories. diff --git a/third_party/boringssl/kit/src/util/check_imported_libraries.go b/third_party/boringssl/kit/src/util/check_imported_libraries.go index 187e5144..f3803f1c 100644 --- a/third_party/boringssl/kit/src/util/check_imported_libraries.go +++ b/third_party/boringssl/kit/src/util/check_imported_libraries.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // check_imported_libraries.go checks that each of its arguments only imports // allowed libraries. This is used to avoid accidental dependencies on // libstdc++.so. diff --git a/third_party/boringssl/kit/src/util/check_stack.go b/third_party/boringssl/kit/src/util/check_stack.go new file mode 100644 index 00000000..ad763e65 --- /dev/null +++ b/third_party/boringssl/kit/src/util/check_stack.go @@ -0,0 +1,47 @@ +// Copyright (c) 2022, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore + +// check_stack.go checks that each of its arguments has a non-executable stack. +// See https://www.airs.com/blog/archives/518 for details. +package main + +import ( + "debug/elf" + "fmt" + "os" +) + +func checkStack(path string) { + file, err := elf.Open(path) + if err != nil { + fmt.Fprintf(os.Stderr, "Error opening %s: %s\n", path, err) + os.Exit(1) + } + defer file.Close() + + for _, prog := range file.Progs { + if prog.Type == elf.PT_GNU_STACK && prog.Flags&elf.PF_X != 0 { + fmt.Fprintf(os.Stderr, "%s has an executable stack.\n", path) + os.Exit(1) + } + } +} + +func main() { + for _, path := range os.Args[1:] { + checkStack(path) + } +} diff --git a/third_party/boringssl/kit/src/util/compare_benchmarks.go b/third_party/boringssl/kit/src/util/compare_benchmarks.go index fd7fdfb3..05e1b5db 100644 --- a/third_party/boringssl/kit/src/util/compare_benchmarks.go +++ b/third_party/boringssl/kit/src/util/compare_benchmarks.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2020 Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2020 Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // compare_benchmarks takes the JSON-formatted output of bssl speed and // compares it against a baseline output. @@ -20,7 +22,6 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" "os" ) @@ -63,7 +64,7 @@ func printResult(result Result, baseline *Result) error { } func readResults(path string) ([]Result, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/third_party/boringssl/kit/src/util/convert_comments.go b/third_party/boringssl/kit/src/util/convert_comments.go index c03eeb81..df9e3d3a 100644 --- a/third_party/boringssl/kit/src/util/convert_comments.go +++ b/third_party/boringssl/kit/src/util/convert_comments.go @@ -12,12 +12,13 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( "bytes" "fmt" - "io/ioutil" "os" "strings" ) @@ -232,6 +233,29 @@ func convertComments(path string, in []byte) []byte { } for i, line := range group.lines { + // The OpenSSL style writes multiline block comments with a + // blank line at the top and bottom, like so: + // + // /* + // * Some multi-line + // * comment + // */ + // + // The trailing lines are already removed above, when buffering. + // Remove the leading lines here. (The leading lines cannot be + // removed when buffering because we may discover the comment is + // not convertible in later lines.) + // + // Note the leading line cannot be easily removed if there is + // code before it, such as the following. Skip those cases. + // + // foo(); /* + // * Some multi-line + // * comment + // */ + if i == 0 && allSpaces(line[:group.column]) && len(line) == group.column+2 { + continue + } newLine := fmt.Sprintf("%s%s//%s", line[:group.column], adjust, strings.TrimRight(line[group.column+2:], " ")) if len(newLine) > 80 { fmt.Fprintf(os.Stderr, "%s:%d: Line is now longer than 80 characters\n", path, lineNo+i+1) @@ -247,11 +271,11 @@ func convertComments(path string, in []byte) []byte { func main() { for _, arg := range os.Args[1:] { - in, err := ioutil.ReadFile(arg) + in, err := os.ReadFile(arg) if err != nil { panic(err) } - if err := ioutil.WriteFile(arg, convertComments(arg, in), 0666); err != nil { + if err := os.WriteFile(arg, convertComments(arg, in), 0666); err != nil { panic(err) } } diff --git a/third_party/boringssl/kit/src/util/convert_wycheproof.go b/third_party/boringssl/kit/src/util/convert_wycheproof/convert_wycheproof.go similarity index 83% rename from third_party/boringssl/kit/src/util/convert_wycheproof.go rename to third_party/boringssl/kit/src/util/convert_wycheproof/convert_wycheproof.go index 0e9f81b5..cf1e6498 100644 --- a/third_party/boringssl/kit/src/util/convert_wycheproof.go +++ b/third_party/boringssl/kit/src/util/convert_wycheproof/convert_wycheproof.go @@ -1,26 +1,25 @@ -/* Copyright (c) 2018, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2018, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// convert_wycheproof.go converts Wycheproof test vectors into a format more -// easily consumed by BoringSSL. +// convert_wycheproof converts Wycheproof test vectors into a format more easily +// consumed by BoringSSL. package main import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "sort" "strings" @@ -34,10 +33,10 @@ type wycheproofTest struct { Header []string `json:"header"` // encoding/json does not support collecting unused keys, so we leave // everything past this point as generic. - TestGroups []map[string]interface{} `json:"testGroups"` + TestGroups []map[string]any `json:"testGroups"` } -func sortedKeys(m map[string]interface{}) []string { +func sortedKeys(m map[string]any) []string { keys := make([]string, 0, len(m)) for k, _ := range m { keys = append(keys, k) @@ -46,8 +45,8 @@ func sortedKeys(m map[string]interface{}) []string { return keys } -func printAttribute(w io.Writer, key string, valueI interface{}, isInstruction bool) error { - switch value := valueI.(type) { +func printAttribute(w io.Writer, key string, valueAny any, isInstruction bool) error { + switch value := valueAny.(type) { case float64: if float64(int(value)) != value { panic(key + "was not an integer.") @@ -74,14 +73,14 @@ func printAttribute(w io.Writer, key string, valueI interface{}, isInstruction b return err } } - case map[string]interface{}: + case map[string]any: for _, k := range sortedKeys(value) { if err := printAttribute(w, key+"."+k, value[k], isInstruction); err != nil { return err } } default: - panic(fmt.Sprintf("Unknown type for %q: %T", key, valueI)) + panic(fmt.Sprintf("Unknown type for %q: %T", key, valueAny)) } return nil } @@ -122,7 +121,7 @@ func printComment(w io.Writer, in string) error { } func convertWycheproof(f io.Writer, jsonPath string) error { - jsonData, err := ioutil.ReadFile(jsonPath) + jsonData, err := os.ReadFile(jsonPath) if err != nil { return err } @@ -155,9 +154,9 @@ func convertWycheproof(f io.Writer, jsonPath string) error { } } fmt.Fprintf(f, "\n") - tests := group["tests"].([]interface{}) - for _, testI := range tests { - test := testI.(map[string]interface{}) + tests := group["tests"].([]any) + for _, testAny := range tests { + test := testAny.(map[string]any) if _, err := fmt.Fprintf(f, "# tcId = %d\n", int(test["tcId"].(float64))); err != nil { return err } @@ -174,10 +173,10 @@ func convertWycheproof(f io.Writer, jsonPath string) error { return err } } - if flagsI, ok := test["flags"]; ok { + if flagsAny, ok := test["flags"]; ok { var flags []string - for _, flagI := range flagsI.([]interface{}) { - flag := flagI.(string) + for _, flagAny := range flagsAny.([]any) { + flag := flagAny.(string) flags = append(flags, flag) } if len(flags) != 0 { diff --git a/third_party/boringssl/kit/src/util/diff_asm.go b/third_party/boringssl/kit/src/util/diff_asm.go index 710a42cb..5ac1c04b 100644 --- a/third_party/boringssl/kit/src/util/diff_asm.go +++ b/third_party/boringssl/kit/src/util/diff_asm.go @@ -1,16 +1,18 @@ -/* Copyright (c) 2016, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// Copyright (c) 2016, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore package main diff --git a/third_party/boringssl/kit/src/util/doc.config b/third_party/boringssl/kit/src/util/doc.config index 12fdefca..d6ae9258 100644 --- a/third_party/boringssl/kit/src/util/doc.config +++ b/third_party/boringssl/kit/src/util/doc.config @@ -8,7 +8,6 @@ "include/openssl/buf.h", "include/openssl/bytestring.h", "include/openssl/err.h", - "include/openssl/cpu.h", "include/openssl/crypto.h", "include/openssl/ex_data.h", "include/openssl/lhash.h", @@ -36,6 +35,7 @@ "include/openssl/engine.h", "include/openssl/hkdf.h", "include/openssl/hmac.h", + "include/openssl/kyber.h", "include/openssl/md5.h", "include/openssl/rc4.h", "include/openssl/rsa.h", @@ -49,12 +49,14 @@ "include/openssl/cipher.h", "include/openssl/aead.h", "include/openssl/evp.h", - "include/openssl/hpke.h" + "include/openssl/hpke.h", + "include/openssl/kdf.h" ] },{ "Name": "Legacy ASN.1 and X.509 implementation (documentation in progress)", "Headers": [ - "include/openssl/asn1.h" + "include/openssl/asn1.h", + "include/openssl/time.h" ] },{ "Name": "SSL implementation", diff --git a/third_party/boringssl/kit/src/util/doc.go b/third_party/boringssl/kit/src/util/doc.go index a38e078c..4fb73ca0 100644 --- a/third_party/boringssl/kit/src/util/doc.go +++ b/third_party/boringssl/kit/src/util/doc.go @@ -1,10 +1,11 @@ +//go:build ignore + // doc generates HTML files from the comments in header files. // // doc expects to be given the path to a JSON file via the --config option. // From that JSON (which is defined by the Config struct) it reads a list of // header file locations and generates HTML files for each in the current // directory. - package main import ( @@ -14,7 +15,6 @@ import ( "flag" "fmt" "html/template" - "io/ioutil" "os" "path/filepath" "regexp" @@ -414,7 +414,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) { break } if line == cppGuard { - return nil, fmt.Errorf("hit ending C++ guard while in section on line %d", lineNo) + return nil, fmt.Errorf("hit ending C++ guard while in section on line %d (possibly missing two empty lines ahead of guard?)", lineNo) } var comment []string @@ -503,7 +503,7 @@ func firstSentence(paragraphs []string) string { // markupPipeWords converts |s| into an HTML string, safe to be included outside // a tag, while also marking up words surrounded by |. -func markupPipeWords(allDecls map[string]string, s string) template.HTML { +func markupPipeWords(allDecls map[string]string, s string, linkDecls bool) template.HTML { // It is safe to look for '|' in the HTML-escaped version of |s| // below. The escaped version cannot include '|' instead tags because // there are no tags by construction. @@ -524,12 +524,10 @@ func markupPipeWords(allDecls map[string]string, s string) template.HTML { if i > 0 && (j == -1 || j > i) { ret += "" anchor, isLink := allDecls[s[:i]] - if isLink { - ret += fmt.Sprintf("", template.HTMLEscapeString(anchor)) - } - ret += s[:i] - if isLink { - ret += "" + if linkDecls && isLink { + ret += fmt.Sprintf("%s", template.HTMLEscapeString(anchor), s[:i]) + } else { + ret += s[:i] } ret += "" s = s[i+1:] @@ -602,11 +600,12 @@ func generate(outPath string, config *Config) (map[string]string, error) { headerTmpl := template.New("headerTmpl") headerTmpl.Funcs(template.FuncMap{ - "firstSentence": firstSentence, - "markupPipeWords": func(s string) template.HTML { return markupPipeWords(allDecls, s) }, - "markupFirstWord": markupFirstWord, - "markupRFC": markupRFC, - "newlinesToBR": newlinesToBR, + "firstSentence": firstSentence, + "markupPipeWords": func(s string) template.HTML { return markupPipeWords(allDecls, s, true /* linkDecls */) }, + "markupPipeWordsNoLink": func(s string) template.HTML { return markupPipeWords(allDecls, s, false /* linkDecls */) }, + "markupFirstWord": markupFirstWord, + "markupRFC": markupRFC, + "newlinesToBR": newlinesToBR, }) headerTmpl, err := headerTmpl.Parse(` @@ -623,12 +622,12 @@ func generate(outPath string, config *Config) (map[string]string, error) { All headers - {{range .Preamble}}

{{. | markupPipeWords}}

{{end}} + {{range .Preamble}}

{{. | markupPipeWords | markupRFC}}

{{end}}
    {{range .Sections}} {{if not .IsPrivate}} - {{if .Anchor}}
  1. {{.Preamble | firstSentence | markupPipeWords}}
  2. {{end}} + {{if .Anchor}}
  3. {{.Preamble | firstSentence | markupPipeWordsNoLink}}
  4. {{end}} {{range .Decls}} {{if .Anchor}}
  5. {{.Name}}
  6. {{end}} {{end}} @@ -641,7 +640,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
    {{if .Preamble}}
    - {{range .Preamble}}

    {{. | markupPipeWords}}

    {{end}} + {{range .Preamble}}

    {{. | markupPipeWords | markupRFC}}

    {{end}}
    {{end}} @@ -747,11 +746,11 @@ func generateIndex(outPath string, config *Config, headerDescriptions map[string } func copyFile(outPath string, inFilePath string) error { - bytes, err := ioutil.ReadFile(inFilePath) + bytes, err := os.ReadFile(inFilePath) if err != nil { return err } - return ioutil.WriteFile(filepath.Join(outPath, filepath.Base(inFilePath)), bytes, 0666) + return os.WriteFile(filepath.Join(outPath, filepath.Base(inFilePath)), bytes, 0666) } func main() { @@ -773,7 +772,7 @@ func main() { os.Exit(1) } - configBytes, err := ioutil.ReadFile(*configFlag) + configBytes, err := os.ReadFile(*configFlag) if err != nil { fmt.Printf("Failed to open config file: %s\n", err) os.Exit(1) diff --git a/third_party/boringssl/kit/src/util/embed_test_data.go b/third_party/boringssl/kit/src/util/embed_test_data.go index 9fd7de1e..ae7135fa 100644 --- a/third_party/boringssl/kit/src/util/embed_test_data.go +++ b/third_party/boringssl/kit/src/util/embed_test_data.go @@ -10,7 +10,9 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // embed_test_data generates a C++ source file which exports a function, // GetTestData, which looks up the specified data files. @@ -20,7 +22,6 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" "os" "strings" ) @@ -77,7 +78,7 @@ func main() { var files []string if len(*fileList) != 0 { - data, err := ioutil.ReadFile(*fileList) + data, err := os.ReadFile(*fileList) if err != nil { fmt.Fprintf(os.Stderr, "Error reading %s: %s.\n", *fileList, err) os.Exit(1) @@ -127,7 +128,7 @@ func main() { const chunkSize = 8192 for i, arg := range files { - data, err := ioutil.ReadFile(arg) + data, err := os.ReadFile(arg) if err != nil { fmt.Fprintf(os.Stderr, "Error reading %s: %s.\n", arg, err) os.Exit(1) diff --git a/third_party/boringssl/kit/src/util/fetch_ech_config_list.go b/third_party/boringssl/kit/src/util/fetch_ech_config_list.go index badaae29..732d0d3b 100644 --- a/third_party/boringssl/kit/src/util/fetch_ech_config_list.go +++ b/third_party/boringssl/kit/src/util/fetch_ech_config_list.go @@ -12,13 +12,14 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( "errors" "flag" "fmt" - "io/ioutil" "log" "net" "os" @@ -379,7 +380,7 @@ func main() { } outFile := path.Join(*outDir, fmt.Sprintf("ech-config-list-%d", echConfigListCount)) - if err = ioutil.WriteFile(outFile, record.ech, 0644); err != nil { + if err = os.WriteFile(outFile, record.ech, 0644); err != nil { log.Printf("Failed to write file: %s\n", err) os.Exit(1) } diff --git a/third_party/boringssl/kit/src/util/fipstools/CMakeLists.txt b/third_party/boringssl/kit/src/util/fipstools/CMakeLists.txt new file mode 100644 index 00000000..87abf0ab --- /dev/null +++ b/third_party/boringssl/kit/src/util/fipstools/CMakeLists.txt @@ -0,0 +1,8 @@ +if(FIPS) + add_executable( + test_fips + + test_fips.c + ) + target_link_libraries(test_fips crypto) +endif() diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/ACVP.md b/third_party/boringssl/kit/src/util/fipstools/acvp/ACVP.md index ba5bdbb2..066a39b7 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/ACVP.md +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/ACVP.md @@ -77,6 +77,8 @@ The other commands are as follows. (Note that you only need to implement the com | ECDSA/sigVer | Curve name, hash name, message, X, Y, R, S | Single-byte validity flag | | FFDH | p, q, g, peer public key, local private key (or empty), local public key (or empty) | Local public key, shared key | | HKDF/<HASH> | key, salt, info, num output bytes | Key | +| HKDFExtract | secret, salt | Key | +| HKDFExpandLabel | Output length, secret, label, transcript hash | Key | | HMAC-SHA-1 | Value to hash, key | Digest | | HMAC-SHA2-224 | Value to hash, key | Digest | | HMAC-SHA2-256 | Value to hash, key | Digest | @@ -104,12 +106,18 @@ The other commands are as follows. (Note that you only need to implement the com | SHA2-384/MCT | Initial seed¹ | Digest | | SHA2-512/MCT | Initial seed¹ | Digest | | SHA2-512/256/MCT | Initial seed¹ | Digest | -| TLSKDF/<1.0\|1.2>/<HASH> | Number output bytes, secret, label, seed1, seed2 | Output | +| TLSKDF/1.2/<HASH> | Number output bytes, secret, label, seed1, seed2 | Output | ¹ The iterated tests would result in excessive numbers of round trips if the module wrapper handled only basic operations. Thus some ACVP logic is pushed down for these tests so that the inner loop can be handled locally. Either read the NIST documentation ([block-ciphers](https://pages.nist.gov/ACVP/draft-celi-acvp-symmetric.html#name-monte-carlo-tests-for-block) [hashes](https://pages.nist.gov/ACVP/draft-celi-acvp-sha.html#name-monte-carlo-tests-for-sha-1)) to understand the iteration count and return values or, probably more fruitfully, see how these functions are handled in the `modulewrapper` directory. ² Will always be one because MCT tests are not supported for CS3. +### Batching + +Requests are written without waiting for responses. Implementations can run a read-execute-reply loop without worrying about this. However, if batching is useful then implementations may gather up multiple requests before executing them. But this risks deadlock because some requests depend on the result of the previous one. If the `getConfig` result contains a dummy entry for the algorithm `acvptool` it will be filtered out when running with `-regcap`. However, a list of strings called `features` in that block may include the string `batch` to indicate that the implementation would like to receive a `flush` command whenever previous results must be received in order to progress. Implementations that batch can observe this to avoid deadlock. + +The `flush` command must not produce a response itself; it only indicates that all previous responses must be received to progress. The `getConfig` command must always be serviced immediately because a flush command will not be sent prior to processing the `getConfig` response. + ## Online operation If you have credentials to speak to either of the NIST ACVP servers then you can run the tool in online mode. @@ -249,6 +257,12 @@ The current list of objects is: ### Running test sessions -In online mode, a given algorithm can be run by using the `-run` option. For example, `-run SHA2-256`. This will fetch a vector set, have the module-under-test answer it, and upload the answer. If you want to just fetch the vector set for later use with the `-json` option (documented above) then you can use `-fetch` instead of `-run`. +In online mode, a given algorithm can be run by using the `-run` option. For example, `-run SHA2-256`. This will fetch a vector set, have the module-under-test answer it, and upload the answer. If you want to just fetch the vector set for later use with the `-json` option (documented above) then you can use `-fetch` instead of `-run`. The `-fetch` option also supports passing `-expected-out ` to fetch and write the expected results, if the server supports that. -The tool doesn't currently support the sorts of operations that a lab would need, like uploading results from a file. +After results have been produced with `-json`, they can be uploaded with `-upload`. So `-run` is effectively these three steps combined: + +``` +./acvptool -fetch SHA2-256 > request +./acvptool -json request > result +./acvptool -upload result +``` diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp.go index f477d659..cbb07f63 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp.go @@ -28,7 +28,7 @@ import ( "errors" "flag" "fmt" - "io/ioutil" + "io" "log" "net/http" neturl "net/url" @@ -42,12 +42,14 @@ import ( ) var ( - dumpRegcap = flag.Bool("regcap", false, "Print module capabilities JSON to stdout") - configFilename = flag.String("config", "config.json", "Location of the configuration JSON file") - jsonInputFile = flag.String("json", "", "Location of a vector-set input file") - runFlag = flag.String("run", "", "Name of primitive to run tests for") - fetchFlag = flag.String("fetch", "", "Name of primitive to fetch vectors for") - wrapperPath = flag.String("wrapper", "../../../../build/util/fipstools/acvp/modulewrapper/modulewrapper", "Path to the wrapper binary") + dumpRegcap = flag.Bool("regcap", false, "Print module capabilities JSON to stdout") + configFilename = flag.String("config", "config.json", "Location of the configuration JSON file") + jsonInputFile = flag.String("json", "", "Location of a vector-set input file") + uploadInputFile = flag.String("upload", "", "Location of a JSON results file to upload") + runFlag = flag.String("run", "", "Name of primitive to run tests for") + fetchFlag = flag.String("fetch", "", "Name of primitive to fetch vectors for") + expectedOutFlag = flag.String("expected-out", "", "Name of a file to write the expected results to") + wrapperPath = flag.String("wrapper", "../../../../build/util/fipstools/acvp/modulewrapper/modulewrapper", "Path to the wrapper binary") ) type Config struct { @@ -78,7 +80,7 @@ func isCommentLine(line []byte) bool { return false } -func jsonFromFile(out interface{}, filename string) error { +func jsonFromFile(out any, filename string) error { in, err := os.Open(filename) if err != nil { return err @@ -129,7 +131,7 @@ func TOTP(secret []byte) string { type Middle interface { Close() Config() ([]byte, error) - Process(algorithm string, vectorSet []byte) (interface{}, error) + Process(algorithm string, vectorSet []byte) (any, error) } func loadCachedSessionTokens(server *acvp.Server, cachePath string) error { @@ -155,7 +157,7 @@ func loadCachedSessionTokens(server *acvp.Server, cachePath string) error { continue } path := filepath.Join(cachePath, name) - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return fmt.Errorf("Failed to read session token cache entry %q: %s", path, err) } @@ -178,14 +180,14 @@ func trimLeadingSlash(s string) string { return s } -// looksLikeHeaderElement returns true iff element looks like it's a header, not -// a test. Some ACVP files contain a header as the first element that should be -// duplicated into the response, and some don't. If the element contains -// a "url" field, or if it's missing an "algorithm" field, then we guess that -// it's a header. -func looksLikeHeaderElement(element json.RawMessage) bool { +// looksLikeVectorSetHeader returns true iff element looks like it's a +// vectorSetHeader, not a test. Some ACVP files contain a header as the first +// element that should be duplicated into the response, and some don't. If the +// element contains a "url" field, or if it's missing an "algorithm" field, +// then we guess that it's a header. +func looksLikeVectorSetHeader(element json.RawMessage) bool { var headerFields struct { - URL string `json:"url"` + URL string `json:"url"` Algorithm string `json:"algorithm"` } if err := json.Unmarshal(element, &headerFields); err != nil { @@ -196,8 +198,8 @@ func looksLikeHeaderElement(element json.RawMessage) bool { // processFile reads a file containing vector sets, at least in the format // preferred by our lab, and writes the results to stdout. -func processFile(filename string, supportedAlgos []map[string]interface{}, middle Middle) error { - jsonBytes, err := ioutil.ReadFile(filename) +func processFile(filename string, supportedAlgos []map[string]any, middle Middle) error { + jsonBytes, err := os.ReadFile(filename) if err != nil { return err } @@ -213,7 +215,7 @@ func processFile(filename string, supportedAlgos []map[string]interface{}, middl } var header json.RawMessage - if looksLikeHeaderElement(elements[0]) { + if looksLikeVectorSetHeader(elements[0]) { header, elements = elements[0], elements[1:] if len(elements) == 0 { return errors.New("JSON input is empty") @@ -265,9 +267,10 @@ func processFile(filename string, supportedAlgos []map[string]interface{}, middl return fmt.Errorf("while processing vector set #%d: %s", i+1, err) } - group := map[string]interface{}{ + group := map[string]any{ "vsId": commonFields.ID, "testGroups": replyGroups, + "algorithm": algo, } replyBytes, err := json.MarshalIndent(group, "", " ") if err != nil { @@ -286,99 +289,113 @@ func processFile(filename string, supportedAlgos []map[string]interface{}, middl return nil } -func main() { - flag.Parse() +// getVectorsWithRetry fetches the given url from the server and parses it as a +// set of vectors. Any server requested retry is handled. +func getVectorsWithRetry(server *acvp.Server, url string) (out acvp.Vectors, vectorsBytes []byte, err error) { + for { + if vectorsBytes, err = server.GetBytes(url); err != nil { + return out, nil, err + } - var err error - var middle Middle - middle, err = subprocess.New(*wrapperPath) + var vectors acvp.Vectors + if err := json.Unmarshal(vectorsBytes, &vectors); err != nil { + return out, nil, err + } + + retry := vectors.Retry + if retry == 0 { + return vectors, vectorsBytes, nil + } + + log.Printf("Server requested %d seconds delay", retry) + if retry > 10 { + retry = 10 + } + time.Sleep(time.Duration(retry) * time.Second) + } +} + +func uploadResult(server *acvp.Server, setURL string, resultData []byte) error { + resultSize := uint64(len(resultData)) + 32 /* for framing overhead */ + if server.SizeLimit == 0 || resultSize < server.SizeLimit { + log.Printf("Result size %d bytes", resultSize) + return server.Post(nil, trimLeadingSlash(setURL)+"/results", resultData) + } + + // The NIST ACVP server no longer requires the large-upload process, + // suggesting that this may no longer be needed. + log.Printf("Result is %d bytes, too much given server limit of %d bytes. Using large-upload process.", resultSize, server.SizeLimit) + largeRequestBytes, err := json.Marshal(acvp.LargeUploadRequest{ + Size: resultSize, + URL: setURL, + }) if err != nil { - log.Fatalf("failed to initialise middle: %s", err) + return errors.New("failed to marshal large-upload request: " + err.Error()) } - defer middle.Close() - configBytes, err := middle.Config() + var largeResponse acvp.LargeUploadResponse + if err := server.Post(&largeResponse, "/large", largeRequestBytes); err != nil { + return errors.New("failed to request large-upload endpoint: " + err.Error()) + } + + log.Printf("Directed to large-upload endpoint at %q", largeResponse.URL) + req, err := http.NewRequest("POST", largeResponse.URL, bytes.NewBuffer(resultData)) if err != nil { - log.Fatalf("failed to get config from middle: %s", err) + return errors.New("failed to create POST request: " + err.Error()) + } + token := largeResponse.AccessToken + if len(token) == 0 { + token = server.AccessToken + } + req.Header.Add("Authorization", "Bearer "+token) + req.Header.Add("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return errors.New("failed writing large upload: " + err.Error()) + } + resp.Body.Close() + if resp.StatusCode != 200 { + return fmt.Errorf("large upload resulted in status code %d", resp.StatusCode) } - var supportedAlgos []map[string]interface{} - if err := json.Unmarshal(configBytes, &supportedAlgos); err != nil { - log.Fatalf("failed to parse configuration from Middle: %s", err) - } - - if *dumpRegcap { - nonTestAlgos := make([]map[string]interface{}, 0, len(supportedAlgos)) - for _, algo := range supportedAlgos { - if value, ok := algo["acvptoolTestOnly"]; ok { - testOnly, ok := value.(bool) - if !ok { - log.Fatalf("modulewrapper config contains acvptoolTestOnly field with non-boolean value %#v", value) - } - if testOnly { - continue - } - } - nonTestAlgos = append(nonTestAlgos, algo) - } - - regcap := []map[string]interface{}{ - map[string]interface{}{"acvVersion": "1.0"}, - map[string]interface{}{"algorithms": nonTestAlgos}, - } - regcapBytes, err := json.MarshalIndent(regcap, "", " ") - if err != nil { - log.Fatalf("failed to marshal regcap: %s", err) - } - os.Stdout.Write(regcapBytes) - os.Stdout.WriteString("\n") - os.Exit(0) - } - - if len(*jsonInputFile) > 0 { - if err := processFile(*jsonInputFile, supportedAlgos, middle); err != nil { - log.Fatalf("failed to process input file: %s", err) - } - os.Exit(0) - } - - var config Config - if err := jsonFromFile(&config, *configFilename); err != nil { - log.Fatalf("Failed to load config file: %s", err) - } + return nil +} +func connect(config *Config, sessionTokensCacheDir string) (*acvp.Server, error) { if len(config.TOTPSecret) == 0 { - log.Fatal("Config file missing TOTPSecret") + return nil, errors.New("config file missing TOTPSecret") } totpSecret, err := base64.StdEncoding.DecodeString(config.TOTPSecret) if err != nil { - log.Fatalf("Failed to base64-decode TOTP secret from config file: %s. (Note that the secret _itself_ should be in the config, not the name of a file that contains it.)", err) + return nil, fmt.Errorf("failed to base64-decode TOTP secret from config file: %s. (Note that the secret _itself_ should be in the config, not the name of a file that contains it.)", err) } if len(config.CertPEMFile) == 0 { - log.Fatal("Config file missing CertPEMFile") + return nil, errors.New("config file missing CertPEMFile") } - certPEM, err := ioutil.ReadFile(config.CertPEMFile) + certPEM, err := os.ReadFile(config.CertPEMFile) if err != nil { - log.Fatalf("failed to read certificate from %q: %s", config.CertPEMFile, err) + return nil, fmt.Errorf("failed to read certificate from %q: %s", config.CertPEMFile, err) } block, _ := pem.Decode(certPEM) certDER := block.Bytes if len(config.PrivateKeyDERFile) == 0 && len(config.PrivateKeyFile) == 0 { - log.Fatal("Config file missing PrivateKeyDERFile and PrivateKeyFile") + return nil, errors.New("config file missing PrivateKeyDERFile and PrivateKeyFile") } if len(config.PrivateKeyDERFile) != 0 && len(config.PrivateKeyFile) != 0 { - log.Fatal("Config file has both PrivateKeyDERFile and PrivateKeyFile. Can only have one.") + return nil, errors.New("config file has both PrivateKeyDERFile and PrivateKeyFile. Can only have one.") } privateKeyFile := config.PrivateKeyDERFile if len(config.PrivateKeyFile) > 0 { privateKeyFile = config.PrivateKeyFile } - keyBytes, err := ioutil.ReadFile(privateKeyFile) + keyBytes, err := os.ReadFile(privateKeyFile) if err != nil { - log.Fatalf("failed to read private key from %q: %s", privateKeyFile, err) + return nil, fmt.Errorf("failed to read private key from %q: %s", privateKeyFile, err) } var keyDER []byte @@ -392,18 +409,231 @@ func main() { var certKey crypto.PrivateKey if certKey, err = x509.ParsePKCS1PrivateKey(keyDER); err != nil { if certKey, err = x509.ParsePKCS8PrivateKey(keyDER); err != nil { - log.Fatalf("failed to parse private key from %q: %s", privateKeyFile, err) + return nil, fmt.Errorf("failed to parse private key from %q: %s", privateKeyFile, err) } } + serverURL := "https://demo.acvts.nist.gov/" + if len(config.ACVPServer) > 0 { + serverURL = config.ACVPServer + } + server := acvp.NewServer(serverURL, config.LogFile, [][]byte{certDER}, certKey, func() string { + return TOTP(totpSecret[:]) + }) + + if len(sessionTokensCacheDir) > 0 { + if err := loadCachedSessionTokens(server, sessionTokensCacheDir); err != nil { + return nil, err + } + } + + return server, nil +} + +func getResultsWithRetry(server *acvp.Server, url string) (bool, error) { +FetchResults: + for { + var results acvp.SessionResults + if err := server.Get(&results, trimLeadingSlash(url)+"/results"); err != nil { + return false, errors.New("failed to fetch session results: " + err.Error()) + } + + if results.Passed { + log.Print("Test passed") + return true, nil + } + + for _, result := range results.Results { + if result.Status == "incomplete" { + log.Print("Server hasn't finished processing results. Waiting 10 seconds.") + time.Sleep(10 * time.Second) + continue FetchResults + } + } + + log.Printf("Server did not accept results: %#v", results) + return false, nil + } +} + +// vectorSetHeader is the first element in the array of JSON elements that makes +// up the on-disk format for a vector set. +type vectorSetHeader struct { + URL string `json:"url,omitempty"` + VectorSetURLs []string `json:"vectorSetUrls,omitempty"` + Time string `json:"time,omitempty"` +} + +func uploadFromFile(file string, config *Config, sessionTokensCacheDir string) { + if len(*jsonInputFile) > 0 { + log.Fatalf("-upload cannot be used with -json") + } + if len(*runFlag) > 0 { + log.Fatalf("-upload cannot be used with -run") + } + if len(*fetchFlag) > 0 { + log.Fatalf("-upload cannot be used with -fetch") + } + if len(*expectedOutFlag) > 0 { + log.Fatalf("-upload cannot be used with -expected-out") + } + if *dumpRegcap { + log.Fatalf("-upload cannot be used with -regcap") + } + + in, err := os.Open(file) + if err != nil { + log.Fatalf("Cannot open input: %s", err) + } + defer in.Close() + + decoder := json.NewDecoder(in) + + var input []json.RawMessage + if err := decoder.Decode(&input); err != nil { + log.Fatalf("Failed to parse input: %s", err) + } + + if len(input) < 2 { + log.Fatalf("Input JSON has fewer than two elements") + } + + var header vectorSetHeader + if err := json.Unmarshal(input[0], &header); err != nil { + log.Fatalf("Failed to parse input header: %s", err) + } + + if numGroups := len(input) - 1; numGroups != len(header.VectorSetURLs) { + log.Fatalf("have %d URLs from header, but only %d result groups", len(header.VectorSetURLs), numGroups) + } + + server, err := connect(config, sessionTokensCacheDir) + if err != nil { + log.Fatal(err) + } + + for i, url := range header.VectorSetURLs { + log.Printf("Uploading result for %q", url) + if err := uploadResult(server, url, input[i+1]); err != nil { + log.Fatalf("Failed to upload: %s", err) + } + } + + if ok, err := getResultsWithRetry(server, header.URL); err != nil { + log.Fatal(err) + } else if !ok { + os.Exit(1) + } +} + +func main() { + flag.Parse() + + var config Config + if err := jsonFromFile(&config, *configFilename); err != nil { + log.Fatalf("Failed to load config file: %s", err) + } + + var sessionTokensCacheDir string + if len(config.SessionTokensCache) > 0 { + sessionTokensCacheDir = config.SessionTokensCache + if strings.HasPrefix(sessionTokensCacheDir, "~/") { + home := os.Getenv("HOME") + if len(home) == 0 { + log.Fatal("~ used in config file but $HOME not set") + } + sessionTokensCacheDir = filepath.Join(home, sessionTokensCacheDir[2:]) + } + } + + if len(*uploadInputFile) > 0 { + uploadFromFile(*uploadInputFile, &config, sessionTokensCacheDir) + return + } + + middle, err := subprocess.New(*wrapperPath) + if err != nil { + log.Fatalf("failed to initialise middle: %s", err) + } + defer middle.Close() + + configBytes, err := middle.Config() + if err != nil { + log.Fatalf("failed to get config from middle: %s", err) + } + + var supportedAlgos []map[string]any + if err := json.Unmarshal(configBytes, &supportedAlgos); err != nil { + log.Fatalf("failed to parse configuration from Middle: %s", err) + } + + if *dumpRegcap { + nonTestAlgos := make([]map[string]any, 0, len(supportedAlgos)) + for _, algo := range supportedAlgos { + if value, ok := algo["acvptoolTestOnly"]; ok { + testOnly, ok := value.(bool) + if !ok { + log.Fatalf("modulewrapper config contains acvptoolTestOnly field with non-boolean value %#v", value) + } + if testOnly { + continue + } + } + if value, ok := algo["algorithm"]; ok { + algorithm, ok := value.(string) + if ok && algorithm == "acvptool" { + continue + } + } + nonTestAlgos = append(nonTestAlgos, algo) + } + + regcap := []map[string]any{ + {"acvVersion": "1.0"}, + {"algorithms": nonTestAlgos}, + } + regcapBytes, err := json.MarshalIndent(regcap, "", " ") + if err != nil { + log.Fatalf("failed to marshal regcap: %s", err) + } + os.Stdout.Write(regcapBytes) + os.Stdout.WriteString("\n") + return + } + + if len(*jsonInputFile) > 0 { + if err := processFile(*jsonInputFile, supportedAlgos, middle); err != nil { + log.Fatalf("failed to process input file: %s", err) + } + return + } + var requestedAlgosFlag string + // The output file to which expected results are written, if requested. + var expectedOut *os.File + // A tee that outputs to both stdout (for vectors) and the file for + // expected results, if any. + var fetchOutputTee io.Writer + if len(*runFlag) > 0 && len(*fetchFlag) > 0 { log.Fatalf("cannot specify both -run and -fetch") } + if len(*expectedOutFlag) > 0 && len(*fetchFlag) == 0 { + log.Fatalf("-expected-out can only be used with -fetch") + } if len(*runFlag) > 0 { requestedAlgosFlag = *runFlag } else { requestedAlgosFlag = *fetchFlag + if len(*expectedOutFlag) > 0 { + if expectedOut, err = os.Create(*expectedOutFlag); err != nil { + log.Fatalf("cannot open %q: %s", *expectedOutFlag, err) + } + fetchOutputTee = io.MultiWriter(os.Stdout, expectedOut) + defer expectedOut.Close() + } else { + fetchOutputTee = os.Stdout + } } runAlgos := make(map[string]bool) @@ -413,7 +643,7 @@ func main() { } } - var algorithms []map[string]interface{} + var algorithms []map[string]any for _, supportedAlgo := range supportedAlgos { algoInterface, ok := supportedAlgo["algorithm"] if !ok { @@ -437,27 +667,9 @@ func main() { } } - if len(config.ACVPServer) == 0 { - config.ACVPServer = "https://demo.acvts.nist.gov/" - } - server := acvp.NewServer(config.ACVPServer, config.LogFile, [][]byte{certDER}, certKey, func() string { - return TOTP(totpSecret[:]) - }) - - var sessionTokensCacheDir string - if len(config.SessionTokensCache) > 0 { - sessionTokensCacheDir = config.SessionTokensCache - if strings.HasPrefix(sessionTokensCacheDir, "~/") { - home := os.Getenv("HOME") - if len(home) == 0 { - log.Fatal("~ used in config file but $HOME not set") - } - sessionTokensCacheDir = filepath.Join(home, sessionTokensCacheDir[2:]) - } - - if err := loadCachedSessionTokens(server, sessionTokensCacheDir); err != nil { - log.Fatal(err) - } + server, err := connect(&config, sessionTokensCacheDir) + if err != nil { + log.Fatal(err) } if err := server.Login(); err != nil { @@ -492,164 +704,97 @@ func main() { if token := result.AccessToken; len(token) > 0 { server.PrefixTokens[url] = token if len(sessionTokensCacheDir) > 0 { - ioutil.WriteFile(filepath.Join(sessionTokensCacheDir, neturl.PathEscape(url))+".token", []byte(token), 0600) + os.WriteFile(filepath.Join(sessionTokensCacheDir, neturl.PathEscape(url))+".token", []byte(token), 0600) } } log.Printf("Have vector sets %v", result.VectorSetURLs) if len(*fetchFlag) > 0 { - os.Stdout.WriteString("[\n") - json.NewEncoder(os.Stdout).Encode(map[string]interface{}{ - "url": url, - "vectorSetUrls": result.VectorSetURLs, - "time": time.Now().Format(time.RFC3339), + io.WriteString(fetchOutputTee, "[\n") + json.NewEncoder(fetchOutputTee).Encode(vectorSetHeader{ + URL: url, + VectorSetURLs: result.VectorSetURLs, + Time: time.Now().Format(time.RFC3339), }) } for _, setURL := range result.VectorSetURLs { - firstTime := true - for { - if firstTime { - log.Printf("Fetching test vectors %q", setURL) - firstTime = false - } + log.Printf("Fetching test vectors %q", setURL) - vectorsBytes, err := server.GetBytes(trimLeadingSlash(setURL)) + vectors, vectorsBytes, err := getVectorsWithRetry(server, trimLeadingSlash(setURL)) + if err != nil { + log.Fatalf("Failed to fetch vector set %q: %s", setURL, err) + } + + if len(*fetchFlag) > 0 { + os.Stdout.WriteString(",\n") + os.Stdout.Write(vectorsBytes) + } + + if expectedOut != nil { + log.Printf("Fetching expected results") + + _, expectedResultsBytes, err := getVectorsWithRetry(server, trimLeadingSlash(setURL)+"/expected") if err != nil { - log.Fatalf("Failed to fetch vector set %q: %s", setURL, err) + log.Fatalf("Failed to fetch expected results: %s", err) } - var vectors acvp.Vectors - if err := json.Unmarshal(vectorsBytes, &vectors); err != nil { - log.Fatalf("Failed to parse vector set from %q: %s", setURL, err) - } + expectedOut.WriteString(",") + expectedOut.Write(expectedResultsBytes) + } - if retry := vectors.Retry; retry > 0 { - log.Printf("Server requested %d seconds delay", retry) - if retry > 10 { - retry = 10 - } - time.Sleep(time.Duration(retry) * time.Second) - continue - } + if len(*fetchFlag) > 0 { + continue + } - if len(*fetchFlag) > 0 { - os.Stdout.WriteString(",\n") - os.Stdout.Write(vectorsBytes) - break - } + replyGroups, err := middle.Process(vectors.Algo, vectorsBytes) + if err != nil { + log.Printf("Failed: %s", err) + log.Printf("Deleting test set") + server.Delete(url) + os.Exit(1) + } - replyGroups, err := middle.Process(vectors.Algo, vectorsBytes) - if err != nil { - log.Printf("Failed: %s", err) - log.Printf("Deleting test set") - server.Delete(url) - os.Exit(1) - } + headerBytes, err := json.Marshal(acvp.Vectors{ + ID: vectors.ID, + Algo: vectors.Algo, + }) + if err != nil { + log.Printf("Failed to marshal result: %s", err) + log.Printf("Deleting test set") + server.Delete(url) + os.Exit(1) + } - headerBytes, err := json.Marshal(acvp.Vectors{ - ID: vectors.ID, - Algo: vectors.Algo, - }) - if err != nil { - log.Printf("Failed to marshal result: %s", err) - log.Printf("Deleting test set") - server.Delete(url) - os.Exit(1) - } + var resultBuf bytes.Buffer + resultBuf.Write(headerBytes[:len(headerBytes)-1]) + resultBuf.WriteString(`,"testGroups":`) + replyBytes, err := json.Marshal(replyGroups) + if err != nil { + log.Printf("Failed to marshal result: %s", err) + log.Printf("Deleting test set") + server.Delete(url) + os.Exit(1) + } + resultBuf.Write(replyBytes) + resultBuf.WriteString("}") - var resultBuf bytes.Buffer - resultBuf.Write(headerBytes[:len(headerBytes)-1]) - resultBuf.WriteString(`,"testGroups":`) - replyBytes, err := json.Marshal(replyGroups) - if err != nil { - log.Printf("Failed to marshal result: %s", err) - log.Printf("Deleting test set") - server.Delete(url) - os.Exit(1) - } - resultBuf.Write(replyBytes) - resultBuf.WriteString("}") - - resultData := resultBuf.Bytes() - resultSize := uint64(len(resultData)) + 32 /* for framing overhead */ - if server.SizeLimit > 0 && resultSize >= server.SizeLimit { - // The NIST ACVP server no longer requires the large-upload process, - // suggesting that it may no longer be needed. - log.Printf("Result is %d bytes, too much given server limit of %d bytes. Using large-upload process.", resultSize, server.SizeLimit) - largeRequestBytes, err := json.Marshal(acvp.LargeUploadRequest{ - Size: resultSize, - URL: setURL, - }) - if err != nil { - log.Printf("Failed to marshal large-upload request: %s", err) - log.Printf("Deleting test set") - server.Delete(url) - os.Exit(1) - } - - var largeResponse acvp.LargeUploadResponse - if err := server.Post(&largeResponse, "/large", largeRequestBytes); err != nil { - log.Fatalf("Failed to request large-upload endpoint: %s", err) - } - - log.Printf("Directed to large-upload endpoint at %q", largeResponse.URL) - client := &http.Client{} - req, err := http.NewRequest("POST", largeResponse.URL, bytes.NewBuffer(resultData)) - if err != nil { - log.Fatalf("Failed to create POST request: %s", err) - } - token := largeResponse.AccessToken - if len(token) == 0 { - token = server.AccessToken - } - req.Header.Add("Authorization", "Bearer "+token) - req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) - if err != nil { - log.Fatalf("Failed writing large upload: %s", err) - } - resp.Body.Close() - if resp.StatusCode != 200 { - log.Fatalf("Large upload resulted in status code %d", resp.StatusCode) - } - } else { - log.Printf("Result size %d bytes", resultSize) - if err := server.Post(nil, trimLeadingSlash(setURL)+"/results", resultData); err != nil { - log.Fatalf("Failed to upload results: %s\n", err) - } - } - - break + if err := uploadResult(server, setURL, resultBuf.Bytes()); err != nil { + log.Printf("Deleting test set") + server.Delete(url) + log.Fatal(err) } } if len(*fetchFlag) > 0 { - os.Stdout.WriteString("]\n") - os.Exit(0) + io.WriteString(fetchOutputTee, "]\n") + return } -FetchResults: - for { - var results acvp.SessionResults - if err := server.Get(&results, trimLeadingSlash(url)+"/results"); err != nil { - log.Fatalf("Failed to fetch session results: %s", err) - } - - if results.Passed { - log.Print("Test passed") - break - } - - for _, result := range results.Results { - if result.Status == "incomplete" { - log.Print("Server hasn't finished processing results. Waiting 10 seconds.") - time.Sleep(10 * time.Second) - continue FetchResults - } - } - - log.Fatalf("Server did not accept results: %#v", results) + if ok, err := getResultsWithRetry(server, url); err != nil { + log.Fatal(err) + } else if !ok { + os.Exit(1) } } diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp/acvp.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp/acvp.go index 04f0932a..9d20ed88 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp/acvp.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/acvp/acvp.go @@ -23,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "net/url" @@ -33,6 +32,8 @@ import ( "time" ) +const loginEndpoint = "acvp/v1/login" + // Server represents an ACVP server. type Server struct { // PrefixTokens are access tokens that apply to URLs under a certain prefix. @@ -89,7 +90,7 @@ func NewServer(prefix string, logFile string, derCertificates [][]byte, privateK return conn, err }, }, - Timeout: 30 * time.Second, + Timeout: 120 * time.Second, } return &Server{client: client, prefix: prefix, totpFunc: totp, PrefixTokens: make(map[string]string)} @@ -166,12 +167,12 @@ func parseReplyToBytes(in io.Reader) ([]byte, error) { return nil, err } - buf, err := ioutil.ReadAll(decoder.Buffered()) + buf, err := io.ReadAll(decoder.Buffered()) if err != nil { return nil, err } - rest, err := ioutil.ReadAll(in) + rest, err := io.ReadAll(in) if err != nil { return nil, err } @@ -194,7 +195,7 @@ func parseReplyToBytes(in io.Reader) ([]byte, error) { // parseReply parses the contents of an ACVP reply (after removing the header // element) into out. See the documentation of the encoding/json package for // details of the parsing. -func parseReply(out interface{}, in io.Reader) error { +func parseReply(out any, in io.Reader) error { if out == nil { // No reply expected. return nil @@ -239,7 +240,7 @@ func expired(tokenStr string) bool { if json.Unmarshal(jsonBytes, &token) != nil { return false } - return token.Expiry > 0 && token.Expiry < uint64(time.Now().Unix()) + return token.Expiry > 0 && token.Expiry < uint64(time.Now().Add(-10*time.Second).Unix()) } func (server *Server) getToken(endPoint string) (string, error) { @@ -255,7 +256,7 @@ func (server *Server) getToken(endPoint string) (string, error) { var reply struct { AccessToken string `json:"accessToken"` } - if err := server.postMessage(&reply, "acvp/v1/login", map[string]string{ + if err := server.postMessage(&reply, loginEndpoint, map[string]string{ "password": server.totpFunc(), "accessToken": token, }); err != nil { @@ -278,7 +279,7 @@ func (server *Server) Login() error { SizeLimit int64 `json:"sizeConstraint"` } - if err := server.postMessage(&reply, "acvp/v1/login", map[string]string{"password": server.totpFunc()}); err != nil { + if err := server.postMessage(&reply, loginEndpoint, map[string]string{"password": server.totpFunc()}); err != nil { return err } @@ -372,13 +373,13 @@ func (server *Server) newRequestWithToken(method, endpoint string, body io.Reade if err != nil { return nil, err } - if len(token) != 0 { + if len(token) != 0 && endpoint != loginEndpoint { req.Header.Add("Authorization", "Bearer "+token) } return req, nil } -func (server *Server) Get(out interface{}, endPoint string) error { +func (server *Server) Get(out any, endPoint string) error { req, err := server.newRequestWithToken("GET", endPoint, nil) if err != nil { return err @@ -416,7 +417,7 @@ func (server *Server) GetBytes(endPoint string) ([]byte, error) { return parseReplyToBytes(resp.Body) } -func (server *Server) write(method string, reply interface{}, endPoint string, contents []byte) error { +func (server *Server) write(method string, reply any, endPoint string, contents []byte) error { var buf bytes.Buffer buf.WriteString(requestPrefix) buf.Write(contents) @@ -441,7 +442,7 @@ func (server *Server) write(method string, reply interface{}, endPoint string, c return parseReply(reply, resp.Body) } -func (server *Server) postMessage(reply interface{}, endPoint string, request interface{}) error { +func (server *Server) postMessage(reply any, endPoint string, request any) error { contents, err := json.Marshal(request) if err != nil { return err @@ -449,11 +450,11 @@ func (server *Server) postMessage(reply interface{}, endPoint string, request in return server.write("POST", reply, endPoint, contents) } -func (server *Server) Post(out interface{}, endPoint string, contents []byte) error { +func (server *Server) Post(out any, endPoint string, contents []byte) error { return server.write("POST", out, endPoint, contents) } -func (server *Server) Put(out interface{}, endPoint string, contents []byte) error { +func (server *Server) Put(out any, endPoint string, contents []byte) error { return server.write("PUT", out, endPoint, contents) } @@ -480,7 +481,7 @@ var ( // GetPaged returns an array of records of some type using one or more requests to the server. See // https://pages.nist.gov/ACVP/draft-fussell-acvp-spec.html#paging_response -func (server *Server) GetPaged(out interface{}, endPoint string, condition Query) error { +func (server *Server) GetPaged(out any, endPoint string, condition Query) error { output := reflect.ValueOf(out) if output.Kind() != reflect.Ptr { panic(fmt.Sprintf("GetPaged output parameter of non-pointer type %T", out)) @@ -617,22 +618,22 @@ type OperationalEnvironment struct { Dependencies []Dependency `json:"dependencies,omitempty"` } -type Dependency map[string]interface{} +type Dependency map[string]any -type Algorithm map[string]interface{} +type Algorithm map[string]any type TestSession struct { - URL string `json:"url,omitempty"` - ACVPVersion string `json:"acvpVersion,omitempty"` - Created string `json:"createdOn,omitempty"` - Expires string `json:"expiresOn,omitempty"` - VectorSetURLs []string `json:"vectorSetUrls,omitempty"` - AccessToken string `json:"accessToken,omitempty"` - Algorithms []map[string]interface{} `json:"algorithms,omitempty"` - EncryptAtRest bool `json:"encryptAtRest,omitempty"` - IsSample bool `json:"isSample,omitempty"` - Publishable bool `json:"publishable,omitempty"` - Passed bool `json:"passed,omitempty"` + URL string `json:"url,omitempty"` + ACVPVersion string `json:"acvpVersion,omitempty"` + Created string `json:"createdOn,omitempty"` + Expires string `json:"expiresOn,omitempty"` + VectorSetURLs []string `json:"vectorSetUrls,omitempty"` + AccessToken string `json:"accessToken,omitempty"` + Algorithms []map[string]any `json:"algorithms,omitempty"` + EncryptAtRest bool `json:"encryptAtRest,omitempty"` + IsSample bool `json:"isSample,omitempty"` + Publishable bool `json:"publishable,omitempty"` + Passed bool `json:"passed,omitempty"` } type Vectors struct { diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/interactive.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/interactive.go index b13a549f..1c040aea 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/interactive.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/interactive.go @@ -12,6 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build interactive // +build interactive package main @@ -22,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" neturl "net/url" "os" "os/exec" @@ -142,7 +142,7 @@ func (set ServerObjectSet) Action(action string, args []string) error { return nil } - var result map[string]interface{} + var result map[string]any if err := set.env.server.Post(&result, "acvp/v1/"+set.name, newContents); err != nil { return err } @@ -158,7 +158,7 @@ func (set ServerObjectSet) Action(action string, args []string) error { } set.env.server.PrefixTokens[url] = token if len(set.env.config.SessionTokensCache) > 0 { - ioutil.WriteFile(filepath.Join(set.env.config.SessionTokensCache, neturl.PathEscape(url))+".token", []byte(token), 0600) + os.WriteFile(filepath.Join(set.env.config.SessionTokensCache, neturl.PathEscape(url))+".token", []byte(token), 0600) } } } @@ -204,7 +204,7 @@ func (ServerObject) Search(condition acvp.Query) (Object, error) { } func edit(initialContents string) ([]byte, error) { - tmp, err := ioutil.TempFile("", "acvp*.json") + tmp, err := os.CreateTemp("", "acvp*.json") if err != nil { return nil, err } @@ -230,7 +230,7 @@ func edit(initialContents string) ([]byte, error) { return nil, err } - return ioutil.ReadFile(path) + return os.ReadFile(path) } func (obj ServerObject) Action(action string, args []string) error { @@ -308,7 +308,7 @@ type Algorithms struct { func (algos Algorithms) String() (string, error) { var result struct { - Algorithms []map[string]interface{} `json:"algorithms"` + Algorithms []map[string]any `json:"algorithms"` } if err := algos.env.server.Get(&result, "acvp/v1/algorithms"); err != nil { return "", err @@ -360,7 +360,7 @@ func (s stringLiteral) Action(action string, args []string) error { return fmt.Errorf("found %d arguments but %q takes none", len(args), action) } - var results map[string]interface{} + var results map[string]any if err := s.env.server.Get(&results, s.contents); err != nil { return err } @@ -379,7 +379,7 @@ type results struct { } func (r results) String() (string, error) { - var results map[string]interface{} + var results map[string]any if err := r.env.server.Get(&results, "acvp/v1/"+r.prefix+"/results"); err != nil { return "", err } diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/nointeractive.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/nointeractive.go index 06c8890e..8aa08393 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/nointeractive.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/nointeractive.go @@ -12,6 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build !interactive // +build !interactive package main diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/aead.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/aead.go index e6585d1b..ba0eee96 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/aead.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/aead.go @@ -61,7 +61,7 @@ type aeadTestResponse struct { Passed *bool `json:"testPassed,omitempty"` } -func (a *aead) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (a *aead) Process(vectorSet []byte, m Transactable) (any, error) { var parsed aeadVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -161,46 +161,48 @@ func (a *aead) Process(vectorSet []byte, m Transactable) (interface{}, error) { testResp := aeadTestResponse{ID: test.ID} if encrypt { - result, err := m.Transact(op, 1, uint32le(uint32(tagBytes)), key, input, nonce, aad) - if err != nil { - return nil, err - } + m.TransactAsync(op, 1, [][]byte{uint32le(uint32(tagBytes)), key, input, nonce, aad}, func(result [][]byte) error { + if len(result[0]) < tagBytes { + return fmt.Errorf("ciphertext from subprocess for test case %d/%d is shorter than the tag (%d vs %d)", group.ID, test.ID, len(result[0]), tagBytes) + } - if len(result[0]) < tagBytes { - return nil, fmt.Errorf("ciphertext from subprocess for test case %d/%d is shorter than the tag (%d vs %d)", group.ID, test.ID, len(result[0]), tagBytes) - } - - if a.tagMergedWithCiphertext { - ciphertextHex := hex.EncodeToString(result[0]) - testResp.CiphertextHex = &ciphertextHex - } else { - ciphertext := result[0][:len(result[0])-tagBytes] - ciphertextHex := hex.EncodeToString(ciphertext) - testResp.CiphertextHex = &ciphertextHex - tag := result[0][len(result[0])-tagBytes:] - testResp.TagHex = hex.EncodeToString(tag) - } + if a.tagMergedWithCiphertext { + ciphertextHex := hex.EncodeToString(result[0]) + testResp.CiphertextHex = &ciphertextHex + } else { + ciphertext := result[0][:len(result[0])-tagBytes] + ciphertextHex := hex.EncodeToString(ciphertext) + testResp.CiphertextHex = &ciphertextHex + tag := result[0][len(result[0])-tagBytes:] + testResp.TagHex = hex.EncodeToString(tag) + } + response.Tests = append(response.Tests, testResp) + return nil + }) } else { - result, err := m.Transact(op, 2, uint32le(uint32(tagBytes)), key, append(input, tag...), nonce, aad) - if err != nil { - return nil, err - } - - if len(result[0]) != 1 || (result[0][0]&0xfe) != 0 { - return nil, fmt.Errorf("invalid AEAD status result from subprocess") - } - passed := result[0][0] == 1 - testResp.Passed = &passed - if passed { - plaintextHex := hex.EncodeToString(result[1]) - testResp.PlaintextHex = &plaintextHex - } + m.TransactAsync(op, 2, [][]byte{uint32le(uint32(tagBytes)), key, append(input, tag...), nonce, aad}, func(result [][]byte) error { + if len(result[0]) != 1 || (result[0][0]&0xfe) != 0 { + return fmt.Errorf("invalid AEAD status result from subprocess") + } + passed := result[0][0] == 1 + testResp.Passed = &passed + if passed { + plaintextHex := hex.EncodeToString(result[1]) + testResp.PlaintextHex = &plaintextHex + } + response.Tests = append(response.Tests, testResp) + return nil + }) } - - response.Tests = append(response.Tests, testResp) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/block.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/block.go index 1b1e93b9..2f058027 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/block.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/block.go @@ -288,7 +288,7 @@ type blockCipherMCTResult struct { Key3Hex string `json:"key3,omitempty"` } -func (b *blockCipher) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (b *blockCipher) Process(vectorSet []byte, m Transactable) (any, error) { var parsed blockCipherVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -397,31 +397,35 @@ func (b *blockCipher) Process(vectorSet []byte, m Transactable) (interface{}, er testResp := blockCipherTestResponse{ID: test.ID} if !mct { - var result [][]byte - var err error - + var args [][]byte if b.hasIV { - result, err = m.Transact(op, b.numResults, key, input, iv, uint32le(1)) + args = [][]byte{key, input, iv, uint32le(1)} } else { - result, err = m.Transact(op, b.numResults, key, input, uint32le(1)) - } - if err != nil { - panic("block operation failed: " + err.Error()) + args = [][]byte{key, input, uint32le(1)} } - if encrypt { - testResp.CiphertextHex = hex.EncodeToString(result[0]) - } else { - testResp.PlaintextHex = hex.EncodeToString(result[0]) - } + m.TransactAsync(op, b.numResults, args, func(result [][]byte) error { + if encrypt { + testResp.CiphertextHex = hex.EncodeToString(result[0]) + } else { + testResp.PlaintextHex = hex.EncodeToString(result[0]) + } + response.Tests = append(response.Tests, testResp) + return nil + }) } else { testResp.MCTResults = b.mctFunc(transact, encrypt, key, input, iv) + response.Tests = append(response.Tests, testResp) } - - response.Tests = append(response.Tests, testResp) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/drbg.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/drbg.go index d2f7572f..b403f046 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/drbg.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/drbg.go @@ -73,7 +73,7 @@ type drbg struct { modes map[string]bool // the supported underlying primitives for the DRBG } -func (d *drbg) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (d *drbg) Process(vectorSet []byte, m Transactable) (any, error) { var parsed drbgTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -116,7 +116,8 @@ func (d *drbg) Process(vectorSet []byte, m Transactable) (interface{}, error) { var outLenBytes [4]byte binary.LittleEndian.PutUint32(outLenBytes[:], uint32(outLen)) - var result [][]byte + var cmd string + var args [][]byte if group.PredictionResistance { var a1, a2, a3, a4 []byte if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{ @@ -124,7 +125,8 @@ func (d *drbg) Process(vectorSet []byte, m Transactable) (interface{}, error) { {"generate", group.AdditionalDataBits, &a3, group.EntropyBits, &a4}}); err != nil { return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err) } - result, err = m.Transact(d.algo+"-pr/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce) + cmd = d.algo + "-pr/" + group.Mode + args = [][]byte{outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce} } else if group.Reseed { var a1, a2, a3, a4 []byte if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{ @@ -133,7 +135,8 @@ func (d *drbg) Process(vectorSet []byte, m Transactable) (interface{}, error) { {"generate", group.AdditionalDataBits, &a4, 0, nil}}); err != nil { return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err) } - result, err = m.Transact(d.algo+"-reseed/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce) + cmd = d.algo + "-reseed/" + group.Mode + args = [][]byte{outLenBytes[:], ent, perso, a1, a2, a3, a4, nonce} } else { var a1, a2 []byte if err := extractOtherInputs(test.Other, []drbgOtherInputExpectations{ @@ -141,25 +144,31 @@ func (d *drbg) Process(vectorSet []byte, m Transactable) (interface{}, error) { {"generate", group.AdditionalDataBits, &a2, 0, nil}}); err != nil { return nil, fmt.Errorf("failed to parse other inputs from test case %d/%d: %s", group.ID, test.ID, err) } - result, err = m.Transact(d.algo+"/"+group.Mode, 1, outLenBytes[:], ent, perso, a1, a2, nonce) + cmd = d.algo + "/" + group.Mode + args = [][]byte{outLenBytes[:], ent, perso, a1, a2, nonce} } - if err != nil { - return nil, fmt.Errorf("DRBG operation failed: %s", err) - } + m.TransactAsync(cmd, 1, args, func(result [][]byte) error { + if l := uint64(len(result[0])); l != outLen { + return fmt.Errorf("wrong length DRBG result: %d bytes but wanted %d", l, outLen) + } - if l := uint64(len(result[0])); l != outLen { - return nil, fmt.Errorf("wrong length DRBG result: %d bytes but wanted %d", l, outLen) - } - - // https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#name-responses - response.Tests = append(response.Tests, drbgTestResponse{ - ID: test.ID, - OutHex: hex.EncodeToString(result[0]), + // https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#name-responses + response.Tests = append(response.Tests, drbgTestResponse{ + ID: test.ID, + OutHex: hex.EncodeToString(result[0]), + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/ecdsa.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/ecdsa.go index 4f688d38..16d3a833 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/ecdsa.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/ecdsa.go @@ -72,7 +72,7 @@ type ecdsa struct { primitives map[string]primitive } -func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (e *ecdsa) Process(vectorSet []byte, m Transactable) (any, error) { var parsed ecdsaTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -94,19 +94,20 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { for _, test := range group.Tests { var testResp ecdsaTestResponse + testResp.ID = test.ID switch parsed.Mode { case "keyGen": if group.SecretGenerationMode != "testing candidates" { return nil, fmt.Errorf("invalid secret generation mode in test group %d: %q", group.ID, group.SecretGenerationMode) } - result, err := m.Transact(e.algo+"/"+"keyGen", 3, []byte(group.Curve)) - if err != nil { - return nil, fmt.Errorf("key generation failed for test case %d/%d: %s", group.ID, test.ID, err) - } - testResp.DHex = hex.EncodeToString(result[0]) - testResp.QxHex = hex.EncodeToString(result[1]) - testResp.QyHex = hex.EncodeToString(result[2]) + m.TransactAsync(e.algo+"/"+"keyGen", 3, [][]byte{[]byte(group.Curve)}, func(result [][]byte) error { + testResp.DHex = hex.EncodeToString(result[0]) + testResp.QxHex = hex.EncodeToString(result[1]) + testResp.QyHex = hex.EncodeToString(result[2]) + response.Tests = append(response.Tests, testResp) + return nil + }) case "keyVer": qx, err := hex.DecodeString(test.QxHex) @@ -117,21 +118,21 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { if err != nil { return nil, fmt.Errorf("failed to decode qy in test case %d/%d: %s", group.ID, test.ID, err) } - result, err := m.Transact(e.algo+"/"+"keyVer", 1, []byte(group.Curve), qx, qy) - if err != nil { - return nil, fmt.Errorf("key verification failed for test case %d/%d: %s", group.ID, test.ID, err) - } - // result[0] should be a single byte: zero if false, one if true - switch { - case bytes.Equal(result[0], []byte{00}): - f := false - testResp.Passed = &f - case bytes.Equal(result[0], []byte{01}): - t := true - testResp.Passed = &t - default: - return nil, fmt.Errorf("key verification returned unexpected result: %q", result[0]) - } + m.TransactAsync(e.algo+"/"+"keyVer", 1, [][]byte{[]byte(group.Curve), qx, qy}, func(result [][]byte) error { + // result[0] should be a single byte: zero if false, one if true + switch { + case bytes.Equal(result[0], []byte{00}): + f := false + testResp.Passed = &f + case bytes.Equal(result[0], []byte{01}): + t := true + testResp.Passed = &t + default: + return fmt.Errorf("key verification returned unexpected result: %q", result[0]) + } + response.Tests = append(response.Tests, testResp) + return nil + }) case "sigGen": p := e.primitives[group.HashAlgo] @@ -163,12 +164,12 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { } op += "/componentTest" } - result, err := m.Transact(op, 2, []byte(group.Curve), sigGenPrivateKey, []byte(group.HashAlgo), msg) - if err != nil { - return nil, fmt.Errorf("signature generation failed for test case %d/%d: %s", group.ID, test.ID, err) - } - testResp.RHex = hex.EncodeToString(result[0]) - testResp.SHex = hex.EncodeToString(result[1]) + m.TransactAsync(op, 2, [][]byte{[]byte(group.Curve), sigGenPrivateKey, []byte(group.HashAlgo), msg}, func(result [][]byte) error { + testResp.RHex = hex.EncodeToString(result[0]) + testResp.SHex = hex.EncodeToString(result[1]) + response.Tests = append(response.Tests, testResp) + return nil + }) case "sigVer": p := e.primitives[group.HashAlgo] @@ -197,31 +198,34 @@ func (e *ecdsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { if err != nil { return nil, fmt.Errorf("failed to decode S in test case %d/%d: %s", group.ID, test.ID, err) } - result, err := m.Transact(e.algo+"/"+"sigVer", 1, []byte(group.Curve), []byte(group.HashAlgo), msg, qx, qy, r, s) - if err != nil { - return nil, fmt.Errorf("signature verification failed for test case %d/%d: %s", group.ID, test.ID, err) - } - // result[0] should be a single byte: zero if false, one if true - switch { - case bytes.Equal(result[0], []byte{00}): - f := false - testResp.Passed = &f - case bytes.Equal(result[0], []byte{01}): - t := true - testResp.Passed = &t - default: - return nil, fmt.Errorf("signature verification returned unexpected result: %q", result[0]) - } + m.TransactAsync(e.algo+"/"+"sigVer", 1, [][]byte{[]byte(group.Curve), []byte(group.HashAlgo), msg, qx, qy, r, s}, func(result [][]byte) error { + // result[0] should be a single byte: zero if false, one if true + switch { + case bytes.Equal(result[0], []byte{00}): + f := false + testResp.Passed = &f + case bytes.Equal(result[0], []byte{01}): + t := true + testResp.Passed = &t + default: + return fmt.Errorf("signature verification returned unexpected result: %q", result[0]) + } + response.Tests = append(response.Tests, testResp) + return nil + }) default: return nil, fmt.Errorf("invalid mode %q in ECDSA vector set", parsed.Mode) } - - testResp.ID = test.ID - response.Tests = append(response.Tests, testResp) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hash.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hash.go index b58c6f66..1f34d1a9 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hash.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hash.go @@ -62,7 +62,7 @@ type hashPrimitive struct { size int } -func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (any, error) { var parsed hashTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -89,14 +89,12 @@ func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, // http://usnistgov.github.io/ACVP/artifacts/draft-celi-acvp-sha-00.html#rfc.section.3 switch group.Type { case "AFT": - result, err := m.Transact(h.algo, 1, msg) - if err != nil { - panic(h.algo + " hash operation failed: " + err.Error()) - } - - response.Tests = append(response.Tests, hashTestResponse{ - ID: test.ID, - DigestHex: hex.EncodeToString(result[0]), + m.TransactAsync(h.algo, 1, [][]byte{msg}, func(result [][]byte) error { + response.Tests = append(response.Tests, hashTestResponse{ + ID: test.ID, + DigestHex: hex.EncodeToString(result[0]), + }) + return nil }) case "MCT": @@ -124,7 +122,13 @@ func (h *hashPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, } } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hkdf.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hkdf.go index 21ebca6f..3a6ba04c 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hkdf.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hkdf.go @@ -19,11 +19,10 @@ import ( "encoding/hex" "encoding/json" "fmt" - "strings" ) // The following structures reflect the JSON of ACVP KAS KDF tests. See -// https://pages.nist.gov/ACVP/draft-hammett-acvp-kas-kdf-twostep.html +// https://pages.nist.gov/ACVP/draft-hammett-acvp-kas-kdf-hkdf.html type hkdfTestVectorSet struct { Groups []hkdfTestGroup `json:"testGroups"` @@ -46,33 +45,21 @@ type hkdfTest struct { type hkdfConfiguration struct { Type string `json:"kdfType"` - AdditionalNonce bool `json:"requiresAdditionalNoncePair"` OutputBits uint32 `json:"l"` + HashName string `json:"hmacAlg"` FixedInfoPattern string `json:"fixedInfoPattern"` FixedInputEncoding string `json:"fixedInfoEncoding"` - KDFMode string `json:"kdfMode"` - MACMode string `json:"macMode"` - CounterLocation string `json:"counterLocation"` - CounterBits uint `json:"counterLen"` } func (c *hkdfConfiguration) extract() (outBytes uint32, hashName string, err error) { - if c.Type != "twoStep" || - c.AdditionalNonce || + if c.Type != "hkdf" || c.FixedInfoPattern != "uPartyInfo||vPartyInfo" || c.FixedInputEncoding != "concatenation" || - c.KDFMode != "feedback" || - c.CounterLocation != "after fixed data" || - c.CounterBits != 8 || c.OutputBits%8 != 0 { - return 0, "", fmt.Errorf("KAS-KDF not configured for HKDF: %#v", c) + return 0, "", fmt.Errorf("KDA not configured for HKDF: %#v", c) } - if !strings.HasPrefix(c.MACMode, "HMAC-") { - return 0, "", fmt.Errorf("MAC mode %q does't start with 'HMAC-'", c.MACMode) - } - - return c.OutputBits / 8, c.MACMode[5:], nil + return c.OutputBits / 8, c.HashName, nil } type hkdfParameters struct { @@ -129,7 +116,7 @@ type hkdfTestResponse struct { type hkdf struct{} -func (k *hkdf) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *hkdf) Process(vectorSet []byte, m Transactable) (any, error) { var parsed hkdfTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -182,21 +169,29 @@ func (k *hkdf) Process(vectorSet []byte, m Transactable) (interface{}, error) { info = append(info, uData...) info = append(info, vData...) - resp, err := m.Transact("HKDF/"+hashName, 1, key, salt, info, uint32le(outBytes)) - if err != nil { - return nil, fmt.Errorf("HKDF operation failed: %s", err) - } + m.TransactAsync("HKDF/"+hashName, 1, [][]byte{key, salt, info, uint32le(outBytes)}, func(result [][]byte) error { + if len(result[0]) != int(outBytes) { + return fmt.Errorf("HKDF operation resulted in %d bytes but wanted %d", len(result[0]), outBytes) + } + if isValidationTest { + passed := bytes.Equal(expected, result[0]) + testResp.Passed = &passed + } else { + testResp.KeyOut = hex.EncodeToString(result[0]) + } - if isValidationTest { - passed := bytes.Equal(expected, resp[0]) - testResp.Passed = &passed - } else { - testResp.KeyOut = hex.EncodeToString(resp[0]) - } - - groupResp.Tests = append(groupResp.Tests, testResp) + groupResp.Tests = append(groupResp.Tests, testResp) + return nil + }) } - respGroups = append(respGroups, groupResp) + + m.Barrier(func() { + respGroups = append(respGroups, groupResp) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return respGroups, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hmac.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hmac.go index 2fd90eac..8fc76951 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hmac.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/hmac.go @@ -76,7 +76,7 @@ func (h *hmacPrimitive) hmac(msg []byte, key []byte, outBits int, m Transactable return result[0][:outBytes] } -func (h *hmacPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (h *hmacPrimitive) Process(vectorSet []byte, m Transactable) (any, error) { var parsed hmacTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -93,6 +93,10 @@ func (h *hmacPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, if group.MACBits > h.mdLen*8 { return nil, fmt.Errorf("test group %d specifies MAC length should be %d, but maximum possible length is %d", group.ID, group.MACBits, h.mdLen*8) } + if group.MACBits%8 != 0 { + return nil, fmt.Errorf("fractional-byte HMAC output length requested: %d", group.MACBits) + } + outBytes := group.MACBits / 8 for _, test := range group.Tests { if len(test.MsgHex)*4 != group.MsgBits { @@ -111,14 +115,27 @@ func (h *hmacPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, return nil, fmt.Errorf("failed to decode key in test case %d/%d: %s", group.ID, test.ID, err) } - // https://pages.nist.gov/ACVP/draft-fussell-acvp-mac.html#name-test-vectors - response.Tests = append(response.Tests, hmacTestResponse{ - ID: test.ID, - MACHex: hex.EncodeToString(h.hmac(msg, key, group.MACBits, m)), + m.TransactAsync(h.algo, 1, [][]byte{msg, key}, func(result [][]byte) error { + if l := len(result[0]); l < outBytes { + return fmt.Errorf("HMAC result too short: %d bytes but wanted %d", l, outBytes) + } + + // https://pages.nist.gov/ACVP/draft-fussell-acvp-mac.html#name-test-vectors + response.Tests = append(response.Tests, hmacTestResponse{ + ID: test.ID, + MACHex: hex.EncodeToString(result[0][:outBytes]), + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kas.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kas.go index cb1eb915..cbc99ed5 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kas.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kas.go @@ -68,7 +68,7 @@ type kasTestResponse struct { type kas struct{} -func (k *kas) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *kas) Process(vectorSet []byte, m Transactable) (any, error) { var parsed kasVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -155,40 +155,42 @@ func (k *kas) Process(vectorSet []byte, m Transactable) (interface{}, error) { return nil, err } - result, err := m.Transact(method, 3, peerX, peerY, privateKey) - if err != nil { - return nil, err - } - - ok := bytes.Equal(result[2], expectedOutput) - response.Tests = append(response.Tests, kasTestResponse{ - ID: test.ID, - Passed: &ok, + m.TransactAsync(method, 3, [][]byte{peerX, peerY, privateKey}, func(result [][]byte) error { + ok := bytes.Equal(result[2], expectedOutput) + response.Tests = append(response.Tests, kasTestResponse{ + ID: test.ID, + Passed: &ok, + }) + return nil }) } else { - result, err := m.Transact(method, 3, peerX, peerY, nil) - if err != nil { - return nil, err - } + m.TransactAsync(method, 3, [][]byte{peerX, peerY, nil}, func(result [][]byte) error { + testResponse := kasTestResponse{ + ID: test.ID, + ResultHex: hex.EncodeToString(result[2]), + } - testResponse := kasTestResponse{ - ID: test.ID, - ResultHex: hex.EncodeToString(result[2]), - } + if useStaticNamedFields { + testResponse.StaticXHex = hex.EncodeToString(result[0]) + testResponse.StaticYHex = hex.EncodeToString(result[1]) + } else { + testResponse.EphemeralXHex = hex.EncodeToString(result[0]) + testResponse.EphemeralYHex = hex.EncodeToString(result[1]) + } - if useStaticNamedFields { - testResponse.StaticXHex = hex.EncodeToString(result[0]) - testResponse.StaticYHex = hex.EncodeToString(result[1]) - } else { - testResponse.EphemeralXHex = hex.EncodeToString(result[0]) - testResponse.EphemeralYHex = hex.EncodeToString(result[1]) - } - - response.Tests = append(response.Tests, testResponse) + response.Tests = append(response.Tests, testResponse) + return nil + }) } } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kasdh.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kasdh.go index a21d4ee4..f262b820 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kasdh.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kasdh.go @@ -59,7 +59,7 @@ type kasDHTestResponse struct { type kasDH struct{} -func (k *kasDH) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *kasDH) Process(vectorSet []byte, m Transactable) (any, error) { var parsed kasDHVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -139,31 +139,33 @@ func (k *kasDH) Process(vectorSet []byte, m Transactable) (interface{}, error) { return nil, err } - result, err := m.Transact(method, 2, p, q, g, peerPublic, privateKey, publicKey) - if err != nil { - return nil, err - } - - ok := bytes.Equal(result[1], expectedOutput) - response.Tests = append(response.Tests, kasDHTestResponse{ - ID: test.ID, - Passed: &ok, + m.TransactAsync(method, 2, [][]byte{p, q, g, peerPublic, privateKey, publicKey}, func(result [][]byte) error { + ok := bytes.Equal(result[1], expectedOutput) + response.Tests = append(response.Tests, kasDHTestResponse{ + ID: test.ID, + Passed: &ok, + }) + return nil }) } else { - result, err := m.Transact(method, 2, p, q, g, peerPublic, nil, nil) - if err != nil { - return nil, err - } - - response.Tests = append(response.Tests, kasDHTestResponse{ - ID: test.ID, - LocalPublicHex: hex.EncodeToString(result[0]), - ResultHex: hex.EncodeToString(result[1]), + m.TransactAsync(method, 2, [][]byte{p, q, g, peerPublic, nil, nil}, func(result [][]byte) error { + response.Tests = append(response.Tests, kasDHTestResponse{ + ID: test.ID, + LocalPublicHex: hex.EncodeToString(result[0]), + ResultHex: hex.EncodeToString(result[1]), + }) + return nil }) } } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kdf.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kdf.go index a80a53fd..e27fcaa9 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kdf.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/kdf.go @@ -60,7 +60,7 @@ type kdfTestResponse struct { type kdfPrimitive struct{} -func (k *kdfPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *kdfPrimitive) Process(vectorSet []byte, m Transactable) (any, error) { var parsed kdfTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -106,26 +106,30 @@ func (k *kdfPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, e } // Make the call to the crypto module. - resp, err := m.Transact("KDF-counter", 3, outputBytes, []byte(group.MACMode), []byte(group.CounterLocation), key, counterBits) - if err != nil { - return nil, fmt.Errorf("wrapper KDF operation failed: %s", err) - } + m.TransactAsync("KDF-counter", 3, [][]byte{outputBytes, []byte(group.MACMode), []byte(group.CounterLocation), key, counterBits}, func(result [][]byte) error { + testResp.ID = test.ID + if test.Deferred { + testResp.KeyIn = hex.EncodeToString(result[0]) + } + testResp.FixedData = hex.EncodeToString(result[1]) + testResp.KeyOut = hex.EncodeToString(result[2]) - // Parse results. - testResp.ID = test.ID - if test.Deferred { - testResp.KeyIn = hex.EncodeToString(resp[0]) - } - testResp.FixedData = hex.EncodeToString(resp[1]) - testResp.KeyOut = hex.EncodeToString(resp[2]) + if !test.Deferred && !bytes.Equal(result[0], key) { + return fmt.Errorf("wrapper returned a different key for non-deferred KDF operation") + } - if !test.Deferred && !bytes.Equal(resp[0], key) { - return nil, fmt.Errorf("wrapper returned a different key for non-deferred KDF operation") - } - - groupResp.Tests = append(groupResp.Tests, testResp) + groupResp.Tests = append(groupResp.Tests, testResp) + return nil + }) } - respGroups = append(respGroups, groupResp) + + m.Barrier(func() { + respGroups = append(respGroups, groupResp) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return respGroups, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/keyedMac.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/keyedMac.go index 94be1860..e43ab5d5 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/keyedMac.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/keyedMac.go @@ -57,7 +57,7 @@ type keyedMACPrimitive struct { algo string } -func (k *keyedMACPrimitive) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *keyedMACPrimitive) Process(vectorSet []byte, m Transactable) (any, error) { var vs keyedMACTestVectorSet if err := json.Unmarshal(vectorSet, &vs); err != nil { return nil, err @@ -122,17 +122,17 @@ func (k *keyedMACPrimitive) Process(vectorSet []byte, m Transactable) (interface } if generate { - result, err := m.Transact(k.algo, 1, outputBytes, key, msg) - if err != nil { - return nil, fmt.Errorf("wrapper %s operation failed: %s", k.algo, err) - } + expectedNumBytes := int(group.MACBits / 8) - calculatedMAC := result[0] - if len(calculatedMAC) != int(group.MACBits/8) { - return nil, fmt.Errorf("%s operation returned incorrect length value", k.algo) - } + m.TransactAsync(k.algo, 1, [][]byte{outputBytes, key, msg}, func(result [][]byte) error { + calculatedMAC := result[0] + if len(calculatedMAC) != expectedNumBytes { + return fmt.Errorf("%s operation returned incorrect length value", k.algo) + } - respTest.MACHex = hex.EncodeToString(calculatedMAC) + respTest.MACHex = hex.EncodeToString(calculatedMAC) + return nil + }) } else { expectedMAC, err := hex.DecodeString(test.MACHex) if err != nil { @@ -142,23 +142,29 @@ func (k *keyedMACPrimitive) Process(vectorSet []byte, m Transactable) (interface return nil, fmt.Errorf("MACHex in test case %d/%d is %x, but should be %d bits", group.ID, test.ID, expectedMAC, group.MACBits) } - result, err := m.Transact(k.algo+"/verify", 1, key, msg, expectedMAC) - if err != nil { - return nil, fmt.Errorf("wrapper %s operation failed: %s", k.algo, err) - } + m.TransactAsync(k.algo+"/verify", 1, [][]byte{key, msg, expectedMAC}, func(result [][]byte) error { + if len(result[0]) != 1 || (result[0][0]&0xfe) != 0 { + return fmt.Errorf("wrapper %s returned invalid success flag: %x", k.algo, result[0]) + } - if len(result[0]) != 1 || (result[0][0]&0xfe) != 0 { - return nil, fmt.Errorf("wrapper %s returned invalid success flag: %x", k.algo, result[0]) - } - - ok := result[0][0] == 1 - respTest.Passed = &ok + ok := result[0][0] == 1 + respTest.Passed = &ok + return nil + }) } - respGroup.Tests = append(respGroup.Tests, respTest) + m.Barrier(func() { + respGroup.Tests = append(respGroup.Tests, respTest) + }) } - respGroups = append(respGroups, respGroup) + m.Barrier(func() { + respGroups = append(respGroups, respGroup) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return respGroups, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/rsa.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/rsa.go index 2f5197e9..d975026e 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/rsa.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/rsa.go @@ -117,7 +117,7 @@ type rsaSigVerTestResponse struct { Passed bool `json:"testPassed"` } -func processKeyGen(vectorSet []byte, m Transactable) (interface{}, error) { +func processKeyGen(vectorSet []byte, m Transactable) (any, error) { var parsed rsaKeyGenTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -137,28 +137,32 @@ func processKeyGen(vectorSet []byte, m Transactable) (interface{}, error) { } for _, test := range group.Tests { - results, err := m.Transact("RSA/keyGen", 5, uint32le(group.ModulusBits)) - if err != nil { - return nil, err - } - - response.Tests = append(response.Tests, rsaKeyGenTestResponse{ - ID: test.ID, - E: hex.EncodeToString(results[0]), - P: hex.EncodeToString(results[1]), - Q: hex.EncodeToString(results[2]), - N: hex.EncodeToString(results[3]), - D: hex.EncodeToString(results[4]), + m.TransactAsync("RSA/keyGen", 5, [][]byte{uint32le(group.ModulusBits)}, func(result [][]byte) error { + response.Tests = append(response.Tests, rsaKeyGenTestResponse{ + ID: test.ID, + E: hex.EncodeToString(result[0]), + P: hex.EncodeToString(result[1]), + Q: hex.EncodeToString(result[2]), + N: hex.EncodeToString(result[3]), + D: hex.EncodeToString(result[4]), + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil } -func processSigGen(vectorSet []byte, m Transactable) (interface{}, error) { +func processSigGen(vectorSet []byte, m Transactable) (any, error) { var parsed rsaSigGenTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -185,31 +189,35 @@ func processSigGen(vectorSet []byte, m Transactable) (interface{}, error) { return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err) } - results, err := m.Transact(operation, 3, uint32le(group.ModulusBits), msg) - if err != nil { - return nil, err - } + m.TransactAsync(operation, 3, [][]byte{uint32le(group.ModulusBits), msg}, func(result [][]byte) error { + if len(response.N) == 0 { + response.N = hex.EncodeToString(result[0]) + response.E = hex.EncodeToString(result[1]) + } else if response.N != hex.EncodeToString(result[0]) { + return fmt.Errorf("module wrapper returned different RSA keys for the same SigGen configuration") + } - if len(response.N) == 0 { - response.N = hex.EncodeToString(results[0]) - response.E = hex.EncodeToString(results[1]) - } else if response.N != hex.EncodeToString(results[0]) { - return nil, fmt.Errorf("module wrapper returned different RSA keys for the same SigGen configuration") - } - - response.Tests = append(response.Tests, rsaSigGenTestResponse{ - ID: test.ID, - Sig: hex.EncodeToString(results[2]), + response.Tests = append(response.Tests, rsaSigGenTestResponse{ + ID: test.ID, + Sig: hex.EncodeToString(result[2]), + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil } -func processSigVer(vectorSet []byte, m Transactable) (interface{}, error) { +func processSigVer(vectorSet []byte, m Transactable) (any, error) { var parsed rsaSigVerTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -249,18 +257,22 @@ func processSigVer(vectorSet []byte, m Transactable) (interface{}, error) { return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err) } - results, err := m.Transact(operation, 1, n, e, msg, sig) - if err != nil { - return nil, err - } - - response.Tests = append(response.Tests, rsaSigVerTestResponse{ - ID: test.ID, - Passed: len(results[0]) == 1 && results[0][0] == 1, + m.TransactAsync(operation, 1, [][]byte{n, e, msg, sig}, func(result [][]byte) error { + response.Tests = append(response.Tests, rsaSigVerTestResponse{ + ID: test.ID, + Passed: len(result[0]) == 1 && result[0][0] == 1, + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil @@ -268,7 +280,7 @@ func processSigVer(vectorSet []byte, m Transactable) (interface{}, error) { type rsa struct{} -func (*rsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (*rsa) Process(vectorSet []byte, m Transactable) (any, error) { var parsed rsaTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go index 844c9c45..f1cb5fa8 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go @@ -30,6 +30,9 @@ import ( // that don't call a server. type Transactable interface { Transact(cmd string, expectedResults int, args ...[]byte) ([][]byte, error) + TransactAsync(cmd string, expectedResults int, args [][]byte, callback func([][]byte) error) + Barrier(callback func()) error + Flush() error } // Subprocess is a "middle" layer that interacts with a FIPS module via running @@ -39,6 +42,24 @@ type Subprocess struct { stdin io.WriteCloser stdout io.ReadCloser primitives map[string]primitive + // supportsFlush is true if the modulewrapper indicated that it wants to receive flush commands. + supportsFlush bool + // pendingReads is a queue of expected responses. `readerRoutine` reads each response and calls the callback in the matching pendingRead. + pendingReads chan pendingRead + // readerFinished is a channel that is closed if `readerRoutine` has finished (e.g. because of a read error). + readerFinished chan struct{} +} + +// pendingRead represents an expected response from the modulewrapper. +type pendingRead struct { + // barrierCallback is called as soon as this pendingRead is the next in the queue, before any read from the modulewrapper. + barrierCallback func() + + // callback is called with the result from the modulewrapper. If this is nil then no read is performed. + callback func(result [][]byte) error + // cmd is the command that requested this read for logging purposes. + cmd string + expectedNumResults int } // New returns a new Subprocess middle layer that runs the given binary. @@ -61,51 +82,67 @@ func New(path string) (*Subprocess, error) { return NewWithIO(cmd, stdin, stdout), nil } +// maxPending is the maximum number of requests that can be in the pipeline. +const maxPending = 4096 + // NewWithIO returns a new Subprocess middle layer with the given ReadCloser and // WriteCloser. The returned Subprocess will call Wait on the Cmd when closed. func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess { m := &Subprocess{ - cmd: cmd, - stdin: in, - stdout: out, + cmd: cmd, + stdin: in, + stdout: out, + pendingReads: make(chan pendingRead, maxPending), + readerFinished: make(chan struct{}), } m.primitives = map[string]primitive{ - "SHA-1": &hashPrimitive{"SHA-1", 20}, - "SHA2-224": &hashPrimitive{"SHA2-224", 28}, - "SHA2-256": &hashPrimitive{"SHA2-256", 32}, - "SHA2-384": &hashPrimitive{"SHA2-384", 48}, - "SHA2-512": &hashPrimitive{"SHA2-512", 64}, - "SHA2-512/256": &hashPrimitive{"SHA2-512/256", 32}, - "ACVP-AES-ECB": &blockCipher{"AES", 16, 2, true, false, iterateAES}, - "ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, 2, true, true, iterateAESCBC}, - "ACVP-AES-CBC-CS3": &blockCipher{"AES-CBC-CS3", 16, 1, false, true, iterateAESCBC}, - "ACVP-AES-CTR": &blockCipher{"AES-CTR", 16, 1, false, true, nil}, - "ACVP-AES-XTS": &xts{}, - "ACVP-TDES-ECB": &blockCipher{"3DES-ECB", 8, 3, true, false, iterate3DES}, - "ACVP-TDES-CBC": &blockCipher{"3DES-CBC", 8, 3, true, true, iterate3DESCBC}, - "ACVP-AES-GCM": &aead{"AES-GCM", false}, - "ACVP-AES-GMAC": &aead{"AES-GCM", false}, - "ACVP-AES-CCM": &aead{"AES-CCM", true}, - "ACVP-AES-KW": &aead{"AES-KW", false}, - "ACVP-AES-KWP": &aead{"AES-KWP", false}, - "HMAC-SHA-1": &hmacPrimitive{"HMAC-SHA-1", 20}, - "HMAC-SHA2-224": &hmacPrimitive{"HMAC-SHA2-224", 28}, - "HMAC-SHA2-256": &hmacPrimitive{"HMAC-SHA2-256", 32}, - "HMAC-SHA2-384": &hmacPrimitive{"HMAC-SHA2-384", 48}, - "HMAC-SHA2-512": &hmacPrimitive{"HMAC-SHA2-512", 64}, - "ctrDRBG": &drbg{"ctrDRBG", map[string]bool{"AES-128": true, "AES-192": true, "AES-256": true}}, - "hmacDRBG": &drbg{"hmacDRBG", map[string]bool{"SHA-1": true, "SHA2-224": true, "SHA2-256": true, "SHA2-384": true, "SHA2-512": true}}, - "KDF": &kdfPrimitive{}, - "KAS-KDF": &hkdf{}, - "CMAC-AES": &keyedMACPrimitive{"CMAC-AES"}, - "RSA": &rsa{}, - "kdf-components": &tlsKDF{}, - "KAS-ECC-SSC": &kas{}, - "KAS-FFC-SSC": &kasDH{}, + "SHA-1": &hashPrimitive{"SHA-1", 20}, + "SHA2-224": &hashPrimitive{"SHA2-224", 28}, + "SHA2-256": &hashPrimitive{"SHA2-256", 32}, + "SHA2-384": &hashPrimitive{"SHA2-384", 48}, + "SHA2-512": &hashPrimitive{"SHA2-512", 64}, + "SHA2-512/256": &hashPrimitive{"SHA2-512/256", 32}, + "SHA3-224": &hashPrimitive{"SHA3-224", 28}, + "SHA3-256": &hashPrimitive{"SHA3-256", 32}, + "SHA3-384": &hashPrimitive{"SHA3-384", 48}, + "SHA3-512": &hashPrimitive{"SHA3-512", 64}, + "ACVP-AES-ECB": &blockCipher{"AES", 16, 2, true, false, iterateAES}, + "ACVP-AES-CBC": &blockCipher{"AES-CBC", 16, 2, true, true, iterateAESCBC}, + "ACVP-AES-CBC-CS3": &blockCipher{"AES-CBC-CS3", 16, 1, false, true, iterateAESCBC}, + "ACVP-AES-CTR": &blockCipher{"AES-CTR", 16, 1, false, true, nil}, + "ACVP-TDES-ECB": &blockCipher{"3DES-ECB", 8, 3, true, false, iterate3DES}, + "ACVP-TDES-CBC": &blockCipher{"3DES-CBC", 8, 3, true, true, iterate3DESCBC}, + "ACVP-AES-XTS": &xts{}, + "ACVP-AES-GCM": &aead{"AES-GCM", false}, + "ACVP-AES-GMAC": &aead{"AES-GCM", false}, + "ACVP-AES-CCM": &aead{"AES-CCM", true}, + "ACVP-AES-KW": &aead{"AES-KW", false}, + "ACVP-AES-KWP": &aead{"AES-KWP", false}, + "HMAC-SHA-1": &hmacPrimitive{"HMAC-SHA-1", 20}, + "HMAC-SHA2-224": &hmacPrimitive{"HMAC-SHA2-224", 28}, + "HMAC-SHA2-256": &hmacPrimitive{"HMAC-SHA2-256", 32}, + "HMAC-SHA2-384": &hmacPrimitive{"HMAC-SHA2-384", 48}, + "HMAC-SHA2-512": &hmacPrimitive{"HMAC-SHA2-512", 64}, + "HMAC-SHA2-512/256": &hmacPrimitive{"HMAC-SHA2-512/256", 32}, + "HMAC-SHA3-224": &hmacPrimitive{"HMAC-SHA3-224", 28}, + "HMAC-SHA3-256": &hmacPrimitive{"HMAC-SHA3-256", 32}, + "HMAC-SHA3-384": &hmacPrimitive{"HMAC-SHA3-384", 48}, + "HMAC-SHA3-512": &hmacPrimitive{"HMAC-SHA3-512", 64}, + "ctrDRBG": &drbg{"ctrDRBG", map[string]bool{"AES-128": true, "AES-192": true, "AES-256": true}}, + "hmacDRBG": &drbg{"hmacDRBG", map[string]bool{"SHA-1": true, "SHA2-224": true, "SHA2-256": true, "SHA2-384": true, "SHA2-512": true}}, + "KDF": &kdfPrimitive{}, + "KDA": &hkdf{}, + "TLS-v1.2": &tlsKDF{}, + "TLS-v1.3": &tls13{}, + "CMAC-AES": &keyedMACPrimitive{"CMAC-AES"}, + "RSA": &rsa{}, + "KAS-ECC-SSC": &kas{}, + "KAS-FFC-SSC": &kasDH{}, } m.primitives["ECDSA"] = &ecdsa{"ECDSA", map[string]bool{"P-224": true, "P-256": true, "P-384": true, "P-521": true}, m.primitives} + go m.readerRoutine() return m } @@ -114,10 +151,58 @@ func (m *Subprocess) Close() { m.stdout.Close() m.stdin.Close() m.cmd.Wait() + close(m.pendingReads) + <-m.readerFinished } -// Transact performs a single request--response pair with the subprocess. -func (m *Subprocess) Transact(cmd string, expectedResults int, args ...[]byte) ([][]byte, error) { +func (m *Subprocess) flush() error { + if !m.supportsFlush { + return nil + } + + const cmd = "flush" + buf := make([]byte, 8, 8+len(cmd)) + binary.LittleEndian.PutUint32(buf, 1) + binary.LittleEndian.PutUint32(buf[4:], uint32(len(cmd))) + buf = append(buf, []byte(cmd)...) + + if _, err := m.stdin.Write(buf); err != nil { + return err + } + return nil +} + +func (m *Subprocess) enqueueRead(pending pendingRead) error { + select { + case <-m.readerFinished: + panic("attempted to enqueue request after the reader failed") + default: + } + + select { + case m.pendingReads <- pending: + break + default: + // `pendingReads` is full. Ensure that the modulewrapper will process + // some outstanding requests to free up space in the queue. + if err := m.flush(); err != nil { + return err + } + m.pendingReads <- pending + } + + return nil +} + +// TransactAsync performs a single request--response pair with the subprocess. +// The callback will run at some future point, in a separate goroutine. All +// callbacks will, however, be run in the order that TransactAsync was called. +// Use Flush to wait for all outstanding callbacks. +func (m *Subprocess) TransactAsync(cmd string, expectedNumResults int, args [][]byte, callback func(result [][]byte) error) { + if err := m.enqueueRead(pendingRead{nil, callback, cmd, expectedNumResults}); err != nil { + panic(err) + } + argLength := len(cmd) for _, arg := range args { argLength += len(arg) @@ -135,17 +220,88 @@ func (m *Subprocess) Transact(cmd string, expectedResults int, args ...[]byte) ( } if _, err := m.stdin.Write(buf); err != nil { + panic(err) + } +} + +// Flush tells the subprocess to complete all outstanding requests and waits +// for all outstanding TransactAsync callbacks to complete. +func (m *Subprocess) Flush() error { + if m.supportsFlush { + m.flush() + } + + done := make(chan struct{}) + if err := m.enqueueRead(pendingRead{barrierCallback: func() { + close(done) + }}); err != nil { + return err + } + + <-done + return nil +} + +// Barrier runs callback after all outstanding TransactAsync callbacks have +// been run. +func (m *Subprocess) Barrier(callback func()) error { + return m.enqueueRead(pendingRead{barrierCallback: callback}) +} + +func (m *Subprocess) Transact(cmd string, expectedNumResults int, args ...[]byte) ([][]byte, error) { + done := make(chan struct{}) + var result [][]byte + m.TransactAsync(cmd, expectedNumResults, args, func(r [][]byte) error { + result = r + close(done) + return nil + }) + + if err := m.flush(); err != nil { return nil, err } - buf = buf[:4] + select { + case <-done: + return result, nil + case <-m.readerFinished: + panic("was still waiting for a result when the reader finished") + } +} + +func (m *Subprocess) readerRoutine() { + defer close(m.readerFinished) + + for pendingRead := range m.pendingReads { + if pendingRead.barrierCallback != nil { + pendingRead.barrierCallback() + } + + if pendingRead.callback == nil { + continue + } + + result, err := m.readResult(pendingRead.cmd, pendingRead.expectedNumResults) + if err != nil { + panic(fmt.Errorf("failed to read from subprocess: %w", err)) + } + + if err := pendingRead.callback(result); err != nil { + panic(fmt.Errorf("result from subprocess was rejected: %w", err)) + } + } +} + +func (m *Subprocess) readResult(cmd string, expectedNumResults int) ([][]byte, error) { + buf := make([]byte, 4) + if _, err := io.ReadFull(m.stdout, buf); err != nil { return nil, err } numResults := binary.LittleEndian.Uint32(buf) - if int(numResults) != expectedResults { - return nil, fmt.Errorf("expected %d results from %q but got %d", expectedResults, cmd, numResults) + if int(numResults) != expectedNumResults { + return nil, fmt.Errorf("expected %d results from %q but got %d", expectedNumResults, cmd, numResults) } buf = make([]byte, 4*numResults) @@ -187,21 +343,30 @@ func (m *Subprocess) Config() ([]byte, error) { return nil, err } var config []struct { - Algorithm string `json:"algorithm"` + Algorithm string `json:"algorithm"` + Features []string `json:"features"` } if err := json.Unmarshal(results[0], &config); err != nil { return nil, errors.New("failed to parse config response from wrapper: " + err.Error()) } for _, algo := range config { - if _, ok := m.primitives[algo.Algorithm]; !ok { + if algo.Algorithm == "acvptool" { + for _, feature := range algo.Features { + switch feature { + case "batch": + m.supportsFlush = true + } + } + } else if _, ok := m.primitives[algo.Algorithm]; !ok { return nil, fmt.Errorf("wrapper config advertises support for unknown algorithm %q", algo.Algorithm) } } + return results[0], nil } // Process runs a set of test vectors and returns the result. -func (m *Subprocess) Process(algorithm string, vectorSet []byte) (interface{}, error) { +func (m *Subprocess) Process(algorithm string, vectorSet []byte) (any, error) { prim, ok := m.primitives[algorithm] if !ok { return nil, fmt.Errorf("unknown algorithm %q", algorithm) @@ -214,7 +379,7 @@ func (m *Subprocess) Process(algorithm string, vectorSet []byte) (interface{}, e } type primitive interface { - Process(vectorSet []byte, t Transactable) (interface{}, error) + Process(vectorSet []byte, t Transactable) (any, error) } func uint32le(n uint32) []byte { diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tls13.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tls13.go new file mode 100644 index 00000000..af2aae83 --- /dev/null +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tls13.go @@ -0,0 +1,240 @@ +// Copyright (c) 2023, Google Inc. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +package subprocess + +import ( + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "encoding/json" + "fmt" +) + +// The following structures reflect the JSON of TLS 1.3 tests. See +// https://pages.nist.gov/ACVP/draft-hammett-acvp-kdf-tls-v1.3.html + +type tls13TestVectorSet struct { + Groups []tls13TestGroup `json:"testGroups"` +} + +type tls13TestGroup struct { + ID uint64 `json:"tgId"` + HashFunc string `json:"hmacAlg"` + Tests []tls13Test `json:"tests"` +} + +type tls13Test struct { + ID uint64 `json:"tcId"` + // Although ACVP refers to these as client and server randoms, these + // fields are misnamed and really contain portions of the handshake + // transcript. Concatenated in order, they give the transcript up to + // the named message. In case of HelloRetryRequest, ClientHelloHex + // includes up to the second ClientHello. + ClientHelloHex string `json:"helloClientRandom"` + ServerHelloHex string `json:"helloServerRandom"` + ServerFinishedHex string `json:"finishedServerRandom"` + ClientFinishedHex string `json:"finishedClientRandom"` + DHEInputHex string `json:"dhe"` + PSKInputHex string `json:"psk"` +} + +type tls13TestGroupResponse struct { + ID uint64 `json:"tgId"` + Tests []tls13TestResponse `json:"tests"` +} + +type tls13TestResponse struct { + ID uint64 `json:"tcId"` + ClientEarlyTrafficSecretHex string `json:"clientEarlyTrafficSecret"` + EarlyExporterMasterSecretHex string `json:"earlyExporterMasterSecret"` + ClientHandshakeTrafficSecretHex string `json:"clientHandshakeTrafficSecret"` + ServerHandshakeTrafficSecretHex string `json:"serverHandshakeTrafficSecret"` + ClientApplicationTrafficSecretHex string `json:"clientApplicationTrafficSecret"` + ServerApplicationTrafficSecretHex string `json:"serverApplicationTrafficSecret"` + ExporterMasterSecretHex string `json:"exporterMasterSecret"` + ResumptionMasterSecretHex string `json:"resumptionMasterSecret"` +} + +type tls13 struct{} + +func (k *tls13) Process(vectorSet []byte, m Transactable) (any, error) { + var parsed tls13TestVectorSet + if err := json.Unmarshal(vectorSet, &parsed); err != nil { + return nil, err + } + + var respGroups []tls13TestGroupResponse + for _, group := range parsed.Groups { + groupResp := tls13TestGroupResponse{ID: group.ID} + + for _, test := range group.Tests { + testResp := tls13TestResponse{ID: test.ID} + + clientHello, err := hex.DecodeString(test.ClientHelloHex) + if err != nil { + return nil, err + } + serverHello, err := hex.DecodeString(test.ServerHelloHex) + if err != nil { + return nil, err + } + serverFinished, err := hex.DecodeString(test.ServerFinishedHex) + if err != nil { + return nil, err + } + clientFinished, err := hex.DecodeString(test.ClientFinishedHex) + if err != nil { + return nil, err + } + + // See https://www.rfc-editor.org/rfc/rfc8446#section-7.1 + var hashLen int + var emptyHash []byte + switch group.HashFunc { + case "SHA2-256": + hashLen = 256 / 8 + digest := sha256.Sum256(nil) + emptyHash = digest[:] + case "SHA2-384": + hashLen = 384 / 8 + digest := sha512.Sum384(nil) + emptyHash = digest[:] + default: + return nil, fmt.Errorf("hash function %q is not supported for TLS v1.3", group.HashFunc) + } + hashLenBytes := uint32le(uint32(hashLen)) + + psk, err := hex.DecodeString(test.PSKInputHex) + if err != nil { + return nil, err + } + if len(psk) == 0 { + psk = make([]byte, hashLen) + } + + dhe, err := hex.DecodeString(test.DHEInputHex) + if err != nil { + return nil, err + } + if len(dhe) == 0 { + dhe = make([]byte, hashLen) + } + + zeros := make([]byte, hashLen) + earlySecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, psk, zeros) + if err != nil { + return nil, fmt.Errorf("HKDFExtract operation failed: %s", err) + } + + hashedToClientHello, err := m.Transact(group.HashFunc, 1, clientHello) + if err != nil { + return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err) + } + hashedToServerHello, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello)) + if err != nil { + return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err) + } + hashedToServerFinished, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello, serverFinished)) + if err != nil { + return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err) + } + hashedMessages, err := m.Transact(group.HashFunc, 1, concat(clientHello, serverHello, serverFinished, clientFinished)) + if err != nil { + return nil, fmt.Errorf("%q operation failed: %s", group.HashFunc, err) + } + + clientEarlyTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("c e traffic"), hashedToClientHello[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ClientEarlyTrafficSecretHex = hex.EncodeToString(clientEarlyTrafficSecret[0]) + + earlyExporter, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("e exp master"), hashedToClientHello[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.EarlyExporterMasterSecretHex = hex.EncodeToString(earlyExporter[0]) + + derivedSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, earlySecret[0], []byte("derived"), emptyHash[:]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + + handshakeSecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, dhe, derivedSecret[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExtract operation failed: %s", err) + } + + clientHandshakeTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("c hs traffic"), hashedToServerHello[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ClientHandshakeTrafficSecretHex = hex.EncodeToString(clientHandshakeTrafficSecret[0]) + + serverHandshakeTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("s hs traffic"), hashedToServerHello[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ServerHandshakeTrafficSecretHex = hex.EncodeToString(serverHandshakeTrafficSecret[0]) + + derivedSecret, err = m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, handshakeSecret[0], []byte("derived"), emptyHash[:]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + + masterSecret, err := m.Transact("HKDFExtract/"+group.HashFunc, 1, zeros, derivedSecret[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExtract operation failed: %s", err) + } + + clientAppTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("c ap traffic"), hashedToServerFinished[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ClientApplicationTrafficSecretHex = hex.EncodeToString(clientAppTrafficSecret[0]) + + serverAppTrafficSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("s ap traffic"), hashedToServerFinished[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ServerApplicationTrafficSecretHex = hex.EncodeToString(serverAppTrafficSecret[0]) + + exporterSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("exp master"), hashedToServerFinished[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ExporterMasterSecretHex = hex.EncodeToString(exporterSecret[0]) + + resumptionSecret, err := m.Transact("HKDFExpandLabel/"+group.HashFunc, 1, hashLenBytes, masterSecret[0], []byte("res master"), hashedMessages[0]) + if err != nil { + return nil, fmt.Errorf("HKDFExpandLabel operation failed: %s", err) + } + testResp.ResumptionMasterSecretHex = hex.EncodeToString(resumptionSecret[0]) + + groupResp.Tests = append(groupResp.Tests, testResp) + } + respGroups = append(respGroups, groupResp) + } + + return respGroups, nil +} + +func concat(slices ...[]byte) []byte { + var ret []byte + for _, slice := range slices { + ret = append(ret, slice...) + } + return ret +} diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tlskdf.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tlskdf.go index 2e2b65d3..3a0d7cea 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tlskdf.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/tlskdf.go @@ -35,17 +35,11 @@ type tlsKDFTestGroup struct { } type tlsKDFTest struct { - ID uint64 `json:"tcId"` - PMSHex string `json:"preMasterSecret"` - // ClientHelloRandomHex and ServerHelloRandomHex are used for deriving the - // master secret. ClientRandomHex and ServerRandomHex are used for deriving the - // key block. Having different values for these is not possible in a TLS - // handshake unless you squint at a resumption handshake and somehow rederive - // the master secret from the session information during resumption. - ClientHelloRandomHex string `json:"clientHelloRandom"` - ServerHelloRandomHex string `json:"serverHelloRandom"` - ClientRandomHex string `json:"clientRandom"` - ServerRandomHex string `json:"serverRandom"` + ID uint64 `json:"tcId"` + PMSHex string `json:"preMasterSecret"` + ClientRandomHex string `json:"clientRandom"` + ServerRandomHex string `json:"serverRandom"` + SessionHashHex string `json:"sessionHash"` } type tlsKDFTestGroupResponse struct { @@ -61,7 +55,7 @@ type tlsKDFTestResponse struct { type tlsKDF struct{} -func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (any, error) { var parsed tlsKDFVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -74,35 +68,18 @@ func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) ID: group.ID, } - var tlsVer string - switch group.TLSVersion { - case "v1.0/1.1": - tlsVer = "1.0" - case "v1.2": - tlsVer = "1.2" - default: - return nil, fmt.Errorf("unknown TLS version %q", group.TLSVersion) - } - - hashIsTLS10 := false switch group.Hash { - case "SHA-1": - hashIsTLS10 = true case "SHA2-256", "SHA2-384", "SHA2-512": break default: return nil, fmt.Errorf("unknown hash %q", group.Hash) } - if (tlsVer == "1.0") != hashIsTLS10 { - return nil, fmt.Errorf("hash %q not permitted with TLS version %q", group.Hash, group.TLSVersion) - } - if group.KeyBlockBits%8 != 0 { return nil, fmt.Errorf("requested key-block length (%d bits) is not a whole number of bytes", group.KeyBlockBits) } - method := "TLSKDF/" + tlsVer + "/" + group.Hash + method := "TLSKDF/1.2/" + group.Hash for _, test := range group.Tests { pms, err := hex.DecodeString(test.PMSHex) @@ -110,16 +87,6 @@ func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) return nil, err } - clientHelloRandom, err := hex.DecodeString(test.ClientHelloRandomHex) - if err != nil { - return nil, err - } - - serverHelloRandom, err := hex.DecodeString(test.ServerHelloRandomHex) - if err != nil { - return nil, err - } - clientRandom, err := hex.DecodeString(test.ClientRandomHex) if err != nil { return nil, err @@ -130,15 +97,20 @@ func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) return nil, err } + sessionHash, err := hex.DecodeString(test.SessionHashHex) + if err != nil { + return nil, err + } + const ( masterSecretLength = 48 - masterSecretLabel = "master secret" + masterSecretLabel = "extended master secret" keyBlockLabel = "key expansion" ) var outLenBytes [4]byte binary.LittleEndian.PutUint32(outLenBytes[:], uint32(masterSecretLength)) - result, err := m.Transact(method, 1, outLenBytes[:], pms, []byte(masterSecretLabel), clientHelloRandom, serverHelloRandom) + result, err := m.Transact(method, 1, outLenBytes[:], pms, []byte(masterSecretLabel), sessionHash, nil) if err != nil { return nil, err } @@ -146,19 +118,23 @@ func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) binary.LittleEndian.PutUint32(outLenBytes[:], uint32(group.KeyBlockBits/8)) // TLS 1.0, 1.1, and 1.2 use a different order for the client and server // randoms when computing the key block. - result2, err := m.Transact(method, 1, outLenBytes[:], result[0], []byte(keyBlockLabel), serverRandom, clientRandom) - if err != nil { - return nil, err - } - - response.Tests = append(response.Tests, tlsKDFTestResponse{ - ID: test.ID, - MasterSecretHex: hex.EncodeToString(result[0]), - KeyBlockHex: hex.EncodeToString(result2[0]), + m.TransactAsync(method, 1, [][]byte{outLenBytes[:], result[0], []byte(keyBlockLabel), serverRandom, clientRandom}, func(result2 [][]byte) error { + response.Tests = append(response.Tests, tlsKDFTestResponse{ + ID: test.ID, + MasterSecretHex: hex.EncodeToString(result[0]), + KeyBlockHex: hex.EncodeToString(result2[0]), + }) + return nil }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/xts.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/xts.go index e3546a33..e8134097 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/xts.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/subprocess/xts.go @@ -59,7 +59,7 @@ type xtsTestResponse struct { // encrypt/decrypt with AES-XTS. type xts struct{} -func (h *xts) Process(vectorSet []byte, m Transactable) (interface{}, error) { +func (h *xts) Process(vectorSet []byte, m Transactable) (any, error) { var parsed xtsTestVectorSet if err := json.Unmarshal(vectorSet, &parsed); err != nil { return nil, err @@ -126,22 +126,26 @@ func (h *xts) Process(vectorSet []byte, m Transactable) (interface{}, error) { return nil, fmt.Errorf("failed to decode hex in test case %d/%d: %s", group.ID, test.ID, err) } - result, err := m.Transact(funcName, 1, key, msg, tweak[:]) - if err != nil { - return nil, fmt.Errorf("submodule failed on test case %d/%d: %s", group.ID, test.ID, err) - } + m.TransactAsync(funcName, 1, [][]byte{key, msg, tweak[:]}, func(result [][]byte) error { + testResponse := xtsTestResponse{ID: test.ID} + if decrypt { + testResponse.PlaintextHex = hex.EncodeToString(result[0]) + } else { + testResponse.CiphertextHex = hex.EncodeToString(result[0]) + } - testResponse := xtsTestResponse{ID: test.ID} - if decrypt { - testResponse.PlaintextHex = hex.EncodeToString(result[0]) - } else { - testResponse.CiphertextHex = hex.EncodeToString(result[0]) - } - - response.Tests = append(response.Tests, testResponse) + response.Tests = append(response.Tests, testResponse) + return nil + }) } - ret = append(ret, response) + m.Barrier(func() { + ret = append(ret, response) + }) + } + + if err := m.Flush(); err != nil { + return nil, err } return ret, nil diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/check_expected.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/check_expected.go index 8a120212..d02f2729 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/check_expected.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/check_expected.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -21,7 +23,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "os" "os/exec" @@ -43,6 +44,7 @@ type invocation struct { wrapperPath string inPath string expectedPath string + configPath string } func main() { @@ -86,6 +88,15 @@ func main() { log.Fatal(err) } + configFile, err := os.CreateTemp("", "boringssl-check_expected-config-") + if err != nil { + log.Fatalf("Failed to create temp file for config: %s", err) + } + defer os.Remove(configFile.Name()) + if _, err := configFile.WriteString("{}\n"); err != nil { + log.Fatalf("Failed to write config file: %s", err) + } + work := make(chan invocation, runtime.NumCPU()) var numFailed uint32 @@ -105,6 +116,7 @@ func main() { wrapperPath: wrapper, inPath: test.In, expectedPath: test.Out, + configPath: configFile.Name(), } } @@ -138,7 +150,7 @@ func doTest(test invocation) error { } defer input.Close() - tempFile, err := ioutil.TempFile("", "boringssl-check_expected-") + tempFile, err := os.CreateTemp("", "boringssl-check_expected-") if err != nil { return fmt.Errorf("Failed to create temp file: %s", err) } @@ -150,7 +162,7 @@ func doTest(test invocation) error { return fmt.Errorf("Failed to decompress %q: %s", test.inPath, err) } - cmd := exec.Command(test.toolPath, "-wrapper", test.wrapperPath, "-json", tempFile.Name()) + cmd := exec.Command(test.toolPath, "-wrapper", test.wrapperPath, "-json", tempFile.Name(), "-config", test.configPath) result, err := cmd.CombinedOutput() if err != nil { os.Stderr.Write(result) @@ -190,7 +202,8 @@ func doTest(test invocation) error { } func writeUpdate(path string, contents []byte) { - if err := ioutil.WriteFile(path, contents, 0644); err != nil { + path = strings.TrimSuffix(path, ".bz2") + if err := os.WriteFile(path, contents, 0644); err != nil { log.Printf("Failed to create missing file %q: %s", path, err) } else { log.Printf("Wrote %q", path) diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC-CS3.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC-CS3.bz2 index 9a6c4c04..02d4ddee 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC-CS3.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC-CS3.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC.bz2 index b5a679ef..ae3a9a5c 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CBC.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CCM.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CCM.bz2 index a8b6d6ce..3d13d558 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CCM.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CCM.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CTR.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CTR.bz2 index 2962c992..967cea85 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CTR.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-CTR.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-ECB.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-ECB.bz2 index 13f52fdd..28f8e200 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-ECB.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-ECB.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GCM.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GCM.bz2 index d50948da..a3d9b523 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GCM.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GCM.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GMAC.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GMAC.bz2 index 0ca163ba..1d97836d 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GMAC.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-GMAC.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KW.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KW.bz2 index 276c35df..29041418 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KW.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KW.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KWP.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KWP.bz2 index 69129bc2..9714e6db 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KWP.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-KWP.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-XTS.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-XTS.bz2 index a197e273..3598e133 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-XTS.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-AES-XTS.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 deleted file mode 100644 index 4c2832c5..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-CBC.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-ECB.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-ECB.bz2 deleted file mode 100644 index 1128b499..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ACVP-TDES-ECB.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 index c97faded..f80e5021 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/CMAC-AES.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 index 7ee11ad6..aa5c7030 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ECDSA.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 new file mode 100644 index 00000000..791fa7a0 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HKDF.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 index c1ae2ad5..a95786d5 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA-1.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 index 33756def..c8ab1f9c 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-224.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 index 43688c8c..10908353 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-256.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 index f6c074d1..5b445a5a 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-384.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 new file mode 100644 index 00000000..1fdfa428 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512-256.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 index f0ab7d6c..3e467241 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/HMAC-SHA2-512.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KAS-KDF.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KAS-KDF.bz2 deleted file mode 100644 index df3edf56..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KAS-KDF.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KDA.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KDA.bz2 new file mode 100644 index 00000000..aabc63b3 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/KDA.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/RSA.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/RSA.bz2 index bf22ce55..2e5e8b15 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/RSA.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/RSA.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA-1.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA-1.bz2 index c21a83f6..bfa98d92 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA-1.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA-1.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-224.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-224.bz2 index 20d0a908..a2dca779 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-224.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-224.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-256.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-256.bz2 index 5c99dafb..b21ae00a 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-256.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-256.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-384.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-384.bz2 index d22e81c6..e3c8b1b3 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-384.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-384.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-512.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-512.bz2 index c130659e..2bbc7162 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-512.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/SHA2-512.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS12.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS12.bz2 new file mode 100644 index 00000000..d83b6916 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS12.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS13.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS13.bz2 new file mode 100644 index 00000000..7693c5f6 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/TLS13.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ctrDRBG.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ctrDRBG.bz2 index 9f6e4870..60da2b2b 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ctrDRBG.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/ctrDRBG.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/hmacDRBG.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/hmacDRBG.bz2 index 286ba0cf..530a813a 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/hmacDRBG.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/hmacDRBG.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/kdf-components.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/kdf-components.bz2 index 93ef1e48..f0a4d3aa 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/kdf-components.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/expected/kdf-components.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/tests.json b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/tests.json index f6139177..421e2535 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/tests.json +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/tests.json @@ -9,8 +9,6 @@ {"Wrapper": "modulewrapper", "In": "vectors/ACVP-AES-KW.bz2", "Out": "expected/ACVP-AES-KW.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ACVP-AES-KWP.bz2", "Out": "expected/ACVP-AES-KWP.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/ACVP-AES-XTS.bz2", "Out": "expected/ACVP-AES-XTS.bz2"}, -{"Wrapper": "modulewrapper", "In": "vectors/ACVP-TDES-CBC.bz2", "Out": "expected/ACVP-TDES-CBC.bz2"}, -{"Wrapper": "modulewrapper", "In": "vectors/ACVP-TDES-ECB.bz2", "Out": "expected/ACVP-TDES-ECB.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/CMAC-AES.bz2", "Out": "expected/CMAC-AES.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ctrDRBG.bz2", "Out": "expected/ctrDRBG.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/ECDSA.bz2", "Out": "expected/ECDSA.bz2"}, @@ -19,16 +17,19 @@ {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-256.bz2", "Out": "expected/HMAC-SHA2-256.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-384.bz2", "Out": "expected/HMAC-SHA2-384.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-512.bz2", "Out": "expected/HMAC-SHA2-512.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/HMAC-SHA2-512-256.bz2", "Out": "expected/HMAC-SHA2-512-256.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/HKDF.bz2", "Out": "expected/HKDF.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/hmacDRBG.bz2", "Out": "expected/hmacDRBG.bz2"}, -{"Wrapper": "testmodulewrapper", "In": "vectors/KAS-KDF.bz2", "Out": "expected/KAS-KDF.bz2"}, +{"Wrapper": "testmodulewrapper", "In": "vectors/KDA.bz2", "Out": "expected/KDA.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/KAS-ECC-SSC.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/KAS-FFC-SSC.bz2"}, {"Wrapper": "testmodulewrapper", "In": "vectors/KDF.bz2"}, -{"Wrapper": "modulewrapper", "In": "vectors/kdf-components.bz2", "Out": "expected/kdf-components.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/RSA.bz2", "Out": "expected/RSA.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/SHA-1.bz2", "Out": "expected/SHA-1.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/SHA2-224.bz2", "Out": "expected/SHA2-224.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/SHA2-256.bz2", "Out": "expected/SHA2-256.bz2"}, {"Wrapper": "modulewrapper", "In": "vectors/SHA2-384.bz2", "Out": "expected/SHA2-384.bz2"}, -{"Wrapper": "modulewrapper", "In": "vectors/SHA2-512.bz2", "Out": "expected/SHA2-512.bz2"} +{"Wrapper": "modulewrapper", "In": "vectors/SHA2-512.bz2", "Out": "expected/SHA2-512.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/TLS12.bz2", "Out": "expected/TLS12.bz2"}, +{"Wrapper": "modulewrapper", "In": "vectors/TLS13.bz2", "Out": "expected/TLS13.bz2"} ] diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/trim_vectors.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/trim_vectors.go index 53e970e0..d3402109 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/trim_vectors.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/trim_vectors.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // trimvectors takes an ACVP vector set file and discards all but a single test // from each test group. This hope is that this achieves good coverage without // having to check in megabytes worth of JSON files. @@ -23,7 +25,7 @@ import ( ) func main() { - var vectorSets []interface{} + var vectorSets []any decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(&vectorSets); err != nil { panic(err) @@ -31,18 +33,18 @@ func main() { // The first element is the metadata which is left unmodified. for i := 1; i < len(vectorSets); i++ { - vectorSet := vectorSets[i].(map[string]interface{}) - testGroups := vectorSet["testGroups"].([]interface{}) + vectorSet := vectorSets[i].(map[string]any) + testGroups := vectorSet["testGroups"].([]any) for _, testGroupInterface := range testGroups { - testGroup := testGroupInterface.(map[string]interface{}) - tests := testGroup["tests"].([]interface{}) + testGroup := testGroupInterface.(map[string]any) + tests := testGroup["tests"].([]any) keepIndex := 10 if keepIndex >= len(tests) { keepIndex = len(tests) - 1 } - testGroup["tests"] = []interface{}{tests[keepIndex]} + testGroup["tests"] = []any{tests[keepIndex]} } } diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 deleted file mode 100644 index 33fdbf35..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-CBC.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 deleted file mode 100644 index c8853ed2..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ACVP-TDES-ECB.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 new file mode 100644 index 00000000..f69a4619 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HKDF.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 new file mode 100644 index 00000000..d9813002 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/HMAC-SHA2-512-256.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KAS-KDF.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KAS-KDF.bz2 deleted file mode 100644 index eadbc7e2..00000000 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KAS-KDF.bz2 and /dev/null differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KDA.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KDA.bz2 new file mode 100644 index 00000000..a5a8aa8e Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/KDA.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS12.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS12.bz2 new file mode 100644 index 00000000..d1911ab9 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS12.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS13.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS13.bz2 new file mode 100644 index 00000000..7e8ea080 Binary files /dev/null and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/TLS13.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ctrDRBG.bz2 b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ctrDRBG.bz2 index 16f447f8..12312721 100644 Binary files a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ctrDRBG.bz2 and b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/test/vectors/ctrDRBG.bz2 differ diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/testmodulewrapper/testmodulewrapper.go b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/testmodulewrapper/testmodulewrapper.go index afb18046..4cf50693 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/testmodulewrapper/testmodulewrapper.go +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/acvptool/testmodulewrapper/testmodulewrapper.go @@ -35,7 +35,13 @@ import ( "golang.org/x/crypto/xts" ) +var ( + output io.Writer + outputBuffer *bytes.Buffer +) + var handlers = map[string]func([][]byte) error{ + "flush": flush, "getConfig": getConfig, "KDF-counter": kdfCounter, "AES-XTS/encrypt": xtsEncrypt, @@ -47,13 +53,29 @@ var handlers = map[string]func([][]byte) error{ "AES-CBC-CS3/decrypt": ctsDecrypt, } +func flush(args [][]byte) error { + if outputBuffer == nil { + return nil + } + + if _, err := os.Stdout.Write(outputBuffer.Bytes()); err != nil { + return err + } + outputBuffer = new(bytes.Buffer) + output = outputBuffer + return nil +} + func getConfig(args [][]byte) error { if len(args) != 0 { return fmt.Errorf("getConfig received %d args", len(args)) } - return reply([]byte(`[ + if err := reply([]byte(`[ { + "algorithm": "acvptool", + "features": ["batch"] + }, { "algorithm": "KDF", "revision": "1.0", "capabilities": [{ @@ -91,36 +113,20 @@ func getConfig(args [][]byte) error { "number" ] }, { - "algorithm": "KAS-KDF", - "mode": "TwoStep", - "revision": "Sp800-56Cr2", - "capabilities": [{ - "macSaltMethods": [ - "random", - "default" - ], - "fixedInfoPattern": "uPartyInfo||vPartyInfo", - "encoding": [ - "concatenation" - ], - "kdfMode": "feedback", - "macMode": [ - "HMAC-SHA2-256" - ], - "supportedLengths": [{ - "min": 128, - "max": 512, - "increment": 64 - }], - "fixedDataOrder": [ - "after fixed data" - ], - "counterLength": [ - 8 - ], - "requiresEmptyIv": true, - "supportsEmptyIv": true - }], + "algorithm": "KDA", + "mode": "HKDF", + "revision": "Sp800-56Cr1", + "fixedInfoPattern": "uPartyInfo||vPartyInfo", + "encoding": [ + "concatenation" + ], + "hmacAlg": [ + "SHA2-256" + ], + "macSaltMethods": [ + "default", + "random" + ], "l": 256, "z": [256, 384] }, { @@ -162,7 +168,11 @@ func getConfig(args [][]byte) error { 256 ] } -]`)) +]`)); err != nil { + return err + } + + return flush(nil) } func kdfCounter(args [][]byte) error { @@ -223,12 +233,12 @@ func reply(responses ...[]byte) error { } lengthsLength := (1 + len(responses)) * 4 - if n, err := os.Stdout.Write(lengths[:lengthsLength]); n != lengthsLength || err != nil { + if n, err := output.Write(lengths[:lengthsLength]); n != lengthsLength || err != nil { return fmt.Errorf("write failed: %s", err) } for _, response := range responses { - if n, err := os.Stdout.Write(response); n != len(response) || err != nil { + if n, err := output.Write(response); n != len(response) || err != nil { return fmt.Errorf("write failed: %s", err) } } @@ -476,6 +486,10 @@ func main() { } func do() error { + // In order to exercise pipelining, all output is buffered until a "flush". + outputBuffer = new(bytes.Buffer) + output = outputBuffer + var nums [4 * (1 + maxArgs)]byte var argLengths [maxArgs]uint32 var args [maxArgs][]byte diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/CMakeLists.txt b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/CMakeLists.txt index 267f82c3..7938d390 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/CMakeLists.txt +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/CMakeLists.txt @@ -1,5 +1,3 @@ -include_directories(../../../../include) - if(FIPS) add_executable( modulewrapper @@ -7,8 +5,5 @@ if(FIPS) main.cc modulewrapper.cc ) - - add_dependencies(modulewrapper global_target) - target_link_libraries(modulewrapper crypto) endif() diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/main.cc b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/main.cc index a903361b..546091f3 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/main.cc +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/main.cc @@ -23,6 +23,10 @@ #include "modulewrapper.h" +static bool EqString(bssl::Span cmd, const char *str) { + return cmd.size() == strlen(str) && memcmp(str, cmd.data(), cmd.size()) == 0; +} + int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "--version") == 0) { printf("Built for architecture: "); @@ -33,8 +37,6 @@ int main(int argc, char **argv) { puts("ARM (32-bit)"); #elif defined(OPENSSL_AARCH64) puts("aarch64 (64-bit)"); -#elif defined(OPENSSL_PPC64LE) - puts("PPC64LE (64-bit)"); #else #error "FIPS build not supported on this architecture" #endif @@ -48,10 +50,14 @@ int main(int argc, char **argv) { return 4; } + // modulewrapper buffers responses to the greatest degree allowed in order to + // fully exercise the async handling in acvptool. std::unique_ptr buffer = bssl::acvp::RequestBuffer::New(); const bssl::acvp::ReplyCallback write_reply = std::bind( bssl::acvp::WriteReplyToFd, STDOUT_FILENO, std::placeholders::_1); + const bssl::acvp::ReplyCallback buffer_reply = + std::bind(bssl::acvp::WriteReplyToBuffer, std::placeholders::_1); for (;;) { const bssl::Span> args = @@ -60,12 +66,21 @@ int main(int argc, char **argv) { return 1; } + if (EqString(args[0], "flush")) { + if (!bssl::acvp::FlushBuffer(STDOUT_FILENO)) { + abort(); + } + continue; + } + const bssl::acvp::Handler handler = bssl::acvp::FindHandler(args); if (!handler) { return 2; } - if (!handler(args.subspan(1).data(), write_reply)) { + auto &reply_callback = + EqString(args[0], "getConfig") ? write_reply : buffer_reply; + if (!handler(args.subspan(1).data(), reply_callback)) { const std::string name(reinterpret_cast(args[0].data()), args[0].size()); fprintf(stderr, "\'%s\' operation failed.\n", name.c_str()); diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.cc index 7188029e..0c1359e7 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.cc +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -163,8 +165,51 @@ Span> ParseArgsFromFd(int fd, return Span>(buffer->args, num_args); } +// g_reply_buffer contains buffered replies which will be flushed when acvp +// requests. +static std::vector g_reply_buffer; + +bool WriteReplyToBuffer(const std::vector> &spans) { + if (spans.size() > kMaxArgs) { + abort(); + } + + uint8_t buf[4]; + CRYPTO_store_u32_le(buf, spans.size()); + g_reply_buffer.insert(g_reply_buffer.end(), buf, buf + sizeof(buf)); + for (const auto &span : spans) { + CRYPTO_store_u32_le(buf, span.size()); + g_reply_buffer.insert(g_reply_buffer.end(), buf, buf + sizeof(buf)); + } + for (const auto &span : spans) { + g_reply_buffer.insert(g_reply_buffer.end(), span.begin(), span.end()); + } + + return true; +} + +bool FlushBuffer(int fd) { + size_t done = 0; + + while (done < g_reply_buffer.size()) { + ssize_t n; + do { + n = write(fd, g_reply_buffer.data() + done, g_reply_buffer.size() - done); + } while (n < 0 && errno == EINTR); + + if (n < 0) { + return false; + } + done += static_cast(n); + } + + g_reply_buffer.clear(); + + return true; +} + bool WriteReplyToFd(int fd, const std::vector> &spans) { - if (spans.empty() || spans.size() > kMaxArgs) { + if (spans.size() > kMaxArgs) { abort(); } @@ -225,6 +270,10 @@ bool WriteReplyToFd(int fd, const std::vector> &spans) { static bool GetConfig(const Span args[], ReplyCallback write_reply) { static constexpr char kConfig[] = R"([ + { + "algorithm": "acvptool", + "features": ["batch"] + }, { "algorithm": "SHA2-224", "revision": "1.0", @@ -297,10 +346,10 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "direction": ["encrypt", "decrypt"], "keyLen": [128, 192, 256], "payloadLen": [{ - "min": 0, "max": 256, "increment": 8 + "min": 0, "max": 65536, "increment": 8 }], "aadLen": [{ - "min": 0, "max": 320, "increment": 8 + "min": 0, "max": 65536, "increment": 8 }], "tagLen": [32, 64, 96, 104, 112, 120, 128], "ivLen": [96], @@ -312,10 +361,10 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "direction": ["encrypt", "decrypt"], "keyLen": [128, 192, 256], "payloadLen": [{ - "min": 0, "max": 256, "increment": 8 + "min": 0, "max": 65536, "increment": 8 }], "aadLen": [{ - "min": 0, "max": 320, "increment": 8 + "min": 0, "max": 65536, "increment": 8 }], "tagLen": [32, 64, 96, 104, 112, 120, 128], "ivLen": [96], @@ -334,7 +383,7 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "keyLen": [ 128, 192, 256 ], - "payloadLen": [{"min": 128, "max": 1024, "increment": 64}] + "payloadLen": [{"min": 128, "max": 4096, "increment": 64}] }, { "algorithm": "ACVP-AES-KWP", @@ -363,28 +412,14 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl ], "payloadLen": [{"min": 0, "max": 256, "increment": 8}], "ivLen": [104], - "tagLen": [32], - "aadLen": [{"min": 0, "max": 1024, "increment": 8}] - }, - { - "algorithm": "ACVP-TDES-ECB", - "revision": "1.0", - "direction": ["encrypt", "decrypt"], - "keyLen": [192], - "keyingOption": [1] - }, - { - "algorithm": "ACVP-TDES-CBC", - "revision": "1.0", - "direction": ["encrypt", "decrypt"], - "keyLen": [192], - "keyingOption": [1] + "tagLen": [32, 64], + "aadLen": [{"min": 0, "max": 524288, "increment": 8}] }, { "algorithm": "HMAC-SHA-1", "revision": "1.0", "keyLen": [{ - "min": 8, "max": 2048, "increment": 8 + "min": 8, "max": 524288, "increment": 8 }], "macLen": [{ "min": 32, "max": 160, "increment": 8 @@ -394,7 +429,7 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "algorithm": "HMAC-SHA2-224", "revision": "1.0", "keyLen": [{ - "min": 8, "max": 2048, "increment": 8 + "min": 8, "max": 524288, "increment": 8 }], "macLen": [{ "min": 32, "max": 224, "increment": 8 @@ -404,7 +439,7 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "algorithm": "HMAC-SHA2-256", "revision": "1.0", "keyLen": [{ - "min": 8, "max": 2048, "increment": 8 + "min": 8, "max": 524288, "increment": 8 }], "macLen": [{ "min": 32, "max": 256, "increment": 8 @@ -414,7 +449,7 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "algorithm": "HMAC-SHA2-384", "revision": "1.0", "keyLen": [{ - "min": 8, "max": 2048, "increment": 8 + "min": 8, "max": 524288, "increment": 8 }], "macLen": [{ "min": 32, "max": 384, "increment": 8 @@ -424,17 +459,27 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "algorithm": "HMAC-SHA2-512", "revision": "1.0", "keyLen": [{ - "min": 8, "max": 2048, "increment": 8 + "min": 8, "max": 524288, "increment": 8 }], "macLen": [{ "min": 32, "max": 512, "increment": 8 }] }, + { + "algorithm": "HMAC-SHA2-512/256", + "revision": "1.0", + "keyLen": [{ + "min": 8, "max": 524288, "increment": 8 + }], + "macLen": [{ + "min": 32, "max": 256, "increment": 8 + }] + }, { "algorithm": "ctrDRBG", "revision": "1.0", "predResistanceEnabled": [false], - "reseedImplemented": false, + "reseedImplemented": true, "capabilities": [{ "mode": "AES-256", "derFuncEnabled": false, @@ -487,7 +532,8 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "SHA2-224", "SHA2-256", "SHA2-384", - "SHA2-512" + "SHA2-512", + "SHA2-512/256" ] }] }, @@ -507,7 +553,8 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "SHA2-224", "SHA2-256", "SHA2-384", - "SHA2-512" + "SHA2-512", + "SHA2-512/256" ] }] }, @@ -601,6 +648,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }] }] },{ @@ -619,6 +669,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }] }] },{ @@ -637,6 +690,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }] }] }] @@ -711,6 +767,27 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "hashAlg": "SHA-1" }] }] + },{ + "sigType": "pss", + "properties": [{ + "modulo": 1024, + "hashPair": [{ + "hashAlg": "SHA2-224", + "saltLen": 28 + }, { + "hashAlg": "SHA2-256", + "saltLen": 32 + }, { + "hashAlg": "SHA2-384", + "saltLen": 48 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 + }, { + "hashAlg": "SHA-1", + "saltLen": 20 + }] + }] },{ "sigType": "pss", "properties": [{ @@ -727,6 +804,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }, { "hashAlg": "SHA-1", "saltLen": 20 @@ -748,6 +828,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }, { "hashAlg": "SHA-1", "saltLen": 20 @@ -769,6 +852,9 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl }, { "hashAlg": "SHA2-512", "saltLen": 64 + }, { + "hashAlg": "SHA2-512/256", + "saltLen": 32 }, { "hashAlg": "SHA-1", "saltLen": 20 @@ -784,31 +870,17 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "direction": ["gen", "ver"], "msgLen": [{ "min": 0, - "max": 65536, + "max": 524288, "increment": 8 }], "keyLen": [128, 256], "macLen": [{ - "min": 32, + "min": 8, "max": 128, "increment": 8 }] }] }, - { - "algorithm": "kdf-components", - "revision": "1.0", - "mode": "tls", - "tlsVersion": [ - "v1.0/1.1", - "v1.2" - ], - "hashAlg": [ - "SHA2-256", - "SHA2-384", - "SHA2-512" - ] - }, { "algorithm": "KAS-ECC-SSC", "revision": "Sp800-56Ar3", @@ -847,12 +919,72 @@ static bool GetConfig(const Span args[], ReplyCallback write_repl "FB", "FC" ] + }, + { + "algorithm": "KDA", + "mode": "HKDF", + "revision": "Sp800-56Cr1", + "fixedInfoPattern": "uPartyInfo||vPartyInfo", + "encoding": [ + "concatenation" + ], + "hmacAlg": [ + "SHA2-224", + "SHA2-256", + "SHA2-384", + "SHA2-512", + "SHA2-512/256" + ], + "macSaltMethods": [ + "default", + "random" + ], + "l": 2048, + "z": [ + { + "min": 224, + "max": 65336, + "increment": 8 + } + ] + }, + { + "algorithm": "TLS-v1.2", + "mode": "KDF", + "revision": "RFC7627", + "hashAlg": [ + "SHA2-256", + "SHA2-384", + "SHA2-512" + ] + }, + { + "algorithm": "TLS-v1.3", + "mode": "KDF", + "revision": "RFC8446", + "hmacAlg": [ + "SHA2-256", + "SHA2-384" + ], + "runningMode": [ + "DHE", + "PSK", + "PSK-DHE" + ] } ])"; return write_reply({Span( reinterpret_cast(kConfig), sizeof(kConfig) - 1)}); } +static bool Flush(const Span args[], ReplyCallback write_reply) { + fprintf( + stderr, + "modulewrapper code processed a `flush` command but this must be handled " + "at a higher-level. See the example in main.cc in BoringSSL\n"); + abort(); +} + template static bool Hash(const Span args[], ReplyCallback write_reply) { @@ -1059,10 +1191,21 @@ static bool AESCCMSetup(EVP_AEAD_CTX *ctx, Span tag_len_span, return false; } memcpy(&tag_len_32, tag_len_span.data(), sizeof(tag_len_32)); - if (tag_len_32 != 4) { - LOG_ERROR("AES-CCM only supports 4-byte tags, but %u was requested\n", - static_cast(tag_len_32)); - return false; + const EVP_AEAD *aead; + switch (tag_len_32) { + case 4: + aead = EVP_aead_aes_128_ccm_bluetooth(); + break; + + case 8: + aead = EVP_aead_aes_128_ccm_bluetooth_8(); + break; + + default: + LOG_ERROR( + "AES-CCM only supports 4- and 8-byte tags, but %u was requested\n", + static_cast(tag_len_32)); + return false; } if (key.size() != 16) { @@ -1071,8 +1214,8 @@ static bool AESCCMSetup(EVP_AEAD_CTX *ctx, Span tag_len_span, return false; } - if (!EVP_AEAD_CTX_init(ctx, EVP_aead_aes_128_ccm_bluetooth(), key.data(), - key.size(), tag_len_32, nullptr)) { + if (!EVP_AEAD_CTX_init(ctx, aead, key.data(), key.size(), tag_len_32, + nullptr)) { LOG_ERROR("Failed to setup AES-CCM with tag length %u\n", static_cast(tag_len_32)); return false; @@ -1382,17 +1525,98 @@ static bool HMAC(const Span args[], ReplyCallback write_reply) { return write_reply({Span(digest, digest_len)}); } +template +static bool HKDF(const Span args[], ReplyCallback write_reply) { + const EVP_MD *const md = HashFunc(); + const auto key = args[0]; + const auto salt = args[1]; + const auto info = args[2]; + const auto out_len_bytes = args[3]; + + if (out_len_bytes.size() != sizeof(uint32_t)) { + return false; + } + const uint32_t out_len = CRYPTO_load_u32_le(out_len_bytes.data()); + if (out_len > (1 << 24)) { + return false; + } + + std::vector out(out_len); + if (!::HKDF(out.data(), out_len, md, key.data(), key.size(), salt.data(), + salt.size(), info.data(), info.size())) { + return false; + } + return write_reply({out}); +} + +template +static bool HKDFExtract(const Span args[], + ReplyCallback write_reply) { + const EVP_MD *const md = HashFunc(); + const auto secret = args[0]; + const auto salt = args[1]; + + std::vector out(EVP_MD_size(md)); + size_t out_len; + if (!HKDF_extract(out.data(), &out_len, md, secret.data(), secret.size(), + salt.data(), salt.size())) { + return false; + } + assert(out_len == out.size()); + return write_reply({out}); +} + +template +static bool HKDFExpandLabel(const Span args[], + ReplyCallback write_reply) { + const EVP_MD *const md = HashFunc(); + const auto out_len_bytes = args[0]; + const auto secret = args[1]; + const auto label = args[2]; + const auto hash = args[3]; + + if (out_len_bytes.size() != sizeof(uint32_t)) { + return false; + } + const uint32_t out_len = CRYPTO_load_u32_le(out_len_bytes.data()); + if (out_len > (1 << 24)) { + return false; + } + + std::vector out(out_len); + if (!CRYPTO_tls13_hkdf_expand_label(out.data(), out_len, md, secret.data(), + secret.size(), label.data(), label.size(), + hash.data(), hash.size())) { + return false; + } + return write_reply({out}); +} + +template static bool DRBG(const Span args[], ReplyCallback write_reply) { const auto out_len_bytes = args[0]; const auto entropy = args[1]; const auto personalisation = args[2]; - const auto additional_data1 = args[3]; - const auto additional_data2 = args[4]; - const auto nonce = args[5]; + + Span reseed_additional_data, reseed_entropy, additional_data1, + additional_data2, nonce; + if (!WithReseed) { + additional_data1 = args[3]; + additional_data2 = args[4]; + nonce = args[5]; + } else { + reseed_additional_data = args[3]; + reseed_entropy = args[4]; + additional_data1 = args[5]; + additional_data2 = args[6]; + nonce = args[7]; + } uint32_t out_len; if (out_len_bytes.size() != sizeof(out_len) || entropy.size() != CTR_DRBG_ENTROPY_LEN || + (!reseed_entropy.empty() && + reseed_entropy.size() != CTR_DRBG_ENTROPY_LEN) || // nonces are not supported nonce.size() != 0) { return false; @@ -1406,6 +1630,10 @@ static bool DRBG(const Span args[], ReplyCallback write_reply) { CTR_DRBG_STATE drbg; if (!CTR_DRBG_init(&drbg, entropy.data(), personalisation.data(), personalisation.size()) || + (!reseed_entropy.empty() && + !CTR_DRBG_reseed(&drbg, reseed_entropy.data(), + reseed_additional_data.data(), + reseed_additional_data.size())) || !CTR_DRBG_generate(&drbg, out.data(), out_len, additional_data1.data(), additional_data1.size()) || !CTR_DRBG_generate(&drbg, out.data(), out_len, additional_data2.data(), @@ -1491,12 +1719,8 @@ static bool ECDSAKeyVer(const Span args[], ReplyCallback write_re bssl::UniquePtr x(BytesToBIGNUM(args[1])); bssl::UniquePtr y(BytesToBIGNUM(args[2])); - bssl::UniquePtr point(EC_POINT_new(EC_KEY_get0_group(key.get()))); uint8_t reply[1]; - if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(key.get()), - point.get(), x.get(), y.get(), - /*ctx=*/nullptr) || - !EC_KEY_set_public_key(key.get(), point.get()) || + if (!EC_KEY_set_public_key_affine_coordinates(key.get(), x.get(), y.get()) || !EC_KEY_check_fips(key.get())) { reply[0] = 0; } else { @@ -1517,6 +1741,8 @@ static const EVP_MD *HashFromName(Span name) { return EVP_sha384(); } else if (StringEq(name, "SHA2-512")) { return EVP_sha512(); + } else if (StringEq(name, "SHA2-512/256")) { + return EVP_sha512_256(); } else { return nullptr; } @@ -1567,12 +1793,8 @@ static bool ECDSASigVer(const Span args[], ReplyCallback write_re return false; } - bssl::UniquePtr point(EC_POINT_new(EC_KEY_get0_group(key.get()))); uint8_t reply[1]; - if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(key.get()), - point.get(), x.get(), y.get(), - /*ctx=*/nullptr) || - !EC_KEY_set_public_key(key.get(), point.get()) || + if (!EC_KEY_set_public_key_affine_coordinates(key.get(), x.get(), y.get()) || !EC_KEY_check_fips(key.get()) || !ECDSA_do_verify(digest, digest_len, &sig, key.get())) { reply[0] = 0; @@ -1880,6 +2102,7 @@ static constexpr struct { bool (*handler)(const Span args[], ReplyCallback write_reply); } kFunctions[] = { {"getConfig", 0, GetConfig}, + {"flush", 0, Flush}, {"SHA-1", 1, Hash}, {"SHA2-224", 1, Hash}, {"SHA2-256", 1, Hash}, @@ -1910,12 +2133,23 @@ static constexpr struct { {"3DES-ECB/decrypt", 3, TDES}, {"3DES-CBC/encrypt", 4, TDES_CBC}, {"3DES-CBC/decrypt", 4, TDES_CBC}, + {"HKDF/SHA2-224", 4, HKDF}, + {"HKDF/SHA2-256", 4, HKDF}, + {"HKDF/SHA2-384", 4, HKDF}, + {"HKDF/SHA2-512", 4, HKDF}, + {"HKDF/SHA2-512/256", 4, HKDF}, + {"HKDFExpandLabel/SHA2-256", 4, HKDFExpandLabel}, + {"HKDFExpandLabel/SHA2-384", 4, HKDFExpandLabel}, + {"HKDFExtract/SHA2-256", 2, HKDFExtract}, + {"HKDFExtract/SHA2-384", 2, HKDFExtract}, {"HMAC-SHA-1", 2, HMAC}, {"HMAC-SHA2-224", 2, HMAC}, {"HMAC-SHA2-256", 2, HMAC}, {"HMAC-SHA2-384", 2, HMAC}, {"HMAC-SHA2-512", 2, HMAC}, - {"ctrDRBG/AES-256", 6, DRBG}, + {"HMAC-SHA2-512/256", 2, HMAC}, + {"ctrDRBG/AES-256", 6, DRBG}, + {"ctrDRBG-reseed/AES-256", 8, DRBG}, {"ECDSA/keyGen", 1, ECDSAKeyGen}, {"ECDSA/keyVer", 3, ECDSAKeyVer}, {"ECDSA/sigGen", 4, ECDSASigGen}, @@ -1932,6 +2166,7 @@ static constexpr struct { {"RSA/sigGen/SHA2-256/pss", 2, RSASigGen}, {"RSA/sigGen/SHA2-384/pss", 2, RSASigGen}, {"RSA/sigGen/SHA2-512/pss", 2, RSASigGen}, + {"RSA/sigGen/SHA2-512/256/pss", 2, RSASigGen}, {"RSA/sigGen/SHA-1/pss", 2, RSASigGen}, {"RSA/sigVer/SHA2-224/pkcs1v1.5", 4, RSASigVer}, {"RSA/sigVer/SHA2-256/pkcs1v1.5", 4, RSASigVer}, @@ -1942,8 +2177,8 @@ static constexpr struct { {"RSA/sigVer/SHA2-256/pss", 4, RSASigVer}, {"RSA/sigVer/SHA2-384/pss", 4, RSASigVer}, {"RSA/sigVer/SHA2-512/pss", 4, RSASigVer}, + {"RSA/sigVer/SHA2-512/256/pss", 4, RSASigVer}, {"RSA/sigVer/SHA-1/pss", 4, RSASigVer}, - {"TLSKDF/1.0/SHA-1", 5, TLSKDF}, {"TLSKDF/1.2/SHA2-256", 5, TLSKDF}, {"TLSKDF/1.2/SHA2-384", 5, TLSKDF}, {"TLSKDF/1.2/SHA2-512", 5, TLSKDF}, diff --git a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.h b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.h index 0472800f..8a5bdb82 100644 --- a/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.h +++ b/third_party/boringssl/kit/src/util/fipstools/acvp/modulewrapper/modulewrapper.h @@ -26,7 +26,7 @@ namespace acvp { // kMaxArgs is the maximum number of arguments (including the function name) // that an ACVP request can contain. -constexpr size_t kMaxArgs = 8; +constexpr size_t kMaxArgs = 9; // kMaxNameLength is the maximum length of a function name in an ACVP request. constexpr size_t kMaxNameLength = 30; @@ -49,6 +49,13 @@ Span> ParseArgsFromFd(int fd, RequestBuffer *buffer); // WriteReplyToFd writes a reply to the given file descriptor. bool WriteReplyToFd(int fd, const std::vector> &spans); +// WriteReplyToBuffer writes a reply to an internal buffer that may be flushed +// with |FlushBuffer|. +bool WriteReplyToBuffer(const std::vector> &spans); + +// FlushBuffer writes the buffer that |WriteReplyToBuffer| fills, to |fd|. +bool FlushBuffer(int fd); + // ReplyCallback is the type of a callback that writes a reply to an ACVP // request. typedef std::function> &)> diff --git a/third_party/boringssl/kit/src/util/fipstools/break-hash.go b/third_party/boringssl/kit/src/util/fipstools/break-hash.go index 8c817d8d..a4ab8083 100644 --- a/third_party/boringssl/kit/src/util/fipstools/break-hash.go +++ b/third_party/boringssl/kit/src/util/fipstools/break-hash.go @@ -10,7 +10,9 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +//go:build ignore // break-hash parses an ELF binary containing the FIPS module and corrupts the // first byte of the module. This should cause the integrity check to fail. @@ -24,12 +26,11 @@ import ( "encoding/hex" "errors" "fmt" - "io/ioutil" "os" ) func do(outPath, inPath string) error { - objectBytes, err := ioutil.ReadFile(inPath) + objectBytes, err := os.ReadFile(inPath) if err != nil { return err } @@ -131,7 +132,7 @@ func do(outPath, inPath string) error { fmt.Printf("\nHash of module was: %x\n", hashWas) fmt.Printf("Hash of corrupted module is: %x\n", newHash) - return ioutil.WriteFile(outPath, objectBytes, 0755) + return os.WriteFile(outPath, objectBytes, 0755) } func main() { diff --git a/third_party/boringssl/kit/src/util/fipstools/break-kat.go b/third_party/boringssl/kit/src/util/fipstools/break-kat.go new file mode 100644 index 00000000..e4d323ab --- /dev/null +++ b/third_party/boringssl/kit/src/util/fipstools/break-kat.go @@ -0,0 +1,102 @@ +//go:build + +// break-kat corrupts a known-answer-test input in a binary and writes the +// corrupted binary to stdout. This is used to demonstrate that the KATs in the +// binary notice the error. +package main + +import ( + "bytes" + "encoding/hex" + "flag" + "fmt" + "os" + "sort" +) + +var ( + kats = map[string]string{ + "HMAC-SHA-256": "dad91293dfcf2a7c8ecd13fe353fa75b", + "AES-CBC-encrypt": "078609a6c5ac2544699adf682fa377f9be8ab6aef563e8c56a36b84f557fadd3", + "AES-CBC-decrypt": "347aa5a024b28257b36510be583d4f47adb7bbeedc6005bbbd0d0a9f06bb7b10", + "AES-GCM-encrypt": "8fcc4099808e75caaff582898848a88d808b55ab4e9370797d940be8cc1d7884", + "AES-GCM-decrypt": "35f3058f875760ff09d3120f70c4bc9ed7a86872e13452202176f7371ae04faae1dd391920f5d13953d896785994823c", + "DRBG": "c4da0740d505f1ee280b95e58c4931ac6de846a0152fbb4a3f174cf4787a4f1a40c2b50babe14aae530be5886d910a27", + "DRBG-reseed": "c7161ca36c2309b716e9859bb96c6d49bdc8352103a18cd24ef42ec97ef46bf446eb1a4576c186e9351803763a7912fe", + "HKDF": "68678504b9b3add17d5967a1a7bd37993fd8a33ce7303071f39c096d1635b3c9", + "SHA-1": "132fd9bad5c1826263bafbb699f707a5", + "SHA-256": "ff3b857da7236a2baa0f396b51522217", + "SHA-512": "212512f8d2ad8322781c6c4d69a9daa1", + "TLS-KDF": "abc3657b094c7628a0b282996fe75a75f4984fd94d4ecc2fcf53a2c469a3f731", + "TLS13-KDF": "024a0d80f357f2499a1244dac26dab66fc13ed85fca71dace146211119525874", + "RSA-sign": "d2b56e53306f720d7929d8708bf46f1c22300305582b115bedcac722d8aa5ab2", + "RSA-verify": "abe2cbc13d6bd39d48db5334ddbf8d070a93bdcb104e2cc5d0ee486ee295f6b31bda126c41890b98b73e70e6b65d82f95c663121755a90744c8d1c21148a1960be0eca446e9ff497f1345c537ef8119b9a4398e95c5c6de2b1c955905c5299d8ce7a3b6ab76380d9babdd15f610237e1f3f2aa1c1f1e770b62fbb596381b2ebdd77ecef9c90d4c92f7b6b05fed2936285fa94826e62055322a33b6f04c74ce69e5d8d737fb838b79d2d48e3daf71387531882531a95ac964d02ea413bf85952982bbc089527daff5b845c9a0f4d14ef1956d9c3acae882d12da66da0f35794f5ee32232333517db9315232a183b991654dbea41615345c885325926744a53915", + "ECDSA-sign": "1e35930be860d0942ca7bbd6f6ded87f157e4de24f81ed4b875c0e018e89a81f", + "ECDSA-verify": "6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c2d36e5799790bfbe2183d33e96f3c51f6a232f2a24488c8e5f64c37ea2cf0529", + "Z-computation": "e7604491269afb5b102d6ea52cb59feb70aede6ce3bfb3e0105485abd861d77b", + "FFDH": "a14f8ad36be37b18b8f35864392f150ab7ee22c47e1870052a3f17918274af18aaeaf4cf6aacfde96c9d586eb7ebaff6b03fe3b79a8e2ff9dd6df34caaf2ac70fd3771d026b41a561ee90e4337d0575f8a0bd160c868e7e3cef88aa1d88448b1e4742ba11480a9f8a8b737347c408d74a7d57598c48875629df0c85327a124ddec1ad50cd597a985588434ce19c6f044a1696b5f244b899b7e77d4f6f20213ae8eb15d37eb8e67e6c8bdbc4fd6e17426283da96f23a897b210058c7c70fb126a5bf606dbeb1a6d5cca04184c4e95c2e8a70f50f5c1eabd066bd79c180456316ac02d366eb3b0e7ba82fb70dcbd737ca55734579dd250fffa8e0584be99d32b35", + } + + listTests = flag.Bool("list-tests", false, "List known test values and exit") +) + +func main() { + flag.Parse() + + if *listTests { + for _, kat := range sortedKATs() { + fmt.Println(kat) + } + os.Exit(0) + } + + if flag.NArg() != 2 || kats[flag.Arg(1)] == "" { + fmt.Fprintln(os.Stderr, "Usage: break-kat > output") + fmt.Fprintln(os.Stderr, "Possible values for :") + for _, kat := range sortedKATs() { + fmt.Fprintln(os.Stderr, " ", kat) + } + os.Exit(1) + } + + inPath := flag.Arg(0) + test := flag.Arg(1) + testInputValue, err := hex.DecodeString(kats[test]) + if err != nil { + panic("invalid kat data: " + err.Error()) + } + + binaryContents, err := os.ReadFile(inPath) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + + i := bytes.Index(binaryContents, testInputValue) + if i < 0 { + fmt.Fprintln(os.Stderr, "Expected test input value was not found in binary.") + os.Exit(3) + } + + // Zero out the entire value because the compiler may produce code + // where parts of the value are embedded in the instructions. + for j := range testInputValue { + binaryContents[i+j] = 0 + } + + if bytes.Index(binaryContents, testInputValue) >= 0 { + fmt.Fprintln(os.Stderr, "Test input value was still found after erasing it. Second copy?") + os.Exit(4) + } + + os.Stdout.Write(binaryContents) +} + +func sortedKATs() []string { + var ret []string + for kat := range kats { + ret = append(ret, kat) + } + sort.Strings(ret) + return ret +} diff --git a/third_party/boringssl/kit/src/util/fipstools/break-tests-android.sh b/third_party/boringssl/kit/src/util/fipstools/break-tests-android.sh deleted file mode 100644 index efb166ea..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/break-tests-android.sh +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2019, Google Inc. -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -# This script exists to exercise breaking each of the FIPS tests on an Android -# device. Since, on Android, BoringCrypto exists in both 32- and 64-bit -# versions, the first argument must be either "32" or "64" to select which is -# being tested. The Android source tree must have been setup (with "lunch") for -# a matching build configuration before using this script to build the -# binaries. (Although it'll fail non-silently if there's a mismatch.) -# -# Since each test needs the FIPS module to be compiled differently, and that -# can take a long time, this script is run twice: once with "build" as the -# second argument to run the builds, and then with "run" as the second argument -# to run each test. -# -# Run it with /bin/bash, not /bin/sh, otherwise "read" may fail. -# -# In order to reconfigure the build for each test, it needs to set a define. It -# does so by rewriting a template in external/boringssl/Android.bp and you must -# add the template value before doing the builds. To do so, insert -# -DBORINGSSL_FIPS_BREAK_XXX=1 in the cflags list for the module, probably by -# putting it in the "boringssl_flags" stanza. - -set -x -set -e - -if [ ! -f external/boringssl/Android.bp ]; then - echo "Must be run from the top-level of an Android source tree." - exit 1 -fi - -. build/envsetup.sh - -TESTS="NONE ECDSA_PWCT CRNG RSA_PWCT AES_CBC AES_GCM DES SHA_1 SHA_256 SHA_512 RSA_SIG DRBG ECDSA_SIG Z_COMPUTATION TLS_KDF FFC_DH" - -if [ "x$1" = "x32" ]; then - lib="lib" - bits="32" -elif [ "x$1" = "x64" ] ; then - lib="lib64" - bits="64" -else - echo "First argument must be 32 or 64" - exit 1 -fi - -if [ "x$2" = "xbuild" ]; then - if ! grep -q DBORINGSSL_FIPS_BREAK_XXX=1 external/boringssl/Android.bp; then - echo "Missing DBORINGSSL_FIPS_BREAK_XXX in external/boringssl/Android.bp. Edit the file and insert -DBORINGSSL_FIPS_BREAK_XXX=1 in the cflags for the FIPS module" - exit 1 - fi - - printf "\\x1b[1mBuilding modules\\x1b[0m\n" - for test in $TESTS; do - printf "\\x1b[1mBuilding for ${test}\\x1b[0m\n" - cp external/boringssl/Android.bp external/boringssl/Android.bp.orig - sed -i -e "s/DBORINGSSL_FIPS_BREAK_XXX/DBORINGSSL_FIPS_BREAK_${test}/" external/boringssl/Android.bp - m test_fips - dir=test-${bits}-${test} - rm -Rf $dir - mkdir $dir - cp ${ANDROID_PRODUCT_OUT}/system/${lib}/libcrypto.so $dir - cp ${ANDROID_PRODUCT_OUT}/system/bin/test_fips $dir - if [ $bits = "32" ] ; then - if ! file ${dir}/test_fips | grep -q "32-bit" ; then - echo "32-bit build requested but binaries don't appear to be 32-bit:" - file ${dir}/test_fips - exit 1 - fi - else - if ! file ${dir}/test_fips | grep -q "64-bit" ; then - echo "64-bit build requested but binaries don't appear to be 64-bit:" - file ${dir}/test_fips - exit 1 - fi - fi - cp external/boringssl/Android.bp.orig external/boringssl/Android.bp - done -elif [ "x$2" = "xrun" ]; then - printf "\\x1b[1mTesting\\x1b[0m\n" - for test in $TESTS; do - dir=test-${bits}-${test} - if [ ! '(' -d ${dir} -a -f ${dir}/test_fips -a -f ${dir}/libcrypto.so ')' ] ; then - echo "Build directory ${dir} is missing or is missing files" - exit 1 - fi - adb push ${dir}/* /data/local/tmp - printf "\\x1b[1mTesting ${test}\\x1b[0m\n" - adb shell -n -t -x LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/test_fips - read - done - - printf "\\x1b[1mTesting integrity}\\x1b[0m\n" - src=test-${bits}-NONE - dir=test-${bits}-INT - rm -Rf $dir - mkdir $dir - go run external/boringssl/src/util/fipstools/break-hash.go ${src}/libcrypto.so ${dir}/libcrypto.so - cp ${src}/test_fips $dir - adb push ${dir}/* /data/local/tmp - adb shell -n -t -x LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/test_fips - read -else - echo "Second argument must be build or run" - exit 1 -fi diff --git a/third_party/boringssl/kit/src/util/fipstools/break-tests.sh b/third_party/boringssl/kit/src/util/fipstools/break-tests.sh index 84c24eef..695b6293 100644 --- a/third_party/boringssl/kit/src/util/fipstools/break-tests.sh +++ b/third_party/boringssl/kit/src/util/fipstools/break-tests.sh @@ -1,4 +1,4 @@ -# Copyright (c) 2018, Google Inc. +# Copyright (c) 2022, Google Inc. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -10,44 +10,182 @@ # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# This script exists to exercise breaking each of the FIPS tests. It builds -# BoringSSL differently for each test and that can take a long time. Thus it's -# run twice: once, from a BoringSSL source tree, with "build" as the sole -# argument to run the builds, and then (from the same location) with no -# arguments to run each script. +# This script runs test_fips repeatedly with different FIPS tests broken. It is +# intended to be observed to demonstrate that the various tests are working and +# thus pauses for a keystroke between tests. # -# Run it with /bin/bash, not /bin/sh, otherwise "read" may fail. +# Runs in either device mode (on an attached Android device) or in a locally built +# BoringSSL checkout. +# +# On Android static binaries are not built using FIPS mode, so in device mode each +# test makes changes to libcrypto.so rather than the test binary, test_fips. -set -x +set -e -TESTS="NONE ECDSA_PWCT CRNG RSA_PWCT AES_CBC AES_GCM DES SHA_1 SHA_256 SHA_512 RSA_SIG DRBG ECDSA_SIG Z_COMPUTATION TLS_KDF FFC_DH" +die () { + echo "ERROR: $@" + exit 1 +} -if [ "x$1" = "xbuild" ]; then - for test in $TESTS; do - rm -Rf build-$test - mkdir build-$test - pushd build-$test - cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchain -DFIPS=1 -DFIPS_BREAK_TEST=${test} -DCMAKE_BUILD_TYPE=Release .. - ninja test_fips - popd - done +usage() { + echo "USAGE: $0 [local|device]" + exit 1 +} - exit 0 +inferred_mode() { + # Try and infer local or device mode based on makefiles and artifacts. + if [ -f Android.bp -o -f external/boringssl/Android.bp ]; then + echo device + elif [ -f CMakeLists.txt -a -d build/crypto -a -d build/ssl ]; then + echo local + else + echo "Unable to infer mode, please specify on the command line." + usage + fi +} + +# Prefer mode from command line if present. +case "$1" in + local|device) + MODE=$1 + ;; + + "") + MODE=`inferred_mode` + ;; + + *) + usage + ;; +esac + +check_directory() { + test -d "$1" || die "Directory $1 not found." +} + +check_file() { + test -f "$1" || die "File $1 not found." +} + +run_test_locally() { + eval "$1" || true +} + +run_test_on_device() { + EXECFILE="$1" + LIBRARY="$2" + adb shell rm -rf "$DEVICE_TMP" + adb shell mkdir -p "$DEVICE_TMP" + adb push "$EXECFILE" "$DEVICE_TMP" > /dev/null + EXECPATH=$(basename "$EXECFILE") + adb push "$LIBRARY" "$DEVICE_TMP" > /dev/null + adb shell "LD_LIBRARY_PATH=$DEVICE_TMP" "$DEVICE_TMP/$EXECPATH" || true +} + +device_integrity_break_test() { + go run "$BORINGSSL/util/fipstools/break-hash.go" "$LIBCRYPTO_BIN" ./libcrypto.so + $RUN "$TEST_FIPS_BIN" ./libcrypto.so + rm ./libcrypto.so +} + +local_integrity_break_test() { + go run $BORINGSSL/util/fipstools/break-hash.go "$TEST_FIPS_BIN" ./break-bin + chmod u+x ./break-bin + $RUN ./break-bin + rm ./break-bin +} + +local_runtime_break_test() { + BORINGSSL_FIPS_BREAK_TEST=$1 "$RUN" "$TEST_FIPS_BREAK_BIN" +} + +# TODO(prb): make break-hash and break-kat take similar arguments to save having +# separate functions for each. +device_kat_break_test() { + KAT="$1" + go run "$BORINGSSL/util/fipstools/break-kat.go" "$LIBCRYPTO_BREAK_BIN" "$KAT" > ./libcrypto.so + $RUN "$TEST_FIPS_BIN" ./libcrypto.so + rm ./libcrypto.so +} + +local_kat_break_test() { + KAT="$1" + go run "$BORINGSSL/util/fipstools/break-kat.go" "$TEST_FIPS_BREAK_BIN" "$KAT" > ./break-bin + chmod u+x ./break-bin + $RUN ./break-bin + rm ./break-bin +} + +pause () { + echo -n "Press " + read +} + +if [ "$MODE" = "local" ]; then + TEST_FIPS_BIN=${TEST_FIPS_BIN:-build/util/fipstools/test_fips} + TEST_FIPS_BREAK_BIN=${TEST_FIPS_BREAK_BIN:-./test_fips_break} + check_file "$TEST_FIPS_BIN" + check_file "$TEST_FIPS_BREAK_BIN" + + BORINGSSL=. + RUN=run_test_locally + BREAK_TEST=local_break_test + INTEGRITY_BREAK_TEST=local_integrity_break_test + KAT_BREAK_TEST=local_kat_break_test + RUNTIME_BREAK_TEST=local_runtime_break_test + if [ ! -f "$TEST_FIPS_BIN" ]; then + echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a" + echo "BoringSSL checkout and ensure that BoringSSL has been built in" + echo "build/ with -DFIPS_BREAK_TEST=TESTS passed to CMake." + exit 1 + fi +else # Device mode + test "$ANDROID_BUILD_TOP" || die "'lunch aosp_arm64-eng' first" + check_directory "$ANDROID_PRODUCT_OUT" + + TEST_FIPS_BIN="$ANDROID_PRODUCT_OUT/system/bin/test_fips" + check_file "$TEST_FIPS_BIN" + LIBCRYPTO_BIN="$ANDROID_PRODUCT_OUT/system/lib64/libcrypto.so" + LIBCRYPTO_BREAK_BIN="libcrypto.so" + check_file "$LIBCRYPTO_BIN" + check_file "$LIBCRYPTO_BREAK_BIN" + + test "$ANDROID_SERIAL" || die "ANDROID_SERIAL not set" + DEVICE_TMP=/data/local/tmp + + BORINGSSL="$ANDROID_BUILD_TOP/external/boringssl/src" + RUN=run_test_on_device + INTEGRITY_BREAK_TEST=device_integrity_break_test + KAT_BREAK_TEST=device_kat_break_test fi -for test in $TESTS; do - pushd build-$test - printf "\n\n\\x1b[1m$test\\x1b[0m\n" - ./util/fipstools/cavp/test_fips - echo "Waiting for keypress..." - read - popd + +KATS=$(go run "$BORINGSSL/util/fipstools/break-kat.go" --list-tests) + +echo -e '\033[1mNormal output\033[0m' +$RUN "$TEST_FIPS_BIN" "$LIBCRYPTO_BIN" +pause + +echo +echo -e '\033[1mIntegrity test failure\033[0m' +$INTEGRITY_BREAK_TEST +pause + +for kat in $KATS; do + echo + echo -e "\033[1mKAT failure ${kat}\033[0m" + $KAT_BREAK_TEST $kat + pause done -pushd build-NONE -printf "\\x1b[1mIntegrity\\x1b[0m\n" -go run ../util/fipstools/break-hash.go ./util/fipstools/cavp/test_fips ./util/fipstools/cavp/test_fips_broken -./util/fipstools/cavp/test_fips_broken -popd +if [ "$MODE" = "local" ]; then + # TODO(prb): add support for Android devices. + for runtime_test in ECDSA_PWCT RSA_PWCT CRNG; do + echo + echo -e "\033[1m${runtime_test} failure\033[0m" + $RUNTIME_BREAK_TEST ${runtime_test} + pause + done +fi diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/CMakeLists.txt b/third_party/boringssl/kit/src/util/fipstools/cavp/CMakeLists.txt deleted file mode 100644 index a50c9ab8..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -include_directories(../../../include) - -if(FIPS) - add_executable( - cavp - - cavp_main.cc - - cavp_aes_gcm_test.cc - cavp_aes_test.cc - cavp_ctr_drbg_test.cc - cavp_ecdsa2_keypair_test.cc - cavp_ecdsa2_pkv_test.cc - cavp_ecdsa2_siggen_test.cc - cavp_ecdsa2_sigver_test.cc - cavp_hmac_test.cc - cavp_kas_test.cc - cavp_keywrap_test.cc - cavp_rsa2_keygen_test.cc - cavp_rsa2_siggen_test.cc - cavp_rsa2_sigver_test.cc - cavp_sha_monte_test.cc - cavp_sha_test.cc - cavp_tdes_test.cc - cavp_tlskdf_test.cc - - cavp_test_util.cc - ) - - add_dependencies(cavp global_target) - - add_executable( - test_fips - - test_fips.c - ) - - add_dependencies(test_fips global_target) - - target_link_libraries(cavp test_support_lib crypto) - target_link_libraries(test_fips test_support_lib crypto) -endif() diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_gcm_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_gcm_test.cc deleted file mode 100644 index 6ee991d0..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_gcm_test.cc +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_aes_gcm_test processes a NIST CAVP AES GCM test vector request file and -// emits the corresponding response. - -#include - -#include -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - const EVP_AEAD *aead; -}; - -} - -static const EVP_AEAD *GetAEAD(const std::string &name, const bool enc) { - if (name == "aes-128-gcm") { - return EVP_aead_aes_128_gcm(); - } else if (name == "aes-192-gcm") { - return EVP_aead_aes_192_gcm(); - } else if (name == "aes-256-gcm") { - return EVP_aead_aes_256_gcm(); - } - return nullptr; -} - -static bool TestAEADEncrypt(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - std::string key_len_str, iv_len_str, pt_len_str, aad_len_str, tag_len_str; - if (!t->GetInstruction(&key_len_str, "Keylen") || - !t->GetInstruction(&iv_len_str, "IVlen") || - !t->GetInstruction(&pt_len_str, "PTlen") || - !t->GetInstruction(&aad_len_str, "AADlen") || - !t->GetInstruction(&tag_len_str, "Taglen")) { - return false; - } - - std::string count; - std::vector key, iv, pt, aad, tag, ct; - if (!t->GetAttribute(&count, "Count") || - !t->GetBytes(&key, "Key") || - !t->GetBytes(&iv, "IV") || - !t->GetBytes(&pt, "PT") || - !t->GetBytes(&aad, "AAD") || - key.size() * 8 != strtoul(key_len_str.c_str(), nullptr, 0) || - iv.size() * 8 != strtoul(iv_len_str.c_str(), nullptr, 0) || - pt.size() * 8 != strtoul(pt_len_str.c_str(), nullptr, 0) || - aad.size() * 8 != strtoul(aad_len_str.c_str(), nullptr, 0) || - iv.size() != 12) { - return false; - } - - const size_t tag_len = strtoul(tag_len_str.c_str(), nullptr, 0) / 8; - if (!AEADEncrypt(ctx->aead, &ct, &tag, tag_len, key, pt, aad, iv)) { - return false; - } - printf("%s", t->CurrentTestToString().c_str()); - printf("CT = %s\r\n", EncodeHex(ct).c_str()); - printf("Tag = %s\r\n\r\n", EncodeHex(tag).c_str()); - - return true; -} - -static bool TestAEADDecrypt(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - std::string key_len, iv_len, pt_len_str, aad_len_str, tag_len; - if (!t->GetInstruction(&key_len, "Keylen") || - !t->GetInstruction(&iv_len, "IVlen") || - !t->GetInstruction(&pt_len_str, "PTlen") || - !t->GetInstruction(&aad_len_str, "AADlen") || - !t->GetInstruction(&tag_len, "Taglen")) { - t->PrintLine("Invalid instruction block."); - return false; - } - size_t aad_len = strtoul(aad_len_str.c_str(), nullptr, 0) / 8; - size_t pt_len = strtoul(pt_len_str.c_str(), nullptr, 0) / 8; - - std::string count; - std::vector key, iv, ct, aad, tag, pt; - if (!t->GetAttribute(&count, "Count") || - !t->GetBytes(&key, "Key") || - !t->GetBytes(&aad, "AAD") || - !t->GetBytes(&tag, "Tag") || - !t->GetBytes(&iv, "IV") || - !t->GetBytes(&ct, "CT") || - key.size() * 8 != strtoul(key_len.c_str(), nullptr, 0) || - iv.size() * 8 != strtoul(iv_len.c_str(), nullptr, 0) || - ct.size() != pt_len || - aad.size() != aad_len || - tag.size() * 8 != strtoul(tag_len.c_str(), nullptr, 0)) { - t->PrintLine("Invalid test case"); - return false; - } - - printf("%s", t->CurrentTestToString().c_str()); - bool aead_result = - AEADDecrypt(ctx->aead, &pt, pt_len, key, aad, ct, tag, iv); - if (aead_result) { - printf("PT = %s\r\n\r\n", EncodeHex(pt).c_str()); - } else { - printf("FAIL\r\n\r\n"); - } - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s (enc|dec) \n", arg); - return 1; -} - -int cavp_aes_gcm_test_main(int argc, char **argv) { - if (argc != 4) { - return usage(argv[0]); - } - - const std::string mode(argv[1]); - bool (*test_fn)(FileTest * t, void *arg); - if (mode == "enc") { - test_fn = &TestAEADEncrypt; - } else if (mode == "dec") { - test_fn = &TestAEADDecrypt; - } else { - return usage(argv[0]); - } - - const EVP_AEAD *aead = GetAEAD(argv[2], mode == "enc"); - if (aead == nullptr) { - fprintf(stderr, "invalid aead: %s\n", argv[2]); - return 1; - } - - TestCtx ctx = {aead}; - - FileTest::Options opts; - opts.path = argv[3]; - opts.callback = test_fn; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_test.cc deleted file mode 100644 index d1f49b4b..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_aes_test.cc +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_aes_test processes a NIST CAVP AES test vector request file and emits -// the corresponding response. - -#include - -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - const EVP_CIPHER *cipher; - bool has_iv; - enum Mode { - kKAT, // Known Answer Test - kMCT, // Monte Carlo Test - }; - Mode mode; -}; - -} - -static bool MonteCarlo(const TestCtx *ctx, FileTest *t, - const EVP_CIPHER *cipher, std::vector *out, - bool encrypt, std::vector key, - std::vector iv, std::vector in) { - const std::string in_label = encrypt ? "PLAINTEXT" : "CIPHERTEXT", - result_label = encrypt ? "CIPHERTEXT" : "PLAINTEXT"; - std::vector prev_result, result, prev_in; - for (int i = 0; i < 100; i++) { - printf("COUNT = %d\r\nKEY = %s\r\n", i, EncodeHex(key).c_str()); - if (ctx->has_iv) { - printf("IV = %s\r\n", EncodeHex(iv).c_str()); - } - printf("%s = %s\r\n", in_label.c_str(), EncodeHex(in).c_str()); - - if (!ctx->has_iv) { // ECB mode - for (int j = 0; j < 1000; j++) { - prev_result = result; - if (!CipherOperation(cipher, &result, encrypt, key, iv, in)) { - return false; - } - in = result; - } - } else { - for (int j = 0; j < 1000; j++) { - prev_result = result; - if (j > 0) { - if (encrypt) { - iv = result; - } else { - iv = prev_in; - } - } - - if (!CipherOperation(cipher, &result, encrypt, key, iv, in)) { - return false; - } - - prev_in = in; - - if (j == 0) { - in = iv; - } else { - in = prev_result; - } - } - } - - printf("%s = %s\r\n\r\n", result_label.c_str(), EncodeHex(result).c_str()); - - const size_t key_len = key.size() * 8; - if (key_len == 128) { - for (size_t k = 0; k < key.size(); k++) { - key[k] ^= result[k]; - } - } else if (key_len == 192) { - for (size_t k = 0; k < key.size(); k++) { - // Key[i+1] = Key[i] xor (last 64-bits of CT[j-1] || CT[j]) - if (k < 8) { - key[k] ^= prev_result[prev_result.size() - 8 + k]; - } else { - key[k] ^= result[k - 8]; - } - } - } else { // key_len == 256 - for (size_t k = 0; k < key.size(); k++) { - // Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) - if (k < 16) { - key[k] ^= prev_result[k]; - } else { - key[k] ^= result[k - 16]; - } - } - } - - if (ctx->has_iv) { - iv = result; - in = prev_result; - } else { - in = result; - } - } - - return true; -} - -static bool TestCipher(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - if (t->HasInstruction("ENCRYPT") == t->HasInstruction("DECRYPT")) { - t->PrintLine("Want either ENCRYPT or DECRYPT"); - return false; - } - enum { - kEncrypt, - kDecrypt, - } operation = t->HasInstruction("ENCRYPT") ? kEncrypt : kDecrypt; - - std::string count; - std::vector key, iv, in, result; - if (!t->GetAttribute(&count, "COUNT") || - !t->GetBytes(&key, "KEY") || - (ctx->has_iv && !t->GetBytes(&iv, "IV"))) { - return false; - } - - const EVP_CIPHER *cipher = ctx->cipher; - if (operation == kEncrypt) { - if (!t->GetBytes(&in, "PLAINTEXT")) { - return false; - } - } else { // operation == kDecrypt - if (!t->GetBytes(&in, "CIPHERTEXT")) { - return false; - } - } - - if (ctx->mode == TestCtx::kKAT) { - if (!CipherOperation(cipher, &result, operation == kEncrypt, key, iv, in)) { - return false; - } - const std::string label = - operation == kEncrypt ? "CIPHERTEXT" : "PLAINTEXT"; - printf("%s%s = %s\r\n\r\n", t->CurrentTestToString().c_str(), label.c_str(), - EncodeHex(result).c_str()); - } else { // ctx->mode == kMCT - const std::string op_label = - operation == kEncrypt ? "[ENCRYPT]" : "[DECRYPT]"; - printf("%s\r\n\r\n", op_label.c_str()); - if (!MonteCarlo(ctx, t, cipher, &result, operation == kEncrypt, key, iv, - in)) { - return false; - } - if (operation == kEncrypt) { - // MCT tests contain a stray blank line after the ENCRYPT section. - printf("\r\n"); - } - } - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s (kat|mct) \n", arg); - return 1; -} - -int cavp_aes_test_main(int argc, char **argv) { - if (argc != 4) { - return usage(argv[0]); - } - - const std::string tm(argv[1]); - enum TestCtx::Mode test_mode; - if (tm == "kat") { - test_mode = TestCtx::kKAT; - } else if (tm == "mct") { - test_mode = TestCtx::kMCT; - } else { - fprintf(stderr, "invalid test_mode: %s\n", tm.c_str()); - return usage(argv[0]); - } - - const std::string cipher_name(argv[2]); - const EVP_CIPHER *cipher = GetCipher(argv[2]); - if (cipher == nullptr) { - fprintf(stderr, "invalid cipher: %s\n", argv[2]); - return 1; - } - const bool has_iv = - (cipher_name != "aes-128-ecb" && - cipher_name != "aes-192-ecb" && - cipher_name != "aes-256-ecb"); - - TestCtx ctx = {cipher, has_iv, test_mode}; - - FileTest::Options opts; - opts.path = argv[3]; - opts.callback = TestCipher; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ctr_drbg_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ctr_drbg_test.cc deleted file mode 100644 index a27736e2..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ctr_drbg_test.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_ctr_drbg_test processes a NIST CAVP DRBG800-90A test vector request -// file and emits the corresponding response. - -#include - -#include - -#include "cavp_test_util.h" -#include "../crypto/fipsmodule/rand/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" - - -static bool TestCTRDRBG(FileTest *t, void *arg) { - std::string test_type, prediction_resistance, entropy_input_len, nonce_len, - personalization_str_len, additional_input_len, returned_bits_len; - if (!t->GetInstruction(&test_type, "AES-256 no df") || - !t->GetInstruction(&prediction_resistance, "PredictionResistance") || - !t->GetInstruction(&entropy_input_len, "EntropyInputLen") || - !t->GetInstruction(&nonce_len, "NonceLen") || - !t->GetInstruction(&personalization_str_len, - "PersonalizationStringLen") || - !t->GetInstruction(&additional_input_len, "AdditionalInputLen") || - !t->GetInstruction(&returned_bits_len, "ReturnedBitsLen") || - !test_type.empty() || - prediction_resistance != "False" || - strtoul(entropy_input_len.c_str(), nullptr, 0) != - CTR_DRBG_ENTROPY_LEN * 8 || - nonce_len != "0") { - return false; - } - - std::string count; - std::vector entropy, nonce, personalization_str, ai1, ai2; - if (!t->GetAttribute(&count, "COUNT") || - !t->GetBytes(&entropy, "EntropyInput") || - !t->GetBytes(&nonce, "Nonce") || - !t->GetBytes(&personalization_str, "PersonalizationString") || - !t->GetBytes(&ai1, "AdditionalInput") || - !t->GetBytes(&ai2, "AdditionalInput/2") || - entropy.size() * 8 != strtoul(entropy_input_len.c_str(), nullptr, 0) || - nonce.size() != 0 || - personalization_str.size() * 8 != - strtoul(personalization_str_len.c_str(), nullptr, 0) || - ai1.size() != ai2.size() || - ai1.size() * 8 != strtoul(additional_input_len.c_str(), nullptr, 0)) { - return false; - } - - CTR_DRBG_STATE drbg; - CTR_DRBG_init(&drbg, entropy.data(), - personalization_str.size() > 0 ? personalization_str.data() - : nullptr, - personalization_str.size()); - - uint64_t out_len = strtoul(returned_bits_len.c_str(), nullptr, 0); - if (out_len == 0 || (out_len & 7) != 0) { - return false; - } - out_len /= 8; - - std::vector out; - out.resize(out_len); - - CTR_DRBG_generate(&drbg, out.data(), out.size(), - ai1.size() > 0 ? ai1.data() : nullptr, ai1.size()); - CTR_DRBG_generate(&drbg, out.data(), out.size(), - ai2.size() > 0 ? ai2.data() : nullptr, ai2.size()); - - printf("%s", t->CurrentTestToString().c_str()); - printf("ReturnedBits = %s\r\n\r\n", EncodeHex(out).c_str()); - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s \n", arg); - return 1; -} - -int cavp_ctr_drbg_test_main(int argc, char **argv) { - if (argc != 2) { - return usage(argv[0]); - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestCTRDRBG; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_keypair_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_keypair_test.cc deleted file mode 100644 index f8c4a017..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_keypair_test.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_ecdsa2_keypair_test processes a NIST CAVP ECDSA2 KeyPair test vector -// request file and emits the corresponding response. - -#include - -#include - -#include -#include -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -static bool TestECDSA2KeyPair(FileTest *t, void *arg) { - std::string n_str; - const char *group_str; - int nid = GetECGroupNIDFromInstruction(t, &group_str); - if (nid == NID_undef || - !t->GetAttribute(&n_str, "N")) { - return false; - } - - // Don't use CurrentTestToString to avoid printing the N. - printf( - "[%s]\r\n\r\n[B.4.2 Key Pair Generation by Testing Candidates]\r\n\r\n", - group_str); - - unsigned long n = strtoul(n_str.c_str(), nullptr, 10); - for (unsigned long i = 0; i < n; i++) { - bssl::UniquePtr qx(BN_new()), qy(BN_new()); - bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); - if (!key || - !EC_KEY_generate_key_fips(key.get()) || - !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()), - EC_KEY_get0_public_key(key.get()), - qx.get(), qy.get(), nullptr)) { - return false; - } - - size_t degree_len = - (EC_GROUP_get_degree(EC_KEY_get0_group(key.get())) + 7) / 8; - size_t order_len = - BN_num_bytes(EC_GROUP_get0_order(EC_KEY_get0_group(key.get()))); - std::vector qx_bytes(degree_len), qy_bytes(degree_len); - std::vector d_bytes(order_len); - if (!BN_bn2bin_padded(qx_bytes.data(), qx_bytes.size(), qx.get()) || - !BN_bn2bin_padded(qy_bytes.data(), qy_bytes.size(), qy.get()) || - !BN_bn2bin_padded(d_bytes.data(), d_bytes.size(), - EC_KEY_get0_private_key(key.get()))) { - return false; - } - - printf("d = %s\r\nQx = %s\r\nQy = %s\r\n\r\n", EncodeHex(d_bytes).c_str(), - EncodeHex(qx_bytes).c_str(), EncodeHex(qy_bytes).c_str()); - } - - return true; -} - -int cavp_ecdsa2_keypair_test_main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: %s \n", - argv[0]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestECDSA2KeyPair; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_pkv_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_pkv_test.cc deleted file mode 100644 index d823e7af..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_pkv_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_ecdsa2_pkv_test processes a NIST CAVP ECDSA2 PKV test vector request file -// and emits the corresponding response. - -#include - -#include -#include -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "cavp_test_util.h" - - -static bool TestECDSA2PKV(FileTest *t, void *arg) { - int nid = GetECGroupNIDFromInstruction(t); - if (nid == NID_undef) { - return false; - } - bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); - bssl::UniquePtr qx = GetBIGNUM(t, "Qx"); - bssl::UniquePtr qy = GetBIGNUM(t, "Qy"); - if (!key || !qx || !qy) { - return false; - } - - if (EC_KEY_set_public_key_affine_coordinates(key.get(), qx.get(), qy.get())) { - printf("%sResult = P\r\n\r\n", t->CurrentTestToString().c_str()); - } else { - char buf[256]; - ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); - printf("%sResult = F (%s)\r\n\r\n", t->CurrentTestToString().c_str(), buf); - } - ERR_clear_error(); - return true; -} - -int cavp_ecdsa2_pkv_test_main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: %s \n", - argv[0]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestECDSA2PKV; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_siggen_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_siggen_test.cc deleted file mode 100644 index 1282eaae..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_siggen_test.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_ecdsa2_siggen_test processes NIST CAVP ECDSA2 SigGen and -// SigGenComponent test vector request files and emits the corresponding -// response. - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../crypto/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -static bool TestECDSA2SigGenImpl(FileTest *t, bool is_component) { - int nid = GetECGroupNIDFromInstruction(t); - const EVP_MD *md = GetDigestFromInstruction(t); - if (nid == NID_undef || md == nullptr) { - return false; - } - bssl::UniquePtr qx(BN_new()), qy(BN_new()); - bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); - std::vector msg; - if (!qx || !qy || !key || - !EC_KEY_generate_key_fips(key.get()) || - !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()), - EC_KEY_get0_public_key(key.get()), - qx.get(), qy.get(), nullptr) || - !t->GetBytes(&msg, "Msg")) { - return false; - } - - uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned digest_len; - if (is_component) { - if (msg.size() != EVP_MD_size(md)) { - t->PrintLine("Bad input length."); - return false; - } - digest_len = EVP_MD_size(md); - OPENSSL_memcpy(digest, msg.data(), msg.size()); - } else if (!EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, - nullptr)) { - return false; - } - - bssl::UniquePtr sig(ECDSA_do_sign(digest, digest_len, key.get())); - if (!sig) { - return false; - } - - size_t degree_len = - (EC_GROUP_get_degree(EC_KEY_get0_group(key.get())) + 7) / 8; - size_t order_len = - BN_num_bytes(EC_GROUP_get0_order(EC_KEY_get0_group(key.get()))); - std::vector qx_bytes(degree_len), qy_bytes(degree_len); - std::vector r_bytes(order_len), s_bytes(order_len); - if (!BN_bn2bin_padded(qx_bytes.data(), qx_bytes.size(), qx.get()) || - !BN_bn2bin_padded(qy_bytes.data(), qy_bytes.size(), qy.get()) || - !BN_bn2bin_padded(r_bytes.data(), r_bytes.size(), sig->r) || - !BN_bn2bin_padded(s_bytes.data(), s_bytes.size(), sig->s)) { - return false; - } - - printf("%sQx = %s\r\nQy = %s\r\nR = %s\r\nS = %s\r\n\r\n", - t->CurrentTestToString().c_str(), EncodeHex(qx_bytes).c_str(), - EncodeHex(qy_bytes).c_str(), EncodeHex(r_bytes).c_str(), - EncodeHex(s_bytes).c_str()); - return true; -} - -static bool TestECDSA2SigGen(FileTest *t, void *arg) { - return TestECDSA2SigGenImpl(t, false); -} - -static bool TestECDSA2SigGenComponent(FileTest *t, void *arg) { - return TestECDSA2SigGenImpl(t, true); -} - -int cavp_ecdsa2_siggen_test_main(int argc, char **argv) { - if (argc != 3) { - fprintf(stderr, "usage: %s (SigGen|SigGenComponent) \n", - argv[0]); - return 1; - } - - static bool (*test_func)(FileTest *, void *); - if (strcmp(argv[1], "SigGen") == 0) { - test_func = TestECDSA2SigGen; - } else if (strcmp(argv[1], "SigGenComponent") == 0) { - test_func = TestECDSA2SigGenComponent; - } else { - fprintf(stderr, "Unknown test type: %s\n", argv[1]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[2]; - opts.callback = test_func; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_sigver_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_sigver_test.cc deleted file mode 100644 index f3fd4b1e..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_ecdsa2_sigver_test.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_ecdsa2_sigver_test processes a NIST CAVP ECDSA2 SigVer test vector -// request file and emits the corresponding response. - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "cavp_test_util.h" - - -static bool TestECDSA2SigVer(FileTest *t, void *arg) { - int nid = GetECGroupNIDFromInstruction(t); - const EVP_MD *md = GetDigestFromInstruction(t); - if (nid == NID_undef || md == nullptr) { - return false; - } - bssl::UniquePtr sig(ECDSA_SIG_new()); - bssl::UniquePtr key(EC_KEY_new_by_curve_name(nid)); - bssl::UniquePtr qx = GetBIGNUM(t, "Qx"); - bssl::UniquePtr qy = GetBIGNUM(t, "Qy"); - bssl::UniquePtr r = GetBIGNUM(t, "R"); - bssl::UniquePtr s = GetBIGNUM(t, "S"); - std::vector msg; - uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned digest_len; - if (!sig || !key || !qx || !qy || !r || !s || - !EC_KEY_set_public_key_affine_coordinates(key.get(), qx.get(), - qy.get()) || - !t->GetBytes(&msg, "Msg") || - !EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr)) { - return false; - } - - BN_free(sig->r); - sig->r = r.release(); - BN_free(sig->s); - sig->s = s.release(); - - if (ECDSA_do_verify(digest, digest_len, sig.get(), key.get())) { - printf("%sResult = P\r\n\r\n", t->CurrentTestToString().c_str()); - } else { - char buf[256]; - ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); - printf("%sResult = F (%s)\r\n\r\n", t->CurrentTestToString().c_str(), buf); - } - ERR_clear_error(); - return true; -} - -int cavp_ecdsa2_sigver_test_main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: %s \n", - argv[0]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestECDSA2SigVer; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_hmac_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_hmac_test.cc deleted file mode 100644 index c88226a9..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_hmac_test.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_hmac_test processes a NIST CAVP HMAC test vector request file and emits -// the corresponding response. - -#include - -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -static bool TestHMAC(FileTest *t, void *arg) { - std::string md_len_str; - if (!t->GetInstruction(&md_len_str, "L")) { - return false; - } - const size_t md_len = strtoul(md_len_str.c_str(), nullptr, 0); - - const EVP_MD *md; - switch (md_len) { - case 20: - md = EVP_sha1(); - break; - case 28: - md = EVP_sha224(); - break; - case 32: - md = EVP_sha256(); - break; - case 48: - md = EVP_sha384(); - break; - case 64: - md = EVP_sha512(); - break; - default: - return false; - } - - std::string count_str, k_len_str, t_len_str; - std::vector key, msg; - if (!t->GetAttribute(&count_str, "Count") || - !t->GetAttribute(&k_len_str, "Klen") || - !t->GetAttribute(&t_len_str, "Tlen") || - !t->GetBytes(&key, "Key") || - !t->GetBytes(&msg, "Msg")) { - return false; - } - - size_t k_len = strtoul(k_len_str.c_str(), nullptr, 0); - size_t t_len = strtoul(t_len_str.c_str(), nullptr, 0); - if (key.size() < k_len) { - return false; - } - unsigned out_len; - uint8_t out[EVP_MAX_MD_SIZE]; - if (HMAC(md, key.data(), k_len, msg.data(), msg.size(), out, &out_len) == - NULL) { - return false; - } - - if (out_len < t_len) { - return false; - } - - printf("%s", t->CurrentTestToString().c_str()); - printf("Mac = %s\r\n\r\n", - EncodeHex(bssl::MakeConstSpan(out, t_len)).c_str()); - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s \n", arg); - return 1; -} - -int cavp_hmac_test_main(int argc, char **argv) { - if (argc != 2) { - return usage(argv[0]); - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestHMAC; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_kas_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_kas_test.cc deleted file mode 100644 index 9a74f1d4..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_kas_test.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2018, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_kas_test processes NIST CAVP ECC KAS test vector request files and -// emits the corresponding response. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../crypto/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -static bool TestKAS(FileTest *t, void *arg) { - const bool validate = *reinterpret_cast(arg); - - int nid = NID_undef; - size_t digest_len = 0; - - if (t->HasInstruction("EB - SHA224")) { - nid = NID_secp224r1; - digest_len = SHA224_DIGEST_LENGTH; - } else if (t->HasInstruction("EC - SHA256")) { - nid = NID_X9_62_prime256v1; - digest_len = SHA256_DIGEST_LENGTH; - } else if (t->HasInstruction("ED - SHA384")) { - nid = NID_secp384r1; - digest_len = SHA384_DIGEST_LENGTH; - } else if (t->HasInstruction("EE - SHA512")) { - nid = NID_secp521r1; - digest_len = SHA512_DIGEST_LENGTH; - } else { - return false; - } - - if (!t->HasAttribute("COUNT")) { - return false; - } - - bssl::UniquePtr their_x(GetBIGNUM(t, "QeCAVSx")); - bssl::UniquePtr their_y(GetBIGNUM(t, "QeCAVSy")); - bssl::UniquePtr ec_key(EC_KEY_new_by_curve_name(nid)); - bssl::UniquePtr ctx(BN_CTX_new()); - if (!their_x || !their_y || !ec_key || !ctx) { - return false; - } - - const EC_GROUP *const group = EC_KEY_get0_group(ec_key.get()); - bssl::UniquePtr their_point(EC_POINT_new(group)); - if (!their_point || - !EC_POINT_set_affine_coordinates_GFp( - group, their_point.get(), their_x.get(), their_y.get(), ctx.get())) { - return false; - } - - if (validate) { - bssl::UniquePtr our_k(GetBIGNUM(t, "deIUT")); - if (!our_k || - !EC_KEY_set_private_key(ec_key.get(), our_k.get()) || - // These attributes are ignored. - !t->HasAttribute("QeIUTx") || - !t->HasAttribute("QeIUTy")) { - return false; - } - } else if (!EC_KEY_generate_key(ec_key.get())) { - return false; - } - - uint8_t digest[EVP_MAX_MD_SIZE]; - if (!ECDH_compute_key_fips(digest, digest_len, their_point.get(), - ec_key.get())) { - return false; - } - - if (validate) { - std::vector expected_shared_bytes; - if (!t->GetBytes(&expected_shared_bytes, "CAVSHashZZ")) { - return false; - } - const bool ok = - digest_len == expected_shared_bytes.size() && - OPENSSL_memcmp(digest, expected_shared_bytes.data(), digest_len) == 0; - - printf("%sIUTHashZZ = %s\r\nResult = %c\r\n\r\n\r\n", - t->CurrentTestToString().c_str(), - EncodeHex(bssl::MakeConstSpan(digest, digest_len)).c_str(), - ok ? 'P' : 'F'); - } else { - const EC_POINT *pub = EC_KEY_get0_public_key(ec_key.get()); - bssl::UniquePtr x(BN_new()); - bssl::UniquePtr y(BN_new()); - if (!x || !y || - !EC_POINT_get_affine_coordinates_GFp(group, pub, x.get(), y.get(), - ctx.get())) { - return false; - } - bssl::UniquePtr x_hex(BN_bn2hex(x.get())); - bssl::UniquePtr y_hex(BN_bn2hex(y.get())); - - printf("%sQeIUTx = %s\r\nQeIUTy = %s\r\nHashZZ = %s\r\n", - t->CurrentTestToString().c_str(), x_hex.get(), y_hex.get(), - EncodeHex(bssl::MakeConstSpan(digest, digest_len)).c_str()); - } - - return true; -} - -int cavp_kas_test_main(int argc, char **argv) { - if (argc != 3) { - fprintf(stderr, "usage: %s (validity|function) \n", - argv[0]); - return 1; - } - - bool validity; - if (strcmp(argv[1], "validity") == 0) { - validity = true; - } else if (strcmp(argv[1], "function") == 0) { - validity = false; - } else { - fprintf(stderr, "Unknown test type: %s\n", argv[1]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[2]; - opts.arg = &validity; - opts.callback = TestKAS; - opts.silent = true; - opts.comment_callback = EchoComment; - opts.is_kas_test = true; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_keywrap_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_keywrap_test.cc deleted file mode 100644 index 67397ecb..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_keywrap_test.cc +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_keywrap_test processes a NIST CAVP AES test vector request file and -// emits the corresponding response. - -#include - -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - bool encrypt; - bool padding; -}; - -} // namespace - -static bool AESKeyWrap(std::vector *out, bool encrypt, - const std::vector &key, - const std::vector &in) { - size_t key_bits = key.size() * 8; - if (key_bits != 128 && key_bits != 192 && key_bits != 256) { - return false; - } - AES_KEY aes_key; - - if (encrypt) { - out->resize(in.size() + 8); - if (AES_set_encrypt_key(key.data(), key_bits, &aes_key) || - AES_wrap_key(&aes_key, nullptr, out->data(), in.data(), in.size()) == - -1) { - return false; - } - } else { - out->resize(in.size() - 8); - if (AES_set_decrypt_key(key.data(), key_bits, &aes_key) || - AES_unwrap_key(&aes_key, nullptr, out->data(), in.data(), in.size()) == - -1) { - return false; - } - } - - return true; -} - -static bool AESKeyWrapWithPadding(std::vector *out, bool encrypt, - const std::vector &key, - const std::vector &in) { - const size_t key_bits = key.size() * 8; - if (key_bits != 128 && key_bits != 192 && key_bits != 256) { - return false; - } - AES_KEY aes_key; - - size_t out_len; - if (encrypt) { - out->resize(in.size() + 15); - if (AES_set_encrypt_key(key.data(), key_bits, &aes_key) || - !AES_wrap_key_padded(&aes_key, out->data(), &out_len, out->size(), - in.data(), in.size())) { - return false; - } - } else { - out->resize(in.size()); - if (AES_set_decrypt_key(key.data(), key_bits, &aes_key) || - !AES_unwrap_key_padded(&aes_key, out->data(), &out_len, out->size(), - in.data(), in.size())) { - return false; - } - } - - out->resize(out_len); - return true; -} - -static bool TestCipher(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - std::string count, unused, in_label = ctx->encrypt ? "P" : "C", - result_label = ctx->encrypt ? "C" : "P"; - std::vector key, in, result; - // clang-format off - if (!t->GetInstruction(&unused, "PLAINTEXT LENGTH") || - !t->GetAttribute(&count, "COUNT") || - !t->GetBytes(&key, "K") || - !t->GetBytes(&in, in_label)) { - return false; - } - // clang-format on - - auto wrap_function = AESKeyWrap; - if (ctx->padding) { - wrap_function = AESKeyWrapWithPadding; - } - - printf("%s", t->CurrentTestToString().c_str()); - if (!wrap_function(&result, ctx->encrypt, key, in)) { - if (ctx->encrypt) { - return false; - } else { - printf("FAIL\r\n\r\n"); - } - } else { - printf("%s = %s\r\n\r\n", result_label.c_str(), EncodeHex(result).c_str()); - } - - return true; -} - -static int usage(char *arg) { - fprintf( - stderr, - "usage: %s (enc|dec|enc-pad|dec-pad) (128|192|256) \n", - arg); - return 1; -} - -int cavp_keywrap_test_main(int argc, char **argv) { - if (argc != 4) { - return usage(argv[0]); - } - - const std::string op(argv[1]); - bool encrypt = false; - bool padding = false; - if (op == "enc") { - encrypt = true; - } else if (op == "dec") { - } else if (op == "enc-pad") { - encrypt = true; - padding = true; - } else if (op == "dec-pad") { - padding = true; - } else { - return usage(argv[0]); - } - - TestCtx ctx = {encrypt, padding}; - - FileTest::Options opts; - opts.path = argv[3]; - opts.callback = TestCipher; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_main.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_main.cc deleted file mode 100644 index 64dbd69d..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_main.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_main is a wrapper that invokes the main entry function of one of the -// CAVP validation suite binaries. - -#include -#include -#include - -#include - -#include "cavp_test_util.h" - - -static int usage(char *arg) { - fprintf(stderr, "usage: %s \n", arg); - return 1; -} - -struct TestSuite { - std::string name; - int (*main_func)(int argc, char **argv); -}; - -static TestSuite all_test_suites[] = { - {"aes", &cavp_aes_test_main}, - {"aes_gcm", &cavp_aes_gcm_test_main}, - {"ctr_drbg", &cavp_ctr_drbg_test_main}, - {"ecdsa2_keypair", &cavp_ecdsa2_keypair_test_main}, - {"ecdsa2_pkv", &cavp_ecdsa2_pkv_test_main}, - {"ecdsa2_siggen", &cavp_ecdsa2_siggen_test_main}, - {"ecdsa2_sigver", &cavp_ecdsa2_sigver_test_main}, - {"hmac", &cavp_hmac_test_main}, - {"kas", &cavp_kas_test_main}, - {"keywrap", &cavp_keywrap_test_main}, - {"rsa2_keygen", &cavp_rsa2_keygen_test_main}, - {"rsa2_siggen", &cavp_rsa2_siggen_test_main}, - {"rsa2_sigver", &cavp_rsa2_sigver_test_main}, - {"tlskdf", &cavp_tlskdf_test_main}, - {"sha", &cavp_sha_test_main}, - {"sha_monte", &cavp_sha_monte_test_main}, - {"tdes", &cavp_tdes_test_main} -}; - -int main(int argc, char **argv) { - CRYPTO_library_init(); - - if (argc < 3) { - return usage(argv[0]); - } - - const std::string suite(argv[1]); - for (const TestSuite &s : all_test_suites) { - if (s.name == suite) { - return s.main_func(argc - 1, &argv[1]); - } - } - - fprintf(stderr, "invalid test suite: %s\n\n", argv[1]); - return usage(argv[0]); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_keygen_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_keygen_test.cc deleted file mode 100644 index e7088c7b..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_keygen_test.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_rsa2_keygen_test processes NIST CAVP RSA2 KeyGen test vector request -// files and emits the corresponding response. - -#include - -#include -#include -#include - -#include "../crypto/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -static bool TestRSA2KeyGen(FileTest *t, void *arg) { - std::string mod_str, table, count_str; - if (!t->GetInstruction(&mod_str, "mod") || - !t->GetInstruction(&table, "Table for M-R Test") || - table != "C.2" || - !t->GetAttribute(&count_str, "N")) { - return false; - } - - printf("[mod = %s]\r\n", mod_str.c_str()); - printf("[Table for M-R Test = %s]\r\n\r\n", table.c_str()); - - size_t bits = strtoul(mod_str.c_str(), nullptr, 0); - size_t count = strtoul(count_str.c_str(), nullptr, 0); - for (size_t i = 0; i < count; i++) { - bssl::UniquePtr key(RSA_new()); - if (key == nullptr || - bits == 0 || - !RSA_generate_key_fips(key.get(), bits, nullptr)) { - return 0; - } - - const BIGNUM *n, *e, *d, *p, *q; - RSA_get0_key(key.get(), &n, &e, &d); - RSA_get0_factors(key.get(), &p, &q); - std::vector n_bytes(BN_num_bytes(n)), e_bytes(BN_num_bytes(e)), - d_bytes((bits + 7) / 8), p_bytes(BN_num_bytes(p)), - q_bytes(BN_num_bytes(q)); - if (n == NULL || - BN_bn2bin(n, n_bytes.data()) != n_bytes.size() || - e == NULL || - BN_bn2bin(e, e_bytes.data()) != e_bytes.size() || - d == NULL || - !BN_bn2bin_padded(d_bytes.data(), d_bytes.size(), d) || - p == NULL || - BN_bn2bin(p, p_bytes.data()) != p_bytes.size() || - q == NULL || - BN_bn2bin(q, q_bytes.data()) != q_bytes.size()) { - return false; - } - - printf("e = %s\r\np = %s\r\nq = %s\r\nn = %s\r\nd = %s\r\n\r\n", - EncodeHex(e_bytes).c_str(), EncodeHex(p_bytes).c_str(), - EncodeHex(q_bytes).c_str(), EncodeHex(n_bytes).c_str(), - EncodeHex(d_bytes).c_str()); - } - - return true; -} - -int cavp_rsa2_keygen_test_main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: %s \n", - argv[0]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestRSA2KeyGen; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_siggen_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_siggen_test.cc deleted file mode 100644 index 636a73a9..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_siggen_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_rsa2_siggen_test processes NIST CAVP RSA2 SigGen test vector request -// files and emits the corresponding response. - -#include - -#include -#include -#include -#include - -#include "../crypto/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - -namespace { - -struct TestCtx { - bssl::UniquePtr key; - bool is_pss; -}; - -} - -static bool TestRSA2SigGen(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - std::string mod_str, hash; - std::vector msg; - if (!t->GetInstruction(&mod_str, "mod") || - !t->GetAttribute(&hash, "SHAAlg") || - !t->GetBytes(&msg, "Msg")) { - return false; - } - - std::string test = t->CurrentTestToString(); - if (t->IsAtNewInstructionBlock()) { - int mod_bits = strtoul(mod_str.c_str(), nullptr, 0); - ctx->key = bssl::UniquePtr(RSA_new()); - if (ctx->key == nullptr || - mod_bits == 0 || - !RSA_generate_key_fips(ctx->key.get(), mod_bits, nullptr)) { - return false; - } - - const BIGNUM *n, *e; - RSA_get0_key(ctx->key.get(), &n, &e, nullptr); - - std::vector n_bytes(BN_num_bytes(n)); - std::vector e_bytes(BN_num_bytes(e)); - if (!BN_bn2bin_padded(n_bytes.data(), n_bytes.size(), n) || - !BN_bn2bin_padded(e_bytes.data(), e_bytes.size(), e)) { - return false; - } - - printf("[mod = %s]\r\n\r\nn = %s\r\n\r\ne = %s", mod_str.c_str(), - EncodeHex(n_bytes).c_str(), EncodeHex(e_bytes).c_str()); - test = test.substr(test.find("]") + 3); - } - - const EVP_MD *md = EVP_get_digestbyname(hash.c_str()); - uint8_t digest_buf[EVP_MAX_MD_SIZE]; - std::vector sig(RSA_size(ctx->key.get())); - unsigned digest_len; - size_t sig_len; - if (md == NULL || - !EVP_Digest(msg.data(), msg.size(), digest_buf, &digest_len, md, NULL)) { - return false; - } - - if (ctx->is_pss) { - if (!RSA_sign_pss_mgf1(ctx->key.get(), &sig_len, sig.data(), sig.size(), - digest_buf, digest_len, md, md, -1)) { - return false; - } - } else { - unsigned sig_len_u; - if (!RSA_sign(EVP_MD_type(md), digest_buf, digest_len, sig.data(), - &sig_len_u, ctx->key.get())) { - return false; - } - sig_len = sig_len_u; - } - - sig.resize(sig_len); - printf("%sS = %s\r\n\r\n", test.c_str(), EncodeHex(sig).c_str()); - return true; -} - -int cavp_rsa2_siggen_test_main(int argc, char **argv) { - if (argc != 3) { - fprintf(stderr, "usage: %s (pkcs15|pss) \n", - argv[0]); - return 1; - } - - TestCtx ctx; - if (strcmp(argv[1], "pkcs15") == 0) { - ctx = {nullptr, false}; - } else if (strcmp(argv[1], "pss") == 0) { - ctx = {nullptr, true}; - } else { - fprintf(stderr, "Unknown test type: %s\n", argv[1]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[2]; - opts.callback = TestRSA2SigGen; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_sigver_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_sigver_test.cc deleted file mode 100644 index cbcfc1fc..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_rsa2_sigver_test.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_rsa2_sigver_test processes NIST CAVP RSA2 SigVer test vector request -// files and emits the corresponding response. - -#include - -#include -#include -#include -#include -#include - -#include "../crypto/internal.h" -#include "../crypto/test/file_test.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - std::vector N; - bool is_pss; -}; - -} - -static bool TestRSA2SigVer(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - std::string mod_str; - if (!t->GetInstruction(&mod_str, "mod")) { - return false; - } - - printf("%s", t->CurrentTestToString().c_str()); - - if (t->HasAttribute("n")) { - printf("\r\n"); - return t->GetBytes(&ctx->N, "n"); - } - - std::string hash; - std::vector e_bytes, msg, sig; - if (!t->GetAttribute(&hash, "SHAAlg") || - !t->GetBytes(&e_bytes, "e") || - !t->GetBytes(&msg, "Msg") || - !t->GetBytes(&sig, "S")) { - return false; - } - - bssl::UniquePtr key(RSA_new()); - key->n = BN_new(); - key->e = BN_new(); - if (key == nullptr || - !BN_bin2bn(ctx->N.data(), ctx->N.size(), key->n) || - !BN_bin2bn(e_bytes.data(), e_bytes.size(), key->e)) { - return false; - } - - const EVP_MD *md = EVP_get_digestbyname(hash.c_str()); - uint8_t digest_buf[EVP_MAX_MD_SIZE]; - unsigned digest_len; - if (md == NULL || - !EVP_Digest(msg.data(), msg.size(), digest_buf, &digest_len, md, NULL)) { - return false; - } - - int ok; - if (ctx->is_pss) { - ok = RSA_verify_pss_mgf1(key.get(), digest_buf, digest_len, md, md, -1, - sig.data(), sig.size()); - } else { - ok = RSA_verify(EVP_MD_type(md), digest_buf, digest_len, sig.data(), - sig.size(), key.get()); - } - - if (ok) { - printf("Result = P\r\n\r\n"); - } else { - char buf[256]; - ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); - printf("Result = F (%s)\r\n\r\n", buf); - } - ERR_clear_error(); - return true; -} - -int cavp_rsa2_sigver_test_main(int argc, char **argv) { - if (argc != 3) { - fprintf(stderr, "usage: %s (pkcs15|pss) \n", - argv[0]); - return 1; - } - - TestCtx ctx; - if (strcmp(argv[1], "pkcs15") == 0) { - ctx = {std::vector(), false}; - } else if (strcmp(argv[1], "pss") == 0) { - ctx = {std::vector(), true}; - } else { - fprintf(stderr, "Unknown test type: %s\n", argv[1]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[2]; - opts.callback = TestRSA2SigVer; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_monte_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_monte_test.cc deleted file mode 100644 index f5bcdd11..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_monte_test.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_sha_monte_test processes a NIST CAVP SHA-Monte test vector request file -// and emits the corresponding response. - -#include - -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - std::string hash; -}; - -} - -static bool TestSHAMonte(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - const EVP_MD *md = EVP_get_digestbyname(ctx->hash.c_str()); - if (md == nullptr) { - return false; - } - const size_t md_len = EVP_MD_size(md); - - std::string out_len; - if (!t->GetInstruction(&out_len, "L") || - md_len != strtoul(out_len.c_str(), nullptr, 0)) { - return false; - } - - std::vector seed; - if (!t->GetBytes(&seed, "Seed") || - seed.size() != md_len) { - return false; - } - - std::vector out = seed; - - printf("%s\r\n", t->CurrentTestToString().c_str()); - - for (int count = 0; count < 100; count++) { - std::vector msg; - msg.insert(msg.end(), out.begin(), out.end()); - msg.insert(msg.end(), out.begin(), out.end()); - msg.insert(msg.end(), out.begin(), out.end()); - for (int i = 0; i < 1000; i++) { - unsigned digest_len; - if (!EVP_Digest(msg.data(), msg.size(), out.data(), &digest_len, md, - nullptr) || - digest_len != out.size()) { - return false; - } - - msg.erase(msg.begin(), msg.begin() + out.size()); - msg.insert(msg.end(), out.begin(), out.end()); - } - printf("COUNT = %d\r\n", count); - printf("MD = %s\r\n\r\n", EncodeHex(out).c_str()); - } - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s \n", arg); - return 1; -} - -int cavp_sha_monte_test_main(int argc, char **argv) { - if (argc != 3) { - return usage(argv[0]); - } - - TestCtx ctx = {std::string(argv[1])}; - - FileTest::Options opts; - opts.path = argv[2]; - opts.callback = TestSHAMonte; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_test.cc deleted file mode 100644 index c0464516..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_sha_test.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_sha_test processes a NIST CAVP SHA test vector request file and emits -// the corresponding response. - -#include - -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - -namespace { - -struct TestCtx { - std::string hash; -}; - -} - -static bool TestSHA(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - const EVP_MD *md = EVP_get_digestbyname(ctx->hash.c_str()); - if (md == nullptr) { - return false; - } - const size_t md_len = EVP_MD_size(md); - - std::string out_len; - if (!t->GetInstruction(&out_len, "L") || - md_len != strtoul(out_len.c_str(), nullptr, 0)) { - return false; - } - - std::string msg_len_str; - std::vector msg; - if (!t->GetAttribute(&msg_len_str, "Len") || - !t->GetBytes(&msg, "Msg")) { - return false; - } - - size_t msg_len = strtoul(msg_len_str.c_str(), nullptr, 0); - if (msg_len % 8 != 0 || - msg_len / 8 > msg.size()) { - return false; - } - msg_len /= 8; - - std::vector out; - out.resize(md_len); - unsigned digest_len; - if (!EVP_Digest(msg.data(), msg_len, out.data(), &digest_len, md, nullptr) || - digest_len != out.size()) { - return false; - } - - printf("%s", t->CurrentTestToString().c_str()); - printf("MD = %s\r\n\r\n", EncodeHex(out).c_str()); - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s \n", arg); - return 1; -} - -int cavp_sha_test_main(int argc, char **argv) { - if (argc != 3) { - return usage(argv[0]); - } - - TestCtx ctx = {std::string(argv[1])}; - - FileTest::Options opts; - opts.path = argv[2]; - opts.callback = TestSHA; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tdes_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tdes_test.cc deleted file mode 100644 index 7b8839d6..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tdes_test.cc +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_tdes_test processes a NIST TMOVS test vector request file and emits the -// corresponding response. - -#include - -#include -#include -#include - -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" -#include "cavp_test_util.h" - - -namespace { - -struct TestCtx { - const EVP_CIPHER *cipher; - enum Mode { - kKAT, // Known Answer Test - kMCT, // Monte Carlo Test - }; - bool has_iv; - Mode mode; -}; - -} - -static bool TestKAT(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - if (t->HasInstruction("ENCRYPT") == t->HasInstruction("DECRYPT")) { - t->PrintLine("Want either ENCRYPT or DECRYPT"); - return false; - } - enum { - kEncrypt, - kDecrypt, - } operation = t->HasInstruction("ENCRYPT") ? kEncrypt : kDecrypt; - - if (t->HasAttribute("NumKeys")) { - // Another file format quirk: NumKeys is a single attribute line immediately - // following an instruction and should probably have been an instruction - // instead. If it is present, the file has separate attributes "KEY{1,2,3}". - // If it is not, the keys are concatenated in a single attribute "KEYs". - std::string num_keys; - t->GetAttribute(&num_keys, "NumKeys"); - t->InjectInstruction("NumKeys", num_keys); - - std::string header = operation == kEncrypt ? "[ENCRYPT]" : "[DECRYPT]"; - printf("%s\r\n\r\n", header.c_str()); - - return true; - } - - enum { - kNotPresent, - kTwo, - kThree, - } num_keys = kNotPresent; - if (t->HasInstruction("NumKeys")) { - std::string num_keys_str; - t->GetInstruction(&num_keys_str, "NumKeys"); - const int n = strtoul(num_keys_str.c_str(), nullptr, 0); - if (n == 2) { - num_keys = kTwo; - } else if (n == 3) { - num_keys = kThree; - } else { - t->PrintLine("invalid NumKeys value"); - return false; - } - } - - std::string count; - std::vector keys, key1, key2, key3, iv, in, result; - const std::string in_label = - operation == kEncrypt ? "PLAINTEXT" : "CIPHERTEXT"; - // clang-format off - if (!t->GetAttribute(&count, "COUNT") || - (num_keys == 0 && !t->GetBytes(&keys, "KEYs")) || - (num_keys > 0 && - (!t->GetBytes(&key1, "KEY1") || - !t->GetBytes(&key2, "KEY2") || - !t->GetBytes(&key3, "KEY3"))) || - (ctx->has_iv && !t->GetBytes(&iv, "IV")) || - !t->GetBytes(&in, in_label)) { - return false; - } - // clang-format on - std::vector key; - if (num_keys != kNotPresent) { - key.insert(key.end(), key1.begin(), key1.end()); - key.insert(key.end(), key2.begin(), key2.end()); - if (num_keys == kThree) { - key.insert(key.end(), key3.begin(), key3.end()); - } - } else { - key.insert(key.end(), keys.begin(), keys.end()); - key.insert(key.end(), keys.begin(), keys.end()); - key.insert(key.end(), keys.begin(), keys.end()); - } - - if (!CipherOperation(ctx->cipher, &result, operation == kEncrypt, key, iv, - in)) { - return false; - } - - // TDES fax files output format differs from file to file, and the input - // format is inconsistent with the output, so we construct the output manually - // rather than printing CurrentTestToString(). - if (t->IsAtNewInstructionBlock() && num_keys == kNotPresent) { - // If NumKeys is present, header is printed when parsing NumKeys. - std::string header = operation == kEncrypt ? "[ENCRYPT]" : "[DECRYPT]"; - printf("%s\r\n", header.c_str()); - } - const std::string result_label = - operation == kEncrypt ? "CIPHERTEXT" : "PLAINTEXT"; - printf("COUNT = %s\r\n", count.c_str()); - if (num_keys == kNotPresent) { - printf("KEYs = %s\r\n", EncodeHex(keys).c_str()); - } else { - printf("KEY1 = %s\r\nKEY2 = %s\r\nKEY3 = %s\r\n", EncodeHex(key1).c_str(), - EncodeHex(key2).c_str(), EncodeHex(key3).c_str()); - } - if (ctx->has_iv) { - printf("IV = %s\r\n", EncodeHex(iv).c_str()); - } - printf("%s = %s\r\n", in_label.c_str(), EncodeHex(in).c_str()); - printf("%s = %s\r\n\r\n", result_label.c_str(), EncodeHex(result).c_str()); - - return true; -} - -// XORKeyWithOddParityLSB sets |*key| to |key| XOR |value| and then writes -// the LSB of each byte to establish odd parity for that byte. This parity-based -// embedded of a DES key into 64 bits is an old tradition and something that -// NIST's tests require. -static void XORKeyWithOddParityLSB(std::vector *key, - const std::vector &value) { - for (size_t i = 0; i < key->size(); i++) { - uint8_t v = (*key)[i] ^ value[i]; - - // Use LSB to establish odd parity. - v |= 0x01; - for (uint8_t j = 1; j < 8; j++) { - v ^= ((v >> j) & 0x01); - } - (*key)[i] = v; - } -} - -static bool TestMCT(FileTest *t, void *arg) { - TestCtx *ctx = reinterpret_cast(arg); - - if (t->HasInstruction("ENCRYPT") == t->HasInstruction("DECRYPT")) { - t->PrintLine("Want either ENCRYPT or DECRYPT"); - return false; - } - enum { - kEncrypt, - kDecrypt, - } operation = t->HasInstruction("ENCRYPT") ? kEncrypt : kDecrypt; - - if (t->HasAttribute("NumKeys")) { - // Another file format quirk: NumKeys is a single attribute line immediately - // following an instruction and should probably have been an instruction - // instead. - std::string num_keys; - t->GetAttribute(&num_keys, "NumKeys"); - t->InjectInstruction("NumKeys", num_keys); - return true; - } - - enum { - kTwo, - kThree, - } num_keys; - std::string num_keys_str; - if (!t->GetInstruction(&num_keys_str, "NumKeys")) { - return false; - } else { - const int n = strtoul(num_keys_str.c_str(), nullptr, 0); - if (n == 2) { - num_keys = kTwo; - } else if (n == 3) { - num_keys = kThree; - } else { - t->PrintLine("invalid NumKeys value"); - return false; - } - } - - std::string count; - std::vector key1, key2, key3, iv, in, result; - const std::string in_label = - operation == kEncrypt ? "PLAINTEXT" : "CIPHERTEXT"; - // clang-format off - if (!t->GetBytes(&key1, "KEY1") || - !t->GetBytes(&key2, "KEY2") || - !t->GetBytes(&key3, "KEY3") || - (ctx->has_iv && !t->GetBytes(&iv, "IV")) || - !t->GetBytes(&in, in_label)) { - return false; - } - // clang-format on - - for (int i = 0; i < 400; i++) { - std::vector current_iv = iv, current_in = in, prev_result, - prev_prev_result; - - std::vector key(key1); - key.insert(key.end(), key2.begin(), key2.end()); - key.insert(key.end(), key3.begin(), key3.end()); - - for (int j = 0; j < 10000; j++) { - prev_prev_result = prev_result; - prev_result = result; - const EVP_CIPHER *cipher = ctx->cipher; - if (!CipherOperation(cipher, &result, operation == kEncrypt, key, - current_iv, current_in)) { - t->PrintLine("CipherOperation failed"); - return false; - } - if (ctx->has_iv) { - if (operation == kEncrypt) { - if (j == 0) { - current_in = current_iv; - } else { - current_in = prev_result; - } - current_iv = result; - } else { // operation == kDecrypt - current_iv = current_in; - current_in = result; - } - } else { - current_in = result; - } - } - - // Output result for COUNT = i. - const std::string result_label = - operation == kEncrypt ? "CIPHERTEXT" : "PLAINTEXT"; - if (i == 0) { - const std::string op_label = - operation == kEncrypt ? "ENCRYPT" : "DECRYPT"; - printf("[%s]\n\n", op_label.c_str()); - } - printf("COUNT = %d\r\nKEY1 = %s\r\nKEY2 = %s\r\nKEY3 = %s\r\n", i, - EncodeHex(key1).c_str(), EncodeHex(key2).c_str(), - EncodeHex(key3).c_str()); - if (ctx->has_iv) { - printf("IV = %s\r\n", EncodeHex(iv).c_str()); - } - printf("%s = %s\r\n", in_label.c_str(), EncodeHex(in).c_str()); - printf("%s = %s\r\n\r\n", result_label.c_str(), EncodeHex(result).c_str()); - - - XORKeyWithOddParityLSB(&key1, result); - XORKeyWithOddParityLSB(&key2, prev_result); - if (num_keys == kThree) { - XORKeyWithOddParityLSB(&key3, prev_prev_result); - } else { - XORKeyWithOddParityLSB(&key3, result); - } - - if (ctx->has_iv) { - if (operation == kEncrypt) { - in = prev_result; - iv = result; - } else { - iv = current_iv; - in = current_in; - } - } else { - in = result; - } - } - - return true; -} - -static int usage(char *arg) { - fprintf(stderr, "usage: %s (kat|mct) \n", arg); - return 1; -} - -int cavp_tdes_test_main(int argc, char **argv) { - if (argc != 4) { - return usage(argv[0]); - } - - const std::string tm(argv[1]); - enum TestCtx::Mode test_mode; - if (tm == "kat") { - test_mode = TestCtx::kKAT; - } else if (tm == "mct") { - test_mode = TestCtx::kMCT; - } else { - fprintf(stderr, "invalid test_mode: %s\n", tm.c_str()); - return usage(argv[0]); - } - - const std::string cipher_name(argv[2]); - const EVP_CIPHER *cipher = GetCipher(argv[2]); - if (cipher == nullptr) { - fprintf(stderr, "invalid cipher: %s\n", argv[2]); - return 1; - } - bool has_iv = cipher_name != "des-ede" && cipher_name != "des-ede3"; - TestCtx ctx = {cipher, has_iv, test_mode}; - - FileTestFunc test_fn = test_mode == TestCtx::kKAT ? &TestKAT : &TestMCT; - FileTest::Options opts; - opts.path = argv[3]; - opts.callback = test_fn; - opts.arg = &ctx; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.cc deleted file mode 100644 index 1b4e3a17..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include "cavp_test_util.h" - -#include -#include -#include -#include - - -const EVP_CIPHER *GetCipher(const std::string &name) { - if (name == "des-cbc") { - return EVP_des_cbc(); - } else if (name == "des-ecb") { - return EVP_des_ecb(); - } else if (name == "des-ede") { - return EVP_des_ede(); - } else if (name == "des-ede3") { - return EVP_des_ede3(); - } else if (name == "des-ede-cbc") { - return EVP_des_ede_cbc(); - } else if (name == "des-ede3-cbc") { - return EVP_des_ede3_cbc(); - } else if (name == "rc4") { - return EVP_rc4(); - } else if (name == "aes-128-ecb") { - return EVP_aes_128_ecb(); - } else if (name == "aes-256-ecb") { - return EVP_aes_256_ecb(); - } else if (name == "aes-128-cbc") { - return EVP_aes_128_cbc(); - } else if (name == "aes-128-gcm") { - return EVP_aes_128_gcm(); - } else if (name == "aes-128-ofb") { - return EVP_aes_128_ofb(); - } else if (name == "aes-192-cbc") { - return EVP_aes_192_cbc(); - } else if (name == "aes-192-ctr") { - return EVP_aes_192_ctr(); - } else if (name == "aes-192-ecb") { - return EVP_aes_192_ecb(); - } else if (name == "aes-256-cbc") { - return EVP_aes_256_cbc(); - } else if (name == "aes-128-ctr") { - return EVP_aes_128_ctr(); - } else if (name == "aes-256-ctr") { - return EVP_aes_256_ctr(); - } else if (name == "aes-256-gcm") { - return EVP_aes_256_gcm(); - } else if (name == "aes-256-ofb") { - return EVP_aes_256_ofb(); - } - return nullptr; -} - -bool CipherOperation(const EVP_CIPHER *cipher, std::vector *out, - bool encrypt, const std::vector &key, - const std::vector &iv, - const std::vector &in) { - bssl::ScopedEVP_CIPHER_CTX ctx; - if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr, - encrypt ? 1 : 0)) { - return false; - } - if (!iv.empty() && iv.size() != EVP_CIPHER_CTX_iv_length(ctx.get())) { - return false; - } - - int result_len1 = 0, result_len2; - *out = std::vector(in.size()); - if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()) || - !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data(), - -1) || - !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) || - !EVP_CipherUpdate(ctx.get(), out->data(), &result_len1, in.data(), - in.size()) || - !EVP_CipherFinal_ex(ctx.get(), out->data() + result_len1, &result_len2)) { - return false; - } - out->resize(result_len1 + result_len2); - - return true; -} - -bool AEADEncrypt(const EVP_AEAD *aead, std::vector *ct, - std::vector *tag, size_t tag_len, - const std::vector &key, - const std::vector &pt, - const std::vector &aad, - const std::vector &iv) { - bssl::ScopedEVP_AEAD_CTX ctx; - if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key.size(), tag_len, - nullptr)) { - return false; - } - - std::vector out; - out.resize(pt.size() + EVP_AEAD_max_overhead(aead)); - size_t out_len; - if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(), iv.data(), - iv.size(), pt.data(), pt.size(), aad.data(), - aad.size())) { - return false; - } - out.resize(out_len); - - ct->assign(out.begin(), out.end() - tag_len); - tag->assign(out.end() - tag_len, out.end()); - - return true; -} - -bool AEADDecrypt(const EVP_AEAD *aead, std::vector *pt, size_t pt_len, - const std::vector &key, - const std::vector &aad, - const std::vector &ct, - const std::vector &tag, - const std::vector &iv) { - bssl::ScopedEVP_AEAD_CTX ctx; - if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(), - tag.size(), evp_aead_open)) { - return false; - } - std::vector in = ct; - in.reserve(ct.size() + tag.size()); - in.insert(in.end(), tag.begin(), tag.end()); - - pt->resize(pt_len); - size_t out_pt_len; - if (!EVP_AEAD_CTX_open(ctx.get(), pt->data(), &out_pt_len, pt->size(), - iv.data(), iv.size(), in.data(), in.size(), aad.data(), - aad.size()) || - out_pt_len != pt_len) { - return false; - } - return true; -} - -static int HexToBIGNUM(bssl::UniquePtr *out, const char *in) { - BIGNUM *raw = NULL; - int ret = BN_hex2bn(&raw, in); - out->reset(raw); - return ret; -} - -bssl::UniquePtr GetBIGNUM(FileTest *t, const char *attribute) { - std::string hex; - if (!t->GetAttribute(&hex, attribute)) { - return nullptr; - } - - bssl::UniquePtr ret; - if (HexToBIGNUM(&ret, hex.c_str()) != static_cast(hex.size())) { - t->PrintLine("Could not decode '%s'.", hex.c_str()); - return nullptr; - } - return ret; -} - -int GetECGroupNIDFromInstruction(FileTest *t, const char **out_str) { - const char *dummy; - if (out_str == nullptr) { - out_str = &dummy; - } - - if (t->HasInstruction("P-224")) { - *out_str = "P-224"; - return NID_secp224r1; - } - if (t->HasInstruction("P-256")) { - *out_str = "P-256"; - return NID_X9_62_prime256v1; - } - if (t->HasInstruction("P-384")) { - *out_str = "P-384"; - return NID_secp384r1; - } - if (t->HasInstruction("P-521")) { - *out_str = "P-521"; - return NID_secp521r1; - } - t->PrintLine("No supported group specified."); - return NID_undef; -} - -const EVP_MD *GetDigestFromInstruction(FileTest *t) { - if (t->HasInstruction("SHA-1")) { - return EVP_sha1(); - } - if (t->HasInstruction("SHA-224")) { - return EVP_sha224(); - } - if (t->HasInstruction("SHA-256")) { - return EVP_sha256(); - } - if (t->HasInstruction("SHA-384")) { - return EVP_sha384(); - } - if (t->HasInstruction("SHA-512")) { - return EVP_sha512(); - } - t->PrintLine("No supported digest function specified."); - return nullptr; -} - -void EchoComment(const std::string& comment) { - fwrite(comment.c_str(), comment.size(), 1, stdout); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.h b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.h deleted file mode 100644 index d51dfe60..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_test_util.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2017, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_CAVP_TEST_UTIL_H -#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_CAVP_TEST_UTIL_H - -#include -#include -#include - -#include -#include - -#include "../crypto/test/file_test.h" - - -const EVP_CIPHER *GetCipher(const std::string &name); - -bool CipherOperation(const EVP_CIPHER *cipher, std::vector *out, - bool encrypt, const std::vector &key, - const std::vector &iv, - const std::vector &in); - -bool AEADEncrypt(const EVP_AEAD *aead, std::vector *ct, - std::vector *tag, size_t tag_len, - const std::vector &key, - const std::vector &pt, - const std::vector &aad, - const std::vector &iv); - -bool AEADDecrypt(const EVP_AEAD *aead, std::vector *pt, size_t pt_len, - const std::vector &key, - const std::vector &aad, - const std::vector &ct, - const std::vector &tag, - const std::vector &iv); - -bssl::UniquePtr GetBIGNUM(FileTest *t, const char *attribute); - -int GetECGroupNIDFromInstruction(FileTest *t, const char **out_str = nullptr); - -const EVP_MD *GetDigestFromInstruction(FileTest *t); - -void EchoComment(const std::string& comment); - -int cavp_aes_gcm_test_main(int argc, char **argv); -int cavp_aes_test_main(int argc, char **argv); -int cavp_ctr_drbg_test_main(int argc, char **argv); -int cavp_ecdsa2_keypair_test_main(int argc, char **argv); -int cavp_ecdsa2_pkv_test_main(int argc, char **argv); -int cavp_ecdsa2_siggen_test_main(int argc, char **argv); -int cavp_ecdsa2_sigver_test_main(int argc, char **argv); -int cavp_hmac_test_main(int argc, char **argv); -int cavp_kas_test_main(int argc, char **argv); -int cavp_keywrap_test_main(int argc, char **argv); -int cavp_rsa2_keygen_test_main(int argc, char **argv); -int cavp_rsa2_siggen_test_main(int argc, char **argv); -int cavp_rsa2_sigver_test_main(int argc, char **argv); -int cavp_sha_monte_test_main(int argc, char **argv); -int cavp_sha_test_main(int argc, char **argv); -int cavp_tdes_test_main(int argc, char **argv); -int cavp_tlskdf_test_main(int argc, char **argv); - - -#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_CAVP_TEST_UTIL_H diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tlskdf_test.cc b/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tlskdf_test.cc deleted file mode 100644 index 0243439d..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/cavp_tlskdf_test.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2018, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -// cavp_tlskdf_test processes NIST TLS KDF test vectors and emits the -// corresponding response. -// See https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/components/askdfvs.pdf, section 6.4. - -#include - -#include - -#include - -#include "cavp_test_util.h" -#include "../crypto/fipsmodule/tls/internal.h" -#include "../crypto/test/file_test.h" -#include "../crypto/test/test_util.h" - - -static bool TestTLSKDF(FileTest *t, void *arg) { - const EVP_MD *md = nullptr; - - if (t->HasInstruction("TLS 1.0/1.1")) { - md = EVP_md5_sha1(); - } else if (t->HasInstruction("TLS 1.2")) { - if (t->HasInstruction("SHA-256")) { - md = EVP_sha256(); - } else if (t->HasInstruction("SHA-384")) { - md = EVP_sha384(); - } else if (t->HasInstruction("SHA-512")) { - md = EVP_sha512(); - } - } - - if (md == nullptr) { - return false; - } - - std::string key_block_len_str; - std::vector premaster, server_random, client_random, - key_block_server_random, key_block_client_random; - if (!t->GetBytes(&premaster, "pre_master_secret") || - !t->GetBytes(&server_random, "serverHello_random") || - !t->GetBytes(&client_random, "clientHello_random") || - // The NIST tests specify different client and server randoms for the - // expansion step from the master-secret step. This is impossible in TLS. - !t->GetBytes(&key_block_server_random, "server_random") || - !t->GetBytes(&key_block_client_random, "client_random") || - !t->GetInstruction(&key_block_len_str, "key block length") || - // These are ignored. - !t->HasAttribute("COUNT") || - !t->HasInstruction("pre-master secret length")) { - return false; - } - - uint8_t master_secret[48]; - static const char kMasterSecretLabel[] = "master secret"; - if (!CRYPTO_tls1_prf(md, master_secret, sizeof(master_secret), - premaster.data(), premaster.size(), kMasterSecretLabel, - sizeof(kMasterSecretLabel) - 1, client_random.data(), - client_random.size(), server_random.data(), - server_random.size())) { - return false; - } - - errno = 0; - const long int key_block_bits = - strtol(key_block_len_str.c_str(), nullptr, 10); - if (errno != 0 || key_block_bits <= 0 || (key_block_bits & 7) != 0) { - return false; - } - const size_t key_block_len = key_block_bits / 8; - std::vector key_block(key_block_len); - static const char kLabel[] = "key expansion"; - if (!CRYPTO_tls1_prf( - md, key_block.data(), key_block.size(), master_secret, - sizeof(master_secret), kLabel, sizeof(kLabel) - 1, - key_block_server_random.data(), key_block_server_random.size(), - key_block_client_random.data(), key_block_client_random.size())) { - return false; - } - - printf("%smaster_secret = %s\r\nkey_block = %s\r\n\r\n", - t->CurrentTestToString().c_str(), EncodeHex(master_secret).c_str(), - EncodeHex(key_block).c_str()); - - return true; -} - -int cavp_tlskdf_test_main(int argc, char **argv) { - if (argc != 2) { - fprintf(stderr, "usage: %s \n", argv[0]); - return 1; - } - - FileTest::Options opts; - opts.path = argv[1]; - opts.callback = TestTLSKDF; - opts.silent = true; - opts.comment_callback = EchoComment; - return FileTestMain(opts); -} diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/run_cavp.go b/third_party/boringssl/kit/src/util/fipstools/cavp/run_cavp.go deleted file mode 100644 index 51a4100a..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/run_cavp.go +++ /dev/null @@ -1,592 +0,0 @@ -// run_cavp.go processes CAVP input files and generates suitable response -// files, optionally comparing the results against the provided FAX files. -package main - -import ( - "bufio" - "errors" - "flag" - "fmt" - "os" - "os/exec" - "path" - "path/filepath" - "runtime" - "strings" - "sync" - "time" -) - -var ( - oraclePath = flag.String("oracle-bin", "", "Path to the oracle binary") - suiteDir = flag.String("suite-dir", "", "Base directory containing the CAVP test suite") - noFAX = flag.Bool("no-fax", false, "Skip comparing against FAX files") - android = flag.Bool("android", false, "Run tests via ADB") -) - -const ( - androidTmpPath = "/data/local/tmp/" - androidCAVPPath = androidTmpPath + "cavp" - androidLibCryptoPath = androidTmpPath + "libcrypto.so" -) - -// test describes a single request file. -type test struct { - // inFile is the base of the filename without an extension, i.e. - // “ECBMCT128”. - inFile string - // args are the arguments (not including the input filename) to the - // oracle binary. - args []string - // noFAX, if true, indicates that the output cannot be compared against - // the FAX file. (E.g. because the primitive is non-deterministic.) - noFAX bool -} - -// nextLineState can be used by FAX next-line function to store state. -type nextLineState struct { - // State used by the KAS test. - nextIsIUTHash bool -} - -// testSuite describes a series of tests that are handled by a single oracle -// binary. -type testSuite struct { - // directory is the name of the directory in the CAVP input, i.e. “AES”. - directory string - // suite names the test suite to pass as the first command-line argument. - suite string - // nextLineFunc, if not nil, is the function used to read the next line - // from the FAX file. This can be used to skip lines and/or mutate them - // as needed. The second argument can be used by the scanner to store - // state, if needed. If isWildcard is true on return then line is not - // meaningful and any line from the response file should be accepted. - nextLineFunc func(*bufio.Scanner, *nextLineState) (line string, isWildcard, ok bool) - tests []test -} - -func (t *testSuite) getDirectory() string { - return filepath.Join(*suiteDir, t.directory) -} - -var aesGCMTests = testSuite{ - "AES_GCM", - "aes_gcm", - nil, - []test{ - {"gcmDecrypt128", []string{"dec", "aes-128-gcm"}, false}, - {"gcmDecrypt192", []string{"dec", "aes-192-gcm"}, false}, - {"gcmDecrypt256", []string{"dec", "aes-256-gcm"}, false}, - {"gcmEncryptExtIV128", []string{"enc", "aes-128-gcm"}, false}, - {"gcmEncryptExtIV192", []string{"enc", "aes-192-gcm"}, false}, - {"gcmEncryptExtIV256", []string{"enc", "aes-256-gcm"}, false}, - }, -} - -var aesTests = testSuite{ - "AES", - "aes", - nil, - []test{ - {"CBCGFSbox128", []string{"kat", "aes-128-cbc"}, false}, - {"CBCGFSbox192", []string{"kat", "aes-192-cbc"}, false}, - {"CBCGFSbox256", []string{"kat", "aes-256-cbc"}, false}, - {"CBCKeySbox128", []string{"kat", "aes-128-cbc"}, false}, - {"CBCKeySbox192", []string{"kat", "aes-192-cbc"}, false}, - {"CBCKeySbox256", []string{"kat", "aes-256-cbc"}, false}, - {"CBCMMT128", []string{"kat", "aes-128-cbc"}, false}, - {"CBCMMT192", []string{"kat", "aes-192-cbc"}, false}, - {"CBCMMT256", []string{"kat", "aes-256-cbc"}, false}, - {"CBCVarKey128", []string{"kat", "aes-128-cbc"}, false}, - {"CBCVarKey192", []string{"kat", "aes-192-cbc"}, false}, - {"CBCVarKey256", []string{"kat", "aes-256-cbc"}, false}, - {"CBCVarTxt128", []string{"kat", "aes-128-cbc"}, false}, - {"CBCVarTxt192", []string{"kat", "aes-192-cbc"}, false}, - {"CBCVarTxt256", []string{"kat", "aes-256-cbc"}, false}, - {"ECBGFSbox128", []string{"kat", "aes-128-ecb"}, false}, - {"ECBGFSbox192", []string{"kat", "aes-192-ecb"}, false}, - {"ECBGFSbox256", []string{"kat", "aes-256-ecb"}, false}, - {"ECBKeySbox128", []string{"kat", "aes-128-ecb"}, false}, - {"ECBKeySbox192", []string{"kat", "aes-192-ecb"}, false}, - {"ECBKeySbox256", []string{"kat", "aes-256-ecb"}, false}, - {"ECBMMT128", []string{"kat", "aes-128-ecb"}, false}, - {"ECBMMT192", []string{"kat", "aes-192-ecb"}, false}, - {"ECBMMT256", []string{"kat", "aes-256-ecb"}, false}, - {"ECBVarKey128", []string{"kat", "aes-128-ecb"}, false}, - {"ECBVarKey192", []string{"kat", "aes-192-ecb"}, false}, - {"ECBVarKey256", []string{"kat", "aes-256-ecb"}, false}, - {"ECBVarTxt128", []string{"kat", "aes-128-ecb"}, false}, - {"ECBVarTxt192", []string{"kat", "aes-192-ecb"}, false}, - {"ECBVarTxt256", []string{"kat", "aes-256-ecb"}, false}, - // AES Monte-Carlo tests - {"ECBMCT128", []string{"mct", "aes-128-ecb"}, false}, - {"ECBMCT192", []string{"mct", "aes-192-ecb"}, false}, - {"ECBMCT256", []string{"mct", "aes-256-ecb"}, false}, - {"CBCMCT128", []string{"mct", "aes-128-cbc"}, false}, - {"CBCMCT192", []string{"mct", "aes-192-cbc"}, false}, - {"CBCMCT256", []string{"mct", "aes-256-cbc"}, false}, - }, -} - -var ecdsa2KeyPairTests = testSuite{ - "ECDSA2", - "ecdsa2_keypair", - nil, - []test{{"KeyPair", nil, true}}, -} - -var ecdsa2PKVTests = testSuite{ - "ECDSA2", - "ecdsa2_pkv", - nil, - []test{{"PKV", nil, false}}, -} - -var ecdsa2SigGenTests = testSuite{ - "ECDSA2", - "ecdsa2_siggen", - nil, - []test{ - {"SigGen", []string{"SigGen"}, true}, - {"SigGenComponent", []string{"SigGenComponent"}, true}, - }, -} - -var ecdsa2SigVerTests = testSuite{ - "ECDSA2", - "ecdsa2_sigver", - nil, - []test{{"SigVer", nil, false}}, -} - -var rsa2KeyGenTests = testSuite{ - "RSA2", - "rsa2_keygen", - nil, - []test{ - {"KeyGen_RandomProbablyPrime3_3", nil, true}, - }, -} - -var rsa2SigGenTests = testSuite{ - "RSA2", - "rsa2_siggen", - nil, - []test{ - {"SigGen15_186-3", []string{"pkcs15"}, true}, - {"SigGenPSS_186-3", []string{"pss"}, true}, - }, -} - -var rsa2SigVerTests = testSuite{ - "RSA2", - "rsa2_sigver", - func(s *bufio.Scanner, state *nextLineState) (string, bool, bool) { - for { - if !s.Scan() { - return "", false, false - } - - line := s.Text() - if strings.HasPrefix(line, "p = ") || strings.HasPrefix(line, "d = ") || strings.HasPrefix(line, "SaltVal = ") || strings.HasPrefix(line, "EM with ") { - continue - } - if strings.HasPrefix(line, "q = ") { - // Skip the "q = " line and an additional blank line. - if !s.Scan() || - len(strings.TrimSpace(s.Text())) > 0 { - return "", false, false - } - continue - } - return line, false, true - } - }, - []test{ - {"SigVer15_186-3", []string{"pkcs15"}, false}, - {"SigVerPSS_186-3", []string{"pss"}, false}, - }, -} - -var hmacTests = testSuite{ - "HMAC", - "hmac", - nil, - []test{{"HMAC", nil, false}}, -} - -var shaTests = testSuite{ - "SHA", - "sha", - nil, - []test{ - {"SHA1LongMsg", []string{"SHA1"}, false}, - {"SHA1ShortMsg", []string{"SHA1"}, false}, - {"SHA224LongMsg", []string{"SHA224"}, false}, - {"SHA224ShortMsg", []string{"SHA224"}, false}, - {"SHA256LongMsg", []string{"SHA256"}, false}, - {"SHA256ShortMsg", []string{"SHA256"}, false}, - {"SHA384LongMsg", []string{"SHA384"}, false}, - {"SHA384ShortMsg", []string{"SHA384"}, false}, - {"SHA512LongMsg", []string{"SHA512"}, false}, - {"SHA512ShortMsg", []string{"SHA512"}, false}, - }, -} - -var shaMonteTests = testSuite{ - "SHA", - "sha_monte", - nil, - []test{ - {"SHA1Monte", []string{"SHA1"}, false}, - {"SHA224Monte", []string{"SHA224"}, false}, - {"SHA256Monte", []string{"SHA256"}, false}, - {"SHA384Monte", []string{"SHA384"}, false}, - {"SHA512Monte", []string{"SHA512"}, false}, - }, -} - -var ctrDRBGTests = testSuite{ - "DRBG800-90A", - "ctr_drbg", - nil, - []test{{"CTR_DRBG", nil, false}}, -} - -var tdesTests = testSuite{ - "TDES", - "tdes", - nil, - []test{ - {"TCBCMMT2", []string{"kat", "des-ede-cbc"}, false}, - {"TCBCMMT3", []string{"kat", "des-ede3-cbc"}, false}, - {"TCBCMonte2", []string{"mct", "des-ede3-cbc"}, false}, - {"TCBCMonte3", []string{"mct", "des-ede3-cbc"}, false}, - {"TCBCinvperm", []string{"kat", "des-ede3-cbc"}, false}, - {"TCBCpermop", []string{"kat", "des-ede3-cbc"}, false}, - {"TCBCsubtab", []string{"kat", "des-ede3-cbc"}, false}, - {"TCBCvarkey", []string{"kat", "des-ede3-cbc"}, false}, - {"TCBCvartext", []string{"kat", "des-ede3-cbc"}, false}, - {"TECBMMT2", []string{"kat", "des-ede"}, false}, - {"TECBMMT3", []string{"kat", "des-ede3"}, false}, - {"TECBMonte2", []string{"mct", "des-ede3"}, false}, - {"TECBMonte3", []string{"mct", "des-ede3"}, false}, - {"TECBinvperm", []string{"kat", "des-ede3"}, false}, - {"TECBpermop", []string{"kat", "des-ede3"}, false}, - {"TECBsubtab", []string{"kat", "des-ede3"}, false}, - {"TECBvarkey", []string{"kat", "des-ede3"}, false}, - {"TECBvartext", []string{"kat", "des-ede3"}, false}, - }, -} - -var keyWrapTests = testSuite{ - "KeyWrap38F", - "keywrap", - nil, - []test{ - {"KW_AD_128", []string{"dec", "128"}, false}, - {"KW_AD_192", []string{"dec", "192"}, false}, - {"KW_AD_256", []string{"dec", "256"}, false}, - {"KW_AE_128", []string{"enc", "128"}, false}, - {"KW_AE_192", []string{"enc", "192"}, false}, - {"KW_AE_256", []string{"enc", "256"}, false}, - {"KWP_AD_128", []string{"dec-pad", "128"}, false}, - {"KWP_AD_192", []string{"dec-pad", "192"}, false}, - {"KWP_AD_256", []string{"dec-pad", "256"}, false}, - {"KWP_AE_128", []string{"enc-pad", "128"}, false}, - {"KWP_AE_192", []string{"enc-pad", "192"}, false}, - {"KWP_AE_256", []string{"enc-pad", "256"}, false}, - }, -} - -var kasTests = testSuite{ - "KAS", - "kas", - func(s *bufio.Scanner, state *nextLineState) (line string, isWildcard, ok bool) { - for { - // If the response file will include the IUT hash next, - // return a wildcard signal because this cannot be - // matched against the FAX file. - if state.nextIsIUTHash { - state.nextIsIUTHash = false - return "", true, true - } - - if !s.Scan() { - return "", false, false - } - - line := s.Text() - if strings.HasPrefix(line, "deCAVS = ") || strings.HasPrefix(line, "Z = ") { - continue - } - if strings.HasPrefix(line, "CAVSHashZZ = ") { - state.nextIsIUTHash = true - } - return line, false, true - } - }, - []test{ - {"KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init", []string{"function"}, true}, - {"KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp", []string{"function"}, true}, - {"KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init", []string{"validity"}, false}, - {"KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp", []string{"validity"}, false}, - }, -} - -var tlsKDFTests = testSuite{ - "KDF135", - "tlskdf", - nil, - []test{ - {"tls", nil, false}, - }, -} - -var testSuites = []*testSuite{ - &aesGCMTests, - &aesTests, - &ctrDRBGTests, - &ecdsa2KeyPairTests, - &ecdsa2PKVTests, - &ecdsa2SigGenTests, - &ecdsa2SigVerTests, - &hmacTests, - &keyWrapTests, - &rsa2KeyGenTests, - &rsa2SigGenTests, - &rsa2SigVerTests, - &shaTests, - &shaMonteTests, - &tdesTests, - &kasTests, - &tlsKDFTests, -} - -// testInstance represents a specific test in a testSuite. -type testInstance struct { - suite *testSuite - testIndex int -} - -func worker(wg *sync.WaitGroup, work <-chan testInstance) { - defer wg.Done() - - for ti := range work { - test := ti.suite.tests[ti.testIndex] - - if err := doTest(ti.suite, test); err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(2) - } - - if !*noFAX && !test.noFAX { - if err := compareFAX(ti.suite, test); err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(3) - } - } - } -} - -func checkAndroidPrereqs() error { - // The cavp binary, and a matching libcrypto.so, are required to be placed - // in /data/local/tmp before running this script. - if err := exec.Command("adb", "shell", "ls", androidCAVPPath).Run(); err != nil { - return errors.New("failed to list cavp binary; ensure that adb works and cavp binary is in place: " + err.Error()) - } - if err := exec.Command("adb", "shell", "ls", androidLibCryptoPath).Run(); err != nil { - return errors.New("failed to list libcrypto.so; ensure that library is in place: " + err.Error()) - } - return nil -} - -func main() { - flag.Parse() - - if *android { - if err := checkAndroidPrereqs(); err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) - } - } else if len(*oraclePath) == 0 { - fmt.Fprintf(os.Stderr, "Must give -oracle-bin\n") - os.Exit(1) - } - - work := make(chan testInstance) - var wg sync.WaitGroup - - numWorkers := runtime.NumCPU() - if *android { - numWorkers = 1 - } - - for i := 0; i < numWorkers; i++ { - wg.Add(1) - go worker(&wg, work) - } - - for _, suite := range testSuites { - for i := range suite.tests { - work <- testInstance{suite, i} - } - } - - close(work) - wg.Wait() -} - -func doTest(suite *testSuite, test test) error { - bin := *oraclePath - var args []string - - if *android { - bin = "adb" - args = []string{"shell", "LD_LIBRARY_PATH=" + androidTmpPath, androidCAVPPath} - } - - args = append(args, suite.suite) - args = append(args, test.args...) - reqPath := filepath.Join(suite.getDirectory(), "req", test.inFile+".req") - var reqPathOnDevice string - - if *android { - reqPathOnDevice = path.Join(androidTmpPath, test.inFile+".req") - if err := exec.Command("adb", "push", reqPath, reqPathOnDevice).Run(); err != nil { - return errors.New("failed to push request file: " + err.Error()) - } - args = append(args, reqPathOnDevice) - } else { - args = append(args, reqPath) - } - - respDir := filepath.Join(suite.getDirectory(), "resp") - if err := os.Mkdir(respDir, 0755); err != nil && !os.IsExist(err) { - return fmt.Errorf("cannot create resp directory: %s", err) - } - outPath := filepath.Join(respDir, test.inFile+".rsp") - outFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) - if err != nil { - return fmt.Errorf("cannot open output file for %q %q: %s", suite.getDirectory(), test.inFile, err) - } - defer outFile.Close() - - cmd := exec.Command(bin, args...) - cmd.Stdout = outFile - cmd.Stderr = os.Stderr - - cmdLine := strings.Join(append([]string{bin}, args...), " ") - startTime := time.Now() - if err := cmd.Run(); err != nil { - return fmt.Errorf("cannot run command for %q %q (%s): %s", suite.getDirectory(), test.inFile, cmdLine, err) - } - - fmt.Printf("%s (%ds)\n", cmdLine, int(time.Since(startTime).Seconds())) - - if *android { - exec.Command("adb", "shell", "rm", reqPathOnDevice).Run() - } - - return nil -} - -func canonicalizeLine(in string) string { - if strings.HasPrefix(in, "Result = P (") { - return "Result = P" - } - if strings.HasPrefix(in, "Result = F (") { - return "Result = F" - } - return in -} - -func compareFAX(suite *testSuite, test test) error { - nextLineFunc := suite.nextLineFunc - if nextLineFunc == nil { - nextLineFunc = func(s *bufio.Scanner, state *nextLineState) (string, bool, bool) { - if !s.Scan() { - return "", false, false - } - return s.Text(), false, true - } - } - - respPath := filepath.Join(suite.getDirectory(), "resp", test.inFile+".rsp") - respFile, err := os.Open(respPath) - if err != nil { - return fmt.Errorf("cannot read output of %q %q: %s", suite.getDirectory(), test.inFile, err) - } - defer respFile.Close() - - faxPath := filepath.Join(suite.getDirectory(), "fax", test.inFile+".fax") - faxFile, err := os.Open(faxPath) - if err != nil { - return fmt.Errorf("cannot open fax file for %q %q: %s", suite.getDirectory(), test.inFile, err) - } - defer faxFile.Close() - - respScanner := bufio.NewScanner(respFile) - faxScanner := bufio.NewScanner(faxFile) - var nextLineState nextLineState - - lineNo := 0 - inHeader := true - - for respScanner.Scan() { - lineNo++ - respLine := respScanner.Text() - var faxLine string - var isWildcard, ok bool - - if inHeader && (len(respLine) == 0 || respLine[0] == '#') { - continue - } - - for { - haveFaxLine := false - - if inHeader { - for { - if faxLine, isWildcard, ok = nextLineFunc(faxScanner, &nextLineState); !ok { - break - } - if len(faxLine) != 0 && faxLine[0] != '#' { - haveFaxLine = true - break - } - } - - inHeader = false - } else { - faxLine, isWildcard, haveFaxLine = nextLineFunc(faxScanner, &nextLineState) - } - - if !haveFaxLine { - // Ignore blank lines at the end of the generated file. - if len(respLine) == 0 { - break - } - return fmt.Errorf("resp file is longer than fax for %q %q", suite.getDirectory(), test.inFile) - } - - if strings.HasPrefix(faxLine, " (Reason: ") { - continue - } - - break - } - - if isWildcard || canonicalizeLine(faxLine) == canonicalizeLine(respLine) { - continue - } - - return fmt.Errorf("resp and fax differ at line %d for %q %q: %q vs %q", lineNo, suite.getDirectory(), test.inFile, respLine, faxLine) - } - - if _, _, ok := nextLineFunc(faxScanner, &nextLineState); ok { - return fmt.Errorf("fax file is longer than resp for %q %q", suite.getDirectory(), test.inFile) - } - - return nil -} diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.go b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.go index 2d92520d..b801d6df 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.go +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.go @@ -10,18 +10,20 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // delocate performs several transformations of textual assembly code. See // crypto/fipsmodule/FIPS.md for an overview. package main import ( + "bytes" "errors" "flag" "fmt" - "io/ioutil" "os" + "os/exec" + "path/filepath" "sort" "strconv" "strings" @@ -52,8 +54,7 @@ type stringWriter interface { type processorType int const ( - ppc64le processorType = iota + 1 - x86_64 + x86_64 processorType = iota + 1 aarch64 ) @@ -66,8 +67,6 @@ type delocation struct { // symbols is the set of symbols defined in the module. symbols map[string]struct{} - // localEntrySymbols is the set of symbols with .localentry directives. - localEntrySymbols map[string]struct{} // redirectors maps from out-call symbol name to the name of a // redirector function for that symbol. E.g. “memcpy” -> // “bcm_redirector_memcpy”. @@ -76,9 +75,6 @@ type delocation struct { // should be used to reference it. E.g. “P384_data_storage” -> // “P384_data_storage”. bssAccessorsNeeded map[string]string - // tocLoaders is a set of symbol names for which TOC helper functions - // are required. (ppc64le only.) - tocLoaders map[string]struct{} // gotExternalsNeeded is a set of symbol names for which we need // “delta” symbols: symbols that contain the offset from their location // to the memory in question. @@ -155,8 +151,6 @@ func (d *delocation) processInput(input inputFile) (err error) { switch d.processor { case x86_64: statement, err = d.processIntelInstruction(statement, node.up) - case ppc64le: - statement, err = d.processPPCInstruction(statement, node.up) case aarch64: statement, err = d.processAarch64Instruction(statement, node.up) default: @@ -253,7 +247,7 @@ func (d *delocation) processDirective(statement, directive *node32) (*node32, er d.writeNode(statement) break - case ".debug", ".note", ".toc": + case ".debug", ".note": d.writeNode(statement) break @@ -313,10 +307,6 @@ func (d *delocation) processLabelContainingDirective(statement, directive *node3 d.output.WriteString("\t" + name + "\t" + strings.Join(args, ", ") + "\n") } - if name == ".localentry" { - d.output.WriteString(localEntryName(args[0]) + ":\n") - } - return statement, nil } @@ -439,7 +429,7 @@ func (d *delocation) processAarch64Instruction(statement, instruction *node32) ( argNodes := instructionArgs(instruction.next) switch instructionName { - case "cset", "csel", "csetm", "cneg", "csinv", "cinc", "csinc", "csneg": + case "ccmn", "ccmp", "cinc", "cinv", "cneg", "csel", "cset", "csetm", "csinc", "csinv", "csneg": // These functions are special because they take a condition-code name as // an argument and that looks like a symbol reference. d.writeNode(statement) @@ -509,7 +499,7 @@ func (d *delocation) processAarch64Instruction(statement, instruction *node32) ( // This is a branch. Either the target needs to be written to a local // version of the symbol to ensure that no relocations are emitted, or // it needs to jump to a redirector function. - symbol, _, _, didChange, symbolIsLocal, _ := d.parseMemRef(arg.up) + symbol, offset, _, didChange, symbolIsLocal, _ := d.parseMemRef(arg.up) changed = didChange if _, knownSymbol := d.symbols[symbol]; knownSymbol { @@ -520,6 +510,13 @@ func (d *delocation) processAarch64Instruction(statement, instruction *node32) ( d.redirectors[symbol] = redirector symbol = redirector changed = true + } else if didChange && symbolIsLocal && len(offset) > 0 { + // didChange is set when the inputFile index is not 0; which is the index of the + // first file copied to the output, which is the generated assembly of bcm.c. + // In subsequently copied assembly files, local symbols are changed by appending (BCM_ + index) + // in order to ensure they don't collide. `index` gets incremented per file. + // If there is offset after the symbol, append the `offset`. + symbol = symbol + offset } args = append(args, symbol) @@ -620,191 +617,6 @@ func (d *delocation) processAarch64Instruction(statement, instruction *node32) ( return statement, nil } -/* ppc64le - -[PABI]: “64-Bit ELF V2 ABI Specification. Power Architecture.” March 21st, - 2017 - -(Also useful is “Power ISA Version 2.07 B”. Note that version three of that -document is /not/ good as that's POWER9 specific.) - -ppc64le doesn't have IP-relative addressing and does a lot to work around this. -Rather than reference a PLT and GOT direction, it has a single structure called -the TOC (Table Of Contents). Within the TOC is the contents of .rodata, .data, -.got, .plt, .bss, etc sections [PABI;3.3]. - -A pointer to the TOC is maintained in r2 and the following pattern is used to -load the address of an element into a register: - - addis
    , 2, foo@toc@ha - addi
    ,
    , foo@toc@l - -The “addis” instruction shifts a signed constant left 16 bits and adds the -result to its second argument, saving the result in the first argument. The -“addi” instruction does the same, but without shifting. Thus the “@toc@ha" -suffix on a symbol means “the top 16 bits of the TOC offset” and “@toc@l” means -“the bottom 16 bits of the offset”. However, note that both values are signed, -thus offsets in the top half of a 64KB chunk will have an @ha value that's one -greater than expected and a negative @l value. - -The TOC is specific to a “module” (basically an executable or shared object). -This means that there's not a single TOC in a process and that r2 needs to -change as control moves between modules. Thus functions have two entry points: -the “global” entry point and the “local” entry point. Jumps from within the -same module can use the local entry while jumps from other modules must use the -global entry. The global entry establishes the correct value of r2 before -running the function and the local entry skips that code. - -The global entry point for a function is defined by its label. The local entry -is a power-of-two number of bytes from the global entry, set by the -“.localentry” directive. (ppc64le instructions are always 32 bits, so an offset -of 1 or 2 bytes is treated as an offset of zero.) - -In order to help the global entry code set r2 to point to the local TOC, r12 is -set to the address of the global entry point when called [PABI;2.2.1.1]. Thus -the global entry will typically use an addis+addi pair to add a known offset to -r12 and store it in r2. For example: - -foo: - addis 2, 12, .TOC. - foo@ha - addi 2, 2, .TOC. - foo@l - -(It's worth noting that the '@' operator binds very loosely, so the 3rd -arguments parse as (.TOC. - foo)@ha and (.TOC. - foo)@l.) - -When calling a function, the compiler doesn't know whether that function is in -the same module or not. Thus it doesn't know whether r12 needs to be set nor -whether r2 will be clobbered on return. Rather than always assume the worst, -the linker fixes stuff up once it knows that a call is going out of module: - -Firstly, calling, say, memcpy (which we assume to be in a different module) -won't actually jump directly to memcpy, or even a PLT resolution function. -It'll call a synthesised function that: - a) saves r2 in the caller's stack frame - b) loads the address of memcpy@PLT into r12 - c) jumps to r12. - -As this synthesised function loads memcpy@PLT, a call to memcpy from the -compiled code just references “memcpy” directly, not “memcpy@PLT”. - -Since it jumps directly to memcpy@PLT, it can't restore r2 on return. Thus -calls must be followed by a nop. If the call ends up going out-of-module, the -linker will rewrite that nop to load r2 from the stack. - -Speaking of the stack, the stack pointer is kept in r1 and there's a 288-byte -red-zone. The format of the stack frame is defined [PABI;2.2.2] and must be -followed as called functions will write into their parent's stack frame. For -example, the synthesised out-of-module trampolines will save r2 24 bytes into -the caller's frame and all non-leaf functions save the return address 16 bytes -into the caller's frame. - -A final point worth noting: some RISC ISAs have r0 wired to zero: all reads -result in zero and all writes are discarded. POWER does something a little like -that, but r0 is only special in certain argument positions for certain -instructions. You just have to read the manual to know which they are. - - -Delocation is easier than Intel because there's just TOC references, but it's -also harder because there's no IP-relative addressing. - -Jumps are IP-relative however, and have a 24-bit immediate value. So we can -jump to functions that set a register to the needed value. (r3 is the -return-value register and so that's what is generally used here.) */ - -// isPPC64LEAPair recognises an addis+addi pair that's adding the offset of -// source to relative and writing the result to target. -func (d *delocation) isPPC64LEAPair(statement *node32) (target, source, relative string, ok bool) { - instruction := skipWS(statement.up).up - assertNodeType(instruction, ruleInstructionName) - name1 := d.contents(instruction) - args1 := instructionArgs(instruction.next) - - statement = statement.next - instruction = skipWS(statement.up).up - assertNodeType(instruction, ruleInstructionName) - name2 := d.contents(instruction) - args2 := instructionArgs(instruction.next) - - if name1 != "addis" || - len(args1) != 3 || - name2 != "addi" || - len(args2) != 3 { - return "", "", "", false - } - - target = d.contents(args1[0]) - relative = d.contents(args1[1]) - source1 := d.contents(args1[2]) - source2 := d.contents(args2[2]) - - if !strings.HasSuffix(source1, "@ha") || - !strings.HasSuffix(source2, "@l") || - source1[:len(source1)-3] != source2[:len(source2)-2] || - d.contents(args2[0]) != target || - d.contents(args2[1]) != target { - return "", "", "", false - } - - source = source1[:len(source1)-3] - ok = true - return -} - -// establishTOC writes the global entry prelude for a function. The standard -// prelude involves relocations so this version moves the relocation outside -// the integrity-checked area. -func establishTOC(w stringWriter) { - w.WriteString("999:\n") - w.WriteString("\taddis 2, 12, .LBORINGSSL_external_toc-999b@ha\n") - w.WriteString("\taddi 2, 2, .LBORINGSSL_external_toc-999b@l\n") - w.WriteString("\tld 12, 0(2)\n") - w.WriteString("\tadd 2, 2, 12\n") -} - -// loadTOCFuncName returns the name of a synthesized function that sets r3 to -// the value of “symbol+offset”. -func loadTOCFuncName(symbol, offset string) string { - symbol = strings.Replace(symbol, ".", "_dot_", -1) - ret := ".Lbcm_loadtoc_" + symbol - if len(offset) != 0 { - offset = strings.Replace(offset, "+", "_plus_", -1) - offset = strings.Replace(offset, "-", "_minus_", -1) - ret += "_" + offset - } - return ret -} - -func (d *delocation) loadFromTOC(w stringWriter, symbol, offset, dest string) wrapperFunc { - d.tocLoaders[symbol+"\x00"+offset] = struct{}{} - - return func(k func()) { - w.WriteString("\taddi 1, 1, -288\n") // Clear the red zone. - w.WriteString("\tmflr " + dest + "\n") // Stash the link register. - w.WriteString("\tstd " + dest + ", -8(1)\n") - // The TOC loader will use r3, so stash it if necessary. - if dest != "3" { - w.WriteString("\tstd 3, -16(1)\n") - } - - // Because loadTOCFuncName returns a “.L” name, we don't need a - // nop after this call. - w.WriteString("\tbl " + loadTOCFuncName(symbol, offset) + "\n") - - // Cycle registers around. We need r3 -> destReg, -8(1) -> - // lr and, optionally, -16(1) -> r3. - w.WriteString("\tstd 3, -24(1)\n") - w.WriteString("\tld 3, -8(1)\n") - w.WriteString("\tmtlr 3\n") - w.WriteString("\tld " + dest + ", -24(1)\n") - if dest != "3" { - w.WriteString("\tld 3, -16(1)\n") - } - w.WriteString("\taddi 1, 1, 288\n") - - k() - } -} - func (d *delocation) gatherOffsets(symRef *node32, offsets string) (*node32, string) { for symRef != nil && symRef.pegRule == ruleOffset { offset := d.contents(symRef) @@ -859,215 +671,6 @@ func (d *delocation) parseMemRef(memRef *node32) (symbol, offset, section string return } -func (d *delocation) processPPCInstruction(statement, instruction *node32) (*node32, error) { - assertNodeType(instruction, ruleInstructionName) - instructionName := d.contents(instruction) - isBranch := instructionName[0] == 'b' - - argNodes := instructionArgs(instruction.next) - - var wrappers wrapperStack - var args []string - changed := false - -Args: - for i, arg := range argNodes { - fullArg := arg - isIndirect := false - - if arg.pegRule == ruleIndirectionIndicator { - arg = arg.next - isIndirect = true - } - - switch arg.pegRule { - case ruleRegisterOrConstant, ruleLocalLabelRef: - args = append(args, d.contents(fullArg)) - - case ruleTOCRefLow: - return nil, errors.New("Found low TOC reference outside preamble pattern") - - case ruleTOCRefHigh: - target, _, relative, ok := d.isPPC64LEAPair(statement) - if !ok { - return nil, errors.New("Found high TOC reference outside preamble pattern") - } - - if relative != "12" { - return nil, fmt.Errorf("preamble is relative to %q, not r12", relative) - } - - if target != "2" { - return nil, fmt.Errorf("preamble is setting %q, not r2", target) - } - - statement = statement.next - establishTOC(d.output) - instructionName = "" - changed = true - break Args - - case ruleMemoryRef: - symbol, offset, section, didChange, symbolIsLocal, memRef := d.parseMemRef(arg.up) - changed = didChange - - if len(symbol) > 0 { - if _, localEntrySymbol := d.localEntrySymbols[symbol]; localEntrySymbol && isBranch { - symbol = localEntryName(symbol) - changed = true - } else if _, knownSymbol := d.symbols[symbol]; knownSymbol { - symbol = localTargetName(symbol) - changed = true - } else if !symbolIsLocal && !isSynthesized(symbol) && len(section) == 0 { - changed = true - d.redirectors[symbol] = redirectorName(symbol) - symbol = redirectorName(symbol) - // TODO(davidben): This should sanity-check the next - // instruction is a nop and ideally remove it. - wrappers = append(wrappers, func(k func()) { - k() - // Like the linker's PLT stubs, redirector functions - // expect callers to restore r2. - d.output.WriteString("\tld 2, 24(1)\n") - }) - } - } - - switch section { - case "": - - case "tls": - // This section identifier just tells the - // assembler to use r13, the pointer to the - // thread-local data [PABI;3.7.3.3]. - - case "toc@ha": - // Delete toc@ha instructions. Per - // [PABI;3.6.3], the linker is allowed to erase - // toc@ha instructions. We take advantage of - // this by unconditionally erasing the toc@ha - // instructions and doing the full lookup when - // processing toc@l. - // - // Note that any offset here applies before @ha - // and @l. That is, 42+foo@toc@ha is - // #ha(42+foo-.TOC.), not 42+#ha(foo-.TOC.). Any - // corresponding toc@l references are required - // by the ABI to have the same offset. The - // offset will be incorporated in full when - // those are processed. - if instructionName != "addis" || len(argNodes) != 3 || i != 2 || args[1] != "2" { - return nil, errors.New("can't process toc@ha reference") - } - changed = true - instructionName = "" - break Args - - case "toc@l": - // Per [PAB;3.6.3], this instruction must take - // as input a register which was the output of - // a toc@ha computation and compute the actual - // address of some symbol. The toc@ha - // computation was elided, so we ignore that - // input register and compute the address - // directly. - changed = true - - // For all supported toc@l instructions, the - // destination register is the first argument. - destReg := args[0] - - wrappers = append(wrappers, d.loadFromTOC(d.output, symbol, offset, destReg)) - switch instructionName { - case "addi": - // The original instruction was: - // addi destReg, tocHaReg, offset+symbol@toc@l - instructionName = "" - - case "ld", "lhz", "lwz": - // The original instruction was: - // l?? destReg, offset+symbol@toc@l(tocHaReg) - // - // We transform that into the - // equivalent dereference of destReg: - // l?? destReg, 0(destReg) - origInstructionName := instructionName - instructionName = "" - - assertNodeType(memRef, ruleBaseIndexScale) - assertNodeType(memRef.up, ruleRegisterOrConstant) - if memRef.next != nil || memRef.up.next != nil { - return nil, errors.New("expected single register in BaseIndexScale for ld argument") - } - - baseReg := destReg - if baseReg == "0" { - // Register zero is special as the base register for a load. - // Avoid it by spilling and using r3 instead. - baseReg = "3" - wrappers = append(wrappers, func(k func()) { - d.output.WriteString("\taddi 1, 1, -288\n") // Clear the red zone. - d.output.WriteString("\tstd " + baseReg + ", -8(1)\n") - d.output.WriteString("\tmr " + baseReg + ", " + destReg + "\n") - k() - d.output.WriteString("\tld " + baseReg + ", -8(1)\n") - d.output.WriteString("\taddi 1, 1, 288\n") // Clear the red zone. - }) - } - - wrappers = append(wrappers, func(k func()) { - d.output.WriteString("\t" + origInstructionName + " " + destReg + ", 0(" + baseReg + ")\n") - }) - default: - return nil, fmt.Errorf("can't process TOC argument to %q", instructionName) - } - - default: - return nil, fmt.Errorf("Unknown section type %q", section) - } - - argStr := "" - if isIndirect { - argStr += "*" - } - argStr += symbol - if len(offset) > 0 { - argStr += offset - } - if len(section) > 0 { - argStr += "@" - argStr += section - } - - for ; memRef != nil; memRef = memRef.next { - argStr += d.contents(memRef) - } - - args = append(args, argStr) - - default: - panic(fmt.Sprintf("unknown instruction argument type %q", rul3s[arg.pegRule])) - } - } - - if changed { - d.writeCommentedNode(statement) - - var replacement string - if len(instructionName) > 0 { - replacement = "\t" + instructionName + "\t" + strings.Join(args, ", ") + "\n" - } - - wrappers.do(func() { - d.output.WriteString(replacement) - }) - } else { - d.writeNode(statement) - } - - return statement, nil -} - /* Intel */ type instructionType int @@ -1665,8 +1268,6 @@ func writeAarch64Function(w stringWriter, funcName string, writeContents func(st func transform(w stringWriter, inputs []inputFile) error { // symbols contains all defined symbols. symbols := make(map[string]struct{}) - // localEntrySymbols contains all symbols with a .localentry directive. - localEntrySymbols := make(map[string]struct{}) // fileNumbers is the set of IDs seen in .file directives. fileNumbers := make(map[int]struct{}) // maxObservedFileNumber contains the largest seen file number in a @@ -1689,25 +1290,6 @@ func transform(w stringWriter, inputs []inputFile) error { symbols[symbol] = struct{}{} }, ruleStatement, ruleLabel, ruleSymbolName) - forEachPath(input.ast.up, func(node *node32) { - node = node.up - assertNodeType(node, ruleLabelContainingDirectiveName) - directive := input.contents[node.begin:node.end] - if directive != ".localentry" { - return - } - // Extract the first argument. - node = skipWS(node.next) - assertNodeType(node, ruleSymbolArgs) - node = node.up - assertNodeType(node, ruleSymbolArg) - symbol := input.contents[node.begin:node.end] - if _, ok := localEntrySymbols[symbol]; ok { - panic(fmt.Sprintf("Duplicate .localentry directive found: %q in %q", symbol, input.path)) - } - localEntrySymbols[symbol] = struct{}{} - }, ruleStatement, ruleLabelContainingDirective) - forEachPath(input.ast.up, func(node *node32) { assertNodeType(node, ruleLocationDirective) directive := input.contents[node.begin:node.end] @@ -1756,13 +1338,11 @@ func transform(w stringWriter, inputs []inputFile) error { d := &delocation{ symbols: symbols, - localEntrySymbols: localEntrySymbols, processor: processor, commentIndicator: commentIndicator, output: w, redirectors: make(map[string]string), bssAccessorsNeeded: make(map[string]string), - tocLoaders: make(map[string]struct{}), gotExternalsNeeded: make(map[string]struct{}), gotOffsetsNeeded: make(map[string]struct{}), gotOffOffsetsNeeded: make(map[string]struct{}), @@ -1797,22 +1377,6 @@ func transform(w stringWriter, inputs []inputFile) error { for _, name := range redirectorNames { redirector := d.redirectors[name] switch d.processor { - case ppc64le: - w.WriteString(".section \".toc\", \"aw\"\n") - w.WriteString(".Lredirector_toc_" + name + ":\n") - w.WriteString(".quad " + name + "\n") - w.WriteString(".text\n") - w.WriteString(".type " + redirector + ", @function\n") - w.WriteString(redirector + ":\n") - // |name| will clobber r2, so save it. This is matched by a restore in - // redirector calls. - w.WriteString("\tstd 2, 24(1)\n") - // Load and call |name|'s global entry point. - w.WriteString("\taddis 12, 2, .Lredirector_toc_" + name + "@toc@ha\n") - w.WriteString("\tld 12, .Lredirector_toc_" + name + "@toc@l(12)\n") - w.WriteString("\tmtctr 12\n") - w.WriteString("\tbctr\n") - case aarch64: writeAarch64Function(w, redirector, func(w stringWriter) { w.WriteString("\tb " + name + "\n") @@ -1837,13 +1401,6 @@ func transform(w stringWriter, inputs []inputFile) error { target := d.bssAccessorsNeeded[name] switch d.processor { - case ppc64le: - w.WriteString(".type " + funcName + ", @function\n") - w.WriteString(funcName + ":\n") - w.WriteString("\taddis 3, 2, " + target + "@toc@ha\n") - w.WriteString("\taddi 3, 3, " + target + "@toc@l\n") - w.WriteString("\tblr\n") - case x86_64: w.WriteString(".type " + funcName + ", @function\n") w.WriteString(funcName + ":\n") @@ -1859,26 +1416,6 @@ func transform(w stringWriter, inputs []inputFile) error { } switch d.processor { - case ppc64le: - loadTOCNames := sortedSet(d.tocLoaders) - for _, symbolAndOffset := range loadTOCNames { - parts := strings.SplitN(symbolAndOffset, "\x00", 2) - symbol, offset := parts[0], parts[1] - - funcName := loadTOCFuncName(symbol, offset) - ref := symbol + offset - - w.WriteString(".type " + funcName[2:] + ", @function\n") - w.WriteString(funcName[2:] + ":\n") - w.WriteString(funcName + ":\n") - w.WriteString("\taddis 3, 2, " + ref + "@toc@ha\n") - w.WriteString("\taddi 3, 3, " + ref + "@toc@l\n") - w.WriteString("\tblr\n") - } - - w.WriteString(".LBORINGSSL_external_toc:\n") - w.WriteString(".quad .TOC.-.LBORINGSSL_external_toc\n") - case aarch64: externalNames := sortedSet(d.gotExternalsNeeded) for _, symbol := range externalNames { @@ -1940,7 +1477,7 @@ func transform(w stringWriter, inputs []inputFile) error { } w.WriteString(".type BORINGSSL_bcm_text_hash, @object\n") - w.WriteString(".size BORINGSSL_bcm_text_hash, 64\n") + w.WriteString(".size BORINGSSL_bcm_text_hash, 32\n") w.WriteString("BORINGSSL_bcm_text_hash:\n") for _, b := range fipscommon.UninitHashValue { w.WriteString(".byte 0x" + strconv.FormatUint(uint64(b), 16) + "\n") @@ -1949,7 +1486,25 @@ func transform(w stringWriter, inputs []inputFile) error { return nil } -func parseInputs(inputs []inputFile) error { +// preprocess runs source through the C preprocessor. +func preprocess(cppCommand []string, path string) ([]byte, error) { + var args []string + args = append(args, cppCommand...) + args = append(args, path) + + cpp := exec.Command(args[0], args[1:]...) + cpp.Stderr = os.Stderr + var result bytes.Buffer + cpp.Stdout = &result + + if err := cpp.Run(); err != nil { + return nil, err + } + + return result.Bytes(), nil +} + +func parseInputs(inputs []inputFile, cppCommand []string) error { for i, input := range inputs { var contents string @@ -1973,7 +1528,14 @@ func parseInputs(inputs []inputFile) error { contents = string(c) } } else { - inBytes, err := ioutil.ReadFile(input.path) + var inBytes []byte + var err error + + if len(cppCommand) > 0 { + inBytes, err = preprocess(cppCommand, input.path) + } else { + inBytes, err = os.ReadFile(input.path) + } if err != nil { return err } @@ -1995,12 +1557,36 @@ func parseInputs(inputs []inputFile) error { return nil } +// includePathFromHeaderFilePath returns an include directory path based on the +// path of a specific header file. It walks up the path and assumes that the +// include files are rooted in a directory called "openssl". +func includePathFromHeaderFilePath(path string) (string, error) { + dir := path + for { + var file string + dir, file = filepath.Split(dir) + + if file == "openssl" { + return dir, nil + } + + if len(dir) == 0 { + break + } + dir = dir[:len(dir)-1] + } + + return "", fmt.Errorf("failed to find 'openssl' path element in header file path %q", path) +} + func main() { // The .a file, if given, is expected to be an archive of textual // assembly sources. That's odd, but CMake really wants to create // archive files so it's the only way that we can make it work. arInput := flag.String("a", "", "Path to a .a file containing assembly sources") outFile := flag.String("o", "", "Path to output assembly") + ccPath := flag.String("cc", "", "Path to the C compiler for preprocessing inputs") + ccFlags := flag.String("cc-flags", "", "Flags for the C compiler when preprocessing") flag.Parse() @@ -2018,18 +1604,49 @@ func main() { }) } + includePaths := make(map[string]struct{}) + for i, path := range flag.Args() { if len(path) == 0 { continue } + // Header files are not processed but their path is remembered + // and passed as -I arguments when invoking the preprocessor. + if strings.HasSuffix(path, ".h") { + dir, err := includePathFromHeaderFilePath(path) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + includePaths[dir] = struct{}{} + continue + } + inputs = append(inputs, inputFile{ path: path, index: i + 1, }) } - if err := parseInputs(inputs); err != nil { + var cppCommand []string + if len(*ccPath) > 0 { + cppCommand = append(cppCommand, *ccPath) + cppCommand = append(cppCommand, strings.Fields(*ccFlags)...) + // Some of ccFlags might be superfluous when running the + // preprocessor, but we don't want the compiler complaining that + // "argument unused during compilation". + cppCommand = append(cppCommand, "-Wno-unused-command-line-argument") + + for includePath := range includePaths { + cppCommand = append(cppCommand, "-I"+includePath) + } + + // -E requests only preprocessing. + cppCommand = append(cppCommand, "-E") + } + + if err := parseInputs(inputs, cppCommand); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) } @@ -2109,10 +1726,6 @@ func localTargetName(name string) string { return ".L" + name + "_local_target" } -func localEntryName(name string) string { - return ".L" + name + "_local_entry" -} - func isSynthesized(symbol string) bool { return strings.HasSuffix(symbol, "_bss_get") || symbol == "OPENSSL_ia32cap_get" || @@ -2168,8 +1781,6 @@ func detectProcessor(input inputFile) processorType { switch instructionName { case "movq", "call", "leaq": return x86_64 - case "addis", "addi", "mflr": - return ppc64le case "str", "bl", "ldr", "st1": return aarch64 } diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg index f79ed76e..9db3e8cf 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg @@ -12,10 +12,17 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -# This is a rough parser for x86-64 and ppc64le assembly designed to work with +# This is a rough parser for x86-64 and aarch64 assembly designed to work with # https://github.com/pointlander/peg. delocate.go has a go:generate line for # rebuilding delocate.peg.go from this file. +# To regenerate delocate.peg.go: +# +# go install github.com/pointlander/peg@latest +# ~/go/bin/peg +# +# this will generate delocate.peg.go next to delocate.peg. + package main type Asm Peg {} @@ -44,7 +51,7 @@ SymbolShift <- ('<<' / '>>') WS? [0-9]+ SymbolArg <- (OpenParen WS?)? ( Offset / SymbolType / - (Offset / LocalSymbol / SymbolName / Dot) WS? Operator WS? (Offset / LocalSymbol / SymbolName) / + (Offset / LocalSymbol / SymbolName / Dot) (WS? Operator WS? (Offset / LocalSymbol / SymbolName))* / LocalSymbol TCMarker? / SymbolName Offset / SymbolName TCMarker?) @@ -77,8 +84,8 @@ RegisterOrConstant <- (('%'[[A-Z]][[A-Z0-9]]*) / ('#' '~'? '(' [0-9] WS? "<<" WS? [0-9] ')' ) / ARMRegister) ![fb:(+\-] -ARMConstantTweak <- ("lsl" / "sxtw" / "sxtb" / "uxtw" / "uxtb" / "lsr" / "ror" / "asr") (WS '#' Offset)? -ARMRegister <- "sp" / ([xwdqs] [0-9] [0-9]?) / "xzr" / "wzr" / ARMVectorRegister / ('{' WS? ARMVectorRegister (',' WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')? ) +ARMConstantTweak <- (([us] "xt" [xwhb]) / "lsl" / "lsr" / "ror" / "asr") (WS '#' Offset)? +ARMRegister <- "sp" / ([xwdqshb] [0-9] [0-9]?) / "xzr" / "wzr" / "NZCV" / ARMVectorRegister / ('{' WS? ARMVectorRegister (',' WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')? ) ARMVectorRegister <- "v" [0-9] [0-9]? ('.' [0-9]* [bsdhq] ('[' [0-9] [0-9]? ']')? )? # Compilers only output a very limited number of expression forms. Rather than # implement a full expression parser, this enumerate those forms plus a few @@ -94,7 +101,7 @@ MemoryRef <- (SymbolRef BaseIndexScale / BaseIndexScale) SymbolRef <- (Offset* '+')? (LocalSymbol / SymbolName) Offset* ('@' Section Offset*)? Low12BitsSymbolRef <- ":lo12:" (LocalSymbol / SymbolName) Offset? -ARMBaseIndexScale <- '[' ARMRegister (',' WS? (('#' Offset ('*' [0-9]+)? ) / ARMGOTLow12 / Low12BitsSymbolRef / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement? +ARMBaseIndexScale <- '[' ARMRegister (',' WS? (('#' Offset (('*' [0-9]+) / ('*' '(' [0-9]+ Operator [0-9]+ ')') / (('+' [0-9]+)*))? ) / ARMGOTLow12 / Low12BitsSymbolRef / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement? ARMGOTLow12 <- ":got_lo12:" SymbolName ARMPostincrement <- '!' BaseIndexScale <- '(' RegisterOrConstant? WS? (',' WS? RegisterOrConstant WS? (',' [0-9]+)? )? ')' diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg.go b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg.go index 56c4a20f..01a1fc2c 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg.go +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate.peg.go @@ -1,10 +1,14 @@ package main +// Code generated by ./peg/peg delocate.peg DO NOT EDIT. + import ( "fmt" - "math" + "io" + "os" "sort" "strconv" + "strings" ) const endSymbol rune = 1114112 @@ -142,19 +146,19 @@ type node32 struct { up, next *node32 } -func (node *node32) print(pretty bool, buffer string) { +func (node *node32) print(w io.Writer, pretty bool, buffer string) { var print func(node *node32, depth int) print = func(node *node32, depth int) { for node != nil { for c := 0; c < depth; c++ { - fmt.Printf(" ") + fmt.Fprintf(w, " ") } rule := rul3s[node.pegRule] quote := strconv.Quote(string(([]rune(buffer)[node.begin:node.end]))) if !pretty { - fmt.Printf("%v %v\n", rule, quote) + fmt.Fprintf(w, "%v %v\n", rule, quote) } else { - fmt.Printf("\x1B[34m%v\x1B[m %v\n", rule, quote) + fmt.Fprintf(w, "\x1B[36m%v\x1B[m %v\n", rule, quote) } if node.up != nil { print(node.up, depth+1) @@ -165,12 +169,12 @@ func (node *node32) print(pretty bool, buffer string) { print(node, 0) } -func (node *node32) Print(buffer string) { - node.print(false, buffer) +func (node *node32) Print(w io.Writer, buffer string) { + node.print(w, false, buffer) } -func (node *node32) PrettyPrint(buffer string) { - node.print(true, buffer) +func (node *node32) PrettyPrint(w io.Writer, buffer string) { + node.print(w, true, buffer) } type tokens32 struct { @@ -213,24 +217,24 @@ func (t *tokens32) AST() *node32 { } func (t *tokens32) PrintSyntaxTree(buffer string) { - t.AST().Print(buffer) + t.AST().Print(os.Stdout, buffer) +} + +func (t *tokens32) WriteSyntaxTree(w io.Writer, buffer string) { + t.AST().Print(w, buffer) } func (t *tokens32) PrettyPrintSyntaxTree(buffer string) { - t.AST().PrettyPrint(buffer) + t.AST().PrettyPrint(os.Stdout, buffer) } func (t *tokens32) Add(rule pegRule, begin, end, index uint32) { - if tree := t.tree; int(index) >= len(tree) { - expanded := make([]token32, 2*len(tree)) - copy(expanded, tree) - t.tree = expanded - } - t.tree[index] = token32{ - pegRule: rule, - begin: begin, - end: end, + tree, i := t.tree, int(index) + if i >= len(tree) { + t.tree = append(tree, token32{pegRule: rule, begin: begin, end: end}) + return } + tree[i] = token32{pegRule: rule, begin: begin, end: end} } func (t *tokens32) Tokens() []token32 { @@ -292,7 +296,7 @@ type parseError struct { } func (e *parseError) Error() string { - tokens, error := []token32{e.max}, "\n" + tokens, err := []token32{e.max}, "\n" positions, p := make([]int, 2*len(tokens)), 0 for _, token := range tokens { positions[p], p = int(token.begin), p+1 @@ -305,14 +309,14 @@ func (e *parseError) Error() string { } for _, token := range tokens { begin, end := int(token.begin), int(token.end) - error += fmt.Sprintf(format, + err += fmt.Sprintf(format, rul3s[token.pegRule], translations[begin].line, translations[begin].symbol, translations[end].line, translations[end].symbol, strconv.Quote(string(e.p.buffer[begin:end]))) } - return error + return err } func (p *Asm) PrintSyntaxTree() { @@ -323,12 +327,41 @@ func (p *Asm) PrintSyntaxTree() { } } -func (p *Asm) Init() { +func (p *Asm) WriteSyntaxTree(w io.Writer) { + p.tokens32.WriteSyntaxTree(w, p.Buffer) +} + +func (p *Asm) SprintSyntaxTree() string { + var bldr strings.Builder + p.WriteSyntaxTree(&bldr) + return bldr.String() +} + +func Pretty(pretty bool) func(*Asm) error { + return func(p *Asm) error { + p.Pretty = pretty + return nil + } +} + +func Size(size int) func(*Asm) error { + return func(p *Asm) error { + p.tokens32 = tokens32{tree: make([]token32, 0, size)} + return nil + } +} +func (p *Asm) Init(options ...func(*Asm) error) error { var ( max token32 position, tokenIndex uint32 buffer []rune ) + for _, option := range options { + err := option(p) + if err != nil { + return err + } + } p.reset = func() { max = token32{} position, tokenIndex = 0, 0 @@ -342,7 +375,7 @@ func (p *Asm) Init() { p.reset() _rules := p.rules - tree := tokens32{tree: make([]token32, math.MaxInt16)} + tree := p.tokens32 p.parse = func(rule ...int) error { r := 1 if len(rule) > 0 { @@ -2540,7 +2573,7 @@ func (p *Asm) Init() { position, tokenIndex = position291, tokenIndex291 return false }, - /* 16 SymbolArg <- <((OpenParen WS?)? (Offset / SymbolType / ((Offset / LocalSymbol / SymbolName / Dot) WS? Operator WS? (Offset / LocalSymbol / SymbolName)) / (LocalSymbol TCMarker?) / (SymbolName Offset) / (SymbolName TCMarker?)) (WS? CloseParen)? (WS? SymbolShift)?)> */ + /* 16 SymbolArg <- <((OpenParen WS?)? (Offset / SymbolType / ((Offset / LocalSymbol / SymbolName / Dot) (WS? Operator WS? (Offset / LocalSymbol / SymbolName))*) / (LocalSymbol TCMarker?) / (SymbolName Offset) / (SymbolName TCMarker?)) (WS? CloseParen)? (WS? SymbolShift)?)> */ func() bool { position299, tokenIndex299 := position, tokenIndex { @@ -2604,131 +2637,138 @@ func (p *Asm) Init() { } } l309: + l313: { - position313, tokenIndex313 := position, tokenIndex - if !_rules[ruleWS]() { - goto l313 + position314, tokenIndex314 := position, tokenIndex + { + position315, tokenIndex315 := position, tokenIndex + if !_rules[ruleWS]() { + goto l315 + } + goto l316 + l315: + position, tokenIndex = position315, tokenIndex315 } - goto l314 - l313: - position, tokenIndex = position313, tokenIndex313 - } - l314: - if !_rules[ruleOperator]() { - goto l308 - } - { - position315, tokenIndex315 := position, tokenIndex - if !_rules[ruleWS]() { - goto l315 + l316: + if !_rules[ruleOperator]() { + goto l314 } - goto l316 - l315: - position, tokenIndex = position315, tokenIndex315 - } - l316: - { - position317, tokenIndex317 := position, tokenIndex - if !_rules[ruleOffset]() { + { + position317, tokenIndex317 := position, tokenIndex + if !_rules[ruleWS]() { + goto l317 + } goto l318 + l317: + position, tokenIndex = position317, tokenIndex317 } - goto l317 l318: - position, tokenIndex = position317, tokenIndex317 - if !_rules[ruleLocalSymbol]() { + { + position319, tokenIndex319 := position, tokenIndex + if !_rules[ruleOffset]() { + goto l320 + } goto l319 + l320: + position, tokenIndex = position319, tokenIndex319 + if !_rules[ruleLocalSymbol]() { + goto l321 + } + goto l319 + l321: + position, tokenIndex = position319, tokenIndex319 + if !_rules[ruleSymbolName]() { + goto l314 + } } - goto l317 l319: - position, tokenIndex = position317, tokenIndex317 - if !_rules[ruleSymbolName]() { - goto l308 - } + goto l313 + l314: + position, tokenIndex = position314, tokenIndex314 } - l317: goto l305 l308: position, tokenIndex = position305, tokenIndex305 if !_rules[ruleLocalSymbol]() { - goto l320 + goto l322 } { - position321, tokenIndex321 := position, tokenIndex + position323, tokenIndex323 := position, tokenIndex if !_rules[ruleTCMarker]() { - goto l321 + goto l323 } - goto l322 - l321: - position, tokenIndex = position321, tokenIndex321 + goto l324 + l323: + position, tokenIndex = position323, tokenIndex323 } - l322: + l324: goto l305 - l320: + l322: position, tokenIndex = position305, tokenIndex305 if !_rules[ruleSymbolName]() { - goto l323 + goto l325 } if !_rules[ruleOffset]() { - goto l323 + goto l325 } goto l305 - l323: + l325: position, tokenIndex = position305, tokenIndex305 if !_rules[ruleSymbolName]() { goto l299 } { - position324, tokenIndex324 := position, tokenIndex + position326, tokenIndex326 := position, tokenIndex if !_rules[ruleTCMarker]() { - goto l324 + goto l326 } - goto l325 - l324: - position, tokenIndex = position324, tokenIndex324 + goto l327 + l326: + position, tokenIndex = position326, tokenIndex326 } - l325: + l327: } l305: { - position326, tokenIndex326 := position, tokenIndex + position328, tokenIndex328 := position, tokenIndex { - position328, tokenIndex328 := position, tokenIndex + position330, tokenIndex330 := position, tokenIndex if !_rules[ruleWS]() { - goto l328 + goto l330 } - goto l329 - l328: - position, tokenIndex = position328, tokenIndex328 + goto l331 + l330: + position, tokenIndex = position330, tokenIndex330 } - l329: + l331: if !_rules[ruleCloseParen]() { - goto l326 + goto l328 } - goto l327 - l326: - position, tokenIndex = position326, tokenIndex326 + goto l329 + l328: + position, tokenIndex = position328, tokenIndex328 } - l327: + l329: { - position330, tokenIndex330 := position, tokenIndex + position332, tokenIndex332 := position, tokenIndex { - position332, tokenIndex332 := position, tokenIndex + position334, tokenIndex334 := position, tokenIndex if !_rules[ruleWS]() { - goto l332 + goto l334 } - goto l333 - l332: - position, tokenIndex = position332, tokenIndex332 + goto l335 + l334: + position, tokenIndex = position334, tokenIndex334 } - l333: + l335: if !_rules[ruleSymbolShift]() { - goto l330 + goto l332 } - goto l331 - l330: - position, tokenIndex = position330, tokenIndex330 + goto l333 + l332: + position, tokenIndex = position332, tokenIndex332 } - l331: + l333: add(ruleSymbolArg, position300) } return true @@ -2737,722 +2777,708 @@ func (p *Asm) Init() { return false }, /* 17 OpenParen <- <'('> */ - func() bool { - position334, tokenIndex334 := position, tokenIndex - { - position335 := position - if buffer[position] != rune('(') { - goto l334 - } - position++ - add(ruleOpenParen, position335) - } - return true - l334: - position, tokenIndex = position334, tokenIndex334 - return false - }, - /* 18 CloseParen <- <')'> */ func() bool { position336, tokenIndex336 := position, tokenIndex { position337 := position - if buffer[position] != rune(')') { + if buffer[position] != rune('(') { goto l336 } position++ - add(ruleCloseParen, position337) + add(ruleOpenParen, position337) } return true l336: position, tokenIndex = position336, tokenIndex336 return false }, - /* 19 SymbolType <- <(('@' / '%') (('f' 'u' 'n' 'c' 't' 'i' 'o' 'n') / ('o' 'b' 'j' 'e' 'c' 't')))> */ + /* 18 CloseParen <- <')'> */ func() bool { position338, tokenIndex338 := position, tokenIndex { position339 := position - { - position340, tokenIndex340 := position, tokenIndex - if buffer[position] != rune('@') { - goto l341 - } - position++ - goto l340 - l341: - position, tokenIndex = position340, tokenIndex340 - if buffer[position] != rune('%') { - goto l338 - } - position++ + if buffer[position] != rune(')') { + goto l338 } - l340: - { - position342, tokenIndex342 := position, tokenIndex - if buffer[position] != rune('f') { - goto l343 - } - position++ - if buffer[position] != rune('u') { - goto l343 - } - position++ - if buffer[position] != rune('n') { - goto l343 - } - position++ - if buffer[position] != rune('c') { - goto l343 - } - position++ - if buffer[position] != rune('t') { - goto l343 - } - position++ - if buffer[position] != rune('i') { - goto l343 - } - position++ - if buffer[position] != rune('o') { - goto l343 - } - position++ - if buffer[position] != rune('n') { - goto l343 - } - position++ - goto l342 - l343: - position, tokenIndex = position342, tokenIndex342 - if buffer[position] != rune('o') { - goto l338 - } - position++ - if buffer[position] != rune('b') { - goto l338 - } - position++ - if buffer[position] != rune('j') { - goto l338 - } - position++ - if buffer[position] != rune('e') { - goto l338 - } - position++ - if buffer[position] != rune('c') { - goto l338 - } - position++ - if buffer[position] != rune('t') { - goto l338 - } - position++ - } - l342: - add(ruleSymbolType, position339) + position++ + add(ruleCloseParen, position339) } return true l338: position, tokenIndex = position338, tokenIndex338 return false }, - /* 20 Dot <- <'.'> */ + /* 19 SymbolType <- <(('@' / '%') (('f' 'u' 'n' 'c' 't' 'i' 'o' 'n') / ('o' 'b' 'j' 'e' 'c' 't')))> */ func() bool { - position344, tokenIndex344 := position, tokenIndex + position340, tokenIndex340 := position, tokenIndex { - position345 := position - if buffer[position] != rune('.') { - goto l344 + position341 := position + { + position342, tokenIndex342 := position, tokenIndex + if buffer[position] != rune('@') { + goto l343 + } + position++ + goto l342 + l343: + position, tokenIndex = position342, tokenIndex342 + if buffer[position] != rune('%') { + goto l340 + } + position++ } - position++ - add(ruleDot, position345) + l342: + { + position344, tokenIndex344 := position, tokenIndex + if buffer[position] != rune('f') { + goto l345 + } + position++ + if buffer[position] != rune('u') { + goto l345 + } + position++ + if buffer[position] != rune('n') { + goto l345 + } + position++ + if buffer[position] != rune('c') { + goto l345 + } + position++ + if buffer[position] != rune('t') { + goto l345 + } + position++ + if buffer[position] != rune('i') { + goto l345 + } + position++ + if buffer[position] != rune('o') { + goto l345 + } + position++ + if buffer[position] != rune('n') { + goto l345 + } + position++ + goto l344 + l345: + position, tokenIndex = position344, tokenIndex344 + if buffer[position] != rune('o') { + goto l340 + } + position++ + if buffer[position] != rune('b') { + goto l340 + } + position++ + if buffer[position] != rune('j') { + goto l340 + } + position++ + if buffer[position] != rune('e') { + goto l340 + } + position++ + if buffer[position] != rune('c') { + goto l340 + } + position++ + if buffer[position] != rune('t') { + goto l340 + } + position++ + } + l344: + add(ruleSymbolType, position341) } return true - l344: - position, tokenIndex = position344, tokenIndex344 + l340: + position, tokenIndex = position340, tokenIndex340 return false }, - /* 21 TCMarker <- <('[' 'T' 'C' ']')> */ + /* 20 Dot <- <'.'> */ func() bool { position346, tokenIndex346 := position, tokenIndex { position347 := position - if buffer[position] != rune('[') { + if buffer[position] != rune('.') { goto l346 } position++ - if buffer[position] != rune('T') { - goto l346 - } - position++ - if buffer[position] != rune('C') { - goto l346 - } - position++ - if buffer[position] != rune(']') { - goto l346 - } - position++ - add(ruleTCMarker, position347) + add(ruleDot, position347) } return true l346: position, tokenIndex = position346, tokenIndex346 return false }, - /* 22 EscapedChar <- <('\\' .)> */ + /* 21 TCMarker <- <('[' 'T' 'C' ']')> */ func() bool { position348, tokenIndex348 := position, tokenIndex { position349 := position - if buffer[position] != rune('\\') { + if buffer[position] != rune('[') { goto l348 } position++ - if !matchDot() { + if buffer[position] != rune('T') { goto l348 } - add(ruleEscapedChar, position349) + position++ + if buffer[position] != rune('C') { + goto l348 + } + position++ + if buffer[position] != rune(']') { + goto l348 + } + position++ + add(ruleTCMarker, position349) } return true l348: position, tokenIndex = position348, tokenIndex348 return false }, - /* 23 WS <- <(' ' / '\t')+> */ + /* 22 EscapedChar <- <('\\' .)> */ func() bool { position350, tokenIndex350 := position, tokenIndex { position351 := position - { - position354, tokenIndex354 := position, tokenIndex - if buffer[position] != rune(' ') { - goto l355 - } - position++ - goto l354 - l355: - position, tokenIndex = position354, tokenIndex354 - if buffer[position] != rune('\t') { - goto l350 - } - position++ + if buffer[position] != rune('\\') { + goto l350 } - l354: - l352: - { - position353, tokenIndex353 := position, tokenIndex - { - position356, tokenIndex356 := position, tokenIndex - if buffer[position] != rune(' ') { - goto l357 - } - position++ - goto l356 - l357: - position, tokenIndex = position356, tokenIndex356 - if buffer[position] != rune('\t') { - goto l353 - } - position++ - } - l356: - goto l352 - l353: - position, tokenIndex = position353, tokenIndex353 + position++ + if !matchDot() { + goto l350 } - add(ruleWS, position351) + add(ruleEscapedChar, position351) } return true l350: position, tokenIndex = position350, tokenIndex350 return false }, - /* 24 Comment <- <((('/' '/') / '#') (!'\n' .)*)> */ + /* 23 WS <- <(' ' / '\t')+> */ func() bool { - position358, tokenIndex358 := position, tokenIndex + position352, tokenIndex352 := position, tokenIndex { - position359 := position + position353 := position { - position360, tokenIndex360 := position, tokenIndex - if buffer[position] != rune('/') { - goto l361 + position356, tokenIndex356 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l357 } position++ - if buffer[position] != rune('/') { - goto l361 - } - position++ - goto l360 - l361: - position, tokenIndex = position360, tokenIndex360 - if buffer[position] != rune('#') { - goto l358 + goto l356 + l357: + position, tokenIndex = position356, tokenIndex356 + if buffer[position] != rune('\t') { + goto l352 } position++ } - l360: - l362: + l356: + l354: { - position363, tokenIndex363 := position, tokenIndex + position355, tokenIndex355 := position, tokenIndex { - position364, tokenIndex364 := position, tokenIndex - if buffer[position] != rune('\n') { - goto l364 + position358, tokenIndex358 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l359 + } + position++ + goto l358 + l359: + position, tokenIndex = position358, tokenIndex358 + if buffer[position] != rune('\t') { + goto l355 } position++ - goto l363 - l364: - position, tokenIndex = position364, tokenIndex364 } - if !matchDot() { - goto l363 - } - goto l362 - l363: - position, tokenIndex = position363, tokenIndex363 + l358: + goto l354 + l355: + position, tokenIndex = position355, tokenIndex355 } - add(ruleComment, position359) + add(ruleWS, position353) } return true - l358: - position, tokenIndex = position358, tokenIndex358 + l352: + position, tokenIndex = position352, tokenIndex352 + return false + }, + /* 24 Comment <- <((('/' '/') / '#') (!'\n' .)*)> */ + func() bool { + position360, tokenIndex360 := position, tokenIndex + { + position361 := position + { + position362, tokenIndex362 := position, tokenIndex + if buffer[position] != rune('/') { + goto l363 + } + position++ + if buffer[position] != rune('/') { + goto l363 + } + position++ + goto l362 + l363: + position, tokenIndex = position362, tokenIndex362 + if buffer[position] != rune('#') { + goto l360 + } + position++ + } + l362: + l364: + { + position365, tokenIndex365 := position, tokenIndex + { + position366, tokenIndex366 := position, tokenIndex + if buffer[position] != rune('\n') { + goto l366 + } + position++ + goto l365 + l366: + position, tokenIndex = position366, tokenIndex366 + } + if !matchDot() { + goto l365 + } + goto l364 + l365: + position, tokenIndex = position365, tokenIndex365 + } + add(ruleComment, position361) + } + return true + l360: + position, tokenIndex = position360, tokenIndex360 return false }, /* 25 Label <- <((LocalSymbol / LocalLabel / SymbolName) ':')> */ func() bool { - position365, tokenIndex365 := position, tokenIndex + position367, tokenIndex367 := position, tokenIndex { - position366 := position + position368 := position { - position367, tokenIndex367 := position, tokenIndex + position369, tokenIndex369 := position, tokenIndex if !_rules[ruleLocalSymbol]() { - goto l368 + goto l370 } - goto l367 - l368: - position, tokenIndex = position367, tokenIndex367 + goto l369 + l370: + position, tokenIndex = position369, tokenIndex369 if !_rules[ruleLocalLabel]() { - goto l369 + goto l371 } - goto l367 - l369: - position, tokenIndex = position367, tokenIndex367 + goto l369 + l371: + position, tokenIndex = position369, tokenIndex369 if !_rules[ruleSymbolName]() { - goto l365 + goto l367 } } - l367: + l369: if buffer[position] != rune(':') { - goto l365 + goto l367 } position++ - add(ruleLabel, position366) + add(ruleLabel, position368) } return true - l365: - position, tokenIndex = position365, tokenIndex365 + l367: + position, tokenIndex = position367, tokenIndex367 return false }, /* 26 SymbolName <- <(([a-z] / [A-Z] / '.' / '_') ([a-z] / [A-Z] / '.' / ([0-9] / [0-9]) / '$' / '_')*)> */ func() bool { - position370, tokenIndex370 := position, tokenIndex + position372, tokenIndex372 := position, tokenIndex { - position371 := position + position373 := position { - position372, tokenIndex372 := position, tokenIndex + position374, tokenIndex374 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l373 - } - position++ - goto l372 - l373: - position, tokenIndex = position372, tokenIndex372 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l374 - } - position++ - goto l372 - l374: - position, tokenIndex = position372, tokenIndex372 - if buffer[position] != rune('.') { goto l375 } position++ - goto l372 + goto l374 l375: - position, tokenIndex = position372, tokenIndex372 + position, tokenIndex = position374, tokenIndex374 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l376 + } + position++ + goto l374 + l376: + position, tokenIndex = position374, tokenIndex374 + if buffer[position] != rune('.') { + goto l377 + } + position++ + goto l374 + l377: + position, tokenIndex = position374, tokenIndex374 if buffer[position] != rune('_') { - goto l370 + goto l372 } position++ } - l372: - l376: + l374: + l378: { - position377, tokenIndex377 := position, tokenIndex + position379, tokenIndex379 := position, tokenIndex { - position378, tokenIndex378 := position, tokenIndex + position380, tokenIndex380 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l379 - } - position++ - goto l378 - l379: - position, tokenIndex = position378, tokenIndex378 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l380 - } - position++ - goto l378 - l380: - position, tokenIndex = position378, tokenIndex378 - if buffer[position] != rune('.') { goto l381 } position++ - goto l378 + goto l380 l381: - position, tokenIndex = position378, tokenIndex378 + position, tokenIndex = position380, tokenIndex380 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l382 + } + position++ + goto l380 + l382: + position, tokenIndex = position380, tokenIndex380 + if buffer[position] != rune('.') { + goto l383 + } + position++ + goto l380 + l383: + position, tokenIndex = position380, tokenIndex380 { - position383, tokenIndex383 := position, tokenIndex + position385, tokenIndex385 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l386 + } + position++ + goto l385 + l386: + position, tokenIndex = position385, tokenIndex385 if c := buffer[position]; c < rune('0') || c > rune('9') { goto l384 } position++ - goto l383 - l384: - position, tokenIndex = position383, tokenIndex383 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l382 - } - position++ } - l383: - goto l378 - l382: - position, tokenIndex = position378, tokenIndex378 + l385: + goto l380 + l384: + position, tokenIndex = position380, tokenIndex380 if buffer[position] != rune('$') { - goto l385 + goto l387 } position++ - goto l378 - l385: - position, tokenIndex = position378, tokenIndex378 + goto l380 + l387: + position, tokenIndex = position380, tokenIndex380 if buffer[position] != rune('_') { - goto l377 + goto l379 } position++ } - l378: - goto l376 - l377: - position, tokenIndex = position377, tokenIndex377 + l380: + goto l378 + l379: + position, tokenIndex = position379, tokenIndex379 } - add(ruleSymbolName, position371) + add(ruleSymbolName, position373) } return true - l370: - position, tokenIndex = position370, tokenIndex370 + l372: + position, tokenIndex = position372, tokenIndex372 return false }, /* 27 LocalSymbol <- <('.' 'L' ([a-z] / [A-Z] / ([a-z] / [A-Z]) / '.' / ([0-9] / [0-9]) / '$' / '_')+)> */ func() bool { - position386, tokenIndex386 := position, tokenIndex + position388, tokenIndex388 := position, tokenIndex { - position387 := position + position389 := position if buffer[position] != rune('.') { - goto l386 + goto l388 } position++ if buffer[position] != rune('L') { - goto l386 + goto l388 } position++ { - position390, tokenIndex390 := position, tokenIndex + position392, tokenIndex392 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l391 + goto l393 } position++ - goto l390 - l391: - position, tokenIndex = position390, tokenIndex390 + goto l392 + l393: + position, tokenIndex = position392, tokenIndex392 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l392 + goto l394 } position++ - goto l390 - l392: - position, tokenIndex = position390, tokenIndex390 + goto l392 + l394: + position, tokenIndex = position392, tokenIndex392 { - position394, tokenIndex394 := position, tokenIndex + position396, tokenIndex396 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l397 + } + position++ + goto l396 + l397: + position, tokenIndex = position396, tokenIndex396 + if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l395 } position++ - goto l394 - l395: - position, tokenIndex = position394, tokenIndex394 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l393 - } - position++ } - l394: - goto l390 - l393: - position, tokenIndex = position390, tokenIndex390 + l396: + goto l392 + l395: + position, tokenIndex = position392, tokenIndex392 if buffer[position] != rune('.') { - goto l396 + goto l398 } position++ - goto l390 - l396: - position, tokenIndex = position390, tokenIndex390 + goto l392 + l398: + position, tokenIndex = position392, tokenIndex392 { - position398, tokenIndex398 := position, tokenIndex + position400, tokenIndex400 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l401 + } + position++ + goto l400 + l401: + position, tokenIndex = position400, tokenIndex400 if c := buffer[position]; c < rune('0') || c > rune('9') { goto l399 } position++ - goto l398 - l399: - position, tokenIndex = position398, tokenIndex398 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l397 - } - position++ } - l398: - goto l390 - l397: - position, tokenIndex = position390, tokenIndex390 + l400: + goto l392 + l399: + position, tokenIndex = position392, tokenIndex392 if buffer[position] != rune('$') { - goto l400 + goto l402 } position++ - goto l390 - l400: - position, tokenIndex = position390, tokenIndex390 + goto l392 + l402: + position, tokenIndex = position392, tokenIndex392 if buffer[position] != rune('_') { - goto l386 + goto l388 } position++ } + l392: l390: - l388: { - position389, tokenIndex389 := position, tokenIndex + position391, tokenIndex391 := position, tokenIndex { - position401, tokenIndex401 := position, tokenIndex + position403, tokenIndex403 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l402 + goto l404 } position++ - goto l401 - l402: - position, tokenIndex = position401, tokenIndex401 + goto l403 + l404: + position, tokenIndex = position403, tokenIndex403 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l403 + goto l405 } position++ - goto l401 - l403: - position, tokenIndex = position401, tokenIndex401 + goto l403 + l405: + position, tokenIndex = position403, tokenIndex403 { - position405, tokenIndex405 := position, tokenIndex + position407, tokenIndex407 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l408 + } + position++ + goto l407 + l408: + position, tokenIndex = position407, tokenIndex407 + if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l406 } position++ - goto l405 - l406: - position, tokenIndex = position405, tokenIndex405 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l404 - } - position++ } - l405: - goto l401 - l404: - position, tokenIndex = position401, tokenIndex401 + l407: + goto l403 + l406: + position, tokenIndex = position403, tokenIndex403 if buffer[position] != rune('.') { - goto l407 + goto l409 } position++ - goto l401 - l407: - position, tokenIndex = position401, tokenIndex401 + goto l403 + l409: + position, tokenIndex = position403, tokenIndex403 { - position409, tokenIndex409 := position, tokenIndex + position411, tokenIndex411 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l412 + } + position++ + goto l411 + l412: + position, tokenIndex = position411, tokenIndex411 if c := buffer[position]; c < rune('0') || c > rune('9') { goto l410 } position++ - goto l409 - l410: - position, tokenIndex = position409, tokenIndex409 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l408 - } - position++ } - l409: - goto l401 - l408: - position, tokenIndex = position401, tokenIndex401 + l411: + goto l403 + l410: + position, tokenIndex = position403, tokenIndex403 if buffer[position] != rune('$') { - goto l411 + goto l413 } position++ - goto l401 - l411: - position, tokenIndex = position401, tokenIndex401 + goto l403 + l413: + position, tokenIndex = position403, tokenIndex403 if buffer[position] != rune('_') { - goto l389 + goto l391 } position++ } - l401: - goto l388 - l389: - position, tokenIndex = position389, tokenIndex389 + l403: + goto l390 + l391: + position, tokenIndex = position391, tokenIndex391 } - add(ruleLocalSymbol, position387) + add(ruleLocalSymbol, position389) } return true - l386: - position, tokenIndex = position386, tokenIndex386 + l388: + position, tokenIndex = position388, tokenIndex388 return false }, /* 28 LocalLabel <- <([0-9] ([0-9] / '$')*)> */ func() bool { - position412, tokenIndex412 := position, tokenIndex + position414, tokenIndex414 := position, tokenIndex { - position413 := position + position415 := position if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l412 + goto l414 } position++ - l414: + l416: { - position415, tokenIndex415 := position, tokenIndex + position417, tokenIndex417 := position, tokenIndex { - position416, tokenIndex416 := position, tokenIndex + position418, tokenIndex418 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l419 + } + position++ + goto l418 + l419: + position, tokenIndex = position418, tokenIndex418 + if buffer[position] != rune('$') { goto l417 } position++ - goto l416 - l417: - position, tokenIndex = position416, tokenIndex416 - if buffer[position] != rune('$') { - goto l415 - } - position++ } - l416: - goto l414 - l415: - position, tokenIndex = position415, tokenIndex415 + l418: + goto l416 + l417: + position, tokenIndex = position417, tokenIndex417 } - add(ruleLocalLabel, position413) + add(ruleLocalLabel, position415) } return true - l412: - position, tokenIndex = position412, tokenIndex412 + l414: + position, tokenIndex = position414, tokenIndex414 return false }, /* 29 LocalLabelRef <- <([0-9] ([0-9] / '$')* ('b' / 'f'))> */ func() bool { - position418, tokenIndex418 := position, tokenIndex + position420, tokenIndex420 := position, tokenIndex { - position419 := position + position421 := position if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l418 + goto l420 } position++ - l420: + l422: { - position421, tokenIndex421 := position, tokenIndex + position423, tokenIndex423 := position, tokenIndex { - position422, tokenIndex422 := position, tokenIndex + position424, tokenIndex424 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l425 + } + position++ + goto l424 + l425: + position, tokenIndex = position424, tokenIndex424 + if buffer[position] != rune('$') { goto l423 } position++ - goto l422 - l423: - position, tokenIndex = position422, tokenIndex422 - if buffer[position] != rune('$') { - goto l421 - } - position++ } - l422: - goto l420 - l421: - position, tokenIndex = position421, tokenIndex421 + l424: + goto l422 + l423: + position, tokenIndex = position423, tokenIndex423 } { - position424, tokenIndex424 := position, tokenIndex + position426, tokenIndex426 := position, tokenIndex if buffer[position] != rune('b') { - goto l425 + goto l427 } position++ - goto l424 - l425: - position, tokenIndex = position424, tokenIndex424 + goto l426 + l427: + position, tokenIndex = position426, tokenIndex426 if buffer[position] != rune('f') { - goto l418 + goto l420 } position++ } - l424: - add(ruleLocalLabelRef, position419) + l426: + add(ruleLocalLabelRef, position421) } return true - l418: - position, tokenIndex = position418, tokenIndex418 + l420: + position, tokenIndex = position420, tokenIndex420 return false }, /* 30 Instruction <- <(InstructionName (WS InstructionArg (WS? ',' WS? InstructionArg)*)?)> */ func() bool { - position426, tokenIndex426 := position, tokenIndex + position428, tokenIndex428 := position, tokenIndex { - position427 := position + position429 := position if !_rules[ruleInstructionName]() { - goto l426 + goto l428 } { - position428, tokenIndex428 := position, tokenIndex + position430, tokenIndex430 := position, tokenIndex if !_rules[ruleWS]() { - goto l428 + goto l430 } if !_rules[ruleInstructionArg]() { - goto l428 + goto l430 } - l430: + l432: { - position431, tokenIndex431 := position, tokenIndex - { - position432, tokenIndex432 := position, tokenIndex - if !_rules[ruleWS]() { - goto l432 - } - goto l433 - l432: - position, tokenIndex = position432, tokenIndex432 - } - l433: - if buffer[position] != rune(',') { - goto l431 - } - position++ + position433, tokenIndex433 := position, tokenIndex { position434, tokenIndex434 := position, tokenIndex if !_rules[ruleWS]() { @@ -3463,1013 +3489,1009 @@ func (p *Asm) Init() { position, tokenIndex = position434, tokenIndex434 } l435: - if !_rules[ruleInstructionArg]() { - goto l431 + if buffer[position] != rune(',') { + goto l433 } - goto l430 - l431: - position, tokenIndex = position431, tokenIndex431 + position++ + { + position436, tokenIndex436 := position, tokenIndex + if !_rules[ruleWS]() { + goto l436 + } + goto l437 + l436: + position, tokenIndex = position436, tokenIndex436 + } + l437: + if !_rules[ruleInstructionArg]() { + goto l433 + } + goto l432 + l433: + position, tokenIndex = position433, tokenIndex433 } - goto l429 - l428: - position, tokenIndex = position428, tokenIndex428 + goto l431 + l430: + position, tokenIndex = position430, tokenIndex430 } - l429: - add(ruleInstruction, position427) + l431: + add(ruleInstruction, position429) } return true - l426: - position, tokenIndex = position426, tokenIndex426 + l428: + position, tokenIndex = position428, tokenIndex428 return false }, /* 31 InstructionName <- <(([a-z] / [A-Z]) ([a-z] / [A-Z] / '.' / ([0-9] / [0-9]))* ('.' / '+' / '-')?)> */ func() bool { - position436, tokenIndex436 := position, tokenIndex + position438, tokenIndex438 := position, tokenIndex { - position437 := position + position439 := position { - position438, tokenIndex438 := position, tokenIndex + position440, tokenIndex440 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l439 + goto l441 } position++ - goto l438 - l439: - position, tokenIndex = position438, tokenIndex438 + goto l440 + l441: + position, tokenIndex = position440, tokenIndex440 if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l436 + goto l438 } position++ } - l438: l440: + l442: { - position441, tokenIndex441 := position, tokenIndex + position443, tokenIndex443 := position, tokenIndex { - position442, tokenIndex442 := position, tokenIndex + position444, tokenIndex444 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l443 - } - position++ - goto l442 - l443: - position, tokenIndex = position442, tokenIndex442 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l444 - } - position++ - goto l442 - l444: - position, tokenIndex = position442, tokenIndex442 - if buffer[position] != rune('.') { goto l445 } position++ - goto l442 + goto l444 l445: - position, tokenIndex = position442, tokenIndex442 + position, tokenIndex = position444, tokenIndex444 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l446 + } + position++ + goto l444 + l446: + position, tokenIndex = position444, tokenIndex444 + if buffer[position] != rune('.') { + goto l447 + } + position++ + goto l444 + l447: + position, tokenIndex = position444, tokenIndex444 { - position446, tokenIndex446 := position, tokenIndex + position448, tokenIndex448 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l447 + goto l449 } position++ - goto l446 - l447: - position, tokenIndex = position446, tokenIndex446 + goto l448 + l449: + position, tokenIndex = position448, tokenIndex448 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l441 + goto l443 } position++ } - l446: + l448: } - l442: - goto l440 - l441: - position, tokenIndex = position441, tokenIndex441 + l444: + goto l442 + l443: + position, tokenIndex = position443, tokenIndex443 } { - position448, tokenIndex448 := position, tokenIndex + position450, tokenIndex450 := position, tokenIndex { - position450, tokenIndex450 := position, tokenIndex + position452, tokenIndex452 := position, tokenIndex if buffer[position] != rune('.') { - goto l451 + goto l453 } position++ - goto l450 - l451: - position, tokenIndex = position450, tokenIndex450 + goto l452 + l453: + position, tokenIndex = position452, tokenIndex452 if buffer[position] != rune('+') { - goto l452 + goto l454 } position++ - goto l450 - l452: - position, tokenIndex = position450, tokenIndex450 + goto l452 + l454: + position, tokenIndex = position452, tokenIndex452 if buffer[position] != rune('-') { - goto l448 + goto l450 } position++ } + l452: + goto l451 l450: - goto l449 - l448: - position, tokenIndex = position448, tokenIndex448 + position, tokenIndex = position450, tokenIndex450 } - l449: - add(ruleInstructionName, position437) + l451: + add(ruleInstructionName, position439) } return true - l436: - position, tokenIndex = position436, tokenIndex436 + l438: + position, tokenIndex = position438, tokenIndex438 return false }, /* 32 InstructionArg <- <(IndirectionIndicator? (ARMConstantTweak / RegisterOrConstant / LocalLabelRef / TOCRefHigh / TOCRefLow / GOTLocation / GOTSymbolOffset / MemoryRef) AVX512Token*)> */ func() bool { - position453, tokenIndex453 := position, tokenIndex + position455, tokenIndex455 := position, tokenIndex { - position454 := position - { - position455, tokenIndex455 := position, tokenIndex - if !_rules[ruleIndirectionIndicator]() { - goto l455 - } - goto l456 - l455: - position, tokenIndex = position455, tokenIndex455 - } - l456: + position456 := position { position457, tokenIndex457 := position, tokenIndex + if !_rules[ruleIndirectionIndicator]() { + goto l457 + } + goto l458 + l457: + position, tokenIndex = position457, tokenIndex457 + } + l458: + { + position459, tokenIndex459 := position, tokenIndex if !_rules[ruleARMConstantTweak]() { - goto l458 - } - goto l457 - l458: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleRegisterOrConstant]() { - goto l459 - } - goto l457 - l459: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleLocalLabelRef]() { goto l460 } - goto l457 + goto l459 l460: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleTOCRefHigh]() { + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleRegisterOrConstant]() { goto l461 } - goto l457 + goto l459 l461: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleTOCRefLow]() { + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleLocalLabelRef]() { goto l462 } - goto l457 + goto l459 l462: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleGOTLocation]() { + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleTOCRefHigh]() { goto l463 } - goto l457 + goto l459 l463: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleGOTSymbolOffset]() { + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleTOCRefLow]() { goto l464 } - goto l457 + goto l459 l464: - position, tokenIndex = position457, tokenIndex457 - if !_rules[ruleMemoryRef]() { - goto l453 + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleGOTLocation]() { + goto l465 } - } - l457: - l465: - { - position466, tokenIndex466 := position, tokenIndex - if !_rules[ruleAVX512Token]() { + goto l459 + l465: + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleGOTSymbolOffset]() { goto l466 } - goto l465 + goto l459 l466: - position, tokenIndex = position466, tokenIndex466 + position, tokenIndex = position459, tokenIndex459 + if !_rules[ruleMemoryRef]() { + goto l455 + } } - add(ruleInstructionArg, position454) + l459: + l467: + { + position468, tokenIndex468 := position, tokenIndex + if !_rules[ruleAVX512Token]() { + goto l468 + } + goto l467 + l468: + position, tokenIndex = position468, tokenIndex468 + } + add(ruleInstructionArg, position456) } return true - l453: - position, tokenIndex = position453, tokenIndex453 + l455: + position, tokenIndex = position455, tokenIndex455 return false }, /* 33 GOTLocation <- <('$' '_' 'G' 'L' 'O' 'B' 'A' 'L' '_' 'O' 'F' 'F' 'S' 'E' 'T' '_' 'T' 'A' 'B' 'L' 'E' '_' '-' LocalSymbol)> */ - func() bool { - position467, tokenIndex467 := position, tokenIndex - { - position468 := position - if buffer[position] != rune('$') { - goto l467 - } - position++ - if buffer[position] != rune('_') { - goto l467 - } - position++ - if buffer[position] != rune('G') { - goto l467 - } - position++ - if buffer[position] != rune('L') { - goto l467 - } - position++ - if buffer[position] != rune('O') { - goto l467 - } - position++ - if buffer[position] != rune('B') { - goto l467 - } - position++ - if buffer[position] != rune('A') { - goto l467 - } - position++ - if buffer[position] != rune('L') { - goto l467 - } - position++ - if buffer[position] != rune('_') { - goto l467 - } - position++ - if buffer[position] != rune('O') { - goto l467 - } - position++ - if buffer[position] != rune('F') { - goto l467 - } - position++ - if buffer[position] != rune('F') { - goto l467 - } - position++ - if buffer[position] != rune('S') { - goto l467 - } - position++ - if buffer[position] != rune('E') { - goto l467 - } - position++ - if buffer[position] != rune('T') { - goto l467 - } - position++ - if buffer[position] != rune('_') { - goto l467 - } - position++ - if buffer[position] != rune('T') { - goto l467 - } - position++ - if buffer[position] != rune('A') { - goto l467 - } - position++ - if buffer[position] != rune('B') { - goto l467 - } - position++ - if buffer[position] != rune('L') { - goto l467 - } - position++ - if buffer[position] != rune('E') { - goto l467 - } - position++ - if buffer[position] != rune('_') { - goto l467 - } - position++ - if buffer[position] != rune('-') { - goto l467 - } - position++ - if !_rules[ruleLocalSymbol]() { - goto l467 - } - add(ruleGOTLocation, position468) - } - return true - l467: - position, tokenIndex = position467, tokenIndex467 - return false - }, - /* 34 GOTSymbolOffset <- <(('$' SymbolName ('@' 'G' 'O' 'T') ('O' 'F' 'F')?) / (':' ('g' / 'G') ('o' / 'O') ('t' / 'T') ':' SymbolName))> */ func() bool { position469, tokenIndex469 := position, tokenIndex { position470 := position - { - position471, tokenIndex471 := position, tokenIndex - if buffer[position] != rune('$') { - goto l472 - } - position++ - if !_rules[ruleSymbolName]() { - goto l472 - } - if buffer[position] != rune('@') { - goto l472 - } - position++ - if buffer[position] != rune('G') { - goto l472 - } - position++ - if buffer[position] != rune('O') { - goto l472 - } - position++ - if buffer[position] != rune('T') { - goto l472 - } - position++ - { - position473, tokenIndex473 := position, tokenIndex - if buffer[position] != rune('O') { - goto l473 - } - position++ - if buffer[position] != rune('F') { - goto l473 - } - position++ - if buffer[position] != rune('F') { - goto l473 - } - position++ - goto l474 - l473: - position, tokenIndex = position473, tokenIndex473 - } - l474: - goto l471 - l472: - position, tokenIndex = position471, tokenIndex471 - if buffer[position] != rune(':') { - goto l469 - } - position++ - { - position475, tokenIndex475 := position, tokenIndex - if buffer[position] != rune('g') { - goto l476 - } - position++ - goto l475 - l476: - position, tokenIndex = position475, tokenIndex475 - if buffer[position] != rune('G') { - goto l469 - } - position++ - } - l475: - { - position477, tokenIndex477 := position, tokenIndex - if buffer[position] != rune('o') { - goto l478 - } - position++ - goto l477 - l478: - position, tokenIndex = position477, tokenIndex477 - if buffer[position] != rune('O') { - goto l469 - } - position++ - } - l477: - { - position479, tokenIndex479 := position, tokenIndex - if buffer[position] != rune('t') { - goto l480 - } - position++ - goto l479 - l480: - position, tokenIndex = position479, tokenIndex479 - if buffer[position] != rune('T') { - goto l469 - } - position++ - } - l479: - if buffer[position] != rune(':') { - goto l469 - } - position++ - if !_rules[ruleSymbolName]() { - goto l469 - } + if buffer[position] != rune('$') { + goto l469 } - l471: - add(ruleGOTSymbolOffset, position470) + position++ + if buffer[position] != rune('_') { + goto l469 + } + position++ + if buffer[position] != rune('G') { + goto l469 + } + position++ + if buffer[position] != rune('L') { + goto l469 + } + position++ + if buffer[position] != rune('O') { + goto l469 + } + position++ + if buffer[position] != rune('B') { + goto l469 + } + position++ + if buffer[position] != rune('A') { + goto l469 + } + position++ + if buffer[position] != rune('L') { + goto l469 + } + position++ + if buffer[position] != rune('_') { + goto l469 + } + position++ + if buffer[position] != rune('O') { + goto l469 + } + position++ + if buffer[position] != rune('F') { + goto l469 + } + position++ + if buffer[position] != rune('F') { + goto l469 + } + position++ + if buffer[position] != rune('S') { + goto l469 + } + position++ + if buffer[position] != rune('E') { + goto l469 + } + position++ + if buffer[position] != rune('T') { + goto l469 + } + position++ + if buffer[position] != rune('_') { + goto l469 + } + position++ + if buffer[position] != rune('T') { + goto l469 + } + position++ + if buffer[position] != rune('A') { + goto l469 + } + position++ + if buffer[position] != rune('B') { + goto l469 + } + position++ + if buffer[position] != rune('L') { + goto l469 + } + position++ + if buffer[position] != rune('E') { + goto l469 + } + position++ + if buffer[position] != rune('_') { + goto l469 + } + position++ + if buffer[position] != rune('-') { + goto l469 + } + position++ + if !_rules[ruleLocalSymbol]() { + goto l469 + } + add(ruleGOTLocation, position470) } return true l469: position, tokenIndex = position469, tokenIndex469 return false }, - /* 35 AVX512Token <- <(WS? '{' '%'? ([0-9] / [a-z])* '}')> */ + /* 34 GOTSymbolOffset <- <(('$' SymbolName ('@' 'G' 'O' 'T') ('O' 'F' 'F')?) / (':' ('g' / 'G') ('o' / 'O') ('t' / 'T') ':' SymbolName))> */ func() bool { - position481, tokenIndex481 := position, tokenIndex + position471, tokenIndex471 := position, tokenIndex { - position482 := position + position472 := position { - position483, tokenIndex483 := position, tokenIndex - if !_rules[ruleWS]() { - goto l483 - } - goto l484 - l483: - position, tokenIndex = position483, tokenIndex483 - } - l484: - if buffer[position] != rune('{') { - goto l481 - } - position++ - { - position485, tokenIndex485 := position, tokenIndex - if buffer[position] != rune('%') { - goto l485 + position473, tokenIndex473 := position, tokenIndex + if buffer[position] != rune('$') { + goto l474 } position++ + if !_rules[ruleSymbolName]() { + goto l474 + } + if buffer[position] != rune('@') { + goto l474 + } + position++ + if buffer[position] != rune('G') { + goto l474 + } + position++ + if buffer[position] != rune('O') { + goto l474 + } + position++ + if buffer[position] != rune('T') { + goto l474 + } + position++ + { + position475, tokenIndex475 := position, tokenIndex + if buffer[position] != rune('O') { + goto l475 + } + position++ + if buffer[position] != rune('F') { + goto l475 + } + position++ + if buffer[position] != rune('F') { + goto l475 + } + position++ + goto l476 + l475: + position, tokenIndex = position475, tokenIndex475 + } + l476: + goto l473 + l474: + position, tokenIndex = position473, tokenIndex473 + if buffer[position] != rune(':') { + goto l471 + } + position++ + { + position477, tokenIndex477 := position, tokenIndex + if buffer[position] != rune('g') { + goto l478 + } + position++ + goto l477 + l478: + position, tokenIndex = position477, tokenIndex477 + if buffer[position] != rune('G') { + goto l471 + } + position++ + } + l477: + { + position479, tokenIndex479 := position, tokenIndex + if buffer[position] != rune('o') { + goto l480 + } + position++ + goto l479 + l480: + position, tokenIndex = position479, tokenIndex479 + if buffer[position] != rune('O') { + goto l471 + } + position++ + } + l479: + { + position481, tokenIndex481 := position, tokenIndex + if buffer[position] != rune('t') { + goto l482 + } + position++ + goto l481 + l482: + position, tokenIndex = position481, tokenIndex481 + if buffer[position] != rune('T') { + goto l471 + } + position++ + } + l481: + if buffer[position] != rune(':') { + goto l471 + } + position++ + if !_rules[ruleSymbolName]() { + goto l471 + } + } + l473: + add(ruleGOTSymbolOffset, position472) + } + return true + l471: + position, tokenIndex = position471, tokenIndex471 + return false + }, + /* 35 AVX512Token <- <(WS? '{' '%'? ([0-9] / [a-z])* '}')> */ + func() bool { + position483, tokenIndex483 := position, tokenIndex + { + position484 := position + { + position485, tokenIndex485 := position, tokenIndex + if !_rules[ruleWS]() { + goto l485 + } goto l486 l485: position, tokenIndex = position485, tokenIndex485 } l486: - l487: + if buffer[position] != rune('{') { + goto l483 + } + position++ { - position488, tokenIndex488 := position, tokenIndex + position487, tokenIndex487 := position, tokenIndex + if buffer[position] != rune('%') { + goto l487 + } + position++ + goto l488 + l487: + position, tokenIndex = position487, tokenIndex487 + } + l488: + l489: + { + position490, tokenIndex490 := position, tokenIndex { - position489, tokenIndex489 := position, tokenIndex + position491, tokenIndex491 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l492 + } + position++ + goto l491 + l492: + position, tokenIndex = position491, tokenIndex491 + if c := buffer[position]; c < rune('a') || c > rune('z') { goto l490 } position++ - goto l489 - l490: - position, tokenIndex = position489, tokenIndex489 - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l488 - } - position++ } - l489: - goto l487 - l488: - position, tokenIndex = position488, tokenIndex488 + l491: + goto l489 + l490: + position, tokenIndex = position490, tokenIndex490 } if buffer[position] != rune('}') { - goto l481 + goto l483 } position++ - add(ruleAVX512Token, position482) + add(ruleAVX512Token, position484) } return true - l481: - position, tokenIndex = position481, tokenIndex481 + l483: + position, tokenIndex = position483, tokenIndex483 return false }, /* 36 TOCRefHigh <- <('.' 'T' 'O' 'C' '.' '-' (('0' 'b') / ('.' 'L' ([a-z] / [A-Z] / '_' / [0-9])+)) ('@' ('h' / 'H') ('a' / 'A')))> */ func() bool { - position491, tokenIndex491 := position, tokenIndex + position493, tokenIndex493 := position, tokenIndex { - position492 := position + position494 := position if buffer[position] != rune('.') { - goto l491 + goto l493 } position++ if buffer[position] != rune('T') { - goto l491 + goto l493 } position++ if buffer[position] != rune('O') { - goto l491 + goto l493 } position++ if buffer[position] != rune('C') { - goto l491 + goto l493 } position++ if buffer[position] != rune('.') { - goto l491 + goto l493 } position++ if buffer[position] != rune('-') { - goto l491 + goto l493 } position++ { - position493, tokenIndex493 := position, tokenIndex + position495, tokenIndex495 := position, tokenIndex if buffer[position] != rune('0') { - goto l494 + goto l496 } position++ if buffer[position] != rune('b') { - goto l494 + goto l496 } position++ - goto l493 - l494: - position, tokenIndex = position493, tokenIndex493 + goto l495 + l496: + position, tokenIndex = position495, tokenIndex495 if buffer[position] != rune('.') { - goto l491 + goto l493 } position++ if buffer[position] != rune('L') { - goto l491 + goto l493 } position++ { - position497, tokenIndex497 := position, tokenIndex + position499, tokenIndex499 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l498 - } - position++ - goto l497 - l498: - position, tokenIndex = position497, tokenIndex497 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l499 - } - position++ - goto l497 - l499: - position, tokenIndex = position497, tokenIndex497 - if buffer[position] != rune('_') { goto l500 } position++ - goto l497 + goto l499 l500: - position, tokenIndex = position497, tokenIndex497 + position, tokenIndex = position499, tokenIndex499 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l501 + } + position++ + goto l499 + l501: + position, tokenIndex = position499, tokenIndex499 + if buffer[position] != rune('_') { + goto l502 + } + position++ + goto l499 + l502: + position, tokenIndex = position499, tokenIndex499 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l491 + goto l493 } position++ } + l499: l497: - l495: { - position496, tokenIndex496 := position, tokenIndex + position498, tokenIndex498 := position, tokenIndex { - position501, tokenIndex501 := position, tokenIndex + position503, tokenIndex503 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l502 - } - position++ - goto l501 - l502: - position, tokenIndex = position501, tokenIndex501 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l503 - } - position++ - goto l501 - l503: - position, tokenIndex = position501, tokenIndex501 - if buffer[position] != rune('_') { goto l504 } position++ - goto l501 + goto l503 l504: - position, tokenIndex = position501, tokenIndex501 + position, tokenIndex = position503, tokenIndex503 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l505 + } + position++ + goto l503 + l505: + position, tokenIndex = position503, tokenIndex503 + if buffer[position] != rune('_') { + goto l506 + } + position++ + goto l503 + l506: + position, tokenIndex = position503, tokenIndex503 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l496 + goto l498 } position++ } - l501: - goto l495 - l496: - position, tokenIndex = position496, tokenIndex496 + l503: + goto l497 + l498: + position, tokenIndex = position498, tokenIndex498 } } - l493: + l495: if buffer[position] != rune('@') { - goto l491 + goto l493 } position++ - { - position505, tokenIndex505 := position, tokenIndex - if buffer[position] != rune('h') { - goto l506 - } - position++ - goto l505 - l506: - position, tokenIndex = position505, tokenIndex505 - if buffer[position] != rune('H') { - goto l491 - } - position++ - } - l505: { position507, tokenIndex507 := position, tokenIndex - if buffer[position] != rune('a') { + if buffer[position] != rune('h') { goto l508 } position++ goto l507 l508: position, tokenIndex = position507, tokenIndex507 - if buffer[position] != rune('A') { - goto l491 + if buffer[position] != rune('H') { + goto l493 } position++ } l507: - add(ruleTOCRefHigh, position492) + { + position509, tokenIndex509 := position, tokenIndex + if buffer[position] != rune('a') { + goto l510 + } + position++ + goto l509 + l510: + position, tokenIndex = position509, tokenIndex509 + if buffer[position] != rune('A') { + goto l493 + } + position++ + } + l509: + add(ruleTOCRefHigh, position494) } return true - l491: - position, tokenIndex = position491, tokenIndex491 + l493: + position, tokenIndex = position493, tokenIndex493 return false }, /* 37 TOCRefLow <- <('.' 'T' 'O' 'C' '.' '-' (('0' 'b') / ('.' 'L' ([a-z] / [A-Z] / '_' / [0-9])+)) ('@' ('l' / 'L')))> */ func() bool { - position509, tokenIndex509 := position, tokenIndex + position511, tokenIndex511 := position, tokenIndex { - position510 := position + position512 := position if buffer[position] != rune('.') { - goto l509 + goto l511 } position++ if buffer[position] != rune('T') { - goto l509 + goto l511 } position++ if buffer[position] != rune('O') { - goto l509 + goto l511 } position++ if buffer[position] != rune('C') { - goto l509 + goto l511 } position++ if buffer[position] != rune('.') { - goto l509 + goto l511 } position++ if buffer[position] != rune('-') { - goto l509 + goto l511 } position++ { - position511, tokenIndex511 := position, tokenIndex + position513, tokenIndex513 := position, tokenIndex if buffer[position] != rune('0') { - goto l512 + goto l514 } position++ if buffer[position] != rune('b') { - goto l512 + goto l514 } position++ - goto l511 - l512: - position, tokenIndex = position511, tokenIndex511 + goto l513 + l514: + position, tokenIndex = position513, tokenIndex513 if buffer[position] != rune('.') { - goto l509 + goto l511 } position++ if buffer[position] != rune('L') { - goto l509 + goto l511 } position++ { - position515, tokenIndex515 := position, tokenIndex + position517, tokenIndex517 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l516 - } - position++ - goto l515 - l516: - position, tokenIndex = position515, tokenIndex515 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l517 - } - position++ - goto l515 - l517: - position, tokenIndex = position515, tokenIndex515 - if buffer[position] != rune('_') { goto l518 } position++ - goto l515 + goto l517 l518: - position, tokenIndex = position515, tokenIndex515 + position, tokenIndex = position517, tokenIndex517 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l519 + } + position++ + goto l517 + l519: + position, tokenIndex = position517, tokenIndex517 + if buffer[position] != rune('_') { + goto l520 + } + position++ + goto l517 + l520: + position, tokenIndex = position517, tokenIndex517 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l509 + goto l511 } position++ } + l517: l515: - l513: { - position514, tokenIndex514 := position, tokenIndex + position516, tokenIndex516 := position, tokenIndex { - position519, tokenIndex519 := position, tokenIndex + position521, tokenIndex521 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l520 - } - position++ - goto l519 - l520: - position, tokenIndex = position519, tokenIndex519 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l521 - } - position++ - goto l519 - l521: - position, tokenIndex = position519, tokenIndex519 - if buffer[position] != rune('_') { goto l522 } position++ - goto l519 + goto l521 l522: - position, tokenIndex = position519, tokenIndex519 + position, tokenIndex = position521, tokenIndex521 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l523 + } + position++ + goto l521 + l523: + position, tokenIndex = position521, tokenIndex521 + if buffer[position] != rune('_') { + goto l524 + } + position++ + goto l521 + l524: + position, tokenIndex = position521, tokenIndex521 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l514 + goto l516 } position++ } - l519: - goto l513 - l514: - position, tokenIndex = position514, tokenIndex514 + l521: + goto l515 + l516: + position, tokenIndex = position516, tokenIndex516 } } - l511: + l513: if buffer[position] != rune('@') { - goto l509 + goto l511 } position++ { - position523, tokenIndex523 := position, tokenIndex + position525, tokenIndex525 := position, tokenIndex if buffer[position] != rune('l') { - goto l524 + goto l526 } position++ - goto l523 - l524: - position, tokenIndex = position523, tokenIndex523 + goto l525 + l526: + position, tokenIndex = position525, tokenIndex525 if buffer[position] != rune('L') { - goto l509 + goto l511 } position++ } - l523: - add(ruleTOCRefLow, position510) + l525: + add(ruleTOCRefLow, position512) } return true - l509: - position, tokenIndex = position509, tokenIndex509 + l511: + position, tokenIndex = position511, tokenIndex511 return false }, /* 38 IndirectionIndicator <- <'*'> */ func() bool { - position525, tokenIndex525 := position, tokenIndex + position527, tokenIndex527 := position, tokenIndex { - position526 := position + position528 := position if buffer[position] != rune('*') { - goto l525 + goto l527 } position++ - add(ruleIndirectionIndicator, position526) + add(ruleIndirectionIndicator, position528) } return true - l525: - position, tokenIndex = position525, tokenIndex525 + l527: + position, tokenIndex = position527, tokenIndex527 return false }, /* 39 RegisterOrConstant <- <((('%' ([a-z] / [A-Z]) ([a-z] / [A-Z] / ([0-9] / [0-9]))*) / ('$'? ((Offset Offset) / Offset)) / ('#' Offset ('*' [0-9]+ ('-' [0-9] [0-9]*)?)?) / ('#' '~'? '(' [0-9] WS? ('<' '<') WS? [0-9] ')') / ARMRegister) !('f' / 'b' / ':' / '(' / '+' / '-'))> */ func() bool { - position527, tokenIndex527 := position, tokenIndex + position529, tokenIndex529 := position, tokenIndex { - position528 := position + position530 := position { - position529, tokenIndex529 := position, tokenIndex + position531, tokenIndex531 := position, tokenIndex if buffer[position] != rune('%') { - goto l530 + goto l532 } position++ { - position531, tokenIndex531 := position, tokenIndex + position533, tokenIndex533 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l534 + } + position++ + goto l533 + l534: + position, tokenIndex = position533, tokenIndex533 + if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l532 } position++ - goto l531 - l532: - position, tokenIndex = position531, tokenIndex531 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l530 - } - position++ } - l531: l533: + l535: { - position534, tokenIndex534 := position, tokenIndex + position536, tokenIndex536 := position, tokenIndex { - position535, tokenIndex535 := position, tokenIndex + position537, tokenIndex537 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l536 - } - position++ - goto l535 - l536: - position, tokenIndex = position535, tokenIndex535 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l537 - } - position++ - goto l535 - l537: - position, tokenIndex = position535, tokenIndex535 - { - position538, tokenIndex538 := position, tokenIndex - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l539 - } - position++ goto l538 - l539: - position, tokenIndex = position538, tokenIndex538 + } + position++ + goto l537 + l538: + position, tokenIndex = position537, tokenIndex537 + if c := buffer[position]; c < rune('A') || c > rune('Z') { + goto l539 + } + position++ + goto l537 + l539: + position, tokenIndex = position537, tokenIndex537 + { + position540, tokenIndex540 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l534 + goto l541 + } + position++ + goto l540 + l541: + position, tokenIndex = position540, tokenIndex540 + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l536 } position++ } - l538: + l540: } - l535: - goto l533 - l534: - position, tokenIndex = position534, tokenIndex534 + l537: + goto l535 + l536: + position, tokenIndex = position536, tokenIndex536 } - goto l529 - l530: - position, tokenIndex = position529, tokenIndex529 - { - position541, tokenIndex541 := position, tokenIndex - if buffer[position] != rune('$') { - goto l541 - } - position++ - goto l542 - l541: - position, tokenIndex = position541, tokenIndex541 - } - l542: + goto l531 + l532: + position, tokenIndex = position531, tokenIndex531 { position543, tokenIndex543 := position, tokenIndex - if !_rules[ruleOffset]() { - goto l544 + if buffer[position] != rune('$') { + goto l543 } - if !_rules[ruleOffset]() { - goto l544 - } - goto l543 - l544: + position++ + goto l544 + l543: position, tokenIndex = position543, tokenIndex543 + } + l544: + { + position545, tokenIndex545 := position, tokenIndex if !_rules[ruleOffset]() { - goto l540 + goto l546 + } + if !_rules[ruleOffset]() { + goto l546 + } + goto l545 + l546: + position, tokenIndex = position545, tokenIndex545 + if !_rules[ruleOffset]() { + goto l542 } } - l543: - goto l529 - l540: - position, tokenIndex = position529, tokenIndex529 + l545: + goto l531 + l542: + position, tokenIndex = position531, tokenIndex531 if buffer[position] != rune('#') { - goto l545 + goto l547 } position++ if !_rules[ruleOffset]() { - goto l545 + goto l547 } { - position546, tokenIndex546 := position, tokenIndex + position548, tokenIndex548 := position, tokenIndex if buffer[position] != rune('*') { - goto l546 + goto l548 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l546 + goto l548 } position++ - l548: + l550: { - position549, tokenIndex549 := position, tokenIndex + position551, tokenIndex551 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l549 + goto l551 } position++ - goto l548 - l549: - position, tokenIndex = position549, tokenIndex549 + goto l550 + l551: + position, tokenIndex = position551, tokenIndex551 } { - position550, tokenIndex550 := position, tokenIndex + position552, tokenIndex552 := position, tokenIndex if buffer[position] != rune('-') { - goto l550 + goto l552 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l550 + goto l552 } position++ - l552: + l554: { - position553, tokenIndex553 := position, tokenIndex + position555, tokenIndex555 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l553 + goto l555 } position++ - goto l552 - l553: - position, tokenIndex = position553, tokenIndex553 + goto l554 + l555: + position, tokenIndex = position555, tokenIndex555 } - goto l551 - l550: - position, tokenIndex = position550, tokenIndex550 + goto l553 + l552: + position, tokenIndex = position552, tokenIndex552 } - l551: - goto l547 - l546: - position, tokenIndex = position546, tokenIndex546 + l553: + goto l549 + l548: + position, tokenIndex = position548, tokenIndex548 } + l549: + goto l531 l547: - goto l529 - l545: - position, tokenIndex = position529, tokenIndex529 + position, tokenIndex = position531, tokenIndex531 if buffer[position] != rune('#') { - goto l554 - } - position++ - { - position555, tokenIndex555 := position, tokenIndex - if buffer[position] != rune('~') { - goto l555 - } - position++ goto l556 - l555: - position, tokenIndex = position555, tokenIndex555 - } - l556: - if buffer[position] != rune('(') { - goto l554 - } - position++ - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l554 } position++ { position557, tokenIndex557 := position, tokenIndex - if !_rules[ruleWS]() { + if buffer[position] != rune('~') { goto l557 } + position++ goto l558 l557: position, tokenIndex = position557, tokenIndex557 } l558: - if buffer[position] != rune('<') { - goto l554 + if buffer[position] != rune('(') { + goto l556 } position++ - if buffer[position] != rune('<') { - goto l554 + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l556 } position++ { @@ -4482,400 +4504,402 @@ func (p *Asm) Init() { position, tokenIndex = position559, tokenIndex559 } l560: + if buffer[position] != rune('<') { + goto l556 + } + position++ + if buffer[position] != rune('<') { + goto l556 + } + position++ + { + position561, tokenIndex561 := position, tokenIndex + if !_rules[ruleWS]() { + goto l561 + } + goto l562 + l561: + position, tokenIndex = position561, tokenIndex561 + } + l562: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l554 + goto l556 } position++ if buffer[position] != rune(')') { - goto l554 + goto l556 } position++ - goto l529 - l554: - position, tokenIndex = position529, tokenIndex529 + goto l531 + l556: + position, tokenIndex = position531, tokenIndex531 if !_rules[ruleARMRegister]() { - goto l527 + goto l529 } } - l529: + l531: { - position561, tokenIndex561 := position, tokenIndex + position563, tokenIndex563 := position, tokenIndex { - position562, tokenIndex562 := position, tokenIndex + position564, tokenIndex564 := position, tokenIndex if buffer[position] != rune('f') { - goto l563 - } - position++ - goto l562 - l563: - position, tokenIndex = position562, tokenIndex562 - if buffer[position] != rune('b') { - goto l564 - } - position++ - goto l562 - l564: - position, tokenIndex = position562, tokenIndex562 - if buffer[position] != rune(':') { goto l565 } position++ - goto l562 + goto l564 l565: - position, tokenIndex = position562, tokenIndex562 - if buffer[position] != rune('(') { + position, tokenIndex = position564, tokenIndex564 + if buffer[position] != rune('b') { goto l566 } position++ - goto l562 + goto l564 l566: - position, tokenIndex = position562, tokenIndex562 - if buffer[position] != rune('+') { + position, tokenIndex = position564, tokenIndex564 + if buffer[position] != rune(':') { goto l567 } position++ - goto l562 + goto l564 l567: - position, tokenIndex = position562, tokenIndex562 + position, tokenIndex = position564, tokenIndex564 + if buffer[position] != rune('(') { + goto l568 + } + position++ + goto l564 + l568: + position, tokenIndex = position564, tokenIndex564 + if buffer[position] != rune('+') { + goto l569 + } + position++ + goto l564 + l569: + position, tokenIndex = position564, tokenIndex564 if buffer[position] != rune('-') { - goto l561 + goto l563 } position++ } - l562: - goto l527 - l561: - position, tokenIndex = position561, tokenIndex561 + l564: + goto l529 + l563: + position, tokenIndex = position563, tokenIndex563 } - add(ruleRegisterOrConstant, position528) + add(ruleRegisterOrConstant, position530) } return true - l527: - position, tokenIndex = position527, tokenIndex527 + l529: + position, tokenIndex = position529, tokenIndex529 return false }, - /* 40 ARMConstantTweak <- <(((('l' / 'L') ('s' / 'S') ('l' / 'L')) / (('s' / 'S') ('x' / 'X') ('t' / 'T') ('w' / 'W')) / (('s' / 'S') ('x' / 'X') ('t' / 'T') ('b' / 'B')) / (('u' / 'U') ('x' / 'X') ('t' / 'T') ('w' / 'W')) / (('u' / 'U') ('x' / 'X') ('t' / 'T') ('b' / 'B')) / (('l' / 'L') ('s' / 'S') ('r' / 'R')) / (('r' / 'R') ('o' / 'O') ('r' / 'R')) / (('a' / 'A') ('s' / 'S') ('r' / 'R'))) (WS '#' Offset)?)> */ + /* 40 ARMConstantTweak <- <(((('u' / 's') (('x' / 'X') ('t' / 'T')) ('x' / 'w' / 'h' / 'b')) / (('l' / 'L') ('s' / 'S') ('l' / 'L')) / (('l' / 'L') ('s' / 'S') ('r' / 'R')) / (('r' / 'R') ('o' / 'O') ('r' / 'R')) / (('a' / 'A') ('s' / 'S') ('r' / 'R'))) (WS '#' Offset)?)> */ func() bool { - position568, tokenIndex568 := position, tokenIndex + position570, tokenIndex570 := position, tokenIndex { - position569 := position + position571 := position { - position570, tokenIndex570 := position, tokenIndex - { - position572, tokenIndex572 := position, tokenIndex - if buffer[position] != rune('l') { - goto l573 - } - position++ - goto l572 - l573: - position, tokenIndex = position572, tokenIndex572 - if buffer[position] != rune('L') { - goto l571 - } - position++ - } - l572: + position572, tokenIndex572 := position, tokenIndex { position574, tokenIndex574 := position, tokenIndex - if buffer[position] != rune('s') { + if buffer[position] != rune('u') { goto l575 } position++ goto l574 l575: position, tokenIndex = position574, tokenIndex574 - if buffer[position] != rune('S') { - goto l571 + if buffer[position] != rune('s') { + goto l573 } position++ } l574: { position576, tokenIndex576 := position, tokenIndex - if buffer[position] != rune('l') { + if buffer[position] != rune('x') { goto l577 } position++ goto l576 l577: position, tokenIndex = position576, tokenIndex576 - if buffer[position] != rune('L') { - goto l571 + if buffer[position] != rune('X') { + goto l573 } position++ } l576: - goto l570 - l571: - position, tokenIndex = position570, tokenIndex570 { - position579, tokenIndex579 := position, tokenIndex - if buffer[position] != rune('s') { - goto l580 + position578, tokenIndex578 := position, tokenIndex + if buffer[position] != rune('t') { + goto l579 } position++ - goto l579 - l580: - position, tokenIndex = position579, tokenIndex579 - if buffer[position] != rune('S') { - goto l578 + goto l578 + l579: + position, tokenIndex = position578, tokenIndex578 + if buffer[position] != rune('T') { + goto l573 } position++ } - l579: + l578: { - position581, tokenIndex581 := position, tokenIndex + position580, tokenIndex580 := position, tokenIndex if buffer[position] != rune('x') { + goto l581 + } + position++ + goto l580 + l581: + position, tokenIndex = position580, tokenIndex580 + if buffer[position] != rune('w') { goto l582 } position++ - goto l581 + goto l580 l582: - position, tokenIndex = position581, tokenIndex581 - if buffer[position] != rune('X') { - goto l578 + position, tokenIndex = position580, tokenIndex580 + if buffer[position] != rune('h') { + goto l583 + } + position++ + goto l580 + l583: + position, tokenIndex = position580, tokenIndex580 + if buffer[position] != rune('b') { + goto l573 } position++ } - l581: - { - position583, tokenIndex583 := position, tokenIndex - if buffer[position] != rune('t') { - goto l584 - } - position++ - goto l583 - l584: - position, tokenIndex = position583, tokenIndex583 - if buffer[position] != rune('T') { - goto l578 - } - position++ - } - l583: + l580: + goto l572 + l573: + position, tokenIndex = position572, tokenIndex572 { position585, tokenIndex585 := position, tokenIndex - if buffer[position] != rune('w') { + if buffer[position] != rune('l') { goto l586 } position++ goto l585 l586: position, tokenIndex = position585, tokenIndex585 - if buffer[position] != rune('W') { - goto l578 + if buffer[position] != rune('L') { + goto l584 } position++ } l585: - goto l570 - l578: - position, tokenIndex = position570, tokenIndex570 { - position588, tokenIndex588 := position, tokenIndex + position587, tokenIndex587 := position, tokenIndex if buffer[position] != rune('s') { - goto l589 + goto l588 } position++ - goto l588 - l589: - position, tokenIndex = position588, tokenIndex588 + goto l587 + l588: + position, tokenIndex = position587, tokenIndex587 if buffer[position] != rune('S') { - goto l587 + goto l584 } position++ } - l588: + l587: { - position590, tokenIndex590 := position, tokenIndex - if buffer[position] != rune('x') { - goto l591 + position589, tokenIndex589 := position, tokenIndex + if buffer[position] != rune('l') { + goto l590 } position++ - goto l590 - l591: - position, tokenIndex = position590, tokenIndex590 - if buffer[position] != rune('X') { - goto l587 + goto l589 + l590: + position, tokenIndex = position589, tokenIndex589 + if buffer[position] != rune('L') { + goto l584 } position++ } - l590: + l589: + goto l572 + l584: + position, tokenIndex = position572, tokenIndex572 { position592, tokenIndex592 := position, tokenIndex - if buffer[position] != rune('t') { + if buffer[position] != rune('l') { goto l593 } position++ goto l592 l593: position, tokenIndex = position592, tokenIndex592 - if buffer[position] != rune('T') { - goto l587 + if buffer[position] != rune('L') { + goto l591 } position++ } l592: { position594, tokenIndex594 := position, tokenIndex - if buffer[position] != rune('b') { + if buffer[position] != rune('s') { goto l595 } position++ goto l594 l595: position, tokenIndex = position594, tokenIndex594 - if buffer[position] != rune('B') { - goto l587 + if buffer[position] != rune('S') { + goto l591 } position++ } l594: - goto l570 - l587: - position, tokenIndex = position570, tokenIndex570 { - position597, tokenIndex597 := position, tokenIndex - if buffer[position] != rune('u') { - goto l598 + position596, tokenIndex596 := position, tokenIndex + if buffer[position] != rune('r') { + goto l597 } position++ - goto l597 - l598: - position, tokenIndex = position597, tokenIndex597 - if buffer[position] != rune('U') { - goto l596 + goto l596 + l597: + position, tokenIndex = position596, tokenIndex596 + if buffer[position] != rune('R') { + goto l591 } position++ } - l597: + l596: + goto l572 + l591: + position, tokenIndex = position572, tokenIndex572 { position599, tokenIndex599 := position, tokenIndex - if buffer[position] != rune('x') { + if buffer[position] != rune('r') { goto l600 } position++ goto l599 l600: position, tokenIndex = position599, tokenIndex599 - if buffer[position] != rune('X') { - goto l596 + if buffer[position] != rune('R') { + goto l598 } position++ } l599: { position601, tokenIndex601 := position, tokenIndex - if buffer[position] != rune('t') { + if buffer[position] != rune('o') { goto l602 } position++ goto l601 l602: position, tokenIndex = position601, tokenIndex601 - if buffer[position] != rune('T') { - goto l596 + if buffer[position] != rune('O') { + goto l598 } position++ } l601: { position603, tokenIndex603 := position, tokenIndex - if buffer[position] != rune('w') { + if buffer[position] != rune('r') { goto l604 } position++ goto l603 l604: position, tokenIndex = position603, tokenIndex603 - if buffer[position] != rune('W') { - goto l596 + if buffer[position] != rune('R') { + goto l598 } position++ } l603: - goto l570 - l596: - position, tokenIndex = position570, tokenIndex570 + goto l572 + l598: + position, tokenIndex = position572, tokenIndex572 { - position606, tokenIndex606 := position, tokenIndex - if buffer[position] != rune('u') { - goto l607 + position605, tokenIndex605 := position, tokenIndex + if buffer[position] != rune('a') { + goto l606 } position++ - goto l606 - l607: - position, tokenIndex = position606, tokenIndex606 - if buffer[position] != rune('U') { - goto l605 + goto l605 + l606: + position, tokenIndex = position605, tokenIndex605 + if buffer[position] != rune('A') { + goto l570 } position++ } - l606: - { - position608, tokenIndex608 := position, tokenIndex - if buffer[position] != rune('x') { - goto l609 - } - position++ - goto l608 - l609: - position, tokenIndex = position608, tokenIndex608 - if buffer[position] != rune('X') { - goto l605 - } - position++ - } - l608: - { - position610, tokenIndex610 := position, tokenIndex - if buffer[position] != rune('t') { - goto l611 - } - position++ - goto l610 - l611: - position, tokenIndex = position610, tokenIndex610 - if buffer[position] != rune('T') { - goto l605 - } - position++ - } - l610: - { - position612, tokenIndex612 := position, tokenIndex - if buffer[position] != rune('b') { - goto l613 - } - position++ - goto l612 - l613: - position, tokenIndex = position612, tokenIndex612 - if buffer[position] != rune('B') { - goto l605 - } - position++ - } - l612: - goto l570 l605: - position, tokenIndex = position570, tokenIndex570 { - position615, tokenIndex615 := position, tokenIndex - if buffer[position] != rune('l') { - goto l616 + position607, tokenIndex607 := position, tokenIndex + if buffer[position] != rune('s') { + goto l608 } position++ - goto l615 - l616: - position, tokenIndex = position615, tokenIndex615 - if buffer[position] != rune('L') { - goto l614 + goto l607 + l608: + position, tokenIndex = position607, tokenIndex607 + if buffer[position] != rune('S') { + goto l570 } position++ } - l615: + l607: + { + position609, tokenIndex609 := position, tokenIndex + if buffer[position] != rune('r') { + goto l610 + } + position++ + goto l609 + l610: + position, tokenIndex = position609, tokenIndex609 + if buffer[position] != rune('R') { + goto l570 + } + position++ + } + l609: + } + l572: + { + position611, tokenIndex611 := position, tokenIndex + if !_rules[ruleWS]() { + goto l611 + } + if buffer[position] != rune('#') { + goto l611 + } + position++ + if !_rules[ruleOffset]() { + goto l611 + } + goto l612 + l611: + position, tokenIndex = position611, tokenIndex611 + } + l612: + add(ruleARMConstantTweak, position571) + } + return true + l570: + position, tokenIndex = position570, tokenIndex570 + return false + }, + /* 41 ARMRegister <- <((('s' / 'S') ('p' / 'P')) / (('x' / 'w' / 'd' / 'q' / 's' / 'h' / 'b') [0-9] [0-9]?) / (('x' / 'X') ('z' / 'Z') ('r' / 'R')) / (('w' / 'W') ('z' / 'Z') ('r' / 'R')) / (('n' / 'N') ('z' / 'Z') ('c' / 'C') ('v' / 'V')) / ARMVectorRegister / ('{' WS? ARMVectorRegister (',' WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')?))> */ + func() bool { + position613, tokenIndex613 := position, tokenIndex + { + position614 := position + { + position615, tokenIndex615 := position, tokenIndex { position617, tokenIndex617 := position, tokenIndex if buffer[position] != rune('s') { @@ -4886,1516 +4910,1516 @@ func (p *Asm) Init() { l618: position, tokenIndex = position617, tokenIndex617 if buffer[position] != rune('S') { - goto l614 + goto l616 } position++ } l617: { position619, tokenIndex619 := position, tokenIndex - if buffer[position] != rune('r') { + if buffer[position] != rune('p') { goto l620 } position++ goto l619 l620: position, tokenIndex = position619, tokenIndex619 - if buffer[position] != rune('R') { - goto l614 + if buffer[position] != rune('P') { + goto l616 } position++ } l619: - goto l570 - l614: - position, tokenIndex = position570, tokenIndex570 + goto l615 + l616: + position, tokenIndex = position615, tokenIndex615 { position622, tokenIndex622 := position, tokenIndex - if buffer[position] != rune('r') { + if buffer[position] != rune('x') { goto l623 } position++ goto l622 l623: position, tokenIndex = position622, tokenIndex622 - if buffer[position] != rune('R') { + if buffer[position] != rune('w') { + goto l624 + } + position++ + goto l622 + l624: + position, tokenIndex = position622, tokenIndex622 + if buffer[position] != rune('d') { + goto l625 + } + position++ + goto l622 + l625: + position, tokenIndex = position622, tokenIndex622 + if buffer[position] != rune('q') { + goto l626 + } + position++ + goto l622 + l626: + position, tokenIndex = position622, tokenIndex622 + if buffer[position] != rune('s') { + goto l627 + } + position++ + goto l622 + l627: + position, tokenIndex = position622, tokenIndex622 + if buffer[position] != rune('h') { + goto l628 + } + position++ + goto l622 + l628: + position, tokenIndex = position622, tokenIndex622 + if buffer[position] != rune('b') { goto l621 } position++ } l622: - { - position624, tokenIndex624 := position, tokenIndex - if buffer[position] != rune('o') { - goto l625 - } - position++ - goto l624 - l625: - position, tokenIndex = position624, tokenIndex624 - if buffer[position] != rune('O') { - goto l621 - } - position++ + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l621 } - l624: + position++ { - position626, tokenIndex626 := position, tokenIndex - if buffer[position] != rune('r') { - goto l627 - } - position++ - goto l626 - l627: - position, tokenIndex = position626, tokenIndex626 - if buffer[position] != rune('R') { - goto l621 - } - position++ - } - l626: - goto l570 - l621: - position, tokenIndex = position570, tokenIndex570 - { - position628, tokenIndex628 := position, tokenIndex - if buffer[position] != rune('a') { + position629, tokenIndex629 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { goto l629 } position++ - goto l628 - l629: - position, tokenIndex = position628, tokenIndex628 - if buffer[position] != rune('A') { - goto l568 - } - position++ - } - l628: - { - position630, tokenIndex630 := position, tokenIndex - if buffer[position] != rune('s') { - goto l631 - } - position++ goto l630 - l631: - position, tokenIndex = position630, tokenIndex630 - if buffer[position] != rune('S') { - goto l568 - } - position++ + l629: + position, tokenIndex = position629, tokenIndex629 } l630: + goto l615 + l621: + position, tokenIndex = position615, tokenIndex615 { position632, tokenIndex632 := position, tokenIndex - if buffer[position] != rune('r') { + if buffer[position] != rune('x') { goto l633 } position++ goto l632 l633: position, tokenIndex = position632, tokenIndex632 - if buffer[position] != rune('R') { - goto l568 + if buffer[position] != rune('X') { + goto l631 } position++ } l632: - } - l570: - { - position634, tokenIndex634 := position, tokenIndex - if !_rules[ruleWS]() { + { + position634, tokenIndex634 := position, tokenIndex + if buffer[position] != rune('z') { + goto l635 + } + position++ goto l634 + l635: + position, tokenIndex = position634, tokenIndex634 + if buffer[position] != rune('Z') { + goto l631 + } + position++ } - if buffer[position] != rune('#') { - goto l634 - } - position++ - if !_rules[ruleOffset]() { - goto l634 - } - goto l635 l634: - position, tokenIndex = position634, tokenIndex634 - } - l635: - add(ruleARMConstantTweak, position569) - } - return true - l568: - position, tokenIndex = position568, tokenIndex568 - return false - }, - /* 41 ARMRegister <- <((('s' / 'S') ('p' / 'P')) / (('x' / 'w' / 'd' / 'q' / 's') [0-9] [0-9]?) / (('x' / 'X') ('z' / 'Z') ('r' / 'R')) / (('w' / 'W') ('z' / 'Z') ('r' / 'R')) / ARMVectorRegister / ('{' WS? ARMVectorRegister (',' WS? ARMVectorRegister)* WS? '}' ('[' [0-9] [0-9]? ']')?))> */ - func() bool { - position636, tokenIndex636 := position, tokenIndex - { - position637 := position - { - position638, tokenIndex638 := position, tokenIndex { - position640, tokenIndex640 := position, tokenIndex - if buffer[position] != rune('s') { - goto l641 + position636, tokenIndex636 := position, tokenIndex + if buffer[position] != rune('r') { + goto l637 } position++ - goto l640 - l641: - position, tokenIndex = position640, tokenIndex640 - if buffer[position] != rune('S') { - goto l639 + goto l636 + l637: + position, tokenIndex = position636, tokenIndex636 + if buffer[position] != rune('R') { + goto l631 } position++ } - l640: + l636: + goto l615 + l631: + position, tokenIndex = position615, tokenIndex615 { - position642, tokenIndex642 := position, tokenIndex - if buffer[position] != rune('p') { - goto l643 - } - position++ - goto l642 - l643: - position, tokenIndex = position642, tokenIndex642 - if buffer[position] != rune('P') { - goto l639 - } - position++ - } - l642: - goto l638 - l639: - position, tokenIndex = position638, tokenIndex638 - { - position645, tokenIndex645 := position, tokenIndex - if buffer[position] != rune('x') { - goto l646 - } - position++ - goto l645 - l646: - position, tokenIndex = position645, tokenIndex645 + position639, tokenIndex639 := position, tokenIndex if buffer[position] != rune('w') { - goto l647 + goto l640 } position++ - goto l645 - l647: - position, tokenIndex = position645, tokenIndex645 - if buffer[position] != rune('d') { - goto l648 + goto l639 + l640: + position, tokenIndex = position639, tokenIndex639 + if buffer[position] != rune('W') { + goto l638 } position++ - goto l645 - l648: - position, tokenIndex = position645, tokenIndex645 - if buffer[position] != rune('q') { - goto l649 + } + l639: + { + position641, tokenIndex641 := position, tokenIndex + if buffer[position] != rune('z') { + goto l642 } position++ - goto l645 - l649: - position, tokenIndex = position645, tokenIndex645 - if buffer[position] != rune('s') { + goto l641 + l642: + position, tokenIndex = position641, tokenIndex641 + if buffer[position] != rune('Z') { + goto l638 + } + position++ + } + l641: + { + position643, tokenIndex643 := position, tokenIndex + if buffer[position] != rune('r') { goto l644 } position++ + goto l643 + l644: + position, tokenIndex = position643, tokenIndex643 + if buffer[position] != rune('R') { + goto l638 + } + position++ } + l643: + goto l615 + l638: + position, tokenIndex = position615, tokenIndex615 + { + position646, tokenIndex646 := position, tokenIndex + if buffer[position] != rune('n') { + goto l647 + } + position++ + goto l646 + l647: + position, tokenIndex = position646, tokenIndex646 + if buffer[position] != rune('N') { + goto l645 + } + position++ + } + l646: + { + position648, tokenIndex648 := position, tokenIndex + if buffer[position] != rune('z') { + goto l649 + } + position++ + goto l648 + l649: + position, tokenIndex = position648, tokenIndex648 + if buffer[position] != rune('Z') { + goto l645 + } + position++ + } + l648: + { + position650, tokenIndex650 := position, tokenIndex + if buffer[position] != rune('c') { + goto l651 + } + position++ + goto l650 + l651: + position, tokenIndex = position650, tokenIndex650 + if buffer[position] != rune('C') { + goto l645 + } + position++ + } + l650: + { + position652, tokenIndex652 := position, tokenIndex + if buffer[position] != rune('v') { + goto l653 + } + position++ + goto l652 + l653: + position, tokenIndex = position652, tokenIndex652 + if buffer[position] != rune('V') { + goto l645 + } + position++ + } + l652: + goto l615 l645: - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l644 + position, tokenIndex = position615, tokenIndex615 + if !_rules[ruleARMVectorRegister]() { + goto l654 + } + goto l615 + l654: + position, tokenIndex = position615, tokenIndex615 + if buffer[position] != rune('{') { + goto l613 } position++ - { - position650, tokenIndex650 := position, tokenIndex - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l650 - } - position++ - goto l651 - l650: - position, tokenIndex = position650, tokenIndex650 - } - l651: - goto l638 - l644: - position, tokenIndex = position638, tokenIndex638 - { - position653, tokenIndex653 := position, tokenIndex - if buffer[position] != rune('x') { - goto l654 - } - position++ - goto l653 - l654: - position, tokenIndex = position653, tokenIndex653 - if buffer[position] != rune('X') { - goto l652 - } - position++ - } - l653: { position655, tokenIndex655 := position, tokenIndex - if buffer[position] != rune('z') { - goto l656 + if !_rules[ruleWS]() { + goto l655 } - position++ - goto l655 - l656: + goto l656 + l655: position, tokenIndex = position655, tokenIndex655 - if buffer[position] != rune('Z') { - goto l652 - } - position++ } - l655: + l656: + if !_rules[ruleARMVectorRegister]() { + goto l613 + } + l657: { - position657, tokenIndex657 := position, tokenIndex - if buffer[position] != rune('r') { + position658, tokenIndex658 := position, tokenIndex + if buffer[position] != rune(',') { goto l658 } position++ + { + position659, tokenIndex659 := position, tokenIndex + if !_rules[ruleWS]() { + goto l659 + } + goto l660 + l659: + position, tokenIndex = position659, tokenIndex659 + } + l660: + if !_rules[ruleARMVectorRegister]() { + goto l658 + } goto l657 l658: - position, tokenIndex = position657, tokenIndex657 - if buffer[position] != rune('R') { - goto l652 - } - position++ + position, tokenIndex = position658, tokenIndex658 } - l657: - goto l638 - l652: - position, tokenIndex = position638, tokenIndex638 { - position660, tokenIndex660 := position, tokenIndex - if buffer[position] != rune('w') { + position661, tokenIndex661 := position, tokenIndex + if !_rules[ruleWS]() { goto l661 } - position++ - goto l660 + goto l662 l661: - position, tokenIndex = position660, tokenIndex660 - if buffer[position] != rune('W') { - goto l659 - } - position++ + position, tokenIndex = position661, tokenIndex661 } - l660: + l662: + if buffer[position] != rune('}') { + goto l613 + } + position++ { - position662, tokenIndex662 := position, tokenIndex - if buffer[position] != rune('z') { + position663, tokenIndex663 := position, tokenIndex + if buffer[position] != rune('[') { goto l663 } position++ - goto l662 - l663: - position, tokenIndex = position662, tokenIndex662 - if buffer[position] != rune('Z') { - goto l659 + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l663 } position++ - } - l662: - { - position664, tokenIndex664 := position, tokenIndex - if buffer[position] != rune('r') { - goto l665 + { + position665, tokenIndex665 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l665 + } + position++ + goto l666 + l665: + position, tokenIndex = position665, tokenIndex665 + } + l666: + if buffer[position] != rune(']') { + goto l663 } position++ goto l664 - l665: - position, tokenIndex = position664, tokenIndex664 - if buffer[position] != rune('R') { - goto l659 - } - position++ + l663: + position, tokenIndex = position663, tokenIndex663 } l664: - goto l638 - l659: - position, tokenIndex = position638, tokenIndex638 - if !_rules[ruleARMVectorRegister]() { - goto l666 - } - goto l638 - l666: - position, tokenIndex = position638, tokenIndex638 - if buffer[position] != rune('{') { - goto l636 - } - position++ - { - position667, tokenIndex667 := position, tokenIndex - if !_rules[ruleWS]() { - goto l667 - } - goto l668 - l667: - position, tokenIndex = position667, tokenIndex667 - } - l668: - if !_rules[ruleARMVectorRegister]() { - goto l636 - } - l669: - { - position670, tokenIndex670 := position, tokenIndex - if buffer[position] != rune(',') { - goto l670 - } - position++ - { - position671, tokenIndex671 := position, tokenIndex - if !_rules[ruleWS]() { - goto l671 - } - goto l672 - l671: - position, tokenIndex = position671, tokenIndex671 - } - l672: - if !_rules[ruleARMVectorRegister]() { - goto l670 - } - goto l669 - l670: - position, tokenIndex = position670, tokenIndex670 - } - { - position673, tokenIndex673 := position, tokenIndex - if !_rules[ruleWS]() { - goto l673 - } - goto l674 - l673: - position, tokenIndex = position673, tokenIndex673 - } - l674: - if buffer[position] != rune('}') { - goto l636 - } - position++ - { - position675, tokenIndex675 := position, tokenIndex - if buffer[position] != rune('[') { - goto l675 - } - position++ - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l675 - } - position++ - { - position677, tokenIndex677 := position, tokenIndex - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l677 - } - position++ - goto l678 - l677: - position, tokenIndex = position677, tokenIndex677 - } - l678: - if buffer[position] != rune(']') { - goto l675 - } - position++ - goto l676 - l675: - position, tokenIndex = position675, tokenIndex675 - } - l676: } - l638: - add(ruleARMRegister, position637) + l615: + add(ruleARMRegister, position614) } return true - l636: - position, tokenIndex = position636, tokenIndex636 + l613: + position, tokenIndex = position613, tokenIndex613 return false }, /* 42 ARMVectorRegister <- <(('v' / 'V') [0-9] [0-9]? ('.' [0-9]* ('b' / 's' / 'd' / 'h' / 'q') ('[' [0-9] [0-9]? ']')?)?)> */ func() bool { - position679, tokenIndex679 := position, tokenIndex + position667, tokenIndex667 := position, tokenIndex { - position680 := position + position668 := position { - position681, tokenIndex681 := position, tokenIndex + position669, tokenIndex669 := position, tokenIndex if buffer[position] != rune('v') { - goto l682 + goto l670 } position++ - goto l681 - l682: - position, tokenIndex = position681, tokenIndex681 + goto l669 + l670: + position, tokenIndex = position669, tokenIndex669 if buffer[position] != rune('V') { - goto l679 + goto l667 } position++ } - l681: + l669: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l679 + goto l667 } position++ { - position683, tokenIndex683 := position, tokenIndex + position671, tokenIndex671 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l683 + goto l671 } position++ - goto l684 - l683: - position, tokenIndex = position683, tokenIndex683 + goto l672 + l671: + position, tokenIndex = position671, tokenIndex671 } - l684: + l672: { - position685, tokenIndex685 := position, tokenIndex + position673, tokenIndex673 := position, tokenIndex if buffer[position] != rune('.') { - goto l685 + goto l673 } position++ - l687: + l675: { - position688, tokenIndex688 := position, tokenIndex + position676, tokenIndex676 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l688 + goto l676 } position++ - goto l687 - l688: - position, tokenIndex = position688, tokenIndex688 + goto l675 + l676: + position, tokenIndex = position676, tokenIndex676 } { - position689, tokenIndex689 := position, tokenIndex + position677, tokenIndex677 := position, tokenIndex if buffer[position] != rune('b') { - goto l690 + goto l678 } position++ - goto l689 - l690: - position, tokenIndex = position689, tokenIndex689 + goto l677 + l678: + position, tokenIndex = position677, tokenIndex677 if buffer[position] != rune('s') { - goto l691 + goto l679 } position++ - goto l689 - l691: - position, tokenIndex = position689, tokenIndex689 + goto l677 + l679: + position, tokenIndex = position677, tokenIndex677 if buffer[position] != rune('d') { - goto l692 + goto l680 } position++ - goto l689 - l692: - position, tokenIndex = position689, tokenIndex689 + goto l677 + l680: + position, tokenIndex = position677, tokenIndex677 if buffer[position] != rune('h') { - goto l693 + goto l681 } position++ - goto l689 - l693: - position, tokenIndex = position689, tokenIndex689 + goto l677 + l681: + position, tokenIndex = position677, tokenIndex677 if buffer[position] != rune('q') { - goto l685 + goto l673 } position++ } - l689: + l677: { - position694, tokenIndex694 := position, tokenIndex + position682, tokenIndex682 := position, tokenIndex if buffer[position] != rune('[') { - goto l694 + goto l682 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l694 + goto l682 } position++ { - position696, tokenIndex696 := position, tokenIndex + position684, tokenIndex684 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l696 + goto l684 } position++ - goto l697 - l696: - position, tokenIndex = position696, tokenIndex696 + goto l685 + l684: + position, tokenIndex = position684, tokenIndex684 } - l697: + l685: if buffer[position] != rune(']') { - goto l694 + goto l682 } position++ - goto l695 - l694: - position, tokenIndex = position694, tokenIndex694 + goto l683 + l682: + position, tokenIndex = position682, tokenIndex682 } - l695: - goto l686 - l685: - position, tokenIndex = position685, tokenIndex685 + l683: + goto l674 + l673: + position, tokenIndex = position673, tokenIndex673 } - l686: - add(ruleARMVectorRegister, position680) + l674: + add(ruleARMVectorRegister, position668) } return true - l679: - position, tokenIndex = position679, tokenIndex679 + l667: + position, tokenIndex = position667, tokenIndex667 return false }, /* 43 MemoryRef <- <((SymbolRef BaseIndexScale) / SymbolRef / Low12BitsSymbolRef / (Offset* BaseIndexScale) / (SegmentRegister Offset BaseIndexScale) / (SegmentRegister BaseIndexScale) / (SegmentRegister Offset) / ARMBaseIndexScale / BaseIndexScale)> */ func() bool { - position698, tokenIndex698 := position, tokenIndex + position686, tokenIndex686 := position, tokenIndex { - position699 := position + position687 := position { - position700, tokenIndex700 := position, tokenIndex + position688, tokenIndex688 := position, tokenIndex if !_rules[ruleSymbolRef]() { - goto l701 + goto l689 } if !_rules[ruleBaseIndexScale]() { - goto l701 + goto l689 } - goto l700 - l701: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l689: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleSymbolRef]() { - goto l702 + goto l690 } - goto l700 - l702: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l690: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleLow12BitsSymbolRef]() { - goto l703 + goto l691 } - goto l700 - l703: - position, tokenIndex = position700, tokenIndex700 - l705: + goto l688 + l691: + position, tokenIndex = position688, tokenIndex688 + l693: { - position706, tokenIndex706 := position, tokenIndex + position694, tokenIndex694 := position, tokenIndex if !_rules[ruleOffset]() { - goto l706 + goto l694 } - goto l705 - l706: - position, tokenIndex = position706, tokenIndex706 + goto l693 + l694: + position, tokenIndex = position694, tokenIndex694 } if !_rules[ruleBaseIndexScale]() { - goto l704 + goto l692 } - goto l700 - l704: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l692: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleSegmentRegister]() { - goto l707 + goto l695 } if !_rules[ruleOffset]() { - goto l707 + goto l695 } if !_rules[ruleBaseIndexScale]() { - goto l707 + goto l695 } - goto l700 - l707: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l695: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleSegmentRegister]() { - goto l708 + goto l696 } if !_rules[ruleBaseIndexScale]() { - goto l708 + goto l696 } - goto l700 - l708: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l696: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleSegmentRegister]() { - goto l709 + goto l697 } if !_rules[ruleOffset]() { - goto l709 + goto l697 } - goto l700 - l709: - position, tokenIndex = position700, tokenIndex700 + goto l688 + l697: + position, tokenIndex = position688, tokenIndex688 if !_rules[ruleARMBaseIndexScale]() { - goto l710 - } - goto l700 - l710: - position, tokenIndex = position700, tokenIndex700 - if !_rules[ruleBaseIndexScale]() { goto l698 } + goto l688 + l698: + position, tokenIndex = position688, tokenIndex688 + if !_rules[ruleBaseIndexScale]() { + goto l686 + } } - l700: - add(ruleMemoryRef, position699) + l688: + add(ruleMemoryRef, position687) } return true - l698: - position, tokenIndex = position698, tokenIndex698 + l686: + position, tokenIndex = position686, tokenIndex686 return false }, /* 44 SymbolRef <- <((Offset* '+')? (LocalSymbol / SymbolName) Offset* ('@' Section Offset*)?)> */ func() bool { - position711, tokenIndex711 := position, tokenIndex + position699, tokenIndex699 := position, tokenIndex { - position712 := position + position700 := position { - position713, tokenIndex713 := position, tokenIndex - l715: + position701, tokenIndex701 := position, tokenIndex + l703: { - position716, tokenIndex716 := position, tokenIndex + position704, tokenIndex704 := position, tokenIndex if !_rules[ruleOffset]() { - goto l716 + goto l704 } - goto l715 - l716: - position, tokenIndex = position716, tokenIndex716 + goto l703 + l704: + position, tokenIndex = position704, tokenIndex704 } if buffer[position] != rune('+') { + goto l701 + } + position++ + goto l702 + l701: + position, tokenIndex = position701, tokenIndex701 + } + l702: + { + position705, tokenIndex705 := position, tokenIndex + if !_rules[ruleLocalSymbol]() { + goto l706 + } + goto l705 + l706: + position, tokenIndex = position705, tokenIndex705 + if !_rules[ruleSymbolName]() { + goto l699 + } + } + l705: + l707: + { + position708, tokenIndex708 := position, tokenIndex + if !_rules[ruleOffset]() { + goto l708 + } + goto l707 + l708: + position, tokenIndex = position708, tokenIndex708 + } + { + position709, tokenIndex709 := position, tokenIndex + if buffer[position] != rune('@') { + goto l709 + } + position++ + if !_rules[ruleSection]() { + goto l709 + } + l711: + { + position712, tokenIndex712 := position, tokenIndex + if !_rules[ruleOffset]() { + goto l712 + } + goto l711 + l712: + position, tokenIndex = position712, tokenIndex712 + } + goto l710 + l709: + position, tokenIndex = position709, tokenIndex709 + } + l710: + add(ruleSymbolRef, position700) + } + return true + l699: + position, tokenIndex = position699, tokenIndex699 + return false + }, + /* 45 Low12BitsSymbolRef <- <(':' ('l' / 'L') ('o' / 'O') '1' '2' ':' (LocalSymbol / SymbolName) Offset?)> */ + func() bool { + position713, tokenIndex713 := position, tokenIndex + { + position714 := position + if buffer[position] != rune(':') { + goto l713 + } + position++ + { + position715, tokenIndex715 := position, tokenIndex + if buffer[position] != rune('l') { + goto l716 + } + position++ + goto l715 + l716: + position, tokenIndex = position715, tokenIndex715 + if buffer[position] != rune('L') { goto l713 } position++ - goto l714 - l713: - position, tokenIndex = position713, tokenIndex713 } - l714: + l715: { position717, tokenIndex717 := position, tokenIndex - if !_rules[ruleLocalSymbol]() { + if buffer[position] != rune('o') { goto l718 } + position++ goto l717 l718: position, tokenIndex = position717, tokenIndex717 - if !_rules[ruleSymbolName]() { - goto l711 + if buffer[position] != rune('O') { + goto l713 } + position++ } l717: - l719: + if buffer[position] != rune('1') { + goto l713 + } + position++ + if buffer[position] != rune('2') { + goto l713 + } + position++ + if buffer[position] != rune(':') { + goto l713 + } + position++ { - position720, tokenIndex720 := position, tokenIndex - if !_rules[ruleOffset]() { + position719, tokenIndex719 := position, tokenIndex + if !_rules[ruleLocalSymbol]() { goto l720 } goto l719 l720: - position, tokenIndex = position720, tokenIndex720 + position, tokenIndex = position719, tokenIndex719 + if !_rules[ruleSymbolName]() { + goto l713 + } } + l719: { position721, tokenIndex721 := position, tokenIndex - if buffer[position] != rune('@') { + if !_rules[ruleOffset]() { goto l721 } - position++ - if !_rules[ruleSection]() { - goto l721 - } - l723: - { - position724, tokenIndex724 := position, tokenIndex - if !_rules[ruleOffset]() { - goto l724 - } - goto l723 - l724: - position, tokenIndex = position724, tokenIndex724 - } goto l722 l721: position, tokenIndex = position721, tokenIndex721 } l722: - add(ruleSymbolRef, position712) + add(ruleLow12BitsSymbolRef, position714) } return true - l711: - position, tokenIndex = position711, tokenIndex711 + l713: + position, tokenIndex = position713, tokenIndex713 return false }, - /* 45 Low12BitsSymbolRef <- <(':' ('l' / 'L') ('o' / 'O') '1' '2' ':' (LocalSymbol / SymbolName) Offset?)> */ + /* 46 ARMBaseIndexScale <- <('[' ARMRegister (',' WS? (('#' Offset (('*' [0-9]+) / ('*' '(' [0-9]+ Operator [0-9]+ ')') / ('+' [0-9]+)*)?) / ARMGOTLow12 / Low12BitsSymbolRef / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement?)> */ func() bool { - position725, tokenIndex725 := position, tokenIndex + position723, tokenIndex723 := position, tokenIndex { - position726 := position - if buffer[position] != rune(':') { - goto l725 - } - position++ - { - position727, tokenIndex727 := position, tokenIndex - if buffer[position] != rune('l') { - goto l728 - } - position++ - goto l727 - l728: - position, tokenIndex = position727, tokenIndex727 - if buffer[position] != rune('L') { - goto l725 - } - position++ - } - l727: - { - position729, tokenIndex729 := position, tokenIndex - if buffer[position] != rune('o') { - goto l730 - } - position++ - goto l729 - l730: - position, tokenIndex = position729, tokenIndex729 - if buffer[position] != rune('O') { - goto l725 - } - position++ - } - l729: - if buffer[position] != rune('1') { - goto l725 - } - position++ - if buffer[position] != rune('2') { - goto l725 - } - position++ - if buffer[position] != rune(':') { - goto l725 - } - position++ - { - position731, tokenIndex731 := position, tokenIndex - if !_rules[ruleLocalSymbol]() { - goto l732 - } - goto l731 - l732: - position, tokenIndex = position731, tokenIndex731 - if !_rules[ruleSymbolName]() { - goto l725 - } - } - l731: - { - position733, tokenIndex733 := position, tokenIndex - if !_rules[ruleOffset]() { - goto l733 - } - goto l734 - l733: - position, tokenIndex = position733, tokenIndex733 - } - l734: - add(ruleLow12BitsSymbolRef, position726) - } - return true - l725: - position, tokenIndex = position725, tokenIndex725 - return false - }, - /* 46 ARMBaseIndexScale <- <('[' ARMRegister (',' WS? (('#' Offset ('*' [0-9]+)?) / ARMGOTLow12 / Low12BitsSymbolRef / ARMRegister) (',' WS? ARMConstantTweak)?)? ']' ARMPostincrement?)> */ - func() bool { - position735, tokenIndex735 := position, tokenIndex - { - position736 := position + position724 := position if buffer[position] != rune('[') { - goto l735 + goto l723 } position++ if !_rules[ruleARMRegister]() { - goto l735 + goto l723 } { - position737, tokenIndex737 := position, tokenIndex + position725, tokenIndex725 := position, tokenIndex if buffer[position] != rune(',') { - goto l737 + goto l725 } position++ { - position739, tokenIndex739 := position, tokenIndex + position727, tokenIndex727 := position, tokenIndex if !_rules[ruleWS]() { - goto l739 + goto l727 } - goto l740 - l739: - position, tokenIndex = position739, tokenIndex739 + goto l728 + l727: + position, tokenIndex = position727, tokenIndex727 } - l740: + l728: { - position741, tokenIndex741 := position, tokenIndex + position729, tokenIndex729 := position, tokenIndex if buffer[position] != rune('#') { - goto l742 + goto l730 } position++ if !_rules[ruleOffset]() { - goto l742 + goto l730 } { - position743, tokenIndex743 := position, tokenIndex - if buffer[position] != rune('*') { - goto l743 - } - position++ - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l743 - } - position++ - l745: + position731, tokenIndex731 := position, tokenIndex { - position746, tokenIndex746 := position, tokenIndex - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l746 + position733, tokenIndex733 := position, tokenIndex + if buffer[position] != rune('*') { + goto l734 } position++ - goto l745 - l746: - position, tokenIndex = position746, tokenIndex746 + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l734 + } + position++ + l735: + { + position736, tokenIndex736 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l736 + } + position++ + goto l735 + l736: + position, tokenIndex = position736, tokenIndex736 + } + goto l733 + l734: + position, tokenIndex = position733, tokenIndex733 + if buffer[position] != rune('*') { + goto l737 + } + position++ + if buffer[position] != rune('(') { + goto l737 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l737 + } + position++ + l738: + { + position739, tokenIndex739 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l739 + } + position++ + goto l738 + l739: + position, tokenIndex = position739, tokenIndex739 + } + if !_rules[ruleOperator]() { + goto l737 + } + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l737 + } + position++ + l740: + { + position741, tokenIndex741 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l741 + } + position++ + goto l740 + l741: + position, tokenIndex = position741, tokenIndex741 + } + if buffer[position] != rune(')') { + goto l737 + } + position++ + goto l733 + l737: + position, tokenIndex = position733, tokenIndex733 + l742: + { + position743, tokenIndex743 := position, tokenIndex + if buffer[position] != rune('+') { + goto l743 + } + position++ + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l743 + } + position++ + l744: + { + position745, tokenIndex745 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l745 + } + position++ + goto l744 + l745: + position, tokenIndex = position745, tokenIndex745 + } + goto l742 + l743: + position, tokenIndex = position743, tokenIndex743 + } } - goto l744 - l743: - position, tokenIndex = position743, tokenIndex743 + l733: + goto l732 + + position, tokenIndex = position731, tokenIndex731 } - l744: - goto l741 - l742: - position, tokenIndex = position741, tokenIndex741 + l732: + goto l729 + l730: + position, tokenIndex = position729, tokenIndex729 if !_rules[ruleARMGOTLow12]() { + goto l746 + } + goto l729 + l746: + position, tokenIndex = position729, tokenIndex729 + if !_rules[ruleLow12BitsSymbolRef]() { goto l747 } - goto l741 + goto l729 l747: - position, tokenIndex = position741, tokenIndex741 - if !_rules[ruleLow12BitsSymbolRef]() { - goto l748 - } - goto l741 - l748: - position, tokenIndex = position741, tokenIndex741 + position, tokenIndex = position729, tokenIndex729 if !_rules[ruleARMRegister]() { - goto l737 + goto l725 } } - l741: + l729: { - position749, tokenIndex749 := position, tokenIndex + position748, tokenIndex748 := position, tokenIndex if buffer[position] != rune(',') { - goto l749 + goto l748 } position++ { - position751, tokenIndex751 := position, tokenIndex + position750, tokenIndex750 := position, tokenIndex if !_rules[ruleWS]() { - goto l751 + goto l750 } - goto l752 - l751: - position, tokenIndex = position751, tokenIndex751 + goto l751 + l750: + position, tokenIndex = position750, tokenIndex750 } - l752: + l751: if !_rules[ruleARMConstantTweak]() { - goto l749 + goto l748 } - goto l750 - l749: - position, tokenIndex = position749, tokenIndex749 + goto l749 + l748: + position, tokenIndex = position748, tokenIndex748 } - l750: - goto l738 - l737: - position, tokenIndex = position737, tokenIndex737 + l749: + goto l726 + l725: + position, tokenIndex = position725, tokenIndex725 } - l738: + l726: if buffer[position] != rune(']') { - goto l735 + goto l723 } position++ { - position753, tokenIndex753 := position, tokenIndex + position752, tokenIndex752 := position, tokenIndex if !_rules[ruleARMPostincrement]() { - goto l753 + goto l752 } - goto l754 - l753: - position, tokenIndex = position753, tokenIndex753 + goto l753 + l752: + position, tokenIndex = position752, tokenIndex752 } - l754: - add(ruleARMBaseIndexScale, position736) + l753: + add(ruleARMBaseIndexScale, position724) } return true - l735: - position, tokenIndex = position735, tokenIndex735 + l723: + position, tokenIndex = position723, tokenIndex723 return false }, /* 47 ARMGOTLow12 <- <(':' ('g' / 'G') ('o' / 'O') ('t' / 'T') '_' ('l' / 'L') ('o' / 'O') '1' '2' ':' SymbolName)> */ func() bool { - position755, tokenIndex755 := position, tokenIndex + position754, tokenIndex754 := position, tokenIndex { - position756 := position + position755 := position if buffer[position] != rune(':') { - goto l755 + goto l754 } position++ { - position757, tokenIndex757 := position, tokenIndex + position756, tokenIndex756 := position, tokenIndex if buffer[position] != rune('g') { - goto l758 + goto l757 } position++ - goto l757 - l758: - position, tokenIndex = position757, tokenIndex757 + goto l756 + l757: + position, tokenIndex = position756, tokenIndex756 if buffer[position] != rune('G') { - goto l755 + goto l754 } position++ } - l757: + l756: { - position759, tokenIndex759 := position, tokenIndex + position758, tokenIndex758 := position, tokenIndex if buffer[position] != rune('o') { - goto l760 + goto l759 } position++ - goto l759 - l760: - position, tokenIndex = position759, tokenIndex759 + goto l758 + l759: + position, tokenIndex = position758, tokenIndex758 if buffer[position] != rune('O') { - goto l755 + goto l754 } position++ } - l759: + l758: { - position761, tokenIndex761 := position, tokenIndex + position760, tokenIndex760 := position, tokenIndex if buffer[position] != rune('t') { - goto l762 + goto l761 } position++ - goto l761 - l762: - position, tokenIndex = position761, tokenIndex761 + goto l760 + l761: + position, tokenIndex = position760, tokenIndex760 if buffer[position] != rune('T') { - goto l755 + goto l754 } position++ } - l761: + l760: if buffer[position] != rune('_') { - goto l755 + goto l754 } position++ { - position763, tokenIndex763 := position, tokenIndex + position762, tokenIndex762 := position, tokenIndex if buffer[position] != rune('l') { - goto l764 + goto l763 } position++ - goto l763 - l764: - position, tokenIndex = position763, tokenIndex763 + goto l762 + l763: + position, tokenIndex = position762, tokenIndex762 if buffer[position] != rune('L') { - goto l755 + goto l754 } position++ } - l763: + l762: { - position765, tokenIndex765 := position, tokenIndex + position764, tokenIndex764 := position, tokenIndex if buffer[position] != rune('o') { - goto l766 + goto l765 } position++ - goto l765 - l766: - position, tokenIndex = position765, tokenIndex765 + goto l764 + l765: + position, tokenIndex = position764, tokenIndex764 if buffer[position] != rune('O') { - goto l755 + goto l754 } position++ } - l765: + l764: if buffer[position] != rune('1') { - goto l755 + goto l754 } position++ if buffer[position] != rune('2') { - goto l755 + goto l754 } position++ if buffer[position] != rune(':') { - goto l755 + goto l754 } position++ if !_rules[ruleSymbolName]() { - goto l755 + goto l754 } - add(ruleARMGOTLow12, position756) + add(ruleARMGOTLow12, position755) } return true - l755: - position, tokenIndex = position755, tokenIndex755 + l754: + position, tokenIndex = position754, tokenIndex754 return false }, /* 48 ARMPostincrement <- <'!'> */ func() bool { - position767, tokenIndex767 := position, tokenIndex + position766, tokenIndex766 := position, tokenIndex { - position768 := position + position767 := position if buffer[position] != rune('!') { - goto l767 + goto l766 } position++ - add(ruleARMPostincrement, position768) + add(ruleARMPostincrement, position767) } return true - l767: - position, tokenIndex = position767, tokenIndex767 + l766: + position, tokenIndex = position766, tokenIndex766 return false }, /* 49 BaseIndexScale <- <('(' RegisterOrConstant? WS? (',' WS? RegisterOrConstant WS? (',' [0-9]+)?)? ')')> */ func() bool { - position769, tokenIndex769 := position, tokenIndex + position768, tokenIndex768 := position, tokenIndex { - position770 := position + position769 := position if buffer[position] != rune('(') { - goto l769 + goto l768 } position++ { - position771, tokenIndex771 := position, tokenIndex + position770, tokenIndex770 := position, tokenIndex if !_rules[ruleRegisterOrConstant]() { - goto l771 + goto l770 } - goto l772 - l771: - position, tokenIndex = position771, tokenIndex771 + goto l771 + l770: + position, tokenIndex = position770, tokenIndex770 } - l772: + l771: { - position773, tokenIndex773 := position, tokenIndex + position772, tokenIndex772 := position, tokenIndex if !_rules[ruleWS]() { - goto l773 + goto l772 } - goto l774 - l773: - position, tokenIndex = position773, tokenIndex773 + goto l773 + l772: + position, tokenIndex = position772, tokenIndex772 } - l774: + l773: { - position775, tokenIndex775 := position, tokenIndex + position774, tokenIndex774 := position, tokenIndex if buffer[position] != rune(',') { - goto l775 + goto l774 } position++ { - position777, tokenIndex777 := position, tokenIndex + position776, tokenIndex776 := position, tokenIndex if !_rules[ruleWS]() { - goto l777 + goto l776 } - goto l778 - l777: - position, tokenIndex = position777, tokenIndex777 + goto l777 + l776: + position, tokenIndex = position776, tokenIndex776 } - l778: + l777: if !_rules[ruleRegisterOrConstant]() { - goto l775 + goto l774 } { - position779, tokenIndex779 := position, tokenIndex + position778, tokenIndex778 := position, tokenIndex if !_rules[ruleWS]() { - goto l779 + goto l778 } - goto l780 - l779: - position, tokenIndex = position779, tokenIndex779 + goto l779 + l778: + position, tokenIndex = position778, tokenIndex778 } - l780: + l779: { - position781, tokenIndex781 := position, tokenIndex + position780, tokenIndex780 := position, tokenIndex if buffer[position] != rune(',') { - goto l781 + goto l780 } position++ if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l781 + goto l780 } position++ - l783: + l782: { - position784, tokenIndex784 := position, tokenIndex + position783, tokenIndex783 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l784 + goto l783 } position++ - goto l783 - l784: - position, tokenIndex = position784, tokenIndex784 + goto l782 + l783: + position, tokenIndex = position783, tokenIndex783 } - goto l782 - l781: - position, tokenIndex = position781, tokenIndex781 + goto l781 + l780: + position, tokenIndex = position780, tokenIndex780 } - l782: - goto l776 - l775: - position, tokenIndex = position775, tokenIndex775 + l781: + goto l775 + l774: + position, tokenIndex = position774, tokenIndex774 } - l776: + l775: if buffer[position] != rune(')') { - goto l769 + goto l768 } position++ - add(ruleBaseIndexScale, position770) + add(ruleBaseIndexScale, position769) } return true - l769: - position, tokenIndex = position769, tokenIndex769 + l768: + position, tokenIndex = position768, tokenIndex768 return false }, /* 50 Operator <- <('+' / '-')> */ func() bool { - position785, tokenIndex785 := position, tokenIndex + position784, tokenIndex784 := position, tokenIndex { - position786 := position + position785 := position { - position787, tokenIndex787 := position, tokenIndex + position786, tokenIndex786 := position, tokenIndex if buffer[position] != rune('+') { - goto l788 + goto l787 } position++ - goto l787 - l788: - position, tokenIndex = position787, tokenIndex787 + goto l786 + l787: + position, tokenIndex = position786, tokenIndex786 if buffer[position] != rune('-') { - goto l785 + goto l784 } position++ } - l787: - add(ruleOperator, position786) + l786: + add(ruleOperator, position785) } return true - l785: - position, tokenIndex = position785, tokenIndex785 + l784: + position, tokenIndex = position784, tokenIndex784 return false }, /* 51 Offset <- <('+'? '-'? (('0' ('b' / 'B') ('0' / '1')+) / ('0' ('x' / 'X') ([0-9] / [0-9] / ([a-f] / [A-F]))+) / [0-9]+))> */ func() bool { - position789, tokenIndex789 := position, tokenIndex + position788, tokenIndex788 := position, tokenIndex { - position790 := position + position789 := position { - position791, tokenIndex791 := position, tokenIndex + position790, tokenIndex790 := position, tokenIndex if buffer[position] != rune('+') { - goto l791 + goto l790 } position++ - goto l792 - l791: - position, tokenIndex = position791, tokenIndex791 + goto l791 + l790: + position, tokenIndex = position790, tokenIndex790 } - l792: + l791: { - position793, tokenIndex793 := position, tokenIndex + position792, tokenIndex792 := position, tokenIndex if buffer[position] != rune('-') { - goto l793 + goto l792 } position++ - goto l794 - l793: - position, tokenIndex = position793, tokenIndex793 + goto l793 + l792: + position, tokenIndex = position792, tokenIndex792 } - l794: + l793: { - position795, tokenIndex795 := position, tokenIndex + position794, tokenIndex794 := position, tokenIndex if buffer[position] != rune('0') { - goto l796 + goto l795 } position++ { - position797, tokenIndex797 := position, tokenIndex + position796, tokenIndex796 := position, tokenIndex if buffer[position] != rune('b') { - goto l798 + goto l797 } position++ - goto l797 - l798: - position, tokenIndex = position797, tokenIndex797 + goto l796 + l797: + position, tokenIndex = position796, tokenIndex796 if buffer[position] != rune('B') { - goto l796 + goto l795 } position++ } - l797: - { - position801, tokenIndex801 := position, tokenIndex - if buffer[position] != rune('0') { - goto l802 - } - position++ - goto l801 - l802: - position, tokenIndex = position801, tokenIndex801 - if buffer[position] != rune('1') { - goto l796 - } - position++ - } - l801: - l799: + l796: { position800, tokenIndex800 := position, tokenIndex + if buffer[position] != rune('0') { + goto l801 + } + position++ + goto l800 + l801: + position, tokenIndex = position800, tokenIndex800 + if buffer[position] != rune('1') { + goto l795 + } + position++ + } + l800: + l798: + { + position799, tokenIndex799 := position, tokenIndex { - position803, tokenIndex803 := position, tokenIndex + position802, tokenIndex802 := position, tokenIndex if buffer[position] != rune('0') { - goto l804 + goto l803 } position++ - goto l803 - l804: - position, tokenIndex = position803, tokenIndex803 + goto l802 + l803: + position, tokenIndex = position802, tokenIndex802 if buffer[position] != rune('1') { - goto l800 + goto l799 } position++ } - l803: - goto l799 - l800: - position, tokenIndex = position800, tokenIndex800 + l802: + goto l798 + l799: + position, tokenIndex = position799, tokenIndex799 } - goto l795 - l796: - position, tokenIndex = position795, tokenIndex795 + goto l794 + l795: + position, tokenIndex = position794, tokenIndex794 if buffer[position] != rune('0') { - goto l805 + goto l804 } position++ { - position806, tokenIndex806 := position, tokenIndex + position805, tokenIndex805 := position, tokenIndex if buffer[position] != rune('x') { - goto l807 + goto l806 } position++ - goto l806 - l807: - position, tokenIndex = position806, tokenIndex806 + goto l805 + l806: + position, tokenIndex = position805, tokenIndex805 if buffer[position] != rune('X') { - goto l805 + goto l804 } position++ } - l806: + l805: { - position810, tokenIndex810 := position, tokenIndex + position809, tokenIndex809 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l810 + } + position++ + goto l809 + l810: + position, tokenIndex = position809, tokenIndex809 if c := buffer[position]; c < rune('0') || c > rune('9') { goto l811 } position++ - goto l810 + goto l809 l811: - position, tokenIndex = position810, tokenIndex810 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l812 - } - position++ - goto l810 - l812: - position, tokenIndex = position810, tokenIndex810 + position, tokenIndex = position809, tokenIndex809 { - position813, tokenIndex813 := position, tokenIndex + position812, tokenIndex812 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l814 + goto l813 } position++ - goto l813 - l814: - position, tokenIndex = position813, tokenIndex813 + goto l812 + l813: + position, tokenIndex = position812, tokenIndex812 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l805 + goto l804 } position++ } - l813: + l812: } - l810: - l808: + l809: + l807: { - position809, tokenIndex809 := position, tokenIndex + position808, tokenIndex808 := position, tokenIndex { - position815, tokenIndex815 := position, tokenIndex + position814, tokenIndex814 := position, tokenIndex + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l815 + } + position++ + goto l814 + l815: + position, tokenIndex = position814, tokenIndex814 if c := buffer[position]; c < rune('0') || c > rune('9') { goto l816 } position++ - goto l815 + goto l814 l816: - position, tokenIndex = position815, tokenIndex815 - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l817 - } - position++ - goto l815 - l817: - position, tokenIndex = position815, tokenIndex815 + position, tokenIndex = position814, tokenIndex814 { - position818, tokenIndex818 := position, tokenIndex + position817, tokenIndex817 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l819 + goto l818 } position++ - goto l818 - l819: - position, tokenIndex = position818, tokenIndex818 + goto l817 + l818: + position, tokenIndex = position817, tokenIndex817 if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l809 + goto l808 } position++ } - l818: + l817: } - l815: - goto l808 - l809: - position, tokenIndex = position809, tokenIndex809 + l814: + goto l807 + l808: + position, tokenIndex = position808, tokenIndex808 } - goto l795 - l805: - position, tokenIndex = position795, tokenIndex795 + goto l794 + l804: + position, tokenIndex = position794, tokenIndex794 if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l789 + goto l788 } position++ - l820: + l819: { - position821, tokenIndex821 := position, tokenIndex + position820, tokenIndex820 := position, tokenIndex if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l821 + goto l820 } position++ - goto l820 - l821: - position, tokenIndex = position821, tokenIndex821 + goto l819 + l820: + position, tokenIndex = position820, tokenIndex820 } } - l795: - add(ruleOffset, position790) + l794: + add(ruleOffset, position789) } return true - l789: - position, tokenIndex = position789, tokenIndex789 + l788: + position, tokenIndex = position788, tokenIndex788 return false }, /* 52 Section <- <([a-z] / [A-Z] / '@')+> */ func() bool { - position822, tokenIndex822 := position, tokenIndex + position821, tokenIndex821 := position, tokenIndex { - position823 := position + position822 := position { - position826, tokenIndex826 := position, tokenIndex + position825, tokenIndex825 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l826 + } + position++ + goto l825 + l826: + position, tokenIndex = position825, tokenIndex825 + if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l827 } position++ - goto l826 + goto l825 l827: - position, tokenIndex = position826, tokenIndex826 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l828 - } - position++ - goto l826 - l828: - position, tokenIndex = position826, tokenIndex826 + position, tokenIndex = position825, tokenIndex825 if buffer[position] != rune('@') { - goto l822 + goto l821 } position++ } - l826: - l824: + l825: + l823: { - position825, tokenIndex825 := position, tokenIndex + position824, tokenIndex824 := position, tokenIndex { - position829, tokenIndex829 := position, tokenIndex + position828, tokenIndex828 := position, tokenIndex if c := buffer[position]; c < rune('a') || c > rune('z') { + goto l829 + } + position++ + goto l828 + l829: + position, tokenIndex = position828, tokenIndex828 + if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l830 } position++ - goto l829 + goto l828 l830: - position, tokenIndex = position829, tokenIndex829 - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l831 - } - position++ - goto l829 - l831: - position, tokenIndex = position829, tokenIndex829 + position, tokenIndex = position828, tokenIndex828 if buffer[position] != rune('@') { - goto l825 + goto l824 } position++ } - l829: - goto l824 - l825: - position, tokenIndex = position825, tokenIndex825 + l828: + goto l823 + l824: + position, tokenIndex = position824, tokenIndex824 } - add(ruleSection, position823) + add(ruleSection, position822) } return true - l822: - position, tokenIndex = position822, tokenIndex822 + l821: + position, tokenIndex = position821, tokenIndex821 return false }, /* 53 SegmentRegister <- <('%' ([c-g] / 's') ('s' ':'))> */ func() bool { - position832, tokenIndex832 := position, tokenIndex + position831, tokenIndex831 := position, tokenIndex { - position833 := position + position832 := position if buffer[position] != rune('%') { - goto l832 + goto l831 } position++ { - position834, tokenIndex834 := position, tokenIndex + position833, tokenIndex833 := position, tokenIndex if c := buffer[position]; c < rune('c') || c > rune('g') { - goto l835 + goto l834 } position++ - goto l834 - l835: - position, tokenIndex = position834, tokenIndex834 + goto l833 + l834: + position, tokenIndex = position833, tokenIndex833 if buffer[position] != rune('s') { - goto l832 + goto l831 } position++ } - l834: + l833: if buffer[position] != rune('s') { - goto l832 + goto l831 } position++ if buffer[position] != rune(':') { - goto l832 + goto l831 } position++ - add(ruleSegmentRegister, position833) + add(ruleSegmentRegister, position832) } return true - l832: - position, tokenIndex = position832, tokenIndex832 + l831: + position, tokenIndex = position831, tokenIndex831 return false }, } p.rules = _rules + return nil } diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate_test.go b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate_test.go index 43b3ff1c..e341a381 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/delocate_test.go +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/delocate_test.go @@ -10,14 +10,14 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package main import ( "bytes" "flag" - "io/ioutil" + "os" "path/filepath" "testing" ) @@ -39,11 +39,6 @@ func (test *delocateTest) Path(file string) string { var delocateTests = []delocateTest{ {"generic-FileDirectives", []string{"in.s"}, "out.s"}, - {"ppc64le-GlobalEntry", []string{"in.s"}, "out.s"}, - {"ppc64le-LoadToR0", []string{"in.s"}, "out.s"}, - {"ppc64le-Sample2", []string{"in.s"}, "out.s"}, - {"ppc64le-Sample", []string{"in.s"}, "out.s"}, - {"ppc64le-TOCWithOffset", []string{"in.s"}, "out.s"}, {"x86_64-Basic", []string{"in.s"}, "out.s"}, {"x86_64-BSS", []string{"in.s"}, "out.s"}, {"x86_64-GOTRewrite", []string{"in.s"}, "out.s"}, @@ -65,7 +60,7 @@ func TestDelocate(t *testing.T) { }) } - if err := parseInputs(inputs); err != nil { + if err := parseInputs(inputs, nil); err != nil { t.Fatalf("parseInputs failed: %s", err) } @@ -75,9 +70,9 @@ func TestDelocate(t *testing.T) { } if *update { - ioutil.WriteFile(test.Path(test.out), buf.Bytes(), 0666) + os.WriteFile(test.Path(test.out), buf.Bytes(), 0666) } else { - expected, err := ioutil.ReadFile(test.Path(test.out)) + expected, err := os.ReadFile(test.Path(test.out)) if err != nil { t.Fatalf("could not read %q: %s", test.Path(test.out), err) } diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/in.s index 3b80125a..8b45e25f 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/in.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/in.s @@ -43,9 +43,41 @@ foo: bl bss_symbol_bss_get - # Regression test for a two-digit index. + // Regression test for a two-digit index. ld1 { v1.b }[10], [x9] + // Ensure that registers aren't interpreted as symbols. + add x0, x0 + add x12, x12 + add w0, x0 + add w12, x12 + add d0, d0 + add d12, d12 + add q0, q0 + add q12, q12 + add s0, s0 + add s12, s12 + add h0, h0 + add h12, h12 + add b0, b0 + add b12, b12 + + // But 'y' is not a register prefix so far, so these should be + // processed as symbols. + add y0, y0 + add y12, y12 + + // Make sure that the magic extension constants are recognised rather + // than being interpreted as symbols. + add w0, w1, b2, uxtb + add w0, w1, b2, uxth + add w0, w1, b2, uxtw + add w0, w1, b2, uxtx + add w0, w1, b2, sxtb + add w0, w1, b2, sxth + add w0, w1, b2, sxtw + add w0, w1, b2, sxtx + local_function: diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/out.s index 12b408dc..0b9828f8 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/aarch64-Basic/out.s @@ -88,9 +88,43 @@ foo: bl bss_symbol_bss_get - # Regression test for a two-digit index. + // Regression test for a two-digit index. ld1 { v1.b }[10], [x9] + // Ensure that registers aren't interpreted as symbols. + add x0, x0 + add x12, x12 + add w0, x0 + add w12, x12 + add d0, d0 + add d12, d12 + add q0, q0 + add q12, q12 + add s0, s0 + add s12, s12 + add h0, h0 + add h12, h12 + add b0, b0 + add b12, b12 + + // But 'y' is not a register prefix so far, so these should be + // processed as symbols. +// WAS add y0, y0 + add bcm_redirector_y0, bcm_redirector_y0 +// WAS add y12, y12 + add bcm_redirector_y12, bcm_redirector_y12 + + // Make sure that the magic extension constants are recognised rather + // than being interpreted as symbols. + add w0, w1, b2, uxtb + add w0, w1, b2, uxth + add w0, w1, b2, uxtw + add w0, w1, b2, uxtx + add w0, w1, b2, sxtb + add w0, w1, b2, sxth + add w0, w1, b2, sxtw + add w0, w1, b2, sxtx + .Llocal_function_local_target: local_function: @@ -115,6 +149,22 @@ bcm_redirector_remote_function: .cfi_endproc .size bcm_redirector_remote_function, .-bcm_redirector_remote_function .p2align 2 +.hidden bcm_redirector_y0 +.type bcm_redirector_y0, @function +bcm_redirector_y0: +.cfi_startproc + b y0 +.cfi_endproc +.size bcm_redirector_y0, .-bcm_redirector_y0 +.p2align 2 +.hidden bcm_redirector_y12 +.type bcm_redirector_y12, @function +bcm_redirector_y12: +.cfi_startproc + b y12 +.cfi_endproc +.size bcm_redirector_y12, .-bcm_redirector_y12 +.p2align 2 .hidden bss_symbol_bss_get .type bss_symbol_bss_get, @function bss_symbol_bss_get: @@ -145,7 +195,7 @@ bss_symbol_bss_get: .cfi_endproc .size .LOPENSSL_armcap_P_addr, .-.LOPENSSL_armcap_P_addr .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -179,35 +229,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/generic-FileDirectives/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/generic-FileDirectives/out.s index bb33e523..84b5134f 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/generic-FileDirectives/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/generic-FileDirectives/out.s @@ -23,7 +23,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -57,35 +57,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/in.s deleted file mode 100644 index af1a182c..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/in.s +++ /dev/null @@ -1,9 +0,0 @@ - .text -foo: -.LCF0: -0: - addis 2,12,.TOC.-.LCF0@ha - addi 2,2,.TOC.-.LCF0@l - .localentry foo,.-foo -.LVL0: - bl diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/out.s deleted file mode 100644 index 304f697a..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-GlobalEntry/out.s +++ /dev/null @@ -1,94 +0,0 @@ -.text -.file 1 "inserted_by_delocate.c" -.loc 1 1 0 -BORINGSSL_bcm_text_start: - .text -.Lfoo_local_target: -foo: -.LCF0: - -0: - -999: - addis 2, 12, .LBORINGSSL_external_toc-999b@ha - addi 2, 2, .LBORINGSSL_external_toc-999b@l - ld 12, 0(2) - add 2, 2, 12 -# WAS addi 2,2,.TOC.-.LCF0@l - .localentry foo,.-foo -.Lfoo_local_entry: -.LVL0: - - bl -.text -.loc 1 2 0 -BORINGSSL_bcm_text_end: -.LBORINGSSL_external_toc: -.quad .TOC.-.LBORINGSSL_external_toc -.type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 -BORINGSSL_bcm_text_hash: -.byte 0xae -.byte 0x2c -.byte 0xea -.byte 0x2a -.byte 0xbd -.byte 0xa6 -.byte 0xf3 -.byte 0xec -.byte 0x97 -.byte 0x7f -.byte 0x9b -.byte 0xf6 -.byte 0x94 -.byte 0x9a -.byte 0xfc -.byte 0x83 -.byte 0x68 -.byte 0x27 -.byte 0xcb -.byte 0xa0 -.byte 0xa0 -.byte 0x9f -.byte 0x6b -.byte 0x6f -.byte 0xde -.byte 0x52 -.byte 0xcd -.byte 0xe2 -.byte 0xcd -.byte 0xff -.byte 0x31 -.byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/in.s deleted file mode 100644 index 81766dc0..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/in.s +++ /dev/null @@ -1,4 +0,0 @@ - .text -foo: - addis 22,2,bar@toc@ha - ld 0,bar@toc@l(22) diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/out.s deleted file mode 100644 index 5fdbeb89..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-LoadToR0/out.s +++ /dev/null @@ -1,104 +0,0 @@ -.text -.file 1 "inserted_by_delocate.c" -.loc 1 1 0 -BORINGSSL_bcm_text_start: - .text -.Lfoo_local_target: -foo: -# WAS addis 22,2,bar@toc@ha -# WAS ld 0,bar@toc@l(22) - addi 1, 1, -288 - mflr 0 - std 0, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc_bar - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 0, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - addi 1, 1, -288 - std 3, -8(1) - mr 3, 0 - ld 0, 0(3) - ld 3, -8(1) - addi 1, 1, 288 -.text -.loc 1 2 0 -BORINGSSL_bcm_text_end: -.type bcm_loadtoc_bar, @function -bcm_loadtoc_bar: -.Lbcm_loadtoc_bar: - addis 3, 2, bar@toc@ha - addi 3, 3, bar@toc@l - blr -.LBORINGSSL_external_toc: -.quad .TOC.-.LBORINGSSL_external_toc -.type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 -BORINGSSL_bcm_text_hash: -.byte 0xae -.byte 0x2c -.byte 0xea -.byte 0x2a -.byte 0xbd -.byte 0xa6 -.byte 0xf3 -.byte 0xec -.byte 0x97 -.byte 0x7f -.byte 0x9b -.byte 0xf6 -.byte 0x94 -.byte 0x9a -.byte 0xfc -.byte 0x83 -.byte 0x68 -.byte 0x27 -.byte 0xcb -.byte 0xa0 -.byte 0xa0 -.byte 0x9f -.byte 0x6b -.byte 0x6f -.byte 0xde -.byte 0x52 -.byte 0xcd -.byte 0xe2 -.byte 0xcd -.byte 0xff -.byte 0x31 -.byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/in.s deleted file mode 100644 index 6e7422ab..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/in.s +++ /dev/null @@ -1,161 +0,0 @@ - .file "foo.c" - .abiversion 2 - .section ".toc","aw" - .section ".text" - .section .rodata - .align 3 - .type kString, @object - .size kString, 12 -kString: - .string "hello world" - .globl kExportedString - .align 3 - .type kExportedString, @object - .size kExportedString, 26 -kExportedString: - .string "hello world, more visibly" - .align 2 - .type kGiantArray, @object - .size kGiantArray, 400000 -kGiantArray: - .long 1 - .long 0 - .zero 399992 - .lcomm bss,20,4 - .type bss, @object - .align 3 -.LC1: - .string "kString is %p\n" - .align 3 -.LC2: - .string "kExportedString is %p\n" - .align 3 -.LC4: - .string "function is %p\n" - .align 3 -.LC5: - .string "exported_function is %p\n" - .align 3 -.LC7: - .string "&kString[5] is %p\n" - .align 3 -.LC9: - .string "&kGiantArray[0x12345] is %p\n" - .section ".toc","aw" -.LC0: - .quad stderr -.LC3: - .quad kExportedString -.LC6: - .quad exported_function -.LC8: - .quad kString+5 -.LC10: - .quad kGiantArray+298260 - .section ".text" - .align 2 - .type function, @function -function: -0: addis 2,12,.TOC.-0b@ha - addi 2,2,.TOC.-0b@l - .localentry function,.-function - mflr 0 - std 0,16(1) - std 31,-8(1) - stdu 1,-112(1) - mr 31,1 - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC1@toc@ha - addi 4,4,.LC1@toc@l - addis 5,2,kString@toc@ha - addi 5,5,kString@toc@l - bl fprintf - nop - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC2@toc@ha - addi 4,4,.LC2@toc@l - addis 9,2,.LC3@toc@ha - ld 5,.LC3@toc@l(9) - bl fprintf - nop - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC4@toc@ha - addi 4,4,.LC4@toc@l - addis 5,2,function@toc@ha - addi 5,5,function@toc@l - bl fprintf - nop - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC5@toc@ha - addi 4,4,.LC5@toc@l - addis 9,2,.LC6@toc@ha - ld 5,.LC6@toc@l(9) - bl fprintf - nop - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC7@toc@ha - addi 4,4,.LC7@toc@l - addis 9,2,.LC8@toc@ha - ld 5,.LC8@toc@l(9) - bl fprintf - nop - addis 10,2,.LC0@toc@ha - ld 9,.LC0@toc@l(10) - ld 9,0(9) - mr 3,9 - addis 4,2,.LC9@toc@ha - addi 4,4,.LC9@toc@l - addis 9,2,.LC10@toc@ha - ld 5,.LC10@toc@l(9) - bl fprintf - nop - bl exported_function - nop - mr 3,9 - addi 1,31,112 - ld 0,16(1) - mtlr 0 - ld 31,-8(1) - blr - .long 0 - .byte 0,0,0,1,128,1,0,1 - .size function,.-function - .align 2 - .globl exported_function - .type exported_function, @function -exported_function: -0: addis 2,12,.TOC.-0b@ha - addi 2,2,.TOC.-0b@l - .localentry exported_function,.-exported_function - mflr 0 - std 0,16(1) - std 31,-8(1) - stdu 1,-48(1) - mr 31,1 - bl function - mr 3,9 - addi 1,31,48 - ld 0,16(1) - mtlr 0 - ld 31,-8(1) - blr - .long 0 - .byte 0,0,0,1,128,1,0,1 - .size exported_function,.-exported_function - .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" - .section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/out.s deleted file mode 100644 index e3d682e5..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample/out.s +++ /dev/null @@ -1,584 +0,0 @@ -.text -.file 1 "inserted_by_delocate.c" -.loc 1 1 0 -BORINGSSL_bcm_text_start: - .file "foo.c" - .abiversion 2 - .section ".toc","aw" -# WAS .section ".text" -.text -# WAS .section .rodata -.text - .align 3 - .type kString, @object - .size kString, 12 -.LkString_local_target: -kString: - .string "hello world" - .globl kExportedString - .align 3 - .type kExportedString, @object - .size kExportedString, 26 -.LkExportedString_local_target: -kExportedString: - .string "hello world, more visibly" - .align 2 - .type kGiantArray, @object - .size kGiantArray, 400000 -.LkGiantArray_local_target: -kGiantArray: - .long 1 - .long 0 - .zero 399992 - .lcomm bss,20,4 - .type bss, @object - .align 3 -.LC1: - - .string "kString is %p\n" - .align 3 -.LC2: - - .string "kExportedString is %p\n" - .align 3 -.LC4: - - .string "function is %p\n" - .align 3 -.LC5: - - .string "exported_function is %p\n" - .align 3 -.LC7: - - .string "&kString[5] is %p\n" - .align 3 -.LC9: - - .string "&kGiantArray[0x12345] is %p\n" - .section ".toc","aw" -.LC0: - - .quad stderr -.LC3: - - .quad kExportedString -.LC6: - - .quad exported_function -.LC8: - - .quad kString+5 -.LC10: - - .quad kGiantArray+298260 -# WAS .section ".text" -.text - .align 2 - .type function, @function -.Lfunction_local_target: -function: -0: -999: - addis 2, 12, .LBORINGSSL_external_toc-999b@ha - addi 2, 2, .LBORINGSSL_external_toc-999b@l - ld 12, 0(2) - add 2, 2, 12 -# WAS addi 2,2,.TOC.-0b@l - .localentry function,.-function -.Lfunction_local_entry: - mflr 0 - std 0,16(1) - std 31,-8(1) - stdu 1,-112(1) - mr 31,1 -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC1@toc@ha -# WAS addi 4,4,.LC1@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC1 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 5,2,kString@toc@ha -# WAS addi 5,5,kString@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LkString_local_target - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC2@toc@ha -# WAS addi 4,4,.LC2@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC2 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 9,2,.LC3@toc@ha -# WAS ld 5,.LC3@toc@l(9) - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC3 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 5, 0(5) -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC4@toc@ha -# WAS addi 4,4,.LC4@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC4 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 5,2,function@toc@ha -# WAS addi 5,5,function@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfunction_local_target - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC5@toc@ha -# WAS addi 4,4,.LC5@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC5 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 9,2,.LC6@toc@ha -# WAS ld 5,.LC6@toc@l(9) - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC6 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 5, 0(5) -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC7@toc@ha -# WAS addi 4,4,.LC7@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC7 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 9,2,.LC8@toc@ha -# WAS ld 5,.LC8@toc@l(9) - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC8 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 5, 0(5) -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS addis 10,2,.LC0@toc@ha -# WAS ld 9,.LC0@toc@l(10) - addi 1, 1, -288 - mflr 9 - std 9, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 9, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 9, 0(9) - ld 9,0(9) - mr 3,9 -# WAS addis 4,2,.LC9@toc@ha -# WAS addi 4,4,.LC9@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC9 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 9,2,.LC10@toc@ha -# WAS ld 5,.LC10@toc@l(9) - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC10 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 5, 0(5) -# WAS bl fprintf - bl bcm_redirector_fprintf - ld 2, 24(1) - nop -# WAS bl exported_function - bl .Lexported_function_local_entry - nop - mr 3,9 - addi 1,31,112 - ld 0,16(1) - mtlr 0 - ld 31,-8(1) - blr - .long 0 - .byte 0,0,0,1,128,1,0,1 - .size function,.-function - .align 2 - .globl exported_function - .type exported_function, @function -.Lexported_function_local_target: -exported_function: -0: -999: - addis 2, 12, .LBORINGSSL_external_toc-999b@ha - addi 2, 2, .LBORINGSSL_external_toc-999b@l - ld 12, 0(2) - add 2, 2, 12 -# WAS addi 2,2,.TOC.-0b@l - .localentry exported_function,.-exported_function -.Lexported_function_local_entry: - mflr 0 - std 0,16(1) - std 31,-8(1) - stdu 1,-48(1) - mr 31,1 -# WAS bl function - bl .Lfunction_local_entry - mr 3,9 - addi 1,31,48 - ld 0,16(1) - mtlr 0 - ld 31,-8(1) - blr - .long 0 - .byte 0,0,0,1,128,1,0,1 - .size exported_function,.-exported_function - .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" - .section .note.GNU-stack,"",@progbits -.text -.loc 1 2 0 -BORINGSSL_bcm_text_end: -.section ".toc", "aw" -.Lredirector_toc_fprintf: -.quad fprintf -.text -.type bcm_redirector_fprintf, @function -bcm_redirector_fprintf: - std 2, 24(1) - addis 12, 2, .Lredirector_toc_fprintf@toc@ha - ld 12, .Lredirector_toc_fprintf@toc@l(12) - mtctr 12 - bctr -.type bss_bss_get, @function -bss_bss_get: - addis 3, 2, bss@toc@ha - addi 3, 3, bss@toc@l - blr -.type bcm_loadtoc__dot_LC0, @function -bcm_loadtoc__dot_LC0: -.Lbcm_loadtoc__dot_LC0: - addis 3, 2, .LC0@toc@ha - addi 3, 3, .LC0@toc@l - blr -.type bcm_loadtoc__dot_LC1, @function -bcm_loadtoc__dot_LC1: -.Lbcm_loadtoc__dot_LC1: - addis 3, 2, .LC1@toc@ha - addi 3, 3, .LC1@toc@l - blr -.type bcm_loadtoc__dot_LC10, @function -bcm_loadtoc__dot_LC10: -.Lbcm_loadtoc__dot_LC10: - addis 3, 2, .LC10@toc@ha - addi 3, 3, .LC10@toc@l - blr -.type bcm_loadtoc__dot_LC2, @function -bcm_loadtoc__dot_LC2: -.Lbcm_loadtoc__dot_LC2: - addis 3, 2, .LC2@toc@ha - addi 3, 3, .LC2@toc@l - blr -.type bcm_loadtoc__dot_LC3, @function -bcm_loadtoc__dot_LC3: -.Lbcm_loadtoc__dot_LC3: - addis 3, 2, .LC3@toc@ha - addi 3, 3, .LC3@toc@l - blr -.type bcm_loadtoc__dot_LC4, @function -bcm_loadtoc__dot_LC4: -.Lbcm_loadtoc__dot_LC4: - addis 3, 2, .LC4@toc@ha - addi 3, 3, .LC4@toc@l - blr -.type bcm_loadtoc__dot_LC5, @function -bcm_loadtoc__dot_LC5: -.Lbcm_loadtoc__dot_LC5: - addis 3, 2, .LC5@toc@ha - addi 3, 3, .LC5@toc@l - blr -.type bcm_loadtoc__dot_LC6, @function -bcm_loadtoc__dot_LC6: -.Lbcm_loadtoc__dot_LC6: - addis 3, 2, .LC6@toc@ha - addi 3, 3, .LC6@toc@l - blr -.type bcm_loadtoc__dot_LC7, @function -bcm_loadtoc__dot_LC7: -.Lbcm_loadtoc__dot_LC7: - addis 3, 2, .LC7@toc@ha - addi 3, 3, .LC7@toc@l - blr -.type bcm_loadtoc__dot_LC8, @function -bcm_loadtoc__dot_LC8: -.Lbcm_loadtoc__dot_LC8: - addis 3, 2, .LC8@toc@ha - addi 3, 3, .LC8@toc@l - blr -.type bcm_loadtoc__dot_LC9, @function -bcm_loadtoc__dot_LC9: -.Lbcm_loadtoc__dot_LC9: - addis 3, 2, .LC9@toc@ha - addi 3, 3, .LC9@toc@l - blr -.type bcm_loadtoc__dot_Lfunction_local_target, @function -bcm_loadtoc__dot_Lfunction_local_target: -.Lbcm_loadtoc__dot_Lfunction_local_target: - addis 3, 2, .Lfunction_local_target@toc@ha - addi 3, 3, .Lfunction_local_target@toc@l - blr -.type bcm_loadtoc__dot_LkString_local_target, @function -bcm_loadtoc__dot_LkString_local_target: -.Lbcm_loadtoc__dot_LkString_local_target: - addis 3, 2, .LkString_local_target@toc@ha - addi 3, 3, .LkString_local_target@toc@l - blr -.LBORINGSSL_external_toc: -.quad .TOC.-.LBORINGSSL_external_toc -.type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 -BORINGSSL_bcm_text_hash: -.byte 0xae -.byte 0x2c -.byte 0xea -.byte 0x2a -.byte 0xbd -.byte 0xa6 -.byte 0xf3 -.byte 0xec -.byte 0x97 -.byte 0x7f -.byte 0x9b -.byte 0xf6 -.byte 0x94 -.byte 0x9a -.byte 0xfc -.byte 0x83 -.byte 0x68 -.byte 0x27 -.byte 0xcb -.byte 0xa0 -.byte 0xa0 -.byte 0x9f -.byte 0x6b -.byte 0x6f -.byte 0xde -.byte 0x52 -.byte 0xcd -.byte 0xe2 -.byte 0xcd -.byte 0xff -.byte 0x31 -.byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/in.s deleted file mode 100644 index eb856269..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/in.s +++ /dev/null @@ -1,226 +0,0 @@ - .file "foo.c" - .abiversion 2 - .section ".toc","aw" - .section ".text" - .section ".toc","aw" -.LC0: - .quad stderr -.LC3: - .quad kExportedString -.LC6: - .quad exported_function - .section ".text" - .align 2 - .p2align 4,,15 - .globl exported_function - .type exported_function, @function -exported_function: -0: addis 2,12,.TOC.-0b@ha - addi 2,2,.TOC.-0b@l - .localentry exported_function,.-exported_function - mflr 0 - std 19,-104(1) - std 20,-96(1) - std 21,-88(1) - std 22,-80(1) - addis 21,2,.LC1@toc@ha - addis 22,2,.LC2@toc@ha - std 23,-72(1) - std 24,-64(1) - addis 23,2,.LC4@toc@ha - addis 24,2,function@toc@ha - std 25,-56(1) - std 26,-48(1) - addis 25,2,.LC5@toc@ha - addis 26,2,.LC7@toc@ha - std 27,-40(1) - std 28,-32(1) - addis 28,2,.LC8@toc@ha - addi 21,21,.LC1@toc@l - std 29,-24(1) - std 30,-16(1) - addis 29,2,.LANCHOR0@toc@ha - addi 22,22,.LC2@toc@l - std 31,-8(1) - std 0,16(1) - addi 29,29,.LANCHOR0@toc@l - addi 23,23,.LC4@toc@l - stdu 1,-208(1) - addis 31,2,.LC0@toc@ha # gpr load fusion, type long - ld 31,.LC0@toc@l(31) - addis 19,2,.LC3@toc@ha # gpr load fusion, type long - ld 19,.LC3@toc@l(19) - addis 30,29,0x5 - addi 24,24,function@toc@l - addis 20,2,.LC6@toc@ha # gpr load fusion, type long - ld 20,.LC6@toc@l(20) - addi 25,25,.LC5@toc@l - addi 26,26,.LC7@toc@l - addi 27,29,5 - addi 28,28,.LC8@toc@l - addi 30,30,-29404 - .p2align 4,,15 -.L2: - ld 3,0(31) - mr 5,21 - mr 6,29 - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - mr 5,22 - mr 6,19 - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - mr 5,23 - mr 6,24 - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - mr 5,25 - mr 6,20 - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - mr 5,26 - mr 6,27 - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - li 4,1 - mr 5,28 - mr 6,30 - bl __fprintf_chk - nop - b .L2 - .long 0 - .byte 0,0,0,1,128,13,0,0 - .size exported_function,.-exported_function - .section ".toc","aw" - .set .LC11,.LC0 - .set .LC12,.LC3 - .set .LC13,.LC6 - .section ".text" - .align 2 - .p2align 4,,15 - .type function, @function -function: -0: addis 2,12,.TOC.-0b@ha - addi 2,2,.TOC.-0b@l - .localentry function,.-function - mflr 0 - std 31,-8(1) - addis 31,2,.LC11@toc@ha # gpr load fusion, type long - ld 31,.LC11@toc@l(31) - addis 5,2,.LC1@toc@ha - std 30,-16(1) - addis 30,2,.LANCHOR0@toc@ha - addi 5,5,.LC1@toc@l - addi 30,30,.LANCHOR0@toc@l - li 4,1 - mr 6,30 - std 0,16(1) - stdu 1,-112(1) - ld 3,0(31) - bl __fprintf_chk - nop - addis 6,2,.LC12@toc@ha # gpr load fusion, type long - ld 6,.LC12@toc@l(6) - ld 3,0(31) - addis 5,2,.LC2@toc@ha - li 4,1 - addi 5,5,.LC2@toc@l - bl __fprintf_chk - nop - ld 3,0(31) - addis 5,2,.LC4@toc@ha - addis 6,2,function@toc@ha - addi 5,5,.LC4@toc@l - addi 6,6,function@toc@l - li 4,1 - bl __fprintf_chk - nop - addis 6,2,.LC13@toc@ha # gpr load fusion, type long - ld 6,.LC13@toc@l(6) - ld 3,0(31) - addis 5,2,.LC5@toc@ha - li 4,1 - addi 5,5,.LC5@toc@l - bl __fprintf_chk - nop - ld 3,0(31) - addis 5,2,.LC7@toc@ha - addi 6,30,5 - addi 5,5,.LC7@toc@l - li 4,1 - bl __fprintf_chk - nop - ld 3,0(31) - addis 6,30,0x5 - addis 5,2,.LC8@toc@ha - li 4,1 - addi 5,5,.LC8@toc@l - addi 6,6,-29404 - bl __fprintf_chk - nop - bl exported_function - nop - addi 1,1,112 - ld 0,16(1) - ld 30,-16(1) - ld 31,-8(1) - mtlr 0 - blr - .long 0 - .byte 0,0,0,1,128,2,0,0 - .size function,.-function - .globl kExportedString - .section .rodata - .align 4 - .set .LANCHOR0,. + 0 - .type kString, @object - .size kString, 12 -kString: - .string "hello world" - .zero 4 - .type kGiantArray, @object - .size kGiantArray, 400000 -kGiantArray: - .long 1 - .long 0 - .zero 399992 - .type kExportedString, @object - .size kExportedString, 26 -kExportedString: - .string "hello world, more visibly" - .section .rodata.str1.8,"aMS",@progbits,1 - .align 3 -.LC1: - .string "kString is %p\n" - .zero 1 -.LC2: - .string "kExportedString is %p\n" - .zero 1 -.LC4: - .string "function is %p\n" -.LC5: - .string "exported_function is %p\n" - .zero 7 -.LC7: - .string "&kString[5] is %p\n" - .zero 5 -.LC8: - .string "&kGiantArray[0x12345] is %p\n" - .section ".bss" - .align 2 - .type bss, @object - .size bss, 20 -bss: - .zero 20 - .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" - .section .note.GNU-stack,"",@progbits diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/out.s deleted file mode 100644 index 54cbd6f8..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-Sample2/out.s +++ /dev/null @@ -1,709 +0,0 @@ -.text -.file 1 "inserted_by_delocate.c" -.loc 1 1 0 -BORINGSSL_bcm_text_start: - .file "foo.c" - .abiversion 2 - .section ".toc","aw" -# WAS .section ".text" -.text - .section ".toc","aw" -.LC0: - - .quad stderr -.LC3: - - .quad kExportedString -.LC6: - - .quad exported_function -# WAS .section ".text" -.text - .align 2 - .p2align 4,,15 - .globl exported_function - .type exported_function, @function -.Lexported_function_local_target: -exported_function: -0: -999: - addis 2, 12, .LBORINGSSL_external_toc-999b@ha - addi 2, 2, .LBORINGSSL_external_toc-999b@l - ld 12, 0(2) - add 2, 2, 12 -# WAS addi 2,2,.TOC.-0b@l - .localentry exported_function,.-exported_function -.Lexported_function_local_entry: - mflr 0 - std 19,-104(1) - std 20,-96(1) - std 21,-88(1) - std 22,-80(1) -# WAS addis 21,2,.LC1@toc@ha -# WAS addis 22,2,.LC2@toc@ha - std 23,-72(1) - std 24,-64(1) -# WAS addis 23,2,.LC4@toc@ha -# WAS addis 24,2,function@toc@ha - std 25,-56(1) - std 26,-48(1) -# WAS addis 25,2,.LC5@toc@ha -# WAS addis 26,2,.LC7@toc@ha - std 27,-40(1) - std 28,-32(1) -# WAS addis 28,2,.LC8@toc@ha -# WAS addi 21,21,.LC1@toc@l - addi 1, 1, -288 - mflr 21 - std 21, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC1 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 21, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - std 29,-24(1) - std 30,-16(1) -# WAS addis 29,2,.LANCHOR0@toc@ha -# WAS addi 22,22,.LC2@toc@l - addi 1, 1, -288 - mflr 22 - std 22, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC2 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 22, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - std 31,-8(1) - std 0,16(1) -# WAS addi 29,29,.LANCHOR0@toc@l - addi 1, 1, -288 - mflr 29 - std 29, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LANCHOR0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 29, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addi 23,23,.LC4@toc@l - addi 1, 1, -288 - mflr 23 - std 23, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC4 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 23, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - stdu 1,-208(1) -# WAS addis 31,2,.LC0@toc@ha # gpr load fusion, type long -# WAS ld 31,.LC0@toc@l(31) - addi 1, 1, -288 - mflr 31 - std 31, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 31, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 31, 0(31) -# WAS addis 19,2,.LC3@toc@ha # gpr load fusion, type long -# WAS ld 19,.LC3@toc@l(19) - addi 1, 1, -288 - mflr 19 - std 19, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC3 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 19, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 19, 0(19) - addis 30,29,0x5 -# WAS addi 24,24,function@toc@l - addi 1, 1, -288 - mflr 24 - std 24, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfunction_local_target - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 24, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addis 20,2,.LC6@toc@ha # gpr load fusion, type long -# WAS ld 20,.LC6@toc@l(20) - addi 1, 1, -288 - mflr 20 - std 20, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC6 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 20, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 20, 0(20) -# WAS addi 25,25,.LC5@toc@l - addi 1, 1, -288 - mflr 25 - std 25, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC5 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 25, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addi 26,26,.LC7@toc@l - addi 1, 1, -288 - mflr 26 - std 26, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC7 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 26, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - addi 27,29,5 -# WAS addi 28,28,.LC8@toc@l - addi 1, 1, -288 - mflr 28 - std 28, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC8 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 28, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - addi 30,30,-29404 - .p2align 4,,15 -.L2: - - ld 3,0(31) - mr 5,21 - mr 6,29 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - mr 5,22 - mr 6,19 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - mr 5,23 - mr 6,24 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - mr 5,25 - mr 6,20 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - mr 5,26 - mr 6,27 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - li 4,1 - mr 5,28 - mr 6,30 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - b .L2 - .long 0 - .byte 0,0,0,1,128,13,0,0 - .size exported_function,.-exported_function - .section ".toc","aw" - .set .LC11,.LC0 - .set .LC12,.LC3 - .set .LC13,.LC6 -# WAS .section ".text" -.text - .align 2 - .p2align 4,,15 - .type function, @function -.Lfunction_local_target: -function: -0: -999: - addis 2, 12, .LBORINGSSL_external_toc-999b@ha - addi 2, 2, .LBORINGSSL_external_toc-999b@l - ld 12, 0(2) - add 2, 2, 12 -# WAS addi 2,2,.TOC.-0b@l - .localentry function,.-function -.Lfunction_local_entry: - mflr 0 - std 31,-8(1) -# WAS addis 31,2,.LC11@toc@ha # gpr load fusion, type long -# WAS ld 31,.LC11@toc@l(31) - addi 1, 1, -288 - mflr 31 - std 31, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC11 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 31, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 31, 0(31) -# WAS addis 5,2,.LC1@toc@ha - std 30,-16(1) -# WAS addis 30,2,.LANCHOR0@toc@ha -# WAS addi 5,5,.LC1@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC1 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addi 30,30,.LANCHOR0@toc@l - addi 1, 1, -288 - mflr 30 - std 30, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LANCHOR0 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 30, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - li 4,1 - mr 6,30 - std 0,16(1) - stdu 1,-112(1) - ld 3,0(31) -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop -# WAS addis 6,2,.LC12@toc@ha # gpr load fusion, type long -# WAS ld 6,.LC12@toc@l(6) - addi 1, 1, -288 - mflr 6 - std 6, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC12 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 6, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 6, 0(6) - ld 3,0(31) -# WAS addis 5,2,.LC2@toc@ha - li 4,1 -# WAS addi 5,5,.LC2@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC2 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) -# WAS addis 5,2,.LC4@toc@ha -# WAS addis 6,2,function@toc@ha -# WAS addi 5,5,.LC4@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC4 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS addi 6,6,function@toc@l - addi 1, 1, -288 - mflr 6 - std 6, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfunction_local_target - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 6, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop -# WAS addis 6,2,.LC13@toc@ha # gpr load fusion, type long -# WAS ld 6,.LC13@toc@l(6) - addi 1, 1, -288 - mflr 6 - std 6, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC13 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 6, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 6, 0(6) - ld 3,0(31) -# WAS addis 5,2,.LC5@toc@ha - li 4,1 -# WAS addi 5,5,.LC5@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC5 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) -# WAS addis 5,2,.LC7@toc@ha - addi 6,30,5 -# WAS addi 5,5,.LC7@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC7 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - li 4,1 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop - ld 3,0(31) - addis 6,30,0x5 -# WAS addis 5,2,.LC8@toc@ha - li 4,1 -# WAS addi 5,5,.LC8@toc@l - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_LC8 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - addi 6,6,-29404 -# WAS bl __fprintf_chk - bl bcm_redirector___fprintf_chk - ld 2, 24(1) - nop -# WAS bl exported_function - bl .Lexported_function_local_entry - nop - addi 1,1,112 - ld 0,16(1) - ld 30,-16(1) - ld 31,-8(1) - mtlr 0 - blr - .long 0 - .byte 0,0,0,1,128,2,0,0 - .size function,.-function - .globl kExportedString -# WAS .section .rodata -.text - .align 4 - .set .LANCHOR0,. + 0 - .type kString, @object - .size kString, 12 -.LkString_local_target: -kString: - .string "hello world" - .zero 4 - .type kGiantArray, @object - .size kGiantArray, 400000 -.LkGiantArray_local_target: -kGiantArray: - .long 1 - .long 0 - .zero 399992 - .type kExportedString, @object - .size kExportedString, 26 -.LkExportedString_local_target: -kExportedString: - .string "hello world, more visibly" -# WAS .section .rodata.str1.8,"aMS",@progbits,1 -.text - .align 3 -.LC1: - - .string "kString is %p\n" - .zero 1 -.LC2: - - .string "kExportedString is %p\n" - .zero 1 -.LC4: - - .string "function is %p\n" -.LC5: - - .string "exported_function is %p\n" - .zero 7 -.LC7: - - .string "&kString[5] is %p\n" - .zero 5 -.LC8: - - .string "&kGiantArray[0x12345] is %p\n" - .section ".bss" - .align 2 - .type bss, @object - .size bss, 20 -bss: -.Lbss_local_target: - - .zero 20 - .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" - .section .note.GNU-stack,"",@progbits -.text -.loc 1 2 0 -BORINGSSL_bcm_text_end: -.section ".toc", "aw" -.Lredirector_toc___fprintf_chk: -.quad __fprintf_chk -.text -.type bcm_redirector___fprintf_chk, @function -bcm_redirector___fprintf_chk: - std 2, 24(1) - addis 12, 2, .Lredirector_toc___fprintf_chk@toc@ha - ld 12, .Lredirector_toc___fprintf_chk@toc@l(12) - mtctr 12 - bctr -.type bss_bss_get, @function -bss_bss_get: - addis 3, 2, .Lbss_local_target@toc@ha - addi 3, 3, .Lbss_local_target@toc@l - blr -.type bcm_loadtoc__dot_LANCHOR0, @function -bcm_loadtoc__dot_LANCHOR0: -.Lbcm_loadtoc__dot_LANCHOR0: - addis 3, 2, .LANCHOR0@toc@ha - addi 3, 3, .LANCHOR0@toc@l - blr -.type bcm_loadtoc__dot_LC0, @function -bcm_loadtoc__dot_LC0: -.Lbcm_loadtoc__dot_LC0: - addis 3, 2, .LC0@toc@ha - addi 3, 3, .LC0@toc@l - blr -.type bcm_loadtoc__dot_LC1, @function -bcm_loadtoc__dot_LC1: -.Lbcm_loadtoc__dot_LC1: - addis 3, 2, .LC1@toc@ha - addi 3, 3, .LC1@toc@l - blr -.type bcm_loadtoc__dot_LC11, @function -bcm_loadtoc__dot_LC11: -.Lbcm_loadtoc__dot_LC11: - addis 3, 2, .LC11@toc@ha - addi 3, 3, .LC11@toc@l - blr -.type bcm_loadtoc__dot_LC12, @function -bcm_loadtoc__dot_LC12: -.Lbcm_loadtoc__dot_LC12: - addis 3, 2, .LC12@toc@ha - addi 3, 3, .LC12@toc@l - blr -.type bcm_loadtoc__dot_LC13, @function -bcm_loadtoc__dot_LC13: -.Lbcm_loadtoc__dot_LC13: - addis 3, 2, .LC13@toc@ha - addi 3, 3, .LC13@toc@l - blr -.type bcm_loadtoc__dot_LC2, @function -bcm_loadtoc__dot_LC2: -.Lbcm_loadtoc__dot_LC2: - addis 3, 2, .LC2@toc@ha - addi 3, 3, .LC2@toc@l - blr -.type bcm_loadtoc__dot_LC3, @function -bcm_loadtoc__dot_LC3: -.Lbcm_loadtoc__dot_LC3: - addis 3, 2, .LC3@toc@ha - addi 3, 3, .LC3@toc@l - blr -.type bcm_loadtoc__dot_LC4, @function -bcm_loadtoc__dot_LC4: -.Lbcm_loadtoc__dot_LC4: - addis 3, 2, .LC4@toc@ha - addi 3, 3, .LC4@toc@l - blr -.type bcm_loadtoc__dot_LC5, @function -bcm_loadtoc__dot_LC5: -.Lbcm_loadtoc__dot_LC5: - addis 3, 2, .LC5@toc@ha - addi 3, 3, .LC5@toc@l - blr -.type bcm_loadtoc__dot_LC6, @function -bcm_loadtoc__dot_LC6: -.Lbcm_loadtoc__dot_LC6: - addis 3, 2, .LC6@toc@ha - addi 3, 3, .LC6@toc@l - blr -.type bcm_loadtoc__dot_LC7, @function -bcm_loadtoc__dot_LC7: -.Lbcm_loadtoc__dot_LC7: - addis 3, 2, .LC7@toc@ha - addi 3, 3, .LC7@toc@l - blr -.type bcm_loadtoc__dot_LC8, @function -bcm_loadtoc__dot_LC8: -.Lbcm_loadtoc__dot_LC8: - addis 3, 2, .LC8@toc@ha - addi 3, 3, .LC8@toc@l - blr -.type bcm_loadtoc__dot_Lfunction_local_target, @function -bcm_loadtoc__dot_Lfunction_local_target: -.Lbcm_loadtoc__dot_Lfunction_local_target: - addis 3, 2, .Lfunction_local_target@toc@ha - addi 3, 3, .Lfunction_local_target@toc@l - blr -.LBORINGSSL_external_toc: -.quad .TOC.-.LBORINGSSL_external_toc -.type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 -BORINGSSL_bcm_text_hash: -.byte 0xae -.byte 0x2c -.byte 0xea -.byte 0x2a -.byte 0xbd -.byte 0xa6 -.byte 0xf3 -.byte 0xec -.byte 0x97 -.byte 0x7f -.byte 0x9b -.byte 0xf6 -.byte 0x94 -.byte 0x9a -.byte 0xfc -.byte 0x83 -.byte 0x68 -.byte 0x27 -.byte 0xcb -.byte 0xa0 -.byte 0xa0 -.byte 0x9f -.byte 0x6b -.byte 0x6f -.byte 0xde -.byte 0x52 -.byte 0xcd -.byte 0xe2 -.byte 0xcd -.byte 0xff -.byte 0x31 -.byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/in.s deleted file mode 100644 index 94ea2111..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/in.s +++ /dev/null @@ -1,23 +0,0 @@ - .text -foo: - # TOC references may have offsets. - addis 3, 2, 5+foo@toc@ha - addi 3, 3, 10+foo@toc@l - - addis 3, 2, 15+foo@toc@ha - addi 3, 3, 20+foo@toc@l - - addis 4, 2, foo@toc@ha - addi 4, 4, foo@toc@l - - addis 5, 2, 5+foo@toc@ha - ld 5, 10+foo@toc@l(5) - - addis 4, 2, foo-10@toc@ha - addi 4, 4, foo-10@toc@l - - addis 4, 2, foo@toc@ha+25 - addi 4, 4, foo@toc@l+25 - - addis 4, 2, 1+foo-2@toc@ha+3 - addi 4, 4, 1+foo-2@toc@l+3 diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/out.s deleted file mode 100644 index 2fff0efb..00000000 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/ppc64le-TOCWithOffset/out.s +++ /dev/null @@ -1,210 +0,0 @@ -.text -.file 1 "inserted_by_delocate.c" -.loc 1 1 0 -BORINGSSL_bcm_text_start: - .text -.Lfoo_local_target: -foo: - # TOC references may have offsets. -# WAS addis 3, 2, 5+foo@toc@ha -# WAS addi 3, 3, 10+foo@toc@l - addi 1, 1, -288 - mflr 3 - std 3, -8(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__plus_10 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 3, -24(1) - addi 1, 1, 288 - -# WAS addis 3, 2, 15+foo@toc@ha -# WAS addi 3, 3, 20+foo@toc@l - addi 1, 1, -288 - mflr 3 - std 3, -8(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__plus_20 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 3, -24(1) - addi 1, 1, 288 - -# WAS addis 4, 2, foo@toc@ha -# WAS addi 4, 4, foo@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - -# WAS addis 5, 2, 5+foo@toc@ha -# WAS ld 5, 10+foo@toc@l(5) - addi 1, 1, -288 - mflr 5 - std 5, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__plus_10 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 5, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - ld 5, 0(5) - -# WAS addis 4, 2, foo-10@toc@ha -# WAS addi 4, 4, foo-10@toc@l - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__minus_10 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - -# WAS addis 4, 2, foo@toc@ha+25 -# WAS addi 4, 4, foo@toc@l+25 - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__plus_25 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 - -# WAS addis 4, 2, 1+foo-2@toc@ha+3 -# WAS addi 4, 4, 1+foo-2@toc@l+3 - addi 1, 1, -288 - mflr 4 - std 4, -8(1) - std 3, -16(1) - bl .Lbcm_loadtoc__dot_Lfoo_local_target__plus_1_minus_2_plus_3 - std 3, -24(1) - ld 3, -8(1) - mtlr 3 - ld 4, -24(1) - ld 3, -16(1) - addi 1, 1, 288 -.text -.loc 1 2 0 -BORINGSSL_bcm_text_end: -.type bcm_loadtoc__dot_Lfoo_local_target, @function -bcm_loadtoc__dot_Lfoo_local_target: -.Lbcm_loadtoc__dot_Lfoo_local_target: - addis 3, 2, .Lfoo_local_target@toc@ha - addi 3, 3, .Lfoo_local_target@toc@l - blr -.type bcm_loadtoc__dot_Lfoo_local_target__plus_1_minus_2_plus_3, @function -bcm_loadtoc__dot_Lfoo_local_target__plus_1_minus_2_plus_3: -.Lbcm_loadtoc__dot_Lfoo_local_target__plus_1_minus_2_plus_3: - addis 3, 2, .Lfoo_local_target+1-2+3@toc@ha - addi 3, 3, .Lfoo_local_target+1-2+3@toc@l - blr -.type bcm_loadtoc__dot_Lfoo_local_target__plus_10, @function -bcm_loadtoc__dot_Lfoo_local_target__plus_10: -.Lbcm_loadtoc__dot_Lfoo_local_target__plus_10: - addis 3, 2, .Lfoo_local_target+10@toc@ha - addi 3, 3, .Lfoo_local_target+10@toc@l - blr -.type bcm_loadtoc__dot_Lfoo_local_target__plus_20, @function -bcm_loadtoc__dot_Lfoo_local_target__plus_20: -.Lbcm_loadtoc__dot_Lfoo_local_target__plus_20: - addis 3, 2, .Lfoo_local_target+20@toc@ha - addi 3, 3, .Lfoo_local_target+20@toc@l - blr -.type bcm_loadtoc__dot_Lfoo_local_target__plus_25, @function -bcm_loadtoc__dot_Lfoo_local_target__plus_25: -.Lbcm_loadtoc__dot_Lfoo_local_target__plus_25: - addis 3, 2, .Lfoo_local_target+25@toc@ha - addi 3, 3, .Lfoo_local_target+25@toc@l - blr -.type bcm_loadtoc__dot_Lfoo_local_target__minus_10, @function -bcm_loadtoc__dot_Lfoo_local_target__minus_10: -.Lbcm_loadtoc__dot_Lfoo_local_target__minus_10: - addis 3, 2, .Lfoo_local_target-10@toc@ha - addi 3, 3, .Lfoo_local_target-10@toc@l - blr -.LBORINGSSL_external_toc: -.quad .TOC.-.LBORINGSSL_external_toc -.type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 -BORINGSSL_bcm_text_hash: -.byte 0xae -.byte 0x2c -.byte 0xea -.byte 0x2a -.byte 0xbd -.byte 0xa6 -.byte 0xf3 -.byte 0xec -.byte 0x97 -.byte 0x7f -.byte 0x9b -.byte 0xf6 -.byte 0x94 -.byte 0x9a -.byte 0xfc -.byte 0x83 -.byte 0x68 -.byte 0x27 -.byte 0xcb -.byte 0xa0 -.byte 0xa0 -.byte 0x9f -.byte 0x6b -.byte 0x6f -.byte 0xde -.byte 0x52 -.byte 0xcd -.byte 0xe2 -.byte 0xcd -.byte 0xff -.byte 0x31 -.byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-BSS/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-BSS/out.s index e8cd56ea..2bb54a80 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-BSS/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-BSS/out.s @@ -77,7 +77,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -111,35 +111,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/in.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/in.s index c54756b4..7e48e274 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/in.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/in.s @@ -47,3 +47,4 @@ foo: .L4: .L5: movq %rbx, %rax # This is also legal. .size foo, .-foo .type foo, @function +.uleb128 .foo-1-.bar diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/out.s index 23e97c8b..657d0903 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Basic/out.s @@ -55,6 +55,7 @@ foo: movq %rbx, %rax # This is also legal. .size foo, .-foo .type foo, @function +.uleb128 .foo-1-.bar .text .loc 2 2 0 BORINGSSL_bcm_text_end: @@ -70,7 +71,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -104,35 +105,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-GOTRewrite/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-GOTRewrite/out.s index 467db65b..f118e4fa 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-GOTRewrite/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-GOTRewrite/out.s @@ -303,7 +303,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -337,35 +337,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LabelRewrite/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LabelRewrite/out.s index feb9a43f..6549db71 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LabelRewrite/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LabelRewrite/out.s @@ -113,7 +113,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -147,35 +147,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LargeMemory/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LargeMemory/out.s index d4534f8a..091e8b72 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LargeMemory/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-LargeMemory/out.s @@ -59,7 +59,7 @@ OPENSSL_ia32cap_addr_delta: .Lboringssl_gotoff__Z1gv: .quad _Z1gv@GOTOFF .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -93,35 +93,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Sections/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Sections/out.s index ab3e3d9d..11123876 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Sections/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-Sections/out.s @@ -59,7 +59,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -93,35 +93,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-ThreeArg/out.s b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-ThreeArg/out.s index 7ad8f768..7a57ed46 100644 --- a/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-ThreeArg/out.s +++ b/third_party/boringssl/kit/src/util/fipstools/delocate/testdata/x86_64-ThreeArg/out.s @@ -46,7 +46,7 @@ OPENSSL_ia32cap_get: OPENSSL_ia32cap_addr_delta: .quad OPENSSL_ia32cap_P-OPENSSL_ia32cap_addr_delta .type BORINGSSL_bcm_text_hash, @object -.size BORINGSSL_bcm_text_hash, 64 +.size BORINGSSL_bcm_text_hash, 32 BORINGSSL_bcm_text_hash: .byte 0xae .byte 0x2c @@ -80,35 +80,3 @@ BORINGSSL_bcm_text_hash: .byte 0xff .byte 0x31 .byte 0x80 -.byte 0xa2 -.byte 0xd4 -.byte 0xc3 -.byte 0x66 -.byte 0xf -.byte 0xc2 -.byte 0x6a -.byte 0x7b -.byte 0xf4 -.byte 0xbe -.byte 0x39 -.byte 0xa2 -.byte 0xd7 -.byte 0x25 -.byte 0xdb -.byte 0x21 -.byte 0x98 -.byte 0xe9 -.byte 0xd5 -.byte 0x53 -.byte 0xbf -.byte 0x5c -.byte 0x32 -.byte 0x6 -.byte 0x83 -.byte 0x34 -.byte 0xc -.byte 0x65 -.byte 0x89 -.byte 0x52 -.byte 0xbd -.byte 0x1f diff --git a/third_party/boringssl/kit/src/util/fipstools/fipscommon/const.go b/third_party/boringssl/kit/src/util/fipstools/fipscommon/const.go index 56934140..c709961e 100644 --- a/third_party/boringssl/kit/src/util/fipstools/fipscommon/const.go +++ b/third_party/boringssl/kit/src/util/fipstools/fipscommon/const.go @@ -10,13 +10,13 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package fipscommon // UninitHashValue is the default hash value that we inject into the module. // This value need only be distinct, i.e. so that we can safely // search-and-replace it in an object file. -var UninitHashValue = [64]byte{ - 0xae, 0x2c, 0xea, 0x2a, 0xbd, 0xa6, 0xf3, 0xec, 0x97, 0x7f, 0x9b, 0xf6, 0x94, 0x9a, 0xfc, 0x83, 0x68, 0x27, 0xcb, 0xa0, 0xa0, 0x9f, 0x6b, 0x6f, 0xde, 0x52, 0xcd, 0xe2, 0xcd, 0xff, 0x31, 0x80, 0xa2, 0xd4, 0xc3, 0x66, 0x0f, 0xc2, 0x6a, 0x7b, 0xf4, 0xbe, 0x39, 0xa2, 0xd7, 0x25, 0xdb, 0x21, 0x98, 0xe9, 0xd5, 0x53, 0xbf, 0x5c, 0x32, 0x06, 0x83, 0x34, 0x0c, 0x65, 0x89, 0x52, 0xbd, 0x1f, +var UninitHashValue = [32]byte{ + 0xae, 0x2c, 0xea, 0x2a, 0xbd, 0xa6, 0xf3, 0xec, 0x97, 0x7f, 0x9b, 0xf6, 0x94, 0x9a, 0xfc, 0x83, 0x68, 0x27, 0xcb, 0xa0, 0xa0, 0x9f, 0x6b, 0x6f, 0xde, 0x52, 0xcd, 0xe2, 0xcd, 0xff, 0x31, 0x80, } diff --git a/third_party/boringssl/kit/src/util/fipstools/inject_hash/inject_hash.go b/third_party/boringssl/kit/src/util/fipstools/inject_hash/inject_hash.go index dbd5fb78..9c308366 100644 --- a/third_party/boringssl/kit/src/util/fipstools/inject_hash/inject_hash.go +++ b/third_party/boringssl/kit/src/util/fipstools/inject_hash/inject_hash.go @@ -10,7 +10,7 @@ // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // inject_hash parses an archive containing a file object file. It finds a FIPS // module inside that object, calculates its hash and replaces the default hash @@ -21,14 +21,12 @@ import ( "bytes" "crypto/hmac" "crypto/sha256" - "crypto/sha512" "debug/elf" "encoding/binary" "errors" "flag" "fmt" "io" - "io/ioutil" "os" "strings" @@ -36,7 +34,7 @@ import ( "boringssl.googlesource.com/boringssl/util/fipstools/fipscommon" ) -func do(outPath, oInput string, arInput string, useSHA256 bool) error { +func do(outPath, oInput string, arInput string) error { var objectBytes []byte var isStatic bool var perm os.FileMode @@ -79,7 +77,7 @@ func do(outPath, oInput string, arInput string, useSHA256 bool) error { } perm = fi.Mode() - if objectBytes, err = ioutil.ReadFile(oInput); err != nil { + if objectBytes, err = os.ReadFile(oInput); err != nil { return err } isStatic = strings.HasSuffix(oInput, ".o") @@ -216,11 +214,7 @@ func do(outPath, oInput string, arInput string, useSHA256 bool) error { } var zeroKey [64]byte - hashFunc := sha512.New - if useSHA256 { - hashFunc = sha256.New - } - mac := hmac.New(hashFunc, zeroKey[:]) + mac := hmac.New(sha256.New, zeroKey[:]) if moduleROData != nil { var lengthBytes [8]byte @@ -250,18 +244,17 @@ func do(outPath, oInput string, arInput string, useSHA256 bool) error { copy(objectBytes[offset:], calculated) - return ioutil.WriteFile(outPath, objectBytes, perm & 0777) + return os.WriteFile(outPath, objectBytes, perm&0777) } func main() { arInput := flag.String("in-archive", "", "Path to a .a file") oInput := flag.String("in-object", "", "Path to a .o file") outPath := flag.String("o", "", "Path to output object") - sha256 := flag.Bool("sha256", false, "Whether to use SHA-256 over SHA-512. This must match what the compiled module expects.") flag.Parse() - if err := do(*outPath, *oInput, *arInput, *sha256); err != nil { + if err := do(*outPath, *oInput, *arInput); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) } diff --git a/third_party/boringssl/kit/src/util/fipstools/test-break-kat.sh b/third_party/boringssl/kit/src/util/fipstools/test-break-kat.sh new file mode 100644 index 00000000..141e73fe --- /dev/null +++ b/third_party/boringssl/kit/src/util/fipstools/test-break-kat.sh @@ -0,0 +1,41 @@ +# Copyright (c) 2022, Google Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# This script attempts to break each of the known KATs and checks that doing so +# seems to work and at least mentions the correct KAT in the output. + +set -x +set -e + +TEST_FIPS_BIN="build/util/fipstools/test_fips" + +if [ ! -f $TEST_FIPS_BIN ]; then + echo "$TEST_FIPS_BIN is missing. Run this script from the top level of a" + echo "BoringSSL checkout and ensure that ./build-fips-break-test-binaries.sh" + echo "has been run first." + exit 1 +fi + +KATS=$(go run util/fipstools/break-kat.go --list-tests) + +for kat in $KATS; do + go run util/fipstools/break-kat.go $TEST_FIPS_BIN $kat > break-kat-bin + chmod u+x ./break-kat-bin + if ! (./break-kat-bin 2>&1 >/dev/null || true) | \ + egrep -q "^$kat[^a-zA-Z0-9]"; then + echo "Failure for $kat did not mention that name in the output" + exit 1 + fi + rm ./break-kat-bin +done diff --git a/third_party/boringssl/kit/src/util/fipstools/cavp/test_fips.c b/third_party/boringssl/kit/src/util/fipstools/test_fips.c similarity index 85% rename from third_party/boringssl/kit/src/util/fipstools/cavp/test_fips.c rename to third_party/boringssl/kit/src/util/fipstools/test_fips.c index dd82d65f..3a1f7fce 100644 --- a/third_party/boringssl/kit/src/util/fipstools/cavp/test_fips.c +++ b/third_party/boringssl/kit/src/util/fipstools/test_fips.c @@ -21,18 +21,20 @@ #include #include #include +#include #include #include -#include #include +#include +#include #include #include #include #include -#include "../crypto/fipsmodule/rand/internal.h" -#include "../crypto/fipsmodule/tls/internal.h" -#include "../crypto/internal.h" +#include "../../crypto/fipsmodule/rand/internal.h" +#include "../../crypto/fipsmodule/tls/internal.h" +#include "../../crypto/internal.h" static void hexdump(const void *a, size_t len) { @@ -47,6 +49,13 @@ static void hexdump(const void *a, size_t len) { int main(int argc, char **argv) { CRYPTO_library_init(); + const uint32_t module_version = FIPS_version(); + if (module_version == 0) { + printf("No module version set\n"); + goto err; + } + printf("Module version: %" PRIu32 "\n", module_version); + static const uint8_t kAESKey[16] = "BoringCrypto Key"; static const uint8_t kPlaintext[64] = "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!"; @@ -270,18 +279,43 @@ int main(int argc, char **argv) { hexdump(output, sizeof(output)); CTR_DRBG_clear(&drbg); - /* TLS KDF */ - printf("About to run TLS KDF\n"); - uint8_t tls_output[32]; - if (!CRYPTO_tls1_prf(EVP_sha256(), tls_output, sizeof(tls_output), kAESKey, - sizeof(kAESKey), "foo", 3, kPlaintextSHA256, - sizeof(kPlaintextSHA256), kPlaintextSHA256, - sizeof(kPlaintextSHA256))) { - fprintf(stderr, "TLS KDF failed.\n"); + /* HKDF */ + printf("About to run HKDF\n"); + uint8_t hkdf_output[32]; + if (!HKDF(hkdf_output, sizeof(hkdf_output), EVP_sha256(), kAESKey, + sizeof(kAESKey), (const uint8_t *)"salt", 4, kPlaintextSHA256, + sizeof(kPlaintextSHA256))) { + fprintf(stderr, "HKDF failed.\n"); goto err; } printf(" got "); - hexdump(tls_output, sizeof(tls_output)); + hexdump(hkdf_output, sizeof(hkdf_output)); + + /* TLS v1.2 KDF */ + printf("About to run TLS v1.2 KDF\n"); + uint8_t tls12_output[32]; + if (!CRYPTO_tls1_prf(EVP_sha256(), tls12_output, sizeof(tls12_output), + kAESKey, sizeof(kAESKey), "foo", 3, kPlaintextSHA256, + sizeof(kPlaintextSHA256), kPlaintextSHA256, + sizeof(kPlaintextSHA256))) { + fprintf(stderr, "TLS v1.2 KDF failed.\n"); + goto err; + } + printf(" got "); + hexdump(tls12_output, sizeof(tls12_output)); + + /* TLS v1.3 KDF */ + printf("About to run TLS v1.3 KDF\n"); + uint8_t tls13_output[32]; + if (!CRYPTO_tls13_hkdf_expand_label( + tls13_output, sizeof(tls13_output), EVP_sha256(), kAESKey, + sizeof(kAESKey), (const uint8_t *)"foo", 3, kPlaintextSHA256, + sizeof(kPlaintextSHA256))) { + fprintf(stderr, "TLS v1.3 KDF failed.\n"); + goto err; + } + printf(" got "); + hexdump(tls13_output, sizeof(tls13_output)); /* FFDH */ printf("About to compute FFDH key-agreement:\n"); @@ -305,5 +339,6 @@ int main(int argc, char **argv) { err: printf("FAIL\n"); + fflush(stdout); abort(); } diff --git a/third_party/boringssl/kit/src/util/generate_build_files.py b/third_party/boringssl/kit/src/util/generate_build_files.py index 5cc2de4a..059caed8 100644 --- a/third_party/boringssl/kit/src/util/generate_build_files.py +++ b/third_party/boringssl/kit/src/util/generate_build_files.py @@ -25,16 +25,18 @@ import json # OS_ARCH_COMBOS maps from OS and platform to the OpenSSL assembly "style" for # that platform and the extension used by asm files. +# +# TODO(https://crbug.com/boringssl/524): This probably should be a map, but some +# downstream scripts import this to find what folders to add/remove from git. OS_ARCH_COMBOS = [ - ('ios', 'arm', 'ios32', [], 'S'), - ('ios', 'aarch64', 'ios64', [], 'S'), + ('apple', 'arm', 'ios32', [], 'S'), + ('apple', 'aarch64', 'ios64', [], 'S'), + ('apple', 'x86', 'macosx', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'), + ('apple', 'x86_64', 'macosx', [], 'S'), ('linux', 'arm', 'linux32', [], 'S'), ('linux', 'aarch64', 'linux64', [], 'S'), - ('linux', 'ppc64le', 'linux64le', [], 'S'), ('linux', 'x86', 'elf', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'), ('linux', 'x86_64', 'elf', [], 'S'), - ('mac', 'x86', 'macosx', ['-fPIC', '-DOPENSSL_IA32_SSE2'], 'S'), - ('mac', 'x86_64', 'macosx', [], 'S'), ('win', 'x86', 'win32n', ['-DOPENSSL_IA32_SSE2'], 'asm'), ('win', 'x86_64', 'nasm', [], 'asm'), ('win', 'aarch64', 'win64', [], 'S'), @@ -43,12 +45,18 @@ OS_ARCH_COMBOS = [ # NON_PERL_FILES enumerates assembly files that are not processed by the # perlasm system. NON_PERL_FILES = { + ('apple', 'x86_64'): [ + 'src/third_party/fiat/asm/fiat_curve25519_adx_mul.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_square.S', + ], ('linux', 'arm'): [ 'src/crypto/curve25519/asm/x25519-asm-arm.S', 'src/crypto/poly1305/poly1305_arm_asm.S', ], ('linux', 'x86_64'): [ 'src/crypto/hrss/asm/poly_rq_mul.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_mul.S', + 'src/third_party/fiat/asm/fiat_curve25519_adx_square.S', ], } @@ -60,24 +68,35 @@ def PathOf(x): return x if not PREFIX else os.path.join(PREFIX, x) +LICENSE_TEMPLATE = """Copyright (c) 2015, Google Inc. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.""".split("\n") + +def LicenseHeader(comment): + lines = [] + for line in LICENSE_TEMPLATE: + if not line: + lines.append(comment) + else: + lines.append("%s %s" % (comment, line)) + lines.append("") + return "\n".join(lines) + + class Android(object): def __init__(self): - self.header = \ -"""# Copyright (C) 2015 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - + self.header = LicenseHeader("#") + """ # This file is created by generate_build_files.py. Do not edit manually. """ @@ -131,7 +150,7 @@ class Android(object): if asm_outputs: blueprint.write(' target: {\n') for ((osname, arch), asm_files) in asm_outputs: - if osname != 'linux' or arch == 'ppc64le': + if osname != 'linux': continue if arch == 'aarch64': arch = 'arm64' @@ -156,6 +175,9 @@ class Android(object): Returns: A copy of |asm| with files filtered according to |want_bcm| """ + # TODO(https://crbug.com/boringssl/542): Rather than filtering by filename, + # use the variable listed in the CMake perlasm line, available in + # ExtractPerlAsmFromCMakeFile. return [(archinfo, filter(lambda p: ("/crypto/fipsmodule/" in p) == want_bcm, files)) for (archinfo, files) in asm] @@ -163,21 +185,7 @@ class Android(object): class AndroidCMake(object): def __init__(self): - self.header = \ -"""# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - + self.header = LicenseHeader("#") + """ # This file is created by generate_build_files.py. Do not edit manually. # To specify a custom path prefix, set BORINGSSL_ROOT before including this # file, or use list(TRANSFORM ... PREPEND) from CMake 3.12. @@ -249,9 +257,13 @@ class Bazel(object): self.PrintVariableSection( out, 'crypto_internal_headers', files['crypto_internal_headers']) self.PrintVariableSection(out, 'crypto_sources', files['crypto']) + self.PrintVariableSection(out, 'crypto_sources_asm', files['crypto_asm']) + self.PrintVariableSection(out, 'crypto_sources_nasm', files['crypto_nasm']) self.PrintVariableSection(out, 'tool_sources', files['tool']) self.PrintVariableSection(out, 'tool_headers', files['tool_headers']) + # TODO(crbug.com/boringssl/542): Migrate everyone to the combined asm + # source lists, so we don't need to generate both sets. for ((osname, arch), asm_files) in asm_outputs: self.PrintVariableSection( out, 'crypto_sources_%s_%s' % (osname, arch), asm_files) @@ -282,21 +294,7 @@ class Bazel(object): class Eureka(object): def __init__(self): - self.header = \ -"""# Copyright (C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - + self.header = LicenseHeader("#") + """ # This file is created by generate_build_files.py. Do not edit manually. """ @@ -327,11 +325,7 @@ class GN(object): def __init__(self): self.firstSection = True - self.header = \ -"""# Copyright (c) 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - + self.header = LicenseHeader("#") + """ # This file is created by generate_build_files.py. Do not edit manually. """ @@ -353,6 +347,9 @@ class GN(object): self.PrintVariableSection(out, 'crypto_sources', files['crypto'] + files['crypto_internal_headers']) + self.PrintVariableSection(out, 'crypto_sources_asm', files['crypto_asm']) + self.PrintVariableSection(out, 'crypto_sources_nasm', + files['crypto_nasm']) self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers']) self.PrintVariableSection(out, 'ssl_sources', @@ -386,11 +383,7 @@ class GN(object): class GYP(object): def __init__(self): - self.header = \ -"""# Copyright (c) 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - + self.header = LicenseHeader("#") + """ # This file is created by generate_build_files.py. Do not edit manually. """ @@ -421,32 +414,24 @@ class GYP(object): class CMake(object): def __init__(self): - self.header = \ -R'''# Copyright (c) 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - + self.header = LicenseHeader("#") + R''' # This file is created by generate_build_files.py. Do not edit manually. -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.10) project(BoringSSL LANGUAGES C CXX) -if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CLANG 1) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fno-common -fno-exceptions -fno-rtti") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fno-common") endif() -if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fvisibility=hidden -fno-common -fno-exceptions -fno-rtti") - if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - endif() - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fno-common -std=c11") -endif() - -# pthread_rwlock_t requires a feature flag. -if(NOT WIN32) +# pthread_rwlock_t requires a feature flag on glibc. +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700") endif() @@ -456,77 +441,24 @@ if(WIN32) add_definitions(-DNOMINMAX) # Allow use of fopen. add_definitions(-D_CRT_SECURE_NO_WARNINGS) - # VS 2017 and higher supports STL-only warning suppressions. - # A bug in CMake < 3.13.0 may cause the space in this value to - # cause issues when building with NASM. In that case, update CMake. - add_definitions("-D_STL_EXTRA_DISABLED_WARNINGS=4774 4987") endif() add_definitions(-DBORINGSSL_IMPLEMENTATION) -# CMake's iOS support uses Apple's multiple-architecture toolchain. It takes an -# architecture list from CMAKE_OSX_ARCHITECTURES, leaves CMAKE_SYSTEM_PROCESSOR -# alone, and expects all architecture-specific logic to be conditioned within -# the source files rather than the build. This does not work for our assembly -# files, so we fix CMAKE_SYSTEM_PROCESSOR and only support single-architecture -# builds. -if(NOT OPENSSL_NO_ASM AND CMAKE_OSX_ARCHITECTURES) - list(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHES) - if(NOT NUM_ARCHES EQUAL 1) - message(FATAL_ERROR "Universal binaries not supported.") - endif() - list(GET CMAKE_OSX_ARCHITECTURES 0 CMAKE_SYSTEM_PROCESSOR) -endif() - if(OPENSSL_NO_ASM) add_definitions(-DOPENSSL_NO_ASM) - set(ARCH "generic") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(ARCH "x86_64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") - set(ARCH "x86_64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") - # cmake reports AMD64 on Windows, but we might be building for 32-bit. - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH "x86_64") - else() - set(ARCH "x86") - endif() -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686") - set(ARCH "x86") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") - set(ARCH "aarch64") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") - set(ARCH "aarch64") -# Apple A12 Bionic chipset which is added in iPhone XS/XS Max/XR uses arm64e architecture. -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64e") - set(ARCH "aarch64") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm*") - set(ARCH "arm") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "mips") - # Just to avoid the “unknown processor” error. - set(ARCH "generic") -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le") - set(ARCH "ppc64le") else() - message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR}) -endif() - -if(NOT OPENSSL_NO_ASM) - if(UNIX) + # On x86 and x86_64 Windows, we use the NASM output. + if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64|amd64|x86|i[3-6]86") + enable_language(ASM_NASM) + set(OPENSSL_NASM TRUE) + set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") + else() enable_language(ASM) - - # Clang's integerated assembler does not support debug symbols. - if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang") - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g") - endif() - - # CMake does not add -isysroot and -arch flags to assembly. - if(APPLE) + set(OPENSSL_ASM TRUE) + # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/20771 in older + # CMake versions. + if(APPLE AND CMAKE_VERSION VERSION_LESS 3.19) if(CMAKE_OSX_SYSROOT) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"") endif() @@ -534,9 +466,13 @@ if(NOT OPENSSL_NO_ASM) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}") endforeach() endif() - else() - set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8") - enable_language(ASM_NASM) + if(NOT WIN32) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack") + endif() + # Clang's integerated assembler does not support debug symbols. + if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang") + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g") + endif() endif() endif() @@ -547,11 +483,9 @@ if(BUILD_SHARED_LIBS) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) endif() -include_directories(src/include) - ''' - def PrintLibrary(self, out, name, files): + def PrintLibrary(self, out, name, files, libs=[]): out.write('add_library(\n') out.write(' %s\n\n' % name) @@ -559,6 +493,8 @@ include_directories(src/include) out.write(' %s\n' % PathOf(f)) out.write(')\n\n') + if libs: + out.write('target_link_libraries(%s %s)\n\n' % (name, ' '.join(libs))) def PrintExe(self, out, name, files, libs): out.write('add_executable(\n') @@ -570,7 +506,7 @@ include_directories(src/include) out.write(')\n\n') out.write('target_link_libraries(%s %s)\n\n' % (name, ' '.join(libs))) - def PrintSection(self, out, name, files): + def PrintVariable(self, out, name, files): out.write('set(\n') out.write(' %s\n\n' % name) for f in sorted(files): @@ -581,37 +517,33 @@ include_directories(src/include) with open('CMakeLists.txt', 'w+') as cmake: cmake.write(self.header) - for ((osname, arch), asm_files) in asm_outputs: - self.PrintSection(cmake, 'CRYPTO_%s_%s_SOURCES' % (osname, arch), - asm_files) + self.PrintVariable(cmake, 'CRYPTO_SOURCES_ASM', files['crypto_asm']) + self.PrintVariable(cmake, 'CRYPTO_SOURCES_NASM', files['crypto_nasm']) cmake.write( -R'''if(APPLE AND ARCH STREQUAL "aarch64") - set(CRYPTO_ARCH_SOURCES ${CRYPTO_ios_aarch64_SOURCES}) -elseif(APPLE AND ARCH STREQUAL "arm") - set(CRYPTO_ARCH_SOURCES ${CRYPTO_ios_arm_SOURCES}) -elseif(APPLE) - set(CRYPTO_ARCH_SOURCES ${CRYPTO_mac_${ARCH}_SOURCES}) -elseif(UNIX) - set(CRYPTO_ARCH_SOURCES ${CRYPTO_linux_${ARCH}_SOURCES}) -elseif(WIN32) - set(CRYPTO_ARCH_SOURCES ${CRYPTO_win_${ARCH}_SOURCES}) +R'''if(OPENSSL_ASM) + list(APPEND CRYPTO_SOURCES_ASM_USED ${CRYPTO_SOURCES_ASM}) +endif() +if(OPENSSL_NASM) + list(APPEND CRYPTO_SOURCES_ASM_USED ${CRYPTO_SOURCES_NASM}) endif() ''') self.PrintLibrary(cmake, 'crypto', - files['crypto'] + ['${CRYPTO_ARCH_SOURCES}']) - self.PrintLibrary(cmake, 'ssl', files['ssl']) + files['crypto'] + ['${CRYPTO_SOURCES_ASM_USED}']) + cmake.write('target_include_directories(crypto PUBLIC $)\n\n') + self.PrintLibrary(cmake, 'ssl', files['ssl'], ['crypto']) self.PrintExe(cmake, 'bssl', files['tool'], ['ssl', 'crypto']) cmake.write( -R'''if(NOT WIN32 AND NOT ANDROID) - target_link_libraries(crypto pthread) +R'''if(NOT ANDROID) + find_package(Threads REQUIRED) + target_link_libraries(crypto Threads::Threads) endif() if(WIN32) - target_link_libraries(bssl ws2_32) + target_link_libraries(crypto ws2_32) endif() ''') @@ -736,12 +668,12 @@ def ExtractPerlAsmFromCMakeFile(cmakefile): raise ValueError('Bad perlasm line in %s' % cmakefile) # Remove "perlasm(" from start and ")" from end params = line[8:-1].split() - if len(params) < 2: + if len(params) != 4: raise ValueError('Bad perlasm line in %s' % cmakefile) perlasms.append({ - 'extra_args': params[2:], - 'input': os.path.join(os.path.dirname(cmakefile), params[1]), - 'output': os.path.join(os.path.dirname(cmakefile), params[0]), + 'arch': params[1], + 'output': os.path.join(os.path.dirname(cmakefile), params[2]), + 'input': os.path.join(os.path.dirname(cmakefile), params[3]), }) return perlasms @@ -768,51 +700,28 @@ def PerlAsm(output_filename, input_filename, perlasm_style, extra_args): ['perl', input_filename, perlasm_style] + extra_args + [output_filename]) -def ArchForAsmFilename(filename): - """Returns the architectures that a given asm file should be compiled for - based on substrings in the filename.""" - - if 'x86_64' in filename or 'avx2' in filename: - return ['x86_64'] - elif ('x86' in filename and 'x86_64' not in filename) or '586' in filename: - return ['x86'] - elif 'armx' in filename: - return ['arm', 'aarch64'] - elif 'armv8' in filename: - return ['aarch64'] - elif 'arm' in filename: - return ['arm'] - elif 'ppc' in filename: - return ['ppc64le'] - else: - raise ValueError('Unknown arch for asm filename: ' + filename) - - def WriteAsmFiles(perlasms): """Generates asm files from perlasm directives for each supported OS x platform combination.""" asmfiles = {} - for osarch in OS_ARCH_COMBOS: - (osname, arch, perlasm_style, extra_args, asm_ext) = osarch - key = (osname, arch) - outDir = '%s-%s' % key - - for perlasm in perlasms: - filename = os.path.basename(perlasm['input']) + for perlasm in perlasms: + for (osname, arch, perlasm_style, extra_args, asm_ext) in OS_ARCH_COMBOS: + if arch != perlasm['arch']: + continue + # TODO(https://crbug.com/boringssl/524): Now that we incorporate osname in + # the output filename, the asm files can just go in a single directory. + # For now, we keep them in target-specific directories to avoid breaking + # downstream scripts. + key = (osname, arch) + outDir = '%s-%s' % key output = perlasm['output'] if not output.startswith('src'): raise ValueError('output missing src: %s' % output) output = os.path.join(outDir, output[4:]) - if output.endswith('-armx.${ASM_EXT}'): - output = output.replace('-armx', - '-armx64' if arch == 'aarch64' else '-armx32') - output = output.replace('${ASM_EXT}', asm_ext) - - if arch in ArchForAsmFilename(filename): - PerlAsm(output, perlasm['input'], perlasm_style, - perlasm['extra_args'] + extra_args) - asmfiles.setdefault(key, []).append(output) + output = '%s-%s.%s' % (output, osname, asm_ext) + PerlAsm(output, perlasm['input'], perlasm_style, extra_args) + asmfiles.setdefault(key, []).append(output) for (key, non_perl_asm_files) in NON_PERL_FILES.items(): asmfiles.setdefault(key, []).extend(non_perl_asm_files) @@ -930,9 +839,26 @@ def main(platforms): FindHeaderFiles(os.path.join('src', 'crypto'), NoTests) + FindHeaderFiles(os.path.join('src', 'third_party', 'fiat'), NoTests)) + asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).items()) + + # Generate combined source lists for gas and nasm. Build files have a choice + # of using the per-platform ones or the combined ones. In the combined mode, + # Windows x86 and Windows x86_64 must still be special-cased, but otherwise + # all assembly files can be linked together. Some files appear in multiple + # per-platform lists, so we duplicate. + asm_sources = set() + nasm_sources = set() + for ((osname, arch), asm_files) in asm_outputs: + if (osname, arch) in (('win', 'x86'), ('win', 'x86_64')): + nasm_sources.update(asm_files) + else: + asm_sources.update(asm_files) + files = { 'bcm_crypto': bcm_crypto_c_files, 'crypto': crypto_c_files, + 'crypto_asm': sorted(list(asm_sources)), + 'crypto_nasm': sorted(list(nasm_sources)), 'crypto_headers': crypto_h_files, 'crypto_internal_headers': crypto_internal_h_files, 'crypto_test': crypto_test_files, @@ -950,8 +876,6 @@ def main(platforms): 'urandom_test': urandom_test_files, } - asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).items()) - for platform in platforms: platform.WriteFiles(files, asm_outputs) @@ -969,8 +893,9 @@ ALL_PLATFORMS = { } if __name__ == '__main__': - parser = optparse.OptionParser(usage='Usage: %%prog [--prefix=] [%s]' % - '|'.join(sorted(ALL_PLATFORMS.keys()))) + parser = optparse.OptionParser( + usage='Usage: %%prog [--prefix=] [all|%s]' % + '|'.join(sorted(ALL_PLATFORMS.keys()))) parser.add_option('--prefix', dest='prefix', help='For Bazel, prepend argument to all source files') parser.add_option( @@ -985,12 +910,15 @@ if __name__ == '__main__': parser.print_help() sys.exit(1) - platforms = [] - for s in args: - platform = ALL_PLATFORMS.get(s) - if platform is None: - parser.print_help() - sys.exit(1) - platforms.append(platform()) + if 'all' in args: + platforms = [platform() for platform in ALL_PLATFORMS.values()] + else: + platforms = [] + for s in args: + platform = ALL_PLATFORMS.get(s) + if platform is None: + parser.print_help() + sys.exit(1) + platforms.append(platform()) sys.exit(main(platforms)) diff --git a/third_party/boringssl/kit/src/util/go_tests.txt b/third_party/boringssl/kit/src/util/go_tests.txt new file mode 100644 index 00000000..0f43cf68 --- /dev/null +++ b/third_party/boringssl/kit/src/util/go_tests.txt @@ -0,0 +1,4 @@ +./ssl/test/runner/hpke +./util/ar +./util/fipstools/acvp/acvptool/testmodulewrapper +./util/fipstools/delocate diff --git a/third_party/boringssl/kit/src/util/godeps.go b/third_party/boringssl/kit/src/util/godeps.go index 960faa46..56be5594 100644 --- a/third_party/boringssl/kit/src/util/godeps.go +++ b/third_party/boringssl/kit/src/util/godeps.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // godeps prints out dependencies of a package in either CMake or Make depfile // format, for incremental rebuilds. // diff --git a/third_party/boringssl/kit/src/util/make_errors.go b/third_party/boringssl/kit/src/util/make_errors.go index 4e2718b8..874a001b 100644 --- a/third_party/boringssl/kit/src/util/make_errors.go +++ b/third_party/boringssl/kit/src/util/make_errors.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -188,28 +190,13 @@ type assignment struct { value int } -type assignmentsSlice []assignment - -func (a assignmentsSlice) Len() int { - return len(a) -} - -func (a assignmentsSlice) Less(i, j int) bool { - return a[i].value < a[j].value -} - -func (a assignmentsSlice) Swap(i, j int) { - a[i], a[j] = a[j], a[i] -} - func outputAssignments(w io.Writer, assignments map[string]int) { - var sorted assignmentsSlice - + sorted := make([]assignment, 0, len(assignments)) for key, value := range assignments { sorted = append(sorted, assignment{key, value}) } - sort.Sort(sorted) + sort.Slice(sorted, func(i, j int) bool { return sorted[i].value < sorted[j].value }) for _, assignment := range sorted { fmt.Fprintf(w, "#define %s %d\n", assignment.key, assignment.value) diff --git a/third_party/boringssl/kit/src/util/make_prefix_headers.go b/third_party/boringssl/kit/src/util/make_prefix_headers.go index b536f14c..8787654b 100644 --- a/third_party/boringssl/kit/src/util/make_prefix_headers.go +++ b/third_party/boringssl/kit/src/util/make_prefix_headers.go @@ -12,12 +12,15 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // This program takes a file containing newline-separated symbols, and generates // boringssl_prefix_symbols.h, boringssl_prefix_symbols_asm.h, and // boringssl_prefix_symbols_nasm.inc. These header files can be used to build // BoringSSL with a prefix for all symbols in order to avoid symbol name // conflicts when linking a project with multiple copies of BoringSSL; see // BUILDING.md for more details. +package main // TODO(joshlf): For platforms which support it, use '#pragma redefine_extname' // instead of a custom macro. This avoids the need for a custom macro, but also @@ -26,8 +29,6 @@ // IllumOS' fork of OpenSSL: // https://github.com/joyent/illumos-extra/blob/master/openssl1x/sunw_prefix.h -package main - import ( "bufio" "flag" diff --git a/third_party/boringssl/kit/src/util/read_symbols.go b/third_party/boringssl/kit/src/util/read_symbols.go index 96c148ab..1d8ec859 100644 --- a/third_party/boringssl/kit/src/util/read_symbols.go +++ b/third_party/boringssl/kit/src/util/read_symbols.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + // read_symbols scans one or more .a files and, for each object contained in // the .a files, reads the list of symbols in that object file. package main @@ -59,7 +61,7 @@ func defaultObjFileFormat(goos string) string { } } -func printAndExit(format string, args ...interface{}) { +func printAndExit(format string, args ...any) { s := fmt.Sprintf(format, args...) fmt.Fprintln(os.Stderr, s) os.Exit(1) @@ -176,6 +178,9 @@ func listSymbolsELF(contents []byte) ([]string, error) { return nil, err } syms, err := f.Symbols() + if err == elf.ErrNoSymbols { + return nil, nil + } if err != nil { return nil, err } diff --git a/third_party/boringssl/kit/src/util/run_android_tests.go b/third_party/boringssl/kit/src/util/run_android_tests.go index 5eae742d..ce878195 100644 --- a/third_party/boringssl/kit/src/util/run_android_tests.go +++ b/third_party/boringssl/kit/src/util/run_android_tests.go @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +//go:build ignore + package main import ( @@ -21,7 +23,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -232,13 +233,14 @@ func detectOptionsFromCMake() error { fmt.Printf("Detected ABI %q from CMakeCache.txt.\n", *abi) } if *apiLevel == 0 { - apiLevelStr, ok := cmakeVars["ANDROID_NATIVE_API_LEVEL"] + apiLevelStr, ok := cmakeVars["ANDROID_PLATFORM"] if !ok { - return errors.New("ANDROID_NATIVE_API_LEVEL not found in CMakeCache.txt") + return errors.New("ANDROID_PLATFORM not found in CMakeCache.txt") } + apiLevelStr = strings.TrimPrefix(apiLevelStr, "android-") var err error if *apiLevel, err = strconv.Atoi(apiLevelStr); err != nil { - return fmt.Errorf("error parsing ANDROID_NATIVE_API_LEVEL: %s", err) + return fmt.Errorf("error parsing ANDROID_PLATFORM: %s", err) } fmt.Printf("Detected API level %d from CMakeCache.txt.\n", *apiLevel) } @@ -293,7 +295,7 @@ func main() { } // Stage everything in a temporary directory. - tmpDir, err := ioutil.TempDir("", "boringssl-android") + tmpDir, err := os.MkdirTemp("", "boringssl-android") if err != nil { fmt.Printf("Error making temporary directory: %s\n", err) os.Exit(1) diff --git a/third_party/boringssl/kit/src/util/whitespace.txt b/third_party/boringssl/kit/src/util/whitespace.txt index c311da36..08ccc0a1 100644 --- a/third_party/boringssl/kit/src/util/whitespace.txt +++ b/third_party/boringssl/kit/src/util/whitespace.txt @@ -1 +1 @@ -This file is ignored. It exists to make no-op commits to trigger new builds. +This file is ignored. It exists to make no-op commits to trigger new builds. diff --git a/third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8-win.S similarity index 98% rename from third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8-win.S index ef06f9b9..8a815438 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/chacha/chacha-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -68,7 +67,7 @@ Lshort: ldp x24,x25,[x3] // load key ldp x26,x27,[x3,#16] ldp x28,x30,[x4] // load counter -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x24,x24,#32 ror x25,x25,#32 ror x26,x26,#32 @@ -229,7 +228,7 @@ Loop: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -286,7 +285,7 @@ Less_than_64: add x15,x15,x16,lsl#32 add x17,x17,x19,lsl#32 add x20,x20,x21,lsl#32 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -354,7 +353,7 @@ ChaCha20_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -652,7 +651,7 @@ Loop_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -732,7 +731,7 @@ Ltail_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -852,7 +851,7 @@ L512_or_more_neon: ldp x28,x30,[x4] // load counter ld1 {v27.4s},[x4] ld1 {v31.4s},[x5] -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev64 v24.4s,v24.4s ror x24,x24,#32 ror x25,x25,#32 @@ -1365,7 +1364,7 @@ Loop_upper_neon: add x20,x20,x21,lsl#32 ldp x19,x21,[x1,#48] add x1,x1,#64 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1879,7 +1878,7 @@ Loop_lower_neon: add x1,x1,#64 add v21.4s,v21.4s,v25.4s -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ rev x5,x5 rev x7,x7 rev x9,x9 @@ -1996,5 +1995,8 @@ Ldone_512_neon: AARCH64_VALIDATE_LINK_REGISTER ret +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-win.S b/third_party/boringssl/kit/win-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-win.S new file mode 100644 index 00000000..8c22c4d5 --- /dev/null +++ b/third_party/boringssl/kit/win-aarch64/crypto/cipher_extra/chacha20_poly1305_armv8-win.S @@ -0,0 +1,3027 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +.section .rodata + +.align 7 +Lchacha20_consts: +.byte 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' +Linc: +.long 1,2,3,4 +Lrol8: +.byte 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +Lclamp: +.quad 0x0FFFFFFC0FFFFFFF, 0x0FFFFFFC0FFFFFFC + +.text + +.def Lpoly_hash_ad_internal + .type 32 +.endef +.align 6 +Lpoly_hash_ad_internal: +.cfi_startproc + cbnz x4, Lpoly_hash_intro + ret + +Lpoly_hash_intro: + cmp x4, #16 + b.lt Lpoly_hash_ad_tail + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b Lpoly_hash_ad_internal + +Lpoly_hash_ad_tail: + cbz x4, Lpoly_hash_ad_ret + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the AAD + sub x4, x4, #1 + +Lpoly_hash_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, x4] + mov v20.b[0], w11 + subs x4, x4, #1 + b.ge Lpoly_hash_tail_16_compose + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lpoly_hash_ad_ret: + ret +.cfi_endproc + + +///////////////////////////////// +// +// void chacha20_poly1305_seal(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *seal_data); +// +.globl chacha20_poly1305_seal + +.def chacha20_poly1305_seal + .type 32 +.endef +.align 6 +chacha20_poly1305_seal: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, Lchacha20_consts + add x11, x11, :lo12:Lchacha20_consts + + ld1 {v24.16b - v27.16b}, [x11] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + ldr x12, [x5, #56] // The total cipher text length includes extra_in_len + add x12, x12, x2 + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x12 + + cmp x2, #128 + b.le Lseal_128 // Optimization for smaller buffers + + // Initially we prepare 5 ChaCha20 blocks. Four to encrypt up to 4 blocks (256 bytes) of plaintext, + // and one for the Poly1305 R and S keys. The first four blocks (A0-A3..D0-D3) are computed vertically, + // the fifth block (A4-D4) horizontally. + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + sub x5, x5, #32 + + mov x6, #10 + +.align 5 +Lseal_init_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.hi Lseal_init_rounds + + add v15.4s, v15.4s, v25.4s + mov x11, #4 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + and v4.16b, v4.16b, v27.16b + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + mov x16, v4.d[0] // Move the R key to GPRs + mov x17, v4.d[1] + mov v27.16b, v9.16b // Store the S key + + bl Lpoly_hash_ad_internal + + mov x3, x0 + cmp x2, #256 + b.le Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #256 + + mov x6, #4 // In the first run of the loop we need to hash 256 bytes, therefore we hash one block for the first 4 rounds + mov x7, #6 // and two blocks for the remaining 6, for a total of (1 * 4 + 2 * 6) * 16 = 256 + +Lseal_main_loop: + adrp x11, Lchacha20_consts + add x11, x11, :lo12:Lchacha20_consts + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + sub x5, x5, #32 +.align 5 +Lseal_main_loop_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x6, x6, #1 + b.ge Lseal_main_loop_rounds + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + subs x7, x7, #1 + b.gt Lseal_main_loop_rounds + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + cmp x2, #320 + b.le Lseal_tail + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #320 + + mov x6, #0 + mov x7, #10 // For the remainder of the loop we always hash and encrypt 320 bytes per iteration + + b Lseal_main_loop + +Lseal_tail: + // This part of the function handles the storage and authentication of the last [0,320) bytes + // We assume A0-A4 ... D0-D4 hold at least inl (320 max) bytes of the stream data. + cmp x2, #64 + b.lt Lseal_tail_64 + + // Store and authenticate 64B blocks per iteration + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + // Shift the state left by 64 bytes for the next iteration of the loop + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + + mov v1.16b, v2.16b + mov v6.16b, v7.16b + mov v11.16b, v12.16b + mov v16.16b, v17.16b + + mov v2.16b, v3.16b + mov v7.16b, v8.16b + mov v12.16b, v13.16b + mov v17.16b, v18.16b + + mov v3.16b, v4.16b + mov v8.16b, v9.16b + mov v13.16b, v14.16b + mov v18.16b, v19.16b + + b Lseal_tail + +Lseal_tail_64: + ldp x3, x4, [x5, #48] // extra_in_len and extra_in_ptr + + // Here we handle the last [0,64) bytes of plaintext + cmp x2, #16 + b.lt Lseal_tail_16 + // Each iteration encrypt and authenticate a 16B block + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + st1 {v20.16b}, [x0], #16 + + sub x2, x2, #16 + + // Shift the state left by 16 bytes for the next iteration of the loop + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + + b Lseal_tail_64 + +Lseal_tail_16: + // Here we handle the last [0,16) bytes of ciphertext that require a padded block + cbz x2, Lseal_hash_extra + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the plaintext/extra in + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask that will only mask the ciphertext bytes + not v22.16b, v20.16b + + mov x6, x2 + add x1, x1, x2 + + cbz x4, Lseal_tail_16_compose // No extra data to pad with, zero padding + + mov x7, #16 // We need to load some extra_in first for padding + sub x7, x7, x2 + cmp x4, x7 + csel x7, x4, x7, lt // Load the minimum of extra_in_len and the amount needed to fill the register + mov x12, x7 + add x3, x3, x7 + sub x4, x4, x7 + +Lseal_tail16_compose_extra_in: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x7, x7, #1 + b.gt Lseal_tail16_compose_extra_in + + add x3, x3, x12 + +Lseal_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x1, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt Lseal_tail_16_compose + + and v0.16b, v0.16b, v21.16b + eor v20.16b, v20.16b, v0.16b + mov v21.16b, v20.16b + +Lseal_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt Lseal_tail_16_store + + // Hash in the final ct block concatenated with extra_in + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lseal_hash_extra: + cbz x4, Lseal_finalize + +Lseal_hash_extra_loop: + cmp x4, #16 + b.lt Lseal_hash_extra_tail + ld1 {v20.16b}, [x3], #16 + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #16 + b Lseal_hash_extra_loop + +Lseal_hash_extra_tail: + cbz x4, Lseal_finalize + eor v20.16b, v20.16b, v20.16b // Use T0 to load the remaining extra ciphertext + add x3, x3, x4 + +Lseal_hash_extra_load: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x3, #-1]! + mov v20.b[0], w11 + subs x4, x4, #1 + b.gt Lseal_hash_extra_load + + // Hash in the final padded extra_in blcok + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + +Lseal_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +Lseal_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +Lseal_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi Lseal_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + // Only the first 32 bytes of the third block (counter = 0) are needed, + // so skip updating v12 and v17. + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl Lpoly_hash_ad_internal + b Lseal_tail +.cfi_endproc + + +///////////////////////////////// +// +// void chacha20_poly1305_open(uint8_t *pt, uint8_t *ct, size_t len_in, uint8_t *ad, size_t len_ad, union open_data *aead_data); +// +.globl chacha20_poly1305_open + +.def chacha20_poly1305_open + .type 32 +.endef +.align 6 +chacha20_poly1305_open: + AARCH64_SIGN_LINK_REGISTER +.cfi_startproc + stp x29, x30, [sp, #-80]! +.cfi_def_cfa_offset 80 +.cfi_offset w30, -72 +.cfi_offset w29, -80 + mov x29, sp + // We probably could do .cfi_def_cfa w29, 80 at this point, but since + // we don't actually use the frame pointer like that, it's probably not + // worth bothering. + stp d8, d9, [sp, #16] + stp d10, d11, [sp, #32] + stp d12, d13, [sp, #48] + stp d14, d15, [sp, #64] +.cfi_offset b15, -8 +.cfi_offset b14, -16 +.cfi_offset b13, -24 +.cfi_offset b12, -32 +.cfi_offset b11, -40 +.cfi_offset b10, -48 +.cfi_offset b9, -56 +.cfi_offset b8, -64 + + adrp x11, Lchacha20_consts + add x11, x11, :lo12:Lchacha20_consts + + ld1 {v24.16b - v27.16b}, [x11] // Load the CONSTS, INC, ROL8 and CLAMP values + ld1 {v28.16b - v30.16b}, [x5] + + mov x15, #1 // Prepare the Poly1305 state + mov x8, #0 + mov x9, #0 + mov x10, #0 + + mov v31.d[0], x4 // Store the input and aad lengths + mov v31.d[1], x2 + + cmp x2, #128 + b.le Lopen_128 // Optimization for smaller buffers + + // Initially we prepare a single ChaCha20 block for the Poly1305 R and S keys + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + + mov x6, #10 + +.align 5 +Lopen_init_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.hi Lopen_init_rounds + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + + and v0.16b, v0.16b, v27.16b + mov x16, v0.d[0] // Move the R key to GPRs + mov x17, v0.d[1] + mov v27.16b, v5.16b // Store the S key + + bl Lpoly_hash_ad_internal + +Lopen_ad_done: + mov x3, x1 + +// Each iteration of the loop hash 320 bytes, and prepare stream for 320 bytes +Lopen_main_loop: + + cmp x2, #192 + b.lt Lopen_tail + + adrp x11, Lchacha20_consts + add x11, x11, :lo12:Lchacha20_consts + + ld4r {v0.4s,v1.4s,v2.4s,v3.4s}, [x11] + mov v4.16b, v24.16b + + ld4r {v5.4s,v6.4s,v7.4s,v8.4s}, [x5], #16 + mov v9.16b, v28.16b + + ld4r {v10.4s,v11.4s,v12.4s,v13.4s}, [x5], #16 + mov v14.16b, v29.16b + + ld4r {v15.4s,v16.4s,v17.4s,v18.4s}, [x5] + sub x5, x5, #32 + add v15.4s, v15.4s, v25.4s + mov v19.16b, v30.16b + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + lsr x4, x2, #4 // How many whole blocks we have to hash, will always be at least 12 + sub x4, x4, #10 + + mov x7, #10 + subs x6, x7, x4 + subs x6, x7, x4 // itr1 can be negative if we have more than 320 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are full + + cbz x7, Lopen_main_loop_rounds_short + +.align 5 +Lopen_main_loop_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +Lopen_main_loop_rounds_short: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v9.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v18.8h, v18.8h + rev32 v19.8h, v19.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + eor v8.16b, v8.16b, v13.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v9.4s, #20 + sli v8.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + add v3.4s, v3.4s, v7.4s + add v4.4s, v4.4s, v8.4s + + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + eor v18.16b, v18.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v18.16b, {v18.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + add v13.4s, v13.4s, v18.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v14.16b + + ushr v9.4s, v8.4s, #25 + sli v9.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #4 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #12 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + add v0.4s, v0.4s, v6.4s + add v1.4s, v1.4s, v7.4s + add v2.4s, v2.4s, v8.4s + add v3.4s, v3.4s, v5.4s + add v4.4s, v4.4s, v9.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + rev32 v18.8h, v18.8h + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + rev32 v19.8h, v19.8h + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v6.16b, v6.16b, v12.16b + eor v7.16b, v7.16b, v13.16b + eor v8.16b, v8.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v9.16b, v9.16b, v14.16b + + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + ushr v7.4s, v8.4s, #20 + sli v7.4s, v8.4s, #12 + ushr v8.4s, v5.4s, #20 + sli v8.4s, v5.4s, #12 + ushr v5.4s, v9.4s, #20 + sli v5.4s, v9.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + add v3.4s, v3.4s, v8.4s + add v4.4s, v4.4s, v5.4s + + eor v18.16b, v18.16b, v0.16b + eor v15.16b, v15.16b, v1.16b + eor v16.16b, v16.16b, v2.16b + eor v17.16b, v17.16b, v3.16b + eor v19.16b, v19.16b, v4.16b + + tbl v18.16b, {v18.16b}, v26.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + tbl v19.16b, {v19.16b}, v26.16b + + add v12.4s, v12.4s, v18.4s + add v13.4s, v13.4s, v15.4s + add v10.4s, v10.4s, v16.4s + add v11.4s, v11.4s, v17.4s + add v14.4s, v14.4s, v19.4s + + eor v20.16b, v20.16b, v12.16b + eor v6.16b, v6.16b, v13.16b + eor v7.16b, v7.16b, v10.16b + eor v8.16b, v8.16b, v11.16b + eor v5.16b, v5.16b, v14.16b + + ushr v9.4s, v5.4s, #25 + sli v9.4s, v5.4s, #7 + ushr v5.4s, v8.4s, #25 + sli v5.4s, v8.4s, #7 + ushr v8.4s, v7.4s, #25 + sli v8.4s, v7.4s, #7 + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + + ext v9.16b, v9.16b, v9.16b, #12 + ext v14.16b, v14.16b, v14.16b, #8 + ext v19.16b, v19.16b, v19.16b, #4 + subs x7, x7, #1 + b.gt Lopen_main_loop_rounds + subs x6, x6, #1 + b.ge Lopen_main_loop_rounds_short + + eor v20.16b, v20.16b, v20.16b //zero + not v21.16b, v20.16b // -1 + sub v21.4s, v25.4s, v21.4s // Add +1 + ext v20.16b, v21.16b, v20.16b, #12 // Get the last element (counter) + add v19.4s, v19.4s, v20.4s + + add v15.4s, v15.4s, v25.4s + mov x11, #5 + dup v20.4s, w11 + add v25.4s, v25.4s, v20.4s + + zip1 v20.4s, v0.4s, v1.4s + zip2 v21.4s, v0.4s, v1.4s + zip1 v22.4s, v2.4s, v3.4s + zip2 v23.4s, v2.4s, v3.4s + + zip1 v0.2d, v20.2d, v22.2d + zip2 v1.2d, v20.2d, v22.2d + zip1 v2.2d, v21.2d, v23.2d + zip2 v3.2d, v21.2d, v23.2d + + zip1 v20.4s, v5.4s, v6.4s + zip2 v21.4s, v5.4s, v6.4s + zip1 v22.4s, v7.4s, v8.4s + zip2 v23.4s, v7.4s, v8.4s + + zip1 v5.2d, v20.2d, v22.2d + zip2 v6.2d, v20.2d, v22.2d + zip1 v7.2d, v21.2d, v23.2d + zip2 v8.2d, v21.2d, v23.2d + + zip1 v20.4s, v10.4s, v11.4s + zip2 v21.4s, v10.4s, v11.4s + zip1 v22.4s, v12.4s, v13.4s + zip2 v23.4s, v12.4s, v13.4s + + zip1 v10.2d, v20.2d, v22.2d + zip2 v11.2d, v20.2d, v22.2d + zip1 v12.2d, v21.2d, v23.2d + zip2 v13.2d, v21.2d, v23.2d + + zip1 v20.4s, v15.4s, v16.4s + zip2 v21.4s, v15.4s, v16.4s + zip1 v22.4s, v17.4s, v18.4s + zip2 v23.4s, v17.4s, v18.4s + + zip1 v15.2d, v20.2d, v22.2d + zip2 v16.2d, v20.2d, v22.2d + zip1 v17.2d, v21.2d, v23.2d + zip2 v18.2d, v21.2d, v23.2d + + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + + add v1.4s, v1.4s, v24.4s + add v6.4s, v6.4s, v28.4s + add v11.4s, v11.4s, v29.4s + add v16.4s, v16.4s, v30.4s + + add v2.4s, v2.4s, v24.4s + add v7.4s, v7.4s, v28.4s + add v12.4s, v12.4s, v29.4s + add v17.4s, v17.4s, v30.4s + + add v3.4s, v3.4s, v24.4s + add v8.4s, v8.4s, v28.4s + add v13.4s, v13.4s, v29.4s + add v18.4s, v18.4s, v30.4s + + add v4.4s, v4.4s, v24.4s + add v9.4s, v9.4s, v28.4s + add v14.4s, v14.4s, v29.4s + add v19.4s, v19.4s, v30.4s + + // We can always safely store 192 bytes + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #192 + + mov v0.16b, v3.16b + mov v5.16b, v8.16b + mov v10.16b, v13.16b + mov v15.16b, v18.16b + + cmp x2, #64 + b.lt Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v3.16b + eor v21.16b, v21.16b, v8.16b + eor v22.16b, v22.16b, v13.16b + eor v23.16b, v23.16b, v18.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v4.16b + mov v5.16b, v9.16b + mov v10.16b, v14.16b + mov v15.16b, v19.16b + + cmp x2, #64 + b.lt Lopen_tail_64_store + + ld1 {v20.16b - v23.16b}, [x1], #64 + eor v20.16b, v20.16b, v4.16b + eor v21.16b, v21.16b, v9.16b + eor v22.16b, v22.16b, v14.16b + eor v23.16b, v23.16b, v19.16b + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + b Lopen_main_loop + +Lopen_tail: + + cbz x2, Lopen_finalize + + lsr x4, x2, #4 // How many whole blocks we have to hash + + cmp x2, #64 + b.le Lopen_tail_64 + cmp x2, #128 + b.le Lopen_tail_128 + +Lopen_tail_192: + // We need three more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + mov v17.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v21.16b, v21.16b, v21.16b + ins v23.s[0], v25.s[0] + ins v21.d[0], x15 + + add v22.4s, v23.4s, v21.4s + add v21.4s, v22.4s, v21.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + mov x7, #10 + subs x6, x7, x4 // itr1 can be negative if we have more than 160 bytes to hash + csel x7, x7, x4, le // if itr1 is zero or less, itr2 should be 10 to indicate all 10 rounds are hashing + sub x4, x4, x7 + + cbz x7, Lopen_tail_192_rounds_no_hash + +Lopen_tail_192_rounds: + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most +Lopen_tail_192_rounds_no_hash: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x7, x7, #1 + b.gt Lopen_tail_192_rounds + subs x6, x6, #1 + b.ge Lopen_tail_192_rounds_no_hash + + // We hashed 160 bytes at most, may still have 32 bytes left +Lopen_tail_192_hash: + cbz x4, Lopen_tail_192_hash_done + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b Lopen_tail_192_hash + +Lopen_tail_192_hash_done: + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v12.4s, v12.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v17.4s, v17.4s, v30.4s + + add v15.4s, v15.4s, v21.4s + add v16.4s, v16.4s, v23.4s + add v17.4s, v17.4s, v22.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v2.16b + eor v21.16b, v21.16b, v7.16b + eor v22.16b, v22.16b, v12.16b + eor v23.16b, v23.16b, v17.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #128 + b Lopen_tail_64_store + +Lopen_tail_128: + // We need two more blocks + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v15.16b, v30.16b + mov v16.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + eor v22.16b, v22.16b, v22.16b + ins v23.s[0], v25.s[0] + ins v22.d[0], x15 + add v22.4s, v22.4s, v23.4s + + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +Lopen_tail_128_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #4 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + add v1.4s, v1.4s, v6.4s + eor v16.16b, v16.16b, v1.16b + rev32 v16.8h, v16.8h + + add v11.4s, v11.4s, v16.4s + eor v6.16b, v6.16b, v11.16b + ushr v20.4s, v6.4s, #20 + sli v20.4s, v6.4s, #12 + add v1.4s, v1.4s, v20.4s + eor v16.16b, v16.16b, v1.16b + tbl v16.16b, {v16.16b}, v26.16b + + add v11.4s, v11.4s, v16.4s + eor v20.16b, v20.16b, v11.16b + ushr v6.4s, v20.4s, #25 + sli v6.4s, v20.4s, #7 + ext v6.16b, v6.16b, v6.16b, #12 + ext v11.16b, v11.16b, v11.16b, #8 + ext v16.16b, v16.16b, v16.16b, #4 + subs x6, x6, #1 + b.gt Lopen_tail_128_rounds + cbz x4, Lopen_tail_128_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b Lopen_tail_128_rounds + +Lopen_tail_128_rounds_done: + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v16.4s, v16.4s, v30.4s + add v15.4s, v15.4s, v22.4s + add v16.4s, v16.4s, v23.4s + + ld1 {v20.16b - v23.16b}, [x1], #64 + + eor v20.16b, v20.16b, v1.16b + eor v21.16b, v21.16b, v6.16b + eor v22.16b, v22.16b, v11.16b + eor v23.16b, v23.16b, v16.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + sub x2, x2, #64 + + b Lopen_tail_64_store + +Lopen_tail_64: + // We just need a single block + mov v0.16b, v24.16b + mov v5.16b, v28.16b + mov v10.16b, v29.16b + mov v15.16b, v30.16b + eor v23.16b, v23.16b, v23.16b + ins v23.s[0], v25.s[0] + add v15.4s, v15.4s, v23.4s + + mov x6, #10 + sub x6, x6, x4 + +Lopen_tail_64_rounds: + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #4 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #12 + add v0.4s, v0.4s, v5.4s + eor v15.16b, v15.16b, v0.16b + rev32 v15.8h, v15.8h + + add v10.4s, v10.4s, v15.4s + eor v5.16b, v5.16b, v10.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + add v0.4s, v0.4s, v20.4s + eor v15.16b, v15.16b, v0.16b + tbl v15.16b, {v15.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + eor v20.16b, v20.16b, v10.16b + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + ext v5.16b, v5.16b, v5.16b, #12 + ext v10.16b, v10.16b, v10.16b, #8 + ext v15.16b, v15.16b, v15.16b, #4 + subs x6, x6, #1 + b.gt Lopen_tail_64_rounds + cbz x4, Lopen_tail_64_rounds_done + subs x4, x4, #1 + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + b Lopen_tail_64_rounds + +Lopen_tail_64_rounds_done: + add v0.4s, v0.4s, v24.4s + add v5.4s, v5.4s, v28.4s + add v10.4s, v10.4s, v29.4s + add v15.4s, v15.4s, v30.4s + add v15.4s, v15.4s, v23.4s + +Lopen_tail_64_store: + cmp x2, #16 + b.lt Lopen_tail_16 + + ld1 {v20.16b}, [x1], #16 + eor v20.16b, v20.16b, v0.16b + st1 {v20.16b}, [x0], #16 + mov v0.16b, v5.16b + mov v5.16b, v10.16b + mov v10.16b, v15.16b + sub x2, x2, #16 + b Lopen_tail_64_store + +Lopen_tail_16: + // Here we handle the last [0,16) bytes that require a padded block + cbz x2, Lopen_finalize + + eor v20.16b, v20.16b, v20.16b // Use T0 to load the ciphertext + eor v21.16b, v21.16b, v21.16b // Use T1 to generate an AND mask + not v22.16b, v20.16b + + add x7, x1, x2 + mov x6, x2 + +Lopen_tail_16_compose: + ext v20.16b, v20.16b, v20.16b, #15 + ldrb w11, [x7, #-1]! + mov v20.b[0], w11 + ext v21.16b, v22.16b, v21.16b, #15 + subs x2, x2, #1 + b.gt Lopen_tail_16_compose + + and v20.16b, v20.16b, v21.16b + // Hash in the final padded block + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + eor v20.16b, v20.16b, v0.16b + +Lopen_tail_16_store: + umov w11, v20.b[0] + strb w11, [x0], #1 + ext v20.16b, v20.16b, v20.16b, #1 + subs x6, x6, #1 + b.gt Lopen_tail_16_store + +Lopen_finalize: + mov x11, v31.d[0] + mov x12, v31.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + // Final reduction step + sub x12, xzr, x15 + orr x13, xzr, #3 + subs x11, x8, #-5 + sbcs x12, x9, x12 + sbcs x13, x10, x13 + csel x8, x11, x8, cs + csel x9, x12, x9, cs + csel x10, x13, x10, cs + mov x11, v27.d[0] + mov x12, v27.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + + stp x8, x9, [x5] + + ldp d8, d9, [sp, #16] + ldp d10, d11, [sp, #32] + ldp d12, d13, [sp, #48] + ldp d14, d15, [sp, #64] +.cfi_restore b15 +.cfi_restore b14 +.cfi_restore b13 +.cfi_restore b12 +.cfi_restore b11 +.cfi_restore b10 +.cfi_restore b9 +.cfi_restore b8 + ldp x29, x30, [sp], 80 +.cfi_restore w29 +.cfi_restore w30 +.cfi_def_cfa_offset 0 + AARCH64_VALIDATE_LINK_REGISTER + ret + +Lopen_128: + // On some architectures preparing 5 blocks for small buffers is wasteful + eor v25.16b, v25.16b, v25.16b + mov x11, #1 + mov v25.s[0], w11 + mov v0.16b, v24.16b + mov v1.16b, v24.16b + mov v2.16b, v24.16b + mov v5.16b, v28.16b + mov v6.16b, v28.16b + mov v7.16b, v28.16b + mov v10.16b, v29.16b + mov v11.16b, v29.16b + mov v12.16b, v29.16b + mov v17.16b, v30.16b + add v15.4s, v17.4s, v25.4s + add v16.4s, v15.4s, v25.4s + + mov x6, #10 + +Lopen_128_rounds: + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #4 + ext v6.16b, v6.16b, v6.16b, #4 + ext v7.16b, v7.16b, v7.16b, #4 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #12 + ext v16.16b, v16.16b, v16.16b, #12 + ext v17.16b, v17.16b, v17.16b, #12 + add v0.4s, v0.4s, v5.4s + add v1.4s, v1.4s, v6.4s + add v2.4s, v2.4s, v7.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + rev32 v15.8h, v15.8h + rev32 v16.8h, v16.8h + rev32 v17.8h, v17.8h + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v5.16b, v5.16b, v10.16b + eor v6.16b, v6.16b, v11.16b + eor v7.16b, v7.16b, v12.16b + ushr v20.4s, v5.4s, #20 + sli v20.4s, v5.4s, #12 + ushr v5.4s, v6.4s, #20 + sli v5.4s, v6.4s, #12 + ushr v6.4s, v7.4s, #20 + sli v6.4s, v7.4s, #12 + + add v0.4s, v0.4s, v20.4s + add v1.4s, v1.4s, v5.4s + add v2.4s, v2.4s, v6.4s + eor v15.16b, v15.16b, v0.16b + eor v16.16b, v16.16b, v1.16b + eor v17.16b, v17.16b, v2.16b + tbl v15.16b, {v15.16b}, v26.16b + tbl v16.16b, {v16.16b}, v26.16b + tbl v17.16b, {v17.16b}, v26.16b + + add v10.4s, v10.4s, v15.4s + add v11.4s, v11.4s, v16.4s + add v12.4s, v12.4s, v17.4s + eor v20.16b, v20.16b, v10.16b + eor v5.16b, v5.16b, v11.16b + eor v6.16b, v6.16b, v12.16b + ushr v7.4s, v6.4s, #25 + sli v7.4s, v6.4s, #7 + ushr v6.4s, v5.4s, #25 + sli v6.4s, v5.4s, #7 + ushr v5.4s, v20.4s, #25 + sli v5.4s, v20.4s, #7 + + ext v5.16b, v5.16b, v5.16b, #12 + ext v6.16b, v6.16b, v6.16b, #12 + ext v7.16b, v7.16b, v7.16b, #12 + + ext v10.16b, v10.16b, v10.16b, #8 + ext v11.16b, v11.16b, v11.16b, #8 + ext v12.16b, v12.16b, v12.16b, #8 + + ext v15.16b, v15.16b, v15.16b, #4 + ext v16.16b, v16.16b, v16.16b, #4 + ext v17.16b, v17.16b, v17.16b, #4 + subs x6, x6, #1 + b.hi Lopen_128_rounds + + add v0.4s, v0.4s, v24.4s + add v1.4s, v1.4s, v24.4s + add v2.4s, v2.4s, v24.4s + + add v5.4s, v5.4s, v28.4s + add v6.4s, v6.4s, v28.4s + add v7.4s, v7.4s, v28.4s + + add v10.4s, v10.4s, v29.4s + add v11.4s, v11.4s, v29.4s + + add v30.4s, v30.4s, v25.4s + add v15.4s, v15.4s, v30.4s + add v30.4s, v30.4s, v25.4s + add v16.4s, v16.4s, v30.4s + + and v2.16b, v2.16b, v27.16b + mov x16, v2.d[0] // Move the R key to GPRs + mov x17, v2.d[1] + mov v27.16b, v7.16b // Store the S key + + bl Lpoly_hash_ad_internal + +Lopen_128_store: + cmp x2, #64 + b.lt Lopen_128_store_64 + + ld1 {v20.16b - v23.16b}, [x1], #64 + + mov x11, v20.d[0] + mov x12, v20.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v21.d[0] + mov x12, v21.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v22.d[0] + mov x12, v22.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + mov x11, v23.d[0] + mov x12, v23.d[1] + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + + eor v20.16b, v20.16b, v0.16b + eor v21.16b, v21.16b, v5.16b + eor v22.16b, v22.16b, v10.16b + eor v23.16b, v23.16b, v15.16b + + st1 {v20.16b - v23.16b}, [x0], #64 + + sub x2, x2, #64 + + mov v0.16b, v1.16b + mov v5.16b, v6.16b + mov v10.16b, v11.16b + mov v15.16b, v16.16b + +Lopen_128_store_64: + + lsr x4, x2, #4 + mov x3, x1 + +Lopen_128_hash_64: + cbz x4, Lopen_tail_64_store + ldp x11, x12, [x3], 16 + adds x8, x8, x11 + adcs x9, x9, x12 + adc x10, x10, x15 + mul x11, x8, x16 // [t2:t1:t0] = [acc2:acc1:acc0] * r0 + umulh x12, x8, x16 + mul x13, x9, x16 + umulh x14, x9, x16 + adds x12, x12, x13 + mul x13, x10, x16 + adc x13, x13, x14 + mul x14, x8, x17 // [t3:t2:t1:t0] = [acc2:acc1:acc0] * [r1:r0] + umulh x8, x8, x17 + adds x12, x12, x14 + mul x14, x9, x17 + umulh x9, x9, x17 + adcs x14, x14, x8 + mul x10, x10, x17 + adc x10, x10, x9 + adds x13, x13, x14 + adc x14, x10, xzr + and x10, x13, #3 // At this point acc2 is 2 bits at most (value of 3) + and x8, x13, #-4 + extr x13, x14, x13, #2 + adds x8, x8, x11 + lsr x11, x14, #2 + adc x9, x14, x11 // No carry out since t0 is 61 bits and t3 is 63 bits + adds x8, x8, x13 + adcs x9, x9, x12 + adc x10, x10, xzr // At this point acc2 has the value of 4 at most + sub x4, x4, #1 + b Lopen_128_hash_64 +.cfi_endproc + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armx64.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armv8-win.S similarity index 98% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armx64.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armv8-win.S index 9a633fbd..5afdfaba 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armx64.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -647,7 +646,7 @@ aes_hw_ctr32_encrypt_blocks: // // [0] ARM-EPM-049219 v23 Cortex-A57 MPCore Software Developers Errata Notice // [1] ARM-EPM-012079 v11.0 Cortex-A72 MPCore Software Developers Errata Notice -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8, w8 #endif add w10, w8, #1 @@ -809,5 +808,8 @@ Lctr32_done: ret #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-win.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-win.S new file mode 100644 index 00000000..0168554e --- /dev/null +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/aesv8-gcm-armv8-win.S @@ -0,0 +1,1571 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include +#if __ARM_MAX_ARCH__ >= 8 + +.arch armv8-a+crypto +.text +.globl aes_gcm_enc_kernel + +.def aes_gcm_enc_kernel + .type 32 +.endef +.align 4 +aes_gcm_enc_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + add x4, x0, x1, lsr #3 // end_input_ptr + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + sub x5, x5, #1 // byte_len - 1 + ldr q18, [x8, #0] // load rk0 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + ldr q25, [x8, #112] // load rk7 + add x5, x5, x0 + lsr x12, x11, #32 + fmov d2, x10 // CTR block 2 + orr w11, w11, w11 + rev w12, w12 // rev_ctr32 + fmov d1, x10 // CTR block 1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + add w12, w12, #1 // increment rev_ctr32 + rev w9, w12 // CTR block 1 + fmov d3, x10 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 1 + add w12, w12, #1 // CTR block 1 + ldr q19, [x8, #16] // load rk1 + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + ldr q20, [x8, #32] // load rk2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + orr x9, x11, x9, lsl #32 // CTR block 3 + fmov v3.d[1], x9 // CTR block 3 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q21, [x8, #48] // load rk3 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q24, [x8, #96] // load rk6 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q23, [x8, #80] // load rk5 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q22, [x8, #64] // load rk4 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + ldr q29, [x8, #176] // load rk11 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + ldr q26, [x8, #128] // load rk8 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + add w12, w12, #1 // CTR block 3 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + ldr q27, [x8, #144] // load rk9 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + ldr q28, [x8, #160] // load rk10 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + b.lt Lenc_finish_first_blocks // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + b.eq Lenc_finish_first_blocks // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Lenc_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v2.16b, v31.16b // AES block 2 - round N-1 + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + aese v3.16b, v31.16b // AES block 3 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + b.ge Lenc_tail // handle tail + + ldp x19, x20, [x0, #16] // AES block 1 - load plaintext + rev w9, w12 // CTR block 4 + ldp x6, x7, [x0, #0] // AES block 0 - load plaintext + ldp x23, x24, [x0, #48] // AES block 3 - load plaintext + ldp x21, x22, [x0, #32] // AES block 2 - load plaintext + add x0, x0, #64 // AES input_ptr update + eor x19, x19, x13 // AES block 1 - round N low + eor x20, x20, x14 // AES block 1 - round N high + fmov d5, x19 // AES block 1 - mov low + eor x6, x6, x13 // AES block 0 - round N low + eor x7, x7, x14 // AES block 0 - round N high + eor x24, x24, x14 // AES block 3 - round N high + fmov d4, x6 // AES block 0 - mov low + cmp x0, x5 // check if we have <= 8 blocks + fmov v4.d[1], x7 // AES block 0 - mov high + eor x23, x23, x13 // AES block 3 - round N low + eor x21, x21, x13 // AES block 2 - round N low + fmov v5.d[1], x20 // AES block 1 - mov high + fmov d6, x21 // AES block 2 - mov low + add w12, w12, #1 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov d7, x23 // AES block 3 - mov low + eor x22, x22, x14 // AES block 2 - round N high + fmov v6.d[1], x22 // AES block 2 - mov high + eor v4.16b, v4.16b, v0.16b // AES block 0 - result + fmov d0, x10 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + eor v5.16b, v5.16b, v1.16b // AES block 1 - result + fmov d1, x10 // CTR block 5 + orr x9, x11, x9, lsl #32 // CTR block 5 + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + st1 { v4.16b}, [x2], #16 // AES block 0 - store result + fmov v7.d[1], x24 // AES block 3 - mov high + orr x9, x11, x9, lsl #32 // CTR block 6 + eor v6.16b, v6.16b, v2.16b // AES block 2 - result + st1 { v5.16b}, [x2], #16 // AES block 1 - store result + add w12, w12, #1 // CTR block 6 + fmov d2, x10 // CTR block 6 + fmov v2.d[1], x9 // CTR block 6 + st1 { v6.16b}, [x2], #16 // AES block 2 - store result + rev w9, w12 // CTR block 7 + orr x9, x11, x9, lsl #32 // CTR block 7 + eor v7.16b, v7.16b, v3.16b // AES block 3 - result + st1 { v7.16b}, [x2], #16 // AES block 3 - store result + b.ge Lenc_prepretail // do prepretail + +Lenc_main_loop: // main loop start + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + fmov v3.d[1], x9 // CTR block 4k+3 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + ldp x23, x24, [x0, #48] // AES block 4k+7 - load plaintext + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + ldp x21, x22, [x0, #32] // AES block 4k+6 - load plaintext + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + eor v4.16b, v4.16b, v11.16b // PRE 1 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x23, x23, x13 // AES block 4k+7 - round N low + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d10, v17.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + eor x22, x22, x14 // AES block 4k+6 - round N high + mov d8, v4.d[1] // GHASH block 4k - mid + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + ldp x19, x20, [x0, #16] // AES block 4k+5 - load plaintext + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor x19, x19, x13 // AES block 4k+5 - round N low + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + eor x21, x21, x13 // AES block 4k+6 - round N low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + movi v8.8b, #0xc2 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + fmov d5, x19 // AES block 4k+5 - mov low + ldp x6, x7, [x0, #0] // AES block 4k+4 - load plaintext + b.lt Lenc_main_loop_continue // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Lenc_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Lenc_main_loop_continue: + shl d8, d8, #56 // mod_constant + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + add w12, w12, #1 // CTR block 4k+3 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + add x0, x0, #64 // AES input_ptr update + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + rev w9, w12 // CTR block 4k+8 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor x6, x6, x13 // AES block 4k+4 - round N low + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + eor x7, x7, x14 // AES block 4k+4 - round N high + fmov d4, x6 // AES block 4k+4 - mov low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v7.16b, v9.16b, v7.16b // MODULO - fold into mid + eor x20, x20, x14 // AES block 4k+5 - round N high + eor x24, x24, x14 // AES block 4k+7 - round N high + add w12, w12, #1 // CTR block 4k+8 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + fmov d7, x23 // AES block 4k+7 - mov low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + fmov v5.d[1], x20 // AES block 4k+5 - mov high + fmov d6, x21 // AES block 4k+6 - mov low + cmp x0, x5 // LOOP CONTROL + fmov v6.d[1], x22 // AES block 4k+6 - mov high + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v4.16b, v4.16b, v0.16b // AES block 4k+4 - result + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + rev w9, w12 // CTR block 4k+9 + add w12, w12, #1 // CTR block 4k+9 + eor v5.16b, v5.16b, v1.16b // AES block 4k+5 - result + fmov d1, x10 // CTR block 4k+9 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + fmov v1.d[1], x9 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + rev w9, w12 // CTR block 4k+10 + st1 { v4.16b}, [x2], #16 // AES block 4k+4 - store result + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + fmov v7.d[1], x24 // AES block 4k+7 - mov high + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + st1 { v5.16b}, [x2], #16 // AES block 4k+5 - store result + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + eor v6.16b, v6.16b, v2.16b // AES block 4k+6 - result + fmov d2, x10 // CTR block 4k+10 + st1 { v6.16b}, [x2], #16 // AES block 4k+6 - store result + fmov v2.d[1], x9 // CTR block 4k+10 + rev w9, w12 // CTR block 4k+11 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + orr x9, x11, x9, lsl #32 // CTR block 4k+11 + eor v7.16b, v7.16b, v3.16b // AES block 4k+7 - result + st1 { v7.16b}, [x2], #16 // AES block 4k+7 - store result + b.lt Lenc_main_loop + +Lenc_prepretail: // PREPRETAIL + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + rev64 v6.16b, v6.16b // GHASH block 4k+2 (t0, t1, and t2 free) + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov d3, x10 // CTR block 4k+3 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + rev64 v4.16b, v4.16b // GHASH block 4k (only t0 is free) + fmov v3.d[1], x9 // CTR block 4k+3 + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v5.16b, v5.16b // GHASH block 4k+1 (t0 and t1 free) + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + rev64 v7.16b, v7.16b // GHASH block 4k+3 (t0, t1, t2 and t3 free) + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + add w12, w12, #1 // CTR block 4k+3 + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + mov d4, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + eor v4.8b, v4.8b, v7.8b // GHASH block 4k+3 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + pmull v4.1q, v4.1d, v16.1d // GHASH block 4k+3 - mid + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+3 - mid + pmull v6.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v11.16b, v11.16b, v6.16b // GHASH block 4k+3 - low + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v10.16b, v10.16b, v9.16b // karatsuba tidy up + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + pmull v4.1q, v9.1d, v8.1d + ext v9.16b, v9.16b, v9.16b, #8 + eor v10.16b, v10.16b, v11.16b + b.lt Lenc_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + b.eq Lenc_finish_prepretail // branch if AES-192 + + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + +Lenc_finish_prepretail: + eor v10.16b, v10.16b, v4.16b + eor v10.16b, v10.16b, v9.16b + pmull v4.1q, v10.1d, v8.1d + ext v10.16b, v10.16b, v10.16b, #8 + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + eor v11.16b, v11.16b, v4.16b + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b + +Lenc_tail: // TAIL + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ldp x6, x7, [x0], #16 // AES block 4k+4 - load plaintext + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + cmp x5, #48 + fmov d4, x6 // AES block 4k+4 - mov low + fmov v4.d[1], x7 // AES block 4k+4 - mov high + eor v5.16b, v4.16b, v0.16b // AES block 4k+4 - result + b.gt Lenc_blocks_more_than_3 + cmp x5, #32 + mov v3.16b, v2.16b + movi v11.8b, #0 + movi v9.8b, #0 + sub w12, w12, #1 + mov v2.16b, v1.16b + movi v10.8b, #0 + b.gt Lenc_blocks_more_than_2 + mov v3.16b, v1.16b + sub w12, w12, #1 + cmp x5, #16 + b.gt Lenc_blocks_more_than_1 + sub w12, w12, #1 + b Lenc_blocks_less_than_1 +Lenc_blocks_more_than_3: // blocks left > 3 + st1 { v5.16b}, [x2], #16 // AES final-3 block - store result + ldp x6, x7, [x0], #16 // AES final-2 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-3 block + eor x6, x6, x13 // AES final-2 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor x7, x7, x14 // AES final-2 block - round N high + mov d22, v4.d[1] // GHASH final-3 block - mid + fmov d5, x6 // AES final-2 block - mov low + fmov v5.d[1], x7 // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + mov d10, v17.d[1] // GHASH final-3 block - mid + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor v5.16b, v5.16b, v1.16b // AES final-2 block - result +Lenc_blocks_more_than_2: // blocks left > 2 + st1 { v5.16b}, [x2], #16 // AES final-2 block - store result + ldp x6, x7, [x0], #16 // AES final-1 block - load input low & high + rev64 v4.16b, v5.16b // GHASH final-2 block + eor x6, x6, x13 // AES final-1 block - round N low + eor v4.16b, v4.16b, v8.16b // feed in partial tag + fmov d5, x6 // AES final-1 block - mov low + eor x7, x7, x14 // AES final-1 block - round N high + fmov v5.d[1], x7 // AES final-1 block - mov high + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + eor v5.16b, v5.16b, v2.16b // AES final-1 block - result + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid +Lenc_blocks_more_than_1: // blocks left > 1 + st1 { v5.16b}, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ldp x6, x7, [x0], #16 // AES final block - load input low & high + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + eor x6, x6, x13 // AES final block - round N low + mov d22, v4.d[1] // GHASH final-1 block - mid + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor x7, x7, x14 // AES final block - round N high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + fmov d5, x6 // AES final block - mov low + fmov v5.d[1], x7 // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + eor v5.16b, v5.16b, v3.16b // AES final block - result + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low +Lenc_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + ld1 { v18.16b}, [x2] // load existing bytes where the possibly partial last block is to be stored + mvn x14, xzr // rkN_h = 0xffffffffffffffff + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x6, x13, x14, lt + csel x7, x14, xzr, lt + fmov d0, x6 // ctr0b is mask for last block + fmov v0.d[1], x7 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + bif v5.16b, v18.16b, v0.16b // insert existing bytes in top end of result before storing + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + mov d8, v4.d[1] // GHASH final block - mid + rev w9, w12 + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v4.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v4.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v9.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + str w9, [x16, #12] // store the updated counter + st1 { v5.16b}, [x2] // store all 16B + eor v11.16b, v11.16b, v9.16b // MODULO - fold into low + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl aes_gcm_dec_kernel + +.def aes_gcm_dec_kernel + .type 32 +.endef +.align 4 +aes_gcm_dec_kernel: + AARCH64_SIGN_LINK_REGISTER + stp x29, x30, [sp, #-128]! + mov x29, sp + stp x19, x20, [sp, #16] + mov x16, x4 + mov x8, x5 + stp x21, x22, [sp, #32] + stp x23, x24, [sp, #48] + stp d8, d9, [sp, #64] + stp d10, d11, [sp, #80] + stp d12, d13, [sp, #96] + stp d14, d15, [sp, #112] + ldr w17, [x8, #240] + add x19, x8, x17, lsl #4 // borrow input_l1 for last key + ldp x13, x14, [x19] // load round N keys + ldr q31, [x19, #-16] // load round N-1 keys + lsr x5, x1, #3 // byte_len + mov x15, x5 + ldp x10, x11, [x16] // ctr96_b64, ctr96_t32 + ldr q26, [x8, #128] // load rk8 + sub x5, x5, #1 // byte_len - 1 + ldr q25, [x8, #112] // load rk7 + and x5, x5, #0xffffffffffffffc0 // number of bytes to be processed in main loop (at least 1 byte must be handled by tail) + add x4, x0, x1, lsr #3 // end_input_ptr + ldr q24, [x8, #96] // load rk6 + lsr x12, x11, #32 + ldr q23, [x8, #80] // load rk5 + orr w11, w11, w11 + ldr q21, [x8, #48] // load rk3 + add x5, x5, x0 + rev w12, w12 // rev_ctr32 + add w12, w12, #1 // increment rev_ctr32 + fmov d3, x10 // CTR block 3 + rev w9, w12 // CTR block 1 + add w12, w12, #1 // CTR block 1 + fmov d1, x10 // CTR block 1 + orr x9, x11, x9, lsl #32 // CTR block 1 + ld1 { v0.16b}, [x16] // special case vector load initial counter so we can start first AES block as quickly as possible + fmov v1.d[1], x9 // CTR block 1 + rev w9, w12 // CTR block 2 + add w12, w12, #1 // CTR block 2 + fmov d2, x10 // CTR block 2 + orr x9, x11, x9, lsl #32 // CTR block 2 + fmov v2.d[1], x9 // CTR block 2 + rev w9, w12 // CTR block 3 + orr x9, x11, x9, lsl #32 // CTR block 3 + ldr q18, [x8, #0] // load rk0 + fmov v3.d[1], x9 // CTR block 3 + add w12, w12, #1 // CTR block 3 + ldr q22, [x8, #64] // load rk4 + ldr q19, [x8, #16] // load rk1 + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 0 - round 0 + ldr q14, [x6, #48] // load h3l | h3h + ext v14.16b, v14.16b, v14.16b, #8 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 3 - round 0 + ldr q15, [x6, #80] // load h4l | h4h + ext v15.16b, v15.16b, v15.16b, #8 + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 1 - round 0 + ldr q13, [x6, #32] // load h2l | h2h + ext v13.16b, v13.16b, v13.16b, #8 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 2 - round 0 + ldr q20, [x8, #32] // load rk2 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 0 - round 1 + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 1 - round 1 + ld1 { v11.16b}, [x3] + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 2 - round 1 + ldr q27, [x8, #144] // load rk9 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 3 - round 1 + ldr q30, [x8, #192] // load rk12 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 0 - round 2 + ldr q12, [x6] // load h1l | h1h + ext v12.16b, v12.16b, v12.16b, #8 + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 2 - round 2 + ldr q28, [x8, #160] // load rk10 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 3 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 0 - round 3 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 1 - round 2 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 3 - round 3 + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 0 - round 4 + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 2 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 1 - round 3 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 3 - round 4 + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 2 - round 4 + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 1 - round 4 + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 3 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 0 - round 5 + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 1 - round 5 + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 2 - round 5 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 0 - round 6 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 3 - round 6 + cmp x17, #12 // setup flags for AES-128/192/256 check + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 1 - round 6 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 2 - round 6 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 0 - round 7 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 1 - round 7 + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 3 - round 7 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 0 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 2 - round 7 + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 3 - round 8 + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 1 - round 8 + ldr q29, [x8, #176] // load rk11 + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 2 - round 8 + b.lt Ldec_finish_first_blocks // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 0 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 1 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 3 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 2 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 0 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 1 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 3 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 2 - round 10 + b.eq Ldec_finish_first_blocks // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 0 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 3 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 1 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 2 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 1 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 0 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 2 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 3 - round 12 + +Ldec_finish_first_blocks: + cmp x0, x5 // check if we have <= 4 blocks + trn1 v9.2d, v14.2d, v15.2d // h4h | h3h + trn2 v17.2d, v14.2d, v15.2d // h4l | h3l + trn1 v8.2d, v12.2d, v13.2d // h2h | h1h + trn2 v16.2d, v12.2d, v13.2d // h2l | h1l + eor v17.16b, v17.16b, v9.16b // h4k | h3k + aese v1.16b, v31.16b // AES block 1 - round N-1 + aese v2.16b, v31.16b // AES block 2 - round N-1 + eor v16.16b, v16.16b, v8.16b // h2k | h1k + aese v3.16b, v31.16b // AES block 3 - round N-1 + aese v0.16b, v31.16b // AES block 0 - round N-1 + b.ge Ldec_tail // handle tail + + ldr q4, [x0, #0] // AES block 0 - load ciphertext + ldr q5, [x0, #16] // AES block 1 - load ciphertext + rev w9, w12 // CTR block 4 + eor v0.16b, v4.16b, v0.16b // AES block 0 - result + eor v1.16b, v5.16b, v1.16b // AES block 1 - result + rev64 v5.16b, v5.16b // GHASH block 1 + ldr q7, [x0, #48] // AES block 3 - load ciphertext + mov x7, v0.d[1] // AES block 0 - mov high + mov x6, v0.d[0] // AES block 0 - mov low + rev64 v4.16b, v4.16b // GHASH block 0 + add w12, w12, #1 // CTR block 4 + fmov d0, x10 // CTR block 4 + orr x9, x11, x9, lsl #32 // CTR block 4 + fmov v0.d[1], x9 // CTR block 4 + rev w9, w12 // CTR block 5 + add w12, w12, #1 // CTR block 5 + mov x19, v1.d[0] // AES block 1 - mov low + orr x9, x11, x9, lsl #32 // CTR block 5 + mov x20, v1.d[1] // AES block 1 - mov high + eor x7, x7, x14 // AES block 0 - round N high + eor x6, x6, x13 // AES block 0 - round N low + stp x6, x7, [x2], #16 // AES block 0 - store result + fmov d1, x10 // CTR block 5 + ldr q6, [x0, #32] // AES block 2 - load ciphertext + add x0, x0, #64 // AES input_ptr update + fmov v1.d[1], x9 // CTR block 5 + rev w9, w12 // CTR block 6 + add w12, w12, #1 // CTR block 6 + eor x19, x19, x13 // AES block 1 - round N low + orr x9, x11, x9, lsl #32 // CTR block 6 + eor x20, x20, x14 // AES block 1 - round N high + stp x19, x20, [x2], #16 // AES block 1 - store result + eor v2.16b, v6.16b, v2.16b // AES block 2 - result + cmp x0, x5 // check if we have <= 8 blocks + b.ge Ldec_prepretail // do prepretail + +Ldec_main_loop: // main loop start + mov x21, v2.d[0] // AES block 4k+2 - mov low + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev w9, w12 // CTR block 4k+7 + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x23, v3.d[0] // AES block 4k+3 - mov low + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + fmov v3.d[1], x9 // CTR block 4k+7 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + eor x22, x22, x14 // AES block 4k+2 - round N high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + eor x21, x21, x13 // AES block 4k+2 - round N low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor x23, x23, x13 // AES block 4k+3 - round N low + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + eor x24, x24, x14 // AES block 4k+3 - round N high + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + add w12, w12, #1 // CTR block 4k+7 + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + rev w9, w12 // CTR block 4k+8 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + add w12, w12, #1 // CTR block 4k+8 + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + orr x9, x11, x9, lsl #32 // CTR block 4k+8 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + movi v8.8b, #0xc2 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + b.lt Ldec_main_loop_continue // branch if AES-128 + + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + b.eq Ldec_main_loop_continue // branch if AES-192 + + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_main_loop_continue: + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + ldr q4, [x0, #0] // AES block 4k+4 - load ciphertext + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + ldr q5, [x0, #16] // AES block 4k+5 - load ciphertext + eor v0.16b, v4.16b, v0.16b // AES block 4k+4 - result + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + ldr q7, [x0, #48] // AES block 4k+7 - load ciphertext + ldr q6, [x0, #32] // AES block 4k+6 - load ciphertext + mov x7, v0.d[1] // AES block 4k+4 - mov high + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + add x0, x0, #64 // AES input_ptr update + mov x6, v0.d[0] // AES block 4k+4 - mov low + fmov d0, x10 // CTR block 4k+8 + fmov v0.d[1], x9 // CTR block 4k+8 + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor v1.16b, v5.16b, v1.16b // AES block 4k+5 - result + rev w9, w12 // CTR block 4k+9 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+9 + cmp x0, x5 // LOOP CONTROL + add w12, w12, #1 // CTR block 4k+9 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + mov x20, v1.d[1] // AES block 4k+5 - mov high + eor v2.16b, v6.16b, v2.16b // AES block 4k+6 - result + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + mov x19, v1.d[0] // AES block 4k+5 - mov low + fmov d1, x10 // CTR block 4k+9 + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + fmov v1.d[1], x9 // CTR block 4k+9 + rev w9, w12 // CTR block 4k+10 + add w12, w12, #1 // CTR block 4k+10 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + orr x9, x11, x9, lsl #32 // CTR block 4k+10 + rev64 v5.16b, v5.16b // GHASH block 4k+5 + eor x20, x20, x14 // AES block 4k+5 - round N high + stp x6, x7, [x2], #16 // AES block 4k+4 - store result + eor x19, x19, x13 // AES block 4k+5 - round N low + stp x19, x20, [x2], #16 // AES block 4k+5 - store result + rev64 v4.16b, v4.16b // GHASH block 4k+4 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + b.lt Ldec_main_loop + +Ldec_prepretail: // PREPRETAIL + ext v11.16b, v11.16b, v11.16b, #8 // PRE 0 + mov x21, v2.d[0] // AES block 4k+2 - mov low + eor v3.16b, v7.16b, v3.16b // AES block 4k+3 - result + aese v0.16b, v18.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 0 + mov x22, v2.d[1] // AES block 4k+2 - mov high + aese v1.16b, v18.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 0 + fmov d2, x10 // CTR block 4k+6 + fmov v2.d[1], x9 // CTR block 4k+6 + rev w9, w12 // CTR block 4k+7 + eor v4.16b, v4.16b, v11.16b // PRE 1 + rev64 v6.16b, v6.16b // GHASH block 4k+2 + orr x9, x11, x9, lsl #32 // CTR block 4k+7 + mov x23, v3.d[0] // AES block 4k+3 - mov low + aese v1.16b, v19.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 1 + mov x24, v3.d[1] // AES block 4k+3 - mov high + pmull v11.1q, v4.1d, v15.1d // GHASH block 4k - low + mov d8, v4.d[1] // GHASH block 4k - mid + fmov d3, x10 // CTR block 4k+7 + pmull2 v9.1q, v4.2d, v15.2d // GHASH block 4k - high + fmov v3.d[1], x9 // CTR block 4k+7 + aese v2.16b, v18.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 0 + mov d10, v17.d[1] // GHASH block 4k - mid + aese v0.16b, v19.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 1 + eor v8.8b, v8.8b, v4.8b // GHASH block 4k - mid + pmull2 v4.1q, v5.2d, v14.2d // GHASH block 4k+1 - high + aese v2.16b, v19.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 1 + rev64 v7.16b, v7.16b // GHASH block 4k+3 + aese v3.16b, v18.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 0 + pmull v10.1q, v8.1d, v10.1d // GHASH block 4k - mid + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+1 - high + pmull v8.1q, v5.1d, v14.1d // GHASH block 4k+1 - low + aese v3.16b, v19.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 1 + mov d4, v5.d[1] // GHASH block 4k+1 - mid + aese v0.16b, v20.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 2 + aese v1.16b, v20.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 2 + eor v11.16b, v11.16b, v8.16b // GHASH block 4k+1 - low + aese v2.16b, v20.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 2 + aese v0.16b, v21.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 3 + mov d8, v6.d[1] // GHASH block 4k+2 - mid + aese v3.16b, v20.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 2 + eor v4.8b, v4.8b, v5.8b // GHASH block 4k+1 - mid + pmull v5.1q, v6.1d, v13.1d // GHASH block 4k+2 - low + aese v0.16b, v22.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 4 + aese v3.16b, v21.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 3 + eor v8.8b, v8.8b, v6.8b // GHASH block 4k+2 - mid + pmull v4.1q, v4.1d, v17.1d // GHASH block 4k+1 - mid + aese v0.16b, v23.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 5 + eor v11.16b, v11.16b, v5.16b // GHASH block 4k+2 - low + aese v3.16b, v22.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 4 + pmull2 v5.1q, v7.2d, v12.2d // GHASH block 4k+3 - high + eor v10.16b, v10.16b, v4.16b // GHASH block 4k+1 - mid + pmull2 v4.1q, v6.2d, v13.2d // GHASH block 4k+2 - high + aese v3.16b, v23.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 5 + ins v8.d[1], v8.d[0] // GHASH block 4k+2 - mid + aese v2.16b, v21.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 3 + aese v1.16b, v21.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 3 + eor v9.16b, v9.16b, v4.16b // GHASH block 4k+2 - high + pmull v4.1q, v7.1d, v12.1d // GHASH block 4k+3 - low + aese v2.16b, v22.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 4 + mov d6, v7.d[1] // GHASH block 4k+3 - mid + aese v1.16b, v22.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 4 + pmull2 v8.1q, v8.2d, v16.2d // GHASH block 4k+2 - mid + aese v2.16b, v23.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 5 + eor v6.8b, v6.8b, v7.8b // GHASH block 4k+3 - mid + aese v1.16b, v23.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 5 + aese v3.16b, v24.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 6 + eor v10.16b, v10.16b, v8.16b // GHASH block 4k+2 - mid + aese v2.16b, v24.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 6 + aese v0.16b, v24.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 6 + movi v8.8b, #0xc2 + aese v1.16b, v24.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 6 + eor v11.16b, v11.16b, v4.16b // GHASH block 4k+3 - low + pmull v6.1q, v6.1d, v16.1d // GHASH block 4k+3 - mid + aese v3.16b, v25.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 7 + cmp x17, #12 // setup flags for AES-128/192/256 check + eor v9.16b, v9.16b, v5.16b // GHASH block 4k+3 - high + aese v1.16b, v25.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 7 + aese v0.16b, v25.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 7 + eor v10.16b, v10.16b, v6.16b // GHASH block 4k+3 - mid + aese v3.16b, v26.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 8 + aese v2.16b, v25.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 7 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + aese v1.16b, v26.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 8 + aese v0.16b, v26.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 8 + shl d8, d8, #56 // mod_constant + aese v2.16b, v26.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 8 + b.lt Ldec_finish_prepretail // branch if AES-128 + + aese v1.16b, v27.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 9 + aese v2.16b, v27.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 9 + aese v3.16b, v27.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 9 + aese v0.16b, v27.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 9 + aese v2.16b, v28.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 10 + aese v3.16b, v28.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 10 + aese v0.16b, v28.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 10 + aese v1.16b, v28.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 10 + b.eq Ldec_finish_prepretail // branch if AES-192 + + aese v2.16b, v29.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 11 + aese v0.16b, v29.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 11 + aese v1.16b, v29.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 11 + aese v2.16b, v30.16b + aesmc v2.16b, v2.16b // AES block 4k+6 - round 12 + aese v3.16b, v29.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 11 + aese v1.16b, v30.16b + aesmc v1.16b, v1.16b // AES block 4k+5 - round 12 + aese v0.16b, v30.16b + aesmc v0.16b, v0.16b // AES block 4k+4 - round 12 + aese v3.16b, v30.16b + aesmc v3.16b, v3.16b // AES block 4k+7 - round 12 + +Ldec_finish_prepretail: + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor x22, x22, x14 // AES block 4k+2 - round N high + eor x23, x23, x13 // AES block 4k+3 - round N low + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + add w12, w12, #1 // CTR block 4k+7 + eor x21, x21, x13 // AES block 4k+2 - round N low + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + eor x24, x24, x14 // AES block 4k+3 - round N high + stp x21, x22, [x2], #16 // AES block 4k+2 - store result + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + stp x23, x24, [x2], #16 // AES block 4k+3 - store result + + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + aese v1.16b, v31.16b // AES block 4k+5 - round N-1 + aese v0.16b, v31.16b // AES block 4k+4 - round N-1 + aese v3.16b, v31.16b // AES block 4k+7 - round N-1 + aese v2.16b, v31.16b // AES block 4k+6 - round N-1 + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + +Ldec_tail: // TAIL + sub x5, x4, x0 // main_end_input_ptr is number of bytes left to process + ld1 { v5.16b}, [x0], #16 // AES block 4k+4 - load ciphertext + eor v0.16b, v5.16b, v0.16b // AES block 4k+4 - result + mov x6, v0.d[0] // AES block 4k+4 - mov low + mov x7, v0.d[1] // AES block 4k+4 - mov high + ext v8.16b, v11.16b, v11.16b, #8 // prepare final partial tag + cmp x5, #48 + eor x6, x6, x13 // AES block 4k+4 - round N low + eor x7, x7, x14 // AES block 4k+4 - round N high + b.gt Ldec_blocks_more_than_3 + sub w12, w12, #1 + mov v3.16b, v2.16b + movi v10.8b, #0 + movi v11.8b, #0 + cmp x5, #32 + movi v9.8b, #0 + mov v2.16b, v1.16b + b.gt Ldec_blocks_more_than_2 + sub w12, w12, #1 + mov v3.16b, v1.16b + cmp x5, #16 + b.gt Ldec_blocks_more_than_1 + sub w12, w12, #1 + b Ldec_blocks_less_than_1 +Ldec_blocks_more_than_3: // blocks left > 3 + rev64 v4.16b, v5.16b // GHASH final-3 block + ld1 { v5.16b}, [x0], #16 // AES final-2 block - load ciphertext + stp x6, x7, [x2], #16 // AES final-3 block - store result + mov d10, v17.d[1] // GHASH final-3 block - mid + eor v4.16b, v4.16b, v8.16b // feed in partial tag + eor v0.16b, v5.16b, v1.16b // AES final-2 block - result + mov d22, v4.d[1] // GHASH final-3 block - mid + mov x6, v0.d[0] // AES final-2 block - mov low + mov x7, v0.d[1] // AES final-2 block - mov high + eor v22.8b, v22.8b, v4.8b // GHASH final-3 block - mid + movi v8.8b, #0 // suppress further partial tag feed in + pmull2 v9.1q, v4.2d, v15.2d // GHASH final-3 block - high + pmull v10.1q, v22.1d, v10.1d // GHASH final-3 block - mid + eor x6, x6, x13 // AES final-2 block - round N low + pmull v11.1q, v4.1d, v15.1d // GHASH final-3 block - low + eor x7, x7, x14 // AES final-2 block - round N high +Ldec_blocks_more_than_2: // blocks left > 2 + rev64 v4.16b, v5.16b // GHASH final-2 block + ld1 { v5.16b}, [x0], #16 // AES final-1 block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + stp x6, x7, [x2], #16 // AES final-2 block - store result + eor v0.16b, v5.16b, v2.16b // AES final-1 block - result + mov d22, v4.d[1] // GHASH final-2 block - mid + pmull v21.1q, v4.1d, v14.1d // GHASH final-2 block - low + pmull2 v20.1q, v4.2d, v14.2d // GHASH final-2 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-2 block - mid + mov x6, v0.d[0] // AES final-1 block - mov low + mov x7, v0.d[1] // AES final-1 block - mov high + eor v11.16b, v11.16b, v21.16b // GHASH final-2 block - low + movi v8.8b, #0 // suppress further partial tag feed in + pmull v22.1q, v22.1d, v17.1d // GHASH final-2 block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final-2 block - high + eor x6, x6, x13 // AES final-1 block - round N low + eor v10.16b, v10.16b, v22.16b // GHASH final-2 block - mid + eor x7, x7, x14 // AES final-1 block - round N high +Ldec_blocks_more_than_1: // blocks left > 1 + stp x6, x7, [x2], #16 // AES final-1 block - store result + rev64 v4.16b, v5.16b // GHASH final-1 block + ld1 { v5.16b}, [x0], #16 // AES final block - load ciphertext + eor v4.16b, v4.16b, v8.16b // feed in partial tag + movi v8.8b, #0 // suppress further partial tag feed in + mov d22, v4.d[1] // GHASH final-1 block - mid + eor v0.16b, v5.16b, v3.16b // AES final block - result + pmull2 v20.1q, v4.2d, v13.2d // GHASH final-1 block - high + eor v22.8b, v22.8b, v4.8b // GHASH final-1 block - mid + pmull v21.1q, v4.1d, v13.1d // GHASH final-1 block - low + mov x6, v0.d[0] // AES final block - mov low + ins v22.d[1], v22.d[0] // GHASH final-1 block - mid + mov x7, v0.d[1] // AES final block - mov high + pmull2 v22.1q, v22.2d, v16.2d // GHASH final-1 block - mid + eor x6, x6, x13 // AES final block - round N low + eor v11.16b, v11.16b, v21.16b // GHASH final-1 block - low + eor v9.16b, v9.16b, v20.16b // GHASH final-1 block - high + eor v10.16b, v10.16b, v22.16b // GHASH final-1 block - mid + eor x7, x7, x14 // AES final block - round N high +Ldec_blocks_less_than_1: // blocks left <= 1 + and x1, x1, #127 // bit_length %= 128 + mvn x14, xzr // rkN_h = 0xffffffffffffffff + sub x1, x1, #128 // bit_length -= 128 + mvn x13, xzr // rkN_l = 0xffffffffffffffff + ldp x4, x5, [x2] // load existing bytes we need to not overwrite + neg x1, x1 // bit_length = 128 - #bits in input (in range [1,128]) + and x1, x1, #127 // bit_length %= 128 + lsr x14, x14, x1 // rkN_h is mask for top 64b of last block + cmp x1, #64 + csel x9, x13, x14, lt + csel x10, x14, xzr, lt + fmov d0, x9 // ctr0b is mask for last block + and x6, x6, x9 + mov v0.d[1], x10 + bic x4, x4, x9 // mask out low existing bytes + rev w9, w12 + bic x5, x5, x10 // mask out high existing bytes + orr x6, x6, x4 + and x7, x7, x10 + orr x7, x7, x5 + and v5.16b, v5.16b, v0.16b // possibly partial last block has zeroes in highest bits + rev64 v4.16b, v5.16b // GHASH final block + eor v4.16b, v4.16b, v8.16b // feed in partial tag + pmull v21.1q, v4.1d, v12.1d // GHASH final block - low + mov d8, v4.d[1] // GHASH final block - mid + eor v8.8b, v8.8b, v4.8b // GHASH final block - mid + pmull2 v20.1q, v4.2d, v12.2d // GHASH final block - high + pmull v8.1q, v8.1d, v16.1d // GHASH final block - mid + eor v9.16b, v9.16b, v20.16b // GHASH final block - high + eor v11.16b, v11.16b, v21.16b // GHASH final block - low + eor v10.16b, v10.16b, v8.16b // GHASH final block - mid + movi v8.8b, #0xc2 + eor v6.16b, v11.16b, v9.16b // MODULO - karatsuba tidy up + shl d8, d8, #56 // mod_constant + eor v10.16b, v10.16b, v6.16b // MODULO - karatsuba tidy up + pmull v7.1q, v9.1d, v8.1d // MODULO - top 64b align with mid + ext v9.16b, v9.16b, v9.16b, #8 // MODULO - other top alignment + eor v10.16b, v10.16b, v7.16b // MODULO - fold into mid + eor v10.16b, v10.16b, v9.16b // MODULO - fold into mid + pmull v8.1q, v10.1d, v8.1d // MODULO - mid 64b align with low + ext v10.16b, v10.16b, v10.16b, #8 // MODULO - other mid alignment + eor v11.16b, v11.16b, v8.16b // MODULO - fold into low + stp x6, x7, [x2] + str w9, [x16, #12] // store the updated counter + eor v11.16b, v11.16b, v10.16b // MODULO - fold into low + ext v11.16b, v11.16b, v11.16b, #8 + rev64 v11.16b, v11.16b + mov x0, x15 + st1 { v11.16b }, [x3] + ldp x19, x20, [sp, #16] + ldp x21, x22, [sp, #32] + ldp x23, x24, [sp, #48] + ldp d8, d9, [sp, #64] + ldp d10, d11, [sp, #80] + ldp d12, d13, [sp, #96] + ldp d14, d15, [sp, #112] + ldp x29, x30, [sp], #128 + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont-win.S similarity index 99% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont-win.S index e1bee282..9b4a9afc 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/armv8-mont-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1437,5 +1436,8 @@ Lmul4x_done: .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 4 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/bn-armv8-win.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/bn-armv8-win.S new file mode 100644 index 00000000..50a9ea92 --- /dev/null +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/bn-armv8-win.S @@ -0,0 +1,101 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include + +.text + +// BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl bn_add_words + +.align 4 +bn_add_words: + AARCH64_VALID_CALL_TARGET + # Clear the carry flag. + cmn xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Ladd_tail +Ladd_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + adcs x4, x4, x6 + adcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Ladd_loop + +Ladd_tail: + cbz x3, Ladd_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + adcs x4, x4, x6 + str x4, [x0], #8 + +Ladd_exit: + cset x0, cs + ret + + +// BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, +// size_t num); + +.globl bn_sub_words + +.align 4 +bn_sub_words: + AARCH64_VALID_CALL_TARGET + # Set the carry flag. Arm's borrow bit is flipped from the carry flag, + # so we want C = 1 here. + cmp xzr, xzr + + # aarch64 can load two registers at a time, so we do two loop iterations at + # at a time. Split x3 = 2 * x8 + x3. This allows loop + # operations to use CBNZ without clobbering the carry flag. + lsr x8, x3, #1 + and x3, x3, #1 + + cbz x8, Lsub_tail +Lsub_loop: + ldp x4, x5, [x1], #16 + ldp x6, x7, [x2], #16 + sub x8, x8, #1 + sbcs x4, x4, x6 + sbcs x5, x5, x7 + stp x4, x5, [x0], #16 + cbnz x8, Lsub_loop + +Lsub_tail: + cbz x3, Lsub_exit + ldr x4, [x1], #8 + ldr x6, [x2], #8 + sbcs x4, x4, x6 + str x4, [x0], #8 + +Lsub_exit: + cset x0, cc + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8-win.S similarity index 97% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8-win.S index 6881d091..bee5b0e1 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghash-neon-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -347,5 +346,8 @@ Lmasks: .byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,100,101,114,105,118,101,100,32,102,114,111,109,32,65,82,77,118,52,32,118,101,114,115,105,111,110,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armx64.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armv8-win.S similarity index 96% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armx64.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armv8-win.S index 7cba4da2..1c463b3b 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armx64.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/ghashv8-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -124,7 +123,7 @@ gcm_gmult_v8: movi v19.16b,#0xe1 ld1 {v20.2d,v21.2d},[x1] //load twisted H, ... shl v19.2d,v19.2d,#57 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v3.16b,v17.16b,v17.16b,#8 @@ -149,7 +148,7 @@ gcm_gmult_v8: eor v18.16b,v18.16b,v2.16b eor v0.16b,v0.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -190,14 +189,14 @@ gcm_ghash_v8: ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi ld1 {v16.2d},[x2],#16 //load [rotated] I[0] shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b rev64 v0.16b,v0.16b #endif ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] b.lo Lodd_tail_v8 //x3 was less than 32 ld1 {v17.2d},[x2],x12 //load [rotated] I[1] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ext v7.16b,v17.16b,v17.16b,#8 @@ -229,13 +228,13 @@ Loop_mod2x_v8: eor v18.16b,v0.16b,v2.16b eor v1.16b,v1.16b,v17.16b ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v16.16b,v16.16b #endif eor v1.16b,v1.16b,v18.16b pmull v18.1q,v0.1d,v19.1d //1st phase of reduction -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v17.16b,v17.16b #endif ins v2.d[0],v1.d[1] @@ -285,7 +284,7 @@ Lodd_tail_v8: eor v0.16b,v0.16b,v18.16b Ldone_v8: -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif ext v0.16b,v0.16b,v0.16b,#8 @@ -306,7 +305,7 @@ Lgcm_ghash_v8_4x: shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b @@ -350,7 +349,7 @@ Loop4x: eor v16.16b,v4.16b,v0.16b ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64 ext v3.16b,v16.16b,v16.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v7.16b,v7.16b @@ -433,7 +432,7 @@ Lthree: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d,v6.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v6.16b,v6.16b rev64 v4.16b,v4.16b @@ -485,7 +484,7 @@ Ltwo: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d,v5.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v5.16b,v5.16b rev64 v4.16b,v4.16b #endif @@ -528,7 +527,7 @@ Lone: eor v1.16b,v1.16b,v17.16b ld1 {v4.2d},[x2] eor v1.16b,v1.16b,v18.16b -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v4.16b,v4.16b #endif @@ -568,7 +567,7 @@ Ldone4x: eor v0.16b,v0.16b,v18.16b ext v0.16b,v0.16b,v0.16b,#8 -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev64 v0.16b,v0.16b #endif st1 {v0.2d},[x0] //write out Xi @@ -579,5 +578,8 @@ Ldone4x: .align 2 .align 2 #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256-armv8-asm-win.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256-armv8-asm-win.S new file mode 100644 index 00000000..4d9e9702 --- /dev/null +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256-armv8-asm-win.S @@ -0,0 +1,1778 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.section .rodata +.align 5 +Lpoly: +.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 +LRR: // 2^512 mod P precomputed for NIST P256 polynomial +.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd +Lone_mont: +.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe +Lone: +.quad 1,0,0,0 +Lord: +.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 +LordK: +.quad 0xccd1c8aaee00bc4f +.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 +.align 2 +.text + +// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_mul_mont + +.def ecp_nistz256_mul_mont + .type 32 +.endef +.align 4 +ecp_nistz256_mul_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_mul_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_sqr_mont + +.def ecp_nistz256_sqr_mont + .type 32 +.endef +.align 4 +ecp_nistz256_sqr_mont: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-32]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sqr_mont + + ldp x19,x20,[sp,#16] + ldp x29,x30,[sp],#32 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_div_by_2 + +.def ecp_nistz256_div_by_2 + .type 32 +.endef +.align 4 +ecp_nistz256_div_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_div_by_2 + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_2 + +.def ecp_nistz256_mul_by_2 + .type 32 +.endef +.align 4 +ecp_nistz256_mul_by_2: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_mul_by_3 + +.def ecp_nistz256_mul_by_3 + .type 32 +.endef +.align 4 +ecp_nistz256_mul_by_3: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + + bl __ecp_nistz256_add_to // ret = a+a // 2*a + + mov x8,x4 + mov x9,x5 + mov x10,x6 + mov x11,x7 + + bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], +// const BN_ULONG x2[4]); +.globl ecp_nistz256_sub + +.def ecp_nistz256_sub + .type 32 +.endef +.align 4 +ecp_nistz256_sub: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldp x14,x15,[x1] + ldp x16,x17,[x1,#16] + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); +.globl ecp_nistz256_neg + +.def ecp_nistz256_neg + .type 32 +.endef +.align 4 +ecp_nistz256_neg: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + mov x2,x1 + mov x14,xzr // a = 0 + mov x15,xzr + mov x16,xzr + mov x17,xzr + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + bl __ecp_nistz256_sub_from + + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret + + +// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded +// to x4-x7 and b[0] - to x3 +.def __ecp_nistz256_mul_mont + .type 32 +.endef +.align 4 +__ecp_nistz256_mul_mont: + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x11,x7,x3 + ldr x3,[x2,#8] // b[1] + + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adc x19,xzr,x11 + mov x20,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(1+1)] // b[1+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + ldr x3,[x2,#8*(2+1)] // b[2+1] + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + mul x8,x4,x3 // lo(a[0]*b[i]) + adcs x15,x16,x9 + mul x9,x5,x3 // lo(a[1]*b[i]) + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + mul x10,x6,x3 // lo(a[2]*b[i]) + adcs x17,x19,x11 + mul x11,x7,x3 // lo(a[3]*b[i]) + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts of multiplication + umulh x8,x4,x3 // hi(a[0]*b[i]) + adcs x15,x15,x9 + umulh x9,x5,x3 // hi(a[1]*b[i]) + adcs x16,x16,x10 + umulh x10,x6,x3 // hi(a[2]*b[i]) + adcs x17,x17,x11 + umulh x11,x7,x3 // hi(a[3]*b[i]) + adc x19,x19,xzr + adds x15,x15,x8 // accumulate high parts of multiplication + lsl x8,x14,#32 + adcs x16,x16,x9 + lsr x9,x14,#32 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + // last reduction + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adcs x17,x19,x11 + adc x19,x20,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded +// to x4-x7 +.def __ecp_nistz256_sqr_mont + .type 32 +.endef +.align 4 +__ecp_nistz256_sqr_mont: + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x2,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + lsl x8,x14,#32 + adcs x1,x1,x11 + lsr x9,x14,#32 + adc x2,x2,x7 + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + lsl x8,x14,#32 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + lsr x9,x14,#32 + adc x17,x11,xzr // can't overflow + subs x10,x14,x8 // "*0xffff0001" + sbc x11,x14,x9 + adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0] + adcs x15,x16,x9 + adcs x16,x17,x10 // +=acc[0]*0xffff0001 + adc x17,x11,xzr // can't overflow + + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x2 + adc x19,xzr,xzr + + adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x19,xzr // did it borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to +// x4-x7 and x8-x11. This is done because it's used in multiple +// contexts, e.g. in multiplication by 2 and 3... +.def __ecp_nistz256_add_to + .type 32 +.endef +.align 4 +__ecp_nistz256_add_to: + adds x14,x14,x8 // ret = a+b + adcs x15,x15,x9 + adcs x16,x16,x10 + adcs x17,x17,x11 + adc x1,xzr,xzr // zap x1 + + adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus + sbcs x9,x15,x12 + sbcs x10,x16,xzr + sbcs x11,x17,x13 + sbcs xzr,x1,xzr // did subtraction borrow? + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ret + + +.def __ecp_nistz256_sub_from + .type 32 +.endef +.align 4 +__ecp_nistz256_sub_from: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x14,x8 // ret = a-b + sbcs x15,x15,x9 + sbcs x16,x16,x10 + sbcs x17,x17,x11 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + +.def __ecp_nistz256_sub_morf + .type 32 +.endef +.align 4 +__ecp_nistz256_sub_morf: + ldp x8,x9,[x2] + ldp x10,x11,[x2,#16] + subs x14,x8,x14 // ret = b-a + sbcs x15,x9,x15 + sbcs x16,x10,x16 + sbcs x17,x11,x17 + sbc x1,xzr,xzr // zap x1 + + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adc x11,x17,x13 + cmp x1,xzr // did subtraction borrow? + + csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret + csel x15,x15,x9,eq + csel x16,x16,x10,eq + stp x14,x15,[x0] + csel x17,x17,x11,eq + stp x16,x17,[x0,#16] + + ret + + +.def __ecp_nistz256_div_by_2 + .type 32 +.endef +.align 4 +__ecp_nistz256_div_by_2: + subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus + adcs x9,x15,x12 + adcs x10,x16,xzr + adcs x11,x17,x13 + adc x1,xzr,xzr // zap x1 + tst x14,#1 // is a even? + + csel x14,x14,x8,eq // ret = even ? a : a+modulus + csel x15,x15,x9,eq + csel x16,x16,x10,eq + csel x17,x17,x11,eq + csel x1,xzr,x1,eq + + lsr x14,x14,#1 // ret >>= 1 + orr x14,x14,x15,lsl#63 + lsr x15,x15,#1 + orr x15,x15,x16,lsl#63 + lsr x16,x16,#1 + orr x16,x16,x17,lsl#63 + lsr x17,x17,#1 + stp x14,x15,[x0] + orr x17,x17,x1,lsl#63 + stp x16,x17,[x0,#16] + + ret + +.globl ecp_nistz256_point_double + +.def ecp_nistz256_point_double + .type 32 +.endef +.align 5 +ecp_nistz256_point_double: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + sub sp,sp,#32*4 + +Ldouble_shortcut: + ldp x14,x15,[x1,#32] + mov x21,x0 + ldp x16,x17,[x1,#48] + mov x22,x1 + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + mov x8,x14 + ldr x13,[x13,#24] + mov x9,x15 + ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[x22,#64+16] + add x0,sp,#0 + bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y); + + add x0,sp,#64 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z); + + ldp x8,x9,[x22] + ldp x10,x11,[x22,#16] + mov x4,x14 // put Zsqr aside for p256_sub + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x); + + add x2,x22,#0 + mov x14,x4 // restore Zsqr + mov x15,x5 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x16,x6 + mov x17,x7 + ldp x6,x7,[sp,#0+16] + add x0,sp,#64 + bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr); + + add x0,sp,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S); + + ldr x3,[x22,#32] + ldp x4,x5,[x22,#64] + ldp x6,x7,[x22,#64+16] + add x2,x22,#32 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#0+16] + add x0,x21,#64 + bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0); + + add x0,sp,#96 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S); + + ldr x3,[sp,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x0,x21,#32 + bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0); + + add x2,sp,#64 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr); + + mov x8,x14 // duplicate M + mov x9,x15 + mov x10,x16 + mov x11,x17 + mov x4,x14 // put M aside + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x0,sp,#32 + bl __ecp_nistz256_add_to + mov x8,x4 // restore M + mov x9,x5 + ldr x3,[x22] // forward load for p256_mul_mont + mov x10,x6 + ldp x4,x5,[sp,#0] + mov x11,x7 + ldp x6,x7,[sp,#0+16] + bl __ecp_nistz256_add_to // p256_mul_by_3(M, M); + + add x2,x22,#0 + add x0,sp,#0 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x); + + mov x8,x14 + mov x9,x15 + ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont + mov x10,x16 + mov x11,x17 + ldp x6,x7,[sp,#32+16] + add x0,sp,#96 + bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S); + + add x0,x21,#0 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M); + + add x2,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0); + + add x2,sp,#0 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x); + + ldr x3,[sp,#32] + mov x4,x14 // copy S + mov x5,x15 + mov x6,x16 + mov x7,x17 + add x2,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M); + + add x2,x21,#32 + add x0,x21,#32 + bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y); + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl ecp_nistz256_point_add + +.def ecp_nistz256_point_add + .type 32 +.endef +.align 5 +ecp_nistz256_point_add: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#32*12 + + ldp x4,x5,[x2,#64] // in2_z + ldp x6,x7,[x2,#64+16] + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + orr x8,x4,x5 + orr x10,x6,x7 + orr x25,x8,x10 + cmp x25,#0 + csetm x25,ne // ~in2infty + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z); + + ldp x4,x5,[x22,#64] // in1_z + ldp x6,x7,[x22,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x2,x23,#64 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x22,#64 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#32] + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x2,x22,#32 + add x0,sp,#320 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#352] + ldp x6,x7,[sp,#352+16] + add x2,x23,#32 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,sp,#320 + ldr x3,[sp,#192] // forward load for p256_mul_mont + ldp x4,x5,[x22] + ldp x6,x7,[x22,#16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x26,x14,x16 // ~is_equal(S1,S2) + + add x2,sp,#192 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr); + + ldr x3,[sp,#128] + ldp x4,x5,[x23] + ldp x6,x7,[x23,#16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr); + + add x2,sp,#256 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#96 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1); + + orr x14,x14,x15 // see if result is zero + orr x16,x16,x17 + orr x14,x14,x16 // ~is_equal(U1,U2) + + mvn x27,x24 // -1/0 -> 0/-1 + mvn x28,x25 // -1/0 -> 0/-1 + orr x14,x14,x27 + orr x14,x14,x28 + orr x14,x14,x26 + cbnz x14,Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) + +Ladd_double: + mov x1,x22 + mov x0,x21 + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames + b Ldouble_shortcut + +.align 4 +Ladd_proceed: + add x0,sp,#192 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldp x4,x5,[sp,#96] + ldp x6,x7,[sp,#96+16] + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldr x3,[x23,#64] + ldp x4,x5,[sp,#64] + ldp x6,x7,[sp,#64+16] + add x2,x23,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z); + + ldr x3,[sp,#96] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,sp,#96 + add x0,sp,#224 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[sp,#128] + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x2,sp,#128 + add x0,sp,#288 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#128 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#192 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#224 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#288 + ldr x3,[sp,#224] // forward load for p256_mul_mont + ldp x4,x5,[sp,#320] + ldp x6,x7,[sp,#320+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,sp,#224 + add x0,sp,#352 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#160 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#352 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + +Ladd_done: + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#96 + AARCH64_VALIDATE_LINK_REGISTER + ret + +.globl ecp_nistz256_point_add_affine + +.def ecp_nistz256_point_add_affine + .type 32 +.endef +.align 5 +ecp_nistz256_point_add_affine: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + sub sp,sp,#32*10 + + mov x21,x0 + mov x22,x1 + mov x23,x2 + adrp x13,Lpoly + add x13,x13,:lo12:Lpoly + ldr x12,[x13,#8] + ldr x13,[x13,#24] + + ldp x4,x5,[x1,#64] // in1_z + ldp x6,x7,[x1,#64+16] + orr x8,x4,x5 + orr x10,x6,x7 + orr x24,x8,x10 + cmp x24,#0 + csetm x24,ne // ~in1infty + + ldp x14,x15,[x2] // in2_x + ldp x16,x17,[x2,#16] + ldp x8,x9,[x2,#32] // in2_y + ldp x10,x11,[x2,#48] + orr x14,x14,x15 + orr x16,x16,x17 + orr x8,x8,x9 + orr x10,x10,x11 + orr x14,x14,x16 + orr x8,x8,x10 + orr x25,x14,x8 + cmp x25,#0 + csetm x25,ne // ~in2infty + + add x0,sp,#128 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z); + + mov x4,x14 + mov x5,x15 + mov x6,x16 + mov x7,x17 + ldr x3,[x23] + add x2,x23,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x); + + add x2,x22,#0 + ldr x3,[x22,#64] // forward load for p256_mul_mont + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x0,sp,#160 + bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x); + + add x2,x22,#64 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z); + + ldr x3,[x22,#64] + ldp x4,x5,[sp,#160] + ldp x6,x7,[sp,#160+16] + add x2,x22,#64 + add x0,sp,#64 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z); + + ldr x3,[x23,#32] + ldp x4,x5,[sp,#128] + ldp x6,x7,[sp,#128+16] + add x2,x23,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y); + + add x2,x22,#32 + ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont + ldp x6,x7,[sp,#160+16] + add x0,sp,#192 + bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y); + + add x0,sp,#224 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H); + + ldp x4,x5,[sp,#192] + ldp x6,x7,[sp,#192+16] + add x0,sp,#288 + bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R); + + ldr x3,[sp,#160] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,sp,#160 + add x0,sp,#256 + bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H); + + ldr x3,[x22] + ldp x4,x5,[sp,#224] + ldp x6,x7,[sp,#224+16] + add x2,x22,#0 + add x0,sp,#96 + bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr); + + mov x8,x14 + mov x9,x15 + mov x10,x16 + mov x11,x17 + add x0,sp,#224 + bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2); + + add x2,sp,#288 + add x0,sp,#0 + bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr); + + add x2,sp,#256 + bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub); + + add x2,sp,#96 + ldr x3,[x22,#32] // forward load for p256_mul_mont + ldp x4,x5,[sp,#256] + ldp x6,x7,[sp,#256+16] + add x0,sp,#32 + bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x); + + add x2,x22,#32 + add x0,sp,#128 + bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub); + + ldr x3,[sp,#192] + ldp x4,x5,[sp,#32] + ldp x6,x7,[sp,#32+16] + add x2,sp,#192 + add x0,sp,#32 + bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R); + + add x2,sp,#128 + bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2); + + ldp x4,x5,[sp,#0] // res + ldp x6,x7,[sp,#0+16] + ldp x8,x9,[x23] // in2 + ldp x10,x11,[x23,#16] + ldp x14,x15,[x22,#0] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#0+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+0+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+0+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#0+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#0+48] + stp x14,x15,[x21,#0] + stp x16,x17,[x21,#0+16] + adrp x23,Lone_mont-64 + add x23,x23,:lo12:Lone_mont-64 + ldp x14,x15,[x22,#32] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#32+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + ldp x4,x5,[sp,#0+32+32] // res + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + ldp x6,x7,[sp,#0+32+48] + csel x14,x8,x14,ne + csel x15,x9,x15,ne + ldp x8,x9,[x23,#32+32] // in2 + csel x16,x10,x16,ne + csel x17,x11,x17,ne + ldp x10,x11,[x23,#32+48] + stp x14,x15,[x21,#32] + stp x16,x17,[x21,#32+16] + ldp x14,x15,[x22,#64] // in1 + cmp x24,#0 // ~, remember? + ldp x16,x17,[x22,#64+16] + csel x8,x4,x8,ne + csel x9,x5,x9,ne + csel x10,x6,x10,ne + csel x11,x7,x11,ne + cmp x25,#0 // ~, remember? + csel x14,x8,x14,ne + csel x15,x9,x15,ne + csel x16,x10,x16,ne + csel x17,x11,x17,ne + stp x14,x15,[x21,#64] + stp x16,x17,[x21,#64+16] + + add sp,x29,#0 // destroy frame + ldp x19,x20,[x29,#16] + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x29,x30,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], +// uint64_t b[4]); +.globl ecp_nistz256_ord_mul_mont + +.def ecp_nistz256_ord_mul_mont + .type 32 +.endef +.align 4 +ecp_nistz256_ord_mul_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,Lord + add x23,x23,:lo12:Lord + ldr x3,[x2] // bp[0] + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + + mul x14,x4,x3 // a[0]*b[0] + umulh x8,x4,x3 + + mul x15,x5,x3 // a[1]*b[0] + umulh x9,x5,x3 + + mul x16,x6,x3 // a[2]*b[0] + umulh x10,x6,x3 + + mul x17,x7,x3 // a[3]*b[0] + umulh x19,x7,x3 + + mul x24,x14,x23 + + adds x15,x15,x8 // accumulate high parts of multiplication + adcs x16,x16,x9 + adcs x17,x17,x10 + adc x19,x19,xzr + mov x20,xzr + ldr x3,[x2,#8*1] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*2] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + ldr x3,[x2,#8*3] // b[i] + + lsl x8,x24,#32 + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + mul x8,x4,x3 + adc x11,x11,xzr + mul x9,x5,x3 + + adds x14,x15,x10 + mul x10,x6,x3 + adcs x15,x16,x11 + mul x11,x7,x3 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + adds x14,x14,x8 // accumulate low parts + umulh x8,x4,x3 + adcs x15,x15,x9 + umulh x9,x5,x3 + adcs x16,x16,x10 + umulh x10,x6,x3 + adcs x17,x17,x11 + umulh x11,x7,x3 + adc x19,x19,xzr + mul x24,x14,x23 + adds x15,x15,x8 // accumulate high parts + adcs x16,x16,x9 + adcs x17,x17,x10 + adcs x19,x19,x11 + adc x20,xzr,xzr + lsl x8,x24,#32 // last reduction + subs x16,x16,x24 + lsr x9,x24,#32 + sbcs x17,x17,x8 + sbcs x19,x19,x9 + sbc x20,x20,xzr + + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adcs x17,x19,x24 + adc x19,x20,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x15,x15,x9,lo + csel x16,x16,x10,lo + stp x14,x15,[x0] + csel x17,x17,x11,lo + stp x16,x17,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], +// uint64_t rep); +.globl ecp_nistz256_ord_sqr_mont + +.def ecp_nistz256_ord_sqr_mont + .type 32 +.endef +.align 4 +ecp_nistz256_ord_sqr_mont: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-64]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + + adrp x23,Lord + add x23,x23,:lo12:Lord + ldp x4,x5,[x1] + ldp x6,x7,[x1,#16] + + ldp x12,x13,[x23,#0] + ldp x21,x22,[x23,#16] + ldr x23,[x23,#32] + b Loop_ord_sqr + +.align 4 +Loop_ord_sqr: + sub x2,x2,#1 + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x15,x5,x4 // a[1]*a[0] + umulh x9,x5,x4 + mul x16,x6,x4 // a[2]*a[0] + umulh x10,x6,x4 + mul x17,x7,x4 // a[3]*a[0] + umulh x19,x7,x4 + + adds x16,x16,x9 // accumulate high parts of multiplication + mul x8,x6,x5 // a[2]*a[1] + umulh x9,x6,x5 + adcs x17,x17,x10 + mul x10,x7,x5 // a[3]*a[1] + umulh x11,x7,x5 + adc x19,x19,xzr // can't overflow + + mul x20,x7,x6 // a[3]*a[2] + umulh x1,x7,x6 + + adds x9,x9,x10 // accumulate high parts of multiplication + mul x14,x4,x4 // a[0]*a[0] + adc x10,x11,xzr // can't overflow + + adds x17,x17,x8 // accumulate low parts of multiplication + umulh x4,x4,x4 + adcs x19,x19,x9 + mul x9,x5,x5 // a[1]*a[1] + adcs x20,x20,x10 + umulh x5,x5,x5 + adc x1,x1,xzr // can't overflow + + adds x15,x15,x15 // acc[1-6]*=2 + mul x10,x6,x6 // a[2]*a[2] + adcs x16,x16,x16 + umulh x6,x6,x6 + adcs x17,x17,x17 + mul x11,x7,x7 // a[3]*a[3] + adcs x19,x19,x19 + umulh x7,x7,x7 + adcs x20,x20,x20 + adcs x1,x1,x1 + adc x3,xzr,xzr + + adds x15,x15,x4 // +a[i]*a[i] + mul x24,x14,x23 + adcs x16,x16,x9 + adcs x17,x17,x5 + adcs x19,x19,x10 + adcs x20,x20,x6 + adcs x1,x1,x11 + adc x3,x3,x7 + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + mul x24,x14,x23 + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x24 + mul x10,x13,x24 + umulh x11,x13,x24 + + adcs x10,x10,x9 + adc x11,x11,xzr + + adds x14,x15,x10 + adcs x15,x16,x11 + adcs x16,x17,x24 + adc x17,xzr,x24 // can't overflow + mul x11,x14,x23 + lsl x8,x24,#32 + subs x15,x15,x24 + lsr x9,x24,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + subs xzr,x14,#1 + umulh x9,x12,x11 + mul x10,x13,x11 + umulh x24,x13,x11 + + adcs x10,x10,x9 + adc x24,x24,xzr + + adds x14,x15,x10 + adcs x15,x16,x24 + adcs x16,x17,x11 + adc x17,xzr,x11 // can't overflow + lsl x8,x11,#32 + subs x15,x15,x11 + lsr x9,x11,#32 + sbcs x16,x16,x8 + sbc x17,x17,x9 // can't borrow + adds x14,x14,x19 // accumulate upper half + adcs x15,x15,x20 + adcs x16,x16,x1 + adcs x17,x17,x3 + adc x19,xzr,xzr + + subs x8,x14,x12 // ret -= modulus + sbcs x9,x15,x13 + sbcs x10,x16,x21 + sbcs x11,x17,x22 + sbcs xzr,x19,xzr + + csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus + csel x5,x15,x9,lo + csel x6,x16,x10,lo + csel x7,x17,x11,lo + + cbnz x2,Loop_ord_sqr + + stp x4,x5,[x0] + stp x6,x7,[x0,#16] + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldr x29,[sp],#64 + ret + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w5 + +.def ecp_nistz256_select_w5 + .type 32 +.endef +.align 4 +ecp_nistz256_select_w5: + AARCH64_VALID_CALL_TARGET + + // x10 := x0 + // w9 := 0; loop counter and incremented internal index + mov x10, x0 + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + movi v20.16b, #0 + movi v21.16b, #0 + +Lselect_w5_loop: + // Loop 16 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v27] := Load a (3*256-bit = 6*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // continue loading ... + ld1 {v26.2d, v27.2d}, [x1],#32 + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + bit v20.16b, v26.16b, v3.16b + bit v21.16b, v27.16b, v3.16b + + // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back + tbz w9, #4, Lselect_w5_loop + + // Write [v16-v21] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x10],#64 + st1 {v20.2d, v21.2d}, [x10] + + ret + + + +//////////////////////////////////////////////////////////////////////// +// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index); +.globl ecp_nistz256_select_w7 + +.def ecp_nistz256_select_w7 + .type 32 +.endef +.align 4 +ecp_nistz256_select_w7: + AARCH64_VALID_CALL_TARGET + + // w9 := 0; loop counter and incremented internal index + mov w9, #0 + + // [v16-v21] := 0 + movi v16.16b, #0 + movi v17.16b, #0 + movi v18.16b, #0 + movi v19.16b, #0 + +Lselect_w7_loop: + // Loop 64 times. + + // Increment index (loop counter); tested at the end of the loop + add w9, w9, #1 + + // [v22-v25] := Load a (2*256-bit = 4*128-bit) table entry starting at x1 + // and advance x1 to point to the next entry + ld1 {v22.2d, v23.2d, v24.2d, v25.2d}, [x1],#64 + + // x11 := (w9 == w2)? All 1s : All 0s + cmp w9, w2 + csetm x11, eq + + // duplicate mask_64 into Mask (all 0s or all 1s) + dup v3.2d, x11 + + // [v16-v19] := (Mask == all 1s)? [v22-v25] : [v16-v19] + // i.e., values in output registers will remain the same if w9 != w2 + bit v16.16b, v22.16b, v3.16b + bit v17.16b, v23.16b, v3.16b + + bit v18.16b, v24.16b, v3.16b + bit v19.16b, v25.16b, v3.16b + + // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back + tbz w9, #6, Lselect_w7_loop + + // Write [v16-v19] to memory at the output pointer + st1 {v16.2d, v17.2d, v18.2d, v19.2d}, [x0] + + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-win.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-win.S new file mode 100644 index 00000000..db796f0d --- /dev/null +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/p256_beeu-armv8-asm-win.S @@ -0,0 +1,321 @@ +// This file is generated from a similarly-named Perl script in the BoringSSL +// source tree. Do not edit by hand. + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM) +#define OPENSSL_NO_ASM +#endif + +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(BORINGSSL_PREFIX) +#include +#endif +#include "openssl/arm_arch.h" + +.text +.globl beeu_mod_inverse_vartime + + +.align 4 +beeu_mod_inverse_vartime: + // Reserve enough space for 14 8-byte registers on the stack + // in the first stp call for x29, x30. + // Then store the remaining callee-saved registers. + // + // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 | + // ^ ^ + // sp <------------------- 112 bytes ----------------> old sp + // x29 (FP) + // + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-112]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + stp x0,x2,[sp,#96] + + // B = b3..b0 := a + ldp x25,x26,[x1] + ldp x27,x28,[x1,#16] + + // n3..n0 := n + // Note: the value of input params are changed in the following. + ldp x0,x1,[x2] + ldp x2,x30,[x2,#16] + + // A = a3..a0 := n + mov x21, x0 + mov x22, x1 + mov x23, x2 + mov x24, x30 + + // X = x4..x0 := 1 + mov x3, #1 + eor x4, x4, x4 + eor x5, x5, x5 + eor x6, x6, x6 + eor x7, x7, x7 + + // Y = y4..y0 := 0 + eor x8, x8, x8 + eor x9, x9, x9 + eor x10, x10, x10 + eor x11, x11, x11 + eor x12, x12, x12 + +Lbeeu_loop: + // if B == 0, jump to .Lbeeu_loop_end + orr x14, x25, x26 + orr x14, x14, x27 + + // reverse the bit order of x25. This is needed for clz after this macro + rbit x15, x25 + + orr x14, x14, x28 + cbz x14,Lbeeu_loop_end + + + // 0 < B < |n|, + // 0 < A <= |n|, + // (1) X*a == B (mod |n|), + // (2) (-1)*Y*a == A (mod |n|) + + // Now divide B by the maximum possible power of two in the + // integers, and divide X by the same value mod |n|. + // When we're done, (1) still holds. + + // shift := number of trailing 0s in x25 + // ( = number of leading 0s in x15; see the "rbit" instruction in TEST_B_ZERO) + clz x13, x15 + + // If there is no shift, goto shift_A_Y + cbz x13, Lbeeu_shift_A_Y + + // Shift B right by "x13" bits + neg x14, x13 + lsr x25, x25, x13 + lsl x15, x26, x14 + + lsr x26, x26, x13 + lsl x19, x27, x14 + + orr x25, x25, x15 + + lsr x27, x27, x13 + lsl x20, x28, x14 + + orr x26, x26, x19 + + lsr x28, x28, x13 + + orr x27, x27, x20 + + + // Shift X right by "x13" bits, adding n whenever X becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_X: + tbz x3, #0, Lshift1_0 + adds x3, x3, x0 + adcs x4, x4, x1 + adcs x5, x5, x2 + adcs x6, x6, x30 + adc x7, x7, x14 +Lshift1_0: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x3, x4, x3, #1 + extr x4, x5, x4, #1 + extr x5, x6, x5, #1 + extr x6, x7, x6, #1 + lsr x7, x7, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_X + + // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl + // with the following differences: + // - "x13" is set directly to the number of trailing 0s in B + // (using rbit and clz instructions) + // - The loop is only used to call SHIFT1(X) + // and x13 is decreased while executing the X loop. + // - SHIFT256(B, x13) is performed before right-shifting X; they are independent + +Lbeeu_shift_A_Y: + // Same for A and Y. + // Afterwards, (2) still holds. + // Reverse the bit order of x21 + // x13 := number of trailing 0s in x21 (= number of leading 0s in x15) + rbit x15, x21 + clz x13, x15 + + // If there is no shift, goto |B-A|, X+Y update + cbz x13, Lbeeu_update_B_X_or_A_Y + + // Shift A right by "x13" bits + neg x14, x13 + lsr x21, x21, x13 + lsl x15, x22, x14 + + lsr x22, x22, x13 + lsl x19, x23, x14 + + orr x21, x21, x15 + + lsr x23, x23, x13 + lsl x20, x24, x14 + + orr x22, x22, x19 + + lsr x24, x24, x13 + + orr x23, x23, x20 + + + // Shift Y right by "x13" bits, adding n whenever Y becomes odd. + // x13--; + // x14 := 0; needed in the addition to the most significant word in SHIFT1 + eor x14, x14, x14 +Lbeeu_shift_loop_Y: + tbz x8, #0, Lshift1_1 + adds x8, x8, x0 + adcs x9, x9, x1 + adcs x10, x10, x2 + adcs x11, x11, x30 + adc x12, x12, x14 +Lshift1_1: + // var0 := [var1|var0]<64..1>; + // i.e. concatenate var1 and var0, + // extract bits <64..1> from the resulting 128-bit value + // and put them in var0 + extr x8, x9, x8, #1 + extr x9, x10, x9, #1 + extr x10, x11, x10, #1 + extr x11, x12, x11, #1 + lsr x12, x12, #1 + + subs x13, x13, #1 + bne Lbeeu_shift_loop_Y + +Lbeeu_update_B_X_or_A_Y: + // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow) + // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words + // without taking a sign bit if generated. The lack of a carry would + // indicate a negative result. See, for example, + // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes + subs x14, x25, x21 + sbcs x15, x26, x22 + sbcs x19, x27, x23 + sbcs x20, x28, x24 + bcs Lbeeu_B_greater_than_A + + // Else A > B => + // A := A - B; Y := Y + X; goto beginning of the loop + subs x21, x21, x25 + sbcs x22, x22, x26 + sbcs x23, x23, x27 + sbcs x24, x24, x28 + + adds x8, x8, x3 + adcs x9, x9, x4 + adcs x10, x10, x5 + adcs x11, x11, x6 + adc x12, x12, x7 + b Lbeeu_loop + +Lbeeu_B_greater_than_A: + // Continue with B > A => + // B := B - A; X := X + Y; goto beginning of the loop + mov x25, x14 + mov x26, x15 + mov x27, x19 + mov x28, x20 + + adds x3, x3, x8 + adcs x4, x4, x9 + adcs x5, x5, x10 + adcs x6, x6, x11 + adc x7, x7, x12 + b Lbeeu_loop + +Lbeeu_loop_end: + // The Euclid's algorithm loop ends when A == gcd(a,n); + // this would be 1, when a and n are co-prime (i.e. do not have a common factor). + // Since (-1)*Y*a == A (mod |n|), Y>0 + // then out = -Y mod n + + // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|) + // Is A-1 == 0? + // If not, fail. + sub x14, x21, #1 + orr x14, x14, x22 + orr x14, x14, x23 + orr x14, x14, x24 + cbnz x14, Lbeeu_err + + // If Y>n ==> Y:=Y-n +Lbeeu_reduction_loop: + // x_i := y_i - n_i (X is no longer needed, use it as temp) + // (x14 = 0 from above) + subs x3, x8, x0 + sbcs x4, x9, x1 + sbcs x5, x10, x2 + sbcs x6, x11, x30 + sbcs x7, x12, x14 + + // If result is non-negative (i.e., cs = carry set = no borrow), + // y_i := x_i; goto reduce again + // else + // y_i := y_i; continue + csel x8, x3, x8, cs + csel x9, x4, x9, cs + csel x10, x5, x10, cs + csel x11, x6, x11, cs + csel x12, x7, x12, cs + bcs Lbeeu_reduction_loop + + // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0) + // out = -Y = n-Y + subs x8, x0, x8 + sbcs x9, x1, x9 + sbcs x10, x2, x10 + sbcs x11, x30, x11 + + // Save Y in output (out (x0) was saved on the stack) + ldr x3, [sp,#96] + stp x8, x9, [x3] + stp x10, x11, [x3,#16] + // return 1 (success) + mov x0, #1 + b Lbeeu_finish + +Lbeeu_err: + // return 0 (error) + eor x0, x0, x0 + +Lbeeu_finish: + // Restore callee-saved registers, except x0, x2 + add sp,x29,#0 + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldp x29,x30,[sp],#112 + + AARCH64_VALIDATE_LINK_REGISTER + ret + +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8-win.S similarity index 98% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8-win.S index 2a6a9dc3..8f528ac0 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha1-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -54,7 +53,7 @@ Loop: movz w28,#0x7999 sub x2,x2,#1 movk w28,#0x5a82,lsl#16 -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x3,x3,#32 #else rev32 x3,x3 @@ -72,7 +71,7 @@ Loop: ror w21,w21,#2 add w23,w23,w4 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x5,x5,#32 #else rev32 x5,x5 @@ -97,7 +96,7 @@ Loop: ror w24,w24,#2 add w21,w21,w6 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x7,x7,#32 #else rev32 x7,x7 @@ -122,7 +121,7 @@ Loop: ror w22,w22,#2 add w24,w24,w8 // future e+=X[i] add w20,w20,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x9,x9,#32 #else rev32 x9,x9 @@ -147,7 +146,7 @@ Loop: ror w20,w20,#2 add w22,w22,w10 // future e+=X[i] add w23,w23,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x11,x11,#32 #else rev32 x11,x11 @@ -172,7 +171,7 @@ Loop: ror w23,w23,#2 add w20,w20,w12 // future e+=X[i] add w21,w21,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x13,x13,#32 #else rev32 x13,x13 @@ -197,7 +196,7 @@ Loop: ror w21,w21,#2 add w23,w23,w14 // future e+=X[i] add w24,w24,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x15,x15,#32 #else rev32 x15,x15 @@ -222,7 +221,7 @@ Loop: ror w24,w24,#2 add w21,w21,w16 // future e+=X[i] add w22,w22,w25 // e+=F(b,c,d) -#ifdef __ARMEB__ +#ifdef __AARCH64EB__ ror x17,x17,#32 #else rev32 x17,x17 @@ -1237,5 +1236,8 @@ Lconst: .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8-win.S similarity index 97% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8-win.S index 5f233f9c..9af62ec5 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha256-armv8-win.S @@ -8,12 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -41,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -49,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -103,7 +103,7 @@ Loop: ldr w19,[x30],#4 // *K++ eor w28,w21,w22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w3,w3 // 0 #endif ror w16,w24,#6 @@ -126,7 +126,7 @@ Loop: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w4,w4 // 1 #endif ldp w5,w6,[x1],#2*4 @@ -151,7 +151,7 @@ Loop: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w5,w5 // 2 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -175,7 +175,7 @@ Loop: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w6,w6 // 3 #endif ldp w7,w8,[x1],#2*4 @@ -200,7 +200,7 @@ Loop: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w7,w7 // 4 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -224,7 +224,7 @@ Loop: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w8,w8 // 5 #endif ldp w9,w10,[x1],#2*4 @@ -249,7 +249,7 @@ Loop: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w9,w9 // 6 #endif add w22,w22,w17 // h+=Sigma0(a) @@ -273,7 +273,7 @@ Loop: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w10,w10 // 7 #endif ldp w11,w12,[x1],#2*4 @@ -298,7 +298,7 @@ Loop: add w20,w20,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w20,w20,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w11,w11 // 8 #endif add w20,w20,w17 // h+=Sigma0(a) @@ -322,7 +322,7 @@ Loop: add w27,w27,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w27,w27,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w12,w12 // 9 #endif ldp w13,w14,[x1],#2*4 @@ -347,7 +347,7 @@ Loop: add w26,w26,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w26,w26,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w13,w13 // 10 #endif add w26,w26,w17 // h+=Sigma0(a) @@ -371,7 +371,7 @@ Loop: add w25,w25,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w25,w25,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w14,w14 // 11 #endif ldp w15,w0,[x1],#2*4 @@ -397,7 +397,7 @@ Loop: add w24,w24,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w24,w24,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w15,w15 // 12 #endif add w24,w24,w17 // h+=Sigma0(a) @@ -422,7 +422,7 @@ Loop: add w23,w23,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w23,w23,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w0,w0 // 13 #endif ldp w1,w2,[x1] @@ -448,7 +448,7 @@ Loop: add w22,w22,w19 // h+=Maj(a,b,c) ldr w19,[x30],#4 // *K++, w28 in next round //add w22,w22,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w1,w1 // 14 #endif ldr w6,[sp,#12] @@ -474,7 +474,7 @@ Loop: add w21,w21,w28 // h+=Maj(a,b,c) ldr w28,[x30],#4 // *K++, w19 in next round //add w21,w21,w17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev w2,w2 // 15 #endif ldr w7,[sp,#0] @@ -1213,5 +1213,8 @@ Loop_hw: ret #endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8-win.S similarity index 60% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8-win.S index d01304fd..8fac36e7 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/sha512-armv8-win.S @@ -8,12 +8,11 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif -// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy @@ -41,6 +40,7 @@ // Denver 2.01 10.5 (+26%) 6.70 (+8%) // X-Gene 20.0 (+100%) 12.8 (+300%(***)) // Mongoose 2.36 13.0 (+50%) 8.36 (+33%) +// Kryo 1.92 17.4 (+30%) 11.2 (+8%) // // (*) Software SHA256 results are of lesser relevance, presented // mostly for informational purposes. @@ -49,7 +49,7 @@ // on Cortex-A53 (or by 4 cycles per round). // (***) Super-impressive coefficients over gcc-generated code are // indication of some compiler "pathology", most notably code -// generated with -mgeneral-regs-only is significanty faster +// generated with -mgeneral-regs-only is significantly faster // and the gap is only 40-90%. #ifndef __KERNEL__ @@ -67,6 +67,17 @@ .endef .align 6 sha512_block_data_order: + AARCH64_VALID_CALL_TARGET +#ifndef __KERNEL__ +#if __has_feature(hwaddress_sanitizer) && __clang_major__ >= 10 + adrp x16,:pg_hi21_nc:OPENSSL_armcap_P +#else + adrp x16,OPENSSL_armcap_P +#endif + ldr w16,[x16,:lo12:OPENSSL_armcap_P] + tst w16,#ARMV8_SHA512 + b.ne Lv8_entry +#endif AARCH64_SIGN_LINK_REGISTER stp x29,x30,[sp,#-128]! add x29,sp,#0 @@ -92,7 +103,7 @@ Loop: ldr x19,[x30],#8 // *K++ eor x28,x21,x22 // magic seed str x1,[x29,#112] -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x3,x3 // 0 #endif ror x16,x24,#14 @@ -115,7 +126,7 @@ Loop: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x4,x4 // 1 #endif ldp x5,x6,[x1],#2*8 @@ -140,7 +151,7 @@ Loop: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x5,x5 // 2 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -164,7 +175,7 @@ Loop: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x6,x6 // 3 #endif ldp x7,x8,[x1],#2*8 @@ -189,7 +200,7 @@ Loop: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x7,x7 // 4 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -213,7 +224,7 @@ Loop: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x8,x8 // 5 #endif ldp x9,x10,[x1],#2*8 @@ -238,7 +249,7 @@ Loop: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x9,x9 // 6 #endif add x22,x22,x17 // h+=Sigma0(a) @@ -262,7 +273,7 @@ Loop: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x10,x10 // 7 #endif ldp x11,x12,[x1],#2*8 @@ -287,7 +298,7 @@ Loop: add x20,x20,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x20,x20,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x11,x11 // 8 #endif add x20,x20,x17 // h+=Sigma0(a) @@ -311,7 +322,7 @@ Loop: add x27,x27,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x27,x27,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x12,x12 // 9 #endif ldp x13,x14,[x1],#2*8 @@ -336,7 +347,7 @@ Loop: add x26,x26,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x26,x26,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x13,x13 // 10 #endif add x26,x26,x17 // h+=Sigma0(a) @@ -360,7 +371,7 @@ Loop: add x25,x25,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x25,x25,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x14,x14 // 11 #endif ldp x15,x0,[x1],#2*8 @@ -386,7 +397,7 @@ Loop: add x24,x24,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x24,x24,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x15,x15 // 12 #endif add x24,x24,x17 // h+=Sigma0(a) @@ -411,7 +422,7 @@ Loop: add x23,x23,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x23,x23,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x0,x0 // 13 #endif ldp x1,x2,[x1] @@ -437,7 +448,7 @@ Loop: add x22,x22,x19 // h+=Maj(a,b,c) ldr x19,[x30],#8 // *K++, x28 in next round //add x22,x22,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x1,x1 // 14 #endif ldr x6,[sp,#24] @@ -463,7 +474,7 @@ Loop: add x21,x21,x28 // h+=Maj(a,b,c) ldr x28,[x30],#8 // *K++, x19 in next round //add x21,x21,x17 // h+=Sigma0(a) -#ifndef __ARMEB__ +#ifndef __AARCH64EB__ rev x2,x2 // 15 #endif ldr x7,[sp,#0] @@ -1081,5 +1092,531 @@ LK512: .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 +.text +#ifndef __KERNEL__ +.def sha512_block_armv8 + .type 32 +.endef +.align 6 +sha512_block_armv8: +Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64 + + ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context + adrp x3,LK512 + add x3,x3,:lo12:LK512 + + rev64 v16.16b,v16.16b + rev64 v17.16b,v17.16b + rev64 v18.16b,v18.16b + rev64 v19.16b,v19.16b + rev64 v20.16b,v20.16b + rev64 v21.16b,v21.16b + rev64 v22.16b,v22.16b + rev64 v23.16b,v23.16b + b Loop_hw + +.align 4 +Loop_hw: + ld1 {v24.2d},[x3],#16 + subs x2,x2,#1 + sub x4,x1,#128 + orr v26.16b,v0.16b,v0.16b // offload + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v2.16b,v2.16b + orr v29.16b,v3.16b,v3.16b + csel x1,x1,x4,ne // conditional rewind + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v24.2d,v24.2d,v16.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08230 //sha512su0 v16.16b,v17.16b + ext v7.16b,v20.16b,v21.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v25.2d,v25.2d,v17.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08251 //sha512su0 v17.16b,v18.16b + ext v7.16b,v21.16b,v22.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v24.2d,v24.2d,v18.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec08272 //sha512su0 v18.16b,v19.16b + ext v7.16b,v22.16b,v23.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + add v25.2d,v25.2d,v19.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08293 //sha512su0 v19.16b,v20.16b + ext v7.16b,v23.16b,v16.16b,#8 +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b +.long 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + add v24.2d,v24.2d,v20.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082b4 //sha512su0 v20.16b,v21.16b + ext v7.16b,v16.16b,v17.16b,#8 +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b +.long 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + add v25.2d,v25.2d,v21.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec082d5 //sha512su0 v21.16b,v22.16b + ext v7.16b,v17.16b,v18.16b,#8 +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b +.long 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v24.2d,v24.2d,v22.2d + ld1 {v25.2d},[x3],#16 + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]" +.long 0xcec082f6 //sha512su0 v22.16b,v23.16b + ext v7.16b,v18.16b,v19.16b,#8 +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b +.long 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + add v25.2d,v25.2d,v23.2d + ld1 {v24.2d},[x3],#16 + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]" +.long 0xcec08217 //sha512su0 v23.16b,v16.16b + ext v7.16b,v19.16b,v20.16b,#8 +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b +.long 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v16.2d + ld1 {v16.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v16.16b,v16.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v17.2d + ld1 {v17.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v17.16b,v17.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v18.2d + ld1 {v18.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v18.16b,v18.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v19.2d + ld1 {v19.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v2.16b,v3.16b,#8 + ext v6.16b,v1.16b,v2.16b,#8 + add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b + rev64 v19.16b,v19.16b + add v4.2d,v1.2d,v3.2d // "D + T1" +.long 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v20.2d + ld1 {v20.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v4.16b,v2.16b,#8 + ext v6.16b,v0.16b,v4.16b,#8 + add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b + rev64 v20.16b,v20.16b + add v1.2d,v0.2d,v2.2d // "D + T1" +.long 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b + ld1 {v24.2d},[x3],#16 + add v25.2d,v25.2d,v21.2d + ld1 {v21.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v1.16b,v4.16b,#8 + ext v6.16b,v3.16b,v1.16b,#8 + add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b + rev64 v21.16b,v21.16b + add v0.2d,v3.2d,v4.2d // "D + T1" +.long 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b + ld1 {v25.2d},[x3],#16 + add v24.2d,v24.2d,v22.2d + ld1 {v22.16b},[x1],#16 // load next input + ext v24.16b,v24.16b,v24.16b,#8 + ext v5.16b,v0.16b,v1.16b,#8 + ext v6.16b,v2.16b,v0.16b,#8 + add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]" +.long 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b + rev64 v22.16b,v22.16b + add v3.2d,v2.2d,v1.2d // "D + T1" +.long 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b + sub x3,x3,#80*8 // rewind + add v25.2d,v25.2d,v23.2d + ld1 {v23.16b},[x1],#16 // load next input + ext v25.16b,v25.16b,v25.16b,#8 + ext v5.16b,v3.16b,v0.16b,#8 + ext v6.16b,v4.16b,v3.16b,#8 + add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]" +.long 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b + rev64 v23.16b,v23.16b + add v2.2d,v4.2d,v0.2d // "D + T1" +.long 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b + add v0.2d,v0.2d,v26.2d // accumulate + add v1.2d,v1.2d,v27.2d + add v2.2d,v2.2d,v28.2d + add v3.2d,v3.2d,v29.2d + + cbnz x2,Loop_hw + + st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context + + ldr x29,[sp],#16 + ret + +#endif +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8-win.S similarity index 99% rename from third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8-win.S index c97ec124..bba4e86f 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/fipsmodule/vpaes-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -1268,5 +1267,8 @@ Lctr32_done: AARCH64_VALIDATE_LINK_REGISTER ret +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8.S b/third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8-win.S similarity index 97% rename from third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8.S rename to third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8-win.S index 4e17d4b3..5dbfcfc3 100644 --- a/third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8.S +++ b/third_party/boringssl/kit/win-aarch64/crypto/test/trampoline-armv8-win.S @@ -8,8 +8,7 @@ #define OPENSSL_NO_ASM #endif -#if !defined(OPENSSL_NO_ASM) -#if defined(__aarch64__) +#if !defined(OPENSSL_NO_ASM) && defined(__AARCH64EL__) && defined(_WIN32) #if defined(BORINGSSL_PREFIX) #include #endif @@ -756,5 +755,8 @@ abi_test_clobber_v15_upper: fmov v15.d[1], xzr ret +#endif // !OPENSSL_NO_ASM && defined(__AARCH64EL__) && defined(_WIN32) +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits #endif -#endif // !OPENSSL_NO_ASM diff --git a/third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86.asm b/third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86-win.asm index 34393af7..8bd0ce58 100644 --- a/third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/chacha/chacha-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -973,3 +974,7 @@ db 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 db 114,103,62,0 segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86-win.asm index 9ea13756..19b1d98b 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/aesni-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -2459,3 +2460,7 @@ db 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 db 115,108,46,111,114,103,62,0 segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586-win.asm index 4d1b793a..f7ddfa84 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/bn-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -975,3 +976,7 @@ L$025aw_end: ret segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586-win.asm index 7c2afe83..6ad46962 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/co-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -1256,3 +1257,7 @@ L$_bn_sqr_comba4_begin: pop edi pop esi ret +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86-win.asm index e0192fc8..52108aac 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-ssse3-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -290,3 +291,7 @@ db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 align 16 L$low4_mask: dd 252645135,252645135,252645135,252645135 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86-win.asm similarity index 98% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86-win.asm index 3703cb5a..3f6c7074 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/ghash-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -323,3 +324,7 @@ db 71,72,65,83,72,32,102,111,114,32,120,56,54,44,32,67 db 82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112 db 112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62 db 0 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586-win.asm similarity index 98% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586-win.asm index e09bd0c2..25592b8d 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/md5-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -687,3 +688,7 @@ L$000start: pop edi pop esi ret +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586-win.asm index 4b05c9da..51a89074 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha1-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -3804,3 +3805,7 @@ db 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 db 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586-win.asm index 5d6661d0..4e0278b0 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha256-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -5569,3 +5570,7 @@ L$013avx_00_47: ret segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586-win.asm index f2c47a7a..3603a6dc 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/sha512-586-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -2839,3 +2840,7 @@ db 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103 db 62,0 segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86-win.asm index 49f8866b..661496e3 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/vpaes-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -672,3 +673,7 @@ L$022cbc_abort: pop ebx pop ebp ret +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont.asm b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont-win.asm similarity index 98% rename from third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont.asm rename to third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont-win.asm index 14aa9887..cd77529c 100644 --- a/third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont.asm +++ b/third_party/boringssl/kit/win-x86/crypto/fipsmodule/x86-mont-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -483,3 +484,7 @@ db 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 db 111,114,103,62,0 segment .bss common _OPENSSL_ia32cap_P 16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86.asm b/third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86-win.asm similarity index 96% rename from third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86.asm rename to third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86-win.asm index 5fb72c74..3ef9917a 100644 --- a/third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86.asm +++ b/third_party/boringssl/kit/win-x86/crypto/test/trampoline-x86-win.asm @@ -4,6 +4,7 @@ %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif +%ifidn __OUTPUT_FORMAT__, win32 %ifidn __OUTPUT_FORMAT__,obj section code use32 class=code align=64 %elifidn __OUTPUT_FORMAT__,win32 @@ -154,3 +155,7 @@ _abi_test_clobber_xmm7: L$_abi_test_clobber_xmm7_begin: pxor xmm7,xmm7 ret +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64-win.asm similarity index 98% rename from third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64-win.asm index a3c29381..994b787f 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/chacha/chacha-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -14,6 +15,7 @@ section .text code align=64 EXTERN OPENSSL_ia32cap_P +section .rdata rdata align=8 ALIGN 64 $L$zero: DD 0,0,0,0 @@ -28,12 +30,12 @@ $L$incy: $L$eight: DD 8,8,8,8,8,8,8,8 $L$rot16: -DB 0x2,0x3,0x0,0x1,0x6,0x7,0x4,0x5,0xa,0xb,0x8,0x9,0xe,0xf,0xc,0xd + DB 0x2,0x3,0x0,0x1,0x6,0x7,0x4,0x5,0xa,0xb,0x8,0x9,0xe,0xf,0xc,0xd $L$rot24: -DB 0x3,0x0,0x1,0x2,0x7,0x4,0x5,0x6,0xb,0x8,0x9,0xa,0xf,0xc,0xd,0xe + DB 0x3,0x0,0x1,0x2,0x7,0x4,0x5,0x6,0xb,0x8,0x9,0xa,0xf,0xc,0xd,0xe $L$sigma: -DB 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107 -DB 0 + DB 101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107 + DB 0 ALIGN 64 $L$zeroz: DD 0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0 @@ -43,10 +45,12 @@ $L$incz: DD 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 $L$sixteen: DD 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 -DB 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54 -DB 95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32 -DB 98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115 -DB 108,46,111,114,103,62,0 + DB 67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54 + DB 95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32 + DB 98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115 + DB 108,46,111,114,103,62,0 +section .text + global ChaCha20_ctr32 ALIGN 64 @@ -1908,19 +1912,23 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_ChaCha20_ctr32: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase $L$SEH_info_ChaCha20_ssse3: -DB 9,0,0,0 + DB 9,0,0,0 DD ssse3_handler wrt ..imagebase DD $L$ssse3_body wrt ..imagebase,$L$ssse3_epilogue wrt ..imagebase $L$SEH_info_ChaCha20_4x: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$4x_body wrt ..imagebase,$L$4x_epilogue wrt ..imagebase $L$SEH_info_ChaCha20_8x: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$8x_body wrt ..imagebase,$L$8x_epilogue wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-win.asm index e711826b..0019f333 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/aes128gcmsiv-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -9,8 +10,7 @@ default rel %ifdef BORINGSSL_PREFIX %include "boringssl_prefix_symbols_nasm.inc" %endif -section .data data align=8 - +section .rdata rdata align=8 ALIGN 16 one: @@ -41,7 +41,7 @@ con1: con2: DD 0x1b,0x1b,0x1b,0x1b con3: -DB -1,-1,-1,-1,-1,-1,-1,-1,4,5,6,7,4,5,6,7 + DB -1,-1,-1,-1,-1,-1,-1,-1,4,5,6,7,4,5,6,7 and_mask: DD 0,0xffffffff,0xffffffff,0xffffffff section .text code align=64 @@ -3275,3 +3275,7 @@ $L$SEH_begin_aes256gcmsiv_kdf: DB 0F3h,0C3h ;repret $L$SEH_end_aes256gcmsiv_kdf: +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-win.asm index 7e3d6dd9..527762a5 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/cipher_extra/chacha20_poly1305_x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -15,16 +16,17 @@ EXTERN OPENSSL_ia32cap_P chacha20_poly1305_constants: +section .rdata rdata align=8 ALIGN 64 $L$chacha20_consts: -DB 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' -DB 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' + DB 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' + DB 'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k' $L$rol8: -DB 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 -DB 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 + DB 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 + DB 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14 $L$rol16: -DB 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 -DB 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 + DB 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 + DB 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13 $L$avx2_init: DD 0,0,0,0 $L$sse_inc: @@ -36,22 +38,24 @@ $L$clamp: DQ 0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF ALIGN 16 $L$and_masks: -DB 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 -DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff + DB 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 + DB 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +section .text + ALIGN 64 @@ -8944,3 +8948,7 @@ $L$seal_avx2_exit: jmp NEAR $L$seal_sse_tail_16 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-win.asm similarity index 54% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-win.asm index 2b51a268..52e2babe 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -17,9 +18,9 @@ ALIGN 32 _aesni_ctr32_ghash_6x: vmovdqu xmm2,XMMWORD[32+r11] - sub rdx,6 + sub r8,6 vpxor xmm4,xmm4,xmm4 - vmovdqu xmm15,XMMWORD[((0-128))+rcx] + vmovdqu xmm15,XMMWORD[((0-128))+r9] vpaddb xmm10,xmm1,xmm2 vpaddb xmm11,xmm10,xmm2 vpaddb xmm12,xmm11,xmm2 @@ -33,16 +34,16 @@ ALIGN 32 $L$oop6x: add ebx,100663296 jc NEAR $L$handle_ctr32 - vmovdqu xmm3,XMMWORD[((0-32))+r9] + vmovdqu xmm3,XMMWORD[((0-32))+rsi] vpaddb xmm1,xmm14,xmm2 vpxor xmm10,xmm10,xmm15 vpxor xmm11,xmm11,xmm15 $L$resume_ctr32: - vmovdqu XMMWORD[r8],xmm1 + vmovdqu XMMWORD[rdi],xmm1 vpclmulqdq xmm5,xmm7,xmm3,0x10 vpxor xmm12,xmm12,xmm15 - vmovups xmm2,XMMWORD[((16-128))+rcx] + vmovups xmm2,XMMWORD[((16-128))+r9] vpclmulqdq xmm6,xmm7,xmm3,0x01 @@ -73,7 +74,7 @@ $L$resume_ctr32: setnc r12b vpclmulqdq xmm7,xmm7,xmm3,0x11 vaesenc xmm11,xmm11,xmm2 - vmovdqu xmm3,XMMWORD[((16-32))+r9] + vmovdqu xmm3,XMMWORD[((16-32))+rsi] neg r12 vaesenc xmm12,xmm12,xmm2 vpxor xmm6,xmm6,xmm5 @@ -82,7 +83,7 @@ $L$resume_ctr32: vaesenc xmm13,xmm13,xmm2 vpxor xmm4,xmm1,xmm5 and r12,0x60 - vmovups xmm15,XMMWORD[((32-128))+rcx] + vmovups xmm15,XMMWORD[((32-128))+r9] vpclmulqdq xmm1,xmm0,xmm3,0x10 vaesenc xmm14,xmm14,xmm2 @@ -100,10 +101,10 @@ $L$resume_ctr32: mov QWORD[((32+8))+rsp],r13 vaesenc xmm13,xmm13,xmm15 mov QWORD[((40+8))+rsp],r12 - vmovdqu xmm5,XMMWORD[((48-32))+r9] + vmovdqu xmm5,XMMWORD[((48-32))+rsi] vaesenc xmm14,xmm14,xmm15 - vmovups xmm15,XMMWORD[((48-128))+rcx] + vmovups xmm15,XMMWORD[((48-128))+r9] vpxor xmm6,xmm6,xmm1 vpclmulqdq xmm1,xmm0,xmm5,0x00 vaesenc xmm9,xmm9,xmm15 @@ -118,10 +119,10 @@ $L$resume_ctr32: vaesenc xmm12,xmm12,xmm15 vaesenc xmm13,xmm13,xmm15 vpxor xmm4,xmm4,xmm1 - vmovdqu xmm1,XMMWORD[((64-32))+r9] + vmovdqu xmm1,XMMWORD[((64-32))+rsi] vaesenc xmm14,xmm14,xmm15 - vmovups xmm15,XMMWORD[((64-128))+rcx] + vmovups xmm15,XMMWORD[((64-128))+r9] vpxor xmm6,xmm6,xmm2 vpclmulqdq xmm2,xmm0,xmm1,0x00 vaesenc xmm9,xmm9,xmm15 @@ -140,10 +141,10 @@ $L$resume_ctr32: vaesenc xmm13,xmm13,xmm15 mov QWORD[((56+8))+rsp],r12 vpxor xmm4,xmm4,xmm2 - vmovdqu xmm2,XMMWORD[((96-32))+r9] + vmovdqu xmm2,XMMWORD[((96-32))+rsi] vaesenc xmm14,xmm14,xmm15 - vmovups xmm15,XMMWORD[((80-128))+rcx] + vmovups xmm15,XMMWORD[((80-128))+r9] vpxor xmm6,xmm6,xmm3 vpclmulqdq xmm3,xmm0,xmm2,0x00 vaesenc xmm9,xmm9,xmm15 @@ -162,10 +163,10 @@ $L$resume_ctr32: vaesenc xmm13,xmm13,xmm15 mov QWORD[((72+8))+rsp],r12 vpxor xmm4,xmm4,xmm3 - vmovdqu xmm3,XMMWORD[((112-32))+r9] + vmovdqu xmm3,XMMWORD[((112-32))+rsi] vaesenc xmm14,xmm14,xmm15 - vmovups xmm15,XMMWORD[((96-128))+rcx] + vmovups xmm15,XMMWORD[((96-128))+r9] vpxor xmm6,xmm6,xmm5 vpclmulqdq xmm5,xmm8,xmm3,0x10 vaesenc xmm9,xmm9,xmm15 @@ -186,7 +187,7 @@ $L$resume_ctr32: vaesenc xmm14,xmm14,xmm15 vpxor xmm6,xmm6,xmm1 - vmovups xmm15,XMMWORD[((112-128))+rcx] + vmovups xmm15,XMMWORD[((112-128))+r9] vpslldq xmm5,xmm6,8 vpxor xmm4,xmm4,xmm2 vmovdqu xmm3,XMMWORD[16+r11] @@ -204,11 +205,11 @@ $L$resume_ctr32: vaesenc xmm12,xmm12,xmm15 mov QWORD[((104+8))+rsp],r12 vaesenc xmm13,xmm13,xmm15 - vmovups xmm1,XMMWORD[((128-128))+rcx] + vmovups xmm1,XMMWORD[((128-128))+r9] vaesenc xmm14,xmm14,xmm15 vaesenc xmm9,xmm9,xmm1 - vmovups xmm15,XMMWORD[((144-128))+rcx] + vmovups xmm15,XMMWORD[((144-128))+r9] vaesenc xmm10,xmm10,xmm1 vpsrldq xmm6,xmm6,8 vaesenc xmm11,xmm11,xmm1 @@ -219,8 +220,8 @@ $L$resume_ctr32: vaesenc xmm13,xmm13,xmm1 movbe r12,QWORD[r14] vaesenc xmm14,xmm14,xmm1 - vmovups xmm1,XMMWORD[((160-128))+rcx] - cmp ebp,11 + vmovups xmm1,XMMWORD[((160-128))+r9] + cmp r10d,11 jb NEAR $L$enc_tail vaesenc xmm9,xmm9,xmm15 @@ -235,9 +236,9 @@ $L$resume_ctr32: vaesenc xmm11,xmm11,xmm1 vaesenc xmm12,xmm12,xmm1 vaesenc xmm13,xmm13,xmm1 - vmovups xmm15,XMMWORD[((176-128))+rcx] + vmovups xmm15,XMMWORD[((176-128))+r9] vaesenc xmm14,xmm14,xmm1 - vmovups xmm1,XMMWORD[((192-128))+rcx] + vmovups xmm1,XMMWORD[((192-128))+r9] je NEAR $L$enc_tail vaesenc xmm9,xmm9,xmm15 @@ -252,9 +253,9 @@ $L$resume_ctr32: vaesenc xmm11,xmm11,xmm1 vaesenc xmm12,xmm12,xmm1 vaesenc xmm13,xmm13,xmm1 - vmovups xmm15,XMMWORD[((208-128))+rcx] + vmovups xmm15,XMMWORD[((208-128))+r9] vaesenc xmm14,xmm14,xmm1 - vmovups xmm1,XMMWORD[((224-128))+rcx] + vmovups xmm1,XMMWORD[((224-128))+r9] jmp NEAR $L$enc_tail ALIGN 32 @@ -264,7 +265,7 @@ $L$handle_ctr32: vmovdqu xmm5,XMMWORD[48+r11] vpaddd xmm10,xmm6,XMMWORD[64+r11] vpaddd xmm11,xmm6,xmm5 - vmovdqu xmm3,XMMWORD[((0-32))+r9] + vmovdqu xmm3,XMMWORD[((0-32))+rsi] vpaddd xmm12,xmm10,xmm5 vpshufb xmm10,xmm10,xmm0 vpaddd xmm13,xmm11,xmm5 @@ -286,29 +287,32 @@ $L$enc_tail: vpalignr xmm8,xmm4,xmm4,8 vaesenc xmm10,xmm10,xmm15 vpclmulqdq xmm4,xmm4,xmm3,0x10 - vpxor xmm2,xmm1,XMMWORD[rdi] + vpxor xmm2,xmm1,XMMWORD[rcx] vaesenc xmm11,xmm11,xmm15 - vpxor xmm0,xmm1,XMMWORD[16+rdi] + vpxor xmm0,xmm1,XMMWORD[16+rcx] vaesenc xmm12,xmm12,xmm15 - vpxor xmm5,xmm1,XMMWORD[32+rdi] + vpxor xmm5,xmm1,XMMWORD[32+rcx] vaesenc xmm13,xmm13,xmm15 - vpxor xmm6,xmm1,XMMWORD[48+rdi] + vpxor xmm6,xmm1,XMMWORD[48+rcx] vaesenc xmm14,xmm14,xmm15 - vpxor xmm7,xmm1,XMMWORD[64+rdi] - vpxor xmm3,xmm1,XMMWORD[80+rdi] - vmovdqu xmm1,XMMWORD[r8] + vpxor xmm7,xmm1,XMMWORD[64+rcx] + vpxor xmm3,xmm1,XMMWORD[80+rcx] + vmovdqu xmm1,XMMWORD[rdi] vaesenclast xmm9,xmm9,xmm2 vmovdqu xmm2,XMMWORD[32+r11] vaesenclast xmm10,xmm10,xmm0 vpaddb xmm0,xmm1,xmm2 mov QWORD[((112+8))+rsp],r13 - lea rdi,[96+rdi] + lea rcx,[96+rcx] + + prefetcht0 [512+rcx] + prefetcht0 [576+rcx] vaesenclast xmm11,xmm11,xmm5 vpaddb xmm5,xmm0,xmm2 mov QWORD[((120+8))+rsp],r12 - lea rsi,[96+rsi] - vmovdqu xmm15,XMMWORD[((0-128))+rcx] + lea rdx,[96+rdx] + vmovdqu xmm15,XMMWORD[((0-128))+r9] vaesenclast xmm12,xmm12,xmm6 vpaddb xmm6,xmm5,xmm2 vaesenclast xmm13,xmm13,xmm7 @@ -316,21 +320,21 @@ $L$enc_tail: vaesenclast xmm14,xmm14,xmm3 vpaddb xmm3,xmm7,xmm2 - add r10,0x60 - sub rdx,0x6 + add rax,0x60 + sub r8,0x6 jc NEAR $L$6x_done - vmovups XMMWORD[(-96)+rsi],xmm9 + vmovups XMMWORD[(-96)+rdx],xmm9 vpxor xmm9,xmm1,xmm15 - vmovups XMMWORD[(-80)+rsi],xmm10 + vmovups XMMWORD[(-80)+rdx],xmm10 vmovdqa xmm10,xmm0 - vmovups XMMWORD[(-64)+rsi],xmm11 + vmovups XMMWORD[(-64)+rdx],xmm11 vmovdqa xmm11,xmm5 - vmovups XMMWORD[(-48)+rsi],xmm12 + vmovups XMMWORD[(-48)+rdx],xmm12 vmovdqa xmm12,xmm6 - vmovups XMMWORD[(-32)+rsi],xmm13 + vmovups XMMWORD[(-32)+rdx],xmm13 vmovdqa xmm13,xmm7 - vmovups XMMWORD[(-16)+rsi],xmm14 + vmovups XMMWORD[(-16)+rdx],xmm14 vmovdqa xmm14,xmm3 vmovdqu xmm7,XMMWORD[((32+8))+rsp] jmp NEAR $L$oop6x @@ -346,66 +350,83 @@ global aesni_gcm_decrypt ALIGN 32 aesni_gcm_decrypt: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_aesni_gcm_decrypt: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,QWORD[40+rsp] - mov r9,QWORD[48+rsp] + +$L$SEH_begin_aesni_gcm_decrypt_1: + xor rax,rax - xor r10,r10 - - - - cmp rdx,0x60 + cmp r8,0x60 jb NEAR $L$gcm_dec_abort - lea rax,[rsp] - - push rbx - push rbp +$L$SEH_prolog_aesni_gcm_decrypt_2: + mov rbp,rsp + + push rbx + +$L$SEH_prolog_aesni_gcm_decrypt_3: push r12 +$L$SEH_prolog_aesni_gcm_decrypt_4: push r13 +$L$SEH_prolog_aesni_gcm_decrypt_5: push r14 +$L$SEH_prolog_aesni_gcm_decrypt_6: push r15 +$L$SEH_prolog_aesni_gcm_decrypt_7: lea rsp,[((-168))+rsp] - movaps XMMWORD[(-216)+rax],xmm6 - movaps XMMWORD[(-200)+rax],xmm7 - movaps XMMWORD[(-184)+rax],xmm8 - movaps XMMWORD[(-168)+rax],xmm9 - movaps XMMWORD[(-152)+rax],xmm10 - movaps XMMWORD[(-136)+rax],xmm11 - movaps XMMWORD[(-120)+rax],xmm12 - movaps XMMWORD[(-104)+rax],xmm13 - movaps XMMWORD[(-88)+rax],xmm14 - movaps XMMWORD[(-72)+rax],xmm15 -$L$gcm_dec_body: +$L$SEH_prolog_aesni_gcm_decrypt_8: +$L$SEH_prolog_aesni_gcm_decrypt_9: + + + + mov QWORD[16+rbp],rdi +$L$SEH_prolog_aesni_gcm_decrypt_10: + mov QWORD[24+rbp],rsi +$L$SEH_prolog_aesni_gcm_decrypt_11: + mov rdi,QWORD[48+rbp] + mov rsi,QWORD[56+rbp] + + movaps XMMWORD[(-208)+rbp],xmm6 +$L$SEH_prolog_aesni_gcm_decrypt_12: + movaps XMMWORD[(-192)+rbp],xmm7 +$L$SEH_prolog_aesni_gcm_decrypt_13: + movaps XMMWORD[(-176)+rbp],xmm8 +$L$SEH_prolog_aesni_gcm_decrypt_14: + movaps XMMWORD[(-160)+rbp],xmm9 +$L$SEH_prolog_aesni_gcm_decrypt_15: + movaps XMMWORD[(-144)+rbp],xmm10 +$L$SEH_prolog_aesni_gcm_decrypt_16: + movaps XMMWORD[(-128)+rbp],xmm11 +$L$SEH_prolog_aesni_gcm_decrypt_17: + movaps XMMWORD[(-112)+rbp],xmm12 +$L$SEH_prolog_aesni_gcm_decrypt_18: + movaps XMMWORD[(-96)+rbp],xmm13 +$L$SEH_prolog_aesni_gcm_decrypt_19: + movaps XMMWORD[(-80)+rbp],xmm14 +$L$SEH_prolog_aesni_gcm_decrypt_20: + movaps XMMWORD[(-64)+rbp],xmm15 +$L$SEH_prolog_aesni_gcm_decrypt_21: vzeroupper - vmovdqu xmm1,XMMWORD[r8] + mov r12,QWORD[64+rbp] + vmovdqu xmm1,XMMWORD[rdi] add rsp,-128 - mov ebx,DWORD[12+r8] + mov ebx,DWORD[12+rdi] lea r11,[$L$bswap_mask] - lea r14,[((-128))+rcx] + lea r14,[((-128))+r9] mov r15,0xf80 - vmovdqu xmm8,XMMWORD[r9] + vmovdqu xmm8,XMMWORD[r12] and rsp,-128 vmovdqu xmm0,XMMWORD[r11] - lea rcx,[128+rcx] - lea r9,[((32+32))+r9] - mov ebp,DWORD[((240-128))+rcx] + lea r9,[128+r9] + lea rsi,[32+rsi] + mov r10d,DWORD[((240-128))+r9] vpshufb xmm8,xmm8,xmm0 and r14,r15 @@ -417,9 +438,9 @@ $L$gcm_dec_body: sub rsp,r15 $L$dec_no_key_aliasing: - vmovdqu xmm7,XMMWORD[80+rdi] - lea r14,[rdi] - vmovdqu xmm4,XMMWORD[64+rdi] + vmovdqu xmm7,XMMWORD[80+rcx] + mov r14,rcx + vmovdqu xmm4,XMMWORD[64+rcx] @@ -427,16 +448,16 @@ $L$dec_no_key_aliasing: - lea r15,[((-192))+rdx*1+rdi] + lea r15,[((-192))+r8*1+rcx] - vmovdqu xmm5,XMMWORD[48+rdi] - shr rdx,4 - xor r10,r10 - vmovdqu xmm6,XMMWORD[32+rdi] + vmovdqu xmm5,XMMWORD[48+rcx] + shr r8,4 + xor rax,rax + vmovdqu xmm6,XMMWORD[32+rcx] vpshufb xmm7,xmm7,xmm0 - vmovdqu xmm2,XMMWORD[16+rdi] + vmovdqu xmm2,XMMWORD[16+rcx] vpshufb xmm4,xmm4,xmm0 - vmovdqu xmm3,XMMWORD[rdi] + vmovdqu xmm3,XMMWORD[rcx] vpshufb xmm5,xmm5,xmm0 vmovdqu XMMWORD[48+rsp],xmm4 vpshufb xmm6,xmm6,xmm0 @@ -449,57 +470,58 @@ $L$dec_no_key_aliasing: call _aesni_ctr32_ghash_6x - vmovups XMMWORD[(-96)+rsi],xmm9 - vmovups XMMWORD[(-80)+rsi],xmm10 - vmovups XMMWORD[(-64)+rsi],xmm11 - vmovups XMMWORD[(-48)+rsi],xmm12 - vmovups XMMWORD[(-32)+rsi],xmm13 - vmovups XMMWORD[(-16)+rsi],xmm14 + mov r12,QWORD[64+rbp] + vmovups XMMWORD[(-96)+rdx],xmm9 + vmovups XMMWORD[(-80)+rdx],xmm10 + vmovups XMMWORD[(-64)+rdx],xmm11 + vmovups XMMWORD[(-48)+rdx],xmm12 + vmovups XMMWORD[(-32)+rdx],xmm13 + vmovups XMMWORD[(-16)+rdx],xmm14 vpshufb xmm8,xmm8,XMMWORD[r11] - vmovdqu XMMWORD[(-64)+r9],xmm8 + vmovdqu XMMWORD[r12],xmm8 vzeroupper - movaps xmm6,XMMWORD[((-216))+rax] - movaps xmm7,XMMWORD[((-200))+rax] - movaps xmm8,XMMWORD[((-184))+rax] - movaps xmm9,XMMWORD[((-168))+rax] - movaps xmm10,XMMWORD[((-152))+rax] - movaps xmm11,XMMWORD[((-136))+rax] - movaps xmm12,XMMWORD[((-120))+rax] - movaps xmm13,XMMWORD[((-104))+rax] - movaps xmm14,XMMWORD[((-88))+rax] - movaps xmm15,XMMWORD[((-72))+rax] - mov r15,QWORD[((-48))+rax] + movaps xmm6,XMMWORD[((-208))+rbp] + movaps xmm7,XMMWORD[((-192))+rbp] + movaps xmm8,XMMWORD[((-176))+rbp] + movaps xmm9,XMMWORD[((-160))+rbp] + movaps xmm10,XMMWORD[((-144))+rbp] + movaps xmm11,XMMWORD[((-128))+rbp] + movaps xmm12,XMMWORD[((-112))+rbp] + movaps xmm13,XMMWORD[((-96))+rbp] + movaps xmm14,XMMWORD[((-80))+rbp] + movaps xmm15,XMMWORD[((-64))+rbp] + mov rdi,QWORD[16+rbp] + mov rsi,QWORD[24+rbp] + lea rsp,[((-40))+rbp] - mov r14,QWORD[((-40))+rax] + pop r15 - mov r13,QWORD[((-32))+rax] + pop r14 - mov r12,QWORD[((-24))+rax] + pop r13 - mov rbp,QWORD[((-16))+rax] + pop r12 - mov rbx,QWORD[((-8))+rax] + pop rbx - lea rsp,[rax] + pop rbp $L$gcm_dec_abort: - mov rax,r10 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] DB 0F3h,0C3h ;repret +$L$SEH_end_aesni_gcm_decrypt_22: + -$L$SEH_end_aesni_gcm_decrypt: ALIGN 32 _aesni_ctr32_6x: - vmovdqu xmm4,XMMWORD[((0-128))+rcx] + vmovdqu xmm4,XMMWORD[((0-128))+r9] vmovdqu xmm2,XMMWORD[32+r11] - lea r13,[((-1))+rbp] - vmovups xmm15,XMMWORD[((16-128))+rcx] - lea r12,[((32-128))+rcx] + lea r13,[((-1))+r10] + vmovups xmm15,XMMWORD[((16-128))+r9] + lea r12,[((32-128))+r9] vpxor xmm9,xmm1,xmm4 add ebx,100663296 jc NEAR $L$handle_ctr32_2 @@ -531,18 +553,18 @@ $L$oop_ctr32: vmovdqu xmm3,XMMWORD[r12] vaesenc xmm9,xmm9,xmm15 - vpxor xmm4,xmm3,XMMWORD[rdi] + vpxor xmm4,xmm3,XMMWORD[rcx] vaesenc xmm10,xmm10,xmm15 - vpxor xmm5,xmm3,XMMWORD[16+rdi] + vpxor xmm5,xmm3,XMMWORD[16+rcx] vaesenc xmm11,xmm11,xmm15 - vpxor xmm6,xmm3,XMMWORD[32+rdi] + vpxor xmm6,xmm3,XMMWORD[32+rcx] vaesenc xmm12,xmm12,xmm15 - vpxor xmm8,xmm3,XMMWORD[48+rdi] + vpxor xmm8,xmm3,XMMWORD[48+rcx] vaesenc xmm13,xmm13,xmm15 - vpxor xmm2,xmm3,XMMWORD[64+rdi] + vpxor xmm2,xmm3,XMMWORD[64+rcx] vaesenc xmm14,xmm14,xmm15 - vpxor xmm3,xmm3,XMMWORD[80+rdi] - lea rdi,[96+rdi] + vpxor xmm3,xmm3,XMMWORD[80+rcx] + lea rcx,[96+rcx] vaesenclast xmm9,xmm9,xmm4 vaesenclast xmm10,xmm10,xmm5 @@ -550,13 +572,13 @@ $L$oop_ctr32: vaesenclast xmm12,xmm12,xmm8 vaesenclast xmm13,xmm13,xmm2 vaesenclast xmm14,xmm14,xmm3 - vmovups XMMWORD[rsi],xmm9 - vmovups XMMWORD[16+rsi],xmm10 - vmovups XMMWORD[32+rsi],xmm11 - vmovups XMMWORD[48+rsi],xmm12 - vmovups XMMWORD[64+rsi],xmm13 - vmovups XMMWORD[80+rsi],xmm14 - lea rsi,[96+rsi] + vmovups XMMWORD[rdx],xmm9 + vmovups XMMWORD[16+rdx],xmm10 + vmovups XMMWORD[32+rdx],xmm11 + vmovups XMMWORD[48+rdx],xmm12 + vmovups XMMWORD[64+rdx],xmm13 + vmovups XMMWORD[80+rdx],xmm14 + lea rdx,[96+rdx] DB 0F3h,0C3h ;repret ALIGN 32 @@ -588,69 +610,85 @@ global aesni_gcm_encrypt ALIGN 32 aesni_gcm_encrypt: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_aesni_gcm_encrypt: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,QWORD[40+rsp] - mov r9,QWORD[48+rsp] - - +$L$SEH_begin_aesni_gcm_encrypt_1: %ifdef BORINGSSL_DISPATCH_TEST EXTERN BORINGSSL_function_hit mov BYTE[((BORINGSSL_function_hit+2))],1 %endif - xor r10,r10 + xor rax,rax - cmp rdx,0x60*3 + cmp r8,0x60*3 jb NEAR $L$gcm_enc_abort - lea rax,[rsp] - - push rbx - push rbp +$L$SEH_prolog_aesni_gcm_encrypt_2: + mov rbp,rsp + + push rbx + +$L$SEH_prolog_aesni_gcm_encrypt_3: push r12 +$L$SEH_prolog_aesni_gcm_encrypt_4: push r13 +$L$SEH_prolog_aesni_gcm_encrypt_5: push r14 +$L$SEH_prolog_aesni_gcm_encrypt_6: push r15 +$L$SEH_prolog_aesni_gcm_encrypt_7: lea rsp,[((-168))+rsp] - movaps XMMWORD[(-216)+rax],xmm6 - movaps XMMWORD[(-200)+rax],xmm7 - movaps XMMWORD[(-184)+rax],xmm8 - movaps XMMWORD[(-168)+rax],xmm9 - movaps XMMWORD[(-152)+rax],xmm10 - movaps XMMWORD[(-136)+rax],xmm11 - movaps XMMWORD[(-120)+rax],xmm12 - movaps XMMWORD[(-104)+rax],xmm13 - movaps XMMWORD[(-88)+rax],xmm14 - movaps XMMWORD[(-72)+rax],xmm15 -$L$gcm_enc_body: +$L$SEH_prolog_aesni_gcm_encrypt_8: +$L$SEH_prolog_aesni_gcm_encrypt_9: + + + + mov QWORD[16+rbp],rdi +$L$SEH_prolog_aesni_gcm_encrypt_10: + mov QWORD[24+rbp],rsi +$L$SEH_prolog_aesni_gcm_encrypt_11: + mov rdi,QWORD[48+rbp] + mov rsi,QWORD[56+rbp] + + movaps XMMWORD[(-208)+rbp],xmm6 +$L$SEH_prolog_aesni_gcm_encrypt_12: + movaps XMMWORD[(-192)+rbp],xmm7 +$L$SEH_prolog_aesni_gcm_encrypt_13: + movaps XMMWORD[(-176)+rbp],xmm8 +$L$SEH_prolog_aesni_gcm_encrypt_14: + movaps XMMWORD[(-160)+rbp],xmm9 +$L$SEH_prolog_aesni_gcm_encrypt_15: + movaps XMMWORD[(-144)+rbp],xmm10 +$L$SEH_prolog_aesni_gcm_encrypt_16: + movaps XMMWORD[(-128)+rbp],xmm11 +$L$SEH_prolog_aesni_gcm_encrypt_17: + movaps XMMWORD[(-112)+rbp],xmm12 +$L$SEH_prolog_aesni_gcm_encrypt_18: + movaps XMMWORD[(-96)+rbp],xmm13 +$L$SEH_prolog_aesni_gcm_encrypt_19: + movaps XMMWORD[(-80)+rbp],xmm14 +$L$SEH_prolog_aesni_gcm_encrypt_20: + movaps XMMWORD[(-64)+rbp],xmm15 +$L$SEH_prolog_aesni_gcm_encrypt_21: vzeroupper - vmovdqu xmm1,XMMWORD[r8] + vmovdqu xmm1,XMMWORD[rdi] add rsp,-128 - mov ebx,DWORD[12+r8] + mov ebx,DWORD[12+rdi] lea r11,[$L$bswap_mask] - lea r14,[((-128))+rcx] + lea r14,[((-128))+r9] mov r15,0xf80 - lea rcx,[128+rcx] + lea r9,[128+r9] vmovdqu xmm0,XMMWORD[r11] and rsp,-128 - mov ebp,DWORD[((240-128))+rcx] + mov r10d,DWORD[((240-128))+r9] and r14,r15 and r15,rsp @@ -661,7 +699,7 @@ $L$gcm_enc_body: sub rsp,r15 $L$enc_no_key_aliasing: - lea r14,[rsi] + mov r14,rdx @@ -670,9 +708,9 @@ $L$enc_no_key_aliasing: - lea r15,[((-192))+rdx*1+rsi] + lea r15,[((-192))+r8*1+rdx] - shr rdx,4 + shr r8,4 call _aesni_ctr32_6x vpshufb xmm8,xmm9,xmm0 @@ -689,34 +727,35 @@ $L$enc_no_key_aliasing: call _aesni_ctr32_6x - vmovdqu xmm8,XMMWORD[r9] - lea r9,[((32+32))+r9] - sub rdx,12 - mov r10,0x60*2 + mov r12,QWORD[64+rbp] + lea rsi,[32+rsi] + vmovdqu xmm8,XMMWORD[r12] + sub r8,12 + mov rax,0x60*2 vpshufb xmm8,xmm8,xmm0 call _aesni_ctr32_ghash_6x vmovdqu xmm7,XMMWORD[32+rsp] vmovdqu xmm0,XMMWORD[r11] - vmovdqu xmm3,XMMWORD[((0-32))+r9] + vmovdqu xmm3,XMMWORD[((0-32))+rsi] vpunpckhqdq xmm1,xmm7,xmm7 - vmovdqu xmm15,XMMWORD[((32-32))+r9] - vmovups XMMWORD[(-96)+rsi],xmm9 + vmovdqu xmm15,XMMWORD[((32-32))+rsi] + vmovups XMMWORD[(-96)+rdx],xmm9 vpshufb xmm9,xmm9,xmm0 vpxor xmm1,xmm1,xmm7 - vmovups XMMWORD[(-80)+rsi],xmm10 + vmovups XMMWORD[(-80)+rdx],xmm10 vpshufb xmm10,xmm10,xmm0 - vmovups XMMWORD[(-64)+rsi],xmm11 + vmovups XMMWORD[(-64)+rdx],xmm11 vpshufb xmm11,xmm11,xmm0 - vmovups XMMWORD[(-48)+rsi],xmm12 + vmovups XMMWORD[(-48)+rdx],xmm12 vpshufb xmm12,xmm12,xmm0 - vmovups XMMWORD[(-32)+rsi],xmm13 + vmovups XMMWORD[(-32)+rdx],xmm13 vpshufb xmm13,xmm13,xmm0 - vmovups XMMWORD[(-16)+rsi],xmm14 + vmovups XMMWORD[(-16)+rdx],xmm14 vpshufb xmm14,xmm14,xmm0 vmovdqu XMMWORD[16+rsp],xmm9 vmovdqu xmm6,XMMWORD[48+rsp] - vmovdqu xmm0,XMMWORD[((16-32))+r9] + vmovdqu xmm0,XMMWORD[((16-32))+rsi] vpunpckhqdq xmm2,xmm6,xmm6 vpclmulqdq xmm5,xmm7,xmm3,0x00 vpxor xmm2,xmm2,xmm6 @@ -725,19 +764,19 @@ $L$enc_no_key_aliasing: vmovdqu xmm9,XMMWORD[64+rsp] vpclmulqdq xmm4,xmm6,xmm0,0x00 - vmovdqu xmm3,XMMWORD[((48-32))+r9] + vmovdqu xmm3,XMMWORD[((48-32))+rsi] vpxor xmm4,xmm4,xmm5 vpunpckhqdq xmm5,xmm9,xmm9 vpclmulqdq xmm6,xmm6,xmm0,0x11 vpxor xmm5,xmm5,xmm9 vpxor xmm6,xmm6,xmm7 vpclmulqdq xmm2,xmm2,xmm15,0x10 - vmovdqu xmm15,XMMWORD[((80-32))+r9] + vmovdqu xmm15,XMMWORD[((80-32))+rsi] vpxor xmm2,xmm2,xmm1 vmovdqu xmm1,XMMWORD[80+rsp] vpclmulqdq xmm7,xmm9,xmm3,0x00 - vmovdqu xmm0,XMMWORD[((64-32))+r9] + vmovdqu xmm0,XMMWORD[((64-32))+rsi] vpxor xmm7,xmm7,xmm4 vpunpckhqdq xmm4,xmm1,xmm1 vpclmulqdq xmm9,xmm9,xmm3,0x11 @@ -748,19 +787,19 @@ $L$enc_no_key_aliasing: vmovdqu xmm2,XMMWORD[96+rsp] vpclmulqdq xmm6,xmm1,xmm0,0x00 - vmovdqu xmm3,XMMWORD[((96-32))+r9] + vmovdqu xmm3,XMMWORD[((96-32))+rsi] vpxor xmm6,xmm6,xmm7 vpunpckhqdq xmm7,xmm2,xmm2 vpclmulqdq xmm1,xmm1,xmm0,0x11 vpxor xmm7,xmm7,xmm2 vpxor xmm1,xmm1,xmm9 vpclmulqdq xmm4,xmm4,xmm15,0x10 - vmovdqu xmm15,XMMWORD[((128-32))+r9] + vmovdqu xmm15,XMMWORD[((128-32))+rsi] vpxor xmm4,xmm4,xmm5 vpxor xmm8,xmm8,XMMWORD[112+rsp] vpclmulqdq xmm5,xmm2,xmm3,0x00 - vmovdqu xmm0,XMMWORD[((112-32))+r9] + vmovdqu xmm0,XMMWORD[((112-32))+rsi] vpunpckhqdq xmm9,xmm8,xmm8 vpxor xmm5,xmm5,xmm6 vpclmulqdq xmm2,xmm2,xmm3,0x11 @@ -770,17 +809,17 @@ $L$enc_no_key_aliasing: vpxor xmm4,xmm7,xmm4 vpclmulqdq xmm6,xmm8,xmm0,0x00 - vmovdqu xmm3,XMMWORD[((0-32))+r9] + vmovdqu xmm3,XMMWORD[((0-32))+rsi] vpunpckhqdq xmm1,xmm14,xmm14 vpclmulqdq xmm8,xmm8,xmm0,0x11 vpxor xmm1,xmm1,xmm14 vpxor xmm5,xmm6,xmm5 vpclmulqdq xmm9,xmm9,xmm15,0x10 - vmovdqu xmm15,XMMWORD[((32-32))+r9] + vmovdqu xmm15,XMMWORD[((32-32))+rsi] vpxor xmm7,xmm8,xmm2 vpxor xmm6,xmm9,xmm4 - vmovdqu xmm0,XMMWORD[((16-32))+r9] + vmovdqu xmm0,XMMWORD[((16-32))+rsi] vpxor xmm9,xmm7,xmm5 vpclmulqdq xmm4,xmm14,xmm3,0x00 vpxor xmm6,xmm6,xmm9 @@ -794,7 +833,7 @@ $L$enc_no_key_aliasing: vpxor xmm7,xmm7,xmm6 vpclmulqdq xmm5,xmm13,xmm0,0x00 - vmovdqu xmm3,XMMWORD[((48-32))+r9] + vmovdqu xmm3,XMMWORD[((48-32))+rsi] vpxor xmm5,xmm5,xmm4 vpunpckhqdq xmm9,xmm12,xmm12 vpclmulqdq xmm13,xmm13,xmm0,0x11 @@ -802,11 +841,11 @@ $L$enc_no_key_aliasing: vpxor xmm13,xmm13,xmm14 vpalignr xmm14,xmm8,xmm8,8 vpclmulqdq xmm2,xmm2,xmm15,0x10 - vmovdqu xmm15,XMMWORD[((80-32))+r9] + vmovdqu xmm15,XMMWORD[((80-32))+rsi] vpxor xmm2,xmm2,xmm1 vpclmulqdq xmm4,xmm12,xmm3,0x00 - vmovdqu xmm0,XMMWORD[((64-32))+r9] + vmovdqu xmm0,XMMWORD[((64-32))+rsi] vpxor xmm4,xmm4,xmm5 vpunpckhqdq xmm1,xmm11,xmm11 vpclmulqdq xmm12,xmm12,xmm3,0x11 @@ -820,7 +859,7 @@ $L$enc_no_key_aliasing: vxorps xmm8,xmm8,xmm14 vpclmulqdq xmm5,xmm11,xmm0,0x00 - vmovdqu xmm3,XMMWORD[((96-32))+r9] + vmovdqu xmm3,XMMWORD[((96-32))+rsi] vpxor xmm5,xmm5,xmm4 vpunpckhqdq xmm2,xmm10,xmm10 vpclmulqdq xmm11,xmm11,xmm0,0x11 @@ -828,7 +867,7 @@ $L$enc_no_key_aliasing: vpalignr xmm14,xmm8,xmm8,8 vpxor xmm11,xmm11,xmm12 vpclmulqdq xmm1,xmm1,xmm15,0x10 - vmovdqu xmm15,XMMWORD[((128-32))+r9] + vmovdqu xmm15,XMMWORD[((128-32))+rsi] vpxor xmm1,xmm1,xmm9 vxorps xmm14,xmm14,xmm7 @@ -836,7 +875,7 @@ $L$enc_no_key_aliasing: vxorps xmm8,xmm8,xmm14 vpclmulqdq xmm4,xmm10,xmm3,0x00 - vmovdqu xmm0,XMMWORD[((112-32))+r9] + vmovdqu xmm0,XMMWORD[((112-32))+rsi] vpxor xmm4,xmm4,xmm5 vpunpckhqdq xmm9,xmm8,xmm8 vpclmulqdq xmm10,xmm10,xmm3,0x11 @@ -868,166 +907,192 @@ $L$enc_no_key_aliasing: vpclmulqdq xmm8,xmm8,xmm3,0x10 vpxor xmm2,xmm2,xmm7 vpxor xmm8,xmm8,xmm2 + mov r12,QWORD[64+rbp] vpshufb xmm8,xmm8,XMMWORD[r11] - vmovdqu XMMWORD[(-64)+r9],xmm8 + vmovdqu XMMWORD[r12],xmm8 vzeroupper - movaps xmm6,XMMWORD[((-216))+rax] - movaps xmm7,XMMWORD[((-200))+rax] - movaps xmm8,XMMWORD[((-184))+rax] - movaps xmm9,XMMWORD[((-168))+rax] - movaps xmm10,XMMWORD[((-152))+rax] - movaps xmm11,XMMWORD[((-136))+rax] - movaps xmm12,XMMWORD[((-120))+rax] - movaps xmm13,XMMWORD[((-104))+rax] - movaps xmm14,XMMWORD[((-88))+rax] - movaps xmm15,XMMWORD[((-72))+rax] - mov r15,QWORD[((-48))+rax] + movaps xmm6,XMMWORD[((-208))+rbp] + movaps xmm7,XMMWORD[((-192))+rbp] + movaps xmm8,XMMWORD[((-176))+rbp] + movaps xmm9,XMMWORD[((-160))+rbp] + movaps xmm10,XMMWORD[((-144))+rbp] + movaps xmm11,XMMWORD[((-128))+rbp] + movaps xmm12,XMMWORD[((-112))+rbp] + movaps xmm13,XMMWORD[((-96))+rbp] + movaps xmm14,XMMWORD[((-80))+rbp] + movaps xmm15,XMMWORD[((-64))+rbp] + mov rdi,QWORD[16+rbp] + mov rsi,QWORD[24+rbp] + lea rsp,[((-40))+rbp] - mov r14,QWORD[((-40))+rax] + pop r15 - mov r13,QWORD[((-32))+rax] + pop r14 - mov r12,QWORD[((-24))+rax] + pop r13 - mov rbp,QWORD[((-16))+rax] + pop r12 - mov rbx,QWORD[((-8))+rax] + pop rbx - lea rsp,[rax] + pop rbp $L$gcm_enc_abort: - mov rax,r10 - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] DB 0F3h,0C3h ;repret +$L$SEH_end_aesni_gcm_encrypt_22: -$L$SEH_end_aesni_gcm_encrypt: + +section .rdata rdata align=8 ALIGN 64 $L$bswap_mask: -DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 $L$poly: -DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 $L$one_msb: -DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 $L$two_lsb: -DB 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + DB 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 $L$one_lsb: -DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -DB 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108 -DB 101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82 -DB 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 -DB 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 + DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + DB 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108 + DB 101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82 + DB 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112 + DB 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 ALIGN 64 -EXTERN __imp_RtlVirtualUnwind - -ALIGN 16 -gcm_se_handler: - push rsi - push rdi - push rbx - push rbp - push r12 - push r13 - push r14 - push r15 - pushfq - sub rsp,64 - - mov rax,QWORD[120+r8] - mov rbx,QWORD[248+r8] - - mov rsi,QWORD[8+r9] - mov r11,QWORD[56+r9] - - mov r10d,DWORD[r11] - lea r10,[r10*1+rsi] - cmp rbx,r10 - jb NEAR $L$common_seh_tail - - mov rax,QWORD[152+r8] - - mov r10d,DWORD[4+r11] - lea r10,[r10*1+rsi] - cmp rbx,r10 - jae NEAR $L$common_seh_tail - - mov rax,QWORD[120+r8] - - mov r15,QWORD[((-48))+rax] - mov r14,QWORD[((-40))+rax] - mov r13,QWORD[((-32))+rax] - mov r12,QWORD[((-24))+rax] - mov rbp,QWORD[((-16))+rax] - mov rbx,QWORD[((-8))+rax] - mov QWORD[240+r8],r15 - mov QWORD[232+r8],r14 - mov QWORD[224+r8],r13 - mov QWORD[216+r8],r12 - mov QWORD[160+r8],rbp - mov QWORD[144+r8],rbx - - lea rsi,[((-216))+rax] - lea rdi,[512+r8] - mov ecx,20 - DD 0xa548f3fc - -$L$common_seh_tail: - mov rdi,QWORD[8+rax] - mov rsi,QWORD[16+rax] - mov QWORD[152+r8],rax - mov QWORD[168+r8],rsi - mov QWORD[176+r8],rdi - - mov rdi,QWORD[40+r9] - mov rsi,r8 - mov ecx,154 - DD 0xa548f3fc - - mov rsi,r9 - xor rcx,rcx - mov rdx,QWORD[8+rsi] - mov r8,QWORD[rsi] - mov r9,QWORD[16+rsi] - mov r10,QWORD[40+rsi] - lea r11,[56+rsi] - lea r12,[24+rsi] - mov QWORD[32+rsp],r10 - mov QWORD[40+rsp],r11 - mov QWORD[48+rsp],r12 - mov QWORD[56+rsp],rcx - call QWORD[__imp_RtlVirtualUnwind] - - mov eax,1 - add rsp,64 - popfq - pop r15 - pop r14 - pop r13 - pop r12 - pop rbp - pop rbx - pop rdi - pop rsi - DB 0F3h,0C3h ;repret - +section .text section .pdata rdata align=4 ALIGN 4 - DD $L$SEH_begin_aesni_gcm_decrypt wrt ..imagebase - DD $L$SEH_end_aesni_gcm_decrypt wrt ..imagebase - DD $L$SEH_gcm_dec_info wrt ..imagebase + DD $L$SEH_begin_aesni_gcm_decrypt_1 wrt ..imagebase + DD $L$SEH_end_aesni_gcm_decrypt_22 wrt ..imagebase + DD $L$SEH_info_aesni_gcm_decrypt_0 wrt ..imagebase + + DD $L$SEH_begin_aesni_gcm_encrypt_1 wrt ..imagebase + DD $L$SEH_end_aesni_gcm_encrypt_22 wrt ..imagebase + DD $L$SEH_info_aesni_gcm_encrypt_0 wrt ..imagebase + - DD $L$SEH_begin_aesni_gcm_encrypt wrt ..imagebase - DD $L$SEH_end_aesni_gcm_encrypt wrt ..imagebase - DD $L$SEH_gcm_enc_info wrt ..imagebase section .xdata rdata align=8 -ALIGN 8 -$L$SEH_gcm_dec_info: -DB 9,0,0,0 - DD gcm_se_handler wrt ..imagebase - DD $L$gcm_dec_body wrt ..imagebase,$L$gcm_dec_abort wrt ..imagebase -$L$SEH_gcm_enc_info: -DB 9,0,0,0 - DD gcm_se_handler wrt ..imagebase - DD $L$gcm_enc_body wrt ..imagebase,$L$gcm_enc_abort wrt ..imagebase +ALIGN 4 +$L$SEH_info_aesni_gcm_decrypt_0: + DB 1 + DB $L$SEH_prolog_aesni_gcm_decrypt_21-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 33 + DB 213 + DB $L$SEH_prolog_aesni_gcm_decrypt_21-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 248 + DW 9 + DB $L$SEH_prolog_aesni_gcm_decrypt_20-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 232 + DW 8 + DB $L$SEH_prolog_aesni_gcm_decrypt_19-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 216 + DW 7 + DB $L$SEH_prolog_aesni_gcm_decrypt_18-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 200 + DW 6 + DB $L$SEH_prolog_aesni_gcm_decrypt_17-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 184 + DW 5 + DB $L$SEH_prolog_aesni_gcm_decrypt_16-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 168 + DW 4 + DB $L$SEH_prolog_aesni_gcm_decrypt_15-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 152 + DW 3 + DB $L$SEH_prolog_aesni_gcm_decrypt_14-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 136 + DW 2 + DB $L$SEH_prolog_aesni_gcm_decrypt_13-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 120 + DW 1 + DB $L$SEH_prolog_aesni_gcm_decrypt_12-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 104 + DW 0 + DB $L$SEH_prolog_aesni_gcm_decrypt_11-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 100 + DW 29 + DB $L$SEH_prolog_aesni_gcm_decrypt_10-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 116 + DW 28 + DB $L$SEH_prolog_aesni_gcm_decrypt_9-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 3 + DB $L$SEH_prolog_aesni_gcm_decrypt_8-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 1 + DW 21 + DB $L$SEH_prolog_aesni_gcm_decrypt_7-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 240 + DB $L$SEH_prolog_aesni_gcm_decrypt_6-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 224 + DB $L$SEH_prolog_aesni_gcm_decrypt_5-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 208 + DB $L$SEH_prolog_aesni_gcm_decrypt_4-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 192 + DB $L$SEH_prolog_aesni_gcm_decrypt_3-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 48 + DB $L$SEH_prolog_aesni_gcm_decrypt_2-$L$SEH_begin_aesni_gcm_decrypt_1 + DB 80 + +$L$SEH_info_aesni_gcm_encrypt_0: + DB 1 + DB $L$SEH_prolog_aesni_gcm_encrypt_21-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 33 + DB 213 + DB $L$SEH_prolog_aesni_gcm_encrypt_21-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 248 + DW 9 + DB $L$SEH_prolog_aesni_gcm_encrypt_20-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 232 + DW 8 + DB $L$SEH_prolog_aesni_gcm_encrypt_19-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 216 + DW 7 + DB $L$SEH_prolog_aesni_gcm_encrypt_18-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 200 + DW 6 + DB $L$SEH_prolog_aesni_gcm_encrypt_17-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 184 + DW 5 + DB $L$SEH_prolog_aesni_gcm_encrypt_16-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 168 + DW 4 + DB $L$SEH_prolog_aesni_gcm_encrypt_15-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 152 + DW 3 + DB $L$SEH_prolog_aesni_gcm_encrypt_14-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 136 + DW 2 + DB $L$SEH_prolog_aesni_gcm_encrypt_13-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 120 + DW 1 + DB $L$SEH_prolog_aesni_gcm_encrypt_12-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 104 + DW 0 + DB $L$SEH_prolog_aesni_gcm_encrypt_11-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 100 + DW 29 + DB $L$SEH_prolog_aesni_gcm_encrypt_10-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 116 + DW 28 + DB $L$SEH_prolog_aesni_gcm_encrypt_9-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 3 + DB $L$SEH_prolog_aesni_gcm_encrypt_8-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 1 + DW 21 + DB $L$SEH_prolog_aesni_gcm_encrypt_7-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 240 + DB $L$SEH_prolog_aesni_gcm_encrypt_6-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 224 + DB $L$SEH_prolog_aesni_gcm_encrypt_5-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 208 + DB $L$SEH_prolog_aesni_gcm_encrypt_4-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 192 + DB $L$SEH_prolog_aesni_gcm_encrypt_3-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 48 + DB $L$SEH_prolog_aesni_gcm_encrypt_2-$L$SEH_begin_aesni_gcm_encrypt_1 + DB 80 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64-win.asm similarity index 77% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64-win.asm index 342c1523..09cad733 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/aesni-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -28,12 +29,12 @@ EXTERN BORINGSSL_function_hit lea r8,[32+r8] xorps xmm2,xmm0 $L$oop_enc1_1: -DB 102,15,56,220,209 + DB 102,15,56,220,209 dec eax movups xmm1,XMMWORD[r8] lea r8,[16+r8] jnz NEAR $L$oop_enc1_1 -DB 102,15,56,221,209 + DB 102,15,56,221,209 pxor xmm0,xmm0 pxor xmm1,xmm1 movups XMMWORD[rdx],xmm2 @@ -54,12 +55,12 @@ aes_hw_decrypt: lea r8,[32+r8] xorps xmm2,xmm0 $L$oop_dec1_2: -DB 102,15,56,222,209 + DB 102,15,56,222,209 dec eax movups xmm1,XMMWORD[r8] lea r8,[16+r8] jnz NEAR $L$oop_dec1_2 -DB 102,15,56,223,209 + DB 102,15,56,223,209 pxor xmm0,xmm0 pxor xmm1,xmm1 movups XMMWORD[rdx],xmm2 @@ -82,19 +83,19 @@ _aesni_encrypt2: add rax,16 $L$enc_loop2: -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,220,208 -DB 102,15,56,220,216 + DB 102,15,56,220,208 + DB 102,15,56,220,216 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$enc_loop2 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,221,208 -DB 102,15,56,221,216 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,221,208 + DB 102,15,56,221,216 DB 0F3h,0C3h ;repret @@ -113,19 +114,19 @@ _aesni_decrypt2: add rax,16 $L$dec_loop2: -DB 102,15,56,222,209 -DB 102,15,56,222,217 + DB 102,15,56,222,209 + DB 102,15,56,222,217 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,222,208 -DB 102,15,56,222,216 + DB 102,15,56,222,208 + DB 102,15,56,222,216 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$dec_loop2 -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,223,208 -DB 102,15,56,223,216 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,223,208 + DB 102,15,56,223,216 DB 0F3h,0C3h ;repret @@ -145,23 +146,23 @@ _aesni_encrypt3: add rax,16 $L$enc_loop3: -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$enc_loop3 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,221,208 -DB 102,15,56,221,216 -DB 102,15,56,221,224 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,221,208 + DB 102,15,56,221,216 + DB 102,15,56,221,224 DB 0F3h,0C3h ;repret @@ -181,23 +182,23 @@ _aesni_decrypt3: add rax,16 $L$dec_loop3: -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$dec_loop3 -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,223,208 -DB 102,15,56,223,216 -DB 102,15,56,223,224 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,223,208 + DB 102,15,56,223,216 + DB 102,15,56,223,224 DB 0F3h,0C3h ;repret @@ -215,31 +216,31 @@ _aesni_encrypt4: movups xmm0,XMMWORD[32+rcx] lea rcx,[32+rax*1+rcx] neg rax -DB 0x0f,0x1f,0x00 + DB 0x0f,0x1f,0x00 add rax,16 $L$enc_loop4: -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 -DB 102,15,56,220,232 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 + DB 102,15,56,220,232 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$enc_loop4 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,221,208 -DB 102,15,56,221,216 -DB 102,15,56,221,224 -DB 102,15,56,221,232 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,221,208 + DB 102,15,56,221,216 + DB 102,15,56,221,224 + DB 102,15,56,221,232 DB 0F3h,0C3h ;repret @@ -257,31 +258,31 @@ _aesni_decrypt4: movups xmm0,XMMWORD[32+rcx] lea rcx,[32+rax*1+rcx] neg rax -DB 0x0f,0x1f,0x00 + DB 0x0f,0x1f,0x00 add rax,16 $L$dec_loop4: -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$dec_loop4 -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,223,208 -DB 102,15,56,223,216 -DB 102,15,56,223,224 -DB 102,15,56,223,232 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,223,208 + DB 102,15,56,223,216 + DB 102,15,56,223,224 + DB 102,15,56,223,232 DB 0F3h,0C3h ;repret @@ -295,49 +296,49 @@ _aesni_encrypt6: xorps xmm2,xmm0 pxor xmm3,xmm0 pxor xmm4,xmm0 -DB 102,15,56,220,209 + DB 102,15,56,220,209 lea rcx,[32+rax*1+rcx] neg rax -DB 102,15,56,220,217 + DB 102,15,56,220,217 pxor xmm5,xmm0 pxor xmm6,xmm0 -DB 102,15,56,220,225 + DB 102,15,56,220,225 pxor xmm7,xmm0 movups xmm0,XMMWORD[rax*1+rcx] add rax,16 jmp NEAR $L$enc_loop6_enter ALIGN 16 $L$enc_loop6: -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 $L$enc_loop6_enter: -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 -DB 102,15,56,220,232 -DB 102,15,56,220,240 -DB 102,15,56,220,248 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 + DB 102,15,56,220,232 + DB 102,15,56,220,240 + DB 102,15,56,220,248 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$enc_loop6 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,15,56,221,208 -DB 102,15,56,221,216 -DB 102,15,56,221,224 -DB 102,15,56,221,232 -DB 102,15,56,221,240 -DB 102,15,56,221,248 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,15,56,221,208 + DB 102,15,56,221,216 + DB 102,15,56,221,224 + DB 102,15,56,221,232 + DB 102,15,56,221,240 + DB 102,15,56,221,248 DB 0F3h,0C3h ;repret @@ -351,49 +352,49 @@ _aesni_decrypt6: xorps xmm2,xmm0 pxor xmm3,xmm0 pxor xmm4,xmm0 -DB 102,15,56,222,209 + DB 102,15,56,222,209 lea rcx,[32+rax*1+rcx] neg rax -DB 102,15,56,222,217 + DB 102,15,56,222,217 pxor xmm5,xmm0 pxor xmm6,xmm0 -DB 102,15,56,222,225 + DB 102,15,56,222,225 pxor xmm7,xmm0 movups xmm0,XMMWORD[rax*1+rcx] add rax,16 jmp NEAR $L$dec_loop6_enter ALIGN 16 $L$dec_loop6: -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 $L$dec_loop6_enter: -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$dec_loop6 -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,15,56,223,208 -DB 102,15,56,223,216 -DB 102,15,56,223,224 -DB 102,15,56,223,232 -DB 102,15,56,223,240 -DB 102,15,56,223,248 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,15,56,223,208 + DB 102,15,56,223,216 + DB 102,15,56,223,224 + DB 102,15,56,223,232 + DB 102,15,56,223,240 + DB 102,15,56,223,248 DB 0F3h,0C3h ;repret @@ -411,55 +412,55 @@ _aesni_encrypt8: pxor xmm6,xmm0 lea rcx,[32+rax*1+rcx] neg rax -DB 102,15,56,220,209 + DB 102,15,56,220,209 pxor xmm7,xmm0 pxor xmm8,xmm0 -DB 102,15,56,220,217 + DB 102,15,56,220,217 pxor xmm9,xmm0 movups xmm0,XMMWORD[rax*1+rcx] add rax,16 jmp NEAR $L$enc_loop8_inner ALIGN 16 $L$enc_loop8: -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 $L$enc_loop8_inner: -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 $L$enc_loop8_enter: movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 -DB 102,15,56,220,232 -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 + DB 102,15,56,220,232 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$enc_loop8 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 -DB 102,15,56,221,208 -DB 102,15,56,221,216 -DB 102,15,56,221,224 -DB 102,15,56,221,232 -DB 102,15,56,221,240 -DB 102,15,56,221,248 -DB 102,68,15,56,221,192 -DB 102,68,15,56,221,200 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 + DB 102,15,56,221,208 + DB 102,15,56,221,216 + DB 102,15,56,221,224 + DB 102,15,56,221,232 + DB 102,15,56,221,240 + DB 102,15,56,221,248 + DB 102,68,15,56,221,192 + DB 102,68,15,56,221,200 DB 0F3h,0C3h ;repret @@ -477,55 +478,55 @@ _aesni_decrypt8: pxor xmm6,xmm0 lea rcx,[32+rax*1+rcx] neg rax -DB 102,15,56,222,209 + DB 102,15,56,222,209 pxor xmm7,xmm0 pxor xmm8,xmm0 -DB 102,15,56,222,217 + DB 102,15,56,222,217 pxor xmm9,xmm0 movups xmm0,XMMWORD[rax*1+rcx] add rax,16 jmp NEAR $L$dec_loop8_inner ALIGN 16 $L$dec_loop8: -DB 102,15,56,222,209 -DB 102,15,56,222,217 + DB 102,15,56,222,209 + DB 102,15,56,222,217 $L$dec_loop8_inner: -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 $L$dec_loop8_enter: movups xmm1,XMMWORD[rax*1+rcx] add rax,32 -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((-16))+rax*1+rcx] jnz NEAR $L$dec_loop8 -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 -DB 102,15,56,223,208 -DB 102,15,56,223,216 -DB 102,15,56,223,224 -DB 102,15,56,223,232 -DB 102,15,56,223,240 -DB 102,15,56,223,248 -DB 102,68,15,56,223,192 -DB 102,68,15,56,223,200 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 + DB 102,15,56,223,208 + DB 102,15,56,223,216 + DB 102,15,56,223,224 + DB 102,15,56,223,232 + DB 102,15,56,223,240 + DB 102,15,56,223,248 + DB 102,68,15,56,223,192 + DB 102,68,15,56,223,200 DB 0F3h,0C3h ;repret @@ -652,12 +653,12 @@ $L$ecb_enc_one: lea rcx,[32+rcx] xorps xmm2,xmm0 $L$oop_enc1_3: -DB 102,15,56,220,209 + DB 102,15,56,220,209 dec eax movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_enc1_3 -DB 102,15,56,221,209 + DB 102,15,56,221,209 movups XMMWORD[rsi],xmm2 jmp NEAR $L$ecb_ret ALIGN 16 @@ -813,12 +814,12 @@ $L$ecb_dec_one: lea rcx,[32+rcx] xorps xmm2,xmm0 $L$oop_dec1_4: -DB 102,15,56,222,209 + DB 102,15,56,222,209 dec eax movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_dec1_4 -DB 102,15,56,223,209 + DB 102,15,56,223,209 movups XMMWORD[rsi],xmm2 pxor xmm2,xmm2 jmp NEAR $L$ecb_ret @@ -934,12 +935,12 @@ $L$SEH_begin_aes_hw_ctr32_encrypt_blocks: lea rcx,[32+rcx] xorps xmm2,xmm0 $L$oop_enc1_5: -DB 102,15,56,220,209 + DB 102,15,56,220,209 dec edx movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_enc1_5 -DB 102,15,56,221,209 + DB 102,15,56,221,209 pxor xmm0,xmm0 pxor xmm1,xmm1 xorps xmm2,xmm3 @@ -1053,39 +1054,39 @@ ALIGN 16 $L$ctr32_loop6: add r8d,6 movups xmm0,XMMWORD[((-48))+r10*1+rcx] -DB 102,15,56,220,209 + DB 102,15,56,220,209 mov eax,r8d xor eax,ebp -DB 102,15,56,220,217 -DB 0x0f,0x38,0xf1,0x44,0x24,12 + DB 102,15,56,220,217 + DB 0x0f,0x38,0xf1,0x44,0x24,12 lea eax,[1+r8] -DB 102,15,56,220,225 + DB 102,15,56,220,225 xor eax,ebp -DB 0x0f,0x38,0xf1,0x44,0x24,28 -DB 102,15,56,220,233 + DB 0x0f,0x38,0xf1,0x44,0x24,28 + DB 102,15,56,220,233 lea eax,[2+r8] xor eax,ebp -DB 102,15,56,220,241 -DB 0x0f,0x38,0xf1,0x44,0x24,44 + DB 102,15,56,220,241 + DB 0x0f,0x38,0xf1,0x44,0x24,44 lea eax,[3+r8] -DB 102,15,56,220,249 + DB 102,15,56,220,249 movups xmm1,XMMWORD[((-32))+r10*1+rcx] xor eax,ebp -DB 102,15,56,220,208 -DB 0x0f,0x38,0xf1,0x44,0x24,60 + DB 102,15,56,220,208 + DB 0x0f,0x38,0xf1,0x44,0x24,60 lea eax,[4+r8] -DB 102,15,56,220,216 + DB 102,15,56,220,216 xor eax,ebp -DB 0x0f,0x38,0xf1,0x44,0x24,76 -DB 102,15,56,220,224 + DB 0x0f,0x38,0xf1,0x44,0x24,76 + DB 102,15,56,220,224 lea eax,[5+r8] xor eax,ebp -DB 102,15,56,220,232 -DB 0x0f,0x38,0xf1,0x44,0x24,92 + DB 102,15,56,220,232 + DB 0x0f,0x38,0xf1,0x44,0x24,92 mov rax,r10 -DB 102,15,56,220,240 -DB 102,15,56,220,248 + DB 102,15,56,220,240 + DB 102,15,56,220,248 movups xmm0,XMMWORD[((-16))+r10*1+rcx] call $L$enc_loop6 @@ -1134,163 +1135,163 @@ ALIGN 32 $L$ctr32_loop8: add r8d,8 movdqa xmm8,XMMWORD[96+rsp] -DB 102,15,56,220,209 + DB 102,15,56,220,209 mov r9d,r8d movdqa xmm9,XMMWORD[112+rsp] -DB 102,15,56,220,217 + DB 102,15,56,220,217 bswap r9d movups xmm0,XMMWORD[((32-128))+rcx] -DB 102,15,56,220,225 + DB 102,15,56,220,225 xor r9d,ebp nop -DB 102,15,56,220,233 + DB 102,15,56,220,233 mov DWORD[((0+12))+rsp],r9d lea r9,[1+r8] -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((48-128))+rcx] bswap r9d -DB 102,15,56,220,208 -DB 102,15,56,220,216 + DB 102,15,56,220,208 + DB 102,15,56,220,216 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,224 -DB 102,15,56,220,232 + DB 0x66,0x90 + DB 102,15,56,220,224 + DB 102,15,56,220,232 mov DWORD[((16+12))+rsp],r9d lea r9,[2+r8] -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((64-128))+rcx] bswap r9d -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,225 -DB 102,15,56,220,233 + DB 0x66,0x90 + DB 102,15,56,220,225 + DB 102,15,56,220,233 mov DWORD[((32+12))+rsp],r9d lea r9,[3+r8] -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((80-128))+rcx] bswap r9d -DB 102,15,56,220,208 -DB 102,15,56,220,216 + DB 102,15,56,220,208 + DB 102,15,56,220,216 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,224 -DB 102,15,56,220,232 + DB 0x66,0x90 + DB 102,15,56,220,224 + DB 102,15,56,220,232 mov DWORD[((48+12))+rsp],r9d lea r9,[4+r8] -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((96-128))+rcx] bswap r9d -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,225 -DB 102,15,56,220,233 + DB 0x66,0x90 + DB 102,15,56,220,225 + DB 102,15,56,220,233 mov DWORD[((64+12))+rsp],r9d lea r9,[5+r8] -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((112-128))+rcx] bswap r9d -DB 102,15,56,220,208 -DB 102,15,56,220,216 + DB 102,15,56,220,208 + DB 102,15,56,220,216 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,224 -DB 102,15,56,220,232 + DB 0x66,0x90 + DB 102,15,56,220,224 + DB 102,15,56,220,232 mov DWORD[((80+12))+rsp],r9d lea r9,[6+r8] -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((128-128))+rcx] bswap r9d -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 xor r9d,ebp -DB 0x66,0x90 -DB 102,15,56,220,225 -DB 102,15,56,220,233 + DB 0x66,0x90 + DB 102,15,56,220,225 + DB 102,15,56,220,233 mov DWORD[((96+12))+rsp],r9d lea r9,[7+r8] -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((144-128))+rcx] bswap r9d -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 xor r9d,ebp movdqu xmm10,XMMWORD[rdi] -DB 102,15,56,220,232 + DB 102,15,56,220,232 mov DWORD[((112+12))+rsp],r9d cmp eax,11 -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((160-128))+rcx] jb NEAR $L$ctr32_enc_done -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((176-128))+rcx] -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 -DB 102,15,56,220,232 -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 + DB 102,15,56,220,232 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((192-128))+rcx] je NEAR $L$ctr32_enc_done -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movups xmm1,XMMWORD[((208-128))+rcx] -DB 102,15,56,220,208 -DB 102,15,56,220,216 -DB 102,15,56,220,224 -DB 102,15,56,220,232 -DB 102,15,56,220,240 -DB 102,15,56,220,248 -DB 102,68,15,56,220,192 -DB 102,68,15,56,220,200 + DB 102,15,56,220,208 + DB 102,15,56,220,216 + DB 102,15,56,220,224 + DB 102,15,56,220,232 + DB 102,15,56,220,240 + DB 102,15,56,220,248 + DB 102,68,15,56,220,192 + DB 102,68,15,56,220,200 movups xmm0,XMMWORD[((224-128))+rcx] jmp NEAR $L$ctr32_enc_done @@ -1306,36 +1307,38 @@ $L$ctr32_enc_done: pxor xmm13,xmm0 movdqu xmm15,XMMWORD[80+rdi] pxor xmm14,xmm0 + prefetcht0 [448+rdi] + prefetcht0 [512+rdi] pxor xmm15,xmm0 -DB 102,15,56,220,209 -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 -DB 102,15,56,220,241 -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 -DB 102,68,15,56,220,201 + DB 102,15,56,220,209 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 + DB 102,15,56,220,241 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 + DB 102,68,15,56,220,201 movdqu xmm1,XMMWORD[96+rdi] lea rdi,[128+rdi] -DB 102,65,15,56,221,210 + DB 102,65,15,56,221,210 pxor xmm1,xmm0 movdqu xmm10,XMMWORD[((112-128))+rdi] -DB 102,65,15,56,221,219 + DB 102,65,15,56,221,219 pxor xmm10,xmm0 movdqa xmm11,XMMWORD[rsp] -DB 102,65,15,56,221,228 -DB 102,65,15,56,221,237 + DB 102,65,15,56,221,228 + DB 102,65,15,56,221,237 movdqa xmm12,XMMWORD[16+rsp] movdqa xmm13,XMMWORD[32+rsp] -DB 102,65,15,56,221,246 -DB 102,65,15,56,221,255 + DB 102,65,15,56,221,246 + DB 102,65,15,56,221,255 movdqa xmm14,XMMWORD[48+rsp] movdqa xmm15,XMMWORD[64+rsp] -DB 102,68,15,56,221,193 + DB 102,68,15,56,221,193 movdqa xmm0,XMMWORD[80+rsp] movups xmm1,XMMWORD[((16-128))+rcx] -DB 102,69,15,56,221,202 + DB 102,69,15,56,221,202 movups XMMWORD[rsi],xmm2 movdqa xmm2,xmm11 @@ -1374,19 +1377,19 @@ $L$ctr32_tail: pxor xmm9,xmm9 movups xmm0,XMMWORD[16+rcx] -DB 102,15,56,220,209 -DB 102,15,56,220,217 + DB 102,15,56,220,209 + DB 102,15,56,220,217 lea rcx,[((32-16))+rax*1+rcx] neg rax -DB 102,15,56,220,225 + DB 102,15,56,220,225 add rax,16 movups xmm10,XMMWORD[rdi] -DB 102,15,56,220,233 -DB 102,15,56,220,241 + DB 102,15,56,220,233 + DB 102,15,56,220,241 movups xmm11,XMMWORD[16+rdi] movups xmm12,XMMWORD[32+rdi] -DB 102,15,56,220,249 -DB 102,68,15,56,220,193 + DB 102,15,56,220,249 + DB 102,68,15,56,220,193 call $L$enc_loop8_enter @@ -1417,20 +1420,20 @@ DB 102,68,15,56,220,193 ALIGN 32 $L$ctr32_loop4: -DB 102,15,56,220,209 + DB 102,15,56,220,209 lea rcx,[16+rcx] dec eax -DB 102,15,56,220,217 -DB 102,15,56,220,225 -DB 102,15,56,220,233 + DB 102,15,56,220,217 + DB 102,15,56,220,225 + DB 102,15,56,220,233 movups xmm1,XMMWORD[rcx] jnz NEAR $L$ctr32_loop4 -DB 102,15,56,221,209 -DB 102,15,56,221,217 + DB 102,15,56,221,209 + DB 102,15,56,221,217 movups xmm10,XMMWORD[rdi] movups xmm11,XMMWORD[16+rdi] -DB 102,15,56,221,225 -DB 102,15,56,221,233 + DB 102,15,56,221,225 + DB 102,15,56,221,233 movups xmm12,XMMWORD[32+rdi] movups xmm13,XMMWORD[48+rdi] @@ -1446,16 +1449,16 @@ DB 102,15,56,221,233 ALIGN 32 $L$ctr32_loop3: -DB 102,15,56,220,209 + DB 102,15,56,220,209 lea rcx,[16+rcx] dec eax -DB 102,15,56,220,217 -DB 102,15,56,220,225 + DB 102,15,56,220,217 + DB 102,15,56,220,225 movups xmm1,XMMWORD[rcx] jnz NEAR $L$ctr32_loop3 -DB 102,15,56,221,209 -DB 102,15,56,221,217 -DB 102,15,56,221,225 + DB 102,15,56,221,209 + DB 102,15,56,221,217 + DB 102,15,56,221,225 movups xmm10,XMMWORD[rdi] xorps xmm2,xmm10 @@ -1560,12 +1563,12 @@ $L$cbc_enc_loop: lea rcx,[32+rcx] xorps xmm2,xmm3 $L$oop_enc1_6: -DB 102,15,56,220,209 + DB 102,15,56,220,209 dec eax movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_enc1_6 -DB 102,15,56,221,209 + DB 102,15,56,221,209 mov eax,r10d mov rcx,r11 movups XMMWORD[rsi],xmm2 @@ -1611,12 +1614,12 @@ $L$cbc_decrypt: lea rcx,[32+rcx] xorps xmm2,xmm0 $L$oop_dec1_7: -DB 102,15,56,222,209 + DB 102,15,56,222,209 dec r10d movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_dec1_7 -DB 102,15,56,223,209 + DB 102,15,56,223,209 pxor xmm0,xmm0 pxor xmm1,xmm1 movdqu XMMWORD[r8],xmm4 @@ -1692,166 +1695,166 @@ $L$cbc_dec_loop8_enter: pxor xmm7,xmm0 pxor xmm8,xmm0 -DB 102,15,56,222,209 + DB 102,15,56,222,209 pxor xmm9,xmm0 movups xmm0,XMMWORD[((32-112))+rcx] -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 adc rbp,0 and rbp,128 -DB 102,68,15,56,222,201 + DB 102,68,15,56,222,201 add rbp,rdi movups xmm1,XMMWORD[((48-112))+rcx] -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((64-112))+rcx] nop -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movups xmm1,XMMWORD[((80-112))+rcx] nop -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((96-112))+rcx] nop -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movups xmm1,XMMWORD[((112-112))+rcx] nop -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((128-112))+rcx] nop -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movups xmm1,XMMWORD[((144-112))+rcx] cmp eax,11 -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((160-112))+rcx] jb NEAR $L$cbc_dec_done -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movups xmm1,XMMWORD[((176-112))+rcx] nop -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((192-112))+rcx] je NEAR $L$cbc_dec_done -DB 102,15,56,222,209 -DB 102,15,56,222,217 -DB 102,15,56,222,225 -DB 102,15,56,222,233 -DB 102,15,56,222,241 -DB 102,15,56,222,249 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,15,56,222,209 + DB 102,15,56,222,217 + DB 102,15,56,222,225 + DB 102,15,56,222,233 + DB 102,15,56,222,241 + DB 102,15,56,222,249 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movups xmm1,XMMWORD[((208-112))+rcx] nop -DB 102,15,56,222,208 -DB 102,15,56,222,216 -DB 102,15,56,222,224 -DB 102,15,56,222,232 -DB 102,15,56,222,240 -DB 102,15,56,222,248 -DB 102,68,15,56,222,192 -DB 102,68,15,56,222,200 + DB 102,15,56,222,208 + DB 102,15,56,222,216 + DB 102,15,56,222,224 + DB 102,15,56,222,232 + DB 102,15,56,222,240 + DB 102,15,56,222,248 + DB 102,68,15,56,222,192 + DB 102,68,15,56,222,200 movups xmm0,XMMWORD[((224-112))+rcx] jmp NEAR $L$cbc_dec_done ALIGN 16 $L$cbc_dec_done: -DB 102,15,56,222,209 -DB 102,15,56,222,217 + DB 102,15,56,222,209 + DB 102,15,56,222,217 pxor xmm10,xmm0 pxor xmm11,xmm0 -DB 102,15,56,222,225 -DB 102,15,56,222,233 + DB 102,15,56,222,225 + DB 102,15,56,222,233 pxor xmm12,xmm0 pxor xmm13,xmm0 -DB 102,15,56,222,241 -DB 102,15,56,222,249 + DB 102,15,56,222,241 + DB 102,15,56,222,249 pxor xmm14,xmm0 pxor xmm15,xmm0 -DB 102,68,15,56,222,193 -DB 102,68,15,56,222,201 + DB 102,68,15,56,222,193 + DB 102,68,15,56,222,201 movdqu xmm1,XMMWORD[80+rdi] -DB 102,65,15,56,223,210 + DB 102,65,15,56,223,210 movdqu xmm10,XMMWORD[96+rdi] pxor xmm1,xmm0 -DB 102,65,15,56,223,219 + DB 102,65,15,56,223,219 pxor xmm10,xmm0 movdqu xmm0,XMMWORD[112+rdi] -DB 102,65,15,56,223,228 + DB 102,65,15,56,223,228 lea rdi,[128+rdi] movdqu xmm11,XMMWORD[rbp] -DB 102,65,15,56,223,237 -DB 102,65,15,56,223,246 + DB 102,65,15,56,223,237 + DB 102,65,15,56,223,246 movdqu xmm12,XMMWORD[16+rbp] movdqu xmm13,XMMWORD[32+rbp] -DB 102,65,15,56,223,255 -DB 102,68,15,56,223,193 + DB 102,65,15,56,223,255 + DB 102,68,15,56,223,193 movdqu xmm14,XMMWORD[48+rbp] movdqu xmm15,XMMWORD[64+rbp] -DB 102,69,15,56,223,202 + DB 102,69,15,56,223,202 movdqa xmm10,xmm0 movdqu xmm1,XMMWORD[80+rbp] movups xmm0,XMMWORD[((-112))+rcx] @@ -2040,12 +2043,12 @@ $L$cbc_dec_one: lea rcx,[32+rcx] xorps xmm2,xmm0 $L$oop_dec1_8: -DB 102,15,56,222,209 + DB 102,15,56,222,209 dec eax movups xmm1,XMMWORD[rcx] lea rcx,[16+rcx] jnz NEAR $L$oop_dec1_8 -DB 102,15,56,223,209 + DB 102,15,56,223,209 xorps xmm2,xmm10 movaps xmm10,xmm11 jmp NEAR $L$cbc_dec_tail_collected @@ -2156,7 +2159,7 @@ global aes_hw_set_decrypt_key ALIGN 16 aes_hw_set_decrypt_key: -DB 0x48,0x83,0xEC,0x08 + DB 0x48,0x83,0xEC,0x08 call __aesni_set_encrypt_key shl edx,4 @@ -2174,8 +2177,8 @@ DB 0x48,0x83,0xEC,0x08 $L$dec_key_inverse: movups xmm0,XMMWORD[r8] movups xmm1,XMMWORD[rcx] -DB 102,15,56,219,192 -DB 102,15,56,219,201 + DB 102,15,56,219,192 + DB 102,15,56,219,201 lea r8,[16+r8] lea rcx,[((-16))+rcx] movups XMMWORD[16+rcx],xmm0 @@ -2184,7 +2187,7 @@ DB 102,15,56,219,201 ja NEAR $L$dec_key_inverse movups xmm0,XMMWORD[r8] -DB 102,15,56,219,192 + DB 102,15,56,219,192 pxor xmm1,xmm1 movups XMMWORD[rcx],xmm0 pxor xmm0,xmm0 @@ -2204,7 +2207,7 @@ __aesni_set_encrypt_key: %ifdef BORINGSSL_DISPATCH_TEST mov BYTE[((BORINGSSL_function_hit+3))],1 %endif -DB 0x48,0x83,0xEC,0x08 + DB 0x48,0x83,0xEC,0x08 mov rax,-1 test rcx,rcx @@ -2231,25 +2234,25 @@ $L$10rounds: je NEAR $L$10rounds_alt movups XMMWORD[r8],xmm0 -DB 102,15,58,223,200,1 + DB 102,15,58,223,200,1 call $L$key_expansion_128_cold -DB 102,15,58,223,200,2 + DB 102,15,58,223,200,2 call $L$key_expansion_128 -DB 102,15,58,223,200,4 + DB 102,15,58,223,200,4 call $L$key_expansion_128 -DB 102,15,58,223,200,8 + DB 102,15,58,223,200,8 call $L$key_expansion_128 -DB 102,15,58,223,200,16 + DB 102,15,58,223,200,16 call $L$key_expansion_128 -DB 102,15,58,223,200,32 + DB 102,15,58,223,200,32 call $L$key_expansion_128 -DB 102,15,58,223,200,64 + DB 102,15,58,223,200,64 call $L$key_expansion_128 -DB 102,15,58,223,200,128 + DB 102,15,58,223,200,128 call $L$key_expansion_128 -DB 102,15,58,223,200,27 + DB 102,15,58,223,200,27 call $L$key_expansion_128 -DB 102,15,58,223,200,54 + DB 102,15,58,223,200,54 call $L$key_expansion_128 movups XMMWORD[rax],xmm0 mov DWORD[80+rax],edx @@ -2268,7 +2271,7 @@ $L$10rounds_alt: ALIGN 16 $L$oop_key128: DB 102,15,56,0,197 -DB 102,15,56,221,196 + DB 102,15,56,221,196 pslld xmm4,1 lea rax,[16+rax] @@ -2290,7 +2293,7 @@ DB 102,15,56,221,196 movdqa xmm4,XMMWORD[$L$key_rcon1b] DB 102,15,56,0,197 -DB 102,15,56,221,196 + DB 102,15,56,221,196 pslld xmm4,1 movdqa xmm3,xmm2 @@ -2306,7 +2309,7 @@ DB 102,15,56,221,196 movdqa xmm2,xmm0 DB 102,15,56,0,197 -DB 102,15,56,221,196 + DB 102,15,56,221,196 movdqa xmm3,xmm2 pslldq xmm2,4 @@ -2331,21 +2334,21 @@ $L$12rounds: je NEAR $L$12rounds_alt movups XMMWORD[r8],xmm0 -DB 102,15,58,223,202,1 + DB 102,15,58,223,202,1 call $L$key_expansion_192a_cold -DB 102,15,58,223,202,2 + DB 102,15,58,223,202,2 call $L$key_expansion_192b -DB 102,15,58,223,202,4 + DB 102,15,58,223,202,4 call $L$key_expansion_192a -DB 102,15,58,223,202,8 + DB 102,15,58,223,202,8 call $L$key_expansion_192b -DB 102,15,58,223,202,16 + DB 102,15,58,223,202,16 call $L$key_expansion_192a -DB 102,15,58,223,202,32 + DB 102,15,58,223,202,32 call $L$key_expansion_192b -DB 102,15,58,223,202,64 + DB 102,15,58,223,202,64 call $L$key_expansion_192a -DB 102,15,58,223,202,128 + DB 102,15,58,223,202,128 call $L$key_expansion_192b movups XMMWORD[rax],xmm0 mov DWORD[48+rax],edx @@ -2365,7 +2368,7 @@ $L$oop_key192: movq QWORD[rax],xmm2 movdqa xmm1,xmm2 DB 102,15,56,0,213 -DB 102,15,56,221,212 + DB 102,15,56,221,212 pslld xmm4,1 lea rax,[24+rax] @@ -2403,31 +2406,31 @@ $L$14rounds: movups XMMWORD[r8],xmm0 movups XMMWORD[16+r8],xmm2 -DB 102,15,58,223,202,1 + DB 102,15,58,223,202,1 call $L$key_expansion_256a_cold -DB 102,15,58,223,200,1 + DB 102,15,58,223,200,1 call $L$key_expansion_256b -DB 102,15,58,223,202,2 + DB 102,15,58,223,202,2 call $L$key_expansion_256a -DB 102,15,58,223,200,2 + DB 102,15,58,223,200,2 call $L$key_expansion_256b -DB 102,15,58,223,202,4 + DB 102,15,58,223,202,4 call $L$key_expansion_256a -DB 102,15,58,223,200,4 + DB 102,15,58,223,200,4 call $L$key_expansion_256b -DB 102,15,58,223,202,8 + DB 102,15,58,223,202,8 call $L$key_expansion_256a -DB 102,15,58,223,200,8 + DB 102,15,58,223,200,8 call $L$key_expansion_256b -DB 102,15,58,223,202,16 + DB 102,15,58,223,202,16 call $L$key_expansion_256a -DB 102,15,58,223,200,16 + DB 102,15,58,223,200,16 call $L$key_expansion_256b -DB 102,15,58,223,202,32 + DB 102,15,58,223,202,32 call $L$key_expansion_256a -DB 102,15,58,223,200,32 + DB 102,15,58,223,200,32 call $L$key_expansion_256b -DB 102,15,58,223,202,64 + DB 102,15,58,223,202,64 call $L$key_expansion_256a movups XMMWORD[rax],xmm0 mov DWORD[16+rax],edx @@ -2447,7 +2450,7 @@ $L$14rounds_alt: ALIGN 16 $L$oop_key256: DB 102,15,56,0,213 -DB 102,15,56,221,212 + DB 102,15,56,221,212 movdqa xmm3,xmm0 pslldq xmm0,4 @@ -2466,7 +2469,7 @@ DB 102,15,56,221,212 pshufd xmm2,xmm0,0xff pxor xmm3,xmm3 -DB 102,15,56,221,211 + DB 102,15,56,221,211 movdqa xmm3,xmm1 pslldq xmm1,4 @@ -2574,9 +2577,10 @@ $L$key_expansion_256b: DB 0F3h,0C3h ;repret +section .rdata rdata align=8 ALIGN 64 $L$bswap_mask: -DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 $L$increment32: DD 6,6,6,0 $L$increment64: @@ -2584,7 +2588,7 @@ $L$increment64: $L$xts_magic: DD 0x87,0,1,0 $L$increment1: -DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 $L$key_rotate: DD 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d $L$key_rotate192: @@ -2594,11 +2598,13 @@ $L$key_rcon1: $L$key_rcon1b: DD 0x1b,0x1b,0x1b,0x1b -DB 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69 -DB 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 -DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 -DB 115,108,46,111,114,103,62,0 + DB 65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69 + DB 83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83 + DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 + DB 115,108,46,111,114,103,62,0 ALIGN 64 +section .text + EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -2791,16 +2797,20 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_ecb: -DB 9,0,0,0 + DB 9,0,0,0 DD ecb_ccm64_se_handler wrt ..imagebase DD $L$ecb_enc_body wrt ..imagebase,$L$ecb_enc_ret wrt ..imagebase $L$SEH_info_ctr32: -DB 9,0,0,0 + DB 9,0,0,0 DD ctr_xts_se_handler wrt ..imagebase DD $L$ctr32_body wrt ..imagebase,$L$ctr32_epilogue wrt ..imagebase $L$SEH_info_cbc: -DB 9,0,0,0 + DB 9,0,0,0 DD cbc_se_handler wrt ..imagebase $L$SEH_info_key: -DB 0x01,0x04,0x01,0x00 -DB 0x04,0x02,0x00,0x00 + DB 0x01,0x04,0x01,0x00 + DB 0x04,0x02,0x00,0x00 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-win.asm similarity index 76% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-win.asm index 434ba10e..b3d54e6a 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -21,14 +22,13 @@ global gcm_gmult_ssse3 ALIGN 16 gcm_gmult_ssse3: -$L$gmult_seh_begin: +$L$SEH_begin_gcm_gmult_ssse3_1: sub rsp,40 -$L$gmult_seh_allocstack: +$L$SEH_prolog_gcm_gmult_ssse3_2: movdqa XMMWORD[rsp],xmm6 -$L$gmult_seh_save_xmm6: +$L$SEH_prolog_gcm_gmult_ssse3_3: movdqa XMMWORD[16+rsp],xmm10 -$L$gmult_seh_save_xmm10: -$L$gmult_seh_prolog_end: +$L$SEH_prolog_gcm_gmult_ssse3_4: movdqu xmm0,XMMWORD[rcx] movdqa xmm10,XMMWORD[$L$reverse_bytes] movdqa xmm2,XMMWORD[$L$low4_mask] @@ -207,8 +207,8 @@ DB 102,65,15,56,0,210 movdqa xmm10,XMMWORD[16+rsp] add rsp,40 DB 0F3h,0C3h ;repret -$L$gmult_seh_end: +$L$SEH_end_gcm_gmult_ssse3_5: @@ -219,17 +219,16 @@ $L$gmult_seh_end: global gcm_ghash_ssse3 ALIGN 16 gcm_ghash_ssse3: -$L$ghash_seh_begin: +$L$SEH_begin_gcm_ghash_ssse3_1: sub rsp,56 -$L$ghash_seh_allocstack: +$L$SEH_prolog_gcm_ghash_ssse3_2: movdqa XMMWORD[rsp],xmm6 -$L$ghash_seh_save_xmm6: +$L$SEH_prolog_gcm_ghash_ssse3_3: movdqa XMMWORD[16+rsp],xmm10 -$L$ghash_seh_save_xmm10: +$L$SEH_prolog_gcm_ghash_ssse3_4: movdqa XMMWORD[32+rsp],xmm11 -$L$ghash_seh_save_xmm11: -$L$ghash_seh_prolog_end: +$L$SEH_prolog_gcm_ghash_ssse3_5: movdqu xmm0,XMMWORD[rcx] movdqa xmm10,XMMWORD[$L$reverse_bytes] movdqa xmm11,XMMWORD[$L$low4_mask] @@ -431,65 +430,65 @@ DB 102,65,15,56,0,194 movdqa xmm11,XMMWORD[32+rsp] add rsp,56 DB 0F3h,0C3h ;repret -$L$ghash_seh_end: - + +$L$SEH_end_gcm_ghash_ssse3_6: +section .rdata rdata align=8 ALIGN 16 $L$reverse_bytes: -DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 $L$low4_mask: DQ 0x0f0f0f0f0f0f0f0f,0x0f0f0f0f0f0f0f0f +section .text + section .pdata rdata align=4 ALIGN 4 - DD $L$gmult_seh_begin wrt ..imagebase - DD $L$gmult_seh_end wrt ..imagebase - DD $L$gmult_seh_info wrt ..imagebase + DD $L$SEH_begin_gcm_gmult_ssse3_1 wrt ..imagebase + DD $L$SEH_end_gcm_gmult_ssse3_5 wrt ..imagebase + DD $L$SEH_info_gcm_gmult_ssse3_0 wrt ..imagebase + + DD $L$SEH_begin_gcm_ghash_ssse3_1 wrt ..imagebase + DD $L$SEH_end_gcm_ghash_ssse3_6 wrt ..imagebase + DD $L$SEH_info_gcm_ghash_ssse3_0 wrt ..imagebase - DD $L$ghash_seh_begin wrt ..imagebase - DD $L$ghash_seh_end wrt ..imagebase - DD $L$ghash_seh_info wrt ..imagebase section .xdata rdata align=8 -ALIGN 8 -$L$gmult_seh_info: -DB 1 -DB $L$gmult_seh_prolog_end-$L$gmult_seh_begin -DB 5 -DB 0 - -DB $L$gmult_seh_save_xmm10-$L$gmult_seh_begin -DB 168 +ALIGN 4 +$L$SEH_info_gcm_gmult_ssse3_0: + DB 1 + DB $L$SEH_prolog_gcm_gmult_ssse3_4-$L$SEH_begin_gcm_gmult_ssse3_1 + DB 5 + DB 0 + DB $L$SEH_prolog_gcm_gmult_ssse3_4-$L$SEH_begin_gcm_gmult_ssse3_1 + DB 168 DW 1 - -DB $L$gmult_seh_save_xmm6-$L$gmult_seh_begin -DB 104 + DB $L$SEH_prolog_gcm_gmult_ssse3_3-$L$SEH_begin_gcm_gmult_ssse3_1 + DB 104 DW 0 + DB $L$SEH_prolog_gcm_gmult_ssse3_2-$L$SEH_begin_gcm_gmult_ssse3_1 + DB 66 -DB $L$gmult_seh_allocstack-$L$gmult_seh_begin -DB 66 - -ALIGN 8 -$L$ghash_seh_info: -DB 1 -DB $L$ghash_seh_prolog_end-$L$ghash_seh_begin -DB 7 -DB 0 - -DB $L$ghash_seh_save_xmm11-$L$ghash_seh_begin -DB 184 +$L$SEH_info_gcm_ghash_ssse3_0: + DB 1 + DB $L$SEH_prolog_gcm_ghash_ssse3_5-$L$SEH_begin_gcm_ghash_ssse3_1 + DB 7 + DB 0 + DB $L$SEH_prolog_gcm_ghash_ssse3_5-$L$SEH_begin_gcm_ghash_ssse3_1 + DB 184 DW 2 - -DB $L$ghash_seh_save_xmm10-$L$ghash_seh_begin -DB 168 + DB $L$SEH_prolog_gcm_ghash_ssse3_4-$L$SEH_begin_gcm_ghash_ssse3_1 + DB 168 DW 1 - -DB $L$ghash_seh_save_xmm6-$L$ghash_seh_begin -DB 104 + DB $L$SEH_prolog_gcm_ghash_ssse3_3-$L$SEH_begin_gcm_ghash_ssse3_1 + DB 104 DW 0 - -DB $L$ghash_seh_allocstack-$L$ghash_seh_begin -DB 98 + DB $L$SEH_prolog_gcm_ghash_ssse3_2-$L$SEH_begin_gcm_ghash_ssse3_1 + DB 98 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64-win.asm similarity index 80% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64-win.asm index 194ea8df..b2323ee6 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/ghash-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -17,11 +18,12 @@ global gcm_init_clmul ALIGN 16 gcm_init_clmul: +$L$SEH_begin_gcm_init_clmul_1: $L$_init_clmul: -$L$SEH_begin_gcm_init_clmul: - -DB 0x48,0x83,0xec,0x18 -DB 0x0f,0x29,0x34,0x24 + sub rsp,0x18 +$L$SEH_prolog_gcm_init_clmul_2: + movaps XMMWORD[rsp],xmm6 +$L$SEH_prolog_gcm_init_clmul_3: movdqu xmm2,XMMWORD[rdx] pshufd xmm2,xmm2,78 @@ -173,9 +175,9 @@ DB 102,15,58,15,227,8 movdqu XMMWORD[80+rcx],xmm4 movaps xmm6,XMMWORD[rsp] lea rsp,[24+rsp] -$L$SEH_end_gcm_init_clmul: DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_init_clmul_4: global gcm_gmult_clmul @@ -235,21 +237,31 @@ global gcm_ghash_clmul ALIGN 32 gcm_ghash_clmul: +$L$SEH_begin_gcm_ghash_clmul_1: $L$_ghash_clmul: lea rax,[((-136))+rsp] -$L$SEH_begin_gcm_ghash_clmul: - -DB 0x48,0x8d,0x60,0xe0 -DB 0x0f,0x29,0x70,0xe0 -DB 0x0f,0x29,0x78,0xf0 -DB 0x44,0x0f,0x29,0x00 -DB 0x44,0x0f,0x29,0x48,0x10 -DB 0x44,0x0f,0x29,0x50,0x20 -DB 0x44,0x0f,0x29,0x58,0x30 -DB 0x44,0x0f,0x29,0x60,0x40 -DB 0x44,0x0f,0x29,0x68,0x50 -DB 0x44,0x0f,0x29,0x70,0x60 -DB 0x44,0x0f,0x29,0x78,0x70 + lea rsp,[((-32))+rax] +$L$SEH_prolog_gcm_ghash_clmul_2: + movaps XMMWORD[(-32)+rax],xmm6 +$L$SEH_prolog_gcm_ghash_clmul_3: + movaps XMMWORD[(-16)+rax],xmm7 +$L$SEH_prolog_gcm_ghash_clmul_4: + movaps XMMWORD[rax],xmm8 +$L$SEH_prolog_gcm_ghash_clmul_5: + movaps XMMWORD[16+rax],xmm9 +$L$SEH_prolog_gcm_ghash_clmul_6: + movaps XMMWORD[32+rax],xmm10 +$L$SEH_prolog_gcm_ghash_clmul_7: + movaps XMMWORD[48+rax],xmm11 +$L$SEH_prolog_gcm_ghash_clmul_8: + movaps XMMWORD[64+rax],xmm12 +$L$SEH_prolog_gcm_ghash_clmul_9: + movaps XMMWORD[80+rax],xmm13 +$L$SEH_prolog_gcm_ghash_clmul_10: + movaps XMMWORD[96+rax],xmm14 +$L$SEH_prolog_gcm_ghash_clmul_11: + movaps XMMWORD[112+rax],xmm15 +$L$SEH_prolog_gcm_ghash_clmul_12: movdqa xmm10,XMMWORD[$L$bswap_mask] movdqu xmm0,XMMWORD[rcx] @@ -638,19 +650,20 @@ DB 102,65,15,56,0,194 movaps xmm14,XMMWORD[128+rsp] movaps xmm15,XMMWORD[144+rsp] lea rsp,[168+rsp] -$L$SEH_end_gcm_ghash_clmul: DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_ghash_clmul_13: global gcm_init_avx ALIGN 32 gcm_init_avx: -$L$SEH_begin_gcm_init_avx: - -DB 0x48,0x83,0xec,0x18 -DB 0x0f,0x29,0x34,0x24 +$L$SEH_begin_gcm_init_avx_1: + sub rsp,0x18 +$L$SEH_prolog_gcm_init_avx_2: + movaps XMMWORD[rsp],xmm6 +$L$SEH_prolog_gcm_init_avx_3: vzeroupper vmovdqu xmm2,XMMWORD[rdx] @@ -754,8 +767,8 @@ $L$init_start_avx: vzeroupper movaps xmm6,XMMWORD[rsp] lea rsp,[24+rsp] -$L$SEH_end_gcm_init_avx: DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_init_avx_4: global gcm_gmult_avx @@ -771,20 +784,30 @@ global gcm_ghash_avx ALIGN 32 gcm_ghash_avx: +$L$SEH_begin_gcm_ghash_avx_1: lea rax,[((-136))+rsp] -$L$SEH_begin_gcm_ghash_avx: - -DB 0x48,0x8d,0x60,0xe0 -DB 0x0f,0x29,0x70,0xe0 -DB 0x0f,0x29,0x78,0xf0 -DB 0x44,0x0f,0x29,0x00 -DB 0x44,0x0f,0x29,0x48,0x10 -DB 0x44,0x0f,0x29,0x50,0x20 -DB 0x44,0x0f,0x29,0x58,0x30 -DB 0x44,0x0f,0x29,0x60,0x40 -DB 0x44,0x0f,0x29,0x68,0x50 -DB 0x44,0x0f,0x29,0x70,0x60 -DB 0x44,0x0f,0x29,0x78,0x70 + lea rsp,[((-32))+rax] +$L$SEH_prolog_gcm_ghash_avx_2: + movaps XMMWORD[(-32)+rax],xmm6 +$L$SEH_prolog_gcm_ghash_avx_3: + movaps XMMWORD[(-16)+rax],xmm7 +$L$SEH_prolog_gcm_ghash_avx_4: + movaps XMMWORD[rax],xmm8 +$L$SEH_prolog_gcm_ghash_avx_5: + movaps XMMWORD[16+rax],xmm9 +$L$SEH_prolog_gcm_ghash_avx_6: + movaps XMMWORD[32+rax],xmm10 +$L$SEH_prolog_gcm_ghash_avx_7: + movaps XMMWORD[48+rax],xmm11 +$L$SEH_prolog_gcm_ghash_avx_8: + movaps XMMWORD[64+rax],xmm12 +$L$SEH_prolog_gcm_ghash_avx_9: + movaps XMMWORD[80+rax],xmm13 +$L$SEH_prolog_gcm_ghash_avx_10: + movaps XMMWORD[96+rax],xmm14 +$L$SEH_prolog_gcm_ghash_avx_11: + movaps XMMWORD[112+rax],xmm15 +$L$SEH_prolog_gcm_ghash_avx_12: vzeroupper vmovdqu xmm10,XMMWORD[rcx] @@ -1166,56 +1189,148 @@ $L$tail_no_xor_avx: movaps xmm14,XMMWORD[128+rsp] movaps xmm15,XMMWORD[144+rsp] lea rsp,[168+rsp] -$L$SEH_end_gcm_ghash_avx: DB 0F3h,0C3h ;repret +$L$SEH_end_gcm_ghash_avx_13: +section .rdata rdata align=8 ALIGN 64 $L$bswap_mask: -DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 $L$0x1c2_polynomial: -DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 + DB 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 $L$7_mask: DD 7,0,7,0 ALIGN 64 -DB 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52 -DB 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 -DB 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 -DB 114,103,62,0 + DB 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52 + DB 44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32 + DB 60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111 + DB 114,103,62,0 ALIGN 64 +section .text + section .pdata rdata align=4 ALIGN 4 - DD $L$SEH_begin_gcm_init_clmul wrt ..imagebase - DD $L$SEH_end_gcm_init_clmul wrt ..imagebase - DD $L$SEH_info_gcm_init_clmul wrt ..imagebase + DD $L$SEH_begin_gcm_init_clmul_1 wrt ..imagebase + DD $L$SEH_end_gcm_init_clmul_4 wrt ..imagebase + DD $L$SEH_info_gcm_init_clmul_0 wrt ..imagebase + + DD $L$SEH_begin_gcm_ghash_clmul_1 wrt ..imagebase + DD $L$SEH_end_gcm_ghash_clmul_13 wrt ..imagebase + DD $L$SEH_info_gcm_ghash_clmul_0 wrt ..imagebase + + DD $L$SEH_begin_gcm_init_avx_1 wrt ..imagebase + DD $L$SEH_end_gcm_init_avx_4 wrt ..imagebase + DD $L$SEH_info_gcm_init_avx_0 wrt ..imagebase + + DD $L$SEH_begin_gcm_ghash_avx_1 wrt ..imagebase + DD $L$SEH_end_gcm_ghash_avx_13 wrt ..imagebase + DD $L$SEH_info_gcm_ghash_avx_0 wrt ..imagebase - DD $L$SEH_begin_gcm_ghash_clmul wrt ..imagebase - DD $L$SEH_end_gcm_ghash_clmul wrt ..imagebase - DD $L$SEH_info_gcm_ghash_clmul wrt ..imagebase - DD $L$SEH_begin_gcm_init_avx wrt ..imagebase - DD $L$SEH_end_gcm_init_avx wrt ..imagebase - DD $L$SEH_info_gcm_init_clmul wrt ..imagebase - DD $L$SEH_begin_gcm_ghash_avx wrt ..imagebase - DD $L$SEH_end_gcm_ghash_avx wrt ..imagebase - DD $L$SEH_info_gcm_ghash_clmul wrt ..imagebase section .xdata rdata align=8 -ALIGN 8 -$L$SEH_info_gcm_init_clmul: -DB 0x01,0x08,0x03,0x00 -DB 0x08,0x68,0x00,0x00 -DB 0x04,0x22,0x00,0x00 -$L$SEH_info_gcm_ghash_clmul: -DB 0x01,0x33,0x16,0x00 -DB 0x33,0xf8,0x09,0x00 -DB 0x2e,0xe8,0x08,0x00 -DB 0x29,0xd8,0x07,0x00 -DB 0x24,0xc8,0x06,0x00 -DB 0x1f,0xb8,0x05,0x00 -DB 0x1a,0xa8,0x04,0x00 -DB 0x15,0x98,0x03,0x00 -DB 0x10,0x88,0x02,0x00 -DB 0x0c,0x78,0x01,0x00 -DB 0x08,0x68,0x00,0x00 -DB 0x04,0x01,0x15,0x00 +ALIGN 4 +$L$SEH_info_gcm_init_clmul_0: + DB 1 + DB $L$SEH_prolog_gcm_init_clmul_3-$L$SEH_begin_gcm_init_clmul_1 + DB 3 + DB 0 + DB $L$SEH_prolog_gcm_init_clmul_3-$L$SEH_begin_gcm_init_clmul_1 + DB 104 + DW 0 + DB $L$SEH_prolog_gcm_init_clmul_2-$L$SEH_begin_gcm_init_clmul_1 + DB 34 + +$L$SEH_info_gcm_ghash_clmul_0: + DB 1 + DB $L$SEH_prolog_gcm_ghash_clmul_12-$L$SEH_begin_gcm_ghash_clmul_1 + DB 22 + DB 0 + DB $L$SEH_prolog_gcm_ghash_clmul_12-$L$SEH_begin_gcm_ghash_clmul_1 + DB 248 + DW 9 + DB $L$SEH_prolog_gcm_ghash_clmul_11-$L$SEH_begin_gcm_ghash_clmul_1 + DB 232 + DW 8 + DB $L$SEH_prolog_gcm_ghash_clmul_10-$L$SEH_begin_gcm_ghash_clmul_1 + DB 216 + DW 7 + DB $L$SEH_prolog_gcm_ghash_clmul_9-$L$SEH_begin_gcm_ghash_clmul_1 + DB 200 + DW 6 + DB $L$SEH_prolog_gcm_ghash_clmul_8-$L$SEH_begin_gcm_ghash_clmul_1 + DB 184 + DW 5 + DB $L$SEH_prolog_gcm_ghash_clmul_7-$L$SEH_begin_gcm_ghash_clmul_1 + DB 168 + DW 4 + DB $L$SEH_prolog_gcm_ghash_clmul_6-$L$SEH_begin_gcm_ghash_clmul_1 + DB 152 + DW 3 + DB $L$SEH_prolog_gcm_ghash_clmul_5-$L$SEH_begin_gcm_ghash_clmul_1 + DB 136 + DW 2 + DB $L$SEH_prolog_gcm_ghash_clmul_4-$L$SEH_begin_gcm_ghash_clmul_1 + DB 120 + DW 1 + DB $L$SEH_prolog_gcm_ghash_clmul_3-$L$SEH_begin_gcm_ghash_clmul_1 + DB 104 + DW 0 + DB $L$SEH_prolog_gcm_ghash_clmul_2-$L$SEH_begin_gcm_ghash_clmul_1 + DB 1 + DW 21 + +$L$SEH_info_gcm_init_avx_0: + DB 1 + DB $L$SEH_prolog_gcm_init_avx_3-$L$SEH_begin_gcm_init_avx_1 + DB 3 + DB 0 + DB $L$SEH_prolog_gcm_init_avx_3-$L$SEH_begin_gcm_init_avx_1 + DB 104 + DW 0 + DB $L$SEH_prolog_gcm_init_avx_2-$L$SEH_begin_gcm_init_avx_1 + DB 34 + +$L$SEH_info_gcm_ghash_avx_0: + DB 1 + DB $L$SEH_prolog_gcm_ghash_avx_12-$L$SEH_begin_gcm_ghash_avx_1 + DB 22 + DB 0 + DB $L$SEH_prolog_gcm_ghash_avx_12-$L$SEH_begin_gcm_ghash_avx_1 + DB 248 + DW 9 + DB $L$SEH_prolog_gcm_ghash_avx_11-$L$SEH_begin_gcm_ghash_avx_1 + DB 232 + DW 8 + DB $L$SEH_prolog_gcm_ghash_avx_10-$L$SEH_begin_gcm_ghash_avx_1 + DB 216 + DW 7 + DB $L$SEH_prolog_gcm_ghash_avx_9-$L$SEH_begin_gcm_ghash_avx_1 + DB 200 + DW 6 + DB $L$SEH_prolog_gcm_ghash_avx_8-$L$SEH_begin_gcm_ghash_avx_1 + DB 184 + DW 5 + DB $L$SEH_prolog_gcm_ghash_avx_7-$L$SEH_begin_gcm_ghash_avx_1 + DB 168 + DW 4 + DB $L$SEH_prolog_gcm_ghash_avx_6-$L$SEH_begin_gcm_ghash_avx_1 + DB 152 + DW 3 + DB $L$SEH_prolog_gcm_ghash_avx_5-$L$SEH_begin_gcm_ghash_avx_1 + DB 136 + DW 2 + DB $L$SEH_prolog_gcm_ghash_avx_4-$L$SEH_begin_gcm_ghash_avx_1 + DB 120 + DW 1 + DB $L$SEH_prolog_gcm_ghash_avx_3-$L$SEH_begin_gcm_ghash_avx_1 + DB 104 + DW 0 + DB $L$SEH_prolog_gcm_ghash_avx_2-$L$SEH_begin_gcm_ghash_avx_1 + DB 1 + DW 21 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64-win.asm index 646201bb..003a589e 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/md5-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -792,5 +793,9 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_md5_block_asm_data_order: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm-win.asm index 215f5d2a..73f536ea 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256-x86_64-asm-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -14,6 +15,7 @@ section .text code align=64 EXTERN OPENSSL_ia32cap_P +section .rdata rdata align=8 ALIGN 64 $L$poly: DQ 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001 @@ -32,6 +34,8 @@ $L$ord: DQ 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000 $L$ordK: DQ 0xccd1c8aaee00bc4f +section .text + @@ -1072,7 +1076,7 @@ DB 102,72,15,126,210 adox r10,rcx adcx r14,r14 mulx rbp,rcx,rdx -DB 0x67 + DB 0x67 DB 102,72,15,126,218 adox r11,rax adcx r15,r15 @@ -1962,7 +1966,7 @@ __ecp_nistz256_sqr_montx: adcx r13,r13 adox r10,rcx adcx r14,r14 -DB 0x67 + DB 0x67 mulx rbp,rcx,rdx mov rdx,QWORD[((24+128))+rsi] adox r11,rax @@ -1970,7 +1974,7 @@ DB 0x67 adox r12,rcx mov rsi,32 adox r13,rbp -DB 0x67,0x67 + DB 0x67,0x67 mulx rax,rcx,rdx mov rdx,QWORD[(($L$poly+24))] adox r14,rcx @@ -2060,17 +2064,17 @@ ecp_nistz256_select_w5: jnz NEAR $L$avx2_select_w5 lea rax,[((-136))+rsp] $L$SEH_begin_ecp_nistz256_select_w5: -DB 0x48,0x8d,0x60,0xe0 -DB 0x0f,0x29,0x70,0xe0 -DB 0x0f,0x29,0x78,0xf0 -DB 0x44,0x0f,0x29,0x00 -DB 0x44,0x0f,0x29,0x48,0x10 -DB 0x44,0x0f,0x29,0x50,0x20 -DB 0x44,0x0f,0x29,0x58,0x30 -DB 0x44,0x0f,0x29,0x60,0x40 -DB 0x44,0x0f,0x29,0x68,0x50 -DB 0x44,0x0f,0x29,0x70,0x60 -DB 0x44,0x0f,0x29,0x78,0x70 + DB 0x48,0x8d,0x60,0xe0 + DB 0x0f,0x29,0x70,0xe0 + DB 0x0f,0x29,0x78,0xf0 + DB 0x44,0x0f,0x29,0x00 + DB 0x44,0x0f,0x29,0x48,0x10 + DB 0x44,0x0f,0x29,0x50,0x20 + DB 0x44,0x0f,0x29,0x58,0x30 + DB 0x44,0x0f,0x29,0x60,0x40 + DB 0x44,0x0f,0x29,0x68,0x50 + DB 0x44,0x0f,0x29,0x70,0x60 + DB 0x44,0x0f,0x29,0x78,0x70 movdqa xmm0,XMMWORD[$L$One] movd xmm1,r8d @@ -2150,17 +2154,17 @@ ecp_nistz256_select_w7: jnz NEAR $L$avx2_select_w7 lea rax,[((-136))+rsp] $L$SEH_begin_ecp_nistz256_select_w7: -DB 0x48,0x8d,0x60,0xe0 -DB 0x0f,0x29,0x70,0xe0 -DB 0x0f,0x29,0x78,0xf0 -DB 0x44,0x0f,0x29,0x00 -DB 0x44,0x0f,0x29,0x48,0x10 -DB 0x44,0x0f,0x29,0x50,0x20 -DB 0x44,0x0f,0x29,0x58,0x30 -DB 0x44,0x0f,0x29,0x60,0x40 -DB 0x44,0x0f,0x29,0x68,0x50 -DB 0x44,0x0f,0x29,0x70,0x60 -DB 0x44,0x0f,0x29,0x78,0x70 + DB 0x48,0x8d,0x60,0xe0 + DB 0x0f,0x29,0x70,0xe0 + DB 0x0f,0x29,0x78,0xf0 + DB 0x44,0x0f,0x29,0x00 + DB 0x44,0x0f,0x29,0x48,0x10 + DB 0x44,0x0f,0x29,0x50,0x20 + DB 0x44,0x0f,0x29,0x58,0x30 + DB 0x44,0x0f,0x29,0x60,0x40 + DB 0x44,0x0f,0x29,0x68,0x50 + DB 0x44,0x0f,0x29,0x70,0x60 + DB 0x44,0x0f,0x29,0x78,0x70 movdqa xmm8,XMMWORD[$L$One] movd xmm1,r8d @@ -2226,17 +2230,17 @@ $L$avx2_select_w5: lea rax,[((-136))+rsp] mov r11,rsp $L$SEH_begin_ecp_nistz256_avx2_select_w5: -DB 0x48,0x8d,0x60,0xe0 -DB 0xc5,0xf8,0x29,0x70,0xe0 -DB 0xc5,0xf8,0x29,0x78,0xf0 -DB 0xc5,0x78,0x29,0x40,0x00 -DB 0xc5,0x78,0x29,0x48,0x10 -DB 0xc5,0x78,0x29,0x50,0x20 -DB 0xc5,0x78,0x29,0x58,0x30 -DB 0xc5,0x78,0x29,0x60,0x40 -DB 0xc5,0x78,0x29,0x68,0x50 -DB 0xc5,0x78,0x29,0x70,0x60 -DB 0xc5,0x78,0x29,0x78,0x70 + DB 0x48,0x8d,0x60,0xe0 + DB 0xc5,0xf8,0x29,0x70,0xe0 + DB 0xc5,0xf8,0x29,0x78,0xf0 + DB 0xc5,0x78,0x29,0x40,0x00 + DB 0xc5,0x78,0x29,0x48,0x10 + DB 0xc5,0x78,0x29,0x50,0x20 + DB 0xc5,0x78,0x29,0x58,0x30 + DB 0xc5,0x78,0x29,0x60,0x40 + DB 0xc5,0x78,0x29,0x68,0x50 + DB 0xc5,0x78,0x29,0x70,0x60 + DB 0xc5,0x78,0x29,0x78,0x70 vmovdqa ymm0,YMMWORD[$L$Two] vpxor ymm2,ymm2,ymm2 @@ -2316,17 +2320,17 @@ $L$avx2_select_w7: mov r11,rsp lea rax,[((-136))+rsp] $L$SEH_begin_ecp_nistz256_avx2_select_w7: -DB 0x48,0x8d,0x60,0xe0 -DB 0xc5,0xf8,0x29,0x70,0xe0 -DB 0xc5,0xf8,0x29,0x78,0xf0 -DB 0xc5,0x78,0x29,0x40,0x00 -DB 0xc5,0x78,0x29,0x48,0x10 -DB 0xc5,0x78,0x29,0x50,0x20 -DB 0xc5,0x78,0x29,0x58,0x30 -DB 0xc5,0x78,0x29,0x60,0x40 -DB 0xc5,0x78,0x29,0x68,0x50 -DB 0xc5,0x78,0x29,0x70,0x60 -DB 0xc5,0x78,0x29,0x78,0x70 + DB 0x48,0x8d,0x60,0xe0 + DB 0xc5,0xf8,0x29,0x70,0xe0 + DB 0xc5,0xf8,0x29,0x78,0xf0 + DB 0xc5,0x78,0x29,0x40,0x00 + DB 0xc5,0x78,0x29,0x48,0x10 + DB 0xc5,0x78,0x29,0x50,0x20 + DB 0xc5,0x78,0x29,0x58,0x30 + DB 0xc5,0x78,0x29,0x60,0x40 + DB 0xc5,0x78,0x29,0x68,0x50 + DB 0xc5,0x78,0x29,0x70,0x60 + DB 0xc5,0x78,0x29,0x78,0x70 vmovdqa ymm0,YMMWORD[$L$Three] vpxor ymm2,ymm2,ymm2 @@ -2956,7 +2960,7 @@ DB 102,73,15,110,220 DB 102,73,15,126,208 DB 102,73,15,126,217 or r12,r8 -DB 0x3e + DB 0x3e jnz NEAR $L$add_proceedq @@ -4097,7 +4101,7 @@ DB 102,73,15,110,220 DB 102,73,15,126,208 DB 102,73,15,126,217 or r12,r8 -DB 0x3e + DB 0x3e jnz NEAR $L$add_proceedx @@ -4889,96 +4893,100 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_ecp_nistz256_neg: -DB 9,0,0,0 + DB 9,0,0,0 DD short_handler wrt ..imagebase DD $L$neg_body wrt ..imagebase,$L$neg_epilogue wrt ..imagebase $L$SEH_info_ecp_nistz256_ord_mul_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$ord_mul_body wrt ..imagebase,$L$ord_mul_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_ord_sqr_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$ord_sqr_body wrt ..imagebase,$L$ord_sqr_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_ord_mul_montx: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$ord_mulx_body wrt ..imagebase,$L$ord_mulx_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_ord_sqr_montx: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$ord_sqrx_body wrt ..imagebase,$L$ord_sqrx_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_mul_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$mul_body wrt ..imagebase,$L$mul_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_sqr_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$sqr_body wrt ..imagebase,$L$sqr_epilogue wrt ..imagebase DD 48,0 $L$SEH_info_ecp_nistz256_select_wX: -DB 0x01,0x33,0x16,0x00 -DB 0x33,0xf8,0x09,0x00 -DB 0x2e,0xe8,0x08,0x00 -DB 0x29,0xd8,0x07,0x00 -DB 0x24,0xc8,0x06,0x00 -DB 0x1f,0xb8,0x05,0x00 -DB 0x1a,0xa8,0x04,0x00 -DB 0x15,0x98,0x03,0x00 -DB 0x10,0x88,0x02,0x00 -DB 0x0c,0x78,0x01,0x00 -DB 0x08,0x68,0x00,0x00 -DB 0x04,0x01,0x15,0x00 + DB 0x01,0x33,0x16,0x00 + DB 0x33,0xf8,0x09,0x00 + DB 0x2e,0xe8,0x08,0x00 + DB 0x29,0xd8,0x07,0x00 + DB 0x24,0xc8,0x06,0x00 + DB 0x1f,0xb8,0x05,0x00 + DB 0x1a,0xa8,0x04,0x00 + DB 0x15,0x98,0x03,0x00 + DB 0x10,0x88,0x02,0x00 + DB 0x0c,0x78,0x01,0x00 + DB 0x08,0x68,0x00,0x00 + DB 0x04,0x01,0x15,0x00 ALIGN 8 $L$SEH_info_ecp_nistz256_avx2_select_wX: -DB 0x01,0x36,0x17,0x0b -DB 0x36,0xf8,0x09,0x00 -DB 0x31,0xe8,0x08,0x00 -DB 0x2c,0xd8,0x07,0x00 -DB 0x27,0xc8,0x06,0x00 -DB 0x22,0xb8,0x05,0x00 -DB 0x1d,0xa8,0x04,0x00 -DB 0x18,0x98,0x03,0x00 -DB 0x13,0x88,0x02,0x00 -DB 0x0e,0x78,0x01,0x00 -DB 0x09,0x68,0x00,0x00 -DB 0x04,0x01,0x15,0x00 -DB 0x00,0xb3,0x00,0x00 + DB 0x01,0x36,0x17,0x0b + DB 0x36,0xf8,0x09,0x00 + DB 0x31,0xe8,0x08,0x00 + DB 0x2c,0xd8,0x07,0x00 + DB 0x27,0xc8,0x06,0x00 + DB 0x22,0xb8,0x05,0x00 + DB 0x1d,0xa8,0x04,0x00 + DB 0x18,0x98,0x03,0x00 + DB 0x13,0x88,0x02,0x00 + DB 0x0e,0x78,0x01,0x00 + DB 0x09,0x68,0x00,0x00 + DB 0x04,0x01,0x15,0x00 + DB 0x00,0xb3,0x00,0x00 ALIGN 8 $L$SEH_info_ecp_nistz256_point_double: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$point_doubleq_body wrt ..imagebase,$L$point_doubleq_epilogue wrt ..imagebase DD 32*5+56,0 $L$SEH_info_ecp_nistz256_point_add: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$point_addq_body wrt ..imagebase,$L$point_addq_epilogue wrt ..imagebase DD 32*18+56,0 $L$SEH_info_ecp_nistz256_point_add_affine: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$add_affineq_body wrt ..imagebase,$L$add_affineq_epilogue wrt ..imagebase DD 32*15+56,0 ALIGN 8 $L$SEH_info_ecp_nistz256_point_doublex: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$point_doublex_body wrt ..imagebase,$L$point_doublex_epilogue wrt ..imagebase DD 32*5+56,0 $L$SEH_info_ecp_nistz256_point_addx: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$point_addx_body wrt ..imagebase,$L$point_addx_epilogue wrt ..imagebase DD 32*18+56,0 $L$SEH_info_ecp_nistz256_point_add_affinex: -DB 9,0,0,0 + DB 9,0,0,0 DD full_handler wrt ..imagebase DD $L$add_affinex_body wrt ..imagebase,$L$add_affinex_epilogue wrt ..imagebase DD 32*15+56,0 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-win.asm index 563699d5..0488afd8 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -337,3 +338,7 @@ $L$beeu_finish: $L$SEH_end_beeu_mod_inverse_vartime: +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64-win.asm similarity index 86% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64-win.asm index 89b91de1..2b2e0aab 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rdrand-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -56,3 +57,7 @@ $L$err: DB 0F3h,0C3h ;repret +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2-win.asm index 74e2705c..fd41206e 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/rsaz-avx2-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -381,9 +382,9 @@ $L$OOP_REDUCE_1024: imul rax,QWORD[((8-128))+r13] vpaddq ymm2,ymm2,ymm14 vpmuludq ymm11,ymm12,YMMWORD[((96-128))+r13] -DB 0x67 + DB 0x67 add r11,rax -DB 0x67 + DB 0x67 mov rax,rdx imul rax,QWORD[((16-128))+r13] shr r10,29 @@ -427,12 +428,12 @@ DB 0x67 vpaddq ymm3,ymm3,ymm14 vpmuludq ymm11,ymm11,ymm13 vmovdqu ymm14,YMMWORD[((192-8-128))+r13] -DB 0x67 + DB 0x67 mov r12,rax imul eax,ecx vpaddq ymm4,ymm4,ymm11 vpmuludq ymm10,ymm10,ymm13 -DB 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 + DB 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 and eax,0x1fffffff vpaddq ymm5,ymm5,ymm10 vpmuludq ymm14,ymm14,ymm13 @@ -457,12 +458,12 @@ DB 0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00 vpaddq ymm1,ymm1,ymm14 vpmuludq ymm13,ymm13,ymm0 vpmuludq ymm11,ymm11,ymm12 -DB 0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff + DB 0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff vpaddq ymm13,ymm13,ymm1 vpaddq ymm2,ymm2,ymm11 vpmuludq ymm10,ymm10,ymm12 vmovdqu ymm11,YMMWORD[((160-16-128))+r13] -DB 0x67 + DB 0x67 vmovq rax,xmm13 vmovdqu YMMWORD[rsp],ymm13 vpaddq ymm3,ymm3,ymm10 @@ -489,7 +490,7 @@ DB 0x67 and eax,0x1fffffff vmovd xmm12,eax vmovdqu ymm11,YMMWORD[((96-24-128))+r13] -DB 0x67 + DB 0x67 vpaddq ymm9,ymm9,ymm10 vpbroadcastq ymm12,xmm12 @@ -504,7 +505,7 @@ DB 0x67 add r9,rax mov rax,rdx imul rax,QWORD[((8-128))+r13] -DB 0x67 + DB 0x67 shr r9,29 mov r11,QWORD[16+rsp] vpaddq ymm2,ymm3,ymm11 @@ -755,7 +756,7 @@ $L$mul_1024_body: -DB 0x67,0x67 + DB 0x67,0x67 mov r15,rsi and r15,4095 add r15,32*10 @@ -771,7 +772,7 @@ DB 0x67,0x67 and r15,4095 add r15,32*10 -DB 0x67,0x67 + DB 0x67,0x67 shr r15,12 jz NEAR $L$mul_1024_no_n_copy @@ -817,7 +818,7 @@ $L$mul_1024_no_n_copy: vpbroadcastq ymm10,QWORD[r13] vmovdqu YMMWORD[rsp],ymm0 xor r9,r9 -DB 0x67 + DB 0x67 xor r10,r10 xor r11,r11 xor r12,r12 @@ -1689,17 +1690,17 @@ rsaz_1024_gather5_avx2: lea rax,[((-136))+rsp] $L$SEH_begin_rsaz_1024_gather5: -DB 0x48,0x8d,0x60,0xe0 -DB 0xc5,0xf8,0x29,0x70,0xe0 -DB 0xc5,0xf8,0x29,0x78,0xf0 -DB 0xc5,0x78,0x29,0x40,0x00 -DB 0xc5,0x78,0x29,0x48,0x10 -DB 0xc5,0x78,0x29,0x50,0x20 -DB 0xc5,0x78,0x29,0x58,0x30 -DB 0xc5,0x78,0x29,0x60,0x40 -DB 0xc5,0x78,0x29,0x68,0x50 -DB 0xc5,0x78,0x29,0x70,0x60 -DB 0xc5,0x78,0x29,0x78,0x70 + DB 0x48,0x8d,0x60,0xe0 + DB 0xc5,0xf8,0x29,0x70,0xe0 + DB 0xc5,0xf8,0x29,0x78,0xf0 + DB 0xc5,0x78,0x29,0x40,0x00 + DB 0xc5,0x78,0x29,0x48,0x10 + DB 0xc5,0x78,0x29,0x50,0x20 + DB 0xc5,0x78,0x29,0x58,0x30 + DB 0xc5,0x78,0x29,0x60,0x40 + DB 0xc5,0x78,0x29,0x68,0x50 + DB 0xc5,0x78,0x29,0x70,0x60 + DB 0xc5,0x78,0x29,0x78,0x70 lea rsp,[((-256))+rsp] and rsp,-32 lea r10,[$L$inc] @@ -1823,6 +1824,7 @@ $L$oop_gather_1024: $L$SEH_end_rsaz_1024_gather5: +section .rdata rdata align=8 ALIGN 64 $L$and_mask: DQ 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff @@ -1835,6 +1837,8 @@ $L$inc: DD 2,2,2,2,3,3,3,3 DD 4,4,4,4,4,4,4,4 ALIGN 64 +section .text + EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -1947,26 +1951,30 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_rsaz_1024_sqr_avx2: -DB 9,0,0,0 + DB 9,0,0,0 DD rsaz_se_handler wrt ..imagebase DD $L$sqr_1024_body wrt ..imagebase,$L$sqr_1024_epilogue wrt ..imagebase,$L$sqr_1024_in_tail wrt ..imagebase DD 0 $L$SEH_info_rsaz_1024_mul_avx2: -DB 9,0,0,0 + DB 9,0,0,0 DD rsaz_se_handler wrt ..imagebase DD $L$mul_1024_body wrt ..imagebase,$L$mul_1024_epilogue wrt ..imagebase,$L$mul_1024_in_tail wrt ..imagebase DD 0 $L$SEH_info_rsaz_1024_gather5: -DB 0x01,0x36,0x17,0x0b -DB 0x36,0xf8,0x09,0x00 -DB 0x31,0xe8,0x08,0x00 -DB 0x2c,0xd8,0x07,0x00 -DB 0x27,0xc8,0x06,0x00 -DB 0x22,0xb8,0x05,0x00 -DB 0x1d,0xa8,0x04,0x00 -DB 0x18,0x98,0x03,0x00 -DB 0x13,0x88,0x02,0x00 -DB 0x0e,0x78,0x01,0x00 -DB 0x09,0x68,0x00,0x00 -DB 0x04,0x01,0x15,0x00 -DB 0x00,0xb3,0x00,0x00 + DB 0x01,0x36,0x17,0x0b + DB 0x36,0xf8,0x09,0x00 + DB 0x31,0xe8,0x08,0x00 + DB 0x2c,0xd8,0x07,0x00 + DB 0x27,0xc8,0x06,0x00 + DB 0x22,0xb8,0x05,0x00 + DB 0x1d,0xa8,0x04,0x00 + DB 0x18,0x98,0x03,0x00 + DB 0x13,0x88,0x02,0x00 + DB 0x0e,0x78,0x01,0x00 + DB 0x09,0x68,0x00,0x00 + DB 0x04,0x01,0x15,0x00 + DB 0x00,0xb3,0x00,0x00 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64-win.asm similarity index 98% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64-win.asm index 1654df1d..c842eee8 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha1-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -1322,133 +1323,134 @@ $L$oop_shaext: lea r8,[64+rsi] paddd xmm1,xmm4 cmovne rsi,r8 + prefetcht0 [512+rsi] movdqa xmm8,xmm0 -DB 15,56,201,229 + DB 15,56,201,229 movdqa xmm2,xmm0 -DB 15,58,204,193,0 -DB 15,56,200,213 + DB 15,58,204,193,0 + DB 15,56,200,213 pxor xmm4,xmm6 -DB 15,56,201,238 -DB 15,56,202,231 + DB 15,56,201,238 + DB 15,56,202,231 movdqa xmm1,xmm0 -DB 15,58,204,194,0 -DB 15,56,200,206 + DB 15,58,204,194,0 + DB 15,56,200,206 pxor xmm5,xmm7 -DB 15,56,202,236 -DB 15,56,201,247 + DB 15,56,202,236 + DB 15,56,201,247 movdqa xmm2,xmm0 -DB 15,58,204,193,0 -DB 15,56,200,215 + DB 15,58,204,193,0 + DB 15,56,200,215 pxor xmm6,xmm4 -DB 15,56,201,252 -DB 15,56,202,245 + DB 15,56,201,252 + DB 15,56,202,245 movdqa xmm1,xmm0 -DB 15,58,204,194,0 -DB 15,56,200,204 + DB 15,58,204,194,0 + DB 15,56,200,204 pxor xmm7,xmm5 -DB 15,56,202,254 -DB 15,56,201,229 + DB 15,56,202,254 + DB 15,56,201,229 movdqa xmm2,xmm0 -DB 15,58,204,193,0 -DB 15,56,200,213 + DB 15,58,204,193,0 + DB 15,56,200,213 pxor xmm4,xmm6 -DB 15,56,201,238 -DB 15,56,202,231 + DB 15,56,201,238 + DB 15,56,202,231 movdqa xmm1,xmm0 -DB 15,58,204,194,1 -DB 15,56,200,206 + DB 15,58,204,194,1 + DB 15,56,200,206 pxor xmm5,xmm7 -DB 15,56,202,236 -DB 15,56,201,247 + DB 15,56,202,236 + DB 15,56,201,247 movdqa xmm2,xmm0 -DB 15,58,204,193,1 -DB 15,56,200,215 + DB 15,58,204,193,1 + DB 15,56,200,215 pxor xmm6,xmm4 -DB 15,56,201,252 -DB 15,56,202,245 + DB 15,56,201,252 + DB 15,56,202,245 movdqa xmm1,xmm0 -DB 15,58,204,194,1 -DB 15,56,200,204 + DB 15,58,204,194,1 + DB 15,56,200,204 pxor xmm7,xmm5 -DB 15,56,202,254 -DB 15,56,201,229 + DB 15,56,202,254 + DB 15,56,201,229 movdqa xmm2,xmm0 -DB 15,58,204,193,1 -DB 15,56,200,213 + DB 15,58,204,193,1 + DB 15,56,200,213 pxor xmm4,xmm6 -DB 15,56,201,238 -DB 15,56,202,231 + DB 15,56,201,238 + DB 15,56,202,231 movdqa xmm1,xmm0 -DB 15,58,204,194,1 -DB 15,56,200,206 + DB 15,58,204,194,1 + DB 15,56,200,206 pxor xmm5,xmm7 -DB 15,56,202,236 -DB 15,56,201,247 + DB 15,56,202,236 + DB 15,56,201,247 movdqa xmm2,xmm0 -DB 15,58,204,193,2 -DB 15,56,200,215 + DB 15,58,204,193,2 + DB 15,56,200,215 pxor xmm6,xmm4 -DB 15,56,201,252 -DB 15,56,202,245 + DB 15,56,201,252 + DB 15,56,202,245 movdqa xmm1,xmm0 -DB 15,58,204,194,2 -DB 15,56,200,204 + DB 15,58,204,194,2 + DB 15,56,200,204 pxor xmm7,xmm5 -DB 15,56,202,254 -DB 15,56,201,229 + DB 15,56,202,254 + DB 15,56,201,229 movdqa xmm2,xmm0 -DB 15,58,204,193,2 -DB 15,56,200,213 + DB 15,58,204,193,2 + DB 15,56,200,213 pxor xmm4,xmm6 -DB 15,56,201,238 -DB 15,56,202,231 + DB 15,56,201,238 + DB 15,56,202,231 movdqa xmm1,xmm0 -DB 15,58,204,194,2 -DB 15,56,200,206 + DB 15,58,204,194,2 + DB 15,56,200,206 pxor xmm5,xmm7 -DB 15,56,202,236 -DB 15,56,201,247 + DB 15,56,202,236 + DB 15,56,201,247 movdqa xmm2,xmm0 -DB 15,58,204,193,2 -DB 15,56,200,215 + DB 15,58,204,193,2 + DB 15,56,200,215 pxor xmm6,xmm4 -DB 15,56,201,252 -DB 15,56,202,245 + DB 15,56,201,252 + DB 15,56,202,245 movdqa xmm1,xmm0 -DB 15,58,204,194,3 -DB 15,56,200,204 + DB 15,58,204,194,3 + DB 15,56,200,204 pxor xmm7,xmm5 -DB 15,56,202,254 + DB 15,56,202,254 movdqu xmm4,XMMWORD[rsi] movdqa xmm2,xmm0 -DB 15,58,204,193,3 -DB 15,56,200,213 + DB 15,58,204,193,3 + DB 15,56,200,213 movdqu xmm5,XMMWORD[16+rsi] DB 102,15,56,0,227 movdqa xmm1,xmm0 -DB 15,58,204,194,3 -DB 15,56,200,206 + DB 15,58,204,194,3 + DB 15,56,200,206 movdqu xmm6,XMMWORD[32+rsi] DB 102,15,56,0,235 movdqa xmm2,xmm0 -DB 15,58,204,193,3 -DB 15,56,200,215 + DB 15,58,204,193,3 + DB 15,56,200,215 movdqu xmm7,XMMWORD[48+rsi] DB 102,15,56,0,243 movdqa xmm1,xmm0 -DB 15,58,204,194,3 -DB 65,15,56,200,201 + DB 15,58,204,194,3 + DB 65,15,56,200,201 DB 102,15,56,0,251 paddd xmm0,xmm8 @@ -5553,6 +5555,7 @@ $L$epilogue_avx2: DB 0F3h,0C3h ;repret $L$SEH_end_sha1_block_data_order_avx2: +section .rdata rdata align=8 ALIGN 64 K_XX_XX: DD 0x5a827999,0x5a827999,0x5a827999,0x5a827999 @@ -5565,13 +5568,15 @@ K_XX_XX: DD 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 DD 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f DD 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f -DB 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 -DB 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115 -DB 102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44 -DB 32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60 -DB 97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114 -DB 103,62,0 + DB 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 + DB 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115 + DB 102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44 + DB 32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60 + DB 97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114 + DB 103,62,0 ALIGN 64 +section .text + EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -5755,20 +5760,24 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha1_block_data_order: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase $L$SEH_info_sha1_block_data_order_shaext: -DB 9,0,0,0 + DB 9,0,0,0 DD shaext_handler wrt ..imagebase $L$SEH_info_sha1_block_data_order_ssse3: -DB 9,0,0,0 + DB 9,0,0,0 DD ssse3_handler wrt ..imagebase DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase $L$SEH_info_sha1_block_data_order_avx: -DB 9,0,0,0 + DB 9,0,0,0 DD ssse3_handler wrt ..imagebase DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase $L$SEH_info_sha1_block_data_order_avx2: -DB 9,0,0,0 + DB 9,0,0,0 DD ssse3_handler wrt ..imagebase DD $L$prologue_avx2 wrt ..imagebase,$L$epilogue_avx2 wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64-win.asm similarity index 91% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64-win.asm index 68c74cc1..d1a6a902 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha256-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -31,6 +32,8 @@ $L$SEH_begin_sha256_block_data_order: mov r9d,DWORD[r11] mov r10d,DWORD[4+r11] mov r11d,DWORD[8+r11] + test r11d,536870912 + jnz NEAR $L$shaext_shortcut and r9d,1073741824 and r10d,268435968 or r10d,r9d @@ -1746,6 +1749,7 @@ $L$epilogue: DB 0F3h,0C3h ;repret $L$SEH_end_sha256_block_data_order: +section .rdata rdata align=8 ALIGN 64 K256: @@ -1788,11 +1792,247 @@ K256: DD 0x03020100,0x0b0a0908,0xffffffff,0xffffffff DD 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 DD 0xffffffff,0xffffffff,0x03020100,0x0b0a0908 -DB 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97 -DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54 -DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 -DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 -DB 111,114,103,62,0 + DB 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97 + DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54 + DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 + DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 + DB 111,114,103,62,0 +section .text + + +ALIGN 64 +sha256_block_data_order_shaext: + mov QWORD[8+rsp],rdi ;WIN64 prologue + mov QWORD[16+rsp],rsi + mov rax,rsp +$L$SEH_begin_sha256_block_data_order_shaext: + mov rdi,rcx + mov rsi,rdx + mov rdx,r8 + + + +$L$shaext_shortcut: + lea rsp,[((-88))+rsp] + movaps XMMWORD[(-8-80)+rax],xmm6 + movaps XMMWORD[(-8-64)+rax],xmm7 + movaps XMMWORD[(-8-48)+rax],xmm8 + movaps XMMWORD[(-8-32)+rax],xmm9 + movaps XMMWORD[(-8-16)+rax],xmm10 +$L$prologue_shaext: + lea rcx,[((K256+128))] + movdqu xmm1,XMMWORD[rdi] + movdqu xmm2,XMMWORD[16+rdi] + movdqa xmm7,XMMWORD[((512-128))+rcx] + + pshufd xmm0,xmm1,0x1b + pshufd xmm1,xmm1,0xb1 + pshufd xmm2,xmm2,0x1b + movdqa xmm8,xmm7 +DB 102,15,58,15,202,8 + punpcklqdq xmm2,xmm0 + jmp NEAR $L$oop_shaext + +ALIGN 16 +$L$oop_shaext: + movdqu xmm3,XMMWORD[rsi] + movdqu xmm4,XMMWORD[16+rsi] + movdqu xmm5,XMMWORD[32+rsi] +DB 102,15,56,0,223 + movdqu xmm6,XMMWORD[48+rsi] + + movdqa xmm0,XMMWORD[((0-128))+rcx] + paddd xmm0,xmm3 +DB 102,15,56,0,231 + movdqa xmm10,xmm2 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + nop + movdqa xmm9,xmm1 + DB 15,56,203,202 + + movdqa xmm0,XMMWORD[((32-128))+rcx] + paddd xmm0,xmm4 +DB 102,15,56,0,239 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + lea rsi,[64+rsi] + DB 15,56,204,220 + DB 15,56,203,202 + + movdqa xmm0,XMMWORD[((64-128))+rcx] + paddd xmm0,xmm5 +DB 102,15,56,0,247 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm6 +DB 102,15,58,15,253,4 + nop + paddd xmm3,xmm7 + DB 15,56,204,229 + DB 15,56,203,202 + + movdqa xmm0,XMMWORD[((96-128))+rcx] + paddd xmm0,xmm6 + DB 15,56,205,222 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm3 +DB 102,15,58,15,254,4 + nop + paddd xmm4,xmm7 + DB 15,56,204,238 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((128-128))+rcx] + paddd xmm0,xmm3 + DB 15,56,205,227 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm4 +DB 102,15,58,15,251,4 + nop + paddd xmm5,xmm7 + DB 15,56,204,243 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((160-128))+rcx] + paddd xmm0,xmm4 + DB 15,56,205,236 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm5 +DB 102,15,58,15,252,4 + nop + paddd xmm6,xmm7 + DB 15,56,204,220 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((192-128))+rcx] + paddd xmm0,xmm5 + DB 15,56,205,245 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm6 +DB 102,15,58,15,253,4 + nop + paddd xmm3,xmm7 + DB 15,56,204,229 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((224-128))+rcx] + paddd xmm0,xmm6 + DB 15,56,205,222 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm3 +DB 102,15,58,15,254,4 + nop + paddd xmm4,xmm7 + DB 15,56,204,238 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((256-128))+rcx] + paddd xmm0,xmm3 + DB 15,56,205,227 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm4 +DB 102,15,58,15,251,4 + nop + paddd xmm5,xmm7 + DB 15,56,204,243 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((288-128))+rcx] + paddd xmm0,xmm4 + DB 15,56,205,236 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm5 +DB 102,15,58,15,252,4 + nop + paddd xmm6,xmm7 + DB 15,56,204,220 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((320-128))+rcx] + paddd xmm0,xmm5 + DB 15,56,205,245 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm6 +DB 102,15,58,15,253,4 + nop + paddd xmm3,xmm7 + DB 15,56,204,229 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((352-128))+rcx] + paddd xmm0,xmm6 + DB 15,56,205,222 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm3 +DB 102,15,58,15,254,4 + nop + paddd xmm4,xmm7 + DB 15,56,204,238 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((384-128))+rcx] + paddd xmm0,xmm3 + DB 15,56,205,227 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm4 +DB 102,15,58,15,251,4 + nop + paddd xmm5,xmm7 + DB 15,56,204,243 + DB 15,56,203,202 + movdqa xmm0,XMMWORD[((416-128))+rcx] + paddd xmm0,xmm4 + DB 15,56,205,236 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + movdqa xmm7,xmm5 +DB 102,15,58,15,252,4 + DB 15,56,203,202 + paddd xmm6,xmm7 + + movdqa xmm0,XMMWORD[((448-128))+rcx] + paddd xmm0,xmm5 + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + DB 15,56,205,245 + movdqa xmm7,xmm8 + DB 15,56,203,202 + + movdqa xmm0,XMMWORD[((480-128))+rcx] + paddd xmm0,xmm6 + nop + DB 15,56,203,209 + pshufd xmm0,xmm0,0x0e + dec rdx + nop + DB 15,56,203,202 + + paddd xmm2,xmm10 + paddd xmm1,xmm9 + jnz NEAR $L$oop_shaext + + pshufd xmm2,xmm2,0xb1 + pshufd xmm7,xmm1,0x1b + pshufd xmm1,xmm1,0xb1 + punpckhqdq xmm1,xmm2 +DB 102,15,58,15,215,8 + + movdqu XMMWORD[rdi],xmm1 + movdqu XMMWORD[16+rdi],xmm2 + movaps xmm6,XMMWORD[((-8-80))+rax] + movaps xmm7,XMMWORD[((-8-64))+rax] + movaps xmm8,XMMWORD[((-8-48))+rax] + movaps xmm9,XMMWORD[((-8-32))+rax] + movaps xmm10,XMMWORD[((-8-16))+rax] + mov rsp,rax +$L$epilogue_shaext: + mov rdi,QWORD[8+rsp] ;WIN64 epilogue + mov rsi,QWORD[16+rsp] + DB 0F3h,0C3h ;repret + +$L$SEH_end_sha256_block_data_order_shaext: ALIGN 64 sha256_block_data_order_ssse3: @@ -4115,11 +4355,46 @@ $L$in_prologue: pop rsi DB 0F3h,0C3h ;repret + +ALIGN 16 +shaext_handler: + push rsi + push rdi + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + pushfq + sub rsp,64 + + mov rax,QWORD[120+r8] + mov rbx,QWORD[248+r8] + + lea r10,[$L$prologue_shaext] + cmp rbx,r10 + jb NEAR $L$in_prologue + + lea r10,[$L$epilogue_shaext] + cmp rbx,r10 + jae NEAR $L$in_prologue + + lea rsi,[((-8-80))+rax] + lea rdi,[512+r8] + mov ecx,10 + DD 0xa548f3fc + + jmp NEAR $L$in_prologue + section .pdata rdata align=4 ALIGN 4 DD $L$SEH_begin_sha256_block_data_order wrt ..imagebase DD $L$SEH_end_sha256_block_data_order wrt ..imagebase DD $L$SEH_info_sha256_block_data_order wrt ..imagebase + DD $L$SEH_begin_sha256_block_data_order_shaext wrt ..imagebase + DD $L$SEH_end_sha256_block_data_order_shaext wrt ..imagebase + DD $L$SEH_info_sha256_block_data_order_shaext wrt ..imagebase DD $L$SEH_begin_sha256_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_end_sha256_block_data_order_ssse3 wrt ..imagebase DD $L$SEH_info_sha256_block_data_order_ssse3 wrt ..imagebase @@ -4129,14 +4404,21 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha256_block_data_order: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue wrt ..imagebase,$L$epilogue wrt ..imagebase +$L$SEH_info_sha256_block_data_order_shaext: + DB 9,0,0,0 + DD shaext_handler wrt ..imagebase $L$SEH_info_sha256_block_data_order_ssse3: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase $L$SEH_info_sha256_block_data_order_avx: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64-win.asm similarity index 99% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64-win.asm index 33dc2c2e..a85813c0 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/sha512-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -1744,6 +1745,7 @@ $L$epilogue: DB 0F3h,0C3h ;repret $L$SEH_end_sha512_block_data_order: +section .rdata rdata align=8 ALIGN 64 K512: @@ -1830,11 +1832,13 @@ K512: DQ 0x0001020304050607,0x08090a0b0c0d0e0f DQ 0x0001020304050607,0x08090a0b0c0d0e0f -DB 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97 -DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54 -DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 -DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 -DB 111,114,103,62,0 + DB 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97 + DB 110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54 + DB 52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 + DB 32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46 + DB 111,114,103,62,0 +section .text + ALIGN 64 sha512_block_data_order_avx: @@ -3130,10 +3134,14 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_sha512_block_data_order: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue wrt ..imagebase,$L$epilogue wrt ..imagebase $L$SEH_info_sha512_block_data_order_avx: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64-win.asm index ccfc870a..593ab402 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/vpaes-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -1226,6 +1227,7 @@ _vpaes_preheat: +section .rdata rdata align=8 ALIGN 64 _vpaes_consts: $L$k_inv: @@ -1332,13 +1334,15 @@ $L$ctr_add_one: $L$ctr_add_two: DQ 0x0000000000000000,0x0000000200000000 -DB 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105 -DB 111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54 -DB 52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97 -DB 109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32 -DB 85,110,105,118,101,114,115,105,116,121,41,0 + DB 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105 + DB 111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54 + DB 52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97 + DB 109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32 + DB 85,110,105,118,101,114,115,105,116,121,41,0 ALIGN 64 +section .text + EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -1447,26 +1451,30 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_vpaes_set_encrypt_key: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$enc_key_body wrt ..imagebase,$L$enc_key_epilogue wrt ..imagebase $L$SEH_info_vpaes_set_decrypt_key: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$dec_key_body wrt ..imagebase,$L$dec_key_epilogue wrt ..imagebase $L$SEH_info_vpaes_encrypt: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$enc_body wrt ..imagebase,$L$enc_epilogue wrt ..imagebase $L$SEH_info_vpaes_decrypt: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$dec_body wrt ..imagebase,$L$dec_epilogue wrt ..imagebase $L$SEH_info_vpaes_cbc_encrypt: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$cbc_body wrt ..imagebase,$L$cbc_epilogue wrt ..imagebase $L$SEH_info_vpaes_ctr32_encrypt_blocks: -DB 9,0,0,0 + DB 9,0,0,0 DD se_handler wrt ..imagebase DD $L$ctr32_body wrt ..imagebase,$L$ctr32_epilogue wrt ..imagebase +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont-win.asm similarity index 97% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont-win.asm index d6d8bdd6..5ea1f2ed 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -1046,7 +1047,7 @@ $L$mulx4x_body: mulx r11,rax,QWORD[8+rcx] adcx r10,rax adox r11,r12 -DB 0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00 + DB 0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00 mov rdi,QWORD[48+rsp] mov QWORD[((-32))+rbx],r10 adcx r11,rax @@ -1071,7 +1072,7 @@ $L$mulx4x_1st: mulx rax,r12,QWORD[16+rsi] adcx r12,r14 mulx r14,r13,QWORD[24+rsi] -DB 0x67,0x67 + DB 0x67,0x67 mov rdx,r8 adcx r13,rax adcx r14,rbp @@ -1305,11 +1306,11 @@ $L$mulx4x_epilogue: DB 0F3h,0C3h ;repret $L$SEH_end_bn_mulx4x_mont: -DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 -DB 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 -DB 54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83 -DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 -DB 115,108,46,111,114,103,62,0 + DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 + DB 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 + DB 54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83 + DB 32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115 + DB 115,108,46,111,114,103,62,0 ALIGN 16 EXTERN __imp_RtlVirtualUnwind @@ -1462,20 +1463,24 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_bn_mul_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$mul_body wrt ..imagebase,$L$mul_epilogue wrt ..imagebase $L$SEH_info_bn_mul4x_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$mul4x_body wrt ..imagebase,$L$mul4x_epilogue wrt ..imagebase $L$SEH_info_bn_sqr8x_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD sqr_handler wrt ..imagebase DD $L$sqr8x_prologue wrt ..imagebase,$L$sqr8x_body wrt ..imagebase,$L$sqr8x_epilogue wrt ..imagebase ALIGN 8 $L$SEH_info_bn_mulx4x_mont: -DB 9,0,0,0 + DB 9,0,0,0 DD sqr_handler wrt ..imagebase DD $L$mulx4x_prologue wrt ..imagebase,$L$mulx4x_body wrt ..imagebase,$L$mulx4x_epilogue wrt ..imagebase ALIGN 8 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5-win.asm similarity index 92% rename from third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm rename to third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5-win.asm index 7a1d5dbd..8583bda1 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/fipsmodule/x86_64-mont5-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -101,7 +102,7 @@ $L$mul_body: movdqa xmm2,xmm1 paddd xmm1,xmm0 pcmpeqd xmm0,xmm5 -DB 0x67 + DB 0x67 movdqa xmm3,xmm4 paddd xmm2,xmm1 pcmpeqd xmm1,xmm5 @@ -165,7 +166,7 @@ DB 0x67 movdqa XMMWORD[304+r10],xmm0 paddd xmm3,xmm2 -DB 0x67 + DB 0x67 pcmpeqd xmm2,xmm5 movdqa XMMWORD[320+r10],xmm1 @@ -216,6 +217,7 @@ DB 0x67 por xmm0,xmm2 por xmm1,xmm3 por xmm0,xmm1 + pshufd xmm1,xmm0,0x4e por xmm0,xmm1 lea r12,[256+r12] @@ -339,6 +341,7 @@ $L$outer: por xmm4,xmm2 por xmm5,xmm3 por xmm4,xmm5 + pshufd xmm0,xmm4,0x4e por xmm0,xmm4 lea r12,[256+r12] @@ -484,7 +487,7 @@ $L$SEH_begin_bn_mul4x_mont_gather5: -DB 0x67 + DB 0x67 mov rax,rsp $L$mul4x_enter: @@ -505,7 +508,7 @@ $L$mul4x_enter: $L$mul4x_prologue: -DB 0x67 + DB 0x67 shl r9d,3 lea r10,[r9*2+r9] neg r9 @@ -604,11 +607,11 @@ mul4x_internal: pshufd xmm5,xmm5,0 movdqa xmm4,xmm1 -DB 0x67,0x67 + DB 0x67,0x67 movdqa xmm2,xmm1 paddd xmm1,xmm0 pcmpeqd xmm0,xmm5 -DB 0x67 + DB 0x67 movdqa xmm3,xmm4 paddd xmm2,xmm1 pcmpeqd xmm1,xmm5 @@ -672,7 +675,7 @@ DB 0x67 movdqa XMMWORD[304+r10],xmm0 paddd xmm3,xmm2 -DB 0x67 + DB 0x67 pcmpeqd xmm2,xmm5 movdqa XMMWORD[320+r10],xmm1 @@ -723,6 +726,7 @@ DB 0x67 por xmm0,xmm2 por xmm1,xmm3 por xmm0,xmm1 + pshufd xmm1,xmm0,0x4e por xmm0,xmm1 lea r12,[256+r12] @@ -930,6 +934,7 @@ $L$outer4x: por xmm4,xmm2 por xmm5,xmm3 por xmm4,xmm5 + pshufd xmm0,xmm4,0x4e por xmm0,xmm4 lea r12,[256+r12] @@ -1533,7 +1538,7 @@ $L$sqr4x_inner: add r13,QWORD[rcx*1+rdi] adc r12,0 -DB 0x67 + DB 0x67 mul r14 add r11,rax mov rax,rbx @@ -1565,7 +1570,7 @@ DB 0x67 cmp rcx,0 jne NEAR $L$sqr4x_inner -DB 0x67 + DB 0x67 mul r15 add r13,rax adc rdx,0 @@ -1758,7 +1763,7 @@ $L$sqr4x_shift_n_add: jnz NEAR $L$sqr4x_shift_n_add lea r12,[r10*2+r14] -DB 0x67 + DB 0x67 shr r10,63 lea r13,[r11*2+rcx] shr r11,63 @@ -1800,7 +1805,7 @@ __bn_sqr8x_reduction: ALIGN 32 $L$8x_reduction_loop: lea rdi,[r9*1+rdi] -DB 0x66 + DB 0x66 mov rbx,QWORD[rdi] mov r9,QWORD[8+rdi] mov r10,QWORD[16+rdi] @@ -1812,7 +1817,7 @@ DB 0x66 mov QWORD[rdx],rax lea rdi,[64+rdi] -DB 0x67 + DB 0x67 mov r8,rbx imul rbx,QWORD[((32+8))+rsp] mov rax,QWORD[rbp] @@ -1896,7 +1901,7 @@ $L$8x_reduce: cmp rbp,QWORD[((0+8))+rsp] jae NEAR $L$8x_no_tail -DB 0x66 + DB 0x66 add r8,QWORD[rdi] adc r9,QWORD[8+rdi] adc r10,QWORD[16+rdi] @@ -2104,200 +2109,6 @@ $L$sqr4x_sub_entry: DB 0F3h,0C3h ;repret -global bn_from_montgomery - -ALIGN 32 -bn_from_montgomery: - - test DWORD[48+rsp],7 - jz NEAR bn_from_mont8x - xor eax,eax - DB 0F3h,0C3h ;repret - - - - -ALIGN 32 -bn_from_mont8x: - mov QWORD[8+rsp],rdi ;WIN64 prologue - mov QWORD[16+rsp],rsi - mov rax,rsp -$L$SEH_begin_bn_from_mont8x: - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,QWORD[40+rsp] - mov r9,QWORD[48+rsp] - - - -DB 0x67 - mov rax,rsp - - push rbx - - push rbp - - push r12 - - push r13 - - push r14 - - push r15 - -$L$from_prologue: - - shl r9d,3 - lea r10,[r9*2+r9] - neg r9 - mov r8,QWORD[r8] - - - - - - - - - lea r11,[((-320))+r9*2+rsp] - mov rbp,rsp - sub r11,rdi - and r11,4095 - cmp r10,r11 - jb NEAR $L$from_sp_alt - sub rbp,r11 - lea rbp,[((-320))+r9*2+rbp] - jmp NEAR $L$from_sp_done - -ALIGN 32 -$L$from_sp_alt: - lea r10,[((4096-320))+r9*2] - lea rbp,[((-320))+r9*2+rbp] - sub r11,r10 - mov r10,0 - cmovc r11,r10 - sub rbp,r11 -$L$from_sp_done: - and rbp,-64 - mov r11,rsp - sub r11,rbp - and r11,-4096 - lea rsp,[rbp*1+r11] - mov r10,QWORD[rsp] - cmp rsp,rbp - ja NEAR $L$from_page_walk - jmp NEAR $L$from_page_walk_done - -$L$from_page_walk: - lea rsp,[((-4096))+rsp] - mov r10,QWORD[rsp] - cmp rsp,rbp - ja NEAR $L$from_page_walk -$L$from_page_walk_done: - - mov r10,r9 - neg r9 - - - - - - - - - - - mov QWORD[32+rsp],r8 - mov QWORD[40+rsp],rax - -$L$from_body: - mov r11,r9 - lea rax,[48+rsp] - pxor xmm0,xmm0 - jmp NEAR $L$mul_by_1 - -ALIGN 32 -$L$mul_by_1: - movdqu xmm1,XMMWORD[rsi] - movdqu xmm2,XMMWORD[16+rsi] - movdqu xmm3,XMMWORD[32+rsi] - movdqa XMMWORD[r9*1+rax],xmm0 - movdqu xmm4,XMMWORD[48+rsi] - movdqa XMMWORD[16+r9*1+rax],xmm0 -DB 0x48,0x8d,0xb6,0x40,0x00,0x00,0x00 - movdqa XMMWORD[rax],xmm1 - movdqa XMMWORD[32+r9*1+rax],xmm0 - movdqa XMMWORD[16+rax],xmm2 - movdqa XMMWORD[48+r9*1+rax],xmm0 - movdqa XMMWORD[32+rax],xmm3 - movdqa XMMWORD[48+rax],xmm4 - lea rax,[64+rax] - sub r11,64 - jnz NEAR $L$mul_by_1 - -DB 102,72,15,110,207 -DB 102,72,15,110,209 -DB 0x67 - mov rbp,rcx -DB 102,73,15,110,218 - lea r11,[OPENSSL_ia32cap_P] - mov r11d,DWORD[8+r11] - and r11d,0x80108 - cmp r11d,0x80108 - jne NEAR $L$from_mont_nox - - lea rdi,[r9*1+rax] - call __bn_sqrx8x_reduction - call __bn_postx4x_internal - - pxor xmm0,xmm0 - lea rax,[48+rsp] - jmp NEAR $L$from_mont_zero - -ALIGN 32 -$L$from_mont_nox: - call __bn_sqr8x_reduction - call __bn_post4x_internal - - pxor xmm0,xmm0 - lea rax,[48+rsp] - jmp NEAR $L$from_mont_zero - -ALIGN 32 -$L$from_mont_zero: - mov rsi,QWORD[40+rsp] - - movdqa XMMWORD[rax],xmm0 - movdqa XMMWORD[16+rax],xmm0 - movdqa XMMWORD[32+rax],xmm0 - movdqa XMMWORD[48+rax],xmm0 - lea rax,[64+rax] - sub r9,32 - jnz NEAR $L$from_mont_zero - - mov rax,1 - mov r15,QWORD[((-48))+rsi] - - mov r14,QWORD[((-40))+rsi] - - mov r13,QWORD[((-32))+rsi] - - mov r12,QWORD[((-24))+rsi] - - mov rbp,QWORD[((-16))+rsi] - - mov rbx,QWORD[((-8))+rsi] - - lea rsp,[rsi] - -$L$from_epilogue: - mov rdi,QWORD[8+rsp] ;WIN64 epilogue - mov rsi,QWORD[16+rsp] - DB 0F3h,0C3h ;repret - -$L$SEH_end_bn_from_mont8x: ALIGN 32 bn_mulx4x_mont_gather5: @@ -2447,9 +2258,9 @@ mulx4x_internal: pshufd xmm5,xmm5,0 movdqa xmm4,xmm1 -DB 0x67 + DB 0x67 movdqa xmm2,xmm1 -DB 0x67 + DB 0x67 paddd xmm1,xmm0 pcmpeqd xmm0,xmm5 movdqa xmm3,xmm4 @@ -2510,7 +2321,7 @@ DB 0x67 pcmpeqd xmm0,xmm5 movdqa XMMWORD[288+r10],xmm3 movdqa xmm3,xmm4 -DB 0x67 + DB 0x67 paddd xmm2,xmm1 pcmpeqd xmm1,xmm5 movdqa XMMWORD[304+r10],xmm0 @@ -2566,6 +2377,7 @@ DB 0x67 por xmm0,xmm2 por xmm1,xmm3 pxor xmm0,xmm1 + pshufd xmm1,xmm0,0x4e por xmm0,xmm1 lea rdi,[256+rdi] @@ -2622,7 +2434,7 @@ $L$mulx4x_1st: mulx rax,r12,QWORD[16+rsi] adcx r12,r14 mulx r14,r13,QWORD[24+rsi] -DB 0x67,0x67 + DB 0x67,0x67 mov rdx,r8 adcx r13,rax adcx r14,rbp @@ -2665,7 +2477,7 @@ ALIGN 32 $L$mulx4x_outer: lea r10,[((16-256))+rbx] pxor xmm4,xmm4 -DB 0x67,0x67 + DB 0x67,0x67 pxor xmm5,xmm5 movdqa xmm0,XMMWORD[((-128))+rdi] movdqa xmm1,XMMWORD[((-112))+rdi] @@ -2716,6 +2528,7 @@ DB 0x67,0x67 por xmm4,xmm2 por xmm5,xmm3 por xmm4,xmm5 + pshufd xmm0,xmm4,0x4e por xmm0,xmm4 lea rdi,[256+rdi] @@ -3050,9 +2863,9 @@ __bn_sqrx8x_internal: jmp NEAR $L$sqr8x_zero_start ALIGN 32 -DB 0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 + DB 0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 $L$sqrx8x_zero: -DB 0x3e + DB 0x3e movdqa XMMWORD[rdi],xmm0 movdqa XMMWORD[16+rdi],xmm0 movdqa XMMWORD[32+rdi],xmm0 @@ -3086,10 +2899,10 @@ $L$sqrx8x_outer_loop: mulx rax,r9,QWORD[16+rsi] adcx r9,r10 adox r11,rax -DB 0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00 + DB 0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00 adcx r10,r11 adox r12,rax -DB 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 + DB 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 adcx r11,r12 adox r13,rax mulx rax,r12,QWORD[40+rsi] @@ -3116,13 +2929,13 @@ DB 0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00 mulx rbx,r10,QWORD[32+rsi] adcx r9,r11 adox r10,rax -DB 0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00 + DB 0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00 adcx r10,r12 adox r11,rbx -DB 0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00 + DB 0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00 adcx r11,r13 adox r12,r14 -DB 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 + DB 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 mov rdx,QWORD[16+rsi] adcx r12,rax adox r13,rbx @@ -3140,11 +2953,11 @@ DB 0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00 mulx rbx,r10,QWORD[40+rsi] adcx r9,r11 adox r10,rax -DB 0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00 + DB 0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00 adcx r10,r12 adox r11,r13 -DB 0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00 -DB 0x3e + DB 0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00 + DB 0x3e mov rdx,QWORD[24+rsi] adcx r11,rbx adox r12,rax @@ -3196,7 +3009,7 @@ DB 0x3e adcx r12,rax adox r13,rbp -DB 0x67,0x67 + DB 0x67,0x67 mulx r14,r8,r8 adcx r13,r8 adcx r14,rbp @@ -3246,7 +3059,7 @@ $L$sqrx8x_loop: adcx r10,rax adox r11,r12 -DB 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + DB 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 adcx r11,rax adox r12,r13 @@ -3260,13 +3073,13 @@ DB 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 adcx r13,rax adox r14,r15 -DB 0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00 + DB 0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00 mov rdx,QWORD[8+rcx*8+rsi] adcx r14,rax adox r15,rbx adcx r15,rbx -DB 0x67 + DB 0x67 inc rcx jnz NEAR $L$sqrx8x_loop @@ -3276,7 +3089,7 @@ DB 0x67 je NEAR $L$sqrx8x_break sub rbx,QWORD[((16+8))+rsp] -DB 0x66 + DB 0x66 mov rdx,QWORD[((-64))+rsi] adcx r8,QWORD[rdi] adcx r9,QWORD[8+rdi] @@ -3287,7 +3100,7 @@ DB 0x66 adc r14,QWORD[48+rdi] adc r15,QWORD[56+rdi] lea rdi,[64+rdi] -DB 0x67 + DB 0x67 sbb rax,rax xor ebx,ebx mov QWORD[((16+8))+rsp],rax @@ -3353,8 +3166,8 @@ $L$sqrx4x_shift_n_add: mulx rbx,rax,rdx adox r12,r12 adcx rax,r10 -DB 0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00 -DB 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 + DB 0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00 + DB 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 adox r13,r13 adcx rbx,r11 mov r11,QWORD[40+rdi] @@ -3388,7 +3201,7 @@ DB 0x4c,0x8b,0x97,0x20,0x00,0x00,0x00 adox r10,r10 adcx rax,r12 jrcxz $L$sqrx4x_shift_n_add_break -DB 0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00 + DB 0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00 adox r11,r11 adcx rbx,r13 mov r12,QWORD[80+rdi] @@ -3455,7 +3268,7 @@ $L$sqrx8x_reduce: adcx r10,rbx adox r11,r12 -DB 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 + DB 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 mov rax,rdx mov rdx,r8 adcx r11,rbx @@ -3479,7 +3292,7 @@ DB 0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00 adox r15,rsi adcx r15,rsi -DB 0x67,0x67,0x67 + DB 0x67,0x67,0x67 inc rcx jnz NEAR $L$sqrx8x_reduce @@ -3524,7 +3337,7 @@ $L$sqrx8x_tail: adcx r10,rax adox r11,r12 -DB 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 + DB 0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00 adcx r11,rax adox r12,r13 @@ -3676,6 +3489,15 @@ bn_scatter5: cmp edx,0 jz NEAR $L$scatter_epilogue + + + + + + + + + lea r8,[r9*8+r8] $L$scatter: mov rax,QWORD[rcx] @@ -3696,9 +3518,9 @@ bn_gather5: $L$SEH_begin_bn_gather5: -DB 0x4c,0x8d,0x14,0x24 + DB 0x4c,0x8d,0x14,0x24 -DB 0x48,0x81,0xec,0x08,0x01,0x00,0x00 + DB 0x48,0x81,0xec,0x08,0x01,0x00,0x00 lea rax,[$L$inc] and rsp,-16 @@ -3843,6 +3665,7 @@ $L$gather: por xmm5,xmm3 por xmm4,xmm5 lea r11,[256+r11] + pshufd xmm0,xmm4,0x4e por xmm0,xmm4 movq QWORD[rcx],xmm0 @@ -3856,16 +3679,19 @@ $L$gather: $L$SEH_end_bn_gather5: +section .rdata rdata align=8 ALIGN 64 $L$inc: DD 0,0,1,1 DD 2,2,2,2 -DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 -DB 112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115 -DB 99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111 -DB 114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79 -DB 71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111 -DB 112,101,110,115,115,108,46,111,114,103,62,0 + DB 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 + DB 112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115 + DB 99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111 + DB 114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79 + DB 71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111 + DB 112,101,110,115,115,108,46,111,114,103,62,0 +section .text + EXTERN __imp_RtlVirtualUnwind ALIGN 16 @@ -3982,10 +3808,6 @@ ALIGN 4 DD $L$SEH_begin_bn_power5 wrt ..imagebase DD $L$SEH_end_bn_power5 wrt ..imagebase DD $L$SEH_info_bn_power5 wrt ..imagebase - - DD $L$SEH_begin_bn_from_mont8x wrt ..imagebase - DD $L$SEH_end_bn_from_mont8x wrt ..imagebase - DD $L$SEH_info_bn_from_mont8x wrt ..imagebase DD $L$SEH_begin_bn_mulx4x_mont_gather5 wrt ..imagebase DD $L$SEH_end_bn_mulx4x_mont_gather5 wrt ..imagebase DD $L$SEH_info_bn_mulx4x_mont_gather5 wrt ..imagebase @@ -4000,37 +3822,36 @@ ALIGN 4 section .xdata rdata align=8 ALIGN 8 $L$SEH_info_bn_mul_mont_gather5: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$mul_body wrt ..imagebase,$L$mul_body wrt ..imagebase,$L$mul_epilogue wrt ..imagebase ALIGN 8 $L$SEH_info_bn_mul4x_mont_gather5: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$mul4x_prologue wrt ..imagebase,$L$mul4x_body wrt ..imagebase,$L$mul4x_epilogue wrt ..imagebase ALIGN 8 $L$SEH_info_bn_power5: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$power5_prologue wrt ..imagebase,$L$power5_body wrt ..imagebase,$L$power5_epilogue wrt ..imagebase ALIGN 8 -$L$SEH_info_bn_from_mont8x: -DB 9,0,0,0 - DD mul_handler wrt ..imagebase - DD $L$from_prologue wrt ..imagebase,$L$from_body wrt ..imagebase,$L$from_epilogue wrt ..imagebase -ALIGN 8 $L$SEH_info_bn_mulx4x_mont_gather5: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$mulx4x_prologue wrt ..imagebase,$L$mulx4x_body wrt ..imagebase,$L$mulx4x_epilogue wrt ..imagebase ALIGN 8 $L$SEH_info_bn_powerx5: -DB 9,0,0,0 + DB 9,0,0,0 DD mul_handler wrt ..imagebase DD $L$powerx5_prologue wrt ..imagebase,$L$powerx5_body wrt ..imagebase,$L$powerx5_epilogue wrt ..imagebase ALIGN 8 $L$SEH_info_bn_gather5: -DB 0x01,0x0b,0x03,0x0a -DB 0x0b,0x01,0x21,0x00 -DB 0x04,0xa3,0x00,0x00 + DB 0x01,0x0b,0x03,0x0a + DB 0x0b,0x01,0x21,0x00 + DB 0x04,0xa3,0x00,0x00 ALIGN 8 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64.asm b/third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64-win.asm similarity index 61% rename from third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64.asm rename to third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64-win.asm index 99006695..a63c060f 100644 --- a/third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64.asm +++ b/third_party/boringssl/kit/win-x86_64/crypto/test/trampoline-x86_64-win.asm @@ -1,6 +1,7 @@ ; This file is generated from a similarly-named Perl script in the BoringSSL ; source tree. Do not edit by hand. +%ifidn __OUTPUT_FORMAT__, win64 default rel %define XMMWORD %define YMMWORD @@ -23,8 +24,8 @@ section .text code align=64 global abi_test_trampoline ALIGN 16 abi_test_trampoline: -$L$abi_test_trampoline_seh_begin: +$L$SEH_begin_abi_test_trampoline_1: @@ -36,62 +37,61 @@ $L$abi_test_trampoline_seh_begin: sub rsp,344 -$L$abi_test_trampoline_seh_prolog_alloc: +$L$SEH_prolog_abi_test_trampoline_2: mov QWORD[112+rsp],rbx -$L$abi_test_trampoline_seh_prolog_rbx: +$L$SEH_prolog_abi_test_trampoline_3: mov QWORD[120+rsp],rbp -$L$abi_test_trampoline_seh_prolog_rbp: +$L$SEH_prolog_abi_test_trampoline_4: mov QWORD[128+rsp],rdi -$L$abi_test_trampoline_seh_prolog_rdi: +$L$SEH_prolog_abi_test_trampoline_5: mov QWORD[136+rsp],rsi -$L$abi_test_trampoline_seh_prolog_rsi: +$L$SEH_prolog_abi_test_trampoline_6: mov QWORD[144+rsp],r12 -$L$abi_test_trampoline_seh_prolog_r12: +$L$SEH_prolog_abi_test_trampoline_7: mov QWORD[152+rsp],r13 -$L$abi_test_trampoline_seh_prolog_r13: +$L$SEH_prolog_abi_test_trampoline_8: mov QWORD[160+rsp],r14 -$L$abi_test_trampoline_seh_prolog_r14: +$L$SEH_prolog_abi_test_trampoline_9: mov QWORD[168+rsp],r15 -$L$abi_test_trampoline_seh_prolog_r15: +$L$SEH_prolog_abi_test_trampoline_10: movdqa XMMWORD[176+rsp],xmm6 -$L$abi_test_trampoline_seh_prolog_xmm6: +$L$SEH_prolog_abi_test_trampoline_11: movdqa XMMWORD[192+rsp],xmm7 -$L$abi_test_trampoline_seh_prolog_xmm7: +$L$SEH_prolog_abi_test_trampoline_12: movdqa XMMWORD[208+rsp],xmm8 -$L$abi_test_trampoline_seh_prolog_xmm8: +$L$SEH_prolog_abi_test_trampoline_13: movdqa XMMWORD[224+rsp],xmm9 -$L$abi_test_trampoline_seh_prolog_xmm9: +$L$SEH_prolog_abi_test_trampoline_14: movdqa XMMWORD[240+rsp],xmm10 -$L$abi_test_trampoline_seh_prolog_xmm10: +$L$SEH_prolog_abi_test_trampoline_15: movdqa XMMWORD[256+rsp],xmm11 -$L$abi_test_trampoline_seh_prolog_xmm11: +$L$SEH_prolog_abi_test_trampoline_16: movdqa XMMWORD[272+rsp],xmm12 -$L$abi_test_trampoline_seh_prolog_xmm12: +$L$SEH_prolog_abi_test_trampoline_17: movdqa XMMWORD[288+rsp],xmm13 -$L$abi_test_trampoline_seh_prolog_xmm13: +$L$SEH_prolog_abi_test_trampoline_18: movdqa XMMWORD[304+rsp],xmm14 -$L$abi_test_trampoline_seh_prolog_xmm14: +$L$SEH_prolog_abi_test_trampoline_19: movdqa XMMWORD[320+rsp],xmm15 -$L$abi_test_trampoline_seh_prolog_xmm15: -$L$abi_test_trampoline_seh_prolog_end: +$L$SEH_prolog_abi_test_trampoline_20: mov rbx,QWORD[rdx] mov rbp,QWORD[8+rdx] mov rdi,QWORD[16+rdx] @@ -252,7 +252,7 @@ $L$call_done: DB 0F3h,0C3h ;repret -$L$abi_test_trampoline_seh_end: +$L$SEH_end_abi_test_trampoline_21: global abi_test_clobber_rax @@ -479,10 +479,10 @@ global abi_test_bad_unwind_wrong_register ALIGN 16 abi_test_bad_unwind_wrong_register: -$L$abi_test_bad_unwind_wrong_register_seh_begin: +$L$SEH_begin_abi_test_bad_unwind_wrong_register_1: push r12 -$L$abi_test_bad_unwind_wrong_register_seh_push_r13: +$L$SEH_prolog_abi_test_bad_unwind_wrong_register_2: @@ -490,7 +490,7 @@ $L$abi_test_bad_unwind_wrong_register_seh_push_r13: pop r12 DB 0F3h,0C3h ;repret -$L$abi_test_bad_unwind_wrong_register_seh_end: +$L$SEH_end_abi_test_bad_unwind_wrong_register_3: @@ -502,10 +502,10 @@ global abi_test_bad_unwind_temporary ALIGN 16 abi_test_bad_unwind_temporary: -$L$abi_test_bad_unwind_temporary_seh_begin: +$L$SEH_begin_abi_test_bad_unwind_temporary_1: push r12 -$L$abi_test_bad_unwind_temporary_seh_push_r12: +$L$SEH_prolog_abi_test_bad_unwind_temporary_2: mov rax,r12 inc rax @@ -519,8 +519,8 @@ $L$abi_test_bad_unwind_temporary_seh_push_r12: pop r12 DB 0F3h,0C3h ;repret -$L$abi_test_bad_unwind_temporary_seh_end: +$L$SEH_end_abi_test_bad_unwind_temporary_3: @@ -553,9 +553,9 @@ abi_test_set_direction_flag: global abi_test_bad_unwind_epilog ALIGN 16 abi_test_bad_unwind_epilog: -$L$abi_test_bad_unwind_epilog_seh_begin: +$L$SEH_begin_abi_test_bad_unwind_epilog_1: push r12 -$L$abi_test_bad_unwind_epilog_seh_push_r12: +$L$SEH_prolog_abi_test_bad_unwind_epilog_2: nop @@ -563,120 +563,116 @@ $L$abi_test_bad_unwind_epilog_seh_push_r12: pop r12 nop DB 0F3h,0C3h ;repret -$L$abi_test_bad_unwind_epilog_seh_end: +$L$SEH_end_abi_test_bad_unwind_epilog_3: section .pdata rdata align=4 ALIGN 4 + DD $L$SEH_begin_abi_test_trampoline_1 wrt ..imagebase + DD $L$SEH_end_abi_test_trampoline_21 wrt ..imagebase + DD $L$SEH_info_abi_test_trampoline_0 wrt ..imagebase - DD $L$abi_test_trampoline_seh_begin wrt ..imagebase - DD $L$abi_test_trampoline_seh_end wrt ..imagebase - DD $L$abi_test_trampoline_seh_info wrt ..imagebase + DD $L$SEH_begin_abi_test_bad_unwind_wrong_register_1 wrt ..imagebase + DD $L$SEH_end_abi_test_bad_unwind_wrong_register_3 wrt ..imagebase + DD $L$SEH_info_abi_test_bad_unwind_wrong_register_0 wrt ..imagebase - DD $L$abi_test_bad_unwind_wrong_register_seh_begin wrt ..imagebase - DD $L$abi_test_bad_unwind_wrong_register_seh_end wrt ..imagebase - DD $L$abi_test_bad_unwind_wrong_register_seh_info wrt ..imagebase + DD $L$SEH_begin_abi_test_bad_unwind_temporary_1 wrt ..imagebase + DD $L$SEH_end_abi_test_bad_unwind_temporary_3 wrt ..imagebase + DD $L$SEH_info_abi_test_bad_unwind_temporary_0 wrt ..imagebase - DD $L$abi_test_bad_unwind_temporary_seh_begin wrt ..imagebase - DD $L$abi_test_bad_unwind_temporary_seh_end wrt ..imagebase - DD $L$abi_test_bad_unwind_temporary_seh_info wrt ..imagebase + DD $L$SEH_begin_abi_test_bad_unwind_epilog_1 wrt ..imagebase + DD $L$SEH_end_abi_test_bad_unwind_epilog_3 wrt ..imagebase + DD $L$SEH_info_abi_test_bad_unwind_epilog_0 wrt ..imagebase - DD $L$abi_test_bad_unwind_epilog_seh_begin wrt ..imagebase - DD $L$abi_test_bad_unwind_epilog_seh_end wrt ..imagebase - DD $L$abi_test_bad_unwind_epilog_seh_info wrt ..imagebase section .xdata rdata align=8 -ALIGN 8 -$L$abi_test_trampoline_seh_info: - -DB 1 -DB $L$abi_test_trampoline_seh_prolog_end-$L$abi_test_trampoline_seh_begin -DB 38 -DB 0 -DB $L$abi_test_trampoline_seh_prolog_xmm15-$L$abi_test_trampoline_seh_begin -DB 248 +ALIGN 4 +$L$SEH_info_abi_test_trampoline_0: + DB 1 + DB $L$SEH_prolog_abi_test_trampoline_20-$L$SEH_begin_abi_test_trampoline_1 + DB 38 + DB 0 + DB $L$SEH_prolog_abi_test_trampoline_20-$L$SEH_begin_abi_test_trampoline_1 + DB 248 DW 20 -DB $L$abi_test_trampoline_seh_prolog_xmm14-$L$abi_test_trampoline_seh_begin -DB 232 + DB $L$SEH_prolog_abi_test_trampoline_19-$L$SEH_begin_abi_test_trampoline_1 + DB 232 DW 19 -DB $L$abi_test_trampoline_seh_prolog_xmm13-$L$abi_test_trampoline_seh_begin -DB 216 + DB $L$SEH_prolog_abi_test_trampoline_18-$L$SEH_begin_abi_test_trampoline_1 + DB 216 DW 18 -DB $L$abi_test_trampoline_seh_prolog_xmm12-$L$abi_test_trampoline_seh_begin -DB 200 + DB $L$SEH_prolog_abi_test_trampoline_17-$L$SEH_begin_abi_test_trampoline_1 + DB 200 DW 17 -DB $L$abi_test_trampoline_seh_prolog_xmm11-$L$abi_test_trampoline_seh_begin -DB 184 + DB $L$SEH_prolog_abi_test_trampoline_16-$L$SEH_begin_abi_test_trampoline_1 + DB 184 DW 16 -DB $L$abi_test_trampoline_seh_prolog_xmm10-$L$abi_test_trampoline_seh_begin -DB 168 + DB $L$SEH_prolog_abi_test_trampoline_15-$L$SEH_begin_abi_test_trampoline_1 + DB 168 DW 15 -DB $L$abi_test_trampoline_seh_prolog_xmm9-$L$abi_test_trampoline_seh_begin -DB 152 + DB $L$SEH_prolog_abi_test_trampoline_14-$L$SEH_begin_abi_test_trampoline_1 + DB 152 DW 14 -DB $L$abi_test_trampoline_seh_prolog_xmm8-$L$abi_test_trampoline_seh_begin -DB 136 + DB $L$SEH_prolog_abi_test_trampoline_13-$L$SEH_begin_abi_test_trampoline_1 + DB 136 DW 13 -DB $L$abi_test_trampoline_seh_prolog_xmm7-$L$abi_test_trampoline_seh_begin -DB 120 + DB $L$SEH_prolog_abi_test_trampoline_12-$L$SEH_begin_abi_test_trampoline_1 + DB 120 DW 12 -DB $L$abi_test_trampoline_seh_prolog_xmm6-$L$abi_test_trampoline_seh_begin -DB 104 + DB $L$SEH_prolog_abi_test_trampoline_11-$L$SEH_begin_abi_test_trampoline_1 + DB 104 DW 11 -DB $L$abi_test_trampoline_seh_prolog_r15-$L$abi_test_trampoline_seh_begin -DB 244 + DB $L$SEH_prolog_abi_test_trampoline_10-$L$SEH_begin_abi_test_trampoline_1 + DB 244 DW 21 -DB $L$abi_test_trampoline_seh_prolog_r14-$L$abi_test_trampoline_seh_begin -DB 228 + DB $L$SEH_prolog_abi_test_trampoline_9-$L$SEH_begin_abi_test_trampoline_1 + DB 228 DW 20 -DB $L$abi_test_trampoline_seh_prolog_r13-$L$abi_test_trampoline_seh_begin -DB 212 + DB $L$SEH_prolog_abi_test_trampoline_8-$L$SEH_begin_abi_test_trampoline_1 + DB 212 DW 19 -DB $L$abi_test_trampoline_seh_prolog_r12-$L$abi_test_trampoline_seh_begin -DB 196 + DB $L$SEH_prolog_abi_test_trampoline_7-$L$SEH_begin_abi_test_trampoline_1 + DB 196 DW 18 -DB $L$abi_test_trampoline_seh_prolog_rsi-$L$abi_test_trampoline_seh_begin -DB 100 + DB $L$SEH_prolog_abi_test_trampoline_6-$L$SEH_begin_abi_test_trampoline_1 + DB 100 DW 17 -DB $L$abi_test_trampoline_seh_prolog_rdi-$L$abi_test_trampoline_seh_begin -DB 116 + DB $L$SEH_prolog_abi_test_trampoline_5-$L$SEH_begin_abi_test_trampoline_1 + DB 116 DW 16 -DB $L$abi_test_trampoline_seh_prolog_rbp-$L$abi_test_trampoline_seh_begin -DB 84 + DB $L$SEH_prolog_abi_test_trampoline_4-$L$SEH_begin_abi_test_trampoline_1 + DB 84 DW 15 -DB $L$abi_test_trampoline_seh_prolog_rbx-$L$abi_test_trampoline_seh_begin -DB 52 + DB $L$SEH_prolog_abi_test_trampoline_3-$L$SEH_begin_abi_test_trampoline_1 + DB 52 DW 14 -DB $L$abi_test_trampoline_seh_prolog_alloc-$L$abi_test_trampoline_seh_begin -DB 1 + DB $L$SEH_prolog_abi_test_trampoline_2-$L$SEH_begin_abi_test_trampoline_1 + DB 1 DW 43 +$L$SEH_info_abi_test_bad_unwind_wrong_register_0: + DB 1 + DB $L$SEH_prolog_abi_test_bad_unwind_wrong_register_2-$L$SEH_begin_abi_test_bad_unwind_wrong_register_1 + DB 1 + DB 0 + DB $L$SEH_prolog_abi_test_bad_unwind_wrong_register_2-$L$SEH_begin_abi_test_bad_unwind_wrong_register_1 + DB 208 -ALIGN 8 -$L$abi_test_bad_unwind_wrong_register_seh_info: -DB 1 -DB $L$abi_test_bad_unwind_wrong_register_seh_push_r13-$L$abi_test_bad_unwind_wrong_register_seh_begin -DB 1 -DB 0 +$L$SEH_info_abi_test_bad_unwind_temporary_0: + DB 1 + DB $L$SEH_prolog_abi_test_bad_unwind_temporary_2-$L$SEH_begin_abi_test_bad_unwind_temporary_1 + DB 1 + DB 0 + DB $L$SEH_prolog_abi_test_bad_unwind_temporary_2-$L$SEH_begin_abi_test_bad_unwind_temporary_1 + DB 192 -DB $L$abi_test_bad_unwind_wrong_register_seh_push_r13-$L$abi_test_bad_unwind_wrong_register_seh_begin -DB 208 - -ALIGN 8 -$L$abi_test_bad_unwind_temporary_seh_info: -DB 1 -DB $L$abi_test_bad_unwind_temporary_seh_push_r12-$L$abi_test_bad_unwind_temporary_seh_begin -DB 1 -DB 0 - -DB $L$abi_test_bad_unwind_temporary_seh_push_r12-$L$abi_test_bad_unwind_temporary_seh_begin -DB 192 - -ALIGN 8 -$L$abi_test_bad_unwind_epilog_seh_info: -DB 1 -DB $L$abi_test_bad_unwind_epilog_seh_push_r12-$L$abi_test_bad_unwind_epilog_seh_begin -DB 1 -DB 0 - -DB $L$abi_test_bad_unwind_epilog_seh_push_r12-$L$abi_test_bad_unwind_epilog_seh_begin -DB 192 +$L$SEH_info_abi_test_bad_unwind_epilog_0: + DB 1 + DB $L$SEH_prolog_abi_test_bad_unwind_epilog_2-$L$SEH_begin_abi_test_bad_unwind_epilog_1 + DB 1 + DB 0 + DB $L$SEH_prolog_abi_test_bad_unwind_epilog_2-$L$SEH_begin_abi_test_bad_unwind_epilog_1 + DB 192 +%else +; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738 +ret +%endif diff --git a/third_party/protobuf.gyp b/third_party/protobuf.gyp index 79c2ed03..1c14e0cb 100644 --- a/third_party/protobuf.gyp +++ b/third_party/protobuf.gyp @@ -5,7 +5,7 @@ # point here and protobuf_config is set to 'source'. # # Based on the BUILD file in the Protobuf C++ release package. -# Source lists accurate as of Protobuf v3.8.0 +# Source lists accurate as of Protobuf v21.12 (aka 3.21.12) { # Some sources are used by both protobuf_lite and protobuf. Representing this @@ -18,9 +18,9 @@ 'protobuf/src/google/protobuf/any_lite.cc', 'protobuf/src/google/protobuf/arena.cc', 'protobuf/src/google/protobuf/arenastring.cc', + 'protobuf/src/google/protobuf/arenaz_sampler.cc', 'protobuf/src/google/protobuf/extension_set.cc', 'protobuf/src/google/protobuf/generated_enum_util.cc', - 'protobuf/src/google/protobuf/generated_message_table_driven_lite.cc', 'protobuf/src/google/protobuf/generated_message_tctable_lite.cc', 'protobuf/src/google/protobuf/generated_message_util.cc', 'protobuf/src/google/protobuf/implicit_weak_message.cc', @@ -117,7 +117,6 @@ 'protobuf/src/google/protobuf/field_mask.pb.cc', 'protobuf/src/google/protobuf/generated_message_bases.cc', 'protobuf/src/google/protobuf/generated_message_reflection.cc', - 'protobuf/src/google/protobuf/generated_message_table_driven.cc', 'protobuf/src/google/protobuf/generated_message_tctable_full.cc', 'protobuf/src/google/protobuf/io/gzip_stream.cc', 'protobuf/src/google/protobuf/io/printer.cc', @@ -182,21 +181,21 @@ 'sources': [ 'protobuf/src/google/protobuf/compiler/code_generator.cc', 'protobuf/src/google/protobuf/compiler/command_line_interface.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc', - 'protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/enum.cc', + 'protobuf/src/google/protobuf/compiler/cpp/enum_field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/extension.cc', + 'protobuf/src/google/protobuf/compiler/cpp/field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/file.cc', + 'protobuf/src/google/protobuf/compiler/cpp/generator.cc', + 'protobuf/src/google/protobuf/compiler/cpp/helpers.cc', + 'protobuf/src/google/protobuf/compiler/cpp/map_field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/message.cc', + 'protobuf/src/google/protobuf/compiler/cpp/message_field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.cc', + 'protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.cc', + 'protobuf/src/google/protobuf/compiler/cpp/primitive_field.cc', + 'protobuf/src/google/protobuf/compiler/cpp/service.cc', + 'protobuf/src/google/protobuf/compiler/cpp/string_field.cc', 'protobuf/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'protobuf/src/google/protobuf/compiler/csharp/csharp_enum.cc', 'protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.cc', @@ -213,37 +212,35 @@ 'protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'protobuf/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_context.cc', - 'protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc', - 'protobuf/src/google/protobuf/compiler/java/java_enum.cc', - 'protobuf/src/google/protobuf/compiler/java/java_enum_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_enum_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_extension.cc', - 'protobuf/src/google/protobuf/compiler/java/java_extension_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_file.cc', - 'protobuf/src/google/protobuf/compiler/java/java_generator.cc', - 'protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc', - 'protobuf/src/google/protobuf/compiler/java/java_helpers.cc', - 'protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.cc', - 'protobuf/src/google/protobuf/compiler/java/java_map_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_map_field_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message_builder.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message_field_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_message_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc', - 'protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.cc', - 'protobuf/src/google/protobuf/compiler/java/java_service.cc', - 'protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc', - 'protobuf/src/google/protobuf/compiler/java/java_string_field.cc', - 'protobuf/src/google/protobuf/compiler/java/java_string_field_lite.cc', - 'protobuf/src/google/protobuf/compiler/js/js_generator.cc', - 'protobuf/src/google/protobuf/compiler/js/well_known_types_embed.cc', + 'protobuf/src/google/protobuf/compiler/java/context.cc', + 'protobuf/src/google/protobuf/compiler/java/doc_comment.cc', + 'protobuf/src/google/protobuf/compiler/java/enum.cc', + 'protobuf/src/google/protobuf/compiler/java/enum_field.cc', + 'protobuf/src/google/protobuf/compiler/java/enum_field_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/enum_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/extension.cc', + 'protobuf/src/google/protobuf/compiler/java/extension_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/field.cc', + 'protobuf/src/google/protobuf/compiler/java/file.cc', + 'protobuf/src/google/protobuf/compiler/java/generator.cc', + 'protobuf/src/google/protobuf/compiler/java/generator_factory.cc', + 'protobuf/src/google/protobuf/compiler/java/helpers.cc', + 'protobuf/src/google/protobuf/compiler/java/kotlin_generator.cc', + 'protobuf/src/google/protobuf/compiler/java/map_field.cc', + 'protobuf/src/google/protobuf/compiler/java/map_field_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/message.cc', + 'protobuf/src/google/protobuf/compiler/java/message_builder.cc', + 'protobuf/src/google/protobuf/compiler/java/message_builder_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/message_field.cc', + 'protobuf/src/google/protobuf/compiler/java/message_field_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/message_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/name_resolver.cc', + 'protobuf/src/google/protobuf/compiler/java/primitive_field.cc', + 'protobuf/src/google/protobuf/compiler/java/primitive_field_lite.cc', + 'protobuf/src/google/protobuf/compiler/java/service.cc', + 'protobuf/src/google/protobuf/compiler/java/shared_code_generator.cc', + 'protobuf/src/google/protobuf/compiler/java/string_field.cc', + 'protobuf/src/google/protobuf/compiler/java/string_field_lite.cc', 'protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc', 'protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'protobuf/src/google/protobuf/compiler/objectivec/objectivec_extension.cc', @@ -259,7 +256,9 @@ 'protobuf/src/google/protobuf/compiler/php/php_generator.cc', 'protobuf/src/google/protobuf/compiler/plugin.cc', 'protobuf/src/google/protobuf/compiler/plugin.pb.cc', - 'protobuf/src/google/protobuf/compiler/python/python_generator.cc', + 'protobuf/src/google/protobuf/compiler/python/generator.cc', + 'protobuf/src/google/protobuf/compiler/python/helpers.cc', + 'protobuf/src/google/protobuf/compiler/python/pyi_generator.cc', 'protobuf/src/google/protobuf/compiler/ruby/ruby_generator.cc', 'protobuf/src/google/protobuf/compiler/subprocess.cc', 'protobuf/src/google/protobuf/compiler/zip_writer.cc', diff --git a/third_party/protobuf/BUILD b/third_party/protobuf/BUILD.bazel similarity index 68% rename from third_party/protobuf/BUILD rename to third_party/protobuf/BUILD.bazel index 1690d421..0f6e41e3 100644 --- a/third_party/protobuf/BUILD +++ b/third_party/protobuf/BUILD.bazel @@ -1,157 +1,29 @@ # Bazel (https://bazel.build/) BUILD file for Protobuf. load("@bazel_skylib//rules:common_settings.bzl", "string_flag") -load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test", "objc_library", native_cc_proto_library = "cc_proto_library") +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") load("@rules_python//python:defs.bzl", "py_library") load("@rules_java//java:defs.bzl", "java_binary", "java_lite_proto_library", "java_proto_library") -load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test") +load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS", "PROTOC_LINK_OPTS") +load( + ":protobuf.bzl", + "adapt_proto_library", + "cc_proto_library", + "internal_copied_filegroup", + "internal_protobuf_py_tests", + "py_proto_library", +) licenses(["notice"]) exports_files(["LICENSE"]) -################################################################################ -# build configuration -################################################################################ - -################################################################################ -# ZLIB configuration -################################################################################ - -ZLIB_DEPS = ["@zlib//:zlib"] - ################################################################################ # Protobuf Runtime Library ################################################################################ -MSVC_COPTS = [ - "/wd4018", # -Wno-sign-compare - "/wd4065", # switch statement contains 'default' but no 'case' labels - "/wd4146", # unary minus operator applied to unsigned type, result still unsigned - "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data - "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' - "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data - "/wd4305", # 'identifier' : truncation from 'type1' to 'type2' - "/wd4307", # 'operator' : integral constant overflow - "/wd4309", # 'conversion' : truncation of constant value - "/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) - "/wd4355", # 'this' : used in base member initializer list - "/wd4506", # no definition for inline function 'function' - "/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning) - "/wd4996", # The compiler encountered a deprecated declaration. -] - -COPTS = select({ - ":msvc": MSVC_COPTS, - "//conditions:default": [ - "-DHAVE_ZLIB", - "-Wmissing-field-initializers", - "-Woverloaded-virtual", - "-Wno-sign-compare", - ], -}) - -load(":compiler_config_setting.bzl", "create_compiler_config_setting") - -create_compiler_config_setting( - name = "msvc", - value = "msvc-cl", - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -# Android NDK builds can specify different crosstool_top flags to choose which -# STL they use for C++. We need these multiple variants to catch all of those -# versions of crosstool_top and reliably detect Android. -# -# For more info on the various crosstool_tops used by NDK Bazel builds, see: -# https://docs.bazel.build/versions/master/android-ndk.html#configuring-the-stl - -config_setting( - name = "android", - values = { - "crosstool_top": "//external:android/crosstool", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -config_setting( - name = "android-stlport", - values = { - "crosstool_top": "@androidndk//:toolchain-stlport", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -config_setting( - name = "android-libcpp", - values = { - "crosstool_top": "@androidndk//:toolchain-libcpp", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -config_setting( - name = "android-gnu-libstdcpp", - values = { - "crosstool_top": "@androidndk//:toolchain-gnu-libstdcpp", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -config_setting( - name = "android-default", - values = { - "crosstool_top": "@androidndk//:default_crosstool", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -# Android and MSVC builds do not need to link in a separate pthread library. -LINK_OPTS = select({ - ":android": [], - ":android-stlport": [], - ":android-libcpp": [], - ":android-gnu-libstdcpp": [], - ":android-default": [], - ":msvc": [ - # Suppress linker warnings about files with no symbols defined. - "-ignore:4221", - ], - "//conditions:default": [ - "-lpthread", - "-lm", - ], -}) - -load( - ":protobuf.bzl", - "adapt_proto_library", - "cc_proto_library", - "internal_copied_filegroup", - "internal_gen_well_known_protos_java", - "internal_protobuf_py_tests", - "py_proto_library", -) - cc_library( name = "protobuf_lite", srcs = [ @@ -159,9 +31,9 @@ cc_library( "src/google/protobuf/any_lite.cc", "src/google/protobuf/arena.cc", "src/google/protobuf/arenastring.cc", + "src/google/protobuf/arenaz_sampler.cc", "src/google/protobuf/extension_set.cc", "src/google/protobuf/generated_enum_util.cc", - "src/google/protobuf/generated_message_table_driven_lite.cc", "src/google/protobuf/generated_message_tctable_lite.cc", "src/google/protobuf/generated_message_util.cc", "src/google/protobuf/implicit_weak_message.cc", @@ -199,11 +71,6 @@ cc_library( visibility = ["//visibility:public"], ) -PROTOBUF_DEPS = select({ - ":msvc": [], - "//conditions:default": ZLIB_DEPS, -}) - cc_library( name = "protobuf", srcs = [ @@ -223,7 +90,6 @@ cc_library( "src/google/protobuf/field_mask.pb.cc", "src/google/protobuf/generated_message_bases.cc", "src/google/protobuf/generated_message_reflection.cc", - "src/google/protobuf/generated_message_table_driven.cc", "src/google/protobuf/generated_message_tctable_full.cc", "src/google/protobuf/io/gzip_stream.cc", "src/google/protobuf/io/printer.cc", @@ -270,7 +136,10 @@ cc_library( includes = ["src/"], linkopts = LINK_OPTS, visibility = ["//visibility:public"], - deps = [":protobuf_lite"] + PROTOBUF_DEPS, + deps = [":protobuf_lite"] + select({ + "//build_defs:config_msvc": [], + "//conditions:default": ["@zlib//:zlib"], + }), ) # This provides just the header files for use in projects that need to build @@ -287,83 +156,88 @@ cc_library( visibility = ["//visibility:public"], ) -# Map of all well known protos. -# name => (include path, imports) -WELL_KNOWN_PROTO_MAP = { - "any": ("src/google/protobuf/any.proto", []), - "api": ( - "src/google/protobuf/api.proto", - [ - "source_context", - "type", - ], - ), - "compiler_plugin": ( - "src/google/protobuf/compiler/plugin.proto", - ["descriptor"], - ), - "descriptor": ("src/google/protobuf/descriptor.proto", []), - "duration": ("src/google/protobuf/duration.proto", []), - "empty": ("src/google/protobuf/empty.proto", []), - "field_mask": ("src/google/protobuf/field_mask.proto", []), - "source_context": ("src/google/protobuf/source_context.proto", []), - "struct": ("src/google/protobuf/struct.proto", []), - "timestamp": ("src/google/protobuf/timestamp.proto", []), - "type": ( - "src/google/protobuf/type.proto", - [ - "any", - "source_context", - ], - ), - "wrappers": ("src/google/protobuf/wrappers.proto", []), -} - -WELL_KNOWN_PROTOS = [value[0] for value in WELL_KNOWN_PROTO_MAP.values()] - -LITE_WELL_KNOWN_PROTO_MAP = { - "any": ("src/google/protobuf/any.proto", []), - "api": ( - "src/google/protobuf/api.proto", - [ - "source_context", - "type", - ], - ), - "duration": ("src/google/protobuf/duration.proto", []), - "empty": ("src/google/protobuf/empty.proto", []), - "field_mask": ("src/google/protobuf/field_mask.proto", []), - "source_context": ("src/google/protobuf/source_context.proto", []), - "struct": ("src/google/protobuf/struct.proto", []), - "timestamp": ("src/google/protobuf/timestamp.proto", []), - "type": ( - "src/google/protobuf/type.proto", - [ - "any", - "source_context", - ], - ), - "wrappers": ("src/google/protobuf/wrappers.proto", []), -} - -LITE_WELL_KNOWN_PROTOS = [value[0] for value in LITE_WELL_KNOWN_PROTO_MAP.values()] - +# DEPRECATED: Prefer :well_known_type_protos for the Well-Known Types +# (https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) +# or :descriptor_proto(_srcs) for descriptor.proto (source), or +# :compiler_plugin_proto for compiler/plugin.proto. filegroup( name = "well_known_protos", - srcs = WELL_KNOWN_PROTOS, + srcs = [ + "src/google/protobuf/compiler/plugin.proto", + "src/google/protobuf/descriptor.proto", + ":well_known_type_protos", + ], + deprecation = "Prefer :well_known_type_protos instead.", visibility = ["//visibility:public"], ) filegroup( + name = "well_known_type_protos", + srcs = [ + "src/google/protobuf/any.proto", + "src/google/protobuf/api.proto", + "src/google/protobuf/duration.proto", + "src/google/protobuf/empty.proto", + "src/google/protobuf/field_mask.proto", + "src/google/protobuf/source_context.proto", + "src/google/protobuf/struct.proto", + "src/google/protobuf/timestamp.proto", + "src/google/protobuf/type.proto", + "src/google/protobuf/wrappers.proto", + ], + visibility = ["//visibility:public"], +) + +filegroup( + name = "built_in_runtime_protos", + srcs = [ + "src/google/protobuf/compiler/plugin.proto", + "src/google/protobuf/descriptor.proto", + ], + visibility = ["//:__subpackages__"], +) + +exports_files( + srcs = [ + "src/google/protobuf/any.proto", + "src/google/protobuf/api.proto", + "src/google/protobuf/compiler/plugin.proto", + "src/google/protobuf/descriptor.proto", + "src/google/protobuf/duration.proto", + "src/google/protobuf/empty.proto", + "src/google/protobuf/field_mask.proto", + "src/google/protobuf/source_context.proto", + "src/google/protobuf/struct.proto", + "src/google/protobuf/timestamp.proto", + "src/google/protobuf/type.proto", + "src/google/protobuf/wrappers.proto", + ], + visibility = ["//pkg:__pkg__"], +) + +alias( name = "lite_well_known_protos", - srcs = LITE_WELL_KNOWN_PROTOS, + actual = ":well_known_type_protos", visibility = ["//visibility:public"], ) adapt_proto_library( name = "cc_wkt_protos_genproto", visibility = ["//visibility:public"], - deps = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + deps = [ + "//:any_proto", + "//:api_proto", + "//:compiler_plugin_proto", + "//:descriptor_proto", + "//:duration_proto", + "//:empty_proto", + "//:field_mask_proto", + "//:source_context_proto", + "//:struct_proto", + "//:timestamp_proto", + "//:type_proto", + "//:wrappers_proto", + ], ) cc_library( @@ -375,6 +249,8 @@ cc_library( ################################################################################ # Well Known Types Proto Library Rules # +# https://developers.google.com/protocol-buffers/docs/reference/google.protobuf +################################################################################ # These proto_library rules can be used with one of the language specific proto # library rules i.e. java_proto_library: # @@ -384,31 +260,99 @@ cc_library( # ) ################################################################################ -[proto_library( - name = proto[0] + "_proto", - srcs = [proto[1][0]], +proto_library( + name = "any_proto", + srcs = ["src/google/protobuf/any.proto"], strip_import_prefix = "src", visibility = ["//visibility:public"], - deps = [dep + "_proto" for dep in proto[1][1]], -) for proto in WELL_KNOWN_PROTO_MAP.items()] +) -[native_cc_proto_library( - name = proto + "_cc_proto", - visibility = ["//visibility:private"], - deps = [proto + "_proto"], -) for proto in WELL_KNOWN_PROTO_MAP.keys()] - -cc_proto_blacklist_test( - name = "cc_proto_blacklist_test", - tags = [ - # Exclude this target from wildcard expansion (//...). Due to - # https://github.com/bazelbuild/bazel/issues/10590, this test has to - # be nominated using the `@com_google_protobuf//` prefix. We do that, - # e.g., in kokoro/linux/bazel/build.sh. - # See also https://github.com/protocolbuffers/protobuf/pull/7096. - "manual", +proto_library( + name = "api_proto", + srcs = ["src/google/protobuf/api.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], + deps = [ + "//:source_context_proto", + "//:type_proto", ], - deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], +) + +proto_library( + name = "duration_proto", + srcs = ["//:src/google/protobuf/duration.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "empty_proto", + srcs = ["src/google/protobuf/empty.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "field_mask_proto", + srcs = ["src/google/protobuf/field_mask.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "source_context_proto", + srcs = ["src/google/protobuf/source_context.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "struct_proto", + srcs = ["src/google/protobuf/struct.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "timestamp_proto", + srcs = ["src/google/protobuf/timestamp.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +proto_library( + name = "type_proto", + srcs = ["src/google/protobuf/type.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], + deps = [ + "//:any_proto", + "//:source_context_proto", + ], +) + +proto_library( + name = "wrappers_proto", + srcs = ["src/google/protobuf/wrappers.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], +) + +# Built-in runtime types + +proto_library( + name = "compiler_plugin_proto", + srcs = ["src/google/protobuf/compiler/plugin.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], + deps = ["//:descriptor_proto"], +) + +proto_library( + name = "descriptor_proto", + srcs = ["src/google/protobuf/descriptor.proto"], + strip_import_prefix = "src", + visibility = ["//visibility:public"], ) ################################################################################ @@ -421,21 +365,21 @@ cc_library( # AUTOGEN(protoc_lib_srcs) "src/google/protobuf/compiler/code_generator.cc", "src/google/protobuf/compiler/command_line_interface.cc", - "src/google/protobuf/compiler/cpp/cpp_enum.cc", - "src/google/protobuf/compiler/cpp/cpp_enum_field.cc", - "src/google/protobuf/compiler/cpp/cpp_extension.cc", - "src/google/protobuf/compiler/cpp/cpp_field.cc", - "src/google/protobuf/compiler/cpp/cpp_file.cc", - "src/google/protobuf/compiler/cpp/cpp_generator.cc", - "src/google/protobuf/compiler/cpp/cpp_helpers.cc", - "src/google/protobuf/compiler/cpp/cpp_map_field.cc", - "src/google/protobuf/compiler/cpp/cpp_message.cc", - "src/google/protobuf/compiler/cpp/cpp_message_field.cc", - "src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc", - "src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc", - "src/google/protobuf/compiler/cpp/cpp_primitive_field.cc", - "src/google/protobuf/compiler/cpp/cpp_service.cc", - "src/google/protobuf/compiler/cpp/cpp_string_field.cc", + "src/google/protobuf/compiler/cpp/enum.cc", + "src/google/protobuf/compiler/cpp/enum_field.cc", + "src/google/protobuf/compiler/cpp/extension.cc", + "src/google/protobuf/compiler/cpp/field.cc", + "src/google/protobuf/compiler/cpp/file.cc", + "src/google/protobuf/compiler/cpp/generator.cc", + "src/google/protobuf/compiler/cpp/helpers.cc", + "src/google/protobuf/compiler/cpp/map_field.cc", + "src/google/protobuf/compiler/cpp/message.cc", + "src/google/protobuf/compiler/cpp/message_field.cc", + "src/google/protobuf/compiler/cpp/padding_optimizer.cc", + "src/google/protobuf/compiler/cpp/parse_function_generator.cc", + "src/google/protobuf/compiler/cpp/primitive_field.cc", + "src/google/protobuf/compiler/cpp/service.cc", + "src/google/protobuf/compiler/cpp/string_field.cc", "src/google/protobuf/compiler/csharp/csharp_doc_comment.cc", "src/google/protobuf/compiler/csharp/csharp_enum.cc", "src/google/protobuf/compiler/csharp/csharp_enum_field.cc", @@ -452,37 +396,35 @@ cc_library( "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc", "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc", - "src/google/protobuf/compiler/java/java_context.cc", - "src/google/protobuf/compiler/java/java_doc_comment.cc", - "src/google/protobuf/compiler/java/java_enum.cc", - "src/google/protobuf/compiler/java/java_enum_field.cc", - "src/google/protobuf/compiler/java/java_enum_field_lite.cc", - "src/google/protobuf/compiler/java/java_enum_lite.cc", - "src/google/protobuf/compiler/java/java_extension.cc", - "src/google/protobuf/compiler/java/java_extension_lite.cc", - "src/google/protobuf/compiler/java/java_field.cc", - "src/google/protobuf/compiler/java/java_file.cc", - "src/google/protobuf/compiler/java/java_generator.cc", - "src/google/protobuf/compiler/java/java_generator_factory.cc", - "src/google/protobuf/compiler/java/java_helpers.cc", - "src/google/protobuf/compiler/java/java_kotlin_generator.cc", - "src/google/protobuf/compiler/java/java_map_field.cc", - "src/google/protobuf/compiler/java/java_map_field_lite.cc", - "src/google/protobuf/compiler/java/java_message.cc", - "src/google/protobuf/compiler/java/java_message_builder.cc", - "src/google/protobuf/compiler/java/java_message_builder_lite.cc", - "src/google/protobuf/compiler/java/java_message_field.cc", - "src/google/protobuf/compiler/java/java_message_field_lite.cc", - "src/google/protobuf/compiler/java/java_message_lite.cc", - "src/google/protobuf/compiler/java/java_name_resolver.cc", - "src/google/protobuf/compiler/java/java_primitive_field.cc", - "src/google/protobuf/compiler/java/java_primitive_field_lite.cc", - "src/google/protobuf/compiler/java/java_service.cc", - "src/google/protobuf/compiler/java/java_shared_code_generator.cc", - "src/google/protobuf/compiler/java/java_string_field.cc", - "src/google/protobuf/compiler/java/java_string_field_lite.cc", - "src/google/protobuf/compiler/js/js_generator.cc", - "src/google/protobuf/compiler/js/well_known_types_embed.cc", + "src/google/protobuf/compiler/java/context.cc", + "src/google/protobuf/compiler/java/doc_comment.cc", + "src/google/protobuf/compiler/java/enum.cc", + "src/google/protobuf/compiler/java/enum_field.cc", + "src/google/protobuf/compiler/java/enum_field_lite.cc", + "src/google/protobuf/compiler/java/enum_lite.cc", + "src/google/protobuf/compiler/java/extension.cc", + "src/google/protobuf/compiler/java/extension_lite.cc", + "src/google/protobuf/compiler/java/field.cc", + "src/google/protobuf/compiler/java/file.cc", + "src/google/protobuf/compiler/java/generator.cc", + "src/google/protobuf/compiler/java/generator_factory.cc", + "src/google/protobuf/compiler/java/helpers.cc", + "src/google/protobuf/compiler/java/kotlin_generator.cc", + "src/google/protobuf/compiler/java/map_field.cc", + "src/google/protobuf/compiler/java/map_field_lite.cc", + "src/google/protobuf/compiler/java/message.cc", + "src/google/protobuf/compiler/java/message_builder.cc", + "src/google/protobuf/compiler/java/message_builder_lite.cc", + "src/google/protobuf/compiler/java/message_field.cc", + "src/google/protobuf/compiler/java/message_field_lite.cc", + "src/google/protobuf/compiler/java/message_lite.cc", + "src/google/protobuf/compiler/java/name_resolver.cc", + "src/google/protobuf/compiler/java/primitive_field.cc", + "src/google/protobuf/compiler/java/primitive_field_lite.cc", + "src/google/protobuf/compiler/java/service.cc", + "src/google/protobuf/compiler/java/shared_code_generator.cc", + "src/google/protobuf/compiler/java/string_field.cc", + "src/google/protobuf/compiler/java/string_field_lite.cc", "src/google/protobuf/compiler/objectivec/objectivec_enum.cc", "src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc", "src/google/protobuf/compiler/objectivec/objectivec_extension.cc", @@ -498,7 +440,9 @@ cc_library( "src/google/protobuf/compiler/php/php_generator.cc", "src/google/protobuf/compiler/plugin.cc", "src/google/protobuf/compiler/plugin.pb.cc", - "src/google/protobuf/compiler/python/python_generator.cc", + "src/google/protobuf/compiler/python/generator.cc", + "src/google/protobuf/compiler/python/helpers.cc", + "src/google/protobuf/compiler/python/pyi_generator.cc", "src/google/protobuf/compiler/ruby/ruby_generator.cc", "src/google/protobuf/compiler/subprocess.cc", "src/google/protobuf/compiler/zip_writer.cc", @@ -513,7 +457,7 @@ cc_library( cc_binary( name = "protoc", srcs = ["src/google/protobuf/compiler/main.cc"], - linkopts = LINK_OPTS, + linkopts = LINK_OPTS + PROTOC_LINK_OPTS, visibility = ["//visibility:public"], deps = [":protoc_lib"], ) @@ -525,7 +469,10 @@ cc_binary( filegroup( name = "testdata", srcs = glob(["src/google/protobuf/testdata/**/*"]), - visibility = ["//:__subpackages__"], + visibility = [ + "//:__subpackages__", + "@upb//:__subpackages__", + ], ) RELATIVE_LITE_TEST_PROTOS = [ @@ -541,8 +488,8 @@ LITE_TEST_PROTOS = ["src/" + s for s in RELATIVE_LITE_TEST_PROTOS] RELATIVE_TEST_PROTOS = [ # AUTOGEN(test_protos) "google/protobuf/any_test.proto", - "google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto", - "google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto", + "google/protobuf/compiler/cpp/test_bad_identifiers.proto", + "google/protobuf/compiler/cpp/test_large_enum_value.proto", "google/protobuf/map_proto2_unittest.proto", "google/protobuf/map_unittest.proto", "google/protobuf/unittest.proto", @@ -590,6 +537,8 @@ RELATIVE_TEST_PROTOS = [ TEST_PROTOS = ["src/" + s for s in RELATIVE_TEST_PROTOS] GENERIC_RELATIVE_TEST_PROTOS = [ + "google/protobuf/map_proto2_unittest.proto", + "google/protobuf/map_unittest.proto", "google/protobuf/unittest.proto", "google/protobuf/unittest_arena.proto", "google/protobuf/unittest_custom_options.proto", @@ -699,23 +648,24 @@ cc_test( "src/google/protobuf/any_test.cc", "src/google/protobuf/arena_unittest.cc", "src/google/protobuf/arenastring_unittest.cc", + "src/google/protobuf/arenaz_sampler_test.cc", "src/google/protobuf/compiler/annotation_test_util.cc", "src/google/protobuf/compiler/command_line_interface_unittest.cc", - "src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc", - "src/google/protobuf/compiler/cpp/cpp_move_unittest.cc", - "src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc", - "src/google/protobuf/compiler/cpp/cpp_unittest.cc", - "src/google/protobuf/compiler/cpp/cpp_unittest.inc", + "src/google/protobuf/compiler/cpp/bootstrap_unittest.cc", "src/google/protobuf/compiler/cpp/metadata_test.cc", + "src/google/protobuf/compiler/cpp/move_unittest.cc", + "src/google/protobuf/compiler/cpp/plugin_unittest.cc", + "src/google/protobuf/compiler/cpp/unittest.cc", + "src/google/protobuf/compiler/cpp/unittest.inc", "src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc", "src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc", "src/google/protobuf/compiler/importer_unittest.cc", - "src/google/protobuf/compiler/java/java_doc_comment_unittest.cc", - "src/google/protobuf/compiler/java/java_plugin_unittest.cc", + "src/google/protobuf/compiler/java/doc_comment_unittest.cc", + "src/google/protobuf/compiler/java/plugin_unittest.cc", "src/google/protobuf/compiler/mock_code_generator.cc", "src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc", "src/google/protobuf/compiler/parser_unittest.cc", - "src/google/protobuf/compiler/python/python_plugin_unittest.cc", + "src/google/protobuf/compiler/python/plugin_unittest.cc", "src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc", "src/google/protobuf/descriptor_database_unittest.cc", "src/google/protobuf/descriptor_unittest.cc", @@ -723,6 +673,7 @@ cc_test( "src/google/protobuf/dynamic_message_unittest.cc", "src/google/protobuf/extension_set_unittest.cc", "src/google/protobuf/generated_message_reflection_unittest.cc", + "src/google/protobuf/generated_message_tctable_lite_test.cc", "src/google/protobuf/inlined_string_field_unittest.cc", "src/google/protobuf/io/coded_stream_unittest.cc", "src/google/protobuf/io/io_win32_unittest.cc", @@ -772,26 +723,26 @@ cc_test( "src/google/protobuf/well_known_types_unittest.cc", "src/google/protobuf/wire_format_unittest.cc", "src/google/protobuf/wire_format_unittest.inc", - ] + select({ - "//conditions:default": [ - # AUTOGEN(non_msvc_test_srcs) - ], - ":msvc": [], - }), + ], copts = COPTS + select({ - ":msvc": [], + "//build_defs:config_msvc": [], "//conditions:default": [ "-Wno-deprecated-declarations", ], }), data = [ + # Files for csharp_bootstrap_unittest.cc. + "//conformance:all_files", ":test_plugin", ] + glob([ "src/google/protobuf/**/*", - # Files for csharp_bootstrap_unittest.cc. - "conformance/**/*", - "csharp/src/**/*", - ]), + ]) + glob( + [ + # Files for csharp_bootstrap_unittest.cc. + "csharp/src/**/*", + ], + allow_empty = True, + ), includes = [ "src/", ], @@ -802,30 +753,16 @@ cc_test( ":protoc_lib", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", - ] + PROTOBUF_DEPS, + ] + select({ + "//build_defs:config_msvc": [], + "//conditions:default": ["@zlib//:zlib"], + }), ) ################################################################################ # Java support ################################################################################ -internal_gen_well_known_protos_java( - name = "gen_well_known_protos_java", - visibility = [ - "//java:__subpackages__", - ], - deps = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], -) - -internal_gen_well_known_protos_java( - name = "gen_well_known_protos_javalite", - javalite = True, - visibility = [ - "//java:__subpackages__", - ], - deps = [proto + "_proto" for proto in LITE_WELL_KNOWN_PROTO_MAP.keys()], -) - alias( name = "protobuf_java", actual = "//java/core", @@ -866,13 +803,23 @@ py_library( [ "python/google/protobuf/**/*.py", ], - exclude = [ + ), + imports = ["python"], + srcs_version = "PY2AND3", + visibility = ["@upb//:__subpackages__"], +) + +py_library( + name = "python_test_srcs", + srcs = glob( + [ "python/google/protobuf/internal/*_test.py", "python/google/protobuf/internal/test_util.py", ], ), imports = ["python"], - srcs_version = "PY2AND3", + srcs_version = "PY3", + visibility = ["@upb//:__subpackages__"], ) cc_binary( @@ -959,19 +906,49 @@ config_setting( # package. internal_copied_filegroup( name = "protos_python", - srcs = WELL_KNOWN_PROTOS, + srcs = [ + "src/google/protobuf/any.proto", + "src/google/protobuf/api.proto", + "src/google/protobuf/compiler/plugin.proto", + "src/google/protobuf/descriptor.proto", + "src/google/protobuf/duration.proto", + "src/google/protobuf/empty.proto", + "src/google/protobuf/field_mask.proto", + "src/google/protobuf/source_context.proto", + "src/google/protobuf/struct.proto", + "src/google/protobuf/timestamp.proto", + "src/google/protobuf/type.proto", + "src/google/protobuf/wrappers.proto", + ], dest = "python", strip_prefix = "src", ) -# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in -# which case we can simply add :protos_python in srcs. -COPIED_WELL_KNOWN_PROTOS = ["python/" + s[4:] for s in WELL_KNOWN_PROTOS] - py_proto_library( - name = "protobuf_python", - srcs = COPIED_WELL_KNOWN_PROTOS, + name = "well_known_types_py_pb2", + srcs = [ + "python/google/protobuf/any.proto", + "python/google/protobuf/api.proto", + "python/google/protobuf/compiler/plugin.proto", + "python/google/protobuf/descriptor.proto", + "python/google/protobuf/duration.proto", + "python/google/protobuf/empty.proto", + "python/google/protobuf/field_mask.proto", + "python/google/protobuf/source_context.proto", + "python/google/protobuf/struct.proto", + "python/google/protobuf/timestamp.proto", + "python/google/protobuf/type.proto", + "python/google/protobuf/wrappers.proto", + ], include = "python", + default_runtime = "", + protoc = ":protoc", + srcs_version = "PY2AND3", + visibility = ["//visibility:public"], +) + +py_library( + name = "protobuf_python", data = select({ "//conditions:default": [], ":use_fast_cpp_protos": [ @@ -979,13 +956,11 @@ py_proto_library( ":python/google/protobuf/pyext/_message.so", ], }), - default_runtime = "", - protoc = ":protoc", - py_libs = [ - ":python_srcs", - ], - srcs_version = "PY2AND3", visibility = ["//visibility:public"], + deps = [ + ":python_srcs", + ":well_known_types_py_pb2", + ], ) # Copy the test proto files from src/google/protobuf to @@ -1013,7 +988,8 @@ py_proto_library( default_runtime = "", protoc = ":protoc", srcs_version = "PY2AND3", - deps = [":protobuf_python"], + visibility = ["//visibility:public"], + deps = [":well_known_types_py_pb2"], ) py_proto_library( @@ -1026,6 +1002,7 @@ py_proto_library( default_runtime = ":protobuf_python", protoc = ":protoc", srcs_version = "PY2AND3", + visibility = ["//visibility:public"], deps = [":python_common_test_protos"], ) @@ -1083,7 +1060,20 @@ cc_library( proto_lang_toolchain( name = "cc_toolchain", - blacklisted_protos = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + blacklisted_protos = [ + "@com_google_protobuf//:any_proto", + "@com_google_protobuf//:api_proto", + "@com_google_protobuf//:compiler_plugin_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:field_mask_proto", + "@com_google_protobuf//:source_context_proto", + "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:type_proto", + "@com_google_protobuf//:wrappers_proto", + ], command_line = "--cpp_out=$(OUT)", runtime = ":protobuf", visibility = ["//visibility:public"], @@ -1092,12 +1082,14 @@ proto_lang_toolchain( alias( name = "objectivec", actual = "//objectivec", + tags = ["manual"], visibility = ["//visibility:public"], ) alias( name = "protobuf_objc", actual = "//objectivec", + tags = ["manual"], visibility = ["//visibility:public"], ) @@ -1108,7 +1100,7 @@ alias( genrule( name = "generated_protos", srcs = ["src/google/protobuf/unittest_import.proto"], - outs = ["unittest_gen.proto"], + outs = ["unittest_gen_import.proto"], cmd = "cat $(SRCS) | sed 's|google/|src/google/|' > $(OUTS)", ) @@ -1116,7 +1108,7 @@ proto_library( name = "generated_protos_proto", srcs = [ "src/google/protobuf/unittest_import_public.proto", - "unittest_gen.proto", + "unittest_gen_import.proto", ], ) @@ -1124,7 +1116,7 @@ py_proto_library( name = "generated_protos_py", srcs = [ "src/google/protobuf/unittest_import_public.proto", - "unittest_gen.proto", + "unittest_gen_import.proto", ], default_runtime = "", protoc = ":protoc", @@ -1134,14 +1126,22 @@ py_proto_library( # Conformance tests ################################################################################ +alias( + name = "conformance_test_runner", + actual = "//conformance:conformance_test_runner", + visibility = ["//visibility:public"], +) + proto_library( name = "test_messages_proto2_proto", + strip_import_prefix = "src", srcs = ["src/google/protobuf/test_messages_proto2.proto"], visibility = ["//visibility:public"], ) proto_library( name = "test_messages_proto3_proto", + strip_import_prefix = "src", srcs = ["src/google/protobuf/test_messages_proto3.proto"], visibility = ["//visibility:public"], deps = [ @@ -1154,87 +1154,6 @@ proto_library( ], ) -cc_proto_library( - name = "test_messages_proto2_proto_cc", - srcs = ["src/google/protobuf/test_messages_proto2.proto"], -) - -cc_proto_library( - name = "test_messages_proto3_proto_cc", - srcs = ["src/google/protobuf/test_messages_proto3.proto"], - deps = [ - ":cc_wkt_protos", - ], -) - -proto_library( - name = "conformance_proto", - srcs = ["conformance/conformance.proto"], - visibility = ["//visibility:public"], -) - -cc_proto_library( - name = "conformance_proto_cc", - srcs = ["conformance/conformance.proto"], -) - -cc_library( - name = "jsoncpp", - srcs = ["conformance/third_party/jsoncpp/jsoncpp.cpp"], - hdrs = ["conformance/third_party/jsoncpp/json.h"], - includes = ["conformance"], -) - -cc_library( - name = "conformance_test", - srcs = [ - "conformance/conformance_test.cc", - "conformance/conformance_test_runner.cc", - ], - hdrs = [ - "conformance/conformance_test.h", - ], - includes = [ - "conformance", - "src", - ], - deps = [":conformance_proto_cc"], -) - -cc_library( - name = "binary_json_conformance_suite", - srcs = ["conformance/binary_json_conformance_suite.cc"], - hdrs = ["conformance/binary_json_conformance_suite.h"], - deps = [ - ":conformance_test", - ":jsoncpp", - ":test_messages_proto2_proto_cc", - ":test_messages_proto3_proto_cc", - ], -) - -cc_library( - name = "text_format_conformance_suite", - srcs = ["conformance/text_format_conformance_suite.cc"], - hdrs = ["conformance/text_format_conformance_suite.h"], - deps = [ - ":conformance_test", - ":test_messages_proto2_proto_cc", - ":test_messages_proto3_proto_cc", - ], -) - -cc_binary( - name = "conformance_test_runner", - srcs = ["conformance/conformance_test_main.cc"], - visibility = ["//visibility:public"], - deps = [ - ":binary_json_conformance_suite", - ":conformance_test", - ":text_format_conformance_suite", - ], -) - # TODO: re-enable this test if appropriate, or replace with something that # uses the new setup. # sh_test( @@ -1257,6 +1176,7 @@ cc_binary( java_proto_library( name = "test_messages_proto2_java_proto", visibility = [ + "//conformance:__pkg__", "//java:__subpackages__", ], deps = [":test_messages_proto2_proto"], @@ -1265,85 +1185,184 @@ java_proto_library( java_proto_library( name = "test_messages_proto3_java_proto", visibility = [ + "//conformance:__pkg__", "//java:__subpackages__", ], deps = [":test_messages_proto3_proto"], ) -java_proto_library( - name = "conformance_java_proto", - visibility = [ - "//java:__subpackages__", - ], - deps = [":conformance_proto"], -) - java_lite_proto_library( name = "test_messages_proto2_java_proto_lite", visibility = [ + "//conformance:__pkg__", "//java:__subpackages__", ], deps = [":test_messages_proto2_proto"], ) -java_lite_proto_library( - name = "conformance_java_proto_lite", - visibility = [ - "//java:__subpackages__", - ], - deps = [":conformance_proto"], -) - java_lite_proto_library( name = "test_messages_proto3_java_proto_lite", visibility = [ + "//conformance:__pkg__", "//java:__subpackages__", ], deps = [":test_messages_proto3_proto"], ) -java_binary( - name = "conformance_java", - srcs = ["conformance/ConformanceJava.java"], - main_class = "ConformanceJava", - visibility = [ - "//java:__subpackages__", - ], - deps = [ - ":conformance_java_proto", - ":test_messages_proto2_java_proto", - ":test_messages_proto3_java_proto", - "//:protobuf_java", - "//:protobuf_java_util", - ], -) - -java_binary( - name = "conformance_java_lite", - srcs = ["conformance/ConformanceJavaLite.java"], - main_class = "ConformanceJavaLite", - visibility = [ - "//java:__subpackages__", - ], - deps = [ - ":conformance_java_proto_lite", - ":test_messages_proto2_java_proto_lite", - ":test_messages_proto3_java_proto_lite", - "//:protobuf_java_util", - "//:protobuf_javalite", - ], -) - -exports_files([ - "conformance/conformance_test_runner.sh", - "conformance/failure_list_java.txt", - "conformance/failure_list_java_lite.txt", - "conformance/text_format_failure_list_java.txt", - "conformance/text_format_failure_list_java_lite.txt", -]) - filegroup( name = "bzl_srcs", srcs = glob(["**/*.bzl"]), visibility = ["//visibility:public"], ) + +# Kotlin proto rules + +proto_library( + name = "kt_unittest_lite", + srcs = [ + "src/google/protobuf/map_lite_unittest.proto", + "src/google/protobuf/unittest_import_lite.proto", + "src/google/protobuf/unittest_import_public_lite.proto", + "src/google/protobuf/unittest_lite.proto", + ], + visibility = ["//java/kotlin-lite:__subpackages__"], + strip_import_prefix = "src", +) + +proto_library( + name = "kt_unittest", + srcs = [ + "src/google/protobuf/map_proto2_unittest.proto", + "src/google/protobuf/unittest.proto", + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + ], + visibility = ["//java/kotlin:__subpackages__"], + strip_import_prefix = "src", +) + +proto_library( + name = "kt_proto3_unittest", + srcs = [ + "src/google/protobuf/unittest_import.proto", + "src/google/protobuf/unittest_import_public.proto", + "src/google/protobuf/unittest_proto3.proto", + ], + visibility = [ + "//java/kotlin:__subpackages__", + "//java/kotlin-lite:__subpackages__", + ], + strip_import_prefix = "src", +) + +################################################################################ +# Packaging rules +################################################################################ + +# Files included in all source distributions +pkg_files( + name = "common_dist_files", + srcs = glob( + [ + "*.bzl", + "cmake/*.cmake", + "cmake/*.in", + "editors/*", + + # Several of these files are generated by autogen.sh, so using + # glob() lets us ignore them if they are missing. (This is not good + # practice, though.) + "Makefile.in", + "aclocal.m4", + "ar-lib", + "compile", + "config*", + "depcomp", + "install-sh", + "ltmain.sh", + "m4/*.m4", + "missing", + "protobuf*.pc.in", + "test-driver", + ], + allow_empty = True, + ) + [ + "BUILD.bazel", + "CHANGES.txt", + "CMakeLists.txt", + "CONTRIBUTORS.txt", + "LICENSE", + "Makefile.am", + "README.md", + "WORKSPACE", + "autogen.sh", + "build_files_updated_unittest.sh", + "cmake/CMakeLists.txt", + "cmake/README.md", + "generate_descriptor_proto.sh", + "maven_install.json", + "update_file_lists.sh", + "//third_party:BUILD.bazel", + "//third_party:zlib.BUILD", + "//util/python:BUILD.bazel", + ], + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) + +# C++ runtime +pkg_files( + name = "cpp_dist_files", + srcs = glob( + ["src/**/*"], + exclude = [ + "src/google/protobuf/compiler/objectivec/method_dump.sh", # not in autotools dist + ], + ), + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) + +# Additional files for C# +pkg_files( + name = "csharp_dist_files", + srcs = [ + "global.json", + ], + visibility = ["//pkg:__pkg__"], +) + +# Additional files for ObjC +pkg_files( + name = "objectivec_dist_files", + srcs = [ + "Protobuf.podspec", + ], + visibility = ["//pkg:__pkg__"], +) + +# Python runtime +pkg_files( + name = "python_dist_files", + srcs = glob([ + "python/google/**/*.proto", + "python/google/**/*.py", + "python/google/protobuf/internal/*.cc", + "python/google/protobuf/pyext/*.cc", + "python/google/protobuf/pyext/*.h", + ]) + [ + "python/MANIFEST.in", + "python/README.md", + "python/google/protobuf/proto_api.h", + "python/google/protobuf/pyext/README", + "python/google/protobuf/python_protobuf.h", + "python/mox.py", + "python/release.sh", + "python/setup.cfg", + "python/setup.py", + "python/stubout.py", + "python/tox.ini", + ], + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) diff --git a/third_party/protobuf/CHANGES.txt b/third_party/protobuf/CHANGES.txt index 926eff72..cf6a74db 100644 --- a/third_party/protobuf/CHANGES.txt +++ b/third_party/protobuf/CHANGES.txt @@ -1,3 +1,435 @@ +2022-12-07 version 21.11 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + Python + * Add license file to pypi wheels (#10936) + * Fix round-trip bug (#10158) + +2022-11-29 version 21.10 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + Java + * Use bit-field int values in buildPartial to skip work on unset groups of fields. (#10960) + * Mark nested builder as clean after clear is called (#10984) + UPB + * Fix UPB_LIKELY() for 32-bit Windows builds; update protobuf_deps to point to the current upb 21.x (#11028) + Other + * Add public modifiers to kotlin code (#11068) + +2022-10-26 version 21.9 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + C++ + * Update zlib to 1.2.13 (#10819) + + Python + * Target MacOS 10.9 to fix #10799 (#10807) + + Ruby + * Replace libc strdup usage with internal impl to restore musl compat (#10818) + +2022-10-18 version 21.8 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + Other + * Fix for grpc.tools #17995 & protobuf #7474 (handle UTF-8 paths in argumentfile) (#10721) + + C++ + * 21.x No longer define no_threadlocal on OpenBSD (#10743) + + Java + * Mark default instance as immutable first to avoid race during static initialization of default instances (#10771) + + Ruby + * Auto capitalize enums name in Ruby (#10454) (#10763) + + +2022-09-29 version 21.7 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + Java + * Refactoring java full runtime to reuse sub-message builders and prepare to + migrate parsing logic from parse constructor to builder. + * Move proto wireformat parsing functionality from the private "parsing + constructor" to the Builder class. + * Change the Lite runtime to prefer merging from the wireformat into mutable + messages rather than building up a new immutable object before merging. This + way results in fewer allocations and copy operations. + * Make message-type extensions merge from wire-format instead of building up + instances and merging afterwards. This has much better performance. + * Fix TextFormat parser to build up recurring (but supposedly not repeated) + sub-messages directly from text rather than building a new sub-message and + merging the fully formed message into the existing field. + +2022-09-13 version 21.6 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + +C++ +* Reduce memory consumption of MessageSet parsing + +2022-08-09 version 21.5 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + PHP + * Added getContainingOneof and getRealContainingOneof to descriptor. + * fix PHP readonly legacy files for nested messages + + Python + * Fixed comparison of maps in Python. + + +2022-07-25 version 21.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + C++ + * Reduce the required alignment of ArenaString from 8 to 4 (#10298) + + +2022-07-19 version 21.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + C++ + * Add header search paths to Protobuf-C++.podspec (#10024) + * Fixed Visual Studio constinit errors (#10232) + * Fix #9947: make the ABI compatible between debug and non-debug builds (#10271) + + UPB + * Allow empty package names (fixes behavior regression in 4.21.0) + * Fix a SEGV bug when comparing a non-materialized sub-message (#10208) + * Fix several bugs in descriptor mapping containers (eg. descriptor.services_by_name) + * for x in mapping now yields keys rather than values, to match Python conventions and the behavior of the old library. + * Lookup operations now correctly reject unhashable types as map keys. + * We implement repr() to use the same format as dict. + * Fix maps to use the ScalarMapContainer class when appropriate + * Fix bug when parsing an unknown value in a proto2 enum extension (protocolbuffers/upb#717) + + PHP + * Add "readonly" as a keyword for PHP and add previous classnames to descriptor pool (#10041) + + Python + * Make //:protobuf_python and //:well_known_types_py_pb2 public (#10118) + + Bazel + * Add back a filegroup for :well_known_protos (#10061) + +2022-06-27 version 21.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + C++ + * ArenaString improvements (fix alignment issue) + + PHP + * API changes for OneOf (#10102) + + +2022-05-27 version 21.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + C++ + * cmake: Revert "Fix cmake install targets (#9822)" (#10060) + * Remove Abseil dependency from CMake build (#10056) + + Python + * Update python wheel metadata with more information incl. required python version (#10058) + * Fix segmentation fault when instantiating field via repeated field assignment (#10066) + +2022-05-25 version 21.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + C++ + * cmake: Call get_filename_component() with DIRECTORY mode instead of PATH mode (#9614) + * Escape GetObject macro inside protoc-generated code (#9739) + * Update CMake configuration to add a dependency on Abseil (#9793) + * Fix cmake install targets (#9822) + * Use __constinit only in GCC 12.2 and up (#9936) + + Java + * Update protobuf_version.bzl to separate protoc and per-language java … (#9900) + + Python + * Increment python major version to 4 in version.json for python upb (#9926) + * The C extension module for Python has been rewritten to use the upb library. + This is expected to deliver significant performance benefits, especially when + parsing large payloads. There are some minor breaking changes, but these + should not impact most users. For more information see: + https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates + * Fixed win32 build and fixed str(message) on all Windows platforms. (#9976) + * The binary wheel for macOS now supports Apple silicon. + + PHP + * [PHP] fix PHP build system (#9571) + * Fix building packaged PHP extension (#9727) + * fix: reserve "ReadOnly" keyword for PHP 8.1 and add compatibility (#9633) + * fix: phpdoc syntax for repeatedfield parameters (#9784) + * fix: phpdoc for repeatedfield (#9783) + * Change enum string name for reserved words (#9780) + * chore: [PHP] fix phpdoc for MapField keys (#9536) + * Fixed PHP SEGV by not writing to shared memory for zend_class_entry. (#9996) + + Ruby + * Allow pre-compiled binaries for ruby 3.1.0 (#9566) + * Implement `respond_to?` in RubyMessage (#9677) + * [Ruby] Fix RepeatedField#last, #first inconsistencies (#9722) + * Do not use range based UTF-8 validation in truffleruby (#9769) + * Improve range handling logic of `RepeatedField` (#9799) + * Support x64-mingw-ucrt platform + + Other + * [Kotlin] remove redundant public modifiers for compiled code (#9642) + * [C#] Update GetExtension to support getting typed value (#9655) + * Fix invalid dependency manifest when using `descriptor_set_out` (#9647) + * Fix C# generator handling of a field named "none" in a oneof (#9636) + * Add initial version.json file for 21-dev (#9840) + * Remove duplicate java generated code (#9909) + * Cherry-pick PR #9981 into 21.x branch (#10000) + + +2022-05-19 version 21.0-rc2(C++/Java/Python/PHP/Objective-C/C#/Ruby) + + Python + * Fix windows builds + * Throw more helpful error if generated code is out of date + * Fixed two reference leaks + + Ruby + * Support x64-mingw-ucrt platform + + PHP + * Fix SEGV by not writing to shared memory for zend_class_entry + + C# + * Suppress warning CS8981 + + Other + * Fix Maven release to release actual osx_aarch64 binary + * Fix protoc zips to have the proto files for well known types + +2022-05-10 version 21.0-rc1 (C++/Java/Python/PHP/Objective-C/C#/Ruby) + + C++ + * Rename main cmake/CMakeLists.txt to CMakeLists.txt (#9603) + * avoid allocating memory if all extension are cleared (#9345) + * cmake: Call get_filename_component() with DIRECTORY mode instead of PATH mode (#9614) + * Escape GetObject macro inside protoc-generated code (#9739) + * Update CMake configuration to add a dependency on Abseil (#9793) + * Use __constinit only in GCC 12.2 and up (#9936) + * Refactor generated message class layout + * Optimize tokenizer ParseInteger by removing division + * Reserve exactly the right amount of capacity in ExtensionSet::MergeFrom + * Parse FLT_MAX correctly when represented in JSON + + Java + * Update protobuf_version.bzl to separate protoc and per-language java … (#9900) + * 6x speedup in ArrayEncoder.writeUInt32NotTag + + Python + * Increment python major version to 4 in version.json for python upb (#9926) + * The C extension module for Python has been rewritten to use the upb library. + This is expected to deliver significant performance benefits, especially when + parsing large payloads. There are some minor breaking changes, but these + should not impact most users. For more information see: + https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates + * Due to the breaking changes for Python, the major version number for Python + has been incremented. + * The binary wheel for macOS now supports Apple silicon. + + + PHP + * chore: [PHP] fix phpdoc for MapField keys (#9536) + * [PHP] Remove unnecessary zval initialization (#9600) + * [PHP] fix PHP build system (#9571) + * Fix building packaged PHP extension (#9727) + * fix: reserve "ReadOnly" keyword for PHP 8.1 and add compatibility (#9633) + * fix: phpdoc syntax for repeatedfield parameters (#9784) + * fix: phpdoc for repeatedfield (#9783) + * Change enum string name for reserved words (#9780) + * Fixed composer.json to only advertise compatibility with PHP 7.0+. (#9819) + + Ruby + * Allow pre-compiled binaries for ruby 3.1.0 (#9566) + * Implement `respond_to?` in RubyMessage (#9677) + * [Ruby] Fix RepeatedField#last, #first inconsistencies (#9722) + * Do not use range based UTF-8 validation in truffleruby (#9769) + * Improve range handling logic of `RepeatedField` (#9799) + * Disable the aarch64 build on macOS until it can be fixed. (#9816) + + Other + * [Kotlin] remove redundant public modifiers for compiled code (#9642) + * [C#] Update GetExtension to support getting typed value (#9655) + * Fix invalid dependency manifest when using `descriptor_set_out` (#9647) + * Fix C# generator handling of a field named "none" in a oneof (#9636) + * Add initial version.json file for 21-dev (#9840) + * Remove duplicate java generated code (#9909) + * Fix versioning issues in 3.20.0 + + Compiler + * Protoc outputs the list of suggested field numbers when invalid field + numbers are specified in the .proto file. + * Require package names to be less than 512 bytes in length + +2022-04-21 version 3.20.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + PHP + * Fix building packaged PHP extension (#9727) + + Other + * Fix versioning issues in 3.20.0 + +2022-03-04 version 3.20.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Dropped Ruby 2.3 and 2.4 support for CI and releases. (#9311) + * Added Ruby 3.1 support for CI and releases (#9566). + * Message.decode/encode: Add recursion_limit option (#9218/#9486) + * Allocate with xrealloc()/xfree() so message allocation is visible to the + Ruby GC. In certain tests this leads to much lower memory usage due to more + frequent GC runs (#9586). + * Fix conversion of singleton classes in Ruby (#9342) + * Suppress warning for intentional circular require (#9556) + * JSON will now output shorter strings for double and float fields when possible + without losing precision. + * Encoding and decoding of binary format will now work properly on big-endian + systems. + * UTF-8 verification was fixed to properly reject surrogate code points. + * Unknown enums for proto2 protos now properly implement proto2's behavior of + putting such values in unknown fields. + + Java + * Revert "Standardize on Array copyOf" (#9400) + * Resolve more java field accessor name conflicts (#8198) + * Don't support map fields in DynamicMessage.Builder.{getFieldBuilder,getRepeatedFieldBuilder} + * Fix parseFrom to only throw InvalidProtocolBufferException + * InvalidProtocolBufferException now allows arbitrary wrapped Exception types. + * Fix bug in `FieldSet.Builder.mergeFrom` + * Flush CodedOutputStream also flushes underlying OutputStream + * When oneof case is the same and the field type is Message, merge the + subfield. (previously it was replaced.)’ + * Add @CheckReturnValue to some protobuf types + * Report original exceptions when parsing JSON + * Add more info to @deprecated javadoc for set/get/has methods + * Fix initialization bug in doc comment line numbers + * Fix comments for message set wire format. + + Kotlin + * Add test scope to kotlin-test for protobuf-kotlin-lite (#9518) + * Add orNull extensions for optional message fields. + * Add orNull extensions to all proto3 message fields. + + Python + * Dropped support for Python < 3.7 (#9480) + * Protoc is now able to generate python stubs (.pyi) with --pyi_out + * Pin multibuild scripts to get manylinux1 wheels back (#9216) + * Fix type annotations of some Duration and Timestamp methods. + * Repeated field containers are now generic in field types and could be used + in type annotations. + * Protobuf python generated codes are simplified. Descriptors and message + classes' definitions are now dynamic created in internal/builder.py. + Insertion Points for messages classes are discarded. + * has_presence is added for FieldDescriptor in python + * Loosen indexing type requirements to allow valid __index__() implementations + rather than only PyLongObjects. + * Fix the deepcopy bug caused by not copying message_listener. + * Added python JSON parse recursion limit (default 100) + * Path info is added for python JSON parse errors + * Pure python repeated scalar fields will not able to pickle. Convert to list + first. + * Timestamp.ToDatetime() now accepts an optional tzinfo parameter. If + specified, the function returns a timezone-aware datetime in the given time + zone. If omitted or None, the function returns a timezone-naive UTC datetime + (as previously). + * Adds client_streaming and server_streaming fields to MethodDescriptor. + * Add "ensure_ascii" parameter to json_format.MessageToJson. This allows smaller + JSON serializations with UTF-8 or other non-ASCII encodings. + * Added experimental support for directly assigning numpy scalars and array. + * Improve the calculation of public_dependencies in DescriptorPool. + * [Breaking Change] Disallow setting fields to numpy singleton arrays or repeated fields to numpy + multi-dimensional arrays. Numpy arrays should be indexed or flattened explicitly before assignment. + + Compiler + * Migrate IsDefault(const std::string*) and UnsafeSetDefault(const std::string*) + * Implement strong qualified tags for TaggedPtr + * Rework allocations to power-of-two byte sizes. + * Migrate IsDefault(const std::string*) and UnsafeSetDefault(const std::string*) + * Implement strong qualified tags for TaggedPtr + * Make TaggedPtr Set...() calls explicitly spell out the content type. + * Check for parsing error before verifying UTF8. + * Enforce a maximum message nesting limit of 32 in the descriptor builder to + guard against stack overflows + * Fixed bugs in operators for RepeatedPtrIterator + * Assert a maximum map alignment for allocated values + * Fix proto1 group extension protodb parsing error + * Do not log/report the same descriptor symbol multiple times if it contains + more than one invalid character. + * Add UnknownFieldSet::SerializeToString and SerializeToCodedStream. + * Remove explicit default pointers and deprecated API from protocol compiler + + Arenas + * Change Repeated*Field to reuse memory when using arenas. + * Implements pbarenaz for profiling proto arenas + * Introduce CreateString() and CreateArenaString() for cleaner semantics + * Fix unreferenced parameter for MSVC builds + * Add UnsafeSetAllocated to be used for one-of string fields. + * Make Arena::AllocateAligned() a public function. + * Determine if ArenaDtor related code generation is necessary in one place. + * Implement on demand register ArenaDtor for InlinedStringField + + C++ + * Enable testing via CTest (#8737) + * Add option to use external GTest in CMake (#8736) + * CMake: Set correct sonames for libprotobuf-lite.so and libprotoc.so (#8635) (#9529) + * Add cmake option `protobuf_INSTALL` to not install files (#7123) + * CMake: Allow custom plugin options e.g. to generate mocks (#9105) + * CMake: Use linker version scripts (#9545) + * Manually *struct Cord fields to work better with arenas. + * Manually destruct map fields. + * Generate narrower code + * Fix https://github.com/protocolbuffers/protobuf/issues/9378 by removing + shadowed _cached_size_ field + * Remove GetPointer() and explicit nullptr defaults. + * Add proto_h flag for speeding up large builds + * Add missing overload for reference wrapped fields. + * Add MergedDescriptorDatabase::FindAllFileNames() + * RepeatedField now defines an iterator type instead of using a pointer. + * Remove obsolete macros GOOGLE_PROTOBUF_HAS_ONEOF and GOOGLE_PROTOBUF_HAS_ARENAS. + + PHP + * Fix: add missing reserved classnames (#9458) + * PHP 8.1 compatibility (#9370) + + C# + * Fix trim warnings (#9182) + * Fixes NullReferenceException when accessing FieldDescriptor.IsPacked (#9430) + * Add ToProto() method to all descriptor classes (#9426) + * Add an option to preserve proto names in JsonFormatter (#6307) + + Objective-C + * Add prefix_to_proto_package_mappings_path option. (#9498) + * Rename `proto_package_to_prefix_mappings_path` to `package_to_prefix_mappings_path`. (#9552) + * Add a generation option to control use of forward declarations in headers. (#9568) + +2022-01-28 version 3.19.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Make libprotobuf symbols local on OSX to fix issue #9395 (#9435) + + Ruby + * Fixed a data loss bug that could occur when the number of `optional` + fields in a message is an exact multiple of 32. (#9440). + + PHP + * Fixed a data loss bug that could occur when the number of `optional` + fields in a message is an exact multiple of 32. (#9440). + +2022-01-10 version 3.19.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Python + * Fix missing Windows wheel for Python 3.10 on PyPI + +2022-01-05 version 3.19.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + +2022-01-05 version 3.18.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + +2022-01-05 version 3.16.1 (Java) + + Java + * Improve performance characteristics of UnknownFieldSet parsing (#9371) + * This release addresses a Security Advisory for Java users + (https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-wrvw-hg22-4m67) + 2021-10-28 version 3.19.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) Bazel @@ -777,11 +1209,11 @@ mistakenly tagged at the wrong commit. 2020-02-14 version 3.11.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) - + C# * Fix latest ArgumentException for C# extensions (#7188) * Enforce recursion depth checking for unknown fields (#7210) - + Ruby * Fix wrappers with a zero value (#7195) * Fix JSON serialization of 0/empty-valued wrapper types (#7198) @@ -794,13 +1226,13 @@ mistakenly tagged at the wrong commit. PHP * Refactored ulong to zend_ulong for php7.4 compatibility (#7147) * Call register_class before getClass from desc to fix segfault (#7077) - + 2019-12-10 version 3.11.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) PHP * Make c extension portable for php 7.4 (#6968) - + 2019-12-02 version 3.11.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) @@ -876,7 +1308,7 @@ mistakenly tagged at the wrong commit. * Support 32 bit values for ProtoStreamObjectWriter to Struct. * Removed the internal-only header coded_stream_inl.h and the internal-only methods defined there. * Enforced no SWIG wrapping of descriptor_database.h (other headers already had this restriction). - * Implementation of the equivalent of the MOMI parser for serialization. This removes one of the two serialization routines, by making the fast array serialization routine completely general. SerializeToCodedStream can now be implemented in terms of the much much faster array serialization. The array serialization regresses slightly, but when array serialization is not possible this wins big. + * Implementation of the equivalent of the MOMI parser for serialization. This removes one of the two serialization routines, by making the fast array serialization routine completely general. SerializeToCodedStream can now be implemented in terms of the much much faster array serialization. The array serialization regresses slightly, but when array serialization is not possible this wins big. * Do not convert unknown field name to snake case to accurately report error. * Fix a UBSAN warnings. (#6333) * Add podspec for C++ (#6404) @@ -910,7 +1342,7 @@ mistakenly tagged at the wrong commit. * Change the parameter types of binaryReaderFn in ExtensionFieldBinaryInfo to (number, ?, ?). * Create dates.ts and time_of_days.ts to mirror Java versions. This is a near-identical conversion of c.g.type.util.{Dates,TimeOfDays} respectively. * Migrate moneys to TypeScript. - + PHP * Fix incorrect leap day for Timestamp (#6696) * Initialize well known type values (#6713) @@ -924,7 +1356,7 @@ mistakenly tagged at the wrong commit. * Optimization for layout_init() (#6547) * Fix for GC of Ruby map frames. (#6533) * Fixed leap year handling by reworking upb_mktime() -> upb_timegm(). (#6695) - + Objective C * Remove OSReadLittle* due to alignment requirements (#6678) * Don't use unions and instead use memcpy for the type swaps. (#6672) diff --git a/third_party/protobuf/CMakeLists.txt b/third_party/protobuf/CMakeLists.txt new file mode 100644 index 00000000..04cb3303 --- /dev/null +++ b/third_party/protobuf/CMakeLists.txt @@ -0,0 +1,351 @@ +# Minimum CMake required +cmake_minimum_required(VERSION 3.5) + +if(protobuf_VERBOSE) + message(STATUS "Protocol Buffers Configuring...") +endif() + +# CMake policies +cmake_policy(SET CMP0022 NEW) +# On MacOS use @rpath/ for target's install name prefix path +if (POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) +endif () +# Clear VERSION variables when no VERSION is given to project() +if(POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif() +# MSVC runtime library flags are selected by an abstraction. +if(POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) +endif() + +# Project +project(protobuf C CXX) + +if(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE) + if(CMAKE_PROJECT_NAME STREQUAL "protobuf") + get_filename_component(CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR} DIRECTORY) + endif() + get_filename_component(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) + get_filename_component(PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR} DIRECTORY) + get_filename_component(protobuf_SOURCE_DIR ${protobuf_SOURCE_DIR} DIRECTORY) +endif() + +# Add c++11 flags +if (CYGWIN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") +else() + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() + +# The Intel compiler isn't able to deal with noinline member functions of +# template classes defined in headers. As such it spams the output with +# warning #2196: routine is both "inline" and "noinline" +# This silences that warning. +if (CMAKE_CXX_COMPILER_ID MATCHES Intel) + string(APPEND CMAKE_CXX_FLAGS " -diag-disable=2196") +endif() + +# Options +option(protobuf_INSTALL "Install protobuf binaries and files" ON) +if(WITH_PROTOC) + set(protobuf_PROTOC_EXE ${WITH_PROTOC} CACHE FILEPATH "Protocol Buffer Compiler executable" FORCE) +endif() +option(protobuf_BUILD_TESTS "Build tests" ON) +option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF) +option(protobuf_BUILD_EXAMPLES "Build examples" OFF) +option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON) +option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF) +option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF) +if (BUILD_SHARED_LIBS) + set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON) +else (BUILD_SHARED_LIBS) + set(protobuf_BUILD_SHARED_LIBS_DEFAULT OFF) +endif (BUILD_SHARED_LIBS) +option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHARED_LIBS_DEFAULT}) +include(CMakeDependentOption) +cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON + "NOT protobuf_BUILD_SHARED_LIBS" OFF) +set(protobuf_WITH_ZLIB_DEFAULT ON) +option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT}) +set(protobuf_DEBUG_POSTFIX "d" + CACHE STRING "Default debug postfix") +mark_as_advanced(protobuf_DEBUG_POSTFIX) +# User options +include(${protobuf_SOURCE_DIR}/cmake/protobuf-options.cmake) + +# Overrides for option dependencies +if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS) + set(protobuf_BUILD_LIBPROTOC ON) +endif () +# Path to main configure script +set(protobuf_CONFIGURE_SCRIPT "${protobuf_SOURCE_DIR}/configure.ac") + +# Parse configure script +set(protobuf_AC_INIT_REGEX + "^AC_INIT\\(\\[([^]]+)\\],\\[([^]]+)\\],\\[([^]]+)\\],\\[([^]]+)\\]\\)$") +file(STRINGS "${protobuf_CONFIGURE_SCRIPT}" protobuf_AC_INIT_LINE + LIMIT_COUNT 1 REGEX "^AC_INIT") +# Description +string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\1" + protobuf_DESCRIPTION "${protobuf_AC_INIT_LINE}") +# Version +string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\2" + protobuf_VERSION_STRING "${protobuf_AC_INIT_LINE}") +# Contact +string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\3" + protobuf_CONTACT "${protobuf_AC_INIT_LINE}") +# Parse version tweaks +set(protobuf_VERSION_REGEX "^([0-9]+)\\.([0-9]+)\\.([0-9]+)([-]rc[-]|\\.)?([0-9]*)$") +string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\1" + protobuf_VERSION_MAJOR "${protobuf_VERSION_STRING}") +string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\2" + protobuf_VERSION_MINOR "${protobuf_VERSION_STRING}") +string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\3" + protobuf_VERSION_PATCH "${protobuf_VERSION_STRING}") +string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\5" + protobuf_VERSION_PRERELEASE "${protobuf_VERSION_STRING}") + +message(STATUS "${protobuf_VERSION_PRERELEASE}") + +# Package version +set(protobuf_VERSION + "${protobuf_VERSION_MAJOR}.${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}") + +if(protobuf_VERSION_PRERELEASE) + set(protobuf_VERSION "${protobuf_VERSION}.${protobuf_VERSION_PRERELEASE}") +else() + set(protobuf_VERSION "${protobuf_VERSION}.0") +endif() +message(STATUS "${protobuf_VERSION}") + +if(protobuf_VERBOSE) + message(STATUS "Configuration script parsing status [") + message(STATUS " Description : ${protobuf_DESCRIPTION}") + message(STATUS " Version : ${protobuf_VERSION} (${protobuf_VERSION_STRING})") + message(STATUS " Contact : ${protobuf_CONTACT}") + message(STATUS "]") +endif() + +add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD) + +if (protobuf_DISABLE_RTTI) + add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1) +endif() + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map +"{ + global: + main; + local: + *; +};") +# CheckLinkerFlag module available in CMake >=3.18. +if(${CMAKE_VERSION} VERSION_GREATER 3.18 OR ${CMAKE_VERSION} VERSION_EQUAL 3.18) + include(CheckLinkerFlag) + check_linker_flag(CXX -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map protobuf_HAVE_LD_VERSION_SCRIPT) +else() + include(CheckCXXSourceCompiles) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map) + check_cxx_source_compiles(" + int main() { + return 0; + } + " protobuf_HAVE_LD_VERSION_SCRIPT) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endif() +file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map) + +find_package(Threads REQUIRED) + +set(_protobuf_FIND_ZLIB) +if (protobuf_WITH_ZLIB) + find_package(ZLIB) + if (ZLIB_FOUND) + set(HAVE_ZLIB 1) + # FindZLIB module define ZLIB_INCLUDE_DIRS variable + # Set ZLIB_INCLUDE_DIRECTORIES for compatible + set(ZLIB_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRECTORIES} ${ZLIB_INCLUDE_DIRS}) + # Using imported target if exists + if (TARGET ZLIB::ZLIB) + set(ZLIB_LIBRARIES ZLIB::ZLIB) + set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()") + endif (TARGET ZLIB::ZLIB) + else (ZLIB_FOUND) + set(HAVE_ZLIB 0) + # Explicitly set these to empty (override NOT_FOUND) so cmake doesn't + # complain when we use them later. + set(ZLIB_INCLUDE_DIRECTORIES) + set(ZLIB_LIBRARIES) + endif (ZLIB_FOUND) +endif (protobuf_WITH_ZLIB) + +if (HAVE_ZLIB) + add_definitions(-DHAVE_ZLIB) +endif (HAVE_ZLIB) + +# We need to link with libatomic on systems that do not have builtin atomics, or +# don't have builtin support for 8 byte atomics +set(protobuf_LINK_LIBATOMIC false) +if (NOT MSVC) + include(CheckCXXSourceCompiles) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -std=c++11) + check_cxx_source_compiles(" + #include + int main() { + return std::atomic{}; + } + " protobuf_HAVE_BUILTIN_ATOMICS) + if (NOT protobuf_HAVE_BUILTIN_ATOMICS) + set(protobuf_LINK_LIBATOMIC true) + endif (NOT protobuf_HAVE_BUILTIN_ATOMICS) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endif (NOT MSVC) + +if (protobuf_BUILD_SHARED_LIBS) + set(protobuf_SHARED_OR_STATIC "SHARED") +else (protobuf_BUILD_SHARED_LIBS) + set(protobuf_SHARED_OR_STATIC "STATIC") + # The CMAKE__FLAGS(_)? is meant to be user controlled. + # Prior to CMake 3.15, the MSVC runtime library was pushed into the same flags + # making programmatic control difficult. Prefer the functionality in newer + # CMake versions when available. + if(${CMAKE_VERSION} VERSION_GREATER 3.15 OR ${CMAKE_VERSION} VERSION_EQUAL 3.15) + if (protobuf_MSVC_STATIC_RUNTIME) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>DLL) + endif() + else() + # In case we are building static libraries, link also the runtime library statically + # so that MSVCR*.DLL is not required at runtime. + # https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx + # This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd + # http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F + if (MSVC AND protobuf_MSVC_STATIC_RUNTIME) + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) + endif (MSVC AND protobuf_MSVC_STATIC_RUNTIME) + endif() +endif (protobuf_BUILD_SHARED_LIBS) + +if (MSVC) + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Build with multiple processes + add_definitions(/MP) + endif() + # Set source file and execution character sets to UTF-8 + add_definitions(/utf-8) + # MSVC warning suppressions + add_definitions( + /wd4065 # switch statement contains 'default' but no 'case' labels + /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data + /wd4251 # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' + /wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data + /wd4305 # 'identifier' : truncation from 'type1' to 'type2' + /wd4307 # 'operator' : integral constant overflow + /wd4309 # 'conversion' : truncation of constant value + /wd4334 # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + /wd4355 # 'this' : used in base member initializer list + /wd4506 # no definition for inline function 'function' + /wd4800 # 'type' : forcing value to bool 'true' or 'false' (performance warning) + /wd4996 # The compiler encountered a deprecated declaration. + ) + # Allow big object + add_definitions(/bigobj) + string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR}) + string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR}) + string(REPLACE "." "," protobuf_RC_FILEVERSION "${protobuf_VERSION}") + configure_file(${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in extract_includes.bat) + + # Suppress linker warnings about files with no symbols defined. + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") + + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Configure Resource Compiler + enable_language(RC) + # use English language (0x409) in resource compiler + set(rc_flags "/l0x409") + # fix rc.exe invocations because of usage of add_definitions() + set(CMAKE_RC_COMPILE_OBJECT " ${rc_flags} /fo ") + endif() + + # Generate the version.rc file used elsewhere. + configure_file(${protobuf_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) + set(protobuf_version_rc_file ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + + # Add the "lib" prefix for generated .lib outputs. + set(LIB_PREFIX lib) +else (MSVC) + # No version.rc file. + set(protobuf_version_rc_file) + + # When building with "make", "lib" prefix will be added automatically by + # the build tool. + set(LIB_PREFIX) +endif (MSVC) + +include_directories( + ${ZLIB_INCLUDE_DIRECTORIES} + ${protobuf_BINARY_DIR} + ${protobuf_SOURCE_DIR}/src) + +if (protobuf_UNICODE) + add_definitions(-DUNICODE -D_UNICODE) +endif (protobuf_UNICODE) + +include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake) +include(${protobuf_SOURCE_DIR}/cmake/libprotobuf.cmake) +if (protobuf_BUILD_LIBPROTOC) + include(${protobuf_SOURCE_DIR}/cmake/libprotoc.cmake) +endif (protobuf_BUILD_LIBPROTOC) +if (protobuf_BUILD_PROTOC_BINARIES) + include(${protobuf_SOURCE_DIR}/cmake/protoc.cmake) + if (NOT DEFINED protobuf_PROTOC_EXE) + set(protobuf_PROTOC_EXE protoc) + endif (NOT DEFINED protobuf_PROTOC_EXE) +endif (protobuf_BUILD_PROTOC_BINARIES) + +# Ensure we have a protoc executable if we need one +if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLES) + if (NOT DEFINED protobuf_PROTOC_EXE) + find_program(protobuf_PROTOC_EXE protoc) + if (NOT protobuf_PROTOC_EXE) + message(FATAL "Build requires 'protoc' but binary not found and not building protoc.") + endif () + endif () + if(protobuf_VERBOSE) + message(STATUS "Using protoc : ${protobuf_PROTOC_EXE}") + endif(protobuf_VERBOSE) +endif () + +if (protobuf_BUILD_TESTS) + enable_testing() + include(${protobuf_SOURCE_DIR}/cmake/tests.cmake) +endif (protobuf_BUILD_TESTS) + +if (protobuf_BUILD_CONFORMANCE) + include(${protobuf_SOURCE_DIR}/cmake/conformance.cmake) +endif (protobuf_BUILD_CONFORMANCE) + +if (protobuf_INSTALL) + include(${protobuf_SOURCE_DIR}/cmake/install.cmake) +endif (protobuf_INSTALL) + +if (protobuf_BUILD_EXAMPLES) + include(${protobuf_SOURCE_DIR}/cmake/examples.cmake) +endif (protobuf_BUILD_EXAMPLES) + +if(protobuf_VERBOSE) + message(STATUS "Protocol Buffers Configuring done") +endif(protobuf_VERBOSE) diff --git a/third_party/protobuf/CONTRIBUTORS.txt b/third_party/protobuf/CONTRIBUTORS.txt index b8d97fc2..c2da98f2 100644 --- a/third_party/protobuf/CONTRIBUTORS.txt +++ b/third_party/protobuf/CONTRIBUTORS.txt @@ -100,3 +100,8 @@ Patch contributors: Andrew Paprocki * Fixed minor IBM xlC compiler build issues * Added atomicops for AIX (POWER) + Nipunn Koorapati + * Provide a type alias field ValueType on EnumTypeWrapper + * Match service argument names to abstract interface + + diff --git a/third_party/protobuf/Makefile.am b/third_party/protobuf/Makefile.am index 178c124b..681cd8c2 100644 --- a/third_party/protobuf/Makefile.am +++ b/third_party/protobuf/Makefile.am @@ -9,6 +9,9 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = . src # Always include third_party directories in distributions. +# +# Note that distribution artifacts will be produced by Bazel in the future. +# See pkg/BUILD.bazel for overall definitions. DIST_SUBDIRS = src conformance benchmarks third_party/googletest # Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS @@ -48,12 +51,15 @@ clean-local: pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = protobuf.pc protobuf-lite.pc +# Note: please keep this in sync with the dist_files rule in csharp/BUILD.bazel. csharp_EXTRA_DIST= \ global.json \ + csharp/.editorconfig \ csharp/.gitignore \ csharp/CHANGES.txt \ csharp/Google.Protobuf.Tools.targets \ csharp/Google.Protobuf.Tools.nuspec \ + csharp/NuGet.Config \ csharp/README.md \ csharp/build_packages.bat \ csharp/build_tools.sh \ @@ -181,10 +187,14 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/Collections/ProtobufEqualityComparers.cs \ csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \ csharp/src/Google.Protobuf/Collections/RepeatedField.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs \ csharp/src/Google.Protobuf/Compatibility/MethodInfoExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs \ csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs \ csharp/src/Google.Protobuf/Extension.cs \ csharp/src/Google.Protobuf/ExtensionRegistry.cs \ csharp/src/Google.Protobuf/ExtensionSet.cs \ @@ -273,10 +283,11 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/UnknownFieldSet.cs \ csharp/src/Google.Protobuf/UnsafeByteOperations.cs +# Note: please keep this in sync with the dist_files rules under java/.../BUILD.bazel. java_EXTRA_DIST= \ java/README.md \ java/bom/pom.xml \ - java/core/BUILD \ + java/core/BUILD.bazel \ java/core/generate-sources-build.xml \ java/core/generate-test-sources-build.xml \ java/core/pom.xml \ @@ -303,6 +314,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java \ + java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java \ java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/Descriptors.java \ java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \ @@ -326,6 +338,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java \ + java/core/src/main/java/com/google/protobuf/InlineMe.java \ java/core/src/main/java/com/google/protobuf/IntArrayList.java \ java/core/src/main/java/com/google/protobuf/Internal.java \ java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \ @@ -437,9 +450,9 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java \ java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \ java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \ - java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \ java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java \ java/core/src/test/java/com/google/protobuf/IntArrayListTest.java \ + java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \ java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java \ @@ -464,15 +477,12 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java \ java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java \ java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \ java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java \ @@ -493,9 +503,9 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java \ java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \ java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \ + java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java \ java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ java/core/src/test/java/com/google/protobuf/Utf8Test.java \ - java/core/src/test/java/com/google/protobuf/Utf8Utils.java \ java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatTest.java \ @@ -504,6 +514,7 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/any_test.proto \ java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto \ java/core/src/test/proto/com/google/protobuf/deprecated_file.proto \ + java/core/src/test/proto/com/google/protobuf/dynamic_message_test.proto \ java/core/src/test/proto/com/google/protobuf/field_presence_test.proto \ java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto \ java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto \ @@ -512,7 +523,6 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto \ java/core/src/test/proto/com/google/protobuf/map_lite_test.proto \ java/core/src/test/proto/com/google/protobuf/map_test.proto \ - java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto\ java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_extension.proto \ @@ -533,21 +543,24 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \ java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \ java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \ - java/internal/BUILD \ + java/internal/BUILD.bazel \ java/internal/testing.bzl \ + java/kotlin/BUILD.bazel \ java/kotlin/generate-sources-build.xml \ java/kotlin/generate-test-sources-build.xml \ java/kotlin/pom.xml \ + java/kotlin/pom_template.xml \ + java/kotlin/src/main/kotlin/com/google/protobuf/Anies.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt \ - java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt \ + java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt \ @@ -559,15 +572,18 @@ java_EXTRA_DIST= java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto \ java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto \ java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto \ + java/kotlin-lite/BUILD.bazel \ java/kotlin-lite/generate-sources-build.xml \ java/kotlin-lite/generate-test-sources-build.xml \ java/kotlin-lite/lite.awk \ java/kotlin-lite/pom.xml \ + java/kotlin-lite/pom_template.xml \ java/kotlin-lite/process-lite-sources-build.xml \ + java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt \ java/lite.md \ - java/lite/BUILD \ + java/lite/BUILD.bazel \ java/lite/generate-sources-build.xml \ java/lite/generate-test-sources-build.xml \ java/lite/lite.awk \ @@ -575,10 +591,9 @@ java_EXTRA_DIST= java/lite/pom_template.xml \ java/lite/process-lite-sources-build.xml \ java/lite/src/test/java/com/google/protobuf/LiteTest.java \ - java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java \ - java/BUILD \ + java/BUILD.bazel \ java/pom.xml \ - java/util/BUILD \ + java/util/BUILD.bazel \ java/util/pom.xml \ java/util/pom_template.xml \ java/util/src/main/java/com/google/protobuf/util/Durations.java \ @@ -588,16 +603,19 @@ java_EXTRA_DIST= java/util/src/main/java/com/google/protobuf/util/Structs.java \ java/util/src/main/java/com/google/protobuf/util/Timestamps.java \ java/util/src/main/java/com/google/protobuf/util/Values.java \ + java/util/src/test/java/com/google/protobuf/util/DurationsTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \ java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ + java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/proto/com/google/protobuf/util/json_test.proto +# Note: please keep this in sync with the dist_files rule in objectivec/BUILD.bazel. objectivec_EXTRA_DIST= \ objectivec/.clang-format \ - objectivec/BUILD \ + objectivec/BUILD.bazel \ objectivec/DevTools/check_version_stamps.sh \ objectivec/DevTools/compile_testing_protos.sh \ objectivec/DevTools/full_mac_build.sh \ @@ -696,33 +714,6 @@ objectivec_EXTRA_DIST= \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \ objectivec/README.md \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static \ - objectivec/Tests/CocoaPods/README.md \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m \ - objectivec/Tests/CocoaPods/run_tests.sh \ objectivec/Tests/golden_message \ objectivec/Tests/golden_packed_fields_message \ objectivec/Tests/GPBARCUnittestProtos.m \ @@ -803,11 +794,12 @@ objectivec_EXTRA_DIST= \ objectivec/Tests/UnitTests-Info.plist \ Protobuf.podspec +# Note: please keep this in sync with the dist_files rule in php/BUILD.bazel. php_EXTRA_DIST= \ - composer.json \ php/README.md \ php/REFCOUNTING.md \ php/composer.json \ + php/composer.json.dist \ php/ext/google/protobuf/arena.c \ php/ext/google/protobuf/arena.h \ php/ext/google/protobuf/array.c \ @@ -817,18 +809,21 @@ php_EXTRA_DIST= \ php/ext/google/protobuf/convert.h \ php/ext/google/protobuf/def.c \ php/ext/google/protobuf/def.h \ + php/ext/google/protobuf/generate_package_xml.sh \ php/ext/google/protobuf/map.c \ php/ext/google/protobuf/map.h \ php/ext/google/protobuf/message.c \ php/ext/google/protobuf/message.h \ php/ext/google/protobuf/names.c \ php/ext/google/protobuf/names.h \ - php/ext/google/protobuf/package.xml \ php/ext/google/protobuf/php-upb.c \ php/ext/google/protobuf/php-upb.h \ + php/ext/google/protobuf/php_protobuf.h \ php/ext/google/protobuf/protobuf.c \ php/ext/google/protobuf/protobuf.h \ + php/ext/google/protobuf/template_package.xml \ php/ext/google/protobuf/wkt.inc \ + php/ext/google/protobuf/tests/unnecessary_zval.phpt \ php/generate_descriptor_protos.sh \ php/generate_test_protos.sh \ php/release.sh \ @@ -964,6 +959,8 @@ php_EXTRA_DIST= \ php/tests/EncodeDecodeTest.php \ php/tests/force_c_ext.php \ php/tests/gdb_test.sh \ + php/tests/generated_previous/GPBMetadata/ProtoPrevious/TestPreviouslyUnreservedMessage.php \ + php/tests/generated_previous/Previous/readonly.php \ php/tests/GeneratedClassTest.php \ php/tests/GeneratedPhpdocTest.php \ php/tests/GeneratedServiceTest.php \ @@ -973,6 +970,7 @@ php_EXTRA_DIST= \ php/tests/multirequest.php \ php/tests/multirequest.sh \ php/tests/PhpImplementationTest.php \ + php/tests/PreviouslyGeneratedClassTest.php \ php/tests/proto/empty/echo.proto \ php/tests/proto/test.proto \ php/tests/proto/test_descriptors.proto \ @@ -991,12 +989,14 @@ php_EXTRA_DIST= \ php/tests/proto/test_service.proto \ php/tests/proto/test_service_namespace.proto \ php/tests/proto/test_wrapper_type_setters.proto \ + php/tests/proto_previous/test_previously_unreserved_message.proto \ php/tests/test_base.php \ php/tests/test_util.php \ php/tests/valgrind.supp \ php/tests/WellKnownTest.php \ php/tests/WrapperTypeSettersTest.php +# Note: please keep this in sync with the python_dist_files rule in BUILD.bazel. python_EXTRA_DIST= \ python/MANIFEST.in \ python/google/__init__.py \ @@ -1011,6 +1011,7 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/any_test.proto \ python/google/protobuf/internal/api_implementation.cc \ python/google/protobuf/internal/api_implementation.py \ + python/google/protobuf/internal/builder.py \ python/google/protobuf/internal/containers.py \ python/google/protobuf/internal/decoder.py \ python/google/protobuf/internal/descriptor_database_test.py \ @@ -1025,7 +1026,10 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/factory_test2.proto \ python/google/protobuf/internal/file_options_test.proto \ python/google/protobuf/internal/generator_test.py \ + python/google/protobuf/internal/import_test.py \ python/google/protobuf/internal/import_test_package/__init__.py \ + python/google/protobuf/internal/import_test_package/import_public.proto \ + python/google/protobuf/internal/import_test_package/import_public_nested.proto \ python/google/protobuf/internal/import_test_package/inner.proto \ python/google/protobuf/internal/import_test_package/outer.proto \ python/google/protobuf/internal/json_format_test.py \ @@ -1097,6 +1101,8 @@ python_EXTRA_DIST= \ python/google/protobuf/pyext/repeated_scalar_container.h \ python/google/protobuf/pyext/safe_numerics.h \ python/google/protobuf/pyext/scoped_pyobject_ptr.h \ + python/google/protobuf/pyext/unknown_field_set.cc \ + python/google/protobuf/pyext/unknown_field_set.h \ python/google/protobuf/python_protobuf.h \ python/google/protobuf/reflection.py \ python/google/protobuf/service.py \ @@ -1104,6 +1110,7 @@ python_EXTRA_DIST= \ python/google/protobuf/symbol_database.py \ python/google/protobuf/text_encoding.py \ python/google/protobuf/text_format.py \ + python/google/protobuf/unknown_fields.py \ python/google/protobuf/util/__init__.py \ python/release.sh \ python/mox.py \ @@ -1113,6 +1120,7 @@ python_EXTRA_DIST= \ python/tox.ini \ python/README.md +# Note: please keep this in sync with the dist_files rule in ruby/BUILD.bazel. ruby_EXTRA_DIST= \ ruby/Gemfile \ ruby/.gitignore \ @@ -1188,250 +1196,79 @@ ruby_EXTRA_DIST= \ ruby/tests/type_errors.rb \ ruby/travis-test.sh -js_EXTRA_DIST= \ - js/README.md \ - js/binary/arith.js \ - js/binary/arith_test.js \ - js/binary/constants.js \ - js/binary/decoder.js \ - js/binary/decoder_test.js \ - js/binary/encoder.js \ - js/binary/message_test.js \ - js/binary/proto_test.js \ - js/binary/reader.js \ - js/binary/reader_test.js \ - js/binary/utils.js \ - js/binary/utils_test.js \ - js/binary/writer.js \ - js/binary/writer_test.js \ - js/commonjs/export.js \ - js/commonjs/export_asserts.js \ - js/commonjs/export_testdeps.js \ - js/commonjs/import_test.js \ - js/commonjs/jasmine.json \ - js/commonjs/rewrite_tests_for_commonjs.js \ - js/commonjs/strict_test.js \ - js/commonjs/test6/test6.proto \ - js/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/binary/arith_test.js \ - js/compatibility_tests/v3.0.0/binary/decoder_test.js \ - js/compatibility_tests/v3.0.0/binary/proto_test.js \ - js/compatibility_tests/v3.0.0/binary/reader_test.js \ - js/compatibility_tests/v3.0.0/binary/utils_test.js \ - js/compatibility_tests/v3.0.0/binary/writer_test.js \ - js/compatibility_tests/v3.0.0/commonjs/export_asserts.js \ - js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js \ - js/compatibility_tests/v3.0.0/commonjs/import_test.js \ - js/compatibility_tests/v3.0.0/commonjs/jasmine.json \ - js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js \ - js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/data.proto \ - js/compatibility_tests/v3.0.0/debug_test.js \ - js/compatibility_tests/v3.0.0/jasmine1.json \ - js/compatibility_tests/v3.0.0/jasmine2.json \ - js/compatibility_tests/v3.0.0/jasmine3.json \ - js/compatibility_tests/v3.0.0/message_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.proto \ - js/compatibility_tests/v3.0.0/test2.proto \ - js/compatibility_tests/v3.0.0/test3.proto \ - js/compatibility_tests/v3.0.0/test4.proto \ - js/compatibility_tests/v3.0.0/test5.proto \ - js/compatibility_tests/v3.0.0/testbinary.proto \ - js/compatibility_tests/v3.0.0/testempty.proto \ - js/compatibility_tests/v3.0.0/test.proto \ - js/compatibility_tests/v3.0.0/test.sh \ - js/compatibility_tests/v3.1.0/testempty.proto \ - js/compatibility_tests/v3.1.0/testbinary.proto \ - js/compatibility_tests/v3.1.0/test5.proto \ - js/compatibility_tests/v3.1.0/test4.proto \ - js/compatibility_tests/v3.1.0/test3.proto \ - js/compatibility_tests/v3.1.0/test2.proto \ - js/compatibility_tests/v3.1.0/test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.js \ - js/compatibility_tests/v3.1.0/message_test.js \ - js/compatibility_tests/v3.1.0/maps_test.js \ - js/compatibility_tests/v3.1.0/debug_test.js \ - js/compatibility_tests/v3.1.0/data.proto \ - js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.1.0/binary/writer_test.js \ - js/compatibility_tests/v3.1.0/binary/utils_test.js \ - js/compatibility_tests/v3.1.0/binary/reader_test.js \ - js/compatibility_tests/v3.1.0/binary/proto_test.js \ - js/compatibility_tests/v3.1.0/binary/decoder_test.js \ - js/compatibility_tests/v3.1.0/binary/arith_test.js \ - js/data.proto \ - js/debug.js \ - js/debug_test.js \ - js/experimental/runtime/kernel/message_set.js \ - js/experimental/runtime/kernel/message_set_test.js \ - js/experimental/runtime/kernel/tag.js \ - js/experimental/runtime/kernel/tag_test.js \ - js/gulpfile.js \ - js/jasmine.json \ - js/map.js \ - js/maps_test.js \ - js/message.js \ - js/message_test.js \ - js/node_loader.js \ - js/package.json \ - js/proto3_test.js \ - js/proto3_test.proto \ - js/test.proto \ - js/test2.proto \ - js/test3.proto \ - js/test4.proto \ - js/test5.proto \ - js/test8.proto \ - js/test9.proto \ - js/test10.proto \ - js/test11.proto \ - js/test12.proto \ - js/test13.proto \ - js/test14.proto \ - js/test15.proto \ - js/test_bootstrap.js \ - js/testbinary.proto \ - js/testempty.proto \ - js/testlargenumbers.proto \ - js/experimental/runtime/testing/jasmine_protobuf.js \ - js/experimental/runtime/testing/ensure_custom_equality_test.js \ - js/experimental/runtime/testing/binary/test_message.js \ - js/experimental/runtime/kernel/writer_test.js \ - js/experimental/runtime/kernel/writer.js \ - js/experimental/runtime/kernel/wire_type.js \ - js/experimental/runtime/kernel/uint8arrays_test.js \ - js/experimental/runtime/kernel/uint8arrays.js \ - js/experimental/runtime/kernel/uint32_test_pairs.js \ - js/experimental/runtime/kernel/typed_arrays_test.js \ - js/experimental/runtime/kernel/typed_arrays.js \ - js/experimental/runtime/kernel/textencoding_test.js \ - js/experimental/runtime/kernel/textencoding.js \ - js/experimental/runtime/kernel/storage.js \ - js/experimental/runtime/kernel/sint64_test_pairs.js \ - js/experimental/runtime/kernel/sint32_test_pairs.js \ - js/experimental/runtime/kernel/sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/reader_test.js \ - js/experimental/runtime/kernel/reader.js \ - js/experimental/runtime/kernel/packed_uint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_int64_test_pairs.js \ - js/experimental/runtime/kernel/packed_int32_test_pairs.js \ - js/experimental/runtime/kernel/packed_float_test_pairs.js \ - js/experimental/runtime/kernel/packed_fixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_double_test_pairs.js \ - js/experimental/runtime/kernel/packed_bool_test_pairs.js \ - js/experimental/runtime/kernel/kernel_test.js \ - js/experimental/runtime/kernel/kernel_repeated_test.js \ - js/experimental/runtime/kernel/kernel_compatibility_test.js \ - js/experimental/runtime/kernel/kernel.js \ - js/experimental/runtime/kernel/internal_message.js \ - js/experimental/runtime/kernel/int64_test_pairs.js \ - js/experimental/runtime/kernel/int32_test_pairs.js \ - js/experimental/runtime/kernel/indexer_test.js \ - js/experimental/runtime/kernel/indexer.js \ - js/experimental/runtime/kernel/float_test_pairs.js \ - js/experimental/runtime/kernel/fixed32_test_pairs.js \ - js/experimental/runtime/kernel/field.js \ - js/experimental/runtime/kernel/double_test_pairs.js \ - js/experimental/runtime/kernel/conformance/wire_format.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto3.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto2.js \ - js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js \ - js/experimental/runtime/kernel/conformance/conformance_testee.js \ - js/experimental/runtime/kernel/conformance/conformance_response.js \ - js/experimental/runtime/kernel/conformance/conformance_request.js \ - js/experimental/runtime/kernel/buffer_decoder_test.js \ - js/experimental/runtime/kernel/buffer_decoder_helper.js \ - js/experimental/runtime/kernel/buffer_decoder.js \ - js/experimental/runtime/kernel/bool_test_pairs.js \ - js/experimental/runtime/kernel/binary_storage_test.js \ - js/experimental/runtime/kernel/binary_storage.js \ - js/experimental/runtime/internal/checks_test.js \ - js/experimental/runtime/internal/checks.js \ - js/experimental/runtime/int64_test.js \ - js/experimental/runtime/int64.js \ - js/experimental/runtime/bytestring_test.js \ - js/experimental/runtime/bytestring_internal.js \ - js/experimental/runtime/bytestring.js \ - js/experimental/benchmarks/code_size/kernel/popular_types.js \ - js/experimental/benchmarks/code_size/kernel/all_types.js \ - js/experimental/benchmarks/code_size/code_size_base.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js - -all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) - -EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ - autogen.sh \ - generate_descriptor_proto.sh \ - README.md \ - LICENSE \ - CONTRIBUTORS.txt \ - CHANGES.txt \ - update_file_lists.sh \ - BUILD \ - WORKSPACE \ - cmake/CMakeLists.txt \ - cmake/README.md \ - cmake/conformance.cmake \ - cmake/examples.cmake \ - cmake/extract_includes.bat.in \ - cmake/install.cmake \ - cmake/libprotobuf.cmake \ - cmake/libprotobuf-lite.cmake \ - cmake/libprotoc.cmake \ - cmake/protobuf-config-version.cmake.in \ - cmake/protobuf-config.cmake.in \ - cmake/protobuf-lite.pc.cmake \ - cmake/protobuf-module.cmake.in \ - cmake/protobuf-options.cmake \ - cmake/protobuf.pc.cmake \ - cmake/protoc.cmake \ - cmake/tests.cmake \ - cmake/version.rc.in \ - compiler_config_setting.bzl \ - build_files_updated_unittest.sh \ - cc_proto_blacklist_test.bzl \ - editors/README.txt \ - editors/proto.vim \ - editors/protobuf-mode.el \ - examples/AddPerson.java \ - examples/BUILD \ - examples/CMakeLists.txt \ - examples/ListPeople.java \ - examples/Makefile \ - examples/README.md \ - examples/WORKSPACE \ - examples/add_person.cc \ - examples/add_person.dart \ - examples/add_person.go \ - examples/add_person.py \ - examples/add_person_test.go \ - examples/addressbook.proto \ - examples/list_people.cc \ - examples/list_people.dart \ - examples/list_people.go \ - examples/list_people.py \ - examples/list_people_test.go \ - examples/pubspec.yaml \ - maven_install.json \ - protobuf.bzl \ - protobuf_deps.bzl \ - protobuf_version.bzl \ - third_party/zlib.BUILD \ - util/python/BUILD \ - internal.bzl +all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) +# Note: please keep this in sync with the common_dist_files rule in BUILD.bazel. +EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ + autogen.sh \ + generate_descriptor_proto.sh \ + README.md \ + LICENSE \ + CONTRIBUTORS.txt \ + CHANGES.txt \ + update_file_lists.sh \ + BUILD.bazel \ + WORKSPACE \ + CMakeLists.txt \ + build_defs/BUILD.bazel \ + build_defs/cc_proto_blacklist_test.bzl \ + build_defs/compiler_config_setting.bzl \ + build_defs/cpp_opts.bzl \ + build_files_updated_unittest.sh \ + cmake/CMakeLists.txt \ + cmake/README.md \ + cmake/conformance.cmake \ + cmake/examples.cmake \ + cmake/extract_includes.bat.in \ + cmake/install.cmake \ + cmake/libprotobuf-lite.cmake \ + cmake/libprotobuf.cmake \ + cmake/libprotoc.cmake \ + cmake/protobuf-config-version.cmake.in \ + cmake/protobuf-config.cmake.in \ + cmake/protobuf-lite.pc.cmake \ + cmake/protobuf-module.cmake.in \ + cmake/protobuf-options.cmake \ + cmake/protobuf.pc.cmake \ + cmake/protoc.cmake \ + cmake/tests.cmake \ + cmake/version.rc.in \ + csharp/BUILD.bazel \ + editors/README.txt \ + editors/proto.vim \ + editors/protobuf-mode.el \ + examples/AddPerson.java \ + examples/BUILD.bazel \ + examples/CMakeLists.txt \ + examples/ListPeople.java \ + examples/Makefile \ + examples/README.md \ + examples/WORKSPACE \ + examples/add_person.cc \ + examples/add_person.dart \ + examples/add_person.py \ + examples/addressbook.proto \ + examples/go/cmd/add_person/add_person.go \ + examples/go/cmd/add_person/add_person_test.go \ + examples/go/cmd/list_people/list_people.go \ + examples/go/cmd/list_people/list_people_test.go \ + examples/go/go.sum \ + examples/go/go.mod \ + examples/list_people.cc \ + examples/list_people.dart \ + examples/list_people.py \ + examples/pubspec.yaml \ + conformance/BUILD.bazel \ + conformance/defs.bzl \ + maven_install.json \ + php/BUILD.bazel \ + protobuf.bzl \ + protobuf_deps.bzl \ + protobuf_release.bzl \ + protobuf_version.bzl \ + ruby/BUILD.bazel \ + third_party/zlib.BUILD \ + util/python/BUILD.bazel # Deletes all the files generated by autogen.sh. MAINTAINERCLEANFILES = \ diff --git a/third_party/protobuf/Makefile.in b/third_party/protobuf/Makefile.in index 22c56754..2dc5d2f6 100644 --- a/third_party/protobuf/Makefile.in +++ b/third_party/protobuf/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.16.4 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -283,6 +283,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INSTALL = @INSTALL@ @@ -407,15 +408,22 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = . src # Always include third_party directories in distributions. +# +# Note that distribution artifacts will be produced by Bazel in the future. +# See pkg/BUILD.bazel for overall definitions. DIST_SUBDIRS = src conformance benchmarks third_party/googletest pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = protobuf.pc protobuf-lite.pc + +# Note: please keep this in sync with the dist_files rule in csharp/BUILD.bazel. csharp_EXTRA_DIST = \ global.json \ + csharp/.editorconfig \ csharp/.gitignore \ csharp/CHANGES.txt \ csharp/Google.Protobuf.Tools.targets \ csharp/Google.Protobuf.Tools.nuspec \ + csharp/NuGet.Config \ csharp/README.md \ csharp/build_packages.bat \ csharp/build_tools.sh \ @@ -543,10 +551,14 @@ csharp_EXTRA_DIST = \ csharp/src/Google.Protobuf/Collections/ProtobufEqualityComparers.cs \ csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs \ csharp/src/Google.Protobuf/Collections/RepeatedField.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMembersAttribute.cs \ + csharp/src/Google.Protobuf/Compatibility/DynamicallyAccessedMemberTypes.cs \ csharp/src/Google.Protobuf/Compatibility/MethodInfoExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/RequiresUnreferencedCodeAttribute.cs \ csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \ + csharp/src/Google.Protobuf/Compatibility/UnconditionalSuppressMessageAttribute.cs \ csharp/src/Google.Protobuf/Extension.cs \ csharp/src/Google.Protobuf/ExtensionRegistry.cs \ csharp/src/Google.Protobuf/ExtensionSet.cs \ @@ -635,10 +647,12 @@ csharp_EXTRA_DIST = \ csharp/src/Google.Protobuf/UnknownFieldSet.cs \ csharp/src/Google.Protobuf/UnsafeByteOperations.cs + +# Note: please keep this in sync with the dist_files rules under java/.../BUILD.bazel. java_EXTRA_DIST = \ java/README.md \ java/bom/pom.xml \ - java/core/BUILD \ + java/core/BUILD.bazel \ java/core/generate-sources-build.xml \ java/core/generate-test-sources-build.xml \ java/core/pom.xml \ @@ -665,6 +679,7 @@ java_EXTRA_DIST = \ java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java \ + java/core/src/main/java/com/google/protobuf/CompileTimeConstant.java \ java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/Descriptors.java \ java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \ @@ -688,6 +703,7 @@ java_EXTRA_DIST = \ java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \ java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java \ + java/core/src/main/java/com/google/protobuf/InlineMe.java \ java/core/src/main/java/com/google/protobuf/IntArrayList.java \ java/core/src/main/java/com/google/protobuf/Internal.java \ java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \ @@ -799,9 +815,9 @@ java_EXTRA_DIST = \ java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java \ java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \ java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \ - java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \ java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java \ java/core/src/test/java/com/google/protobuf/IntArrayListTest.java \ + java/core/src/test/java/com/google/protobuf/InvalidProtocolBufferExceptionTest.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \ java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java \ @@ -826,15 +842,12 @@ java_EXTRA_DIST = \ java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java \ java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java \ java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java \ - java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java \ java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java \ java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \ java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java \ @@ -855,9 +868,9 @@ java_EXTRA_DIST = \ java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java \ java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \ java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \ + java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java \ java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ java/core/src/test/java/com/google/protobuf/Utf8Test.java \ - java/core/src/test/java/com/google/protobuf/Utf8Utils.java \ java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java \ java/core/src/test/java/com/google/protobuf/WireFormatTest.java \ @@ -866,6 +879,7 @@ java_EXTRA_DIST = \ java/core/src/test/proto/com/google/protobuf/any_test.proto \ java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto \ java/core/src/test/proto/com/google/protobuf/deprecated_file.proto \ + java/core/src/test/proto/com/google/protobuf/dynamic_message_test.proto \ java/core/src/test/proto/com/google/protobuf/field_presence_test.proto \ java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto \ java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto \ @@ -874,7 +888,6 @@ java_EXTRA_DIST = \ java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto \ java/core/src/test/proto/com/google/protobuf/map_lite_test.proto \ java/core/src/test/proto/com/google/protobuf/map_test.proto \ - java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto\ java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto \ java/core/src/test/proto/com/google/protobuf/nested_extension.proto \ @@ -895,21 +908,24 @@ java_EXTRA_DIST = \ java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \ java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \ java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \ - java/internal/BUILD \ + java/internal/BUILD.bazel \ java/internal/testing.bzl \ + java/kotlin/BUILD.bazel \ java/kotlin/generate-sources-build.xml \ java/kotlin/generate-test-sources-build.xml \ java/kotlin/pom.xml \ + java/kotlin/pom_template.xml \ + java/kotlin/src/main/kotlin/com/google/protobuf/Anies.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ByteStrings.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslMap.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/DslProxy.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageExtensions.kt \ - java/kotlin/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/OnlyForUseByGeneratedProtoCode.kt\ java/kotlin/src/main/kotlin/com/google/protobuf/ProtoDslMarker.kt \ java/kotlin/src/main/kotlin/com/google/protobuf/UnmodifiableCollections.kt \ + java/kotlin/src/test/kotlin/com/google/protobuf/AniesTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/ByteStringsTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt \ java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt \ @@ -921,15 +937,18 @@ java_EXTRA_DIST = \ java/kotlin/src/test/proto/com/google/protobuf/evil_names_proto3.proto \ java/kotlin/src/test/proto/com/google/protobuf/example_extensible_message.proto \ java/kotlin/src/test/proto/com/google/protobuf/multiple_files_proto3.proto \ + java/kotlin-lite/BUILD.bazel \ java/kotlin-lite/generate-sources-build.xml \ java/kotlin-lite/generate-test-sources-build.xml \ java/kotlin-lite/lite.awk \ java/kotlin-lite/pom.xml \ + java/kotlin-lite/pom_template.xml \ java/kotlin-lite/process-lite-sources-build.xml \ + java/kotlin-lite/src/main/kotlin/com/google/protobuf/ExtendableMessageLiteExtensions.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/ExtendableMessageLiteExtensionsTest.kt\ java/kotlin-lite/src/test/kotlin/com/google/protobuf/Proto2LiteTest.kt \ java/lite.md \ - java/lite/BUILD \ + java/lite/BUILD.bazel \ java/lite/generate-sources-build.xml \ java/lite/generate-test-sources-build.xml \ java/lite/lite.awk \ @@ -937,10 +956,9 @@ java_EXTRA_DIST = \ java/lite/pom_template.xml \ java/lite/process-lite-sources-build.xml \ java/lite/src/test/java/com/google/protobuf/LiteTest.java \ - java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java \ - java/BUILD \ + java/BUILD.bazel \ java/pom.xml \ - java/util/BUILD \ + java/util/BUILD.bazel \ java/util/pom.xml \ java/util/pom_template.xml \ java/util/src/main/java/com/google/protobuf/util/Durations.java \ @@ -950,16 +968,20 @@ java_EXTRA_DIST = \ java/util/src/main/java/com/google/protobuf/util/Structs.java \ java/util/src/main/java/com/google/protobuf/util/Timestamps.java \ java/util/src/main/java/com/google/protobuf/util/Values.java \ + java/util/src/test/java/com/google/protobuf/util/DurationsTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \ java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ + java/util/src/test/java/com/google/protobuf/util/TimestampsTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/proto/com/google/protobuf/util/json_test.proto + +# Note: please keep this in sync with the dist_files rule in objectivec/BUILD.bazel. objectivec_EXTRA_DIST = \ objectivec/.clang-format \ - objectivec/BUILD \ + objectivec/BUILD.bazel \ objectivec/DevTools/check_version_stamps.sh \ objectivec/DevTools/compile_testing_protos.sh \ objectivec/DevTools/full_mac_build.sh \ @@ -1058,33 +1080,6 @@ objectivec_EXTRA_DIST = \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \ objectivec/ProtocolBuffers_tvOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \ objectivec/README.md \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework \ - objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static \ - objectivec/Tests/CocoaPods/README.md \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m \ - objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m \ - objectivec/Tests/CocoaPods/run_tests.sh \ objectivec/Tests/golden_message \ objectivec/Tests/golden_packed_fields_message \ objectivec/Tests/GPBARCUnittestProtos.m \ @@ -1165,11 +1160,13 @@ objectivec_EXTRA_DIST = \ objectivec/Tests/UnitTests-Info.plist \ Protobuf.podspec + +# Note: please keep this in sync with the dist_files rule in php/BUILD.bazel. php_EXTRA_DIST = \ - composer.json \ php/README.md \ php/REFCOUNTING.md \ php/composer.json \ + php/composer.json.dist \ php/ext/google/protobuf/arena.c \ php/ext/google/protobuf/arena.h \ php/ext/google/protobuf/array.c \ @@ -1179,18 +1176,21 @@ php_EXTRA_DIST = \ php/ext/google/protobuf/convert.h \ php/ext/google/protobuf/def.c \ php/ext/google/protobuf/def.h \ + php/ext/google/protobuf/generate_package_xml.sh \ php/ext/google/protobuf/map.c \ php/ext/google/protobuf/map.h \ php/ext/google/protobuf/message.c \ php/ext/google/protobuf/message.h \ php/ext/google/protobuf/names.c \ php/ext/google/protobuf/names.h \ - php/ext/google/protobuf/package.xml \ php/ext/google/protobuf/php-upb.c \ php/ext/google/protobuf/php-upb.h \ + php/ext/google/protobuf/php_protobuf.h \ php/ext/google/protobuf/protobuf.c \ php/ext/google/protobuf/protobuf.h \ + php/ext/google/protobuf/template_package.xml \ php/ext/google/protobuf/wkt.inc \ + php/ext/google/protobuf/tests/unnecessary_zval.phpt \ php/generate_descriptor_protos.sh \ php/generate_test_protos.sh \ php/release.sh \ @@ -1326,6 +1326,8 @@ php_EXTRA_DIST = \ php/tests/EncodeDecodeTest.php \ php/tests/force_c_ext.php \ php/tests/gdb_test.sh \ + php/tests/generated_previous/GPBMetadata/ProtoPrevious/TestPreviouslyUnreservedMessage.php \ + php/tests/generated_previous/Previous/readonly.php \ php/tests/GeneratedClassTest.php \ php/tests/GeneratedPhpdocTest.php \ php/tests/GeneratedServiceTest.php \ @@ -1335,6 +1337,7 @@ php_EXTRA_DIST = \ php/tests/multirequest.php \ php/tests/multirequest.sh \ php/tests/PhpImplementationTest.php \ + php/tests/PreviouslyGeneratedClassTest.php \ php/tests/proto/empty/echo.proto \ php/tests/proto/test.proto \ php/tests/proto/test_descriptors.proto \ @@ -1353,12 +1356,15 @@ php_EXTRA_DIST = \ php/tests/proto/test_service.proto \ php/tests/proto/test_service_namespace.proto \ php/tests/proto/test_wrapper_type_setters.proto \ + php/tests/proto_previous/test_previously_unreserved_message.proto \ php/tests/test_base.php \ php/tests/test_util.php \ php/tests/valgrind.supp \ php/tests/WellKnownTest.php \ php/tests/WrapperTypeSettersTest.php + +# Note: please keep this in sync with the python_dist_files rule in BUILD.bazel. python_EXTRA_DIST = \ python/MANIFEST.in \ python/google/__init__.py \ @@ -1373,6 +1379,7 @@ python_EXTRA_DIST = \ python/google/protobuf/internal/any_test.proto \ python/google/protobuf/internal/api_implementation.cc \ python/google/protobuf/internal/api_implementation.py \ + python/google/protobuf/internal/builder.py \ python/google/protobuf/internal/containers.py \ python/google/protobuf/internal/decoder.py \ python/google/protobuf/internal/descriptor_database_test.py \ @@ -1387,7 +1394,10 @@ python_EXTRA_DIST = \ python/google/protobuf/internal/factory_test2.proto \ python/google/protobuf/internal/file_options_test.proto \ python/google/protobuf/internal/generator_test.py \ + python/google/protobuf/internal/import_test.py \ python/google/protobuf/internal/import_test_package/__init__.py \ + python/google/protobuf/internal/import_test_package/import_public.proto \ + python/google/protobuf/internal/import_test_package/import_public_nested.proto \ python/google/protobuf/internal/import_test_package/inner.proto \ python/google/protobuf/internal/import_test_package/outer.proto \ python/google/protobuf/internal/json_format_test.py \ @@ -1459,6 +1469,8 @@ python_EXTRA_DIST = \ python/google/protobuf/pyext/repeated_scalar_container.h \ python/google/protobuf/pyext/safe_numerics.h \ python/google/protobuf/pyext/scoped_pyobject_ptr.h \ + python/google/protobuf/pyext/unknown_field_set.cc \ + python/google/protobuf/pyext/unknown_field_set.h \ python/google/protobuf/python_protobuf.h \ python/google/protobuf/reflection.py \ python/google/protobuf/service.py \ @@ -1466,6 +1478,7 @@ python_EXTRA_DIST = \ python/google/protobuf/symbol_database.py \ python/google/protobuf/text_encoding.py \ python/google/protobuf/text_format.py \ + python/google/protobuf/unknown_fields.py \ python/google/protobuf/util/__init__.py \ python/release.sh \ python/mox.py \ @@ -1475,6 +1488,8 @@ python_EXTRA_DIST = \ python/tox.ini \ python/README.md + +# Note: please keep this in sync with the dist_files rule in ruby/BUILD.bazel. ruby_EXTRA_DIST = \ ruby/Gemfile \ ruby/.gitignore \ @@ -1550,248 +1565,79 @@ ruby_EXTRA_DIST = \ ruby/tests/type_errors.rb \ ruby/travis-test.sh -js_EXTRA_DIST = \ - js/README.md \ - js/binary/arith.js \ - js/binary/arith_test.js \ - js/binary/constants.js \ - js/binary/decoder.js \ - js/binary/decoder_test.js \ - js/binary/encoder.js \ - js/binary/message_test.js \ - js/binary/proto_test.js \ - js/binary/reader.js \ - js/binary/reader_test.js \ - js/binary/utils.js \ - js/binary/utils_test.js \ - js/binary/writer.js \ - js/binary/writer_test.js \ - js/commonjs/export.js \ - js/commonjs/export_asserts.js \ - js/commonjs/export_testdeps.js \ - js/commonjs/import_test.js \ - js/commonjs/jasmine.json \ - js/commonjs/rewrite_tests_for_commonjs.js \ - js/commonjs/strict_test.js \ - js/commonjs/test6/test6.proto \ - js/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/binary/arith_test.js \ - js/compatibility_tests/v3.0.0/binary/decoder_test.js \ - js/compatibility_tests/v3.0.0/binary/proto_test.js \ - js/compatibility_tests/v3.0.0/binary/reader_test.js \ - js/compatibility_tests/v3.0.0/binary/utils_test.js \ - js/compatibility_tests/v3.0.0/binary/writer_test.js \ - js/compatibility_tests/v3.0.0/commonjs/export_asserts.js \ - js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js \ - js/compatibility_tests/v3.0.0/commonjs/import_test.js \ - js/compatibility_tests/v3.0.0/commonjs/jasmine.json \ - js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js \ - js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/data.proto \ - js/compatibility_tests/v3.0.0/debug_test.js \ - js/compatibility_tests/v3.0.0/jasmine1.json \ - js/compatibility_tests/v3.0.0/jasmine2.json \ - js/compatibility_tests/v3.0.0/jasmine3.json \ - js/compatibility_tests/v3.0.0/message_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.proto \ - js/compatibility_tests/v3.0.0/test2.proto \ - js/compatibility_tests/v3.0.0/test3.proto \ - js/compatibility_tests/v3.0.0/test4.proto \ - js/compatibility_tests/v3.0.0/test5.proto \ - js/compatibility_tests/v3.0.0/testbinary.proto \ - js/compatibility_tests/v3.0.0/testempty.proto \ - js/compatibility_tests/v3.0.0/test.proto \ - js/compatibility_tests/v3.0.0/test.sh \ - js/compatibility_tests/v3.1.0/testempty.proto \ - js/compatibility_tests/v3.1.0/testbinary.proto \ - js/compatibility_tests/v3.1.0/test5.proto \ - js/compatibility_tests/v3.1.0/test4.proto \ - js/compatibility_tests/v3.1.0/test3.proto \ - js/compatibility_tests/v3.1.0/test2.proto \ - js/compatibility_tests/v3.1.0/test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.js \ - js/compatibility_tests/v3.1.0/message_test.js \ - js/compatibility_tests/v3.1.0/maps_test.js \ - js/compatibility_tests/v3.1.0/debug_test.js \ - js/compatibility_tests/v3.1.0/data.proto \ - js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.1.0/binary/writer_test.js \ - js/compatibility_tests/v3.1.0/binary/utils_test.js \ - js/compatibility_tests/v3.1.0/binary/reader_test.js \ - js/compatibility_tests/v3.1.0/binary/proto_test.js \ - js/compatibility_tests/v3.1.0/binary/decoder_test.js \ - js/compatibility_tests/v3.1.0/binary/arith_test.js \ - js/data.proto \ - js/debug.js \ - js/debug_test.js \ - js/experimental/runtime/kernel/message_set.js \ - js/experimental/runtime/kernel/message_set_test.js \ - js/experimental/runtime/kernel/tag.js \ - js/experimental/runtime/kernel/tag_test.js \ - js/gulpfile.js \ - js/jasmine.json \ - js/map.js \ - js/maps_test.js \ - js/message.js \ - js/message_test.js \ - js/node_loader.js \ - js/package.json \ - js/proto3_test.js \ - js/proto3_test.proto \ - js/test.proto \ - js/test2.proto \ - js/test3.proto \ - js/test4.proto \ - js/test5.proto \ - js/test8.proto \ - js/test9.proto \ - js/test10.proto \ - js/test11.proto \ - js/test12.proto \ - js/test13.proto \ - js/test14.proto \ - js/test15.proto \ - js/test_bootstrap.js \ - js/testbinary.proto \ - js/testempty.proto \ - js/testlargenumbers.proto \ - js/experimental/runtime/testing/jasmine_protobuf.js \ - js/experimental/runtime/testing/ensure_custom_equality_test.js \ - js/experimental/runtime/testing/binary/test_message.js \ - js/experimental/runtime/kernel/writer_test.js \ - js/experimental/runtime/kernel/writer.js \ - js/experimental/runtime/kernel/wire_type.js \ - js/experimental/runtime/kernel/uint8arrays_test.js \ - js/experimental/runtime/kernel/uint8arrays.js \ - js/experimental/runtime/kernel/uint32_test_pairs.js \ - js/experimental/runtime/kernel/typed_arrays_test.js \ - js/experimental/runtime/kernel/typed_arrays.js \ - js/experimental/runtime/kernel/textencoding_test.js \ - js/experimental/runtime/kernel/textencoding.js \ - js/experimental/runtime/kernel/storage.js \ - js/experimental/runtime/kernel/sint64_test_pairs.js \ - js/experimental/runtime/kernel/sint32_test_pairs.js \ - js/experimental/runtime/kernel/sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/reader_test.js \ - js/experimental/runtime/kernel/reader.js \ - js/experimental/runtime/kernel/packed_uint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_int64_test_pairs.js \ - js/experimental/runtime/kernel/packed_int32_test_pairs.js \ - js/experimental/runtime/kernel/packed_float_test_pairs.js \ - js/experimental/runtime/kernel/packed_fixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_double_test_pairs.js \ - js/experimental/runtime/kernel/packed_bool_test_pairs.js \ - js/experimental/runtime/kernel/kernel_test.js \ - js/experimental/runtime/kernel/kernel_repeated_test.js \ - js/experimental/runtime/kernel/kernel_compatibility_test.js \ - js/experimental/runtime/kernel/kernel.js \ - js/experimental/runtime/kernel/internal_message.js \ - js/experimental/runtime/kernel/int64_test_pairs.js \ - js/experimental/runtime/kernel/int32_test_pairs.js \ - js/experimental/runtime/kernel/indexer_test.js \ - js/experimental/runtime/kernel/indexer.js \ - js/experimental/runtime/kernel/float_test_pairs.js \ - js/experimental/runtime/kernel/fixed32_test_pairs.js \ - js/experimental/runtime/kernel/field.js \ - js/experimental/runtime/kernel/double_test_pairs.js \ - js/experimental/runtime/kernel/conformance/wire_format.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto3.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto2.js \ - js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js \ - js/experimental/runtime/kernel/conformance/conformance_testee.js \ - js/experimental/runtime/kernel/conformance/conformance_response.js \ - js/experimental/runtime/kernel/conformance/conformance_request.js \ - js/experimental/runtime/kernel/buffer_decoder_test.js \ - js/experimental/runtime/kernel/buffer_decoder_helper.js \ - js/experimental/runtime/kernel/buffer_decoder.js \ - js/experimental/runtime/kernel/bool_test_pairs.js \ - js/experimental/runtime/kernel/binary_storage_test.js \ - js/experimental/runtime/kernel/binary_storage.js \ - js/experimental/runtime/internal/checks_test.js \ - js/experimental/runtime/internal/checks.js \ - js/experimental/runtime/int64_test.js \ - js/experimental/runtime/int64.js \ - js/experimental/runtime/bytestring_test.js \ - js/experimental/runtime/bytestring_internal.js \ - js/experimental/runtime/bytestring.js \ - js/experimental/benchmarks/code_size/kernel/popular_types.js \ - js/experimental/benchmarks/code_size/kernel/all_types.js \ - js/experimental/benchmarks/code_size/code_size_base.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js +all_EXTRA_DIST = $(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) -all_EXTRA_DIST = $(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) -EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ - autogen.sh \ - generate_descriptor_proto.sh \ - README.md \ - LICENSE \ - CONTRIBUTORS.txt \ - CHANGES.txt \ - update_file_lists.sh \ - BUILD \ - WORKSPACE \ - cmake/CMakeLists.txt \ - cmake/README.md \ - cmake/conformance.cmake \ - cmake/examples.cmake \ - cmake/extract_includes.bat.in \ - cmake/install.cmake \ - cmake/libprotobuf.cmake \ - cmake/libprotobuf-lite.cmake \ - cmake/libprotoc.cmake \ - cmake/protobuf-config-version.cmake.in \ - cmake/protobuf-config.cmake.in \ - cmake/protobuf-lite.pc.cmake \ - cmake/protobuf-module.cmake.in \ - cmake/protobuf-options.cmake \ - cmake/protobuf.pc.cmake \ - cmake/protoc.cmake \ - cmake/tests.cmake \ - cmake/version.rc.in \ - compiler_config_setting.bzl \ - build_files_updated_unittest.sh \ - cc_proto_blacklist_test.bzl \ - editors/README.txt \ - editors/proto.vim \ - editors/protobuf-mode.el \ - examples/AddPerson.java \ - examples/BUILD \ - examples/CMakeLists.txt \ - examples/ListPeople.java \ - examples/Makefile \ - examples/README.md \ - examples/WORKSPACE \ - examples/add_person.cc \ - examples/add_person.dart \ - examples/add_person.go \ - examples/add_person.py \ - examples/add_person_test.go \ - examples/addressbook.proto \ - examples/list_people.cc \ - examples/list_people.dart \ - examples/list_people.go \ - examples/list_people.py \ - examples/list_people_test.go \ - examples/pubspec.yaml \ - maven_install.json \ - protobuf.bzl \ - protobuf_deps.bzl \ - protobuf_version.bzl \ - third_party/zlib.BUILD \ - util/python/BUILD \ - internal.bzl +# Note: please keep this in sync with the common_dist_files rule in BUILD.bazel. +EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ + autogen.sh \ + generate_descriptor_proto.sh \ + README.md \ + LICENSE \ + CONTRIBUTORS.txt \ + CHANGES.txt \ + update_file_lists.sh \ + BUILD.bazel \ + WORKSPACE \ + CMakeLists.txt \ + build_defs/BUILD.bazel \ + build_defs/cc_proto_blacklist_test.bzl \ + build_defs/compiler_config_setting.bzl \ + build_defs/cpp_opts.bzl \ + build_files_updated_unittest.sh \ + cmake/CMakeLists.txt \ + cmake/README.md \ + cmake/conformance.cmake \ + cmake/examples.cmake \ + cmake/extract_includes.bat.in \ + cmake/install.cmake \ + cmake/libprotobuf-lite.cmake \ + cmake/libprotobuf.cmake \ + cmake/libprotoc.cmake \ + cmake/protobuf-config-version.cmake.in \ + cmake/protobuf-config.cmake.in \ + cmake/protobuf-lite.pc.cmake \ + cmake/protobuf-module.cmake.in \ + cmake/protobuf-options.cmake \ + cmake/protobuf.pc.cmake \ + cmake/protoc.cmake \ + cmake/tests.cmake \ + cmake/version.rc.in \ + csharp/BUILD.bazel \ + editors/README.txt \ + editors/proto.vim \ + editors/protobuf-mode.el \ + examples/AddPerson.java \ + examples/BUILD.bazel \ + examples/CMakeLists.txt \ + examples/ListPeople.java \ + examples/Makefile \ + examples/README.md \ + examples/WORKSPACE \ + examples/add_person.cc \ + examples/add_person.dart \ + examples/add_person.py \ + examples/addressbook.proto \ + examples/go/cmd/add_person/add_person.go \ + examples/go/cmd/add_person/add_person_test.go \ + examples/go/cmd/list_people/list_people.go \ + examples/go/cmd/list_people/list_people_test.go \ + examples/go/go.sum \ + examples/go/go.mod \ + examples/list_people.cc \ + examples/list_people.dart \ + examples/list_people.py \ + examples/pubspec.yaml \ + conformance/BUILD.bazel \ + conformance/defs.bzl \ + maven_install.json \ + php/BUILD.bazel \ + protobuf.bzl \ + protobuf_deps.bzl \ + protobuf_release.bzl \ + protobuf_version.bzl \ + ruby/BUILD.bazel \ + third_party/zlib.BUILD \ + util/python/BUILD.bazel # Deletes all the files generated by autogen.sh. diff --git a/third_party/protobuf/README.md b/third_party/protobuf/README.md index 618dc2a7..c2e6575f 100644 --- a/third_party/protobuf/README.md +++ b/third_party/protobuf/README.md @@ -38,7 +38,7 @@ page, check out the maven repo here: [https://repo1.maven.org/maven2/com/google/protobuf/protoc/](https://repo1.maven.org/maven2/com/google/protobuf/protoc/) These pre-built binaries are only provided for released versions. If you want -to use the github master version at HEAD, or you need to modify protobuf code, +to use the github main version at HEAD, or you need to modify protobuf code, or you are using C++, it's recommended to build your own protoc binary from source. @@ -59,7 +59,6 @@ how to install protobuf runtime for that specific language: | Python | [python](python) | | Objective-C | [objectivec](objectivec) | | C# | [csharp](csharp) | -| JavaScript | [js](js) | | Ruby | [ruby](ruby) | | Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)| | PHP | [php](php) | diff --git a/third_party/protobuf/WORKSPACE b/third_party/protobuf/WORKSPACE index e500967f..d01122a9 100644 --- a/third_party/protobuf/WORKSPACE +++ b/third_party/protobuf/WORKSPACE @@ -56,3 +56,16 @@ pinned_maven_install() load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() + +load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") +rules_pkg_dependencies() + +# For `kt_jvm_library` +load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories") +kotlin_repositories() + +load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") +kt_register_toolchains() + +load("@upb//bazel:workspace_deps.bzl", "upb_deps") +upb_deps() diff --git a/third_party/protobuf/aclocal.m4 b/third_party/protobuf/aclocal.m4 index 69552d75..6579e62e 100644 --- a/third_party/protobuf/aclocal.m4 +++ b/third_party/protobuf/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.16.4 -*- Autoconf -*- +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.4], [], +m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,7 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.4])dnl +[AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -488,6 +488,10 @@ m4_defn([AC_PROG_CC]) # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl +m4_ifdef([_$0_ALREADY_INIT], + [m4_fatal([$0 expanded multiple times +]m4_defn([_$0_ALREADY_INIT]))], + [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl diff --git a/third_party/protobuf/benchmarks/Makefile.am b/third_party/protobuf/benchmarks/Makefile.am index 2b2204d0..ed579788 100644 --- a/third_party/protobuf/benchmarks/Makefile.am +++ b/third_party/protobuf/benchmarks/Makefile.am @@ -91,8 +91,8 @@ $(benchmarks_protoc_outputs_proto2_header): protoc_middleman2 initialize_submodule: oldpwd=`pwd` - cd $(top_srcdir) && git submodule update --init -r third_party/benchmark && \ - cd third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make + cd $(top_srcdir) && git submodule update --init -r third_party/benchmark && cd third_party/benchmark \ + && cmake -DCMAKE_BUILD_TYPE=Release && make cd $$oldpwd touch initialize_submodule @@ -165,7 +165,7 @@ python_add_init: protoc_middleman protoc_middleman2 done \ done -python_cpp_pkg_flags = `pkg-config --cflags --libs python` +python_cpp_pkg_flags = `pkg-config --cflags --libs python3` lib_LTLIBRARIES = libbenchmark_messages.la libbenchmark_messages_la_SOURCES = python/python_benchmark_messages.cc @@ -186,7 +186,7 @@ python-pure-python-benchmark: python_add_init @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'python\' >> python-pure-python-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-pure-python-benchmark - @echo python tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark + @echo python3 tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark @chmod +x python-pure-python-benchmark python-cpp-reflection-benchmark: python_add_init @@ -196,7 +196,7 @@ python-cpp-reflection-benchmark: python_add_init @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-reflection-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-reflection-benchmark - @echo python tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark + @echo python3 tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark @chmod +x python-cpp-reflection-benchmark python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la @@ -206,7 +206,7 @@ python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-generated-code-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-generated-code-benchmark - @echo python tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark + @echo python3 tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark @chmod +x python-cpp-generated-code-benchmark python-pure-python: python-pure-python-benchmark diff --git a/third_party/protobuf/benchmarks/Makefile.in b/third_party/protobuf/benchmarks/Makefile.in index ee08ba5c..a8701627 100644 --- a/third_party/protobuf/benchmarks/Makefile.in +++ b/third_party/protobuf/benchmarks/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.16.4 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -514,6 +514,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INSTALL = @INSTALL@ @@ -715,7 +716,7 @@ nodist_cpp_benchmark_SOURCES = \ java_benchmark_testing_files = \ java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java -python_cpp_pkg_flags = `pkg-config --cflags --libs python` +python_cpp_pkg_flags = `pkg-config --cflags --libs python3` lib_LTLIBRARIES = libbenchmark_messages.la libbenchmark_messages_la_SOURCES = python/python_benchmark_messages.cc libbenchmark_messages_la_LIBADD = $(top_srcdir)/src/.libs/libprotobuf.la @@ -3166,8 +3167,8 @@ $(benchmarks_protoc_outputs_proto2_header): protoc_middleman2 initialize_submodule: oldpwd=`pwd` - cd $(top_srcdir) && git submodule update --init -r third_party/benchmark && \ - cd third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make + cd $(top_srcdir) && git submodule update --init -r third_party/benchmark && cd third_party/benchmark \ + && cmake -DCMAKE_BUILD_TYPE=Release && make cd $$oldpwd touch initialize_submodule @@ -3227,7 +3228,7 @@ python-pure-python-benchmark: python_add_init @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'python\' >> python-pure-python-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-pure-python-benchmark - @echo python tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark + @echo python3 tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark @chmod +x python-pure-python-benchmark python-cpp-reflection-benchmark: python_add_init @@ -3237,7 +3238,7 @@ python-cpp-reflection-benchmark: python_add_init @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-reflection-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-reflection-benchmark - @echo python tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark + @echo python3 tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark @chmod +x python-cpp-reflection-benchmark python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la @@ -3247,7 +3248,7 @@ python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-generated-code-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-generated-code-benchmark - @echo python tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark + @echo python3 tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark @chmod +x python-cpp-generated-code-benchmark python-pure-python: python-pure-python-benchmark diff --git a/third_party/protobuf/benchmarks/README.md b/third_party/protobuf/benchmarks/README.md index 9c25c780..70c35966 100644 --- a/third_party/protobuf/benchmarks/README.md +++ b/third_party/protobuf/benchmarks/README.md @@ -4,8 +4,8 @@ This directory contains benchmarking schemas and data sets that you can use to test a variety of performance scenarios against your protobuf language runtime. If you are looking for performance -numbers of officially support languages, see [here]( -https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md) +numbers of officially supported languages, see [Protobuf Performance]( +https://github.com/protocolbuffers/protobuf/blob/main/docs/performance.md). ## Prerequisite @@ -61,7 +61,7 @@ PHP benchmark's requirement is the same as PHP protobuf's requirements. The benc include PHP protobuf's src and build the c extension if required. ### Node.js -Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/master/js), which needn't to manually install either +Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/main/js), which needn't to manually install either ### C# The C# benchmark code is built as part of the main Google.Protobuf @@ -69,25 +69,23 @@ solution. It requires the .NET Core SDK, and depends on [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet), which will be downloaded automatically. -### Big data - -There's some optional big testing data which is not included in the directory -initially, you need to run the following command to download the testing data: - -``` -$ ./download_data.sh -``` - -After doing this the big data file will automatically generated in the -benchmark directory. - ## Run instructions To run all the benchmark dataset: ### Java: +First build the Java binary in the usual way with Maven: + ``` +$ cd java +$ mvn install +``` + +Assuming that completes successfully, + +``` +$ cd ../benchmarks $ make java ``` diff --git a/third_party/protobuf/benchmarks/python/python_benchmark_messages.cc b/third_party/protobuf/benchmarks/python/python_benchmark_messages.cc index ded16fe9..f6ddcf31 100644 --- a/third_party/protobuf/benchmarks/python/python_benchmark_messages.cc +++ b/third_party/protobuf/benchmarks/python/python_benchmark_messages.cc @@ -7,13 +7,18 @@ #include "datasets/google_message3/benchmark_message3.pb.h" #include "datasets/google_message4/benchmark_message4.pb.h" -static PyMethodDef python_benchmark_methods[] = { - {NULL, NULL, 0, NULL} /* Sentinel */ -}; +static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, + "libbenchmark_messages", + "Benchmark messages Python module", + -1, + NULL, + NULL, + NULL, + NULL, + NULL}; - -PyMODINIT_FUNC -initlibbenchmark_messages() { +extern "C" { +PyMODINIT_FUNC PyInit_libbenchmark_messages() { benchmarks::BenchmarkDataset().descriptor(); benchmarks::proto3::GoogleMessage1().descriptor(); benchmarks::proto2::GoogleMessage1().descriptor(); @@ -21,9 +26,6 @@ initlibbenchmark_messages() { benchmarks::google_message3::GoogleMessage3().descriptor(); benchmarks::google_message4::GoogleMessage4().descriptor(); - PyObject *m; - - m = Py_InitModule("libbenchmark_messages", python_benchmark_methods); - if (m == NULL) - return; + return PyModule_Create(&_module); +} } diff --git a/third_party/protobuf/build_defs/BUILD.bazel b/third_party/protobuf/build_defs/BUILD.bazel new file mode 100644 index 00000000..a5d831c9 --- /dev/null +++ b/third_party/protobuf/build_defs/BUILD.bazel @@ -0,0 +1,173 @@ +# Internal Starlark definitions for Protobuf. + +load("@rules_cc//cc:defs.bzl", starlark_cc_proto_library = "cc_proto_library") +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") +load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test") +load(":compiler_config_setting.bzl", "create_compiler_config_setting") + +package( + default_visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], +) + +create_compiler_config_setting( + name = "config_msvc", + value = "msvc-cl", +) + +# Android NDK builds can specify different crosstool_top flags to choose which +# STL they use for C++. We need these multiple variants to catch all of those +# versions of crosstool_top and reliably detect Android. +# +# For more info on the various crosstool_tops used by NDK Bazel builds, see: +# https://docs.bazel.build/versions/master/android-ndk.html#configuring-the-stl + +config_setting( + name = "config_android", + values = { + "crosstool_top": "//external:android/crosstool", + }, +) + +config_setting( + name = "config_android-stlport", + values = { + "crosstool_top": "@androidndk//:toolchain-stlport", + }, +) + +config_setting( + name = "config_android-libcpp", + values = { + "crosstool_top": "@androidndk//:toolchain-libcpp", + }, +) + +config_setting( + name = "config_android-gnu-libstdcpp", + values = { + "crosstool_top": "@androidndk//:toolchain-gnu-libstdcpp", + }, +) + +config_setting( + name = "config_android-default", + values = { + "crosstool_top": "@androidndk//:default_crosstool", + }, +) + +config_setting( + name = "config_win32", + values = { + "cpu": "win32", + }, +) + +config_setting( + name = "config_win64", + values = { + "cpu": "win64", + }, +) + +# Internal testing: + +starlark_cc_proto_library( + name = "any_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:any_proto"], +) + +starlark_cc_proto_library( + name = "api_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:api_proto"], +) + +starlark_cc_proto_library( + name = "compiler_plugin_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:compiler_plugin_proto"], +) + +starlark_cc_proto_library( + name = "descriptor_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:descriptor_proto"], +) + +starlark_cc_proto_library( + name = "duration_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:duration_proto"], +) + +starlark_cc_proto_library( + name = "empty_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:empty_proto"], +) + +starlark_cc_proto_library( + name = "field_mask_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:field_mask_proto"], +) + +starlark_cc_proto_library( + name = "source_context_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:source_context_proto"], +) + +starlark_cc_proto_library( + name = "struct_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:struct_proto"], +) + +starlark_cc_proto_library( + name = "timestamp_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:timestamp_proto"], +) + +starlark_cc_proto_library( + name = "type_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:type_proto"], +) + +starlark_cc_proto_library( + name = "wrappers_cc_proto", + visibility = ["//visibility:private"], + deps = ["//:wrappers_proto"], +) + +cc_proto_blacklist_test( + name = "cc_proto_blacklist_test", + deps = [ + ":any_cc_proto", + ":api_cc_proto", + ":compiler_plugin_cc_proto", + ":descriptor_cc_proto", + ":duration_cc_proto", + ":empty_cc_proto", + ":field_mask_cc_proto", + ":source_context_cc_proto", + ":struct_cc_proto", + ":timestamp_cc_proto", + ":type_cc_proto", + ":wrappers_cc_proto", + ], +) + +pkg_files( + name = "dist_files", + srcs = glob(["*"]), + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) diff --git a/third_party/protobuf/cc_proto_blacklist_test.bzl b/third_party/protobuf/build_defs/cc_proto_blacklist_test.bzl similarity index 92% rename from third_party/protobuf/cc_proto_blacklist_test.bzl rename to third_party/protobuf/build_defs/cc_proto_blacklist_test.bzl index df54293c..260abdef 100644 --- a/third_party/protobuf/cc_proto_blacklist_test.bzl +++ b/third_party/protobuf/build_defs/cc_proto_blacklist_test.bzl @@ -14,14 +14,14 @@ def _cc_proto_blacklist_test_impl(ctx): env = unittest.begin(ctx) for dep in ctx.attr.deps: - files = len(dep.files.to_list()) + files = dep.files.to_list() asserts.equals( env, - 0, + [], files, "Expected that target '{}' does not provide files, got {}".format( dep.label, - files, + len(files), ), ) diff --git a/third_party/protobuf/compiler_config_setting.bzl b/third_party/protobuf/build_defs/compiler_config_setting.bzl similarity index 100% rename from third_party/protobuf/compiler_config_setting.bzl rename to third_party/protobuf/build_defs/compiler_config_setting.bzl diff --git a/third_party/protobuf/build_defs/cpp_opts.bzl b/third_party/protobuf/build_defs/cpp_opts.bzl new file mode 100644 index 00000000..1d5594d1 --- /dev/null +++ b/third_party/protobuf/build_defs/cpp_opts.bzl @@ -0,0 +1,47 @@ +# C++ compile/link options for Protobuf. + +COPTS = select({ + "//build_defs:config_msvc": [ + "/wd4065", # switch statement contains 'default' but no 'case' labels + "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data + "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' + "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data + "/wd4305", # 'identifier' : truncation from 'type1' to 'type2' + "/wd4307", # 'operator' : integral constant overflow + "/wd4309", # 'conversion' : truncation of constant value + "/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + "/wd4355", # 'this' : used in base member initializer list + "/wd4506", # no definition for inline function 'function' + "/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning) + "/wd4996", # The compiler encountered a deprecated declaration. + ], + "//conditions:default": [ + "-DHAVE_ZLIB", + "-Woverloaded-virtual", + "-Wno-sign-compare", + ], +}) + +# Android and MSVC builds do not need to link in a separate pthread library. +LINK_OPTS = select({ + "//build_defs:config_android": [], + "//build_defs:config_android-stlport": [], + "//build_defs:config_android-libcpp": [], + "//build_defs:config_android-gnu-libstdcpp": [], + "//build_defs:config_android-default": [], + "//build_defs:config_msvc": [ + # Suppress linker warnings about files with no symbols defined. + "-ignore:4221", + ], + "//conditions:default": [ + "-lpthread", + "-lm", + ], +}) + +# When cross-compiling for Windows we need to statically link pthread and the C++ library. +PROTOC_LINK_OPTS = select({ + "//build_defs:config_win32": ["-static"], + "//build_defs:config_win64": ["-static"], + "//conditions:default": [], +}) diff --git a/third_party/protobuf/cmake/CMakeLists.txt b/third_party/protobuf/cmake/CMakeLists.txt index 51e8478f..4e395735 100644 --- a/third_party/protobuf/cmake/CMakeLists.txt +++ b/third_party/protobuf/cmake/CMakeLists.txt @@ -1,312 +1,9 @@ -# Minimum CMake required -cmake_minimum_required(VERSION 3.1.3) +cmake_minimum_required(VERSION 3.5) -if(protobuf_VERBOSE) - message(STATUS "Protocol Buffers Configuring...") -endif() +message(WARNING "Calling of cmake with source directory set to \"cmake\" subdirectory of Protocol Buffers project is deprecated. Top-level directory of Protocol Buffers project should be used instead.") -# CMake policies -cmake_policy(SET CMP0022 NEW) -# On MacOS use @rpath/ for target's install name prefix path -if (POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) -endif () -# Clear VERSION variables when no VERSION is given to project() -if(POLICY CMP0048) - cmake_policy(SET CMP0048 NEW) -endif() -# MSVC runtime library flags are selected by an abstraction. -if(POLICY CMP0091) - cmake_policy(SET CMP0091 NEW) -endif() - -# Project project(protobuf C CXX) -# Add c++11 flags -if (CYGWIN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") -else() - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) -endif() +set(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE TRUE) -# The Intel compiler isn't able to deal with noinline member functions of -# template classes defined in headers. As such it spams the output with -# warning #2196: routine is both "inline" and "noinline" -# This silences that warning. -if (CMAKE_CXX_COMPILER_ID MATCHES Intel) - string(APPEND CMAKE_CXX_FLAGS " -diag-disable=2196") -endif() - -# Options -if(WITH_PROTOC) - set(protobuf_PROTOC_EXE ${WITH_PROTOC} CACHE FILEPATH "Protocol Buffer Compiler executable" FORCE) -endif() -option(protobuf_BUILD_TESTS "Build tests" ON) -option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF) -option(protobuf_BUILD_EXAMPLES "Build examples" OFF) -option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON) -option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF) -option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF) -if (BUILD_SHARED_LIBS) - set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON) -else (BUILD_SHARED_LIBS) - set(protobuf_BUILD_SHARED_LIBS_DEFAULT OFF) -endif (BUILD_SHARED_LIBS) -option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHARED_LIBS_DEFAULT}) -include(CMakeDependentOption) -cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON - "NOT protobuf_BUILD_SHARED_LIBS" OFF) -set(protobuf_WITH_ZLIB_DEFAULT ON) -option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT}) -set(protobuf_DEBUG_POSTFIX "d" - CACHE STRING "Default debug postfix") -mark_as_advanced(protobuf_DEBUG_POSTFIX) -# User options -include(protobuf-options.cmake) - -# Overrides for option dependencies -if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS) - set(protobuf_BUILD_LIBPROTOC ON) -endif () -# Path to main configure script -set(protobuf_CONFIGURE_SCRIPT "../configure.ac") - -# Parse configure script -set(protobuf_AC_INIT_REGEX - "^AC_INIT\\(\\[([^]]+)\\],\\[([^]]+)\\],\\[([^]]+)\\],\\[([^]]+)\\]\\)$") -file(STRINGS "${protobuf_CONFIGURE_SCRIPT}" protobuf_AC_INIT_LINE - LIMIT_COUNT 1 REGEX "^AC_INIT") -# Description -string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\1" - protobuf_DESCRIPTION "${protobuf_AC_INIT_LINE}") -# Version -string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\2" - protobuf_VERSION_STRING "${protobuf_AC_INIT_LINE}") -# Contact -string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\3" - protobuf_CONTACT "${protobuf_AC_INIT_LINE}") -# Parse version tweaks -set(protobuf_VERSION_REGEX "^([0-9]+)\\.([0-9]+)\\.([0-9]+)([-]rc[-]|\\.)?([0-9]*)$") -string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\1" - protobuf_VERSION_MAJOR "${protobuf_VERSION_STRING}") -string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\2" - protobuf_VERSION_MINOR "${protobuf_VERSION_STRING}") -string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\3" - protobuf_VERSION_PATCH "${protobuf_VERSION_STRING}") -string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\5" - protobuf_VERSION_PRERELEASE "${protobuf_VERSION_STRING}") - -message(STATUS "${protobuf_VERSION_PRERELEASE}") - -# Package version -set(protobuf_VERSION - "${protobuf_VERSION_MAJOR}.${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}") - -if(protobuf_VERSION_PRERELEASE) - set(protobuf_VERSION "${protobuf_VERSION}.${protobuf_VERSION_PRERELEASE}") -else() - set(protobuf_VERSION "${protobuf_VERSION}.0") -endif() -message(STATUS "${protobuf_VERSION}") - -if(protobuf_VERBOSE) - message(STATUS "Configuration script parsing status [") - message(STATUS " Description : ${protobuf_DESCRIPTION}") - message(STATUS " Version : ${protobuf_VERSION} (${protobuf_VERSION_STRING})") - message(STATUS " Contact : ${protobuf_CONTACT}") - message(STATUS "]") -endif() - -add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD) - -if (protobuf_DISABLE_RTTI) - add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1) -endif() - -find_package(Threads REQUIRED) - -set(_protobuf_FIND_ZLIB) -if (protobuf_WITH_ZLIB) - find_package(ZLIB) - if (ZLIB_FOUND) - set(HAVE_ZLIB 1) - # FindZLIB module define ZLIB_INCLUDE_DIRS variable - # Set ZLIB_INCLUDE_DIRECTORIES for compatible - set(ZLIB_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRECTORIES} ${ZLIB_INCLUDE_DIRS}) - # Using imported target if exists - if (TARGET ZLIB::ZLIB) - set(ZLIB_LIBRARIES ZLIB::ZLIB) - set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()") - endif (TARGET ZLIB::ZLIB) - else (ZLIB_FOUND) - set(HAVE_ZLIB 0) - # Explicitly set these to empty (override NOT_FOUND) so cmake doesn't - # complain when we use them later. - set(ZLIB_INCLUDE_DIRECTORIES) - set(ZLIB_LIBRARIES) - endif (ZLIB_FOUND) -endif (protobuf_WITH_ZLIB) - -if (HAVE_ZLIB) - add_definitions(-DHAVE_ZLIB) -endif (HAVE_ZLIB) - -# We need to link with libatomic on systems that do not have builtin atomics, or -# don't have builtin support for 8 byte atomics -set(protobuf_LINK_LIBATOMIC false) -if (NOT MSVC) - include(CheckCXXSourceCompiles) - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -std=c++11) - check_cxx_source_compiles(" - #include - int main() { - return std::atomic{}; - } - " protobuf_HAVE_BUILTIN_ATOMICS) - if (NOT protobuf_HAVE_BUILTIN_ATOMICS) - set(protobuf_LINK_LIBATOMIC true) - endif (NOT protobuf_HAVE_BUILTIN_ATOMICS) - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) -endif (NOT MSVC) - -if (protobuf_BUILD_SHARED_LIBS) - set(protobuf_SHARED_OR_STATIC "SHARED") -else (protobuf_BUILD_SHARED_LIBS) - set(protobuf_SHARED_OR_STATIC "STATIC") - # The CMAKE__FLAGS(_)? is meant to be user controlled. - # Prior to CMake 3.15, the MSVC runtime library was pushed into the same flags - # making programmatic control difficult. Prefer the functionality in newer - # CMake versions when available. - if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) - else() - # In case we are building static libraries, link also the runtime library statically - # so that MSVCR*.DLL is not required at runtime. - # https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx - # This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd - # http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F - if (MSVC AND protobuf_MSVC_STATIC_RUNTIME) - foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - endif (MSVC AND protobuf_MSVC_STATIC_RUNTIME) - endif() -endif (protobuf_BUILD_SHARED_LIBS) - -if (MSVC) - if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - # Build with multiple processes - add_definitions(/MP) - endif() - # Set source file and execution character sets to UTF-8 - add_definitions(/utf-8) - # MSVC warning suppressions - add_definitions( - /wd4018 # 'expression' : signed/unsigned mismatch - /wd4065 # switch statement contains 'default' but no 'case' labels - /wd4146 # unary minus operator applied to unsigned type, result still unsigned - /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data - /wd4251 # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' - /wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data - /wd4305 # 'identifier' : truncation from 'type1' to 'type2' - /wd4307 # 'operator' : integral constant overflow - /wd4309 # 'conversion' : truncation of constant value - /wd4334 # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) - /wd4355 # 'this' : used in base member initializer list - /wd4506 # no definition for inline function 'function' - /wd4800 # 'type' : forcing value to bool 'true' or 'false' (performance warning) - /wd4996 # The compiler encountered a deprecated declaration. - ) - # Allow big object - add_definitions(/bigobj) - string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR}) - string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR}) - string(REPLACE "." "," protobuf_RC_FILEVERSION "${protobuf_VERSION}") - configure_file(extract_includes.bat.in extract_includes.bat) - - # Suppress linker warnings about files with no symbols defined. - set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") - - if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - # Configure Resource Compiler - enable_language(RC) - # use English language (0x409) in resource compiler - set(rc_flags "/l0x409") - # fix rc.exe invocations because of usage of add_definitions() - set(CMAKE_RC_COMPILE_OBJECT " ${rc_flags} /fo ") - endif() - - configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) -endif (MSVC) - - -get_filename_component(protobuf_source_dir ${protobuf_SOURCE_DIR} PATH) - -include_directories( - ${ZLIB_INCLUDE_DIRECTORIES} - ${protobuf_BINARY_DIR} - ${protobuf_source_dir}/src) - -if (MSVC) - # Add the "lib" prefix for generated .lib outputs. - set(LIB_PREFIX lib) -else (MSVC) - # When building with "make", "lib" prefix will be added automatically by - # the build tool. - set(LIB_PREFIX) -endif (MSVC) - -if (protobuf_UNICODE) - add_definitions(-DUNICODE -D_UNICODE) -endif (protobuf_UNICODE) - -include(libprotobuf-lite.cmake) -include(libprotobuf.cmake) -if (protobuf_BUILD_LIBPROTOC) - include(libprotoc.cmake) -endif (protobuf_BUILD_LIBPROTOC) -if (protobuf_BUILD_PROTOC_BINARIES) - include(protoc.cmake) - if (NOT DEFINED protobuf_PROTOC_EXE) - set(protobuf_PROTOC_EXE protoc) - endif (NOT DEFINED protobuf_PROTOC_EXE) -endif (protobuf_BUILD_PROTOC_BINARIES) - -# Ensure we have a protoc executable if we need one -if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLES) - if (NOT DEFINED protobuf_PROTOC_EXE) - find_program(protobuf_PROTOC_EXE protoc) - if (NOT protobuf_PROTOC_EXE) - message(FATAL "Build requires 'protoc' but binary not found and not building protoc.") - endif () - endif () - if(protobuf_VERBOSE) - message(STATUS "Using protoc : ${protobuf_PROTOC_EXE}") - endif(protobuf_VERBOSE) -endif () - -if (protobuf_BUILD_TESTS) - include(tests.cmake) -endif (protobuf_BUILD_TESTS) - -if (protobuf_BUILD_CONFORMANCE) - include(conformance.cmake) -endif (protobuf_BUILD_CONFORMANCE) - -include(install.cmake) - -if (protobuf_BUILD_EXAMPLES) - include(examples.cmake) -endif (protobuf_BUILD_EXAMPLES) - -if(protobuf_VERBOSE) - message(STATUS "Protocol Buffers Configuring done") -endif(protobuf_VERBOSE) +include(../CMakeLists.txt) diff --git a/third_party/protobuf/cmake/README.md b/third_party/protobuf/cmake/README.md index 89d00c1b..ce3e6802 100644 --- a/third_party/protobuf/cmake/README.md +++ b/third_party/protobuf/cmake/README.md @@ -36,6 +36,10 @@ If *git* command is not available from *Command Prompt*, add it to system *PATH* C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd +Optionally, you will want to download [ninja](https://ninja-build.org/) and add it to your *PATH* variable. + + C:\Path\to>set PATH=%PATH%;C:\tools\ninja + Good. Now you are ready to continue. Getting Sources @@ -52,29 +56,25 @@ download `protobuf-all-[VERSION].tar.gz`. Or you can use git to clone from protobuf git repository. - C:\Path\to> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git + C:\Path\to> mkdir src & cd src + C:\Path\to\src> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git -Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *master* +Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *main* if you want to get the latest code. Go to the project folder: - C:\Path\to>cd protobuf - C:\Path\to\protobuf> + C:\Path\to\src> cd protobuf + C:\Path\to\src\protobuf> Remember to update any submodules if you are using git clone (you can skip this step if you are using a release .tar.gz or .zip package): ```console -C:\Path\to> git submodule update --init --recursive +C:\Path\to\src\protobuf> git submodule update --init --recursive ``` -Now go to *cmake* folder in protobuf sources: - - C:\Path\to\protobuf>cd cmake - C:\Path\to\protobuf\cmake> - -Good. Now you are ready to *CMake* configuration. +Good. Now you are ready for *CMake* configuration. CMake Configuration =================== @@ -82,71 +82,119 @@ CMake Configuration *CMake* supports a lot of different [generators](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html) for various native build systems. -We are only interested in -[Makefile](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#makefile-generators) -and -[Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) -generators. -We will use shadow building to separate the temporary files from the protobuf source code. +Of most interest to Windows programmers are the following: + +* [Makefile](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#makefile-generators). + This generates NMake Makefiles for Visual Studio. These work, but they are rather slow. + +* [Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) + This generates a Visual Studio solution for the project. + +* [Ninja](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#ninja-generator) + This uses the external tool [Ninja](https://ninja-build.org/) to build. It is the fastest solution available. + +Note that as of Visual Studio 2015, Visual Studio includes +[support for opening directly CMake-based projects](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio). + +It is considered good practice not to build CMake projects in the source tree but in a separate folder. Create a temporary *build* folder and change your working directory to it: - C:\Path\to\protobuf\cmake>mkdir build & cd build - C:\Path\to\protobuf\cmake\build> + mkdir C:\Path\to\build\protobuf + cd C:\Path\to\build\protobuf + C:\Path\to\build\protobuf> -The *Makefile* generator can build the project in only one configuration, so you need to build +The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build a separate folder for each configuration. -To start using a *Release* configuration: +To start using a *Release* configuration via the *NMmake* generator: - C:\Path\to\protobuf\cmake\build>mkdir release & cd release - C:\Path\to\protobuf\cmake\build\release>cmake -G "NMake Makefiles" ^ + C:\Path\to\build\protobuf>mkdir release & cd release + C:\Path\to\build\protobuf\release>cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf -It will generate *nmake* *Makefile* in current directory. +It will generate a *NMake* *Makefile* in the current directory. -To use *Debug* configuration: +To use *Debug* configuration using *Ninja*: - C:\Path\to\protobuf\cmake\build>mkdir debug & cd debug - C:\Path\to\protobuf\cmake\build\debug>cmake -G "NMake Makefiles" ^ + C:\Path\to\build\protobuf>mkdir debug & cd debug + C:\Path\to\build\protobuf\debug>cmake -G "Ninja" ^ -DCMAKE_BUILD_TYPE=Debug ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf -It will generate *nmake* *Makefile* in current directory. +It will generate *Ninja* build scripts in current directory. -To create *Visual Studio* solution file: +The *Visual Studio* generator is multi-configuration: it will generate a single *.sln* file that can be used for both *Debug* and *Release*: - C:\Path\to\protobuf\cmake\build>mkdir solution & cd solution - C:\Path\to\protobuf\cmake\build\solution>cmake -G "Visual Studio 16 2019" ^ - -DCMAKE_INSTALL_PREFIX=../../../../install ^ - ../.. + C:\Path\to\build\protobuf>mkdir solution & cd solution + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + C:\Path\to\src\protobuf It will generate *Visual Studio* solution file *protobuf.sln* in current directory. -If the *gmock* directory does not exist, and you do not want to build protobuf unit tests, -you need to add *cmake* command argument `-Dprotobuf_BUILD_TESTS=OFF` to disable testing. +Unit Tests +---------- -To make a *Visual Studio* file for Visual Studio 16 2019, create the *Visual Studio* -solution file above and edit the CMakeCache file. +Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test). - C:Path\to\protobuf\cmake\build\solution\CMakeCache +A copy of [Google Test](https://github.com/google/googletest) is included as a Git submodule in the `third-party/googletest` folder. +(You do need to initialize the Git submodules as explained above.) -Then create the *Visual Studio* solution file again +Alternately, you may want to use protobuf in a larger set-up, you may want to use that standard CMake approach where +you build and install a shared copy of Google Test. + +After you've built and installed your Google Test copy, you need add the following definition to your *cmake* command line +during the configuration step: `-Dprotobuf_USE_EXTERNAL_GTEST=ON`. +This will cause the standard CMake `find_package(GTest REQUIRED)` to be used. + +[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) will search in a default location, +which on Windows is *C:\Program Files*. This is most likely not what you want. You will want instead to search for +Google Test in your project's root directory (i.e. the same directory you've passed to `CMAKE_INSTALL_PREFIX` when +building Google Test). For this, you need to set the `CMAKE_PREFIX_PATH` CMake variable. (There are other ways in CMake, +see the [manual](https://cmake.org/cmake/help/latest/command/find_package.html) for details.) + +For example: + + C:\Path\to\build\protobuf>mkdir solution & cd solution + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + -DCMAKE_PREFIX_PATH=C:\Path\to\my_big_project ^ + -Dprotobuf_USE_EXTERNAL_GTEST=ON ^ + C:\Path\to\src\protobuf + +In most cases, `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX` will point to the same directory. + +To disable testing completely, you need to add the following argument to you *cmake* command line: `-Dprotobuf_BUILD_TESTS=OFF`. + +For example: + + C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^ + -Dprotobuf_BUILD_TESTS=OFF ^ + C:\Path\to\src\protobuf Compiling ========= -To compile protobuf: +The standard way to compile a *CMake* project is `cmake --build `. - C:\Path\to\protobuf\cmake\build\release>nmake + +Note that if your generator supports multiple configurations, you will probably want to specify which one to build: + + cmake --build C:\Path\to\build\protobuf\solution --config Release + +You can also run directly the build tool you've configured: + + C:\Path\to\build\protobuf\release>nmake or - C:\Path\to\protobuf\cmake\build\debug>nmake + C:\Path\to\build\protobuf\debug>ninja And wait for the compilation to finish. @@ -164,11 +212,15 @@ Testing To run unit-tests, first you must compile protobuf as described above. Then run: - C:\Path\to\protobuf\cmake\build\release>nmake check + C:\Path\to\protobuf\cmake\build\release>ctest --progress --output-on-failure + +You can also build the `check` target (not idiomatic CMake usage, though): + + C:\Path\to\protobuf\cmake\build\release>cmake --build . --target check or - C:\Path\to\protobuf\cmake\build\debug>nmake check + C:\Path\to\build\protobuf\release>ninja check You can also build project *check* from Visual Studio solution. Yes, it may sound strange, but it works. @@ -183,9 +235,9 @@ You should see output similar to: [==========] 1546 tests from 165 test cases ran. (2529 ms total) [ PASSED ] 1546 tests. -To run specific tests: +To run specific tests, you need to pass some command line arguments to the test program itself: - C:\Path\to\protobuf>cmake\build\release\tests.exe --gtest_filter=AnyTest* + C:\Path\to\build\protobuf\release>tests.exe --gtest_filter=AnyTest* Running main() from gmock_main.cc Note: Google Test filter = AnyTest* [==========] Running 3 tests from 1 test case. @@ -210,13 +262,17 @@ If all tests are passed, safely continue. Installing ========== -To install protobuf to the specified *install* folder: +To install protobuf to the *install* folder you've specified in the configuration step, you need to build the `install` target: - C:\Path\to\protobuf\cmake\build\release>nmake install + cmake --build C:\Path\to\build\protobuf\solution --config Release --target install + +Or if you prefer: + + C:\Path\to\build\protobuf\release>nmake install or - C:\Path\to\protobuf\cmake\build\debug>nmake install + C:\Path\to\build\protobuf\debug>ninja install You can also build project *INSTALL* from Visual Studio solution. It sounds not so strange and it works. @@ -280,16 +336,16 @@ You can also compile it from source by yourself. Getting sources: - C:\Path\to>git clone -b v1.2.8 https://github.com/madler/zlib.git - C:\Path\to>cd zlib + C:\Path\to\src>git clone -b v1.2.8 https://github.com/madler/zlib.git + C:\Path\to\src>cd zlib Compiling and Installing: - C:\Path\to\zlib>mkdir build & cd build - C:\Path\to\zlib\build>mkdir release & cd release - C:\Path\to\zlib\build\release>cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ^ - -DCMAKE_INSTALL_PREFIX=../../../install ../.. - C:\Path\to\zlib\build\release>nmake & nmake install + C:\Path\to\src\zlib>mkdir C:\Path\to\build\zlib & cd C:\Path\to\build\zlib + C:\Path\to\build\zlib>mkdir release & cd release + C:\Path\to\build\zlib\release>cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_INSTALL_PREFIX=C:\Path\to\install C:\Path\to\src\zlib + C:\Path\to\src\zlib\build\release>cmake --build . --target install You can make *debug* version or use *Visual Studio* generator also as before for the protobuf project. @@ -308,8 +364,8 @@ the headers or the .lib file in the right directory. If you already have ZLIB library and headers at some other location on your system then alternatively you can define following configuration flags to locate them: - -DZLIB_INCLUDE_DIR= - -DZLIB_LIB= + -DZLIB_INCLUDE_DIR= + -DZLIB_LIB= Build and testing protobuf as usual. @@ -320,8 +376,6 @@ The following warnings have been disabled while building the protobuf libraries and compiler. You may have to disable some of them in your own project as well, or live with them. -* C4018 - 'expression' : signed/unsigned mismatch -* C4146 - unary minus operator applied to unsigned type, result still unsigned * C4244 - Conversion from 'type1' to 'type2', possible loss of data. * C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' diff --git a/third_party/protobuf/cmake/conformance.cmake b/third_party/protobuf/cmake/conformance.cmake index b9485ff9..d6c435ac 100644 --- a/third_party/protobuf/cmake/conformance.cmake +++ b/third_party/protobuf/cmake/conformance.cmake @@ -1,49 +1,49 @@ add_custom_command( - OUTPUT ${protobuf_source_dir}/conformance/conformance.pb.cc - DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/conformance/conformance.proto - COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/conformance/conformance.proto - --proto_path=${protobuf_source_dir}/conformance - --cpp_out=${protobuf_source_dir}/conformance + OUTPUT ${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc + DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto + COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto + --proto_path=${protobuf_SOURCE_DIR}/conformance + --cpp_out=${protobuf_SOURCE_DIR}/conformance ) add_custom_command( - OUTPUT ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.pb.cc - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.pb.cc - DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto - ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.proto - COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.proto - --proto_path=${protobuf_source_dir}/src - --cpp_out=${protobuf_source_dir}/src + OUTPUT ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc + DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto + ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto + COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto + --proto_path=${protobuf_SOURCE_DIR}/src + --cpp_out=${protobuf_SOURCE_DIR}/src ) add_executable(conformance_test_runner - ${protobuf_source_dir}/conformance/binary_json_conformance_suite.cc - ${protobuf_source_dir}/conformance/binary_json_conformance_suite.h - ${protobuf_source_dir}/conformance/conformance.pb.cc - ${protobuf_source_dir}/conformance/conformance_test.cc - ${protobuf_source_dir}/conformance/conformance_test_runner.cc - ${protobuf_source_dir}/conformance/third_party/jsoncpp/json.h - ${protobuf_source_dir}/conformance/third_party/jsoncpp/jsoncpp.cpp - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.pb.cc - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.pb.cc + ${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.cc + ${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.h + ${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc + ${protobuf_SOURCE_DIR}/conformance/conformance_test.cc + ${protobuf_SOURCE_DIR}/conformance/conformance_test_runner.cc + ${protobuf_SOURCE_DIR}/conformance/third_party/jsoncpp/json.h + ${protobuf_SOURCE_DIR}/conformance/third_party/jsoncpp/jsoncpp.cpp + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc ) add_executable(conformance_cpp - ${protobuf_source_dir}/conformance/conformance.pb.cc - ${protobuf_source_dir}/conformance/conformance_cpp.cc - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.pb.cc - ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.pb.cc + ${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc + ${protobuf_SOURCE_DIR}/conformance/conformance_cpp.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc ) target_include_directories( conformance_test_runner - PUBLIC ${protobuf_source_dir}/conformance) + PUBLIC ${protobuf_SOURCE_DIR}/conformance) target_include_directories( conformance_cpp - PUBLIC ${protobuf_source_dir}/conformance) + PUBLIC ${protobuf_SOURCE_DIR}/conformance) target_link_libraries(conformance_test_runner libprotobuf) target_link_libraries(conformance_cpp libprotobuf) diff --git a/third_party/protobuf/cmake/examples.cmake b/third_party/protobuf/cmake/examples.cmake index e5cad63f..3b83d2b4 100644 --- a/third_party/protobuf/cmake/examples.cmake +++ b/third_party/protobuf/cmake/examples.cmake @@ -2,7 +2,7 @@ if(protobuf_VERBOSE) message(STATUS "Protocol Buffers Examples Configuring...") endif() -get_filename_component(examples_dir "../examples" ABSOLUTE) +get_filename_component(examples_dir "${protobuf_SOURCE_DIR}/examples" ABSOLUTE) if(protobuf_VERBOSE) message(STATUS "Protocol Buffers Examples Configuring done") diff --git a/third_party/protobuf/cmake/extract_includes.bat.in b/third_party/protobuf/cmake/extract_includes.bat.in index 605c5f96..12928292 100644 --- a/third_party/protobuf/cmake/extract_includes.bat.in +++ b/third_party/protobuf/cmake/extract_includes.bat.in @@ -5,7 +5,6 @@ mkdir include\google\protobuf\compiler mkdir include\google\protobuf\compiler\cpp mkdir include\google\protobuf\compiler\csharp mkdir include\google\protobuf\compiler\java -mkdir include\google\protobuf\compiler\js mkdir include\google\protobuf\compiler\objectivec mkdir include\google\protobuf\compiler\php mkdir include\google\protobuf\compiler\python @@ -19,27 +18,31 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\goo copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena_impl.h" include\google\protobuf\arena_impl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenaz_sampler.h" include\google\protobuf\arenaz_sampler.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_file.h" include\google\protobuf\compiler\cpp\cpp_file.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\file.h" include\google\protobuf\compiler\cpp\file.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h" include\google\protobuf\compiler\cpp\cpp_generator.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_helpers.h" include\google\protobuf\compiler\cpp\cpp_helpers.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_names.h" include\google\protobuf\compiler\cpp\cpp_names.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\generator.h" include\google\protobuf\compiler\cpp\generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\helpers.h" include\google\protobuf\compiler\cpp\helpers.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\names.h" include\google\protobuf\compiler\cpp\names.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_doc_comment.h" include\google\protobuf\compiler\csharp\csharp_doc_comment.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h" include\google\protobuf\compiler\csharp\csharp_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h" include\google\protobuf\compiler\csharp\csharp_names.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_options.h" include\google\protobuf\compiler\csharp\csharp_options.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" include\google\protobuf\compiler\importer.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\generator.h" include\google\protobuf\compiler\java\generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h" include\google\protobuf\compiler\java\java_generator.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_kotlin_generator.h" include\google\protobuf\compiler\java\java_kotlin_generator.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h" include\google\protobuf\compiler\java\java_names.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h" include\google\protobuf\compiler\js\js_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\kotlin_generator.h" include\google\protobuf\compiler\java\kotlin_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\names.h" include\google\protobuf\compiler\java\names.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h" include\google\protobuf\compiler\objectivec\objectivec_helpers.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" include\google\protobuf\compiler\parser.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\generator.h" include\google\protobuf\compiler\python\generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\pyi_generator.h" include\google\protobuf\compiler\python\pyi_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h @@ -48,6 +51,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\endian.h" include\google\protobuf\endian.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\explicitly_constructed.h" include\google\protobuf\explicitly_constructed.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h @@ -57,11 +61,8 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflec copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_bases.h" include\google\protobuf\generated_message_bases.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven_lite.h" include\google\protobuf\generated_message_table_driven_lite.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_decl.h" include\google\protobuf\generated_message_tctable_decl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.h" include\google\protobuf\generated_message_tctable_impl.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tctable_impl.inc" include\google\protobuf\generated_message_tctable_impl.inc copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h diff --git a/third_party/protobuf/cmake/install.cmake b/third_party/protobuf/cmake/install.cmake index 4e1c5deb..825cb25f 100644 --- a/third_party/protobuf/cmake/install.cmake +++ b/third_party/protobuf/cmake/install.cmake @@ -1,8 +1,8 @@ include(GNUInstallDirs) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protobuf.pc.cmake +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc @ONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protobuf-lite.pc.cmake +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf-lite.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY) set(_protobuf_libraries libprotobuf-lite libprotobuf) @@ -13,7 +13,7 @@ endif (protobuf_BUILD_LIBPROTOC) foreach(_library ${_protobuf_libraries}) set_property(TARGET ${_library} PROPERTY INTERFACE_INCLUDE_DIRECTORIES - $ + $ $) if (UNIX AND NOT APPLE) set_property(TARGET ${_library} @@ -43,15 +43,15 @@ endif (protobuf_BUILD_PROTOC_BINARIES) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") -file(STRINGS extract_includes.bat.in _extract_strings +file(STRINGS ${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in _extract_strings REGEX "^copy") foreach(_extract_string ${_extract_strings}) string(REGEX REPLACE "^.* .+ include\\\\(.+)$" "\\1" _header ${_extract_string}) string(REPLACE "\\" "/" _header ${_header}) - get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/../src/${_header}" ABSOLUTE) + get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/src/${_header}" ABSOLUTE) get_filename_component(_extract_name ${_header} NAME) - get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" PATH) + get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY) if(EXISTS "${_extract_from}") install(FILES "${_extract_from}" DESTINATION "${_extract_to}" @@ -84,19 +84,19 @@ function(_protobuf_auto_list FILE_NAME VARIABLE) endfunction() # Install well-known type proto files -_protobuf_auto_list("../src/Makefile.am" nobase_dist_proto_DATA) +_protobuf_auto_list("${protobuf_SOURCE_DIR}/src/Makefile.am" nobase_dist_proto_DATA) foreach(_file ${nobase_dist_proto_DATA}) - get_filename_component(_file_from "../src/${_file}" ABSOLUTE) + get_filename_component(_file_from "${protobuf_SOURCE_DIR}/src/${_file}" ABSOLUTE) get_filename_component(_file_name ${_file} NAME) - get_filename_component(_file_path ${_file} PATH) + get_filename_component(_dir ${_file} DIRECTORY) if(EXISTS "${_file_from}") install(FILES "${_file_from}" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_file_path}" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_dir}" COMPONENT protobuf-protos RENAME "${_file_name}") else() message(AUTHOR_WARNING "The file \"${_file_from}\" is listed in " - "\"${protobuf_SOURCE_DIR}/../src/Makefile.am\" as nobase_dist_proto_DATA " + "\"${protobuf_SOURCE_DIR}/src/Makefile.am\" as nobase_dist_proto_DATA " "but there not exists. The file will not be installed.") endif() endforeach() @@ -114,13 +114,13 @@ endif() mark_as_advanced(CMAKE_INSTALL_CMAKEDIR) mark_as_advanced(CMAKE_INSTALL_EXAMPLEDIR) -configure_file(protobuf-config.cmake.in +configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config.cmake.in ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config.cmake @ONLY) -configure_file(protobuf-config-version.cmake.in +configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config-version.cmake.in ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config-version.cmake @ONLY) -configure_file(protobuf-module.cmake.in +configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-module.cmake.in ${CMAKE_INSTALL_CMAKEDIR}/protobuf-module.cmake @ONLY) -configure_file(protobuf-options.cmake +configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-options.cmake ${CMAKE_INSTALL_CMAKEDIR}/protobuf-options.cmake @ONLY) # Allows the build directory to be used as a find directory. @@ -150,7 +150,7 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/ option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF) if(protobuf_INSTALL_EXAMPLES) - install(DIRECTORY ../examples/ + install(DIRECTORY examples/ DESTINATION "${CMAKE_INSTALL_EXAMPLEDIR}" COMPONENT protobuf-examples) endif() diff --git a/third_party/protobuf/cmake/libprotobuf-lite.cmake b/third_party/protobuf/cmake/libprotobuf-lite.cmake index f36a7acf..83e97031 100644 --- a/third_party/protobuf/cmake/libprotobuf-lite.cmake +++ b/third_party/protobuf/cmake/libprotobuf-lite.cmake @@ -1,115 +1,118 @@ set(libprotobuf_lite_files - ${protobuf_source_dir}/src/google/protobuf/any_lite.cc - ${protobuf_source_dir}/src/google/protobuf/arena.cc - ${protobuf_source_dir}/src/google/protobuf/arenastring.cc - ${protobuf_source_dir}/src/google/protobuf/extension_set.cc - ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_lite.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_util.cc - ${protobuf_source_dir}/src/google/protobuf/implicit_weak_message.cc - ${protobuf_source_dir}/src/google/protobuf/inlined_string_field.cc - ${protobuf_source_dir}/src/google/protobuf/io/coded_stream.cc - ${protobuf_source_dir}/src/google/protobuf/io/io_win32.cc - ${protobuf_source_dir}/src/google/protobuf/io/strtod.cc - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.cc - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc - ${protobuf_source_dir}/src/google/protobuf/map.cc - ${protobuf_source_dir}/src/google/protobuf/message_lite.cc - ${protobuf_source_dir}/src/google/protobuf/parse_context.cc - ${protobuf_source_dir}/src/google/protobuf/repeated_field.cc - ${protobuf_source_dir}/src/google/protobuf/repeated_ptr_field.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/common.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/status.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/stringprintf.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/structurally_valid.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/strutil.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/time.cc - ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/any_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_enum_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/strtod.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream_impl.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/message_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/statusor.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringpiece.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/time.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.cc ) set(libprotobuf_lite_includes - ${protobuf_source_dir}/src/google/protobuf/any.h - ${protobuf_source_dir}/src/google/protobuf/arena.h - ${protobuf_source_dir}/src/google/protobuf/arena_impl.h - ${protobuf_source_dir}/src/google/protobuf/arenastring.h - ${protobuf_source_dir}/src/google/protobuf/explicitly_constructed.h - ${protobuf_source_dir}/src/google/protobuf/extension_set.h - ${protobuf_source_dir}/src/google/protobuf/extension_set_inl.h - ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_decl.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_impl.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_impl.inc - ${protobuf_source_dir}/src/google/protobuf/generated_message_util.h - ${protobuf_source_dir}/src/google/protobuf/has_bits.h - ${protobuf_source_dir}/src/google/protobuf/implicit_weak_message.h - ${protobuf_source_dir}/src/google/protobuf/inlined_string_field.h - ${protobuf_source_dir}/src/google/protobuf/io/coded_stream.h - ${protobuf_source_dir}/src/google/protobuf/io/io_win32.h - ${protobuf_source_dir}/src/google/protobuf/io/strtod.h - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.h - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.h - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.h - ${protobuf_source_dir}/src/google/protobuf/map.h - ${protobuf_source_dir}/src/google/protobuf/map_entry_lite.h - ${protobuf_source_dir}/src/google/protobuf/map_field_lite.h - ${protobuf_source_dir}/src/google/protobuf/map_type_handler.h - ${protobuf_source_dir}/src/google/protobuf/message_lite.h - ${protobuf_source_dir}/src/google/protobuf/metadata_lite.h - ${protobuf_source_dir}/src/google/protobuf/parse_context.h - ${protobuf_source_dir}/src/google/protobuf/port.h - ${protobuf_source_dir}/src/google/protobuf/repeated_field.h - ${protobuf_source_dir}/src/google/protobuf/repeated_ptr_field.h - ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.h - ${protobuf_source_dir}/src/google/protobuf/stubs/callback.h - ${protobuf_source_dir}/src/google/protobuf/stubs/casts.h - ${protobuf_source_dir}/src/google/protobuf/stubs/common.h - ${protobuf_source_dir}/src/google/protobuf/stubs/hash.h - ${protobuf_source_dir}/src/google/protobuf/stubs/logging.h - ${protobuf_source_dir}/src/google/protobuf/stubs/macros.h - ${protobuf_source_dir}/src/google/protobuf/stubs/map_util.h - ${protobuf_source_dir}/src/google/protobuf/stubs/mutex.h - ${protobuf_source_dir}/src/google/protobuf/stubs/once.h - ${protobuf_source_dir}/src/google/protobuf/stubs/platform_macros.h - ${protobuf_source_dir}/src/google/protobuf/stubs/port.h - ${protobuf_source_dir}/src/google/protobuf/stubs/status.h - ${protobuf_source_dir}/src/google/protobuf/stubs/stl_util.h - ${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.h - ${protobuf_source_dir}/src/google/protobuf/stubs/strutil.h - ${protobuf_source_dir}/src/google/protobuf/stubs/template_util.h - ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/any.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/endian.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/explicitly_constructed.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set_inl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_enum_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_decl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_impl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/has_bits.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/implicit_weak_message.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/strtod.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream_impl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream_impl_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_entry_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_field_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_type_handler.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/message_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/metadata_lite.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/port.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/casts.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/hash.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/macros.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/map_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/mutex.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/once.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stl_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringpiece.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/template_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_lite.h ) -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") -set(libprotobuf_lite_rc_files - ${CMAKE_CURRENT_BINARY_DIR}/version.rc -) -endif() - add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC} - ${libprotobuf_lite_files} ${libprotobuf_lite_includes} ${libprotobuf_lite_rc_files}) -target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) + ${libprotobuf_lite_files} ${libprotobuf_lite_includes} ${protobuf_version_rc_file}) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map) + endif() + set_target_properties(libprotobuf-lite PROPERTIES + LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map) +endif() +target_link_libraries(libprotobuf-lite PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_LINK_LIBATOMIC) - target_link_libraries(libprotobuf-lite atomic) + target_link_libraries(libprotobuf-lite PRIVATE atomic) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") - target_link_libraries(libprotobuf-lite log) + target_link_libraries(libprotobuf-lite PRIVATE log) endif() -target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) +target_include_directories(libprotobuf-lite PUBLIC ${protobuf_SOURCE_DIR}/src) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf-lite PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOBUF_EXPORTS) endif() set_target_properties(libprotobuf-lite PROPERTIES VERSION ${protobuf_VERSION} + SOVERSION 32 OUTPUT_NAME ${LIB_PREFIX}protobuf-lite DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite) diff --git a/third_party/protobuf/cmake/libprotobuf.cmake b/third_party/protobuf/cmake/libprotobuf.cmake index 668b8c27..07e4bcf5 100644 --- a/third_party/protobuf/cmake/libprotobuf.cmake +++ b/third_party/protobuf/cmake/libprotobuf.cmake @@ -1,130 +1,134 @@ set(libprotobuf_files - ${protobuf_source_dir}/src/google/protobuf/any.cc - ${protobuf_source_dir}/src/google/protobuf/any.pb.cc - ${protobuf_source_dir}/src/google/protobuf/api.pb.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/importer.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/parser.cc - ${protobuf_source_dir}/src/google/protobuf/descriptor.cc - ${protobuf_source_dir}/src/google/protobuf/descriptor.pb.cc - ${protobuf_source_dir}/src/google/protobuf/descriptor_database.cc - ${protobuf_source_dir}/src/google/protobuf/duration.pb.cc - ${protobuf_source_dir}/src/google/protobuf/dynamic_message.cc - ${protobuf_source_dir}/src/google/protobuf/empty.pb.cc - ${protobuf_source_dir}/src/google/protobuf/extension_set_heavy.cc - ${protobuf_source_dir}/src/google/protobuf/field_mask.pb.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_bases.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_tctable_full.cc - ${protobuf_source_dir}/src/google/protobuf/io/gzip_stream.cc - ${protobuf_source_dir}/src/google/protobuf/io/printer.cc - ${protobuf_source_dir}/src/google/protobuf/io/tokenizer.cc - ${protobuf_source_dir}/src/google/protobuf/map_field.cc - ${protobuf_source_dir}/src/google/protobuf/message.cc - ${protobuf_source_dir}/src/google/protobuf/reflection_ops.cc - ${protobuf_source_dir}/src/google/protobuf/service.cc - ${protobuf_source_dir}/src/google/protobuf/source_context.pb.cc - ${protobuf_source_dir}/src/google/protobuf/struct.pb.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/substitute.cc - ${protobuf_source_dir}/src/google/protobuf/text_format.cc - ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.cc - ${protobuf_source_dir}/src/google/protobuf/type.pb.cc - ${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc - ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.cc - ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc - ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/error_listener.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/field_mask_utility.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/json_escaping.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/object_writer.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/proto_writer.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/utility.cc - ${protobuf_source_dir}/src/google/protobuf/util/json_util.cc - ${protobuf_source_dir}/src/google/protobuf/util/message_differencer.cc - ${protobuf_source_dir}/src/google/protobuf/util/time_util.cc - ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.cc - ${protobuf_source_dir}/src/google/protobuf/wire_format.cc - ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/any.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/any.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/dynamic_message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set_heavy.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_bases.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_reflection.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_full.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_ops.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/service.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/substitute.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/type.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_comparator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_mask_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/datapiece.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/default_value_objectwriter.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/error_listener.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/field_mask_utility.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/json_escaping.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/json_objectwriter.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/json_stream_parser.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/object_writer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/proto_writer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/protostream_objectsource.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/protostream_objectwriter.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/type_info.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/utility.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/json_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/message_differencer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/time_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/type_resolver_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.pb.cc ) set(libprotobuf_includes - ${protobuf_source_dir}/src/google/protobuf/any.pb.h - ${protobuf_source_dir}/src/google/protobuf/api.pb.h - ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h - ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h - ${protobuf_source_dir}/src/google/protobuf/descriptor.h - ${protobuf_source_dir}/src/google/protobuf/descriptor.pb.h - ${protobuf_source_dir}/src/google/protobuf/descriptor_database.h - ${protobuf_source_dir}/src/google/protobuf/duration.pb.h - ${protobuf_source_dir}/src/google/protobuf/dynamic_message.h - ${protobuf_source_dir}/src/google/protobuf/empty.pb.h - ${protobuf_source_dir}/src/google/protobuf/field_access_listener.h - ${protobuf_source_dir}/src/google/protobuf/field_mask.pb.h - ${protobuf_source_dir}/src/google/protobuf/generated_enum_reflection.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_bases.h - ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection.h - ${protobuf_source_dir}/src/google/protobuf/io/gzip_stream.h - ${protobuf_source_dir}/src/google/protobuf/io/printer.h - ${protobuf_source_dir}/src/google/protobuf/io/tokenizer.h - ${protobuf_source_dir}/src/google/protobuf/map_entry.h - ${protobuf_source_dir}/src/google/protobuf/map_field.h - ${protobuf_source_dir}/src/google/protobuf/map_field_inl.h - ${protobuf_source_dir}/src/google/protobuf/message.h - ${protobuf_source_dir}/src/google/protobuf/metadata.h - ${protobuf_source_dir}/src/google/protobuf/reflection.h - ${protobuf_source_dir}/src/google/protobuf/reflection_ops.h - ${protobuf_source_dir}/src/google/protobuf/service.h - ${protobuf_source_dir}/src/google/protobuf/source_context.pb.h - ${protobuf_source_dir}/src/google/protobuf/struct.pb.h - ${protobuf_source_dir}/src/google/protobuf/text_format.h - ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.h - ${protobuf_source_dir}/src/google/protobuf/type.pb.h - ${protobuf_source_dir}/src/google/protobuf/unknown_field_set.h - ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.h - ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.h - ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.h - ${protobuf_source_dir}/src/google/protobuf/util/json_util.h - ${protobuf_source_dir}/src/google/protobuf/util/message_differencer.h - ${protobuf_source_dir}/src/google/protobuf/util/time_util.h - ${protobuf_source_dir}/src/google/protobuf/util/type_resolver.h - ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.h - ${protobuf_source_dir}/src/google/protobuf/wire_format.h - ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/any.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/dynamic_message.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/field_access_listener.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_enum_reflection.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_bases.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_reflection.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/gzip_stream.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_entry.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_field.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_field_inl.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/message.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/metadata.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_internal.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_ops.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/service.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/type.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_comparator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_mask_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/json_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/message_differencer.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/time_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/type_resolver.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/type_resolver_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.pb.h ) -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") -set(libprotobuf_rc_files - ${CMAKE_CURRENT_BINARY_DIR}/version.rc -) -endif() - add_library(libprotobuf ${protobuf_SHARED_OR_STATIC} - ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes} ${libprotobuf_rc_files}) -target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT}) + ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes} ${protobuf_version_rc_file}) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map) + endif() + set_target_properties(libprotobuf PROPERTIES + LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf.map) +endif() +target_link_libraries(libprotobuf PRIVATE ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_WITH_ZLIB) - target_link_libraries(libprotobuf ${ZLIB_LIBRARIES}) + target_link_libraries(libprotobuf PRIVATE ${ZLIB_LIBRARIES}) endif() if(protobuf_LINK_LIBATOMIC) - target_link_libraries(libprotobuf atomic) + target_link_libraries(libprotobuf PRIVATE atomic) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") - target_link_libraries(libprotobuf log) + target_link_libraries(libprotobuf PRIVATE log) endif() -target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) +target_include_directories(libprotobuf PUBLIC ${protobuf_SOURCE_DIR}/src) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOBUF_EXPORTS) endif() set_target_properties(libprotobuf PROPERTIES VERSION ${protobuf_VERSION} + SOVERSION 32 OUTPUT_NAME ${LIB_PREFIX}protobuf DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotobuf ALIAS libprotobuf) diff --git a/third_party/protobuf/cmake/libprotoc.cmake b/third_party/protobuf/cmake/libprotoc.cmake index 6f043316..15a47e53 100644 --- a/third_party/protobuf/cmake/libprotoc.cmake +++ b/third_party/protobuf/cmake/libprotoc.cmake @@ -1,125 +1,128 @@ set(libprotoc_files - ${protobuf_source_dir}/src/google/protobuf/compiler/code_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_enum.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_enum_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_extension.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_file.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_helpers.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_map_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_service.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_string_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_field_base.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_helpers.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_map_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_context.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_kotlin_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_builder.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_builder_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_field_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_name_resolver.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_primitive_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_primitive_field_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_service.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_shared_code_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_string_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_string_field_lite.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types_embed.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_file.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/extension.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/map_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/padding_optimizer.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/parse_function_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/primitive_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/service.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/string_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_enum.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_enum_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_field_base.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_map_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/context.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_field_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/enum_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/extension.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/extension_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/file.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator_factory.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/map_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/map_field_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_builder.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_builder_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_field_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/name_resolver.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/primitive_field_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/service.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/shared_code_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_file.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/zip_writer.cc ) set(libprotoc_headers - ${protobuf_source_dir}/src/google/protobuf/compiler/code_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface.h - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_file.h - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_helpers.h - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_names.h - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_doc_comment.h - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_names.h - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_options.h - ${protobuf_source_dir}/src/google/protobuf/compiler/importer.h - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_kotlin_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_names.h - ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h - ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h - ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.h - ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.h - ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.h - ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/cpp_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/file.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/helpers.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/names.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_doc_comment.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_names.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_options.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/python_generator.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.h ) -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") -set(libprotoc_rc_files - ${CMAKE_CURRENT_BINARY_DIR}/version.rc -) -endif() - add_library(libprotoc ${protobuf_SHARED_OR_STATIC} - ${libprotoc_files} ${libprotoc_headers} ${libprotoc_rc_files}) -target_link_libraries(libprotoc libprotobuf) -if(MSVC AND protobuf_BUILD_SHARED_LIBS) + ${libprotoc_files} ${libprotoc_headers} ${protobuf_version_rc_file}) +if(protobuf_HAVE_LD_VERSION_SCRIPT) + if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13) + target_link_options(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map) + elseif(protobuf_BUILD_SHARED_LIBS) + target_link_libraries(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map) + endif() + set_target_properties(libprotoc PROPERTIES + LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotoc.map) +endif() +target_link_libraries(libprotoc PRIVATE libprotobuf) +if(protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotoc PUBLIC PROTOBUF_USE_DLLS PRIVATE LIBPROTOC_EXPORTS) @@ -127,6 +130,7 @@ endif() set_target_properties(libprotoc PROPERTIES COMPILE_DEFINITIONS LIBPROTOC_EXPORTS VERSION ${protobuf_VERSION} + SOVERSION 32 OUTPUT_NAME ${LIB_PREFIX}protoc DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}") add_library(protobuf::libprotoc ALIAS libprotoc) diff --git a/third_party/protobuf/cmake/protobuf-config.cmake.in b/third_party/protobuf/cmake/protobuf-config.cmake.in index 9197625d..61669118 100644 --- a/third_party/protobuf/cmake/protobuf-config.cmake.in +++ b/third_party/protobuf/cmake/protobuf-config.cmake.in @@ -11,7 +11,7 @@ function(protobuf_generate) include(CMakeParseArguments) set(_options APPEND_PATH) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -39,9 +39,18 @@ function(protobuf_generate) endif() if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) - set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") + set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}") endif() - + + foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS}) + # append comma - not using CMake lists and string replacement as users + # might have semicolons in options + if(_plugin_options) + set( _plugin_options "${_plugin_options},") + endif() + set(_plugin_options "${_plugin_options}${_option}") + endforeach() + if(protobuf_generate_PLUGIN) set(_plugin "--plugin=${protobuf_generate_PLUGIN}") endif() @@ -75,10 +84,10 @@ function(protobuf_generate) # Create an include path for each file specified foreach(_file ${protobuf_generate_PROTOS}) get_filename_component(_abs_file ${_file} ABSOLUTE) - get_filename_component(_abs_path ${_abs_file} PATH) - list(FIND _protobuf_include_path ${_abs_path} _contains_already) + get_filename_component(_abs_dir ${_abs_file} DIRECTORY) + list(FIND _protobuf_include_path ${_abs_dir} _contains_already) if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${_abs_path}) + list(APPEND _protobuf_include_path -I ${_abs_dir}) endif() endforeach() endif() @@ -127,12 +136,20 @@ function(protobuf_generate) endforeach() list(APPEND _generated_srcs_all ${_generated_srcs}) + set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}") + if(protobuf_generate_PROTOC_OPTIONS) + set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}") + endif() + if(_plugin_options) + set(_comment "${_comment}, plugin-options: ${_plugin_options}") + endif() + add_custom_command( OUTPUT ${_generated_srcs} - COMMAND protobuf::protoc - ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} + COMMAND protobuf::protoc + ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc - COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}. Custom options: ${protobuf_generate_PROTOC_OPTIONS}" + COMMENT ${_comment} VERBATIM ) endforeach() diff --git a/third_party/protobuf/cmake/protobuf-module.cmake.in b/third_party/protobuf/cmake/protobuf-module.cmake.in index 09b9d29c..0bb05e38 100644 --- a/third_party/protobuf/cmake/protobuf-module.cmake.in +++ b/third_party/protobuf/cmake/protobuf-module.cmake.in @@ -94,7 +94,7 @@ function(_protobuf_find_libraries name filename) elseif(${name}_LIBRARY) # Honor cache entry used by CMake 3.5 and lower. set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE) - else() + elseif(TARGET protobuf::lib${filename}) get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename} LOCATION_RELEASE) get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename} @@ -134,23 +134,25 @@ get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) # Set the protoc Executable -get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_RELEASE) -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") +if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc) get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_RELWITHDEBINFO) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_MINSIZEREL) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_DEBUG) -endif() -if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") - get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc - IMPORTED_LOCATION_NOCONFIG) + IMPORTED_LOCATION_RELEASE) + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_RELWITHDEBINFO) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_MINSIZEREL) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_DEBUG) + endif() + if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_NOCONFIG) + endif() endif() # Version info variable diff --git a/third_party/protobuf/cmake/protoc.cmake b/third_party/protobuf/cmake/protoc.cmake index c86d6628..472b6421 100644 --- a/third_party/protobuf/cmake/protoc.cmake +++ b/third_party/protobuf/cmake/protoc.cmake @@ -1,15 +1,12 @@ set(protoc_files - ${protobuf_source_dir}/src/google/protobuf/compiler/main.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/main.cc ) -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") -set(protoc_rc_files - ${CMAKE_CURRENT_BINARY_DIR}/version.rc +add_executable(protoc ${protoc_files} ${protobuf_version_rc_file}) +target_link_libraries(protoc + libprotoc + libprotobuf ) -endif() - -add_executable(protoc ${protoc_files} ${protoc_rc_files}) -target_link_libraries(protoc libprotoc libprotobuf) add_executable(protobuf::protoc ALIAS protoc) set_target_properties(protoc PROPERTIES diff --git a/third_party/protobuf/cmake/tests.cmake b/third_party/protobuf/cmake/tests.cmake index 52968585..1905673b 100644 --- a/third_party/protobuf/cmake/tests.cmake +++ b/third_party/protobuf/cmake/tests.cmake @@ -1,96 +1,107 @@ -if (NOT EXISTS "${PROJECT_SOURCE_DIR}/../third_party/googletest/CMakeLists.txt") - message(FATAL_ERROR - "Cannot find third_party/googletest directory that's needed to " - "build tests. If you use git, make sure you have cloned submodules:\n" - " git submodule update --init --recursive\n" - "If instead you want to skip tests, run cmake with:\n" - " cmake -Dprotobuf_BUILD_TESTS=OFF\n") -endif() +option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF) + +option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "") option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH "Using absolute test_plugin path in tests" ON) mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH) -set(googlemock_source_dir "${protobuf_source_dir}/third_party/googletest/googlemock") -set(googletest_source_dir "${protobuf_source_dir}/third_party/googletest/googletest") -include_directories( - ${googlemock_source_dir} - ${googletest_source_dir} - ${googletest_source_dir}/include - ${googlemock_source_dir}/include -) +if (protobuf_USE_EXTERNAL_GTEST) + find_package(GTest REQUIRED) +else() + if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/googletest/CMakeLists.txt") + message(FATAL_ERROR + "Cannot find third_party/googletest directory that's needed to " + "build tests. If you use git, make sure you have cloned submodules:\n" + " git submodule update --init --recursive\n" + "If instead you want to skip tests, run cmake with:\n" + " cmake -Dprotobuf_BUILD_TESTS=OFF\n") + endif() -add_library(gmock STATIC - "${googlemock_source_dir}/src/gmock-all.cc" - "${googletest_source_dir}/src/gtest-all.cc" -) -target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) -add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc") -target_link_libraries(gmock_main gmock) + set(googlemock_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googlemock") + set(googletest_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googletest") + include_directories( + ${googlemock_source_dir} + ${googletest_source_dir} + ${googletest_source_dir}/include + ${googlemock_source_dir}/include + ) + + add_library(gmock STATIC + "${googlemock_source_dir}/src/gmock-all.cc" + "${googletest_source_dir}/src/gtest-all.cc" + ) + target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) + add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc") + target_link_libraries(gmock_main gmock) + + add_library(GTest::gmock ALIAS gmock) + add_library(GTest::gmock_main ALIAS gmock_main) +endif() set(lite_test_protos - google/protobuf/map_lite_unittest.proto - google/protobuf/unittest_import_lite.proto - google/protobuf/unittest_import_public_lite.proto - google/protobuf/unittest_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_lite_unittest.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_import_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_import_public_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_lite.proto ) set(tests_protos - google/protobuf/any_test.proto - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto - google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto - google/protobuf/map_proto2_unittest.proto - google/protobuf/map_unittest.proto - google/protobuf/unittest.proto - google/protobuf/unittest_arena.proto - google/protobuf/unittest_custom_options.proto - google/protobuf/unittest_drop_unknown_fields.proto - google/protobuf/unittest_embed_optimize_for.proto - google/protobuf/unittest_empty.proto - google/protobuf/unittest_import.proto - google/protobuf/unittest_import_public.proto - google/protobuf/unittest_lazy_dependencies.proto - google/protobuf/unittest_lazy_dependencies_custom_option.proto - google/protobuf/unittest_lazy_dependencies_enum.proto - google/protobuf/unittest_lite_imports_nonlite.proto - google/protobuf/unittest_mset.proto - google/protobuf/unittest_mset_wire_format.proto - google/protobuf/unittest_no_field_presence.proto - google/protobuf/unittest_no_generic_services.proto - google/protobuf/unittest_optimize_for.proto - google/protobuf/unittest_preserve_unknown_enum.proto - google/protobuf/unittest_preserve_unknown_enum2.proto - google/protobuf/unittest_proto3.proto - google/protobuf/unittest_proto3_arena.proto - google/protobuf/unittest_proto3_arena_lite.proto - google/protobuf/unittest_proto3_lite.proto - google/protobuf/unittest_proto3_optional.proto - google/protobuf/unittest_well_known_types.proto - google/protobuf/util/internal/testdata/anys.proto - google/protobuf/util/internal/testdata/books.proto - google/protobuf/util/internal/testdata/default_value.proto - google/protobuf/util/internal/testdata/default_value_test.proto - google/protobuf/util/internal/testdata/field_mask.proto - google/protobuf/util/internal/testdata/maps.proto - google/protobuf/util/internal/testdata/oneofs.proto - google/protobuf/util/internal/testdata/proto3.proto - google/protobuf/util/internal/testdata/struct.proto - google/protobuf/util/internal/testdata/timestamp_duration.proto - google/protobuf/util/internal/testdata/wrappers.proto - google/protobuf/util/json_format.proto - google/protobuf/util/json_format_proto3.proto - google/protobuf/util/message_differencer_unittest.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/any_test.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/test_bad_identifiers.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/test_large_enum_value.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_proto2_unittest.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_unittest.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_arena.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_custom_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_drop_unknown_fields.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_embed_optimize_for.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_empty.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_enormous_descriptor.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_import.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_import_public.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_lazy_dependencies.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_lazy_dependencies_enum.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_lite_imports_nonlite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_mset.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_mset_wire_format.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_no_field_presence.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_no_generic_services.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_optimize_for.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_preserve_unknown_enum.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_preserve_unknown_enum2.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_arena.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_arena_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_optional.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_well_known_types.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/anys.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/books.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/default_value.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/default_value_test.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/field_mask.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/maps.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/oneofs.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/struct.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/timestamp_duration.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/testdata/wrappers.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/json_format.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/json_format_proto3.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/message_differencer_unittest.proto ) macro(compile_proto_file filename) - get_filename_component(dirname ${filename} PATH) - get_filename_component(basename ${filename} NAME_WE) + string(REPLACE .proto .pb.cc pb_file ${filename}) add_custom_command( - OUTPUT ${protobuf_source_dir}/src/${dirname}/${basename}.pb.cc - DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/${dirname}/${basename}.proto - COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/${dirname}/${basename}.proto - --proto_path=${protobuf_source_dir}/src - --cpp_out=${protobuf_source_dir}/src + OUTPUT ${pb_file} + DEPENDS ${protobuf_PROTOC_EXE} ${filename} + COMMAND ${protobuf_PROTOC_EXE} ${filename} + --proto_path=${protobuf_SOURCE_DIR}/src + --cpp_out=${protobuf_SOURCE_DIR}/src --experimental_allow_proto3_optional ) endmacro(compile_proto_file) @@ -98,112 +109,119 @@ endmacro(compile_proto_file) set(lite_test_proto_files) foreach(proto_file ${lite_test_protos}) compile_proto_file(${proto_file}) - string(REPLACE .proto .pb.cc pb_file ${proto_file}) - set(lite_test_proto_files ${lite_test_proto_files} - ${protobuf_source_dir}/src/${pb_file}) + set(lite_test_proto_files ${lite_test_proto_files} ${pb_file}) endforeach(proto_file) set(tests_proto_files) foreach(proto_file ${tests_protos}) compile_proto_file(${proto_file}) - string(REPLACE .proto .pb.cc pb_file ${proto_file}) - set(tests_proto_files ${tests_proto_files} - ${protobuf_source_dir}/src/${pb_file}) + set(tests_proto_files ${tests_proto_files} ${pb_file}) endforeach(proto_file) set(common_lite_test_files - ${protobuf_source_dir}/src/google/protobuf/arena_test_util.cc - ${protobuf_source_dir}/src/google/protobuf/map_lite_test_util.cc - ${protobuf_source_dir}/src/google/protobuf/test_util_lite.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_test_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_lite_test_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_util_lite.cc ) +add_library(protobuf-lite-test-common STATIC + ${common_lite_test_files} ${lite_test_proto_files}) +target_link_libraries(protobuf-lite-test-common libprotobuf-lite GTest::gmock) + set(common_test_files ${common_lite_test_files} - ${protobuf_source_dir}/src/google/protobuf/map_test_util.inc - ${protobuf_source_dir}/src/google/protobuf/reflection_tester.cc - ${protobuf_source_dir}/src/google/protobuf/test_util.cc - ${protobuf_source_dir}/src/google/protobuf/test_util.inc - ${protobuf_source_dir}/src/google/protobuf/testing/file.cc - ${protobuf_source_dir}/src/google/protobuf/testing/googletest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/mock_code_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_test_util.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_tester.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/testing/file.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/testing/googletest.cc ) +add_library(protobuf-test-common STATIC + ${common_test_files} ${tests_proto_files}) +target_link_libraries(protobuf-test-common libprotobuf GTest::gmock) + set(tests_files - ${protobuf_source_dir}/src/google/protobuf/any_test.cc - ${protobuf_source_dir}/src/google/protobuf/arena_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/arenastring_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/annotation_test_util.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.inc - ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_plugin_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/parser_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_plugin_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/descriptor_database_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/descriptor_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/drop_unknown_fields_test.cc - ${protobuf_source_dir}/src/google/protobuf/dynamic_message_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/extension_set_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/inlined_string_field_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/io/coded_stream_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/io/io_win32_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/io/printer_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/io/tokenizer_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/map_field_test.cc - ${protobuf_source_dir}/src/google/protobuf/map_test.cc - ${protobuf_source_dir}/src/google/protobuf/map_test.inc - ${protobuf_source_dir}/src/google/protobuf/message_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/message_unittest.inc - ${protobuf_source_dir}/src/google/protobuf/no_field_presence_test.cc - ${protobuf_source_dir}/src/google/protobuf/preserve_unknown_enum_test.cc - ${protobuf_source_dir}/src/google/protobuf/proto3_arena_lite_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/proto3_arena_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.inc - ${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/stringprintf_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/structurally_valid_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/strutil_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/template_util_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/time_test.cc - ${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc - ${protobuf_source_dir}/src/google/protobuf/util/json_util_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/message_differencer_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/util/time_util_test.cc - ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc - ${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/any_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/message_size_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/metadata_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/move_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/plugin_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/unittest.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/doc_comment_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/plugin_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/plugin_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/drop_unknown_fields_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/dynamic_message_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_reflection_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/generated_message_tctable_lite_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/inlined_string_field_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_stream_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_field_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/map_test.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/message_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/message_unittest.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/no_field_presence_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/preserve_unknown_enum_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/proto3_arena_lite_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/proto3_arena_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/proto3_lite_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/proto3_lite_unittest.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_ops_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field_reflection_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_field_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/status_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/statusor_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringpiece_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/template_util_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/time_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/delimited_message_util_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_comparator_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/field_mask_util_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/json_objectwriter_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/json_stream_parser_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/protostream_objectsource_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/internal/type_info_test_helper.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/json_util_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/message_differencer_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/time_util_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/util/type_resolver_util_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/well_known_types_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.inc ) if(protobuf_ABSOLUTE_TEST_PLUGIN_PATH) @@ -221,32 +239,56 @@ if(MINGW) endif() -add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files}) -target_link_libraries(tests libprotoc libprotobuf gmock_main) +if(protobuf_TEST_XML_OUTDIR) + if(NOT "${protobuf_TEST_XML_OUTDIR}" MATCHES "[/\\]$") + string(APPEND protobuf_TEST_XML_OUTDIR "/") + endif() + set(protobuf_GTEST_ARGS "--gtest_output=xml:${protobuf_TEST_XML_OUTDIR}") +else() + set(protobuf_GTEST_ARGS) +endif() + +add_executable(tests ${tests_files}) +if (MSVC) + target_compile_options(tests PRIVATE + /wd4146 # unary minus operator applied to unsigned type, result still unsigned + ) +endif() +target_link_libraries(tests protobuf-lite-test-common protobuf-test-common libprotoc libprotobuf GTest::gmock_main) set(test_plugin_files - ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/test_plugin.cc - ${protobuf_source_dir}/src/google/protobuf/testing/file.cc - ${protobuf_source_dir}/src/google/protobuf/testing/file.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/mock_code_generator.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/test_plugin.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/testing/file.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/testing/file.h ) add_executable(test_plugin ${test_plugin_files}) -target_link_libraries(test_plugin libprotoc libprotobuf gmock) +target_link_libraries(test_plugin libprotoc libprotobuf GTest::gmock) set(lite_test_files - ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/lite_unittest.cc ) -add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files}) -target_link_libraries(lite-test libprotobuf-lite gmock_main) +add_executable(lite-test ${lite_test_files}) +target_link_libraries(lite-test protobuf-lite-test-common libprotobuf-lite GTest::gmock_main) + +add_test(NAME lite-test + COMMAND lite-test ${protobuf_GTEST_ARGS}) set(lite_arena_test_files - ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/lite_arena_unittest.cc ) -add_executable(lite-arena-test ${lite_arena_test_files} ${common_lite_test_files} ${lite_test_proto_files}) -target_link_libraries(lite-arena-test libprotobuf-lite gmock_main) +add_executable(lite-arena-test ${lite_arena_test_files}) +target_link_libraries(lite-arena-test protobuf-lite-test-common libprotobuf-lite GTest::gmock_main) + +add_test(NAME lite-arena-test + COMMAND lite-arena-test ${protobuf_GTEST_ARGS}) add_custom_target(check COMMAND tests DEPENDS tests test_plugin - WORKING_DIRECTORY ${protobuf_source_dir}) + WORKING_DIRECTORY ${protobuf_SOURCE_DIR}) + +add_test(NAME check + COMMAND tests ${protobuf_GTEST_ARGS} + WORKING_DIRECTORY "${protobuf_SOURCE_DIR}") diff --git a/third_party/protobuf/config.guess b/third_party/protobuf/config.guess index f50dcdb6..7f76b622 100755 --- a/third_party/protobuf/config.guess +++ b/third_party/protobuf/config.guess @@ -1,12 +1,14 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2022 Free Software Foundation, Inc. -timestamp='2018-02-24' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-09' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -27,11 +29,19 @@ timestamp='2018-02-24' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ @@ -50,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,7 +94,8 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 +# Just in case it came from the environment. +GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires @@ -96,73 +107,90 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > "$dummy.c" ; - for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "$UNAME_SYSTEM" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -174,12 +202,12 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; @@ -188,18 +216,18 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` - machine="${arch}${endian}"-unknown + machine=${arch}${endian}-unknown ;; - *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -215,7 +243,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ;; esac # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` @@ -226,7 +254,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; @@ -237,45 +265,57 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi}" - exit ;; + GUESS=$machine-${os}${release}${abi-} + ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; *:MidnightBSD:*:*) - echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; *:ekkoBSD:*:*) - echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; *:SolidBSD:*:*) - echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; *:MirBSD:*:*) - echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; *:Sortix:*:*) - echo "$UNAME_MACHINE"-unknown-sortix - exit ;; + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; *:Redox:*:*) - echo "$UNAME_MACHINE"-unknown-redox - exit ;; + GUESS=$UNAME_MACHINE-unknown-redox + ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + GUESS=mips-dec-osf1 + ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -289,7 +329,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") @@ -326,117 +366,121 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; + GUESS=m68k-unknown-sysv4 + ;; *:[Aa]miga[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-amigaos - exit ;; + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; *:[Mm]orph[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-morphos - exit ;; + GUESS=$UNAME_MACHINE-unknown-morphos + ;; *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; + GUESS=i370-ibm-openedition + ;; *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; + GUESS=s390-ibm-zvmoe + ;; *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; + GUESS=powerpc-ibm-os400 + ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix"$UNAME_RELEASE" - exit ;; + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; + GUESS=arm-unknown-riscos + ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; + GUESS=hppa1.1-hitachi-hiuxmpp + ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; + GUESS=pyramid-pyramid-svr4 + ;; DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; + GUESS=sparc-icl-nx6 + ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux"$UNAME_RELEASE" - exit ;; + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos"$UNAME_RELEASE" - exit ;; + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + case `/bin/arch` in sun3) - echo m68k-sun-sunos"$UNAME_RELEASE" + GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) - echo sparc-sun-sunos"$UNAME_RELEASE" + GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac - exit ;; + ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos"$UNAME_RELEASE" - exit ;; + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -446,43 +490,43 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; m68k:machten:*:*) - echo m68k-apple-machten"$UNAME_RELEASE" - exit ;; + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; powerpc:machten:*:*) - echo powerpc-apple-machten"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; + GUESS=mips-dec-mach_bsd4.3 + ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix"$UNAME_RELEASE" - exit ;; + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix"$UNAME_RELEASE" - exit ;; + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix"$UNAME_RELEASE" - exit ;; + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -508,78 +552,79 @@ EOF dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos"$UNAME_RELEASE" - exit ;; + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; + GUESS=powerpc-motorola-powermax + ;; Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; + GUESS=powerpc-harris-powerunix + ;; m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; + GUESS=m88k-harris-cxux7 + ;; m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; + GUESS=m88k-motorola-sysv4 + ;; m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux"$UNAME_RELEASE" + GUESS=m88k-dg-dgux$UNAME_RELEASE else - echo m88k-dg-dguxbcs"$UNAME_RELEASE" + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else - echo i586-dg-dgux"$UNAME_RELEASE" + GUESS=i586-dg-dgux$UNAME_RELEASE fi - exit ;; + ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; + GUESS=m88k-dolphin-sysv3 + ;; M88*:*:R3*:*) # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; + GUESS=m88k-tektronix-sysv3 + ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; + GUESS=m68k-tektronix-bsd + ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" - exit ;; + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; + GUESS=i386-ibm-aix + ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then + if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" - exit ;; + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -593,16 +638,16 @@ EOF EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then - echo "$SYSTEM_NAME" + GUESS=$SYSTEM_NAME else - echo rs6000-ibm-aix3.2.5 + GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 + GUESS=rs6000-ibm-aix3.2.4 else - echo rs6000-ibm-aix3.2 + GUESS=rs6000-ibm-aix3.2 fi - exit ;; + ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then @@ -610,57 +655,57 @@ EOF else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo "$IBM_ARCH"-ibm-aix"$IBM_REV" - exit ;; + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; + GUESS=rs6000-ibm-aix + ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) - echo romp-ibm-bsd4.4 - exit ;; + GUESS=romp-ibm-bsd4.4 + ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; + GUESS=rs6000-bull-bosx + ;; DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; + GUESS=m68k-bull-sysv3 + ;; 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; + GUESS=m68k-hp-bsd + ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; + GUESS=m68k-hp-bsd4.4 + ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - case "$UNAME_MACHINE" in + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then + if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "$sc_cpu_version" in + case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in + case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + if test "$HP_ARCH" = ""; then + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -698,9 +743,9 @@ EOF test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -719,14 +764,14 @@ EOF HP_ARCH=hppa64 fi fi - echo "$HP_ARCH"-hp-hpux"$HPUX_REV" - exit ;; + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux"$HPUX_REV" - exit ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -754,36 +799,36 @@ EOF EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; + GUESS=unknown-hitachi-hiuxwe2 + ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) - echo hppa1.1-hp-bsd - exit ;; + GUESS=hppa1.1-hp-bsd + ;; 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; + GUESS=hppa1.0-hp-bsd + ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; + GUESS=hppa1.0-hp-mpeix + ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - echo hppa1.1-hp-osf - exit ;; + GUESS=hppa1.1-hp-osf + ;; hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; + GUESS=hppa1.0-hp-osf + ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo "$UNAME_MACHINE"-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk else - echo "$UNAME_MACHINE"-unknown-osf1 + GUESS=$UNAME_MACHINE-unknown-osf1 fi - exit ;; + ;; parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; + GUESS=hppa1.1-hp-lites + ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; + GUESS=c1-convex-bsd + ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd @@ -791,17 +836,18 @@ EOF fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; + GUESS=c34-convex-bsd + ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; + GUESS=c38-convex-bsd + ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; + GUESS=c4-convex-bsd + ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ @@ -809,103 +855,129 @@ EOF -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; *:BSD/OS:*:*) - echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in + case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" - exit ;; + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; i*:CYGWIN*:*) - echo "$UNAME_MACHINE"-pc-cygwin - exit ;; + GUESS=$UNAME_MACHINE-pc-cygwin + ;; *:MINGW64*:*) - echo "$UNAME_MACHINE"-pc-mingw64 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; *:MINGW*:*) - echo "$UNAME_MACHINE"-pc-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; *:MSYS*:*) - echo "$UNAME_MACHINE"-pc-msys - exit ;; + GUESS=$UNAME_MACHINE-pc-msys + ;; i*:PW*:*) - echo "$UNAME_MACHINE"-pc-pw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; *:Interix*:*) - case "$UNAME_MACHINE" in + case $UNAME_MACHINE in x86) - echo i586-pc-interix"$UNAME_RELEASE" - exit ;; + GUESS=i586-pc-interix$UNAME_RELEASE + ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix"$UNAME_RELEASE" - exit ;; + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; IA64) - echo ia64-unknown-interix"$UNAME_RELEASE" - exit ;; + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; esac ;; i*:UWIN*:*) - echo "$UNAME_MACHINE"-pc-uwin - exit ;; + GUESS=$UNAME_MACHINE-pc-uwin + ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; + GUESS=x86_64-pc-cygwin + ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" - exit ;; + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" - exit ;; - i*86:Minix:*:*) - echo "$UNAME_MACHINE"-pc-minix - exit ;; + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; aarch64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -916,187 +988,225 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi - exit ;; + ;; avr32*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; cris:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; crisv32:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; e2k:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; frv:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; hexagon:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; ia64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; k1om:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m32r*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m68*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" - test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-"$LIBC" - exit ;; + GUESS=or1k-unknown-linux-$LIBC + ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; padre:Linux:*:*) - echo sparc-unknown-linux-"$LIBC" - exit ;; + GUESS=sparc-unknown-linux-$LIBC + ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-"$LIBC" - exit ;; + GUESS=hppa64-unknown-linux-$LIBC + ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; - PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; - *) echo hppa-unknown-linux-"$LIBC" ;; + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; esac - exit ;; + ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc64-unknown-linux-$LIBC + ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc-unknown-linux-$LIBC + ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc64le-unknown-linux-$LIBC + ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-"$LIBC" - exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; s390:Linux:*:* | s390x:Linux:*:*) - echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; sh64*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sh*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; vax:Linux:*:*) - echo "$UNAME_MACHINE"-dec-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; x86_64:Linux:*:*) - if objdump -f /bin/sh | grep -q elf32-x86-64; then - echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 - else - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI=${LIBC}x32 + fi fi - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + ;; xtensa*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; + GUESS=i386-sequent-sysv4 + ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" - exit ;; + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo "$UNAME_MACHINE"-pc-os2-emx - exit ;; + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; i*86:XTS-300:*:STOP) - echo "$UNAME_MACHINE"-unknown-stop - exit ;; + GUESS=$UNAME_MACHINE-unknown-stop + ;; i*86:atheos:*:*) - echo "$UNAME_MACHINE"-unknown-atheos - exit ;; + GUESS=$UNAME_MACHINE-unknown-atheos + ;; i*86:syllable:*:*) - echo "$UNAME_MACHINE"-pc-syllable - exit ;; + GUESS=$UNAME_MACHINE-pc-syllable + ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; i*86:*DOS:*:*) - echo "$UNAME_MACHINE"-pc-msdosdjgpp - exit ;; + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else - echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi - exit ;; + ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in @@ -1104,12 +1214,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" - exit ;; + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1119,11 +1229,11 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else - echo "$UNAME_MACHINE"-pc-sysv32 + GUESS=$UNAME_MACHINE-pc-sysv32 fi - exit ;; + ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about @@ -1131,31 +1241,31 @@ EOF # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; + GUESS=i586-pc-msdosdjgpp + ;; Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; + GUESS=i386-pc-mach3 + ;; paragon:*:*:*) - echo i860-intel-osf1 - exit ;; + GUESS=i860-intel-osf1 + ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi - exit ;; + ;; mini*:CTIX:SYS*5:*) # "miniframe" - echo m68010-convergent-sysv - exit ;; + GUESS=m68010-convergent-sysv + ;; mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; + GUESS=m68k-convergent-sysv + ;; M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; + GUESS=m68k-diab-dnix + ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) @@ -1180,249 +1290,404 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; + GUESS=m68k-atari-sysv4 + ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv"$UNAME_RELEASE" - exit ;; + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo "$UNAME_MACHINE"-sni-sysv4 + GUESS=$UNAME_MACHINE-sni-sysv4 else - echo ns32k-sni-sysv + GUESS=ns32k-sni-sysv fi - exit ;; + ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says - echo i586-unisys-sysv4 - exit ;; + GUESS=i586-unisys-sysv4 + ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; + GUESS=hppa1.1-stratus-sysv4 + ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; + GUESS=i860-stratus-sysv4 + ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo "$UNAME_MACHINE"-stratus-vos - exit ;; + GUESS=$UNAME_MACHINE-stratus-vos + ;; *:VOS:*:*) # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; + GUESS=hppa1.1-stratus-vos + ;; mc68*:A/UX:*:*) - echo m68k-apple-aux"$UNAME_RELEASE" - exit ;; + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; + GUESS=mips-sony-newsos6 + ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv"$UNAME_RELEASE" + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE else - echo mips-unknown-sysv"$UNAME_RELEASE" + GUESS=mips-unknown-sysv$UNAME_RELEASE fi - exit ;; + ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; + GUESS=powerpc-be-beos + ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; + GUESS=powerpc-apple-beos + ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; + GUESS=i586-pc-beos + ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; + GUESS=i586-pc-haiku + ;; x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; + GUESS=x86_64-unknown-haiku + ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; *:Rhapsody:*:*) - echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi - echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; *:QNX:*:4*) - echo i386-pc-qnx - exit ;; + GUESS=i386-pc-qnx + ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; NSV-*:NONSTOP_KERNEL:*:*) - echo nsv-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; + GUESS=mips-compaq-nonstopux + ;; BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; + GUESS=bs2000-siemens-sysv + ;; DS/*:UNIX_System_V:*:*) - echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = 386; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype fi - echo "$UNAME_MACHINE"-unknown-plan9 - exit ;; + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; + GUESS=pdp10-unknown-tops10 + ;; *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; + GUESS=pdp10-unknown-tenex + ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; + GUESS=pdp10-dec-tops20 + ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; + GUESS=pdp10-xkl-tops20 + ;; *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; + GUESS=pdp10-unknown-tops20 + ;; *:ITS:*:*) - echo pdp10-unknown-its - exit ;; + GUESS=pdp10-unknown-its + ;; SEI:*:*:SEIUX) - echo mips-sei-seiux"$UNAME_RELEASE" - exit ;; + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" - exit ;; + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; + GUESS=i386-pc-xenix + ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" - exit ;; + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; i*86:rdos:*:*) - echo "$UNAME_MACHINE"-pc-rdos - exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros - exit ;; + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; x86_64:VMkernel:*:*) - echo "$UNAME_MACHINE"-unknown-esx - exit ;; + GUESS=$UNAME_MACHINE-unknown-esx + ;; amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs - exit ;; + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; esac +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + echo "$0: unable to guess system type" >&2 -case "$UNAME_MACHINE:$UNAME_SYSTEM" in +case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 exit 1 ;; *local*) @@ -110,1223 +119,1186 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo "$1" | sed 's/-[^-]*$//'` - if [ "$basic_machine" != "$1" ] - then os=`echo "$1" | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -bluegene*) - os=-cnk + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pru \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - c54x) - basic_machine=tic54x-unknown + op50n) + cpu=hppa1.1 + vendor=oki ;; - c55x) - basic_machine=tic55x-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - c6x) - basic_machine=tic6x-unknown + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none ;; leon|leon[3-9]) - basic_machine=sparc-$basic_machine + cpu=sparc + vendor=$basic_machine ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) - ;; - ms1) - basic_machine=mt-unknown + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - strongarm | thumb | xscale) - basic_machine=arm-unknown + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pru-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-pc - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2*) - basic_machine=m68k-bull - os=-sysv3 - ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=$os"spe" - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - nsv-tandem) - basic_machine=nsv-tandem - ;; - nsx-tandem) - basic_machine=nsx-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 + cpu=$basic_machine + vendor=pc ;; + # These rules are duplicated from below for sake of the special case above; + # i.e. things that normalized to x86 arches should also default to "pc" pc98) - basic_machine=i386-pc + cpu=i386 + vendor=pc ;; - pc98-*) - basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + x64 | amd64) + cpu=x86_64 + vendor=pc ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc + # Recognize the basic CPU types without company name. + *) + cpu=$basic_machine + vendor=unknown ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + basic_os=${basic_os:-unicosmp} ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc + c90-unknown | c90-cray) + vendor=cray + basic_os=${Basic_os:-unicos} ;; - pentium4) - basic_machine=i786-pc + fx80-unknown) + vendor=alliant ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + romp-unknown) + vendor=ibm ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + mmix-unknown) + vendor=knuth ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + microblaze-unknown | microblazeel-unknown) + vendor=xilinx ;; - pentium4-*) - basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + rs6000-unknown) + vendor=ibm ;; - pn) - basic_machine=pn-gould + vax-unknown) + vendor=dec ;; - power) basic_machine=power-ibm + pdp11-unknown) + vendor=dec ;; - ppc | ppcbe) basic_machine=powerpc-unknown + we32k-unknown) + vendor=att ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + cydra-unknown) + vendor=cydrome ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown + i370-ibm*) + vendor=ibm ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + orion-unknown) + vendor=highlevel ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - x64) - basic_machine=x86_64-pc - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - none) - basic_machine=none-none - os=-none + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell ;; -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond + # Here we normalize CPU types with a missing or matching vendor + armh-unknown | armh-alt) + cpu=armv7l + vendor=alt + basic_os=${basic_os:-linux-gnueabihf} ;; - op50n) - basic_machine=hppa1.1-oki + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + basic_os=${basic_os:-bosx} ;; - op60c) - basic_machine=hppa1.1-oki + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 ;; - romp) - basic_machine=romp-ibm + blackfin-*) + cpu=bfin + basic_os=linux ;; - mmix) - basic_machine=mmix-knuth + c54x-*) + cpu=tic54x ;; - rs6000) - basic_machine=rs6000-ibm + c55x-*) + cpu=tic55x ;; - vax) - basic_machine=vax-dec + c6x-*) + cpu=tic6x ;; - pdp11) - basic_machine=pdp11-dec + e500v[12]-*) + cpu=powerpc + basic_os=${basic_os}"spe" ;; - we32k) - basic_machine=we32k-att + mips3*-*) + cpu=mips64 ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown + ms1-*) + cpu=mt ;; - cydra) - basic_machine=cydra-cydrome + m68knommu-*) + cpu=m68k + basic_os=linux ;; - orion) - basic_machine=orion-highlevel + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z ;; - orion105) - basic_machine=clipper-highlevel + openrisc-*) + cpu=or32 ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple + parisc-*) + cpu=hppa + basic_os=linux ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. + pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + cpu=i686 ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 + ;; + pentium4-*) + cpu=i786 + ;; + pc98-*) + cpu=i386 + ;; + ppc-* | ppcbe-*) + cpu=powerpc + ;; + ppcle-* | powerpclittle-*) + cpu=powerpcle + ;; + ppc64-*) + cpu=powerpc64 + ;; + ppc64le-* | powerpc64little-*) + cpu=powerpc64le + ;; + sb1-*) + cpu=mipsisa64sb1 + ;; + sb1el-*) + cpu=mipsisa64sb1el + ;; + sh5e[lb]-*) + cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + ;; + spur-*) + cpu=spur + ;; + strongarm-* | thumb-*) + cpu=arm + ;; + tx39-*) + cpu=mipstx39 + ;; + tx39el-*) + cpu=mipstx39el + ;; + x64-*) + cpu=x86_64 + ;; + xscale-* | xscalee[bl]-*) + cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + ;; + arm64-* | aarch64le-*) + cpu=aarch64 + ;; + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + basic_os=${basic_os:-elf} + ;; + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis + ;; + cris-* | etrax*-*) + cpu=cris + vendor=axis + ;; + crx-*) + basic_os=${basic_os:-elf} + ;; + neo-tandem) + cpu=neo + vendor=tandem + ;; + nse-tandem) + cpu=nse + vendor=tandem + ;; + nsr-tandem) + cpu=nsr + vendor=tandem + ;; + nsv-tandem) + cpu=nsv + vendor=tandem + ;; + nsx-tandem) + cpu=nsx + vendor=tandem + ;; + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony + ;; + tile*-*) + basic_os=${basic_os:-linux-gnu} + ;; + *) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc32 | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1334,203 +1306,215 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if test x$basic_os != x then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1543,258 +1527,363 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; pru-*) - os=-elf + os=elf ;; *-be) - os=-beos + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; *-next) - os=-nextstep + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | relibc* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ + | fiwix* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) vendor=ibm ;; - -os400*) + *-os400*) vendor=ibm ;; - -ptx*) + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-functions 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/third_party/protobuf/configure b/third_party/protobuf/configure index 5e956dfe..67cec6c1 100755 --- a/third_party/protobuf/configure +++ b/third_party/protobuf/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for Protocol Buffers 3.19.1. +# Generated by GNU Autoconf 2.71 for Protocol Buffers 3.21.12. # # Report bugs to . # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Protocol Buffers' PACKAGE_TARNAME='protobuf' -PACKAGE_VERSION='3.19.1' -PACKAGE_STRING='Protocol Buffers 3.19.1' +PACKAGE_VERSION='3.21.12' +PACKAGE_STRING='Protocol Buffers 3.21.12' PACKAGE_BUGREPORT='protobuf@googlegroups.com' PACKAGE_URL='' @@ -694,6 +694,7 @@ MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP +FILECMD LN_S NM ac_ct_DUMPBIN @@ -1424,7 +1425,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Protocol Buffers 3.19.1 to adapt to many kinds of systems. +\`configure' configures Protocol Buffers 3.21.12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1496,7 +1497,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Protocol Buffers 3.19.1:";; + short | recursive ) echo "Configuration of Protocol Buffers 3.21.12:";; esac cat <<\_ACEOF @@ -1626,7 +1627,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Protocol Buffers configure 3.19.1 +Protocol Buffers configure 3.21.12 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2235,7 +2236,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Protocol Buffers $as_me 3.19.1, which was +It was created by Protocol Buffers $as_me 3.21.12, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3245,7 +3246,7 @@ ac_config_headers="$ac_config_headers config.h" case "$DIST_LANG" in "") DIST_LANG=all ;; - all | cpp | csharp | java | python | javanano | objectivec | ruby | js | php) ;; + all | cpp | csharp | java | python | javanano | objectivec | ruby | php) ;; *) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "unknown language: $DIST_LANG @@ -3894,7 +3895,7 @@ fi # Define the identity of the package. PACKAGE='protobuf' - VERSION='3.19.1' + VERSION='3.21.12' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -8294,7 +8295,9 @@ else GCC_FALSE= fi # let the Makefile know if we're gcc -ac_ext=m +case $target_os in #( + darwin*) : + ac_ext=m ac_cpp='$OBJCPP $CPPFLAGS' ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -8689,7 +8692,17 @@ else am__fastdepOBJC_FALSE= fi - + ;; #( + *) : + if false; then + am__fastdepOBJC_TRUE= + am__fastdepOBJC_FALSE='#' +else + am__fastdepOBJC_TRUE='#' + am__fastdepOBJC_FALSE= +fi + ;; +esac # test_util.cc takes forever to compile with GCC and optimization turned on. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking C++ compiler flags..." >&5 @@ -8954,8 +8967,8 @@ esac -macro_version='2.4.6' -macro_revision='2.4.6' +macro_version='2.4.7' +macro_revision='2.4.7' @@ -9508,13 +9521,13 @@ else mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -9652,7 +9665,7 @@ esac fi fi - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -9756,7 +9769,7 @@ else $as_nop lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -9799,7 +9812,7 @@ else $as_nop sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -10004,6 +10017,114 @@ esac +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. +set dummy ${ac_tool_prefix}file; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_FILECMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$FILECMD"; then + ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_FILECMD="${ac_tool_prefix}file" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +FILECMD=$ac_cv_prog_FILECMD +if test -n "$FILECMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 +printf "%s\n" "$FILECMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_FILECMD"; then + ac_ct_FILECMD=$FILECMD + # Extract the first word of "file", so it can be a program name with args. +set dummy file; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_FILECMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_FILECMD"; then + ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_FILECMD="file" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD +if test -n "$ac_ct_FILECMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 +printf "%s\n" "$ac_ct_FILECMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_FILECMD" = x; then + FILECMD=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + FILECMD=$ac_ct_FILECMD + fi +else + FILECMD="$ac_cv_prog_FILECMD" +fi + + + + + + + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 @@ -10147,7 +10268,7 @@ beos*) bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -10181,14 +10302,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -10202,7 +10323,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' @@ -10249,7 +10370,7 @@ netbsd* | netbsdelf*-gnu) newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -10622,13 +10743,29 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cr} +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because thats what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS + + + + + + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. + @@ -11045,7 +11182,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -11063,20 +11200,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -11100,7 +11237,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ @@ -11118,9 +11255,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -11320,7 +11457,7 @@ case $with_sysroot in #( fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -11445,7 +11582,7 @@ ia64-*-hpux*) ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -11466,7 +11603,7 @@ ia64-*-hpux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -11478,7 +11615,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -11504,7 +11641,7 @@ mips64*-*linux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -11512,7 +11649,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -11520,7 +11657,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -11544,14 +11681,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -11659,7 +11796,7 @@ printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -12442,8 +12579,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cr libconftest.a conftest.o" >&5 - $AR cr libconftest.a conftest.o 2>&5 + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 + $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF @@ -12470,17 +12607,12 @@ printf "%s\n" "$lt_cv_ld_force_load" >&6; } _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[912]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[012],*|,*powerpc*-darwin[5-8]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac @@ -12849,8 +12981,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -13368,7 +13500,7 @@ lt_prog_compiler_static= lt_prog_compiler_static='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' @@ -13791,15 +13923,15 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -13854,7 +13986,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -13966,6 +14098,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; interix[3-9]*) @@ -13980,7 +14113,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -14023,7 +14156,7 @@ _LT_EOF compiler_needs_object=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes @@ -14035,13 +14168,14 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -14051,7 +14185,7 @@ _LT_EOF archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -14183,7 +14317,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -14454,12 +14588,12 @@ fi cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes @@ -14500,7 +14634,7 @@ fi fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. @@ -14541,8 +14675,8 @@ fi output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -14576,7 +14710,7 @@ fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -14757,6 +14891,7 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; @@ -14828,6 +14963,7 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; osf3*) @@ -15520,7 +15656,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; @@ -15530,14 +15666,14 @@ cygwin* | mingw* | pw32* | cegcc*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -15556,7 +15692,7 @@ cygwin* | mingw* | pw32* | cegcc*) done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -15593,7 +15729,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -15626,7 +15762,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -16791,30 +16927,41 @@ striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +if test -z "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; - esac + ;; + esac + fi fi @@ -17584,8 +17731,8 @@ fi cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' @@ -17676,11 +17823,11 @@ fi output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else @@ -17715,6 +17862,7 @@ fi emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes + file_list_spec_CXX='@' ;; dgux*) @@ -17745,7 +17893,7 @@ fi archive_cmds_need_lc_CXX=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes @@ -17882,7 +18030,7 @@ fi # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -18022,13 +18170,13 @@ fi archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' @@ -18685,7 +18833,7 @@ lt_prog_compiler_static_CXX= ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -18768,7 +18916,7 @@ lt_prog_compiler_static_CXX= lt_prog_compiler_static_CXX='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' @@ -19155,7 +19303,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) @@ -19163,7 +19311,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -19514,7 +19662,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) @@ -19523,14 +19671,14 @@ cygwin* | mingw* | pw32* | cegcc*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -19549,7 +19697,7 @@ cygwin* | mingw* | pw32* | cegcc*) done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -19586,7 +19734,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -19618,7 +19766,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -22534,6 +22682,10 @@ if test -z "${am__fastdepOBJC_TRUE}" && test -z "${am__fastdepOBJC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepOBJC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${am__fastdepOBJC_TRUE}" && test -z "${am__fastdepOBJC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepOBJC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -22944,7 +23096,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Protocol Buffers $as_me 3.19.1, which was +This file was extended by Protocol Buffers $as_me 3.21.12, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23012,7 +23164,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Protocol Buffers config.status 3.19.1 +Protocol Buffers config.status 3.21.12 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" @@ -23175,6 +23327,7 @@ lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_q lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' @@ -23183,6 +23336,7 @@ want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' @@ -23357,6 +23511,7 @@ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ +FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ @@ -23365,7 +23520,6 @@ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ -AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ @@ -24356,6 +24510,9 @@ to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd +# A file(cmd) program that detects file types. +FILECMD=$lt_FILECMD + # An object symbol dumper. OBJDUMP=$lt_OBJDUMP @@ -24380,8 +24537,11 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR +# Flags to create an archive (by configure). +lt_ar_flags=$lt_ar_flags + # Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS +AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec @@ -24771,7 +24931,7 @@ ltmain=$ac_aux_dir/ltmain.sh # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || diff --git a/third_party/protobuf/configure.ac b/third_party/protobuf/configure.ac index fb5f9d09..7243fd31 100644 --- a/third_party/protobuf/configure.ac +++ b/third_party/protobuf/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.19.1],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.21.12],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) @@ -31,7 +31,7 @@ AC_CONFIG_MACRO_DIR([m4]) AC_ARG_VAR(DIST_LANG, [language to include in the distribution package (i.e., make dist)]) case "$DIST_LANG" in "") DIST_LANG=all ;; - all | cpp | csharp | java | python | javanano | objectivec | ruby | js | php) ;; + all | cpp | csharp | java | python | javanano | objectivec | ruby | php) ;; *) AC_MSG_FAILURE([unknown language: $DIST_LANG]) ;; esac AC_SUBST(DIST_LANG) @@ -80,7 +80,7 @@ AC_LANG([C++]) ACX_USE_SYSTEM_EXTENSIONS m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc -AC_PROG_OBJC +AS_CASE([$target_os], [darwin*], [AC_PROG_OBJC], [AM_CONDITIONAL([am__fastdepOBJC], [false])]) # test_util.cc takes forever to compile with GCC and optimization turned on. AC_MSG_CHECKING([C++ compiler flags...]) diff --git a/third_party/protobuf/conformance/BUILD.bazel b/third_party/protobuf/conformance/BUILD.bazel new file mode 100644 index 00000000..7de2b8e6 --- /dev/null +++ b/third_party/protobuf/conformance/BUILD.bazel @@ -0,0 +1,183 @@ +# Conformance testing for Protobuf. + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library") +load( + "@rules_pkg//:mappings.bzl", + "pkg_attributes", + "pkg_filegroup", + "pkg_files", + "strip_prefix", +) + +exports_files([ + "conformance_test_runner.sh", + "failure_list_java.txt", + "failure_list_java_lite.txt", + "text_format_failure_list_java.txt", + "text_format_failure_list_java_lite.txt", +]) + +cc_proto_library( + name = "test_messages_proto2_proto_cc", + deps = ["//:test_messages_proto2_proto"], +) + +cc_proto_library( + name = "test_messages_proto3_proto_cc", + deps = ["//:test_messages_proto3_proto"], +) + +proto_library( + name = "conformance_proto", + srcs = ["conformance.proto"], + visibility = ["//visibility:public"], +) + +cc_proto_library( + name = "conformance_proto_cc", + deps = [":conformance_proto"], +) + +java_proto_library( + name = "conformance_java_proto", + visibility = [ + "//java:__subpackages__", + ], + deps = [":conformance_proto"], +) + +java_lite_proto_library( + name = "conformance_java_proto_lite", + visibility = [ + "//java:__subpackages__", + ], + deps = [":conformance_proto"], +) + +cc_library( + name = "jsoncpp", + srcs = ["third_party/jsoncpp/jsoncpp.cpp"], + hdrs = ["third_party/jsoncpp/json.h"], + includes = ["."], +) + +cc_library( + name = "conformance_test", + srcs = [ + "conformance_test.cc", + "conformance_test_runner.cc", + ], + hdrs = [ + "conformance_test.h", + ], + includes = ["."], + deps = [":conformance_proto_cc"], +) + +cc_library( + name = "binary_json_conformance_suite", + srcs = ["binary_json_conformance_suite.cc"], + hdrs = ["binary_json_conformance_suite.h"], + deps = [ + ":conformance_test", + ":jsoncpp", + ":test_messages_proto2_proto_cc", + ":test_messages_proto3_proto_cc", + ], +) + +cc_library( + name = "text_format_conformance_suite", + srcs = ["text_format_conformance_suite.cc"], + hdrs = ["text_format_conformance_suite.h"], + deps = [ + ":conformance_test", + ":test_messages_proto2_proto_cc", + ":test_messages_proto3_proto_cc", + ], +) + +cc_binary( + name = "conformance_test_runner", + srcs = ["conformance_test_main.cc"], + visibility = ["//visibility:public"], + deps = [ + ":binary_json_conformance_suite", + ":conformance_test", + ":text_format_conformance_suite", + ], +) + +java_binary( + name = "conformance_java", + srcs = ["ConformanceJava.java"], + main_class = "ConformanceJava", + visibility = [ + "//java:__subpackages__", + ], + deps = [ + ":conformance_java_proto", + "//:protobuf_java", + "//:protobuf_java_util", + "//:test_messages_proto2_java_proto", + "//:test_messages_proto3_java_proto", + ], +) + +java_binary( + name = "conformance_java_lite", + srcs = ["ConformanceJavaLite.java"], + main_class = "ConformanceJavaLite", + visibility = [ + "//java:__subpackages__", + ], + deps = [ + ":conformance_java_proto_lite", + "//:protobuf_java_util", + "//:protobuf_javalite", + "//:test_messages_proto2_java_proto_lite", + "//:test_messages_proto3_java_proto_lite", + ], +) + +filegroup( + name = "all_files", + srcs = glob(["**/*"]), + visibility = ["//:__pkg__"], +) + +pkg_files( + name = "dist_files", + srcs = glob( + ["**/*"], + exclude = [ + # Handled by dist_scripts: + "conformance_test_runner.sh", + + # The following are not in autotools dist: + "autoload.php", + "conformance_nodejs.js", + "failure_list_jruby.txt", + "update_failure_list.py", + ], + ), + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) + +pkg_files( + name = "dist_scripts", + srcs = ["conformance_test_runner.sh"], + attributes = pkg_attributes(mode = "0555"), + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) + +pkg_filegroup( + name = "all_dist_files", + srcs = [ + ":dist_files", + ":dist_scripts", + ], + visibility = ["//pkg:__pkg__"], +) diff --git a/third_party/protobuf/conformance/ConformanceJava.java b/third_party/protobuf/conformance/ConformanceJava.java index 100bec4b..571b413b 100644 --- a/third_party/protobuf/conformance/ConformanceJava.java +++ b/third_party/protobuf/conformance/ConformanceJava.java @@ -229,11 +229,12 @@ class ConformanceJava { } private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) { - com.google.protobuf.AbstractMessage testMessage; + AbstractMessage testMessage; + String messageType = request.getMessageType(); boolean isProto3 = - request.getMessageType().equals("protobuf_test_messages.proto3.TestAllTypesProto3"); + messageType.equals("protobuf_test_messages.proto3.TestAllTypesProto3"); boolean isProto2 = - request.getMessageType().equals("protobuf_test_messages.proto2.TestAllTypesProto2"); + messageType.equals("protobuf_test_messages.proto2.TestAllTypesProto2"); switch (request.getPayloadCase()) { case PROTOBUF_PAYLOAD: @@ -263,7 +264,8 @@ class ConformanceJava { .build(); } } else { - throw new RuntimeException("Protobuf request doesn't have specific payload type."); + throw new IllegalArgumentException( + "Protobuf request has unexpected payload type: " + messageType); } break; } @@ -286,7 +288,8 @@ class ConformanceJava { parser.merge(request.getJsonPayload(), builder); testMessage = builder.build(); } else { - throw new RuntimeException("Protobuf request doesn't have specific payload type."); + throw new IllegalArgumentException( + "Protobuf request has unexpected payload type: " + messageType); } } catch (InvalidProtocolBufferException e) { return Conformance.ConformanceResponse.newBuilder() @@ -320,24 +323,25 @@ class ConformanceJava { .build(); } } else { - throw new RuntimeException("Protobuf request doesn't have specific payload type."); + throw new IllegalArgumentException( + "Protobuf request has unexpected payload type: " + messageType); } break; } case PAYLOAD_NOT_SET: { - throw new RuntimeException("Request didn't have payload."); + throw new IllegalArgumentException("Request didn't have payload."); } default: { - throw new RuntimeException("Unexpected payload case."); + throw new IllegalArgumentException("Unexpected payload case."); } } switch (request.getRequestedOutputFormat()) { case UNSPECIFIED: - throw new RuntimeException("Unspecified output format."); + throw new IllegalArgumentException("Unspecified output format."); case PROTOBUF: { @@ -361,12 +365,12 @@ class ConformanceJava { case TEXT_FORMAT: return Conformance.ConformanceResponse.newBuilder() - .setTextPayload(TextFormat.printToString(testMessage)) + .setTextPayload(TextFormat.printer().printToString(testMessage)) .build(); default: { - throw new RuntimeException("Unexpected request output."); + throw new IllegalArgumentException("Unexpected request output."); } } } diff --git a/third_party/protobuf/conformance/Makefile.am b/third_party/protobuf/conformance/Makefile.am index ac6f9e1b..415412bc 100644 --- a/third_party/protobuf/conformance/Makefile.am +++ b/third_party/protobuf/conformance/Makefile.am @@ -260,9 +260,9 @@ if USE_EXTERNAL_PROTOC # Some implementations include pre-generated versions of well-known types. protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs) - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs) - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. $(conformance_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_proto2_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs) ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) touch protoc_middleman @@ -272,9 +272,9 @@ else # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) ) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) ) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd $(conformance_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_proto2_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) ) ## @mkdir -p lite ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) ) touch protoc_middleman @@ -316,7 +316,7 @@ conformance-java-lite: javac_middleman_lite conformance-csharp: $(other_language_protoc_outputs) @echo "Writing shortcut script conformance-csharp..." @echo '#! /bin/sh' > conformance-csharp - @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp2.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp + @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp3.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp @chmod +x conformance-csharp conformance-php: @@ -364,9 +364,6 @@ test_python: protoc_middleman conformance-test-runner test_python_cpp: protoc_middleman conformance-test-runner ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py -test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) - NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js - if OBJC_CONFORMANCE_TEST test_objc: protoc_middleman conformance-test-runner conformance-objc diff --git a/third_party/protobuf/conformance/Makefile.in b/third_party/protobuf/conformance/Makefile.in index 37aee934..59cc86aa 100644 --- a/third_party/protobuf/conformance/Makefile.in +++ b/third_party/protobuf/conformance/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.16.4 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -323,6 +323,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INSTALL = @INSTALL@ @@ -1445,18 +1446,18 @@ google-protobuf: # Some implementations include pre-generated versions of well-known types. @USE_EXTERNAL_PROTOC_TRUE@protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf -@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs) -@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs) -@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs) +@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. $(conformance_protoc_inputs) +@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_proto2_protoc_inputs) +@USE_EXTERNAL_PROTOC_TRUE@ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs) @USE_EXTERNAL_PROTOC_TRUE@ touch protoc_middleman # We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. @USE_EXTERNAL_PROTOC_FALSE@protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf -@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) ) -@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) ) -@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) ) +@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd $(conformance_protoc_inputs) ) +@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_proto2_protoc_inputs) ) +@USE_EXTERNAL_PROTOC_FALSE@ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) ) @USE_EXTERNAL_PROTOC_FALSE@ touch protoc_middleman $(protoc_outputs): protoc_middleman @@ -1489,7 +1490,7 @@ conformance-java-lite: javac_middleman_lite conformance-csharp: $(other_language_protoc_outputs) @echo "Writing shortcut script conformance-csharp..." @echo '#! /bin/sh' > conformance-csharp - @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp2.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp + @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp3.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp @chmod +x conformance-csharp conformance-php: @@ -1537,9 +1538,6 @@ test_python: protoc_middleman conformance-test-runner test_python_cpp: protoc_middleman conformance-test-runner ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py -test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) - NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js - @OBJC_CONFORMANCE_TEST_TRUE@test_objc: protoc_middleman conformance-test-runner conformance-objc @OBJC_CONFORMANCE_TEST_TRUE@ ./conformance-test-runner --enforce_recommended --failure_list failure_list_objc.txt ./conformance-objc diff --git a/third_party/protobuf/conformance/README.md b/third_party/protobuf/conformance/README.md index 06925dbb..901d287f 100644 --- a/third_party/protobuf/conformance/README.md +++ b/third_party/protobuf/conformance/README.md @@ -49,7 +49,7 @@ Running the tests for other languages Most of the languages in the Protobuf source tree are set up to run conformance tests. However some of them are more tricky to set up properly. See `tests.sh` in the base of the repository to see how -Travis runs the tests. +Kokoro runs the tests. Testing other Protocol Buffer implementations --------------------------------------------- @@ -57,10 +57,10 @@ Testing other Protocol Buffer implementations To run these tests against a new Protocol Buffers implementation, write a program in your language that uses the protobuf implementation you want to test. This program should implement the testing protocol defined in -[conformance.proto](https://github.com/protocolbuffers/protobuf/blob/master/conformance/conformance.proto). +[conformance.proto](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance.proto). This is designed to be as easy as possible: the C++ version is only 150 lines and is a good example for what this program should look like -(see [conformance_cpp.cc](https://github.com/protocolbuffers/protobuf/blob/master/conformance/conformance_cpp.cc)). +(see [conformance_cpp.cc](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance_cpp.cc)). The program only needs to be able to read from stdin and write to stdout. Portability diff --git a/third_party/protobuf/conformance/binary_json_conformance_suite.cc b/third_party/protobuf/conformance/binary_json_conformance_suite.cc index b12978fa..9b1548df 100644 --- a/third_party/protobuf/conformance/binary_json_conformance_suite.cc +++ b/third_party/protobuf/conformance/binary_json_conformance_suite.cc @@ -2226,11 +2226,11 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { "optional_aliased_enum: ALIAS_BAZ"); RunValidJsonTest( "EnumFieldWithAliasUseAlias", REQUIRED, - R"({"optionalAliasedEnum": "QUX"})", + R"({"optionalAliasedEnum": "MOO"})", "optional_aliased_enum: ALIAS_BAZ"); RunValidJsonTest( "EnumFieldWithAliasLowerCase", REQUIRED, - R"({"optionalAliasedEnum": "qux"})", + R"({"optionalAliasedEnum": "moo"})", "optional_aliased_enum: ALIAS_BAZ"); RunValidJsonTest( "EnumFieldWithAliasDifferentCase", REQUIRED, diff --git a/third_party/protobuf/conformance/conformance_test.cc b/third_party/protobuf/conformance/conformance_test.cc index 07b41506..2c856f58 100644 --- a/third_party/protobuf/conformance/conformance_test.cc +++ b/third_party/protobuf/conformance/conformance_test.cc @@ -350,7 +350,17 @@ bool ConformanceTestSuite::CheckSetEmpty( StringAppendF(&output_, "\n"); if (!write_to_file.empty()) { - std::ofstream os(write_to_file); + std::string full_filename; + const std::string* filename = &write_to_file; + if (!output_dir_.empty()) { + full_filename = output_dir_; + if (*output_dir_.rbegin() != '/') { + full_filename.push_back('/'); + } + full_filename += write_to_file; + filename = &full_filename; + } + std::ofstream os(*filename); if (os) { for (std::set::const_iterator iter = set_to_check.begin(); iter != set_to_check.end(); ++iter) { @@ -358,7 +368,7 @@ bool ConformanceTestSuite::CheckSetEmpty( } } else { StringAppendF(&output_, "Failed to open file: %s\n", - write_to_file.c_str()); + filename->c_str()); } } diff --git a/third_party/protobuf/conformance/conformance_test.h b/third_party/protobuf/conformance/conformance_test.h index 76bd1bc3..83d94f89 100644 --- a/third_party/protobuf/conformance/conformance_test.h +++ b/third_party/protobuf/conformance/conformance_test.h @@ -124,7 +124,7 @@ class ForkPipeRunner : public ConformanceTestRunner { // class MyConformanceTestSuite : public ConformanceTestSuite { // public: // void RunSuiteImpl() { -// // INSERT ACTURAL TESTS. +// // INSERT ACTUAL TESTS. // } // }; // @@ -174,6 +174,11 @@ class ConformanceTestSuite { failure_list_flag_name_ = failure_list_flag_name; } + // Sets the path of the output directory. + void SetOutputDir(const char* output_dir) { + output_dir_ = output_dir; + } + // Run all the conformance tests against the given test runner. // Test output will be stored in "output". // @@ -296,6 +301,7 @@ class ConformanceTestSuite { bool verbose_; bool enforce_recommended_; std::string output_; + std::string output_dir_; std::string failure_list_flag_name_; std::string failure_list_filename_; diff --git a/third_party/protobuf/conformance/conformance_test_runner.cc b/third_party/protobuf/conformance/conformance_test_runner.cc index 1572ac03..2aac35c5 100644 --- a/third_party/protobuf/conformance/conformance_test_runner.cc +++ b/third_party/protobuf/conformance/conformance_test_runner.cc @@ -141,6 +141,9 @@ void UsageError() { " strictly conforming to protobuf\n"); fprintf(stderr, " spec.\n"); + fprintf(stderr, + " --output_dir Directory to write\n" + " output files.\n"); exit(1); } @@ -162,7 +165,7 @@ void ForkPipeRunner::RunTest( // We failed to read from the child, assume a crash and try to reap. GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_; - int status; + int status = 0; waitpid(child_pid_, &status, WEXITED); string error_msg; @@ -208,6 +211,9 @@ int ForkPipeRunner::Run( suite->SetVerbose(true); } else if (strcmp(argv[arg], "--enforce_recommended") == 0) { suite->SetEnforceRecommended(true); + } else if (strcmp(argv[arg], "--output_dir") == 0) { + if (++arg == argc) UsageError(); + suite->SetOutputDir(argv[arg]); } else if (argv[arg][0] == '-') { bool recognized_flag = false; for (ConformanceTestSuite* suite : suites) { diff --git a/third_party/protobuf/internal.bzl b/third_party/protobuf/conformance/defs.bzl similarity index 83% rename from third_party/protobuf/internal.bzl rename to third_party/protobuf/conformance/defs.bzl index a281418c..905953a1 100644 --- a/third_party/protobuf/internal.bzl +++ b/third_party/protobuf/conformance/defs.bzl @@ -12,9 +12,9 @@ def conformance_test(name, testee, failure_list = None, text_format_failure_list native.sh_test( name = name, - srcs = ["//:conformance/conformance_test_runner.sh"], + srcs = ["//conformance:conformance_test_runner.sh"], data = [testee] + failure_lists + [ - "//:conformance_test_runner", + "//conformance:conformance_test_runner", ], args = args, deps = [ @@ -22,8 +22,7 @@ def conformance_test(name, testee, failure_list = None, text_format_failure_list ], ) - def _strip_bazel(testee): if testee.startswith("//"): - testee = testee.replace("//", "com_google_protobuf") + testee = testee.replace("//", "com_google_protobuf/") return testee.replace(":", "/") diff --git a/third_party/protobuf/conformance/failure_list_js.txt b/third_party/protobuf/conformance/failure_list_js.txt index e69de29b..b7d36b6d 100644 --- a/third_party/protobuf/conformance/failure_list_js.txt +++ b/third_party/protobuf/conformance/failure_list_js.txt @@ -0,0 +1,162 @@ +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput +Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput +Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput +Required.Proto2.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput diff --git a/third_party/protobuf/csharp/BUILD.bazel b/third_party/protobuf/csharp/BUILD.bazel new file mode 100644 index 00000000..2c150841 --- /dev/null +++ b/third_party/protobuf/csharp/BUILD.bazel @@ -0,0 +1,34 @@ +# Protobuf C# runtime +# +# See also code generation logic under /src/google/protobuf/compiler/csharp. + +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") + +pkg_files( + name = "dist_files", + srcs = glob([ + "keys/*", + "protos/*", + "src/**/*.cs*", # .cs and .csproj + ]) + [ + ".editorconfig", + ".gitignore", + "BUILD.bazel", + "CHANGES.txt", + "Google.Protobuf.Tools.nuspec", + "Google.Protobuf.Tools.targets", + "NuGet.Config", + "README.md", + "build_packages.bat", + "build_tools.sh", + "buildall.bat", + "buildall.sh", + "generate_protos.sh", + "install_dotnet_sdk.ps1", + "src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto", + "src/Google.Protobuf.Test/testprotos.pb", + "src/Google.Protobuf.sln", + ], + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) diff --git a/third_party/protobuf/editors/protobuf-mode.el b/third_party/protobuf/editors/protobuf-mode.el index bbb82b7f..e97b95cf 100644 --- a/third_party/protobuf/editors/protobuf-mode.el +++ b/third_party/protobuf/editors/protobuf-mode.el @@ -193,7 +193,7 @@ ;;;###autoload (add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode)) ;;;###autoload -(define-derived-mode protobuf-mode prog-mode "Protobuf" +(define-derived-mode protobuf-mode prog-mode "Protocol-Buffers" "Major mode for editing Protocol Buffers description language. The hook `c-mode-common-hook' is run with no argument at mode @@ -201,26 +201,17 @@ initialization, then `protobuf-mode-hook'. Key bindings: \\{protobuf-mode-map}" - (interactive) - (kill-all-local-variables) - (set-syntax-table protobuf-mode-syntax-table) - (setq major-mode 'protobuf-mode - mode-name "Protocol-Buffers" - local-abbrev-table protobuf-mode-abbrev-table - abbrev-mode t) - (use-local-map protobuf-mode-map) + :after-hook (c-update-modeline) + (setq abbrev-mode t) (c-initialize-cc-mode t) - (if (fboundp 'c-make-emacs-variables-local) - (c-make-emacs-variables-local)) (c-init-language-vars protobuf-mode) (c-common-init 'protobuf-mode) (easy-menu-add protobuf-menu) - (c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook) - (c-update-modeline) (setq imenu-generic-expression '(("Message" "^[[:space:]]*message[[:space:]]+\\([[:alnum:]]+\\)" 1) ("Enum" "^[[:space:]]*enum[[:space:]]+\\([[:alnum:]]+\\)" 1) - ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1)))) + ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1))) + (c-run-mode-hooks 'c-mode-common-hook)) (provide 'protobuf-mode) diff --git a/third_party/protobuf/examples/BUILD b/third_party/protobuf/examples/BUILD.bazel similarity index 80% rename from third_party/protobuf/examples/BUILD rename to third_party/protobuf/examples/BUILD.bazel index 7d15e83a..d5a719ca 100644 --- a/third_party/protobuf/examples/BUILD +++ b/third_party/protobuf/examples/BUILD.bazel @@ -6,6 +6,7 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_proto_library") load("@rules_java//java:defs.bzl", "java_binary", "java_lite_proto_library", "java_proto_library") +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_proto//proto:defs.bzl", "proto_library") # For each .proto file, a proto_library target should be defined. This target @@ -103,3 +104,34 @@ java_binary( main_class = "ListPeople", deps = [":addressbook_java_lite_proto"], ) + +# Files included in all source distributions +pkg_files( + name = "dist_files", + srcs = [ + "AddPerson.java", + "BUILD.bazel", + "CMakeLists.txt", + "ListPeople.java", + "Makefile", + "README.md", + "WORKSPACE", + "add_person.cc", + "add_person.dart", + "add_person.py", + "addressbook.proto", + "go/cmd/add_person/add_person.go", + "go/cmd/add_person/add_person_test.go", + "go/cmd/list_people/list_people.go", + "go/cmd/list_people/list_people_test.go", + "go/go.mod", + "go/go.sum", + "list_people.cc", + "list_people.dart", + "list_people.py", + "pubspec.yaml", + ], + prefix = "examples/", + strip_prefix = strip_prefix.from_root(""), + visibility = ["//visibility:public"], +) diff --git a/third_party/protobuf/examples/README.md b/third_party/protobuf/examples/README.md index 4bf7c17c..a99883e0 100644 --- a/third_party/protobuf/examples/README.md +++ b/third_party/protobuf/examples/README.md @@ -91,22 +91,18 @@ scripts) and can be used to create/display an address book data file. ### Go -The Go example requires a plugin to the protocol buffer compiler, so it is not -build with all the other examples. See: +Follow instructions in [../README.md](../README.md) to install protoc. Then +install the Go protoc plugin (protoc-gen-go): - https://github.com/golang/protobuf + $ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -for more information about Go protocol buffer support. +The "go install" command will install protoc-gen-go into the GOBIN +directory. You can set the $GOBIN environment variable before +running "go install" to change the install location. Make sure the +install directory is in your shell $PATH. -First, install the Protocol Buffers compiler (protoc). - -Then, install the Go Protocol Buffers plugin ($GOPATH/bin must be in your $PATH -for protoc to find it): - - go get github.com/golang/protobuf/protoc-gen-go - -Build the Go samples in this directory with "make go". This creates the -following executable files in the current directory: +Build the Go samples with "make go". This creates the following +executable files in the current directory: add_person_go list_people_go diff --git a/third_party/protobuf/examples/WORKSPACE b/third_party/protobuf/examples/WORKSPACE index fb36639a..3897572a 100644 --- a/third_party/protobuf/examples/WORKSPACE +++ b/third_party/protobuf/examples/WORKSPACE @@ -10,8 +10,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # # http_archive( # name = "com_google_protobuf", -# strip_prefix = "protobuf-master", -# urls = ["https://github.com/protocolbuffers/protobuf/archive/master.zip"], +# strip_prefix = "protobuf-main", +# urls = ["https://github.com/protocolbuffers/protobuf/archive/main.zip"], # ) local_repository( name = "com_google_protobuf", diff --git a/third_party/protobuf/examples/addressbook.proto b/third_party/protobuf/examples/addressbook.proto index 5bb35772..1bff4ad3 100644 --- a/third_party/protobuf/examples/addressbook.proto +++ b/third_party/protobuf/examples/addressbook.proto @@ -24,7 +24,7 @@ option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; // [END csharp_declaration] // [START go_declaration] -option go_package = "../tutorial"; +option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"; // [END go_declaration] // [START messages] diff --git a/third_party/protobuf/examples/add_person.go b/third_party/protobuf/examples/go/cmd/add_person/add_person.go similarity index 96% rename from third_party/protobuf/examples/add_person.go rename to third_party/protobuf/examples/go/cmd/add_person/add_person.go index 7ffb0ab0..5d2f21c1 100644 --- a/third_party/protobuf/examples/add_person.go +++ b/third_party/protobuf/examples/go/cmd/add_person/add_person.go @@ -9,8 +9,8 @@ import ( "os" "strings" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func promptForAddress(r io.Reader) (*pb.Person, error) { diff --git a/third_party/protobuf/examples/add_person_test.go b/third_party/protobuf/examples/go/cmd/add_person/add_person_test.go similarity index 88% rename from third_party/protobuf/examples/add_person_test.go rename to third_party/protobuf/examples/go/cmd/add_person/add_person_test.go index d35f10ec..f10c355a 100644 --- a/third_party/protobuf/examples/add_person_test.go +++ b/third_party/protobuf/examples/go/cmd/add_person/add_person_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func TestPromptForAddressReturnsAddress(t *testing.T) { @@ -51,7 +51,7 @@ unknown } for i := 0; i < phones; i++ { if !proto.Equal(got.Phones[i], want[i]) { - t.Errorf("want phone %q, got %q", *want[i], *got.Phones[i]) + t.Errorf("want phone %q, got %q", want[i], got.Phones[i]) } } diff --git a/third_party/protobuf/examples/list_people.go b/third_party/protobuf/examples/go/cmd/list_people/list_people.go similarity index 92% rename from third_party/protobuf/examples/list_people.go rename to third_party/protobuf/examples/go/cmd/list_people/list_people.go index 6c2c34ac..5ca0dcf3 100644 --- a/third_party/protobuf/examples/list_people.go +++ b/third_party/protobuf/examples/go/cmd/list_people/list_people.go @@ -7,8 +7,8 @@ import ( "log" "os" - "github.com/golang/protobuf/proto" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" + "google.golang.org/protobuf/proto" ) func writePerson(w io.Writer, p *pb.Person) { diff --git a/third_party/protobuf/examples/list_people_test.go b/third_party/protobuf/examples/go/cmd/list_people/list_people_test.go similarity index 97% rename from third_party/protobuf/examples/list_people_test.go rename to third_party/protobuf/examples/go/cmd/list_people/list_people_test.go index aceabd4a..b116c16a 100644 --- a/third_party/protobuf/examples/list_people_test.go +++ b/third_party/protobuf/examples/go/cmd/list_people/list_people_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - pb "github.com/protocolbuffers/protobuf/examples/tutorial" + pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb" ) func TestWritePersonWritesPerson(t *testing.T) { diff --git a/third_party/protobuf/examples/go/go.mod b/third_party/protobuf/examples/go/go.mod new file mode 100644 index 00000000..ed43328d --- /dev/null +++ b/third_party/protobuf/examples/go/go.mod @@ -0,0 +1,5 @@ +module github.com/protocolbuffers/protobuf/examples/go + +go 1.14 + +require google.golang.org/protobuf v1.27.1 diff --git a/third_party/protobuf/examples/go/go.sum b/third_party/protobuf/examples/go/go.sum new file mode 100644 index 00000000..9f8c0643 --- /dev/null +++ b/third_party/protobuf/examples/go/go.sum @@ -0,0 +1,6 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/third_party/protobuf/ltmain.sh b/third_party/protobuf/ltmain.sh index 21e5e078..8fb8700e 100755 --- a/third_party/protobuf/ltmain.sh +++ b/third_party/protobuf/ltmain.sh @@ -1,12 +1,12 @@ -#! /bin/sh +#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 +## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.4.6 +# libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-15" -package_revision=2.4.6 +VERSION="2.4.7 Debian-2.4.7-4" +package_revision=2.4.7 ## ------ ## @@ -64,34 +64,25 @@ package_revision=2.4.6 # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2015-01-20.17; # UTC +scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2004-2019, 2021 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. +# Please report bugs or propose patches to: +# ## ------ ## @@ -139,9 +130,12 @@ do _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# These NLS vars are set unconditionally (bootstrap issue #24). Unset those +# in case the environment reset is needed later and the $save_* variant is not +# defined (see the code above). +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' @@ -159,6 +153,26 @@ if test "${PATH_SEPARATOR+set}" != set; then fi +# func_unset VAR +# -------------- +# Portably unset VAR. +# In some shells, an 'unset VAR' statement leaves a non-zero return +# status if VAR is already unset, which might be problematic if the +# statement is used at the end of a function (thus poisoning its return +# value) or when 'set -e' is active (causing even a spurious abort of +# the script in this case). +func_unset () +{ + { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } +} + + +# Make sure CDPATH doesn't cause `cd` commands to output the target dir. +func_unset CDPATH + +# Make sure ${,E,F}GREP behave sanely. +func_unset GREP_OPTIONS + ## ------------------------- ## ## Locate command utilities. ## @@ -259,7 +273,7 @@ test -z "$SED" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } @@ -295,7 +309,7 @@ test -z "$GREP" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } @@ -360,6 +374,35 @@ sed_double_backslash="\ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" +# require_check_ifs_backslash +# --------------------------- +# Check if we can use backslash as IFS='\' separator, and set +# $check_ifs_backshlash_broken to ':' or 'false'. +require_check_ifs_backslash=func_require_check_ifs_backslash +func_require_check_ifs_backslash () +{ + _G_save_IFS=$IFS + IFS='\' + _G_check_ifs_backshlash='a\\b' + for _G_i in $_G_check_ifs_backshlash + do + case $_G_i in + a) + check_ifs_backshlash_broken=false + ;; + '') + break + ;; + *) + check_ifs_backshlash_broken=: + break + ;; + esac + done + IFS=$_G_save_IFS + require_check_ifs_backslash=: +} + ## ----------------- ## ## Global variables. ## @@ -580,16 +623,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then { $debug_cmd - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1=\$$1\\ \$func_quote_arg_result" } fi @@ -1091,85 +1134,203 @@ func_relative_path () } -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () +# func_quote_portable EVAL ARG +# ---------------------------- +# Internal function to portably implement func_quote_arg. Note that we still +# keep attention to performance here so we as much as possible try to avoid +# calling sed binary (so far O(N) complexity as long as func_append is O(1)). +func_quote_portable () { $debug_cmd - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in + $require_check_ifs_backslash + + func_quote_portable_result=$2 + + # one-time-loop (easy break) + while true + do + if $1; then + func_quote_portable_result=`$ECHO "$2" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` + break + fi + + # Quote for eval. + case $func_quote_portable_result in *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" - fi + # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string + # contains the shell wildcard characters. + case $check_ifs_backshlash_broken$func_quote_portable_result in + :*|*[\[\*\?]*) + func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ + | $SED "$sed_quote_subst"` + break + ;; + esac - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" + func_quote_portable_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_portable_result + do + case $1 in + quote) + func_append func_quote_portable_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_portable_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + done + IFS=$func_quote_portable_old_IFS ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; + *) ;; esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift + break done + + func_quote_portable_unquoted_result=$func_quote_portable_result + case $func_quote_portable_result in + # double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # many bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_portable_result=\"$func_quote_portable_result\" + ;; + esac } -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () +# func_quotefast_eval ARG +# ----------------------- +# Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', +# but optimized for speed. Result is stored in $func_quotefast_eval. +if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then + printf -v _GL_test_printf_tilde %q '~' + if test '\~' = "$_GL_test_printf_tilde"; then + func_quotefast_eval () + { + printf -v func_quotefast_eval_result %q "$1" + } + else + # Broken older Bash implementations. Make those faster too if possible. + func_quotefast_eval () + { + case $1 in + '~'*) + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + ;; + *) + printf -v func_quotefast_eval_result %q "$1" + ;; + esac + } + fi +else + func_quotefast_eval () + { + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + } +fi + + +# func_quote_arg MODEs ARG +# ------------------------ +# Quote one ARG to be evaled later. MODEs argument may contain zero or more +# specifiers listed below separated by ',' character. This function returns two +# values: +# i) func_quote_arg_result +# double-quoted (when needed), suitable for a subsequent eval +# ii) func_quote_arg_unquoted_result +# has all characters that are still active within double +# quotes backslashified. Available only if 'unquoted' is specified. +# +# Available modes: +# ---------------- +# 'eval' (default) +# - escape shell special characters +# 'expand' +# - the same as 'eval'; but do not quote variable references +# 'pretty' +# - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might +# be used later in func_quote to get output like: 'echo "a b"' instead +# of 'echo a\ b'. This is slower than default on some shells. +# 'unquoted' +# - produce also $func_quote_arg_unquoted_result which does not contain +# wrapping double-quotes. +# +# Examples for 'func_quote_arg pretty,unquoted string': +# +# string | *_result | *_unquoted_result +# ------------+-----------------------+------------------- +# " | \" | \" +# a b | "a b" | a b +# "a b" | "\"a b\"" | \"a b\" +# * | "*" | * +# z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" +# +# Examples for 'func_quote_arg pretty,unquoted,expand string': +# +# string | *_result | *_unquoted_result +# --------------+---------------------+-------------------- +# z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" +func_quote_arg () { - $debug_cmd - - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; - esac - - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" + _G_quote_expand=false + case ,$1, in + *,expand,*) + _G_quote_expand=: ;; esac - func_quote_for_expand_result=$_G_arg + case ,$1, in + *,pretty,*|*,expand,*|*,unquoted,*) + func_quote_portable $_G_quote_expand "$2" + func_quote_arg_result=$func_quote_portable_result + func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result + ;; + *) + # Faster quote-for-eval for some shells. + func_quotefast_eval "$2" + func_quote_arg_result=$func_quotefast_eval_result + ;; + esac +} + + +# func_quote MODEs ARGs... +# ------------------------ +# Quote all ARGs to be evaled later and join them into single command. See +# func_quote_arg's description for more info. +func_quote () +{ + $debug_cmd + _G_func_quote_mode=$1 ; shift + func_quote_result= + while test 0 -lt $#; do + func_quote_arg "$_G_func_quote_mode" "$1" + if test -n "$func_quote_result"; then + func_append func_quote_result " $func_quote_arg_result" + else + func_append func_quote_result "$func_quote_arg_result" + fi + shift + done } @@ -1215,8 +1376,8 @@ func_show_eval () _G_cmd=$1 _G_fail_exp=${2-':'} - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" + func_quote_arg pretty,expand "$_G_cmd" + eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" @@ -1241,8 +1402,8 @@ func_show_eval_locale () _G_fail_exp=${2-':'} $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$_G_cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || { @@ -1369,30 +1530,26 @@ func_lt_ver () # End: #! /bin/sh -# Set a version string for this script. -scriptversion=2015-10-07.11; # UTC - # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2010-2019, 2021 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# Please report bugs or propose patches to: +# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. +# Set a version string for this script. +scriptversion=2019-02-19.15; # UTC ## ------ ## @@ -1415,7 +1572,7 @@ scriptversion=2015-10-07.11; # UTC # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. +# starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the @@ -1427,7 +1584,7 @@ scriptversion=2015-10-07.11; # UTC # to display verbose messages only when your user has specified # '--verbose'. # -# After sourcing this file, you can plug processing for additional +# After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. @@ -1476,8 +1633,8 @@ fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## # This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. +# in the main code. A hook is just a list of function names that can be +# run in order later on. # func_hookable FUNC_NAME # ----------------------- @@ -1510,7 +1667,8 @@ func_add_hook () # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +# Remove HOOK_FUNC from the list of hook functions to be called by +# FUNC_NAME. func_remove_hook () { $debug_cmd @@ -1519,10 +1677,28 @@ func_remove_hook () } +# func_propagate_result FUNC_NAME_A FUNC_NAME_B +# --------------------------------------------- +# If the *_result variable of FUNC_NAME_A _is set_, assign its value to +# *_result variable of FUNC_NAME_B. +func_propagate_result () +{ + $debug_cmd + + func_propagate_result_result=: + if eval "test \"\${${1}_result+set}\" = set" + then + eval "${2}_result=\$${1}_result" + else + func_propagate_result_result=false + fi +} + + # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more +# It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. @@ -1534,22 +1710,19 @@ func_run_hooks () case " $hookable_fns " in *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; + *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - if eval $_G_hook '"$@"'; then - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift - _G_rc_run_hooks=: + func_unset "${_G_hook}_result" + eval $_G_hook '${1+"$@"}' + func_propagate_result $_G_hook func_run_hooks + if $func_propagate_result_result; then + eval set dummy "$func_run_hooks_result"; shift fi done - - $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result } @@ -1559,14 +1732,16 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, you may remove/edit -# any options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. In this case you also must return $EXIT_SUCCESS to let the -# hook's caller know that it should pay attention to -# '_result'. Returning $EXIT_FAILURE signalizes that -# arguments are left untouched by the hook and therefore caller will ignore the -# result variable. +# full positional parameter list from your hook function. You may remove +# or edit any options that you action, and then pass back the remaining +# unprocessed options in '_result', escaped +# suitably for 'eval'. +# +# The '_result' variable is automatically unset +# before your hook gets called; for best performance, only set the +# *_result variable when necessary (i.e. don't call the 'func_quote' +# function unnecessarily because it can be an expensive operation on some +# machines). # # Like this: # @@ -1578,11 +1753,8 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# # No change in '$@' (ignored completely by this hook). There is -# # no need to do the equivalent (but slower) action: -# # func_quote_for_eval ${1+"$@"} -# # my_options_prep_result=$func_quote_for_eval_result -# false +# # No change in '$@' (ignored completely by this hook). Leave +# # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # @@ -1593,7 +1765,7 @@ func_run_hooks () # # args_changed=false # -# # Note that for efficiency, we parse as many options as we can +# # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do @@ -1610,18 +1782,17 @@ func_run_hooks () # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" -# # is added back to "$@", we could need that later -# # if $args_changed is true. +# # is added back to "$@" in case we need it later, +# # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # +# # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result +# func_quote eval ${1+"$@"} +# my_silent_option_result=$func_quote_result # fi -# -# $args_changed # } # func_add_hook func_parse_options my_silent_option # @@ -1632,8 +1803,6 @@ func_run_hooks () # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." -# -# false # } # func_add_hook func_validate_options my_option_validation # @@ -1649,13 +1818,8 @@ func_options_finish () { $debug_cmd - _G_func_options_finish_exit=false - if func_run_hooks func_options ${1+"$@"}; then - func_options_finish_result=$func_run_hooks_result - _G_func_options_finish_exit=: - fi - - $_G_func_options_finish_exit + func_run_hooks func_options ${1+"$@"} + func_propagate_result func_run_hooks func_options_finish } @@ -1668,28 +1832,27 @@ func_options () { $debug_cmd - _G_rc_options=false + _G_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do - if eval func_$my_func '${1+"$@"}'; then - eval _G_res_var='$'"func_${my_func}_result" - eval set dummy "$_G_res_var" ; shift - _G_rc_options=: + func_unset func_${my_func}_result + func_unset func_run_hooks_result + eval func_$my_func '${1+"$@"}' + func_propagate_result func_$my_func func_options + if $func_propagate_result_result; then + eval set dummy "$func_options_result"; shift + _G_options_quoted=: fi done - # Save modified positional parameters for caller. As a top-level - # options-parser function we always need to set the 'func_options_result' - # variable (regardless the $_G_rc_options value). - if $_G_rc_options; then - func_options_result=$_G_res_var - else - func_quote_for_eval ${1+"$@"} - func_options_result=$func_quote_for_eval_result - fi - - $_G_rc_options + $_G_options_quoted || { + # As we (func_options) are top-level options-parser function and + # nobody quoted "$@" for us yet, we need to do it explicitly for + # caller. + func_quote eval ${1+"$@"} + func_options_result=$func_quote_result + } } @@ -1699,8 +1862,7 @@ func_options () # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +# modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { @@ -1710,14 +1872,8 @@ func_options_prep () opt_verbose=false opt_warning_types= - _G_rc_options_prep=false - if func_run_hooks func_options_prep ${1+"$@"}; then - _G_rc_options_prep=: - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result - fi - - $_G_rc_options_prep + func_run_hooks func_options_prep ${1+"$@"} + func_propagate_result func_run_hooks func_options_prep } @@ -1729,27 +1885,32 @@ func_parse_options () { $debug_cmd - func_parse_options_result= - - _G_rc_parse_options=false + _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. - if func_run_hooks func_parse_options ${1+"$@"}; then - eval set dummy "$func_run_hooks_result"; shift - _G_rc_parse_options=: + func_run_hooks func_parse_options ${1+"$@"} + func_propagate_result func_run_hooks func_parse_options + if $func_propagate_result_result; then + eval set dummy "$func_parse_options_result"; shift + # Even though we may have changed "$@", we passed the "$@" array + # down into the hook and it quoted it for us (because we are in + # this if-branch). No need to quote it again. + _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break + # We expect that one of the options parsed in this function matches + # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" + func_echo "enabling shell trace mode" >&2 $debug_cmd ;; @@ -1760,7 +1921,7 @@ func_parse_options () --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then - _G_rc_parse_options=: + _G_parse_options_requote=: break fi case " $warning_categories $1" in @@ -1815,7 +1976,7 @@ func_parse_options () shift ;; - --) _G_rc_parse_options=: ; break ;; + --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false @@ -1823,17 +1984,16 @@ func_parse_options () ;; esac - $_G_match_parse_options && _G_rc_parse_options=: + if $_G_match_parse_options; then + _G_parse_options_requote=: + fi done - - if $_G_rc_parse_options; then + if $_G_parse_options_requote; then # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + func_parse_options_result=$func_quote_result fi - - $_G_rc_parse_options } @@ -1846,21 +2006,14 @@ func_validate_options () { $debug_cmd - _G_rc_validate_options=false - # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - if func_run_hooks func_validate_options ${1+"$@"}; then - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result - _G_rc_validate_options=: - fi + func_run_hooks func_validate_options ${1+"$@"} + func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - - $_G_rc_validate_options } @@ -1916,8 +2069,8 @@ func_missing_arg () # func_split_equals STRING # ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. +# Set func_split_equals_lhs and func_split_equals_rhs shell variables +# after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ @@ -1932,8 +2085,9 @@ then func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= + if test "x$func_split_equals_lhs" = "x$1"; then + func_split_equals_rhs= + fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. @@ -1943,7 +2097,7 @@ else func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ + test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals @@ -1969,7 +2123,7 @@ else { $debug_cmd - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt @@ -2011,31 +2165,44 @@ func_usage_message () # func_version # ------------ # Echo version message to standard output and exit. +# The version message is extracted from the calling file's header +# comments, with leading '# ' stripped: +# 1. First display the progname and version +# 2. Followed by the header comment line matching /^# Written by / +# 3. Then a blank line followed by the first following line matching +# /^# Copyright / +# 4. Immediately followed by any lines between the previous matches, +# except lines preceding the intervening completely blank line. +# For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more + /^# Written by /!b + s|^# ||; p; n + + :fwd2blnk + /./ { + n + b fwd2blnk } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p + p; n + + :holdwrnt + s|^# || + s|^# *$|| + /^Copyright /!{ + /./H + n + b holdwrnt } - /^# Written by / { - s|^# || - p - } - /^warranty; /q' < "$progpath" + + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + G + s|\(\n\)\n*|\1|g + p; q' < "$progpath" exit $? } @@ -2045,12 +2212,12 @@ func_version () # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.6' +scriptversion='(GNU libtool) 2.4.7' # func_echo ARG... @@ -2141,7 +2308,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname $scriptversion Debian-2.4.6-15 + version: $progname $scriptversion Debian-2.4.7-4 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` @@ -2197,7 +2364,7 @@ fi # a configuration failure hint, and exit. func_fatal_configuration () { - func__fatal_error ${1+"$@"} \ + func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } @@ -2345,6 +2512,8 @@ libtool_options_prep () _G_rc_lt_options_prep=: + _G_rc_lt_options_prep=: + # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2375,11 +2544,9 @@ libtool_options_prep () if $_G_rc_lt_options_prep; then # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_options_prep_result=$func_quote_result fi - - $_G_rc_lt_options_prep } func_add_hook func_options_prep libtool_options_prep @@ -2482,11 +2649,9 @@ libtool_parse_options () if $_G_rc_lt_parse_options; then # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_parse_options_result=$func_quote_result fi - - $_G_rc_lt_parse_options } func_add_hook func_parse_options libtool_parse_options @@ -2543,8 +2708,8 @@ libtool_validate_options () } # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options @@ -3510,8 +3675,8 @@ func_mode_compile () esac done - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ + func_quote_arg pretty "$libobj" + test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" @@ -3584,8 +3749,8 @@ compiler." func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result + func_quote_arg pretty "$srcfile" + qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then @@ -3740,7 +3905,8 @@ This mode accepts the following additional options: -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler + -Wc,FLAG + -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. @@ -3846,6 +4012,8 @@ The following components of LINK-COMMAND are treated specially: -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wa,FLAG + -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) @@ -4188,8 +4356,8 @@ func_mode_install () case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " + func_quote_arg pretty "$nonopt" + install_prog="$func_quote_arg_result " arg=$1 shift else @@ -4199,8 +4367,8 @@ func_mode_install () # The real first argument should be the name of the installation program. # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; @@ -4257,12 +4425,12 @@ func_mode_install () esac # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then - func_quote_for_eval "$arg2" + func_quote_arg pretty "$arg2" fi - func_append install_shared_prog " $func_quote_for_eval_result" + func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ @@ -4273,8 +4441,8 @@ func_mode_install () if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" + func_quote_arg pretty "$install_override_mode" + func_append install_shared_prog " -m $func_quote_arg_result" fi fi @@ -4570,8 +4738,8 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$relink_command" + eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else @@ -5350,7 +5518,8 @@ else if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + func_quote_arg pretty "$ECHO" + qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. @@ -5360,7 +5529,7 @@ func_fallback_echo () \$1 _LTECHO_EOF' } - ECHO=\"$qECHO\" + ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to @@ -6703,9 +6872,9 @@ func_mode_link () while test "$#" -gt 0; do arg=$1 shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" + func_quote_arg pretty,unquoted "$arg" + qarg=$func_quote_arg_unquoted_result + func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then @@ -6941,6 +7110,13 @@ func_mode_link () prev= continue ;; + xassembler) + func_append compiler_flags " -Xassembler $qarg" + prev= + func_append compile_command " -Xassembler $qarg" + func_append finalize_command " -Xassembler $qarg" + continue + ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" @@ -7111,7 +7287,7 @@ func_mode_link () # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; @@ -7131,7 +7307,7 @@ func_mode_link () esac elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -7161,8 +7337,20 @@ func_mode_link () prev=xcompiler continue ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. + -pthread) + case $host in + *solaris2*) ;; + *) + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + ;; + esac + continue + ;; + -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" @@ -7303,9 +7491,9 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $func_quote_arg_result" + func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" @@ -7319,16 +7507,21 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $wl$func_quote_arg_result" + func_append compiler_flags " $wl$func_quote_arg_result" + func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; + -Xassembler) + prev=xassembler + continue + ;; + -Xcompiler) prev=xcompiler continue @@ -7346,8 +7539,8 @@ func_mode_link () # -msg_* for osf cc -msg_*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: @@ -7370,12 +7563,13 @@ func_mode_link () # -fuse-ld=* Linker select flags for GCC # -static-* direct GCC to link specific libraries statically # -fcilkplus Cilk Plus language extension features for C/C++ + # -Wa,* Pass flags directly to the assembler -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ - -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus|-Wa,*) + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" @@ -7396,15 +7590,15 @@ func_mode_link () continue else # Otherwise treat like 'Some other compiler flag' below - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; *.$objext) @@ -7524,8 +7718,8 @@ func_mode_link () *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; esac # arg @@ -8733,7 +8927,7 @@ func_mode_link () test CXX = "$tagname" && { case $host_os in linux*) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi @@ -8906,7 +9100,7 @@ func_mode_link () # case $version_type in # correct linux to gnu/linux during the next big refactor - darwin|freebsd-elf|linux|osf|windows|none) + darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor @@ -9000,7 +9194,7 @@ func_mode_link () versuffix=.$current.$revision ;; - freebsd-elf) + freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision @@ -9226,7 +9420,7 @@ func_mode_link () *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) @@ -10037,8 +10231,8 @@ EOF for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? @@ -10131,8 +10325,8 @@ EOF eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? @@ -10606,12 +10800,13 @@ EOF elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + func_quote_arg pretty "$var_value" + relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + func_quote eval cd "`pwd`" + func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" + relink_command=$func_quote_arg_unquoted_result fi # Only actually do things if not in dry run mode. @@ -10851,13 +11046,15 @@ EOF elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + func_quote_arg pretty,unquoted "$var_value" + relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + func_quote eval cd "`pwd`" + relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + func_quote_arg pretty,unquoted "$relink_command" + relink_command=$func_quote_arg_unquoted_result if test yes = "$hardcode_automatic"; then relink_command= fi diff --git a/third_party/protobuf/m4/libtool.m4 b/third_party/protobuf/m4/libtool.m4 index c4c02946..e7b68334 100644 --- a/third_party/protobuf/m4/libtool.m4 +++ b/third_party/protobuf/m4/libtool.m4 @@ -1,6 +1,7 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -31,7 +32,7 @@ m4_define([_LT_COPYING], [dnl # along with this program. If not, see . ]) -# serial 58 LT_INIT +# serial 59 LT_INIT # LT_PREREQ(VERSION) @@ -181,6 +182,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl @@ -219,8 +221,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -777,7 +779,7 @@ _LT_EOF # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -1041,8 +1043,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1066,17 +1068,12 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac @@ -1125,12 +1122,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1244,7 +1241,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) +[m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot @@ -1261,7 +1259,7 @@ case $with_sysroot in #( fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -1291,7 +1289,7 @@ ia64-*-hpux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -1308,7 +1306,7 @@ ia64-*-hpux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -1320,7 +1318,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -1342,7 +1340,7 @@ mips64*-*linux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -1350,7 +1348,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -1358,7 +1356,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -1378,14 +1376,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -1453,7 +1451,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -1492,9 +1490,22 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cr} _LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because thats what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS +_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. +_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], + [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no @@ -1713,7 +1724,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1756,7 +1767,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -2206,26 +2217,35 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) @@ -2548,7 +2568,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; @@ -2558,14 +2578,14 @@ m4_if([$1], [],[ ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -2584,7 +2604,7 @@ m4_if([$1], [],[ done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -2621,7 +2641,7 @@ m4_if([$1], [],[ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -2654,7 +2674,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -3465,7 +3485,7 @@ beos*) bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -3499,14 +3519,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -3520,7 +3540,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' @@ -3567,7 +3587,7 @@ netbsd* | netbsdelf*-gnu) newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -3694,13 +3714,13 @@ else mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -3726,7 +3746,7 @@ else # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -3966,7 +3986,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -3984,20 +4004,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -4021,7 +4041,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ @@ -4039,9 +4059,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -4329,7 +4349,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -4412,7 +4432,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4754,7 +4774,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4937,7 +4957,7 @@ m4_if([$1], [CXX], [ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) @@ -4945,7 +4965,7 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -5005,15 +5025,15 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -5068,7 +5088,7 @@ dnl Note also adjust exclude_expsyms for C++ above. _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -5180,6 +5200,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) @@ -5194,7 +5215,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -5237,7 +5258,7 @@ _LT_EOF _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes @@ -5249,13 +5270,14 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -5265,7 +5287,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -5397,7 +5419,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -5580,12 +5602,12 @@ _LT_EOF cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5626,7 +5648,7 @@ _LT_EOF fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. @@ -5674,7 +5696,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5815,6 +5837,7 @@ _LT_EOF # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; @@ -5886,6 +5909,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) @@ -6656,8 +6680,8 @@ if test yes != "$_lt_caught_CXX_error"; then cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' @@ -6755,6 +6779,7 @@ if test yes != "$_lt_caught_CXX_error"; then emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) @@ -6785,7 +6810,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes @@ -6922,7 +6947,7 @@ if test yes != "$_lt_caught_CXX_error"; then # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -7062,13 +7087,13 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' @@ -8214,6 +8239,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) +# _LT_DECL_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_TOOL([FILECMD], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates diff --git a/third_party/protobuf/m4/ltoptions.m4 b/third_party/protobuf/m4/ltoptions.m4 index 94b08297..b0b5e9c2 100644 --- a/third_party/protobuf/m4/ltoptions.m4 +++ b/third_party/protobuf/m4/ltoptions.m4 @@ -1,7 +1,7 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free +# Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives diff --git a/third_party/protobuf/m4/ltsugar.m4 b/third_party/protobuf/m4/ltsugar.m4 index 48bc9344..902508bd 100644 --- a/third_party/protobuf/m4/ltsugar.m4 +++ b/third_party/protobuf/m4/ltsugar.m4 @@ -1,6 +1,6 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # diff --git a/third_party/protobuf/m4/ltversion.m4 b/third_party/protobuf/m4/ltversion.m4 index fa04b52a..b155d0ac 100644 --- a/third_party/protobuf/m4/ltversion.m4 +++ b/third_party/protobuf/m4/ltversion.m4 @@ -1,6 +1,7 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, +# Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +10,15 @@ # @configure_input@ -# serial 4179 ltversion.m4 +# serial 4245 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) +m4_define([LT_PACKAGE_VERSION], [2.4.7]) +m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' +[macro_version='2.4.7' +macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/third_party/protobuf/m4/lt~obsolete.m4 b/third_party/protobuf/m4/lt~obsolete.m4 index c6b26f88..0f7a8759 100644 --- a/third_party/protobuf/m4/lt~obsolete.m4 +++ b/third_party/protobuf/m4/lt~obsolete.m4 @@ -1,7 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free +# Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives diff --git a/third_party/protobuf/maven_install.json b/third_party/protobuf/maven_install.json new file mode 100644 index 00000000..9c5860a9 --- /dev/null +++ b/third_party/protobuf/maven_install.json @@ -0,0 +1,287 @@ +{ + "dependency_tree": { + "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", + "__INPUT_ARTIFACTS_HASH": -228414992, + "__RESOLVED_ARTIFACTS_HASH": -722345565, + "conflict_resolution": { + "com.google.errorprone:error_prone_annotations:2.3.2": "com.google.errorprone:error_prone_annotations:2.11.0", + "junit:junit:4.12": "junit:junit:4.13.2" + }, + "dependencies": [ + { + "coord": "com.google.auto.value:auto-value-annotations:1.7.4", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar", + "https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar" + ], + "sha256": "fedd59b0b4986c342f6ab2d182f2a4ee9fceb2c7e2d5bdc4dc764c92394a23d3", + "url": "https://repo1.maven.org/maven2/com/google/auto/value/auto-value-annotations/1.7.4/auto-value-annotations-1.7.4.jar" + }, + { + "coord": "com.google.code.findbugs:jsr305:3.0.2", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar", + "https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" + ], + "sha256": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", + "url": "https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" + }, + { + "coord": "com.google.code.gson:gson:2.8.9", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar", + "https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar" + ], + "sha256": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", + "url": "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar" + }, + { + "coord": "com.google.errorprone:error_prone_annotations:2.11.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar", + "https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar" + ], + "sha256": "721cb91842b46fa056847d104d5225c8b8e1e8b62263b993051e1e5a0137b7ec", + "url": "https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar" + }, + { + "coord": "com.google.guava:failureaccess:1.0.1", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar", + "https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" + ], + "sha256": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", + "url": "https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" + }, + { + "coord": "com.google.guava:guava-testlib:31.1-jre", + "dependencies": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:guava:31.1-jre", + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "com.google.j2objc:j2objc-annotations:1.3", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.12.0", + "org.hamcrest:hamcrest-core:1.3" + ], + "directDependencies": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:guava:31.1-jre", + "com.google.j2objc:j2objc-annotations:1.3", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.12.0" + ], + "file": "v1/https/repo1.maven.org/maven2/com/google/guava/guava-testlib/31.1-jre/guava-testlib-31.1-jre.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/guava/guava-testlib/31.1-jre/guava-testlib-31.1-jre.jar", + "https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/31.1-jre/guava-testlib-31.1-jre.jar" + ], + "sha256": "aadc71b10d5c3ac474dd16be84cfb18d257e584d1e0a59f8cab64ef4376226ce", + "url": "https://repo1.maven.org/maven2/com/google/guava/guava-testlib/31.1-jre/guava-testlib-31.1-jre.jar" + }, + { + "coord": "com.google.guava:guava:31.1-jre", + "dependencies": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "com.google.j2objc:j2objc-annotations:1.3", + "org.checkerframework:checker-qual:3.12.0" + ], + "directDependencies": [ + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "com.google.j2objc:j2objc-annotations:1.3", + "org.checkerframework:checker-qual:3.12.0" + ], + "file": "v1/https/repo1.maven.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar", + "https://repo.maven.apache.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar" + ], + "sha256": "a42edc9cab792e39fe39bb94f3fca655ed157ff87a8af78e1d6ba5b07c4a00ab", + "url": "https://repo1.maven.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar" + }, + { + "coord": "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar", + "https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" + ], + "sha256": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99", + "url": "https://repo1.maven.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" + }, + { + "coord": "com.google.j2objc:j2objc-annotations:1.3", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar", + "https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" + ], + "sha256": "21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b", + "url": "https://repo1.maven.org/maven2/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" + }, + { + "coord": "com.google.truth:truth:1.1.2", + "dependencies": [ + "com.google.auto.value:auto-value-annotations:1.7.4", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:guava:31.1-jre", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.12.0", + "org.ow2.asm:asm:9.0" + ], + "directDependencies": [ + "com.google.auto.value:auto-value-annotations:1.7.4", + "com.google.errorprone:error_prone_annotations:2.11.0", + "com.google.guava:guava:31.1-jre", + "junit:junit:4.13.2", + "org.checkerframework:checker-qual:3.12.0", + "org.ow2.asm:asm:9.0" + ], + "file": "v1/https/repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar", + "https://repo.maven.apache.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar" + ], + "sha256": "a85e03b8b6ae8780f060cfded9500a3d1b5f52808f99a2ea6da9c683313c7518", + "url": "https://repo1.maven.org/maven2/com/google/truth/truth/1.1.2/truth-1.1.2.jar" + }, + { + "coord": "junit:junit:4.13.2", + "dependencies": [ + "org.hamcrest:hamcrest-core:1.3" + ], + "directDependencies": [ + "org.hamcrest:hamcrest-core:1.3" + ], + "file": "v1/https/repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar", + "https://repo.maven.apache.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" + ], + "sha256": "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", + "url": "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar" + }, + { + "coord": "net.bytebuddy:byte-buddy-agent:1.12.7", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar", + "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar" + ], + "sha256": "73d84bb6e8e8980e674d796a29063f510ceb527c6f8c912a08a13e236be05c71", + "url": "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy-agent/1.12.7/byte-buddy-agent-1.12.7.jar" + }, + { + "coord": "net.bytebuddy:byte-buddy:1.12.7", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar", + "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar" + ], + "sha256": "d2e46555699e70361b5471a7e142f9c67855bba6907a285177ebd8ad973775d8", + "url": "https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy/1.12.7/byte-buddy-1.12.7.jar" + }, + { + "coord": "org.checkerframework:checker-qual:3.12.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar", + "https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar" + ], + "sha256": "ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb", + "url": "https://repo1.maven.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar" + }, + { + "coord": "org.hamcrest:hamcrest-core:1.3", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar", + "https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" + ], + "sha256": "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", + "url": "https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" + }, + { + "coord": "org.mockito:mockito-core:4.3.1", + "dependencies": [ + "net.bytebuddy:byte-buddy-agent:1.12.7", + "net.bytebuddy:byte-buddy:1.12.7", + "org.objenesis:objenesis:3.2" + ], + "directDependencies": [ + "net.bytebuddy:byte-buddy-agent:1.12.7", + "net.bytebuddy:byte-buddy:1.12.7", + "org.objenesis:objenesis:3.2" + ], + "file": "v1/https/repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar", + "https://repo.maven.apache.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar" + ], + "sha256": "148de2c6928365db29443ca12d35c930d9f481172b934fdd801d1cb1409ea83a", + "url": "https://repo1.maven.org/maven2/org/mockito/mockito-core/4.3.1/mockito-core-4.3.1.jar" + }, + { + "coord": "org.objenesis:objenesis:3.2", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar", + "https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar" + ], + "sha256": "03d960bd5aef03c653eb000413ada15eb77cdd2b8e4448886edf5692805e35f3", + "url": "https://repo1.maven.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.jar" + }, + { + "coord": "org.ow2.asm:asm:9.0", + "dependencies": [], + "directDependencies": [], + "file": "v1/https/repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar", + "mirror_urls": [ + "https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar", + "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar" + ], + "sha256": "0df97574914aee92fd349d0cb4e00f3345d45b2c239e0bb50f0a90ead47888e0", + "url": "https://repo1.maven.org/maven2/org/ow2/asm/asm/9.0/asm-9.0.jar" + } + ], + "version": "0.1.0" + } +} diff --git a/third_party/protobuf/php/BUILD.bazel b/third_party/protobuf/php/BUILD.bazel new file mode 100644 index 00000000..7fededad --- /dev/null +++ b/third_party/protobuf/php/BUILD.bazel @@ -0,0 +1,107 @@ +# Protobuf PHP runtime +# +# See also code generation logic under /src/google/protobuf/compiler/php. + +load("@rules_pkg//:pkg.bzl", "pkg_tar") +load("@rules_pkg//:mappings.bzl", "pkg_files", "pkg_filegroup", "strip_prefix") +load("//:protobuf_version.bzl", "PROTOBUF_PHP_VERSION") + +pkg_files( + name = "dist_files", + srcs = glob([ + "ext/google/protobuf/**/*", + "src/GPBMetadata/Google/Protobuf/**/*.php", + "src/Google/Protobuf/**/*.php", + "tests/*.php", + "tests/*.sh", + "tests/generated_previous/**/*.php", + "tests/proto/**/*.proto", + "tests/proto_previous/*.proto", + ]) + [ + "BUILD.bazel", + "README.md", + "REFCOUNTING.md", + "composer.json", + "generate_descriptor_protos.sh", + "generate_test_protos.sh", + "release.sh", + "src/phpdoc.dist.xml", + "tests/valgrind.supp", + ], + prefix = "php", + strip_prefix = strip_prefix.from_pkg(""), + visibility = ["//pkg:__pkg__"], +) + +################################################################################ +# PECL .tgz Release +################################################################################ + +pkg_files( + name = "php_ext_source_files", + srcs = glob([ + "ext/google/protobuf/*.h", + "ext/google/protobuf/*.c", + ]) + [ + "//:LICENSE", + "ext/google/protobuf/config.m4", + "ext/google/protobuf/wkt.inc", + ], +) + +pkg_files( + name = "utf8_range_files", + srcs = [ + "//third_party/utf8_range:utf8_range_srcs", + "//third_party/utf8_range:LICENSE", + + ], + prefix = "third_party/utf8_range", +) + +pkg_filegroup( + name = "pecl_release_files", + srcs = [ + ":php_ext_source_files", + ":utf8_range_files", + ], + prefix = "protobuf-%s" % PROTOBUF_PHP_VERSION, +) + +# PECL .tgz without package.xml +pkg_tar( + name = "release_without_package", + extension = "tgz", + srcs = [ + ":pecl_release_files", + ], + out = "release_without_package.tgz", +) + +# Generate PECL package.xml +genrule( + name = "generate_package_xml", + srcs = [ + ":release_without_package", + "ext/google/protobuf/template_package.xml", + ], + outs = ["package.xml"], + cmd = " ".join([ + "$(location ext/google/protobuf/generate_package_xml.sh)", + "$(location ext/google/protobuf/template_package.xml)", + PROTOBUF_PHP_VERSION, + "$$(tar -tf $(location :release_without_package) | sed -z -e 's;\\n;,;g')", + "$(location package.xml)" + ]), + tools = ["ext/google/protobuf/generate_package_xml.sh"], +) + +pkg_tar( + name = "release", + extension = "tgz", + srcs = [ + ":pecl_release_files", + ":generate_package_xml", + ], + out = "protobuf-%s.tgz" % PROTOBUF_PHP_VERSION, +) \ No newline at end of file diff --git a/third_party/protobuf/protobuf.bzl b/third_party/protobuf/protobuf.bzl index 97161281..c5b8dab3 100644 --- a/third_party/protobuf/protobuf.bzl +++ b/third_party/protobuf/protobuf.bzl @@ -79,10 +79,20 @@ def _proto_gen_impl(ctx): deps = depset(direct=ctx.files.srcs) source_dir = _SourceDir(ctx) gen_dir = _GenDir(ctx).rstrip("/") + import_flags = [] + if source_dir: - import_flags = depset(direct=["-I" + source_dir, "-I" + gen_dir]) + has_sources = any([src.is_source for src in srcs]) + if has_sources: + import_flags += ["-I" + source_dir] else: - import_flags = depset(direct=["-I."]) + import_flags += ["-I."] + + has_generated = any([not src.is_source for src in srcs]) + if has_generated: + import_flags += ["-I" + gen_dir] + + import_flags = depset(direct=import_flags) for dep in ctx.attr.deps: if type(dep.proto.import_flags) == "list": @@ -156,7 +166,7 @@ def _proto_gen_impl(ctx): for out in outs: orig_command = " ".join( ["$(realpath %s)" % ctx.executable.protoc.path] + args + - import_flags_real + ["-I.", src.basename], + import_flags_real + [src.basename], ) command = ";".join([ 'CMD="%s"' % orig_command, @@ -384,6 +394,70 @@ internal_gen_well_known_protos_java = rule( }, ) +def _internal_gen_kt_protos(ctx): + args = ctx.actions.args() + + deps = [d[ProtoInfo] for d in ctx.attr.deps] + + srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name)) + if ctx.attr.lite: + out = "lite:%s" % srcjar.path + else: + out = srcjar + + args.add("--kotlin_out", out) + + descriptors = depset( + transitive = [dep.transitive_descriptor_sets for dep in deps], + ) + args.add_joined( + "--descriptor_set_in", + descriptors, + join_with = ctx.configuration.host_path_separator, + ) + + for dep in deps: + if "." == dep.proto_source_root: + args.add_all([src.path for src in dep.direct_sources]) + else: + source_root = dep.proto_source_root + offset = len(source_root) + 1 # + '/'. + args.add_all([src.path[offset:] for src in dep.direct_sources]) + + ctx.actions.run( + executable = ctx.executable._protoc, + inputs = descriptors, + outputs = [srcjar], + arguments = [args], + use_default_shell_env = True, + ) + + return [ + DefaultInfo( + files = depset([srcjar]), + ), + ] + +internal_gen_kt_protos = rule( + implementation = _internal_gen_kt_protos, + attrs = { + "deps": attr.label_list( + mandatory = True, + providers = [ProtoInfo], + ), + "lite": attr.bool( + default = False, + ), + "_protoc": attr.label( + executable = True, + cfg = "exec", + default = "//:protoc", + ), + }, +) + + + def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): """Macro to copy files to a different directory and then create a filegroup. @@ -403,10 +477,12 @@ def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): name = name + "_genrule", srcs = srcs, outs = outs, - cmd = " && ".join( + cmd_bash = " && ".join( ["cp $(location %s) $(location %s)" % - (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs], - ), + (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]), + cmd_bat = " && ".join( + ["@copy /Y $(location %s) $(location %s) >NUL" % + (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]), ) native.filegroup( diff --git a/third_party/protobuf/protobuf_deps.bzl b/third_party/protobuf/protobuf_deps.bzl index 32f38ebb..0949ef37 100644 --- a/third_party/protobuf/protobuf_deps.bzl +++ b/third_party/protobuf/protobuf_deps.bzl @@ -4,15 +4,24 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") PROTOBUF_MAVEN_ARTIFACTS = [ "com.google.code.findbugs:jsr305:3.0.2", - "com.google.code.gson:gson:2.8.6", + "com.google.code.gson:gson:2.8.9", "com.google.errorprone:error_prone_annotations:2.3.2", "com.google.j2objc:j2objc-annotations:1.3", - "com.google.guava:guava:30.1.1-jre", + "com.google.guava:guava:31.1-jre", + "com.google.guava:guava-testlib:31.1-jre", "com.google.truth:truth:1.1.2", - "junit:junit:4.12", - "org.easymock:easymock:3.2", + "junit:junit:4.13.2", + "org.mockito:mockito-core:4.3.1", ] +def _github_archive(repo, commit, **kwargs): + repo_name = repo.split("/")[-1] + http_archive( + urls = [repo + "/archive/" + commit + ".zip"], + strip_prefix = repo_name + "-" + commit, + **kwargs + ) + def protobuf_deps(): """Loads common dependencies needed to compile the protobuf library.""" @@ -26,50 +35,88 @@ def protobuf_deps(): ], ) + if not native.existing_rule("com_google_absl"): + # Abseil LTS from November 2021 + _github_archive( + name = "com_google_absl", + repo = "https://github.com/abseil/abseil-cpp", + commit = "215105818dfde3174fe799600bb0f3cae233d0bf", + sha256 = "b4e20d9e752a75c10636675691b1e9c2698e0764cb404987d0ffa77223041c19", + ) + if not native.existing_rule("zlib"): http_archive( name = "zlib", build_file = "@com_google_protobuf//:third_party/zlib.BUILD", - sha256 = "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff", - strip_prefix = "zlib-1.2.11", - urls = ["https://github.com/madler/zlib/archive/v1.2.11.tar.gz"], + sha256 = "d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98", + strip_prefix = "zlib-1.2.13", + urls = [ + "https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.xz", + "https://zlib.net/zlib-1.2.13.tar.xz", + ], ) if not native.existing_rule("rules_cc"): - http_archive( + _github_archive( name = "rules_cc", - sha256 = "9d48151ea71b3e225adfb6867e6d2c7d0dce46cbdc8710d9a9a628574dfd40a0", - strip_prefix = "rules_cc-818289e5613731ae410efb54218a4077fb9dbb03", - urls = ["https://github.com/bazelbuild/rules_cc/archive/818289e5613731ae410efb54218a4077fb9dbb03.tar.gz"], + repo = "https://github.com/bazelbuild/rules_cc", + commit = "818289e5613731ae410efb54218a4077fb9dbb03", + sha256 = "0adbd6f567291ad526e82c765e15aed33cea5e256eeba129f1501142c2c56610", ) if not native.existing_rule("rules_java"): - http_archive( + _github_archive( name = "rules_java", - sha256 = "f5a3e477e579231fca27bf202bb0e8fbe4fc6339d63b38ccb87c2760b533d1c3", - strip_prefix = "rules_java-981f06c3d2bd10225e85209904090eb7b5fb26bd", - urls = ["https://github.com/bazelbuild/rules_java/archive/981f06c3d2bd10225e85209904090eb7b5fb26bd.tar.gz"], + repo = "https://github.com/bazelbuild/rules_java", + commit = "981f06c3d2bd10225e85209904090eb7b5fb26bd", + sha256 = "7979ece89e82546b0dcd1dff7538c34b5a6ebc9148971106f0e3705444f00665", ) if not native.existing_rule("rules_proto"): - http_archive( + _github_archive( name = "rules_proto", + repo = "https://github.com/bazelbuild/rules_proto", + commit = "f7a30f6f80006b591fa7c437fe5a951eb10bcbcf", sha256 = "a4382f78723af788f0bc19fd4c8411f44ffe0a72723670a34692ffad56ada3ac", - strip_prefix = "rules_proto-f7a30f6f80006b591fa7c437fe5a951eb10bcbcf", - urls = ["https://github.com/bazelbuild/rules_proto/archive/f7a30f6f80006b591fa7c437fe5a951eb10bcbcf.zip"], ) if not native.existing_rule("rules_python"): http_archive( name = "rules_python", - sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0", - urls = ["https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz"], + sha256 = "9fcf91dbcc31fde6d1edb15f117246d912c33c36f44cf681976bd886538deba6", + strip_prefix = "rules_python-0.8.0", + url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.8.0.tar.gz", ) if not native.existing_rule("rules_jvm_external"): - http_archive( + _github_archive( name = "rules_jvm_external", - sha256 = "f36441aa876c4f6427bfb2d1f2d723b48e9d930b62662bf723ddfb8fc80f0140", - strip_prefix = "rules_jvm_external-4.1", - urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/4.1.zip"], + repo = "https://github.com/bazelbuild/rules_jvm_external", + commit = "906875b0d5eaaf61a8ca2c9c3835bde6f435d011", + sha256 = "744bd7436f63af7e9872948773b8b106016dc164acb3960b4963f86754532ee7", + ) + + if not native.existing_rule("rules_pkg"): + http_archive( + name = "rules_pkg", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", + "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", + ], + sha256 = "8a298e832762eda1830597d64fe7db58178aa84cd5926d76d5b744d6558941c2", + ) + + if not native.existing_rule("io_bazel_rules_kotlin"): + http_archive( + name = "io_bazel_rules_kotlin", + urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.5.0-beta-4/rules_kotlin_release.tgz"], + sha256 = "6cbd4e5768bdfae1598662e40272729ec9ece8b7bded8f0d2c81c8ff96dc139d", + ) + + if not native.existing_rule("upb"): + _github_archive( + name = "upb", + repo = "https://github.com/protocolbuffers/upb", + commit = "20b542a767139732548f7b8cf28c4c928cdcb07b", + sha256 = "c77158955326f9e9a0cf8481c118b8ad5c34df99e5db3af27f3d1662d8bedef7", ) diff --git a/third_party/protobuf/protobuf_release.bzl b/third_party/protobuf/protobuf_release.bzl new file mode 100644 index 00000000..327ae9a0 --- /dev/null +++ b/third_party/protobuf/protobuf_release.bzl @@ -0,0 +1,50 @@ +""" +Generates package naming variables for use with rules_pkg. +""" + +load("@rules_pkg//:providers.bzl", "PackageVariablesInfo") +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load(":protobuf_version.bzl", "PROTOC_VERSION") + +def _package_naming_impl(ctx): + values = {} + values["version"] = PROTOC_VERSION + + # infer from the current cpp toolchain. + toolchain = find_cpp_toolchain(ctx) + cpu = toolchain.cpu + system_name = toolchain.target_gnu_system_name + + # rename cpus to match what we want artifacts to be + if cpu == "systemz": + cpu = "s390_64" + elif cpu == "aarch64": + cpu = "aarch_64" + elif cpu == "ppc64": + cpu = "ppcle_64" + + # use the system name to determine the os and then create platform names + if "apple" in system_name: + values["platform"] = "osx-" + cpu + elif "linux" in system_name: + values["platform"] = "linux-" + cpu + elif "mingw" in system_name: + if cpu == "x86_64": + values["platform"] = "win64" + else: + values["platform"] = "win32" + else: + values["platform"] = "unknown" + + return PackageVariablesInfo(values = values) + + +package_naming = rule( + implementation = _package_naming_impl, + attrs = { + # Necessary data dependency for find_cpp_toolchain. + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + incompatible_use_toolchain_transition = True, +) diff --git a/third_party/protobuf/protobuf_version.bzl b/third_party/protobuf/protobuf_version.bzl index 31ce2e3b..4ac031cb 100644 --- a/third_party/protobuf/protobuf_version.bzl +++ b/third_party/protobuf/protobuf_version.bzl @@ -1 +1,4 @@ -PROTOBUF_VERSION = '3.19.1' +PROTOC_VERSION = "21.12" +PROTOBUF_JAVA_VERSION = "3.21.12" +PROTOBUF_PYTHON_VERSION = "4.21.12" +PROTOBUF_PHP_VERSION = "3.21.12" diff --git a/third_party/protobuf/ruby/BUILD.bazel b/third_party/protobuf/ruby/BUILD.bazel new file mode 100644 index 00000000..fe336e54 --- /dev/null +++ b/third_party/protobuf/ruby/BUILD.bazel @@ -0,0 +1,34 @@ +# Protobuf Ruby runtime +# +# See also code generation logic under /src/google/protobuf/compiler/ruby. + +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") + +pkg_files( + name = "dist_files", + srcs = glob([ + "compatibility_tests/v3.0.0/**/*", + "ext/google/protobuf_c/*", + "src/main/java/com/google/protobuf/jruby/*.java", + "tests/*.proto", + "tests/*.rb", + ]) + [ + ".gitignore", + "BUILD.bazel", + "Gemfile", + "README.md", + "Rakefile", + "google-protobuf.gemspec", + "lib/google/protobuf.rb", + "lib/google/protobuf/descriptor_dsl.rb", + "lib/google/protobuf/message_exts.rb", + "lib/google/protobuf/repeated_field.rb", + "lib/google/protobuf/well_known_types.rb", + "pom.xml", + "src/main/java/google/ProtobufJavaService.java", + "src/main/sentinel.proto", + "travis-test.sh", + ], + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) diff --git a/third_party/protobuf/src/Makefile.am b/third_party/protobuf/src/Makefile.am index 2d6034a0..f48f7d44 100644 --- a/third_party/protobuf/src/Makefile.am +++ b/third_party/protobuf/src/Makefile.am @@ -18,7 +18,7 @@ else PTHREAD_DEF = endif -PROTOBUF_VERSION = 30:1:0 +PROTOBUF_VERSION = 32:12:0 if GCC # Turn on all warnings except for sign comparison (we ignore sign comparison @@ -71,27 +71,31 @@ nobase_include_HEADERS = \ google/protobuf/arena.h \ google/protobuf/arena_impl.h \ google/protobuf/arenastring.h \ + google/protobuf/arenaz_sampler.h \ google/protobuf/compiler/code_generator.h \ google/protobuf/compiler/command_line_interface.h \ - google/protobuf/compiler/cpp/cpp_file.h \ google/protobuf/compiler/cpp/cpp_generator.h \ - google/protobuf/compiler/cpp/cpp_helpers.h \ - google/protobuf/compiler/cpp/cpp_names.h \ + google/protobuf/compiler/cpp/file.h \ + google/protobuf/compiler/cpp/generator.h \ + google/protobuf/compiler/cpp/helpers.h \ + google/protobuf/compiler/cpp/names.h \ google/protobuf/compiler/csharp/csharp_doc_comment.h \ google/protobuf/compiler/csharp/csharp_generator.h \ google/protobuf/compiler/csharp/csharp_names.h \ google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/importer.h \ + google/protobuf/compiler/java/generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/java/java_kotlin_generator.h \ - google/protobuf/compiler/java/java_names.h \ - google/protobuf/compiler/js/js_generator.h \ + google/protobuf/compiler/java/kotlin_generator.h \ + google/protobuf/compiler/java/names.h \ google/protobuf/compiler/objectivec/objectivec_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers.h \ google/protobuf/compiler/parser.h \ google/protobuf/compiler/php/php_generator.h \ google/protobuf/compiler/plugin.h \ google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/python/generator.h \ + google/protobuf/compiler/python/pyi_generator.h \ google/protobuf/compiler/python/python_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/descriptor.h \ @@ -100,6 +104,7 @@ nobase_include_HEADERS = \ google/protobuf/duration.pb.h \ google/protobuf/dynamic_message.h \ google/protobuf/empty.pb.h \ + google/protobuf/endian.h \ google/protobuf/explicitly_constructed.h \ google/protobuf/extension_set.h \ google/protobuf/extension_set_inl.h \ @@ -109,11 +114,8 @@ nobase_include_HEADERS = \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_bases.h \ google/protobuf/generated_message_reflection.h \ - google/protobuf/generated_message_table_driven.h \ - google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_tctable_decl.h \ google/protobuf/generated_message_tctable_impl.h \ - google/protobuf/generated_message_tctable_impl.inc \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ @@ -143,6 +145,7 @@ nobase_include_HEADERS = \ google/protobuf/port_def.inc \ google/protobuf/port_undef.inc \ google/protobuf/reflection.h \ + google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.h \ google/protobuf/repeated_field.h \ google/protobuf/repeated_ptr_field.h \ @@ -194,9 +197,9 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/any_lite.cc \ google/protobuf/arena.cc \ google/protobuf/arenastring.cc \ + google/protobuf/arenaz_sampler.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_enum_util.cc \ - google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/generated_message_tctable_lite.cc \ google/protobuf/generated_message_util.cc \ google/protobuf/implicit_weak_message.cc \ @@ -254,14 +257,12 @@ libprotobuf_la_SOURCES = \ google/protobuf/field_mask.pb.cc \ google/protobuf/generated_message_bases.cc \ google/protobuf/generated_message_reflection.cc \ - google/protobuf/generated_message_table_driven.cc \ google/protobuf/generated_message_tctable_full.cc \ google/protobuf/io/gzip_stream.cc \ google/protobuf/io/printer.cc \ google/protobuf/io/tokenizer.cc \ google/protobuf/map_field.cc \ google/protobuf/message.cc \ - google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.cc \ google/protobuf/service.cc \ google/protobuf/source_context.pb.cc \ @@ -327,35 +328,35 @@ endif libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ - google/protobuf/compiler/cpp/cpp_enum.cc \ - google/protobuf/compiler/cpp/cpp_enum.h \ - google/protobuf/compiler/cpp/cpp_enum_field.cc \ - google/protobuf/compiler/cpp/cpp_enum_field.h \ - google/protobuf/compiler/cpp/cpp_extension.cc \ - google/protobuf/compiler/cpp/cpp_extension.h \ - google/protobuf/compiler/cpp/cpp_field.cc \ - google/protobuf/compiler/cpp/cpp_field.h \ - google/protobuf/compiler/cpp/cpp_file.cc \ - google/protobuf/compiler/cpp/cpp_generator.cc \ - google/protobuf/compiler/cpp/cpp_helpers.cc \ - google/protobuf/compiler/cpp/cpp_map_field.cc \ - google/protobuf/compiler/cpp/cpp_map_field.h \ - google/protobuf/compiler/cpp/cpp_message.cc \ - google/protobuf/compiler/cpp/cpp_message.h \ - google/protobuf/compiler/cpp/cpp_message_field.cc \ - google/protobuf/compiler/cpp/cpp_message_field.h \ - google/protobuf/compiler/cpp/cpp_message_layout_helper.h \ - google/protobuf/compiler/cpp/cpp_options.h \ - google/protobuf/compiler/cpp/cpp_padding_optimizer.cc \ - google/protobuf/compiler/cpp/cpp_padding_optimizer.h \ - google/protobuf/compiler/cpp/cpp_parse_function_generator.cc \ - google/protobuf/compiler/cpp/cpp_parse_function_generator.h \ - google/protobuf/compiler/cpp/cpp_primitive_field.cc \ - google/protobuf/compiler/cpp/cpp_primitive_field.h \ - google/protobuf/compiler/cpp/cpp_service.cc \ - google/protobuf/compiler/cpp/cpp_service.h \ - google/protobuf/compiler/cpp/cpp_string_field.cc \ - google/protobuf/compiler/cpp/cpp_string_field.h \ + google/protobuf/compiler/cpp/enum.cc \ + google/protobuf/compiler/cpp/enum.h \ + google/protobuf/compiler/cpp/enum_field.cc \ + google/protobuf/compiler/cpp/enum_field.h \ + google/protobuf/compiler/cpp/extension.cc \ + google/protobuf/compiler/cpp/extension.h \ + google/protobuf/compiler/cpp/field.cc \ + google/protobuf/compiler/cpp/field.h \ + google/protobuf/compiler/cpp/file.cc \ + google/protobuf/compiler/cpp/generator.cc \ + google/protobuf/compiler/cpp/helpers.cc \ + google/protobuf/compiler/cpp/map_field.cc \ + google/protobuf/compiler/cpp/map_field.h \ + google/protobuf/compiler/cpp/message.cc \ + google/protobuf/compiler/cpp/message.h \ + google/protobuf/compiler/cpp/message_field.cc \ + google/protobuf/compiler/cpp/message_field.h \ + google/protobuf/compiler/cpp/message_layout_helper.h \ + google/protobuf/compiler/cpp/options.h \ + google/protobuf/compiler/cpp/padding_optimizer.cc \ + google/protobuf/compiler/cpp/padding_optimizer.h \ + google/protobuf/compiler/cpp/parse_function_generator.cc \ + google/protobuf/compiler/cpp/parse_function_generator.h \ + google/protobuf/compiler/cpp/primitive_field.cc \ + google/protobuf/compiler/cpp/primitive_field.h \ + google/protobuf/compiler/cpp/service.cc \ + google/protobuf/compiler/cpp/service.h \ + google/protobuf/compiler/cpp/string_field.cc \ + google/protobuf/compiler/cpp/string_field.h \ google/protobuf/compiler/csharp/csharp_doc_comment.cc \ google/protobuf/compiler/csharp/csharp_enum.cc \ google/protobuf/compiler/csharp/csharp_enum.h \ @@ -386,66 +387,63 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_source_generator_base.h \ google/protobuf/compiler/csharp/csharp_wrapper_field.cc \ google/protobuf/compiler/csharp/csharp_wrapper_field.h \ - google/protobuf/compiler/java/java_context.cc \ - google/protobuf/compiler/java/java_context.h \ - google/protobuf/compiler/java/java_doc_comment.cc \ - google/protobuf/compiler/java/java_doc_comment.h \ - google/protobuf/compiler/java/java_enum.cc \ - google/protobuf/compiler/java/java_enum.h \ - google/protobuf/compiler/java/java_enum_field.cc \ - google/protobuf/compiler/java/java_enum_field.h \ - google/protobuf/compiler/java/java_enum_field_lite.cc \ - google/protobuf/compiler/java/java_enum_field_lite.h \ - google/protobuf/compiler/java/java_enum_lite.cc \ - google/protobuf/compiler/java/java_enum_lite.h \ - google/protobuf/compiler/java/java_extension.cc \ - google/protobuf/compiler/java/java_extension.h \ - google/protobuf/compiler/java/java_extension_lite.cc \ - google/protobuf/compiler/java/java_extension_lite.h \ - google/protobuf/compiler/java/java_field.cc \ - google/protobuf/compiler/java/java_field.h \ - google/protobuf/compiler/java/java_file.cc \ - google/protobuf/compiler/java/java_file.h \ - google/protobuf/compiler/java/java_generator.cc \ - google/protobuf/compiler/java/java_generator_factory.cc \ - google/protobuf/compiler/java/java_generator_factory.h \ - google/protobuf/compiler/java/java_helpers.cc \ - google/protobuf/compiler/java/java_helpers.h \ - google/protobuf/compiler/java/java_kotlin_generator.cc \ - google/protobuf/compiler/java/java_map_field.cc \ - google/protobuf/compiler/java/java_map_field.h \ - google/protobuf/compiler/java/java_map_field_lite.cc \ - google/protobuf/compiler/java/java_map_field_lite.h \ - google/protobuf/compiler/java/java_message.cc \ - google/protobuf/compiler/java/java_message.h \ - google/protobuf/compiler/java/java_message_builder.cc \ - google/protobuf/compiler/java/java_message_builder.h \ - google/protobuf/compiler/java/java_message_builder_lite.cc \ - google/protobuf/compiler/java/java_message_builder_lite.h \ - google/protobuf/compiler/java/java_message_field.cc \ - google/protobuf/compiler/java/java_message_field.h \ - google/protobuf/compiler/java/java_message_field_lite.cc \ - google/protobuf/compiler/java/java_message_field_lite.h \ - google/protobuf/compiler/java/java_message_lite.cc \ - google/protobuf/compiler/java/java_message_lite.h \ - google/protobuf/compiler/java/java_name_resolver.cc \ - google/protobuf/compiler/java/java_name_resolver.h \ - google/protobuf/compiler/java/java_options.h \ - google/protobuf/compiler/java/java_primitive_field.cc \ - google/protobuf/compiler/java/java_primitive_field.h \ - google/protobuf/compiler/java/java_primitive_field_lite.cc \ - google/protobuf/compiler/java/java_primitive_field_lite.h \ - google/protobuf/compiler/java/java_service.cc \ - google/protobuf/compiler/java/java_service.h \ - google/protobuf/compiler/java/java_shared_code_generator.cc \ - google/protobuf/compiler/java/java_shared_code_generator.h \ - google/protobuf/compiler/java/java_string_field.cc \ - google/protobuf/compiler/java/java_string_field.h \ - google/protobuf/compiler/java/java_string_field_lite.cc \ - google/protobuf/compiler/java/java_string_field_lite.h \ - google/protobuf/compiler/js/js_generator.cc \ - google/protobuf/compiler/js/well_known_types_embed.cc \ - google/protobuf/compiler/js/well_known_types_embed.h \ + google/protobuf/compiler/java/context.cc \ + google/protobuf/compiler/java/context.h \ + google/protobuf/compiler/java/doc_comment.cc \ + google/protobuf/compiler/java/doc_comment.h \ + google/protobuf/compiler/java/enum.cc \ + google/protobuf/compiler/java/enum.h \ + google/protobuf/compiler/java/enum_field.cc \ + google/protobuf/compiler/java/enum_field.h \ + google/protobuf/compiler/java/enum_field_lite.cc \ + google/protobuf/compiler/java/enum_field_lite.h \ + google/protobuf/compiler/java/enum_lite.cc \ + google/protobuf/compiler/java/enum_lite.h \ + google/protobuf/compiler/java/extension.cc \ + google/protobuf/compiler/java/extension.h \ + google/protobuf/compiler/java/extension_lite.cc \ + google/protobuf/compiler/java/extension_lite.h \ + google/protobuf/compiler/java/field.cc \ + google/protobuf/compiler/java/field.h \ + google/protobuf/compiler/java/file.cc \ + google/protobuf/compiler/java/file.h \ + google/protobuf/compiler/java/generator.cc \ + google/protobuf/compiler/java/generator_factory.cc \ + google/protobuf/compiler/java/generator_factory.h \ + google/protobuf/compiler/java/helpers.cc \ + google/protobuf/compiler/java/helpers.h \ + google/protobuf/compiler/java/kotlin_generator.cc \ + google/protobuf/compiler/java/map_field.cc \ + google/protobuf/compiler/java/map_field.h \ + google/protobuf/compiler/java/map_field_lite.cc \ + google/protobuf/compiler/java/map_field_lite.h \ + google/protobuf/compiler/java/message.cc \ + google/protobuf/compiler/java/message.h \ + google/protobuf/compiler/java/message_builder.cc \ + google/protobuf/compiler/java/message_builder.h \ + google/protobuf/compiler/java/message_builder_lite.cc \ + google/protobuf/compiler/java/message_builder_lite.h \ + google/protobuf/compiler/java/message_field.cc \ + google/protobuf/compiler/java/message_field.h \ + google/protobuf/compiler/java/message_field_lite.cc \ + google/protobuf/compiler/java/message_field_lite.h \ + google/protobuf/compiler/java/message_lite.cc \ + google/protobuf/compiler/java/message_lite.h \ + google/protobuf/compiler/java/name_resolver.cc \ + google/protobuf/compiler/java/name_resolver.h \ + google/protobuf/compiler/java/options.h \ + google/protobuf/compiler/java/primitive_field.cc \ + google/protobuf/compiler/java/primitive_field.h \ + google/protobuf/compiler/java/primitive_field_lite.cc \ + google/protobuf/compiler/java/primitive_field_lite.h \ + google/protobuf/compiler/java/service.cc \ + google/protobuf/compiler/java/service.h \ + google/protobuf/compiler/java/shared_code_generator.cc \ + google/protobuf/compiler/java/shared_code_generator.h \ + google/protobuf/compiler/java/string_field.cc \ + google/protobuf/compiler/java/string_field.h \ + google/protobuf/compiler/java/string_field_lite.cc \ + google/protobuf/compiler/java/string_field_lite.h \ google/protobuf/compiler/objectivec/objectivec_enum.cc \ google/protobuf/compiler/objectivec/objectivec_enum.h \ google/protobuf/compiler/objectivec/objectivec_enum_field.cc \ @@ -472,7 +470,10 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/php/php_generator.cc \ google/protobuf/compiler/plugin.cc \ google/protobuf/compiler/plugin.pb.cc \ - google/protobuf/compiler/python/python_generator.cc \ + google/protobuf/compiler/python/generator.cc \ + google/protobuf/compiler/python/helpers.cc \ + google/protobuf/compiler/python/helpers.h \ + google/protobuf/compiler/python/pyi_generator.cc \ google/protobuf/compiler/ruby/ruby_generator.cc \ google/protobuf/compiler/scc.h \ google/protobuf/compiler/subprocess.cc \ @@ -488,8 +489,8 @@ protoc_SOURCES = google/protobuf/compiler/main.cc protoc_inputs = \ google/protobuf/any_test.proto \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto \ + google/protobuf/compiler/cpp/test_bad_identifiers.proto \ + google/protobuf/compiler/cpp/test_large_enum_value.proto \ google/protobuf/map_lite_unittest.proto \ google/protobuf/map_proto2_unittest.proto \ google/protobuf/map_unittest.proto \ @@ -592,10 +593,10 @@ protoc_outputs = \ $(protoc_lite_outputs) \ google/protobuf/any_test.pb.cc \ google/protobuf/any_test.pb.h \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.h \ + google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc \ + google/protobuf/compiler/cpp/test_bad_identifiers.pb.h \ + google/protobuf/compiler/cpp/test_large_enum_value.pb.cc \ + google/protobuf/compiler/cpp/test_large_enum_value.pb.h \ google/protobuf/map_proto2_unittest.pb.cc \ google/protobuf/map_proto2_unittest.pb.h \ google/protobuf/map_unittest.pb.cc \ @@ -702,7 +703,7 @@ $(protoc_outputs): unittest_proto_middleman COMMON_TEST_SOURCES = \ $(COMMON_LITE_TEST_SOURCES) \ - google/protobuf/compiler/cpp/cpp_unittest.h \ + google/protobuf/compiler/cpp/unittest.h \ google/protobuf/map_test_util.h \ google/protobuf/map_test_util.inc \ google/protobuf/reflection_tester.cc \ @@ -738,25 +739,27 @@ protobuf_test_SOURCES = \ google/protobuf/any_test.cc \ google/protobuf/arena_unittest.cc \ google/protobuf/arenastring_unittest.cc \ + google/protobuf/arenaz_sampler_test.cc \ google/protobuf/compiler/annotation_test_util.cc \ google/protobuf/compiler/annotation_test_util.h \ google/protobuf/compiler/command_line_interface_unittest.cc \ - google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ - google/protobuf/compiler/cpp/cpp_move_unittest.cc \ - google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ - google/protobuf/compiler/cpp/cpp_unittest.cc \ - google/protobuf/compiler/cpp/cpp_unittest.inc \ + google/protobuf/compiler/cpp/bootstrap_unittest.cc \ + google/protobuf/compiler/cpp/message_size_unittest.cc \ google/protobuf/compiler/cpp/metadata_test.cc \ + google/protobuf/compiler/cpp/move_unittest.cc \ + google/protobuf/compiler/cpp/plugin_unittest.cc \ + google/protobuf/compiler/cpp/unittest.cc \ + google/protobuf/compiler/cpp/unittest.inc \ google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc \ google/protobuf/compiler/csharp/csharp_generator_unittest.cc \ google/protobuf/compiler/importer_unittest.cc \ - google/protobuf/compiler/java/java_doc_comment_unittest.cc \ - google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/java/doc_comment_unittest.cc \ + google/protobuf/compiler/java/plugin_unittest.cc \ google/protobuf/compiler/mock_code_generator.cc \ google/protobuf/compiler/mock_code_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc \ google/protobuf/compiler/parser_unittest.cc \ - google/protobuf/compiler/python/python_plugin_unittest.cc \ + google/protobuf/compiler/python/plugin_unittest.cc \ google/protobuf/compiler/ruby/ruby_generator_unittest.cc \ google/protobuf/descriptor_database_unittest.cc \ google/protobuf/descriptor_unittest.cc \ @@ -764,6 +767,7 @@ protobuf_test_SOURCES = \ google/protobuf/dynamic_message_unittest.cc \ google/protobuf/extension_set_unittest.cc \ google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/generated_message_tctable_lite_test.cc \ google/protobuf/inlined_string_field_unittest.cc \ google/protobuf/io/coded_stream_unittest.cc \ google/protobuf/io/io_win32_unittest.cc \ @@ -828,7 +832,7 @@ protobuf_lazy_descriptor_test_CPPFLAGS = -I$(GOOGLEMOCK_SRC_DIR)/include \ -DPROTOBUF_TEST_NO_DESCRIPTORS protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) protobuf_lazy_descriptor_test_SOURCES = \ - google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/unittest.cc \ $(COMMON_TEST_SOURCES) nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs) $(am_protobuf_lazy_descriptor_test_OBJECTS): unittest_proto_middleman diff --git a/third_party/protobuf/src/Makefile.in b/third_party/protobuf/src/Makefile.in index 9dc5a69d..96dbc42a 100644 --- a/third_party/protobuf/src/Makefile.in +++ b/third_party/protobuf/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.16.4 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. @@ -163,9 +163,9 @@ libprotobuf_lite_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ am__dirstamp = $(am__leading_dot)dirstamp am_libprotobuf_lite_la_OBJECTS = google/protobuf/any_lite.lo \ google/protobuf/arena.lo google/protobuf/arenastring.lo \ + google/protobuf/arenaz_sampler.lo \ google/protobuf/extension_set.lo \ google/protobuf/generated_enum_util.lo \ - google/protobuf/generated_message_table_driven_lite.lo \ google/protobuf/generated_message_tctable_lite.lo \ google/protobuf/generated_message_util.lo \ google/protobuf/implicit_weak_message.lo \ @@ -202,9 +202,9 @@ libprotobuf_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__objects_1 = google/protobuf/any_lite.lo google/protobuf/arena.lo \ google/protobuf/arenastring.lo \ + google/protobuf/arenaz_sampler.lo \ google/protobuf/extension_set.lo \ google/protobuf/generated_enum_util.lo \ - google/protobuf/generated_message_table_driven_lite.lo \ google/protobuf/generated_message_tctable_lite.lo \ google/protobuf/generated_message_util.lo \ google/protobuf/implicit_weak_message.lo \ @@ -240,7 +240,6 @@ am_libprotobuf_la_OBJECTS = $(am__objects_1) google/protobuf/any.lo \ google/protobuf/field_mask.pb.lo \ google/protobuf/generated_message_bases.lo \ google/protobuf/generated_message_reflection.lo \ - google/protobuf/generated_message_table_driven.lo \ google/protobuf/generated_message_tctable_full.lo \ google/protobuf/io/gzip_stream.lo \ google/protobuf/io/printer.lo google/protobuf/io/tokenizer.lo \ @@ -283,21 +282,21 @@ libprotobuf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ libprotoc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la am_libprotoc_la_OBJECTS = google/protobuf/compiler/code_generator.lo \ google/protobuf/compiler/command_line_interface.lo \ - google/protobuf/compiler/cpp/cpp_enum.lo \ - google/protobuf/compiler/cpp/cpp_enum_field.lo \ - google/protobuf/compiler/cpp/cpp_extension.lo \ - google/protobuf/compiler/cpp/cpp_field.lo \ - google/protobuf/compiler/cpp/cpp_file.lo \ - google/protobuf/compiler/cpp/cpp_generator.lo \ - google/protobuf/compiler/cpp/cpp_helpers.lo \ - google/protobuf/compiler/cpp/cpp_map_field.lo \ - google/protobuf/compiler/cpp/cpp_message.lo \ - google/protobuf/compiler/cpp/cpp_message_field.lo \ - google/protobuf/compiler/cpp/cpp_padding_optimizer.lo \ - google/protobuf/compiler/cpp/cpp_parse_function_generator.lo \ - google/protobuf/compiler/cpp/cpp_primitive_field.lo \ - google/protobuf/compiler/cpp/cpp_service.lo \ - google/protobuf/compiler/cpp/cpp_string_field.lo \ + google/protobuf/compiler/cpp/enum.lo \ + google/protobuf/compiler/cpp/enum_field.lo \ + google/protobuf/compiler/cpp/extension.lo \ + google/protobuf/compiler/cpp/field.lo \ + google/protobuf/compiler/cpp/file.lo \ + google/protobuf/compiler/cpp/generator.lo \ + google/protobuf/compiler/cpp/helpers.lo \ + google/protobuf/compiler/cpp/map_field.lo \ + google/protobuf/compiler/cpp/message.lo \ + google/protobuf/compiler/cpp/message_field.lo \ + google/protobuf/compiler/cpp/padding_optimizer.lo \ + google/protobuf/compiler/cpp/parse_function_generator.lo \ + google/protobuf/compiler/cpp/primitive_field.lo \ + google/protobuf/compiler/cpp/service.lo \ + google/protobuf/compiler/cpp/string_field.lo \ google/protobuf/compiler/csharp/csharp_doc_comment.lo \ google/protobuf/compiler/csharp/csharp_enum.lo \ google/protobuf/compiler/csharp/csharp_enum_field.lo \ @@ -314,37 +313,35 @@ am_libprotoc_la_OBJECTS = google/protobuf/compiler/code_generator.lo \ google/protobuf/compiler/csharp/csharp_repeated_primitive_field.lo \ google/protobuf/compiler/csharp/csharp_source_generator_base.lo \ google/protobuf/compiler/csharp/csharp_wrapper_field.lo \ - google/protobuf/compiler/java/java_context.lo \ - google/protobuf/compiler/java/java_doc_comment.lo \ - google/protobuf/compiler/java/java_enum.lo \ - google/protobuf/compiler/java/java_enum_field.lo \ - google/protobuf/compiler/java/java_enum_field_lite.lo \ - google/protobuf/compiler/java/java_enum_lite.lo \ - google/protobuf/compiler/java/java_extension.lo \ - google/protobuf/compiler/java/java_extension_lite.lo \ - google/protobuf/compiler/java/java_field.lo \ - google/protobuf/compiler/java/java_file.lo \ - google/protobuf/compiler/java/java_generator.lo \ - google/protobuf/compiler/java/java_generator_factory.lo \ - google/protobuf/compiler/java/java_helpers.lo \ - google/protobuf/compiler/java/java_kotlin_generator.lo \ - google/protobuf/compiler/java/java_map_field.lo \ - google/protobuf/compiler/java/java_map_field_lite.lo \ - google/protobuf/compiler/java/java_message.lo \ - google/protobuf/compiler/java/java_message_builder.lo \ - google/protobuf/compiler/java/java_message_builder_lite.lo \ - google/protobuf/compiler/java/java_message_field.lo \ - google/protobuf/compiler/java/java_message_field_lite.lo \ - google/protobuf/compiler/java/java_message_lite.lo \ - google/protobuf/compiler/java/java_name_resolver.lo \ - google/protobuf/compiler/java/java_primitive_field.lo \ - google/protobuf/compiler/java/java_primitive_field_lite.lo \ - google/protobuf/compiler/java/java_service.lo \ - google/protobuf/compiler/java/java_shared_code_generator.lo \ - google/protobuf/compiler/java/java_string_field.lo \ - google/protobuf/compiler/java/java_string_field_lite.lo \ - google/protobuf/compiler/js/js_generator.lo \ - google/protobuf/compiler/js/well_known_types_embed.lo \ + google/protobuf/compiler/java/context.lo \ + google/protobuf/compiler/java/doc_comment.lo \ + google/protobuf/compiler/java/enum.lo \ + google/protobuf/compiler/java/enum_field.lo \ + google/protobuf/compiler/java/enum_field_lite.lo \ + google/protobuf/compiler/java/enum_lite.lo \ + google/protobuf/compiler/java/extension.lo \ + google/protobuf/compiler/java/extension_lite.lo \ + google/protobuf/compiler/java/field.lo \ + google/protobuf/compiler/java/file.lo \ + google/protobuf/compiler/java/generator.lo \ + google/protobuf/compiler/java/generator_factory.lo \ + google/protobuf/compiler/java/helpers.lo \ + google/protobuf/compiler/java/kotlin_generator.lo \ + google/protobuf/compiler/java/map_field.lo \ + google/protobuf/compiler/java/map_field_lite.lo \ + google/protobuf/compiler/java/message.lo \ + google/protobuf/compiler/java/message_builder.lo \ + google/protobuf/compiler/java/message_builder_lite.lo \ + google/protobuf/compiler/java/message_field.lo \ + google/protobuf/compiler/java/message_field_lite.lo \ + google/protobuf/compiler/java/message_lite.lo \ + google/protobuf/compiler/java/name_resolver.lo \ + google/protobuf/compiler/java/primitive_field.lo \ + google/protobuf/compiler/java/primitive_field_lite.lo \ + google/protobuf/compiler/java/service.lo \ + google/protobuf/compiler/java/shared_code_generator.lo \ + google/protobuf/compiler/java/string_field.lo \ + google/protobuf/compiler/java/string_field_lite.lo \ google/protobuf/compiler/objectivec/objectivec_enum.lo \ google/protobuf/compiler/objectivec/objectivec_enum_field.lo \ google/protobuf/compiler/objectivec/objectivec_extension.lo \ @@ -360,7 +357,9 @@ am_libprotoc_la_OBJECTS = google/protobuf/compiler/code_generator.lo \ google/protobuf/compiler/php/php_generator.lo \ google/protobuf/compiler/plugin.lo \ google/protobuf/compiler/plugin.pb.lo \ - google/protobuf/compiler/python/python_generator.lo \ + google/protobuf/compiler/python/generator.lo \ + google/protobuf/compiler/python/helpers.lo \ + google/protobuf/compiler/python/pyi_generator.lo \ google/protobuf/compiler/ruby/ruby_generator.lo \ google/protobuf/compiler/subprocess.lo \ google/protobuf/compiler/zip_writer.lo @@ -374,8 +373,8 @@ am__objects_2 = google/protobuf/no_warning_test-map_lite_unittest.pb.$(OBJEXT) \ google/protobuf/no_warning_test-unittest_lite.pb.$(OBJEXT) am__objects_3 = $(am__objects_2) \ google/protobuf/no_warning_test-any_test.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.$(OBJEXT) \ google/protobuf/no_warning_test-map_proto2_unittest.pb.$(OBJEXT) \ google/protobuf/no_warning_test-map_unittest.pb.$(OBJEXT) \ google/protobuf/no_warning_test-unittest.pb.$(OBJEXT) \ @@ -435,7 +434,7 @@ am__objects_5 = $(am__objects_4) \ google/protobuf/protobuf_lazy_descriptor_test-test_util.$(OBJEXT) \ google/protobuf/testing/protobuf_lazy_descriptor_test-file.$(OBJEXT) \ google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.$(OBJEXT) -am_protobuf_lazy_descriptor_test_OBJECTS = google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT) \ +am_protobuf_lazy_descriptor_test_OBJECTS = google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.$(OBJEXT) \ $(am__objects_5) am__objects_6 = google/protobuf/protobuf_lazy_descriptor_test-map_lite_unittest.pb.$(OBJEXT) \ google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT) \ @@ -443,8 +442,8 @@ am__objects_6 = google/protobuf/protobuf_lazy_descriptor_test-map_lite_unittest. google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) am__objects_7 = $(am__objects_6) \ google/protobuf/protobuf_lazy_descriptor_test-any_test.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.$(OBJEXT) \ google/protobuf/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.$(OBJEXT) \ google/protobuf/protobuf_lazy_descriptor_test-map_unittest.pb.$(OBJEXT) \ google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \ @@ -556,22 +555,24 @@ am_protobuf_test_OBJECTS = $(am__objects_13) \ google/protobuf/protobuf_test-any_test.$(OBJEXT) \ google/protobuf/protobuf_test-arena_unittest.$(OBJEXT) \ google/protobuf/protobuf_test-arenastring_unittest.$(OBJEXT) \ + google/protobuf/protobuf_test-arenaz_sampler_test.$(OBJEXT) \ google/protobuf/compiler/protobuf_test-annotation_test_util.$(OBJEXT) \ google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.$(OBJEXT) \ google/protobuf/compiler/cpp/protobuf_test-metadata_test.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-move_unittest.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-unittest.$(OBJEXT) \ google/protobuf/compiler/csharp/protobuf_test-csharp_bootstrap_unittest.$(OBJEXT) \ google/protobuf/compiler/csharp/protobuf_test-csharp_generator_unittest.$(OBJEXT) \ google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT) \ - google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT) \ - google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT) \ + google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.$(OBJEXT) \ + google/protobuf/compiler/java/protobuf_test-plugin_unittest.$(OBJEXT) \ google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT) \ google/protobuf/compiler/objectivec/protobuf_test-objectivec_helpers_unittest.$(OBJEXT) \ google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT) \ - google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT) \ + google/protobuf/compiler/python/protobuf_test-plugin_unittest.$(OBJEXT) \ google/protobuf/compiler/ruby/protobuf_test-ruby_generator_unittest.$(OBJEXT) \ google/protobuf/protobuf_test-descriptor_database_unittest.$(OBJEXT) \ google/protobuf/protobuf_test-descriptor_unittest.$(OBJEXT) \ @@ -579,6 +580,7 @@ am_protobuf_test_OBJECTS = $(am__objects_13) \ google/protobuf/protobuf_test-dynamic_message_unittest.$(OBJEXT) \ google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT) \ google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT) \ + google/protobuf/protobuf_test-generated_message_tctable_lite_test.$(OBJEXT) \ google/protobuf/protobuf_test-inlined_string_field_unittest.$(OBJEXT) \ google/protobuf/io/protobuf_test-coded_stream_unittest.$(OBJEXT) \ google/protobuf/io/protobuf_test-io_win32_unittest.$(OBJEXT) \ @@ -631,8 +633,8 @@ am__objects_14 = \ google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT) am__objects_15 = $(am__objects_14) \ google/protobuf/protobuf_test-any_test.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT) \ - google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.$(OBJEXT) \ + google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.$(OBJEXT) \ google/protobuf/protobuf_test-map_proto2_unittest.pb.$(OBJEXT) \ google/protobuf/protobuf_test-map_unittest.pb.$(OBJEXT) \ google/protobuf/protobuf_test-unittest.pb.$(OBJEXT) \ @@ -730,6 +732,7 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/$(DEPDIR)/api.pb.Plo \ google/protobuf/$(DEPDIR)/arena.Plo \ google/protobuf/$(DEPDIR)/arenastring.Plo \ + google/protobuf/$(DEPDIR)/arenaz_sampler.Plo \ google/protobuf/$(DEPDIR)/descriptor.Plo \ google/protobuf/$(DEPDIR)/descriptor.pb.Plo \ google/protobuf/$(DEPDIR)/descriptor_database.Plo \ @@ -742,8 +745,6 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/$(DEPDIR)/generated_enum_util.Plo \ google/protobuf/$(DEPDIR)/generated_message_bases.Plo \ google/protobuf/$(DEPDIR)/generated_message_reflection.Plo \ - google/protobuf/$(DEPDIR)/generated_message_table_driven.Plo \ - google/protobuf/$(DEPDIR)/generated_message_table_driven_lite.Plo \ google/protobuf/$(DEPDIR)/generated_message_tctable_full.Plo \ google/protobuf/$(DEPDIR)/generated_message_tctable_lite.Plo \ google/protobuf/$(DEPDIR)/generated_message_util.Plo \ @@ -846,12 +847,14 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/$(DEPDIR)/protobuf_test-arena_test_util.Po \ google/protobuf/$(DEPDIR)/protobuf_test-arena_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-arenastring_unittest.Po \ + google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po \ google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-drop_unknown_fields_test.Po \ google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po \ + google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po \ google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Po \ google/protobuf/$(DEPDIR)/protobuf_test-map_field_test.Po \ google/protobuf/$(DEPDIR)/protobuf_test-map_lite_test_util.Po \ @@ -933,33 +936,34 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po \ google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po \ google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_map_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_padding_optimizer.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_parse_function_generator.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo \ - google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po \ - google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/enum.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/enum_field.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/extension.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/field.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/file.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/generator.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/helpers.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/map_field.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/message.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/message_field.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/padding_optimizer.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/parse_function_generator.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/primitive_field.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po \ google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-metadata_test.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po \ + google/protobuf/compiler/cpp/$(DEPDIR)/service.Plo \ + google/protobuf/compiler/cpp/$(DEPDIR)/string_field.Plo \ google/protobuf/compiler/csharp/$(DEPDIR)/csharp_doc_comment.Plo \ google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum.Plo \ google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum_field.Plo \ @@ -978,39 +982,37 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/compiler/csharp/$(DEPDIR)/csharp_wrapper_field.Plo \ google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Po \ google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_generator_unittest.Po \ - google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_enum_field_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_enum_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_extension_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_kotlin_generator.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_map_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_map_field_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message_builder.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message_builder_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message_field_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_message_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/java_string_field_lite.Plo \ - google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po \ - google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po \ - google/protobuf/compiler/js/$(DEPDIR)/js_generator.Plo \ - google/protobuf/compiler/js/$(DEPDIR)/well_known_types_embed.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/context.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/doc_comment.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/enum.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/enum_field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/enum_field_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/enum_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/extension.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/extension_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/file.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/generator.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/generator_factory.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/helpers.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/kotlin_generator.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/map_field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/map_field_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message_builder.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message_builder_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message_field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message_field_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/message_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/name_resolver.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/primitive_field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/primitive_field_lite.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po \ + google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po \ + google/protobuf/compiler/java/$(DEPDIR)/service.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/shared_code_generator.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/string_field.Plo \ + google/protobuf/compiler/java/$(DEPDIR)/string_field_lite.Plo \ google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum.Plo \ google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum_field.Plo \ google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_extension.Plo \ @@ -1025,8 +1027,10 @@ am__depfiles_remade = ./$(DEPDIR)/no_warning_test-no_warning_test.Po \ google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_primitive_field.Plo \ google/protobuf/compiler/objectivec/$(DEPDIR)/protobuf_test-objectivec_helpers_unittest.Po \ google/protobuf/compiler/php/$(DEPDIR)/php_generator.Plo \ - google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po \ - google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo \ + google/protobuf/compiler/python/$(DEPDIR)/generator.Plo \ + google/protobuf/compiler/python/$(DEPDIR)/helpers.Plo \ + google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po \ + google/protobuf/compiler/python/$(DEPDIR)/pyi_generator.Plo \ google/protobuf/compiler/ruby/$(DEPDIR)/protobuf_test-ruby_generator_unittest.Po \ google/protobuf/compiler/ruby/$(DEPDIR)/ruby_generator.Plo \ google/protobuf/io/$(DEPDIR)/coded_stream.Plo \ @@ -1211,34 +1215,38 @@ DATA = $(nobase_dist_proto_DATA) am__nobase_include_HEADERS_DIST = google/protobuf/any.h \ google/protobuf/any.pb.h google/protobuf/api.pb.h \ google/protobuf/arena.h google/protobuf/arena_impl.h \ - google/protobuf/arenastring.h \ + google/protobuf/arenastring.h google/protobuf/arenaz_sampler.h \ google/protobuf/compiler/code_generator.h \ google/protobuf/compiler/command_line_interface.h \ - google/protobuf/compiler/cpp/cpp_file.h \ google/protobuf/compiler/cpp/cpp_generator.h \ - google/protobuf/compiler/cpp/cpp_helpers.h \ - google/protobuf/compiler/cpp/cpp_names.h \ + google/protobuf/compiler/cpp/file.h \ + google/protobuf/compiler/cpp/generator.h \ + google/protobuf/compiler/cpp/helpers.h \ + google/protobuf/compiler/cpp/names.h \ google/protobuf/compiler/csharp/csharp_doc_comment.h \ google/protobuf/compiler/csharp/csharp_generator.h \ google/protobuf/compiler/csharp/csharp_names.h \ google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/importer.h \ + google/protobuf/compiler/java/generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/java/java_kotlin_generator.h \ - google/protobuf/compiler/java/java_names.h \ - google/protobuf/compiler/js/js_generator.h \ + google/protobuf/compiler/java/kotlin_generator.h \ + google/protobuf/compiler/java/names.h \ google/protobuf/compiler/objectivec/objectivec_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers.h \ google/protobuf/compiler/parser.h \ google/protobuf/compiler/php/php_generator.h \ google/protobuf/compiler/plugin.h \ google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/python/generator.h \ + google/protobuf/compiler/python/pyi_generator.h \ google/protobuf/compiler/python/python_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/descriptor.h google/protobuf/descriptor.pb.h \ google/protobuf/descriptor_database.h \ google/protobuf/duration.pb.h \ google/protobuf/dynamic_message.h google/protobuf/empty.pb.h \ + google/protobuf/endian.h \ google/protobuf/explicitly_constructed.h \ google/protobuf/extension_set.h \ google/protobuf/extension_set_inl.h \ @@ -1248,11 +1256,8 @@ am__nobase_include_HEADERS_DIST = google/protobuf/any.h \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_bases.h \ google/protobuf/generated_message_reflection.h \ - google/protobuf/generated_message_table_driven.h \ - google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_tctable_decl.h \ google/protobuf/generated_message_tctable_impl.h \ - google/protobuf/generated_message_tctable_impl.inc \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ @@ -1273,7 +1278,9 @@ am__nobase_include_HEADERS_DIST = google/protobuf/any.h \ google/protobuf/metadata_lite.h \ google/protobuf/parse_context.h google/protobuf/port.h \ google/protobuf/port_def.inc google/protobuf/port_undef.inc \ - google/protobuf/reflection.h google/protobuf/reflection_ops.h \ + google/protobuf/reflection.h \ + google/protobuf/reflection_internal.h \ + google/protobuf/reflection_ops.h \ google/protobuf/repeated_field.h \ google/protobuf/repeated_ptr_field.h google/protobuf/service.h \ google/protobuf/source_context.pb.h \ @@ -1546,6 +1553,7 @@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INSTALL = @INSTALL@ @@ -1672,7 +1680,7 @@ top_srcdir = @top_srcdir@ @HAVE_ZLIB_TRUE@ZLIB_DEF = -DHAVE_ZLIB=1 @HAVE_PTHREAD_FALSE@PTHREAD_DEF = @HAVE_PTHREAD_TRUE@PTHREAD_DEF = -DHAVE_PTHREAD=1 -PROTOBUF_VERSION = 30:1:0 +PROTOBUF_VERSION = 32:12:0 @GCC_FALSE@NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) # Turn on all warnings except for sign comparison (we ignore sign comparison @@ -1716,27 +1724,31 @@ nobase_include_HEADERS = \ google/protobuf/arena.h \ google/protobuf/arena_impl.h \ google/protobuf/arenastring.h \ + google/protobuf/arenaz_sampler.h \ google/protobuf/compiler/code_generator.h \ google/protobuf/compiler/command_line_interface.h \ - google/protobuf/compiler/cpp/cpp_file.h \ google/protobuf/compiler/cpp/cpp_generator.h \ - google/protobuf/compiler/cpp/cpp_helpers.h \ - google/protobuf/compiler/cpp/cpp_names.h \ + google/protobuf/compiler/cpp/file.h \ + google/protobuf/compiler/cpp/generator.h \ + google/protobuf/compiler/cpp/helpers.h \ + google/protobuf/compiler/cpp/names.h \ google/protobuf/compiler/csharp/csharp_doc_comment.h \ google/protobuf/compiler/csharp/csharp_generator.h \ google/protobuf/compiler/csharp/csharp_names.h \ google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/importer.h \ + google/protobuf/compiler/java/generator.h \ google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/java/java_kotlin_generator.h \ - google/protobuf/compiler/java/java_names.h \ - google/protobuf/compiler/js/js_generator.h \ + google/protobuf/compiler/java/kotlin_generator.h \ + google/protobuf/compiler/java/names.h \ google/protobuf/compiler/objectivec/objectivec_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers.h \ google/protobuf/compiler/parser.h \ google/protobuf/compiler/php/php_generator.h \ google/protobuf/compiler/plugin.h \ google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/python/generator.h \ + google/protobuf/compiler/python/pyi_generator.h \ google/protobuf/compiler/python/python_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/descriptor.h \ @@ -1745,6 +1757,7 @@ nobase_include_HEADERS = \ google/protobuf/duration.pb.h \ google/protobuf/dynamic_message.h \ google/protobuf/empty.pb.h \ + google/protobuf/endian.h \ google/protobuf/explicitly_constructed.h \ google/protobuf/extension_set.h \ google/protobuf/extension_set_inl.h \ @@ -1754,11 +1767,8 @@ nobase_include_HEADERS = \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_bases.h \ google/protobuf/generated_message_reflection.h \ - google/protobuf/generated_message_table_driven.h \ - google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_tctable_decl.h \ google/protobuf/generated_message_tctable_impl.h \ - google/protobuf/generated_message_tctable_impl.inc \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ @@ -1788,6 +1798,7 @@ nobase_include_HEADERS = \ google/protobuf/port_def.inc \ google/protobuf/port_undef.inc \ google/protobuf/reflection.h \ + google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.h \ google/protobuf/repeated_field.h \ google/protobuf/repeated_ptr_field.h \ @@ -1836,9 +1847,9 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/any_lite.cc \ google/protobuf/arena.cc \ google/protobuf/arenastring.cc \ + google/protobuf/arenaz_sampler.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_enum_util.cc \ - google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/generated_message_tctable_lite.cc \ google/protobuf/generated_message_util.cc \ google/protobuf/implicit_weak_message.cc \ @@ -1894,14 +1905,12 @@ libprotobuf_la_SOURCES = \ google/protobuf/field_mask.pb.cc \ google/protobuf/generated_message_bases.cc \ google/protobuf/generated_message_reflection.cc \ - google/protobuf/generated_message_table_driven.cc \ google/protobuf/generated_message_tctable_full.cc \ google/protobuf/io/gzip_stream.cc \ google/protobuf/io/printer.cc \ google/protobuf/io/tokenizer.cc \ google/protobuf/map_field.cc \ google/protobuf/message.cc \ - google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.cc \ google/protobuf/service.cc \ google/protobuf/source_context.pb.cc \ @@ -1964,35 +1973,35 @@ libprotoc_la_LDFLAGS = -version-info $(PROTOBUF_VERSION) \ libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ - google/protobuf/compiler/cpp/cpp_enum.cc \ - google/protobuf/compiler/cpp/cpp_enum.h \ - google/protobuf/compiler/cpp/cpp_enum_field.cc \ - google/protobuf/compiler/cpp/cpp_enum_field.h \ - google/protobuf/compiler/cpp/cpp_extension.cc \ - google/protobuf/compiler/cpp/cpp_extension.h \ - google/protobuf/compiler/cpp/cpp_field.cc \ - google/protobuf/compiler/cpp/cpp_field.h \ - google/protobuf/compiler/cpp/cpp_file.cc \ - google/protobuf/compiler/cpp/cpp_generator.cc \ - google/protobuf/compiler/cpp/cpp_helpers.cc \ - google/protobuf/compiler/cpp/cpp_map_field.cc \ - google/protobuf/compiler/cpp/cpp_map_field.h \ - google/protobuf/compiler/cpp/cpp_message.cc \ - google/protobuf/compiler/cpp/cpp_message.h \ - google/protobuf/compiler/cpp/cpp_message_field.cc \ - google/protobuf/compiler/cpp/cpp_message_field.h \ - google/protobuf/compiler/cpp/cpp_message_layout_helper.h \ - google/protobuf/compiler/cpp/cpp_options.h \ - google/protobuf/compiler/cpp/cpp_padding_optimizer.cc \ - google/protobuf/compiler/cpp/cpp_padding_optimizer.h \ - google/protobuf/compiler/cpp/cpp_parse_function_generator.cc \ - google/protobuf/compiler/cpp/cpp_parse_function_generator.h \ - google/protobuf/compiler/cpp/cpp_primitive_field.cc \ - google/protobuf/compiler/cpp/cpp_primitive_field.h \ - google/protobuf/compiler/cpp/cpp_service.cc \ - google/protobuf/compiler/cpp/cpp_service.h \ - google/protobuf/compiler/cpp/cpp_string_field.cc \ - google/protobuf/compiler/cpp/cpp_string_field.h \ + google/protobuf/compiler/cpp/enum.cc \ + google/protobuf/compiler/cpp/enum.h \ + google/protobuf/compiler/cpp/enum_field.cc \ + google/protobuf/compiler/cpp/enum_field.h \ + google/protobuf/compiler/cpp/extension.cc \ + google/protobuf/compiler/cpp/extension.h \ + google/protobuf/compiler/cpp/field.cc \ + google/protobuf/compiler/cpp/field.h \ + google/protobuf/compiler/cpp/file.cc \ + google/protobuf/compiler/cpp/generator.cc \ + google/protobuf/compiler/cpp/helpers.cc \ + google/protobuf/compiler/cpp/map_field.cc \ + google/protobuf/compiler/cpp/map_field.h \ + google/protobuf/compiler/cpp/message.cc \ + google/protobuf/compiler/cpp/message.h \ + google/protobuf/compiler/cpp/message_field.cc \ + google/protobuf/compiler/cpp/message_field.h \ + google/protobuf/compiler/cpp/message_layout_helper.h \ + google/protobuf/compiler/cpp/options.h \ + google/protobuf/compiler/cpp/padding_optimizer.cc \ + google/protobuf/compiler/cpp/padding_optimizer.h \ + google/protobuf/compiler/cpp/parse_function_generator.cc \ + google/protobuf/compiler/cpp/parse_function_generator.h \ + google/protobuf/compiler/cpp/primitive_field.cc \ + google/protobuf/compiler/cpp/primitive_field.h \ + google/protobuf/compiler/cpp/service.cc \ + google/protobuf/compiler/cpp/service.h \ + google/protobuf/compiler/cpp/string_field.cc \ + google/protobuf/compiler/cpp/string_field.h \ google/protobuf/compiler/csharp/csharp_doc_comment.cc \ google/protobuf/compiler/csharp/csharp_enum.cc \ google/protobuf/compiler/csharp/csharp_enum.h \ @@ -2023,66 +2032,63 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_source_generator_base.h \ google/protobuf/compiler/csharp/csharp_wrapper_field.cc \ google/protobuf/compiler/csharp/csharp_wrapper_field.h \ - google/protobuf/compiler/java/java_context.cc \ - google/protobuf/compiler/java/java_context.h \ - google/protobuf/compiler/java/java_doc_comment.cc \ - google/protobuf/compiler/java/java_doc_comment.h \ - google/protobuf/compiler/java/java_enum.cc \ - google/protobuf/compiler/java/java_enum.h \ - google/protobuf/compiler/java/java_enum_field.cc \ - google/protobuf/compiler/java/java_enum_field.h \ - google/protobuf/compiler/java/java_enum_field_lite.cc \ - google/protobuf/compiler/java/java_enum_field_lite.h \ - google/protobuf/compiler/java/java_enum_lite.cc \ - google/protobuf/compiler/java/java_enum_lite.h \ - google/protobuf/compiler/java/java_extension.cc \ - google/protobuf/compiler/java/java_extension.h \ - google/protobuf/compiler/java/java_extension_lite.cc \ - google/protobuf/compiler/java/java_extension_lite.h \ - google/protobuf/compiler/java/java_field.cc \ - google/protobuf/compiler/java/java_field.h \ - google/protobuf/compiler/java/java_file.cc \ - google/protobuf/compiler/java/java_file.h \ - google/protobuf/compiler/java/java_generator.cc \ - google/protobuf/compiler/java/java_generator_factory.cc \ - google/protobuf/compiler/java/java_generator_factory.h \ - google/protobuf/compiler/java/java_helpers.cc \ - google/protobuf/compiler/java/java_helpers.h \ - google/protobuf/compiler/java/java_kotlin_generator.cc \ - google/protobuf/compiler/java/java_map_field.cc \ - google/protobuf/compiler/java/java_map_field.h \ - google/protobuf/compiler/java/java_map_field_lite.cc \ - google/protobuf/compiler/java/java_map_field_lite.h \ - google/protobuf/compiler/java/java_message.cc \ - google/protobuf/compiler/java/java_message.h \ - google/protobuf/compiler/java/java_message_builder.cc \ - google/protobuf/compiler/java/java_message_builder.h \ - google/protobuf/compiler/java/java_message_builder_lite.cc \ - google/protobuf/compiler/java/java_message_builder_lite.h \ - google/protobuf/compiler/java/java_message_field.cc \ - google/protobuf/compiler/java/java_message_field.h \ - google/protobuf/compiler/java/java_message_field_lite.cc \ - google/protobuf/compiler/java/java_message_field_lite.h \ - google/protobuf/compiler/java/java_message_lite.cc \ - google/protobuf/compiler/java/java_message_lite.h \ - google/protobuf/compiler/java/java_name_resolver.cc \ - google/protobuf/compiler/java/java_name_resolver.h \ - google/protobuf/compiler/java/java_options.h \ - google/protobuf/compiler/java/java_primitive_field.cc \ - google/protobuf/compiler/java/java_primitive_field.h \ - google/protobuf/compiler/java/java_primitive_field_lite.cc \ - google/protobuf/compiler/java/java_primitive_field_lite.h \ - google/protobuf/compiler/java/java_service.cc \ - google/protobuf/compiler/java/java_service.h \ - google/protobuf/compiler/java/java_shared_code_generator.cc \ - google/protobuf/compiler/java/java_shared_code_generator.h \ - google/protobuf/compiler/java/java_string_field.cc \ - google/protobuf/compiler/java/java_string_field.h \ - google/protobuf/compiler/java/java_string_field_lite.cc \ - google/protobuf/compiler/java/java_string_field_lite.h \ - google/protobuf/compiler/js/js_generator.cc \ - google/protobuf/compiler/js/well_known_types_embed.cc \ - google/protobuf/compiler/js/well_known_types_embed.h \ + google/protobuf/compiler/java/context.cc \ + google/protobuf/compiler/java/context.h \ + google/protobuf/compiler/java/doc_comment.cc \ + google/protobuf/compiler/java/doc_comment.h \ + google/protobuf/compiler/java/enum.cc \ + google/protobuf/compiler/java/enum.h \ + google/protobuf/compiler/java/enum_field.cc \ + google/protobuf/compiler/java/enum_field.h \ + google/protobuf/compiler/java/enum_field_lite.cc \ + google/protobuf/compiler/java/enum_field_lite.h \ + google/protobuf/compiler/java/enum_lite.cc \ + google/protobuf/compiler/java/enum_lite.h \ + google/protobuf/compiler/java/extension.cc \ + google/protobuf/compiler/java/extension.h \ + google/protobuf/compiler/java/extension_lite.cc \ + google/protobuf/compiler/java/extension_lite.h \ + google/protobuf/compiler/java/field.cc \ + google/protobuf/compiler/java/field.h \ + google/protobuf/compiler/java/file.cc \ + google/protobuf/compiler/java/file.h \ + google/protobuf/compiler/java/generator.cc \ + google/protobuf/compiler/java/generator_factory.cc \ + google/protobuf/compiler/java/generator_factory.h \ + google/protobuf/compiler/java/helpers.cc \ + google/protobuf/compiler/java/helpers.h \ + google/protobuf/compiler/java/kotlin_generator.cc \ + google/protobuf/compiler/java/map_field.cc \ + google/protobuf/compiler/java/map_field.h \ + google/protobuf/compiler/java/map_field_lite.cc \ + google/protobuf/compiler/java/map_field_lite.h \ + google/protobuf/compiler/java/message.cc \ + google/protobuf/compiler/java/message.h \ + google/protobuf/compiler/java/message_builder.cc \ + google/protobuf/compiler/java/message_builder.h \ + google/protobuf/compiler/java/message_builder_lite.cc \ + google/protobuf/compiler/java/message_builder_lite.h \ + google/protobuf/compiler/java/message_field.cc \ + google/protobuf/compiler/java/message_field.h \ + google/protobuf/compiler/java/message_field_lite.cc \ + google/protobuf/compiler/java/message_field_lite.h \ + google/protobuf/compiler/java/message_lite.cc \ + google/protobuf/compiler/java/message_lite.h \ + google/protobuf/compiler/java/name_resolver.cc \ + google/protobuf/compiler/java/name_resolver.h \ + google/protobuf/compiler/java/options.h \ + google/protobuf/compiler/java/primitive_field.cc \ + google/protobuf/compiler/java/primitive_field.h \ + google/protobuf/compiler/java/primitive_field_lite.cc \ + google/protobuf/compiler/java/primitive_field_lite.h \ + google/protobuf/compiler/java/service.cc \ + google/protobuf/compiler/java/service.h \ + google/protobuf/compiler/java/shared_code_generator.cc \ + google/protobuf/compiler/java/shared_code_generator.h \ + google/protobuf/compiler/java/string_field.cc \ + google/protobuf/compiler/java/string_field.h \ + google/protobuf/compiler/java/string_field_lite.cc \ + google/protobuf/compiler/java/string_field_lite.h \ google/protobuf/compiler/objectivec/objectivec_enum.cc \ google/protobuf/compiler/objectivec/objectivec_enum.h \ google/protobuf/compiler/objectivec/objectivec_enum_field.cc \ @@ -2109,7 +2115,10 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/php/php_generator.cc \ google/protobuf/compiler/plugin.cc \ google/protobuf/compiler/plugin.pb.cc \ - google/protobuf/compiler/python/python_generator.cc \ + google/protobuf/compiler/python/generator.cc \ + google/protobuf/compiler/python/helpers.cc \ + google/protobuf/compiler/python/helpers.h \ + google/protobuf/compiler/python/pyi_generator.cc \ google/protobuf/compiler/ruby/ruby_generator.cc \ google/protobuf/compiler/scc.h \ google/protobuf/compiler/subprocess.cc \ @@ -2123,8 +2132,8 @@ protoc_SOURCES = google/protobuf/compiler/main.cc # Tests ============================================================== protoc_inputs = \ google/protobuf/any_test.proto \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto \ + google/protobuf/compiler/cpp/test_bad_identifiers.proto \ + google/protobuf/compiler/cpp/test_large_enum_value.proto \ google/protobuf/map_lite_unittest.proto \ google/protobuf/map_proto2_unittest.proto \ google/protobuf/map_unittest.proto \ @@ -2227,10 +2236,10 @@ protoc_outputs = \ $(protoc_lite_outputs) \ google/protobuf/any_test.pb.cc \ google/protobuf/any_test.pb.h \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc \ - google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.h \ + google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc \ + google/protobuf/compiler/cpp/test_bad_identifiers.pb.h \ + google/protobuf/compiler/cpp/test_large_enum_value.pb.cc \ + google/protobuf/compiler/cpp/test_large_enum_value.pb.h \ google/protobuf/map_proto2_unittest.pb.cc \ google/protobuf/map_proto2_unittest.pb.h \ google/protobuf/map_unittest.pb.cc \ @@ -2318,7 +2327,7 @@ protoc_outputs = \ COMMON_TEST_SOURCES = \ $(COMMON_LITE_TEST_SOURCES) \ - google/protobuf/compiler/cpp/cpp_unittest.h \ + google/protobuf/compiler/cpp/unittest.h \ google/protobuf/map_test_util.h \ google/protobuf/map_test_util.inc \ google/protobuf/reflection_tester.cc \ @@ -2353,25 +2362,27 @@ protobuf_test_SOURCES = \ google/protobuf/any_test.cc \ google/protobuf/arena_unittest.cc \ google/protobuf/arenastring_unittest.cc \ + google/protobuf/arenaz_sampler_test.cc \ google/protobuf/compiler/annotation_test_util.cc \ google/protobuf/compiler/annotation_test_util.h \ google/protobuf/compiler/command_line_interface_unittest.cc \ - google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ - google/protobuf/compiler/cpp/cpp_move_unittest.cc \ - google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ - google/protobuf/compiler/cpp/cpp_unittest.cc \ - google/protobuf/compiler/cpp/cpp_unittest.inc \ + google/protobuf/compiler/cpp/bootstrap_unittest.cc \ + google/protobuf/compiler/cpp/message_size_unittest.cc \ google/protobuf/compiler/cpp/metadata_test.cc \ + google/protobuf/compiler/cpp/move_unittest.cc \ + google/protobuf/compiler/cpp/plugin_unittest.cc \ + google/protobuf/compiler/cpp/unittest.cc \ + google/protobuf/compiler/cpp/unittest.inc \ google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc \ google/protobuf/compiler/csharp/csharp_generator_unittest.cc \ google/protobuf/compiler/importer_unittest.cc \ - google/protobuf/compiler/java/java_doc_comment_unittest.cc \ - google/protobuf/compiler/java/java_plugin_unittest.cc \ + google/protobuf/compiler/java/doc_comment_unittest.cc \ + google/protobuf/compiler/java/plugin_unittest.cc \ google/protobuf/compiler/mock_code_generator.cc \ google/protobuf/compiler/mock_code_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc \ google/protobuf/compiler/parser_unittest.cc \ - google/protobuf/compiler/python/python_plugin_unittest.cc \ + google/protobuf/compiler/python/plugin_unittest.cc \ google/protobuf/compiler/ruby/ruby_generator_unittest.cc \ google/protobuf/descriptor_database_unittest.cc \ google/protobuf/descriptor_unittest.cc \ @@ -2379,6 +2390,7 @@ protobuf_test_SOURCES = \ google/protobuf/dynamic_message_unittest.cc \ google/protobuf/extension_set_unittest.cc \ google/protobuf/generated_message_reflection_unittest.cc \ + google/protobuf/generated_message_tctable_lite_test.cc \ google/protobuf/inlined_string_field_unittest.cc \ google/protobuf/io/coded_stream_unittest.cc \ google/protobuf/io/io_win32_unittest.cc \ @@ -2444,7 +2456,7 @@ protobuf_lazy_descriptor_test_CPPFLAGS = -I$(GOOGLEMOCK_SRC_DIR)/include \ protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) protobuf_lazy_descriptor_test_SOURCES = \ - google/protobuf/compiler/cpp/cpp_unittest.cc \ + google/protobuf/compiler/cpp/unittest.cc \ $(COMMON_TEST_SOURCES) nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs) @@ -2653,14 +2665,13 @@ google/protobuf/arena.lo: google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/arenastring.lo: google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) +google/protobuf/arenaz_sampler.lo: google/protobuf/$(am__dirstamp) \ + google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/extension_set.lo: google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/generated_enum_util.lo: \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) -google/protobuf/generated_message_table_driven_lite.lo: \ - google/protobuf/$(am__dirstamp) \ - google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/generated_message_tctable_lite.lo: \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) @@ -2788,9 +2799,6 @@ google/protobuf/generated_message_bases.lo: \ google/protobuf/generated_message_reflection.lo: \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) -google/protobuf/generated_message_table_driven.lo: \ - google/protobuf/$(am__dirstamp) \ - google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/generated_message_tctable_full.lo: \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) @@ -2914,49 +2922,49 @@ google/protobuf/compiler/cpp/$(am__dirstamp): google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) google/protobuf/compiler/cpp/$(DEPDIR) @: > google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_enum.lo: \ +google/protobuf/compiler/cpp/enum.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_enum_field.lo: \ +google/protobuf/compiler/cpp/enum_field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_extension.lo: \ +google/protobuf/compiler/cpp/extension.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_field.lo: \ +google/protobuf/compiler/cpp/field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_file.lo: \ +google/protobuf/compiler/cpp/file.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_generator.lo: \ +google/protobuf/compiler/cpp/generator.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_helpers.lo: \ +google/protobuf/compiler/cpp/helpers.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_map_field.lo: \ +google/protobuf/compiler/cpp/map_field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_message.lo: \ +google/protobuf/compiler/cpp/message.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_message_field.lo: \ +google/protobuf/compiler/cpp/message_field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_padding_optimizer.lo: \ +google/protobuf/compiler/cpp/padding_optimizer.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_parse_function_generator.lo: \ +google/protobuf/compiler/cpp/parse_function_generator.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_primitive_field.lo: \ +google/protobuf/compiler/cpp/primitive_field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_service.lo: \ +google/protobuf/compiler/cpp/service.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/cpp_string_field.lo: \ +google/protobuf/compiler/cpp/string_field.lo: \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/csharp/$(am__dirstamp): @@ -3019,105 +3027,93 @@ google/protobuf/compiler/java/$(am__dirstamp): google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) google/protobuf/compiler/java/$(DEPDIR) @: > google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_context.lo: \ +google/protobuf/compiler/java/context.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_doc_comment.lo: \ +google/protobuf/compiler/java/doc_comment.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_enum.lo: \ +google/protobuf/compiler/java/enum.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_enum_field.lo: \ +google/protobuf/compiler/java/enum_field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_enum_field_lite.lo: \ +google/protobuf/compiler/java/enum_field_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_enum_lite.lo: \ +google/protobuf/compiler/java/enum_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_extension.lo: \ +google/protobuf/compiler/java/extension.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_extension_lite.lo: \ +google/protobuf/compiler/java/extension_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_field.lo: \ +google/protobuf/compiler/java/field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_file.lo: \ +google/protobuf/compiler/java/file.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_generator.lo: \ +google/protobuf/compiler/java/generator.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_generator_factory.lo: \ +google/protobuf/compiler/java/generator_factory.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_helpers.lo: \ +google/protobuf/compiler/java/helpers.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_kotlin_generator.lo: \ +google/protobuf/compiler/java/kotlin_generator.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_map_field.lo: \ +google/protobuf/compiler/java/map_field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_map_field_lite.lo: \ +google/protobuf/compiler/java/map_field_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message.lo: \ +google/protobuf/compiler/java/message.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message_builder.lo: \ +google/protobuf/compiler/java/message_builder.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message_builder_lite.lo: \ +google/protobuf/compiler/java/message_builder_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message_field.lo: \ +google/protobuf/compiler/java/message_field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message_field_lite.lo: \ +google/protobuf/compiler/java/message_field_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_message_lite.lo: \ +google/protobuf/compiler/java/message_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_name_resolver.lo: \ +google/protobuf/compiler/java/name_resolver.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_primitive_field.lo: \ +google/protobuf/compiler/java/primitive_field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_primitive_field_lite.lo: \ +google/protobuf/compiler/java/primitive_field_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_service.lo: \ +google/protobuf/compiler/java/service.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_shared_code_generator.lo: \ +google/protobuf/compiler/java/shared_code_generator.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_string_field.lo: \ +google/protobuf/compiler/java/string_field.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/java_string_field_lite.lo: \ +google/protobuf/compiler/java/string_field_lite.lo: \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/js/$(am__dirstamp): - @$(MKDIR_P) google/protobuf/compiler/js - @: > google/protobuf/compiler/js/$(am__dirstamp) -google/protobuf/compiler/js/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) google/protobuf/compiler/js/$(DEPDIR) - @: > google/protobuf/compiler/js/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/js/js_generator.lo: \ - google/protobuf/compiler/js/$(am__dirstamp) \ - google/protobuf/compiler/js/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/js/well_known_types_embed.lo: \ - google/protobuf/compiler/js/$(am__dirstamp) \ - google/protobuf/compiler/js/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/objectivec/$(am__dirstamp): @$(MKDIR_P) google/protobuf/compiler/objectivec @: > google/protobuf/compiler/objectivec/$(am__dirstamp) @@ -3181,7 +3177,13 @@ google/protobuf/compiler/python/$(am__dirstamp): google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) google/protobuf/compiler/python/$(DEPDIR) @: > google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/python/python_generator.lo: \ +google/protobuf/compiler/python/generator.lo: \ + google/protobuf/compiler/python/$(am__dirstamp) \ + google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp) +google/protobuf/compiler/python/helpers.lo: \ + google/protobuf/compiler/python/$(am__dirstamp) \ + google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp) +google/protobuf/compiler/python/pyi_generator.lo: \ google/protobuf/compiler/python/$(am__dirstamp) \ google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/ruby/$(am__dirstamp): @@ -3217,10 +3219,10 @@ google/protobuf/no_warning_test-unittest_lite.pb.$(OBJEXT): \ google/protobuf/no_warning_test-any_test.pb.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/no_warning_test-map_proto2_unittest.pb.$(OBJEXT): \ @@ -3359,7 +3361,7 @@ google/protobuf/util/no_warning_test-message_differencer_unittest.pb.$(OBJEXT): no-warning-test$(EXEEXT): $(no_warning_test_OBJECTS) $(no_warning_test_DEPENDENCIES) $(EXTRA_no_warning_test_DEPENDENCIES) @rm -f no-warning-test$(EXEEXT) $(AM_V_CXXLD)$(no_warning_test_LINK) $(no_warning_test_OBJECTS) $(no_warning_test_LDADD) $(LIBS) -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/protobuf_lazy_descriptor_test-arena_test_util.$(OBJEXT): \ @@ -3404,10 +3406,10 @@ google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT): \ google/protobuf/protobuf_lazy_descriptor_test-any_test.pb.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.$(OBJEXT): \ @@ -3626,27 +3628,33 @@ google/protobuf/protobuf_test-arena_unittest.$(OBJEXT): \ google/protobuf/protobuf_test-arenastring_unittest.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) +google/protobuf/protobuf_test-arenaz_sampler_test.$(OBJEXT): \ + google/protobuf/$(am__dirstamp) \ + google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/protobuf_test-annotation_test_util.$(OBJEXT): \ google/protobuf/compiler/$(am__dirstamp) \ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT): \ google/protobuf/compiler/$(am__dirstamp) \ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.$(OBJEXT): \ - google/protobuf/compiler/cpp/$(am__dirstamp) \ - google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT): \ - google/protobuf/compiler/cpp/$(am__dirstamp) \ - google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/cpp/protobuf_test-metadata_test.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) +google/protobuf/compiler/cpp/protobuf_test-move_unittest.$(OBJEXT): \ + google/protobuf/compiler/cpp/$(am__dirstamp) \ + google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) +google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.$(OBJEXT): \ + google/protobuf/compiler/cpp/$(am__dirstamp) \ + google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) +google/protobuf/compiler/cpp/protobuf_test-unittest.$(OBJEXT): \ + google/protobuf/compiler/cpp/$(am__dirstamp) \ + google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/csharp/protobuf_test-csharp_bootstrap_unittest.$(OBJEXT): \ google/protobuf/compiler/csharp/$(am__dirstamp) \ google/protobuf/compiler/csharp/$(DEPDIR)/$(am__dirstamp) @@ -3656,10 +3664,10 @@ google/protobuf/compiler/csharp/protobuf_test-csharp_generator_unittest.$(OBJEXT google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT): \ google/protobuf/compiler/$(am__dirstamp) \ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT): \ +google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.$(OBJEXT): \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT): \ +google/protobuf/compiler/java/protobuf_test-plugin_unittest.$(OBJEXT): \ google/protobuf/compiler/java/$(am__dirstamp) \ google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT): \ @@ -3671,7 +3679,7 @@ google/protobuf/compiler/objectivec/protobuf_test-objectivec_helpers_unittest.$( google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT): \ google/protobuf/compiler/$(am__dirstamp) \ google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT): \ +google/protobuf/compiler/python/protobuf_test-plugin_unittest.$(OBJEXT): \ google/protobuf/compiler/python/$(am__dirstamp) \ google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp) google/protobuf/compiler/ruby/protobuf_test-ruby_generator_unittest.$(OBJEXT): \ @@ -3695,6 +3703,9 @@ google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT): \ google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) +google/protobuf/protobuf_test-generated_message_tctable_lite_test.$(OBJEXT): \ + google/protobuf/$(am__dirstamp) \ + google/protobuf/$(DEPDIR)/$(am__dirstamp) google/protobuf/protobuf_test-inlined_string_field_unittest.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) @@ -3845,10 +3856,10 @@ google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT): \ google/protobuf/protobuf_test-any_test.pb.$(OBJEXT): \ google/protobuf/$(am__dirstamp) \ google/protobuf/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) -google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.$(OBJEXT): \ +google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.$(OBJEXT): \ google/protobuf/compiler/cpp/$(am__dirstamp) \ google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp) google/protobuf/protobuf_test-map_proto2_unittest.pb.$(OBJEXT): \ @@ -4028,8 +4039,6 @@ mostlyclean-compile: -rm -f google/protobuf/compiler/csharp/*.lo -rm -f google/protobuf/compiler/java/*.$(OBJEXT) -rm -f google/protobuf/compiler/java/*.lo - -rm -f google/protobuf/compiler/js/*.$(OBJEXT) - -rm -f google/protobuf/compiler/js/*.lo -rm -f google/protobuf/compiler/objectivec/*.$(OBJEXT) -rm -f google/protobuf/compiler/objectivec/*.lo -rm -f google/protobuf/compiler/php/*.$(OBJEXT) @@ -4059,6 +4068,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/api.pb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/arena.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/arenastring.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/arenaz_sampler.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.pb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor_database.Plo@am__quote@ # am--include-marker @@ -4071,8 +4081,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_enum_util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_bases.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_reflection.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_table_driven.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_table_driven_lite.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_tctable_full.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_tctable_lite.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_util.Plo@am__quote@ # am--include-marker @@ -4175,12 +4183,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-arena_test_util.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-arena_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-arenastring_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-drop_unknown_fields_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-map_field_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-map_lite_test_util.Po@am__quote@ # am--include-marker @@ -4262,33 +4272,34 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_map_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_padding_optimizer.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_parse_function_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/enum.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/enum_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/extension.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/helpers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/map_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/message.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/message_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/padding_optimizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/parse_function_generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/primitive_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-metadata_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/service.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/string_field.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/csharp_doc_comment.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum_field.Plo@am__quote@ # am--include-marker @@ -4307,39 +4318,37 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/csharp_wrapper_field.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_generator_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum_field_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_extension_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_kotlin_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_map_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_map_field_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_builder.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_builder_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_field_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_string_field_lite.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/js/$(DEPDIR)/js_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/js/$(DEPDIR)/well_known_types_embed.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/doc_comment.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/enum.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/enum_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/enum_field_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/enum_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/extension.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/extension_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/generator_factory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/helpers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/kotlin_generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/map_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/map_field_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message_builder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message_builder_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message_field_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/message_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/name_resolver.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/primitive_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/primitive_field_lite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/service.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/shared_code_generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/string_field.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/string_field_lite.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum_field.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_extension.Plo@am__quote@ # am--include-marker @@ -4354,8 +4363,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_primitive_field.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/objectivec/$(DEPDIR)/protobuf_test-objectivec_helpers_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/php/$(DEPDIR)/php_generator.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/generator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/helpers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/pyi_generator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/ruby/$(DEPDIR)/protobuf_test-ruby_generator_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/ruby/$(DEPDIR)/ruby_generator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/coded_stream.Plo@am__quote@ # am--include-marker @@ -4591,33 +4602,33 @@ google/protobuf/no_warning_test-any_test.pb.obj: google/protobuf/any_test.pb.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/no_warning_test-any_test.pb.obj `if test -f 'google/protobuf/any_test.pb.cc'; then $(CYGPATH_W) 'google/protobuf/any_test.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/any_test.pb.cc'; fi` -google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc -google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` -google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.o: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.o: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc -google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/no_warning_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` google/protobuf/no_warning_test-map_proto2_unittest.pb.o: google/protobuf/map_proto2_unittest.pb.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/no_warning_test-map_proto2_unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/no_warning_test-map_proto2_unittest.pb.Tpo -c -o google/protobuf/no_warning_test-map_proto2_unittest.pb.o `test -f 'google/protobuf/map_proto2_unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/map_proto2_unittest.pb.cc @@ -5207,19 +5218,19 @@ google/protobuf/util/no_warning_test-message_differencer_unittest.pb.obj: google @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(no_warning_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/util/no_warning_test-message_differencer_unittest.pb.obj `if test -f 'google/protobuf/util/message_differencer_unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/util/message_differencer_unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/util/message_differencer_unittest.pb.cc'; fi` -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.o: google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.o `test -f 'google/protobuf/compiler/cpp/unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.o `test -f 'google/protobuf/compiler/cpp/unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/unittest.cc -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.obj: google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.obj `if test -f 'google/protobuf/compiler/cpp/unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-unittest.obj `if test -f 'google/protobuf/compiler/cpp/unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/unittest.cc'; fi` google/protobuf/protobuf_lazy_descriptor_test-arena_test_util.o: google/protobuf/arena_test_util.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-arena_test_util.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-arena_test_util.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-arena_test_util.o `test -f 'google/protobuf/arena_test_util.cc' || echo '$(srcdir)/'`google/protobuf/arena_test_util.cc @@ -5389,33 +5400,33 @@ google/protobuf/protobuf_lazy_descriptor_test-any_test.pb.obj: google/protobuf/a @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-any_test.pb.obj `if test -f 'google/protobuf/any_test.pb.cc'; then $(CYGPATH_W) 'google/protobuf/any_test.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/any_test.pb.cc'; fi` -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.o: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.o: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc -google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` google/protobuf/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.o: google/protobuf/map_proto2_unittest.pb.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-map_proto2_unittest.pb.o `test -f 'google/protobuf/map_proto2_unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/map_proto2_unittest.pb.cc @@ -6369,6 +6380,20 @@ google/protobuf/protobuf_test-arenastring_unittest.obj: google/protobuf/arenastr @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-arenastring_unittest.obj `if test -f 'google/protobuf/arenastring_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/arenastring_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/arenastring_unittest.cc'; fi` +google/protobuf/protobuf_test-arenaz_sampler_test.o: google/protobuf/arenaz_sampler_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-arenaz_sampler_test.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Tpo -c -o google/protobuf/protobuf_test-arenaz_sampler_test.o `test -f 'google/protobuf/arenaz_sampler_test.cc' || echo '$(srcdir)/'`google/protobuf/arenaz_sampler_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Tpo google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/arenaz_sampler_test.cc' object='google/protobuf/protobuf_test-arenaz_sampler_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-arenaz_sampler_test.o `test -f 'google/protobuf/arenaz_sampler_test.cc' || echo '$(srcdir)/'`google/protobuf/arenaz_sampler_test.cc + +google/protobuf/protobuf_test-arenaz_sampler_test.obj: google/protobuf/arenaz_sampler_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-arenaz_sampler_test.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Tpo -c -o google/protobuf/protobuf_test-arenaz_sampler_test.obj `if test -f 'google/protobuf/arenaz_sampler_test.cc'; then $(CYGPATH_W) 'google/protobuf/arenaz_sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/arenaz_sampler_test.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Tpo google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/arenaz_sampler_test.cc' object='google/protobuf/protobuf_test-arenaz_sampler_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-arenaz_sampler_test.obj `if test -f 'google/protobuf/arenaz_sampler_test.cc'; then $(CYGPATH_W) 'google/protobuf/arenaz_sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/arenaz_sampler_test.cc'; fi` + google/protobuf/compiler/protobuf_test-annotation_test_util.o: google/protobuf/compiler/annotation_test_util.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-annotation_test_util.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-annotation_test_util.Tpo -c -o google/protobuf/compiler/protobuf_test-annotation_test_util.o `test -f 'google/protobuf/compiler/annotation_test_util.cc' || echo '$(srcdir)/'`google/protobuf/compiler/annotation_test_util.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-annotation_test_util.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-annotation_test_util.Po @@ -6397,61 +6422,33 @@ google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj: goog @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi` -google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.o: google/protobuf/compiler/cpp/bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/bootstrap_unittest.cc -google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.obj: google/protobuf/compiler/cpp/bootstrap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/bootstrap_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/bootstrap_unittest.cc'; fi` -google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.o: google/protobuf/compiler/cpp/cpp_move_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_move_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_move_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_move_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.o: google/protobuf/compiler/cpp/message_size_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.o `test -f 'google/protobuf/compiler/cpp/message_size_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/message_size_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/message_size_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_move_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_move_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.o `test -f 'google/protobuf/compiler/cpp/message_size_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/message_size_unittest.cc -google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.obj: google/protobuf/compiler/cpp/cpp_move_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_move_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_move_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_move_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_move_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.obj: google/protobuf/compiler/cpp/message_size_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.obj `if test -f 'google/protobuf/compiler/cpp/message_size_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/message_size_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/message_size_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/message_size_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_move_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_move_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_move_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_move_unittest.cc'; fi` - -google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc - -google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi` - -google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc - -google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-message_size_unittest.obj `if test -f 'google/protobuf/compiler/cpp/message_size_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/message_size_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/message_size_unittest.cc'; fi` google/protobuf/compiler/cpp/protobuf_test-metadata_test.o: google/protobuf/compiler/cpp/metadata_test.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-metadata_test.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-metadata_test.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-metadata_test.o `test -f 'google/protobuf/compiler/cpp/metadata_test.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/metadata_test.cc @@ -6467,6 +6464,48 @@ google/protobuf/compiler/cpp/protobuf_test-metadata_test.obj: google/protobuf/co @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-metadata_test.obj `if test -f 'google/protobuf/compiler/cpp/metadata_test.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/metadata_test.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/metadata_test.cc'; fi` +google/protobuf/compiler/cpp/protobuf_test-move_unittest.o: google/protobuf/compiler/cpp/move_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-move_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-move_unittest.o `test -f 'google/protobuf/compiler/cpp/move_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/move_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/move_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-move_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-move_unittest.o `test -f 'google/protobuf/compiler/cpp/move_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/move_unittest.cc + +google/protobuf/compiler/cpp/protobuf_test-move_unittest.obj: google/protobuf/compiler/cpp/move_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-move_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-move_unittest.obj `if test -f 'google/protobuf/compiler/cpp/move_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/move_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/move_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/move_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-move_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-move_unittest.obj `if test -f 'google/protobuf/compiler/cpp/move_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/move_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/move_unittest.cc'; fi` + +google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.o: google/protobuf/compiler/cpp/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/plugin_unittest.cc + +google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.obj: google/protobuf/compiler/cpp/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/plugin_unittest.cc'; fi` + +google/protobuf/compiler/cpp/protobuf_test-unittest.o: google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-unittest.o `test -f 'google/protobuf/compiler/cpp/unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-unittest.o `test -f 'google/protobuf/compiler/cpp/unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/unittest.cc + +google/protobuf/compiler/cpp/protobuf_test-unittest.obj: google/protobuf/compiler/cpp/unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-unittest.obj `if test -f 'google/protobuf/compiler/cpp/unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-unittest.obj `if test -f 'google/protobuf/compiler/cpp/unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/unittest.cc'; fi` + google/protobuf/compiler/csharp/protobuf_test-csharp_bootstrap_unittest.o: google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/csharp/protobuf_test-csharp_bootstrap_unittest.o -MD -MP -MF google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/csharp/protobuf_test-csharp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Tpo google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Po @@ -6509,33 +6548,33 @@ google/protobuf/compiler/protobuf_test-importer_unittest.obj: google/protobuf/co @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi` -google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o: google/protobuf/compiler/java/java_doc_comment_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.o: google/protobuf/compiler/java/doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/doc_comment_unittest.cc -google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj: google/protobuf/compiler/java/java_doc_comment_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.obj: google/protobuf/compiler/java/doc_comment_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/doc_comment_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/doc_comment_unittest.cc'; fi` -google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/java/protobuf_test-plugin_unittest.o: google/protobuf/compiler/java/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-plugin_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/java/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/java/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/plugin_unittest.cc -google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/java/protobuf_test-plugin_unittest.obj: google/protobuf/compiler/java/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/java/plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/plugin_unittest.cc'; fi` google/protobuf/compiler/protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-mock_code_generator.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc @@ -6579,19 +6618,19 @@ google/protobuf/compiler/protobuf_test-parser_unittest.obj: google/protobuf/comp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi` -google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/python/protobuf_test-plugin_unittest.o: google/protobuf/compiler/python/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-plugin_unittest.o -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/python/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-plugin_unittest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-plugin_unittest.o `test -f 'google/protobuf/compiler/python/plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/plugin_unittest.cc -google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/python/protobuf_test-plugin_unittest.obj: google/protobuf/compiler/python/plugin_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/plugin_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/python/plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/plugin_unittest.cc'; fi` google/protobuf/compiler/ruby/protobuf_test-ruby_generator_unittest.o: google/protobuf/compiler/ruby/ruby_generator_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/ruby/protobuf_test-ruby_generator_unittest.o -MD -MP -MF google/protobuf/compiler/ruby/$(DEPDIR)/protobuf_test-ruby_generator_unittest.Tpo -c -o google/protobuf/compiler/ruby/protobuf_test-ruby_generator_unittest.o `test -f 'google/protobuf/compiler/ruby/ruby_generator_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -6691,6 +6730,20 @@ google/protobuf/protobuf_test-generated_message_reflection_unittest.obj: google/ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi` +google/protobuf/protobuf_test-generated_message_tctable_lite_test.o: google/protobuf/generated_message_tctable_lite_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_tctable_lite_test.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Tpo -c -o google/protobuf/protobuf_test-generated_message_tctable_lite_test.o `test -f 'google/protobuf/generated_message_tctable_lite_test.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_tctable_lite_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/generated_message_tctable_lite_test.cc' object='google/protobuf/protobuf_test-generated_message_tctable_lite_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_tctable_lite_test.o `test -f 'google/protobuf/generated_message_tctable_lite_test.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_tctable_lite_test.cc + +google/protobuf/protobuf_test-generated_message_tctable_lite_test.obj: google/protobuf/generated_message_tctable_lite_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_tctable_lite_test.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Tpo -c -o google/protobuf/protobuf_test-generated_message_tctable_lite_test.obj `if test -f 'google/protobuf/generated_message_tctable_lite_test.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_tctable_lite_test.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_tctable_lite_test.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/generated_message_tctable_lite_test.cc' object='google/protobuf/protobuf_test-generated_message_tctable_lite_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_tctable_lite_test.obj `if test -f 'google/protobuf/generated_message_tctable_lite_test.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_tctable_lite_test.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_tctable_lite_test.cc'; fi` + google/protobuf/protobuf_test-inlined_string_field_unittest.o: google/protobuf/inlined_string_field_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-inlined_string_field_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Tpo -c -o google/protobuf/protobuf_test-inlined_string_field_unittest.o `test -f 'google/protobuf/inlined_string_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/inlined_string_field_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Po @@ -7391,33 +7444,33 @@ google/protobuf/protobuf_test-any_test.pb.obj: google/protobuf/any_test.pb.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-any_test.pb.obj `if test -f 'google/protobuf/any_test.pb.cc'; then $(CYGPATH_W) 'google/protobuf/any_test.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/any_test.pb.cc'; fi` -google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc -google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_bad_identifiers.pb.cc'; fi` -google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.o: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.o: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.o `test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/test_large_enum_value.pb.cc -google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ +google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.obj: google/protobuf/compiler/cpp/test_large_enum_value.pb.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='google/protobuf/compiler/cpp/test_large_enum_value.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-test_large_enum_value.pb.obj `if test -f 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/test_large_enum_value.pb.cc'; fi` google/protobuf/protobuf_test-map_proto2_unittest.pb.o: google/protobuf/map_proto2_unittest.pb.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-map_proto2_unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-map_proto2_unittest.pb.Tpo -c -o google/protobuf/protobuf_test-map_proto2_unittest.pb.o `test -f 'google/protobuf/map_proto2_unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/map_proto2_unittest.pb.cc @@ -8059,7 +8112,6 @@ clean-libtool: -rm -rf google/protobuf/compiler/cpp/.libs google/protobuf/compiler/cpp/_libs -rm -rf google/protobuf/compiler/csharp/.libs google/protobuf/compiler/csharp/_libs -rm -rf google/protobuf/compiler/java/.libs google/protobuf/compiler/java/_libs - -rm -rf google/protobuf/compiler/js/.libs google/protobuf/compiler/js/_libs -rm -rf google/protobuf/compiler/objectivec/.libs google/protobuf/compiler/objectivec/_libs -rm -rf google/protobuf/compiler/php/.libs google/protobuf/compiler/php/_libs -rm -rf google/protobuf/compiler/python/.libs google/protobuf/compiler/python/_libs @@ -8413,6 +8465,8 @@ check: check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(DATA) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES +install-checkPROGRAMS: install-libLTLIBRARIES + installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ @@ -8457,8 +8511,6 @@ distclean-generic: -rm -f google/protobuf/compiler/csharp/$(am__dirstamp) -rm -f google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp) -rm -f google/protobuf/compiler/java/$(am__dirstamp) - -rm -f google/protobuf/compiler/js/$(DEPDIR)/$(am__dirstamp) - -rm -f google/protobuf/compiler/js/$(am__dirstamp) -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/$(am__dirstamp) -rm -f google/protobuf/compiler/objectivec/$(am__dirstamp) -rm -f google/protobuf/compiler/php/$(DEPDIR)/$(am__dirstamp) @@ -8497,6 +8549,7 @@ distclean: distclean-am -rm -f google/protobuf/$(DEPDIR)/api.pb.Plo -rm -f google/protobuf/$(DEPDIR)/arena.Plo -rm -f google/protobuf/$(DEPDIR)/arenastring.Plo + -rm -f google/protobuf/$(DEPDIR)/arenaz_sampler.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor.pb.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor_database.Plo @@ -8509,8 +8562,6 @@ distclean: distclean-am -rm -f google/protobuf/$(DEPDIR)/generated_enum_util.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_bases.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_reflection.Plo - -rm -f google/protobuf/$(DEPDIR)/generated_message_table_driven.Plo - -rm -f google/protobuf/$(DEPDIR)/generated_message_table_driven_lite.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_tctable_full.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_tctable_lite.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_util.Plo @@ -8613,12 +8664,14 @@ distclean: distclean-am -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arena_test_util.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arena_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arenastring_unittest.Po + -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-drop_unknown_fields_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po + -rm -f google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-map_field_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-map_lite_test_util.Po @@ -8700,33 +8753,34 @@ distclean: distclean-am -rm -f google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po -rm -f google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po -rm -f google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_map_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_padding_optimizer.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_parse_function_generator.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/enum.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/enum_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/extension.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/file.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/map_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/message.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/message_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/padding_optimizer.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/parse_function_generator.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/primitive_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-metadata_test.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/service.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/string_field.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_doc_comment.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum_field.Plo @@ -8745,39 +8799,37 @@ distclean: distclean-am -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_wrapper_field.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Po -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_generator_unittest.Po - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_extension_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_kotlin_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_map_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_map_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_builder.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_builder_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_string_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po - -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po - -rm -f google/protobuf/compiler/js/$(DEPDIR)/js_generator.Plo - -rm -f google/protobuf/compiler/js/$(DEPDIR)/well_known_types_embed.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/context.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/doc_comment.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/extension.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/extension_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/file.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/generator_factory.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/kotlin_generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/map_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/map_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_builder.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_builder_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/name_resolver.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/primitive_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/primitive_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po + -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/java/$(DEPDIR)/service.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/shared_code_generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/string_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/string_field_lite.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum_field.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_extension.Plo @@ -8792,8 +8844,10 @@ distclean: distclean-am -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_primitive_field.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/protobuf_test-objectivec_helpers_unittest.Po -rm -f google/protobuf/compiler/php/$(DEPDIR)/php_generator.Plo - -rm -f google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po - -rm -f google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/python/$(DEPDIR)/pyi_generator.Plo -rm -f google/protobuf/compiler/ruby/$(DEPDIR)/protobuf_test-ruby_generator_unittest.Po -rm -f google/protobuf/compiler/ruby/$(DEPDIR)/ruby_generator.Plo -rm -f google/protobuf/io/$(DEPDIR)/coded_stream.Plo @@ -8967,6 +9021,7 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/$(DEPDIR)/api.pb.Plo -rm -f google/protobuf/$(DEPDIR)/arena.Plo -rm -f google/protobuf/$(DEPDIR)/arenastring.Plo + -rm -f google/protobuf/$(DEPDIR)/arenaz_sampler.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor.pb.Plo -rm -f google/protobuf/$(DEPDIR)/descriptor_database.Plo @@ -8979,8 +9034,6 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/$(DEPDIR)/generated_enum_util.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_bases.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_reflection.Plo - -rm -f google/protobuf/$(DEPDIR)/generated_message_table_driven.Plo - -rm -f google/protobuf/$(DEPDIR)/generated_message_table_driven_lite.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_tctable_full.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_tctable_lite.Plo -rm -f google/protobuf/$(DEPDIR)/generated_message_util.Plo @@ -9083,12 +9136,14 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arena_test_util.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arena_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arenastring_unittest.Po + -rm -f google/protobuf/$(DEPDIR)/protobuf_test-arenaz_sampler_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-drop_unknown_fields_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po + -rm -f google/protobuf/$(DEPDIR)/protobuf_test-generated_message_tctable_lite_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-inlined_string_field_unittest.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-map_field_test.Po -rm -f google/protobuf/$(DEPDIR)/protobuf_test-map_lite_test_util.Po @@ -9170,33 +9225,34 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po -rm -f google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po -rm -f google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_map_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_padding_optimizer.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_parse_function_generator.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_move_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_large_enum_value.pb.Po - -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/enum.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/enum_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/extension.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/file.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/map_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/message.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/message_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/no_warning_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/padding_optimizer.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/parse_function_generator.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/primitive_field.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-bootstrap_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-message_size_unittest.Po -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-metadata_test.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-move_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_bad_identifiers.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-test_large_enum_value.pb.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-unittest.Po + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/service.Plo + -rm -f google/protobuf/compiler/cpp/$(DEPDIR)/string_field.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_doc_comment.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_enum_field.Plo @@ -9215,39 +9271,37 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/csharp_wrapper_field.Plo -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_bootstrap_unittest.Po -rm -f google/protobuf/compiler/csharp/$(DEPDIR)/protobuf_test-csharp_generator_unittest.Po - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_enum_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_extension_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_kotlin_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_map_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_map_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_builder.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_builder_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_message_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/java_string_field_lite.Plo - -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po - -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po - -rm -f google/protobuf/compiler/js/$(DEPDIR)/js_generator.Plo - -rm -f google/protobuf/compiler/js/$(DEPDIR)/well_known_types_embed.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/context.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/doc_comment.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/enum_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/extension.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/extension_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/file.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/generator_factory.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/kotlin_generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/map_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/map_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_builder.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_builder_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/message_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/name_resolver.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/primitive_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/primitive_field_lite.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-doc_comment_unittest.Po + -rm -f google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/java/$(DEPDIR)/service.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/shared_code_generator.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/string_field.Plo + -rm -f google/protobuf/compiler/java/$(DEPDIR)/string_field_lite.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_enum_field.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_extension.Plo @@ -9262,8 +9316,10 @@ maintainer-clean: maintainer-clean-am -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/objectivec_primitive_field.Plo -rm -f google/protobuf/compiler/objectivec/$(DEPDIR)/protobuf_test-objectivec_helpers_unittest.Po -rm -f google/protobuf/compiler/php/$(DEPDIR)/php_generator.Plo - -rm -f google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po - -rm -f google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/generator.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/helpers.Plo + -rm -f google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-plugin_unittest.Po + -rm -f google/protobuf/compiler/python/$(DEPDIR)/pyi_generator.Plo -rm -f google/protobuf/compiler/ruby/$(DEPDIR)/protobuf_test-ruby_generator_unittest.Po -rm -f google/protobuf/compiler/ruby/$(DEPDIR)/ruby_generator.Plo -rm -f google/protobuf/io/$(DEPDIR)/coded_stream.Plo diff --git a/third_party/protobuf/src/README.md b/third_party/protobuf/src/README.md index 9db40fdd..cf843d75 100644 --- a/third_party/protobuf/src/README.md +++ b/third_party/protobuf/src/README.md @@ -48,7 +48,7 @@ Buffer compiler (protoc) execute the following: ./configure - make + make -j$(nproc) # $(nproc) ensures it uses all cores for compilation make check sudo make install sudo ldconfig # refresh shared library cache. @@ -129,6 +129,10 @@ Mac installations. sudo /opt/local/bin/port install autoconf automake libtool +Alternative for Homebrew users: + + brew install autoconf automake libtool + Then follow the Unix instructions above. **Note for cross-compiling** diff --git a/third_party/protobuf/src/google/protobuf/any.cc b/third_party/protobuf/src/google/protobuf/any.cc index 73c002f6..346fa19f 100644 --- a/third_party/protobuf/src/google/protobuf/any.cc +++ b/third_party/protobuf/src/google/protobuf/any.cc @@ -35,6 +35,7 @@ #include #include +// Must be included last. #include namespace google { @@ -48,10 +49,8 @@ bool AnyMetadata::PackFrom(Arena* arena, const Message& message) { bool AnyMetadata::PackFrom(Arena* arena, const Message& message, StringPiece type_url_prefix) { type_url_->Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), arena); - return message.SerializeToString( - value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); + return message.SerializeToString(value_->Mutable(arena)); } bool AnyMetadata::UnpackTo(Message* message) const { diff --git a/third_party/protobuf/src/google/protobuf/any.h b/third_party/protobuf/src/google/protobuf/any.h index e8336fa1..92ea2bb2 100644 --- a/third_party/protobuf/src/google/protobuf/any.h +++ b/third_party/protobuf/src/google/protobuf/any.h @@ -37,6 +37,7 @@ #include #include +// Must be included last. #include namespace google { @@ -129,8 +130,8 @@ class PROTOBUF_EXPORT AnyMetadata { // *full_type_name. Returns false if the type_url does not have a "/" // in the type url separating the full type name. // -// NOTE: this function is available publicly as: -// google::protobuf::Any() // static method on the generated message type. +// NOTE: this function is available publicly as a static method on the +// generated message type: google::protobuf::Any::ParseAnyTypeUrl() bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name); // Get the proto type name and prefix from Any::type_url value. For example, diff --git a/third_party/protobuf/src/google/protobuf/any.pb.cc b/third_party/protobuf/src/google/protobuf/any.pb.cc index 52c6ccca..c02f9eb7 100644 --- a/third_party/protobuf/src/google/protobuf/any.pb.cc +++ b/third_party/protobuf/src/google/protobuf/any.pb.cc @@ -16,25 +16,34 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + +#if defined(__llvm__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wuninitialized" +#endif // __llvm__ PROTOBUF_NAMESPACE_OPEN -constexpr Any::Any( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , value_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , _any_metadata_(&type_url_, &value_){} +PROTOBUF_CONSTEXPR Any::Any( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_}} {} struct AnyDefaultTypeInternal { - constexpr AnyDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR AnyDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~AnyDefaultTypeInternal() {} union { Any _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT AnyDefaultTypeInternal _Any_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 AnyDefaultTypeInternal _Any_default_instance_; PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1]; +static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -43,15 +52,15 @@ const uint32_t TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] PROTOBUF_S ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, type_url_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, value_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, _impl_.type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Any, _impl_.value_), }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Any)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Any_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::_Any_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -62,19 +71,21 @@ const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_ "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT" "ypesb\006proto3" ; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { - false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", - &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { + false, false, 212, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, + "google/protobuf/any.proto", + &descriptor_table_google_2fprotobuf_2fany_2eproto_once, nullptr, 0, 1, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fany_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fany_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -83,14 +94,13 @@ bool Any::GetAnyFieldDescriptors( const ::PROTOBUF_NAMESPACE_ID::Message& message, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field) { - return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors( + return ::_pbi::GetAnyFieldDescriptors( message, type_url_field, value_field); } bool Any::ParseAnyTypeUrl( ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, std::string* full_type_name) { - return ::PROTOBUF_NAMESPACE_ID::internal::ParseAnyTypeUrl(type_url, - full_type_name); + return ::_pbi::ParseAnyTypeUrl(type_url, full_type_name); } class Any::_Internal { @@ -99,69 +109,77 @@ class Any::_Internal { Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), - _any_metadata_(&type_url_, &value_) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.Any) } Any::Any(const Any& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _any_metadata_(&type_url_, &value_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + Any* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.type_url_){} + , decltype(_impl_.value_){} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_type_url().empty()) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), - GetArenaForAllocation()); + _this->_impl_.type_url_.Set(from._internal_type_url(), + _this->GetArenaForAllocation()); } - value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.value_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.value_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_value().empty()) { - value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), - GetArenaForAllocation()); + _this->_impl_.value_.Set(from._internal_value(), + _this->GetArenaForAllocation()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) } -inline void Any::SharedCtor() { -type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +inline void Any::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.type_url_){} + , decltype(_impl_.value_){} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_._any_metadata_)*/{&_impl_.type_url_, &_impl_.value_} + }; + _impl_.type_url_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.type_url_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.value_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.value_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } Any::~Any() { // @@protoc_insertion_point(destructor:google.protobuf.Any) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Any::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.type_url_.Destroy(); + _impl_.value_.Destroy(); + _impl_._any_metadata_.~AnyMetadata(); } -void Any::ArenaDtor(void* object) { - Any* _this = reinterpret_cast< Any* >(object); - (void)_this; -} -void Any::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Any::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void Any::Clear() { @@ -170,24 +188,24 @@ void Any::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - type_url_.ClearToEmpty(); - value_.ClearToEmpty(); + _impl_.type_url_.ClearToEmpty(); + _impl_.value_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Any::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string type_url = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Any.type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Any.type_url")); } else goto handle_unusual; continue; @@ -195,7 +213,7 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_value(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); } else goto handle_unusual; @@ -246,7 +264,7 @@ uint8_t* Any::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any) @@ -275,35 +293,31 @@ size_t Any::ByteSizeLong() const { this->_internal_value()); } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Any::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, Any::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Any::GetClassData() const { return &_class_data_; } -void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void Any::MergeFrom(const Any& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any) - GOOGLE_DCHECK_NE(&from, this); +void Any::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; if (!from._internal_type_url().empty()) { - _internal_set_type_url(from._internal_type_url()); + _this->_internal_set_type_url(from._internal_type_url()); } if (!from._internal_value().empty()) { - _internal_set_value(from._internal_value()); + _this->_internal_set_value(from._internal_value()); } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void Any::CopyFrom(const Any& from) { @@ -323,19 +337,17 @@ void Any::InternalSwap(Any* other) { auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &type_url_, lhs_arena, - &other->type_url_, rhs_arena + &_impl_.type_url_, lhs_arena, + &other->_impl_.type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &value_, lhs_arena, - &other->value_, rhs_arena + &_impl_.value_, lhs_arena, + &other->_impl_.value_, rhs_arena ); } ::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once, file_level_metadata_google_2fprotobuf_2fany_2eproto[0]); } @@ -343,10 +355,14 @@ void Any::InternalSwap(Any* other) { // @@protoc_insertion_point(namespace_scope) PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Any* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Any >(arena); } PROTOBUF_NAMESPACE_CLOSE // @@protoc_insertion_point(global_scope) +#if defined(__llvm__) + #pragma clang diagnostic pop +#endif // __llvm__ #include diff --git a/third_party/protobuf/src/google/protobuf/any.pb.h b/third_party/protobuf/src/google/protobuf/any.pb.h index ab07cc70..2c060526 100644 --- a/third_party/protobuf/src/google/protobuf/any.pb.h +++ b/third_party/protobuf/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3021000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -42,14 +41,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto; @@ -70,7 +61,7 @@ class PROTOBUF_EXPORT Any final : public: inline Any() : Any(nullptr) {} ~Any() override; - explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Any(const Any& from); Any(Any&& from) noexcept @@ -118,14 +109,16 @@ class PROTOBUF_EXPORT Any final : // implements Any ----------------------------------------------- bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { - return _any_metadata_.PackFrom(GetArena(), message); + GOOGLE_DCHECK_NE(&message, this); + return _impl_._any_metadata_.PackFrom(GetArena(), message); } bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { - return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix); + GOOGLE_DCHECK_NE(&message, this); + return _impl_._any_metadata_.PackFrom(GetArena(), message, type_url_prefix); } bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const { - return _any_metadata_.UnpackTo(message); + return _impl_._any_metadata_.UnpackTo(message); } static bool GetAnyFieldDescriptors( const ::PROTOBUF_NAMESPACE_ID::Message& message, @@ -133,18 +126,18 @@ class PROTOBUF_EXPORT Any final : const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field); template ::value>::type> bool PackFrom(const T& message) { - return _any_metadata_.PackFrom(GetArena(), message); + return _impl_._any_metadata_.PackFrom(GetArena(), message); } template ::value>::type> bool PackFrom(const T& message, ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { - return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix);} + return _impl_._any_metadata_.PackFrom(GetArena(), message, type_url_prefix);} template ::value>::type> bool UnpackTo(T* message) const { - return _any_metadata_.UnpackTo(message); + return _impl_._any_metadata_.UnpackTo(message); } template bool Is() const { - return _any_metadata_.Is(); + return _impl_._any_metadata_.Is(); } static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, std::string* full_type_name); @@ -178,9 +171,11 @@ class PROTOBUF_EXPORT Any final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const Any& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Any& from); + void MergeFrom( const Any& from) { + Any::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -189,10 +184,10 @@ class PROTOBUF_EXPORT Any final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(Any* other); @@ -205,9 +200,6 @@ class PROTOBUF_EXPORT Any final : protected: explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -258,10 +250,13 @@ class PROTOBUF_EXPORT Any final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata _any_metadata_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata _any_metadata_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fany_2eproto; }; // =================================================================== @@ -277,7 +272,7 @@ class PROTOBUF_EXPORT Any final : // string type_url = 1; inline void Any::clear_type_url() { - type_url_.ClearToEmpty(); + _impl_.type_url_.ClearToEmpty(); } inline const std::string& Any::type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) @@ -287,7 +282,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_type_url(ArgT0&& arg0, ArgT... args) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) } inline std::string* Any::mutable_type_url() { @@ -296,19 +291,19 @@ inline std::string* Any::mutable_type_url() { return _s; } inline const std::string& Any::_internal_type_url() const { - return type_url_.Get(); + return _impl_.type_url_.Get(); } inline void Any::_internal_set_type_url(const std::string& value) { - type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Any::_internal_mutable_type_url() { - return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Any::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) - return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.type_url_.Release(); } inline void Any::set_allocated_type_url(std::string* type_url) { if (type_url != nullptr) { @@ -316,11 +311,10 @@ inline void Any::set_allocated_type_url(std::string* type_url) { } else { } - type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, - GetArenaForAllocation()); + _impl_.type_url_.SetAllocated(type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.type_url_.IsDefault()) { + _impl_.type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) @@ -328,7 +322,7 @@ inline void Any::set_allocated_type_url(std::string* type_url) { // bytes value = 2; inline void Any::clear_value() { - value_.ClearToEmpty(); + _impl_.value_.ClearToEmpty(); } inline const std::string& Any::value() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.value) @@ -338,7 +332,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_value(ArgT0&& arg0, ArgT... args) { - value_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.value_.SetBytes(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Any.value) } inline std::string* Any::mutable_value() { @@ -347,19 +341,19 @@ inline std::string* Any::mutable_value() { return _s; } inline const std::string& Any::_internal_value() const { - return value_.Get(); + return _impl_.value_.Get(); } inline void Any::_internal_set_value(const std::string& value) { - value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.value_.Set(value, GetArenaForAllocation()); } inline std::string* Any::_internal_mutable_value() { - return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.value_.Mutable(GetArenaForAllocation()); } inline std::string* Any::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.Any.value) - return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.value_.Release(); } inline void Any::set_allocated_value(std::string* value) { if (value != nullptr) { @@ -367,11 +361,10 @@ inline void Any::set_allocated_value(std::string* value) { } else { } - value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, - GetArenaForAllocation()); + _impl_.value_.SetAllocated(value, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (value_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.value_.IsDefault()) { + _impl_.value_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) diff --git a/third_party/protobuf/src/google/protobuf/any.proto b/third_party/protobuf/src/google/protobuf/any.proto index 6ed8a23c..e2c2042f 100644 --- a/third_party/protobuf/src/google/protobuf/any.proto +++ b/third_party/protobuf/src/google/protobuf/any.proto @@ -64,7 +64,7 @@ option objc_class_prefix = "GPB"; // foo = any.unpack(Foo.class); // } // -// Example 3: Pack and unpack a message in Python. +// Example 3: Pack and unpack a message in Python. // // foo = Foo(...) // any = Any() @@ -74,7 +74,7 @@ option objc_class_prefix = "GPB"; // any.Unpack(foo) // ... // -// Example 4: Pack and unpack a message in Go +// Example 4: Pack and unpack a message in Go // // foo := &pb.Foo{...} // any, err := anypb.New(foo) @@ -95,7 +95,7 @@ option objc_class_prefix = "GPB"; // // // JSON -// ==== +// // The JSON representation of an `Any` value uses the regular // representation of the deserialized, embedded message, with an // additional field `@type` which contains the type URL. Example: diff --git a/third_party/protobuf/src/google/protobuf/any_lite.cc b/third_party/protobuf/src/google/protobuf/any_lite.cc index a98559da..f283a31b 100644 --- a/third_party/protobuf/src/google/protobuf/any_lite.cc +++ b/third_party/protobuf/src/google/protobuf/any_lite.cc @@ -28,12 +28,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include - #include +#include +#include #include #include -#include namespace google { namespace protobuf { @@ -56,10 +55,8 @@ const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; bool AnyMetadata::InternalPackFrom(Arena* arena, const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { - type_url_->Set(&::google::protobuf::internal::GetEmptyString(), - GetTypeUrl(type_name, type_url_prefix), arena); - return message.SerializeToString( - value_->Mutable(ArenaStringPtr::EmptyDefault{}, arena)); + type_url_->Set(GetTypeUrl(type_name, type_url_prefix), arena); + return message.SerializeToString(value_->Mutable(arena)); } bool AnyMetadata::InternalUnpackTo(StringPiece type_name, diff --git a/third_party/protobuf/src/google/protobuf/any_test.cc b/third_party/protobuf/src/google/protobuf/any_test.cc index 1d136aa5..a82afb21 100644 --- a/third_party/protobuf/src/google/protobuf/any_test.cc +++ b/third_party/protobuf/src/google/protobuf/any_test.cc @@ -176,6 +176,16 @@ TEST(AnyTest, MoveAssignment) { EXPECT_EQ(12345, payload.int32_value()); } +#ifdef PROTOBUF_HAS_DEATH_TEST +#ifndef NDEBUG +TEST(AnyTest, PackSelfDeath) { + google::protobuf::Any any; + EXPECT_DEATH(any.PackFrom(any), "&message"); + EXPECT_DEATH(any.PackFrom(any, ""), "&message"); +} +#endif // !NDEBUG +#endif // PROTOBUF_HAS_DEATH_TEST + } // namespace } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/api.pb.cc b/third_party/protobuf/src/google/protobuf/api.pb.cc index 72cc72e0..24b60497 100644 --- a/third_party/protobuf/src/google/protobuf/api.pb.cc +++ b/third_party/protobuf/src/google/protobuf/api.pb.cc @@ -16,62 +16,67 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + PROTOBUF_NAMESPACE_OPEN -constexpr Api::Api( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : methods_() - , options_() - , mixins_() - , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , version_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , source_context_(nullptr) - , syntax_(0) -{} +PROTOBUF_CONSTEXPR Api::Api( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.methods_)*/{} + , /*decltype(_impl_.options_)*/{} + , /*decltype(_impl_.mixins_)*/{} + , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.version_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.source_context_)*/nullptr + , /*decltype(_impl_.syntax_)*/0 + , /*decltype(_impl_._cached_size_)*/{}} {} struct ApiDefaultTypeInternal { - constexpr ApiDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR ApiDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~ApiDefaultTypeInternal() {} union { Api _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ApiDefaultTypeInternal _Api_default_instance_; -constexpr Method::Method( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : options_() - , name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , request_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , response_type_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , request_streaming_(false) - , response_streaming_(false) - , syntax_(0) -{} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_; +PROTOBUF_CONSTEXPR Method::Method( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.options_)*/{} + , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.request_type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.response_type_url_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.request_streaming_)*/false + , /*decltype(_impl_.response_streaming_)*/false + , /*decltype(_impl_.syntax_)*/0 + , /*decltype(_impl_._cached_size_)*/{}} {} struct MethodDefaultTypeInternal { - constexpr MethodDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR MethodDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~MethodDefaultTypeInternal() {} union { Method _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MethodDefaultTypeInternal _Method_default_instance_; -constexpr Mixin::Mixin( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , root_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string){} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_; +PROTOBUF_CONSTEXPR Mixin::Mixin( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.root_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_._cached_size_)*/{}} {} struct MixinDefaultTypeInternal { - constexpr MixinDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR MixinDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~MixinDefaultTypeInternal() {} union { Mixin _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT MixinDefaultTypeInternal _Mixin_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MixinDefaultTypeInternal _Mixin_default_instance_; PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3]; +static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -80,45 +85,45 @@ const uint32_t TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] PROTOBUF_S ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, name_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, methods_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, options_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, version_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, source_context_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, mixins_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, syntax_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.methods_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.version_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.source_context_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.mixins_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Api, _impl_.syntax_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, name_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_type_url_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, request_streaming_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_type_url_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, response_streaming_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, options_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, syntax_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.request_type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.request_streaming_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.response_type_url_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.response_streaming_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.options_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Method, _impl_.syntax_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, name_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, root_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::Mixin, _impl_.root_), }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Api)}, { 13, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Method)}, { 26, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::Mixin)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Api_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Method_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::_Method_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -142,23 +147,25 @@ const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_ "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google." "Protobuf.WellKnownTypesb\006proto3" ; -static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = { +static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = { &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, &::descriptor_table_google_2fprotobuf_2ftype_2eproto, }; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { - false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", - &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { + false, false, 751, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, + "google/protobuf/api.proto", + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 2, 3, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fapi_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fapi_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== @@ -170,97 +177,105 @@ class Api::_Internal { const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::_Internal::source_context(const Api* msg) { - return *msg->source_context_; + return *msg->_impl_.source_context_; } void Api::clear_options() { - options_.Clear(); + _impl_.options_.Clear(); } void Api::clear_source_context() { - if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { - delete source_context_; + if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) { + delete _impl_.source_context_; } - source_context_ = nullptr; + _impl_.source_context_ = nullptr; } Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), - methods_(arena), - options_(arena), - mixins_(arena) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.Api) } Api::Api(const Api& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - methods_(from.methods_), - options_(from.options_), - mixins_(from.mixins_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + Api* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.methods_){from._impl_.methods_} + , decltype(_impl_.options_){from._impl_.options_} + , decltype(_impl_.mixins_){from._impl_.mixins_} + , decltype(_impl_.name_){} + , decltype(_impl_.version_){} + , decltype(_impl_.source_context_){nullptr} + , decltype(_impl_.syntax_){} + , /*decltype(_impl_._cached_size_)*/{}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), - GetArenaForAllocation()); + _this->_impl_.name_.Set(from._internal_name(), + _this->GetArenaForAllocation()); } - version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.version_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.version_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_version().empty()) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(), - GetArenaForAllocation()); + _this->_impl_.version_.Set(from._internal_version(), + _this->GetArenaForAllocation()); } if (from._internal_has_source_context()) { - source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); - } else { - source_context_ = nullptr; + _this->_impl_.source_context_ = new ::PROTOBUF_NAMESPACE_ID::SourceContext(*from._impl_.source_context_); } - syntax_ = from.syntax_; + _this->_impl_.syntax_ = from._impl_.syntax_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Api) } -inline void Api::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -::memset(reinterpret_cast(this) + static_cast( - reinterpret_cast(&source_context_) - reinterpret_cast(this)), - 0, static_cast(reinterpret_cast(&syntax_) - - reinterpret_cast(&source_context_)) + sizeof(syntax_)); +inline void Api::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.methods_){arena} + , decltype(_impl_.options_){arena} + , decltype(_impl_.mixins_){arena} + , decltype(_impl_.name_){} + , decltype(_impl_.version_){} + , decltype(_impl_.source_context_){nullptr} + , decltype(_impl_.syntax_){0} + , /*decltype(_impl_._cached_size_)*/{} + }; + _impl_.name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.version_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.version_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } Api::~Api() { // @@protoc_insertion_point(destructor:google.protobuf.Api) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Api::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) delete source_context_; + _impl_.methods_.~RepeatedPtrField(); + _impl_.options_.~RepeatedPtrField(); + _impl_.mixins_.~RepeatedPtrField(); + _impl_.name_.Destroy(); + _impl_.version_.Destroy(); + if (this != internal_default_instance()) delete _impl_.source_context_; } -void Api::ArenaDtor(void* object) { - Api* _this = reinterpret_cast< Api* >(object); - (void)_this; -} -void Api::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Api::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void Api::Clear() { @@ -269,32 +284,32 @@ void Api::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - methods_.Clear(); - options_.Clear(); - mixins_.Clear(); - name_.ClearToEmpty(); - version_.ClearToEmpty(); - if (GetArenaForAllocation() == nullptr && source_context_ != nullptr) { - delete source_context_; + _impl_.methods_.Clear(); + _impl_.options_.Clear(); + _impl_.mixins_.Clear(); + _impl_.name_.ClearToEmpty(); + _impl_.version_.ClearToEmpty(); + if (GetArenaForAllocation() == nullptr && _impl_.source_context_ != nullptr) { + delete _impl_.source_context_; } - source_context_ = nullptr; - syntax_ = 0; + _impl_.source_context_ = nullptr; + _impl_.syntax_ = 0; _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Api::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.name")); } else goto handle_unusual; continue; @@ -328,9 +343,9 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_version(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Api.version")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Api.version")); } else goto handle_unusual; continue; @@ -404,19 +419,19 @@ uint8_t* Api::_InternalSerialize( } // repeated .google.protobuf.Method methods = 2; - for (unsigned int i = 0, - n = static_cast(this->_internal_methods_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_methods_size()); i < n; i++) { + const auto& repfield = this->_internal_methods(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(2, this->_internal_methods(i), target, stream); + InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream); } // repeated .google.protobuf.Option options = 3; - for (unsigned int i = 0, - n = static_cast(this->_internal_options_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_options_size()); i < n; i++) { + const auto& repfield = this->_internal_options(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(3, this->_internal_options(i), target, stream); + InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream); } // string version = 4; @@ -431,29 +446,28 @@ uint8_t* Api::_InternalSerialize( // .google.protobuf.SourceContext source_context = 5; if (this->_internal_has_source_context()) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 5, _Internal::source_context(this), target, stream); + InternalWriteMessage(5, _Internal::source_context(this), + _Internal::source_context(this).GetCachedSize(), target, stream); } // repeated .google.protobuf.Mixin mixins = 6; - for (unsigned int i = 0, - n = static_cast(this->_internal_mixins_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_mixins_size()); i < n; i++) { + const auto& repfield = this->_internal_mixins(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(6, this->_internal_mixins(i), target, stream); + InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + target = ::_pbi::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api) @@ -470,21 +484,21 @@ size_t Api::ByteSizeLong() const { // repeated .google.protobuf.Method methods = 2; total_size += 1UL * this->_internal_methods_size(); - for (const auto& msg : this->methods_) { + for (const auto& msg : this->_impl_.methods_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } // repeated .google.protobuf.Option options = 3; total_size += 1UL * this->_internal_options_size(); - for (const auto& msg : this->options_) { + for (const auto& msg : this->_impl_.options_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } // repeated .google.protobuf.Mixin mixins = 6; total_size += 1UL * this->_internal_mixins_size(); - for (const auto& msg : this->mixins_) { + for (const auto& msg : this->_impl_.mixins_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } @@ -507,53 +521,50 @@ size_t Api::ByteSizeLong() const { if (this->_internal_has_source_context()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *source_context_); + *_impl_.source_context_); } // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax()); } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Api::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, Api::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Api::GetClassData() const { return &_class_data_; } -void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void Api::MergeFrom(const Api& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api) - GOOGLE_DCHECK_NE(&from, this); +void Api::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - methods_.MergeFrom(from.methods_); - options_.MergeFrom(from.options_); - mixins_.MergeFrom(from.mixins_); + _this->_impl_.methods_.MergeFrom(from._impl_.methods_); + _this->_impl_.options_.MergeFrom(from._impl_.options_); + _this->_impl_.mixins_.MergeFrom(from._impl_.mixins_); if (!from._internal_name().empty()) { - _internal_set_name(from._internal_name()); + _this->_internal_set_name(from._internal_name()); } if (!from._internal_version().empty()) { - _internal_set_version(from._internal_version()); + _this->_internal_set_version(from._internal_version()); } if (from._internal_has_source_context()) { - _internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); + _this->_internal_mutable_source_context()->::PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom( + from._internal_source_context()); } if (from._internal_syntax() != 0) { - _internal_set_syntax(from._internal_syntax()); + _this->_internal_set_syntax(from._internal_syntax()); } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void Api::CopyFrom(const Api& from) { @@ -572,29 +583,27 @@ void Api::InternalSwap(Api* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - methods_.InternalSwap(&other->methods_); - options_.InternalSwap(&other->options_); - mixins_.InternalSwap(&other->mixins_); + _impl_.methods_.InternalSwap(&other->_impl_.methods_); + _impl_.options_.InternalSwap(&other->_impl_.options_); + _impl_.mixins_.InternalSwap(&other->_impl_.mixins_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, lhs_arena, - &other->name_, rhs_arena + &_impl_.name_, lhs_arena, + &other->_impl_.name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &version_, lhs_arena, - &other->version_, rhs_arena + &_impl_.version_, lhs_arena, + &other->_impl_.version_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(Api, syntax_) - + sizeof(Api::syntax_) - - PROTOBUF_FIELD_OFFSET(Api, source_context_)>( - reinterpret_cast(&source_context_), - reinterpret_cast(&other->source_context_)); + PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_) + + sizeof(Api::_impl_.syntax_) + - PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)>( + reinterpret_cast(&_impl_.source_context_), + reinterpret_cast(&other->_impl_.source_context_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]); } @@ -606,93 +615,105 @@ class Method::_Internal { }; void Method::clear_options() { - options_.Clear(); + _impl_.options_.Clear(); } Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), - options_(arena) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.Method) } Method::Method(const Method& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - options_(from.options_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + Method* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.options_){from._impl_.options_} + , decltype(_impl_.name_){} + , decltype(_impl_.request_type_url_){} + , decltype(_impl_.response_type_url_){} + , decltype(_impl_.request_streaming_){} + , decltype(_impl_.response_streaming_){} + , decltype(_impl_.syntax_){} + , /*decltype(_impl_._cached_size_)*/{}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), - GetArenaForAllocation()); + _this->_impl_.name_.Set(from._internal_name(), + _this->GetArenaForAllocation()); } - request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.request_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.request_type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_request_type_url().empty()) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), - GetArenaForAllocation()); + _this->_impl_.request_type_url_.Set(from._internal_request_type_url(), + _this->GetArenaForAllocation()); } - response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.response_type_url_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.response_type_url_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_response_type_url().empty()) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(), - GetArenaForAllocation()); + _this->_impl_.response_type_url_.Set(from._internal_response_type_url(), + _this->GetArenaForAllocation()); } - ::memcpy(&request_streaming_, &from.request_streaming_, - static_cast(reinterpret_cast(&syntax_) - - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); + ::memcpy(&_impl_.request_streaming_, &from._impl_.request_streaming_, + static_cast(reinterpret_cast(&_impl_.syntax_) - + reinterpret_cast(&_impl_.request_streaming_)) + sizeof(_impl_.syntax_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.Method) } -inline void Method::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -::memset(reinterpret_cast(this) + static_cast( - reinterpret_cast(&request_streaming_) - reinterpret_cast(this)), - 0, static_cast(reinterpret_cast(&syntax_) - - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); +inline void Method::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.options_){arena} + , decltype(_impl_.name_){} + , decltype(_impl_.request_type_url_){} + , decltype(_impl_.response_type_url_){} + , decltype(_impl_.request_streaming_){false} + , decltype(_impl_.response_streaming_){false} + , decltype(_impl_.syntax_){0} + , /*decltype(_impl_._cached_size_)*/{} + }; + _impl_.name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.request_type_url_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.request_type_url_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.response_type_url_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.response_type_url_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } Method::~Method() { // @@protoc_insertion_point(destructor:google.protobuf.Method) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Method::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - response_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.options_.~RepeatedPtrField(); + _impl_.name_.Destroy(); + _impl_.request_type_url_.Destroy(); + _impl_.response_type_url_.Destroy(); } -void Method::ArenaDtor(void* object) { - Method* _this = reinterpret_cast< Method* >(object); - (void)_this; -} -void Method::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Method::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void Method::Clear() { @@ -701,29 +722,29 @@ void Method::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - options_.Clear(); - name_.ClearToEmpty(); - request_type_url_.ClearToEmpty(); - response_type_url_.ClearToEmpty(); - ::memset(&request_streaming_, 0, static_cast( - reinterpret_cast(&syntax_) - - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); + _impl_.options_.Clear(); + _impl_.name_.ClearToEmpty(); + _impl_.request_type_url_.ClearToEmpty(); + _impl_.response_type_url_.ClearToEmpty(); + ::memset(&_impl_.request_streaming_, 0, static_cast( + reinterpret_cast(&_impl_.syntax_) - + reinterpret_cast(&_impl_.request_streaming_)) + sizeof(_impl_.syntax_)); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Method::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.name")); } else goto handle_unusual; continue; @@ -731,16 +752,16 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_request_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.request_type_url")); } else goto handle_unusual; continue; // bool request_streaming = 3; case 3: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { - request_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + _impl_.request_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -749,16 +770,16 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_response_type_url(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Method.response_type_url")); } else goto handle_unusual; continue; // bool response_streaming = 5; case 5: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 40)) { - response_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + _impl_.response_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -837,7 +858,7 @@ uint8_t* Method::_InternalSerialize( // bool request_streaming = 3; if (this->_internal_request_streaming() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); } // string response_type_url = 4; @@ -853,26 +874,26 @@ uint8_t* Method::_InternalSerialize( // bool response_streaming = 5; if (this->_internal_response_streaming() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); + target = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); } // repeated .google.protobuf.Option options = 6; - for (unsigned int i = 0, - n = static_cast(this->_internal_options_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_options_size()); i < n; i++) { + const auto& repfield = this->_internal_options(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(6, this->_internal_options(i), target, stream); + InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( + target = ::_pbi::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method) @@ -889,7 +910,7 @@ size_t Method::ByteSizeLong() const { // repeated .google.protobuf.Option options = 6; total_size += 1UL * this->_internal_options_size(); - for (const auto& msg : this->options_) { + for (const auto& msg : this->_impl_.options_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } @@ -928,51 +949,47 @@ size_t Method::ByteSizeLong() const { // .google.protobuf.Syntax syntax = 7; if (this->_internal_syntax() != 0) { total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); + ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax()); } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Method::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, Method::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Method::GetClassData() const { return &_class_data_; } -void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void Method::MergeFrom(const Method& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method) - GOOGLE_DCHECK_NE(&from, this); +void Method::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - options_.MergeFrom(from.options_); + _this->_impl_.options_.MergeFrom(from._impl_.options_); if (!from._internal_name().empty()) { - _internal_set_name(from._internal_name()); + _this->_internal_set_name(from._internal_name()); } if (!from._internal_request_type_url().empty()) { - _internal_set_request_type_url(from._internal_request_type_url()); + _this->_internal_set_request_type_url(from._internal_request_type_url()); } if (!from._internal_response_type_url().empty()) { - _internal_set_response_type_url(from._internal_response_type_url()); + _this->_internal_set_response_type_url(from._internal_response_type_url()); } if (from._internal_request_streaming() != 0) { - _internal_set_request_streaming(from._internal_request_streaming()); + _this->_internal_set_request_streaming(from._internal_request_streaming()); } if (from._internal_response_streaming() != 0) { - _internal_set_response_streaming(from._internal_response_streaming()); + _this->_internal_set_response_streaming(from._internal_response_streaming()); } if (from._internal_syntax() != 0) { - _internal_set_syntax(from._internal_syntax()); + _this->_internal_set_syntax(from._internal_syntax()); } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void Method::CopyFrom(const Method& from) { @@ -991,32 +1008,29 @@ void Method::InternalSwap(Method* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - options_.InternalSwap(&other->options_); + _impl_.options_.InternalSwap(&other->_impl_.options_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, lhs_arena, - &other->name_, rhs_arena + &_impl_.name_, lhs_arena, + &other->_impl_.name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &request_type_url_, lhs_arena, - &other->request_type_url_, rhs_arena + &_impl_.request_type_url_, lhs_arena, + &other->_impl_.request_type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &response_type_url_, lhs_arena, - &other->response_type_url_, rhs_arena + &_impl_.response_type_url_, lhs_arena, + &other->_impl_.response_type_url_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(Method, syntax_) - + sizeof(Method::syntax_) - - PROTOBUF_FIELD_OFFSET(Method, request_streaming_)>( - reinterpret_cast(&request_streaming_), - reinterpret_cast(&other->request_streaming_)); + PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_) + + sizeof(Method::_impl_.syntax_) + - PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_)>( + reinterpret_cast(&_impl_.request_streaming_), + reinterpret_cast(&other->_impl_.request_streaming_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]); } @@ -1030,66 +1044,73 @@ class Mixin::_Internal { Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin) } Mixin::Mixin(const Mixin& from) : ::PROTOBUF_NAMESPACE_ID::Message() { + Mixin* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_.name_){} + , decltype(_impl_.root_){} + , /*decltype(_impl_._cached_size_)*/{}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_name().empty()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), - GetArenaForAllocation()); + _this->_impl_.name_.Set(from._internal_name(), + _this->GetArenaForAllocation()); } - root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.root_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.root_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (!from._internal_root().empty()) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(), - GetArenaForAllocation()); + _this->_impl_.root_.Set(from._internal_root(), + _this->GetArenaForAllocation()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin) } -inline void Mixin::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING +inline void Mixin::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_.name_){} + , decltype(_impl_.root_){} + , /*decltype(_impl_._cached_size_)*/{} + }; + _impl_.name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.root_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.root_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } Mixin::~Mixin() { // @@protoc_insertion_point(destructor:google.protobuf.Mixin) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Mixin::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.name_.Destroy(); + _impl_.root_.Destroy(); } -void Mixin::ArenaDtor(void* object) { - Mixin* _this = reinterpret_cast< Mixin* >(object); - (void)_this; -} -void Mixin::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Mixin::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void Mixin::Clear() { @@ -1098,24 +1119,24 @@ void Mixin::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - name_.ClearToEmpty(); - root_.ClearToEmpty(); + _impl_.name_.ClearToEmpty(); + _impl_.root_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Mixin::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.name")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.name")); } else goto handle_unusual; continue; @@ -1123,9 +1144,9 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_root(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.Mixin.root")); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + CHK_(::_pbi::VerifyUTF8(str, "google.protobuf.Mixin.root")); } else goto handle_unusual; continue; @@ -1179,7 +1200,7 @@ uint8_t* Mixin::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin) @@ -1208,35 +1229,31 @@ size_t Mixin::ByteSizeLong() const { this->_internal_root()); } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Mixin::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, Mixin::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Mixin::GetClassData() const { return &_class_data_; } -void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void Mixin::MergeFrom(const Mixin& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin) - GOOGLE_DCHECK_NE(&from, this); +void Mixin::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; if (!from._internal_name().empty()) { - _internal_set_name(from._internal_name()); + _this->_internal_set_name(from._internal_name()); } if (!from._internal_root().empty()) { - _internal_set_root(from._internal_root()); + _this->_internal_set_root(from._internal_root()); } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void Mixin::CopyFrom(const Mixin& from) { @@ -1256,19 +1273,17 @@ void Mixin::InternalSwap(Mixin* other) { auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, lhs_arena, - &other->name_, rhs_arena + &_impl_.name_, lhs_arena, + &other->_impl_.name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &root_, lhs_arena, - &other->root_, rhs_arena + &_impl_.root_, lhs_arena, + &other->_impl_.root_, rhs_arena ); } ::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]); } @@ -1276,13 +1291,16 @@ void Mixin::InternalSwap(Mixin* other) { // @@protoc_insertion_point(namespace_scope) PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Api* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Api >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Method* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Method >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::Mixin* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::Mixin >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/third_party/protobuf/src/google/protobuf/api.pb.h b/third_party/protobuf/src/google/protobuf/api.pb.h index 26e1946f..2c454892 100644 --- a/third_party/protobuf/src/google/protobuf/api.pb.h +++ b/third_party/protobuf/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3021000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -44,14 +43,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto; @@ -80,7 +71,7 @@ class PROTOBUF_EXPORT Api final : public: inline Api() : Api(nullptr) {} ~Api() override; - explicit constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Api(const Api& from); Api(Api&& from) noexcept @@ -155,9 +146,11 @@ class PROTOBUF_EXPORT Api final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const Api& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Api& from); + void MergeFrom( const Api& from) { + Api::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -166,10 +159,10 @@ class PROTOBUF_EXPORT Api final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(Api* other); @@ -182,9 +175,6 @@ class PROTOBUF_EXPORT Api final : protected: explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -321,14 +311,17 @@ class PROTOBUF_EXPORT Api final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method > methods_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin > mixins_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_; - ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_; - int syntax_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method > methods_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin > mixins_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_; + ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; }; // ------------------------------------------------------------------- @@ -338,7 +331,7 @@ class PROTOBUF_EXPORT Method final : public: inline Method() : Method(nullptr) {} ~Method() override; - explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Method(const Method& from); Method(Method&& from) noexcept @@ -413,9 +406,11 @@ class PROTOBUF_EXPORT Method final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const Method& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Method& from); + void MergeFrom( const Method& from) { + Method::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -424,10 +419,10 @@ class PROTOBUF_EXPORT Method final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(Method* other); @@ -440,9 +435,6 @@ class PROTOBUF_EXPORT Method final : protected: explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -557,14 +549,17 @@ class PROTOBUF_EXPORT Method final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr response_type_url_; - bool request_streaming_; - bool response_streaming_; - int syntax_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr response_type_url_; + bool request_streaming_; + bool response_streaming_; + int syntax_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; }; // ------------------------------------------------------------------- @@ -574,7 +569,7 @@ class PROTOBUF_EXPORT Mixin final : public: inline Mixin() : Mixin(nullptr) {} ~Mixin() override; - explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Mixin(const Mixin& from); Mixin(Mixin&& from) noexcept @@ -649,9 +644,11 @@ class PROTOBUF_EXPORT Mixin final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const Mixin& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Mixin& from); + void MergeFrom( const Mixin& from) { + Mixin::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -660,10 +657,10 @@ class PROTOBUF_EXPORT Mixin final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(Mixin* other); @@ -676,9 +673,6 @@ class PROTOBUF_EXPORT Mixin final : protected: explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -729,9 +723,12 @@ class PROTOBUF_EXPORT Mixin final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; }; // =================================================================== @@ -747,7 +744,7 @@ class PROTOBUF_EXPORT Mixin final : // string name = 1; inline void Api::clear_name() { - name_.ClearToEmpty(); + _impl_.name_.ClearToEmpty(); } inline const std::string& Api::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.name) @@ -757,7 +754,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Api.name) } inline std::string* Api::mutable_name() { @@ -766,19 +763,19 @@ inline std::string* Api::mutable_name() { return _s; } inline const std::string& Api::_internal_name() const { - return name_.Get(); + return _impl_.name_.Get(); } inline void Api::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.name_.Set(value, GetArenaForAllocation()); } inline std::string* Api::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.name_.Mutable(GetArenaForAllocation()); } inline std::string* Api::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Api.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.name_.Release(); } inline void Api::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -786,11 +783,10 @@ inline void Api::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + _impl_.name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.name_.IsDefault()) { + _impl_.name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) @@ -798,32 +794,32 @@ inline void Api::set_allocated_name(std::string* name) { // repeated .google.protobuf.Method methods = 2; inline int Api::_internal_methods_size() const { - return methods_.size(); + return _impl_.methods_.size(); } inline int Api::methods_size() const { return _internal_methods_size(); } inline void Api::clear_methods() { - methods_.Clear(); + _impl_.methods_.Clear(); } inline ::PROTOBUF_NAMESPACE_ID::Method* Api::mutable_methods(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods) - return methods_.Mutable(index); + return _impl_.methods_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >* Api::mutable_methods() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods) - return &methods_; + return &_impl_.methods_; } inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::_internal_methods(int index) const { - return methods_.Get(index); + return _impl_.methods_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::methods(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.Api.methods) return _internal_methods(index); } inline ::PROTOBUF_NAMESPACE_ID::Method* Api::_internal_add_methods() { - return methods_.Add(); + return _impl_.methods_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::Method* Api::add_methods() { ::PROTOBUF_NAMESPACE_ID::Method* _add = _internal_add_methods(); @@ -833,34 +829,34 @@ inline ::PROTOBUF_NAMESPACE_ID::Method* Api::add_methods() { inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >& Api::methods() const { // @@protoc_insertion_point(field_list:google.protobuf.Api.methods) - return methods_; + return _impl_.methods_; } // repeated .google.protobuf.Option options = 3; inline int Api::_internal_options_size() const { - return options_.size(); + return _impl_.options_.size(); } inline int Api::options_size() const { return _internal_options_size(); } inline ::PROTOBUF_NAMESPACE_ID::Option* Api::mutable_options(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options) - return options_.Mutable(index); + return _impl_.options_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* Api::mutable_options() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options) - return &options_; + return &_impl_.options_; } inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::_internal_options(int index) const { - return options_.Get(index); + return _impl_.options_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::options(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.Api.options) return _internal_options(index); } inline ::PROTOBUF_NAMESPACE_ID::Option* Api::_internal_add_options() { - return options_.Add(); + return _impl_.options_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::Option* Api::add_options() { ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); @@ -870,12 +866,12 @@ inline ::PROTOBUF_NAMESPACE_ID::Option* Api::add_options() { inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& Api::options() const { // @@protoc_insertion_point(field_list:google.protobuf.Api.options) - return options_; + return _impl_.options_; } // string version = 4; inline void Api::clear_version() { - version_.ClearToEmpty(); + _impl_.version_.ClearToEmpty(); } inline const std::string& Api::version() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.version) @@ -885,7 +881,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_version(ArgT0&& arg0, ArgT... args) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.version_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Api.version) } inline std::string* Api::mutable_version() { @@ -894,19 +890,19 @@ inline std::string* Api::mutable_version() { return _s; } inline const std::string& Api::_internal_version() const { - return version_.Get(); + return _impl_.version_.Get(); } inline void Api::_internal_set_version(const std::string& value) { - version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.version_.Set(value, GetArenaForAllocation()); } inline std::string* Api::_internal_mutable_version() { - return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.version_.Mutable(GetArenaForAllocation()); } inline std::string* Api::release_version() { // @@protoc_insertion_point(field_release:google.protobuf.Api.version) - return version_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.version_.Release(); } inline void Api::set_allocated_version(std::string* version) { if (version != nullptr) { @@ -914,11 +910,10 @@ inline void Api::set_allocated_version(std::string* version) { } else { } - version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version, - GetArenaForAllocation()); + _impl_.version_.SetAllocated(version, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (version_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.version_.IsDefault()) { + _impl_.version_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) @@ -926,13 +921,13 @@ inline void Api::set_allocated_version(std::string* version) { // .google.protobuf.SourceContext source_context = 5; inline bool Api::_internal_has_source_context() const { - return this != internal_default_instance() && source_context_ != nullptr; + return this != internal_default_instance() && _impl_.source_context_ != nullptr; } inline bool Api::has_source_context() const { return _internal_has_source_context(); } inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const { - const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; + const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = _impl_.source_context_; return p != nullptr ? *p : reinterpret_cast( ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } @@ -943,9 +938,9 @@ inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const inline void Api::unsafe_arena_set_allocated_source_context( ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { if (GetArenaForAllocation() == nullptr) { - delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_); } - source_context_ = source_context; + _impl_.source_context_ = source_context; if (source_context) { } else { @@ -955,8 +950,8 @@ inline void Api::unsafe_arena_set_allocated_source_context( } inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { - ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; - source_context_ = nullptr; + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_; + _impl_.source_context_ = nullptr; #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); @@ -971,17 +966,17 @@ inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() { // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context) - ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; - source_context_ = nullptr; + ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_; + _impl_.source_context_ = nullptr; return temp; } inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() { - if (source_context_ == nullptr) { + if (_impl_.source_context_ == nullptr) { auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation()); - source_context_ = p; + _impl_.source_context_ = p; } - return source_context_; + return _impl_.source_context_; } inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() { ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context(); @@ -991,12 +986,11 @@ inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() { inline void Api::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); if (message_arena == nullptr) { - delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_); } if (source_context) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< - ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)); if (message_arena != submessage_arena) { source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( @@ -1006,38 +1000,38 @@ inline void Api::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceCon } else { } - source_context_ = source_context; + _impl_.source_context_ = source_context; // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context) } // repeated .google.protobuf.Mixin mixins = 6; inline int Api::_internal_mixins_size() const { - return mixins_.size(); + return _impl_.mixins_.size(); } inline int Api::mixins_size() const { return _internal_mixins_size(); } inline void Api::clear_mixins() { - mixins_.Clear(); + _impl_.mixins_.Clear(); } inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::mutable_mixins(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins) - return mixins_.Mutable(index); + return _impl_.mixins_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >* Api::mutable_mixins() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins) - return &mixins_; + return &_impl_.mixins_; } inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::_internal_mixins(int index) const { - return mixins_.Get(index); + return _impl_.mixins_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::mixins(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins) return _internal_mixins(index); } inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::_internal_add_mixins() { - return mixins_.Add(); + return _impl_.mixins_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::add_mixins() { ::PROTOBUF_NAMESPACE_ID::Mixin* _add = _internal_add_mixins(); @@ -1047,15 +1041,15 @@ inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::add_mixins() { inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >& Api::mixins() const { // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins) - return mixins_; + return _impl_.mixins_; } // .google.protobuf.Syntax syntax = 7; inline void Api::clear_syntax() { - syntax_ = 0; + _impl_.syntax_ = 0; } inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::_internal_syntax() const { - return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.syntax_); } inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::syntax() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax) @@ -1063,7 +1057,7 @@ inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::syntax() const { } inline void Api::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { - syntax_ = value; + _impl_.syntax_ = value; } inline void Api::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { _internal_set_syntax(value); @@ -1076,7 +1070,7 @@ inline void Api::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Method::clear_name() { - name_.ClearToEmpty(); + _impl_.name_.ClearToEmpty(); } inline const std::string& Method::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.name) @@ -1086,7 +1080,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.name) } inline std::string* Method::mutable_name() { @@ -1095,19 +1089,19 @@ inline std::string* Method::mutable_name() { return _s; } inline const std::string& Method::_internal_name() const { - return name_.Get(); + return _impl_.name_.Get(); } inline void Method::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.name_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.name_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Method.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.name_.Release(); } inline void Method::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1115,11 +1109,10 @@ inline void Method::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + _impl_.name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.name_.IsDefault()) { + _impl_.name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) @@ -1127,7 +1120,7 @@ inline void Method::set_allocated_name(std::string* name) { // string request_type_url = 2; inline void Method::clear_request_type_url() { - request_type_url_.ClearToEmpty(); + _impl_.request_type_url_.ClearToEmpty(); } inline const std::string& Method::request_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) @@ -1137,7 +1130,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_request_type_url(ArgT0&& arg0, ArgT... args) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.request_type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) } inline std::string* Method::mutable_request_type_url() { @@ -1146,19 +1139,19 @@ inline std::string* Method::mutable_request_type_url() { return _s; } inline const std::string& Method::_internal_request_type_url() const { - return request_type_url_.Get(); + return _impl_.request_type_url_.Get(); } inline void Method::_internal_set_request_type_url(const std::string& value) { - request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.request_type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_request_type_url() { - return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.request_type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_request_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) - return request_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.request_type_url_.Release(); } inline void Method::set_allocated_request_type_url(std::string* request_type_url) { if (request_type_url != nullptr) { @@ -1166,11 +1159,10 @@ inline void Method::set_allocated_request_type_url(std::string* request_type_url } else { } - request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url, - GetArenaForAllocation()); + _impl_.request_type_url_.SetAllocated(request_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (request_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.request_type_url_.IsDefault()) { + _impl_.request_type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) @@ -1178,10 +1170,10 @@ inline void Method::set_allocated_request_type_url(std::string* request_type_url // bool request_streaming = 3; inline void Method::clear_request_streaming() { - request_streaming_ = false; + _impl_.request_streaming_ = false; } inline bool Method::_internal_request_streaming() const { - return request_streaming_; + return _impl_.request_streaming_; } inline bool Method::request_streaming() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming) @@ -1189,7 +1181,7 @@ inline bool Method::request_streaming() const { } inline void Method::_internal_set_request_streaming(bool value) { - request_streaming_ = value; + _impl_.request_streaming_ = value; } inline void Method::set_request_streaming(bool value) { _internal_set_request_streaming(value); @@ -1198,7 +1190,7 @@ inline void Method::set_request_streaming(bool value) { // string response_type_url = 4; inline void Method::clear_response_type_url() { - response_type_url_.ClearToEmpty(); + _impl_.response_type_url_.ClearToEmpty(); } inline const std::string& Method::response_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) @@ -1208,7 +1200,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_response_type_url(ArgT0&& arg0, ArgT... args) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.response_type_url_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) } inline std::string* Method::mutable_response_type_url() { @@ -1217,19 +1209,19 @@ inline std::string* Method::mutable_response_type_url() { return _s; } inline const std::string& Method::_internal_response_type_url() const { - return response_type_url_.Get(); + return _impl_.response_type_url_.Get(); } inline void Method::_internal_set_response_type_url(const std::string& value) { - response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.response_type_url_.Set(value, GetArenaForAllocation()); } inline std::string* Method::_internal_mutable_response_type_url() { - return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.response_type_url_.Mutable(GetArenaForAllocation()); } inline std::string* Method::release_response_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) - return response_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.response_type_url_.Release(); } inline void Method::set_allocated_response_type_url(std::string* response_type_url) { if (response_type_url != nullptr) { @@ -1237,11 +1229,10 @@ inline void Method::set_allocated_response_type_url(std::string* response_type_u } else { } - response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url, - GetArenaForAllocation()); + _impl_.response_type_url_.SetAllocated(response_type_url, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (response_type_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.response_type_url_.IsDefault()) { + _impl_.response_type_url_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) @@ -1249,10 +1240,10 @@ inline void Method::set_allocated_response_type_url(std::string* response_type_u // bool response_streaming = 5; inline void Method::clear_response_streaming() { - response_streaming_ = false; + _impl_.response_streaming_ = false; } inline bool Method::_internal_response_streaming() const { - return response_streaming_; + return _impl_.response_streaming_; } inline bool Method::response_streaming() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming) @@ -1260,7 +1251,7 @@ inline bool Method::response_streaming() const { } inline void Method::_internal_set_response_streaming(bool value) { - response_streaming_ = value; + _impl_.response_streaming_ = value; } inline void Method::set_response_streaming(bool value) { _internal_set_response_streaming(value); @@ -1269,29 +1260,29 @@ inline void Method::set_response_streaming(bool value) { // repeated .google.protobuf.Option options = 6; inline int Method::_internal_options_size() const { - return options_.size(); + return _impl_.options_.size(); } inline int Method::options_size() const { return _internal_options_size(); } inline ::PROTOBUF_NAMESPACE_ID::Option* Method::mutable_options(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options) - return options_.Mutable(index); + return _impl_.options_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >* Method::mutable_options() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options) - return &options_; + return &_impl_.options_; } inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::_internal_options(int index) const { - return options_.Get(index); + return _impl_.options_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::options(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.Method.options) return _internal_options(index); } inline ::PROTOBUF_NAMESPACE_ID::Option* Method::_internal_add_options() { - return options_.Add(); + return _impl_.options_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::Option* Method::add_options() { ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options(); @@ -1301,15 +1292,15 @@ inline ::PROTOBUF_NAMESPACE_ID::Option* Method::add_options() { inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >& Method::options() const { // @@protoc_insertion_point(field_list:google.protobuf.Method.options) - return options_; + return _impl_.options_; } // .google.protobuf.Syntax syntax = 7; inline void Method::clear_syntax() { - syntax_ = 0; + _impl_.syntax_ = 0; } inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::_internal_syntax() const { - return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(syntax_); + return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.syntax_); } inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::syntax() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax) @@ -1317,7 +1308,7 @@ inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::syntax() const { } inline void Method::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { - syntax_ = value; + _impl_.syntax_ = value; } inline void Method::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { _internal_set_syntax(value); @@ -1330,7 +1321,7 @@ inline void Method::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Mixin::clear_name() { - name_.ClearToEmpty(); + _impl_.name_.ClearToEmpty(); } inline const std::string& Mixin::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name) @@ -1340,7 +1331,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_name(ArgT0&& arg0, ArgT... args) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name) } inline std::string* Mixin::mutable_name() { @@ -1349,19 +1340,19 @@ inline std::string* Mixin::mutable_name() { return _s; } inline const std::string& Mixin::_internal_name() const { - return name_.Get(); + return _impl_.name_.Get(); } inline void Mixin::_internal_set_name(const std::string& value) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.name_.Set(value, GetArenaForAllocation()); } inline std::string* Mixin::_internal_mutable_name() { - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.name_.Mutable(GetArenaForAllocation()); } inline std::string* Mixin::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.name_.Release(); } inline void Mixin::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1369,11 +1360,10 @@ inline void Mixin::set_allocated_name(std::string* name) { } else { } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + _impl_.name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.name_.IsDefault()) { + _impl_.name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name) @@ -1381,7 +1371,7 @@ inline void Mixin::set_allocated_name(std::string* name) { // string root = 2; inline void Mixin::clear_root() { - root_.ClearToEmpty(); + _impl_.root_.ClearToEmpty(); } inline const std::string& Mixin::root() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root) @@ -1391,7 +1381,7 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_root(ArgT0&& arg0, ArgT... args) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_.root_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root) } inline std::string* Mixin::mutable_root() { @@ -1400,19 +1390,19 @@ inline std::string* Mixin::mutable_root() { return _s; } inline const std::string& Mixin::_internal_root() const { - return root_.Get(); + return _impl_.root_.Get(); } inline void Mixin::_internal_set_root(const std::string& value) { - root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_.root_.Set(value, GetArenaForAllocation()); } inline std::string* Mixin::_internal_mutable_root() { - return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return _impl_.root_.Mutable(GetArenaForAllocation()); } inline std::string* Mixin::release_root() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) - return root_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + return _impl_.root_.Release(); } inline void Mixin::set_allocated_root(std::string* root) { if (root != nullptr) { @@ -1420,11 +1410,10 @@ inline void Mixin::set_allocated_root(std::string* root) { } else { } - root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root, - GetArenaForAllocation()); + _impl_.root_.SetAllocated(root, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (root_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.root_.IsDefault()) { + _impl_.root_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) diff --git a/third_party/protobuf/src/google/protobuf/arena.cc b/third_party/protobuf/src/google/protobuf/arena.cc index 7624e0b2..6ba508a5 100644 --- a/third_party/protobuf/src/google/protobuf/arena.cc +++ b/third_party/protobuf/src/google/protobuf/arena.cc @@ -38,12 +38,15 @@ #include #include +#include +#include #include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER +// Must be included last. #include namespace google { @@ -91,11 +94,7 @@ class GetDeallocator { if (dealloc_) { dealloc_(mem.ptr, mem.size); } else { -#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) - ::operator delete(mem.ptr, mem.size); -#else - ::operator delete(mem.ptr); -#endif + internal::SizedDelete(mem.ptr, mem.size); } *space_allocated_ += mem.size; } @@ -105,18 +104,22 @@ class GetDeallocator { size_t* space_allocated_; }; -SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) { +SerialArena::SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats) + : space_allocated_(b->size) { owner_ = owner; head_ = b; ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize); limit_ = b->Pointer(b->size & static_cast(-8)); + arena_stats_ = stats; } -SerialArena* SerialArena::New(Memory mem, void* owner) { +SerialArena* SerialArena::New(Memory mem, void* owner, + ThreadSafeArenaStats* stats) { GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); - + ThreadSafeArenaStats::RecordAllocateStats( + stats, /*requested=*/mem.size, /*allocated=*/mem.size, /*wasted=*/0); auto b = new (mem.ptr) Block{nullptr, mem.size}; - return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); + return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner, stats); } template @@ -151,7 +154,14 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { head_->start = reinterpret_cast(limit_); // Record how much used in this block. - space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize); + size_t used = ptr_ - head_->Pointer(kBlockHeaderSize); + size_t wasted = head_->size - used; + space_used_ += used; + + // TODO(sbenza): Evaluate if pushing unused space into the cached blocks is a + // win. In preliminary testing showed increased memory savings as expected, + // but with a CPU regression. The regression might have been an artifact of + // the microbenchmark. auto mem = AllocateMemory(policy, head_->size, n); // We don't want to emit an expensive RMW instruction that requires @@ -159,6 +169,8 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { // regular add. auto relaxed = std::memory_order_relaxed; space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed); + ThreadSafeArenaStats::RecordAllocateStats(arena_stats_, /*requested=*/n, + /*allocated=*/mem.size, wasted); head_ = new (mem.ptr) Block{head_, mem.size}; ptr_ = head_->Pointer(kBlockHeaderSize); limit_ = head_->Pointer(head_->size); @@ -312,10 +324,12 @@ void ThreadSafeArena::Init() { #ifndef NDEBUG GOOGLE_CHECK_EQ(was_message_owned, IsMessageOwned()); #endif // NDEBUG + arena_stats_ = Sample(); } void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { - SerialArena* serial = SerialArena::New({mem, size}, &thread_cache()); + SerialArena* serial = SerialArena::New({mem, size}, &thread_cache(), + arena_stats_.MutableStats()); serial->set_next(NULL); threads_.store(serial, std::memory_order_relaxed); CacheSerialArena(serial); @@ -334,6 +348,10 @@ ThreadSafeArena::~ThreadSafeArena() { ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr; if (alloc_policy_.is_user_owned_initial_block()) { +#ifdef ADDRESS_SANITIZER + // Unpoison the initial block, now that it's going back to the user. + ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size); +#endif // ADDRESS_SANITIZER space_allocated += mem.size; } else { GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); @@ -360,6 +378,7 @@ uint64_t ThreadSafeArena::Reset() { // Discard all blocks except the special block (if present). size_t space_allocated = 0; auto mem = Free(&space_allocated); + arena_stats_.RecordReset(); AllocationPolicy* policy = alloc_policy_.get(); if (policy) { @@ -474,7 +493,8 @@ SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { // This thread doesn't have any SerialArena, which also means it doesn't // have any blocks yet. So we'll allocate its first block now. serial = SerialArena::New( - AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me); + AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me, + arena_stats_.MutableStats()); SerialArena* head = threads_.load(std::memory_order_relaxed); do { @@ -499,6 +519,12 @@ void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) { return impl_.AllocateAligned(n, type); } +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedWithHookForArray(size_t n, + const std::type_info* type) { + return impl_.AllocateAligned(n, type); +} + PROTOBUF_FUNC_ALIGN(32) std::pair Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) { diff --git a/third_party/protobuf/src/google/protobuf/arena.h b/third_party/protobuf/src/google/protobuf/arena.h index 6dd6467f..3b5f16c3 100644 --- a/third_party/protobuf/src/google/protobuf/arena.h +++ b/third_party/protobuf/src/google/protobuf/arena.h @@ -37,9 +37,6 @@ #include #include #include -#ifdef max -#undef max // Visual Studio defines this macro -#endif #if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS // Work around bugs in MSVC header when _HAS_EXCEPTIONS=0. #include @@ -55,6 +52,7 @@ using type_info = ::type_info; #include #include +// Must be included last. #include #ifdef SWIG @@ -83,10 +81,11 @@ class ReflectionTester; // defined in test_util.h namespace internal { -struct ArenaStringPtr; // defined in arenastring.h -class InlinedStringField; // defined in inlined_string_field.h -class LazyField; // defined in lazy_field.h -class EpsCopyInputStream; // defined in parse_context.h +struct ArenaTestPeer; // defined in arena_test_util.h +class InternalMetadata; // defined in metadata_lite.h +class LazyField; // defined in lazy_field.h +class EpsCopyInputStream; // defined in parse_context.h +class RepeatedPtrFieldBase; // defined in repeated_ptr_field.h template class GenericTypeHandler; // defined in repeated_field.h @@ -316,6 +315,20 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { static_cast(args)...); } + // Allocates memory with the specific size and alignment. + void* AllocateAligned(size_t size, size_t align = 8) { + if (align <= 8) { + return AllocateAlignedNoHook(internal::AlignUpTo8(size)); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a scheme would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedNoHook(size + align - 8), align); + } + } + // Create an array of object type T on the arena *without* invoking the // constructor of T. If `arena` is null, then the return value should be freed // with `delete[] x;` (or `::operator delete[](x);`). @@ -397,27 +410,12 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template class InternalHelper { - public: + private: // Provides access to protected GetOwningArena to generated messages. static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); } - // Provides access to protected GetArenaForAllocation to generated messages. - static Arena* GetArenaForAllocation(const T* p) { - return GetArenaForAllocationInternal( - p, std::is_convertible()); - } + static void InternalSwap(T* a, T* b) { a->InternalSwap(b); } - // Creates message-owned arena. - static Arena* CreateMessageOwnedArena() { - return new Arena(internal::MessageOwned{}); - } - - // Checks whether the given arena is message-owned. - static bool IsMessageOwnedArena(Arena* arena) { - return arena->IsMessageOwned(); - } - - private: static Arena* GetArenaForAllocationInternal( const T* p, std::true_type /*is_derived_from*/) { return p->GetArenaForAllocation(); @@ -500,6 +498,29 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { friend class TestUtil::ReflectionTester; }; + // Provides access to protected GetOwningArena to generated messages. For + // internal use only. + template + static Arena* InternalGetOwningArena(const T* p) { + return InternalHelper::GetOwningArena(p); + } + + // Provides access to protected GetArenaForAllocation to generated messages. + // For internal use only. + template + static Arena* InternalGetArenaForAllocation(const T* p) { + return InternalHelper::GetArenaForAllocationInternal( + p, std::is_convertible()); + } + + // Creates message-owned arena. For internal use only. + static Arena* InternalCreateMessageOwnedArena() { + return new Arena(internal::MessageOwned{}); + } + + // Checks whether this arena is message-owned. For internal use only. + bool InternalIsMessageOwnedArena() { return IsMessageOwned(); } + // Helper typetraits that indicates support for arenas in a type T at compile // time. This is public only to allow construction of higher-level templated // utilities. @@ -532,6 +553,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return impl_.IsMessageOwned(); } + void ReturnArrayMemory(void* p, size_t size) { + impl_.ReturnArrayMemory(p, size); + } + template PROTOBUF_NDEBUG_INLINE static T* CreateMessageInternal(Arena* arena, Args&&... args) { @@ -622,7 +647,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // 8 AlignUpTo can be elided. const size_t n = sizeof(T) * num_elements; return static_cast( - AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T))); + AllocateAlignedWithHookForArray(n, alignof(T), RTTI_TYPE_ID(T))); } template @@ -765,17 +790,18 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return nullptr; } - // For friends of arena. - void* AllocateAligned(size_t n, size_t align = 8) { + void* AllocateAlignedWithHookForArray(size_t n, size_t align, + const std::type_info* type) { if (align <= 8) { - return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + return AllocateAlignedWithHookForArray(internal::AlignUpTo8(n), type); } else { // We are wasting space by over allocating align - 8 bytes. Compared // to a dedicated function that takes current alignment in consideration. // Such a scheme would only waste (align - 8)/2 bytes on average, but // requires a dedicated function in the outline arena allocation // functions. Possibly re-evaluate tradeoffs later. - return internal::AlignTo(AllocateAlignedNoHook(n + align - 8), align); + return internal::AlignTo( + AllocateAlignedWithHookForArray(n + align - 8, type), align); } } @@ -786,7 +812,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } else { // We are wasting space by over allocating align - 8 bytes. Compared // to a dedicated function that takes current alignment in consideration. - // Such a schemee would only waste (align - 8)/2 bytes on average, but + // Such a scheme would only waste (align - 8)/2 bytes on average, but // requires a dedicated function in the outline arena allocation // functions. Possibly re-evaluate tradeoffs later. return internal::AlignTo(AllocateAlignedWithHook(n + align - 8, type), @@ -796,18 +822,22 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { void* AllocateAlignedNoHook(size_t n); void* AllocateAlignedWithHook(size_t n, const std::type_info* type); + void* AllocateAlignedWithHookForArray(size_t n, const std::type_info* type); std::pair AllocateAlignedWithCleanup(size_t n, const std::type_info* type); template friend class internal::GenericTypeHandler; - friend struct internal::ArenaStringPtr; // For AllocateAligned. - friend class internal::InlinedStringField; // For AllocateAligned. + friend class internal::InternalMetadata; // For user_arena(). friend class internal::LazyField; // For CreateMaybeMessage. friend class internal::EpsCopyInputStream; // For parser performance friend class MessageLite; template friend class Map; + template + friend class RepeatedField; // For ReturnArrayMemory + friend class internal::RepeatedPtrFieldBase; // For ReturnArrayMemory + friend struct internal::ArenaTestPeer; }; // Defined above for supporting environments without RTTI. diff --git a/third_party/protobuf/src/google/protobuf/arena_impl.h b/third_party/protobuf/src/google/protobuf/arena_impl.h index 2ffac319..76727688 100644 --- a/third_party/protobuf/src/google/protobuf/arena_impl.h +++ b/third_party/protobuf/src/google/protobuf/arena_impl.h @@ -39,11 +39,15 @@ #include #include +#include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER +#include + +// Must be included last. #include @@ -51,6 +55,13 @@ namespace google { namespace protobuf { namespace internal { +// To prevent sharing cache lines between threads +#ifdef __cpp_aligned_new +enum { kCacheAlignment = 64 }; +#else +enum { kCacheAlignment = alignof(max_align_t) }; // do the best we can +#endif + inline constexpr size_t AlignUpTo8(size_t n) { // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) return (n + 7) & static_cast(-8); @@ -177,6 +188,8 @@ class TaggedAllocationPolicyPtr { uintptr_t policy_; }; +enum class AllocationClient { kDefault, kArray }; + // A simple arena allocator. Calls to allocate functions must be properly // serialized by the caller, hence this class cannot be used as a general // purpose allocator in a multi-threaded program. It serves as a building block @@ -208,11 +221,47 @@ class PROTOBUF_EXPORT SerialArena { } uint64_t SpaceUsed() const; - bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } + bool HasSpace(size_t n) const { + return n <= static_cast(limit_ - ptr_); + } + // See comments on `cached_blocks_` member for details. + PROTOBUF_ALWAYS_INLINE void* TryAllocateFromCachedBlock(size_t size) { + if (PROTOBUF_PREDICT_FALSE(size < 16)) return nullptr; + // We round up to the next larger block in case the memory doesn't match + // the pattern we are looking for. + const size_t index = Bits::Log2FloorNonZero64(size - 1) - 3; + + if (index >= cached_block_length_) return nullptr; + auto& cached_head = cached_blocks_[index]; + if (cached_head == nullptr) return nullptr; + + void* ret = cached_head; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, size); +#endif // ADDRESS_SANITIZER + cached_head = cached_head->next; + return ret; + } + + // In kArray mode we look through cached blocks. + // We do not do this by default because most non-array allocations will not + // have the right size and will fail to find an appropriate cached block. + // + // TODO(sbenza): Evaluate if we should use cached blocks for message types of + // the right size. We can statically know if the allocation size can benefit + // from it. + template void* AllocateAligned(size_t n, const AllocationPolicy* policy) { GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. GOOGLE_DCHECK_GE(limit_, ptr_); + + if (alloc_client == AllocationClient::kArray) { + if (void* res = TryAllocateFromCachedBlock(n)) { + return res; + } + } + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { return AllocateAlignedFallback(n, policy); } @@ -229,6 +278,50 @@ class PROTOBUF_EXPORT SerialArena { return ret; } + // See comments on `cached_blocks_` member for details. + void ReturnArrayMemory(void* p, size_t size) { + // We only need to check for 32-bit platforms. + // In 64-bit platforms the minimum allocation size from Repeated*Field will + // be 16 guaranteed. + if (sizeof(void*) < 8) { + if (PROTOBUF_PREDICT_FALSE(size < 16)) return; + } else { + GOOGLE_DCHECK(size >= 16); + } + + // We round down to the next smaller block in case the memory doesn't match + // the pattern we are looking for. eg, someone might have called Reserve() + // on the repeated field. + const size_t index = Bits::Log2FloorNonZero64(size) - 4; + + if (PROTOBUF_PREDICT_FALSE(index >= cached_block_length_)) { + // We can't put this object on the freelist so make this object the + // freelist. It is guaranteed it is larger than the one we have, and + // large enough to hold another allocation of `size`. + CachedBlock** new_list = static_cast(p); + size_t new_size = size / sizeof(CachedBlock*); + + std::copy(cached_blocks_, cached_blocks_ + cached_block_length_, + new_list); + std::fill(new_list + cached_block_length_, new_list + new_size, nullptr); + cached_blocks_ = new_list; + // Make the size fit in uint8_t. This is the power of two, so we don't + // need anything larger. + cached_block_length_ = + static_cast(std::min(size_t{64}, new_size)); + + return; + } + + auto& cached_head = cached_blocks_[index]; + auto* new_node = static_cast(p); + new_node->next = cached_head; + cached_head = new_node; +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(p, size); +#endif // ADDRESS_SANITIZER + } + public: // Allocate space if the current region provides enough space. bool MaybeAllocateAligned(size_t n, void** out) { @@ -279,7 +372,8 @@ class PROTOBUF_EXPORT SerialArena { // Creates a new SerialArena inside mem using the remaining memory as for // future allocations. - static SerialArena* New(SerialArena::Memory mem, void* owner); + static SerialArena* New(SerialArena::Memory mem, void* owner, + ThreadSafeArenaStats* stats); // Free SerialArena returning the memory passed in to New template Memory Free(Deallocator deallocator); @@ -310,10 +404,28 @@ class PROTOBUF_EXPORT SerialArena { // head_ (and head_->pos will always be non-canonical). We keep these // here to reduce indirection. char* ptr_; + // Limiting address up to which memory can be allocated from the head block. char* limit_; + // For holding sampling information. The pointer is owned by the + // ThreadSafeArena that holds this serial arena. + ThreadSafeArenaStats* arena_stats_; + + // Repeated*Field and Arena play together to reduce memory consumption by + // reusing blocks. Currently, natural growth of the repeated field types makes + // them allocate blocks of size `8 + 2^N, N>=3`. + // When the repeated field grows returns the previous block and we put it in + // this free list. + // `cached_blocks_[i]` points to the free list for blocks of size `8+2^(i+3)`. + // The array of freelists is grown when needed in `ReturnArrayMemory()`. + struct CachedBlock { + // Simple linked list. + CachedBlock* next; + }; + uint8_t cached_block_length_ = 0; + CachedBlock** cached_blocks_ = nullptr; // Constructor is private as only New() should be used. - inline SerialArena(Block* b, void* owner); + inline SerialArena(Block* b, void* owner, ThreadSafeArenaStats* stats); void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy); std::pair AllocateAlignedWithCleanupFallback( size_t n, const AllocationPolicy* policy); @@ -368,26 +480,34 @@ class PROTOBUF_EXPORT ThreadSafeArena { uint64_t SpaceAllocated() const; uint64_t SpaceUsed() const; + template void* AllocateAligned(size_t n, const std::type_info* type) { SerialArena* arena; if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && GetSerialArenaFast(&arena))) { - return arena->AllocateAligned(n, AllocPolicy()); + return arena->AllocateAligned(n, AllocPolicy()); } else { return AllocateAlignedFallback(n, type); } } + void ReturnArrayMemory(void* p, size_t size) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { + arena->ReturnArrayMemory(p, size); + } + } + // This function allocates n bytes if the common happy case is true and // returns true. Otherwise does nothing and returns false. This strange // semantics is necessary to allow callers to program functions that only // have fallback function calls in tail position. This substantially improves // code for the happy path. PROTOBUF_NDEBUG_INLINE bool MaybeAllocateAligned(size_t n, void** out) { - SerialArena* a; + SerialArena* arena; if (PROTOBUF_PREDICT_TRUE(!alloc_policy_.should_record_allocs() && - GetSerialArenaFromThreadCache(&a))) { - return a->MaybeAllocateAligned(n, out); + GetSerialArenaFromThreadCache(&arena))) { + return arena->MaybeAllocateAligned(n, out); } return false; } @@ -411,6 +531,8 @@ class PROTOBUF_EXPORT ThreadSafeArena { TaggedAllocationPolicyPtr alloc_policy_; // Tagged pointer to AllocPolicy. + static_assert(std::is_trivially_destructible{}, + "SerialArena needs to be trivially destructible."); // Pointer to a linked list of SerialArena. std::atomic threads_; std::atomic hint_; // Fast thread-local block access @@ -449,7 +571,7 @@ class PROTOBUF_EXPORT ThreadSafeArena { // fast path optimizes the case where a single thread uses multiple arenas. ThreadCache* tc = &thread_cache(); SerialArena* serial = hint_.load(std::memory_order_acquire); - if (PROTOBUF_PREDICT_TRUE(serial != NULL && serial->owner() == tc)) { + if (PROTOBUF_PREDICT_TRUE(serial != nullptr && serial->owner() == tc)) { *arena = serial; return true; } @@ -487,7 +609,7 @@ class PROTOBUF_EXPORT ThreadSafeArena { #ifdef _MSC_VER #pragma warning(disable : 4324) #endif - struct alignas(64) ThreadCache { + struct alignas(kCacheAlignment) ThreadCache { #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // If we are using the ThreadLocalStorage class to store the ThreadCache, // then the ThreadCache's default constructor has to be responsible for @@ -495,7 +617,7 @@ class PROTOBUF_EXPORT ThreadSafeArena { ThreadCache() : next_lifecycle_id(0), last_lifecycle_id_seen(-1), - last_serial_arena(NULL) {} + last_serial_arena(nullptr) {} #endif // Number of per-thread lifecycle IDs to reserve. Must be power of two. @@ -518,7 +640,7 @@ class PROTOBUF_EXPORT ThreadSafeArena { #ifdef _MSC_VER #pragma warning(disable : 4324) #endif - struct alignas(64) CacheAlignedLifecycleIdGenerator { + struct alignas(kCacheAlignment) CacheAlignedLifecycleIdGenerator { std::atomic id; }; static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; @@ -535,6 +657,8 @@ class PROTOBUF_EXPORT ThreadSafeArena { static ThreadCache& thread_cache() { return thread_cache_; } #endif + ThreadSafeArenaStatsHandle arena_stats_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena); // All protos have pointers back to the arena hence Arena must have // pointer stability. diff --git a/third_party/protobuf/src/google/protobuf/arena_test_util.cc b/third_party/protobuf/src/google/protobuf/arena_test_util.cc index da32960c..2cb50755 100644 --- a/third_party/protobuf/src/google/protobuf/arena_test_util.cc +++ b/third_party/protobuf/src/google/protobuf/arena_test_util.cc @@ -29,6 +29,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include + #include #include diff --git a/third_party/protobuf/src/google/protobuf/arena_test_util.h b/third_party/protobuf/src/google/protobuf/arena_test_util.h index 33f5cf41..6e42d4bc 100644 --- a/third_party/protobuf/src/google/protobuf/arena_test_util.h +++ b/third_party/protobuf/src/google/protobuf/arena_test_util.h @@ -33,9 +33,9 @@ #include #include +#include #include #include -#include namespace google { namespace protobuf { @@ -76,6 +76,12 @@ void TestParseCorruptedString(const T& message) { namespace internal { +struct ArenaTestPeer { + static void ReturnArrayMemory(Arena* arena, void* p, size_t size) { + arena->ReturnArrayMemory(p, size); + } +}; + class NoHeapChecker { public: NoHeapChecker() { capture_alloc.Hook(); } diff --git a/third_party/protobuf/src/google/protobuf/arena_unittest.cc b/third_party/protobuf/src/google/protobuf/arena_unittest.cc index 76d9126a..7539b4b2 100644 --- a/third_party/protobuf/src/google/protobuf/arena_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/arena_unittest.cc @@ -41,27 +41,29 @@ #include #include -#include -#include #include #include -#include -#include +#include +#include +#include +#include #include #include +#include +#include #include #include #include +#include #include #include -#include -#include // Must be included last #include using proto2_arena_unittest::ArenaMessage; +using protobuf_unittest::ForeignMessage; using protobuf_unittest::TestAllExtensions; using protobuf_unittest::TestAllTypes; using protobuf_unittest::TestEmptyMessage; @@ -542,6 +544,16 @@ TEST(ArenaTest, UnsafeArenaSwap) { TestUtil::ExpectAllFieldsSet(*message2); } +TEST(ArenaTest, GetOwningArena) { + Arena arena; + auto* m1 = Arena::CreateMessage(&arena); + EXPECT_EQ(Arena::InternalGetOwningArena(m1), &arena); + EXPECT_EQ(&arena, Arena::InternalGetOwningArena( + m1->mutable_repeated_foreign_message())); + EXPECT_EQ(&arena, + Arena::InternalGetOwningArena(m1->mutable_repeated_int32())); +} + TEST(ArenaTest, SwapBetweenArenasUsingReflection) { Arena arena1; TestAllTypes* arena1_message = Arena::CreateMessage(&arena1); @@ -1465,6 +1477,71 @@ TEST(ArenaTest, AddCleanup) { } } +TEST(ArenaTest, SpaceReuseForArraysSizeChecks) { + // Limit to 1<<20 to avoid using too much memory on the test. + for (int i = 0; i < 20; ++i) { + SCOPED_TRACE(i); + Arena arena; + std::vector pointers; + + const size_t size = 16 << i; + + for (int j = 0; j < 10; ++j) { + pointers.push_back(Arena::CreateArray(&arena, size)); + } + + for (void* p : pointers) { + internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, size); + } + + std::vector second_pointers; + for (int j = 9; j != 0; --j) { + second_pointers.push_back(Arena::CreateArray(&arena, size)); + } + + // The arena will give us back the pointers we returned, except the first + // one. That one becomes part of the freelist data structure. + ASSERT_THAT(second_pointers, + testing::UnorderedElementsAreArray( + std::vector(pointers.begin() + 1, pointers.end()))); + } +} + +TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { +#ifdef ADDRESS_SANITIZER + char buf[1024]{}; + { + Arena arena(buf, sizeof(buf)); + std::vector pointers; + for (int i = 0; i < 100; ++i) { + pointers.push_back(Arena::CreateArray(&arena, 16)); + } + for (void* p : pointers) { + internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, 16); + // The first one is not poisoned because it becomes the freelist. + if (p != pointers[0]) EXPECT_TRUE(__asan_address_is_poisoned(p)); + } + + bool found_poison = false; + for (char& c : buf) { + if (__asan_address_is_poisoned(&c)) { + found_poison = true; + break; + } + } + EXPECT_TRUE(found_poison); + } + + // Should not be poisoned after destruction. + for (char& c : buf) { + ASSERT_FALSE(__asan_address_is_poisoned(&c)); + } + +#else // ADDRESS_SANITIZER + GTEST_SKIP(); +#endif // ADDRESS_SANITIZER +} + namespace { uint32_t hooks_num_init = 0; uint32_t hooks_num_allocations = 0; diff --git a/third_party/protobuf/src/google/protobuf/arenastring.cc b/third_party/protobuf/src/google/protobuf/arenastring.cc index 169f5272..af0c9df6 100644 --- a/third_party/protobuf/src/google/protobuf/arenastring.cc +++ b/third_party/protobuf/src/google/protobuf/arenastring.cc @@ -30,13 +30,14 @@ #include +#include #include #include -#include #include -#include #include #include +#include +#include #include // clang-format off @@ -47,6 +48,28 @@ namespace google { namespace protobuf { namespace internal { +namespace { + +// TaggedStringPtr::Flags uses the lower 2 bits as tags. +// Enforce that allocated data aligns to at least 4 bytes, and that +// the alignment of the global const string value does as well. +// The alignment guaranteed by `new std::string` depends on both: +// - new align = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / max_align_t +// - alignof(std::string) +#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ +constexpr size_t kNewAlign = __STDCPP_DEFAULT_NEW_ALIGNMENT__; +#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 +constexpr size_t kNewAlign = alignof(::max_align_t); +#else +constexpr size_t kNewAlign = alignof(std::max_align_t); +#endif +constexpr size_t kStringAlign = alignof(std::string); + +static_assert((kStringAlign > kNewAlign ? kStringAlign : kNewAlign) >= 4, ""); +static_assert(alignof(ExplicitlyConstructedArenaString) >= 4, ""); + +} // namespace + const std::string& LazyString::Init() const { static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; mu.Lock(); @@ -61,185 +84,150 @@ const std::string& LazyString::Init() const { return *res; } +namespace { -std::string* ArenaStringPtr::SetAndReturnNewString() { - std::string* new_string = new std::string(); - tagged_ptr_.Set(new_string); - return new_string; + +#if defined(NDEBUG) || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +class ScopedCheckPtrInvariants { + public: + explicit ScopedCheckPtrInvariants(const TaggedStringPtr*) {} +}; + +#endif // NDEBUG || !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +// Creates a heap allocated std::string value. +inline TaggedStringPtr CreateString(ConstStringParam value) { + TaggedStringPtr res; + res.SetAllocated(new std::string(value.data(), value.length())); + return res; } -void ArenaStringPtr::DestroyNoArenaSlowPath() { delete UnsafeMutablePointer(); } +#if !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL -void ArenaStringPtr::Set(const std::string* default_value, - ConstStringParam value, ::google::protobuf::Arena* arena) { - if (IsDefault(default_value)) { - tagged_ptr_.Set(Arena::Create(arena, value)); +// Creates an arena allocated std::string value. +TaggedStringPtr CreateArenaString(Arena& arena, ConstStringParam s) { + TaggedStringPtr res; + res.SetMutableArena(Arena::Create(&arena, s.data(), s.length())); + return res; +} + +#endif // !GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL + +} // namespace + +void ArenaStringPtr::Set(ConstStringParam value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (IsDefault()) { + // If we're not on an arena, skip straight to a true string to avoid + // possible copy cost later. + tagged_ptr_ = arena != nullptr ? CreateArenaString(*arena, value) + : CreateString(value); } else { UnsafeMutablePointer()->assign(value.data(), value.length()); } } -void ArenaStringPtr::Set(const std::string* default_value, std::string&& value, - ::google::protobuf::Arena* arena) { - if (IsDefault(default_value)) { - if (arena == nullptr) { - tagged_ptr_.Set(new std::string(std::move(value))); - } else { - tagged_ptr_.Set(Arena::Create(arena, std::move(value))); - } - } else if (IsDonatedString()) { +void ArenaStringPtr::Set(std::string&& value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (IsDefault()) { + NewString(arena, std::move(value)); + } else if (IsFixedSizeArena()) { std::string* current = tagged_ptr_.Get(); auto* s = new (current) std::string(std::move(value)); arena->OwnDestructor(s); - tagged_ptr_.Set(s); - } else /* !IsDonatedString() */ { + tagged_ptr_.SetMutableArena(s); + } else /* !IsFixedSizeArena() */ { *UnsafeMutablePointer() = std::move(value); } } -void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value, - ::google::protobuf::Arena* arena) { - Set(&GetEmptyStringAlreadyInited(), value, arena); -} - -void ArenaStringPtr::Set(EmptyDefault, std::string&& value, - ::google::protobuf::Arena* arena) { - Set(&GetEmptyStringAlreadyInited(), std::move(value), arena); -} - -void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value, - ::google::protobuf::Arena* arena) { - Set(nullptr, value, arena); -} - -void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value, - ::google::protobuf::Arena* arena) { - Set(nullptr, std::move(value), arena); -} - -std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { - return UnsafeMutablePointer(); +std::string* ArenaStringPtr::Mutable(Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } else { return MutableSlow(arena); } } std::string* ArenaStringPtr::Mutable(const LazyString& default_value, - ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(nullptr)) { - return UnsafeMutablePointer(); + Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } else { return MutableSlow(arena, default_value); } } -std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value, - ::google::protobuf::Arena* arena) { - if (!IsDonatedString() && !IsDefault(default_value)) { - return UnsafeMutablePointer(); +std::string* ArenaStringPtr::MutableNoCopy(Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (tagged_ptr_.IsMutable()) { + return tagged_ptr_.Get(); } else { - GOOGLE_DCHECK(IsDefault(default_value)); + GOOGLE_DCHECK(IsDefault()); // Allocate empty. The contents are not relevant. - std::string* new_string = Arena::Create(arena); - tagged_ptr_.Set(new_string); - return new_string; + return NewString(arena); } } template std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default) { - const std::string* const default_value = - sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr; - GOOGLE_DCHECK(IsDefault(default_value)); - std::string* new_string = - Arena::Create(arena, lazy_default.get()...); - tagged_ptr_.Set(new_string); - return new_string; + GOOGLE_DCHECK(IsDefault()); + + // For empty defaults, this ends up calling the default constructor which is + // more efficient than a copy construction from + // GetEmptyStringAlreadyInited(). + return NewString(arena, lazy_default.get()...); } -std::string* ArenaStringPtr::Release(const std::string* default_value, - ::google::protobuf::Arena* arena) { - if (IsDefault(default_value)) { - return nullptr; - } else { - return ReleaseNonDefault(default_value, arena); +std::string* ArenaStringPtr::Release() { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (IsDefault()) return nullptr; + + std::string* released = tagged_ptr_.Get(); + if (tagged_ptr_.IsArena()) { + released = tagged_ptr_.IsMutable() ? new std::string(std::move(*released)) + : new std::string(*released); } + InitDefault(); + return released; } -std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, - ::google::protobuf::Arena* arena) { - GOOGLE_DCHECK(!IsDefault(default_value)); - - if (!IsDonatedString()) { - std::string* released; - if (arena != nullptr) { - released = new std::string; - released->swap(*UnsafeMutablePointer()); - } else { - released = UnsafeMutablePointer(); - } - tagged_ptr_.Set(const_cast(default_value)); - return released; - } else /* IsDonatedString() */ { - GOOGLE_DCHECK(arena != nullptr); - std::string* released = new std::string(Get()); - tagged_ptr_.Set(const_cast(default_value)); - return released; - } -} - -void ArenaStringPtr::SetAllocated(const std::string* default_value, - std::string* value, ::google::protobuf::Arena* arena) { +void ArenaStringPtr::SetAllocated(std::string* value, Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); // Release what we have first. - if (arena == nullptr && !IsDefault(default_value)) { - delete UnsafeMutablePointer(); - } + Destroy(); + if (value == nullptr) { - tagged_ptr_.Set(const_cast(default_value)); + InitDefault(); } else { -#ifdef NDEBUG - tagged_ptr_.Set(value); - if (arena != nullptr) { - arena->Own(value); - } -#else +#ifndef NDEBUG // On debug builds, copy the string so the address differs. delete will // fail if value was a stack-allocated temporary/etc., which would have // failed when arena ran its cleanup list. - std::string* new_value = Arena::Create(arena, *value); + std::string* new_value = new std::string(std::move(*value)); delete value; - tagged_ptr_.Set(new_value); -#endif + value = new_value; +#endif // !NDEBUG + InitAllocated(value, arena); } } -void ArenaStringPtr::Destroy(const std::string* default_value, - ::google::protobuf::Arena* arena) { - if (arena == nullptr) { - GOOGLE_DCHECK(!IsDonatedString()); - if (!IsDefault(default_value)) { - delete UnsafeMutablePointer(); - } - } -} - -void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) { - Destroy(&GetEmptyStringAlreadyInited(), arena); -} - -void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) { - Destroy(nullptr, arena); +void ArenaStringPtr::Destroy() { + delete tagged_ptr_.GetIfAllocated(); } void ArenaStringPtr::ClearToEmpty() { - if (IsDefault(&GetEmptyStringAlreadyInited())) { + ScopedCheckPtrInvariants check(&tagged_ptr_); + if (IsDefault()) { // Already set to default -- do nothing. } else { // Unconditionally mask away the tag. // - // UpdateDonatedString uses assign when capacity is larger than the new + // UpdateArenaString uses assign when capacity is larger than the new // value, which is trivially true in the donated string case. // const_cast(PtrValue())->clear(); tagged_ptr_.Get()->clear(); @@ -248,34 +236,27 @@ void ArenaStringPtr::ClearToEmpty() { void ArenaStringPtr::ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena) { + ScopedCheckPtrInvariants check(&tagged_ptr_); (void)arena; - if (IsDefault(nullptr)) { + if (IsDefault()) { // Already set to default -- do nothing. - } else if (!IsDonatedString()) { + } else { UnsafeMutablePointer()->assign(default_value.get()); } } -inline void SetStrWithHeapBuffer(std::string* str, ArenaStringPtr* s) { - TaggedPtr res; - res.Set(str); - s->UnsafeSetTaggedPointer(res); -} - const char* EpsCopyInputStream::ReadArenaString(const char* ptr, ArenaStringPtr* s, Arena* arena) { + ScopedCheckPtrInvariants check(&s->tagged_ptr_); GOOGLE_DCHECK(arena != nullptr); int size = ReadSize(&ptr); if (!ptr) return nullptr; - auto* str = Arena::Create(arena); + auto* str = s->NewString(arena); ptr = ReadString(ptr, size, str); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); - - SetStrWithHeapBuffer(str, s); - return ptr; } diff --git a/third_party/protobuf/src/google/protobuf/arenastring.h b/third_party/protobuf/src/google/protobuf/arenastring.h index 38c36378..6bc8395f 100644 --- a/third_party/protobuf/src/google/protobuf/arenastring.h +++ b/third_party/protobuf/src/google/protobuf/arenastring.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ #define GOOGLE_PROTOBUF_ARENASTRING_H__ +#include #include #include #include @@ -39,7 +40,9 @@ #include #include #include +#include +// must be last: #include #ifdef SWIG @@ -50,12 +53,14 @@ namespace google { namespace protobuf { namespace internal { - -template -class ExplicitlyConstructed; +class EpsCopyInputStream; class SwapFieldHelper; +// Declared in message_lite.h +PROTOBUF_EXPORT extern ExplicitlyConstructedArenaString + fixed_address_empty_string; + // Lazy string instance to support string fields with non-empty default. // These are initialized on the first call to .get(). class PROTOBUF_EXPORT LazyString { @@ -89,182 +94,229 @@ class PROTOBUF_EXPORT LazyString { const std::string& Init() const; }; -template -class TaggedPtr { +class TaggedStringPtr { public: - TaggedPtr() = default; - explicit constexpr TaggedPtr(const ExplicitlyConstructed* ptr) - : ptr_(const_cast*>(ptr)) {} + // Bit flags qualifying string properties. We can use 2 bits as + // ptr_ is guaranteed and enforced to be aligned on 4 byte boundaries. + enum Flags { + kArenaBit = 0x1, // ptr is arena allocated + kMutableBit = 0x2, // ptr contents are fully mutable + kMask = 0x3 // Bit mask + }; - void SetTagged(T* p) { - Set(p); - ptr_ = reinterpret_cast(as_int() | 1); + // Composed logical types + enum Type { + // Default strings are immutable and never owned. + kDefault = 0, + + // Allocated strings are mutable and (as the name implies) owned. + // A heap allocated string must be deleted. + kAllocated = kMutableBit, + + // Mutable arena strings are strings where the string instance is owned + // by the arena, but the string contents itself are owned by the string + // instance. Mutable arena string instances need to be destroyed which is + // typically done through a cleanup action added to the arena owning it. + kMutableArena = kArenaBit | kMutableBit, + + // Fixed size arena strings are strings where both the string instance and + // the string contents are fully owned by the arena. Fixed size arena + // strings are a platform and c++ library specific customization. Fixed + // size arena strings are immutable, with the exception of custom internal + // updates to the content that fit inside the existing capacity. + // Fixed size arena strings must never be deleted or destroyed. + kFixedSizeArena = kArenaBit, + }; + + TaggedStringPtr() = default; + explicit constexpr TaggedStringPtr(ExplicitlyConstructedArenaString* ptr) + : ptr_(ptr) {} + + // Sets the value to `p`, tagging the value as being a 'default' value. + // See documentation for kDefault for more info. + inline const std::string* SetDefault(const std::string* p) { + return TagAs(kDefault, const_cast(p)); } - void Set(T* p) { ptr_ = p; } - T* Get() const { return reinterpret_cast(as_int() & -2); } - bool IsTagged() const { return as_int() & 1; } - // Returned value is only safe to dereference if IsTagged() == false. - // It is safe to compare. - T* UnsafeGet() const { return static_cast(ptr_); } + // Sets the value to `p`, tagging the value as a heap allocated value. + // Allocated strings are mutable and (as the name implies) owned. + // `p` must not be null + inline std::string* SetAllocated(std::string* p) { + return TagAs(kAllocated, p); + } - bool IsNull() { return ptr_ == nullptr; } + // Sets the value to `p`, tagging the value as a fixed size arena string. + // See documentation for kFixedSizeArena for more info. + // `p` must not be null + inline std::string* SetFixedSizeArena(std::string* p) { + return TagAs(kFixedSizeArena, p); + } + + // Sets the value to `p`, tagging the value as a mutable arena string. + // See documentation for kMutableArena for more info. + // `p` must not be null + inline std::string* SetMutableArena(std::string* p) { + return TagAs(kMutableArena, p); + } + + // Returns true if the contents of the current string are fully mutable. + inline bool IsMutable() const { return as_int() & kMutableBit; } + + // Returns true if the current string is an immutable default value. + inline bool IsDefault() const { return (as_int() & kMask) == kDefault; } + + // If the current string is a heap-allocated mutable value, returns a pointer + // to it. Returns nullptr otherwise. + inline std::string *GetIfAllocated() const { + auto allocated = as_int() ^ kAllocated; + if (allocated & kMask) return nullptr; + + auto ptr = reinterpret_cast(allocated); + PROTOBUF_ASSUME(ptr != nullptr); + return ptr; + } + + // Returns true if the current string is an arena allocated value. + // This means it's either a mutable or fixed size arena string. + inline bool IsArena() const { return as_int() & kArenaBit; } + + // Returns true if the current string is a fixed size arena allocated value. + inline bool IsFixedSizeArena() const { + return (as_int() & kMask) == kFixedSizeArena; + } + + // Returns the contained string pointer. + inline std::string* Get() const { + return reinterpret_cast(as_int() & ~kMask); + } + + // Returns true if the contained pointer is null, indicating some error. + // The Null value is only used during parsing for temporary values. + // A persisted ArenaStringPtr value is never null. + inline bool IsNull() { return ptr_ == nullptr; } private: + static inline void assert_aligned(const void* p) { + GOOGLE_DCHECK_EQ(reinterpret_cast(p) & kMask, 0UL); + } + + inline std::string* TagAs(Type type, std::string* p) { + GOOGLE_DCHECK(p != nullptr); + assert_aligned(p); + ptr_ = reinterpret_cast(reinterpret_cast(p) | type); + return p; + } + uintptr_t as_int() const { return reinterpret_cast(ptr_); } void* ptr_; }; -static_assert(std::is_trivial>::value, - "TaggedPtr must be trivial"); +static_assert(std::is_trivial::value, + "TaggedStringPtr must be trivial"); -// This class encapsulates a pointer to a std::string with or without a donated -// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly -// corresponds to the interface required by string fields in generated -// code. It replaces the old std::string* pointer in such cases. +// This class encapsulates a pointer to a std::string with or without arena +// owned contents, tagged by the bottom bits of the string pointer. It is a +// high-level wrapper that almost directly corresponds to the interface required +// by string fields in generated code. It replaces the old std::string* pointer +// in such cases. // -// The object has different but similar code paths for when the default value is -// the empty string and when it is a non-empty string. -// The empty string is handled different throughout the library and there is a -// single global instance of it we can share. +// The string pointer is tagged to be either a default, externally owned value, +// a mutable heap allocated value, or an arena allocated value. The object uses +// a single global instance of an empty string that is used as the initial +// default value. Fields that have empty default values directly use this global +// default. Fields that have non empty default values are supported through +// lazily initialized default values managed by the LazyString class. // -// For fields with an empty string default value, there are three distinct -// states: -// -// - Pointer set to 'String' tag (LSB is 0), equal to -// &GetEmptyStringAlreadyInited(): field is set to its default value. Points -// to a true std::string*, but we do not own that std::string* (it's a -// globally shared instance). -// -// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty -// string: field points to a true std::string* instance that we own. This -// instance is either on the heap or on the arena (i.e. registered on -// free()/destructor-call list) as appropriate. -// -// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string -// instance with a buffer on the arena (arena is never nullptr in this case). -// -// For fields with a non-empty string default value, there are three distinct -// states: -// -// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`: -// Field is in "default" mode and does not point to any actual instance. -// Methods that might need to create an instance of the object will pass a -// `const LazyString&` for it. -// -// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`: -// field points to a true std::string* instance that we own. This instance is -// either on the heap or on the arena (i.e. registered on -// free()/destructor-call list) as appropriate. -// -// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string -// instance with a buffer on the arena (arena is never nullptr in this case). -// -// Generated code and reflection code both ensure that ptr_ is never null for -// fields with an empty default. +// Generated code and reflection code both ensure that ptr_ is never null. // Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and -// so the field is always manually initialized via method calls. +// the field is always manually initialized via method calls. // -// Side-note: why pass information about the default on every API call? Because -// we don't want to hold it in a member variable, or else this would go into -// every proto message instance. This would be a huge waste of space, since the -// default instance pointer is typically a global (static class field). We want -// the generated code to be as efficient as possible, and if we take -// the default value information as a parameter that's in practice taken from a -// static class field, and compare ptr_ to the default value, we end up with a -// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also -// requires the String tag to be 0 so we can avoid the mask before comparing.) +// See TaggedStringPtr for more information about the types of string values +// being held, and the mutable and ownership invariants for each type. struct PROTOBUF_EXPORT ArenaStringPtr { ArenaStringPtr() = default; - explicit constexpr ArenaStringPtr( - const ExplicitlyConstructed* default_value) + constexpr ArenaStringPtr(ExplicitlyConstructedArenaString* default_value, + ConstantInitialized) : tagged_ptr_(default_value) {} - // Some methods below are overloaded on a `default_value` and on tags. - // The tagged overloads help reduce code size in the callers in generated - // code, while the `default_value` overloads are useful from reflection. - // By-value empty struct arguments are elided in the ABI. - struct EmptyDefault {}; - struct NonEmptyDefault {}; + // Called from generated code / reflection runtime only. Resets value to point + // to a default string pointer, with the semantics that this ArenaStringPtr + // does not own the pointed-to memory. Disregards initial value of ptr_ (so + // this is the *ONLY* safe method to call after construction or when + // reinitializing after becoming the active field in a oneof union). + inline void InitDefault(); - void Set(const std::string* default_value, ConstStringParam value, - ::google::protobuf::Arena* arena); - void Set(const std::string* default_value, std::string&& value, - ::google::protobuf::Arena* arena); - void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); - void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); - void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); - void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); - template - void Set(FirstParam p1, const char* str, ::google::protobuf::Arena* arena) { - Set(p1, ConstStringParam(str), arena); - } - template - void Set(FirstParam p1, const char* str, size_t size, + // Similar to `InitDefault` except that it allows the default value to be + // initialized to an externally owned string. This method is called from + // parsing code. `str` must not be null and outlive this instance. + inline void InitExternal(const std::string* str); + + // Called from generated code / reflection runtime only. Resets the value of + // this instances to the heap allocated value in `str`. `str` must not be + // null. Invokes `arena->Own(str)` to transfer ownership into the arena if + // `arena` is not null, else, `str` will be owned by ArenaStringPtr. This + // function should only be used to initialize a ArenaStringPtr or on an + // instance known to not carry any heap allocated value. + inline void InitAllocated(std::string* str, Arena* arena); + + void Set(ConstStringParam value, Arena* arena); + void Set(std::string&& value, Arena* arena); + void Set(const char* s, Arena* arena); + void Set(const char* s, size_t n, Arena* arena); + + void SetBytes(ConstStringParam value, Arena* arena); + void SetBytes(std::string&& value, Arena* arena); + void SetBytes(const char* s, Arena* arena); + void SetBytes(const void* p, size_t n, Arena* arena); + + template + void Set(std::reference_wrapper const_string_ref, ::google::protobuf::Arena* arena) { - ConstStringParam sp{str, size}; // for string_view and `const string &` - Set(p1, sp, arena); - } - template - void Set(FirstParam p1, - std::reference_wrapper const_string_ref, - ::google::protobuf::Arena* arena) { - Set(p1, const_string_ref.get(), arena); + Set(const_string_ref.get(), arena); } - template - void SetBytes(FirstParam p1, SecondParam&& p2, ::google::protobuf::Arena* arena) { - Set(p1, static_cast(p2), arena); - } - template - void SetBytes(FirstParam p1, const void* str, size_t size, - ::google::protobuf::Arena* arena) { - // must work whether ConstStringParam is string_view or `const string &` - ConstStringParam sp{static_cast(str), size}; - Set(p1, sp, arena); - } + // Returns a mutable std::string reference. + // The version accepting a `LazyString` value is used in the generated code to + // initialize mutable copies for fields with a non-empty default where the + // default value is lazily initialized. + std::string* Mutable(Arena* arena); + std::string* Mutable(const LazyString& default_value, Arena* arena); + + // Gets a mutable pointer with unspecified contents. + // This function is identical to Mutable(), except it is optimized for the + // case where the caller is not interested in the current contents. For + // example, if the current field is not mutable, it will re-initialize the + // value with an empty string rather than a (non-empty) default value. + // Likewise, if the current value is a fixed size arena string with contents, + // it will be initialized into an empty mutable arena string. + std::string* MutableNoCopy(Arena* arena); // Basic accessors. PROTOBUF_NDEBUG_INLINE const std::string& Get() const { // Unconditionally mask away the tag. return *tagged_ptr_.Get(); } - PROTOBUF_NDEBUG_INLINE const std::string* GetPointer() const { - // Unconditionally mask away the tag. + + // Returns a pointer to the stored contents for this instance. + // This method is for internal debugging and tracking purposes only. + PROTOBUF_NDEBUG_INLINE const std::string* UnsafeGetPointer() const + PROTOBUF_RETURNS_NONNULL { return tagged_ptr_.Get(); } - // For fields with an empty default value. - std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena); - // For fields with a non-empty default value. - std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena); - // Release returns a std::string* instance that is heap-allocated and is not // Own()'d by any arena. If the field is not set, this returns nullptr. The - // caller retains ownership. Clears this field back to nullptr state. Used to - // implement release_() methods on generated classes. - PROTOBUF_NODISCARD std::string* Release(const std::string* default_value, - ::google::protobuf::Arena* arena); - PROTOBUF_NODISCARD std::string* ReleaseNonDefault( - const std::string* default_value, ::google::protobuf::Arena* arena); + // caller retains ownership. Clears this field back to the default state. + // Used to implement release_() methods on generated classes. + PROTOBUF_NODISCARD std::string* Release(); // Takes a std::string that is heap-allocated, and takes ownership. The // std::string's destructor is registered with the arena. Used to implement // set_allocated_ in generated classes. - void SetAllocated(const std::string* default_value, std::string* value, - ::google::protobuf::Arena* arena); - - // Swaps internal pointers. Arena-safety semantics: this is guarded by the - // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is - // 'unsafe' if called directly. - inline PROTOBUF_NDEBUG_INLINE static void InternalSwap( - const std::string* default_value, ArenaStringPtr* rhs, Arena* rhs_arena, - ArenaStringPtr* lhs, Arena* lhs_arena); + void SetAllocated(std::string* value, Arena* arena); // Frees storage (if not on an arena). - void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena); - void Destroy(EmptyDefault, ::google::protobuf::Arena* arena); - void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena); + void Destroy(); // Clears content, but keeps allocated std::string, to avoid the overhead of // heap operations. After this returns, the content (as seen by the user) will @@ -281,48 +333,40 @@ struct PROTOBUF_EXPORT ArenaStringPtr { // (as seen by the user) will always be equal to |default_value|. void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena); - // Called from generated code / reflection runtime only. Resets value to point - // to a default string pointer, with the semantics that this - // ArenaStringPtr does not own the pointed-to memory. Disregards initial value - // of ptr_ (so this is the *ONLY* safe method to call after construction or - // when reinitializing after becoming the active field in a oneof union). - inline void UnsafeSetDefault(const std::string* default_value); - - // Returns a mutable pointer, but doesn't initialize the string to the - // default value. - std::string* MutableNoArenaNoDefault(const std::string* default_value); - - // Get a mutable pointer with unspecified contents. - // Similar to `MutableNoArenaNoDefault`, but also handles the arena case. - // If the value was donated, the contents are discarded. - std::string* MutableNoCopy(const std::string* default_value, - ::google::protobuf::Arena* arena); - - // Destroy the string. Assumes `arena == nullptr`. - void DestroyNoArena(const std::string* default_value); + // Swaps internal pointers. Arena-safety semantics: this is guarded by the + // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is + // 'unsafe' if called directly. + inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(ArenaStringPtr* rhs, + Arena* rhs_arena, + ArenaStringPtr* lhs, + Arena* lhs_arena); // Internal setter used only at parse time to directly set a donated string // value. - void UnsafeSetTaggedPointer(TaggedPtr value) { - tagged_ptr_ = value; - } + void UnsafeSetTaggedPointer(TaggedStringPtr value) { tagged_ptr_ = value; } // Generated code only! An optimization, in certain cases the generated // code is certain we can obtain a std::string with no default checks and // tag tests. std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; - inline bool IsDefault(const std::string* default_value) const { - // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the - // actual std::string pointer (and if !IsString(), ptr_ will never be equal - // to any aligned |default_value| pointer). The key is that we want to avoid - // masking in the fastpath const-pointer Get() case for non-arena code. - return tagged_ptr_.UnsafeGet() == default_value; - } + // Returns true if this instances holds an immutable default value. + inline bool IsDefault() const { return tagged_ptr_.IsDefault(); } private: - TaggedPtr tagged_ptr_; + template + inline std::string* NewString(Arena* arena, Args&&... args) { + if (arena == nullptr) { + auto* s = new std::string(std::forward(args)...); + return tagged_ptr_.SetAllocated(s); + } else { + auto* s = Arena::Create(arena, std::forward(args)...); + return tagged_ptr_.SetMutableArena(s); + } + } - bool IsDonatedString() const { return false; } + TaggedStringPtr tagged_ptr_; + + bool IsFixedSizeArena() const { return false; } // Swaps tagged pointer without debug hardening. This is to allow python // protobuf to maintain pointer stability even in DEBUG builds. @@ -332,46 +376,81 @@ struct PROTOBUF_EXPORT ArenaStringPtr { } friend class ::google::protobuf::internal::SwapFieldHelper; + friend class TcParser; // Slow paths. // MutableSlow requires that !IsString() || IsDefault - // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString. + // Variadic to support 0 args for empty default and 1 arg for LazyString. template std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default); - // Sets value to a newly allocated string and returns it - std::string* SetAndReturnNewString(); - - // Destroys the non-default string value out-of-line - void DestroyNoArenaSlowPath(); - + friend class EpsCopyInputStream; }; -inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) { - tagged_ptr_.Set(const_cast(value)); +inline void ArenaStringPtr::InitDefault() { + tagged_ptr_ = TaggedStringPtr(&fixed_address_empty_string); +} + +inline void ArenaStringPtr::InitExternal(const std::string* str) { + tagged_ptr_.SetDefault(str); +} + +inline void ArenaStringPtr::InitAllocated(std::string* str, Arena* arena) { + if (arena != nullptr) { + tagged_ptr_.SetMutableArena(str); + arena->Own(str); + } else { + tagged_ptr_.SetAllocated(str); + } +} + +inline void ArenaStringPtr::Set(const char* s, Arena* arena) { + Set(ConstStringParam{s}, arena); +} + +inline void ArenaStringPtr::Set(const char* s, size_t n, Arena* arena) { + Set(ConstStringParam{s, n}, arena); +} + +inline void ArenaStringPtr::SetBytes(ConstStringParam value, Arena* arena) { + Set(value, arena); +} + +inline void ArenaStringPtr::SetBytes(std::string&& value, Arena* arena) { + Set(std::move(value), arena); +} + +inline void ArenaStringPtr::SetBytes(const char* s, Arena* arena) { + Set(s, arena); +} + +inline void ArenaStringPtr::SetBytes(const void* p, size_t n, Arena* arena) { + Set(ConstStringParam{static_cast(p), n}, arena); } // Make sure rhs_arena allocated rhs, and lhs_arena allocated lhs. inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap( // - const std::string* default_value, // ArenaStringPtr* rhs, Arena* rhs_arena, // ArenaStringPtr* lhs, Arena* lhs_arena) { // Silence unused variable warnings in release buildls. - (void)default_value; (void)rhs_arena; (void)lhs_arena; std::swap(lhs->tagged_ptr_, rhs->tagged_ptr_); #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - auto force_realloc = [default_value](ArenaStringPtr* p, Arena* arena) { - if (p->IsDefault(default_value)) return; + auto force_realloc = [](ArenaStringPtr* p, Arena* arena) { + if (p->IsDefault()) return; std::string* old_value = p->tagged_ptr_.Get(); std::string* new_value = - p->IsDonatedString() + p->IsFixedSizeArena() ? Arena::Create(arena, *old_value) : Arena::Create(arena, std::move(*old_value)); - if (arena == nullptr) delete old_value; - p->tagged_ptr_.Set(new_value); + if (arena == nullptr) { + delete old_value; + p->tagged_ptr_.SetAllocated(new_value); + } else { + p->tagged_ptr_.SetMutableArena(new_value); + } }; // Because, at this point, tagged_ptr_ has been swapped, arena should also be // swapped. @@ -385,29 +464,10 @@ inline void ArenaStringPtr::ClearNonDefaultToEmpty() { tagged_ptr_.Get()->clear(); } -inline std::string* ArenaStringPtr::MutableNoArenaNoDefault( - const std::string* default_value) { - // VERY IMPORTANT for performance and code size: this will reduce to a member - // variable load, a pointer check (against |default_value|, in practice a - // static global) and a branch to the slowpath (which calls operator new and - // the ctor). DO NOT add any tagged-pointer operations here. - if (IsDefault(default_value)) { - return SetAndReturnNewString(); - } else { - return UnsafeMutablePointer(); - } -} - -inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) { - if (!IsDefault(default_value)) { - DestroyNoArenaSlowPath(); - } -} - inline std::string* ArenaStringPtr::UnsafeMutablePointer() { - GOOGLE_DCHECK(!tagged_ptr_.IsTagged()); - GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr); - return tagged_ptr_.UnsafeGet(); + GOOGLE_DCHECK(tagged_ptr_.IsMutable()); + GOOGLE_DCHECK(tagged_ptr_.Get() != nullptr); + return tagged_ptr_.Get(); } diff --git a/third_party/protobuf/src/google/protobuf/arenastring_unittest.cc b/third_party/protobuf/src/google/protobuf/arenastring_unittest.cc index db988afb..0e5ea9b3 100644 --- a/third_party/protobuf/src/google/protobuf/arenastring_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/arenastring_unittest.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,6 @@ namespace protobuf { using internal::ArenaStringPtr; -using EmptyDefault = ArenaStringPtr::EmptyDefault; - const internal::LazyString nonempty_default{{{"default", 7}}, {nullptr}}; const std::string* empty_default = &internal::GetEmptyString(); @@ -72,37 +71,36 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, SingleArena, testing::Bool()); TEST_P(SingleArena, GetSet) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(empty_default); + field.InitDefault(); EXPECT_EQ("", field.Get()); - field.Set(empty_default, "Test short", arena.get()); + field.Set("Test short", arena.get()); EXPECT_EQ("Test short", field.Get()); - field.Set(empty_default, "Test long long long long value", arena.get()); + field.Set("Test long long long long value", arena.get()); EXPECT_EQ("Test long long long long value", field.Get()); - field.Set(empty_default, "", arena.get()); - field.Destroy(empty_default, arena.get()); + field.Set("", arena.get()); + field.Destroy(); } TEST_P(SingleArena, MutableAccessor) { auto arena = GetArena(); ArenaStringPtr field; - const std::string* empty_default = &internal::GetEmptyString(); - field.UnsafeSetDefault(empty_default); + field.InitDefault(); - std::string* mut = field.Mutable(EmptyDefault{}, arena.get()); - EXPECT_EQ(mut, field.Mutable(EmptyDefault{}, arena.get())); + std::string* mut = field.Mutable(arena.get()); + EXPECT_EQ(mut, field.Mutable(arena.get())); EXPECT_EQ(mut, &field.Get()); EXPECT_NE(empty_default, mut); EXPECT_EQ("", *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ("Test long long long long value", field.Get()); - field.Destroy(empty_default, arena.get()); + field.Destroy(); } TEST_P(SingleArena, NullDefault) { auto arena = GetArena(); ArenaStringPtr field; - field.UnsafeSetDefault(nullptr); + field.InitDefault(); std::string* mut = field.Mutable(nonempty_default, arena.get()); EXPECT_EQ(mut, field.Mutable(nonempty_default, arena.get())); EXPECT_EQ(mut, &field.Get()); @@ -110,7 +108,7 @@ TEST_P(SingleArena, NullDefault) { EXPECT_EQ("default", *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ("Test long long long long value", field.Get()); - field.Destroy(nullptr, arena.get()); + field.Destroy(); } class DualArena : public testing::TestWithParam> { @@ -131,23 +129,22 @@ INSTANTIATE_TEST_SUITE_P(ArenaString, DualArena, TEST_P(DualArena, Swap) { auto lhs_arena = GetLhsArena(); ArenaStringPtr lhs; - lhs.UnsafeSetDefault(empty_default); + lhs.InitDefault(); ArenaStringPtr rhs; - rhs.UnsafeSetDefault(empty_default); + rhs.InitDefault(); { auto rhs_arena = GetRhsArena(); - lhs.Set(empty_default, "lhs value that has some heft", lhs_arena.get()); - rhs.Set(empty_default, "rhs value that has some heft", rhs_arena.get()); - ArenaStringPtr::InternalSwap(empty_default, // - &lhs, lhs_arena.get(), // + lhs.Set("lhs value that has some heft", lhs_arena.get()); + rhs.Set("rhs value that has some heft", rhs_arena.get()); + ArenaStringPtr::InternalSwap(&lhs, lhs_arena.get(), // &rhs, rhs_arena.get()); EXPECT_EQ("rhs value that has some heft", lhs.Get()); EXPECT_EQ("lhs value that has some heft", rhs.Get()); - lhs.Destroy(empty_default, rhs_arena.get()); + lhs.Destroy(); } EXPECT_EQ("lhs value that has some heft", rhs.Get()); - rhs.Destroy(empty_default, lhs_arena.get()); + rhs.Destroy(); } diff --git a/third_party/protobuf/src/google/protobuf/arenaz_sampler.cc b/third_party/protobuf/src/google/protobuf/arenaz_sampler.cc new file mode 100644 index 00000000..0eac693d --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/arenaz_sampler.cc @@ -0,0 +1,177 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { + +ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler() { + static auto* sampler = new ThreadSafeArenazSampler(); + return *sampler; +} + +void UnsampleSlow(ThreadSafeArenaStats* info) { + GlobalThreadSafeArenazSampler().Unregister(info); +} + +#if defined(PROTOBUF_ARENAZ_SAMPLE) +namespace { + +PROTOBUF_CONSTINIT std::atomic g_arenaz_enabled{true}; +PROTOBUF_CONSTINIT std::atomic g_arenaz_sample_parameter{1 << 10}; +PROTOBUF_THREAD_LOCAL absl::profiling_internal::ExponentialBiased + g_exponential_biased_generator; + +} // namespace + +PROTOBUF_THREAD_LOCAL int64_t global_next_sample = 1LL << 10; + +ThreadSafeArenaStats::ThreadSafeArenaStats() { PrepareForSampling(); } +ThreadSafeArenaStats::~ThreadSafeArenaStats() = default; + +void ThreadSafeArenaStats::PrepareForSampling() { + num_allocations.store(0, std::memory_order_relaxed); + num_resets.store(0, std::memory_order_relaxed); + bytes_requested.store(0, std::memory_order_relaxed); + bytes_allocated.store(0, std::memory_order_relaxed); + bytes_wasted.store(0, std::memory_order_relaxed); + max_bytes_allocated.store(0, std::memory_order_relaxed); + thread_ids.store(0, std::memory_order_relaxed); + // The inliner makes hardcoded skip_count difficult (especially when combined + // with LTO). We use the ability to exclude stacks by regex when encoding + // instead. + depth = absl::GetStackTrace(stack, kMaxStackDepth, /* skip_count= */ 0); +} + +void RecordResetSlow(ThreadSafeArenaStats* info) { + const size_t max_bytes = + info->max_bytes_allocated.load(std::memory_order_relaxed); + const size_t allocated_bytes = + info->bytes_allocated.load(std::memory_order_relaxed); + if (max_bytes < allocated_bytes) { + info->max_bytes_allocated.store(allocated_bytes); + } + info->bytes_requested.store(0, std::memory_order_relaxed); + info->bytes_allocated.store(0, std::memory_order_relaxed); + info->bytes_wasted.fetch_add(0, std::memory_order_relaxed); + info->num_allocations.fetch_add(0, std::memory_order_relaxed); + info->num_resets.fetch_add(1, std::memory_order_relaxed); +} + +void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted) { + info->bytes_requested.fetch_add(requested, std::memory_order_relaxed); + info->bytes_allocated.fetch_add(allocated, std::memory_order_relaxed); + info->bytes_wasted.fetch_add(wasted, std::memory_order_relaxed); + info->num_allocations.fetch_add(1, std::memory_order_relaxed); + const uint64_t tid = (1ULL << (GetCachedTID() % 63)); + const uint64_t thread_ids = info->thread_ids.load(std::memory_order_relaxed); + if (!(thread_ids & tid)) { + info->thread_ids.store(thread_ids | tid, std::memory_order_relaxed); + } +} + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) { + bool first = *next_sample < 0; + *next_sample = g_exponential_biased_generator.GetStride( + g_arenaz_sample_parameter.load(std::memory_order_relaxed)); + // Small values of interval are equivalent to just sampling next time. + ABSL_ASSERT(*next_sample >= 1); + + // g_arenaz_enabled can be dynamically flipped, we need to set a threshold low + // enough that we will start sampling in a reasonable time, so we just use the + // default sampling rate. + if (!g_arenaz_enabled.load(std::memory_order_relaxed)) return nullptr; + // We will only be negative on our first count, so we should just retry in + // that case. + if (first) { + if (PROTOBUF_PREDICT_TRUE(--*next_sample > 0)) return nullptr; + return SampleSlow(next_sample); + } + + return GlobalThreadSafeArenazSampler().Register(); +} + +void SetThreadSafeArenazEnabled(bool enabled) { + g_arenaz_enabled.store(enabled, std::memory_order_release); +} + +void SetThreadSafeArenazSampleParameter(int32_t rate) { + if (rate > 0) { + g_arenaz_sample_parameter.store(rate, std::memory_order_release); + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz sample rate: %lld", + static_cast(rate)); // NOLINT(runtime/int) + } +} + +void SetThreadSafeArenazMaxSamples(int32_t max) { + if (max > 0) { + GlobalThreadSafeArenazSampler().SetMaxSamples(max); + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz max samples: %lld", + static_cast(max)); // NOLINT(runtime/int) + } +} + +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) { + if (next_sample >= 0) { + global_next_sample = next_sample; + } else { + ABSL_RAW_LOG(ERROR, "Invalid thread safe arenaz next sample: %lld", + static_cast(next_sample)); // NOLINT(runtime/int) + } +} + +#else +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample) { + *next_sample = std::numeric_limits::max(); + return nullptr; +} + +void SetThreadSafeArenazEnabled(bool enabled) {} +void SetThreadSafeArenazSampleParameter(int32_t rate) {} +void SetThreadSafeArenazMaxSamples(int32_t max) {} +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample) {} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/arenaz_sampler.h b/third_party/protobuf/src/google/protobuf/arenaz_sampler.h new file mode 100644 index 00000000..b04b0cc6 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/arenaz_sampler.h @@ -0,0 +1,207 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__ +#define GOOGLE_PROTOBUF_SRC_GOOGLE_PROTOBUF_ARENAZ_SAMPLER_H__ + +#include +#include +#include + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { + +#if defined(PROTOBUF_ARENAZ_SAMPLE) +struct ThreadSafeArenaStats; +void RecordResetSlow(ThreadSafeArenaStats* info); +void RecordAllocateSlow(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted); +// Stores information about a sampled thread safe arena. All mutations to this +// *must* be made through `Record*` functions below. All reads from this *must* +// only occur in the callback to `ThreadSafeArenazSampler::Iterate`. +struct ThreadSafeArenaStats + : public absl::profiling_internal::Sample { + // Constructs the object but does not fill in any fields. + ThreadSafeArenaStats(); + ~ThreadSafeArenaStats(); + + // Puts the object into a clean state, fills in the logically `const` members, + // blocking for any readers that are currently sampling the object. + void PrepareForSampling() ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu); + + // These fields are mutated by the various Record* APIs and need to be + // thread-safe. + std::atomic num_allocations; + std::atomic num_resets; + std::atomic bytes_requested; + std::atomic bytes_allocated; + std::atomic bytes_wasted; + // Records the largest size an arena ever had. Maintained across resets. + std::atomic max_bytes_allocated; + // Bit i when set to 1 indicates that a thread with tid % 63 = i accessed the + // underlying arena. The field is maintained across resets. + std::atomic thread_ids; + + // All of the fields below are set by `PrepareForSampling`, they must not + // be mutated in `Record*` functions. They are logically `const` in that + // sense. These are guarded by init_mu, but that is not externalized to + // clients, who can only read them during + // `ThreadSafeArenazSampler::Iterate` which will hold the lock. + static constexpr int kMaxStackDepth = 64; + int32_t depth; + void* stack[kMaxStackDepth]; + static void RecordAllocateStats(ThreadSafeArenaStats* info, size_t requested, + size_t allocated, size_t wasted) { + if (PROTOBUF_PREDICT_TRUE(info == nullptr)) return; + RecordAllocateSlow(info, requested, allocated, wasted); + } +}; + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample); +void UnsampleSlow(ThreadSafeArenaStats* info); + +class ThreadSafeArenaStatsHandle { + public: + explicit ThreadSafeArenaStatsHandle() = default; + explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats* info) + : info_(info) {} + + ~ThreadSafeArenaStatsHandle() { + if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return; + UnsampleSlow(info_); + } + + ThreadSafeArenaStatsHandle(ThreadSafeArenaStatsHandle&& other) noexcept + : info_(absl::exchange(other.info_, nullptr)) {} + + ThreadSafeArenaStatsHandle& operator=( + ThreadSafeArenaStatsHandle&& other) noexcept { + if (PROTOBUF_PREDICT_FALSE(info_ != nullptr)) { + UnsampleSlow(info_); + } + info_ = absl::exchange(other.info_, nullptr); + return *this; + } + + void RecordReset() { + if (PROTOBUF_PREDICT_TRUE(info_ == nullptr)) return; + RecordResetSlow(info_); + } + + ThreadSafeArenaStats* MutableStats() { return info_; } + + friend void swap(ThreadSafeArenaStatsHandle& lhs, + ThreadSafeArenaStatsHandle& rhs) { + std::swap(lhs.info_, rhs.info_); + } + + friend class ThreadSafeArenaStatsHandlePeer; + + private: + ThreadSafeArenaStats* info_ = nullptr; +}; + +using ThreadSafeArenazSampler = + ::absl::profiling_internal::SampleRecorder; + +extern PROTOBUF_THREAD_LOCAL int64_t global_next_sample; + +// Returns an RAII sampling handle that manages registration and unregistation +// with the global sampler. +inline ThreadSafeArenaStatsHandle Sample() { + if (PROTOBUF_PREDICT_TRUE(--global_next_sample > 0)) { + return ThreadSafeArenaStatsHandle(nullptr); + } + return ThreadSafeArenaStatsHandle(SampleSlow(&global_next_sample)); +} + +#else +struct ThreadSafeArenaStats { + static void RecordAllocateStats(ThreadSafeArenaStats*, size_t /*requested*/, + size_t /*allocated*/, size_t /*wasted*/) {} +}; + +ThreadSafeArenaStats* SampleSlow(int64_t* next_sample); +void UnsampleSlow(ThreadSafeArenaStats* info); + +class ThreadSafeArenaStatsHandle { + public: + explicit ThreadSafeArenaStatsHandle() = default; + explicit ThreadSafeArenaStatsHandle(ThreadSafeArenaStats*) {} + + void RecordReset() {} + + ThreadSafeArenaStats* MutableStats() { return nullptr; } + + friend void swap(ThreadSafeArenaStatsHandle&, ThreadSafeArenaStatsHandle&) {} + + private: + friend class ThreadSafeArenaStatsHandlePeer; +}; + +class ThreadSafeArenazSampler { + public: + void Unregister(ThreadSafeArenaStats*) {} + void SetMaxSamples(int32_t) {} +}; + +// Returns an RAII sampling handle that manages registration and unregistation +// with the global sampler. +inline ThreadSafeArenaStatsHandle Sample() { + return ThreadSafeArenaStatsHandle(nullptr); +} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +// Returns a global Sampler. +ThreadSafeArenazSampler& GlobalThreadSafeArenazSampler(); + +// Enables or disables sampling for thread safe arenas. +void SetThreadSafeArenazEnabled(bool enabled); + +// Sets the rate at which thread safe arena will be sampled. +void SetThreadSafeArenazSampleParameter(int32_t rate); + +// Sets a soft max for the number of samples that will be kept. +void SetThreadSafeArenazMaxSamples(int32_t max); + +// Sets the current value for when arenas should be next sampled. +void SetThreadSafeArenazGlobalNextSample(int64_t next_sample); + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include +#endif // GOOGLE_PROTOBUF_SRC_PROTOBUF_ARENAZ_SAMPLER_H__ diff --git a/third_party/protobuf/src/google/protobuf/arenaz_sampler_test.cc b/third_party/protobuf/src/google/protobuf/arenaz_sampler_test.cc new file mode 100644 index 00000000..1bfec542 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/arenaz_sampler_test.cc @@ -0,0 +1,382 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include + +#include +#include +#include + + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace internal { +#if defined(PROTOBUF_ARENAZ_SAMPLE) +class ThreadSafeArenaStatsHandlePeer { + public: + static bool IsSampled(const ThreadSafeArenaStatsHandle& h) { + return h.info_ != nullptr; + } + + static ThreadSafeArenaStats* GetInfo(ThreadSafeArenaStatsHandle* h) { + return h->info_; + } +}; +std::vector GetBytesAllocated(ThreadSafeArenazSampler* s) { + std::vector res; + s->Iterate([&](const ThreadSafeArenaStats& info) { + res.push_back(info.bytes_allocated.load(std::memory_order_acquire)); + }); + return res; +} + +ThreadSafeArenaStats* Register(ThreadSafeArenazSampler* s, size_t size) { + auto* info = s->Register(); + assert(info != nullptr); + info->bytes_allocated.store(size); + return info; +} + +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +namespace { + +#if defined(PROTOBUF_ARENAZ_SAMPLE) + +TEST(ThreadSafeArenaStatsTest, PrepareForSampling) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + + EXPECT_EQ(info.num_allocations.load(), 0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); + + info.num_allocations.store(1, std::memory_order_relaxed); + info.num_resets.store(1, std::memory_order_relaxed); + info.bytes_requested.store(1, std::memory_order_relaxed); + info.bytes_allocated.store(1, std::memory_order_relaxed); + info.bytes_wasted.store(1, std::memory_order_relaxed); + info.max_bytes_allocated.store(1, std::memory_order_relaxed); + + info.PrepareForSampling(); + EXPECT_EQ(info.num_allocations.load(), 0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenaStatsTest, RecordAllocateSlow) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/128, /*wasted=*/0); + EXPECT_EQ(info.num_allocations.load(), 1); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 100); + EXPECT_EQ(info.bytes_allocated.load(), 128); + EXPECT_EQ(info.bytes_wasted.load(), 0); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/256, + /*wasted=*/28); + EXPECT_EQ(info.num_allocations.load(), 2); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_requested.load(), 200); + EXPECT_EQ(info.bytes_allocated.load(), 384); + EXPECT_EQ(info.bytes_wasted.load(), 28); + EXPECT_EQ(info.max_bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenaStatsTest, RecordResetSlow) { + ThreadSafeArenaStats info; + MutexLock l(&info.init_mu); + info.PrepareForSampling(); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 0); + RecordAllocateSlow(&info, /*requested=*/100, /*allocated=*/128, /*wasted=*/0); + EXPECT_EQ(info.num_resets.load(), 0); + EXPECT_EQ(info.bytes_allocated.load(), 128); + RecordResetSlow(&info); + EXPECT_EQ(info.num_resets.load(), 1); + EXPECT_EQ(info.bytes_allocated.load(), 0); +} + +TEST(ThreadSafeArenazSamplerTest, SmallSampleParameter) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(100); + + for (int i = 0; i < 1000; ++i) { + int64_t next_sample = 0; + ThreadSafeArenaStats* sample = SampleSlow(&next_sample); + EXPECT_GT(next_sample, 0); + EXPECT_NE(sample, nullptr); + UnsampleSlow(sample); + } +} + +TEST(ThreadSafeArenazSamplerTest, LargeSampleParameter) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(std::numeric_limits::max()); + + for (int i = 0; i < 1000; ++i) { + int64_t next_sample = 0; + ThreadSafeArenaStats* sample = SampleSlow(&next_sample); + EXPECT_GT(next_sample, 0); + EXPECT_NE(sample, nullptr); + UnsampleSlow(sample); + } +} + +TEST(ThreadSafeArenazSamplerTest, Sample) { + SetThreadSafeArenazEnabled(true); + SetThreadSafeArenazSampleParameter(100); + SetThreadSafeArenazGlobalNextSample(0); + int64_t num_sampled = 0; + int64_t total = 0; + double sample_rate = 0.0; + for (int i = 0; i < 1000000; ++i) { + ThreadSafeArenaStatsHandle h = Sample(); + ++total; + if (ThreadSafeArenaStatsHandlePeer::IsSampled(h)) { + ++num_sampled; + } + sample_rate = static_cast(num_sampled) / total; + if (0.005 < sample_rate && sample_rate < 0.015) break; + } + EXPECT_NEAR(sample_rate, 0.01, 0.005); +} + +TEST(ThreadSafeArenazSamplerTest, Handle) { + auto& sampler = GlobalThreadSafeArenazSampler(); + ThreadSafeArenaStatsHandle h(sampler.Register()); + auto* info = ThreadSafeArenaStatsHandlePeer::GetInfo(&h); + info->bytes_allocated.store(0x12345678, std::memory_order_relaxed); + + bool found = false; + sampler.Iterate([&](const ThreadSafeArenaStats& h) { + if (&h == info) { + EXPECT_EQ(h.bytes_allocated.load(), 0x12345678); + found = true; + } + }); + EXPECT_TRUE(found); + + h = ThreadSafeArenaStatsHandle(); + found = false; + sampler.Iterate([&](const ThreadSafeArenaStats& h) { + if (&h == info) { + // this will only happen if some other thread has resurrected the info + // the old handle was using. + if (h.bytes_allocated.load() == 0x12345678) { + found = true; + } + } + }); + EXPECT_FALSE(found); +} + +TEST(ThreadSafeArenazSamplerTest, Registration) { + ThreadSafeArenazSampler sampler; + auto* info1 = Register(&sampler, 1); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(1)); + + auto* info2 = Register(&sampler, 2); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(1, 2)); + info1->bytes_allocated.store(3); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(3, 2)); + + sampler.Unregister(info1); + sampler.Unregister(info2); +} + +TEST(ThreadSafeArenazSamplerTest, Unregistration) { + ThreadSafeArenazSampler sampler; + std::vector infos; + for (size_t i = 0; i < 3; ++i) { + infos.push_back(Register(&sampler, i)); + } + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 1, 2)); + + sampler.Unregister(infos[1]); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2)); + + infos.push_back(Register(&sampler, 3)); + infos.push_back(Register(&sampler, 4)); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2, 3, 4)); + sampler.Unregister(infos[3]); + EXPECT_THAT(GetBytesAllocated(&sampler), UnorderedElementsAre(0, 2, 4)); + + sampler.Unregister(infos[0]); + sampler.Unregister(infos[2]); + sampler.Unregister(infos[4]); + EXPECT_THAT(GetBytesAllocated(&sampler), IsEmpty()); +} + +TEST(ThreadSafeArenazSamplerTest, MultiThreaded) { + ThreadSafeArenazSampler sampler; + absl::Notification stop; + ThreadPool pool(10); + + for (int i = 0; i < 10; ++i) { + pool.Schedule([&sampler, &stop]() { + std::random_device rd; + std::mt19937 gen(rd()); + + std::vector infoz; + while (!stop.HasBeenNotified()) { + if (infoz.empty()) { + infoz.push_back(sampler.Register()); + } + switch (std::uniform_int_distribution<>(0, 1)(gen)) { + case 0: { + infoz.push_back(sampler.Register()); + break; + } + case 1: { + size_t p = + std::uniform_int_distribution<>(0, infoz.size() - 1)(gen); + ThreadSafeArenaStats* info = infoz[p]; + infoz[p] = infoz.back(); + infoz.pop_back(); + sampler.Unregister(info); + break; + } + } + } + }); + } + // The threads will hammer away. Give it a little bit of time for tsan to + // spot errors. + absl::SleepFor(absl::Seconds(3)); + stop.Notify(); +} + +TEST(ThreadSafeArenazSamplerTest, Callback) { + ThreadSafeArenazSampler sampler; + + auto* info1 = Register(&sampler, 1); + auto* info2 = Register(&sampler, 2); + + static const ThreadSafeArenaStats* expected; + + auto callback = [](const ThreadSafeArenaStats& info) { + // We can't use `info` outside of this callback because the object will be + // disposed as soon as we return from here. + EXPECT_EQ(&info, expected); + }; + + // Set the callback. + EXPECT_EQ(sampler.SetDisposeCallback(callback), nullptr); + expected = info1; + sampler.Unregister(info1); + + // Unset the callback. + EXPECT_EQ(callback, sampler.SetDisposeCallback(nullptr)); + expected = nullptr; // no more calls. + sampler.Unregister(info2); +} + +class ThreadSafeArenazSamplerTestThread : public Thread { + protected: + void Run() override { + google::protobuf::ArenaSafeUniquePtr< + protobuf_test_messages::proto2::TestAllTypesProto2> + message = google::protobuf::MakeArenaSafeUnique< + protobuf_test_messages::proto2::TestAllTypesProto2>(arena_); + GOOGLE_CHECK(message != nullptr); + // Signal that a message on the arena has been created. This should create + // a SerialArena for this thread. + if (barrier_->Block()) { + delete barrier_; + } + } + + public: + ThreadSafeArenazSamplerTestThread(const thread::Options& options, + StringPiece name, + google::protobuf::Arena* arena, + absl::Barrier* barrier) + : Thread(options, name), arena_(arena), barrier_(barrier) {} + + private: + google::protobuf::Arena* arena_; + absl::Barrier* barrier_; +}; + +TEST(ThreadSafeArenazSamplerTest, MultiThread) { + SetThreadSafeArenazEnabled(true); + // Setting 1 as the parameter value means one in every two arenas would be + // sampled, on average. + SetThreadSafeArenazSampleParameter(1); + SetThreadSafeArenazGlobalNextSample(0); + auto& sampler = GlobalThreadSafeArenazSampler(); + int count = 0; + for (int i = 0; i < 10; ++i) { + const int kNumThreads = 10; + absl::Barrier* barrier = new absl::Barrier(kNumThreads + 1); + google::protobuf::Arena arena; + thread::Options options; + options.set_joinable(true); + std::vector> threads; + for (int i = 0; i < kNumThreads; i++) { + auto t = std::make_unique( + options, StrCat("thread", i), &arena, barrier); + t->Start(); + threads.push_back(std::move(t)); + } + // Wait till each thread has created a message on the arena. + if (barrier->Block()) { + delete barrier; + } + sampler.Iterate([&](const ThreadSafeArenaStats& h) { ++count; }); + for (int i = 0; i < kNumThreads; i++) { + threads[i]->Join(); + } + } + EXPECT_GT(count, 0); +} +#endif // defined(PROTOBUF_ARENAZ_SAMPLE) + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc b/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc index 3c47aa42..f0815c56 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc @@ -58,9 +58,8 @@ class DescriptorCapturingGenerator : public CodeGenerator { explicit DescriptorCapturingGenerator(FileDescriptorProto* file) : file_(file) {} - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const { + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override { file->CopyTo(file_); return true; } @@ -128,7 +127,7 @@ const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( std::vector annotations; FindAnnotationsOnPath(info, source_file, path, &annotations); if (annotations.empty()) { - return NULL; + return nullptr; } return annotations[0]; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.h b/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.h index 551f2244..b7c6ddd3 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.h +++ b/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.h @@ -78,7 +78,7 @@ bool RunProtoCompiler(const std::string& filename, bool DecodeMetadata(const std::string& path, GeneratedCodeInfo* info); // Finds all of the Annotations for a given source file and path. -// See Location.path in https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto for +// See Location.path in https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto for // explanation of what path vector is. void FindAnnotationsOnPath( const GeneratedCodeInfo& info, const std::string& source_file, @@ -88,7 +88,7 @@ void FindAnnotationsOnPath( // Finds the Annotation for a given source file and path (or returns null if it // couldn't). If there are several annotations for given path, returns the first // one. See Location.path in -// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto for explanation of what path +// https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto for explanation of what path // vector is. const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( const GeneratedCodeInfo& info, const std::string& source_file, diff --git a/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc index 4544f3e7..dc9d450a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc @@ -76,13 +76,13 @@ GeneratorContext::~GeneratorContext() {} io::ZeroCopyOutputStream* GeneratorContext::OpenForAppend( const std::string& filename) { - return NULL; + return nullptr; } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( const std::string& filename, const std::string& insertion_point) { GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion."; - return NULL; // make compiler happy + return nullptr; // make compiler happy } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo( diff --git a/third_party/protobuf/src/google/protobuf/compiler/code_generator.h b/third_party/protobuf/src/google/protobuf/compiler/code_generator.h index 2cbda270..9c0b115c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/code_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/code_generator.h @@ -43,6 +43,7 @@ #include #include +// Must be included last. #include namespace google { @@ -188,9 +189,9 @@ typedef GeneratorContext OutputDirectory; // Several code generators treat the parameter argument as holding a // list of options separated by commas. This helper function parses // a set of comma-delimited name/value pairs: e.g., -// "foo=bar,baz,qux=corge" +// "foo=bar,baz,moo=corge" // parses to the pairs: -// ("foo", "bar"), ("baz", ""), ("qux", "corge") +// ("foo", "bar"), ("baz", ""), ("moo", "corge") PROTOC_EXPORT void ParseGeneratorParameter( const std::string&, std::vector >*); diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc index bfc6b055..5e9a2c41 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc @@ -34,8 +34,6 @@ #include -#include - #include #include @@ -53,10 +51,11 @@ #endif #include #include + #include #include -#include //For PATH_MAX +#include // For PATH_MAX #include @@ -68,25 +67,26 @@ #include #include -#include #include -#include #include +#include +#include +#include #include #include -#include -#include -#include +#include #include #include -#include -#include -#include +#include #include +#include +#include +#include #include #include +// Must be included last. #include namespace google { @@ -195,7 +195,7 @@ bool TryCreateParentDirectory(const std::string& prefix, bool GetProtocAbsolutePath(std::string* path) { #ifdef _WIN32 char buffer[MAX_PATH]; - int len = GetModuleFileNameA(NULL, buffer, MAX_PATH); + int len = GetModuleFileNameA(nullptr, buffer, MAX_PATH); #elif defined(__APPLE__) char buffer[PATH_MAX]; int len = 0; @@ -210,7 +210,7 @@ bool GetProtocAbsolutePath(std::string* path) { char buffer[PATH_MAX]; size_t len = PATH_MAX; int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; - if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) { + if (sysctl(mib, 4, &buffer, &len, nullptr, 0) != 0) { len = 0; } #else @@ -289,12 +289,12 @@ class CommandLineInterface::ErrorPrinter public io::ErrorCollector, public DescriptorPool::ErrorCollector { public: - ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL) + ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = nullptr) : format_(format), tree_(tree), found_errors_(false), found_warnings_(false) {} - ~ErrorPrinter() {} + ~ErrorPrinter() override {} // implements MultiFileErrorCollector ------------------------------ void AddError(const std::string& filename, int line, int column, @@ -341,8 +341,8 @@ class CommandLineInterface::ErrorPrinter std::ostream& out) { // Print full path when running under MSVS std::string dfile; - if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL && - tree_->VirtualFileToDiskFile(filename, &dfile)) { + if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && + tree_ != nullptr && tree_->VirtualFileToDiskFile(filename, &dfile)) { out << dfile; } else { out << filename; @@ -434,7 +434,7 @@ class CommandLineInterface::MemoryOutputStream const std::string& filename, const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info); - virtual ~MemoryOutputStream(); + ~MemoryOutputStream() override; // implements ZeroCopyOutputStream --------------------------------- bool Next(void** data, int* size) override { @@ -1116,7 +1116,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { FileDescriptorProto file; file.set_name("empty_message.proto"); file.add_message_type()->set_name("EmptyMessage"); - GOOGLE_CHECK(pool.BuildFile(file) != NULL); + GOOGLE_CHECK(pool.BuildFile(file) != nullptr); codec_type_ = "EmptyMessage"; if (!EncodeOrDecode(&pool)) { return 1; @@ -1270,7 +1270,7 @@ bool CommandLineInterface::ParseInputFiles( // Import the file. const FileDescriptor* parsed_file = descriptor_pool->FindFileByName(input_file); - if (parsed_file == NULL) { + if (parsed_file == nullptr) { result = false; break; } @@ -1496,7 +1496,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( for (std::vector::const_iterator j = output_directives_.begin(); j != output_directives_.end(); ++j) { - if (j->generator == NULL) { + if (j->generator == nullptr) { std::string plugin_name = PluginName(plugin_prefix_, j->name); if (plugin_name == i->first) { foundImplicitPlugin = true; @@ -1606,7 +1606,7 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name, // Two dashes: Multi-character name, with '=' separating name and // value. const char* equals_pos = strchr(arg, '='); - if (equals_pos != NULL) { + if (equals_pos != nullptr) { *name = std::string(arg, equals_pos - arg); *value = equals_pos + 1; parsed_value = true; @@ -1674,8 +1674,9 @@ CommandLineInterface::InterpretArgument(const std::string& name, // On Windows, the shell (typically cmd.exe) does not expand wildcards in // file names (e.g. foo\*.proto), so we do it ourselves. switch (google::protobuf::io::win32::ExpandWildcards( - value, - [this](const string& path) { this->input_files_.push_back(path); })) { + value, [this](const std::string& path) { + this->input_files_.push_back(path); + })) { case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess: break; case google::protobuf::io::win32::ExpandWildcardsResult:: @@ -1946,11 +1947,11 @@ CommandLineInterface::InterpretArgument(const std::string& name, // Some other flag. Look it up in the generators list. const GeneratorInfo* generator_info = FindOrNull(generators_by_flag_name_, name); - if (generator_info == NULL && + if (generator_info == nullptr && (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { // Check if it's a generator option flag. generator_info = FindOrNull(generators_by_option_name_, name); - if (generator_info != NULL) { + if (generator_info != nullptr) { std::string* parameters = &generator_parameters_[generator_info->flag_name]; if (!parameters->empty()) { @@ -1979,8 +1980,8 @@ CommandLineInterface::InterpretArgument(const std::string& name, OutputDirective directive; directive.name = name; - if (generator_info == NULL) { - directive.generator = NULL; + if (generator_info == nullptr) { + directive.generator = nullptr; } else { directive.generator = generator_info->generator; } @@ -2136,7 +2137,7 @@ bool CommandLineInterface::GenerateOutput( GeneratorContext* generator_context) { // Call the generator. std::string error; - if (output_directive.generator == NULL) { + if (output_directive.generator == nullptr) { // This is a plugin. GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && HasSuffixString(output_directive.name, "_out")) @@ -2208,6 +2209,10 @@ bool CommandLineInterface::GenerateDependencyManifestFile( } } + if (!descriptor_set_out_name_.empty()) { + output_filenames.push_back(descriptor_set_out_name_); + } + int fd; do { fd = open(dependency_out_name_.c_str(), @@ -2304,7 +2309,7 @@ bool CommandLineInterface::GeneratePluginOutput( if (!output_file.insertion_point().empty()) { std::string filename = output_file.name(); // Open a file for insert. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset( @@ -2313,11 +2318,11 @@ bool CommandLineInterface::GeneratePluginOutput( output_file.generated_code_info())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset(generator_context->Open(output_file.name())); - } else if (current_output == NULL) { + } else if (current_output == nullptr) { *error = strings::Substitute( "$0: First file chunk returned by plugin did not specify a file " "name.", @@ -2347,7 +2352,7 @@ bool CommandLineInterface::GeneratePluginOutput( bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { // Look up the type. const Descriptor* type = pool->FindMessageTypeByName(codec_type_); - if (type == NULL) { + if (type == nullptr) { std::cerr << "Type not defined: " << codec_type_ << std::endl; return false; } @@ -2586,7 +2591,8 @@ void FormatFreeFieldNumbers(const std::string& name, StringAppendF(&output, " %d", next_free_number); } else { // Range - StringAppendF(&output, " %d-%d", next_free_number, i->first - 1); + StringAppendF(&output, " %d-%d", next_free_number, + i->first - 1); } } next_free_number = i->second; diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h index 27178b1b..e8425508 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h @@ -49,6 +49,8 @@ #include #include + +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc index 9cc8cf98..f48135ec 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -50,24 +50,27 @@ #include #include #include -#include -#include -#include -#include #include #include #include -#include -#include #include -#include #include #include #include #include +#include +#include +#include +#include +#include #include +#include +#include +// Must be included last. +#include + namespace google { namespace protobuf { namespace compiler { @@ -96,8 +99,8 @@ bool FileExists(const std::string& path) { class CommandLineInterfaceTest : public testing::Test { protected: - virtual void SetUp(); - virtual void TearDown(); + void SetUp() override; + void TearDown() override; // Runs the CommandLineInterface with the given command line. The // command is automatically split on spaces, and the string "$tmpdir" @@ -256,14 +259,14 @@ class CommandLineInterfaceTest : public testing::Test { class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { public: NullCodeGenerator() : called_(false) {} - ~NullCodeGenerator() {} + ~NullCodeGenerator() override {} mutable bool called_; mutable std::string parameter_; // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const { + GeneratorContext* context, std::string* error) const override { called_ = true; parameter_ = parameter; return true; @@ -1714,7 +1717,7 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFile) { " optional Foo foo = 1;\n" "}\n"); - std::string current_working_directory = getcwd(NULL, 0); + std::string current_working_directory = getcwd(nullptr, 0); SwitchToTempDirectory(); Run("protocol_compiler --dependency_out=manifest --test_out=. " @@ -1753,6 +1756,28 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) { "$tmpdir/bar.proto.MockCodeGenerator.test_generator: " "$tmpdir/foo.proto\\\n $tmpdir/bar.proto"); } + +TEST_F(CommandLineInterfaceTest, + WriteDependencyManifestFileWithDescriptorSetOut) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"foo.proto\";\n" + "message Bar {\n" + " optional Foo foo = 1;\n" + "}\n"); + + Run("protocol_compiler --dependency_out=$tmpdir/manifest " + "--descriptor_set_out=$tmpdir/bar.pb --proto_path=$tmpdir bar.proto"); + + ExpectNoErrors(); + + ExpectFileContent("manifest", + "$tmpdir/bar.pb: " + "$tmpdir/foo.proto\\\n $tmpdir/bar.proto"); +} #endif // !_WIN32 TEST_F(CommandLineInterfaceTest, TestArgumentFile) { @@ -2518,12 +2543,12 @@ enum EncodeDecodeTestMode { PROTO_PATH, DESCRIPTOR_SET_IN }; class EncodeDecodeTest : public testing::TestWithParam { protected: - virtual void SetUp() { + void SetUp() override { WriteUnittestProtoDescriptorSet(); duped_stdin_ = dup(STDIN_FILENO); } - virtual void TearDown() { + void TearDown() override { dup2(duped_stdin_, STDIN_FILENO); close(duped_stdin_); } @@ -2755,6 +2780,8 @@ INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest, #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN +#include + } // namespace compiler } // namespace protobuf } // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc similarity index 94% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc index 60619f10..2619e604 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc @@ -46,8 +46,7 @@ #include #include -#include -#include +#include #include #include #include @@ -56,6 +55,7 @@ #include #include #include +#include #include #include @@ -69,13 +69,13 @@ namespace { class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, - const std::string& message) { + const std::string& message) override { strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -113,7 +113,7 @@ class MockGeneratorContext : public GeneratorContext { // implements GeneratorContext -------------------------------------- - virtual io::ZeroCopyOutputStream* Open(const std::string& filename) { + io::ZeroCopyOutputStream* Open(const std::string& filename) override { auto& map_slot = files_[filename]; map_slot.reset(new std::string); return new io::StringOutputStream(map_slot.get()); @@ -137,9 +137,9 @@ TEST(BootstrapTest, GeneratedFilesMatch) { // of the data to compare to. std::map vpath_map; std::map rpath_map; - rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] = + rpath_map["third_party/protobuf/test_messages_proto2"] = "net/proto2/z_generated_example/test_messages_proto2"; - rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] = + rpath_map["third_party/protobuf/test_messages_proto3"] = "net/proto2/z_generated_example/test_messages_proto3"; rpath_map["net/proto2/internal/proto2_weak"] = "net/proto2/z_generated_example/proto2_weak"; diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h index 97e848dc..1716ab20 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h @@ -1,106 +1,6 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ +#define GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Generates C++ code for a given .proto file. +#include -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ - -#include -#include - -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -// CodeGenerator implementation which generates a C++ source file and -// header. If you create your own protocol compiler binary and you want -// it to support C++ output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class PROTOC_EXPORT CppGenerator : public CodeGenerator { - public: - CppGenerator(); - ~CppGenerator(); - - enum class Runtime { - kGoogle3, // Use the internal google3 runtime. - kOpensource, // Use the open-source runtime. - - // Use the open-source runtime with google3 #include paths. We make these - // absolute to avoid ambiguity, so the runtime will be #included like: - // #include "third_party/protobuf/.../google/protobuf/message.h" - kOpensourceGoogle3 - }; - - void set_opensource_runtime(bool opensource) { - opensource_runtime_ = opensource; - } - - // If set to a non-empty string, generated code will do: - // #include "/google/protobuf/message.h" - // instead of: - // #include - // This has no effect if opensource_runtime = false. - void set_runtime_include_base(const std::string& base) { - runtime_include_base_ = base; - } - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* generator_context, - std::string* error) const override; - - uint64_t GetSupportedFeatures() const override { - // We don't fully support this yet, but this is needed to unblock the tests, - // and we will have full support before the experimental flag is removed. - return FEATURE_PROTO3_OPTIONAL; - } - - private: - bool opensource_runtime_ = true; - std::string runtime_include_base_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc deleted file mode 100644 index 810f240a..00000000 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc +++ /dev/null @@ -1,1303 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include -#include - -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -namespace { -using google::protobuf::internal::TcFieldData; -using google::protobuf::internal::WireFormat; -using google::protobuf::internal::WireFormatLite; - -std::vector GetOrderedFields( - const Descriptor* descriptor, const Options& options) { - std::vector ordered_fields; - for (auto field : FieldRange(descriptor)) { - if (!IsFieldStripped(field, options)) { - ordered_fields.push_back(field); - } - } - std::sort(ordered_fields.begin(), ordered_fields.end(), - [](const FieldDescriptor* a, const FieldDescriptor* b) { - return a->number() < b->number(); - }); - return ordered_fields; -} - -bool HasInternalAccessors(const FieldOptions::CType ctype) { - return ctype == FieldOptions::STRING || ctype == FieldOptions::CORD; -} - -int TagSize(uint32_t field_number) { - if (field_number < 16) return 1; - GOOGLE_CHECK_LT(field_number, (1 << 14)) - << "coded tag for " << field_number << " too big for uint16_t"; - return 2; -} - -const char* CodedTagType(int tag_size) { - return tag_size == 1 ? "uint8_t" : "uint16_t"; -} - -const char* TagType(const FieldDescriptor* field) { - return CodedTagType(TagSize(field->number())); -} - -std::string TcParserName(const Options& options) { - return StrCat("::", ProtobufNamespace(options), - "::internal::TcParser::"); -} - -std::string MessageTcParseFunctionName(const FieldDescriptor* field, - const Options& options) { - if (field->message_type()->field_count() == 0 || - !HasGeneratedMethods(field->message_type()->file(), options)) { - // For files with `option optimize_for = CODE_SIZE`, or which derive from - // `ZeroFieldsBase`, we need to call the `_InternalParse` function, because - // there is no generated tailcall function. For tailcall parsing, this is - // done by helpers in TcParser. - return StrCat(TcParserName(options), - (field->is_repeated() ? "Repeated" : "Singular"), - "ParseMessage<", - QualifiedClassName(field->message_type()), // - ", ", TagType(field), ">"); - } - // This matches macros in generated_message_tctable_impl.h: - return StrCat("PROTOBUF_TC_PARSE_", - (field->is_repeated() ? "REPEATED" : "SINGULAR"), - TagSize(field->number()), "(", - QualifiedClassName(field->message_type()), ")"); -} - -std::string FieldParseFunctionName(const FieldDescriptor* field, - const Options& options); - -} // namespace - -TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor, - const Options& options, - const std::vector& has_bit_indices, - MessageSCCAnalyzer* scc_analyzer) { - std::vector ordered_fields = - GetOrderedFields(descriptor, options); - - // The table size is rounded up to the nearest power of 2, clamping at 2^5. - // Note that this is a naive approach: a better approach should only consider - // table-eligible fields. We may also want to push rarely-encountered fields - // into the fallback, to make the table smaller. - table_size_log2 = ordered_fields.size() >= 16 ? 5 - : ordered_fields.size() >= 8 ? 4 - : ordered_fields.size() >= 4 ? 3 - : ordered_fields.size() >= 2 ? 2 - : 1; - const unsigned table_size = 1 << table_size_log2; - - // Construct info for each possible entry. Fields that do not use table-driven - // parsing will still have an entry that nominates the fallback function. - fast_path_fields.resize(table_size); - - for (const auto* field : ordered_fields) { - // Eagerly assume slow path. If we can handle this field on the fast path, - // we will pop its entry from `fallback_fields`. - fallback_fields.push_back(field); - - // Anything difficult slow path: - if (field->is_map()) continue; - if (field->real_containing_oneof()) continue; - if (field->options().weak()) continue; - if (IsImplicitWeakField(field, options, scc_analyzer)) continue; - if (IsLazy(field, options, scc_analyzer)) continue; - - // The largest tag that can be read by the tailcall parser is two bytes - // when varint-coded. This allows 14 bits for the numeric tag value: - // byte 0 byte 1 - // 1nnnnttt 0nnnnnnn - // ^^^^^^^ ^^^^^^^ - uint32_t tag = WireFormat::MakeTag(field); - if (tag >= 1 << 14) { - continue; - } else if (tag >= 1 << 7) { - tag = ((tag << 1) & 0x7F00) | 0x80 | (tag & 0x7F); - } - // The field index is determined by the low bits of the field number, where - // the table size determines the width of the mask. The largest table - // supported is 32 entries. The parse loop uses these bits directly, so that - // the dispatch does not require arithmetic: - // byte 0 byte 1 - // 1nnnnttt 0nnnnnnn - // ^^^^^ - // This means that any field number that does not fit in the lower 4 bits - // will always have the top bit of its table index asserted: - uint32_t idx = (tag >> 3) & (table_size - 1); - // If this entry in the table is already used, then this field will be - // handled by the generated fallback function. - if (!fast_path_fields[idx].func_name.empty()) continue; - - // Determine the hasbit mask for this field, if needed. (Note that fields - // without hasbits use different parse functions.) - int hasbit_idx; - if (HasHasbit(field)) { - hasbit_idx = has_bit_indices[field->index()]; - GOOGLE_CHECK_NE(-1, hasbit_idx) << field->DebugString(); - // The tailcall parser can only update the first 32 hasbits. If this - // field's has-bit is beyond that, then it will need to be handled by the - // fallback parse function. - if (hasbit_idx >= 32) continue; - } else { - // The tailcall parser only ever syncs 32 has-bits, so if there is no - // presence, set a bit that will not be used. - hasbit_idx = 63; - } - - // Determine the name of the fastpath parse function to use for this field. - std::string name; - - switch (field->type()) { - case FieldDescriptor::TYPE_MESSAGE: - name = MessageTcParseFunctionName(field, options); - break; - - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_DOUBLE: - case FieldDescriptor::TYPE_FLOAT: - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_BOOL: - name = FieldParseFunctionName(field, options); - break; - - case FieldDescriptor::TYPE_BYTES: - if (field->options().ctype() == FieldOptions::STRING && - field->default_value_string().empty() && - !IsStringInlined(field, options)) { - name = FieldParseFunctionName(field, options); - } - break; - - default: - break; - } - - if (name.empty()) { - continue; - } - // This field made it into the fast path, so remove it from the fallback - // fields and fill in the table entry. - fallback_fields.pop_back(); - fast_path_fields[idx].func_name = name; - fast_path_fields[idx].bits = TcFieldData(tag, hasbit_idx, 0); - fast_path_fields[idx].field = field; - } - - // If there are no fallback fields, and at most one extension range, the - // parser can use a generic fallback function. Otherwise, a message-specific - // fallback routine is needed. - use_generated_fallback = - !fallback_fields.empty() || descriptor->extension_range_count() > 1; -} - -ParseFunctionGenerator::ParseFunctionGenerator( - const Descriptor* descriptor, int max_has_bit_index, - const std::vector& has_bit_indices, - const std::vector& inlined_string_indices, const Options& options, - MessageSCCAnalyzer* scc_analyzer, - const std::map& vars) - : descriptor_(descriptor), - scc_analyzer_(scc_analyzer), - options_(options), - variables_(vars), - inlined_string_indices_(inlined_string_indices), - num_hasbits_(max_has_bit_index) { - if (should_generate_tctable()) { - tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_, - has_bit_indices, scc_analyzer)); - } - SetCommonVars(options_, &variables_); - SetUnknownFieldsVariable(descriptor_, options_, &variables_); - variables_["classname"] = ClassName(descriptor, false); -} - -void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { - Formatter format(printer, variables_); - if (should_generate_tctable()) { - auto declare_function = [&format](const char* name, - const std::string& guard) { - if (!guard.empty()) { - format.Outdent(); - format("#if $1$\n", guard); - format.Indent(); - } - format("static const char* $1$(PROTOBUF_TC_PARAM_DECL);\n", name); - if (!guard.empty()) { - format.Outdent(); - format("#endif // $1$\n", guard); - format.Indent(); - } - }; - if (should_generate_guarded_tctable()) { - format.Outdent(); - format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - format.Indent(); - } - format("// The Tct_* functions are internal to the protobuf runtime:\n"); - // These guards are defined in port_def.inc: - declare_function("Tct_ParseS1", "PROTOBUF_TC_STATIC_PARSE_SINGULAR1"); - declare_function("Tct_ParseS2", "PROTOBUF_TC_STATIC_PARSE_SINGULAR2"); - declare_function("Tct_ParseR1", "PROTOBUF_TC_STATIC_PARSE_REPEATED1"); - declare_function("Tct_ParseR2", "PROTOBUF_TC_STATIC_PARSE_REPEATED2"); - if (tc_table_info_->use_generated_fallback) { - format.Outdent(); - format( - " private:\n" - " "); - declare_function("Tct_ParseFallback", ""); - format(" public:\n"); - format.Indent(); - } - if (should_generate_guarded_tctable()) { - format.Outdent(); - format("#endif\n"); - format.Indent(); - } - } - format( - "const char* _InternalParse(const char* ptr, " - "::$proto_ns$::internal::ParseContext* ctx) final;\n"); -} - -void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { - Formatter format(printer, variables_); - bool need_parse_function = true; - if (descriptor_->options().message_set_wire_format()) { - // Special-case MessageSet. - need_parse_function = false; - format( - "const char* $classname$::_InternalParse(const char* ptr,\n" - " ::$proto_ns$::internal::ParseContext* ctx) {\n" - "$annotate_deserialize$" - " return _extensions_.ParseMessageSet(ptr, \n" - " internal_default_instance(), &_internal_metadata_, ctx);\n" - "}\n"); - } - if (!should_generate_tctable()) { - if (need_parse_function) { - GenerateLoopingParseFunction(format); - } - return; - } - if (should_generate_guarded_tctable()) { - format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); - } - if (need_parse_function) { - GenerateTailcallParseFunction(format); - } - if (tc_table_info_->use_generated_fallback) { - GenerateTailcallFallbackFunction(format); - } - GenerateTailcallFieldParseFunctions(format); - if (should_generate_guarded_tctable()) { - if (need_parse_function) { - format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); - GenerateLoopingParseFunction(format); - } - format("\n#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - } -} - -bool ParseFunctionGenerator::should_generate_tctable() const { - if (options_.tctable_mode == Options::kTCTableNever) { - return false; - } - return true; -} - -void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) { - GOOGLE_CHECK(should_generate_tctable()); - - // Generate an `_InternalParse` that starts the tail-calling loop. - format( - "const char* $classname$::_InternalParse(\n" - " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n" - "$annotate_deserialize$" - " ptr = ::$proto_ns$::internal::TcParser::ParseLoop(\n" - " this, ptr, ctx, &_table_.header);\n"); - format( - " return ptr;\n" - "}\n\n"); -} - -void ParseFunctionGenerator::GenerateTailcallFallbackFunction( - Formatter& format) { - GOOGLE_CHECK(should_generate_tctable()); - format( - "const char* $classname$::Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL) {\n" - "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr\n"); - format.Indent(); - format("auto* typed_msg = static_cast<$classname$*>(msg);\n"); - - if (num_hasbits_ > 0) { - // Sync hasbits - format("typed_msg->_has_bits_[0] = hasbits;\n"); - } - - format.Set("msg", "typed_msg->"); - format.Set("this", "typed_msg"); - format.Set("has_bits", "typed_msg->_has_bits_"); - format.Set("next_tag", "goto next_tag"); - GenerateParseIterationBody(format, descriptor_, - tc_table_info_->fallback_fields); - - format.Outdent(); - format( - "next_tag:\n" - "message_done:\n" - " return ptr;\n" - "#undef CHK_\n" - "}\n"); -} - -void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions( - Formatter& format) { - GOOGLE_CHECK(should_generate_tctable()); - // There are four cases where a tailcall target are needed for messages: - // {singular, repeated} x {1, 2}-byte tag - struct { - const char* type; - int size; - } const kTagLayouts[] = { - {"uint8_t", 1}, - {"uint16_t", 2}, - }; - // Singular: - for (const auto& layout : kTagLayouts) { - // Guard macros are defined in port_def.inc. - format( - "#if PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n" - "const char* $classname$::Tct_ParseS$1$(PROTOBUF_TC_PARAM_DECL) {\n" - " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0))\n" - " PROTOBUF_MUSTTAIL " - "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" - " ptr += $1$;\n" - " hasbits |= (uint64_t{1} << data.hasbit_idx());\n" - " ::$proto_ns$::internal::TcParser::SyncHasbits" - "(msg, hasbits, table);\n" - " auto& field = ::$proto_ns$::internal::TcParser::" - "RefAt<$classtype$*>(msg, data.offset());\n" - " if (field == nullptr)\n" - " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n" - " return ctx->ParseMessage(field, ptr);\n" - "}\n" - "#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n", - layout.size, layout.type); - } - // Repeated: - for (const auto& layout : kTagLayouts) { - // Guard macros are defined in port_def.inc. - format( - "#if PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n" - "const char* $classname$::Tct_ParseR$1$(PROTOBUF_TC_PARAM_DECL) {\n" - " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0)) {\n" - " PROTOBUF_MUSTTAIL " - "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" - " }\n" - " ptr += $1$;\n" - " auto& field = ::$proto_ns$::internal::TcParser::RefAt<" - "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n" - " ::$proto_ns$::internal::TcParser::SyncHasbits" - "(msg, hasbits, table);\n" - " ptr = ctx->ParseMessage(field.Add(), ptr);\n" - " return ptr;\n" - "}\n" - "#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n", - layout.size, layout.type); - } -} - -void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { - if (!should_generate_tctable()) { - return; - } - Formatter format(printer, variables_); - if (should_generate_guarded_tctable()) { - format.Outdent(); - format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - format.Indent(); - } - format( - "static const ::$proto_ns$::internal::TcParseTable<$1$>\n" - " _table_;\n", - tc_table_info_->table_size_log2); - if (should_generate_guarded_tctable()) { - format.Outdent(); - format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - format.Indent(); - } -} - -void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) { - if (!should_generate_tctable()) { - return; - } - Formatter format(printer, variables_); - if (should_generate_guarded_tctable()) { - format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - } - GenerateTailCallTable(format); - if (should_generate_guarded_tctable()) { - format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); - } -} - -void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) { - format( - "const char* $classname$::_InternalParse(const char* ptr, " - "::$proto_ns$::internal::ParseContext* ctx) {\n" - "$annotate_deserialize$" - "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n"); - format.Indent(); - format.Set("msg", ""); - format.Set("this", "this"); - int hasbits_size = 0; - if (num_hasbits_ > 0) { - hasbits_size = (num_hasbits_ + 31) / 32; - } - // For now only optimize small hasbits. - if (hasbits_size != 1) hasbits_size = 0; - if (hasbits_size) { - format("_Internal::HasBits has_bits{};\n"); - format.Set("has_bits", "has_bits"); - } else { - format.Set("has_bits", "_has_bits_"); - } - format.Set("next_tag", "continue"); - format("while (!ctx->Done(&ptr)) {\n"); - format.Indent(); - - GenerateParseIterationBody(format, descriptor_, - GetOrderedFields(descriptor_, options_)); - - format.Outdent(); - format("} // while\n"); - - format.Outdent(); - format("message_done:\n"); - if (hasbits_size) format(" _has_bits_.Or(has_bits);\n"); - - format( - " return ptr;\n" - "failure:\n" - " ptr = nullptr;\n" - " goto message_done;\n" - "#undef CHK_\n" - "}\n"); -} - -void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { - GOOGLE_CHECK(should_generate_tctable()); - // All entries without a fast-path parsing function need a fallback. - std::string fallback; - if (tc_table_info_->use_generated_fallback) { - fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; - } else { - fallback = TcParserName(options_) + "GenericFallback"; - if (GetOptimizeFor(descriptor_->file(), options_) == - FileOptions::LITE_RUNTIME) { - fallback += "Lite"; - } - } - - // For simplicity and speed, the table is not covering all proto - // configurations. This model uses a fallback to cover all situations that - // the table can't accommodate, together with unknown fields or extensions. - // These are number of fields over 32, fields with 3 or more tag bytes, - // maps, weak fields, lazy, more than 1 extension range. In the cases - // the table is sufficient we can use a generic routine, that just handles - // unknown fields and potentially an extension range. - format( - "const ::$proto_ns$::internal::TcParseTable<$1$>\n" - " $classname$::_table_ = {\n", - tc_table_info_->table_size_log2); - { - auto table_scope = format.ScopedIndent(); - format("{\n"); - { - auto header_scope = format.ScopedIndent(); - if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classname$, _has_bits_),\n"); - } else { - format("0, // no _has_bits_\n"); - } - if (descriptor_->extension_range_count() == 1) { - format( - "PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n" - "$1$, $2$, // extension_range_{low,high}\n", - descriptor_->extension_range(0)->start, - descriptor_->extension_range(0)->end); - } else { - format("0, 0, 0, // no _extensions_\n"); - } - format( - "$1$, 0, $2$, // fast_idx_mask, reserved, num_fields\n" - "&$3$._instance,\n" - "$4$ // fallback\n", - (((1 << tc_table_info_->table_size_log2) - 1) << 3), - descriptor_->field_count(), - DefaultInstanceName(descriptor_, options_), fallback); - } - format("}, {\n"); - { - auto fast_scope = format.ScopedIndent(); - GenerateFastFieldEntries(format, fallback); - } - format("},\n"); // entries[] - } - format("};\n\n"); // _table_ -} - -void ParseFunctionGenerator::GenerateFastFieldEntries( - Formatter& format, const std::string& fallback) { - for (const auto& info : tc_table_info_->fast_path_fields) { - if (info.field != nullptr) { - PrintFieldComment(format, info.field); - } - format("{$1$, ", info.func_name.empty() ? fallback : info.func_name); - if (info.bits.data) { - GOOGLE_DCHECK_NE(nullptr, info.field); - format( - "{$1$, $2$, " - "static_cast(PROTOBUF_FIELD_OFFSET($classname$, $3$_))}", - info.bits.coded_tag(), info.bits.hasbit_idx(), FieldName(info.field)); - } else { - format("{}"); - } - format("},\n"); - } -} - -void ParseFunctionGenerator::GenerateArenaString(Formatter& format, - const FieldDescriptor* field) { - if (HasHasbit(field)) { - format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); - } - std::string default_string = - field->default_value_string().empty() - ? "::" + ProtobufNamespace(options_) + - "::internal::GetEmptyStringAlreadyInited()" - : QualifiedClassName(field->containing_type(), options_) + - "::" + MakeDefaultName(field) + ".get()"; - format( - "if (arena != nullptr) {\n" - " ptr = ctx->ReadArenaString(ptr, &$msg$$name$_, arena"); - if (IsStringInlined(field, options_)) { - GOOGLE_DCHECK(!inlined_string_indices_.empty()); - int inlined_string_index = inlined_string_indices_[field->index()]; - GOOGLE_DCHECK_GE(inlined_string_index, 0); - format( - ", $msg$_internal_$name$_donated()" - ", &$msg$_inlined_string_donated_[$1$]" - ", ~0x$2$u", - inlined_string_index / 32, - strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8)); - } else { - GOOGLE_DCHECK(field->default_value_string().empty()); - } - format( - ");\n" - "} else {\n" - " ptr = ::$proto_ns$::internal::InlineGreedyStringParser(" - "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n" - "}\n" - "const std::string* str = &$msg$$name$_.Get(); (void)str;\n", - default_string); -} - -void ParseFunctionGenerator::GenerateStrings(Formatter& format, - const FieldDescriptor* field, - bool check_utf8) { - FieldOptions::CType ctype = FieldOptions::STRING; - if (!options_.opensource_runtime) { - // Open source doesn't support other ctypes; - ctype = field->options().ctype(); - } - if (!field->is_repeated() && !options_.opensource_runtime && - GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && - // For now only use arena string for strings with empty defaults. - field->default_value_string().empty() && - !field->real_containing_oneof() && ctype == FieldOptions::STRING) { - GenerateArenaString(format, field); - } else { - std::string parser_name; - switch (ctype) { - case FieldOptions::STRING: - parser_name = "GreedyStringParser"; - break; - case FieldOptions::CORD: - parser_name = "CordParser"; - break; - case FieldOptions::STRING_PIECE: - parser_name = "StringPieceParser"; - break; - } - format( - "auto str = $msg$$1$$2$_$name$();\n" - "ptr = ::$proto_ns$::internal::Inline$3$(str, ptr, ctx);\n", - HasInternalAccessors(ctype) ? "_internal_" : "", - field->is_repeated() && !field->is_packable() ? "add" : "mutable", - parser_name); - } - if (!check_utf8) return; // return if this is a bytes field - auto level = GetUtf8CheckMode(field, options_); - switch (level) { - case Utf8CheckMode::kNone: - return; - case Utf8CheckMode::kVerify: - format("#ifndef NDEBUG\n"); - break; - case Utf8CheckMode::kStrict: - format("CHK_("); - break; - } - std::string field_name; - field_name = "nullptr"; - if (HasDescriptorMethods(field->file(), options_)) { - field_name = StrCat("\"", field->full_name(), "\""); - } - format("::$proto_ns$::internal::VerifyUTF8(str, $1$)", field_name); - switch (level) { - case Utf8CheckMode::kNone: - return; - case Utf8CheckMode::kVerify: - format( - ";\n" - "#endif // !NDEBUG\n"); - break; - case Utf8CheckMode::kStrict: - format(");\n"); - break; - } -} - -void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, - const FieldDescriptor* field) { - if (field->is_packable()) { - if (field->type() == FieldDescriptor::TYPE_ENUM && - !HasPreservingUnknownEnumSemantics(field)) { - std::string enum_type = QualifiedClassName(field->enum_type(), options_); - format( - "ptr = " - "::$proto_ns$::internal::Packed$1$Parser<$unknown_fields_type$>(" - "$msg$_internal_mutable_$name$(), ptr, ctx, $2$_IsValid, " - "&$msg$_internal_metadata_, $3$);\n", - DeclaredTypeMethodName(field->type()), enum_type, field->number()); - } else { - format( - "ptr = ::$proto_ns$::internal::Packed$1$Parser(" - "$msg$_internal_mutable_$name$(), ptr, ctx);\n", - DeclaredTypeMethodName(field->type())); - } - } else { - auto field_type = field->type(); - switch (field_type) { - case FieldDescriptor::TYPE_STRING: - GenerateStrings(format, field, true /* utf8 */); - break; - case FieldDescriptor::TYPE_BYTES: - GenerateStrings(format, field, false /* utf8 */); - break; - case FieldDescriptor::TYPE_MESSAGE: { - if (field->is_map()) { - const FieldDescriptor* val = - field->message_type()->FindFieldByName("value"); - GOOGLE_CHECK(val); - if (val->type() == FieldDescriptor::TYPE_ENUM && - !HasPreservingUnknownEnumSemantics(field)) { - format( - "auto object = " - "::$proto_ns$::internal::InitEnumParseWrapper<" - "$unknown_fields_type$>(&$msg$$name$_, $1$_IsValid, " - "$2$, &$msg$_internal_metadata_);\n" - "ptr = ctx->ParseMessage(&object, ptr);\n", - QualifiedClassName(val->enum_type(), options_), - field->number()); - } else { - format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); - } - } else if (IsLazy(field, options_, scc_analyzer_)) { - if (field->real_containing_oneof()) { - format( - "if (!$msg$_internal_has_$name$()) {\n" - " $msg$clear_$1$();\n" - " $msg$$1$_.$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" - " ::$proto_ns$::internal::LazyField>(" - "$msg$GetArenaForAllocation());\n" - " $msg$set_has_$name$();\n" - "}\n" - "auto* lazy_field = $msg$$1$_.$name$_;\n", - field->containing_oneof()->name()); - } else if (HasHasbit(field)) { - format( - "_Internal::set_has_$name$(&$has_bits$);\n" - "auto* lazy_field = &$msg$$name$_;\n"); - } else { - format("auto* lazy_field = &$msg$$name$_;\n"); - } - format( - "::$proto_ns$::internal::LazyFieldParseHelper<\n" - " ::$proto_ns$::internal::LazyField> parse_helper(\n" - " $1$::default_instance(),\n" - " $msg$GetArenaForAllocation(), lazy_field);\n" - "ptr = ctx->ParseMessage(&parse_helper, ptr);\n", - FieldMessageTypeName(field, options_)); - } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) { - if (!field->is_repeated()) { - format( - "ptr = ctx->ParseMessage(_Internal::mutable_$name$($this$), " - "ptr);\n"); - } else { - format( - "ptr = ctx->ParseMessage($msg$$name$_.AddWeak(" - "reinterpret_cast($1$ptr_)" - "), ptr);\n", - QualifiedDefaultInstanceName(field->message_type(), options_)); - } - } else if (IsWeak(field, options_)) { - format( - "{\n" - " auto* default_ = &reinterpret_cast($1$);\n" - " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage(" - "$2$, default_), ptr);\n" - "}\n", - QualifiedDefaultInstanceName(field->message_type(), options_), - field->number()); - } else { - format( - "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), " - "ptr);\n"); - } - break; - } - default: - GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype " - << " filed type is " << field->type(); - } - } -} - -static bool ShouldRepeat(const FieldDescriptor* descriptor, - WireFormatLite::WireType wiretype) { - constexpr int kMaxTwoByteFieldNumber = 16 * 128; - return descriptor->number() < kMaxTwoByteFieldNumber && - descriptor->is_repeated() && - (!descriptor->is_packable() || - wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); -} - -void ParseFunctionGenerator::GenerateFieldBody( - Formatter& format, WireFormatLite::WireType wiretype, - const FieldDescriptor* field) { - Formatter::SaveState formatter_state(&format); - format.AddMap( - {{"name", FieldName(field)}, - {"primitive_type", PrimitiveTypeName(options_, field->cpp_type())}}); - if (field->is_repeated()) { - format.AddMap({{"put_field", StrCat("add_", FieldName(field))}, - {"mutable_field", StrCat("add_", FieldName(field))}}); - } else { - format.AddMap( - {{"put_field", StrCat("set_", FieldName(field))}, - {"mutable_field", StrCat("mutable_", FieldName(field))}}); - } - uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); - switch (wiretype) { - case WireFormatLite::WIRETYPE_VARINT: { - std::string type = PrimitiveTypeName(options_, field->cpp_type()); - if (field->type() == FieldDescriptor::TYPE_ENUM) { - format.Set("enum_type", - QualifiedClassName(field->enum_type(), options_)); - format( - "$uint64$ val = ::$proto_ns$::internal::ReadVarint64(&ptr);\n" - "CHK_(ptr);\n"); - if (!HasPreservingUnknownEnumSemantics(field)) { - format("if (PROTOBUF_PREDICT_TRUE($enum_type$_IsValid(val))) {\n"); - format.Indent(); - } - format("$msg$_internal_$put_field$(static_cast<$enum_type$>(val));\n"); - if (!HasPreservingUnknownEnumSemantics(field)) { - format.Outdent(); - format( - "} else {\n" - " ::$proto_ns$::internal::WriteVarint(" - "$1$, val, $msg$mutable_unknown_fields());\n" - "}\n", - field->number()); - } - } else { - std::string size = (field->type() == FieldDescriptor::TYPE_INT32 || - field->type() == FieldDescriptor::TYPE_SINT32 || - field->type() == FieldDescriptor::TYPE_UINT32) - ? "32" - : "64"; - std::string zigzag; - if ((field->type() == FieldDescriptor::TYPE_SINT32 || - field->type() == FieldDescriptor::TYPE_SINT64)) { - zigzag = "ZigZag"; - } - if (field->is_repeated() || field->real_containing_oneof()) { - format( - "$msg$_internal_$put_field$(" - "::$proto_ns$::internal::ReadVarint$1$$2$(&ptr));\n" - "CHK_(ptr);\n", - zigzag, size); - } else { - if (HasHasbit(field)) { - format("_Internal::set_has_$name$(&$has_bits$);\n"); - } - format( - "$msg$$name$_ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n" - "CHK_(ptr);\n", - zigzag, size); - } - } - break; - } - case WireFormatLite::WIRETYPE_FIXED32: - case WireFormatLite::WIRETYPE_FIXED64: { - if (field->is_repeated() || field->real_containing_oneof()) { - format( - "$msg$_internal_$put_field$(" - "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr));\n" - "ptr += sizeof($primitive_type$);\n"); - } else { - if (HasHasbit(field)) { - format("_Internal::set_has_$name$(&$has_bits$);\n"); - } - format( - "$msg$$name$_ = " - "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n" - "ptr += sizeof($primitive_type$);\n"); - } - break; - } - case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { - GenerateLengthDelim(format, field); - format("CHK_(ptr);\n"); - break; - } - case WireFormatLite::WIRETYPE_START_GROUP: { - format( - "ptr = ctx->ParseGroup($msg$_internal_$mutable_field$(), ptr, $1$);\n" - "CHK_(ptr);\n", - tag); - break; - } - case WireFormatLite::WIRETYPE_END_GROUP: { - GOOGLE_LOG(FATAL) << "Can't have end group field\n"; - break; - } - } // switch (wire_type) -} - -// Returns the tag for this field and in case of repeated packable fields, -// sets a fallback tag in fallback_tag_ptr. -static uint32_t ExpectedTag(const FieldDescriptor* field, - uint32_t* fallback_tag_ptr) { - uint32_t expected_tag; - if (field->is_packable()) { - auto expected_wiretype = WireFormat::WireTypeForFieldType(field->type()); - expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype); - GOOGLE_CHECK(expected_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - auto fallback_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - uint32_t fallback_tag = - WireFormatLite::MakeTag(field->number(), fallback_wiretype); - - if (field->is_packed()) std::swap(expected_tag, fallback_tag); - *fallback_tag_ptr = fallback_tag; - } else { - auto expected_wiretype = WireFormat::WireTypeForField(field); - expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype); - } - return expected_tag; -} - -// These variables are used by the generated parse iteration, and must already -// be defined in the generated code: -// - `const char* ptr`: the input buffer. -// - `ParseContext* ctx`: the associated context for `ptr`. -// - implicit `this`: i.e., we must be in a non-static member function. -// -// The macro `CHK_(x)` must be defined. It should return an error condition if -// the macro parameter is false. -// -// Whenever an END_GROUP tag was read, or tag 0 was read, the generated code -// branches to the label `message_done`. -// -// These formatter variables are used: -// - `next_tag`: a single statement to begin parsing the next tag. -// -// At the end of the generated code, the enclosing function should proceed to -// parse the next tag in the stream. -void ParseFunctionGenerator::GenerateParseIterationBody( - Formatter& format, const Descriptor* descriptor, - const std::vector& ordered_fields) { - format( - "$uint32$ tag;\n" - "ptr = ::$proto_ns$::internal::ReadTag(ptr, &tag);\n"); - - if (!ordered_fields.empty()) { - GenerateFieldSwitch(format, ordered_fields); - // Each field `case` only considers field number. Field numbers that are - // not defined in the message, or tags with an incompatible wire type, are - // considered "unusual" cases. They will be handled by the logic below. - format.Outdent(); - format("handle_unusual:\n"); - format.Indent(); - } - - // Unusual/extension/unknown case: - format( - "if ((tag == 0) || ((tag & 7) == 4)) {\n" - " CHK_(ptr);\n" - " ctx->SetLastTag(tag);\n" - " goto message_done;\n" - "}\n"); - if (IsMapEntryMessage(descriptor)) { - format("$next_tag$;\n"); - } else { - if (descriptor->extension_range_count() > 0) { - format("if ("); - for (int i = 0; i < descriptor->extension_range_count(); i++) { - const Descriptor::ExtensionRange* range = - descriptor->extension_range(i); - if (i > 0) format(" ||\n "); - - uint32_t start_tag = WireFormatLite::MakeTag( - range->start, static_cast(0)); - uint32_t end_tag = WireFormatLite::MakeTag( - range->end, static_cast(0)); - - if (range->end > FieldDescriptor::kMaxNumber) { - format("($1$u <= tag)", start_tag); - } else { - format("($1$u <= tag && tag < $2$u)", start_tag, end_tag); - } - } - format( - ") {\n" - " ptr = $msg$_extensions_.ParseField(tag, ptr, " - "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n" - " CHK_(ptr != nullptr);\n" - " $next_tag$;\n" - "}\n"); - } - format( - "ptr = UnknownFieldParse(\n" - " tag,\n" - " $msg$_internal_metadata_.mutable_unknown_fields<" - "$unknown_fields_type$>(),\n" - " ptr, ctx);\n" - "CHK_(ptr != nullptr);\n"); - } -} - -void ParseFunctionGenerator::GenerateFieldSwitch( - Formatter& format, - const std::vector& ordered_fields) { - format("switch (tag >> 3) {\n"); - format.Indent(); - - for (const auto* field : ordered_fields) { - PrintFieldComment(format, field); - format("case $1$:\n", field->number()); - format.Indent(); - uint32_t fallback_tag = 0; - uint32_t expected_tag = ExpectedTag(field, &fallback_tag); - format("if (PROTOBUF_PREDICT_TRUE(static_cast<$uint8$>(tag) == $1$)) {\n", - expected_tag & 0xFF); - format.Indent(); - auto wiretype = WireFormatLite::GetTagWireType(expected_tag); - uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); - int tag_size = io::CodedOutputStream::VarintSize32(tag); - bool is_repeat = ShouldRepeat(field, wiretype); - if (is_repeat) { - format( - "ptr -= $1$;\n" - "do {\n" - " ptr += $1$;\n", - tag_size); - format.Indent(); - } - GenerateFieldBody(format, wiretype, field); - if (is_repeat) { - format.Outdent(); - format( - " if (!ctx->DataAvailable(ptr)) break;\n" - "} while (::$proto_ns$::internal::ExpectTag<$1$>(ptr));\n", - tag); - } - format.Outdent(); - if (fallback_tag) { - format("} else if (static_cast<$uint8$>(tag) == $1$) {\n", - fallback_tag & 0xFF); - format.Indent(); - GenerateFieldBody(format, WireFormatLite::GetTagWireType(fallback_tag), - field); - format.Outdent(); - } - format( - "} else\n" - " goto handle_unusual;\n" - "$next_tag$;\n"); - format.Outdent(); - } // for loop over ordered fields - - format( - "default:\n" - " goto handle_unusual;\n"); - format.Outdent(); - format("} // switch\n"); -} - -namespace { - -std::string FieldParseFunctionName(const FieldDescriptor* field, - const Options& options) { - ParseCardinality card = // - field->is_packed() ? ParseCardinality::kPacked - : field->is_repeated() ? ParseCardinality::kRepeated - : field->real_containing_oneof() ? ParseCardinality::kOneof - : ParseCardinality::kSingular; - - TypeFormat type_format; - switch (field->type()) { - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_DOUBLE: - type_format = TypeFormat::kFixed64; - break; - - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_FLOAT: - type_format = TypeFormat::kFixed32; - break; - - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - type_format = TypeFormat::kVar64; - break; - - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT32: - type_format = TypeFormat::kVar32; - break; - - case FieldDescriptor::TYPE_SINT64: - type_format = TypeFormat::kSInt64; - break; - - case FieldDescriptor::TYPE_SINT32: - type_format = TypeFormat::kSInt32; - break; - - case FieldDescriptor::TYPE_BOOL: - type_format = TypeFormat::kBool; - break; - - case FieldDescriptor::TYPE_BYTES: - type_format = TypeFormat::kBytes; - break; - - case FieldDescriptor::TYPE_STRING: - switch (GetUtf8CheckMode(field, options)) { - case Utf8CheckMode::kNone: - type_format = TypeFormat::kBytes; - break; - case Utf8CheckMode::kStrict: - type_format = TypeFormat::kString; - break; - case Utf8CheckMode::kVerify: - type_format = TypeFormat::kStringValidateOnly; - break; - default: - GOOGLE_LOG(DFATAL) << "Mode not handled: " - << static_cast(GetUtf8CheckMode(field, options)); - return ""; - } - break; - - default: - GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString(); - return ""; - } - - return "::" + ProtobufNamespace(options) + "::internal::TcParser::" + - GetTailCallFieldHandlerName(card, type_format, - TagSize(field->number()), options); -} - -} // namespace - -std::string GetTailCallFieldHandlerName(ParseCardinality card, - TypeFormat type_format, - int tag_length_bytes, - const Options& options) { - std::string name; - - // The field implementation functions are prefixed by cardinality: - // `Singular` for optional or implicit fields. - // `Repeated` for non-packed repeated. - // `Packed` for packed repeated. - switch (card) { - case ParseCardinality::kSingular: - name.append("Singular"); - break; - case ParseCardinality::kOneof: - name.append("Oneof"); - break; - case ParseCardinality::kRepeated: - name.append("Repeated"); - break; - case ParseCardinality::kPacked: - name.append("Packed"); - break; - } - - // Next in the function name is the TypeFormat-specific name. - switch (type_format) { - case TypeFormat::kFixed64: - case TypeFormat::kFixed32: - name.append("Fixed"); - break; - - case TypeFormat::kVar64: - case TypeFormat::kVar32: - case TypeFormat::kSInt64: - case TypeFormat::kSInt32: - case TypeFormat::kBool: - name.append("Varint"); - break; - - case TypeFormat::kBytes: - case TypeFormat::kString: - case TypeFormat::kStringValidateOnly: - name.append("String"); - break; - - default: - break; - } - - name.append("<"); - - // Determine the numeric layout type for the parser to use, independent of - // the specific parsing logic used. - switch (type_format) { - case TypeFormat::kVar64: - case TypeFormat::kFixed64: - name.append("uint64_t, "); - break; - - case TypeFormat::kSInt64: - name.append("int64_t, "); - break; - - case TypeFormat::kVar32: - case TypeFormat::kFixed32: - name.append("uint32_t, "); - break; - - case TypeFormat::kSInt32: - name.append("int32_t, "); - break; - - case TypeFormat::kBool: - name.append("bool, "); - break; - - default: - break; - } - - name.append(CodedTagType(tag_length_bytes)); - - switch (type_format) { - case TypeFormat::kVar64: - case TypeFormat::kVar32: - case TypeFormat::kBool: - StrAppend(&name, ", ", TcParserName(options), "kNoConversion"); - break; - - case TypeFormat::kSInt64: - case TypeFormat::kSInt32: - StrAppend(&name, ", ", TcParserName(options), "kZigZag"); - break; - - case TypeFormat::kBytes: - StrAppend(&name, ", ", TcParserName(options), "kNoUtf8"); - break; - - case TypeFormat::kString: - StrAppend(&name, ", ", TcParserName(options), "kUtf8"); - break; - - case TypeFormat::kStringValidateOnly: - StrAppend(&name, ", ", TcParserName(options), "kUtf8ValidateOnly"); - break; - - default: - break; - } - - name.append(">"); - return name; -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum.cc similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/enum.cc index 6ae5cf42..8124369c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum.cc @@ -32,16 +32,16 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include -#include -#include #include #include +#include +#include namespace google { namespace protobuf { @@ -88,7 +88,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, variables_["nested_name"] = descriptor_->name(); variables_["resolved_name"] = ResolveKeyword(descriptor_->name()); variables_["prefix"] = - (descriptor_->containing_type() == NULL) ? "" : classname_ + "_"; + (descriptor_->containing_type() == nullptr) ? "" : classname_ + "_"; } EnumGenerator::~EnumGenerator() {} @@ -405,7 +405,7 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { descriptor_->value_count()); } - if (descriptor_->containing_type() != NULL) { + if (descriptor_->containing_type() != nullptr) { std::string parent = ClassName(descriptor_->containing_type(), false); // Before C++17, we must define the static constants which were // declared in the header, to give the linker a place to put them. diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/enum.h index 3687f04c..610d4fc7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum.h @@ -38,8 +38,9 @@ #include #include #include -#include + #include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.cc similarity index 77% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.cc index 70311dde..8ffb699e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.cc @@ -32,11 +32,13 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include -#include +#include + #include #include #include +#include +#include namespace google { namespace protobuf { @@ -53,6 +55,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options); (*variables)["default"] = Int32ToString(default_value->number()); (*variables)["full_name"] = descriptor->full_name(); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + bool cold = ShouldSplit(descriptor, options); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor, cold); } } // namespace @@ -90,7 +96,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$() const {\n" - " return static_cast< $type$ >($name$_);\n" + " return static_cast< $type$ >($field$);\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -103,9 +109,10 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( } format( " $set_hasbit$\n" - " $name$_ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" + "$maybe_prepare_split_message$" " _internal_set_$name$(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -114,28 +121,23 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions( void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("_internal_set_$name$(from._internal_$name$());\n"); + format("_this->_internal_set_$name$(from._internal_$name$());\n"); } void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); -} - -void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("swap($field$, other->$field$);\n"); } void EnumFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = from.$name$_;\n"); + format("_this->$field$ = from.$field$;\n"); } void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -143,7 +145,7 @@ void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); format( "target = stream->EnsureSpace(target);\n" - "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n" + "target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" " $number$, this->_internal_$name$(), target);\n"); } @@ -151,15 +153,29 @@ void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { Formatter format(printer, variables_); format( "total_size += $tag_size$ +\n" - " " - "::$proto_ns$::internal::WireFormatLite::EnumSize(this->_internal_$name$(" - "));\n"); + " ::_pbi::WireFormatLite::EnumSize(this->_internal_$name$());\n"); } -void EnumFieldGenerator::GenerateConstinitInitializer( +void EnumFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_($default$)\n"); + format("/*decltype($field$)*/$default$"); +} + +void EnumFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format("decltype(Impl_::Split::$name$_){$default$}"); + return; + } + format("decltype($field$){$default$}"); +} + +void EnumFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){}"); } // =================================================================== @@ -178,7 +194,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline $type$ $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return static_cast< $type$ >($field_member$);\n" + " return static_cast< $type$ >($field$);\n" " }\n" " return static_cast< $type$ >($default$);\n" "}\n" @@ -196,7 +212,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( " clear_$oneof_name$();\n" " set_has_$name$();\n" " }\n" - " $field_member$ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" " _internal_set_$name$(value);\n" @@ -207,7 +223,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions( void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$field_member$ = $default$;\n"); + format("$field$ = $default$;\n"); } void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { @@ -217,7 +233,7 @@ void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { void EnumOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); + format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n"); } // =================================================================== @@ -236,7 +252,7 @@ void RepeatedEnumFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField $name$_;\n"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -265,7 +281,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$(int index) const {\n" - " return static_cast< $type$ >($name$_.Get(index));\n" + " return static_cast< $type$ >($field$.Get(index));\n" "}\n" "inline $type$ $classname$::$name$(int index) const {\n" "$annotate_get$" @@ -277,7 +293,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( format(" assert($type$_IsValid(value));\n"); } format( - " $name$_.Set(index, value);\n" + " $field$.Set(index, value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" @@ -286,7 +302,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( format(" assert($type$_IsValid(value));\n"); } format( - " $name$_.Add(value);\n" + " $field$.Add(value);\n" "}\n" "inline void $classname$::add_$name$($type$ value) {\n" " _internal_add_$name$(value);\n" @@ -297,11 +313,11 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( "$classname$::$name$() const {\n" "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField*\n" "$classname$::_internal_mutable_$name$() {\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField*\n" "$classname$::mutable_$name$() {\n" @@ -314,19 +330,19 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedEnumFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedEnumFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("_this->$field$.MergeFrom(from.$field$);\n"); } void RepeatedEnumFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedEnumFieldGenerator::GenerateConstructorCode( @@ -334,6 +350,12 @@ void RepeatedEnumFieldGenerator::GenerateConstructorCode( // Not needed for repeated fields. } +void RepeatedEnumFieldGenerator::GenerateDestructorCode( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("$field$.~RepeatedField();\n"); +} + void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { Formatter format(printer, variables_); @@ -342,17 +364,17 @@ void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->WriteEnumPacked(\n" - " $number$, $name$_, byte_size, target);\n" + " $number$, $field$, byte_size, target);\n" " }\n" "}\n"); } else { format( "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n" " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n" + " target = ::_pbi::WireFormatLite::WriteEnumToArray(\n" " $number$, this->_internal_$name$(i), target);\n" "}\n"); } @@ -368,7 +390,7 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { format.Indent(); format( "for (unsigned int i = 0; i < count; i++) {\n" - " data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n" + " data_size += ::_pbi::WireFormatLite::EnumSize(\n" " this->_internal_$name$(static_cast(i)));\n" "}\n"); @@ -376,11 +398,11 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { format( "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n" - " static_cast<$int32$>(data_size));\n" + " " + "::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" "}\n" - "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n" - "_$name$_cached_byte_size_.store(cached_size,\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n" "total_size += data_size;\n"); } else { @@ -390,13 +412,36 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { format("}\n"); } -void RepeatedEnumFieldGenerator::GenerateConstinitInitializer( +void RepeatedEnumFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_()"); + format("/*decltype($field$)*/{}"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); + } +} + +void RepeatedEnumFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){arena}"); + if (descriptor_->is_packed() && + HasGeneratedMethods(descriptor_->file(), options_)) { + // std::atomic has no copy constructor, which prevents explicit aggregate + // initialization pre-C++17. + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); + } +} + +void RepeatedEnumFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){from.$field$}"); + if (descriptor_->is_packed() && + HasGeneratedMethods(descriptor_->file(), options_)) { + // std::atomic has no copy constructor. + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.h similarity index 85% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.h index e65ec0f5..61bae855 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/enum_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { @@ -47,7 +48,7 @@ namespace cpp { class EnumFieldGenerator : public FieldGenerator { public: EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~EnumFieldGenerator(); + ~EnumFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -56,12 +57,15 @@ class EnumFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); @@ -71,7 +75,7 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator { public: EnumOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~EnumOneofFieldGenerator(); + ~EnumOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -87,7 +91,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { public: RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedEnumFieldGenerator(); + ~RepeatedEnumFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -97,11 +101,17 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; - void GenerateCopyConstructorCode(io::Printer* printer) const override {} + void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override { + GOOGLE_CHECK(!ShouldSplit(descriptor_, options_)); + } + void GenerateDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/extension.cc similarity index 91% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/extension.cc index 8604da5f..950ed9e7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/extension.cc @@ -32,12 +32,14 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include + #include -#include -#include + #include #include +#include +#include namespace google { namespace protobuf { @@ -76,6 +78,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, break; } SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(descriptor_->containing_type(), &variables_); variables_["extendee"] = QualifiedClassName(descriptor_->containing_type(), options_); variables_["type_traits"] = type_traits_; @@ -91,6 +94,19 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, variables_["scope"] = scope; variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = StrCat(descriptor_->number()); + + bool add_verify_fn = + // Only verify msgs. + descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + // Options say to verify. + ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && + ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_); + + variables_["verify_fn"] = + add_verify_fn + ? StrCat("&", FieldMessageTypeName(descriptor_, options_), + "::InternalVerify") + : "nullptr"; } ExtensionGenerator::~ExtensionGenerator() {} @@ -164,23 +180,11 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { } format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" - " $scoped_name$($constant_name$, $1$);\n", + " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" + " $scoped_name$($constant_name$, $1$, $verify_fn$);\n", default_str); - - // Register extension verify function if needed. - if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && - ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_)) { - format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " - "::$proto_ns$::internal::RegisterExtensionVerify< $extendee$,\n" - " $1$, $number$> $2$_$name$_register;\n", - ClassName(descriptor_->message_type(), true), - IsScoped() ? ClassName(descriptor_->extension_scope(), false) : ""); - } } } // namespace cpp diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/extension.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/extension.h index bcc80186..282931fa 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/extension.h @@ -39,7 +39,7 @@ #include #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/field.cc similarity index 85% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/field.cc index a95dd33e..90d20848 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/field.cc @@ -32,25 +32,25 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include namespace google { namespace protobuf { @@ -81,7 +81,7 @@ std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, std::string field_name = google::protobuf::compiler::cpp::FieldName(descriptor); std::string field_pointer = descriptor->options().ctype() == google::protobuf::FieldOptions::STRING - ? "$0.GetPointer()" + ? "$0.UnsafeGetPointer()" : "$0"; if (descriptor->default_value_string().empty()) { @@ -103,7 +103,7 @@ std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, return strings::Substitute( StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ", default_value_pointer), - field_member, MakeDefaultName(descriptor)); + field_member, MakeDefaultFieldName(descriptor)); } std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, @@ -114,8 +114,8 @@ std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) { return strings::Substitute( - "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member, - MakeDefaultName(descriptor)); + "$0.IsDefault() ? &$1.get() : $0.UnsafeGetPointer()", field_member, + MakeDefaultFieldName(descriptor)); } return StrCat("&", field_member); @@ -150,14 +150,12 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, google::protobuf::FileOptions::LITE_RUNTIME) { return; } - std::string field_member = (*variables)["field_member"]; + std::string field_member = (*variables)["field"]; const google::protobuf::OneofDescriptor* oneof_member = descriptor->real_containing_oneof(); - if (oneof_member) { - field_member = StrCat(oneof_member->name(), "_.", field_member); - } const std::string proto_ns = (*variables)["proto_ns"]; - const std::string substitute_template_prefix = " _tracker_.$1<$0>(this, "; + const std::string substitute_template_prefix = + StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, "); std::string prepared_template; // Flat template is needed if the prepared one is introspecting the values @@ -178,7 +176,7 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, } else if (descriptor->is_map()) { prepared_template = "nullptr"; } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE && - !descriptor->options().lazy()) { + !IsExplicitLazy(descriptor)) { prepared_template = "nullptr"; } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { if (oneof_member) { @@ -238,13 +236,16 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map* variables, const Options& options) { SetCommonVars(options, variables); + SetCommonMessageDataVariables(descriptor->containing_type(), variables); + (*variables)["ns"] = Namespace(descriptor, options); (*variables)["name"] = FieldName(descriptor); (*variables)["index"] = StrCat(descriptor->index()); (*variables)["number"] = StrCat(descriptor->number()); (*variables)["classname"] = ClassName(FieldScope(descriptor), false); (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["field_member"] = FieldName(descriptor) + "_"; + bool split = ShouldSplit(descriptor, options); + (*variables)["field"] = FieldMemberName(descriptor, split); (*variables)["tag_size"] = StrCat( WireFormat::TagSize(descriptor->number(), descriptor->type())); @@ -252,12 +253,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["set_hasbit"] = ""; (*variables)["clear_hasbit"] = ""; - if (HasHasbit(descriptor)) { - (*variables)["set_hasbit_io"] = - "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);"; - } else { - (*variables)["set_hasbit_io"] = ""; - } + (*variables)["maybe_prepare_split_message"] = + split ? " PrepareSplitMessageForWrite();\n" : ""; AddAccessorAnnotations(descriptor, options, variables); @@ -275,10 +272,10 @@ void FieldGenerator::SetHasBitIndex(int32_t has_bit_index) { return; } variables_["set_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] |= 0x", + variables_["has_bits"], "[", has_bit_index / 32, "] |= 0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); variables_["clear_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] &= ~0x", + variables_["has_bits"], "[", has_bit_index / 32, "] &= ~0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); } @@ -287,24 +284,57 @@ void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) { GOOGLE_CHECK_EQ(inlined_string_index, -1); return; } + // The first bit is the tracking bit for on demand registering ArenaDtor. + GOOGLE_CHECK_GT(inlined_string_index, 0) + << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; variables_["inlined_string_donated"] = StrCat( - "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x", + "(", variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "] & 0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u) != 0;"); variables_["donating_states_word"] = - StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]"); + StrCat(variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "]"); variables_["mask_for_undonate"] = StrCat( "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u"); } +void FieldGenerator::GenerateAggregateInitializer(io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format("decltype(Impl_::Split::$name$_){arena}"); + return; + } + format("decltype($field$){arena}"); +} + +void FieldGenerator::GenerateConstexprAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("/*decltype($field$)*/{}"); +} + +void FieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){from.$field$}"); +} + +void FieldGenerator::GenerateCopyConstructorCode(io::Printer* printer) const { + if (ShouldSplit(descriptor_, options_)) { + // There is no copy constructor for the `Split` struct, so we need to copy + // the value here. + Formatter format(printer, variables_); + format("$field$ = from.$field$;\n"); + } +} + void SetCommonOneofFieldVariables( const FieldDescriptor* descriptor, std::map* variables) { const std::string prefix = descriptor->containing_oneof()->name() + "_."; (*variables)["oneof_name"] = descriptor->containing_oneof()->name(); - (*variables)["field_member"] = - StrCat(prefix, (*variables)["name"], "_"); } FieldGenerator::~FieldGenerator() {} diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/field.h similarity index 82% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/field.h index e0eb679b..dd2a51a2 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/field.h @@ -40,9 +40,9 @@ #include #include -#include -#include #include +#include +#include namespace google { namespace protobuf { @@ -136,7 +136,7 @@ class FieldGenerator { virtual void GenerateMergingCode(io::Printer* printer) const = 0; // Generates a copy constructor - virtual void GenerateCopyConstructorCode(io::Printer* printer) const = 0; + virtual void GenerateCopyConstructorCode(io::Printer* printer) const; // Generate lines of code (statements, not declarations) which swaps // this field and the corresponding field of another message, which @@ -150,6 +150,9 @@ class FieldGenerator { // method, invoked by each of the generated constructors. virtual void GenerateConstructorCode(io::Printer* printer) const = 0; + // Generate initialization code for private members in the cold struct. + virtual void GenerateCreateSplitMessageCode(io::Printer* printer) const {} + // Generate any code that needs to go in the class's SharedDtor() method, // invoked by the destructor. // Most field types don't need this, so the default implementation is empty. @@ -158,18 +161,39 @@ class FieldGenerator { // Generate a manual destructor invocation for use when the message is on an // arena. The code that this method generates will be executed inside a // shared-for-the-whole-message-class method registered with - // OwnDestructor(). The method should return |true| if it generated any code - // that requires a call; this allows the message generator to eliminate the - // OwnDestructor() registration if no fields require it. - virtual bool GenerateArenaDestructorCode(io::Printer* printer) const { - return false; + // OwnDestructor(). + virtual void GenerateArenaDestructorCode(io::Printer* printer) const { + GOOGLE_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone) + << descriptor_->cpp_type_name(); } // Generate initialization code for private members declared by - // GeneratePrivateMembers(), specifically for the constexpr constructor. - // These go into the constructor's initializer list and must follow that - // syntax (eg `field_(args)`). Does not include `:` or `,` separators. - virtual void GenerateConstinitInitializer(io::Printer* printer) const {} + // GeneratePrivateMembers(). These go into the SharedCtor's + // aggregate initialization of the _impl_ struct and must follow the syntax + // (e.g. `decltype($field$){$default$}`). Does not include `:` or `,` + // separators. Default values should be specified here when possible. + // + // Note: We use `decltype($field$)` for both explicit construction and the + // fact that it's self-documenting. Pre-C++17, copy elision isn't guaranteed + // in aggregate initialization so a valid copy/move constructor must exist + // (even though it's not used). Because of this, we need to comment out the + // decltype and fallback to implicit construction. + virtual void GenerateAggregateInitializer(io::Printer* printer) const; + + // Generate constinit initialization code for private members declared by + // GeneratePrivateMembers(). These go into the constexpr constructor's + // aggregate initialization of the _impl_ struct and must follow the syntax + // (e.g. `/*decltype($field$)*/{}`, see above). Does not + // include `:` or `,` separators. + virtual void GenerateConstexprAggregateInitializer( + io::Printer* printer) const; + + // Generate copy initialization code for private members declared by + // GeneratePrivateMembers(). These go into the copy constructor's + // aggregate initialization of the _impl_ struct and must follow the syntax + // (e.g. `decltype($field$){from.$field$}`, see above). Does not + // include `:` or `,` separators. + virtual void GenerateCopyAggregateInitializer(io::Printer* printer) const; // Generate lines to serialize this field directly to the array "target", // which are placed within the message's SerializeWithCachedSizesToArray() @@ -187,6 +211,10 @@ class FieldGenerator { virtual bool IsInlined() const { return false; } + virtual ArenaDtorNeeds NeedsArenaDestructor() const { + return ArenaDtorNeeds::kNone; + } + void SetHasBitIndex(int32_t has_bit_index); void SetInlinedStringIndex(int32_t inlined_string_index); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/file.cc similarity index 83% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/file.cc index c7816b54..838e0ab9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/file.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -42,16 +42,16 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include #include #include +#include +#include +#include +#include +#include +#include +#include // Must be last. #include @@ -87,6 +87,23 @@ std::vector Sorted(const std::unordered_set& vals) { return sorted; } +// TODO(b/203101078): remove pragmas that suppresses uninitialized warnings when +// clang bug is fixed. +inline void MuteWuninitialized(Formatter& format) { + format( + "#if defined(__llvm__)\n" + " #pragma clang diagnostic push\n" + " #pragma clang diagnostic ignored \"-Wuninitialized\"\n" + "#endif // __llvm__\n"); +} + +inline void UnmuteWuninitialized(Formatter& format) { + format( + "#if defined(__llvm__)\n" + " #pragma clang diagnostic pop\n" + "#endif // __llvm__\n"); +} + } // namespace FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) @@ -335,7 +352,14 @@ void FileGenerator::DoIncludeFile(const std::string& google3_name, options_.runtime_include_base, path); } } else { - format("#include \"$1$\"", google3_name); + std::string path = google3_name; + // The bootstrapped proto generated code needs to use the + // third_party/protobuf header paths to avoid circular dependencies. + if (options_.bootstrap) { + path = StringReplace(google3_name, "net/proto2/public", + "third_party/protobuf", false); + } + format("#include \"$1$\"", path); } if (do_export) { @@ -428,26 +452,72 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { format("// @@protoc_insertion_point(includes)\n"); IncludeFile("net/proto2/public/port_def.inc", printer); +} + +void FileGenerator::GenerateSourcePrelude(io::Printer* printer) { + Formatter format(printer, variables_); // For MSVC builds, we use #pragma init_seg to move the initialization of our // libraries to happen before the user code. // This worksaround the fact that MSVC does not do constant initializers when // required by the standard. format("\nPROTOBUF_PRAGMA_INIT_SEG\n"); + + // Generate convenience aliases. + format( + "\n" + "namespace _pb = ::$1$;\n" + "namespace _pbi = _pb::internal;\n", + ProtobufNamespace(options_)); + if (HasGeneratedMethods(file_, options_) && + options_.tctable_mode != Options::kTCTableNever) { + format("namespace _fl = _pbi::field_layout;\n"); + } + format("\n"); } void FileGenerator::GenerateSourceDefaultInstance(int idx, io::Printer* printer) { Formatter format(printer, variables_); MessageGenerator* generator = message_generators_[idx].get(); + // Generate the split instance first because it's needed in the constexpr + // constructor. + if (ShouldSplit(generator->descriptor_, options_)) { + // Use a union to disable the destructor of the _instance member. + // We can constant initialize, but the object will still have a non-trivial + // destructor that we need to elide. + format( + "struct $1$ {\n" + " PROTOBUF_CONSTEXPR $1$()\n" + " : _instance{", + DefaultInstanceType(generator->descriptor_, options_, + /*split=*/true)); + generator->GenerateInitDefaultSplitInstance(printer); + format( + "} {}\n" + " ~$1$() {}\n" + " union {\n" + " $2$ _instance;\n" + " };\n" + "};\n", + DefaultInstanceType(generator->descriptor_, options_, /*split=*/true), + StrCat(generator->classname_, "::Impl_::Split")); + // NO_DESTROY is not necessary for correctness. The empty destructor is + // enough. However, the empty destructor fails to be elided in some + // configurations (like non-opt or with certain sanitizers). NO_DESTROY is + // there just to improve performance and binary size in these builds. + format( + "PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n", + DefaultInstanceType(generator->descriptor_, options_, /*split=*/true), + DefaultInstanceName(generator->descriptor_, options_, /*split=*/true)); + } + generator->GenerateConstexprConstructor(printer); - // Use a union to disable the destructor of the _instance member. - // We can constant initialize, but the object will still have a non-trivial - // destructor that we need to elide. format( "struct $1$ {\n" - " constexpr $1$()\n" - " : _instance(::$proto_ns$::internal::ConstantInitialized{}) {}\n" + " PROTOBUF_CONSTEXPR $1$()\n" + " : _instance(::_pbi::ConstantInitialized{}) {}\n" " ~$1$() {}\n" " union {\n" " $2$ _instance;\n" @@ -455,32 +525,32 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, "};\n", DefaultInstanceType(generator->descriptor_, options_), generator->classname_); - // NO_DESTROY is not necessary for correctness. The empty destructor is - // enough. However, the empty destructor fails to be elided in some - // configurations (like non-opt or with certain sanitizers). NO_DESTROY is - // there just to improve performance and binary size in these builds. - format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT $1$ $2$;\n", - DefaultInstanceType(generator->descriptor_, options_), - DefaultInstanceName(generator->descriptor_, options_)); + format( + "PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT " + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n", + DefaultInstanceType(generator->descriptor_, options_), + DefaultInstanceName(generator->descriptor_, options_)); for (int i = 0; i < generator->descriptor_->field_count(); i++) { const FieldDescriptor* field = generator->descriptor_->field(i); if (IsStringInlined(field, options_)) { // Force the initialization of the inlined string in the default instance. format( - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY std::true_type " - "$1$::_init_inline_$2$_ = " - "($3$._instance.$2$_.Init(), std::true_type{});\n", + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 std::true_type " + "$1$::Impl_::_init_inline_$2$_ = " + "($3$._instance.$4$.Init(), std::true_type{});\n", ClassName(generator->descriptor_), FieldName(field), - DefaultInstanceName(generator->descriptor_, options_)); + DefaultInstanceName(generator->descriptor_, options_), + FieldMemberName(field, ShouldSplit(field, options_))); } } if (options_.lite_implicit_weak_fields) { - format("$1$* $2$ = &$3$;\n", - DefaultInstanceType(generator->descriptor_, options_), - DefaultInstancePtr(generator->descriptor_, options_), - DefaultInstanceName(generator->descriptor_, options_)); + format( + "PROTOBUF_CONSTINIT const void* $1$ =\n" + " &$2$;\n", + DefaultInstancePtr(generator->descriptor_, options_), + DefaultInstanceName(generator->descriptor_, options_)); } } @@ -534,11 +604,10 @@ void FileGenerator::GenerateInternalForwardDeclarations( for (auto instance : Sorted(refs.weak_default_instances)) { ns.ChangeTo(Namespace(instance, options_)); if (options_.lite_implicit_weak_fields) { - format("extern $1$ $2$;\n", DefaultInstanceType(instance, options_), - DefaultInstanceName(instance, options_)); - format("__attribute__((weak)) $1$* $2$ = nullptr;\n", - DefaultInstanceType(instance, options_), - DefaultInstancePtr(instance, options_)); + format( + "PROTOBUF_CONSTINIT __attribute__((weak)) const void* $1$ =\n" + " &::_pbi::implicit_weak_message_default_instance;\n", + DefaultInstancePtr(instance, options_)); } else { format("extern __attribute__((weak)) $1$ $2$;\n", DefaultInstanceType(instance, options_), @@ -549,8 +618,7 @@ void FileGenerator::GenerateInternalForwardDeclarations( for (auto file : Sorted(refs.weak_reflection_files)) { format( - "extern __attribute__((weak)) const " - "::$proto_ns$::internal::DescriptorTable $1$;\n", + "extern __attribute__((weak)) const ::_pbi::DescriptorTable $1$;\n", DescriptorTableName(file, options_)); } } @@ -558,6 +626,9 @@ void FileGenerator::GenerateInternalForwardDeclarations( void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); + + if (IsAnyMessage(file_, options_)) MuteWuninitialized(format); CrossFileReferences refs; ForEachField(message_generators_[idx]->descriptor_, @@ -586,6 +657,8 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { message_generators_[idx]->GenerateSourceInProto2Namespace(printer); } + if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format); + format( "\n" "// @@protoc_insertion_point(global_scope)\n"); @@ -594,6 +667,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); NamespaceOpener ns(Namespace(file_, options_), format); extension_generators_[idx]->GenerateDefinition(printer); } @@ -601,10 +675,9 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) { void FileGenerator::GenerateGlobalSource(io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); { - GenerateTables(printer); - // Define the code to initialize reflection. This code uses a global // constructor to register reflection data with the runtime pre-main. if (HasDescriptorMethods(file_, options_)) { @@ -623,10 +696,13 @@ void FileGenerator::GenerateGlobalSource(io::Printer* printer) { void FileGenerator::GenerateSource(io::Printer* printer) { Formatter format(printer, variables_); GenerateSourceIncludes(printer); + GenerateSourcePrelude(printer); CrossFileReferences refs; GetCrossFileReferencesForFile(file_, &refs); GenerateInternalForwardDeclarations(refs, printer); + if (IsAnyMessage(file_, options_)) MuteWuninitialized(format); + { NamespaceOpener ns(Namespace(file_, options_), format); @@ -637,8 +713,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) { } { - GenerateTables(printer); - if (HasDescriptorMethods(file_, options_)) { // Define the code to initialize reflection. This code uses a global // constructor to register reflection data with the runtime pre-main. @@ -695,6 +769,8 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "\n" "// @@protoc_insertion_point(global_scope)\n"); + if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format); + IncludeFile("net/proto2/public/port_undef.inc", printer); } @@ -702,31 +778,30 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { Formatter format(printer, variables_); if (!message_generators_.empty()) { - format("static ::$proto_ns$::Metadata $file_level_metadata$[$1$];\n", + format("static ::_pb::Metadata $file_level_metadata$[$1$];\n", message_generators_.size()); } if (!enum_generators_.empty()) { format( - "static " - "const ::$proto_ns$::EnumDescriptor* " + "static const ::_pb::EnumDescriptor* " "$file_level_enum_descriptors$[$1$];\n", enum_generators_.size()); } else { format( "static " - "constexpr ::$proto_ns$::EnumDescriptor const** " + "constexpr ::_pb::EnumDescriptor const** " "$file_level_enum_descriptors$ = nullptr;\n"); } if (HasGenericServices(file_, options_) && file_->service_count() > 0) { format( "static " - "const ::$proto_ns$::ServiceDescriptor* " + "const ::_pb::ServiceDescriptor* " "$file_level_service_descriptors$[$1$];\n", file_->service_count()); } else { format( "static " - "constexpr ::$proto_ns$::ServiceDescriptor const** " + "constexpr ::_pb::ServiceDescriptor const** " "$file_level_service_descriptors$ = nullptr;\n"); } @@ -744,7 +819,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format.Outdent(); format( "};\n" - "static const ::$proto_ns$::internal::MigrationSchema schemas[] " + "static const ::_pbi::MigrationSchema schemas[] " "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); format.Indent(); { @@ -758,16 +833,13 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format.Outdent(); format( "};\n" - "\nstatic " - "::$proto_ns$::Message const * const file_default_instances[] = {\n"); + "\nstatic const ::_pb::Message* const file_default_instances[] = {\n"); format.Indent(); for (int i = 0; i < message_generators_.size(); i++) { const Descriptor* descriptor = message_generators_[i]->descriptor_; - format( - "reinterpret_cast(&$1$::_$2$_default_instance_),\n", - Namespace(descriptor, options_), // 1 - ClassName(descriptor)); // 2 + format("&$1$::_$2$_default_instance_._instance,\n", + Namespace(descriptor, options_), // 1 + ClassName(descriptor)); // 2 } format.Outdent(); format( @@ -778,10 +850,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format( // MSVC doesn't like empty arrays, so we add a dummy. "const $uint32$ $tablename$::offsets[1] = {};\n" - "static constexpr ::$proto_ns$::internal::MigrationSchema* schemas = " - "nullptr;" - "\n" - "static constexpr ::$proto_ns$::Message* const* " + "static constexpr ::_pbi::MigrationSchema* schemas = nullptr;\n" + "static constexpr ::_pb::Message* const* " "file_default_instances = nullptr;\n" "\n"); } @@ -836,7 +906,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // Build array of DescriptorTable deps. if (num_deps > 0) { format( - "static const ::$proto_ns$::internal::DescriptorTable*const " + "static const ::_pbi::DescriptorTable* const " "$desc_table$_deps[$1$] = {\n", num_deps); @@ -856,13 +926,14 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // so disable for now. bool eager = false; format( - "static ::$proto_ns$::internal::once_flag $desc_table$_once;\n" - "const ::$proto_ns$::internal::DescriptorTable $desc_table$ = {\n" - " false, $1$, $2$, $3$, \"$filename$\", \n" - " &$desc_table$_once, $4$, $5$, $6$,\n" - " schemas, file_default_instances, $tablename$::offsets,\n" - " $7$, $file_level_enum_descriptors$, " - "$file_level_service_descriptors$,\n" + "static ::_pbi::once_flag $desc_table$_once;\n" + "const ::_pbi::DescriptorTable $desc_table$ = {\n" + " false, $1$, $2$, $3$,\n" + " \"$filename$\",\n" + " &$desc_table$_once, $4$, $5$, $6$,\n" + " schemas, file_default_instances, $tablename$::offsets,\n" + " $7$, $file_level_enum_descriptors$,\n" + " $file_level_service_descriptors$,\n" "};\n" // This function exists to be marked as weak. // It can significantly speed up compilation by breaking up LLVM's SCC in @@ -875,7 +946,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // vtables -> GetMetadata // By adding a weak function here we break the connection from the // individual vtables back into the descriptor table. - "PROTOBUF_ATTRIBUTE_WEAK const ::$proto_ns$::internal::DescriptorTable* " + "PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* " "$desc_table$_getter() {\n" " return &$desc_table$;\n" "}\n" @@ -893,127 +964,17 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { if (file_->name() != "net/proto2/proto/descriptor.proto") { format( "// Force running AddDescriptors() at dynamic initialization time.\n" - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " - "static ::$proto_ns$::internal::AddDescriptorsRunner " - "$1$(&$desc_table$);\n", + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " + "static ::_pbi::AddDescriptorsRunner $1$(&$desc_table$);\n", UniqueName("dynamic_init_dummy", file_, options_)); } } -void FileGenerator::GenerateTables(io::Printer* printer) { - Formatter format(printer, variables_); - if (options_.table_driven_parsing) { - // TODO(ckennelly): Gate this with the same options flag to enable - // table-driven parsing. - format( - "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n" - " const $tablename$::entries[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - std::vector entries; - size_t count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseOffsets(printer); - entries.push_back(value); - count += value; - } - - // We need these arrays to exist, and MSVC does not like empty arrays. - if (count == 0) { - format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n"); - } - - format.Outdent(); - format( - "};\n" - "\n" - "PROTOBUF_CONSTEXPR_VAR " - "::$proto_ns$::internal::AuxiliaryParseTableField\n" - " const $tablename$::aux[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - std::vector aux_entries; - count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseAuxTable(printer); - aux_entries.push_back(value); - count += value; - } - - if (count == 0) { - format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); - } - - format.Outdent(); - format( - "};\n" - "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n" - " $tablename$::schema[] " - "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); - format.Indent(); - - size_t offset = 0; - size_t aux_offset = 0; - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateParseTable(printer, offset, aux_offset); - offset += entries[i]; - aux_offset += aux_entries[i]; - } - - if (message_generators_.empty()) { - format("{ nullptr, nullptr, 0, -1, -1, false },\n"); - } - - format.Outdent(); - format( - "};\n" - "\n"); - } - - if (!message_generators_.empty() && options_.table_driven_serialization) { - format( - "const ::$proto_ns$::internal::FieldMetadata " - "$tablename$::field_metadata[] " - "= {\n"); - format.Indent(); - std::vector field_metadata_offsets; - int idx = 0; - for (int i = 0; i < message_generators_.size(); i++) { - field_metadata_offsets.push_back(idx); - idx += message_generators_[i]->GenerateFieldMetadata(printer); - } - field_metadata_offsets.push_back(idx); - format.Outdent(); - format( - "};\n" - "const ::$proto_ns$::internal::SerializationTable " - "$tablename$::serialization_table[] = {\n"); - format.Indent(); - // We rely on the order we layout the tables to match the order we - // calculate them with FlattenMessagesInFile, so we check here that - // these match exactly. - std::vector calculated_order = - FlattenMessagesInFile(file_); - GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size()); - for (int i = 0; i < message_generators_.size(); i++) { - GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_); - format("{$1$, $tablename$::field_metadata + $2$},\n", - field_metadata_offsets[i + 1] - field_metadata_offsets[i], // 1 - field_metadata_offsets[i]); // 2 - } - format.Outdent(); - format( - "};\n" - "\n"); - } -} - class FileGenerator::ForwardDeclarations { public: void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; } void AddEnum(const EnumDescriptor* d) { enums_[ClassName(d)] = d; } + void AddSplit(const Descriptor* d) { splits_[ClassName(d)] = d; } void Print(const Formatter& format, const Options& options) const { for (const auto& p : enums_) { @@ -1034,6 +995,14 @@ class FileGenerator::ForwardDeclarations { class_desc, classname, DefaultInstanceType(class_desc, options), DefaultInstanceName(class_desc, options)); } + for (const auto& p : splits_) { + const Descriptor* class_desc = p.second; + format( + "struct $1$;\n" + "$dllexport_decl $extern $1$ $2$;\n", + DefaultInstanceType(class_desc, options, /*split=*/true), + DefaultInstanceName(class_desc, options, /*split=*/true)); + } } void PrintTopLevelDecl(const Formatter& format, @@ -1049,6 +1018,7 @@ class FileGenerator::ForwardDeclarations { private: std::map classes_; std::map enums_; + std::map splits_; }; static void PublicImportDFS(const FileDescriptor* fd, @@ -1094,6 +1064,12 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { if (d && !public_set.count(d->file())) decls[Namespace(d, options_)].AddEnum(d); } + for (const auto& mg : message_generators_) { + const Descriptor* d = mg->descriptor_; + if ((d != nullptr) && (public_set.count(d->file()) == 0u) && + ShouldSplit(mg->descriptor_, options_)) + decls[Namespace(d, options_)].AddSplit(d); + } { NamespaceOpener ns(format); @@ -1185,7 +1161,6 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { if (HasSimpleBaseClasses(file_, options_)) { IncludeFile("net/proto2/public/generated_message_bases.h", printer); } - IncludeFile("net/proto2/public/generated_message_table_driven.h", printer); if (HasGeneratedMethods(file_, options_) && options_.tctable_mode != Options::kTCTableNever) { IncludeFile("net/proto2/public/generated_message_tctable_decl.h", printer); @@ -1297,20 +1272,8 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( "\n" "// Internal implementation detail -- do not use these members.\n" "struct $dllexport_decl $$tablename$ {\n" - // These tables describe how to serialize and parse messages. Used - // for table driven code. - " static const ::$proto_ns$::internal::ParseTableField entries[]\n" - " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" - " static const ::$proto_ns$::internal::AuxiliaryParseTableField aux[]\n" - " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" - " static const ::$proto_ns$::internal::ParseTable schema[$1$]\n" - " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" - " static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n" - " static const ::$proto_ns$::internal::SerializationTable " - "serialization_table[];\n" " static const $uint32$ offsets[];\n" - "};\n", - std::max(size_t(1), message_generators_.size())); + "};\n"); if (HasDescriptorMethods(file_, options_)) { format( "$dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable " diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/file.h similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/file.h index e8816020..ca05361b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/file.h @@ -40,11 +40,12 @@ #include #include #include + #include -#include -#include -#include +#include +#include #include +#include namespace google { namespace protobuf { @@ -122,11 +123,11 @@ class FileGenerator { void GenerateInternalForwardDeclarations(const CrossFileReferences& refs, io::Printer* printer); void GenerateSourceIncludes(io::Printer* printer); + void GenerateSourcePrelude(io::Printer* printer); void GenerateSourceDefaultInstance(int idx, io::Printer* printer); void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs, io::Printer* printer); - void GenerateTables(io::Printer* printer); void GenerateReflectionInitializationCode(io::Printer* printer); // For other imports, generates their forward-declarations. diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/generator.cc similarity index 91% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/generator.cc index 08515710..63a2bceb 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/generator.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,11 +40,11 @@ #include #include -#include -#include -#include #include #include +#include +#include +#include namespace google { namespace protobuf { @@ -82,6 +82,12 @@ bool CppGenerator::Generate(const FileDescriptor* file, // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or // __declspec(dllimport) depending on what is being compiled. // + // If the proto_h option is passed to the compiler, we will generate all + // classes and enums so that they can be forward-declared from files that + // need them from imports. + // + // If the lite option is passed to the compiler, we will generate the + // current files and all transitive dependencies using the LITE runtime. Options file_options; file_options.opensource_runtime = opensource_runtime_; @@ -109,8 +115,10 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.lite_implicit_weak_fields = true; if (!options[i].second.empty()) { file_options.num_cc_files = - strto32(options[i].second.c_str(), NULL, 10); + strto32(options[i].second.c_str(), nullptr, 10); } + } else if (options[i].first == "proto_h") { + file_options.proto_h = true; } else if (options[i].first == "annotate_accessor") { file_options.annotate_accessor = true; } else if (options[i].first == "inject_field_listener_events") { @@ -127,14 +135,14 @@ bool CppGenerator::Generate(const FileDescriptor* file, .insert(options[i].second.substr(pos, next_pos - pos)); pos = next_pos + 1; } while (pos < options[i].second.size()); - } else if (options[i].first == "eagerly_verified_lazy") { - file_options.eagerly_verified_lazy = true; + } else if (options[i].first == "verified_lazy") { + file_options.unverified_lazy = false; + } else if (options[i].first == "unverified_lazy_message_sets") { + file_options.unverified_lazy_message_sets = true; + } else if (options[i].first == "message_owned_arena_trial") { + file_options.message_owned_arena_trial = true; } else if (options[i].first == "force_eagerly_verified_lazy") { file_options.force_eagerly_verified_lazy = true; - } else if (options[i].first == "table_driven_parsing") { - file_options.table_driven_parsing = true; - } else if (options[i].first == "table_driven_serialization") { - file_options.table_driven_serialization = true; } else if (options[i].first == "experimental_tail_call_table_mode") { if (options[i].second == "never") { file_options.tctable_mode = Options::kTCTableNever; @@ -183,7 +191,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, std::string info_path = basename + ".proto.h.meta"; io::Printer printer( output.get(), '$', - file_options.annotate_headers ? &annotation_collector : NULL); + file_options.annotate_headers ? &annotation_collector : nullptr); file_generator.GenerateProtoHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { @@ -202,7 +210,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, std::string info_path = basename + ".pb.h.meta"; io::Printer printer( output.get(), '$', - file_options.annotate_headers ? &annotation_collector : NULL); + file_options.annotate_headers ? &annotation_collector : nullptr); file_generator.GeneratePBHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/generator.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/generator.h new file mode 100644 index 00000000..1a374b9f --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/generator.h @@ -0,0 +1,107 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates C++ code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ + +#include +#include + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// CodeGenerator implementation which generates a C++ source file and +// header. If you create your own protocol compiler binary and you want +// it to support C++ output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class PROTOC_EXPORT CppGenerator : public CodeGenerator { + public: + CppGenerator(); + ~CppGenerator() override; + + enum class Runtime { + kGoogle3, // Use the internal google3 runtime. + kOpensource, // Use the open-source runtime. + + // Use the open-source runtime with google3 #include paths. We make these + // absolute to avoid ambiguity, so the runtime will be #included like: + // #include "third_party/protobuf/.../google/protobuf/message.h" + kOpensourceGoogle3 + }; + + void set_opensource_runtime(bool opensource) { + opensource_runtime_ = opensource; + } + + // If set to a non-empty string, generated code will do: + // #include "/google/protobuf/message.h" + // instead of: + // #include + // This has no effect if opensource_runtime = false. + void set_runtime_include_base(const std::string& base) { + runtime_include_base_ = base; + } + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override { + // We don't fully support this yet, but this is needed to unblock the tests, + // and we will have full support before the experimental flag is removed. + return FEATURE_PROTO3_OPTIONAL; + } + + private: + bool opensource_runtime_ = true; + std::string runtime_include_base_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include + +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.cc similarity index 91% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.cc index 9fe47bff..4b7c5c9d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.cc @@ -32,22 +32,23 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include #include +#include #include #include #include #include #include -#include -#include -#include #include +#include +#include +#include #include #include #include @@ -178,18 +179,53 @@ void SetIntVar(const Options& options, const std::string& type, std::map* variables) { (*variables)[type] = IntTypeName(options, type); } -bool IsEagerlyVerifiedLazyImpl(const FieldDescriptor* field, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) { + +// Returns true if the message can potentially allocate memory for its field. +// This is used to determine if message-owned arena will be useful. +bool AllocExpected(const Descriptor* descriptor) { return false; } +// Describes different approaches to detect non-canonical int32 encoding. Only +// kNever or kAlways is eligible for *simple* verification methods. +enum class VerifyInt32Type { + kCustom, // Only check if field number matches. + kNever, // Do not check. + kAlways, // Always check. +}; + +inline VerifySimpleType VerifyInt32TypeToVerifyCustom(VerifyInt32Type t) { + static VerifySimpleType kCustomTypes[] = { + VerifySimpleType::kCustom, VerifySimpleType::kCustomInt32Never, + VerifySimpleType::kCustomInt32Always}; + return kCustomTypes[static_cast(t) - + static_cast(VerifyInt32Type::kCustom)]; +} + } // namespace bool IsLazy(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer) { return IsLazilyVerifiedLazy(field, options) || - IsEagerlyVerifiedLazyImpl(field, options, scc_analyzer); + IsEagerlyVerifiedLazy(field, options, scc_analyzer); +} + +// Returns true if "field" is a message field that is backed by LazyField per +// profile (go/pdlazy). +inline bool IsEagerlyVerifiedLazyByProfile(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return false; +} + +bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return false; +} + +bool IsLazilyVerifiedLazy(const FieldDescriptor* field, + const Options& options) { + return false; } void SetCommonVars(const Options& options, @@ -229,6 +265,23 @@ void SetCommonVars(const Options& options, (*variables)["string"] = "std::string"; } +void SetCommonMessageDataVariables( + const Descriptor* descriptor, + std::map* variables) { + std::string prefix = IsMapEntryMessage(descriptor) ? "" : "_impl_."; + (*variables)["any_metadata"] = prefix + "_any_metadata_"; + (*variables)["cached_size"] = prefix + "_cached_size_"; + (*variables)["extensions"] = prefix + "_extensions_"; + (*variables)["has_bits"] = prefix + "_has_bits_"; + (*variables)["inlined_string_donated_array"] = + prefix + "_inlined_string_donated_"; + (*variables)["oneof_case"] = prefix + "_oneof_case_"; + (*variables)["tracker"] = "Impl_::_tracker_"; + (*variables)["weak_field_map"] = prefix + "_weak_field_map_"; + (*variables)["split"] = prefix + "_split_"; + (*variables)["cached_split_ptr"] = "cached_split_ptr"; +} + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables) { @@ -391,29 +444,32 @@ std::string Namespace(const EnumDescriptor* d, const Options& options) { } std::string DefaultInstanceType(const Descriptor* descriptor, - const Options& options) { - return ClassName(descriptor) + "DefaultTypeInternal"; + const Options& /*options*/, bool split) { + return ClassName(descriptor) + (split ? "__Impl_Split" : "") + + "DefaultTypeInternal"; } std::string DefaultInstanceName(const Descriptor* descriptor, - const Options& options) { - return "_" + ClassName(descriptor, false) + "_default_instance_"; + const Options& /*options*/, bool split) { + return "_" + ClassName(descriptor, false) + (split ? "__Impl_Split" : "") + + "_default_instance_"; } std::string DefaultInstancePtr(const Descriptor* descriptor, - const Options& options) { - return DefaultInstanceName(descriptor, options) + "ptr_"; + const Options& options, bool split) { + return DefaultInstanceName(descriptor, options, split) + "ptr_"; } std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, - const Options& options) { + const Options& options, bool split) { return QualifiedFileLevelSymbol( - descriptor->file(), DefaultInstanceName(descriptor, options), options); + descriptor->file(), DefaultInstanceName(descriptor, options, split), + options); } std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, - const Options& options) { - return QualifiedDefaultInstanceName(descriptor, options) + "ptr_"; + const Options& options, bool split) { + return QualifiedDefaultInstanceName(descriptor, options, split) + "ptr_"; } std::string DescriptorTableName(const FileDescriptor* file, @@ -453,6 +509,19 @@ std::string FieldName(const FieldDescriptor* field) { return result; } +std::string FieldMemberName(const FieldDescriptor* field, bool split) { + StringPiece prefix = + IsMapEntryMessage(field->containing_type()) ? "" : "_impl_."; + StringPiece split_prefix = split ? "_split_->" : ""; + if (field->real_containing_oneof() == nullptr) { + return StrCat(prefix, split_prefix, FieldName(field), "_"); + } + // Oneof fields are never split. + GOOGLE_CHECK(!split); + return StrCat(prefix, field->containing_oneof()->name(), "_.", + FieldName(field), "_"); +} + std::string OneofCaseConstantName(const FieldDescriptor* field) { GOOGLE_DCHECK(field->containing_oneof()); std::string field_name = UnderscoresToCamelCase(field->name(), true); @@ -831,6 +900,9 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options, return false; } +bool ShouldSplit(const Descriptor*, const Options&) { return false; } +bool ShouldSplit(const FieldDescriptor*, const Options&) { return false; } + static bool HasRepeatedFields(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) { @@ -967,6 +1039,16 @@ bool ShouldVerify(const FileDescriptor* file, const Options& options, return false; } +bool IsUtf8String(const FieldDescriptor* field) { + return IsProto3(field->file()) && + field->type() == FieldDescriptor::TYPE_STRING; +} + +VerifySimpleType ShouldVerifySimple(const Descriptor* descriptor) { + (void)descriptor; + return VerifySimpleType::kCustom; +} + bool IsStringOrMessage(const FieldDescriptor* field) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: @@ -1147,7 +1229,6 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, return UsingImplicitWeakFields(field->file(), options) && field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_required() && !field->is_map() && !field->is_extension() && - !field->real_containing_oneof() && !IsWellKnownMessage(field->message_type()->file()) && field->message_type()->file()->name() != "net/proto2/proto/descriptor.proto" && @@ -1264,7 +1345,7 @@ bool GetBootstrapBasename(const Options& options, const std::string& basename, std::unordered_map bootstrap_mapping{ {"net/proto2/proto/descriptor", - "net/proto2/internal/descriptor"}, + "third_party/protobuf/descriptor"}, {"net/proto2/compiler/proto/plugin", "net/proto2/compiler/proto/plugin"}, {"net/proto2/compiler/proto/profile", @@ -1297,7 +1378,7 @@ bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, *basename = bootstrap_basename; return false; } else { - std::string forward_to_basename = bootstrap_basename; + const std::string& forward_to_basename = bootstrap_basename; // Generate forwarding headers and empty .pb.cc. { @@ -1486,8 +1567,29 @@ FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, return FileOptions::SPEED; } -bool EnableMessageOwnedArena(const Descriptor* desc) { +inline bool IsMessageOwnedArenaEligible(const Descriptor* desc, + const Options& options) { + return GetOptimizeFor(desc->file(), options) != FileOptions::LITE_RUNTIME && + !options.bootstrap && !options.opensource_runtime && + AllocExpected(desc); +} + +bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options) { (void)desc; + (void)options; + return false; +} + +bool EnableMessageOwnedArenaTrial(const Descriptor* desc, + const Options& options) { + return false; +} + +bool HasMessageFieldOrExtension(const Descriptor* desc) { + if (desc->extension_range_count() > 0) return true; + for (const auto* f : FieldRange(desc)) { + if (f->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) return true; + } return false; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.h similarity index 86% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.h index bd4f48bc..d8dcda72 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/helpers.h @@ -41,10 +41,10 @@ #include #include -#include -#include #include #include +#include +#include #include #include #include @@ -59,6 +59,8 @@ namespace protobuf { namespace compiler { namespace cpp { +enum class ArenaDtorNeeds { kNone = 0, kOnDemand = 1, kRequired = 2 }; + inline std::string ProtobufNamespace(const Options& /* options */) { return "PROTOBUF_NAMESPACE_ID"; } @@ -85,6 +87,11 @@ extern const char kThinSeparator[]; void SetCommonVars(const Options& options, std::map* variables); +// Variables to access message data from the message scope. +void SetCommonMessageDataVariables( + const Descriptor* descriptor, + std::map* variables); + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables); @@ -121,11 +128,11 @@ std::string QualifiedClassName(const EnumDescriptor* d); // Returns the non-nested type name for the given type. If "qualified" is // true, prefix the type with the full namespace. For example, if you had: // package foo.bar; -// message Baz { message Qux {} } -// Then the qualified ClassName for Qux would be: -// ::foo::bar::Baz_Qux +// message Baz { message Moo {} } +// Then the qualified ClassName for Moo would be: +// ::foo::bar::Baz_Moo // While the non-qualified version would be: -// Baz_Qux +// Baz_Moo inline std::string ClassName(const Descriptor* descriptor, bool qualified) { return qualified ? QualifiedClassName(descriptor, Options()) : ClassName(descriptor); @@ -146,24 +153,26 @@ std::string QualifiedExtensionName(const FieldDescriptor* d); // Type name of default instance. std::string DefaultInstanceType(const Descriptor* descriptor, - const Options& options); + const Options& options, bool split = false); // Non-qualified name of the default_instance of this message. std::string DefaultInstanceName(const Descriptor* descriptor, - const Options& options); + const Options& options, bool split = false); // Non-qualified name of the default instance pointer. This is used only for // implicit weak fields, where we need an extra indirection. std::string DefaultInstancePtr(const Descriptor* descriptor, - const Options& options); + const Options& options, bool split = false); // Fully qualified name of the default_instance of this message. std::string QualifiedDefaultInstanceName(const Descriptor* descriptor, - const Options& options); + const Options& options, + bool split = false); // Fully qualified name of the default instance pointer. std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor, - const Options& options); + const Options& options, + bool split = false); // DescriptorTable variable name. std::string DescriptorTableName(const FileDescriptor* file, @@ -186,6 +195,9 @@ std::string ResolveKeyword(const std::string& name); // anyway, so normally this just returns field->name(). std::string FieldName(const FieldDescriptor* field); +// Returns the (unqualified) private member name for this field in C++ code. +std::string FieldMemberName(const FieldDescriptor* field, bool split); + // Returns an estimate of the compiler's alignment for the field. This // can't guarantee to be correct because the generated code could be compiled on // different systems with different alignment rules. The estimates below assume @@ -348,19 +360,22 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options, bool IsLazy(const FieldDescriptor* field, const Options& options, MessageSCCAnalyzer* scc_analyzer); -inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field, - const Options& options) { - return field->options().lazy() && !field->is_repeated() && - field->type() == FieldDescriptor::TYPE_MESSAGE && - GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME && - !options.opensource_runtime; +// Is this an explicit (non-profile driven) lazy field, as denoted by +// lazy/unverified_lazy in the descriptor? +inline bool IsExplicitLazy(const FieldDescriptor* field) { + return field->options().lazy() || field->options().unverified_lazy(); } -inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) { - return IsLazy(field, options, scc_analyzer) && !field->options().lazy(); -} +bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer); + +bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options); + +// Is the given message being split (go/pdsplit)? +bool ShouldSplit(const Descriptor* desc, const Options& options); + +// Is the given field being split out? +bool ShouldSplit(const FieldDescriptor* field, const Options& options); inline bool IsFieldUsed(const FieldDescriptor* /* field */, const Options& /* options */) { @@ -468,10 +483,49 @@ inline bool IsCrossFileMessage(const FieldDescriptor* field) { } inline std::string MakeDefaultName(const FieldDescriptor* field) { - return "_i_give_permission_to_break_this_code_default_" + FieldName(field) + - "_"; + return StrCat("_i_give_permission_to_break_this_code_default_", + FieldName(field), "_"); } +// Semantically distinct from MakeDefaultName in that it gives the C++ code +// referencing a default field from the message scope, rather than just the +// variable name. +// For example, declarations of default variables should always use just +// MakeDefaultName to produce code like: +// Type _i_give_permission_to_break_this_code_default_field_; +// +// Code that references these should use MakeDefaultFieldName, in case the field +// exists at some nested level like: +// internal_container_._i_give_permission_to_break_this_code_default_field_; +inline std::string MakeDefaultFieldName(const FieldDescriptor* field) { + return StrCat("Impl_::", MakeDefaultName(field)); +} + +inline std::string MakeVarintCachedSizeName(const FieldDescriptor* field) { + return StrCat("_", FieldName(field), "_cached_byte_size_"); +} + +// Semantically distinct from MakeVarintCachedSizeName in that it gives the C++ +// code referencing the object from the message scope, rather than just the +// variable name. +// For example, declarations of default variables should always use just +// MakeVarintCachedSizeName to produce code like: +// Type _field_cached_byte_size_; +// +// Code that references these variables should use +// MakeVarintCachedSizeFieldName, in case the field exists at some nested level +// like: +// internal_container_._field_cached_byte_size_; +inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field, + bool split) { + return StrCat("_impl_.", split ? "_split_->" : "", "_", + FieldName(field), "_cached_byte_size_"); +} + +// Note: A lot of libraries detect Any protos based on Descriptor::full_name() +// while the two functions below use FileDescriptor::name(). In a sane world the +// two approaches should be equivalent. But if you are dealing with descriptors +// from untrusted sources, you might need to match semantics across libraries. bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options); bool IsAnyMessage(const Descriptor* descriptor, const Options& options); @@ -680,6 +734,18 @@ inline std::string SimpleBaseClass(const Descriptor* desc, return ""; } +// Returns true if this message has a _tracker_ field. +inline bool HasTracker(const Descriptor* desc, const Options& options) { + return options.field_listener_options.inject_field_listener_events && + desc->file()->options().optimize_for() != + google::protobuf::FileOptions::LITE_RUNTIME; +} + +// Returns true if this message needs an Impl_ struct for it's data. +inline bool HasImplData(const Descriptor* desc, const Options& options) { + return !HasSimpleBaseClass(desc, options); +} + // Formatter is a functor class which acts as a closure around printer and // the variable map. It's much like printer->Print except it supports both named // variables that are substituted using a key value map and direct arguments. In @@ -711,7 +777,7 @@ inline std::string SimpleBaseClass(const Descriptor* desc, // but consider using named variables. Named variables like $foo$, with some // identifier foo, are looked up in the map. One additional feature is that // spaces are accepted between the '$' delimiters, $ foo$ will -// substiture to " bar" if foo stands for "bar", but in case it's empty +// substitute to " bar" if foo stands for "bar", but in case it's empty // will substitute to "". Hence, for example, // // Format(vars, "$dllexport $void fun();") -> "void fun();" @@ -955,12 +1021,39 @@ inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; } PROTOC_EXPORT std::string StripProto(const std::string& filename); -bool EnableMessageOwnedArena(const Descriptor* desc); +bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options); + +bool EnableMessageOwnedArenaTrial(const Descriptor* desc, + const Options& options); bool ShouldVerify(const Descriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); bool ShouldVerify(const FileDescriptor* file, const Options& options, MessageSCCAnalyzer* scc_analyzer); + +// Indicates whether to use predefined verify methods for a given message. If a +// message is "simple" and needs no special verification per field (e.g. message +// field, repeated packed, UTF8 string, etc.), we can use either VerifySimple or +// VerifySimpleAlwaysCheckInt32 methods as all verification can be done based on +// the wire type. +// +// Otherwise, we need "custom" verify methods tailored to a message to pass +// which field needs a special verification; i.e. InternalVerify. +enum class VerifySimpleType { + kSimpleInt32Never, // Use VerifySimple + kSimpleInt32Always, // Use VerifySimpleAlwaysCheckInt32 + kCustom, // Use InternalVerify and check only for int32 + kCustomInt32Never, // Use InternalVerify but never check for int32 + kCustomInt32Always, // Use InternalVerify and always check for int32 +}; + +// Returns VerifySimpleType if messages can be verified by predefined methods. +VerifySimpleType ShouldVerifySimple(const Descriptor* descriptor); + +bool IsUtf8String(const FieldDescriptor* field); + +bool HasMessageFieldOrExtension(const Descriptor* desc); + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.cc similarity index 66% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.cc index 130e90eb..3a55ef53 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.cc @@ -28,12 +28,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include -#include #include #include #include +#include namespace google { @@ -53,10 +53,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["type"] = ClassName(descriptor->message_type(), false); (*variables)["full_name"] = descriptor->full_name(); - const FieldDescriptor* key = - descriptor->message_type()->FindFieldByName("key"); - const FieldDescriptor* val = - descriptor->message_type()->FindFieldByName("value"); + const FieldDescriptor* key = descriptor->message_type()->map_key(); + const FieldDescriptor* val = descriptor->message_type()->map_value(); (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type()); switch (val->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: @@ -128,7 +126,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::_internal_$name$() const {\n" - " return $name$_.GetMap();\n" + " return $field$.GetMap();\n" "}\n" "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::$name$() const {\n" @@ -138,7 +136,8 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::_internal_mutable_$name$() {\n" - " return $name$_.MutableMap();\n" + "$maybe_prepare_split_message$" + " return $field$.MutableMap();\n" "}\n" "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::mutable_$name$() {\n" @@ -150,17 +149,17 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions( void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("_this->$field$.MergeFrom(from.$field$);\n"); } void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void MapFieldGenerator::GenerateCopyConstructorCode( @@ -169,35 +168,27 @@ void MapFieldGenerator::GenerateCopyConstructorCode( GenerateMergingCode(printer); } -static void GenerateSerializationLoop(const Formatter& format, bool string_key, +static void GenerateSerializationLoop(Formatter& format, bool string_key, bool string_value, bool is_deterministic) { - std::string ptr; if (is_deterministic) { - format("for (size_type i = 0; i < n; i++) {\n"); - ptr = string_key ? "items[static_cast(i)]" - : "items[static_cast(i)].second"; - } else { format( - "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = this->_internal_$name$().begin();\n" - " it != this->_internal_$name$().end(); ++it) {\n"); - ptr = "it"; + "for (const auto& entry : " + "::_pbi::MapSorter$1$(map_field)) {\n", + (string_key ? "Ptr" : "Flat")); + } else { + format("for (const auto& entry : map_field) {\n"); } - format.Indent(); + { + auto loop_scope = format.ScopedIndent(); + format( + "target = WireHelper::InternalSerialize($number$, " + "entry.first, entry.second, target, stream);\n"); - format( - "target = $map_classname$::Funcs::InternalSerialize($number$, " - "$1$->first, $1$->second, target, stream);\n", - ptr); - - if (string_key || string_value) { - // ptr is either an actual pointer or an iterator, either way we can - // create a pointer by taking the address after de-referencing it. - format("Utf8Check::Check(&(*$1$));\n", ptr); + if (string_key || string_value) { + format("check_utf8(entry);\n"); + } } - - format.Outdent(); format("}\n"); } @@ -206,77 +197,52 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); format("if (!this->_internal_$name$().empty()) {\n"); format.Indent(); - const FieldDescriptor* key_field = - descriptor_->message_type()->FindFieldByName("key"); - const FieldDescriptor* value_field = - descriptor_->message_type()->FindFieldByName("value"); + const FieldDescriptor* key_field = descriptor_->message_type()->map_key(); + const FieldDescriptor* value_field = descriptor_->message_type()->map_value(); const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; format( - "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n" - " ConstPtr;\n"); - if (string_key) { - format( - "typedef ConstPtr SortItem;\n" - "typedef ::$proto_ns$::internal::" - "CompareByDerefFirst Less;\n"); - } else { - format( - "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > " - "SortItem;\n" - "typedef ::$proto_ns$::internal::CompareByFirstField " - "Less;\n"); - } + "using MapType = ::_pb::Map<$key_cpp$, $val_cpp$>;\n" + "using WireHelper = $map_classname$::Funcs;\n" + "const auto& map_field = this->_internal_$name$();\n"); bool utf8_check = string_key || string_value; if (utf8_check) { - format( - "struct Utf8Check {\n" - " static void Check(ConstPtr p) {\n" - // p may be unused when GetUtf8CheckMode evaluates to kNone, - // thus disabling the validation. - " (void)p;\n"); - format.Indent(); - format.Indent(); - if (string_key) { - GenerateUtf8CheckCodeForString( - key_field, options_, false, - "p->first.data(), static_cast(p->first.length()),\n", format); + format("auto check_utf8 = [](const MapType::value_type& entry) {\n"); + { + auto check_scope = format.ScopedIndent(); + // p may be unused when GetUtf8CheckMode evaluates to kNone, + // thus disabling the validation. + format("(void)entry;\n"); + if (string_key) { + GenerateUtf8CheckCodeForString( + key_field, options_, false, + "entry.first.data(), static_cast(entry.first.length()),\n", + format); + } + if (string_value) { + GenerateUtf8CheckCodeForString( + value_field, options_, false, + "entry.second.data(), static_cast(entry.second.length()),\n", + format); + } } - if (string_value) { - GenerateUtf8CheckCodeForString( - value_field, options_, false, - "p->second.data(), static_cast(p->second.length()),\n", format); - } - format.Outdent(); - format.Outdent(); - format( - " }\n" - "};\n"); + format("};\n"); } format( "\n" - "if (stream->IsSerializationDeterministic() &&\n" - " this->_internal_$name$().size() > 1) {\n" - " ::std::unique_ptr items(\n" - " new SortItem[this->_internal_$name$().size()]);\n" - " typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type " - "size_type;\n" - " size_type n = 0;\n" - " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = this->_internal_$name$().begin();\n" - " it != this->_internal_$name$().end(); ++it, ++n) {\n" - " items[static_cast(n)] = SortItem(&*it);\n" - " }\n" - " ::std::sort(&items[0], &items[static_cast(n)], Less());\n"); - format.Indent(); - GenerateSerializationLoop(format, string_key, string_value, true); - format.Outdent(); + "if (stream->IsSerializationDeterministic() && " + "map_field.size() > 1) {\n"); + { + auto deterministic_scope = format.ScopedIndent(); + GenerateSerializationLoop(format, string_key, string_value, true); + } format("} else {\n"); - format.Indent(); - GenerateSerializationLoop(format, string_key, string_value, false); - format.Outdent(); + { + auto map_order_scope = format.ScopedIndent(); + GenerateSerializationLoop(format, string_key, string_value, false); + } format("}\n"); format.Outdent(); format("}\n"); @@ -301,31 +267,69 @@ void MapFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { Formatter format(printer, variables_); format( - "if (!::$proto_ns$::internal::AllAreInitialized($name$_)) return " + "if (!::$proto_ns$::internal::AllAreInitialized($field$)) return " "false;\n"); } -void MapFieldGenerator::GenerateConstinitInitializer( +void MapFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); if (HasDescriptorMethods(descriptor_->file(), options_)) { - format("$name$_(::$proto_ns$::internal::ConstantInitialized{})"); + format("/*decltype($field$)*/{::_pbi::ConstantInitialized()}"); } else { - format("$name$_()"); + format("/*decltype($field$)*/{}"); } } -bool MapFieldGenerator::GenerateArenaDestructorCode( +void MapFieldGenerator::GenerateCopyAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - if (HasDescriptorMethods(descriptor_->file(), options_)) { - // _this is the object being destructed (we are inside a static method - // here). - format("_this->$name$_. ~MapField();\n"); - return true; - } else { - return false; + // MapField has no move constructor, which prevents explicit aggregate + // initialization pre-C++17. + format("/*decltype($field$)*/{}"); +} + +void MapFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format( + "/*decltype($classname$::Split::$name$_)*/" + "{::_pbi::ArenaInitialized(), arena}"); + return; } + // MapField has no move constructor. + format("/*decltype($field$)*/{::_pbi::ArenaInitialized(), arena}"); +} + +void MapFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format("$cached_split_ptr$->$name$_.Destruct();\n"); + format("$cached_split_ptr$->$name$_.~MapField$lite$();\n"); + return; + } + format("$field$.Destruct();\n"); + format("$field$.~MapField$lite$();\n"); +} + +void MapFieldGenerator::GenerateArenaDestructorCode( + io::Printer* printer) const { + if (NeedsArenaDestructor() == ArenaDtorNeeds::kNone) { + return; + } + + Formatter format(printer, variables_); + // _this is the object being destructed (we are inside a static method here). + format("_this->$field$.Destruct();\n"); +} + +ArenaDtorNeeds MapFieldGenerator::NeedsArenaDestructor() const { + return HasDescriptorMethods(descriptor_->file(), options_) + ? ArenaDtorNeeds::kRequired + : ArenaDtorNeeds::kNone; } } // namespace cpp diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.h similarity index 85% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.h index c01ae498..678a128b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/map_field.h @@ -34,8 +34,8 @@ #include #include -#include -#include +#include +#include namespace google { namespace protobuf { @@ -61,8 +61,13 @@ class MapFieldGenerator : public FieldGenerator { io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateIsInitialized(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; - bool GenerateArenaDestructorCode(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateDestructorCode(io::Printer* printer) const override; + void GenerateArenaDestructorCode(io::Printer* printer) const override; + ArenaDtorNeeds NeedsArenaDestructor() const override; private: const bool has_required_fields_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/message.cc similarity index 78% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/message.cc index 70d8a57e..69069dac 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -44,22 +44,22 @@ #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include #include #include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -84,7 +84,7 @@ static constexpr int kNoHasbit = -1; // masks must be non-zero. std::string ConditionalToCheckBitmasks( const std::vector& masks, bool return_success = true, - StringPiece has_bits_var = "_has_bits_") { + StringPiece has_bits_var = "_impl_._has_bits_") { std::vector parts; for (int i = 0; i < masks.size(); i++) { if (masks[i] == 0) continue; @@ -109,7 +109,7 @@ void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field, int has_bit_index = has_bit_indices[field->index()]; if (*cached_has_word_index != (has_bit_index / 32)) { *cached_has_word_index = (has_bit_index / 32); - format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", *cached_has_word_index); } const std::string mask = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); @@ -276,8 +276,8 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, std::map* variables) { GOOGLE_CHECK(IsMapEntryMessage(descriptor)); std::map& vars = *variables; - const FieldDescriptor* key = descriptor->FindFieldByName("key"); - const FieldDescriptor* val = descriptor->FindFieldByName("value"); + const FieldDescriptor* key = descriptor->map_key(); + const FieldDescriptor* val = descriptor->map_value(); vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type()); switch (val->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: @@ -323,64 +323,6 @@ bool ShouldSerializeInOrder(const Descriptor* descriptor, return true; } -bool TableDrivenParsingEnabled(const Descriptor* descriptor, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) { - if (!options.table_driven_parsing) { - return false; - } - - // Consider table-driven parsing. We only do this if: - // - We have has_bits for fields. This avoids a check on every field we set - // when are present (the common case). - bool has_hasbit = false; - for (int i = 0; i < descriptor->field_count(); i++) { - if (HasHasbit(descriptor->field(i))) { - has_hasbit = true; - break; - } - } - - if (!has_hasbit) return false; - - const double table_sparseness = 0.5; - int max_field_number = 0; - for (auto field : FieldRange(descriptor)) { - if (max_field_number < field->number()) { - max_field_number = field->number(); - } - - // - There are no weak fields. - if (IsWeak(field, options)) { - return false; - } - - // - There are no lazy fields (they require the non-lite library). - if (IsLazy(field, options, scc_analyzer)) { - return false; - } - } - - // - There range of field numbers is "small" - if (max_field_number >= (2 << 14)) { - return false; - } - - // - Field numbers are relatively dense within the actual number of fields. - // We check for strictly greater than in the case where there are no fields - // (only extensions) so max_field_number == descriptor->field_count() == 0. - if (max_field_number * table_sparseness > descriptor->field_count()) { - return false; - } - - // - This is not a MapEntryMessage. - if (IsMapEntryMessage(descriptor)) { - return false; - } - - return true; -} - bool IsCrossFileMapField(const FieldDescriptor* field) { if (!field->is_map()) { return false; @@ -404,10 +346,10 @@ bool IsRequired(const std::vector& v) { return v.front()->is_required(); } -bool HasSingularString(const Descriptor* desc, const Options& options) { +bool HasNonSplitOptionalString(const Descriptor* desc, const Options& options) { for (const auto* field : FieldRange(desc)) { - if (IsString(field, options) && !IsStringInlined(field, options) && - !field->is_repeated() && !field->real_containing_oneof()) { + if (IsString(field, options) && !field->is_repeated() && + !field->real_containing_oneof() && !ShouldSplit(field, options)) { return true; } } @@ -462,7 +404,7 @@ static int popcnt(uint32_t n) { class ColdChunkSkipper { public: ColdChunkSkipper( - const Options& options, + const Descriptor* descriptor, const Options& options, const std::vector>& chunks, const std::vector& has_bit_indices, const double cold_threshold) : chunks_(chunks), @@ -470,6 +412,7 @@ class ColdChunkSkipper { access_info_map_(options.access_info_map), cold_threshold_(cold_threshold) { SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(descriptor, &variables_); } // May open an external if check for a batch of cold fields. "from" is the @@ -553,7 +496,7 @@ void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_word_index, if (this_word == cached_has_word_index) { format("(cached_has_bits & 0x$mask$u) != 0"); } else { - format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word); + format("($1$_impl_._has_bits_[$2$] & 0x$mask$u) != 0", from, this_word); } } format(")) {\n"); @@ -605,11 +548,11 @@ void GenerateExtensionAnnotations( for (const auto& annotation : accessor_annotations_to_hooks) { (*variables)[annotation.first] = ""; } - if (!options.field_listener_options.inject_field_listener_events || - descriptor->file()->options().optimize_for() == - google::protobuf::FileOptions::LITE_RUNTIME) { + if (!HasTracker(descriptor, options)) { return; } + StringPiece tracker = (*variables)["tracker"]; + StringPiece extensions = (*variables)["extensions"]; for (const auto& annotation : accessor_annotations_to_hooks) { const std::string& annotation_name = annotation.first; const std::string& listener_call = annotation.second; @@ -619,29 +562,29 @@ void GenerateExtensionAnnotations( // Primitive fields accessors. // "Has" is here as users calling "has" on a repeated field is a mistake. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), " - "_extensions_, id.default_value_ref()));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", id.default_value_ref()));"); } else if (StrContains(annotation_name, "repeated") && !StrContains(annotation_name, "list") && !StrContains(annotation_name, "size")) { // Repeated index accessors. std::string str_index = "index"; if (StrContains(annotation_name, "add")) { - str_index = "_extensions_.ExtensionSize(id.number()) - 1"; + str_index = StrCat(extensions, ".ExtensionSize(id.number()) - 1"); } (*variables)[annotation_name] = - StrCat(" _tracker_.", listener_call, + StrCat(" ", tracker, ".", listener_call, "(this, id.number(), " - "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ", - str_index, "));"); + "_proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", ", str_index, "));"); } else if (StrContains(annotation_name, "list") || StrContains(annotation_name, "size")) { // Repeated full accessors. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), " - "_extensions_));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), ", + extensions, "));"); } else { // Generic accessors such as "clear". // TODO(b/190614678): Generalize clear from both repeated and non repeated @@ -673,6 +616,7 @@ MessageGenerator::MessageGenerator( if (!message_layout_helper_) { message_layout_helper_.reset(new PaddingOptimizer()); } + SetCommonMessageDataVariables(descriptor, &variables_); // Variables that apply to this class variables_["classname"] = classname_; @@ -685,10 +629,9 @@ MessageGenerator::MessageGenerator( variables_["annotate_bytesize"] = ""; variables_["annotate_mergefrom"] = ""; - if (options.field_listener_options.inject_field_listener_events && - descriptor->file()->options().optimize_for() != - google::protobuf::FileOptions::LITE_RUNTIME) { - const std::string injector_template = " _tracker_."; + if (HasTracker(descriptor_, options_)) { + const std::string injector_template = + StrCat(" ", variables_["tracker"], "."); MaySetAnnotationVariable(options, "serialize", injector_template, "OnSerialize(this);\n", &variables_); @@ -703,7 +646,7 @@ MessageGenerator::MessageGenerator( MaySetAnnotationVariable(options, "bytesize", injector_template, "OnByteSize(this);\n", &variables_); MaySetAnnotationVariable(options, "mergefrom", injector_template, - "OnMergeFrom(this, &from);\n", &variables_); + "OnMergeFrom(_this, &from);\n", &variables_); } GenerateExtensionAnnotations(descriptor_, options_, &variables_); @@ -738,6 +681,9 @@ MessageGenerator::MessageGenerator( if (IsStringInlined(field, options_)) { if (inlined_string_indices_.empty()) { inlined_string_indices_.resize(descriptor_->field_count(), kNoHasbit); + // The bitset[0] is for arena dtor tracking. Donating states start from + // bitset[1]; + max_inlined_string_index_++; } inlined_string_indices_[field->index()] = max_inlined_string_index_++; } @@ -758,8 +704,6 @@ MessageGenerator::MessageGenerator( } } - table_driven_ = - TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_); parse_function_generator_.reset(new ParseFunctionGenerator( descriptor_, max_has_bit_index_, has_bit_indices_, inlined_string_indices_, options_, scc_analyzer_, variables_)); @@ -903,7 +847,7 @@ inline bool HasExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_has$ - return _extensions_.Has(id.number()); + return $extensions$.Has(id.number()); } template & id) { - _extensions_.ClearExtension(id.number()); + $extensions$.ClearExtension(id.number()); $annotate_extension_clear$ } @@ -923,7 +867,7 @@ inline int ExtensionSize( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_repeated_size$ - return _extensions_.ExtensionSize(id.number()); + return $extensions$.ExtensionSize(id.number()); } template & id) const { $annotate_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, + return _proto_TypeTraits::Get(id.number(), $extensions$, id.default_value()); } @@ -945,7 +889,7 @@ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { $annotate_extension_mutable$ return _proto_TypeTraits::Mutable(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, typename _proto_TypeTraits::Singular::ConstType value) { - _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), _field_type, value, &$extensions$); $annotate_extension_set$ } @@ -967,7 +911,7 @@ inline void SetAllocatedExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, - &_extensions_); + &$extensions$); $annotate_extension_set$ } template & id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, - value, &_extensions_); + value, &$extensions$); $annotate_extension_set$ } template & id) { $annotate_extension_release$ return _proto_TypeTraits::Release(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id) { $annotate_extension_release$ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, int index) const { $annotate_repeated_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, index); + return _proto_TypeTraits::Get(id.number(), $extensions$, index); } template & id, int index) { $annotate_repeated_extension_mutable$ - return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + return _proto_TypeTraits::Mutable(id.number(), index, &$extensions$); } template & id, int index, typename _proto_TypeTraits::Repeated::ConstType value) { - _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), index, value, &$extensions$); $annotate_repeated_extension_set$ } @@ -1045,7 +989,7 @@ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { typename _proto_TypeTraits::Repeated::MutableType to_add = - _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + _proto_TypeTraits::Add(id.number(), _field_type, &$extensions$); $annotate_repeated_extension_add_mutable$ return to_add; } @@ -1058,7 +1002,7 @@ inline void AddExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Repeated::ConstType value) { _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, - &_extensions_); + &$extensions$); $annotate_repeated_extension_add$ } @@ -1070,7 +1014,7 @@ GetRepeatedExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_repeated_extension_list$ - return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + return _proto_TypeTraits::GetRepeated(id.number(), $extensions$); } template & id) { $annotate_repeated_extension_list_mutable$ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, - _is_packed, &_extensions_); + _is_packed, &$extensions$); } )"); @@ -1119,7 +1063,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::has_$name$() const {\n" "$annotate_has$" - " return _weak_field_map_.Has($number$);\n" + " return $weak_field_map$.Has($number$);\n" "}\n"); return; } @@ -1133,14 +1077,14 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::_internal_has_$name$() const {\n" " bool value = " - "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"); + "($has_bits$[$has_array_index$] & 0x$has_mask$u) != 0;\n"); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !IsLazy(field, options_, scc_analyzer_)) { // We maintain the invariant that for a submessage x, has_x() returning // true implies that x_ is not null. By giving this information to the // compiler, we allow it to eliminate unnecessary null checks later on. - format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n"); + format(" PROTOBUF_ASSUME(!value || $field$ != nullptr);\n"); } format( @@ -1155,13 +1099,13 @@ void MessageGenerator::GenerateSingularFieldHasBits( if (IsLazy(field, options_, scc_analyzer_)) { format( "inline bool $classname$::_internal_has_$name$() const {\n" - " return !$name$_.IsCleared();\n" + " return !$field$.IsCleared();\n" "}\n"); } else { format( "inline bool $classname$::_internal_has_$name$() const {\n" " return this != internal_default_instance() " - "&& $name$_ != nullptr;\n" + "&& $field$ != nullptr;\n" "}\n"); } format( @@ -1183,7 +1127,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" "}\n" "inline void $classname$::clear_has_$oneof_name$() {\n" - " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" + " $oneof_case$[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" "}\n"); } } @@ -1229,7 +1173,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, // annotated. format( "inline void $classname$::set_has_$name$() {\n" - " _oneof_case_[$oneof_index$] = k$field_name$;\n" + " $oneof_case$[$oneof_index$] = k$field_name$;\n" "}\n"); } @@ -1258,13 +1202,16 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format.Outdent(); format("}\n"); } else { + if (ShouldSplit(field, options_)) { + format("if (IsSplitMessageDefault()) return;\n"); + } field_generators_.get(field).GenerateClearingCode(format.printer()); if (HasHasbit(field)) { int has_bit_index = HasBitIndex(field); format.Set("has_array_index", has_bit_index / 32); format.Set("has_mask", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); - format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"); + format("$has_bits$[$has_array_index$] &= ~0x$has_mask$u;\n"); } } format("$annotate_clear$"); @@ -1298,7 +1245,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { } else { format( "inline int $classname$::_internal_$name$_size() const {\n" - " return $name$_$1$.size();\n" + " return $field$$1$.size();\n" "}\n" "inline int $classname$::$name$_size() const {\n" "$annotate_size$" @@ -1360,7 +1307,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " "SuperType;\n" " $classname$();\n" - " explicit constexpr $classname$(\n" + " explicit PROTOBUF_CONSTEXPR $classname$(\n" " ::$proto_ns$::internal::ConstantInitialized);\n" " explicit $classname$(::$proto_ns$::Arena* arena);\n" " void MergeFrom(const $classname$& other);\n" @@ -1432,7 +1379,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "" " ::$proto_ns$::Metadata GetMetadata() const final;\n"); } - format("};\n"); + format( + " friend struct ::$tablename$;\n" + "};\n"); return; } @@ -1444,11 +1393,15 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format(" public:\n"); format.Indent(); - if (EnableMessageOwnedArena(descriptor_)) { + if (EnableMessageOwnedArena(descriptor_, options_)) { format( "inline $classname$() : $classname$(" - "::$proto_ns$::Arena::InternalHelper<$classname$>::\n" - " CreateMessageOwnedArena(), true) {}\n"); + "::$proto_ns$::Arena::InternalCreateMessageOwnedArena(), true) {}\n"); + } else if (EnableMessageOwnedArenaTrial(descriptor_, options_)) { + format( + "inline $classname$() : $classname$(InMoaTrial() ? " + "::$proto_ns$::Arena::InternalCreateMessageOwnedArena() : nullptr, " + "InMoaTrial()) {}\n"); } else { format("inline $classname$() : $classname$(nullptr) {}\n"); } @@ -1456,7 +1409,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format("~$classname$() override;\n"); } format( - "explicit constexpr " + "explicit PROTOBUF_CONSTEXPR " "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" "\n" "$classname$(const $classname$& from);\n" @@ -1484,14 +1437,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "}\n" "\n"); - if (options_.table_driven_serialization) { - format( - "private:\n" - "const void* InternalGetTable() const override;\n" - "public:\n" - "\n"); - } - if (PublicUnknownFieldsAccessors(descriptor_)) { format( "inline const $unknown_fields_type$& unknown_fields() const {\n" @@ -1569,16 +1514,18 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( "bool PackFrom(const ::$proto_ns$::Message& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " $DCHK$_NE(&message, this);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "bool PackFrom(const ::$proto_ns$::Message& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " $DCHK$_NE(&message, this);\n" + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "bool UnpackTo(::$proto_ns$::Message* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n" "static bool GetAnyFieldDescriptors(\n" " const ::$proto_ns$::Message& message,\n" @@ -1588,7 +1535,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "!std::is_convertible" "::value>::type>\n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template " @@ -1596,36 +1543,36 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);" "}\n" "template " "::value>::type>\n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } else { format( "template \n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template \n" "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "template \n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } format( "template bool Is() const {\n" - " return _any_metadata_.Is();\n" + " return $any_metadata$.Is();\n" "}\n" "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url,\n" @@ -1677,27 +1624,28 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // argument is a generic Message instance, and only define the // custom MergeFrom and CopyFrom instances when the source of the // merge/copy is known to be the same class as the destination. - // TODO(jorg): Define MergeFrom in terms of MergeImpl, rather than - // the other way around, to save even more code size. "using $superclass$::CopyFrom;\n" "void CopyFrom(const $classname$& from);\n" "" "using $superclass$::MergeFrom;\n" - "void MergeFrom(const $classname$& from);\n" + "void MergeFrom(" + " const $classname$& from) {\n" + " $classname$::MergeImpl(*this, from);\n" + "}\n" "private:\n" - "static void MergeImpl(::$proto_ns$::Message* to, const " - "::$proto_ns$::Message& from);\n" + "static void MergeImpl(::$proto_ns$::Message& to_msg, const " + "::$proto_ns$::Message& from_msg);\n" "public:\n"); } else { format( "using $superclass$::CopyFrom;\n" "inline void CopyFrom(const $classname$& from) {\n" - " $superclass$::CopyImpl(this, from);\n" + " $superclass$::CopyImpl(*this, from);\n" "}\n" "" "using $superclass$::MergeFrom;\n" "void MergeFrom(const $classname$& from) {\n" - " $superclass$::MergeImpl(this, from);\n" + " $superclass$::MergeImpl(*this, from);\n" "}\n" "public:\n"); } @@ -1732,9 +1680,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (!HasSimpleBaseClass(descriptor_, options_)) { format( - "int GetCachedSize() const final { return _cached_size_.Get(); }" + "int GetCachedSize() const final { return " + "$cached_size$.Get(); }" "\n\nprivate:\n" - "void SharedCtor();\n" + "void SharedCtor(::$proto_ns$::Arena* arena, bool is_message_owned);\n" "void SharedDtor();\n" "void SetCachedSize(int size) const$ full_final$;\n" "void InternalSwap($classname$* other);\n"); @@ -1756,13 +1705,32 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // we rely on. "protected:\n" "explicit $classname$(::$proto_ns$::Arena* arena,\n" - " bool is_message_owned = false);\n" - "private:\n"); + " bool is_message_owned = false);\n"); - if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - "static void ArenaDtor(void* object);\n" - "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); + switch (NeedsArenaDestructor()) { + case ArenaDtorNeeds::kOnDemand: + format( + "private:\n" + "static void ArenaDtor(void* object);\n" + "inline void OnDemandRegisterArenaDtor(::$proto_ns$::Arena* arena) " + "override {\n" + " if (arena == nullptr || ($inlined_string_donated_array$[0] & " + "0x1u) " + "== " + "0) {\n" + " return;\n" + " }\n" + " $inlined_string_donated_array$[0] &= 0xFFFFFFFEu;\n" + " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" + "}\n"); + break; + case ArenaDtorNeeds::kRequired: + format( + "private:\n" + "static void ArenaDtor(void* object);\n"); + break; + case ArenaDtorNeeds::kNone: + break; } format( @@ -1786,6 +1754,17 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); } + if (ShouldSplit(descriptor_, options_)) { + format( + "private:\n" + "inline bool IsSplitMessageDefault() const {\n" + " return $split$ == reinterpret_cast(&$1$);\n" + "}\n" + "PROTOBUF_NOINLINE void PrepareSplitMessageForWrite();\n" + "public:\n", + DefaultInstanceName(descriptor_, options_, /*split=*/true)); + } + format( "// nested types ----------------------------------------------------\n" "\n"); @@ -1866,7 +1845,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // Prepare decls for _cached_size_ and _has_bits_. Their position in the // output will be determined later. - bool need_to_emit_cached_size = true; + bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); const std::string cached_size_decl = "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n"; @@ -1876,12 +1855,21 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { : StrCat("::$proto_ns$::internal::HasBits<", sizeof_has_bits, "> _has_bits_;\n"); + format( + "template friend class " + "::$proto_ns$::Arena::InternalHelper;\n" + "typedef void InternalArenaConstructable_;\n" + "typedef void DestructorSkippable_;\n"); + // To minimize padding, data members are divided into three sections: // (1) members assumed to align to 8 bytes // (2) members corresponding to message fields, re-ordered to optimize // alignment. // (3) members assumed to align to 4 bytes. + format("struct Impl_ {\n"); + format.Indent(); + // Members assumed to align to 8 bytes: if (descriptor_->extension_range_count() > 0) { @@ -1890,9 +1878,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); } - if (options_.field_listener_options.inject_field_listener_events && - descriptor_->file()->options().optimize_for() != - google::protobuf::FileOptions::LITE_RUNTIME) { + if (HasTracker(descriptor_, options_)) { format("static ::$proto_ns$::AccessListener<$1$> _tracker_;\n", ClassName(descriptor_)); } @@ -1905,20 +1891,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { InlinedStringDonatedSize()); } - format( - "template friend class " - "::$proto_ns$::Arena::InternalHelper;\n" - "typedef void InternalArenaConstructable_;\n" - "typedef void DestructorSkippable_;\n"); - if (!has_bit_indices_.empty()) { // _has_bits_ is frequently accessed, so to reduce code size and improve // speed, it should be close to the start of the object. Placing // _cached_size_ together with _has_bits_ improves cache locality despite // potential alignment padding. format(has_bits_decl.c_str()); - format(cached_size_decl.c_str()); - need_to_emit_cached_size = false; + if (need_to_emit_cached_size) { + format(cached_size_decl.c_str()); + need_to_emit_cached_size = false; + } } // Field members: @@ -1927,7 +1909,24 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { for (auto field : optimized_order_) { const FieldGenerator& generator = field_generators_.get(field); generator.GenerateStaticMembers(printer); - generator.GeneratePrivateMembers(printer); + if (!ShouldSplit(field, options_)) { + generator.GeneratePrivateMembers(printer); + } + } + if (ShouldSplit(descriptor_, options_)) { + format("struct Split {\n"); + format.Indent(); + for (auto field : optimized_order_) { + if (!ShouldSplit(field, options_)) continue; + const FieldGenerator& generator = field_generators_.get(field); + generator.GeneratePrivateMembers(printer); + } + format.Outdent(); + format( + " typedef void InternalArenaConstructable_;\n" + " typedef void DestructorSkippable_;\n" + "};\n" + "Split* _split_;\n"); } // For each oneof generate a union @@ -1978,6 +1977,22 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n"); } + format.Outdent(); + format("};\n"); + + // Only create the _impl_ field if it contains data. + if (HasImplData(descriptor_, options_)) { + format("union { Impl_ _impl_; };\n"); + } + + if (ShouldSplit(descriptor_, options_)) { + format( + "static Impl_::Split* CreateSplitMessage(" + "::$proto_ns$::Arena* arena);\n"); + format("friend struct $1$;\n", + DefaultInstanceType(descriptor_, options_, /*split=*/true)); + } + // The TableStruct struct needs access to the private parts, in order to // construct the offsets of all members. format("friend struct ::$tablename$;\n"); @@ -2001,73 +2016,12 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { "inline $classname$::$camel_oneof_name$Case $classname$::" "${1$$oneof_name$_case$}$() const {\n" " return $classname$::$camel_oneof_name$Case(" - "_oneof_case_[$oneof_index$]);\n" + "$oneof_case$[$oneof_index$]);\n" "}\n", oneof); } } -bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, - size_t aux_offset) { - Formatter format(printer, variables_); - - if (!table_driven_) { - format("{ nullptr, nullptr, 0, -1, -1, -1, -1, nullptr, false },\n"); - return false; - } - - int max_field_number = 0; - for (auto field : FieldRange(descriptor_)) { - if (max_field_number < field->number()) { - max_field_number = field->number(); - } - } - - format("{\n"); - format.Indent(); - - format( - "$tablename$::entries + $1$,\n" - "$tablename$::aux + $2$,\n" - "$3$,\n", - offset, aux_offset, max_field_number); - - if (has_bit_indices_.empty()) { - // If no fields have hasbits, then _has_bits_ does not exist. - format("-1,\n"); - } else { - format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); - } - - if (descriptor_->real_oneof_decl_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n"); - } else { - format("-1, // no _oneof_case_\n"); - } - - if (descriptor_->extension_range_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n"); - } else { - format("-1, // no _extensions_\n"); - } - - // TODO(ckennelly): Consolidate this with the calculation for - // AuxiliaryParseTableField. - format( - "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n" - "&$package_ns$::_$classname$_default_instance_,\n"); - - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format("true,\n"); - } else { - format("false,\n"); - } - - format.Outdent(); - format("},\n"); - return true; -} - void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, int has_offset) { Formatter format(printer, variables_); @@ -2087,218 +2041,6 @@ void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, inlined_string_indices_offset); } -namespace { - -// We need to calculate for each field what function the table driven code -// should use to serialize it. This returns the index in a lookup table. -uint32_t CalcFieldNum(const FieldGenerator& generator, - const FieldDescriptor* field, const Options& options) { - bool is_a_map = IsMapEntryMessage(field->containing_type()); - int type = field->type(); - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - // string field - if (generator.IsInlined()) { - type = internal::FieldMetadata::kInlinedType; - } else if (IsCord(field, options)) { - type = internal::FieldMetadata::kCordType; - } else if (IsStringPiece(field, options)) { - type = internal::FieldMetadata::kStringPieceType; - } - } - - if (field->real_containing_oneof()) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kOneOf); - } else if (field->is_packed()) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kPacked); - } else if (field->is_repeated()) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kRepeated); - } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kPresence); - } else { - return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kNoPresence); - } -} - -int FindMessageIndexInFile(const Descriptor* descriptor) { - std::vector flatten = - FlattenMessagesInFile(descriptor->file()); - return std::find(flatten.begin(), flatten.end(), descriptor) - - flatten.begin(); -} - -} // namespace - -int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { - Formatter format(printer, variables_); - if (!options_.table_driven_serialization) { - return 0; - } - - std::vector sorted = SortFieldsByNumber(descriptor_); - if (IsMapEntryMessage(descriptor_)) { - for (int i = 0; i < 2; i++) { - const FieldDescriptor* field = sorted[i]; - const FieldGenerator& generator = field_generators_.get(field); - - uint32_t tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormat::WireTypeForFieldType(field->type())); - - std::map vars; - vars["classtype"] = QualifiedClassName(descriptor_, options_); - vars["field_name"] = FieldName(field); - vars["tag"] = StrCat(tag); - vars["hasbit"] = StrCat(i); - vars["type"] = StrCat(CalcFieldNum(generator, field, options_)); - vars["ptr"] = "nullptr"; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - GOOGLE_CHECK(!IsMapEntryMessage(field->message_type())); - vars["ptr"] = - "::" + UniqueName("TableStruct", field->message_type(), options_) + - "::serialization_table + " + - StrCat(FindMessageIndexInFile(field->message_type())); - } - Formatter::SaveState saver(&format); - format.AddMap(vars); - format( - "{PROTOBUF_FIELD_OFFSET(" - "::$proto_ns$::internal::MapEntryHelper<$classtype$::" - "SuperType>, $field_name$_), $tag$," - "PROTOBUF_FIELD_OFFSET(" - "::$proto_ns$::internal::MapEntryHelper<$classtype$::" - "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, " - "$ptr$},\n"); - } - return 2; - } - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_)," - " 0, 0, 0, nullptr},\n"); - std::vector sorted_extensions; - sorted_extensions.reserve(descriptor_->extension_range_count()); - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { - sorted_extensions.push_back(descriptor_->extension_range(i)); - } - std::sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeSorter()); - for (int i = 0, extension_idx = 0; /* no range */; i++) { - for (; extension_idx < sorted_extensions.size() && - (i == sorted.size() || - sorted_extensions[extension_idx]->start < sorted[i]->number()); - extension_idx++) { - const Descriptor::ExtensionRange* range = - sorted_extensions[extension_idx]; - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), " - "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(::$proto_ns$::internal::ExtensionSerializer)},\n", - range->start, range->end); - } - if (i == sorted.size()) break; - const FieldDescriptor* field = sorted[i]; - - uint32_t tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormat::WireTypeForFieldType(field->type())); - if (field->is_packed()) { - tag = internal::WireFormatLite::MakeTag( - field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - } - - std::string classfieldname = FieldName(field); - if (field->real_containing_oneof()) { - classfieldname = field->containing_oneof()->name(); - } - format.Set("field_name", classfieldname); - std::string ptr = "nullptr"; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (IsMapEntryMessage(field->message_type())) { - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(static_cast< " - "::$proto_ns$::internal::SpecialSerializer>(" - "::$proto_ns$::internal::MapFieldSerializer< " - "::$proto_ns$::internal::MapEntryToMapField<" - "$3$>::MapFieldType, " - "$tablename$::serialization_table>))},\n", - tag, FindMessageIndexInFile(field->message_type()), - QualifiedClassName(field->message_type(), options_)); - continue; - } else if (!field->message_type()->options().message_set_wire_format()) { - // message_set doesn't have the usual table and we need to - // dispatch to generated serializer, hence ptr stays zero. - ptr = - "::" + UniqueName("TableStruct", field->message_type(), options_) + - "::serialization_table + " + - StrCat(FindMessageIndexInFile(field->message_type())); - } - } - - const FieldGenerator& generator = field_generators_.get(field); - int type = CalcFieldNum(generator, field, options_); - - if (IsLazy(field, options_, scc_analyzer_)) { - type = internal::FieldMetadata::kSpecial; - ptr = "reinterpret_cast(::" + variables_["proto_ns"] + - "::internal::LazyFieldSerializer"; - if (field->real_containing_oneof()) { - ptr += "OneOf"; - } else if (!HasHasbit(field)) { - ptr += "NoPresence"; - } - ptr += ")"; - } - - if (field->options().weak()) { - // TODO(gerbens) merge weak fields into ranges - format( - "{PROTOBUF_FIELD_OFFSET(" - "$classtype$, _weak_field_map_), $1$, $1$, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, " - "reinterpret_cast(::$proto_ns$::internal::WeakFieldSerializer)},\n", - tag); - } else if (field->real_containing_oneof()) { - format.Set("oneofoffset", - sizeof(uint32_t) * field->containing_oneof()->index()); - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$," - " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + " - "$oneofoffset$, $2$, $3$},\n", - tag, type, ptr); - } else if (HasHasbit(field)) { - format.Set("hasbitsoffset", has_bit_indices_[field->index()]); - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), " - "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + " - "$hasbitsoffset$, $2$, $3$},\n", - tag, type, ptr); - } else { - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), " - "$1$, ~0u, $2$, $3$},\n", - tag, type, ptr); - } - } - int num_field_metadata = 1 + sorted.size() + sorted_extensions.size(); - num_field_metadata++; - std::string serializer = UseUnknownFieldSet(descriptor_->file(), options_) - ? "UnknownFieldSetSerializer" - : "UnknownFieldSerializerLite"; - format( - "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, " - "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast(::$proto_ns$::internal::$1$)},\n", - serializer); - return num_field_metadata; -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { @@ -2314,7 +2056,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" "$annotate_reflection$" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2322,7 +2064,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } else { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2339,7 +2081,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { " const ::$proto_ns$::Message& message,\n" " const ::$proto_ns$::FieldDescriptor** type_url_field,\n" " const ::$proto_ns$::FieldDescriptor** value_field) {\n" - " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n" + " return ::_pbi::GetAnyFieldDescriptors(\n" " message, type_url_field, value_field);\n" "}\n"); } @@ -2347,8 +2089,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { "bool $classname$::ParseAnyTypeUrl(\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n" " std::string* full_type_name) {\n" - " return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n" - " full_type_name);\n" + " return ::_pbi::ParseAnyTypeUrl(type_url, full_type_name);\n" "}\n" "\n"); } @@ -2359,7 +2100,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format.Indent(); if (!has_bit_indices_.empty()) { format( - "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n"); + "using HasBits = " + "decltype(std::declval<$classname$>().$has_bits$);\n"); } for (auto field : FieldRange(descriptor_)) { field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); @@ -2390,7 +2132,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format("};\n\n"); for (auto field : FieldRange(descriptor_)) { if (!IsFieldStripped(field, options_)) { - field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); + field_generators_.get(field).GenerateInternalAccessorDefinitions( + printer); } } @@ -2440,7 +2183,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { GenerateMergeFrom(printer); format("\n"); - GenerateClassSpecificMergeFrom(printer); + GenerateClassSpecificMergeImpl(printer); format("\n"); GenerateCopyFrom(printer); @@ -2450,25 +2193,26 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format("\n"); } + if (ShouldSplit(descriptor_, options_)) { + format( + "void $classname$::PrepareSplitMessageForWrite() {\n" + " if (IsSplitMessageDefault()) {\n" + " $split$ = CreateSplitMessage(GetArenaForAllocation());\n" + " }\n" + "}\n"); + } + GenerateVerify(printer); GenerateSwap(printer); format("\n"); - if (options_.table_driven_serialization) { - format( - "const void* $classname$::InternalGetTable() const {\n" - " return ::$tablename$::serialization_table + $1$;\n" - "}\n" - "\n", - index_in_file_messages_); - } if (HasDescriptorMethods(descriptor_->file(), options_)) { if (!descriptor_->options().map_entry()) { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" "$annotate_reflection$" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2476,7 +2220,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { } else { format( "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::$proto_ns$::internal::AssignDescriptors(\n" + " return ::_pbi::AssignDescriptors(\n" " &$desc_table$_getter, &$desc_table$_once,\n" " $file_level_metadata$[$1$]);\n" "}\n", @@ -2490,239 +2234,43 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { "\n"); } - if (options_.field_listener_options.inject_field_listener_events && - descriptor_->file()->options().optimize_for() != - google::protobuf::FileOptions::LITE_RUNTIME) { + if (HasTracker(descriptor_, options_)) { format( "::$proto_ns$::AccessListener<$classtype$> " - "$1$::_tracker_(&FullMessageName);\n", + "$1$::$tracker$(&FullMessageName);\n", ClassName(descriptor_)); } } -size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { - Formatter format(printer, variables_); - - if (!table_driven_) { - return 0; - } - - // Field "0" is special: We use it in our switch statement of processing - // types to handle the successful end tag case. - format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n"); - int last_field_number = 1; - - std::vector ordered_fields = - SortFieldsByNumber(descriptor_); - - for (auto field : ordered_fields) { - Formatter::SaveState saver(&format); - GOOGLE_CHECK_GE(field->number(), last_field_number); - - for (; last_field_number < field->number(); last_field_number++) { - format( - "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n" - " ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n"); - } - last_field_number++; - - unsigned char normal_wiretype, packed_wiretype, processing_type; - normal_wiretype = WireFormat::WireTypeForFieldType(field->type()); - - if (field->is_packable()) { - packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - } else { - packed_wiretype = internal::kNotPackedMask; - } - - processing_type = static_cast(field->type()); - const FieldGenerator& generator = field_generators_.get(field); - if (field->type() == FieldDescriptor::TYPE_STRING) { - switch (EffectiveStringCType(field, options_)) { - case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_STRING_INLINED; - } - break; - case FieldOptions::CORD: - processing_type = internal::TYPE_STRING_CORD; - break; - case FieldOptions::STRING_PIECE: - processing_type = internal::TYPE_STRING_STRING_PIECE; - break; - } - } else if (field->type() == FieldDescriptor::TYPE_BYTES) { - switch (EffectiveStringCType(field, options_)) { - case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_BYTES_INLINED; - } - break; - case FieldOptions::CORD: - processing_type = internal::TYPE_BYTES_CORD; - break; - case FieldOptions::STRING_PIECE: - processing_type = internal::TYPE_BYTES_STRING_PIECE; - break; - } - } - - processing_type |= static_cast( - field->is_repeated() ? internal::kRepeatedMask : 0); - processing_type |= static_cast( - field->real_containing_oneof() ? internal::kOneofMask : 0); - - if (field->is_map()) { - processing_type = internal::TYPE_MAP; - } - - const unsigned char tag_size = - WireFormat::TagSize(field->number(), field->type()); - - std::map vars; - if (field->real_containing_oneof()) { - vars["name"] = field->containing_oneof()->name(); - vars["presence"] = StrCat(field->containing_oneof()->index()); - } else { - vars["name"] = FieldName(field); - vars["presence"] = StrCat(has_bit_indices_[field->index()]); - } - vars["nwtype"] = StrCat(normal_wiretype); - vars["pwtype"] = StrCat(packed_wiretype); - vars["ptype"] = StrCat(processing_type); - vars["tag_size"] = StrCat(tag_size); - - format.AddMap(vars); - - format( - "{\n" - " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n" - " static_cast<$uint32$>($presence$),\n" - " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" - "},\n"); - } - - return last_field_number; -} - -size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { - Formatter format(printer, variables_); - - if (!table_driven_) { - return 0; - } - - std::vector ordered_fields = - SortFieldsByNumber(descriptor_); - - format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); - int last_field_number = 1; - for (auto field : ordered_fields) { - Formatter::SaveState saver(&format); - - GOOGLE_CHECK_GE(field->number(), last_field_number); - for (; last_field_number < field->number(); last_field_number++) { - format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); - } - - std::map vars; - SetCommonFieldVariables(field, &vars, options_); - format.AddMap(vars); - - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_ENUM: - if (HasPreservingUnknownEnumSemantics(field)) { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" - "nullptr}},\n"); - } else { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" - "$1$_IsValid}},\n", - ClassName(field->enum_type(), true)); - } - last_field_number++; - break; - case FieldDescriptor::CPPTYPE_MESSAGE: { - if (field->is_map()) { - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::map_" - "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n", - QualifiedClassName(field->message_type(), options_)); - last_field_number++; - break; - } - format.Set("field_classname", ClassName(field->message_type(), false)); - format.Set("default_instance", QualifiedDefaultInstanceName( - field->message_type(), options_)); - - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::message_aux{\n" - " &$default_instance$}},\n"); - last_field_number++; - break; - } - case FieldDescriptor::CPPTYPE_STRING: { - std::string default_val; - switch (EffectiveStringCType(field, options_)) { - case FieldOptions::STRING: - default_val = field->default_value_string().empty() - ? "&::" + variables_["proto_ns"] + - "::internal::fixed_address_empty_string" - : "&" + - QualifiedClassName(descriptor_, options_) + - "::" + MakeDefaultName(field); - break; - case FieldOptions::CORD: - case FieldOptions::STRING_PIECE: - default_val = - "\"" + CEscape(field->default_value_string()) + "\""; - break; - } - format( - "{::$proto_ns$::internal::AuxiliaryParseTableField::string_aux{\n" - " $1$,\n" - " \"$2$\"\n" - "}},\n", - default_val, field->full_name()); - last_field_number++; - break; - } - default: - break; - } - } - - return last_field_number; -} - std::pair MessageGenerator::GenerateOffsets( io::Printer* printer) { Formatter format(printer, variables_); if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $has_bits$),\n"); } else { format("~0u, // no _has_bits_\n"); } format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"); if (descriptor_->extension_range_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $extensions$),\n"); } else { format("~0u, // no _extensions_\n"); } if (descriptor_->real_oneof_decl_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$[0]),\n"); } else { format("~0u, // no _oneof_case_\n"); } if (num_weak_fields_ > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $weak_field_map$),\n"); } else { format("~0u, // no _weak_field_map_\n"); } if (!inlined_string_indices_.empty()) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n"); + format( + "PROTOBUF_FIELD_OFFSET($classtype$, " + "$inlined_string_donated_array$),\n"); } else { format("~0u, // no _inlined_string_donated_\n"); } @@ -2740,9 +2288,13 @@ std::pair MessageGenerator::GenerateOffsets( if (field->options().weak() || field->real_containing_oneof()) { // Mark the field to prevent unintentional access through reflection. // Don't use the top bit because that is for unused fields. - format("::$proto_ns$::internal::kInvalidFieldOffsetTag"); + format("::_pbi::kInvalidFieldOffsetTag"); } else { - format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); + format("PROTOBUF_FIELD_OFFSET($classtype$$1$, $2$)", + ShouldSplit(field, options_) ? "::Impl_::Split" : "", + ShouldSplit(field, options_) + ? FieldName(field) + "_" + : FieldMemberName(field, /*cold=*/false)); } // Some information about a field is in the pdproto profile. The profile is @@ -2750,11 +2302,6 @@ std::pair MessageGenerator::GenerateOffsets( // offset of the field, so that the information is available when // reflectively accessing the field at run time. // - // Embed whether the field is used to the MSB of the offset. - if (!IsFieldUsed(field, options_)) { - format(" | 0x80000000u // unused\n"); - } - // Embed whether the field is eagerly verified lazy or inlined string to the // LSB of the offset. if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { @@ -2767,7 +2314,7 @@ std::pair MessageGenerator::GenerateOffsets( int count = 0; for (auto oneof : OneOfRange(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name()); + format("PROTOBUF_FIELD_OFFSET($classtype$, _impl_.$1$_),\n", oneof->name()); count++; } GOOGLE_CHECK_EQ(count, descriptor_->real_oneof_decl_count()); @@ -2787,11 +2334,12 @@ std::pair MessageGenerator::GenerateOffsets( } if (!inlined_string_indices_.empty()) { entries += inlined_string_indices_.size(); - for (int inlined_string_indice : inlined_string_indices_) { - const std::string index = inlined_string_indice >= 0 - ? StrCat(inlined_string_indice) - : "~0u"; - format("$1$,\n", index); + for (int inlined_string_index : inlined_string_indices_) { + const std::string index = + inlined_string_index >= 0 + ? StrCat(inlined_string_index, ", // inlined_string_index") + : "~0u,"; + format("$1$\n", index); } } @@ -2802,18 +2350,181 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) { if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); - format("inline void $classname$::SharedCtor() {\n"); + format( + "inline void $classname$::SharedCtor(\n" + " ::_pb::Arena* arena, bool is_message_owned) {\n" + " (void)arena;\n" + " (void)is_message_owned;\n"); - std::vector processed(optimized_order_.size(), false); - GenerateConstructorBody(printer, processed, false); + format.Indent(); + // Impl_ _impl_. + format("new (&_impl_) Impl_{"); + format.Indent(); + const char* field_sep = " "; + const auto put_sep = [&] { + format("\n$1$ ", field_sep); + field_sep = ","; + }; + + // Note: any fields without move/copy constructors can't be explicitly + // aggregate initialized pre-C++17. + if (descriptor_->extension_range_count() > 0) { + put_sep(); + format("/*decltype($extensions$)*/{::_pbi::ArenaInitialized(), arena}"); + } + if (!inlined_string_indices_.empty()) { + put_sep(); + format("decltype($inlined_string_donated_array$){}"); + } + bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); + if (!has_bit_indices_.empty()) { + put_sep(); + format("decltype($has_bits$){}"); + if (need_to_emit_cached_size) { + put_sep(); + format("/*decltype($cached_size$)*/{}"); + need_to_emit_cached_size = false; + } + } + + // Initialize member variables with arena constructor. + for (auto field : optimized_order_) { + GOOGLE_DCHECK(!IsFieldStripped(field, options_)); + if (ShouldSplit(field, options_)) { + continue; + } + put_sep(); + field_generators_.get(field).GenerateAggregateInitializer(printer); + } + if (ShouldSplit(descriptor_, options_)) { + put_sep(); + format("decltype($split$){reinterpret_cast(&$1$)}", + DefaultInstanceName(descriptor_, options_, /*split=*/true)); + } + for (auto oneof : OneOfRange(descriptor_)) { + put_sep(); + format("decltype(_impl_.$1$_){}", oneof->name()); + } + + if (need_to_emit_cached_size) { + put_sep(); + format("/*decltype($cached_size$)*/{}"); + } + + if (descriptor_->real_oneof_decl_count() != 0) { + put_sep(); + format("/*decltype($oneof_case$)*/{}"); + } + if (num_weak_fields_ > 0) { + put_sep(); + format("decltype($weak_field_map$){arena}"); + } + if (IsAnyMessage(descriptor_, options_)) { + put_sep(); + // AnyMetadata has no move constructor. + format("/*decltype($any_metadata$)*/{&_impl_.type_url_, &_impl_.value_}"); + } + + format.Outdent(); + format("\n};\n"); + + if (!inlined_string_indices_.empty()) { + // Donate inline string fields. + format.Indent(); + // The last bit is the tracking bit for registering ArenaDtor. The bit is 1 + // means ArenaDtor is not registered on construction, and on demand register + // is needed. + format("if (arena != nullptr) {\n"); + if (NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand) { + format( + " if (!is_message_owned) {\n" + " $inlined_string_donated_array$[0] = ~0u;\n" + " } else {\n" + // We should not register ArenaDtor for MOA. + " $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n" + " }\n"); + } else { + format(" $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n"); + } + for (size_t i = 1; i < InlinedStringDonatedSize(); ++i) { + format(" $inlined_string_donated_array$[$1$] = ~0u;\n", i); + } + format("}\n"); + format.Outdent(); + } + + for (const FieldDescriptor* field : optimized_order_) { + if (ShouldSplit(field, options_)) { + continue; + } + field_generators_.get(field).GenerateConstructorCode(printer); + } for (auto oneof : OneOfRange(descriptor_)) { format("clear_has_$1$();\n", oneof->name()); } + format.Outdent(); format("}\n\n"); } +void MessageGenerator::GenerateCreateSplitMessage(io::Printer* printer) { + Formatter format(printer, variables_); + format( + "$classname$::Impl_::Split* " + "$classname$::CreateSplitMessage(::$proto_ns$::Arena* arena) {\n"); + format.Indent(); + const char* field_sep = " "; + const auto put_sep = [&] { + format("\n$1$ ", field_sep); + field_sep = ","; + }; + format( + "const size_t size = sizeof(Impl_::Split);\n" + "void* chunk = (arena == nullptr) ?\n" + " ::operator new(size) :\n" + " arena->AllocateAligned(size, alignof(Impl_::Split));\n" + "Impl_::Split* ptr = reinterpret_cast(chunk);\n" + "new (ptr) Impl_::Split{"); + format.Indent(); + for (const FieldDescriptor* field : optimized_order_) { + GOOGLE_DCHECK(!IsFieldStripped(field, options_)); + if (ShouldSplit(field, options_)) { + put_sep(); + field_generators_.get(field).GenerateAggregateInitializer(printer); + } + } + format.Outdent(); + format("};\n"); + for (const FieldDescriptor* field : optimized_order_) { + GOOGLE_DCHECK(!IsFieldStripped(field, options_)); + if (ShouldSplit(field, options_)) { + field_generators_.get(field).GenerateCreateSplitMessageCode(printer); + } + } + format("return ptr;\n"); + format.Outdent(); + format("}\n"); +} + +void MessageGenerator::GenerateInitDefaultSplitInstance(io::Printer* printer) { + if (!ShouldSplit(descriptor_, options_)) return; + + Formatter format(printer, variables_); + const char* field_sep = " "; + const auto put_sep = [&] { + format("\n$1$ ", field_sep); + field_sep = ","; + }; + for (const auto* field : optimized_order_) { + if (ShouldSplit(field, options_)) { + put_sep(); + field_generators_.get(field).GenerateConstexprAggregateInitializer( + printer); + } + } +} + void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); @@ -2821,11 +2532,32 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { format("inline void $classname$::SharedDtor() {\n"); format.Indent(); format("$DCHK$(GetArenaForAllocation() == nullptr);\n"); + + if (descriptor_->extension_range_count() > 0) { + format("$extensions$.~ExtensionSet();\n"); + } + // Write the destructors for each field except oneof members. // optimized_order_ does not contain oneof fields. for (auto field : optimized_order_) { + if (ShouldSplit(field, options_)) { + continue; + } field_generators_.get(field).GenerateDestructorCode(printer); } + if (ShouldSplit(descriptor_, options_)) { + format("if (!IsSplitMessageDefault()) {\n"); + format.Indent(); + format("auto* $cached_split_ptr$ = $split$;\n"); + for (auto field : optimized_order_) { + if (ShouldSplit(field, options_)) { + field_generators_.get(field).GenerateDestructorCode(printer); + } + } + format("delete $cached_split_ptr$;\n"); + format.Outdent(); + format("}\n"); + } // Generate code to destruct oneofs. Clearing should do the work. for (auto oneof : OneOfRange(descriptor_)) { @@ -2837,16 +2569,33 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } + + if (IsAnyMessage(descriptor_, options_)) { + format("$any_metadata$.~AnyMetadata();\n"); + } + format.Outdent(); format( "}\n" "\n"); } +ArenaDtorNeeds MessageGenerator::NeedsArenaDestructor() const { + if (HasSimpleBaseClass(descriptor_, options_)) return ArenaDtorNeeds::kNone; + ArenaDtorNeeds needs = ArenaDtorNeeds::kNone; + for (const auto* field : FieldRange(descriptor_)) { + if (IsFieldStripped(field, options_)) continue; + needs = + std::max(needs, field_generators_.get(field).NeedsArenaDestructor()); + } + return needs; +} + void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { - if (HasSimpleBaseClass(descriptor_, options_)) return; + GOOGLE_CHECK(NeedsArenaDestructor() > ArenaDtorNeeds::kNone); + Formatter format(printer, variables_); // Generate the ArenaDtor() method. Track whether any fields actually produced @@ -2858,119 +2607,155 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { // since that simplifies Arena's destructor list (ordinary function pointers // rather than member function pointers). _this is the object being // destructed. - format( - "$classname$* _this = reinterpret_cast< $classname$* >(object);\n" - // avoid an "unused variable" warning in case no fields have dtor code. - "(void)_this;\n"); + format("$classname$* _this = reinterpret_cast< $classname$* >(object);\n"); - bool need_registration = false; // Process non-oneof fields first. for (auto field : optimized_order_) { - if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) { - need_registration = true; + if (IsFieldStripped(field, options_) || ShouldSplit(field, options_)) + continue; + const FieldGenerator& fg = field_generators_.get(field); + fg.GenerateArenaDestructorCode(printer); + } + if (ShouldSplit(descriptor_, options_)) { + format("if (!_this->IsSplitMessageDefault()) {\n"); + format.Indent(); + for (auto field : optimized_order_) { + if (IsFieldStripped(field, options_) || !ShouldSplit(field, options_)) + continue; + const FieldGenerator& fg = field_generators_.get(field); + fg.GenerateArenaDestructorCode(printer); } + format.Outdent(); + format("}\n"); } // Process oneof fields. - // - // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything - // and returns false for oneof fields. for (auto oneof : OneOfRange(descriptor_)) { for (auto field : FieldRange(oneof)) { - if (!IsFieldStripped(field, options_) && - field_generators_.get(field).GenerateArenaDestructorCode(printer)) { - need_registration = true; - } + if (IsFieldStripped(field, options_)) continue; + field_generators_.get(field).GenerateArenaDestructorCode(printer); } } format.Outdent(); format("}\n"); - - if (need_registration) { - format( - "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* " - "arena) {\n" - " if (arena != nullptr) {\n" - " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" - " }\n" - "}\n"); - } else { - format( - "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n" - "}\n"); - } } void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) { Formatter format(printer, variables_); + if (IsMapEntryMessage(descriptor_) || !HasImplData(descriptor_, options_)) { + format( + "PROTOBUF_CONSTEXPR $classname$::$classname$(\n" + " ::_pbi::ConstantInitialized) {}\n"); + return; + } + format( - "constexpr $classname$::$classname$(\n" - " ::$proto_ns$::internal::ConstantInitialized)"); + "PROTOBUF_CONSTEXPR $classname$::$classname$(\n" + " ::_pbi::ConstantInitialized)"); + + bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); + format(": _impl_{"); format.Indent(); - const char* field_sep = ":"; + const char* field_sep = " "; const auto put_sep = [&] { format("\n$1$ ", field_sep); field_sep = ","; }; - - if (!IsMapEntryMessage(descriptor_)) { - // Process non-oneof fields first. - for (auto field : optimized_order_) { - auto& gen = field_generators_.get(field); + if (descriptor_->extension_range_count() > 0) { + put_sep(); + format("/*decltype($extensions$)*/{}"); + } + if (!inlined_string_indices_.empty()) { + put_sep(); + format("/*decltype($inlined_string_donated_array$)*/{}"); + } + if (!has_bit_indices_.empty()) { + put_sep(); + format("/*decltype($has_bits$)*/{}"); + if (need_to_emit_cached_size) { put_sep(); - gen.GenerateConstinitInitializer(printer); + format("/*decltype($cached_size$)*/{}"); + need_to_emit_cached_size = false; } + } + for (auto field : optimized_order_) { + if (ShouldSplit(field, options_)) { + continue; + } + put_sep(); + field_generators_.get(field).GenerateConstexprAggregateInitializer( + printer); + } + if (ShouldSplit(descriptor_, options_)) { + put_sep(); + format("/*decltype($split$)*/&$1$._instance", + DefaultInstanceName(descriptor_, options_, /*split=*/true)); + } - if (IsAnyMessage(descriptor_, options_)) { - put_sep(); - format("_any_metadata_(&type_url_, &value_)"); - } + for (auto oneof : OneOfRange(descriptor_)) { + put_sep(); + format("/*decltype(_impl_.$1$_)*/{}", oneof->name()); + } - if (descriptor_->real_oneof_decl_count() != 0) { - put_sep(); - format("_oneof_case_{}"); - } + if (need_to_emit_cached_size) { + put_sep(); + format("/*decltype($cached_size$)*/{}"); + } + + if (descriptor_->real_oneof_decl_count() != 0) { + put_sep(); + format("/*decltype($oneof_case$)*/{}"); + } + + if (num_weak_fields_) { + put_sep(); + format("/*decltype($weak_field_map$)*/{}"); + } + + if (IsAnyMessage(descriptor_, options_)) { + put_sep(); + format( + "/*decltype($any_metadata$)*/{&_impl_.type_url_, " + "&_impl_.value_}"); } format.Outdent(); - format("{}\n"); + format("} {}\n"); } -void MessageGenerator::GenerateConstructorBody(io::Printer* printer, - std::vector processed, - bool copy_constructor) const { +void MessageGenerator::GenerateCopyConstructorBody(io::Printer* printer) const { Formatter format(printer, variables_); - const RunMap runs = FindRuns( - optimized_order_, [copy_constructor, this](const FieldDescriptor* field) { - return (copy_constructor && IsPOD(field)) || - (!copy_constructor && - CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_)); + const RunMap runs = + FindRuns(optimized_order_, [this](const FieldDescriptor* field) { + return IsPOD(field) && !ShouldSplit(field, options_); }); - std::string pod_template; - if (copy_constructor) { - pod_template = - "::memcpy(&$first$_, &from.$first$_,\n" - " static_cast(reinterpret_cast(&$last$_) -\n" - " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; - } else { - pod_template = - "::memset(reinterpret_cast(this) + static_cast(\n" - " reinterpret_cast(&$first$_) - " - "reinterpret_cast(this)),\n" - " 0, static_cast(reinterpret_cast(&$last$_) -\n" - " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; + std::string pod_template = + "::memcpy(&$first$, &from.$first$,\n" + " static_cast(reinterpret_cast(&$last$) -\n" + " reinterpret_cast(&$first$)) + sizeof($last$));\n"; + + if (ShouldSplit(descriptor_, options_)) { + format("if (!from.IsSplitMessageDefault()) {\n"); + format.Indent(); + format("_this->PrepareSplitMessageForWrite();\n"); + for (auto field : optimized_order_) { + if (ShouldSplit(field, options_)) { + field_generators_.get(field).GenerateCopyConstructorCode(printer); + } + } + format.Outdent(); + format("}\n"); } - for (int i = 0; i < optimized_order_.size(); ++i) { - if (processed[i]) { + for (size_t i = 0; i < optimized_order_.size(); ++i) { + const FieldDescriptor* field = optimized_order_[i]; + if (ShouldSplit(field, options_)) { continue; } - - const FieldDescriptor* field = optimized_order_[i]; const auto it = runs.find(field); // We only apply the memset technique to runs of more than one field, as @@ -2978,9 +2763,10 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, if (it != runs.end() && it->second > 1) { // Use a memset, then skip run_length fields. const size_t run_length = it->second; - const std::string first_field_name = FieldName(field); + const std::string first_field_name = + FieldMemberName(field, /*cold=*/false); const std::string last_field_name = - FieldName(optimized_order_[i + run_length - 1]); + FieldMemberName(optimized_order_[i + run_length - 1], /*cold=*/false); format.Set("first", first_field_name); format.Set("last", last_field_name); @@ -2990,11 +2776,7 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, i += run_length - 1; // ++i at the top of the loop. } else { - if (copy_constructor) { - field_generators_.get(field).GenerateCopyConstructorCode(printer); - } else { - field_generators_.get(field).GenerateConstructorCode(printer); - } + field_generators_.get(field).GenerateCopyConstructorCode(printer); } } } @@ -3002,66 +2784,20 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, void MessageGenerator::GenerateStructors(io::Printer* printer) { Formatter format(printer, variables_); - std::string superclass; - superclass = SuperClassName(descriptor_, options_); - std::string initializer_with_arena = superclass + "(arena, is_message_owned)"; - - if (descriptor_->extension_range_count() > 0) { - initializer_with_arena += ",\n _extensions_(arena)"; - } - - // Initialize member variables with arena constructor. - for (auto field : optimized_order_) { - GOOGLE_DCHECK(!IsFieldStripped(field, options_)); - bool has_arena_constructor = field->is_repeated(); - if (!field->real_containing_oneof() && - (IsLazy(field, options_, scc_analyzer_) || - IsStringPiece(field, options_) || - (IsString(field, options_) && IsStringInlined(field, options_)))) { - has_arena_constructor = true; - } - if (has_arena_constructor) { - initializer_with_arena += - std::string(",\n ") + FieldName(field) + std::string("_(arena)"); - } - } - - if (IsAnyMessage(descriptor_, options_)) { - initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)"; - } - if (num_weak_fields_ > 0) { - initializer_with_arena += ", _weak_field_map_(arena)"; - } - - std::string initializer_null = superclass + "()"; - if (IsAnyMessage(descriptor_, options_)) { - initializer_null += ", _any_metadata_(&type_url_, &value_)"; - } - if (num_weak_fields_ > 0) { - initializer_null += ", _weak_field_map_(nullptr)"; - } - format( "$classname$::$classname$(::$proto_ns$::Arena* arena,\n" " bool is_message_owned)\n" - " : $1$ {\n", - initializer_with_arena); - - if (!inlined_string_indices_.empty()) { - // Donate inline string fields. - format(" if (arena != nullptr) {\n"); - for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { - format(" _inlined_string_donated_[$1$] = ~0u;\n", i); - } - format(" }\n"); - } + " : $1$(arena, is_message_owned) {\n", + SuperClassName(descriptor_, options_)); if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - " SharedCtor();\n" - " if (!is_message_owned) {\n" - " RegisterArenaDtor(arena);\n" - " }\n"); + format(" SharedCtor(arena, is_message_owned);\n"); + if (NeedsArenaDestructor() == ArenaDtorNeeds::kRequired) { + format( + " if (arena != nullptr && !is_message_owned) {\n" + " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" + " }\n"); + } } format( " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" @@ -3085,40 +2821,81 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { } else { format( "$classname$::$classname$(const $classname$& from)\n" - " : $superclass$()"); - format.Indent(); - format.Indent(); + " : $superclass$() {\n"); format.Indent(); + format("$classname$* const _this = this; (void)_this;\n"); - // Do not copy inlined_string_donated_, because this is not an arena - // constructor. + if (HasImplData(descriptor_, options_)) { + const char* field_sep = " "; + const auto put_sep = [&] { + format("\n$1$ ", field_sep); + field_sep = ","; + }; - if (!has_bit_indices_.empty()) { - format(",\n_has_bits_(from._has_bits_)"); - } + format("new (&_impl_) Impl_{"); + format.Indent(); - std::vector processed(optimized_order_.size(), false); - for (int i = 0; i < optimized_order_.size(); i++) { - auto field = optimized_order_[i]; - if (!(field->is_repeated() && !(field->is_map())) && - !IsCord(field, options_)) { - continue; + if (descriptor_->extension_range_count() > 0) { + put_sep(); + format("/*decltype($extensions$)*/{}"); + } + if (!inlined_string_indices_.empty()) { + // Do not copy inlined_string_donated_, because this is not an arena + // constructor. + put_sep(); + format("decltype($inlined_string_donated_array$){}"); + } + bool need_to_emit_cached_size = + !HasSimpleBaseClass(descriptor_, options_); + if (!has_bit_indices_.empty()) { + put_sep(); + format("decltype($has_bits$){from.$has_bits$}"); + if (need_to_emit_cached_size) { + put_sep(); + format("/*decltype($cached_size$)*/{}"); + need_to_emit_cached_size = false; + } } - processed[i] = true; - format(",\n$1$_(from.$1$_)", FieldName(field)); - } + // Initialize member variables with arena constructor. + for (auto field : optimized_order_) { + if (ShouldSplit(field, options_)) { + continue; + } + put_sep(); + field_generators_.get(field).GenerateCopyAggregateInitializer(printer); + } + if (ShouldSplit(descriptor_, options_)) { + put_sep(); + format("decltype($split$){reinterpret_cast(&$1$)}", + DefaultInstanceName(descriptor_, options_, /*split=*/true)); + } + for (auto oneof : OneOfRange(descriptor_)) { + put_sep(); + format("decltype(_impl_.$1$_){}", oneof->name()); + } - if (IsAnyMessage(descriptor_, options_)) { - format(",\n_any_metadata_(&type_url_, &value_)"); - } - if (num_weak_fields_ > 0) { - format(",\n_weak_field_map_(from._weak_field_map_)"); - } + if (need_to_emit_cached_size) { + put_sep(); + format("/*decltype($cached_size$)*/{}"); + } - format.Outdent(); - format.Outdent(); - format(" {\n"); + if (descriptor_->real_oneof_decl_count() != 0) { + put_sep(); + format("/*decltype($oneof_case$)*/{}"); + } + if (num_weak_fields_ > 0) { + put_sep(); + format("decltype($weak_field_map$){from.$weak_field_map$}"); + } + if (IsAnyMessage(descriptor_, options_)) { + put_sep(); + format( + "/*decltype($any_metadata$)*/{&_impl_.type_url_, &_impl_.value_}"); + } + format.Outdent(); + format("};\n\n"); + } format( "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_" @@ -3126,11 +2903,11 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } - GenerateConstructorBody(printer, processed, true); + GenerateCopyConstructorBody(printer); // Copy oneof fields. Oneof field requires oneof case check. for (auto oneof : OneOfRange(descriptor_)) { @@ -3168,14 +2945,27 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { // Generate the shared constructor code. GenerateSharedConstructorCode(printer); + if (ShouldSplit(descriptor_, options_)) { + GenerateCreateSplitMessage(printer); + } + // Generate the destructor. if (!HasSimpleBaseClass(descriptor_, options_)) { format( "$classname$::~$classname$() {\n" - " // @@protoc_insertion_point(destructor:$full_name$)\n" - " if (GetArenaForAllocation() != nullptr) return;\n" + " // @@protoc_insertion_point(destructor:$full_name$)\n"); + format( + " if (auto *arena = " + "_internal_metadata_.DeleteReturnArena<$unknown_fields_type$>()) {\n" + " (void)arena;\n"); + if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) { + format(" ArenaDtor(this);\n"); + } + format( + " return;\n" + " }\n"); + format( " SharedDtor();\n" - " _internal_metadata_.Delete<$unknown_fields_type$>();\n" "}\n" "\n"); } else { @@ -3190,13 +2980,15 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { GenerateSharedDestructorCode(printer); // Generate the arena-specific destructor code. - GenerateArenaDestructorCode(printer); + if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) { + GenerateArenaDestructorCode(printer); + } if (!HasSimpleBaseClass(descriptor_, options_)) { // Generate SetCachedSize. format( "void $classname$::SetCachedSize(int size) const {\n" - " _cached_size_.Set(size);\n" + " $cached_size$.Set(size);\n" "}\n"); } } @@ -3205,8 +2997,8 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { Formatter format(printer, variables_); format( "template<> " - "PROTOBUF_NOINLINE " - "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" + "PROTOBUF_NOINLINE $classtype$*\n" + "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" "}\n"); } @@ -3232,7 +3024,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "(void) cached_has_bits;\n\n"); if (descriptor_->extension_range_count() > 0) { - format("_extensions_.Clear();\n"); + format("$extensions$.Clear();\n"); } // Collect fields into chunks. Each chunk may have an if() condition that @@ -3254,6 +3046,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { // (memset) per chunk, and if present it will be at the beginning. bool same = HasByteIndex(a) == HasByteIndex(b) && a->is_repeated() == b->is_repeated() && + ShouldSplit(a, options_) == ShouldSplit(b, options_) && (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) || (CanInitializeByZeroing(a) && (chunk_count == 1 || merge_zero_init))); @@ -3261,7 +3054,8 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { return same; }); - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); + ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_, + kColdRatio); int cached_has_word_index = -1; for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { @@ -3271,7 +3065,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { const FieldDescriptor* memset_start = nullptr; const FieldDescriptor* memset_end = nullptr; bool saw_non_zero_init = false; - + bool chunk_is_cold = !chunk.empty() && ShouldSplit(chunk.front(), options_); for (const auto& field : chunk) { if (CanInitializeByZeroing(field)) { GOOGLE_CHECK(!saw_non_zero_init); @@ -3305,23 +3099,31 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); } + if (chunk_is_cold) { + format("if (!IsSplitMessageDefault()) {\n"); + format.Indent(); + } + if (memset_start) { if (memset_start == memset_end) { // For clarity, do not memset a single field. field_generators_.get(memset_start) .GenerateMessageClearingCode(printer); } else { + GOOGLE_CHECK_EQ(chunk_is_cold, ShouldSplit(memset_start, options_)); + GOOGLE_CHECK_EQ(chunk_is_cold, ShouldSplit(memset_end, options_)); format( - "::memset(&$1$_, 0, static_cast(\n" - " reinterpret_cast(&$2$_) -\n" - " reinterpret_cast(&$1$_)) + sizeof($2$_));\n", - FieldName(memset_start), FieldName(memset_end)); + "::memset(&$1$, 0, static_cast(\n" + " reinterpret_cast(&$2$) -\n" + " reinterpret_cast(&$1$)) + sizeof($2$));\n", + FieldMemberName(memset_start, chunk_is_cold), + FieldMemberName(memset_end, chunk_is_cold)); } } @@ -3350,6 +3152,11 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { } } + if (chunk_is_cold) { + format.Outdent(); + format("}\n"); + } + if (have_outer_if) { format.Outdent(); format("}\n"); @@ -3367,14 +3174,14 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } // We don't clear donated status. if (!has_bit_indices_.empty()) { // Step 5: Everything else. - format("_has_bits_.Clear();\n"); + format("$has_bits$.Clear();\n"); } std::map vars; @@ -3420,7 +3227,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format.Outdent(); format( "}\n" - "_oneof_case_[$1$] = $2$_NOT_SET;\n", + "$oneof_case$[$1$] = $2$_NOT_SET;\n", i, ToUpper(oneof->name())); format.Outdent(); format( @@ -3440,13 +3247,15 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (HasGeneratedMethods(descriptor_->file(), options_)) { if (descriptor_->extension_range_count() > 0) { - format("_extensions_.InternalSwap(&other->_extensions_);\n"); + format( + "$extensions$.InternalSwap(&other->$extensions$);" + "\n"); } std::map vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); - if (HasSingularString(descriptor_, options_)) { + if (HasNonSplitOptionalString(descriptor_, options_)) { format( "auto* lhs_arena = GetArenaForAllocation();\n" "auto* rhs_arena = other->GetArenaForAllocation();\n"); @@ -3455,18 +3264,22 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (!has_bit_indices_.empty()) { for (int i = 0; i < HasBitsSize(); ++i) { - format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); + format("swap($has_bits$[$1$], other->$has_bits$[$1$]);\n", i); } } // If possible, we swap several fields at once, including padding. const RunMap runs = FindRuns(optimized_order_, [this](const FieldDescriptor* field) { - return CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_); + return !ShouldSplit(field, options_) && + CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_); }); - for (int i = 0; i < optimized_order_.size(); ++i) { + for (size_t i = 0; i < optimized_order_.size(); ++i) { const FieldDescriptor* field = optimized_order_[i]; + if (ShouldSplit(field, options_)) { + continue; + } const auto it = runs.find(field); // We only apply the memswap technique to runs of more than one field, as @@ -3475,20 +3288,21 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (it != runs.end() && it->second > 1) { // Use a memswap, then skip run_length fields. const size_t run_length = it->second; - const std::string first_field_name = FieldName(field); - const std::string last_field_name = - FieldName(optimized_order_[i + run_length - 1]); + const std::string first_field_name = + FieldMemberName(field, /*cold=*/false); + const std::string last_field_name = FieldMemberName( + optimized_order_[i + run_length - 1], /*cold=*/false); format.Set("first", first_field_name); format.Set("last", last_field_name); format( "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n" - " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n" - " + sizeof($classname$::$last$_)\n" - " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n" - " reinterpret_cast(&$first$_),\n" - " reinterpret_cast(&other->$first$_));\n"); + " PROTOBUF_FIELD_OFFSET($classname$, $last$)\n" + " + sizeof($classname$::$last$)\n" + " - PROTOBUF_FIELD_OFFSET($classname$, $first$)>(\n" + " reinterpret_cast(&$first$),\n" + " reinterpret_cast(&other->$first$));\n"); i += run_length - 1; // ++i at the top of the loop. @@ -3496,17 +3310,31 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { field_generators_.get(field).GenerateSwappingCode(printer); } } + if (ShouldSplit(descriptor_, options_)) { + format("swap($split$, other->$split$);\n"); + } for (auto oneof : OneOfRange(descriptor_)) { - format("swap($1$_, other->$1$_);\n", oneof->name()); + format("swap(_impl_.$1$_, other->_impl_.$1$_);\n", oneof->name()); } for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { - format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); + format("swap($oneof_case$[$1$], other->$oneof_case$[$1$]);\n", i); } if (num_weak_fields_) { - format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n"); + format( + "$weak_field_map$.UnsafeArenaSwap(&other->$weak_field_map$)" + ";\n"); + } + + if (!inlined_string_indices_.empty()) { + for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { + format( + "swap($inlined_string_donated_array$[$1$], " + "other->$inlined_string_donated_array$[$1$]);\n", + i); + } } } else { format("GetReflection()->Swap(this, other);"); @@ -3532,24 +3360,18 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { format( "const ::$proto_ns$::Message::ClassData " "$classname$::_class_data_ = {\n" - " ::$proto_ns$::Message::CopyWithSizeCheck,\n" + " ::$proto_ns$::Message::CopyWithSourceCheck,\n" " $classname$::MergeImpl\n" "};\n" "const ::$proto_ns$::Message::ClassData*" "$classname$::GetClassData() const { return &_class_data_; }\n" - "\n" - "void $classname$::MergeImpl(::$proto_ns$::Message* to,\n" - " const ::$proto_ns$::Message& from) {\n" - " static_cast<$classname$ *>(to)->MergeFrom(\n" - " static_cast(from));\n" - "}\n" "\n"); } else { // Generate CheckTypeAndMergeFrom(). format( "void $classname$::CheckTypeAndMergeFrom(\n" " const ::$proto_ns$::MessageLite& from) {\n" - " MergeFrom(*::$proto_ns$::internal::DownCast(\n" + " MergeFrom(*::_pbi::DownCast(\n" " &from));\n" "}\n"); } @@ -3569,29 +3391,50 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { } } -void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { +void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* printer) { if (HasSimpleBaseClass(descriptor_, options_)) return; // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. Formatter format(printer, variables_); + if (!HasDescriptorMethods(descriptor_->file(), options_)) { + // For messages that don't inherit from Message, just implement MergeFrom + // directly. + format( + "void $classname$::MergeFrom(const $classname$& from) {\n" + " $classname$* const _this = this;\n"); + } else { + format( + "void $classname$::MergeImpl(::$proto_ns$::Message& to_msg, const " + "::$proto_ns$::Message& from_msg) {\n" + " auto* const _this = static_cast<$classname$*>(&to_msg);\n" + " auto& from = static_cast(from_msg);\n"); + } + format.Indent(); format( - "void $classname$::MergeFrom(const $classname$& from) {\n" "$annotate_mergefrom$" "// @@protoc_insertion_point(class_specific_merge_from_start:" - "$full_name$)\n" - " $DCHK$_NE(&from, this);\n"); - format.Indent(); + "$full_name$)\n"); + format("$DCHK$_NE(&from, _this);\n"); format( "$uint32$ cached_has_bits = 0;\n" "(void) cached_has_bits;\n\n"); + if (ShouldSplit(descriptor_, options_)) { + format( + "if (!from.IsSplitMessageDefault()) {\n" + " _this->PrepareSplitMessageForWrite();\n" + "}\n"); + } + std::vector> chunks = CollectFields( optimized_order_, [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { - return HasByteIndex(a) == HasByteIndex(b); + return HasByteIndex(a) == HasByteIndex(b) && + ShouldSplit(a, options_) == ShouldSplit(b, options_); }); - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); + ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_, + kColdRatio); // cached_has_word_index maintains that: // cached_has_bits = from._has_bits_[cached_has_word_index] @@ -3619,7 +3462,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = from._has_bits_[$1$];\n", + format("cached_has_bits = from.$has_bits$[$1$];\n", cached_has_word_index); } @@ -3680,7 +3523,8 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (deferred_has_bit_changes) { // Flush the has bits for the primitives we deferred. GOOGLE_CHECK_LE(0, cached_has_word_index); - format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index); + format("_this->$has_bits$[$1$] |= cached_has_bits;\n", + cached_has_word_index); } format.Outdent(); @@ -3716,19 +3560,22 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { format("}\n"); } if (num_weak_fields_) { - format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n"); + format( + "_this->$weak_field_map$.MergeFrom(from.$weak_field_map$);" + "\n"); } // Merging of extensions and unknown fields is done last, to maximize // the opportunity for tail calls. if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "_this->$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } format( - "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_" + "_this->_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._" + "internal_" "metadata_);\n"); format.Outdent(); @@ -3743,12 +3590,12 @@ void MessageGenerator::GenerateCopyFrom(io::Printer* printer) { // takes in the Message base class as a parameter); instead we just // let the base Message::CopyFrom take care of it. The base MergeFrom // knows how to quickly confirm the types exactly match, and if so, will - // use GetClassData() to get the address of Message::CopyWithSizeCheck, + // use GetClassData() to get the address of Message::CopyWithSourceCheck, // which calls Clear() and then MergeFrom(), as well as making sure that - // clearing the destination message doesn't alter the size of the source, - // when in debug builds. - // Most callers avoid this by passing a "from" message that is the same - // type as the message being merged into, rather than a generic Message. + // clearing the destination message doesn't alter the source, when in debug + // builds. Most callers avoid this by passing a "from" message that is the + // same type as the message being merged into, rather than a generic + // Message. } // Generate the class-specific CopyFrom. @@ -3760,20 +3607,33 @@ void MessageGenerator::GenerateCopyFrom(io::Printer* printer) { format("if (&from == this) return;\n"); - if (!options_.opensource_runtime) { + if (!options_.opensource_runtime && HasMessageFieldOrExtension(descriptor_)) { // This check is disabled in the opensource release because we're // concerned that many users do not define NDEBUG in their release builds. + // It is also disabled if a message has neither message fields nor + // extensions, as it's impossible to copy from its descendant. + // + // Note that FailIfCopyFromDescendant is implemented by reflection and not + // available for lite runtime. In that case, check if the size of the source + // has changed after Clear. + format("#ifndef NDEBUG\n"); + if (HasDescriptorMethods(descriptor_->file(), options_)) { + format("FailIfCopyFromDescendant(*this, from);\n"); + } else { + format("size_t from_size = from.ByteSizeLong();\n"); + } format( - "#ifndef NDEBUG\n" - "size_t from_size = from.ByteSizeLong();\n" "#endif\n" - "Clear();\n" - "#ifndef NDEBUG\n" - "$CHK$_EQ(from_size, from.ByteSizeLong())\n" - " << \"Source of CopyFrom changed when clearing target. Either \"\n" - " \"source is a nested message in target (not allowed), or \"\n" - " \"another thread is modifying the source.\";\n" - "#endif\n"); + "Clear();\n"); + if (!HasDescriptorMethods(descriptor_->file(), options_)) { + format( + "#ifndef NDEBUG\n" + "$CHK$_EQ(from_size, from.ByteSizeLong())\n" + " << \"Source of CopyFrom changed when clearing target. Either \"\n" + " \"source is a nested message in target (not allowed), or \"\n" + " \"another thread is modifying the source.\";\n" + "#endif\n"); + } } else { format("Clear();\n"); } @@ -3860,7 +3720,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange( Formatter format(printer, vars); format("// Extension range [$start$, $end$)\n"); format( - "target = _extensions_._InternalSerialize(\n" + "target = $extensions$._InternalSerialize(\n" "internal_default_instance(), $start$, $end$, target, stream);\n\n"); } @@ -3875,14 +3735,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " "const {\n" "$annotate_serialize$" - " target = _extensions_." + " target = $extensions$." "InternalSerializeMessageSetWithCachedSizesToArray(\n" // "internal_default_instance(), target, stream);\n"); std::map vars; SetUnknownFieldsVariable(descriptor_, options_, &vars); format.AddMap(vars); format( - " target = ::$proto_ns$::internal::" + " target = ::_pbi::" "InternalSerializeUnknownMessageSetItemsToArray(\n" " $unknown_fields$, target, stream);\n"); format( @@ -3965,7 +3825,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( // Reload. int new_index = has_bit_index / 32; - format_("cached_has_bits = _has_bits_[$1$];\n", new_index); + format_("cached_has_bits = _impl_._has_bits_[$1$];\n", new_index); cached_has_bit_index_ = new_index; } @@ -4077,8 +3937,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( ExtensionRangeSorter()); if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "::_pbi::WeakFieldMap::FieldWriter field_writer(" + "$weak_field_map$);\n"); } format( @@ -4126,7 +3986,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( if (UseUnknownFieldSet(descriptor_->file(), options_)) { format( "target = " - "::$proto_ns$::internal::WireFormat::" + "::_pbi::WireFormat::" "InternalSerializeUnknownFieldsToArray(\n" " $unknown_fields$, target, stream);\n"); } else { @@ -4167,8 +4027,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (num_weak_fields_) { format( - "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "::_pbi::WeakFieldMap::FieldWriter field_writer(" + "$weak_field_map$);\n"); } format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1); @@ -4218,7 +4078,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (UseUnknownFieldSet(descriptor_->file(), options_)) { format( "target = " - "::$proto_ns$::internal::WireFormat::" + "::_pbi::WireFormat::" "InternalSerializeUnknownFieldsToArray(\n" " $unknown_fields$, target, stream);\n"); } else { @@ -4259,13 +4119,13 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { "size_t $classname$::ByteSizeLong() const {\n" "$annotate_bytesize$" "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\n" + " size_t total_size = $extensions$.MessageSetByteSize();\n" " if ($have_unknown_fields$) {\n" - " total_size += ::$proto_ns$::internal::\n" + " total_size += ::_pbi::\n" " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" " }\n" " int cached_size = " - "::$proto_ns$::internal::ToCachedSize(total_size);\n" + "::_pbi::ToCachedSize(total_size);\n" " SetCachedSize(cached_size);\n" " return total_size;\n" "}\n"); @@ -4312,7 +4172,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "total_size += _extensions_.ByteSize();\n" + "total_size += $extensions$.ByteSize();\n" "\n"); } @@ -4358,14 +4218,16 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { std::vector> chunks = CollectFields( optimized_order_, [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { - return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b); + return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b) && + ShouldSplit(a, options_) == ShouldSplit(b, options_); }); // Remove chunks with required fields. chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired), chunks.end()); - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); + ColdChunkSkipper cold_skipper(descriptor_, options_, chunks, has_bit_indices_, + kColdRatio); int cached_has_word_index = -1; format( @@ -4393,7 +4255,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); @@ -4473,7 +4335,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (num_weak_fields_) { // TagSize + MessageSize - format("total_size += _weak_field_map_.ByteSizeLong();\n"); + format("total_size += $weak_field_map$.ByteSizeLong();\n"); } if (UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -4481,7 +4343,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // unknown fields in tail position. This allows for better code generation // of this function for simple protos. format( - "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n"); + "return MaybeComputeUnknownFieldsSize(total_size, &$cached_size$);\n"); } else { format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); format(" total_size += $unknown_fields$.size();\n"); @@ -4496,7 +4358,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // where even relaxed memory order might have perf impact to replace it with // ordinary loads and stores. format( - "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n" + "int cached_size = ::_pbi::ToCachedSize(total_size);\n" "SetCachedSize(cached_size);\n" "return total_size;\n"); } @@ -4513,14 +4375,14 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "if (!_extensions_.IsInitialized()) {\n" + "if (!$extensions$.IsInitialized()) {\n" " return false;\n" "}\n\n"); } if (num_required_fields_ > 0) { format( - "if (_Internal::MissingRequiredFields(_has_bits_))" + "if (_Internal::MissingRequiredFields($has_bits$))" " return false;\n"); } @@ -4530,7 +4392,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } if (num_weak_fields_) { // For Weak fields. - format("if (!_weak_field_map_.IsInitialized()) return false;\n"); + format("if (!$weak_field_map$.IsInitialized()) return false;\n"); } // Go through the oneof fields, emitting a switch if any might have required // fields. diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/message.h similarity index 86% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/message.h index 64af2bf8..5bdfcb35 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message.h @@ -40,11 +40,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace google { namespace protobuf { @@ -96,22 +96,10 @@ class MessageGenerator { void GenerateFieldAccessorDeclarations(io::Printer* printer); void GenerateFieldAccessorDefinitions(io::Printer* printer); - // Generate the table-driven parsing array. Returns the number of entries - // generated. - size_t GenerateParseOffsets(io::Printer* printer); - size_t GenerateParseAuxTable(io::Printer* printer); - // Generates a ParseTable entry. Returns whether the proto uses - // table-driven parsing. - bool GenerateParseTable(io::Printer* printer, size_t offset, - size_t aux_offset); - // Generate the field offsets array. Returns the a pair of the total number // of entries generated and the index of the first has_bit entry. std::pair GenerateOffsets(io::Printer* printer); void GenerateSchema(io::Printer* printer, int offset, int has_offset); - // For each field generates a table entry describing the field for the - // table driven serializer. - int GenerateFieldMetadata(io::Printer* printer); // Generate constructors and destructor. void GenerateStructors(io::Printer* printer); @@ -131,6 +119,9 @@ class MessageGenerator { // default instance. void GenerateConstexprConstructor(io::Printer* printer); + void GenerateCreateSplitMessage(io::Printer* printer); + void GenerateInitDefaultSplitInstance(io::Printer* printer); + // Generate standard Message methods. void GenerateClear(io::Printer* printer); void GenerateOneofClear(io::Printer* printer); @@ -141,7 +132,7 @@ class MessageGenerator { void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer); void GenerateByteSize(io::Printer* printer); void GenerateMergeFrom(io::Printer* printer); - void GenerateClassSpecificMergeFrom(io::Printer* printer); + void GenerateClassSpecificMergeImpl(io::Printer* printer); void GenerateCopyFrom(io::Printer* printer); void GenerateSwap(io::Printer* printer); void GenerateIsInitialized(io::Printer* printer); @@ -173,9 +164,20 @@ class MessageGenerator { void GenerateFieldClear(const FieldDescriptor* field, bool is_inline, Formatter format); - void GenerateConstructorBody(io::Printer* printer, - std::vector already_processed, - bool copy_constructor) const; + // Generates the body of the message's copy constructor. + void GenerateCopyConstructorBody(io::Printer* printer) const; + + // Returns the level that this message needs ArenaDtor. If the message has + // a field that is not arena-exclusive, it needs an ArenaDtor + // (go/proto-destructor). + // + // - Returning kNone means we don't need to generate ArenaDtor. + // - Returning kOnDemand means we need to generate ArenaDtor, but don't need + // to register ArenaDtor at construction. Such as when the message's + // ArenaDtor code is only for destructing inlined string. + // - Returning kRequired means we meed to generate ArenaDtor and register it + // at construction. + ArenaDtorNeeds NeedsArenaDestructor() const; size_t HasBitsSize() const; size_t InlinedStringDonatedSize() const; @@ -200,7 +202,8 @@ class MessageGenerator { int max_has_bit_index_; // A map from field index to inlined_string index. For non-inlined-string - // fields, the element is -1. + // fields, the element is -1. If there is no inlined string in the message, + // this is empty. std::vector inlined_string_indices_; // The count of inlined_string fields in the message. int max_inlined_string_index_; @@ -209,8 +212,6 @@ class MessageGenerator { std::vector extension_generators_; int num_required_fields_; int num_weak_fields_; - // table_driven_ indicates the generated message uses table-driven parsing. - bool table_driven_; std::unique_ptr message_layout_helper_; std::unique_ptr parse_function_generator_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.cc similarity index 78% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.cc index 61999033..7e87a079 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.cc @@ -32,9 +32,11 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include -#include +#include + #include +#include +#include #include @@ -60,11 +62,16 @@ void SetMessageVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor, options); (*variables)["casted_member"] = ReinterpretCast( - (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak); + (*variables)["type"] + "*", (*variables)["field"], implicit_weak); + (*variables)["casted_member_const"] = + ReinterpretCast("const " + (*variables)["type"] + "&", + "*" + (*variables)["field"], implicit_weak); (*variables)["type_default_instance"] = QualifiedDefaultInstanceName(descriptor->message_type(), options); - (*variables)["type_default_instance_ptr"] = - QualifiedDefaultInstancePtr(descriptor->message_type(), options); + (*variables)["type_default_instance_ptr"] = ReinterpretCast( + "const ::PROTOBUF_NAMESPACE_ID::MessageLite*", + QualifiedDefaultInstancePtr(descriptor->message_type(), options), + implicit_weak); (*variables)["type_reference_function"] = implicit_weak ? (" ::" + (*variables)["proto_ns"] + "::internal::StrongReference(reinterpret_cast($name$_);\n" + " delete reinterpret_cast<::$proto_ns$::MessageLite*>($field$);\n" " }\n"); if (implicit_weak_field_) { format( - " $name$_ = " - "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); + " $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); } else { - format(" $name$_ = $name$;\n"); + format(" $field$ = $name$;\n"); } format( " if ($name$) {\n" @@ -199,9 +205,10 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline $type$* $classname$::$release_name$() {\n" "$type_reference_function$" "$annotate_release$" + "$maybe_prepare_split_message$" " $clear_hasbit$\n" " $type$* temp = $casted_member$;\n" - " $name$_ = nullptr;\n" + " $field$ = nullptr;\n" "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n" " auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n" " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" @@ -217,9 +224,10 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n" "$type_reference_function$" + "$maybe_prepare_split_message$" " $clear_hasbit$\n" " $type$* temp = $casted_member$;\n" - " $name$_ = nullptr;\n" + " $field$ = nullptr;\n" " return temp;\n" "}\n"); @@ -227,18 +235,21 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline $type$* $classname$::_internal_mutable_$name$() {\n" "$type_reference_function$" " $set_hasbit$\n" - " if ($name$_ == nullptr) {\n" + " if ($field$ == nullptr) {\n" " auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n"); if (implicit_weak_field_) { - format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n"); + format(" $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n"); } else { - format(" $name$_ = p;\n"); + format(" $field$ = p;\n"); } format( " }\n" " return $casted_member$;\n" "}\n" "inline $type$* $classname$::mutable_$name$() {\n" + // TODO(b/122856539): add tests to make sure all write accessors are able + // to prepare split message allocation. + "$maybe_prepare_split_message$" " $type$* _msg = _internal_mutable_$name$();\n" "$annotate_mutable$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" @@ -250,12 +261,14 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"); - format(" if (message_arena == nullptr) {\n"); + format( + "$maybe_prepare_split_message$" + " if (message_arena == nullptr) {\n"); if (IsCrossFileMessage(descriptor_)) { format( - " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n"); + " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n"); } else { - format(" delete $name$_;\n"); + format(" delete $field$;\n"); } format( " }\n" @@ -265,14 +278,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<\n" - " ::$proto_ns$::MessageLite>::GetOwningArena(\n" + " ::$proto_ns$::Arena::InternalGetOwningArena(\n" " reinterpret_cast<::$proto_ns$::MessageLite*>(" "$name$));\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<$type$>::GetOwningArena(" + " ::$proto_ns$::Arena::InternalGetOwningArena(" "$name$);\n"); } format( @@ -285,9 +297,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n" " }\n"); if (implicit_weak_field_) { - format(" $name$_ = reinterpret_cast($name$);\n"); + format(" $field$ = reinterpret_cast($name$);\n"); } else { - format(" $name$_ = $name$;\n"); + format(" $field$ = $name$;\n"); } format( "$annotate_set$" @@ -322,14 +334,10 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( format( "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n" " const $classname$* msg) {\n" - " if (msg->$name$_ != nullptr) {\n" - " return *msg->$name$_;\n" - " } else if ($type_default_instance_ptr$ != nullptr) {\n" - " return *reinterpret_cast(\n" - " $type_default_instance_ptr$);\n" + " if (msg->$field$ != nullptr) {\n" + " return *msg->$field$;\n" " } else {\n" - " return " - "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n" + " return *$type_default_instance_ptr$;\n" " }\n" "}\n"); format( @@ -338,20 +346,19 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( if (HasHasbit(descriptor_)) { format(" msg->$set_hasbit$\n"); } + if (descriptor_->real_containing_oneof() == nullptr) { + format(" if (msg->$field$ == nullptr) {\n"); + } else { + format( + " if (!msg->_internal_has_$name$()) {\n" + " msg->clear_$oneof_name$();\n" + " msg->set_has_$name$();\n"); + } format( - " if (msg->$name$_ == nullptr) {\n" - " if ($type_default_instance_ptr$ == nullptr) {\n" - " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" - " ::$proto_ns$::internal::ImplicitWeakMessage>(\n" - " msg->GetArenaForAllocation());\n" - " } else {\n" - " msg->$name$_ = \n" - " reinterpret_cast(\n" - " $type_default_instance_ptr$)->New(\n" - " msg->GetArenaForAllocation());\n" - " }\n" + " msg->$field$ = $type_default_instance_ptr$->New(\n" + " msg->GetArenaForAllocation());\n" " }\n" - " return msg->$name$_;\n" + " return msg->$field$;\n" "}\n"); } else { // This inline accessor directly returns member field and is used in @@ -360,7 +367,7 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( format( "const $type$&\n" "$classname$::_Internal::$name$(const $classname$* msg) {\n" - " return *msg->$field_member$;\n" + " return *msg->$field$;\n" "}\n"); } } @@ -371,14 +378,14 @@ void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); if (!HasHasbit(descriptor_)) { // If we don't have has-bits, message presence is indicated only by ptr != - // NULL. Thus on clear, we need to delete the object. + // nullptr. Thus on clear, we need to delete the object. format( - "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n" - " delete $name$_;\n" + "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n" + " delete $field$;\n" "}\n" - "$name$_ = nullptr;\n"); + "$field$ = nullptr;\n"); } else { - format("if ($name$_ != nullptr) $name$_->Clear();\n"); + format("if ($field$ != nullptr) $field$->Clear();\n"); } } @@ -389,16 +396,16 @@ void MessageFieldGenerator::GenerateMessageClearingCode( Formatter format(printer, variables_); if (!HasHasbit(descriptor_)) { // If we don't have has-bits, message presence is indicated only by ptr != - // NULL. Thus on clear, we need to delete the object. + // nullptr. Thus on clear, we need to delete the object. format( - "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n" - " delete $name$_;\n" + "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n" + " delete $field$;\n" "}\n" - "$name$_ = nullptr;\n"); + "$field$ = nullptr;\n"); } else { format( - "$DCHK$($name$_ != nullptr);\n" - "$name$_->Clear();\n"); + "$DCHK$($field$ != nullptr);\n" + "$field$->Clear();\n"); } } @@ -408,12 +415,12 @@ void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); if (implicit_weak_field_) { format( - "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n" + "_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n" " _Internal::$name$(&from));\n"); } else { format( - "_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())" - ";\n"); + "_this->_internal_mutable_$name$()->$type$::MergeFrom(\n" + " from._internal_$name$());\n"); } } @@ -421,7 +428,7 @@ void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); + format("swap($field$, other->$field$);\n"); } void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { @@ -436,15 +443,11 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { // care when handling them. format("if (this != internal_default_instance()) "); } - format("delete $name$_;\n"); -} - -void MessageFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); - - Formatter format(printer, variables_); - format("$name$_ = nullptr;\n"); + if (ShouldSplit(descriptor_, options_)) { + format("delete $cached_split_ptr$->$name$_;\n"); + return; + } + format("delete $field$;\n"); } void MessageFieldGenerator::GenerateCopyConstructorCode( @@ -454,9 +457,7 @@ void MessageFieldGenerator::GenerateCopyConstructorCode( Formatter format(printer, variables_); format( "if (from._internal_has_$name$()) {\n" - " $name$_ = new $type$(*from.$name$_);\n" - "} else {\n" - " $name$_ = nullptr;\n" + " _this->$field$ = new $type$(*from.$field$);\n" "}\n"); } @@ -465,11 +466,18 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format( - "target = stream->EnsureSpace(target);\n" - "target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$(\n" - " $number$, _Internal::$name$(this), target, stream);\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + "target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, _Internal::$name$(this),\n" + " _Internal::$name$(this).GetCachedSize(), target, stream);\n"); + } else { + format( + "target = stream->EnsureSpace(target);\n" + "target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$(\n" + " $number$, _Internal::$name$(this), target, stream);\n"); + } } void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { @@ -479,7 +487,7 @@ void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { format( "total_size += $tag_size$ +\n" " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" - " *$field_member$);\n"); + " *$field$);\n"); } void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { @@ -490,14 +498,30 @@ void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { Formatter format(printer, variables_); format( "if (_internal_has_$name$()) {\n" - " if (!$name$_->IsInitialized()) return false;\n" + " if (!$field$->IsInitialized()) return false;\n" "}\n"); } -void MessageFieldGenerator::GenerateConstinitInitializer( +void MessageFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_(nullptr)"); + format("/*decltype($field$)*/nullptr"); +} + +void MessageFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){nullptr}"); +} + +void MessageFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format("decltype(Impl_::Split::$name$_){nullptr}"); + return; + } + format("decltype($field$){nullptr}"); } // =================================================================== @@ -524,15 +548,13 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<\n" - " ::$proto_ns$::MessageLite>::GetOwningArena(\n" + " ::$proto_ns$::Arena::InternalGetOwningArena(\n" " reinterpret_cast<::$proto_ns$::MessageLite*>(" "$name$));\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" - " ::$proto_ns$::Arena::InternalHelper<" - "$type$>::GetOwningArena($name$);\n"); + " ::$proto_ns$::Arena::InternalGetOwningArena($name$);\n"); } format( " if (message_arena != submessage_arena) {\n" @@ -540,7 +562,7 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( " message_arena, $name$, submessage_arena);\n" " }\n" " set_has_$name$();\n" - " $field_member$ = $name$;\n" + " $field$ = $name$;\n" " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" @@ -554,13 +576,14 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "inline $type$* $classname$::$release_name$() {\n" "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n" + "$type_reference_function$" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" + " $type$* temp = $casted_member$;\n" " if (GetArenaForAllocation() != nullptr) {\n" " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" " }\n" - " $field_member$ = nullptr;\n" + " $field$ = nullptr;\n" " return temp;\n" " } else {\n" " return nullptr;\n" @@ -569,8 +592,9 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const $type$& $classname$::_internal_$name$() const {\n" + "$type_reference_function$" " return _internal_has_$name$()\n" - " ? *$field_member$\n" + " ? $casted_member_const$\n" " : reinterpret_cast< $type$&>($type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" @@ -582,10 +606,11 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_release$" " // @@protoc_insertion_point(field_unsafe_arena_release" ":$full_name$)\n" + "$type_reference_function$" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" - " $field_member$ = nullptr;\n" + " $type$* temp = $casted_member$;\n" + " $field$ = nullptr;\n" " return temp;\n" " } else {\n" " return nullptr;\n" @@ -598,21 +623,38 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( // new value. " clear_$oneof_name$();\n" " if ($name$) {\n" - " set_has_$name$();\n" - " $field_member$ = $name$;\n" + " set_has_$name$();\n"); + if (implicit_weak_field_) { + format( + " $field$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); + } else { + format(" $field$ = $name$;\n"); + } + format( " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" "$full_name$)\n" "}\n" "inline $type$* $classname$::_internal_mutable_$name$() {\n" + "$type_reference_function$" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$ = CreateMaybeMessage< $type$ " - ">(GetArenaForAllocation());\n" + " set_has_$name$();\n"); + if (implicit_weak_field_) { + format( + " $field$ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< " + "$type$ >(GetArenaForAllocation()));\n"); + } else { + format( + " $field$ = CreateMaybeMessage< $type$ " + ">(GetArenaForAllocation());\n"); + } + format( " }\n" - " return $field_member$;\n" + " return $casted_member$;\n" "}\n" "inline $type$* $classname$::mutable_$name$() {\n" " $type$* _msg = _internal_mutable_$name$();\n" @@ -629,7 +671,7 @@ void MessageOneofFieldGenerator::GenerateClearingCode( Formatter format(printer, variables_); format( "if (GetArenaForAllocation() == nullptr) {\n" - " delete $field_member$;\n" + " delete $field$;\n" "}\n"); } @@ -662,7 +704,7 @@ void MessageOneofFieldGenerator::GenerateIsInitialized( Formatter format(printer, variables_); format( "if (_internal_has_$name$()) {\n" - " if (!$field_member$->IsInitialized()) return false;\n" + " if (!$field$->IsInitialized()) return false;\n" "}\n"); } @@ -741,21 +783,21 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( // TODO(dlj): move insertion points " // @@protoc_insertion_point(field_mutable:$full_name$)\n" "$type_reference_function$" - " return $name$_$weak$.Mutable(index);\n" + " return $field$$weak$.Mutable(index);\n" "}\n" "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n" "$classname$::mutable_$name$() {\n" "$annotate_mutable_list$" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" "$type_reference_function$" - " return &$name$_$weak$;\n" + " return &$field$$weak$;\n" "}\n"); if (options_.safe_boundary_check) { format( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" - " return $name$_$weak$.InternalCheckedGet(index,\n" + " return $field$$weak$.InternalCheckedGet(index,\n" " reinterpret_cast($type_default_instance$));\n" "}\n"); } else { @@ -763,7 +805,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" "$type_reference_function$" - " return $name$_$weak$.Get(index);\n" + " return $field$$weak$.Get(index);\n" "}\n"); } @@ -774,7 +816,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( " return _internal_$name$(index);\n" "}\n" "inline $type$* $classname$::_internal_add_$name$() {\n" - " return $name$_$weak$.Add();\n" + " return $field$$weak$.Add();\n" "}\n" "inline $type$* $classname$::add_$name$() {\n" " $type$* _add = _internal_add_$name$();\n" @@ -789,7 +831,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" "$type_reference_function$" - " return $name$_$weak$;\n" + " return $field$$weak$;\n" "}\n"); } @@ -798,7 +840,7 @@ void RepeatedMessageFieldGenerator::GenerateClearingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedMessageFieldGenerator::GenerateMergingCode( @@ -806,7 +848,7 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("_this->$field$.MergeFrom(from.$field$);\n"); } void RepeatedMessageFieldGenerator::GenerateSwappingCode( @@ -814,7 +856,7 @@ void RepeatedMessageFieldGenerator::GenerateSwappingCode( GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } void RepeatedMessageFieldGenerator::GenerateConstructorCode( @@ -822,6 +864,18 @@ void RepeatedMessageFieldGenerator::GenerateConstructorCode( // Not needed for repeated fields. } +void RepeatedMessageFieldGenerator::GenerateDestructorCode( + io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + + Formatter format(printer, variables_); + if (implicit_weak_field_) { + format("$field$.~WeakRepeatedPtrField();\n"); + } else { + format("$field$.~RepeatedPtrField();\n"); + } +} + void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); @@ -829,23 +883,41 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( Formatter format(printer, variables_); if (implicit_weak_field_) { format( - "for (auto it = this->$name$_.pointer_begin(),\n" - " end = this->$name$_.pointer_end(); it < end; ++it) {\n" - " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$($number$, **it, target, stream);\n" - "}\n"); + "for (auto it = this->$field$.pointer_begin(),\n" + " end = this->$field$.pointer_end(); it < end; ++it) {\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "**it, (**it).GetCachedSize(), target, stream);\n"); + } else { + format( + " target = stream->EnsureSpace(target);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, **it, target, " + "stream);\n"); + } + format("}\n"); } else { format( - "for (unsigned int i = 0,\n" - " n = static_cast(this->_internal_$name$_size()); i < " - "n; i++) " - "{\n" - " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::\n" - " InternalWrite$declared_type$($number$, " - "this->_internal_$name$(i), target, stream);\n" - "}\n"); + "for (unsigned i = 0,\n" + " n = static_cast(this->_internal_$name$_size());" + " i < n; i++) {\n"); + if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + format( + " const auto& repfield = this->_internal_$name$(i);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "repfield, repfield.GetCachedSize(), target, stream);\n" + "}\n"); + } else { + format( + " target = stream->EnsureSpace(target);\n" + " target = ::$proto_ns$::internal::WireFormatLite::\n" + " InternalWrite$declared_type$($number$, " + "this->_internal_$name$(i), target, stream);\n" + "}\n"); + } } } @@ -856,7 +928,7 @@ void RepeatedMessageFieldGenerator::GenerateByteSize( Formatter format(printer, variables_); format( "total_size += $tag_size$UL * this->_internal_$name$_size();\n" - "for (const auto& msg : this->$name$_) {\n" + "for (const auto& msg : this->$field$) {\n" " total_size +=\n" " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n" "}\n"); @@ -871,21 +943,15 @@ void RepeatedMessageFieldGenerator::GenerateIsInitialized( Formatter format(printer, variables_); if (implicit_weak_field_) { format( - "if (!::$proto_ns$::internal::AllAreInitializedWeak($name$_.weak))\n" + "if (!::$proto_ns$::internal::AllAreInitializedWeak($field$.weak))\n" " return false;\n"); } else { format( - "if (!::$proto_ns$::internal::AllAreInitialized($name$_))\n" + "if (!::$proto_ns$::internal::AllAreInitialized($field$))\n" " return false;\n"); } } -void RepeatedMessageFieldGenerator::GenerateConstinitInitializer( - io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_()"); -} - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.h similarity index 93% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.h index 2beac625..70c42c0e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.h @@ -37,8 +37,9 @@ #include #include -#include -#include + +#include +#include namespace google { namespace protobuf { @@ -66,13 +67,16 @@ class MessageFieldGenerator : public FieldGenerator { void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateIsInitialized(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; protected: const bool implicit_weak_field_; @@ -123,11 +127,11 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { void GenerateSwappingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; void GenerateCopyConstructorCode(io::Printer* printer) const override {} + void GenerateDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateIsInitialized(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; private: const bool implicit_weak_field_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_layout_helper.h similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/message_layout_helper.h index 9d8063d9..a8813a1f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_layout_helper.h @@ -35,8 +35,8 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ -#include #include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/message_size_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_size_unittest.cc new file mode 100644 index 00000000..761988bf --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/message_size_unittest.cc @@ -0,0 +1,272 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { + + +#if !defined(GOOGLE_CHECK_MESSAGE_SIZE) +#define GOOGLE_CHECK_MESSAGE_SIZE(t, expected) +#endif + +// Mock structures to lock down the size of messages in a platform-independent +// way. The commented sizes only apply when build with clang x86_64. +struct MockMessageBase { + virtual ~MockMessageBase() = default; // 8 bytes vtable + void* internal_metadata; // 8 bytes +}; +GOOGLE_CHECK_MESSAGE_SIZE(MockMessageBase, 16); + +struct MockZeroFieldsBase : public MockMessageBase { + int cached_size; // 4 bytes + // + 4 bytes padding +}; +GOOGLE_CHECK_MESSAGE_SIZE(MockZeroFieldsBase, 24); + +struct MockExtensionSet { + void* arena; // 8 bytes + int16_t capacity; // 4 bytes + int16_t size; // 4 bytes + void* data; // 8 bytes +}; +GOOGLE_CHECK_MESSAGE_SIZE(MockExtensionSet, 24); + +struct MockRepeatedPtrField { + void* arena; // 8 bytes + int current_size; // 4 bytes + int total_size; // 4 bytes + void* data; // 8 bytes +}; +GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedPtrField, 24); + +struct MockRepeatedField { + int current_size; // 4 bytes + int total_size; // 4 bytes + void* data; // 8 bytes +}; +GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedField, 16); + +TEST(GeneratedMessageTest, MockSizes) { + // Consistency checks -- if these fail, the tests below will definitely fail. + GOOGLE_CHECK_EQ(sizeof(MessageLite), sizeof(MockMessageBase)); + GOOGLE_CHECK_EQ(sizeof(Message), sizeof(MockMessageBase)); + GOOGLE_CHECK_EQ(sizeof(internal::ZeroFieldsBase), sizeof(MockZeroFieldsBase)); + GOOGLE_CHECK_EQ(sizeof(internal::ExtensionSet), sizeof(MockExtensionSet)); + GOOGLE_CHECK_EQ(sizeof(RepeatedPtrField), sizeof(MockRepeatedPtrField)); + GOOGLE_CHECK_EQ(sizeof(RepeatedField), sizeof(MockRepeatedField)); +} + +TEST(GeneratedMessageTest, EmptyMessageSize) { + EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessage), + sizeof(MockZeroFieldsBase)); +} + +TEST(GeneratedMessageTest, ReservedSize) { + EXPECT_EQ(sizeof(protobuf_unittest::TestReservedFields), + sizeof(MockZeroFieldsBase)); +} + +TEST(GeneratedMessageTest, EmptyMessageWithExtensionsSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + MockExtensionSet extensions; // 24 bytes + int cached_size; // 4 bytes + // + 4 bytes of padding + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48); + EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessageWithExtensions), + sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, RecursiveMessageSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + void* a; // 8 bytes + int32_t i; // 4 bytes + // + 4 bytes padding + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 40); + EXPECT_EQ(sizeof(protobuf_unittest::TestRecursiveMessage), + sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, OneStringSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + void* data; // 8 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32); + EXPECT_EQ(sizeof(protobuf_unittest::OneString), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, MoreStringSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + MockRepeatedPtrField data; // 24 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48); + EXPECT_EQ(sizeof(protobuf_unittest::MoreString), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, Int32MessageSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + int32_t data; // 4 bytes + // + 4 bytes padding + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32); + EXPECT_EQ(sizeof(protobuf_unittest::Int32Message), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, Int64MessageSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + int64_t data; // 8 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32); + EXPECT_EQ(sizeof(protobuf_unittest::Int64Message), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, BoolMessageSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + bool data; // 1 byte + // + 3 bytes padding + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32); + EXPECT_EQ(sizeof(protobuf_unittest::BoolMessage), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, OneofSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + void* foo; // 8 bytes + int cached_size; // 4 bytes + uint32_t oneof_case[1]; // 4 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32); + EXPECT_EQ(sizeof(protobuf_unittest::TestOneof), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, Oneof2Size) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + void* baz_string; // 8 bytes + int32_t baz_int; // 4 bytes + // + 4 bytes padding + void* foo; // 8 bytes + void* bar; // 8 bytes + uint32_t oneof_case[2]; // 8 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 64); + EXPECT_EQ(sizeof(protobuf_unittest::TestOneof2), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, FieldOrderingsSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + MockExtensionSet extensions; // 24 bytes + void* my_string; // 8 bytes + void* optional_nested_message; // 8 bytes + int64_t my_int; // 8 bytes + float my_float; // 4 bytes + // + 4 bytes of padding + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 80); + EXPECT_EQ(sizeof(protobuf_unittest::TestFieldOrderings), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, TestMessageSize) { + // We expect the message to contain (not in this order): + struct MockGenerated : public MockMessageBase { // 16 bytes + int has_bits[1]; // 4 bytes + int cached_size; // 4 bytes + void* m4; // 8 bytes + int64_t m2; // 8 bytes + bool m1; // 1 bytes + bool m3; // 1 bytes + // + 2 bytes padding + int m5; // 4 bytes + int64_t m6; // 8 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 56); + EXPECT_EQ(sizeof(protobuf_unittest::TestMessageSize), sizeof(MockGenerated)); +} + +TEST(GeneratedMessageTest, PackedTypesSize) { + struct MockGenerated : public MockMessageBase { // 16 bytes + MockRepeatedField packed_int32; // 16 bytes + int packed_int32_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_int64; // 16 bytes + int packed_int64_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_uint32; // 16 bytes + int packed_uint32_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_uint64; // 16 bytes + int packed_uint64_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_sint32; // 16 bytes + int packed_sint32_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_sint64; // 16 bytes + int packed_sint64_cached_byte_size; // 4 bytes + 4 bytes padding + MockRepeatedField packed_fixed32; // 16 bytes + MockRepeatedField packed_fixed64; // 16 bytes + MockRepeatedField packed_sfixed32; // 16 bytes + MockRepeatedField packed_sfixed64; // 16 bytes + MockRepeatedField packed_float; // 16 bytes + MockRepeatedField packed_double; // 16 bytes + MockRepeatedField packed_bool; // 16 bytes + MockRepeatedField packed_enum; // 16 bytes + int packed_enum_cached_byte_size; // 4 bytes + int cached_size; // 4 bytes + }; + GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 16 * 15 + 8 * 6 + 8); + EXPECT_EQ(sizeof(protobuf_unittest::TestPackedTypes), sizeof(MockGenerated)); +} + +} // namespace cpp_unittest +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/metadata_test.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/metadata_test.cc index b5cac8f4..1ffd3574 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/metadata_test.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -32,13 +32,13 @@ #include #include -#include -#include -#include +#include #include #include #include #include +#include +#include namespace google { namespace protobuf { @@ -76,12 +76,12 @@ class CppMetadataTest : public ::testing::Test { std::string output_base = TestTempDir() + "/" + StripProto(filename); - if (pb_cc != NULL) { + if (pb_cc != nullptr) { GOOGLE_CHECK_OK( File::GetContents(output_base + ".pb.cc", pb_cc, true)); } - if (pb_h != NULL && pb_h_info != NULL) { + if (pb_h != nullptr && pb_h_info != nullptr) { GOOGLE_CHECK_OK( File::GetContents(output_base + ".pb.h", pb_h, true)); if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { @@ -89,7 +89,7 @@ class CppMetadataTest : public ::testing::Test { } } - if (proto_h != NULL && proto_h_info != NULL) { + if (proto_h != nullptr && proto_h_info != nullptr) { GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h, true)); if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { @@ -112,15 +112,15 @@ TEST_F(CppMetadataTest, CapturesEnumNames) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_EQ("Enum", file.enum_type(0).name()); std::vector enum_path; enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber); enum_path.push_back(0); const GeneratedCodeInfo::Annotation* enum_annotation = atu::FindAnnotationOnPath(info, "test.proto", enum_path); - EXPECT_TRUE(NULL != enum_annotation); + EXPECT_TRUE(nullptr != enum_annotation); EXPECT_TRUE(atu::AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum")); } @@ -129,8 +129,8 @@ TEST_F(CppMetadataTest, AddsPragma) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_TRUE(pb_h.find("#ifdef guard_name") != std::string::npos); EXPECT_TRUE(pb_h.find("#pragma pragma_name \"test.pb.h.meta\"") != std::string::npos); @@ -141,15 +141,15 @@ TEST_F(CppMetadataTest, CapturesMessageNames) { GeneratedCodeInfo info; std::string pb_h; atu::AddFile("test.proto", kSmallTestFile); - EXPECT_TRUE( - CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); + EXPECT_TRUE(CaptureMetadata("test.proto", &file, &pb_h, &info, nullptr, + nullptr, nullptr)); EXPECT_EQ("Message", file.message_type(0).name()); std::vector message_path; message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber); message_path.push_back(0); const GeneratedCodeInfo::Annotation* message_annotation = atu::FindAnnotationOnPath(info, "test.proto", message_path); - EXPECT_TRUE(NULL != message_annotation); + EXPECT_TRUE(nullptr != message_annotation); EXPECT_TRUE( atu::AnnotationMatchesSubstring(pb_h, message_annotation, "Message")); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/move_unittest.cc similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/move_unittest.cc diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_names.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/names.h similarity index 95% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_names.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/names.h index 6bcbff06..7404ac53 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_names.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/names.h @@ -33,6 +33,7 @@ #include +// Must be included last. #include namespace google { @@ -50,9 +51,9 @@ namespace cpp { // // For example, if you had: // package foo.bar; -// message Baz { message Qux {} } +// message Baz { message Moo {} } // Then the non-qualified version would be: -// Baz_Qux +// Baz_Moo std::string ClassName(const Descriptor* descriptor); std::string ClassName(const EnumDescriptor* enum_descriptor); @@ -60,9 +61,9 @@ std::string ClassName(const EnumDescriptor* enum_descriptor); // // For example, if you had: // package foo.bar; -// message Baz { message Qux {} } -// Then the qualified ClassName for Qux would be: -// ::foo::bar::Baz_Qux +// message Baz { message Moo {} } +// Then the qualified ClassName for Moo would be: +// ::foo::bar::Baz_Moo std::string QualifiedClassName(const Descriptor* d); std::string QualifiedClassName(const EnumDescriptor* d); std::string QualifiedExtensionName(const FieldDescriptor* d); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/options.h similarity index 91% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/options.h index d0f16d03..5d935e9e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/options.h @@ -57,34 +57,40 @@ struct FieldListenerOptions { // Generator options (see generator.cc for a description of each): struct Options { + const AccessInfoMap* access_info_map = nullptr; std::string dllexport_decl; - bool safe_boundary_check = false; - bool proto_h = false; - bool transitive_pb_h = true; - bool annotate_headers = false; - EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement; - bool table_driven_parsing = false; - bool table_driven_serialization = false; - bool lite_implicit_weak_fields = false; - bool bootstrap = false; - bool opensource_runtime = false; - bool annotate_accessor = false; - bool unused_field_stripping = false; - bool profile_driven_inline_string = true; - bool force_inline_string = false; std::string runtime_include_base; - int num_cc_files = 0; std::string annotation_pragma_name; std::string annotation_guard_name; - const AccessInfoMap* access_info_map = nullptr; + FieldListenerOptions field_listener_options; + EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement; enum { kTCTableNever, kTCTableGuarded, kTCTableAlways } tctable_mode = kTCTableNever; - FieldListenerOptions field_listener_options; - bool eagerly_verified_lazy = false; + int num_cc_files = 0; + bool safe_boundary_check = false; + bool proto_h = false; + bool transitive_pb_h = true; + bool annotate_headers = false; + bool lite_implicit_weak_fields = false; + bool bootstrap = false; + bool opensource_runtime = false; + bool annotate_accessor = false; + bool unused_field_stripping = false; + bool unverified_lazy_message_sets = false; + bool unverified_lazy = false; + bool profile_driven_inline_string = true; + bool message_owned_arena_trial = false; + bool force_split = false; +#ifdef PROTOBUF_STABLE_EXPERIMENTS + bool force_eagerly_verified_lazy = true; + bool force_inline_string = true; +#else // PROTOBUF_STABLE_EXPERIMENTS bool force_eagerly_verified_lazy = false; + bool force_inline_string = false; +#endif // !PROTOBUF_STABLE_EXPERIMENTS }; } // namespace cpp diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.cc similarity index 95% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.cc index 0b660c75..20910520 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.cc @@ -28,9 +28,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include -#include +#include namespace google { namespace protobuf { @@ -47,7 +47,7 @@ class FieldGroup { FieldGroup() : preferred_location_(0) {} // A group with a single field. - FieldGroup(float preferred_location, const FieldDescriptor* field) + FieldGroup(double preferred_location, const FieldDescriptor* field) : preferred_location_(preferred_location), fields_(1, field) {} // Append the fields in 'other' to this group. @@ -63,7 +63,7 @@ class FieldGroup { fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); } - void SetPreferredLocation(float location) { preferred_location_ = location; } + void SetPreferredLocation(double location) { preferred_location_ = location; } const std::vector& fields() const { return fields_; } // FieldGroup objects sort by their preferred location. @@ -77,7 +77,7 @@ class FieldGroup { // field in this group in the original ordering of fields. This is very // approximate, but should put this group close to where its member fields // originally went. - float preferred_location_; + double preferred_location_; std::vector fields_; // We rely on the default copy constructor and operator= so this type can be // used in a vector. @@ -203,7 +203,7 @@ void PaddingOptimizer::OptimizeLayout( field_group.SetPreferredLocation(-1); } else { // Move incomplete 4-byte block to the end. - field_group.SetPreferredLocation(fields->size() + 1); + field_group.SetPreferredLocation(double{FieldDescriptor::kMaxNumber}); } } aligned_to_8[f].push_back(field_group); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.h similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.h index ebdb17de..9c76f38c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/padding_optimizer.h @@ -35,7 +35,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.cc new file mode 100644 index 00000000..0f1d767c --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -0,0 +1,1725 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { +using google::protobuf::internal::WireFormat; +using google::protobuf::internal::WireFormatLite; + +std::vector GetOrderedFields( + const Descriptor* descriptor, const Options& options) { + std::vector ordered_fields; + for (auto field : FieldRange(descriptor)) { + if (!IsFieldStripped(field, options)) { + ordered_fields.push_back(field); + } + } + std::sort(ordered_fields.begin(), ordered_fields.end(), + [](const FieldDescriptor* a, const FieldDescriptor* b) { + return a->number() < b->number(); + }); + return ordered_fields; +} + +bool HasInternalAccessors(const FieldOptions::CType ctype) { + return ctype == FieldOptions::STRING || ctype == FieldOptions::CORD; +} + +int TagSize(uint32_t field_number) { + if (field_number < 16) return 1; + GOOGLE_CHECK_LT(field_number, (1 << 14)) + << "coded tag for " << field_number << " too big for uint16_t"; + return 2; +} + +std::string FieldParseFunctionName( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options); + +bool IsFieldEligibleForFastParsing( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + const auto* field = entry.field; + // Map, oneof, weak, and lazy fields are not handled on the fast path. + if (field->is_map() || field->real_containing_oneof() || + field->options().weak() || + IsImplicitWeakField(field, options, scc_analyzer) || + IsLazy(field, options, scc_analyzer)) { + return false; + } + + // We will check for a valid auxiliary index range later. However, we might + // want to change the value we check for inlined string fields. + int aux_idx = entry.aux_idx; + + switch (field->type()) { + case FieldDescriptor::TYPE_ENUM: + // If enum values are not validated at parse time, then this field can be + // handled on the fast path like an int32. + if (HasPreservingUnknownEnumSemantics(field)) { + break; + } + if (field->is_repeated() && field->is_packed()) { + return false; + } + break; + + // Some bytes fields can be handled on fast path. + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: + if (field->options().ctype() != FieldOptions::STRING) { + return false; + } + if (IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + // For inlined strings, the donation state index is stored in the + // `aux_idx` field of the fast parsing info. We need to check the range + // of that value instead of the auxiliary index. + aux_idx = entry.inlined_string_idx; + } + break; + + default: + break; + } + + if (HasHasbit(field)) { + // The tailcall parser can only update the first 32 hasbits. Fields with + // has-bits beyond the first 32 are handled by mini parsing/fallback. + GOOGLE_CHECK_GE(entry.hasbit_idx, 0) << field->DebugString(); + if (entry.hasbit_idx >= 32) return false; + } + + // If the field needs auxiliary data, then the aux index is needed. This + // must fit in a uint8_t. + if (aux_idx > std::numeric_limits::max()) { + return false; + } + + // The largest tag that can be read by the tailcall parser is two bytes + // when varint-coded. This allows 14 bits for the numeric tag value: + // byte 0 byte 1 + // 1nnnnttt 0nnnnnnn + // ^^^^^^^ ^^^^^^^ + if (field->number() >= 1 << 11) return false; + + return true; +} + +std::vector SplitFastFieldsForSize( + const std::vector& field_entries, + int table_size_log2, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + std::vector result(1 << table_size_log2); + const uint32_t idx_mask = result.size() - 1; + + for (const auto& entry : field_entries) { + if (!IsFieldEligibleForFastParsing(entry, options, scc_analyzer)) { + continue; + } + + const auto* field = entry.field; + uint32_t tag = WireFormat::MakeTag(field); + + // Construct the varint-coded tag. If it is more than 7 bits, we need to + // shift the high bits and add a continue bit. + if (uint32_t hibits = tag & 0xFFFFFF80) { + tag = tag + hibits + 128; // tag = lobits + 2*hibits + 128 + } + + // The field index is determined by the low bits of the field number, where + // the table size determines the width of the mask. The largest table + // supported is 32 entries. The parse loop uses these bits directly, so that + // the dispatch does not require arithmetic: + // byte 0 byte 1 + // tag: 1nnnnttt 0nnnnnnn + // ^^^^^ + // idx (table_size_log2=5) + // This means that any field number that does not fit in the lower 4 bits + // will always have the top bit of its table index asserted. + const uint32_t fast_idx = (tag >> 3) & idx_mask; + + TailCallTableInfo::FastFieldInfo& info = result[fast_idx]; + if (info.field != nullptr) { + // This field entry is already filled. + continue; + } + + // Fill in this field's entry: + GOOGLE_CHECK(info.func_name.empty()) << info.func_name; + info.func_name = FieldParseFunctionName(entry, options); + info.field = field; + info.coded_tag = tag; + // If this field does not have presence, then it can set an out-of-bounds + // bit (tailcall parsing uses a uint64_t for hasbits, but only stores 32). + info.hasbit_idx = HasHasbit(field) ? entry.hasbit_idx : 63; + if (IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + info.aux_idx = static_cast(entry.inlined_string_idx); + } else { + info.aux_idx = static_cast(entry.aux_idx); + } + } + return result; +} + +// Filter out fields that will be handled by mini parsing. +std::vector FilterMiniParsedFields( + const std::vector& fields, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + std::vector generated_fallback_fields; + + for (const auto* field : fields) { + bool handled = false; + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_BOOL: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_INT64: + // These are handled by MiniParse, so we don't need any generated + // fallback code. + handled = true; + break; + + case FieldDescriptor::TYPE_ENUM: + if (field->is_repeated() && !HasPreservingUnknownEnumSemantics(field)) { + // TODO(b/206890171): handle packed repeated closed enums + // Non-packed repeated can be handled using tables, but we still + // need to generate fallback code for all repeated enums in order to + // handle packed encoding. This is because of the lite/full split + // when handling invalid enum values in a packed field. + handled = false; + } else { + handled = true; + } + break; + + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_STRING: + if (IsStringInlined(field, options)) { + // TODO(b/198211897): support InilnedStringField. + handled = false; + } else { + handled = true; + } + break; + + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_GROUP: + // TODO(b/210762816): support remaining field types. + if (field->is_map() || IsWeak(field, options) || + IsImplicitWeakField(field, options, scc_analyzer) || + IsLazy(field, options, scc_analyzer)) { + handled = false; + } else { + handled = true; + } + break; + + default: + handled = false; + break; + } + if (!handled) generated_fallback_fields.push_back(field); + } + + return generated_fallback_fields; +} + +} // namespace + +TailCallTableInfo::TailCallTableInfo( + const Descriptor* descriptor, const Options& options, + const std::vector& ordered_fields, + const std::vector& has_bit_indices, + const std::vector& inlined_string_indices, + MessageSCCAnalyzer* scc_analyzer) { + int oneof_count = descriptor->real_oneof_decl_count(); + // If this message has any oneof fields, store the case offset in the first + // auxiliary entry. + if (oneof_count > 0) { + GOOGLE_LOG_IF(DFATAL, ordered_fields.empty()) + << "Invalid message: " << descriptor->full_name() << " has " + << oneof_count << " oneof declarations, but no fields"; + aux_entries.push_back(StrCat("_fl::Offset{offsetof(", + ClassName(descriptor), + ", _impl_._oneof_case_)}")); + } + + // If this message has any inlined string fields, store the donation state + // offset in the second auxiliary entry. + if (!inlined_string_indices.empty()) { + aux_entries.resize(2); // pad if necessary + aux_entries[1] = + StrCat("_fl::Offset{offsetof(", ClassName(descriptor), + ", _impl_._inlined_string_donated_)}"); + } + + // Fill in mini table entries. + for (const FieldDescriptor* field : ordered_fields) { + field_entries.push_back( + {field, (HasHasbit(field) ? has_bit_indices[field->index()] : -1)}); + auto& entry = field_entries.back(); + + if (field->type() == FieldDescriptor::TYPE_MESSAGE || + field->type() == FieldDescriptor::TYPE_GROUP) { + // Message-typed fields have a FieldAux with the default instance pointer. + if (field->is_map()) { + // TODO(b/205904770): generate aux entries for maps + } else if (IsWeak(field, options)) { + // Don't generate anything for weak fields. They are handled by the + // generated fallback. + } else if (IsImplicitWeakField(field, options, scc_analyzer)) { + // Implicit weak fields don't need to store a default instance pointer. + } else if (IsLazy(field, options, scc_analyzer)) { + // Lazy fields are handled by the generated fallback function. + } else { + field_entries.back().aux_idx = aux_entries.size(); + const Descriptor* field_type = field->message_type(); + aux_entries.push_back(StrCat( + "reinterpret_cast(&", QualifiedDefaultInstanceName(field_type, options), ")")); + } + } else if (field->type() == FieldDescriptor::TYPE_ENUM && + !HasPreservingUnknownEnumSemantics(field)) { + // Enum fields which preserve unknown values (proto3 behavior) are + // effectively int32 fields with respect to parsing -- i.e., the value + // does not need to be validated at parse time. + // + // Enum fields which do not preserve unknown values (proto2 behavior) use + // a FieldAux to store validation information. If the enum values are + // sequential (and within a range we can represent), then the FieldAux + // entry represents the range using the minimum value (which must fit in + // an int16_t) and count (a uint16_t). Otherwise, the entry holds a + // pointer to the generated Name_IsValid function. + + entry.aux_idx = aux_entries.size(); + const EnumDescriptor* enum_type = field->enum_type(); + GOOGLE_CHECK_GT(enum_type->value_count(), 0) << enum_type->DebugString(); + + // Check if the enum values are a single, contiguous range. + std::vector enum_values; + for (int i = 0, N = enum_type->value_count(); i < N; ++i) { + enum_values.push_back(enum_type->value(i)->number()); + } + auto values_begin = enum_values.begin(); + auto values_end = enum_values.end(); + std::sort(values_begin, values_end); + enum_values.erase(std::unique(values_begin, values_end), values_end); + + if (enum_values.back() - enum_values[0] == enum_values.size() - 1 && + enum_values[0] >= std::numeric_limits::min() && + enum_values[0] <= std::numeric_limits::max() && + enum_values.size() <= std::numeric_limits::max()) { + entry.is_enum_range = true; + aux_entries.push_back( + StrCat(enum_values[0], ", ", enum_values.size())); + } else { + entry.is_enum_range = false; + aux_entries.push_back( + StrCat(QualifiedClassName(enum_type, options), "_IsValid")); + } + } else if ((field->type() == FieldDescriptor::TYPE_STRING || + field->type() == FieldDescriptor::TYPE_BYTES) && + IsStringInlined(field, options)) { + GOOGLE_CHECK(!field->is_repeated()); + // Inlined strings have an extra marker to represent their donation state. + int idx = inlined_string_indices[field->index()]; + // For mini parsing, the donation state index is stored as an `offset` + // auxiliary entry. + entry.aux_idx = aux_entries.size(); + aux_entries.push_back(StrCat("_fl::Offset{", idx, "}")); + // For fast table parsing, the donation state index is stored instead of + // the aux_idx (this will limit the range to 8 bits). + entry.inlined_string_idx = idx; + } + } + + // Choose the smallest fast table that covers the maximum number of fields. + table_size_log2 = 0; // fallback value + int num_fast_fields = -1; + for (int try_size_log2 : {0, 1, 2, 3, 4, 5}) { + size_t try_size = 1 << try_size_log2; + auto split_fields = SplitFastFieldsForSize(field_entries, try_size_log2, + options, scc_analyzer); + GOOGLE_CHECK_EQ(split_fields.size(), try_size); + int try_num_fast_fields = 0; + for (const auto& info : split_fields) { + if (info.field != nullptr) ++try_num_fast_fields; + } + // Use this size if (and only if) it covers more fields. + if (try_num_fast_fields > num_fast_fields) { + fast_path_fields = std::move(split_fields); + table_size_log2 = try_size_log2; + num_fast_fields = try_num_fast_fields; + } + // The largest table we allow has the same number of entries as the message + // has fields, rounded up to the next power of 2 (e.g., a message with 5 + // fields can have a fast table of size 8). A larger table *might* cover + // more fields in certain cases, but a larger table in that case would have + // mostly empty entries; so, we cap the size to avoid pathologically sparse + // tables. + if (try_size > ordered_fields.size()) { + break; + } + } + + // Filter out fields that are handled by MiniParse. We don't need to generate + // a fallback for these, which saves code size. + fallback_fields = FilterMiniParsedFields(ordered_fields, options, + scc_analyzer); + + // If there are no fallback fields, and at most one extension range, the + // parser can use a generic fallback function. Otherwise, a message-specific + // fallback routine is needed. + use_generated_fallback = + !fallback_fields.empty() || descriptor->extension_range_count() > 1; +} + +ParseFunctionGenerator::ParseFunctionGenerator( + const Descriptor* descriptor, int max_has_bit_index, + const std::vector& has_bit_indices, + const std::vector& inlined_string_indices, const Options& options, + MessageSCCAnalyzer* scc_analyzer, + const std::map& vars) + : descriptor_(descriptor), + scc_analyzer_(scc_analyzer), + options_(options), + variables_(vars), + inlined_string_indices_(inlined_string_indices), + ordered_fields_(GetOrderedFields(descriptor_, options_)), + num_hasbits_(max_has_bit_index) { + if (should_generate_tctable()) { + tc_table_info_.reset(new TailCallTableInfo( + descriptor_, options_, ordered_fields_, has_bit_indices, + inlined_string_indices, scc_analyzer)); + } + SetCommonVars(options_, &variables_); + SetCommonMessageDataVariables(descriptor_, &variables_); + SetUnknownFieldsVariable(descriptor_, options_, &variables_); + variables_["classname"] = ClassName(descriptor, false); +} + +void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { + Formatter format(printer, variables_); + if (should_generate_tctable()) { + format.Outdent(); + if (should_generate_guarded_tctable()) { + format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + } + format( + " private:\n" + " static const char* Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL);\n" + " public:\n"); + if (should_generate_guarded_tctable()) { + format("#endif\n"); + } + format.Indent(); + } + format( + "const char* _InternalParse(const char* ptr, " + "::$proto_ns$::internal::ParseContext* ctx) final;\n"); +} + +void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { + Formatter format(printer, variables_); + bool need_parse_function = true; + if (descriptor_->options().message_set_wire_format()) { + // Special-case MessageSet. + need_parse_function = false; + format( + "const char* $classname$::_InternalParse(const char* ptr,\n" + " ::_pbi::ParseContext* ctx) {\n" + "$annotate_deserialize$"); + if (!options_.unverified_lazy_message_sets && + ShouldVerify(descriptor_, options_, scc_analyzer_)) { + format( + " ctx->set_lazy_eager_verify_func(&$classname$::InternalVerify);\n"); + } + format( + " return $extensions$.ParseMessageSet(ptr, \n" + " internal_default_instance(), &_internal_metadata_, ctx);\n" + "}\n"); + } + if (!should_generate_tctable()) { + if (need_parse_function) { + GenerateLoopingParseFunction(format); + } + return; + } + if (should_generate_guarded_tctable()) { + format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); + } + if (need_parse_function) { + GenerateTailcallParseFunction(format); + } + if (tc_table_info_->use_generated_fallback) { + GenerateTailcallFallbackFunction(format); + } + if (should_generate_guarded_tctable()) { + if (need_parse_function) { + format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n"); + GenerateLoopingParseFunction(format); + } + format("\n#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + } +} + +bool ParseFunctionGenerator::should_generate_tctable() const { + if (options_.tctable_mode == Options::kTCTableNever) { + return false; + } + return true; +} + +void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); + + // Generate an `_InternalParse` that starts the tail-calling loop. + format( + "const char* $classname$::_InternalParse(\n" + " const char* ptr, ::_pbi::ParseContext* ctx) {\n" + "$annotate_deserialize$" + " ptr = ::_pbi::TcParser::ParseLoop(this, ptr, ctx, " + "&_table_.header);\n"); + format( + " return ptr;\n" + "}\n\n"); +} + +void ParseFunctionGenerator::GenerateTailcallFallbackFunction( + Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); + format( + "const char* $classname$::Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL) {\n" + "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr\n"); + format.Indent(); + format("auto* typed_msg = static_cast<$classname$*>(msg);\n"); + + if (num_hasbits_ > 0) { + // Sync hasbits + format("typed_msg->_impl_._has_bits_[0] = hasbits;\n"); + } + format("uint32_t tag = data.tag();\n"); + + format.Set("msg", "typed_msg->"); + format.Set("this", "typed_msg"); + format.Set("has_bits", "typed_msg->_impl_._has_bits_"); + format.Set("next_tag", "goto next_tag"); + GenerateParseIterationBody(format, descriptor_, + tc_table_info_->fallback_fields); + + format.Outdent(); + format( + "next_tag:\n" + "message_done:\n" + " return ptr;\n" + "#undef CHK_\n" + "}\n"); +} + +struct SkipEntry16 { + uint16_t skipmap; + uint16_t field_entry_offset; +}; +struct SkipEntryBlock { + uint32_t first_fnum; + std::vector entries; +}; +struct NumToEntryTable { + uint32_t skipmap32; // for fields #1 - #32 + std::vector blocks; + // Compute the number of uint16_t required to represent this table. + int size16() const { + int size = 2; // for the termination field# + for (const auto& block : blocks) { + // 2 for the field#, 1 for a count of skip entries, 2 for each entry. + size += 3 + block.entries.size() * 2; + } + return size; + } +}; + +static NumToEntryTable MakeNumToEntryTable( + const std::vector& field_descriptors); + +void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { + if (!should_generate_tctable()) { + return; + } + Formatter format(printer, variables_); + if (should_generate_guarded_tctable()) { + format.Outdent(); + format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + format.Indent(); + } + auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_); + format( + "static const ::$proto_ns$::internal::" + "TcParseTable<$1$, $2$, $3$, $4$, $5$> _table_;\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(), + field_num_to_entry_table.size16()); + if (should_generate_guarded_tctable()) { + format.Outdent(); + format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + format.Indent(); + } +} + +void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) { + if (!should_generate_tctable()) { + return; + } + Formatter format(printer, variables_); + if (should_generate_guarded_tctable()) { + format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + } + GenerateTailCallTable(format); + if (should_generate_guarded_tctable()) { + format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n"); + } +} + +void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) { + format( + "const char* $classname$::_InternalParse(const char* ptr, " + "::_pbi::ParseContext* ctx) {\n" + "$annotate_deserialize$" + "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n"); + format.Indent(); + format.Set("msg", ""); + format.Set("this", "this"); + int hasbits_size = 0; + if (num_hasbits_ > 0) { + hasbits_size = (num_hasbits_ + 31) / 32; + } + // For now only optimize small hasbits. + if (hasbits_size != 1) hasbits_size = 0; + if (hasbits_size) { + format("_Internal::HasBits has_bits{};\n"); + format.Set("has_bits", "has_bits"); + } else { + format.Set("has_bits", "_impl_._has_bits_"); + } + format.Set("next_tag", "continue"); + format("while (!ctx->Done(&ptr)) {\n"); + format.Indent(); + + format( + "uint32_t tag;\n" + "ptr = ::_pbi::ReadTag(ptr, &tag);\n"); + GenerateParseIterationBody(format, descriptor_, ordered_fields_); + + format.Outdent(); + format("} // while\n"); + + format.Outdent(); + format("message_done:\n"); + if (hasbits_size) format(" _impl_._has_bits_.Or(has_bits);\n"); + + format( + " return ptr;\n" + "failure:\n" + " ptr = nullptr;\n" + " goto message_done;\n" + "#undef CHK_\n" + "}\n"); +} + +static NumToEntryTable MakeNumToEntryTable( + const std::vector& field_descriptors) { + NumToEntryTable num_to_entry_table; + num_to_entry_table.skipmap32 = static_cast(-1); + + // skip_entry_block is the current block of SkipEntries that we're + // appending to. cur_block_first_fnum is the number of the first + // field represented by the block. + uint16_t field_entry_index = 0; + uint16_t N = field_descriptors.size(); + // First, handle field numbers 1-32, which affect only the initial + // skipmap32 and don't generate additional skip-entry blocks. + for (; field_entry_index != N; ++field_entry_index) { + auto* field_descriptor = field_descriptors[field_entry_index]; + if (field_descriptor->number() > 32) break; + auto skipmap32_index = field_descriptor->number() - 1; + num_to_entry_table.skipmap32 -= 1 << skipmap32_index; + } + // If all the field numbers were less than or equal to 32, we will have + // no further entries to process, and we are already done. + if (field_entry_index == N) return num_to_entry_table; + + SkipEntryBlock* block = nullptr; + bool start_new_block = true; + // To determine sparseness, track the field number corresponding to + // the start of the most recent skip entry. + uint32_t last_skip_entry_start = 0; + for (; field_entry_index != N; ++field_entry_index) { + auto* field_descriptor = field_descriptors[field_entry_index]; + uint32_t fnum = field_descriptor->number(); + GOOGLE_CHECK_GT(fnum, last_skip_entry_start); + if (start_new_block == false) { + // If the next field number is within 15 of the last_skip_entry_start, we + // continue writing just to that entry. If it's between 16 and 31 more, + // then we just extend the current block by one. If it's more than 31 + // more, we have to add empty skip entries in order to continue using the + // existing block. Obviously it's just 32 more, it doesn't make sense to + // start a whole new block, since new blocks mean having to write out + // their starting field number, which is 32 bits, as well as the size of + // the additional block, which is 16... while an empty SkipEntry16 only + // costs 32 bits. So if it was 48 more, it's a slight space win; we save + // 16 bits, but probably at the cost of slower run time. We're choosing + // 96 for now. + if (fnum - last_skip_entry_start > 96) start_new_block = true; + } + if (start_new_block) { + num_to_entry_table.blocks.push_back(SkipEntryBlock{fnum}); + block = &num_to_entry_table.blocks.back(); + start_new_block = false; + } + + auto skip_entry_num = (fnum - block->first_fnum) / 16; + auto skip_entry_index = (fnum - block->first_fnum) % 16; + while (skip_entry_num >= block->entries.size()) + block->entries.push_back({0xFFFF, field_entry_index}); + block->entries[skip_entry_num].skipmap -= 1 << (skip_entry_index); + + last_skip_entry_start = fnum - skip_entry_index; + } + return num_to_entry_table; +} + +void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { + GOOGLE_CHECK(should_generate_tctable()); + // All entries without a fast-path parsing function need a fallback. + std::string fallback; + if (tc_table_info_->use_generated_fallback) { + fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; + } else { + fallback = "::_pbi::TcParser::GenericFallback"; + if (GetOptimizeFor(descriptor_->file(), options_) == + FileOptions::LITE_RUNTIME) { + fallback += "Lite"; + } + } + + // For simplicity and speed, the table is not covering all proto + // configurations. This model uses a fallback to cover all situations that + // the table can't accommodate, together with unknown fields or extensions. + // These are number of fields over 32, fields with 3 or more tag bytes, + // maps, weak fields, lazy, more than 1 extension range. In the cases + // the table is sufficient we can use a generic routine, that just handles + // unknown fields and potentially an extension range. + auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_); + format( + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1\n" + "const ::_pbi::TcParseTable<$1$, $2$, $3$, $4$, $5$> " + "$classname$::_table_ = " + "{\n", + tc_table_info_->table_size_log2, ordered_fields_.size(), + tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(), + field_num_to_entry_table.size16()); + { + auto table_scope = format.ScopedIndent(); + format("{\n"); + { + auto header_scope = format.ScopedIndent(); + if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) { + format("PROTOBUF_FIELD_OFFSET($classname$, _impl_._has_bits_),\n"); + } else { + format("0, // no _has_bits_\n"); + } + if (descriptor_->extension_range_count() == 1) { + format( + "PROTOBUF_FIELD_OFFSET($classname$, $extensions$),\n" + "$1$, $2$, // extension_range_{low,high}\n", + descriptor_->extension_range(0)->start, + descriptor_->extension_range(0)->end); + } else { + format("0, 0, 0, // no _extensions_\n"); + } + format("$1$, $2$, // max_field_number, fast_idx_mask\n", + (ordered_fields_.empty() ? 0 : ordered_fields_.back()->number()), + (((1 << tc_table_info_->table_size_log2) - 1) << 3)); + format( + "offsetof(decltype(_table_), field_lookup_table),\n" + "$1$, // skipmap\n", + field_num_to_entry_table.skipmap32); + if (ordered_fields_.empty()) { + format( + "offsetof(decltype(_table_), field_names), // no field_entries\n"); + } else { + format("offsetof(decltype(_table_), field_entries),\n"); + } + + format( + "$1$, // num_field_entries\n" + "$2$, // num_aux_entries\n", + ordered_fields_.size(), tc_table_info_->aux_entries.size()); + if (tc_table_info_->aux_entries.empty()) { + format( + "offsetof(decltype(_table_), field_names), // no aux_entries\n"); + } else { + format("offsetof(decltype(_table_), aux_entries),\n"); + } + format( + "&$1$._instance,\n" + "$2$, // fallback\n" + "", + DefaultInstanceName(descriptor_, options_), fallback); + } + format("}, {{\n"); + { + // fast_entries[] + auto fast_scope = format.ScopedIndent(); + GenerateFastFieldEntries(format); + } + format("}}, {{\n"); + { + // field_lookup_table[] + auto field_lookup_scope = format.ScopedIndent(); + int line_entries = 0; + for (int i = 0, N = field_num_to_entry_table.blocks.size(); i < N; ++i) { + SkipEntryBlock& entry_block = field_num_to_entry_table.blocks[i]; + format("$1$, $2$, $3$,\n", entry_block.first_fnum & 65535, + entry_block.first_fnum / 65536, entry_block.entries.size()); + for (auto se16 : entry_block.entries) { + if (line_entries == 0) { + format("$1$, $2$,", se16.skipmap, se16.field_entry_offset); + ++line_entries; + } else if (line_entries < 5) { + format(" $1$, $2$,", se16.skipmap, se16.field_entry_offset); + ++line_entries; + } else { + format(" $1$, $2$,\n", se16.skipmap, se16.field_entry_offset); + line_entries = 0; + } + } + } + if (line_entries) format("\n"); + format("65535, 65535\n"); + } + if (ordered_fields_.empty()) { + GOOGLE_LOG_IF(DFATAL, !tc_table_info_->aux_entries.empty()) + << "Invalid message: " << descriptor_->full_name() << " has " + << tc_table_info_->aux_entries.size() + << " auxiliary field entries, but no fields"; + format( + "}},\n" + "// no field_entries, or aux_entries\n" + "{{\n"); + } else { + format("}}, {{\n"); + { + // field_entries[] + auto field_scope = format.ScopedIndent(); + GenerateFieldEntries(format); + } + if (tc_table_info_->aux_entries.empty()) { + format( + "}},\n" + "// no aux_entries\n" + "{{\n"); + } else { + format("}}, {{\n"); + { + // aux_entries[] + auto aux_scope = format.ScopedIndent(); + for (const std::string& aux_entry : tc_table_info_->aux_entries) { + format("{$1$},\n", aux_entry); + } + } + format("}}, {{\n"); + } + } // ordered_fields_.empty() + { + // field_names[] + auto field_name_scope = format.ScopedIndent(); + GenerateFieldNames(format); + } + format("}},\n"); + } + format("};\n\n"); // _table_ +} + +void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) { + for (const auto& info : tc_table_info_->fast_path_fields) { + if (info.field != nullptr) { + PrintFieldComment(format, info.field); + } + if (info.func_name.empty()) { + format("{::_pbi::TcParser::MiniParse, {}},\n"); + } else { + bool cold = ShouldSplit(info.field, options_); + format( + "{$1$,\n" + " {$2$, $3$, $4$, PROTOBUF_FIELD_OFFSET($classname$$5$, $6$)}},\n", + info.func_name, info.coded_tag, info.hasbit_idx, info.aux_idx, + cold ? "::Impl_::Split" : "", + cold ? FieldName(info.field) + "_" + : FieldMemberName(info.field, /*cold=*/false)); + } + } +} + +static void FormatFieldKind(Formatter& format, + const TailCallTableInfo::FieldEntryInfo& entry, + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + const FieldDescriptor* field = entry.field; + // Spell the field kind in proto language declaration order, starting with + // cardinality: + format("(::_fl::kFc"); + if (HasHasbit(field)) { + format("Optional"); + } else if (field->is_repeated()) { + format("Repeated"); + } else if (field->real_containing_oneof()) { + format("Oneof"); + } else { + format("Singular"); + } + + // The rest of the type uses convenience aliases: + format(" | ::_fl::k"); + if (field->is_repeated() && field->is_packed()) { + format("Packed"); + } + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + format("Double"); + break; + case FieldDescriptor::TYPE_FLOAT: + format("Float"); + break; + case FieldDescriptor::TYPE_FIXED32: + format("Fixed32"); + break; + case FieldDescriptor::TYPE_SFIXED32: + format("SFixed32"); + break; + case FieldDescriptor::TYPE_FIXED64: + format("Fixed64"); + break; + case FieldDescriptor::TYPE_SFIXED64: + format("SFixed64"); + break; + case FieldDescriptor::TYPE_BOOL: + format("Bool"); + break; + case FieldDescriptor::TYPE_ENUM: + if (HasPreservingUnknownEnumSemantics(field)) { + // No validation is required. + format("OpenEnum"); + } else if (entry.is_enum_range) { + // Validation is done by range check (start/length in FieldAux). + format("EnumRange"); + } else { + // Validation uses the generated _IsValid function. + format("Enum"); + } + break; + case FieldDescriptor::TYPE_UINT32: + format("UInt32"); + break; + case FieldDescriptor::TYPE_SINT32: + format("SInt32"); + break; + case FieldDescriptor::TYPE_INT32: + format("Int32"); + break; + case FieldDescriptor::TYPE_UINT64: + format("UInt64"); + break; + case FieldDescriptor::TYPE_SINT64: + format("SInt64"); + break; + case FieldDescriptor::TYPE_INT64: + format("Int64"); + break; + + case FieldDescriptor::TYPE_BYTES: + format("Bytes"); + break; + case FieldDescriptor::TYPE_STRING: { + auto mode = GetUtf8CheckMode(field, options); + switch (mode) { + case Utf8CheckMode::kStrict: + format("Utf8String"); + break; + case Utf8CheckMode::kVerify: + format("RawString"); + break; + case Utf8CheckMode::kNone: + // Treat LITE_RUNTIME strings as bytes. + format("Bytes"); + break; + default: + GOOGLE_LOG(FATAL) << "Invalid Utf8CheckMode (" << static_cast(mode) + << ") for " << field->DebugString(); + } + break; + } + + case FieldDescriptor::TYPE_GROUP: + format("Message | ::_fl::kRepGroup"); + break; + case FieldDescriptor::TYPE_MESSAGE: + if (field->is_map()) { + format("Map"); + } else { + format("Message"); + if (IsLazy(field, options, scc_analyzer)) { + format(" | ::_fl::kRepLazy"); + } else if (IsImplicitWeakField(field, options, scc_analyzer)) { + format(" | ::_fl::kRepIWeak"); + } + } + break; + } + + // Fill in extra information about string and bytes field representations. + if (field->type() == FieldDescriptor::TYPE_BYTES || + field->type() == FieldDescriptor::TYPE_STRING) { + if (field->is_repeated()) { + format(" | ::_fl::kRepSString"); + } else { + format(" | ::_fl::kRepAString"); + } + } + + format(")"); +} + +void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) { + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + PrintFieldComment(format, field); + format("{"); + if (IsWeak(field, options_)) { + // Weak fields are handled by the generated fallback function. + // (These are handled by legacy Google-internal logic.) + format("/* weak */ 0, 0, 0, 0"); + } else { + const OneofDescriptor* oneof = field->real_containing_oneof(); + bool cold = ShouldSplit(field, options_); + format("PROTOBUF_FIELD_OFFSET($classname$$1$, $2$), $3$, $4$,\n ", + cold ? "::Impl_::Split" : "", + cold ? FieldName(field) + "_" + : FieldMemberName(field, /*cold=*/false), + (oneof ? oneof->index() : entry.hasbit_idx), entry.aux_idx); + FormatFieldKind(format, entry, options_, scc_analyzer_); + } + format("},\n"); + } +} + +static constexpr int kMaxNameLength = 255; + +int ParseFunctionGenerator::CalculateFieldNamesSize() const { + // The full name of the message appears first. + int size = std::min(static_cast(descriptor_->full_name().size()), + kMaxNameLength); + int lengths_size = 1; + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + GOOGLE_CHECK_LE(field->name().size(), kMaxNameLength); + size += field->name().size(); + lengths_size += 1; + } + // align to an 8-byte boundary + lengths_size = (lengths_size + 7) & -8; + return size + lengths_size + 1; +} + +static void FormatOctal(Formatter& format, int size) { + int octal_size = ((size >> 6) & 3) * 100 + // + ((size >> 3) & 7) * 10 + // + ((size >> 0) & 7); + format("\\$1$", octal_size); +} + +void ParseFunctionGenerator::GenerateFieldNames(Formatter& format) { + // First, we output the size of each string, as an unsigned byte. The first + // string is the message name. + int count = 1; + format("\""); + FormatOctal(format, + std::min(static_cast(descriptor_->full_name().size()), 255)); + for (const auto& entry : tc_table_info_->field_entries) { + FormatOctal(format, entry.field->name().size()); + ++count; + } + while (count & 7) { // align to an 8-byte boundary + format("\\0"); + ++count; + } + format("\"\n"); + // The message name is stored at the beginning of the string + std::string message_name = descriptor_->full_name(); + if (message_name.size() > kMaxNameLength) { + static constexpr int kNameHalfLength = (kMaxNameLength - 3) / 2; + message_name = StrCat( + message_name.substr(0, kNameHalfLength), "...", + message_name.substr(message_name.size() - kNameHalfLength)); + } + format("\"$1$\"\n", message_name); + // Then we output the actual field names + for (const auto& entry : tc_table_info_->field_entries) { + const FieldDescriptor* field = entry.field; + format("\"$1$\"\n", field->name()); + } +} + +void ParseFunctionGenerator::GenerateArenaString(Formatter& format, + const FieldDescriptor* field) { + if (HasHasbit(field)) { + format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); + } + format( + "if (arena != nullptr) {\n" + " ptr = ctx->ReadArenaString(ptr, &$msg$$field$, arena"); + if (IsStringInlined(field, options_)) { + GOOGLE_DCHECK(!inlined_string_indices_.empty()); + int inlined_string_index = inlined_string_indices_[field->index()]; + GOOGLE_DCHECK_GT(inlined_string_index, 0); + format(", &$msg$$inlined_string_donated_array$[0], $1$, $this$", + inlined_string_index); + } else { + GOOGLE_DCHECK(field->default_value_string().empty()); + } + format( + ");\n" + "} else {\n" + " ptr = ::_pbi::InlineGreedyStringParser(" + "$msg$$field$.MutableNoCopy(nullptr), ptr, ctx);\n" + "}\n" + "const std::string* str = &$msg$$field$.Get(); (void)str;\n"); +} + +void ParseFunctionGenerator::GenerateStrings(Formatter& format, + const FieldDescriptor* field, + bool check_utf8) { + FieldOptions::CType ctype = FieldOptions::STRING; + if (!options_.opensource_runtime) { + // Open source doesn't support other ctypes; + ctype = field->options().ctype(); + } + if (!field->is_repeated() && !options_.opensource_runtime && + GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && + // For now only use arena string for strings with empty defaults. + field->default_value_string().empty() && + !field->real_containing_oneof() && ctype == FieldOptions::STRING) { + GenerateArenaString(format, field); + } else { + std::string parser_name; + switch (ctype) { + case FieldOptions::STRING: + parser_name = "GreedyStringParser"; + break; + case FieldOptions::CORD: + parser_name = "CordParser"; + break; + case FieldOptions::STRING_PIECE: + parser_name = "StringPieceParser"; + break; + } + format( + "auto str = $msg$$1$$2$_$name$();\n" + "ptr = ::_pbi::Inline$3$(str, ptr, ctx);\n", + HasInternalAccessors(ctype) ? "_internal_" : "", + field->is_repeated() && !field->is_packable() ? "add" : "mutable", + parser_name); + } + // It is intentionally placed before VerifyUTF8 because it doesn't make sense + // to verify UTF8 when we already know parsing failed. + format("CHK_(ptr);\n"); + if (!check_utf8) return; // return if this is a bytes field + auto level = GetUtf8CheckMode(field, options_); + switch (level) { + case Utf8CheckMode::kNone: + return; + case Utf8CheckMode::kVerify: + format("#ifndef NDEBUG\n"); + break; + case Utf8CheckMode::kStrict: + format("CHK_("); + break; + } + std::string field_name; + field_name = "nullptr"; + if (HasDescriptorMethods(field->file(), options_)) { + field_name = StrCat("\"", field->full_name(), "\""); + } + format("::_pbi::VerifyUTF8(str, $1$)", field_name); + switch (level) { + case Utf8CheckMode::kNone: + return; + case Utf8CheckMode::kVerify: + format( + ";\n" + "#endif // !NDEBUG\n"); + break; + case Utf8CheckMode::kStrict: + format(");\n"); + break; + } +} + +void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, + const FieldDescriptor* field) { + if (field->is_packable()) { + if (field->type() == FieldDescriptor::TYPE_ENUM && + !HasPreservingUnknownEnumSemantics(field)) { + std::string enum_type = QualifiedClassName(field->enum_type(), options_); + format( + "ptr = " + "::$proto_ns$::internal::Packed$1$Parser<$unknown_fields_type$>(" + "$msg$_internal_mutable_$name$(), ptr, ctx, $2$_IsValid, " + "&$msg$_internal_metadata_, $3$);\n", + DeclaredTypeMethodName(field->type()), enum_type, field->number()); + } else { + format( + "ptr = ::$proto_ns$::internal::Packed$1$Parser(" + "$msg$_internal_mutable_$name$(), ptr, ctx);\n", + DeclaredTypeMethodName(field->type())); + } + format("CHK_(ptr);\n"); + } else { + auto field_type = field->type(); + switch (field_type) { + case FieldDescriptor::TYPE_STRING: + GenerateStrings(format, field, true /* utf8 */); + break; + case FieldDescriptor::TYPE_BYTES: + GenerateStrings(format, field, false /* utf8 */); + break; + case FieldDescriptor::TYPE_MESSAGE: { + if (field->is_map()) { + const FieldDescriptor* val = field->message_type()->map_value(); + GOOGLE_CHECK(val); + if (val->type() == FieldDescriptor::TYPE_ENUM && + !HasPreservingUnknownEnumSemantics(field)) { + format( + "auto object = " + "::$proto_ns$::internal::InitEnumParseWrapper<" + "$unknown_fields_type$>(&$msg$$field$, $1$_IsValid, " + "$2$, &$msg$_internal_metadata_);\n" + "ptr = ctx->ParseMessage(&object, ptr);\n", + QualifiedClassName(val->enum_type(), options_), + field->number()); + } else { + format("ptr = ctx->ParseMessage(&$msg$$field$, ptr);\n"); + } + } else if (IsLazy(field, options_, scc_analyzer_)) { + bool eager_verify = + IsEagerlyVerifiedLazy(field, options_, scc_analyzer_); + if (ShouldVerify(descriptor_, options_, scc_analyzer_)) { + format( + "ctx->set_lazy_eager_verify_func($1$);\n", + eager_verify + ? StrCat("&", ClassName(field->message_type(), true), + "::InternalVerify") + : "nullptr"); + } + if (field->real_containing_oneof()) { + format( + "if (!$msg$_internal_has_$name$()) {\n" + " $msg$clear_$1$();\n" + " $msg$$field$ = ::$proto_ns$::Arena::CreateMessage<\n" + " ::$proto_ns$::internal::LazyField>(" + "$msg$GetArenaForAllocation());\n" + " $msg$set_has_$name$();\n" + "}\n" + "auto* lazy_field = $msg$$field$;\n", + field->containing_oneof()->name()); + } else if (HasHasbit(field)) { + format( + "_Internal::set_has_$name$(&$has_bits$);\n" + "auto* lazy_field = &$msg$$field$;\n"); + } else { + format("auto* lazy_field = &$msg$$field$;\n"); + } + format( + "::$proto_ns$::internal::LazyFieldParseHelper<\n" + " ::$proto_ns$::internal::LazyField> parse_helper(\n" + " $1$::default_instance(),\n" + " $msg$GetArenaForAllocation(),\n" + " ::google::protobuf::internal::LazyVerifyOption::$2$,\n" + " lazy_field);\n" + "ptr = ctx->ParseMessage(&parse_helper, ptr);\n", + FieldMessageTypeName(field, options_), + eager_verify ? "kEager" : "kLazy"); + if (ShouldVerify(descriptor_, options_, scc_analyzer_) && + eager_verify) { + format("ctx->set_lazy_eager_verify_func(nullptr);\n"); + } + } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) { + if (!field->is_repeated()) { + format( + "ptr = ctx->ParseMessage(_Internal::mutable_$name$($this$), " + "ptr);\n"); + } else { + format( + "ptr = ctx->ParseMessage($msg$$field$.AddWeak(" + "reinterpret_cast($1$ptr_)" + "), ptr);\n", + QualifiedDefaultInstanceName(field->message_type(), options_)); + } + } else if (IsWeak(field, options_)) { + format( + "{\n" + " auto* default_ = &reinterpret_cast($1$);\n" + " ptr = ctx->ParseMessage($msg$$weak_field_map$.MutableMessage(" + "$2$, default_), ptr);\n" + "}\n", + QualifiedDefaultInstanceName(field->message_type(), options_), + field->number()); + } else { + format( + "ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), " + "ptr);\n"); + } + format("CHK_(ptr);\n"); + break; + } + default: + GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype " + << " filed type is " << field->type(); + } + } +} + +static bool ShouldRepeat(const FieldDescriptor* descriptor, + WireFormatLite::WireType wiretype) { + constexpr int kMaxTwoByteFieldNumber = 16 * 128; + return descriptor->number() < kMaxTwoByteFieldNumber && + descriptor->is_repeated() && + (!descriptor->is_packable() || + wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); +} + +void ParseFunctionGenerator::GenerateFieldBody( + Formatter& format, WireFormatLite::WireType wiretype, + const FieldDescriptor* field) { + Formatter::SaveState formatter_state(&format); + format.AddMap( + {{"name", FieldName(field)}, + {"primitive_type", PrimitiveTypeName(options_, field->cpp_type())}}); + if (field->is_repeated()) { + format.AddMap({{"put_field", StrCat("add_", FieldName(field))}, + {"mutable_field", StrCat("add_", FieldName(field))}}); + } else { + format.AddMap( + {{"put_field", StrCat("set_", FieldName(field))}, + {"mutable_field", StrCat("mutable_", FieldName(field))}}); + } + uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); + switch (wiretype) { + case WireFormatLite::WIRETYPE_VARINT: { + std::string type = PrimitiveTypeName(options_, field->cpp_type()); + if (field->type() == FieldDescriptor::TYPE_ENUM) { + format.Set("enum_type", + QualifiedClassName(field->enum_type(), options_)); + format( + "$uint64$ val = ::$proto_ns$::internal::ReadVarint64(&ptr);\n" + "CHK_(ptr);\n"); + if (!HasPreservingUnknownEnumSemantics(field)) { + format("if (PROTOBUF_PREDICT_TRUE($enum_type$_IsValid(val))) {\n"); + format.Indent(); + } + format("$msg$_internal_$put_field$(static_cast<$enum_type$>(val));\n"); + if (!HasPreservingUnknownEnumSemantics(field)) { + format.Outdent(); + format( + "} else {\n" + " ::$proto_ns$::internal::WriteVarint(" + "$1$, val, $msg$mutable_unknown_fields());\n" + "}\n", + field->number()); + } + } else { + std::string size = (field->type() == FieldDescriptor::TYPE_INT32 || + field->type() == FieldDescriptor::TYPE_SINT32 || + field->type() == FieldDescriptor::TYPE_UINT32) + ? "32" + : "64"; + std::string zigzag; + if ((field->type() == FieldDescriptor::TYPE_SINT32 || + field->type() == FieldDescriptor::TYPE_SINT64)) { + zigzag = "ZigZag"; + } + if (field->is_repeated() || field->real_containing_oneof()) { + format( + "$msg$_internal_$put_field$(" + "::$proto_ns$::internal::ReadVarint$1$$2$(&ptr));\n" + "CHK_(ptr);\n", + zigzag, size); + } else { + if (HasHasbit(field)) { + format("_Internal::set_has_$name$(&$has_bits$);\n"); + } + format( + "$msg$$field$ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n" + "CHK_(ptr);\n", + zigzag, size); + } + } + break; + } + case WireFormatLite::WIRETYPE_FIXED32: + case WireFormatLite::WIRETYPE_FIXED64: { + if (field->is_repeated() || field->real_containing_oneof()) { + format( + "$msg$_internal_$put_field$(" + "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr));\n" + "ptr += sizeof($primitive_type$);\n"); + } else { + if (HasHasbit(field)) { + format("_Internal::set_has_$name$(&$has_bits$);\n"); + } + format( + "$msg$$field$ = " + "::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n" + "ptr += sizeof($primitive_type$);\n"); + } + break; + } + case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { + GenerateLengthDelim(format, field); + break; + } + case WireFormatLite::WIRETYPE_START_GROUP: { + format( + "ptr = ctx->ParseGroup($msg$_internal_$mutable_field$(), ptr, $1$);\n" + "CHK_(ptr);\n", + tag); + break; + } + case WireFormatLite::WIRETYPE_END_GROUP: { + GOOGLE_LOG(FATAL) << "Can't have end group field\n"; + break; + } + } // switch (wire_type) +} + +// Returns the tag for this field and in case of repeated packable fields, +// sets a fallback tag in fallback_tag_ptr. +static uint32_t ExpectedTag(const FieldDescriptor* field, + uint32_t* fallback_tag_ptr) { + uint32_t expected_tag; + if (field->is_packable()) { + auto expected_wiretype = WireFormat::WireTypeForFieldType(field->type()); + expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype); + GOOGLE_CHECK(expected_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + auto fallback_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + uint32_t fallback_tag = + WireFormatLite::MakeTag(field->number(), fallback_wiretype); + + if (field->is_packed()) std::swap(expected_tag, fallback_tag); + *fallback_tag_ptr = fallback_tag; + } else { + auto expected_wiretype = WireFormat::WireTypeForField(field); + expected_tag = WireFormatLite::MakeTag(field->number(), expected_wiretype); + } + return expected_tag; +} + +// These variables are used by the generated parse iteration, and must already +// be defined in the generated code: +// - `const char* ptr`: the input buffer. +// - `ParseContext* ctx`: the associated context for `ptr`. +// - implicit `this`: i.e., we must be in a non-static member function. +// +// The macro `CHK_(x)` must be defined. It should return an error condition if +// the macro parameter is false. +// +// Whenever an END_GROUP tag was read, or tag 0 was read, the generated code +// branches to the label `message_done`. +// +// These formatter variables are used: +// - `next_tag`: a single statement to begin parsing the next tag. +// +// At the end of the generated code, the enclosing function should proceed to +// parse the next tag in the stream. +void ParseFunctionGenerator::GenerateParseIterationBody( + Formatter& format, const Descriptor* descriptor, + const std::vector& fields) { + if (!fields.empty()) { + GenerateFieldSwitch(format, fields); + // Each field `case` only considers field number. Field numbers that are + // not defined in the message, or tags with an incompatible wire type, are + // considered "unusual" cases. They will be handled by the logic below. + format.Outdent(); + format("handle_unusual:\n"); + format.Indent(); + } + + // Unusual/extension/unknown case: + format( + "if ((tag == 0) || ((tag & 7) == 4)) {\n" + " CHK_(ptr);\n" + " ctx->SetLastTag(tag);\n" + " goto message_done;\n" + "}\n"); + if (IsMapEntryMessage(descriptor)) { + format("$next_tag$;\n"); + } else { + if (descriptor->extension_range_count() > 0) { + format("if ("); + for (int i = 0; i < descriptor->extension_range_count(); i++) { + const Descriptor::ExtensionRange* range = + descriptor->extension_range(i); + if (i > 0) format(" ||\n "); + + uint32_t start_tag = WireFormatLite::MakeTag( + range->start, static_cast(0)); + uint32_t end_tag = WireFormatLite::MakeTag( + range->end, static_cast(0)); + + if (range->end > FieldDescriptor::kMaxNumber) { + format("($1$u <= tag)", start_tag); + } else { + format("($1$u <= tag && tag < $2$u)", start_tag, end_tag); + } + } + format( + ") {\n" + " ptr = $msg$$extensions$.ParseField(tag, ptr, " + "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n" + " CHK_(ptr != nullptr);\n" + " $next_tag$;\n" + "}\n"); + } + format( + "ptr = UnknownFieldParse(\n" + " tag,\n" + " $msg$_internal_metadata_.mutable_unknown_fields<" + "$unknown_fields_type$>(),\n" + " ptr, ctx);\n" + "CHK_(ptr != nullptr);\n"); + } +} + +void ParseFunctionGenerator::GenerateFieldSwitch( + Formatter& format, const std::vector& fields) { + format("switch (tag >> 3) {\n"); + format.Indent(); + + for (const auto* field : fields) { + bool cold = ShouldSplit(field, options_); + format.Set("field", FieldMemberName(field, cold)); + PrintFieldComment(format, field); + format("case $1$:\n", field->number()); + format.Indent(); + uint32_t fallback_tag = 0; + uint32_t expected_tag = ExpectedTag(field, &fallback_tag); + format("if (PROTOBUF_PREDICT_TRUE(static_cast<$uint8$>(tag) == $1$)) {\n", + expected_tag & 0xFF); + format.Indent(); + if (cold) { + format("$msg$PrepareSplitMessageForWrite();\n"); + } + auto wiretype = WireFormatLite::GetTagWireType(expected_tag); + uint32_t tag = WireFormatLite::MakeTag(field->number(), wiretype); + int tag_size = io::CodedOutputStream::VarintSize32(tag); + bool is_repeat = ShouldRepeat(field, wiretype); + if (is_repeat) { + format( + "ptr -= $1$;\n" + "do {\n" + " ptr += $1$;\n", + tag_size); + format.Indent(); + } + GenerateFieldBody(format, wiretype, field); + if (is_repeat) { + format.Outdent(); + format( + " if (!ctx->DataAvailable(ptr)) break;\n" + "} while (::$proto_ns$::internal::ExpectTag<$1$>(ptr));\n", + tag); + } + format.Outdent(); + if (fallback_tag) { + format("} else if (static_cast<$uint8$>(tag) == $1$) {\n", + fallback_tag & 0xFF); + format.Indent(); + GenerateFieldBody(format, WireFormatLite::GetTagWireType(fallback_tag), + field); + format.Outdent(); + } + format( + "} else\n" + " goto handle_unusual;\n" + "$next_tag$;\n"); + format.Outdent(); + } // for loop over ordered fields + + format( + "default:\n" + " goto handle_unusual;\n"); + format.Outdent(); + format("} // switch\n"); +} + +namespace { + +std::string FieldParseFunctionName( + const TailCallTableInfo::FieldEntryInfo& entry, const Options& options) { + const FieldDescriptor* field = entry.field; + std::string name = "::_pbi::TcParser::Fast"; + + switch (field->type()) { + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_FLOAT: + name.append("F32"); + break; + + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_DOUBLE: + name.append("F64"); + break; + + case FieldDescriptor::TYPE_BOOL: + name.append("V8"); + break; + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + name.append("V32"); + break; + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + name.append("V64"); + break; + + case FieldDescriptor::TYPE_ENUM: + if (HasPreservingUnknownEnumSemantics(field)) { + name.append("V32"); + break; + } + if (field->is_repeated() && field->is_packed()) { + GOOGLE_LOG(DFATAL) << "Enum validation not handled: " << field->DebugString(); + return ""; + } + name.append(entry.is_enum_range ? "Er" : "Ev"); + break; + + case FieldDescriptor::TYPE_SINT32: + name.append("Z32"); + break; + case FieldDescriptor::TYPE_SINT64: + name.append("Z64"); + break; + + case FieldDescriptor::TYPE_BYTES: + name.append("B"); + if (IsStringInlined(field, options)) { + name.append("i"); + } + break; + case FieldDescriptor::TYPE_STRING: + switch (GetUtf8CheckMode(field, options)) { + case Utf8CheckMode::kNone: + name.append("B"); + break; + case Utf8CheckMode::kVerify: + name.append("S"); + break; + case Utf8CheckMode::kStrict: + name.append("U"); + break; + default: + GOOGLE_LOG(DFATAL) << "Mode not handled: " + << static_cast(GetUtf8CheckMode(field, options)); + return ""; + } + if (IsStringInlined(field, options)) { + name.append("i"); + } + break; + + case FieldDescriptor::TYPE_MESSAGE: + name.append("M"); + break; + case FieldDescriptor::TYPE_GROUP: + name.append("G"); + break; + + default: + GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString(); + return ""; + } + + // The field implementation functions are prefixed by cardinality: + // `S` for optional or implicit fields. + // `R` for non-packed repeated. + // `P` for packed repeated. + name.append(field->is_packed() ? "P" + : field->is_repeated() ? "R" + : field->real_containing_oneof() ? "O" + : "S"); + + // Append the tag length. Fast parsing only handles 1- or 2-byte tags. + name.append(TagSize(field->number()) == 1 ? "1" : "2"); + + return name; +} + +} // namespace + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.h similarity index 75% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.h index b921067b..542a15a0 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/parse_function_generator.h @@ -35,12 +35,11 @@ #include #include -#include -#include #include #include -#include #include +#include +#include namespace google { namespace protobuf { @@ -50,18 +49,36 @@ namespace cpp { // Helper class for generating tailcall parsing functions. struct TailCallTableInfo { TailCallTableInfo(const Descriptor* descriptor, const Options& options, + const std::vector& ordered_fields, const std::vector& has_bit_indices, + const std::vector& inlined_string_indices, MessageSCCAnalyzer* scc_analyzer); - // Information to generate field entries. - struct FieldInfo { - const FieldDescriptor* field; - google::protobuf::internal::TcFieldData bits; - std::string func_name; - }; + // Fields parsed by the table fast-path. - std::vector fast_path_fields; - // Fields parsed by slow-path fallback. + struct FastFieldInfo { + std::string func_name; + const FieldDescriptor* field; + uint16_t coded_tag; + uint8_t hasbit_idx; + uint8_t aux_idx; + }; + std::vector fast_path_fields; + + // Fields parsed by mini parsing routines. + struct FieldEntryInfo { + const FieldDescriptor* field; + int hasbit_idx; + int inlined_string_idx; + uint16_t aux_idx; + // True for enums entirely covered by the start/length fields of FieldAux: + bool is_enum_range; + }; + std::vector field_entries; + std::vector aux_entries; + + // Fields parsed by generated fallback function. std::vector fallback_fields; + // Table size. int table_size_log2; // Mask for has-bits of required fields. @@ -110,15 +127,15 @@ class ParseFunctionGenerator { // Generates a fallback function for tailcall table-based parsing. void GenerateTailcallFallbackFunction(Formatter& format); - // Generates functions for parsing this message as a field. - void GenerateTailcallFieldParseFunctions(Formatter& format); - // Generates a looping `_InternalParse` function. void GenerateLoopingParseFunction(Formatter& format); // Generates the tail-call table definition. void GenerateTailCallTable(Formatter& format); - void GenerateFastFieldEntries(Formatter& format, const std::string& fallback); + void GenerateFastFieldEntries(Formatter& format); + void GenerateFieldEntries(Formatter& format); + int CalculateFieldNamesSize() const; + void GenerateFieldNames(Formatter& format); // Generates parsing code for an `ArenaString` field. void GenerateArenaString(Formatter& format, const FieldDescriptor* field); @@ -139,12 +156,11 @@ class ParseFunctionGenerator { // Generates code to parse the next field from the input stream. void GenerateParseIterationBody( Formatter& format, const Descriptor* descriptor, - const std::vector& ordered_fields); + const std::vector& fields); - // Generates a `switch` statement to parse each of `ordered_fields`. - void GenerateFieldSwitch( - Formatter& format, - const std::vector& ordered_fields); + // Generates a `switch` statement to parse each of `fields`. + void GenerateFieldSwitch(Formatter& format, + const std::vector& fields); const Descriptor* descriptor_; MessageSCCAnalyzer* scc_analyzer_; @@ -152,45 +168,10 @@ class ParseFunctionGenerator { std::map variables_; std::unique_ptr tc_table_info_; std::vector inlined_string_indices_; + const std::vector ordered_fields_; int num_hasbits_; }; -enum class ParseCardinality { - kSingular, - kOneof, - kRepeated, - kPacked, -}; - -// TypeFormat defines parsing types, which encapsulates the expected wire -// format, conversion or validation, and the in-memory layout. -enum class TypeFormat { - // Fixed types: - kFixed64, // fixed64, sfixed64, double - kFixed32, // fixed32, sfixed32, float - - // Varint types: - kVar64, // int64, uint64 - kVar32, // int32, uint32 - kSInt64, // sint64 - kSInt32, // sint32 - kBool, // bool - - // Length-delimited types: - kBytes, // bytes - kString, // string (proto3/UTF-8 strict) - kStringValidateOnly, // string (proto2/UTF-8 validate only) -}; - -// Returns the name of a field parser function. -// -// These are out-of-line functions generated by -// parse_function_inc_generator_main. -std::string GetTailCallFieldHandlerName(ParseCardinality card, - TypeFormat type_format, - int tag_length_bytes, - const Options& options); - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/plugin_unittest.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/plugin_unittest.cc index 373f38d8..f023dcf7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/plugin_unittest.cc @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include @@ -54,11 +54,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const { + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override { TryInsert("test.pb.h", "includes", context); TryInsert("test.pb.h", "namespace_scope", context); TryInsert("test.pb.h", "global_scope", context); @@ -199,7 +198,7 @@ TEST(CppPluginTest, PluginTest) { " ctype = CORD\n" " ];\n" "\n" - " oneof Qux {\n" + " oneof Moo {\n" " int64 oneOfInt = 20;\n" " string oneOfString = 21;\n" " Baz oneOfMessage = 22;\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.cc similarity index 81% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.cc index ffccf08a..6c92ede2 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.cc @@ -32,12 +32,12 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include -#include #include #include #include +#include namespace google { namespace protobuf { @@ -104,6 +104,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type()); (*variables)["default"] = DefaultValue(options, descriptor); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + bool cold = ShouldSplit(descriptor, options); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor, cold); (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor)); int fixed_size = FixedSize(descriptor->type()); if (fixed_size != -1) { @@ -150,7 +154,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$() const {\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -159,9 +163,10 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline void $classname$::_internal_set_$name$($type$ value) {\n" " $set_hasbit$\n" - " $name$_ = value;\n" + " $field$ = value;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" + "$maybe_prepare_split_message$" " _internal_set_$name$(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -170,29 +175,23 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( void PrimitiveFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("$field$ = $default$;\n"); } void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("_internal_set_$name$(from._internal_$name$());\n"); + format("_this->_internal_set_$name$(from._internal_$name$());\n"); } void PrimitiveFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - format("swap($name$_, other->$name$_);\n"); -} - -void PrimitiveFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_ = $default$;\n"); + format("swap($field$, other->$field$);\n"); } void PrimitiveFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_ = from.$name$_;\n"); + format("_this->$field$ = from.$field$;\n"); } void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -201,7 +200,7 @@ void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "target = stream->EnsureSpace(target);\n" "target = " - "::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray(" + "::_pbi::WireFormatLite::Write$declared_type$ToArray(" "$number$, this->_internal_$name$(), target);\n"); } @@ -214,12 +213,12 @@ void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const { // Adding one is very common and it turns out it can be done for // free inside of WireFormatLite, so we can save an instruction here. format( - "total_size += ::$proto_ns$::internal::WireFormatLite::" + "total_size += ::_pbi::WireFormatLite::" "$declared_type$SizePlusOne(this->_internal_$name$());\n"); } else { format( "total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" + " ::_pbi::WireFormatLite::$declared_type$Size(\n" " this->_internal_$name$());\n"); } } else { @@ -227,10 +226,26 @@ void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const { } } -void PrimitiveFieldGenerator::GenerateConstinitInitializer( +void PrimitiveFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_($default$)"); + format("/*decltype($field$)*/$default$"); +} + +void PrimitiveFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + format("decltype(Impl_::Split::$name$_){$default$}"); + return; + } + format("decltype($field$){$default$}"); +} + +void PrimitiveFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){}"); } // =================================================================== @@ -249,7 +264,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline $type$ $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return $field_member$;\n" + " return $field$;\n" " }\n" " return $default$;\n" "}\n" @@ -258,7 +273,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( " clear_$oneof_name$();\n" " set_has_$name$();\n" " }\n" - " $field_member$ = value;\n" + " $field$ = value;\n" "}\n" "inline $type$ $classname$::$name$() const {\n" "$annotate_get$" @@ -275,7 +290,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions( void PrimitiveOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$field_member$ = $default$;\n"); + format("$field$ = $default$;\n"); } void PrimitiveOneofFieldGenerator::GenerateSwappingCode( @@ -286,7 +301,7 @@ void PrimitiveOneofFieldGenerator::GenerateSwappingCode( void PrimitiveOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); + format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n"); } // =================================================================== @@ -313,7 +328,7 @@ void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -344,7 +359,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( Formatter format(printer, variables_); format( "inline $type$ $classname$::_internal_$name$(int index) const {\n" - " return $name$_.Get(index);\n" + " return $field$.Get(index);\n" "}\n" "inline $type$ $classname$::$name$(int index) const {\n" "$annotate_get$" @@ -353,11 +368,11 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline void $classname$::set_$name$(int index, $type$ value) {\n" "$annotate_set$" - " $name$_.Set(index, value);\n" + " $field$.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::_internal_add_$name$($type$ value) {\n" - " $name$_.Add(value);\n" + " $field$.Add(value);\n" "}\n" "inline void $classname$::add_$name$($type$ value) {\n" " _internal_add_$name$(value);\n" @@ -366,7 +381,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline const ::$proto_ns$::RepeatedField< $type$ >&\n" "$classname$::_internal_$name$() const {\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline const ::$proto_ns$::RepeatedField< $type$ >&\n" "$classname$::$name$() const {\n" @@ -376,7 +391,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline ::$proto_ns$::RepeatedField< $type$ >*\n" "$classname$::_internal_mutable_$name$() {\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n" "inline ::$proto_ns$::RepeatedField< $type$ >*\n" "$classname$::mutable_$name$() {\n" @@ -389,30 +404,25 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedPrimitiveFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedPrimitiveFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("_this->$field$.MergeFrom(from.$field$);\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedPrimitiveFieldGenerator::GenerateCopyConstructorCode( +void RepeatedPrimitiveFieldGenerator::GenerateDestructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.CopyFrom(from.$name$_);\n"); + format("$field$.~RepeatedField();\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -423,7 +433,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->Write$declared_type$Packed(\n" " $number$, _internal_$name$(), byte_size, target);\n" @@ -440,7 +450,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n" " target = stream->EnsureSpace(target);\n" - " target = ::$proto_ns$::internal::WireFormatLite::" + " target = ::_pbi::WireFormatLite::" "Write$declared_type$ToArray($number$, this->_internal_$name$(i), " "target);\n" "}\n"); @@ -455,8 +465,8 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( int fixed_size = FixedSize(descriptor_->type()); if (fixed_size == -1) { format( - "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n" - " $declared_type$Size(this->$name$_);\n"); + "size_t data_size = ::_pbi::WireFormatLite::\n" + " $declared_type$Size(this->$field$);\n"); } else { format( "unsigned int count = static_cast 0) {\n" " total_size += $tag_size$ +\n" - " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n" - " static_cast<$int32$>(data_size));\n" + " " + "::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" "}\n"); if (FixedSize(descriptor_->type()) == -1) { format( - "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n" - "_$name$_cached_byte_size_.store(cached_size,\n" + "int cached_size = ::_pbi::ToCachedSize(data_size);\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n"); } format("total_size += data_size;\n"); @@ -482,20 +492,44 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( format( "total_size += $tag_size$ *\n" " " - "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n" + "::_pbi::FromIntSize(this->_internal_$name$_size());\n" "total_size += data_size;\n"); } format.Outdent(); format("}\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateConstinitInitializer( +void RepeatedPrimitiveFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_()"); + format("/*decltype($field$)*/{}"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); + } +} + +void RepeatedPrimitiveFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){arena}"); + if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && + HasGeneratedMethods(descriptor_->file(), options_)) { + // std::atomic has no move constructor, which prevents explicit aggregate + // initialization pre-C++17. + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); + } +} + +void RepeatedPrimitiveFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + + Formatter format(printer, variables_); + format("decltype($field$){from.$field$}"); + if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && + HasGeneratedMethods(descriptor_->file(), options_)) { + // std::atomic has no move constructor. + format("\n, /*decltype($cached_byte_size_field$)*/{0}"); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.h similarity index 84% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.h index ff7c208f..bb8a08aa 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/primitive_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { @@ -48,7 +49,7 @@ class PrimitiveFieldGenerator : public FieldGenerator { public: PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~PrimitiveFieldGenerator(); + ~PrimitiveFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -57,12 +58,15 @@ class PrimitiveFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); @@ -72,7 +76,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { public: PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~PrimitiveOneofFieldGenerator(); + ~PrimitiveOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -88,7 +92,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { public: RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedPrimitiveFieldGenerator(); + ~RepeatedPrimitiveFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -97,12 +101,18 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; - void GenerateCopyConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} + void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override { + GOOGLE_CHECK(!ShouldSplit(descriptor_, options_)); + } + void GenerateDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/service.cc similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/service.cc index 6b1ca83e..7a0d4805 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/service.cc @@ -32,10 +32,11 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include -#include +#include + #include #include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/service.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/service.h index 63c7ca44..b3bd2d7d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/service.h @@ -37,8 +37,9 @@ #include #include -#include + #include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.cc similarity index 77% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.cc index 607e8150..9e7c96d7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.cc @@ -32,11 +32,12 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include -#include -#include +#include + #include #include +#include +#include namespace google { @@ -50,36 +51,30 @@ void SetStringVariables(const FieldDescriptor* descriptor, std::map* variables, const Options& options) { SetCommonFieldVariables(descriptor, variables, options); + + const std::string kNS = "::" + (*variables)["proto_ns"] + "::internal::"; + const std::string kArenaStringPtr = kNS + "ArenaStringPtr"; + (*variables)["default"] = DefaultValue(options, descriptor); (*variables)["default_length"] = StrCat(descriptor->default_value_string().length()); - std::string default_variable_string = MakeDefaultName(descriptor); - (*variables)["default_variable_name"] = default_variable_string; + (*variables)["default_variable_name"] = MakeDefaultName(descriptor); + (*variables)["default_variable_field"] = MakeDefaultFieldName(descriptor); - if (!descriptor->default_value_string().empty()) { + if (descriptor->default_value_string().empty()) { + (*variables)["default_string"] = kNS + "GetEmptyStringAlreadyInited()"; + (*variables)["default_value"] = "&" + (*variables)["default_string"]; + (*variables)["lazy_variable_args"] = ""; + } else { (*variables)["lazy_variable"] = - QualifiedClassName(descriptor->containing_type(), options) + - "::" + default_variable_string; + StrCat(QualifiedClassName(descriptor->containing_type(), options), + "::", MakeDefaultFieldName(descriptor)); + + (*variables)["default_string"] = (*variables)["lazy_variable"] + ".get()"; + (*variables)["default_value"] = "nullptr"; + (*variables)["lazy_variable_args"] = (*variables)["lazy_variable"] + ", "; } - (*variables)["default_string"] = - descriptor->default_value_string().empty() - ? "::" + (*variables)["proto_ns"] + - "::internal::GetEmptyStringAlreadyInited()" - : (*variables)["lazy_variable"] + ".get()"; - (*variables)["init_value"] = - descriptor->default_value_string().empty() - ? "&::" + (*variables)["proto_ns"] + - "::internal::GetEmptyStringAlreadyInited()" - : "nullptr"; - (*variables)["default_value_tag"] = - "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" + - (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") + - "Default{}"; - (*variables)["default_variable_or_tag"] = - (*variables)[descriptor->default_value_string().empty() - ? "default_value_tag" - : "lazy_variable"]; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; (*variables)["setter"] = @@ -116,10 +111,11 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { if (!inlined_) { format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); } else { - // `_init_inline_xxx` is used for initializing default instances. - format( - "::$proto_ns$::internal::InlinedStringField $name$_;\n" - "static std::true_type _init_inline_$name$_;\n"); + // Skips the automatic destruction; rather calls it explicitly if + // allocating arena is null. This is required to support message-owned + // arena (go/path-to-arenas) where a root proto is destroyed but + // InlinedStringField may have arena-allocated memory. + format("::$proto_ns$::internal::InlinedStringField $name$_;\n"); } } @@ -130,6 +126,10 @@ void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const { "static const ::$proto_ns$::internal::LazyString" " $default_variable_name$;\n"); } + if (inlined_) { + // `_init_inline_xxx` is used for initializing default instances. + format("static std::true_type _init_inline_$name$_;\n"); + } } void StringFieldGenerator::GenerateAccessorDeclarations( @@ -204,8 +204,8 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_get:$full_name$)\n"); if (!descriptor_->default_value_string().empty()) { format( - " if ($name$_.IsDefault(nullptr)) return " - "$default_variable_name$.get();\n"); + " if ($field$.IsDefault()) return " + "$default_variable_field$.get();\n"); } format( " return _internal_$name$();\n" @@ -215,8 +215,9 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "template \n" "inline PROTOBUF_ALWAYS_INLINE\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" + "$maybe_prepare_split_message$" " $set_hasbit$\n" - " $name$_.$setter$($default_value_tag$, static_cast(arg0)," + " $field$.$setter$(static_cast(arg0)," " args..., GetArenaForAllocation());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -226,10 +227,11 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "template \n" "inline PROTOBUF_ALWAYS_INLINE\n" "void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n" + "$maybe_prepare_split_message$" " $set_hasbit$\n" - " $name$_.$setter$(nullptr, static_cast(arg0)," + " $field$.$setter$(static_cast(arg0)," " args..., GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n" + "&$donating_states_word$, $mask_for_undonate$, this);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" @@ -240,26 +242,27 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( } format( "inline std::string* $classname$::mutable_$name$() {\n" + "$maybe_prepare_split_message$" " std::string* _s = _internal_mutable_$name$();\n" "$annotate_mutable$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return _s;\n" "}\n" "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.Get();\n" + " return $field$.Get();\n" "}\n" "inline void $classname$::_internal_set_$name$(const std::string& " "value) {\n" " $set_hasbit$\n"); if (!inlined_) { format( - " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n" + " $field$.Set(value, GetArenaForAllocation());\n" "}\n"); } else { format( - " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n" + " $field$.Set(value, GetArenaForAllocation(),\n" " _internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n" + "$mask_for_undonate$, this);\n" "}\n"); } format( @@ -267,19 +270,20 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $set_hasbit$\n"); if (!inlined_) { format( - " return $name$_.Mutable($default_variable_or_tag$, " + " return $field$.Mutable($lazy_variable_args$" "GetArenaForAllocation());\n" "}\n"); } else { format( - " return $name$_.Mutable($default_variable_or_tag$, " + " return $field$.Mutable($lazy_variable_args$" "GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n" + "&$donating_states_word$, $mask_for_undonate$, this);\n" "}\n"); } format( "inline std::string* $classname$::$release_name$() {\n" "$annotate_release$" + "$maybe_prepare_split_message$" " // @@protoc_insertion_point(field_release:$full_name$)\n"); if (HasHasbit(descriptor_)) { @@ -289,54 +293,50 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " }\n" " $clear_hasbit$\n"); if (!inlined_) { - format( - " auto* p = $name$_.ReleaseNonDefault($init_value$, " - "GetArenaForAllocation());\n"); + format(" auto* p = $field$.Release();\n"); if (descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " if ($name$_.IsDefault($init_value$)) {\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " if ($field$.IsDefault()) {\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } format(" return p;\n"); } else { format( - " return $name$_.Release(nullptr, GetArenaForAllocation(), " + " return $field$.Release(GetArenaForAllocation(), " "_internal_$name$_donated());\n"); } } else { - format( - " return $name$_.Release($init_value$, GetArenaForAllocation());\n"); + format(" return $field$.Release();\n"); } format( "}\n" "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" + "$maybe_prepare_split_message$" " if ($name$ != nullptr) {\n" " $set_hasbit$\n" " } else {\n" " $clear_hasbit$\n" " }\n"); if (!inlined_) { - format( - " $name$_.SetAllocated($init_value$, $name$,\n" - " GetArenaForAllocation());\n"); + format(" $field$.SetAllocated($name$, GetArenaForAllocation());\n"); if (descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " if ($name$_.IsDefault($init_value$)) {\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " if ($field$.IsDefault()) {\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" " }\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } } else { // Currently, string fields with default value can't be inlined. format( - " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " + " $field$.SetAllocated(nullptr, $name$, GetArenaForAllocation(), " "_internal_$name$_donated(), &$donating_states_word$, " - "$mask_for_undonate$);\n"); + "$mask_for_undonate$, this);\n"); } format( "$annotate_set$" @@ -350,7 +350,7 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( if (!descriptor_->default_value_string().empty()) { format( "const ::$proto_ns$::internal::LazyString " - "$classname$::$default_variable_name$" + "$classname$::$default_variable_field$" "{{{$default$, $default_length$}}, {nullptr}};\n"); } } @@ -358,11 +358,11 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmpty();\n"); + format("$field$.ClearToEmpty();\n"); } else { GOOGLE_DCHECK(!inlined_); format( - "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n"); + "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n"); } } @@ -388,27 +388,27 @@ void StringFieldGenerator::GenerateMessageClearingCode( // // For non-inlined strings, we distinguish from non-default by comparing // instances, rather than contents. - format("$DCHK$(!$name$_.IsDefault(nullptr));\n"); + format("$DCHK$(!$field$.IsDefault());\n"); } if (descriptor_->default_value_string().empty()) { if (must_be_present) { - format("$name$_.ClearNonDefaultToEmpty();\n"); + format("$field$.ClearNonDefaultToEmpty();\n"); } else { - format("$name$_.ClearToEmpty();\n"); + format("$field$.ClearToEmpty();\n"); } } else { // Clear to a non-empty default is more involved, as we try to use the // Arena if one is present and may need to reallocate the string. format( - "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n "); + "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n "); } } void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); // TODO(gpike): improve this - format("_internal_set_$name$(from._internal_$name$());\n"); + format("_this->_internal_set_$name$(from._internal_$name$());\n"); } void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { @@ -416,34 +416,46 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { if (!inlined_) { format( "::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n" - " $init_value$,\n" - " &$name$_, lhs_arena,\n" - " &other->$name$_, rhs_arena\n" + " &$field$, lhs_arena,\n" + " &other->$field$, rhs_arena\n" ");\n"); } else { - // At this point, it's guaranteed that the two fields being swapped are on - // the same arena. format( - "$name$_.Swap(&other->$name$_, nullptr, GetArenaForAllocation(), " - "_internal_$name$_donated(), other->_internal_$name$_donated(), " - "&$donating_states_word$, &(other->$donating_states_word$), " - "$mask_for_undonate$);\n"); + "::$proto_ns$::internal::InlinedStringField::InternalSwap(\n" + " &$field$, lhs_arena, " + "($inlined_string_donated_array$[0] & 0x1u) == 0, this,\n" + " &other->$field$, rhs_arena, " + "(other->$inlined_string_donated_array$[0] & 0x1u) == 0, other);\n"); } } void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); if (inlined_ && descriptor_->default_value_string().empty()) { - // Automatic initialization will construct the string. return; } GOOGLE_DCHECK(!inlined_); - format("$name$_.UnsafeSetDefault($init_value$);\n"); + format("$field$.InitDefault();\n"); if (IsString(descriptor_, options_) && descriptor_->default_value_string().empty()) { format( "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" - " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + " $field$.Set(\"\", GetArenaForAllocation());\n" + "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); + } +} + +void StringFieldGenerator::GenerateCreateSplitMessageCode( + io::Printer* printer) const { + GOOGLE_CHECK(ShouldSplit(descriptor_, options_)); + GOOGLE_CHECK(!inlined_); + Formatter format(printer, variables_); + format("ptr->$name$_.InitDefault();\n"); + if (IsString(descriptor_, options_) && + descriptor_->default_value_string().empty()) { + format( + "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" + " ptr->$name$_.Set(\"\", GetArenaForAllocation());\n" "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); } } @@ -452,6 +464,9 @@ void StringFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { Formatter format(printer, variables_); GenerateConstructorCode(printer); + if (inlined_) { + format("new (&_this->$field$) ::_pbi::InlinedStringField();\n"); + } if (HasHasbit(descriptor_)) { format("if (from._internal_has_$name$()) {\n"); @@ -463,13 +478,13 @@ void StringFieldGenerator::GenerateCopyConstructorCode( if (!inlined_) { format( - "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" - " GetArenaForAllocation());\n"); + "_this->$field$.Set(from._internal_$name$(), \n" + " _this->GetArenaForAllocation());\n"); } else { format( - "$name$_.Set(nullptr, from._internal_$name$(),\n" - " GetArenaForAllocation(), _internal_$name$_donated(), " - "&$donating_states_word$, $mask_for_undonate$);\n"); + "_this->$field$.Set(from._internal_$name$(),\n" + " _this->GetArenaForAllocation(), _this->_internal_$name$_donated(), " + "&_this->$donating_states_word$, $mask_for_undonate$, _this);\n"); } format.Outdent(); @@ -478,12 +493,35 @@ void StringFieldGenerator::GenerateCopyConstructorCode( void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - // The destructor is automatically invoked. + if (!inlined_) { + if (ShouldSplit(descriptor_, options_)) { + format("$cached_split_ptr$->$name$_.Destroy();\n"); + return; + } + format("$field$.Destroy();\n"); return; } + // Explicitly calls ~InlinedStringField as its automatic call is disabled. + // Destructor has been implicitly skipped as a union, and even the + // message-owned arena is enabled, arena could still be missing for + // Arena::CreateMessage(nullptr). + GOOGLE_DCHECK(!ShouldSplit(descriptor_, options_)); + format("$field$.~InlinedStringField();\n"); +} - format("$name$_.DestroyNoArena($init_value$);\n"); +ArenaDtorNeeds StringFieldGenerator::NeedsArenaDestructor() const { + return inlined_ ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone; +} + +void StringFieldGenerator::GenerateArenaDestructorCode( + io::Printer* printer) const { + if (!inlined_) return; + Formatter format(printer, variables_); + // _this is the object being destructed (we are inside a static method here). + format( + "if (!_this->_internal_$name$_donated()) {\n" + " _this->$field$.~InlinedStringField();\n" + "}\n"); } void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -509,20 +547,43 @@ void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const { " this->_internal_$name$());\n"); } -void StringFieldGenerator::GenerateConstinitInitializer( +void StringFieldGenerator::GenerateConstexprAggregateInitializer( io::Printer* printer) const { Formatter format(printer, variables_); if (inlined_) { - format("$name$_(nullptr, false)"); + format("/*decltype($field$)*/{nullptr, false}"); return; } if (descriptor_->default_value_string().empty()) { - format("$name$_(&::$proto_ns$::internal::fixed_address_empty_string)"); + format( + "/*decltype($field$)*/{&::_pbi::fixed_address_empty_string, " + "::_pbi::ConstantInitialized{}}"); } else { - format("$name$_(nullptr)"); + format("/*decltype($field$)*/{nullptr, ::_pbi::ConstantInitialized{}}"); } } +void StringFieldGenerator::GenerateAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + if (ShouldSplit(descriptor_, options_)) { + GOOGLE_CHECK(!inlined_); + format("decltype(Impl_::Split::$name$_){}"); + return; + } + if (!inlined_) { + format("decltype($field$){}"); + } else { + format("decltype($field$)(arena)"); + } +} + +void StringFieldGenerator::GenerateCopyAggregateInitializer( + io::Printer* printer) const { + Formatter format(printer, variables_); + format("decltype($field$){}"); +} + // =================================================================== StringOneofFieldGenerator::StringOneofFieldGenerator( @@ -550,9 +611,9 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " $field_member$.$setter$($default_value_tag$," + " $field$.$setter$(" " static_cast(arg0), args..., GetArenaForAllocation());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -565,7 +626,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( "}\n" "inline const std::string& $classname$::_internal_$name$() const {\n" " if (_internal_has_$name$()) {\n" - " return $field_member$.Get();\n" + " return $field$.Get();\n" " }\n" " return $default_string$;\n" "}\n" @@ -574,28 +635,26 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " $field_member$.Set($default_value_tag$, value, " - "GetArenaForAllocation());\n" + " $field$.Set(value, GetArenaForAllocation());\n" "}\n"); format( "inline std::string* $classname$::_internal_mutable_$name$() {\n" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($init_value$);\n" + " $field$.InitDefault();\n" " }\n" - " return $field_member$.Mutable(\n" - " $default_variable_or_tag$, GetArenaForAllocation());\n" + " return $field$.Mutable($lazy_variable_args$" + " GetArenaForAllocation());\n" "}\n" "inline std::string* $classname$::$release_name$() {\n" "$annotate_release$" " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $field_member$.ReleaseNonDefault($init_value$, " - "GetArenaForAllocation());\n" + " return $field$.Release();\n" " } else {\n" " return nullptr;\n" " }\n" @@ -606,11 +665,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " }\n" " if ($name$ != nullptr) {\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " ::$proto_ns$::Arena* arena = GetArenaForAllocation();\n" - " if (arena != nullptr) {\n" - " arena->Own($name$);\n" - " }\n" + " $field$.InitAllocated($name$, GetArenaForAllocation());\n" " }\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" @@ -620,9 +675,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( void StringOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format( - "$field_member$.Destroy($default_value_tag$, " - "GetArenaForAllocation());\n"); + format("$field$.Destroy();\n"); } void StringOneofFieldGenerator::GenerateMessageClearingCode( @@ -737,14 +790,14 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const std::string& $classname$::_internal_$name$(int index) " "const {\n" - " return $name$_.InternalCheckedGet(\n" + " return $field$.InternalCheckedGet(\n" " index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n" "}\n"); } else { format( "inline const std::string& $classname$::_internal_$name$(int index) " "const {\n" - " return $name$_.Get(index);\n" + " return $field$.Get(index);\n" "}\n"); } format( @@ -756,23 +809,23 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "inline std::string* $classname$::mutable_$name$(int index) {\n" "$annotate_mutable$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_.Mutable(index);\n" + " return $field$.Mutable(index);\n" "}\n" "inline void $classname$::set_$name$(int index, const std::string& " "value) " "{\n" - " $name$_.Mutable(index)->assign(value);\n" + " $field$.Mutable(index)->assign(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(int index, std::string&& value) {\n" - " $name$_.Mutable(index)->assign(std::move(value));\n" + " $field$.Mutable(index)->assign(std::move(value));\n" "$annotate_set$" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(int index, const char* value) {\n" " $null_check$" - " $name$_.Mutable(index)->assign(value);\n" + " $field$.Mutable(index)->assign(value);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); @@ -780,7 +833,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void " "$classname$::set_$name$(int index, StringPiece value) {\n" - " $name$_.Mutable(index)->assign(value.data(), value.size());\n" + " $field$.Mutable(index)->assign(value.data(), value.size());\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); @@ -789,34 +842,34 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "inline void " "$classname$::set_$name$" "(int index, const $pointer_type$* value, size_t size) {\n" - " $name$_.Mutable(index)->assign(\n" + " $field$.Mutable(index)->assign(\n" " reinterpret_cast(value), size);\n" "$annotate_set$" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" "inline std::string* $classname$::_internal_add_$name$() {\n" - " return $name$_.Add();\n" + " return $field$.Add();\n" "}\n" "inline void $classname$::add_$name$(const std::string& value) {\n" - " $name$_.Add()->assign(value);\n" + " $field$.Add()->assign(value);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "inline void $classname$::add_$name$(std::string&& value) {\n" - " $name$_.Add(std::move(value));\n" + " $field$.Add(std::move(value));\n" "$annotate_add$" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "inline void $classname$::add_$name$(const char* value) {\n" " $null_check$" - " $name$_.Add()->assign(value);\n" + " $field$.Add()->assign(value);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_char:$full_name$)\n" "}\n"); if (!options_.opensource_runtime) { format( "inline void $classname$::add_$name$(StringPiece value) {\n" - " $name$_.Add()->assign(value.data(), value.size());\n" + " $field$.Add()->assign(value.data(), value.size());\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n" "}\n"); @@ -824,7 +877,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void " "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" - " $name$_.Add()->assign(reinterpret_cast(value), size);\n" + " $field$.Add()->assign(reinterpret_cast(value), size);\n" "$annotate_add$" " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n" "}\n" @@ -832,43 +885,38 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions( "$classname$::$name$() const {\n" "$annotate_list$" " // @@protoc_insertion_point(field_list:$full_name$)\n" - " return $name$_;\n" + " return $field$;\n" "}\n" "inline ::$proto_ns$::RepeatedPtrField*\n" "$classname$::mutable_$name$() {\n" "$annotate_mutable_list$" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" - " return &$name$_;\n" + " return &$field$;\n" "}\n"); } void RepeatedStringFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.Clear();\n"); + format("$field$.Clear();\n"); } void RepeatedStringFieldGenerator::GenerateMergingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.MergeFrom(from.$name$_);\n"); + format("_this->$field$.MergeFrom(from.$field$);\n"); } void RepeatedStringFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.InternalSwap(&other->$name$_);\n"); + format("$field$.InternalSwap(&other->$field$);\n"); } -void RepeatedStringFieldGenerator::GenerateConstructorCode( - io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedStringFieldGenerator::GenerateCopyConstructorCode( +void RepeatedStringFieldGenerator::GenerateDestructorCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$name$_.CopyFrom(from.$name$_);"); + format("$field$.~RepeatedPtrField();\n"); } void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -895,20 +943,14 @@ void RepeatedStringFieldGenerator::GenerateByteSize( Formatter format(printer, variables_); format( "total_size += $tag_size$ *\n" - " ::$proto_ns$::internal::FromIntSize($name$_.size());\n" - "for (int i = 0, n = $name$_.size(); i < n; i++) {\n" + " ::$proto_ns$::internal::FromIntSize($field$.size());\n" + "for (int i = 0, n = $field$.size(); i < n; i++) {\n" " total_size += " "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n" - " $name$_.Get(i));\n" + " $field$.Get(i));\n" "}\n"); } -void RepeatedStringFieldGenerator::GenerateConstinitInitializer( - io::Printer* printer) const { - Formatter format(printer, variables_); - format("$name$_()"); -} - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.h similarity index 86% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.h index 3f05443f..db5f18bf 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/string_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { @@ -48,7 +49,7 @@ class StringFieldGenerator : public FieldGenerator { public: StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~StringFieldGenerator(); + ~StringFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -62,13 +63,19 @@ class StringFieldGenerator : public FieldGenerator { void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; + void GenerateCreateSplitMessageCode(io::Printer* printer) const override; void GenerateCopyConstructorCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override; + void GenerateArenaDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; + void GenerateConstexprAggregateInitializer( + io::Printer* printer) const override; + void GenerateAggregateInitializer(io::Printer* printer) const override; + void GenerateCopyAggregateInitializer(io::Printer* printer) const override; bool IsInlined() const override { return inlined_; } + ArenaDtorNeeds NeedsArenaDestructor() const override; private: bool inlined_; @@ -79,7 +86,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator { public: StringOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~StringOneofFieldGenerator(); + ~StringOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -99,7 +106,7 @@ class RepeatedStringFieldGenerator : public FieldGenerator { public: RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~RepeatedStringFieldGenerator(); + ~RepeatedStringFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -108,12 +115,14 @@ class RepeatedStringFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; - void GenerateConstructorCode(io::Printer* printer) const override; - void GenerateCopyConstructorCode(io::Printer* printer) const override; + void GenerateConstructorCode(io::Printer* printer) const override {} + void GenerateCopyConstructorCode(io::Printer* /*printer*/) const override { + GOOGLE_CHECK(!ShouldSplit(descriptor_, options_)); + } + void GenerateDestructorCode(io::Printer* printer) const override; void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; - void GenerateConstinitInitializer(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator); diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/third_party/protobuf/src/google/protobuf/compiler/cpp/test_bad_identifiers.proto similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto rename to third_party/protobuf/src/google/protobuf/compiler/cpp/test_bad_identifiers.proto diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto b/third_party/protobuf/src/google/protobuf/compiler/cpp/test_large_enum_value.proto similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto rename to third_party/protobuf/src/google/protobuf/compiler/cpp/test_large_enum_value.proto diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.cc similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.cc index 74310a7f..e2730d7d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.cc @@ -44,12 +44,11 @@ // correctly and produces the interfaces we expect, which is why this test // is written this way. -#include +#include #include #include #include - #include #define MESSAGE_TEST_NAME MessageTest @@ -65,7 +64,7 @@ #define UNITTEST_IMPORT ::protobuf_unittest_import // Must include after the above macros. -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.h similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h rename to third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.h diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.inc similarity index 91% rename from third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.inc rename to third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.inc index 782d2263..0b471761 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.inc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/unittest.inc @@ -49,25 +49,25 @@ #include #include -#include +#include #include -#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) -// We exclude this large proto from cmake build because it's too large for +#ifndef _MSC_VER +// We exclude this large proto because it's too large for // visual studio to compile (report internal errors). #include #endif -#include -#include -#include -#include -#include +#include +#include #include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include #include #include @@ -95,7 +95,7 @@ void DoNothing() {} class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; @@ -126,7 +126,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) { const FileDescriptor* parsed_descriptor = importer.Import(TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH)); EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(parsed_descriptor != NULL); + ASSERT_TRUE(parsed_descriptor != nullptr); // Test that descriptors are generated correctly by converting them to // FileDescriptorProtos and comparing. @@ -138,7 +138,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) { generated_descriptor_proto.DebugString()); } -#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) +#ifndef _MSC_VER // Test that generated code has proper descriptors: // Touch a descriptor generated from an enormous message to validate special // handling for descriptors exceeding the C++ standard's recommended minimum @@ -147,7 +147,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, EnormousDescriptor) { const Descriptor* generated_descriptor = ::protobuf_unittest::TestEnormousDescriptor::descriptor(); - EXPECT_TRUE(generated_descriptor != NULL); + EXPECT_TRUE(generated_descriptor != nullptr); } #endif @@ -249,11 +249,11 @@ TEST(GENERATED_MESSAGE_TEST_NAME, StringDefaults) { } TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestAllTypes message; - EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_EQ(nullptr, message.release_default_string()); EXPECT_FALSE(message.has_default_string()); EXPECT_EQ("hello", message.default_string()); @@ -261,30 +261,30 @@ TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) { EXPECT_TRUE(message.has_default_string()); std::unique_ptr str(message.release_default_string()); EXPECT_FALSE(message.has_default_string()); - ASSERT_TRUE(str != NULL); + ASSERT_TRUE(str != nullptr); EXPECT_EQ("blah", *str); - EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_EQ(nullptr, message.release_default_string()); EXPECT_FALSE(message.has_default_string()); EXPECT_EQ("hello", message.default_string()); } TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestAllTypes message; - EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_EQ(nullptr, message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); message.mutable_optional_nested_message()->set_bb(1); std::unique_ptr nest( message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); - ASSERT_TRUE(nest != NULL); + ASSERT_TRUE(nest != nullptr); EXPECT_EQ(1, nest->bb()); - EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_EQ(nullptr, message.release_optional_nested_message()); EXPECT_FALSE(message.has_optional_nested_message()); } @@ -297,7 +297,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedString) { message.set_optional_string(kHello); EXPECT_TRUE(message.has_optional_string()); - message.set_allocated_optional_string(NULL); + message.set_allocated_optional_string(nullptr); EXPECT_FALSE(message.has_optional_string()); EXPECT_EQ("", message.optional_string()); @@ -315,7 +315,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) { message.mutable_optional_nested_message()->set_bb(1); EXPECT_TRUE(message.has_optional_nested_message()); - message.set_allocated_optional_nested_message(NULL); + message.set_allocated_optional_nested_message(nullptr); EXPECT_FALSE(message.has_optional_nested_message()); EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), &message.optional_nested_message()); @@ -323,7 +323,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) { message.mutable_optional_nested_message()->set_bb(1); UNITTEST::TestAllTypes::NestedMessage* nest = message.release_optional_nested_message(); - ASSERT_TRUE(nest != NULL); + ASSERT_TRUE(nest != nullptr); EXPECT_FALSE(message.has_optional_nested_message()); message.set_allocated_optional_nested_message(nest); @@ -339,19 +339,6 @@ TEST(GENERATED_MESSAGE_TEST_NAME, Clear) { TestUtil::SetAllFields(&message); message.Clear(); TestUtil::ExpectClear(message); - - // Unlike with the defaults test, we do NOT expect that requesting embedded - // messages will return a pointer to the default instance. Instead, they - // should return the objects that were created when mutable_blah() was - // called. - EXPECT_NE(&UNITTEST::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&UNITTEST::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&UNITTEST_IMPORT::ImportMessage::default_instance(), - &message.optional_import_message()); } TEST(GENERATED_MESSAGE_TEST_NAME, EmbeddedNullsInBytesCharStar) { @@ -406,6 +393,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, StringCharStarLength) { } +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || defined(NDEBUG) TEST(GENERATED_MESSAGE_TEST_NAME, CopyFrom) { UNITTEST::TestAllTypes message1, message2; @@ -418,6 +406,20 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CopyFrom) { TestUtil::ExpectAllFieldsSet(message2); } +TEST(GENERATED_MESSAGE_TEST_NAME, CopyAssignmentOperator) { + UNITTEST::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + UNITTEST::TestAllTypes message2; + message2 = message1; + TestUtil::ExpectAllFieldsSet(message2); + + // Make sure that self-assignment does something sane. + message2.operator=(message2); + TestUtil::ExpectAllFieldsSet(message2); +} +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS || NDEBUG + TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithEmpty) { UNITTEST::TestAllTypes message1, message2; @@ -503,6 +505,9 @@ TEST(GENERATED_MESSAGE_TEST_NAME, ADLSwap) { // Note the address of one of the repeated fields, to verify it was swapped // rather than copied. const int32_t* addr = &message1.repeated_int32().Get(0); +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + const int32_t value = *addr; +#endif using std::swap; swap(message1, message2); @@ -512,7 +517,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, ADLSwap) { #ifdef PROTOBUF_FORCE_COPY_IN_SWAP EXPECT_NE(addr, &message2.repeated_int32().Get(0)); - EXPECT_EQ(*addr, message2.repeated_int32().Get(0)); + EXPECT_EQ(value, message2.repeated_int32().Get(0)); #else EXPECT_EQ(addr, &message2.repeated_int32().Get(0)); #endif @@ -531,6 +536,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructor) { // None set. { UNITTEST::TestAllTypes message1; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) UNITTEST::TestAllTypes message2(message1); EXPECT_FALSE(message1.has_optional_string()); @@ -588,20 +594,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructorWithArenas) { TestUtil::ExpectAllFieldsSet(*message2_heap); } -TEST(GENERATED_MESSAGE_TEST_NAME, CopyAssignmentOperator) { - UNITTEST::TestAllTypes message1; - TestUtil::SetAllFields(&message1); - - UNITTEST::TestAllTypes message2; - message2 = message1; - TestUtil::ExpectAllFieldsSet(message2); - - // Make sure that self-assignment does something sane. - message2.operator=(message2); - TestUtil::ExpectAllFieldsSet(message2); -} - -#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) { // Test the CopyFrom method that takes in the generic const Message& // parameter. @@ -614,9 +607,6 @@ TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) { TestUtil::ExpectAllFieldsSet(message2); } -#endif - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS TEST(GENERATED_MESSAGE_TEST_NAME, DynamicMessageCopyFrom) { // Test copying from a DynamicMessage, which must fall back to using @@ -833,7 +823,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CamelCaseFieldNames) { message.mutable_messagefield()->set_c(6); message.add_repeatedprimitivefield(8); - message.add_repeatedstringfield("qux"); + message.add_repeatedstringfield("moo"); message.add_repeatedenumfield(UNITTEST::FOREIGN_BAR); message.add_repeatedmessagefield()->set_c(15); @@ -843,7 +833,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CamelCaseFieldNames) { EXPECT_EQ(6, message.messagefield().c()); EXPECT_EQ(8, message.repeatedprimitivefield(0)); - EXPECT_EQ("qux", message.repeatedstringfield(0)); + EXPECT_EQ("moo", message.repeatedstringfield(0)); EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeatedenumfield(0)); EXPECT_EQ(15, message.repeatedmessagefield(0).c()); } @@ -879,82 +869,85 @@ TEST(GENERATED_MESSAGE_TEST_NAME, TestEmbedOptimizedForSize) { } TEST(GENERATED_MESSAGE_TEST_NAME, TestSpaceUsed) { - UNITTEST::TestAllTypes message1; + // Allocate explicitly on the heap to prevent arena creation. + std::unique_ptr message1( + Arena::CreateMessage(nullptr)); // sizeof provides a lower bound on SpaceUsedLong(). - EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1.SpaceUsedLong()); - const size_t empty_message_size = message1.SpaceUsedLong(); + EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1->SpaceUsedLong()); + const size_t empty_message_size = message1->SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. - message1.set_optional_int32(123); - message1.set_optional_int64(12345); - message1.set_optional_uint32(123); - message1.set_optional_uint64(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + message1->set_optional_int32(123); + message1->set_optional_int64(12345); + message1->set_optional_uint32(123); + message1->set_optional_uint64(12345); + EXPECT_EQ(empty_message_size, message1->SpaceUsedLong()); // On some STL implementations, setting the string to a small value should // only increase SpaceUsedLong() by the size of a string object, though this // is not true everywhere. - message1.set_optional_string("abc"); - EXPECT_LE(empty_message_size + message1.optional_string().size(), - message1.SpaceUsedLong()); + message1->set_optional_string("abc"); + EXPECT_LE(empty_message_size + message1->optional_string().size(), + message1->SpaceUsedLong()); // Setting a string to a value larger than the string object itself should // increase SpaceUsedLong(), because it cannot store the value internally. - message1.set_optional_string(std::string(sizeof(std::string) + 1, 'x')); - int min_expected_increase = message1.optional_string().capacity(); + message1->set_optional_string(std::string(sizeof(std::string) + 1, 'x')); + int min_expected_increase = message1->optional_string().capacity(); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); - size_t previous_size = message1.SpaceUsedLong(); + size_t previous_size = message1->SpaceUsedLong(); // Adding an optional message should increase the size by the size of the // nested message type. NestedMessage is simple enough (1 int field) that it // is equal to sizeof(NestedMessage) - message1.mutable_optional_nested_message(); + message1->mutable_optional_nested_message(); ASSERT_EQ(sizeof(UNITTEST::TestAllTypes::NestedMessage), - message1.optional_nested_message().SpaceUsedLong()); + message1->optional_nested_message().SpaceUsedLong()); EXPECT_EQ(previous_size + sizeof(UNITTEST::TestAllTypes::NestedMessage), - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); } TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) { - UNITTEST::TestOneof2 message1; - EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1.SpaceUsedLong()); + // Allocate explicitly on the heap to prevent arena creation. + std::unique_ptr message1( + Arena::CreateMessage(nullptr)); + EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1->SpaceUsedLong()); - const size_t empty_message_size = message1.SpaceUsedLong(); + const size_t empty_message_size = message1->SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. - message1.set_foo_int(123); - message1.set_bar_int(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + message1->set_foo_int(123); + message1->set_bar_int(12345); + EXPECT_EQ(empty_message_size, message1->SpaceUsedLong()); // Setting a string in oneof to a small value should only increase // SpaceUsedLong() by the size of a string object. - message1.set_foo_string("abc"); - EXPECT_LE(empty_message_size + sizeof(std::string), message1.SpaceUsedLong()); + message1->set_foo_string("abc"); + EXPECT_LE(empty_message_size + sizeof(std::string), message1->SpaceUsedLong()); // Setting a string in oneof to a value larger than the string object itself // should increase SpaceUsedLong(), because it cannot store the value // internally. - message1.set_foo_string(std::string(sizeof(std::string) + 1, 'x')); + message1->set_foo_string(std::string(sizeof(std::string) + 1, 'x')); int min_expected_increase = - message1.foo_string().capacity() + sizeof(std::string); + message1->foo_string().capacity() + sizeof(std::string); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); // Setting a message in oneof should delete the other fields and increase the // size by the size of the nested message type. NestedMessage is simple enough // that it is equal to sizeof(NestedMessage). It may be backed by LazyField, // increasing space used by LazyField and backing Cord. - message1.mutable_foo_message(); + message1->mutable_foo_message(); ASSERT_EQ(sizeof(UNITTEST::TestOneof2::NestedMessage), - message1.foo_message().SpaceUsedLong()); + message1->foo_message().SpaceUsedLong()); EXPECT_LE(empty_message_size + sizeof(UNITTEST::TestOneof2::NestedMessage), - message1.SpaceUsedLong()); + message1->SpaceUsedLong()); } #endif // !PROTOBUF_TEST_NO_DESCRIPTORS - TEST(GENERATED_MESSAGE_TEST_NAME, FieldConstantValues) { UNITTEST::TestRequired message; EXPECT_EQ(UNITTEST::TestAllTypes_NestedMessage::kBbFieldNumber, 1); @@ -1065,14 +1058,13 @@ TEST(GENERATED_ENUM_TEST_NAME, MinAndMax) { EXPECT_EQ(12589235, UNITTEST::TestSparseEnum_ARRAYSIZE); // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. - void* null_pointer = 0; // NULL may be integer-type, not pointer-type. - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MIN); - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MAX); - EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(nullptr, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MIN); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MAX); - EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_ARRAYSIZE); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_MIN); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_MAX); + EXPECT_NE(nullptr, &UNITTEST::ForeignEnum_ARRAYSIZE); // Make sure we can use _MIN and _MAX as switch cases. switch (UNITTEST::SPARSE_A) { @@ -1146,14 +1138,14 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { class MockTestService : public UNITTEST::TestService { public: MockTestService() - : called_(false), - method_(""), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL) {} + : called_(false), + method_(""), + controller_(nullptr), + request_(nullptr), + response_(nullptr), + done_(nullptr) {} - ~MockTestService() {} + ~MockTestService() override {} void Reset() { called_ = false; } @@ -1194,16 +1186,16 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { class MockRpcChannel : public RpcChannel { public: MockRpcChannel() - : called_(false), - method_(NULL), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL), - destroyed_(NULL) {} + : called_(false), + method_(nullptr), + controller_(nullptr), + request_(nullptr), + response_(nullptr), + done_(nullptr), + destroyed_(nullptr) {} - ~MockRpcChannel() { - if (destroyed_ != NULL) *destroyed_ = true; + ~MockRpcChannel() override { + if (destroyed_ != nullptr) *destroyed_ = true; } void Reset() { called_ = false; } @@ -1269,8 +1261,8 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} void SetUp() override { - ASSERT_TRUE(foo_ != NULL); - ASSERT_TRUE(bar_ != NULL); + ASSERT_TRUE(foo_ != nullptr); + ASSERT_TRUE(bar_ != nullptr); } const ServiceDescriptor* descriptor_; @@ -1480,7 +1472,7 @@ TEST_F(OneofTest, SettingOneFieldClearsOthers) { TestUtil::ExpectAtMostOneFieldSetInOneof(message); - message.set_foo_bytes("qux"); + message.set_foo_bytes("moo"); EXPECT_TRUE(message.has_foo_bytes()); TestUtil::ExpectAtMostOneFieldSetInOneof(message); @@ -1488,7 +1480,7 @@ TEST_F(OneofTest, SettingOneFieldClearsOthers) { EXPECT_TRUE(message.has_foo_enum()); TestUtil::ExpectAtMostOneFieldSetInOneof(message); - message.mutable_foo_message()->set_qux_int(234); + message.mutable_foo_message()->set_moo_int(234); EXPECT_TRUE(message.has_foo_message()); TestUtil::ExpectAtMostOneFieldSetInOneof(message); @@ -1511,11 +1503,11 @@ TEST_F(OneofTest, EnumCases) { ExpectEnumCasesWork(message); message.set_foo_string("foo"); ExpectEnumCasesWork(message); - message.set_foo_bytes("qux"); + message.set_foo_bytes("moo"); ExpectEnumCasesWork(message); message.set_foo_enum(UNITTEST::TestOneof2::FOO); ExpectEnumCasesWork(message); - message.mutable_foo_message()->set_qux_int(234); + message.mutable_foo_message()->set_moo_int(234); ExpectEnumCasesWork(message); message.mutable_foogroup()->set_a(345); ExpectEnumCasesWork(message); @@ -1565,15 +1557,15 @@ TEST_F(OneofTest, SetString) { EXPECT_FALSE(message.has_foo_string()); - message.set_foo_string("qux", 3); + message.set_foo_string("moo", 3); EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "qux"); + EXPECT_EQ(message.foo_string(), "moo"); message.clear_foo_string(); EXPECT_FALSE(message.has_foo_string()); - message.mutable_foo_string()->assign("quux"); + message.mutable_foo_string()->assign("mooo"); EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "quux"); + EXPECT_EQ(message.foo_string(), "mooo"); message.clear_foo_string(); EXPECT_FALSE(message.has_foo_string()); @@ -1585,21 +1577,21 @@ TEST_F(OneofTest, SetString) { } TEST_F(OneofTest, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestOneof2 message; - EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_EQ(nullptr, message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); message.set_foo_string("blah"); EXPECT_TRUE(message.has_foo_string()); std::unique_ptr str(message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); - ASSERT_TRUE(str != NULL); + ASSERT_TRUE(str != nullptr); EXPECT_EQ("blah", *str); - EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_EQ(nullptr, message.release_foo_string()); EXPECT_FALSE(message.has_foo_string()); } @@ -1612,7 +1604,7 @@ TEST_F(OneofTest, SetAllocatedString) { message.set_foo_string(kHello); EXPECT_TRUE(message.has_foo_string()); - message.set_allocated_foo_string(NULL); + message.set_allocated_foo_string(nullptr); EXPECT_FALSE(message.has_foo_string()); EXPECT_EQ("", message.foo_string()); @@ -1632,7 +1624,7 @@ TEST_F(OneofTest, ArenaSetAllocatedString) { message->set_foo_string(kHello); EXPECT_TRUE(message->has_foo_string()); - message->set_allocated_foo_string(NULL); + message->set_allocated_foo_string(nullptr); EXPECT_FALSE(message->has_foo_string()); EXPECT_EQ("", message->foo_string()); @@ -1649,32 +1641,32 @@ TEST_F(OneofTest, SetMessage) { // Unset field returns default instance EXPECT_EQ(&message.foo_message(), &UNITTEST::TestOneof2_NestedMessage::default_instance()); - EXPECT_EQ(message.foo_message().qux_int(), 0); + EXPECT_EQ(message.foo_message().moo_int(), 0); - message.mutable_foo_message()->set_qux_int(234); + message.mutable_foo_message()->set_moo_int(234); EXPECT_TRUE(message.has_foo_message()); - EXPECT_EQ(message.foo_message().qux_int(), 234); + EXPECT_EQ(message.foo_message().moo_int(), 234); message.clear_foo_message(); EXPECT_FALSE(message.has_foo_message()); } TEST_F(OneofTest, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value + // Check that release_foo() starts out nullptr, and gives us a value // that we can delete after it's been set. UNITTEST::TestOneof2 message; - EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_EQ(nullptr, message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); - message.mutable_foo_message()->set_qux_int(1); + message.mutable_foo_message()->set_moo_int(1); EXPECT_TRUE(message.has_foo_message()); std::unique_ptr mes( message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); - ASSERT_TRUE(mes != NULL); - EXPECT_EQ(1, mes->qux_int()); + ASSERT_TRUE(mes != nullptr); + EXPECT_EQ(1, mes->moo_int()); - EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_EQ(nullptr, message.release_foo_message()); EXPECT_FALSE(message.has_foo_message()); } @@ -1684,22 +1676,22 @@ TEST_F(OneofTest, SetAllocatedMessage) { EXPECT_FALSE(message.has_foo_message()); - message.mutable_foo_message()->set_qux_int(1); + message.mutable_foo_message()->set_moo_int(1); EXPECT_TRUE(message.has_foo_message()); - message.set_allocated_foo_message(NULL); + message.set_allocated_foo_message(nullptr); EXPECT_FALSE(message.has_foo_message()); EXPECT_EQ(&message.foo_message(), &UNITTEST::TestOneof2_NestedMessage::default_instance()); - message.mutable_foo_message()->set_qux_int(1); + message.mutable_foo_message()->set_moo_int(1); UNITTEST::TestOneof2_NestedMessage* mes = message.release_foo_message(); - ASSERT_TRUE(mes != NULL); + ASSERT_TRUE(mes != nullptr); EXPECT_FALSE(message.has_foo_message()); message.set_allocated_foo_message(mes); EXPECT_TRUE(message.has_foo_message()); - EXPECT_EQ(1, message.foo_message().qux_int()); + EXPECT_EQ(1, message.foo_message().moo_int()); } @@ -1729,7 +1721,7 @@ TEST_F(OneofTest, Defaults) { EXPECT_EQ(message.foo_enum(), 1); EXPECT_FALSE(message.has_foo_message()); - EXPECT_EQ(message.foo_message().qux_int(), 0); + EXPECT_EQ(message.foo_message().moo_int(), 0); EXPECT_FALSE(message.has_foogroup()); EXPECT_EQ(message.foogroup().a(), 0); @@ -1773,14 +1765,14 @@ TEST_F(OneofTest, SwapBothHasFields) { message1.set_foo_string("FOO"); EXPECT_TRUE(message1.has_foo_string()); - message2.mutable_foo_message()->set_qux_int(1); + message2.mutable_foo_message()->set_moo_int(1); EXPECT_TRUE(message2.has_foo_message()); message1.Swap(&message2); EXPECT_FALSE(message1.has_foo_string()); EXPECT_FALSE(message2.has_foo_message()); EXPECT_TRUE(message1.has_foo_message()); - EXPECT_EQ(message1.foo_message().qux_int(), 1); + EXPECT_EQ(message1.foo_message().moo_int(), 1); EXPECT_TRUE(message2.has_foo_string()); EXPECT_EQ(message2.foo_string(), "FOO"); } @@ -1811,16 +1803,16 @@ TEST_F(OneofTest, CopyFrom) { TEST_F(OneofTest, CopyAssignmentOperator) { UNITTEST::TestOneof2 message1; - message1.mutable_foo_message()->set_qux_int(123); + message1.mutable_foo_message()->set_moo_int(123); EXPECT_TRUE(message1.has_foo_message()); UNITTEST::TestOneof2 message2; message2 = message1; - EXPECT_EQ(message2.foo_message().qux_int(), 123); + EXPECT_EQ(message2.foo_message().moo_int(), 123); // Make sure that self-assignment does something sane. message2 = *&message2; // Avoid -Wself-assign. - EXPECT_EQ(message2.foo_message().qux_int(), 123); + EXPECT_EQ(message2.foo_message().moo_int(), 123); } TEST_F(OneofTest, UpcastCopyFrom) { @@ -1875,14 +1867,14 @@ EXPECT_EQ(message2.foo_int(), 123); { UNITTEST::TestOneof2 message1, message2; std::string data; - message1.set_foo_bytes("qux"); + message1.set_foo_bytes("moo"); int size = message1.ByteSizeLong(); data.resize(size); uint8_t* start = reinterpret_cast(::google::protobuf::string_as_array(&data)); uint8_t* end = message1.SerializeWithCachedSizesToArray(start); EXPECT_EQ(size, end - start); EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_bytes(), "qux"); + EXPECT_EQ(message2.foo_bytes(), "moo"); } // Enum @@ -1903,14 +1895,14 @@ EXPECT_EQ(message2.foo_int(), 123); { UNITTEST::TestOneof2 message1, message2; std::string data; - message1.mutable_foo_message()->set_qux_int(234); + message1.mutable_foo_message()->set_moo_int(234); int size = message1.ByteSizeLong(); data.resize(size); uint8_t* start = reinterpret_cast(::google::protobuf::string_as_array(&data)); uint8_t* end = message1.SerializeWithCachedSizesToArray(start); EXPECT_EQ(size, end - start); EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_message().qux_int(), 234); + EXPECT_EQ(message2.foo_message().moo_int(), 234); } // Group @@ -1982,7 +1974,7 @@ data.resize(size); { UNITTEST::TestOneof2 message1, message2; std::string data; - message1.set_foo_bytes("qux"); + message1.set_foo_bytes("moo"); int size = message1.ByteSizeLong(); data.resize(size); @@ -1996,7 +1988,7 @@ data.resize(size); } EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_bytes(), "qux"); + EXPECT_EQ(message2.foo_bytes(), "moo"); } // Enum @@ -2024,7 +2016,7 @@ data.resize(size); { UNITTEST::TestOneof2 message1, message2; std::string data; - message1.mutable_foo_message()->set_qux_int(234); + message1.mutable_foo_message()->set_moo_int(234); int size = message1.ByteSizeLong(); data.resize(size); @@ -2038,7 +2030,7 @@ data.resize(size); } EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_message().qux_int(), 234); + EXPECT_EQ(message2.foo_message().moo_int(), 234); } // Group @@ -2080,11 +2072,11 @@ TEST_F(OneofTest, MergeFrom) { EXPECT_EQ(message2.foo_string(), "foo"); - message1.set_foo_bytes("qux"); + message1.set_foo_bytes("moo"); message2.MergeFrom(message1); TestUtil::ExpectAtMostOneFieldSetInOneof(message2); EXPECT_TRUE(message2.has_foo_bytes()); - EXPECT_EQ(message2.foo_bytes(), "qux"); + EXPECT_EQ(message2.foo_bytes(), "moo"); message1.set_foo_enum(UNITTEST::TestOneof2::FOO); message2.MergeFrom(message1); @@ -2092,11 +2084,11 @@ TEST_F(OneofTest, MergeFrom) { EXPECT_TRUE(message2.has_foo_enum()); EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO); - message1.mutable_foo_message()->set_qux_int(234); + message1.mutable_foo_message()->set_moo_int(234); message2.MergeFrom(message1); TestUtil::ExpectAtMostOneFieldSetInOneof(message2); EXPECT_TRUE(message2.has_foo_message()); - EXPECT_EQ(message2.foo_message().qux_int(), 234); + EXPECT_EQ(message2.foo_message().moo_int(), 234); message1.mutable_foogroup()->set_a(345); message2.MergeFrom(message1); diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 86bacf81..84aacca5 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -110,13 +110,14 @@ class MockGeneratorContext : public GeneratorContext { class GenerateAndTest { public: GenerateAndTest() {} - void Run(const FileDescriptor* proto_file, std::string file1, std::string file2) { + void Run(const FileDescriptor* proto_file, std::string file1, + std::string file2) { ASSERT_TRUE(proto_file != NULL) << TestSourceDir(); ASSERT_TRUE(generator_.Generate(proto_file, parameter_, &context_, &error_)); context_.ExpectFileMatches(file1, file2); } - void SetParameter(string parameter) { + void SetParameter(std::string parameter) { parameter_ = parameter; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.cc index 186fa27e..55fb60c5 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.cc @@ -109,7 +109,7 @@ void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, "$oneof_name$_ = input.ReadEnum();\n" - "$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"); + "$oneof_name$Case_ = $oneof_property_name$OneofCase.$oneof_case_name$;\n"); } void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.h index e282d723..0c6b023b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_enum_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 477b49e5..17847e36 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -61,7 +61,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( part_tag_size /= 2; } uint tag = internal::WireFormat::MakeTag(descriptor_); - uint8 tag_array[5]; + uint8_t tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); std::string tag_bytes = StrCat(tag_array[0]); for (int i = 1; i < part_tag_size; i++) { @@ -130,8 +130,9 @@ void FieldGeneratorBase::SetCommonOneofFieldVariables( } else { (*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() + - "OneofCase." + property_name(); + "OneofCase." + oneof_case_name(); } + (*variables)["oneof_case_name"] = oneof_case_name(); (*variables)["oneof_property_name"] = oneof_property_name(); } @@ -187,6 +188,10 @@ void FieldGeneratorBase::AddPublicMemberAttributes(io::Printer* printer) { WriteGeneratedCodeAttributes(printer); } +std::string FieldGeneratorBase::oneof_case_name() { + return GetOneofCaseName(descriptor_); +} + std::string FieldGeneratorBase::oneof_property_name() { return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), true); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.h index f875fa11..c7b7469b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -85,6 +85,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::map* variables); std::string oneof_property_name(); + std::string oneof_case_name(); std::string oneof_name(); std::string property_name(); std::string name(); diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc index 5755fee0..e21eff17 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc @@ -30,14 +30,14 @@ #include +#include #include #include +#include #include #include -#include #include -#include namespace google { namespace protobuf { @@ -63,6 +63,17 @@ TEST(CSharpEnumValue, PascalCasedPrefixStripping) { EXPECT_EQ("_2", GetEnumValueName("Foo", "FOO___2")); } +TEST(DescriptorProtoHelpers, IsDescriptorProto) { + EXPECT_TRUE(IsDescriptorProto(DescriptorProto::descriptor()->file())); + EXPECT_FALSE(IsDescriptorProto(google::protobuf::Any::descriptor()->file())); +} + +TEST(DescriptorProtoHelpers, IsDescriptorOptionMessage) { + EXPECT_TRUE(IsDescriptorOptionMessage(FileOptions::descriptor())); + EXPECT_FALSE(IsDescriptorOptionMessage(google::protobuf::Any::descriptor())); + EXPECT_FALSE(IsDescriptorOptionMessage(DescriptorProto::descriptor())); +} + } // namespace } // namespace csharp } // namespace compiler diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc index 32ef3994..73ca8680 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -393,6 +393,13 @@ std::string GetPropertyName(const FieldDescriptor* descriptor) { return property_name; } +std::string GetOneofCaseName(const FieldDescriptor* descriptor) { + // The name in a oneof case enum is the same as for the property, but as we always have a "None" + // value as well, we need to reserve that by appending an underscore. + std::string property_name = GetPropertyName(descriptor); + return property_name == "None" ? "None_" : property_name; +} + std::string GetOutputFile(const FileDescriptor* descriptor, const std::string file_extension, const bool generate_directories, diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h index a6009c8b..836bd5de 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -87,6 +87,8 @@ std::string GetFieldConstantName(const FieldDescriptor* field); std::string GetPropertyName(const FieldDescriptor* descriptor); +std::string GetOneofCaseName(const FieldDescriptor* descriptor); + int GetFixedSize(FieldDescriptor::Type type); std::string UnderscoresToCamelCase(const std::string& input, @@ -130,7 +132,8 @@ uint GetGroupEndTag(const Descriptor* descriptor); // descriptors etc, for use in the runtime. This is the only type which is // allowed to use proto2 syntax, and it generates internal classes. inline bool IsDescriptorProto(const FileDescriptor* descriptor) { - return descriptor->name() == "google/protobuf/descriptor.proto"; + return descriptor->name() == "google/protobuf/descriptor.proto" || + descriptor->name() == "net/proto2/proto/descriptor.proto"; } // Determines whether the given message is an options message within descriptor.proto. @@ -138,15 +141,15 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { if (!IsDescriptorProto(descriptor->file())) { return false; } - const std::string name = descriptor->full_name(); - return name == "google.protobuf.FileOptions" || - name == "google.protobuf.MessageOptions" || - name == "google.protobuf.FieldOptions" || - name == "google.protobuf.OneofOptions" || - name == "google.protobuf.EnumOptions" || - name == "google.protobuf.EnumValueOptions" || - name == "google.protobuf.ServiceOptions" || - name == "google.protobuf.MethodOptions"; + const std::string name = descriptor->name(); + return name == "FileOptions" || + name == "MessageOptions" || + name == "FieldOptions" || + name == "OneofOptions" || + name == "EnumOptions" || + name == "EnumValueOptions" || + name == "ServiceOptions" || + name == "MethodOptions"; } inline bool IsWrapperType(const FieldDescriptor* descriptor) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 44c13e2f..a13b995d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -57,9 +57,9 @@ MapFieldGenerator::~MapFieldGenerator() { void MapFieldGenerator::GenerateMembers(io::Printer* printer) { const FieldDescriptor* key_descriptor = - descriptor_->message_type()->FindFieldByName("key"); + descriptor_->message_type()->map_key(); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); variables_["key_type_name"] = type_name(key_descriptor); variables_["value_type_name"] = type_name(value_descriptor); std::unique_ptr key_generator( diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.h index 9b5e214e..23b36199 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_map_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_MAP_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc index 99808749..a119bdde 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -238,8 +238,8 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("None = 0,\n"); for (int j = 0; j < oneof->field_count(); j++) { const FieldDescriptor* field = oneof->field(j); - printer->Print("$field_property_name$ = $index$,\n", - "field_property_name", GetPropertyName(field), + printer->Print("$oneof_case_name$ = $index$,\n", + "oneof_case_name", GetOneofCaseName(field), "index", StrCat(field->number())); } printer->Outdent(); @@ -403,10 +403,10 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { for (int j = 0; j < oneof->field_count(); j++) { const FieldDescriptor* field = oneof->field(j); std::unique_ptr generator(CreateFieldGeneratorInternal(field)); - vars["field_property_name"] = GetPropertyName(field); + vars["oneof_case_name"] = GetOneofCaseName(field); printer->Print( vars, - "case $property_name$OneofCase.$field_property_name$:\n"); + "case $property_name$OneofCase.$oneof_case_name$:\n"); printer->Indent(); generator->GenerateCloningCode(printer); printer->Print("break;\n"); @@ -635,10 +635,10 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Indent(); for (int j = 0; j < oneof->field_count(); j++) { const FieldDescriptor* field = oneof->field(j); - vars["field_property_name"] = GetPropertyName(field); + vars["oneof_case_name"] = GetOneofCaseName(field); printer->Print( vars, - "case $property_name$OneofCase.$field_property_name$:\n"); + "case $property_name$OneofCase.$oneof_case_name$:\n"); printer->Indent(); std::unique_ptr generator(CreateFieldGeneratorInternal(field)); generator->GenerateMergingCode(printer); @@ -717,7 +717,7 @@ void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_pars const FieldDescriptor* field = fields_by_number()[i]; internal::WireFormatLite::WireType wt = internal::WireFormat::WireTypeForFieldType(field->type()); - uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); + uint32_t tag = internal::WireFormatLite::MakeTag(field->number(), wt); // Handle both packed and unpacked repeated fields with the same Read*Array call; // the two generated cases are the packed and unpacked tags. // TODO(jonskeet): Check that is_packable is equivalent to diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 034fbd92..487d01dd 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -225,7 +225,7 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n" " set {\n" " $oneof_name$_ = value;\n" - " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" + " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$oneof_case_name$;\n" " }\n" "}\n"); if (SupportsPresenceApi(descriptor_)) { @@ -236,7 +236,7 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "$access_level$ bool Has$property_name$ {\n" - " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n" + " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$oneof_case_name$; }\n" "}\n"); printer->Print( variables_, diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.h index 1436fe20..e76dfd20 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 9df1dd6a..e7d51168 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -296,7 +296,7 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { } printer->Print( variables_, - " $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n" + " $oneof_name$Case_ = $oneof_property_name$OneofCase.$oneof_case_name$;\n" " }\n" "}\n"); if (SupportsPresenceApi(descriptor_)) { @@ -307,7 +307,7 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "$access_level$ bool Has$property_name$ {\n" - " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n" + " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$oneof_case_name$; }\n" "}\n"); printer->Print( variables_, diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.h index a2c11050..6d495d55 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_primitive_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc index 644fbf16..d9ab4b49 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc @@ -128,7 +128,7 @@ void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) { "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $file_name$\n" "// \n" - "#pragma warning disable 1591, 0612, 3021\n" + "#pragma warning disable 1591, 0612, 3021, 8981\n" "#region Designer generated code\n" "\n" "using pb = global::Google.Protobuf;\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h index 2e265702..2379f38e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h index a2267adf..026efea8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h index d432f37b..bdd12a02 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index 578f54ba..e638dd86 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -233,7 +233,7 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : ($type_name$) null; }\n" " set {\n" " $oneof_name$_ = value;\n" - " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" + " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$oneof_case_name$;\n" " }\n" "}\n"); if (SupportsPresenceApi(descriptor_)) { @@ -244,7 +244,7 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "$access_level$ bool Has$property_name$ {\n" - " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n" + " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$oneof_case_name$; }\n" "}\n"); printer->Print( variables_, diff --git a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h index 57c4f5e7..cc8a3137 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRAPPER_FIELD_H__ -#include - #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/importer.cc b/third_party/protobuf/src/google/protobuf/compiler/importer.cc index 3bcb0c90..f1e26f8b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/importer.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/importer.cc @@ -93,13 +93,13 @@ class SourceTreeDescriptorDatabase::SingleFileErrorCollector : filename_(filename), multi_file_error_collector_(multi_file_error_collector), had_errors_(false) {} - ~SingleFileErrorCollector() {} + ~SingleFileErrorCollector() override {} bool had_errors() { return had_errors_; } // implements ErrorCollector --------------------------------------- void AddError(int line, int column, const std::string& message) override { - if (multi_file_error_collector_ != NULL) { + if (multi_file_error_collector_ != nullptr) { multi_file_error_collector_->AddError(filename_, line, column, message); } had_errors_ = true; @@ -134,12 +134,12 @@ SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { std::unique_ptr input(source_tree_->Open(filename)); - if (input == NULL) { + if (input == nullptr) { if (fallback_database_ != nullptr && fallback_database_->FindFileByName(filename, output)) { return true; } - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(filename, -1, 0, source_tree_->GetLastErrorMessage()); } @@ -151,7 +151,7 @@ bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename, io::Tokenizer tokenizer(input.get(), &file_error_collector); Parser parser; - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { parser.RecordErrorsTo(&file_error_collector); } if (using_validation_error_collector_) { @@ -187,7 +187,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError( const std::string& filename, const std::string& element_name, const Message* descriptor, ErrorLocation location, const std::string& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -203,7 +203,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning( const std::string& filename, const std::string& element_name, const Message* descriptor, ErrorLocation location, const std::string& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -429,7 +429,7 @@ DiskSourceTree::DiskFileToVirtualFile(const std::string& disk_file, // of verifying that we are not canonicalizing away any non-existent // directories. std::unique_ptr stream(OpenDiskFile(disk_file)); - if (stream == NULL) { + if (stream == nullptr) { return CANNOT_OPEN; } @@ -440,11 +440,11 @@ bool DiskSourceTree::VirtualFileToDiskFile(const std::string& virtual_file, std::string* disk_file) { std::unique_ptr stream( OpenVirtualFile(virtual_file, disk_file)); - return stream != NULL; + return stream != nullptr; } io::ZeroCopyInputStream* DiskSourceTree::Open(const std::string& filename) { - return OpenVirtualFile(filename, NULL); + return OpenVirtualFile(filename, nullptr); } std::string DiskSourceTree::GetLastErrorMessage() { @@ -461,7 +461,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" " "are not allowed in the virtual path"; - return NULL; + return nullptr; } for (const auto& mapping : mappings_) { @@ -469,8 +469,8 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( if (ApplyMapping(virtual_file, mapping.virtual_path, mapping.disk_path, &temp_disk_file)) { io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file); - if (stream != NULL) { - if (disk_file != NULL) { + if (stream != nullptr) { + if (disk_file != nullptr) { *disk_file = temp_disk_file; } return stream; @@ -480,12 +480,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( // The file exists but is not readable. last_error_message_ = "Read access is denied for file: " + temp_disk_file; - return NULL; + return nullptr; } } } last_error_message_ = "File not found."; - return NULL; + return nullptr; } io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( @@ -498,12 +498,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( #if defined(_WIN32) if (ret == 0 && sb.st_mode & S_IFDIR) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #else if (ret == 0 && S_ISDIR(sb.st_mode)) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #endif int file_descriptor; @@ -515,7 +515,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( result->SetCloseOnDelete(true); return result; } else { - return NULL; + return nullptr; } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/importer.h b/third_party/protobuf/src/google/protobuf/compiler/importer.h index 08a49c55..2fb88b92 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/importer.h +++ b/third_party/protobuf/src/google/protobuf/compiler/importer.h @@ -41,10 +41,12 @@ #include #include #include + #include #include #include +// Must be included last. #include namespace google { @@ -85,7 +87,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { // the specified source_tree. SourceTreeDescriptorDatabase(SourceTree* source_tree, DescriptorDatabase* fallback_database); - ~SourceTreeDescriptorDatabase(); + ~SourceTreeDescriptorDatabase() override; // Instructs the SourceTreeDescriptorDatabase to report any parse errors // to the given MultiFileErrorCollector. This should be called before @@ -124,7 +126,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { : public DescriptorPool::ErrorCollector { public: ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); - ~ValidationErrorCollector(); + ~ValidationErrorCollector() override; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, const std::string& element_name, @@ -241,7 +243,7 @@ class PROTOBUF_EXPORT SourceTree { class PROTOBUF_EXPORT DiskSourceTree : public SourceTree { public: DiskSourceTree(); - ~DiskSourceTree(); + ~DiskSourceTree() override; // Map a path on disk to a location in the SourceTree. The path may be // either a file or a directory. If it is a directory, the entire tree diff --git a/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc index daa197f4..d2810ade 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc @@ -66,20 +66,20 @@ bool FileExists(const std::string& path) { class MockErrorCollector : public MultiFileErrorCollector { public: MockErrorCollector() {} - ~MockErrorCollector() {} + ~MockErrorCollector() override {} std::string text_; std::string warning_text_; // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, - const std::string& message) { + const std::string& message) override { strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, message); } void AddWarning(const std::string& filename, int line, int column, - const std::string& message) { + const std::string& message) override { strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -91,23 +91,23 @@ class MockErrorCollector : public MultiFileErrorCollector { class MockSourceTree : public SourceTree { public: MockSourceTree() {} - ~MockSourceTree() {} + ~MockSourceTree() override {} void AddFile(const std::string& name, const char* contents) { files_[name] = contents; } // implements SourceTree ------------------------------------------- - io::ZeroCopyInputStream* Open(const std::string& filename) { + io::ZeroCopyInputStream* Open(const std::string& filename) override { const char* contents = FindPtrOrNull(files_, filename); - if (contents == NULL) { - return NULL; + if (contents == nullptr) { + return nullptr; } else { return new io::ArrayInputStream(contents, strlen(contents)); } } - std::string GetLastErrorMessage() { return "File not found."; } + std::string GetLastErrorMessage() override { return "File not found."; } private: std::unordered_map files_; @@ -139,7 +139,7 @@ TEST_F(ImporterTest, Import) { const FileDescriptor* file = importer_.Import("foo.proto"); EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); ASSERT_EQ(1, file->message_type_count()); EXPECT_EQ("Foo", file->message_type(0)->name()); @@ -168,8 +168,8 @@ TEST_F(ImporterTest, ImportNested) { const FileDescriptor* foo = importer_.Import("foo.proto"); const FileDescriptor* bar = importer_.Import("bar.proto"); EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(foo != NULL); - ASSERT_TRUE(bar != NULL); + ASSERT_TRUE(foo != nullptr); + ASSERT_TRUE(bar != nullptr); // Check that foo's dependency is the same object as bar. ASSERT_EQ(1, foo->dependency_count()); @@ -187,7 +187,7 @@ TEST_F(ImporterTest, ImportNested) { TEST_F(ImporterTest, FileNotFound) { // Error: Parsing a file that doesn't exist. - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_TRUE(importer_.Import("foo.proto") == nullptr); EXPECT_EQ("foo.proto:-1:0: File not found.\n", error_collector_.text_); } @@ -197,7 +197,7 @@ TEST_F(ImporterTest, ImportNotFound) { "syntax = \"proto2\";\n" "import \"bar.proto\";\n"); - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); + EXPECT_TRUE(importer_.Import("foo.proto") == nullptr); EXPECT_EQ( "bar.proto:-1:0: File not found.\n" "foo.proto:1:0: Import \"bar.proto\" was not found or had errors.\n", @@ -214,7 +214,7 @@ TEST_F(ImporterTest, RecursiveImport) { "syntax = \"proto2\";\n" "import \"recursive1.proto\";\n"); - EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL); + EXPECT_TRUE(importer_.Import("recursive1.proto") == nullptr); EXPECT_EQ( "recursive1.proto:2:0: File recursively imports itself: " "recursive1.proto " @@ -262,7 +262,7 @@ TEST_F(ImporterTest, LiteRuntimeImport) { class DiskSourceTreeTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1"); dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); @@ -274,7 +274,7 @@ class DiskSourceTreeTest : public testing::Test { } } - virtual void TearDown() { + void TearDown() override { for (int i = 0; i < dirnames_.size(); i++) { if (FileExists(dirnames_[i])) { File::DeleteRecursively(dirnames_[i], NULL, NULL); @@ -294,7 +294,7 @@ class DiskSourceTreeTest : public testing::Test { const char* expected_contents) { std::unique_ptr input(source_tree_.Open(filename)); - ASSERT_FALSE(input == NULL); + ASSERT_FALSE(input == nullptr); // Read all the data from the file. std::string file_contents; @@ -310,7 +310,7 @@ class DiskSourceTreeTest : public testing::Test { void ExpectCannotOpenFile(const std::string& filename, const std::string& error_message) { std::unique_ptr input(source_tree_.Open(filename)); - EXPECT_TRUE(input == NULL); + EXPECT_TRUE(input == nullptr); EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); } @@ -537,8 +537,8 @@ TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) { EXPECT_EQ("not touched", not_touched); // Accept NULL as output parameter. - EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL)); - EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL)); + EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", nullptr)); + EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", nullptr)); } } // namespace diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_context.cc b/third_party/protobuf/src/google/protobuf/compiler/java/context.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_context.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/context.cc index fea870f1..cdc0d447 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_context.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/context.cc @@ -28,13 +28,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include -#include -#include -#include #include #include +#include +#include +#include #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_context.h b/third_party/protobuf/src/google/protobuf/compiler/java/context.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_context.h rename to third_party/protobuf/src/google/protobuf/compiler/java/context.h index 3fa6af17..c224ab73 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_context.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/context.h @@ -36,7 +36,7 @@ #include #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.cc index 80b79025..066bff64 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.cc @@ -32,13 +32,13 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include -#include #include #include +#include namespace google { namespace protobuf { @@ -199,7 +199,16 @@ void WriteDeprecatedJavadoc(io::Printer* printer, const FieldDescriptor* field, return; } - printer->Print(" * @deprecated\n"); + std::string startLine = "0"; + SourceLocation location; + if (field->GetSourceLocation(&location)) { + startLine = std::to_string(location.start_line); + } + + printer->Print(" * @deprecated $name$ is deprecated.\n", "name", + field->full_name()); + printer->Print(" * See $file$;l=$line$\n", "file", field->file()->name(), + "line", startLine); } void WriteFieldAccessorDocComment(io::Printer* printer, diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.h similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h rename to third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.h index b7de8776..7f687781 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment.h @@ -37,6 +37,7 @@ #include +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment_unittest.cc similarity index 75% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/doc_comment_unittest.cc index ae582ea6..3fcdf074 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/doc_comment_unittest.cc @@ -30,7 +30,7 @@ // Author: kenton@google.com (Kenton Varda) -#include +#include #include @@ -49,17 +49,6 @@ TEST(JavaDocCommentTest, Escaping) { EXPECT_EQ("@deprecated", EscapeJavadoc("@deprecated")); } -// TODO(kenton): It's hard to write a robust test of the doc comments -- we -// can only really compare the output against a golden value, which is a -// fairly tedious and fragile testing strategy. If we want to go that route, -// it probably makes sense to bite the bullet and write a test that compares -// the whole generated output for unittest.proto against a golden value, with -// a very simple script that can be run to regenerate it with the latest code. -// This would mean that updates to the golden file would have to be included -// in any change to the code generator, which would actually be fairly useful -// as it allows the reviewer to see clearly how the generated code is -// changing. - } // namespace } // namespace java } // namespace compiler diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc b/third_party/protobuf/src/google/protobuf/compiler/java/enum.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/enum.cc index 51032c27..0cab93c3 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum.cc @@ -32,17 +32,21 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -389,3 +393,5 @@ bool EnumGenerator::CanUseEnumValues() { } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.h b/third_party/protobuf/src/google/protobuf/compiler/java/enum.h similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum.h rename to third_party/protobuf/src/google/protobuf/compiler/java/enum.h diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field.cc similarity index 85% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_field.cc index 0dad42ad..e64ee5bc 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field.cc @@ -32,21 +32,24 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include "google/protobuf/compiler/java/enum_field.h" #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "google/protobuf/stubs/logging.h" +#include "google/protobuf/stubs/common.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" +#include "google/protobuf/stubs/strutil.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" + +// Must be last. +#include "google/protobuf/port_def.inc" namespace google { namespace protobuf { @@ -55,10 +58,11 @@ namespace java { namespace { -void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables) { +void SetEnumVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + std::map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = @@ -77,40 +81,27 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; - (*variables)["on_changed"] = "onChanged();"; - // Use deprecated valueOf() method to be compatible with old generated code - // for v2.5.0/v2.6.1. - // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility - // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations. - (*variables)["for_number"] = "valueOf"; - + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); - // Note that these have a trailing ";". (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex) + ";"; - (*variables)["set_has_field_bit_builder"] = - GenerateSetBit(builderBitIndex) + ";"; - (*variables)["clear_has_field_bit_builder"] = - GenerateClearBit(builderBitIndex) + ";"; - + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { (*variables)["set_has_field_bit_message"] = ""; - (*variables)["set_has_field_bit_builder"] = ""; - (*variables)["clear_has_field_bit_builder"] = ""; - - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"] + - ".getNumber()"; + (*variables)["set_has_field_bit_to_local"] = ""; + variables->insert({"is_field_present_message", + StrCat((*variables)["name"], "_ != ", + (*variables)["default"], ".getNumber()")}); } // For repeated builders, one bit is used for whether the array is immutable. @@ -118,22 +109,21 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); - // For repeated fields, one bit is used for whether the array is immutable - // in the parsing constructor. - (*variables)["get_mutable_bit_parser"] = - GenerateGetBitMutableLocal(builderBitIndex); - (*variables)["set_mutable_bit_parser"] = - GenerateSetBitMutableLocal(builderBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); - (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); if (SupportUnknownEnumValue(descriptor->file())) { - (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED"; + variables->insert( + {"unknown", StrCat((*variables)["type"], ".UNRECOGNIZED")}); } else { - (*variables)["unknown"] = (*variables)["default"]; + variables->insert({"unknown", (*variables)["default"]}); } } @@ -144,21 +134,30 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + : descriptor_(descriptor), + message_bit_index_(messageBitIndex), + builder_bit_index_(builderBitIndex), + name_resolver_(context->GetNameResolver()) { SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, context->GetFieldGeneratorInfo(descriptor), name_resolver_, - &variables_); + &variables_, context); } ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {} +int ImmutableEnumFieldGenerator::GetMessageBitIndex() const { + return message_bit_index_; +} + +int ImmutableEnumFieldGenerator::GetBuilderBitIndex() const { + return builder_bit_index_; +} + int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { return HasHasbit(descriptor_) ? 1 : 0; } -int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { - return GetNumBitsForMessage(); -} +int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { return 1; } void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { @@ -177,7 +176,7 @@ void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( } void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, "private int $name$_;\n"); + printer->Print(variables_, "private int $name$_ = $default_number$;\n"); PrintExtraFieldInfo(variables_, printer); if (HasHazzer(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); @@ -201,8 +200,7 @@ void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "@java.lang.Override $deprecation$public $type$ " "${$get$capitalized_name$$}$() {\n" - " @SuppressWarnings(\"deprecation\")\n" - " $type$ result = $type$.$for_number$($name$_);\n" + " $type$ result = $type$.forNumber($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -233,9 +231,9 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder " "${$set$capitalized_name$Value$}$(int value) {\n" - " $set_has_field_bit_builder$\n" " $name$_ = value;\n" - " $on_changed$\n" + " $set_has_field_bit_builder$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -244,8 +242,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" - " @SuppressWarnings(\"deprecation\")\n" - " $type$ result = $type$.$for_number$($name$_);\n" + " $type$ result = $type$.forNumber($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -259,7 +256,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( " }\n" " $set_has_field_bit_builder$\n" " $name$_ = value.getNumber();\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -270,7 +267,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n" " $name$_ = $default_number$;\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -317,9 +314,7 @@ void ImmutableEnumFieldGenerator::GenerateInitializationCode( void ImmutableEnumFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - printer->Print(variables_, - "$name$_ = $default_number$;\n" - "$clear_has_field_bit_builder$\n"); + printer->Print(variables_, "$name$_ = $default_number$;\n"); } void ImmutableEnumFieldGenerator::GenerateMergingCode( @@ -342,41 +337,35 @@ void ImmutableEnumFieldGenerator::GenerateMergingCode( void ImmutableEnumFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (HasHazzer(descriptor_)) { - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n"); + if (GetNumBitsForMessage() > 0) { + printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } - printer->Print(variables_, "result.$name$_ = $name$_;\n"); + printer->Print("}\n"); } -void ImmutableEnumFieldGenerator::GenerateParsingCode( +void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print(variables_, - "int rawValue = input.readEnum();\n" - "$set_has_field_bit_message$\n" - "$name$_ = rawValue;\n"); + "$name$_ = input.readEnum();\n" + "$set_has_field_bit_builder$\n"); } else { printer->Print(variables_, - "int rawValue = input.readEnum();\n" - " @SuppressWarnings(\"deprecation\")\n" - "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n" - " unknownFields.mergeVarintField($number$, rawValue);\n" + "int tmpRaw = input.readEnum();\n" + "$type$ tmpValue =\n" + " $type$.forNumber(tmpRaw);\n" + "if (tmpValue == null) {\n" + " mergeUnknownVarintField($number$, tmpRaw);\n" "} else {\n" - " $set_has_field_bit_message$\n" - " $name$_ = rawValue;\n" + " $name$_ = tmpRaw;\n" + " $set_has_field_bit_builder$\n" "}\n"); } } -void ImmutableEnumFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - // noop for enums -} - void ImmutableEnumFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, @@ -450,8 +439,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers( printer->Print(variables_, "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" - " @SuppressWarnings(\"deprecation\")\n" - " $type$ result = $type$.$for_number$(\n" + " $type$ result = $type$.forNumber(\n" " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" @@ -490,7 +478,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( "${$set$capitalized_name$Value$}$(int value) {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -500,14 +488,14 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" - " @SuppressWarnings(\"deprecation\")\n" - " $type$ result = $type$.$for_number$(\n" + " $type$ result = $type$.forNumber(\n" " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, /* builder */ true); printer->Print(variables_, @@ -518,10 +506,11 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " }\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value.getNumber();\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ true); printer->Print( @@ -530,19 +519,21 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" - " $on_changed$\n" + " onChanged();\n" " }\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + // No-op: Enum fields in oneofs are correctly cleared by clearing the oneof +} + void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " result.$oneof_name$_ = $oneof_name$_;\n" - "}\n"); + // No-Op: Handled by single statement for the oneof } void ImmutableEnumOneofFieldGenerator::GenerateMergingCode( @@ -557,7 +548,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateMergingCode( } } -void ImmutableEnumOneofFieldGenerator::GenerateParsingCode( +void ImmutableEnumOneofFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print(variables_, @@ -567,10 +558,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateParsingCode( } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" - "@SuppressWarnings(\"deprecation\")\n" - "$type$ value = $type$.$for_number$(rawValue);\n" + "$type$ value =\n" + " $type$.forNumber(rawValue);\n" "if (value == null) {\n" - " unknownFields.mergeVarintField($number$, rawValue);\n" + " mergeUnknownVarintField($number$, rawValue);\n" "} else {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = rawValue;\n" @@ -631,11 +622,8 @@ void ImmutableEnumOneofFieldGenerator::GenerateHashCode( RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { - SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, - context->GetFieldGeneratorInfo(descriptor), name_resolver_, - &variables_); -} + : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex, + context) {} RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {} @@ -675,6 +663,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print( variables_, + "@SuppressWarnings(\"serial\")\n" "private java.util.List $name$_;\n" "private static final " "com.google.protobuf.Internal.ListAdapter.Converter<\n" @@ -682,8 +671,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( " new com.google.protobuf.Internal.ListAdapter.Converter<\n" " java.lang.Integer, $type$>() {\n" " public $type$ convert(java.lang.Integer from) {\n" - " @SuppressWarnings(\"deprecation\")\n" - " $type$ result = $type$.$for_number$(from);\n" + " $type$ result = $type$.forNumber(from);\n" " return result == null ? $unknown$ : result;\n" " }\n" " };\n"); @@ -799,7 +787,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " }\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value.getNumber());\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -813,7 +801,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " }\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value.getNumber());\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -826,7 +814,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " for ($type$ value : values) {\n" " $name$_.add(value.getNumber());\n" " }\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -837,7 +825,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = java.util.Collections.emptyList();\n" " $clear_mutable_bit_builder$;\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -859,7 +847,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldEnumValueAccessorDocComment(printer, descriptor_, - LIST_INDEXED_GETTER, + LIST_INDEXED_SETTER, /* builder */ true); printer->Print( variables_, @@ -867,7 +855,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " int index, int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value);\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -878,7 +866,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( "${$add$capitalized_name$Value$}$(int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -892,7 +880,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " for (int value : values) {\n" " $name$_.add(value);\n" " }\n" - " $on_changed$\n" + " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -932,7 +920,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode( " ensure$capitalized_name$IsMutable();\n" " $name$_.addAll(other.$name$_);\n" " }\n" - " $on_changed$\n" + " onChanged();\n" "}\n"); } @@ -949,36 +937,29 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode( "result.$name$_ = $name$_;\n"); } -void RepeatedImmutableEnumFieldGenerator::GenerateParsingCode( +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { // Read and store the enum if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print(variables_, - "int rawValue = input.readEnum();\n" - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = new java.util.ArrayList();\n" - " $set_mutable_bit_parser$;\n" - "}\n" - "$name$_.add(rawValue);\n"); + "int tmpRaw = input.readEnum();\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(tmpRaw);\n"); } else { - printer->Print( - variables_, - "int rawValue = input.readEnum();\n" - "@SuppressWarnings(\"deprecation\")\n" - "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n" - " unknownFields.mergeVarintField($number$, rawValue);\n" - "} else {\n" - " if (!$get_mutable_bit_parser$) {\n" - " $name$_ = new java.util.ArrayList();\n" - " $set_mutable_bit_parser$;\n" - " }\n" - " $name$_.add(rawValue);\n" - "}\n"); + printer->Print(variables_, + "int tmpRaw = input.readEnum();\n" + "$type$ tmpValue =\n" + " $type$.forNumber(tmpRaw);\n" + "if (tmpValue == null) {\n" + " mergeUnknownVarintField($number$, tmpRaw);\n" + "} else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(tmpRaw);\n" + "}\n"); } } -void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked( +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCodeFromPacked( io::Printer* printer) const { // Wrap GenerateParsingCode's contents with a while loop. @@ -988,7 +969,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked( "while(input.getBytesUntilLimit() > 0) {\n"); printer->Indent(); - GenerateParsingCode(printer); + GenerateBuilderParsingCode(printer); printer->Outdent(); printer->Print(variables_, @@ -996,15 +977,6 @@ void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked( "input.popLimit(oldLimit);\n"); } -void RepeatedImmutableEnumFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - printer->Print( - variables_, - "if ($get_mutable_bit_parser$) {\n" - " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" - "}\n"); -} - void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { if (descriptor_->is_packed()) { @@ -1087,7 +1059,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateKotlinDslMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$kt_deprecation$ public val $kt_name$: " + "$kt_deprecation$public val $kt_name$: " "com.google.protobuf.kotlin.DslList" "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" " @kotlin.jvm.JvmSynthetic\n" @@ -1174,3 +1146,5 @@ std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const { } // namespace compiler } // namespace protobuf } // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field.h similarity index 83% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_field.h index 82dbd9e4..8f0a5c3e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include "google/protobuf/compiler/java/field.h" namespace google { namespace protobuf { @@ -60,10 +61,15 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); + ImmutableEnumFieldGenerator(const ImmutableEnumFieldGenerator&) = delete; + ImmutableEnumFieldGenerator& operator=(const ImmutableEnumFieldGenerator&) = + delete; ~ImmutableEnumFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- + int GetMessageBitIndex() const override; + int GetBuilderBitIndex() const override; int GetNumBitsForMessage() const override; int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; @@ -71,10 +77,9 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderMembers(io::Printer* printer) const override; void GenerateInitializationCode(io::Printer* printer) const override; void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -87,11 +92,10 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; + int message_bit_index_; + int builder_bit_index_; std::map variables_; ClassNameResolver* name_resolver_; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator); }; class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { @@ -99,27 +103,33 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableEnumOneofFieldGenerator(); + ImmutableEnumOneofFieldGenerator(const ImmutableEnumOneofFieldGenerator&) = + delete; + ImmutableEnumOneofFieldGenerator& operator=( + const ImmutableEnumOneofFieldGenerator&) = delete; + ~ImmutableEnumOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateEqualsCode(io::Printer* printer) const override; void GenerateHashCode(io::Printer* printer) const override; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator); }; -class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator { +class RepeatedImmutableEnumFieldGenerator : public ImmutableEnumFieldGenerator { public: explicit RepeatedImmutableEnumFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); + RepeatedImmutableEnumFieldGenerator( + const RepeatedImmutableEnumFieldGenerator&) = delete; + RepeatedImmutableEnumFieldGenerator& operator=( + const RepeatedImmutableEnumFieldGenerator&) = delete; ~RepeatedImmutableEnumFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- @@ -132,9 +142,9 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingCodeFromPacked(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCodeFromPacked( + io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -144,13 +154,6 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator { void GenerateKotlinDslMembers(io::Printer* printer) const override; std::string GetBoxedType() const override; - - private: - const FieldDescriptor* descriptor_; - std::map variables_; - ClassNameResolver* name_resolver_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator); }; } // namespace java diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.cc similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.cc index ca3a2e88..e80b938f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,13 +40,16 @@ #include #include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -916,3 +919,5 @@ std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const { } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.h similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.h index 6ed11c9e..492b268b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum_field_lite.h @@ -39,7 +39,7 @@ #include #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/enum_lite.cc similarity index 96% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_lite.cc index aa64c971..4387090a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/enum_lite.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/enum_lite.h similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_enum_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/enum_lite.h diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc b/third_party/protobuf/src/google/protobuf/compiler/java/extension.cc similarity index 94% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/extension.cc index db210fb3..8b93eb18 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/extension.cc @@ -32,14 +32,17 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -170,3 +173,5 @@ int ImmutableExtensionGenerator::GenerateRegistrationCode( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h b/third_party/protobuf/src/google/protobuf/compiler/java/extension.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h rename to third_party/protobuf/src/google/protobuf/compiler/java/extension.h index f928a783..318cfa4c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/extension.h @@ -92,7 +92,7 @@ class ImmutableExtensionGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionGenerator(); + ~ImmutableExtensionGenerator() override; void Generate(io::Printer* printer) override; int GenerateNonNestedInitializationCode(io::Printer* printer) override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.cc similarity index 92% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.cc index 71bf4e23..bffb1d65 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.cc @@ -28,14 +28,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -113,3 +116,5 @@ int ImmutableExtensionLiteGenerator::GenerateRegistrationCode( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.h similarity index 96% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.h index 76961563..264230cb 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/extension_lite.h @@ -35,7 +35,7 @@ #include #include -#include +#include namespace google { namespace protobuf { @@ -49,7 +49,7 @@ class ImmutableExtensionLiteGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionLiteGenerator(); + ~ImmutableExtensionLiteGenerator() override; void Generate(io::Printer* printer) override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/field.cc similarity index 93% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/field.cc index 8916d138..3dd528ff 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/field.cc @@ -32,27 +32,27 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace google { @@ -185,7 +185,7 @@ static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) { // but this method should be overridden. // - This FieldGenerator doesn't support packing, and this method // should never have been called. - GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() " + GOOGLE_LOG(FATAL) << "GenerateBuilderParsingCodeFromPacked() " << "called on field generator that does not support packing."; } @@ -193,7 +193,7 @@ static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) { ImmutableFieldGenerator::~ImmutableFieldGenerator() {} -void ImmutableFieldGenerator::GenerateParsingCodeFromPacked( +void ImmutableFieldGenerator::GenerateBuilderParsingCodeFromPacked( io::Printer* printer) const { ReportUnexpectedPackedFieldsCall(printer); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/field.h similarity index 95% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/field.h index a7c995c4..7f82316b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/field.h @@ -68,6 +68,8 @@ class ImmutableFieldGenerator { ImmutableFieldGenerator() {} virtual ~ImmutableFieldGenerator(); + virtual int GetMessageBitIndex() const = 0; + virtual int GetBuilderBitIndex() const = 0; virtual int GetNumBitsForMessage() const = 0; virtual int GetNumBitsForBuilder() const = 0; virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; @@ -77,9 +79,8 @@ class ImmutableFieldGenerator { virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0; virtual void GenerateMergingCode(io::Printer* printer) const = 0; virtual void GenerateBuildingCode(io::Printer* printer) const = 0; - virtual void GenerateParsingCode(io::Printer* printer) const = 0; - virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const; - virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0; + virtual void GenerateBuilderParsingCode(io::Printer* printer) const = 0; + virtual void GenerateBuilderParsingCodeFromPacked(io::Printer* printer) const; virtual void GenerateSerializationCode(io::Printer* printer) const = 0; virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; virtual void GenerateFieldBuilderInitializationCode( @@ -156,7 +157,7 @@ template <> FieldGeneratorMap::~FieldGeneratorMap(); -// Field information used in FieldGeneartors. +// Field information used in FieldGenerators. struct FieldGeneratorInfo { std::string name; std::string capitalized_name; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc b/third_party/protobuf/src/google/protobuf/compiler/java/file.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/file.cc index 9dbf8181..cf277034 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/file.cc @@ -32,27 +32,30 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -247,7 +250,7 @@ bool FileGenerator::Validate(std::string* error) { << "generate full runtime code for Java. To use Java Lite runtime, " << "users should use the Java Lite plugin instead. See:\n" << " " - "https://github.com/protocolbuffers/protobuf/blob/master/java/" + "https://github.com/protocolbuffers/protobuf/blob/main/java/" "lite.md"; } return true; @@ -732,3 +735,5 @@ bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor, } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h b/third_party/protobuf/src/google/protobuf/compiler/java/file.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_file.h rename to third_party/protobuf/src/google/protobuf/compiler/java/file.h index 71ee3e85..b2e03730 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/file.h @@ -38,8 +38,9 @@ #include #include #include + #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/java/generator.cc similarity index 94% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/generator.cc index 29ae2cf9..85e39913 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/generator.cc @@ -32,20 +32,21 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/generator.h b/third_party/protobuf/src/google/protobuf/compiler/java/generator.h new file mode 100644 index 00000000..bbc71700 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/java/generator.h @@ -0,0 +1,77 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates Java code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ + +#include +#include + +// Must be included last. +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// CodeGenerator implementation which generates Java code. If you create your +// own protocol compiler binary and you want it to support Java output, you +// can do so by registering an instance of this CodeGenerator with the +// CommandLineInterface in your main() function. +class PROTOC_EXPORT JavaGenerator : public CodeGenerator { + public: + JavaGenerator(); + ~JavaGenerator() override; + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc b/third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.cc similarity index 83% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.cc index 3a62adb1..dd526ba7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.cc @@ -30,17 +30,17 @@ // Author: liujisi@google.com (Pherl Liu) -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h b/third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h rename to third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.h index 831d9dd8..807bca38 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/generator_factory.h @@ -78,7 +78,7 @@ class GeneratorFactory { class ImmutableGeneratorFactory : public GeneratorFactory { public: ImmutableGeneratorFactory(Context* context); - virtual ~ImmutableGeneratorFactory(); + ~ImmutableGeneratorFactory() override; MessageGenerator* NewMessageGenerator( const Descriptor* descriptor) const override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/java/helpers.cc similarity index 95% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/helpers.cc index f37ecde7..15ee8f55 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/helpers.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,15 +40,18 @@ #include #include -#include -#include -#include -#include #include #include +#include #include +#include +#include +#include #include // for hash +// Must be last. +#include + namespace google { namespace protobuf { namespace compiler { @@ -66,15 +69,26 @@ namespace { const char* kDefaultPackage = ""; -// Names that should be avoided as field names. -// Using them will cause the compiler to generate accessors whose names are -// colliding with methods defined in base classes. +// Names that should be avoided (in UpperCamelCase format). +// Using them will cause the compiler to generate accessors whose names +// collide with methods defined in base classes. +// Keep this list in sync with specialFieldNames in +// java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java const char* kForbiddenWordList[] = { - // message base class: - "cached_size", - "serialized_size", // java.lang.Object: - "class", + "Class", + // com.google.protobuf.MessageLiteOrBuilder: + "DefaultInstanceForType", + // com.google.protobuf.MessageLite: + "ParserForType", + "SerializedSize", + // com.google.protobuf.MessageOrBuilder: + "AllFields", + "DescriptorForType", + "InitializationErrorString", + "UnknownFields", + // obsolete. kept for backwards compatibility of generated code + "CachedSize", }; const std::unordered_set* kReservedNames = @@ -93,7 +107,7 @@ const std::unordered_set* kReservedNames = bool IsForbidden(const std::string& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { - if (field_name == kForbiddenWordList[i]) { + if (UnderscoresToCamelCase(field_name, true) == kForbiddenWordList[i]) { return true; } } @@ -249,18 +263,18 @@ std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) { return name; } +// Names that should be avoided as field names in Kotlin. +// All Kotlin hard keywords are in this list. +const std::unordered_set* kKotlinForbiddenNames = + new std::unordered_set({ + "as", "as?", "break", "class", "continue", "do", "else", + "false", "for", "fun", "if", "in", "!in", "interface", + "is", "!is", "null", "object", "package", "return", "super", + "this", "throw", "true", "try", "typealias", "typeof", "val", + "var", "when", "while", + }); + bool IsForbiddenKotlin(const std::string& field_name) { - // Names that should be avoided as field names in Kotlin. - // All Kotlin hard keywords are in this list. - const std::unordered_set* kKotlinForbiddenNames = - new std::unordered_set({ - "as", "as?", "break", "class", "continue", "do", - "else", "false", "for", "fun", "if", "in", - "!in", "interface", "is", "!is", "null", "object", - "package", "return", "super", "this", "throw", "true", - "try", "typealias", "typeof", "val", "var", "when", - "while", - }); return kKotlinForbiddenNames->find(field_name) != kKotlinForbiddenNames->end(); } @@ -1049,8 +1063,7 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { if (field->is_map()) { if (!SupportUnknownEnumValue(field)) { - const FieldDescriptor* value = - field->message_type()->FindFieldByName("value"); + const FieldDescriptor* value = field->message_type()->map_value(); if (GetJavaType(value) == JAVATYPE_ENUM) { extra_bits |= kMapWithProto2EnumValue; } @@ -1098,3 +1111,5 @@ void EscapeUtf16ToString(uint16_t code, std::string* output) { } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/java/helpers.h similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h rename to third_party/protobuf/src/google/protobuf/compiler/java/helpers.h index 28cac6af..9f1a5573 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/helpers.h @@ -38,10 +38,10 @@ #include #include -#include -#include #include #include +#include +#include namespace google { namespace protobuf { @@ -151,6 +151,21 @@ inline bool IsDescriptorProto(const Descriptor* descriptor) { // fields. std::string GetOneofStoredType(const FieldDescriptor* field); +// We use either the proto1 enums if the enum is generated, otherwise fall back +// to use integers. +enum class Proto1EnumRepresentation { + kEnum, + kInteger, +}; + +// Returns which representation we should use. +inline Proto1EnumRepresentation GetProto1EnumRepresentation( + const EnumDescriptor* descriptor) { + if (descriptor->containing_type() != nullptr) { + return Proto1EnumRepresentation::kEnum; + } + return Proto1EnumRepresentation::kInteger; +} // Whether we should generate multiple java files for messages. inline bool MultipleJavaFiles(const FileDescriptor* descriptor, diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h index 6315e7c3..294b1bde 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h @@ -1,76 +1,6 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_JAVA_GENERATOR_H_ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_JAVA_GENERATOR_H_ -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Generates Java code for a given .proto file. +#include -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ - -#include -#include - -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -// CodeGenerator implementation which generates Java code. If you create your -// own protocol compiler binary and you want it to support Java output, you -// can do so by registering an instance of this CodeGenerator with the -// CommandLineInterface in your main() function. -class PROTOC_EXPORT JavaGenerator : public CodeGenerator { - public: - JavaGenerator(); - ~JavaGenerator(); - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const override; - - uint64_t GetSupportedFeatures() const override; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_JAVA_GENERATOR_H_ diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.cc similarity index 88% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.cc index 8d262a01..1af548a9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.cc @@ -28,13 +28,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include -#include -#include -#include -#include #include +#include +#include +#include +#include namespace google { namespace protobuf { @@ -63,11 +63,13 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, if (option.first == "output_list_file") { file_options.output_list_file = option.second; } else if (option.first == "immutable") { + // Note: the option is considered always set regardless of the input. file_options.generate_immutable_code = true; } else if (option.first == "mutable") { *error = "Mutable not supported by Kotlin generator"; return false; } else if (option.first == "shared") { + // Note: the option is considered always set regardless of the input. file_options.generate_shared_code = true; } else if (option.first == "lite") { file_options.enforce_lite = true; @@ -81,23 +83,17 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, } } - // By default we generate immutable code and shared code for immutable API. - if (!file_options.generate_immutable_code && - !file_options.generate_shared_code) { - file_options.generate_immutable_code = true; - file_options.generate_shared_code = true; - } + // We only support generation of immutable code so we do it. + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; std::vector all_files; std::vector all_annotations; - std::unique_ptr file_generator; - if (file_options.generate_immutable_code) { - file_generator.reset( + std::unique_ptr file_generator( new FileGenerator(file, file_options, /* immutable_api = */ true)); - } - if (!file_generator->Validate(error)) { + if (!file_generator || !file_generator->Validate(error)) { return false; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.h b/third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.h similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.h rename to third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.h index 66e32b9e..ccd9688c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_kotlin_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/kotlin_generator.h @@ -36,6 +36,8 @@ #include #include + +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/map_field.cc similarity index 77% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/map_field.cc index 8a891007..777f107d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/map_field.cc @@ -28,13 +28,16 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "google/protobuf/compiler/java/map_field.h" -#include -#include -#include -#include -#include +#include "google/protobuf/io/printer.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" + +// Must be last. +#include "google/protobuf/port_def.inc" namespace google { namespace protobuf { @@ -47,14 +50,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } std::string TypeName(const FieldDescriptor* field, @@ -85,10 +88,10 @@ std::string WireType(const FieldDescriptor* field) { std::string(FieldTypeName(field->type())); } -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - Context* context, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, Context* context, + std::map* variables) { SetCommonFieldVariables(descriptor, info, variables); ClassNameResolver* name_resolver = context->GetNameResolver(); @@ -99,6 +102,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + std::string pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); std::string boxed_key_type = TypeName(key, name_resolver, true); (*variables)["boxed_key_type"] = boxed_key_type; @@ -115,13 +120,14 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, : ""; (*variables)["value_null_check"] = valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType) - ? "if (value == null) {\n" - " throw new NullPointerException(\"map value\");\n" - "}\n" + ? "if (value == null) { " + "throw new NullPointerException(\"map value\"); }" : ""; if (valueJavaType == JAVATYPE_ENUM) { // We store enums as Integers internally. (*variables)["value_type"] = "int"; + variables->insert( + {"value_type_pass_through_nullness", (*variables)["value_type"]}); (*variables)["boxed_value_type"] = "java.lang.Integer"; (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -129,10 +135,15 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + variables->insert( + {"value_enum_type_pass_through_nullness", + StrCat(pass_through_nullness, (*variables)["value_enum_type"])}); + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. - (*variables)["unrecognized_value"] = - (*variables)["value_enum_type"] + ".UNRECOGNIZED"; + variables->insert( + {"unrecognized_value", + StrCat((*variables)["value_enum_type"], ".UNRECOGNIZED")}); } else { // Map unknown values to the default value if we don't have UNRECOGNIZED. (*variables)["unrecognized_value"] = @@ -140,38 +151,49 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + variables->insert( + {"value_type_pass_through_nullness", + StrCat( + (IsReferenceType(valueJavaType) ? pass_through_nullness : ""), + (*variables)["value_type"])}); + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = DefaultValue(value, true, name_resolver); } - (*variables)["type_parameters"] = - (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"]; + variables->insert( + {"type_parameters", StrCat((*variables)["boxed_key_type"], ", ", + (*variables)["boxed_value_type"])}); // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; - // For repeated fields, one bit is used for whether the array is immutable - // in the parsing constructor. - (*variables)["get_mutable_bit_parser"] = - GenerateGetBitMutableLocal(builderBitIndex); - (*variables)["set_mutable_bit_parser"] = - GenerateSetBitMutableLocal(builderBitIndex); - - (*variables)["default_entry"] = - (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; - (*variables)["map_field_parameter"] = (*variables)["default_entry"]; + variables->insert( + {"default_entry", StrCat((*variables)["capitalized_name"], + "DefaultEntryHolder.defaultEntry")}); + variables->insert({"map_field_parameter", (*variables)["default_entry"]}); (*variables)["descriptor"] = name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" + UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, "; (*variables)["ver"] = GeneratedCodeVersionSuffix(); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; } } // namespace @@ -179,7 +201,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, ImmutableMapFieldGenerator::ImmutableMapFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + : descriptor_(descriptor), + message_bit_index_(messageBitIndex), + builder_bit_index_(builderBitIndex), + name_resolver_(context->GetNameResolver()), + context_(context) { SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, context->GetFieldGeneratorInfo(descriptor), context, &variables_); @@ -187,6 +213,14 @@ ImmutableMapFieldGenerator::ImmutableMapFieldGenerator( ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {} +int ImmutableMapFieldGenerator::GetMessageBitIndex() const { + return message_bit_index_; +} + +int ImmutableMapFieldGenerator::GetBuilderBitIndex() const { + return builder_bit_index_; +} + int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; } int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; } @@ -218,11 +252,12 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -247,16 +282,16 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + "$deprecation$$value_type_pass_through_nullness$ " + "${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" - " $key_type$ key);\n"); + printer->Print( + variables_, + "$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key);\n"); printer->Annotate("{", "}", descriptor_); } } else { @@ -275,16 +310,16 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$deprecation$$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" - " $key_type$ key);\n"); + printer->Print( + variables_, + "$deprecation$$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); printer->Annotate("{", "}", descriptor_); } } @@ -304,6 +339,7 @@ void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { " $value_default_value$);\n" "}\n"); printer->Print(variables_, + "@SuppressWarnings(\"serial\")\n" "private com.google.protobuf.MapField<\n" " $type_parameters$> $name$_;\n" "private com.google.protobuf.MapField<$type_parameters$>\n" @@ -339,42 +375,45 @@ void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { void ImmutableMapFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { - printer->Print(variables_, - "private com.google.protobuf.MapField<\n" - " $type_parameters$> $name$_;\n" - "private com.google.protobuf.MapField<$type_parameters$>\n" - "internalGet$capitalized_name$() {\n" - " if ($name$_ == null) {\n" - " return com.google.protobuf.MapField.emptyMapField(\n" - " $map_field_parameter$);\n" - " }\n" - " return $name$_;\n" - "}\n" - "private com.google.protobuf.MapField<$type_parameters$>\n" - "internalGetMutable$capitalized_name$() {\n" - " $on_changed$;\n" - " if ($name$_ == null) {\n" - " $name$_ = com.google.protobuf.MapField.newMapField(\n" - " $map_field_parameter$);\n" - " }\n" - " if (!$name$_.isMutable()) {\n" - " $name$_ = $name$_.copy();\n" - " }\n" - " return $name$_;\n" - "}\n"); + printer->Print( + variables_, + "private com.google.protobuf.MapField<\n" + " $type_parameters$> $name$_;\n" + "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n" + " internalGet$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return com.google.protobuf.MapField.emptyMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n" + "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n" + " internalGetMutable$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " $name$_ = com.google.protobuf.MapField.newMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.copy();\n" + " }\n" + " $set_has_field_bit_builder$\n" + " $on_changed$\n" + " return $name$_;\n" + "}\n"); GenerateMapGetters(printer); - printer->Print(variables_, - "$deprecation$\n" - "public Builder ${$clear$capitalized_name$$}$() {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .clear();\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit_builder$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .clear();\n" + " return this;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$\n" - "public Builder ${$remove$capitalized_name$$}$(\n" + "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" @@ -382,6 +421,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -390,7 +430,8 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "${$getMutable$capitalized_name$$}$() {\n" + " ${$getMutable$capitalized_name$$}$() {\n" + " $set_has_field_bit_builder$\n" " return internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap());\n" "}\n"); @@ -404,9 +445,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " $value_null_check$\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .put(key, $name$ValueConverter.doBackward(value));\n" + " $set_has_field_bit_builder$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -415,9 +458,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap())\n" " .putAll(values);\n" + " $set_has_field_bit_builder$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -427,6 +472,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$getMutable$capitalized_name$Value$}$() {\n" + " $set_has_field_bit_builder$\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -440,9 +486,11 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " $value_null_check$\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .put(key, value);\n" + " $set_has_field_bit_builder$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -450,6 +498,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .putAll(values);\n" + " $set_has_field_bit_builder$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); @@ -462,55 +511,59 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$>\n" - "${$getMutable$capitalized_name$$}$() {\n" + " ${$getMutable$capitalized_name$$}$() {\n" + " $set_has_field_bit_builder$\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$" - "public Builder ${$put$capitalized_name$$}$(\n" + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" " $value_null_check$\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .put(key, value);\n" + " $set_has_field_bit_builder$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public Builder ${$putAll$capitalized_name$$}$(\n" - " java.util.Map<$type_parameters$> values) {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .putAll(values);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " $set_has_field_bit_builder$\n" + " return this;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); } } void ImmutableMapFieldGenerator::GenerateMapGetters( io::Printer* printer) const { - printer->Print(variables_, - "$deprecation$\n" - "public int ${$get$capitalized_name$Count$}$() {\n" - " return internalGet$capitalized_name$().getMap().size();\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return internalGet$capitalized_name$().getMap().size();\n" + "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$\n" "@java.lang.Override\n" - "public boolean ${$contains$capitalized_name$$}$(\n" + "$deprecation$public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return internalGet$capitalized_name$().getMap().containsKey(key);\n" "}\n"); printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print(variables_, "/**\n" @@ -526,21 +579,22 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "$deprecation$public java.util.Map<$boxed_key_type$, " + "$value_enum_type$>\n" "${$get$capitalized_name$Map$}$() {\n" " return internalGetAdapted$capitalized_name$Map(\n" " internalGet$capitalized_name$().getMap());" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$deprecation$public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" " internalGet$capitalized_name$().getMap();\n" @@ -549,12 +603,12 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( " : defaultValue;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + "$deprecation$public $value_enum_type$ get$capitalized_name$OrThrow(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -565,6 +619,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( " return $name$ValueConverter.doForward(map.get(key));\n" "}\n"); printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -579,23 +634,22 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "${$get$capitalized_name$ValueMap$}$() {\n" - " return internalGet$capitalized_name$().getMap();\n" - "}\n"); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.Map<$boxed_key_type$, " + "$boxed_value_type$>\n" + "${$get$capitalized_name$ValueMap$}$() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + "$deprecation$public $value_type_pass_through_nullness$ " + "${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue) {\n" + " $value_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" " internalGet$capitalized_name$().getMap();\n" @@ -606,8 +660,8 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Print( variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + "$deprecation$public $value_type$ " + "${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -634,8 +688,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public java.util.Map<$type_parameters$> " + "$deprecation$public java.util.Map<$type_parameters$> " "${$get$capitalized_name$Map$}$() {\n" " return internalGet$capitalized_name$().getMap();\n" "}\n"); @@ -644,10 +697,10 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Print( variables_, "@java.lang.Override\n" - "$deprecation$\n" - "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$deprecation$public $value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue) {\n" + " $value_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" " internalGet$capitalized_name$().getMap();\n" @@ -655,19 +708,19 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$\n" - "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" - " $key_type$ key) {\n" - " $key_null_check$\n" - " java.util.Map<$type_parameters$> map =\n" - " internalGet$capitalized_name$().getMap();\n" - " if (!map.containsKey(key)) {\n" - " throw new java.lang.IllegalArgumentException();\n" - " }\n" - " return map.get(key);\n" - "}\n"); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); printer->Annotate("{", "}", descriptor_); } } @@ -766,6 +819,7 @@ void ImmutableMapFieldGenerator::GenerateInitializationCode( void ImmutableMapFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { + // No need to clear the has-bit since we clear the bitField ints all at once. printer->Print(variables_, "internalGetMutable$capitalized_name$().clear();\n"); } @@ -774,38 +828,34 @@ void ImmutableMapFieldGenerator::GenerateMergingCode( io::Printer* printer) const { printer->Print(variables_, "internalGetMutable$capitalized_name$().mergeFrom(\n" - " other.internalGet$capitalized_name$());\n"); + " other.internalGet$capitalized_name$());\n" + "$set_has_field_bit_builder$\n"); } void ImmutableMapFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { printer->Print(variables_, - "result.$name$_ = internalGet$capitalized_name$();\n" - "result.$name$_.makeImmutable();\n"); + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = internalGet$capitalized_name$();\n" + " result.$name$_.makeImmutable();\n" + "}\n"); } -void ImmutableMapFieldGenerator::GenerateParsingCode( +void ImmutableMapFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { - printer->Print(variables_, - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = com.google.protobuf.MapField.newMapField(\n" - " $map_field_parameter$);\n" - " $set_mutable_bit_parser$;\n" - "}\n"); if (!SupportUnknownEnumValue(descriptor_->file()) && GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, "com.google.protobuf.ByteString bytes = input.readBytes();\n" "com.google.protobuf.MapEntry<$type_parameters$>\n" - "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"); - printer->Print( - variables_, + "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n" "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n" - " unknownFields.mergeLengthDelimitedField($number$, bytes);\n" + " mergeUnknownLengthDelimitedField($number$, bytes);\n" "} else {\n" - " $name$_.getMutableMap().put(\n" + " internalGetMutable$capitalized_name$().getMutableMap().put(\n" " $name$__.getKey(), $name$__.getValue());\n" + " $set_has_field_bit_builder$\n" "}\n"); } else { printer->Print( @@ -813,16 +863,11 @@ void ImmutableMapFieldGenerator::GenerateParsingCode( "com.google.protobuf.MapEntry<$type_parameters$>\n" "$name$__ = input.readMessage(\n" " $default_entry$.getParserForType(), extensionRegistry);\n" - "$name$_.getMutableMap().put(\n" - " $name$__.getKey(), $name$__.getValue());\n"); + "internalGetMutable$capitalized_name$().getMutableMap().put(\n" + " $name$__.getKey(), $name$__.getValue());\n" + "$set_has_field_bit_builder$\n"); } } - -void ImmutableMapFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - // Nothing to do here. -} - void ImmutableMapFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, @@ -874,3 +919,5 @@ std::string ImmutableMapFieldGenerator::GetBoxedType() const { } // namespace compiler } // namespace protobuf } // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/map_field.h similarity index 92% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/map_field.h index 98d9249a..d54a28bd 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/map_field.h @@ -31,7 +31,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__ -#include +#include "google/protobuf/compiler/java/field.h" namespace google { namespace protobuf { @@ -46,6 +46,8 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { ~ImmutableMapFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- + int GetMessageBitIndex() const override; + int GetBuilderBitIndex() const override; int GetNumBitsForMessage() const override; int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; @@ -55,8 +57,7 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -69,8 +70,11 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { private: const FieldDescriptor* descriptor_; + int message_bit_index_; + int builder_bit_index_; std::map variables_; ClassNameResolver* name_resolver_; + Context* context_; void GenerateMapGetters(io::Printer* printer) const; }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.cc similarity index 96% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.cc index e7111686..ed6f8f39 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.cc @@ -28,15 +28,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include #include -#include -#include -#include -#include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -49,14 +52,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } std::string TypeName(const FieldDescriptor* field, @@ -101,6 +104,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + std::string pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver); @@ -128,6 +133,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + (*variables)["value_enum_type_pass_through_nullness"] = + pass_through_nullness + (*variables)["value_enum_type"]; + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. (*variables)["unrecognized_value"] = @@ -139,6 +147,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + (*variables)["value_type_pass_through_nullness"] = + (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + + (*variables)["value_type"]; + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -203,11 +216,12 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -261,9 +275,10 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -606,9 +621,10 @@ void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers( variables_, "@java.lang.Override\n" "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" " instance.get$capitalized_name$Map();\n" @@ -907,3 +923,5 @@ std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const { } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.h index da046b21..964f0982 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_map_field_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.h @@ -33,7 +33,7 @@ #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message.cc similarity index 88% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message.cc index 27d1014f..a29d9a78 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,21 +40,25 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -67,7 +71,7 @@ using internal::WireFormatLite; namespace { std::string MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } @@ -376,6 +380,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "}\n" "\n"); + // TODO(b/248149118): Remove this superfluous override. printer->Print( "@java.lang.Override\n" "public final com.google.protobuf.UnknownFieldSet\n" @@ -383,10 +388,6 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { " return this.unknownFields;\n" "}\n"); - if (context_->HasGeneratedMethods(descriptor_)) { - GenerateParsingConstructor(printer); - } - GenerateDescriptorMethods(printer); // Nested types @@ -635,9 +636,9 @@ void ImmutableMessageGenerator::GenerateMessageSerializationMethods( } if (descriptor_->options().message_set_wire_format()) { - printer->Print("unknownFields.writeAsMessageSetTo(output);\n"); + printer->Print("getUnknownFields().writeAsMessageSetTo(output);\n"); } else { - printer->Print("unknownFields.writeTo(output);\n"); + printer->Print("getUnknownFields().writeTo(output);\n"); } printer->Outdent(); @@ -666,9 +667,10 @@ void ImmutableMessageGenerator::GenerateMessageSerializationMethods( } if (descriptor_->options().message_set_wire_format()) { - printer->Print("size += unknownFields.getSerializedSizeAsMessageSet();\n"); + printer->Print( + "size += getUnknownFields().getSerializedSizeAsMessageSet();\n"); } else { - printer->Print("size += unknownFields.getSerializedSize();\n"); + printer->Print("size += getUnknownFields().getSerializedSize();\n"); } printer->Print( @@ -1065,7 +1067,8 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( // false for non-canonical ordering when running in LITE_RUNTIME but it's // the best we can do. printer->Print( - "if (!unknownFields.equals(other.unknownFields)) return false;\n"); + "if (!getUnknownFields().equals(other.getUnknownFields())) return " + "false;\n"); if (descriptor_->extension_range_count() > 0) { printer->Print( "if (!getExtensionFields().equals(other.getExtensionFields()))\n" @@ -1139,7 +1142,7 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( printer->Print("hash = hashFields(hash, getExtensionFields());\n"); } - printer->Print("hash = (29 * hash) + unknownFields.hashCode();\n"); + printer->Print("hash = (29 * hash) + getUnknownFields().hashCode();\n"); printer->Print( "memoizedHashCode = hash;\n" "return hash;\n"); @@ -1164,186 +1167,33 @@ void ImmutableMessageGenerator::GenerateExtensionRegistrationCode( } } -// =================================================================== -void ImmutableMessageGenerator::GenerateParsingConstructor( - io::Printer* printer) { - std::unique_ptr sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print( - "private $classname$(\n" - " com.google.protobuf.CodedInputStream input,\n" - " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n", - "classname", descriptor_->name()); - printer->Indent(); - - // Initialize all fields to default. - printer->Print( - "this();\n" - "if (extensionRegistry == null) {\n" - " throw new java.lang.NullPointerException();\n" - "}\n"); - - // Use builder bits to track mutable repeated fields. - int totalBuilderBits = 0; - for (int i = 0; i < descriptor_->field_count(); i++) { - const ImmutableFieldGenerator& field = - field_generators_.get(descriptor_->field(i)); - totalBuilderBits += field.GetNumBitsForBuilder(); - } - int totalBuilderInts = (totalBuilderBits + 31) / 32; - for (int i = 0; i < totalBuilderInts; i++) { - printer->Print("int mutable_$bit_field_name$ = 0;\n", "bit_field_name", - GetBitFieldName(i)); - } - - printer->Print( - "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" - " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); - - printer->Print("try {\n"); - printer->Indent(); - - printer->Print( - "boolean done = false;\n" - "while (!done) {\n"); - printer->Indent(); - - printer->Print( - "int tag = input.readTag();\n" - "switch (tag) {\n"); - printer->Indent(); - - printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " done = true;\n" - " break;\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32_t tag = WireFormatLite::MakeTag( - field->number(), WireFormat::WireTypeForFieldType(field->type())); - - printer->Print("case $tag$: {\n", "tag", - StrCat(static_cast(tag))); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCode(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - - if (field->is_packable()) { - // To make packed = true wire compatible, we generate parsing code from a - // packed version of this field regardless of field->options().packed(). - uint32_t packed_tag = WireFormatLite::MakeTag( - field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - printer->Print("case $tag$: {\n", "tag", - StrCat(static_cast(packed_tag))); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCodeFromPacked(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - } - } - - printer->Print( - "default: {\n" - " if (!parseUnknownField(\n" - " input, unknownFields, extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // switch (tag) - "}\n"); // while (!done) - - printer->Outdent(); - printer->Print( - "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw e.setUnfinishedMessage(this);\n" - "} catch (java.io.IOException e) {\n" - " throw new com.google.protobuf.InvalidProtocolBufferException(\n" - " e).setUnfinishedMessage(this);\n" - "} finally {\n"); - printer->Indent(); - - // Make repeated field list immutable. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - field_generators_.get(field).GenerateParsingDoneCode(printer); - } - - // Make unknown fields immutable. - printer->Print("this.unknownFields = unknownFields.build();\n"); - - // Make extensions immutable. - printer->Print("makeExtensionsImmutable();\n"); - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // finally - "}\n"); -} - // =================================================================== void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { printer->Print( "$visibility$ static final com.google.protobuf.Parser<$classname$>\n" - " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n", - "visibility", - ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public" - : "private", - "classname", descriptor_->name()); - printer->Indent(); - printer->Print( - "@java.lang.Override\n" - "public $classname$ parsePartialFrom(\n" - " com.google.protobuf.CodedInputStream input,\n" - " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n", - "classname", descriptor_->name()); - if (context_->HasGeneratedMethods(descriptor_)) { - printer->Print(" return new $classname$(input, extensionRegistry);\n", - "classname", descriptor_->name()); - } else { - // When parsing constructor isn't generated, use builder to parse - // messages. Note, will fallback to use reflection based mergeFieldFrom() - // in AbstractMessage.Builder. - printer->Indent(); - printer->Print( - "Builder builder = newBuilder();\n" - "try {\n" - " builder.mergeFrom(input, extensionRegistry);\n" - "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw e.setUnfinishedMessage(builder.buildPartial());\n" - "} catch (java.io.IOException e) {\n" - " throw new com.google.protobuf.InvalidProtocolBufferException(\n" - " e.getMessage()).setUnfinishedMessage(\n" - " builder.buildPartial());\n" - "}\n" - "return builder.buildPartial();\n"); - printer->Outdent(); - } - printer->Print("}\n"); - printer->Outdent(); - printer->Print( + " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n" + " @java.lang.Override\n" + " public $classname$ parsePartialFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " Builder builder = newBuilder();\n" + " try {\n" + " builder.mergeFrom(input, extensionRegistry);\n" + " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " throw e.setUnfinishedMessage(builder.buildPartial());\n" + " } catch (com.google.protobuf.UninitializedMessageException e) {\n" + " throw " + "e.asInvalidProtocolBufferException().setUnfinishedMessage(builder." + "buildPartial());\n" + " } catch (java.io.IOException e) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(e)\n" + " .setUnfinishedMessage(builder.buildPartial());\n" + " }\n" + " return builder.buildPartial();\n" + " }\n" "};\n" - "\n"); - - printer->Print( + "\n" "public static com.google.protobuf.Parser<$classname$> parser() {\n" " return PARSER;\n" "}\n" @@ -1353,6 +1203,9 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " return PARSER;\n" "}\n" "\n", + "visibility", + ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public" + : "private", "classname", descriptor_->name()); } @@ -1455,7 +1308,7 @@ void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const { void ImmutableMessageGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ " @@ -1486,7 +1339,7 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -1495,6 +1348,24 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "public val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageGenerator::GenerateKotlinExtensions( @@ -1504,7 +1375,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun get(extension: " + "public operator fun get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -1520,7 +1391,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun get(\n" + "public operator fun get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List>\n" "): com.google.protobuf.kotlin.ExtensionList {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -1549,7 +1420,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun setExtension(extension: " + "internal fun setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -1582,7 +1453,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun set(\n" + "inline operator fun set(\n" " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" " value: T\n" ") {\n" @@ -1592,7 +1463,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -1601,7 +1472,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign" "(value: E) {\n" @@ -1611,7 +1482,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.addAll(values: Iterable) {\n" " for (value in values) {\n" " add(value)\n" @@ -1622,7 +1493,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign(values: " "Iterable) {\n" @@ -1632,7 +1503,8 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun com.google.protobuf.kotlin.ExtensionList " + "com.google.protobuf.kotlin.ExtensionList.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" @@ -1727,3 +1599,5 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h b/third_party/protobuf/src/google/protobuf/compiler/java/message.h similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message.h index cafc91e6..2dbd0dd9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { @@ -100,7 +101,7 @@ class MessageGenerator { class ImmutableMessageGenerator : public MessageGenerator { public: ImmutableMessageGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageGenerator(); + ~ImmutableMessageGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -136,6 +137,7 @@ class ImmutableMessageGenerator : public MessageGenerator { void GenerateParsingConstructor(io::Printer* printer); void GenerateMutableCopy(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; void GenerateAnyMethods(io::Printer* printer); Context* context_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder.cc similarity index 69% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message_builder.cc index 320852b1..32ad668d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder.cc @@ -32,36 +32,43 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include "google/protobuf/compiler/java/message_builder.h" #include #include #include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" +#include "google/protobuf/stubs/strutil.h" +#include "google/protobuf/stubs/substitute.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/enum.h" +#include "google/protobuf/compiler/java/extension.h" +#include "google/protobuf/compiler/java/generator_factory.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" +#include "google/protobuf/descriptor.pb.h" + +// Must be last. +#include "google/protobuf/port_def.inc" namespace google { namespace protobuf { namespace compiler { namespace java { +using internal::WireFormat; +using internal::WireFormatLite; + namespace { std::string MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } @@ -139,12 +146,11 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) { "\n" "public Builder clear$oneof_capitalized_name$() {\n" " $oneof_name$Case_ = 0;\n" - " $oneof_name$_ = null;\n"); - printer->Print(" onChanged();\n"); - printer->Print( - " return this;\n" - "}\n" - "\n"); + " $oneof_name$_ = null;\n" + " onChanged();\n" + " return this;\n" + "}\n" + "\n"); } // Integers for bit fields. @@ -285,43 +291,63 @@ void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) { void MessageBuilderGenerator::GenerateCommonBuilderMethods( io::Printer* printer) { + // Decide if we really need to have the "maybeForceBuilderInitialization()" + // method. + // TODO(b/249158148): Remove the need for this entirely + bool need_maybe_force_builder_init = false; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (descriptor_->field(i)->message_type() != nullptr && + !IsRealOneof(descriptor_->field(i)) && + HasHasbit(descriptor_->field(i))) { + need_maybe_force_builder_init = true; + break; + } + } + + const char* force_builder_init = need_maybe_force_builder_init + ? " maybeForceBuilderInitialization();" + : ""; + printer->Print( "// Construct using $classname$.newBuilder()\n" "private Builder() {\n" - " maybeForceBuilderInitialization();\n" + "$force_builder_init$\n" "}\n" "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "force_builder_init", force_builder_init); printer->Print( "private Builder(\n" " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n" " super(parent);\n" - " maybeForceBuilderInitialization();\n" + "$force_builder_init$\n" "}\n", "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver", - GeneratedCodeVersionSuffix()); + GeneratedCodeVersionSuffix(), "force_builder_init", force_builder_init); - printer->Print( - "private void maybeForceBuilderInitialization() {\n" - " if (com.google.protobuf.GeneratedMessage$ver$\n" - " .alwaysUseFieldBuilders) {\n", - "ver", GeneratedCodeVersionSuffix()); + if (need_maybe_force_builder_init) { + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + " if (com.google.protobuf.GeneratedMessage$ver$\n" + " .alwaysUseFieldBuilders) {\n", + "ver", GeneratedCodeVersionSuffix()); - printer->Indent(); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); i++) { - if (!IsRealOneof(descriptor_->field(i))) { - field_generators_.get(descriptor_->field(i)) - .GenerateFieldBuilderInitializationCode(printer); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateFieldBuilderInitializationCode(printer); + } } - } - printer->Outdent(); - printer->Outdent(); + printer->Outdent(); + printer->Outdent(); - printer->Print( - " }\n" - "}\n"); + printer->Print( + " }\n" + "}\n"); + } printer->Print( "@java.lang.Override\n" @@ -329,12 +355,15 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( " super.clear();\n"); printer->Indent(); + int totalBuilderInts = (descriptor_->field_count() + 31) / 32; + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("$bit_field_name$ = 0;\n", "bit_field_name", + GetBitFieldName(i)); + } for (int i = 0; i < descriptor_->field_count(); i++) { - if (!IsRealOneof(descriptor_->field(i))) { - field_generators_.get(descriptor_->field(i)) - .GenerateBuilderClearCode(printer); - } + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderClearCode(printer); } for (auto oneof : oneofs_) { @@ -382,63 +411,7 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); - printer->Print( - "@java.lang.Override\n" - "public $classname$ buildPartial() {\n" - " $classname$ result = new $classname$(this);\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - - printer->Indent(); - - int totalBuilderBits = 0; - int totalMessageBits = 0; - for (int i = 0; i < descriptor_->field_count(); i++) { - const ImmutableFieldGenerator& field = - field_generators_.get(descriptor_->field(i)); - totalBuilderBits += field.GetNumBitsForBuilder(); - totalMessageBits += field.GetNumBitsForMessage(); - } - int totalBuilderInts = (totalBuilderBits + 31) / 32; - int totalMessageInts = (totalMessageBits + 31) / 32; - - // Local vars for from and to bit fields to avoid accessing the builder and - // message over and over for these fields. Seems to provide a slight - // perforamance improvement in micro benchmark and this is also what proto1 - // code does. - for (int i = 0; i < totalBuilderInts; i++) { - printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n", - "bit_field_name", GetBitFieldName(i)); - } - for (int i = 0; i < totalMessageInts; i++) { - printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name", - GetBitFieldName(i)); - } - - // Output generation code for each field. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); - } - - // Copy the bit field results to the generated message - for (int i = 0; i < totalMessageInts; i++) { - printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n", - "bit_field_name", GetBitFieldName(i)); - } - - for (auto oneof : oneofs_) { - printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n", - "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); - } - - printer->Outdent(); - - printer->Print(" onBuilt();\n"); - - printer->Print( - " return result;\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + GenerateBuildPartial(printer); // Override methods declared in GeneratedMessage to return the concrete // generated type so callsites won't depend on GeneratedMessage. This @@ -575,7 +548,7 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( printer->Print(" this.mergeExtensionFields(other);\n"); } - printer->Print(" this.mergeUnknownFields(other.unknownFields);\n"); + printer->Print(" this.mergeUnknownFields(other.getUnknownFields());\n"); printer->Print(" onChanged();\n"); @@ -586,6 +559,156 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( } } +void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public $classname$ buildPartial() {\n" + " $classname$ result = new $classname$(this);\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Indent(); + + // Handle the repeated fields first so that the "mutable bits" are cleared. + bool has_repeated_fields = false; + for (int i = 0; i < descriptor_->field_count(); ++i) { + if (descriptor_->field(i)->is_repeated() && + !IsMapField(descriptor_->field(i))) { + has_repeated_fields = true; + printer->Print("buildPartialRepeatedFields(result);\n"); + break; + } + } + + // One buildPartial#() per from_bit_field + int totalBuilderInts = (descriptor_->field_count() + 31) / 32; + if (totalBuilderInts > 0) { + for (int i = 0; i < totalBuilderInts; ++i) { + printer->Print( + "if ($bit_field_name$ != 0) { buildPartial$piece$(result); }\n", + "bit_field_name", GetBitFieldName(i), "piece", StrCat(i)); + } + } + + if (!oneofs_.empty()) { + printer->Print("buildPartialOneofs(result);\n"); + } + + printer->Outdent(); + printer->Print( + " onBuilt();\n" + " return result;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // Build Repeated Fields + if (has_repeated_fields) { + printer->Print( + "private void buildPartialRepeatedFields($classname$ result) {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); ++i) { + if (descriptor_->field(i)->is_repeated() && + !IsMapField(descriptor_->field(i))) { + const ImmutableFieldGenerator& field = + field_generators_.get(descriptor_->field(i)); + field.GenerateBuildingCode(printer); + } + } + printer->Outdent(); + printer->Print("}\n\n"); + } + + // Build non-oneof fields + int start_field = 0; + for (int i = 0; i < totalBuilderInts; i++) { + start_field = GenerateBuildPartialPiece(printer, i, start_field); + } + + // Build Oneofs + if (!oneofs_.empty()) { + printer->Print("private void buildPartialOneofs($classname$ result) {\n", + "classname", + name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); + for (auto oneof : oneofs_) { + printer->Print( + "result.$oneof_name$Case_ = $oneof_name$Case_;\n" + "result.$oneof_name$_ = this.$oneof_name$_;\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); + for (int i = 0; i < oneof->field_count(); ++i) { + if (oneof->field(i)->message_type() != nullptr) { + const ImmutableFieldGenerator& field = + field_generators_.get(oneof->field(i)); + field.GenerateBuildingCode(printer); + } + } + } + printer->Outdent(); + printer->Print("}\n\n"); + } +} + +int MessageBuilderGenerator::GenerateBuildPartialPiece(io::Printer* printer, + int piece, + int first_field) { + printer->Print( + "private void buildPartial$piece$($classname$ result) {\n" + " int from_$bit_field_name$ = $bit_field_name$;\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), "piece", + StrCat(piece), "bit_field_name", GetBitFieldName(piece)); + printer->Indent(); + std::set declared_to_bitfields; + + int bit = 0; + int next = first_field; + for (; bit < 32 && next < descriptor_->field_count(); ++next) { + const ImmutableFieldGenerator& field = + field_generators_.get(descriptor_->field(next)); + bit += field.GetNumBitsForBuilder(); + + // Skip oneof fields that are handled separately + if (IsRealOneof(descriptor_->field(next))) { + continue; + } + + // Skip repeated fields because they are currently handled + // in separate buildPartial sub-methods. + if (descriptor_->field(next)->is_repeated() && + !IsMapField(descriptor_->field(next))) { + continue; + } + // Skip fields without presence bits in the builder + if (field.GetNumBitsForBuilder() == 0) { + continue; + } + + // Track message bits if necessary + if (field.GetNumBitsForMessage() > 0) { + int to_bitfield = field.GetMessageBitIndex() / 32; + if (declared_to_bitfields.count(to_bitfield) == 0) { + printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name", + GetBitFieldName(to_bitfield)); + declared_to_bitfields.insert(to_bitfield); + } + } + + // Copy the field from the builder to the message + field.GenerateBuildingCode(printer); + } + + // Copy the bit field results to the generated message + for (int to_bitfield : declared_to_bitfields) { + printer->Print("result.$bit_field_name$ |= to_$bit_field_name$;\n", + "bit_field_name", GetBitFieldName(to_bitfield)); + } + + printer->Outdent(); + printer->Print("}\n\n"); + + return next; +} + // =================================================================== void MessageBuilderGenerator::GenerateBuilderParsingMethods( @@ -596,20 +719,92 @@ void MessageBuilderGenerator::GenerateBuilderParsingMethods( " com.google.protobuf.CodedInputStream input,\n" " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" " throws java.io.IOException {\n" - " $classname$ parsedMessage = null;\n" + " if (extensionRegistry == null) {\n" + " throw new java.lang.NullPointerException();\n" + " }\n" " try {\n" - " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n" + " boolean done = false;\n" + " while (!done) {\n" + " int tag = input.readTag();\n" + " switch (tag) {\n" + " case 0:\n" // zero signals EOF / limit reached + " done = true;\n" + " break;\n"); + printer->Indent(); // method + printer->Indent(); // try + printer->Indent(); // while + printer->Indent(); // switch + GenerateBuilderFieldParsingCases(printer); + printer->Outdent(); // switch + printer->Outdent(); // while + printer->Outdent(); // try + printer->Outdent(); // method + printer->Print( + " default: {\n" + " if (!super.parseUnknownField(input, extensionRegistry, tag)) " + "{\n" + " done = true; // was an endgroup tag\n" + " }\n" + " break;\n" + " } // default:\n" + " } // switch (tag)\n" + " } // while (!done)\n" " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " parsedMessage = ($classname$) e.getUnfinishedMessage();\n" " throw e.unwrapIOException();\n" " } finally {\n" - " if (parsedMessage != null) {\n" - " mergeFrom(parsedMessage);\n" - " }\n" - " }\n" + " onChanged();\n" + " } // finally\n" " return this;\n" - "}\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "}\n"); +} + +void MessageBuilderGenerator::GenerateBuilderFieldParsingCases( + io::Printer* printer) { + std::unique_ptr sorted_fields( + SortFieldsByNumber(descriptor_)); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + GenerateBuilderFieldParsingCase(printer, field); + if (field->is_packable()) { + GenerateBuilderPackedFieldParsingCase(printer, field); + } + } +} + +void MessageBuilderGenerator::GenerateBuilderFieldParsingCase( + io::Printer* printer, const FieldDescriptor* field) { + uint32_t tag = WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + std::string tagString = StrCat(static_cast(tag)); + printer->Print("case $tag$: {\n", "tag", tagString); + printer->Indent(); + + field_generators_.get(field).GenerateBuilderParsingCode(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "} // case $tag$\n", + "tag", tagString); +} + +void MessageBuilderGenerator::GenerateBuilderPackedFieldParsingCase( + io::Printer* printer, const FieldDescriptor* field) { + // To make packed = true wire compatible, we generate parsing code from a + // packed version of this field regardless of field->options().packed(). + uint32_t tag = WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + std::string tagString = StrCat(static_cast(tag)); + printer->Print("case $tag$: {\n", "tag", tagString); + printer->Indent(); + + field_generators_.get(field).GenerateBuilderParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "} // case $tag$\n", + "tag", tagString); } // =================================================================== @@ -710,3 +905,5 @@ void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) { } // namespace compiler } // namespace protobuf } // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.h b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder.h similarity index 82% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message_builder.h index fcd73b34..4b1cc7e9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { @@ -68,8 +69,18 @@ class MessageBuilderGenerator { private: void GenerateCommonBuilderMethods(io::Printer* printer); + void GenerateBuildPartial(io::Printer* printer); + int GenerateBuildPartialPiece(io::Printer* printer, int piece, + int first_field); + int GenerateBuildPartialPieceWithoutPresence(io::Printer* printer, int piece, + int first_field); void GenerateDescriptorMethods(io::Printer* printer); void GenerateBuilderParsingMethods(io::Printer* printer); + void GenerateBuilderFieldParsingCases(io::Printer* printer); + void GenerateBuilderFieldParsingCase(io::Printer* printer, + const FieldDescriptor* field); + void GenerateBuilderPackedFieldParsingCase(io::Printer* printer, + const FieldDescriptor* field); void GenerateIsInitialized(io::Printer* printer); const Descriptor* descriptor_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.cc similarity index 90% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.cc index 7b69a9ab..526f949b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.cc @@ -32,26 +32,29 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -149,3 +152,5 @@ void MessageBuilderLiteGenerator::GenerateCommonBuilderMethods( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.h index 3402adf3..0d895fcf 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_builder_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_builder_lite.h @@ -37,7 +37,8 @@ #include #include -#include + +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message_field.cc similarity index 83% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message_field.cc index 8aae9614..5093be4b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_field.cc @@ -32,17 +32,21 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include "google/protobuf/compiler/java/message_field.h" + #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" +#include "google/protobuf/stubs/strutil.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" + +// Must be last. +#include "google/protobuf/port_def.inc" namespace google { namespace protobuf { @@ -52,10 +56,11 @@ namespace java { namespace { -void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables) { +void SetMessageVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + std::map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["type"] = @@ -70,11 +75,12 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; (*variables)["ver"] = GeneratedCodeVersionSuffix(); (*variables)["get_parser"] = @@ -84,24 +90,16 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); // Note that these have a trailing ";". - (*variables)["set_has_field_bit_message"] = - GenerateSetBit(messageBitIndex) + ";"; - (*variables)["set_has_field_bit_builder"] = - GenerateSetBit(builderBitIndex) + ";"; - (*variables)["clear_has_field_bit_builder"] = - GenerateClearBit(builderBitIndex) + ";"; + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { - (*variables)["set_has_field_bit_message"] = ""; - (*variables)["set_has_field_bit_builder"] = ""; - (*variables)["clear_has_field_bit_builder"] = ""; - - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != null"; + (*variables)["set_has_field_bit_to_local"] = ""; + variables->insert({"is_field_present_message", + StrCat((*variables)["name"], "_ != null")}); } // For repeated builders, one bit is used for whether the array is immutable. @@ -109,17 +107,13 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); - // For repeated fields, one bit is used for whether the array is immutable - // in the parsing constructor. - (*variables)["get_mutable_bit_parser"] = - GenerateGetBitMutableLocal(builderBitIndex); - (*variables)["set_mutable_bit_parser"] = - GenerateSetBitMutableLocal(builderBitIndex); - + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); - (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); } } // namespace @@ -129,21 +123,31 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + : descriptor_(descriptor), + message_bit_index_(messageBitIndex), + builder_bit_index_(builderBitIndex), + name_resolver_(context->GetNameResolver()), + context_(context) { SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); + name_resolver_, &variables_, context); } ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {} +int ImmutableMessageFieldGenerator::GetMessageBitIndex() const { + return message_bit_index_; +} + +int ImmutableMessageFieldGenerator::GetBuilderBitIndex() const { + return builder_bit_index_; +} + int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const { return HasHasbit(descriptor_) ? 1 : 0; } -int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { - return GetNumBitsForMessage(); -} +int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; } void ImmutableMessageFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { @@ -176,24 +180,6 @@ void ImmutableMessageFieldGenerator::GenerateMembers( " return $get_has_field_bit_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, GETTER); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" - " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - - WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public $type$OrBuilder " - "${$get$capitalized_name$OrBuilder$}$() {\n" - " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); } else { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( @@ -203,24 +189,25 @@ void ImmutableMessageFieldGenerator::GenerateMembers( " return $name$_ != null;\n" "}\n"); printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, GETTER); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" - " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public $type$OrBuilder " - "${$get$capitalized_name$OrBuilder$}$() {\n" - " return get$capitalized_name$();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition( @@ -258,9 +245,6 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( // When using nested-builders, the code initially works just like the // non-nested builder case. It only creates a nested builder lazily on // demand and then forever delegates to it after creation. - - bool has_hasbit = HasHasbit(descriptor_); - printer->Print(variables_, "private $type$ $name$_;\n"); printer->Print(variables_, @@ -275,21 +259,11 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( // boolean hasField() WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); - if (has_hasbit) { - printer->Print( - variables_, - "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } else { - printer->Print( - variables_, - "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $name$Builder_ != null || $name$_ != null;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldAccessorDocComment(printer, descriptor_, GETTER); @@ -307,12 +281,12 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( "if (value == null) {\n" " throw new NullPointerException();\n" "}\n" - "$name$_ = value;\n" - "$on_changed$\n", + "$name$_ = value;\n", "$name$Builder_.setMessage(value);\n", "$set_has_field_bit_builder$\n" + "$on_changed$\n" "return this;\n"); // Field.Builder setField(Field.Builder builderForValue) @@ -322,58 +296,48 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", - "$name$_ = builderForValue.build();\n" - "$on_changed$\n", + "$name$_ = builderForValue.build();\n", "$name$Builder_.setMessage(builderForValue.build());\n", "$set_has_field_bit_builder$\n" + "$on_changed$\n" "return this;\n"); - // Field.Builder mergeField(Field value) + // Message.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction( printer, "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", - - has_hasbit - ? "if ($get_has_field_bit_builder$ &&\n" - " $name$_ != null &&\n" - " $name$_ != $type$.getDefaultInstance()) {\n" - " $name$_ =\n" - " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" - "} else {\n" - " $name$_ = value;\n" - "}\n" - "$on_changed$\n" - : "if ($name$_ != null) {\n" - " $name$_ =\n" - " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" - "} else {\n" - " $name$_ = value;\n" - "}\n" - "$on_changed$\n", + "if ($get_has_field_bit_builder$ &&\n" + " $name$_ != null &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " get$capitalized_name$Builder().mergeFrom(value);\n" + "} else {\n" + " $name$_ = value;\n" + "}\n", "$name$Builder_.mergeFrom(value);\n", "$set_has_field_bit_builder$\n" + "$on_changed$\n" "return this;\n"); - // Field.Builder clearField() + // Message.Builder clearField() WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction( - printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", - - "$name$_ = null;\n" - "$on_changed$\n", - - has_hasbit ? "$name$Builder_.clear();\n" - : "$name$_ = null;\n" - "$name$Builder_ = null;\n", - - "$clear_has_field_bit_builder$\n" - "return this;\n"); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$\n" + " $name$_ = null;\n" + " if ($name$Builder_ != null) {\n" + " $name$Builder_.dispose();\n" + " $name$Builder_ = null;\n" + " }\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + // Field.Builder getFieldBuilder() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$.Builder " @@ -383,6 +347,8 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // FieldOrBuilder getFieldOrBuilder() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " @@ -395,6 +361,8 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // SingleFieldBuilder getFieldFieldBuilder WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -438,13 +406,21 @@ void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { - if (HasHasbit(descriptor_)) { - printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); - } + printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); } void ImmutableMessageFieldGenerator::GenerateInitializationCode( @@ -452,17 +428,13 @@ void ImmutableMessageFieldGenerator::GenerateInitializationCode( void ImmutableMessageFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - if (HasHasbit(descriptor_)) { - PrintNestedBuilderCondition(printer, "$name$_ = null;\n", - - "$name$Builder_.clear();\n"); - printer->Print(variables_, "$clear_has_field_bit_builder$\n"); - } else { - PrintNestedBuilderCondition(printer, "$name$_ = null;\n", - - "$name$_ = null;\n" - "$name$Builder_ = null;\n"); - } + // No need to clear the has-bit since we clear the bitField ints all at once. + printer->Print(variables_, + "$name$_ = null;\n" + "if ($name$Builder_ != null) {\n" + " $name$Builder_.dispose();\n" + " $name$Builder_ = null;\n" + "}\n"); } void ImmutableMessageFieldGenerator::GenerateMergingCode( @@ -475,50 +447,32 @@ void ImmutableMessageFieldGenerator::GenerateMergingCode( void ImmutableMessageFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (HasHasbit(descriptor_)) { - printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n"); - printer->Indent(); - PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", - "result.$name$_ = $name$Builder_.build();\n"); - printer->Outdent(); - printer->Print(variables_, - " $set_has_field_bit_to_local$;\n" - "}\n"); - } else { - PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", - "result.$name$_ = $name$Builder_.build();\n"); + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$Builder_ == null\n" + " ? $name$_\n" + " : $name$Builder_.build();\n"); + if (GetNumBitsForMessage() > 0) { + printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } + printer->Print("}\n"); } -void ImmutableMessageFieldGenerator::GenerateParsingCode( +void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = null;\n" - "if ($is_field_present_message$) {\n" - " subBuilder = $name$_.toBuilder();\n" - "}\n"); - if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { printer->Print(variables_, - "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n" - " extensionRegistry);\n"); + "input.readGroup($number$,\n" + " get$capitalized_name$FieldBuilder().getBuilder(),\n" + " extensionRegistry);\n" + "$set_has_field_bit_builder$\n"); } else { printer->Print(variables_, - "$name$_ = input.readMessage($type$.$get_parser$, " - "extensionRegistry);\n"); + "input.readMessage(\n" + " get$capitalized_name$FieldBuilder().getBuilder(),\n" + " extensionRegistry);\n" + "$set_has_field_bit_builder$\n"); } - - printer->Print(variables_, - "if (subBuilder != null) {\n" - " subBuilder.mergeFrom($name$_);\n" - " $name$_ = subBuilder.buildPartial();\n" - "}\n" - "$set_has_field_bit_message$\n"); -} - -void ImmutableMessageFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - // noop for messages. } void ImmutableMessageFieldGenerator::GenerateSerializationCode( @@ -582,6 +536,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, "@java.lang.Override\n" @@ -698,8 +653,9 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "if ($has_oneof_case_message$) {\n" " $name$Builder_.mergeFrom(value);\n" - "}\n" - "$name$Builder_.setMessage(value);\n", + "} else {\n" + " $name$Builder_.setMessage(value);\n" + "}\n", "$set_oneof_case_message$;\n" "return this;\n"); @@ -764,24 +720,28 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( " $oneof_name$_ = null;\n" " }\n" " $set_oneof_case_message$;\n" - " $on_changed$;\n" + " $on_changed$\n" " return $name$Builder_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + // Make sure the builder gets cleared. + printer->Print(variables_, + "if ($name$Builder_ != null) {\n" + " $name$Builder_.clear();\n" + "}\n"); +} + void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - printer->Print(variables_, "if ($has_oneof_case_message$) {\n"); - printer->Indent(); - - PrintNestedBuilderCondition( - printer, "result.$oneof_name$_ = $oneof_name$_;\n", - - "result.$oneof_name$_ = $name$Builder_.build();\n"); - - printer->Outdent(); - printer->Print("}\n"); + printer->Print(variables_, + "if ($has_oneof_case_message$ &&\n" + " $name$Builder_ != null) {\n" + " result.$oneof_name$_ = $name$Builder_.build();\n" + "}\n"); } void ImmutableMessageOneofFieldGenerator::GenerateMergingCode( @@ -790,32 +750,21 @@ void ImmutableMessageOneofFieldGenerator::GenerateMergingCode( "merge$capitalized_name$(other.get$capitalized_name$());\n"); } -void ImmutableMessageOneofFieldGenerator::GenerateParsingCode( +void ImmutableMessageOneofFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = null;\n" - "if ($has_oneof_case_message$) {\n" - " subBuilder = (($type$) $oneof_name$_).toBuilder();\n" - "}\n"); - if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { - printer->Print( - variables_, - "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n" - " extensionRegistry);\n"); + printer->Print(variables_, + "input.readGroup($number$,\n" + " get$capitalized_name$FieldBuilder().getBuilder(),\n" + " extensionRegistry);\n" + "$set_oneof_case_message$;\n"); } else { - printer->Print( - variables_, - "$oneof_name$_ =\n" - " input.readMessage($type$.$get_parser$, extensionRegistry);\n"); + printer->Print(variables_, + "input.readMessage(\n" + " get$capitalized_name$FieldBuilder().getBuilder(),\n" + " extensionRegistry);\n" + "$set_oneof_case_message$;\n"); } - - printer->Print(variables_, - "if (subBuilder != null) {\n" - " subBuilder.mergeFrom(($type$) $oneof_name$_);\n" - " $oneof_name$_ = subBuilder.buildPartial();\n" - "}\n"); - printer->Print(variables_, "$set_oneof_case_message$;\n"); } void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode( @@ -842,11 +791,8 @@ void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode( RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { - SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, - context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); -} + : ImmutableMessageFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) {} RepeatedImmutableMessageFieldGenerator:: ~RepeatedImmutableMessageFieldGenerator() {} @@ -889,7 +835,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers( void RepeatedImmutableMessageFieldGenerator::GenerateMembers( io::Printer* printer) const { - printer->Print(variables_, "private java.util.List<$type$> $name$_;\n"); + printer->Print(variables_, "@SuppressWarnings(\"serial\")\n" + "private java.util.List<$type$> $name$_;\n"); PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -899,6 +846,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_;\n" // note: unmodifiable list "}\n"); printer->Annotate("{", "}", descriptor_); + + // List getFieldOrBuilderList() WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -908,6 +857,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // int getFieldCount() WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -916,6 +867,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // Field getField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -924,6 +877,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_.get(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // FieldOrBuilder getFieldOrBuilder(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "@java.lang.Override\n" @@ -1149,7 +1104,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "return this;\n"); - // Builder clearAllRepeatedField() + // Builder clearRepeatedField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction( printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", @@ -1176,6 +1131,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "return this;\n"); + // Field.Builder getRepeatedFieldBuilder(int index) WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -1185,6 +1141,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "}\n"); printer->Annotate("{", "}", descriptor_); + // FieldOrBuilder getRepeatedFieldOrBuilder(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " @@ -1198,6 +1155,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "}\n"); printer->Annotate("{", "}", descriptor_); + // List getRepeatedFieldOrBuilderList() WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -1211,6 +1169,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "}\n"); printer->Annotate("{", "}", descriptor_); + // Field.Builder addRepeatedField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$.Builder " @@ -1219,6 +1178,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " $type$.getDefaultInstance());\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // Field.Builder addRepeatedFieldBuilder(int index) WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -1228,6 +1189,8 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " index, $type$.getDefaultInstance());\n" "}\n"); printer->Annotate("{", "}", descriptor_); + + // List getRepeatedFieldBuilderList() WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -1266,10 +1229,12 @@ void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode( void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { PrintNestedBuilderCondition(printer, - "$name$_ = java.util.Collections.emptyList();\n" - "$clear_mutable_bit_builder$;\n", + "$name$_ = java.util.Collections.emptyList();\n", + "$name$_ = null;\n" "$name$Builder_.clear();\n"); + + printer->Print(variables_, "$clear_mutable_bit_builder$;\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode( @@ -1324,34 +1289,25 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode( "result.$name$_ = $name$Builder_.build();\n"); } -void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode( +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { - printer->Print(variables_, - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = new java.util.ArrayList<$type$>();\n" - " $set_mutable_bit_parser$;\n" - "}\n"); - if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { - printer->Print( - variables_, - "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n" - " extensionRegistry));\n"); + printer->Print(variables_, + "$type$ m =\n" + " input.readGroup($number$,\n" + " $type$.$get_parser$,\n" + " extensionRegistry);\n"); } else { - printer->Print( - variables_, - "$name$_.add(\n" - " input.readMessage($type$.$get_parser$, extensionRegistry));\n"); + printer->Print(variables_, + "$type$ m =\n" + " input.readMessage(\n" + " $type$.$get_parser$,\n" + " extensionRegistry);\n"); } -} - -void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - printer->Print( - variables_, - "if ($get_mutable_bit_parser$) {\n" - " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" - "}\n"); + PrintNestedBuilderCondition(printer, + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(m);\n", + "$name$Builder_.addMessage(m);\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode( @@ -1426,7 +1382,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -1438,7 +1394,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1449,7 +1405,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1462,7 +1418,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -1474,7 +1430,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -1485,10 +1441,12 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n\n"); } } // namespace java } // namespace compiler } // namespace protobuf } // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/message_field.h similarity index 76% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message_field.h index 8588100b..f16062f0 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include "google/protobuf/compiler/java/field.h" namespace google { namespace protobuf { @@ -61,10 +62,16 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageFieldGenerator(); + ImmutableMessageFieldGenerator(const ImmutableMessageFieldGenerator&) = + delete; + ImmutableMessageFieldGenerator& operator=( + const ImmutableMessageFieldGenerator&) = delete; + ~ImmutableMessageFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- + int GetMessageBitIndex() const override; + int GetBuilderBitIndex() const override; int GetNumBitsForMessage() const override; int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; @@ -74,8 +81,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -88,20 +94,23 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; + int message_bit_index_; + int builder_bit_index_; std::map variables_; ClassNameResolver* name_resolver_; + Context* context_; - void PrintNestedBuilderCondition(io::Printer* printer, - const char* regular_case, - const char* nested_builder_case) const; - void PrintNestedBuilderFunction(io::Printer* printer, - const char* method_prototype, - const char* regular_case, - const char* nested_builder_case, - const char* trailing_code) const; + virtual void PrintNestedBuilderCondition( + io::Printer* printer, const char* regular_case, + const char* nested_builder_case) const; + virtual void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldGenerator @@ -110,25 +119,32 @@ class ImmutableMessageOneofFieldGenerator ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageOneofFieldGenerator(); + ImmutableMessageOneofFieldGenerator( + const ImmutableMessageOneofFieldGenerator&) = delete; + ImmutableMessageOneofFieldGenerator& operator=( + const ImmutableMessageOneofFieldGenerator&) = delete; + ~ImmutableMessageOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator); }; -class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator { +class RepeatedImmutableMessageFieldGenerator + : public ImmutableMessageFieldGenerator { public: explicit RepeatedImmutableMessageFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); + RepeatedImmutableMessageFieldGenerator( + const RepeatedImmutableMessageFieldGenerator&) = delete; + RepeatedImmutableMessageFieldGenerator& operator=( + const RepeatedImmutableMessageFieldGenerator&) = delete; ~RepeatedImmutableMessageFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- @@ -141,8 +157,7 @@ class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -154,21 +169,14 @@ class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; protected: - const FieldDescriptor* descriptor_; - std::map variables_; - ClassNameResolver* name_resolver_; - - void PrintNestedBuilderCondition(io::Printer* printer, - const char* regular_case, - const char* nested_builder_case) const; + void PrintNestedBuilderCondition( + io::Printer* printer, const char* regular_case, + const char* nested_builder_case) const override; void PrintNestedBuilderFunction(io::Printer* printer, const char* method_prototype, const char* regular_case, const char* nested_builder_case, - const char* trailing_code) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator); + const char* trailing_code) const override; }; } // namespace java diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.cc index 1c4d016d..da96790e 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.cc @@ -32,19 +32,22 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include #include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -308,6 +311,15 @@ void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( @@ -816,7 +828,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -828,7 +840,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -839,7 +851,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -852,7 +864,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -864,7 +876,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -875,10 +887,12 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n"); } } // namespace java } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.h similarity index 96% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.h index 8f81f60d..4253acc8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_field_lite.h @@ -39,7 +39,7 @@ #include #include -#include +#include namespace google { namespace protobuf { @@ -62,7 +62,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageFieldLiteGenerator(); + ~ImmutableMessageFieldLiteGenerator() override; // implements ImmutableFieldLiteGenerator // ------------------------------------ @@ -85,6 +85,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldLiteGenerator @@ -93,7 +94,7 @@ class ImmutableMessageOneofFieldLiteGenerator ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageOneofFieldLiteGenerator(); + ~ImmutableMessageOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/message_lite.cc similarity index 94% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/message_lite.cc index c2c27889..9a85734a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_lite.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,21 +40,24 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -779,7 +782,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinDsl( void ImmutableMessageLiteGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ =\n" @@ -808,7 +811,7 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -817,6 +820,26 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + // Generate getFieldOrNull getters for all optional message fields. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "public val $full_classname$OrBuilder.$camelcase_name$OrNull: " + "$full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( @@ -826,7 +849,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun get(extension: " + "public operator fun get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -842,7 +865,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun get(\n" + "public operator fun get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List>\n" "): com.google.protobuf.kotlin.ExtensionList {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -871,7 +894,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun setExtension(extension: " + "internal fun setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -914,7 +937,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -923,7 +946,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign" "(value: E) {\n" @@ -933,7 +956,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun com.google.protobuf.kotlin.ExtensionList com.google.protobuf.kotlin.ExtensionList.addAll(values: Iterable) {\n" " for (value in values) {\n" " add(value)\n" @@ -944,7 +967,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun " + "public inline operator fun " "com.google.protobuf.kotlin.ExtensionList.plusAssign(values: " "Iterable) {\n" @@ -954,7 +977,8 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun com.google.protobuf.kotlin.ExtensionList " + "com.google.protobuf.kotlin.ExtensionList.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" @@ -975,3 +999,5 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/message_lite.h similarity index 94% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/message_lite.h index adb0df7c..d1e4b689 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/message_lite.h @@ -35,10 +35,8 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__ #define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__ -#include -#include -#include -#include +#include +#include namespace google { namespace protobuf { @@ -48,7 +46,7 @@ namespace java { class ImmutableMessageLiteGenerator : public MessageGenerator { public: ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageLiteGenerator(); + ~ImmutableMessageLiteGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -70,6 +68,7 @@ class ImmutableMessageLiteGenerator : public MessageGenerator { void GenerateConstructor(io::Printer* printer); void GenerateDynamicMethodNewBuildMessageInfo(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; Context* context_; ClassNameResolver* name_resolver_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc b/third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.cc similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.cc index 39bf3e27..06a637e3 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.cc @@ -28,15 +28,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include #include #include -#include -#include #include #include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -378,3 +381,5 @@ std::string ClassNameResolver::GetDowngradedClassName( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h b/third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h rename to third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.h index a688d49a..103cace4 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/name_resolver.h @@ -36,6 +36,9 @@ #include +// Must be last. +#include + namespace google { namespace protobuf { class Descriptor; @@ -123,7 +126,6 @@ class ClassNameResolver { std::string GetDowngradedFileClassName(const FileDescriptor* file); std::string GetDowngradedClassName(const Descriptor* descriptor); - private: // Get the full name of a Java class by prepending the Java package name // or outer class name. std::string GetClassFullName(const std::string& name_without_package, @@ -132,6 +134,8 @@ class ClassNameResolver { std::string GetClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file, bool kotlin); + + private: // Get the Java Class style full name of a message. std::string GetJavaClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable); @@ -150,4 +154,6 @@ class ClassNameResolver { } // namespace protobuf } // namespace google +#include + #endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_names.h b/third_party/protobuf/src/google/protobuf/compiler/java/names.h similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_names.h rename to third_party/protobuf/src/google/protobuf/compiler/java/names.h diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_options.h b/third_party/protobuf/src/google/protobuf/compiler/java/options.h similarity index 100% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_options.h rename to third_party/protobuf/src/google/protobuf/compiler/java/options.h diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/java/plugin_unittest.cc similarity index 81% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/plugin_unittest.cc index 3bdd53bf..8135f86d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/plugin_unittest.cc @@ -29,19 +29,17 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// -// TODO(kenton): Share code with the versions of this test in other languages? -// It seemed like parameterizing it would add more complexity than it is -// worth. #include +#include #include #include -#include +#include #include #include #include +#include #include #include @@ -54,11 +52,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const { + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override { std::string filename = "Test.java"; TryInsert(filename, "outer_class_scope", context); TryInsert(filename, "class_scope:foo.Bar", context); @@ -110,6 +107,26 @@ TEST(JavaPluginTest, PluginTest) { test_out.c_str(), "test.proto"}; EXPECT_EQ(0, cli.Run(5, argv)); + + // Loop over the lines of the generated code and verify that we find what we + // expect + + std::string output; + GOOGLE_CHECK_OK(File::GetContents(TestTempDir() + "/Test.java", &output, + true)); + std::vector lines = Split(output, "\n"); + bool found_generated_annotation = false; + bool found_do_not_edit = false; + for (const auto& line : lines) { + if (line.find(" DO NOT EDIT!") != std::string::npos) { + found_do_not_edit = true; + } + if (line.find("@com.google.protobuf.Generated") != std::string::npos) { + found_generated_annotation = true; + } + } + EXPECT_TRUE(found_do_not_edit); + (void)found_generated_annotation; } } // namespace diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.cc similarity index 84% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.cc index f67f6d39..2e3b8eaa 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.cc @@ -32,21 +32,21 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include "google/protobuf/compiler/java/primitive_field.h" #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "google/protobuf/stubs/logging.h" +#include "google/protobuf/stubs/common.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" +#include "google/protobuf/stubs/strutil.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" namespace google { namespace protobuf { @@ -57,53 +57,55 @@ using internal::WireFormat; namespace { -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + std::map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); JavaType javaType = GetJavaType(descriptor); (*variables)["type"] = PrimitiveTypeName(javaType); (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); (*variables)["kt_type"] = KotlinTypeName(javaType); - (*variables)["field_type"] = (*variables)["type"]; + variables->insert({"field_type", (*variables)["type"]}); + std::string name = (*variables)["name"]; if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE || javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT || javaType == JAVATYPE_LONG) { std::string capitalized_type = UnderscoresToCamelCase( PrimitiveTypeName(javaType), /*cap_first_letter=*/true); (*variables)["field_list_type"] = - "com.google.protobuf.Internal." + capitalized_type + "List"; - (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; - (*variables)["create_list"] = "new" + capitalized_type + "List()"; - (*variables)["mutable_copy_list"] = - "mutableCopy(" + (*variables)["name"] + "_)"; - (*variables)["name_make_immutable"] = - (*variables)["name"] + "_.makeImmutable()"; - (*variables)["repeated_get"] = - (*variables)["name"] + "_.get" + capitalized_type; - (*variables)["repeated_add"] = - (*variables)["name"] + "_.add" + capitalized_type; - (*variables)["repeated_set"] = - (*variables)["name"] + "_.set" + capitalized_type; - } else { - (*variables)["field_list_type"] = - "java.util.List<" + (*variables)["boxed_type"] + ">"; + StrCat("com.google.protobuf.Internal.", capitalized_type, "List"); + (*variables)["empty_list"] = + StrCat("empty", capitalized_type, "List()"); (*variables)["create_list"] = - "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()"; - (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" + - (*variables)["boxed_type"] + ">(" + - (*variables)["name"] + "_)"; - (*variables)["empty_list"] = "java.util.Collections.emptyList()"; + StrCat("new", capitalized_type, "List()"); + (*variables)["mutable_copy_list"] = + StrCat("mutableCopy(", name, "_)"); (*variables)["name_make_immutable"] = - (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" + - (*variables)["name"] + "_)"; - (*variables)["repeated_get"] = (*variables)["name"] + "_.get"; - (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; - (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + StrCat(name, "_.makeImmutable()"); + (*variables)["repeated_get"] = + StrCat(name, "_.get", capitalized_type); + (*variables)["repeated_add"] = + StrCat(name, "_.add", capitalized_type); + (*variables)["repeated_set"] = + StrCat(name, "_.set", capitalized_type); + } else { + std::string boxed_type = (*variables)["boxed_type"]; + (*variables)["field_list_type"] = + StrCat("java.util.List<", boxed_type, ">"); + (*variables)["create_list"] = + StrCat("new java.util.ArrayList<", boxed_type, ">()"); + (*variables)["mutable_copy_list"] = + StrCat("new java.util.ArrayList<", boxed_type, ">(", name, "_)"); + (*variables)["empty_list"] = "java.util.Collections.emptyList()"; + (*variables)["name_make_immutable"] = StrCat( + name, "_ = java.util.Collections.unmodifiableList(", name, "_)"); + (*variables)["repeated_get"] = StrCat(name, "_.get"); + (*variables)["repeated_add"] = StrCat(name, "_.add"); + (*variables)["repeated_set"] = StrCat(name, "_.set"); } (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); @@ -119,9 +121,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, WireFormat::TagSize(descriptor->number(), GetType(descriptor))); if (IsReferenceType(GetJavaType(descriptor))) { (*variables)["null_check"] = - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n"; + "if (value == null) { throw new NullPointerException(); }"; } else { (*variables)["null_check"] = ""; } @@ -131,8 +131,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["kt_deprecation"] = descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " + ? StrCat("@kotlin.Deprecated(message = \"Field ", name, + " is deprecated\") ") : ""; int fixed_size = FixedSize(GetType(descriptor)); if (fixed_size != -1) { @@ -143,40 +143,29 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); - // Note that these have a trailing ";". - (*variables)["set_has_field_bit_message"] = - GenerateSetBit(messageBitIndex) + ";"; - (*variables)["set_has_field_bit_builder"] = - GenerateSetBit(builderBitIndex) + ";"; - (*variables)["clear_has_field_bit_builder"] = - GenerateClearBit(builderBitIndex) + ";"; - + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex) + ";"; (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { - (*variables)["set_has_field_bit_message"] = ""; - (*variables)["set_has_field_bit_builder"] = ""; - (*variables)["clear_has_field_bit_builder"] = ""; - + (*variables)["set_has_field_bit_to_local"] = ""; switch (descriptor->type()) { case FieldDescriptor::TYPE_BYTES: (*variables)["is_field_present_message"] = - "!" + (*variables)["name"] + "_.isEmpty()"; + StrCat("!", name, "_.isEmpty()"); break; case FieldDescriptor::TYPE_FLOAT: (*variables)["is_field_present_message"] = - "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] + - "_) != 0"; + StrCat("java.lang.Float.floatToRawIntBits(", name, "_) != 0"); break; case FieldDescriptor::TYPE_DOUBLE: - (*variables)["is_field_present_message"] = - "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] + - "_) != 0"; + (*variables)["is_field_present_message"] = StrCat( + "java.lang.Double.doubleToRawLongBits(", name, "_) != 0"); break; default: - (*variables)["is_field_present_message"] = - (*variables)["name"] + "_ != " + (*variables)["default"]; + variables->insert( + {"is_field_present_message", + StrCat(name, "_ != ", (*variables)["default"])}); break; } } @@ -186,17 +175,15 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); - // For repeated fields, one bit is used for whether the array is immutable - // in the parsing constructor. - (*variables)["get_mutable_bit_parser"] = - GenerateGetBitMutableLocal(builderBitIndex); - (*variables)["set_mutable_bit_parser"] = - GenerateSetBitMutableLocal(builderBitIndex); - + // Always track the presence of a field explicitly in the builder, regardless + // of syntax. + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); - (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; } } // namespace @@ -206,21 +193,30 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + : descriptor_(descriptor), + message_bit_index_(messageBitIndex), + builder_bit_index_(builderBitIndex), + name_resolver_(context->GetNameResolver()) { SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); + name_resolver_, &variables_, context); } ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {} +int ImmutablePrimitiveFieldGenerator::GetMessageBitIndex() const { + return message_bit_index_; +} + +int ImmutablePrimitiveFieldGenerator::GetBuilderBitIndex() const { + return builder_bit_index_; +} + int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { return HasHasbit(descriptor_) ? 1 : 0; } -int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { - return GetNumBitsForMessage(); -} +int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { return 1; } void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { @@ -235,7 +231,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( void ImmutablePrimitiveFieldGenerator::GenerateMembers( io::Printer* printer) const { - printer->Print(variables_, "private $field_type$ $name$_;\n"); + printer->Print(variables_, "private $field_type$ $name$_ = $default$;\n"); PrintExtraFieldInfo(variables_, printer); if (HasHazzer(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); @@ -285,9 +281,9 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder " "${$set$capitalized_name$$}$($type$ value) {\n" - "$null_check$" - " $set_has_field_bit_builder$\n" + " $null_check$\n" " $name$_ = value;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" " return this;\n" "}\n"); @@ -359,9 +355,8 @@ void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode( void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - printer->Print(variables_, - "$name$_ = $default$;\n" - "$clear_has_field_bit_builder$\n"); + // No need to clear the has-bit since we clear the bitField ints all at once. + printer->Print(variables_, "$name$_ = $default$;\n"); } void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( @@ -381,35 +376,20 @@ void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (HasHazzer(descriptor_)) { - if (IsDefaultValueJavaDefault(descriptor_)) { - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " result.$name$_ = $name$_;\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); - } else { - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n" - "result.$name$_ = $name$_;\n"); - } - } else { - printer->Print(variables_, "result.$name$_ = $name$_;\n"); + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n"); + if (GetNumBitsForMessage() > 0) { + printer->Print(variables_, " $set_has_field_bit_to_local$\n"); } + printer->Print("}\n"); } -void ImmutablePrimitiveFieldGenerator::GenerateParsingCode( +void ImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { printer->Print(variables_, - "$set_has_field_bit_message$\n" - "$name$_ = input.read$capitalized_type$();\n"); -} - -void ImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - // noop for primitives. + "$name$_ = input.read$capitalized_type$();\n" + "$set_has_field_bit_builder$\n"); } void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode( @@ -591,7 +571,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder " "${$set$capitalized_name$$}$($type$ value) {\n" - "$null_check$" + " $null_check$\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" @@ -614,12 +594,15 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_); } +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + // No-Op: When a primitive field is in a oneof, clearing the oneof clears that + // field. +} + void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " result.$oneof_name$_ = $oneof_name$_;\n" - "}\n"); + // no-op } void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode( @@ -628,7 +611,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode( "set$capitalized_name$(other.get$capitalized_name$());\n"); } -void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode( +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { printer->Print(variables_, "$oneof_name$_ = input.read$capitalized_type$();\n" @@ -677,11 +660,8 @@ RepeatedImmutablePrimitiveFieldGenerator:: int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { - SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, - context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); -} + : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) {} RepeatedImmutablePrimitiveFieldGenerator:: ~RepeatedImmutablePrimitiveFieldGenerator() {} @@ -710,7 +690,8 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( io::Printer* printer) const { - printer->Print(variables_, "private $field_list_type$ $name$_;\n"); + printer->Print(variables_, "@SuppressWarnings(\"serial\")\n" + "private $field_list_type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); printer->Print(variables_, @@ -760,7 +741,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( " if (!$get_mutable_bit_builder$) {\n" " $name$_ = $mutable_copy_list$;\n" " $set_mutable_bit_builder$;\n" - " }\n" + " }\n" "}\n"); // Note: We return an unmodifiable list because otherwise the caller @@ -795,7 +776,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" - "$null_check$" + " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $repeated_set$(index, value);\n" " $on_changed$\n" @@ -807,7 +788,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder " "${$add$capitalized_name$$}$($type$ value) {\n" - "$null_check$" + " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $repeated_add$(value);\n" " $on_changed$\n" @@ -945,9 +926,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode( void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - printer->Print(variables_, - "$name$_ = $empty_list$;\n" - "$clear_mutable_bit_builder$;\n"); + printer->Print(variables_, "$name$_ = $empty_list$;\n"); } void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode( @@ -982,38 +961,24 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode( "result.$name$_ = $name$_;\n"); } -void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCode( +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { printer->Print(variables_, - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = $create_list$;\n" - " $set_mutable_bit_parser$;\n" + "$type$ v = input.read$capitalized_type$();\n" + "ensure$capitalized_name$IsMutable();\n" + "$repeated_add$(v);\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator:: + GenerateBuilderParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "ensure$capitalized_name$IsMutable();\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " $repeated_add$(input.read$capitalized_type$());\n" "}\n" - "$repeated_add$(input.read$capitalized_type$());\n"); -} - -void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCodeFromPacked( - io::Printer* printer) const { - printer->Print( - variables_, - "int length = input.readRawVarint32();\n" - "int limit = input.pushLimit(length);\n" - "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n" - " $name$_ = $create_list$;\n" - " $set_mutable_bit_parser$;\n" - "}\n" - "while (input.getBytesUntilLimit() > 0) {\n" - " $repeated_add$(input.read$capitalized_type$());\n" - "}\n" - "input.popLimit(limit);\n"); -} - -void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - printer->Print(variables_, - "if ($get_mutable_bit_parser$) {\n" - " $name_make_immutable$; // C\n" - "}\n"); + "input.popLimit(limit);\n"); } void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode( diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.h similarity index 82% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.h index 1f0eb8c8..9d956559 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field.h @@ -37,7 +37,8 @@ #include #include -#include + +#include "google/protobuf/compiler/java/field.h" namespace google { namespace protobuf { @@ -61,10 +62,16 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { int messageBitIndex, int builderBitIndex, Context* context); + ImmutablePrimitiveFieldGenerator(const ImmutablePrimitiveFieldGenerator&) = + delete; + ImmutablePrimitiveFieldGenerator& operator=( + const ImmutablePrimitiveFieldGenerator&) = delete; ~ImmutablePrimitiveFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- + int GetMessageBitIndex() const override; + int GetBuilderBitIndex() const override; int GetNumBitsForMessage() const override; int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; @@ -74,8 +81,7 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -88,11 +94,10 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; + int message_bit_index_; + int builder_bit_index_; std::map variables_; ClassNameResolver* name_resolver_; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator); }; class ImmutablePrimitiveOneofFieldGenerator @@ -101,26 +106,32 @@ class ImmutablePrimitiveOneofFieldGenerator ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldGenerator(); + ImmutablePrimitiveOneofFieldGenerator( + const ImmutablePrimitiveOneofFieldGenerator&) = delete; + ImmutablePrimitiveOneofFieldGenerator& operator=( + const ImmutablePrimitiveOneofFieldGenerator&) = delete; + ~ImmutablePrimitiveOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator); }; class RepeatedImmutablePrimitiveFieldGenerator - : public ImmutableFieldGenerator { + : public ImmutablePrimitiveFieldGenerator { public: explicit RepeatedImmutablePrimitiveFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); + RepeatedImmutablePrimitiveFieldGenerator( + const RepeatedImmutablePrimitiveFieldGenerator&) = delete; + RepeatedImmutablePrimitiveFieldGenerator& operator=( + const RepeatedImmutablePrimitiveFieldGenerator&) = delete; ~RepeatedImmutablePrimitiveFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- @@ -133,9 +144,9 @@ class RepeatedImmutablePrimitiveFieldGenerator void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingCodeFromPacked(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCodeFromPacked( + io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -145,13 +156,6 @@ class RepeatedImmutablePrimitiveFieldGenerator void GenerateKotlinDslMembers(io::Printer* printer) const override; std::string GetBoxedType() const override; - - private: - const FieldDescriptor* descriptor_; - std::map variables_; - ClassNameResolver* name_resolver_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator); }; } // namespace java diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.cc similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.cc index 5441d01a..28c23d57 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -40,13 +40,13 @@ #include #include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include namespace google { namespace protobuf { @@ -160,7 +160,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { - (*variables)["set_has_field_bit_message"] = ""; (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.h index dfafae39..2da0cd8f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/primitive_field_lite.h @@ -39,7 +39,7 @@ #include #include -#include +#include namespace google { namespace protobuf { @@ -93,7 +93,7 @@ class ImmutablePrimitiveOneofFieldLiteGenerator ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldLiteGenerator(); + ~ImmutablePrimitiveOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc b/third_party/protobuf/src/google/protobuf/compiler/java/service.cc similarity index 97% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/service.cc index e30d155e..9e206208 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/service.cc @@ -32,14 +32,17 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include + +// Must be last. +#include namespace google { namespace protobuf { @@ -472,3 +475,5 @@ void ImmutableServiceGenerator::GenerateBlockingMethodSignature( } // namespace compiler } // namespace protobuf } // namespace google + +#include diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.h b/third_party/protobuf/src/google/protobuf/compiler/java/service.h similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_service.h rename to third_party/protobuf/src/google/protobuf/compiler/java/service.h index 81db5194..9cb90216 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/service.h @@ -78,7 +78,7 @@ class ImmutableServiceGenerator : public ServiceGenerator { public: ImmutableServiceGenerator(const ServiceDescriptor* descriptor, Context* context); - virtual ~ImmutableServiceGenerator(); + ~ImmutableServiceGenerator() override; void Generate(io::Printer* printer) override; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.cc similarity index 96% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.cc index 45943d76..39b96eec 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.cc @@ -30,19 +30,19 @@ // Author: xiaofeng@google.com (Feng Xiao) -#include +#include #include -#include -#include -#include #include -#include #include #include #include #include +#include +#include +#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h b/third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.h similarity index 98% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h rename to third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.h index 7c79abe2..b1f6eb3c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/shared_code_generator.h @@ -40,7 +40,7 @@ #include #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/string_field.cc similarity index 90% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/string_field.cc index 1a0959e4..5f207924 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/string_field.cc @@ -33,21 +33,21 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include "google/protobuf/compiler/java/string_field.h" #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "google/protobuf/stubs/logging.h" +#include "google/protobuf/stubs/common.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" +#include "google/protobuf/stubs/strutil.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/doc_comment.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/name_resolver.h" namespace google { namespace protobuf { @@ -59,11 +59,11 @@ using internal::WireFormatLite; namespace { -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, - std::map* variables) { +void SetPrimitiveVariables( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, + std::map* variables, + Context* context) { SetCommonFieldVariables(descriptor, info, variables); (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY"; @@ -77,9 +77,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["tag_size"] = StrCat( WireFormat::TagSize(descriptor->number(), GetType(descriptor))); (*variables)["null_check"] = - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n"; + "if (value == null) { throw new NullPointerException(); }"; (*variables)["isStringEmpty"] = "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() + ".isStringEmpty"; @@ -93,34 +91,33 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, // by the proto compiler (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - (*variables)["kt_deprecation"] = - descriptor->options().deprecated() - ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + - " is deprecated\") " - : ""; + variables->insert( + {"kt_deprecation", + descriptor->options().deprecated() + ? StrCat("@kotlin.Deprecated(message = \"Field ", + (*variables)["name"], " is deprecated\") ") + : ""}); (*variables)["on_changed"] = "onChanged();"; if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); // Note that these have a trailing ";". (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex) + ";"; - (*variables)["set_has_field_bit_builder"] = - GenerateSetBit(builderBitIndex) + ";"; - (*variables)["clear_has_field_bit_builder"] = - GenerateClearBit(builderBitIndex) + ";"; (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { + (*variables)["get_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_to_local"] = ""; (*variables)["set_has_field_bit_message"] = ""; - (*variables)["set_has_field_bit_builder"] = ""; - (*variables)["clear_has_field_bit_builder"] = ""; - (*variables)["is_field_present_message"] = - "!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)"; + variables->insert({"is_field_present_message", + StrCat("!", (*variables)["isStringEmpty"], "(", + (*variables)["name"], "_)")}); } // For repeated builders, one bit is used for whether the array is immutable. @@ -128,17 +125,13 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); - // For repeated fields, one bit is used for whether the array is immutable - // in the parsing constructor. - (*variables)["get_mutable_bit_parser"] = - GenerateGetBitMutableLocal(builderBitIndex); - (*variables)["set_mutable_bit_parser"] = - GenerateSetBitMutableLocal(builderBitIndex); - + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); - (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; } } // namespace @@ -148,21 +141,30 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, ImmutableStringFieldGenerator::ImmutableStringFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + : descriptor_(descriptor), + message_bit_index_(messageBitIndex), + builder_bit_index_(builderBitIndex), + name_resolver_(context->GetNameResolver()) { SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); + name_resolver_, &variables_, context); } ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {} +int ImmutableStringFieldGenerator::GetMessageBitIndex() const { + return message_bit_index_; +} + +int ImmutableStringFieldGenerator::GetBuilderBitIndex() const { + return builder_bit_index_; +} + int ImmutableStringFieldGenerator::GetNumBitsForMessage() const { return HasHasbit(descriptor_) ? 1 : 0; } -int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { - return GetNumBitsForMessage(); -} +int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { return 1; } // A note about how strings are handled. This code used to just store a String // in the Message. This had two issues: @@ -214,7 +216,9 @@ void ImmutableStringFieldGenerator::GenerateInterfaceMembers( void ImmutableStringFieldGenerator::GenerateMembers( io::Printer* printer) const { - printer->Print(variables_, "private volatile java.lang.Object $name$_;\n"); + printer->Print(variables_, + "@SuppressWarnings(\"serial\")\n" + "private volatile java.lang.Object $name$_ = $default$;\n"); PrintExtraFieldInfo(variables_, printer); if (HasHazzer(descriptor_)) { @@ -333,9 +337,9 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" - "$null_check$" - " $set_has_field_bit_builder$\n" + " $null_check$\n" " $name$_ = value;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" " return this;\n" "}\n"); @@ -344,14 +348,14 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( /* builder */ true); printer->Print( variables_, - "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n"); + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"); printer->Annotate("{", "}", descriptor_); // The default value is not a simple literal so we want to avoid executing // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); printer->Print(variables_, + " $clear_has_field_bit_builder$\n" " $on_changed$\n" " return this;\n" "}\n"); @@ -362,14 +366,14 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" - "$null_check$"); + " $null_check$\n"); printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); } printer->Print(variables_, - " $set_has_field_bit_builder$\n" " $name$_ = value;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" " return this;\n" "}\n"); @@ -416,9 +420,7 @@ void ImmutableStringFieldGenerator::GenerateInitializationCode( void ImmutableStringFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - printer->Print(variables_, - "$name$_ = $default$;\n" - "$clear_has_field_bit_builder$\n"); + printer->Print(variables_, "$name$_ = $default$;\n"); } void ImmutableStringFieldGenerator::GenerateMergingCode( @@ -428,14 +430,15 @@ void ImmutableStringFieldGenerator::GenerateMergingCode( // all string fields to Strings when copying fields from a Message. printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" - " $set_has_field_bit_builder$\n" " $name$_ = other.$name$_;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" "}\n"); } else { printer->Print(variables_, "if (!other.get$capitalized_name$().isEmpty()) {\n" " $name$_ = other.$name$_;\n" + " $set_has_field_bit_builder$\n" " $on_changed$\n" "}\n"); } @@ -443,35 +446,28 @@ void ImmutableStringFieldGenerator::GenerateMergingCode( void ImmutableStringFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (HasHazzer(descriptor_)) { - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n"); + if (GetNumBitsForMessage() > 0) { + printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } - printer->Print(variables_, "result.$name$_ = $name$_;\n"); + printer->Print("}\n"); } -void ImmutableStringFieldGenerator::GenerateParsingCode( +void ImmutableStringFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "java.lang.String s = input.readStringRequireUtf8();\n" - "$set_has_field_bit_message$\n" - "$name$_ = s;\n"); + "$name$_ = input.readStringRequireUtf8();\n" + "$set_has_field_bit_builder$\n"); } else { printer->Print(variables_, - "com.google.protobuf.ByteString bs = input.readBytes();\n" - "$set_has_field_bit_message$\n" - "$name$_ = bs;\n"); + "$name$_ = input.readBytes();\n" + "$set_has_field_bit_builder$\n"); } } -void ImmutableStringFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - // noop for strings. -} - void ImmutableStringFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, @@ -655,7 +651,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" - "$null_check$" + " $null_check$\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" @@ -682,7 +678,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" - "$null_check$"); + " $null_check$\n"); printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -695,6 +691,11 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( "}\n"); } +void ImmutableStringOneofFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + // No-Op: String fields in oneofs are correctly cleared by clearing the oneof +} + void ImmutableStringOneofFieldGenerator::GenerateMergingCode( io::Printer* printer) const { // Allow a slight breach of abstraction here in order to avoid forcing @@ -707,13 +708,10 @@ void ImmutableStringOneofFieldGenerator::GenerateMergingCode( void ImmutableStringOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " result.$oneof_name$_ = $oneof_name$_;\n" - "}\n"); + // No-Op: oneof fields are built by a single statement } -void ImmutableStringOneofFieldGenerator::GenerateParsingCode( +void ImmutableStringOneofFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, @@ -749,11 +747,8 @@ void ImmutableStringOneofFieldGenerator::GenerateSerializedSizeCode( RepeatedImmutableStringFieldGenerator::RepeatedImmutableStringFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context) - : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { - SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, - context->GetFieldGeneratorInfo(descriptor), - name_resolver_, &variables_); -} + : ImmutableStringFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) {} RepeatedImmutableStringFieldGenerator:: ~RepeatedImmutableStringFieldGenerator() {} @@ -796,6 +791,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers( void RepeatedImmutableStringFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, + "@SuppressWarnings(\"serial\")\n" "private com.google.protobuf.LazyStringList $name$_;\n"); PrintExtraFieldInfo(variables_, printer); WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); @@ -891,7 +887,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, java.lang.String value) {\n" - "$null_check$" + " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value);\n" " $on_changed$\n" @@ -903,7 +899,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " java.lang.String value) {\n" - "$null_check$" + " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" " $on_changed$\n" @@ -940,7 +936,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" - "$null_check$"); + " $null_check$\n"); printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -992,7 +988,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( // List += String WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); - printer->Print(variables_, + printer->Print(variables_, "@kotlin.jvm.JvmSynthetic\n" "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" @@ -1104,33 +1100,19 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuildingCode( "result.$name$_ = $name$_;\n"); } -void RepeatedImmutableStringFieldGenerator::GenerateParsingCode( +void RepeatedImmutableStringFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "java.lang.String s = input.readStringRequireUtf8();\n"); + "java.lang.String s = input.readStringRequireUtf8();\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(s);\n"); } else { printer->Print(variables_, - "com.google.protobuf.ByteString bs = input.readBytes();\n"); + "com.google.protobuf.ByteString bs = input.readBytes();\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(bs);\n"); } - printer->Print(variables_, - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" - " $set_mutable_bit_parser$;\n" - "}\n"); - if (CheckUtf8(descriptor_)) { - printer->Print(variables_, "$name$_.add(s);\n"); - } else { - printer->Print(variables_, "$name$_.add(bs);\n"); - } -} - -void RepeatedImmutableStringFieldGenerator::GenerateParsingDoneCode( - io::Printer* printer) const { - printer->Print(variables_, - "if ($get_mutable_bit_parser$) {\n" - " $name$_ = $name$_.getUnmodifiableView();\n" - "}\n"); } void RepeatedImmutableStringFieldGenerator::GenerateSerializationCode( diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/string_field.h similarity index 82% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h rename to third_party/protobuf/src/google/protobuf/compiler/java/string_field.h index efab5fee..814ebf21 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/string_field.h @@ -38,7 +38,8 @@ #include #include -#include + +#include "google/protobuf/compiler/java/field.h" namespace google { namespace protobuf { @@ -61,10 +62,15 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringFieldGenerator(); + ImmutableStringFieldGenerator(const ImmutableStringFieldGenerator&) = delete; + ImmutableStringFieldGenerator& operator=( + const ImmutableStringFieldGenerator&) = delete; + ~ImmutableStringFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- + int GetMessageBitIndex() const override; + int GetBuilderBitIndex() const override; int GetNumBitsForMessage() const override; int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; @@ -74,8 +80,7 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -88,11 +93,10 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { protected: const FieldDescriptor* descriptor_; + int message_bit_index_; + int builder_bit_index_; std::map variables_; ClassNameResolver* name_resolver_; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator); }; class ImmutableStringOneofFieldGenerator @@ -101,25 +105,33 @@ class ImmutableStringOneofFieldGenerator ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringOneofFieldGenerator(); + ImmutableStringOneofFieldGenerator( + const ImmutableStringOneofFieldGenerator&) = delete; + ImmutableStringOneofFieldGenerator& operator=( + const ImmutableStringOneofFieldGenerator&) = delete; + ~ImmutableStringOneofFieldGenerator() override; private: void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator); }; -class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator { +class RepeatedImmutableStringFieldGenerator + : public ImmutableStringFieldGenerator { public: explicit RepeatedImmutableStringFieldGenerator( const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); + RepeatedImmutableStringFieldGenerator( + const RepeatedImmutableStringFieldGenerator&) = delete; + RepeatedImmutableStringFieldGenerator& operator=( + const RepeatedImmutableStringFieldGenerator&) = delete; ~RepeatedImmutableStringFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- @@ -132,8 +144,7 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator { void GenerateBuilderClearCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; void GenerateBuildingCode(io::Printer* printer) const override; - void GenerateParsingCode(io::Printer* printer) const override; - void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateFieldBuilderInitializationCode( @@ -143,13 +154,6 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator { void GenerateKotlinDslMembers(io::Printer* printer) const override; std::string GetBoxedType() const override; - - private: - const FieldDescriptor* descriptor_; - std::map variables_; - ClassNameResolver* name_resolver_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator); }; } // namespace java diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.cc b/third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.cc similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.cc rename to third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.cc index 18339033..49f6891d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.cc @@ -33,7 +33,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include +#include #include #include @@ -41,13 +41,13 @@ #include #include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include namespace google { namespace protobuf { @@ -758,7 +758,7 @@ void RepeatedImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers( "$kt_deprecation$public val $kt_name$: " "com.google.protobuf.kotlin.DslList" "\n" - " @kotlin.OptIn" + "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" " get() = com.google.protobuf.kotlin.DslList(\n" " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.h b/third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.h similarity index 99% rename from third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.h rename to third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.h index 85ec6027..b6ad1ea8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field_lite.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/string_field_lite.h @@ -40,7 +40,7 @@ #include #include -#include +#include namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.cc deleted file mode 100644 index d2dac2f6..00000000 --- a/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.cc +++ /dev/null @@ -1,3941 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace js { - -// Sorted list of JavaScript keywords. These cannot be used as names. If they -// appear, we prefix them with "pb_". -const char* kKeyword[] = { - "abstract", "boolean", "break", "byte", "case", - "catch", "char", "class", "const", "continue", - "debugger", "default", "delete", "do", "double", - "else", "enum", "export", "extends", "false", - "final", "finally", "float", "for", "function", - "goto", "if", "implements", "import", "in", - "instanceof", "int", "interface", "long", "native", - "new", "null", "package", "private", "protected", - "public", "return", "short", "static", "super", - "switch", "synchronized", "this", "throw", "throws", - "transient", "try", "typeof", "var", "void", - "volatile", "while", "with", -}; - -static const int kNumKeyword = sizeof(kKeyword) / sizeof(char*); - -namespace { - -// The mode of operation for bytes fields. Historically JSPB always carried -// bytes as JS {string}, containing base64 content by convention. With binary -// and proto3 serialization the new convention is to represent it as binary -// data in Uint8Array. See b/26173701 for background on the migration. -enum BytesMode { - BYTES_DEFAULT, // Default type for getBytesField to return. - BYTES_B64, // Explicitly coerce to base64 string where needed. - BYTES_U8, // Explicitly coerce to Uint8Array where needed. -}; - -bool IsReserved(const std::string& ident) { - for (int i = 0; i < kNumKeyword; i++) { - if (ident == kKeyword[i]) { - return true; - } - } - return false; -} - -std::string GetSnakeFilename(const std::string& filename) { - std::string snake_name = filename; - ReplaceCharacters(&snake_name, "/", '_'); - return snake_name; -} - -// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript -// file foo/bar/baz.js. -std::string GetJSFilename(const GeneratorOptions& options, - const std::string& filename) { - return StripProto(filename) + options.GetFileNameExtension(); -} - -// Given a filename like foo/bar/baz.proto, returns the root directory -// path ../../ -std::string GetRootPath(const std::string& from_filename, - const std::string& to_filename) { - if (to_filename.find("google/protobuf") == 0) { - // Well-known types (.proto files in the google/protobuf directory) are - // assumed to come from the 'google-protobuf' npm package. We may want to - // generalize this exception later by letting others put generated code in - // their own npm packages. - return "google-protobuf/"; - } - - size_t slashes = std::count(from_filename.begin(), from_filename.end(), '/'); - if (slashes == 0) { - return "./"; - } - std::string result = ""; - for (size_t i = 0; i < slashes; i++) { - result += "../"; - } - return result; -} - -// Returns the alias we assign to the module of the given .proto filename -// when importing. -std::string ModuleAlias(const std::string& filename) { - // This scheme could technically cause problems if a file includes any 2 of: - // foo/bar_baz.proto - // foo_bar_baz.proto - // foo_bar/baz.proto - // - // We'll worry about this problem if/when we actually see it. This name isn't - // exposed to users so we can change it later if we need to. - std::string basename = StripProto(filename); - ReplaceCharacters(&basename, "-", '$'); - ReplaceCharacters(&basename, "/", '_'); - ReplaceCharacters(&basename, ".", '_'); - return basename + "_pb"; -} - -// Returns the fully normalized JavaScript namespace for the given -// file descriptor's package. -std::string GetNamespace(const GeneratorOptions& options, - const FileDescriptor* file) { - if (!options.namespace_prefix.empty()) { - return options.namespace_prefix; - } else if (!file->package().empty()) { - return "proto." + file->package(); - } else { - return "proto"; - } -} - -// Returns the name of the message with a leading dot and taking into account -// nesting, for example ".OuterMessage.InnerMessage", or returns empty if -// descriptor is null. This function does not handle namespacing, only message -// nesting. -std::string GetNestedMessageName(const Descriptor* descriptor) { - if (descriptor == NULL) { - return ""; - } - std::string result = - StripPrefixString(descriptor->full_name(), descriptor->file()->package()); - // Add a leading dot if one is not already present. - if (!result.empty() && result[0] != '.') { - result = "." + result; - } - return result; -} - -// Returns the path prefix for a message or enumeration that -// lives under the given file and containing type. -std::string GetPrefix(const GeneratorOptions& options, - const FileDescriptor* file_descriptor, - const Descriptor* containing_type) { - std::string prefix = GetNamespace(options, file_descriptor) + - GetNestedMessageName(containing_type); - if (!prefix.empty()) { - prefix += "."; - } - return prefix; -} - -// Returns the fully normalized JavaScript path prefix for the given -// message descriptor. -std::string GetMessagePathPrefix(const GeneratorOptions& options, - const Descriptor* descriptor) { - return GetPrefix(options, descriptor->file(), descriptor->containing_type()); -} - -// Returns the fully normalized JavaScript path for the given -// message descriptor. -std::string GetMessagePath(const GeneratorOptions& options, - const Descriptor* descriptor) { - return GetMessagePathPrefix(options, descriptor) + descriptor->name(); -} - -// Returns the fully normalized JavaScript path prefix for the given -// enumeration descriptor. -std::string GetEnumPathPrefix(const GeneratorOptions& options, - const EnumDescriptor* enum_descriptor) { - return GetPrefix(options, enum_descriptor->file(), - enum_descriptor->containing_type()); -} - -// Returns the fully normalized JavaScript path for the given -// enumeration descriptor. -std::string GetEnumPath(const GeneratorOptions& options, - const EnumDescriptor* enum_descriptor) { - return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name(); -} - -std::string MaybeCrossFileRef(const GeneratorOptions& options, - const FileDescriptor* from_file, - const Descriptor* to_message) { - if ((options.import_style == GeneratorOptions::kImportCommonJs || - options.import_style == GeneratorOptions::kImportCommonJsStrict) && - from_file != to_message->file()) { - // Cross-file ref in CommonJS needs to use the module alias instead of - // the global name. - return ModuleAlias(to_message->file()->name()) + - GetNestedMessageName(to_message->containing_type()) + "." + - to_message->name(); - } else { - // Within a single file we use a full name. - return GetMessagePath(options, to_message); - } -} - -std::string SubmessageTypeRef(const GeneratorOptions& options, - const FieldDescriptor* field) { - GOOGLE_CHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); - return MaybeCrossFileRef(options, field->file(), field->message_type()); -} - -// - Object field name: LOWER_UNDERSCORE -> LOWER_CAMEL, except for group fields -// (UPPER_CAMEL -> LOWER_CAMEL), with "List" (or "Map") appended if appropriate, -// and with reserved words triggering a "pb_" prefix. -// - Getters/setters: LOWER_UNDERSCORE -> UPPER_CAMEL, except for group fields -// (use the name directly), then append "List" if appropriate, then append "$" -// if resulting name is equal to a reserved word. -// - Enums: just uppercase. - -// Locale-independent version of ToLower that deals only with ASCII A-Z. -char ToLowerASCII(char c) { - if (c >= 'A' && c <= 'Z') { - return (c - 'A') + 'a'; - } else { - return c; - } -} - -std::vector ParseLowerUnderscore(const std::string& input) { - std::vector words; - std::string running = ""; - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { - if (!running.empty()) { - words.push_back(running); - running.clear(); - } - } else { - running += ToLowerASCII(input[i]); - } - } - if (!running.empty()) { - words.push_back(running); - } - return words; -} - -std::vector ParseUpperCamel(const std::string& input) { - std::vector words; - std::string running = ""; - for (int i = 0; i < input.size(); i++) { - if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) { - words.push_back(running); - running.clear(); - } - running += ToLowerASCII(input[i]); - } - if (!running.empty()) { - words.push_back(running); - } - return words; -} - -std::string ToLowerCamel(const std::vector& words) { - std::string result; - for (int i = 0; i < words.size(); i++) { - std::string word = words[i]; - if (i == 0 && (word[0] >= 'A' && word[0] <= 'Z')) { - word[0] = (word[0] - 'A') + 'a'; - } else if (i != 0 && (word[0] >= 'a' && word[0] <= 'z')) { - word[0] = (word[0] - 'a') + 'A'; - } - result += word; - } - return result; -} - -std::string ToUpperCamel(const std::vector& words) { - std::string result; - for (int i = 0; i < words.size(); i++) { - std::string word = words[i]; - if (word[0] >= 'a' && word[0] <= 'z') { - word[0] = (word[0] - 'a') + 'A'; - } - result += word; - } - return result; -} - -// Based on code from descriptor.cc (Thanks Kenton!) -// Uppercases the entire string, turning ValueName into -// VALUENAME. -std::string ToEnumCase(const std::string& input) { - std::string result; - result.reserve(input.size()); - - for (int i = 0; i < input.size(); i++) { - if ('a' <= input[i] && input[i] <= 'z') { - result.push_back(input[i] - 'a' + 'A'); - } else { - result.push_back(input[i]); - } - } - - return result; -} - -std::string ToLower(const std::string& input) { - std::string result; - result.reserve(input.size()); - - for (int i = 0; i < input.size(); i++) { - if ('A' <= input[i] && input[i] <= 'Z') { - result.push_back(input[i] - 'A' + 'a'); - } else { - result.push_back(input[i]); - } - } - - return result; -} - -// When we're generating one output file per SCC, this is the filename -// that top-level extensions should go in. -// e.g. one proto file (test.proto): -// package a; -// extends Foo { -// ... -// } -// If "with_filename" equals true, the extension filename will be -// "proto.a_test_extensions.js", otherwise will be "proto.a.js" -std::string GetExtensionFileName(const GeneratorOptions& options, - const FileDescriptor* file, - bool with_filename) { - std::string snake_name = StripProto(GetSnakeFilename(file->name())); - return options.output_dir + "/" + ToLower(GetNamespace(options, file)) + - (with_filename ? ("_" + snake_name + "_extensions") : "") + - options.GetFileNameExtension(); -} -// When we're generating one output file per SCC, this is the filename -// that all messages in the SCC should go in. -// If with_package equals true, filename will have package prefix, -// If the filename length is longer than 200, the filename will be the -// SCC's proto filename with suffix "_long_sccs_(index)" (if with_package equals -// true it still has package prefix) -std::string GetMessagesFileName(const GeneratorOptions& options, const SCC* scc, - bool with_package) { - static std::map* long_name_dict = - new std::map(); - std::string package_base = - with_package - ? ToLower(GetNamespace(options, scc->GetRepresentative()->file()) + - "_") - : ""; - std::string filename_base = ""; - std::vector all_message_names; - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - all_message_names.push_back(ToLower(one_desc->name())); - } - } - sort(all_message_names.begin(), all_message_names.end()); - for (auto one_message : all_message_names) { - if (!filename_base.empty()) { - filename_base += "_"; - } - filename_base += one_message; - } - if (filename_base.size() + package_base.size() > 200) { - if ((*long_name_dict).find(scc->GetRepresentative()) == - (*long_name_dict).end()) { - std::string snake_name = StripProto( - GetSnakeFilename(scc->GetRepresentative()->file()->name())); - (*long_name_dict)[scc->GetRepresentative()] = - StrCat(snake_name, "_long_sccs_", - static_cast((*long_name_dict).size())); - } - filename_base = (*long_name_dict)[scc->GetRepresentative()]; - } - return options.output_dir + "/" + package_base + filename_base + - options.GetFileNameExtension(); -} - -// When we're generating one output file per type name, this is the filename -// that a top-level enum should go in. -// If with_package equals true, filename will have package prefix. -std::string GetEnumFileName(const GeneratorOptions& options, - const EnumDescriptor* desc, bool with_package) { - return options.output_dir + "/" + - (with_package ? ToLower(GetNamespace(options, desc->file()) + "_") - : "") + - ToLower(desc->name()) + options.GetFileNameExtension(); -} - -// Returns the message/response ID, if set. -std::string GetMessageId(const Descriptor* desc) { return std::string(); } - -bool IgnoreExtensionField(const FieldDescriptor* field) { - // Exclude descriptor extensions from output "to avoid clutter" (from original - // codegen). - if (!field->is_extension()) return false; - const FileDescriptor* file = field->containing_type()->file(); - return file->name() == "net/proto2/proto/descriptor.proto" || - file->name() == "google/protobuf/descriptor.proto"; -} - -// Used inside Google only -- do not remove. -bool IsResponse(const Descriptor* desc) { return false; } - -bool IgnoreField(const FieldDescriptor* field) { - return IgnoreExtensionField(field); -} - -// Do we ignore this message type? -bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); } - -// Does JSPB ignore this entire oneof? True only if all fields are ignored. -bool IgnoreOneof(const OneofDescriptor* oneof) { - if (oneof->is_synthetic()) return true; - for (int i = 0; i < oneof->field_count(); i++) { - if (!IgnoreField(oneof->field(i))) { - return false; - } - } - return true; -} - -std::string JSIdent(const GeneratorOptions& options, - const FieldDescriptor* field, bool is_upper_camel, - bool is_map, bool drop_list) { - std::string result; - if (field->type() == FieldDescriptor::TYPE_GROUP) { - result = is_upper_camel - ? ToUpperCamel(ParseUpperCamel(field->message_type()->name())) - : ToLowerCamel(ParseUpperCamel(field->message_type()->name())); - } else { - result = is_upper_camel ? ToUpperCamel(ParseLowerUnderscore(field->name())) - : ToLowerCamel(ParseLowerUnderscore(field->name())); - } - if (is_map || field->is_map()) { - // JSPB-style or proto3-style map. - result += "Map"; - } else if (!drop_list && field->is_repeated()) { - // Repeated field. - result += "List"; - } - return result; -} - -std::string JSObjectFieldName(const GeneratorOptions& options, - const FieldDescriptor* field) { - std::string name = JSIdent(options, field, - /* is_upper_camel = */ false, - /* is_map = */ false, - /* drop_list = */ false); - if (IsReserved(name)) { - name = "pb_" + name; - } - return name; -} - -std::string JSByteGetterSuffix(BytesMode bytes_mode) { - switch (bytes_mode) { - case BYTES_DEFAULT: - return ""; - case BYTES_B64: - return "B64"; - case BYTES_U8: - return "U8"; - default: - assert(false); - } - return ""; -} - -// Returns the field name as a capitalized portion of a getter/setter method -// name, e.g. MyField for .getMyField(). -std::string JSGetterName(const GeneratorOptions& options, - const FieldDescriptor* field, - BytesMode bytes_mode = BYTES_DEFAULT, - bool drop_list = false) { - std::string name = JSIdent(options, field, - /* is_upper_camel = */ true, - /* is_map = */ false, drop_list); - if (field->type() == FieldDescriptor::TYPE_BYTES) { - std::string suffix = JSByteGetterSuffix(bytes_mode); - if (!suffix.empty()) { - name += "_as" + suffix; - } - } - if (name == "Extension" || name == "JsPbMessageId") { - // Avoid conflicts with base-class names. - name += "$"; - } - return name; -} - -std::string JSOneofName(const OneofDescriptor* oneof) { - return ToUpperCamel(ParseLowerUnderscore(oneof->name())); -} - -// Returns the index corresponding to this field in the JSPB array (underlying -// data storage array). -std::string JSFieldIndex(const FieldDescriptor* field) { - // Determine whether this field is a member of a group. Group fields are a bit - // wonky: their "containing type" is a message type created just for the - // group, and that type's parent type has a field with the group-message type - // as its message type and TYPE_GROUP as its field type. For such fields, the - // index we use is relative to the field number of the group submessage field. - // For all other fields, we just use the field number. - const Descriptor* containing_type = field->containing_type(); - const Descriptor* parent_type = containing_type->containing_type(); - if (parent_type != NULL) { - for (int i = 0; i < parent_type->field_count(); i++) { - if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP && - parent_type->field(i)->message_type() == containing_type) { - return StrCat(field->number() - parent_type->field(i)->number()); - } - } - } - return StrCat(field->number()); -} - -std::string JSOneofIndex(const OneofDescriptor* oneof) { - int index = -1; - for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) { - const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i); - if (o->is_synthetic()) continue; - // If at least one field in this oneof is not JSPB-ignored, count the oneof. - for (int j = 0; j < o->field_count(); j++) { - const FieldDescriptor* f = o->field(j); - if (!IgnoreField(f)) { - index++; - break; // inner loop - } - } - if (o == oneof) { - break; - } - } - return StrCat(index); -} - -// Decodes a codepoint in \x0000 -- \xFFFF. -uint16 DecodeUTF8Codepoint(uint8* bytes, size_t* length) { - if (*length == 0) { - return 0; - } - size_t expected = 0; - if ((*bytes & 0x80) == 0) { - expected = 1; - } else if ((*bytes & 0xe0) == 0xc0) { - expected = 2; - } else if ((*bytes & 0xf0) == 0xe0) { - expected = 3; - } else { - // Too long -- don't accept. - *length = 0; - return 0; - } - - if (*length < expected) { - // Not enough bytes -- don't accept. - *length = 0; - return 0; - } - - *length = expected; - switch (expected) { - case 1: - return bytes[0]; - case 2: - return ((bytes[0] & 0x1F) << 6) | ((bytes[1] & 0x3F) << 0); - case 3: - return ((bytes[0] & 0x0F) << 12) | ((bytes[1] & 0x3F) << 6) | - ((bytes[2] & 0x3F) << 0); - default: - return 0; - } -} - -// Escapes the contents of a string to be included within double-quotes ("") in -// JavaScript. The input data should be a UTF-8 encoded C++ string of chars. -// Returns false if |out| was truncated because |in| contained invalid UTF-8 or -// codepoints outside the BMP. -// TODO(b/115551870): Support codepoints outside the BMP. -bool EscapeJSString(const std::string& in, std::string* out) { - size_t decoded = 0; - for (size_t i = 0; i < in.size(); i += decoded) { - uint16 codepoint = 0; - // Decode the next UTF-8 codepoint. - size_t have_bytes = in.size() - i; - uint8 bytes[3] = { - static_cast(in[i]), - static_cast(((i + 1) < in.size()) ? in[i + 1] : 0), - static_cast(((i + 2) < in.size()) ? in[i + 2] : 0), - }; - codepoint = DecodeUTF8Codepoint(bytes, &have_bytes); - if (have_bytes == 0) { - return false; - } - decoded = have_bytes; - - switch (codepoint) { - case '\'': - *out += "\\x27"; - break; - case '"': - *out += "\\x22"; - break; - case '<': - *out += "\\x3c"; - break; - case '=': - *out += "\\x3d"; - break; - case '>': - *out += "\\x3e"; - break; - case '&': - *out += "\\x26"; - break; - case '\b': - *out += "\\b"; - break; - case '\t': - *out += "\\t"; - break; - case '\n': - *out += "\\n"; - break; - case '\f': - *out += "\\f"; - break; - case '\r': - *out += "\\r"; - break; - case '\\': - *out += "\\\\"; - break; - default: - // TODO(b/115551870): Once we're supporting codepoints outside the BMP, - // use a single Unicode codepoint escape if the output language is - // ECMAScript 2015 or above. Otherwise, use a surrogate pair. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals - if (codepoint >= 0x20 && codepoint <= 0x7e) { - *out += static_cast(codepoint); - } else if (codepoint >= 0x100) { - *out += StringPrintf("\\u%04x", codepoint); - } else { - *out += StringPrintf("\\x%02x", codepoint); - } - break; - } - } - return true; -} - -std::string EscapeBase64(const std::string& in) { - static const char* kAlphabet = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - std::string result; - - for (size_t i = 0; i < in.size(); i += 3) { - int value = (in[i] << 16) | (((i + 1) < in.size()) ? (in[i + 1] << 8) : 0) | - (((i + 2) < in.size()) ? (in[i + 2] << 0) : 0); - result += kAlphabet[(value >> 18) & 0x3f]; - result += kAlphabet[(value >> 12) & 0x3f]; - if ((i + 1) < in.size()) { - result += kAlphabet[(value >> 6) & 0x3f]; - } else { - result += '='; - } - if ((i + 2) < in.size()) { - result += kAlphabet[(value >> 0) & 0x3f]; - } else { - result += '='; - } - } - - return result; -} - -// Post-process the result of SimpleFtoa/SimpleDtoa to *exactly* match the -// original codegen's formatting (which is just .toString() on java.lang.Double -// or java.lang.Float). -std::string PostProcessFloat(std::string result) { - // If inf, -inf or nan, replace with +Infinity, -Infinity or NaN. - if (result == "inf") { - return "Infinity"; - } else if (result == "-inf") { - return "-Infinity"; - } else if (result == "nan") { - return "NaN"; - } - - // If scientific notation (e.g., "1e10"), (i) capitalize the "e", (ii) - // ensure that the mantissa (portion prior to the "e") has at least one - // fractional digit (after the decimal point), and (iii) strip any unnecessary - // leading zeroes and/or '+' signs from the exponent. - std::string::size_type exp_pos = result.find('e'); - if (exp_pos != std::string::npos) { - std::string mantissa = result.substr(0, exp_pos); - std::string exponent = result.substr(exp_pos + 1); - - // Add ".0" to mantissa if no fractional part exists. - if (mantissa.find('.') == std::string::npos) { - mantissa += ".0"; - } - - // Strip the sign off the exponent and store as |exp_neg|. - bool exp_neg = false; - if (!exponent.empty() && exponent[0] == '+') { - exponent = exponent.substr(1); - } else if (!exponent.empty() && exponent[0] == '-') { - exp_neg = true; - exponent = exponent.substr(1); - } - - // Strip any leading zeroes off the exponent. - while (exponent.size() > 1 && exponent[0] == '0') { - exponent = exponent.substr(1); - } - - return mantissa + "E" + std::string(exp_neg ? "-" : "") + exponent; - } - - // Otherwise, this is an ordinary decimal number. Append ".0" if result has no - // decimal/fractional part in order to match output of original codegen. - if (result.find('.') == std::string::npos) { - result += ".0"; - } - - return result; -} - -std::string FloatToString(float value) { - std::string result = SimpleFtoa(value); - return PostProcessFloat(result); -} - -std::string DoubleToString(double value) { - std::string result = SimpleDtoa(value); - return PostProcessFloat(result); -} - -bool InRealOneof(const FieldDescriptor* field) { - return field->containing_oneof() && - !field->containing_oneof()->is_synthetic(); -} - -// Return true if this is an integral field that should be represented as string -// in JS. -bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT64: - case FieldDescriptor::CPPTYPE_UINT64: - // The default value of JSType is JS_NORMAL, which behaves the same as - // JS_NUMBER. - return field->options().jstype() == FieldOptions::JS_STRING; - default: - return false; - } -} - -std::string MaybeNumberString(const FieldDescriptor* field, - const std::string& orig) { - return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig; -} - -std::string JSFieldDefault(const FieldDescriptor* field) { - if (field->is_repeated()) { - return "[]"; - } - - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return MaybeNumberString(field, StrCat(field->default_value_int32())); - case FieldDescriptor::CPPTYPE_UINT32: - // The original codegen is in Java, and Java protobufs store unsigned - // integer values as signed integer values. In order to exactly match the - // output, we need to reinterpret as base-2 signed. Ugh. - return MaybeNumberString( - field, StrCat(static_cast(field->default_value_uint32()))); - case FieldDescriptor::CPPTYPE_INT64: - return MaybeNumberString(field, StrCat(field->default_value_int64())); - case FieldDescriptor::CPPTYPE_UINT64: - // See above note for uint32 -- reinterpreting as signed. - return MaybeNumberString( - field, StrCat(static_cast(field->default_value_uint64()))); - case FieldDescriptor::CPPTYPE_ENUM: - return StrCat(field->default_value_enum()->number()); - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_FLOAT: - return FloatToString(field->default_value_float()); - case FieldDescriptor::CPPTYPE_DOUBLE: - return DoubleToString(field->default_value_double()); - case FieldDescriptor::CPPTYPE_STRING: - if (field->type() == FieldDescriptor::TYPE_STRING) { - std::string out; - bool is_valid = EscapeJSString(field->default_value_string(), &out); - if (!is_valid) { - // TODO(b/115551870): Decide whether this should be a hard error. - GOOGLE_LOG(WARNING) - << "The default value for field " << field->full_name() - << " was truncated since it contained invalid UTF-8 or" - " codepoints outside the basic multilingual plane."; - } - return "\"" + out + "\""; - } else { // Bytes - return "\"" + EscapeBase64(field->default_value_string()) + "\""; - } - case FieldDescriptor::CPPTYPE_MESSAGE: - return "null"; - } - GOOGLE_LOG(FATAL) << "Shouldn't reach here."; - return ""; -} - -std::string ProtoTypeName(const GeneratorOptions& options, - const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_BOOL: - return "bool"; - case FieldDescriptor::TYPE_INT32: - return "int32"; - case FieldDescriptor::TYPE_UINT32: - return "uint32"; - case FieldDescriptor::TYPE_SINT32: - return "sint32"; - case FieldDescriptor::TYPE_FIXED32: - return "fixed32"; - case FieldDescriptor::TYPE_SFIXED32: - return "sfixed32"; - case FieldDescriptor::TYPE_INT64: - return "int64"; - case FieldDescriptor::TYPE_UINT64: - return "uint64"; - case FieldDescriptor::TYPE_SINT64: - return "sint64"; - case FieldDescriptor::TYPE_FIXED64: - return "fixed64"; - case FieldDescriptor::TYPE_SFIXED64: - return "sfixed64"; - case FieldDescriptor::TYPE_FLOAT: - return "float"; - case FieldDescriptor::TYPE_DOUBLE: - return "double"; - case FieldDescriptor::TYPE_STRING: - return "string"; - case FieldDescriptor::TYPE_BYTES: - return "bytes"; - case FieldDescriptor::TYPE_GROUP: - return GetMessagePath(options, field->message_type()); - case FieldDescriptor::TYPE_ENUM: - return GetEnumPath(options, field->enum_type()); - case FieldDescriptor::TYPE_MESSAGE: - return GetMessagePath(options, field->message_type()); - default: - return ""; - } -} - -std::string JSIntegerTypeName(const FieldDescriptor* field) { - return IsIntegralFieldWithStringJSType(field) ? "string" : "number"; -} - -std::string JSStringTypeName(const GeneratorOptions& options, - const FieldDescriptor* field, - BytesMode bytes_mode) { - if (field->type() == FieldDescriptor::TYPE_BYTES) { - switch (bytes_mode) { - case BYTES_DEFAULT: - return "(string|Uint8Array)"; - case BYTES_B64: - return "string"; - case BYTES_U8: - return "Uint8Array"; - default: - assert(false); - } - } - return "string"; -} - -std::string JSTypeName(const GeneratorOptions& options, - const FieldDescriptor* field, BytesMode bytes_mode) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_BOOL: - return "boolean"; - case FieldDescriptor::CPPTYPE_INT32: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_INT64: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_UINT32: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_UINT64: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_FLOAT: - return "number"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return "number"; - case FieldDescriptor::CPPTYPE_STRING: - return JSStringTypeName(options, field, bytes_mode); - case FieldDescriptor::CPPTYPE_ENUM: - return GetEnumPath(options, field->enum_type()); - case FieldDescriptor::CPPTYPE_MESSAGE: - return GetMessagePath(options, field->message_type()); - default: - return ""; - } -} - -// Used inside Google only -- do not remove. -bool UseBrokenPresenceSemantics(const GeneratorOptions& options, - const FieldDescriptor* field) { - return false; -} - -// Returns true for fields that return "null" from accessors when they are -// unset. This should normally only be true for non-repeated submessages, but we -// have legacy users who relied on old behavior where accessors behaved this -// way. -bool ReturnsNullWhenUnset(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - field->is_optional()) { - return true; - } - - // TODO(haberman): remove this case and unconditionally return false. - return UseBrokenPresenceSemantics(options, field) && !field->is_repeated() && - !field->has_default_value(); -} - -// In a sane world, this would be the same as ReturnsNullWhenUnset(). But in -// the status quo, some fields declare that they never return null/undefined -// even though they actually do: -// * required fields -// * optional enum fields -// * proto3 primitive fields. -bool DeclaredReturnTypeIsNullable(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->is_required() || field->type() == FieldDescriptor::TYPE_ENUM) { - return false; - } - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - return false; - } - - return ReturnsNullWhenUnset(options, field); -} - -bool SetterAcceptsUndefined(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (ReturnsNullWhenUnset(options, field)) { - return true; - } - - // Broken presence semantics always accepts undefined for setters. - return UseBrokenPresenceSemantics(options, field); -} - -bool SetterAcceptsNull(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (ReturnsNullWhenUnset(options, field)) { - return true; - } - - // With broken presence semantics, fields with defaults accept "null" for - // setters, but other fields do not. This is a strange quirk of the old - // codegen. - return UseBrokenPresenceSemantics(options, field) && - field->has_default_value(); -} - -// Returns types which are known to by non-nullable by default. -// The style guide requires that we omit "!" in this case. -bool IsPrimitive(const std::string& type) { - return type == "undefined" || type == "string" || type == "number" || - type == "boolean"; -} - -std::string JSFieldTypeAnnotation(const GeneratorOptions& options, - const FieldDescriptor* field, - bool is_setter_argument, bool force_present, - bool singular_if_not_packed, - BytesMode bytes_mode = BYTES_DEFAULT, - bool force_singular = false) { - std::string jstype = JSTypeName(options, field, bytes_mode); - - if (!force_singular && field->is_repeated() && - (field->is_packed() || !singular_if_not_packed)) { - if (field->type() == FieldDescriptor::TYPE_BYTES && - bytes_mode == BYTES_DEFAULT) { - jstype = "(Array|Array)"; - } else { - if (!IsPrimitive(jstype)) { - jstype = "!" + jstype; - } - jstype = "Array<" + jstype + ">"; - } - } - - bool is_null_or_undefined = false; - - if (is_setter_argument) { - if (SetterAcceptsNull(options, field)) { - jstype = "?" + jstype; - is_null_or_undefined = true; - } - - if (SetterAcceptsUndefined(options, field)) { - jstype += "|undefined"; - is_null_or_undefined = true; - } - } else if (force_present) { - // Don't add null or undefined. - } else { - if (DeclaredReturnTypeIsNullable(options, field)) { - jstype = "?" + jstype; - is_null_or_undefined = true; - } - } - - if (!is_null_or_undefined && !IsPrimitive(jstype)) { - jstype = "!" + jstype; - } - - return jstype; -} - -std::string JSBinaryReaderMethodType(const FieldDescriptor* field) { - std::string name = field->type_name(); - if (name[0] >= 'a' && name[0] <= 'z') { - name[0] = (name[0] - 'a') + 'A'; - } - return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name; -} - -std::string JSBinaryReadWriteMethodName(const FieldDescriptor* field, - bool is_writer) { - std::string name = JSBinaryReaderMethodType(field); - if (field->is_packed()) { - name = "Packed" + name; - } else if (is_writer && field->is_repeated()) { - name = "Repeated" + name; - } - return name; -} - -std::string JSBinaryReaderMethodName(const GeneratorOptions& options, - const FieldDescriptor* field) { - return "jspb.BinaryReader.prototype.read" + - JSBinaryReadWriteMethodName(field, /* is_writer = */ false); -} - -std::string JSBinaryWriterMethodName(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->containing_type() && - field->containing_type()->options().message_set_wire_format()) { - return "jspb.BinaryWriter.prototype.writeMessageSet"; - } - return "jspb.BinaryWriter.prototype.write" + - JSBinaryReadWriteMethodName(field, /* is_writer = */ true); -} - -std::string JSTypeTag(const FieldDescriptor* desc) { - switch (desc->type()) { - case FieldDescriptor::TYPE_DOUBLE: - case FieldDescriptor::TYPE_FLOAT: - return "Float"; - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_SFIXED64: - if (IsIntegralFieldWithStringJSType(desc)) { - return "StringInt"; - } else { - return "Int"; - } - case FieldDescriptor::TYPE_BOOL: - return "Boolean"; - case FieldDescriptor::TYPE_STRING: - return "String"; - case FieldDescriptor::TYPE_BYTES: - return "Bytes"; - case FieldDescriptor::TYPE_ENUM: - return "Enum"; - default: - assert(false); - } - return ""; -} - -bool HasRepeatedFields(const GeneratorOptions& options, - const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { - return true; - } - } - return false; -} - -static const char* kRepeatedFieldArrayName = ".repeatedFields_"; - -std::string RepeatedFieldsArrayName(const GeneratorOptions& options, - const Descriptor* desc) { - return HasRepeatedFields(options, desc) - ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName) - : "null"; -} - -bool HasOneofFields(const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (InRealOneof(desc->field(i))) { - return true; - } - } - return false; -} - -static const char* kOneofGroupArrayName = ".oneofGroups_"; - -std::string OneofFieldsArrayName(const GeneratorOptions& options, - const Descriptor* desc) { - return HasOneofFields(desc) - ? (GetMessagePath(options, desc) + kOneofGroupArrayName) - : "null"; -} - -std::string RepeatedFieldNumberList(const GeneratorOptions& options, - const Descriptor* desc) { - std::vector numbers; - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { - numbers.push_back(JSFieldIndex(desc->field(i))); - } - } - return "[" + Join(numbers, ",") + "]"; -} - -std::string OneofGroupList(const Descriptor* desc) { - // List of arrays (one per oneof), each of which is a list of field indices - std::vector oneof_entries; - for (int i = 0; i < desc->oneof_decl_count(); i++) { - const OneofDescriptor* oneof = desc->oneof_decl(i); - if (IgnoreOneof(oneof)) { - continue; - } - - std::vector oneof_fields; - for (int j = 0; j < oneof->field_count(); j++) { - if (IgnoreField(oneof->field(j))) { - continue; - } - oneof_fields.push_back(JSFieldIndex(oneof->field(j))); - } - oneof_entries.push_back("[" + Join(oneof_fields, ",") + "]"); - } - return "[" + Join(oneof_entries, ",") + "]"; -} - -std::string JSOneofArray(const GeneratorOptions& options, - const FieldDescriptor* field) { - return OneofFieldsArrayName(options, field->containing_type()) + "[" + - JSOneofIndex(field->containing_oneof()) + "]"; -} - -std::string RelativeTypeName(const FieldDescriptor* field) { - assert(field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM || - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); - // For a field with an enum or message type, compute a name relative to the - // path name of the message type containing this field. - std::string package = field->file()->package(); - std::string containing_type = field->containing_type()->full_name() + "."; - std::string type = (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) - ? field->enum_type()->full_name() - : field->message_type()->full_name(); - - // |prefix| is advanced as we find separators '.' past the common package - // prefix that yield common prefixes in the containing type's name and this - // type's name. - int prefix = 0; - for (int i = 0; i < type.size() && i < containing_type.size(); i++) { - if (type[i] != containing_type[i]) { - break; - } - if (type[i] == '.' && i >= package.size()) { - prefix = i + 1; - } - } - - return type.substr(prefix); -} - -std::string JSExtensionsObjectName(const GeneratorOptions& options, - const FileDescriptor* from_file, - const Descriptor* desc) { - if (desc->full_name() == "google.protobuf.bridge.MessageSet") { - // TODO(haberman): fix this for the kImportCommonJs case. - return "jspb.Message.messageSetExtensions"; - } else { - return MaybeCrossFileRef(options, from_file, desc) + ".extensions"; - } -} - -static const int kMapKeyField = 1; -static const int kMapValueField = 2; - -const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) { - assert(field->is_map()); - return field->message_type()->FindFieldByNumber(kMapKeyField); -} - -const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) { - assert(field->is_map()); - return field->message_type()->FindFieldByNumber(kMapValueField); -} - -std::string FieldDefinition(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - std::string key_type = ProtoTypeName(options, key_field); - std::string value_type; - if (value_field->type() == FieldDescriptor::TYPE_ENUM || - value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - value_type = RelativeTypeName(value_field); - } else { - value_type = ProtoTypeName(options, value_field); - } - return StringPrintf("map<%s, %s> %s = %d;", key_type.c_str(), - value_type.c_str(), field->name().c_str(), - field->number()); - } else { - std::string qualifier = - field->is_repeated() ? "repeated" - : (field->is_optional() ? "optional" : "required"); - std::string type, name; - if (field->type() == FieldDescriptor::TYPE_ENUM || - field->type() == FieldDescriptor::TYPE_MESSAGE) { - type = RelativeTypeName(field); - name = field->name(); - } else if (field->type() == FieldDescriptor::TYPE_GROUP) { - type = "group"; - name = field->message_type()->name(); - } else { - type = ProtoTypeName(options, field); - name = field->name(); - } - return StringPrintf("%s %s %s = %d;", qualifier.c_str(), type.c_str(), - name.c_str(), field->number()); - } -} - -std::string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) { - std::string comments; - if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) { - comments += - " * Note that Uint8Array is not supported on all browsers.\n" - " * @see http://caniuse.com/Uint8Array\n"; - } - return comments; -} - -bool ShouldGenerateExtension(const FieldDescriptor* field) { - return field->is_extension() && !IgnoreField(field); -} - -bool HasExtensions(const Descriptor* desc) { - for (int i = 0; i < desc->extension_count(); i++) { - if (ShouldGenerateExtension(desc->extension(i))) { - return true; - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (HasExtensions(desc->nested_type(i))) { - return true; - } - } - return false; -} - -bool HasExtensions(const FileDescriptor* file) { - for (int i = 0; i < file->extension_count(); i++) { - if (ShouldGenerateExtension(file->extension(i))) { - return true; - } - } - for (int i = 0; i < file->message_type_count(); i++) { - if (HasExtensions(file->message_type(i))) { - return true; - } - } - return false; -} - -bool HasMap(const GeneratorOptions& options, const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_map()) { - return true; - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (HasMap(options, desc->nested_type(i))) { - return true; - } - } - return false; -} - -bool FileHasMap(const GeneratorOptions& options, const FileDescriptor* desc) { - for (int i = 0; i < desc->message_type_count(); i++) { - if (HasMap(options, desc->message_type(i))) { - return true; - } - } - return false; -} - -bool IsExtendable(const Descriptor* desc) { - return desc->extension_range_count() > 0; -} - -// Returns the max index in the underlying data storage array beyond which the -// extension object is used. -std::string GetPivot(const Descriptor* desc) { - static const int kDefaultPivot = 500; - - // Find the max field number - int max_field_number = 0; - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i)) && - desc->field(i)->number() > max_field_number) { - max_field_number = desc->field(i)->number(); - } - } - - int pivot = -1; - if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) { - pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1) - : kDefaultPivot; - } - - return StrCat(pivot); -} - -// Whether this field represents presence. For fields with presence, we -// generate extra methods (clearFoo() and hasFoo()) for this field. -bool HasFieldPresence(const GeneratorOptions& options, - const FieldDescriptor* field) { - // This returns false for repeated fields and maps, but we still do - // generate clearFoo() methods for these through a special case elsewhere. - return field->has_presence(); -} - -// We use this to implement the semantics that same file can be generated -// multiple times, but only the last one keep the short name. Others all use -// long name with extra information to distinguish (For message and enum, the -// extra information is package name, for file level extension, the extra -// information is proto's filename). -// We never actually write the files, but we keep a set of which descriptors -// were the final one for a given filename. -class FileDeduplicator { - public: - explicit FileDeduplicator(const GeneratorOptions& options) {} - - // params: - // filenames: a pair of {short filename, full filename} - // (short filename don't have extra information, full filename - // contains extra information) - // desc: The Descriptor or SCC pointer or EnumDescriptor. - bool AddFile(const std::pair filenames, - const void* desc) { - if (descs_by_shortname_.find(filenames.first) != - descs_by_shortname_.end()) { - // Change old pointer's actual name to full name. - auto short_name_desc = descs_by_shortname_[filenames.first]; - allowed_descs_actual_name_[short_name_desc] = - allowed_descs_full_name_[short_name_desc]; - } - descs_by_shortname_[filenames.first] = desc; - allowed_descs_actual_name_[desc] = filenames.first; - allowed_descs_full_name_[desc] = filenames.second; - - return true; - } - - void GetAllowedMap(std::map* allowed_set) { - *allowed_set = allowed_descs_actual_name_; - } - - private: - // The map that restores all the descs that are using short name as filename. - std::map descs_by_shortname_; - // The final actual filename map. - std::map allowed_descs_actual_name_; - // The full name map. - std::map allowed_descs_full_name_; -}; - -void DepthFirstSearch(const FileDescriptor* file, - std::vector* list, - std::set* seen) { - if (!seen->insert(file).second) { - return; - } - - // Add all dependencies. - for (int i = 0; i < file->dependency_count(); i++) { - DepthFirstSearch(file->dependency(i), list, seen); - } - - // Add this file. - list->push_back(file); -} - -// A functor for the predicate to remove_if() below. Returns true if a given -// FileDescriptor is not in the given set. -class NotInSet { - public: - explicit NotInSet(const std::set& file_set) - : file_set_(file_set) {} - - bool operator()(const FileDescriptor* file) { - return file_set_.count(file) == 0; - } - - private: - const std::set& file_set_; -}; - -// This function generates an ordering of the input FileDescriptors that matches -// the logic of the old code generator. The order is significant because two -// different input files can generate the same output file, and the last one -// needs to win. -void GenerateJspbFileOrder(const std::vector& input, - std::vector* ordered) { - // First generate an ordering of all reachable files (including dependencies) - // with depth-first search. This mimics the behavior of --include_imports, - // which is what the old codegen used. - ordered->clear(); - std::set seen; - std::set input_set; - for (int i = 0; i < input.size(); i++) { - DepthFirstSearch(input[i], ordered, &seen); - input_set.insert(input[i]); - } - - // Now remove the entries that are not actually in our input list. - ordered->erase( - std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)), - ordered->end()); -} - -// If we're generating code in file-per-type mode, avoid overwriting files -// by choosing the last descriptor that writes each filename and permitting -// only those to generate code. - -struct DepsGenerator { - std::vector operator()(const Descriptor* desc) const { - std::vector deps; - auto maybe_add = [&](const Descriptor* d) { - if (d) deps.push_back(d); - }; - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - maybe_add(desc->field(i)->message_type()); - } - } - for (int i = 0; i < desc->extension_count(); i++) { - maybe_add(desc->extension(i)->message_type()); - maybe_add(desc->extension(i)->containing_type()); - } - for (int i = 0; i < desc->nested_type_count(); i++) { - maybe_add(desc->nested_type(i)); - } - maybe_add(desc->containing_type()); - - return deps; - } -}; - -bool GenerateJspbAllowedMap(const GeneratorOptions& options, - const std::vector& files, - std::map* allowed_set, - SCCAnalyzer* analyzer) { - std::vector files_ordered; - GenerateJspbFileOrder(files, &files_ordered); - - // Choose the last descriptor for each filename. - FileDeduplicator dedup(options); - std::set added; - for (int i = 0; i < files_ordered.size(); i++) { - for (int j = 0; j < files_ordered[i]->message_type_count(); j++) { - const Descriptor* desc = files_ordered[i]->message_type(j); - if (added.insert(analyzer->GetSCC(desc)).second && - !dedup.AddFile( - std::make_pair( - GetMessagesFileName(options, analyzer->GetSCC(desc), false), - GetMessagesFileName(options, analyzer->GetSCC(desc), true)), - analyzer->GetSCC(desc))) { - return false; - } - } - for (int j = 0; j < files_ordered[i]->enum_type_count(); j++) { - const EnumDescriptor* desc = files_ordered[i]->enum_type(j); - if (!dedup.AddFile(std::make_pair(GetEnumFileName(options, desc, false), - GetEnumFileName(options, desc, true)), - desc)) { - return false; - } - } - - // Pull out all free-floating extensions and generate files for those too. - bool has_extension = false; - - for (int j = 0; j < files_ordered[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files_ordered[i]->extension(j))) { - has_extension = true; - } - } - - if (has_extension) { - if (!dedup.AddFile( - std::make_pair( - GetExtensionFileName(options, files_ordered[i], false), - GetExtensionFileName(options, files_ordered[i], true)), - files_ordered[i])) { - return false; - } - } - } - - dedup.GetAllowedMap(allowed_set); - - return true; -} - -// Embeds base64 encoded GeneratedCodeInfo proto in a comment at the end of -// file. -void EmbedCodeAnnotations(const GeneratedCodeInfo& annotations, - io::Printer* printer) { - // Serialize annotations proto into base64 string. - std::string meta_content; - annotations.SerializeToString(&meta_content); - std::string meta_64; - Base64Escape(meta_content, &meta_64); - - // Print base64 encoded annotations at the end of output file in - // a comment. - printer->Print("\n// Below is base64 encoded GeneratedCodeInfo proto"); - printer->Print("\n// $encoded_proto$\n", "encoded_proto", meta_64); -} - -bool IsWellKnownTypeFile(const FileDescriptor* file) { - return HasPrefixString(file->name(), "google/protobuf/"); -} - -} // anonymous namespace - -void Generator::GenerateHeader(const GeneratorOptions& options, - const FileDescriptor* file, - io::Printer* printer) const { - if (file != nullptr) { - printer->Print("// source: $filename$\n", "filename", file->name()); - } - printer->Print( - "/**\n" - " * @fileoverview\n" - " * @enhanceable\n" - // TODO(b/152440355): requireType/requires diverged from internal version. - " * @suppress {missingRequire} reports error on implicit type usages.\n" - " * @suppress {messageConventions} JS Compiler reports an " - "error if a variable or\n" - " * field starts with 'MSG_' and isn't a translatable " - "message.\n" - " * @public\n" - " */\n" - "// GENERATED CODE -- DO NOT EDIT!\n" - "/* eslint-disable */\n" - "// @ts-nocheck\n" - "\n"); -} - -void Generator::FindProvidesForFile(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file, - std::set* provided) const { - for (int i = 0; i < file->message_type_count(); i++) { - FindProvidesForMessage(options, printer, file->message_type(i), provided); - } - for (int i = 0; i < file->enum_type_count(); i++) { - FindProvidesForEnum(options, printer, file->enum_type(i), provided); - } -} - -void Generator::FindProvides(const GeneratorOptions& options, - io::Printer* printer, - const std::vector& files, - std::set* provided) const { - for (int i = 0; i < files.size(); i++) { - FindProvidesForFile(options, printer, files[i], provided); - } - - printer->Print("\n"); -} - -void FindProvidesForOneOfEnum(const GeneratorOptions& options, - const OneofDescriptor* oneof, - std::set* provided) { - std::string name = GetMessagePath(options, oneof->containing_type()) + "." + - JSOneofName(oneof) + "Case"; - provided->insert(name); -} - -void FindProvidesForOneOfEnums(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc, - std::set* provided) { - if (HasOneofFields(desc)) { - for (int i = 0; i < desc->oneof_decl_count(); i++) { - if (IgnoreOneof(desc->oneof_decl(i))) { - continue; - } - FindProvidesForOneOfEnum(options, desc->oneof_decl(i), provided); - } - } -} - -void Generator::FindProvidesForMessage(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc, - std::set* provided) const { - if (IgnoreMessage(desc)) { - return; - } - - std::string name = GetMessagePath(options, desc); - provided->insert(name); - - for (int i = 0; i < desc->enum_type_count(); i++) { - FindProvidesForEnum(options, printer, desc->enum_type(i), provided); - } - - FindProvidesForOneOfEnums(options, printer, desc, provided); - - for (int i = 0; i < desc->nested_type_count(); i++) { - FindProvidesForMessage(options, printer, desc->nested_type(i), provided); - } -} -void Generator::FindProvidesForEnum(const GeneratorOptions& options, - io::Printer* printer, - const EnumDescriptor* enumdesc, - std::set* provided) const { - std::string name = GetEnumPath(options, enumdesc); - provided->insert(name); -} - -void Generator::FindProvidesForFields( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const { - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - - if (IgnoreField(field)) { - continue; - } - - std::string name = GetNamespace(options, field->file()) + "." + - JSObjectFieldName(options, field); - provided->insert(name); - } -} - -void Generator::GenerateProvides(const GeneratorOptions& options, - io::Printer* printer, - std::set* provided) const { - for (std::set::iterator it = provided->begin(); - it != provided->end(); ++it) { - if (options.import_style == GeneratorOptions::kImportClosure) { - printer->Print("goog.provide('$name$');\n", "name", *it); - } else { - // We aren't using Closure's import system, but we use goog.exportSymbol() - // to construct the expected tree of objects, eg. - // - // goog.exportSymbol('foo.bar.Baz', null, this); - // - // // Later generated code expects foo.bar = {} to exist: - // foo.bar.Baz = function() { /* ... */ } - - // Do not use global scope in strict mode - if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - std::string namespaceObject = *it; - // Remove "proto." from the namespace object - GOOGLE_CHECK_EQ(0, namespaceObject.compare(0, 6, "proto.")); - namespaceObject.erase(0, 6); - printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name", - namespaceObject); - } else { - printer->Print("goog.exportSymbol('$name$', null, global);\n", "name", - *it); - } - } - } -} - -void Generator::GenerateRequiresForSCC(const GeneratorOptions& options, - io::Printer* printer, const SCC* scc, - std::set* provided) const { - std::set required; - std::set forwards; - bool have_message = false; - bool has_extension = false; - bool has_map = false; - for (auto desc : scc->descriptors) { - if (desc->containing_type() == nullptr) { - FindRequiresForMessage(options, desc, &required, &forwards, - &have_message); - has_extension = (has_extension || HasExtensions(desc)); - has_map = (has_map || HasMap(options, desc)); - } - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ have_message, - /* require_extension = */ has_extension, - /* require_map = */ has_map); -} - -void Generator::GenerateRequiresForLibrary( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files, - std::set* provided) const { - GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::kImportClosure); - // For Closure imports we need to import every message type individually. - std::set required; - std::set forwards; - bool have_extensions = false; - bool have_map = false; - bool have_message = false; - - for (int i = 0; i < files.size(); i++) { - for (int j = 0; j < files[i]->message_type_count(); j++) { - const Descriptor* desc = files[i]->message_type(j); - if (!IgnoreMessage(desc)) { - FindRequiresForMessage(options, desc, &required, &forwards, - &have_message); - } - } - - if (!have_extensions && HasExtensions(files[i])) { - have_extensions = true; - } - - if (!have_map && FileHasMap(options, files[i])) { - have_map = true; - } - - for (int j = 0; j < files[i]->extension_count(); j++) { - const FieldDescriptor* extension = files[i]->extension(j); - if (IgnoreField(extension)) { - continue; - } - if (extension->containing_type()->full_name() != - "google.protobuf.bridge.MessageSet") { - required.insert(GetMessagePath(options, extension->containing_type())); - } - FindRequiresForField(options, extension, &required, &forwards); - have_extensions = true; - } - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ have_message, - /* require_extension = */ have_extensions, - /* require_map = */ have_map); -} - -void Generator::GenerateRequiresForExtensions( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const { - std::set required; - std::set forwards; - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (IgnoreField(field)) { - continue; - } - FindRequiresForExtension(options, field, &required, &forwards); - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ false, - /* require_extension = */ fields.size() > 0, - /* require_map = */ false); -} - -void Generator::GenerateRequiresImpl(const GeneratorOptions& options, - io::Printer* printer, - std::set* required, - std::set* forwards, - std::set* provided, - bool require_jspb, bool require_extension, - bool require_map) const { - if (require_jspb) { - required->insert("jspb.Message"); - required->insert("jspb.BinaryReader"); - required->insert("jspb.BinaryWriter"); - } - if (require_extension) { - required->insert("jspb.ExtensionFieldBinaryInfo"); - required->insert("jspb.ExtensionFieldInfo"); - } - if (require_map) { - required->insert("jspb.Map"); - } - - std::set::iterator it; - for (it = required->begin(); it != required->end(); ++it) { - if (provided->find(*it) != provided->end()) { - continue; - } - printer->Print("goog.require('$name$');\n", "name", *it); - } - - printer->Print("\n"); - - for (it = forwards->begin(); it != forwards->end(); ++it) { - if (provided->find(*it) != provided->end()) { - continue; - } - printer->Print("goog.forwardDeclare('$name$');\n", "name", *it); - } -} - -bool NamespaceOnly(const Descriptor* desc) { return false; } - -void Generator::FindRequiresForMessage(const GeneratorOptions& options, - const Descriptor* desc, - std::set* required, - std::set* forwards, - bool* have_message) const { - if (!NamespaceOnly(desc)) { - *have_message = true; - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (IgnoreField(field)) { - continue; - } - FindRequiresForField(options, field, required, forwards); - } - } - - for (int i = 0; i < desc->extension_count(); i++) { - const FieldDescriptor* field = desc->extension(i); - if (IgnoreField(field)) { - continue; - } - FindRequiresForExtension(options, field, required, forwards); - } - - for (int i = 0; i < desc->nested_type_count(); i++) { - FindRequiresForMessage(options, desc->nested_type(i), required, forwards, - have_message); - } -} - -void Generator::FindRequiresForField(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && - // N.B.: file-level extensions with enum type do *not* create - // dependencies, as per original codegen. - !(field->is_extension() && field->extension_scope() == nullptr)) { - if (options.add_require_for_enums) { - required->insert(GetEnumPath(options, field->enum_type())); - } else { - forwards->insert(GetEnumPath(options, field->enum_type())); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (!IgnoreMessage(field->message_type())) { - required->insert(GetMessagePath(options, field->message_type())); - } - } -} - -void Generator::FindRequiresForExtension( - const GeneratorOptions& options, const FieldDescriptor* field, - std::set* required, std::set* forwards) const { - if (field->containing_type()->full_name() != - "google.protobuf.bridge.MessageSet") { - required->insert(GetMessagePath(options, field->containing_type())); - } - FindRequiresForField(options, field, required, forwards); -} - -void Generator::GenerateTestOnly(const GeneratorOptions& options, - io::Printer* printer) const { - if (options.testonly) { - printer->Print("goog.setTestOnly();\n\n"); - } - printer->Print("\n"); -} - -void Generator::GenerateClassesAndEnums(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const { - for (int i = 0; i < file->message_type_count(); i++) { - GenerateClassConstructorAndDeclareExtensionFieldInfo(options, printer, - file->message_type(i)); - } - for (int i = 0; i < file->message_type_count(); i++) { - GenerateClass(options, printer, file->message_type(i)); - } - for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnum(options, printer, file->enum_type(i)); - } -} - -void Generator::GenerateClass(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (IgnoreMessage(desc)) { - return; - } - - if (!NamespaceOnly(desc)) { - printer->Print("\n"); - GenerateClassFieldInfo(options, printer, desc); - - GenerateClassToObject(options, printer, desc); - // These must come *before* the extension-field info generation in - // GenerateClassRegistration so that references to the binary - // serialization/deserialization functions may be placed in the extension - // objects. - GenerateClassDeserializeBinary(options, printer, desc); - GenerateClassSerializeBinary(options, printer, desc); - } - - // Recurse on nested types. These must come *before* the extension-field - // info generation in GenerateClassRegistration so that extensions that - // reference nested types proceed the definitions of the nested types. - for (int i = 0; i < desc->enum_type_count(); i++) { - GenerateEnum(options, printer, desc->enum_type(i)); - } - for (int i = 0; i < desc->nested_type_count(); i++) { - GenerateClass(options, printer, desc->nested_type(i)); - } - - if (!NamespaceOnly(desc)) { - GenerateClassRegistration(options, printer, desc); - GenerateClassFields(options, printer, desc); - - if (options.import_style != GeneratorOptions::kImportClosure) { - for (int i = 0; i < desc->extension_count(); i++) { - GenerateExtension(options, printer, desc->extension(i)); - } - } - } -} - -void Generator::GenerateClassConstructor(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "/**\n" - " * Generated by JsPbCodeGenerator.\n" - " * @param {Array=} opt_data Optional initial data array, typically " - "from a\n" - " * server response, or constructed directly in Javascript. The array " - "is used\n" - " * in place and becomes part of the constructed object. It is not " - "cloned.\n" - " * If no data is provided, the constructed object will be empty, but " - "still\n" - " * valid.\n" - " * @extends {jspb.Message}\n" - " * @constructor\n" - " */\n" - "$classprefix$$classname$ = function(opt_data) {\n", - "classprefix", GetMessagePathPrefix(options, desc), "classname", - desc->name()); - printer->Annotate("classname", desc); - std::string message_id = GetMessageId(desc); - printer->Print( - " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, " - "$rptfields$, $oneoffields$);\n", - "messageId", - !message_id.empty() ? ("'" + message_id + "'") - : (IsResponse(desc) ? "''" : "0"), - "pivot", GetPivot(desc), "rptfields", - RepeatedFieldsArrayName(options, desc), "oneoffields", - OneofFieldsArrayName(options, desc)); - printer->Print( - "};\n" - "goog.inherits($classname$, jspb.Message);\n" - "if (goog.DEBUG && !COMPILED) {\n" - // displayName overrides Function.prototype.displayName - // http://google3/javascript/externs/es3.js?l=511 - " /**\n" - " * @public\n" - " * @override\n" - " */\n" - " $classname$.displayName = '$classname$';\n" - "}\n", - "classname", GetMessagePath(options, desc)); -} - -void Generator::GenerateClassConstructorAndDeclareExtensionFieldInfo( - const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const { - if (!NamespaceOnly(desc)) { - GenerateClassConstructor(options, printer, desc); - if (IsExtendable(desc) && - desc->full_name() != "google.protobuf.bridge.MessageSet") { - GenerateClassExtensionFieldInfo(options, printer, desc); - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (!IgnoreMessage(desc->nested_type(i))) { - GenerateClassConstructorAndDeclareExtensionFieldInfo( - options, printer, desc->nested_type(i)); - } - } -} - -void Generator::GenerateClassFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (HasRepeatedFields(options, desc)) { - printer->Print( - "/**\n" - " * List of repeated fields within this message type.\n" - " * @private {!Array}\n" - " * @const\n" - " */\n" - "$classname$$rptfieldarray$ = $rptfields$;\n" - "\n", - "classname", GetMessagePath(options, desc), "rptfieldarray", - kRepeatedFieldArrayName, "rptfields", - RepeatedFieldNumberList(options, desc)); - } - - if (HasOneofFields(desc)) { - printer->Print( - "/**\n" - " * Oneof group definitions for this message. Each group defines the " - "field\n" - " * numbers belonging to that group. When of these fields' value is " - "set, all\n" - " * other fields in the group are cleared. During deserialization, if " - "multiple\n" - " * fields are encountered for a group, only the last value seen will " - "be kept.\n" - " * @private {!Array>}\n" - " * @const\n" - " */\n" - "$classname$$oneofgrouparray$ = $oneofgroups$;\n" - "\n", - "classname", GetMessagePath(options, desc), "oneofgrouparray", - kOneofGroupArrayName, "oneofgroups", OneofGroupList(desc)); - - for (int i = 0; i < desc->oneof_decl_count(); i++) { - if (IgnoreOneof(desc->oneof_decl(i))) { - continue; - } - GenerateOneofCaseDefinition(options, printer, desc->oneof_decl(i)); - } - } -} - -void Generator::GenerateClassXid(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "\n" - "\n" - "$class$.prototype.messageXid = xid('$class$');\n", - "class", GetMessagePath(options, desc)); -} - -void Generator::GenerateOneofCaseDefinition( - const GeneratorOptions& options, io::Printer* printer, - const OneofDescriptor* oneof) const { - printer->Print( - "/**\n" - " * @enum {number}\n" - " */\n" - "$classname$.$oneof$Case = {\n" - " $upcase$_NOT_SET: 0", - "classname", GetMessagePath(options, oneof->containing_type()), "oneof", - JSOneofName(oneof), "upcase", ToEnumCase(oneof->name())); - - for (int i = 0; i < oneof->field_count(); i++) { - if (IgnoreField(oneof->field(i))) { - continue; - } - - printer->Print( - ",\n" - " $upcase$: $number$", - "upcase", ToEnumCase(oneof->field(i)->name()), "number", - JSFieldIndex(oneof->field(i))); - printer->Annotate("upcase", oneof->field(i)); - } - - printer->Print( - "\n" - "};\n" - "\n" - "/**\n" - " * @return {$class$.$oneof$Case}\n" - " */\n" - "$class$.prototype.get$oneof$Case = function() {\n" - " return /** @type {$class$.$oneof$Case} */(jspb.Message." - "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n" - "};\n" - "\n", - "class", GetMessagePath(options, oneof->containing_type()), "oneof", - JSOneofName(oneof), "oneofindex", JSOneofIndex(oneof)); -} - -void Generator::GenerateClassToObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "\n" - "\n" - "if (jspb.Message.GENERATE_TO_OBJECT) {\n" - "/**\n" - " * Creates an object representation of this proto.\n" - " * Field names that are reserved in JavaScript and will be renamed to " - "pb_name.\n" - " * Optional fields that are not set will be set to undefined.\n" - " * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n" - " * For the list of reserved names please see:\n" - " * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n" - " * @param {boolean=} opt_includeInstance Deprecated. whether to include " - "the\n" - " * JSPB instance for transitional soy proto support:\n" - " * http://goto/soy-param-migration\n" - " * @return {!Object}\n" - " */\n" - "$classname$.prototype.toObject = function(opt_includeInstance) {\n" - " return $classname$.toObject(opt_includeInstance, this);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Static version of the {@see toObject} method.\n" - " * @param {boolean|undefined} includeInstance Deprecated. Whether to " - "include\n" - " * the JSPB instance for transitional soy proto support:\n" - " * http://goto/soy-param-migration\n" - " * @param {!$classname$} msg The msg instance to transform.\n" - " * @return {!Object}\n" - " * @suppress {unusedLocalVariables} f is only used for nested messages\n" - " */\n" - "$classname$.toObject = function(includeInstance, msg) {\n" - " var f, obj = {", - "classname", GetMessagePath(options, desc)); - - bool first = true; - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (IgnoreField(field)) { - continue; - } - - if (!first) { - printer->Print(",\n "); - } else { - printer->Print("\n "); - first = false; - } - - GenerateClassFieldToObject(options, printer, field); - } - - if (!first) { - printer->Print("\n };\n\n"); - } else { - printer->Print("\n\n };\n\n"); - } - - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), " - "obj,\n" - " $extObject$, $class$.prototype.getExtension,\n" - " includeInstance);\n", - "extObject", JSExtensionsObjectName(options, desc->file(), desc), - "class", GetMessagePath(options, desc)); - } - - printer->Print( - " if (includeInstance) {\n" - " obj.$$jspbMessageInstance = msg;\n" - " }\n" - " return obj;\n" - "};\n" - "}\n" - "\n" - "\n", - "classname", GetMessagePath(options, desc)); -} - -void Generator::GenerateFieldValueExpression(io::Printer* printer, - const char* obj_reference, - const FieldDescriptor* field, - bool use_default) const { - const bool is_float_or_double = - field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT || - field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE; - const bool is_boolean = field->cpp_type() == FieldDescriptor::CPPTYPE_BOOL; - - const std::string with_default = use_default ? "WithDefault" : ""; - const std::string default_arg = - use_default ? StrCat(", ", JSFieldDefault(field)) : ""; - const std::string cardinality = field->is_repeated() ? "Repeated" : ""; - std::string type = ""; - if (is_float_or_double) { - type = "FloatingPoint"; - } - if (is_boolean) { - type = "Boolean"; - } - - // Prints the appropriate function, among: - // - getField - // - getBooleanField - // - getFloatingPointField => Replaced by getOptionalFloatingPointField to - // preserve backward compatibility. - // - getFieldWithDefault - // - getBooleanFieldWithDefault - // - getFloatingPointFieldWithDefault - // - getRepeatedField - // - getRepeatedBooleanField - // - getRepeatedFloatingPointField - if (is_float_or_double && !field->is_repeated() && !use_default) { - printer->Print( - "jspb.Message.getOptionalFloatingPointField($obj$, " - "$index$$default$)", - "obj", obj_reference, "index", JSFieldIndex(field), "default", - default_arg); - } else { - printer->Print( - "jspb.Message.get$cardinality$$type$Field$with_default$($obj$, " - "$index$$default$)", - "cardinality", cardinality, "type", type, "with_default", with_default, - "obj", obj_reference, "index", JSFieldIndex(field), "default", - default_arg); - } -} - -void Generator::GenerateClassFieldToObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print("$fieldname$: ", "fieldname", - JSObjectFieldName(options, field)); - - if (field->is_map()) { - const FieldDescriptor* value_field = MapFieldValue(field); - // If the map values are of a message type, we must provide their static - // toObject() method; otherwise we pass undefined for that argument. - std::string value_to_object; - if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - value_to_object = - GetMessagePath(options, value_field->message_type()) + ".toObject"; - } else { - value_to_object = "undefined"; - } - printer->Print( - "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) " - ": []", - "name", JSGetterName(options, field), "valuetoobject", value_to_object); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field. - if (field->is_repeated()) { - { - printer->Print( - "jspb.Message.toObjectList(msg.get$getter$(),\n" - " $type$.toObject, includeInstance)", - "getter", JSGetterName(options, field), "type", - SubmessageTypeRef(options, field)); - } - } else { - printer->Print( - "(f = msg.get$getter$()) && " - "$type$.toObject(includeInstance, f)", - "getter", JSGetterName(options, field), "type", - SubmessageTypeRef(options, field)); - } - } else if (field->type() == FieldDescriptor::TYPE_BYTES) { - // For bytes fields we want to always return the B64 data. - printer->Print("msg.get$getter$()", "getter", - JSGetterName(options, field, BYTES_B64)); - } else { - bool use_default = field->has_default_value(); - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - // Repeated fields get initialized to their default in the constructor - // (why?), so we emit a plain getField() call for them. - !field->is_repeated()) { - // Proto3 puts all defaults (including implicit defaults) in toObject(). - // But for proto2 we leave the existing semantics unchanged: unset fields - // without default are unset. - use_default = true; - } - - // We don't implement this by calling the accessors, because the semantics - // of the accessors are changing independently of the toObject() semantics. - // We are migrating the accessors to return defaults instead of null, but - // it may take longer to migrate toObject (or we might not want to do it at - // all). So we want to generate independent code. - // The accessor for unset optional values without default should return - // null. Those are converted to undefined in the generated object. - if (!use_default) { - printer->Print("(f = "); - } - GenerateFieldValueExpression(printer, "msg", field, use_default); - if (!use_default) { - printer->Print(") == null ? undefined : f"); - } - } -} - -void Generator::GenerateObjectTypedef(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // TODO(b/122687752): Consider renaming nested messages called ObjectFormat - // to prevent collisions. - const std::string type_name = GetMessagePath(options, desc) + ".ObjectFormat"; - - printer->Print( - "/**\n" - " * The raw object form of $messageName$ as accepted by the `fromObject` " - "method.\n" - " * @record\n" - " */\n" - "$typeName$ = function() {\n", - "messageName", desc->name(), "typeName", type_name); - - for (int i = 0; i < desc->field_count(); i++) { - if (i > 0) { - printer->Print("\n"); - } - printer->Print( - " /** @type {$fieldType$|undefined} */\n" - " this.$fieldName$;\n", - "fieldName", JSObjectFieldName(options, desc->field(i)), - // TODO(b/121097361): Add type checking for field values. - "fieldType", "?"); - } - - printer->Print("};\n\n"); -} - -void Generator::GenerateClassFromObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print("if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n"); - - GenerateObjectTypedef(options, printer, desc); - - printer->Print( - "/**\n" - " * Loads data from an object into a new instance of this proto.\n" - " * @param {!$classname$.ObjectFormat} obj\n" - " * The object representation of this proto to load the data from.\n" - " * @return {!$classname$}\n" - " */\n" - "$classname$.fromObject = function(obj) {\n" - " var msg = new $classname$();\n", - "classname", GetMessagePath(options, desc)); - - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (!IgnoreField(field)) { - GenerateClassFieldFromObject(options, printer, field); - } - } - - printer->Print( - " return msg;\n" - "};\n" - "}\n\n"); -} - -void Generator::GenerateClassFieldFromObject( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - if (field->is_map()) { - const FieldDescriptor* value_field = MapFieldValue(field); - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - // Since the map values are of message type, we have to do some extra work - // to recursively call fromObject() on them before setting the map field. - printer->Print( - " obj.$name$ && jspb.Message.setWrapperField(\n" - " msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, " - "$fieldclass$.fromObject));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", - GetMessagePath(options, value_field->message_type())); - } else { - // `msg` is a newly-constructed message object that has not yet built any - // map containers wrapping underlying arrays, so we can simply directly - // set the array here without fear of a stale wrapper. - printer->Print( - " obj.$name$ && " - "jspb.Message.setField(msg, $index$, obj.$name$);\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field)); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field (singular or repeated) - if (field->is_repeated()) { - { - printer->Print( - " obj.$name$ && " - "jspb.Message.setRepeatedWrapperField(\n" - " msg, $index$, obj.$name$.map(\n" - " $fieldclass$.fromObject));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", - SubmessageTypeRef(options, field)); - } - } else { - printer->Print( - " obj.$name$ && jspb.Message.setWrapperField(\n" - " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field)); - } - } else { - // Simple (primitive) field. - printer->Print( - " obj.$name$ != null && jspb.Message.setField(msg, $index$, " - "obj.$name$);\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field)); - } -} - -void Generator::GenerateClassRegistration(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // Register any extensions defined inside this message type. - for (int i = 0; i < desc->extension_count(); i++) { - const FieldDescriptor* extension = desc->extension(i); - if (ShouldGenerateExtension(extension)) { - GenerateExtension(options, printer, extension); - } - } -} - -void Generator::GenerateClassFields(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassField(options, printer, desc->field(i)); - } - } -} - -void GenerateBytesWrapper(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field, BytesMode bytes_mode) { - std::string type = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, bytes_mode); - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * This is a type-conversion wrapper around `get$defname$()`\n" - " * @return {$type$}\n" - " */\n" - "$class$.prototype.get$name$ = function() {\n" - " return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n" - " this.get$defname$()));\n" - "};\n" - "\n" - "\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, bytes_mode), "type", type, "class", - GetMessagePath(options, field->containing_type()), "name", - JSGetterName(options, field, bytes_mode), "list", - field->is_repeated() ? "List" : "", "suffix", - JSByteGetterSuffix(bytes_mode), "defname", - JSGetterName(options, field, BYTES_DEFAULT)); -} - -void Generator::GenerateClassField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - // Map field: special handling to instantiate the map object on demand. - std::string key_type = - JSFieldTypeAnnotation(options, key_field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false); - std::string value_type = - JSFieldTypeAnnotation(options, value_field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false); - - printer->Print( - "/**\n" - " * $fielddef$\n" - " * @param {boolean=} opt_noLazyCreate Do not create the map if\n" - " * empty, instead returning `undefined`\n" - " * @return {!jspb.Map<$keytype$,$valuetype$>}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "keytype", key_type, - "valuetype", value_type); - printer->Print( - "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n" - " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n", - "class", GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field), "keytype", key_type, - "valuetype", value_type); - printer->Annotate("gettername", field); - printer->Print( - " jspb.Message.getMapField(this, $index$, opt_noLazyCreate", - "index", JSFieldIndex(field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print( - ",\n" - " $messageType$", - "messageType", GetMessagePath(options, value_field->message_type())); - } else { - printer->Print( - ",\n" - " null"); - } - - printer->Print("));\n"); - - printer->Print( - "};\n" - "\n" - "\n"); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field: special handling in order to wrap the underlying data - // array with a message object. - - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * @return {$type$}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, BYTES_DEFAULT), "type", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false)); - printer->Print( - "$class$.prototype.$gettername$ = function() {\n" - " return /** @type{$type$} */ (\n" - " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, " - "$index$$required$));\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field), "type", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false), - "rpt", (field->is_repeated() ? "Repeated" : ""), "index", - JSFieldIndex(field), "wrapperclass", SubmessageTypeRef(options, field), - "required", - (field->label() == FieldDescriptor::LABEL_REQUIRED ? ", 1" : "")); - printer->Annotate("gettername", field); - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @return {!$class$} returns this\n" - "*/\n" - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.set$oneoftag$$repeatedtag$WrapperField(", - "optionaltype", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ true, - /* force_present = */ false, - /* singular_if_not_packed = */ false), - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "oneoftag", - (InRealOneof(field) ? "Oneof" : ""), "repeatedtag", - (field->is_repeated() ? "Repeated" : "")); - printer->Annotate("settername", field); - - printer->Print( - "this, $index$$oneofgroup$, value);\n" - "};\n" - "\n" - "\n", - "index", JSFieldIndex(field), "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : "")); - - if (field->is_repeated()) { - GenerateRepeatedMessageHelperMethods(options, printer, field); - } - - } else { - bool untyped = false; - - // Simple (primitive) field, either singular or repeated. - - // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type; - // at this point we "lie" to non-binary users and tell the return - // type is always base64 string, pending a LSC to migrate to typed getters. - BytesMode bytes_mode = - field->type() == FieldDescriptor::TYPE_BYTES && !options.binary - ? BYTES_B64 - : BYTES_DEFAULT; - std::string typed_annotation = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, - /* bytes_mode = */ bytes_mode); - if (untyped) { - printer->Print( - "/**\n" - " * @return {?} Raw field, untyped.\n" - " */\n"); - } else { - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * @return {$type$}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, bytes_mode), "type", typed_annotation); - } - - printer->Print("$class$.prototype.$gettername$ = function() {\n", "class", - GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field)); - printer->Annotate("gettername", field); - - if (untyped) { - printer->Print(" return "); - } else { - printer->Print(" return /** @type {$type$} */ (", "type", - typed_annotation); - } - - bool use_default = !ReturnsNullWhenUnset(options, field); - - // Raw fields with no default set should just return undefined. - if (untyped && !field->has_default_value()) { - use_default = false; - } - - // Repeated fields get initialized to their default in the constructor - // (why?), so we emit a plain getField() call for them. - if (field->is_repeated()) { - use_default = false; - } - - GenerateFieldValueExpression(printer, "this", field, use_default); - - if (untyped) { - printer->Print( - ";\n" - "};\n" - "\n" - "\n"); - } else { - printer->Print( - ");\n" - "};\n" - "\n" - "\n"); - } - - if (field->type() == FieldDescriptor::TYPE_BYTES && !untyped) { - GenerateBytesWrapper(options, printer, field, BYTES_B64); - GenerateBytesWrapper(options, printer, field, BYTES_U8); - } - - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @return {!$class$} returns this\n" - " */\n", - "class", GetMessagePath(options, field->containing_type()), - "optionaltype", - untyped ? "*" - : JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ true, - /* force_present = */ false, - /* singular_if_not_packed = */ false)); - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - !field->is_repeated() && !field->is_map() && - !HasFieldPresence(options, field)) { - // Proto3 non-repeated and non-map fields without presence use the - // setProto3*Field function. - printer->Print( - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.setProto3$typetag$Field(this, $index$, " - "value);" - "\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "typetag", - JSTypeTag(field), "index", JSFieldIndex(field)); - printer->Annotate("settername", field); - } else { - // Otherwise, use the regular setField function. - printer->Print( - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.set$oneoftag$Field(this, $index$", - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "oneoftag", - (InRealOneof(field) ? "Oneof" : ""), "index", JSFieldIndex(field)); - printer->Annotate("settername", field); - printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);\n" - "};\n" - "\n" - "\n", - "type", - untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "", - "typeclose", untyped ? ")" : "", "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), - "rptvalueinit", (field->is_repeated() ? " || []" : "")); - } - - if (untyped) { - printer->Print( - "/**\n" - " * Clears the value.\n" - " * @return {!$class$} returns this\n" - " */\n", - "class", GetMessagePath(options, field->containing_type())); - } - - if (field->is_repeated()) { - GenerateRepeatedPrimitiveHelperMethods(options, printer, field, untyped); - } - } - - // Generate clearFoo() method for map fields, repeated fields, and other - // fields with presence. - if (field->is_map()) { - // clang-format off - printer->Print( - "/**\n" - " * Clears values from the map. The map will be non-null.\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " this.$gettername$().clear();\n" - " return this;" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "gettername", "get" + JSGetterName(options, field)); - // clang-format on - printer->Annotate("clearername", field); - } else if (field->is_repeated() || - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_required())) { - // Fields where we can delegate to the regular setter. - // clang-format off - printer->Print( - "/**\n" - " * $jsdoc$\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " return this.$settername$($clearedvalue$);\n" - "};\n" - "\n" - "\n", - "jsdoc", field->is_repeated() - ? "Clears the list making it empty but non-null." - : "Clears the message field making it undefined.", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "settername", "set" + JSGetterName(options, field), - "clearedvalue", (field->is_repeated() ? "[]" : "undefined")); - // clang-format on - printer->Annotate("clearername", field); - } else if (HasFieldPresence(options, field)) { - // Fields where we can't delegate to the regular setter because it doesn't - // accept "undefined" as an argument. - // clang-format off - printer->Print( - "/**\n" - " * Clears the field making it undefined.\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " return jspb.Message.set$maybeoneof$Field(this, " - "$index$$maybeoneofgroup$, ", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "maybeoneof", (InRealOneof(field) ? "Oneof" : ""), - "maybeoneofgroup", (InRealOneof(field) - ? (", " + JSOneofArray(options, field)) - : ""), - "index", JSFieldIndex(field)); - // clang-format on - printer->Annotate("clearername", field); - printer->Print( - "$clearedvalue$);\n" - "};\n" - "\n" - "\n", - "clearedvalue", (field->is_repeated() ? "[]" : "undefined")); - } - - if (HasFieldPresence(options, field)) { - printer->Print( - "/**\n" - " * Returns whether this field is set.\n" - " * @return {boolean}\n" - " */\n" - "$class$.prototype.$hasername$ = function() {\n" - " return jspb.Message.getField(this, $index$) != null;\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), "hasername", - "has" + JSGetterName(options, field), "index", JSFieldIndex(field)); - printer->Annotate("hasername", field); - } -} - -void Generator::GenerateRepeatedPrimitiveHelperMethods( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field, bool untyped) const { - // clang-format off - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @param {number=} opt_index\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$addername$ = function(value, opt_index) {\n" - " return jspb.Message.addToRepeatedField(this, " - "$index$", - "class", GetMessagePath(options, field->containing_type()), "addername", - "add" + JSGetterName(options, field, BYTES_DEFAULT, - /* drop_list = */ true), - "optionaltype", - JSFieldTypeAnnotation( - options, field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false, - BYTES_DEFAULT, - /* force_singular = */ true), - "index", JSFieldIndex(field)); - printer->Annotate("addername", field); - printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, " - "opt_index);\n" - "};\n" - "\n" - "\n", - "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "", - "typeclose", untyped ? ")" : "", "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), - "rptvalueinit", ""); - // clang-format on -} - -void Generator::GenerateRepeatedMessageHelperMethods( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print( - "/**\n" - " * @param {!$optionaltype$=} opt_value\n" - " * @param {number=} opt_index\n" - " * @return {!$optionaltype$}\n" - " */\n" - "$class$.prototype.$addername$ = function(opt_value, opt_index) {\n" - " return jspb.Message.addTo$repeatedtag$WrapperField(", - "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class", - GetMessagePath(options, field->containing_type()), "addername", - "add" + JSGetterName(options, field, BYTES_DEFAULT, - /* drop_list = */ true), - "repeatedtag", (field->is_repeated() ? "Repeated" : "")); - - printer->Annotate("addername", field); - printer->Print( - "this, $index$$oneofgroup$, opt_value, $ctor$, opt_index);\n" - "};\n" - "\n" - "\n", - "index", JSFieldIndex(field), "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "ctor", - GetMessagePath(options, field->message_type())); -} - -void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (IsExtendable(desc)) { - printer->Print( - "\n" - "/**\n" - " * The extensions registered with this message class. This is a " - "map of\n" - " * extension field number to fieldInfo object.\n" - " *\n" - " * For example:\n" - " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, " - "ctor: proto.example.MyMessage} }\n" - " *\n" - " * fieldName contains the JsCompiler renamed field name property " - "so that it\n" - " * works in OPTIMIZED mode.\n" - " *\n" - " * @type {!Object}\n" - " */\n" - "$class$.extensions = {};\n" - "\n", - "class", GetMessagePath(options, desc)); - - printer->Print( - "\n" - "/**\n" - " * The extensions registered with this message class. This is a " - "map of\n" - " * extension field number to fieldInfo object.\n" - " *\n" - " * For example:\n" - " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, " - "ctor: proto.example.MyMessage} }\n" - " *\n" - " * fieldName contains the JsCompiler renamed field name property " - "so that it\n" - " * works in OPTIMIZED mode.\n" - " *\n" - " * @type {!Object}\n" - " */\n" - "$class$.extensionsBinary = {};\n" - "\n", - "class", GetMessagePath(options, desc)); - } -} - -void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // TODO(cfallin): Handle lazy decoding when requested by field option and/or - // by default for 'bytes' fields and packed repeated fields. - - printer->Print( - "/**\n" - " * Deserializes binary data (in protobuf wire format).\n" - " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n" - " * @return {!$class$}\n" - " */\n" - "$class$.deserializeBinary = function(bytes) {\n" - " var reader = new jspb.BinaryReader(bytes);\n" - " var msg = new $class$;\n" - " return $class$.deserializeBinaryFromReader(msg, reader);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Deserializes binary data (in protobuf wire format) from the\n" - " * given reader into the given message object.\n" - " * @param {!$class$} msg The message object to deserialize into.\n" - " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n" - " * @return {!$class$}\n" - " */\n" - "$class$.deserializeBinaryFromReader = function(msg, reader) {\n" - " while (reader.nextField()) {\n", - "class", GetMessagePath(options, desc)); - printer->Print( - " if (reader.isEndGroup()) {\n" - " break;\n" - " }\n" - " var field = reader.getFieldNumber();\n" - " switch (field) {\n"); - - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassDeserializeBinaryField(options, printer, desc->field(i)); - } - } - - printer->Print(" default:\n"); - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.readBinaryExtension(msg, reader,\n" - " $extobj$Binary,\n" - " $class$.prototype.getExtension,\n" - " $class$.prototype.setExtension);\n" - " break;\n" - " }\n", - "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class", - GetMessagePath(options, desc)); - } else { - printer->Print( - " reader.skipField();\n" - " break;\n" - " }\n"); - } - - printer->Print( - " }\n" - " return msg;\n" - "};\n" - "\n" - "\n"); -} - -void Generator::GenerateClassDeserializeBinaryField( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print(" case $num$:\n", "num", StrCat(field->number())); - - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - printer->Print( - " var value = msg.get$name$();\n" - " reader.readMessage(value, function(message, reader) {\n", - "name", JSGetterName(options, field)); - - printer->Print( - " jspb.Map.deserializeBinary(message, reader, " - "$keyReaderFn$, $valueReaderFn$", - "keyReaderFn", JSBinaryReaderMethodName(options, key_field), - "valueReaderFn", JSBinaryReaderMethodName(options, value_field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", $messageType$.deserializeBinaryFromReader", - "messageType", - GetMessagePath(options, value_field->message_type())); - } else { - printer->Print(", null"); - } - printer->Print(", $defaultKey$", "defaultKey", JSFieldDefault(key_field)); - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", new $messageType$()", "messageType", - GetMessagePath(options, value_field->message_type())); - } else { - printer->Print(", $defaultValue$", "defaultValue", - JSFieldDefault(value_field)); - } - printer->Print(");\n"); - printer->Print(" });\n"); - } else { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - " var value = new $fieldclass$;\n" - " reader.read$msgOrGroup$($grpfield$value," - "$fieldclass$.deserializeBinaryFromReader);\n", - "fieldclass", SubmessageTypeRef(options, field), "msgOrGroup", - (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message", - "grpfield", - (field->type() == FieldDescriptor::TYPE_GROUP) - ? (StrCat(field->number()) + ", ") - : ""); - } else if (field->is_packable()) { - printer->Print( - " var values = /** @type {$fieldtype$} */ " - "(reader.isDelimited() " - "? reader.readPacked$reader$() : [reader.read$reader$()]);\n", - "fieldtype", - JSFieldTypeAnnotation(options, field, false, true, - /* singular_if_not_packed */ false, BYTES_U8), - "reader", JSBinaryReaderMethodType(field)); - } else { - printer->Print( - " var value = /** @type {$fieldtype$} */ " - "(reader.read$reader$());\n", - "fieldtype", - JSFieldTypeAnnotation(options, field, false, true, - /* singular_if_not_packed */ true, BYTES_U8), - "reader", - JSBinaryReadWriteMethodName(field, /* is_writer = */ false)); - } - - if (field->is_packable()) { - printer->Print( - " for (var i = 0; i < values.length; i++) {\n" - " msg.add$name$(values[i]);\n" - " }\n", - "name", - JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); - } else if (field->is_repeated()) { - printer->Print( - " msg.add$name$(value);\n", "name", - JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); - } else { - // Singular fields, and packed repeated fields, receive a |value| either - // as the field's value or as the array of all the field's values; set - // this as the field's value directly. - printer->Print(" msg.set$name$(value);\n", "name", - JSGetterName(options, field)); - } - } - - printer->Print(" break;\n"); -} - -void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "/**\n" - " * Serializes the message to binary data (in protobuf wire format).\n" - " * @return {!Uint8Array}\n" - " */\n" - "$class$.prototype.serializeBinary = function() {\n" - " var writer = new jspb.BinaryWriter();\n" - " $class$.serializeBinaryToWriter(this, writer);\n" - " return writer.getResultBuffer();\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Serializes the given message to binary data (in protobuf wire\n" - " * format), writing to the given BinaryWriter.\n" - " * @param {!$class$} message\n" - " * @param {!jspb.BinaryWriter} writer\n" - " * @suppress {unusedLocalVariables} f is only used for nested messages\n" - " */\n" - "$class$.serializeBinaryToWriter = function(message, " - "writer) {\n" - " var f = undefined;\n", - "class", GetMessagePath(options, desc)); - - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassSerializeBinaryField(options, printer, desc->field(i)); - } - } - - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.serializeBinaryExtensions(message, writer,\n" - " $extobj$Binary, $class$.prototype.getExtension);\n", - "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class", - GetMessagePath(options, desc)); - } - - printer->Print( - "};\n" - "\n" - "\n"); -} - -void Generator::GenerateClassSerializeBinaryField( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - if (HasFieldPresence(options, field) && - field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - std::string typed_annotation = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, - /* bytes_mode = */ BYTES_DEFAULT); - printer->Print( - " f = /** @type {$type$} */ " - "(jspb.Message.getField(message, $index$));\n", - "index", JSFieldIndex(field), "type", typed_annotation); - } else { - printer->Print( - " f = message.get$name$($nolazy$);\n", "name", - JSGetterName(options, field, BYTES_U8), - // No lazy creation for maps containers -- fastpath the empty case. - "nolazy", field->is_map() ? "true" : ""); - } - - // Print an `if (condition)` statement that evaluates to true if the field - // goes on the wire. - if (field->is_map()) { - printer->Print(" if (f && f.getLength() > 0) {\n"); - } else if (field->is_repeated()) { - printer->Print(" if (f.length > 0) {\n"); - } else { - if (HasFieldPresence(options, field)) { - printer->Print(" if (f != null) {\n"); - } else { - // No field presence: serialize onto the wire only if value is - // non-default. Defaults are documented here: - // https://goto.google.com/lhdfm - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - case FieldDescriptor::CPPTYPE_INT64: - case FieldDescriptor::CPPTYPE_UINT32: - case FieldDescriptor::CPPTYPE_UINT64: { - if (IsIntegralFieldWithStringJSType(field)) { - // We can use `parseInt` here even though it will not be precise for - // 64-bit quantities because we are only testing for zero/nonzero, - // and JS numbers (64-bit floating point values, i.e., doubles) are - // integer-precise in the range that includes zero. - printer->Print(" if (parseInt(f, 10) !== 0) {\n"); - } else { - printer->Print(" if (f !== 0) {\n"); - } - break; - } - - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_DOUBLE: - printer->Print(" if (f !== 0.0) {\n"); - break; - case FieldDescriptor::CPPTYPE_BOOL: - printer->Print(" if (f) {\n"); - break; - case FieldDescriptor::CPPTYPE_STRING: - printer->Print(" if (f.length > 0) {\n"); - break; - default: - assert(false); - break; - } - } - } - - // Write the field on the wire. - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - printer->Print( - " f.serializeBinary($index$, writer, " - "$keyWriterFn$, $valueWriterFn$", - "index", StrCat(field->number()), "keyWriterFn", - JSBinaryWriterMethodName(options, key_field), "valueWriterFn", - JSBinaryWriterMethodName(options, value_field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", $messageType$.serializeBinaryToWriter", "messageType", - GetMessagePath(options, value_field->message_type())); - } - - printer->Print(");\n"); - } else { - printer->Print( - " writer.write$method$(\n" - " $index$,\n" - " f", - "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true), - "index", StrCat(field->number())); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_map()) { - printer->Print( - ",\n" - " $submsg$.serializeBinaryToWriter\n", - "submsg", SubmessageTypeRef(options, field)); - } else { - printer->Print("\n"); - } - - printer->Print(" );\n"); - } - - // Close the `if`. - printer->Print(" }\n"); -} - -void Generator::GenerateEnum(const GeneratorOptions& options, - io::Printer* printer, - const EnumDescriptor* enumdesc) const { - printer->Print( - "/**\n" - " * @enum {number}\n" - " */\n" - "$enumprefix$$name$ = {\n", - "enumprefix", GetEnumPathPrefix(options, enumdesc), "name", - enumdesc->name()); - printer->Annotate("name", enumdesc); - - std::set used_name; - std::vector valid_index; - for (int i = 0; i < enumdesc->value_count(); i++) { - if (enumdesc->options().allow_alias() && - !used_name.insert(ToEnumCase(enumdesc->value(i)->name())).second) { - continue; - } - valid_index.push_back(i); - } - for (auto i : valid_index) { - const EnumValueDescriptor* value = enumdesc->value(i); - printer->Print(" $name$: $value$$comma$\n", "name", - ToEnumCase(value->name()), "value", StrCat(value->number()), - "comma", (i == valid_index.back()) ? "" : ","); - printer->Annotate("name", value); - } - - printer->Print( - "};\n" - "\n"); -} - -void Generator::GenerateExtension(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - std::string extension_scope = - (field->extension_scope() - ? GetMessagePath(options, field->extension_scope()) - : GetNamespace(options, field->file())); - - const std::string extension_object_name = JSObjectFieldName(options, field); - printer->Print( - "\n" - "/**\n" - " * A tuple of {field number, class constructor} for the extension\n" - " * field named `$nameInComment$`.\n" - " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n" - " */\n" - "$class$.$name$ = new jspb.ExtensionFieldInfo(\n", - "nameInComment", extension_object_name, "name", extension_object_name, - "class", extension_scope, "extensionType", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false)); - printer->Annotate("name", field); - printer->Print( - " $index$,\n" - " {$name$: 0},\n" - " $ctor$,\n" - " /** @type {?function((boolean|undefined),!jspb.Message=): " - "!Object} */ (\n" - " $toObject$),\n" - " $repeated$);\n", - "index", StrCat(field->number()), "name", extension_object_name, "ctor", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE - ? SubmessageTypeRef(options, field) - : std::string("null")), - "toObject", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE - ? (SubmessageTypeRef(options, field) + ".toObject") - : std::string("null")), - "repeated", (field->is_repeated() ? "1" : "0")); - - printer->Print( - "\n" - "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n" - " $class$.$name$,\n" - " $binaryReaderFn$,\n" - " $binaryWriterFn$,\n" - " $binaryMessageSerializeFn$,\n" - " $binaryMessageDeserializeFn$,\n", - "extendName", - JSExtensionsObjectName(options, field->file(), field->containing_type()), - "index", StrCat(field->number()), "class", extension_scope, "name", - extension_object_name, "binaryReaderFn", - JSBinaryReaderMethodName(options, field), "binaryWriterFn", - JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) - ? (SubmessageTypeRef(options, field) + ".serializeBinaryToWriter") - : "undefined", - "binaryMessageDeserializeFn", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) - ? (SubmessageTypeRef(options, field) + ".deserializeBinaryFromReader") - : "undefined"); - - printer->Print(" $isPacked$);\n", "isPacked", - (field->is_packed() ? "true" : "false")); - - printer->Print( - "// This registers the extension field with the extended class, so that\n" - "// toObject() will function correctly.\n" - "$extendName$[$index$] = $class$.$name$;\n" - "\n", - "extendName", - JSExtensionsObjectName(options, field->file(), field->containing_type()), - "index", StrCat(field->number()), "class", extension_scope, "name", - extension_object_name); -} - -bool GeneratorOptions::ParseFromOptions( - const std::vector >& options, - std::string* error) { - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "add_require_for_enums") { - if (options[i].second != "") { - *error = "Unexpected option value for add_require_for_enums"; - return false; - } - add_require_for_enums = true; - } else if (options[i].first == "binary") { - if (options[i].second != "") { - *error = "Unexpected option value for binary"; - return false; - } - binary = true; - } else if (options[i].first == "testonly") { - if (options[i].second != "") { - *error = "Unexpected option value for testonly"; - return false; - } - testonly = true; - - } else if (options[i].first == "error_on_name_conflict") { - GOOGLE_LOG(WARNING) << "Ignoring error_on_name_conflict option, this " - "will be removed in a future release"; - } else if (options[i].first == "output_dir") { - output_dir = options[i].second; - } else if (options[i].first == "namespace_prefix") { - namespace_prefix = options[i].second; - } else if (options[i].first == "library") { - library = options[i].second; - } else if (options[i].first == "import_style") { - if (options[i].second == "closure") { - import_style = kImportClosure; - } else if (options[i].second == "commonjs") { - import_style = kImportCommonJs; - } else if (options[i].second == "commonjs_strict") { - import_style = kImportCommonJsStrict; - } else if (options[i].second == "browser") { - import_style = kImportBrowser; - } else if (options[i].second == "es6") { - import_style = kImportEs6; - } else { - *error = "Unknown import style " + options[i].second + ", expected " + - "one of: closure, commonjs, browser, es6."; - } - } else if (options[i].first == "extension") { - extension = options[i].second; - } else if (options[i].first == "one_output_file_per_input_file") { - if (!options[i].second.empty()) { - *error = "Unexpected option value for one_output_file_per_input_file"; - return false; - } - one_output_file_per_input_file = true; - } else if (options[i].first == "annotate_code") { - if (!options[i].second.empty()) { - *error = "Unexpected option value for annotate_code"; - return false; - } - annotate_code = true; - } else { - // Assume any other option is an output directory, as long as it is a bare - // `key` rather than a `key=value` option. - if (options[i].second != "") { - *error = "Unknown option: " + options[i].first; - return false; - } - output_dir = options[i].first; - } - } - - if (import_style != kImportClosure && - (add_require_for_enums || testonly || !library.empty() || - extension != ".js" || one_output_file_per_input_file)) { - *error = - "The add_require_for_enums, testonly, library, extension, and " - "one_output_file_per_input_file options should only be " - "used for import_style=closure"; - return false; - } - - return true; -} - -GeneratorOptions::OutputMode GeneratorOptions::output_mode() const { - // We use one output file per input file if we are not using Closure or if - // this is explicitly requested. - if (import_style != kImportClosure || one_output_file_per_input_file) { - return kOneOutputFilePerInputFile; - } - - // If a library name is provided, we put everything in that one file. - if (!library.empty()) { - return kEverythingInOneFile; - } - - // Otherwise, we create one output file per SCC. - return kOneOutputFilePerSCC; -} - -void Generator::GenerateFilesInDepOrder( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files) const { - // Build a std::set over all files so that the DFS can detect when it recurses - // into a dep not specified in the user's command line. - std::set all_files(files.begin(), files.end()); - // Track the in-progress set of files that have been generated already. - std::set generated; - for (int i = 0; i < files.size(); i++) { - GenerateFileAndDeps(options, printer, files[i], &all_files, &generated); - } -} - -void Generator::GenerateFileAndDeps( - const GeneratorOptions& options, io::Printer* printer, - const FileDescriptor* root, std::set* all_files, - std::set* generated) const { - // Skip if already generated. - if (generated->find(root) != generated->end()) { - return; - } - generated->insert(root); - - // Generate all dependencies before this file's content. - for (int i = 0; i < root->dependency_count(); i++) { - const FileDescriptor* dep = root->dependency(i); - GenerateFileAndDeps(options, printer, dep, all_files, generated); - } - - // Generate this file's content. Only generate if the file is part of the - // original set requested to be generated; i.e., don't take all transitive - // deps down to the roots. - if (all_files->find(root) != all_files->end()) { - GenerateClassesAndEnums(options, printer, root); - } -} - -bool Generator::GenerateFile(const FileDescriptor* file, - const GeneratorOptions& options, - GeneratorContext* context, - bool use_short_name) const { - std::string filename = - options.output_dir + "/" + - GetJSFilename(options, use_short_name - ? file->name().substr(file->name().rfind('/')) - : file->name()); - std::unique_ptr output(context->Open(filename)); - GOOGLE_CHECK(output); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer(output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateFile(options, &printer, file); - - if (printer.failed()) { - return false; - } - - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - - return true; -} - -void Generator::GenerateFile(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const { - GenerateHeader(options, file, printer); - - // Generate "require" statements. - if ((options.import_style == GeneratorOptions::kImportCommonJs || - options.import_style == GeneratorOptions::kImportCommonJsStrict)) { - printer->Print("var jspb = require('google-protobuf');\n"); - printer->Print("var goog = jspb;\n"); - - // Do not use global scope in strict mode - if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - printer->Print("var proto = {};\n\n"); - } else { - // To get the global object we call a function with .call(null), this will set "this" inside the - // function to the global object. - // This does not work if we are running in strict mode ("use strict"), - // so we fallback to the following things (in order from first to last): - // - window: defined in browsers - // - global: defined in most server side environments like NodeJS - // - self: defined inside Web Workers (WorkerGlobalScope) - // - Function('return this')(): this will work on most platforms, but it may be blocked by things like CSP. - // Function('') is almost the same as eval('') - printer->Print( - "var global = (function() {\n" - " if (this) { return this; }\n" - " if (typeof window !== 'undefined') { return window; }\n" - " if (typeof global !== 'undefined') { return global; }\n" - " if (typeof self !== 'undefined') { return self; }\n" - " return Function('return this')();\n" - "}.call(null));\n\n"); - } - - for (int i = 0; i < file->dependency_count(); i++) { - const std::string& name = file->dependency(i)->name(); - printer->Print( - "var $alias$ = require('$file$');\n" - "goog.object.extend(proto, $alias$);\n", - "alias", ModuleAlias(name), "file", - GetRootPath(file->name(), name) + GetJSFilename(options, name)); - } - } - - std::set provided; - std::set extensions; - for (int i = 0; i < file->extension_count(); i++) { - // We honor the jspb::ignore option here only when working with - // Closure-style imports. Use of this option is discouraged and so we want - // to avoid adding new support for it. - if (options.import_style == GeneratorOptions::kImportClosure && - IgnoreField(file->extension(i))) { - continue; - } - provided.insert(GetNamespace(options, file) + "." + - JSObjectFieldName(options, file->extension(i))); - extensions.insert(file->extension(i)); - } - - FindProvidesForFile(options, printer, file, &provided); - GenerateProvides(options, printer, &provided); - std::vector files; - files.push_back(file); - if (options.import_style == GeneratorOptions::kImportClosure) { - GenerateRequiresForLibrary(options, printer, files, &provided); - } - - GenerateClassesAndEnums(options, printer, file); - - // Generate code for top-level extensions. Extensions nested inside messages - // are emitted inside GenerateClassesAndEnums(). - for (std::set::const_iterator it = extensions.begin(); - it != extensions.end(); ++it) { - GenerateExtension(options, printer, *it); - } - - // if provided is empty, do not export anything - if (options.import_style == GeneratorOptions::kImportCommonJs && - !provided.empty()) { - printer->Print("goog.object.extend(exports, $package$);\n", "package", - GetNamespace(options, file)); - } else if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - printer->Print("goog.object.extend(exports, proto);\n", "package", - GetNamespace(options, file)); - } - - // Emit well-known type methods. - for (FileToc* toc = well_known_types_js; toc->name != NULL; toc++) { - std::string name = std::string("google/protobuf/") + toc->name; - if (name == StripProto(file->name()) + ".js") { - printer->Print(toc->data); - } - } -} - -bool Generator::GenerateAll(const std::vector& files, - const std::string& parameter, - GeneratorContext* context, - std::string* error) const { - std::vector > option_pairs; - ParseGeneratorParameter(parameter, &option_pairs); - GeneratorOptions options; - if (!options.ParseFromOptions(option_pairs, error)) { - return false; - } - - if (options.output_mode() == GeneratorOptions::kEverythingInOneFile) { - // All output should go in a single file. - std::string filename = options.output_dir + "/" + options.library + - options.GetFileNameExtension(); - std::unique_ptr output(context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - // Pull out all extensions -- we need these to generate all - // provides/requires. - std::vector extensions; - for (int i = 0; i < files.size(); i++) { - for (int j = 0; j < files[i]->extension_count(); j++) { - const FieldDescriptor* extension = files[i]->extension(j); - extensions.push_back(extension); - } - } - - if (files.size() == 1) { - GenerateHeader(options, files[0], &printer); - } else { - GenerateHeader(options, nullptr, &printer); - } - - std::set provided; - FindProvides(options, &printer, files, &provided); - FindProvidesForFields(options, &printer, extensions, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForLibrary(options, &printer, files, &provided); - - GenerateFilesInDepOrder(options, &printer, files); - - for (int i = 0; i < extensions.size(); i++) { - if (ShouldGenerateExtension(extensions[i])) { - GenerateExtension(options, &printer, extensions[i]); - } - } - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } else if (options.output_mode() == GeneratorOptions::kOneOutputFilePerSCC) { - std::set have_printed; - SCCAnalyzer analyzer; - std::map allowed_map; - if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer)) { - return false; - } - - bool generated = false; - for (int i = 0; i < files.size(); i++) { - const FileDescriptor* file = files[i]; - // Force well known type to generate in a whole file. - if (IsWellKnownTypeFile(file)) { - if (!GenerateFile(file, options, context, true)) { - return false; - } - generated = true; - continue; - } - for (int j = 0; j < file->message_type_count(); j++) { - const Descriptor* desc = file->message_type(j); - if (have_printed.count(desc) || - allowed_map.count(analyzer.GetSCC(desc)) == 0) { - continue; - } - - generated = true; - const SCC* scc = analyzer.GetSCC(desc); - const std::string& filename = allowed_map[scc]; - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - FindProvidesForMessage(options, &printer, one_desc, &provided); - } - } - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForSCC(options, &printer, scc, &provided); - - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - GenerateClassConstructorAndDeclareExtensionFieldInfo( - options, &printer, one_desc); - } - } - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - GenerateClass(options, &printer, one_desc); - } - } - - for (auto one_desc : scc->descriptors) { - have_printed.insert(one_desc); - } - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - for (int j = 0; j < file->enum_type_count(); j++) { - const EnumDescriptor* enumdesc = file->enum_type(j); - if (allowed_map.count(enumdesc) == 0) { - continue; - } - - generated = true; - const std::string& filename = allowed_map[enumdesc]; - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - FindProvidesForEnum(options, &printer, enumdesc, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - - GenerateEnum(options, &printer, enumdesc); - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - // File-level extensions (message-level extensions are generated under - // the enclosing message). - if (allowed_map.count(file) == 1) { - generated = true; - const std::string& filename = allowed_map[file]; - - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - std::vector fields; - - for (int j = 0; j < files[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files[i]->extension(j))) { - fields.push_back(files[i]->extension(j)); - } - } - - FindProvidesForFields(options, &printer, fields, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForExtensions(options, &printer, fields, &provided); - - for (int j = 0; j < files[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files[i]->extension(j))) { - GenerateExtension(options, &printer, files[i]->extension(j)); - } - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - } - if (!generated) { - std::string filename = options.output_dir + "/" + - "empty_no_content_void_file" + - options.GetFileNameExtension(); - std::unique_ptr output(context->Open(filename)); - } - } else /* options.output_mode() == kOneOutputFilePerInputFile */ { - // Generate one output file per input (.proto) file. - - for (int i = 0; i < files.size(); i++) { - const FileDescriptor* file = files[i]; - if (!GenerateFile(file, options, context, false)) { - return false; - } - } - } - return true; -} - -} // namespace js -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.h b/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.h deleted file mode 100644 index cd9631af..00000000 --- a/third_party/protobuf/src/google/protobuf/compiler/js/js_generator.h +++ /dev/null @@ -1,336 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Generates JavaScript code for a given .proto file. -// -#ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ - -#include -#include - -#include -#include -#include -#include - -#include - -namespace google { -namespace protobuf { - -class Descriptor; -class EnumDescriptor; -class FieldDescriptor; -class OneofDescriptor; -class FileDescriptor; - -namespace io { -class Printer; -} - -namespace compiler { -namespace js { - -struct GeneratorOptions { - // Output path. - std::string output_dir; - // Namespace prefix. - std::string namespace_prefix; - // Enable binary-format support? - bool binary; - // What style of imports should be used. - enum ImportStyle { - kImportClosure, // goog.require() - kImportCommonJs, // require() - kImportCommonJsStrict, // require() with no global export - kImportBrowser, // no import statements - kImportEs6, // import { member } from '' - } import_style; - - GeneratorOptions() - : output_dir("."), - namespace_prefix(""), - binary(false), - import_style(kImportClosure), - add_require_for_enums(false), - testonly(false), - library(""), - extension(".js"), - one_output_file_per_input_file(false), - annotate_code(false) {} - - bool ParseFromOptions( - const std::vector >& options, - std::string* error); - - // Returns the file name extension to use for generated code. - std::string GetFileNameExtension() const { - return import_style == kImportClosure ? extension : "_pb.js"; - } - - enum OutputMode { - // Create an output file for each input .proto file. - kOneOutputFilePerInputFile, - // Create an output file for each type. - kOneOutputFilePerSCC, - // Put everything in a single file named by the library option. - kEverythingInOneFile, - }; - - // Indicates how to output the generated code based on the provided options. - OutputMode output_mode() const; - - // The remaining options are only relevant when we are using kImportClosure. - - // Add a `goog.requires()` call for each enum type used. If not set, a - // forward declaration with `goog.forwardDeclare` is produced instead. - bool add_require_for_enums; - // Set this as a test-only module via `goog.setTestOnly();`. - bool testonly; - // Create a library with name _lib.js rather than a separate .js file - // per type? - std::string library; - // The extension to use for output file names. - std::string extension; - // Create a separate output file for each input file? - bool one_output_file_per_input_file; - // If true, we should append annotations as comments on the last line for - // generated .js file. Annotations used by tools like https://kythe.io - // to provide cross-references between .js and .proto files. Annotations - // are encoded as base64 proto of GeneratedCodeInfo message (see - // descriptor.proto). - bool annotate_code; -}; - -// CodeGenerator implementation which generates a JavaScript source file and -// header. If you create your own protocol compiler binary and you want it to -// support JavaScript output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class PROTOC_EXPORT Generator : public CodeGenerator { - public: - Generator() {} - virtual ~Generator() {} - - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const override { - *error = "Unimplemented Generate() method. Call GenerateAll() instead."; - return false; - } - - bool HasGenerateAll() const override { return true; } - - bool GenerateAll(const std::vector& files, - const std::string& parameter, GeneratorContext* context, - std::string* error) const override; - - uint64 GetSupportedFeatures() const override { - return FEATURE_PROTO3_OPTIONAL; - } - - private: - void GenerateHeader(const GeneratorOptions& options, - const FileDescriptor* file, io::Printer* printer) const; - - // Generate goog.provides() calls. - void FindProvides(const GeneratorOptions& options, io::Printer* printer, - const std::vector& file, - std::set* provided) const; - void FindProvidesForFile(const GeneratorOptions& options, - io::Printer* printer, const FileDescriptor* file, - std::set* provided) const; - void FindProvidesForMessage(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc, - std::set* provided) const; - void FindProvidesForEnum(const GeneratorOptions& options, - io::Printer* printer, const EnumDescriptor* enumdesc, - std::set* provided) const; - // For extension fields at file scope. - void FindProvidesForFields(const GeneratorOptions& options, - io::Printer* printer, - const std::vector& fields, - std::set* provided) const; - // Print the goog.provides() found by the methods above. - void GenerateProvides(const GeneratorOptions& options, io::Printer* printer, - std::set* provided) const; - - // Generate goog.setTestOnly() if indicated. - void GenerateTestOnly(const GeneratorOptions& options, - io::Printer* printer) const; - - // Generate goog.requires() calls. - void GenerateRequiresForLibrary( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files, - std::set* provided) const; - void GenerateRequiresForSCC(const GeneratorOptions& options, - io::Printer* printer, const SCC* scc, - std::set* provided) const; - // For extension fields at file scope. - void GenerateRequiresForExtensions( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const; - void GenerateRequiresImpl(const GeneratorOptions& options, - io::Printer* printer, - std::set* required, - std::set* forwards, - std::set* provided, bool require_jspb, - bool require_extension, bool require_map) const; - void FindRequiresForMessage(const GeneratorOptions& options, - const Descriptor* desc, - std::set* required, - std::set* forwards, - bool* have_message) const; - void FindRequiresForField(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const; - void FindRequiresForExtension(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const; - // Generate all things in a proto file into one file. - // If use_short_name is true, the generated file's name will only be short - // name that without directory, otherwise filename equals file->name() - bool GenerateFile(const FileDescriptor* file, const GeneratorOptions& options, - GeneratorContext* context, bool use_short_name) const; - void GenerateFile(const GeneratorOptions& options, io::Printer* printer, - const FileDescriptor* file) const; - - // Generate definitions for all message classes and enums in all files, - // processing the files in dependence order. - void GenerateFilesInDepOrder( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& file) const; - // Helper for above. - void GenerateFileAndDeps(const GeneratorOptions& options, - io::Printer* printer, const FileDescriptor* root, - std::set* all_files, - std::set* generated) const; - - // Generate definitions for all message classes and enums. - void GenerateClassesAndEnums(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const; - - void GenerateFieldValueExpression(io::Printer* printer, - const char* obj_reference, - const FieldDescriptor* field, - bool use_default) const; - - // Generate definition for one class. - void GenerateClass(const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassConstructor(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassConstructorAndDeclareExtensionFieldInfo( - const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassXid(const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateOneofCaseDefinition(const GeneratorOptions& options, - io::Printer* printer, - const OneofDescriptor* oneof) const; - void GenerateObjectTypedef(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassToObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldToObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassFromObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldFromObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassRegistration(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFields(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc) const; - void GenerateClassField(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* desc) const; - void GenerateClassExtensionFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserialize(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserializeBinaryField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassSerializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassSerializeBinaryField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - - // Generate definition for one enum. - void GenerateEnum(const GeneratorOptions& options, io::Printer* printer, - const EnumDescriptor* enumdesc) const; - - // Generate an extension definition. - void GenerateExtension(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const; - - // Generate addFoo() method for repeated primitive fields. - void GenerateRepeatedPrimitiveHelperMethods(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field, - bool untyped) const; - - // Generate addFoo() method for repeated message fields. - void GenerateRepeatedMessageHelperMethods(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); -}; - -} // namespace js -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.cc b/third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.cc deleted file mode 100644 index 5cb73657..00000000 --- a/third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.cc +++ /dev/null @@ -1,270 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -struct FileToc well_known_types_js[] = { - {"any.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/any.proto. */\n" - "\n" - "/**\n" - " * Returns the type name contained in this instance, if any.\n" - " * @return {string|undefined}\n" - " */\n" - "proto.google.protobuf.Any.prototype.getTypeName = function() {\n" - " return this.getTypeUrl().split('/').pop();\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Packs the given message instance into this Any.\n" - " * For binary format usage only.\n" - " * @param {!Uint8Array} serialized The serialized data to pack.\n" - " * @param {string} name The type name of this message object.\n" - " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n" - " */\n" - "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n" - " opt_typeUrlPrefix) " - "{\n" - " if (!opt_typeUrlPrefix) {\n" - " opt_typeUrlPrefix = 'type.googleapis.com/';\n" - " }\n" - "\n" - " if (opt_typeUrlPrefix.substr(-1) != '/') {\n" - " this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n" - " } else {\n" - " this.setTypeUrl(opt_typeUrlPrefix + name);\n" - " }\n" - "\n" - " this.setValue(serialized);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * @template T\n" - " * Unpacks this Any into the given message object.\n" - " * @param {function(Uint8Array):T} deserialize Function that will " - "deserialize\n" - " * the binary data properly.\n" - " * @param {string} name The expected type name of this message object.\n" - " * @return {?T} If the name matched the expected name, returns the " - "deserialized\n" - " * object, otherwise returns null.\n" - " */\n" - "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) " - "{\n" - " if (this.getTypeName() == name) {\n" - " return deserialize(this.getValue_asU8());\n" - " } else {\n" - " return null;\n" - " }\n" - "};\n" - }, - {"timestamp.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/timestamp.proto. */\n" - "\n" - "/**\n" - " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n" - " * @return {!Date}\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n" - " var seconds = this.getSeconds();\n" - " var nanos = this.getNanos();\n" - "\n" - " return new Date((seconds * 1000) + (nanos / 1000000));\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Sets the value of this Timestamp object to be the given Date.\n" - " * @param {!Date} value The value to set.\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n" - " this.setSeconds(Math.floor(value.getTime() / 1000));\n" - " this.setNanos(value.getMilliseconds() * 1000000);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Factory method that returns a Timestamp object with value equal to\n" - " * the given Date.\n" - " * @param {!Date} value The value to set.\n" - " * @return {!proto.google.protobuf.Timestamp}\n" - " */\n" - "proto.google.protobuf.Timestamp.fromDate = function(value) {\n" - " var timestamp = new proto.google.protobuf.Timestamp();\n" - " timestamp.fromDate(value);\n" - " return timestamp;\n" - "};\n"}, - {"struct.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/struct.proto. */\n" - "\n" - "/**\n" - " * Typedef representing plain JavaScript values that can go into a\n" - " * Struct.\n" - " * @typedef {null|number|string|boolean|Array|Object}\n" - " */\n" - "proto.google.protobuf.JavaScriptValue;\n" - "\n" - "\n" - "/**\n" - " * Converts this Value object to a plain JavaScript value.\n" - " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n" - " * value representing this Struct.\n" - " */\n" - "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n" - " var kindCase = proto.google.protobuf.Value.KindCase;\n" - " switch (this.getKindCase()) {\n" - " case kindCase.NULL_VALUE:\n" - " return null;\n" - " case kindCase.NUMBER_VALUE:\n" - " return this.getNumberValue();\n" - " case kindCase.STRING_VALUE:\n" - " return this.getStringValue();\n" - " case kindCase.BOOL_VALUE:\n" - " return this.getBoolValue();\n" - " case kindCase.STRUCT_VALUE:\n" - " return this.getStructValue().toJavaScript();\n" - " case kindCase.LIST_VALUE:\n" - " return this.getListValue().toJavaScript();\n" - " default:\n" - " throw new Error('Unexpected struct type');\n" - " }\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this JavaScript value to a new Value proto.\n" - " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n" - " * convert.\n" - " * @return {!proto.google.protobuf.Value} The newly constructed value.\n" - " */\n" - "proto.google.protobuf.Value.fromJavaScript = function(value) {\n" - " var ret = new proto.google.protobuf.Value();\n" - " switch (goog.typeOf(value)) {\n" - " case 'string':\n" - " ret.setStringValue(/** @type {string} */ (value));\n" - " break;\n" - " case 'number':\n" - " ret.setNumberValue(/** @type {number} */ (value));\n" - " break;\n" - " case 'boolean':\n" - " ret.setBoolValue(/** @type {boolean} */ (value));\n" - " break;\n" - " case 'null':\n" - " ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n" - " break;\n" - " case 'array':\n" - " ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n" - " /** @type{!Array} */ (value)));\n" - " break;\n" - " case 'object':\n" - " ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n" - " /** @type{!Object} */ (value)));\n" - " break;\n" - " default:\n" - " throw new Error('Unexpected struct type.');\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this ListValue object to a plain JavaScript array.\n" - " * @return {!Array} a plain JavaScript array representing this List.\n" - " */\n" - "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n" - " var ret = [];\n" - " var values = this.getValuesList();\n" - "\n" - " for (var i = 0; i < values.length; i++) {\n" - " ret[i] = values[i].toJavaScript();\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a ListValue protobuf from this plain JavaScript array.\n" - " * @param {!Array} array a plain JavaScript array\n" - " * @return {proto.google.protobuf.ListValue} a new ListValue object\n" - " */\n" - "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n" - " var ret = new proto.google.protobuf.ListValue();\n" - "\n" - " for (var i = 0; i < array.length; i++) {\n" - " " - "ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this Struct object to a plain JavaScript object.\n" - " * @return {!Object} a " - "plain\n" - " * JavaScript object representing this Struct.\n" - " */\n" - "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n" - " var ret = {};\n" - "\n" - " this.getFieldsMap().forEach(function(value, key) {\n" - " ret[key] = value.toJavaScript();\n" - " });\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a Struct protobuf from this plain JavaScript object.\n" - " * @param {!Object} obj a plain JavaScript object\n" - " * @return {proto.google.protobuf.Struct} a new Struct object\n" - " */\n" - "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n" - " var ret = new proto.google.protobuf.Struct();\n" - " var map = ret.getFieldsMap();\n" - "\n" - " for (var property in obj) {\n" - " var val = obj[property];\n" - " map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n" - " }\n" - "\n" - " return ret;\n" - "};\n"}, - {NULL, NULL} // Terminate the list. -}; diff --git a/third_party/protobuf/src/google/protobuf/compiler/main.cc b/third_party/protobuf/src/google/protobuf/compiler/main.cc index 7cb7a637..39609468 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/main.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/main.cc @@ -28,17 +28,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include -#include -#include -#include +#include +#include +#include #include -#include #include #include #include +#include +#include #include +// Must be included last. #include namespace google { @@ -75,6 +76,10 @@ int ProtobufMain(int argc, char* argv[]) { python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, "Generate Python source file."); + // Python pyi + python::PyiGenerator pyi_generator; + cli.RegisterGenerator("--pyi_out", &pyi_generator, + "Generate python pyi stub."); // PHP php::Generator php_generator; @@ -96,11 +101,6 @@ int ProtobufMain(int argc, char* argv[]) { cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator, "Generate Objective-C header and source."); - // JavaScript - js::Generator js_generator; - cli.RegisterGenerator("--js_out", "--js_opt", &js_generator, - "Generate JavaScript source."); - return cli.Run(argc, argv); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc index 1fce1060..4d045114 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc @@ -47,13 +47,13 @@ #include #include #include -#include -#include #include -#include -#include #include #include +#include +#include +#include +#include #ifdef major #undef major @@ -315,7 +315,7 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, io::AnnotationProtoCollector annotation_collector( &annotations); io::Printer printer(output.get(), '$', - annotate ? &annotation_collector : NULL); + annotate ? &annotation_collector : nullptr); printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); std::string annotate_suffix = "_annotation"; if (annotate) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h index 6e101055..45d735a3 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h @@ -78,7 +78,7 @@ namespace compiler { class MockCodeGenerator : public CodeGenerator { public: MockCodeGenerator(const std::string& name); - virtual ~MockCodeGenerator(); + ~MockCodeGenerator() override; // Expect (via gTest) that a MockCodeGenerator with the given name was called // with the given parameters by inspecting the output location. diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index ff69f39f..6e0d69bc 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -34,7 +34,6 @@ #include #include #include -#include namespace google { namespace protobuf { @@ -65,9 +64,8 @@ void SetEnumVariables(const FieldDescriptor* descriptor, } } // namespace -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); } @@ -116,12 +114,16 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // If it is an enum defined in a different file, then we'll need a forward - // declaration for it. When it is in our file, all the enums are output - // before the message, so it will be declared before it is needed. - if (descriptor_->file() != descriptor_->enum_type()->file()) { + std::set* fwd_decls, + bool include_external_types) const { + SingleFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // If it is an enum defined in a different file (and not a WKT), then we'll + // need a forward declaration for it. When it is in our file, all the enums + // are output before the message, so it will be declared before it is needed. + if (include_external_types && + descriptor_->file() != descriptor_->enum_type()->file() && + !IsProtobufLibraryBundledProtoFile(descriptor_->enum_type()->file())) { // Enum name is already in "storage_type". const std::string& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); @@ -129,8 +131,8 @@ void EnumFieldGenerator::DetermineForwardDeclarations( } RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); variables_["array_storage_type"] = "GPBEnumArray"; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 3fb0a9fd..f0d685c3 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); EnumFieldGenerator(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; @@ -53,23 +52,22 @@ class EnumFieldGenerator : public SingleFieldGenerator { virtual void GenerateCFunctionImplementations( io::Printer* printer) const override; virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + explicit EnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~EnumFieldGenerator(); }; class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization() override; protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedEnumFieldGenerator(); }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc index eb23fee1..004ea19f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -37,7 +37,6 @@ #include #include #include -#include #include namespace google { @@ -118,40 +117,39 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } // namespace -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* result = NULL; if (field->is_repeated()) { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { if (field->is_map()) { - result = new MapFieldGenerator(field, options); + result = new MapFieldGenerator(field); } else { - result = new RepeatedMessageFieldGenerator(field, options); + result = new RepeatedMessageFieldGenerator(field); } break; } case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); + result = new RepeatedEnumFieldGenerator(field); break; default: - result = new RepeatedPrimitiveFieldGenerator(field, options); + result = new RepeatedPrimitiveFieldGenerator(field); break; } } else { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); + result = new MessageFieldGenerator(field); break; } case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); + result = new EnumFieldGenerator(field); break; default: if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); + result = new PrimitiveObjFieldGenerator(field); } else { - result = new PrimitiveFieldGenerator(field, options); + result = new PrimitiveFieldGenerator(field); } break; } @@ -160,8 +158,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, return result; } -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetCommonFieldVariables(descriptor, &variables_); } @@ -185,7 +182,8 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls, + bool include_external_types) const { // Nothing } @@ -266,9 +264,8 @@ void FieldGenerator::FinishInitialization(void) { } } -SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { // Nothing } @@ -310,9 +307,8 @@ bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { return true; } -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { variables_["property_storage_attribute"] = "strong"; if (IsRetainedName(variables_["name"])) { variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -353,8 +349,8 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( } RepeatedFieldGenerator::RepeatedFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { // Default to no comment and let the cases needing it fill it in. variables_["array_comment"] = ""; } @@ -407,19 +403,18 @@ bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { return false; // The array (or map/dict) having anything is what is used. } -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_(descriptor->field_count()), extension_generators_(descriptor->extension_count()) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { field_generators_[i].reset( - FieldGenerator::Make(descriptor->field(i), options)); + FieldGenerator::Make(descriptor->field(i))); } for (int i = 0; i < descriptor->extension_count(); i++) { extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); + FieldGenerator::Make(descriptor->extension(i))); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.h index ad8e55ae..759ef808 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -44,8 +43,7 @@ namespace objectivec { class FieldGenerator { public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); + static FieldGenerator* Make(const FieldDescriptor* field); virtual ~FieldGenerator(); @@ -66,7 +64,8 @@ class FieldGenerator { // Exposed for subclasses, should always call it on the parent class also. virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const; + std::set* fwd_decls, + bool include_external_types) const; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const; @@ -96,7 +95,7 @@ class FieldGenerator { std::string raw_field_name() const { return variable("raw_field_name"); } protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + explicit FieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void); bool WantsHasProperty(void) const; @@ -120,8 +119,7 @@ class SingleFieldGenerator : public FieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit SingleFieldGenerator(const FieldDescriptor* descriptor); }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -136,8 +134,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator { virtual void GeneratePropertyDeclaration(io::Printer* printer) const override; protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor); }; class RepeatedFieldGenerator : public ObjCObjFieldGenerator { @@ -155,15 +152,14 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void) override; }; // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + explicit FieldGeneratorMap(const Descriptor* descriptor); ~FieldGeneratorMap(); FieldGeneratorMap(const FieldGeneratorMap&) = delete; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc index d9f43a55..50b4285a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,10 @@ const int32_t GOOGLE_PROTOBUF_OBJC_VERSION = 30004; const char* kHeaderExtension = ".pbobjc.h"; +std::string BundledFileName(const FileDescriptor* file) { + return "GPB" + FilePathBasename(file) + kHeaderExtension; +} + // Checks if a message contains any enums definitions (on the message or // a nested message under it). bool MessageContainsEnums(const Descriptor* message) { @@ -112,46 +117,77 @@ bool FileContainsExtensions(const FileDescriptor* file) { return false; } -// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all -// deps as visited and prunes them from the needed files list. -void PruneFileAndDepsMarkingAsVisited( - const FileDescriptor* file, - std::vector* files, - std::set* files_visited) { - std::vector::iterator iter = - std::find(files->begin(), files->end(), file); - if (iter != files->end()) { - files->erase(iter); - } - files_visited->insert(file); +bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { for (int i = 0; i < file->dependency_count(); i++) { - PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited); + if (dep == file->dependency(i)) { + return true; + } } + return false; } -// Helper for CollectMinimalFileDepsContainingExtensions. -void CollectMinimalFileDepsContainingExtensionsWorker( - const FileDescriptor* file, - std::vector* files, - std::set* files_visited) { - if (files_visited->find(file) != files_visited->end()) { - return; +struct FileDescriptorsOrderedByName { + inline bool operator()(const FileDescriptor* a, + const FileDescriptor* b) const { + return a->name() < b->name(); } - files_visited->insert(file); +}; - if (FileContainsExtensions(file)) { - files->push_back(file); - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - PruneFileAndDepsMarkingAsVisited(dep, files, files_visited); - } - } else { - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - CollectMinimalFileDepsContainingExtensionsWorker(dep, files, - files_visited); +} // namespace + +FileGenerator::CommonState::CommonState() { } + +const FileGenerator::CommonState::MinDepsEntry& +FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal( + const FileDescriptor* file) { + auto it = deps_info_cache_.find(file); + if (it != deps_info_cache_.end()) { + return it->second; + } + + std::set min_deps_collector; + std::set covered_deps_collector; + std::set to_prune; + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dep = file->dependency(i); + MinDepsEntry dep_info = + CollectMinimalFileDepsContainingExtensionsInternal(dep); + + // Everything the dep covered, this file will also cover. + covered_deps_collector.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end()); + // Prune everything from the dep's covered list in case another dep lists it + // as a min dep. + to_prune.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end()); + + // Does the dep have any extensions... + if (dep_info.has_extensions) { + // Yes -> Add this file, prune its min_deps and add them to the covered deps. + min_deps_collector.insert(dep); + to_prune.insert(dep_info.min_deps.begin(), dep_info.min_deps.end()); + covered_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end()); + } else { + // No -> Just use its min_deps. + min_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end()); } } + + const bool file_has_exts = FileContainsExtensions(file); + + // Fast path: if nothing to prune or there was only one dep, the prune work is + // a waste, skip it. + if (to_prune.empty() || file->dependency_count() == 1) { + return deps_info_cache_.insert( + {file, {file_has_exts, min_deps_collector, covered_deps_collector}}).first->second; + } + + std::set min_deps; + std::copy_if(min_deps_collector.begin(), min_deps_collector.end(), + std::inserter(min_deps, min_deps.end()), + [&](const FileDescriptor* value){ + return to_prune.find(value) == to_prune.end(); + }); + return deps_info_cache_.insert( + {file, {file_has_exts, min_deps, covered_deps_collector}}).first->second; } // Collect the deps of the given file that contain extensions. This can be used to @@ -163,40 +199,32 @@ void CollectMinimalFileDepsContainingExtensionsWorker( // There are comments about what the expected code should be line and limited // testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports // specifically). -void CollectMinimalFileDepsContainingExtensions( - const FileDescriptor* file, - std::vector* files) { - std::set files_visited; - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - CollectMinimalFileDepsContainingExtensionsWorker(dep, files, - &files_visited); - } +const std::vector +FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions( + const FileDescriptor* file) { + std::set min_deps = + CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps; + // Sort the list since pointer order isn't stable across runs. + std::vector result(min_deps.begin(), min_deps.end()); + std::sort(result.begin(), result.end(), FileDescriptorsOrderedByName()); + return result; } -bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { - for (int i = 0; i < file->dependency_count(); i++) { - if (dep == file->dependency(i)) { - return true; - } - } - return false; -} - -} // namespace - -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) +FileGenerator::FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options, + CommonState& common_state) : file_(file), + generation_options_(generation_options), + common_state_(common_state), root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { for (int i = 0; i < file_->enum_type_count(); i++) { EnumGenerator* generator = new EnumGenerator(file_->enum_type(i)); enum_generators_.emplace_back(generator); } for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator* generator = - new MessageGenerator(root_class_name_, file_->message_type(i), options_); + new MessageGenerator(root_class_name_, file_->message_type(i)); message_generators_.emplace_back(generator); } for (int i = 0; i < file_->extension_count(); i++) { @@ -216,6 +244,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { headers.push_back("GPBDescriptor.h"); headers.push_back("GPBMessage.h"); headers.push_back("GPBRootObject.h"); + for (int i = 0; i < file_->dependency_count(); i++) { + const std::string header_name = BundledFileName(file_->dependency(i)); + headers.push_back(header_name); + } } else { headers.push_back("GPBProtocolBuffers.h"); } @@ -237,16 +269,26 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "\n", "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); - // #import any headers for "public imports" in the proto file. + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const std::string header_extension(kHeaderExtension); - for (int i = 0; i < file_->public_dependency_count(); i++) { - import_writer.AddFile(file_->public_dependency(i), header_extension); + if (headers_use_forward_declarations) { + // #import any headers for "public imports" in the proto file. + for (int i = 0; i < file_->public_dependency_count(); i++) { + import_writer.AddFile(file_->public_dependency(i), header_extension); + } + } else { + for (int i = 0; i < file_->dependency_count(); i++) { + import_writer.AddFile(file_->dependency(i), header_extension); + } } import_writer.Print(printer); } @@ -266,7 +308,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { std::set fwd_decls; for (const auto& generator : message_generators_) { - generator->DetermineForwardDeclarations(&fwd_decls); + generator->DetermineForwardDeclarations( + &fwd_decls, + /* include_external_types = */ headers_use_forward_declarations); } for (std::set::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { @@ -340,6 +384,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { // #import the runtime support. std::vector headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_) { + headers.push_back(BundledFileName(file_)); + } PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -349,31 +396,37 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "\n"); } - std::vector deps_with_extensions; - CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); + std::vector deps_with_extensions = + common_state_.CollectMinimalFileDepsContainingExtensions(file_); + + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const std::string header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); - // #import the headers for anything that a plain dependency of this proto - // file (that means they were just an include, not a "public" include). - std::set public_import_names; - for (int i = 0; i < file_->public_dependency_count(); i++) { - public_import_names.insert(file_->public_dependency(i)->name()); - } - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor *dep = file_->dependency(i); - bool public_import = (public_import_names.count(dep->name()) != 0); - if (!public_import) { - import_writer.AddFile(dep, header_extension); + if (headers_use_forward_declarations) { + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + std::set public_import_names; + for (int i = 0; i < file_->public_dependency_count(); i++) { + public_import_names.insert(file_->public_dependency(i)->name()); + } + for (int i = 0; i < file_->dependency_count(); i++) { + const FileDescriptor *dep = file_->dependency(i); + bool public_import = (public_import_names.count(dep->name()) != 0); + if (!public_import) { + import_writer.AddFile(dep, header_extension); + } } } @@ -599,8 +652,26 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); + + if (is_bundled_proto_) { + // This is basically a clone of ImportWriter::PrintRuntimeImports() but + // without the CPP symbol gate, since within the bundled files, that isn't + // needed. + std::string import_prefix = generation_options_.runtime_import_prefix; + if (!import_prefix.empty()) { + import_prefix += "/"; + } + for (const auto& header : headers_to_import) { + printer->Print( + "#import \"$import_prefix$$header$\"\n", + "import_prefix", import_prefix, + "header", header); + } + } else { + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, generation_options_.runtime_import_prefix, true); + } + printer->Print("\n"); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.h index 87258a39..ef49cf8a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -31,10 +31,10 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ -#include +#include #include +#include #include -#include #include #include @@ -49,7 +49,40 @@ class MessageGenerator; class FileGenerator { public: - FileGenerator(const FileDescriptor* file, const Options& options); + struct GenerationOptions { + GenerationOptions() + // TODO(thomasvl): Eventually flip this default to false for better + // interop with Swift if proto usages span modules made from ObjC sources. + : headers_use_forward_declarations(true) {} + std::string generate_for_named_framework; + std::string named_framework_to_proto_path_mappings_path; + std::string runtime_import_prefix; + bool headers_use_forward_declarations; + }; + + // Wrapper for some common state that is shared between file generations to + // improve performance when more than one file is generated at a time. + struct CommonState { + CommonState(); + + const std::vector + CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file); + + private: + struct MinDepsEntry { + bool has_extensions; + std::set min_deps; + // `covered_deps` are the transtive deps of `min_deps_w_exts` that also + // have extensions. + std::set covered_deps; + }; + const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(const FileDescriptor* file); + std::map deps_info_cache_; + }; + + FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options, + CommonState& common_state); ~FileGenerator(); FileGenerator(const FileGenerator&) = delete; @@ -60,6 +93,8 @@ class FileGenerator { private: const FileDescriptor* file_; + const GenerationOptions& generation_options_; + CommonState& common_state_; std::string root_class_name_; bool is_bundled_proto_; @@ -67,8 +102,6 @@ class FileGenerator { std::vector> message_generators_; std::vector> extension_generators_; - const Options options_; - void PrintFileRuntimePreamble( io::Printer* printer, const std::vector& headers_to_import) const; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index a03b8604..9dccf149 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -94,7 +94,8 @@ bool ObjectiveCGenerator::GenerateAll( // // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - Options generation_options; + Options validation_options; + FileGenerator::GenerationOptions generation_options; std::vector > options; ParseGeneratorParameter(parameter, &options); @@ -110,17 +111,20 @@ bool ObjectiveCGenerator::GenerateAll( // - Comments start with "#". // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. // // There is no validation that the prefixes are good prefixes, it is // assumed that they are when you create the file. - generation_options.expected_prefixes_path = options[i].second; + validation_options.expected_prefixes_path = options[i].second; } else if (options[i].first == "expected_prefixes_suppressions") { // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. for (StringPiece split_piece : Split( options[i].second, ";", true)) { - generation_options.expected_prefixes_suppressions.push_back( + validation_options.expected_prefixes_suppressions.push_back( std::string(split_piece)); } } else if (options[i].first == "prefixes_must_be_registered") { @@ -132,7 +136,7 @@ bool ObjectiveCGenerator::GenerateAll( // tried to use a prefix that isn't registered. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.prefixes_must_be_registered)) { + &validation_options.prefixes_must_be_registered)) { *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second; return false; } @@ -144,7 +148,7 @@ bool ObjectiveCGenerator::GenerateAll( // raised if a files doesn't have one. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.require_prefixes)) { + &validation_options.require_prefixes)) { *error = "error: Unknown value for require_prefixes: " + options[i].second; return false; } @@ -185,8 +189,22 @@ bool ObjectiveCGenerator::GenerateAll( // generated files. When integrating ObjC protos into a build system, // this can be used to avoid having to add the runtime directory to the // header search path since the generate #import will be more complete. - generation_options.runtime_import_prefix = - StripSuffixString(options[i].second, "/"); + generation_options.runtime_import_prefix = StripSuffixString(options[i].second, "/"); + } else if (options[i].first == "package_to_prefix_mappings_path") { + // Path to use for when loading the objc class prefix mappings to use. + // The `objc_class_prefix` file option is always honored first if one is present. + // This option also has precedent over the use_package_as_prefix option. + // + // The format of the file is: + // - An entry is a line of "package=prefix". + // - Comments start with "#". + // - A comment can go on a line after a expected package/prefix pair. + // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. + // + SetPackageToPrefixMappingsPath(options[i].second); } else if (options[i].first == "use_package_as_prefix") { // Controls how the symbols should be prefixed to avoid symbols // collisions. The objc_class_prefix file option is always honored, this @@ -212,6 +230,12 @@ bool ObjectiveCGenerator::GenerateAll( // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "some.proto.package # comment") SetProtoPackagePrefixExceptionList(options[i].second); + } else if (options[i].first == "headers_use_forward_declarations") { + if (!StringToBool(options[i].second, + &generation_options.headers_use_forward_declarations)) { + *error = "error: Unknown value for headers_use_forward_declarations: " + options[i].second; + return false; + } } else { *error = "error: Unknown generator option: " + options[i].first; return false; @@ -240,14 +264,15 @@ bool ObjectiveCGenerator::GenerateAll( // ----------------------------------------------------------------- // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + if (!ValidateObjCClassPrefixes(files, validation_options, error)) { // *error will have been filled in. return false; } + FileGenerator::CommonState state; for (int i = 0; i < files.size(); i++) { const FileDescriptor* file = files[i]; - FileGenerator file_generator(file, generation_options); + FileGenerator file_generator(file, generation_options, state); std::string filepath = FilePath(file); // Generate header. diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 5f4b7f60..b15f5809 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -73,6 +73,14 @@ using ::open; namespace { +bool BoolFromEnvVar(const char* env_var, bool default_value) { + const char* value = getenv(env_var); + if (value) { + return std::string("YES") == ToUpper(value); + } + return default_value; +} + class SimpleLineCollector : public LineConsumer { public: SimpleLineCollector(std::unordered_set* inout_set) @@ -87,10 +95,31 @@ class SimpleLineCollector : public LineConsumer { std::unordered_set* set_; }; +class PackageToPrefixesCollector : public LineConsumer { + public: + PackageToPrefixesCollector(const std::string &usage, + std::map* inout_package_to_prefix_map) + : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} + + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; + + private: + const std::string usage_; + std::map* prefix_map_; +}; + class PrefixModeStorage { public: PrefixModeStorage(); + const std::string package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } + void set_package_to_prefix_mappings_path(const std::string& path) { + package_to_prefix_mappings_path_ = path; + package_to_prefix_map_.clear(); + } + + std::string prefix_from_proto_package_mappings(const FileDescriptor* file); + bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } @@ -102,9 +131,16 @@ class PrefixModeStorage { bool is_package_exempted(const std::string& package); + // When using a proto package as the prefix, this should be added as the + // prefix in front of it. + const std::string& forced_package_prefix() const { return forced_prefix_; } + private: bool use_package_name_; + std::map package_to_prefix_map_; + std::string package_to_prefix_mappings_path_; std::string exception_path_; + std::string forced_prefix_; std::unordered_set exceptions_; }; @@ -112,14 +148,57 @@ PrefixModeStorage::PrefixModeStorage() { // Even thought there are generation options, have an env back door since some // of these helpers could be used in other plugins. - const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX"); - use_package_name_ = - (use_package_cstr && (std::string("YES") == ToUpper(use_package_cstr))); + use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false); const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH"); if (exception_path) { exception_path_ = exception_path; } + + // This one is a not expected to be common, so it doesn't get a generation + // option, just the env var. + const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX"); + if (prefix) { + forced_prefix_ = prefix; + } +} + +std::string PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) { + if (!file) { + return ""; + } + + if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) { + std::string error_str; + // Re use the same collector as we use for expected_prefixes_path since the file + // format is the same. + PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_); + if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { + if (error_str.empty()) { + error_str = std::string("protoc:0: warning: Failed to parse") + + std::string(" prefix to proto package mappings file: ") + + package_to_prefix_mappings_path_; + } + std::cerr << error_str << std::endl; + std::cerr.flush(); + package_to_prefix_map_.clear(); + } + } + + const std::string package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const std::string no_package_prefix("no_package:"); + const std::string lookup_key = package.empty() ? no_package_prefix + file->name() : package; + + std::map::const_iterator prefix_lookup = + package_to_prefix_map_.find(lookup_key); + + if (prefix_lookup != package_to_prefix_map_.end()) { + return prefix_lookup->second; + } + + return ""; } bool PrefixModeStorage::is_package_exempted(const std::string& package) { @@ -151,6 +230,14 @@ PrefixModeStorage g_prefix_mode; } // namespace +std::string GetPackageToPrefixMappingsPath() { + return g_prefix_mode.package_to_prefix_mappings_path(); +} + +void SetPackageToPrefixMappingsPath(const std::string& file_path) { + g_prefix_mode.set_package_to_prefix_mappings_path(file_path); +} + bool UseProtoPackageAsDefaultPrefix() { return g_prefix_mode.use_package_name(); } @@ -168,7 +255,9 @@ void SetProtoPackagePrefixExceptionList(const std::string& file_path) { } Options::Options() { - // Default is the value of the env for the package prefixes. + // While there are generator options, also support env variables to help with + // build systems where it isn't as easy to hook in for add the generation + // options when invoking protoc. const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); if (file_path) { expected_prefixes_path = file_path; @@ -178,8 +267,9 @@ Options::Options() { expected_prefixes_suppressions = Split(suppressions, ";", true); } - prefixes_must_be_registered = false; - require_prefixes = false; + prefixes_must_be_registered = + BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false); + require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false); } namespace { @@ -352,9 +442,9 @@ bool IsReservedCIdentifier(const std::string& input) { } std::string SanitizeNameForObjC(const std::string& prefix, - const std::string& input, - const std::string& extension, - std::string* out_suffix_added) { + const std::string& input, + const std::string& extension, + std::string* out_suffix_added) { static const std::unordered_set kReservedWords = MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); static const std::unordered_set kNSObjectMethods = @@ -510,8 +600,14 @@ std::string FileClassPrefix(const FileDescriptor* file) { return file->options().objc_class_prefix(); } - // If package prefix isn't enabled or no package, done. - if (!g_prefix_mode.use_package_name() || file->package().empty()) { + // If package prefix is specified in an prefix to proto mappings file then use that. + std::string objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); + if (!objc_class_prefix.empty()) { + return objc_class_prefix; + } + + // If package prefix isn't enabled, done. + if (!g_prefix_mode.use_package_name()) { return ""; } @@ -538,7 +634,7 @@ std::string FileClassPrefix(const FileDescriptor* file) { if (!result.empty()) { result.append("_"); } - return result; + return g_prefix_mode.forced_package_prefix() + result; } std::string FilePath(const FileDescriptor* file) { @@ -1184,23 +1280,11 @@ void RemoveComment(StringPiece* input) { namespace { -class ExpectedPrefixesCollector : public LineConsumer { - public: - ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) - : prefix_map_(inout_package_to_prefix_map) {} - - virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; - - private: - std::map* prefix_map_; -}; - -bool ExpectedPrefixesCollector::ConsumeLine( +bool PackageToPrefixesCollector::ConsumeLine( const StringPiece& line, std::string* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = std::string("Expected prefixes file line without equal sign: '") + - std::string(line) + "'."; + *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1214,16 +1298,16 @@ bool ExpectedPrefixesCollector::ConsumeLine( return true; } -bool LoadExpectedPackagePrefixes(const Options& generation_options, +bool LoadExpectedPackagePrefixes(const std::string& expected_prefixes_path, std::map* prefix_map, std::string* out_error) { - if (generation_options.expected_prefixes_path.empty()) { + if (expected_prefixes_path.empty()) { return true; } - ExpectedPrefixesCollector collector(prefix_map); + PackageToPrefixesCollector collector("Expected prefixes", prefix_map); return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); + expected_prefixes_path, &collector, out_error); } bool ValidateObjCClassPrefix( @@ -1240,6 +1324,11 @@ bool ValidateObjCClassPrefix( const std::string prefix = file->options().objc_class_prefix(); const std::string package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const std::string no_package_prefix("no_package:"); + const std::string lookup_key = + package.empty() ? no_package_prefix + file->name() : package; // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. @@ -1247,7 +1336,7 @@ bool ValidateObjCClassPrefix( // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). std::map::const_iterator package_match = - expected_package_prefixes.find(package); + expected_package_prefixes.find(lookup_key); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... if (has_prefix && package_match->second == prefix) { @@ -1256,8 +1345,11 @@ bool ValidateObjCClassPrefix( } else { // ...it didn't match! *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";' for package '" + package + - "' in '" + file->name() + "'"; + package_match->second + "\";'"; + if (!package.empty()) { + *out_error += " for package '" + package + "'"; + } + *out_error += " in '" + file->name() + "'"; if (has_prefix) { *out_error += "; but found '" + prefix + "' instead"; } @@ -1286,51 +1378,34 @@ bool ValidateObjCClassPrefix( i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; - break; + // Stop on the first real package listing, if it was a no_package file + // specific entry, keep looking to try and find a package one. + if (!HasPrefixString(other_package_for_prefix, no_package_prefix)) { + break; + } } } - // Check: Warning - If the file does not have a package, check whether the - // prefix was declared is being used by another package or not. This is - // a special case for empty packages. - if (package.empty()) { - // The file does not have a package and ... - if (other_package_for_prefix.empty()) { - // ... no other package has declared that prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no " - << "package. Consider adding a new package to the proto and adding '" - << "new.package = " << prefix << "' to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); - } else { - // ... another package has declared the same prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no package " - << "and package '" << other_package_for_prefix << "' already uses '" - << prefix << "' as its prefix. Consider either adding a new package " - << "to the proto, or reusing one of the packages already using this " - << "prefix in the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); - } - return true; - } - // Check: Error - Make sure the prefix wasn't expected for a different // package (overlap is allowed, but it has to be listed as an expected // overlap). if (!other_package_for_prefix.empty()) { *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for 'package " + - other_package_for_prefix + ";'. It can only be reused by listing " + - "it in the expected file (" + - expected_prefixes_path + ")."; + "\";' in '" + file->name() + "'; that prefix is already used for "; + if (HasPrefixString(other_package_for_prefix, no_package_prefix)) { + *out_error += "file '" + + StripPrefixString(other_package_for_prefix, no_package_prefix) + + "'."; + } else { + *out_error += "'package " + other_package_for_prefix + ";'."; + } + *out_error += + " It can only be reused by adding '" + lookup_key + " = " + prefix + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; // Only report first usage of the prefix. } - } // !prefix.empty() + } // !prefix.empty() && have_expected_prefix_file // Check: Warning - Make sure the prefix is is a reasonable value according // to Apple's rules (the checks above implicitly whitelist anything that @@ -1359,17 +1434,18 @@ bool ValidateObjCClassPrefix( if (prefixes_must_be_registered) { *out_error = "error: '" + file->name() + "' has 'option objc_class_prefix = \"" + - prefix + "\";', but it is not registered; add it to the expected " + - "prefixes file (" + expected_prefixes_path + ") for the package '" + - package + "'."; + prefix + "\";', but it is not registered. Add '" + lookup_key + " = " + + (prefix.empty() ? "\"\"" : prefix) + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; } std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " consider adding it to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; + << prefix << "\";' in '" << file->name() << "'; consider adding '" + << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix) + << "' to the expected prefixes file (" << expected_prefixes_path + << ")." << std::endl; std::cerr.flush(); } @@ -1378,6 +1454,13 @@ bool ValidateObjCClassPrefix( } // namespace +bool ValidateObjCClassPrefixes(const std::vector& files, + std::string* out_error) { + // Options's ctor load from the environment. + Options options; + return ValidateObjCClassPrefixes(files, options, out_error); +} + bool ValidateObjCClassPrefixes(const std::vector& files, const Options& generation_options, std::string* out_error) { @@ -1389,7 +1472,7 @@ bool ValidateObjCClassPrefixes(const std::vector& files, // Load the expected package prefixes, if available, to validate against. std::map expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, + if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 13a10524..d21fed21 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -47,6 +47,10 @@ namespace protobuf { namespace compiler { namespace objectivec { +// Get/Set the path to a file to load for objc class prefix lookups. +std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath(); +void PROTOC_EXPORT SetPackageToPrefixMappingsPath( + const std::string& file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -54,20 +58,18 @@ namespace objectivec { bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix(); void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off); // Get/Set the path to a file to load as exceptions when -// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`. -// And empty string means there should be no exceptions loaded. +// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there +// should be no exceptions. std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); void PROTOC_EXPORT SetProtoPackagePrefixExceptionList( const std::string& file_path); -// Generator options (see objectivec_generator.cc for a description of each): +// Generator Prefix Validation Options (see objectivec_generator.cc for a +// description of each): struct Options { Options(); std::string expected_prefixes_path; std::vector expected_prefixes_suppressions; - std::string generate_for_named_framework; - std::string named_framework_to_proto_path_mappings_path; - std::string runtime_import_prefix; bool prefixes_must_be_registered; bool require_prefixes; }; @@ -251,7 +253,11 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // and the result is false. bool PROTOC_EXPORT ValidateObjCClassPrefixes( const std::vector& files, - const Options& generation_options, std::string* out_error); + const Options& validation_options, std::string* out_error); +// Same was the other ValidateObjCClassPrefixes() calls, but the options all +// come from the environment variables. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector& files, std::string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc index 3c5eda22..7ae6a927 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc @@ -30,7 +30,6 @@ #include #include -#include #include namespace google { @@ -154,7 +153,7 @@ TEST(ObjCHelper, TextFormatDecodeData_RawStrings) { EXPECT_EQ(4, decode_data.num_entries()); - uint8 expected_data[] = { + uint8_t expected_data[] = { 0x4, 0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0, 0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0, @@ -179,7 +178,7 @@ TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) { EXPECT_EQ(5, decode_data.num_entries()); - uint8 expected_data[] = { + uint8_t expected_data[] = { 0x5, // All as is (00 op) 0x1, 0x0A, 0x0, diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 746224ff..99d75815 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -81,14 +81,13 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { } // namespace -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { const FieldDescriptor* key_descriptor = descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = descriptor->message_type()->map_value(); - value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); // Pull over some variables_ from the value. variables_["field_type"] = value_field_generator_->variable("field_type"); @@ -153,7 +152,7 @@ void MapFieldGenerator::FinishInitialization(void) { // Use the array_comment support in RepeatedFieldGenerator to output what the // values in the map are. const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { variables_["array_comment"] = "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; @@ -161,11 +160,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); + std::set* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + descriptor_->message_type()->map_value(); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE && + ((include_external_types && + !IsProtobufLibraryBundledProtoFile(value_descriptor->file())) || + descriptor_->file() == value_descriptor->file())) { const std::string& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); @@ -176,7 +183,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { fwd_decls->insert(ObjCClassDeclaration( value_field_generator_->variable("storage_type"))); diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index 84eac618..d9aa3871 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization(void) override; @@ -51,13 +50,14 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + explicit MapFieldGenerator(const FieldDescriptor* descriptor); virtual ~MapFieldGenerator(); virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; private: std::unique_ptr value_field_generator_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 3a00113f..4ebb75c2 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include namespace google { @@ -171,11 +169,10 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } // namespace MessageGenerator::MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, - const Options& options) + const Descriptor* descriptor) : root_classname_(root_classname), descriptor_(descriptor), - field_generators_(descriptor, options), + field_generators_(descriptor), class_name_(ClassName(descriptor_)), deprecated_attribute_(GetOptionalDeprecatedAttribute( descriptor, descriptor->file(), false, true)) { @@ -197,8 +194,7 @@ MessageGenerator::MessageGenerator(const std::string& root_classname, for (int i = 0; i < descriptor_->nested_type_count(); i++) { MessageGenerator* generator = new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); + descriptor_->nested_type(i)); nested_message_generators_.emplace_back(generator); } } @@ -217,17 +213,18 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } void MessageGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) { + std::set* fwd_decls, + bool include_external_types) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); field_generators_.get(fieldDescriptor) - .DetermineForwardDeclarations(fwd_decls); + .DetermineForwardDeclarations(fwd_decls, include_external_types); } } for (const auto& generator : nested_message_generators_) { - generator->DetermineForwardDeclarations(fwd_decls); + generator->DetermineForwardDeclarations(fwd_decls, include_external_types); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.h index 01108d29..9d144309 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,7 @@ class EnumGenerator; class MessageGenerator { public: MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, const Options& options); + const Descriptor* descriptor); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,7 +62,8 @@ class MessageGenerator { void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); - void DetermineForwardDeclarations(std::set* fwd_decls); + void DetermineForwardDeclarations(std::set* fwd_decls, + bool include_external_types); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 299a20b1..2ff0b44a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -34,7 +34,6 @@ #include #include #include -#include namespace google { namespace protobuf { @@ -58,19 +57,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } // namespace -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set* fwd_decls, + bool include_external_types) const { + ObjCObjFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( @@ -79,8 +86,8 @@ void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( } RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = @@ -90,10 +97,19 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 01799a12..49a84fbd 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit MessageFieldGenerator(const FieldDescriptor* descriptor); MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; @@ -55,18 +53,17 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedMessageFieldGenerator(); RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; @@ -74,7 +71,8 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set* fwd_decls) const override; + std::set* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const override; }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index e198c5c1..1fefde5f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -35,8 +35,6 @@ #include #include #include -#include -#include namespace google { namespace protobuf { @@ -125,8 +123,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } // namespace PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); } @@ -159,8 +157,8 @@ void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { } PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); variables_["property_storage_attribute"] = "copy"; } @@ -168,8 +166,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); std::string base_name = PrimitiveArrayTypeName(descriptor); diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h index a9f30f64..06a1528a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h @@ -31,8 +31,6 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ -#include -#include #include namespace google { @@ -41,12 +39,10 @@ namespace compiler { namespace objectivec { class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveFieldGenerator(); PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; @@ -59,12 +55,10 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator { }; class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveObjFieldGenerator(); PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; @@ -73,12 +67,10 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedPrimitiveFieldGenerator(); RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser.cc b/third_party/protobuf/src/google/protobuf/compiler/parser.cc index 49ddfceb..5bd37d14 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/parser.cc @@ -46,11 +46,11 @@ #include #include #include +#include +#include #include #include -#include #include -#include #include #include @@ -64,32 +64,33 @@ namespace { typedef std::unordered_map TypeNameMap; -TypeNameMap MakeTypeNameTable() { - TypeNameMap result; +const TypeNameMap& GetTypeNameTable() { + static auto* table = new auto([]() { + TypeNameMap result; - result["double"] = FieldDescriptorProto::TYPE_DOUBLE; - result["float"] = FieldDescriptorProto::TYPE_FLOAT; - result["uint64"] = FieldDescriptorProto::TYPE_UINT64; - result["fixed64"] = FieldDescriptorProto::TYPE_FIXED64; - result["fixed32"] = FieldDescriptorProto::TYPE_FIXED32; - result["bool"] = FieldDescriptorProto::TYPE_BOOL; - result["string"] = FieldDescriptorProto::TYPE_STRING; - result["group"] = FieldDescriptorProto::TYPE_GROUP; + result["double"] = FieldDescriptorProto::TYPE_DOUBLE; + result["float"] = FieldDescriptorProto::TYPE_FLOAT; + result["uint64"] = FieldDescriptorProto::TYPE_UINT64; + result["fixed64"] = FieldDescriptorProto::TYPE_FIXED64; + result["fixed32"] = FieldDescriptorProto::TYPE_FIXED32; + result["bool"] = FieldDescriptorProto::TYPE_BOOL; + result["string"] = FieldDescriptorProto::TYPE_STRING; + result["group"] = FieldDescriptorProto::TYPE_GROUP; - result["bytes"] = FieldDescriptorProto::TYPE_BYTES; - result["uint32"] = FieldDescriptorProto::TYPE_UINT32; - result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32; - result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64; - result["int32"] = FieldDescriptorProto::TYPE_INT32; - result["int64"] = FieldDescriptorProto::TYPE_INT64; - result["sint32"] = FieldDescriptorProto::TYPE_SINT32; - result["sint64"] = FieldDescriptorProto::TYPE_SINT64; + result["bytes"] = FieldDescriptorProto::TYPE_BYTES; + result["uint32"] = FieldDescriptorProto::TYPE_UINT32; + result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32; + result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64; + result["int32"] = FieldDescriptorProto::TYPE_INT32; + result["int64"] = FieldDescriptorProto::TYPE_INT64; + result["sint32"] = FieldDescriptorProto::TYPE_SINT32; + result["sint64"] = FieldDescriptorProto::TYPE_SINT64; - return result; + return result; + }()); + return *table; } -const TypeNameMap kTypeNames = MakeTypeNameTable(); - // Camel-case the field name and append "Entry" for generated map entry name. // e.g. map foo_map => FooMapEntry std::string MapEntryName(const std::string& field_name) { @@ -180,9 +181,9 @@ bool IsNumberFollowUnderscore(const std::string& name) { // =================================================================== Parser::Parser() - : input_(NULL), - error_collector_(NULL), - source_location_table_(NULL), + : input_(nullptr), + error_collector_(nullptr), + source_location_table_(nullptr), had_errors_(false), require_syntax_identifier_(false), stop_after_syntax_identifier_(false) { @@ -221,12 +222,8 @@ bool Parser::Consume(const char* text, const char* error) { } bool Parser::Consume(const char* text) { - if (TryConsume(text)) { - return true; - } else { - AddError("Expected \"" + std::string(text) + "\"."); - return false; - } + std::string error = "Expected \"" + std::string(text) + "\"."; + return Consume(text, error.c_str()); } bool Parser::ConsumeIdentifier(std::string* output, const char* error) { @@ -347,7 +344,7 @@ bool Parser::TryConsumeEndOfDeclaration(const char* text, // from last time. leading.swap(upcoming_doc_comments_); - if (location != NULL) { + if (location != nullptr) { upcoming_detached_comments_.swap(detached); location->AttachComments(&leading, &trailing, &detached); } else if (strcmp(text, "}") == 0) { @@ -380,7 +377,7 @@ bool Parser::ConsumeEndOfDeclaration(const char* text, // ------------------------------------------------------------------- void Parser::AddError(int line, int column, const std::string& error) { - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(line, column, error); } had_errors_ = true; @@ -473,7 +470,7 @@ void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { void Parser::LocationRecorder::RecordLegacyLocation( const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location) { - if (parser_->source_location_table_ != NULL) { + if (parser_->source_location_table_ != nullptr) { parser_->source_location_table_->Add( descriptor, location, location_->span(0), location_->span(1)); } @@ -516,7 +513,7 @@ void Parser::SkipStatement() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -534,7 +531,7 @@ void Parser::SkipRestOfBlock() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration("}", NULL)) { + if (TryConsumeEndOfDeclaration("}", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -628,7 +625,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } @@ -644,7 +641,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { return false; } // Store the syntax into the file. - if (file != NULL) file->set_syntax(syntax_identifier_); + if (file != nullptr) file->set_syntax(syntax_identifier_); } else if (!stop_after_syntax_identifier_) { GOOGLE_LOG(WARNING) << "No syntax specified for the proto file: " << file->name() << ". Please use 'syntax = \"proto2\";' " @@ -664,16 +661,16 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAt("}")) { AddError("Unmatched \"}\"."); - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } } } } - input_ = NULL; - source_code_info_ = NULL; - assert(file != NULL); + input_ = nullptr; + source_code_info_ = nullptr; + assert(file != nullptr); source_code_info.Swap(file->mutable_source_code_info()); return !had_errors_; } @@ -706,7 +703,7 @@ bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) { bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, const LocationRecorder& root_location) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -862,7 +859,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &message_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in message definition (missing '}')."); return false; @@ -887,7 +884,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, bool Parser::ParseMessageStatement(DescriptorProto* message, const LocationRecorder& message_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -945,7 +942,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, const FileDescriptorProto* containing_file) { { FieldDescriptorProto::Label label; - if (ParseLabel(&label, field_location, containing_file)) { + if (ParseLabel(&label, field_location)) { field->set_label(label); if (label == FieldDescriptorProto::LABEL_OPTIONAL && syntax_identifier_ == "proto3") { @@ -980,37 +977,14 @@ bool Parser::ParseMessageFieldNoLabel( if (TryConsume("map")) { if (LookingAt("<")) { map_field.is_map_field = true; + DO(ParseMapType(&map_field, field, location)); } else { // False positive type_parsed = true; type_name = "map"; } } - if (map_field.is_map_field) { - if (field->has_oneof_index()) { - AddError("Map fields are not allowed in oneofs."); - return false; - } - if (field->has_label()) { - AddError( - "Field labels (required/optional/repeated) are not allowed on " - "map fields."); - return false; - } - if (field->has_extendee()) { - AddError("Map fields are not allowed to be extensions."); - return false; - } - field->set_label(FieldDescriptorProto::LABEL_REPEATED); - DO(Consume("<")); - DO(ParseType(&map_field.key_type, &map_field.key_type_name)); - DO(Consume(",")); - DO(ParseType(&map_field.value_type, &map_field.value_type_name)); - DO(Consume(">")); - // Defer setting of the type name of the map field until the - // field name is parsed. Add the source location though. - location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); - } else { + if (!map_field.is_map_field) { // Handle the case where no explicit label is given for a non-map field. if (!field->has_label() && DefaultToOptionalFields()) { field->set_label(FieldDescriptorProto::LABEL_OPTIONAL); @@ -1022,8 +996,8 @@ bool Parser::ParseMessageFieldNoLabel( field->set_label(FieldDescriptorProto::LABEL_OPTIONAL); } - // Handle the case where the actual type is a message or enum named "map", - // which we already consumed in the code above. + // Handle the case where the actual type is a message or enum named + // "map", which we already consumed in the code above. if (!type_parsed) { DO(ParseType(&type, &type_name)); } @@ -1131,6 +1105,34 @@ bool Parser::ParseMessageFieldNoLabel( return true; } +bool Parser::ParseMapType(MapField* map_field, FieldDescriptorProto* field, + LocationRecorder& type_name_location) { + if (field->has_oneof_index()) { + AddError("Map fields are not allowed in oneofs."); + return false; + } + if (field->has_label()) { + AddError( + "Field labels (required/optional/repeated) are not allowed on " + "map fields."); + return false; + } + if (field->has_extendee()) { + AddError("Map fields are not allowed to be extensions."); + return false; + } + field->set_label(FieldDescriptorProto::LABEL_REPEATED); + DO(Consume("<")); + DO(ParseType(&map_field->key_type, &map_field->key_type_name)); + DO(Consume(",")); + DO(ParseType(&map_field->value_type, &map_field->value_type_name)); + DO(Consume(">")); + // Defer setting of the type name of the map field until the + // field name is parsed. Add the source location though. + type_name_location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); + return true; +} + void Parser::GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field, RepeatedPtrField* messages) { @@ -1458,7 +1460,7 @@ bool Parser::ParseOption(Message* options, // Create an entry in the uninterpreted_option field. const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(uninterpreted_option_field != NULL) + GOOGLE_CHECK(uninterpreted_option_field != nullptr) << "No field named \"uninterpreted_option\" in the Options proto."; const Reflection* reflection = options->GetReflection(); @@ -1906,7 +1908,7 @@ bool Parser::ParseExtend(RepeatedPtrField* extensions, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -1970,7 +1972,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -2003,7 +2005,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &enum_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in enum definition (missing '}')."); return false; @@ -2022,7 +2024,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, const LocationRecorder& enum_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2120,7 +2122,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &service_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in service definition (missing '}')."); return false; @@ -2139,7 +2141,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, const LocationRecorder& service_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2177,7 +2179,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); method->set_client_streaming(true); DO(Consume("stream")); - } LocationRecorder location(method_location, MethodDescriptorProto::kInputTypeFieldNumber); @@ -2198,7 +2199,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); DO(Consume("stream")); method->set_server_streaming(true); - } LocationRecorder location(method_location, MethodDescriptorProto::kOutputTypeFieldNumber); @@ -2226,13 +2226,13 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, Message* mutable_options) { // Options! ConsumeEndOfDeclaration("{", &parent_location); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in method options (missing '}')."); return false; } - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore } else { LocationRecorder location(parent_location, optionsFieldNumber); @@ -2251,8 +2251,7 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, // ------------------------------------------------------------------- bool Parser::ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { + const LocationRecorder& field_location) { if (!LookingAt("optional") && !LookingAt("repeated") && !LookingAt("required")) { return false; @@ -2272,8 +2271,9 @@ bool Parser::ParseLabel(FieldDescriptorProto::Label* label, bool Parser::ParseType(FieldDescriptorProto::Type* type, std::string* type_name) { - TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); - if (iter != kTypeNames.end()) { + const auto& type_names_table = GetTypeNameTable(); + auto iter = type_names_table.find(input_->current().text); + if (iter != type_names_table.end()) { *type = iter->second; input_->Next(); } else { @@ -2285,8 +2285,9 @@ bool Parser::ParseType(FieldDescriptorProto::Type* type, bool Parser::ParseUserDefinedType(std::string* type_name) { type_name->clear(); - TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); - if (iter != kTypeNames.end()) { + const auto& type_names_table = GetTypeNameTable(); + auto iter = type_names_table.find(input_->current().text); + if (iter != type_names_table.end()) { // Note: The only place enum types are allowed is for field types, but // if we are parsing a field type then we would not get here because // primitives are allowed there as well. So this error message doesn't @@ -2396,7 +2397,7 @@ bool SourceLocationTable::Find( int* column) const { const std::pair* result = FindOrNull(location_map_, std::make_pair(descriptor, location)); - if (result == NULL) { + if (result == nullptr) { *line = -1; *column = 0; return false; diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser.h b/third_party/protobuf/src/google/protobuf/compiler/parser.h index b5a5df89..d4eb7630 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser.h +++ b/third_party/protobuf/src/google/protobuf/compiler/parser.h @@ -42,9 +42,9 @@ #include #include +#include #include #include -#include #include // Must be included last. @@ -122,6 +122,7 @@ class PROTOBUF_EXPORT Parser { private: class LocationRecorder; + struct MapField; // ================================================================= // Error recovery helpers @@ -281,9 +282,6 @@ class PROTOBUF_EXPORT Parser { std::vector* detached_comments) const; private: - // Indexes of parent and current location in the parent - // SourceCodeInfo.location repeated field. For top-level elements, - // parent_index_ is -1. Parser* parser_; SourceCodeInfo* source_code_info_; SourceCodeInfo::Location* location_; @@ -381,6 +379,9 @@ class PROTOBUF_EXPORT Parser { const LocationRecorder& field_location, const FileDescriptorProto* containing_file); + bool ParseMapType(MapField* map_field, FieldDescriptorProto* field, + LocationRecorder& type_name_location); + // Parse an "extensions" declaration. bool ParseExtensions(DescriptorProto* message, const LocationRecorder& extensions_location, @@ -434,7 +435,6 @@ class PROTOBUF_EXPORT Parser { const LocationRecorder& method_location, const FileDescriptorProto* containing_file); - // Parse options of a single method or stream. bool ParseMethodOptions(const LocationRecorder& parent_location, const FileDescriptorProto* containing_file, @@ -444,8 +444,7 @@ class PROTOBUF_EXPORT Parser { // Parse "required", "optional", or "repeated" and fill in "label" // with the value. Returns true if such a label is consumed. bool ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file); + const LocationRecorder& field_location); // Parse a type name and fill in "type" (if it is a primitive) or // "type_name" (if it is not) with the type parsed. @@ -485,7 +484,7 @@ class PROTOBUF_EXPORT Parser { // Parses a single part of a multipart option name. A multipart name consists // of names separated by dots. Each name is either an identifier or a series // of identifiers separated by dots and enclosed in parentheses. E.g., - // "foo.(bar.baz).qux". + // "foo.(bar.baz).moo". bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option, const LocationRecorder& part_location, const FileDescriptorProto* containing_file); diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc index 6973bc99..2d681d95 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc @@ -83,7 +83,7 @@ class MockValidationErrorCollector : public DescriptorPool::ErrorCollector { io::ErrorCollector* wrapped_collector) : source_locations_(source_locations), wrapped_collector_(wrapped_collector) {} - ~MockValidationErrorCollector() {} + ~MockValidationErrorCollector() override {} // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, const std::string& element_name, @@ -173,7 +173,7 @@ class ParserTest : public testing::Test { MockValidationErrorCollector validation_error_collector(source_locations, &error_collector_); EXPECT_TRUE(pool_.BuildFileCollectingErrors( - file, &validation_error_collector) == NULL); + file, &validation_error_collector) == nullptr); EXPECT_EQ(expected_errors, error_collector_.text_); } @@ -194,7 +194,7 @@ TEST_F(ParserTest, StopAfterSyntaxIdentifier) { "syntax = \"foobar\";\n" "this line will not be parsed\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_TRUE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("", error_collector_.text_); EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier()); } @@ -204,7 +204,7 @@ TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) { "// blah\n" "this line will not be parsed\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_TRUE(parser_->Parse(input_.get(), NULL)); + EXPECT_TRUE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("", error_collector_.text_); EXPECT_EQ("", parser_->GetSyntaxIdentifier()); } @@ -214,7 +214,7 @@ TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) { "// blah\n" "syntax = error;\n"); parser_->SetStopAfterSyntaxIdentifier(true); - EXPECT_FALSE(parser_->Parse(input_.get(), NULL)); + EXPECT_FALSE(parser_->Parse(input_.get(), nullptr)); EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_); } @@ -1792,7 +1792,7 @@ TEST_F(ParserValidationErrorTest, PackageNameError) { FileDescriptorProto other_file; other_file.set_name("bar.proto"); other_file.add_message_type()->set_name("foo"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // Now try to define it as a package. ExpectHasValidationErrors( @@ -1861,7 +1861,8 @@ TEST_F(ParserValidationErrorTest, FieldNumberError) { "message Foo {\n" " optional int32 bar = 0;\n" "}\n", - "1:23: Field numbers must be positive integers.\n"); + "1:23: Field numbers must be positive integers.\n" + "1:23: Suggested field numbers for Foo: 1\n"); } TEST_F(ParserValidationErrorTest, FieldExtendeeError) { @@ -1926,7 +1927,8 @@ TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) { "message Foo {\n" " extensions 0;\n" "}\n", - "1:13: Extension numbers must be positive integers.\n"); + "1:13: Extension numbers must be positive integers.\n" + "1:13: Suggested field numbers for Foo: 1\n"); } TEST_F(ParserValidationErrorTest, Proto3ExtensionError) { @@ -2071,7 +2073,7 @@ TEST_F(ParserValidationErrorTest, ResolvedUndefinedError) { other_file.set_name("base.proto"); other_file.set_package("base"); other_file.add_message_type()->set_name("bar"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // Define "foo.base" and try "base.bar". // "base.bar" is resolved to "foo.base.bar" which is not defined. @@ -2092,7 +2094,7 @@ TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) { // Build descriptor message in test pool FileDescriptorProto descriptor_proto; DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto); - ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != nullptr); // base2.proto: // package baz @@ -2121,7 +2123,7 @@ TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) { extension->set_type_name("Bar"); extension->set_extendee("google.protobuf.FileOptions"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); + EXPECT_TRUE(pool_.BuildFile(other_file) != nullptr); // qux.proto: // package qux.baz @@ -2228,17 +2230,17 @@ TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) { protobuf_unittest_import::PublicImportMessage::descriptor()->file(); FileDescriptorProto public_import_proto; public_import->CopyTo(&public_import_proto); - ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(public_import_proto) != nullptr); const FileDescriptor* import = protobuf_unittest_import::ImportMessage::descriptor()->file(); FileDescriptorProto import_proto; import->CopyTo(&import_proto); - ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(import_proto) != nullptr); const FileDescriptor* actual = pool_.BuildFile(parsed); parsed.Clear(); - ASSERT_TRUE(actual != NULL) << "Failed to validate:\n" << debug_string; + ASSERT_TRUE(actual != nullptr) << "Failed to validate:\n" << debug_string; actual->CopyTo(&parsed); - ASSERT_TRUE(actual != NULL); + ASSERT_TRUE(actual != nullptr); // The messages might be in different orders, making them hard to compare. // So, sort the messages in the descriptor protos (including nested messages, @@ -2276,14 +2278,14 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { const FileDescriptor* import = FileDescriptorProto::descriptor()->file(); FileDescriptorProto import_proto; import->CopyTo(&import_proto); - ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + ASSERT_TRUE(pool_.BuildFile(import_proto) != nullptr); FileDescriptorProto any_import; google::protobuf::Any::descriptor()->file()->CopyTo(&any_import); ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr); const FileDescriptor* actual = pool_.BuildFile(parsed); - ASSERT_TRUE(actual != NULL); + ASSERT_TRUE(actual != nullptr); parsed.Clear(); actual->CopyTo(&parsed); @@ -2365,7 +2367,7 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) { MockValidationErrorCollector collector(source_locations, &error_collector_); const FileDescriptor* descriptor = pool_.BuildFileCollectingErrors(parsed_desc, &collector); - ASSERT_TRUE(descriptor != NULL); + ASSERT_TRUE(descriptor != nullptr); // Ensure that each of the comments appears somewhere in the DebugString(). // We don't test the exact comment placement or formatting, because we do not @@ -2429,7 +2431,7 @@ TEST_F(ParseDescriptorDebugTest, TestMaps) { EXPECT_TRUE(parser_->Parse(input_.get(), &original)); original.set_name("foo.proto"); const FileDescriptor* file = pool_.BuildFile(original); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); // Make sure the debug string uses map syntax and does not have the auto // generated entry. @@ -2466,13 +2468,15 @@ TEST_F(ParseDescriptorDebugTest, TestMaps) { // *output_field to the descriptor of the field, and *output_index to -1. // Returns true if the path was valid, false otherwise. A gTest failure is // recorded before returning false. -bool FollowPath(const Message& root, const int* path_begin, const int* path_end, +bool FollowPath(const Message& root, + RepeatedField::const_iterator path_begin, + RepeatedField::const_iterator path_end, const Message** output_message, const FieldDescriptor** output_field, int* output_index) { if (path_begin == path_end) { // Path refers to this whole message. *output_message = &root; - *output_field = NULL; + *output_field = nullptr; *output_index = -1; return true; } @@ -2482,7 +2486,7 @@ bool FollowPath(const Message& root, const int* path_begin, const int* path_end, const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin); - if (field == NULL) { + if (field == nullptr) { ADD_FAILURE() << descriptor->name() << " has no field number: " << *path_begin; return false; @@ -2573,8 +2577,8 @@ class SourceInfoTest : public ParserTest { const SourceCodeInfo& source_info = file_.source_code_info(); for (int i = 0; i < source_info.location_size(); i++) { const SourceCodeInfo::Location& location = source_info.location(i); - const Message* descriptor_proto = NULL; - const FieldDescriptor* field = NULL; + const Message* descriptor_proto = nullptr; + const FieldDescriptor* field = nullptr; int index = 0; if (!FollowPath(file_, location.path().begin(), location.path().end(), &descriptor_proto, &field, &index)) { @@ -2601,8 +2605,8 @@ class SourceInfoTest : public ParserTest { bool HasSpan(char start_marker, char end_marker, const Message& descriptor_proto) { - return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL, - -1, NULL, NULL, NULL); + return HasSpanWithComment(start_marker, end_marker, descriptor_proto, + nullptr, -1, nullptr, nullptr, nullptr); } bool HasSpanWithComment(char start_marker, char end_marker, @@ -2610,8 +2614,8 @@ class SourceInfoTest : public ParserTest { const char* expected_leading_comments, const char* expected_trailing_comments, const char* expected_leading_detached_comments) { - return HasSpanWithComment(start_marker, end_marker, descriptor_proto, NULL, - -1, expected_leading_comments, + return HasSpanWithComment(start_marker, end_marker, descriptor_proto, + nullptr, -1, expected_leading_comments, expected_trailing_comments, expected_leading_detached_comments); } @@ -2625,7 +2629,7 @@ class SourceInfoTest : public ParserTest { const Message& descriptor_proto, const std::string& field_name, int index) { return HasSpan(start_marker, end_marker, descriptor_proto, field_name, - index, NULL, NULL, NULL); + index, nullptr, nullptr, nullptr); } bool HasSpan(char start_marker, char end_marker, @@ -2635,7 +2639,7 @@ class SourceInfoTest : public ParserTest { const char* expected_leading_detached_comments) { const FieldDescriptor* field = descriptor_proto.GetDescriptor()->FindFieldByName(field_name); - if (field == NULL) { + if (field == nullptr) { ADD_FAILURE() << descriptor_proto.GetDescriptor()->name() << " has no such field: " << field_name; return false; @@ -2648,8 +2652,8 @@ class SourceInfoTest : public ParserTest { } bool HasSpan(const Message& descriptor_proto) { - return HasSpanWithComment('\0', '\0', descriptor_proto, NULL, -1, NULL, - NULL, NULL); + return HasSpanWithComment('\0', '\0', descriptor_proto, nullptr, -1, + nullptr, nullptr, nullptr); } bool HasSpan(const Message& descriptor_proto, const std::string& field_name) { @@ -2686,21 +2690,21 @@ class SourceInfoTest : public ParserTest { for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) { if (CompareSpans(expected_span, iter->second->span())) { - if (expected_leading_comments == NULL) { + if (expected_leading_comments == nullptr) { EXPECT_FALSE(iter->second->has_leading_comments()); } else { EXPECT_TRUE(iter->second->has_leading_comments()); EXPECT_EQ(expected_leading_comments, iter->second->leading_comments()); } - if (expected_trailing_comments == NULL) { + if (expected_trailing_comments == nullptr) { EXPECT_FALSE(iter->second->has_trailing_comments()); } else { EXPECT_TRUE(iter->second->has_trailing_comments()); EXPECT_EQ(expected_trailing_comments, iter->second->trailing_comments()); } - if (expected_leading_detached_comments == NULL) { + if (expected_leading_detached_comments == nullptr) { EXPECT_EQ(0, iter->second->leading_detached_comments_size()); } else { EXPECT_EQ( @@ -3496,7 +3500,7 @@ TEST_F(SourceInfoTest, DocComments) { const FieldDescriptorProto& bar = foo.field(0); EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n", - " Foo trailing\n line 2\n", NULL)); + " Foo trailing\n line 2\n", nullptr)); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", " bar trailing\n", " detached\n")); @@ -3572,7 +3576,7 @@ TEST_F(SourceInfoTest, DocComments3) { const FieldDescriptorProto& bar = foo.field(0); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", - " bar trailing\n", NULL)); + " bar trailing\n", nullptr)); // Ignore these. EXPECT_TRUE(HasSpan(file_)); @@ -3655,7 +3659,7 @@ TEST_F(SourceInfoTest, DocCommentsOneof) { const FieldDescriptorProto& bar_int = foo.field(0); EXPECT_TRUE(HasSpanWithComment('a', 'f', foo, " Foo leading\n", - " Foo trailing\n", NULL)); + " Foo trailing\n", nullptr)); EXPECT_TRUE(HasSpanWithComment('b', 'e', bar, " bar leading\n line 2 ", " bar trailing\n line 2 ", " detached before oneof\n")); diff --git a/third_party/protobuf/src/google/protobuf/compiler/php/php_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/php/php_generator.cc index 05f8acad..f3aa92f1 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/php/php_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/php/php_generator.cc @@ -48,28 +48,29 @@ const std::string kDescriptorMetadataFile = const std::string kDescriptorDirName = "Google/Protobuf/Internal"; const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal"; const char* const kReservedNames[] = { - "abstract", "and", "array", "as", "break", - "callable", "case", "catch", "class", "clone", - "const", "continue", "declare", "default", "die", - "do", "echo", "else", "elseif", "empty", - "enddeclare", "endfor", "endforeach", "endif", "endswitch", - "endwhile", "eval", "exit", "extends", "final", - "finally", "fn", "for", "foreach", "function", - "global", "goto", "if", "implements", "include", - "include_once", "instanceof", "insteadof", "interface", "isset", - "list", "match", "namespace", "new", "or", - "print", "private", "protected", "public", "require", - "require_once", "return", "static", "switch", "throw", - "trait", "try", "unset", "use", "var", - "while", "xor", "yield", "int", "float", - "bool", "string", "true", "false", "null", - "void", "iterable"}; + "abstract", "and", "array", "as", "break", + "callable", "case", "catch", "class", "clone", + "const", "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", "empty", + "enddeclare", "endfor", "endforeach", "endif", "endswitch", + "endwhile", "eval", "exit", "extends", "final", + "finally", "fn", "for", "foreach", "function", + "global", "goto", "if", "implements", "include", + "include_once", "instanceof", "insteadof", "interface", "isset", + "list", "match", "namespace", "new", "or", + "parent", "print", "private", "protected", "public", + "readonly", "require", "require_once", "return", "self", + "static", "switch", "throw", "trait", "try", + "unset", "use", "var", "while", "xor", + "yield", "int", "float", "bool", "string", + "true", "false", "null", "void", "iterable"}; const char* const kValidConstantNames[] = { "int", "float", "bool", "string", "true", - "false", "null", "void", "iterable", + "false", "null", "void", "iterable", "parent", + "self", "readonly" }; -const int kReservedNamesSize = 77; -const int kValidConstantNamesSize = 9; +const int kReservedNamesSize = 80; +const int kValidConstantNamesSize = 12; const int kFieldSetter = 1; const int kFieldGetter = 2; const int kFieldProperty = 3; @@ -83,14 +84,14 @@ struct Options { bool is_descriptor = false; bool aggregate_metadata = false; bool gen_c_wkt = false; - std::set aggregate_metadata_prefixes; + std::set aggregate_metadata_prefixes; }; namespace { // Forward decls. std::string PhpName(const std::string& full_name, const Options& options); -std::string IntToString(int32 value); +std::string IntToString(int32_t value); std::string FilenameToClassname(const std::string& filename); std::string GeneratedMetadataFileName(const FileDescriptor* file, const Options& options); @@ -419,6 +420,21 @@ std::string LegacyGeneratedClassFileName(const DescriptorType* desc, return result + ".php"; } +template +std::string LegacyReadOnlyGeneratedClassFileName(std::string php_namespace, + const DescriptorType* desc) { + if (!php_namespace.empty()) { + for (int i = 0; i < php_namespace.size(); i++) { + if (php_namespace[i] == '\\') { + php_namespace[i] = '/'; + } + } + return php_namespace + "/" + desc->name() + ".php"; + } + + return desc->name() + ".php"; +} + std::string GeneratedServiceFileName(const ServiceDescriptor* service, const Options& options) { std::string result = FullClassName(service, options) + "Interface"; @@ -430,7 +446,7 @@ std::string GeneratedServiceFileName(const ServiceDescriptor* service, return result + ".php"; } -std::string IntToString(int32 value) { +std::string IntToString(int32_t value) { std::ostringstream os; os << value; return os.str(); @@ -489,9 +505,9 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, // accommodate for edge case with multiple types. size_t start_pos = type.find("|"); if (start_pos != std::string::npos) { - type.replace(start_pos, 1, "[]|"); + type.replace(start_pos, 1, ">|array<"); } - type += "[]|\\Google\\Protobuf\\Internal\\RepeatedField"; + type = "array<" + type + ">|\\Google\\Protobuf\\Internal\\RepeatedField"; } return type; } @@ -741,8 +757,8 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, // Type check. if (field->is_map()) { const Descriptor* map_entry = field->message_type(); - const FieldDescriptor* key = map_entry->FindFieldByName("key"); - const FieldDescriptor* value = map_entry->FindFieldByName("value"); + const FieldDescriptor* key = map_entry->map_key(); + const FieldDescriptor* value = map_entry->map_value(); printer->Print( "$arr = GPBUtil::checkMapField($var, " "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, " @@ -889,9 +905,9 @@ void GenerateMessageToPool(const std::string& name_prefix, const FieldDescriptor* field = message->field(i); if (field->is_map()) { const FieldDescriptor* key = - field->message_type()->FindFieldByName("key"); + field->message_type()->map_key(); const FieldDescriptor* val = - field->message_type()->FindFieldByName("value"); + field->message_type()->map_value(); printer->Print( "->map('^field^', \\Google\\Protobuf\\Internal\\GPBType::^key^, " "\\Google\\Protobuf\\Internal\\GPBType::^value^, ^number^^other^)\n", @@ -1114,7 +1130,7 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, std::map dependency_count; std::set nodes_without_dependency; FileDescriptorSet sorted_file_set; - + AnalyzeDependencyForFile( file, &nodes_without_dependency, &deps, &dependency_count); @@ -1301,6 +1317,45 @@ void LegacyGenerateClassFile(const FileDescriptor* file, "fullname", newname); } +template +void LegacyReadOnlyGenerateClassFile(const FileDescriptor* file, + const DescriptorType* desc, const Options& options, + GeneratorContext* generator_context) { + std::string fullname = FullClassName(desc, options); + std::string php_namespace; + std::string classname; + int lastindex = fullname.find_last_of("\\"); + + if (lastindex != std::string::npos) { + php_namespace = fullname.substr(0, lastindex); + classname = fullname.substr(lastindex + 1); + } else { + php_namespace = ""; + classname = fullname; + } + + std::string filename = LegacyReadOnlyGeneratedClassFileName(php_namespace, desc); + std::unique_ptr output( + generator_context->Open(filename)); + io::Printer printer(output.get(), '^'); + + GenerateHead(file, &printer); + + if (!php_namespace.empty()) { + printer.Print( + "namespace ^name^;\n\n", + "name", php_namespace); + } + + printer.Print("class_exists(^new^::class); // autoload the new class, which " + "will also create an alias to the deprecated class\n", + "new", classname); + printer.Print("@trigger_error(__NAMESPACE__ . '\\^old^ is deprecated and will be removed in " + "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n", + "old", desc->name(), + "fullname", classname); +} + void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, const Options& options, GeneratorContext* generator_context) { @@ -1336,11 +1391,18 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, "name", fullname); Indent(&printer); + bool hasReserved = false; for (int i = 0; i < en->value_count(); i++) { const EnumValueDescriptor* value = en->value(i); GenerateEnumValueDocComment(&printer, value); + + std::string prefix = ConstantNamePrefix(value->name()); + if (!prefix.empty()) { + hasReserved = true; + } + printer.Print("const ^name^ = ^number^;\n", - "name", ConstantNamePrefix(value->name()) + value->name(), + "name", prefix + value->name(), "number", IntToString(value->number())); } @@ -1348,8 +1410,9 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, Indent(&printer); for (int i = 0; i < en->value_count(); i++) { const EnumValueDescriptor* value = en->value(i); - printer.Print("self::^name^ => '^name^',\n", - "name", ConstantNamePrefix(value->name()) + value->name()); + printer.Print("self::^constant^ => '^name^',\n", + "constant", ConstantNamePrefix(value->name()) + value->name(), + "name", value->name()); } Outdent(&printer); printer.Print("];\n"); @@ -1379,12 +1442,22 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print("$const = __CLASS__ . '::' . strtoupper($name);\n" "if (!defined($const)) {\n"); Indent(&printer); + if (hasReserved) { + printer.Print("$pbconst = __CLASS__. '::PB' . strtoupper($name);\n" + "if (!defined($pbconst)) {\n"); + Indent(&printer); + } printer.Print("throw new UnexpectedValueException(sprintf(\n"); Indent(&printer); Indent(&printer); printer.Print("'Enum %s has no value defined for name %s', __CLASS__, $name));\n"); Outdent(&printer); Outdent(&printer); + if (hasReserved) { + Outdent(&printer); + printer.Print("}\n" + "return constant($pbconst);\n"); + } Outdent(&printer); printer.Print("}\n" "return constant($const);\n"); @@ -1404,6 +1477,19 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, "old", LegacyFullClassName(en, options)); LegacyGenerateClassFile(file, en, options, generator_context); } + + // Write legacy file for backwards compatibility with "readonly" keywword + std::string lower = en->name(); + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + if (lower == "readonly") { + printer.Print( + "// Adding a class alias for backwards compatibility with the \"readonly\" keyword.\n"); + printer.Print( + "class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n", + "new", fullname, + "old", en->name()); + LegacyReadOnlyGenerateClassFile(file, en, options, generator_context); + } } void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, @@ -1520,6 +1606,19 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, LegacyGenerateClassFile(file, message, options, generator_context); } + // Write legacy file for backwards compatibility with "readonly" keywword + std::string lower = message->name(); + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + if (lower == "readonly") { + printer.Print( + "// Adding a class alias for backwards compatibility with the \"readonly\" keyword.\n"); + printer.Print( + "class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n", + "new", fullname, + "old", message->name()); + LegacyReadOnlyGenerateClassFile(file, message, options, generator_context); + } + // Nested messages and enums. for (int i = 0; i < message->nested_type_count(); i++) { GenerateMessageFile(file, message->nested_type(i), options, @@ -1869,44 +1968,45 @@ void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) { "\n" "PHP_METHOD($c_name$, name) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" - " const char *name;\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " zend_long value;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n" " FAILURE) {\n" " return;\n" " }\n" - " name = upb_enumdef_iton(e, value);\n" - " if (!name) {\n" + " const upb_EnumValueDef* ev =\n" + " upb_EnumDef_FindValueByNumber(e, value);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no name \"\n" " \"defined for value \" ZEND_LONG_FMT \".\",\n" " value);\n" " return;\n" " }\n" - " RETURN_STRING(name);\n" + " RETURN_STRING(upb_EnumValueDef_Name(ev));\n" "}\n" "\n" "PHP_METHOD($c_name$, value) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " char *name = NULL;\n" " size_t name_len;\n" - " int32_t num;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n" " &name_len) == FAILURE) {\n" " return;\n" " }\n" - " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n" + " const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize(\n" + " e, name, name_len);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no value \"\n" " \"defined for name %s.\",\n" " name);\n" " return;\n" " }\n" - " RETURN_LONG(num);\n" + " RETURN_LONG(upb_EnumValueDef_Number(ev));\n" "}\n" "\n" "static zend_function_entry $c_name$_phpmethods[] = {\n" @@ -1965,8 +2065,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval ret;\n" " Message_get(intern, f, &ret);\n" " RETURN_COPY_VALUE(&ret);\n" @@ -1974,8 +2074,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { "\n" "static PHP_METHOD($c_name$, set$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval *val;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n" " == FAILURE) {\n" @@ -1995,10 +2095,11 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n" - " \"$name$\");\n" - " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n" - " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n" + " const upb_OneofDef *oneof = upb_MessageDef_FindOneofByName(\n" + " intern->desc->msgdef, \"$name$\");\n" + " const upb_FieldDef *field = \n" + " upb_Message_WhichOneof(intern->msg, oneof);\n" + " RETURN_STRING(field ? upb_FieldDef_Name(field) : \"\");\n" "}\n", "c_name", c_name, "name", oneof->name(), @@ -2065,7 +2166,7 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { break; default: break; - } + } printer->Print( " ZEND_FE_END\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.cc b/third_party/protobuf/src/google/protobuf/compiler/plugin.cc index 78099686..0a323843 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.cc @@ -45,9 +45,10 @@ #include #include #include -#include #include +#include #include +#include namespace google { @@ -68,7 +69,7 @@ class GeneratorResponseContext : public GeneratorContext { : compiler_version_(compiler_version), response_(response), parsed_files_(parsed_files) {} - virtual ~GeneratorResponseContext() {} + ~GeneratorResponseContext() override {} // implements GeneratorContext -------------------------------------- @@ -117,7 +118,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, DescriptorPool pool; for (int i = 0; i < request.proto_file_size(); i++) { const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); - if (file == NULL) { + if (file == nullptr) { // BuildFile() already wrote an error message. return false; } @@ -126,7 +127,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, std::vector parsed_files; for (int i = 0; i < request.file_to_generate_size(); i++) { parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); - if (parsed_files.back() == NULL) { + if (parsed_files.back() == nullptr) { *error_msg = "protoc asked plugin to generate a file but " "did not provide a descriptor for the file: " + diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.h b/third_party/protobuf/src/google/protobuf/compiler/plugin.h index 7d1bf450..611713e2 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.h +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.h @@ -64,6 +64,7 @@ #include +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc index e423e851..8f8d83f0 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc @@ -16,141 +16,153 @@ #include PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + PROTOBUF_NAMESPACE_OPEN namespace compiler { -constexpr Version::Version( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : suffix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , major_(0) - , minor_(0) - , patch_(0){} +PROTOBUF_CONSTEXPR Version::Version( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.suffix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.major_)*/0 + , /*decltype(_impl_.minor_)*/0 + , /*decltype(_impl_.patch_)*/0} {} struct VersionDefaultTypeInternal { - constexpr VersionDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR VersionDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~VersionDefaultTypeInternal() {} union { Version _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_; -constexpr CodeGeneratorRequest::CodeGeneratorRequest( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : file_to_generate_() - , proto_file_() - , parameter_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , compiler_version_(nullptr){} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorRequest::CodeGeneratorRequest( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.file_to_generate_)*/{} + , /*decltype(_impl_.proto_file_)*/{} + , /*decltype(_impl_.parameter_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.compiler_version_)*/nullptr} {} struct CodeGeneratorRequestDefaultTypeInternal { - constexpr CodeGeneratorRequestDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorRequestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorRequestDefaultTypeInternal() {} union { CodeGeneratorRequest _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; -constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , insertion_point_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , content_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , generated_code_info_(nullptr){} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse_File::CodeGeneratorResponse_File( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.insertion_point_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.content_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.generated_code_info_)*/nullptr} {} struct CodeGeneratorResponse_FileDefaultTypeInternal { - constexpr CodeGeneratorResponse_FileDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponse_FileDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponse_FileDefaultTypeInternal() {} union { CodeGeneratorResponse_File _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; -constexpr CodeGeneratorResponse::CodeGeneratorResponse( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : file_() - , error_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , supported_features_(uint64_t{0u}){} +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse( + ::_pbi::ConstantInitialized): _impl_{ + /*decltype(_impl_._has_bits_)*/{} + , /*decltype(_impl_._cached_size_)*/{} + , /*decltype(_impl_.file_)*/{} + , /*decltype(_impl_.error_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} + , /*decltype(_impl_.supported_features_)*/uint64_t{0u}} {} struct CodeGeneratorResponseDefaultTypeInternal { - constexpr CodeGeneratorResponseDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponseDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponseDefaultTypeInternal() {} union { CodeGeneratorResponse _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; } // namespace compiler PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; -static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; +static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; const uint32_t TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, major_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, minor_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, patch_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, suffix_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _impl_.major_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _impl_.minor_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _impl_.patch_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _impl_.suffix_), 1, 2, 3, 0, - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, file_to_generate_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, parameter_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, proto_file_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, compiler_version_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _impl_.file_to_generate_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _impl_.parameter_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _impl_.proto_file_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest, _impl_.compiler_version_), ~0u, 0, ~0u, 1, - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, name_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, generated_code_info_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _impl_.name_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _impl_.insertion_point_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _impl_.content_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, _impl_.generated_code_info_), 0, 1, 2, 3, - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _has_bits_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ ~0u, // no _inlined_string_donated_ - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, error_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, supported_features_), - PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, file_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _impl_.error_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _impl_.supported_features_), + PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _impl_.file_), 0, 1, ~0u, }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, 10, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::Version)}, { 14, 24, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, { 28, 38, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, { 42, 51, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_), - reinterpret_cast(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -175,22 +187,24 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "uginProtosZ)google.golang.org/protobuf/t" "ypes/pluginpb" ; -static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { +static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, }; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { - false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { + false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + "google/protobuf/compiler/plugin.proto", + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); PROTOBUF_NAMESPACE_OPEN namespace compiler { const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() { @@ -219,7 +233,7 @@ constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE; class Version::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); + using HasBits = decltype(std::declval()._impl_._has_bits_); static void set_has_major(HasBits* has_bits) { (*has_bits)[0] |= 2u; } @@ -237,61 +251,69 @@ class Version::_Internal { Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version) } Version::Version(const Version& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _has_bits_(from._has_bits_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + Version* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.suffix_){} + , decltype(_impl_.major_){} + , decltype(_impl_.minor_){} + , decltype(_impl_.patch_){}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.suffix_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.suffix_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_suffix()) { - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(), - GetArenaForAllocation()); + _this->_impl_.suffix_.Set(from._internal_suffix(), + _this->GetArenaForAllocation()); } - ::memcpy(&major_, &from.major_, - static_cast(reinterpret_cast(&patch_) - - reinterpret_cast(&major_)) + sizeof(patch_)); + ::memcpy(&_impl_.major_, &from._impl_.major_, + static_cast(reinterpret_cast(&_impl_.patch_) - + reinterpret_cast(&_impl_.major_)) + sizeof(_impl_.patch_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version) } -inline void Version::SharedCtor() { -suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -::memset(reinterpret_cast(this) + static_cast( - reinterpret_cast(&major_) - reinterpret_cast(this)), - 0, static_cast(reinterpret_cast(&patch_) - - reinterpret_cast(&major_)) + sizeof(patch_)); +inline void Version::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.suffix_){} + , decltype(_impl_.major_){0} + , decltype(_impl_.minor_){0} + , decltype(_impl_.patch_){0} + }; + _impl_.suffix_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.suffix_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } Version::~Version() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Version::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.suffix_.Destroy(); } -void Version::ArenaDtor(void* object) { - Version* _this = reinterpret_cast< Version* >(object); - (void)_this; -} -void Version::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Version::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void Version::Clear() { @@ -300,31 +322,31 @@ void Version::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x00000001u) { - suffix_.ClearNonDefaultToEmpty(); + _impl_.suffix_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x0000000eu) { - ::memset(&major_, 0, static_cast( - reinterpret_cast(&patch_) - - reinterpret_cast(&major_)) + sizeof(patch_)); + ::memset(&_impl_.major_, 0, static_cast( + reinterpret_cast(&_impl_.patch_) - + reinterpret_cast(&_impl_.major_)) + sizeof(_impl_.patch_)); } - _has_bits_.Clear(); + _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Version::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional int32 major = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 8)) { _Internal::set_has_major(&has_bits); - major_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + _impl_.major_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -333,7 +355,7 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { _Internal::set_has_minor(&has_bits); - minor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + _impl_.minor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -342,7 +364,7 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in case 3: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 24)) { _Internal::set_has_patch(&has_bits); - patch_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); + _impl_.patch_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -351,11 +373,11 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in case 4: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 34)) { auto str = _internal_mutable_suffix(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -375,7 +397,7 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in CHK_(ptr != nullptr); } // while message_done: - _has_bits_.Or(has_bits); + _impl_._has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; @@ -389,23 +411,23 @@ uint8_t* Version::_InternalSerialize( uint32_t cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); } // optional string suffix = 4; @@ -419,7 +441,7 @@ uint8_t* Version::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version) @@ -434,7 +456,7 @@ size_t Version::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { // optional string suffix = 4; if (cached_has_bits & 0x00000001u) { @@ -445,59 +467,55 @@ size_t Version::ByteSizeLong() const { // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_major()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_major()); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); } } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData Version::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, Version::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*Version::GetClassData() const { return &_class_data_; } -void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void Version::MergeFrom(const Version& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version) - GOOGLE_DCHECK_NE(&from, this); +void Version::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = from._has_bits_[0]; + cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _internal_set_suffix(from._internal_suffix()); + _this->_internal_set_suffix(from._internal_suffix()); } if (cached_has_bits & 0x00000002u) { - major_ = from.major_; + _this->_impl_.major_ = from._impl_.major_; } if (cached_has_bits & 0x00000004u) { - minor_ = from.minor_; + _this->_impl_.minor_ = from._impl_.minor_; } if (cached_has_bits & 0x00000008u) { - patch_ = from.patch_; + _this->_impl_.patch_ = from._impl_.patch_; } - _has_bits_[0] |= cached_has_bits; + _this->_impl_._has_bits_[0] |= cached_has_bits; } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void Version::CopyFrom(const Version& from) { @@ -516,22 +534,21 @@ void Version::InternalSwap(Version* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &suffix_, lhs_arena, - &other->suffix_, rhs_arena + &_impl_.suffix_, lhs_arena, + &other->_impl_.suffix_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::memswap< - PROTOBUF_FIELD_OFFSET(Version, patch_) - + sizeof(Version::patch_) - - PROTOBUF_FIELD_OFFSET(Version, major_)>( - reinterpret_cast(&major_), - reinterpret_cast(&other->major_)); + PROTOBUF_FIELD_OFFSET(Version, _impl_.patch_) + + sizeof(Version::_impl_.patch_) + - PROTOBUF_FIELD_OFFSET(Version, _impl_.major_)>( + reinterpret_cast(&_impl_.major_), + reinterpret_cast(&other->_impl_.major_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]); } @@ -540,7 +557,7 @@ void Version::InternalSwap(Version* other) { class CodeGeneratorRequest::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); + using HasBits = decltype(std::declval()._impl_._has_bits_); static void set_has_parameter(HasBits* has_bits) { (*has_bits)[0] |= 1u; } @@ -552,73 +569,80 @@ class CodeGeneratorRequest::_Internal { const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* msg) { - return *msg->compiler_version_; + return *msg->_impl_.compiler_version_; } void CodeGeneratorRequest::clear_proto_file() { - proto_file_.Clear(); + _impl_.proto_file_.Clear(); } CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), - file_to_generate_(arena), - proto_file_(arena) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest) } CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _has_bits_(from._has_bits_), - file_to_generate_(from.file_to_generate_), - proto_file_(from.proto_file_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + CodeGeneratorRequest* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.file_to_generate_){from._impl_.file_to_generate_} + , decltype(_impl_.proto_file_){from._impl_.proto_file_} + , decltype(_impl_.parameter_){} + , decltype(_impl_.compiler_version_){nullptr}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.parameter_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.parameter_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_parameter()) { - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(), - GetArenaForAllocation()); + _this->_impl_.parameter_.Set(from._internal_parameter(), + _this->GetArenaForAllocation()); } if (from._internal_has_compiler_version()) { - compiler_version_ = new ::PROTOBUF_NAMESPACE_ID::compiler::Version(*from.compiler_version_); - } else { - compiler_version_ = nullptr; + _this->_impl_.compiler_version_ = new ::PROTOBUF_NAMESPACE_ID::compiler::Version(*from._impl_.compiler_version_); } // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest) } -inline void CodeGeneratorRequest::SharedCtor() { -parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -compiler_version_ = nullptr; +inline void CodeGeneratorRequest::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.file_to_generate_){arena} + , decltype(_impl_.proto_file_){arena} + , decltype(_impl_.parameter_){} + , decltype(_impl_.compiler_version_){nullptr} + }; + _impl_.parameter_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.parameter_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } CodeGeneratorRequest::~CodeGeneratorRequest() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorRequest::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) delete compiler_version_; + _impl_.file_to_generate_.~RepeatedPtrField(); + _impl_.proto_file_.~RepeatedPtrField(); + _impl_.parameter_.Destroy(); + if (this != internal_default_instance()) delete _impl_.compiler_version_; } -void CodeGeneratorRequest::ArenaDtor(void* object) { - CodeGeneratorRequest* _this = reinterpret_cast< CodeGeneratorRequest* >(object); - (void)_this; -} -void CodeGeneratorRequest::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorRequest::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void CodeGeneratorRequest::Clear() { @@ -627,28 +651,28 @@ void CodeGeneratorRequest::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - file_to_generate_.Clear(); - proto_file_.Clear(); - cached_has_bits = _has_bits_[0]; + _impl_.file_to_generate_.Clear(); + _impl_.proto_file_.Clear(); + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - parameter_.ClearNonDefaultToEmpty(); + _impl_.parameter_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000002u) { - GOOGLE_DCHECK(compiler_version_ != nullptr); - compiler_version_->Clear(); + GOOGLE_DCHECK(_impl_.compiler_version_ != nullptr); + _impl_.compiler_version_->Clear(); } } - _has_bits_.Clear(); + _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // repeated string file_to_generate = 1; case 1: @@ -657,11 +681,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM do { ptr += 1; auto str = _internal_add_file_to_generate(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); + #endif // !NDEBUG if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); } else @@ -671,11 +695,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_parameter(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -716,7 +740,7 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM CHK_(ptr != nullptr); } // while message_done: - _has_bits_.Or(has_bits); + _impl_._has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; @@ -740,7 +764,7 @@ uint8_t* CodeGeneratorRequest::_InternalSerialize( target = stream->WriteString(1, s, target); } - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; // optional string parameter = 2; if (cached_has_bits & 0x00000001u) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( @@ -753,22 +777,21 @@ uint8_t* CodeGeneratorRequest::_InternalSerialize( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 3, _Internal::compiler_version(this), target, stream); + InternalWriteMessage(3, _Internal::compiler_version(this), + _Internal::compiler_version(this).GetCachedSize(), target, stream); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - for (unsigned int i = 0, - n = static_cast(this->_internal_proto_file_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_proto_file_size()); i < n; i++) { + const auto& repfield = this->_internal_proto_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_proto_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest) @@ -785,20 +808,20 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { // repeated string file_to_generate = 1; total_size += 1 * - ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(file_to_generate_.size()); - for (int i = 0, n = file_to_generate_.size(); i < n; i++) { + ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.file_to_generate_.size()); + for (int i = 0, n = _impl_.file_to_generate_.size(); i < n; i++) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - file_to_generate_.Get(i)); + _impl_.file_to_generate_.Get(i)); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; total_size += 1UL * this->_internal_proto_file_size(); - for (const auto& msg : this->proto_file_) { + for (const auto& msg : this->_impl_.proto_file_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { // optional string parameter = 2; if (cached_has_bits & 0x00000001u) { @@ -811,44 +834,41 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { if (cached_has_bits & 0x00000002u) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *compiler_version_); + *_impl_.compiler_version_); } } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorRequest::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, CodeGeneratorRequest::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorRequest::GetClassData() const { return &_class_data_; } -void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) - GOOGLE_DCHECK_NE(&from, this); +void CodeGeneratorRequest::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - file_to_generate_.MergeFrom(from.file_to_generate_); - proto_file_.MergeFrom(from.proto_file_); - cached_has_bits = from._has_bits_[0]; + _this->_impl_.file_to_generate_.MergeFrom(from._impl_.file_to_generate_); + _this->_impl_.proto_file_.MergeFrom(from._impl_.proto_file_); + cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _internal_set_parameter(from._internal_parameter()); + _this->_internal_set_parameter(from._internal_parameter()); } if (cached_has_bits & 0x00000002u) { - _internal_mutable_compiler_version()->::PROTOBUF_NAMESPACE_ID::compiler::Version::MergeFrom(from._internal_compiler_version()); + _this->_internal_mutable_compiler_version()->::PROTOBUF_NAMESPACE_ID::compiler::Version::MergeFrom( + from._internal_compiler_version()); } } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) { @@ -859,7 +879,7 @@ void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) { } bool CodeGeneratorRequest::IsInitialized() const { - if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(proto_file_)) + if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.proto_file_)) return false; return true; } @@ -869,19 +889,18 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - file_to_generate_.InternalSwap(&other->file_to_generate_); - proto_file_.InternalSwap(&other->proto_file_); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); + _impl_.file_to_generate_.InternalSwap(&other->_impl_.file_to_generate_); + _impl_.proto_file_.InternalSwap(&other->_impl_.proto_file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ¶meter_, lhs_arena, - &other->parameter_, rhs_arena + &_impl_.parameter_, lhs_arena, + &other->_impl_.parameter_, rhs_arena ); - swap(compiler_version_, other->compiler_version_); + swap(_impl_.compiler_version_, other->_impl_.compiler_version_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorRequest::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]); } @@ -890,7 +909,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { class CodeGeneratorResponse_File::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); + using HasBits = decltype(std::declval()._impl_._has_bits_); static void set_has_name(HasBits* has_bits) { (*has_bits)[0] |= 1u; } @@ -908,96 +927,105 @@ class CodeGeneratorResponse_File::_Internal { const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) { - return *msg->generated_code_info_; + return *msg->_impl_.generated_code_info_; } void CodeGeneratorResponse_File::clear_generated_code_info() { - if (generated_code_info_ != nullptr) generated_code_info_->Clear(); - _has_bits_[0] &= ~0x00000008u; + if (_impl_.generated_code_info_ != nullptr) _impl_.generated_code_info_->Clear(); + _impl_._has_bits_[0] &= ~0x00000008u; } CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _has_bits_(from._has_bits_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + CodeGeneratorResponse_File* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.name_){} + , decltype(_impl_.insertion_point_){} + , decltype(_impl_.content_){} + , decltype(_impl_.generated_code_info_){nullptr}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_name()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), - GetArenaForAllocation()); + _this->_impl_.name_.Set(from._internal_name(), + _this->GetArenaForAllocation()); } - insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.insertion_point_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.insertion_point_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_insertion_point()) { - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), - GetArenaForAllocation()); + _this->_impl_.insertion_point_.Set(from._internal_insertion_point(), + _this->GetArenaForAllocation()); } - content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.content_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.content_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_content()) { - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(), - GetArenaForAllocation()); + _this->_impl_.content_.Set(from._internal_content(), + _this->GetArenaForAllocation()); } if (from._internal_has_generated_code_info()) { - generated_code_info_ = new ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from.generated_code_info_); - } else { - generated_code_info_ = nullptr; + _this->_impl_.generated_code_info_ = new ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from._impl_.generated_code_info_); } // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } -inline void CodeGeneratorResponse_File::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -generated_code_info_ = nullptr; +inline void CodeGeneratorResponse_File::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.name_){} + , decltype(_impl_.insertion_point_){} + , decltype(_impl_.content_){} + , decltype(_impl_.generated_code_info_){nullptr} + }; + _impl_.name_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.name_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.insertion_point_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.insertion_point_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.content_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.content_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse_File::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) delete generated_code_info_; + _impl_.name_.Destroy(); + _impl_.insertion_point_.Destroy(); + _impl_.content_.Destroy(); + if (this != internal_default_instance()) delete _impl_.generated_code_info_; } -void CodeGeneratorResponse_File::ArenaDtor(void* object) { - CodeGeneratorResponse_File* _this = reinterpret_cast< CodeGeneratorResponse_File* >(object); - (void)_this; -} -void CodeGeneratorResponse_File::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorResponse_File::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void CodeGeneratorResponse_File::Clear() { @@ -1006,42 +1034,42 @@ void CodeGeneratorResponse_File::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - name_.ClearNonDefaultToEmpty(); + _impl_.name_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000002u) { - insertion_point_.ClearNonDefaultToEmpty(); + _impl_.insertion_point_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000004u) { - content_.ClearNonDefaultToEmpty(); + _impl_.content_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000008u) { - GOOGLE_DCHECK(generated_code_info_ != nullptr); - generated_code_info_->Clear(); + GOOGLE_DCHECK(_impl_.generated_code_info_ != nullptr); + _impl_.generated_code_info_->Clear(); } } - _has_bits_.Clear(); + _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -1049,11 +1077,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 18)) { auto str = _internal_mutable_insertion_point(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -1061,11 +1089,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 15: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 122)) { auto str = _internal_mutable_content(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -1093,7 +1121,7 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB CHK_(ptr != nullptr); } // while message_done: - _has_bits_.Or(has_bits); + _impl_._has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; @@ -1107,7 +1135,7 @@ uint8_t* CodeGeneratorResponse_File::_InternalSerialize( uint32_t cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; // optional string name = 1; if (cached_has_bits & 0x00000001u) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1140,14 +1168,13 @@ uint8_t* CodeGeneratorResponse_File::_InternalSerialize( // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; if (cached_has_bits & 0x00000008u) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 16, _Internal::generated_code_info(this), target, stream); + InternalWriteMessage(16, _Internal::generated_code_info(this), + _Internal::generated_code_info(this).GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File) @@ -1162,7 +1189,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { // optional string name = 1; if (cached_has_bits & 0x00000001u) { @@ -1189,48 +1216,45 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { if (cached_has_bits & 0x00000008u) { total_size += 2 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( - *generated_code_info_); + *_impl_.generated_code_info_); } } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse_File::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, CodeGeneratorResponse_File::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse_File::GetClassData() const { return &_class_data_; } -void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) - GOOGLE_DCHECK_NE(&from, this); +void CodeGeneratorResponse_File::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = from._has_bits_[0]; + cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _internal_set_name(from._internal_name()); + _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _internal_set_insertion_point(from._internal_insertion_point()); + _this->_internal_set_insertion_point(from._internal_insertion_point()); } if (cached_has_bits & 0x00000004u) { - _internal_set_content(from._internal_content()); + _this->_internal_set_content(from._internal_content()); } if (cached_has_bits & 0x00000008u) { - _internal_mutable_generated_code_info()->::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info()); + _this->_internal_mutable_generated_code_info()->::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom( + from._internal_generated_code_info()); } } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) { @@ -1249,27 +1273,24 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &name_, lhs_arena, - &other->name_, rhs_arena + &_impl_.name_, lhs_arena, + &other->_impl_.name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &insertion_point_, lhs_arena, - &other->insertion_point_, rhs_arena + &_impl_.insertion_point_, lhs_arena, + &other->_impl_.insertion_point_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &content_, lhs_arena, - &other->content_, rhs_arena + &_impl_.content_, lhs_arena, + &other->_impl_.content_, rhs_arena ); - swap(generated_code_info_, other->generated_code_info_); + swap(_impl_.generated_code_info_, other->_impl_.generated_code_info_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]); } @@ -1278,7 +1299,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) class CodeGeneratorResponse::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); + using HasBits = decltype(std::declval()._impl_._has_bits_); static void set_has_error(HasBits* has_bits) { (*has_bits)[0] |= 1u; } @@ -1289,59 +1310,67 @@ class CodeGeneratorResponse::_Internal { CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) - : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), - file_(arena) { - SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } + : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { + SharedCtor(arena, is_message_owned); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse) } CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _has_bits_(from._has_bits_), - file_(from.file_) { + : ::PROTOBUF_NAMESPACE_ID::Message() { + CodeGeneratorResponse* const _this = this; (void)_this; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){from._impl_._has_bits_} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.file_){from._impl_.file_} + , decltype(_impl_.error_){} + , decltype(_impl_.supported_features_){}}; + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.error_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + _impl_.error_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_error()) { - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(), - GetArenaForAllocation()); + _this->_impl_.error_.Set(from._internal_error(), + _this->GetArenaForAllocation()); } - supported_features_ = from.supported_features_; + _this->_impl_.supported_features_ = from._impl_.supported_features_; // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse) } -inline void CodeGeneratorResponse::SharedCtor() { -error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); -#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); -#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -supported_features_ = uint64_t{0u}; +inline void CodeGeneratorResponse::SharedCtor( + ::_pb::Arena* arena, bool is_message_owned) { + (void)arena; + (void)is_message_owned; + new (&_impl_) Impl_{ + decltype(_impl_._has_bits_){} + , /*decltype(_impl_._cached_size_)*/{} + , decltype(_impl_.file_){arena} + , decltype(_impl_.error_){} + , decltype(_impl_.supported_features_){uint64_t{0u}} + }; + _impl_.error_.InitDefault(); + #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING + _impl_.error_.Set("", GetArenaForAllocation()); + #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING } CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + _impl_.file_.~RepeatedPtrField(); + _impl_.error_.Destroy(); } -void CodeGeneratorResponse::ArenaDtor(void* object) { - CodeGeneratorResponse* _this = reinterpret_cast< CodeGeneratorResponse* >(object); - (void)_this; -} -void CodeGeneratorResponse::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorResponse::SetCachedSize(int size) const { - _cached_size_.Set(size); + _impl_._cached_size_.Set(size); } void CodeGeneratorResponse::Clear() { @@ -1350,32 +1379,32 @@ void CodeGeneratorResponse::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - file_.Clear(); - cached_has_bits = _has_bits_[0]; + _impl_.file_.Clear(); + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x00000001u) { - error_.ClearNonDefaultToEmpty(); + _impl_.error_.ClearNonDefaultToEmpty(); } - supported_features_ = uint64_t{0u}; - _has_bits_.Clear(); + _impl_.supported_features_ = uint64_t{0u}; + _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { uint32_t tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string error = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 10)) { auto str = _internal_mutable_error(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); - #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); - #endif // !NDEBUG + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); CHK_(ptr); + #ifndef NDEBUG + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); + #endif // !NDEBUG } else goto handle_unusual; continue; @@ -1383,7 +1412,7 @@ const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NA case 2: if (PROTOBUF_PREDICT_TRUE(static_cast(tag) == 16)) { _Internal::set_has_supported_features(&has_bits); - supported_features_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + _impl_.supported_features_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); CHK_(ptr); } else goto handle_unusual; @@ -1417,7 +1446,7 @@ const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NA CHK_(ptr != nullptr); } // while message_done: - _has_bits_.Or(has_bits); + _impl_._has_bits_.Or(has_bits); return ptr; failure: ptr = nullptr; @@ -1431,7 +1460,7 @@ uint8_t* CodeGeneratorResponse::_InternalSerialize( uint32_t cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; // optional string error = 1; if (cached_has_bits & 0x00000001u) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1445,19 +1474,19 @@ uint8_t* CodeGeneratorResponse::_InternalSerialize( // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target); + target = ::_pbi::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target); } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - for (unsigned int i = 0, - n = static_cast(this->_internal_file_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast(this->_internal_file_size()); i < n; i++) { + const auto& repfield = this->_internal_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse) @@ -1474,12 +1503,12 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; total_size += 1UL * this->_internal_file_size(); - for (const auto& msg : this->file_) { + for (const auto& msg : this->_impl_.file_) { total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - cached_has_bits = _has_bits_[0]; + cached_has_bits = _impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { // optional string error = 1; if (cached_has_bits & 0x00000001u) { @@ -1490,44 +1519,40 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); + total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); } } - return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_); + return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } const ::PROTOBUF_NAMESPACE_ID::Message::ClassData CodeGeneratorResponse::_class_data_ = { - ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck, + ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck, CodeGeneratorResponse::MergeImpl }; const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*CodeGeneratorResponse::GetClassData() const { return &_class_data_; } -void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, - const ::PROTOBUF_NAMESPACE_ID::Message& from) { - static_cast(to)->MergeFrom( - static_cast(from)); -} - -void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse) - GOOGLE_DCHECK_NE(&from, this); +void CodeGeneratorResponse::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) { + auto* const _this = static_cast(&to_msg); + auto& from = static_cast(from_msg); + // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse) + GOOGLE_DCHECK_NE(&from, _this); uint32_t cached_has_bits = 0; (void) cached_has_bits; - file_.MergeFrom(from.file_); - cached_has_bits = from._has_bits_[0]; + _this->_impl_.file_.MergeFrom(from._impl_.file_); + cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _internal_set_error(from._internal_error()); + _this->_internal_set_error(from._internal_error()); } if (cached_has_bits & 0x00000002u) { - supported_features_ = from.supported_features_; + _this->_impl_.supported_features_ = from._impl_.supported_features_; } - _has_bits_[0] |= cached_has_bits; + _this->_impl_._has_bits_[0] |= cached_has_bits; } - _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); + _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); } void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) { @@ -1546,18 +1571,17 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { auto* lhs_arena = GetArenaForAllocation(); auto* rhs_arena = other->GetArenaForAllocation(); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); - file_.InternalSwap(&other->file_); + swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); + _impl_.file_.InternalSwap(&other->_impl_.file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - &error_, lhs_arena, - &other->error_, rhs_arena + &_impl_.error_, lhs_arena, + &other->_impl_.error_, rhs_arena ); - swap(supported_features_, other->supported_features_); + swap(_impl_.supported_features_, other->_impl_.supported_features_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]); } @@ -1566,16 +1590,20 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // namespace compiler PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h index 569bb30a..5f3fa52c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3021000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION +#if 3021012 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -50,14 +49,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const uint32_t offsets[]; }; PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; @@ -116,7 +107,7 @@ class PROTOC_EXPORT Version final : public: inline Version() : Version(nullptr) {} ~Version() override; - explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Version(const Version& from); Version(Version&& from) noexcept @@ -198,9 +189,11 @@ class PROTOC_EXPORT Version final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const Version& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const Version& from); + void MergeFrom( const Version& from) { + Version::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -209,10 +202,10 @@ class PROTOC_EXPORT Version final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(Version* other); @@ -225,9 +218,6 @@ class PROTOC_EXPORT Version final : protected: explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -309,12 +299,15 @@ class PROTOC_EXPORT Version final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr suffix_; - int32_t major_; - int32_t minor_; - int32_t patch_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr suffix_; + int32_t major_; + int32_t minor_; + int32_t patch_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // ------------------------------------------------------------------- @@ -324,7 +317,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} ~CodeGeneratorRequest() override; - explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorRequest(const CodeGeneratorRequest& from); CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept @@ -406,9 +399,11 @@ class PROTOC_EXPORT CodeGeneratorRequest final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const CodeGeneratorRequest& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const CodeGeneratorRequest& from); + void MergeFrom( const CodeGeneratorRequest& from) { + CodeGeneratorRequest::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -417,10 +412,10 @@ class PROTOC_EXPORT CodeGeneratorRequest final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorRequest* other); @@ -433,9 +428,6 @@ class PROTOC_EXPORT CodeGeneratorRequest final : protected: explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -538,12 +530,15 @@ class PROTOC_EXPORT CodeGeneratorRequest final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField file_to_generate_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > proto_file_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr parameter_; - ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField file_to_generate_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > proto_file_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr parameter_; + ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // ------------------------------------------------------------------- @@ -553,7 +548,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : public: inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} ~CodeGeneratorResponse_File() override; - explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept @@ -635,9 +630,11 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const CodeGeneratorResponse_File& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const CodeGeneratorResponse_File& from); + void MergeFrom( const CodeGeneratorResponse_File& from) { + CodeGeneratorResponse_File::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -646,10 +643,10 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorResponse_File* other); @@ -662,9 +659,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : protected: explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -761,12 +755,15 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_; - ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_; + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // ------------------------------------------------------------------- @@ -776,7 +773,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public: inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} ~CodeGeneratorResponse() override; - explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse(const CodeGeneratorResponse& from); CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept @@ -858,9 +855,11 @@ class PROTOC_EXPORT CodeGeneratorResponse final : using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom; void CopyFrom(const CodeGeneratorResponse& from); using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom; - void MergeFrom(const CodeGeneratorResponse& from); + void MergeFrom( const CodeGeneratorResponse& from) { + CodeGeneratorResponse::MergeImpl(*this, from); + } private: - static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from); + static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg); public: PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -869,10 +868,10 @@ class PROTOC_EXPORT CodeGeneratorResponse final : const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; uint8_t* _InternalSerialize( uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; - int GetCachedSize() const final { return _cached_size_.Get(); } + int GetCachedSize() const final { return _impl_._cached_size_.Get(); } private: - void SharedCtor(); + void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned); void SharedDtor(); void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorResponse* other); @@ -885,9 +884,6 @@ class PROTOC_EXPORT CodeGeneratorResponse final : protected: explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -992,11 +988,14 @@ class PROTOC_EXPORT CodeGeneratorResponse final : template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File > file_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_; - uint64_t supported_features_; + struct Impl_ { + ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File > file_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_; + uint64_t supported_features_; + }; + union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // =================================================================== @@ -1012,26 +1011,26 @@ class PROTOC_EXPORT CodeGeneratorResponse final : // optional int32 major = 1; inline bool Version::_internal_has_major() const { - bool value = (_has_bits_[0] & 0x00000002u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; return value; } inline bool Version::has_major() const { return _internal_has_major(); } inline void Version::clear_major() { - major_ = 0; - _has_bits_[0] &= ~0x00000002u; + _impl_.major_ = 0; + _impl_._has_bits_[0] &= ~0x00000002u; } inline int32_t Version::_internal_major() const { - return major_; + return _impl_.major_; } inline int32_t Version::major() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major) return _internal_major(); } inline void Version::_internal_set_major(int32_t value) { - _has_bits_[0] |= 0x00000002u; - major_ = value; + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.major_ = value; } inline void Version::set_major(int32_t value) { _internal_set_major(value); @@ -1040,26 +1039,26 @@ inline void Version::set_major(int32_t value) { // optional int32 minor = 2; inline bool Version::_internal_has_minor() const { - bool value = (_has_bits_[0] & 0x00000004u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; return value; } inline bool Version::has_minor() const { return _internal_has_minor(); } inline void Version::clear_minor() { - minor_ = 0; - _has_bits_[0] &= ~0x00000004u; + _impl_.minor_ = 0; + _impl_._has_bits_[0] &= ~0x00000004u; } inline int32_t Version::_internal_minor() const { - return minor_; + return _impl_.minor_; } inline int32_t Version::minor() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor) return _internal_minor(); } inline void Version::_internal_set_minor(int32_t value) { - _has_bits_[0] |= 0x00000004u; - minor_ = value; + _impl_._has_bits_[0] |= 0x00000004u; + _impl_.minor_ = value; } inline void Version::set_minor(int32_t value) { _internal_set_minor(value); @@ -1068,26 +1067,26 @@ inline void Version::set_minor(int32_t value) { // optional int32 patch = 3; inline bool Version::_internal_has_patch() const { - bool value = (_has_bits_[0] & 0x00000008u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; return value; } inline bool Version::has_patch() const { return _internal_has_patch(); } inline void Version::clear_patch() { - patch_ = 0; - _has_bits_[0] &= ~0x00000008u; + _impl_.patch_ = 0; + _impl_._has_bits_[0] &= ~0x00000008u; } inline int32_t Version::_internal_patch() const { - return patch_; + return _impl_.patch_; } inline int32_t Version::patch() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch) return _internal_patch(); } inline void Version::_internal_set_patch(int32_t value) { - _has_bits_[0] |= 0x00000008u; - patch_ = value; + _impl_._has_bits_[0] |= 0x00000008u; + _impl_.patch_ = value; } inline void Version::set_patch(int32_t value) { _internal_set_patch(value); @@ -1096,15 +1095,15 @@ inline void Version::set_patch(int32_t value) { // optional string suffix = 4; inline bool Version::_internal_has_suffix() const { - bool value = (_has_bits_[0] & 0x00000001u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; return value; } inline bool Version::has_suffix() const { return _internal_has_suffix(); } inline void Version::clear_suffix() { - suffix_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000001u; + _impl_.suffix_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; } inline const std::string& Version::suffix() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix) @@ -1113,8 +1112,8 @@ inline const std::string& Version::suffix() const { template inline PROTOBUF_ALWAYS_INLINE void Version::set_suffix(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.suffix_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix) } inline std::string* Version::mutable_suffix() { @@ -1123,41 +1122,40 @@ inline std::string* Version::mutable_suffix() { return _s; } inline const std::string& Version::_internal_suffix() const { - return suffix_.Get(); + return _impl_.suffix_.Get(); } inline void Version::_internal_set_suffix(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.suffix_.Set(value, GetArenaForAllocation()); } inline std::string* Version::_internal_mutable_suffix() { - _has_bits_[0] |= 0x00000001u; - return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.suffix_.Mutable(GetArenaForAllocation()); } inline std::string* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) if (!_internal_has_suffix()) { return nullptr; } - _has_bits_[0] &= ~0x00000001u; - auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.suffix_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.suffix_.IsDefault()) { + _impl_.suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void Version::set_allocated_suffix(std::string* suffix) { if (suffix != nullptr) { - _has_bits_[0] |= 0x00000001u; + _impl_._has_bits_[0] |= 0x00000001u; } else { - _has_bits_[0] &= ~0x00000001u; + _impl_._has_bits_[0] &= ~0x00000001u; } - suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix, - GetArenaForAllocation()); + _impl_.suffix_.SetAllocated(suffix, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.suffix_.IsDefault()) { + _impl_.suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix) @@ -1169,13 +1167,13 @@ inline void Version::set_allocated_suffix(std::string* suffix) { // repeated string file_to_generate = 1; inline int CodeGeneratorRequest::_internal_file_to_generate_size() const { - return file_to_generate_.size(); + return _impl_.file_to_generate_.size(); } inline int CodeGeneratorRequest::file_to_generate_size() const { return _internal_file_to_generate_size(); } inline void CodeGeneratorRequest::clear_file_to_generate() { - file_to_generate_.Clear(); + _impl_.file_to_generate_.Clear(); } inline std::string* CodeGeneratorRequest::add_file_to_generate() { std::string* _s = _internal_add_file_to_generate(); @@ -1183,7 +1181,7 @@ inline std::string* CodeGeneratorRequest::add_file_to_generate() { return _s; } inline const std::string& CodeGeneratorRequest::_internal_file_to_generate(int index) const { - return file_to_generate_.Get(index); + return _impl_.file_to_generate_.Get(index); } inline const std::string& CodeGeneratorRequest::file_to_generate(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) @@ -1191,68 +1189,68 @@ inline const std::string& CodeGeneratorRequest::file_to_generate(int index) cons } inline std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) - return file_to_generate_.Mutable(index); + return _impl_.file_to_generate_.Mutable(index); } inline void CodeGeneratorRequest::set_file_to_generate(int index, const std::string& value) { - file_to_generate_.Mutable(index)->assign(value); + _impl_.file_to_generate_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::set_file_to_generate(int index, std::string&& value) { - file_to_generate_.Mutable(index)->assign(std::move(value)); + _impl_.file_to_generate_.Mutable(index)->assign(std::move(value)); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { GOOGLE_DCHECK(value != nullptr); - file_to_generate_.Mutable(index)->assign(value); + _impl_.file_to_generate_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) { - file_to_generate_.Mutable(index)->assign( + _impl_.file_to_generate_.Mutable(index)->assign( reinterpret_cast(value), size); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline std::string* CodeGeneratorRequest::_internal_add_file_to_generate() { - return file_to_generate_.Add(); + return _impl_.file_to_generate_.Add(); } inline void CodeGeneratorRequest::add_file_to_generate(const std::string& value) { - file_to_generate_.Add()->assign(value); + _impl_.file_to_generate_.Add()->assign(value); // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::add_file_to_generate(std::string&& value) { - file_to_generate_.Add(std::move(value)); + _impl_.file_to_generate_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::add_file_to_generate(const char* value) { GOOGLE_DCHECK(value != nullptr); - file_to_generate_.Add()->assign(value); + _impl_.file_to_generate_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) { - file_to_generate_.Add()->assign(reinterpret_cast(value), size); + _impl_.file_to_generate_.Add()->assign(reinterpret_cast(value), size); // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField& CodeGeneratorRequest::file_to_generate() const { // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) - return file_to_generate_; + return _impl_.file_to_generate_; } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField* CodeGeneratorRequest::mutable_file_to_generate() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) - return &file_to_generate_; + return &_impl_.file_to_generate_; } // optional string parameter = 2; inline bool CodeGeneratorRequest::_internal_has_parameter() const { - bool value = (_has_bits_[0] & 0x00000001u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; return value; } inline bool CodeGeneratorRequest::has_parameter() const { return _internal_has_parameter(); } inline void CodeGeneratorRequest::clear_parameter() { - parameter_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000001u; + _impl_.parameter_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorRequest::parameter() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1261,8 +1259,8 @@ inline const std::string& CodeGeneratorRequest::parameter() const { template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.parameter_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline std::string* CodeGeneratorRequest::mutable_parameter() { @@ -1271,41 +1269,40 @@ inline std::string* CodeGeneratorRequest::mutable_parameter() { return _s; } inline const std::string& CodeGeneratorRequest::_internal_parameter() const { - return parameter_.Get(); + return _impl_.parameter_.Get(); } inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.parameter_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() { - _has_bits_[0] |= 0x00000001u; - return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.parameter_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) if (!_internal_has_parameter()) { return nullptr; } - _has_bits_[0] &= ~0x00000001u; - auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.parameter_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.parameter_.IsDefault()) { + _impl_.parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter) { if (parameter != nullptr) { - _has_bits_[0] |= 0x00000001u; + _impl_._has_bits_[0] |= 0x00000001u; } else { - _has_bits_[0] &= ~0x00000001u; + _impl_._has_bits_[0] &= ~0x00000001u; } - parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter, - GetArenaForAllocation()); + _impl_.parameter_.SetAllocated(parameter, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.parameter_.IsDefault()) { + _impl_.parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1313,29 +1310,29 @@ inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter // repeated .google.protobuf.FileDescriptorProto proto_file = 15; inline int CodeGeneratorRequest::_internal_proto_file_size() const { - return proto_file_.size(); + return _impl_.proto_file_.size(); } inline int CodeGeneratorRequest::proto_file_size() const { return _internal_proto_file_size(); } inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file) - return proto_file_.Mutable(index); + return _impl_.proto_file_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >* CodeGeneratorRequest::mutable_proto_file() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) - return &proto_file_; + return &_impl_.proto_file_; } inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::_internal_proto_file(int index) const { - return proto_file_.Get(index); + return _impl_.proto_file_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file) return _internal_proto_file(index); } inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::_internal_add_proto_file() { - return proto_file_.Add(); + return _impl_.proto_file_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_proto_file(); @@ -1345,24 +1342,24 @@ inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::add_p inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >& CodeGeneratorRequest::proto_file() const { // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) - return proto_file_; + return _impl_.proto_file_; } // optional .google.protobuf.compiler.Version compiler_version = 3; inline bool CodeGeneratorRequest::_internal_has_compiler_version() const { - bool value = (_has_bits_[0] & 0x00000002u) != 0; - PROTOBUF_ASSUME(!value || compiler_version_ != nullptr); + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; + PROTOBUF_ASSUME(!value || _impl_.compiler_version_ != nullptr); return value; } inline bool CodeGeneratorRequest::has_compiler_version() const { return _internal_has_compiler_version(); } inline void CodeGeneratorRequest::clear_compiler_version() { - if (compiler_version_ != nullptr) compiler_version_->Clear(); - _has_bits_[0] &= ~0x00000002u; + if (_impl_.compiler_version_ != nullptr) _impl_.compiler_version_->Clear(); + _impl_._has_bits_[0] &= ~0x00000002u; } inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const { - const ::PROTOBUF_NAMESPACE_ID::compiler::Version* p = compiler_version_; + const ::PROTOBUF_NAMESPACE_ID::compiler::Version* p = _impl_.compiler_version_; return p != nullptr ? *p : reinterpret_cast( ::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_); } @@ -1373,20 +1370,20 @@ inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::c inline void CodeGeneratorRequest::unsafe_arena_set_allocated_compiler_version( ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) { if (GetArenaForAllocation() == nullptr) { - delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(compiler_version_); + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.compiler_version_); } - compiler_version_ = compiler_version; + _impl_.compiler_version_ = compiler_version; if (compiler_version) { - _has_bits_[0] |= 0x00000002u; + _impl_._has_bits_[0] |= 0x00000002u; } else { - _has_bits_[0] &= ~0x00000002u; + _impl_._has_bits_[0] &= ~0x00000002u; } // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) } inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_compiler_version() { - _has_bits_[0] &= ~0x00000002u; - ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_; - compiler_version_ = nullptr; + _impl_._has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = _impl_.compiler_version_; + _impl_.compiler_version_ = nullptr; #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); @@ -1400,18 +1397,18 @@ inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release } inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - _has_bits_[0] &= ~0x00000002u; - ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_; - compiler_version_ = nullptr; + _impl_._has_bits_[0] &= ~0x00000002u; + ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = _impl_.compiler_version_; + _impl_.compiler_version_ = nullptr; return temp; } inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() { - _has_bits_[0] |= 0x00000002u; - if (compiler_version_ == nullptr) { + _impl_._has_bits_[0] |= 0x00000002u; + if (_impl_.compiler_version_ == nullptr) { auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::Version>(GetArenaForAllocation()); - compiler_version_ = p; + _impl_.compiler_version_ = p; } - return compiler_version_; + return _impl_.compiler_version_; } inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { ::PROTOBUF_NAMESPACE_ID::compiler::Version* _msg = _internal_mutable_compiler_version(); @@ -1421,20 +1418,20 @@ inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) { ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); if (message_arena == nullptr) { - delete compiler_version_; + delete _impl_.compiler_version_; } if (compiler_version) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::compiler::Version>::GetOwningArena(compiler_version); + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(compiler_version); if (message_arena != submessage_arena) { compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, compiler_version, submessage_arena); } - _has_bits_[0] |= 0x00000002u; + _impl_._has_bits_[0] |= 0x00000002u; } else { - _has_bits_[0] &= ~0x00000002u; + _impl_._has_bits_[0] &= ~0x00000002u; } - compiler_version_ = compiler_version; + _impl_.compiler_version_ = compiler_version; // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) } @@ -1444,15 +1441,15 @@ inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAME // optional string name = 1; inline bool CodeGeneratorResponse_File::_internal_has_name() const { - bool value = (_has_bits_[0] & 0x00000001u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; return value; } inline bool CodeGeneratorResponse_File::has_name() const { return _internal_has_name(); } inline void CodeGeneratorResponse_File::clear_name() { - name_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000001u; + _impl_.name_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse_File::name() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1461,8 +1458,8 @@ inline const std::string& CodeGeneratorResponse_File::name() const { template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.name_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline std::string* CodeGeneratorResponse_File::mutable_name() { @@ -1471,41 +1468,40 @@ inline std::string* CodeGeneratorResponse_File::mutable_name() { return _s; } inline const std::string& CodeGeneratorResponse_File::_internal_name() const { - return name_.Get(); + return _impl_.name_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.name_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() { - _has_bits_[0] |= 0x00000001u; - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.name_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) if (!_internal_has_name()) { return nullptr; } - _has_bits_[0] &= ~0x00000001u; - auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.name_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.name_.IsDefault()) { + _impl_.name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; + _impl_._has_bits_[0] |= 0x00000001u; } else { - _has_bits_[0] &= ~0x00000001u; + _impl_._has_bits_[0] &= ~0x00000001u; } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + _impl_.name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.name_.IsDefault()) { + _impl_.name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1513,15 +1509,15 @@ inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { // optional string insertion_point = 2; inline bool CodeGeneratorResponse_File::_internal_has_insertion_point() const { - bool value = (_has_bits_[0] & 0x00000002u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; return value; } inline bool CodeGeneratorResponse_File::has_insertion_point() const { return _internal_has_insertion_point(); } inline void CodeGeneratorResponse_File::clear_insertion_point() { - insertion_point_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000002u; + _impl_.insertion_point_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000002u; } inline const std::string& CodeGeneratorResponse_File::insertion_point() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1530,8 +1526,8 @@ inline const std::string& CodeGeneratorResponse_File::insertion_point() const { template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.insertion_point_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() { @@ -1540,41 +1536,40 @@ inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() { return _s; } inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point() const { - return insertion_point_.Get(); + return _impl_.insertion_point_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) { - _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.insertion_point_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() { - _has_bits_[0] |= 0x00000002u; - return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000002u; + return _impl_.insertion_point_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) if (!_internal_has_insertion_point()) { return nullptr; } - _has_bits_[0] &= ~0x00000002u; - auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000002u; + auto* p = _impl_.insertion_point_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.insertion_point_.IsDefault()) { + _impl_.insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* insertion_point) { if (insertion_point != nullptr) { - _has_bits_[0] |= 0x00000002u; + _impl_._has_bits_[0] |= 0x00000002u; } else { - _has_bits_[0] &= ~0x00000002u; + _impl_._has_bits_[0] &= ~0x00000002u; } - insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point, - GetArenaForAllocation()); + _impl_.insertion_point_.SetAllocated(insertion_point, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.insertion_point_.IsDefault()) { + _impl_.insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1582,15 +1577,15 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::strin // optional string content = 15; inline bool CodeGeneratorResponse_File::_internal_has_content() const { - bool value = (_has_bits_[0] & 0x00000004u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; return value; } inline bool CodeGeneratorResponse_File::has_content() const { return _internal_has_content(); } inline void CodeGeneratorResponse_File::clear_content() { - content_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000004u; + _impl_.content_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000004u; } inline const std::string& CodeGeneratorResponse_File::content() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1599,8 +1594,8 @@ inline const std::string& CodeGeneratorResponse_File::content() const { template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000004u; + _impl_.content_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline std::string* CodeGeneratorResponse_File::mutable_content() { @@ -1609,41 +1604,40 @@ inline std::string* CodeGeneratorResponse_File::mutable_content() { return _s; } inline const std::string& CodeGeneratorResponse_File::_internal_content() const { - return content_.Get(); + return _impl_.content_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) { - _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000004u; + _impl_.content_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() { - _has_bits_[0] |= 0x00000004u; - return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000004u; + return _impl_.content_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) if (!_internal_has_content()) { return nullptr; } - _has_bits_[0] &= ~0x00000004u; - auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000004u; + auto* p = _impl_.content_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.content_.IsDefault()) { + _impl_.content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void CodeGeneratorResponse_File::set_allocated_content(std::string* content) { if (content != nullptr) { - _has_bits_[0] |= 0x00000004u; + _impl_._has_bits_[0] |= 0x00000004u; } else { - _has_bits_[0] &= ~0x00000004u; + _impl_._has_bits_[0] &= ~0x00000004u; } - content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content, - GetArenaForAllocation()); + _impl_.content_.SetAllocated(content, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.content_.IsDefault()) { + _impl_.content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1651,15 +1645,15 @@ inline void CodeGeneratorResponse_File::set_allocated_content(std::string* conte // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const { - bool value = (_has_bits_[0] & 0x00000008u) != 0; - PROTOBUF_ASSUME(!value || generated_code_info_ != nullptr); + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; + PROTOBUF_ASSUME(!value || _impl_.generated_code_info_ != nullptr); return value; } inline bool CodeGeneratorResponse_File::has_generated_code_info() const { return _internal_has_generated_code_info(); } inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const { - const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = generated_code_info_; + const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = _impl_.generated_code_info_; return p != nullptr ? *p : reinterpret_cast( ::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_); } @@ -1670,20 +1664,20 @@ inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_F inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info( ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { if (GetArenaForAllocation() == nullptr) { - delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.generated_code_info_); } - generated_code_info_ = generated_code_info; + _impl_.generated_code_info_ = generated_code_info; if (generated_code_info) { - _has_bits_[0] |= 0x00000008u; + _impl_._has_bits_[0] |= 0x00000008u; } else { - _has_bits_[0] &= ~0x00000008u; + _impl_._has_bits_[0] &= ~0x00000008u; } // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) } inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() { - _has_bits_[0] &= ~0x00000008u; - ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; - generated_code_info_ = nullptr; + _impl_._has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = _impl_.generated_code_info_; + _impl_.generated_code_info_ = nullptr; #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); @@ -1697,18 +1691,18 @@ inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::r } inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) - _has_bits_[0] &= ~0x00000008u; - ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; - generated_code_info_ = nullptr; + _impl_._has_bits_[0] &= ~0x00000008u; + ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = _impl_.generated_code_info_; + _impl_.generated_code_info_ = nullptr; return temp; } inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() { - _has_bits_[0] |= 0x00000008u; - if (generated_code_info_ == nullptr) { + _impl_._has_bits_[0] |= 0x00000008u; + if (_impl_.generated_code_info_ == nullptr) { auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(GetArenaForAllocation()); - generated_code_info_ = p; + _impl_.generated_code_info_ = p; } - return generated_code_info_; + return _impl_.generated_code_info_; } inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() { ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _msg = _internal_mutable_generated_code_info(); @@ -1718,22 +1712,21 @@ inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::m inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation(); if (message_arena == nullptr) { - delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.generated_code_info_); } if (generated_code_info) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< - ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)); if (message_arena != submessage_arena) { generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, generated_code_info, submessage_arena); } - _has_bits_[0] |= 0x00000008u; + _impl_._has_bits_[0] |= 0x00000008u; } else { - _has_bits_[0] &= ~0x00000008u; + _impl_._has_bits_[0] &= ~0x00000008u; } - generated_code_info_ = generated_code_info; + _impl_.generated_code_info_ = generated_code_info; // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) } @@ -1743,15 +1736,15 @@ inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROT // optional string error = 1; inline bool CodeGeneratorResponse::_internal_has_error() const { - bool value = (_has_bits_[0] & 0x00000001u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; return value; } inline bool CodeGeneratorResponse::has_error() const { return _internal_has_error(); } inline void CodeGeneratorResponse::clear_error() { - error_.ClearToEmpty(); - _has_bits_[0] &= ~0x00000001u; + _impl_.error_.ClearToEmpty(); + _impl_._has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse::error() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error) @@ -1760,8 +1753,8 @@ inline const std::string& CodeGeneratorResponse::error() const { template inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) { - _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast(arg0), args..., GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.error_.Set(static_cast(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error) } inline std::string* CodeGeneratorResponse::mutable_error() { @@ -1770,41 +1763,40 @@ inline std::string* CodeGeneratorResponse::mutable_error() { return _s; } inline const std::string& CodeGeneratorResponse::_internal_error() const { - return error_.Get(); + return _impl_.error_.Get(); } inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) { - _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + _impl_.error_.Set(value, GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse::_internal_mutable_error() { - _has_bits_[0] |= 0x00000001u; - return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + _impl_._has_bits_[0] |= 0x00000001u; + return _impl_.error_.Mutable(GetArenaForAllocation()); } inline std::string* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) if (!_internal_has_error()) { return nullptr; } - _has_bits_[0] &= ~0x00000001u; - auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + _impl_._has_bits_[0] &= ~0x00000001u; + auto* p = _impl_.error_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.error_.IsDefault()) { + _impl_.error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; } inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { if (error != nullptr) { - _has_bits_[0] |= 0x00000001u; + _impl_._has_bits_[0] |= 0x00000001u; } else { - _has_bits_[0] &= ~0x00000001u; + _impl_._has_bits_[0] &= ~0x00000001u; } - error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error, - GetArenaForAllocation()); + _impl_.error_.SetAllocated(error, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (_impl_.error_.IsDefault()) { + _impl_.error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) @@ -1812,26 +1804,26 @@ inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { // optional uint64 supported_features = 2; inline bool CodeGeneratorResponse::_internal_has_supported_features() const { - bool value = (_has_bits_[0] & 0x00000002u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; return value; } inline bool CodeGeneratorResponse::has_supported_features() const { return _internal_has_supported_features(); } inline void CodeGeneratorResponse::clear_supported_features() { - supported_features_ = uint64_t{0u}; - _has_bits_[0] &= ~0x00000002u; + _impl_.supported_features_ = uint64_t{0u}; + _impl_._has_bits_[0] &= ~0x00000002u; } inline uint64_t CodeGeneratorResponse::_internal_supported_features() const { - return supported_features_; + return _impl_.supported_features_; } inline uint64_t CodeGeneratorResponse::supported_features() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.supported_features) return _internal_supported_features(); } inline void CodeGeneratorResponse::_internal_set_supported_features(uint64_t value) { - _has_bits_[0] |= 0x00000002u; - supported_features_ = value; + _impl_._has_bits_[0] |= 0x00000002u; + _impl_.supported_features_ = value; } inline void CodeGeneratorResponse::set_supported_features(uint64_t value) { _internal_set_supported_features(value); @@ -1840,32 +1832,32 @@ inline void CodeGeneratorResponse::set_supported_features(uint64_t value) { // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; inline int CodeGeneratorResponse::_internal_file_size() const { - return file_.size(); + return _impl_.file_.size(); } inline int CodeGeneratorResponse::file_size() const { return _internal_file_size(); } inline void CodeGeneratorResponse::clear_file() { - file_.Clear(); + _impl_.file_.Clear(); } inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file) - return file_.Mutable(index); + return _impl_.file_.Mutable(index); } inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >* CodeGeneratorResponse::mutable_file() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file) - return &file_; + return &_impl_.file_; } inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::_internal_file(int index) const { - return file_.Get(index); + return _impl_.file_.Get(index); } inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file) return _internal_file(index); } inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::_internal_add_file() { - return file_.Add(); + return _impl_.file_.Add(); } inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _add = _internal_add_file(); @@ -1875,7 +1867,7 @@ inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGenera inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >& CodeGeneratorResponse::file() const { // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file) - return file_; + return _impl_.file_; } #ifdef __GNUC__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/python/generator.cc similarity index 86% rename from third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc rename to third_party/protobuf/src/google/protobuf/compiler/python/generator.cc index 9ad7a33b..d8d6d749 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/python/generator.cc @@ -42,7 +42,7 @@ // performance-minded Python code leverage the fast C++ implementation // directly. -#include +#include #include #include @@ -54,13 +54,15 @@ #include #include +#include #include +#include +#include +#include +#include #include #include #include -#include -#include -#include namespace google { namespace protobuf { @@ -68,16 +70,6 @@ namespace compiler { namespace python { namespace { - - -// Returns the Python module name expected for a given .proto filename. -std::string ModuleName(const std::string& filename) { - std::string basename = StripProto(filename); - ReplaceCharacters(&basename, "-", '_'); - ReplaceCharacters(&basename, "/", '.'); - return basename + "_pb2"; -} - // Returns the alias we assign to the module of the given .proto filename // when importing. See testPackageInitializationImport in // net/proto2/python/internal/reflection_test.py @@ -92,78 +84,13 @@ std::string ModuleAlias(const std::string& filename) { return module_name; } -// Keywords reserved by the Python language. -const char* const kKeywords[] = { - "False", "None", "True", "and", "as", "assert", - "async", "await", "break", "class", "continue", "def", - "del", "elif", "else", "except", "finally", "for", - "from", "global", "if", "import", "in", "is", - "lambda", "nonlocal", "not", "or", "pass", "raise", - "return", "try", "while", "with", "yield", "print", -}; -const char* const* kKeywordsEnd = - kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0])); - -bool ContainsPythonKeyword(const std::string& module_name) { - std::vector tokens = Split(module_name, "."); - for (int i = 0; i < tokens.size(); ++i) { - if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { - return true; - } - } - return false; -} - -inline bool IsPythonKeyword(const std::string& name) { - return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); -} - -std::string ResolveKeyword(const std::string& name) { - if (IsPythonKeyword(name)) { - return "globals()['" + name + "']"; - } - return name; -} - -// Returns the name of all containing types for descriptor, -// in order from outermost to innermost, followed by descriptor's -// own name. Each name is separated by |separator|. -template -std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, - const std::string& separator) { - std::string name = descriptor.name(); - const Descriptor* parent = descriptor.containing_type(); - if (parent != nullptr) { - std::string prefix = NamePrefixedWithNestedTypes(*parent, separator); - if (separator == "." && IsPythonKeyword(name)) { - return "getattr(" + prefix + ", '" + name + "')"; - } else { - return prefix + separator + name; - } - } - if (separator == ".") { - name = ResolveKeyword(name); - } - return name; -} - // Name of the class attribute where we store the Python // descriptor.Descriptor instance for the generated class. // Must stay consistent with the _DESCRIPTOR_KEY constant // in proto2/public/reflection.py. const char kDescriptorKey[] = "DESCRIPTOR"; -// Does the file have top-level enums? -inline bool HasTopLevelEnums(const FileDescriptor* file) { - return file->enum_type_count() > 0; -} -// Should we generate generic services for this file? -inline bool HasGenericServices(const FileDescriptor* file) { - return file->service_count() > 0 && file->options().py_generic_services(); -} - -// Prints the common boilerplate needed at the top of every .py // file output by this generator. void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { @@ -174,27 +101,16 @@ void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, "# source: $filename$\n" "\"\"\"Generated protocol buffer code.\"\"\"\n", "filename", file->name()); - if (HasTopLevelEnums(file)) { - printer->Print( - "from google.protobuf.internal import enum_type_wrapper\n"); - } printer->Print( + "from google.protobuf.internal import builder as _builder\n" "from google.protobuf import descriptor as _descriptor\n" "from google.protobuf import descriptor_pool as " "_descriptor_pool\n" - "from google.protobuf import message as _message\n" - "from google.protobuf import reflection as _reflection\n" "from google.protobuf import symbol_database as " "_symbol_database\n"); - if (HasGenericServices(file)) { - printer->Print( - "from google.protobuf import service as _service\n" - "from google.protobuf import service_reflection\n"); - } - printer->Print( - "# @@protoc_insertion_point(imports)\n\n" - "_sym_db = _symbol_database.Default()\n"); + printer->Print("# @@protoc_insertion_point(imports)\n\n"); + printer->Print("_sym_db = _symbol_database.Default()\n"); printer->Print("\n\n"); } @@ -309,6 +225,11 @@ bool Generator::Generate(const FileDescriptor* file, for (int i = 0; i < options.size(); i++) { if (options[i].first == "cpp_generated_lib_linked") { cpp_generated_lib_linked = true; + } else if (options[i].first == "pyi_out") { + python::PyiGenerator pyi_generator; + if (!pyi_generator.Generate(file, "", context, error)) { + return false; + } } else { *error = "Unknown generator option: " + options[i].first; return false; @@ -324,11 +245,8 @@ bool Generator::Generate(const FileDescriptor* file, // to have any mutable members. Then it is implicitly thread-safe. MutexLock lock(&mutex_); file_ = file; - std::string module_name = ModuleName(file->name()); - std::string filename = module_name; - ReplaceCharacters(&filename, ".", '/'); - filename += ".py"; + std::string filename = GetFileName(file, ".py"); pure_python_workable_ = !cpp_generated_lib_linked; if (HasPrefixString(file->name(), "google/protobuf/")) { pure_python_workable_ = true; @@ -349,15 +267,13 @@ bool Generator::Generate(const FileDescriptor* file, PrintImports(); } PrintFileDescriptor(); - PrintTopLevelEnums(); - PrintTopLevelExtensions(); if (pure_python_workable_) { if (GeneratingDescriptorProto()) { printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); // Create enums before message descriptors - PrintAllNestedEnumsInFile(StripPrintDescriptor::kCreate); - PrintMessageDescriptors(StripPrintDescriptor::kCreate); + PrintAllNestedEnumsInFile(); + PrintMessageDescriptors(); FixForeignFieldsInDescriptors(); printer_->Outdent(); printer_->Print("else:\n"); @@ -365,16 +281,18 @@ bool Generator::Generate(const FileDescriptor* file, } // Find the message descriptors first and then use the message // descriptor to find enums. - PrintMessageDescriptors(StripPrintDescriptor::kFind); - PrintAllNestedEnumsInFile(StripPrintDescriptor::kFind); + printer_->Print( + "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())\n"); if (GeneratingDescriptorProto()) { printer_->Outdent(); } } - PrintMessages(); + std::string module_name = ModuleName(file->name()); + printer_->Print( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, '$module_name$', " + "globals())\n", + "module_name", module_name); if (pure_python_workable_) { - PrintServiceDescriptors(); - printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); @@ -395,7 +313,9 @@ bool Generator::Generate(const FileDescriptor* file, printer_->Outdent(); } if (HasGenericServices(file)) { - PrintServices(); + printer_->Print( + "_builder.BuildServices(DESCRIPTOR, '$module_name$', globals())\n", + "module_name", module_name); } printer.Print("# @@protoc_insertion_point(module_scope)\n"); @@ -403,7 +323,6 @@ bool Generator::Generate(const FileDescriptor* file, return !printer.failed(); } - // Prints Python imports for all modules imported by |file|. void Generator::PrintImports() const { for (int i = 0; i < file_->dependency_count(); ++i) { @@ -516,47 +435,17 @@ void Generator::PrintFileDescriptor() const { printer_->Print("\n"); } -// Prints descriptors and module-level constants for all top-level -// enums defined in |file|. -void Generator::PrintTopLevelEnums() const { - std::vector > top_level_enum_values; - for (int i = 0; i < file_->enum_type_count(); ++i) { - const EnumDescriptor& enum_descriptor = *file_->enum_type(i); - PrintFindEnum(enum_descriptor); - printer_->Print( - "$name$ = " - "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", - "name", ResolveKeyword(enum_descriptor.name()), "descriptor_name", - ModuleLevelDescriptorName(enum_descriptor)); - printer_->Print("\n"); - - for (int j = 0; j < enum_descriptor.value_count(); ++j) { - const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); - top_level_enum_values.push_back( - std::make_pair(value_descriptor.name(), value_descriptor.number())); - } - } - - for (int i = 0; i < top_level_enum_values.size(); ++i) { - printer_->Print("$name$ = $value$\n", "name", - ResolveKeyword(top_level_enum_values[i].first), "value", - StrCat(top_level_enum_values[i].second)); - } - printer_->Print("\n"); -} - // Prints all enums contained in all message types in |file|. -void Generator::PrintAllNestedEnumsInFile( - StripPrintDescriptor print_mode) const { +void Generator::PrintAllNestedEnumsInFile() const { for (int i = 0; i < file_->message_type_count(); ++i) { - PrintNestedEnums(*file_->message_type(i), print_mode); + PrintNestedEnums(*file_->message_type(i)); } } // Prints a Python statement assigning the appropriate module-level // enum name to a Python EnumDescriptor object equivalent to // enum_descriptor. -void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { +void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { std::map m; std::string module_level_descriptor_name = ModuleLevelDescriptorName(enum_descriptor); @@ -600,68 +489,23 @@ void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { printer_->Print("\n"); } -void Generator::PrintFindEnum(const EnumDescriptor& enum_descriptor) const { - std::map m; - m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); - m["name"] = enum_descriptor.name(); - m["file"] = kDescriptorKey; - if (enum_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*enum_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.enum_types_by_name['$name$']\n"); - } else { - printer_->Print( - m, "$descriptor_name$ = $file$.enum_types_by_name['$name$']\n"); - } -} - // Recursively prints enums in nested types within descriptor, then // prints enums contained at the top level in descriptor. -void Generator::PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const { +void Generator::PrintNestedEnums(const Descriptor& descriptor) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { - PrintNestedEnums(*descriptor.nested_type(i), print_mode); + PrintNestedEnums(*descriptor.nested_type(i)); } for (int i = 0; i < descriptor.enum_type_count(); ++i) { - if (print_mode == StripPrintDescriptor::kCreate) { - PrintCreateEnum(*descriptor.enum_type(i)); - } else { - PrintFindEnum(*descriptor.enum_type(i)); - } + PrintEnum(*descriptor.enum_type(i)); } } -void Generator::PrintTopLevelExtensions() const { - for (int i = 0; i < file_->extension_count(); ++i) { - const FieldDescriptor& extension_field = *file_->extension(i); - std::string constant_name = extension_field.name() + "_FIELD_NUMBER"; - ToUpper(&constant_name); - printer_->Print("$constant_name$ = $number$\n", "constant_name", - constant_name, "number", - StrCat(extension_field.number())); - printer_->Print( - "$resolved_name$ = " - "$file$.extensions_by_name['$name$']\n", - "resolved_name", ResolveKeyword(extension_field.name()), "file", - kDescriptorKey, "name", extension_field.name()); - } - printer_->Print("\n"); -} - // Prints Python equivalents of all Descriptors in |file|. -void Generator::PrintMessageDescriptors(StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintCreateDescriptor(*file_->message_type(i)); - printer_->Print("\n"); - } - } else { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintFindDescriptor(*file_->message_type(i)); - } +void Generator::PrintMessageDescriptors() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintDescriptor(*file_->message_type(i)); + printer_->Print("\n"); } } @@ -730,14 +574,13 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { // to a Python Descriptor object for message_descriptor. // // Mutually recursive with PrintNestedDescriptors(). -void Generator::PrintCreateDescriptor( - const Descriptor& message_descriptor) const { +void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { std::map m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); m["file"] = kDescriptorKey; - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kCreate); + PrintNestedDescriptors(message_descriptor); printer_->Print("\n"); printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", @@ -823,41 +666,14 @@ void Generator::PrintCreateDescriptor( printer_->Print(")\n"); } -void Generator::PrintFindDescriptor( - const Descriptor& message_descriptor) const { - std::map m; - m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); - m["name"] = message_descriptor.name(); - - if (message_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*message_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.nested_types_by_name['$name$']\n"); - } else { - m["file"] = kDescriptorKey; - printer_->Print( - m, "$descriptor_name$ = $file$.message_types_by_name['$name$']\n"); - } - - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kFind); -} - // Prints Python Descriptor objects for all nested types contained in // message_descriptor. // // Mutually recursive with PrintDescriptor(). -void Generator::PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintCreateDescriptor(*containing_descriptor.nested_type(i)); - } - } else { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintFindDescriptor(*containing_descriptor.nested_type(i)); - } +void Generator::PrintNestedDescriptors( + const Descriptor& containing_descriptor) const { + for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { + PrintDescriptor(*containing_descriptor.nested_type(i)); } } @@ -1463,7 +1279,7 @@ void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { if (value_options != "None") { PrintDescriptorOptionsFixingCode( StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), - value_descriptor.name().c_str()), + value_descriptor.name().c_str()), value_options, printer_); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/generator.h b/third_party/protobuf/src/google/protobuf/compiler/python/generator.h new file mode 100644 index 00000000..f1fecbc7 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/python/generator.h @@ -0,0 +1,185 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) +// +// Generates Python code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ + +#include + +#include +#include + +// Must be included last. +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class FieldDescriptor; +class OneofDescriptor; +class ServiceDescriptor; + +namespace io { +class Printer; +} + +namespace compiler { +namespace python { + +// CodeGenerator implementation for generated Python protocol buffer classes. +// If you create your own protocol compiler binary and you want it to support +// Python output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class PROTOC_EXPORT Generator : public CodeGenerator { + public: + Generator(); + ~Generator() override; + + // CodeGenerator methods. + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; + + private: + void PrintImports() const; + void PrintFileDescriptor() const; + void PrintAllNestedEnumsInFile() const; + void PrintNestedEnums(const Descriptor& descriptor) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + + void PrintFieldDescriptor(const FieldDescriptor& field, + bool is_extension) const; + void PrintFieldDescriptorsInDescriptor( + const Descriptor& message_descriptor, bool is_extension, + const std::string& list_variable_name, int (Descriptor::*CountFn)() const, + const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const; + void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; + void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; + void PrintMessageDescriptors() const; + void PrintDescriptor(const Descriptor& message_descriptor) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; + + void PrintMessages() const; + void PrintMessage(const Descriptor& message_descriptor, + const std::string& prefix, + std::vector* to_register, + bool is_nested) const; + void PrintNestedMessages(const Descriptor& containing_descriptor, + const std::string& prefix, + std::vector* to_register) const; + + void FixForeignFieldsInDescriptors() const; + void FixForeignFieldsInDescriptor( + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const; + void FixForeignFieldsInField(const Descriptor* containing_type, + const FieldDescriptor& field, + const std::string& python_dict_name) const; + void AddMessageToFileDescriptor(const Descriptor& descriptor) const; + void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const; + void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const; + void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const; + std::string FieldReferencingExpression( + const Descriptor* containing_type, const FieldDescriptor& field, + const std::string& python_dict_name) const; + template + void FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const; + + void FixForeignFieldsInExtensions() const; + void FixForeignFieldsInExtension( + const FieldDescriptor& extension_field) const; + void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; + + void PrintServices() const; + void PrintServiceDescriptors() const; + void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; + void PrintServiceClass(const ServiceDescriptor& descriptor) const; + void PrintServiceStub(const ServiceDescriptor& descriptor) const; + void PrintDescriptorKeyAndModuleName( + const ServiceDescriptor& descriptor) const; + + void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; + std::string OptionsValue(const std::string& serialized_options) const; + bool GeneratingDescriptorProto() const; + + template + std::string ModuleLevelDescriptorName(const DescriptorT& descriptor) const; + std::string ModuleLevelMessageName(const Descriptor& descriptor) const; + std::string ModuleLevelServiceDescriptorName( + const ServiceDescriptor& descriptor) const; + + template + void PrintSerializedPbInterval(const DescriptorT& descriptor, + DescriptorProtoT& proto, + const std::string& name) const; + + void FixAllDescriptorOptions() const; + void FixOptionsForField(const FieldDescriptor& field) const; + void FixOptionsForOneof(const OneofDescriptor& oneof) const; + void FixOptionsForEnum(const EnumDescriptor& descriptor) const; + void FixOptionsForService(const ServiceDescriptor& descriptor) const; + void FixOptionsForMessage(const Descriptor& descriptor) const; + + void SetSerializedPbInterval() const; + void SetMessagePbInterval(const Descriptor& descriptor) const; + + void CopyPublicDependenciesAliases(const std::string& copy_from, + const FileDescriptor* file) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_, printer_ and file_descriptor_serialized_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable std::string file_descriptor_serialized_; + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + mutable bool pure_python_workable_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/python/helpers.cc new file mode 100644 index 00000000..e4d3c138 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/python/helpers.cc @@ -0,0 +1,131 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +// Returns the Python module name expected for a given .proto filename. +std::string ModuleName(const std::string& filename) { + std::string basename = StripProto(filename); + ReplaceCharacters(&basename, "-", '_'); + ReplaceCharacters(&basename, "/", '.'); + return basename + "_pb2"; +} + +std::string StrippedModuleName(const std::string& filename) { + std::string module_name = ModuleName(filename); + return module_name; +} + +// Keywords reserved by the Python language. +const char* const kKeywords[] = { + "False", "None", "True", "and", "as", "assert", + "async", "await", "break", "class", "continue", "def", + "del", "elif", "else", "except", "finally", "for", + "from", "global", "if", "import", "in", "is", + "lambda", "nonlocal", "not", "or", "pass", "raise", + "return", "try", "while", "with", "yield", +}; +const char* const* kKeywordsEnd = + kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0])); + +bool ContainsPythonKeyword(const std::string& module_name) { + std::vector tokens = Split(module_name, "."); + for (int i = 0; i < static_cast(tokens.size()); ++i) { + if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { + return true; + } + } + return false; +} + +bool IsPythonKeyword(const std::string& name) { + return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); +} + +std::string ResolveKeyword(const std::string& name) { + if (IsPythonKeyword(name)) { + return "globals()['" + name + "']"; + } + return name; +} + +std::string GetFileName(const FileDescriptor* file_des, + const std::string& suffix) { + std::string module_name = ModuleName(file_des->name()); + std::string filename = module_name; + ReplaceCharacters(&filename, ".", '/'); + filename += suffix; + return filename; +} + +bool HasGenericServices(const FileDescriptor* file) { + return file->service_count() > 0 && file->options().py_generic_services(); +} + +template +std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const std::string& separator) { + std::string name = descriptor.name(); + const Descriptor* parent = descriptor.containing_type(); + if (parent != nullptr) { + std::string prefix = NamePrefixedWithNestedTypes(*parent, separator); + if (separator == "." && IsPythonKeyword(name)) { + return "getattr(" + prefix + ", '" + name + "')"; + } else { + return prefix + separator + name; + } + } + if (separator == ".") { + name = ResolveKeyword(name); + } + return name; +} + +template std::string NamePrefixedWithNestedTypes( + const Descriptor& descriptor, const std::string& separator); +template std::string NamePrefixedWithNestedTypes( + const EnumDescriptor& descriptor, const std::string& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.h b/third_party/protobuf/src/google/protobuf/compiler/python/helpers.h similarity index 64% rename from third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.h rename to third_party/protobuf/src/google/protobuf/compiler/python/helpers.h index 174c665e..a68ceb19 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.h +++ b/third_party/protobuf/src/google/protobuf/compiler/python/helpers.h @@ -28,16 +28,35 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ -#define GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ -#include +#include -struct FileToc { - const char* name; - const char* data; -}; +#include -extern struct FileToc well_known_types_js[]; +namespace google { +namespace protobuf { +namespace compiler { +namespace python { -#endif // GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ + +std::string ModuleName(const std::string& filename); +std::string StrippedModuleName(const std::string& filename); +bool ContainsPythonKeyword(const std::string& module_name); +bool IsPythonKeyword(const std::string& name); +std::string ResolveKeyword(const std::string& name); +std::string GetFileName(const FileDescriptor* file_des, + const std::string& suffix); +bool HasGenericServices(const FileDescriptor* file); + +template +std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const std::string& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/python/plugin_unittest.cc similarity index 74% rename from third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc rename to third_party/protobuf/src/google/protobuf/compiler/python/plugin_unittest.cc index 76ceef32..7f9589b8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/python/plugin_unittest.cc @@ -29,17 +29,14 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) -// -// TODO(kenton): Share code with the versions of this test in other languages? -// It seemed like parameterizing it would add more complexity than it is -// worth. #include +#include #include #include #include -#include +#include #include #include #include @@ -55,11 +52,10 @@ namespace { class TestGenerator : public CodeGenerator { public: TestGenerator() {} - ~TestGenerator() {} + ~TestGenerator() override {} - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const { + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override { TryInsert("test_pb2.py", "imports", context); TryInsert("test_pb2.py", "module_scope", context); TryInsert("test_pb2.py", "class_scope:foo.Bar", context); @@ -77,37 +73,6 @@ class TestGenerator : public CodeGenerator { } }; -// This test verifies that all the expected insertion points exist. It does -// not verify that they are correctly-placed; that would require actually -// compiling the output which is a bit more than I care to do for this test. -TEST(PythonPluginTest, PluginTest) { - GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto", - "syntax = \"proto2\";\n" - "package foo;\n" - "message Bar {\n" - " message Baz {}\n" - "}\n", - true)); - - compiler::CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); - - python::Generator python_generator; - TestGenerator test_generator; - cli.RegisterGenerator("--python_out", &python_generator, ""); - cli.RegisterGenerator("--test_out", &test_generator, ""); - - std::string proto_path = "-I" + TestTempDir(); - std::string python_out = "--python_out=" + TestTempDir(); - std::string test_out = "--test_out=" + TestTempDir(); - - const char* argv[] = {"protoc", proto_path.c_str(), python_out.c_str(), - test_out.c_str(), "test.proto"}; - - EXPECT_EQ(0, cli.Run(5, argv)); -} - -// This test verifies that the generated Python output uses regular imports (as // opposed to importlib) in the usual case where the .proto file paths do not // not contain any Python keywords. TEST(PythonPluginTest, ImportTest) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.cc new file mode 100644 index 00000000..1ccc9a21 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.cc @@ -0,0 +1,636 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +template +struct SortByName { + bool operator()(const DescriptorT* l, const DescriptorT* r) const { + return l->name() < r->name(); + } +}; + +PyiGenerator::PyiGenerator() : file_(nullptr) {} + +PyiGenerator::~PyiGenerator() {} + +void PyiGenerator::PrintItemMap( + const std::map& item_map) const { + for (const auto& entry : item_map) { + printer_->Print("$key$: $value$\n", "key", entry.first, "value", + entry.second); + } +} + +template +std::string PyiGenerator::ModuleLevelName( + const DescriptorT& descriptor, + const std::map& import_map) const { + std::string name = NamePrefixedWithNestedTypes(descriptor, "."); + if (descriptor.file() != file_) { + std::string module_alias; + std::string filename = descriptor.file()->name(); + if (import_map.find(filename) == import_map.end()) { + std::string module_name = ModuleName(descriptor.file()->name()); + std::vector tokens = Split(module_name, "."); + module_alias = "_" + tokens.back(); + } else { + module_alias = import_map.at(filename); + } + name = module_alias + "." + name; + } + return name; +} + +struct ImportModules { + bool has_repeated = false; // _containers + bool has_iterable = false; // typing.Iterable + bool has_messages = false; // _message + bool has_enums = false; // _enum_type_wrapper + bool has_extendable = false; // _python_message + bool has_mapping = false; // typing.Mapping + bool has_optional = false; // typing.Optional + bool has_union = false; // typing.Union + bool has_well_known_type = false; +}; + +// Checks whether a descriptor name matches a well-known type. +bool IsWellKnownType(const std::string& name) { + // LINT.IfChange(wktbases) + return (name == "google.protobuf.Any" || + name == "google.protobuf.Duration" || + name == "google.protobuf.FieldMask" || + name == "google.protobuf.ListValue" || + name == "google.protobuf.Struct" || + name == "google.protobuf.Timestamp"); + // LINT.ThenChange(//depot/google3/net/proto2/python/internal/well_known_types.py:wktbases) +} + +// Checks what modules should be imported for this message +// descriptor. +void CheckImportModules(const Descriptor* descriptor, + ImportModules* import_modules) { + if (descriptor->extension_range_count() > 0) { + import_modules->has_extendable = true; + } + if (descriptor->enum_type_count() > 0) { + import_modules->has_enums = true; + } + if (IsWellKnownType(descriptor->full_name())) { + import_modules->has_well_known_type = true; + } + for (int i = 0; i < descriptor->field_count(); ++i) { + const FieldDescriptor* field = descriptor->field(i); + if (IsPythonKeyword(field->name())) { + continue; + } + import_modules->has_optional = true; + if (field->is_repeated()) { + import_modules->has_repeated = true; + } + if (field->is_map()) { + import_modules->has_mapping = true; + const FieldDescriptor* value_des = field->message_type()->field(1); + if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + value_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } else { + if (field->is_repeated()) { + import_modules->has_iterable = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + import_modules->has_union = true; + import_modules->has_mapping = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } + } + for (int i = 0; i < descriptor->nested_type_count(); ++i) { + CheckImportModules(descriptor->nested_type(i), import_modules); + } +} + +void PyiGenerator::PrintImportForDescriptor( + const FileDescriptor& desc, + std::map* import_map, + std::set* seen_aliases) const { + const std::string& filename = desc.name(); + std::string module_name = StrippedModuleName(filename); + size_t last_dot_pos = module_name.rfind('.'); + std::string import_statement; + if (last_dot_pos == std::string::npos) { + import_statement = "import " + module_name; + } else { + import_statement = "from " + module_name.substr(0, last_dot_pos) + + " import " + module_name.substr(last_dot_pos + 1); + module_name = module_name.substr(last_dot_pos + 1); + } + std::string alias = "_" + module_name; + // Generate a unique alias by adding _1 suffixes until we get an unused alias. + while (seen_aliases->find(alias) != seen_aliases->end()) { + alias = alias + "_1"; + } + printer_->Print("$statement$ as $alias$\n", "statement", + import_statement, "alias", alias); + (*import_map)[filename] = alias; + seen_aliases->insert(alias); +} + +void PyiGenerator::PrintImports( + std::map* item_map, + std::map* import_map) const { + // Prints imported dependent _pb2 files. + std::set seen_aliases; + for (int i = 0; i < file_->dependency_count(); ++i) { + const FileDescriptor* dep = file_->dependency(i); + PrintImportForDescriptor(*dep, import_map, &seen_aliases); + for (int j = 0; j < dep->public_dependency_count(); ++j) { + PrintImportForDescriptor( + *dep->public_dependency(j), import_map, &seen_aliases); + } + } + + // Checks what modules should be imported. + ImportModules import_modules; + if (file_->message_type_count() > 0) { + import_modules.has_messages = true; + } + if (file_->enum_type_count() > 0) { + import_modules.has_enums = true; + } + for (int i = 0; i < file_->message_type_count(); i++) { + CheckImportModules(file_->message_type(i), &import_modules); + } + + // Prints modules (e.g. _containers, _messages, typing) that are + // required in the proto file. + if (import_modules.has_repeated) { + printer_->Print( + "from google.protobuf.internal import containers as " + "_containers\n"); + } + if (import_modules.has_enums) { + printer_->Print( + "from google.protobuf.internal import enum_type_wrapper" + " as _enum_type_wrapper\n"); + } + if (import_modules.has_extendable) { + printer_->Print( + "from google.protobuf.internal import python_message" + " as _python_message\n"); + } + if (import_modules.has_well_known_type) { + printer_->Print( + "from google.protobuf.internal import well_known_types" + " as _well_known_types\n"); + } + printer_->Print( + "from google.protobuf import" + " descriptor as _descriptor\n"); + if (import_modules.has_messages) { + printer_->Print( + "from google.protobuf import message as _message\n"); + } + if (HasGenericServices(file_)) { + printer_->Print( + "from google.protobuf import service as" + " _service\n"); + } + printer_->Print("from typing import "); + printer_->Print("ClassVar as _ClassVar"); + if (import_modules.has_iterable) { + printer_->Print(", Iterable as _Iterable"); + } + if (import_modules.has_mapping) { + printer_->Print(", Mapping as _Mapping"); + } + if (import_modules.has_optional) { + printer_->Print(", Optional as _Optional"); + } + if (import_modules.has_union) { + printer_->Print(", Union as _Union"); + } + printer_->Print("\n\n"); + + // Public imports + for (int i = 0; i < file_->public_dependency_count(); ++i) { + const FileDescriptor* public_dep = file_->public_dependency(i); + std::string module_name = StrippedModuleName(public_dep->name()); + // Top level messages in public imports + for (int i = 0; i < public_dep->message_type_count(); ++i) { + printer_->Print("from $module$ import $message_class$\n", "module", + module_name, "message_class", + public_dep->message_type(i)->name()); + } + // Top level enums for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + printer_->Print("from $module$ import $enum_class$\n", "module", + module_name, "enum_class", + public_dep->enum_type(i)->name()); + } + // Enum values for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + const EnumDescriptor* enum_descriptor = public_dep->enum_type(i); + for (int j = 0; j < enum_descriptor->value_count(); ++j) { + (*item_map)[enum_descriptor->value(j)->name()] = + ModuleLevelName(*enum_descriptor, *import_map); + } + } + // Top level extensions for public imports + AddExtensions(*public_dep, item_map); + } +} + +void PyiGenerator::PrintEnum(const EnumDescriptor& enum_descriptor) const { + std::string enum_name = enum_descriptor.name(); + printer_->Print( + "class $enum_name$(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):\n" + " __slots__ = []\n", + "enum_name", enum_name); +} + +// Adds enum value to item map which will be ordered and printed later. +void PyiGenerator::AddEnumValue( + const EnumDescriptor& enum_descriptor, + std::map* item_map, + const std::map& import_map) const { + // enum values + std::string module_enum_name = ModuleLevelName(enum_descriptor, import_map); + for (int j = 0; j < enum_descriptor.value_count(); ++j) { + const EnumValueDescriptor* value_descriptor = enum_descriptor.value(j); + (*item_map)[value_descriptor->name()] = module_enum_name; + } +} + +// Prints top level enums +void PyiGenerator::PrintTopLevelEnums() const { + for (int i = 0; i < file_->enum_type_count(); ++i) { + printer_->Print("\n"); + PrintEnum(*file_->enum_type(i)); + } +} + +// Add top level extensions to item_map which will be ordered and +// printed later. +template +void PyiGenerator::AddExtensions( + const DescriptorT& descriptor, + std::map* item_map) const { + for (int i = 0; i < descriptor.extension_count(); ++i) { + const FieldDescriptor* extension_field = descriptor.extension(i); + std::string constant_name = extension_field->name() + "_FIELD_NUMBER"; + ToUpper(&constant_name); + (*item_map)[constant_name] = "_ClassVar[int]"; + (*item_map)[extension_field->name()] = "_descriptor.FieldDescriptor"; + } +} + +// Returns the string format of a field's cpp_type +std::string PyiGenerator::GetFieldType( + const FieldDescriptor& field_des, const Descriptor& containing_des, + const std::map& import_map) const { + switch (field_des.cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + return "int"; + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + return "float"; + case FieldDescriptor::CPPTYPE_BOOL: + return "bool"; + case FieldDescriptor::CPPTYPE_ENUM: + return ModuleLevelName(*field_des.enum_type(), import_map); + case FieldDescriptor::CPPTYPE_STRING: + if (field_des.type() == FieldDescriptor::TYPE_STRING) { + return "str"; + } else { + return "bytes"; + } + case FieldDescriptor::CPPTYPE_MESSAGE: { + // If the field is inside a nested message and the nested message has the + // same name as a top-level message, then we need to prefix the field type + // with the module name for disambiguation. + std::string name = ModuleLevelName(*field_des.message_type(), import_map); + if ((containing_des.containing_type() != nullptr && + name == containing_des.name())) { + std::string module = ModuleName(field_des.file()->name()); + name = module + "." + name; + } + return name; + } + default: + GOOGLE_LOG(FATAL) << "Unsupported field type."; + } + return ""; +} + +void PyiGenerator::PrintMessage( + const Descriptor& message_descriptor, bool is_nested, + const std::map& import_map) const { + if (!is_nested) { + printer_->Print("\n"); + } + std::string class_name = message_descriptor.name(); + std::string extra_base; + // A well-known type needs to inherit from its corresponding base class in + // net/proto2/python/internal/well_known_types. + if (IsWellKnownType(message_descriptor.full_name())) { + extra_base = ", _well_known_types." + message_descriptor.name(); + } else { + extra_base = ""; + } + printer_->Print("class $class_name$(_message.Message$extra_base$):\n", + "class_name", class_name, "extra_base", extra_base); + printer_->Indent(); + printer_->Indent(); + + std::vector fields; + fields.reserve(message_descriptor.field_count()); + for (int i = 0; i < message_descriptor.field_count(); ++i) { + fields.push_back(message_descriptor.field(i)); + } + std::sort(fields.begin(), fields.end(), SortByName()); + + // Prints slots + printer_->Print("__slots__ = [", "class_name", class_name); + bool first_item = true; + for (const auto& field_des : fields) { + if (IsPythonKeyword(field_des->name())) { + continue; + } + if (first_item) { + first_item = false; + } else { + printer_->Print(", "); + } + printer_->Print("\"$field_name$\"", "field_name", field_des->name()); + } + printer_->Print("]\n"); + + std::map item_map; + // Prints Extensions for extendable messages + if (message_descriptor.extension_range_count() > 0) { + item_map["Extensions"] = "_python_message._ExtensionDict"; + } + + // Prints nested enums + std::vector nested_enums; + nested_enums.reserve(message_descriptor.enum_type_count()); + for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { + nested_enums.push_back(message_descriptor.enum_type(i)); + } + std::sort(nested_enums.begin(), nested_enums.end(), + SortByName()); + + for (const auto& entry : nested_enums) { + PrintEnum(*entry); + // Adds enum value to item_map which will be ordered and printed later + AddEnumValue(*entry, &item_map, import_map); + } + + // Prints nested messages + std::vector nested_messages; + nested_messages.reserve(message_descriptor.nested_type_count()); + for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { + nested_messages.push_back(message_descriptor.nested_type(i)); + } + std::sort(nested_messages.begin(), nested_messages.end(), + SortByName()); + + for (const auto& entry : nested_messages) { + PrintMessage(*entry, true, import_map); + } + + // Adds extensions to item_map which will be ordered and printed later + AddExtensions(message_descriptor, &item_map); + + // Adds field number and field descriptor to item_map + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor& field_des = *message_descriptor.field(i); + item_map[ToUpper(field_des.name()) + "_FIELD_NUMBER"] = + "_ClassVar[int]"; + if (IsPythonKeyword(field_des.name())) { + continue; + } + std::string field_type = ""; + if (field_des.is_map()) { + const FieldDescriptor* key_des = field_des.message_type()->field(0); + const FieldDescriptor* value_des = field_des.message_type()->field(1); + field_type = (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.MessageMap[" + : "_containers.ScalarMap["); + field_type += GetFieldType(*key_des, message_descriptor, import_map); + field_type += ", "; + field_type += GetFieldType(*value_des, message_descriptor, import_map); + } else { + if (field_des.is_repeated()) { + field_type = (field_des.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.RepeatedCompositeFieldContainer[" + : "_containers.RepeatedScalarFieldContainer["); + } + field_type += GetFieldType(field_des, message_descriptor, import_map); + } + + if (field_des.is_repeated()) { + field_type += "]"; + } + item_map[field_des.name()] = field_type; + } + + // Prints all items in item_map + PrintItemMap(item_map); + + // Prints __init__ + printer_->Print("def __init__(self"); + bool has_key_words = false; + bool is_first = true; + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor* field_des = message_descriptor.field(i); + if (IsPythonKeyword(field_des->name())) { + has_key_words = true; + continue; + } + std::string field_name = field_des->name(); + if (is_first && field_name == "self") { + // See b/144146793 for an example of real code that generates a (self, + // self) method signature. Since repeating a parameter name is illegal in + // Python, we rename the duplicate self. + field_name = "self_"; + } + is_first = false; + printer_->Print(", $field_name$: ", "field_name", field_name); + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("_Optional["); + } + if (field_des->is_map()) { + const Descriptor* map_entry = field_des->message_type(); + printer_->Print( + "_Mapping[$key_type$, $value_type$]", "key_type", + GetFieldType(*map_entry->field(0), message_descriptor, import_map), + "value_type", + GetFieldType(*map_entry->field(1), message_descriptor, import_map)); + } else { + if (field_des->is_repeated()) { + printer_->Print("_Iterable["); + } + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer_->Print( + "_Union[$type_name$, _Mapping]", "type_name", + GetFieldType(*field_des, message_descriptor, import_map)); + } else { + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer_->Print("_Union[$type_name$, str]", "type_name", + ModuleLevelName(*field_des->enum_type(), import_map)); + } else { + printer_->Print( + "$type_name$", "type_name", + GetFieldType(*field_des, message_descriptor, import_map)); + } + } + if (field_des->is_repeated()) { + printer_->Print("]"); + } + } + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("]"); + } + printer_->Print(" = ..."); + } + if (has_key_words) { + printer_->Print(", **kwargs"); + } + printer_->Print(") -> None: ...\n"); + + printer_->Outdent(); + printer_->Outdent(); +} + +void PyiGenerator::PrintMessages( + const std::map& import_map) const { + // Deterministically order the descriptors. + std::vector messages; + messages.reserve(file_->message_type_count()); + for (int i = 0; i < file_->message_type_count(); ++i) { + messages.push_back(file_->message_type(i)); + } + std::sort(messages.begin(), messages.end(), SortByName()); + + for (const auto& entry : messages) { + PrintMessage(*entry, false, import_map); + } +} + +void PyiGenerator::PrintServices() const { + std::vector services; + services.reserve(file_->service_count()); + for (int i = 0; i < file_->service_count(); ++i) { + services.push_back(file_->service(i)); + } + std::sort(services.begin(), services.end(), SortByName()); + + // Prints $Service$ and $Service$_Stub classes + for (const auto& entry : services) { + printer_->Print("\n"); + printer_->Print( + "class $service_name$(_service.service): ...\n\n" + "class $service_name$_Stub($service_name$): ...\n", + "service_name", entry->name()); + } +} + +bool PyiGenerator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* context, + std::string* error) const { + MutexLock lock(&mutex_); + // Calculate file name. + file_ = file; + std::string filename = + parameter.empty() ? GetFileName(file, ".pyi") : parameter; + + std::unique_ptr output(context->Open(filename)); + GOOGLE_CHECK(output.get()); + io::Printer printer(output.get(), '$'); + printer_ = &printer; + + // item map will store "DESCRIPTOR", top level extensions, top level enum + // values. The items will be sorted and printed later. + std::map item_map; + + // Adds "DESCRIPTOR" into item_map. + item_map["DESCRIPTOR"] = "_descriptor.FileDescriptor"; + + // import_map will be a mapping from filename to module alias, e.g. + // "google3/foo/bar.py" -> "_bar" + std::map import_map; + + PrintImports(&item_map, &import_map); + // Adds top level enum values to item_map. + for (int i = 0; i < file_->enum_type_count(); ++i) { + AddEnumValue(*file_->enum_type(i), &item_map, import_map); + } + // Adds top level extensions to item_map. + AddExtensions(*file_, &item_map); + // Prints item map + PrintItemMap(item_map); + + PrintMessages(import_map); + PrintTopLevelEnums(); + if (HasGenericServices(file)) { + PrintServices(); + } + return true; +} + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.h b/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.h new file mode 100644 index 00000000..9611ed43 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/python/pyi_generator.h @@ -0,0 +1,120 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jieluo@google.com (Jie Luo) +// +// Generates Python stub (.pyi) for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ + +#include +#include +#include + +#include +#include + +// Must be included last. +#include + +namespace google { +namespace protobuf { +class Descriptor; +class EnumDescriptor; +class FieldDescriptor; +class MethodDescriptor; +class ServiceDescriptor; + +namespace io { +class Printer; +} + +namespace compiler { +namespace python { + +class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenerator { + public: + PyiGenerator(); + ~PyiGenerator() override; + + // CodeGenerator methods. + uint64_t GetSupportedFeatures() const override { + // Code generators must explicitly support proto3 optional. + return CodeGenerator::FEATURE_PROTO3_OPTIONAL; + } + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + private: + void PrintImportForDescriptor(const FileDescriptor& desc, + std::map* import_map, + std::set* seen_aliases) const; + void PrintImports(std::map* item_map, + std::map* import_map) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + void AddEnumValue(const EnumDescriptor& enum_descriptor, + std::map* item_map, + const std::map& import_map) const; + void PrintTopLevelEnums() const; + template + void AddExtensions(const DescriptorT& descriptor, + std::map* item_map) const; + void PrintMessages( + const std::map& import_map) const; + void PrintMessage(const Descriptor& message_descriptor, bool is_nested, + const std::map& import_map) const; + void PrintServices() const; + void PrintItemMap(const std::map& item_map) const; + std::string GetFieldType( + const FieldDescriptor& field_des, const Descriptor& containing_des, + const std::map& import_map) const; + template + std::string ModuleLevelName( + const DescriptorT& descriptor, + const std::map& import_map) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_ and printer_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PyiGenerator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h index 3b4c1323..21d48cd9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h @@ -1,193 +1,6 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYTHON_GENERATOR_H_ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYTHON_GENERATOR_H_ -// Author: robinson@google.com (Will Robinson) -// -// Generates Python code for a given .proto file. +#include -#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ - -#include - -#include -#include - -#include - -namespace google { -namespace protobuf { - -class Descriptor; -class EnumDescriptor; -class EnumValueDescriptor; -class FieldDescriptor; -class OneofDescriptor; -class ServiceDescriptor; - -namespace io { -class Printer; -} - -namespace compiler { -namespace python { - -enum class StripPrintDescriptor { kCreate, kFind }; - -// CodeGenerator implementation for generated Python protocol buffer classes. -// If you create your own protocol compiler binary and you want it to support -// Python output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class PROTOC_EXPORT Generator : public CodeGenerator { - public: - Generator(); - virtual ~Generator(); - - // CodeGenerator methods. - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* generator_context, - std::string* error) const override; - - uint64_t GetSupportedFeatures() const override; - - private: - void PrintImports() const; - void PrintFileDescriptor() const; - void PrintTopLevelEnums() const; - void PrintAllNestedEnumsInFile(StripPrintDescriptor print_mode) const; - void PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const; - void PrintCreateEnum(const EnumDescriptor& enum_descriptor) const; - void PrintFindEnum(const EnumDescriptor& enum_descriptor) const; - - void PrintTopLevelExtensions() const; - - void PrintFieldDescriptor(const FieldDescriptor& field, - bool is_extension) const; - void PrintFieldDescriptorsInDescriptor( - const Descriptor& message_descriptor, bool is_extension, - const std::string& list_variable_name, int (Descriptor::*CountFn)() const, - const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const; - void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; - void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; - void PrintMessageDescriptors(StripPrintDescriptor print_mode) const; - void PrintCreateDescriptor(const Descriptor& message_descriptor) const; - void PrintFindDescriptor(const Descriptor& message_descriptor) const; - void PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const; - - void PrintMessages() const; - void PrintMessage(const Descriptor& message_descriptor, - const std::string& prefix, - std::vector* to_register, - bool is_nested) const; - void PrintNestedMessages(const Descriptor& containing_descriptor, - const std::string& prefix, - std::vector* to_register) const; - - void FixForeignFieldsInDescriptors() const; - void FixForeignFieldsInDescriptor( - const Descriptor& descriptor, - const Descriptor* containing_descriptor) const; - void FixForeignFieldsInField(const Descriptor* containing_type, - const FieldDescriptor& field, - const std::string& python_dict_name) const; - void AddMessageToFileDescriptor(const Descriptor& descriptor) const; - void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const; - void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const; - void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const; - std::string FieldReferencingExpression( - const Descriptor* containing_type, const FieldDescriptor& field, - const std::string& python_dict_name) const; - template - void FixContainingTypeInDescriptor( - const DescriptorT& descriptor, - const Descriptor* containing_descriptor) const; - - void FixForeignFieldsInExtensions() const; - void FixForeignFieldsInExtension( - const FieldDescriptor& extension_field) const; - void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; - - void PrintServices() const; - void PrintServiceDescriptors() const; - void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; - void PrintServiceClass(const ServiceDescriptor& descriptor) const; - void PrintServiceStub(const ServiceDescriptor& descriptor) const; - void PrintDescriptorKeyAndModuleName( - const ServiceDescriptor& descriptor) const; - - void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; - std::string OptionsValue(const std::string& serialized_options) const; - bool GeneratingDescriptorProto() const; - - template - std::string ModuleLevelDescriptorName(const DescriptorT& descriptor) const; - std::string ModuleLevelMessageName(const Descriptor& descriptor) const; - std::string ModuleLevelServiceDescriptorName( - const ServiceDescriptor& descriptor) const; - - template - void PrintSerializedPbInterval(const DescriptorT& descriptor, - DescriptorProtoT& proto, - const std::string& name) const; - - void FixAllDescriptorOptions() const; - void FixOptionsForField(const FieldDescriptor& field) const; - void FixOptionsForOneof(const OneofDescriptor& oneof) const; - void FixOptionsForEnum(const EnumDescriptor& descriptor) const; - void FixOptionsForService(const ServiceDescriptor& descriptor) const; - void FixOptionsForMessage(const Descriptor& descriptor) const; - - void SetSerializedPbInterval() const; - void SetMessagePbInterval(const Descriptor& descriptor) const; - - void CopyPublicDependenciesAliases(const std::string& copy_from, - const FileDescriptor* file) const; - - // Very coarse-grained lock to ensure that Generate() is reentrant. - // Guards file_, printer_ and file_descriptor_serialized_. - mutable Mutex mutex_; - mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. - mutable std::string file_descriptor_serialized_; - mutable io::Printer* printer_; // Set in Generate(). Under mutex_. - mutable bool pure_python_workable_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); -}; - -} // namespace python -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYTHON_GENERATOR_H_ diff --git a/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator.cc index 46e60f58..d4a53d56 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -158,7 +158,7 @@ std::string DefaultValueForField(const FieldDescriptor* field) { for (int i = 0; i < default_str.length(); ++i) { // Write the hex form of each byte. os << "\\x" << std::hex << std::setw(2) - << ((uint16)((unsigned char)default_str.at(i))); + << ((uint16_t)((unsigned char)default_str.at(i))); } os << "\".force_encoding(\"ASCII-8BIT\")"; } @@ -421,7 +421,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { // -> A.B.C if (package_name.find("::") != std::string::npos) { need_change_to_module = false; - } else { + } else if (package_name.find(".") != std::string::npos) { GOOGLE_LOG(WARNING) << "ruby_package option should be in the form of:" << " 'A::B::C' and not 'A.B.C'"; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index 040b6c98..c3ce1d36 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -57,7 +57,7 @@ std::string FindRubyTestDir() { // Some day, we may integrate build systems between protoc and the language // extensions to the point where we can do this test in a more automated way. -void RubyTest(string proto_file, string import_proto_file = "") { +void RubyTest(std::string proto_file, std::string import_proto_file = "") { std::string ruby_tests = FindRubyTestDir(); google::protobuf::compiler::CommandLineInterface cli; diff --git a/third_party/protobuf/src/google/protobuf/compiler/scc.h b/third_party/protobuf/src/google/protobuf/compiler/scc.h index a1394602..7b95689d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/scc.h +++ b/third_party/protobuf/src/google/protobuf/compiler/scc.h @@ -37,6 +37,7 @@ #include #include +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc b/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc index 7e59cd7d..6f547db7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc @@ -45,8 +45,9 @@ #include #include -#include #include +#include +#include namespace google { namespace protobuf { @@ -55,7 +56,7 @@ namespace compiler { namespace { char* portable_strdup(const char* s) { char* ns = (char*)malloc(strlen(s) + 1); - if (ns != NULL) { + if (ns != nullptr) { strcpy(ns, s); } return ns; @@ -73,15 +74,15 @@ static void CloseHandleOrDie(HANDLE handle) { Subprocess::Subprocess() : process_start_error_(ERROR_SUCCESS), - child_handle_(NULL), - child_stdin_(NULL), - child_stdout_(NULL) {} + child_handle_(nullptr), + child_stdin_(nullptr), + child_stdout_(nullptr) {} Subprocess::~Subprocess() { - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { CloseHandleOrDie(child_stdin_); } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { CloseHandleOrDie(child_stdout_); } } @@ -93,10 +94,10 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { HANDLE stdout_pipe_read; HANDLE stdout_pipe_write; - if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } - if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } @@ -113,7 +114,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { } // Setup STARTUPINFO to redirect handles. - STARTUPINFOA startup_info; + STARTUPINFOW startup_info; ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESTDHANDLES; @@ -125,23 +126,36 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { GOOGLE_LOG(FATAL) << "GetStdHandle: " << Win32ErrorMessage(GetLastError()); } + // get wide string version of program as the path may contain non-ascii characters + std::wstring wprogram; + if (!io::win32::strings::utf8_to_wcs(program.c_str(), &wprogram)) { + GOOGLE_LOG(FATAL) << "utf8_to_wcs: " << Win32ErrorMessage(GetLastError()); + } + // Invoking cmd.exe allows for '.bat' files from the path as well as '.exe'. + std::string command_line = "cmd.exe /c \"" + program + "\""; + + // get wide string version of command line as the path may contain non-ascii characters + std::wstring wcommand_line; + if (!io::win32::strings::utf8_to_wcs(command_line.c_str(), &wcommand_line)) { + GOOGLE_LOG(FATAL) << "utf8_to_wcs: " << Win32ErrorMessage(GetLastError()); + } + // Using a malloc'ed string because CreateProcess() can mutate its second // parameter. - char* command_line = - portable_strdup(("cmd.exe /c \"" + program + "\"").c_str()); + wchar_t *wcommand_line_copy = _wcsdup(wcommand_line.c_str()); // Create the process. PROCESS_INFORMATION process_info; - if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(), - (search_mode == SEARCH_PATH) ? command_line : NULL, - NULL, // process security attributes - NULL, // thread security attributes - TRUE, // inherit handles? - 0, // obscure creation flags - NULL, // environment (inherit from parent) - NULL, // current directory (inherit from parent) + if (CreateProcessW((search_mode == SEARCH_PATH) ? nullptr : wprogram.c_str(), + (search_mode == SEARCH_PATH) ? wcommand_line_copy : NULL, + nullptr, // process security attributes + nullptr, // thread security attributes + TRUE, // inherit handles? + 0, // obscure creation flags + nullptr, // environment (inherit from parent) + nullptr, // current directory (inherit from parent) &startup_info, &process_info)) { child_handle_ = process_info.hProcess; CloseHandleOrDie(process_info.hThread); @@ -155,7 +169,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { CloseHandleOrDie(stdin_pipe_read); CloseHandleOrDie(stdout_pipe_write); - free(command_line); + free(wcommand_line_copy); } bool Subprocess::Communicate(const Message& input, Message* output, @@ -165,28 +179,32 @@ bool Subprocess::Communicate(const Message& input, Message* output, return false; } - GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first."; + GOOGLE_CHECK(child_handle_ != nullptr) << "Must call Start() first."; - std::string input_data = input.SerializeAsString(); + std::string input_data; + if (!input.SerializeToString(&input_data)) { + *error = "Failed to serialize request."; + return false; + } std::string output_data; int input_pos = 0; - while (child_stdout_ != NULL) { + while (child_stdout_ != nullptr) { HANDLE handles[2]; int handle_count = 0; - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { handles[handle_count++] = child_stdin_; } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { handles[handle_count++] = child_stdout_; } DWORD wait_result = WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE); - HANDLE signaled_handle = NULL; + HANDLE signaled_handle = nullptr; if (wait_result >= WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + handle_count) { signaled_handle = handles[wait_result - WAIT_OBJECT_0]; @@ -201,7 +219,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (signaled_handle == child_stdin_) { DWORD n; if (!WriteFile(child_stdin_, input_data.data() + input_pos, - input_data.size() - input_pos, &n, NULL)) { + input_data.size() - input_pos, &n, nullptr)) { // Child closed pipe. Presumably it will report an error later. // Pretend we're done for now. input_pos = input_data.size(); @@ -212,27 +230,27 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (input_pos == input_data.size()) { // We're done writing. Close. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } } else if (signaled_handle == child_stdout_) { char buffer[4096]; DWORD n; - if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) { + if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, nullptr)) { // We're done reading. Close. CloseHandleOrDie(child_stdout_); - child_stdout_ = NULL; + child_stdout_ = nullptr; } else { output_data.append(buffer, n); } } } - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { // Child did not finish reading input before it closed the output. // Presumably it exited with an error. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE); @@ -252,7 +270,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, } CloseHandleOrDie(child_handle_); - child_handle_ = NULL; + child_handle_ = nullptr; if (exit_code != 0) { *error = strings::Substitute("Plugin failed with status code $0.", exit_code); @@ -273,9 +291,10 @@ std::string Subprocess::Win32ErrorMessage(DWORD error_code) { // WTF? FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + nullptr, error_code, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, // NOT A BUG! - 0, NULL); + 0, nullptr); std::string result = message; LocalFree(message); @@ -309,7 +328,7 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) { GOOGLE_CHECK(pipe(stdin_pipe) != -1); GOOGLE_CHECK(pipe(stdout_pipe) != -1); - char* argv[2] = {portable_strdup(program.c_str()), NULL}; + char* argv[2] = {portable_strdup(program.c_str()), nullptr}; child_pid_ = fork(); if (child_pid_ == -1) { @@ -368,7 +387,11 @@ bool Subprocess::Communicate(const Message& input, Message* output, // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us. SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN); - std::string input_data = input.SerializeAsString(); + std::string input_data; + if (!input.SerializeToString(&input_data)) { + *error = "Failed to serialize request."; + return false; + } std::string output_data; int input_pos = 0; @@ -386,7 +409,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, FD_SET(child_stdin_, &write_fds); } - if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) { + if (select(max_fd + 1, &read_fds, &write_fds, nullptr, nullptr) < 0) { if (errno == EINTR) { // Interrupted by signal. Try again. continue; diff --git a/third_party/protobuf/src/google/protobuf/compiler/subprocess.h b/third_party/protobuf/src/google/protobuf/compiler/subprocess.h index c1ddaae5..5cb784d4 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/subprocess.h +++ b/third_party/protobuf/src/google/protobuf/compiler/subprocess.h @@ -46,6 +46,7 @@ #include +// Must be included last. #include namespace google { diff --git a/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc b/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc index 6b561700..2556078c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc @@ -34,7 +34,9 @@ // command_line_interface_unittest. #include + #include + #include #include diff --git a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h index 0a8a7735..5d7f69a4 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h +++ b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h @@ -29,6 +29,8 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) +#ifndef GOOGLE_PROTOBUF_COMPILER_ZIP_WRITER_H__ +#define GOOGLE_PROTOBUF_COMPILER_ZIP_WRITER_H__ #include #include @@ -63,3 +65,5 @@ class ZipWriter { } // namespace compiler } // namespace protobuf } // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_ZIP_WRITER_H__ diff --git a/third_party/protobuf/src/google/protobuf/descriptor.cc b/third_party/protobuf/src/google/protobuf/descriptor.cc index c8ce218a..5f3427dc 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor.cc @@ -41,30 +41,32 @@ #include #include #include +#include #include +#include #include #include #include #include #include -#include #include +#include #include #include -#include #include #include #include +#include +#include +#include #include #include #include +#include +#include #include #include -#include -#include -#include -#include #include #include #include @@ -72,11 +74,493 @@ #undef PACKAGE // autoheader #defines this. :( +// Must be included last. #include namespace google { namespace protobuf { +namespace { +const int kPackageLimit = 100; + +// Note: I distrust ctype.h due to locales. +char ToUpper(char ch) { + return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; +} + +char ToLower(char ch) { + return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch; +} + +std::string ToCamelCase(const std::string& input, bool lower_first) { + bool capitalize_next = !lower_first; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = ToLower(result[0]); + } + + return result; +} + +std::string ToJsonName(const std::string& input) { + bool capitalize_next = false; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + return result; +} + +// Backport of fold expressions for the comma operator to C++11. +// Usage: Fold({expr...}); +// Guaranteed to evaluate left-to-right +struct ExpressionEater { + template + ExpressionEater(T&&) {} // NOLINT +}; +void Fold(std::initializer_list) {} + +template +constexpr size_t RoundUpTo(size_t n) { + static_assert((R & (R - 1)) == 0, "Must be power of two"); + return (n + (R - 1)) & ~(R - 1); +} + +constexpr size_t Max(size_t a, size_t b) { return a > b ? a : b; } +template +constexpr size_t Max(T a, Ts... b) { + return Max(a, Max(b...)); +} + +template +constexpr size_t EffectiveAlignof() { + // `char` is special in that it gets aligned to 8. It is where we drop the + // trivial structs. + return std::is_same::value ? 8 : alignof(T); +} + +template +using AppendIfAlign = + typename std::conditional() == align, void (*)(T..., U), + void (*)(T...)>::type; + +// Metafunction to sort types in descending order of alignment. +// Useful for the flat allocator to ensure proper alignment of all elements +// without having to add padding. +// Instead of implementing a proper sort metafunction we just do a +// filter+merge, which is much simpler to write as a metafunction. +// We have a fixed set of alignments we can filter on. +// For simplicity we use a function pointer as a type list. +template +struct TypeListSortImpl; + +template +struct TypeListSortImpl { + using type = void (*)(T16..., T8..., T4..., T2..., T1...); +}; + +template +struct TypeListSortImpl { + using type = typename TypeListSortImpl< + void (*)(Rest...), AppendIfAlign<16, First, T16...>, + AppendIfAlign<8, First, T8...>, AppendIfAlign<4, First, T4...>, + AppendIfAlign<2, First, T2...>, AppendIfAlign<1, First, T1...>>::type; +}; + +template +using SortByAlignment = + typename TypeListSortImpl::type; + +template